diff --git a/.gitmodules b/.gitmodules index 290f900b..ec64c376 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,18 @@ [submodule "presentation/src/main/cpp/third_party/libvpx"] path = presentation/src/main/cpp/third_party/libvpx url = https://github.com/webmproject/libvpx.git +[submodule "tdlib"] + path = tdlib + url = https://github.com/monogram-android/monogram_tdlib_module.git +[submodule "core"] + path = core + url = https://github.com/monogram-android/monogram_core_module.git +[submodule "domain"] + path = domain + url = https://github.com/monogram-android/monogram_domain_module.git +[submodule "data"] + path = data + url = https://github.com/monogram-android/monogram_data_module.git +[submodule "presentation"] + path = presentation + url = https://github.com/monogram-android/monogram_presentation_module.git diff --git a/README.md b/README.md index 0f12af2b..de5f680b 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ Follow these steps to set up the project locally. ### 1. Clone the Repository ```bash -git clone https://github.com/monogram-android/monogram.git +git clone --recursive https://github.com/monogram-android/monogram.git cd monogram ``` diff --git a/README_RU.md b/README_RU.md index e330ebb8..7cd9aa7f 100644 --- a/README_RU.md +++ b/README_RU.md @@ -75,7 +75,7 @@ Monogram использует новейшие инструменты и биб ### 1. Клонирование репозитория ```bash -git clone https://github.com/monogram-android/monogram.git +git clone --recursive https://github.com/monogram-android/monogram.git cd monogram ``` diff --git a/core b/core new file mode 160000 index 00000000..52330b64 --- /dev/null +++ b/core @@ -0,0 +1 @@ +Subproject commit 52330b6491a34d9cae4be4329afe4bdc79410851 diff --git a/core/build.gradle.kts b/core/build.gradle.kts deleted file mode 100644 index e2bcf86f..00000000 --- a/core/build.gradle.kts +++ /dev/null @@ -1,11 +0,0 @@ -plugins { - kotlin("jvm") -} - -kotlin { - jvmToolchain(21) -} - -dependencies { - implementation(libs.kotlinx.coroutines.core) -} \ No newline at end of file diff --git a/core/src/main/kotlin/org/monogram/core/AppError.kt b/core/src/main/kotlin/org/monogram/core/AppError.kt deleted file mode 100644 index 875b8a0f..00000000 --- a/core/src/main/kotlin/org/monogram/core/AppError.kt +++ /dev/null @@ -1,9 +0,0 @@ -package org.monogram.core - -sealed interface AppError { - data class Network(val cause: Throwable?) : AppError - data class Unauthorized(val cause: Throwable?) : AppError - data class NotFound(val cause: Throwable?) : AppError - data class Validation(val message: String) : AppError - data class Unknown(val cause: Throwable?) : AppError -} \ No newline at end of file diff --git a/core/src/main/kotlin/org/monogram/core/AppResult.kt b/core/src/main/kotlin/org/monogram/core/AppResult.kt deleted file mode 100644 index f585b552..00000000 --- a/core/src/main/kotlin/org/monogram/core/AppResult.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.monogram.core - -sealed interface AppResult { - data class Success( - val value: T - ) : AppResult - - data class Error( - val error: AppError - ) : AppResult -} \ No newline at end of file diff --git a/core/src/main/kotlin/org/monogram/core/DispatcherProvider.kt b/core/src/main/kotlin/org/monogram/core/DispatcherProvider.kt deleted file mode 100644 index 997480b7..00000000 --- a/core/src/main/kotlin/org/monogram/core/DispatcherProvider.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.monogram.core - -import kotlinx.coroutines.CoroutineDispatcher - -interface DispatcherProvider { - val main: CoroutineDispatcher - val io: CoroutineDispatcher - val default: CoroutineDispatcher - val mainImmediate: CoroutineDispatcher -} \ No newline at end of file diff --git a/core/src/main/kotlin/org/monogram/core/FlowExt.kt b/core/src/main/kotlin/org/monogram/core/FlowExt.kt deleted file mode 100644 index 3722732e..00000000 --- a/core/src/main/kotlin/org/monogram/core/FlowExt.kt +++ /dev/null @@ -1,31 +0,0 @@ -package org.monogram.core - -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.catch -import kotlinx.coroutines.flow.map - -fun Flow.asResult(): Flow> { - return this - .map> { - AppResult.Success(it) - } - .catch { - if (it is CancellationException) { - throw it - } - emit(AppResult.Error(AppError.Unknown(it))) - } -} - -suspend fun runCatchingApp( - block: suspend () -> T -): AppResult { - return try { - AppResult.Success(block()) - } catch (e: CancellationException) { - throw e - } catch (t: Throwable) { - AppResult.Error(AppError.Unknown(t)) - } -} \ No newline at end of file diff --git a/core/src/main/kotlin/org/monogram/core/Logger.kt b/core/src/main/kotlin/org/monogram/core/Logger.kt deleted file mode 100644 index 6b25fbfd..00000000 --- a/core/src/main/kotlin/org/monogram/core/Logger.kt +++ /dev/null @@ -1,60 +0,0 @@ -package org.monogram.core - -enum class LogLevel { - VERBOSE, - DEBUG, - INFO, - WARNING, - ERROR -} - -data class LogEvent( - val level: LogLevel, - val message: String, - val tag: String? = null, - val throwable: Throwable? = null, - val timestamp: Long = System.currentTimeMillis(), - val metadata: Map = emptyMap() -) - -interface Logger { - val isDebugEnabled: Boolean - fun log(event: LogEvent) -} - - -inline fun Logger.debug( - tag: String? = null, - throwable: Throwable? = null, - metadata: Map = emptyMap(), - message: () -> String -) { - if (!isDebugEnabled) return - - log( - LogEvent( - level = LogLevel.DEBUG, - message = message(), - tag = tag, - throwable = throwable, - metadata = metadata - ) - ) -} - -inline fun Logger.error( - tag: String? = null, - throwable: Throwable? = null, - metadata: Map = emptyMap(), - message: () -> String -) { - log( - LogEvent( - level = LogLevel.ERROR, - message = message(), - tag = tag, - throwable = throwable, - metadata = metadata - ) - ) -} \ No newline at end of file diff --git a/core/src/main/kotlin/org/monogram/core/Mapper.kt b/core/src/main/kotlin/org/monogram/core/Mapper.kt deleted file mode 100644 index c7a496da..00000000 --- a/core/src/main/kotlin/org/monogram/core/Mapper.kt +++ /dev/null @@ -1,5 +0,0 @@ -package org.monogram.core - -interface Mapper { - fun map(input: I): O -} \ No newline at end of file diff --git a/core/src/main/kotlin/org/monogram/core/ScopeProvider.kt b/core/src/main/kotlin/org/monogram/core/ScopeProvider.kt deleted file mode 100644 index 8a62a55d..00000000 --- a/core/src/main/kotlin/org/monogram/core/ScopeProvider.kt +++ /dev/null @@ -1,7 +0,0 @@ -package org.monogram.core - -import kotlinx.coroutines.CoroutineScope - -interface ScopeProvider { - val appScope: CoroutineScope -} \ No newline at end of file diff --git a/core/src/main/kotlin/org/monogram/core/SuspendMapper.kt b/core/src/main/kotlin/org/monogram/core/SuspendMapper.kt deleted file mode 100644 index c059a41f..00000000 --- a/core/src/main/kotlin/org/monogram/core/SuspendMapper.kt +++ /dev/null @@ -1,5 +0,0 @@ -package org.monogram.core - -interface SuspendMapper { - suspend fun map(input: I): O -} \ No newline at end of file diff --git a/core/src/main/kotlin/org/monogram/core/UseCase.kt b/core/src/main/kotlin/org/monogram/core/UseCase.kt deleted file mode 100644 index b70802d0..00000000 --- a/core/src/main/kotlin/org/monogram/core/UseCase.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.monogram.core - -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.withContext - -abstract class UseCase( - private val dispatcher: CoroutineDispatcher -) { - suspend operator fun invoke(param: Param): Result = - withContext(dispatcher) { - execute(param) - } - protected abstract suspend fun execute(param: Param): Result -} \ No newline at end of file diff --git a/data b/data new file mode 160000 index 00000000..6883ff6d --- /dev/null +++ b/data @@ -0,0 +1 @@ +Subproject commit 6883ff6dfd182b9ab81a8ab601f9b116734da54b diff --git a/data/.gitignore b/data/.gitignore deleted file mode 100644 index 42afabfd..00000000 --- a/data/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/data/build.gradle.kts b/data/build.gradle.kts deleted file mode 100644 index 78823b35..00000000 --- a/data/build.gradle.kts +++ /dev/null @@ -1,85 +0,0 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import java.util.* - -plugins { - alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.android) - alias(libs.plugins.kotlin.serialization) - alias(libs.plugins.ksp) -} - -android { - namespace = "org.monogram.data" - buildFeatures { - buildConfig = true - } - - compileSdk { - version = release(36) - } - sourceSets { - getByName("main") { - jniLibs.srcDirs("src/main/jniLibs") - } - } - defaultConfig { - ndk { - abiFilters.add("arm64-v8a") - } - - val properties = Properties() - val localPropertiesFile = project.rootProject.file("local.properties") - if (localPropertiesFile.exists()) { - localPropertiesFile.inputStream().use { properties.load(it) } - } - - val apiId = properties.getProperty("API_ID") ?: "0" - val apiHash = properties.getProperty("API_HASH") ?: "" - - buildConfigField("int", "API_ID", apiId) - buildConfigField("String", "API_HASH", "\"$apiHash\"") - } - packaging { - jniLibs { - useLegacyPackaging = true - } - } - defaultConfig { - minSdk = 25 - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 - } - kotlin { - compilerOptions { - jvmTarget = JvmTarget.JVM_17 - } - } -} - -dependencies { - implementation(project(":core")) - implementation(project(":domain")) - implementation(libs.koin.android) - implementation(libs.kotlinx.coroutines.core) - implementation(libs.kotlinx.serialization.json) - implementation(libs.androidx.media3.datasource) - implementation(platform(libs.firebase.bom)) - implementation(libs.firebase.messaging) - - implementation(libs.androidx.room.runtime) - implementation(libs.androidx.room.ktx) - ksp(libs.androidx.room.compiler) -} \ No newline at end of file diff --git a/data/consumer-rules.pro b/data/consumer-rules.pro deleted file mode 100644 index e69de29b..00000000 diff --git a/data/proguard-rules.pro b/data/proguard-rules.pro deleted file mode 100644 index 481bb434..00000000 --- a/data/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/data/src/main/AndroidManifest.xml b/data/src/main/AndroidManifest.xml deleted file mode 100644 index 0be57ce1..00000000 --- a/data/src/main/AndroidManifest.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data/src/main/java/org/drinkless/tdlib/Client.java b/data/src/main/java/org/drinkless/tdlib/Client.java deleted file mode 100644 index 9b911c57..00000000 --- a/data/src/main/java/org/drinkless/tdlib/Client.java +++ /dev/null @@ -1,259 +0,0 @@ -// -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2026 -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -package org.drinkless.tdlib; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; - -/** - * Main class for interaction with the TDLib. - */ -public final class Client { - static { - try { - System.loadLibrary("tdjni"); - } catch (UnsatisfiedLinkError e) { - e.printStackTrace(); - } - } - - /** - * Interface for handler for results of queries to TDLib and incoming updates from TDLib. - */ - public interface ResultHandler { - /** - * Callback called on result of query to TDLib or incoming update from TDLib. - * - * @param object Result of query or update of type TdApi.Update about new events. - */ - void onResult(TdApi.Object object); - } - - /** - * Interface for handler of exceptions thrown while invoking ResultHandler. - * By default, all such exceptions are ignored. - * All exceptions thrown from ExceptionHandler are ignored. - */ - public interface ExceptionHandler { - /** - * Callback called on exceptions thrown while invoking ResultHandler. - * - * @param e Exception thrown by ResultHandler. - */ - void onException(Throwable e); - } - - /** - * Interface for handler of messages that are added to the internal TDLib log. - */ - public interface LogMessageHandler { - /** - * Callback called on messages that are added to the internal TDLib log. - * - * @param verbosityLevel Log verbosity level with which the message was added from -1 up to 1024. - * If 0, then TDLib will crash as soon as the callback returns. - * None of the TDLib methods can be called from the callback. - * @param message The message added to the internal TDLib log. - */ - void onLogMessage(int verbosityLevel, String message); - } - - /** - * Exception class thrown when TDLib error occurred while performing {@link #execute(TdApi.Function)}. - */ - public static class ExecutionException extends Exception { - /** - * Original TDLib error occurred when performing one of the synchronous functions. - */ - public final TdApi.Error error; - - /** - * @param error TDLib error occurred while performing {@link #execute(TdApi.Function)}. - */ - ExecutionException (TdApi.Error error) { - super(error.code + ": " + error.message); - this.error = error; - } - } - - /** - * Sends a request to the TDLib. - * - * @param query Object representing a query to the TDLib. - * @param resultHandler Result handler with onResult method which will be called with result - * of the query or with TdApi.Error as parameter. If it is null, nothing - * will be called. - * @param exceptionHandler Exception handler with onException method which will be called on - * exception thrown from resultHandler. If it is null, then - * defaultExceptionHandler will be called. - */ - public void send(TdApi.Function query, ResultHandler resultHandler, ExceptionHandler exceptionHandler) { - long queryId = currentQueryId.incrementAndGet(); - if (resultHandler != null) { - handlers.put(queryId, new Handler(resultHandler, exceptionHandler)); - } - nativeClientSend(nativeClientId, queryId, query); - } - - /** - * Sends a request to the TDLib with an empty ExceptionHandler. - * - * @param query Object representing a query to the TDLib. - * @param resultHandler Result handler with onResult method which will be called with result - * of the query or with TdApi.Error as parameter. If it is null, then - * defaultExceptionHandler will be called. - */ - public void send(TdApi.Function query, ResultHandler resultHandler) { - send(query, resultHandler, null); - } - - /** - * Synchronously executes a TDLib request. Only a few marked accordingly requests can be executed synchronously. - * - * @param query Object representing a query to the TDLib. - * @param Automatically deduced return type of the query. - * @return request result. - * @throws ExecutionException if query execution fails. - */ - @SuppressWarnings("unchecked") - public static T execute(TdApi.Function query) throws ExecutionException { - TdApi.Object object = nativeClientExecute(query); - if (object instanceof TdApi.Error) { - throw new ExecutionException((TdApi.Error) object); - } - return (T) object; - } - - /** - * Creates new Client. - * - * @param updateHandler Handler for incoming updates. - * @param updateExceptionHandler Handler for exceptions thrown from updateHandler. If it is null, exceptions will be ignored. - * @param defaultExceptionHandler Default handler for exceptions thrown from all ResultHandler. If it is null, exceptions will be ignored. - * @return created Client - */ - public static Client create(ResultHandler updateHandler, ExceptionHandler updateExceptionHandler, ExceptionHandler defaultExceptionHandler) { - Client client = new Client(updateHandler, updateExceptionHandler, defaultExceptionHandler); - synchronized (responseReceiver) { - if (!responseReceiver.isRun) { - responseReceiver.isRun = true; - - Thread receiverThread = new Thread(responseReceiver, "TDLib thread"); - receiverThread.setDaemon(true); - receiverThread.start(); - } - } - return client; - } - - /** - * Sets the handler for messages that are added to the internal TDLib log. - * None of the TDLib methods can be called from the callback. - * - * @param maxVerbosityLevel The maximum verbosity level of messages for which the callback will be called. - * @param logMessageHandler Handler for messages that are added to the internal TDLib log. Pass null to remove the handler. - */ - public static void setLogMessageHandler(int maxVerbosityLevel, Client.LogMessageHandler logMessageHandler) { - nativeClientSetLogMessageHandler(maxVerbosityLevel, logMessageHandler); - } - - private static class ResponseReceiver implements Runnable { - public boolean isRun = false; - - @Override - public void run() { - while (true) { - int resultN = nativeClientReceive(clientIds, eventIds, events, 100000.0 /*seconds*/); - for (int i = 0; i < resultN; i++) { - processResult(clientIds[i], eventIds[i], events[i]); - events[i] = null; - } - } - } - - private void processResult(int clientId, long id, TdApi.Object object) { - boolean isClosed = false; - if (id == 0 && object instanceof TdApi.UpdateAuthorizationState) { - TdApi.AuthorizationState authorizationState = ((TdApi.UpdateAuthorizationState) object).authorizationState; - if (authorizationState instanceof TdApi.AuthorizationStateClosed) { - isClosed = true; - } - } - - Handler handler = id == 0 ? updateHandlers.get(clientId) : handlers.remove(id); - if (handler != null) { - try { - handler.resultHandler.onResult(object); - } catch (Throwable cause) { - ExceptionHandler exceptionHandler = handler.exceptionHandler; - if (exceptionHandler == null) { - exceptionHandler = defaultExceptionHandlers.get(clientId); - } - if (exceptionHandler != null) { - try { - exceptionHandler.onException(cause); - } catch (Throwable ignored) { - } - } - } - } - - if (isClosed) { - updateHandlers.remove(clientId); // there will be no more updates - defaultExceptionHandlers.remove(clientId); // ignore further exceptions - clientCount.decrementAndGet(); - } - } - - private static final int MAX_EVENTS = 1000; - private final int[] clientIds = new int[MAX_EVENTS]; - private final long[] eventIds = new long[MAX_EVENTS]; - private final TdApi.Object[] events = new TdApi.Object[MAX_EVENTS]; - } - - private final int nativeClientId; - - private static final ConcurrentHashMap defaultExceptionHandlers = new ConcurrentHashMap(); - private static final ConcurrentHashMap updateHandlers = new ConcurrentHashMap(); - private static final ConcurrentHashMap handlers = new ConcurrentHashMap(); - private static final AtomicLong currentQueryId = new AtomicLong(); - private static final AtomicLong clientCount = new AtomicLong(); - - private static final ResponseReceiver responseReceiver = new ResponseReceiver(); - - private static class Handler { - final ResultHandler resultHandler; - final ExceptionHandler exceptionHandler; - - Handler(ResultHandler resultHandler, ExceptionHandler exceptionHandler) { - this.resultHandler = resultHandler; - this.exceptionHandler = exceptionHandler; - } - } - - private Client(ResultHandler updateHandler, ExceptionHandler updateExceptionHandler, ExceptionHandler defaultExceptionHandler) { - clientCount.incrementAndGet(); - nativeClientId = createNativeClient(); - if (updateHandler != null) { - updateHandlers.put(nativeClientId, new Handler(updateHandler, updateExceptionHandler)); - } - if (defaultExceptionHandler != null) { - defaultExceptionHandlers.put(nativeClientId, defaultExceptionHandler); - } - send(new TdApi.GetOption("version"), null, null); - } - - private static native int createNativeClient(); - - private static native void nativeClientSend(int nativeClientId, long eventId, TdApi.Function function); - - private static native int nativeClientReceive(int[] clientIds, long[] eventIds, TdApi.Object[] events, double timeout); - - private static native TdApi.Object nativeClientExecute(TdApi.Function function); - - private static native void nativeClientSetLogMessageHandler(int maxVerbosityLevel, LogMessageHandler logMessageHandler); -} diff --git a/data/src/main/java/org/drinkless/tdlib/TdApi.java b/data/src/main/java/org/drinkless/tdlib/TdApi.java deleted file mode 100644 index 6a89c6dd..00000000 --- a/data/src/main/java/org/drinkless/tdlib/TdApi.java +++ /dev/null @@ -1,142367 +0,0 @@ -package org.drinkless.tdlib; - -import androidx.annotation.IntDef; -import androidx.annotation.Nullable; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * This class contains as static nested classes all other TDLib interface - * type-classes and function-classes. - *

- * It has no inner classes, functions or public members. - */ -public class TdApi { - static { - try { - System.loadLibrary("tdjni"); - } catch (UnsatisfiedLinkError e) { - e.printStackTrace(); - } - } - - private static final String GIT_COMMIT_HASH = "af0cb1d30a1e5cb1a10cd83b48998ca9ea9ce249"; - - private TdApi() { - } - - /** - * This class is a base class for all TDLib interface classes. - */ - public abstract static class Object { - /** - * Default Object constructor. - */ - public Object() { - } - - /** - * Returns a string representation of the object. - * - * @return a string representation of the object. - */ - public native String toString(); - - /** - * Returns an identifier uniquely determining type of the object. - * - * @return a unique identifier of the object type. - */ - public abstract int getConstructor(); - } - - /** - * This class is a base class for all TDLib interface function-classes. - * - * @param The object type that is returned by the function - */ - public abstract static class Function extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - AcceptCall.CONSTRUCTOR, - AcceptOauthRequest.CONSTRUCTOR, - AcceptTermsOfService.CONSTRUCTOR, - ActivateStoryStealthMode.CONSTRUCTOR, - AddBotMediaPreview.CONSTRUCTOR, - AddChatFolderByInviteLink.CONSTRUCTOR, - AddChatMember.CONSTRUCTOR, - AddChatMembers.CONSTRUCTOR, - AddChatToList.CONSTRUCTOR, - AddChecklistTasks.CONSTRUCTOR, - AddContact.CONSTRUCTOR, - AddCustomServerLanguagePack.CONSTRUCTOR, - AddFavoriteSticker.CONSTRUCTOR, - AddFileToDownloads.CONSTRUCTOR, - AddGiftCollectionGifts.CONSTRUCTOR, - AddLocalMessage.CONSTRUCTOR, - AddLogMessage.CONSTRUCTOR, - AddLoginPasskey.CONSTRUCTOR, - AddMessageReaction.CONSTRUCTOR, - AddNetworkStatistics.CONSTRUCTOR, - AddOffer.CONSTRUCTOR, - AddPendingLiveStoryReaction.CONSTRUCTOR, - AddPendingPaidMessageReaction.CONSTRUCTOR, - AddProfileAudio.CONSTRUCTOR, - AddProxy.CONSTRUCTOR, - AddQuickReplyShortcutInlineQueryResultMessage.CONSTRUCTOR, - AddQuickReplyShortcutMessage.CONSTRUCTOR, - AddQuickReplyShortcutMessageAlbum.CONSTRUCTOR, - AddRecentSticker.CONSTRUCTOR, - AddRecentlyFoundChat.CONSTRUCTOR, - AddSavedAnimation.CONSTRUCTOR, - AddSavedNotificationSound.CONSTRUCTOR, - AddStickerToSet.CONSTRUCTOR, - AddStoryAlbumStories.CONSTRUCTOR, - AllowBotToSendMessages.CONSTRUCTOR, - AllowUnpaidMessagesFromUser.CONSTRUCTOR, - AnswerCallbackQuery.CONSTRUCTOR, - AnswerCustomQuery.CONSTRUCTOR, - AnswerInlineQuery.CONSTRUCTOR, - AnswerPreCheckoutQuery.CONSTRUCTOR, - AnswerShippingQuery.CONSTRUCTOR, - AnswerWebAppQuery.CONSTRUCTOR, - ApplyPremiumGiftCode.CONSTRUCTOR, - ApproveSuggestedPost.CONSTRUCTOR, - AssignStoreTransaction.CONSTRUCTOR, - BanChatMember.CONSTRUCTOR, - BanGroupCallParticipants.CONSTRUCTOR, - BlockMessageSenderFromReplies.CONSTRUCTOR, - BoostChat.CONSTRUCTOR, - BuyGiftUpgrade.CONSTRUCTOR, - CanBotSendMessages.CONSTRUCTOR, - CanPostStory.CONSTRUCTOR, - CanPurchaseFromStore.CONSTRUCTOR, - CanSendGift.CONSTRUCTOR, - CanSendMessageToUser.CONSTRUCTOR, - CanTransferOwnership.CONSTRUCTOR, - CancelDownloadFile.CONSTRUCTOR, - CancelPasswordReset.CONSTRUCTOR, - CancelPreliminaryUploadFile.CONSTRUCTOR, - CancelRecoveryEmailAddressVerification.CONSTRUCTOR, - ChangeImportedContacts.CONSTRUCTOR, - ChangeStickerSet.CONSTRUCTOR, - CheckAuthenticationBotToken.CONSTRUCTOR, - CheckAuthenticationCode.CONSTRUCTOR, - CheckAuthenticationEmailCode.CONSTRUCTOR, - CheckAuthenticationPasskey.CONSTRUCTOR, - CheckAuthenticationPassword.CONSTRUCTOR, - CheckAuthenticationPasswordRecoveryCode.CONSTRUCTOR, - CheckAuthenticationPremiumPurchase.CONSTRUCTOR, - CheckChatFolderInviteLink.CONSTRUCTOR, - CheckChatInviteLink.CONSTRUCTOR, - CheckChatUsername.CONSTRUCTOR, - CheckCreatedPublicChatsLimit.CONSTRUCTOR, - CheckEmailAddressVerificationCode.CONSTRUCTOR, - CheckLoginEmailAddressCode.CONSTRUCTOR, - CheckOauthRequestMatchCode.CONSTRUCTOR, - CheckPasswordRecoveryCode.CONSTRUCTOR, - CheckPhoneNumberCode.CONSTRUCTOR, - CheckPremiumGiftCode.CONSTRUCTOR, - CheckQuickReplyShortcutName.CONSTRUCTOR, - CheckRecoveryEmailAddressCode.CONSTRUCTOR, - CheckStickerSetName.CONSTRUCTOR, - CheckWebAppFileDownload.CONSTRUCTOR, - CleanFileName.CONSTRUCTOR, - ClearAllDraftMessages.CONSTRUCTOR, - ClearAutosaveSettingsExceptions.CONSTRUCTOR, - ClearImportedContacts.CONSTRUCTOR, - ClearRecentEmojiStatuses.CONSTRUCTOR, - ClearRecentReactions.CONSTRUCTOR, - ClearRecentStickers.CONSTRUCTOR, - ClearRecentlyFoundChats.CONSTRUCTOR, - ClearSearchedForTags.CONSTRUCTOR, - ClickAnimatedEmojiMessage.CONSTRUCTOR, - ClickChatSponsoredMessage.CONSTRUCTOR, - ClickPremiumSubscriptionButton.CONSTRUCTOR, - ClickVideoMessageAdvertisement.CONSTRUCTOR, - Close.CONSTRUCTOR, - CloseChat.CONSTRUCTOR, - CloseGiftAuction.CONSTRUCTOR, - CloseSecretChat.CONSTRUCTOR, - CloseStory.CONSTRUCTOR, - CloseWebApp.CONSTRUCTOR, - CommitPendingLiveStoryReactions.CONSTRUCTOR, - CommitPendingPaidMessageReactions.CONSTRUCTOR, - ConfirmQrCodeAuthentication.CONSTRUCTOR, - ConfirmSession.CONSTRUCTOR, - ConnectAffiliateProgram.CONSTRUCTOR, - CraftGift.CONSTRUCTOR, - CreateBasicGroupChat.CONSTRUCTOR, - CreateBusinessChatLink.CONSTRUCTOR, - CreateCall.CONSTRUCTOR, - CreateChatFolder.CONSTRUCTOR, - CreateChatFolderInviteLink.CONSTRUCTOR, - CreateChatInviteLink.CONSTRUCTOR, - CreateChatSubscriptionInviteLink.CONSTRUCTOR, - CreateForumTopic.CONSTRUCTOR, - CreateGiftCollection.CONSTRUCTOR, - CreateGroupCall.CONSTRUCTOR, - CreateInvoiceLink.CONSTRUCTOR, - CreateNewBasicGroupChat.CONSTRUCTOR, - CreateNewSecretChat.CONSTRUCTOR, - CreateNewStickerSet.CONSTRUCTOR, - CreateNewSupergroupChat.CONSTRUCTOR, - CreatePrivateChat.CONSTRUCTOR, - CreateSecretChat.CONSTRUCTOR, - CreateStoryAlbum.CONSTRUCTOR, - CreateSupergroupChat.CONSTRUCTOR, - CreateTemporaryPassword.CONSTRUCTOR, - CreateVideoChat.CONSTRUCTOR, - DeclineGroupCallInvitation.CONSTRUCTOR, - DeclineOauthRequest.CONSTRUCTOR, - DeclineSuggestedPost.CONSTRUCTOR, - DecryptGroupCallData.CONSTRUCTOR, - DeleteAccount.CONSTRUCTOR, - DeleteAllCallMessages.CONSTRUCTOR, - DeleteAllRevokedChatInviteLinks.CONSTRUCTOR, - DeleteBotMediaPreviews.CONSTRUCTOR, - DeleteBusinessChatLink.CONSTRUCTOR, - DeleteBusinessConnectedBot.CONSTRUCTOR, - DeleteBusinessMessages.CONSTRUCTOR, - DeleteBusinessStory.CONSTRUCTOR, - DeleteChat.CONSTRUCTOR, - DeleteChatBackground.CONSTRUCTOR, - DeleteChatFolder.CONSTRUCTOR, - DeleteChatFolderInviteLink.CONSTRUCTOR, - DeleteChatHistory.CONSTRUCTOR, - DeleteChatMessagesByDate.CONSTRUCTOR, - DeleteChatMessagesBySender.CONSTRUCTOR, - DeleteChatReplyMarkup.CONSTRUCTOR, - DeleteCommands.CONSTRUCTOR, - DeleteDefaultBackground.CONSTRUCTOR, - DeleteDirectMessagesChatTopicHistory.CONSTRUCTOR, - DeleteDirectMessagesChatTopicMessagesByDate.CONSTRUCTOR, - DeleteFile.CONSTRUCTOR, - DeleteForumTopic.CONSTRUCTOR, - DeleteGiftCollection.CONSTRUCTOR, - DeleteGroupCallMessages.CONSTRUCTOR, - DeleteGroupCallMessagesBySender.CONSTRUCTOR, - DeleteLanguagePack.CONSTRUCTOR, - DeleteMessages.CONSTRUCTOR, - DeletePassportElement.CONSTRUCTOR, - DeleteProfilePhoto.CONSTRUCTOR, - DeleteQuickReplyShortcut.CONSTRUCTOR, - DeleteQuickReplyShortcutMessages.CONSTRUCTOR, - DeleteRevokedChatInviteLink.CONSTRUCTOR, - DeleteSavedCredentials.CONSTRUCTOR, - DeleteSavedMessagesTopicHistory.CONSTRUCTOR, - DeleteSavedMessagesTopicMessagesByDate.CONSTRUCTOR, - DeleteSavedOrderInfo.CONSTRUCTOR, - DeleteStickerSet.CONSTRUCTOR, - DeleteStory.CONSTRUCTOR, - DeleteStoryAlbum.CONSTRUCTOR, - Destroy.CONSTRUCTOR, - DisableAllSupergroupUsernames.CONSTRUCTOR, - DisableProxy.CONSTRUCTOR, - DiscardCall.CONSTRUCTOR, - DisconnectAffiliateProgram.CONSTRUCTOR, - DisconnectAllWebsites.CONSTRUCTOR, - DisconnectWebsite.CONSTRUCTOR, - DownloadFile.CONSTRUCTOR, - DropGiftOriginalDetails.CONSTRUCTOR, - EditBotMediaPreview.CONSTRUCTOR, - EditBusinessChatLink.CONSTRUCTOR, - EditBusinessMessageCaption.CONSTRUCTOR, - EditBusinessMessageChecklist.CONSTRUCTOR, - EditBusinessMessageLiveLocation.CONSTRUCTOR, - EditBusinessMessageMedia.CONSTRUCTOR, - EditBusinessMessageReplyMarkup.CONSTRUCTOR, - EditBusinessMessageText.CONSTRUCTOR, - EditBusinessStory.CONSTRUCTOR, - EditChatFolder.CONSTRUCTOR, - EditChatFolderInviteLink.CONSTRUCTOR, - EditChatInviteLink.CONSTRUCTOR, - EditChatSubscriptionInviteLink.CONSTRUCTOR, - EditCustomLanguagePackInfo.CONSTRUCTOR, - EditForumTopic.CONSTRUCTOR, - EditInlineMessageCaption.CONSTRUCTOR, - EditInlineMessageLiveLocation.CONSTRUCTOR, - EditInlineMessageMedia.CONSTRUCTOR, - EditInlineMessageReplyMarkup.CONSTRUCTOR, - EditInlineMessageText.CONSTRUCTOR, - EditMessageCaption.CONSTRUCTOR, - EditMessageChecklist.CONSTRUCTOR, - EditMessageLiveLocation.CONSTRUCTOR, - EditMessageMedia.CONSTRUCTOR, - EditMessageReplyMarkup.CONSTRUCTOR, - EditMessageSchedulingState.CONSTRUCTOR, - EditMessageText.CONSTRUCTOR, - EditProxy.CONSTRUCTOR, - EditQuickReplyMessage.CONSTRUCTOR, - EditStarSubscription.CONSTRUCTOR, - EditStory.CONSTRUCTOR, - EditStoryCover.CONSTRUCTOR, - EditUserStarSubscription.CONSTRUCTOR, - EnableProxy.CONSTRUCTOR, - EncryptGroupCallData.CONSTRUCTOR, - EndGroupCall.CONSTRUCTOR, - EndGroupCallRecording.CONSTRUCTOR, - EndGroupCallScreenSharing.CONSTRUCTOR, - FinishFileGeneration.CONSTRUCTOR, - ForwardMessages.CONSTRUCTOR, - GetAccountTtl.CONSTRUCTOR, - GetActiveSessions.CONSTRUCTOR, - GetAllPassportElements.CONSTRUCTOR, - GetAllStickerEmojis.CONSTRUCTOR, - GetAnimatedEmoji.CONSTRUCTOR, - GetApplicationConfig.CONSTRUCTOR, - GetApplicationDownloadLink.CONSTRUCTOR, - GetArchiveChatListSettings.CONSTRUCTOR, - GetArchivedStickerSets.CONSTRUCTOR, - GetAttachedStickerSets.CONSTRUCTOR, - GetAttachmentMenuBot.CONSTRUCTOR, - GetAuthenticationPasskeyParameters.CONSTRUCTOR, - GetAuthorizationState.CONSTRUCTOR, - GetAutoDownloadSettingsPresets.CONSTRUCTOR, - GetAutosaveSettings.CONSTRUCTOR, - GetAvailableChatBoostSlots.CONSTRUCTOR, - GetAvailableGifts.CONSTRUCTOR, - GetBackgroundUrl.CONSTRUCTOR, - GetBankCardInfo.CONSTRUCTOR, - GetBasicGroup.CONSTRUCTOR, - GetBasicGroupFullInfo.CONSTRUCTOR, - GetBlockedMessageSenders.CONSTRUCTOR, - GetBotInfoDescription.CONSTRUCTOR, - GetBotInfoShortDescription.CONSTRUCTOR, - GetBotMediaPreviewInfo.CONSTRUCTOR, - GetBotMediaPreviews.CONSTRUCTOR, - GetBotName.CONSTRUCTOR, - GetBotSimilarBotCount.CONSTRUCTOR, - GetBotSimilarBots.CONSTRUCTOR, - GetBusinessAccountStarAmount.CONSTRUCTOR, - GetBusinessChatLinkInfo.CONSTRUCTOR, - GetBusinessChatLinks.CONSTRUCTOR, - GetBusinessConnectedBot.CONSTRUCTOR, - GetBusinessConnection.CONSTRUCTOR, - GetBusinessFeatures.CONSTRUCTOR, - GetCallbackQueryAnswer.CONSTRUCTOR, - GetCallbackQueryMessage.CONSTRUCTOR, - GetChat.CONSTRUCTOR, - GetChatActiveStories.CONSTRUCTOR, - GetChatAdministrators.CONSTRUCTOR, - GetChatArchivedStories.CONSTRUCTOR, - GetChatAvailableMessageSenders.CONSTRUCTOR, - GetChatAvailablePaidMessageReactionSenders.CONSTRUCTOR, - GetChatBoostFeatures.CONSTRUCTOR, - GetChatBoostLevelFeatures.CONSTRUCTOR, - GetChatBoostLink.CONSTRUCTOR, - GetChatBoostLinkInfo.CONSTRUCTOR, - GetChatBoostStatus.CONSTRUCTOR, - GetChatBoosts.CONSTRUCTOR, - GetChatEventLog.CONSTRUCTOR, - GetChatFolder.CONSTRUCTOR, - GetChatFolderChatCount.CONSTRUCTOR, - GetChatFolderChatsToLeave.CONSTRUCTOR, - GetChatFolderDefaultIconName.CONSTRUCTOR, - GetChatFolderInviteLinks.CONSTRUCTOR, - GetChatFolderNewChats.CONSTRUCTOR, - GetChatHistory.CONSTRUCTOR, - GetChatInviteLink.CONSTRUCTOR, - GetChatInviteLinkCounts.CONSTRUCTOR, - GetChatInviteLinkMembers.CONSTRUCTOR, - GetChatInviteLinks.CONSTRUCTOR, - GetChatJoinRequests.CONSTRUCTOR, - GetChatListsToAddChat.CONSTRUCTOR, - GetChatMember.CONSTRUCTOR, - GetChatMessageByDate.CONSTRUCTOR, - GetChatMessageCalendar.CONSTRUCTOR, - GetChatMessageCount.CONSTRUCTOR, - GetChatMessagePosition.CONSTRUCTOR, - GetChatNotificationSettingsExceptions.CONSTRUCTOR, - GetChatOwnerAfterLeaving.CONSTRUCTOR, - GetChatPinnedMessage.CONSTRUCTOR, - GetChatPostedToChatPageStories.CONSTRUCTOR, - GetChatRevenueStatistics.CONSTRUCTOR, - GetChatRevenueTransactions.CONSTRUCTOR, - GetChatRevenueWithdrawalUrl.CONSTRUCTOR, - GetChatScheduledMessages.CONSTRUCTOR, - GetChatSimilarChatCount.CONSTRUCTOR, - GetChatSimilarChats.CONSTRUCTOR, - GetChatSparseMessagePositions.CONSTRUCTOR, - GetChatSponsoredMessages.CONSTRUCTOR, - GetChatStatistics.CONSTRUCTOR, - GetChatStoryAlbums.CONSTRUCTOR, - GetChatStoryInteractions.CONSTRUCTOR, - GetChats.CONSTRUCTOR, - GetChatsForChatFolderInviteLink.CONSTRUCTOR, - GetChatsToPostStories.CONSTRUCTOR, - GetCloseFriends.CONSTRUCTOR, - GetCollectibleItemInfo.CONSTRUCTOR, - GetCommands.CONSTRUCTOR, - GetConnectedAffiliateProgram.CONSTRUCTOR, - GetConnectedAffiliatePrograms.CONSTRUCTOR, - GetConnectedWebsites.CONSTRUCTOR, - GetContacts.CONSTRUCTOR, - GetCountries.CONSTRUCTOR, - GetCountryCode.CONSTRUCTOR, - GetCountryFlagEmoji.CONSTRUCTOR, - GetCreatedPublicChats.CONSTRUCTOR, - GetCurrentState.CONSTRUCTOR, - GetCurrentWeather.CONSTRUCTOR, - GetCustomEmojiReactionAnimations.CONSTRUCTOR, - GetCustomEmojiStickers.CONSTRUCTOR, - GetDatabaseStatistics.CONSTRUCTOR, - GetDeepLinkInfo.CONSTRUCTOR, - GetDefaultBackgroundCustomEmojiStickers.CONSTRUCTOR, - GetDefaultChatEmojiStatuses.CONSTRUCTOR, - GetDefaultChatPhotoCustomEmojiStickers.CONSTRUCTOR, - GetDefaultEmojiStatuses.CONSTRUCTOR, - GetDefaultMessageAutoDeleteTime.CONSTRUCTOR, - GetDefaultProfilePhotoCustomEmojiStickers.CONSTRUCTOR, - GetDirectMessagesChatTopic.CONSTRUCTOR, - GetDirectMessagesChatTopicHistory.CONSTRUCTOR, - GetDirectMessagesChatTopicMessageByDate.CONSTRUCTOR, - GetDirectMessagesChatTopicRevenue.CONSTRUCTOR, - GetDisallowedChatEmojiStatuses.CONSTRUCTOR, - GetEmojiCategories.CONSTRUCTOR, - GetEmojiReaction.CONSTRUCTOR, - GetEmojiSuggestionsUrl.CONSTRUCTOR, - GetExternalLink.CONSTRUCTOR, - GetExternalLinkInfo.CONSTRUCTOR, - GetFavoriteStickers.CONSTRUCTOR, - GetFile.CONSTRUCTOR, - GetFileDownloadedPrefixSize.CONSTRUCTOR, - GetFileExtension.CONSTRUCTOR, - GetFileMimeType.CONSTRUCTOR, - GetForumTopic.CONSTRUCTOR, - GetForumTopicDefaultIcons.CONSTRUCTOR, - GetForumTopicHistory.CONSTRUCTOR, - GetForumTopicLink.CONSTRUCTOR, - GetForumTopics.CONSTRUCTOR, - GetGameHighScores.CONSTRUCTOR, - GetGiftAuctionAcquiredGifts.CONSTRUCTOR, - GetGiftAuctionState.CONSTRUCTOR, - GetGiftChatThemes.CONSTRUCTOR, - GetGiftCollections.CONSTRUCTOR, - GetGiftUpgradePreview.CONSTRUCTOR, - GetGiftsForCrafting.CONSTRUCTOR, - GetGiveawayInfo.CONSTRUCTOR, - GetGreetingStickers.CONSTRUCTOR, - GetGrossingWebAppBots.CONSTRUCTOR, - GetGroupCall.CONSTRUCTOR, - GetGroupCallParticipants.CONSTRUCTOR, - GetGroupCallStreamSegment.CONSTRUCTOR, - GetGroupCallStreams.CONSTRUCTOR, - GetGroupsInCommon.CONSTRUCTOR, - GetImportedContactCount.CONSTRUCTOR, - GetInactiveSupergroupChats.CONSTRUCTOR, - GetInlineGameHighScores.CONSTRUCTOR, - GetInlineQueryResults.CONSTRUCTOR, - GetInstalledBackgrounds.CONSTRUCTOR, - GetInstalledStickerSets.CONSTRUCTOR, - GetInternalLink.CONSTRUCTOR, - GetInternalLinkType.CONSTRUCTOR, - GetJsonString.CONSTRUCTOR, - GetJsonValue.CONSTRUCTOR, - GetKeywordEmojis.CONSTRUCTOR, - GetLanguagePackInfo.CONSTRUCTOR, - GetLanguagePackString.CONSTRUCTOR, - GetLanguagePackStrings.CONSTRUCTOR, - GetLinkPreview.CONSTRUCTOR, - GetLiveStoryAvailableMessageSenders.CONSTRUCTOR, - GetLiveStoryRtmpUrl.CONSTRUCTOR, - GetLiveStoryStreamer.CONSTRUCTOR, - GetLiveStoryTopDonors.CONSTRUCTOR, - GetLocalizationTargetInfo.CONSTRUCTOR, - GetLogStream.CONSTRUCTOR, - GetLogTagVerbosityLevel.CONSTRUCTOR, - GetLogTags.CONSTRUCTOR, - GetLogVerbosityLevel.CONSTRUCTOR, - GetLoginPasskeys.CONSTRUCTOR, - GetLoginUrl.CONSTRUCTOR, - GetLoginUrlInfo.CONSTRUCTOR, - GetMainWebApp.CONSTRUCTOR, - GetMapThumbnailFile.CONSTRUCTOR, - GetMarkdownText.CONSTRUCTOR, - GetMe.CONSTRUCTOR, - GetMenuButton.CONSTRUCTOR, - GetMessage.CONSTRUCTOR, - GetMessageAddedReactions.CONSTRUCTOR, - GetMessageAuthor.CONSTRUCTOR, - GetMessageAvailableReactions.CONSTRUCTOR, - GetMessageEffect.CONSTRUCTOR, - GetMessageEmbeddingCode.CONSTRUCTOR, - GetMessageFileType.CONSTRUCTOR, - GetMessageImportConfirmationText.CONSTRUCTOR, - GetMessageLink.CONSTRUCTOR, - GetMessageLinkInfo.CONSTRUCTOR, - GetMessageLocally.CONSTRUCTOR, - GetMessageProperties.CONSTRUCTOR, - GetMessagePublicForwards.CONSTRUCTOR, - GetMessageReadDate.CONSTRUCTOR, - GetMessageStatistics.CONSTRUCTOR, - GetMessageThread.CONSTRUCTOR, - GetMessageThreadHistory.CONSTRUCTOR, - GetMessageViewers.CONSTRUCTOR, - GetMessages.CONSTRUCTOR, - GetNetworkStatistics.CONSTRUCTOR, - GetNewChatPrivacySettings.CONSTRUCTOR, - GetOauthLinkInfo.CONSTRUCTOR, - GetOption.CONSTRUCTOR, - GetOwnedBots.CONSTRUCTOR, - GetOwnedStickerSets.CONSTRUCTOR, - GetPaidMessageRevenue.CONSTRUCTOR, - GetPasskeyParameters.CONSTRUCTOR, - GetPassportAuthorizationForm.CONSTRUCTOR, - GetPassportAuthorizationFormAvailableElements.CONSTRUCTOR, - GetPassportElement.CONSTRUCTOR, - GetPasswordState.CONSTRUCTOR, - GetPaymentForm.CONSTRUCTOR, - GetPaymentReceipt.CONSTRUCTOR, - GetPhoneNumberInfo.CONSTRUCTOR, - GetPhoneNumberInfoSync.CONSTRUCTOR, - GetPollVoters.CONSTRUCTOR, - GetPreferredCountryLanguage.CONSTRUCTOR, - GetPremiumFeatures.CONSTRUCTOR, - GetPremiumGiftPaymentOptions.CONSTRUCTOR, - GetPremiumGiveawayPaymentOptions.CONSTRUCTOR, - GetPremiumInfoSticker.CONSTRUCTOR, - GetPremiumLimit.CONSTRUCTOR, - GetPremiumState.CONSTRUCTOR, - GetPremiumStickerExamples.CONSTRUCTOR, - GetPremiumStickers.CONSTRUCTOR, - GetPreparedInlineMessage.CONSTRUCTOR, - GetProxies.CONSTRUCTOR, - GetPublicPostSearchLimits.CONSTRUCTOR, - GetPushReceiverId.CONSTRUCTOR, - GetReadDatePrivacySettings.CONSTRUCTOR, - GetReceivedGift.CONSTRUCTOR, - GetReceivedGifts.CONSTRUCTOR, - GetRecentEmojiStatuses.CONSTRUCTOR, - GetRecentInlineBots.CONSTRUCTOR, - GetRecentStickers.CONSTRUCTOR, - GetRecentlyOpenedChats.CONSTRUCTOR, - GetRecentlyVisitedTMeUrls.CONSTRUCTOR, - GetRecommendedChatFolders.CONSTRUCTOR, - GetRecommendedChats.CONSTRUCTOR, - GetRecoveryEmailAddress.CONSTRUCTOR, - GetRemoteFile.CONSTRUCTOR, - GetRepliedMessage.CONSTRUCTOR, - GetSavedAnimations.CONSTRUCTOR, - GetSavedMessagesTags.CONSTRUCTOR, - GetSavedMessagesTopicHistory.CONSTRUCTOR, - GetSavedMessagesTopicMessageByDate.CONSTRUCTOR, - GetSavedNotificationSound.CONSTRUCTOR, - GetSavedNotificationSounds.CONSTRUCTOR, - GetSavedOrderInfo.CONSTRUCTOR, - GetScopeNotificationSettings.CONSTRUCTOR, - GetSearchSponsoredChats.CONSTRUCTOR, - GetSearchedForTags.CONSTRUCTOR, - GetSecretChat.CONSTRUCTOR, - GetStakeDiceState.CONSTRUCTOR, - GetStarAdAccountUrl.CONSTRUCTOR, - GetStarGiftPaymentOptions.CONSTRUCTOR, - GetStarGiveawayPaymentOptions.CONSTRUCTOR, - GetStarPaymentOptions.CONSTRUCTOR, - GetStarRevenueStatistics.CONSTRUCTOR, - GetStarSubscriptions.CONSTRUCTOR, - GetStarTransactions.CONSTRUCTOR, - GetStarWithdrawalUrl.CONSTRUCTOR, - GetStatisticalGraph.CONSTRUCTOR, - GetStickerEmojis.CONSTRUCTOR, - GetStickerOutline.CONSTRUCTOR, - GetStickerOutlineSvgPath.CONSTRUCTOR, - GetStickerSet.CONSTRUCTOR, - GetStickerSetName.CONSTRUCTOR, - GetStickers.CONSTRUCTOR, - GetStorageStatistics.CONSTRUCTOR, - GetStorageStatisticsFast.CONSTRUCTOR, - GetStory.CONSTRUCTOR, - GetStoryAlbumStories.CONSTRUCTOR, - GetStoryAvailableReactions.CONSTRUCTOR, - GetStoryInteractions.CONSTRUCTOR, - GetStoryNotificationSettingsExceptions.CONSTRUCTOR, - GetStoryPublicForwards.CONSTRUCTOR, - GetStoryStatistics.CONSTRUCTOR, - GetSuggestedFileName.CONSTRUCTOR, - GetSuggestedStickerSetName.CONSTRUCTOR, - GetSuitableDiscussionChats.CONSTRUCTOR, - GetSuitablePersonalChats.CONSTRUCTOR, - GetSupergroup.CONSTRUCTOR, - GetSupergroupFullInfo.CONSTRUCTOR, - GetSupergroupMembers.CONSTRUCTOR, - GetSupportName.CONSTRUCTOR, - GetSupportUser.CONSTRUCTOR, - GetTemporaryPasswordState.CONSTRUCTOR, - GetTextEntities.CONSTRUCTOR, - GetThemeParametersJsonString.CONSTRUCTOR, - GetThemedChatEmojiStatuses.CONSTRUCTOR, - GetThemedEmojiStatuses.CONSTRUCTOR, - GetTimeZones.CONSTRUCTOR, - GetTonRevenueStatistics.CONSTRUCTOR, - GetTonTransactions.CONSTRUCTOR, - GetTonWithdrawalUrl.CONSTRUCTOR, - GetTopChats.CONSTRUCTOR, - GetTrendingStickerSets.CONSTRUCTOR, - GetUpgradedGift.CONSTRUCTOR, - GetUpgradedGiftEmojiStatuses.CONSTRUCTOR, - GetUpgradedGiftValueInfo.CONSTRUCTOR, - GetUpgradedGiftVariants.CONSTRUCTOR, - GetUpgradedGiftWithdrawalUrl.CONSTRUCTOR, - GetUpgradedGiftsPromotionalAnimation.CONSTRUCTOR, - GetUser.CONSTRUCTOR, - GetUserChatBoosts.CONSTRUCTOR, - GetUserFullInfo.CONSTRUCTOR, - GetUserLink.CONSTRUCTOR, - GetUserPrivacySettingRules.CONSTRUCTOR, - GetUserProfileAudios.CONSTRUCTOR, - GetUserProfilePhotos.CONSTRUCTOR, - GetUserSupportInfo.CONSTRUCTOR, - GetVideoChatAvailableParticipants.CONSTRUCTOR, - GetVideoChatInviteLink.CONSTRUCTOR, - GetVideoChatRtmpUrl.CONSTRUCTOR, - GetVideoMessageAdvertisements.CONSTRUCTOR, - GetWebAppLinkUrl.CONSTRUCTOR, - GetWebAppPlaceholder.CONSTRUCTOR, - GetWebAppUrl.CONSTRUCTOR, - GetWebPageInstantView.CONSTRUCTOR, - GiftPremiumWithStars.CONSTRUCTOR, - HideContactCloseBirthdays.CONSTRUCTOR, - HideSuggestedAction.CONSTRUCTOR, - ImportContacts.CONSTRUCTOR, - ImportMessages.CONSTRUCTOR, - IncreaseGiftAuctionBid.CONSTRUCTOR, - InviteGroupCallParticipant.CONSTRUCTOR, - InviteVideoChatParticipants.CONSTRUCTOR, - IsLoginEmailAddressRequired.CONSTRUCTOR, - IsProfileAudio.CONSTRUCTOR, - JoinChat.CONSTRUCTOR, - JoinChatByInviteLink.CONSTRUCTOR, - JoinGroupCall.CONSTRUCTOR, - JoinLiveStory.CONSTRUCTOR, - JoinVideoChat.CONSTRUCTOR, - LaunchPrepaidGiveaway.CONSTRUCTOR, - LeaveChat.CONSTRUCTOR, - LeaveGroupCall.CONSTRUCTOR, - LoadActiveStories.CONSTRUCTOR, - LoadChats.CONSTRUCTOR, - LoadDirectMessagesChatTopics.CONSTRUCTOR, - LoadGroupCallParticipants.CONSTRUCTOR, - LoadQuickReplyShortcutMessages.CONSTRUCTOR, - LoadQuickReplyShortcuts.CONSTRUCTOR, - LoadSavedMessagesTopics.CONSTRUCTOR, - LogOut.CONSTRUCTOR, - MarkChecklistTasksAsDone.CONSTRUCTOR, - OpenBotSimilarBot.CONSTRUCTOR, - OpenChat.CONSTRUCTOR, - OpenChatSimilarChat.CONSTRUCTOR, - OpenGiftAuction.CONSTRUCTOR, - OpenMessageContent.CONSTRUCTOR, - OpenSponsoredChat.CONSTRUCTOR, - OpenStory.CONSTRUCTOR, - OpenWebApp.CONSTRUCTOR, - OptimizeStorage.CONSTRUCTOR, - ParseMarkdown.CONSTRUCTOR, - ParseTextEntities.CONSTRUCTOR, - PinChatMessage.CONSTRUCTOR, - PingProxy.CONSTRUCTOR, - PlaceGiftAuctionBid.CONSTRUCTOR, - PostStory.CONSTRUCTOR, - PreliminaryUploadFile.CONSTRUCTOR, - ProcessChatFolderNewChats.CONSTRUCTOR, - ProcessChatHasProtectedContentDisableRequest.CONSTRUCTOR, - ProcessChatJoinRequest.CONSTRUCTOR, - ProcessChatJoinRequests.CONSTRUCTOR, - ProcessGiftPurchaseOffer.CONSTRUCTOR, - ProcessPushNotification.CONSTRUCTOR, - RateSpeechRecognition.CONSTRUCTOR, - ReadAllChatMentions.CONSTRUCTOR, - ReadAllChatReactions.CONSTRUCTOR, - ReadAllDirectMessagesChatTopicReactions.CONSTRUCTOR, - ReadAllForumTopicMentions.CONSTRUCTOR, - ReadAllForumTopicReactions.CONSTRUCTOR, - ReadBusinessMessage.CONSTRUCTOR, - ReadChatList.CONSTRUCTOR, - ReadFilePart.CONSTRUCTOR, - ReaddQuickReplyShortcutMessages.CONSTRUCTOR, - RecognizeSpeech.CONSTRUCTOR, - RecoverAuthenticationPassword.CONSTRUCTOR, - RecoverPassword.CONSTRUCTOR, - RefundStarPayment.CONSTRUCTOR, - RegisterDevice.CONSTRUCTOR, - RegisterUser.CONSTRUCTOR, - RemoveAllFilesFromDownloads.CONSTRUCTOR, - RemoveBusinessConnectedBotFromChat.CONSTRUCTOR, - RemoveChatActionBar.CONSTRUCTOR, - RemoveContacts.CONSTRUCTOR, - RemoveFavoriteSticker.CONSTRUCTOR, - RemoveFileFromDownloads.CONSTRUCTOR, - RemoveGiftCollectionGifts.CONSTRUCTOR, - RemoveInstalledBackground.CONSTRUCTOR, - RemoveLoginPasskey.CONSTRUCTOR, - RemoveMessageReaction.CONSTRUCTOR, - RemoveMessageSenderBotVerification.CONSTRUCTOR, - RemoveNotification.CONSTRUCTOR, - RemoveNotificationGroup.CONSTRUCTOR, - RemovePendingLiveStoryReactions.CONSTRUCTOR, - RemovePendingPaidMessageReactions.CONSTRUCTOR, - RemoveProfileAudio.CONSTRUCTOR, - RemoveProxy.CONSTRUCTOR, - RemoveRecentHashtag.CONSTRUCTOR, - RemoveRecentSticker.CONSTRUCTOR, - RemoveRecentlyFoundChat.CONSTRUCTOR, - RemoveSavedAnimation.CONSTRUCTOR, - RemoveSavedNotificationSound.CONSTRUCTOR, - RemoveSearchedForTag.CONSTRUCTOR, - RemoveStickerFromSet.CONSTRUCTOR, - RemoveStoryAlbumStories.CONSTRUCTOR, - RemoveTopChat.CONSTRUCTOR, - ReorderActiveUsernames.CONSTRUCTOR, - ReorderBotActiveUsernames.CONSTRUCTOR, - ReorderBotMediaPreviews.CONSTRUCTOR, - ReorderChatFolders.CONSTRUCTOR, - ReorderGiftCollectionGifts.CONSTRUCTOR, - ReorderGiftCollections.CONSTRUCTOR, - ReorderInstalledStickerSets.CONSTRUCTOR, - ReorderQuickReplyShortcuts.CONSTRUCTOR, - ReorderStoryAlbumStories.CONSTRUCTOR, - ReorderStoryAlbums.CONSTRUCTOR, - ReorderSupergroupActiveUsernames.CONSTRUCTOR, - ReplaceLiveStoryRtmpUrl.CONSTRUCTOR, - ReplacePrimaryChatInviteLink.CONSTRUCTOR, - ReplaceStickerInSet.CONSTRUCTOR, - ReplaceVideoChatRtmpUrl.CONSTRUCTOR, - ReportAuthenticationCodeMissing.CONSTRUCTOR, - ReportChat.CONSTRUCTOR, - ReportChatPhoto.CONSTRUCTOR, - ReportChatSponsoredMessage.CONSTRUCTOR, - ReportMessageReactions.CONSTRUCTOR, - ReportPhoneNumberCodeMissing.CONSTRUCTOR, - ReportSponsoredChat.CONSTRUCTOR, - ReportStory.CONSTRUCTOR, - ReportSupergroupAntiSpamFalsePositive.CONSTRUCTOR, - ReportSupergroupSpam.CONSTRUCTOR, - ReportVideoMessageAdvertisement.CONSTRUCTOR, - RequestAuthenticationPasswordRecovery.CONSTRUCTOR, - RequestPasswordRecovery.CONSTRUCTOR, - RequestQrCodeAuthentication.CONSTRUCTOR, - ResendAuthenticationCode.CONSTRUCTOR, - ResendEmailAddressVerificationCode.CONSTRUCTOR, - ResendLoginEmailAddressCode.CONSTRUCTOR, - ResendMessages.CONSTRUCTOR, - ResendPhoneNumberCode.CONSTRUCTOR, - ResendRecoveryEmailAddressCode.CONSTRUCTOR, - ResetAllNotificationSettings.CONSTRUCTOR, - ResetAuthenticationEmailAddress.CONSTRUCTOR, - ResetInstalledBackgrounds.CONSTRUCTOR, - ResetNetworkStatistics.CONSTRUCTOR, - ResetPassword.CONSTRUCTOR, - ReuseStarSubscription.CONSTRUCTOR, - RevokeChatInviteLink.CONSTRUCTOR, - RevokeGroupCallInviteLink.CONSTRUCTOR, - SaveApplicationLogEvent.CONSTRUCTOR, - SavePreparedInlineMessage.CONSTRUCTOR, - SearchAffiliatePrograms.CONSTRUCTOR, - SearchBackground.CONSTRUCTOR, - SearchCallMessages.CONSTRUCTOR, - SearchChatAffiliateProgram.CONSTRUCTOR, - SearchChatMembers.CONSTRUCTOR, - SearchChatMessages.CONSTRUCTOR, - SearchChatRecentLocationMessages.CONSTRUCTOR, - SearchChats.CONSTRUCTOR, - SearchChatsOnServer.CONSTRUCTOR, - SearchContacts.CONSTRUCTOR, - SearchEmojis.CONSTRUCTOR, - SearchFileDownloads.CONSTRUCTOR, - SearchGiftsForResale.CONSTRUCTOR, - SearchHashtags.CONSTRUCTOR, - SearchInstalledStickerSets.CONSTRUCTOR, - SearchMessages.CONSTRUCTOR, - SearchOutgoingDocumentMessages.CONSTRUCTOR, - SearchPublicChat.CONSTRUCTOR, - SearchPublicChats.CONSTRUCTOR, - SearchPublicMessagesByTag.CONSTRUCTOR, - SearchPublicPosts.CONSTRUCTOR, - SearchPublicStoriesByLocation.CONSTRUCTOR, - SearchPublicStoriesByTag.CONSTRUCTOR, - SearchPublicStoriesByVenue.CONSTRUCTOR, - SearchQuote.CONSTRUCTOR, - SearchRecentlyFoundChats.CONSTRUCTOR, - SearchSavedMessages.CONSTRUCTOR, - SearchSecretMessages.CONSTRUCTOR, - SearchStickerSet.CONSTRUCTOR, - SearchStickerSets.CONSTRUCTOR, - SearchStickers.CONSTRUCTOR, - SearchStringsByPrefix.CONSTRUCTOR, - SearchUserByPhoneNumber.CONSTRUCTOR, - SearchUserByToken.CONSTRUCTOR, - SearchWebApp.CONSTRUCTOR, - SellGift.CONSTRUCTOR, - SendAuthenticationFirebaseSms.CONSTRUCTOR, - SendBotStartMessage.CONSTRUCTOR, - SendBusinessMessage.CONSTRUCTOR, - SendBusinessMessageAlbum.CONSTRUCTOR, - SendCallDebugInformation.CONSTRUCTOR, - SendCallLog.CONSTRUCTOR, - SendCallRating.CONSTRUCTOR, - SendCallSignalingData.CONSTRUCTOR, - SendChatAction.CONSTRUCTOR, - SendCustomRequest.CONSTRUCTOR, - SendEmailAddressVerificationCode.CONSTRUCTOR, - SendGift.CONSTRUCTOR, - SendGiftPurchaseOffer.CONSTRUCTOR, - SendGroupCallMessage.CONSTRUCTOR, - SendInlineQueryResultMessage.CONSTRUCTOR, - SendMessage.CONSTRUCTOR, - SendMessageAlbum.CONSTRUCTOR, - SendPassportAuthorizationForm.CONSTRUCTOR, - SendPaymentForm.CONSTRUCTOR, - SendPhoneNumberCode.CONSTRUCTOR, - SendPhoneNumberFirebaseSms.CONSTRUCTOR, - SendQuickReplyShortcutMessages.CONSTRUCTOR, - SendResoldGift.CONSTRUCTOR, - SendTextMessageDraft.CONSTRUCTOR, - SendWebAppCustomRequest.CONSTRUCTOR, - SendWebAppData.CONSTRUCTOR, - SetAccentColor.CONSTRUCTOR, - SetAccountTtl.CONSTRUCTOR, - SetAlarm.CONSTRUCTOR, - SetApplicationVerificationToken.CONSTRUCTOR, - SetArchiveChatListSettings.CONSTRUCTOR, - SetAuthenticationEmailAddress.CONSTRUCTOR, - SetAuthenticationPhoneNumber.CONSTRUCTOR, - SetAuthenticationPremiumPurchaseTransaction.CONSTRUCTOR, - SetAutoDownloadSettings.CONSTRUCTOR, - SetAutosaveSettings.CONSTRUCTOR, - SetBio.CONSTRUCTOR, - SetBirthdate.CONSTRUCTOR, - SetBotInfoDescription.CONSTRUCTOR, - SetBotInfoShortDescription.CONSTRUCTOR, - SetBotName.CONSTRUCTOR, - SetBotProfilePhoto.CONSTRUCTOR, - SetBotUpdatesStatus.CONSTRUCTOR, - SetBusinessAccountBio.CONSTRUCTOR, - SetBusinessAccountGiftSettings.CONSTRUCTOR, - SetBusinessAccountName.CONSTRUCTOR, - SetBusinessAccountProfilePhoto.CONSTRUCTOR, - SetBusinessAccountUsername.CONSTRUCTOR, - SetBusinessAwayMessageSettings.CONSTRUCTOR, - SetBusinessConnectedBot.CONSTRUCTOR, - SetBusinessGreetingMessageSettings.CONSTRUCTOR, - SetBusinessLocation.CONSTRUCTOR, - SetBusinessMessageIsPinned.CONSTRUCTOR, - SetBusinessOpeningHours.CONSTRUCTOR, - SetBusinessStartPage.CONSTRUCTOR, - SetChatAccentColor.CONSTRUCTOR, - SetChatActiveStoriesList.CONSTRUCTOR, - SetChatAffiliateProgram.CONSTRUCTOR, - SetChatAvailableReactions.CONSTRUCTOR, - SetChatBackground.CONSTRUCTOR, - SetChatClientData.CONSTRUCTOR, - SetChatDescription.CONSTRUCTOR, - SetChatDirectMessagesGroup.CONSTRUCTOR, - SetChatDiscussionGroup.CONSTRUCTOR, - SetChatDraftMessage.CONSTRUCTOR, - SetChatEmojiStatus.CONSTRUCTOR, - SetChatLocation.CONSTRUCTOR, - SetChatMemberStatus.CONSTRUCTOR, - SetChatMemberTag.CONSTRUCTOR, - SetChatMessageAutoDeleteTime.CONSTRUCTOR, - SetChatMessageSender.CONSTRUCTOR, - SetChatNotificationSettings.CONSTRUCTOR, - SetChatPaidMessageStarCount.CONSTRUCTOR, - SetChatPermissions.CONSTRUCTOR, - SetChatPhoto.CONSTRUCTOR, - SetChatPinnedStories.CONSTRUCTOR, - SetChatProfileAccentColor.CONSTRUCTOR, - SetChatSlowModeDelay.CONSTRUCTOR, - SetChatTheme.CONSTRUCTOR, - SetChatTitle.CONSTRUCTOR, - SetCloseFriends.CONSTRUCTOR, - SetCommands.CONSTRUCTOR, - SetCustomEmojiStickerSetThumbnail.CONSTRUCTOR, - SetCustomLanguagePack.CONSTRUCTOR, - SetCustomLanguagePackString.CONSTRUCTOR, - SetDatabaseEncryptionKey.CONSTRUCTOR, - SetDefaultBackground.CONSTRUCTOR, - SetDefaultChannelAdministratorRights.CONSTRUCTOR, - SetDefaultGroupAdministratorRights.CONSTRUCTOR, - SetDefaultMessageAutoDeleteTime.CONSTRUCTOR, - SetDefaultReactionType.CONSTRUCTOR, - SetDirectMessagesChatTopicIsMarkedAsUnread.CONSTRUCTOR, - SetEmojiStatus.CONSTRUCTOR, - SetFileGenerationProgress.CONSTRUCTOR, - SetForumTopicNotificationSettings.CONSTRUCTOR, - SetGameScore.CONSTRUCTOR, - SetGiftCollectionName.CONSTRUCTOR, - SetGiftResalePrice.CONSTRUCTOR, - SetGiftSettings.CONSTRUCTOR, - SetGroupCallPaidMessageStarCount.CONSTRUCTOR, - SetGroupCallParticipantIsSpeaking.CONSTRUCTOR, - SetGroupCallParticipantVolumeLevel.CONSTRUCTOR, - SetInactiveSessionTtl.CONSTRUCTOR, - SetInlineGameScore.CONSTRUCTOR, - SetLiveStoryMessageSender.CONSTRUCTOR, - SetLogStream.CONSTRUCTOR, - SetLogTagVerbosityLevel.CONSTRUCTOR, - SetLogVerbosityLevel.CONSTRUCTOR, - SetLoginEmailAddress.CONSTRUCTOR, - SetMainProfileTab.CONSTRUCTOR, - SetMenuButton.CONSTRUCTOR, - SetMessageFactCheck.CONSTRUCTOR, - SetMessageReactions.CONSTRUCTOR, - SetMessageSenderBlockList.CONSTRUCTOR, - SetMessageSenderBotVerification.CONSTRUCTOR, - SetName.CONSTRUCTOR, - SetNetworkType.CONSTRUCTOR, - SetNewChatPrivacySettings.CONSTRUCTOR, - SetOption.CONSTRUCTOR, - SetPaidMessageReactionType.CONSTRUCTOR, - SetPassportElement.CONSTRUCTOR, - SetPassportElementErrors.CONSTRUCTOR, - SetPassword.CONSTRUCTOR, - SetPersonalChat.CONSTRUCTOR, - SetPinnedChats.CONSTRUCTOR, - SetPinnedForumTopics.CONSTRUCTOR, - SetPinnedGifts.CONSTRUCTOR, - SetPinnedSavedMessagesTopics.CONSTRUCTOR, - SetPollAnswer.CONSTRUCTOR, - SetProfileAccentColor.CONSTRUCTOR, - SetProfileAudioPosition.CONSTRUCTOR, - SetProfilePhoto.CONSTRUCTOR, - SetQuickReplyShortcutName.CONSTRUCTOR, - SetReactionNotificationSettings.CONSTRUCTOR, - SetReadDatePrivacySettings.CONSTRUCTOR, - SetRecoveryEmailAddress.CONSTRUCTOR, - SetSavedMessagesTagLabel.CONSTRUCTOR, - SetScopeNotificationSettings.CONSTRUCTOR, - SetStickerEmojis.CONSTRUCTOR, - SetStickerKeywords.CONSTRUCTOR, - SetStickerMaskPosition.CONSTRUCTOR, - SetStickerPositionInSet.CONSTRUCTOR, - SetStickerSetThumbnail.CONSTRUCTOR, - SetStickerSetTitle.CONSTRUCTOR, - SetStoryAlbumName.CONSTRUCTOR, - SetStoryPrivacySettings.CONSTRUCTOR, - SetStoryReaction.CONSTRUCTOR, - SetSupergroupCustomEmojiStickerSet.CONSTRUCTOR, - SetSupergroupMainProfileTab.CONSTRUCTOR, - SetSupergroupStickerSet.CONSTRUCTOR, - SetSupergroupUnrestrictBoostCount.CONSTRUCTOR, - SetSupergroupUsername.CONSTRUCTOR, - SetTdlibParameters.CONSTRUCTOR, - SetUpgradedGiftColors.CONSTRUCTOR, - SetUserEmojiStatus.CONSTRUCTOR, - SetUserNote.CONSTRUCTOR, - SetUserPersonalProfilePhoto.CONSTRUCTOR, - SetUserPrivacySettingRules.CONSTRUCTOR, - SetUserSupportInfo.CONSTRUCTOR, - SetUsername.CONSTRUCTOR, - SetVideoChatDefaultParticipant.CONSTRUCTOR, - SetVideoChatTitle.CONSTRUCTOR, - ShareChatWithBot.CONSTRUCTOR, - SharePhoneNumber.CONSTRUCTOR, - ShareUsersWithBot.CONSTRUCTOR, - StartGroupCallRecording.CONSTRUCTOR, - StartGroupCallScreenSharing.CONSTRUCTOR, - StartLiveStory.CONSTRUCTOR, - StartScheduledVideoChat.CONSTRUCTOR, - StopBusinessPoll.CONSTRUCTOR, - StopPoll.CONSTRUCTOR, - SuggestUserBirthdate.CONSTRUCTOR, - SuggestUserProfilePhoto.CONSTRUCTOR, - SummarizeMessage.CONSTRUCTOR, - SynchronizeLanguagePack.CONSTRUCTOR, - TerminateAllOtherSessions.CONSTRUCTOR, - TerminateSession.CONSTRUCTOR, - TestCallBytes.CONSTRUCTOR, - TestCallEmpty.CONSTRUCTOR, - TestCallString.CONSTRUCTOR, - TestCallVectorInt.CONSTRUCTOR, - TestCallVectorIntObject.CONSTRUCTOR, - TestCallVectorString.CONSTRUCTOR, - TestCallVectorStringObject.CONSTRUCTOR, - TestGetDifference.CONSTRUCTOR, - TestNetwork.CONSTRUCTOR, - TestProxy.CONSTRUCTOR, - TestReturnError.CONSTRUCTOR, - TestSquareInt.CONSTRUCTOR, - TestUseUpdate.CONSTRUCTOR, - ToggleAllDownloadsArePaused.CONSTRUCTOR, - ToggleBotCanManageEmojiStatus.CONSTRUCTOR, - ToggleBotIsAddedToAttachmentMenu.CONSTRUCTOR, - ToggleBotUsernameIsActive.CONSTRUCTOR, - ToggleBusinessConnectedBotChatIsPaused.CONSTRUCTOR, - ToggleChatDefaultDisableNotification.CONSTRUCTOR, - ToggleChatFolderTags.CONSTRUCTOR, - ToggleChatGiftNotifications.CONSTRUCTOR, - ToggleChatHasProtectedContent.CONSTRUCTOR, - ToggleChatIsMarkedAsUnread.CONSTRUCTOR, - ToggleChatIsPinned.CONSTRUCTOR, - ToggleChatIsTranslatable.CONSTRUCTOR, - ToggleChatViewAsTopics.CONSTRUCTOR, - ToggleDirectMessagesChatTopicCanSendUnpaidMessages.CONSTRUCTOR, - ToggleDownloadIsPaused.CONSTRUCTOR, - ToggleForumTopicIsClosed.CONSTRUCTOR, - ToggleForumTopicIsPinned.CONSTRUCTOR, - ToggleGeneralForumTopicIsHidden.CONSTRUCTOR, - ToggleGiftIsSaved.CONSTRUCTOR, - ToggleGroupCallAreMessagesAllowed.CONSTRUCTOR, - ToggleGroupCallIsMyVideoEnabled.CONSTRUCTOR, - ToggleGroupCallIsMyVideoPaused.CONSTRUCTOR, - ToggleGroupCallParticipantIsHandRaised.CONSTRUCTOR, - ToggleGroupCallParticipantIsMuted.CONSTRUCTOR, - ToggleGroupCallScreenSharingIsPaused.CONSTRUCTOR, - ToggleHasSponsoredMessagesEnabled.CONSTRUCTOR, - ToggleSavedMessagesTopicIsPinned.CONSTRUCTOR, - ToggleSessionCanAcceptCalls.CONSTRUCTOR, - ToggleSessionCanAcceptSecretChats.CONSTRUCTOR, - ToggleStoryIsPostedToChatPage.CONSTRUCTOR, - ToggleSupergroupCanHaveSponsoredMessages.CONSTRUCTOR, - ToggleSupergroupHasAggressiveAntiSpamEnabled.CONSTRUCTOR, - ToggleSupergroupHasAutomaticTranslation.CONSTRUCTOR, - ToggleSupergroupHasHiddenMembers.CONSTRUCTOR, - ToggleSupergroupIsAllHistoryAvailable.CONSTRUCTOR, - ToggleSupergroupIsBroadcastGroup.CONSTRUCTOR, - ToggleSupergroupIsForum.CONSTRUCTOR, - ToggleSupergroupJoinByRequest.CONSTRUCTOR, - ToggleSupergroupJoinToSendMessages.CONSTRUCTOR, - ToggleSupergroupSignMessages.CONSTRUCTOR, - ToggleSupergroupUsernameIsActive.CONSTRUCTOR, - ToggleUsernameIsActive.CONSTRUCTOR, - ToggleVideoChatEnabledStartNotification.CONSTRUCTOR, - ToggleVideoChatMuteNewParticipants.CONSTRUCTOR, - TransferBusinessAccountStars.CONSTRUCTOR, - TransferChatOwnership.CONSTRUCTOR, - TransferGift.CONSTRUCTOR, - TranslateMessageText.CONSTRUCTOR, - TranslateText.CONSTRUCTOR, - UnpinAllChatMessages.CONSTRUCTOR, - UnpinAllDirectMessagesChatTopicMessages.CONSTRUCTOR, - UnpinAllForumTopicMessages.CONSTRUCTOR, - UnpinChatMessage.CONSTRUCTOR, - UpgradeBasicGroupChatToSupergroupChat.CONSTRUCTOR, - UpgradeGift.CONSTRUCTOR, - UploadStickerFile.CONSTRUCTOR, - ValidateOrderInfo.CONSTRUCTOR, - ViewMessages.CONSTRUCTOR, - ViewPremiumFeature.CONSTRUCTOR, - ViewSponsoredChat.CONSTRUCTOR, - ViewTrendingStickerSets.CONSTRUCTOR, - ViewVideoMessageAdvertisement.CONSTRUCTOR, - WriteGeneratedFilePart.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default Function constructor. - */ - public Function() { - } - - /** - * Returns a string representation of the object. - * - * @return a string representation of the object. - */ - public native String toString(); - } - - /** - * Contains information about supported accent color for user/chat name, background of empty chat photo, replies to messages and link previews. - */ - public static class AccentColor extends Object { - /** - * Accent color identifier. - */ - public int id; - /** - * Identifier of a built-in color to use in places, where only one color is needed; 0-6. - */ - public int builtInAccentColorId; - /** - * The list of 1-3 colors in RGB format, describing the accent color, as expected to be shown in light themes. - */ - public int[] lightThemeColors; - /** - * The list of 1-3 colors in RGB format, describing the accent color, as expected to be shown in dark themes. - */ - public int[] darkThemeColors; - /** - * The minimum chat boost level required to use the color in a channel chat. - */ - public int minChannelChatBoostLevel; - - /** - * Contains information about supported accent color for user/chat name, background of empty chat photo, replies to messages and link previews. - */ - public AccentColor() { - } - - /** - * Contains information about supported accent color for user/chat name, background of empty chat photo, replies to messages and link previews. - * - * @param id Accent color identifier. - * @param builtInAccentColorId Identifier of a built-in color to use in places, where only one color is needed; 0-6. - * @param lightThemeColors The list of 1-3 colors in RGB format, describing the accent color, as expected to be shown in light themes. - * @param darkThemeColors The list of 1-3 colors in RGB format, describing the accent color, as expected to be shown in dark themes. - * @param minChannelChatBoostLevel The minimum chat boost level required to use the color in a channel chat. - */ - public AccentColor(int id, int builtInAccentColorId, int[] lightThemeColors, int[] darkThemeColors, int minChannelChatBoostLevel) { - this.id = id; - this.builtInAccentColorId = builtInAccentColorId; - this.lightThemeColors = lightThemeColors; - this.darkThemeColors = darkThemeColors; - this.minChannelChatBoostLevel = minChannelChatBoostLevel; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -496870680; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes gift types that are accepted by a user. - */ - public static class AcceptedGiftTypes extends Object { - /** - * True, if unlimited regular gifts are accepted. - */ - public boolean unlimitedGifts; - /** - * True, if limited regular gifts are accepted. - */ - public boolean limitedGifts; - /** - * True, if upgraded gifts and regular gifts that can be upgraded for free are accepted. - */ - public boolean upgradedGifts; - /** - * True, if gifts from channels are accepted subject to other restrictions. - */ - public boolean giftsFromChannels; - /** - * True, if Telegram Premium subscription is accepted. - */ - public boolean premiumSubscription; - - /** - * Describes gift types that are accepted by a user. - */ - public AcceptedGiftTypes() { - } - - /** - * Describes gift types that are accepted by a user. - * - * @param unlimitedGifts True, if unlimited regular gifts are accepted. - * @param limitedGifts True, if limited regular gifts are accepted. - * @param upgradedGifts True, if upgraded gifts and regular gifts that can be upgraded for free are accepted. - * @param giftsFromChannels True, if gifts from channels are accepted subject to other restrictions. - * @param premiumSubscription True, if Telegram Premium subscription is accepted. - */ - public AcceptedGiftTypes(boolean unlimitedGifts, boolean limitedGifts, boolean upgradedGifts, boolean giftsFromChannels, boolean premiumSubscription) { - this.unlimitedGifts = unlimitedGifts; - this.limitedGifts = limitedGifts; - this.upgradedGifts = upgradedGifts; - this.giftsFromChannels = giftsFromChannels; - this.premiumSubscription = premiumSubscription; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1288451078; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains basic information about another user who started a chat with the current user. - */ - public static class AccountInfo extends Object { - /** - * Month when the user was registered in Telegram; 0-12; may be 0 if unknown. - */ - public int registrationMonth; - /** - * Year when the user was registered in Telegram; 0-9999; may be 0 if unknown. - */ - public int registrationYear; - /** - * A two-letter ISO 3166-1 alpha-2 country code based on the phone number of the user; may be empty if unknown. - */ - public String phoneNumberCountryCode; - /** - * Point in time (Unix timestamp) when the user changed name last time; 0 if unknown. - */ - public int lastNameChangeDate; - /** - * Point in time (Unix timestamp) when the user changed photo last time; 0 if unknown. - */ - public int lastPhotoChangeDate; - - /** - * Contains basic information about another user who started a chat with the current user. - */ - public AccountInfo() { - } - - /** - * Contains basic information about another user who started a chat with the current user. - * - * @param registrationMonth Month when the user was registered in Telegram; 0-12; may be 0 if unknown. - * @param registrationYear Year when the user was registered in Telegram; 0-9999; may be 0 if unknown. - * @param phoneNumberCountryCode A two-letter ISO 3166-1 alpha-2 country code based on the phone number of the user; may be empty if unknown. - * @param lastNameChangeDate Point in time (Unix timestamp) when the user changed name last time; 0 if unknown. - * @param lastPhotoChangeDate Point in time (Unix timestamp) when the user changed photo last time; 0 if unknown. - */ - public AccountInfo(int registrationMonth, int registrationYear, String phoneNumberCountryCode, int lastNameChangeDate, int lastPhotoChangeDate) { - this.registrationMonth = registrationMonth; - this.registrationYear = registrationYear; - this.phoneNumberCountryCode = phoneNumberCountryCode; - this.lastNameChangeDate = lastNameChangeDate; - this.lastPhotoChangeDate = lastPhotoChangeDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1803492711; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about the period of inactivity after which the current user's account will automatically be deleted. - */ - public static class AccountTtl extends Object { - /** - * Number of days of inactivity before the account will be flagged for deletion; 30-730 days. - */ - public int days; - - /** - * Contains information about the period of inactivity after which the current user's account will automatically be deleted. - */ - public AccountTtl() { - } - - /** - * Contains information about the period of inactivity after which the current user's account will automatically be deleted. - * - * @param days Number of days of inactivity before the account will be flagged for deletion; 30-730 days. - */ - public AccountTtl(int days) { - this.days = days; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1324495492; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes state of active stories posted by a chat. - */ - public abstract static class ActiveStoryState extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ActiveStoryStateLive.CONSTRUCTOR, - ActiveStoryStateUnread.CONSTRUCTOR, - ActiveStoryStateRead.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ActiveStoryState() { - } - } - - /** - * The chat has an active live story. - */ - public static class ActiveStoryStateLive extends ActiveStoryState { - /** - * Identifier of the active live story. - */ - public int storyId; - - /** - * The chat has an active live story. - */ - public ActiveStoryStateLive() { - } - - /** - * The chat has an active live story. - * - * @param storyId Identifier of the active live story. - */ - public ActiveStoryStateLive(int storyId) { - this.storyId = storyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -292947851; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat has some unread active stories. - */ - public static class ActiveStoryStateUnread extends ActiveStoryState { - - /** - * The chat has some unread active stories. - */ - public ActiveStoryStateUnread() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1903622483; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat has active stories, all of which were read. - */ - public static class ActiveStoryStateRead extends ActiveStoryState { - - /** - * The chat has active stories, all of which were read. - */ - public ActiveStoryStateRead() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 153525350; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of added proxy servers. - */ - public static class AddedProxies extends Object { - /** - * List of proxy servers. - */ - public AddedProxy[] proxies; - - /** - * Represents a list of added proxy servers. - */ - public AddedProxies() { - } - - /** - * Represents a list of added proxy servers. - * - * @param proxies List of proxy servers. - */ - public AddedProxies(AddedProxy[] proxies) { - this.proxies = proxies; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 833708853; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a proxy server added to the list of proxies. - */ - public static class AddedProxy extends Object { - /** - * Unique identifier of the proxy. - */ - public int id; - /** - * Point in time (Unix timestamp) when the proxy was last used; 0 if never. - */ - public int lastUsedDate; - /** - * True, if the proxy is enabled now. - */ - public boolean isEnabled; - /** - * The proxy. - */ - public Proxy proxy; - - /** - * Contains information about a proxy server added to the list of proxies. - */ - public AddedProxy() { - } - - /** - * Contains information about a proxy server added to the list of proxies. - * - * @param id Unique identifier of the proxy. - * @param lastUsedDate Point in time (Unix timestamp) when the proxy was last used; 0 if never. - * @param isEnabled True, if the proxy is enabled now. - * @param proxy The proxy. - */ - public AddedProxy(int id, int lastUsedDate, boolean isEnabled, Proxy proxy) { - this.id = id; - this.lastUsedDate = lastUsedDate; - this.isEnabled = isEnabled; - this.proxy = proxy; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 820767669; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a reaction applied to a message. - */ - public static class AddedReaction extends Object { - /** - * Type of the reaction. - */ - public ReactionType type; - /** - * Identifier of the chat member, applied the reaction. - */ - public MessageSender senderId; - /** - * True, if the reaction was added by the current user. - */ - public boolean isOutgoing; - /** - * Point in time (Unix timestamp) when the reaction was added. - */ - public int date; - - /** - * Represents a reaction applied to a message. - */ - public AddedReaction() { - } - - /** - * Represents a reaction applied to a message. - * - * @param type Type of the reaction. - * @param senderId Identifier of the chat member, applied the reaction. - * @param isOutgoing True, if the reaction was added by the current user. - * @param date Point in time (Unix timestamp) when the reaction was added. - */ - public AddedReaction(ReactionType type, MessageSender senderId, boolean isOutgoing, int date) { - this.type = type; - this.senderId = senderId; - this.isOutgoing = isOutgoing; - this.date = date; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1258586525; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of reactions added to a message. - */ - public static class AddedReactions extends Object { - /** - * The total number of found reactions. - */ - public int totalCount; - /** - * The list of added reactions. - */ - public AddedReaction[] reactions; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Represents a list of reactions added to a message. - */ - public AddedReactions() { - } - - /** - * Represents a list of reactions added to a message. - * - * @param totalCount The total number of found reactions. - * @param reactions The list of added reactions. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public AddedReactions(int totalCount, AddedReaction[] reactions, String nextOffset) { - this.totalCount = totalCount; - this.reactions = reactions; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 226352304; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an address. - */ - public static class Address extends Object { - /** - * A two-letter ISO 3166-1 alpha-2 country code. - */ - public String countryCode; - /** - * State, if applicable. - */ - public String state; - /** - * City. - */ - public String city; - /** - * First line of the address. - */ - public String streetLine1; - /** - * Second line of the address. - */ - public String streetLine2; - /** - * Address postal code. - */ - public String postalCode; - - /** - * Describes an address. - */ - public Address() { - } - - /** - * Describes an address. - * - * @param countryCode A two-letter ISO 3166-1 alpha-2 country code. - * @param state State, if applicable. - * @param city City. - * @param streetLine1 First line of the address. - * @param streetLine2 Second line of the address. - * @param postalCode Address postal code. - */ - public Address(String countryCode, String state, String city, String streetLine1, String streetLine2, String postalCode) { - this.countryCode = countryCode; - this.state = state; - this.city = city; - this.streetLine1 = streetLine1; - this.streetLine2 = streetLine2; - this.postalCode = postalCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2043654342; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Information about the sponsor of an advertisement. - */ - public static class AdvertisementSponsor extends Object { - /** - * URL of the sponsor to be opened when the advertisement is clicked. - */ - public String url; - /** - * Photo of the sponsor; may be null if must not be shown. - */ - @Nullable public Photo photo; - /** - * Additional optional information about the sponsor to be shown along with the advertisement. - */ - public String info; - - /** - * Information about the sponsor of an advertisement. - */ - public AdvertisementSponsor() { - } - - /** - * Information about the sponsor of an advertisement. - * - * @param url URL of the sponsor to be opened when the advertisement is clicked. - * @param photo Photo of the sponsor; may be null if must not be shown. - * @param info Additional optional information about the sponsor to be shown along with the advertisement. - */ - public AdvertisementSponsor(String url, Photo photo, String info) { - this.url = url; - this.photo = photo; - this.info = info; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1388914159; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about an affiliate that received commission from a Telegram Star transaction. - */ - public static class AffiliateInfo extends Object { - /** - * The number of Telegram Stars received by the affiliate for each 1000 Telegram Stars received by the program owner. - */ - public int commissionPerMille; - /** - * Identifier of the chat which received the commission. - */ - public long affiliateChatId; - /** - * The Telegram Star amount that was received by the affiliate; can be negative for refunds. - */ - public StarAmount starAmount; - - /** - * Contains information about an affiliate that received commission from a Telegram Star transaction. - */ - public AffiliateInfo() { - } - - /** - * Contains information about an affiliate that received commission from a Telegram Star transaction. - * - * @param commissionPerMille The number of Telegram Stars received by the affiliate for each 1000 Telegram Stars received by the program owner. - * @param affiliateChatId Identifier of the chat which received the commission. - * @param starAmount The Telegram Star amount that was received by the affiliate; can be negative for refunds. - */ - public AffiliateInfo(int commissionPerMille, long affiliateChatId, StarAmount starAmount) { - this.commissionPerMille = commissionPerMille; - this.affiliateChatId = affiliateChatId; - this.starAmount = starAmount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1312695046; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about an active affiliate program. - */ - public static class AffiliateProgramInfo extends Object { - /** - * Parameters of the affiliate program. - */ - public AffiliateProgramParameters parameters; - /** - * Point in time (Unix timestamp) when the affiliate program will be closed; 0 if the affiliate program isn't scheduled to be closed. If positive, then the program can't be connected using connectAffiliateProgram, but active connections will work until the date. - */ - public int endDate; - /** - * The amount of daily revenue per user in Telegram Stars of the bot that created the affiliate program. - */ - public StarAmount dailyRevenuePerUserAmount; - - /** - * Contains information about an active affiliate program. - */ - public AffiliateProgramInfo() { - } - - /** - * Contains information about an active affiliate program. - * - * @param parameters Parameters of the affiliate program. - * @param endDate Point in time (Unix timestamp) when the affiliate program will be closed; 0 if the affiliate program isn't scheduled to be closed. If positive, then the program can't be connected using connectAffiliateProgram, but active connections will work until the date. - * @param dailyRevenuePerUserAmount The amount of daily revenue per user in Telegram Stars of the bot that created the affiliate program. - */ - public AffiliateProgramInfo(AffiliateProgramParameters parameters, int endDate, StarAmount dailyRevenuePerUserAmount) { - this.parameters = parameters; - this.endDate = endDate; - this.dailyRevenuePerUserAmount = dailyRevenuePerUserAmount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1761810251; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes parameters of an affiliate program. - */ - public static class AffiliateProgramParameters extends Object { - /** - * The number of Telegram Stars received by the affiliate for each 1000 Telegram Stars received by the program owner; getOption("affiliate_program_commission_per_mille_min")-getOption("affiliate_program_commission_per_mille_max"). - */ - public int commissionPerMille; - /** - * Number of months the program will be active; 0-36. If 0, then the program is eternal. - */ - public int monthCount; - - /** - * Describes parameters of an affiliate program. - */ - public AffiliateProgramParameters() { - } - - /** - * Describes parameters of an affiliate program. - * - * @param commissionPerMille The number of Telegram Stars received by the affiliate for each 1000 Telegram Stars received by the program owner; getOption("affiliate_program_commission_per_mille_min")-getOption("affiliate_program_commission_per_mille_max"). - * @param monthCount Number of months the program will be active; 0-36. If 0, then the program is eternal. - */ - public AffiliateProgramParameters(int commissionPerMille, int monthCount) { - this.commissionPerMille = commissionPerMille; - this.monthCount = monthCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1642662996; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the order of the found affiliate programs. - */ - public abstract static class AffiliateProgramSortOrder extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - AffiliateProgramSortOrderProfitability.CONSTRUCTOR, - AffiliateProgramSortOrderCreationDate.CONSTRUCTOR, - AffiliateProgramSortOrderRevenue.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public AffiliateProgramSortOrder() { - } - } - - /** - * The affiliate programs must be sorted by the profitability. - */ - public static class AffiliateProgramSortOrderProfitability extends AffiliateProgramSortOrder { - - /** - * The affiliate programs must be sorted by the profitability. - */ - public AffiliateProgramSortOrderProfitability() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1963282585; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The affiliate programs must be sorted by creation date. - */ - public static class AffiliateProgramSortOrderCreationDate extends AffiliateProgramSortOrder { - - /** - * The affiliate programs must be sorted by creation date. - */ - public AffiliateProgramSortOrderCreationDate() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1558628083; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The affiliate programs must be sorted by the expected revenue. - */ - public static class AffiliateProgramSortOrderRevenue extends AffiliateProgramSortOrder { - - /** - * The affiliate programs must be sorted by the expected revenue. - */ - public AffiliateProgramSortOrderRevenue() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1923269304; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of affiliate for an affiliate program. - */ - public abstract static class AffiliateType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - AffiliateTypeCurrentUser.CONSTRUCTOR, - AffiliateTypeBot.CONSTRUCTOR, - AffiliateTypeChannel.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public AffiliateType() { - } - } - - /** - * The affiliate is the current user. - */ - public static class AffiliateTypeCurrentUser extends AffiliateType { - - /** - * The affiliate is the current user. - */ - public AffiliateTypeCurrentUser() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1453785589; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The affiliate is a bot owned by the current user. - */ - public static class AffiliateTypeBot extends AffiliateType { - /** - * User identifier of the bot. - */ - public long userId; - - /** - * The affiliate is a bot owned by the current user. - */ - public AffiliateTypeBot() { - } - - /** - * The affiliate is a bot owned by the current user. - * - * @param userId User identifier of the bot. - */ - public AffiliateTypeBot(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1032587200; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The affiliate is a channel chat where the current user has canPostMessages administrator right. - */ - public static class AffiliateTypeChannel extends AffiliateType { - /** - * Identifier of the channel chat. - */ - public long chatId; - - /** - * The affiliate is a channel chat where the current user has canPostMessages administrator right. - */ - public AffiliateTypeChannel() { - } - - /** - * The affiliate is a channel chat where the current user has canPostMessages administrator right. - * - * @param chatId Identifier of the channel chat. - */ - public AffiliateTypeChannel(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -683939735; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes parameters for age verification of the current user. - */ - public static class AgeVerificationParameters extends Object { - /** - * The minimum age required to view restricted content. - */ - public int minAge; - /** - * Username of the bot which main Web App may be used to verify age of the user. - */ - public String verificationBotUsername; - /** - * Unique name for the country or region, which legislation required age verification. May be used to get the corresponding localization key. - */ - public String country; - - /** - * Describes parameters for age verification of the current user. - */ - public AgeVerificationParameters() { - } - - /** - * Describes parameters for age verification of the current user. - * - * @param minAge The minimum age required to view restricted content. - * @param verificationBotUsername Username of the bot which main Web App may be used to verify age of the user. - * @param country Unique name for the country or region, which legislation required age verification. May be used to get the corresponding localization key. - */ - public AgeVerificationParameters(int minAge, String verificationBotUsername, String country) { - this.minAge = minAge; - this.verificationBotUsername = verificationBotUsername; - this.country = country; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2050025833; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an alternative re-encoded quality of a video file. - */ - public static class AlternativeVideo extends Object { - /** - * Unique identifier of the alternative video, which is used in the HLS file. - */ - public long id; - /** - * Video width. - */ - public int width; - /** - * Video height. - */ - public int height; - /** - * Codec used for video file encoding, for example, "h264", "h265", "av1", or "av01". - */ - public String codec; - /** - * HLS file describing the video. - */ - public File hlsFile; - /** - * File containing the video. - */ - public File video; - - /** - * Describes an alternative re-encoded quality of a video file. - */ - public AlternativeVideo() { - } - - /** - * Describes an alternative re-encoded quality of a video file. - * - * @param id Unique identifier of the alternative video, which is used in the HLS file. - * @param width Video width. - * @param height Video height. - * @param codec Codec used for video file encoding, for example, "h264", "h265", "av1", or "av01". - * @param hlsFile HLS file describing the video. - * @param video File containing the video. - */ - public AlternativeVideo(long id, int width, int height, String codec, File hlsFile, File video) { - this.id = id; - this.width = width; - this.height = height; - this.codec = codec; - this.hlsFile = hlsFile; - this.video = video; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 483379470; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Animated variant of a chat photo in MPEG4 format. - */ - public static class AnimatedChatPhoto extends Object { - /** - * Animation width and height. - */ - public int length; - /** - * Information about the animation file. - */ - public File file; - /** - * Timestamp of the frame, used as a static chat photo. - */ - public double mainFrameTimestamp; - - /** - * Animated variant of a chat photo in MPEG4 format. - */ - public AnimatedChatPhoto() { - } - - /** - * Animated variant of a chat photo in MPEG4 format. - * - * @param length Animation width and height. - * @param file Information about the animation file. - * @param mainFrameTimestamp Timestamp of the frame, used as a static chat photo. - */ - public AnimatedChatPhoto(int length, File file, double mainFrameTimestamp) { - this.length = length; - this.file = file; - this.mainFrameTimestamp = mainFrameTimestamp; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 191994926; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an animated or custom representation of an emoji. - */ - public static class AnimatedEmoji extends Object { - /** - * Sticker for the emoji; may be null if yet unknown for a custom emoji. If the sticker is a custom emoji, then it can have arbitrary format. - */ - @Nullable public Sticker sticker; - /** - * Expected width of the sticker, which can be used if the sticker is null. - */ - public int stickerWidth; - /** - * Expected height of the sticker, which can be used if the sticker is null. - */ - public int stickerHeight; - /** - * Emoji modifier fitzpatrick type; 0-6; 0 if none. - */ - public int fitzpatrickType; - /** - * File containing the sound to be played when the sticker is clicked; may be null. The sound is encoded with the Opus codec, and stored inside an OGG container. - */ - @Nullable public File sound; - - /** - * Describes an animated or custom representation of an emoji. - */ - public AnimatedEmoji() { - } - - /** - * Describes an animated or custom representation of an emoji. - * - * @param sticker Sticker for the emoji; may be null if yet unknown for a custom emoji. If the sticker is a custom emoji, then it can have arbitrary format. - * @param stickerWidth Expected width of the sticker, which can be used if the sticker is null. - * @param stickerHeight Expected height of the sticker, which can be used if the sticker is null. - * @param fitzpatrickType Emoji modifier fitzpatrick type; 0-6; 0 if none. - * @param sound File containing the sound to be played when the sticker is clicked; may be null. The sound is encoded with the Opus codec, and stored inside an OGG container. - */ - public AnimatedEmoji(Sticker sticker, int stickerWidth, int stickerHeight, int fitzpatrickType, File sound) { - this.sticker = sticker; - this.stickerWidth = stickerWidth; - this.stickerHeight = stickerHeight; - this.fitzpatrickType = fitzpatrickType; - this.sound = sound; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1378918079; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an animation file. The animation must be encoded in GIF or MPEG4 format. - */ - public static class Animation extends Object { - /** - * Duration of the animation, in seconds; as defined by the sender. - */ - public int duration; - /** - * Width of the animation. - */ - public int width; - /** - * Height of the animation. - */ - public int height; - /** - * Original name of the file; as defined by the sender. - */ - public String fileName; - /** - * MIME type of the file, usually "image/gif" or "video/mp4". - */ - public String mimeType; - /** - * True, if stickers were added to the animation. The list of corresponding sticker set can be received using getAttachedStickerSets. - */ - public boolean hasStickers; - /** - * Animation minithumbnail; may be null. - */ - @Nullable public Minithumbnail minithumbnail; - /** - * Animation thumbnail in JPEG or MPEG4 format; may be null. - */ - @Nullable public Thumbnail thumbnail; - /** - * File containing the animation. - */ - public File animation; - - /** - * Describes an animation file. The animation must be encoded in GIF or MPEG4 format. - */ - public Animation() { - } - - /** - * Describes an animation file. The animation must be encoded in GIF or MPEG4 format. - * - * @param duration Duration of the animation, in seconds; as defined by the sender. - * @param width Width of the animation. - * @param height Height of the animation. - * @param fileName Original name of the file; as defined by the sender. - * @param mimeType MIME type of the file, usually "image/gif" or "video/mp4". - * @param hasStickers True, if stickers were added to the animation. The list of corresponding sticker set can be received using getAttachedStickerSets. - * @param minithumbnail Animation minithumbnail; may be null. - * @param thumbnail Animation thumbnail in JPEG or MPEG4 format; may be null. - * @param animation File containing the animation. - */ - public Animation(int duration, int width, int height, String fileName, String mimeType, boolean hasStickers, Minithumbnail minithumbnail, Thumbnail thumbnail, File animation) { - this.duration = duration; - this.width = width; - this.height = height; - this.fileName = fileName; - this.mimeType = mimeType; - this.hasStickers = hasStickers; - this.minithumbnail = minithumbnail; - this.thumbnail = thumbnail; - this.animation = animation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -872359106; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of animations. - */ - public static class Animations extends Object { - /** - * List of animations. - */ - public Animation[] animations; - - /** - * Represents a list of animations. - */ - public Animations() { - } - - /** - * Represents a list of animations. - * - * @param animations List of animations. - */ - public Animations(Animation[] animations) { - this.animations = animations; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 344216945; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains settings for automatic moving of chats to and from the Archive chat lists. - */ - public static class ArchiveChatListSettings extends Object { - /** - * True, if new chats from non-contacts will be automatically archived and muted. Can be set to true only if the option "can_archive_and_mute_new_chats_from_unknown_users" is true. - */ - public boolean archiveAndMuteNewChatsFromUnknownUsers; - /** - * True, if unmuted chats will be kept in the Archive chat list when they get a new message. - */ - public boolean keepUnmutedChatsArchived; - /** - * True, if unmuted chats, that are always included or pinned in a folder, will be kept in the Archive chat list when they get a new message. Ignored if keepUnmutedChatsArchived == true. - */ - public boolean keepChatsFromFoldersArchived; - - /** - * Contains settings for automatic moving of chats to and from the Archive chat lists. - */ - public ArchiveChatListSettings() { - } - - /** - * Contains settings for automatic moving of chats to and from the Archive chat lists. - * - * @param archiveAndMuteNewChatsFromUnknownUsers True, if new chats from non-contacts will be automatically archived and muted. Can be set to true only if the option "can_archive_and_mute_new_chats_from_unknown_users" is true. - * @param keepUnmutedChatsArchived True, if unmuted chats will be kept in the Archive chat list when they get a new message. - * @param keepChatsFromFoldersArchived True, if unmuted chats, that are always included or pinned in a folder, will be kept in the Archive chat list when they get a new message. Ignored if keepUnmutedChatsArchived == true. - */ - public ArchiveChatListSettings(boolean archiveAndMuteNewChatsFromUnknownUsers, boolean keepUnmutedChatsArchived, boolean keepChatsFromFoldersArchived) { - this.archiveAndMuteNewChatsFromUnknownUsers = archiveAndMuteNewChatsFromUnknownUsers; - this.keepUnmutedChatsArchived = keepUnmutedChatsArchived; - this.keepChatsFromFoldersArchived = keepChatsFromFoldersArchived; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1058499236; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a bot, which can be added to attachment or side menu. - */ - public static class AttachmentMenuBot extends Object { - /** - * User identifier of the bot. - */ - public long botUserId; - /** - * True, if the bot supports opening from attachment menu in the chat with the bot. - */ - public boolean supportsSelfChat; - /** - * True, if the bot supports opening from attachment menu in private chats with ordinary users. - */ - public boolean supportsUserChats; - /** - * True, if the bot supports opening from attachment menu in private chats with other bots. - */ - public boolean supportsBotChats; - /** - * True, if the bot supports opening from attachment menu in basic group and supergroup chats. - */ - public boolean supportsGroupChats; - /** - * True, if the bot supports opening from attachment menu in channel chats. - */ - public boolean supportsChannelChats; - /** - * True, if the user must be asked for the permission to send messages to the bot. - */ - public boolean requestWriteAccess; - /** - * True, if the bot was explicitly added by the user. If the bot isn't added, then on the first bot launch toggleBotIsAddedToAttachmentMenu must be called and the bot must be added or removed. - */ - public boolean isAdded; - /** - * True, if the bot must be shown in the attachment menu. - */ - public boolean showInAttachmentMenu; - /** - * True, if the bot must be shown in the side menu. - */ - public boolean showInSideMenu; - /** - * True, if a disclaimer, why the bot is shown in the side menu, is needed. - */ - public boolean showDisclaimerInSideMenu; - /** - * Name for the bot in attachment menu. - */ - public String name; - /** - * Color to highlight selected name of the bot if appropriate; may be null. - */ - @Nullable public AttachmentMenuBotColor nameColor; - /** - * Default icon for the bot in SVG format; may be null. - */ - @Nullable public File defaultIcon; - /** - * Icon for the bot in SVG format for the official iOS app; may be null. - */ - @Nullable public File iosStaticIcon; - /** - * Icon for the bot in TGS format for the official iOS app; may be null. - */ - @Nullable public File iosAnimatedIcon; - /** - * Icon for the bot in PNG format for the official iOS app side menu; may be null. - */ - @Nullable public File iosSideMenuIcon; - /** - * Icon for the bot in TGS format for the official Android app; may be null. - */ - @Nullable public File androidIcon; - /** - * Icon for the bot in SVG format for the official Android app side menu; may be null. - */ - @Nullable public File androidSideMenuIcon; - /** - * Icon for the bot in TGS format for the official native macOS app; may be null. - */ - @Nullable public File macosIcon; - /** - * Icon for the bot in PNG format for the official macOS app side menu; may be null. - */ - @Nullable public File macosSideMenuIcon; - /** - * Color to highlight selected icon of the bot if appropriate; may be null. - */ - @Nullable public AttachmentMenuBotColor iconColor; - /** - * Default placeholder for opened Web Apps in SVG format; may be null. - */ - @Nullable public File webAppPlaceholder; - - /** - * Represents a bot, which can be added to attachment or side menu. - */ - public AttachmentMenuBot() { - } - - /** - * Represents a bot, which can be added to attachment or side menu. - * - * @param botUserId User identifier of the bot. - * @param supportsSelfChat True, if the bot supports opening from attachment menu in the chat with the bot. - * @param supportsUserChats True, if the bot supports opening from attachment menu in private chats with ordinary users. - * @param supportsBotChats True, if the bot supports opening from attachment menu in private chats with other bots. - * @param supportsGroupChats True, if the bot supports opening from attachment menu in basic group and supergroup chats. - * @param supportsChannelChats True, if the bot supports opening from attachment menu in channel chats. - * @param requestWriteAccess True, if the user must be asked for the permission to send messages to the bot. - * @param isAdded True, if the bot was explicitly added by the user. If the bot isn't added, then on the first bot launch toggleBotIsAddedToAttachmentMenu must be called and the bot must be added or removed. - * @param showInAttachmentMenu True, if the bot must be shown in the attachment menu. - * @param showInSideMenu True, if the bot must be shown in the side menu. - * @param showDisclaimerInSideMenu True, if a disclaimer, why the bot is shown in the side menu, is needed. - * @param name Name for the bot in attachment menu. - * @param nameColor Color to highlight selected name of the bot if appropriate; may be null. - * @param defaultIcon Default icon for the bot in SVG format; may be null. - * @param iosStaticIcon Icon for the bot in SVG format for the official iOS app; may be null. - * @param iosAnimatedIcon Icon for the bot in TGS format for the official iOS app; may be null. - * @param iosSideMenuIcon Icon for the bot in PNG format for the official iOS app side menu; may be null. - * @param androidIcon Icon for the bot in TGS format for the official Android app; may be null. - * @param androidSideMenuIcon Icon for the bot in SVG format for the official Android app side menu; may be null. - * @param macosIcon Icon for the bot in TGS format for the official native macOS app; may be null. - * @param macosSideMenuIcon Icon for the bot in PNG format for the official macOS app side menu; may be null. - * @param iconColor Color to highlight selected icon of the bot if appropriate; may be null. - * @param webAppPlaceholder Default placeholder for opened Web Apps in SVG format; may be null. - */ - public AttachmentMenuBot(long botUserId, boolean supportsSelfChat, boolean supportsUserChats, boolean supportsBotChats, boolean supportsGroupChats, boolean supportsChannelChats, boolean requestWriteAccess, boolean isAdded, boolean showInAttachmentMenu, boolean showInSideMenu, boolean showDisclaimerInSideMenu, String name, AttachmentMenuBotColor nameColor, File defaultIcon, File iosStaticIcon, File iosAnimatedIcon, File iosSideMenuIcon, File androidIcon, File androidSideMenuIcon, File macosIcon, File macosSideMenuIcon, AttachmentMenuBotColor iconColor, File webAppPlaceholder) { - this.botUserId = botUserId; - this.supportsSelfChat = supportsSelfChat; - this.supportsUserChats = supportsUserChats; - this.supportsBotChats = supportsBotChats; - this.supportsGroupChats = supportsGroupChats; - this.supportsChannelChats = supportsChannelChats; - this.requestWriteAccess = requestWriteAccess; - this.isAdded = isAdded; - this.showInAttachmentMenu = showInAttachmentMenu; - this.showInSideMenu = showInSideMenu; - this.showDisclaimerInSideMenu = showDisclaimerInSideMenu; - this.name = name; - this.nameColor = nameColor; - this.defaultIcon = defaultIcon; - this.iosStaticIcon = iosStaticIcon; - this.iosAnimatedIcon = iosAnimatedIcon; - this.iosSideMenuIcon = iosSideMenuIcon; - this.androidIcon = androidIcon; - this.androidSideMenuIcon = androidSideMenuIcon; - this.macosIcon = macosIcon; - this.macosSideMenuIcon = macosSideMenuIcon; - this.iconColor = iconColor; - this.webAppPlaceholder = webAppPlaceholder; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1183966273; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a color to highlight a bot added to attachment menu. - */ - public static class AttachmentMenuBotColor extends Object { - /** - * Color in the RGB format for light themes. - */ - public int lightColor; - /** - * Color in the RGB format for dark themes. - */ - public int darkColor; - - /** - * Describes a color to highlight a bot added to attachment menu. - */ - public AttachmentMenuBotColor() { - } - - /** - * Describes a color to highlight a bot added to attachment menu. - * - * @param lightColor Color in the RGB format for light themes. - * @param darkColor Color in the RGB format for dark themes. - */ - public AttachmentMenuBotColor(int lightColor, int darkColor) { - this.lightColor = lightColor; - this.darkColor = darkColor; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1680039612; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes chance of the crafted gift to have the backdrop or symbol of one of the original gifts. - */ - public static class AttributeCraftPersistenceProbability extends Object { - /** - * The 4 numbers that describe probability of the craft result to have the same attribute as one of the original gifts if 1, 2, 3, or 4 gifts with the attribute are used in the craft. Each number represents the number of crafted gifts with the original attribute per 1000 successful craftings. - */ - public int[] persistenceChancePerMille; - - /** - * Describes chance of the crafted gift to have the backdrop or symbol of one of the original gifts. - */ - public AttributeCraftPersistenceProbability() { - } - - /** - * Describes chance of the crafted gift to have the backdrop or symbol of one of the original gifts. - * - * @param persistenceChancePerMille The 4 numbers that describe probability of the craft result to have the same attribute as one of the original gifts if 1, 2, 3, or 4 gifts with the attribute are used in the craft. Each number represents the number of crafted gifts with the original attribute per 1000 successful craftings. - */ - public AttributeCraftPersistenceProbability(int[] persistenceChancePerMille) { - this.persistenceChancePerMille = persistenceChancePerMille; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -922780991; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a bid in an auction. - */ - public static class AuctionBid extends Object { - /** - * The number of Telegram Stars that were put in the bid. - */ - public long starCount; - /** - * Point in time (Unix timestamp) when the bid was made. - */ - public int bidDate; - /** - * Position of the bid in the list of all bids. - */ - public int position; - - /** - * Describes a bid in an auction. - */ - public AuctionBid() { - } - - /** - * Describes a bid in an auction. - * - * @param starCount The number of Telegram Stars that were put in the bid. - * @param bidDate Point in time (Unix timestamp) when the bid was made. - * @param position Position of the bid in the list of all bids. - */ - public AuctionBid(long starCount, int bidDate, int position) { - this.starCount = starCount; - this.bidDate = bidDate; - this.position = position; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1756434144; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a round of an auction. - */ - public static class AuctionRound extends Object { - /** - * 1-based number of the round. - */ - public int number; - /** - * Duration of the round, in seconds. - */ - public int duration; - /** - * The number of seconds for which the round will be extended if there are changes in the top winners. - */ - public int extendTime; - /** - * The number of top winners who trigger round extension if changed. - */ - public int topWinnerCount; - - /** - * Describes a round of an auction. - */ - public AuctionRound() { - } - - /** - * Describes a round of an auction. - * - * @param number 1-based number of the round. - * @param duration Duration of the round, in seconds. - * @param extendTime The number of seconds for which the round will be extended if there are changes in the top winners. - * @param topWinnerCount The number of top winners who trigger round extension if changed. - */ - public AuctionRound(int number, int duration, int extendTime, int topWinnerCount) { - this.number = number; - this.duration = duration; - this.extendTime = extendTime; - this.topWinnerCount = topWinnerCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -986948877; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes state of an auction. - */ - public abstract static class AuctionState extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - AuctionStateActive.CONSTRUCTOR, - AuctionStateFinished.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public AuctionState() { - } - } - - /** - * Contains information about an ongoing or scheduled auction. - */ - public static class AuctionStateActive extends AuctionState { - /** - * Point in time (Unix timestamp) when the auction started or will start. - */ - public int startDate; - /** - * Point in time (Unix timestamp) when the auction will be ended. - */ - public int endDate; - /** - * The minimum possible bid in the auction in Telegram Stars. - */ - public long minBid; - /** - * A sparse list of bids that were made in the auction. - */ - public AuctionBid[] bidLevels; - /** - * User identifiers of at most 3 users with the biggest bids. - */ - public long[] topBidderUserIds; - /** - * Rounds of the auction in which their duration or extension rules are changed. - */ - public AuctionRound[] rounds; - /** - * Point in time (Unix timestamp) when the current round will end. - */ - public int currentRoundEndDate; - /** - * 1-based number of the current round. - */ - public int currentRoundNumber; - /** - * The total number of rounds. - */ - public int totalRoundCount; - /** - * The number of items that were purchased on the auction by all users. - */ - public int distributedItemCount; - /** - * The number of items that have to be distributed on the auction. - */ - public int leftItemCount; - /** - * The number of items that were purchased by the current user on the auction. - */ - public int acquiredItemCount; - /** - * Bid of the current user in the auction; may be null if none. - */ - @Nullable public UserAuctionBid userBid; - - /** - * Contains information about an ongoing or scheduled auction. - */ - public AuctionStateActive() { - } - - /** - * Contains information about an ongoing or scheduled auction. - * - * @param startDate Point in time (Unix timestamp) when the auction started or will start. - * @param endDate Point in time (Unix timestamp) when the auction will be ended. - * @param minBid The minimum possible bid in the auction in Telegram Stars. - * @param bidLevels A sparse list of bids that were made in the auction. - * @param topBidderUserIds User identifiers of at most 3 users with the biggest bids. - * @param rounds Rounds of the auction in which their duration or extension rules are changed. - * @param currentRoundEndDate Point in time (Unix timestamp) when the current round will end. - * @param currentRoundNumber 1-based number of the current round. - * @param totalRoundCount The total number of rounds. - * @param distributedItemCount The number of items that were purchased on the auction by all users. - * @param leftItemCount The number of items that have to be distributed on the auction. - * @param acquiredItemCount The number of items that were purchased by the current user on the auction. - * @param userBid Bid of the current user in the auction; may be null if none. - */ - public AuctionStateActive(int startDate, int endDate, long minBid, AuctionBid[] bidLevels, long[] topBidderUserIds, AuctionRound[] rounds, int currentRoundEndDate, int currentRoundNumber, int totalRoundCount, int distributedItemCount, int leftItemCount, int acquiredItemCount, UserAuctionBid userBid) { - this.startDate = startDate; - this.endDate = endDate; - this.minBid = minBid; - this.bidLevels = bidLevels; - this.topBidderUserIds = topBidderUserIds; - this.rounds = rounds; - this.currentRoundEndDate = currentRoundEndDate; - this.currentRoundNumber = currentRoundNumber; - this.totalRoundCount = totalRoundCount; - this.distributedItemCount = distributedItemCount; - this.leftItemCount = leftItemCount; - this.acquiredItemCount = acquiredItemCount; - this.userBid = userBid; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1169774099; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a finished auction. - */ - public static class AuctionStateFinished extends AuctionState { - /** - * Point in time (Unix timestamp) when the auction started. - */ - public int startDate; - /** - * Point in time (Unix timestamp) when the auction will be ended. - */ - public int endDate; - /** - * Average price of bought items in Telegram Stars. - */ - public long averagePrice; - /** - * The number of items that were purchased by the current user on the auction. - */ - public int acquiredItemCount; - /** - * Number of items from the auction being resold on Telegram. - */ - public int telegramListedItemCount; - /** - * Number of items from the auction being resold on Fragment. - */ - public int fragmentListedItemCount; - /** - * The HTTPS link to the Fragment for the resold items; may be empty if there are no such items being sold on Fragment. - */ - public String fragmentUrl; - - /** - * Contains information about a finished auction. - */ - public AuctionStateFinished() { - } - - /** - * Contains information about a finished auction. - * - * @param startDate Point in time (Unix timestamp) when the auction started. - * @param endDate Point in time (Unix timestamp) when the auction will be ended. - * @param averagePrice Average price of bought items in Telegram Stars. - * @param acquiredItemCount The number of items that were purchased by the current user on the auction. - * @param telegramListedItemCount Number of items from the auction being resold on Telegram. - * @param fragmentListedItemCount Number of items from the auction being resold on Fragment. - * @param fragmentUrl The HTTPS link to the Fragment for the resold items; may be empty if there are no such items being sold on Fragment. - */ - public AuctionStateFinished(int startDate, int endDate, long averagePrice, int acquiredItemCount, int telegramListedItemCount, int fragmentListedItemCount, String fragmentUrl) { - this.startDate = startDate; - this.endDate = endDate; - this.averagePrice = averagePrice; - this.acquiredItemCount = acquiredItemCount; - this.telegramListedItemCount = telegramListedItemCount; - this.fragmentListedItemCount = fragmentListedItemCount; - this.fragmentUrl = fragmentUrl; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -451306439; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an audio file. Audio is usually in MP3 or M4A format. - */ - public static class Audio extends Object { - /** - * Duration of the audio, in seconds; as defined by the sender. - */ - public int duration; - /** - * Title of the audio; as defined by the sender. - */ - public String title; - /** - * Performer of the audio; as defined by the sender. - */ - public String performer; - /** - * Original name of the file; as defined by the sender. - */ - public String fileName; - /** - * The MIME type of the file; as defined by the sender. - */ - public String mimeType; - /** - * The minithumbnail of the album cover; may be null. - */ - @Nullable public Minithumbnail albumCoverMinithumbnail; - /** - * The thumbnail of the album cover in JPEG format; as defined by the sender. The full size thumbnail is expected to be extracted from the downloaded audio file; may be null. - */ - @Nullable public Thumbnail albumCoverThumbnail; - /** - * Album cover variants to use if the downloaded audio file contains no album cover. Provided thumbnail dimensions are approximate. - */ - public Thumbnail[] externalAlbumCovers; - /** - * File containing the audio. - */ - public File audio; - - /** - * Describes an audio file. Audio is usually in MP3 or M4A format. - */ - public Audio() { - } - - /** - * Describes an audio file. Audio is usually in MP3 or M4A format. - * - * @param duration Duration of the audio, in seconds; as defined by the sender. - * @param title Title of the audio; as defined by the sender. - * @param performer Performer of the audio; as defined by the sender. - * @param fileName Original name of the file; as defined by the sender. - * @param mimeType The MIME type of the file; as defined by the sender. - * @param albumCoverMinithumbnail The minithumbnail of the album cover; may be null. - * @param albumCoverThumbnail The thumbnail of the album cover in JPEG format; as defined by the sender. The full size thumbnail is expected to be extracted from the downloaded audio file; may be null. - * @param externalAlbumCovers Album cover variants to use if the downloaded audio file contains no album cover. Provided thumbnail dimensions are approximate. - * @param audio File containing the audio. - */ - public Audio(int duration, String title, String performer, String fileName, String mimeType, Minithumbnail albumCoverMinithumbnail, Thumbnail albumCoverThumbnail, Thumbnail[] externalAlbumCovers, File audio) { - this.duration = duration; - this.title = title; - this.performer = performer; - this.fileName = fileName; - this.mimeType = mimeType; - this.albumCoverMinithumbnail = albumCoverMinithumbnail; - this.albumCoverThumbnail = albumCoverThumbnail; - this.externalAlbumCovers = externalAlbumCovers; - this.audio = audio; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -166398841; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of audio files. - */ - public static class Audios extends Object { - /** - * Approximate total number of audio files found. - */ - public int totalCount; - /** - * List of audio files. - */ - public Audio[] audios; - - /** - * Contains a list of audio files. - */ - public Audios() { - } - - /** - * Contains a list of audio files. - * - * @param totalCount Approximate total number of audio files found. - * @param audios List of audio files. - */ - public Audios(int totalCount, Audio[] audios) { - this.totalCount = totalCount; - this.audios = audios; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -680688982; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Information about the authentication code that was sent. - */ - public static class AuthenticationCodeInfo extends Object { - /** - * A phone number that is being authenticated. - */ - public String phoneNumber; - /** - * The way the code was sent to the user. - */ - public AuthenticationCodeType type; - /** - * The way the next code will be sent to the user; may be null. - */ - @Nullable public AuthenticationCodeType nextType; - /** - * Timeout before the code can be re-sent, in seconds. - */ - public int timeout; - - /** - * Information about the authentication code that was sent. - */ - public AuthenticationCodeInfo() { - } - - /** - * Information about the authentication code that was sent. - * - * @param phoneNumber A phone number that is being authenticated. - * @param type The way the code was sent to the user. - * @param nextType The way the next code will be sent to the user; may be null. - * @param timeout Timeout before the code can be re-sent, in seconds. - */ - public AuthenticationCodeInfo(String phoneNumber, AuthenticationCodeType type, AuthenticationCodeType nextType, int timeout) { - this.phoneNumber = phoneNumber; - this.type = type; - this.nextType = nextType; - this.timeout = timeout; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -860345416; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Provides information about the method by which an authentication code is delivered to the user. - */ - public abstract static class AuthenticationCodeType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - AuthenticationCodeTypeTelegramMessage.CONSTRUCTOR, - AuthenticationCodeTypeSms.CONSTRUCTOR, - AuthenticationCodeTypeSmsWord.CONSTRUCTOR, - AuthenticationCodeTypeSmsPhrase.CONSTRUCTOR, - AuthenticationCodeTypeCall.CONSTRUCTOR, - AuthenticationCodeTypeFlashCall.CONSTRUCTOR, - AuthenticationCodeTypeMissedCall.CONSTRUCTOR, - AuthenticationCodeTypeFragment.CONSTRUCTOR, - AuthenticationCodeTypeFirebaseAndroid.CONSTRUCTOR, - AuthenticationCodeTypeFirebaseIos.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public AuthenticationCodeType() { - } - } - - /** - * A digit-only authentication code is delivered via a private Telegram message, which can be viewed from another active session. - */ - public static class AuthenticationCodeTypeTelegramMessage extends AuthenticationCodeType { - /** - * Length of the code. - */ - public int length; - - /** - * A digit-only authentication code is delivered via a private Telegram message, which can be viewed from another active session. - */ - public AuthenticationCodeTypeTelegramMessage() { - } - - /** - * A digit-only authentication code is delivered via a private Telegram message, which can be viewed from another active session. - * - * @param length Length of the code. - */ - public AuthenticationCodeTypeTelegramMessage(int length) { - this.length = length; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2079628074; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A digit-only authentication code is delivered via an SMS message to the specified phone number; non-official applications may not receive this type of code. - */ - public static class AuthenticationCodeTypeSms extends AuthenticationCodeType { - /** - * Length of the code. - */ - public int length; - - /** - * A digit-only authentication code is delivered via an SMS message to the specified phone number; non-official applications may not receive this type of code. - */ - public AuthenticationCodeTypeSms() { - } - - /** - * A digit-only authentication code is delivered via an SMS message to the specified phone number; non-official applications may not receive this type of code. - * - * @param length Length of the code. - */ - public AuthenticationCodeTypeSms(int length) { - this.length = length; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 962650760; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An authentication code is a word delivered via an SMS message to the specified phone number; non-official applications may not receive this type of code. - */ - public static class AuthenticationCodeTypeSmsWord extends AuthenticationCodeType { - /** - * The first letters of the word if known. - */ - public String firstLetter; - - /** - * An authentication code is a word delivered via an SMS message to the specified phone number; non-official applications may not receive this type of code. - */ - public AuthenticationCodeTypeSmsWord() { - } - - /** - * An authentication code is a word delivered via an SMS message to the specified phone number; non-official applications may not receive this type of code. - * - * @param firstLetter The first letters of the word if known. - */ - public AuthenticationCodeTypeSmsWord(String firstLetter) { - this.firstLetter = firstLetter; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1509540765; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An authentication code is a phrase from multiple words delivered via an SMS message to the specified phone number; non-official applications may not receive this type of code. - */ - public static class AuthenticationCodeTypeSmsPhrase extends AuthenticationCodeType { - /** - * The first word of the phrase if known. - */ - public String firstWord; - - /** - * An authentication code is a phrase from multiple words delivered via an SMS message to the specified phone number; non-official applications may not receive this type of code. - */ - public AuthenticationCodeTypeSmsPhrase() { - } - - /** - * An authentication code is a phrase from multiple words delivered via an SMS message to the specified phone number; non-official applications may not receive this type of code. - * - * @param firstWord The first word of the phrase if known. - */ - public AuthenticationCodeTypeSmsPhrase(String firstWord) { - this.firstWord = firstWord; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 784108753; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A digit-only authentication code is delivered via a phone call to the specified phone number. - */ - public static class AuthenticationCodeTypeCall extends AuthenticationCodeType { - /** - * Length of the code. - */ - public int length; - - /** - * A digit-only authentication code is delivered via a phone call to the specified phone number. - */ - public AuthenticationCodeTypeCall() { - } - - /** - * A digit-only authentication code is delivered via a phone call to the specified phone number. - * - * @param length Length of the code. - */ - public AuthenticationCodeTypeCall(int length) { - this.length = length; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1636265063; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An authentication code is delivered by an immediately canceled call to the specified phone number. The phone number that calls is the code that must be entered automatically. - */ - public static class AuthenticationCodeTypeFlashCall extends AuthenticationCodeType { - /** - * Pattern of the phone number from which the call will be made. - */ - public String pattern; - - /** - * An authentication code is delivered by an immediately canceled call to the specified phone number. The phone number that calls is the code that must be entered automatically. - */ - public AuthenticationCodeTypeFlashCall() { - } - - /** - * An authentication code is delivered by an immediately canceled call to the specified phone number. The phone number that calls is the code that must be entered automatically. - * - * @param pattern Pattern of the phone number from which the call will be made. - */ - public AuthenticationCodeTypeFlashCall(String pattern) { - this.pattern = pattern; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1395882402; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An authentication code is delivered by an immediately canceled call to the specified phone number. The last digits of the phone number that calls are the code that must be entered manually by the user. - */ - public static class AuthenticationCodeTypeMissedCall extends AuthenticationCodeType { - /** - * Prefix of the phone number from which the call will be made. - */ - public String phoneNumberPrefix; - /** - * Number of digits in the code, excluding the prefix. - */ - public int length; - - /** - * An authentication code is delivered by an immediately canceled call to the specified phone number. The last digits of the phone number that calls are the code that must be entered manually by the user. - */ - public AuthenticationCodeTypeMissedCall() { - } - - /** - * An authentication code is delivered by an immediately canceled call to the specified phone number. The last digits of the phone number that calls are the code that must be entered manually by the user. - * - * @param phoneNumberPrefix Prefix of the phone number from which the call will be made. - * @param length Number of digits in the code, excluding the prefix. - */ - public AuthenticationCodeTypeMissedCall(String phoneNumberPrefix, int length) { - this.phoneNumberPrefix = phoneNumberPrefix; - this.length = length; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 700123783; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A digit-only authentication code is delivered to https://fragment.com. The user must be logged in there via a wallet owning the phone number's NFT. - */ - public static class AuthenticationCodeTypeFragment extends AuthenticationCodeType { - /** - * URL to open to receive the code. - */ - public String url; - /** - * Length of the code. - */ - public int length; - - /** - * A digit-only authentication code is delivered to https://fragment.com. The user must be logged in there via a wallet owning the phone number's NFT. - */ - public AuthenticationCodeTypeFragment() { - } - - /** - * A digit-only authentication code is delivered to https://fragment.com. The user must be logged in there via a wallet owning the phone number's NFT. - * - * @param url URL to open to receive the code. - * @param length Length of the code. - */ - public AuthenticationCodeTypeFragment(String url, int length) { - this.url = url; - this.length = length; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2129693491; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A digit-only authentication code is delivered via Firebase Authentication to the official Android application. - */ - public static class AuthenticationCodeTypeFirebaseAndroid extends AuthenticationCodeType { - /** - * Parameters to be used for device verification. - */ - public FirebaseDeviceVerificationParameters deviceVerificationParameters; - /** - * Length of the code. - */ - public int length; - - /** - * A digit-only authentication code is delivered via Firebase Authentication to the official Android application. - */ - public AuthenticationCodeTypeFirebaseAndroid() { - } - - /** - * A digit-only authentication code is delivered via Firebase Authentication to the official Android application. - * - * @param deviceVerificationParameters Parameters to be used for device verification. - * @param length Length of the code. - */ - public AuthenticationCodeTypeFirebaseAndroid(FirebaseDeviceVerificationParameters deviceVerificationParameters, int length) { - this.deviceVerificationParameters = deviceVerificationParameters; - this.length = length; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1872475422; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A digit-only authentication code is delivered via Firebase Authentication to the official iOS application. - */ - public static class AuthenticationCodeTypeFirebaseIos extends AuthenticationCodeType { - /** - * Receipt of successful application token validation to compare with receipt from push notification. - */ - public String receipt; - /** - * Time after the next authentication method is expected to be used if verification push notification isn't received, in seconds. - */ - public int pushTimeout; - /** - * Length of the code. - */ - public int length; - - /** - * A digit-only authentication code is delivered via Firebase Authentication to the official iOS application. - */ - public AuthenticationCodeTypeFirebaseIos() { - } - - /** - * A digit-only authentication code is delivered via Firebase Authentication to the official iOS application. - * - * @param receipt Receipt of successful application token validation to compare with receipt from push notification. - * @param pushTimeout Time after the next authentication method is expected to be used if verification push notification isn't received, in seconds. - * @param length Length of the code. - */ - public AuthenticationCodeTypeFirebaseIos(String receipt, int pushTimeout, int length) { - this.receipt = receipt; - this.pushTimeout = pushTimeout; - this.length = length; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -11162989; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents the current authorization state of the TDLib client. - */ - public abstract static class AuthorizationState extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - AuthorizationStateWaitTdlibParameters.CONSTRUCTOR, - AuthorizationStateWaitPhoneNumber.CONSTRUCTOR, - AuthorizationStateWaitPremiumPurchase.CONSTRUCTOR, - AuthorizationStateWaitEmailAddress.CONSTRUCTOR, - AuthorizationStateWaitEmailCode.CONSTRUCTOR, - AuthorizationStateWaitCode.CONSTRUCTOR, - AuthorizationStateWaitOtherDeviceConfirmation.CONSTRUCTOR, - AuthorizationStateWaitRegistration.CONSTRUCTOR, - AuthorizationStateWaitPassword.CONSTRUCTOR, - AuthorizationStateReady.CONSTRUCTOR, - AuthorizationStateLoggingOut.CONSTRUCTOR, - AuthorizationStateClosing.CONSTRUCTOR, - AuthorizationStateClosed.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public AuthorizationState() { - } - } - - /** - * Initialization parameters are needed. Call setTdlibParameters to provide them. - */ - public static class AuthorizationStateWaitTdlibParameters extends AuthorizationState { - - /** - * Initialization parameters are needed. Call setTdlibParameters to provide them. - */ - public AuthorizationStateWaitTdlibParameters() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 904720988; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * TDLib needs the user's phone number to authorize. Call setAuthenticationPhoneNumber to provide the phone number, or use requestQrCodeAuthentication, getAuthenticationPasskeyParameters, or checkAuthenticationBotToken for other authentication options. - */ - public static class AuthorizationStateWaitPhoneNumber extends AuthorizationState { - - /** - * TDLib needs the user's phone number to authorize. Call setAuthenticationPhoneNumber to provide the phone number, or use requestQrCodeAuthentication, getAuthenticationPasskeyParameters, or checkAuthenticationBotToken for other authentication options. - */ - public AuthorizationStateWaitPhoneNumber() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 306402531; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user must buy Telegram Premium as an in-store purchase to log in. Call checkAuthenticationPremiumPurchase and then setAuthenticationPremiumPurchaseTransaction. - */ - public static class AuthorizationStateWaitPremiumPurchase extends AuthorizationState { - /** - * Identifier of the store product that must be bought. - */ - public String storeProductId; - /** - * Email address to use for support if the user has issues with Telegram Premium purchase. - */ - public String supportEmailAddress; - /** - * Subject for the email sent to the support email address. - */ - public String supportEmailSubject; - - /** - * The user must buy Telegram Premium as an in-store purchase to log in. Call checkAuthenticationPremiumPurchase and then setAuthenticationPremiumPurchaseTransaction. - */ - public AuthorizationStateWaitPremiumPurchase() { - } - - /** - * The user must buy Telegram Premium as an in-store purchase to log in. Call checkAuthenticationPremiumPurchase and then setAuthenticationPremiumPurchaseTransaction. - * - * @param storeProductId Identifier of the store product that must be bought. - * @param supportEmailAddress Email address to use for support if the user has issues with Telegram Premium purchase. - * @param supportEmailSubject Subject for the email sent to the support email address. - */ - public AuthorizationStateWaitPremiumPurchase(String storeProductId, String supportEmailAddress, String supportEmailSubject) { - this.storeProductId = storeProductId; - this.supportEmailAddress = supportEmailAddress; - this.supportEmailSubject = supportEmailSubject; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2097616261; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * TDLib needs the user's email address to authorize. Call setAuthenticationEmailAddress to provide the email address, or directly call checkAuthenticationEmailCode with Apple ID/Google ID token if allowed. - */ - public static class AuthorizationStateWaitEmailAddress extends AuthorizationState { - /** - * True, if authorization through Apple ID is allowed. - */ - public boolean allowAppleId; - /** - * True, if authorization through Google ID is allowed. - */ - public boolean allowGoogleId; - - /** - * TDLib needs the user's email address to authorize. Call setAuthenticationEmailAddress to provide the email address, or directly call checkAuthenticationEmailCode with Apple ID/Google ID token if allowed. - */ - public AuthorizationStateWaitEmailAddress() { - } - - /** - * TDLib needs the user's email address to authorize. Call setAuthenticationEmailAddress to provide the email address, or directly call checkAuthenticationEmailCode with Apple ID/Google ID token if allowed. - * - * @param allowAppleId True, if authorization through Apple ID is allowed. - * @param allowGoogleId True, if authorization through Google ID is allowed. - */ - public AuthorizationStateWaitEmailAddress(boolean allowAppleId, boolean allowGoogleId) { - this.allowAppleId = allowAppleId; - this.allowGoogleId = allowGoogleId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1040478663; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * TDLib needs the user's authentication code sent to an email address to authorize. Call checkAuthenticationEmailCode to provide the code. - */ - public static class AuthorizationStateWaitEmailCode extends AuthorizationState { - /** - * True, if authorization through Apple ID is allowed. - */ - public boolean allowAppleId; - /** - * True, if authorization through Google ID is allowed. - */ - public boolean allowGoogleId; - /** - * Information about the sent authentication code. - */ - public EmailAddressAuthenticationCodeInfo codeInfo; - /** - * Reset state of the email address; may be null if the email address can't be reset. - */ - @Nullable public EmailAddressResetState emailAddressResetState; - - /** - * TDLib needs the user's authentication code sent to an email address to authorize. Call checkAuthenticationEmailCode to provide the code. - */ - public AuthorizationStateWaitEmailCode() { - } - - /** - * TDLib needs the user's authentication code sent to an email address to authorize. Call checkAuthenticationEmailCode to provide the code. - * - * @param allowAppleId True, if authorization through Apple ID is allowed. - * @param allowGoogleId True, if authorization through Google ID is allowed. - * @param codeInfo Information about the sent authentication code. - * @param emailAddressResetState Reset state of the email address; may be null if the email address can't be reset. - */ - public AuthorizationStateWaitEmailCode(boolean allowAppleId, boolean allowGoogleId, EmailAddressAuthenticationCodeInfo codeInfo, EmailAddressResetState emailAddressResetState) { - this.allowAppleId = allowAppleId; - this.allowGoogleId = allowGoogleId; - this.codeInfo = codeInfo; - this.emailAddressResetState = emailAddressResetState; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1868627365; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * TDLib needs the user's authentication code to authorize. Call checkAuthenticationCode to check the code. - */ - public static class AuthorizationStateWaitCode extends AuthorizationState { - /** - * Information about the authorization code that was sent. - */ - public AuthenticationCodeInfo codeInfo; - - /** - * TDLib needs the user's authentication code to authorize. Call checkAuthenticationCode to check the code. - */ - public AuthorizationStateWaitCode() { - } - - /** - * TDLib needs the user's authentication code to authorize. Call checkAuthenticationCode to check the code. - * - * @param codeInfo Information about the authorization code that was sent. - */ - public AuthorizationStateWaitCode(AuthenticationCodeInfo codeInfo) { - this.codeInfo = codeInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 52643073; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user needs to confirm authorization on another logged in device by scanning a QR code with the provided link. - */ - public static class AuthorizationStateWaitOtherDeviceConfirmation extends AuthorizationState { - /** - * A tg:// URL for the QR code. The link will be updated frequently. - */ - public String link; - - /** - * The user needs to confirm authorization on another logged in device by scanning a QR code with the provided link. - */ - public AuthorizationStateWaitOtherDeviceConfirmation() { - } - - /** - * The user needs to confirm authorization on another logged in device by scanning a QR code with the provided link. - * - * @param link A tg:// URL for the QR code. The link will be updated frequently. - */ - public AuthorizationStateWaitOtherDeviceConfirmation(String link) { - this.link = link; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 860166378; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is unregistered and need to accept terms of service and enter their first name and last name to finish registration. Call registerUser to accept the terms of service and provide the data. - */ - public static class AuthorizationStateWaitRegistration extends AuthorizationState { - /** - * Telegram terms of service. - */ - public TermsOfService termsOfService; - - /** - * The user is unregistered and need to accept terms of service and enter their first name and last name to finish registration. Call registerUser to accept the terms of service and provide the data. - */ - public AuthorizationStateWaitRegistration() { - } - - /** - * The user is unregistered and need to accept terms of service and enter their first name and last name to finish registration. Call registerUser to accept the terms of service and provide the data. - * - * @param termsOfService Telegram terms of service. - */ - public AuthorizationStateWaitRegistration(TermsOfService termsOfService) { - this.termsOfService = termsOfService; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 550350511; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user has been authorized, but needs to enter a 2-step verification password to start using the application. Call checkAuthenticationPassword to provide the password, or requestAuthenticationPasswordRecovery to recover the password, or deleteAccount to delete the account after a week. - */ - public static class AuthorizationStateWaitPassword extends AuthorizationState { - /** - * Hint for the password; may be empty. - */ - public String passwordHint; - /** - * True, if a recovery email address has been set up. - */ - public boolean hasRecoveryEmailAddress; - /** - * True, if some Telegram Passport elements were saved. - */ - public boolean hasPassportData; - /** - * Pattern of the email address to which the recovery email was sent; empty until a recovery email has been sent. - */ - public String recoveryEmailAddressPattern; - - /** - * The user has been authorized, but needs to enter a 2-step verification password to start using the application. Call checkAuthenticationPassword to provide the password, or requestAuthenticationPasswordRecovery to recover the password, or deleteAccount to delete the account after a week. - */ - public AuthorizationStateWaitPassword() { - } - - /** - * The user has been authorized, but needs to enter a 2-step verification password to start using the application. Call checkAuthenticationPassword to provide the password, or requestAuthenticationPasswordRecovery to recover the password, or deleteAccount to delete the account after a week. - * - * @param passwordHint Hint for the password; may be empty. - * @param hasRecoveryEmailAddress True, if a recovery email address has been set up. - * @param hasPassportData True, if some Telegram Passport elements were saved. - * @param recoveryEmailAddressPattern Pattern of the email address to which the recovery email was sent; empty until a recovery email has been sent. - */ - public AuthorizationStateWaitPassword(String passwordHint, boolean hasRecoveryEmailAddress, boolean hasPassportData, String recoveryEmailAddressPattern) { - this.passwordHint = passwordHint; - this.hasRecoveryEmailAddress = hasRecoveryEmailAddress; - this.hasPassportData = hasPassportData; - this.recoveryEmailAddressPattern = recoveryEmailAddressPattern; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 112238030; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user has been successfully authorized. TDLib is now ready to answer general requests. - */ - public static class AuthorizationStateReady extends AuthorizationState { - - /** - * The user has been successfully authorized. TDLib is now ready to answer general requests. - */ - public AuthorizationStateReady() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1834871737; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is currently logging out. - */ - public static class AuthorizationStateLoggingOut extends AuthorizationState { - - /** - * The user is currently logging out. - */ - public AuthorizationStateLoggingOut() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 154449270; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * TDLib is closing, all subsequent queries will be answered with the error 500. Note that closing TDLib can take a while. All resources will be freed only after authorizationStateClosed has been received. - */ - public static class AuthorizationStateClosing extends AuthorizationState { - - /** - * TDLib is closing, all subsequent queries will be answered with the error 500. Note that closing TDLib can take a while. All resources will be freed only after authorizationStateClosed has been received. - */ - public AuthorizationStateClosing() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 445855311; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * TDLib client is in its final state. All databases are closed and all resources are released. No other updates will be received after this. All queries will be responded to with error code 500. To continue working, one must create a new instance of the TDLib client. - */ - public static class AuthorizationStateClosed extends AuthorizationState { - - /** - * TDLib client is in its final state. All databases are closed and all resources are released. No other updates will be received after this. All queries will be responded to with error code 500. To continue working, one must create a new instance of the TDLib client. - */ - public AuthorizationStateClosed() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1526047584; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains auto-download settings. - */ - public static class AutoDownloadSettings extends Object { - /** - * True, if the auto-download is enabled. - */ - public boolean isAutoDownloadEnabled; - /** - * The maximum size of a photo file to be auto-downloaded, in bytes. - */ - public int maxPhotoFileSize; - /** - * The maximum size of a video file to be auto-downloaded, in bytes. - */ - public long maxVideoFileSize; - /** - * The maximum size of other file types to be auto-downloaded, in bytes. - */ - public long maxOtherFileSize; - /** - * The maximum suggested bitrate for uploaded videos, in kbit/s. - */ - public int videoUploadBitrate; - /** - * True, if the beginning of video files needs to be preloaded for instant playback. - */ - public boolean preloadLargeVideos; - /** - * True, if the next audio track needs to be preloaded while the user is listening to an audio file. - */ - public boolean preloadNextAudio; - /** - * True, if stories needs to be preloaded. - */ - public boolean preloadStories; - /** - * True, if "use less data for calls" option needs to be enabled. - */ - public boolean useLessDataForCalls; - - /** - * Contains auto-download settings. - */ - public AutoDownloadSettings() { - } - - /** - * Contains auto-download settings. - * - * @param isAutoDownloadEnabled True, if the auto-download is enabled. - * @param maxPhotoFileSize The maximum size of a photo file to be auto-downloaded, in bytes. - * @param maxVideoFileSize The maximum size of a video file to be auto-downloaded, in bytes. - * @param maxOtherFileSize The maximum size of other file types to be auto-downloaded, in bytes. - * @param videoUploadBitrate The maximum suggested bitrate for uploaded videos, in kbit/s. - * @param preloadLargeVideos True, if the beginning of video files needs to be preloaded for instant playback. - * @param preloadNextAudio True, if the next audio track needs to be preloaded while the user is listening to an audio file. - * @param preloadStories True, if stories needs to be preloaded. - * @param useLessDataForCalls True, if "use less data for calls" option needs to be enabled. - */ - public AutoDownloadSettings(boolean isAutoDownloadEnabled, int maxPhotoFileSize, long maxVideoFileSize, long maxOtherFileSize, int videoUploadBitrate, boolean preloadLargeVideos, boolean preloadNextAudio, boolean preloadStories, boolean useLessDataForCalls) { - this.isAutoDownloadEnabled = isAutoDownloadEnabled; - this.maxPhotoFileSize = maxPhotoFileSize; - this.maxVideoFileSize = maxVideoFileSize; - this.maxOtherFileSize = maxOtherFileSize; - this.videoUploadBitrate = videoUploadBitrate; - this.preloadLargeVideos = preloadLargeVideos; - this.preloadNextAudio = preloadNextAudio; - this.preloadStories = preloadStories; - this.useLessDataForCalls = useLessDataForCalls; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 991433696; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains auto-download settings presets for the current user. - */ - public static class AutoDownloadSettingsPresets extends Object { - /** - * Preset with lowest settings; expected to be used by default when roaming. - */ - public AutoDownloadSettings low; - /** - * Preset with medium settings; expected to be used by default when using mobile data. - */ - public AutoDownloadSettings medium; - /** - * Preset with highest settings; expected to be used by default when connected on Wi-Fi. - */ - public AutoDownloadSettings high; - - /** - * Contains auto-download settings presets for the current user. - */ - public AutoDownloadSettingsPresets() { - } - - /** - * Contains auto-download settings presets for the current user. - * - * @param low Preset with lowest settings; expected to be used by default when roaming. - * @param medium Preset with medium settings; expected to be used by default when using mobile data. - * @param high Preset with highest settings; expected to be used by default when connected on Wi-Fi. - */ - public AutoDownloadSettingsPresets(AutoDownloadSettings low, AutoDownloadSettings medium, AutoDownloadSettings high) { - this.low = low; - this.medium = medium; - this.high = high; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -782099166; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes autosave settings. - */ - public static class AutosaveSettings extends Object { - /** - * Default autosave settings for private chats. - */ - public ScopeAutosaveSettings privateChatSettings; - /** - * Default autosave settings for basic group and supergroup chats. - */ - public ScopeAutosaveSettings groupSettings; - /** - * Default autosave settings for channel chats. - */ - public ScopeAutosaveSettings channelSettings; - /** - * Autosave settings for specific chats. - */ - public AutosaveSettingsException[] exceptions; - - /** - * Describes autosave settings. - */ - public AutosaveSettings() { - } - - /** - * Describes autosave settings. - * - * @param privateChatSettings Default autosave settings for private chats. - * @param groupSettings Default autosave settings for basic group and supergroup chats. - * @param channelSettings Default autosave settings for channel chats. - * @param exceptions Autosave settings for specific chats. - */ - public AutosaveSettings(ScopeAutosaveSettings privateChatSettings, ScopeAutosaveSettings groupSettings, ScopeAutosaveSettings channelSettings, AutosaveSettingsException[] exceptions) { - this.privateChatSettings = privateChatSettings; - this.groupSettings = groupSettings; - this.channelSettings = channelSettings; - this.exceptions = exceptions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1629412502; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains autosave settings for a chat, which overrides default settings for the corresponding scope. - */ - public static class AutosaveSettingsException extends Object { - /** - * Chat identifier. - */ - public long chatId; - /** - * Autosave settings for the chat. - */ - public ScopeAutosaveSettings settings; - - /** - * Contains autosave settings for a chat, which overrides default settings for the corresponding scope. - */ - public AutosaveSettingsException() { - } - - /** - * Contains autosave settings for a chat, which overrides default settings for the corresponding scope. - * - * @param chatId Chat identifier. - * @param settings Autosave settings for the chat. - */ - public AutosaveSettingsException(long chatId, ScopeAutosaveSettings settings) { - this.chatId = chatId; - this.settings = settings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1483470280; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes scope of autosave settings. - */ - public abstract static class AutosaveSettingsScope extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - AutosaveSettingsScopePrivateChats.CONSTRUCTOR, - AutosaveSettingsScopeGroupChats.CONSTRUCTOR, - AutosaveSettingsScopeChannelChats.CONSTRUCTOR, - AutosaveSettingsScopeChat.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public AutosaveSettingsScope() { - } - } - - /** - * Autosave settings applied to all private chats without chat-specific settings. - */ - public static class AutosaveSettingsScopePrivateChats extends AutosaveSettingsScope { - - /** - * Autosave settings applied to all private chats without chat-specific settings. - */ - public AutosaveSettingsScopePrivateChats() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1395227007; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Autosave settings applied to all basic group and supergroup chats without chat-specific settings. - */ - public static class AutosaveSettingsScopeGroupChats extends AutosaveSettingsScope { - - /** - * Autosave settings applied to all basic group and supergroup chats without chat-specific settings. - */ - public AutosaveSettingsScopeGroupChats() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 853544526; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Autosave settings applied to all channel chats without chat-specific settings. - */ - public static class AutosaveSettingsScopeChannelChats extends AutosaveSettingsScope { - - /** - * Autosave settings applied to all channel chats without chat-specific settings. - */ - public AutosaveSettingsScopeChannelChats() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -499572783; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Autosave settings applied to a chat. - */ - public static class AutosaveSettingsScopeChat extends AutosaveSettingsScope { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Autosave settings applied to a chat. - */ - public AutosaveSettingsScopeChat() { - } - - /** - * Autosave settings applied to a chat. - * - * @param chatId Chat identifier. - */ - public AutosaveSettingsScopeChat(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1632255255; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a gift that is available for purchase. - */ - public static class AvailableGift extends Object { - /** - * The gift. - */ - public Gift gift; - /** - * Number of gifts that are available for resale. - */ - public int resaleCount; - /** - * The minimum price for the gifts available for resale in Telegram Star equivalent; 0 if there are no such gifts. - */ - public long minResaleStarCount; - /** - * The title of the upgraded gift; empty if the gift isn't available for resale. - */ - public String title; - - /** - * Describes a gift that is available for purchase. - */ - public AvailableGift() { - } - - /** - * Describes a gift that is available for purchase. - * - * @param gift The gift. - * @param resaleCount Number of gifts that are available for resale. - * @param minResaleStarCount The minimum price for the gifts available for resale in Telegram Star equivalent; 0 if there are no such gifts. - * @param title The title of the upgraded gift; empty if the gift isn't available for resale. - */ - public AvailableGift(Gift gift, int resaleCount, long minResaleStarCount, String title) { - this.gift = gift; - this.resaleCount = resaleCount; - this.minResaleStarCount = minResaleStarCount; - this.title = title; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 850530502; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of gifts that can be sent to another user or channel chat. - */ - public static class AvailableGifts extends Object { - /** - * The list of gifts. - */ - public AvailableGift[] gifts; - - /** - * Contains a list of gifts that can be sent to another user or channel chat. - */ - public AvailableGifts() { - } - - /** - * Contains a list of gifts that can be sent to another user or channel chat. - * - * @param gifts The list of gifts. - */ - public AvailableGifts(AvailableGift[] gifts) { - this.gifts = gifts; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1450341886; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents an available reaction. - */ - public static class AvailableReaction extends Object { - /** - * Type of the reaction. - */ - public ReactionType type; - /** - * True, if Telegram Premium is needed to send the reaction. - */ - public boolean needsPremium; - - /** - * Represents an available reaction. - */ - public AvailableReaction() { - } - - /** - * Represents an available reaction. - * - * @param type Type of the reaction. - * @param needsPremium True, if Telegram Premium is needed to send the reaction. - */ - public AvailableReaction(ReactionType type, boolean needsPremium) { - this.type = type; - this.needsPremium = needsPremium; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -117292153; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of reactions that can be added to a message. - */ - public static class AvailableReactions extends Object { - /** - * List of reactions to be shown at the top. - */ - public AvailableReaction[] topReactions; - /** - * List of recently used reactions. - */ - public AvailableReaction[] recentReactions; - /** - * List of popular reactions. - */ - public AvailableReaction[] popularReactions; - /** - * True, if any custom emoji reaction can be added by Telegram Premium subscribers. - */ - public boolean allowCustomEmoji; - /** - * True, if the reactions will be tags and the message can be found by them. - */ - public boolean areTags; - /** - * The reason why the current user can't add reactions to the message, despite some other users can; may be null if none. - */ - @Nullable public ReactionUnavailabilityReason unavailabilityReason; - - /** - * Represents a list of reactions that can be added to a message. - */ - public AvailableReactions() { - } - - /** - * Represents a list of reactions that can be added to a message. - * - * @param topReactions List of reactions to be shown at the top. - * @param recentReactions List of recently used reactions. - * @param popularReactions List of popular reactions. - * @param allowCustomEmoji True, if any custom emoji reaction can be added by Telegram Premium subscribers. - * @param areTags True, if the reactions will be tags and the message can be found by them. - * @param unavailabilityReason The reason why the current user can't add reactions to the message, despite some other users can; may be null if none. - */ - public AvailableReactions(AvailableReaction[] topReactions, AvailableReaction[] recentReactions, AvailableReaction[] popularReactions, boolean allowCustomEmoji, boolean areTags, ReactionUnavailabilityReason unavailabilityReason) { - this.topReactions = topReactions; - this.recentReactions = recentReactions; - this.popularReactions = popularReactions; - this.allowCustomEmoji = allowCustomEmoji; - this.areTags = areTags; - this.unavailabilityReason = unavailabilityReason; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 912529522; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a chat background. - */ - public static class Background extends Object { - /** - * Unique background identifier. - */ - public long id; - /** - * True, if this is one of default backgrounds. - */ - public boolean isDefault; - /** - * True, if the background is dark and is recommended to be used with dark theme. - */ - public boolean isDark; - /** - * Unique background name. - */ - public String name; - /** - * Document with the background; may be null. Null only for filled and chat theme backgrounds. - */ - @Nullable public Document document; - /** - * Type of the background. - */ - public BackgroundType type; - - /** - * Describes a chat background. - */ - public Background() { - } - - /** - * Describes a chat background. - * - * @param id Unique background identifier. - * @param isDefault True, if this is one of default backgrounds. - * @param isDark True, if the background is dark and is recommended to be used with dark theme. - * @param name Unique background name. - * @param document Document with the background; may be null. Null only for filled and chat theme backgrounds. - * @param type Type of the background. - */ - public Background(long id, boolean isDefault, boolean isDark, String name, Document document, BackgroundType type) { - this.id = id; - this.isDefault = isDefault; - this.isDark = isDark; - this.name = name; - this.document = document; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -429971172; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a fill of a background. - */ - public abstract static class BackgroundFill extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - BackgroundFillSolid.CONSTRUCTOR, - BackgroundFillGradient.CONSTRUCTOR, - BackgroundFillFreeformGradient.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public BackgroundFill() { - } - } - - /** - * Describes a solid fill of a background. - */ - public static class BackgroundFillSolid extends BackgroundFill { - /** - * A color of the background in the RGB format. - */ - public int color; - - /** - * Describes a solid fill of a background. - */ - public BackgroundFillSolid() { - } - - /** - * Describes a solid fill of a background. - * - * @param color A color of the background in the RGB format. - */ - public BackgroundFillSolid(int color) { - this.color = color; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1010678813; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a gradient fill of a background. - */ - public static class BackgroundFillGradient extends BackgroundFill { - /** - * A top color of the background in the RGB format. - */ - public int topColor; - /** - * A bottom color of the background in the RGB format. - */ - public int bottomColor; - /** - * Clockwise rotation angle of the gradient, in degrees; 0-359. Must always be divisible by 45. - */ - public int rotationAngle; - - /** - * Describes a gradient fill of a background. - */ - public BackgroundFillGradient() { - } - - /** - * Describes a gradient fill of a background. - * - * @param topColor A top color of the background in the RGB format. - * @param bottomColor A bottom color of the background in the RGB format. - * @param rotationAngle Clockwise rotation angle of the gradient, in degrees; 0-359. Must always be divisible by 45. - */ - public BackgroundFillGradient(int topColor, int bottomColor, int rotationAngle) { - this.topColor = topColor; - this.bottomColor = bottomColor; - this.rotationAngle = rotationAngle; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1839206017; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a freeform gradient fill of a background. - */ - public static class BackgroundFillFreeformGradient extends BackgroundFill { - /** - * A list of 3 or 4 colors of the freeform gradient in the RGB format. - */ - public int[] colors; - - /** - * Describes a freeform gradient fill of a background. - */ - public BackgroundFillFreeformGradient() { - } - - /** - * Describes a freeform gradient fill of a background. - * - * @param colors A list of 3 or 4 colors of the freeform gradient in the RGB format. - */ - public BackgroundFillFreeformGradient(int[] colors) { - this.colors = colors; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1145469255; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the type of background. - */ - public abstract static class BackgroundType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - BackgroundTypeWallpaper.CONSTRUCTOR, - BackgroundTypePattern.CONSTRUCTOR, - BackgroundTypeFill.CONSTRUCTOR, - BackgroundTypeChatTheme.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public BackgroundType() { - } - } - - /** - * A wallpaper in JPEG format. - */ - public static class BackgroundTypeWallpaper extends BackgroundType { - /** - * True, if the wallpaper must be downscaled to fit in 450x450 square and then box-blurred with radius 12. - */ - public boolean isBlurred; - /** - * True, if the background needs to be slightly moved when device is tilted. - */ - public boolean isMoving; - - /** - * A wallpaper in JPEG format. - */ - public BackgroundTypeWallpaper() { - } - - /** - * A wallpaper in JPEG format. - * - * @param isBlurred True, if the wallpaper must be downscaled to fit in 450x450 square and then box-blurred with radius 12. - * @param isMoving True, if the background needs to be slightly moved when device is tilted. - */ - public BackgroundTypeWallpaper(boolean isBlurred, boolean isMoving) { - this.isBlurred = isBlurred; - this.isMoving = isMoving; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1972128891; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A PNG or TGV (gzipped subset of SVG with MIME type "application/x-tgwallpattern") pattern to be combined with the background fill chosen by the user. - */ - public static class BackgroundTypePattern extends BackgroundType { - /** - * Fill of the background. - */ - public BackgroundFill fill; - /** - * Intensity of the pattern when it is shown above the filled background; 0-100. - */ - public int intensity; - /** - * True, if the background fill must be applied only to the pattern itself. All other pixels are black in this case. For dark themes only. - */ - public boolean isInverted; - /** - * True, if the background needs to be slightly moved when device is tilted. - */ - public boolean isMoving; - - /** - * A PNG or TGV (gzipped subset of SVG with MIME type "application/x-tgwallpattern") pattern to be combined with the background fill chosen by the user. - */ - public BackgroundTypePattern() { - } - - /** - * A PNG or TGV (gzipped subset of SVG with MIME type "application/x-tgwallpattern") pattern to be combined with the background fill chosen by the user. - * - * @param fill Fill of the background. - * @param intensity Intensity of the pattern when it is shown above the filled background; 0-100. - * @param isInverted True, if the background fill must be applied only to the pattern itself. All other pixels are black in this case. For dark themes only. - * @param isMoving True, if the background needs to be slightly moved when device is tilted. - */ - public BackgroundTypePattern(BackgroundFill fill, int intensity, boolean isInverted, boolean isMoving) { - this.fill = fill; - this.intensity = intensity; - this.isInverted = isInverted; - this.isMoving = isMoving; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1290213117; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A filled background. - */ - public static class BackgroundTypeFill extends BackgroundType { - /** - * The background fill. - */ - public BackgroundFill fill; - - /** - * A filled background. - */ - public BackgroundTypeFill() { - } - - /** - * A filled background. - * - * @param fill The background fill. - */ - public BackgroundTypeFill(BackgroundFill fill) { - this.fill = fill; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 993008684; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A background from a chat theme based on an emoji; can be used only as a chat background in channels. - */ - public static class BackgroundTypeChatTheme extends BackgroundType { - /** - * Name of the emoji chat theme. - */ - public String themeName; - - /** - * A background from a chat theme based on an emoji; can be used only as a chat background in channels. - */ - public BackgroundTypeChatTheme() { - } - - /** - * A background from a chat theme based on an emoji; can be used only as a chat background in channels. - * - * @param themeName Name of the emoji chat theme. - */ - public BackgroundTypeChatTheme(String themeName) { - this.themeName = themeName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1299879762; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of backgrounds. - */ - public static class Backgrounds extends Object { - /** - * A list of backgrounds. - */ - public Background[] backgrounds; - - /** - * Contains a list of backgrounds. - */ - public Backgrounds() { - } - - /** - * Contains a list of backgrounds. - * - * @param backgrounds A list of backgrounds. - */ - public Backgrounds(Background[] backgrounds) { - this.backgrounds = backgrounds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 724728704; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an action associated with a bank card number. - */ - public static class BankCardActionOpenUrl extends Object { - /** - * Action text. - */ - public String text; - /** - * The URL to be opened. - */ - public String url; - - /** - * Describes an action associated with a bank card number. - */ - public BankCardActionOpenUrl() { - } - - /** - * Describes an action associated with a bank card number. - * - * @param text Action text. - * @param url The URL to be opened. - */ - public BankCardActionOpenUrl(String text, String url) { - this.text = text; - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -196454267; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Information about a bank card. - */ - public static class BankCardInfo extends Object { - /** - * Title of the bank card description. - */ - public String title; - /** - * Actions that can be done with the bank card number. - */ - public BankCardActionOpenUrl[] actions; - - /** - * Information about a bank card. - */ - public BankCardInfo() { - } - - /** - * Information about a bank card. - * - * @param title Title of the bank card description. - * @param actions Actions that can be done with the bank card number. - */ - public BankCardInfo(String title, BankCardActionOpenUrl[] actions) { - this.title = title; - this.actions = actions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2116647730; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a basic group of 0-200 users (must be upgraded to a supergroup to accommodate more than 200 users). - */ - public static class BasicGroup extends Object { - /** - * Group identifier. - */ - public long id; - /** - * Number of members in the group. - */ - public int memberCount; - /** - * Status of the current user in the group. - */ - public ChatMemberStatus status; - /** - * True, if the group is active. - */ - public boolean isActive; - /** - * Identifier of the supergroup to which this group was upgraded; 0 if none. - */ - public long upgradedToSupergroupId; - - /** - * Represents a basic group of 0-200 users (must be upgraded to a supergroup to accommodate more than 200 users). - */ - public BasicGroup() { - } - - /** - * Represents a basic group of 0-200 users (must be upgraded to a supergroup to accommodate more than 200 users). - * - * @param id Group identifier. - * @param memberCount Number of members in the group. - * @param status Status of the current user in the group. - * @param isActive True, if the group is active. - * @param upgradedToSupergroupId Identifier of the supergroup to which this group was upgraded; 0 if none. - */ - public BasicGroup(long id, int memberCount, ChatMemberStatus status, boolean isActive, long upgradedToSupergroupId) { - this.id = id; - this.memberCount = memberCount; - this.status = status; - this.isActive = isActive; - this.upgradedToSupergroupId = upgradedToSupergroupId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -194767217; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains full information about a basic group. - */ - public static class BasicGroupFullInfo extends Object { - /** - * Chat photo; may be null if empty or unknown. If non-null, then it is the same photo as in chat.photo. - */ - @Nullable public ChatPhoto photo; - /** - * Group description. Updated only after the basic group is opened. - */ - public String description; - /** - * User identifier of the creator of the group; 0 if unknown. - */ - public long creatorUserId; - /** - * Group members. - */ - public ChatMember[] members; - /** - * True, if non-administrators and non-bots can be hidden in responses to getSupergroupMembers and searchChatMembers for non-administrators after upgrading the basic group to a supergroup. - */ - public boolean canHideMembers; - /** - * True, if aggressive anti-spam checks can be enabled or disabled in the supergroup after upgrading the basic group to a supergroup. - */ - public boolean canToggleAggressiveAntiSpam; - /** - * Primary invite link for this group; may be null. For chat administrators with canInviteUsers right only. Updated only after the basic group is opened. - */ - @Nullable public ChatInviteLink inviteLink; - /** - * List of commands of bots in the group. - */ - public BotCommands[] botCommands; - - /** - * Contains full information about a basic group. - */ - public BasicGroupFullInfo() { - } - - /** - * Contains full information about a basic group. - * - * @param photo Chat photo; may be null if empty or unknown. If non-null, then it is the same photo as in chat.photo. - * @param description Group description. Updated only after the basic group is opened. - * @param creatorUserId User identifier of the creator of the group; 0 if unknown. - * @param members Group members. - * @param canHideMembers True, if non-administrators and non-bots can be hidden in responses to getSupergroupMembers and searchChatMembers for non-administrators after upgrading the basic group to a supergroup. - * @param canToggleAggressiveAntiSpam True, if aggressive anti-spam checks can be enabled or disabled in the supergroup after upgrading the basic group to a supergroup. - * @param inviteLink Primary invite link for this group; may be null. For chat administrators with canInviteUsers right only. Updated only after the basic group is opened. - * @param botCommands List of commands of bots in the group. - */ - public BasicGroupFullInfo(ChatPhoto photo, String description, long creatorUserId, ChatMember[] members, boolean canHideMembers, boolean canToggleAggressiveAntiSpam, ChatInviteLink inviteLink, BotCommands[] botCommands) { - this.photo = photo; - this.description = description; - this.creatorUserId = creatorUserId; - this.members = members; - this.canHideMembers = canHideMembers; - this.canToggleAggressiveAntiSpam = canToggleAggressiveAntiSpam; - this.inviteLink = inviteLink; - this.botCommands = botCommands; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1879035520; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a birthdate of a user. - */ - public static class Birthdate extends Object { - /** - * Day of the month; 1-31. - */ - public int day; - /** - * Month of the year; 1-12. - */ - public int month; - /** - * Birth year; 0 if unknown. - */ - public int year; - - /** - * Represents a birthdate of a user. - */ - public Birthdate() { - } - - /** - * Represents a birthdate of a user. - * - * @param day Day of the month; 1-31. - * @param month Month of the year; 1-12. - * @param year Birth year; 0 if unknown. - */ - public Birthdate(int day, int month, int year) { - this.day = day; - this.month = month; - this.year = year; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1644064030; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of block list. - */ - public abstract static class BlockList extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - BlockListMain.CONSTRUCTOR, - BlockListStories.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public BlockList() { - } - } - - /** - * The main block list that disallows writing messages to the current user, receiving their status and photo, viewing of stories, and some other actions. - */ - public static class BlockListMain extends BlockList { - - /** - * The main block list that disallows writing messages to the current user, receiving their status and photo, viewing of stories, and some other actions. - */ - public BlockListMain() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1352930172; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The block list that disallows viewing of stories of the current user. - */ - public static class BlockListStories extends BlockList { - - /** - * The block list that disallows viewing of stories of the current user. - */ - public BlockListStories() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 103323228; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a command supported by a bot. - */ - public static class BotCommand extends Object { - /** - * Text of the bot command. - */ - public String command; - /** - * Description of the bot command. - */ - public String description; - - /** - * Represents a command supported by a bot. - */ - public BotCommand() { - } - - /** - * Represents a command supported by a bot. - * - * @param command Text of the bot command. - * @param description Description of the bot command. - */ - public BotCommand(String command, String description) { - this.command = command; - this.description = description; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1032140601; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents the scope to which bot commands are relevant. - */ - public abstract static class BotCommandScope extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - BotCommandScopeDefault.CONSTRUCTOR, - BotCommandScopeAllPrivateChats.CONSTRUCTOR, - BotCommandScopeAllGroupChats.CONSTRUCTOR, - BotCommandScopeAllChatAdministrators.CONSTRUCTOR, - BotCommandScopeChat.CONSTRUCTOR, - BotCommandScopeChatAdministrators.CONSTRUCTOR, - BotCommandScopeChatMember.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public BotCommandScope() { - } - } - - /** - * A scope covering all users. - */ - public static class BotCommandScopeDefault extends BotCommandScope { - - /** - * A scope covering all users. - */ - public BotCommandScopeDefault() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 795652779; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A scope covering all private chats. - */ - public static class BotCommandScopeAllPrivateChats extends BotCommandScope { - - /** - * A scope covering all private chats. - */ - public BotCommandScopeAllPrivateChats() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -344889543; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A scope covering all group and supergroup chats. - */ - public static class BotCommandScopeAllGroupChats extends BotCommandScope { - - /** - * A scope covering all group and supergroup chats. - */ - public BotCommandScopeAllGroupChats() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -981088162; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A scope covering all group and supergroup chat administrators. - */ - public static class BotCommandScopeAllChatAdministrators extends BotCommandScope { - - /** - * A scope covering all group and supergroup chat administrators. - */ - public BotCommandScopeAllChatAdministrators() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1998329169; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A scope covering all members of a chat. - */ - public static class BotCommandScopeChat extends BotCommandScope { - /** - * Chat identifier. - */ - public long chatId; - - /** - * A scope covering all members of a chat. - */ - public BotCommandScopeChat() { - } - - /** - * A scope covering all members of a chat. - * - * @param chatId Chat identifier. - */ - public BotCommandScopeChat(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -430234971; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A scope covering all administrators of a chat. - */ - public static class BotCommandScopeChatAdministrators extends BotCommandScope { - /** - * Chat identifier. - */ - public long chatId; - - /** - * A scope covering all administrators of a chat. - */ - public BotCommandScopeChatAdministrators() { - } - - /** - * A scope covering all administrators of a chat. - * - * @param chatId Chat identifier. - */ - public BotCommandScopeChatAdministrators(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1119682126; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A scope covering a member of a chat. - */ - public static class BotCommandScopeChatMember extends BotCommandScope { - /** - * Chat identifier. - */ - public long chatId; - /** - * User identifier. - */ - public long userId; - - /** - * A scope covering a member of a chat. - */ - public BotCommandScopeChatMember() { - } - - /** - * A scope covering a member of a chat. - * - * @param chatId Chat identifier. - * @param userId User identifier. - */ - public BotCommandScopeChatMember(long chatId, long userId) { - this.chatId = chatId; - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -211380494; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of bot commands. - */ - public static class BotCommands extends Object { - /** - * Bot's user identifier. - */ - public long botUserId; - /** - * List of bot commands. - */ - public BotCommand[] commands; - - /** - * Contains a list of bot commands. - */ - public BotCommands() { - } - - /** - * Contains a list of bot commands. - * - * @param botUserId Bot's user identifier. - * @param commands List of bot commands. - */ - public BotCommands(long botUserId, BotCommand[] commands) { - this.botUserId = botUserId; - this.commands = commands; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1741364468; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a bot. - */ - public static class BotInfo extends Object { - /** - * The text that is shown on the bot's profile page and is sent together with the link when users share the bot. - */ - public String shortDescription; - /** - * The text shown in the chat with the bot if the chat is empty. - */ - public String description; - /** - * Photo shown in the chat with the bot if the chat is empty; may be null. - */ - @Nullable public Photo photo; - /** - * Animation shown in the chat with the bot if the chat is empty; may be null. - */ - @Nullable public Animation animation; - /** - * Information about a button to show instead of the bot commands menu button; may be null if ordinary bot commands menu must be shown. - */ - @Nullable public BotMenuButton menuButton; - /** - * List of the bot commands. - */ - public BotCommand[] commands; - /** - * The HTTP link to the privacy policy of the bot. If empty, then /privacy command must be used if supported by the bot. If the command isn't supported, then https://telegram.org/privacy-tpa must be opened. - */ - public String privacyPolicyUrl; - /** - * Default administrator rights for adding the bot to basic group and supergroup chats; may be null. - */ - @Nullable public ChatAdministratorRights defaultGroupAdministratorRights; - /** - * Default administrator rights for adding the bot to channels; may be null. - */ - @Nullable public ChatAdministratorRights defaultChannelAdministratorRights; - /** - * Information about the affiliate program of the bot; may be null if none. - */ - @Nullable public AffiliateProgramInfo affiliateProgram; - /** - * Default light background color for bot Web Apps; -1 if not specified. - */ - public int webAppBackgroundLightColor; - /** - * Default dark background color for bot Web Apps; -1 if not specified. - */ - public int webAppBackgroundDarkColor; - /** - * Default light header color for bot Web Apps; -1 if not specified. - */ - public int webAppHeaderLightColor; - /** - * Default dark header color for bot Web Apps; -1 if not specified. - */ - public int webAppHeaderDarkColor; - /** - * Parameters of the verification that can be provided by the bot; may be null if none or the current user isn't the owner of the bot. - */ - @Nullable public BotVerificationParameters verificationParameters; - /** - * True, if the bot's revenue statistics are available to the current user. - */ - public boolean canGetRevenueStatistics; - /** - * True, if the bot can manage emoji status of the current user. - */ - public boolean canManageEmojiStatus; - /** - * True, if the bot has media previews. - */ - public boolean hasMediaPreviews; - /** - * The internal link, which can be used to edit bot commands; may be null. - */ - @Nullable public InternalLinkType editCommandsLink; - /** - * The internal link, which can be used to edit bot description; may be null. - */ - @Nullable public InternalLinkType editDescriptionLink; - /** - * The internal link, which can be used to edit the photo or animation shown in the chat with the bot if the chat is empty; may be null. - */ - @Nullable public InternalLinkType editDescriptionMediaLink; - /** - * The internal link, which can be used to edit bot settings; may be null. - */ - @Nullable public InternalLinkType editSettingsLink; - - /** - * Contains information about a bot. - */ - public BotInfo() { - } - - /** - * Contains information about a bot. - * - * @param shortDescription The text that is shown on the bot's profile page and is sent together with the link when users share the bot. - * @param description The text shown in the chat with the bot if the chat is empty. - * @param photo Photo shown in the chat with the bot if the chat is empty; may be null. - * @param animation Animation shown in the chat with the bot if the chat is empty; may be null. - * @param menuButton Information about a button to show instead of the bot commands menu button; may be null if ordinary bot commands menu must be shown. - * @param commands List of the bot commands. - * @param privacyPolicyUrl The HTTP link to the privacy policy of the bot. If empty, then /privacy command must be used if supported by the bot. If the command isn't supported, then https://telegram.org/privacy-tpa must be opened. - * @param defaultGroupAdministratorRights Default administrator rights for adding the bot to basic group and supergroup chats; may be null. - * @param defaultChannelAdministratorRights Default administrator rights for adding the bot to channels; may be null. - * @param affiliateProgram Information about the affiliate program of the bot; may be null if none. - * @param webAppBackgroundLightColor Default light background color for bot Web Apps; -1 if not specified. - * @param webAppBackgroundDarkColor Default dark background color for bot Web Apps; -1 if not specified. - * @param webAppHeaderLightColor Default light header color for bot Web Apps; -1 if not specified. - * @param webAppHeaderDarkColor Default dark header color for bot Web Apps; -1 if not specified. - * @param verificationParameters Parameters of the verification that can be provided by the bot; may be null if none or the current user isn't the owner of the bot. - * @param canGetRevenueStatistics True, if the bot's revenue statistics are available to the current user. - * @param canManageEmojiStatus True, if the bot can manage emoji status of the current user. - * @param hasMediaPreviews True, if the bot has media previews. - * @param editCommandsLink The internal link, which can be used to edit bot commands; may be null. - * @param editDescriptionLink The internal link, which can be used to edit bot description; may be null. - * @param editDescriptionMediaLink The internal link, which can be used to edit the photo or animation shown in the chat with the bot if the chat is empty; may be null. - * @param editSettingsLink The internal link, which can be used to edit bot settings; may be null. - */ - public BotInfo(String shortDescription, String description, Photo photo, Animation animation, BotMenuButton menuButton, BotCommand[] commands, String privacyPolicyUrl, ChatAdministratorRights defaultGroupAdministratorRights, ChatAdministratorRights defaultChannelAdministratorRights, AffiliateProgramInfo affiliateProgram, int webAppBackgroundLightColor, int webAppBackgroundDarkColor, int webAppHeaderLightColor, int webAppHeaderDarkColor, BotVerificationParameters verificationParameters, boolean canGetRevenueStatistics, boolean canManageEmojiStatus, boolean hasMediaPreviews, InternalLinkType editCommandsLink, InternalLinkType editDescriptionLink, InternalLinkType editDescriptionMediaLink, InternalLinkType editSettingsLink) { - this.shortDescription = shortDescription; - this.description = description; - this.photo = photo; - this.animation = animation; - this.menuButton = menuButton; - this.commands = commands; - this.privacyPolicyUrl = privacyPolicyUrl; - this.defaultGroupAdministratorRights = defaultGroupAdministratorRights; - this.defaultChannelAdministratorRights = defaultChannelAdministratorRights; - this.affiliateProgram = affiliateProgram; - this.webAppBackgroundLightColor = webAppBackgroundLightColor; - this.webAppBackgroundDarkColor = webAppBackgroundDarkColor; - this.webAppHeaderLightColor = webAppHeaderLightColor; - this.webAppHeaderDarkColor = webAppHeaderDarkColor; - this.verificationParameters = verificationParameters; - this.canGetRevenueStatistics = canGetRevenueStatistics; - this.canManageEmojiStatus = canManageEmojiStatus; - this.hasMediaPreviews = hasMediaPreviews; - this.editCommandsLink = editCommandsLink; - this.editDescriptionLink = editDescriptionLink; - this.editDescriptionMediaLink = editDescriptionMediaLink; - this.editSettingsLink = editSettingsLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1771886272; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes media previews of a bot. - */ - public static class BotMediaPreview extends Object { - /** - * Point in time (Unix timestamp) when the preview was added or changed last time. - */ - public int date; - /** - * Content of the preview; may only be of the types storyContentPhoto, storyContentVideo, or storyContentUnsupported. - */ - public StoryContent content; - - /** - * Describes media previews of a bot. - */ - public BotMediaPreview() { - } - - /** - * Describes media previews of a bot. - * - * @param date Point in time (Unix timestamp) when the preview was added or changed last time. - * @param content Content of the preview; may only be of the types storyContentPhoto, storyContentVideo, or storyContentUnsupported. - */ - public BotMediaPreview(int date, StoryContent content) { - this.date = date; - this.content = content; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1632264984; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of media previews of a bot for the given language and the list of languages for which the bot has dedicated previews. - */ - public static class BotMediaPreviewInfo extends Object { - /** - * List of media previews. - */ - public BotMediaPreview[] previews; - /** - * List of language codes for which the bot has dedicated previews. - */ - public String[] languageCodes; - - /** - * Contains a list of media previews of a bot for the given language and the list of languages for which the bot has dedicated previews. - */ - public BotMediaPreviewInfo() { - } - - /** - * Contains a list of media previews of a bot for the given language and the list of languages for which the bot has dedicated previews. - * - * @param previews List of media previews. - * @param languageCodes List of language codes for which the bot has dedicated previews. - */ - public BotMediaPreviewInfo(BotMediaPreview[] previews, String[] languageCodes) { - this.previews = previews; - this.languageCodes = languageCodes; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -284783012; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of media previews of a bot. - */ - public static class BotMediaPreviews extends Object { - /** - * List of media previews. - */ - public BotMediaPreview[] previews; - - /** - * Contains a list of media previews of a bot. - */ - public BotMediaPreviews() { - } - - /** - * Contains a list of media previews of a bot. - * - * @param previews List of media previews. - */ - public BotMediaPreviews(BotMediaPreview[] previews) { - this.previews = previews; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1787720586; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a button to be shown instead of bot commands menu button. - */ - public static class BotMenuButton extends Object { - /** - * Text of the button. - */ - public String text; - /** - * URL of a Web App to open when the button is pressed. If the link is of the type internalLinkTypeWebApp, then it must be processed accordingly. Otherwise, the link must be passed to openWebApp. - */ - public String url; - - /** - * Describes a button to be shown instead of bot commands menu button. - */ - public BotMenuButton() { - } - - /** - * Describes a button to be shown instead of bot commands menu button. - * - * @param text Text of the button. - * @param url URL of a Web App to open when the button is pressed. If the link is of the type internalLinkTypeWebApp, then it must be processed accordingly. Otherwise, the link must be passed to openWebApp. - */ - public BotMenuButton(String text, String url) { - this.text = text; - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -944407322; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes verification status provided by a bot. - */ - public static class BotVerification extends Object { - /** - * Identifier of the bot that provided the verification. - */ - public long botUserId; - /** - * Identifier of the custom emoji that is used as the verification sign. - */ - public long iconCustomEmojiId; - /** - * Custom description of verification reason set by the bot. Can contain only Mention, Hashtag, Cashtag, PhoneNumber, BankCardNumber, Url, and EmailAddress entities. - */ - public FormattedText customDescription; - - /** - * Describes verification status provided by a bot. - */ - public BotVerification() { - } - - /** - * Describes verification status provided by a bot. - * - * @param botUserId Identifier of the bot that provided the verification. - * @param iconCustomEmojiId Identifier of the custom emoji that is used as the verification sign. - * @param customDescription Custom description of verification reason set by the bot. Can contain only Mention, Hashtag, Cashtag, PhoneNumber, BankCardNumber, Url, and EmailAddress entities. - */ - public BotVerification(long botUserId, long iconCustomEmojiId, FormattedText customDescription) { - this.botUserId = botUserId; - this.iconCustomEmojiId = iconCustomEmojiId; - this.customDescription = customDescription; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1319061774; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes parameters of verification that is provided by a bot. - */ - public static class BotVerificationParameters extends Object { - /** - * Identifier of the custom emoji that is used as the verification sign. - */ - public long iconCustomEmojiId; - /** - * Name of the organization that provides verification. - */ - public String organizationName; - /** - * Default custom description of verification reason to be used as placeholder in setMessageSenderBotVerification; may be null if none. - */ - @Nullable public FormattedText defaultCustomDescription; - /** - * True, if the bot is allowed to provide custom description for verified entities. - */ - public boolean canSetCustomDescription; - - /** - * Describes parameters of verification that is provided by a bot. - */ - public BotVerificationParameters() { - } - - /** - * Describes parameters of verification that is provided by a bot. - * - * @param iconCustomEmojiId Identifier of the custom emoji that is used as the verification sign. - * @param organizationName Name of the organization that provides verification. - * @param defaultCustomDescription Default custom description of verification reason to be used as placeholder in setMessageSenderBotVerification; may be null if none. - * @param canSetCustomDescription True, if the bot is allowed to provide custom description for verified entities. - */ - public BotVerificationParameters(long iconCustomEmojiId, String organizationName, FormattedText defaultCustomDescription, boolean canSetCustomDescription) { - this.iconCustomEmojiId = iconCustomEmojiId; - this.organizationName = organizationName; - this.defaultCustomDescription = defaultCustomDescription; - this.canSetCustomDescription = canSetCustomDescription; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -723737249; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a reason why a bot was allowed to write messages to the current user. - */ - public abstract static class BotWriteAccessAllowReason extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - BotWriteAccessAllowReasonConnectedWebsite.CONSTRUCTOR, - BotWriteAccessAllowReasonAddedToAttachmentMenu.CONSTRUCTOR, - BotWriteAccessAllowReasonLaunchedWebApp.CONSTRUCTOR, - BotWriteAccessAllowReasonAcceptedRequest.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public BotWriteAccessAllowReason() { - } - } - - /** - * The user connected a website by logging in using Telegram Login Widget on it. - */ - public static class BotWriteAccessAllowReasonConnectedWebsite extends BotWriteAccessAllowReason { - /** - * Domain name of the connected website. - */ - public String domainName; - - /** - * The user connected a website by logging in using Telegram Login Widget on it. - */ - public BotWriteAccessAllowReasonConnectedWebsite() { - } - - /** - * The user connected a website by logging in using Telegram Login Widget on it. - * - * @param domainName Domain name of the connected website. - */ - public BotWriteAccessAllowReasonConnectedWebsite(String domainName) { - this.domainName = domainName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2016325603; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user added the bot to attachment or side menu using toggleBotIsAddedToAttachmentMenu. - */ - public static class BotWriteAccessAllowReasonAddedToAttachmentMenu extends BotWriteAccessAllowReason { - - /** - * The user added the bot to attachment or side menu using toggleBotIsAddedToAttachmentMenu. - */ - public BotWriteAccessAllowReasonAddedToAttachmentMenu() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2104795235; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user launched a Web App using getWebAppLinkUrl. - */ - public static class BotWriteAccessAllowReasonLaunchedWebApp extends BotWriteAccessAllowReason { - /** - * Information about the Web App. - */ - public WebApp webApp; - - /** - * The user launched a Web App using getWebAppLinkUrl. - */ - public BotWriteAccessAllowReasonLaunchedWebApp() { - } - - /** - * The user launched a Web App using getWebAppLinkUrl. - * - * @param webApp Information about the Web App. - */ - public BotWriteAccessAllowReasonLaunchedWebApp(WebApp webApp) { - this.webApp = webApp; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -240843561; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user accepted bot's request to send messages with allowBotToSendMessages. - */ - public static class BotWriteAccessAllowReasonAcceptedRequest extends BotWriteAccessAllowReason { - - /** - * The user accepted bot's request to send messages with allowBotToSendMessages. - */ - public BotWriteAccessAllowReasonAcceptedRequest() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1983497220; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a built-in theme of an official app. - */ - public abstract static class BuiltInTheme extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - BuiltInThemeClassic.CONSTRUCTOR, - BuiltInThemeDay.CONSTRUCTOR, - BuiltInThemeNight.CONSTRUCTOR, - BuiltInThemeTinted.CONSTRUCTOR, - BuiltInThemeArctic.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public BuiltInTheme() { - } - } - - /** - * Classic light theme. - */ - public static class BuiltInThemeClassic extends BuiltInTheme { - - /** - * Classic light theme. - */ - public BuiltInThemeClassic() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -696429972; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Regular light theme. - */ - public static class BuiltInThemeDay extends BuiltInTheme { - - /** - * Regular light theme. - */ - public BuiltInThemeDay() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 411774754; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Regular dark theme. - */ - public static class BuiltInThemeNight extends BuiltInTheme { - - /** - * Regular dark theme. - */ - public BuiltInThemeNight() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 429672829; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Tinted dark theme. - */ - public static class BuiltInThemeTinted extends BuiltInTheme { - - /** - * Tinted dark theme. - */ - public BuiltInThemeTinted() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 513932973; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Arctic light theme. - */ - public static class BuiltInThemeArctic extends BuiltInTheme { - - /** - * Arctic light theme. - */ - public BuiltInThemeArctic() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1427659554; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes conditions for sending of away messages by a Telegram Business account. - */ - public abstract static class BusinessAwayMessageSchedule extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - BusinessAwayMessageScheduleAlways.CONSTRUCTOR, - BusinessAwayMessageScheduleOutsideOfOpeningHours.CONSTRUCTOR, - BusinessAwayMessageScheduleCustom.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public BusinessAwayMessageSchedule() { - } - } - - /** - * Send away messages always. - */ - public static class BusinessAwayMessageScheduleAlways extends BusinessAwayMessageSchedule { - - /** - * Send away messages always. - */ - public BusinessAwayMessageScheduleAlways() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -910564679; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Send away messages outside of the business opening hours. - */ - public static class BusinessAwayMessageScheduleOutsideOfOpeningHours extends BusinessAwayMessageSchedule { - - /** - * Send away messages outside of the business opening hours. - */ - public BusinessAwayMessageScheduleOutsideOfOpeningHours() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -968630506; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Send away messages only in the specified time span. - */ - public static class BusinessAwayMessageScheduleCustom extends BusinessAwayMessageSchedule { - /** - * Point in time (Unix timestamp) when the away messages will start to be sent. - */ - public int startDate; - /** - * Point in time (Unix timestamp) when the away messages will stop to be sent. - */ - public int endDate; - - /** - * Send away messages only in the specified time span. - */ - public BusinessAwayMessageScheduleCustom() { - } - - /** - * Send away messages only in the specified time span. - * - * @param startDate Point in time (Unix timestamp) when the away messages will start to be sent. - * @param endDate Point in time (Unix timestamp) when the away messages will stop to be sent. - */ - public BusinessAwayMessageScheduleCustom(int startDate, int endDate) { - this.startDate = startDate; - this.endDate = endDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1967108654; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes settings for messages that are automatically sent by a Telegram Business account when it is away. - */ - public static class BusinessAwayMessageSettings extends Object { - /** - * Unique quick reply shortcut identifier for the away messages. - */ - public int shortcutId; - /** - * Chosen recipients of the away messages. - */ - public BusinessRecipients recipients; - /** - * Settings used to check whether the current user is away. - */ - public BusinessAwayMessageSchedule schedule; - /** - * True, if the messages must not be sent if the account was online in the last 10 minutes. - */ - public boolean offlineOnly; - - /** - * Describes settings for messages that are automatically sent by a Telegram Business account when it is away. - */ - public BusinessAwayMessageSettings() { - } - - /** - * Describes settings for messages that are automatically sent by a Telegram Business account when it is away. - * - * @param shortcutId Unique quick reply shortcut identifier for the away messages. - * @param recipients Chosen recipients of the away messages. - * @param schedule Settings used to check whether the current user is away. - * @param offlineOnly True, if the messages must not be sent if the account was online in the last 10 minutes. - */ - public BusinessAwayMessageSettings(int shortcutId, BusinessRecipients recipients, BusinessAwayMessageSchedule schedule, boolean offlineOnly) { - this.shortcutId = shortcutId; - this.recipients = recipients; - this.schedule = schedule; - this.offlineOnly = offlineOnly; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 353084137; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a business bot that manages the chat. - */ - public static class BusinessBotManageBar extends Object { - /** - * User identifier of the bot. - */ - public long botUserId; - /** - * URL to be opened to manage the bot. - */ - public String manageUrl; - /** - * True, if the bot is paused. Use toggleBusinessConnectedBotChatIsPaused to change the value of the field. - */ - public boolean isBotPaused; - /** - * True, if the bot can reply. - */ - public boolean canBotReply; - - /** - * Contains information about a business bot that manages the chat. - */ - public BusinessBotManageBar() { - } - - /** - * Contains information about a business bot that manages the chat. - * - * @param botUserId User identifier of the bot. - * @param manageUrl URL to be opened to manage the bot. - * @param isBotPaused True, if the bot is paused. Use toggleBusinessConnectedBotChatIsPaused to change the value of the field. - * @param canBotReply True, if the bot can reply. - */ - public BusinessBotManageBar(long botUserId, String manageUrl, boolean isBotPaused, boolean canBotReply) { - this.botUserId = botUserId; - this.manageUrl = manageUrl; - this.isBotPaused = isBotPaused; - this.canBotReply = canBotReply; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -311399806; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes rights of a business bot. - */ - public static class BusinessBotRights extends Object { - /** - * True, if the bot can send and edit messages in the private chats that had incoming messages in the last 24 hours. - */ - public boolean canReply; - /** - * True, if the bot can mark incoming private messages as read. - */ - public boolean canReadMessages; - /** - * True, if the bot can delete sent messages. - */ - public boolean canDeleteSentMessages; - /** - * True, if the bot can delete any message. - */ - public boolean canDeleteAllMessages; - /** - * True, if the bot can edit name of the business account. - */ - public boolean canEditName; - /** - * True, if the bot can edit bio of the business account. - */ - public boolean canEditBio; - /** - * True, if the bot can edit profile photo of the business account. - */ - public boolean canEditProfilePhoto; - /** - * True, if the bot can edit username of the business account. - */ - public boolean canEditUsername; - /** - * True, if the bot can view gifts and Telegram Star amount owned by the business account. - */ - public boolean canViewGiftsAndStars; - /** - * True, if the bot can sell regular gifts received by the business account. - */ - public boolean canSellGifts; - /** - * True, if the bot can change gift receiving settings of the business account. - */ - public boolean canChangeGiftSettings; - /** - * True, if the bot can transfer and upgrade gifts received by the business account. - */ - public boolean canTransferAndUpgradeGifts; - /** - * True, if the bot can transfer Telegram Stars received by the business account to account of the bot, or use them to upgrade and transfer gifts. - */ - public boolean canTransferStars; - /** - * True, if the bot can post, edit and delete stories. - */ - public boolean canManageStories; - - /** - * Describes rights of a business bot. - */ - public BusinessBotRights() { - } - - /** - * Describes rights of a business bot. - * - * @param canReply True, if the bot can send and edit messages in the private chats that had incoming messages in the last 24 hours. - * @param canReadMessages True, if the bot can mark incoming private messages as read. - * @param canDeleteSentMessages True, if the bot can delete sent messages. - * @param canDeleteAllMessages True, if the bot can delete any message. - * @param canEditName True, if the bot can edit name of the business account. - * @param canEditBio True, if the bot can edit bio of the business account. - * @param canEditProfilePhoto True, if the bot can edit profile photo of the business account. - * @param canEditUsername True, if the bot can edit username of the business account. - * @param canViewGiftsAndStars True, if the bot can view gifts and Telegram Star amount owned by the business account. - * @param canSellGifts True, if the bot can sell regular gifts received by the business account. - * @param canChangeGiftSettings True, if the bot can change gift receiving settings of the business account. - * @param canTransferAndUpgradeGifts True, if the bot can transfer and upgrade gifts received by the business account. - * @param canTransferStars True, if the bot can transfer Telegram Stars received by the business account to account of the bot, or use them to upgrade and transfer gifts. - * @param canManageStories True, if the bot can post, edit and delete stories. - */ - public BusinessBotRights(boolean canReply, boolean canReadMessages, boolean canDeleteSentMessages, boolean canDeleteAllMessages, boolean canEditName, boolean canEditBio, boolean canEditProfilePhoto, boolean canEditUsername, boolean canViewGiftsAndStars, boolean canSellGifts, boolean canChangeGiftSettings, boolean canTransferAndUpgradeGifts, boolean canTransferStars, boolean canManageStories) { - this.canReply = canReply; - this.canReadMessages = canReadMessages; - this.canDeleteSentMessages = canDeleteSentMessages; - this.canDeleteAllMessages = canDeleteAllMessages; - this.canEditName = canEditName; - this.canEditBio = canEditBio; - this.canEditProfilePhoto = canEditProfilePhoto; - this.canEditUsername = canEditUsername; - this.canViewGiftsAndStars = canViewGiftsAndStars; - this.canSellGifts = canSellGifts; - this.canChangeGiftSettings = canChangeGiftSettings; - this.canTransferAndUpgradeGifts = canTransferAndUpgradeGifts; - this.canTransferStars = canTransferStars; - this.canManageStories = canManageStories; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1224839038; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a business chat link. - */ - public static class BusinessChatLink extends Object { - /** - * The HTTPS link. - */ - public String link; - /** - * Message draft text that will be added to the input field. - */ - public FormattedText text; - /** - * Link title. - */ - public String title; - /** - * Number of times the link was used. - */ - public int viewCount; - - /** - * Contains information about a business chat link. - */ - public BusinessChatLink() { - } - - /** - * Contains information about a business chat link. - * - * @param link The HTTPS link. - * @param text Message draft text that will be added to the input field. - * @param title Link title. - * @param viewCount Number of times the link was used. - */ - public BusinessChatLink(String link, FormattedText text, String title, int viewCount) { - this.link = link; - this.text = text; - this.title = title; - this.viewCount = viewCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1902539901; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a business chat link. - */ - public static class BusinessChatLinkInfo extends Object { - /** - * Identifier of the private chat that created the link. - */ - public long chatId; - /** - * Message draft text that must be added to the input field. - */ - public FormattedText text; - - /** - * Contains information about a business chat link. - */ - public BusinessChatLinkInfo() { - } - - /** - * Contains information about a business chat link. - * - * @param chatId Identifier of the private chat that created the link. - * @param text Message draft text that must be added to the input field. - */ - public BusinessChatLinkInfo(long chatId, FormattedText text) { - this.chatId = chatId; - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -864865105; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of business chat links created by the user. - */ - public static class BusinessChatLinks extends Object { - /** - * List of links. - */ - public BusinessChatLink[] links; - - /** - * Contains a list of business chat links created by the user. - */ - public BusinessChatLinks() { - } - - /** - * Contains a list of business chat links created by the user. - * - * @param links List of links. - */ - public BusinessChatLinks(BusinessChatLink[] links) { - this.links = links; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 79067036; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a bot connected to a business account. - */ - public static class BusinessConnectedBot extends Object { - /** - * User identifier of the bot. - */ - public long botUserId; - /** - * Private chats that will be accessible to the bot. - */ - public BusinessRecipients recipients; - /** - * Rights of the bot. - */ - public BusinessBotRights rights; - - /** - * Describes a bot connected to a business account. - */ - public BusinessConnectedBot() { - } - - /** - * Describes a bot connected to a business account. - * - * @param botUserId User identifier of the bot. - * @param recipients Private chats that will be accessible to the bot. - * @param rights Rights of the bot. - */ - public BusinessConnectedBot(long botUserId, BusinessRecipients recipients, BusinessBotRights rights) { - this.botUserId = botUserId; - this.recipients = recipients; - this.rights = rights; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1815439021; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a connection of the bot with a business account. - */ - public static class BusinessConnection extends Object { - /** - * Unique identifier of the connection. - */ - public String id; - /** - * Identifier of the business user who created the connection. - */ - public long userId; - /** - * Chat identifier of the private chat with the user. - */ - public long userChatId; - /** - * Point in time (Unix timestamp) when the connection was established. - */ - public int date; - /** - * Rights of the bot; may be null if the connection was disabled. - */ - @Nullable public BusinessBotRights rights; - /** - * True, if the connection is enabled; false otherwise. - */ - public boolean isEnabled; - - /** - * Describes a connection of the bot with a business account. - */ - public BusinessConnection() { - } - - /** - * Describes a connection of the bot with a business account. - * - * @param id Unique identifier of the connection. - * @param userId Identifier of the business user who created the connection. - * @param userChatId Chat identifier of the private chat with the user. - * @param date Point in time (Unix timestamp) when the connection was established. - * @param rights Rights of the bot; may be null if the connection was disabled. - * @param isEnabled True, if the connection is enabled; false otherwise. - */ - public BusinessConnection(String id, long userId, long userChatId, int date, BusinessBotRights rights, boolean isEnabled) { - this.id = id; - this.userId = userId; - this.userChatId = userChatId; - this.date = date; - this.rights = rights; - this.isEnabled = isEnabled; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -995703933; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a feature available to Business user accounts. - */ - public abstract static class BusinessFeature extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - BusinessFeatureLocation.CONSTRUCTOR, - BusinessFeatureOpeningHours.CONSTRUCTOR, - BusinessFeatureQuickReplies.CONSTRUCTOR, - BusinessFeatureGreetingMessage.CONSTRUCTOR, - BusinessFeatureAwayMessage.CONSTRUCTOR, - BusinessFeatureAccountLinks.CONSTRUCTOR, - BusinessFeatureStartPage.CONSTRUCTOR, - BusinessFeatureBots.CONSTRUCTOR, - BusinessFeatureEmojiStatus.CONSTRUCTOR, - BusinessFeatureChatFolderTags.CONSTRUCTOR, - BusinessFeatureUpgradedStories.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public BusinessFeature() { - } - } - - /** - * The ability to set location. - */ - public static class BusinessFeatureLocation extends BusinessFeature { - - /** - * The ability to set location. - */ - public BusinessFeatureLocation() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1064304004; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to set opening hours. - */ - public static class BusinessFeatureOpeningHours extends BusinessFeature { - - /** - * The ability to set opening hours. - */ - public BusinessFeatureOpeningHours() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 461054701; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to use quick replies. - */ - public static class BusinessFeatureQuickReplies extends BusinessFeature { - - /** - * The ability to use quick replies. - */ - public BusinessFeatureQuickReplies() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1674048894; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to set up a greeting message. - */ - public static class BusinessFeatureGreetingMessage extends BusinessFeature { - - /** - * The ability to set up a greeting message. - */ - public BusinessFeatureGreetingMessage() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1789424756; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to set up an away message. - */ - public static class BusinessFeatureAwayMessage extends BusinessFeature { - - /** - * The ability to set up an away message. - */ - public BusinessFeatureAwayMessage() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1090119901; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to create links to the business account with predefined message text. - */ - public static class BusinessFeatureAccountLinks extends BusinessFeature { - - /** - * The ability to create links to the business account with predefined message text. - */ - public BusinessFeatureAccountLinks() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1878693646; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to customize start page. - */ - public static class BusinessFeatureStartPage extends BusinessFeature { - - /** - * The ability to customize start page. - */ - public BusinessFeatureStartPage() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 401471457; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to connect a bot to the account. - */ - public static class BusinessFeatureBots extends BusinessFeature { - - /** - * The ability to connect a bot to the account. - */ - public BusinessFeatureBots() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 275084773; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to show an emoji status along with the business name. - */ - public static class BusinessFeatureEmojiStatus extends BusinessFeature { - - /** - * The ability to show an emoji status along with the business name. - */ - public BusinessFeatureEmojiStatus() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -846282523; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to display folder names for each chat in the chat list. - */ - public static class BusinessFeatureChatFolderTags extends BusinessFeature { - - /** - * The ability to display folder names for each chat in the chat list. - */ - public BusinessFeatureChatFolderTags() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -543880918; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Allowed to use many additional features for stories. - */ - public static class BusinessFeatureUpgradedStories extends BusinessFeature { - - /** - * Allowed to use many additional features for stories. - */ - public BusinessFeatureUpgradedStories() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1812245550; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a promotion animation for a Business feature. - */ - public static class BusinessFeaturePromotionAnimation extends Object { - /** - * Business feature. - */ - public BusinessFeature feature; - /** - * Promotion animation for the feature. - */ - public Animation animation; - - /** - * Describes a promotion animation for a Business feature. - */ - public BusinessFeaturePromotionAnimation() { - } - - /** - * Describes a promotion animation for a Business feature. - * - * @param feature Business feature. - * @param animation Promotion animation for the feature. - */ - public BusinessFeaturePromotionAnimation(BusinessFeature feature, Animation animation) { - this.feature = feature; - this.animation = animation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2047174666; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about features, available to Business user accounts. - */ - public static class BusinessFeatures extends Object { - /** - * The list of available business features. - */ - public BusinessFeature[] features; - - /** - * Contains information about features, available to Business user accounts. - */ - public BusinessFeatures() { - } - - /** - * Contains information about features, available to Business user accounts. - * - * @param features The list of available business features. - */ - public BusinessFeatures(BusinessFeature[] features) { - this.features = features; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1532468184; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes settings for greeting messages that are automatically sent by a Telegram Business account as response to incoming messages in an inactive private chat. - */ - public static class BusinessGreetingMessageSettings extends Object { - /** - * Unique quick reply shortcut identifier for the greeting messages. - */ - public int shortcutId; - /** - * Chosen recipients of the greeting messages. - */ - public BusinessRecipients recipients; - /** - * The number of days after which a chat will be considered as inactive; currently, must be on of 7, 14, 21, or 28. - */ - public int inactivityDays; - - /** - * Describes settings for greeting messages that are automatically sent by a Telegram Business account as response to incoming messages in an inactive private chat. - */ - public BusinessGreetingMessageSettings() { - } - - /** - * Describes settings for greeting messages that are automatically sent by a Telegram Business account as response to incoming messages in an inactive private chat. - * - * @param shortcutId Unique quick reply shortcut identifier for the greeting messages. - * @param recipients Chosen recipients of the greeting messages. - * @param inactivityDays The number of days after which a chat will be considered as inactive; currently, must be on of 7, 14, 21, or 28. - */ - public BusinessGreetingMessageSettings(int shortcutId, BusinessRecipients recipients, int inactivityDays) { - this.shortcutId = shortcutId; - this.recipients = recipients; - this.inactivityDays = inactivityDays; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1689140754; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a Telegram Business account. - */ - public static class BusinessInfo extends Object { - /** - * Location of the business; may be null if none. - */ - @Nullable public BusinessLocation location; - /** - * Opening hours of the business; may be null if none. The hours are guaranteed to be valid and has already been split by week days. - */ - @Nullable public BusinessOpeningHours openingHours; - /** - * Opening hours of the business in the local time; may be null if none. The hours are guaranteed to be valid and has already been split by week days. Local time zone identifier will be empty. An updateUserFullInfo update is not triggered when value of this field changes. - */ - @Nullable public BusinessOpeningHours localOpeningHours; - /** - * Time left before the business will open the next time, in seconds; 0 if unknown. An updateUserFullInfo update is not triggered when value of this field changes. - */ - public int nextOpenIn; - /** - * Time left before the business will close the next time, in seconds; 0 if unknown. An updateUserFullInfo update is not triggered when value of this field changes. - */ - public int nextCloseIn; - /** - * The greeting message; may be null if none or the Business account is not of the current user. - */ - @Nullable public BusinessGreetingMessageSettings greetingMessageSettings; - /** - * The away message; may be null if none or the Business account is not of the current user. - */ - @Nullable public BusinessAwayMessageSettings awayMessageSettings; - /** - * Information about start page of the account; may be null if none. - */ - @Nullable public BusinessStartPage startPage; - - /** - * Contains information about a Telegram Business account. - */ - public BusinessInfo() { - } - - /** - * Contains information about a Telegram Business account. - * - * @param location Location of the business; may be null if none. - * @param openingHours Opening hours of the business; may be null if none. The hours are guaranteed to be valid and has already been split by week days. - * @param localOpeningHours Opening hours of the business in the local time; may be null if none. The hours are guaranteed to be valid and has already been split by week days. Local time zone identifier will be empty. An updateUserFullInfo update is not triggered when value of this field changes. - * @param nextOpenIn Time left before the business will open the next time, in seconds; 0 if unknown. An updateUserFullInfo update is not triggered when value of this field changes. - * @param nextCloseIn Time left before the business will close the next time, in seconds; 0 if unknown. An updateUserFullInfo update is not triggered when value of this field changes. - * @param greetingMessageSettings The greeting message; may be null if none or the Business account is not of the current user. - * @param awayMessageSettings The away message; may be null if none or the Business account is not of the current user. - * @param startPage Information about start page of the account; may be null if none. - */ - public BusinessInfo(BusinessLocation location, BusinessOpeningHours openingHours, BusinessOpeningHours localOpeningHours, int nextOpenIn, int nextCloseIn, BusinessGreetingMessageSettings greetingMessageSettings, BusinessAwayMessageSettings awayMessageSettings, BusinessStartPage startPage) { - this.location = location; - this.openingHours = openingHours; - this.localOpeningHours = localOpeningHours; - this.nextOpenIn = nextOpenIn; - this.nextCloseIn = nextCloseIn; - this.greetingMessageSettings = greetingMessageSettings; - this.awayMessageSettings = awayMessageSettings; - this.startPage = startPage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1428179342; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a location of a business. - */ - public static class BusinessLocation extends Object { - /** - * The location; may be null if not specified. - */ - @Nullable public Location location; - /** - * Location address; 1-96 characters. - */ - public String address; - - /** - * Represents a location of a business. - */ - public BusinessLocation() { - } - - /** - * Represents a location of a business. - * - * @param location The location; may be null if not specified. - * @param address Location address; 1-96 characters. - */ - public BusinessLocation(Location location, String address) { - this.location = location; - this.address = address; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1084969126; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a message from a business account as received by a bot. - */ - public static class BusinessMessage extends Object { - /** - * The message. - */ - public Message message; - /** - * Message that is replied by the message in the same chat; may be null if none. - */ - @Nullable public Message replyToMessage; - - /** - * Describes a message from a business account as received by a bot. - */ - public BusinessMessage() { - } - - /** - * Describes a message from a business account as received by a bot. - * - * @param message The message. - * @param replyToMessage Message that is replied by the message in the same chat; may be null if none. - */ - public BusinessMessage(Message message, Message replyToMessage) { - this.message = message; - this.replyToMessage = replyToMessage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -94353850; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of messages from a business account as received by a bot. - */ - public static class BusinessMessages extends Object { - /** - * List of business messages. - */ - public BusinessMessage[] messages; - - /** - * Contains a list of messages from a business account as received by a bot. - */ - public BusinessMessages() { - } - - /** - * Contains a list of messages from a business account as received by a bot. - * - * @param messages List of business messages. - */ - public BusinessMessages(BusinessMessage[] messages) { - this.messages = messages; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -764562473; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes opening hours of a business. - */ - public static class BusinessOpeningHours extends Object { - /** - * Unique time zone identifier. - */ - public String timeZoneId; - /** - * Intervals of the time when the business is open. - */ - public BusinessOpeningHoursInterval[] openingHours; - - /** - * Describes opening hours of a business. - */ - public BusinessOpeningHours() { - } - - /** - * Describes opening hours of a business. - * - * @param timeZoneId Unique time zone identifier. - * @param openingHours Intervals of the time when the business is open. - */ - public BusinessOpeningHours(String timeZoneId, BusinessOpeningHoursInterval[] openingHours) { - this.timeZoneId = timeZoneId; - this.openingHours = openingHours; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 816603700; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an interval of time when the business is open. - */ - public static class BusinessOpeningHoursInterval extends Object { - /** - * The minute's sequence number in a week, starting on Monday, marking the start of the time interval during which the business is open; 0-7*24*60. - */ - public int startMinute; - /** - * The minute's sequence number in a week, starting on Monday, marking the end of the time interval during which the business is open; 1-8*24*60. - */ - public int endMinute; - - /** - * Describes an interval of time when the business is open. - */ - public BusinessOpeningHoursInterval() { - } - - /** - * Describes an interval of time when the business is open. - * - * @param startMinute The minute's sequence number in a week, starting on Monday, marking the start of the time interval during which the business is open; 0-7*24*60. - * @param endMinute The minute's sequence number in a week, starting on Monday, marking the end of the time interval during which the business is open; 1-8*24*60. - */ - public BusinessOpeningHoursInterval(int startMinute, int endMinute) { - this.startMinute = startMinute; - this.endMinute = endMinute; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1108322732; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes private chats chosen for automatic interaction with a business. - */ - public static class BusinessRecipients extends Object { - /** - * Identifiers of selected private chats. - */ - public long[] chatIds; - /** - * Identifiers of private chats that are always excluded; for businessConnectedBot only. - */ - public long[] excludedChatIds; - /** - * True, if all existing private chats are selected. - */ - public boolean selectExistingChats; - /** - * True, if all new private chats are selected. - */ - public boolean selectNewChats; - /** - * True, if all private chats with contacts are selected. - */ - public boolean selectContacts; - /** - * True, if all private chats with non-contacts are selected. - */ - public boolean selectNonContacts; - /** - * If true, then all private chats except the selected are chosen. Otherwise, only the selected chats are chosen. - */ - public boolean excludeSelected; - - /** - * Describes private chats chosen for automatic interaction with a business. - */ - public BusinessRecipients() { - } - - /** - * Describes private chats chosen for automatic interaction with a business. - * - * @param chatIds Identifiers of selected private chats. - * @param excludedChatIds Identifiers of private chats that are always excluded; for businessConnectedBot only. - * @param selectExistingChats True, if all existing private chats are selected. - * @param selectNewChats True, if all new private chats are selected. - * @param selectContacts True, if all private chats with contacts are selected. - * @param selectNonContacts True, if all private chats with non-contacts are selected. - * @param excludeSelected If true, then all private chats except the selected are chosen. Otherwise, only the selected chats are chosen. - */ - public BusinessRecipients(long[] chatIds, long[] excludedChatIds, boolean selectExistingChats, boolean selectNewChats, boolean selectContacts, boolean selectNonContacts, boolean excludeSelected) { - this.chatIds = chatIds; - this.excludedChatIds = excludedChatIds; - this.selectExistingChats = selectExistingChats; - this.selectNewChats = selectNewChats; - this.selectContacts = selectContacts; - this.selectNonContacts = selectNonContacts; - this.excludeSelected = excludeSelected; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 868656909; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes settings for a business account start page. - */ - public static class BusinessStartPage extends Object { - /** - * Title text of the start page. - */ - public String title; - /** - * Message text of the start page. - */ - public String message; - /** - * Greeting sticker of the start page; may be null if none. - */ - @Nullable public Sticker sticker; - - /** - * Describes settings for a business account start page. - */ - public BusinessStartPage() { - } - - /** - * Describes settings for a business account start page. - * - * @param title Title text of the start page. - * @param message Message text of the start page. - * @param sticker Greeting sticker of the start page; may be null if none. - */ - public BusinessStartPage(String title, String message, Sticker sticker) { - this.title = title; - this.message = message; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1616709681; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes style of a button. - */ - public abstract static class ButtonStyle extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ButtonStyleDefault.CONSTRUCTOR, - ButtonStylePrimary.CONSTRUCTOR, - ButtonStyleDanger.CONSTRUCTOR, - ButtonStyleSuccess.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ButtonStyle() { - } - } - - /** - * The button has default style. - */ - public static class ButtonStyleDefault extends ButtonStyle { - - /** - * The button has default style. - */ - public ButtonStyleDefault() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 588834315; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The button has dark blue color. - */ - public static class ButtonStylePrimary extends ButtonStyle { - - /** - * The button has dark blue color. - */ - public ButtonStylePrimary() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2048071333; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The button has red color. - */ - public static class ButtonStyleDanger extends ButtonStyle { - - /** - * The button has red color. - */ - public ButtonStyleDanger() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1637377793; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The button has green color. - */ - public static class ButtonStyleSuccess extends ButtonStyle { - - /** - * The button has green color. - */ - public ButtonStyleSuccess() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1042215008; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a call. - */ - public static class Call extends Object { - /** - * Call identifier, not persistent. - */ - public int id; - /** - * Persistent unique call identifier; 0 if isn't assigned yet by the server. - */ - public long uniqueId; - /** - * User identifier of the other call participant. - */ - public long userId; - /** - * True, if the call is outgoing. - */ - public boolean isOutgoing; - /** - * True, if the call is a video call. - */ - public boolean isVideo; - /** - * Call state. - */ - public CallState state; - - /** - * Describes a call. - */ - public Call() { - } - - /** - * Describes a call. - * - * @param id Call identifier, not persistent. - * @param uniqueId Persistent unique call identifier; 0 if isn't assigned yet by the server. - * @param userId User identifier of the other call participant. - * @param isOutgoing True, if the call is outgoing. - * @param isVideo True, if the call is a video call. - * @param state Call state. - */ - public Call(int id, long uniqueId, long userId, boolean isOutgoing, boolean isVideo, CallState state) { - this.id = id; - this.uniqueId = uniqueId; - this.userId = userId; - this.isOutgoing = isOutgoing; - this.isVideo = isVideo; - this.state = state; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 837356336; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the reason why a call was discarded. - */ - public abstract static class CallDiscardReason extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - CallDiscardReasonEmpty.CONSTRUCTOR, - CallDiscardReasonMissed.CONSTRUCTOR, - CallDiscardReasonDeclined.CONSTRUCTOR, - CallDiscardReasonDisconnected.CONSTRUCTOR, - CallDiscardReasonHungUp.CONSTRUCTOR, - CallDiscardReasonUpgradeToGroupCall.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public CallDiscardReason() { - } - } - - /** - * The call wasn't discarded, or the reason is unknown. - */ - public static class CallDiscardReasonEmpty extends CallDiscardReason { - - /** - * The call wasn't discarded, or the reason is unknown. - */ - public CallDiscardReasonEmpty() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1258917949; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The call was ended before the conversation started. It was canceled by the caller or missed by the other party. - */ - public static class CallDiscardReasonMissed extends CallDiscardReason { - - /** - * The call was ended before the conversation started. It was canceled by the caller or missed by the other party. - */ - public CallDiscardReasonMissed() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1680358012; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The call was ended before the conversation started. It was declined by the other party. - */ - public static class CallDiscardReasonDeclined extends CallDiscardReason { - - /** - * The call was ended before the conversation started. It was declined by the other party. - */ - public CallDiscardReasonDeclined() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1729926094; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The call was ended during the conversation because the users were disconnected. - */ - public static class CallDiscardReasonDisconnected extends CallDiscardReason { - - /** - * The call was ended during the conversation because the users were disconnected. - */ - public CallDiscardReasonDisconnected() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1342872670; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The call was ended because one of the parties hung up. - */ - public static class CallDiscardReasonHungUp extends CallDiscardReason { - - /** - * The call was ended because one of the parties hung up. - */ - public CallDiscardReasonHungUp() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 438216166; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The call was ended because it has been upgraded to a group call. - */ - public static class CallDiscardReasonUpgradeToGroupCall extends CallDiscardReason { - /** - * Invite link for the group call. - */ - public String inviteLink; - - /** - * The call was ended because it has been upgraded to a group call. - */ - public CallDiscardReasonUpgradeToGroupCall() { - } - - /** - * The call was ended because it has been upgraded to a group call. - * - * @param inviteLink Invite link for the group call. - */ - public CallDiscardReasonUpgradeToGroupCall(String inviteLink) { - this.inviteLink = inviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1254509319; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains the call identifier. - */ - public static class CallId extends Object { - /** - * Call identifier. - */ - public int id; - - /** - * Contains the call identifier. - */ - public CallId() { - } - - /** - * Contains the call identifier. - * - * @param id Call identifier. - */ - public CallId(int id) { - this.id = id; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 65717769; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the exact type of problem with a call. - */ - public abstract static class CallProblem extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - CallProblemEcho.CONSTRUCTOR, - CallProblemNoise.CONSTRUCTOR, - CallProblemInterruptions.CONSTRUCTOR, - CallProblemDistortedSpeech.CONSTRUCTOR, - CallProblemSilentLocal.CONSTRUCTOR, - CallProblemSilentRemote.CONSTRUCTOR, - CallProblemDropped.CONSTRUCTOR, - CallProblemDistortedVideo.CONSTRUCTOR, - CallProblemPixelatedVideo.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public CallProblem() { - } - } - - /** - * The user heard their own voice. - */ - public static class CallProblemEcho extends CallProblem { - - /** - * The user heard their own voice. - */ - public CallProblemEcho() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 801116548; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user heard background noise. - */ - public static class CallProblemNoise extends CallProblem { - - /** - * The user heard background noise. - */ - public CallProblemNoise() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1053065359; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The other side kept disappearing. - */ - public static class CallProblemInterruptions extends CallProblem { - - /** - * The other side kept disappearing. - */ - public CallProblemInterruptions() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1119493218; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The speech was distorted. - */ - public static class CallProblemDistortedSpeech extends CallProblem { - - /** - * The speech was distorted. - */ - public CallProblemDistortedSpeech() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 379960581; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user couldn't hear the other side. - */ - public static class CallProblemSilentLocal extends CallProblem { - - /** - * The user couldn't hear the other side. - */ - public CallProblemSilentLocal() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 253652790; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The other side couldn't hear the user. - */ - public static class CallProblemSilentRemote extends CallProblem { - - /** - * The other side couldn't hear the user. - */ - public CallProblemSilentRemote() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 573634714; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The call ended unexpectedly. - */ - public static class CallProblemDropped extends CallProblem { - - /** - * The call ended unexpectedly. - */ - public CallProblemDropped() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1207311487; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The video was distorted. - */ - public static class CallProblemDistortedVideo extends CallProblem { - - /** - * The video was distorted. - */ - public CallProblemDistortedVideo() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 385245706; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The video was pixelated. - */ - public static class CallProblemPixelatedVideo extends CallProblem { - - /** - * The video was pixelated. - */ - public CallProblemPixelatedVideo() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2115315411; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Specifies the supported call protocols. - */ - public static class CallProtocol extends Object { - /** - * True, if UDP peer-to-peer connections are supported. - */ - public boolean udpP2p; - /** - * True, if connection through UDP reflectors is supported. - */ - public boolean udpReflector; - /** - * The minimum supported API layer; use 65. - */ - public int minLayer; - /** - * The maximum supported API layer; use 92. - */ - public int maxLayer; - /** - * List of supported tgcalls versions. - */ - public String[] libraryVersions; - - /** - * Specifies the supported call protocols. - */ - public CallProtocol() { - } - - /** - * Specifies the supported call protocols. - * - * @param udpP2p True, if UDP peer-to-peer connections are supported. - * @param udpReflector True, if connection through UDP reflectors is supported. - * @param minLayer The minimum supported API layer; use 65. - * @param maxLayer The maximum supported API layer; use 92. - * @param libraryVersions List of supported tgcalls versions. - */ - public CallProtocol(boolean udpP2p, boolean udpReflector, int minLayer, int maxLayer, String[] libraryVersions) { - this.udpP2p = udpP2p; - this.udpReflector = udpReflector; - this.minLayer = minLayer; - this.maxLayer = maxLayer; - this.libraryVersions = libraryVersions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1075562897; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a server for relaying call data. - */ - public static class CallServer extends Object { - /** - * Server identifier. - */ - public long id; - /** - * Server IPv4 address. - */ - public String ipAddress; - /** - * Server IPv6 address. - */ - public String ipv6Address; - /** - * Server port number. - */ - public int port; - /** - * Server type. - */ - public CallServerType type; - - /** - * Describes a server for relaying call data. - */ - public CallServer() { - } - - /** - * Describes a server for relaying call data. - * - * @param id Server identifier. - * @param ipAddress Server IPv4 address. - * @param ipv6Address Server IPv6 address. - * @param port Server port number. - * @param type Server type. - */ - public CallServer(long id, String ipAddress, String ipv6Address, int port, CallServerType type) { - this.id = id; - this.ipAddress = ipAddress; - this.ipv6Address = ipv6Address; - this.port = port; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1865932695; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the type of call server. - */ - public abstract static class CallServerType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - CallServerTypeTelegramReflector.CONSTRUCTOR, - CallServerTypeWebrtc.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public CallServerType() { - } - } - - /** - * A Telegram call reflector. - */ - public static class CallServerTypeTelegramReflector extends CallServerType { - /** - * A peer tag to be used with the reflector. - */ - public byte[] peerTag; - /** - * True, if the server uses TCP instead of UDP. - */ - public boolean isTcp; - - /** - * A Telegram call reflector. - */ - public CallServerTypeTelegramReflector() { - } - - /** - * A Telegram call reflector. - * - * @param peerTag A peer tag to be used with the reflector. - * @param isTcp True, if the server uses TCP instead of UDP. - */ - public CallServerTypeTelegramReflector(byte[] peerTag, boolean isTcp) { - this.peerTag = peerTag; - this.isTcp = isTcp; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 850343189; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A WebRTC server. - */ - public static class CallServerTypeWebrtc extends CallServerType { - /** - * Username to be used for authentication. - */ - public String username; - /** - * Authentication password. - */ - public String password; - /** - * True, if the server supports TURN. - */ - public boolean supportsTurn; - /** - * True, if the server supports STUN. - */ - public boolean supportsStun; - - /** - * A WebRTC server. - */ - public CallServerTypeWebrtc() { - } - - /** - * A WebRTC server. - * - * @param username Username to be used for authentication. - * @param password Authentication password. - * @param supportsTurn True, if the server supports TURN. - * @param supportsStun True, if the server supports STUN. - */ - public CallServerTypeWebrtc(String username, String password, boolean supportsTurn, boolean supportsStun) { - this.username = username; - this.password = password; - this.supportsTurn = supportsTurn; - this.supportsStun = supportsStun; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1250622821; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the current call state. - */ - public abstract static class CallState extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - CallStatePending.CONSTRUCTOR, - CallStateExchangingKeys.CONSTRUCTOR, - CallStateReady.CONSTRUCTOR, - CallStateHangingUp.CONSTRUCTOR, - CallStateDiscarded.CONSTRUCTOR, - CallStateError.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public CallState() { - } - } - - /** - * The call is pending, waiting to be accepted by a user. - */ - public static class CallStatePending extends CallState { - /** - * True, if the call has already been created by the server. - */ - public boolean isCreated; - /** - * True, if the call has already been received by the other party. - */ - public boolean isReceived; - - /** - * The call is pending, waiting to be accepted by a user. - */ - public CallStatePending() { - } - - /** - * The call is pending, waiting to be accepted by a user. - * - * @param isCreated True, if the call has already been created by the server. - * @param isReceived True, if the call has already been received by the other party. - */ - public CallStatePending(boolean isCreated, boolean isReceived) { - this.isCreated = isCreated; - this.isReceived = isReceived; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1073048620; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The call has been answered and encryption keys are being exchanged. - */ - public static class CallStateExchangingKeys extends CallState { - - /** - * The call has been answered and encryption keys are being exchanged. - */ - public CallStateExchangingKeys() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1848149403; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The call is ready to use. - */ - public static class CallStateReady extends CallState { - /** - * Call protocols supported by the other call participant. - */ - public CallProtocol protocol; - /** - * List of available call servers. - */ - public CallServer[] servers; - /** - * A JSON-encoded call config. - */ - public String config; - /** - * Call encryption key. - */ - public byte[] encryptionKey; - /** - * Encryption key fingerprint represented as 4 emoji. - */ - public String[] emojis; - /** - * True, if peer-to-peer connection is allowed by users privacy settings. - */ - public boolean allowP2p; - /** - * True, if the other party supports upgrading of the call to a group call. - */ - public boolean isGroupCallSupported; - /** - * Custom JSON-encoded call parameters to be passed to tgcalls. - */ - public String customParameters; - - /** - * The call is ready to use. - */ - public CallStateReady() { - } - - /** - * The call is ready to use. - * - * @param protocol Call protocols supported by the other call participant. - * @param servers List of available call servers. - * @param config A JSON-encoded call config. - * @param encryptionKey Call encryption key. - * @param emojis Encryption key fingerprint represented as 4 emoji. - * @param allowP2p True, if peer-to-peer connection is allowed by users privacy settings. - * @param isGroupCallSupported True, if the other party supports upgrading of the call to a group call. - * @param customParameters Custom JSON-encoded call parameters to be passed to tgcalls. - */ - public CallStateReady(CallProtocol protocol, CallServer[] servers, String config, byte[] encryptionKey, String[] emojis, boolean allowP2p, boolean isGroupCallSupported, String customParameters) { - this.protocol = protocol; - this.servers = servers; - this.config = config; - this.encryptionKey = encryptionKey; - this.emojis = emojis; - this.allowP2p = allowP2p; - this.isGroupCallSupported = isGroupCallSupported; - this.customParameters = customParameters; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -281776921; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The call is hanging up after discardCall has been called. - */ - public static class CallStateHangingUp extends CallState { - - /** - * The call is hanging up after discardCall has been called. - */ - public CallStateHangingUp() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2133790038; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The call has ended successfully. - */ - public static class CallStateDiscarded extends CallState { - /** - * The reason why the call has ended. - */ - public CallDiscardReason reason; - /** - * True, if the call rating must be sent to the server. - */ - public boolean needRating; - /** - * True, if the call debug information must be sent to the server. - */ - public boolean needDebugInformation; - /** - * True, if the call log must be sent to the server. - */ - public boolean needLog; - - /** - * The call has ended successfully. - */ - public CallStateDiscarded() { - } - - /** - * The call has ended successfully. - * - * @param reason The reason why the call has ended. - * @param needRating True, if the call rating must be sent to the server. - * @param needDebugInformation True, if the call debug information must be sent to the server. - * @param needLog True, if the call log must be sent to the server. - */ - public CallStateDiscarded(CallDiscardReason reason, boolean needRating, boolean needDebugInformation, boolean needLog) { - this.reason = reason; - this.needRating = needRating; - this.needDebugInformation = needDebugInformation; - this.needLog = needLog; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1394310213; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The call has ended with an error. - */ - public static class CallStateError extends CallState { - /** - * Error. An error with the code 4005000 will be returned if an outgoing call is missed because of an expired timeout. - */ - public Error error; - - /** - * The call has ended with an error. - */ - public CallStateError() { - } - - /** - * The call has ended with an error. - * - * @param error Error. An error with the code 4005000 will be returned if an outgoing call is missed because of an expired timeout. - */ - public CallStateError(Error error) { - this.error = error; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -975215467; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a bot's answer to a callback query. - */ - public static class CallbackQueryAnswer extends Object { - /** - * Text of the answer. - */ - public String text; - /** - * True, if an alert must be shown to the user instead of a toast notification. - */ - public boolean showAlert; - /** - * URL to be opened. - */ - public String url; - - /** - * Contains a bot's answer to a callback query. - */ - public CallbackQueryAnswer() { - } - - /** - * Contains a bot's answer to a callback query. - * - * @param text Text of the answer. - * @param showAlert True, if an alert must be shown to the user instead of a toast notification. - * @param url URL to be opened. - */ - public CallbackQueryAnswer(String text, boolean showAlert, String url) { - this.text = text; - this.showAlert = showAlert; - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 360867933; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents a payload of a callback query. - */ - public abstract static class CallbackQueryPayload extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - CallbackQueryPayloadData.CONSTRUCTOR, - CallbackQueryPayloadDataWithPassword.CONSTRUCTOR, - CallbackQueryPayloadGame.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public CallbackQueryPayload() { - } - } - - /** - * The payload for a general callback button. - */ - public static class CallbackQueryPayloadData extends CallbackQueryPayload { - /** - * Data that was attached to the callback button. - */ - public byte[] data; - - /** - * The payload for a general callback button. - */ - public CallbackQueryPayloadData() { - } - - /** - * The payload for a general callback button. - * - * @param data Data that was attached to the callback button. - */ - public CallbackQueryPayloadData(byte[] data) { - this.data = data; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1977729946; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The payload for a callback button requiring password. - */ - public static class CallbackQueryPayloadDataWithPassword extends CallbackQueryPayload { - /** - * The 2-step verification password for the current user. - */ - public String password; - /** - * Data that was attached to the callback button. - */ - public byte[] data; - - /** - * The payload for a callback button requiring password. - */ - public CallbackQueryPayloadDataWithPassword() { - } - - /** - * The payload for a callback button requiring password. - * - * @param password The 2-step verification password for the current user. - * @param data Data that was attached to the callback button. - */ - public CallbackQueryPayloadDataWithPassword(String password, byte[] data) { - this.password = password; - this.data = data; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1340266738; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The payload for a game callback button. - */ - public static class CallbackQueryPayloadGame extends CallbackQueryPayload { - /** - * A short name of the game that was attached to the callback button. - */ - public String gameShortName; - - /** - * The payload for a game callback button. - */ - public CallbackQueryPayloadGame() { - } - - /** - * The payload for a game callback button. - * - * @param gameShortName A short name of the game that was attached to the callback button. - */ - public CallbackQueryPayloadGame(String gameShortName) { - this.gameShortName = gameShortName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1303571512; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents result of checking whether the current user can post a story on behalf of the specific chat. - */ - public abstract static class CanPostStoryResult extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - CanPostStoryResultOk.CONSTRUCTOR, - CanPostStoryResultPremiumNeeded.CONSTRUCTOR, - CanPostStoryResultBoostNeeded.CONSTRUCTOR, - CanPostStoryResultActiveStoryLimitExceeded.CONSTRUCTOR, - CanPostStoryResultWeeklyLimitExceeded.CONSTRUCTOR, - CanPostStoryResultMonthlyLimitExceeded.CONSTRUCTOR, - CanPostStoryResultLiveStoryIsActive.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public CanPostStoryResult() { - } - } - - /** - * A story can be sent. - */ - public static class CanPostStoryResultOk extends CanPostStoryResult { - /** - * Number of stories that can be posted by the user. - */ - public int storyCount; - - /** - * A story can be sent. - */ - public CanPostStoryResultOk() { - } - - /** - * A story can be sent. - * - * @param storyCount Number of stories that can be posted by the user. - */ - public CanPostStoryResultOk(int storyCount) { - this.storyCount = storyCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2083205610; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user must subscribe to Telegram Premium to be able to post stories. - */ - public static class CanPostStoryResultPremiumNeeded extends CanPostStoryResult { - - /** - * The user must subscribe to Telegram Premium to be able to post stories. - */ - public CanPostStoryResultPremiumNeeded() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 935130501; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat must be boosted first by Telegram Premium subscribers to post more stories. Call getChatBoostStatus to get current boost status of the chat. - */ - public static class CanPostStoryResultBoostNeeded extends CanPostStoryResult { - - /** - * The chat must be boosted first by Telegram Premium subscribers to post more stories. Call getChatBoostStatus to get current boost status of the chat. - */ - public CanPostStoryResultBoostNeeded() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 80246195; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The limit for the number of active stories exceeded. The user can buy Telegram Premium, delete an active story, or wait for the oldest story to expire. - */ - public static class CanPostStoryResultActiveStoryLimitExceeded extends CanPostStoryResult { - - /** - * The limit for the number of active stories exceeded. The user can buy Telegram Premium, delete an active story, or wait for the oldest story to expire. - */ - public CanPostStoryResultActiveStoryLimitExceeded() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1640759002; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The weekly limit for the number of posted stories exceeded. The user needs to buy Telegram Premium or wait specified time. - */ - public static class CanPostStoryResultWeeklyLimitExceeded extends CanPostStoryResult { - /** - * Time left before the user can post the next story, in seconds. - */ - public int retryAfter; - - /** - * The weekly limit for the number of posted stories exceeded. The user needs to buy Telegram Premium or wait specified time. - */ - public CanPostStoryResultWeeklyLimitExceeded() { - } - - /** - * The weekly limit for the number of posted stories exceeded. The user needs to buy Telegram Premium or wait specified time. - * - * @param retryAfter Time left before the user can post the next story, in seconds. - */ - public CanPostStoryResultWeeklyLimitExceeded(int retryAfter) { - this.retryAfter = retryAfter; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 552858605; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The monthly limit for the number of posted stories exceeded. The user needs to buy Telegram Premium or wait specified time. - */ - public static class CanPostStoryResultMonthlyLimitExceeded extends CanPostStoryResult { - /** - * Time left before the user can post the next story, in seconds. - */ - public int retryAfter; - - /** - * The monthly limit for the number of posted stories exceeded. The user needs to buy Telegram Premium or wait specified time. - */ - public CanPostStoryResultMonthlyLimitExceeded() { - } - - /** - * The monthly limit for the number of posted stories exceeded. The user needs to buy Telegram Premium or wait specified time. - * - * @param retryAfter Time left before the user can post the next story, in seconds. - */ - public CanPostStoryResultMonthlyLimitExceeded(int retryAfter) { - this.retryAfter = retryAfter; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -784208562; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user or the chat has an active live story. The live story must be deleted first. - */ - public static class CanPostStoryResultLiveStoryIsActive extends CanPostStoryResult { - /** - * Identifier of the active live story. - */ - public int storyId; - - /** - * The user or the chat has an active live story. The live story must be deleted first. - */ - public CanPostStoryResultLiveStoryIsActive() { - } - - /** - * The user or the chat has an active live story. The live story must be deleted first. - * - * @param storyId Identifier of the active live story. - */ - public CanPostStoryResultLiveStoryIsActive(int storyId) { - this.storyId = storyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1156939675; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes whether a gift can be sent now by the current user. - */ - public abstract static class CanSendGiftResult extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - CanSendGiftResultOk.CONSTRUCTOR, - CanSendGiftResultFail.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public CanSendGiftResult() { - } - } - - /** - * The gift can be sent now by the current user. - */ - public static class CanSendGiftResultOk extends CanSendGiftResult { - - /** - * The gift can be sent now by the current user. - */ - public CanSendGiftResultOk() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 641908725; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The gift can't be sent now by the current user. - */ - public static class CanSendGiftResultFail extends CanSendGiftResult { - /** - * Reason to be shown to the user. - */ - public FormattedText reason; - - /** - * The gift can't be sent now by the current user. - */ - public CanSendGiftResultFail() { - } - - /** - * The gift can't be sent now by the current user. - * - * @param reason Reason to be shown to the user. - */ - public CanSendGiftResultFail(FormattedText reason) { - this.reason = reason; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1359108924; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes result of canSendMessageToUser. - */ - public abstract static class CanSendMessageToUserResult extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - CanSendMessageToUserResultOk.CONSTRUCTOR, - CanSendMessageToUserResultUserHasPaidMessages.CONSTRUCTOR, - CanSendMessageToUserResultUserIsDeleted.CONSTRUCTOR, - CanSendMessageToUserResultUserRestrictsNewChats.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public CanSendMessageToUserResult() { - } - } - - /** - * The user can be messaged. - */ - public static class CanSendMessageToUserResultOk extends CanSendMessageToUserResult { - - /** - * The user can be messaged. - */ - public CanSendMessageToUserResultOk() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1530583042; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user can be messaged, but the messages are paid. - */ - public static class CanSendMessageToUserResultUserHasPaidMessages extends CanSendMessageToUserResult { - /** - * Number of Telegram Stars that must be paid by the current user for each sent message to the user. - */ - public long outgoingPaidMessageStarCount; - - /** - * The user can be messaged, but the messages are paid. - */ - public CanSendMessageToUserResultUserHasPaidMessages() { - } - - /** - * The user can be messaged, but the messages are paid. - * - * @param outgoingPaidMessageStarCount Number of Telegram Stars that must be paid by the current user for each sent message to the user. - */ - public CanSendMessageToUserResultUserHasPaidMessages(long outgoingPaidMessageStarCount) { - this.outgoingPaidMessageStarCount = outgoingPaidMessageStarCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1346487602; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user can't be messaged, because they are deleted or unknown. - */ - public static class CanSendMessageToUserResultUserIsDeleted extends CanSendMessageToUserResult { - - /** - * The user can't be messaged, because they are deleted or unknown. - */ - public CanSendMessageToUserResultUserIsDeleted() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1944639903; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user can't be messaged, because they restrict new chats with non-contacts. - */ - public static class CanSendMessageToUserResultUserRestrictsNewChats extends CanSendMessageToUserResult { - - /** - * The user can't be messaged, because they restrict new chats with non-contacts. - */ - public CanSendMessageToUserResultUserRestrictsNewChats() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1929699797; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents result of checking whether the current session can be used to transfer a chat ownership to another user. - */ - public abstract static class CanTransferOwnershipResult extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - CanTransferOwnershipResultOk.CONSTRUCTOR, - CanTransferOwnershipResultPasswordNeeded.CONSTRUCTOR, - CanTransferOwnershipResultPasswordTooFresh.CONSTRUCTOR, - CanTransferOwnershipResultSessionTooFresh.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public CanTransferOwnershipResult() { - } - } - - /** - * The session can be used. - */ - public static class CanTransferOwnershipResultOk extends CanTransferOwnershipResult { - - /** - * The session can be used. - */ - public CanTransferOwnershipResultOk() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -89881021; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The 2-step verification needs to be enabled first. - */ - public static class CanTransferOwnershipResultPasswordNeeded extends CanTransferOwnershipResult { - - /** - * The 2-step verification needs to be enabled first. - */ - public CanTransferOwnershipResultPasswordNeeded() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1548372703; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The 2-step verification was enabled recently, user needs to wait. - */ - public static class CanTransferOwnershipResultPasswordTooFresh extends CanTransferOwnershipResult { - /** - * Time left before the session can be used to transfer ownership of a chat, in seconds. - */ - public int retryAfter; - - /** - * The 2-step verification was enabled recently, user needs to wait. - */ - public CanTransferOwnershipResultPasswordTooFresh() { - } - - /** - * The 2-step verification was enabled recently, user needs to wait. - * - * @param retryAfter Time left before the session can be used to transfer ownership of a chat, in seconds. - */ - public CanTransferOwnershipResultPasswordTooFresh(int retryAfter) { - this.retryAfter = retryAfter; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 811440913; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The session was created recently, user needs to wait. - */ - public static class CanTransferOwnershipResultSessionTooFresh extends CanTransferOwnershipResult { - /** - * Time left before the session can be used to transfer ownership of a chat, in seconds. - */ - public int retryAfter; - - /** - * The session was created recently, user needs to wait. - */ - public CanTransferOwnershipResultSessionTooFresh() { - } - - /** - * The session was created recently, user needs to wait. - * - * @param retryAfter Time left before the session can be used to transfer ownership of a chat, in seconds. - */ - public CanTransferOwnershipResultSessionTooFresh(int retryAfter) { - this.retryAfter = retryAfter; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 984664289; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat. (Can be a private chat, basic group, supergroup, or secret chat.) - */ - public static class Chat extends Object { - /** - * Chat unique identifier. - */ - public long id; - /** - * Type of the chat. - */ - public ChatType type; - /** - * Chat title. - */ - public String title; - /** - * Chat photo; may be null. - */ - @Nullable public ChatPhotoInfo photo; - /** - * Identifier of the accent color for message sender name, and backgrounds of chat photo, reply header, and link preview. - */ - public int accentColorId; - /** - * Identifier of a custom emoji to be shown on the reply header and link preview background for messages sent by the chat; 0 if none. - */ - public long backgroundCustomEmojiId; - /** - * Color scheme based on an upgraded gift to be used for the chat instead of accentColorId and backgroundCustomEmojiId; may be null if none. - */ - @Nullable public UpgradedGiftColors upgradedGiftColors; - /** - * Identifier of the profile accent color for the chat's profile; -1 if none. - */ - public int profileAccentColorId; - /** - * Identifier of a custom emoji to be shown on the background of the chat's profile; 0 if none. - */ - public long profileBackgroundCustomEmojiId; - /** - * Actions that non-administrator chat members are allowed to take in the chat. - */ - public ChatPermissions permissions; - /** - * Last message in the chat; may be null if none or unknown. - */ - @Nullable public Message lastMessage; - /** - * Positions of the chat in chat lists. - */ - public ChatPosition[] positions; - /** - * Chat lists to which the chat belongs. A chat can have a non-zero position in a chat list even if it doesn't belong to the chat list and have no position in a chat list even if it belongs to the chat list. - */ - public ChatList[] chatLists; - /** - * Identifier of a user or chat that is selected to send messages in the chat; may be null if the user can't change message sender. - */ - @Nullable public MessageSender messageSenderId; - /** - * Block list to which the chat is added; may be null if none. - */ - @Nullable public BlockList blockList; - /** - * True, if chat content can't be saved locally, forwarded, or copied. - */ - public boolean hasProtectedContent; - /** - * True, if translation of all messages in the chat must be suggested to the user. - */ - public boolean isTranslatable; - /** - * True, if the chat is marked as unread. - */ - public boolean isMarkedAsUnread; - /** - * True, if the chat is a forum supergroup that must be shown in the "View as topics" mode, or Saved Messages chat that must be shown in the "View as chats". - */ - public boolean viewAsTopics; - /** - * True, if the chat has scheduled messages. - */ - public boolean hasScheduledMessages; - /** - * True, if the chat messages can be deleted only for the current user while other users will continue to see the messages. - */ - public boolean canBeDeletedOnlyForSelf; - /** - * True, if the chat messages can be deleted for all users. - */ - public boolean canBeDeletedForAllUsers; - /** - * True, if the chat can be reported to Telegram moderators through reportChat or reportChatPhoto. - */ - public boolean canBeReported; - /** - * Default value of the disableNotification parameter, used when a message is sent to the chat. - */ - public boolean defaultDisableNotification; - /** - * Number of unread messages in the chat. - */ - public int unreadCount; - /** - * Identifier of the last read incoming message. - */ - public long lastReadInboxMessageId; - /** - * Identifier of the last read outgoing message. - */ - public long lastReadOutboxMessageId; - /** - * Number of unread messages with a mention/reply in the chat. - */ - public int unreadMentionCount; - /** - * Number of messages with unread reactions in the chat. - */ - public int unreadReactionCount; - /** - * Notification settings for the chat. - */ - public ChatNotificationSettings notificationSettings; - /** - * Types of reaction, available in the chat. - */ - public ChatAvailableReactions availableReactions; - /** - * Current message auto-delete or self-destruct timer setting for the chat, in seconds; 0 if disabled. Self-destruct timer in secret chats starts after the message or its content is viewed. Auto-delete timer in other chats starts from the send date. - */ - public int messageAutoDeleteTime; - /** - * Emoji status to be shown along with chat title; may be null. - */ - @Nullable public EmojiStatus emojiStatus; - /** - * Background set for the chat; may be null if none. - */ - @Nullable public ChatBackground background; - /** - * Theme set for the chat; may be null if none. - */ - @Nullable public ChatTheme theme; - /** - * Information about actions which must be possible to do through the chat action bar; may be null if none. - */ - @Nullable public ChatActionBar actionBar; - /** - * Information about bar for managing a business bot in the chat; may be null if none. - */ - @Nullable public BusinessBotManageBar businessBotManageBar; - /** - * Information about video chat of the chat. - */ - public VideoChat videoChat; - /** - * Information about pending join requests; may be null if none. - */ - @Nullable public ChatJoinRequestsInfo pendingJoinRequests; - /** - * Identifier of the message from which reply markup needs to be used; 0 if there is no reply markup in the chat. - */ - public long replyMarkupMessageId; - /** - * A draft of a message in the chat; may be null if none. - */ - @Nullable public DraftMessage draftMessage; - /** - * Application-specific data associated with the chat. (For example, the chat scroll position or local chat notification settings can be stored here.) Persistent if the message database is used. - */ - public String clientData; - - /** - * A chat. (Can be a private chat, basic group, supergroup, or secret chat.) - */ - public Chat() { - } - - /** - * A chat. (Can be a private chat, basic group, supergroup, or secret chat.) - * - * @param id Chat unique identifier. - * @param type Type of the chat. - * @param title Chat title. - * @param photo Chat photo; may be null. - * @param accentColorId Identifier of the accent color for message sender name, and backgrounds of chat photo, reply header, and link preview. - * @param backgroundCustomEmojiId Identifier of a custom emoji to be shown on the reply header and link preview background for messages sent by the chat; 0 if none. - * @param upgradedGiftColors Color scheme based on an upgraded gift to be used for the chat instead of accentColorId and backgroundCustomEmojiId; may be null if none. - * @param profileAccentColorId Identifier of the profile accent color for the chat's profile; -1 if none. - * @param profileBackgroundCustomEmojiId Identifier of a custom emoji to be shown on the background of the chat's profile; 0 if none. - * @param permissions Actions that non-administrator chat members are allowed to take in the chat. - * @param lastMessage Last message in the chat; may be null if none or unknown. - * @param positions Positions of the chat in chat lists. - * @param chatLists Chat lists to which the chat belongs. A chat can have a non-zero position in a chat list even if it doesn't belong to the chat list and have no position in a chat list even if it belongs to the chat list. - * @param messageSenderId Identifier of a user or chat that is selected to send messages in the chat; may be null if the user can't change message sender. - * @param blockList Block list to which the chat is added; may be null if none. - * @param hasProtectedContent True, if chat content can't be saved locally, forwarded, or copied. - * @param isTranslatable True, if translation of all messages in the chat must be suggested to the user. - * @param isMarkedAsUnread True, if the chat is marked as unread. - * @param viewAsTopics True, if the chat is a forum supergroup that must be shown in the "View as topics" mode, or Saved Messages chat that must be shown in the "View as chats". - * @param hasScheduledMessages True, if the chat has scheduled messages. - * @param canBeDeletedOnlyForSelf True, if the chat messages can be deleted only for the current user while other users will continue to see the messages. - * @param canBeDeletedForAllUsers True, if the chat messages can be deleted for all users. - * @param canBeReported True, if the chat can be reported to Telegram moderators through reportChat or reportChatPhoto. - * @param defaultDisableNotification Default value of the disableNotification parameter, used when a message is sent to the chat. - * @param unreadCount Number of unread messages in the chat. - * @param lastReadInboxMessageId Identifier of the last read incoming message. - * @param lastReadOutboxMessageId Identifier of the last read outgoing message. - * @param unreadMentionCount Number of unread messages with a mention/reply in the chat. - * @param unreadReactionCount Number of messages with unread reactions in the chat. - * @param notificationSettings Notification settings for the chat. - * @param availableReactions Types of reaction, available in the chat. - * @param messageAutoDeleteTime Current message auto-delete or self-destruct timer setting for the chat, in seconds; 0 if disabled. Self-destruct timer in secret chats starts after the message or its content is viewed. Auto-delete timer in other chats starts from the send date. - * @param emojiStatus Emoji status to be shown along with chat title; may be null. - * @param background Background set for the chat; may be null if none. - * @param theme Theme set for the chat; may be null if none. - * @param actionBar Information about actions which must be possible to do through the chat action bar; may be null if none. - * @param businessBotManageBar Information about bar for managing a business bot in the chat; may be null if none. - * @param videoChat Information about video chat of the chat. - * @param pendingJoinRequests Information about pending join requests; may be null if none. - * @param replyMarkupMessageId Identifier of the message from which reply markup needs to be used; 0 if there is no reply markup in the chat. - * @param draftMessage A draft of a message in the chat; may be null if none. - * @param clientData Application-specific data associated with the chat. (For example, the chat scroll position or local chat notification settings can be stored here.) Persistent if the message database is used. - */ - public Chat(long id, ChatType type, String title, ChatPhotoInfo photo, int accentColorId, long backgroundCustomEmojiId, UpgradedGiftColors upgradedGiftColors, int profileAccentColorId, long profileBackgroundCustomEmojiId, ChatPermissions permissions, Message lastMessage, ChatPosition[] positions, ChatList[] chatLists, MessageSender messageSenderId, BlockList blockList, boolean hasProtectedContent, boolean isTranslatable, boolean isMarkedAsUnread, boolean viewAsTopics, boolean hasScheduledMessages, boolean canBeDeletedOnlyForSelf, boolean canBeDeletedForAllUsers, boolean canBeReported, boolean defaultDisableNotification, int unreadCount, long lastReadInboxMessageId, long lastReadOutboxMessageId, int unreadMentionCount, int unreadReactionCount, ChatNotificationSettings notificationSettings, ChatAvailableReactions availableReactions, int messageAutoDeleteTime, EmojiStatus emojiStatus, ChatBackground background, ChatTheme theme, ChatActionBar actionBar, BusinessBotManageBar businessBotManageBar, VideoChat videoChat, ChatJoinRequestsInfo pendingJoinRequests, long replyMarkupMessageId, DraftMessage draftMessage, String clientData) { - this.id = id; - this.type = type; - this.title = title; - this.photo = photo; - this.accentColorId = accentColorId; - this.backgroundCustomEmojiId = backgroundCustomEmojiId; - this.upgradedGiftColors = upgradedGiftColors; - this.profileAccentColorId = profileAccentColorId; - this.profileBackgroundCustomEmojiId = profileBackgroundCustomEmojiId; - this.permissions = permissions; - this.lastMessage = lastMessage; - this.positions = positions; - this.chatLists = chatLists; - this.messageSenderId = messageSenderId; - this.blockList = blockList; - this.hasProtectedContent = hasProtectedContent; - this.isTranslatable = isTranslatable; - this.isMarkedAsUnread = isMarkedAsUnread; - this.viewAsTopics = viewAsTopics; - this.hasScheduledMessages = hasScheduledMessages; - this.canBeDeletedOnlyForSelf = canBeDeletedOnlyForSelf; - this.canBeDeletedForAllUsers = canBeDeletedForAllUsers; - this.canBeReported = canBeReported; - this.defaultDisableNotification = defaultDisableNotification; - this.unreadCount = unreadCount; - this.lastReadInboxMessageId = lastReadInboxMessageId; - this.lastReadOutboxMessageId = lastReadOutboxMessageId; - this.unreadMentionCount = unreadMentionCount; - this.unreadReactionCount = unreadReactionCount; - this.notificationSettings = notificationSettings; - this.availableReactions = availableReactions; - this.messageAutoDeleteTime = messageAutoDeleteTime; - this.emojiStatus = emojiStatus; - this.background = background; - this.theme = theme; - this.actionBar = actionBar; - this.businessBotManageBar = businessBotManageBar; - this.videoChat = videoChat; - this.pendingJoinRequests = pendingJoinRequests; - this.replyMarkupMessageId = replyMarkupMessageId; - this.draftMessage = draftMessage; - this.clientData = clientData; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -77484353; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the different types of activity in a chat. - */ - public abstract static class ChatAction extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ChatActionTyping.CONSTRUCTOR, - ChatActionRecordingVideo.CONSTRUCTOR, - ChatActionUploadingVideo.CONSTRUCTOR, - ChatActionRecordingVoiceNote.CONSTRUCTOR, - ChatActionUploadingVoiceNote.CONSTRUCTOR, - ChatActionUploadingPhoto.CONSTRUCTOR, - ChatActionUploadingDocument.CONSTRUCTOR, - ChatActionChoosingSticker.CONSTRUCTOR, - ChatActionChoosingLocation.CONSTRUCTOR, - ChatActionChoosingContact.CONSTRUCTOR, - ChatActionStartPlayingGame.CONSTRUCTOR, - ChatActionRecordingVideoNote.CONSTRUCTOR, - ChatActionUploadingVideoNote.CONSTRUCTOR, - ChatActionWatchingAnimations.CONSTRUCTOR, - ChatActionCancel.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ChatAction() { - } - } - - /** - * The user is typing a message. - */ - public static class ChatActionTyping extends ChatAction { - - /** - * The user is typing a message. - */ - public ChatActionTyping() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 380122167; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is recording a video. - */ - public static class ChatActionRecordingVideo extends ChatAction { - - /** - * The user is recording a video. - */ - public ChatActionRecordingVideo() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 216553362; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is uploading a video. - */ - public static class ChatActionUploadingVideo extends ChatAction { - /** - * Upload progress, as a percentage. - */ - public int progress; - - /** - * The user is uploading a video. - */ - public ChatActionUploadingVideo() { - } - - /** - * The user is uploading a video. - * - * @param progress Upload progress, as a percentage. - */ - public ChatActionUploadingVideo(int progress) { - this.progress = progress; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1234185270; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is recording a voice note. - */ - public static class ChatActionRecordingVoiceNote extends ChatAction { - - /** - * The user is recording a voice note. - */ - public ChatActionRecordingVoiceNote() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -808850058; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is uploading a voice note. - */ - public static class ChatActionUploadingVoiceNote extends ChatAction { - /** - * Upload progress, as a percentage. - */ - public int progress; - - /** - * The user is uploading a voice note. - */ - public ChatActionUploadingVoiceNote() { - } - - /** - * The user is uploading a voice note. - * - * @param progress Upload progress, as a percentage. - */ - public ChatActionUploadingVoiceNote(int progress) { - this.progress = progress; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -613643666; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is uploading a photo. - */ - public static class ChatActionUploadingPhoto extends ChatAction { - /** - * Upload progress, as a percentage. - */ - public int progress; - - /** - * The user is uploading a photo. - */ - public ChatActionUploadingPhoto() { - } - - /** - * The user is uploading a photo. - * - * @param progress Upload progress, as a percentage. - */ - public ChatActionUploadingPhoto(int progress) { - this.progress = progress; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 654240583; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is uploading a document. - */ - public static class ChatActionUploadingDocument extends ChatAction { - /** - * Upload progress, as a percentage. - */ - public int progress; - - /** - * The user is uploading a document. - */ - public ChatActionUploadingDocument() { - } - - /** - * The user is uploading a document. - * - * @param progress Upload progress, as a percentage. - */ - public ChatActionUploadingDocument(int progress) { - this.progress = progress; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 167884362; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is picking a sticker to send. - */ - public static class ChatActionChoosingSticker extends ChatAction { - - /** - * The user is picking a sticker to send. - */ - public ChatActionChoosingSticker() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 372753697; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is picking a location or venue to send. - */ - public static class ChatActionChoosingLocation extends ChatAction { - - /** - * The user is picking a location or venue to send. - */ - public ChatActionChoosingLocation() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2017893596; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is picking a contact to send. - */ - public static class ChatActionChoosingContact extends ChatAction { - - /** - * The user is picking a contact to send. - */ - public ChatActionChoosingContact() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1222507496; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user has started to play a game. - */ - public static class ChatActionStartPlayingGame extends ChatAction { - - /** - * The user has started to play a game. - */ - public ChatActionStartPlayingGame() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -865884164; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is recording a video note. - */ - public static class ChatActionRecordingVideoNote extends ChatAction { - - /** - * The user is recording a video note. - */ - public ChatActionRecordingVideoNote() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 16523393; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is uploading a video note. - */ - public static class ChatActionUploadingVideoNote extends ChatAction { - /** - * Upload progress, as a percentage. - */ - public int progress; - - /** - * The user is uploading a video note. - */ - public ChatActionUploadingVideoNote() { - } - - /** - * The user is uploading a video note. - * - * @param progress Upload progress, as a percentage. - */ - public ChatActionUploadingVideoNote(int progress) { - this.progress = progress; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1172364918; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is watching animations sent by the other party by clicking on an animated emoji. - */ - public static class ChatActionWatchingAnimations extends ChatAction { - /** - * The animated emoji. - */ - public String emoji; - - /** - * The user is watching animations sent by the other party by clicking on an animated emoji. - */ - public ChatActionWatchingAnimations() { - } - - /** - * The user is watching animations sent by the other party by clicking on an animated emoji. - * - * @param emoji The animated emoji. - */ - public ChatActionWatchingAnimations(String emoji) { - this.emoji = emoji; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2052990641; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user has canceled the previous action. - */ - public static class ChatActionCancel extends ChatAction { - - /** - * The user has canceled the previous action. - */ - public ChatActionCancel() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1160523958; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes actions which must be possible to do through a chat action bar. - */ - public abstract static class ChatActionBar extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ChatActionBarReportSpam.CONSTRUCTOR, - ChatActionBarInviteMembers.CONSTRUCTOR, - ChatActionBarReportAddBlock.CONSTRUCTOR, - ChatActionBarAddContact.CONSTRUCTOR, - ChatActionBarSharePhoneNumber.CONSTRUCTOR, - ChatActionBarJoinRequest.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ChatActionBar() { - } - } - - /** - * The chat can be reported as spam using the method reportChat with an empty optionId and messageIds. If the chat is a private chat with a user with an emoji status, then a notice about emoji status usage must be shown. - */ - public static class ChatActionBarReportSpam extends ChatActionBar { - /** - * If true, the chat was automatically archived and can be moved back to the main chat list using addChatToList simultaneously with setting chat notification settings to default using setChatNotificationSettings. - */ - public boolean canUnarchive; - - /** - * The chat can be reported as spam using the method reportChat with an empty optionId and messageIds. If the chat is a private chat with a user with an emoji status, then a notice about emoji status usage must be shown. - */ - public ChatActionBarReportSpam() { - } - - /** - * The chat can be reported as spam using the method reportChat with an empty optionId and messageIds. If the chat is a private chat with a user with an emoji status, then a notice about emoji status usage must be shown. - * - * @param canUnarchive If true, the chat was automatically archived and can be moved back to the main chat list using addChatToList simultaneously with setting chat notification settings to default using setChatNotificationSettings. - */ - public ChatActionBarReportSpam(boolean canUnarchive) { - this.canUnarchive = canUnarchive; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1312758246; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat is a recently created group chat to which new members can be invited. - */ - public static class ChatActionBarInviteMembers extends ChatActionBar { - - /** - * The chat is a recently created group chat to which new members can be invited. - */ - public ChatActionBarInviteMembers() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1985313904; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat is a private or secret chat, which can be reported using the method reportChat, or the other user can be blocked using the method setMessageSenderBlockList, or the other user can be added to the contact list using the method addContact. If the chat is a private chat with a user with an emoji status, then a notice about emoji status usage must be shown. - */ - public static class ChatActionBarReportAddBlock extends ChatActionBar { - /** - * If true, the chat was automatically archived and can be moved back to the main chat list using addChatToList simultaneously with setting chat notification settings to default using setChatNotificationSettings. - */ - public boolean canUnarchive; - /** - * Basic information about the other user in the chat; may be null if unknown. - */ - @Nullable public AccountInfo accountInfo; - - /** - * The chat is a private or secret chat, which can be reported using the method reportChat, or the other user can be blocked using the method setMessageSenderBlockList, or the other user can be added to the contact list using the method addContact. If the chat is a private chat with a user with an emoji status, then a notice about emoji status usage must be shown. - */ - public ChatActionBarReportAddBlock() { - } - - /** - * The chat is a private or secret chat, which can be reported using the method reportChat, or the other user can be blocked using the method setMessageSenderBlockList, or the other user can be added to the contact list using the method addContact. If the chat is a private chat with a user with an emoji status, then a notice about emoji status usage must be shown. - * - * @param canUnarchive If true, the chat was automatically archived and can be moved back to the main chat list using addChatToList simultaneously with setting chat notification settings to default using setChatNotificationSettings. - * @param accountInfo Basic information about the other user in the chat; may be null if unknown. - */ - public ChatActionBarReportAddBlock(boolean canUnarchive, AccountInfo accountInfo) { - this.canUnarchive = canUnarchive; - this.accountInfo = accountInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1476817269; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat is a private or secret chat and the other user can be added to the contact list using the method addContact. - */ - public static class ChatActionBarAddContact extends ChatActionBar { - - /** - * The chat is a private or secret chat and the other user can be added to the contact list using the method addContact. - */ - public ChatActionBarAddContact() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -733325295; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat is a private or secret chat with a mutual contact and the user's phone number can be shared with the other user using the method sharePhoneNumber. - */ - public static class ChatActionBarSharePhoneNumber extends ChatActionBar { - - /** - * The chat is a private or secret chat with a mutual contact and the user's phone number can be shared with the other user using the method sharePhoneNumber. - */ - public ChatActionBarSharePhoneNumber() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 35188697; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat is a private chat with an administrator of a chat to which the user sent join request. - */ - public static class ChatActionBarJoinRequest extends ChatActionBar { - /** - * Title of the chat to which the join request was sent. - */ - public String title; - /** - * True, if the join request was sent to a channel chat. - */ - public boolean isChannel; - /** - * Point in time (Unix timestamp) when the join request was sent. - */ - public int requestDate; - - /** - * The chat is a private chat with an administrator of a chat to which the user sent join request. - */ - public ChatActionBarJoinRequest() { - } - - /** - * The chat is a private chat with an administrator of a chat to which the user sent join request. - * - * @param title Title of the chat to which the join request was sent. - * @param isChannel True, if the join request was sent to a channel chat. - * @param requestDate Point in time (Unix timestamp) when the join request was sent. - */ - public ChatActionBarJoinRequest(String title, boolean isChannel, int requestDate) { - this.title = title; - this.isChannel = isChannel; - this.requestDate = requestDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1037140744; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes active stories posted by a chat. - */ - public static class ChatActiveStories extends Object { - /** - * Identifier of the chat that posted the stories. - */ - public long chatId; - /** - * Identifier of the story list in which the stories are shown; may be null if the stories aren't shown in a story list. - */ - @Nullable public StoryList list; - /** - * A parameter used to determine order of the stories in the story list; 0 if the stories doesn't need to be shown in the story list. Stories must be sorted by the pair (order, storyPosterChatId) in descending order. - */ - public long order; - /** - * True, if the stories are shown in the main story list and can be archived; otherwise, the stories can be hidden from the main story list only by calling removeTopChat with topChatCategoryUsers and the chatId. Stories of the current user can't be archived nor hidden using removeTopChat. - */ - public boolean canBeArchived; - /** - * Identifier of the last read active story. - */ - public int maxReadStoryId; - /** - * Basic information about the stories; use getStory to get full information about the stories. The stories are in chronological order (i.e., in order of increasing story identifiers). - */ - public StoryInfo[] stories; - - /** - * Describes active stories posted by a chat. - */ - public ChatActiveStories() { - } - - /** - * Describes active stories posted by a chat. - * - * @param chatId Identifier of the chat that posted the stories. - * @param list Identifier of the story list in which the stories are shown; may be null if the stories aren't shown in a story list. - * @param order A parameter used to determine order of the stories in the story list; 0 if the stories doesn't need to be shown in the story list. Stories must be sorted by the pair (order, storyPosterChatId) in descending order. - * @param canBeArchived True, if the stories are shown in the main story list and can be archived; otherwise, the stories can be hidden from the main story list only by calling removeTopChat with topChatCategoryUsers and the chatId. Stories of the current user can't be archived nor hidden using removeTopChat. - * @param maxReadStoryId Identifier of the last read active story. - * @param stories Basic information about the stories; use getStory to get full information about the stories. The stories are in chronological order (i.e., in order of increasing story identifiers). - */ - public ChatActiveStories(long chatId, StoryList list, long order, boolean canBeArchived, int maxReadStoryId, StoryInfo[] stories) { - this.chatId = chatId; - this.list = list; - this.order = order; - this.canBeArchived = canBeArchived; - this.maxReadStoryId = maxReadStoryId; - this.stories = stories; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 396502772; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a chat administrator. - */ - public static class ChatAdministrator extends Object { - /** - * User identifier of the administrator. - */ - public long userId; - /** - * Custom title of the administrator. - */ - public String customTitle; - /** - * True, if the user is the owner of the chat. - */ - public boolean isOwner; - - /** - * Contains information about a chat administrator. - */ - public ChatAdministrator() { - } - - /** - * Contains information about a chat administrator. - * - * @param userId User identifier of the administrator. - * @param customTitle Custom title of the administrator. - * @param isOwner True, if the user is the owner of the chat. - */ - public ChatAdministrator(long userId, String customTitle, boolean isOwner) { - this.userId = userId; - this.customTitle = customTitle; - this.isOwner = isOwner; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1920449836; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes rights of the administrator. - */ - public static class ChatAdministratorRights extends Object { - /** - * True, if the administrator can access the chat event log, get boost list, see hidden supergroup and channel members, report supergroup spam messages, ignore slow mode, and send messages to the chat without paying Telegram Stars. Implied by any other privilege; applicable to supergroups and channels only. - */ - public boolean canManageChat; - /** - * True, if the administrator can change the chat title, photo, and other settings. - */ - public boolean canChangeInfo; - /** - * True, if the administrator can create channel posts, approve suggested channel posts, or view channel statistics; applicable to channels only. - */ - public boolean canPostMessages; - /** - * True, if the administrator can edit messages of other users and pin messages; applicable to channels only. - */ - public boolean canEditMessages; - /** - * True, if the administrator can delete messages of other users. - */ - public boolean canDeleteMessages; - /** - * True, if the administrator can invite new users to the chat. - */ - public boolean canInviteUsers; - /** - * True, if the administrator can restrict, ban, or unban chat members or view supergroup statistics. - */ - public boolean canRestrictMembers; - /** - * True, if the administrator can pin messages; applicable to basic groups and supergroups only. - */ - public boolean canPinMessages; - /** - * True, if the administrator can create, rename, close, reopen, hide, and unhide forum topics; applicable to forum supergroups only. - */ - public boolean canManageTopics; - /** - * True, if the administrator can add new administrators with a subset of their own privileges or demote administrators that were directly or indirectly promoted by them. - */ - public boolean canPromoteMembers; - /** - * True, if the administrator can manage video chats. - */ - public boolean canManageVideoChats; - /** - * True, if the administrator can create new chat stories, or edit and delete posted stories; applicable to supergroups and channels only. - */ - public boolean canPostStories; - /** - * True, if the administrator can edit stories posted by other users, post stories to the chat page, pin chat stories, and access story archive; applicable to supergroups and channels only. - */ - public boolean canEditStories; - /** - * True, if the administrator can delete stories posted by other users; applicable to supergroups and channels only. - */ - public boolean canDeleteStories; - /** - * True, if the administrator can answer to channel direct messages; applicable to channels only. - */ - public boolean canManageDirectMessages; - /** - * True, if the administrator can change tags of other users; applicable to basic groups and supergroups only. - */ - public boolean canManageTags; - /** - * True, if the administrator isn't shown in the chat member list and sends messages anonymously; applicable to supergroups only. - */ - public boolean isAnonymous; - - /** - * Describes rights of the administrator. - */ - public ChatAdministratorRights() { - } - - /** - * Describes rights of the administrator. - * - * @param canManageChat True, if the administrator can access the chat event log, get boost list, see hidden supergroup and channel members, report supergroup spam messages, ignore slow mode, and send messages to the chat without paying Telegram Stars. Implied by any other privilege; applicable to supergroups and channels only. - * @param canChangeInfo True, if the administrator can change the chat title, photo, and other settings. - * @param canPostMessages True, if the administrator can create channel posts, approve suggested channel posts, or view channel statistics; applicable to channels only. - * @param canEditMessages True, if the administrator can edit messages of other users and pin messages; applicable to channels only. - * @param canDeleteMessages True, if the administrator can delete messages of other users. - * @param canInviteUsers True, if the administrator can invite new users to the chat. - * @param canRestrictMembers True, if the administrator can restrict, ban, or unban chat members or view supergroup statistics. - * @param canPinMessages True, if the administrator can pin messages; applicable to basic groups and supergroups only. - * @param canManageTopics True, if the administrator can create, rename, close, reopen, hide, and unhide forum topics; applicable to forum supergroups only. - * @param canPromoteMembers True, if the administrator can add new administrators with a subset of their own privileges or demote administrators that were directly or indirectly promoted by them. - * @param canManageVideoChats True, if the administrator can manage video chats. - * @param canPostStories True, if the administrator can create new chat stories, or edit and delete posted stories; applicable to supergroups and channels only. - * @param canEditStories True, if the administrator can edit stories posted by other users, post stories to the chat page, pin chat stories, and access story archive; applicable to supergroups and channels only. - * @param canDeleteStories True, if the administrator can delete stories posted by other users; applicable to supergroups and channels only. - * @param canManageDirectMessages True, if the administrator can answer to channel direct messages; applicable to channels only. - * @param canManageTags True, if the administrator can change tags of other users; applicable to basic groups and supergroups only. - * @param isAnonymous True, if the administrator isn't shown in the chat member list and sends messages anonymously; applicable to supergroups only. - */ - public ChatAdministratorRights(boolean canManageChat, boolean canChangeInfo, boolean canPostMessages, boolean canEditMessages, boolean canDeleteMessages, boolean canInviteUsers, boolean canRestrictMembers, boolean canPinMessages, boolean canManageTopics, boolean canPromoteMembers, boolean canManageVideoChats, boolean canPostStories, boolean canEditStories, boolean canDeleteStories, boolean canManageDirectMessages, boolean canManageTags, boolean isAnonymous) { - this.canManageChat = canManageChat; - this.canChangeInfo = canChangeInfo; - this.canPostMessages = canPostMessages; - this.canEditMessages = canEditMessages; - this.canDeleteMessages = canDeleteMessages; - this.canInviteUsers = canInviteUsers; - this.canRestrictMembers = canRestrictMembers; - this.canPinMessages = canPinMessages; - this.canManageTopics = canManageTopics; - this.canPromoteMembers = canPromoteMembers; - this.canManageVideoChats = canManageVideoChats; - this.canPostStories = canPostStories; - this.canEditStories = canEditStories; - this.canDeleteStories = canDeleteStories; - this.canManageDirectMessages = canManageDirectMessages; - this.canManageTags = canManageTags; - this.isAnonymous = isAnonymous; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1562741834; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of chat administrators. - */ - public static class ChatAdministrators extends Object { - /** - * A list of chat administrators. - */ - public ChatAdministrator[] administrators; - - /** - * Represents a list of chat administrators. - */ - public ChatAdministrators() { - } - - /** - * Represents a list of chat administrators. - * - * @param administrators A list of chat administrators. - */ - public ChatAdministrators(ChatAdministrator[] administrators) { - this.administrators = administrators; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2126186435; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes reactions available in the chat. - */ - public abstract static class ChatAvailableReactions extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ChatAvailableReactionsAll.CONSTRUCTOR, - ChatAvailableReactionsSome.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ChatAvailableReactions() { - } - } - - /** - * All reactions are available in the chat, excluding the paid reaction and custom reactions in channel chats. - */ - public static class ChatAvailableReactionsAll extends ChatAvailableReactions { - /** - * The maximum allowed number of reactions per message; 1-11. - */ - public int maxReactionCount; - - /** - * All reactions are available in the chat, excluding the paid reaction and custom reactions in channel chats. - */ - public ChatAvailableReactionsAll() { - } - - /** - * All reactions are available in the chat, excluding the paid reaction and custom reactions in channel chats. - * - * @param maxReactionCount The maximum allowed number of reactions per message; 1-11. - */ - public ChatAvailableReactionsAll(int maxReactionCount) { - this.maxReactionCount = maxReactionCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 694160279; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Only specific reactions are available in the chat. - */ - public static class ChatAvailableReactionsSome extends ChatAvailableReactions { - /** - * The list of reactions. - */ - public ReactionType[] reactions; - /** - * The maximum allowed number of reactions per message; 1-11. - */ - public int maxReactionCount; - - /** - * Only specific reactions are available in the chat. - */ - public ChatAvailableReactionsSome() { - } - - /** - * Only specific reactions are available in the chat. - * - * @param reactions The list of reactions. - * @param maxReactionCount The maximum allowed number of reactions per message; 1-11. - */ - public ChatAvailableReactionsSome(ReactionType[] reactions, int maxReactionCount) { - this.reactions = reactions; - this.maxReactionCount = maxReactionCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 152513153; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a background set for a specific chat. - */ - public static class ChatBackground extends Object { - /** - * The background. - */ - public Background background; - /** - * Dimming of the background in dark themes, as a percentage; 0-100. Applied only to Wallpaper and Fill types of background. - */ - public int darkThemeDimming; - - /** - * Describes a background set for a specific chat. - */ - public ChatBackground() { - } - - /** - * Describes a background set for a specific chat. - * - * @param background The background. - * @param darkThemeDimming Dimming of the background in dark themes, as a percentage; 0-100. Applied only to Wallpaper and Fill types of background. - */ - public ChatBackground(Background background, int darkThemeDimming) { - this.background = background; - this.darkThemeDimming = darkThemeDimming; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1653152104; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a boost applied to a chat. - */ - public static class ChatBoost extends Object { - /** - * Unique identifier of the boost. - */ - public String id; - /** - * The number of identical boosts applied. - */ - public int count; - /** - * Source of the boost. - */ - public ChatBoostSource source; - /** - * Point in time (Unix timestamp) when the chat was boosted. - */ - public int startDate; - /** - * Point in time (Unix timestamp) when the boost will expire. - */ - public int expirationDate; - - /** - * Describes a boost applied to a chat. - */ - public ChatBoost() { - } - - /** - * Describes a boost applied to a chat. - * - * @param id Unique identifier of the boost. - * @param count The number of identical boosts applied. - * @param source Source of the boost. - * @param startDate Point in time (Unix timestamp) when the chat was boosted. - * @param expirationDate Point in time (Unix timestamp) when the boost will expire. - */ - public ChatBoost(String id, int count, ChatBoostSource source, int startDate, int expirationDate) { - this.id = id; - this.count = count; - this.source = source; - this.startDate = startDate; - this.expirationDate = expirationDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1765815118; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of features available on the first chat boost levels. - */ - public static class ChatBoostFeatures extends Object { - /** - * The list of features. - */ - public ChatBoostLevelFeatures[] features; - /** - * The minimum boost level required to set custom emoji for profile background. - */ - public int minProfileBackgroundCustomEmojiBoostLevel; - /** - * The minimum boost level required to set custom emoji for reply header and link preview background; for channel chats only. - */ - public int minBackgroundCustomEmojiBoostLevel; - /** - * The minimum boost level required to set emoji status. - */ - public int minEmojiStatusBoostLevel; - /** - * The minimum boost level required to set a chat theme background as chat background. - */ - public int minChatThemeBackgroundBoostLevel; - /** - * The minimum boost level required to set custom chat background. - */ - public int minCustomBackgroundBoostLevel; - /** - * The minimum boost level required to set custom emoji sticker set for the chat; for supergroup chats only. - */ - public int minCustomEmojiStickerSetBoostLevel; - /** - * The minimum boost level allowing to enable automatic translation of messages for non-Premium users; for channel chats only. - */ - public int minAutomaticTranslationBoostLevel; - /** - * The minimum boost level allowing to recognize speech in video note and voice note messages for non-Premium users; for supergroup chats only. - */ - public int minSpeechRecognitionBoostLevel; - /** - * The minimum boost level allowing to disable sponsored messages in the chat; for channel chats only. - */ - public int minSponsoredMessageDisableBoostLevel; - - /** - * Contains a list of features available on the first chat boost levels. - */ - public ChatBoostFeatures() { - } - - /** - * Contains a list of features available on the first chat boost levels. - * - * @param features The list of features. - * @param minProfileBackgroundCustomEmojiBoostLevel The minimum boost level required to set custom emoji for profile background. - * @param minBackgroundCustomEmojiBoostLevel The minimum boost level required to set custom emoji for reply header and link preview background; for channel chats only. - * @param minEmojiStatusBoostLevel The minimum boost level required to set emoji status. - * @param minChatThemeBackgroundBoostLevel The minimum boost level required to set a chat theme background as chat background. - * @param minCustomBackgroundBoostLevel The minimum boost level required to set custom chat background. - * @param minCustomEmojiStickerSetBoostLevel The minimum boost level required to set custom emoji sticker set for the chat; for supergroup chats only. - * @param minAutomaticTranslationBoostLevel The minimum boost level allowing to enable automatic translation of messages for non-Premium users; for channel chats only. - * @param minSpeechRecognitionBoostLevel The minimum boost level allowing to recognize speech in video note and voice note messages for non-Premium users; for supergroup chats only. - * @param minSponsoredMessageDisableBoostLevel The minimum boost level allowing to disable sponsored messages in the chat; for channel chats only. - */ - public ChatBoostFeatures(ChatBoostLevelFeatures[] features, int minProfileBackgroundCustomEmojiBoostLevel, int minBackgroundCustomEmojiBoostLevel, int minEmojiStatusBoostLevel, int minChatThemeBackgroundBoostLevel, int minCustomBackgroundBoostLevel, int minCustomEmojiStickerSetBoostLevel, int minAutomaticTranslationBoostLevel, int minSpeechRecognitionBoostLevel, int minSponsoredMessageDisableBoostLevel) { - this.features = features; - this.minProfileBackgroundCustomEmojiBoostLevel = minProfileBackgroundCustomEmojiBoostLevel; - this.minBackgroundCustomEmojiBoostLevel = minBackgroundCustomEmojiBoostLevel; - this.minEmojiStatusBoostLevel = minEmojiStatusBoostLevel; - this.minChatThemeBackgroundBoostLevel = minChatThemeBackgroundBoostLevel; - this.minCustomBackgroundBoostLevel = minCustomBackgroundBoostLevel; - this.minCustomEmojiStickerSetBoostLevel = minCustomEmojiStickerSetBoostLevel; - this.minAutomaticTranslationBoostLevel = minAutomaticTranslationBoostLevel; - this.minSpeechRecognitionBoostLevel = minSpeechRecognitionBoostLevel; - this.minSponsoredMessageDisableBoostLevel = minSponsoredMessageDisableBoostLevel; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -940531367; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of features available on a specific chat boost level. - */ - public static class ChatBoostLevelFeatures extends Object { - /** - * Target chat boost level. - */ - public int level; - /** - * Number of stories that the chat can publish daily. - */ - public int storyPerDayCount; - /** - * Number of custom emoji reactions that can be added to the list of available reactions. - */ - public int customEmojiReactionCount; - /** - * Number of custom colors for chat title. - */ - public int titleColorCount; - /** - * Number of custom colors for profile photo background. - */ - public int profileAccentColorCount; - /** - * True, if custom emoji for profile background can be set. - */ - public boolean canSetProfileBackgroundCustomEmoji; - /** - * Number of custom colors for background of empty chat photo, replies to messages and link previews. - */ - public int accentColorCount; - /** - * True, if custom emoji for reply header and link preview background can be set. - */ - public boolean canSetBackgroundCustomEmoji; - /** - * True, if emoji status can be set. - */ - public boolean canSetEmojiStatus; - /** - * Number of chat theme backgrounds that can be set as chat background. - */ - public int chatThemeBackgroundCount; - /** - * True, if custom background can be set in the chat for all users. - */ - public boolean canSetCustomBackground; - /** - * True, if custom emoji sticker set can be set for the chat. - */ - public boolean canSetCustomEmojiStickerSet; - /** - * True, if automatic translation of messages can be enabled in the chat. - */ - public boolean canEnableAutomaticTranslation; - /** - * True, if speech recognition can be used for video note and voice note messages by all users. - */ - public boolean canRecognizeSpeech; - /** - * True, if sponsored messages can be disabled in the chat. - */ - public boolean canDisableSponsoredMessages; - - /** - * Contains a list of features available on a specific chat boost level. - */ - public ChatBoostLevelFeatures() { - } - - /** - * Contains a list of features available on a specific chat boost level. - * - * @param level Target chat boost level. - * @param storyPerDayCount Number of stories that the chat can publish daily. - * @param customEmojiReactionCount Number of custom emoji reactions that can be added to the list of available reactions. - * @param titleColorCount Number of custom colors for chat title. - * @param profileAccentColorCount Number of custom colors for profile photo background. - * @param canSetProfileBackgroundCustomEmoji True, if custom emoji for profile background can be set. - * @param accentColorCount Number of custom colors for background of empty chat photo, replies to messages and link previews. - * @param canSetBackgroundCustomEmoji True, if custom emoji for reply header and link preview background can be set. - * @param canSetEmojiStatus True, if emoji status can be set. - * @param chatThemeBackgroundCount Number of chat theme backgrounds that can be set as chat background. - * @param canSetCustomBackground True, if custom background can be set in the chat for all users. - * @param canSetCustomEmojiStickerSet True, if custom emoji sticker set can be set for the chat. - * @param canEnableAutomaticTranslation True, if automatic translation of messages can be enabled in the chat. - * @param canRecognizeSpeech True, if speech recognition can be used for video note and voice note messages by all users. - * @param canDisableSponsoredMessages True, if sponsored messages can be disabled in the chat. - */ - public ChatBoostLevelFeatures(int level, int storyPerDayCount, int customEmojiReactionCount, int titleColorCount, int profileAccentColorCount, boolean canSetProfileBackgroundCustomEmoji, int accentColorCount, boolean canSetBackgroundCustomEmoji, boolean canSetEmojiStatus, int chatThemeBackgroundCount, boolean canSetCustomBackground, boolean canSetCustomEmojiStickerSet, boolean canEnableAutomaticTranslation, boolean canRecognizeSpeech, boolean canDisableSponsoredMessages) { - this.level = level; - this.storyPerDayCount = storyPerDayCount; - this.customEmojiReactionCount = customEmojiReactionCount; - this.titleColorCount = titleColorCount; - this.profileAccentColorCount = profileAccentColorCount; - this.canSetProfileBackgroundCustomEmoji = canSetProfileBackgroundCustomEmoji; - this.accentColorCount = accentColorCount; - this.canSetBackgroundCustomEmoji = canSetBackgroundCustomEmoji; - this.canSetEmojiStatus = canSetEmojiStatus; - this.chatThemeBackgroundCount = chatThemeBackgroundCount; - this.canSetCustomBackground = canSetCustomBackground; - this.canSetCustomEmojiStickerSet = canSetCustomEmojiStickerSet; - this.canEnableAutomaticTranslation = canEnableAutomaticTranslation; - this.canRecognizeSpeech = canRecognizeSpeech; - this.canDisableSponsoredMessages = canDisableSponsoredMessages; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 975439470; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains an HTTPS link to boost a chat. - */ - public static class ChatBoostLink extends Object { - /** - * The link. - */ - public String link; - /** - * True, if the link will work for non-members of the chat. - */ - public boolean isPublic; - - /** - * Contains an HTTPS link to boost a chat. - */ - public ChatBoostLink() { - } - - /** - * Contains an HTTPS link to boost a chat. - * - * @param link The link. - * @param isPublic True, if the link will work for non-members of the chat. - */ - public ChatBoostLink(String link, boolean isPublic) { - this.link = link; - this.isPublic = isPublic; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1253999503; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a link to boost a chat. - */ - public static class ChatBoostLinkInfo extends Object { - /** - * True, if the link will work for non-members of the chat. - */ - public boolean isPublic; - /** - * Identifier of the chat to which the link points; 0 if the chat isn't found. - */ - public long chatId; - - /** - * Contains information about a link to boost a chat. - */ - public ChatBoostLinkInfo() { - } - - /** - * Contains information about a link to boost a chat. - * - * @param isPublic True, if the link will work for non-members of the chat. - * @param chatId Identifier of the chat to which the link points; 0 if the chat isn't found. - */ - public ChatBoostLinkInfo(boolean isPublic, long chatId) { - this.isPublic = isPublic; - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -602785660; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a slot for chat boost. - */ - public static class ChatBoostSlot extends Object { - /** - * Unique identifier of the slot. - */ - public int slotId; - /** - * Identifier of the currently boosted chat; 0 if none. - */ - public long currentlyBoostedChatId; - /** - * Point in time (Unix timestamp) when the chat was boosted; 0 if none. - */ - public int startDate; - /** - * Point in time (Unix timestamp) when the boost will expire. - */ - public int expirationDate; - /** - * Point in time (Unix timestamp) after which the boost can be used for another chat. - */ - public int cooldownUntilDate; - - /** - * Describes a slot for chat boost. - */ - public ChatBoostSlot() { - } - - /** - * Describes a slot for chat boost. - * - * @param slotId Unique identifier of the slot. - * @param currentlyBoostedChatId Identifier of the currently boosted chat; 0 if none. - * @param startDate Point in time (Unix timestamp) when the chat was boosted; 0 if none. - * @param expirationDate Point in time (Unix timestamp) when the boost will expire. - * @param cooldownUntilDate Point in time (Unix timestamp) after which the boost can be used for another chat. - */ - public ChatBoostSlot(int slotId, long currentlyBoostedChatId, int startDate, int expirationDate, int cooldownUntilDate) { - this.slotId = slotId; - this.currentlyBoostedChatId = currentlyBoostedChatId; - this.startDate = startDate; - this.expirationDate = expirationDate; - this.cooldownUntilDate = cooldownUntilDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 123206343; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of chat boost slots. - */ - public static class ChatBoostSlots extends Object { - /** - * List of boost slots. - */ - public ChatBoostSlot[] slots; - - /** - * Contains a list of chat boost slots. - */ - public ChatBoostSlots() { - } - - /** - * Contains a list of chat boost slots. - * - * @param slots List of boost slots. - */ - public ChatBoostSlots(ChatBoostSlot[] slots) { - this.slots = slots; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1014966293; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes source of a chat boost. - */ - public abstract static class ChatBoostSource extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ChatBoostSourceGiftCode.CONSTRUCTOR, - ChatBoostSourceGiveaway.CONSTRUCTOR, - ChatBoostSourcePremium.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ChatBoostSource() { - } - } - - /** - * The chat created a Telegram Premium gift code for a user. - */ - public static class ChatBoostSourceGiftCode extends ChatBoostSource { - /** - * Identifier of a user, for which the gift code was created. - */ - public long userId; - /** - * The created Telegram Premium gift code, which is known only if this is a gift code for the current user, or it has already been claimed. - */ - public String giftCode; - - /** - * The chat created a Telegram Premium gift code for a user. - */ - public ChatBoostSourceGiftCode() { - } - - /** - * The chat created a Telegram Premium gift code for a user. - * - * @param userId Identifier of a user, for which the gift code was created. - * @param giftCode The created Telegram Premium gift code, which is known only if this is a gift code for the current user, or it has already been claimed. - */ - public ChatBoostSourceGiftCode(long userId, String giftCode) { - this.userId = userId; - this.giftCode = giftCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -98299206; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat created a giveaway. - */ - public static class ChatBoostSourceGiveaway extends ChatBoostSource { - /** - * Identifier of a user who won in the giveaway; 0 if none. - */ - public long userId; - /** - * The created Telegram Premium gift code if it was used by the user or can be claimed by the current user; an empty string otherwise; for Telegram Premium giveways only. - */ - public String giftCode; - /** - * Number of Telegram Stars distributed among winners of the giveaway. - */ - public long starCount; - /** - * Identifier of the corresponding giveaway message; can be an identifier of a deleted message. - */ - public long giveawayMessageId; - /** - * True, if the winner for the corresponding giveaway prize wasn't chosen, because there were not enough participants. - */ - public boolean isUnclaimed; - - /** - * The chat created a giveaway. - */ - public ChatBoostSourceGiveaway() { - } - - /** - * The chat created a giveaway. - * - * @param userId Identifier of a user who won in the giveaway; 0 if none. - * @param giftCode The created Telegram Premium gift code if it was used by the user or can be claimed by the current user; an empty string otherwise; for Telegram Premium giveways only. - * @param starCount Number of Telegram Stars distributed among winners of the giveaway. - * @param giveawayMessageId Identifier of the corresponding giveaway message; can be an identifier of a deleted message. - * @param isUnclaimed True, if the winner for the corresponding giveaway prize wasn't chosen, because there were not enough participants. - */ - public ChatBoostSourceGiveaway(long userId, String giftCode, long starCount, long giveawayMessageId, boolean isUnclaimed) { - this.userId = userId; - this.giftCode = giftCode; - this.starCount = starCount; - this.giveawayMessageId = giveawayMessageId; - this.isUnclaimed = isUnclaimed; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1918145690; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A user with Telegram Premium subscription or gifted Telegram Premium boosted the chat. - */ - public static class ChatBoostSourcePremium extends ChatBoostSource { - /** - * Identifier of the user. - */ - public long userId; - - /** - * A user with Telegram Premium subscription or gifted Telegram Premium boosted the chat. - */ - public ChatBoostSourcePremium() { - } - - /** - * A user with Telegram Premium subscription or gifted Telegram Premium boosted the chat. - * - * @param userId Identifier of the user. - */ - public ChatBoostSourcePremium(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 972011; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes current boost status of a chat. - */ - public static class ChatBoostStatus extends Object { - /** - * An HTTP URL, which can be used to boost the chat. - */ - public String boostUrl; - /** - * Identifiers of boost slots of the current user applied to the chat. - */ - public int[] appliedSlotIds; - /** - * Current boost level of the chat. - */ - public int level; - /** - * The number of boosts received by the chat from created Telegram Premium gift codes and giveaways; always 0 if the current user isn't an administrator in the chat. - */ - public int giftCodeBoostCount; - /** - * The number of boosts received by the chat. - */ - public int boostCount; - /** - * The number of boosts added to reach the current level. - */ - public int currentLevelBoostCount; - /** - * The number of boosts needed to reach the next level; 0 if the next level isn't available. - */ - public int nextLevelBoostCount; - /** - * Approximate number of Telegram Premium subscribers joined the chat; always 0 if the current user isn't an administrator in the chat. - */ - public int premiumMemberCount; - /** - * A percentage of Telegram Premium subscribers joined the chat; always 0 if the current user isn't an administrator in the chat. - */ - public double premiumMemberPercentage; - /** - * The list of prepaid giveaways available for the chat; only for chat administrators. - */ - public PrepaidGiveaway[] prepaidGiveaways; - - /** - * Describes current boost status of a chat. - */ - public ChatBoostStatus() { - } - - /** - * Describes current boost status of a chat. - * - * @param boostUrl An HTTP URL, which can be used to boost the chat. - * @param appliedSlotIds Identifiers of boost slots of the current user applied to the chat. - * @param level Current boost level of the chat. - * @param giftCodeBoostCount The number of boosts received by the chat from created Telegram Premium gift codes and giveaways; always 0 if the current user isn't an administrator in the chat. - * @param boostCount The number of boosts received by the chat. - * @param currentLevelBoostCount The number of boosts added to reach the current level. - * @param nextLevelBoostCount The number of boosts needed to reach the next level; 0 if the next level isn't available. - * @param premiumMemberCount Approximate number of Telegram Premium subscribers joined the chat; always 0 if the current user isn't an administrator in the chat. - * @param premiumMemberPercentage A percentage of Telegram Premium subscribers joined the chat; always 0 if the current user isn't an administrator in the chat. - * @param prepaidGiveaways The list of prepaid giveaways available for the chat; only for chat administrators. - */ - public ChatBoostStatus(String boostUrl, int[] appliedSlotIds, int level, int giftCodeBoostCount, int boostCount, int currentLevelBoostCount, int nextLevelBoostCount, int premiumMemberCount, double premiumMemberPercentage, PrepaidGiveaway[] prepaidGiveaways) { - this.boostUrl = boostUrl; - this.appliedSlotIds = appliedSlotIds; - this.level = level; - this.giftCodeBoostCount = giftCodeBoostCount; - this.boostCount = boostCount; - this.currentLevelBoostCount = currentLevelBoostCount; - this.nextLevelBoostCount = nextLevelBoostCount; - this.premiumMemberCount = premiumMemberCount; - this.premiumMemberPercentage = premiumMemberPercentage; - this.prepaidGiveaways = prepaidGiveaways; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1050332618; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a chat event. - */ - public static class ChatEvent extends Object { - /** - * Chat event identifier. - */ - public long id; - /** - * Point in time (Unix timestamp) when the event happened. - */ - public int date; - /** - * Identifier of the user or chat who performed the action. - */ - public MessageSender memberId; - /** - * The action. - */ - public ChatEventAction action; - - /** - * Represents a chat event. - */ - public ChatEvent() { - } - - /** - * Represents a chat event. - * - * @param id Chat event identifier. - * @param date Point in time (Unix timestamp) when the event happened. - * @param memberId Identifier of the user or chat who performed the action. - * @param action The action. - */ - public ChatEvent(long id, int date, MessageSender memberId, ChatEventAction action) { - this.id = id; - this.date = date; - this.memberId = memberId; - this.action = action; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -652102704; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents a chat event. - */ - public abstract static class ChatEventAction extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ChatEventMessageEdited.CONSTRUCTOR, - ChatEventMessageDeleted.CONSTRUCTOR, - ChatEventMessagePinned.CONSTRUCTOR, - ChatEventMessageUnpinned.CONSTRUCTOR, - ChatEventPollStopped.CONSTRUCTOR, - ChatEventMemberJoined.CONSTRUCTOR, - ChatEventMemberJoinedByInviteLink.CONSTRUCTOR, - ChatEventMemberJoinedByRequest.CONSTRUCTOR, - ChatEventMemberInvited.CONSTRUCTOR, - ChatEventMemberLeft.CONSTRUCTOR, - ChatEventMemberPromoted.CONSTRUCTOR, - ChatEventMemberRestricted.CONSTRUCTOR, - ChatEventMemberTagChanged.CONSTRUCTOR, - ChatEventMemberSubscriptionExtended.CONSTRUCTOR, - ChatEventAvailableReactionsChanged.CONSTRUCTOR, - ChatEventBackgroundChanged.CONSTRUCTOR, - ChatEventDescriptionChanged.CONSTRUCTOR, - ChatEventEmojiStatusChanged.CONSTRUCTOR, - ChatEventLinkedChatChanged.CONSTRUCTOR, - ChatEventLocationChanged.CONSTRUCTOR, - ChatEventMessageAutoDeleteTimeChanged.CONSTRUCTOR, - ChatEventPermissionsChanged.CONSTRUCTOR, - ChatEventPhotoChanged.CONSTRUCTOR, - ChatEventSlowModeDelayChanged.CONSTRUCTOR, - ChatEventStickerSetChanged.CONSTRUCTOR, - ChatEventCustomEmojiStickerSetChanged.CONSTRUCTOR, - ChatEventTitleChanged.CONSTRUCTOR, - ChatEventUsernameChanged.CONSTRUCTOR, - ChatEventActiveUsernamesChanged.CONSTRUCTOR, - ChatEventAccentColorChanged.CONSTRUCTOR, - ChatEventProfileAccentColorChanged.CONSTRUCTOR, - ChatEventHasProtectedContentToggled.CONSTRUCTOR, - ChatEventInvitesToggled.CONSTRUCTOR, - ChatEventIsAllHistoryAvailableToggled.CONSTRUCTOR, - ChatEventHasAggressiveAntiSpamEnabledToggled.CONSTRUCTOR, - ChatEventSignMessagesToggled.CONSTRUCTOR, - ChatEventShowMessageSenderToggled.CONSTRUCTOR, - ChatEventAutomaticTranslationToggled.CONSTRUCTOR, - ChatEventInviteLinkEdited.CONSTRUCTOR, - ChatEventInviteLinkRevoked.CONSTRUCTOR, - ChatEventInviteLinkDeleted.CONSTRUCTOR, - ChatEventVideoChatCreated.CONSTRUCTOR, - ChatEventVideoChatEnded.CONSTRUCTOR, - ChatEventVideoChatMuteNewParticipantsToggled.CONSTRUCTOR, - ChatEventVideoChatParticipantIsMutedToggled.CONSTRUCTOR, - ChatEventVideoChatParticipantVolumeLevelChanged.CONSTRUCTOR, - ChatEventIsForumToggled.CONSTRUCTOR, - ChatEventForumTopicCreated.CONSTRUCTOR, - ChatEventForumTopicEdited.CONSTRUCTOR, - ChatEventForumTopicToggleIsClosed.CONSTRUCTOR, - ChatEventForumTopicToggleIsHidden.CONSTRUCTOR, - ChatEventForumTopicDeleted.CONSTRUCTOR, - ChatEventForumTopicPinned.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ChatEventAction() { - } - } - - /** - * A message was edited. - */ - public static class ChatEventMessageEdited extends ChatEventAction { - /** - * The original message before the edit. - */ - public Message oldMessage; - /** - * The message after it was edited. - */ - public Message newMessage; - - /** - * A message was edited. - */ - public ChatEventMessageEdited() { - } - - /** - * A message was edited. - * - * @param oldMessage The original message before the edit. - * @param newMessage The message after it was edited. - */ - public ChatEventMessageEdited(Message oldMessage, Message newMessage) { - this.oldMessage = oldMessage; - this.newMessage = newMessage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -430967304; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message was deleted. - */ - public static class ChatEventMessageDeleted extends ChatEventAction { - /** - * Deleted message. - */ - public Message message; - /** - * True, if the message deletion can be reported via reportSupergroupAntiSpamFalsePositive. - */ - public boolean canReportAntiSpamFalsePositive; - - /** - * A message was deleted. - */ - public ChatEventMessageDeleted() { - } - - /** - * A message was deleted. - * - * @param message Deleted message. - * @param canReportAntiSpamFalsePositive True, if the message deletion can be reported via reportSupergroupAntiSpamFalsePositive. - */ - public ChatEventMessageDeleted(Message message, boolean canReportAntiSpamFalsePositive) { - this.message = message; - this.canReportAntiSpamFalsePositive = canReportAntiSpamFalsePositive; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 935316851; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message was pinned. - */ - public static class ChatEventMessagePinned extends ChatEventAction { - /** - * Pinned message. - */ - public Message message; - - /** - * A message was pinned. - */ - public ChatEventMessagePinned() { - } - - /** - * A message was pinned. - * - * @param message Pinned message. - */ - public ChatEventMessagePinned(Message message) { - this.message = message; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 438742298; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message was unpinned. - */ - public static class ChatEventMessageUnpinned extends ChatEventAction { - /** - * Unpinned message. - */ - public Message message; - - /** - * A message was unpinned. - */ - public ChatEventMessageUnpinned() { - } - - /** - * A message was unpinned. - * - * @param message Unpinned message. - */ - public ChatEventMessageUnpinned(Message message) { - this.message = message; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -376161513; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A poll in a message was stopped. - */ - public static class ChatEventPollStopped extends ChatEventAction { - /** - * The message with the poll. - */ - public Message message; - - /** - * A poll in a message was stopped. - */ - public ChatEventPollStopped() { - } - - /** - * A poll in a message was stopped. - * - * @param message The message with the poll. - */ - public ChatEventPollStopped(Message message) { - this.message = message; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2009893861; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new member joined the chat. - */ - public static class ChatEventMemberJoined extends ChatEventAction { - - /** - * A new member joined the chat. - */ - public ChatEventMemberJoined() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -235468508; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new member joined the chat via an invite link. - */ - public static class ChatEventMemberJoinedByInviteLink extends ChatEventAction { - /** - * Invite link used to join the chat. - */ - public ChatInviteLink inviteLink; - /** - * True, if the user has joined the chat using an invite link for a chat folder. - */ - public boolean viaChatFolderInviteLink; - - /** - * A new member joined the chat via an invite link. - */ - public ChatEventMemberJoinedByInviteLink() { - } - - /** - * A new member joined the chat via an invite link. - * - * @param inviteLink Invite link used to join the chat. - * @param viaChatFolderInviteLink True, if the user has joined the chat using an invite link for a chat folder. - */ - public ChatEventMemberJoinedByInviteLink(ChatInviteLink inviteLink, boolean viaChatFolderInviteLink) { - this.inviteLink = inviteLink; - this.viaChatFolderInviteLink = viaChatFolderInviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1445536390; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new member was accepted to the chat by an administrator. - */ - public static class ChatEventMemberJoinedByRequest extends ChatEventAction { - /** - * User identifier of the chat administrator, approved user join request. - */ - public long approverUserId; - /** - * Invite link used to join the chat; may be null. - */ - @Nullable public ChatInviteLink inviteLink; - - /** - * A new member was accepted to the chat by an administrator. - */ - public ChatEventMemberJoinedByRequest() { - } - - /** - * A new member was accepted to the chat by an administrator. - * - * @param approverUserId User identifier of the chat administrator, approved user join request. - * @param inviteLink Invite link used to join the chat; may be null. - */ - public ChatEventMemberJoinedByRequest(long approverUserId, ChatInviteLink inviteLink) { - this.approverUserId = approverUserId; - this.inviteLink = inviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1647804865; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new chat member was invited. - */ - public static class ChatEventMemberInvited extends ChatEventAction { - /** - * New member user identifier. - */ - public long userId; - /** - * New member status. - */ - public ChatMemberStatus status; - - /** - * A new chat member was invited. - */ - public ChatEventMemberInvited() { - } - - /** - * A new chat member was invited. - * - * @param userId New member user identifier. - * @param status New member status. - */ - public ChatEventMemberInvited(long userId, ChatMemberStatus status) { - this.userId = userId; - this.status = status; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 953663433; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A member left the chat. - */ - public static class ChatEventMemberLeft extends ChatEventAction { - - /** - * A member left the chat. - */ - public ChatEventMemberLeft() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -948420593; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat member has gained/lost administrator status, or the list of their administrator privileges has changed. - */ - public static class ChatEventMemberPromoted extends ChatEventAction { - /** - * Affected chat member user identifier. - */ - public long userId; - /** - * Previous status of the chat member. - */ - public ChatMemberStatus oldStatus; - /** - * New status of the chat member. - */ - public ChatMemberStatus newStatus; - - /** - * A chat member has gained/lost administrator status, or the list of their administrator privileges has changed. - */ - public ChatEventMemberPromoted() { - } - - /** - * A chat member has gained/lost administrator status, or the list of their administrator privileges has changed. - * - * @param userId Affected chat member user identifier. - * @param oldStatus Previous status of the chat member. - * @param newStatus New status of the chat member. - */ - public ChatEventMemberPromoted(long userId, ChatMemberStatus oldStatus, ChatMemberStatus newStatus) { - this.userId = userId; - this.oldStatus = oldStatus; - this.newStatus = newStatus; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 525297761; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat member was restricted/unrestricted or banned/unbanned, or the list of their restrictions has changed. - */ - public static class ChatEventMemberRestricted extends ChatEventAction { - /** - * Affected chat member identifier. - */ - public MessageSender memberId; - /** - * Previous status of the chat member. - */ - public ChatMemberStatus oldStatus; - /** - * New status of the chat member. - */ - public ChatMemberStatus newStatus; - - /** - * A chat member was restricted/unrestricted or banned/unbanned, or the list of their restrictions has changed. - */ - public ChatEventMemberRestricted() { - } - - /** - * A chat member was restricted/unrestricted or banned/unbanned, or the list of their restrictions has changed. - * - * @param memberId Affected chat member identifier. - * @param oldStatus Previous status of the chat member. - * @param newStatus New status of the chat member. - */ - public ChatEventMemberRestricted(MessageSender memberId, ChatMemberStatus oldStatus, ChatMemberStatus newStatus) { - this.memberId = memberId; - this.oldStatus = oldStatus; - this.newStatus = newStatus; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1603608069; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat member tag has been changed. - */ - public static class ChatEventMemberTagChanged extends ChatEventAction { - /** - * Affected chat member user identifier. - */ - public long userId; - /** - * Previous tag of the chat member. - */ - public String oldTag; - /** - * New tag of the chat member. - */ - public String newTag; - - /** - * A chat member tag has been changed. - */ - public ChatEventMemberTagChanged() { - } - - /** - * A chat member tag has been changed. - * - * @param userId Affected chat member user identifier. - * @param oldTag Previous tag of the chat member. - * @param newTag New tag of the chat member. - */ - public ChatEventMemberTagChanged(long userId, String oldTag, String newTag) { - this.userId = userId; - this.oldTag = oldTag; - this.newTag = newTag; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 63814442; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat member extended their subscription to the chat. - */ - public static class ChatEventMemberSubscriptionExtended extends ChatEventAction { - /** - * Affected chat member user identifier. - */ - public long userId; - /** - * Previous status of the chat member. - */ - public ChatMemberStatus oldStatus; - /** - * New status of the chat member. - */ - public ChatMemberStatus newStatus; - - /** - * A chat member extended their subscription to the chat. - */ - public ChatEventMemberSubscriptionExtended() { - } - - /** - * A chat member extended their subscription to the chat. - * - * @param userId Affected chat member user identifier. - * @param oldStatus Previous status of the chat member. - * @param newStatus New status of the chat member. - */ - public ChatEventMemberSubscriptionExtended(long userId, ChatMemberStatus oldStatus, ChatMemberStatus newStatus) { - this.userId = userId; - this.oldStatus = oldStatus; - this.newStatus = newStatus; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1141198846; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat available reactions were changed. - */ - public static class ChatEventAvailableReactionsChanged extends ChatEventAction { - /** - * Previous chat available reactions. - */ - public ChatAvailableReactions oldAvailableReactions; - /** - * New chat available reactions. - */ - public ChatAvailableReactions newAvailableReactions; - - /** - * The chat available reactions were changed. - */ - public ChatEventAvailableReactionsChanged() { - } - - /** - * The chat available reactions were changed. - * - * @param oldAvailableReactions Previous chat available reactions. - * @param newAvailableReactions New chat available reactions. - */ - public ChatEventAvailableReactionsChanged(ChatAvailableReactions oldAvailableReactions, ChatAvailableReactions newAvailableReactions) { - this.oldAvailableReactions = oldAvailableReactions; - this.newAvailableReactions = newAvailableReactions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1749491521; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat background was changed. - */ - public static class ChatEventBackgroundChanged extends ChatEventAction { - /** - * Previous background; may be null if none. - */ - @Nullable public ChatBackground oldBackground; - /** - * New background; may be null if none. - */ - @Nullable public ChatBackground newBackground; - - /** - * The chat background was changed. - */ - public ChatEventBackgroundChanged() { - } - - /** - * The chat background was changed. - * - * @param oldBackground Previous background; may be null if none. - * @param newBackground New background; may be null if none. - */ - public ChatEventBackgroundChanged(ChatBackground oldBackground, ChatBackground newBackground) { - this.oldBackground = oldBackground; - this.newBackground = newBackground; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1225953992; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat description was changed. - */ - public static class ChatEventDescriptionChanged extends ChatEventAction { - /** - * Previous chat description. - */ - public String oldDescription; - /** - * New chat description. - */ - public String newDescription; - - /** - * The chat description was changed. - */ - public ChatEventDescriptionChanged() { - } - - /** - * The chat description was changed. - * - * @param oldDescription Previous chat description. - * @param newDescription New chat description. - */ - public ChatEventDescriptionChanged(String oldDescription, String newDescription) { - this.oldDescription = oldDescription; - this.newDescription = newDescription; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 39112478; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat emoji status was changed. - */ - public static class ChatEventEmojiStatusChanged extends ChatEventAction { - /** - * Previous emoji status; may be null if none. - */ - @Nullable public EmojiStatus oldEmojiStatus; - /** - * New emoji status; may be null if none. - */ - @Nullable public EmojiStatus newEmojiStatus; - - /** - * The chat emoji status was changed. - */ - public ChatEventEmojiStatusChanged() { - } - - /** - * The chat emoji status was changed. - * - * @param oldEmojiStatus Previous emoji status; may be null if none. - * @param newEmojiStatus New emoji status; may be null if none. - */ - public ChatEventEmojiStatusChanged(EmojiStatus oldEmojiStatus, EmojiStatus newEmojiStatus) { - this.oldEmojiStatus = oldEmojiStatus; - this.newEmojiStatus = newEmojiStatus; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2081850594; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The linked chat of a supergroup was changed. - */ - public static class ChatEventLinkedChatChanged extends ChatEventAction { - /** - * Previous supergroup linked chat identifier. - */ - public long oldLinkedChatId; - /** - * New supergroup linked chat identifier. - */ - public long newLinkedChatId; - - /** - * The linked chat of a supergroup was changed. - */ - public ChatEventLinkedChatChanged() { - } - - /** - * The linked chat of a supergroup was changed. - * - * @param oldLinkedChatId Previous supergroup linked chat identifier. - * @param newLinkedChatId New supergroup linked chat identifier. - */ - public ChatEventLinkedChatChanged(long oldLinkedChatId, long newLinkedChatId) { - this.oldLinkedChatId = oldLinkedChatId; - this.newLinkedChatId = newLinkedChatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1797419439; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The supergroup location was changed. - */ - public static class ChatEventLocationChanged extends ChatEventAction { - /** - * Previous location; may be null. - */ - @Nullable public ChatLocation oldLocation; - /** - * New location; may be null. - */ - @Nullable public ChatLocation newLocation; - - /** - * The supergroup location was changed. - */ - public ChatEventLocationChanged() { - } - - /** - * The supergroup location was changed. - * - * @param oldLocation Previous location; may be null. - * @param newLocation New location; may be null. - */ - public ChatEventLocationChanged(ChatLocation oldLocation, ChatLocation newLocation) { - this.oldLocation = oldLocation; - this.newLocation = newLocation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -405930674; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message auto-delete timer was changed. - */ - public static class ChatEventMessageAutoDeleteTimeChanged extends ChatEventAction { - /** - * Previous value of messageAutoDeleteTime. - */ - public int oldMessageAutoDeleteTime; - /** - * New value of messageAutoDeleteTime. - */ - public int newMessageAutoDeleteTime; - - /** - * The message auto-delete timer was changed. - */ - public ChatEventMessageAutoDeleteTimeChanged() { - } - - /** - * The message auto-delete timer was changed. - * - * @param oldMessageAutoDeleteTime Previous value of messageAutoDeleteTime. - * @param newMessageAutoDeleteTime New value of messageAutoDeleteTime. - */ - public ChatEventMessageAutoDeleteTimeChanged(int oldMessageAutoDeleteTime, int newMessageAutoDeleteTime) { - this.oldMessageAutoDeleteTime = oldMessageAutoDeleteTime; - this.newMessageAutoDeleteTime = newMessageAutoDeleteTime; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 17317668; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat permissions were changed. - */ - public static class ChatEventPermissionsChanged extends ChatEventAction { - /** - * Previous chat permissions. - */ - public ChatPermissions oldPermissions; - /** - * New chat permissions. - */ - public ChatPermissions newPermissions; - - /** - * The chat permissions were changed. - */ - public ChatEventPermissionsChanged() { - } - - /** - * The chat permissions were changed. - * - * @param oldPermissions Previous chat permissions. - * @param newPermissions New chat permissions. - */ - public ChatEventPermissionsChanged(ChatPermissions oldPermissions, ChatPermissions newPermissions) { - this.oldPermissions = oldPermissions; - this.newPermissions = newPermissions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1311557720; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat photo was changed. - */ - public static class ChatEventPhotoChanged extends ChatEventAction { - /** - * Previous chat photo value; may be null. - */ - @Nullable public ChatPhoto oldPhoto; - /** - * New chat photo value; may be null. - */ - @Nullable public ChatPhoto newPhoto; - - /** - * The chat photo was changed. - */ - public ChatEventPhotoChanged() { - } - - /** - * The chat photo was changed. - * - * @param oldPhoto Previous chat photo value; may be null. - * @param newPhoto New chat photo value; may be null. - */ - public ChatEventPhotoChanged(ChatPhoto oldPhoto, ChatPhoto newPhoto) { - this.oldPhoto = oldPhoto; - this.newPhoto = newPhoto; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -811572541; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The slowModeDelay setting of a supergroup was changed. - */ - public static class ChatEventSlowModeDelayChanged extends ChatEventAction { - /** - * Previous value of slowModeDelay, in seconds. - */ - public int oldSlowModeDelay; - /** - * New value of slowModeDelay, in seconds. - */ - public int newSlowModeDelay; - - /** - * The slowModeDelay setting of a supergroup was changed. - */ - public ChatEventSlowModeDelayChanged() { - } - - /** - * The slowModeDelay setting of a supergroup was changed. - * - * @param oldSlowModeDelay Previous value of slowModeDelay, in seconds. - * @param newSlowModeDelay New value of slowModeDelay, in seconds. - */ - public ChatEventSlowModeDelayChanged(int oldSlowModeDelay, int newSlowModeDelay) { - this.oldSlowModeDelay = oldSlowModeDelay; - this.newSlowModeDelay = newSlowModeDelay; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1653195765; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The supergroup sticker set was changed. - */ - public static class ChatEventStickerSetChanged extends ChatEventAction { - /** - * Previous identifier of the chat sticker set; 0 if none. - */ - public long oldStickerSetId; - /** - * New identifier of the chat sticker set; 0 if none. - */ - public long newStickerSetId; - - /** - * The supergroup sticker set was changed. - */ - public ChatEventStickerSetChanged() { - } - - /** - * The supergroup sticker set was changed. - * - * @param oldStickerSetId Previous identifier of the chat sticker set; 0 if none. - * @param newStickerSetId New identifier of the chat sticker set; 0 if none. - */ - public ChatEventStickerSetChanged(long oldStickerSetId, long newStickerSetId) { - this.oldStickerSetId = oldStickerSetId; - this.newStickerSetId = newStickerSetId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1243130481; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The supergroup sticker set with allowed custom emoji was changed. - */ - public static class ChatEventCustomEmojiStickerSetChanged extends ChatEventAction { - /** - * Previous identifier of the chat sticker set; 0 if none. - */ - public long oldStickerSetId; - /** - * New identifier of the chat sticker set; 0 if none. - */ - public long newStickerSetId; - - /** - * The supergroup sticker set with allowed custom emoji was changed. - */ - public ChatEventCustomEmojiStickerSetChanged() { - } - - /** - * The supergroup sticker set with allowed custom emoji was changed. - * - * @param oldStickerSetId Previous identifier of the chat sticker set; 0 if none. - * @param newStickerSetId New identifier of the chat sticker set; 0 if none. - */ - public ChatEventCustomEmojiStickerSetChanged(long oldStickerSetId, long newStickerSetId) { - this.oldStickerSetId = oldStickerSetId; - this.newStickerSetId = newStickerSetId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 118244123; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat title was changed. - */ - public static class ChatEventTitleChanged extends ChatEventAction { - /** - * Previous chat title. - */ - public String oldTitle; - /** - * New chat title. - */ - public String newTitle; - - /** - * The chat title was changed. - */ - public ChatEventTitleChanged() { - } - - /** - * The chat title was changed. - * - * @param oldTitle Previous chat title. - * @param newTitle New chat title. - */ - public ChatEventTitleChanged(String oldTitle, String newTitle) { - this.oldTitle = oldTitle; - this.newTitle = newTitle; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1134103250; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat editable username was changed. - */ - public static class ChatEventUsernameChanged extends ChatEventAction { - /** - * Previous chat username. - */ - public String oldUsername; - /** - * New chat username. - */ - public String newUsername; - - /** - * The chat editable username was changed. - */ - public ChatEventUsernameChanged() { - } - - /** - * The chat editable username was changed. - * - * @param oldUsername Previous chat username. - * @param newUsername New chat username. - */ - public ChatEventUsernameChanged(String oldUsername, String newUsername) { - this.oldUsername = oldUsername; - this.newUsername = newUsername; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1728558443; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat active usernames were changed. - */ - public static class ChatEventActiveUsernamesChanged extends ChatEventAction { - /** - * Previous list of active usernames. - */ - public String[] oldUsernames; - /** - * New list of active usernames. - */ - public String[] newUsernames; - - /** - * The chat active usernames were changed. - */ - public ChatEventActiveUsernamesChanged() { - } - - /** - * The chat active usernames were changed. - * - * @param oldUsernames Previous list of active usernames. - * @param newUsernames New list of active usernames. - */ - public ChatEventActiveUsernamesChanged(String[] oldUsernames, String[] newUsernames) { - this.oldUsernames = oldUsernames; - this.newUsernames = newUsernames; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1508790810; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat accent color or background custom emoji were changed. - */ - public static class ChatEventAccentColorChanged extends ChatEventAction { - /** - * Previous identifier of chat accent color. - */ - public int oldAccentColorId; - /** - * Previous identifier of the custom emoji; 0 if none. - */ - public long oldBackgroundCustomEmojiId; - /** - * New identifier of chat accent color. - */ - public int newAccentColorId; - /** - * New identifier of the custom emoji; 0 if none. - */ - public long newBackgroundCustomEmojiId; - - /** - * The chat accent color or background custom emoji were changed. - */ - public ChatEventAccentColorChanged() { - } - - /** - * The chat accent color or background custom emoji were changed. - * - * @param oldAccentColorId Previous identifier of chat accent color. - * @param oldBackgroundCustomEmojiId Previous identifier of the custom emoji; 0 if none. - * @param newAccentColorId New identifier of chat accent color. - * @param newBackgroundCustomEmojiId New identifier of the custom emoji; 0 if none. - */ - public ChatEventAccentColorChanged(int oldAccentColorId, long oldBackgroundCustomEmojiId, int newAccentColorId, long newBackgroundCustomEmojiId) { - this.oldAccentColorId = oldAccentColorId; - this.oldBackgroundCustomEmojiId = oldBackgroundCustomEmojiId; - this.newAccentColorId = newAccentColorId; - this.newBackgroundCustomEmojiId = newBackgroundCustomEmojiId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -427591885; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat's profile accent color or profile background custom emoji were changed. - */ - public static class ChatEventProfileAccentColorChanged extends ChatEventAction { - /** - * Previous identifier of chat's profile accent color; -1 if none. - */ - public int oldProfileAccentColorId; - /** - * Previous identifier of the custom emoji; 0 if none. - */ - public long oldProfileBackgroundCustomEmojiId; - /** - * New identifier of chat's profile accent color; -1 if none. - */ - public int newProfileAccentColorId; - /** - * New identifier of the custom emoji; 0 if none. - */ - public long newProfileBackgroundCustomEmojiId; - - /** - * The chat's profile accent color or profile background custom emoji were changed. - */ - public ChatEventProfileAccentColorChanged() { - } - - /** - * The chat's profile accent color or profile background custom emoji were changed. - * - * @param oldProfileAccentColorId Previous identifier of chat's profile accent color; -1 if none. - * @param oldProfileBackgroundCustomEmojiId Previous identifier of the custom emoji; 0 if none. - * @param newProfileAccentColorId New identifier of chat's profile accent color; -1 if none. - * @param newProfileBackgroundCustomEmojiId New identifier of the custom emoji; 0 if none. - */ - public ChatEventProfileAccentColorChanged(int oldProfileAccentColorId, long oldProfileBackgroundCustomEmojiId, int newProfileAccentColorId, long newProfileBackgroundCustomEmojiId) { - this.oldProfileAccentColorId = oldProfileAccentColorId; - this.oldProfileBackgroundCustomEmojiId = oldProfileBackgroundCustomEmojiId; - this.newProfileAccentColorId = newProfileAccentColorId; - this.newProfileBackgroundCustomEmojiId = newProfileBackgroundCustomEmojiId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1514612124; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The hasProtectedContent setting of a channel was toggled. - */ - public static class ChatEventHasProtectedContentToggled extends ChatEventAction { - /** - * New value of hasProtectedContent. - */ - public boolean hasProtectedContent; - - /** - * The hasProtectedContent setting of a channel was toggled. - */ - public ChatEventHasProtectedContentToggled() { - } - - /** - * The hasProtectedContent setting of a channel was toggled. - * - * @param hasProtectedContent New value of hasProtectedContent. - */ - public ChatEventHasProtectedContentToggled(boolean hasProtectedContent) { - this.hasProtectedContent = hasProtectedContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -184270335; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The canInviteUsers permission of a supergroup chat was toggled. - */ - public static class ChatEventInvitesToggled extends ChatEventAction { - /** - * New value of canInviteUsers permission. - */ - public boolean canInviteUsers; - - /** - * The canInviteUsers permission of a supergroup chat was toggled. - */ - public ChatEventInvitesToggled() { - } - - /** - * The canInviteUsers permission of a supergroup chat was toggled. - * - * @param canInviteUsers New value of canInviteUsers permission. - */ - public ChatEventInvitesToggled(boolean canInviteUsers) { - this.canInviteUsers = canInviteUsers; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -62548373; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The isAllHistoryAvailable setting of a supergroup was toggled. - */ - public static class ChatEventIsAllHistoryAvailableToggled extends ChatEventAction { - /** - * New value of isAllHistoryAvailable. - */ - public boolean isAllHistoryAvailable; - - /** - * The isAllHistoryAvailable setting of a supergroup was toggled. - */ - public ChatEventIsAllHistoryAvailableToggled() { - } - - /** - * The isAllHistoryAvailable setting of a supergroup was toggled. - * - * @param isAllHistoryAvailable New value of isAllHistoryAvailable. - */ - public ChatEventIsAllHistoryAvailableToggled(boolean isAllHistoryAvailable) { - this.isAllHistoryAvailable = isAllHistoryAvailable; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1599063019; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The hasAggressiveAntiSpamEnabled setting of a supergroup was toggled. - */ - public static class ChatEventHasAggressiveAntiSpamEnabledToggled extends ChatEventAction { - /** - * New value of hasAggressiveAntiSpamEnabled. - */ - public boolean hasAggressiveAntiSpamEnabled; - - /** - * The hasAggressiveAntiSpamEnabled setting of a supergroup was toggled. - */ - public ChatEventHasAggressiveAntiSpamEnabledToggled() { - } - - /** - * The hasAggressiveAntiSpamEnabled setting of a supergroup was toggled. - * - * @param hasAggressiveAntiSpamEnabled New value of hasAggressiveAntiSpamEnabled. - */ - public ChatEventHasAggressiveAntiSpamEnabledToggled(boolean hasAggressiveAntiSpamEnabled) { - this.hasAggressiveAntiSpamEnabled = hasAggressiveAntiSpamEnabled; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -125348094; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The signMessages setting of a channel was toggled. - */ - public static class ChatEventSignMessagesToggled extends ChatEventAction { - /** - * New value of signMessages. - */ - public boolean signMessages; - - /** - * The signMessages setting of a channel was toggled. - */ - public ChatEventSignMessagesToggled() { - } - - /** - * The signMessages setting of a channel was toggled. - * - * @param signMessages New value of signMessages. - */ - public ChatEventSignMessagesToggled(boolean signMessages) { - this.signMessages = signMessages; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1313265634; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The showMessageSender setting of a channel was toggled. - */ - public static class ChatEventShowMessageSenderToggled extends ChatEventAction { - /** - * New value of showMessageSender. - */ - public boolean showMessageSender; - - /** - * The showMessageSender setting of a channel was toggled. - */ - public ChatEventShowMessageSenderToggled() { - } - - /** - * The showMessageSender setting of a channel was toggled. - * - * @param showMessageSender New value of showMessageSender. - */ - public ChatEventShowMessageSenderToggled(boolean showMessageSender) { - this.showMessageSender = showMessageSender; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -794343453; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The hasAutomaticTranslation setting of a channel was toggled. - */ - public static class ChatEventAutomaticTranslationToggled extends ChatEventAction { - /** - * New value of hasAutomaticTranslation. - */ - public boolean hasAutomaticTranslation; - - /** - * The hasAutomaticTranslation setting of a channel was toggled. - */ - public ChatEventAutomaticTranslationToggled() { - } - - /** - * The hasAutomaticTranslation setting of a channel was toggled. - * - * @param hasAutomaticTranslation New value of hasAutomaticTranslation. - */ - public ChatEventAutomaticTranslationToggled(boolean hasAutomaticTranslation) { - this.hasAutomaticTranslation = hasAutomaticTranslation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 194147926; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat invite link was edited. - */ - public static class ChatEventInviteLinkEdited extends ChatEventAction { - /** - * Previous information about the invite link. - */ - public ChatInviteLink oldInviteLink; - /** - * New information about the invite link. - */ - public ChatInviteLink newInviteLink; - - /** - * A chat invite link was edited. - */ - public ChatEventInviteLinkEdited() { - } - - /** - * A chat invite link was edited. - * - * @param oldInviteLink Previous information about the invite link. - * @param newInviteLink New information about the invite link. - */ - public ChatEventInviteLinkEdited(ChatInviteLink oldInviteLink, ChatInviteLink newInviteLink) { - this.oldInviteLink = oldInviteLink; - this.newInviteLink = newInviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -460190366; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat invite link was revoked. - */ - public static class ChatEventInviteLinkRevoked extends ChatEventAction { - /** - * The invite link. - */ - public ChatInviteLink inviteLink; - - /** - * A chat invite link was revoked. - */ - public ChatEventInviteLinkRevoked() { - } - - /** - * A chat invite link was revoked. - * - * @param inviteLink The invite link. - */ - public ChatEventInviteLinkRevoked(ChatInviteLink inviteLink) { - this.inviteLink = inviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1579417629; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A revoked chat invite link was deleted. - */ - public static class ChatEventInviteLinkDeleted extends ChatEventAction { - /** - * The invite link. - */ - public ChatInviteLink inviteLink; - - /** - * A revoked chat invite link was deleted. - */ - public ChatEventInviteLinkDeleted() { - } - - /** - * A revoked chat invite link was deleted. - * - * @param inviteLink The invite link. - */ - public ChatEventInviteLinkDeleted(ChatInviteLink inviteLink) { - this.inviteLink = inviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1394974361; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A video chat was created. - */ - public static class ChatEventVideoChatCreated extends ChatEventAction { - /** - * Identifier of the video chat. The video chat can be received through the method getGroupCall. - */ - public int groupCallId; - - /** - * A video chat was created. - */ - public ChatEventVideoChatCreated() { - } - - /** - * A video chat was created. - * - * @param groupCallId Identifier of the video chat. The video chat can be received through the method getGroupCall. - */ - public ChatEventVideoChatCreated(int groupCallId) { - this.groupCallId = groupCallId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1822853755; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A video chat was ended. - */ - public static class ChatEventVideoChatEnded extends ChatEventAction { - /** - * Identifier of the video chat. The video chat can be received through the method getGroupCall. - */ - public int groupCallId; - - /** - * A video chat was ended. - */ - public ChatEventVideoChatEnded() { - } - - /** - * A video chat was ended. - * - * @param groupCallId Identifier of the video chat. The video chat can be received through the method getGroupCall. - */ - public ChatEventVideoChatEnded(int groupCallId) { - this.groupCallId = groupCallId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1630039112; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The muteNewParticipants setting of a video chat was toggled. - */ - public static class ChatEventVideoChatMuteNewParticipantsToggled extends ChatEventAction { - /** - * New value of the muteNewParticipants setting. - */ - public boolean muteNewParticipants; - - /** - * The muteNewParticipants setting of a video chat was toggled. - */ - public ChatEventVideoChatMuteNewParticipantsToggled() { - } - - /** - * The muteNewParticipants setting of a video chat was toggled. - * - * @param muteNewParticipants New value of the muteNewParticipants setting. - */ - public ChatEventVideoChatMuteNewParticipantsToggled(boolean muteNewParticipants) { - this.muteNewParticipants = muteNewParticipants; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -126547970; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A video chat participant was muted or unmuted. - */ - public static class ChatEventVideoChatParticipantIsMutedToggled extends ChatEventAction { - /** - * Identifier of the affected group call participant. - */ - public MessageSender participantId; - /** - * New value of isMuted. - */ - public boolean isMuted; - - /** - * A video chat participant was muted or unmuted. - */ - public ChatEventVideoChatParticipantIsMutedToggled() { - } - - /** - * A video chat participant was muted or unmuted. - * - * @param participantId Identifier of the affected group call participant. - * @param isMuted New value of isMuted. - */ - public ChatEventVideoChatParticipantIsMutedToggled(MessageSender participantId, boolean isMuted) { - this.participantId = participantId; - this.isMuted = isMuted; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 521165047; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A video chat participant volume level was changed. - */ - public static class ChatEventVideoChatParticipantVolumeLevelChanged extends ChatEventAction { - /** - * Identifier of the affected group call participant. - */ - public MessageSender participantId; - /** - * New value of volumeLevel; 1-20000 in hundreds of percents. - */ - public int volumeLevel; - - /** - * A video chat participant volume level was changed. - */ - public ChatEventVideoChatParticipantVolumeLevelChanged() { - } - - /** - * A video chat participant volume level was changed. - * - * @param participantId Identifier of the affected group call participant. - * @param volumeLevel New value of volumeLevel; 1-20000 in hundreds of percents. - */ - public ChatEventVideoChatParticipantVolumeLevelChanged(MessageSender participantId, int volumeLevel) { - this.participantId = participantId; - this.volumeLevel = volumeLevel; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1131385534; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The isForum setting of a channel was toggled. - */ - public static class ChatEventIsForumToggled extends ChatEventAction { - /** - * New value of isForum. - */ - public boolean isForum; - - /** - * The isForum setting of a channel was toggled. - */ - public ChatEventIsForumToggled() { - } - - /** - * The isForum setting of a channel was toggled. - * - * @param isForum New value of isForum. - */ - public ChatEventIsForumToggled(boolean isForum) { - this.isForum = isForum; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1516491033; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new forum topic was created. - */ - public static class ChatEventForumTopicCreated extends ChatEventAction { - /** - * Information about the topic. - */ - public ForumTopicInfo topicInfo; - - /** - * A new forum topic was created. - */ - public ChatEventForumTopicCreated() { - } - - /** - * A new forum topic was created. - * - * @param topicInfo Information about the topic. - */ - public ChatEventForumTopicCreated(ForumTopicInfo topicInfo) { - this.topicInfo = topicInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2005269314; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A forum topic was edited. - */ - public static class ChatEventForumTopicEdited extends ChatEventAction { - /** - * Old information about the topic. - */ - public ForumTopicInfo oldTopicInfo; - /** - * New information about the topic. - */ - public ForumTopicInfo newTopicInfo; - - /** - * A forum topic was edited. - */ - public ChatEventForumTopicEdited() { - } - - /** - * A forum topic was edited. - * - * @param oldTopicInfo Old information about the topic. - * @param newTopicInfo New information about the topic. - */ - public ChatEventForumTopicEdited(ForumTopicInfo oldTopicInfo, ForumTopicInfo newTopicInfo) { - this.oldTopicInfo = oldTopicInfo; - this.newTopicInfo = newTopicInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1624910860; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A forum topic was closed or reopened. - */ - public static class ChatEventForumTopicToggleIsClosed extends ChatEventAction { - /** - * New information about the topic. - */ - public ForumTopicInfo topicInfo; - - /** - * A forum topic was closed or reopened. - */ - public ChatEventForumTopicToggleIsClosed() { - } - - /** - * A forum topic was closed or reopened. - * - * @param topicInfo New information about the topic. - */ - public ChatEventForumTopicToggleIsClosed(ForumTopicInfo topicInfo) { - this.topicInfo = topicInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -962704070; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The General forum topic was hidden or unhidden. - */ - public static class ChatEventForumTopicToggleIsHidden extends ChatEventAction { - /** - * New information about the topic. - */ - public ForumTopicInfo topicInfo; - - /** - * The General forum topic was hidden or unhidden. - */ - public ChatEventForumTopicToggleIsHidden() { - } - - /** - * The General forum topic was hidden or unhidden. - * - * @param topicInfo New information about the topic. - */ - public ChatEventForumTopicToggleIsHidden(ForumTopicInfo topicInfo) { - this.topicInfo = topicInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1609175250; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A forum topic was deleted. - */ - public static class ChatEventForumTopicDeleted extends ChatEventAction { - /** - * Information about the topic. - */ - public ForumTopicInfo topicInfo; - - /** - * A forum topic was deleted. - */ - public ChatEventForumTopicDeleted() { - } - - /** - * A forum topic was deleted. - * - * @param topicInfo Information about the topic. - */ - public ChatEventForumTopicDeleted(ForumTopicInfo topicInfo) { - this.topicInfo = topicInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1332795123; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A pinned forum topic was changed. - */ - public static class ChatEventForumTopicPinned extends ChatEventAction { - /** - * Information about the old pinned topic; may be null. - */ - @Nullable public ForumTopicInfo oldTopicInfo; - /** - * Information about the new pinned topic; may be null. - */ - @Nullable public ForumTopicInfo newTopicInfo; - - /** - * A pinned forum topic was changed. - */ - public ChatEventForumTopicPinned() { - } - - /** - * A pinned forum topic was changed. - * - * @param oldTopicInfo Information about the old pinned topic; may be null. - * @param newTopicInfo Information about the new pinned topic; may be null. - */ - public ChatEventForumTopicPinned(ForumTopicInfo oldTopicInfo, ForumTopicInfo newTopicInfo) { - this.oldTopicInfo = oldTopicInfo; - this.newTopicInfo = newTopicInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2143626222; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a set of filters used to obtain a chat event log. - */ - public static class ChatEventLogFilters extends Object { - /** - * True, if message edits need to be returned. - */ - public boolean messageEdits; - /** - * True, if message deletions need to be returned. - */ - public boolean messageDeletions; - /** - * True, if pin/unpin events need to be returned. - */ - public boolean messagePins; - /** - * True, if members joining events need to be returned. - */ - public boolean memberJoins; - /** - * True, if members leaving events need to be returned. - */ - public boolean memberLeaves; - /** - * True, if invited member events need to be returned. - */ - public boolean memberInvites; - /** - * True, if member promotion/demotion events need to be returned. - */ - public boolean memberPromotions; - /** - * True, if member restricted/unrestricted/banned/unbanned events need to be returned. - */ - public boolean memberRestrictions; - /** - * True, if member tag and custom title change events need to be returned. - */ - public boolean memberTagChanges; - /** - * True, if changes in chat information need to be returned. - */ - public boolean infoChanges; - /** - * True, if changes in chat settings need to be returned. - */ - public boolean settingChanges; - /** - * True, if changes to invite links need to be returned. - */ - public boolean inviteLinkChanges; - /** - * True, if video chat actions need to be returned. - */ - public boolean videoChatChanges; - /** - * True, if forum-related actions need to be returned. - */ - public boolean forumChanges; - /** - * True, if subscription extensions need to be returned. - */ - public boolean subscriptionExtensions; - - /** - * Represents a set of filters used to obtain a chat event log. - */ - public ChatEventLogFilters() { - } - - /** - * Represents a set of filters used to obtain a chat event log. - * - * @param messageEdits True, if message edits need to be returned. - * @param messageDeletions True, if message deletions need to be returned. - * @param messagePins True, if pin/unpin events need to be returned. - * @param memberJoins True, if members joining events need to be returned. - * @param memberLeaves True, if members leaving events need to be returned. - * @param memberInvites True, if invited member events need to be returned. - * @param memberPromotions True, if member promotion/demotion events need to be returned. - * @param memberRestrictions True, if member restricted/unrestricted/banned/unbanned events need to be returned. - * @param memberTagChanges True, if member tag and custom title change events need to be returned. - * @param infoChanges True, if changes in chat information need to be returned. - * @param settingChanges True, if changes in chat settings need to be returned. - * @param inviteLinkChanges True, if changes to invite links need to be returned. - * @param videoChatChanges True, if video chat actions need to be returned. - * @param forumChanges True, if forum-related actions need to be returned. - * @param subscriptionExtensions True, if subscription extensions need to be returned. - */ - public ChatEventLogFilters(boolean messageEdits, boolean messageDeletions, boolean messagePins, boolean memberJoins, boolean memberLeaves, boolean memberInvites, boolean memberPromotions, boolean memberRestrictions, boolean memberTagChanges, boolean infoChanges, boolean settingChanges, boolean inviteLinkChanges, boolean videoChatChanges, boolean forumChanges, boolean subscriptionExtensions) { - this.messageEdits = messageEdits; - this.messageDeletions = messageDeletions; - this.messagePins = messagePins; - this.memberJoins = memberJoins; - this.memberLeaves = memberLeaves; - this.memberInvites = memberInvites; - this.memberPromotions = memberPromotions; - this.memberRestrictions = memberRestrictions; - this.memberTagChanges = memberTagChanges; - this.infoChanges = infoChanges; - this.settingChanges = settingChanges; - this.inviteLinkChanges = inviteLinkChanges; - this.videoChatChanges = videoChatChanges; - this.forumChanges = forumChanges; - this.subscriptionExtensions = subscriptionExtensions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1572752816; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of chat events. - */ - public static class ChatEvents extends Object { - /** - * List of events. - */ - public ChatEvent[] events; - - /** - * Contains a list of chat events. - */ - public ChatEvents() { - } - - /** - * Contains a list of chat events. - * - * @param events List of events. - */ - public ChatEvents(ChatEvent[] events) { - this.events = events; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -585329664; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a folder for user chats. - */ - public static class ChatFolder extends Object { - /** - * The name of the folder. - */ - public ChatFolderName name; - /** - * The chosen icon for the chat folder; may be null. If null, use getChatFolderDefaultIconName to get default icon name for the folder. - */ - @Nullable public ChatFolderIcon icon; - /** - * The identifier of the chosen color for the chat folder icon; from -1 to 6. If -1, then color is disabled. Can't be changed if folder tags are disabled or the current user doesn't have Telegram Premium subscription. - */ - public int colorId; - /** - * True, if at least one link has been created for the folder. - */ - public boolean isShareable; - /** - * The chat identifiers of pinned chats in the folder. There can be up to getOption("chat_folder_chosen_chat_count_max") pinned and always included non-secret chats and the same number of secret chats, but the limit can be increased with Telegram Premium. - */ - public long[] pinnedChatIds; - /** - * The chat identifiers of always included chats in the folder. There can be up to getOption("chat_folder_chosen_chat_count_max") pinned and always included non-secret chats and the same number of secret chats, but the limit can be increased with Telegram Premium. - */ - public long[] includedChatIds; - /** - * The chat identifiers of always excluded chats in the folder. There can be up to getOption("chat_folder_chosen_chat_count_max") always excluded non-secret chats and the same number of secret chats, but the limit can be increased with Telegram Premium. - */ - public long[] excludedChatIds; - /** - * True, if muted chats need to be excluded. - */ - public boolean excludeMuted; - /** - * True, if read chats need to be excluded. - */ - public boolean excludeRead; - /** - * True, if archived chats need to be excluded. - */ - public boolean excludeArchived; - /** - * True, if contacts need to be included. - */ - public boolean includeContacts; - /** - * True, if non-contact users need to be included. - */ - public boolean includeNonContacts; - /** - * True, if bots need to be included. - */ - public boolean includeBots; - /** - * True, if basic groups and supergroups need to be included. - */ - public boolean includeGroups; - /** - * True, if channels need to be included. - */ - public boolean includeChannels; - - /** - * Represents a folder for user chats. - */ - public ChatFolder() { - } - - /** - * Represents a folder for user chats. - * - * @param name The name of the folder. - * @param icon The chosen icon for the chat folder; may be null. If null, use getChatFolderDefaultIconName to get default icon name for the folder. - * @param colorId The identifier of the chosen color for the chat folder icon; from -1 to 6. If -1, then color is disabled. Can't be changed if folder tags are disabled or the current user doesn't have Telegram Premium subscription. - * @param isShareable True, if at least one link has been created for the folder. - * @param pinnedChatIds The chat identifiers of pinned chats in the folder. There can be up to getOption("chat_folder_chosen_chat_count_max") pinned and always included non-secret chats and the same number of secret chats, but the limit can be increased with Telegram Premium. - * @param includedChatIds The chat identifiers of always included chats in the folder. There can be up to getOption("chat_folder_chosen_chat_count_max") pinned and always included non-secret chats and the same number of secret chats, but the limit can be increased with Telegram Premium. - * @param excludedChatIds The chat identifiers of always excluded chats in the folder. There can be up to getOption("chat_folder_chosen_chat_count_max") always excluded non-secret chats and the same number of secret chats, but the limit can be increased with Telegram Premium. - * @param excludeMuted True, if muted chats need to be excluded. - * @param excludeRead True, if read chats need to be excluded. - * @param excludeArchived True, if archived chats need to be excluded. - * @param includeContacts True, if contacts need to be included. - * @param includeNonContacts True, if non-contact users need to be included. - * @param includeBots True, if bots need to be included. - * @param includeGroups True, if basic groups and supergroups need to be included. - * @param includeChannels True, if channels need to be included. - */ - public ChatFolder(ChatFolderName name, ChatFolderIcon icon, int colorId, boolean isShareable, long[] pinnedChatIds, long[] includedChatIds, long[] excludedChatIds, boolean excludeMuted, boolean excludeRead, boolean excludeArchived, boolean includeContacts, boolean includeNonContacts, boolean includeBots, boolean includeGroups, boolean includeChannels) { - this.name = name; - this.icon = icon; - this.colorId = colorId; - this.isShareable = isShareable; - this.pinnedChatIds = pinnedChatIds; - this.includedChatIds = includedChatIds; - this.excludedChatIds = excludedChatIds; - this.excludeMuted = excludeMuted; - this.excludeRead = excludeRead; - this.excludeArchived = excludeArchived; - this.includeContacts = includeContacts; - this.includeNonContacts = includeNonContacts; - this.includeBots = includeBots; - this.includeGroups = includeGroups; - this.includeChannels = includeChannels; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1596164696; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents an icon for a chat folder. - */ - public static class ChatFolderIcon extends Object { - /** - * The chosen icon name for short folder representation; one of "All", "Unread", "Unmuted", "Bots", "Channels", "Groups", "Private", "Custom", "Setup", "Cat", "Crown", "Favorite", "Flower", "Game", "Home", "Love", "Mask", "Party", "Sport", "Study", "Trade", "Travel", "Work", "Airplane", "Book", "Light", "Like", "Money", "Note", "Palette". - */ - public String name; - - /** - * Represents an icon for a chat folder. - */ - public ChatFolderIcon() { - } - - /** - * Represents an icon for a chat folder. - * - * @param name The chosen icon name for short folder representation; one of "All", "Unread", "Unmuted", "Bots", "Channels", "Groups", "Private", "Custom", "Setup", "Cat", "Crown", "Favorite", "Flower", "Game", "Home", "Love", "Mask", "Party", "Sport", "Study", "Trade", "Travel", "Work", "Airplane", "Book", "Light", "Like", "Money", "Note", "Palette". - */ - public ChatFolderIcon(String name) { - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -146104090; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains basic information about a chat folder. - */ - public static class ChatFolderInfo extends Object { - /** - * Unique chat folder identifier. - */ - public int id; - /** - * The name of the folder. - */ - public ChatFolderName name; - /** - * The chosen or default icon for the chat folder. - */ - public ChatFolderIcon icon; - /** - * The identifier of the chosen color for the chat folder icon; from -1 to 6. If -1, then color is disabled. - */ - public int colorId; - /** - * True, if at least one link has been created for the folder. - */ - public boolean isShareable; - /** - * True, if the chat folder has invite links created by the current user. - */ - public boolean hasMyInviteLinks; - - /** - * Contains basic information about a chat folder. - */ - public ChatFolderInfo() { - } - - /** - * Contains basic information about a chat folder. - * - * @param id Unique chat folder identifier. - * @param name The name of the folder. - * @param icon The chosen or default icon for the chat folder. - * @param colorId The identifier of the chosen color for the chat folder icon; from -1 to 6. If -1, then color is disabled. - * @param isShareable True, if at least one link has been created for the folder. - * @param hasMyInviteLinks True, if the chat folder has invite links created by the current user. - */ - public ChatFolderInfo(int id, ChatFolderName name, ChatFolderIcon icon, int colorId, boolean isShareable, boolean hasMyInviteLinks) { - this.id = id; - this.name = name; - this.icon = icon; - this.colorId = colorId; - this.isShareable = isShareable; - this.hasMyInviteLinks = hasMyInviteLinks; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 815535117; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a chat folder invite link. - */ - public static class ChatFolderInviteLink extends Object { - /** - * The chat folder invite link. - */ - public String inviteLink; - /** - * Name of the link. - */ - public String name; - /** - * Identifiers of chats, included in the link. - */ - public long[] chatIds; - - /** - * Contains a chat folder invite link. - */ - public ChatFolderInviteLink() { - } - - /** - * Contains a chat folder invite link. - * - * @param inviteLink The chat folder invite link. - * @param name Name of the link. - * @param chatIds Identifiers of chats, included in the link. - */ - public ChatFolderInviteLink(String inviteLink, String name, long[] chatIds) { - this.inviteLink = inviteLink; - this.name = name; - this.chatIds = chatIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 493969661; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about an invite link to a chat folder. - */ - public static class ChatFolderInviteLinkInfo extends Object { - /** - * Basic information about the chat folder; chat folder identifier will be 0 if the user didn't have the chat folder yet. - */ - public ChatFolderInfo chatFolderInfo; - /** - * Identifiers of the chats from the link, which aren't added to the folder yet. - */ - public long[] missingChatIds; - /** - * Identifiers of the chats from the link, which are added to the folder already. - */ - public long[] addedChatIds; - - /** - * Contains information about an invite link to a chat folder. - */ - public ChatFolderInviteLinkInfo() { - } - - /** - * Contains information about an invite link to a chat folder. - * - * @param chatFolderInfo Basic information about the chat folder; chat folder identifier will be 0 if the user didn't have the chat folder yet. - * @param missingChatIds Identifiers of the chats from the link, which aren't added to the folder yet. - * @param addedChatIds Identifiers of the chats from the link, which are added to the folder already. - */ - public ChatFolderInviteLinkInfo(ChatFolderInfo chatFolderInfo, long[] missingChatIds, long[] addedChatIds) { - this.chatFolderInfo = chatFolderInfo; - this.missingChatIds = missingChatIds; - this.addedChatIds = addedChatIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1119450395; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of chat folder invite links. - */ - public static class ChatFolderInviteLinks extends Object { - /** - * List of the invite links. - */ - public ChatFolderInviteLink[] inviteLinks; - - /** - * Represents a list of chat folder invite links. - */ - public ChatFolderInviteLinks() { - } - - /** - * Represents a list of chat folder invite links. - * - * @param inviteLinks List of the invite links. - */ - public ChatFolderInviteLinks(ChatFolderInviteLink[] inviteLinks) { - this.inviteLinks = inviteLinks; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1853351525; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes name of a chat folder. - */ - public static class ChatFolderName extends Object { - /** - * The text of the chat folder name; 1-12 characters without line feeds. May contain only CustomEmoji entities. - */ - public FormattedText text; - /** - * True, if custom emoji in the name must be animated. - */ - public boolean animateCustomEmoji; - - /** - * Describes name of a chat folder. - */ - public ChatFolderName() { - } - - /** - * Describes name of a chat folder. - * - * @param text The text of the chat folder name; 1-12 characters without line feeds. May contain only CustomEmoji entities. - * @param animateCustomEmoji True, if custom emoji in the name must be animated. - */ - public ChatFolderName(FormattedText text, boolean animateCustomEmoji) { - this.text = text; - this.animateCustomEmoji = animateCustomEmoji; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -330482274; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a chat invite link. - */ - public static class ChatInviteLink extends Object { - /** - * Chat invite link. - */ - public String inviteLink; - /** - * Name of the link. - */ - public String name; - /** - * User identifier of an administrator created the link. - */ - public long creatorUserId; - /** - * Point in time (Unix timestamp) when the link was created. - */ - public int date; - /** - * Point in time (Unix timestamp) when the link was last edited; 0 if never or unknown. - */ - public int editDate; - /** - * Point in time (Unix timestamp) when the link will expire; 0 if never. - */ - public int expirationDate; - /** - * Information about subscription plan that is applied to the users joining the chat by the link; may be null if the link doesn't require subscription. - */ - @Nullable public StarSubscriptionPricing subscriptionPricing; - /** - * The maximum number of members, which can join the chat using the link simultaneously; 0 if not limited. Always 0 if the link requires approval. - */ - public int memberLimit; - /** - * Number of chat members, which joined the chat using the link. - */ - public int memberCount; - /** - * Number of chat members, which joined the chat using the link, but have already left because of expired subscription; for subscription links only. - */ - public int expiredMemberCount; - /** - * Number of pending join requests created using this link. - */ - public int pendingJoinRequestCount; - /** - * True, if the link only creates join request. If true, total number of joining members will be unlimited. - */ - public boolean createsJoinRequest; - /** - * True, if the link is primary. Primary invite link can't have name, expiration date, or usage limit. There is exactly one primary invite link for each administrator with canInviteUsers right at a given time. - */ - public boolean isPrimary; - /** - * True, if the link was revoked. - */ - public boolean isRevoked; - - /** - * Contains a chat invite link. - */ - public ChatInviteLink() { - } - - /** - * Contains a chat invite link. - * - * @param inviteLink Chat invite link. - * @param name Name of the link. - * @param creatorUserId User identifier of an administrator created the link. - * @param date Point in time (Unix timestamp) when the link was created. - * @param editDate Point in time (Unix timestamp) when the link was last edited; 0 if never or unknown. - * @param expirationDate Point in time (Unix timestamp) when the link will expire; 0 if never. - * @param subscriptionPricing Information about subscription plan that is applied to the users joining the chat by the link; may be null if the link doesn't require subscription. - * @param memberLimit The maximum number of members, which can join the chat using the link simultaneously; 0 if not limited. Always 0 if the link requires approval. - * @param memberCount Number of chat members, which joined the chat using the link. - * @param expiredMemberCount Number of chat members, which joined the chat using the link, but have already left because of expired subscription; for subscription links only. - * @param pendingJoinRequestCount Number of pending join requests created using this link. - * @param createsJoinRequest True, if the link only creates join request. If true, total number of joining members will be unlimited. - * @param isPrimary True, if the link is primary. Primary invite link can't have name, expiration date, or usage limit. There is exactly one primary invite link for each administrator with canInviteUsers right at a given time. - * @param isRevoked True, if the link was revoked. - */ - public ChatInviteLink(String inviteLink, String name, long creatorUserId, int date, int editDate, int expirationDate, StarSubscriptionPricing subscriptionPricing, int memberLimit, int memberCount, int expiredMemberCount, int pendingJoinRequestCount, boolean createsJoinRequest, boolean isPrimary, boolean isRevoked) { - this.inviteLink = inviteLink; - this.name = name; - this.creatorUserId = creatorUserId; - this.date = date; - this.editDate = editDate; - this.expirationDate = expirationDate; - this.subscriptionPricing = subscriptionPricing; - this.memberLimit = memberLimit; - this.memberCount = memberCount; - this.expiredMemberCount = expiredMemberCount; - this.pendingJoinRequestCount = pendingJoinRequestCount; - this.createsJoinRequest = createsJoinRequest; - this.isPrimary = isPrimary; - this.isRevoked = isRevoked; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -957651664; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a chat administrator with a number of active and revoked chat invite links. - */ - public static class ChatInviteLinkCount extends Object { - /** - * Administrator's user identifier. - */ - public long userId; - /** - * Number of active invite links. - */ - public int inviteLinkCount; - /** - * Number of revoked invite links. - */ - public int revokedInviteLinkCount; - - /** - * Describes a chat administrator with a number of active and revoked chat invite links. - */ - public ChatInviteLinkCount() { - } - - /** - * Describes a chat administrator with a number of active and revoked chat invite links. - * - * @param userId Administrator's user identifier. - * @param inviteLinkCount Number of active invite links. - * @param revokedInviteLinkCount Number of revoked invite links. - */ - public ChatInviteLinkCount(long userId, int inviteLinkCount, int revokedInviteLinkCount) { - this.userId = userId; - this.inviteLinkCount = inviteLinkCount; - this.revokedInviteLinkCount = revokedInviteLinkCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1021999210; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of chat invite link counts. - */ - public static class ChatInviteLinkCounts extends Object { - /** - * List of invite link counts. - */ - public ChatInviteLinkCount[] inviteLinkCounts; - - /** - * Contains a list of chat invite link counts. - */ - public ChatInviteLinkCounts() { - } - - /** - * Contains a list of chat invite link counts. - * - * @param inviteLinkCounts List of invite link counts. - */ - public ChatInviteLinkCounts(ChatInviteLinkCount[] inviteLinkCounts) { - this.inviteLinkCounts = inviteLinkCounts; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 920326637; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a chat invite link. - */ - public static class ChatInviteLinkInfo extends Object { - /** - * Chat identifier of the invite link; 0 if the user has no access to the chat before joining. - */ - public long chatId; - /** - * If non-zero, the amount of time for which read access to the chat will remain available, in seconds. - */ - public int accessibleFor; - /** - * Type of the chat. - */ - public InviteLinkChatType type; - /** - * Title of the chat. - */ - public String title; - /** - * Chat photo; may be null. - */ - @Nullable public ChatPhotoInfo photo; - /** - * Identifier of the accent color for chat title and background of chat photo. - */ - public int accentColorId; - /** - * Chat description. - */ - public String description; - /** - * Number of members in the chat. - */ - public int memberCount; - /** - * User identifiers of some chat members that may be known to the current user. - */ - public long[] memberUserIds; - /** - * Information about subscription plan that must be paid by the user to use the link; may be null if the link doesn't require subscription. - */ - @Nullable public ChatInviteLinkSubscriptionInfo subscriptionInfo; - /** - * True, if the link only creates join request. - */ - public boolean createsJoinRequest; - /** - * True, if the chat is a public supergroup or channel, i.e. it has a username or it is a location-based supergroup. - */ - public boolean isPublic; - /** - * Information about verification status of the chat; may be null if none. - */ - @Nullable public VerificationStatus verificationStatus; - - /** - * Contains information about a chat invite link. - */ - public ChatInviteLinkInfo() { - } - - /** - * Contains information about a chat invite link. - * - * @param chatId Chat identifier of the invite link; 0 if the user has no access to the chat before joining. - * @param accessibleFor If non-zero, the amount of time for which read access to the chat will remain available, in seconds. - * @param type Type of the chat. - * @param title Title of the chat. - * @param photo Chat photo; may be null. - * @param accentColorId Identifier of the accent color for chat title and background of chat photo. - * @param description Chat description. - * @param memberCount Number of members in the chat. - * @param memberUserIds User identifiers of some chat members that may be known to the current user. - * @param subscriptionInfo Information about subscription plan that must be paid by the user to use the link; may be null if the link doesn't require subscription. - * @param createsJoinRequest True, if the link only creates join request. - * @param isPublic True, if the chat is a public supergroup or channel, i.e. it has a username or it is a location-based supergroup. - * @param verificationStatus Information about verification status of the chat; may be null if none. - */ - public ChatInviteLinkInfo(long chatId, int accessibleFor, InviteLinkChatType type, String title, ChatPhotoInfo photo, int accentColorId, String description, int memberCount, long[] memberUserIds, ChatInviteLinkSubscriptionInfo subscriptionInfo, boolean createsJoinRequest, boolean isPublic, VerificationStatus verificationStatus) { - this.chatId = chatId; - this.accessibleFor = accessibleFor; - this.type = type; - this.title = title; - this.photo = photo; - this.accentColorId = accentColorId; - this.description = description; - this.memberCount = memberCount; - this.memberUserIds = memberUserIds; - this.subscriptionInfo = subscriptionInfo; - this.createsJoinRequest = createsJoinRequest; - this.isPublic = isPublic; - this.verificationStatus = verificationStatus; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1145310535; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a chat member joined a chat via an invite link. - */ - public static class ChatInviteLinkMember extends Object { - /** - * User identifier. - */ - public long userId; - /** - * Point in time (Unix timestamp) when the user joined the chat. - */ - public int joinedChatDate; - /** - * True, if the user has joined the chat using an invite link for a chat folder. - */ - public boolean viaChatFolderInviteLink; - /** - * User identifier of the chat administrator, approved user join request. - */ - public long approverUserId; - - /** - * Describes a chat member joined a chat via an invite link. - */ - public ChatInviteLinkMember() { - } - - /** - * Describes a chat member joined a chat via an invite link. - * - * @param userId User identifier. - * @param joinedChatDate Point in time (Unix timestamp) when the user joined the chat. - * @param viaChatFolderInviteLink True, if the user has joined the chat using an invite link for a chat folder. - * @param approverUserId User identifier of the chat administrator, approved user join request. - */ - public ChatInviteLinkMember(long userId, int joinedChatDate, boolean viaChatFolderInviteLink, long approverUserId) { - this.userId = userId; - this.joinedChatDate = joinedChatDate; - this.viaChatFolderInviteLink = viaChatFolderInviteLink; - this.approverUserId = approverUserId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 29156795; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of chat members joined a chat via an invite link. - */ - public static class ChatInviteLinkMembers extends Object { - /** - * Approximate total number of chat members found. - */ - public int totalCount; - /** - * List of chat members, joined a chat via an invite link. - */ - public ChatInviteLinkMember[] members; - - /** - * Contains a list of chat members joined a chat via an invite link. - */ - public ChatInviteLinkMembers() { - } - - /** - * Contains a list of chat members joined a chat via an invite link. - * - * @param totalCount Approximate total number of chat members found. - * @param members List of chat members, joined a chat via an invite link. - */ - public ChatInviteLinkMembers(int totalCount, ChatInviteLinkMember[] members) { - this.totalCount = totalCount; - this.members = members; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 315635051; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about subscription plan that must be paid by the user to use a chat invite link. - */ - public static class ChatInviteLinkSubscriptionInfo extends Object { - /** - * Information about subscription plan that must be paid by the user to use the link. - */ - public StarSubscriptionPricing pricing; - /** - * True, if the user has already paid for the subscription and can use joinChatByInviteLink to join the subscribed chat again. - */ - public boolean canReuse; - /** - * Identifier of the payment form to use for subscription payment; 0 if the subscription can't be paid. - */ - public long formId; - - /** - * Contains information about subscription plan that must be paid by the user to use a chat invite link. - */ - public ChatInviteLinkSubscriptionInfo() { - } - - /** - * Contains information about subscription plan that must be paid by the user to use a chat invite link. - * - * @param pricing Information about subscription plan that must be paid by the user to use the link. - * @param canReuse True, if the user has already paid for the subscription and can use joinChatByInviteLink to join the subscribed chat again. - * @param formId Identifier of the payment form to use for subscription payment; 0 if the subscription can't be paid. - */ - public ChatInviteLinkSubscriptionInfo(StarSubscriptionPricing pricing, boolean canReuse, long formId) { - this.pricing = pricing; - this.canReuse = canReuse; - this.formId = formId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 953119592; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of chat invite links. - */ - public static class ChatInviteLinks extends Object { - /** - * Approximate total number of chat invite links found. - */ - public int totalCount; - /** - * List of invite links. - */ - public ChatInviteLink[] inviteLinks; - - /** - * Contains a list of chat invite links. - */ - public ChatInviteLinks() { - } - - /** - * Contains a list of chat invite links. - * - * @param totalCount Approximate total number of chat invite links found. - * @param inviteLinks List of invite links. - */ - public ChatInviteLinks(int totalCount, ChatInviteLink[] inviteLinks) { - this.totalCount = totalCount; - this.inviteLinks = inviteLinks; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 112891427; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a user who sent a join request and waits for administrator approval. - */ - public static class ChatJoinRequest extends Object { - /** - * User identifier. - */ - public long userId; - /** - * Point in time (Unix timestamp) when the user sent the join request. - */ - public int date; - /** - * A short bio of the user. - */ - public String bio; - - /** - * Describes a user who sent a join request and waits for administrator approval. - */ - public ChatJoinRequest() { - } - - /** - * Describes a user who sent a join request and waits for administrator approval. - * - * @param userId User identifier. - * @param date Point in time (Unix timestamp) when the user sent the join request. - * @param bio A short bio of the user. - */ - public ChatJoinRequest(long userId, int date, String bio) { - this.userId = userId; - this.date = date; - this.bio = bio; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 59341416; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of requests to join a chat. - */ - public static class ChatJoinRequests extends Object { - /** - * Approximate total number of requests found. - */ - public int totalCount; - /** - * List of the requests. - */ - public ChatJoinRequest[] requests; - - /** - * Contains a list of requests to join a chat. - */ - public ChatJoinRequests() { - } - - /** - * Contains a list of requests to join a chat. - * - * @param totalCount Approximate total number of requests found. - * @param requests List of the requests. - */ - public ChatJoinRequests(int totalCount, ChatJoinRequest[] requests) { - this.totalCount = totalCount; - this.requests = requests; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1291680519; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about pending join requests for a chat. - */ - public static class ChatJoinRequestsInfo extends Object { - /** - * Total number of pending join requests. - */ - public int totalCount; - /** - * Identifiers of at most 3 users sent the newest pending join requests. - */ - public long[] userIds; - - /** - * Contains information about pending join requests for a chat. - */ - public ChatJoinRequestsInfo() { - } - - /** - * Contains information about pending join requests for a chat. - * - * @param totalCount Total number of pending join requests. - * @param userIds Identifiers of at most 3 users sent the newest pending join requests. - */ - public ChatJoinRequestsInfo(int totalCount, long[] userIds) { - this.totalCount = totalCount; - this.userIds = userIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 888534463; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a list of chats. - */ - public abstract static class ChatList extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ChatListMain.CONSTRUCTOR, - ChatListArchive.CONSTRUCTOR, - ChatListFolder.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ChatList() { - } - } - - /** - * A main list of chats. - */ - public static class ChatListMain extends ChatList { - - /** - * A main list of chats. - */ - public ChatListMain() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -400991316; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A list of chats usually located at the top of the main chat list. Unmuted chats are automatically moved from the Archive to the Main chat list when a new message arrives. - */ - public static class ChatListArchive extends ChatList { - - /** - * A list of chats usually located at the top of the main chat list. Unmuted chats are automatically moved from the Archive to the Main chat list when a new message arrives. - */ - public ChatListArchive() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 362770115; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A list of chats added to a chat folder. - */ - public static class ChatListFolder extends ChatList { - /** - * Chat folder identifier. - */ - public int chatFolderId; - - /** - * A list of chats added to a chat folder. - */ - public ChatListFolder() { - } - - /** - * A list of chats added to a chat folder. - * - * @param chatFolderId Chat folder identifier. - */ - public ChatListFolder(int chatFolderId) { - this.chatFolderId = chatFolderId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 385760856; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of chat lists. - */ - public static class ChatLists extends Object { - /** - * List of chat lists. - */ - public ChatList[] chatLists; - - /** - * Contains a list of chat lists. - */ - public ChatLists() { - } - - /** - * Contains a list of chat lists. - * - * @param chatLists List of chat lists. - */ - public ChatLists(ChatList[] chatLists) { - this.chatLists = chatLists; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -258292771; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a location to which a chat is connected. - */ - public static class ChatLocation extends Object { - /** - * The location. - */ - public Location location; - /** - * Location address; 1-64 characters, as defined by the chat owner. - */ - public String address; - - /** - * Represents a location to which a chat is connected. - */ - public ChatLocation() { - } - - /** - * Represents a location to which a chat is connected. - * - * @param location The location. - * @param address Location address; 1-64 characters, as defined by the chat owner. - */ - public ChatLocation(Location location, String address) { - this.location = location; - this.address = address; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1566863583; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a user or a chat as a member of another chat. - */ - public static class ChatMember extends Object { - /** - * Identifier of the chat member. Currently, other chats can be only Left or Banned. Only supergroups and channels can have other chats as Left or Banned members and these chats must be supergroups or channels. - */ - public MessageSender memberId; - /** - * Tag of the chat member or its custom title if the member is an administrator of the chat; 0-16 characters without emoji; applicable to basic groups and supergroups only. - */ - public String tag; - /** - * Identifier of a user who invited/promoted/banned this member in the chat; 0 if unknown. - */ - public long inviterUserId; - /** - * Point in time (Unix timestamp) when the user joined/was promoted/was banned in the chat. - */ - public int joinedChatDate; - /** - * Status of the member in the chat. - */ - public ChatMemberStatus status; - - /** - * Describes a user or a chat as a member of another chat. - */ - public ChatMember() { - } - - /** - * Describes a user or a chat as a member of another chat. - * - * @param memberId Identifier of the chat member. Currently, other chats can be only Left or Banned. Only supergroups and channels can have other chats as Left or Banned members and these chats must be supergroups or channels. - * @param tag Tag of the chat member or its custom title if the member is an administrator of the chat; 0-16 characters without emoji; applicable to basic groups and supergroups only. - * @param inviterUserId Identifier of a user who invited/promoted/banned this member in the chat; 0 if unknown. - * @param joinedChatDate Point in time (Unix timestamp) when the user joined/was promoted/was banned in the chat. - * @param status Status of the member in the chat. - */ - public ChatMember(MessageSender memberId, String tag, long inviterUserId, int joinedChatDate, ChatMemberStatus status) { - this.memberId = memberId; - this.tag = tag; - this.inviterUserId = inviterUserId; - this.joinedChatDate = joinedChatDate; - this.status = status; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1910810754; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Provides information about the status of a member in a chat. - */ - public abstract static class ChatMemberStatus extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ChatMemberStatusCreator.CONSTRUCTOR, - ChatMemberStatusAdministrator.CONSTRUCTOR, - ChatMemberStatusMember.CONSTRUCTOR, - ChatMemberStatusRestricted.CONSTRUCTOR, - ChatMemberStatusLeft.CONSTRUCTOR, - ChatMemberStatusBanned.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ChatMemberStatus() { - } - } - - /** - * The user is the owner of the chat and has all the administrator privileges. - */ - public static class ChatMemberStatusCreator extends ChatMemberStatus { - /** - * True, if the creator isn't shown in the chat member list and sends messages anonymously; applicable to supergroups only. - */ - public boolean isAnonymous; - /** - * True, if the user is a member of the chat. - */ - public boolean isMember; - - /** - * The user is the owner of the chat and has all the administrator privileges. - */ - public ChatMemberStatusCreator() { - } - - /** - * The user is the owner of the chat and has all the administrator privileges. - * - * @param isAnonymous True, if the creator isn't shown in the chat member list and sends messages anonymously; applicable to supergroups only. - * @param isMember True, if the user is a member of the chat. - */ - public ChatMemberStatusCreator(boolean isAnonymous, boolean isMember) { - this.isAnonymous = isAnonymous; - this.isMember = isMember; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 877825117; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is a member of the chat and has some additional privileges. In basic groups, administrators can edit and delete messages sent by others, add new members, ban unprivileged members, and manage video chats. In supergroups and channels, there are more detailed options for administrator privileges. - */ - public static class ChatMemberStatusAdministrator extends ChatMemberStatus { - /** - * True, if the current user can edit the administrator privileges for the called user. - */ - public boolean canBeEdited; - /** - * Rights of the administrator. - */ - public ChatAdministratorRights rights; - - /** - * The user is a member of the chat and has some additional privileges. In basic groups, administrators can edit and delete messages sent by others, add new members, ban unprivileged members, and manage video chats. In supergroups and channels, there are more detailed options for administrator privileges. - */ - public ChatMemberStatusAdministrator() { - } - - /** - * The user is a member of the chat and has some additional privileges. In basic groups, administrators can edit and delete messages sent by others, add new members, ban unprivileged members, and manage video chats. In supergroups and channels, there are more detailed options for administrator privileges. - * - * @param canBeEdited True, if the current user can edit the administrator privileges for the called user. - * @param rights Rights of the administrator. - */ - public ChatMemberStatusAdministrator(boolean canBeEdited, ChatAdministratorRights rights) { - this.canBeEdited = canBeEdited; - this.rights = rights; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -861316634; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is a member of the chat, without any additional privileges or restrictions. - */ - public static class ChatMemberStatusMember extends ChatMemberStatus { - /** - * Point in time (Unix timestamp) when the user will be removed from the chat because of the expired subscription; 0 if never. Ignored in setChatMemberStatus. - */ - public int memberUntilDate; - - /** - * The user is a member of the chat, without any additional privileges or restrictions. - */ - public ChatMemberStatusMember() { - } - - /** - * The user is a member of the chat, without any additional privileges or restrictions. - * - * @param memberUntilDate Point in time (Unix timestamp) when the user will be removed from the chat because of the expired subscription; 0 if never. Ignored in setChatMemberStatus. - */ - public ChatMemberStatusMember(int memberUntilDate) { - this.memberUntilDate = memberUntilDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -32707562; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is under certain restrictions in the chat. Not supported in basic groups and channels. - */ - public static class ChatMemberStatusRestricted extends ChatMemberStatus { - /** - * True, if the user is a member of the chat. - */ - public boolean isMember; - /** - * Point in time (Unix timestamp) when restrictions will be lifted from the user; 0 if never. If the user is restricted for more than 366 days or for less than 30 seconds from the current time, the user is considered to be restricted forever. - */ - public int restrictedUntilDate; - /** - * User permissions in the chat. - */ - public ChatPermissions permissions; - - /** - * The user is under certain restrictions in the chat. Not supported in basic groups and channels. - */ - public ChatMemberStatusRestricted() { - } - - /** - * The user is under certain restrictions in the chat. Not supported in basic groups and channels. - * - * @param isMember True, if the user is a member of the chat. - * @param restrictedUntilDate Point in time (Unix timestamp) when restrictions will be lifted from the user; 0 if never. If the user is restricted for more than 366 days or for less than 30 seconds from the current time, the user is considered to be restricted forever. - * @param permissions User permissions in the chat. - */ - public ChatMemberStatusRestricted(boolean isMember, int restrictedUntilDate, ChatPermissions permissions) { - this.isMember = isMember; - this.restrictedUntilDate = restrictedUntilDate; - this.permissions = permissions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1661432998; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user or the chat is not a chat member. - */ - public static class ChatMemberStatusLeft extends ChatMemberStatus { - - /** - * The user or the chat is not a chat member. - */ - public ChatMemberStatusLeft() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -5815259; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user or the chat was banned (and hence is not a member of the chat). Implies the user can't return to the chat, view messages, or be used as a participant identifier to join a video chat of the chat. - */ - public static class ChatMemberStatusBanned extends ChatMemberStatus { - /** - * Point in time (Unix timestamp) when the user will be unbanned; 0 if never. If the user is banned for more than 366 days or for less than 30 seconds from the current time, the user is considered to be banned forever. Always 0 in basic groups. - */ - public int bannedUntilDate; - - /** - * The user or the chat was banned (and hence is not a member of the chat). Implies the user can't return to the chat, view messages, or be used as a participant identifier to join a video chat of the chat. - */ - public ChatMemberStatusBanned() { - } - - /** - * The user or the chat was banned (and hence is not a member of the chat). Implies the user can't return to the chat, view messages, or be used as a participant identifier to join a video chat of the chat. - * - * @param bannedUntilDate Point in time (Unix timestamp) when the user will be unbanned; 0 if never. If the user is banned for more than 366 days or for less than 30 seconds from the current time, the user is considered to be banned forever. Always 0 in basic groups. - */ - public ChatMemberStatusBanned(int bannedUntilDate) { - this.bannedUntilDate = bannedUntilDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1653518666; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of chat members. - */ - public static class ChatMembers extends Object { - /** - * Approximate total number of chat members found. - */ - public int totalCount; - /** - * A list of chat members. - */ - public ChatMember[] members; - - /** - * Contains a list of chat members. - */ - public ChatMembers() { - } - - /** - * Contains a list of chat members. - * - * @param totalCount Approximate total number of chat members found. - * @param members A list of chat members. - */ - public ChatMembers(int totalCount, ChatMember[] members) { - this.totalCount = totalCount; - this.members = members; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -497558622; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Specifies the kind of chat members to return in searchChatMembers. - */ - public abstract static class ChatMembersFilter extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ChatMembersFilterContacts.CONSTRUCTOR, - ChatMembersFilterAdministrators.CONSTRUCTOR, - ChatMembersFilterMembers.CONSTRUCTOR, - ChatMembersFilterMention.CONSTRUCTOR, - ChatMembersFilterRestricted.CONSTRUCTOR, - ChatMembersFilterBanned.CONSTRUCTOR, - ChatMembersFilterBots.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ChatMembersFilter() { - } - } - - /** - * Returns contacts of the user. - */ - public static class ChatMembersFilterContacts extends ChatMembersFilter { - - /** - * Returns contacts of the user. - */ - public ChatMembersFilterContacts() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1774485671; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the owner and administrators. - */ - public static class ChatMembersFilterAdministrators extends ChatMembersFilter { - - /** - * Returns the owner and administrators. - */ - public ChatMembersFilterAdministrators() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1266893796; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns all chat members, including restricted chat members. - */ - public static class ChatMembersFilterMembers extends ChatMembersFilter { - - /** - * Returns all chat members, including restricted chat members. - */ - public ChatMembersFilterMembers() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 670504342; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns users which can be mentioned in the chat. - */ - public static class ChatMembersFilterMention extends ChatMembersFilter { - /** - * Identifier of the topic in which the users will be mentioned; pass null if none. - */ - public MessageTopic topicId; - - /** - * Returns users which can be mentioned in the chat. - */ - public ChatMembersFilterMention() { - } - - /** - * Returns users which can be mentioned in the chat. - * - * @param topicId Identifier of the topic in which the users will be mentioned; pass null if none. - */ - public ChatMembersFilterMention(MessageTopic topicId) { - this.topicId = topicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1932296772; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns users under certain restrictions in the chat; can be used only by administrators in a supergroup. - */ - public static class ChatMembersFilterRestricted extends ChatMembersFilter { - - /** - * Returns users under certain restrictions in the chat; can be used only by administrators in a supergroup. - */ - public ChatMembersFilterRestricted() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1256282813; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns users banned from the chat; can be used only by administrators in a supergroup or in a channel. - */ - public static class ChatMembersFilterBanned extends ChatMembersFilter { - - /** - * Returns users banned from the chat; can be used only by administrators in a supergroup or in a channel. - */ - public ChatMembersFilterBanned() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1863102648; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns bot members of the chat. - */ - public static class ChatMembersFilterBots extends ChatMembersFilter { - - /** - * Returns bot members of the chat. - */ - public ChatMembersFilterBots() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1422567288; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a message sender, which can be used to send messages in a chat. - */ - public static class ChatMessageSender extends Object { - /** - * The message sender. - */ - public MessageSender sender; - /** - * True, if Telegram Premium is needed to use the message sender. - */ - public boolean needsPremium; - - /** - * Represents a message sender, which can be used to send messages in a chat. - */ - public ChatMessageSender() { - } - - /** - * Represents a message sender, which can be used to send messages in a chat. - * - * @param sender The message sender. - * @param needsPremium True, if Telegram Premium is needed to use the message sender. - */ - public ChatMessageSender(MessageSender sender, boolean needsPremium) { - this.sender = sender; - this.needsPremium = needsPremium; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 760590010; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of message senders, which can be used to send messages in a chat. - */ - public static class ChatMessageSenders extends Object { - /** - * List of available message senders. - */ - public ChatMessageSender[] senders; - - /** - * Represents a list of message senders, which can be used to send messages in a chat. - */ - public ChatMessageSenders() { - } - - /** - * Represents a list of message senders, which can be used to send messages in a chat. - * - * @param senders List of available message senders. - */ - public ChatMessageSenders(ChatMessageSender[] senders) { - this.senders = senders; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1866230970; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about notification settings for a chat or a forum topic. - */ - public static class ChatNotificationSettings extends Object { - /** - * If true, the value for the relevant type of chat or the forum chat is used instead of muteFor. - */ - public boolean useDefaultMuteFor; - /** - * Time left before notifications will be unmuted, in seconds. - */ - public int muteFor; - /** - * If true, the value for the relevant type of chat or the forum chat is used instead of soundId. - */ - public boolean useDefaultSound; - /** - * Identifier of the notification sound to be played for messages; 0 if sound is disabled. - */ - public long soundId; - /** - * If true, the value for the relevant type of chat or the forum chat is used instead of showPreview. - */ - public boolean useDefaultShowPreview; - /** - * True, if message content must be displayed in notifications. - */ - public boolean showPreview; - /** - * If true, the value for the relevant type of chat is used instead of muteStories. - */ - public boolean useDefaultMuteStories; - /** - * True, if story notifications are disabled for the chat. - */ - public boolean muteStories; - /** - * If true, the value for the relevant type of chat is used instead of storySoundId. - */ - public boolean useDefaultStorySound; - /** - * Identifier of the notification sound to be played for stories; 0 if sound is disabled. - */ - public long storySoundId; - /** - * If true, the value for the relevant type of chat is used instead of showStoryPoster. - */ - public boolean useDefaultShowStoryPoster; - /** - * True, if the chat that posted a story must be displayed in notifications. - */ - public boolean showStoryPoster; - /** - * If true, the value for the relevant type of chat or the forum chat is used instead of disablePinnedMessageNotifications. - */ - public boolean useDefaultDisablePinnedMessageNotifications; - /** - * If true, notifications for incoming pinned messages will be created as for an ordinary unread message. - */ - public boolean disablePinnedMessageNotifications; - /** - * If true, the value for the relevant type of chat or the forum chat is used instead of disableMentionNotifications. - */ - public boolean useDefaultDisableMentionNotifications; - /** - * If true, notifications for messages with mentions will be created as for an ordinary unread message. - */ - public boolean disableMentionNotifications; - - /** - * Contains information about notification settings for a chat or a forum topic. - */ - public ChatNotificationSettings() { - } - - /** - * Contains information about notification settings for a chat or a forum topic. - * - * @param useDefaultMuteFor If true, the value for the relevant type of chat or the forum chat is used instead of muteFor. - * @param muteFor Time left before notifications will be unmuted, in seconds. - * @param useDefaultSound If true, the value for the relevant type of chat or the forum chat is used instead of soundId. - * @param soundId Identifier of the notification sound to be played for messages; 0 if sound is disabled. - * @param useDefaultShowPreview If true, the value for the relevant type of chat or the forum chat is used instead of showPreview. - * @param showPreview True, if message content must be displayed in notifications. - * @param useDefaultMuteStories If true, the value for the relevant type of chat is used instead of muteStories. - * @param muteStories True, if story notifications are disabled for the chat. - * @param useDefaultStorySound If true, the value for the relevant type of chat is used instead of storySoundId. - * @param storySoundId Identifier of the notification sound to be played for stories; 0 if sound is disabled. - * @param useDefaultShowStoryPoster If true, the value for the relevant type of chat is used instead of showStoryPoster. - * @param showStoryPoster True, if the chat that posted a story must be displayed in notifications. - * @param useDefaultDisablePinnedMessageNotifications If true, the value for the relevant type of chat or the forum chat is used instead of disablePinnedMessageNotifications. - * @param disablePinnedMessageNotifications If true, notifications for incoming pinned messages will be created as for an ordinary unread message. - * @param useDefaultDisableMentionNotifications If true, the value for the relevant type of chat or the forum chat is used instead of disableMentionNotifications. - * @param disableMentionNotifications If true, notifications for messages with mentions will be created as for an ordinary unread message. - */ - public ChatNotificationSettings(boolean useDefaultMuteFor, int muteFor, boolean useDefaultSound, long soundId, boolean useDefaultShowPreview, boolean showPreview, boolean useDefaultMuteStories, boolean muteStories, boolean useDefaultStorySound, long storySoundId, boolean useDefaultShowStoryPoster, boolean showStoryPoster, boolean useDefaultDisablePinnedMessageNotifications, boolean disablePinnedMessageNotifications, boolean useDefaultDisableMentionNotifications, boolean disableMentionNotifications) { - this.useDefaultMuteFor = useDefaultMuteFor; - this.muteFor = muteFor; - this.useDefaultSound = useDefaultSound; - this.soundId = soundId; - this.useDefaultShowPreview = useDefaultShowPreview; - this.showPreview = showPreview; - this.useDefaultMuteStories = useDefaultMuteStories; - this.muteStories = muteStories; - this.useDefaultStorySound = useDefaultStorySound; - this.storySoundId = storySoundId; - this.useDefaultShowStoryPoster = useDefaultShowStoryPoster; - this.showStoryPoster = showStoryPoster; - this.useDefaultDisablePinnedMessageNotifications = useDefaultDisablePinnedMessageNotifications; - this.disablePinnedMessageNotifications = disablePinnedMessageNotifications; - this.useDefaultDisableMentionNotifications = useDefaultDisableMentionNotifications; - this.disableMentionNotifications = disableMentionNotifications; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1459533846; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes actions that a user is allowed to take in a chat. - */ - public static class ChatPermissions extends Object { - /** - * True, if the user can send text messages, contacts, giveaways, giveaway winners, invoices, locations, and venues. - */ - public boolean canSendBasicMessages; - /** - * True, if the user can send music files. - */ - public boolean canSendAudios; - /** - * True, if the user can send documents. - */ - public boolean canSendDocuments; - /** - * True, if the user can send photos. - */ - public boolean canSendPhotos; - /** - * True, if the user can send videos. - */ - public boolean canSendVideos; - /** - * True, if the user can send video notes. - */ - public boolean canSendVideoNotes; - /** - * True, if the user can send voice notes. - */ - public boolean canSendVoiceNotes; - /** - * True, if the user can send polls and checklists. - */ - public boolean canSendPolls; - /** - * True, if the user can send animations, games, stickers, and dice and use inline bots. - */ - public boolean canSendOtherMessages; - /** - * True, if the user may add a link preview to their messages. - */ - public boolean canAddLinkPreviews; - /** - * True, if the user may change the tag of self. - */ - public boolean canEditTag; - /** - * True, if the user can change the chat title, photo, and other settings. - */ - public boolean canChangeInfo; - /** - * True, if the user can invite new users to the chat. - */ - public boolean canInviteUsers; - /** - * True, if the user can pin messages. - */ - public boolean canPinMessages; - /** - * True, if the user can create topics. - */ - public boolean canCreateTopics; - - /** - * Describes actions that a user is allowed to take in a chat. - */ - public ChatPermissions() { - } - - /** - * Describes actions that a user is allowed to take in a chat. - * - * @param canSendBasicMessages True, if the user can send text messages, contacts, giveaways, giveaway winners, invoices, locations, and venues. - * @param canSendAudios True, if the user can send music files. - * @param canSendDocuments True, if the user can send documents. - * @param canSendPhotos True, if the user can send photos. - * @param canSendVideos True, if the user can send videos. - * @param canSendVideoNotes True, if the user can send video notes. - * @param canSendVoiceNotes True, if the user can send voice notes. - * @param canSendPolls True, if the user can send polls and checklists. - * @param canSendOtherMessages True, if the user can send animations, games, stickers, and dice and use inline bots. - * @param canAddLinkPreviews True, if the user may add a link preview to their messages. - * @param canEditTag True, if the user may change the tag of self. - * @param canChangeInfo True, if the user can change the chat title, photo, and other settings. - * @param canInviteUsers True, if the user can invite new users to the chat. - * @param canPinMessages True, if the user can pin messages. - * @param canCreateTopics True, if the user can create topics. - */ - public ChatPermissions(boolean canSendBasicMessages, boolean canSendAudios, boolean canSendDocuments, boolean canSendPhotos, boolean canSendVideos, boolean canSendVideoNotes, boolean canSendVoiceNotes, boolean canSendPolls, boolean canSendOtherMessages, boolean canAddLinkPreviews, boolean canEditTag, boolean canChangeInfo, boolean canInviteUsers, boolean canPinMessages, boolean canCreateTopics) { - this.canSendBasicMessages = canSendBasicMessages; - this.canSendAudios = canSendAudios; - this.canSendDocuments = canSendDocuments; - this.canSendPhotos = canSendPhotos; - this.canSendVideos = canSendVideos; - this.canSendVideoNotes = canSendVideoNotes; - this.canSendVoiceNotes = canSendVoiceNotes; - this.canSendPolls = canSendPolls; - this.canSendOtherMessages = canSendOtherMessages; - this.canAddLinkPreviews = canAddLinkPreviews; - this.canEditTag = canEditTag; - this.canChangeInfo = canChangeInfo; - this.canInviteUsers = canInviteUsers; - this.canPinMessages = canPinMessages; - this.canCreateTopics = canCreateTopics; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1533863184; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a chat or user profile photo. - */ - public static class ChatPhoto extends Object { - /** - * Unique photo identifier. - */ - public long id; - /** - * Point in time (Unix timestamp) when the photo has been added. - */ - public int addedDate; - /** - * Photo minithumbnail; may be null. - */ - @Nullable public Minithumbnail minithumbnail; - /** - * Available variants of the photo in JPEG format, in different size. - */ - public PhotoSize[] sizes; - /** - * A big (up to 1280x1280) animated variant of the photo in MPEG4 format; may be null. - */ - @Nullable public AnimatedChatPhoto animation; - /** - * A small (160x160) animated variant of the photo in MPEG4 format; may be null even if the big animation is available. - */ - @Nullable public AnimatedChatPhoto smallAnimation; - /** - * Sticker-based version of the chat photo; may be null. - */ - @Nullable public ChatPhotoSticker sticker; - - /** - * Describes a chat or user profile photo. - */ - public ChatPhoto() { - } - - /** - * Describes a chat or user profile photo. - * - * @param id Unique photo identifier. - * @param addedDate Point in time (Unix timestamp) when the photo has been added. - * @param minithumbnail Photo minithumbnail; may be null. - * @param sizes Available variants of the photo in JPEG format, in different size. - * @param animation A big (up to 1280x1280) animated variant of the photo in MPEG4 format; may be null. - * @param smallAnimation A small (160x160) animated variant of the photo in MPEG4 format; may be null even if the big animation is available. - * @param sticker Sticker-based version of the chat photo; may be null. - */ - public ChatPhoto(long id, int addedDate, Minithumbnail minithumbnail, PhotoSize[] sizes, AnimatedChatPhoto animation, AnimatedChatPhoto smallAnimation, ChatPhotoSticker sticker) { - this.id = id; - this.addedDate = addedDate; - this.minithumbnail = minithumbnail; - this.sizes = sizes; - this.animation = animation; - this.smallAnimation = smallAnimation; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1430870201; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains basic information about the photo of a chat. - */ - public static class ChatPhotoInfo extends Object { - /** - * A small (160x160) chat photo variant in JPEG format. The file can be downloaded only before the photo is changed. - */ - public File small; - /** - * A big (640x640) chat photo variant in JPEG format. The file can be downloaded only before the photo is changed. - */ - public File big; - /** - * Chat photo minithumbnail; may be null. - */ - @Nullable public Minithumbnail minithumbnail; - /** - * True, if the photo has animated variant. - */ - public boolean hasAnimation; - /** - * True, if the photo is visible only for the current user. - */ - public boolean isPersonal; - - /** - * Contains basic information about the photo of a chat. - */ - public ChatPhotoInfo() { - } - - /** - * Contains basic information about the photo of a chat. - * - * @param small A small (160x160) chat photo variant in JPEG format. The file can be downloaded only before the photo is changed. - * @param big A big (640x640) chat photo variant in JPEG format. The file can be downloaded only before the photo is changed. - * @param minithumbnail Chat photo minithumbnail; may be null. - * @param hasAnimation True, if the photo has animated variant. - * @param isPersonal True, if the photo is visible only for the current user. - */ - public ChatPhotoInfo(File small, File big, Minithumbnail minithumbnail, boolean hasAnimation, boolean isPersonal) { - this.small = small; - this.big = big; - this.minithumbnail = minithumbnail; - this.hasAnimation = hasAnimation; - this.isPersonal = isPersonal; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 281195686; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Information about the sticker, which was used to create the chat photo. The sticker is shown at the center of the photo and occupies at most 67% of it. - */ - public static class ChatPhotoSticker extends Object { - /** - * Type of the sticker. - */ - public ChatPhotoStickerType type; - /** - * The fill to be used as background for the sticker; rotation angle in backgroundFillGradient isn't supported. - */ - public BackgroundFill backgroundFill; - - /** - * Information about the sticker, which was used to create the chat photo. The sticker is shown at the center of the photo and occupies at most 67% of it. - */ - public ChatPhotoSticker() { - } - - /** - * Information about the sticker, which was used to create the chat photo. The sticker is shown at the center of the photo and occupies at most 67% of it. - * - * @param type Type of the sticker. - * @param backgroundFill The fill to be used as background for the sticker; rotation angle in backgroundFillGradient isn't supported. - */ - public ChatPhotoSticker(ChatPhotoStickerType type, BackgroundFill backgroundFill) { - this.type = type; - this.backgroundFill = backgroundFill; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1459387485; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of sticker, which was used to create a chat photo. - */ - public abstract static class ChatPhotoStickerType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ChatPhotoStickerTypeRegularOrMask.CONSTRUCTOR, - ChatPhotoStickerTypeCustomEmoji.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ChatPhotoStickerType() { - } - } - - /** - * Information about the sticker, which was used to create the chat photo. - */ - public static class ChatPhotoStickerTypeRegularOrMask extends ChatPhotoStickerType { - /** - * Sticker set identifier. - */ - public long stickerSetId; - /** - * Identifier of the sticker in the set. - */ - public long stickerId; - - /** - * Information about the sticker, which was used to create the chat photo. - */ - public ChatPhotoStickerTypeRegularOrMask() { - } - - /** - * Information about the sticker, which was used to create the chat photo. - * - * @param stickerSetId Sticker set identifier. - * @param stickerId Identifier of the sticker in the set. - */ - public ChatPhotoStickerTypeRegularOrMask(long stickerSetId, long stickerId) { - this.stickerSetId = stickerSetId; - this.stickerId = stickerId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -415147620; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Information about the custom emoji, which was used to create the chat photo. - */ - public static class ChatPhotoStickerTypeCustomEmoji extends ChatPhotoStickerType { - /** - * Identifier of the custom emoji. - */ - public long customEmojiId; - - /** - * Information about the custom emoji, which was used to create the chat photo. - */ - public ChatPhotoStickerTypeCustomEmoji() { - } - - /** - * Information about the custom emoji, which was used to create the chat photo. - * - * @param customEmojiId Identifier of the custom emoji. - */ - public ChatPhotoStickerTypeCustomEmoji(long customEmojiId) { - this.customEmojiId = customEmojiId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -266224943; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of chat or user profile photos. - */ - public static class ChatPhotos extends Object { - /** - * Total number of photos. - */ - public int totalCount; - /** - * List of photos. - */ - public ChatPhoto[] photos; - - /** - * Contains a list of chat or user profile photos. - */ - public ChatPhotos() { - } - - /** - * Contains a list of chat or user profile photos. - * - * @param totalCount Total number of photos. - * @param photos List of photos. - */ - public ChatPhotos(int totalCount, ChatPhoto[] photos) { - this.totalCount = totalCount; - this.photos = photos; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1510699180; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a position of a chat in a chat list. - */ - public static class ChatPosition extends Object { - /** - * The chat list. - */ - public ChatList list; - /** - * A parameter used to determine order of the chat in the chat list. Chats must be sorted by the pair (order, chat.id) in descending order. - */ - public long order; - /** - * True, if the chat is pinned in the chat list. - */ - public boolean isPinned; - /** - * Source of the chat in the chat list; may be null. - */ - @Nullable public ChatSource source; - - /** - * Describes a position of a chat in a chat list. - */ - public ChatPosition() { - } - - /** - * Describes a position of a chat in a chat list. - * - * @param list The chat list. - * @param order A parameter used to determine order of the chat in the chat list. Chats must be sorted by the pair (order, chat.id) in descending order. - * @param isPinned True, if the chat is pinned in the chat list. - * @param source Source of the chat in the chat list; may be null. - */ - public ChatPosition(ChatList list, long order, boolean isPinned, ChatSource source) { - this.list = list; - this.order = order; - this.isPinned = isPinned; - this.source = source; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -622557355; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about revenue earned from sponsored messages in a chat. - */ - public static class ChatRevenueAmount extends Object { - /** - * Cryptocurrency in which revenue is calculated. - */ - public String cryptocurrency; - /** - * Total amount of the cryptocurrency earned, in the smallest units of the cryptocurrency. - */ - public long totalAmount; - /** - * Amount of the cryptocurrency that isn't withdrawn yet, in the smallest units of the cryptocurrency. - */ - public long balanceAmount; - /** - * Amount of the cryptocurrency available for withdrawal, in the smallest units of the cryptocurrency. - */ - public long availableAmount; - /** - * True, if Telegram Stars can be withdrawn now or later. - */ - public boolean withdrawalEnabled; - - /** - * Contains information about revenue earned from sponsored messages in a chat. - */ - public ChatRevenueAmount() { - } - - /** - * Contains information about revenue earned from sponsored messages in a chat. - * - * @param cryptocurrency Cryptocurrency in which revenue is calculated. - * @param totalAmount Total amount of the cryptocurrency earned, in the smallest units of the cryptocurrency. - * @param balanceAmount Amount of the cryptocurrency that isn't withdrawn yet, in the smallest units of the cryptocurrency. - * @param availableAmount Amount of the cryptocurrency available for withdrawal, in the smallest units of the cryptocurrency. - * @param withdrawalEnabled True, if Telegram Stars can be withdrawn now or later. - */ - public ChatRevenueAmount(String cryptocurrency, long totalAmount, long balanceAmount, long availableAmount, boolean withdrawalEnabled) { - this.cryptocurrency = cryptocurrency; - this.totalAmount = totalAmount; - this.balanceAmount = balanceAmount; - this.availableAmount = availableAmount; - this.withdrawalEnabled = withdrawalEnabled; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1505178024; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A detailed statistics about revenue earned from sponsored messages in a chat. - */ - public static class ChatRevenueStatistics extends Object { - /** - * A graph containing amount of revenue in a given hour. - */ - public StatisticalGraph revenueByHourGraph; - /** - * A graph containing amount of revenue. - */ - public StatisticalGraph revenueGraph; - /** - * Amount of earned revenue. - */ - public ChatRevenueAmount revenueAmount; - /** - * Current conversion rate of the cryptocurrency in which revenue is calculated to USD. - */ - public double usdRate; - - /** - * A detailed statistics about revenue earned from sponsored messages in a chat. - */ - public ChatRevenueStatistics() { - } - - /** - * A detailed statistics about revenue earned from sponsored messages in a chat. - * - * @param revenueByHourGraph A graph containing amount of revenue in a given hour. - * @param revenueGraph A graph containing amount of revenue. - * @param revenueAmount Amount of earned revenue. - * @param usdRate Current conversion rate of the cryptocurrency in which revenue is calculated to USD. - */ - public ChatRevenueStatistics(StatisticalGraph revenueByHourGraph, StatisticalGraph revenueGraph, ChatRevenueAmount revenueAmount, double usdRate) { - this.revenueByHourGraph = revenueByHourGraph; - this.revenueGraph = revenueGraph; - this.revenueAmount = revenueAmount; - this.usdRate = usdRate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1667438779; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a chat revenue transactions. - */ - public static class ChatRevenueTransaction extends Object { - /** - * Cryptocurrency in which revenue is calculated. - */ - public String cryptocurrency; - /** - * The withdrawn amount, in the smallest units of the cryptocurrency. - */ - public long cryptocurrencyAmount; - /** - * Type of the transaction. - */ - public ChatRevenueTransactionType type; - - /** - * Contains a chat revenue transactions. - */ - public ChatRevenueTransaction() { - } - - /** - * Contains a chat revenue transactions. - * - * @param cryptocurrency Cryptocurrency in which revenue is calculated. - * @param cryptocurrencyAmount The withdrawn amount, in the smallest units of the cryptocurrency. - * @param type Type of the transaction. - */ - public ChatRevenueTransaction(String cryptocurrency, long cryptocurrencyAmount, ChatRevenueTransactionType type) { - this.cryptocurrency = cryptocurrency; - this.cryptocurrencyAmount = cryptocurrencyAmount; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 80192767; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of transaction for revenue earned from sponsored messages in a chat. - */ - public abstract static class ChatRevenueTransactionType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ChatRevenueTransactionTypeUnsupported.CONSTRUCTOR, - ChatRevenueTransactionTypeSponsoredMessageEarnings.CONSTRUCTOR, - ChatRevenueTransactionTypeSuggestedPostEarnings.CONSTRUCTOR, - ChatRevenueTransactionTypeFragmentWithdrawal.CONSTRUCTOR, - ChatRevenueTransactionTypeFragmentRefund.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ChatRevenueTransactionType() { - } - } - - /** - * Describes an unsupported transaction. - */ - public static class ChatRevenueTransactionTypeUnsupported extends ChatRevenueTransactionType { - - /** - * Describes an unsupported transaction. - */ - public ChatRevenueTransactionTypeUnsupported() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -27518756; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes earnings from sponsored messages in a chat in some time frame. - */ - public static class ChatRevenueTransactionTypeSponsoredMessageEarnings extends ChatRevenueTransactionType { - /** - * Point in time (Unix timestamp) when the earnings started. - */ - public int startDate; - /** - * Point in time (Unix timestamp) when the earnings ended. - */ - public int endDate; - - /** - * Describes earnings from sponsored messages in a chat in some time frame. - */ - public ChatRevenueTransactionTypeSponsoredMessageEarnings() { - } - - /** - * Describes earnings from sponsored messages in a chat in some time frame. - * - * @param startDate Point in time (Unix timestamp) when the earnings started. - * @param endDate Point in time (Unix timestamp) when the earnings ended. - */ - public ChatRevenueTransactionTypeSponsoredMessageEarnings(int startDate, int endDate) { - this.startDate = startDate; - this.endDate = endDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1907391317; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes earnings from a published suggested post. - */ - public static class ChatRevenueTransactionTypeSuggestedPostEarnings extends ChatRevenueTransactionType { - /** - * Identifier of the user who paid for the suggested post. - */ - public long userId; - - /** - * Describes earnings from a published suggested post. - */ - public ChatRevenueTransactionTypeSuggestedPostEarnings() { - } - - /** - * Describes earnings from a published suggested post. - * - * @param userId Identifier of the user who paid for the suggested post. - */ - public ChatRevenueTransactionTypeSuggestedPostEarnings(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1252049103; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a withdrawal of earnings through Fragment. - */ - public static class ChatRevenueTransactionTypeFragmentWithdrawal extends ChatRevenueTransactionType { - /** - * Point in time (Unix timestamp) when the earnings withdrawal started. - */ - public int withdrawalDate; - /** - * State of the withdrawal. - */ - public RevenueWithdrawalState state; - - /** - * Describes a withdrawal of earnings through Fragment. - */ - public ChatRevenueTransactionTypeFragmentWithdrawal() { - } - - /** - * Describes a withdrawal of earnings through Fragment. - * - * @param withdrawalDate Point in time (Unix timestamp) when the earnings withdrawal started. - * @param state State of the withdrawal. - */ - public ChatRevenueTransactionTypeFragmentWithdrawal(int withdrawalDate, RevenueWithdrawalState state) { - this.withdrawalDate = withdrawalDate; - this.state = state; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 327153867; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a refund for failed withdrawal of earnings through Fragment. - */ - public static class ChatRevenueTransactionTypeFragmentRefund extends ChatRevenueTransactionType { - /** - * Point in time (Unix timestamp) when the transaction was refunded. - */ - public int refundDate; - - /** - * Describes a refund for failed withdrawal of earnings through Fragment. - */ - public ChatRevenueTransactionTypeFragmentRefund() { - } - - /** - * Describes a refund for failed withdrawal of earnings through Fragment. - * - * @param refundDate Point in time (Unix timestamp) when the transaction was refunded. - */ - public ChatRevenueTransactionTypeFragmentRefund(int refundDate) { - this.refundDate = refundDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1488694273; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of chat revenue transactions. - */ - public static class ChatRevenueTransactions extends Object { - /** - * The amount of owned Toncoins; in the smallest units of the cryptocurrency. - */ - public long tonAmount; - /** - * List of transactions. - */ - public ChatRevenueTransaction[] transactions; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Contains a list of chat revenue transactions. - */ - public ChatRevenueTransactions() { - } - - /** - * Contains a list of chat revenue transactions. - * - * @param tonAmount The amount of owned Toncoins; in the smallest units of the cryptocurrency. - * @param transactions List of transactions. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public ChatRevenueTransactions(long tonAmount, ChatRevenueTransaction[] transactions, String nextOffset) { - this.tonAmount = tonAmount; - this.transactions = transactions; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2017122771; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a reason why an external chat is shown in a chat list. - */ - public abstract static class ChatSource extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ChatSourceMtprotoProxy.CONSTRUCTOR, - ChatSourcePublicServiceAnnouncement.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ChatSource() { - } - } - - /** - * The chat is sponsored by the user's MTProxy server. - */ - public static class ChatSourceMtprotoProxy extends ChatSource { - - /** - * The chat is sponsored by the user's MTProxy server. - */ - public ChatSourceMtprotoProxy() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 394074115; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat contains a public service announcement. - */ - public static class ChatSourcePublicServiceAnnouncement extends ChatSource { - /** - * The type of the announcement. - */ - public String type; - /** - * The text of the announcement. - */ - public String text; - - /** - * The chat contains a public service announcement. - */ - public ChatSourcePublicServiceAnnouncement() { - } - - /** - * The chat contains a public service announcement. - * - * @param type The type of the announcement. - * @param text The text of the announcement. - */ - public ChatSourcePublicServiceAnnouncement(String type, String text) { - this.type = type; - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -328571244; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains a detailed statistics about a chat. - */ - public abstract static class ChatStatistics extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ChatStatisticsSupergroup.CONSTRUCTOR, - ChatStatisticsChannel.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ChatStatistics() { - } - } - - /** - * A detailed statistics about a supergroup chat. - */ - public static class ChatStatisticsSupergroup extends ChatStatistics { - /** - * A period to which the statistics applies. - */ - public DateRange period; - /** - * Number of members in the chat. - */ - public StatisticalValue memberCount; - /** - * Number of messages sent to the chat. - */ - public StatisticalValue messageCount; - /** - * Number of users who viewed messages in the chat. - */ - public StatisticalValue viewerCount; - /** - * Number of users who sent messages to the chat. - */ - public StatisticalValue senderCount; - /** - * A graph containing number of members in the chat. - */ - public StatisticalGraph memberCountGraph; - /** - * A graph containing number of members joined and left the chat. - */ - public StatisticalGraph joinGraph; - /** - * A graph containing number of new member joins per source. - */ - public StatisticalGraph joinBySourceGraph; - /** - * A graph containing distribution of active users per language. - */ - public StatisticalGraph languageGraph; - /** - * A graph containing distribution of sent messages by content type. - */ - public StatisticalGraph messageContentGraph; - /** - * A graph containing number of different actions in the chat. - */ - public StatisticalGraph actionGraph; - /** - * A graph containing distribution of message views per hour. - */ - public StatisticalGraph dayGraph; - /** - * A graph containing distribution of message views per day of week. - */ - public StatisticalGraph weekGraph; - /** - * List of users sent most messages in the last week. - */ - public ChatStatisticsMessageSenderInfo[] topSenders; - /** - * List of most active administrators in the last week. - */ - public ChatStatisticsAdministratorActionsInfo[] topAdministrators; - /** - * List of most active inviters of new members in the last week. - */ - public ChatStatisticsInviterInfo[] topInviters; - - /** - * A detailed statistics about a supergroup chat. - */ - public ChatStatisticsSupergroup() { - } - - /** - * A detailed statistics about a supergroup chat. - * - * @param period A period to which the statistics applies. - * @param memberCount Number of members in the chat. - * @param messageCount Number of messages sent to the chat. - * @param viewerCount Number of users who viewed messages in the chat. - * @param senderCount Number of users who sent messages to the chat. - * @param memberCountGraph A graph containing number of members in the chat. - * @param joinGraph A graph containing number of members joined and left the chat. - * @param joinBySourceGraph A graph containing number of new member joins per source. - * @param languageGraph A graph containing distribution of active users per language. - * @param messageContentGraph A graph containing distribution of sent messages by content type. - * @param actionGraph A graph containing number of different actions in the chat. - * @param dayGraph A graph containing distribution of message views per hour. - * @param weekGraph A graph containing distribution of message views per day of week. - * @param topSenders List of users sent most messages in the last week. - * @param topAdministrators List of most active administrators in the last week. - * @param topInviters List of most active inviters of new members in the last week. - */ - public ChatStatisticsSupergroup(DateRange period, StatisticalValue memberCount, StatisticalValue messageCount, StatisticalValue viewerCount, StatisticalValue senderCount, StatisticalGraph memberCountGraph, StatisticalGraph joinGraph, StatisticalGraph joinBySourceGraph, StatisticalGraph languageGraph, StatisticalGraph messageContentGraph, StatisticalGraph actionGraph, StatisticalGraph dayGraph, StatisticalGraph weekGraph, ChatStatisticsMessageSenderInfo[] topSenders, ChatStatisticsAdministratorActionsInfo[] topAdministrators, ChatStatisticsInviterInfo[] topInviters) { - this.period = period; - this.memberCount = memberCount; - this.messageCount = messageCount; - this.viewerCount = viewerCount; - this.senderCount = senderCount; - this.memberCountGraph = memberCountGraph; - this.joinGraph = joinGraph; - this.joinBySourceGraph = joinBySourceGraph; - this.languageGraph = languageGraph; - this.messageContentGraph = messageContentGraph; - this.actionGraph = actionGraph; - this.dayGraph = dayGraph; - this.weekGraph = weekGraph; - this.topSenders = topSenders; - this.topAdministrators = topAdministrators; - this.topInviters = topInviters; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -17244633; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A detailed statistics about a channel chat. - */ - public static class ChatStatisticsChannel extends ChatStatistics { - /** - * A period to which the statistics applies. - */ - public DateRange period; - /** - * Number of members in the chat. - */ - public StatisticalValue memberCount; - /** - * Mean number of times the recently sent messages were viewed. - */ - public StatisticalValue meanMessageViewCount; - /** - * Mean number of times the recently sent messages were shared. - */ - public StatisticalValue meanMessageShareCount; - /** - * Mean number of times reactions were added to the recently sent messages. - */ - public StatisticalValue meanMessageReactionCount; - /** - * Mean number of times the recently posted stories were viewed. - */ - public StatisticalValue meanStoryViewCount; - /** - * Mean number of times the recently posted stories were shared. - */ - public StatisticalValue meanStoryShareCount; - /** - * Mean number of times reactions were added to the recently posted stories. - */ - public StatisticalValue meanStoryReactionCount; - /** - * A percentage of users with enabled notifications for the chat; 0-100. - */ - public double enabledNotificationsPercentage; - /** - * A graph containing number of members in the chat. - */ - public StatisticalGraph memberCountGraph; - /** - * A graph containing number of members joined and left the chat. - */ - public StatisticalGraph joinGraph; - /** - * A graph containing number of members muted and unmuted the chat. - */ - public StatisticalGraph muteGraph; - /** - * A graph containing number of message views in a given hour in the last two weeks. - */ - public StatisticalGraph viewCountByHourGraph; - /** - * A graph containing number of message views per source. - */ - public StatisticalGraph viewCountBySourceGraph; - /** - * A graph containing number of new member joins per source. - */ - public StatisticalGraph joinBySourceGraph; - /** - * A graph containing number of users viewed chat messages per language. - */ - public StatisticalGraph languageGraph; - /** - * A graph containing number of chat message views and shares. - */ - public StatisticalGraph messageInteractionGraph; - /** - * A graph containing number of reactions on messages. - */ - public StatisticalGraph messageReactionGraph; - /** - * A graph containing number of story views and shares. - */ - public StatisticalGraph storyInteractionGraph; - /** - * A graph containing number of reactions on stories. - */ - public StatisticalGraph storyReactionGraph; - /** - * A graph containing number of views of associated with the chat instant views. - */ - public StatisticalGraph instantViewInteractionGraph; - /** - * Detailed statistics about number of views and shares of recently sent messages and posted stories. - */ - public ChatStatisticsInteractionInfo[] recentInteractions; - - /** - * A detailed statistics about a channel chat. - */ - public ChatStatisticsChannel() { - } - - /** - * A detailed statistics about a channel chat. - * - * @param period A period to which the statistics applies. - * @param memberCount Number of members in the chat. - * @param meanMessageViewCount Mean number of times the recently sent messages were viewed. - * @param meanMessageShareCount Mean number of times the recently sent messages were shared. - * @param meanMessageReactionCount Mean number of times reactions were added to the recently sent messages. - * @param meanStoryViewCount Mean number of times the recently posted stories were viewed. - * @param meanStoryShareCount Mean number of times the recently posted stories were shared. - * @param meanStoryReactionCount Mean number of times reactions were added to the recently posted stories. - * @param enabledNotificationsPercentage A percentage of users with enabled notifications for the chat; 0-100. - * @param memberCountGraph A graph containing number of members in the chat. - * @param joinGraph A graph containing number of members joined and left the chat. - * @param muteGraph A graph containing number of members muted and unmuted the chat. - * @param viewCountByHourGraph A graph containing number of message views in a given hour in the last two weeks. - * @param viewCountBySourceGraph A graph containing number of message views per source. - * @param joinBySourceGraph A graph containing number of new member joins per source. - * @param languageGraph A graph containing number of users viewed chat messages per language. - * @param messageInteractionGraph A graph containing number of chat message views and shares. - * @param messageReactionGraph A graph containing number of reactions on messages. - * @param storyInteractionGraph A graph containing number of story views and shares. - * @param storyReactionGraph A graph containing number of reactions on stories. - * @param instantViewInteractionGraph A graph containing number of views of associated with the chat instant views. - * @param recentInteractions Detailed statistics about number of views and shares of recently sent messages and posted stories. - */ - public ChatStatisticsChannel(DateRange period, StatisticalValue memberCount, StatisticalValue meanMessageViewCount, StatisticalValue meanMessageShareCount, StatisticalValue meanMessageReactionCount, StatisticalValue meanStoryViewCount, StatisticalValue meanStoryShareCount, StatisticalValue meanStoryReactionCount, double enabledNotificationsPercentage, StatisticalGraph memberCountGraph, StatisticalGraph joinGraph, StatisticalGraph muteGraph, StatisticalGraph viewCountByHourGraph, StatisticalGraph viewCountBySourceGraph, StatisticalGraph joinBySourceGraph, StatisticalGraph languageGraph, StatisticalGraph messageInteractionGraph, StatisticalGraph messageReactionGraph, StatisticalGraph storyInteractionGraph, StatisticalGraph storyReactionGraph, StatisticalGraph instantViewInteractionGraph, ChatStatisticsInteractionInfo[] recentInteractions) { - this.period = period; - this.memberCount = memberCount; - this.meanMessageViewCount = meanMessageViewCount; - this.meanMessageShareCount = meanMessageShareCount; - this.meanMessageReactionCount = meanMessageReactionCount; - this.meanStoryViewCount = meanStoryViewCount; - this.meanStoryShareCount = meanStoryShareCount; - this.meanStoryReactionCount = meanStoryReactionCount; - this.enabledNotificationsPercentage = enabledNotificationsPercentage; - this.memberCountGraph = memberCountGraph; - this.joinGraph = joinGraph; - this.muteGraph = muteGraph; - this.viewCountByHourGraph = viewCountByHourGraph; - this.viewCountBySourceGraph = viewCountBySourceGraph; - this.joinBySourceGraph = joinBySourceGraph; - this.languageGraph = languageGraph; - this.messageInteractionGraph = messageInteractionGraph; - this.messageReactionGraph = messageReactionGraph; - this.storyInteractionGraph = storyInteractionGraph; - this.storyReactionGraph = storyReactionGraph; - this.instantViewInteractionGraph = instantViewInteractionGraph; - this.recentInteractions = recentInteractions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1375151660; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains statistics about administrator actions done by a user. - */ - public static class ChatStatisticsAdministratorActionsInfo extends Object { - /** - * Administrator user identifier. - */ - public long userId; - /** - * Number of messages deleted by the administrator. - */ - public int deletedMessageCount; - /** - * Number of users banned by the administrator. - */ - public int bannedUserCount; - /** - * Number of users restricted by the administrator. - */ - public int restrictedUserCount; - - /** - * Contains statistics about administrator actions done by a user. - */ - public ChatStatisticsAdministratorActionsInfo() { - } - - /** - * Contains statistics about administrator actions done by a user. - * - * @param userId Administrator user identifier. - * @param deletedMessageCount Number of messages deleted by the administrator. - * @param bannedUserCount Number of users banned by the administrator. - * @param restrictedUserCount Number of users restricted by the administrator. - */ - public ChatStatisticsAdministratorActionsInfo(long userId, int deletedMessageCount, int bannedUserCount, int restrictedUserCount) { - this.userId = userId; - this.deletedMessageCount = deletedMessageCount; - this.bannedUserCount = bannedUserCount; - this.restrictedUserCount = restrictedUserCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -406467202; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains statistics about interactions with a message sent in the chat or a story posted on behalf of the chat. - */ - public static class ChatStatisticsInteractionInfo extends Object { - /** - * Type of the object. - */ - public ChatStatisticsObjectType objectType; - /** - * Number of times the object was viewed. - */ - public int viewCount; - /** - * Number of times the object was forwarded. - */ - public int forwardCount; - /** - * Number of times reactions were added to the object. - */ - public int reactionCount; - - /** - * Contains statistics about interactions with a message sent in the chat or a story posted on behalf of the chat. - */ - public ChatStatisticsInteractionInfo() { - } - - /** - * Contains statistics about interactions with a message sent in the chat or a story posted on behalf of the chat. - * - * @param objectType Type of the object. - * @param viewCount Number of times the object was viewed. - * @param forwardCount Number of times the object was forwarded. - * @param reactionCount Number of times reactions were added to the object. - */ - public ChatStatisticsInteractionInfo(ChatStatisticsObjectType objectType, int viewCount, int forwardCount, int reactionCount) { - this.objectType = objectType; - this.viewCount = viewCount; - this.forwardCount = forwardCount; - this.reactionCount = reactionCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1766496909; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains statistics about number of new members invited by a user. - */ - public static class ChatStatisticsInviterInfo extends Object { - /** - * User identifier. - */ - public long userId; - /** - * Number of new members invited by the user. - */ - public int addedMemberCount; - - /** - * Contains statistics about number of new members invited by a user. - */ - public ChatStatisticsInviterInfo() { - } - - /** - * Contains statistics about number of new members invited by a user. - * - * @param userId User identifier. - * @param addedMemberCount Number of new members invited by the user. - */ - public ChatStatisticsInviterInfo(long userId, int addedMemberCount) { - this.userId = userId; - this.addedMemberCount = addedMemberCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 629396619; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains statistics about messages sent by a user. - */ - public static class ChatStatisticsMessageSenderInfo extends Object { - /** - * User identifier. - */ - public long userId; - /** - * Number of sent messages. - */ - public int sentMessageCount; - /** - * Average number of characters in sent messages; 0 if unknown. - */ - public int averageCharacterCount; - - /** - * Contains statistics about messages sent by a user. - */ - public ChatStatisticsMessageSenderInfo() { - } - - /** - * Contains statistics about messages sent by a user. - * - * @param userId User identifier. - * @param sentMessageCount Number of sent messages. - * @param averageCharacterCount Average number of characters in sent messages; 0 if unknown. - */ - public ChatStatisticsMessageSenderInfo(long userId, int sentMessageCount, int averageCharacterCount) { - this.userId = userId; - this.sentMessageCount = sentMessageCount; - this.averageCharacterCount = averageCharacterCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1762295371; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of object, for which statistics are provided. - */ - public abstract static class ChatStatisticsObjectType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ChatStatisticsObjectTypeMessage.CONSTRUCTOR, - ChatStatisticsObjectTypeStory.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ChatStatisticsObjectType() { - } - } - - /** - * Describes a message sent in the chat. - */ - public static class ChatStatisticsObjectTypeMessage extends ChatStatisticsObjectType { - /** - * Message identifier. - */ - public long messageId; - - /** - * Describes a message sent in the chat. - */ - public ChatStatisticsObjectTypeMessage() { - } - - /** - * Describes a message sent in the chat. - * - * @param messageId Message identifier. - */ - public ChatStatisticsObjectTypeMessage(long messageId) { - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1872700662; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a story posted on behalf of the chat. - */ - public static class ChatStatisticsObjectTypeStory extends ChatStatisticsObjectType { - /** - * Story identifier. - */ - public int storyId; - - /** - * Describes a story posted on behalf of the chat. - */ - public ChatStatisticsObjectTypeStory() { - } - - /** - * Describes a story posted on behalf of the chat. - * - * @param storyId Story identifier. - */ - public ChatStatisticsObjectTypeStory(int storyId) { - this.storyId = storyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 364575152; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a chat theme. - */ - public abstract static class ChatTheme extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ChatThemeEmoji.CONSTRUCTOR, - ChatThemeGift.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ChatTheme() { - } - } - - /** - * A chat theme based on an emoji. - */ - public static class ChatThemeEmoji extends ChatTheme { - /** - * Name of the theme; full theme description is received through updateEmojiChatThemes. - */ - public String name; - - /** - * A chat theme based on an emoji. - */ - public ChatThemeEmoji() { - } - - /** - * A chat theme based on an emoji. - * - * @param name Name of the theme; full theme description is received through updateEmojiChatThemes. - */ - public ChatThemeEmoji(String name) { - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1863920197; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat theme based on an upgraded gift. - */ - public static class ChatThemeGift extends ChatTheme { - /** - * The chat theme. - */ - public GiftChatTheme giftTheme; - - /** - * A chat theme based on an upgraded gift. - */ - public ChatThemeGift() { - } - - /** - * A chat theme based on an upgraded gift. - * - * @param giftTheme The chat theme. - */ - public ChatThemeGift(GiftChatTheme giftTheme) { - this.giftTheme = giftTheme; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 19728441; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the type of chat. - */ - public abstract static class ChatType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ChatTypePrivate.CONSTRUCTOR, - ChatTypeBasicGroup.CONSTRUCTOR, - ChatTypeSupergroup.CONSTRUCTOR, - ChatTypeSecret.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ChatType() { - } - } - - /** - * An ordinary chat with a user. - */ - public static class ChatTypePrivate extends ChatType { - /** - * User identifier. - */ - public long userId; - - /** - * An ordinary chat with a user. - */ - public ChatTypePrivate() { - } - - /** - * An ordinary chat with a user. - * - * @param userId User identifier. - */ - public ChatTypePrivate(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1579049844; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A basic group (a chat with 0-200 other users). - */ - public static class ChatTypeBasicGroup extends ChatType { - /** - * Basic group identifier. - */ - public long basicGroupId; - - /** - * A basic group (a chat with 0-200 other users). - */ - public ChatTypeBasicGroup() { - } - - /** - * A basic group (a chat with 0-200 other users). - * - * @param basicGroupId Basic group identifier. - */ - public ChatTypeBasicGroup(long basicGroupId) { - this.basicGroupId = basicGroupId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 973884508; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A supergroup or channel (with unlimited members). - */ - public static class ChatTypeSupergroup extends ChatType { - /** - * Supergroup or channel identifier. - */ - public long supergroupId; - /** - * True, if the supergroup is a channel. - */ - public boolean isChannel; - - /** - * A supergroup or channel (with unlimited members). - */ - public ChatTypeSupergroup() { - } - - /** - * A supergroup or channel (with unlimited members). - * - * @param supergroupId Supergroup or channel identifier. - * @param isChannel True, if the supergroup is a channel. - */ - public ChatTypeSupergroup(long supergroupId, boolean isChannel) { - this.supergroupId = supergroupId; - this.isChannel = isChannel; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1472570774; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A secret chat with a user. - */ - public static class ChatTypeSecret extends ChatType { - /** - * Secret chat identifier. - */ - public int secretChatId; - /** - * User identifier of the other user in the secret chat. - */ - public long userId; - - /** - * A secret chat with a user. - */ - public ChatTypeSecret() { - } - - /** - * A secret chat with a user. - * - * @param secretChatId Secret chat identifier. - * @param userId User identifier of the other user in the secret chat. - */ - public ChatTypeSecret(int secretChatId, long userId) { - this.secretChatId = secretChatId; - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 862366513; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of chats. - */ - public static class Chats extends Object { - /** - * Approximate total number of chats found. - */ - public int totalCount; - /** - * List of chat identifiers. - */ - public long[] chatIds; - - /** - * Represents a list of chats. - */ - public Chats() { - } - - /** - * Represents a list of chats. - * - * @param totalCount Approximate total number of chats found. - * @param chatIds List of chat identifiers. - */ - public Chats(int totalCount, long[] chatIds) { - this.totalCount = totalCount; - this.chatIds = chatIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1809654812; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents result of checking whether a username can be set for a chat. - */ - public abstract static class CheckChatUsernameResult extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - CheckChatUsernameResultOk.CONSTRUCTOR, - CheckChatUsernameResultUsernameInvalid.CONSTRUCTOR, - CheckChatUsernameResultUsernameOccupied.CONSTRUCTOR, - CheckChatUsernameResultUsernamePurchasable.CONSTRUCTOR, - CheckChatUsernameResultPublicChatsTooMany.CONSTRUCTOR, - CheckChatUsernameResultPublicGroupsUnavailable.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public CheckChatUsernameResult() { - } - } - - /** - * The username can be set. - */ - public static class CheckChatUsernameResultOk extends CheckChatUsernameResult { - - /** - * The username can be set. - */ - public CheckChatUsernameResultOk() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1498956964; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The username is invalid. - */ - public static class CheckChatUsernameResultUsernameInvalid extends CheckChatUsernameResult { - - /** - * The username is invalid. - */ - public CheckChatUsernameResultUsernameInvalid() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -636979370; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The username is occupied. - */ - public static class CheckChatUsernameResultUsernameOccupied extends CheckChatUsernameResult { - - /** - * The username is occupied. - */ - public CheckChatUsernameResultUsernameOccupied() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1320892201; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The username can be purchased at https://fragment.com. Information about the username can be received using getCollectibleItemInfo. - */ - public static class CheckChatUsernameResultUsernamePurchasable extends CheckChatUsernameResult { - - /** - * The username can be purchased at https://fragment.com. Information about the username can be received using getCollectibleItemInfo. - */ - public CheckChatUsernameResultUsernamePurchasable() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 5885529; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user has too many chats with username, one of them must be made private first. - */ - public static class CheckChatUsernameResultPublicChatsTooMany extends CheckChatUsernameResult { - - /** - * The user has too many chats with username, one of them must be made private first. - */ - public CheckChatUsernameResultPublicChatsTooMany() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -659264388; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user can't be a member of a public supergroup. - */ - public static class CheckChatUsernameResultPublicGroupsUnavailable extends CheckChatUsernameResult { - - /** - * The user can't be a member of a public supergroup. - */ - public CheckChatUsernameResultPublicGroupsUnavailable() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -51833641; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents result of checking whether a name can be used for a new sticker set. - */ - public abstract static class CheckStickerSetNameResult extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - CheckStickerSetNameResultOk.CONSTRUCTOR, - CheckStickerSetNameResultNameInvalid.CONSTRUCTOR, - CheckStickerSetNameResultNameOccupied.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public CheckStickerSetNameResult() { - } - } - - /** - * The name can be set. - */ - public static class CheckStickerSetNameResultOk extends CheckStickerSetNameResult { - - /** - * The name can be set. - */ - public CheckStickerSetNameResultOk() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1404308904; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The name is invalid. - */ - public static class CheckStickerSetNameResultNameInvalid extends CheckStickerSetNameResult { - - /** - * The name is invalid. - */ - public CheckStickerSetNameResultNameInvalid() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 177992244; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The name is occupied. - */ - public static class CheckStickerSetNameResultNameOccupied extends CheckStickerSetNameResult { - - /** - * The name is occupied. - */ - public CheckStickerSetNameResultNameOccupied() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1012980872; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a checklist. - */ - public static class Checklist extends Object { - /** - * Title of the checklist; may contain only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities. - */ - public FormattedText title; - /** - * List of tasks in the checklist. - */ - public ChecklistTask[] tasks; - /** - * True, if users other than creator of the list can add tasks to the list. - */ - public boolean othersCanAddTasks; - /** - * True, if the current user can add tasks to the list if they have Telegram Premium subscription. - */ - public boolean canAddTasks; - /** - * True, if users other than creator of the list can mark tasks as done or not done. If true, then the checklist is called "group checklist". - */ - public boolean othersCanMarkTasksAsDone; - /** - * True, if the current user can mark tasks as done or not done if they have Telegram Premium subscription. - */ - public boolean canMarkTasksAsDone; - - /** - * Describes a checklist. - */ - public Checklist() { - } - - /** - * Describes a checklist. - * - * @param title Title of the checklist; may contain only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities. - * @param tasks List of tasks in the checklist. - * @param othersCanAddTasks True, if users other than creator of the list can add tasks to the list. - * @param canAddTasks True, if the current user can add tasks to the list if they have Telegram Premium subscription. - * @param othersCanMarkTasksAsDone True, if users other than creator of the list can mark tasks as done or not done. If true, then the checklist is called "group checklist". - * @param canMarkTasksAsDone True, if the current user can mark tasks as done or not done if they have Telegram Premium subscription. - */ - public Checklist(FormattedText title, ChecklistTask[] tasks, boolean othersCanAddTasks, boolean canAddTasks, boolean othersCanMarkTasksAsDone, boolean canMarkTasksAsDone) { - this.title = title; - this.tasks = tasks; - this.othersCanAddTasks = othersCanAddTasks; - this.canAddTasks = canAddTasks; - this.othersCanMarkTasksAsDone = othersCanMarkTasksAsDone; - this.canMarkTasksAsDone = canMarkTasksAsDone; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -987598247; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a task in a checklist. - */ - public static class ChecklistTask extends Object { - /** - * Unique identifier of the task. - */ - public int id; - /** - * Text of the task; may contain only Bold, Italic, Underline, Strikethrough, Spoiler, CustomEmoji, Url, EmailAddress, Mention, Hashtag, Cashtag and PhoneNumber entities. - */ - public FormattedText text; - /** - * Identifier of the user or chat that completed the task; may be null if the task isn't completed yet. - */ - @Nullable public MessageSender completedBy; - /** - * Point in time (Unix timestamp) when the task was completed; 0 if the task isn't completed. - */ - public int completionDate; - - /** - * Describes a task in a checklist. - */ - public ChecklistTask() { - } - - /** - * Describes a task in a checklist. - * - * @param id Unique identifier of the task. - * @param text Text of the task; may contain only Bold, Italic, Underline, Strikethrough, Spoiler, CustomEmoji, Url, EmailAddress, Mention, Hashtag, Cashtag and PhoneNumber entities. - * @param completedBy Identifier of the user or chat that completed the task; may be null if the task isn't completed yet. - * @param completionDate Point in time (Unix timestamp) when the task was completed; 0 if the task isn't completed. - */ - public ChecklistTask(int id, FormattedText text, MessageSender completedBy, int completionDate) { - this.id = id; - this.text = text; - this.completedBy = completedBy; - this.completionDate = completionDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 464950512; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a user who had or will have a birthday soon. - */ - public static class CloseBirthdayUser extends Object { - /** - * User identifier. - */ - public long userId; - /** - * Birthdate of the user. - */ - public Birthdate birthdate; - - /** - * Describes a user who had or will have a birthday soon. - */ - public CloseBirthdayUser() { - } - - /** - * Describes a user who had or will have a birthday soon. - * - * @param userId User identifier. - * @param birthdate Birthdate of the user. - */ - public CloseBirthdayUser(long userId, Birthdate birthdate) { - this.userId = userId; - this.birthdate = birthdate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2147067410; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a closed vector path. The path begins at the end point of the last command. The coordinate system origin is in the upper-left corner. - */ - public static class ClosedVectorPath extends Object { - /** - * List of vector path commands. - */ - public VectorPathCommand[] commands; - - /** - * Represents a closed vector path. The path begins at the end point of the last command. The coordinate system origin is in the upper-left corner. - */ - public ClosedVectorPath() { - } - - /** - * Represents a closed vector path. The path begins at the end point of the last command. The coordinate system origin is in the upper-left corner. - * - * @param commands List of vector path commands. - */ - public ClosedVectorPath(VectorPathCommand[] commands) { - this.commands = commands; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 589951657; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a collectible item and its last purchase. - */ - public static class CollectibleItemInfo extends Object { - /** - * Point in time (Unix timestamp) when the item was purchased. - */ - public int purchaseDate; - /** - * Currency for the paid amount. - */ - public String currency; - /** - * The paid amount, in the smallest units of the currency. - */ - public long amount; - /** - * Cryptocurrency used to pay for the item. - */ - public String cryptocurrency; - /** - * The paid amount, in the smallest units of the cryptocurrency. - */ - public long cryptocurrencyAmount; - /** - * Individual URL for the item on https://fragment.com. - */ - public String url; - - /** - * Contains information about a collectible item and its last purchase. - */ - public CollectibleItemInfo() { - } - - /** - * Contains information about a collectible item and its last purchase. - * - * @param purchaseDate Point in time (Unix timestamp) when the item was purchased. - * @param currency Currency for the paid amount. - * @param amount The paid amount, in the smallest units of the currency. - * @param cryptocurrency Cryptocurrency used to pay for the item. - * @param cryptocurrencyAmount The paid amount, in the smallest units of the cryptocurrency. - * @param url Individual URL for the item on https://fragment.com. - */ - public CollectibleItemInfo(int purchaseDate, String currency, long amount, String cryptocurrency, long cryptocurrencyAmount, String url) { - this.purchaseDate = purchaseDate; - this.currency = currency; - this.amount = amount; - this.cryptocurrency = cryptocurrency; - this.cryptocurrencyAmount = cryptocurrencyAmount; - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1460640717; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a collectible item that can be purchased at https://fragment.com. - */ - public abstract static class CollectibleItemType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - CollectibleItemTypeUsername.CONSTRUCTOR, - CollectibleItemTypePhoneNumber.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public CollectibleItemType() { - } - } - - /** - * A username. - */ - public static class CollectibleItemTypeUsername extends CollectibleItemType { - /** - * The username. - */ - public String username; - - /** - * A username. - */ - public CollectibleItemTypeUsername() { - } - - /** - * A username. - * - * @param username The username. - */ - public CollectibleItemTypeUsername(String username) { - this.username = username; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 458680273; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A phone number. - */ - public static class CollectibleItemTypePhoneNumber extends CollectibleItemType { - /** - * The phone number. - */ - public String phoneNumber; - - /** - * A phone number. - */ - public CollectibleItemTypePhoneNumber() { - } - - /** - * A phone number. - * - * @param phoneNumber The phone number. - */ - public CollectibleItemTypePhoneNumber(String phoneNumber) { - this.phoneNumber = phoneNumber; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1256251714; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an affiliate program that was connected to an affiliate. - */ - public static class ConnectedAffiliateProgram extends Object { - /** - * The link that can be used to refer users if the program is still active. - */ - public String url; - /** - * User identifier of the bot created the program. - */ - public long botUserId; - /** - * The parameters of the affiliate program. - */ - public AffiliateProgramParameters parameters; - /** - * Point in time (Unix timestamp) when the affiliate program was connected. - */ - public int connectionDate; - /** - * True, if the program was canceled by the bot, or disconnected by the chat owner and isn't available anymore. - */ - public boolean isDisconnected; - /** - * The number of users that used the affiliate program. - */ - public long userCount; - /** - * The number of Telegram Stars that were earned by the affiliate program. - */ - public long revenueStarCount; - - /** - * Describes an affiliate program that was connected to an affiliate. - */ - public ConnectedAffiliateProgram() { - } - - /** - * Describes an affiliate program that was connected to an affiliate. - * - * @param url The link that can be used to refer users if the program is still active. - * @param botUserId User identifier of the bot created the program. - * @param parameters The parameters of the affiliate program. - * @param connectionDate Point in time (Unix timestamp) when the affiliate program was connected. - * @param isDisconnected True, if the program was canceled by the bot, or disconnected by the chat owner and isn't available anymore. - * @param userCount The number of users that used the affiliate program. - * @param revenueStarCount The number of Telegram Stars that were earned by the affiliate program. - */ - public ConnectedAffiliateProgram(String url, long botUserId, AffiliateProgramParameters parameters, int connectionDate, boolean isDisconnected, long userCount, long revenueStarCount) { - this.url = url; - this.botUserId = botUserId; - this.parameters = parameters; - this.connectionDate = connectionDate; - this.isDisconnected = isDisconnected; - this.userCount = userCount; - this.revenueStarCount = revenueStarCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -294102864; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of affiliate programs that were connected to an affiliate. - */ - public static class ConnectedAffiliatePrograms extends Object { - /** - * The total number of affiliate programs that were connected to the affiliate. - */ - public int totalCount; - /** - * The list of connected affiliate programs. - */ - public ConnectedAffiliateProgram[] programs; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Represents a list of affiliate programs that were connected to an affiliate. - */ - public ConnectedAffiliatePrograms() { - } - - /** - * Represents a list of affiliate programs that were connected to an affiliate. - * - * @param totalCount The total number of affiliate programs that were connected to the affiliate. - * @param programs The list of connected affiliate programs. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public ConnectedAffiliatePrograms(int totalCount, ConnectedAffiliateProgram[] programs, String nextOffset) { - this.totalCount = totalCount; - this.programs = programs; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1505880847; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about one website the current user is logged in with Telegram. - */ - public static class ConnectedWebsite extends Object { - /** - * Website identifier. - */ - public long id; - /** - * The domain name of the website. - */ - public String domainName; - /** - * User identifier of a bot linked with the website. - */ - public long botUserId; - /** - * The version of a browser used to log in. - */ - public String browser; - /** - * Operating system the browser is running on. - */ - public String platform; - /** - * Point in time (Unix timestamp) when the user was logged in. - */ - public int logInDate; - /** - * Point in time (Unix timestamp) when obtained authorization was last used. - */ - public int lastActiveDate; - /** - * IP address from which the user was logged in, in human-readable format. - */ - public String ipAddress; - /** - * Human-readable description of a country and a region from which the user was logged in, based on the IP address. - */ - public String location; - - /** - * Contains information about one website the current user is logged in with Telegram. - */ - public ConnectedWebsite() { - } - - /** - * Contains information about one website the current user is logged in with Telegram. - * - * @param id Website identifier. - * @param domainName The domain name of the website. - * @param botUserId User identifier of a bot linked with the website. - * @param browser The version of a browser used to log in. - * @param platform Operating system the browser is running on. - * @param logInDate Point in time (Unix timestamp) when the user was logged in. - * @param lastActiveDate Point in time (Unix timestamp) when obtained authorization was last used. - * @param ipAddress IP address from which the user was logged in, in human-readable format. - * @param location Human-readable description of a country and a region from which the user was logged in, based on the IP address. - */ - public ConnectedWebsite(long id, String domainName, long botUserId, String browser, String platform, int logInDate, int lastActiveDate, String ipAddress, String location) { - this.id = id; - this.domainName = domainName; - this.botUserId = botUserId; - this.browser = browser; - this.platform = platform; - this.logInDate = logInDate; - this.lastActiveDate = lastActiveDate; - this.ipAddress = ipAddress; - this.location = location; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1978115978; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of websites the current user is logged in with Telegram. - */ - public static class ConnectedWebsites extends Object { - /** - * List of connected websites. - */ - public ConnectedWebsite[] websites; - - /** - * Contains a list of websites the current user is logged in with Telegram. - */ - public ConnectedWebsites() { - } - - /** - * Contains a list of websites the current user is logged in with Telegram. - * - * @param websites List of connected websites. - */ - public ConnectedWebsites(ConnectedWebsite[] websites) { - this.websites = websites; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1727949694; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the current state of the connection to Telegram servers. - */ - public abstract static class ConnectionState extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ConnectionStateWaitingForNetwork.CONSTRUCTOR, - ConnectionStateConnectingToProxy.CONSTRUCTOR, - ConnectionStateConnecting.CONSTRUCTOR, - ConnectionStateUpdating.CONSTRUCTOR, - ConnectionStateReady.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ConnectionState() { - } - } - - /** - * Waiting for the network to become available. Use setNetworkType to change the available network type. - */ - public static class ConnectionStateWaitingForNetwork extends ConnectionState { - - /** - * Waiting for the network to become available. Use setNetworkType to change the available network type. - */ - public ConnectionStateWaitingForNetwork() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1695405912; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Establishing a connection with a proxy server. - */ - public static class ConnectionStateConnectingToProxy extends ConnectionState { - - /** - * Establishing a connection with a proxy server. - */ - public ConnectionStateConnectingToProxy() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -93187239; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Establishing a connection to the Telegram servers. - */ - public static class ConnectionStateConnecting extends ConnectionState { - - /** - * Establishing a connection to the Telegram servers. - */ - public ConnectionStateConnecting() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1298400670; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Downloading data expected to be received while the application was offline. - */ - public static class ConnectionStateUpdating extends ConnectionState { - - /** - * Downloading data expected to be received while the application was offline. - */ - public ConnectionStateUpdating() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -188104009; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * There is a working connection to the Telegram servers. - */ - public static class ConnectionStateReady extends ConnectionState { - - /** - * There is a working connection to the Telegram servers. - */ - public ConnectionStateReady() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 48608492; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a contact of a user. - */ - public static class Contact extends Object { - /** - * Phone number of the user. - */ - public String phoneNumber; - /** - * First name of the user; 1-64 characters. - */ - public String firstName; - /** - * Last name of the user; 0-64 characters. - */ - public String lastName; - /** - * Additional data about the user in a form of vCard; 0-2048 bytes in length. - */ - public String vcard; - /** - * Identifier of the user, if known; 0 otherwise. - */ - public long userId; - - /** - * Describes a contact of a user. - */ - public Contact() { - } - - /** - * Describes a contact of a user. - * - * @param phoneNumber Phone number of the user. - * @param firstName First name of the user; 1-64 characters. - * @param lastName Last name of the user; 0-64 characters. - * @param vcard Additional data about the user in a form of vCard; 0-2048 bytes in length. - * @param userId Identifier of the user, if known; 0 otherwise. - */ - public Contact(String phoneNumber, String firstName, String lastName, String vcard, long userId) { - this.phoneNumber = phoneNumber; - this.firstName = firstName; - this.lastName = lastName; - this.vcard = vcard; - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1993844876; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a counter. - */ - public static class Count extends Object { - /** - * Count. - */ - public int count; - - /** - * Contains a counter. - */ - public Count() { - } - - /** - * Contains a counter. - * - * @param count Count. - */ - public Count(int count) { - this.count = count; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1295577348; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about countries. - */ - public static class Countries extends Object { - /** - * The list of countries. - */ - public CountryInfo[] countries; - - /** - * Contains information about countries. - */ - public Countries() { - } - - /** - * Contains information about countries. - * - * @param countries The list of countries. - */ - public Countries(CountryInfo[] countries) { - this.countries = countries; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1854211813; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a country. - */ - public static class CountryInfo extends Object { - /** - * A two-letter ISO 3166-1 alpha-2 country code. - */ - public String countryCode; - /** - * Native name of the country. - */ - public String name; - /** - * English name of the country. - */ - public String englishName; - /** - * True, if the country must be hidden from the list of all countries. - */ - public boolean isHidden; - /** - * List of country calling codes. - */ - public String[] callingCodes; - - /** - * Contains information about a country. - */ - public CountryInfo() { - } - - /** - * Contains information about a country. - * - * @param countryCode A two-letter ISO 3166-1 alpha-2 country code. - * @param name Native name of the country. - * @param englishName English name of the country. - * @param isHidden True, if the country must be hidden from the list of all countries. - * @param callingCodes List of country calling codes. - */ - public CountryInfo(String countryCode, String name, String englishName, boolean isHidden, String[] callingCodes) { - this.countryCode = countryCode; - this.name = name; - this.englishName = englishName; - this.isHidden = isHidden; - this.callingCodes = callingCodes; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1617195722; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains result of gift crafting. - */ - public abstract static class CraftGiftResult extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - CraftGiftResultSuccess.CONSTRUCTOR, - CraftGiftResultTooEarly.CONSTRUCTOR, - CraftGiftResultInvalidGift.CONSTRUCTOR, - CraftGiftResultFail.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public CraftGiftResult() { - } - } - - /** - * Crafting was successful. - */ - public static class CraftGiftResultSuccess extends CraftGiftResult { - /** - * The created gift. - */ - public UpgradedGift gift; - /** - * Unique identifier of the received gift for the current user. - */ - public String receivedGiftId; - - /** - * Crafting was successful. - */ - public CraftGiftResultSuccess() { - } - - /** - * Crafting was successful. - * - * @param gift The created gift. - * @param receivedGiftId Unique identifier of the received gift for the current user. - */ - public CraftGiftResultSuccess(UpgradedGift gift, String receivedGiftId) { - this.gift = gift; - this.receivedGiftId = receivedGiftId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1790823778; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Crafting isn't possible because one of the gifts can't be used for crafting yet. - */ - public static class CraftGiftResultTooEarly extends CraftGiftResult { - /** - * Time left before the gift can be used for crafting. - */ - public int retryAfter; - - /** - * Crafting isn't possible because one of the gifts can't be used for crafting yet. - */ - public CraftGiftResultTooEarly() { - } - - /** - * Crafting isn't possible because one of the gifts can't be used for crafting yet. - * - * @param retryAfter Time left before the gift can be used for crafting. - */ - public CraftGiftResultTooEarly(int retryAfter) { - this.retryAfter = retryAfter; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1383697767; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Crafting isn't possible because one of the gifts isn't suitable for crafting. - */ - public static class CraftGiftResultInvalidGift extends CraftGiftResult { - - /** - * Crafting isn't possible because one of the gifts isn't suitable for crafting. - */ - public CraftGiftResultInvalidGift() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -667740645; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Crafting has failed. - */ - public static class CraftGiftResultFail extends CraftGiftResult { - - /** - * Crafting has failed. - */ - public CraftGiftResultFail() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1394001631; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a newly created basic group chat. - */ - public static class CreatedBasicGroupChat extends Object { - /** - * Chat identifier. - */ - public long chatId; - /** - * Information about failed to add members. - */ - public FailedToAddMembers failedToAddMembers; - - /** - * Contains information about a newly created basic group chat. - */ - public CreatedBasicGroupChat() { - } - - /** - * Contains information about a newly created basic group chat. - * - * @param chatId Chat identifier. - * @param failedToAddMembers Information about failed to add members. - */ - public CreatedBasicGroupChat(long chatId, FailedToAddMembers failedToAddMembers) { - this.chatId = chatId; - this.failedToAddMembers = failedToAddMembers; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -20417068; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes the current weather. - */ - public static class CurrentWeather extends Object { - /** - * Temperature, in degree Celsius. - */ - public double temperature; - /** - * Emoji representing the weather. - */ - public String emoji; - - /** - * Describes the current weather. - */ - public CurrentWeather() { - } - - /** - * Describes the current weather. - * - * @param temperature Temperature, in degree Celsius. - * @param emoji Emoji representing the weather. - */ - public CurrentWeather(double temperature, String emoji) { - this.temperature = temperature; - this.emoji = emoji; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -355555136; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains the result of a custom request. - */ - public static class CustomRequestResult extends Object { - /** - * A JSON-serialized result. - */ - public String result; - - /** - * Contains the result of a custom request. - */ - public CustomRequestResult() { - } - - /** - * Contains the result of a custom request. - * - * @param result A JSON-serialized result. - */ - public CustomRequestResult(String result) { - this.result = result; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2009960452; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains some binary data. - */ - public static class Data extends Object { - /** - * Data. - */ - public byte[] data; - - /** - * Contains some binary data. - */ - public Data() { - } - - /** - * Contains some binary data. - * - * @param data Data. - */ - public Data(byte[] data) { - this.data = data; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 221197337; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains database statistics. - */ - public static class DatabaseStatistics extends Object { - /** - * Database statistics in an unspecified human-readable format. - */ - public String statistics; - - /** - * Contains database statistics. - */ - public DatabaseStatistics() { - } - - /** - * Contains database statistics. - * - * @param statistics Database statistics in an unspecified human-readable format. - */ - public DatabaseStatistics(String statistics) { - this.statistics = statistics; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1123912880; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a date according to the Gregorian calendar. - */ - public static class Date extends Object { - /** - * Day of the month; 1-31. - */ - public int day; - /** - * Month; 1-12. - */ - public int month; - /** - * Year; 1-9999. - */ - public int year; - - /** - * Represents a date according to the Gregorian calendar. - */ - public Date() { - } - - /** - * Represents a date according to the Gregorian calendar. - * - * @param day Day of the month; 1-31. - * @param month Month; 1-12. - * @param year Year; 1-9999. - */ - public Date(int day, int month, int year) { - this.day = day; - this.month = month; - this.year = year; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -277956960; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a date range. - */ - public static class DateRange extends Object { - /** - * Point in time (Unix timestamp) at which the date range begins. - */ - public int startDate; - /** - * Point in time (Unix timestamp) at which the date range ends. - */ - public int endDate; - - /** - * Represents a date range. - */ - public DateRange() { - } - - /** - * Represents a date range. - * - * @param startDate Point in time (Unix timestamp) at which the date range begins. - * @param endDate Point in time (Unix timestamp) at which the date range ends. - */ - public DateRange(int startDate, int endDate) { - this.startDate = startDate; - this.endDate = endDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1360333926; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes date and time formatting. - */ - public abstract static class DateTimeFormattingType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - DateTimeFormattingTypeRelative.CONSTRUCTOR, - DateTimeFormattingTypeAbsolute.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public DateTimeFormattingType() { - } - } - - /** - * The time must be shown relative to the current time ([in ] X seconds, minutes, hours, days, months, years [ago]). - */ - public static class DateTimeFormattingTypeRelative extends DateTimeFormattingType { - - /** - * The time must be shown relative to the current time ([in ] X seconds, minutes, hours, days, months, years [ago]). - */ - public DateTimeFormattingTypeRelative() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -648483424; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The date and time must be shown as absolute timestamps. - */ - public static class DateTimeFormattingTypeAbsolute extends DateTimeFormattingType { - /** - * The precision with which hours, minutes and seconds are shown. - */ - public DateTimePartPrecision timePrecision; - /** - * The precision with which the date is shown. - */ - public DateTimePartPrecision datePrecision; - /** - * True, if the day of week must be shown. - */ - public boolean showDayOfWeek; - - /** - * The date and time must be shown as absolute timestamps. - */ - public DateTimeFormattingTypeAbsolute() { - } - - /** - * The date and time must be shown as absolute timestamps. - * - * @param timePrecision The precision with which hours, minutes and seconds are shown. - * @param datePrecision The precision with which the date is shown. - * @param showDayOfWeek True, if the day of week must be shown. - */ - public DateTimeFormattingTypeAbsolute(DateTimePartPrecision timePrecision, DateTimePartPrecision datePrecision, boolean showDayOfWeek) { - this.timePrecision = timePrecision; - this.datePrecision = datePrecision; - this.showDayOfWeek = showDayOfWeek; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 47463317; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes precision with which to show a date or a time. - */ - public abstract static class DateTimePartPrecision extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - DateTimePartPrecisionNone.CONSTRUCTOR, - DateTimePartPrecisionShort.CONSTRUCTOR, - DateTimePartPrecisionLong.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public DateTimePartPrecision() { - } - } - - /** - * Don't show the date or time. - */ - public static class DateTimePartPrecisionNone extends DateTimePartPrecision { - - /** - * Don't show the date or time. - */ - public DateTimePartPrecisionNone() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1790302111; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Show the date or time in a short way (17.03.22 or 22:45). - */ - public static class DateTimePartPrecisionShort extends DateTimePartPrecision { - - /** - * Show the date or time in a short way (17.03.22 or 22:45). - */ - public DateTimePartPrecisionShort() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1290158159; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Show the date or time in a long way (March 17, 2022 or 22:45:00.) - */ - public static class DateTimePartPrecisionLong extends DateTimePartPrecision { - - /** - * Show the date or time in a long way (March 17, 2022 or 22:45:00.) - */ - public DateTimePartPrecisionLong() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -105378824; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * File with the date it was uploaded. - */ - public static class DatedFile extends Object { - /** - * The file. - */ - public File file; - /** - * Point in time (Unix timestamp) when the file was uploaded. - */ - public int date; - - /** - * File with the date it was uploaded. - */ - public DatedFile() { - } - - /** - * File with the date it was uploaded. - * - * @param file The file. - * @param date Point in time (Unix timestamp) when the file was uploaded. - */ - public DatedFile(File file, int date) { - this.file = file; - this.date = date; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1840795491; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a tg: deep link. - */ - public static class DeepLinkInfo extends Object { - /** - * Text to be shown to the user. - */ - public FormattedText text; - /** - * True, if the user must be asked to update the application. - */ - public boolean needUpdateApplication; - - /** - * Contains information about a tg: deep link. - */ - public DeepLinkInfo() { - } - - /** - * Contains information about a tg: deep link. - * - * @param text Text to be shown to the user. - * @param needUpdateApplication True, if the user must be asked to update the application. - */ - public DeepLinkInfo(FormattedText text, boolean needUpdateApplication) { - this.text = text; - this.needUpdateApplication = needUpdateApplication; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1864081662; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents a data needed to subscribe for push notifications through registerDevice method. To use specific push notification service, the correct application platform must be specified and a valid server authentication data must be uploaded at https://my.telegram.org. - */ - public abstract static class DeviceToken extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - DeviceTokenFirebaseCloudMessaging.CONSTRUCTOR, - DeviceTokenApplePush.CONSTRUCTOR, - DeviceTokenApplePushVoIP.CONSTRUCTOR, - DeviceTokenWindowsPush.CONSTRUCTOR, - DeviceTokenMicrosoftPush.CONSTRUCTOR, - DeviceTokenMicrosoftPushVoIP.CONSTRUCTOR, - DeviceTokenWebPush.CONSTRUCTOR, - DeviceTokenSimplePush.CONSTRUCTOR, - DeviceTokenUbuntuPush.CONSTRUCTOR, - DeviceTokenBlackBerryPush.CONSTRUCTOR, - DeviceTokenTizenPush.CONSTRUCTOR, - DeviceTokenHuaweiPush.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public DeviceToken() { - } - } - - /** - * A token for Firebase Cloud Messaging. - */ - public static class DeviceTokenFirebaseCloudMessaging extends DeviceToken { - /** - * Device registration token; may be empty to deregister a device. - */ - public String token; - /** - * True, if push notifications must be additionally encrypted. - */ - public boolean encrypt; - - /** - * A token for Firebase Cloud Messaging. - */ - public DeviceTokenFirebaseCloudMessaging() { - } - - /** - * A token for Firebase Cloud Messaging. - * - * @param token Device registration token; may be empty to deregister a device. - * @param encrypt True, if push notifications must be additionally encrypted. - */ - public DeviceTokenFirebaseCloudMessaging(String token, boolean encrypt) { - this.token = token; - this.encrypt = encrypt; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -797881849; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A token for Apple Push Notification service. - */ - public static class DeviceTokenApplePush extends DeviceToken { - /** - * Device token; may be empty to deregister a device. - */ - public String deviceToken; - /** - * True, if App Sandbox is enabled. - */ - public boolean isAppSandbox; - - /** - * A token for Apple Push Notification service. - */ - public DeviceTokenApplePush() { - } - - /** - * A token for Apple Push Notification service. - * - * @param deviceToken Device token; may be empty to deregister a device. - * @param isAppSandbox True, if App Sandbox is enabled. - */ - public DeviceTokenApplePush(String deviceToken, boolean isAppSandbox) { - this.deviceToken = deviceToken; - this.isAppSandbox = isAppSandbox; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 387541955; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A token for Apple Push Notification service VoIP notifications. - */ - public static class DeviceTokenApplePushVoIP extends DeviceToken { - /** - * Device token; may be empty to deregister a device. - */ - public String deviceToken; - /** - * True, if App Sandbox is enabled. - */ - public boolean isAppSandbox; - /** - * True, if push notifications must be additionally encrypted. - */ - public boolean encrypt; - - /** - * A token for Apple Push Notification service VoIP notifications. - */ - public DeviceTokenApplePushVoIP() { - } - - /** - * A token for Apple Push Notification service VoIP notifications. - * - * @param deviceToken Device token; may be empty to deregister a device. - * @param isAppSandbox True, if App Sandbox is enabled. - * @param encrypt True, if push notifications must be additionally encrypted. - */ - public DeviceTokenApplePushVoIP(String deviceToken, boolean isAppSandbox, boolean encrypt) { - this.deviceToken = deviceToken; - this.isAppSandbox = isAppSandbox; - this.encrypt = encrypt; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 804275689; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A token for Windows Push Notification Services. - */ - public static class DeviceTokenWindowsPush extends DeviceToken { - /** - * The access token that will be used to send notifications; may be empty to deregister a device. - */ - public String accessToken; - - /** - * A token for Windows Push Notification Services. - */ - public DeviceTokenWindowsPush() { - } - - /** - * A token for Windows Push Notification Services. - * - * @param accessToken The access token that will be used to send notifications; may be empty to deregister a device. - */ - public DeviceTokenWindowsPush(String accessToken) { - this.accessToken = accessToken; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1410514289; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A token for Microsoft Push Notification Service. - */ - public static class DeviceTokenMicrosoftPush extends DeviceToken { - /** - * Push notification channel URI; may be empty to deregister a device. - */ - public String channelUri; - - /** - * A token for Microsoft Push Notification Service. - */ - public DeviceTokenMicrosoftPush() { - } - - /** - * A token for Microsoft Push Notification Service. - * - * @param channelUri Push notification channel URI; may be empty to deregister a device. - */ - public DeviceTokenMicrosoftPush(String channelUri) { - this.channelUri = channelUri; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1224269900; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A token for Microsoft Push Notification Service VoIP channel. - */ - public static class DeviceTokenMicrosoftPushVoIP extends DeviceToken { - /** - * Push notification channel URI; may be empty to deregister a device. - */ - public String channelUri; - - /** - * A token for Microsoft Push Notification Service VoIP channel. - */ - public DeviceTokenMicrosoftPushVoIP() { - } - - /** - * A token for Microsoft Push Notification Service VoIP channel. - * - * @param channelUri Push notification channel URI; may be empty to deregister a device. - */ - public DeviceTokenMicrosoftPushVoIP(String channelUri) { - this.channelUri = channelUri; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -785603759; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A token for web Push API. - */ - public static class DeviceTokenWebPush extends DeviceToken { - /** - * Absolute URL exposed by the push service where the application server can send push messages; may be empty to deregister a device. - */ - public String endpoint; - /** - * Base64url-encoded P-256 elliptic curve Diffie-Hellman public key. - */ - public String p256dhBase64url; - /** - * Base64url-encoded authentication secret. - */ - public String authBase64url; - - /** - * A token for web Push API. - */ - public DeviceTokenWebPush() { - } - - /** - * A token for web Push API. - * - * @param endpoint Absolute URL exposed by the push service where the application server can send push messages; may be empty to deregister a device. - * @param p256dhBase64url Base64url-encoded P-256 elliptic curve Diffie-Hellman public key. - * @param authBase64url Base64url-encoded authentication secret. - */ - public DeviceTokenWebPush(String endpoint, String p256dhBase64url, String authBase64url) { - this.endpoint = endpoint; - this.p256dhBase64url = p256dhBase64url; - this.authBase64url = authBase64url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1694507273; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A token for Simple Push API for Firefox OS. - */ - public static class DeviceTokenSimplePush extends DeviceToken { - /** - * Absolute URL exposed by the push service where the application server can send push messages; may be empty to deregister a device. - */ - public String endpoint; - - /** - * A token for Simple Push API for Firefox OS. - */ - public DeviceTokenSimplePush() { - } - - /** - * A token for Simple Push API for Firefox OS. - * - * @param endpoint Absolute URL exposed by the push service where the application server can send push messages; may be empty to deregister a device. - */ - public DeviceTokenSimplePush(String endpoint) { - this.endpoint = endpoint; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 49584736; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A token for Ubuntu Push Client service. - */ - public static class DeviceTokenUbuntuPush extends DeviceToken { - /** - * Token; may be empty to deregister a device. - */ - public String token; - - /** - * A token for Ubuntu Push Client service. - */ - public DeviceTokenUbuntuPush() { - } - - /** - * A token for Ubuntu Push Client service. - * - * @param token Token; may be empty to deregister a device. - */ - public DeviceTokenUbuntuPush(String token) { - this.token = token; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1782320422; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A token for BlackBerry Push Service. - */ - public static class DeviceTokenBlackBerryPush extends DeviceToken { - /** - * Token; may be empty to deregister a device. - */ - public String token; - - /** - * A token for BlackBerry Push Service. - */ - public DeviceTokenBlackBerryPush() { - } - - /** - * A token for BlackBerry Push Service. - * - * @param token Token; may be empty to deregister a device. - */ - public DeviceTokenBlackBerryPush(String token) { - this.token = token; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1559167234; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A token for Tizen Push Service. - */ - public static class DeviceTokenTizenPush extends DeviceToken { - /** - * Push service registration identifier; may be empty to deregister a device. - */ - public String regId; - - /** - * A token for Tizen Push Service. - */ - public DeviceTokenTizenPush() { - } - - /** - * A token for Tizen Push Service. - * - * @param regId Push service registration identifier; may be empty to deregister a device. - */ - public DeviceTokenTizenPush(String regId) { - this.regId = regId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1359947213; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A token for HUAWEI Push Service. - */ - public static class DeviceTokenHuaweiPush extends DeviceToken { - /** - * Device registration token; may be empty to deregister a device. - */ - public String token; - /** - * True, if push notifications must be additionally encrypted. - */ - public boolean encrypt; - - /** - * A token for HUAWEI Push Service. - */ - public DeviceTokenHuaweiPush() { - } - - /** - * A token for HUAWEI Push Service. - * - * @param token Device registration token; may be empty to deregister a device. - * @param encrypt True, if push notifications must be additionally encrypted. - */ - public DeviceTokenHuaweiPush(String token, boolean encrypt) { - this.token = token; - this.encrypt = encrypt; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1989103142; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains animated stickers which must be used for dice animation rendering. - */ - public abstract static class DiceStickers extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - DiceStickersRegular.CONSTRUCTOR, - DiceStickersSlotMachine.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public DiceStickers() { - } - } - - /** - * A regular animated sticker. - */ - public static class DiceStickersRegular extends DiceStickers { - /** - * The animated sticker with the dice animation. - */ - public Sticker sticker; - - /** - * A regular animated sticker. - */ - public DiceStickersRegular() { - } - - /** - * A regular animated sticker. - * - * @param sticker The animated sticker with the dice animation. - */ - public DiceStickersRegular(Sticker sticker) { - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -740299570; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Animated stickers to be combined into a slot machine. - */ - public static class DiceStickersSlotMachine extends DiceStickers { - /** - * The animated sticker with the slot machine background. The background animation must start playing after all reel animations finish. - */ - public Sticker background; - /** - * The animated sticker with the lever animation. The lever animation must play once in the initial dice state. - */ - public Sticker lever; - /** - * The animated sticker with the left reel. - */ - public Sticker leftReel; - /** - * The animated sticker with the center reel. - */ - public Sticker centerReel; - /** - * The animated sticker with the right reel. - */ - public Sticker rightReel; - - /** - * Animated stickers to be combined into a slot machine. - */ - public DiceStickersSlotMachine() { - } - - /** - * Animated stickers to be combined into a slot machine. - * - * @param background The animated sticker with the slot machine background. The background animation must start playing after all reel animations finish. - * @param lever The animated sticker with the lever animation. The lever animation must play once in the initial dice state. - * @param leftReel The animated sticker with the left reel. - * @param centerReel The animated sticker with the center reel. - * @param rightReel The animated sticker with the right reel. - */ - public DiceStickersSlotMachine(Sticker background, Sticker lever, Sticker leftReel, Sticker centerReel, Sticker rightReel) { - this.background = background; - this.lever = lever; - this.leftReel = leftReel; - this.centerReel = centerReel; - this.rightReel = rightReel; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -375223124; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a topic in a channel direct messages chat administered by the current user. - */ - public static class DirectMessagesChatTopic extends Object { - /** - * Identifier of the chat to which the topic belongs. - */ - public long chatId; - /** - * Unique topic identifier. - */ - public long id; - /** - * Identifier of the user or chat that sends the messages to the topic. - */ - public MessageSender senderId; - /** - * A parameter used to determine order of the topic in the topic list. Topics must be sorted by the order in descending order. - */ - public long order; - /** - * True, if the other party can send unpaid messages even if the chat has paid messages enabled. - */ - public boolean canSendUnpaidMessages; - /** - * True, if the topic is marked as unread. - */ - public boolean isMarkedAsUnread; - /** - * Number of unread messages in the chat. - */ - public long unreadCount; - /** - * Identifier of the last read incoming message. - */ - public long lastReadInboxMessageId; - /** - * Identifier of the last read outgoing message. - */ - public long lastReadOutboxMessageId; - /** - * Number of messages with unread reactions in the chat. - */ - public long unreadReactionCount; - /** - * Last message in the topic; may be null if none or unknown. - */ - @Nullable public Message lastMessage; - /** - * A draft of a message in the topic; may be null if none. - */ - @Nullable public DraftMessage draftMessage; - - /** - * Contains information about a topic in a channel direct messages chat administered by the current user. - */ - public DirectMessagesChatTopic() { - } - - /** - * Contains information about a topic in a channel direct messages chat administered by the current user. - * - * @param chatId Identifier of the chat to which the topic belongs. - * @param id Unique topic identifier. - * @param senderId Identifier of the user or chat that sends the messages to the topic. - * @param order A parameter used to determine order of the topic in the topic list. Topics must be sorted by the order in descending order. - * @param canSendUnpaidMessages True, if the other party can send unpaid messages even if the chat has paid messages enabled. - * @param isMarkedAsUnread True, if the topic is marked as unread. - * @param unreadCount Number of unread messages in the chat. - * @param lastReadInboxMessageId Identifier of the last read incoming message. - * @param lastReadOutboxMessageId Identifier of the last read outgoing message. - * @param unreadReactionCount Number of messages with unread reactions in the chat. - * @param lastMessage Last message in the topic; may be null if none or unknown. - * @param draftMessage A draft of a message in the topic; may be null if none. - */ - public DirectMessagesChatTopic(long chatId, long id, MessageSender senderId, long order, boolean canSendUnpaidMessages, boolean isMarkedAsUnread, long unreadCount, long lastReadInboxMessageId, long lastReadOutboxMessageId, long unreadReactionCount, Message lastMessage, DraftMessage draftMessage) { - this.chatId = chatId; - this.id = id; - this.senderId = senderId; - this.order = order; - this.canSendUnpaidMessages = canSendUnpaidMessages; - this.isMarkedAsUnread = isMarkedAsUnread; - this.unreadCount = unreadCount; - this.lastReadInboxMessageId = lastReadInboxMessageId; - this.lastReadOutboxMessageId = lastReadOutboxMessageId; - this.unreadReactionCount = unreadReactionCount; - this.lastMessage = lastMessage; - this.draftMessage = draftMessage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1778377757; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a document of any type. - */ - public static class Document extends Object { - /** - * Original name of the file; as defined by the sender. - */ - public String fileName; - /** - * MIME type of the file; as defined by the sender. - */ - public String mimeType; - /** - * Document minithumbnail; may be null. - */ - @Nullable public Minithumbnail minithumbnail; - /** - * Document thumbnail in JPEG or PNG format (PNG will be used only for background patterns); as defined by the sender; may be null. - */ - @Nullable public Thumbnail thumbnail; - /** - * File containing the document. - */ - public File document; - - /** - * Describes a document of any type. - */ - public Document() { - } - - /** - * Describes a document of any type. - * - * @param fileName Original name of the file; as defined by the sender. - * @param mimeType MIME type of the file; as defined by the sender. - * @param minithumbnail Document minithumbnail; may be null. - * @param thumbnail Document thumbnail in JPEG or PNG format (PNG will be used only for background patterns); as defined by the sender; may be null. - * @param document File containing the document. - */ - public Document(String fileName, String mimeType, Minithumbnail minithumbnail, Thumbnail thumbnail, File document) { - this.fileName = fileName; - this.mimeType = mimeType; - this.minithumbnail = minithumbnail; - this.thumbnail = thumbnail; - this.document = document; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1357271080; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains number of being downloaded and recently downloaded files found. - */ - public static class DownloadedFileCounts extends Object { - /** - * Number of active file downloads found, including paused. - */ - public int activeCount; - /** - * Number of paused file downloads found. - */ - public int pausedCount; - /** - * Number of completed file downloads found. - */ - public int completedCount; - - /** - * Contains number of being downloaded and recently downloaded files found. - */ - public DownloadedFileCounts() { - } - - /** - * Contains number of being downloaded and recently downloaded files found. - * - * @param activeCount Number of active file downloads found, including paused. - * @param pausedCount Number of paused file downloads found. - * @param completedCount Number of completed file downloads found. - */ - public DownloadedFileCounts(int activeCount, int pausedCount, int completedCount) { - this.activeCount = activeCount; - this.pausedCount = pausedCount; - this.completedCount = completedCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1973999550; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a message draft. - */ - public static class DraftMessage extends Object { - /** - * Information about the message to be replied; inputMessageReplyToStory is unsupported; may be null if none. - */ - @Nullable public InputMessageReplyTo replyTo; - /** - * Point in time (Unix timestamp) when the draft was created. - */ - public int date; - /** - * Content of the message draft; must be of the type inputMessageText, inputMessageVideoNote, or inputMessageVoiceNote. - */ - public InputMessageContent inputMessageText; - /** - * Identifier of the effect to apply to the message when it is sent; 0 if none. - */ - public long effectId; - /** - * Information about the suggested post; may be null if none. - */ - @Nullable public InputSuggestedPostInfo suggestedPostInfo; - - /** - * Contains information about a message draft. - */ - public DraftMessage() { - } - - /** - * Contains information about a message draft. - * - * @param replyTo Information about the message to be replied; inputMessageReplyToStory is unsupported; may be null if none. - * @param date Point in time (Unix timestamp) when the draft was created. - * @param inputMessageText Content of the message draft; must be of the type inputMessageText, inputMessageVideoNote, or inputMessageVoiceNote. - * @param effectId Identifier of the effect to apply to the message when it is sent; 0 if none. - * @param suggestedPostInfo Information about the suggested post; may be null if none. - */ - public DraftMessage(InputMessageReplyTo replyTo, int date, InputMessageContent inputMessageText, long effectId, InputSuggestedPostInfo suggestedPostInfo) { - this.replyTo = replyTo; - this.date = date; - this.inputMessageText = inputMessageText; - this.effectId = effectId; - this.suggestedPostInfo = suggestedPostInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1165040650; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains authentication data for an email address. - */ - public abstract static class EmailAddressAuthentication extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - EmailAddressAuthenticationCode.CONSTRUCTOR, - EmailAddressAuthenticationAppleId.CONSTRUCTOR, - EmailAddressAuthenticationGoogleId.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public EmailAddressAuthentication() { - } - } - - /** - * An authentication code delivered to a user's email address. - */ - public static class EmailAddressAuthenticationCode extends EmailAddressAuthentication { - /** - * The code. - */ - public String code; - - /** - * An authentication code delivered to a user's email address. - */ - public EmailAddressAuthenticationCode() { - } - - /** - * An authentication code delivered to a user's email address. - * - * @param code The code. - */ - public EmailAddressAuthenticationCode(String code) { - this.code = code; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -993257022; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An authentication token received through Apple ID. - */ - public static class EmailAddressAuthenticationAppleId extends EmailAddressAuthentication { - /** - * The token. - */ - public String token; - - /** - * An authentication token received through Apple ID. - */ - public EmailAddressAuthenticationAppleId() { - } - - /** - * An authentication token received through Apple ID. - * - * @param token The token. - */ - public EmailAddressAuthenticationAppleId(String token) { - this.token = token; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 633948265; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An authentication token received through Google ID. - */ - public static class EmailAddressAuthenticationGoogleId extends EmailAddressAuthentication { - /** - * The token. - */ - public String token; - - /** - * An authentication token received through Google ID. - */ - public EmailAddressAuthenticationGoogleId() { - } - - /** - * An authentication token received through Google ID. - * - * @param token The token. - */ - public EmailAddressAuthenticationGoogleId(String token) { - this.token = token; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -19142846; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Information about the email address authentication code that was sent. - */ - public static class EmailAddressAuthenticationCodeInfo extends Object { - /** - * Pattern of the email address to which an authentication code was sent. - */ - public String emailAddressPattern; - /** - * Length of the code; 0 if unknown. - */ - public int length; - - /** - * Information about the email address authentication code that was sent. - */ - public EmailAddressAuthenticationCodeInfo() { - } - - /** - * Information about the email address authentication code that was sent. - * - * @param emailAddressPattern Pattern of the email address to which an authentication code was sent. - * @param length Length of the code; 0 if unknown. - */ - public EmailAddressAuthenticationCodeInfo(String emailAddressPattern, int length) { - this.emailAddressPattern = emailAddressPattern; - this.length = length; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1151066659; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes reset state of an email address. - */ - public abstract static class EmailAddressResetState extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - EmailAddressResetStateAvailable.CONSTRUCTOR, - EmailAddressResetStatePending.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public EmailAddressResetState() { - } - } - - /** - * Email address can be reset after the given period. Call resetAuthenticationEmailAddress to reset it and allow the user to authorize with a code sent to the user's phone number. - */ - public static class EmailAddressResetStateAvailable extends EmailAddressResetState { - /** - * Time required to wait before the email address can be reset; 0 if the user is subscribed to Telegram Premium. - */ - public int waitPeriod; - - /** - * Email address can be reset after the given period. Call resetAuthenticationEmailAddress to reset it and allow the user to authorize with a code sent to the user's phone number. - */ - public EmailAddressResetStateAvailable() { - } - - /** - * Email address can be reset after the given period. Call resetAuthenticationEmailAddress to reset it and allow the user to authorize with a code sent to the user's phone number. - * - * @param waitPeriod Time required to wait before the email address can be reset; 0 if the user is subscribed to Telegram Premium. - */ - public EmailAddressResetStateAvailable(int waitPeriod) { - this.waitPeriod = waitPeriod; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1917177600; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Email address reset has already been requested. Call resetAuthenticationEmailAddress to check whether immediate reset is possible. - */ - public static class EmailAddressResetStatePending extends EmailAddressResetState { - /** - * Left time before the email address will be reset, in seconds. updateAuthorizationState is not sent when this field changes. - */ - public int resetIn; - - /** - * Email address reset has already been requested. Call resetAuthenticationEmailAddress to check whether immediate reset is possible. - */ - public EmailAddressResetStatePending() { - } - - /** - * Email address reset has already been requested. Call resetAuthenticationEmailAddress to check whether immediate reset is possible. - * - * @param resetIn Left time before the email address will be reset, in seconds. updateAuthorizationState is not sent when this field changes. - */ - public EmailAddressResetStatePending(int resetIn) { - this.resetIn = resetIn; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1885966805; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of emoji categories. - */ - public static class EmojiCategories extends Object { - /** - * List of categories. - */ - public EmojiCategory[] categories; - - /** - * Represents a list of emoji categories. - */ - public EmojiCategories() { - } - - /** - * Represents a list of emoji categories. - * - * @param categories List of categories. - */ - public EmojiCategories(EmojiCategory[] categories) { - this.categories = categories; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1455387824; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an emoji category. - */ - public static class EmojiCategory extends Object { - /** - * Name of the category. - */ - public String name; - /** - * Custom emoji sticker, which represents icon of the category. - */ - public Sticker icon; - /** - * Source of stickers for the emoji category. - */ - public EmojiCategorySource source; - /** - * True, if the category must be shown first when choosing a sticker for the start page. - */ - public boolean isGreeting; - - /** - * Describes an emoji category. - */ - public EmojiCategory() { - } - - /** - * Describes an emoji category. - * - * @param name Name of the category. - * @param icon Custom emoji sticker, which represents icon of the category. - * @param source Source of stickers for the emoji category. - * @param isGreeting True, if the category must be shown first when choosing a sticker for the start page. - */ - public EmojiCategory(String name, Sticker icon, EmojiCategorySource source, boolean isGreeting) { - this.name = name; - this.icon = icon; - this.source = source; - this.isGreeting = isGreeting; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 571335919; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes source of stickers for an emoji category. - */ - public abstract static class EmojiCategorySource extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - EmojiCategorySourceSearch.CONSTRUCTOR, - EmojiCategorySourcePremium.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public EmojiCategorySource() { - } - } - - /** - * The category contains a list of similar emoji to search for in getStickers and searchStickers for stickers, or getInlineQueryResults with the bot getOption("animation_search_bot_username") for animations. - */ - public static class EmojiCategorySourceSearch extends EmojiCategorySource { - /** - * List of emojis to search for. - */ - public String[] emojis; - - /** - * The category contains a list of similar emoji to search for in getStickers and searchStickers for stickers, or getInlineQueryResults with the bot getOption("animation_search_bot_username") for animations. - */ - public EmojiCategorySourceSearch() { - } - - /** - * The category contains a list of similar emoji to search for in getStickers and searchStickers for stickers, or getInlineQueryResults with the bot getOption("animation_search_bot_username") for animations. - * - * @param emojis List of emojis to search for. - */ - public EmojiCategorySourceSearch(String[] emojis) { - this.emojis = emojis; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -453260262; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The category contains premium stickers that must be found by getPremiumStickers. - */ - public static class EmojiCategorySourcePremium extends EmojiCategorySource { - - /** - * The category contains premium stickers that must be found by getPremiumStickers. - */ - public EmojiCategorySourcePremium() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1932358388; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of emoji category. - */ - public abstract static class EmojiCategoryType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - EmojiCategoryTypeDefault.CONSTRUCTOR, - EmojiCategoryTypeRegularStickers.CONSTRUCTOR, - EmojiCategoryTypeEmojiStatus.CONSTRUCTOR, - EmojiCategoryTypeChatPhoto.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public EmojiCategoryType() { - } - } - - /** - * The category must be used by default (e.g., for custom emoji or animation search). - */ - public static class EmojiCategoryTypeDefault extends EmojiCategoryType { - - /** - * The category must be used by default (e.g., for custom emoji or animation search). - */ - public EmojiCategoryTypeDefault() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1188782699; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The category must be used by default for regular sticker selection. It may contain greeting emoji category and premium stickers. - */ - public static class EmojiCategoryTypeRegularStickers extends EmojiCategoryType { - - /** - * The category must be used by default for regular sticker selection. It may contain greeting emoji category and premium stickers. - */ - public EmojiCategoryTypeRegularStickers() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1337484846; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The category must be used for emoji status selection. - */ - public static class EmojiCategoryTypeEmojiStatus extends EmojiCategoryType { - - /** - * The category must be used for emoji status selection. - */ - public EmojiCategoryTypeEmojiStatus() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1381282631; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The category must be used for chat photo emoji selection. - */ - public static class EmojiCategoryTypeChatPhoto extends EmojiCategoryType { - - /** - * The category must be used for chat photo emoji selection. - */ - public EmojiCategoryTypeChatPhoto() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1059063081; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a chat theme based on an emoji. - */ - public static class EmojiChatTheme extends Object { - /** - * Theme name. - */ - public String name; - /** - * Theme settings for a light chat theme. - */ - public ThemeSettings lightSettings; - /** - * Theme settings for a dark chat theme. - */ - public ThemeSettings darkSettings; - - /** - * Describes a chat theme based on an emoji. - */ - public EmojiChatTheme() { - } - - /** - * Describes a chat theme based on an emoji. - * - * @param name Theme name. - * @param lightSettings Theme settings for a light chat theme. - * @param darkSettings Theme settings for a dark chat theme. - */ - public EmojiChatTheme(String name, ThemeSettings lightSettings, ThemeSettings darkSettings) { - this.name = name; - this.lightSettings = lightSettings; - this.darkSettings = darkSettings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -329422882; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents an emoji with its keyword. - */ - public static class EmojiKeyword extends Object { - /** - * The emoji. - */ - public String emoji; - /** - * The keyword. - */ - public String keyword; - - /** - * Represents an emoji with its keyword. - */ - public EmojiKeyword() { - } - - /** - * Represents an emoji with its keyword. - * - * @param emoji The emoji. - * @param keyword The keyword. - */ - public EmojiKeyword(String emoji, String keyword) { - this.emoji = emoji; - this.keyword = keyword; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2112285985; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of emojis with their keywords. - */ - public static class EmojiKeywords extends Object { - /** - * List of emojis with their keywords. - */ - public EmojiKeyword[] emojiKeywords; - - /** - * Represents a list of emojis with their keywords. - */ - public EmojiKeywords() { - } - - /** - * Represents a list of emojis with their keywords. - * - * @param emojiKeywords List of emojis with their keywords. - */ - public EmojiKeywords(EmojiKeyword[] emojiKeywords) { - this.emojiKeywords = emojiKeywords; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 689723339; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about an emoji reaction. - */ - public static class EmojiReaction extends Object { - /** - * Text representation of the reaction. - */ - public String emoji; - /** - * Reaction title. - */ - public String title; - /** - * True, if the reaction can be added to new messages and enabled in chats. - */ - public boolean isActive; - /** - * Static icon for the reaction. - */ - public Sticker staticIcon; - /** - * Appear animation for the reaction. - */ - public Sticker appearAnimation; - /** - * Select animation for the reaction. - */ - public Sticker selectAnimation; - /** - * Activate animation for the reaction. - */ - public Sticker activateAnimation; - /** - * Effect animation for the reaction. - */ - public Sticker effectAnimation; - /** - * Around animation for the reaction; may be null. - */ - @Nullable public Sticker aroundAnimation; - /** - * Center animation for the reaction; may be null. - */ - @Nullable public Sticker centerAnimation; - - /** - * Contains information about an emoji reaction. - */ - public EmojiReaction() { - } - - /** - * Contains information about an emoji reaction. - * - * @param emoji Text representation of the reaction. - * @param title Reaction title. - * @param isActive True, if the reaction can be added to new messages and enabled in chats. - * @param staticIcon Static icon for the reaction. - * @param appearAnimation Appear animation for the reaction. - * @param selectAnimation Select animation for the reaction. - * @param activateAnimation Activate animation for the reaction. - * @param effectAnimation Effect animation for the reaction. - * @param aroundAnimation Around animation for the reaction; may be null. - * @param centerAnimation Center animation for the reaction; may be null. - */ - public EmojiReaction(String emoji, String title, boolean isActive, Sticker staticIcon, Sticker appearAnimation, Sticker selectAnimation, Sticker activateAnimation, Sticker effectAnimation, Sticker aroundAnimation, Sticker centerAnimation) { - this.emoji = emoji; - this.title = title; - this.isActive = isActive; - this.staticIcon = staticIcon; - this.appearAnimation = appearAnimation; - this.selectAnimation = selectAnimation; - this.activateAnimation = activateAnimation; - this.effectAnimation = effectAnimation; - this.aroundAnimation = aroundAnimation; - this.centerAnimation = centerAnimation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1616063583; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an emoji to be shown instead of the Telegram Premium badge. - */ - public static class EmojiStatus extends Object { - /** - * Type of the emoji status. - */ - public EmojiStatusType type; - /** - * Point in time (Unix timestamp) when the status will expire; 0 if never. - */ - public int expirationDate; - - /** - * Describes an emoji to be shown instead of the Telegram Premium badge. - */ - public EmojiStatus() { - } - - /** - * Describes an emoji to be shown instead of the Telegram Premium badge. - * - * @param type Type of the emoji status. - * @param expirationDate Point in time (Unix timestamp) when the status will expire; 0 if never. - */ - public EmojiStatus(EmojiStatusType type, int expirationDate) { - this.type = type; - this.expirationDate = expirationDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 973424912; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of custom emoji identifiers for emoji statuses. - */ - public static class EmojiStatusCustomEmojis extends Object { - /** - * The list of custom emoji identifiers. - */ - public long[] customEmojiIds; - - /** - * Contains a list of custom emoji identifiers for emoji statuses. - */ - public EmojiStatusCustomEmojis() { - } - - /** - * Contains a list of custom emoji identifiers for emoji statuses. - * - * @param customEmojiIds The list of custom emoji identifiers. - */ - public EmojiStatusCustomEmojis(long[] customEmojiIds) { - this.customEmojiIds = customEmojiIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 917123337; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of emoji status. - */ - public abstract static class EmojiStatusType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - EmojiStatusTypeCustomEmoji.CONSTRUCTOR, - EmojiStatusTypeUpgradedGift.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public EmojiStatusType() { - } - } - - /** - * A custom emoji set as emoji status. - */ - public static class EmojiStatusTypeCustomEmoji extends EmojiStatusType { - /** - * Identifier of the custom emoji in stickerFormatTgs format. - */ - public long customEmojiId; - - /** - * A custom emoji set as emoji status. - */ - public EmojiStatusTypeCustomEmoji() { - } - - /** - * A custom emoji set as emoji status. - * - * @param customEmojiId Identifier of the custom emoji in stickerFormatTgs format. - */ - public EmojiStatusTypeCustomEmoji(long customEmojiId) { - this.customEmojiId = customEmojiId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1666780939; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An upgraded gift set as emoji status. - */ - public static class EmojiStatusTypeUpgradedGift extends EmojiStatusType { - /** - * Identifier of the upgraded gift. - */ - public long upgradedGiftId; - /** - * The title of the upgraded gift. - */ - public String giftTitle; - /** - * Unique name of the upgraded gift that can be used with internalLinkTypeUpgradedGift. - */ - public String giftName; - /** - * Custom emoji identifier of the model of the upgraded gift. - */ - public long modelCustomEmojiId; - /** - * Custom emoji identifier of the symbol of the upgraded gift. - */ - public long symbolCustomEmojiId; - /** - * Colors of the backdrop of the upgraded gift. - */ - public UpgradedGiftBackdropColors backdropColors; - - /** - * An upgraded gift set as emoji status. - */ - public EmojiStatusTypeUpgradedGift() { - } - - /** - * An upgraded gift set as emoji status. - * - * @param upgradedGiftId Identifier of the upgraded gift. - * @param giftTitle The title of the upgraded gift. - * @param giftName Unique name of the upgraded gift that can be used with internalLinkTypeUpgradedGift. - * @param modelCustomEmojiId Custom emoji identifier of the model of the upgraded gift. - * @param symbolCustomEmojiId Custom emoji identifier of the symbol of the upgraded gift. - * @param backdropColors Colors of the backdrop of the upgraded gift. - */ - public EmojiStatusTypeUpgradedGift(long upgradedGiftId, String giftTitle, String giftName, long modelCustomEmojiId, long symbolCustomEmojiId, UpgradedGiftBackdropColors backdropColors) { - this.upgradedGiftId = upgradedGiftId; - this.giftTitle = giftTitle; - this.giftName = giftName; - this.modelCustomEmojiId = modelCustomEmojiId; - this.symbolCustomEmojiId = symbolCustomEmojiId; - this.backdropColors = backdropColors; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -837921804; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of emoji statuses. - */ - public static class EmojiStatuses extends Object { - /** - * The list of emoji statuses identifiers. - */ - public EmojiStatus[] emojiStatuses; - - /** - * Contains a list of emoji statuses. - */ - public EmojiStatuses() { - } - - /** - * Contains a list of emoji statuses. - * - * @param emojiStatuses The list of emoji statuses identifiers. - */ - public EmojiStatuses(EmojiStatus[] emojiStatuses) { - this.emojiStatuses = emojiStatuses; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1186104146; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of emojis. - */ - public static class Emojis extends Object { - /** - * List of emojis. - */ - public String[] emojis; - - /** - * Represents a list of emojis. - */ - public Emojis() { - } - - /** - * Represents a list of emojis. - * - * @param emojis List of emojis. - */ - public Emojis(String[] emojis) { - this.emojis = emojis; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 950339552; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains encrypted Telegram Passport data credentials. - */ - public static class EncryptedCredentials extends Object { - /** - * The encrypted credentials. - */ - public byte[] data; - /** - * The decrypted data hash. - */ - public byte[] hash; - /** - * Secret for data decryption, encrypted with the service's public key. - */ - public byte[] secret; - - /** - * Contains encrypted Telegram Passport data credentials. - */ - public EncryptedCredentials() { - } - - /** - * Contains encrypted Telegram Passport data credentials. - * - * @param data The encrypted credentials. - * @param hash The decrypted data hash. - * @param secret Secret for data decryption, encrypted with the service's public key. - */ - public EncryptedCredentials(byte[] data, byte[] hash, byte[] secret) { - this.data = data; - this.hash = hash; - this.secret = secret; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1331106766; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about an encrypted Telegram Passport element; for bots only. - */ - public static class EncryptedPassportElement extends Object { - /** - * Type of Telegram Passport element. - */ - public PassportElementType type; - /** - * Encrypted JSON-encoded data about the user. - */ - public byte[] data; - /** - * The front side of an identity document. - */ - public DatedFile frontSide; - /** - * The reverse side of an identity document; may be null. - */ - @Nullable public DatedFile reverseSide; - /** - * Selfie with the document; may be null. - */ - @Nullable public DatedFile selfie; - /** - * List of files containing a certified English translation of the document. - */ - public DatedFile[] translation; - /** - * List of attached files. - */ - public DatedFile[] files; - /** - * Unencrypted data, phone number or email address. - */ - public String value; - /** - * Hash of the entire element. - */ - public String hash; - - /** - * Contains information about an encrypted Telegram Passport element; for bots only. - */ - public EncryptedPassportElement() { - } - - /** - * Contains information about an encrypted Telegram Passport element; for bots only. - * - * @param type Type of Telegram Passport element. - * @param data Encrypted JSON-encoded data about the user. - * @param frontSide The front side of an identity document. - * @param reverseSide The reverse side of an identity document; may be null. - * @param selfie Selfie with the document; may be null. - * @param translation List of files containing a certified English translation of the document. - * @param files List of attached files. - * @param value Unencrypted data, phone number or email address. - * @param hash Hash of the entire element. - */ - public EncryptedPassportElement(PassportElementType type, byte[] data, DatedFile frontSide, DatedFile reverseSide, DatedFile selfie, DatedFile[] translation, DatedFile[] files, String value, String hash) { - this.type = type; - this.data = data; - this.frontSide = frontSide; - this.reverseSide = reverseSide; - this.selfie = selfie; - this.translation = translation; - this.files = files; - this.value = value; - this.hash = hash; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2002386193; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An object of this type can be returned on every function call, in case of an error. - */ - public static class Error extends Object { - /** - * Error code; subject to future changes. If the error code is 406, the error message must not be processed in any way and must not be displayed to the user. - */ - public int code; - /** - * Error message; subject to future changes. - */ - public String message; - - /** - * An object of this type can be returned on every function call, in case of an error. - */ - public Error() { - } - - /** - * An object of this type can be returned on every function call, in case of an error. - * - * @param code Error code; subject to future changes. If the error code is 406, the error message must not be processed in any way and must not be displayed to the user. - * @param message Error message; subject to future changes. - */ - public Error(int code, String message) { - this.code = code; - this.message = message; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1679978726; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a fact-check added to the message by an independent checker. - */ - public static class FactCheck extends Object { - /** - * Text of the fact-check. - */ - public FormattedText text; - /** - * A two-letter ISO 3166-1 alpha-2 country code of the country for which the fact-check is shown. - */ - public String countryCode; - - /** - * Describes a fact-check added to the message by an independent checker. - */ - public FactCheck() { - } - - /** - * Describes a fact-check added to the message by an independent checker. - * - * @param text Text of the fact-check. - * @param countryCode A two-letter ISO 3166-1 alpha-2 country code of the country for which the fact-check is shown. - */ - public FactCheck(FormattedText text, String countryCode) { - this.text = text; - this.countryCode = countryCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1048184552; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a user who has failed to be added to a chat. - */ - public static class FailedToAddMember extends Object { - /** - * User identifier. - */ - public long userId; - /** - * True, if subscription to Telegram Premium would have allowed to add the user to the chat. - */ - public boolean premiumWouldAllowInvite; - /** - * True, if subscription to Telegram Premium is required to send the user chat invite link. - */ - public boolean premiumRequiredToSendMessages; - - /** - * Contains information about a user who has failed to be added to a chat. - */ - public FailedToAddMember() { - } - - /** - * Contains information about a user who has failed to be added to a chat. - * - * @param userId User identifier. - * @param premiumWouldAllowInvite True, if subscription to Telegram Premium would have allowed to add the user to the chat. - * @param premiumRequiredToSendMessages True, if subscription to Telegram Premium is required to send the user chat invite link. - */ - public FailedToAddMember(long userId, boolean premiumWouldAllowInvite, boolean premiumRequiredToSendMessages) { - this.userId = userId; - this.premiumWouldAllowInvite = premiumWouldAllowInvite; - this.premiumRequiredToSendMessages = premiumRequiredToSendMessages; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -282891070; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of users that has failed to be added to a chat. - */ - public static class FailedToAddMembers extends Object { - /** - * Information about users that weren't added to the chat. - */ - public FailedToAddMember[] failedToAddMembers; - - /** - * Represents a list of users that has failed to be added to a chat. - */ - public FailedToAddMembers() { - } - - /** - * Represents a list of users that has failed to be added to a chat. - * - * @param failedToAddMembers Information about users that weren't added to the chat. - */ - public FailedToAddMembers(FailedToAddMember[] failedToAddMembers) { - this.failedToAddMembers = failedToAddMembers; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -272587152; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a file. - */ - public static class File extends Object { - /** - * Unique file identifier. - */ - public int id; - /** - * File size, in bytes; 0 if unknown. - */ - public long size; - /** - * Approximate file size in bytes in case the exact file size is unknown. Can be used to show download/upload progress. - */ - public long expectedSize; - /** - * Information about the local copy of the file. - */ - public LocalFile local; - /** - * Information about the remote copy of the file. - */ - public RemoteFile remote; - - /** - * Represents a file. - */ - public File() { - } - - /** - * Represents a file. - * - * @param id Unique file identifier. - * @param size File size, in bytes; 0 if unknown. - * @param expectedSize Approximate file size in bytes in case the exact file size is unknown. Can be used to show download/upload progress. - * @param local Information about the local copy of the file. - * @param remote Information about the remote copy of the file. - */ - public File(int id, long size, long expectedSize, LocalFile local, RemoteFile remote) { - this.id = id; - this.size = size; - this.expectedSize = expectedSize; - this.local = local; - this.remote = remote; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1263291956; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a file added to file download list. - */ - public static class FileDownload extends Object { - /** - * File identifier. - */ - public int fileId; - /** - * The message with the file. - */ - public Message message; - /** - * Point in time (Unix timestamp) when the file was added to the download list. - */ - public int addDate; - /** - * Point in time (Unix timestamp) when the file downloading was completed; 0 if the file downloading isn't completed. - */ - public int completeDate; - /** - * True, if downloading of the file is paused. - */ - public boolean isPaused; - - /** - * Describes a file added to file download list. - */ - public FileDownload() { - } - - /** - * Describes a file added to file download list. - * - * @param fileId File identifier. - * @param message The message with the file. - * @param addDate Point in time (Unix timestamp) when the file was added to the download list. - * @param completeDate Point in time (Unix timestamp) when the file downloading was completed; 0 if the file downloading isn't completed. - * @param isPaused True, if downloading of the file is paused. - */ - public FileDownload(int fileId, Message message, int addDate, int completeDate, boolean isPaused) { - this.fileId = fileId; - this.message = message; - this.addDate = addDate; - this.completeDate = completeDate; - this.isPaused = isPaused; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2092100780; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains size of downloaded prefix of a file. - */ - public static class FileDownloadedPrefixSize extends Object { - /** - * The prefix size, in bytes. - */ - public long size; - - /** - * Contains size of downloaded prefix of a file. - */ - public FileDownloadedPrefixSize() { - } - - /** - * Contains size of downloaded prefix of a file. - * - * @param size The prefix size, in bytes. - */ - public FileDownloadedPrefixSize(long size) { - this.size = size; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2015205381; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents the type of file. - */ - public abstract static class FileType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - FileTypeNone.CONSTRUCTOR, - FileTypeAnimation.CONSTRUCTOR, - FileTypeAudio.CONSTRUCTOR, - FileTypeDocument.CONSTRUCTOR, - FileTypeNotificationSound.CONSTRUCTOR, - FileTypePhoto.CONSTRUCTOR, - FileTypePhotoStory.CONSTRUCTOR, - FileTypeProfilePhoto.CONSTRUCTOR, - FileTypeSecret.CONSTRUCTOR, - FileTypeSecretThumbnail.CONSTRUCTOR, - FileTypeSecure.CONSTRUCTOR, - FileTypeSelfDestructingPhoto.CONSTRUCTOR, - FileTypeSelfDestructingVideo.CONSTRUCTOR, - FileTypeSelfDestructingVideoNote.CONSTRUCTOR, - FileTypeSelfDestructingVoiceNote.CONSTRUCTOR, - FileTypeSticker.CONSTRUCTOR, - FileTypeThumbnail.CONSTRUCTOR, - FileTypeUnknown.CONSTRUCTOR, - FileTypeVideo.CONSTRUCTOR, - FileTypeVideoNote.CONSTRUCTOR, - FileTypeVideoStory.CONSTRUCTOR, - FileTypeVoiceNote.CONSTRUCTOR, - FileTypeWallpaper.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public FileType() { - } - } - - /** - * The data is not a file. - */ - public static class FileTypeNone extends FileType { - - /** - * The data is not a file. - */ - public FileTypeNone() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2003009189; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is an animation. - */ - public static class FileTypeAnimation extends FileType { - - /** - * The file is an animation. - */ - public FileTypeAnimation() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -290816582; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is an audio file. - */ - public static class FileTypeAudio extends FileType { - - /** - * The file is an audio file. - */ - public FileTypeAudio() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -709112160; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a document. - */ - public static class FileTypeDocument extends FileType { - - /** - * The file is a document. - */ - public FileTypeDocument() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -564722929; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a notification sound. - */ - public static class FileTypeNotificationSound extends FileType { - - /** - * The file is a notification sound. - */ - public FileTypeNotificationSound() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1020289271; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a photo. - */ - public static class FileTypePhoto extends FileType { - - /** - * The file is a photo. - */ - public FileTypePhoto() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1718914651; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a photo published as a story. - */ - public static class FileTypePhotoStory extends FileType { - - /** - * The file is a photo published as a story. - */ - public FileTypePhotoStory() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2018995956; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a profile photo. - */ - public static class FileTypeProfilePhoto extends FileType { - - /** - * The file is a profile photo. - */ - public FileTypeProfilePhoto() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1795089315; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file was sent to a secret chat (the file type is not known to the server). - */ - public static class FileTypeSecret extends FileType { - - /** - * The file was sent to a secret chat (the file type is not known to the server). - */ - public FileTypeSecret() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1871899401; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a thumbnail of a file from a secret chat. - */ - public static class FileTypeSecretThumbnail extends FileType { - - /** - * The file is a thumbnail of a file from a secret chat. - */ - public FileTypeSecretThumbnail() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1401326026; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a file from Secure storage used for storing Telegram Passport files. - */ - public static class FileTypeSecure extends FileType { - - /** - * The file is a file from Secure storage used for storing Telegram Passport files. - */ - public FileTypeSecure() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1419133146; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a self-destructing photo in a private chat. - */ - public static class FileTypeSelfDestructingPhoto extends FileType { - - /** - * The file is a self-destructing photo in a private chat. - */ - public FileTypeSelfDestructingPhoto() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2077176475; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a self-destructing video in a private chat. - */ - public static class FileTypeSelfDestructingVideo extends FileType { - - /** - * The file is a self-destructing video in a private chat. - */ - public FileTypeSelfDestructingVideo() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1223900123; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a self-destructing video note in a private chat. - */ - public static class FileTypeSelfDestructingVideoNote extends FileType { - - /** - * The file is a self-destructing video note in a private chat. - */ - public FileTypeSelfDestructingVideoNote() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1495274177; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a self-destructing voice note in a private chat. - */ - public static class FileTypeSelfDestructingVoiceNote extends FileType { - - /** - * The file is a self-destructing voice note in a private chat. - */ - public FileTypeSelfDestructingVoiceNote() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1691409181; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a sticker. - */ - public static class FileTypeSticker extends FileType { - - /** - * The file is a sticker. - */ - public FileTypeSticker() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 475233385; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a thumbnail of another file. - */ - public static class FileTypeThumbnail extends FileType { - - /** - * The file is a thumbnail of another file. - */ - public FileTypeThumbnail() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -12443298; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file type is not yet known. - */ - public static class FileTypeUnknown extends FileType { - - /** - * The file type is not yet known. - */ - public FileTypeUnknown() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2011566768; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a video. - */ - public static class FileTypeVideo extends FileType { - - /** - * The file is a video. - */ - public FileTypeVideo() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1430816539; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a video note. - */ - public static class FileTypeVideoNote extends FileType { - - /** - * The file is a video note. - */ - public FileTypeVideoNote() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -518412385; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a video published as a story. - */ - public static class FileTypeVideoStory extends FileType { - - /** - * The file is a video published as a story. - */ - public FileTypeVideoStory() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2146754143; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a voice note. - */ - public static class FileTypeVoiceNote extends FileType { - - /** - * The file is a voice note. - */ - public FileTypeVoiceNote() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -588681661; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file is a wallpaper or a background pattern. - */ - public static class FileTypeWallpaper extends FileType { - - /** - * The file is a wallpaper or a background pattern. - */ - public FileTypeWallpaper() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1854930076; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains settings for Firebase Authentication in the official applications. - */ - public abstract static class FirebaseAuthenticationSettings extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - FirebaseAuthenticationSettingsAndroid.CONSTRUCTOR, - FirebaseAuthenticationSettingsIos.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public FirebaseAuthenticationSettings() { - } - } - - /** - * Settings for Firebase Authentication in the official Android application. - */ - public static class FirebaseAuthenticationSettingsAndroid extends FirebaseAuthenticationSettings { - - /** - * Settings for Firebase Authentication in the official Android application. - */ - public FirebaseAuthenticationSettingsAndroid() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1771112932; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Settings for Firebase Authentication in the official iOS application. - */ - public static class FirebaseAuthenticationSettingsIos extends FirebaseAuthenticationSettings { - /** - * Device token from Apple Push Notification service. - */ - public String deviceToken; - /** - * True, if App Sandbox is enabled. - */ - public boolean isAppSandbox; - - /** - * Settings for Firebase Authentication in the official iOS application. - */ - public FirebaseAuthenticationSettingsIos() { - } - - /** - * Settings for Firebase Authentication in the official iOS application. - * - * @param deviceToken Device token from Apple Push Notification service. - * @param isAppSandbox True, if App Sandbox is enabled. - */ - public FirebaseAuthenticationSettingsIos(String deviceToken, boolean isAppSandbox) { - this.deviceToken = deviceToken; - this.isAppSandbox = isAppSandbox; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 222930116; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes parameters to be used for device verification. - */ - public abstract static class FirebaseDeviceVerificationParameters extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - FirebaseDeviceVerificationParametersSafetyNet.CONSTRUCTOR, - FirebaseDeviceVerificationParametersPlayIntegrity.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public FirebaseDeviceVerificationParameters() { - } - } - - /** - * Device verification must be performed with the SafetyNet Attestation API. - */ - public static class FirebaseDeviceVerificationParametersSafetyNet extends FirebaseDeviceVerificationParameters { - /** - * Nonce to pass to the SafetyNet Attestation API. - */ - public byte[] nonce; - - /** - * Device verification must be performed with the SafetyNet Attestation API. - */ - public FirebaseDeviceVerificationParametersSafetyNet() { - } - - /** - * Device verification must be performed with the SafetyNet Attestation API. - * - * @param nonce Nonce to pass to the SafetyNet Attestation API. - */ - public FirebaseDeviceVerificationParametersSafetyNet(byte[] nonce) { - this.nonce = nonce; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 731296497; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Device verification must be performed with the classic Play Integrity verification (https://developer.android.com/google/play/integrity/classic). - */ - public static class FirebaseDeviceVerificationParametersPlayIntegrity extends FirebaseDeviceVerificationParameters { - /** - * Base64url-encoded nonce to pass to the Play Integrity API. - */ - public String nonce; - /** - * Cloud project number to pass to the Play Integrity API. - */ - public long cloudProjectNumber; - - /** - * Device verification must be performed with the classic Play Integrity verification (https://developer.android.com/google/play/integrity/classic). - */ - public FirebaseDeviceVerificationParametersPlayIntegrity() { - } - - /** - * Device verification must be performed with the classic Play Integrity verification (https://developer.android.com/google/play/integrity/classic). - * - * @param nonce Base64url-encoded nonce to pass to the Play Integrity API. - * @param cloudProjectNumber Cloud project number to pass to the Play Integrity API. - */ - public FirebaseDeviceVerificationParametersPlayIntegrity(String nonce, long cloudProjectNumber) { - this.nonce = nonce; - this.cloudProjectNumber = cloudProjectNumber; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -889936502; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A text with some entities. - */ - public static class FormattedText extends Object { - /** - * The text. - */ - public String text; - /** - * Entities contained in the text. Entities can be nested, but must not mutually intersect with each other. Pre, Code and PreCode entities can't contain other entities. BlockQuote entities can't contain other BlockQuote entities. Bold, Italic, Underline, Strikethrough, and Spoiler entities can contain and can be part of any other entities. All other entities can't contain each other. - */ - public TextEntity[] entities; - - /** - * A text with some entities. - */ - public FormattedText() { - } - - /** - * A text with some entities. - * - * @param text The text. - * @param entities Entities contained in the text. Entities can be nested, but must not mutually intersect with each other. Pre, Code and PreCode entities can't contain other entities. BlockQuote entities can't contain other BlockQuote entities. Bold, Italic, Underline, Strikethrough, and Spoiler entities can contain and can be part of any other entities. All other entities can't contain each other. - */ - public FormattedText(String text, TextEntity[] entities) { - this.text = text; - this.entities = entities; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -252624564; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a forum topic. - */ - public static class ForumTopic extends Object { - /** - * Basic information about the topic. - */ - public ForumTopicInfo info; - /** - * Last message in the topic; may be null if unknown. - */ - @Nullable public Message lastMessage; - /** - * A parameter used to determine order of the topic in the topic list. Topics must be sorted by the order in descending order. - */ - public long order; - /** - * True, if the topic is pinned in the topic list. - */ - public boolean isPinned; - /** - * Number of unread messages in the topic. - */ - public int unreadCount; - /** - * Identifier of the last read incoming message. - */ - public long lastReadInboxMessageId; - /** - * Identifier of the last read outgoing message. - */ - public long lastReadOutboxMessageId; - /** - * Number of unread messages with a mention/reply in the topic. - */ - public int unreadMentionCount; - /** - * Number of messages with unread reactions in the topic. - */ - public int unreadReactionCount; - /** - * Notification settings for the topic. - */ - public ChatNotificationSettings notificationSettings; - /** - * A draft of a message in the topic; may be null if none. - */ - @Nullable public DraftMessage draftMessage; - - /** - * Describes a forum topic. - */ - public ForumTopic() { - } - - /** - * Describes a forum topic. - * - * @param info Basic information about the topic. - * @param lastMessage Last message in the topic; may be null if unknown. - * @param order A parameter used to determine order of the topic in the topic list. Topics must be sorted by the order in descending order. - * @param isPinned True, if the topic is pinned in the topic list. - * @param unreadCount Number of unread messages in the topic. - * @param lastReadInboxMessageId Identifier of the last read incoming message. - * @param lastReadOutboxMessageId Identifier of the last read outgoing message. - * @param unreadMentionCount Number of unread messages with a mention/reply in the topic. - * @param unreadReactionCount Number of messages with unread reactions in the topic. - * @param notificationSettings Notification settings for the topic. - * @param draftMessage A draft of a message in the topic; may be null if none. - */ - public ForumTopic(ForumTopicInfo info, Message lastMessage, long order, boolean isPinned, int unreadCount, long lastReadInboxMessageId, long lastReadOutboxMessageId, int unreadMentionCount, int unreadReactionCount, ChatNotificationSettings notificationSettings, DraftMessage draftMessage) { - this.info = info; - this.lastMessage = lastMessage; - this.order = order; - this.isPinned = isPinned; - this.unreadCount = unreadCount; - this.lastReadInboxMessageId = lastReadInboxMessageId; - this.lastReadOutboxMessageId = lastReadOutboxMessageId; - this.unreadMentionCount = unreadMentionCount; - this.unreadReactionCount = unreadReactionCount; - this.notificationSettings = notificationSettings; - this.draftMessage = draftMessage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2094608976; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a forum topic icon. - */ - public static class ForumTopicIcon extends Object { - /** - * Color of the topic icon in RGB format. - */ - public int color; - /** - * Unique identifier of the custom emoji shown on the topic icon; 0 if none. - */ - public long customEmojiId; - - /** - * Describes a forum topic icon. - */ - public ForumTopicIcon() { - } - - /** - * Describes a forum topic icon. - * - * @param color Color of the topic icon in RGB format. - * @param customEmojiId Unique identifier of the custom emoji shown on the topic icon; 0 if none. - */ - public ForumTopicIcon(int color, long customEmojiId) { - this.color = color; - this.customEmojiId = customEmojiId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -818765421; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains basic information about a forum topic. - */ - public static class ForumTopicInfo extends Object { - /** - * Identifier of a forum supergroup chat or a chat with a bot to which the topic belongs. - */ - public long chatId; - /** - * Forum topic identifier of the topic. - */ - public int forumTopicId; - /** - * Name of the topic. - */ - public String name; - /** - * Icon of the topic. - */ - public ForumTopicIcon icon; - /** - * Point in time (Unix timestamp) when the topic was created. - */ - public int creationDate; - /** - * Identifier of the creator of the topic. - */ - public MessageSender creatorId; - /** - * True, if the topic is the General topic. - */ - public boolean isGeneral; - /** - * True, if the topic was created by the current user. - */ - public boolean isOutgoing; - /** - * True, if the topic is closed. If the topic is closed, then the user must have canManageTopics administrator right in the supergroup or must be the creator of the topic to send messages there. - */ - public boolean isClosed; - /** - * True, if the topic is hidden above the topic list and closed; for General topic only. - */ - public boolean isHidden; - /** - * True, if the name of the topic wasn't added explicitly. - */ - public boolean isNameImplicit; - - /** - * Contains basic information about a forum topic. - */ - public ForumTopicInfo() { - } - - /** - * Contains basic information about a forum topic. - * - * @param chatId Identifier of a forum supergroup chat or a chat with a bot to which the topic belongs. - * @param forumTopicId Forum topic identifier of the topic. - * @param name Name of the topic. - * @param icon Icon of the topic. - * @param creationDate Point in time (Unix timestamp) when the topic was created. - * @param creatorId Identifier of the creator of the topic. - * @param isGeneral True, if the topic is the General topic. - * @param isOutgoing True, if the topic was created by the current user. - * @param isClosed True, if the topic is closed. If the topic is closed, then the user must have canManageTopics administrator right in the supergroup or must be the creator of the topic to send messages there. - * @param isHidden True, if the topic is hidden above the topic list and closed; for General topic only. - * @param isNameImplicit True, if the name of the topic wasn't added explicitly. - */ - public ForumTopicInfo(long chatId, int forumTopicId, String name, ForumTopicIcon icon, int creationDate, MessageSender creatorId, boolean isGeneral, boolean isOutgoing, boolean isClosed, boolean isHidden, boolean isNameImplicit) { - this.chatId = chatId; - this.forumTopicId = forumTopicId; - this.name = name; - this.icon = icon; - this.creationDate = creationDate; - this.creatorId = creatorId; - this.isGeneral = isGeneral; - this.isOutgoing = isOutgoing; - this.isClosed = isClosed; - this.isHidden = isHidden; - this.isNameImplicit = isNameImplicit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1951851836; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a list of forum topics. - */ - public static class ForumTopics extends Object { - /** - * Approximate total number of forum topics found. - */ - public int totalCount; - /** - * List of forum topics. - */ - public ForumTopic[] topics; - /** - * Offset date for the next getForumTopics request. - */ - public int nextOffsetDate; - /** - * Offset message identifier for the next getForumTopics request. - */ - public long nextOffsetMessageId; - /** - * Offset forum topic identifier for the next getForumTopics request. - */ - public int nextOffsetForumTopicId; - - /** - * Describes a list of forum topics. - */ - public ForumTopics() { - } - - /** - * Describes a list of forum topics. - * - * @param totalCount Approximate total number of forum topics found. - * @param topics List of forum topics. - * @param nextOffsetDate Offset date for the next getForumTopics request. - * @param nextOffsetMessageId Offset message identifier for the next getForumTopics request. - * @param nextOffsetForumTopicId Offset forum topic identifier for the next getForumTopics request. - */ - public ForumTopics(int totalCount, ForumTopic[] topics, int nextOffsetDate, long nextOffsetMessageId, int nextOffsetForumTopicId) { - this.totalCount = totalCount; - this.topics = topics; - this.nextOffsetDate = nextOffsetDate; - this.nextOffsetMessageId = nextOffsetMessageId; - this.nextOffsetForumTopicId = nextOffsetForumTopicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1877886267; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about the last message from which a new message was forwarded last time. - */ - public static class ForwardSource extends Object { - /** - * Identifier of the chat to which the message that was forwarded belonged; may be 0 if unknown. - */ - public long chatId; - /** - * Identifier of the message; may be 0 if unknown. - */ - public long messageId; - /** - * Identifier of the sender of the message; may be null if unknown or the new message was forwarded not to Saved Messages. - */ - @Nullable public MessageSender senderId; - /** - * Name of the sender of the message if the sender is hidden by their privacy settings. - */ - public String senderName; - /** - * Point in time (Unix timestamp) when the message is sent; 0 if unknown. - */ - public int date; - /** - * True, if the message that was forwarded is outgoing; always false if sender is unknown. - */ - public boolean isOutgoing; - - /** - * Contains information about the last message from which a new message was forwarded last time. - */ - public ForwardSource() { - } - - /** - * Contains information about the last message from which a new message was forwarded last time. - * - * @param chatId Identifier of the chat to which the message that was forwarded belonged; may be 0 if unknown. - * @param messageId Identifier of the message; may be 0 if unknown. - * @param senderId Identifier of the sender of the message; may be null if unknown or the new message was forwarded not to Saved Messages. - * @param senderName Name of the sender of the message if the sender is hidden by their privacy settings. - * @param date Point in time (Unix timestamp) when the message is sent; 0 if unknown. - * @param isOutgoing True, if the message that was forwarded is outgoing; always false if sender is unknown. - */ - public ForwardSource(long chatId, long messageId, MessageSender senderId, String senderName, int date, boolean isOutgoing) { - this.chatId = chatId; - this.messageId = messageId; - this.senderId = senderId; - this.senderName = senderName; - this.date = date; - this.isOutgoing = isOutgoing; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1795337929; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a found affiliate program. - */ - public static class FoundAffiliateProgram extends Object { - /** - * User identifier of the bot created the program. - */ - public long botUserId; - /** - * Information about the affiliate program. - */ - public AffiliateProgramInfo info; - - /** - * Describes a found affiliate program. - */ - public FoundAffiliateProgram() { - } - - /** - * Describes a found affiliate program. - * - * @param botUserId User identifier of the bot created the program. - * @param info Information about the affiliate program. - */ - public FoundAffiliateProgram(long botUserId, AffiliateProgramInfo info) { - this.botUserId = botUserId; - this.info = info; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -966565242; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of found affiliate programs. - */ - public static class FoundAffiliatePrograms extends Object { - /** - * The total number of found affiliate programs. - */ - public int totalCount; - /** - * The list of affiliate programs. - */ - public FoundAffiliateProgram[] programs; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Represents a list of found affiliate programs. - */ - public FoundAffiliatePrograms() { - } - - /** - * Represents a list of found affiliate programs. - * - * @param totalCount The total number of found affiliate programs. - * @param programs The list of affiliate programs. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public FoundAffiliatePrograms(int totalCount, FoundAffiliateProgram[] programs, String nextOffset) { - this.totalCount = totalCount; - this.programs = programs; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 186317057; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of boosts applied to a chat. - */ - public static class FoundChatBoosts extends Object { - /** - * Total number of boosts applied to the chat. - */ - public int totalCount; - /** - * List of boosts. - */ - public ChatBoost[] boosts; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Contains a list of boosts applied to a chat. - */ - public FoundChatBoosts() { - } - - /** - * Contains a list of boosts applied to a chat. - * - * @param totalCount Total number of boosts applied to the chat. - * @param boosts List of boosts. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public FoundChatBoosts(int totalCount, ChatBoost[] boosts, String nextOffset) { - this.totalCount = totalCount; - this.boosts = boosts; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 51457680; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of messages found by a search in a given chat. - */ - public static class FoundChatMessages extends Object { - /** - * Approximate total number of messages found; -1 if unknown. - */ - public int totalCount; - /** - * List of messages. - */ - public Message[] messages; - /** - * The offset for the next request. If 0, there are no more results. - */ - public long nextFromMessageId; - - /** - * Contains a list of messages found by a search in a given chat. - */ - public FoundChatMessages() { - } - - /** - * Contains a list of messages found by a search in a given chat. - * - * @param totalCount Approximate total number of messages found; -1 if unknown. - * @param messages List of messages. - * @param nextFromMessageId The offset for the next request. If 0, there are no more results. - */ - public FoundChatMessages(int totalCount, Message[] messages, long nextFromMessageId) { - this.totalCount = totalCount; - this.messages = messages; - this.nextFromMessageId = nextFromMessageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 427484196; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of downloaded files, found by a search. - */ - public static class FoundFileDownloads extends Object { - /** - * Total number of suitable files, ignoring offset. - */ - public DownloadedFileCounts totalCounts; - /** - * The list of files. - */ - public FileDownload[] files; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Contains a list of downloaded files, found by a search. - */ - public FoundFileDownloads() { - } - - /** - * Contains a list of downloaded files, found by a search. - * - * @param totalCounts Total number of suitable files, ignoring offset. - * @param files The list of files. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public FoundFileDownloads(DownloadedFileCounts totalCounts, FileDownload[] files, String nextOffset) { - this.totalCounts = totalCounts; - this.files = files; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1395890392; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of messages found by a search. - */ - public static class FoundMessages extends Object { - /** - * Approximate total number of messages found; -1 if unknown. - */ - public int totalCount; - /** - * List of messages. - */ - public Message[] messages; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Contains a list of messages found by a search. - */ - public FoundMessages() { - } - - /** - * Contains a list of messages found by a search. - * - * @param totalCount Approximate total number of messages found; -1 if unknown. - * @param messages List of messages. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public FoundMessages(int totalCount, Message[] messages, String nextOffset) { - this.totalCount = totalCount; - this.messages = messages; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -529809608; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains 0-based match position. - */ - public static class FoundPosition extends Object { - /** - * The position of the match. - */ - public int position; - - /** - * Contains 0-based match position. - */ - public FoundPosition() { - } - - /** - * Contains 0-based match position. - * - * @param position The position of the match. - */ - public FoundPosition(int position) { - this.position = position; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1886724216; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains 0-based positions of matched objects. - */ - public static class FoundPositions extends Object { - /** - * Total number of matched objects. - */ - public int totalCount; - /** - * The positions of the matched objects. - */ - public int[] positions; - - /** - * Contains 0-based positions of matched objects. - */ - public FoundPositions() { - } - - /** - * Contains 0-based positions of matched objects. - * - * @param totalCount Total number of matched objects. - * @param positions The positions of the matched objects. - */ - public FoundPositions(int totalCount, int[] positions) { - this.totalCount = totalCount; - this.positions = positions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -80518368; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of messages found by a public post search. - */ - public static class FoundPublicPosts extends Object { - /** - * List of found public posts. - */ - public Message[] messages; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - /** - * Updated public post search limits after the query; repeated requests with the same query will be free; may be null if they didn't change. - */ - @Nullable public PublicPostSearchLimits searchLimits; - /** - * True, if the query has failed because search limits are exceeded. In this case searchLimits.dailyFreeQueryCount will be equal to 0. - */ - public boolean areLimitsExceeded; - - /** - * Contains a list of messages found by a public post search. - */ - public FoundPublicPosts() { - } - - /** - * Contains a list of messages found by a public post search. - * - * @param messages List of found public posts. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - * @param searchLimits Updated public post search limits after the query; repeated requests with the same query will be free; may be null if they didn't change. - * @param areLimitsExceeded True, if the query has failed because search limits are exceeded. In this case searchLimits.dailyFreeQueryCount will be equal to 0. - */ - public FoundPublicPosts(Message[] messages, String nextOffset, PublicPostSearchLimits searchLimits, boolean areLimitsExceeded) { - this.messages = messages; - this.nextOffset = nextOffset; - this.searchLimits = searchLimits; - this.areLimitsExceeded = areLimitsExceeded; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1231347940; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of stories found by a search. - */ - public static class FoundStories extends Object { - /** - * Approximate total number of stories found. - */ - public int totalCount; - /** - * List of stories. - */ - public Story[] stories; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Contains a list of stories found by a search. - */ - public FoundStories() { - } - - /** - * Contains a list of stories found by a search. - * - * @param totalCount Approximate total number of stories found. - * @param stories List of stories. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public FoundStories(int totalCount, Story[] stories, String nextOffset) { - this.totalCount = totalCount; - this.stories = stories; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1678513512; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of found users. - */ - public static class FoundUsers extends Object { - /** - * Identifiers of the found users. - */ - public long[] userIds; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Represents a list of found users. - */ - public FoundUsers() { - } - - /** - * Represents a list of found users. - * - * @param userIds Identifiers of the found users. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public FoundUsers(long[] userIds, String nextOffset) { - this.userIds = userIds; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1150570075; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a Web App found by its short name. - */ - public static class FoundWebApp extends Object { - /** - * The Web App. - */ - public WebApp webApp; - /** - * True, if the user must be asked for the permission to the bot to send them messages. - */ - public boolean requestWriteAccess; - /** - * True, if there is no need to show an ordinary open URL confirmation before opening the Web App. The field must be ignored and confirmation must be shown anyway if the Web App link was hidden. - */ - public boolean skipConfirmation; - - /** - * Contains information about a Web App found by its short name. - */ - public FoundWebApp() { - } - - /** - * Contains information about a Web App found by its short name. - * - * @param webApp The Web App. - * @param requestWriteAccess True, if the user must be asked for the permission to the bot to send them messages. - * @param skipConfirmation True, if there is no need to show an ordinary open URL confirmation before opening the Web App. The field must be ignored and confirmation must be shown anyway if the Web App link was hidden. - */ - public FoundWebApp(WebApp webApp, boolean requestWriteAccess, boolean skipConfirmation) { - this.webApp = webApp; - this.requestWriteAccess = requestWriteAccess; - this.skipConfirmation = skipConfirmation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -290926562; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a game. Use getInternalLink with internalLinkTypeGame to share the game. - */ - public static class Game extends Object { - /** - * Unique game identifier. - */ - public long id; - /** - * Game short name. - */ - public String shortName; - /** - * Game title. - */ - public String title; - /** - * Game text, usually containing scoreboards for a game. - */ - public FormattedText text; - /** - * Game description. - */ - public String description; - /** - * Game photo. - */ - public Photo photo; - /** - * Game animation; may be null. - */ - @Nullable public Animation animation; - - /** - * Describes a game. Use getInternalLink with internalLinkTypeGame to share the game. - */ - public Game() { - } - - /** - * Describes a game. Use getInternalLink with internalLinkTypeGame to share the game. - * - * @param id Unique game identifier. - * @param shortName Game short name. - * @param title Game title. - * @param text Game text, usually containing scoreboards for a game. - * @param description Game description. - * @param photo Game photo. - * @param animation Game animation; may be null. - */ - public Game(long id, String shortName, String title, FormattedText text, String description, Photo photo, Animation animation) { - this.id = id; - this.shortName = shortName; - this.title = title; - this.text = text; - this.description = description; - this.photo = photo; - this.animation = animation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1565597752; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains one row of the game high score table. - */ - public static class GameHighScore extends Object { - /** - * Position in the high score table. - */ - public int position; - /** - * User identifier. - */ - public long userId; - /** - * User score. - */ - public int score; - - /** - * Contains one row of the game high score table. - */ - public GameHighScore() { - } - - /** - * Contains one row of the game high score table. - * - * @param position Position in the high score table. - * @param userId User identifier. - * @param score User score. - */ - public GameHighScore(int position, long userId, int score) { - this.position = position; - this.userId = userId; - this.score = score; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 342871838; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of game high scores. - */ - public static class GameHighScores extends Object { - /** - * A list of game high scores. - */ - public GameHighScore[] scores; - - /** - * Contains a list of game high scores. - */ - public GameHighScores() { - } - - /** - * Contains a list of game high scores. - * - * @param scores A list of game high scores. - */ - public GameHighScores(GameHighScore[] scores) { - this.scores = scores; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -725770727; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a gift that can be sent to another user or channel chat. - */ - public static class Gift extends Object { - /** - * Unique identifier of the gift. - */ - public long id; - /** - * Identifier of the chat that published the gift; 0 if none. - */ - public long publisherChatId; - /** - * The sticker representing the gift. - */ - public Sticker sticker; - /** - * Number of Telegram Stars that must be paid for the gift. - */ - public long starCount; - /** - * Number of Telegram Stars that can be claimed by the receiver instead of the regular gift by default. If the gift was paid with just bought Telegram Stars, then full value can be claimed. - */ - public long defaultSellStarCount; - /** - * Number of Telegram Stars that must be paid to upgrade the gift; 0 if upgrade isn't possible. - */ - public long upgradeStarCount; - /** - * Number of unique gift variants that are available for the upgraded gift; 0 if unknown. - */ - public int upgradeVariantCount; - /** - * True, if the gift can be used to customize the user's name, and backgrounds of profile photo, reply header, and link preview. - */ - public boolean hasColors; - /** - * True, if the gift is a birthday gift. - */ - public boolean isForBirthday; - /** - * True, if the gift can be bought only by Telegram Premium subscribers. - */ - public boolean isPremium; - /** - * Information about the auction on which the gift can be purchased; may be null if the gift can be purchased directly. - */ - @Nullable public GiftAuction auctionInfo; - /** - * Point in time (Unix timestamp) when the gift can be sent next time by the current user; may be 0 or a date in the past. If the date is in the future, then call canSendGift to get the reason, why the gift can't be sent now. - */ - public int nextSendDate; - /** - * Number of times the gift can be purchased by the current user; may be null if not limited. - */ - @Nullable public GiftPurchaseLimits userLimits; - /** - * Number of times the gift can be purchased all users; may be null if not limited. - */ - @Nullable public GiftPurchaseLimits overallLimits; - /** - * Background of the gift. - */ - public GiftBackground background; - /** - * Point in time (Unix timestamp) when the gift was send for the first time; for sold out gifts only. - */ - public int firstSendDate; - /** - * Point in time (Unix timestamp) when the gift was send for the last time; for sold out gifts only. - */ - public int lastSendDate; - - /** - * Describes a gift that can be sent to another user or channel chat. - */ - public Gift() { - } - - /** - * Describes a gift that can be sent to another user or channel chat. - * - * @param id Unique identifier of the gift. - * @param publisherChatId Identifier of the chat that published the gift; 0 if none. - * @param sticker The sticker representing the gift. - * @param starCount Number of Telegram Stars that must be paid for the gift. - * @param defaultSellStarCount Number of Telegram Stars that can be claimed by the receiver instead of the regular gift by default. If the gift was paid with just bought Telegram Stars, then full value can be claimed. - * @param upgradeStarCount Number of Telegram Stars that must be paid to upgrade the gift; 0 if upgrade isn't possible. - * @param upgradeVariantCount Number of unique gift variants that are available for the upgraded gift; 0 if unknown. - * @param hasColors True, if the gift can be used to customize the user's name, and backgrounds of profile photo, reply header, and link preview. - * @param isForBirthday True, if the gift is a birthday gift. - * @param isPremium True, if the gift can be bought only by Telegram Premium subscribers. - * @param auctionInfo Information about the auction on which the gift can be purchased; may be null if the gift can be purchased directly. - * @param nextSendDate Point in time (Unix timestamp) when the gift can be sent next time by the current user; may be 0 or a date in the past. If the date is in the future, then call canSendGift to get the reason, why the gift can't be sent now. - * @param userLimits Number of times the gift can be purchased by the current user; may be null if not limited. - * @param overallLimits Number of times the gift can be purchased all users; may be null if not limited. - * @param background Background of the gift. - * @param firstSendDate Point in time (Unix timestamp) when the gift was send for the first time; for sold out gifts only. - * @param lastSendDate Point in time (Unix timestamp) when the gift was send for the last time; for sold out gifts only. - */ - public Gift(long id, long publisherChatId, Sticker sticker, long starCount, long defaultSellStarCount, long upgradeStarCount, int upgradeVariantCount, boolean hasColors, boolean isForBirthday, boolean isPremium, GiftAuction auctionInfo, int nextSendDate, GiftPurchaseLimits userLimits, GiftPurchaseLimits overallLimits, GiftBackground background, int firstSendDate, int lastSendDate) { - this.id = id; - this.publisherChatId = publisherChatId; - this.sticker = sticker; - this.starCount = starCount; - this.defaultSellStarCount = defaultSellStarCount; - this.upgradeStarCount = upgradeStarCount; - this.upgradeVariantCount = upgradeVariantCount; - this.hasColors = hasColors; - this.isForBirthday = isForBirthday; - this.isPremium = isPremium; - this.auctionInfo = auctionInfo; - this.nextSendDate = nextSendDate; - this.userLimits = userLimits; - this.overallLimits = overallLimits; - this.background = background; - this.firstSendDate = firstSendDate; - this.lastSendDate = lastSendDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1567244615; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an auction on which a gift can be purchased. - */ - public static class GiftAuction extends Object { - /** - * Identifier of the auction. - */ - public String id; - /** - * Number of gifts distributed in each round. - */ - public int giftsPerRound; - /** - * Point in time (Unix timestamp) when the auction will start. - */ - public int startDate; - - /** - * Describes an auction on which a gift can be purchased. - */ - public GiftAuction() { - } - - /** - * Describes an auction on which a gift can be purchased. - * - * @param id Identifier of the auction. - * @param giftsPerRound Number of gifts distributed in each round. - * @param startDate Point in time (Unix timestamp) when the auction will start. - */ - public GiftAuction(String id, int giftsPerRound, int startDate) { - this.id = id; - this.giftsPerRound = giftsPerRound; - this.startDate = startDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -907929982; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a gift that was acquired by the current user on an auction. - */ - public static class GiftAuctionAcquiredGift extends Object { - /** - * Receiver of the gift. - */ - public MessageSender receiverId; - /** - * Point in time (Unix timestamp) when the gift was acquired. - */ - public int date; - /** - * The number of Telegram Stars that were paid for the gift. - */ - public long starCount; - /** - * Identifier of the auction round in which the gift was acquired. - */ - public int auctionRoundNumber; - /** - * Position of the user in the round among all auction participants. - */ - public int auctionRoundPosition; - /** - * Unique number of the gift among gifts upgraded from the same gift after upgrade; 0 if yet unassigned. - */ - public int uniqueGiftNumber; - /** - * Message added to the gift. - */ - public FormattedText text; - /** - * True, if the sender and gift text are shown only to the gift receiver; otherwise, everyone will be able to see them. - */ - public boolean isPrivate; - - /** - * Represents a gift that was acquired by the current user on an auction. - */ - public GiftAuctionAcquiredGift() { - } - - /** - * Represents a gift that was acquired by the current user on an auction. - * - * @param receiverId Receiver of the gift. - * @param date Point in time (Unix timestamp) when the gift was acquired. - * @param starCount The number of Telegram Stars that were paid for the gift. - * @param auctionRoundNumber Identifier of the auction round in which the gift was acquired. - * @param auctionRoundPosition Position of the user in the round among all auction participants. - * @param uniqueGiftNumber Unique number of the gift among gifts upgraded from the same gift after upgrade; 0 if yet unassigned. - * @param text Message added to the gift. - * @param isPrivate True, if the sender and gift text are shown only to the gift receiver; otherwise, everyone will be able to see them. - */ - public GiftAuctionAcquiredGift(MessageSender receiverId, int date, long starCount, int auctionRoundNumber, int auctionRoundPosition, int uniqueGiftNumber, FormattedText text, boolean isPrivate) { - this.receiverId = receiverId; - this.date = date; - this.starCount = starCount; - this.auctionRoundNumber = auctionRoundNumber; - this.auctionRoundPosition = auctionRoundPosition; - this.uniqueGiftNumber = uniqueGiftNumber; - this.text = text; - this.isPrivate = isPrivate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1109930332; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of gifts that were acquired by the current user on an auction. - */ - public static class GiftAuctionAcquiredGifts extends Object { - /** - * The list of acquired gifts. - */ - public GiftAuctionAcquiredGift[] gifts; - - /** - * Represents a list of gifts that were acquired by the current user on an auction. - */ - public GiftAuctionAcquiredGifts() { - } - - /** - * Represents a list of gifts that were acquired by the current user on an auction. - * - * @param gifts The list of acquired gifts. - */ - public GiftAuctionAcquiredGifts(GiftAuctionAcquiredGift[] gifts) { - this.gifts = gifts; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1203777214; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represent auction state of a gift. - */ - public static class GiftAuctionState extends Object { - /** - * The gift. - */ - public Gift gift; - /** - * Auction state of the gift. - */ - public AuctionState state; - - /** - * Represent auction state of a gift. - */ - public GiftAuctionState() { - } - - /** - * Represent auction state of a gift. - * - * @param gift The gift. - * @param state Auction state of the gift. - */ - public GiftAuctionState(Gift gift, AuctionState state) { - this.gift = gift; - this.state = state; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1691485529; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes background of a gift. - */ - public static class GiftBackground extends Object { - /** - * Center color in RGB format. - */ - public int centerColor; - /** - * Edge color in RGB format. - */ - public int edgeColor; - /** - * Text color in RGB format. - */ - public int textColor; - - /** - * Describes background of a gift. - */ - public GiftBackground() { - } - - /** - * Describes background of a gift. - * - * @param centerColor Center color in RGB format. - * @param edgeColor Edge color in RGB format. - * @param textColor Text color in RGB format. - */ - public GiftBackground(int centerColor, int edgeColor, int textColor) { - this.centerColor = centerColor; - this.edgeColor = edgeColor; - this.textColor = textColor; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 269232091; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a chat theme based on an upgraded gift. - */ - public static class GiftChatTheme extends Object { - /** - * The gift. - */ - public UpgradedGift gift; - /** - * Theme settings for a light chat theme. - */ - public ThemeSettings lightSettings; - /** - * Theme settings for a dark chat theme. - */ - public ThemeSettings darkSettings; - - /** - * Describes a chat theme based on an upgraded gift. - */ - public GiftChatTheme() { - } - - /** - * Describes a chat theme based on an upgraded gift. - * - * @param gift The gift. - * @param lightSettings Theme settings for a light chat theme. - * @param darkSettings Theme settings for a dark chat theme. - */ - public GiftChatTheme(UpgradedGift gift, ThemeSettings lightSettings, ThemeSettings darkSettings) { - this.gift = gift; - this.lightSettings = lightSettings; - this.darkSettings = darkSettings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 631944675; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of chat themes based on upgraded gifts. - */ - public static class GiftChatThemes extends Object { - /** - * A list of chat themes. - */ - public GiftChatTheme[] themes; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Contains a list of chat themes based on upgraded gifts. - */ - public GiftChatThemes() { - } - - /** - * Contains a list of chat themes based on upgraded gifts. - * - * @param themes A list of chat themes. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public GiftChatThemes(GiftChatTheme[] themes, String nextOffset) { - this.themes = themes; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2032762331; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes collection of gifts. - */ - public static class GiftCollection extends Object { - /** - * Unique identifier of the collection. - */ - public int id; - /** - * Name of the collection. - */ - public String name; - /** - * Icon of the collection; may be null if none. - */ - @Nullable public Sticker icon; - /** - * Total number of gifts in the collection. - */ - public int giftCount; - - /** - * Describes collection of gifts. - */ - public GiftCollection() { - } - - /** - * Describes collection of gifts. - * - * @param id Unique identifier of the collection. - * @param name Name of the collection. - * @param icon Icon of the collection; may be null if none. - * @param giftCount Total number of gifts in the collection. - */ - public GiftCollection(int id, String name, Sticker icon, int giftCount) { - this.id = id; - this.name = name; - this.icon = icon; - this.giftCount = giftCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -974976984; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of gift collections. - */ - public static class GiftCollections extends Object { - /** - * List of gift collections. - */ - public GiftCollection[] collections; - - /** - * Contains a list of gift collections. - */ - public GiftCollections() { - } - - /** - * Contains a list of gift collections. - * - * @param collections List of gift collections. - */ - public GiftCollections(GiftCollection[] collections) { - this.collections = collections; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2061353335; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a gift available for resale. - */ - public static class GiftForResale extends Object { - /** - * The gift. - */ - public UpgradedGift gift; - /** - * Unique identifier of the received gift for the current user; only for the gifts owned by the current user. - */ - public String receivedGiftId; - - /** - * Describes a gift available for resale. - */ - public GiftForResale() { - } - - /** - * Describes a gift available for resale. - * - * @param gift The gift. - * @param receivedGiftId Unique identifier of the received gift for the current user; only for the gifts owned by the current user. - */ - public GiftForResale(UpgradedGift gift, String receivedGiftId) { - this.gift = gift; - this.receivedGiftId = receivedGiftId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1130990515; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes order in which upgraded gifts for resale will be sorted. - */ - public abstract static class GiftForResaleOrder extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - GiftForResaleOrderPrice.CONSTRUCTOR, - GiftForResaleOrderPriceChangeDate.CONSTRUCTOR, - GiftForResaleOrderNumber.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public GiftForResaleOrder() { - } - } - - /** - * The gifts will be sorted by their price from the lowest to the highest. - */ - public static class GiftForResaleOrderPrice extends GiftForResaleOrder { - - /** - * The gifts will be sorted by their price from the lowest to the highest. - */ - public GiftForResaleOrderPrice() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1371740258; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The gifts will be sorted by the last date when their price was changed from the newest to the oldest. - */ - public static class GiftForResaleOrderPriceChangeDate extends GiftForResaleOrder { - - /** - * The gifts will be sorted by the last date when their price was changed from the newest to the oldest. - */ - public GiftForResaleOrderPriceChangeDate() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1694144054; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The gifts will be sorted by their number from the smallest to the largest. - */ - public static class GiftForResaleOrderNumber extends GiftForResaleOrder { - - /** - * The gifts will be sorted by their number from the smallest to the largest. - */ - public GiftForResaleOrderNumber() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1301157632; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes the maximum number of times that a specific gift can be purchased. - */ - public static class GiftPurchaseLimits extends Object { - /** - * The maximum number of times the gifts can be purchased. - */ - public int totalCount; - /** - * Number of remaining times the gift can be purchased. - */ - public int remainingCount; - - /** - * Describes the maximum number of times that a specific gift can be purchased. - */ - public GiftPurchaseLimits() { - } - - /** - * Describes the maximum number of times that a specific gift can be purchased. - * - * @param totalCount The maximum number of times the gifts can be purchased. - * @param remainingCount Number of remaining times the gift can be purchased. - */ - public GiftPurchaseLimits(int totalCount, int remainingCount) { - this.totalCount = totalCount; - this.remainingCount = remainingCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1628985177; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes state of a gift purchase offer. - */ - public abstract static class GiftPurchaseOfferState extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - GiftPurchaseOfferStatePending.CONSTRUCTOR, - GiftPurchaseOfferStateAccepted.CONSTRUCTOR, - GiftPurchaseOfferStateRejected.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public GiftPurchaseOfferState() { - } - } - - /** - * The offer must be accepted or rejected. - */ - public static class GiftPurchaseOfferStatePending extends GiftPurchaseOfferState { - - /** - * The offer must be accepted or rejected. - */ - public GiftPurchaseOfferStatePending() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 568086522; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The offer was accepted. - */ - public static class GiftPurchaseOfferStateAccepted extends GiftPurchaseOfferState { - - /** - * The offer was accepted. - */ - public GiftPurchaseOfferStateAccepted() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 267078794; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The offer was rejected. - */ - public static class GiftPurchaseOfferStateRejected extends GiftPurchaseOfferState { - - /** - * The offer was rejected. - */ - public GiftPurchaseOfferStateRejected() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1637834462; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes parameters of a unique gift available for resale. - */ - public static class GiftResaleParameters extends Object { - /** - * Resale price of the gift in Telegram Stars. - */ - public long starCount; - /** - * Resale price of the gift in 1/100 of Toncoin. - */ - public long toncoinCentCount; - /** - * True, if the gift can be bought only using Toncoins. - */ - public boolean toncoinOnly; - - /** - * Describes parameters of a unique gift available for resale. - */ - public GiftResaleParameters() { - } - - /** - * Describes parameters of a unique gift available for resale. - * - * @param starCount Resale price of the gift in Telegram Stars. - * @param toncoinCentCount Resale price of the gift in 1/100 of Toncoin. - * @param toncoinOnly True, if the gift can be bought only using Toncoins. - */ - public GiftResaleParameters(long starCount, long toncoinCentCount, boolean toncoinOnly) { - this.starCount = starCount; - this.toncoinCentCount = toncoinCentCount; - this.toncoinOnly = toncoinOnly; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2144380890; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes price of a resold gift. - */ - public abstract static class GiftResalePrice extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - GiftResalePriceStar.CONSTRUCTOR, - GiftResalePriceTon.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public GiftResalePrice() { - } - } - - /** - * Describes price of a resold gift in Telegram Stars. - */ - public static class GiftResalePriceStar extends GiftResalePrice { - /** - * The Telegram Star amount expected to be paid for the gift. Must be in the range getOption("gift_resale_star_count_min")-getOption("gift_resale_star_count_max") for gifts put for resale. - */ - public long starCount; - - /** - * Describes price of a resold gift in Telegram Stars. - */ - public GiftResalePriceStar() { - } - - /** - * Describes price of a resold gift in Telegram Stars. - * - * @param starCount The Telegram Star amount expected to be paid for the gift. Must be in the range getOption("gift_resale_star_count_min")-getOption("gift_resale_star_count_max") for gifts put for resale. - */ - public GiftResalePriceStar(long starCount) { - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1184402054; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes price of a resold gift in Toncoins. - */ - public static class GiftResalePriceTon extends GiftResalePrice { - /** - * The amount of 1/100 of Toncoin expected to be paid for the gift. Must be in the range getOption("gift_resale_toncoin_cent_count_min")-getOption("gift_resale_toncoin_cent_count_max"). - */ - public long toncoinCentCount; - - /** - * Describes price of a resold gift in Toncoins. - */ - public GiftResalePriceTon() { - } - - /** - * Describes price of a resold gift in Toncoins. - * - * @param toncoinCentCount The amount of 1/100 of Toncoin expected to be paid for the gift. Must be in the range getOption("gift_resale_toncoin_cent_count_min")-getOption("gift_resale_toncoin_cent_count_max"). - */ - public GiftResalePriceTon(long toncoinCentCount) { - this.toncoinCentCount = toncoinCentCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -415435950; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes result of sending a resold gift. - */ - public abstract static class GiftResaleResult extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - GiftResaleResultOk.CONSTRUCTOR, - GiftResaleResultPriceIncreased.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public GiftResaleResult() { - } - } - - /** - * Operation was successfully completed. - */ - public static class GiftResaleResultOk extends GiftResaleResult { - /** - * Unique identifier of the received gift; only for the gifts sent to the current user. - */ - public String receivedGiftId; - - /** - * Operation was successfully completed. - */ - public GiftResaleResultOk() { - } - - /** - * Operation was successfully completed. - * - * @param receivedGiftId Unique identifier of the received gift; only for the gifts sent to the current user. - */ - public GiftResaleResultOk(String receivedGiftId) { - this.receivedGiftId = receivedGiftId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -778580572; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Operation has failed, because price has increased. If the price has decreased, then the buying will succeed anyway. - */ - public static class GiftResaleResultPriceIncreased extends GiftResaleResult { - /** - * New price for the gift. - */ - public GiftResalePrice price; - - /** - * Operation has failed, because price has increased. If the price has decreased, then the buying will succeed anyway. - */ - public GiftResaleResultPriceIncreased() { - } - - /** - * Operation has failed, because price has increased. If the price has decreased, then the buying will succeed anyway. - * - * @param price New price for the gift. - */ - public GiftResaleResultPriceIncreased(GiftResalePrice price) { - this.price = price; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1954623859; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains settings for gift receiving for a user. - */ - public static class GiftSettings extends Object { - /** - * True, if a button for sending a gift to the user or by the user must always be shown in the input field. - */ - public boolean showGiftButton; - /** - * Types of gifts accepted by the user; for Telegram Premium users only. - */ - public AcceptedGiftTypes acceptedGiftTypes; - - /** - * Contains settings for gift receiving for a user. - */ - public GiftSettings() { - } - - /** - * Contains settings for gift receiving for a user. - * - * @param showGiftButton True, if a button for sending a gift to the user or by the user must always be shown in the input field. - * @param acceptedGiftTypes Types of gifts accepted by the user; for Telegram Premium users only. - */ - public GiftSettings(boolean showGiftButton, AcceptedGiftTypes acceptedGiftTypes) { - this.showGiftButton = showGiftButton; - this.acceptedGiftTypes = acceptedGiftTypes; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 45783168; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains examples of possible upgraded gifts for the given regular gift. - */ - public static class GiftUpgradePreview extends Object { - /** - * Examples of possible models that can be chosen for the gift after upgrade. - */ - public UpgradedGiftModel[] models; - /** - * Examples of possible symbols that can be chosen for the gift after upgrade. - */ - public UpgradedGiftSymbol[] symbols; - /** - * Examples of possible backdrops that can be chosen for the gift after upgrade. - */ - public UpgradedGiftBackdrop[] backdrops; - /** - * Examples of price for gift upgrade from the maximum price to the minimum price. - */ - public GiftUpgradePrice[] prices; - /** - * Next changes for the price for gift upgrade with more granularity than in prices. - */ - public GiftUpgradePrice[] nextPrices; - - /** - * Contains examples of possible upgraded gifts for the given regular gift. - */ - public GiftUpgradePreview() { - } - - /** - * Contains examples of possible upgraded gifts for the given regular gift. - * - * @param models Examples of possible models that can be chosen for the gift after upgrade. - * @param symbols Examples of possible symbols that can be chosen for the gift after upgrade. - * @param backdrops Examples of possible backdrops that can be chosen for the gift after upgrade. - * @param prices Examples of price for gift upgrade from the maximum price to the minimum price. - * @param nextPrices Next changes for the price for gift upgrade with more granularity than in prices. - */ - public GiftUpgradePreview(UpgradedGiftModel[] models, UpgradedGiftSymbol[] symbols, UpgradedGiftBackdrop[] backdrops, GiftUpgradePrice[] prices, GiftUpgradePrice[] nextPrices) { - this.models = models; - this.symbols = symbols; - this.backdrops = backdrops; - this.prices = prices; - this.nextPrices = nextPrices; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -330012073; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a price required to pay to upgrade a gift. - */ - public static class GiftUpgradePrice extends Object { - /** - * Point in time (Unix timestamp) when the price will be in effect. - */ - public int date; - /** - * The Telegram Star amount required to pay to upgrade the gift. - */ - public long starCount; - - /** - * Describes a price required to pay to upgrade a gift. - */ - public GiftUpgradePrice() { - } - - /** - * Describes a price required to pay to upgrade a gift. - * - * @param date Point in time (Unix timestamp) when the price will be in effect. - * @param starCount The Telegram Star amount required to pay to upgrade the gift. - */ - public GiftUpgradePrice(int date, long starCount) { - this.date = date; - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -914121900; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains all possible variants of upgraded gifts for the given regular gift. - */ - public static class GiftUpgradeVariants extends Object { - /** - * Models that can be chosen for the gift after upgrade. - */ - public UpgradedGiftModel[] models; - /** - * Symbols that can be chosen for the gift after upgrade. - */ - public UpgradedGiftSymbol[] symbols; - /** - * Backdrops that can be chosen for the gift after upgrade. - */ - public UpgradedGiftBackdrop[] backdrops; - - /** - * Contains all possible variants of upgraded gifts for the given regular gift. - */ - public GiftUpgradeVariants() { - } - - /** - * Contains all possible variants of upgraded gifts for the given regular gift. - * - * @param models Models that can be chosen for the gift after upgrade. - * @param symbols Symbols that can be chosen for the gift after upgrade. - * @param backdrops Backdrops that can be chosen for the gift after upgrade. - */ - public GiftUpgradeVariants(UpgradedGiftModel[] models, UpgradedGiftSymbol[] symbols, UpgradedGiftBackdrop[] backdrops) { - this.models = models; - this.symbols = symbols; - this.backdrops = backdrops; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -797379063; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of gifts received by a user or a chat. - */ - public static class GiftsForCrafting extends Object { - /** - * The total number of received gifts. - */ - public int totalCount; - /** - * The list of gifts. - */ - public ReceivedGift[] gifts; - /** - * The 4 objects that describe probabilities of the crafted gift to have the backdrop or symbol of one of the original gifts for the cases when 1, 2, 3 or 4 gifts are used in the craft correspondingly. - */ - public AttributeCraftPersistenceProbability[] attributePersistenceProbabilities; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Represents a list of gifts received by a user or a chat. - */ - public GiftsForCrafting() { - } - - /** - * Represents a list of gifts received by a user or a chat. - * - * @param totalCount The total number of received gifts. - * @param gifts The list of gifts. - * @param attributePersistenceProbabilities The 4 objects that describe probabilities of the crafted gift to have the backdrop or symbol of one of the original gifts for the cases when 1, 2, 3 or 4 gifts are used in the craft correspondingly. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public GiftsForCrafting(int totalCount, ReceivedGift[] gifts, AttributeCraftPersistenceProbability[] attributePersistenceProbabilities, String nextOffset) { - this.totalCount = totalCount; - this.gifts = gifts; - this.attributePersistenceProbabilities = attributePersistenceProbabilities; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -474640200; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes gifts available for resale. - */ - public static class GiftsForResale extends Object { - /** - * Total number of gifts found. - */ - public int totalCount; - /** - * The gifts. - */ - public GiftForResale[] gifts; - /** - * Available models; for searchGiftsForResale requests without offset and attributes only. - */ - public UpgradedGiftModelCount[] models; - /** - * Available symbols; for searchGiftsForResale requests without offset and attributes only. - */ - public UpgradedGiftSymbolCount[] symbols; - /** - * Available backdrops; for searchGiftsForResale requests without offset and attributes only. - */ - public UpgradedGiftBackdropCount[] backdrops; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Describes gifts available for resale. - */ - public GiftsForResale() { - } - - /** - * Describes gifts available for resale. - * - * @param totalCount Total number of gifts found. - * @param gifts The gifts. - * @param models Available models; for searchGiftsForResale requests without offset and attributes only. - * @param symbols Available symbols; for searchGiftsForResale requests without offset and attributes only. - * @param backdrops Available backdrops; for searchGiftsForResale requests without offset and attributes only. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public GiftsForResale(int totalCount, GiftForResale[] gifts, UpgradedGiftModelCount[] models, UpgradedGiftSymbolCount[] symbols, UpgradedGiftBackdropCount[] backdrops, String nextOffset) { - this.totalCount = totalCount; - this.gifts = gifts; - this.models = models; - this.symbols = symbols; - this.backdrops = backdrops; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 35082425; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains information about a giveaway. - */ - public abstract static class GiveawayInfo extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - GiveawayInfoOngoing.CONSTRUCTOR, - GiveawayInfoCompleted.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public GiveawayInfo() { - } - } - - /** - * Describes an ongoing giveaway. - */ - public static class GiveawayInfoOngoing extends GiveawayInfo { - /** - * Point in time (Unix timestamp) when the giveaway was created. - */ - public int creationDate; - /** - * Status of the current user in the giveaway. - */ - public GiveawayParticipantStatus status; - /** - * True, if the giveaway has ended and results are being prepared. - */ - public boolean isEnded; - - /** - * Describes an ongoing giveaway. - */ - public GiveawayInfoOngoing() { - } - - /** - * Describes an ongoing giveaway. - * - * @param creationDate Point in time (Unix timestamp) when the giveaway was created. - * @param status Status of the current user in the giveaway. - * @param isEnded True, if the giveaway has ended and results are being prepared. - */ - public GiveawayInfoOngoing(int creationDate, GiveawayParticipantStatus status, boolean isEnded) { - this.creationDate = creationDate; - this.status = status; - this.isEnded = isEnded; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1649336400; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a completed giveaway. - */ - public static class GiveawayInfoCompleted extends GiveawayInfo { - /** - * Point in time (Unix timestamp) when the giveaway was created. - */ - public int creationDate; - /** - * Point in time (Unix timestamp) when the winners were selected. May be bigger than winners selection date specified in parameters of the giveaway. - */ - public int actualWinnersSelectionDate; - /** - * True, if the giveaway was canceled and was fully refunded. - */ - public boolean wasRefunded; - /** - * True, if the current user is a winner of the giveaway. - */ - public boolean isWinner; - /** - * Number of winners in the giveaway. - */ - public int winnerCount; - /** - * Number of winners, which activated their gift codes; for Telegram Premium giveaways only. - */ - public int activationCount; - /** - * Telegram Premium gift code that was received by the current user; empty if the user isn't a winner in the giveaway or the giveaway isn't a Telegram Premium giveaway. - */ - public String giftCode; - /** - * The Telegram Star amount won by the current user; 0 if the user isn't a winner in the giveaway or the giveaway isn't a Telegram Star giveaway. - */ - public long wonStarCount; - - /** - * Describes a completed giveaway. - */ - public GiveawayInfoCompleted() { - } - - /** - * Describes a completed giveaway. - * - * @param creationDate Point in time (Unix timestamp) when the giveaway was created. - * @param actualWinnersSelectionDate Point in time (Unix timestamp) when the winners were selected. May be bigger than winners selection date specified in parameters of the giveaway. - * @param wasRefunded True, if the giveaway was canceled and was fully refunded. - * @param isWinner True, if the current user is a winner of the giveaway. - * @param winnerCount Number of winners in the giveaway. - * @param activationCount Number of winners, which activated their gift codes; for Telegram Premium giveaways only. - * @param giftCode Telegram Premium gift code that was received by the current user; empty if the user isn't a winner in the giveaway or the giveaway isn't a Telegram Premium giveaway. - * @param wonStarCount The Telegram Star amount won by the current user; 0 if the user isn't a winner in the giveaway or the giveaway isn't a Telegram Star giveaway. - */ - public GiveawayInfoCompleted(int creationDate, int actualWinnersSelectionDate, boolean wasRefunded, boolean isWinner, int winnerCount, int activationCount, String giftCode, long wonStarCount) { - this.creationDate = creationDate; - this.actualWinnersSelectionDate = actualWinnersSelectionDate; - this.wasRefunded = wasRefunded; - this.isWinner = isWinner; - this.winnerCount = winnerCount; - this.activationCount = activationCount; - this.giftCode = giftCode; - this.wonStarCount = wonStarCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 848085852; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes parameters of a giveaway. - */ - public static class GiveawayParameters extends Object { - /** - * Identifier of the supergroup or channel chat, which will be automatically boosted by the winners of the giveaway for duration of the Telegram Premium subscription, or for the specified time. If the chat is a channel, then canPostMessages administrator right is required in the channel, otherwise, the user must be an administrator in the supergroup. - */ - public long boostedChatId; - /** - * Identifiers of other supergroup or channel chats that must be subscribed by the users to be eligible for the giveaway. There can be up to getOption("giveaway_additional_chat_count_max") additional chats. - */ - public long[] additionalChatIds; - /** - * Point in time (Unix timestamp) when the giveaway is expected to be performed; must be 60-getOption("giveaway_duration_max") seconds in the future in scheduled giveaways. - */ - public int winnersSelectionDate; - /** - * True, if only new members of the chats will be eligible for the giveaway. - */ - public boolean onlyNewMembers; - /** - * True, if the list of winners of the giveaway will be available to everyone. - */ - public boolean hasPublicWinners; - /** - * The list of two-letter ISO 3166-1 alpha-2 codes of countries, users from which will be eligible for the giveaway. If empty, then all users can participate in the giveaway. There can be up to getOption("giveaway_country_count_max") chosen countries. Users with phone number that was bought at https://fragment.com can participate in any giveaway and the country code "FT" must not be specified in the list. - */ - public String[] countryCodes; - /** - * Additional description of the giveaway prize; 0-128 characters. - */ - public String prizeDescription; - - /** - * Describes parameters of a giveaway. - */ - public GiveawayParameters() { - } - - /** - * Describes parameters of a giveaway. - * - * @param boostedChatId Identifier of the supergroup or channel chat, which will be automatically boosted by the winners of the giveaway for duration of the Telegram Premium subscription, or for the specified time. If the chat is a channel, then canPostMessages administrator right is required in the channel, otherwise, the user must be an administrator in the supergroup. - * @param additionalChatIds Identifiers of other supergroup or channel chats that must be subscribed by the users to be eligible for the giveaway. There can be up to getOption("giveaway_additional_chat_count_max") additional chats. - * @param winnersSelectionDate Point in time (Unix timestamp) when the giveaway is expected to be performed; must be 60-getOption("giveaway_duration_max") seconds in the future in scheduled giveaways. - * @param onlyNewMembers True, if only new members of the chats will be eligible for the giveaway. - * @param hasPublicWinners True, if the list of winners of the giveaway will be available to everyone. - * @param countryCodes The list of two-letter ISO 3166-1 alpha-2 codes of countries, users from which will be eligible for the giveaway. If empty, then all users can participate in the giveaway. There can be up to getOption("giveaway_country_count_max") chosen countries. Users with phone number that was bought at https://fragment.com can participate in any giveaway and the country code "FT" must not be specified in the list. - * @param prizeDescription Additional description of the giveaway prize; 0-128 characters. - */ - public GiveawayParameters(long boostedChatId, long[] additionalChatIds, int winnersSelectionDate, boolean onlyNewMembers, boolean hasPublicWinners, String[] countryCodes, String prizeDescription) { - this.boostedChatId = boostedChatId; - this.additionalChatIds = additionalChatIds; - this.winnersSelectionDate = winnersSelectionDate; - this.onlyNewMembers = onlyNewMembers; - this.hasPublicWinners = hasPublicWinners; - this.countryCodes = countryCodes; - this.prizeDescription = prizeDescription; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1171549354; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains information about status of a user in a giveaway. - */ - public abstract static class GiveawayParticipantStatus extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - GiveawayParticipantStatusEligible.CONSTRUCTOR, - GiveawayParticipantStatusParticipating.CONSTRUCTOR, - GiveawayParticipantStatusAlreadyWasMember.CONSTRUCTOR, - GiveawayParticipantStatusAdministrator.CONSTRUCTOR, - GiveawayParticipantStatusDisallowedCountry.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public GiveawayParticipantStatus() { - } - } - - /** - * The user is eligible for the giveaway. - */ - public static class GiveawayParticipantStatusEligible extends GiveawayParticipantStatus { - - /** - * The user is eligible for the giveaway. - */ - public GiveawayParticipantStatusEligible() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 304799383; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user participates in the giveaway. - */ - public static class GiveawayParticipantStatusParticipating extends GiveawayParticipantStatus { - - /** - * The user participates in the giveaway. - */ - public GiveawayParticipantStatusParticipating() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 492036975; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user can't participate in the giveaway, because they have already been member of the chat. - */ - public static class GiveawayParticipantStatusAlreadyWasMember extends GiveawayParticipantStatus { - /** - * Point in time (Unix timestamp) when the user joined the chat. - */ - public int joinedChatDate; - - /** - * The user can't participate in the giveaway, because they have already been member of the chat. - */ - public GiveawayParticipantStatusAlreadyWasMember() { - } - - /** - * The user can't participate in the giveaway, because they have already been member of the chat. - * - * @param joinedChatDate Point in time (Unix timestamp) when the user joined the chat. - */ - public GiveawayParticipantStatusAlreadyWasMember(int joinedChatDate) { - this.joinedChatDate = joinedChatDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 301577632; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user can't participate in the giveaway, because they are an administrator in one of the chats that created the giveaway. - */ - public static class GiveawayParticipantStatusAdministrator extends GiveawayParticipantStatus { - /** - * Identifier of the chat administered by the user. - */ - public long chatId; - - /** - * The user can't participate in the giveaway, because they are an administrator in one of the chats that created the giveaway. - */ - public GiveawayParticipantStatusAdministrator() { - } - - /** - * The user can't participate in the giveaway, because they are an administrator in one of the chats that created the giveaway. - * - * @param chatId Identifier of the chat administered by the user. - */ - public GiveawayParticipantStatusAdministrator(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -934593931; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user can't participate in the giveaway, because they phone number is from a disallowed country. - */ - public static class GiveawayParticipantStatusDisallowedCountry extends GiveawayParticipantStatus { - /** - * A two-letter ISO 3166-1 alpha-2 country code of the user's country. - */ - public String userCountryCode; - - /** - * The user can't participate in the giveaway, because they phone number is from a disallowed country. - */ - public GiveawayParticipantStatusDisallowedCountry() { - } - - /** - * The user can't participate in the giveaway, because they phone number is from a disallowed country. - * - * @param userCountryCode A two-letter ISO 3166-1 alpha-2 country code of the user's country. - */ - public GiveawayParticipantStatusDisallowedCountry(String userCountryCode) { - this.userCountryCode = userCountryCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1879794779; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains information about a giveaway prize. - */ - public abstract static class GiveawayPrize extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - GiveawayPrizePremium.CONSTRUCTOR, - GiveawayPrizeStars.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public GiveawayPrize() { - } - } - - /** - * The giveaway sends Telegram Premium subscriptions to the winners. - */ - public static class GiveawayPrizePremium extends GiveawayPrize { - /** - * Number of months the Telegram Premium subscription will be active after code activation. - */ - public int monthCount; - - /** - * The giveaway sends Telegram Premium subscriptions to the winners. - */ - public GiveawayPrizePremium() { - } - - /** - * The giveaway sends Telegram Premium subscriptions to the winners. - * - * @param monthCount Number of months the Telegram Premium subscription will be active after code activation. - */ - public GiveawayPrizePremium(int monthCount) { - this.monthCount = monthCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 454224248; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The giveaway sends Telegram Stars to the winners. - */ - public static class GiveawayPrizeStars extends GiveawayPrize { - /** - * Number of Telegram Stars that will be shared by all winners. - */ - public long starCount; - - /** - * The giveaway sends Telegram Stars to the winners. - */ - public GiveawayPrizeStars() { - } - - /** - * The giveaway sends Telegram Stars to the winners. - * - * @param starCount Number of Telegram Stars that will be shared by all winners. - */ - public GiveawayPrizeStars(long starCount) { - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1790173276; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a group call. - */ - public static class GroupCall extends Object { - /** - * Group call identifier. - */ - public int id; - /** - * Persistent unique group call identifier. - */ - public long uniqueId; - /** - * Group call title; for video chats only. - */ - public String title; - /** - * Invite link for the group call; for group calls that aren't bound to a chat. For video chats call getVideoChatInviteLink to get the link. For live stories in chats with username call getInternalLink with internalLinkTypeLiveStory. - */ - public String inviteLink; - /** - * The minimum number of Telegram Stars that must be paid by general participant for each sent message to the call; for live stories only. - */ - public long paidMessageStarCount; - /** - * Point in time (Unix timestamp) when the group call is expected to be started by an administrator; 0 if it is already active or was ended; for video chats only. - */ - public int scheduledStartDate; - /** - * True, if the group call is scheduled and the current user will receive a notification when the group call starts; for video chats only. - */ - public boolean enabledStartNotification; - /** - * True, if the call is active. - */ - public boolean isActive; - /** - * True, if the call is bound to a chat. - */ - public boolean isVideoChat; - /** - * True, if the call is a live story of a chat. - */ - public boolean isLiveStory; - /** - * True, if the call is an RTMP stream instead of an ordinary video chat; for video chats and live stories only. - */ - public boolean isRtmpStream; - /** - * True, if the call is joined. - */ - public boolean isJoined; - /** - * True, if user was kicked from the call because of network loss and the call needs to be rejoined. - */ - public boolean needRejoin; - /** - * True, if the user is the owner of the call and can end the call, change volume level of other users, or ban users there; for group calls that aren't bound to a chat. - */ - public boolean isOwned; - /** - * True, if the current user can manage the group call; for video chats and live stories only. - */ - public boolean canBeManaged; - /** - * Number of participants in the group call. - */ - public int participantCount; - /** - * True, if group call participants, which are muted, aren't returned in participant list; for video chats only. - */ - public boolean hasHiddenListeners; - /** - * True, if all group call participants are loaded. - */ - public boolean loadedAllParticipants; - /** - * Message sender chosen to send messages to the group call; for live stories only; may be null if the call isn't a live story. - */ - @Nullable public MessageSender messageSenderId; - /** - * At most 3 recently speaking users in the group call. - */ - public GroupCallRecentSpeaker[] recentSpeakers; - /** - * True, if the current user's video is enabled. - */ - public boolean isMyVideoEnabled; - /** - * True, if the current user's video is paused. - */ - public boolean isMyVideoPaused; - /** - * True, if the current user can broadcast video or share screen. - */ - public boolean canEnableVideo; - /** - * True, if only group call administrators can unmute new participants; for video chats only. - */ - public boolean muteNewParticipants; - /** - * True, if the current user can enable or disable muteNewParticipants setting; for video chats only. - */ - public boolean canToggleMuteNewParticipants; - /** - * True, if the current user can send messages to the group call. - */ - public boolean canSendMessages; - /** - * True, if sending of messages is allowed in the group call. - */ - public boolean areMessagesAllowed; - /** - * True, if the current user can enable or disable sending of messages in the group call. - */ - public boolean canToggleAreMessagesAllowed; - /** - * True, if the user can delete messages in the group call. - */ - public boolean canDeleteMessages; - /** - * Duration of the ongoing group call recording, in seconds; 0 if none. An updateGroupCall update is not triggered when value of this field changes, but the same recording goes on. - */ - public int recordDuration; - /** - * True, if a video file is being recorded for the call. - */ - public boolean isVideoRecorded; - /** - * Call duration, in seconds; for ended calls only. - */ - public int duration; - - /** - * Describes a group call. - */ - public GroupCall() { - } - - /** - * Describes a group call. - * - * @param id Group call identifier. - * @param uniqueId Persistent unique group call identifier. - * @param title Group call title; for video chats only. - * @param inviteLink Invite link for the group call; for group calls that aren't bound to a chat. For video chats call getVideoChatInviteLink to get the link. For live stories in chats with username call getInternalLink with internalLinkTypeLiveStory. - * @param paidMessageStarCount The minimum number of Telegram Stars that must be paid by general participant for each sent message to the call; for live stories only. - * @param scheduledStartDate Point in time (Unix timestamp) when the group call is expected to be started by an administrator; 0 if it is already active or was ended; for video chats only. - * @param enabledStartNotification True, if the group call is scheduled and the current user will receive a notification when the group call starts; for video chats only. - * @param isActive True, if the call is active. - * @param isVideoChat True, if the call is bound to a chat. - * @param isLiveStory True, if the call is a live story of a chat. - * @param isRtmpStream True, if the call is an RTMP stream instead of an ordinary video chat; for video chats and live stories only. - * @param isJoined True, if the call is joined. - * @param needRejoin True, if user was kicked from the call because of network loss and the call needs to be rejoined. - * @param isOwned True, if the user is the owner of the call and can end the call, change volume level of other users, or ban users there; for group calls that aren't bound to a chat. - * @param canBeManaged True, if the current user can manage the group call; for video chats and live stories only. - * @param participantCount Number of participants in the group call. - * @param hasHiddenListeners True, if group call participants, which are muted, aren't returned in participant list; for video chats only. - * @param loadedAllParticipants True, if all group call participants are loaded. - * @param messageSenderId Message sender chosen to send messages to the group call; for live stories only; may be null if the call isn't a live story. - * @param recentSpeakers At most 3 recently speaking users in the group call. - * @param isMyVideoEnabled True, if the current user's video is enabled. - * @param isMyVideoPaused True, if the current user's video is paused. - * @param canEnableVideo True, if the current user can broadcast video or share screen. - * @param muteNewParticipants True, if only group call administrators can unmute new participants; for video chats only. - * @param canToggleMuteNewParticipants True, if the current user can enable or disable muteNewParticipants setting; for video chats only. - * @param canSendMessages True, if the current user can send messages to the group call. - * @param areMessagesAllowed True, if sending of messages is allowed in the group call. - * @param canToggleAreMessagesAllowed True, if the current user can enable or disable sending of messages in the group call. - * @param canDeleteMessages True, if the user can delete messages in the group call. - * @param recordDuration Duration of the ongoing group call recording, in seconds; 0 if none. An updateGroupCall update is not triggered when value of this field changes, but the same recording goes on. - * @param isVideoRecorded True, if a video file is being recorded for the call. - * @param duration Call duration, in seconds; for ended calls only. - */ - public GroupCall(int id, long uniqueId, String title, String inviteLink, long paidMessageStarCount, int scheduledStartDate, boolean enabledStartNotification, boolean isActive, boolean isVideoChat, boolean isLiveStory, boolean isRtmpStream, boolean isJoined, boolean needRejoin, boolean isOwned, boolean canBeManaged, int participantCount, boolean hasHiddenListeners, boolean loadedAllParticipants, MessageSender messageSenderId, GroupCallRecentSpeaker[] recentSpeakers, boolean isMyVideoEnabled, boolean isMyVideoPaused, boolean canEnableVideo, boolean muteNewParticipants, boolean canToggleMuteNewParticipants, boolean canSendMessages, boolean areMessagesAllowed, boolean canToggleAreMessagesAllowed, boolean canDeleteMessages, int recordDuration, boolean isVideoRecorded, int duration) { - this.id = id; - this.uniqueId = uniqueId; - this.title = title; - this.inviteLink = inviteLink; - this.paidMessageStarCount = paidMessageStarCount; - this.scheduledStartDate = scheduledStartDate; - this.enabledStartNotification = enabledStartNotification; - this.isActive = isActive; - this.isVideoChat = isVideoChat; - this.isLiveStory = isLiveStory; - this.isRtmpStream = isRtmpStream; - this.isJoined = isJoined; - this.needRejoin = needRejoin; - this.isOwned = isOwned; - this.canBeManaged = canBeManaged; - this.participantCount = participantCount; - this.hasHiddenListeners = hasHiddenListeners; - this.loadedAllParticipants = loadedAllParticipants; - this.messageSenderId = messageSenderId; - this.recentSpeakers = recentSpeakers; - this.isMyVideoEnabled = isMyVideoEnabled; - this.isMyVideoPaused = isMyVideoPaused; - this.canEnableVideo = canEnableVideo; - this.muteNewParticipants = muteNewParticipants; - this.canToggleMuteNewParticipants = canToggleMuteNewParticipants; - this.canSendMessages = canSendMessages; - this.areMessagesAllowed = areMessagesAllowed; - this.canToggleAreMessagesAllowed = canToggleAreMessagesAllowed; - this.canDeleteMessages = canDeleteMessages; - this.recordDuration = recordDuration; - this.isVideoRecorded = isVideoRecorded; - this.duration = duration; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1673382770; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes data channel for a group call. - */ - public abstract static class GroupCallDataChannel extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - GroupCallDataChannelMain.CONSTRUCTOR, - GroupCallDataChannelScreenSharing.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public GroupCallDataChannel() { - } - } - - /** - * The main data channel for audio and video data. - */ - public static class GroupCallDataChannelMain extends GroupCallDataChannel { - - /** - * The main data channel for audio and video data. - */ - public GroupCallDataChannelMain() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -32177779; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The data channel for screen sharing. - */ - public static class GroupCallDataChannelScreenSharing extends GroupCallDataChannel { - - /** - * The data channel for screen sharing. - */ - public GroupCallDataChannelScreenSharing() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -601649103; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains the group call identifier. - */ - public static class GroupCallId extends Object { - /** - * Group call identifier. - */ - public int id; - - /** - * Contains the group call identifier. - */ - public GroupCallId() { - } - - /** - * Contains the group call identifier. - * - * @param id Group call identifier. - */ - public GroupCallId(int id) { - this.id = id; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 350534469; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a just created or just joined group call. - */ - public static class GroupCallInfo extends Object { - /** - * Identifier of the group call. - */ - public int groupCallId; - /** - * Join response payload for tgcalls; empty if the call isn't joined. - */ - public String joinPayload; - - /** - * Contains information about a just created or just joined group call. - */ - public GroupCallInfo() { - } - - /** - * Contains information about a just created or just joined group call. - * - * @param groupCallId Identifier of the group call. - * @param joinPayload Join response payload for tgcalls; empty if the call isn't joined. - */ - public GroupCallInfo(int groupCallId, String joinPayload) { - this.groupCallId = groupCallId; - this.joinPayload = joinPayload; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 892575956; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes parameters used to join a group call. - */ - public static class GroupCallJoinParameters extends Object { - /** - * Audio channel synchronization source identifier; received from tgcalls. - */ - public int audioSourceId; - /** - * Group call join payload; received from tgcalls. - */ - public String payload; - /** - * Pass true to join the call with muted microphone. - */ - public boolean isMuted; - /** - * Pass true if the user's video is enabled. - */ - public boolean isMyVideoEnabled; - - /** - * Describes parameters used to join a group call. - */ - public GroupCallJoinParameters() { - } - - /** - * Describes parameters used to join a group call. - * - * @param audioSourceId Audio channel synchronization source identifier; received from tgcalls. - * @param payload Group call join payload; received from tgcalls. - * @param isMuted Pass true to join the call with muted microphone. - * @param isMyVideoEnabled Pass true if the user's video is enabled. - */ - public GroupCallJoinParameters(int audioSourceId, String payload, boolean isMuted, boolean isMyVideoEnabled) { - this.audioSourceId = audioSourceId; - this.payload = payload; - this.isMuted = isMuted; - this.isMyVideoEnabled = isMyVideoEnabled; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1763438054; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a message sent in a group call. - */ - public static class GroupCallMessage extends Object { - /** - * Unique message identifier within the group call. - */ - public int messageId; - /** - * Identifier of the sender of the message. - */ - public MessageSender senderId; - /** - * Point in time (Unix timestamp) when the message was sent. - */ - public int date; - /** - * Text of the message. If empty, then the message is a paid reaction in a live story. - */ - public FormattedText text; - /** - * The number of Telegram Stars that were paid to send the message; for live stories only. - */ - public long paidMessageStarCount; - /** - * True, if the message is sent by the owner of the call and must be treated as a message of the maximum level; for live stories only. - */ - public boolean isFromOwner; - /** - * True, if the message can be deleted by the current user; for live stories only. - */ - public boolean canBeDeleted; - - /** - * Represents a message sent in a group call. - */ - public GroupCallMessage() { - } - - /** - * Represents a message sent in a group call. - * - * @param messageId Unique message identifier within the group call. - * @param senderId Identifier of the sender of the message. - * @param date Point in time (Unix timestamp) when the message was sent. - * @param text Text of the message. If empty, then the message is a paid reaction in a live story. - * @param paidMessageStarCount The number of Telegram Stars that were paid to send the message; for live stories only. - * @param isFromOwner True, if the message is sent by the owner of the call and must be treated as a message of the maximum level; for live stories only. - * @param canBeDeleted True, if the message can be deleted by the current user; for live stories only. - */ - public GroupCallMessage(int messageId, MessageSender senderId, int date, FormattedText text, long paidMessageStarCount, boolean isFromOwner, boolean canBeDeleted) { - this.messageId = messageId; - this.senderId = senderId; - this.date = date; - this.text = text; - this.paidMessageStarCount = paidMessageStarCount; - this.isFromOwner = isFromOwner; - this.canBeDeleted = canBeDeleted; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 216155597; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a level of features for a message sent in a live story group call. - */ - public static class GroupCallMessageLevel extends Object { - /** - * The minimum number of Telegram Stars required to get features of the level. - */ - public long minStarCount; - /** - * The amount of time the message of this level will be pinned, in seconds. - */ - public int pinDuration; - /** - * The maximum allowed length of the message text. - */ - public int maxTextLength; - /** - * The maximum allowed number of custom emoji in the message text. - */ - public int maxCustomEmojiCount; - /** - * The first color used to show the message text in the RGB format. - */ - public int firstColor; - /** - * The second color used to show the message text in the RGB format. - */ - public int secondColor; - /** - * Background color for the message the RGB format. - */ - public int backgroundColor; - - /** - * Represents a level of features for a message sent in a live story group call. - */ - public GroupCallMessageLevel() { - } - - /** - * Represents a level of features for a message sent in a live story group call. - * - * @param minStarCount The minimum number of Telegram Stars required to get features of the level. - * @param pinDuration The amount of time the message of this level will be pinned, in seconds. - * @param maxTextLength The maximum allowed length of the message text. - * @param maxCustomEmojiCount The maximum allowed number of custom emoji in the message text. - * @param firstColor The first color used to show the message text in the RGB format. - * @param secondColor The second color used to show the message text in the RGB format. - * @param backgroundColor Background color for the message the RGB format. - */ - public GroupCallMessageLevel(long minStarCount, int pinDuration, int maxTextLength, int maxCustomEmojiCount, int firstColor, int secondColor, int backgroundColor) { - this.minStarCount = minStarCount; - this.pinDuration = pinDuration; - this.maxTextLength = maxTextLength; - this.maxCustomEmojiCount = maxCustomEmojiCount; - this.firstColor = firstColor; - this.secondColor = secondColor; - this.backgroundColor = backgroundColor; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 994685918; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a group call participant. - */ - public static class GroupCallParticipant extends Object { - /** - * Identifier of the group call participant. - */ - public MessageSender participantId; - /** - * User's audio channel synchronization source identifier. - */ - public int audioSourceId; - /** - * User's screen sharing audio channel synchronization source identifier. - */ - public int screenSharingAudioSourceId; - /** - * Information about user's video channel; may be null if there is no active video. - */ - @Nullable public GroupCallParticipantVideoInfo videoInfo; - /** - * Information about user's screen sharing video channel; may be null if there is no active screen sharing video. - */ - @Nullable public GroupCallParticipantVideoInfo screenSharingVideoInfo; - /** - * The participant user's bio or the participant chat's description. - */ - public String bio; - /** - * True, if the participant is the current user. - */ - public boolean isCurrentUser; - /** - * True, if the participant is speaking as set by setGroupCallParticipantIsSpeaking. - */ - public boolean isSpeaking; - /** - * True, if the participant hand is raised. - */ - public boolean isHandRaised; - /** - * True, if the current user can mute the participant for all other group call participants. - */ - public boolean canBeMutedForAllUsers; - /** - * True, if the current user can allow the participant to unmute themselves or unmute the participant (if the participant is the current user). - */ - public boolean canBeUnmutedForAllUsers; - /** - * True, if the current user can mute the participant only for self. - */ - public boolean canBeMutedForCurrentUser; - /** - * True, if the current user can unmute the participant for self. - */ - public boolean canBeUnmutedForCurrentUser; - /** - * True, if the participant is muted for all users. - */ - public boolean isMutedForAllUsers; - /** - * True, if the participant is muted for the current user. - */ - public boolean isMutedForCurrentUser; - /** - * True, if the participant is muted for all users, but can unmute themselves. - */ - public boolean canUnmuteSelf; - /** - * Participant's volume level; 1-20000 in hundreds of percents. - */ - public int volumeLevel; - /** - * User's order in the group call participant list. Orders must be compared lexicographically. The bigger is order, the higher is user in the list. If order is empty, the user must be removed from the participant list. - */ - public String order; - - /** - * Represents a group call participant. - */ - public GroupCallParticipant() { - } - - /** - * Represents a group call participant. - * - * @param participantId Identifier of the group call participant. - * @param audioSourceId User's audio channel synchronization source identifier. - * @param screenSharingAudioSourceId User's screen sharing audio channel synchronization source identifier. - * @param videoInfo Information about user's video channel; may be null if there is no active video. - * @param screenSharingVideoInfo Information about user's screen sharing video channel; may be null if there is no active screen sharing video. - * @param bio The participant user's bio or the participant chat's description. - * @param isCurrentUser True, if the participant is the current user. - * @param isSpeaking True, if the participant is speaking as set by setGroupCallParticipantIsSpeaking. - * @param isHandRaised True, if the participant hand is raised. - * @param canBeMutedForAllUsers True, if the current user can mute the participant for all other group call participants. - * @param canBeUnmutedForAllUsers True, if the current user can allow the participant to unmute themselves or unmute the participant (if the participant is the current user). - * @param canBeMutedForCurrentUser True, if the current user can mute the participant only for self. - * @param canBeUnmutedForCurrentUser True, if the current user can unmute the participant for self. - * @param isMutedForAllUsers True, if the participant is muted for all users. - * @param isMutedForCurrentUser True, if the participant is muted for the current user. - * @param canUnmuteSelf True, if the participant is muted for all users, but can unmute themselves. - * @param volumeLevel Participant's volume level; 1-20000 in hundreds of percents. - * @param order User's order in the group call participant list. Orders must be compared lexicographically. The bigger is order, the higher is user in the list. If order is empty, the user must be removed from the participant list. - */ - public GroupCallParticipant(MessageSender participantId, int audioSourceId, int screenSharingAudioSourceId, GroupCallParticipantVideoInfo videoInfo, GroupCallParticipantVideoInfo screenSharingVideoInfo, String bio, boolean isCurrentUser, boolean isSpeaking, boolean isHandRaised, boolean canBeMutedForAllUsers, boolean canBeUnmutedForAllUsers, boolean canBeMutedForCurrentUser, boolean canBeUnmutedForCurrentUser, boolean isMutedForAllUsers, boolean isMutedForCurrentUser, boolean canUnmuteSelf, int volumeLevel, String order) { - this.participantId = participantId; - this.audioSourceId = audioSourceId; - this.screenSharingAudioSourceId = screenSharingAudioSourceId; - this.videoInfo = videoInfo; - this.screenSharingVideoInfo = screenSharingVideoInfo; - this.bio = bio; - this.isCurrentUser = isCurrentUser; - this.isSpeaking = isSpeaking; - this.isHandRaised = isHandRaised; - this.canBeMutedForAllUsers = canBeMutedForAllUsers; - this.canBeUnmutedForAllUsers = canBeUnmutedForAllUsers; - this.canBeMutedForCurrentUser = canBeMutedForCurrentUser; - this.canBeUnmutedForCurrentUser = canBeUnmutedForCurrentUser; - this.isMutedForAllUsers = isMutedForAllUsers; - this.isMutedForCurrentUser = isMutedForCurrentUser; - this.canUnmuteSelf = canUnmuteSelf; - this.volumeLevel = volumeLevel; - this.order = order; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2059182571; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a group call participant's video channel. - */ - public static class GroupCallParticipantVideoInfo extends Object { - /** - * List of synchronization source groups of the video. - */ - public GroupCallVideoSourceGroup[] sourceGroups; - /** - * Video channel endpoint identifier. - */ - public String endpointId; - /** - * True, if the video is paused. This flag needs to be ignored, if new video frames are received. - */ - public boolean isPaused; - - /** - * Contains information about a group call participant's video channel. - */ - public GroupCallParticipantVideoInfo() { - } - - /** - * Contains information about a group call participant's video channel. - * - * @param sourceGroups List of synchronization source groups of the video. - * @param endpointId Video channel endpoint identifier. - * @param isPaused True, if the video is paused. This flag needs to be ignored, if new video frames are received. - */ - public GroupCallParticipantVideoInfo(GroupCallVideoSourceGroup[] sourceGroups, String endpointId, boolean isPaused) { - this.sourceGroups = sourceGroups; - this.endpointId = endpointId; - this.isPaused = isPaused; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -14294645; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains identifiers of group call participants. - */ - public static class GroupCallParticipants extends Object { - /** - * Total number of group call participants. - */ - public int totalCount; - /** - * Identifiers of the participants. - */ - public MessageSender[] participantIds; - - /** - * Contains identifiers of group call participants. - */ - public GroupCallParticipants() { - } - - /** - * Contains identifiers of group call participants. - * - * @param totalCount Total number of group call participants. - * @param participantIds Identifiers of the participants. - */ - public GroupCallParticipants(int totalCount, MessageSender[] participantIds) { - this.totalCount = totalCount; - this.participantIds = participantIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1042491570; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a recently speaking participant in a group call. - */ - public static class GroupCallRecentSpeaker extends Object { - /** - * Group call participant identifier. - */ - public MessageSender participantId; - /** - * True, is the user has spoken recently. - */ - public boolean isSpeaking; - - /** - * Describes a recently speaking participant in a group call. - */ - public GroupCallRecentSpeaker() { - } - - /** - * Describes a recently speaking participant in a group call. - * - * @param participantId Group call participant identifier. - * @param isSpeaking True, is the user has spoken recently. - */ - public GroupCallRecentSpeaker(MessageSender participantId, boolean isSpeaking) { - this.participantId = participantId; - this.isSpeaking = isSpeaking; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1819519436; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an available stream in a video chat or a live story. - */ - public static class GroupCallStream extends Object { - /** - * Identifier of an audio/video channel. - */ - public int channelId; - /** - * Scale of segment durations in the stream. The duration is 1000/(2**scale) milliseconds. - */ - public int scale; - /** - * Point in time when the stream currently ends; Unix timestamp in milliseconds. - */ - public long timeOffset; - - /** - * Describes an available stream in a video chat or a live story. - */ - public GroupCallStream() { - } - - /** - * Describes an available stream in a video chat or a live story. - * - * @param channelId Identifier of an audio/video channel. - * @param scale Scale of segment durations in the stream. The duration is 1000/(2**scale) milliseconds. - * @param timeOffset Point in time when the stream currently ends; Unix timestamp in milliseconds. - */ - public GroupCallStream(int channelId, int scale, long timeOffset) { - this.channelId = channelId; - this.scale = scale; - this.timeOffset = timeOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -264564795; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of group call streams. - */ - public static class GroupCallStreams extends Object { - /** - * A list of group call streams. - */ - public GroupCallStream[] streams; - - /** - * Represents a list of group call streams. - */ - public GroupCallStreams() { - } - - /** - * Represents a list of group call streams. - * - * @param streams A list of group call streams. - */ - public GroupCallStreams(GroupCallStream[] streams) { - this.streams = streams; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1032959578; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the quality of a group call video. - */ - public abstract static class GroupCallVideoQuality extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - GroupCallVideoQualityThumbnail.CONSTRUCTOR, - GroupCallVideoQualityMedium.CONSTRUCTOR, - GroupCallVideoQualityFull.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public GroupCallVideoQuality() { - } - } - - /** - * The worst available video quality. - */ - public static class GroupCallVideoQualityThumbnail extends GroupCallVideoQuality { - - /** - * The worst available video quality. - */ - public GroupCallVideoQualityThumbnail() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -379186304; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The medium video quality. - */ - public static class GroupCallVideoQualityMedium extends GroupCallVideoQuality { - - /** - * The medium video quality. - */ - public GroupCallVideoQualityMedium() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 394968234; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The best available video quality. - */ - public static class GroupCallVideoQualityFull extends GroupCallVideoQuality { - - /** - * The best available video quality. - */ - public GroupCallVideoQualityFull() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2125916617; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a group of video synchronization source identifiers. - */ - public static class GroupCallVideoSourceGroup extends Object { - /** - * The semantics of sources, one of "SIM" or "FID". - */ - public String semantics; - /** - * The list of synchronization source identifiers. - */ - public int[] sourceIds; - - /** - * Describes a group of video synchronization source identifiers. - */ - public GroupCallVideoSourceGroup() { - } - - /** - * Describes a group of video synchronization source identifiers. - * - * @param semantics The semantics of sources, one of "SIM" or "FID". - * @param sourceIds The list of synchronization source identifiers. - */ - public GroupCallVideoSourceGroup(String semantics, int[] sourceIds) { - this.semantics = semantics; - this.sourceIds = sourceIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1190900785; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of hashtags. - */ - public static class Hashtags extends Object { - /** - * A list of hashtags. - */ - public String[] hashtags; - - /** - * Contains a list of hashtags. - */ - public Hashtags() { - } - - /** - * Contains a list of hashtags. - * - * @param hashtags A list of hashtags. - */ - public Hashtags(String[] hashtags) { - this.hashtags = hashtags; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 676798885; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains an HTTP URL. - */ - public static class HttpUrl extends Object { - /** - * The URL. - */ - public String url; - - /** - * Contains an HTTP URL. - */ - public HttpUrl() { - } - - /** - * Contains an HTTP URL. - * - * @param url The URL. - */ - public HttpUrl(String url) { - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2018019930; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An identity document. - */ - public static class IdentityDocument extends Object { - /** - * Document number; 1-24 characters. - */ - public String number; - /** - * Document expiration date; may be null if not applicable. - */ - @Nullable public Date expirationDate; - /** - * Front side of the document. - */ - public DatedFile frontSide; - /** - * Reverse side of the document; only for driver license and identity card; may be null. - */ - @Nullable public DatedFile reverseSide; - /** - * Selfie with the document; may be null. - */ - @Nullable public DatedFile selfie; - /** - * List of files containing a certified English translation of the document. - */ - public DatedFile[] translation; - - /** - * An identity document. - */ - public IdentityDocument() { - } - - /** - * An identity document. - * - * @param number Document number; 1-24 characters. - * @param expirationDate Document expiration date; may be null if not applicable. - * @param frontSide Front side of the document. - * @param reverseSide Reverse side of the document; only for driver license and identity card; may be null. - * @param selfie Selfie with the document; may be null. - * @param translation List of files containing a certified English translation of the document. - */ - public IdentityDocument(String number, Date expirationDate, DatedFile frontSide, DatedFile reverseSide, DatedFile selfie, DatedFile[] translation) { - this.number = number; - this.expirationDate = expirationDate; - this.frontSide = frontSide; - this.reverseSide = reverseSide; - this.selfie = selfie; - this.translation = translation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1001703606; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a contact to import. - */ - public static class ImportedContact extends Object { - /** - * Phone number of the user. - */ - public String phoneNumber; - /** - * First name of the user; 1-64 characters. - */ - public String firstName; - /** - * Last name of the user; 0-64 characters. - */ - public String lastName; - /** - * Note to add about the user; 0-getOption("user_note_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed; pass null to keep the current user's note. - */ - public FormattedText note; - - /** - * Describes a contact to import. - */ - public ImportedContact() { - } - - /** - * Describes a contact to import. - * - * @param phoneNumber Phone number of the user. - * @param firstName First name of the user; 1-64 characters. - * @param lastName Last name of the user; 0-64 characters. - * @param note Note to add about the user; 0-getOption("user_note_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed; pass null to keep the current user's note. - */ - public ImportedContact(String phoneNumber, String firstName, String lastName, FormattedText note) { - this.phoneNumber = phoneNumber; - this.firstName = firstName; - this.lastName = lastName; - this.note = note; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1818209156; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents the result of an importContacts request. - */ - public static class ImportedContacts extends Object { - /** - * User identifiers of the imported contacts in the same order as they were specified in the request; 0 if the contact is not yet a registered user. - */ - public long[] userIds; - /** - * The number of users that imported the corresponding contact; 0 for already registered users or if unavailable. - */ - public int[] importerCount; - - /** - * Represents the result of an importContacts request. - */ - public ImportedContacts() { - } - - /** - * Represents the result of an importContacts request. - * - * @param userIds User identifiers of the imported contacts in the same order as they were specified in the request; 0 if the contact is not yet a registered user. - * @param importerCount The number of users that imported the corresponding contact; 0 for already registered users or if unavailable. - */ - public ImportedContacts(long[] userIds, int[] importerCount) { - this.userIds = userIds; - this.importerCount = importerCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2068432290; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a single button in an inline keyboard. - */ - public static class InlineKeyboardButton extends Object { - /** - * Text of the button. - */ - public String text; - /** - * Identifier of the custom emoji that must be shown on the button; 0 if none. - */ - public long iconCustomEmojiId; - /** - * Style of the button. - */ - public ButtonStyle style; - /** - * Type of the button. - */ - public InlineKeyboardButtonType type; - - /** - * Represents a single button in an inline keyboard. - */ - public InlineKeyboardButton() { - } - - /** - * Represents a single button in an inline keyboard. - * - * @param text Text of the button. - * @param iconCustomEmojiId Identifier of the custom emoji that must be shown on the button; 0 if none. - * @param style Style of the button. - * @param type Type of the button. - */ - public InlineKeyboardButton(String text, long iconCustomEmojiId, ButtonStyle style, InlineKeyboardButtonType type) { - this.text = text; - this.iconCustomEmojiId = iconCustomEmojiId; - this.style = style; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1457530830; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the type of inline keyboard button. - */ - public abstract static class InlineKeyboardButtonType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InlineKeyboardButtonTypeUrl.CONSTRUCTOR, - InlineKeyboardButtonTypeLoginUrl.CONSTRUCTOR, - InlineKeyboardButtonTypeWebApp.CONSTRUCTOR, - InlineKeyboardButtonTypeCallback.CONSTRUCTOR, - InlineKeyboardButtonTypeCallbackWithPassword.CONSTRUCTOR, - InlineKeyboardButtonTypeCallbackGame.CONSTRUCTOR, - InlineKeyboardButtonTypeSwitchInline.CONSTRUCTOR, - InlineKeyboardButtonTypeBuy.CONSTRUCTOR, - InlineKeyboardButtonTypeUser.CONSTRUCTOR, - InlineKeyboardButtonTypeCopyText.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InlineKeyboardButtonType() { - } - } - - /** - * A button that opens a specified URL. - */ - public static class InlineKeyboardButtonTypeUrl extends InlineKeyboardButtonType { - /** - * HTTP or tg:// URL to open. If the link is of the type internalLinkTypeWebApp, then the button must be marked as a Web App button. - */ - public String url; - - /** - * A button that opens a specified URL. - */ - public InlineKeyboardButtonTypeUrl() { - } - - /** - * A button that opens a specified URL. - * - * @param url HTTP or tg:// URL to open. If the link is of the type internalLinkTypeWebApp, then the button must be marked as a Web App button. - */ - public InlineKeyboardButtonTypeUrl(String url) { - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1130741420; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A button that opens a specified URL and automatically authorize the current user by calling getLoginUrlInfo. - */ - public static class InlineKeyboardButtonTypeLoginUrl extends InlineKeyboardButtonType { - /** - * An HTTP URL to pass to getLoginUrlInfo. - */ - public String url; - /** - * Unique button identifier. - */ - public long id; - /** - * If non-empty, new text of the button in forwarded messages. - */ - public String forwardText; - - /** - * A button that opens a specified URL and automatically authorize the current user by calling getLoginUrlInfo. - */ - public InlineKeyboardButtonTypeLoginUrl() { - } - - /** - * A button that opens a specified URL and automatically authorize the current user by calling getLoginUrlInfo. - * - * @param url An HTTP URL to pass to getLoginUrlInfo. - * @param id Unique button identifier. - * @param forwardText If non-empty, new text of the button in forwarded messages. - */ - public InlineKeyboardButtonTypeLoginUrl(String url, long id, String forwardText) { - this.url = url; - this.id = id; - this.forwardText = forwardText; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1203413081; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A button that opens a Web App by calling openWebApp. - */ - public static class InlineKeyboardButtonTypeWebApp extends InlineKeyboardButtonType { - /** - * An HTTP URL to pass to openWebApp. - */ - public String url; - - /** - * A button that opens a Web App by calling openWebApp. - */ - public InlineKeyboardButtonTypeWebApp() { - } - - /** - * A button that opens a Web App by calling openWebApp. - * - * @param url An HTTP URL to pass to openWebApp. - */ - public InlineKeyboardButtonTypeWebApp(String url) { - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1767471672; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A button that sends a callback query to a bot. - */ - public static class InlineKeyboardButtonTypeCallback extends InlineKeyboardButtonType { - /** - * Data to be sent to the bot via a callback query. - */ - public byte[] data; - - /** - * A button that sends a callback query to a bot. - */ - public InlineKeyboardButtonTypeCallback() { - } - - /** - * A button that sends a callback query to a bot. - * - * @param data Data to be sent to the bot via a callback query. - */ - public InlineKeyboardButtonTypeCallback(byte[] data) { - this.data = data; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1127515139; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A button that asks for the 2-step verification password of the current user and then sends a callback query to a bot. - */ - public static class InlineKeyboardButtonTypeCallbackWithPassword extends InlineKeyboardButtonType { - /** - * Data to be sent to the bot via a callback query. - */ - public byte[] data; - - /** - * A button that asks for the 2-step verification password of the current user and then sends a callback query to a bot. - */ - public InlineKeyboardButtonTypeCallbackWithPassword() { - } - - /** - * A button that asks for the 2-step verification password of the current user and then sends a callback query to a bot. - * - * @param data Data to be sent to the bot via a callback query. - */ - public InlineKeyboardButtonTypeCallbackWithPassword(byte[] data) { - this.data = data; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 908018248; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A button with a game that sends a callback query to a bot. This button must be in the first column and row of the keyboard and can be attached only to a message with content of the type messageGame. - */ - public static class InlineKeyboardButtonTypeCallbackGame extends InlineKeyboardButtonType { - - /** - * A button with a game that sends a callback query to a bot. This button must be in the first column and row of the keyboard and can be attached only to a message with content of the type messageGame. - */ - public InlineKeyboardButtonTypeCallbackGame() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -383429528; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A button that forces an inline query to the bot to be inserted in the input field. - */ - public static class InlineKeyboardButtonTypeSwitchInline extends InlineKeyboardButtonType { - /** - * Inline query to be sent to the bot. - */ - public String query; - /** - * Target chat from which to send the inline query. - */ - public TargetChat targetChat; - - /** - * A button that forces an inline query to the bot to be inserted in the input field. - */ - public InlineKeyboardButtonTypeSwitchInline() { - } - - /** - * A button that forces an inline query to the bot to be inserted in the input field. - * - * @param query Inline query to be sent to the bot. - * @param targetChat Target chat from which to send the inline query. - */ - public InlineKeyboardButtonTypeSwitchInline(String query, TargetChat targetChat) { - this.query = query; - this.targetChat = targetChat; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 544906485; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A button to buy something. This button must be in the first column and row of the keyboard and can be attached only to a message with content of the type messageInvoice. - */ - public static class InlineKeyboardButtonTypeBuy extends InlineKeyboardButtonType { - - /** - * A button to buy something. This button must be in the first column and row of the keyboard and can be attached only to a message with content of the type messageInvoice. - */ - public InlineKeyboardButtonTypeBuy() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1360739440; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A button with a user reference to be handled in the same way as textEntityTypeMentionName entities. - */ - public static class InlineKeyboardButtonTypeUser extends InlineKeyboardButtonType { - /** - * User identifier. - */ - public long userId; - - /** - * A button with a user reference to be handled in the same way as textEntityTypeMentionName entities. - */ - public InlineKeyboardButtonTypeUser() { - } - - /** - * A button with a user reference to be handled in the same way as textEntityTypeMentionName entities. - * - * @param userId User identifier. - */ - public InlineKeyboardButtonTypeUser(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1836574114; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A button that copies specified text to clipboard. - */ - public static class InlineKeyboardButtonTypeCopyText extends InlineKeyboardButtonType { - /** - * The text to copy to clipboard. - */ - public String text; - - /** - * A button that copies specified text to clipboard. - */ - public InlineKeyboardButtonTypeCopyText() { - } - - /** - * A button that copies specified text to clipboard. - * - * @param text The text to copy to clipboard. - */ - public InlineKeyboardButtonTypeCopyText(String text) { - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 68883206; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents a single result of an inline query. - */ - public abstract static class InlineQueryResult extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InlineQueryResultArticle.CONSTRUCTOR, - InlineQueryResultContact.CONSTRUCTOR, - InlineQueryResultLocation.CONSTRUCTOR, - InlineQueryResultVenue.CONSTRUCTOR, - InlineQueryResultGame.CONSTRUCTOR, - InlineQueryResultAnimation.CONSTRUCTOR, - InlineQueryResultAudio.CONSTRUCTOR, - InlineQueryResultDocument.CONSTRUCTOR, - InlineQueryResultPhoto.CONSTRUCTOR, - InlineQueryResultSticker.CONSTRUCTOR, - InlineQueryResultVideo.CONSTRUCTOR, - InlineQueryResultVoiceNote.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InlineQueryResult() { - } - } - - /** - * Represents a link to an article or web page. - */ - public static class InlineQueryResultArticle extends InlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * URL of the result, if it exists. - */ - public String url; - /** - * Title of the result. - */ - public String title; - /** - * A short description of the result. - */ - public String description; - /** - * Result thumbnail in JPEG format; may be null. - */ - @Nullable public Thumbnail thumbnail; - - /** - * Represents a link to an article or web page. - */ - public InlineQueryResultArticle() { - } - - /** - * Represents a link to an article or web page. - * - * @param id Unique identifier of the query result. - * @param url URL of the result, if it exists. - * @param title Title of the result. - * @param description A short description of the result. - * @param thumbnail Result thumbnail in JPEG format; may be null. - */ - public InlineQueryResultArticle(String id, String url, String title, String description, Thumbnail thumbnail) { - this.id = id; - this.url = url; - this.title = title; - this.description = description; - this.thumbnail = thumbnail; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 269930522; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a user contact. - */ - public static class InlineQueryResultContact extends InlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * A user contact. - */ - public Contact contact; - /** - * Result thumbnail in JPEG format; may be null. - */ - @Nullable public Thumbnail thumbnail; - - /** - * Represents a user contact. - */ - public InlineQueryResultContact() { - } - - /** - * Represents a user contact. - * - * @param id Unique identifier of the query result. - * @param contact A user contact. - * @param thumbnail Result thumbnail in JPEG format; may be null. - */ - public InlineQueryResultContact(String id, Contact contact, Thumbnail thumbnail) { - this.id = id; - this.contact = contact; - this.thumbnail = thumbnail; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -181960174; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a point on the map. - */ - public static class InlineQueryResultLocation extends InlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Location result. - */ - public Location location; - /** - * Title of the result. - */ - public String title; - /** - * Result thumbnail in JPEG format; may be null. - */ - @Nullable public Thumbnail thumbnail; - - /** - * Represents a point on the map. - */ - public InlineQueryResultLocation() { - } - - /** - * Represents a point on the map. - * - * @param id Unique identifier of the query result. - * @param location Location result. - * @param title Title of the result. - * @param thumbnail Result thumbnail in JPEG format; may be null. - */ - public InlineQueryResultLocation(String id, Location location, String title, Thumbnail thumbnail) { - this.id = id; - this.location = location; - this.title = title; - this.thumbnail = thumbnail; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 466004752; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents information about a venue. - */ - public static class InlineQueryResultVenue extends InlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Venue result. - */ - public Venue venue; - /** - * Result thumbnail in JPEG format; may be null. - */ - @Nullable public Thumbnail thumbnail; - - /** - * Represents information about a venue. - */ - public InlineQueryResultVenue() { - } - - /** - * Represents information about a venue. - * - * @param id Unique identifier of the query result. - * @param venue Venue result. - * @param thumbnail Result thumbnail in JPEG format; may be null. - */ - public InlineQueryResultVenue(String id, Venue venue, Thumbnail thumbnail) { - this.id = id; - this.venue = venue; - this.thumbnail = thumbnail; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1281036382; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents information about a game. - */ - public static class InlineQueryResultGame extends InlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Game result. - */ - public Game game; - - /** - * Represents information about a game. - */ - public InlineQueryResultGame() { - } - - /** - * Represents information about a game. - * - * @param id Unique identifier of the query result. - * @param game Game result. - */ - public InlineQueryResultGame(String id, Game game) { - this.id = id; - this.game = game; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1706916987; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents an animation file. - */ - public static class InlineQueryResultAnimation extends InlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Animation file. - */ - public Animation animation; - /** - * Animation title. - */ - public String title; - - /** - * Represents an animation file. - */ - public InlineQueryResultAnimation() { - } - - /** - * Represents an animation file. - * - * @param id Unique identifier of the query result. - * @param animation Animation file. - * @param title Animation title. - */ - public InlineQueryResultAnimation(String id, Animation animation, String title) { - this.id = id; - this.animation = animation; - this.title = title; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2009984267; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents an audio file. - */ - public static class InlineQueryResultAudio extends InlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Audio file. - */ - public Audio audio; - - /** - * Represents an audio file. - */ - public InlineQueryResultAudio() { - } - - /** - * Represents an audio file. - * - * @param id Unique identifier of the query result. - * @param audio Audio file. - */ - public InlineQueryResultAudio(String id, Audio audio) { - this.id = id; - this.audio = audio; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 842650360; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a document. - */ - public static class InlineQueryResultDocument extends InlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Document. - */ - public Document document; - /** - * Document title. - */ - public String title; - /** - * Document description. - */ - public String description; - - /** - * Represents a document. - */ - public InlineQueryResultDocument() { - } - - /** - * Represents a document. - * - * @param id Unique identifier of the query result. - * @param document Document. - * @param title Document title. - * @param description Document description. - */ - public InlineQueryResultDocument(String id, Document document, String title, String description) { - this.id = id; - this.document = document; - this.title = title; - this.description = description; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1491268539; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a photo. - */ - public static class InlineQueryResultPhoto extends InlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Photo. - */ - public Photo photo; - /** - * Title of the result, if known. - */ - public String title; - /** - * A short description of the result, if known. - */ - public String description; - - /** - * Represents a photo. - */ - public InlineQueryResultPhoto() { - } - - /** - * Represents a photo. - * - * @param id Unique identifier of the query result. - * @param photo Photo. - * @param title Title of the result, if known. - * @param description A short description of the result, if known. - */ - public InlineQueryResultPhoto(String id, Photo photo, String title, String description) { - this.id = id; - this.photo = photo; - this.title = title; - this.description = description; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1848319440; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a sticker. - */ - public static class InlineQueryResultSticker extends InlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Sticker. - */ - public Sticker sticker; - - /** - * Represents a sticker. - */ - public InlineQueryResultSticker() { - } - - /** - * Represents a sticker. - * - * @param id Unique identifier of the query result. - * @param sticker Sticker. - */ - public InlineQueryResultSticker(String id, Sticker sticker) { - this.id = id; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1848224245; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a video. - */ - public static class InlineQueryResultVideo extends InlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Video. - */ - public Video video; - /** - * Title of the video. - */ - public String title; - /** - * Description of the video. - */ - public String description; - - /** - * Represents a video. - */ - public InlineQueryResultVideo() { - } - - /** - * Represents a video. - * - * @param id Unique identifier of the query result. - * @param video Video. - * @param title Title of the video. - * @param description Description of the video. - */ - public InlineQueryResultVideo(String id, Video video, String title, String description) { - this.id = id; - this.video = video; - this.title = title; - this.description = description; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1373158683; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a voice note. - */ - public static class InlineQueryResultVoiceNote extends InlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Voice note. - */ - public VoiceNote voiceNote; - /** - * Title of the voice note. - */ - public String title; - - /** - * Represents a voice note. - */ - public InlineQueryResultVoiceNote() { - } - - /** - * Represents a voice note. - * - * @param id Unique identifier of the query result. - * @param voiceNote Voice note. - * @param title Title of the voice note. - */ - public InlineQueryResultVoiceNote(String id, VoiceNote voiceNote, String title) { - this.id = id; - this.voiceNote = voiceNote; - this.title = title; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1897393105; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents the results of the inline query. Use sendInlineQueryResultMessage to send the result of the query. - */ - public static class InlineQueryResults extends Object { - /** - * Unique identifier of the inline query. - */ - public long inlineQueryId; - /** - * Button to be shown above inline query results; may be null. - */ - @Nullable public InlineQueryResultsButton button; - /** - * Results of the query. - */ - public InlineQueryResult[] results; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Represents the results of the inline query. Use sendInlineQueryResultMessage to send the result of the query. - */ - public InlineQueryResults() { - } - - /** - * Represents the results of the inline query. Use sendInlineQueryResultMessage to send the result of the query. - * - * @param inlineQueryId Unique identifier of the inline query. - * @param button Button to be shown above inline query results; may be null. - * @param results Results of the query. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public InlineQueryResults(long inlineQueryId, InlineQueryResultsButton button, InlineQueryResult[] results, String nextOffset) { - this.inlineQueryId = inlineQueryId; - this.button = button; - this.results = results; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1830685615; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a button to be shown above inline query results. - */ - public static class InlineQueryResultsButton extends Object { - /** - * The text of the button. - */ - public String text; - /** - * Type of the button. - */ - public InlineQueryResultsButtonType type; - - /** - * Represents a button to be shown above inline query results. - */ - public InlineQueryResultsButton() { - } - - /** - * Represents a button to be shown above inline query results. - * - * @param text The text of the button. - * @param type Type of the button. - */ - public InlineQueryResultsButton(String text, InlineQueryResultsButtonType type) { - this.text = text; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -790689618; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents type of button in results of inline query. - */ - public abstract static class InlineQueryResultsButtonType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InlineQueryResultsButtonTypeStartBot.CONSTRUCTOR, - InlineQueryResultsButtonTypeWebApp.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InlineQueryResultsButtonType() { - } - } - - /** - * Describes the button that opens a private chat with the bot and sends a start message to the bot with the given parameter. - */ - public static class InlineQueryResultsButtonTypeStartBot extends InlineQueryResultsButtonType { - /** - * The parameter for the bot start message. - */ - public String parameter; - - /** - * Describes the button that opens a private chat with the bot and sends a start message to the bot with the given parameter. - */ - public InlineQueryResultsButtonTypeStartBot() { - } - - /** - * Describes the button that opens a private chat with the bot and sends a start message to the bot with the given parameter. - * - * @param parameter The parameter for the bot start message. - */ - public InlineQueryResultsButtonTypeStartBot(String parameter) { - this.parameter = parameter; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -23400235; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes the button that opens a Web App by calling getWebAppUrl. - */ - public static class InlineQueryResultsButtonTypeWebApp extends InlineQueryResultsButtonType { - /** - * An HTTP URL to pass to getWebAppUrl. - */ - public String url; - - /** - * Describes the button that opens a Web App by calling getWebAppUrl. - */ - public InlineQueryResultsButtonTypeWebApp() { - } - - /** - * Describes the button that opens a Web App by calling getWebAppUrl. - * - * @param url An HTTP URL to pass to getWebAppUrl. - */ - public InlineQueryResultsButtonTypeWebApp(String url) { - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1197382814; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains information about background to set. - */ - public abstract static class InputBackground extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InputBackgroundLocal.CONSTRUCTOR, - InputBackgroundRemote.CONSTRUCTOR, - InputBackgroundPrevious.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InputBackground() { - } - } - - /** - * A background from a local file. - */ - public static class InputBackgroundLocal extends InputBackground { - /** - * Background file to use. Only inputFileLocal and inputFileGenerated are supported. The file must be in JPEG format for wallpapers and in PNG format for patterns. - */ - public InputFile background; - - /** - * A background from a local file. - */ - public InputBackgroundLocal() { - } - - /** - * A background from a local file. - * - * @param background Background file to use. Only inputFileLocal and inputFileGenerated are supported. The file must be in JPEG format for wallpapers and in PNG format for patterns. - */ - public InputBackgroundLocal(InputFile background) { - this.background = background; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1747094364; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A background from the server. - */ - public static class InputBackgroundRemote extends InputBackground { - /** - * The background identifier. - */ - public long backgroundId; - - /** - * A background from the server. - */ - public InputBackgroundRemote() { - } - - /** - * A background from the server. - * - * @param backgroundId The background identifier. - */ - public InputBackgroundRemote(long backgroundId) { - this.backgroundId = backgroundId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -274976231; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A background previously set in the chat; for chat backgrounds only. - */ - public static class InputBackgroundPrevious extends InputBackground { - /** - * Identifier of the message with the background. - */ - public long messageId; - - /** - * A background previously set in the chat; for chat backgrounds only. - */ - public InputBackgroundPrevious() { - } - - /** - * A background previously set in the chat; for chat backgrounds only. - * - * @param messageId Identifier of the message with the background. - */ - public InputBackgroundPrevious(long messageId) { - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -351905954; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a business chat link to create or edit. - */ - public static class InputBusinessChatLink extends Object { - /** - * Message draft text that will be added to the input field. - */ - public FormattedText text; - /** - * Link title. - */ - public String title; - - /** - * Describes a business chat link to create or edit. - */ - public InputBusinessChatLink() { - } - - /** - * Describes a business chat link to create or edit. - * - * @param text Message draft text that will be added to the input field. - * @param title Link title. - */ - public InputBusinessChatLink(FormattedText text, String title) { - this.text = text; - this.title = title; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 237858296; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes settings for a business account start page to set. - */ - public static class InputBusinessStartPage extends Object { - /** - * Title text of the start page; 0-getOption("business_start_page_title_length_max") characters. - */ - public String title; - /** - * Message text of the start page; 0-getOption("business_start_page_message_length_max") characters. - */ - public String message; - /** - * Greeting sticker of the start page; pass null if none. The sticker must belong to a sticker set and must not be a custom emoji. - */ - public InputFile sticker; - - /** - * Describes settings for a business account start page to set. - */ - public InputBusinessStartPage() { - } - - /** - * Describes settings for a business account start page to set. - * - * @param title Title text of the start page; 0-getOption("business_start_page_title_length_max") characters. - * @param message Message text of the start page; 0-getOption("business_start_page_message_length_max") characters. - * @param sticker Greeting sticker of the start page; pass null if none. The sticker must belong to a sticker set and must not be a custom emoji. - */ - public InputBusinessStartPage(String title, String message, InputFile sticker) { - this.title = title; - this.message = message; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -327383072; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a call. - */ - public abstract static class InputCall extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InputCallDiscarded.CONSTRUCTOR, - InputCallFromMessage.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InputCall() { - } - } - - /** - * A just ended call. - */ - public static class InputCallDiscarded extends InputCall { - /** - * Identifier of the call. - */ - public int callId; - - /** - * A just ended call. - */ - public InputCallDiscarded() { - } - - /** - * A just ended call. - * - * @param callId Identifier of the call. - */ - public InputCallDiscarded(int callId) { - this.callId = callId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1956569937; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A call from a message of the type messageCall with non-zero messageCall.uniqueId. - */ - public static class InputCallFromMessage extends InputCall { - /** - * Chat identifier of the message. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - - /** - * A call from a message of the type messageCall with non-zero messageCall.uniqueId. - */ - public InputCallFromMessage() { - } - - /** - * A call from a message of the type messageCall with non-zero messageCall.uniqueId. - * - * @param chatId Chat identifier of the message. - * @param messageId Message identifier. - */ - public InputCallFromMessage(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 980874855; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a photo to be set as a user profile or chat photo. - */ - public abstract static class InputChatPhoto extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InputChatPhotoPrevious.CONSTRUCTOR, - InputChatPhotoStatic.CONSTRUCTOR, - InputChatPhotoAnimation.CONSTRUCTOR, - InputChatPhotoSticker.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InputChatPhoto() { - } - } - - /** - * A previously used profile photo of the current user. - */ - public static class InputChatPhotoPrevious extends InputChatPhoto { - /** - * Identifier of the current user's profile photo to reuse. - */ - public long chatPhotoId; - - /** - * A previously used profile photo of the current user. - */ - public InputChatPhotoPrevious() { - } - - /** - * A previously used profile photo of the current user. - * - * @param chatPhotoId Identifier of the current user's profile photo to reuse. - */ - public InputChatPhotoPrevious(long chatPhotoId) { - this.chatPhotoId = chatPhotoId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 23128529; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A static photo in JPEG format. - */ - public static class InputChatPhotoStatic extends InputChatPhoto { - /** - * Photo to be set as profile photo. Only inputFileLocal and inputFileGenerated are allowed. - */ - public InputFile photo; - - /** - * A static photo in JPEG format. - */ - public InputChatPhotoStatic() { - } - - /** - * A static photo in JPEG format. - * - * @param photo Photo to be set as profile photo. Only inputFileLocal and inputFileGenerated are allowed. - */ - public InputChatPhotoStatic(InputFile photo) { - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1979179699; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An animation in MPEG4 format; must be square, at most 10 seconds long, have width between 160 and 1280 and be at most 2MB in size. - */ - public static class InputChatPhotoAnimation extends InputChatPhoto { - /** - * Animation to be set as profile photo. Only inputFileLocal and inputFileGenerated are allowed. - */ - public InputFile animation; - /** - * Timestamp of the frame, which will be used as static chat photo. - */ - public double mainFrameTimestamp; - - /** - * An animation in MPEG4 format; must be square, at most 10 seconds long, have width between 160 and 1280 and be at most 2MB in size. - */ - public InputChatPhotoAnimation() { - } - - /** - * An animation in MPEG4 format; must be square, at most 10 seconds long, have width between 160 and 1280 and be at most 2MB in size. - * - * @param animation Animation to be set as profile photo. Only inputFileLocal and inputFileGenerated are allowed. - * @param mainFrameTimestamp Timestamp of the frame, which will be used as static chat photo. - */ - public InputChatPhotoAnimation(InputFile animation, double mainFrameTimestamp) { - this.animation = animation; - this.mainFrameTimestamp = mainFrameTimestamp; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 90846242; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A sticker on a custom background. - */ - public static class InputChatPhotoSticker extends InputChatPhoto { - /** - * Information about the sticker. - */ - public ChatPhotoSticker sticker; - - /** - * A sticker on a custom background. - */ - public InputChatPhotoSticker() { - } - - /** - * A sticker on a custom background. - * - * @param sticker Information about the sticker. - */ - public InputChatPhotoSticker(ChatPhotoSticker sticker) { - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1315861341; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a chat theme to set. - */ - public abstract static class InputChatTheme extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InputChatThemeEmoji.CONSTRUCTOR, - InputChatThemeGift.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InputChatTheme() { - } - } - - /** - * A theme based on an emoji. - */ - public static class InputChatThemeEmoji extends InputChatTheme { - /** - * Name of the theme. - */ - public String name; - - /** - * A theme based on an emoji. - */ - public InputChatThemeEmoji() { - } - - /** - * A theme based on an emoji. - * - * @param name Name of the theme. - */ - public InputChatThemeEmoji(String name) { - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1461787199; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A theme based on an upgraded gift. - */ - public static class InputChatThemeGift extends InputChatTheme { - /** - * Name of the upgraded gift. A gift can be used only in one chat in a time. When the same gift is used in another chat, theme in the previous chat is reset to default. - */ - public String name; - - /** - * A theme based on an upgraded gift. - */ - public InputChatThemeGift() { - } - - /** - * A theme based on an upgraded gift. - * - * @param name Name of the upgraded gift. A gift can be used only in one chat in a time. When the same gift is used in another chat, theme in the previous chat is reset to default. - */ - public InputChatThemeGift(String name) { - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2026976301; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a checklist to be sent. - */ - public static class InputChecklist extends Object { - /** - * Title of the checklist; 1-getOption("checklist_title_length_max") characters. May contain only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities. - */ - public FormattedText title; - /** - * List of tasks in the checklist; 1-getOption("checklist_task_count_max") tasks. - */ - public InputChecklistTask[] tasks; - /** - * True, if other users can add tasks to the list. - */ - public boolean othersCanAddTasks; - /** - * True, if other users can mark tasks as done or not done. - */ - public boolean othersCanMarkTasksAsDone; - - /** - * Describes a checklist to be sent. - */ - public InputChecklist() { - } - - /** - * Describes a checklist to be sent. - * - * @param title Title of the checklist; 1-getOption("checklist_title_length_max") characters. May contain only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities. - * @param tasks List of tasks in the checklist; 1-getOption("checklist_task_count_max") tasks. - * @param othersCanAddTasks True, if other users can add tasks to the list. - * @param othersCanMarkTasksAsDone True, if other users can mark tasks as done or not done. - */ - public InputChecklist(FormattedText title, InputChecklistTask[] tasks, boolean othersCanAddTasks, boolean othersCanMarkTasksAsDone) { - this.title = title; - this.tasks = tasks; - this.othersCanAddTasks = othersCanAddTasks; - this.othersCanMarkTasksAsDone = othersCanMarkTasksAsDone; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -145125739; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a task in a checklist to be sent. - */ - public static class InputChecklistTask extends Object { - /** - * Unique identifier of the task; must be positive. - */ - public int id; - /** - * Text of the task; 1-getOption("checklist_task_text_length_max") characters without line feeds. May contain only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities. - */ - public FormattedText text; - - /** - * Describes a task in a checklist to be sent. - */ - public InputChecklistTask() { - } - - /** - * Describes a task in a checklist to be sent. - * - * @param id Unique identifier of the task; must be positive. - * @param text Text of the task; 1-getOption("checklist_task_text_length_max") characters without line feeds. May contain only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities. - */ - public InputChecklistTask(int id, FormattedText text) { - this.id = id; - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1633462225; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains information about the payment method chosen by the user. - */ - public abstract static class InputCredentials extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InputCredentialsSaved.CONSTRUCTOR, - InputCredentialsNew.CONSTRUCTOR, - InputCredentialsApplePay.CONSTRUCTOR, - InputCredentialsGooglePay.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InputCredentials() { - } - } - - /** - * Applies if a user chooses some previously saved payment credentials. To use their previously saved credentials, the user must have a valid temporary password. - */ - public static class InputCredentialsSaved extends InputCredentials { - /** - * Identifier of the saved credentials. - */ - public String savedCredentialsId; - - /** - * Applies if a user chooses some previously saved payment credentials. To use their previously saved credentials, the user must have a valid temporary password. - */ - public InputCredentialsSaved() { - } - - /** - * Applies if a user chooses some previously saved payment credentials. To use their previously saved credentials, the user must have a valid temporary password. - * - * @param savedCredentialsId Identifier of the saved credentials. - */ - public InputCredentialsSaved(String savedCredentialsId) { - this.savedCredentialsId = savedCredentialsId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2034385364; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Applies if a user enters new credentials on a payment provider website. - */ - public static class InputCredentialsNew extends InputCredentials { - /** - * JSON-encoded data with the credential identifier from the payment provider. - */ - public String data; - /** - * True, if the credential identifier can be saved on the server side. - */ - public boolean allowSave; - - /** - * Applies if a user enters new credentials on a payment provider website. - */ - public InputCredentialsNew() { - } - - /** - * Applies if a user enters new credentials on a payment provider website. - * - * @param data JSON-encoded data with the credential identifier from the payment provider. - * @param allowSave True, if the credential identifier can be saved on the server side. - */ - public InputCredentialsNew(String data, boolean allowSave) { - this.data = data; - this.allowSave = allowSave; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -829689558; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Applies if a user enters new credentials using Apple Pay. - */ - public static class InputCredentialsApplePay extends InputCredentials { - /** - * JSON-encoded data with the credential identifier. - */ - public String data; - - /** - * Applies if a user enters new credentials using Apple Pay. - */ - public InputCredentialsApplePay() { - } - - /** - * Applies if a user enters new credentials using Apple Pay. - * - * @param data JSON-encoded data with the credential identifier. - */ - public InputCredentialsApplePay(String data) { - this.data = data; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1246570799; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Applies if a user enters new credentials using Google Pay. - */ - public static class InputCredentialsGooglePay extends InputCredentials { - /** - * JSON-encoded data with the credential identifier. - */ - public String data; - - /** - * Applies if a user enters new credentials using Google Pay. - */ - public InputCredentialsGooglePay() { - } - - /** - * Applies if a user enters new credentials using Google Pay. - * - * @param data JSON-encoded data with the credential identifier. - */ - public InputCredentialsGooglePay(String data) { - this.data = data; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 844384100; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Points to a file. - */ - public abstract static class InputFile extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InputFileId.CONSTRUCTOR, - InputFileRemote.CONSTRUCTOR, - InputFileLocal.CONSTRUCTOR, - InputFileGenerated.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InputFile() { - } - } - - /** - * A file defined by its unique identifier. - */ - public static class InputFileId extends InputFile { - /** - * Unique file identifier. - */ - public int id; - - /** - * A file defined by its unique identifier. - */ - public InputFileId() { - } - - /** - * A file defined by its unique identifier. - * - * @param id Unique file identifier. - */ - public InputFileId(int id) { - this.id = id; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1788906253; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A file defined by its remote identifier. The remote identifier is guaranteed to be usable only if the corresponding file is still accessible to the user and known to TDLib. For example, if the file is from a message, then the message must be not deleted and accessible to the user. If the file database is disabled, then the corresponding object with the file must be preloaded by the application. - */ - public static class InputFileRemote extends InputFile { - /** - * Remote file identifier. - */ - public String id; - - /** - * A file defined by its remote identifier. The remote identifier is guaranteed to be usable only if the corresponding file is still accessible to the user and known to TDLib. For example, if the file is from a message, then the message must be not deleted and accessible to the user. If the file database is disabled, then the corresponding object with the file must be preloaded by the application. - */ - public InputFileRemote() { - } - - /** - * A file defined by its remote identifier. The remote identifier is guaranteed to be usable only if the corresponding file is still accessible to the user and known to TDLib. For example, if the file is from a message, then the message must be not deleted and accessible to the user. If the file database is disabled, then the corresponding object with the file must be preloaded by the application. - * - * @param id Remote file identifier. - */ - public InputFileRemote(String id) { - this.id = id; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -107574466; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A file defined by a local path. - */ - public static class InputFileLocal extends InputFile { - /** - * Local path to the file. - */ - public String path; - - /** - * A file defined by a local path. - */ - public InputFileLocal() { - } - - /** - * A file defined by a local path. - * - * @param path Local path to the file. - */ - public InputFileLocal(String path) { - this.path = path; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2056030919; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A file generated by the application. The application must handle updates updateFileGenerationStart and updateFileGenerationStop to generate the file when asked by TDLib. - */ - public static class InputFileGenerated extends InputFile { - /** - * Local path to a file from which the file is generated. The path doesn't have to be a valid path and is used by TDLib only to detect name and MIME type of the generated file. - */ - public String originalPath; - /** - * String specifying the conversion applied to the original file; must be persistent across application restarts. Conversions beginning with '#' are reserved for internal TDLib usage. - */ - public String conversion; - /** - * Expected size of the generated file, in bytes; pass 0 if unknown. - */ - public long expectedSize; - - /** - * A file generated by the application. The application must handle updates updateFileGenerationStart and updateFileGenerationStop to generate the file when asked by TDLib. - */ - public InputFileGenerated() { - } - - /** - * A file generated by the application. The application must handle updates updateFileGenerationStart and updateFileGenerationStop to generate the file when asked by TDLib. - * - * @param originalPath Local path to a file from which the file is generated. The path doesn't have to be a valid path and is used by TDLib only to detect name and MIME type of the generated file. - * @param conversion String specifying the conversion applied to the original file; must be persistent across application restarts. Conversions beginning with '#' are reserved for internal TDLib usage. - * @param expectedSize Expected size of the generated file, in bytes; pass 0 if unknown. - */ - public InputFileGenerated(String originalPath, String conversion, long expectedSize) { - this.originalPath = originalPath; - this.conversion = conversion; - this.expectedSize = expectedSize; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1333385216; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a non-joined group call that isn't bound to a chat. - */ - public abstract static class InputGroupCall extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InputGroupCallLink.CONSTRUCTOR, - InputGroupCallMessage.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InputGroupCall() { - } - } - - /** - * The group call is accessible through a link. - */ - public static class InputGroupCallLink extends InputGroupCall { - /** - * The link for the group call. - */ - public String link; - - /** - * The group call is accessible through a link. - */ - public InputGroupCallLink() { - } - - /** - * The group call is accessible through a link. - * - * @param link The link for the group call. - */ - public InputGroupCallLink(String link) { - this.link = link; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -812157480; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The group call is accessible through a message of the type messageGroupCall. - */ - public static class InputGroupCallMessage extends InputGroupCall { - /** - * Identifier of the chat with the message. - */ - public long chatId; - /** - * Identifier of the message of the type messageGroupCall. - */ - public long messageId; - - /** - * The group call is accessible through a message of the type messageGroupCall. - */ - public InputGroupCallMessage() { - } - - /** - * The group call is accessible through a message of the type messageGroupCall. - * - * @param chatId Identifier of the chat with the message. - * @param messageId Identifier of the message of the type messageGroupCall. - */ - public InputGroupCallMessage(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -341793768; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An identity document to be saved to Telegram Passport. - */ - public static class InputIdentityDocument extends Object { - /** - * Document number; 1-24 characters. - */ - public String number; - /** - * Document expiration date; pass null if not applicable. - */ - public Date expirationDate; - /** - * Front side of the document. - */ - public InputFile frontSide; - /** - * Reverse side of the document; only for driver license and identity card; pass null otherwise. - */ - public InputFile reverseSide; - /** - * Selfie with the document; pass null if unavailable. - */ - public InputFile selfie; - /** - * List of files containing a certified English translation of the document. - */ - public InputFile[] translation; - - /** - * An identity document to be saved to Telegram Passport. - */ - public InputIdentityDocument() { - } - - /** - * An identity document to be saved to Telegram Passport. - * - * @param number Document number; 1-24 characters. - * @param expirationDate Document expiration date; pass null if not applicable. - * @param frontSide Front side of the document. - * @param reverseSide Reverse side of the document; only for driver license and identity card; pass null otherwise. - * @param selfie Selfie with the document; pass null if unavailable. - * @param translation List of files containing a certified English translation of the document. - */ - public InputIdentityDocument(String number, Date expirationDate, InputFile frontSide, InputFile reverseSide, InputFile selfie, InputFile[] translation) { - this.number = number; - this.expirationDate = expirationDate; - this.frontSide = frontSide; - this.reverseSide = reverseSide; - this.selfie = selfie; - this.translation = translation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 767353688; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents a single result of an inline query; for bots only. - */ - public abstract static class InputInlineQueryResult extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InputInlineQueryResultAnimation.CONSTRUCTOR, - InputInlineQueryResultArticle.CONSTRUCTOR, - InputInlineQueryResultAudio.CONSTRUCTOR, - InputInlineQueryResultContact.CONSTRUCTOR, - InputInlineQueryResultDocument.CONSTRUCTOR, - InputInlineQueryResultGame.CONSTRUCTOR, - InputInlineQueryResultLocation.CONSTRUCTOR, - InputInlineQueryResultPhoto.CONSTRUCTOR, - InputInlineQueryResultSticker.CONSTRUCTOR, - InputInlineQueryResultVenue.CONSTRUCTOR, - InputInlineQueryResultVideo.CONSTRUCTOR, - InputInlineQueryResultVoiceNote.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InputInlineQueryResult() { - } - } - - /** - * Represents a link to an animated GIF or an animated (i.e., without sound) H.264/MPEG-4 AVC video. - */ - public static class InputInlineQueryResultAnimation extends InputInlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Title of the query result. - */ - public String title; - /** - * URL of the result thumbnail (JPEG, GIF, or MPEG4), if it exists. - */ - public String thumbnailUrl; - /** - * MIME type of the video thumbnail. If non-empty, must be one of "image/jpeg", "image/gif" and "video/mp4". - */ - public String thumbnailMimeType; - /** - * The URL of the video file (file size must not exceed 1MB). - */ - public String videoUrl; - /** - * MIME type of the video file. Must be one of "image/gif" and "video/mp4". - */ - public String videoMimeType; - /** - * Duration of the video, in seconds. - */ - public int videoDuration; - /** - * Width of the video. - */ - public int videoWidth; - /** - * Height of the video. - */ - public int videoHeight; - /** - * The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - */ - public ReplyMarkup replyMarkup; - /** - * The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageAnimation, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputMessageContent inputMessageContent; - - /** - * Represents a link to an animated GIF or an animated (i.e., without sound) H.264/MPEG-4 AVC video. - */ - public InputInlineQueryResultAnimation() { - } - - /** - * Represents a link to an animated GIF or an animated (i.e., without sound) H.264/MPEG-4 AVC video. - * - * @param id Unique identifier of the query result. - * @param title Title of the query result. - * @param thumbnailUrl URL of the result thumbnail (JPEG, GIF, or MPEG4), if it exists. - * @param thumbnailMimeType MIME type of the video thumbnail. If non-empty, must be one of "image/jpeg", "image/gif" and "video/mp4". - * @param videoUrl The URL of the video file (file size must not exceed 1MB). - * @param videoMimeType MIME type of the video file. Must be one of "image/gif" and "video/mp4". - * @param videoDuration Duration of the video, in seconds. - * @param videoWidth Width of the video. - * @param videoHeight Height of the video. - * @param replyMarkup The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - * @param inputMessageContent The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageAnimation, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputInlineQueryResultAnimation(String id, String title, String thumbnailUrl, String thumbnailMimeType, String videoUrl, String videoMimeType, int videoDuration, int videoWidth, int videoHeight, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.id = id; - this.title = title; - this.thumbnailUrl = thumbnailUrl; - this.thumbnailMimeType = thumbnailMimeType; - this.videoUrl = videoUrl; - this.videoMimeType = videoMimeType; - this.videoDuration = videoDuration; - this.videoWidth = videoWidth; - this.videoHeight = videoHeight; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1489808874; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a link to an article or web page. - */ - public static class InputInlineQueryResultArticle extends InputInlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * URL of the result, if it exists. - */ - public String url; - /** - * Title of the result. - */ - public String title; - /** - * A short description of the result. - */ - public String description; - /** - * URL of the result thumbnail, if it exists. - */ - public String thumbnailUrl; - /** - * Thumbnail width, if known. - */ - public int thumbnailWidth; - /** - * Thumbnail height, if known. - */ - public int thumbnailHeight; - /** - * The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - */ - public ReplyMarkup replyMarkup; - /** - * The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputMessageContent inputMessageContent; - - /** - * Represents a link to an article or web page. - */ - public InputInlineQueryResultArticle() { - } - - /** - * Represents a link to an article or web page. - * - * @param id Unique identifier of the query result. - * @param url URL of the result, if it exists. - * @param title Title of the result. - * @param description A short description of the result. - * @param thumbnailUrl URL of the result thumbnail, if it exists. - * @param thumbnailWidth Thumbnail width, if known. - * @param thumbnailHeight Thumbnail height, if known. - * @param replyMarkup The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - * @param inputMessageContent The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputInlineQueryResultArticle(String id, String url, String title, String description, String thumbnailUrl, int thumbnailWidth, int thumbnailHeight, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.id = id; - this.url = url; - this.title = title; - this.description = description; - this.thumbnailUrl = thumbnailUrl; - this.thumbnailWidth = thumbnailWidth; - this.thumbnailHeight = thumbnailHeight; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1983218620; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a link to an MP3 audio file. - */ - public static class InputInlineQueryResultAudio extends InputInlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Title of the audio file. - */ - public String title; - /** - * Performer of the audio file. - */ - public String performer; - /** - * The URL of the audio file. - */ - public String audioUrl; - /** - * Audio file duration, in seconds. - */ - public int audioDuration; - /** - * The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - */ - public ReplyMarkup replyMarkup; - /** - * The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageAudio, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputMessageContent inputMessageContent; - - /** - * Represents a link to an MP3 audio file. - */ - public InputInlineQueryResultAudio() { - } - - /** - * Represents a link to an MP3 audio file. - * - * @param id Unique identifier of the query result. - * @param title Title of the audio file. - * @param performer Performer of the audio file. - * @param audioUrl The URL of the audio file. - * @param audioDuration Audio file duration, in seconds. - * @param replyMarkup The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - * @param inputMessageContent The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageAudio, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputInlineQueryResultAudio(String id, String title, String performer, String audioUrl, int audioDuration, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.id = id; - this.title = title; - this.performer = performer; - this.audioUrl = audioUrl; - this.audioDuration = audioDuration; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1260139988; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a user contact. - */ - public static class InputInlineQueryResultContact extends InputInlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * User contact. - */ - public Contact contact; - /** - * URL of the result thumbnail, if it exists. - */ - public String thumbnailUrl; - /** - * Thumbnail width, if known. - */ - public int thumbnailWidth; - /** - * Thumbnail height, if known. - */ - public int thumbnailHeight; - /** - * The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - */ - public ReplyMarkup replyMarkup; - /** - * The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputMessageContent inputMessageContent; - - /** - * Represents a user contact. - */ - public InputInlineQueryResultContact() { - } - - /** - * Represents a user contact. - * - * @param id Unique identifier of the query result. - * @param contact User contact. - * @param thumbnailUrl URL of the result thumbnail, if it exists. - * @param thumbnailWidth Thumbnail width, if known. - * @param thumbnailHeight Thumbnail height, if known. - * @param replyMarkup The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - * @param inputMessageContent The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputInlineQueryResultContact(String id, Contact contact, String thumbnailUrl, int thumbnailWidth, int thumbnailHeight, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.id = id; - this.contact = contact; - this.thumbnailUrl = thumbnailUrl; - this.thumbnailWidth = thumbnailWidth; - this.thumbnailHeight = thumbnailHeight; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1846064594; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a link to a file. - */ - public static class InputInlineQueryResultDocument extends InputInlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Title of the resulting file. - */ - public String title; - /** - * Short description of the result, if known. - */ - public String description; - /** - * URL of the file. - */ - public String documentUrl; - /** - * MIME type of the file content; only "application/pdf" and "application/zip" are currently allowed. - */ - public String mimeType; - /** - * The URL of the file thumbnail, if it exists. - */ - public String thumbnailUrl; - /** - * Width of the thumbnail. - */ - public int thumbnailWidth; - /** - * Height of the thumbnail. - */ - public int thumbnailHeight; - /** - * The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - */ - public ReplyMarkup replyMarkup; - /** - * The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageDocument, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputMessageContent inputMessageContent; - - /** - * Represents a link to a file. - */ - public InputInlineQueryResultDocument() { - } - - /** - * Represents a link to a file. - * - * @param id Unique identifier of the query result. - * @param title Title of the resulting file. - * @param description Short description of the result, if known. - * @param documentUrl URL of the file. - * @param mimeType MIME type of the file content; only "application/pdf" and "application/zip" are currently allowed. - * @param thumbnailUrl The URL of the file thumbnail, if it exists. - * @param thumbnailWidth Width of the thumbnail. - * @param thumbnailHeight Height of the thumbnail. - * @param replyMarkup The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - * @param inputMessageContent The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageDocument, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputInlineQueryResultDocument(String id, String title, String description, String documentUrl, String mimeType, String thumbnailUrl, int thumbnailWidth, int thumbnailHeight, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.id = id; - this.title = title; - this.description = description; - this.documentUrl = documentUrl; - this.mimeType = mimeType; - this.thumbnailUrl = thumbnailUrl; - this.thumbnailWidth = thumbnailWidth; - this.thumbnailHeight = thumbnailHeight; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 578801869; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a game. - */ - public static class InputInlineQueryResultGame extends InputInlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Short name of the game. - */ - public String gameShortName; - /** - * The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - */ - public ReplyMarkup replyMarkup; - - /** - * Represents a game. - */ - public InputInlineQueryResultGame() { - } - - /** - * Represents a game. - * - * @param id Unique identifier of the query result. - * @param gameShortName Short name of the game. - * @param replyMarkup The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - */ - public InputInlineQueryResultGame(String id, String gameShortName, ReplyMarkup replyMarkup) { - this.id = id; - this.gameShortName = gameShortName; - this.replyMarkup = replyMarkup; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 966074327; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a point on the map. - */ - public static class InputInlineQueryResultLocation extends InputInlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Location result. - */ - public Location location; - /** - * Amount of time relative to the message sent time until the location can be updated, in seconds. - */ - public int livePeriod; - /** - * Title of the result. - */ - public String title; - /** - * URL of the result thumbnail, if it exists. - */ - public String thumbnailUrl; - /** - * Thumbnail width, if known. - */ - public int thumbnailWidth; - /** - * Thumbnail height, if known. - */ - public int thumbnailHeight; - /** - * The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - */ - public ReplyMarkup replyMarkup; - /** - * The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputMessageContent inputMessageContent; - - /** - * Represents a point on the map. - */ - public InputInlineQueryResultLocation() { - } - - /** - * Represents a point on the map. - * - * @param id Unique identifier of the query result. - * @param location Location result. - * @param livePeriod Amount of time relative to the message sent time until the location can be updated, in seconds. - * @param title Title of the result. - * @param thumbnailUrl URL of the result thumbnail, if it exists. - * @param thumbnailWidth Thumbnail width, if known. - * @param thumbnailHeight Thumbnail height, if known. - * @param replyMarkup The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - * @param inputMessageContent The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputInlineQueryResultLocation(String id, Location location, int livePeriod, String title, String thumbnailUrl, int thumbnailWidth, int thumbnailHeight, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.id = id; - this.location = location; - this.livePeriod = livePeriod; - this.title = title; - this.thumbnailUrl = thumbnailUrl; - this.thumbnailWidth = thumbnailWidth; - this.thumbnailHeight = thumbnailHeight; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1887650218; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents link to a JPEG image. - */ - public static class InputInlineQueryResultPhoto extends InputInlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Title of the result, if known. - */ - public String title; - /** - * A short description of the result, if known. - */ - public String description; - /** - * URL of the photo thumbnail, if it exists. - */ - public String thumbnailUrl; - /** - * The URL of the JPEG photo (photo size must not exceed 5MB). - */ - public String photoUrl; - /** - * Width of the photo. - */ - public int photoWidth; - /** - * Height of the photo. - */ - public int photoHeight; - /** - * The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - */ - public ReplyMarkup replyMarkup; - /** - * The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessagePhoto, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputMessageContent inputMessageContent; - - /** - * Represents link to a JPEG image. - */ - public InputInlineQueryResultPhoto() { - } - - /** - * Represents link to a JPEG image. - * - * @param id Unique identifier of the query result. - * @param title Title of the result, if known. - * @param description A short description of the result, if known. - * @param thumbnailUrl URL of the photo thumbnail, if it exists. - * @param photoUrl The URL of the JPEG photo (photo size must not exceed 5MB). - * @param photoWidth Width of the photo. - * @param photoHeight Height of the photo. - * @param replyMarkup The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - * @param inputMessageContent The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessagePhoto, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputInlineQueryResultPhoto(String id, String title, String description, String thumbnailUrl, String photoUrl, int photoWidth, int photoHeight, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.id = id; - this.title = title; - this.description = description; - this.thumbnailUrl = thumbnailUrl; - this.photoUrl = photoUrl; - this.photoWidth = photoWidth; - this.photoHeight = photoHeight; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1123338721; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a link to a WEBP, TGS, or WEBM sticker. - */ - public static class InputInlineQueryResultSticker extends InputInlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * URL of the sticker thumbnail, if it exists. - */ - public String thumbnailUrl; - /** - * The URL of the WEBP, TGS, or WEBM sticker (sticker file size must not exceed 5MB). - */ - public String stickerUrl; - /** - * Width of the sticker. - */ - public int stickerWidth; - /** - * Height of the sticker. - */ - public int stickerHeight; - /** - * The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - */ - public ReplyMarkup replyMarkup; - /** - * The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageSticker, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputMessageContent inputMessageContent; - - /** - * Represents a link to a WEBP, TGS, or WEBM sticker. - */ - public InputInlineQueryResultSticker() { - } - - /** - * Represents a link to a WEBP, TGS, or WEBM sticker. - * - * @param id Unique identifier of the query result. - * @param thumbnailUrl URL of the sticker thumbnail, if it exists. - * @param stickerUrl The URL of the WEBP, TGS, or WEBM sticker (sticker file size must not exceed 5MB). - * @param stickerWidth Width of the sticker. - * @param stickerHeight Height of the sticker. - * @param replyMarkup The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - * @param inputMessageContent The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageSticker, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputInlineQueryResultSticker(String id, String thumbnailUrl, String stickerUrl, int stickerWidth, int stickerHeight, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.id = id; - this.thumbnailUrl = thumbnailUrl; - this.stickerUrl = stickerUrl; - this.stickerWidth = stickerWidth; - this.stickerHeight = stickerHeight; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 274007129; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents information about a venue. - */ - public static class InputInlineQueryResultVenue extends InputInlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Venue result. - */ - public Venue venue; - /** - * URL of the result thumbnail, if it exists. - */ - public String thumbnailUrl; - /** - * Thumbnail width, if known. - */ - public int thumbnailWidth; - /** - * Thumbnail height, if known. - */ - public int thumbnailHeight; - /** - * The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - */ - public ReplyMarkup replyMarkup; - /** - * The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputMessageContent inputMessageContent; - - /** - * Represents information about a venue. - */ - public InputInlineQueryResultVenue() { - } - - /** - * Represents information about a venue. - * - * @param id Unique identifier of the query result. - * @param venue Venue result. - * @param thumbnailUrl URL of the result thumbnail, if it exists. - * @param thumbnailWidth Thumbnail width, if known. - * @param thumbnailHeight Thumbnail height, if known. - * @param replyMarkup The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - * @param inputMessageContent The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputInlineQueryResultVenue(String id, Venue venue, String thumbnailUrl, int thumbnailWidth, int thumbnailHeight, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.id = id; - this.venue = venue; - this.thumbnailUrl = thumbnailUrl; - this.thumbnailWidth = thumbnailWidth; - this.thumbnailHeight = thumbnailHeight; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 541704509; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a link to a page containing an embedded video player or a video file. - */ - public static class InputInlineQueryResultVideo extends InputInlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Title of the result. - */ - public String title; - /** - * A short description of the result, if known. - */ - public String description; - /** - * The URL of the video thumbnail (JPEG), if it exists. - */ - public String thumbnailUrl; - /** - * URL of the embedded video player or video file. - */ - public String videoUrl; - /** - * MIME type of the content of the video URL, only "text/html" or "video/mp4" are currently supported. - */ - public String mimeType; - /** - * Width of the video. - */ - public int videoWidth; - /** - * Height of the video. - */ - public int videoHeight; - /** - * Video duration, in seconds. - */ - public int videoDuration; - /** - * The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - */ - public ReplyMarkup replyMarkup; - /** - * The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageVideo, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputMessageContent inputMessageContent; - - /** - * Represents a link to a page containing an embedded video player or a video file. - */ - public InputInlineQueryResultVideo() { - } - - /** - * Represents a link to a page containing an embedded video player or a video file. - * - * @param id Unique identifier of the query result. - * @param title Title of the result. - * @param description A short description of the result, if known. - * @param thumbnailUrl The URL of the video thumbnail (JPEG), if it exists. - * @param videoUrl URL of the embedded video player or video file. - * @param mimeType MIME type of the content of the video URL, only "text/html" or "video/mp4" are currently supported. - * @param videoWidth Width of the video. - * @param videoHeight Height of the video. - * @param videoDuration Video duration, in seconds. - * @param replyMarkup The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - * @param inputMessageContent The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageVideo, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputInlineQueryResultVideo(String id, String title, String description, String thumbnailUrl, String videoUrl, String mimeType, int videoWidth, int videoHeight, int videoDuration, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.id = id; - this.title = title; - this.description = description; - this.thumbnailUrl = thumbnailUrl; - this.videoUrl = videoUrl; - this.mimeType = mimeType; - this.videoWidth = videoWidth; - this.videoHeight = videoHeight; - this.videoDuration = videoDuration; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1724073191; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a link to an opus-encoded audio file within an OGG container, single channel audio. - */ - public static class InputInlineQueryResultVoiceNote extends InputInlineQueryResult { - /** - * Unique identifier of the query result. - */ - public String id; - /** - * Title of the voice note. - */ - public String title; - /** - * The URL of the voice note file. - */ - public String voiceNoteUrl; - /** - * Duration of the voice note, in seconds. - */ - public int voiceNoteDuration; - /** - * The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - */ - public ReplyMarkup replyMarkup; - /** - * The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageVoiceNote, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputMessageContent inputMessageContent; - - /** - * Represents a link to an opus-encoded audio file within an OGG container, single channel audio. - */ - public InputInlineQueryResultVoiceNote() { - } - - /** - * Represents a link to an opus-encoded audio file within an OGG container, single channel audio. - * - * @param id Unique identifier of the query result. - * @param title Title of the voice note. - * @param voiceNoteUrl The URL of the voice note file. - * @param voiceNoteDuration Duration of the voice note, in seconds. - * @param replyMarkup The message reply markup; pass null if none. Must be of type replyMarkupInlineKeyboard or null. - * @param inputMessageContent The content of the message to be sent. Must be one of the following types: inputMessageText, inputMessageVoiceNote, inputMessageInvoice, inputMessageLocation, inputMessageVenue or inputMessageContact. - */ - public InputInlineQueryResultVoiceNote(String id, String title, String voiceNoteUrl, int voiceNoteDuration, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.id = id; - this.title = title; - this.voiceNoteUrl = voiceNoteUrl; - this.voiceNoteDuration = voiceNoteDuration; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1790072503; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes an invoice to process. - */ - public abstract static class InputInvoice extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InputInvoiceMessage.CONSTRUCTOR, - InputInvoiceName.CONSTRUCTOR, - InputInvoiceTelegram.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InputInvoice() { - } - } - - /** - * An invoice from a message of the type messageInvoice or paid media purchase from messagePaidMedia. - */ - public static class InputInvoiceMessage extends InputInvoice { - /** - * Chat identifier of the message. - */ - public long chatId; - /** - * Message identifier. Use messageProperties.canBePaid to check whether the message can be used in the method. - */ - public long messageId; - - /** - * An invoice from a message of the type messageInvoice or paid media purchase from messagePaidMedia. - */ - public InputInvoiceMessage() { - } - - /** - * An invoice from a message of the type messageInvoice or paid media purchase from messagePaidMedia. - * - * @param chatId Chat identifier of the message. - * @param messageId Message identifier. Use messageProperties.canBePaid to check whether the message can be used in the method. - */ - public InputInvoiceMessage(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1490872848; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An invoice from a link of the type internalLinkTypeInvoice. - */ - public static class InputInvoiceName extends InputInvoice { - /** - * Name of the invoice. - */ - public String name; - - /** - * An invoice from a link of the type internalLinkTypeInvoice. - */ - public InputInvoiceName() { - } - - /** - * An invoice from a link of the type internalLinkTypeInvoice. - * - * @param name Name of the invoice. - */ - public InputInvoiceName(String name) { - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1312155917; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An invoice for a payment toward Telegram; must not be used in the in-store apps. - */ - public static class InputInvoiceTelegram extends InputInvoice { - /** - * Transaction purpose. - */ - public TelegramPaymentPurpose purpose; - - /** - * An invoice for a payment toward Telegram; must not be used in the in-store apps. - */ - public InputInvoiceTelegram() { - } - - /** - * An invoice for a payment toward Telegram; must not be used in the in-store apps. - * - * @param purpose Transaction purpose. - */ - public InputInvoiceTelegram(TelegramPaymentPurpose purpose) { - this.purpose = purpose; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1762853139; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * The content of a message to send. - */ - public abstract static class InputMessageContent extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InputMessageText.CONSTRUCTOR, - InputMessageAnimation.CONSTRUCTOR, - InputMessageAudio.CONSTRUCTOR, - InputMessageDocument.CONSTRUCTOR, - InputMessagePaidMedia.CONSTRUCTOR, - InputMessagePhoto.CONSTRUCTOR, - InputMessageSticker.CONSTRUCTOR, - InputMessageVideo.CONSTRUCTOR, - InputMessageVideoNote.CONSTRUCTOR, - InputMessageVoiceNote.CONSTRUCTOR, - InputMessageLocation.CONSTRUCTOR, - InputMessageVenue.CONSTRUCTOR, - InputMessageContact.CONSTRUCTOR, - InputMessageDice.CONSTRUCTOR, - InputMessageGame.CONSTRUCTOR, - InputMessageInvoice.CONSTRUCTOR, - InputMessagePoll.CONSTRUCTOR, - InputMessageStakeDice.CONSTRUCTOR, - InputMessageStory.CONSTRUCTOR, - InputMessageChecklist.CONSTRUCTOR, - InputMessageForwarded.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InputMessageContent() { - } - } - - /** - * A text message. - */ - public static class InputMessageText extends InputMessageContent { - /** - * Formatted text to be sent; 0-getOption("message_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, CustomEmoji, BlockQuote, ExpandableBlockQuote, Code, Pre, PreCode, TextUrl and MentionName entities are allowed to be specified manually. - */ - public FormattedText text; - /** - * Options to be used for generation of a link preview; may be null if none; pass null to use default link preview options. - */ - @Nullable public LinkPreviewOptions linkPreviewOptions; - /** - * True, if the chat message draft must be deleted. - */ - public boolean clearDraft; - - /** - * A text message. - */ - public InputMessageText() { - } - - /** - * A text message. - * - * @param text Formatted text to be sent; 0-getOption("message_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, CustomEmoji, BlockQuote, ExpandableBlockQuote, Code, Pre, PreCode, TextUrl and MentionName entities are allowed to be specified manually. - * @param linkPreviewOptions Options to be used for generation of a link preview; may be null if none; pass null to use default link preview options. - * @param clearDraft True, if the chat message draft must be deleted. - */ - public InputMessageText(FormattedText text, LinkPreviewOptions linkPreviewOptions, boolean clearDraft) { - this.text = text; - this.linkPreviewOptions = linkPreviewOptions; - this.clearDraft = clearDraft; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -212805484; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An animation message (GIF-style). - */ - public static class InputMessageAnimation extends InputMessageContent { - /** - * Animation file to be sent. - */ - public InputFile animation; - /** - * Animation thumbnail; pass null to skip thumbnail uploading. - */ - public InputThumbnail thumbnail; - /** - * File identifiers of the stickers added to the animation, if applicable. - */ - public int[] addedStickerFileIds; - /** - * Duration of the animation, in seconds. - */ - public int duration; - /** - * Width of the animation; may be replaced by the server. - */ - public int width; - /** - * Height of the animation; may be replaced by the server. - */ - public int height; - /** - * Animation caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters. - */ - public FormattedText caption; - /** - * True, if the caption must be shown above the animation; otherwise, the caption must be shown below the animation; not supported in secret chats. - */ - public boolean showCaptionAboveMedia; - /** - * True, if the animation preview must be covered by a spoiler animation; not supported in secret chats. - */ - public boolean hasSpoiler; - - /** - * An animation message (GIF-style). - */ - public InputMessageAnimation() { - } - - /** - * An animation message (GIF-style). - * - * @param animation Animation file to be sent. - * @param thumbnail Animation thumbnail; pass null to skip thumbnail uploading. - * @param addedStickerFileIds File identifiers of the stickers added to the animation, if applicable. - * @param duration Duration of the animation, in seconds. - * @param width Width of the animation; may be replaced by the server. - * @param height Height of the animation; may be replaced by the server. - * @param caption Animation caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters. - * @param showCaptionAboveMedia True, if the caption must be shown above the animation; otherwise, the caption must be shown below the animation; not supported in secret chats. - * @param hasSpoiler True, if the animation preview must be covered by a spoiler animation; not supported in secret chats. - */ - public InputMessageAnimation(InputFile animation, InputThumbnail thumbnail, int[] addedStickerFileIds, int duration, int width, int height, FormattedText caption, boolean showCaptionAboveMedia, boolean hasSpoiler) { - this.animation = animation; - this.thumbnail = thumbnail; - this.addedStickerFileIds = addedStickerFileIds; - this.duration = duration; - this.width = width; - this.height = height; - this.caption = caption; - this.showCaptionAboveMedia = showCaptionAboveMedia; - this.hasSpoiler = hasSpoiler; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -210404059; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An audio message. - */ - public static class InputMessageAudio extends InputMessageContent { - /** - * Audio file to be sent. - */ - public InputFile audio; - /** - * Thumbnail of the cover for the album; pass null to skip thumbnail uploading. - */ - public InputThumbnail albumCoverThumbnail; - /** - * Duration of the audio, in seconds; may be replaced by the server. - */ - public int duration; - /** - * Title of the audio; 0-64 characters; may be replaced by the server. - */ - public String title; - /** - * Performer of the audio; 0-64 characters, may be replaced by the server. - */ - public String performer; - /** - * Audio caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters. - */ - public FormattedText caption; - - /** - * An audio message. - */ - public InputMessageAudio() { - } - - /** - * An audio message. - * - * @param audio Audio file to be sent. - * @param albumCoverThumbnail Thumbnail of the cover for the album; pass null to skip thumbnail uploading. - * @param duration Duration of the audio, in seconds; may be replaced by the server. - * @param title Title of the audio; 0-64 characters; may be replaced by the server. - * @param performer Performer of the audio; 0-64 characters, may be replaced by the server. - * @param caption Audio caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters. - */ - public InputMessageAudio(InputFile audio, InputThumbnail albumCoverThumbnail, int duration, String title, String performer, FormattedText caption) { - this.audio = audio; - this.albumCoverThumbnail = albumCoverThumbnail; - this.duration = duration; - this.title = title; - this.performer = performer; - this.caption = caption; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -626786126; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A document message (general file). - */ - public static class InputMessageDocument extends InputMessageContent { - /** - * Document to be sent. - */ - public InputFile document; - /** - * Document thumbnail; pass null to skip thumbnail uploading. - */ - public InputThumbnail thumbnail; - /** - * Pass true to disable automatic file type detection and send the document as a file. Always true for files sent to secret chats. - */ - public boolean disableContentTypeDetection; - /** - * Document caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters. - */ - public FormattedText caption; - - /** - * A document message (general file). - */ - public InputMessageDocument() { - } - - /** - * A document message (general file). - * - * @param document Document to be sent. - * @param thumbnail Document thumbnail; pass null to skip thumbnail uploading. - * @param disableContentTypeDetection Pass true to disable automatic file type detection and send the document as a file. Always true for files sent to secret chats. - * @param caption Document caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters. - */ - public InputMessageDocument(InputFile document, InputThumbnail thumbnail, boolean disableContentTypeDetection, FormattedText caption) { - this.document = document; - this.thumbnail = thumbnail; - this.disableContentTypeDetection = disableContentTypeDetection; - this.caption = caption; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1633383097; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with paid media; can be used only in channel chats with supergroupFullInfo.hasPaidMediaAllowed. - */ - public static class InputMessagePaidMedia extends InputMessageContent { - /** - * The number of Telegram Stars that must be paid to see the media; 1-getOption("paid_media_message_star_count_max"). - */ - public long starCount; - /** - * The content of the paid media. - */ - public InputPaidMedia[] paidMedia; - /** - * Message caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters. - */ - public FormattedText caption; - /** - * True, if the caption must be shown above the media; otherwise, the caption must be shown below the media; not supported in secret chats. - */ - public boolean showCaptionAboveMedia; - /** - * Bot-provided data for the paid media; bots only. - */ - public String payload; - - /** - * A message with paid media; can be used only in channel chats with supergroupFullInfo.hasPaidMediaAllowed. - */ - public InputMessagePaidMedia() { - } - - /** - * A message with paid media; can be used only in channel chats with supergroupFullInfo.hasPaidMediaAllowed. - * - * @param starCount The number of Telegram Stars that must be paid to see the media; 1-getOption("paid_media_message_star_count_max"). - * @param paidMedia The content of the paid media. - * @param caption Message caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters. - * @param showCaptionAboveMedia True, if the caption must be shown above the media; otherwise, the caption must be shown below the media; not supported in secret chats. - * @param payload Bot-provided data for the paid media; bots only. - */ - public InputMessagePaidMedia(long starCount, InputPaidMedia[] paidMedia, FormattedText caption, boolean showCaptionAboveMedia, String payload) { - this.starCount = starCount; - this.paidMedia = paidMedia; - this.caption = caption; - this.showCaptionAboveMedia = showCaptionAboveMedia; - this.payload = payload; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1274819374; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A photo message. - */ - public static class InputMessagePhoto extends InputMessageContent { - /** - * Photo to send. The photo must be at most 10 MB in size. The photo's width and height must not exceed 10000 in total. Width and height ratio must be at most 20. - */ - public InputFile photo; - /** - * Photo thumbnail to be sent; pass null to skip thumbnail uploading. The thumbnail is sent to the other party only in secret chats. - */ - public InputThumbnail thumbnail; - /** - * File identifiers of the stickers added to the photo, if applicable. - */ - public int[] addedStickerFileIds; - /** - * Photo width. - */ - public int width; - /** - * Photo height. - */ - public int height; - /** - * Photo caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters. - */ - public FormattedText caption; - /** - * True, if the caption must be shown above the photo; otherwise, the caption must be shown below the photo; not supported in secret chats. - */ - public boolean showCaptionAboveMedia; - /** - * Photo self-destruct type; pass null if none; private chats only. - */ - public MessageSelfDestructType selfDestructType; - /** - * True, if the photo preview must be covered by a spoiler animation; not supported in secret chats. - */ - public boolean hasSpoiler; - - /** - * A photo message. - */ - public InputMessagePhoto() { - } - - /** - * A photo message. - * - * @param photo Photo to send. The photo must be at most 10 MB in size. The photo's width and height must not exceed 10000 in total. Width and height ratio must be at most 20. - * @param thumbnail Photo thumbnail to be sent; pass null to skip thumbnail uploading. The thumbnail is sent to the other party only in secret chats. - * @param addedStickerFileIds File identifiers of the stickers added to the photo, if applicable. - * @param width Photo width. - * @param height Photo height. - * @param caption Photo caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters. - * @param showCaptionAboveMedia True, if the caption must be shown above the photo; otherwise, the caption must be shown below the photo; not supported in secret chats. - * @param selfDestructType Photo self-destruct type; pass null if none; private chats only. - * @param hasSpoiler True, if the photo preview must be covered by a spoiler animation; not supported in secret chats. - */ - public InputMessagePhoto(InputFile photo, InputThumbnail thumbnail, int[] addedStickerFileIds, int width, int height, FormattedText caption, boolean showCaptionAboveMedia, MessageSelfDestructType selfDestructType, boolean hasSpoiler) { - this.photo = photo; - this.thumbnail = thumbnail; - this.addedStickerFileIds = addedStickerFileIds; - this.width = width; - this.height = height; - this.caption = caption; - this.showCaptionAboveMedia = showCaptionAboveMedia; - this.selfDestructType = selfDestructType; - this.hasSpoiler = hasSpoiler; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -810129442; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A sticker message. - */ - public static class InputMessageSticker extends InputMessageContent { - /** - * Sticker to be sent. - */ - public InputFile sticker; - /** - * Sticker thumbnail; pass null to skip thumbnail uploading. - */ - public InputThumbnail thumbnail; - /** - * Sticker width. - */ - public int width; - /** - * Sticker height. - */ - public int height; - /** - * Emoji used to choose the sticker. - */ - public String emoji; - - /** - * A sticker message. - */ - public InputMessageSticker() { - } - - /** - * A sticker message. - * - * @param sticker Sticker to be sent. - * @param thumbnail Sticker thumbnail; pass null to skip thumbnail uploading. - * @param width Sticker width. - * @param height Sticker height. - * @param emoji Emoji used to choose the sticker. - */ - public InputMessageSticker(InputFile sticker, InputThumbnail thumbnail, int width, int height, String emoji) { - this.sticker = sticker; - this.thumbnail = thumbnail; - this.width = width; - this.height = height; - this.emoji = emoji; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1072805625; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A video message. - */ - public static class InputMessageVideo extends InputMessageContent { - /** - * Video to be sent. The video is expected to be re-encoded to MPEG4 format with H.264 codec by the sender. - */ - public InputFile video; - /** - * Video thumbnail; pass null to skip thumbnail uploading. - */ - public InputThumbnail thumbnail; - /** - * Cover of the video; pass null to skip cover uploading; not supported in secret chats and for self-destructing messages. - */ - public InputFile cover; - /** - * Timestamp from which the video playing must start, in seconds. - */ - public int startTimestamp; - /** - * File identifiers of the stickers added to the video, if applicable. - */ - public int[] addedStickerFileIds; - /** - * Duration of the video, in seconds. - */ - public int duration; - /** - * Video width. - */ - public int width; - /** - * Video height. - */ - public int height; - /** - * True, if the video is expected to be streamed. - */ - public boolean supportsStreaming; - /** - * Video caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters. - */ - public FormattedText caption; - /** - * True, if the caption must be shown above the video; otherwise, the caption must be shown below the video; not supported in secret chats. - */ - public boolean showCaptionAboveMedia; - /** - * Video self-destruct type; pass null if none; private chats only. - */ - public MessageSelfDestructType selfDestructType; - /** - * True, if the video preview must be covered by a spoiler animation; not supported in secret chats. - */ - public boolean hasSpoiler; - - /** - * A video message. - */ - public InputMessageVideo() { - } - - /** - * A video message. - * - * @param video Video to be sent. The video is expected to be re-encoded to MPEG4 format with H.264 codec by the sender. - * @param thumbnail Video thumbnail; pass null to skip thumbnail uploading. - * @param cover Cover of the video; pass null to skip cover uploading; not supported in secret chats and for self-destructing messages. - * @param startTimestamp Timestamp from which the video playing must start, in seconds. - * @param addedStickerFileIds File identifiers of the stickers added to the video, if applicable. - * @param duration Duration of the video, in seconds. - * @param width Video width. - * @param height Video height. - * @param supportsStreaming True, if the video is expected to be streamed. - * @param caption Video caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters. - * @param showCaptionAboveMedia True, if the caption must be shown above the video; otherwise, the caption must be shown below the video; not supported in secret chats. - * @param selfDestructType Video self-destruct type; pass null if none; private chats only. - * @param hasSpoiler True, if the video preview must be covered by a spoiler animation; not supported in secret chats. - */ - public InputMessageVideo(InputFile video, InputThumbnail thumbnail, InputFile cover, int startTimestamp, int[] addedStickerFileIds, int duration, int width, int height, boolean supportsStreaming, FormattedText caption, boolean showCaptionAboveMedia, MessageSelfDestructType selfDestructType, boolean hasSpoiler) { - this.video = video; - this.thumbnail = thumbnail; - this.cover = cover; - this.startTimestamp = startTimestamp; - this.addedStickerFileIds = addedStickerFileIds; - this.duration = duration; - this.width = width; - this.height = height; - this.supportsStreaming = supportsStreaming; - this.caption = caption; - this.showCaptionAboveMedia = showCaptionAboveMedia; - this.selfDestructType = selfDestructType; - this.hasSpoiler = hasSpoiler; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -605958271; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A video note message. - */ - public static class InputMessageVideoNote extends InputMessageContent { - /** - * Video note to be sent. The video is expected to be encoded to MPEG4 format with H.264 codec and have no data outside of the visible circle. - */ - public InputFile videoNote; - /** - * Video thumbnail; may be null if empty; pass null to skip thumbnail uploading. - */ - @Nullable public InputThumbnail thumbnail; - /** - * Duration of the video, in seconds; 0-60. - */ - public int duration; - /** - * Video width and height; must be positive and not greater than 640. - */ - public int length; - /** - * Video note self-destruct type; may be null if none; pass null if none; private chats only. - */ - @Nullable public MessageSelfDestructType selfDestructType; - - /** - * A video note message. - */ - public InputMessageVideoNote() { - } - - /** - * A video note message. - * - * @param videoNote Video note to be sent. The video is expected to be encoded to MPEG4 format with H.264 codec and have no data outside of the visible circle. - * @param thumbnail Video thumbnail; may be null if empty; pass null to skip thumbnail uploading. - * @param duration Duration of the video, in seconds; 0-60. - * @param length Video width and height; must be positive and not greater than 640. - * @param selfDestructType Video note self-destruct type; may be null if none; pass null if none; private chats only. - */ - public InputMessageVideoNote(InputFile videoNote, InputThumbnail thumbnail, int duration, int length, MessageSelfDestructType selfDestructType) { - this.videoNote = videoNote; - this.thumbnail = thumbnail; - this.duration = duration; - this.length = length; - this.selfDestructType = selfDestructType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -714598691; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A voice note message. - */ - public static class InputMessageVoiceNote extends InputMessageContent { - /** - * Voice note to be sent. The voice note must be encoded with the Opus codec and stored inside an OGG container with a single audio channel, or be in MP3 or M4A format as regular audio. - */ - public InputFile voiceNote; - /** - * Duration of the voice note, in seconds. - */ - public int duration; - /** - * Waveform representation of the voice note in 5-bit format. - */ - public byte[] waveform; - /** - * Voice note caption; may be null if empty; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters. - */ - @Nullable public FormattedText caption; - /** - * Voice note self-destruct type; may be null if none; pass null if none; private chats only. - */ - @Nullable public MessageSelfDestructType selfDestructType; - - /** - * A voice note message. - */ - public InputMessageVoiceNote() { - } - - /** - * A voice note message. - * - * @param voiceNote Voice note to be sent. The voice note must be encoded with the Opus codec and stored inside an OGG container with a single audio channel, or be in MP3 or M4A format as regular audio. - * @param duration Duration of the voice note, in seconds. - * @param waveform Waveform representation of the voice note in 5-bit format. - * @param caption Voice note caption; may be null if empty; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters. - * @param selfDestructType Voice note self-destruct type; may be null if none; pass null if none; private chats only. - */ - public InputMessageVoiceNote(InputFile voiceNote, int duration, byte[] waveform, FormattedText caption, MessageSelfDestructType selfDestructType) { - this.voiceNote = voiceNote; - this.duration = duration; - this.waveform = waveform; - this.caption = caption; - this.selfDestructType = selfDestructType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1461977004; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a location. - */ - public static class InputMessageLocation extends InputMessageContent { - /** - * Location to be sent. - */ - public Location location; - /** - * Period for which the location can be updated, in seconds; must be between 60 and 86400 for a temporary live location, 0x7FFFFFFF for permanent live location, and 0 otherwise. - */ - public int livePeriod; - /** - * For live locations, a direction in which the location moves, in degrees; 1-360. Pass 0 if unknown. - */ - public int heading; - /** - * For live locations, a maximum distance to another chat member for proximity alerts, in meters (0-100000). Pass 0 if the notification is disabled. Can't be enabled in channels and Saved Messages. - */ - public int proximityAlertRadius; - - /** - * A message with a location. - */ - public InputMessageLocation() { - } - - /** - * A message with a location. - * - * @param location Location to be sent. - * @param livePeriod Period for which the location can be updated, in seconds; must be between 60 and 86400 for a temporary live location, 0x7FFFFFFF for permanent live location, and 0 otherwise. - * @param heading For live locations, a direction in which the location moves, in degrees; 1-360. Pass 0 if unknown. - * @param proximityAlertRadius For live locations, a maximum distance to another chat member for proximity alerts, in meters (0-100000). Pass 0 if the notification is disabled. Can't be enabled in channels and Saved Messages. - */ - public InputMessageLocation(Location location, int livePeriod, int heading, int proximityAlertRadius) { - this.location = location; - this.livePeriod = livePeriod; - this.heading = heading; - this.proximityAlertRadius = proximityAlertRadius; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 648735088; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with information about a venue. - */ - public static class InputMessageVenue extends InputMessageContent { - /** - * Venue to send. - */ - public Venue venue; - - /** - * A message with information about a venue. - */ - public InputMessageVenue() { - } - - /** - * A message with information about a venue. - * - * @param venue Venue to send. - */ - public InputMessageVenue(Venue venue) { - this.venue = venue; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1447926269; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message containing a user contact. - */ - public static class InputMessageContact extends InputMessageContent { - /** - * Contact to send. - */ - public Contact contact; - - /** - * A message containing a user contact. - */ - public InputMessageContact() { - } - - /** - * A message containing a user contact. - * - * @param contact Contact to send. - */ - public InputMessageContact(Contact contact) { - this.contact = contact; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -982446849; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A dice message. - */ - public static class InputMessageDice extends InputMessageContent { - /** - * Emoji on which the dice throw animation is based. - */ - public String emoji; - /** - * True, if the chat message draft must be deleted. - */ - public boolean clearDraft; - - /** - * A dice message. - */ - public InputMessageDice() { - } - - /** - * A dice message. - * - * @param emoji Emoji on which the dice throw animation is based. - * @param clearDraft True, if the chat message draft must be deleted. - */ - public InputMessageDice(String emoji, boolean clearDraft) { - this.emoji = emoji; - this.clearDraft = clearDraft; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 841574313; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a game; not supported for channels or secret chats. - */ - public static class InputMessageGame extends InputMessageContent { - /** - * User identifier of the bot that owns the game. - */ - public long botUserId; - /** - * Short name of the game. - */ - public String gameShortName; - - /** - * A message with a game; not supported for channels or secret chats. - */ - public InputMessageGame() { - } - - /** - * A message with a game; not supported for channels or secret chats. - * - * @param botUserId User identifier of the bot that owns the game. - * @param gameShortName Short name of the game. - */ - public InputMessageGame(long botUserId, String gameShortName) { - this.botUserId = botUserId; - this.gameShortName = gameShortName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1252944610; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with an invoice; can be used only by bots. - */ - public static class InputMessageInvoice extends InputMessageContent { - /** - * Invoice. - */ - public Invoice invoice; - /** - * Product title; 1-32 characters. - */ - public String title; - /** - * Product description; 0-255 characters. - */ - public String description; - /** - * Product photo URL; optional. - */ - public String photoUrl; - /** - * Product photo size. - */ - public int photoSize; - /** - * Product photo width. - */ - public int photoWidth; - /** - * Product photo height. - */ - public int photoHeight; - /** - * The invoice payload. - */ - public byte[] payload; - /** - * Payment provider token; may be empty for payments in Telegram Stars. - */ - public String providerToken; - /** - * JSON-encoded data about the invoice, which will be shared with the payment provider. - */ - public String providerData; - /** - * Unique invoice bot deep link parameter for the generation of this invoice. If empty, it would be possible to pay directly from forwards of the invoice message. - */ - public String startParameter; - /** - * The content of paid media attached to the invoice; pass null if none. - */ - public InputPaidMedia paidMedia; - /** - * Paid media caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters. - */ - public FormattedText paidMediaCaption; - - /** - * A message with an invoice; can be used only by bots. - */ - public InputMessageInvoice() { - } - - /** - * A message with an invoice; can be used only by bots. - * - * @param invoice Invoice. - * @param title Product title; 1-32 characters. - * @param description Product description; 0-255 characters. - * @param photoUrl Product photo URL; optional. - * @param photoSize Product photo size. - * @param photoWidth Product photo width. - * @param photoHeight Product photo height. - * @param payload The invoice payload. - * @param providerToken Payment provider token; may be empty for payments in Telegram Stars. - * @param providerData JSON-encoded data about the invoice, which will be shared with the payment provider. - * @param startParameter Unique invoice bot deep link parameter for the generation of this invoice. If empty, it would be possible to pay directly from forwards of the invoice message. - * @param paidMedia The content of paid media attached to the invoice; pass null if none. - * @param paidMediaCaption Paid media caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters. - */ - public InputMessageInvoice(Invoice invoice, String title, String description, String photoUrl, int photoSize, int photoWidth, int photoHeight, byte[] payload, String providerToken, String providerData, String startParameter, InputPaidMedia paidMedia, FormattedText paidMediaCaption) { - this.invoice = invoice; - this.title = title; - this.description = description; - this.photoUrl = photoUrl; - this.photoSize = photoSize; - this.photoWidth = photoWidth; - this.photoHeight = photoHeight; - this.payload = payload; - this.providerToken = providerToken; - this.providerData = providerData; - this.startParameter = startParameter; - this.paidMedia = paidMedia; - this.paidMediaCaption = paidMediaCaption; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1162047631; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a poll. Polls can't be sent to secret chats and channel direct messages chats. Polls can be sent to a private chat only if the chat is a chat with a bot or the Saved Messages chat. - */ - public static class InputMessagePoll extends InputMessageContent { - /** - * Poll question; 1-255 characters (up to 300 characters for bots). Only custom emoji entities are allowed to be added and only by Premium users. - */ - public FormattedText question; - /** - * List of poll answer options, 2-getOption("poll_answer_count_max") strings 1-100 characters each. Only custom emoji entities are allowed to be added and only by Premium users. - */ - public FormattedText[] options; - /** - * True, if the poll voters are anonymous. Non-anonymous polls can't be sent or forwarded to channels. - */ - public boolean isAnonymous; - /** - * Type of the poll. - */ - public PollType type; - /** - * Amount of time the poll will be active after creation, in seconds; for bots only. - */ - public int openPeriod; - /** - * Point in time (Unix timestamp) when the poll will automatically be closed; for bots only. - */ - public int closeDate; - /** - * True, if the poll needs to be sent already closed; for bots only. - */ - public boolean isClosed; - - /** - * A message with a poll. Polls can't be sent to secret chats and channel direct messages chats. Polls can be sent to a private chat only if the chat is a chat with a bot or the Saved Messages chat. - */ - public InputMessagePoll() { - } - - /** - * A message with a poll. Polls can't be sent to secret chats and channel direct messages chats. Polls can be sent to a private chat only if the chat is a chat with a bot or the Saved Messages chat. - * - * @param question Poll question; 1-255 characters (up to 300 characters for bots). Only custom emoji entities are allowed to be added and only by Premium users. - * @param options List of poll answer options, 2-getOption("poll_answer_count_max") strings 1-100 characters each. Only custom emoji entities are allowed to be added and only by Premium users. - * @param isAnonymous True, if the poll voters are anonymous. Non-anonymous polls can't be sent or forwarded to channels. - * @param type Type of the poll. - * @param openPeriod Amount of time the poll will be active after creation, in seconds; for bots only. - * @param closeDate Point in time (Unix timestamp) when the poll will automatically be closed; for bots only. - * @param isClosed True, if the poll needs to be sent already closed; for bots only. - */ - public InputMessagePoll(FormattedText question, FormattedText[] options, boolean isAnonymous, PollType type, int openPeriod, int closeDate, boolean isClosed) { - this.question = question; - this.options = options; - this.isAnonymous = isAnonymous; - this.type = type; - this.openPeriod = openPeriod; - this.closeDate = closeDate; - this.isClosed = isClosed; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -263337164; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A stake dice message. - */ - public static class InputMessageStakeDice extends InputMessageContent { - /** - * Hash of the stake dice state. The state hash can be used only if it was received recently enough. Otherwise, a new state must be requested using getStakeDiceState. - */ - public String stateHash; - /** - * The Toncoin amount that will be staked; in the smallest units of the currency. Must be in the range getOption("stake_dice_stake_amount_min")-getOption("stake_dice_stake_amount_max"). - */ - public long stakeToncoinAmount; - /** - * True, if the chat message draft must be deleted. - */ - public boolean clearDraft; - - /** - * A stake dice message. - */ - public InputMessageStakeDice() { - } - - /** - * A stake dice message. - * - * @param stateHash Hash of the stake dice state. The state hash can be used only if it was received recently enough. Otherwise, a new state must be requested using getStakeDiceState. - * @param stakeToncoinAmount The Toncoin amount that will be staked; in the smallest units of the currency. Must be in the range getOption("stake_dice_stake_amount_min")-getOption("stake_dice_stake_amount_max"). - * @param clearDraft True, if the chat message draft must be deleted. - */ - public InputMessageStakeDice(String stateHash, long stakeToncoinAmount, boolean clearDraft) { - this.stateHash = stateHash; - this.stakeToncoinAmount = stakeToncoinAmount; - this.clearDraft = clearDraft; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1946603673; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a forwarded story. Stories can't be forwarded to secret chats. A story can be forwarded only if story.canBeForwarded. - */ - public static class InputMessageStory extends InputMessageContent { - /** - * Identifier of the chat that posted the story. - */ - public long storyPosterChatId; - /** - * Story identifier. - */ - public int storyId; - - /** - * A message with a forwarded story. Stories can't be forwarded to secret chats. A story can be forwarded only if story.canBeForwarded. - */ - public InputMessageStory() { - } - - /** - * A message with a forwarded story. Stories can't be forwarded to secret chats. A story can be forwarded only if story.canBeForwarded. - * - * @param storyPosterChatId Identifier of the chat that posted the story. - * @param storyId Story identifier. - */ - public InputMessageStory(long storyPosterChatId, int storyId) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -370732053; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a checklist. Checklists can't be sent to secret chats, channel chats and channel direct messages chats; for Telegram Premium users only. - */ - public static class InputMessageChecklist extends InputMessageContent { - /** - * The checklist to send. - */ - public InputChecklist checklist; - - /** - * A message with a checklist. Checklists can't be sent to secret chats, channel chats and channel direct messages chats; for Telegram Premium users only. - */ - public InputMessageChecklist() { - } - - /** - * A message with a checklist. Checklists can't be sent to secret chats, channel chats and channel direct messages chats; for Telegram Premium users only. - * - * @param checklist The checklist to send. - */ - public InputMessageChecklist(InputChecklist checklist) { - this.checklist = checklist; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1722965261; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A forwarded message. - */ - public static class InputMessageForwarded extends InputMessageContent { - /** - * Identifier for the chat this forwarded message came from. - */ - public long fromChatId; - /** - * Identifier of the message to forward. A message can be forwarded only if messageProperties.canBeForwarded. - */ - public long messageId; - /** - * Pass true if a game message is being shared from a launched game; applies only to game messages. - */ - public boolean inGameShare; - /** - * Pass true to replace video start timestamp in the forwarded message. - */ - public boolean replaceVideoStartTimestamp; - /** - * The new video start timestamp; ignored if replaceVideoStartTimestamp == false. - */ - public int newVideoStartTimestamp; - /** - * Options to be used to copy content of the message without reference to the original sender; pass null to forward the message as usual. - */ - public MessageCopyOptions copyOptions; - - /** - * A forwarded message. - */ - public InputMessageForwarded() { - } - - /** - * A forwarded message. - * - * @param fromChatId Identifier for the chat this forwarded message came from. - * @param messageId Identifier of the message to forward. A message can be forwarded only if messageProperties.canBeForwarded. - * @param inGameShare Pass true if a game message is being shared from a launched game; applies only to game messages. - * @param replaceVideoStartTimestamp Pass true to replace video start timestamp in the forwarded message. - * @param newVideoStartTimestamp The new video start timestamp; ignored if replaceVideoStartTimestamp == false. - * @param copyOptions Options to be used to copy content of the message without reference to the original sender; pass null to forward the message as usual. - */ - public InputMessageForwarded(long fromChatId, long messageId, boolean inGameShare, boolean replaceVideoStartTimestamp, int newVideoStartTimestamp, MessageCopyOptions copyOptions) { - this.fromChatId = fromChatId; - this.messageId = messageId; - this.inGameShare = inGameShare; - this.replaceVideoStartTimestamp = replaceVideoStartTimestamp; - this.newVideoStartTimestamp = newVideoStartTimestamp; - this.copyOptions = copyOptions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1076506316; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains information about the message or the story to be replied. - */ - public abstract static class InputMessageReplyTo extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InputMessageReplyToMessage.CONSTRUCTOR, - InputMessageReplyToExternalMessage.CONSTRUCTOR, - InputMessageReplyToStory.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InputMessageReplyTo() { - } - } - - /** - * Describes a message to be replied in the same chat and forum topic. - */ - public static class InputMessageReplyToMessage extends InputMessageReplyTo { - /** - * The identifier of the message to be replied in the same chat and forum topic. A message can be replied in the same chat and forum topic only if messageProperties.canBeReplied. - */ - public long messageId; - /** - * Quote from the message to be replied; pass null if none. Must always be null for replies in secret chats. - */ - public InputTextQuote quote; - /** - * Identifier of the checklist task in the message to be replied; pass 0 to reply to the whole message. - */ - public int checklistTaskId; - - /** - * Describes a message to be replied in the same chat and forum topic. - */ - public InputMessageReplyToMessage() { - } - - /** - * Describes a message to be replied in the same chat and forum topic. - * - * @param messageId The identifier of the message to be replied in the same chat and forum topic. A message can be replied in the same chat and forum topic only if messageProperties.canBeReplied. - * @param quote Quote from the message to be replied; pass null if none. Must always be null for replies in secret chats. - * @param checklistTaskId Identifier of the checklist task in the message to be replied; pass 0 to reply to the whole message. - */ - public InputMessageReplyToMessage(long messageId, InputTextQuote quote, int checklistTaskId) { - this.messageId = messageId; - this.quote = quote; - this.checklistTaskId = checklistTaskId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -782038760; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a message to be replied that is from a different chat or a forum topic; not supported in secret chats. - */ - public static class InputMessageReplyToExternalMessage extends InputMessageReplyTo { - /** - * The identifier of the chat to which the message to be replied belongs. - */ - public long chatId; - /** - * The identifier of the message to be replied in the specified chat. A message can be replied in another chat or forum topic only if messageProperties.canBeRepliedInAnotherChat. - */ - public long messageId; - /** - * Quote from the message to be replied; pass null if none. - */ - public InputTextQuote quote; - /** - * Identifier of the checklist task in the message to be replied; pass 0 to reply to the whole message. - */ - public int checklistTaskId; - - /** - * Describes a message to be replied that is from a different chat or a forum topic; not supported in secret chats. - */ - public InputMessageReplyToExternalMessage() { - } - - /** - * Describes a message to be replied that is from a different chat or a forum topic; not supported in secret chats. - * - * @param chatId The identifier of the chat to which the message to be replied belongs. - * @param messageId The identifier of the message to be replied in the specified chat. A message can be replied in another chat or forum topic only if messageProperties.canBeRepliedInAnotherChat. - * @param quote Quote from the message to be replied; pass null if none. - * @param checklistTaskId Identifier of the checklist task in the message to be replied; pass 0 to reply to the whole message. - */ - public InputMessageReplyToExternalMessage(long chatId, long messageId, InputTextQuote quote, int checklistTaskId) { - this.chatId = chatId; - this.messageId = messageId; - this.quote = quote; - this.checklistTaskId = checklistTaskId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -505276703; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a story to be replied. - */ - public static class InputMessageReplyToStory extends InputMessageReplyTo { - /** - * The identifier of the poster of the story. Currently, stories can be replied only in the chat that posted the story; channel stories can't be replied. - */ - public long storyPosterChatId; - /** - * The identifier of the story. - */ - public int storyId; - - /** - * Describes a story to be replied. - */ - public InputMessageReplyToStory() { - } - - /** - * Describes a story to be replied. - * - * @param storyPosterChatId The identifier of the poster of the story. Currently, stories can be replied only in the chat that posted the story; channel stories can't be replied. - * @param storyId The identifier of the story. - */ - public InputMessageReplyToStory(long storyPosterChatId, int storyId) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1723842320; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a paid media to be sent. - */ - public static class InputPaidMedia extends Object { - /** - * Type of the media. - */ - public InputPaidMediaType type; - /** - * Photo or video to be sent. - */ - public InputFile media; - /** - * Media thumbnail; pass null to skip thumbnail uploading. - */ - public InputThumbnail thumbnail; - /** - * File identifiers of the stickers added to the media, if applicable. - */ - public int[] addedStickerFileIds; - /** - * Media width. - */ - public int width; - /** - * Media height. - */ - public int height; - - /** - * Describes a paid media to be sent. - */ - public InputPaidMedia() { - } - - /** - * Describes a paid media to be sent. - * - * @param type Type of the media. - * @param media Photo or video to be sent. - * @param thumbnail Media thumbnail; pass null to skip thumbnail uploading. - * @param addedStickerFileIds File identifiers of the stickers added to the media, if applicable. - * @param width Media width. - * @param height Media height. - */ - public InputPaidMedia(InputPaidMediaType type, InputFile media, InputThumbnail thumbnail, int[] addedStickerFileIds, int width, int height) { - this.type = type; - this.media = media; - this.thumbnail = thumbnail; - this.addedStickerFileIds = addedStickerFileIds; - this.width = width; - this.height = height; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 475844035; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of paid media to sent. - */ - public abstract static class InputPaidMediaType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InputPaidMediaTypePhoto.CONSTRUCTOR, - InputPaidMediaTypeVideo.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InputPaidMediaType() { - } - } - - /** - * The media is a photo. The photo must be at most 10 MB in size. The photo's width and height must not exceed 10000 in total. Width and height ratio must be at most 20. - */ - public static class InputPaidMediaTypePhoto extends InputPaidMediaType { - - /** - * The media is a photo. The photo must be at most 10 MB in size. The photo's width and height must not exceed 10000 in total. Width and height ratio must be at most 20. - */ - public InputPaidMediaTypePhoto() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -761660134; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The media is a video. - */ - public static class InputPaidMediaTypeVideo extends InputPaidMediaType { - /** - * Cover of the video; pass null to skip cover uploading. - */ - public InputFile cover; - /** - * Timestamp from which the video playing must start, in seconds. - */ - public int startTimestamp; - /** - * Duration of the video, in seconds. - */ - public int duration; - /** - * True, if the video is expected to be streamed. - */ - public boolean supportsStreaming; - - /** - * The media is a video. - */ - public InputPaidMediaTypeVideo() { - } - - /** - * The media is a video. - * - * @param cover Cover of the video; pass null to skip cover uploading. - * @param startTimestamp Timestamp from which the video playing must start, in seconds. - * @param duration Duration of the video, in seconds. - * @param supportsStreaming True, if the video is expected to be streamed. - */ - public InputPaidMediaTypeVideo(InputFile cover, int startTimestamp, int duration, boolean supportsStreaming) { - this.cover = cover; - this.startTimestamp = startTimestamp; - this.duration = duration; - this.supportsStreaming = supportsStreaming; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1793741625; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains information about a Telegram Passport element to be saved. - */ - public abstract static class InputPassportElement extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InputPassportElementPersonalDetails.CONSTRUCTOR, - InputPassportElementPassport.CONSTRUCTOR, - InputPassportElementDriverLicense.CONSTRUCTOR, - InputPassportElementIdentityCard.CONSTRUCTOR, - InputPassportElementInternalPassport.CONSTRUCTOR, - InputPassportElementAddress.CONSTRUCTOR, - InputPassportElementUtilityBill.CONSTRUCTOR, - InputPassportElementBankStatement.CONSTRUCTOR, - InputPassportElementRentalAgreement.CONSTRUCTOR, - InputPassportElementPassportRegistration.CONSTRUCTOR, - InputPassportElementTemporaryRegistration.CONSTRUCTOR, - InputPassportElementPhoneNumber.CONSTRUCTOR, - InputPassportElementEmailAddress.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InputPassportElement() { - } - } - - /** - * A Telegram Passport element to be saved containing the user's personal details. - */ - public static class InputPassportElementPersonalDetails extends InputPassportElement { - /** - * Personal details of the user. - */ - public PersonalDetails personalDetails; - - /** - * A Telegram Passport element to be saved containing the user's personal details. - */ - public InputPassportElementPersonalDetails() { - } - - /** - * A Telegram Passport element to be saved containing the user's personal details. - * - * @param personalDetails Personal details of the user. - */ - public InputPassportElementPersonalDetails(PersonalDetails personalDetails) { - this.personalDetails = personalDetails; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 164791359; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element to be saved containing the user's passport. - */ - public static class InputPassportElementPassport extends InputPassportElement { - /** - * The passport to be saved. - */ - public InputIdentityDocument passport; - - /** - * A Telegram Passport element to be saved containing the user's passport. - */ - public InputPassportElementPassport() { - } - - /** - * A Telegram Passport element to be saved containing the user's passport. - * - * @param passport The passport to be saved. - */ - public InputPassportElementPassport(InputIdentityDocument passport) { - this.passport = passport; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -497011356; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element to be saved containing the user's driver license. - */ - public static class InputPassportElementDriverLicense extends InputPassportElement { - /** - * The driver license to be saved. - */ - public InputIdentityDocument driverLicense; - - /** - * A Telegram Passport element to be saved containing the user's driver license. - */ - public InputPassportElementDriverLicense() { - } - - /** - * A Telegram Passport element to be saved containing the user's driver license. - * - * @param driverLicense The driver license to be saved. - */ - public InputPassportElementDriverLicense(InputIdentityDocument driverLicense) { - this.driverLicense = driverLicense; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 304813264; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element to be saved containing the user's identity card. - */ - public static class InputPassportElementIdentityCard extends InputPassportElement { - /** - * The identity card to be saved. - */ - public InputIdentityDocument identityCard; - - /** - * A Telegram Passport element to be saved containing the user's identity card. - */ - public InputPassportElementIdentityCard() { - } - - /** - * A Telegram Passport element to be saved containing the user's identity card. - * - * @param identityCard The identity card to be saved. - */ - public InputPassportElementIdentityCard(InputIdentityDocument identityCard) { - this.identityCard = identityCard; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -9963390; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element to be saved containing the user's internal passport. - */ - public static class InputPassportElementInternalPassport extends InputPassportElement { - /** - * The internal passport to be saved. - */ - public InputIdentityDocument internalPassport; - - /** - * A Telegram Passport element to be saved containing the user's internal passport. - */ - public InputPassportElementInternalPassport() { - } - - /** - * A Telegram Passport element to be saved containing the user's internal passport. - * - * @param internalPassport The internal passport to be saved. - */ - public InputPassportElementInternalPassport(InputIdentityDocument internalPassport) { - this.internalPassport = internalPassport; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 715360043; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element to be saved containing the user's address. - */ - public static class InputPassportElementAddress extends InputPassportElement { - /** - * The address to be saved. - */ - public Address address; - - /** - * A Telegram Passport element to be saved containing the user's address. - */ - public InputPassportElementAddress() { - } - - /** - * A Telegram Passport element to be saved containing the user's address. - * - * @param address The address to be saved. - */ - public InputPassportElementAddress(Address address) { - this.address = address; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 461630480; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element to be saved containing the user's utility bill. - */ - public static class InputPassportElementUtilityBill extends InputPassportElement { - /** - * The utility bill to be saved. - */ - public InputPersonalDocument utilityBill; - - /** - * A Telegram Passport element to be saved containing the user's utility bill. - */ - public InputPassportElementUtilityBill() { - } - - /** - * A Telegram Passport element to be saved containing the user's utility bill. - * - * @param utilityBill The utility bill to be saved. - */ - public InputPassportElementUtilityBill(InputPersonalDocument utilityBill) { - this.utilityBill = utilityBill; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1389203841; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element to be saved containing the user's bank statement. - */ - public static class InputPassportElementBankStatement extends InputPassportElement { - /** - * The bank statement to be saved. - */ - public InputPersonalDocument bankStatement; - - /** - * A Telegram Passport element to be saved containing the user's bank statement. - */ - public InputPassportElementBankStatement() { - } - - /** - * A Telegram Passport element to be saved containing the user's bank statement. - * - * @param bankStatement The bank statement to be saved. - */ - public InputPassportElementBankStatement(InputPersonalDocument bankStatement) { - this.bankStatement = bankStatement; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -26585208; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element to be saved containing the user's rental agreement. - */ - public static class InputPassportElementRentalAgreement extends InputPassportElement { - /** - * The rental agreement to be saved. - */ - public InputPersonalDocument rentalAgreement; - - /** - * A Telegram Passport element to be saved containing the user's rental agreement. - */ - public InputPassportElementRentalAgreement() { - } - - /** - * A Telegram Passport element to be saved containing the user's rental agreement. - * - * @param rentalAgreement The rental agreement to be saved. - */ - public InputPassportElementRentalAgreement(InputPersonalDocument rentalAgreement) { - this.rentalAgreement = rentalAgreement; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1736154155; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element to be saved containing the user's passport registration. - */ - public static class InputPassportElementPassportRegistration extends InputPassportElement { - /** - * The passport registration page to be saved. - */ - public InputPersonalDocument passportRegistration; - - /** - * A Telegram Passport element to be saved containing the user's passport registration. - */ - public InputPassportElementPassportRegistration() { - } - - /** - * A Telegram Passport element to be saved containing the user's passport registration. - * - * @param passportRegistration The passport registration page to be saved. - */ - public InputPassportElementPassportRegistration(InputPersonalDocument passportRegistration) { - this.passportRegistration = passportRegistration; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1314562128; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element to be saved containing the user's temporary registration. - */ - public static class InputPassportElementTemporaryRegistration extends InputPassportElement { - /** - * The temporary registration document to be saved. - */ - public InputPersonalDocument temporaryRegistration; - - /** - * A Telegram Passport element to be saved containing the user's temporary registration. - */ - public InputPassportElementTemporaryRegistration() { - } - - /** - * A Telegram Passport element to be saved containing the user's temporary registration. - * - * @param temporaryRegistration The temporary registration document to be saved. - */ - public InputPassportElementTemporaryRegistration(InputPersonalDocument temporaryRegistration) { - this.temporaryRegistration = temporaryRegistration; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1913238047; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element to be saved containing the user's phone number. - */ - public static class InputPassportElementPhoneNumber extends InputPassportElement { - /** - * The phone number to be saved. - */ - public String phoneNumber; - - /** - * A Telegram Passport element to be saved containing the user's phone number. - */ - public InputPassportElementPhoneNumber() { - } - - /** - * A Telegram Passport element to be saved containing the user's phone number. - * - * @param phoneNumber The phone number to be saved. - */ - public InputPassportElementPhoneNumber(String phoneNumber) { - this.phoneNumber = phoneNumber; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1319357497; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element to be saved containing the user's email address. - */ - public static class InputPassportElementEmailAddress extends InputPassportElement { - /** - * The email address to be saved. - */ - public String emailAddress; - - /** - * A Telegram Passport element to be saved containing the user's email address. - */ - public InputPassportElementEmailAddress() { - } - - /** - * A Telegram Passport element to be saved containing the user's email address. - * - * @param emailAddress The email address to be saved. - */ - public InputPassportElementEmailAddress(String emailAddress) { - this.emailAddress = emailAddress; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -248605659; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains the description of an error in a Telegram Passport element; for bots only. - */ - public static class InputPassportElementError extends Object { - /** - * Type of Telegram Passport element that has the error. - */ - public PassportElementType type; - /** - * Error message. - */ - public String message; - /** - * Error source. - */ - public InputPassportElementErrorSource source; - - /** - * Contains the description of an error in a Telegram Passport element; for bots only. - */ - public InputPassportElementError() { - } - - /** - * Contains the description of an error in a Telegram Passport element; for bots only. - * - * @param type Type of Telegram Passport element that has the error. - * @param message Error message. - * @param source Error source. - */ - public InputPassportElementError(PassportElementType type, String message, InputPassportElementErrorSource source) { - this.type = type; - this.message = message; - this.source = source; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 285756898; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains the description of an error in a Telegram Passport element; for bots only. - */ - public abstract static class InputPassportElementErrorSource extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InputPassportElementErrorSourceUnspecified.CONSTRUCTOR, - InputPassportElementErrorSourceDataField.CONSTRUCTOR, - InputPassportElementErrorSourceFrontSide.CONSTRUCTOR, - InputPassportElementErrorSourceReverseSide.CONSTRUCTOR, - InputPassportElementErrorSourceSelfie.CONSTRUCTOR, - InputPassportElementErrorSourceTranslationFile.CONSTRUCTOR, - InputPassportElementErrorSourceTranslationFiles.CONSTRUCTOR, - InputPassportElementErrorSourceFile.CONSTRUCTOR, - InputPassportElementErrorSourceFiles.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InputPassportElementErrorSource() { - } - } - - /** - * The element contains an error in an unspecified place. The error will be considered resolved when new data is added. - */ - public static class InputPassportElementErrorSourceUnspecified extends InputPassportElementErrorSource { - /** - * Current hash of the entire element. - */ - public byte[] elementHash; - - /** - * The element contains an error in an unspecified place. The error will be considered resolved when new data is added. - */ - public InputPassportElementErrorSourceUnspecified() { - } - - /** - * The element contains an error in an unspecified place. The error will be considered resolved when new data is added. - * - * @param elementHash Current hash of the entire element. - */ - public InputPassportElementErrorSourceUnspecified(byte[] elementHash) { - this.elementHash = elementHash; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 267230319; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A data field contains an error. The error is considered resolved when the field's value changes. - */ - public static class InputPassportElementErrorSourceDataField extends InputPassportElementErrorSource { - /** - * Field name. - */ - public String fieldName; - /** - * Current data hash. - */ - public byte[] dataHash; - - /** - * A data field contains an error. The error is considered resolved when the field's value changes. - */ - public InputPassportElementErrorSourceDataField() { - } - - /** - * A data field contains an error. The error is considered resolved when the field's value changes. - * - * @param fieldName Field name. - * @param dataHash Current data hash. - */ - public InputPassportElementErrorSourceDataField(String fieldName, byte[] dataHash) { - this.fieldName = fieldName; - this.dataHash = dataHash; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -426795002; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The front side of the document contains an error. The error is considered resolved when the file with the front side of the document changes. - */ - public static class InputPassportElementErrorSourceFrontSide extends InputPassportElementErrorSource { - /** - * Current hash of the file containing the front side. - */ - public byte[] fileHash; - - /** - * The front side of the document contains an error. The error is considered resolved when the file with the front side of the document changes. - */ - public InputPassportElementErrorSourceFrontSide() { - } - - /** - * The front side of the document contains an error. The error is considered resolved when the file with the front side of the document changes. - * - * @param fileHash Current hash of the file containing the front side. - */ - public InputPassportElementErrorSourceFrontSide(byte[] fileHash) { - this.fileHash = fileHash; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 588023741; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The reverse side of the document contains an error. The error is considered resolved when the file with the reverse side of the document changes. - */ - public static class InputPassportElementErrorSourceReverseSide extends InputPassportElementErrorSource { - /** - * Current hash of the file containing the reverse side. - */ - public byte[] fileHash; - - /** - * The reverse side of the document contains an error. The error is considered resolved when the file with the reverse side of the document changes. - */ - public InputPassportElementErrorSourceReverseSide() { - } - - /** - * The reverse side of the document contains an error. The error is considered resolved when the file with the reverse side of the document changes. - * - * @param fileHash Current hash of the file containing the reverse side. - */ - public InputPassportElementErrorSourceReverseSide(byte[] fileHash) { - this.fileHash = fileHash; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 413072891; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The selfie contains an error. The error is considered resolved when the file with the selfie changes. - */ - public static class InputPassportElementErrorSourceSelfie extends InputPassportElementErrorSource { - /** - * Current hash of the file containing the selfie. - */ - public byte[] fileHash; - - /** - * The selfie contains an error. The error is considered resolved when the file with the selfie changes. - */ - public InputPassportElementErrorSourceSelfie() { - } - - /** - * The selfie contains an error. The error is considered resolved when the file with the selfie changes. - * - * @param fileHash Current hash of the file containing the selfie. - */ - public InputPassportElementErrorSourceSelfie(byte[] fileHash) { - this.fileHash = fileHash; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -773575528; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * One of the files containing the translation of the document contains an error. The error is considered resolved when the file with the translation changes. - */ - public static class InputPassportElementErrorSourceTranslationFile extends InputPassportElementErrorSource { - /** - * Current hash of the file containing the translation. - */ - public byte[] fileHash; - - /** - * One of the files containing the translation of the document contains an error. The error is considered resolved when the file with the translation changes. - */ - public InputPassportElementErrorSourceTranslationFile() { - } - - /** - * One of the files containing the translation of the document contains an error. The error is considered resolved when the file with the translation changes. - * - * @param fileHash Current hash of the file containing the translation. - */ - public InputPassportElementErrorSourceTranslationFile(byte[] fileHash) { - this.fileHash = fileHash; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 505842299; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The translation of the document contains an error. The error is considered resolved when the list of files changes. - */ - public static class InputPassportElementErrorSourceTranslationFiles extends InputPassportElementErrorSource { - /** - * Current hashes of all files with the translation. - */ - public byte[][] fileHashes; - - /** - * The translation of the document contains an error. The error is considered resolved when the list of files changes. - */ - public InputPassportElementErrorSourceTranslationFiles() { - } - - /** - * The translation of the document contains an error. The error is considered resolved when the list of files changes. - * - * @param fileHashes Current hashes of all files with the translation. - */ - public InputPassportElementErrorSourceTranslationFiles(byte[][] fileHashes) { - this.fileHashes = fileHashes; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -527254048; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file contains an error. The error is considered resolved when the file changes. - */ - public static class InputPassportElementErrorSourceFile extends InputPassportElementErrorSource { - /** - * Current hash of the file which has the error. - */ - public byte[] fileHash; - - /** - * The file contains an error. The error is considered resolved when the file changes. - */ - public InputPassportElementErrorSourceFile() { - } - - /** - * The file contains an error. The error is considered resolved when the file changes. - * - * @param fileHash Current hash of the file which has the error. - */ - public InputPassportElementErrorSourceFile(byte[] fileHash) { - this.fileHash = fileHash; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -298492469; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of attached files contains an error. The error is considered resolved when the file list changes. - */ - public static class InputPassportElementErrorSourceFiles extends InputPassportElementErrorSource { - /** - * Current hashes of all attached files. - */ - public byte[][] fileHashes; - - /** - * The list of attached files contains an error. The error is considered resolved when the file list changes. - */ - public InputPassportElementErrorSourceFiles() { - } - - /** - * The list of attached files contains an error. The error is considered resolved when the file list changes. - * - * @param fileHashes Current hashes of all attached files. - */ - public InputPassportElementErrorSourceFiles(byte[][] fileHashes) { - this.fileHashes = fileHashes; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2008541640; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A personal document to be saved to Telegram Passport. - */ - public static class InputPersonalDocument extends Object { - /** - * List of files containing the pages of the document. - */ - public InputFile[] files; - /** - * List of files containing a certified English translation of the document. - */ - public InputFile[] translation; - - /** - * A personal document to be saved to Telegram Passport. - */ - public InputPersonalDocument() { - } - - /** - * A personal document to be saved to Telegram Passport. - * - * @param files List of files containing the pages of the document. - * @param translation List of files containing a certified English translation of the document. - */ - public InputPersonalDocument(InputFile[] files, InputFile[] translation) { - this.files = files; - this.translation = translation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1676966826; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A sticker to be added to a sticker set. - */ - public static class InputSticker extends Object { - /** - * File with the sticker; must fit in a 512x512 square. For WEBP stickers the file must be in WEBP or PNG format, which will be converted to WEBP server-side. See https://core.telegram.org/animated_stickers#technical-requirements for technical requirements. - */ - public InputFile sticker; - /** - * Format of the sticker. - */ - public StickerFormat format; - /** - * String with 1-20 emoji corresponding to the sticker. - */ - public String emojis; - /** - * Position where the mask is placed; pass null if not specified. - */ - public MaskPosition maskPosition; - /** - * List of up to 20 keywords with total length up to 64 characters, which can be used to find the sticker. - */ - public String[] keywords; - - /** - * A sticker to be added to a sticker set. - */ - public InputSticker() { - } - - /** - * A sticker to be added to a sticker set. - * - * @param sticker File with the sticker; must fit in a 512x512 square. For WEBP stickers the file must be in WEBP or PNG format, which will be converted to WEBP server-side. See https://core.telegram.org/animated_stickers#technical-requirements for technical requirements. - * @param format Format of the sticker. - * @param emojis String with 1-20 emoji corresponding to the sticker. - * @param maskPosition Position where the mask is placed; pass null if not specified. - * @param keywords List of up to 20 keywords with total length up to 64 characters, which can be used to find the sticker. - */ - public InputSticker(InputFile sticker, StickerFormat format, String emojis, MaskPosition maskPosition, String[] keywords) { - this.sticker = sticker; - this.format = format; - this.emojis = emojis; - this.maskPosition = maskPosition; - this.keywords = keywords; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1589392402; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a clickable rectangle area on a story media to be added. - */ - public static class InputStoryArea extends Object { - /** - * Position of the area. - */ - public StoryAreaPosition position; - /** - * Type of the area. - */ - public InputStoryAreaType type; - - /** - * Describes a clickable rectangle area on a story media to be added. - */ - public InputStoryArea() { - } - - /** - * Describes a clickable rectangle area on a story media to be added. - * - * @param position Position of the area. - * @param type Type of the area. - */ - public InputStoryArea(StoryAreaPosition position, InputStoryAreaType type) { - this.position = position; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 122859135; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of clickable area on a story media to be added. - */ - public abstract static class InputStoryAreaType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InputStoryAreaTypeLocation.CONSTRUCTOR, - InputStoryAreaTypeFoundVenue.CONSTRUCTOR, - InputStoryAreaTypePreviousVenue.CONSTRUCTOR, - InputStoryAreaTypeSuggestedReaction.CONSTRUCTOR, - InputStoryAreaTypeMessage.CONSTRUCTOR, - InputStoryAreaTypeLink.CONSTRUCTOR, - InputStoryAreaTypeWeather.CONSTRUCTOR, - InputStoryAreaTypeUpgradedGift.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InputStoryAreaType() { - } - } - - /** - * An area pointing to a location. - */ - public static class InputStoryAreaTypeLocation extends InputStoryAreaType { - /** - * The location. - */ - public Location location; - /** - * Address of the location; pass null if unknown. - */ - public LocationAddress address; - - /** - * An area pointing to a location. - */ - public InputStoryAreaTypeLocation() { - } - - /** - * An area pointing to a location. - * - * @param location The location. - * @param address Address of the location; pass null if unknown. - */ - public InputStoryAreaTypeLocation(Location location, LocationAddress address) { - this.location = location; - this.address = address; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1433714887; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An area pointing to a venue found by the bot getOption("venue_search_bot_username"). - */ - public static class InputStoryAreaTypeFoundVenue extends InputStoryAreaType { - /** - * Identifier of the inline query, used to found the venue. - */ - public long queryId; - /** - * Identifier of the inline query result. - */ - public String resultId; - - /** - * An area pointing to a venue found by the bot getOption("venue_search_bot_username"). - */ - public InputStoryAreaTypeFoundVenue() { - } - - /** - * An area pointing to a venue found by the bot getOption("venue_search_bot_username"). - * - * @param queryId Identifier of the inline query, used to found the venue. - * @param resultId Identifier of the inline query result. - */ - public InputStoryAreaTypeFoundVenue(long queryId, String resultId) { - this.queryId = queryId; - this.resultId = resultId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1395809130; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An area pointing to a venue already added to the story. - */ - public static class InputStoryAreaTypePreviousVenue extends InputStoryAreaType { - /** - * Provider of the venue. - */ - public String venueProvider; - /** - * Identifier of the venue in the provider database. - */ - public String venueId; - - /** - * An area pointing to a venue already added to the story. - */ - public InputStoryAreaTypePreviousVenue() { - } - - /** - * An area pointing to a venue already added to the story. - * - * @param venueProvider Provider of the venue. - * @param venueId Identifier of the venue in the provider database. - */ - public InputStoryAreaTypePreviousVenue(String venueProvider, String venueId) { - this.venueProvider = venueProvider; - this.venueId = venueId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1846693388; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An area pointing to a suggested reaction. - */ - public static class InputStoryAreaTypeSuggestedReaction extends InputStoryAreaType { - /** - * Type of the reaction. - */ - public ReactionType reactionType; - /** - * True, if reaction has a dark background. - */ - public boolean isDark; - /** - * True, if reaction corner is flipped. - */ - public boolean isFlipped; - - /** - * An area pointing to a suggested reaction. - */ - public InputStoryAreaTypeSuggestedReaction() { - } - - /** - * An area pointing to a suggested reaction. - * - * @param reactionType Type of the reaction. - * @param isDark True, if reaction has a dark background. - * @param isFlipped True, if reaction corner is flipped. - */ - public InputStoryAreaTypeSuggestedReaction(ReactionType reactionType, boolean isDark, boolean isFlipped) { - this.reactionType = reactionType; - this.isDark = isDark; - this.isFlipped = isFlipped; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2101826003; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An area pointing to a message. - */ - public static class InputStoryAreaTypeMessage extends InputStoryAreaType { - /** - * Identifier of the chat with the message. Currently, the chat must be a supergroup or a channel chat. - */ - public long chatId; - /** - * Identifier of the message. Use messageProperties.canBeSharedInStory to check whether the message is suitable. - */ - public long messageId; - - /** - * An area pointing to a message. - */ - public InputStoryAreaTypeMessage() { - } - - /** - * An area pointing to a message. - * - * @param chatId Identifier of the chat with the message. Currently, the chat must be a supergroup or a channel chat. - * @param messageId Identifier of the message. Use messageProperties.canBeSharedInStory to check whether the message is suitable. - */ - public InputStoryAreaTypeMessage(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -266607529; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An area pointing to a HTTP or tg:// link. - */ - public static class InputStoryAreaTypeLink extends InputStoryAreaType { - /** - * HTTP or tg:// URL to be opened when the area is clicked. - */ - public String url; - - /** - * An area pointing to a HTTP or tg:// link. - */ - public InputStoryAreaTypeLink() { - } - - /** - * An area pointing to a HTTP or tg:// link. - * - * @param url HTTP or tg:// URL to be opened when the area is clicked. - */ - public InputStoryAreaTypeLink(String url) { - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1408441160; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An area with information about weather. - */ - public static class InputStoryAreaTypeWeather extends InputStoryAreaType { - /** - * Temperature, in degree Celsius. - */ - public double temperature; - /** - * Emoji representing the weather. - */ - public String emoji; - /** - * A color of the area background in the ARGB format. - */ - public int backgroundColor; - - /** - * An area with information about weather. - */ - public InputStoryAreaTypeWeather() { - } - - /** - * An area with information about weather. - * - * @param temperature Temperature, in degree Celsius. - * @param emoji Emoji representing the weather. - * @param backgroundColor A color of the area background in the ARGB format. - */ - public InputStoryAreaTypeWeather(double temperature, String emoji, int backgroundColor) { - this.temperature = temperature; - this.emoji = emoji; - this.backgroundColor = backgroundColor; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1212686691; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An area with an upgraded gift. - */ - public static class InputStoryAreaTypeUpgradedGift extends InputStoryAreaType { - /** - * Unique name of the upgraded gift. - */ - public String giftName; - - /** - * An area with an upgraded gift. - */ - public InputStoryAreaTypeUpgradedGift() { - } - - /** - * An area with an upgraded gift. - * - * @param giftName Unique name of the upgraded gift. - */ - public InputStoryAreaTypeUpgradedGift(String giftName) { - this.giftName = giftName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 793059694; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of story areas to be added. - */ - public static class InputStoryAreas extends Object { - /** - * List of input story areas. Currently, a story can have up to 10 inputStoryAreaTypeLocation, inputStoryAreaTypeFoundVenue, and inputStoryAreaTypePreviousVenue areas, up to getOption("story_suggested_reaction_area_count_max") inputStoryAreaTypeSuggestedReaction areas, up to 1 inputStoryAreaTypeMessage area, up to getOption("story_link_area_count_max") inputStoryAreaTypeLink areas if the current user is a Telegram Premium user, up to 3 inputStoryAreaTypeWeather areas, and up to 1 inputStoryAreaTypeUpgradedGift area. - */ - public InputStoryArea[] areas; - - /** - * Contains a list of story areas to be added. - */ - public InputStoryAreas() { - } - - /** - * Contains a list of story areas to be added. - * - * @param areas List of input story areas. Currently, a story can have up to 10 inputStoryAreaTypeLocation, inputStoryAreaTypeFoundVenue, and inputStoryAreaTypePreviousVenue areas, up to getOption("story_suggested_reaction_area_count_max") inputStoryAreaTypeSuggestedReaction areas, up to 1 inputStoryAreaTypeMessage area, up to getOption("story_link_area_count_max") inputStoryAreaTypeLink areas if the current user is a Telegram Premium user, up to 3 inputStoryAreaTypeWeather areas, and up to 1 inputStoryAreaTypeUpgradedGift area. - */ - public InputStoryAreas(InputStoryArea[] areas) { - this.areas = areas; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -883247088; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * The content of a story to post. - */ - public abstract static class InputStoryContent extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InputStoryContentPhoto.CONSTRUCTOR, - InputStoryContentVideo.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InputStoryContent() { - } - } - - /** - * A photo story. - */ - public static class InputStoryContentPhoto extends InputStoryContent { - /** - * Photo to send. The photo must be at most 10 MB in size. The photo size must be 1080x1920. - */ - public InputFile photo; - /** - * File identifiers of the stickers added to the photo, if applicable. - */ - public int[] addedStickerFileIds; - - /** - * A photo story. - */ - public InputStoryContentPhoto() { - } - - /** - * A photo story. - * - * @param photo Photo to send. The photo must be at most 10 MB in size. The photo size must be 1080x1920. - * @param addedStickerFileIds File identifiers of the stickers added to the photo, if applicable. - */ - public InputStoryContentPhoto(InputFile photo, int[] addedStickerFileIds) { - this.photo = photo; - this.addedStickerFileIds = addedStickerFileIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -309196727; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A video story. - */ - public static class InputStoryContentVideo extends InputStoryContent { - /** - * Video to be sent. The video size must be 720x1280. The video must be streamable and stored in MPEG4 format, after encoding with H.265 codec and key frames added each second. - */ - public InputFile video; - /** - * File identifiers of the stickers added to the video, if applicable. - */ - public int[] addedStickerFileIds; - /** - * Precise duration of the video, in seconds; 0-60. - */ - public double duration; - /** - * Timestamp of the frame, which will be used as video thumbnail. - */ - public double coverFrameTimestamp; - /** - * True, if the video has no sound. - */ - public boolean isAnimation; - - /** - * A video story. - */ - public InputStoryContentVideo() { - } - - /** - * A video story. - * - * @param video Video to be sent. The video size must be 720x1280. The video must be streamable and stored in MPEG4 format, after encoding with H.265 codec and key frames added each second. - * @param addedStickerFileIds File identifiers of the stickers added to the video, if applicable. - * @param duration Precise duration of the video, in seconds; 0-60. - * @param coverFrameTimestamp Timestamp of the frame, which will be used as video thumbnail. - * @param isAnimation True, if the video has no sound. - */ - public InputStoryContentVideo(InputFile video, int[] addedStickerFileIds, double duration, double coverFrameTimestamp, boolean isAnimation) { - this.video = video; - this.addedStickerFileIds = addedStickerFileIds; - this.duration = duration; - this.coverFrameTimestamp = coverFrameTimestamp; - this.isAnimation = isAnimation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 3809243; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a post to suggest. - */ - public static class InputSuggestedPostInfo extends Object { - /** - * Price of the suggested post; pass null to suggest a post without payment. If the current user isn't an administrator of the channel direct messages chat and has no enough funds to pay for the post, then the error "BALANCE_TOO_LOW" will be returned immediately. - */ - public SuggestedPostPrice price; - /** - * Point in time (Unix timestamp) when the post is expected to be published; pass 0 if the date isn't restricted. If specified, then the date must be getOption("suggested_post_send_delay_min")-getOption("suggested_post_send_delay_max") seconds in the future. - */ - public int sendDate; - - /** - * Contains information about a post to suggest. - */ - public InputSuggestedPostInfo() { - } - - /** - * Contains information about a post to suggest. - * - * @param price Price of the suggested post; pass null to suggest a post without payment. If the current user isn't an administrator of the channel direct messages chat and has no enough funds to pay for the post, then the error "BALANCE_TOO_LOW" will be returned immediately. - * @param sendDate Point in time (Unix timestamp) when the post is expected to be published; pass 0 if the date isn't restricted. If specified, then the date must be getOption("suggested_post_send_delay_min")-getOption("suggested_post_send_delay_max") seconds in the future. - */ - public InputSuggestedPostInfo(SuggestedPostPrice price, int sendDate) { - this.price = price; - this.sendDate = sendDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1246794382; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes manually chosen quote from another message. - */ - public static class InputTextQuote extends Object { - /** - * Text of the quote; 0-getOption("message_reply_quote_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed to be kept and must be kept in the quote. - */ - public FormattedText text; - /** - * Quote position in the original message in UTF-16 code units. - */ - public int position; - - /** - * Describes manually chosen quote from another message. - */ - public InputTextQuote() { - } - - /** - * Describes manually chosen quote from another message. - * - * @param text Text of the quote; 0-getOption("message_reply_quote_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed to be kept and must be kept in the quote. - * @param position Quote position in the original message in UTF-16 code units. - */ - public InputTextQuote(FormattedText text, int position) { - this.text = text; - this.position = position; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1219859172; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A thumbnail to be sent along with a file; must be in JPEG or WEBP format for stickers, and less than 200 KB in size. - */ - public static class InputThumbnail extends Object { - /** - * Thumbnail file to send. Sending thumbnails by fileId is currently not supported. - */ - public InputFile thumbnail; - /** - * Thumbnail width, usually shouldn't exceed 320. Use 0 if unknown. - */ - public int width; - /** - * Thumbnail height, usually shouldn't exceed 320. Use 0 if unknown. - */ - public int height; - - /** - * A thumbnail to be sent along with a file; must be in JPEG or WEBP format for stickers, and less than 200 KB in size. - */ - public InputThumbnail() { - } - - /** - * A thumbnail to be sent along with a file; must be in JPEG or WEBP format for stickers, and less than 200 KB in size. - * - * @param thumbnail Thumbnail file to send. Sending thumbnails by fileId is currently not supported. - * @param width Thumbnail width, usually shouldn't exceed 320. Use 0 if unknown. - * @param height Thumbnail height, usually shouldn't exceed 320. Use 0 if unknown. - */ - public InputThumbnail(InputFile thumbnail, int width, int height) { - this.thumbnail = thumbnail; - this.width = width; - this.height = height; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1582387236; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes an internal https://t.me or tg: link, which must be processed by the application in a special way. - */ - public abstract static class InternalLinkType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InternalLinkTypeAttachmentMenuBot.CONSTRUCTOR, - InternalLinkTypeAuthenticationCode.CONSTRUCTOR, - InternalLinkTypeBackground.CONSTRUCTOR, - InternalLinkTypeBotAddToChannel.CONSTRUCTOR, - InternalLinkTypeBotStart.CONSTRUCTOR, - InternalLinkTypeBotStartInGroup.CONSTRUCTOR, - InternalLinkTypeBusinessChat.CONSTRUCTOR, - InternalLinkTypeCallsPage.CONSTRUCTOR, - InternalLinkTypeChatAffiliateProgram.CONSTRUCTOR, - InternalLinkTypeChatBoost.CONSTRUCTOR, - InternalLinkTypeChatFolderInvite.CONSTRUCTOR, - InternalLinkTypeChatInvite.CONSTRUCTOR, - InternalLinkTypeChatSelection.CONSTRUCTOR, - InternalLinkTypeContactsPage.CONSTRUCTOR, - InternalLinkTypeDirectMessagesChat.CONSTRUCTOR, - InternalLinkTypeGame.CONSTRUCTOR, - InternalLinkTypeGiftAuction.CONSTRUCTOR, - InternalLinkTypeGiftCollection.CONSTRUCTOR, - InternalLinkTypeGroupCall.CONSTRUCTOR, - InternalLinkTypeInstantView.CONSTRUCTOR, - InternalLinkTypeInvoice.CONSTRUCTOR, - InternalLinkTypeLanguagePack.CONSTRUCTOR, - InternalLinkTypeLiveStory.CONSTRUCTOR, - InternalLinkTypeMainWebApp.CONSTRUCTOR, - InternalLinkTypeMessage.CONSTRUCTOR, - InternalLinkTypeMessageDraft.CONSTRUCTOR, - InternalLinkTypeMyProfilePage.CONSTRUCTOR, - InternalLinkTypeNewChannelChat.CONSTRUCTOR, - InternalLinkTypeNewGroupChat.CONSTRUCTOR, - InternalLinkTypeNewPrivateChat.CONSTRUCTOR, - InternalLinkTypeNewStory.CONSTRUCTOR, - InternalLinkTypeOauth.CONSTRUCTOR, - InternalLinkTypePassportDataRequest.CONSTRUCTOR, - InternalLinkTypePhoneNumberConfirmation.CONSTRUCTOR, - InternalLinkTypePremiumFeaturesPage.CONSTRUCTOR, - InternalLinkTypePremiumGiftCode.CONSTRUCTOR, - InternalLinkTypePremiumGiftPurchase.CONSTRUCTOR, - InternalLinkTypeProxy.CONSTRUCTOR, - InternalLinkTypePublicChat.CONSTRUCTOR, - InternalLinkTypeQrCodeAuthentication.CONSTRUCTOR, - InternalLinkTypeRestorePurchases.CONSTRUCTOR, - InternalLinkTypeSavedMessages.CONSTRUCTOR, - InternalLinkTypeSearch.CONSTRUCTOR, - InternalLinkTypeSettings.CONSTRUCTOR, - InternalLinkTypeStarPurchase.CONSTRUCTOR, - InternalLinkTypeStickerSet.CONSTRUCTOR, - InternalLinkTypeStory.CONSTRUCTOR, - InternalLinkTypeStoryAlbum.CONSTRUCTOR, - InternalLinkTypeTheme.CONSTRUCTOR, - InternalLinkTypeUnknownDeepLink.CONSTRUCTOR, - InternalLinkTypeUpgradedGift.CONSTRUCTOR, - InternalLinkTypeUserPhoneNumber.CONSTRUCTOR, - InternalLinkTypeUserToken.CONSTRUCTOR, - InternalLinkTypeVideoChat.CONSTRUCTOR, - InternalLinkTypeWebApp.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InternalLinkType() { - } - } - - /** - * The link is a link to an attachment menu bot to be opened in the specified or a chosen chat. Process given targetChat to open the chat. Then, call searchPublicChat with the given bot username, check that the user is a bot and can be added to attachment menu. Then, use getAttachmentMenuBot to receive information about the bot. If the bot isn't added to attachment menu, then show a disclaimer about Mini Apps being third-party applications, ask the user to accept their Terms of service and confirm adding the bot to side and attachment menu. If the user accept the terms and confirms adding, then use toggleBotIsAddedToAttachmentMenu to add the bot. If the attachment menu bot can't be used in the opened chat, show an error to the user. If the bot is added to attachment menu and can be used in the chat, then use openWebApp with the given URL. - */ - public static class InternalLinkTypeAttachmentMenuBot extends InternalLinkType { - /** - * Target chat to be opened. - */ - public TargetChat targetChat; - /** - * Username of the bot. - */ - public String botUsername; - /** - * URL to be passed to openWebApp. - */ - public String url; - - /** - * The link is a link to an attachment menu bot to be opened in the specified or a chosen chat. Process given targetChat to open the chat. Then, call searchPublicChat with the given bot username, check that the user is a bot and can be added to attachment menu. Then, use getAttachmentMenuBot to receive information about the bot. If the bot isn't added to attachment menu, then show a disclaimer about Mini Apps being third-party applications, ask the user to accept their Terms of service and confirm adding the bot to side and attachment menu. If the user accept the terms and confirms adding, then use toggleBotIsAddedToAttachmentMenu to add the bot. If the attachment menu bot can't be used in the opened chat, show an error to the user. If the bot is added to attachment menu and can be used in the chat, then use openWebApp with the given URL. - */ - public InternalLinkTypeAttachmentMenuBot() { - } - - /** - * The link is a link to an attachment menu bot to be opened in the specified or a chosen chat. Process given targetChat to open the chat. Then, call searchPublicChat with the given bot username, check that the user is a bot and can be added to attachment menu. Then, use getAttachmentMenuBot to receive information about the bot. If the bot isn't added to attachment menu, then show a disclaimer about Mini Apps being third-party applications, ask the user to accept their Terms of service and confirm adding the bot to side and attachment menu. If the user accept the terms and confirms adding, then use toggleBotIsAddedToAttachmentMenu to add the bot. If the attachment menu bot can't be used in the opened chat, show an error to the user. If the bot is added to attachment menu and can be used in the chat, then use openWebApp with the given URL. - * - * @param targetChat Target chat to be opened. - * @param botUsername Username of the bot. - * @param url URL to be passed to openWebApp. - */ - public InternalLinkTypeAttachmentMenuBot(TargetChat targetChat, String botUsername, String url) { - this.targetChat = targetChat; - this.botUsername = botUsername; - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1682719269; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link contains an authentication code. Call checkAuthenticationCode with the code if the current authorization state is authorizationStateWaitCode. - */ - public static class InternalLinkTypeAuthenticationCode extends InternalLinkType { - /** - * The authentication code. - */ - public String code; - - /** - * The link contains an authentication code. Call checkAuthenticationCode with the code if the current authorization state is authorizationStateWaitCode. - */ - public InternalLinkTypeAuthenticationCode() { - } - - /** - * The link contains an authentication code. Call checkAuthenticationCode with the code if the current authorization state is authorizationStateWaitCode. - * - * @param code The authentication code. - */ - public InternalLinkTypeAuthenticationCode(String code) { - this.code = code; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -209235982; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a background. Call searchBackground with the given background name to process the link. If background is found and the user wants to apply it, then call setDefaultBackground. - */ - public static class InternalLinkTypeBackground extends InternalLinkType { - /** - * Name of the background. - */ - public String backgroundName; - - /** - * The link is a link to a background. Call searchBackground with the given background name to process the link. If background is found and the user wants to apply it, then call setDefaultBackground. - */ - public InternalLinkTypeBackground() { - } - - /** - * The link is a link to a background. Call searchBackground with the given background name to process the link. If background is found and the user wants to apply it, then call setDefaultBackground. - * - * @param backgroundName Name of the background. - */ - public InternalLinkTypeBackground(String backgroundName) { - this.backgroundName = backgroundName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 185411848; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a Telegram bot, which is expected to be added to a channel chat as an administrator. Call searchPublicChat with the given bot username and check that the user is a bot, ask the current user to select a channel chat to add the bot to as an administrator. Then, call getChatMember to receive the current bot rights in the chat and if the bot already is an administrator, check that the current user can edit its administrator rights and combine received rights with the requested administrator rights. Then, show confirmation box to the user, and call setChatMemberStatus with the chosen chat and confirmed rights. - */ - public static class InternalLinkTypeBotAddToChannel extends InternalLinkType { - /** - * Username of the bot. - */ - public String botUsername; - /** - * Expected administrator rights for the bot. - */ - public ChatAdministratorRights administratorRights; - - /** - * The link is a link to a Telegram bot, which is expected to be added to a channel chat as an administrator. Call searchPublicChat with the given bot username and check that the user is a bot, ask the current user to select a channel chat to add the bot to as an administrator. Then, call getChatMember to receive the current bot rights in the chat and if the bot already is an administrator, check that the current user can edit its administrator rights and combine received rights with the requested administrator rights. Then, show confirmation box to the user, and call setChatMemberStatus with the chosen chat and confirmed rights. - */ - public InternalLinkTypeBotAddToChannel() { - } - - /** - * The link is a link to a Telegram bot, which is expected to be added to a channel chat as an administrator. Call searchPublicChat with the given bot username and check that the user is a bot, ask the current user to select a channel chat to add the bot to as an administrator. Then, call getChatMember to receive the current bot rights in the chat and if the bot already is an administrator, check that the current user can edit its administrator rights and combine received rights with the requested administrator rights. Then, show confirmation box to the user, and call setChatMemberStatus with the chosen chat and confirmed rights. - * - * @param botUsername Username of the bot. - * @param administratorRights Expected administrator rights for the bot. - */ - public InternalLinkTypeBotAddToChannel(String botUsername, ChatAdministratorRights administratorRights) { - this.botUsername = botUsername; - this.administratorRights = administratorRights; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1401602752; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a chat with a Telegram bot. Call searchPublicChat with the given bot username, check that the user is a bot, show START button in the chat with the bot, and then call sendBotStartMessage with the given start parameter after the button is pressed. - */ - public static class InternalLinkTypeBotStart extends InternalLinkType { - /** - * Username of the bot. - */ - public String botUsername; - /** - * The parameter to be passed to sendBotStartMessage. - */ - public String startParameter; - /** - * True, if sendBotStartMessage must be called automatically without showing the START button. - */ - public boolean autostart; - - /** - * The link is a link to a chat with a Telegram bot. Call searchPublicChat with the given bot username, check that the user is a bot, show START button in the chat with the bot, and then call sendBotStartMessage with the given start parameter after the button is pressed. - */ - public InternalLinkTypeBotStart() { - } - - /** - * The link is a link to a chat with a Telegram bot. Call searchPublicChat with the given bot username, check that the user is a bot, show START button in the chat with the bot, and then call sendBotStartMessage with the given start parameter after the button is pressed. - * - * @param botUsername Username of the bot. - * @param startParameter The parameter to be passed to sendBotStartMessage. - * @param autostart True, if sendBotStartMessage must be called automatically without showing the START button. - */ - public InternalLinkTypeBotStart(String botUsername, String startParameter, boolean autostart) { - this.botUsername = botUsername; - this.startParameter = startParameter; - this.autostart = autostart; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1066950637; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a Telegram bot, which is expected to be added to a group chat. Call searchPublicChat with the given bot username, check that the user is a bot and can be added to groups, ask the current user to select a basic group or a supergroup chat to add the bot to, taking into account that bots can be added to a public supergroup only by administrators of the supergroup. If administrator rights are provided by the link, call getChatMember to receive the current bot rights in the chat and if the bot already is an administrator, check that the current user can edit its administrator rights, combine received rights with the requested administrator rights, show confirmation box to the user, and call setChatMemberStatus with the chosen chat and confirmed administrator rights. Before call to setChatMemberStatus it may be required to upgrade the chosen basic group chat to a supergroup chat. Then, if startParameter isn't empty, call sendBotStartMessage with the given start parameter and the chosen chat; otherwise, just send /start message with bot's username added to the chat. - */ - public static class InternalLinkTypeBotStartInGroup extends InternalLinkType { - /** - * Username of the bot. - */ - public String botUsername; - /** - * The parameter to be passed to sendBotStartMessage. - */ - public String startParameter; - /** - * Expected administrator rights for the bot; may be null. - */ - @Nullable public ChatAdministratorRights administratorRights; - - /** - * The link is a link to a Telegram bot, which is expected to be added to a group chat. Call searchPublicChat with the given bot username, check that the user is a bot and can be added to groups, ask the current user to select a basic group or a supergroup chat to add the bot to, taking into account that bots can be added to a public supergroup only by administrators of the supergroup. If administrator rights are provided by the link, call getChatMember to receive the current bot rights in the chat and if the bot already is an administrator, check that the current user can edit its administrator rights, combine received rights with the requested administrator rights, show confirmation box to the user, and call setChatMemberStatus with the chosen chat and confirmed administrator rights. Before call to setChatMemberStatus it may be required to upgrade the chosen basic group chat to a supergroup chat. Then, if startParameter isn't empty, call sendBotStartMessage with the given start parameter and the chosen chat; otherwise, just send /start message with bot's username added to the chat. - */ - public InternalLinkTypeBotStartInGroup() { - } - - /** - * The link is a link to a Telegram bot, which is expected to be added to a group chat. Call searchPublicChat with the given bot username, check that the user is a bot and can be added to groups, ask the current user to select a basic group or a supergroup chat to add the bot to, taking into account that bots can be added to a public supergroup only by administrators of the supergroup. If administrator rights are provided by the link, call getChatMember to receive the current bot rights in the chat and if the bot already is an administrator, check that the current user can edit its administrator rights, combine received rights with the requested administrator rights, show confirmation box to the user, and call setChatMemberStatus with the chosen chat and confirmed administrator rights. Before call to setChatMemberStatus it may be required to upgrade the chosen basic group chat to a supergroup chat. Then, if startParameter isn't empty, call sendBotStartMessage with the given start parameter and the chosen chat; otherwise, just send /start message with bot's username added to the chat. - * - * @param botUsername Username of the bot. - * @param startParameter The parameter to be passed to sendBotStartMessage. - * @param administratorRights Expected administrator rights for the bot; may be null. - */ - public InternalLinkTypeBotStartInGroup(String botUsername, String startParameter, ChatAdministratorRights administratorRights) { - this.botUsername = botUsername; - this.startParameter = startParameter; - this.administratorRights = administratorRights; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -905081650; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a business chat. Use getBusinessChatLinkInfo with the provided link name to get information about the link, then open received private chat and replace chat draft with the provided text. - */ - public static class InternalLinkTypeBusinessChat extends InternalLinkType { - /** - * Name of the link. - */ - public String linkName; - - /** - * The link is a link to a business chat. Use getBusinessChatLinkInfo with the provided link name to get information about the link, then open received private chat and replace chat draft with the provided text. - */ - public InternalLinkTypeBusinessChat() { - } - - /** - * The link is a link to a business chat. Use getBusinessChatLinkInfo with the provided link name to get information about the link, then open received private chat and replace chat draft with the provided text. - * - * @param linkName Name of the link. - */ - public InternalLinkTypeBusinessChat(String linkName) { - this.linkName = linkName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1606751785; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to the Call tab or page. - */ - public static class InternalLinkTypeCallsPage extends InternalLinkType { - /** - * Section of the page; may be one of "", "all", "missed", "edit", "show-tab", "start-call". - */ - public String section; - - /** - * The link is a link to the Call tab or page. - */ - public InternalLinkTypeCallsPage() { - } - - /** - * The link is a link to the Call tab or page. - * - * @param section Section of the page; may be one of "", "all", "missed", "edit", "show-tab", "start-call". - */ - public InternalLinkTypeCallsPage(String section) { - this.section = section; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -718405184; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is an affiliate program link. Call searchChatAffiliateProgram with the given username and referrer to process the link. - */ - public static class InternalLinkTypeChatAffiliateProgram extends InternalLinkType { - /** - * Username to be passed to searchChatAffiliateProgram. - */ - public String username; - /** - * Referrer to be passed to searchChatAffiliateProgram. - */ - public String referrer; - - /** - * The link is an affiliate program link. Call searchChatAffiliateProgram with the given username and referrer to process the link. - */ - public InternalLinkTypeChatAffiliateProgram() { - } - - /** - * The link is an affiliate program link. Call searchChatAffiliateProgram with the given username and referrer to process the link. - * - * @param username Username to be passed to searchChatAffiliateProgram. - * @param referrer Referrer to be passed to searchChatAffiliateProgram. - */ - public InternalLinkTypeChatAffiliateProgram(String username, String referrer) { - this.username = username; - this.referrer = referrer; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 632049700; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to boost a Telegram chat. Call getChatBoostLinkInfo with the given URL to process the link. If the chat is found, then call getChatBoostStatus and getAvailableChatBoostSlots to get the current boost status and check whether the chat can be boosted. If the user wants to boost the chat and the chat can be boosted, then call boostChat. - */ - public static class InternalLinkTypeChatBoost extends InternalLinkType { - /** - * URL to be passed to getChatBoostLinkInfo. - */ - public String url; - - /** - * The link is a link to boost a Telegram chat. Call getChatBoostLinkInfo with the given URL to process the link. If the chat is found, then call getChatBoostStatus and getAvailableChatBoostSlots to get the current boost status and check whether the chat can be boosted. If the user wants to boost the chat and the chat can be boosted, then call boostChat. - */ - public InternalLinkTypeChatBoost() { - } - - /** - * The link is a link to boost a Telegram chat. Call getChatBoostLinkInfo with the given URL to process the link. If the chat is found, then call getChatBoostStatus and getAvailableChatBoostSlots to get the current boost status and check whether the chat can be boosted. If the user wants to boost the chat and the chat can be boosted, then call boostChat. - * - * @param url URL to be passed to getChatBoostLinkInfo. - */ - public InternalLinkTypeChatBoost(String url) { - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -716571328; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is an invite link to a chat folder. Call checkChatFolderInviteLink with the given invite link to process the link. If the link is valid and the user wants to join the chat folder, then call addChatFolderByInviteLink. - */ - public static class InternalLinkTypeChatFolderInvite extends InternalLinkType { - /** - * Internal representation of the invite link. - */ - public String inviteLink; - - /** - * The link is an invite link to a chat folder. Call checkChatFolderInviteLink with the given invite link to process the link. If the link is valid and the user wants to join the chat folder, then call addChatFolderByInviteLink. - */ - public InternalLinkTypeChatFolderInvite() { - } - - /** - * The link is an invite link to a chat folder. Call checkChatFolderInviteLink with the given invite link to process the link. If the link is valid and the user wants to join the chat folder, then call addChatFolderByInviteLink. - * - * @param inviteLink Internal representation of the invite link. - */ - public InternalLinkTypeChatFolderInvite(String inviteLink) { - this.inviteLink = inviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1984804546; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a chat invite link. Call checkChatInviteLink with the given invite link to process the link. If the link is valid and the user wants to join the chat, then call joinChatByInviteLink. - */ - public static class InternalLinkTypeChatInvite extends InternalLinkType { - /** - * Internal representation of the invite link. - */ - public String inviteLink; - - /** - * The link is a chat invite link. Call checkChatInviteLink with the given invite link to process the link. If the link is valid and the user wants to join the chat, then call joinChatByInviteLink. - */ - public InternalLinkTypeChatInvite() { - } - - /** - * The link is a chat invite link. Call checkChatInviteLink with the given invite link to process the link. If the link is valid and the user wants to join the chat, then call joinChatByInviteLink. - * - * @param inviteLink Internal representation of the invite link. - */ - public InternalLinkTypeChatInvite(String inviteLink) { - this.inviteLink = inviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 428621017; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link that allows to select some chats. - */ - public static class InternalLinkTypeChatSelection extends InternalLinkType { - - /** - * The link is a link that allows to select some chats. - */ - public InternalLinkTypeChatSelection() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 621470813; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to the Contacts tab or page. - */ - public static class InternalLinkTypeContactsPage extends InternalLinkType { - /** - * Section of the page; may be one of "", "search", "sort", "new", "invite", "manage". - */ - public String section; - - /** - * The link is a link to the Contacts tab or page. - */ - public InternalLinkTypeContactsPage() { - } - - /** - * The link is a link to the Contacts tab or page. - * - * @param section Section of the page; may be one of "", "search", "sort", "new", "invite", "manage". - */ - public InternalLinkTypeContactsPage(String section) { - this.section = section; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 412195917; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a channel direct messages chat by username of the channel. Call searchPublicChat with the given chat username to process the link. If the chat is found and is channel, open the direct messages chat of the channel. - */ - public static class InternalLinkTypeDirectMessagesChat extends InternalLinkType { - /** - * Username of the channel. - */ - public String channelUsername; - - /** - * The link is a link to a channel direct messages chat by username of the channel. Call searchPublicChat with the given chat username to process the link. If the chat is found and is channel, open the direct messages chat of the channel. - */ - public InternalLinkTypeDirectMessagesChat() { - } - - /** - * The link is a link to a channel direct messages chat by username of the channel. Call searchPublicChat with the given chat username to process the link. If the chat is found and is channel, open the direct messages chat of the channel. - * - * @param channelUsername Username of the channel. - */ - public InternalLinkTypeDirectMessagesChat(String channelUsername) { - this.channelUsername = channelUsername; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1795016752; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a game. Call searchPublicChat with the given bot username, check that the user is a bot, ask the current user to select a chat to send the game, and then call sendMessage with inputMessageGame. - */ - public static class InternalLinkTypeGame extends InternalLinkType { - /** - * Username of the bot that owns the game. - */ - public String botUsername; - /** - * Short name of the game. - */ - public String gameShortName; - - /** - * The link is a link to a game. Call searchPublicChat with the given bot username, check that the user is a bot, ask the current user to select a chat to send the game, and then call sendMessage with inputMessageGame. - */ - public InternalLinkTypeGame() { - } - - /** - * The link is a link to a game. Call searchPublicChat with the given bot username, check that the user is a bot, ask the current user to select a chat to send the game, and then call sendMessage with inputMessageGame. - * - * @param botUsername Username of the bot that owns the game. - * @param gameShortName Short name of the game. - */ - public InternalLinkTypeGame(String botUsername, String gameShortName) { - this.botUsername = botUsername; - this.gameShortName = gameShortName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -260788787; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a gift auction. Call getGiftAuctionState with the given auction identifier to process the link. - */ - public static class InternalLinkTypeGiftAuction extends InternalLinkType { - /** - * Unique identifier of the auction. - */ - public String auctionId; - - /** - * The link is a link to a gift auction. Call getGiftAuctionState with the given auction identifier to process the link. - */ - public InternalLinkTypeGiftAuction() { - } - - /** - * The link is a link to a gift auction. Call getGiftAuctionState with the given auction identifier to process the link. - * - * @param auctionId Unique identifier of the auction. - */ - public InternalLinkTypeGiftAuction(String auctionId) { - this.auctionId = auctionId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1724902818; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a gift collection. Call searchPublicChat with the given username, then call getReceivedGifts with the received gift owner identifier and the given collection identifier, then show the collection if received. - */ - public static class InternalLinkTypeGiftCollection extends InternalLinkType { - /** - * Username of the owner of the gift collection. - */ - public String giftOwnerUsername; - /** - * Gift collection identifier. - */ - public int collectionId; - - /** - * The link is a link to a gift collection. Call searchPublicChat with the given username, then call getReceivedGifts with the received gift owner identifier and the given collection identifier, then show the collection if received. - */ - public InternalLinkTypeGiftCollection() { - } - - /** - * The link is a link to a gift collection. Call searchPublicChat with the given username, then call getReceivedGifts with the received gift owner identifier and the given collection identifier, then show the collection if received. - * - * @param giftOwnerUsername Username of the owner of the gift collection. - * @param collectionId Gift collection identifier. - */ - public InternalLinkTypeGiftCollection(String giftOwnerUsername, int collectionId) { - this.giftOwnerUsername = giftOwnerUsername; - this.collectionId = collectionId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -812480347; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a group call that isn't bound to a chat. Use getGroupCallParticipants to get the list of group call participants and show them on the join group call screen. Call joinGroupCall with the given inviteLink to join the call. - */ - public static class InternalLinkTypeGroupCall extends InternalLinkType { - /** - * Internal representation of the invite link. - */ - public String inviteLink; - - /** - * The link is a link to a group call that isn't bound to a chat. Use getGroupCallParticipants to get the list of group call participants and show them on the join group call screen. Call joinGroupCall with the given inviteLink to join the call. - */ - public InternalLinkTypeGroupCall() { - } - - /** - * The link is a link to a group call that isn't bound to a chat. Use getGroupCallParticipants to get the list of group call participants and show them on the join group call screen. Call joinGroupCall with the given inviteLink to join the call. - * - * @param inviteLink Internal representation of the invite link. - */ - public InternalLinkTypeGroupCall(String inviteLink) { - this.inviteLink = inviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1953084438; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link must be opened in an Instant View. Call getWebPageInstantView with the given URL to process the link. If Instant View is found, then show it, otherwise, open the fallback URL in an external browser. - */ - public static class InternalLinkTypeInstantView extends InternalLinkType { - /** - * URL to be passed to getWebPageInstantView. - */ - public String url; - /** - * An URL to open if getWebPageInstantView fails. - */ - public String fallbackUrl; - - /** - * The link must be opened in an Instant View. Call getWebPageInstantView with the given URL to process the link. If Instant View is found, then show it, otherwise, open the fallback URL in an external browser. - */ - public InternalLinkTypeInstantView() { - } - - /** - * The link must be opened in an Instant View. Call getWebPageInstantView with the given URL to process the link. If Instant View is found, then show it, otherwise, open the fallback URL in an external browser. - * - * @param url URL to be passed to getWebPageInstantView. - * @param fallbackUrl An URL to open if getWebPageInstantView fails. - */ - public InternalLinkTypeInstantView(String url, String fallbackUrl) { - this.url = url; - this.fallbackUrl = fallbackUrl; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1776607039; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to an invoice. Call getPaymentForm with the given invoice name to process the link. - */ - public static class InternalLinkTypeInvoice extends InternalLinkType { - /** - * Name of the invoice. - */ - public String invoiceName; - - /** - * The link is a link to an invoice. Call getPaymentForm with the given invoice name to process the link. - */ - public InternalLinkTypeInvoice() { - } - - /** - * The link is a link to an invoice. Call getPaymentForm with the given invoice name to process the link. - * - * @param invoiceName Name of the invoice. - */ - public InternalLinkTypeInvoice(String invoiceName) { - this.invoiceName = invoiceName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -213094996; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a language pack. Call getLanguagePackInfo with the given language pack identifier to process the link. If the language pack is found and the user wants to apply it, then call setOption for the option "language_pack_id". - */ - public static class InternalLinkTypeLanguagePack extends InternalLinkType { - /** - * Language pack identifier. - */ - public String languagePackId; - - /** - * The link is a link to a language pack. Call getLanguagePackInfo with the given language pack identifier to process the link. If the language pack is found and the user wants to apply it, then call setOption for the option "language_pack_id". - */ - public InternalLinkTypeLanguagePack() { - } - - /** - * The link is a link to a language pack. Call getLanguagePackInfo with the given language pack identifier to process the link. If the language pack is found and the user wants to apply it, then call setOption for the option "language_pack_id". - * - * @param languagePackId Language pack identifier. - */ - public InternalLinkTypeLanguagePack(String languagePackId) { - this.languagePackId = languagePackId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1450766996; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a live story. Call searchPublicChat with the given chat username, then getChatActiveStories to get active stories in the chat, then find a live story among active stories of the chat, and then joinLiveStory to join the live story. - */ - public static class InternalLinkTypeLiveStory extends InternalLinkType { - /** - * Username of the poster of the story. - */ - public String storyPosterUsername; - - /** - * The link is a link to a live story. Call searchPublicChat with the given chat username, then getChatActiveStories to get active stories in the chat, then find a live story among active stories of the chat, and then joinLiveStory to join the live story. - */ - public InternalLinkTypeLiveStory() { - } - - /** - * The link is a link to a live story. Call searchPublicChat with the given chat username, then getChatActiveStories to get active stories in the chat, then find a live story among active stories of the chat, and then joinLiveStory to join the live story. - * - * @param storyPosterUsername Username of the poster of the story. - */ - public InternalLinkTypeLiveStory(String storyPosterUsername) { - this.storyPosterUsername = storyPosterUsername; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 665614717; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to the main Web App of a bot. Call searchPublicChat with the given bot username, check that the user is a bot and has the main Web App. If the bot can be added to attachment menu, then use getAttachmentMenuBot to receive information about the bot, then if the bot isn't added to side menu, show a disclaimer about Mini Apps being third-party applications, ask the user to accept their Terms of service and confirm adding the bot to side and attachment menu, then if the user accepts the terms and confirms adding, use toggleBotIsAddedToAttachmentMenu to add the bot. Then, use getMainWebApp with the given start parameter and mode and open the returned URL as a Web App. - */ - public static class InternalLinkTypeMainWebApp extends InternalLinkType { - /** - * Username of the bot. - */ - public String botUsername; - /** - * Start parameter to be passed to getMainWebApp. - */ - public String startParameter; - /** - * The mode to be passed to getMainWebApp. - */ - public WebAppOpenMode mode; - - /** - * The link is a link to the main Web App of a bot. Call searchPublicChat with the given bot username, check that the user is a bot and has the main Web App. If the bot can be added to attachment menu, then use getAttachmentMenuBot to receive information about the bot, then if the bot isn't added to side menu, show a disclaimer about Mini Apps being third-party applications, ask the user to accept their Terms of service and confirm adding the bot to side and attachment menu, then if the user accepts the terms and confirms adding, use toggleBotIsAddedToAttachmentMenu to add the bot. Then, use getMainWebApp with the given start parameter and mode and open the returned URL as a Web App. - */ - public InternalLinkTypeMainWebApp() { - } - - /** - * The link is a link to the main Web App of a bot. Call searchPublicChat with the given bot username, check that the user is a bot and has the main Web App. If the bot can be added to attachment menu, then use getAttachmentMenuBot to receive information about the bot, then if the bot isn't added to side menu, show a disclaimer about Mini Apps being third-party applications, ask the user to accept their Terms of service and confirm adding the bot to side and attachment menu, then if the user accepts the terms and confirms adding, use toggleBotIsAddedToAttachmentMenu to add the bot. Then, use getMainWebApp with the given start parameter and mode and open the returned URL as a Web App. - * - * @param botUsername Username of the bot. - * @param startParameter Start parameter to be passed to getMainWebApp. - * @param mode The mode to be passed to getMainWebApp. - */ - public InternalLinkTypeMainWebApp(String botUsername, String startParameter, WebAppOpenMode mode) { - this.botUsername = botUsername; - this.startParameter = startParameter; - this.mode = mode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1574925033; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a Telegram message or a forum topic. Call getMessageLinkInfo with the given URL to process the link, and then open received forum topic or chat and show the message there. - */ - public static class InternalLinkTypeMessage extends InternalLinkType { - /** - * URL to be passed to getMessageLinkInfo. - */ - public String url; - - /** - * The link is a link to a Telegram message or a forum topic. Call getMessageLinkInfo with the given URL to process the link, and then open received forum topic or chat and show the message there. - */ - public InternalLinkTypeMessage() { - } - - /** - * The link is a link to a Telegram message or a forum topic. Call getMessageLinkInfo with the given URL to process the link, and then open received forum topic or chat and show the message there. - * - * @param url URL to be passed to getMessageLinkInfo. - */ - public InternalLinkTypeMessage(String url) { - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 978541650; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link contains a message draft text. A share screen needs to be shown to the user, then the chosen chat must be opened and the text is added to the input field. - */ - public static class InternalLinkTypeMessageDraft extends InternalLinkType { - /** - * Message draft text. - */ - public FormattedText text; - /** - * True, if the first line of the text contains a link. If true, the input field needs to be focused and the text after the link must be selected. - */ - public boolean containsLink; - - /** - * The link contains a message draft text. A share screen needs to be shown to the user, then the chosen chat must be opened and the text is added to the input field. - */ - public InternalLinkTypeMessageDraft() { - } - - /** - * The link contains a message draft text. A share screen needs to be shown to the user, then the chosen chat must be opened and the text is added to the input field. - * - * @param text Message draft text. - * @param containsLink True, if the first line of the text contains a link. If true, the input field needs to be focused and the text after the link must be selected. - */ - public InternalLinkTypeMessageDraft(FormattedText text, boolean containsLink) { - this.text = text; - this.containsLink = containsLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 661633749; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to the My Profile application page. - */ - public static class InternalLinkTypeMyProfilePage extends InternalLinkType { - /** - * Section of the page; may be one of "", "posts", "posts/all-stories", "posts/add-album", "gifts", "archived-posts". - */ - public String section; - - /** - * The link is a link to the My Profile application page. - */ - public InternalLinkTypeMyProfilePage() { - } - - /** - * The link is a link to the My Profile application page. - * - * @param section Section of the page; may be one of "", "posts", "posts/all-stories", "posts/add-album", "gifts", "archived-posts". - */ - public InternalLinkTypeMyProfilePage(String section) { - this.section = section; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1204697133; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to the screen for creating a new channel chat. - */ - public static class InternalLinkTypeNewChannelChat extends InternalLinkType { - - /** - * The link is a link to the screen for creating a new channel chat. - */ - public InternalLinkTypeNewChannelChat() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -660273891; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to the screen for creating a new group chat. - */ - public static class InternalLinkTypeNewGroupChat extends InternalLinkType { - - /** - * The link is a link to the screen for creating a new group chat. - */ - public InternalLinkTypeNewGroupChat() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -353196057; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to the screen for creating a new private chat with a contact. - */ - public static class InternalLinkTypeNewPrivateChat extends InternalLinkType { - - /** - * The link is a link to the screen for creating a new private chat with a contact. - */ - public InternalLinkTypeNewPrivateChat() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1326134340; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to open the story posting interface. - */ - public static class InternalLinkTypeNewStory extends InternalLinkType { - /** - * The type of the content of the story to post; may be null if unspecified. - */ - @Nullable public StoryContentType contentType; - - /** - * The link is a link to open the story posting interface. - */ - public InternalLinkTypeNewStory() { - } - - /** - * The link is a link to open the story posting interface. - * - * @param contentType The type of the content of the story to post; may be null if unspecified. - */ - public InternalLinkTypeNewStory(StoryContentType contentType) { - this.contentType = contentType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1637792663; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is an OAuth link. Call getOauthLinkInfo with the given URL to process the link if the link was received from outside of the application; otherwise, ignore it. After getOauthLinkInfo, show the user confirmation dialog and process it with checkOauthRequestMatchCode, acceptOauthRequest or declineOauthRequest. - */ - public static class InternalLinkTypeOauth extends InternalLinkType { - /** - * URL to be passed to getOauthLinkInfo. - */ - public String url; - - /** - * The link is an OAuth link. Call getOauthLinkInfo with the given URL to process the link if the link was received from outside of the application; otherwise, ignore it. After getOauthLinkInfo, show the user confirmation dialog and process it with checkOauthRequestMatchCode, acceptOauthRequest or declineOauthRequest. - */ - public InternalLinkTypeOauth() { - } - - /** - * The link is an OAuth link. Call getOauthLinkInfo with the given URL to process the link if the link was received from outside of the application; otherwise, ignore it. After getOauthLinkInfo, show the user confirmation dialog and process it with checkOauthRequestMatchCode, acceptOauthRequest or declineOauthRequest. - * - * @param url URL to be passed to getOauthLinkInfo. - */ - public InternalLinkTypeOauth(String url) { - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 263255628; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link contains a request of Telegram passport data. Call getPassportAuthorizationForm with the given parameters to process the link if the link was received from outside of the application; otherwise, ignore it. - */ - public static class InternalLinkTypePassportDataRequest extends InternalLinkType { - /** - * User identifier of the service's bot; the corresponding user may be unknown yet. - */ - public long botUserId; - /** - * Telegram Passport element types requested by the service. - */ - public String scope; - /** - * Service's public key. - */ - public String publicKey; - /** - * Unique request identifier provided by the service. - */ - public String nonce; - /** - * An HTTP URL to open once the request is finished, canceled, or failed with the parameters tgPassport=success, tgPassport=cancel, or tgPassport=error&error=... respectively. If empty, then onActivityResult method must be used to return response on Android, or the link tgbot{botUserId}://passport/success or tgbot{botUserId}://passport/cancel must be opened otherwise. - */ - public String callbackUrl; - - /** - * The link contains a request of Telegram passport data. Call getPassportAuthorizationForm with the given parameters to process the link if the link was received from outside of the application; otherwise, ignore it. - */ - public InternalLinkTypePassportDataRequest() { - } - - /** - * The link contains a request of Telegram passport data. Call getPassportAuthorizationForm with the given parameters to process the link if the link was received from outside of the application; otherwise, ignore it. - * - * @param botUserId User identifier of the service's bot; the corresponding user may be unknown yet. - * @param scope Telegram Passport element types requested by the service. - * @param publicKey Service's public key. - * @param nonce Unique request identifier provided by the service. - * @param callbackUrl An HTTP URL to open once the request is finished, canceled, or failed with the parameters tgPassport=success, tgPassport=cancel, or tgPassport=error&error=... respectively. If empty, then onActivityResult method must be used to return response on Android, or the link tgbot{botUserId}://passport/success or tgbot{botUserId}://passport/cancel must be opened otherwise. - */ - public InternalLinkTypePassportDataRequest(long botUserId, String scope, String publicKey, String nonce, String callbackUrl) { - this.botUserId = botUserId; - this.scope = scope; - this.publicKey = publicKey; - this.nonce = nonce; - this.callbackUrl = callbackUrl; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -988819839; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link can be used to confirm ownership of a phone number to prevent account deletion. Call sendPhoneNumberCode with the given phone number and with phoneNumberCodeTypeConfirmOwnership with the given hash to process the link. If succeeded, call checkPhoneNumberCode to check entered by the user code, or resendPhoneNumberCode to resend it. - */ - public static class InternalLinkTypePhoneNumberConfirmation extends InternalLinkType { - /** - * Hash value from the link. - */ - public String hash; - /** - * Phone number value from the link. - */ - public String phoneNumber; - - /** - * The link can be used to confirm ownership of a phone number to prevent account deletion. Call sendPhoneNumberCode with the given phone number and with phoneNumberCodeTypeConfirmOwnership with the given hash to process the link. If succeeded, call checkPhoneNumberCode to check entered by the user code, or resendPhoneNumberCode to resend it. - */ - public InternalLinkTypePhoneNumberConfirmation() { - } - - /** - * The link can be used to confirm ownership of a phone number to prevent account deletion. Call sendPhoneNumberCode with the given phone number and with phoneNumberCodeTypeConfirmOwnership with the given hash to process the link. If succeeded, call checkPhoneNumberCode to check entered by the user code, or resendPhoneNumberCode to resend it. - * - * @param hash Hash value from the link. - * @param phoneNumber Phone number value from the link. - */ - public InternalLinkTypePhoneNumberConfirmation(String hash, String phoneNumber) { - this.hash = hash; - this.phoneNumber = phoneNumber; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1757375254; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to the Premium features screen of the application from which the user can subscribe to Telegram Premium. Call getPremiumFeatures with the given referrer to process the link. - */ - public static class InternalLinkTypePremiumFeaturesPage extends InternalLinkType { - /** - * Referrer specified in the link. - */ - public String referrer; - - /** - * The link is a link to the Premium features screen of the application from which the user can subscribe to Telegram Premium. Call getPremiumFeatures with the given referrer to process the link. - */ - public InternalLinkTypePremiumFeaturesPage() { - } - - /** - * The link is a link to the Premium features screen of the application from which the user can subscribe to Telegram Premium. Call getPremiumFeatures with the given referrer to process the link. - * - * @param referrer Referrer specified in the link. - */ - public InternalLinkTypePremiumFeaturesPage(String referrer) { - this.referrer = referrer; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -626346401; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link with a Telegram Premium gift code. Call checkPremiumGiftCode with the given code to process the link. If the code is valid and the user wants to apply it, then call applyPremiumGiftCode. - */ - public static class InternalLinkTypePremiumGiftCode extends InternalLinkType { - /** - * The Telegram Premium gift code. - */ - public String code; - - /** - * The link is a link with a Telegram Premium gift code. Call checkPremiumGiftCode with the given code to process the link. If the code is valid and the user wants to apply it, then call applyPremiumGiftCode. - */ - public InternalLinkTypePremiumGiftCode() { - } - - /** - * The link is a link with a Telegram Premium gift code. Call checkPremiumGiftCode with the given code to process the link. If the code is valid and the user wants to apply it, then call applyPremiumGiftCode. - * - * @param code The Telegram Premium gift code. - */ - public InternalLinkTypePremiumGiftCode(String code) { - this.code = code; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -564356974; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to the screen for gifting Telegram Premium subscriptions to friends via inputInvoiceTelegram with telegramPaymentPurposePremiumGift payments or in-store purchases. - */ - public static class InternalLinkTypePremiumGiftPurchase extends InternalLinkType { - /** - * Referrer specified in the link. - */ - public String referrer; - - /** - * The link is a link to the screen for gifting Telegram Premium subscriptions to friends via inputInvoiceTelegram with telegramPaymentPurposePremiumGift payments or in-store purchases. - */ - public InternalLinkTypePremiumGiftPurchase() { - } - - /** - * The link is a link to the screen for gifting Telegram Premium subscriptions to friends via inputInvoiceTelegram with telegramPaymentPurposePremiumGift payments or in-store purchases. - * - * @param referrer Referrer specified in the link. - */ - public InternalLinkTypePremiumGiftPurchase(String referrer) { - this.referrer = referrer; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -947456567; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a proxy. Call addProxy with the given parameters to process the link and add the proxy. - */ - public static class InternalLinkTypeProxy extends InternalLinkType { - /** - * The proxy; may be null if the proxy is unsupported, in which case an alert can be shown to the user. - */ - @Nullable public Proxy proxy; - - /** - * The link is a link to a proxy. Call addProxy with the given parameters to process the link and add the proxy. - */ - public InternalLinkTypeProxy() { - } - - /** - * The link is a link to a proxy. Call addProxy with the given parameters to process the link and add the proxy. - * - * @param proxy The proxy; may be null if the proxy is unsupported, in which case an alert can be shown to the user. - */ - public InternalLinkTypeProxy(Proxy proxy) { - this.proxy = proxy; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1592321116; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a chat by its username. Call searchPublicChat with the given chat username to process the link. If the chat is found, open its profile information screen or the chat itself. If draft text isn't empty and the chat is a private chat with a regular user, then put the draft text in the input field. - */ - public static class InternalLinkTypePublicChat extends InternalLinkType { - /** - * Username of the chat. - */ - public String chatUsername; - /** - * Draft text for message to send in the chat. - */ - public String draftText; - /** - * True, if chat profile information screen must be opened; otherwise, the chat itself must be opened. - */ - public boolean openProfile; - - /** - * The link is a link to a chat by its username. Call searchPublicChat with the given chat username to process the link. If the chat is found, open its profile information screen or the chat itself. If draft text isn't empty and the chat is a private chat with a regular user, then put the draft text in the input field. - */ - public InternalLinkTypePublicChat() { - } - - /** - * The link is a link to a chat by its username. Call searchPublicChat with the given chat username to process the link. If the chat is found, open its profile information screen or the chat itself. If draft text isn't empty and the chat is a private chat with a regular user, then put the draft text in the input field. - * - * @param chatUsername Username of the chat. - * @param draftText Draft text for message to send in the chat. - * @param openProfile True, if chat profile information screen must be opened; otherwise, the chat itself must be opened. - */ - public InternalLinkTypePublicChat(String chatUsername, String draftText, boolean openProfile) { - this.chatUsername = chatUsername; - this.draftText = draftText; - this.openProfile = openProfile; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1769614592; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link can be used to login the current user on another device, but it must be scanned from QR-code using in-app camera. An alert similar to "This code can be used to allow someone to log in to your Telegram account. To confirm Telegram login, please go to Settings > Devices > Scan QR and scan the code" needs to be shown. - */ - public static class InternalLinkTypeQrCodeAuthentication extends InternalLinkType { - - /** - * The link can be used to login the current user on another device, but it must be scanned from QR-code using in-app camera. An alert similar to "This code can be used to allow someone to log in to your Telegram account. To confirm Telegram login, please go to Settings > Devices > Scan QR and scan the code" needs to be shown. - */ - public InternalLinkTypeQrCodeAuthentication() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1089332956; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link forces restore of App Store purchases when opened. For official iOS application only. - */ - public static class InternalLinkTypeRestorePurchases extends InternalLinkType { - - /** - * The link forces restore of App Store purchases when opened. For official iOS application only. - */ - public InternalLinkTypeRestorePurchases() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 606090371; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to the Saved Messages chat. Call createPrivateChat with getOption("my_id") and open the chat. - */ - public static class InternalLinkTypeSavedMessages extends InternalLinkType { - - /** - * The link is a link to the Saved Messages chat. Call createPrivateChat with getOption("my_id") and open the chat. - */ - public InternalLinkTypeSavedMessages() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 248860451; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to the global chat and messages search field. - */ - public static class InternalLinkTypeSearch extends InternalLinkType { - - /** - * The link is a link to the global chat and messages search field. - */ - public InternalLinkTypeSearch() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -591437024; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to application settings. - */ - public static class InternalLinkTypeSettings extends InternalLinkType { - /** - * Section of the application settings to open; may be null if none. - */ - @Nullable public SettingsSection section; - - /** - * The link is a link to application settings. - */ - public InternalLinkTypeSettings() { - } - - /** - * The link is a link to application settings. - * - * @param section Section of the application settings to open; may be null if none. - */ - public InternalLinkTypeSettings(SettingsSection section) { - this.section = section; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 574986998; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to the Telegram Star purchase section of the application. - */ - public static class InternalLinkTypeStarPurchase extends InternalLinkType { - /** - * The number of Telegram Stars that must be owned by the user. - */ - public long starCount; - /** - * Purpose of Telegram Star purchase. Arbitrary string specified by the server, for example, "subs" if the Telegram Stars are required to extend channel subscriptions. - */ - public String purpose; - - /** - * The link is a link to the Telegram Star purchase section of the application. - */ - public InternalLinkTypeStarPurchase() { - } - - /** - * The link is a link to the Telegram Star purchase section of the application. - * - * @param starCount The number of Telegram Stars that must be owned by the user. - * @param purpose Purpose of Telegram Star purchase. Arbitrary string specified by the server, for example, "subs" if the Telegram Stars are required to extend channel subscriptions. - */ - public InternalLinkTypeStarPurchase(long starCount, String purpose) { - this.starCount = starCount; - this.purpose = purpose; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -459567298; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a sticker set. Call searchStickerSet with the given sticker set name to process the link and show the sticker set. If the sticker set is found and the user wants to add it, then call changeStickerSet. - */ - public static class InternalLinkTypeStickerSet extends InternalLinkType { - /** - * Name of the sticker set. - */ - public String stickerSetName; - /** - * True, if the sticker set is expected to contain custom emoji. - */ - public boolean expectCustomEmoji; - - /** - * The link is a link to a sticker set. Call searchStickerSet with the given sticker set name to process the link and show the sticker set. If the sticker set is found and the user wants to add it, then call changeStickerSet. - */ - public InternalLinkTypeStickerSet() { - } - - /** - * The link is a link to a sticker set. Call searchStickerSet with the given sticker set name to process the link and show the sticker set. If the sticker set is found and the user wants to add it, then call changeStickerSet. - * - * @param stickerSetName Name of the sticker set. - * @param expectCustomEmoji True, if the sticker set is expected to contain custom emoji. - */ - public InternalLinkTypeStickerSet(String stickerSetName, boolean expectCustomEmoji) { - this.stickerSetName = stickerSetName; - this.expectCustomEmoji = expectCustomEmoji; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1589227614; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a story. Call searchPublicChat with the given poster username, then call getStory with the received chat identifier and the given story identifier, then show the story if received. - */ - public static class InternalLinkTypeStory extends InternalLinkType { - /** - * Username of the poster of the story. - */ - public String storyPosterUsername; - /** - * Story identifier. - */ - public int storyId; - - /** - * The link is a link to a story. Call searchPublicChat with the given poster username, then call getStory with the received chat identifier and the given story identifier, then show the story if received. - */ - public InternalLinkTypeStory() { - } - - /** - * The link is a link to a story. Call searchPublicChat with the given poster username, then call getStory with the received chat identifier and the given story identifier, then show the story if received. - * - * @param storyPosterUsername Username of the poster of the story. - * @param storyId Story identifier. - */ - public InternalLinkTypeStory(String storyPosterUsername, int storyId) { - this.storyPosterUsername = storyPosterUsername; - this.storyId = storyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1852042869; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to an album of stories. Call searchPublicChat with the given username, then call getStoryAlbumStories with the received chat identifier and the given story album identifier, then show the story album if received. - */ - public static class InternalLinkTypeStoryAlbum extends InternalLinkType { - /** - * Username of the owner of the story album. - */ - public String storyAlbumOwnerUsername; - /** - * Story album identifier. - */ - public int storyAlbumId; - - /** - * The link is a link to an album of stories. Call searchPublicChat with the given username, then call getStoryAlbumStories with the received chat identifier and the given story album identifier, then show the story album if received. - */ - public InternalLinkTypeStoryAlbum() { - } - - /** - * The link is a link to an album of stories. Call searchPublicChat with the given username, then call getStoryAlbumStories with the received chat identifier and the given story album identifier, then show the story album if received. - * - * @param storyAlbumOwnerUsername Username of the owner of the story album. - * @param storyAlbumId Story album identifier. - */ - public InternalLinkTypeStoryAlbum(String storyAlbumOwnerUsername, int storyAlbumId) { - this.storyAlbumOwnerUsername = storyAlbumOwnerUsername; - this.storyAlbumId = storyAlbumId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -332692184; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a cloud theme. TDLib has no theme support yet. - */ - public static class InternalLinkTypeTheme extends InternalLinkType { - /** - * Name of the theme. - */ - public String themeName; - - /** - * The link is a link to a cloud theme. TDLib has no theme support yet. - */ - public InternalLinkTypeTheme() { - } - - /** - * The link is a link to a cloud theme. TDLib has no theme support yet. - * - * @param themeName Name of the theme. - */ - public InternalLinkTypeTheme(String themeName) { - this.themeName = themeName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -200935417; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is an unknown tg: link. Call getDeepLinkInfo to process the link. - */ - public static class InternalLinkTypeUnknownDeepLink extends InternalLinkType { - /** - * Link to be passed to getDeepLinkInfo. - */ - public String link; - - /** - * The link is an unknown tg: link. Call getDeepLinkInfo to process the link. - */ - public InternalLinkTypeUnknownDeepLink() { - } - - /** - * The link is an unknown tg: link. Call getDeepLinkInfo to process the link. - * - * @param link Link to be passed to getDeepLinkInfo. - */ - public InternalLinkTypeUnknownDeepLink(String link) { - this.link = link; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 625596379; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to an upgraded gift. Call getUpgradedGift with the given name to process the link. - */ - public static class InternalLinkTypeUpgradedGift extends InternalLinkType { - /** - * Name of the unique gift. - */ - public String name; - - /** - * The link is a link to an upgraded gift. Call getUpgradedGift with the given name to process the link. - */ - public InternalLinkTypeUpgradedGift() { - } - - /** - * The link is a link to an upgraded gift. Call getUpgradedGift with the given name to process the link. - * - * @param name Name of the unique gift. - */ - public InternalLinkTypeUpgradedGift(String name) { - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -708405605; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a user by its phone number. Call searchUserByPhoneNumber with the given phone number to process the link. If the user is found, then call createPrivateChat and open user's profile information screen or the chat itself. If draft text isn't empty, then put the draft text in the input field. - */ - public static class InternalLinkTypeUserPhoneNumber extends InternalLinkType { - /** - * Phone number of the user. - */ - public String phoneNumber; - /** - * Draft text for message to send in the chat. - */ - public String draftText; - /** - * True, if user's profile information screen must be opened; otherwise, the chat itself must be opened. - */ - public boolean openProfile; - - /** - * The link is a link to a user by its phone number. Call searchUserByPhoneNumber with the given phone number to process the link. If the user is found, then call createPrivateChat and open user's profile information screen or the chat itself. If draft text isn't empty, then put the draft text in the input field. - */ - public InternalLinkTypeUserPhoneNumber() { - } - - /** - * The link is a link to a user by its phone number. Call searchUserByPhoneNumber with the given phone number to process the link. If the user is found, then call createPrivateChat and open user's profile information screen or the chat itself. If draft text isn't empty, then put the draft text in the input field. - * - * @param phoneNumber Phone number of the user. - * @param draftText Draft text for message to send in the chat. - * @param openProfile True, if user's profile information screen must be opened; otherwise, the chat itself must be opened. - */ - public InternalLinkTypeUserPhoneNumber(String phoneNumber, String draftText, boolean openProfile) { - this.phoneNumber = phoneNumber; - this.draftText = draftText; - this.openProfile = openProfile; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 273398536; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a user by a temporary token. Call searchUserByToken with the given token to process the link. If the user is found, then call createPrivateChat and open the chat. - */ - public static class InternalLinkTypeUserToken extends InternalLinkType { - /** - * The token. - */ - public String token; - - /** - * The link is a link to a user by a temporary token. Call searchUserByToken with the given token to process the link. If the user is found, then call createPrivateChat and open the chat. - */ - public InternalLinkTypeUserToken() { - } - - /** - * The link is a link to a user by a temporary token. Call searchUserByToken with the given token to process the link. If the user is found, then call createPrivateChat and open the chat. - * - * @param token The token. - */ - public InternalLinkTypeUserToken(String token) { - this.token = token; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1462248615; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a video chat. Call searchPublicChat with the given chat username, and then joinVideoChat with the given invite hash to process the link. - */ - public static class InternalLinkTypeVideoChat extends InternalLinkType { - /** - * Username of the chat with the video chat. - */ - public String chatUsername; - /** - * If non-empty, invite hash to be used to join the video chat without being muted by administrators. - */ - public String inviteHash; - /** - * True, if the video chat is expected to be a live stream in a channel or a broadcast group. - */ - public boolean isLiveStream; - - /** - * The link is a link to a video chat. Call searchPublicChat with the given chat username, and then joinVideoChat with the given invite hash to process the link. - */ - public InternalLinkTypeVideoChat() { - } - - /** - * The link is a link to a video chat. Call searchPublicChat with the given chat username, and then joinVideoChat with the given invite hash to process the link. - * - * @param chatUsername Username of the chat with the video chat. - * @param inviteHash If non-empty, invite hash to be used to join the video chat without being muted by administrators. - * @param isLiveStream True, if the video chat is expected to be a live stream in a channel or a broadcast group. - */ - public InternalLinkTypeVideoChat(String chatUsername, String inviteHash, boolean isLiveStream) { - this.chatUsername = chatUsername; - this.inviteHash = inviteHash; - this.isLiveStream = isLiveStream; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2020149068; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a Web App. Call searchPublicChat with the given bot username, check that the user is a bot. If the bot is restricted for the current user, then show an error message. Otherwise, call searchWebApp with the received bot and the given webAppShortName. Process received foundWebApp by showing a confirmation dialog if needed. If the bot can be added to attachment or side menu, but isn't added yet, then show a disclaimer about Mini Apps being third-party applications instead of the dialog and ask the user to accept their Terms of service. If the user accept the terms and confirms adding, then use toggleBotIsAddedToAttachmentMenu to add the bot. Then, call getWebAppLinkUrl and open the returned URL as a Web App. - */ - public static class InternalLinkTypeWebApp extends InternalLinkType { - /** - * Username of the bot that owns the Web App. - */ - public String botUsername; - /** - * Short name of the Web App. - */ - public String webAppShortName; - /** - * Start parameter to be passed to getWebAppLinkUrl. - */ - public String startParameter; - /** - * The mode in which the Web App must be opened. - */ - public WebAppOpenMode mode; - - /** - * The link is a link to a Web App. Call searchPublicChat with the given bot username, check that the user is a bot. If the bot is restricted for the current user, then show an error message. Otherwise, call searchWebApp with the received bot and the given webAppShortName. Process received foundWebApp by showing a confirmation dialog if needed. If the bot can be added to attachment or side menu, but isn't added yet, then show a disclaimer about Mini Apps being third-party applications instead of the dialog and ask the user to accept their Terms of service. If the user accept the terms and confirms adding, then use toggleBotIsAddedToAttachmentMenu to add the bot. Then, call getWebAppLinkUrl and open the returned URL as a Web App. - */ - public InternalLinkTypeWebApp() { - } - - /** - * The link is a link to a Web App. Call searchPublicChat with the given bot username, check that the user is a bot. If the bot is restricted for the current user, then show an error message. Otherwise, call searchWebApp with the received bot and the given webAppShortName. Process received foundWebApp by showing a confirmation dialog if needed. If the bot can be added to attachment or side menu, but isn't added yet, then show a disclaimer about Mini Apps being third-party applications instead of the dialog and ask the user to accept their Terms of service. If the user accept the terms and confirms adding, then use toggleBotIsAddedToAttachmentMenu to add the bot. Then, call getWebAppLinkUrl and open the returned URL as a Web App. - * - * @param botUsername Username of the bot that owns the Web App. - * @param webAppShortName Short name of the Web App. - * @param startParameter Start parameter to be passed to getWebAppLinkUrl. - * @param mode The mode in which the Web App must be opened. - */ - public InternalLinkTypeWebApp(String botUsername, String webAppShortName, String startParameter, WebAppOpenMode mode) { - this.botUsername = botUsername; - this.webAppShortName = webAppShortName; - this.startParameter = startParameter; - this.mode = mode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2062112045; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes result of group call participant invitation. - */ - public abstract static class InviteGroupCallParticipantResult extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InviteGroupCallParticipantResultUserPrivacyRestricted.CONSTRUCTOR, - InviteGroupCallParticipantResultUserAlreadyParticipant.CONSTRUCTOR, - InviteGroupCallParticipantResultUserWasBanned.CONSTRUCTOR, - InviteGroupCallParticipantResultSuccess.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InviteGroupCallParticipantResult() { - } - } - - /** - * The user can't be invited due to their privacy settings. - */ - public static class InviteGroupCallParticipantResultUserPrivacyRestricted extends InviteGroupCallParticipantResult { - - /** - * The user can't be invited due to their privacy settings. - */ - public InviteGroupCallParticipantResultUserPrivacyRestricted() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 53003769; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user can't be invited because they are already a participant of the call. - */ - public static class InviteGroupCallParticipantResultUserAlreadyParticipant extends InviteGroupCallParticipantResult { - - /** - * The user can't be invited because they are already a participant of the call. - */ - public InviteGroupCallParticipantResultUserAlreadyParticipant() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 661526151; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user can't be invited because they were banned by the owner of the call and can be invited back only by the owner of the group call. - */ - public static class InviteGroupCallParticipantResultUserWasBanned extends InviteGroupCallParticipantResult { - - /** - * The user can't be invited because they were banned by the owner of the call and can be invited back only by the owner of the group call. - */ - public InviteGroupCallParticipantResultUserWasBanned() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -204345357; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user was invited and a service message of the type messageGroupCall was sent which can be used in declineGroupCallInvitation to cancel the invitation. - */ - public static class InviteGroupCallParticipantResultSuccess extends InviteGroupCallParticipantResult { - /** - * Identifier of the chat with the invitation message. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - - /** - * The user was invited and a service message of the type messageGroupCall was sent which can be used in declineGroupCallInvitation to cancel the invitation. - */ - public InviteGroupCallParticipantResultSuccess() { - } - - /** - * The user was invited and a service message of the type messageGroupCall was sent which can be used in declineGroupCallInvitation to cancel the invitation. - * - * @param chatId Identifier of the chat with the invitation message. - * @param messageId Identifier of the message. - */ - public InviteGroupCallParticipantResultSuccess(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1914309427; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the type of chat to which points an invite link. - */ - public abstract static class InviteLinkChatType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - InviteLinkChatTypeBasicGroup.CONSTRUCTOR, - InviteLinkChatTypeSupergroup.CONSTRUCTOR, - InviteLinkChatTypeChannel.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public InviteLinkChatType() { - } - } - - /** - * The link is an invite link for a basic group. - */ - public static class InviteLinkChatTypeBasicGroup extends InviteLinkChatType { - - /** - * The link is an invite link for a basic group. - */ - public InviteLinkChatTypeBasicGroup() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1296287214; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is an invite link for a supergroup. - */ - public static class InviteLinkChatTypeSupergroup extends InviteLinkChatType { - - /** - * The link is an invite link for a supergroup. - */ - public InviteLinkChatTypeSupergroup() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1038640984; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is an invite link for a channel. - */ - public static class InviteLinkChatTypeChannel extends InviteLinkChatType { - - /** - * The link is an invite link for a channel. - */ - public InviteLinkChatTypeChannel() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 806547211; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Product invoice. - */ - public static class Invoice extends Object { - /** - * ISO 4217 currency code. - */ - public String currency; - /** - * A list of objects used to calculate the total price of the product. - */ - public LabeledPricePart[] priceParts; - /** - * The number of seconds between consecutive Telegram Star debiting for subscription invoices; 0 if the invoice doesn't create subscription. - */ - public int subscriptionPeriod; - /** - * The maximum allowed amount of tip in the smallest units of the currency. - */ - public long maxTipAmount; - /** - * Suggested amounts of tip in the smallest units of the currency. - */ - public long[] suggestedTipAmounts; - /** - * An HTTP URL with terms of service for recurring payments. If non-empty, the invoice payment will result in recurring payments and the user must accept the terms of service before allowed to pay. - */ - public String recurringPaymentTermsOfServiceUrl; - /** - * An HTTP URL with terms of service for non-recurring payments. If non-empty, then the user must accept the terms of service before allowed to pay. - */ - public String termsOfServiceUrl; - /** - * True, if the payment is a test payment. - */ - public boolean isTest; - /** - * True, if the user's name is needed for payment. - */ - public boolean needName; - /** - * True, if the user's phone number is needed for payment. - */ - public boolean needPhoneNumber; - /** - * True, if the user's email address is needed for payment. - */ - public boolean needEmailAddress; - /** - * True, if the user's shipping address is needed for payment. - */ - public boolean needShippingAddress; - /** - * True, if the user's phone number will be sent to the provider. - */ - public boolean sendPhoneNumberToProvider; - /** - * True, if the user's email address will be sent to the provider. - */ - public boolean sendEmailAddressToProvider; - /** - * True, if the total price depends on the shipping method. - */ - public boolean isFlexible; - - /** - * Product invoice. - */ - public Invoice() { - } - - /** - * Product invoice. - * - * @param currency ISO 4217 currency code. - * @param priceParts A list of objects used to calculate the total price of the product. - * @param subscriptionPeriod The number of seconds between consecutive Telegram Star debiting for subscription invoices; 0 if the invoice doesn't create subscription. - * @param maxTipAmount The maximum allowed amount of tip in the smallest units of the currency. - * @param suggestedTipAmounts Suggested amounts of tip in the smallest units of the currency. - * @param recurringPaymentTermsOfServiceUrl An HTTP URL with terms of service for recurring payments. If non-empty, the invoice payment will result in recurring payments and the user must accept the terms of service before allowed to pay. - * @param termsOfServiceUrl An HTTP URL with terms of service for non-recurring payments. If non-empty, then the user must accept the terms of service before allowed to pay. - * @param isTest True, if the payment is a test payment. - * @param needName True, if the user's name is needed for payment. - * @param needPhoneNumber True, if the user's phone number is needed for payment. - * @param needEmailAddress True, if the user's email address is needed for payment. - * @param needShippingAddress True, if the user's shipping address is needed for payment. - * @param sendPhoneNumberToProvider True, if the user's phone number will be sent to the provider. - * @param sendEmailAddressToProvider True, if the user's email address will be sent to the provider. - * @param isFlexible True, if the total price depends on the shipping method. - */ - public Invoice(String currency, LabeledPricePart[] priceParts, int subscriptionPeriod, long maxTipAmount, long[] suggestedTipAmounts, String recurringPaymentTermsOfServiceUrl, String termsOfServiceUrl, boolean isTest, boolean needName, boolean needPhoneNumber, boolean needEmailAddress, boolean needShippingAddress, boolean sendPhoneNumberToProvider, boolean sendEmailAddressToProvider, boolean isFlexible) { - this.currency = currency; - this.priceParts = priceParts; - this.subscriptionPeriod = subscriptionPeriod; - this.maxTipAmount = maxTipAmount; - this.suggestedTipAmounts = suggestedTipAmounts; - this.recurringPaymentTermsOfServiceUrl = recurringPaymentTermsOfServiceUrl; - this.termsOfServiceUrl = termsOfServiceUrl; - this.isTest = isTest; - this.needName = needName; - this.needPhoneNumber = needPhoneNumber; - this.needEmailAddress = needEmailAddress; - this.needShippingAddress = needShippingAddress; - this.sendPhoneNumberToProvider = sendPhoneNumberToProvider; - this.sendEmailAddressToProvider = sendEmailAddressToProvider; - this.isFlexible = isFlexible; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 113204876; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents one member of a JSON object. - */ - public static class JsonObjectMember extends Object { - /** - * Member's key. - */ - public String key; - /** - * Member's value. - */ - public JsonValue value; - - /** - * Represents one member of a JSON object. - */ - public JsonObjectMember() { - } - - /** - * Represents one member of a JSON object. - * - * @param key Member's key. - * @param value Member's value. - */ - public JsonObjectMember(String key, JsonValue value) { - this.key = key; - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1803309418; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents a JSON value. - */ - public abstract static class JsonValue extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - JsonValueNull.CONSTRUCTOR, - JsonValueBoolean.CONSTRUCTOR, - JsonValueNumber.CONSTRUCTOR, - JsonValueString.CONSTRUCTOR, - JsonValueArray.CONSTRUCTOR, - JsonValueObject.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public JsonValue() { - } - } - - /** - * Represents a null JSON value. - */ - public static class JsonValueNull extends JsonValue { - - /** - * Represents a null JSON value. - */ - public JsonValueNull() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -92872499; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a boolean JSON value. - */ - public static class JsonValueBoolean extends JsonValue { - /** - * The value. - */ - public boolean value; - - /** - * Represents a boolean JSON value. - */ - public JsonValueBoolean() { - } - - /** - * Represents a boolean JSON value. - * - * @param value The value. - */ - public JsonValueBoolean(boolean value) { - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2142186576; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a numeric JSON value. - */ - public static class JsonValueNumber extends JsonValue { - /** - * The value. - */ - public double value; - - /** - * Represents a numeric JSON value. - */ - public JsonValueNumber() { - } - - /** - * Represents a numeric JSON value. - * - * @param value The value. - */ - public JsonValueNumber(double value) { - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1010822033; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a string JSON value. - */ - public static class JsonValueString extends JsonValue { - /** - * The value. - */ - public String value; - - /** - * Represents a string JSON value. - */ - public JsonValueString() { - } - - /** - * Represents a string JSON value. - * - * @param value The value. - */ - public JsonValueString(String value) { - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1597947313; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a JSON array. - */ - public static class JsonValueArray extends JsonValue { - /** - * The list of array elements. - */ - public JsonValue[] values; - - /** - * Represents a JSON array. - */ - public JsonValueArray() { - } - - /** - * Represents a JSON array. - * - * @param values The list of array elements. - */ - public JsonValueArray(JsonValue[] values) { - this.values = values; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -183913546; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a JSON object. - */ - public static class JsonValueObject extends JsonValue { - /** - * The list of object members. - */ - public JsonObjectMember[] members; - - /** - * Represents a JSON object. - */ - public JsonValueObject() { - } - - /** - * Represents a JSON object. - * - * @param members The list of object members. - */ - public JsonValueObject(JsonObjectMember[] members) { - this.members = members; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 520252026; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a single button in a bot keyboard. - */ - public static class KeyboardButton extends Object { - /** - * Text of the button. - */ - public String text; - /** - * Identifier of the custom emoji that must be shown on the button; 0 if none. - */ - public long iconCustomEmojiId; - /** - * Style of the button. - */ - public ButtonStyle style; - /** - * Type of the button. - */ - public KeyboardButtonType type; - - /** - * Represents a single button in a bot keyboard. - */ - public KeyboardButton() { - } - - /** - * Represents a single button in a bot keyboard. - * - * @param text Text of the button. - * @param iconCustomEmojiId Identifier of the custom emoji that must be shown on the button; 0 if none. - * @param style Style of the button. - * @param type Type of the button. - */ - public KeyboardButton(String text, long iconCustomEmojiId, ButtonStyle style, KeyboardButtonType type) { - this.text = text; - this.iconCustomEmojiId = iconCustomEmojiId; - this.style = style; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -405853143; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a keyboard button type. - */ - public abstract static class KeyboardButtonType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - KeyboardButtonTypeText.CONSTRUCTOR, - KeyboardButtonTypeRequestPhoneNumber.CONSTRUCTOR, - KeyboardButtonTypeRequestLocation.CONSTRUCTOR, - KeyboardButtonTypeRequestPoll.CONSTRUCTOR, - KeyboardButtonTypeRequestUsers.CONSTRUCTOR, - KeyboardButtonTypeRequestChat.CONSTRUCTOR, - KeyboardButtonTypeWebApp.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public KeyboardButtonType() { - } - } - - /** - * A simple button, with text that must be sent when the button is pressed. - */ - public static class KeyboardButtonTypeText extends KeyboardButtonType { - - /** - * A simple button, with text that must be sent when the button is pressed. - */ - public KeyboardButtonTypeText() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1773037256; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A button that sends the user's phone number when pressed; available only in private chats. - */ - public static class KeyboardButtonTypeRequestPhoneNumber extends KeyboardButtonType { - - /** - * A button that sends the user's phone number when pressed; available only in private chats. - */ - public KeyboardButtonTypeRequestPhoneNumber() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1529235527; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A button that sends the user's location when pressed; available only in private chats. - */ - public static class KeyboardButtonTypeRequestLocation extends KeyboardButtonType { - - /** - * A button that sends the user's location when pressed; available only in private chats. - */ - public KeyboardButtonTypeRequestLocation() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -125661955; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A button that allows the user to create and send a poll when pressed; available only in private chats. - */ - public static class KeyboardButtonTypeRequestPoll extends KeyboardButtonType { - /** - * If true, only regular polls must be allowed to create. - */ - public boolean forceRegular; - /** - * If true, only polls in quiz mode must be allowed to create. - */ - public boolean forceQuiz; - - /** - * A button that allows the user to create and send a poll when pressed; available only in private chats. - */ - public KeyboardButtonTypeRequestPoll() { - } - - /** - * A button that allows the user to create and send a poll when pressed; available only in private chats. - * - * @param forceRegular If true, only regular polls must be allowed to create. - * @param forceQuiz If true, only polls in quiz mode must be allowed to create. - */ - public KeyboardButtonTypeRequestPoll(boolean forceRegular, boolean forceQuiz) { - this.forceRegular = forceRegular; - this.forceQuiz = forceQuiz; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1902435512; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A button that requests users to be shared by the current user; available only in private chats. Use the method shareUsersWithBot to complete the request. - */ - public static class KeyboardButtonTypeRequestUsers extends KeyboardButtonType { - /** - * Unique button identifier. - */ - public int id; - /** - * True, if the shared users must or must not be bots. - */ - public boolean restrictUserIsBot; - /** - * True, if the shared users must be bots; otherwise, the shared users must not be bots. Ignored if restrictUserIsBot is false. - */ - public boolean userIsBot; - /** - * True, if the shared users must or must not be Telegram Premium users. - */ - public boolean restrictUserIsPremium; - /** - * True, if the shared users must be Telegram Premium users; otherwise, the shared users must not be Telegram Premium users. Ignored if restrictUserIsPremium is false. - */ - public boolean userIsPremium; - /** - * The maximum number of users to share. - */ - public int maxQuantity; - /** - * Pass true to request name of the users; bots only. - */ - public boolean requestName; - /** - * Pass true to request username of the users; bots only. - */ - public boolean requestUsername; - /** - * Pass true to request photo of the users; bots only. - */ - public boolean requestPhoto; - - /** - * A button that requests users to be shared by the current user; available only in private chats. Use the method shareUsersWithBot to complete the request. - */ - public KeyboardButtonTypeRequestUsers() { - } - - /** - * A button that requests users to be shared by the current user; available only in private chats. Use the method shareUsersWithBot to complete the request. - * - * @param id Unique button identifier. - * @param restrictUserIsBot True, if the shared users must or must not be bots. - * @param userIsBot True, if the shared users must be bots; otherwise, the shared users must not be bots. Ignored if restrictUserIsBot is false. - * @param restrictUserIsPremium True, if the shared users must or must not be Telegram Premium users. - * @param userIsPremium True, if the shared users must be Telegram Premium users; otherwise, the shared users must not be Telegram Premium users. Ignored if restrictUserIsPremium is false. - * @param maxQuantity The maximum number of users to share. - * @param requestName Pass true to request name of the users; bots only. - * @param requestUsername Pass true to request username of the users; bots only. - * @param requestPhoto Pass true to request photo of the users; bots only. - */ - public KeyboardButtonTypeRequestUsers(int id, boolean restrictUserIsBot, boolean userIsBot, boolean restrictUserIsPremium, boolean userIsPremium, int maxQuantity, boolean requestName, boolean requestUsername, boolean requestPhoto) { - this.id = id; - this.restrictUserIsBot = restrictUserIsBot; - this.userIsBot = userIsBot; - this.restrictUserIsPremium = restrictUserIsPremium; - this.userIsPremium = userIsPremium; - this.maxQuantity = maxQuantity; - this.requestName = requestName; - this.requestUsername = requestUsername; - this.requestPhoto = requestPhoto; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1738765315; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A button that requests a chat to be shared by the current user; available only in private chats. Use the method shareChatWithBot to complete the request. - */ - public static class KeyboardButtonTypeRequestChat extends KeyboardButtonType { - /** - * Unique button identifier. - */ - public int id; - /** - * True, if the chat must be a channel; otherwise, a basic group or a supergroup chat is shared. - */ - public boolean chatIsChannel; - /** - * True, if the chat must or must not be a forum supergroup. - */ - public boolean restrictChatIsForum; - /** - * True, if the chat must be a forum supergroup; otherwise, the chat must not be a forum supergroup. Ignored if restrictChatIsForum is false. - */ - public boolean chatIsForum; - /** - * True, if the chat must or must not have a username. - */ - public boolean restrictChatHasUsername; - /** - * True, if the chat must have a username; otherwise, the chat must not have a username. Ignored if restrictChatHasUsername is false. - */ - public boolean chatHasUsername; - /** - * True, if the chat must be created by the current user. - */ - public boolean chatIsCreated; - /** - * Expected user administrator rights in the chat; may be null if they aren't restricted. - */ - @Nullable public ChatAdministratorRights userAdministratorRights; - /** - * Expected bot administrator rights in the chat; may be null if they aren't restricted. - */ - @Nullable public ChatAdministratorRights botAdministratorRights; - /** - * True, if the bot must be a member of the chat; for basic group and supergroup chats only. - */ - public boolean botIsMember; - /** - * Pass true to request title of the chat; bots only. - */ - public boolean requestTitle; - /** - * Pass true to request username of the chat; bots only. - */ - public boolean requestUsername; - /** - * Pass true to request photo of the chat; bots only. - */ - public boolean requestPhoto; - - /** - * A button that requests a chat to be shared by the current user; available only in private chats. Use the method shareChatWithBot to complete the request. - */ - public KeyboardButtonTypeRequestChat() { - } - - /** - * A button that requests a chat to be shared by the current user; available only in private chats. Use the method shareChatWithBot to complete the request. - * - * @param id Unique button identifier. - * @param chatIsChannel True, if the chat must be a channel; otherwise, a basic group or a supergroup chat is shared. - * @param restrictChatIsForum True, if the chat must or must not be a forum supergroup. - * @param chatIsForum True, if the chat must be a forum supergroup; otherwise, the chat must not be a forum supergroup. Ignored if restrictChatIsForum is false. - * @param restrictChatHasUsername True, if the chat must or must not have a username. - * @param chatHasUsername True, if the chat must have a username; otherwise, the chat must not have a username. Ignored if restrictChatHasUsername is false. - * @param chatIsCreated True, if the chat must be created by the current user. - * @param userAdministratorRights Expected user administrator rights in the chat; may be null if they aren't restricted. - * @param botAdministratorRights Expected bot administrator rights in the chat; may be null if they aren't restricted. - * @param botIsMember True, if the bot must be a member of the chat; for basic group and supergroup chats only. - * @param requestTitle Pass true to request title of the chat; bots only. - * @param requestUsername Pass true to request username of the chat; bots only. - * @param requestPhoto Pass true to request photo of the chat; bots only. - */ - public KeyboardButtonTypeRequestChat(int id, boolean chatIsChannel, boolean restrictChatIsForum, boolean chatIsForum, boolean restrictChatHasUsername, boolean chatHasUsername, boolean chatIsCreated, ChatAdministratorRights userAdministratorRights, ChatAdministratorRights botAdministratorRights, boolean botIsMember, boolean requestTitle, boolean requestUsername, boolean requestPhoto) { - this.id = id; - this.chatIsChannel = chatIsChannel; - this.restrictChatIsForum = restrictChatIsForum; - this.chatIsForum = chatIsForum; - this.restrictChatHasUsername = restrictChatHasUsername; - this.chatHasUsername = chatHasUsername; - this.chatIsCreated = chatIsCreated; - this.userAdministratorRights = userAdministratorRights; - this.botAdministratorRights = botAdministratorRights; - this.botIsMember = botIsMember; - this.requestTitle = requestTitle; - this.requestUsername = requestUsername; - this.requestPhoto = requestPhoto; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1511138485; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A button that opens a Web App by calling getWebAppUrl. - */ - public static class KeyboardButtonTypeWebApp extends KeyboardButtonType { - /** - * An HTTP URL to pass to getWebAppUrl. - */ - public String url; - - /** - * A button that opens a Web App by calling getWebAppUrl. - */ - public KeyboardButtonTypeWebApp() { - } - - /** - * A button that opens a Web App by calling getWebAppUrl. - * - * @param url An HTTP URL to pass to getWebAppUrl. - */ - public KeyboardButtonTypeWebApp(String url) { - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1892220770; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Portion of the price of a product (e.g., "delivery cost", "tax amount"). - */ - public static class LabeledPricePart extends Object { - /** - * Label for this portion of the product price. - */ - public String label; - /** - * Currency amount in the smallest units of the currency. - */ - public long amount; - - /** - * Portion of the price of a product (e.g., "delivery cost", "tax amount"). - */ - public LabeledPricePart() { - } - - /** - * Portion of the price of a product (e.g., "delivery cost", "tax amount"). - * - * @param label Label for this portion of the product price. - * @param amount Currency amount in the smallest units of the currency. - */ - public LabeledPricePart(String label, long amount) { - this.label = label; - this.amount = amount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 552789798; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a language pack. - */ - public static class LanguagePackInfo extends Object { - /** - * Unique language pack identifier. - */ - public String id; - /** - * Identifier of a base language pack; may be empty. If a string is missed in the language pack, then it must be fetched from base language pack. Unsupported in custom language packs. - */ - public String baseLanguagePackId; - /** - * Language name. - */ - public String name; - /** - * Name of the language in that language. - */ - public String nativeName; - /** - * A language code to be used to apply plural forms. See https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html for more information. - */ - public String pluralCode; - /** - * True, if the language pack is official. - */ - public boolean isOfficial; - /** - * True, if the language pack strings are RTL. - */ - public boolean isRtl; - /** - * True, if the language pack is a beta language pack. - */ - public boolean isBeta; - /** - * True, if the language pack is installed by the current user. - */ - public boolean isInstalled; - /** - * Total number of non-deleted strings from the language pack. - */ - public int totalStringCount; - /** - * Total number of translated strings from the language pack. - */ - public int translatedStringCount; - /** - * Total number of non-deleted strings from the language pack available locally. - */ - public int localStringCount; - /** - * Link to language translation interface; empty for custom local language packs. - */ - public String translationUrl; - - /** - * Contains information about a language pack. - */ - public LanguagePackInfo() { - } - - /** - * Contains information about a language pack. - * - * @param id Unique language pack identifier. - * @param baseLanguagePackId Identifier of a base language pack; may be empty. If a string is missed in the language pack, then it must be fetched from base language pack. Unsupported in custom language packs. - * @param name Language name. - * @param nativeName Name of the language in that language. - * @param pluralCode A language code to be used to apply plural forms. See https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html for more information. - * @param isOfficial True, if the language pack is official. - * @param isRtl True, if the language pack strings are RTL. - * @param isBeta True, if the language pack is a beta language pack. - * @param isInstalled True, if the language pack is installed by the current user. - * @param totalStringCount Total number of non-deleted strings from the language pack. - * @param translatedStringCount Total number of translated strings from the language pack. - * @param localStringCount Total number of non-deleted strings from the language pack available locally. - * @param translationUrl Link to language translation interface; empty for custom local language packs. - */ - public LanguagePackInfo(String id, String baseLanguagePackId, String name, String nativeName, String pluralCode, boolean isOfficial, boolean isRtl, boolean isBeta, boolean isInstalled, int totalStringCount, int translatedStringCount, int localStringCount, String translationUrl) { - this.id = id; - this.baseLanguagePackId = baseLanguagePackId; - this.name = name; - this.nativeName = nativeName; - this.pluralCode = pluralCode; - this.isOfficial = isOfficial; - this.isRtl = isRtl; - this.isBeta = isBeta; - this.isInstalled = isInstalled; - this.totalStringCount = totalStringCount; - this.translatedStringCount = translatedStringCount; - this.localStringCount = localStringCount; - this.translationUrl = translationUrl; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 542199642; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents one language pack string. - */ - public static class LanguagePackString extends Object { - /** - * String key. - */ - public String key; - /** - * String value; pass null if the string needs to be taken from the built-in English language pack. - */ - public LanguagePackStringValue value; - - /** - * Represents one language pack string. - */ - public LanguagePackString() { - } - - /** - * Represents one language pack string. - * - * @param key String key. - * @param value String value; pass null if the string needs to be taken from the built-in English language pack. - */ - public LanguagePackString(String key, LanguagePackStringValue value) { - this.key = key; - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1307632736; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents the value of a string in a language pack. - */ - public abstract static class LanguagePackStringValue extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - LanguagePackStringValueOrdinary.CONSTRUCTOR, - LanguagePackStringValuePluralized.CONSTRUCTOR, - LanguagePackStringValueDeleted.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public LanguagePackStringValue() { - } - } - - /** - * An ordinary language pack string. - */ - public static class LanguagePackStringValueOrdinary extends LanguagePackStringValue { - /** - * String value. - */ - public String value; - - /** - * An ordinary language pack string. - */ - public LanguagePackStringValueOrdinary() { - } - - /** - * An ordinary language pack string. - * - * @param value String value. - */ - public LanguagePackStringValueOrdinary(String value) { - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -249256352; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A language pack string which has different forms based on the number of some object it mentions. See https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html for more information. - */ - public static class LanguagePackStringValuePluralized extends LanguagePackStringValue { - /** - * Value for zero objects. - */ - public String zeroValue; - /** - * Value for one object. - */ - public String oneValue; - /** - * Value for two objects. - */ - public String twoValue; - /** - * Value for few objects. - */ - public String fewValue; - /** - * Value for many objects. - */ - public String manyValue; - /** - * Default value. - */ - public String otherValue; - - /** - * A language pack string which has different forms based on the number of some object it mentions. See https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html for more information. - */ - public LanguagePackStringValuePluralized() { - } - - /** - * A language pack string which has different forms based on the number of some object it mentions. See https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html for more information. - * - * @param zeroValue Value for zero objects. - * @param oneValue Value for one object. - * @param twoValue Value for two objects. - * @param fewValue Value for few objects. - * @param manyValue Value for many objects. - * @param otherValue Default value. - */ - public LanguagePackStringValuePluralized(String zeroValue, String oneValue, String twoValue, String fewValue, String manyValue, String otherValue) { - this.zeroValue = zeroValue; - this.oneValue = oneValue; - this.twoValue = twoValue; - this.fewValue = fewValue; - this.manyValue = manyValue; - this.otherValue = otherValue; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1906840261; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A deleted language pack string, the value must be taken from the built-in English language pack. - */ - public static class LanguagePackStringValueDeleted extends LanguagePackStringValue { - - /** - * A deleted language pack string, the value must be taken from the built-in English language pack. - */ - public LanguagePackStringValueDeleted() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1834792698; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of language pack strings. - */ - public static class LanguagePackStrings extends Object { - /** - * A list of language pack strings. - */ - public LanguagePackString[] strings; - - /** - * Contains a list of language pack strings. - */ - public LanguagePackStrings() { - } - - /** - * Contains a list of language pack strings. - * - * @param strings A list of language pack strings. - */ - public LanguagePackStrings(LanguagePackString[] strings) { - this.strings = strings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1172082922; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a link preview. - */ - public static class LinkPreview extends Object { - /** - * Original URL of the link. - */ - public String url; - /** - * URL to display. - */ - public String displayUrl; - /** - * Short name of the site (e.g., Google Docs, App Store). - */ - public String siteName; - /** - * Title of the content. - */ - public String title; - /** - * Description of the content. - */ - public FormattedText description; - /** - * Author of the content. - */ - public String author; - /** - * Type of the link preview. - */ - public LinkPreviewType type; - /** - * True, if size of media in the preview can be changed. - */ - public boolean hasLargeMedia; - /** - * True, if large media preview must be shown; otherwise, the media preview must be shown small and only the first frame must be shown for videos. - */ - public boolean showLargeMedia; - /** - * True, if media must be shown above link preview description; otherwise, the media must be shown below the description. - */ - public boolean showMediaAboveDescription; - /** - * True, if there is no need to show an ordinary open URL confirmation, when opening the URL from the preview, because the URL is shown in the message text in clear. - */ - public boolean skipConfirmation; - /** - * True, if the link preview must be shown above message text; otherwise, the link preview must be shown below the message text. - */ - public boolean showAboveText; - /** - * Version of instant view (currently, can be 1 or 2) for the web page; 0 if none. - */ - public int instantViewVersion; - - /** - * Describes a link preview. - */ - public LinkPreview() { - } - - /** - * Describes a link preview. - * - * @param url Original URL of the link. - * @param displayUrl URL to display. - * @param siteName Short name of the site (e.g., Google Docs, App Store). - * @param title Title of the content. - * @param description Description of the content. - * @param author Author of the content. - * @param type Type of the link preview. - * @param hasLargeMedia True, if size of media in the preview can be changed. - * @param showLargeMedia True, if large media preview must be shown; otherwise, the media preview must be shown small and only the first frame must be shown for videos. - * @param showMediaAboveDescription True, if media must be shown above link preview description; otherwise, the media must be shown below the description. - * @param skipConfirmation True, if there is no need to show an ordinary open URL confirmation, when opening the URL from the preview, because the URL is shown in the message text in clear. - * @param showAboveText True, if the link preview must be shown above message text; otherwise, the link preview must be shown below the message text. - * @param instantViewVersion Version of instant view (currently, can be 1 or 2) for the web page; 0 if none. - */ - public LinkPreview(String url, String displayUrl, String siteName, String title, FormattedText description, String author, LinkPreviewType type, boolean hasLargeMedia, boolean showLargeMedia, boolean showMediaAboveDescription, boolean skipConfirmation, boolean showAboveText, int instantViewVersion) { - this.url = url; - this.displayUrl = displayUrl; - this.siteName = siteName; - this.title = title; - this.description = description; - this.author = author; - this.type = type; - this.hasLargeMedia = hasLargeMedia; - this.showLargeMedia = showLargeMedia; - this.showMediaAboveDescription = showMediaAboveDescription; - this.skipConfirmation = skipConfirmation; - this.showAboveText = showAboveText; - this.instantViewVersion = instantViewVersion; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1729417714; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a media from a link preview album. - */ - public abstract static class LinkPreviewAlbumMedia extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - LinkPreviewAlbumMediaPhoto.CONSTRUCTOR, - LinkPreviewAlbumMediaVideo.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public LinkPreviewAlbumMedia() { - } - } - - /** - * The media is a photo. - */ - public static class LinkPreviewAlbumMediaPhoto extends LinkPreviewAlbumMedia { - /** - * Photo description. - */ - public Photo photo; - - /** - * The media is a photo. - */ - public LinkPreviewAlbumMediaPhoto() { - } - - /** - * The media is a photo. - * - * @param photo Photo description. - */ - public LinkPreviewAlbumMediaPhoto(Photo photo) { - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -935480434; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The media is a video. - */ - public static class LinkPreviewAlbumMediaVideo extends LinkPreviewAlbumMedia { - /** - * Video description. - */ - public Video video; - - /** - * The media is a video. - */ - public LinkPreviewAlbumMediaVideo() { - } - - /** - * The media is a video. - * - * @param video Video description. - */ - public LinkPreviewAlbumMediaVideo(Video video) { - this.video = video; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 390616795; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Options to be used for generation of a link preview. - */ - public static class LinkPreviewOptions extends Object { - /** - * True, if link preview must be disabled. - */ - public boolean isDisabled; - /** - * URL to use for link preview. If empty, then the first URL found in the message text will be used. - */ - public String url; - /** - * True, if shown media preview must be small; ignored in secret chats or if the URL isn't explicitly specified. - */ - public boolean forceSmallMedia; - /** - * True, if shown media preview must be large; ignored in secret chats or if the URL isn't explicitly specified. - */ - public boolean forceLargeMedia; - /** - * True, if link preview must be shown above message text; otherwise, the link preview will be shown below the message text; ignored in secret chats. - */ - public boolean showAboveText; - - /** - * Options to be used for generation of a link preview. - */ - public LinkPreviewOptions() { - } - - /** - * Options to be used for generation of a link preview. - * - * @param isDisabled True, if link preview must be disabled. - * @param url URL to use for link preview. If empty, then the first URL found in the message text will be used. - * @param forceSmallMedia True, if shown media preview must be small; ignored in secret chats or if the URL isn't explicitly specified. - * @param forceLargeMedia True, if shown media preview must be large; ignored in secret chats or if the URL isn't explicitly specified. - * @param showAboveText True, if link preview must be shown above message text; otherwise, the link preview will be shown below the message text; ignored in secret chats. - */ - public LinkPreviewOptions(boolean isDisabled, String url, boolean forceSmallMedia, boolean forceLargeMedia, boolean showAboveText) { - this.isDisabled = isDisabled; - this.url = url; - this.forceSmallMedia = forceSmallMedia; - this.forceLargeMedia = forceLargeMedia; - this.showAboveText = showAboveText; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1046590451; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of link preview. - */ - public abstract static class LinkPreviewType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - LinkPreviewTypeAlbum.CONSTRUCTOR, - LinkPreviewTypeAnimation.CONSTRUCTOR, - LinkPreviewTypeApp.CONSTRUCTOR, - LinkPreviewTypeArticle.CONSTRUCTOR, - LinkPreviewTypeAudio.CONSTRUCTOR, - LinkPreviewTypeBackground.CONSTRUCTOR, - LinkPreviewTypeChannelBoost.CONSTRUCTOR, - LinkPreviewTypeChat.CONSTRUCTOR, - LinkPreviewTypeDirectMessagesChat.CONSTRUCTOR, - LinkPreviewTypeDocument.CONSTRUCTOR, - LinkPreviewTypeEmbeddedAnimationPlayer.CONSTRUCTOR, - LinkPreviewTypeEmbeddedAudioPlayer.CONSTRUCTOR, - LinkPreviewTypeEmbeddedVideoPlayer.CONSTRUCTOR, - LinkPreviewTypeExternalAudio.CONSTRUCTOR, - LinkPreviewTypeExternalVideo.CONSTRUCTOR, - LinkPreviewTypeGiftAuction.CONSTRUCTOR, - LinkPreviewTypeGiftCollection.CONSTRUCTOR, - LinkPreviewTypeGroupCall.CONSTRUCTOR, - LinkPreviewTypeInvoice.CONSTRUCTOR, - LinkPreviewTypeLiveStory.CONSTRUCTOR, - LinkPreviewTypeMessage.CONSTRUCTOR, - LinkPreviewTypePhoto.CONSTRUCTOR, - LinkPreviewTypePremiumGiftCode.CONSTRUCTOR, - LinkPreviewTypeShareableChatFolder.CONSTRUCTOR, - LinkPreviewTypeSticker.CONSTRUCTOR, - LinkPreviewTypeStickerSet.CONSTRUCTOR, - LinkPreviewTypeStory.CONSTRUCTOR, - LinkPreviewTypeStoryAlbum.CONSTRUCTOR, - LinkPreviewTypeSupergroupBoost.CONSTRUCTOR, - LinkPreviewTypeTheme.CONSTRUCTOR, - LinkPreviewTypeUnsupported.CONSTRUCTOR, - LinkPreviewTypeUpgradedGift.CONSTRUCTOR, - LinkPreviewTypeUser.CONSTRUCTOR, - LinkPreviewTypeVideo.CONSTRUCTOR, - LinkPreviewTypeVideoChat.CONSTRUCTOR, - LinkPreviewTypeVideoNote.CONSTRUCTOR, - LinkPreviewTypeVoiceNote.CONSTRUCTOR, - LinkPreviewTypeWebApp.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public LinkPreviewType() { - } - } - - /** - * The link is a link to a media album consisting of photos and videos. - */ - public static class LinkPreviewTypeAlbum extends LinkPreviewType { - /** - * The list of album media. - */ - public LinkPreviewAlbumMedia[] media; - /** - * Album caption. - */ - public String caption; - - /** - * The link is a link to a media album consisting of photos and videos. - */ - public LinkPreviewTypeAlbum() { - } - - /** - * The link is a link to a media album consisting of photos and videos. - * - * @param media The list of album media. - * @param caption Album caption. - */ - public LinkPreviewTypeAlbum(LinkPreviewAlbumMedia[] media, String caption) { - this.media = media; - this.caption = caption; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -919156671; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to an animation. - */ - public static class LinkPreviewTypeAnimation extends LinkPreviewType { - /** - * The animation. - */ - public Animation animation; - - /** - * The link is a link to an animation. - */ - public LinkPreviewTypeAnimation() { - } - - /** - * The link is a link to an animation. - * - * @param animation The animation. - */ - public LinkPreviewTypeAnimation(Animation animation) { - this.animation = animation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1386429132; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to an app at App Store or Google Play. - */ - public static class LinkPreviewTypeApp extends LinkPreviewType { - /** - * Photo for the app. - */ - public Photo photo; - - /** - * The link is a link to an app at App Store or Google Play. - */ - public LinkPreviewTypeApp() { - } - - /** - * The link is a link to an app at App Store or Google Play. - * - * @param photo Photo for the app. - */ - public LinkPreviewTypeApp(Photo photo) { - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -475623953; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a web site. - */ - public static class LinkPreviewTypeArticle extends LinkPreviewType { - /** - * Article's main photo; may be null. - */ - @Nullable public Photo photo; - - /** - * The link is a link to a web site. - */ - public LinkPreviewTypeArticle() { - } - - /** - * The link is a link to a web site. - * - * @param photo Article's main photo; may be null. - */ - public LinkPreviewTypeArticle(Photo photo) { - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2093915097; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to an audio. - */ - public static class LinkPreviewTypeAudio extends LinkPreviewType { - /** - * The audio description. - */ - public Audio audio; - - /** - * The link is a link to an audio. - */ - public LinkPreviewTypeAudio() { - } - - /** - * The link is a link to an audio. - * - * @param audio The audio description. - */ - public LinkPreviewTypeAudio(Audio audio) { - this.audio = audio; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1977878482; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a background. Link preview title and description are available only for filled backgrounds. - */ - public static class LinkPreviewTypeBackground extends LinkPreviewType { - /** - * Document with the background; may be null for filled backgrounds. - */ - @Nullable public Document document; - /** - * Type of the background; may be null if unknown. - */ - @Nullable public BackgroundType backgroundType; - - /** - * The link is a link to a background. Link preview title and description are available only for filled backgrounds. - */ - public LinkPreviewTypeBackground() { - } - - /** - * The link is a link to a background. Link preview title and description are available only for filled backgrounds. - * - * @param document Document with the background; may be null for filled backgrounds. - * @param backgroundType Type of the background; may be null if unknown. - */ - public LinkPreviewTypeBackground(Document document, BackgroundType backgroundType) { - this.document = document; - this.backgroundType = backgroundType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 977838560; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to boost a channel chat. - */ - public static class LinkPreviewTypeChannelBoost extends LinkPreviewType { - /** - * Photo of the chat; may be null. - */ - @Nullable public ChatPhoto photo; - - /** - * The link is a link to boost a channel chat. - */ - public LinkPreviewTypeChannelBoost() { - } - - /** - * The link is a link to boost a channel chat. - * - * @param photo Photo of the chat; may be null. - */ - public LinkPreviewTypeChannelBoost(ChatPhoto photo) { - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -957086634; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a chat. - */ - public static class LinkPreviewTypeChat extends LinkPreviewType { - /** - * Type of the chat. - */ - public InviteLinkChatType type; - /** - * Photo of the chat; may be null. - */ - @Nullable public ChatPhoto photo; - /** - * True, if the link only creates join request. - */ - public boolean createsJoinRequest; - - /** - * The link is a link to a chat. - */ - public LinkPreviewTypeChat() { - } - - /** - * The link is a link to a chat. - * - * @param type Type of the chat. - * @param photo Photo of the chat; may be null. - * @param createsJoinRequest True, if the link only creates join request. - */ - public LinkPreviewTypeChat(InviteLinkChatType type, ChatPhoto photo, boolean createsJoinRequest) { - this.type = type; - this.photo = photo; - this.createsJoinRequest = createsJoinRequest; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1372610270; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a direct messages chat of a channel. - */ - public static class LinkPreviewTypeDirectMessagesChat extends LinkPreviewType { - /** - * Photo of the channel chat; may be null. - */ - @Nullable public ChatPhoto photo; - - /** - * The link is a link to a direct messages chat of a channel. - */ - public LinkPreviewTypeDirectMessagesChat() { - } - - /** - * The link is a link to a direct messages chat of a channel. - * - * @param photo Photo of the channel chat; may be null. - */ - public LinkPreviewTypeDirectMessagesChat(ChatPhoto photo) { - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 578255582; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a general file. - */ - public static class LinkPreviewTypeDocument extends LinkPreviewType { - /** - * The document description. - */ - public Document document; - - /** - * The link is a link to a general file. - */ - public LinkPreviewTypeDocument() { - } - - /** - * The link is a link to a general file. - * - * @param document The document description. - */ - public LinkPreviewTypeDocument(Document document) { - this.document = document; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1090426462; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to an animation player. - */ - public static class LinkPreviewTypeEmbeddedAnimationPlayer extends LinkPreviewType { - /** - * URL of the external animation player. - */ - public String url; - /** - * The cached animation; may be null if unknown. - */ - @Nullable public Animation animation; - /** - * Thumbnail of the animation; may be null if unknown. - */ - @Nullable public Photo thumbnail; - /** - * Duration of the animation, in seconds. - */ - public int duration; - /** - * Expected width of the embedded player. - */ - public int width; - /** - * Expected height of the embedded player. - */ - public int height; - - /** - * The link is a link to an animation player. - */ - public LinkPreviewTypeEmbeddedAnimationPlayer() { - } - - /** - * The link is a link to an animation player. - * - * @param url URL of the external animation player. - * @param animation The cached animation; may be null if unknown. - * @param thumbnail Thumbnail of the animation; may be null if unknown. - * @param duration Duration of the animation, in seconds. - * @param width Expected width of the embedded player. - * @param height Expected height of the embedded player. - */ - public LinkPreviewTypeEmbeddedAnimationPlayer(String url, Animation animation, Photo thumbnail, int duration, int width, int height) { - this.url = url; - this.animation = animation; - this.thumbnail = thumbnail; - this.duration = duration; - this.width = width; - this.height = height; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 413874679; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to an audio player. - */ - public static class LinkPreviewTypeEmbeddedAudioPlayer extends LinkPreviewType { - /** - * URL of the external audio player. - */ - public String url; - /** - * The cached audio; may be null if unknown. - */ - @Nullable public Audio audio; - /** - * Thumbnail of the audio; may be null if unknown. - */ - @Nullable public Photo thumbnail; - /** - * Duration of the audio, in seconds. - */ - public int duration; - /** - * Expected width of the embedded player. - */ - public int width; - /** - * Expected height of the embedded player. - */ - public int height; - - /** - * The link is a link to an audio player. - */ - public LinkPreviewTypeEmbeddedAudioPlayer() { - } - - /** - * The link is a link to an audio player. - * - * @param url URL of the external audio player. - * @param audio The cached audio; may be null if unknown. - * @param thumbnail Thumbnail of the audio; may be null if unknown. - * @param duration Duration of the audio, in seconds. - * @param width Expected width of the embedded player. - * @param height Expected height of the embedded player. - */ - public LinkPreviewTypeEmbeddedAudioPlayer(String url, Audio audio, Photo thumbnail, int duration, int width, int height) { - this.url = url; - this.audio = audio; - this.thumbnail = thumbnail; - this.duration = duration; - this.width = width; - this.height = height; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2077132997; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a video player. - */ - public static class LinkPreviewTypeEmbeddedVideoPlayer extends LinkPreviewType { - /** - * URL of the external video player. - */ - public String url; - /** - * The cached video; may be null if unknown. - */ - @Nullable public Video video; - /** - * Thumbnail of the video; may be null if unknown. - */ - @Nullable public Photo thumbnail; - /** - * Duration of the video, in seconds. - */ - public int duration; - /** - * Expected width of the embedded player. - */ - public int width; - /** - * Expected height of the embedded player. - */ - public int height; - - /** - * The link is a link to a video player. - */ - public LinkPreviewTypeEmbeddedVideoPlayer() { - } - - /** - * The link is a link to a video player. - * - * @param url URL of the external video player. - * @param video The cached video; may be null if unknown. - * @param thumbnail Thumbnail of the video; may be null if unknown. - * @param duration Duration of the video, in seconds. - * @param width Expected width of the embedded player. - * @param height Expected height of the embedded player. - */ - public LinkPreviewTypeEmbeddedVideoPlayer(String url, Video video, Photo thumbnail, int duration, int width, int height) { - this.url = url; - this.video = video; - this.thumbnail = thumbnail; - this.duration = duration; - this.width = width; - this.height = height; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -571363951; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to an audio file. - */ - public static class LinkPreviewTypeExternalAudio extends LinkPreviewType { - /** - * URL of the audio file. - */ - public String url; - /** - * MIME type of the audio file. - */ - public String mimeType; - /** - * Duration of the audio, in seconds; 0 if unknown. - */ - public int duration; - - /** - * The link is a link to an audio file. - */ - public LinkPreviewTypeExternalAudio() { - } - - /** - * The link is a link to an audio file. - * - * @param url URL of the audio file. - * @param mimeType MIME type of the audio file. - * @param duration Duration of the audio, in seconds; 0 if unknown. - */ - public LinkPreviewTypeExternalAudio(String url, String mimeType, int duration) { - this.url = url; - this.mimeType = mimeType; - this.duration = duration; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1971126291; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a video file. - */ - public static class LinkPreviewTypeExternalVideo extends LinkPreviewType { - /** - * URL of the video file. - */ - public String url; - /** - * MIME type of the video file. - */ - public String mimeType; - /** - * Expected width of the video preview; 0 if unknown. - */ - public int width; - /** - * Expected height of the video preview; 0 if unknown. - */ - public int height; - /** - * Duration of the video, in seconds; 0 if unknown. - */ - public int duration; - - /** - * The link is a link to a video file. - */ - public LinkPreviewTypeExternalVideo() { - } - - /** - * The link is a link to a video file. - * - * @param url URL of the video file. - * @param mimeType MIME type of the video file. - * @param width Expected width of the video preview; 0 if unknown. - * @param height Expected height of the video preview; 0 if unknown. - * @param duration Duration of the video, in seconds; 0 if unknown. - */ - public LinkPreviewTypeExternalVideo(String url, String mimeType, int width, int height, int duration) { - this.url = url; - this.mimeType = mimeType; - this.width = width; - this.height = height; - this.duration = duration; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1367198616; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a gift auction. - */ - public static class LinkPreviewTypeGiftAuction extends LinkPreviewType { - /** - * The gift. - */ - public Gift gift; - /** - * Point in time (Unix timestamp) when the auction will be ended. - */ - public int auctionEndDate; - - /** - * The link is a link to a gift auction. - */ - public LinkPreviewTypeGiftAuction() { - } - - /** - * The link is a link to a gift auction. - * - * @param gift The gift. - * @param auctionEndDate Point in time (Unix timestamp) when the auction will be ended. - */ - public LinkPreviewTypeGiftAuction(Gift gift, int auctionEndDate) { - this.gift = gift; - this.auctionEndDate = auctionEndDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1291307457; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a gift collection. - */ - public static class LinkPreviewTypeGiftCollection extends LinkPreviewType { - /** - * Icons for some gifts from the collection; may be empty. - */ - public Sticker[] icons; - - /** - * The link is a link to a gift collection. - */ - public LinkPreviewTypeGiftCollection() { - } - - /** - * The link is a link to a gift collection. - * - * @param icons Icons for some gifts from the collection; may be empty. - */ - public LinkPreviewTypeGiftCollection(Sticker[] icons) { - this.icons = icons; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 230270537; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a group call that isn't bound to a chat. - */ - public static class LinkPreviewTypeGroupCall extends LinkPreviewType { - - /** - * The link is a link to a group call that isn't bound to a chat. - */ - public LinkPreviewTypeGroupCall() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1242459936; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to an invoice. - */ - public static class LinkPreviewTypeInvoice extends LinkPreviewType { - - /** - * The link is a link to an invoice. - */ - public LinkPreviewTypeInvoice() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -729855782; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a live story group call. - */ - public static class LinkPreviewTypeLiveStory extends LinkPreviewType { - /** - * The identifier of the chat that posted the story. - */ - public long storyPosterChatId; - /** - * Story identifier. - */ - public int storyId; - - /** - * The link is a link to a live story group call. - */ - public LinkPreviewTypeLiveStory() { - } - - /** - * The link is a link to a live story group call. - * - * @param storyPosterChatId The identifier of the chat that posted the story. - * @param storyId Story identifier. - */ - public LinkPreviewTypeLiveStory(long storyPosterChatId, int storyId) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1062126469; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a text or a poll Telegram message. - */ - public static class LinkPreviewTypeMessage extends LinkPreviewType { - - /** - * The link is a link to a text or a poll Telegram message. - */ - public LinkPreviewTypeMessage() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 435470750; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a photo. - */ - public static class LinkPreviewTypePhoto extends LinkPreviewType { - /** - * The photo. - */ - public Photo photo; - - /** - * The link is a link to a photo. - */ - public LinkPreviewTypePhoto() { - } - - /** - * The link is a link to a photo. - * - * @param photo The photo. - */ - public LinkPreviewTypePhoto(Photo photo) { - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1362122068; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a Telegram Premium gift code. - */ - public static class LinkPreviewTypePremiumGiftCode extends LinkPreviewType { - - /** - * The link is a link to a Telegram Premium gift code. - */ - public LinkPreviewTypePremiumGiftCode() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1309507761; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a shareable chat folder. - */ - public static class LinkPreviewTypeShareableChatFolder extends LinkPreviewType { - - /** - * The link is a link to a shareable chat folder. - */ - public LinkPreviewTypeShareableChatFolder() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2141539524; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a sticker. - */ - public static class LinkPreviewTypeSticker extends LinkPreviewType { - /** - * The sticker. It can be an arbitrary WEBP image and can have dimensions bigger than 512. - */ - public Sticker sticker; - - /** - * The link is a link to a sticker. - */ - public LinkPreviewTypeSticker() { - } - - /** - * The link is a link to a sticker. - * - * @param sticker The sticker. It can be an arbitrary WEBP image and can have dimensions bigger than 512. - */ - public LinkPreviewTypeSticker(Sticker sticker) { - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 610225445; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a sticker set. - */ - public static class LinkPreviewTypeStickerSet extends LinkPreviewType { - /** - * Up to 4 stickers from the sticker set. - */ - public Sticker[] stickers; - - /** - * The link is a link to a sticker set. - */ - public LinkPreviewTypeStickerSet() { - } - - /** - * The link is a link to a sticker set. - * - * @param stickers Up to 4 stickers from the sticker set. - */ - public LinkPreviewTypeStickerSet(Sticker[] stickers) { - this.stickers = stickers; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -145958768; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a story. Link preview description is unavailable. - */ - public static class LinkPreviewTypeStory extends LinkPreviewType { - /** - * The identifier of the chat that posted the story. - */ - public long storyPosterChatId; - /** - * Story identifier. - */ - public int storyId; - - /** - * The link is a link to a story. Link preview description is unavailable. - */ - public LinkPreviewTypeStory() { - } - - /** - * The link is a link to a story. Link preview description is unavailable. - * - * @param storyPosterChatId The identifier of the chat that posted the story. - * @param storyId Story identifier. - */ - public LinkPreviewTypeStory(long storyPosterChatId, int storyId) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1045709531; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to an album of stories. - */ - public static class LinkPreviewTypeStoryAlbum extends LinkPreviewType { - /** - * Icon of the album; may be null if none. - */ - @Nullable public Photo photoIcon; - /** - * Video icon of the album; may be null if none. - */ - @Nullable public Video videoIcon; - - /** - * The link is a link to an album of stories. - */ - public LinkPreviewTypeStoryAlbum() { - } - - /** - * The link is a link to an album of stories. - * - * @param photoIcon Icon of the album; may be null if none. - * @param videoIcon Video icon of the album; may be null if none. - */ - public LinkPreviewTypeStoryAlbum(Photo photoIcon, Video videoIcon) { - this.photoIcon = photoIcon; - this.videoIcon = videoIcon; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1935150441; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to boost a supergroup chat. - */ - public static class LinkPreviewTypeSupergroupBoost extends LinkPreviewType { - /** - * Photo of the chat; may be null. - */ - @Nullable public ChatPhoto photo; - - /** - * The link is a link to boost a supergroup chat. - */ - public LinkPreviewTypeSupergroupBoost() { - } - - /** - * The link is a link to boost a supergroup chat. - * - * @param photo Photo of the chat; may be null. - */ - public LinkPreviewTypeSupergroupBoost(ChatPhoto photo) { - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1873345418; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a cloud theme. TDLib has no theme support yet. - */ - public static class LinkPreviewTypeTheme extends LinkPreviewType { - /** - * The list of files with theme description. - */ - public Document[] documents; - /** - * Settings for the cloud theme; may be null if unknown. - */ - @Nullable public ThemeSettings settings; - - /** - * The link is a link to a cloud theme. TDLib has no theme support yet. - */ - public LinkPreviewTypeTheme() { - } - - /** - * The link is a link to a cloud theme. TDLib has no theme support yet. - * - * @param documents The list of files with theme description. - * @param settings Settings for the cloud theme; may be null if unknown. - */ - public LinkPreviewTypeTheme(Document[] documents, ThemeSettings settings) { - this.documents = documents; - this.settings = settings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -226118489; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link preview type is unsupported yet. - */ - public static class LinkPreviewTypeUnsupported extends LinkPreviewType { - - /** - * The link preview type is unsupported yet. - */ - public LinkPreviewTypeUnsupported() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1924738233; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to an upgraded gift. - */ - public static class LinkPreviewTypeUpgradedGift extends LinkPreviewType { - /** - * The gift. - */ - public UpgradedGift gift; - - /** - * The link is a link to an upgraded gift. - */ - public LinkPreviewTypeUpgradedGift() { - } - - /** - * The link is a link to an upgraded gift. - * - * @param gift The gift. - */ - public LinkPreviewTypeUpgradedGift(UpgradedGift gift) { - this.gift = gift; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 293249807; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a user. - */ - public static class LinkPreviewTypeUser extends LinkPreviewType { - /** - * Photo of the user; may be null if none. - */ - @Nullable public ChatPhoto photo; - /** - * True, if the user is a bot. - */ - public boolean isBot; - - /** - * The link is a link to a user. - */ - public LinkPreviewTypeUser() { - } - - /** - * The link is a link to a user. - * - * @param photo Photo of the user; may be null if none. - * @param isBot True, if the user is a bot. - */ - public LinkPreviewTypeUser(ChatPhoto photo, boolean isBot) { - this.photo = photo; - this.isBot = isBot; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1465024132; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a video. - */ - public static class LinkPreviewTypeVideo extends LinkPreviewType { - /** - * The video description. - */ - public Video video; - /** - * Cover of the video; may be null if none. - */ - @Nullable public Photo cover; - /** - * Timestamp from which the video playing must start, in seconds. - */ - public int startTimestamp; - - /** - * The link is a link to a video. - */ - public LinkPreviewTypeVideo() { - } - - /** - * The link is a link to a video. - * - * @param video The video description. - * @param cover Cover of the video; may be null if none. - * @param startTimestamp Timestamp from which the video playing must start, in seconds. - */ - public LinkPreviewTypeVideo(Video video, Photo cover, int startTimestamp) { - this.video = video; - this.cover = cover; - this.startTimestamp = startTimestamp; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1573057926; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a video chat. - */ - public static class LinkPreviewTypeVideoChat extends LinkPreviewType { - /** - * Photo of the chat with the video chat; may be null if none. - */ - @Nullable public ChatPhoto photo; - /** - * True, if the video chat is expected to be a live stream in a channel or a broadcast group. - */ - public boolean isLiveStream; - /** - * True, if the user can use the link to join the video chat without being muted by administrators. - */ - public boolean joinsAsSpeaker; - - /** - * The link is a link to a video chat. - */ - public LinkPreviewTypeVideoChat() { - } - - /** - * The link is a link to a video chat. - * - * @param photo Photo of the chat with the video chat; may be null if none. - * @param isLiveStream True, if the video chat is expected to be a live stream in a channel or a broadcast group. - * @param joinsAsSpeaker True, if the user can use the link to join the video chat without being muted by administrators. - */ - public LinkPreviewTypeVideoChat(ChatPhoto photo, boolean isLiveStream, boolean joinsAsSpeaker) { - this.photo = photo; - this.isLiveStream = isLiveStream; - this.joinsAsSpeaker = joinsAsSpeaker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -295676354; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a video note message. - */ - public static class LinkPreviewTypeVideoNote extends LinkPreviewType { - /** - * The video note. - */ - public VideoNote videoNote; - - /** - * The link is a link to a video note message. - */ - public LinkPreviewTypeVideoNote() { - } - - /** - * The link is a link to a video note message. - * - * @param videoNote The video note. - */ - public LinkPreviewTypeVideoNote(VideoNote videoNote) { - this.videoNote = videoNote; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -814687391; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a voice note message. - */ - public static class LinkPreviewTypeVoiceNote extends LinkPreviewType { - /** - * The voice note. - */ - public VoiceNote voiceNote; - - /** - * The link is a link to a voice note message. - */ - public LinkPreviewTypeVoiceNote() { - } - - /** - * The link is a link to a voice note message. - * - * @param voiceNote The voice note. - */ - public LinkPreviewTypeVoiceNote(VoiceNote voiceNote) { - this.voiceNote = voiceNote; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -757936341; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The link is a link to a Web App. - */ - public static class LinkPreviewTypeWebApp extends LinkPreviewType { - /** - * Web App photo; may be null if none. - */ - @Nullable public Photo photo; - - /** - * The link is a link to a Web App. - */ - public LinkPreviewTypeWebApp() { - } - - /** - * The link is a link to a Web App. - * - * @param photo Web App photo; may be null if none. - */ - public LinkPreviewTypeWebApp(Photo photo) { - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1506873462; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of users and chats that spend most money on paid messages and reactions in a live story. - */ - public static class LiveStoryDonors extends Object { - /** - * Total amount of spend Telegram Stars. - */ - public long totalStarCount; - /** - * List of top donors in the live story. - */ - public PaidReactor[] topDonors; - - /** - * Contains a list of users and chats that spend most money on paid messages and reactions in a live story. - */ - public LiveStoryDonors() { - } - - /** - * Contains a list of users and chats that spend most money on paid messages and reactions in a live story. - * - * @param totalStarCount Total amount of spend Telegram Stars. - * @param topDonors List of top donors in the live story. - */ - public LiveStoryDonors(long totalStarCount, PaidReactor[] topDonors) { - this.totalStarCount = totalStarCount; - this.topDonors = topDonors; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1254388193; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a local file. - */ - public static class LocalFile extends Object { - /** - * Local path to the locally available file part; may be empty. - */ - public String path; - /** - * True, if it is possible to download or generate the file. - */ - public boolean canBeDownloaded; - /** - * True, if the file can be deleted. - */ - public boolean canBeDeleted; - /** - * True, if the file is currently being downloaded (or a local copy is being generated by some other means). - */ - public boolean isDownloadingActive; - /** - * True, if the local copy is fully available. - */ - public boolean isDownloadingCompleted; - /** - * Download will be started from this offset. downloadedPrefixSize is calculated from this offset. - */ - public long downloadOffset; - /** - * If isDownloadingCompleted is false, then only some prefix of the file starting from downloadOffset is ready to be read. downloadedPrefixSize is the size of that prefix in bytes. - */ - public long downloadedPrefixSize; - /** - * Total downloaded file size, in bytes. Can be used only for calculating download progress. The actual file size may be bigger, and some parts of it may contain garbage. - */ - public long downloadedSize; - - /** - * Represents a local file. - */ - public LocalFile() { - } - - /** - * Represents a local file. - * - * @param path Local path to the locally available file part; may be empty. - * @param canBeDownloaded True, if it is possible to download or generate the file. - * @param canBeDeleted True, if the file can be deleted. - * @param isDownloadingActive True, if the file is currently being downloaded (or a local copy is being generated by some other means). - * @param isDownloadingCompleted True, if the local copy is fully available. - * @param downloadOffset Download will be started from this offset. downloadedPrefixSize is calculated from this offset. - * @param downloadedPrefixSize If isDownloadingCompleted is false, then only some prefix of the file starting from downloadOffset is ready to be read. downloadedPrefixSize is the size of that prefix in bytes. - * @param downloadedSize Total downloaded file size, in bytes. Can be used only for calculating download progress. The actual file size may be bigger, and some parts of it may contain garbage. - */ - public LocalFile(String path, boolean canBeDownloaded, boolean canBeDeleted, boolean isDownloadingActive, boolean isDownloadingCompleted, long downloadOffset, long downloadedPrefixSize, long downloadedSize) { - this.path = path; - this.canBeDownloaded = canBeDownloaded; - this.canBeDeleted = canBeDeleted; - this.isDownloadingActive = isDownloadingActive; - this.isDownloadingCompleted = isDownloadingCompleted; - this.downloadOffset = downloadOffset; - this.downloadedPrefixSize = downloadedPrefixSize; - this.downloadedSize = downloadedSize; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1562732153; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about the current localization target. - */ - public static class LocalizationTargetInfo extends Object { - /** - * List of available language packs for this application. - */ - public LanguagePackInfo[] languagePacks; - - /** - * Contains information about the current localization target. - */ - public LocalizationTargetInfo() { - } - - /** - * Contains information about the current localization target. - * - * @param languagePacks List of available language packs for this application. - */ - public LocalizationTargetInfo(LanguagePackInfo[] languagePacks) { - this.languagePacks = languagePacks; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2048670809; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a location on planet Earth. - */ - public static class Location extends Object { - /** - * Latitude of the location in degrees; as defined by the sender. - */ - public double latitude; - /** - * Longitude of the location, in degrees; as defined by the sender. - */ - public double longitude; - /** - * The estimated horizontal accuracy of the location, in meters; as defined by the sender. 0 if unknown. - */ - public double horizontalAccuracy; - - /** - * Describes a location on planet Earth. - */ - public Location() { - } - - /** - * Describes a location on planet Earth. - * - * @param latitude Latitude of the location in degrees; as defined by the sender. - * @param longitude Longitude of the location, in degrees; as defined by the sender. - * @param horizontalAccuracy The estimated horizontal accuracy of the location, in meters; as defined by the sender. 0 if unknown. - */ - public Location(double latitude, double longitude, double horizontalAccuracy) { - this.latitude = latitude; - this.longitude = longitude; - this.horizontalAccuracy = horizontalAccuracy; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -443392141; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an address of a location. - */ - public static class LocationAddress extends Object { - /** - * A two-letter ISO 3166-1 alpha-2 country code. - */ - public String countryCode; - /** - * State, if applicable; empty if unknown. - */ - public String state; - /** - * City; empty if unknown. - */ - public String city; - /** - * The address; empty if unknown. - */ - public String street; - - /** - * Describes an address of a location. - */ - public LocationAddress() { - } - - /** - * Describes an address of a location. - * - * @param countryCode A two-letter ISO 3166-1 alpha-2 country code. - * @param state State, if applicable; empty if unknown. - * @param city City; empty if unknown. - * @param street The address; empty if unknown. - */ - public LocationAddress(String countryCode, String state, String city, String street) { - this.countryCode = countryCode; - this.state = state; - this.city = city; - this.street = street; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1545940190; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a stream to which TDLib internal log is written. - */ - public abstract static class LogStream extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - LogStreamDefault.CONSTRUCTOR, - LogStreamFile.CONSTRUCTOR, - LogStreamEmpty.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public LogStream() { - } - } - - /** - * The log is written to stderr or an OS specific log. - */ - public static class LogStreamDefault extends LogStream { - - /** - * The log is written to stderr or an OS specific log. - */ - public LogStreamDefault() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1390581436; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The log is written to a file. - */ - public static class LogStreamFile extends LogStream { - /** - * Path to the file to where the internal TDLib log will be written. - */ - public String path; - /** - * The maximum size of the file to where the internal TDLib log is written before the file will automatically be rotated, in bytes. - */ - public long maxFileSize; - /** - * Pass true to additionally redirect stderr to the log file. Ignored on Windows. - */ - public boolean redirectStderr; - - /** - * The log is written to a file. - */ - public LogStreamFile() { - } - - /** - * The log is written to a file. - * - * @param path Path to the file to where the internal TDLib log will be written. - * @param maxFileSize The maximum size of the file to where the internal TDLib log is written before the file will automatically be rotated, in bytes. - * @param redirectStderr Pass true to additionally redirect stderr to the log file. Ignored on Windows. - */ - public LogStreamFile(String path, long maxFileSize, boolean redirectStderr) { - this.path = path; - this.maxFileSize = maxFileSize; - this.redirectStderr = redirectStderr; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1532136933; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The log is written nowhere. - */ - public static class LogStreamEmpty extends LogStream { - - /** - * The log is written nowhere. - */ - public LogStreamEmpty() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -499912244; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of available TDLib internal log tags. - */ - public static class LogTags extends Object { - /** - * List of log tags. - */ - public String[] tags; - - /** - * Contains a list of available TDLib internal log tags. - */ - public LogTags() { - } - - /** - * Contains a list of available TDLib internal log tags. - * - * @param tags List of log tags. - */ - public LogTags(String[] tags) { - this.tags = tags; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1604930601; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a TDLib internal log verbosity level. - */ - public static class LogVerbosityLevel extends Object { - /** - * Log verbosity level. - */ - public int verbosityLevel; - - /** - * Contains a TDLib internal log verbosity level. - */ - public LogVerbosityLevel() { - } - - /** - * Contains a TDLib internal log verbosity level. - * - * @param verbosityLevel Log verbosity level. - */ - public LogVerbosityLevel(int verbosityLevel) { - this.verbosityLevel = verbosityLevel; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1734624234; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains information about an inline button of type inlineKeyboardButtonTypeLoginUrl or an external link. - */ - public abstract static class LoginUrlInfo extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - LoginUrlInfoOpen.CONSTRUCTOR, - LoginUrlInfoRequestConfirmation.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public LoginUrlInfo() { - } - } - - /** - * An HTTP URL needs to be open. - */ - public static class LoginUrlInfoOpen extends LoginUrlInfo { - /** - * The URL to open. - */ - public String url; - /** - * True, if there is no need to show an ordinary open URL confirmation. - */ - public boolean skipConfirmation; - - /** - * An HTTP URL needs to be open. - */ - public LoginUrlInfoOpen() { - } - - /** - * An HTTP URL needs to be open. - * - * @param url The URL to open. - * @param skipConfirmation True, if there is no need to show an ordinary open URL confirmation. - */ - public LoginUrlInfoOpen(String url, boolean skipConfirmation) { - this.url = url; - this.skipConfirmation = skipConfirmation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 837282306; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An authorization confirmation dialog needs to be shown to the user. - */ - public static class LoginUrlInfoRequestConfirmation extends LoginUrlInfo { - /** - * An HTTP URL to be opened. - */ - public String url; - /** - * A domain of the URL. - */ - public String domain; - /** - * User identifier of a bot linked with the website. - */ - public long botUserId; - /** - * True, if the user must be asked for the permission to the bot to send them messages. - */ - public boolean requestWriteAccess; - - /** - * An authorization confirmation dialog needs to be shown to the user. - */ - public LoginUrlInfoRequestConfirmation() { - } - - /** - * An authorization confirmation dialog needs to be shown to the user. - * - * @param url An HTTP URL to be opened. - * @param domain A domain of the URL. - * @param botUserId User identifier of a bot linked with the website. - * @param requestWriteAccess True, if the user must be asked for the permission to the bot to send them messages. - */ - public LoginUrlInfoRequestConfirmation(String url, String domain, long botUserId, boolean requestWriteAccess) { - this.url = url; - this.domain = domain; - this.botUserId = botUserId; - this.requestWriteAccess = requestWriteAccess; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2128290863; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about the main Web App of a bot. - */ - public static class MainWebApp extends Object { - /** - * URL of the Web App to open. - */ - public String url; - /** - * The mode in which the Web App must be opened. - */ - public WebAppOpenMode mode; - - /** - * Contains information about the main Web App of a bot. - */ - public MainWebApp() { - } - - /** - * Contains information about the main Web App of a bot. - * - * @param url URL of the Web App to open. - * @param mode The mode in which the Web App must be opened. - */ - public MainWebApp(String url, WebAppOpenMode mode) { - this.url = url; - this.mode = mode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1940368506; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Part of the face, relative to which a mask is placed. - */ - public abstract static class MaskPoint extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - MaskPointForehead.CONSTRUCTOR, - MaskPointEyes.CONSTRUCTOR, - MaskPointMouth.CONSTRUCTOR, - MaskPointChin.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public MaskPoint() { - } - } - - /** - * The mask is placed relatively to the forehead. - */ - public static class MaskPointForehead extends MaskPoint { - - /** - * The mask is placed relatively to the forehead. - */ - public MaskPointForehead() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1027512005; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The mask is placed relatively to the eyes. - */ - public static class MaskPointEyes extends MaskPoint { - - /** - * The mask is placed relatively to the eyes. - */ - public MaskPointEyes() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1748310861; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The mask is placed relatively to the mouth. - */ - public static class MaskPointMouth extends MaskPoint { - - /** - * The mask is placed relatively to the mouth. - */ - public MaskPointMouth() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 411773406; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The mask is placed relatively to the chin. - */ - public static class MaskPointChin extends MaskPoint { - - /** - * The mask is placed relatively to the chin. - */ - public MaskPointChin() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 534995335; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Position on a photo where a mask is placed. - */ - public static class MaskPosition extends Object { - /** - * Part of the face, relative to which the mask is placed. - */ - public MaskPoint point; - /** - * Shift by X-axis measured in widths of the mask scaled to the face size, from left to right. (For example, -1.0 will place the mask just to the left of the default mask position.) - */ - public double xShift; - /** - * Shift by Y-axis measured in heights of the mask scaled to the face size, from top to bottom. (For example, 1.0 will place the mask just below the default mask position.) - */ - public double yShift; - /** - * Mask scaling coefficient. (For example, 2.0 means a doubled size.) - */ - public double scale; - - /** - * Position on a photo where a mask is placed. - */ - public MaskPosition() { - } - - /** - * Position on a photo where a mask is placed. - * - * @param point Part of the face, relative to which the mask is placed. - * @param xShift Shift by X-axis measured in widths of the mask scaled to the face size, from left to right. (For example, -1.0 will place the mask just to the left of the default mask position.) - * @param yShift Shift by Y-axis measured in heights of the mask scaled to the face size, from top to bottom. (For example, 1.0 will place the mask just below the default mask position.) - * @param scale Mask scaling coefficient. (For example, 2.0 means a doubled size.) - */ - public MaskPosition(MaskPoint point, double xShift, double yShift, double scale) { - this.point = point; - this.xShift = xShift; - this.yShift = yShift; - this.scale = scale; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2097433026; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a message. - */ - public static class Message extends Object { - /** - * Message identifier; unique for the chat to which the message belongs. - */ - public long id; - /** - * Identifier of the sender of the message. - */ - public MessageSender senderId; - /** - * Chat identifier. - */ - public long chatId; - /** - * The sending state of the message; may be null if the message isn't being sent and didn't fail to be sent. - */ - @Nullable public MessageSendingState sendingState; - /** - * The scheduling state of the message; may be null if the message isn't scheduled. - */ - @Nullable public MessageSchedulingState schedulingState; - /** - * True, if the message is outgoing. - */ - public boolean isOutgoing; - /** - * True, if the message is pinned. - */ - public boolean isPinned; - /** - * True, if the message was sent because of a scheduled action by the message sender, for example, as away, or greeting service message. - */ - public boolean isFromOffline; - /** - * True, if content of the message can be saved locally. - */ - public boolean canBeSaved; - /** - * True, if media timestamp entities refers to a media in this message as opposed to a media in the replied message. - */ - public boolean hasTimestampedMedia; - /** - * True, if the message is a channel post. All messages to channels are channel posts, all other messages are not channel posts. - */ - public boolean isChannelPost; - /** - * True, if the message is a suggested channel post which was paid in Telegram Stars; a warning must be shown if the message is deleted in less than getOption("suggested_post_lifetime_min") seconds after sending. - */ - public boolean isPaidStarSuggestedPost; - /** - * True, if the message is a suggested channel post which was paid in Toncoins; a warning must be shown if the message is deleted in less than getOption("suggested_post_lifetime_min") seconds after sending. - */ - public boolean isPaidTonSuggestedPost; - /** - * True, if the message contains an unread mention for the current user. - */ - public boolean containsUnreadMention; - /** - * Point in time (Unix timestamp) when the message was sent; 0 for scheduled messages. - */ - public int date; - /** - * Point in time (Unix timestamp) when the message was last edited; 0 for scheduled messages. - */ - public int editDate; - /** - * Information about the initial message sender; may be null if none or unknown. - */ - @Nullable public MessageForwardInfo forwardInfo; - /** - * Information about the initial message for messages created with importMessages; may be null if the message isn't imported. - */ - @Nullable public MessageImportInfo importInfo; - /** - * Information about interactions with the message; may be null if none. - */ - @Nullable public MessageInteractionInfo interactionInfo; - /** - * Information about unread reactions added to the message. - */ - public UnreadReaction[] unreadReactions; - /** - * Information about fact-check added to the message; may be null if none. - */ - @Nullable public FactCheck factCheck; - /** - * Information about the suggested post; may be null if the message isn't a suggested post. - */ - @Nullable public SuggestedPostInfo suggestedPostInfo; - /** - * Information about the message or the story this message is replying to; may be null if none. - */ - @Nullable public MessageReplyTo replyTo; - /** - * Identifier of the topic within the chat to which the message belongs; may be null if none; may change when the chat is converted to a forum or back. - */ - @Nullable public MessageTopic topicId; - /** - * The message's self-destruct type; may be null if none. - */ - @Nullable public MessageSelfDestructType selfDestructType; - /** - * Time left before the message self-destruct timer expires, in seconds; 0 if self-destruction isn't scheduled yet. - */ - public double selfDestructIn; - /** - * Time left before the message will be automatically deleted by messageAutoDeleteTime setting of the chat, in seconds; 0 if never. - */ - public double autoDeleteIn; - /** - * If non-zero, the user identifier of the inline bot through which this message was sent. - */ - public long viaBotUserId; - /** - * If non-zero, the user identifier of the business bot that sent this message. - */ - public long senderBusinessBotUserId; - /** - * Number of times the sender of the message boosted the supergroup at the time the message was sent; 0 if none or unknown. For messages sent by the current user, supergroupFullInfo.myBoostCount must be used instead. - */ - public int senderBoostCount; - /** - * Tag of the sender of the message in the supergroup at the time the message was sent; may be empty if none or unknown. For messages sent in basic groups or supergroup administrators, the current custom title or tag must be used instead. - */ - public String senderTag; - /** - * The number of Telegram Stars the sender paid to send the message. - */ - public long paidMessageStarCount; - /** - * For channel posts and anonymous group messages, optional author signature. - */ - public String authorSignature; - /** - * Unique identifier of an album this message belongs to; 0 if none. Only audios, documents, photos and videos can be grouped together in albums. - */ - public long mediaAlbumId; - /** - * Unique identifier of the effect added to the message; 0 if none. - */ - public long effectId; - /** - * Information about the restrictions that must be applied to the message content; may be null if none. - */ - @Nullable public RestrictionInfo restrictionInfo; - /** - * IETF language tag of the message language on which it can be summarized; empty if summary isn't available for the message. - */ - public String summaryLanguageCode; - /** - * Content of the message. - */ - public MessageContent content; - /** - * Reply markup for the message; may be null if none. - */ - @Nullable public ReplyMarkup replyMarkup; - - /** - * Describes a message. - */ - public Message() { - } - - /** - * Describes a message. - * - * @param id Message identifier; unique for the chat to which the message belongs. - * @param senderId Identifier of the sender of the message. - * @param chatId Chat identifier. - * @param sendingState The sending state of the message; may be null if the message isn't being sent and didn't fail to be sent. - * @param schedulingState The scheduling state of the message; may be null if the message isn't scheduled. - * @param isOutgoing True, if the message is outgoing. - * @param isPinned True, if the message is pinned. - * @param isFromOffline True, if the message was sent because of a scheduled action by the message sender, for example, as away, or greeting service message. - * @param canBeSaved True, if content of the message can be saved locally. - * @param hasTimestampedMedia True, if media timestamp entities refers to a media in this message as opposed to a media in the replied message. - * @param isChannelPost True, if the message is a channel post. All messages to channels are channel posts, all other messages are not channel posts. - * @param isPaidStarSuggestedPost True, if the message is a suggested channel post which was paid in Telegram Stars; a warning must be shown if the message is deleted in less than getOption("suggested_post_lifetime_min") seconds after sending. - * @param isPaidTonSuggestedPost True, if the message is a suggested channel post which was paid in Toncoins; a warning must be shown if the message is deleted in less than getOption("suggested_post_lifetime_min") seconds after sending. - * @param containsUnreadMention True, if the message contains an unread mention for the current user. - * @param date Point in time (Unix timestamp) when the message was sent; 0 for scheduled messages. - * @param editDate Point in time (Unix timestamp) when the message was last edited; 0 for scheduled messages. - * @param forwardInfo Information about the initial message sender; may be null if none or unknown. - * @param importInfo Information about the initial message for messages created with importMessages; may be null if the message isn't imported. - * @param interactionInfo Information about interactions with the message; may be null if none. - * @param unreadReactions Information about unread reactions added to the message. - * @param factCheck Information about fact-check added to the message; may be null if none. - * @param suggestedPostInfo Information about the suggested post; may be null if the message isn't a suggested post. - * @param replyTo Information about the message or the story this message is replying to; may be null if none. - * @param topicId Identifier of the topic within the chat to which the message belongs; may be null if none; may change when the chat is converted to a forum or back. - * @param selfDestructType The message's self-destruct type; may be null if none. - * @param selfDestructIn Time left before the message self-destruct timer expires, in seconds; 0 if self-destruction isn't scheduled yet. - * @param autoDeleteIn Time left before the message will be automatically deleted by messageAutoDeleteTime setting of the chat, in seconds; 0 if never. - * @param viaBotUserId If non-zero, the user identifier of the inline bot through which this message was sent. - * @param senderBusinessBotUserId If non-zero, the user identifier of the business bot that sent this message. - * @param senderBoostCount Number of times the sender of the message boosted the supergroup at the time the message was sent; 0 if none or unknown. For messages sent by the current user, supergroupFullInfo.myBoostCount must be used instead. - * @param senderTag Tag of the sender of the message in the supergroup at the time the message was sent; may be empty if none or unknown. For messages sent in basic groups or supergroup administrators, the current custom title or tag must be used instead. - * @param paidMessageStarCount The number of Telegram Stars the sender paid to send the message. - * @param authorSignature For channel posts and anonymous group messages, optional author signature. - * @param mediaAlbumId Unique identifier of an album this message belongs to; 0 if none. Only audios, documents, photos and videos can be grouped together in albums. - * @param effectId Unique identifier of the effect added to the message; 0 if none. - * @param restrictionInfo Information about the restrictions that must be applied to the message content; may be null if none. - * @param summaryLanguageCode IETF language tag of the message language on which it can be summarized; empty if summary isn't available for the message. - * @param content Content of the message. - * @param replyMarkup Reply markup for the message; may be null if none. - */ - public Message(long id, MessageSender senderId, long chatId, MessageSendingState sendingState, MessageSchedulingState schedulingState, boolean isOutgoing, boolean isPinned, boolean isFromOffline, boolean canBeSaved, boolean hasTimestampedMedia, boolean isChannelPost, boolean isPaidStarSuggestedPost, boolean isPaidTonSuggestedPost, boolean containsUnreadMention, int date, int editDate, MessageForwardInfo forwardInfo, MessageImportInfo importInfo, MessageInteractionInfo interactionInfo, UnreadReaction[] unreadReactions, FactCheck factCheck, SuggestedPostInfo suggestedPostInfo, MessageReplyTo replyTo, MessageTopic topicId, MessageSelfDestructType selfDestructType, double selfDestructIn, double autoDeleteIn, long viaBotUserId, long senderBusinessBotUserId, int senderBoostCount, String senderTag, long paidMessageStarCount, String authorSignature, long mediaAlbumId, long effectId, RestrictionInfo restrictionInfo, String summaryLanguageCode, MessageContent content, ReplyMarkup replyMarkup) { - this.id = id; - this.senderId = senderId; - this.chatId = chatId; - this.sendingState = sendingState; - this.schedulingState = schedulingState; - this.isOutgoing = isOutgoing; - this.isPinned = isPinned; - this.isFromOffline = isFromOffline; - this.canBeSaved = canBeSaved; - this.hasTimestampedMedia = hasTimestampedMedia; - this.isChannelPost = isChannelPost; - this.isPaidStarSuggestedPost = isPaidStarSuggestedPost; - this.isPaidTonSuggestedPost = isPaidTonSuggestedPost; - this.containsUnreadMention = containsUnreadMention; - this.date = date; - this.editDate = editDate; - this.forwardInfo = forwardInfo; - this.importInfo = importInfo; - this.interactionInfo = interactionInfo; - this.unreadReactions = unreadReactions; - this.factCheck = factCheck; - this.suggestedPostInfo = suggestedPostInfo; - this.replyTo = replyTo; - this.topicId = topicId; - this.selfDestructType = selfDestructType; - this.selfDestructIn = selfDestructIn; - this.autoDeleteIn = autoDeleteIn; - this.viaBotUserId = viaBotUserId; - this.senderBusinessBotUserId = senderBusinessBotUserId; - this.senderBoostCount = senderBoostCount; - this.senderTag = senderTag; - this.paidMessageStarCount = paidMessageStarCount; - this.authorSignature = authorSignature; - this.mediaAlbumId = mediaAlbumId; - this.effectId = effectId; - this.restrictionInfo = restrictionInfo; - this.summaryLanguageCode = summaryLanguageCode; - this.content = content; - this.replyMarkup = replyMarkup; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 284850729; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains default auto-delete timer setting for new chats. - */ - public static class MessageAutoDeleteTime extends Object { - /** - * Message auto-delete time, in seconds. If 0, then messages aren't deleted automatically. - */ - public int time; - - /** - * Contains default auto-delete timer setting for new chats. - */ - public MessageAutoDeleteTime() { - } - - /** - * Contains default auto-delete timer setting for new chats. - * - * @param time Message auto-delete time, in seconds. If 0, then messages aren't deleted automatically. - */ - public MessageAutoDeleteTime(int time) { - this.time = time; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1972045589; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about found messages, split by days according to the option "utc_time_offset". - */ - public static class MessageCalendar extends Object { - /** - * Total number of found messages. - */ - public int totalCount; - /** - * Information about messages sent. - */ - public MessageCalendarDay[] days; - - /** - * Contains information about found messages, split by days according to the option "utc_time_offset". - */ - public MessageCalendar() { - } - - /** - * Contains information about found messages, split by days according to the option "utc_time_offset". - * - * @param totalCount Total number of found messages. - * @param days Information about messages sent. - */ - public MessageCalendar(int totalCount, MessageCalendarDay[] days) { - this.totalCount = totalCount; - this.days = days; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1682890519; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about found messages sent on a specific day. - */ - public static class MessageCalendarDay extends Object { - /** - * Total number of found messages sent on the day. - */ - public int totalCount; - /** - * First message sent on the day. - */ - public Message message; - - /** - * Contains information about found messages sent on a specific day. - */ - public MessageCalendarDay() { - } - - /** - * Contains information about found messages sent on a specific day. - * - * @param totalCount Total number of found messages sent on the day. - * @param message First message sent on the day. - */ - public MessageCalendarDay(int totalCount, Message message) { - this.totalCount = totalCount; - this.message = message; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -376467614; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains the content of a message. - */ - public abstract static class MessageContent extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - MessageText.CONSTRUCTOR, - MessageAnimation.CONSTRUCTOR, - MessageAudio.CONSTRUCTOR, - MessageDocument.CONSTRUCTOR, - MessagePaidMedia.CONSTRUCTOR, - MessagePhoto.CONSTRUCTOR, - MessageSticker.CONSTRUCTOR, - MessageVideo.CONSTRUCTOR, - MessageVideoNote.CONSTRUCTOR, - MessageVoiceNote.CONSTRUCTOR, - MessageExpiredPhoto.CONSTRUCTOR, - MessageExpiredVideo.CONSTRUCTOR, - MessageExpiredVideoNote.CONSTRUCTOR, - MessageExpiredVoiceNote.CONSTRUCTOR, - MessageLocation.CONSTRUCTOR, - MessageVenue.CONSTRUCTOR, - MessageContact.CONSTRUCTOR, - MessageAnimatedEmoji.CONSTRUCTOR, - MessageDice.CONSTRUCTOR, - MessageGame.CONSTRUCTOR, - MessagePoll.CONSTRUCTOR, - MessageStakeDice.CONSTRUCTOR, - MessageStory.CONSTRUCTOR, - MessageChecklist.CONSTRUCTOR, - MessageInvoice.CONSTRUCTOR, - MessageCall.CONSTRUCTOR, - MessageGroupCall.CONSTRUCTOR, - MessageVideoChatScheduled.CONSTRUCTOR, - MessageVideoChatStarted.CONSTRUCTOR, - MessageVideoChatEnded.CONSTRUCTOR, - MessageInviteVideoChatParticipants.CONSTRUCTOR, - MessageBasicGroupChatCreate.CONSTRUCTOR, - MessageSupergroupChatCreate.CONSTRUCTOR, - MessageChatChangeTitle.CONSTRUCTOR, - MessageChatChangePhoto.CONSTRUCTOR, - MessageChatDeletePhoto.CONSTRUCTOR, - MessageChatOwnerLeft.CONSTRUCTOR, - MessageChatOwnerChanged.CONSTRUCTOR, - MessageChatHasProtectedContentToggled.CONSTRUCTOR, - MessageChatHasProtectedContentDisableRequested.CONSTRUCTOR, - MessageChatAddMembers.CONSTRUCTOR, - MessageChatJoinByLink.CONSTRUCTOR, - MessageChatJoinByRequest.CONSTRUCTOR, - MessageChatDeleteMember.CONSTRUCTOR, - MessageChatUpgradeTo.CONSTRUCTOR, - MessageChatUpgradeFrom.CONSTRUCTOR, - MessagePinMessage.CONSTRUCTOR, - MessageScreenshotTaken.CONSTRUCTOR, - MessageChatSetBackground.CONSTRUCTOR, - MessageChatSetTheme.CONSTRUCTOR, - MessageChatSetMessageAutoDeleteTime.CONSTRUCTOR, - MessageChatBoost.CONSTRUCTOR, - MessageForumTopicCreated.CONSTRUCTOR, - MessageForumTopicEdited.CONSTRUCTOR, - MessageForumTopicIsClosedToggled.CONSTRUCTOR, - MessageForumTopicIsHiddenToggled.CONSTRUCTOR, - MessageSuggestProfilePhoto.CONSTRUCTOR, - MessageSuggestBirthdate.CONSTRUCTOR, - MessageCustomServiceAction.CONSTRUCTOR, - MessageGameScore.CONSTRUCTOR, - MessagePaymentSuccessful.CONSTRUCTOR, - MessagePaymentSuccessfulBot.CONSTRUCTOR, - MessagePaymentRefunded.CONSTRUCTOR, - MessageGiftedPremium.CONSTRUCTOR, - MessagePremiumGiftCode.CONSTRUCTOR, - MessageGiveawayCreated.CONSTRUCTOR, - MessageGiveaway.CONSTRUCTOR, - MessageGiveawayCompleted.CONSTRUCTOR, - MessageGiveawayWinners.CONSTRUCTOR, - MessageGiftedStars.CONSTRUCTOR, - MessageGiftedTon.CONSTRUCTOR, - MessageGiveawayPrizeStars.CONSTRUCTOR, - MessageGift.CONSTRUCTOR, - MessageUpgradedGift.CONSTRUCTOR, - MessageRefundedUpgradedGift.CONSTRUCTOR, - MessageUpgradedGiftPurchaseOffer.CONSTRUCTOR, - MessageUpgradedGiftPurchaseOfferRejected.CONSTRUCTOR, - MessagePaidMessagesRefunded.CONSTRUCTOR, - MessagePaidMessagePriceChanged.CONSTRUCTOR, - MessageDirectMessagePriceChanged.CONSTRUCTOR, - MessageChecklistTasksDone.CONSTRUCTOR, - MessageChecklistTasksAdded.CONSTRUCTOR, - MessageSuggestedPostApprovalFailed.CONSTRUCTOR, - MessageSuggestedPostApproved.CONSTRUCTOR, - MessageSuggestedPostDeclined.CONSTRUCTOR, - MessageSuggestedPostPaid.CONSTRUCTOR, - MessageSuggestedPostRefunded.CONSTRUCTOR, - MessageContactRegistered.CONSTRUCTOR, - MessageUsersShared.CONSTRUCTOR, - MessageChatShared.CONSTRUCTOR, - MessageBotWriteAccessAllowed.CONSTRUCTOR, - MessageWebAppDataSent.CONSTRUCTOR, - MessageWebAppDataReceived.CONSTRUCTOR, - MessagePassportDataSent.CONSTRUCTOR, - MessagePassportDataReceived.CONSTRUCTOR, - MessageProximityAlertTriggered.CONSTRUCTOR, - MessageUnsupported.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public MessageContent() { - } - } - - /** - * A text message. - */ - public static class MessageText extends MessageContent { - /** - * Text of the message. - */ - public FormattedText text; - /** - * A link preview attached to the message; may be null. - */ - @Nullable public LinkPreview linkPreview; - /** - * Options which were used for generation of the link preview; may be null if default options were used. - */ - @Nullable public LinkPreviewOptions linkPreviewOptions; - - /** - * A text message. - */ - public MessageText() { - } - - /** - * A text message. - * - * @param text Text of the message. - * @param linkPreview A link preview attached to the message; may be null. - * @param linkPreviewOptions Options which were used for generation of the link preview; may be null if default options were used. - */ - public MessageText(FormattedText text, LinkPreview linkPreview, LinkPreviewOptions linkPreviewOptions) { - this.text = text; - this.linkPreview = linkPreview; - this.linkPreviewOptions = linkPreviewOptions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1751469188; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An animation message (GIF-style). - */ - public static class MessageAnimation extends MessageContent { - /** - * The animation description. - */ - public Animation animation; - /** - * Animation caption. - */ - public FormattedText caption; - /** - * True, if the caption must be shown above the animation; otherwise, the caption must be shown below the animation. - */ - public boolean showCaptionAboveMedia; - /** - * True, if the animation preview must be covered by a spoiler animation. - */ - public boolean hasSpoiler; - /** - * True, if the animation thumbnail must be blurred and the animation must be shown only while tapped. - */ - public boolean isSecret; - - /** - * An animation message (GIF-style). - */ - public MessageAnimation() { - } - - /** - * An animation message (GIF-style). - * - * @param animation The animation description. - * @param caption Animation caption. - * @param showCaptionAboveMedia True, if the caption must be shown above the animation; otherwise, the caption must be shown below the animation. - * @param hasSpoiler True, if the animation preview must be covered by a spoiler animation. - * @param isSecret True, if the animation thumbnail must be blurred and the animation must be shown only while tapped. - */ - public MessageAnimation(Animation animation, FormattedText caption, boolean showCaptionAboveMedia, boolean hasSpoiler, boolean isSecret) { - this.animation = animation; - this.caption = caption; - this.showCaptionAboveMedia = showCaptionAboveMedia; - this.hasSpoiler = hasSpoiler; - this.isSecret = isSecret; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1899294424; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An audio message. - */ - public static class MessageAudio extends MessageContent { - /** - * The audio description. - */ - public Audio audio; - /** - * Audio caption. - */ - public FormattedText caption; - - /** - * An audio message. - */ - public MessageAudio() { - } - - /** - * An audio message. - * - * @param audio The audio description. - * @param caption Audio caption. - */ - public MessageAudio(Audio audio, FormattedText caption) { - this.audio = audio; - this.caption = caption; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 276722716; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A document message (general file). - */ - public static class MessageDocument extends MessageContent { - /** - * The document description. - */ - public Document document; - /** - * Document caption. - */ - public FormattedText caption; - - /** - * A document message (general file). - */ - public MessageDocument() { - } - - /** - * A document message (general file). - * - * @param document The document description. - * @param caption Document caption. - */ - public MessageDocument(Document document, FormattedText caption) { - this.document = document; - this.caption = caption; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 596945783; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with paid media. - */ - public static class MessagePaidMedia extends MessageContent { - /** - * Number of Telegram Stars needed to buy access to the media in the message. - */ - public long starCount; - /** - * Information about the media. - */ - public PaidMedia[] media; - /** - * Media caption. - */ - public FormattedText caption; - /** - * True, if the caption must be shown above the media; otherwise, the caption must be shown below the media. - */ - public boolean showCaptionAboveMedia; - - /** - * A message with paid media. - */ - public MessagePaidMedia() { - } - - /** - * A message with paid media. - * - * @param starCount Number of Telegram Stars needed to buy access to the media in the message. - * @param media Information about the media. - * @param caption Media caption. - * @param showCaptionAboveMedia True, if the caption must be shown above the media; otherwise, the caption must be shown below the media. - */ - public MessagePaidMedia(long starCount, PaidMedia[] media, FormattedText caption, boolean showCaptionAboveMedia) { - this.starCount = starCount; - this.media = media; - this.caption = caption; - this.showCaptionAboveMedia = showCaptionAboveMedia; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -724750073; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A photo message. - */ - public static class MessagePhoto extends MessageContent { - /** - * The photo. - */ - public Photo photo; - /** - * Photo caption. - */ - public FormattedText caption; - /** - * True, if the caption must be shown above the photo; otherwise, the caption must be shown below the photo. - */ - public boolean showCaptionAboveMedia; - /** - * True, if the photo preview must be covered by a spoiler animation. - */ - public boolean hasSpoiler; - /** - * True, if the photo must be blurred and must be shown only while tapped. - */ - public boolean isSecret; - - /** - * A photo message. - */ - public MessagePhoto() { - } - - /** - * A photo message. - * - * @param photo The photo. - * @param caption Photo caption. - * @param showCaptionAboveMedia True, if the caption must be shown above the photo; otherwise, the caption must be shown below the photo. - * @param hasSpoiler True, if the photo preview must be covered by a spoiler animation. - * @param isSecret True, if the photo must be blurred and must be shown only while tapped. - */ - public MessagePhoto(Photo photo, FormattedText caption, boolean showCaptionAboveMedia, boolean hasSpoiler, boolean isSecret) { - this.photo = photo; - this.caption = caption; - this.showCaptionAboveMedia = showCaptionAboveMedia; - this.hasSpoiler = hasSpoiler; - this.isSecret = isSecret; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1967947295; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A sticker message. - */ - public static class MessageSticker extends MessageContent { - /** - * The sticker description. - */ - public Sticker sticker; - /** - * True, if premium animation of the sticker must be played. - */ - public boolean isPremium; - - /** - * A sticker message. - */ - public MessageSticker() { - } - - /** - * A sticker message. - * - * @param sticker The sticker description. - * @param isPremium True, if premium animation of the sticker must be played. - */ - public MessageSticker(Sticker sticker, boolean isPremium) { - this.sticker = sticker; - this.isPremium = isPremium; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -437199670; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A video message. - */ - public static class MessageVideo extends MessageContent { - /** - * The video description. - */ - public Video video; - /** - * Alternative qualities of the video. - */ - public AlternativeVideo[] alternativeVideos; - /** - * Available storyboards for the video. - */ - public VideoStoryboard[] storyboards; - /** - * Cover of the video; may be null if none. - */ - @Nullable public Photo cover; - /** - * Timestamp from which the video playing must start, in seconds. - */ - public int startTimestamp; - /** - * Video caption. - */ - public FormattedText caption; - /** - * True, if the caption must be shown above the video; otherwise, the caption must be shown below the video. - */ - public boolean showCaptionAboveMedia; - /** - * True, if the video preview must be covered by a spoiler animation. - */ - public boolean hasSpoiler; - /** - * True, if the video thumbnail must be blurred and the video must be shown only while tapped. - */ - public boolean isSecret; - - /** - * A video message. - */ - public MessageVideo() { - } - - /** - * A video message. - * - * @param video The video description. - * @param alternativeVideos Alternative qualities of the video. - * @param storyboards Available storyboards for the video. - * @param cover Cover of the video; may be null if none. - * @param startTimestamp Timestamp from which the video playing must start, in seconds. - * @param caption Video caption. - * @param showCaptionAboveMedia True, if the caption must be shown above the video; otherwise, the caption must be shown below the video. - * @param hasSpoiler True, if the video preview must be covered by a spoiler animation. - * @param isSecret True, if the video thumbnail must be blurred and the video must be shown only while tapped. - */ - public MessageVideo(Video video, AlternativeVideo[] alternativeVideos, VideoStoryboard[] storyboards, Photo cover, int startTimestamp, FormattedText caption, boolean showCaptionAboveMedia, boolean hasSpoiler, boolean isSecret) { - this.video = video; - this.alternativeVideos = alternativeVideos; - this.storyboards = storyboards; - this.cover = cover; - this.startTimestamp = startTimestamp; - this.caption = caption; - this.showCaptionAboveMedia = showCaptionAboveMedia; - this.hasSpoiler = hasSpoiler; - this.isSecret = isSecret; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 952522912; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A video note message. - */ - public static class MessageVideoNote extends MessageContent { - /** - * The video note description. - */ - public VideoNote videoNote; - /** - * True, if at least one of the recipients has viewed the video note. - */ - public boolean isViewed; - /** - * True, if the video note thumbnail must be blurred and the video note must be shown only while tapped. - */ - public boolean isSecret; - - /** - * A video note message. - */ - public MessageVideoNote() { - } - - /** - * A video note message. - * - * @param videoNote The video note description. - * @param isViewed True, if at least one of the recipients has viewed the video note. - * @param isSecret True, if the video note thumbnail must be blurred and the video note must be shown only while tapped. - */ - public MessageVideoNote(VideoNote videoNote, boolean isViewed, boolean isSecret) { - this.videoNote = videoNote; - this.isViewed = isViewed; - this.isSecret = isSecret; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 963323014; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A voice note message. - */ - public static class MessageVoiceNote extends MessageContent { - /** - * The voice note description. - */ - public VoiceNote voiceNote; - /** - * Voice note caption. - */ - public FormattedText caption; - /** - * True, if at least one of the recipients has listened to the voice note. - */ - public boolean isListened; - - /** - * A voice note message. - */ - public MessageVoiceNote() { - } - - /** - * A voice note message. - * - * @param voiceNote The voice note description. - * @param caption Voice note caption. - * @param isListened True, if at least one of the recipients has listened to the voice note. - */ - public MessageVoiceNote(VoiceNote voiceNote, FormattedText caption, boolean isListened) { - this.voiceNote = voiceNote; - this.caption = caption; - this.isListened = isListened; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 527777781; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A self-destructed photo message. - */ - public static class MessageExpiredPhoto extends MessageContent { - - /** - * A self-destructed photo message. - */ - public MessageExpiredPhoto() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1404641801; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A self-destructed video message. - */ - public static class MessageExpiredVideo extends MessageContent { - - /** - * A self-destructed video message. - */ - public MessageExpiredVideo() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1212209981; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A self-destructed video note message. - */ - public static class MessageExpiredVideoNote extends MessageContent { - - /** - * A self-destructed video note message. - */ - public MessageExpiredVideoNote() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 599540711; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A self-destructed voice note message. - */ - public static class MessageExpiredVoiceNote extends MessageContent { - - /** - * A self-destructed voice note message. - */ - public MessageExpiredVoiceNote() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 143684989; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a location. - */ - public static class MessageLocation extends MessageContent { - /** - * The location description. - */ - public Location location; - /** - * Time relative to the message send date, for which the location can be updated, in seconds; if 0x7FFFFFFF, then location can be updated forever. - */ - public int livePeriod; - /** - * Left time for which the location can be updated, in seconds. If 0, then the location can't be updated anymore. The update updateMessageContent is not sent when this field changes. - */ - public int expiresIn; - /** - * For live locations, a direction in which the location moves, in degrees; 1-360. If 0 the direction is unknown. - */ - public int heading; - /** - * For live locations, a maximum distance to another chat member for proximity alerts, in meters (0-100000). 0 if the notification is disabled. Available only to the message sender. - */ - public int proximityAlertRadius; - - /** - * A message with a location. - */ - public MessageLocation() { - } - - /** - * A message with a location. - * - * @param location The location description. - * @param livePeriod Time relative to the message send date, for which the location can be updated, in seconds; if 0x7FFFFFFF, then location can be updated forever. - * @param expiresIn Left time for which the location can be updated, in seconds. If 0, then the location can't be updated anymore. The update updateMessageContent is not sent when this field changes. - * @param heading For live locations, a direction in which the location moves, in degrees; 1-360. If 0 the direction is unknown. - * @param proximityAlertRadius For live locations, a maximum distance to another chat member for proximity alerts, in meters (0-100000). 0 if the notification is disabled. Available only to the message sender. - */ - public MessageLocation(Location location, int livePeriod, int expiresIn, int heading, int proximityAlertRadius) { - this.location = location; - this.livePeriod = livePeriod; - this.expiresIn = expiresIn; - this.heading = heading; - this.proximityAlertRadius = proximityAlertRadius; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 303973492; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with information about a venue. - */ - public static class MessageVenue extends MessageContent { - /** - * The venue description. - */ - public Venue venue; - - /** - * A message with information about a venue. - */ - public MessageVenue() { - } - - /** - * A message with information about a venue. - * - * @param venue The venue description. - */ - public MessageVenue(Venue venue) { - this.venue = venue; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2146492043; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a user contact. - */ - public static class MessageContact extends MessageContent { - /** - * The contact description. - */ - public Contact contact; - - /** - * A message with a user contact. - */ - public MessageContact() { - } - - /** - * A message with a user contact. - * - * @param contact The contact description. - */ - public MessageContact(Contact contact) { - this.contact = contact; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -512684966; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with an animated emoji. - */ - public static class MessageAnimatedEmoji extends MessageContent { - /** - * The animated emoji. - */ - public AnimatedEmoji animatedEmoji; - /** - * The corresponding emoji. - */ - public String emoji; - - /** - * A message with an animated emoji. - */ - public MessageAnimatedEmoji() { - } - - /** - * A message with an animated emoji. - * - * @param animatedEmoji The animated emoji. - * @param emoji The corresponding emoji. - */ - public MessageAnimatedEmoji(AnimatedEmoji animatedEmoji, String emoji) { - this.animatedEmoji = animatedEmoji; - this.emoji = emoji; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 908195298; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A dice message. The dice value is randomly generated by the server. - */ - public static class MessageDice extends MessageContent { - /** - * The animated stickers with the initial dice animation; may be null if unknown. The update updateMessageContent will be sent when the sticker became known. - */ - @Nullable public DiceStickers initialState; - /** - * The animated stickers with the final dice animation; may be null if unknown. The update updateMessageContent will be sent when the sticker became known. - */ - @Nullable public DiceStickers finalState; - /** - * Emoji on which the dice throw animation is based. - */ - public String emoji; - /** - * The dice value. If the value is 0, then the dice don't have final state yet. - */ - public int value; - /** - * Number of frame after which a success animation like a shower of confetti needs to be shown on updateMessageSendSucceeded. - */ - public int successAnimationFrameNumber; - - /** - * A dice message. The dice value is randomly generated by the server. - */ - public MessageDice() { - } - - /** - * A dice message. The dice value is randomly generated by the server. - * - * @param initialState The animated stickers with the initial dice animation; may be null if unknown. The update updateMessageContent will be sent when the sticker became known. - * @param finalState The animated stickers with the final dice animation; may be null if unknown. The update updateMessageContent will be sent when the sticker became known. - * @param emoji Emoji on which the dice throw animation is based. - * @param value The dice value. If the value is 0, then the dice don't have final state yet. - * @param successAnimationFrameNumber Number of frame after which a success animation like a shower of confetti needs to be shown on updateMessageSendSucceeded. - */ - public MessageDice(DiceStickers initialState, DiceStickers finalState, String emoji, int value, int successAnimationFrameNumber) { - this.initialState = initialState; - this.finalState = finalState; - this.emoji = emoji; - this.value = value; - this.successAnimationFrameNumber = successAnimationFrameNumber; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1115779641; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a game. - */ - public static class MessageGame extends MessageContent { - /** - * The game description. - */ - public Game game; - - /** - * A message with a game. - */ - public MessageGame() { - } - - /** - * A message with a game. - * - * @param game The game description. - */ - public MessageGame(Game game) { - this.game = game; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -69441162; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a poll. - */ - public static class MessagePoll extends MessageContent { - /** - * The poll description. - */ - public Poll poll; - - /** - * A message with a poll. - */ - public MessagePoll() { - } - - /** - * A message with a poll. - * - * @param poll The poll description. - */ - public MessagePoll(Poll poll) { - this.poll = poll; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -662130099; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A stake dice message. The dice value is randomly generated by the server. - */ - public static class MessageStakeDice extends MessageContent { - /** - * The animated stickers with the initial dice animation; may be null if unknown. The update updateMessageContent will be sent when the sticker became known. - */ - @Nullable public DiceStickers initialState; - /** - * The animated stickers with the final dice animation; may be null if unknown. The update updateMessageContent will be sent when the sticker became known. - */ - @Nullable public DiceStickers finalState; - /** - * The dice value. If the value is 0, then the dice don't have final state yet. - */ - public int value; - /** - * The Toncoin amount that was staked; in the smallest units of the currency. - */ - public long stakeToncoinAmount; - /** - * The Toncoin amount that was gained from the roll; in the smallest units of the currency; -1 if the dice don't have final state yet. - */ - public long prizeToncoinAmount; - - /** - * A stake dice message. The dice value is randomly generated by the server. - */ - public MessageStakeDice() { - } - - /** - * A stake dice message. The dice value is randomly generated by the server. - * - * @param initialState The animated stickers with the initial dice animation; may be null if unknown. The update updateMessageContent will be sent when the sticker became known. - * @param finalState The animated stickers with the final dice animation; may be null if unknown. The update updateMessageContent will be sent when the sticker became known. - * @param value The dice value. If the value is 0, then the dice don't have final state yet. - * @param stakeToncoinAmount The Toncoin amount that was staked; in the smallest units of the currency. - * @param prizeToncoinAmount The Toncoin amount that was gained from the roll; in the smallest units of the currency; -1 if the dice don't have final state yet. - */ - public MessageStakeDice(DiceStickers initialState, DiceStickers finalState, int value, long stakeToncoinAmount, long prizeToncoinAmount) { - this.initialState = initialState; - this.finalState = finalState; - this.value = value; - this.stakeToncoinAmount = stakeToncoinAmount; - this.prizeToncoinAmount = prizeToncoinAmount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 844428448; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a forwarded story. - */ - public static class MessageStory extends MessageContent { - /** - * Identifier of the chat that posted the story. - */ - public long storyPosterChatId; - /** - * Story identifier. - */ - public int storyId; - /** - * True, if the story was automatically forwarded because of a mention of the user. - */ - public boolean viaMention; - - /** - * A message with a forwarded story. - */ - public MessageStory() { - } - - /** - * A message with a forwarded story. - * - * @param storyPosterChatId Identifier of the chat that posted the story. - * @param storyId Story identifier. - * @param viaMention True, if the story was automatically forwarded because of a mention of the user. - */ - public MessageStory(long storyPosterChatId, int storyId, boolean viaMention) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - this.viaMention = viaMention; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1514236353; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a checklist. - */ - public static class MessageChecklist extends MessageContent { - /** - * The checklist description. - */ - public Checklist list; - - /** - * A message with a checklist. - */ - public MessageChecklist() { - } - - /** - * A message with a checklist. - * - * @param list The checklist description. - */ - public MessageChecklist(Checklist list) { - this.list = list; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 609926697; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with an invoice from a bot. Use getInternalLink with internalLinkTypeBotStart to share the invoice. - */ - public static class MessageInvoice extends MessageContent { - /** - * Information about the product. - */ - public ProductInfo productInfo; - /** - * Currency for the product price. - */ - public String currency; - /** - * Product total price in the smallest units of the currency. - */ - public long totalAmount; - /** - * Unique invoice bot startParameter to be passed to getInternalLink. - */ - public String startParameter; - /** - * True, if the invoice is a test invoice. - */ - public boolean isTest; - /** - * True, if the shipping address must be specified. - */ - public boolean needShippingAddress; - /** - * The identifier of the message with the receipt, after the product has been purchased. - */ - public long receiptMessageId; - /** - * Extended media attached to the invoice; may be null if none. - */ - @Nullable public PaidMedia paidMedia; - /** - * Extended media caption; may be null if none. - */ - @Nullable public FormattedText paidMediaCaption; - - /** - * A message with an invoice from a bot. Use getInternalLink with internalLinkTypeBotStart to share the invoice. - */ - public MessageInvoice() { - } - - /** - * A message with an invoice from a bot. Use getInternalLink with internalLinkTypeBotStart to share the invoice. - * - * @param productInfo Information about the product. - * @param currency Currency for the product price. - * @param totalAmount Product total price in the smallest units of the currency. - * @param startParameter Unique invoice bot startParameter to be passed to getInternalLink. - * @param isTest True, if the invoice is a test invoice. - * @param needShippingAddress True, if the shipping address must be specified. - * @param receiptMessageId The identifier of the message with the receipt, after the product has been purchased. - * @param paidMedia Extended media attached to the invoice; may be null if none. - * @param paidMediaCaption Extended media caption; may be null if none. - */ - public MessageInvoice(ProductInfo productInfo, String currency, long totalAmount, String startParameter, boolean isTest, boolean needShippingAddress, long receiptMessageId, PaidMedia paidMedia, FormattedText paidMediaCaption) { - this.productInfo = productInfo; - this.currency = currency; - this.totalAmount = totalAmount; - this.startParameter = startParameter; - this.isTest = isTest; - this.needShippingAddress = needShippingAddress; - this.receiptMessageId = receiptMessageId; - this.paidMedia = paidMedia; - this.paidMediaCaption = paidMediaCaption; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 263060806; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with information about an ended call. - */ - public static class MessageCall extends MessageContent { - /** - * Persistent unique call identifier; 0 for calls from other devices, which can't be passed as inputCallFromMessage. - */ - public long uniqueId; - /** - * True, if the call was a video call. - */ - public boolean isVideo; - /** - * Reason why the call was discarded. - */ - public CallDiscardReason discardReason; - /** - * Call duration, in seconds. - */ - public int duration; - - /** - * A message with information about an ended call. - */ - public MessageCall() { - } - - /** - * A message with information about an ended call. - * - * @param uniqueId Persistent unique call identifier; 0 for calls from other devices, which can't be passed as inputCallFromMessage. - * @param isVideo True, if the call was a video call. - * @param discardReason Reason why the call was discarded. - * @param duration Call duration, in seconds. - */ - public MessageCall(long uniqueId, boolean isVideo, CallDiscardReason discardReason, int duration) { - this.uniqueId = uniqueId; - this.isVideo = isVideo; - this.discardReason = discardReason; - this.duration = duration; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 142247375; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with information about a group call not bound to a chat. If the message is incoming, the call isn't active, isn't missed, and has no duration, and getOption("can_accept_calls") is true, then incoming call screen must be shown to the user. Use getGroupCallParticipants to show current group call participants on the screen. Use joinGroupCall to accept the call or declineGroupCallInvitation to decline it. If the call become active or missed, then the call screen must be hidden. - */ - public static class MessageGroupCall extends MessageContent { - /** - * Persistent unique group call identifier. - */ - public long uniqueId; - /** - * True, if the call is active, i.e. the called user joined the call. - */ - public boolean isActive; - /** - * True, if the called user missed or declined the call. - */ - public boolean wasMissed; - /** - * True, if the call is a video call. - */ - public boolean isVideo; - /** - * Call duration, in seconds; for left calls only. - */ - public int duration; - /** - * Identifiers of some other call participants. - */ - public MessageSender[] otherParticipantIds; - - /** - * A message with information about a group call not bound to a chat. If the message is incoming, the call isn't active, isn't missed, and has no duration, and getOption("can_accept_calls") is true, then incoming call screen must be shown to the user. Use getGroupCallParticipants to show current group call participants on the screen. Use joinGroupCall to accept the call or declineGroupCallInvitation to decline it. If the call become active or missed, then the call screen must be hidden. - */ - public MessageGroupCall() { - } - - /** - * A message with information about a group call not bound to a chat. If the message is incoming, the call isn't active, isn't missed, and has no duration, and getOption("can_accept_calls") is true, then incoming call screen must be shown to the user. Use getGroupCallParticipants to show current group call participants on the screen. Use joinGroupCall to accept the call or declineGroupCallInvitation to decline it. If the call become active or missed, then the call screen must be hidden. - * - * @param uniqueId Persistent unique group call identifier. - * @param isActive True, if the call is active, i.e. the called user joined the call. - * @param wasMissed True, if the called user missed or declined the call. - * @param isVideo True, if the call is a video call. - * @param duration Call duration, in seconds; for left calls only. - * @param otherParticipantIds Identifiers of some other call participants. - */ - public MessageGroupCall(long uniqueId, boolean isActive, boolean wasMissed, boolean isVideo, int duration, MessageSender[] otherParticipantIds) { - this.uniqueId = uniqueId; - this.isActive = isActive; - this.wasMissed = wasMissed; - this.isVideo = isVideo; - this.duration = duration; - this.otherParticipantIds = otherParticipantIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1735752741; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new video chat was scheduled. - */ - public static class MessageVideoChatScheduled extends MessageContent { - /** - * Identifier of the video chat. The video chat can be received through the method getGroupCall. - */ - public int groupCallId; - /** - * Point in time (Unix timestamp) when the group call is expected to be started by an administrator. - */ - public int startDate; - - /** - * A new video chat was scheduled. - */ - public MessageVideoChatScheduled() { - } - - /** - * A new video chat was scheduled. - * - * @param groupCallId Identifier of the video chat. The video chat can be received through the method getGroupCall. - * @param startDate Point in time (Unix timestamp) when the group call is expected to be started by an administrator. - */ - public MessageVideoChatScheduled(int groupCallId, int startDate) { - this.groupCallId = groupCallId; - this.startDate = startDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1855185481; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A newly created video chat. - */ - public static class MessageVideoChatStarted extends MessageContent { - /** - * Identifier of the video chat. The video chat can be received through the method getGroupCall. - */ - public int groupCallId; - - /** - * A newly created video chat. - */ - public MessageVideoChatStarted() { - } - - /** - * A newly created video chat. - * - * @param groupCallId Identifier of the video chat. The video chat can be received through the method getGroupCall. - */ - public MessageVideoChatStarted(int groupCallId) { - this.groupCallId = groupCallId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 521225561; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with information about an ended video chat. - */ - public static class MessageVideoChatEnded extends MessageContent { - /** - * Call duration, in seconds. - */ - public int duration; - - /** - * A message with information about an ended video chat. - */ - public MessageVideoChatEnded() { - } - - /** - * A message with information about an ended video chat. - * - * @param duration Call duration, in seconds. - */ - public MessageVideoChatEnded(int duration) { - this.duration = duration; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2032544855; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with information about an invitation to a video chat. - */ - public static class MessageInviteVideoChatParticipants extends MessageContent { - /** - * Identifier of the video chat. The video chat can be received through the method getGroupCall. - */ - public int groupCallId; - /** - * Invited user identifiers. - */ - public long[] userIds; - - /** - * A message with information about an invitation to a video chat. - */ - public MessageInviteVideoChatParticipants() { - } - - /** - * A message with information about an invitation to a video chat. - * - * @param groupCallId Identifier of the video chat. The video chat can be received through the method getGroupCall. - * @param userIds Invited user identifiers. - */ - public MessageInviteVideoChatParticipants(int groupCallId, long[] userIds) { - this.groupCallId = groupCallId; - this.userIds = userIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1459065585; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A newly created basic group. - */ - public static class MessageBasicGroupChatCreate extends MessageContent { - /** - * Title of the basic group. - */ - public String title; - /** - * User identifiers of members in the basic group. - */ - public long[] memberUserIds; - - /** - * A newly created basic group. - */ - public MessageBasicGroupChatCreate() { - } - - /** - * A newly created basic group. - * - * @param title Title of the basic group. - * @param memberUserIds User identifiers of members in the basic group. - */ - public MessageBasicGroupChatCreate(String title, long[] memberUserIds) { - this.title = title; - this.memberUserIds = memberUserIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 795404060; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A newly created supergroup or channel. - */ - public static class MessageSupergroupChatCreate extends MessageContent { - /** - * Title of the supergroup or channel. - */ - public String title; - - /** - * A newly created supergroup or channel. - */ - public MessageSupergroupChatCreate() { - } - - /** - * A newly created supergroup or channel. - * - * @param title Title of the supergroup or channel. - */ - public MessageSupergroupChatCreate(String title) { - this.title = title; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -434325733; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An updated chat title. - */ - public static class MessageChatChangeTitle extends MessageContent { - /** - * New chat title. - */ - public String title; - - /** - * An updated chat title. - */ - public MessageChatChangeTitle() { - } - - /** - * An updated chat title. - * - * @param title New chat title. - */ - public MessageChatChangeTitle(String title) { - this.title = title; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 748272449; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An updated chat photo. - */ - public static class MessageChatChangePhoto extends MessageContent { - /** - * New chat photo. - */ - public ChatPhoto photo; - - /** - * An updated chat photo. - */ - public MessageChatChangePhoto() { - } - - /** - * An updated chat photo. - * - * @param photo New chat photo. - */ - public MessageChatChangePhoto(ChatPhoto photo) { - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -813415093; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A deleted chat photo. - */ - public static class MessageChatDeletePhoto extends MessageContent { - - /** - * A deleted chat photo. - */ - public MessageChatDeletePhoto() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -184374809; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The owner of the chat has left. - */ - public static class MessageChatOwnerLeft extends MessageContent { - /** - * Identifier of the user who will become the new owner of the chat if the previous owner isn't return; 0 if none. - */ - public long newOwnerUserId; - - /** - * The owner of the chat has left. - */ - public MessageChatOwnerLeft() { - } - - /** - * The owner of the chat has left. - * - * @param newOwnerUserId Identifier of the user who will become the new owner of the chat if the previous owner isn't return; 0 if none. - */ - public MessageChatOwnerLeft(long newOwnerUserId) { - this.newOwnerUserId = newOwnerUserId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 391852540; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The owner of the chat has changed. - */ - public static class MessageChatOwnerChanged extends MessageContent { - /** - * Identifier of the user who is the new owner of the chat. - */ - public long newOwnerUserId; - - /** - * The owner of the chat has changed. - */ - public MessageChatOwnerChanged() { - } - - /** - * The owner of the chat has changed. - * - * @param newOwnerUserId Identifier of the user who is the new owner of the chat. - */ - public MessageChatOwnerChanged(long newOwnerUserId) { - this.newOwnerUserId = newOwnerUserId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1679665913; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Chat hasProtectedContent setting was changed or request to change it was rejected. - */ - public static class MessageChatHasProtectedContentToggled extends MessageContent { - /** - * Identifier of the message with the request to change the setting; can be an identifier of a deleted message or 0. - */ - public long requestMessageId; - /** - * Previous value of the setting. - */ - public boolean oldHasProtectedContent; - /** - * New value of the setting. - */ - public boolean newHasProtectedContent; - - /** - * Chat hasProtectedContent setting was changed or request to change it was rejected. - */ - public MessageChatHasProtectedContentToggled() { - } - - /** - * Chat hasProtectedContent setting was changed or request to change it was rejected. - * - * @param requestMessageId Identifier of the message with the request to change the setting; can be an identifier of a deleted message or 0. - * @param oldHasProtectedContent Previous value of the setting. - * @param newHasProtectedContent New value of the setting. - */ - public MessageChatHasProtectedContentToggled(long requestMessageId, boolean oldHasProtectedContent, boolean newHasProtectedContent) { - this.requestMessageId = requestMessageId; - this.oldHasProtectedContent = oldHasProtectedContent; - this.newHasProtectedContent = newHasProtectedContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -809083979; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Chat hasProtectedContent setting was requested to be disabled. - */ - public static class MessageChatHasProtectedContentDisableRequested extends MessageContent { - /** - * True, if the request has expired. - */ - public boolean isExpired; - - /** - * Chat hasProtectedContent setting was requested to be disabled. - */ - public MessageChatHasProtectedContentDisableRequested() { - } - - /** - * Chat hasProtectedContent setting was requested to be disabled. - * - * @param isExpired True, if the request has expired. - */ - public MessageChatHasProtectedContentDisableRequested(boolean isExpired) { - this.isExpired = isExpired; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 334722856; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * New chat members were added. - */ - public static class MessageChatAddMembers extends MessageContent { - /** - * User identifiers of the new members. - */ - public long[] memberUserIds; - - /** - * New chat members were added. - */ - public MessageChatAddMembers() { - } - - /** - * New chat members were added. - * - * @param memberUserIds User identifiers of the new members. - */ - public MessageChatAddMembers(long[] memberUserIds) { - this.memberUserIds = memberUserIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1701117908; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new member joined the chat via an invite link. - */ - public static class MessageChatJoinByLink extends MessageContent { - - /** - * A new member joined the chat via an invite link. - */ - public MessageChatJoinByLink() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1846493311; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new member was accepted to the chat by an administrator. - */ - public static class MessageChatJoinByRequest extends MessageContent { - - /** - * A new member was accepted to the chat by an administrator. - */ - public MessageChatJoinByRequest() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1195428732; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat member was deleted. - */ - public static class MessageChatDeleteMember extends MessageContent { - /** - * User identifier of the deleted chat member. - */ - public long userId; - - /** - * A chat member was deleted. - */ - public MessageChatDeleteMember() { - } - - /** - * A chat member was deleted. - * - * @param userId User identifier of the deleted chat member. - */ - public MessageChatDeleteMember(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 938029481; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A basic group was upgraded to a supergroup and was deactivated as the result. - */ - public static class MessageChatUpgradeTo extends MessageContent { - /** - * Identifier of the supergroup to which the basic group was upgraded. - */ - public long supergroupId; - - /** - * A basic group was upgraded to a supergroup and was deactivated as the result. - */ - public MessageChatUpgradeTo() { - } - - /** - * A basic group was upgraded to a supergroup and was deactivated as the result. - * - * @param supergroupId Identifier of the supergroup to which the basic group was upgraded. - */ - public MessageChatUpgradeTo(long supergroupId) { - this.supergroupId = supergroupId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 104813723; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A supergroup has been created from a basic group. - */ - public static class MessageChatUpgradeFrom extends MessageContent { - /** - * Title of the newly created supergroup. - */ - public String title; - /** - * The identifier of the original basic group. - */ - public long basicGroupId; - - /** - * A supergroup has been created from a basic group. - */ - public MessageChatUpgradeFrom() { - } - - /** - * A supergroup has been created from a basic group. - * - * @param title Title of the newly created supergroup. - * @param basicGroupId The identifier of the original basic group. - */ - public MessageChatUpgradeFrom(String title, long basicGroupId) { - this.title = title; - this.basicGroupId = basicGroupId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 325954268; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message has been pinned. - */ - public static class MessagePinMessage extends MessageContent { - /** - * Identifier of the pinned message, can be an identifier of a deleted message or 0. - */ - public long messageId; - - /** - * A message has been pinned. - */ - public MessagePinMessage() { - } - - /** - * A message has been pinned. - * - * @param messageId Identifier of the pinned message, can be an identifier of a deleted message or 0. - */ - public MessagePinMessage(long messageId) { - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 953503801; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A screenshot of a message in the chat has been taken. - */ - public static class MessageScreenshotTaken extends MessageContent { - - /** - * A screenshot of a message in the chat has been taken. - */ - public MessageScreenshotTaken() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1564971605; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new background was set in the chat. - */ - public static class MessageChatSetBackground extends MessageContent { - /** - * Identifier of the message with a previously set same background; 0 if none. Can be an identifier of a deleted message. - */ - public long oldBackgroundMessageId; - /** - * The new background. - */ - public ChatBackground background; - /** - * True, if the background was set only for self. - */ - public boolean onlyForSelf; - - /** - * A new background was set in the chat. - */ - public MessageChatSetBackground() { - } - - /** - * A new background was set in the chat. - * - * @param oldBackgroundMessageId Identifier of the message with a previously set same background; 0 if none. Can be an identifier of a deleted message. - * @param background The new background. - * @param onlyForSelf True, if the background was set only for self. - */ - public MessageChatSetBackground(long oldBackgroundMessageId, ChatBackground background, boolean onlyForSelf) { - this.oldBackgroundMessageId = oldBackgroundMessageId; - this.background = background; - this.onlyForSelf = onlyForSelf; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1029536832; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A theme in the chat has been changed. - */ - public static class MessageChatSetTheme extends MessageContent { - /** - * New theme for the chat; may be null if chat theme was reset to the default one. - */ - @Nullable public ChatTheme theme; - - /** - * A theme in the chat has been changed. - */ - public MessageChatSetTheme() { - } - - /** - * A theme in the chat has been changed. - * - * @param theme New theme for the chat; may be null if chat theme was reset to the default one. - */ - public MessageChatSetTheme(ChatTheme theme) { - this.theme = theme; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1227514007; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The auto-delete or self-destruct timer for messages in the chat has been changed. - */ - public static class MessageChatSetMessageAutoDeleteTime extends MessageContent { - /** - * New value auto-delete or self-destruct time, in seconds; 0 if disabled. - */ - public int messageAutoDeleteTime; - /** - * If not 0, a user identifier, which default setting was automatically applied. - */ - public long fromUserId; - - /** - * The auto-delete or self-destruct timer for messages in the chat has been changed. - */ - public MessageChatSetMessageAutoDeleteTime() { - } - - /** - * The auto-delete or self-destruct timer for messages in the chat has been changed. - * - * @param messageAutoDeleteTime New value auto-delete or self-destruct time, in seconds; 0 if disabled. - * @param fromUserId If not 0, a user identifier, which default setting was automatically applied. - */ - public MessageChatSetMessageAutoDeleteTime(int messageAutoDeleteTime, long fromUserId) { - this.messageAutoDeleteTime = messageAutoDeleteTime; - this.fromUserId = fromUserId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1637745966; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat was boosted by the sender of the message. - */ - public static class MessageChatBoost extends MessageContent { - /** - * Number of times the chat was boosted. - */ - public int boostCount; - - /** - * The chat was boosted by the sender of the message. - */ - public MessageChatBoost() { - } - - /** - * The chat was boosted by the sender of the message. - * - * @param boostCount Number of times the chat was boosted. - */ - public MessageChatBoost(int boostCount) { - this.boostCount = boostCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1583310219; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A forum topic has been created. - */ - public static class MessageForumTopicCreated extends MessageContent { - /** - * Name of the topic. - */ - public String name; - /** - * True, if the name of the topic wasn't added explicitly. - */ - public boolean isNameImplicit; - /** - * Icon of the topic. - */ - public ForumTopicIcon icon; - - /** - * A forum topic has been created. - */ - public MessageForumTopicCreated() { - } - - /** - * A forum topic has been created. - * - * @param name Name of the topic. - * @param isNameImplicit True, if the name of the topic wasn't added explicitly. - * @param icon Icon of the topic. - */ - public MessageForumTopicCreated(String name, boolean isNameImplicit, ForumTopicIcon icon) { - this.name = name; - this.isNameImplicit = isNameImplicit; - this.icon = icon; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -714462886; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A forum topic has been edited. - */ - public static class MessageForumTopicEdited extends MessageContent { - /** - * If non-empty, the new name of the topic. - */ - public String name; - /** - * True, if icon's customEmojiId is changed. - */ - public boolean editIconCustomEmojiId; - /** - * New unique identifier of the custom emoji shown on the topic icon; 0 if none. Must be ignored if editIconCustomEmojiId is false. - */ - public long iconCustomEmojiId; - - /** - * A forum topic has been edited. - */ - public MessageForumTopicEdited() { - } - - /** - * A forum topic has been edited. - * - * @param name If non-empty, the new name of the topic. - * @param editIconCustomEmojiId True, if icon's customEmojiId is changed. - * @param iconCustomEmojiId New unique identifier of the custom emoji shown on the topic icon; 0 if none. Must be ignored if editIconCustomEmojiId is false. - */ - public MessageForumTopicEdited(String name, boolean editIconCustomEmojiId, long iconCustomEmojiId) { - this.name = name; - this.editIconCustomEmojiId = editIconCustomEmojiId; - this.iconCustomEmojiId = iconCustomEmojiId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 12629888; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A forum topic has been closed or opened. - */ - public static class MessageForumTopicIsClosedToggled extends MessageContent { - /** - * True, if the topic was closed; otherwise, the topic was reopened. - */ - public boolean isClosed; - - /** - * A forum topic has been closed or opened. - */ - public MessageForumTopicIsClosedToggled() { - } - - /** - * A forum topic has been closed or opened. - * - * @param isClosed True, if the topic was closed; otherwise, the topic was reopened. - */ - public MessageForumTopicIsClosedToggled(boolean isClosed) { - this.isClosed = isClosed; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1264029664; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A General forum topic has been hidden or unhidden. - */ - public static class MessageForumTopicIsHiddenToggled extends MessageContent { - /** - * True, if the topic was hidden; otherwise, the topic was unhidden. - */ - public boolean isHidden; - - /** - * A General forum topic has been hidden or unhidden. - */ - public MessageForumTopicIsHiddenToggled() { - } - - /** - * A General forum topic has been hidden or unhidden. - * - * @param isHidden True, if the topic was hidden; otherwise, the topic was unhidden. - */ - public MessageForumTopicIsHiddenToggled(boolean isHidden) { - this.isHidden = isHidden; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1751936002; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A profile photo was suggested to a user in a private chat. - */ - public static class MessageSuggestProfilePhoto extends MessageContent { - /** - * The suggested chat photo. Use the method setProfilePhoto with inputChatPhotoPrevious to apply the photo. - */ - public ChatPhoto photo; - - /** - * A profile photo was suggested to a user in a private chat. - */ - public MessageSuggestProfilePhoto() { - } - - /** - * A profile photo was suggested to a user in a private chat. - * - * @param photo The suggested chat photo. Use the method setProfilePhoto with inputChatPhotoPrevious to apply the photo. - */ - public MessageSuggestProfilePhoto(ChatPhoto photo) { - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1251926297; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A birthdate was suggested to be set. - */ - public static class MessageSuggestBirthdate extends MessageContent { - /** - * The suggested birthdate. Use the method setBirthdate to apply the birthdate. - */ - public Birthdate birthdate; - - /** - * A birthdate was suggested to be set. - */ - public MessageSuggestBirthdate() { - } - - /** - * A birthdate was suggested to be set. - * - * @param birthdate The suggested birthdate. Use the method setBirthdate to apply the birthdate. - */ - public MessageSuggestBirthdate(Birthdate birthdate) { - this.birthdate = birthdate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -682342263; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A non-standard action has happened in the chat. - */ - public static class MessageCustomServiceAction extends MessageContent { - /** - * Message text to be shown in the chat. - */ - public String text; - - /** - * A non-standard action has happened in the chat. - */ - public MessageCustomServiceAction() { - } - - /** - * A non-standard action has happened in the chat. - * - * @param text Message text to be shown in the chat. - */ - public MessageCustomServiceAction(String text) { - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1435879282; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new high score was achieved in a game. - */ - public static class MessageGameScore extends MessageContent { - /** - * Identifier of the message with the game, can be an identifier of a deleted message. - */ - public long gameMessageId; - /** - * Identifier of the game; may be different from the games presented in the message with the game. - */ - public long gameId; - /** - * New score. - */ - public int score; - - /** - * A new high score was achieved in a game. - */ - public MessageGameScore() { - } - - /** - * A new high score was achieved in a game. - * - * @param gameMessageId Identifier of the message with the game, can be an identifier of a deleted message. - * @param gameId Identifier of the game; may be different from the games presented in the message with the game. - * @param score New score. - */ - public MessageGameScore(long gameMessageId, long gameId, int score) { - this.gameMessageId = gameMessageId; - this.gameId = gameId; - this.score = score; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1344904575; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A payment has been sent to a bot or a business account. - */ - public static class MessagePaymentSuccessful extends MessageContent { - /** - * Identifier of the chat, containing the corresponding invoice message. - */ - public long invoiceChatId; - /** - * Identifier of the message with the corresponding invoice; may be 0 or an identifier of a deleted message. - */ - public long invoiceMessageId; - /** - * Currency for the price of the product. - */ - public String currency; - /** - * Total price for the product, in the smallest units of the currency. - */ - public long totalAmount; - /** - * Point in time (Unix timestamp) when the subscription will expire; 0 if unknown or the payment isn't recurring. - */ - public int subscriptionUntilDate; - /** - * True, if this is a recurring payment. - */ - public boolean isRecurring; - /** - * True, if this is the first recurring payment. - */ - public boolean isFirstRecurring; - /** - * Name of the invoice; may be empty if unknown. - */ - public String invoiceName; - - /** - * A payment has been sent to a bot or a business account. - */ - public MessagePaymentSuccessful() { - } - - /** - * A payment has been sent to a bot or a business account. - * - * @param invoiceChatId Identifier of the chat, containing the corresponding invoice message. - * @param invoiceMessageId Identifier of the message with the corresponding invoice; may be 0 or an identifier of a deleted message. - * @param currency Currency for the price of the product. - * @param totalAmount Total price for the product, in the smallest units of the currency. - * @param subscriptionUntilDate Point in time (Unix timestamp) when the subscription will expire; 0 if unknown or the payment isn't recurring. - * @param isRecurring True, if this is a recurring payment. - * @param isFirstRecurring True, if this is the first recurring payment. - * @param invoiceName Name of the invoice; may be empty if unknown. - */ - public MessagePaymentSuccessful(long invoiceChatId, long invoiceMessageId, String currency, long totalAmount, int subscriptionUntilDate, boolean isRecurring, boolean isFirstRecurring, String invoiceName) { - this.invoiceChatId = invoiceChatId; - this.invoiceMessageId = invoiceMessageId; - this.currency = currency; - this.totalAmount = totalAmount; - this.subscriptionUntilDate = subscriptionUntilDate; - this.isRecurring = isRecurring; - this.isFirstRecurring = isFirstRecurring; - this.invoiceName = invoiceName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1046878481; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A payment has been received by the bot or the business account. - */ - public static class MessagePaymentSuccessfulBot extends MessageContent { - /** - * Currency for price of the product. - */ - public String currency; - /** - * Total price for the product, in the smallest units of the currency. - */ - public long totalAmount; - /** - * Point in time (Unix timestamp) when the subscription will expire; 0 if unknown or the payment isn't recurring. - */ - public int subscriptionUntilDate; - /** - * True, if this is a recurring payment. - */ - public boolean isRecurring; - /** - * True, if this is the first recurring payment. - */ - public boolean isFirstRecurring; - /** - * Invoice payload. - */ - public byte[] invoicePayload; - /** - * Identifier of the shipping option chosen by the user; may be empty if not applicable; for bots only. - */ - public String shippingOptionId; - /** - * Information about the order; may be null; for bots only. - */ - @Nullable public OrderInfo orderInfo; - /** - * Telegram payment identifier. - */ - public String telegramPaymentChargeId; - /** - * Provider payment identifier. - */ - public String providerPaymentChargeId; - - /** - * A payment has been received by the bot or the business account. - */ - public MessagePaymentSuccessfulBot() { - } - - /** - * A payment has been received by the bot or the business account. - * - * @param currency Currency for price of the product. - * @param totalAmount Total price for the product, in the smallest units of the currency. - * @param subscriptionUntilDate Point in time (Unix timestamp) when the subscription will expire; 0 if unknown or the payment isn't recurring. - * @param isRecurring True, if this is a recurring payment. - * @param isFirstRecurring True, if this is the first recurring payment. - * @param invoicePayload Invoice payload. - * @param shippingOptionId Identifier of the shipping option chosen by the user; may be empty if not applicable; for bots only. - * @param orderInfo Information about the order; may be null; for bots only. - * @param telegramPaymentChargeId Telegram payment identifier. - * @param providerPaymentChargeId Provider payment identifier. - */ - public MessagePaymentSuccessfulBot(String currency, long totalAmount, int subscriptionUntilDate, boolean isRecurring, boolean isFirstRecurring, byte[] invoicePayload, String shippingOptionId, OrderInfo orderInfo, String telegramPaymentChargeId, String providerPaymentChargeId) { - this.currency = currency; - this.totalAmount = totalAmount; - this.subscriptionUntilDate = subscriptionUntilDate; - this.isRecurring = isRecurring; - this.isFirstRecurring = isFirstRecurring; - this.invoicePayload = invoicePayload; - this.shippingOptionId = shippingOptionId; - this.orderInfo = orderInfo; - this.telegramPaymentChargeId = telegramPaymentChargeId; - this.providerPaymentChargeId = providerPaymentChargeId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -949596737; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A payment has been refunded. - */ - public static class MessagePaymentRefunded extends MessageContent { - /** - * Identifier of the previous owner of the Telegram Stars that refunds them. - */ - public MessageSender ownerId; - /** - * Currency for the price of the product. - */ - public String currency; - /** - * Total price for the product, in the smallest units of the currency. - */ - public long totalAmount; - /** - * Invoice payload; only for bots. - */ - public byte[] invoicePayload; - /** - * Telegram payment identifier. - */ - public String telegramPaymentChargeId; - /** - * Provider payment identifier. - */ - public String providerPaymentChargeId; - - /** - * A payment has been refunded. - */ - public MessagePaymentRefunded() { - } - - /** - * A payment has been refunded. - * - * @param ownerId Identifier of the previous owner of the Telegram Stars that refunds them. - * @param currency Currency for the price of the product. - * @param totalAmount Total price for the product, in the smallest units of the currency. - * @param invoicePayload Invoice payload; only for bots. - * @param telegramPaymentChargeId Telegram payment identifier. - * @param providerPaymentChargeId Provider payment identifier. - */ - public MessagePaymentRefunded(MessageSender ownerId, String currency, long totalAmount, byte[] invoicePayload, String telegramPaymentChargeId, String providerPaymentChargeId) { - this.ownerId = ownerId; - this.currency = currency; - this.totalAmount = totalAmount; - this.invoicePayload = invoicePayload; - this.telegramPaymentChargeId = telegramPaymentChargeId; - this.providerPaymentChargeId = providerPaymentChargeId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 297580787; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Telegram Premium was gifted to a user. - */ - public static class MessageGiftedPremium extends MessageContent { - /** - * The identifier of a user who gifted Telegram Premium; 0 if the gift was anonymous or is outgoing. - */ - public long gifterUserId; - /** - * The identifier of a user who received Telegram Premium; 0 if the gift is incoming. - */ - public long receiverUserId; - /** - * Message added to the gifted Telegram Premium by the sender. - */ - public FormattedText text; - /** - * Currency for the paid amount. - */ - public String currency; - /** - * The paid amount, in the smallest units of the currency. - */ - public long amount; - /** - * Cryptocurrency used to pay for the gift; may be empty if none. - */ - public String cryptocurrency; - /** - * The paid amount, in the smallest units of the cryptocurrency; 0 if none. - */ - public long cryptocurrencyAmount; - /** - * Number of months the Telegram Premium subscription will be active after code activation; 0 if the number of months isn't integer. - */ - public int monthCount; - /** - * Number of days the Telegram Premium subscription will be active. - */ - public int dayCount; - /** - * A sticker to be shown in the message; may be null if unknown. - */ - @Nullable public Sticker sticker; - - /** - * Telegram Premium was gifted to a user. - */ - public MessageGiftedPremium() { - } - - /** - * Telegram Premium was gifted to a user. - * - * @param gifterUserId The identifier of a user who gifted Telegram Premium; 0 if the gift was anonymous or is outgoing. - * @param receiverUserId The identifier of a user who received Telegram Premium; 0 if the gift is incoming. - * @param text Message added to the gifted Telegram Premium by the sender. - * @param currency Currency for the paid amount. - * @param amount The paid amount, in the smallest units of the currency. - * @param cryptocurrency Cryptocurrency used to pay for the gift; may be empty if none. - * @param cryptocurrencyAmount The paid amount, in the smallest units of the cryptocurrency; 0 if none. - * @param monthCount Number of months the Telegram Premium subscription will be active after code activation; 0 if the number of months isn't integer. - * @param dayCount Number of days the Telegram Premium subscription will be active. - * @param sticker A sticker to be shown in the message; may be null if unknown. - */ - public MessageGiftedPremium(long gifterUserId, long receiverUserId, FormattedText text, String currency, long amount, String cryptocurrency, long cryptocurrencyAmount, int monthCount, int dayCount, Sticker sticker) { - this.gifterUserId = gifterUserId; - this.receiverUserId = receiverUserId; - this.text = text; - this.currency = currency; - this.amount = amount; - this.cryptocurrency = cryptocurrency; - this.cryptocurrencyAmount = cryptocurrencyAmount; - this.monthCount = monthCount; - this.dayCount = dayCount; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 807892848; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Premium gift code was created for the user. - */ - public static class MessagePremiumGiftCode extends MessageContent { - /** - * Identifier of a chat or a user who created the gift code; may be null if unknown. - */ - @Nullable public MessageSender creatorId; - /** - * Message added to the gift. - */ - public FormattedText text; - /** - * True, if the gift code was created for a giveaway. - */ - public boolean isFromGiveaway; - /** - * True, if the winner for the corresponding Telegram Premium subscription wasn't chosen. - */ - public boolean isUnclaimed; - /** - * Currency for the paid amount; empty if unknown. - */ - public String currency; - /** - * The paid amount, in the smallest units of the currency; 0 if unknown. - */ - public long amount; - /** - * Cryptocurrency used to pay for the gift; may be empty if none or unknown. - */ - public String cryptocurrency; - /** - * The paid amount, in the smallest units of the cryptocurrency; 0 if unknown. - */ - public long cryptocurrencyAmount; - /** - * Number of months the Telegram Premium subscription will be active after code activation; 0 if the number of months isn't integer. - */ - public int monthCount; - /** - * Number of days the Telegram Premium subscription will be active after code activation. - */ - public int dayCount; - /** - * A sticker to be shown in the message; may be null if unknown. - */ - @Nullable public Sticker sticker; - /** - * The gift code. - */ - public String code; - - /** - * A Telegram Premium gift code was created for the user. - */ - public MessagePremiumGiftCode() { - } - - /** - * A Telegram Premium gift code was created for the user. - * - * @param creatorId Identifier of a chat or a user who created the gift code; may be null if unknown. - * @param text Message added to the gift. - * @param isFromGiveaway True, if the gift code was created for a giveaway. - * @param isUnclaimed True, if the winner for the corresponding Telegram Premium subscription wasn't chosen. - * @param currency Currency for the paid amount; empty if unknown. - * @param amount The paid amount, in the smallest units of the currency; 0 if unknown. - * @param cryptocurrency Cryptocurrency used to pay for the gift; may be empty if none or unknown. - * @param cryptocurrencyAmount The paid amount, in the smallest units of the cryptocurrency; 0 if unknown. - * @param monthCount Number of months the Telegram Premium subscription will be active after code activation; 0 if the number of months isn't integer. - * @param dayCount Number of days the Telegram Premium subscription will be active after code activation. - * @param sticker A sticker to be shown in the message; may be null if unknown. - * @param code The gift code. - */ - public MessagePremiumGiftCode(MessageSender creatorId, FormattedText text, boolean isFromGiveaway, boolean isUnclaimed, String currency, long amount, String cryptocurrency, long cryptocurrencyAmount, int monthCount, int dayCount, Sticker sticker, String code) { - this.creatorId = creatorId; - this.text = text; - this.isFromGiveaway = isFromGiveaway; - this.isUnclaimed = isUnclaimed; - this.currency = currency; - this.amount = amount; - this.cryptocurrency = cryptocurrency; - this.cryptocurrencyAmount = cryptocurrencyAmount; - this.monthCount = monthCount; - this.dayCount = dayCount; - this.sticker = sticker; - this.code = code; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 680217675; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A giveaway was created for the chat. Use telegramPaymentPurposePremiumGiveaway, storePaymentPurposePremiumGiveaway, telegramPaymentPurposeStarGiveaway, or storePaymentPurposeStarGiveaway to create a giveaway. - */ - public static class MessageGiveawayCreated extends MessageContent { - /** - * Number of Telegram Stars that will be shared by winners of the giveaway; 0 for Telegram Premium giveaways. - */ - public long starCount; - - /** - * A giveaway was created for the chat. Use telegramPaymentPurposePremiumGiveaway, storePaymentPurposePremiumGiveaway, telegramPaymentPurposeStarGiveaway, or storePaymentPurposeStarGiveaway to create a giveaway. - */ - public MessageGiveawayCreated() { - } - - /** - * A giveaway was created for the chat. Use telegramPaymentPurposePremiumGiveaway, storePaymentPurposePremiumGiveaway, telegramPaymentPurposeStarGiveaway, or storePaymentPurposeStarGiveaway to create a giveaway. - * - * @param starCount Number of Telegram Stars that will be shared by winners of the giveaway; 0 for Telegram Premium giveaways. - */ - public MessageGiveawayCreated(long starCount) { - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 972252063; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A giveaway. - */ - public static class MessageGiveaway extends MessageContent { - /** - * Giveaway parameters. - */ - public GiveawayParameters parameters; - /** - * Number of users which will receive Telegram Premium subscription gift codes. - */ - public int winnerCount; - /** - * Prize of the giveaway. - */ - public GiveawayPrize prize; - /** - * A sticker to be shown in the message; may be null if unknown. - */ - @Nullable public Sticker sticker; - - /** - * A giveaway. - */ - public MessageGiveaway() { - } - - /** - * A giveaway. - * - * @param parameters Giveaway parameters. - * @param winnerCount Number of users which will receive Telegram Premium subscription gift codes. - * @param prize Prize of the giveaway. - * @param sticker A sticker to be shown in the message; may be null if unknown. - */ - public MessageGiveaway(GiveawayParameters parameters, int winnerCount, GiveawayPrize prize, Sticker sticker) { - this.parameters = parameters; - this.winnerCount = winnerCount; - this.prize = prize; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -345908568; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A giveaway without public winners has been completed for the chat. - */ - public static class MessageGiveawayCompleted extends MessageContent { - /** - * Identifier of the message with the giveaway; may be 0 or an identifier of a deleted message. - */ - public long giveawayMessageId; - /** - * Number of winners in the giveaway. - */ - public int winnerCount; - /** - * True, if the giveaway is a Telegram Star giveaway. - */ - public boolean isStarGiveaway; - /** - * Number of undistributed prizes; for Telegram Premium giveaways only. - */ - public int unclaimedPrizeCount; - - /** - * A giveaway without public winners has been completed for the chat. - */ - public MessageGiveawayCompleted() { - } - - /** - * A giveaway without public winners has been completed for the chat. - * - * @param giveawayMessageId Identifier of the message with the giveaway; may be 0 or an identifier of a deleted message. - * @param winnerCount Number of winners in the giveaway. - * @param isStarGiveaway True, if the giveaway is a Telegram Star giveaway. - * @param unclaimedPrizeCount Number of undistributed prizes; for Telegram Premium giveaways only. - */ - public MessageGiveawayCompleted(long giveawayMessageId, int winnerCount, boolean isStarGiveaway, int unclaimedPrizeCount) { - this.giveawayMessageId = giveawayMessageId; - this.winnerCount = winnerCount; - this.isStarGiveaway = isStarGiveaway; - this.unclaimedPrizeCount = unclaimedPrizeCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -467351305; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A giveaway with public winners has been completed for the chat. - */ - public static class MessageGiveawayWinners extends MessageContent { - /** - * Identifier of the supergroup or channel chat, which was automatically boosted by the winners of the giveaway. - */ - public long boostedChatId; - /** - * Identifier of the message with the giveaway in the boosted chat. - */ - public long giveawayMessageId; - /** - * Number of other chats that participated in the giveaway. - */ - public int additionalChatCount; - /** - * Point in time (Unix timestamp) when the winners were selected. May be bigger than winners selection date specified in parameters of the giveaway. - */ - public int actualWinnersSelectionDate; - /** - * True, if only new members of the chats were eligible for the giveaway. - */ - public boolean onlyNewMembers; - /** - * True, if the giveaway was canceled and was fully refunded. - */ - public boolean wasRefunded; - /** - * Prize of the giveaway. - */ - public GiveawayPrize prize; - /** - * Additional description of the giveaway prize. - */ - public String prizeDescription; - /** - * Total number of winners in the giveaway. - */ - public int winnerCount; - /** - * Up to 100 user identifiers of the winners of the giveaway. - */ - public long[] winnerUserIds; - /** - * Number of undistributed prizes; for Telegram Premium giveaways only. - */ - public int unclaimedPrizeCount; - - /** - * A giveaway with public winners has been completed for the chat. - */ - public MessageGiveawayWinners() { - } - - /** - * A giveaway with public winners has been completed for the chat. - * - * @param boostedChatId Identifier of the supergroup or channel chat, which was automatically boosted by the winners of the giveaway. - * @param giveawayMessageId Identifier of the message with the giveaway in the boosted chat. - * @param additionalChatCount Number of other chats that participated in the giveaway. - * @param actualWinnersSelectionDate Point in time (Unix timestamp) when the winners were selected. May be bigger than winners selection date specified in parameters of the giveaway. - * @param onlyNewMembers True, if only new members of the chats were eligible for the giveaway. - * @param wasRefunded True, if the giveaway was canceled and was fully refunded. - * @param prize Prize of the giveaway. - * @param prizeDescription Additional description of the giveaway prize. - * @param winnerCount Total number of winners in the giveaway. - * @param winnerUserIds Up to 100 user identifiers of the winners of the giveaway. - * @param unclaimedPrizeCount Number of undistributed prizes; for Telegram Premium giveaways only. - */ - public MessageGiveawayWinners(long boostedChatId, long giveawayMessageId, int additionalChatCount, int actualWinnersSelectionDate, boolean onlyNewMembers, boolean wasRefunded, GiveawayPrize prize, String prizeDescription, int winnerCount, long[] winnerUserIds, int unclaimedPrizeCount) { - this.boostedChatId = boostedChatId; - this.giveawayMessageId = giveawayMessageId; - this.additionalChatCount = additionalChatCount; - this.actualWinnersSelectionDate = actualWinnersSelectionDate; - this.onlyNewMembers = onlyNewMembers; - this.wasRefunded = wasRefunded; - this.prize = prize; - this.prizeDescription = prizeDescription; - this.winnerCount = winnerCount; - this.winnerUserIds = winnerUserIds; - this.unclaimedPrizeCount = unclaimedPrizeCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2098585405; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Telegram Stars were gifted to a user. - */ - public static class MessageGiftedStars extends MessageContent { - /** - * The identifier of a user who gifted Telegram Stars; 0 if the gift was anonymous or is outgoing. - */ - public long gifterUserId; - /** - * The identifier of a user who received Telegram Stars; 0 if the gift is incoming. - */ - public long receiverUserId; - /** - * Currency for the paid amount. - */ - public String currency; - /** - * The paid amount, in the smallest units of the currency. - */ - public long amount; - /** - * Cryptocurrency used to pay for the gift; may be empty if none. - */ - public String cryptocurrency; - /** - * The paid amount, in the smallest units of the cryptocurrency; 0 if none. - */ - public long cryptocurrencyAmount; - /** - * Number of Telegram Stars that were gifted. - */ - public long starCount; - /** - * Identifier of the transaction for Telegram Stars purchase; for receiver only. - */ - public String transactionId; - /** - * A sticker to be shown in the message; may be null if unknown. - */ - @Nullable public Sticker sticker; - - /** - * Telegram Stars were gifted to a user. - */ - public MessageGiftedStars() { - } - - /** - * Telegram Stars were gifted to a user. - * - * @param gifterUserId The identifier of a user who gifted Telegram Stars; 0 if the gift was anonymous or is outgoing. - * @param receiverUserId The identifier of a user who received Telegram Stars; 0 if the gift is incoming. - * @param currency Currency for the paid amount. - * @param amount The paid amount, in the smallest units of the currency. - * @param cryptocurrency Cryptocurrency used to pay for the gift; may be empty if none. - * @param cryptocurrencyAmount The paid amount, in the smallest units of the cryptocurrency; 0 if none. - * @param starCount Number of Telegram Stars that were gifted. - * @param transactionId Identifier of the transaction for Telegram Stars purchase; for receiver only. - * @param sticker A sticker to be shown in the message; may be null if unknown. - */ - public MessageGiftedStars(long gifterUserId, long receiverUserId, String currency, long amount, String cryptocurrency, long cryptocurrencyAmount, long starCount, String transactionId, Sticker sticker) { - this.gifterUserId = gifterUserId; - this.receiverUserId = receiverUserId; - this.currency = currency; - this.amount = amount; - this.cryptocurrency = cryptocurrency; - this.cryptocurrencyAmount = cryptocurrencyAmount; - this.starCount = starCount; - this.transactionId = transactionId; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1102954151; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toncoins were gifted to a user. - */ - public static class MessageGiftedTon extends MessageContent { - /** - * The identifier of a user who gifted Toncoins; 0 if the gift was anonymous or is outgoing. - */ - public long gifterUserId; - /** - * The identifier of a user who received Toncoins; 0 if the gift is incoming. - */ - public long receiverUserId; - /** - * The received Toncoin amount, in the smallest units of the cryptocurrency. - */ - public long tonAmount; - /** - * Identifier of the transaction for Toncoin credit; for receiver only. - */ - public String transactionId; - /** - * A sticker to be shown in the message; may be null if unknown. - */ - @Nullable public Sticker sticker; - - /** - * Toncoins were gifted to a user. - */ - public MessageGiftedTon() { - } - - /** - * Toncoins were gifted to a user. - * - * @param gifterUserId The identifier of a user who gifted Toncoins; 0 if the gift was anonymous or is outgoing. - * @param receiverUserId The identifier of a user who received Toncoins; 0 if the gift is incoming. - * @param tonAmount The received Toncoin amount, in the smallest units of the cryptocurrency. - * @param transactionId Identifier of the transaction for Toncoin credit; for receiver only. - * @param sticker A sticker to be shown in the message; may be null if unknown. - */ - public MessageGiftedTon(long gifterUserId, long receiverUserId, long tonAmount, String transactionId, Sticker sticker) { - this.gifterUserId = gifterUserId; - this.receiverUserId = receiverUserId; - this.tonAmount = tonAmount; - this.transactionId = transactionId; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 766483995; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Stars were received by the current user from a giveaway. - */ - public static class MessageGiveawayPrizeStars extends MessageContent { - /** - * Number of Telegram Stars that were received. - */ - public long starCount; - /** - * Identifier of the transaction for Telegram Stars credit. - */ - public String transactionId; - /** - * Identifier of the supergroup or channel chat, which was automatically boosted by the winners of the giveaway. - */ - public long boostedChatId; - /** - * Identifier of the message with the giveaway in the boosted chat; may be 0 or an identifier of a deleted message. - */ - public long giveawayMessageId; - /** - * True, if the corresponding winner wasn't chosen and the Telegram Stars were received by the owner of the boosted chat. - */ - public boolean isUnclaimed; - /** - * A sticker to be shown in the message; may be null if unknown. - */ - @Nullable public Sticker sticker; - - /** - * A Telegram Stars were received by the current user from a giveaway. - */ - public MessageGiveawayPrizeStars() { - } - - /** - * A Telegram Stars were received by the current user from a giveaway. - * - * @param starCount Number of Telegram Stars that were received. - * @param transactionId Identifier of the transaction for Telegram Stars credit. - * @param boostedChatId Identifier of the supergroup or channel chat, which was automatically boosted by the winners of the giveaway. - * @param giveawayMessageId Identifier of the message with the giveaway in the boosted chat; may be 0 or an identifier of a deleted message. - * @param isUnclaimed True, if the corresponding winner wasn't chosen and the Telegram Stars were received by the owner of the boosted chat. - * @param sticker A sticker to be shown in the message; may be null if unknown. - */ - public MessageGiveawayPrizeStars(long starCount, String transactionId, long boostedChatId, long giveawayMessageId, boolean isUnclaimed, Sticker sticker) { - this.starCount = starCount; - this.transactionId = transactionId; - this.boostedChatId = boostedChatId; - this.giveawayMessageId = giveawayMessageId; - this.isUnclaimed = isUnclaimed; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1441833501; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A regular gift was received or sent by the current user, or the current user was notified about a channel gift. - */ - public static class MessageGift extends MessageContent { - /** - * The gift. - */ - public Gift gift; - /** - * Sender of the gift; may be null for outgoing messages about prepaid upgrade of gifts from unknown users. - */ - @Nullable public MessageSender senderId; - /** - * Receiver of the gift. - */ - public MessageSender receiverId; - /** - * Unique identifier of the received gift for the current user; only for the receiver of the gift. - */ - public String receivedGiftId; - /** - * Message added to the gift. - */ - public FormattedText text; - /** - * Unique number of the gift among gifts upgraded from the same gift after upgrade; 0 if yet unassigned. - */ - public int uniqueGiftNumber; - /** - * Number of Telegram Stars that can be claimed by the receiver instead of the regular gift; 0 if the gift can't be sold by the receiver. - */ - public long sellStarCount; - /** - * Number of Telegram Stars that were paid by the sender for the ability to upgrade the gift. - */ - public long prepaidUpgradeStarCount; - /** - * True, if the upgrade was bought after the gift was sent. In this case, prepaid upgrade cost must not be added to the gift cost. - */ - public boolean isUpgradeSeparate; - /** - * True, if the message is a notification about a gift won on an auction. - */ - public boolean isFromAuction; - /** - * True, if the sender and gift text are shown only to the gift receiver; otherwise, everyone will be able to see them. - */ - public boolean isPrivate; - /** - * True, if the gift is displayed on the user's or the channel's profile page; only for the receiver of the gift. - */ - public boolean isSaved; - /** - * True, if the message is about prepaid upgrade of the gift by another user. - */ - public boolean isPrepaidUpgrade; - /** - * True, if the gift can be upgraded to a unique gift; only for the receiver of the gift. - */ - public boolean canBeUpgraded; - /** - * True, if the gift was converted to Telegram Stars; only for the receiver of the gift. - */ - public boolean wasConverted; - /** - * True, if the gift was upgraded to a unique gift. - */ - public boolean wasUpgraded; - /** - * True, if the gift was refunded and isn't available anymore. - */ - public boolean wasRefunded; - /** - * Identifier of the corresponding upgraded gift; may be empty if unknown. Use getReceivedGift to get information about the gift. - */ - public String upgradedReceivedGiftId; - /** - * If non-empty, then the user can pay for an upgrade of the gift using buyGiftUpgrade. - */ - public String prepaidUpgradeHash; - - /** - * A regular gift was received or sent by the current user, or the current user was notified about a channel gift. - */ - public MessageGift() { - } - - /** - * A regular gift was received or sent by the current user, or the current user was notified about a channel gift. - * - * @param gift The gift. - * @param senderId Sender of the gift; may be null for outgoing messages about prepaid upgrade of gifts from unknown users. - * @param receiverId Receiver of the gift. - * @param receivedGiftId Unique identifier of the received gift for the current user; only for the receiver of the gift. - * @param text Message added to the gift. - * @param uniqueGiftNumber Unique number of the gift among gifts upgraded from the same gift after upgrade; 0 if yet unassigned. - * @param sellStarCount Number of Telegram Stars that can be claimed by the receiver instead of the regular gift; 0 if the gift can't be sold by the receiver. - * @param prepaidUpgradeStarCount Number of Telegram Stars that were paid by the sender for the ability to upgrade the gift. - * @param isUpgradeSeparate True, if the upgrade was bought after the gift was sent. In this case, prepaid upgrade cost must not be added to the gift cost. - * @param isFromAuction True, if the message is a notification about a gift won on an auction. - * @param isPrivate True, if the sender and gift text are shown only to the gift receiver; otherwise, everyone will be able to see them. - * @param isSaved True, if the gift is displayed on the user's or the channel's profile page; only for the receiver of the gift. - * @param isPrepaidUpgrade True, if the message is about prepaid upgrade of the gift by another user. - * @param canBeUpgraded True, if the gift can be upgraded to a unique gift; only for the receiver of the gift. - * @param wasConverted True, if the gift was converted to Telegram Stars; only for the receiver of the gift. - * @param wasUpgraded True, if the gift was upgraded to a unique gift. - * @param wasRefunded True, if the gift was refunded and isn't available anymore. - * @param upgradedReceivedGiftId Identifier of the corresponding upgraded gift; may be empty if unknown. Use getReceivedGift to get information about the gift. - * @param prepaidUpgradeHash If non-empty, then the user can pay for an upgrade of the gift using buyGiftUpgrade. - */ - public MessageGift(Gift gift, MessageSender senderId, MessageSender receiverId, String receivedGiftId, FormattedText text, int uniqueGiftNumber, long sellStarCount, long prepaidUpgradeStarCount, boolean isUpgradeSeparate, boolean isFromAuction, boolean isPrivate, boolean isSaved, boolean isPrepaidUpgrade, boolean canBeUpgraded, boolean wasConverted, boolean wasUpgraded, boolean wasRefunded, String upgradedReceivedGiftId, String prepaidUpgradeHash) { - this.gift = gift; - this.senderId = senderId; - this.receiverId = receiverId; - this.receivedGiftId = receivedGiftId; - this.text = text; - this.uniqueGiftNumber = uniqueGiftNumber; - this.sellStarCount = sellStarCount; - this.prepaidUpgradeStarCount = prepaidUpgradeStarCount; - this.isUpgradeSeparate = isUpgradeSeparate; - this.isFromAuction = isFromAuction; - this.isPrivate = isPrivate; - this.isSaved = isSaved; - this.isPrepaidUpgrade = isPrepaidUpgrade; - this.canBeUpgraded = canBeUpgraded; - this.wasConverted = wasConverted; - this.wasUpgraded = wasUpgraded; - this.wasRefunded = wasRefunded; - this.upgradedReceivedGiftId = upgradedReceivedGiftId; - this.prepaidUpgradeHash = prepaidUpgradeHash; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1990929579; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An upgraded gift was received or sent by the current user, or the current user was notified about a channel gift. - */ - public static class MessageUpgradedGift extends MessageContent { - /** - * The gift. - */ - public UpgradedGift gift; - /** - * Sender of the gift; may be null for anonymous gifts. - */ - @Nullable public MessageSender senderId; - /** - * Receiver of the gift. - */ - public MessageSender receiverId; - /** - * Origin of the upgraded gift. - */ - public UpgradedGiftOrigin origin; - /** - * Unique identifier of the received gift for the current user; only for the receiver of the gift. - */ - public String receivedGiftId; - /** - * True, if the gift is displayed on the user's or the channel's profile page; only for the receiver of the gift. - */ - public boolean isSaved; - /** - * True, if the gift can be transferred to another owner; only for the receiver of the gift. - */ - public boolean canBeTransferred; - /** - * True, if the gift has already been transferred to another owner; only for the receiver of the gift. - */ - public boolean wasTransferred; - /** - * Number of Telegram Stars that must be paid to transfer the upgraded gift; only for the receiver of the gift. - */ - public long transferStarCount; - /** - * Number of Telegram Stars that must be paid to drop original details of the upgraded gift; 0 if not available; only for the receiver of the gift. - */ - public long dropOriginalDetailsStarCount; - /** - * Point in time (Unix timestamp) when the gift can be transferred to another owner; can be in the past; 0 if the gift can be transferred immediately or transfer isn't possible; only for the receiver of the gift. - */ - public int nextTransferDate; - /** - * Point in time (Unix timestamp) when the gift can be resold to another user; can be in the past; 0 if the gift can't be resold; only for the receiver of the gift. - */ - public int nextResaleDate; - /** - * Point in time (Unix timestamp) when the gift can be transferred to the TON blockchain as an NFT; can be in the past; 0 if NFT export isn't possible; only for the receiver of the gift. - */ - public int exportDate; - /** - * Point in time (Unix timestamp) when the gift can be used to craft another gift can be in the past; only for the receiver of the gift. - */ - public int craftDate; - - /** - * An upgraded gift was received or sent by the current user, or the current user was notified about a channel gift. - */ - public MessageUpgradedGift() { - } - - /** - * An upgraded gift was received or sent by the current user, or the current user was notified about a channel gift. - * - * @param gift The gift. - * @param senderId Sender of the gift; may be null for anonymous gifts. - * @param receiverId Receiver of the gift. - * @param origin Origin of the upgraded gift. - * @param receivedGiftId Unique identifier of the received gift for the current user; only for the receiver of the gift. - * @param isSaved True, if the gift is displayed on the user's or the channel's profile page; only for the receiver of the gift. - * @param canBeTransferred True, if the gift can be transferred to another owner; only for the receiver of the gift. - * @param wasTransferred True, if the gift has already been transferred to another owner; only for the receiver of the gift. - * @param transferStarCount Number of Telegram Stars that must be paid to transfer the upgraded gift; only for the receiver of the gift. - * @param dropOriginalDetailsStarCount Number of Telegram Stars that must be paid to drop original details of the upgraded gift; 0 if not available; only for the receiver of the gift. - * @param nextTransferDate Point in time (Unix timestamp) when the gift can be transferred to another owner; can be in the past; 0 if the gift can be transferred immediately or transfer isn't possible; only for the receiver of the gift. - * @param nextResaleDate Point in time (Unix timestamp) when the gift can be resold to another user; can be in the past; 0 if the gift can't be resold; only for the receiver of the gift. - * @param exportDate Point in time (Unix timestamp) when the gift can be transferred to the TON blockchain as an NFT; can be in the past; 0 if NFT export isn't possible; only for the receiver of the gift. - * @param craftDate Point in time (Unix timestamp) when the gift can be used to craft another gift can be in the past; only for the receiver of the gift. - */ - public MessageUpgradedGift(UpgradedGift gift, MessageSender senderId, MessageSender receiverId, UpgradedGiftOrigin origin, String receivedGiftId, boolean isSaved, boolean canBeTransferred, boolean wasTransferred, long transferStarCount, long dropOriginalDetailsStarCount, int nextTransferDate, int nextResaleDate, int exportDate, int craftDate) { - this.gift = gift; - this.senderId = senderId; - this.receiverId = receiverId; - this.origin = origin; - this.receivedGiftId = receivedGiftId; - this.isSaved = isSaved; - this.canBeTransferred = canBeTransferred; - this.wasTransferred = wasTransferred; - this.transferStarCount = transferStarCount; - this.dropOriginalDetailsStarCount = dropOriginalDetailsStarCount; - this.nextTransferDate = nextTransferDate; - this.nextResaleDate = nextResaleDate; - this.exportDate = exportDate; - this.craftDate = craftDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1432909893; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A gift which purchase, upgrade or transfer were refunded. - */ - public static class MessageRefundedUpgradedGift extends MessageContent { - /** - * The gift. - */ - public Gift gift; - /** - * Sender of the gift. - */ - public MessageSender senderId; - /** - * Receiver of the gift. - */ - public MessageSender receiverId; - /** - * Origin of the upgraded gift. - */ - public UpgradedGiftOrigin origin; - - /** - * A gift which purchase, upgrade or transfer were refunded. - */ - public MessageRefundedUpgradedGift() { - } - - /** - * A gift which purchase, upgrade or transfer were refunded. - * - * @param gift The gift. - * @param senderId Sender of the gift. - * @param receiverId Receiver of the gift. - * @param origin Origin of the upgraded gift. - */ - public MessageRefundedUpgradedGift(Gift gift, MessageSender senderId, MessageSender receiverId, UpgradedGiftOrigin origin) { - this.gift = gift; - this.senderId = senderId; - this.receiverId = receiverId; - this.origin = origin; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -605744001; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An offer to purchase an upgraded gift was sent or received. - */ - public static class MessageUpgradedGiftPurchaseOffer extends MessageContent { - /** - * The gift. - */ - public UpgradedGift gift; - /** - * State of the offer. - */ - public GiftPurchaseOfferState state; - /** - * The proposed price. - */ - public GiftResalePrice price; - /** - * Point in time (Unix timestamp) when the offer will expire or has expired. - */ - public int expirationDate; - - /** - * An offer to purchase an upgraded gift was sent or received. - */ - public MessageUpgradedGiftPurchaseOffer() { - } - - /** - * An offer to purchase an upgraded gift was sent or received. - * - * @param gift The gift. - * @param state State of the offer. - * @param price The proposed price. - * @param expirationDate Point in time (Unix timestamp) when the offer will expire or has expired. - */ - public MessageUpgradedGiftPurchaseOffer(UpgradedGift gift, GiftPurchaseOfferState state, GiftResalePrice price, int expirationDate) { - this.gift = gift; - this.state = state; - this.price = price; - this.expirationDate = expirationDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1809958483; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An offer to purchase a gift was rejected or expired. - */ - public static class MessageUpgradedGiftPurchaseOfferRejected extends MessageContent { - /** - * The gift. - */ - public UpgradedGift gift; - /** - * The proposed price. - */ - public GiftResalePrice price; - /** - * Identifier of the message with purchase offer which was rejected or expired; may be 0 or an identifier of a deleted message. - */ - public long offerMessageId; - /** - * True, if the offer has expired; otherwise, the offer was explicitly rejected. - */ - public boolean wasExpired; - - /** - * An offer to purchase a gift was rejected or expired. - */ - public MessageUpgradedGiftPurchaseOfferRejected() { - } - - /** - * An offer to purchase a gift was rejected or expired. - * - * @param gift The gift. - * @param price The proposed price. - * @param offerMessageId Identifier of the message with purchase offer which was rejected or expired; may be 0 or an identifier of a deleted message. - * @param wasExpired True, if the offer has expired; otherwise, the offer was explicitly rejected. - */ - public MessageUpgradedGiftPurchaseOfferRejected(UpgradedGift gift, GiftResalePrice price, long offerMessageId, boolean wasExpired) { - this.gift = gift; - this.price = price; - this.offerMessageId = offerMessageId; - this.wasExpired = wasExpired; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 59315711; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Paid messages were refunded. - */ - public static class MessagePaidMessagesRefunded extends MessageContent { - /** - * The number of refunded messages. - */ - public int messageCount; - /** - * The number of refunded Telegram Stars. - */ - public long starCount; - - /** - * Paid messages were refunded. - */ - public MessagePaidMessagesRefunded() { - } - - /** - * Paid messages were refunded. - * - * @param messageCount The number of refunded messages. - * @param starCount The number of refunded Telegram Stars. - */ - public MessagePaidMessagesRefunded(int messageCount, long starCount) { - this.messageCount = messageCount; - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 580403343; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A price for paid messages was changed in the supergroup chat. - */ - public static class MessagePaidMessagePriceChanged extends MessageContent { - /** - * The new number of Telegram Stars that must be paid by non-administrator users of the supergroup chat for each sent message. - */ - public long paidMessageStarCount; - - /** - * A price for paid messages was changed in the supergroup chat. - */ - public MessagePaidMessagePriceChanged() { - } - - /** - * A price for paid messages was changed in the supergroup chat. - * - * @param paidMessageStarCount The new number of Telegram Stars that must be paid by non-administrator users of the supergroup chat for each sent message. - */ - public MessagePaidMessagePriceChanged(long paidMessageStarCount) { - this.paidMessageStarCount = paidMessageStarCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -344945397; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A price for direct messages was changed in the channel chat. - */ - public static class MessageDirectMessagePriceChanged extends MessageContent { - /** - * True, if direct messages group was enabled for the channel; false otherwise. - */ - public boolean isEnabled; - /** - * The new number of Telegram Stars that must be paid by non-administrator users of the channel chat for each message sent to the direct messages group; 0 if the direct messages group was disabled or the messages are free. - */ - public long paidMessageStarCount; - - /** - * A price for direct messages was changed in the channel chat. - */ - public MessageDirectMessagePriceChanged() { - } - - /** - * A price for direct messages was changed in the channel chat. - * - * @param isEnabled True, if direct messages group was enabled for the channel; false otherwise. - * @param paidMessageStarCount The new number of Telegram Stars that must be paid by non-administrator users of the channel chat for each message sent to the direct messages group; 0 if the direct messages group was disabled or the messages are free. - */ - public MessageDirectMessagePriceChanged(boolean isEnabled, long paidMessageStarCount) { - this.isEnabled = isEnabled; - this.paidMessageStarCount = paidMessageStarCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1320832439; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Some tasks from a checklist were marked as done or not done. - */ - public static class MessageChecklistTasksDone extends MessageContent { - /** - * Identifier of the message with the checklist; may be 0 or an identifier of a deleted message. - */ - public long checklistMessageId; - /** - * Identifiers of tasks that were marked as done. - */ - public int[] markedAsDoneTaskIds; - /** - * Identifiers of tasks that were marked as not done. - */ - public int[] markedAsNotDoneTaskIds; - - /** - * Some tasks from a checklist were marked as done or not done. - */ - public MessageChecklistTasksDone() { - } - - /** - * Some tasks from a checklist were marked as done or not done. - * - * @param checklistMessageId Identifier of the message with the checklist; may be 0 or an identifier of a deleted message. - * @param markedAsDoneTaskIds Identifiers of tasks that were marked as done. - * @param markedAsNotDoneTaskIds Identifiers of tasks that were marked as not done. - */ - public MessageChecklistTasksDone(long checklistMessageId, int[] markedAsDoneTaskIds, int[] markedAsNotDoneTaskIds) { - this.checklistMessageId = checklistMessageId; - this.markedAsDoneTaskIds = markedAsDoneTaskIds; - this.markedAsNotDoneTaskIds = markedAsNotDoneTaskIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -716083401; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Some tasks were added to a checklist. - */ - public static class MessageChecklistTasksAdded extends MessageContent { - /** - * Identifier of the message with the checklist; may be 0 or an identifier of a deleted message. - */ - public long checklistMessageId; - /** - * List of tasks added to the checklist. - */ - public ChecklistTask[] tasks; - - /** - * Some tasks were added to a checklist. - */ - public MessageChecklistTasksAdded() { - } - - /** - * Some tasks were added to a checklist. - * - * @param checklistMessageId Identifier of the message with the checklist; may be 0 or an identifier of a deleted message. - * @param tasks List of tasks added to the checklist. - */ - public MessageChecklistTasksAdded(long checklistMessageId, ChecklistTask[] tasks) { - this.checklistMessageId = checklistMessageId; - this.tasks = tasks; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2057538984; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Approval of suggested post has failed, because the user which proposed the post had no enough funds. - */ - public static class MessageSuggestedPostApprovalFailed extends MessageContent { - /** - * Identifier of the message with the suggested post; may be 0 or an identifier of a deleted message. - */ - public long suggestedPostMessageId; - /** - * Price of the suggested post. - */ - public SuggestedPostPrice price; - - /** - * Approval of suggested post has failed, because the user which proposed the post had no enough funds. - */ - public MessageSuggestedPostApprovalFailed() { - } - - /** - * Approval of suggested post has failed, because the user which proposed the post had no enough funds. - * - * @param suggestedPostMessageId Identifier of the message with the suggested post; may be 0 or an identifier of a deleted message. - * @param price Price of the suggested post. - */ - public MessageSuggestedPostApprovalFailed(long suggestedPostMessageId, SuggestedPostPrice price) { - this.suggestedPostMessageId = suggestedPostMessageId; - this.price = price; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1752703725; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A suggested post was approved. - */ - public static class MessageSuggestedPostApproved extends MessageContent { - /** - * Identifier of the message with the suggested post; may be 0 or an identifier of a deleted message. - */ - public long suggestedPostMessageId; - /** - * Price of the suggested post; may be null if the post is non-paid. - */ - @Nullable public SuggestedPostPrice price; - /** - * Point in time (Unix timestamp) when the post is expected to be published. - */ - public int sendDate; - - /** - * A suggested post was approved. - */ - public MessageSuggestedPostApproved() { - } - - /** - * A suggested post was approved. - * - * @param suggestedPostMessageId Identifier of the message with the suggested post; may be 0 or an identifier of a deleted message. - * @param price Price of the suggested post; may be null if the post is non-paid. - * @param sendDate Point in time (Unix timestamp) when the post is expected to be published. - */ - public MessageSuggestedPostApproved(long suggestedPostMessageId, SuggestedPostPrice price, int sendDate) { - this.suggestedPostMessageId = suggestedPostMessageId; - this.price = price; - this.sendDate = sendDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 563425361; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A suggested post was declined. - */ - public static class MessageSuggestedPostDeclined extends MessageContent { - /** - * Identifier of the message with the suggested post; may be 0 or an identifier of a deleted message. - */ - public long suggestedPostMessageId; - /** - * Comment added by administrator of the channel when the post was declined. - */ - public String comment; - - /** - * A suggested post was declined. - */ - public MessageSuggestedPostDeclined() { - } - - /** - * A suggested post was declined. - * - * @param suggestedPostMessageId Identifier of the message with the suggested post; may be 0 or an identifier of a deleted message. - * @param comment Comment added by administrator of the channel when the post was declined. - */ - public MessageSuggestedPostDeclined(long suggestedPostMessageId, String comment) { - this.suggestedPostMessageId = suggestedPostMessageId; - this.comment = comment; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -26948155; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A suggested post was published for getOption("suggested_post_lifetime_min") seconds and payment for the post was received. - */ - public static class MessageSuggestedPostPaid extends MessageContent { - /** - * Identifier of the message with the suggested post; may be 0 or an identifier of a deleted message. - */ - public long suggestedPostMessageId; - /** - * The amount of received Telegram Stars. - */ - public StarAmount starAmount; - /** - * The amount of received Toncoins; in the smallest units of the cryptocurrency. - */ - public long tonAmount; - - /** - * A suggested post was published for getOption("suggested_post_lifetime_min") seconds and payment for the post was received. - */ - public MessageSuggestedPostPaid() { - } - - /** - * A suggested post was published for getOption("suggested_post_lifetime_min") seconds and payment for the post was received. - * - * @param suggestedPostMessageId Identifier of the message with the suggested post; may be 0 or an identifier of a deleted message. - * @param starAmount The amount of received Telegram Stars. - * @param tonAmount The amount of received Toncoins; in the smallest units of the cryptocurrency. - */ - public MessageSuggestedPostPaid(long suggestedPostMessageId, StarAmount starAmount, long tonAmount) { - this.suggestedPostMessageId = suggestedPostMessageId; - this.starAmount = starAmount; - this.tonAmount = tonAmount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1575439273; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A suggested post was refunded. - */ - public static class MessageSuggestedPostRefunded extends MessageContent { - /** - * Identifier of the message with the suggested post; may be 0 or an identifier of a deleted message. - */ - public long suggestedPostMessageId; - /** - * Reason of the refund. - */ - public SuggestedPostRefundReason reason; - - /** - * A suggested post was refunded. - */ - public MessageSuggestedPostRefunded() { - } - - /** - * A suggested post was refunded. - * - * @param suggestedPostMessageId Identifier of the message with the suggested post; may be 0 or an identifier of a deleted message. - * @param reason Reason of the refund. - */ - public MessageSuggestedPostRefunded(long suggestedPostMessageId, SuggestedPostRefundReason reason) { - this.suggestedPostMessageId = suggestedPostMessageId; - this.reason = reason; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -554073340; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A contact has registered with Telegram. - */ - public static class MessageContactRegistered extends MessageContent { - - /** - * A contact has registered with Telegram. - */ - public MessageContactRegistered() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1502020353; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The current user shared users, which were requested by the bot. - */ - public static class MessageUsersShared extends MessageContent { - /** - * The shared users. - */ - public SharedUser[] users; - /** - * Identifier of the keyboard button with the request. - */ - public int buttonId; - - /** - * The current user shared users, which were requested by the bot. - */ - public MessageUsersShared() { - } - - /** - * The current user shared users, which were requested by the bot. - * - * @param users The shared users. - * @param buttonId Identifier of the keyboard button with the request. - */ - public MessageUsersShared(SharedUser[] users, int buttonId) { - this.users = users; - this.buttonId = buttonId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -842442318; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The current user shared a chat, which was requested by the bot. - */ - public static class MessageChatShared extends MessageContent { - /** - * The shared chat. - */ - public SharedChat chat; - /** - * Identifier of the keyboard button with the request. - */ - public int buttonId; - - /** - * The current user shared a chat, which was requested by the bot. - */ - public MessageChatShared() { - } - - /** - * The current user shared a chat, which was requested by the bot. - * - * @param chat The shared chat. - * @param buttonId Identifier of the keyboard button with the request. - */ - public MessageChatShared(SharedChat chat, int buttonId) { - this.chat = chat; - this.buttonId = buttonId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1362699935; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user allowed the bot to send messages. - */ - public static class MessageBotWriteAccessAllowed extends MessageContent { - /** - * The reason why the bot was allowed to write messages. - */ - public BotWriteAccessAllowReason reason; - - /** - * The user allowed the bot to send messages. - */ - public MessageBotWriteAccessAllowed() { - } - - /** - * The user allowed the bot to send messages. - * - * @param reason The reason why the bot was allowed to write messages. - */ - public MessageBotWriteAccessAllowed(BotWriteAccessAllowReason reason) { - this.reason = reason; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1702185036; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Data from a Web App has been sent to a bot. - */ - public static class MessageWebAppDataSent extends MessageContent { - /** - * Text of the keyboardButtonTypeWebApp button, which opened the Web App. - */ - public String buttonText; - - /** - * Data from a Web App has been sent to a bot. - */ - public MessageWebAppDataSent() { - } - - /** - * Data from a Web App has been sent to a bot. - * - * @param buttonText Text of the keyboardButtonTypeWebApp button, which opened the Web App. - */ - public MessageWebAppDataSent(String buttonText) { - this.buttonText = buttonText; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -83674862; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Data from a Web App has been received; for bots only. - */ - public static class MessageWebAppDataReceived extends MessageContent { - /** - * Text of the keyboardButtonTypeWebApp button, which opened the Web App. - */ - public String buttonText; - /** - * The data. - */ - public String data; - - /** - * Data from a Web App has been received; for bots only. - */ - public MessageWebAppDataReceived() { - } - - /** - * Data from a Web App has been received; for bots only. - * - * @param buttonText Text of the keyboardButtonTypeWebApp button, which opened the Web App. - * @param data The data. - */ - public MessageWebAppDataReceived(String buttonText, String data) { - this.buttonText = buttonText; - this.data = data; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -8578539; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Telegram Passport data has been sent to a bot. - */ - public static class MessagePassportDataSent extends MessageContent { - /** - * List of Telegram Passport element types sent. - */ - public PassportElementType[] types; - - /** - * Telegram Passport data has been sent to a bot. - */ - public MessagePassportDataSent() { - } - - /** - * Telegram Passport data has been sent to a bot. - * - * @param types List of Telegram Passport element types sent. - */ - public MessagePassportDataSent(PassportElementType[] types) { - this.types = types; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1017405171; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Telegram Passport data has been received; for bots only. - */ - public static class MessagePassportDataReceived extends MessageContent { - /** - * List of received Telegram Passport elements. - */ - public EncryptedPassportElement[] elements; - /** - * Encrypted data credentials. - */ - public EncryptedCredentials credentials; - - /** - * Telegram Passport data has been received; for bots only. - */ - public MessagePassportDataReceived() { - } - - /** - * Telegram Passport data has been received; for bots only. - * - * @param elements List of received Telegram Passport elements. - * @param credentials Encrypted data credentials. - */ - public MessagePassportDataReceived(EncryptedPassportElement[] elements, EncryptedCredentials credentials) { - this.elements = elements; - this.credentials = credentials; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1367863624; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A user in the chat came within proximity alert range. - */ - public static class MessageProximityAlertTriggered extends MessageContent { - /** - * The identifier of a user or chat that triggered the proximity alert. - */ - public MessageSender travelerId; - /** - * The identifier of a user or chat that subscribed for the proximity alert. - */ - public MessageSender watcherId; - /** - * The distance between the users. - */ - public int distance; - - /** - * A user in the chat came within proximity alert range. - */ - public MessageProximityAlertTriggered() { - } - - /** - * A user in the chat came within proximity alert range. - * - * @param travelerId The identifier of a user or chat that triggered the proximity alert. - * @param watcherId The identifier of a user or chat that subscribed for the proximity alert. - * @param distance The distance between the users. - */ - public MessageProximityAlertTriggered(MessageSender travelerId, MessageSender watcherId, int distance) { - this.travelerId = travelerId; - this.watcherId = watcherId; - this.distance = distance; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 67761875; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message content that is not supported in the current TDLib version. - */ - public static class MessageUnsupported extends MessageContent { - - /** - * A message content that is not supported in the current TDLib version. - */ - public MessageUnsupported() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1816726139; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Options to be used when a message content is copied without reference to the original sender. Service messages, messages with messageInvoice, messagePaidMedia, messageGiveaway, or messageGiveawayWinners content can't be copied. - */ - public static class MessageCopyOptions extends Object { - /** - * True, if content of the message needs to be copied without reference to the original sender. Always true if the message is forwarded to a secret chat or is local. Use messageProperties.canBeCopied and messageProperties.canBeCopiedToSecretChat to check whether the message is suitable. - */ - public boolean sendCopy; - /** - * True, if media caption of the message copy needs to be replaced. Ignored if sendCopy is false. - */ - public boolean replaceCaption; - /** - * New message caption; pass null to copy message without caption. Ignored if replaceCaption is false. - */ - public FormattedText newCaption; - /** - * True, if new caption must be shown above the media; otherwise, new caption must be shown below the media; not supported in secret chats. Ignored if replaceCaption is false. - */ - public boolean newShowCaptionAboveMedia; - - /** - * Options to be used when a message content is copied without reference to the original sender. Service messages, messages with messageInvoice, messagePaidMedia, messageGiveaway, or messageGiveawayWinners content can't be copied. - */ - public MessageCopyOptions() { - } - - /** - * Options to be used when a message content is copied without reference to the original sender. Service messages, messages with messageInvoice, messagePaidMedia, messageGiveaway, or messageGiveawayWinners content can't be copied. - * - * @param sendCopy True, if content of the message needs to be copied without reference to the original sender. Always true if the message is forwarded to a secret chat or is local. Use messageProperties.canBeCopied and messageProperties.canBeCopiedToSecretChat to check whether the message is suitable. - * @param replaceCaption True, if media caption of the message copy needs to be replaced. Ignored if sendCopy is false. - * @param newCaption New message caption; pass null to copy message without caption. Ignored if replaceCaption is false. - * @param newShowCaptionAboveMedia True, if new caption must be shown above the media; otherwise, new caption must be shown below the media; not supported in secret chats. Ignored if replaceCaption is false. - */ - public MessageCopyOptions(boolean sendCopy, boolean replaceCaption, FormattedText newCaption, boolean newShowCaptionAboveMedia) { - this.sendCopy = sendCopy; - this.replaceCaption = replaceCaption; - this.newCaption = newCaption; - this.newShowCaptionAboveMedia = newShowCaptionAboveMedia; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1079772090; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about an effect added to a message. - */ - public static class MessageEffect extends Object { - /** - * Unique identifier of the effect. - */ - public long id; - /** - * Static icon for the effect in WEBP format; may be null if none. - */ - @Nullable public Sticker staticIcon; - /** - * Emoji corresponding to the effect that can be used if static icon isn't available. - */ - public String emoji; - /** - * True, if Telegram Premium subscription is required to use the effect. - */ - public boolean isPremium; - /** - * Type of the effect. - */ - public MessageEffectType type; - - /** - * Contains information about an effect added to a message. - */ - public MessageEffect() { - } - - /** - * Contains information about an effect added to a message. - * - * @param id Unique identifier of the effect. - * @param staticIcon Static icon for the effect in WEBP format; may be null if none. - * @param emoji Emoji corresponding to the effect that can be used if static icon isn't available. - * @param isPremium True, if Telegram Premium subscription is required to use the effect. - * @param type Type of the effect. - */ - public MessageEffect(long id, Sticker staticIcon, String emoji, boolean isPremium, MessageEffectType type) { - this.id = id; - this.staticIcon = staticIcon; - this.emoji = emoji; - this.isPremium = isPremium; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1758836433; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of emoji effect. - */ - public abstract static class MessageEffectType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - MessageEffectTypeEmojiReaction.CONSTRUCTOR, - MessageEffectTypePremiumSticker.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public MessageEffectType() { - } - } - - /** - * An effect from an emoji reaction. - */ - public static class MessageEffectTypeEmojiReaction extends MessageEffectType { - /** - * Select animation for the effect in TGS format. - */ - public Sticker selectAnimation; - /** - * Effect animation for the effect in TGS format. - */ - public Sticker effectAnimation; - - /** - * An effect from an emoji reaction. - */ - public MessageEffectTypeEmojiReaction() { - } - - /** - * An effect from an emoji reaction. - * - * @param selectAnimation Select animation for the effect in TGS format. - * @param effectAnimation Effect animation for the effect in TGS format. - */ - public MessageEffectTypeEmojiReaction(Sticker selectAnimation, Sticker effectAnimation) { - this.selectAnimation = selectAnimation; - this.effectAnimation = effectAnimation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1756079678; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An effect from a premium sticker. - */ - public static class MessageEffectTypePremiumSticker extends MessageEffectType { - /** - * The premium sticker. The effect can be found at sticker.fullType.premiumAnimation. - */ - public Sticker sticker; - - /** - * An effect from a premium sticker. - */ - public MessageEffectTypePremiumSticker() { - } - - /** - * An effect from a premium sticker. - * - * @param sticker The premium sticker. The effect can be found at sticker.fullType.premiumAnimation. - */ - public MessageEffectTypePremiumSticker(Sticker sticker) { - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1637231609; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains information about a file with messages exported from another app. - */ - public abstract static class MessageFileType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - MessageFileTypePrivate.CONSTRUCTOR, - MessageFileTypeGroup.CONSTRUCTOR, - MessageFileTypeUnknown.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public MessageFileType() { - } - } - - /** - * The messages were exported from a private chat. - */ - public static class MessageFileTypePrivate extends MessageFileType { - /** - * Name of the other party; may be empty if unrecognized. - */ - public String name; - - /** - * The messages were exported from a private chat. - */ - public MessageFileTypePrivate() { - } - - /** - * The messages were exported from a private chat. - * - * @param name Name of the other party; may be empty if unrecognized. - */ - public MessageFileTypePrivate(String name) { - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -521908524; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The messages were exported from a group chat. - */ - public static class MessageFileTypeGroup extends MessageFileType { - /** - * Title of the group chat; may be empty if unrecognized. - */ - public String title; - - /** - * The messages were exported from a group chat. - */ - public MessageFileTypeGroup() { - } - - /** - * The messages were exported from a group chat. - * - * @param title Title of the group chat; may be empty if unrecognized. - */ - public MessageFileTypeGroup(String title) { - this.title = title; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -219836568; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The messages were exported from a chat of unknown type. - */ - public static class MessageFileTypeUnknown extends MessageFileType { - - /** - * The messages were exported from a chat of unknown type. - */ - public MessageFileTypeUnknown() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1176353458; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a forwarded message. - */ - public static class MessageForwardInfo extends Object { - /** - * Origin of the forwarded message. - */ - public MessageOrigin origin; - /** - * Point in time (Unix timestamp) when the message was originally sent. - */ - public int date; - /** - * For messages forwarded to the chat with the current user (Saved Messages), to the Replies bot chat, or to the channel's discussion group, information about the source message from which the message was forwarded last time; may be null for other forwards or if unknown. - */ - @Nullable public ForwardSource source; - /** - * The type of public service announcement for the forwarded message. - */ - public String publicServiceAnnouncementType; - - /** - * Contains information about a forwarded message. - */ - public MessageForwardInfo() { - } - - /** - * Contains information about a forwarded message. - * - * @param origin Origin of the forwarded message. - * @param date Point in time (Unix timestamp) when the message was originally sent. - * @param source For messages forwarded to the chat with the current user (Saved Messages), to the Replies bot chat, or to the channel's discussion group, information about the source message from which the message was forwarded last time; may be null for other forwards or if unknown. - * @param publicServiceAnnouncementType The type of public service announcement for the forwarded message. - */ - public MessageForwardInfo(MessageOrigin origin, int date, ForwardSource source, String publicServiceAnnouncementType) { - this.origin = origin; - this.date = date; - this.source = source; - this.publicServiceAnnouncementType = publicServiceAnnouncementType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -880313475; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a message created with importMessages. - */ - public static class MessageImportInfo extends Object { - /** - * Name of the original sender. - */ - public String senderName; - /** - * Point in time (Unix timestamp) when the message was originally sent. - */ - public int date; - - /** - * Contains information about a message created with importMessages. - */ - public MessageImportInfo() { - } - - /** - * Contains information about a message created with importMessages. - * - * @param senderName Name of the original sender. - * @param date Point in time (Unix timestamp) when the message was originally sent. - */ - public MessageImportInfo(String senderName, int date) { - this.senderName = senderName; - this.date = date; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -421549105; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about interactions with a message. - */ - public static class MessageInteractionInfo extends Object { - /** - * Number of times the message was viewed. - */ - public int viewCount; - /** - * Number of times the message was forwarded. - */ - public int forwardCount; - /** - * Information about direct or indirect replies to the message; may be null. Currently, available only in channels with a discussion supergroup and discussion supergroups for messages, which are not replies itself. - */ - @Nullable public MessageReplyInfo replyInfo; - /** - * The list of reactions or tags added to the message; may be null. - */ - @Nullable public MessageReactions reactions; - - /** - * Contains information about interactions with a message. - */ - public MessageInteractionInfo() { - } - - /** - * Contains information about interactions with a message. - * - * @param viewCount Number of times the message was viewed. - * @param forwardCount Number of times the message was forwarded. - * @param replyInfo Information about direct or indirect replies to the message; may be null. Currently, available only in channels with a discussion supergroup and discussion supergroups for messages, which are not replies itself. - * @param reactions The list of reactions or tags added to the message; may be null. - */ - public MessageInteractionInfo(int viewCount, int forwardCount, MessageReplyInfo replyInfo, MessageReactions reactions) { - this.viewCount = viewCount; - this.forwardCount = forwardCount; - this.replyInfo = replyInfo; - this.reactions = reactions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 733797893; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains an HTTPS link to a message in a supergroup or channel, or a forum topic. - */ - public static class MessageLink extends Object { - /** - * The link. - */ - public String link; - /** - * True, if the link will work for non-members of the chat. - */ - public boolean isPublic; - - /** - * Contains an HTTPS link to a message in a supergroup or channel, or a forum topic. - */ - public MessageLink() { - } - - /** - * Contains an HTTPS link to a message in a supergroup or channel, or a forum topic. - * - * @param link The link. - * @param isPublic True, if the link will work for non-members of the chat. - */ - public MessageLink(String link, boolean isPublic) { - this.link = link; - this.isPublic = isPublic; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1354089818; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a link to a message or a forum topic in a chat. - */ - public static class MessageLinkInfo extends Object { - /** - * True, if the link is a public link for a message or a forum topic in a chat. - */ - public boolean isPublic; - /** - * If found, identifier of the chat to which the link points, 0 otherwise. - */ - public long chatId; - /** - * Identifier of the specific topic in which the message must be opened, or a topic to open if the message is missing; may be null if none. - */ - @Nullable public MessageTopic topicId; - /** - * If found, the linked message; may be null. - */ - @Nullable public Message message; - /** - * Timestamp from which the video/audio/video note/voice note/story playing must start, in seconds; 0 if not specified. The media can be in the message content or in its link preview. - */ - public int mediaTimestamp; - /** - * True, if the whole media album to which the message belongs is linked. - */ - public boolean forAlbum; - - /** - * Contains information about a link to a message or a forum topic in a chat. - */ - public MessageLinkInfo() { - } - - /** - * Contains information about a link to a message or a forum topic in a chat. - * - * @param isPublic True, if the link is a public link for a message or a forum topic in a chat. - * @param chatId If found, identifier of the chat to which the link points, 0 otherwise. - * @param topicId Identifier of the specific topic in which the message must be opened, or a topic to open if the message is missing; may be null if none. - * @param message If found, the linked message; may be null. - * @param mediaTimestamp Timestamp from which the video/audio/video note/voice note/story playing must start, in seconds; 0 if not specified. The media can be in the message content or in its link preview. - * @param forAlbum True, if the whole media album to which the message belongs is linked. - */ - public MessageLinkInfo(boolean isPublic, long chatId, MessageTopic topicId, Message message, int mediaTimestamp, boolean forAlbum) { - this.isPublic = isPublic; - this.chatId = chatId; - this.topicId = topicId; - this.message = message; - this.mediaTimestamp = mediaTimestamp; - this.forAlbum = forAlbum; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 361619055; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains information about the origin of a message. - */ - public abstract static class MessageOrigin extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - MessageOriginUser.CONSTRUCTOR, - MessageOriginHiddenUser.CONSTRUCTOR, - MessageOriginChat.CONSTRUCTOR, - MessageOriginChannel.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public MessageOrigin() { - } - } - - /** - * The message was originally sent by a known user. - */ - public static class MessageOriginUser extends MessageOrigin { - /** - * Identifier of the user who originally sent the message. - */ - public long senderUserId; - - /** - * The message was originally sent by a known user. - */ - public MessageOriginUser() { - } - - /** - * The message was originally sent by a known user. - * - * @param senderUserId Identifier of the user who originally sent the message. - */ - public MessageOriginUser(long senderUserId) { - this.senderUserId = senderUserId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1677684669; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message was originally sent by a user, which is hidden by their privacy settings. - */ - public static class MessageOriginHiddenUser extends MessageOrigin { - /** - * Name of the sender. - */ - public String senderName; - - /** - * The message was originally sent by a user, which is hidden by their privacy settings. - */ - public MessageOriginHiddenUser() { - } - - /** - * The message was originally sent by a user, which is hidden by their privacy settings. - * - * @param senderName Name of the sender. - */ - public MessageOriginHiddenUser(String senderName) { - this.senderName = senderName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -317971494; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message was originally sent on behalf of a chat. - */ - public static class MessageOriginChat extends MessageOrigin { - /** - * Identifier of the chat that originally sent the message. - */ - public long senderChatId; - /** - * For messages originally sent by an anonymous chat administrator, original message author signature. - */ - public String authorSignature; - - /** - * The message was originally sent on behalf of a chat. - */ - public MessageOriginChat() { - } - - /** - * The message was originally sent on behalf of a chat. - * - * @param senderChatId Identifier of the chat that originally sent the message. - * @param authorSignature For messages originally sent by an anonymous chat administrator, original message author signature. - */ - public MessageOriginChat(long senderChatId, String authorSignature) { - this.senderChatId = senderChatId; - this.authorSignature = authorSignature; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -205824332; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message was originally a post in a channel. - */ - public static class MessageOriginChannel extends MessageOrigin { - /** - * Identifier of the channel chat to which the message was originally sent. - */ - public long chatId; - /** - * Message identifier of the original message. - */ - public long messageId; - /** - * Original post author signature. - */ - public String authorSignature; - - /** - * The message was originally a post in a channel. - */ - public MessageOriginChannel() { - } - - /** - * The message was originally a post in a channel. - * - * @param chatId Identifier of the channel chat to which the message was originally sent. - * @param messageId Message identifier of the original message. - * @param authorSignature Original post author signature. - */ - public MessageOriginChannel(long chatId, long messageId, String authorSignature) { - this.chatId = chatId; - this.messageId = messageId; - this.authorSignature = authorSignature; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1451535938; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a message in a specific position. - */ - public static class MessagePosition extends Object { - /** - * 0-based message position in the full list of suitable messages. - */ - public int position; - /** - * Message identifier. - */ - public long messageId; - /** - * Point in time (Unix timestamp) when the message was sent. - */ - public int date; - - /** - * Contains information about a message in a specific position. - */ - public MessagePosition() { - } - - /** - * Contains information about a message in a specific position. - * - * @param position 0-based message position in the full list of suitable messages. - * @param messageId Message identifier. - * @param date Point in time (Unix timestamp) when the message was sent. - */ - public MessagePosition(int position, long messageId, int date) { - this.position = position; - this.messageId = messageId; - this.date = date; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1292189935; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of message positions. - */ - public static class MessagePositions extends Object { - /** - * Total number of messages found. - */ - public int totalCount; - /** - * List of message positions. - */ - public MessagePosition[] positions; - - /** - * Contains a list of message positions. - */ - public MessagePositions() { - } - - /** - * Contains a list of message positions. - * - * @param totalCount Total number of messages found. - * @param positions List of message positions. - */ - public MessagePositions(int totalCount, MessagePosition[] positions) { - this.totalCount = totalCount; - this.positions = positions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1930466649; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains properties of a message and describes actions that can be done with the message right now. - */ - public static class MessageProperties extends Object { - /** - * True, if an offer can be added to the message using addOffer. - */ - public boolean canAddOffer; - /** - * True, if tasks can be added to the message's checklist using addChecklistTasks if the current user has Telegram Premium subscription. - */ - public boolean canAddTasks; - /** - * True, if the message is a suggested post that can be approved by the user using approveSuggestedPost. - */ - public boolean canBeApproved; - /** - * True, if content of the message can be copied using inputMessageForwarded or forwardMessages with copy options. - */ - public boolean canBeCopied; - /** - * True, if content of the message can be copied to a secret chat using inputMessageForwarded or forwardMessages with copy options. - */ - public boolean canBeCopiedToSecretChat; - /** - * True, if the message is a suggested post that can be declined by the user using declineSuggestedPost. - */ - public boolean canBeDeclined; - /** - * True, if the message can be deleted only for the current user while other users will continue to see it using the method deleteMessages with revoke == false. - */ - public boolean canBeDeletedOnlyForSelf; - /** - * True, if the message can be deleted for all users using the method deleteMessages with revoke == true. - */ - public boolean canBeDeletedForAllUsers; - /** - * True, if the message can be edited using the methods editMessageText, editMessageCaption, or editMessageReplyMarkup. For live location, poll, and checklist messages this fields shows whether editMessageLiveLocation, stopPoll, or editMessageChecklist respectively can be used with this message. - */ - public boolean canBeEdited; - /** - * True, if the message can be forwarded using inputMessageForwarded or forwardMessages without copy options. - */ - public boolean canBeForwarded; - /** - * True, if the message can be paid using inputInvoiceMessage. - */ - public boolean canBePaid; - /** - * True, if the message can be pinned or unpinned in the chat using pinChatMessage or unpinChatMessage. - */ - public boolean canBePinned; - /** - * True, if the message can be replied in the same chat and forum topic using inputMessageReplyToMessage. - */ - public boolean canBeReplied; - /** - * True, if the message can be replied in another chat or forum topic using inputMessageReplyToExternalMessage. - */ - public boolean canBeRepliedInAnotherChat; - /** - * True, if content of the message can be saved locally. - */ - public boolean canBeSaved; - /** - * True, if the message can be shared in a story using inputStoryAreaTypeMessage. - */ - public boolean canBeSharedInStory; - /** - * True, if the message can be edited using the method editMessageMedia. - */ - public boolean canEditMedia; - /** - * True, if scheduling state of the message can be edited. - */ - public boolean canEditSchedulingState; - /** - * True, if another price or post send time can be suggested using addOffer. - */ - public boolean canEditSuggestedPostInfo; - /** - * True, if author of the message sent on behalf of a chat can be received through getMessageAuthor. - */ - public boolean canGetAuthor; - /** - * True, if code for message embedding can be received using getMessageEmbeddingCode. - */ - public boolean canGetEmbeddingCode; - /** - * True, if a link can be generated for the message using getMessageLink. - */ - public boolean canGetLink; - /** - * True, if media timestamp links can be generated for media timestamp entities in the message text, caption or link preview description using getMessageLink. - */ - public boolean canGetMediaTimestampLinks; - /** - * True, if information about the message thread is available through getMessageThread and getMessageThreadHistory. - */ - public boolean canGetMessageThread; - /** - * True, if read date of the message can be received through getMessageReadDate. - */ - public boolean canGetReadDate; - /** - * True, if message statistics are available through getMessageStatistics and message forwards can be received using getMessagePublicForwards. - */ - public boolean canGetStatistics; - /** - * True, if advertisements for video of the message can be received though getVideoMessageAdvertisements. - */ - public boolean canGetVideoAdvertisements; - /** - * True, if chat members already viewed the message can be received through getMessageViewers. - */ - public boolean canGetViewers; - /** - * True, if tasks can be marked as done or not done in the message's checklist using markChecklistTasksAsDone if the current user has Telegram Premium subscription. - */ - public boolean canMarkTasksAsDone; - /** - * True, if speech can be recognized for the message through recognizeSpeech. - */ - public boolean canRecognizeSpeech; - /** - * True, if the message can be reported using reportChat. - */ - public boolean canReportChat; - /** - * True, if reactions on the message can be reported through reportMessageReactions. - */ - public boolean canReportReactions; - /** - * True, if the message can be reported using reportSupergroupSpam. - */ - public boolean canReportSupergroupSpam; - /** - * True, if fact check for the message can be changed through setMessageFactCheck. - */ - public boolean canSetFactCheck; - /** - * True, if content of the message can't be saved locally, because it is protected by the current user; if true, then canBeSaved is false. - */ - public boolean hasProtectedContentByCurrentUser; - /** - * True, if content of the message can't be saved locally, because it is protected by the other user; if true, then canBeSaved is false. - */ - public boolean hasProtectedContentByOtherUser; - /** - * True, if message statistics must be available from context menu of the message. - */ - public boolean needShowStatistics; - - /** - * Contains properties of a message and describes actions that can be done with the message right now. - */ - public MessageProperties() { - } - - /** - * Contains properties of a message and describes actions that can be done with the message right now. - * - * @param canAddOffer True, if an offer can be added to the message using addOffer. - * @param canAddTasks True, if tasks can be added to the message's checklist using addChecklistTasks if the current user has Telegram Premium subscription. - * @param canBeApproved True, if the message is a suggested post that can be approved by the user using approveSuggestedPost. - * @param canBeCopied True, if content of the message can be copied using inputMessageForwarded or forwardMessages with copy options. - * @param canBeCopiedToSecretChat True, if content of the message can be copied to a secret chat using inputMessageForwarded or forwardMessages with copy options. - * @param canBeDeclined True, if the message is a suggested post that can be declined by the user using declineSuggestedPost. - * @param canBeDeletedOnlyForSelf True, if the message can be deleted only for the current user while other users will continue to see it using the method deleteMessages with revoke == false. - * @param canBeDeletedForAllUsers True, if the message can be deleted for all users using the method deleteMessages with revoke == true. - * @param canBeEdited True, if the message can be edited using the methods editMessageText, editMessageCaption, or editMessageReplyMarkup. For live location, poll, and checklist messages this fields shows whether editMessageLiveLocation, stopPoll, or editMessageChecklist respectively can be used with this message. - * @param canBeForwarded True, if the message can be forwarded using inputMessageForwarded or forwardMessages without copy options. - * @param canBePaid True, if the message can be paid using inputInvoiceMessage. - * @param canBePinned True, if the message can be pinned or unpinned in the chat using pinChatMessage or unpinChatMessage. - * @param canBeReplied True, if the message can be replied in the same chat and forum topic using inputMessageReplyToMessage. - * @param canBeRepliedInAnotherChat True, if the message can be replied in another chat or forum topic using inputMessageReplyToExternalMessage. - * @param canBeSaved True, if content of the message can be saved locally. - * @param canBeSharedInStory True, if the message can be shared in a story using inputStoryAreaTypeMessage. - * @param canEditMedia True, if the message can be edited using the method editMessageMedia. - * @param canEditSchedulingState True, if scheduling state of the message can be edited. - * @param canEditSuggestedPostInfo True, if another price or post send time can be suggested using addOffer. - * @param canGetAuthor True, if author of the message sent on behalf of a chat can be received through getMessageAuthor. - * @param canGetEmbeddingCode True, if code for message embedding can be received using getMessageEmbeddingCode. - * @param canGetLink True, if a link can be generated for the message using getMessageLink. - * @param canGetMediaTimestampLinks True, if media timestamp links can be generated for media timestamp entities in the message text, caption or link preview description using getMessageLink. - * @param canGetMessageThread True, if information about the message thread is available through getMessageThread and getMessageThreadHistory. - * @param canGetReadDate True, if read date of the message can be received through getMessageReadDate. - * @param canGetStatistics True, if message statistics are available through getMessageStatistics and message forwards can be received using getMessagePublicForwards. - * @param canGetVideoAdvertisements True, if advertisements for video of the message can be received though getVideoMessageAdvertisements. - * @param canGetViewers True, if chat members already viewed the message can be received through getMessageViewers. - * @param canMarkTasksAsDone True, if tasks can be marked as done or not done in the message's checklist using markChecklistTasksAsDone if the current user has Telegram Premium subscription. - * @param canRecognizeSpeech True, if speech can be recognized for the message through recognizeSpeech. - * @param canReportChat True, if the message can be reported using reportChat. - * @param canReportReactions True, if reactions on the message can be reported through reportMessageReactions. - * @param canReportSupergroupSpam True, if the message can be reported using reportSupergroupSpam. - * @param canSetFactCheck True, if fact check for the message can be changed through setMessageFactCheck. - * @param hasProtectedContentByCurrentUser True, if content of the message can't be saved locally, because it is protected by the current user; if true, then canBeSaved is false. - * @param hasProtectedContentByOtherUser True, if content of the message can't be saved locally, because it is protected by the other user; if true, then canBeSaved is false. - * @param needShowStatistics True, if message statistics must be available from context menu of the message. - */ - public MessageProperties(boolean canAddOffer, boolean canAddTasks, boolean canBeApproved, boolean canBeCopied, boolean canBeCopiedToSecretChat, boolean canBeDeclined, boolean canBeDeletedOnlyForSelf, boolean canBeDeletedForAllUsers, boolean canBeEdited, boolean canBeForwarded, boolean canBePaid, boolean canBePinned, boolean canBeReplied, boolean canBeRepliedInAnotherChat, boolean canBeSaved, boolean canBeSharedInStory, boolean canEditMedia, boolean canEditSchedulingState, boolean canEditSuggestedPostInfo, boolean canGetAuthor, boolean canGetEmbeddingCode, boolean canGetLink, boolean canGetMediaTimestampLinks, boolean canGetMessageThread, boolean canGetReadDate, boolean canGetStatistics, boolean canGetVideoAdvertisements, boolean canGetViewers, boolean canMarkTasksAsDone, boolean canRecognizeSpeech, boolean canReportChat, boolean canReportReactions, boolean canReportSupergroupSpam, boolean canSetFactCheck, boolean hasProtectedContentByCurrentUser, boolean hasProtectedContentByOtherUser, boolean needShowStatistics) { - this.canAddOffer = canAddOffer; - this.canAddTasks = canAddTasks; - this.canBeApproved = canBeApproved; - this.canBeCopied = canBeCopied; - this.canBeCopiedToSecretChat = canBeCopiedToSecretChat; - this.canBeDeclined = canBeDeclined; - this.canBeDeletedOnlyForSelf = canBeDeletedOnlyForSelf; - this.canBeDeletedForAllUsers = canBeDeletedForAllUsers; - this.canBeEdited = canBeEdited; - this.canBeForwarded = canBeForwarded; - this.canBePaid = canBePaid; - this.canBePinned = canBePinned; - this.canBeReplied = canBeReplied; - this.canBeRepliedInAnotherChat = canBeRepliedInAnotherChat; - this.canBeSaved = canBeSaved; - this.canBeSharedInStory = canBeSharedInStory; - this.canEditMedia = canEditMedia; - this.canEditSchedulingState = canEditSchedulingState; - this.canEditSuggestedPostInfo = canEditSuggestedPostInfo; - this.canGetAuthor = canGetAuthor; - this.canGetEmbeddingCode = canGetEmbeddingCode; - this.canGetLink = canGetLink; - this.canGetMediaTimestampLinks = canGetMediaTimestampLinks; - this.canGetMessageThread = canGetMessageThread; - this.canGetReadDate = canGetReadDate; - this.canGetStatistics = canGetStatistics; - this.canGetVideoAdvertisements = canGetVideoAdvertisements; - this.canGetViewers = canGetViewers; - this.canMarkTasksAsDone = canMarkTasksAsDone; - this.canRecognizeSpeech = canRecognizeSpeech; - this.canReportChat = canReportChat; - this.canReportReactions = canReportReactions; - this.canReportSupergroupSpam = canReportSupergroupSpam; - this.canSetFactCheck = canSetFactCheck; - this.hasProtectedContentByCurrentUser = hasProtectedContentByCurrentUser; - this.hasProtectedContentByOtherUser = hasProtectedContentByOtherUser; - this.needShowStatistics = needShowStatistics; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1101612747; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a reaction to a message. - */ - public static class MessageReaction extends Object { - /** - * Type of the reaction. - */ - public ReactionType type; - /** - * Number of times the reaction was added. - */ - public int totalCount; - /** - * True, if the reaction is chosen by the current user. - */ - public boolean isChosen; - /** - * Identifier of the message sender used by the current user to add the reaction; may be null if unknown or the reaction isn't chosen. - */ - @Nullable public MessageSender usedSenderId; - /** - * Identifiers of at most 3 recent message senders, added the reaction; available in private, basic group and supergroup chats. - */ - public MessageSender[] recentSenderIds; - - /** - * Contains information about a reaction to a message. - */ - public MessageReaction() { - } - - /** - * Contains information about a reaction to a message. - * - * @param type Type of the reaction. - * @param totalCount Number of times the reaction was added. - * @param isChosen True, if the reaction is chosen by the current user. - * @param usedSenderId Identifier of the message sender used by the current user to add the reaction; may be null if unknown or the reaction isn't chosen. - * @param recentSenderIds Identifiers of at most 3 recent message senders, added the reaction; available in private, basic group and supergroup chats. - */ - public MessageReaction(ReactionType type, int totalCount, boolean isChosen, MessageSender usedSenderId, MessageSender[] recentSenderIds) { - this.type = type; - this.totalCount = totalCount; - this.isChosen = isChosen; - this.usedSenderId = usedSenderId; - this.recentSenderIds = recentSenderIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1093994369; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of reactions added to a message. - */ - public static class MessageReactions extends Object { - /** - * List of added reactions. - */ - public MessageReaction[] reactions; - /** - * True, if the reactions are tags and Telegram Premium users can filter messages by them. - */ - public boolean areTags; - /** - * Information about top users that added the paid reaction. - */ - public PaidReactor[] paidReactors; - /** - * True, if the list of added reactions is available using getMessageAddedReactions. - */ - public boolean canGetAddedReactions; - - /** - * Contains a list of reactions added to a message. - */ - public MessageReactions() { - } - - /** - * Contains a list of reactions added to a message. - * - * @param reactions List of added reactions. - * @param areTags True, if the reactions are tags and Telegram Premium users can filter messages by them. - * @param paidReactors Information about top users that added the paid reaction. - * @param canGetAddedReactions True, if the list of added reactions is available using getMessageAddedReactions. - */ - public MessageReactions(MessageReaction[] reactions, boolean areTags, PaidReactor[] paidReactors, boolean canGetAddedReactions) { - this.reactions = reactions; - this.areTags = areTags; - this.paidReactors = paidReactors; - this.canGetAddedReactions = canGetAddedReactions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1475966817; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes read date of a recent outgoing message in a private chat. - */ - public abstract static class MessageReadDate extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - MessageReadDateRead.CONSTRUCTOR, - MessageReadDateUnread.CONSTRUCTOR, - MessageReadDateTooOld.CONSTRUCTOR, - MessageReadDateUserPrivacyRestricted.CONSTRUCTOR, - MessageReadDateMyPrivacyRestricted.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public MessageReadDate() { - } - } - - /** - * Contains read date of the message. - */ - public static class MessageReadDateRead extends MessageReadDate { - /** - * Point in time (Unix timestamp) when the message was read by the other user. - */ - public int readDate; - - /** - * Contains read date of the message. - */ - public MessageReadDateRead() { - } - - /** - * Contains read date of the message. - * - * @param readDate Point in time (Unix timestamp) when the message was read by the other user. - */ - public MessageReadDateRead(int readDate) { - this.readDate = readDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1972186672; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message is unread yet. - */ - public static class MessageReadDateUnread extends MessageReadDate { - - /** - * The message is unread yet. - */ - public MessageReadDateUnread() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 397549868; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message is too old to get read date. - */ - public static class MessageReadDateTooOld extends MessageReadDate { - - /** - * The message is too old to get read date. - */ - public MessageReadDateTooOld() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1233773024; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The read date is unknown due to privacy settings of the other user. - */ - public static class MessageReadDateUserPrivacyRestricted extends MessageReadDate { - - /** - * The read date is unknown due to privacy settings of the other user. - */ - public MessageReadDateUserPrivacyRestricted() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1282567130; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The read date is unknown due to privacy settings of the current user, but will be known if the user subscribes to Telegram Premium. - */ - public static class MessageReadDateMyPrivacyRestricted extends MessageReadDate { - - /** - * The read date is unknown due to privacy settings of the current user, but will be known if the user subscribes to Telegram Premium. - */ - public MessageReadDateMyPrivacyRestricted() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -693971852; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about replies to a message. - */ - public static class MessageReplyInfo extends Object { - /** - * Number of times the message was directly or indirectly replied. - */ - public int replyCount; - /** - * Identifiers of at most 3 recent repliers to the message; available in channels with a discussion supergroup. The users and chats are expected to be inaccessible: only their photo and name will be available. - */ - public MessageSender[] recentReplierIds; - /** - * Identifier of the last read incoming reply to the message. - */ - public long lastReadInboxMessageId; - /** - * Identifier of the last read outgoing reply to the message. - */ - public long lastReadOutboxMessageId; - /** - * Identifier of the last reply to the message. - */ - public long lastMessageId; - - /** - * Contains information about replies to a message. - */ - public MessageReplyInfo() { - } - - /** - * Contains information about replies to a message. - * - * @param replyCount Number of times the message was directly or indirectly replied. - * @param recentReplierIds Identifiers of at most 3 recent repliers to the message; available in channels with a discussion supergroup. The users and chats are expected to be inaccessible: only their photo and name will be available. - * @param lastReadInboxMessageId Identifier of the last read incoming reply to the message. - * @param lastReadOutboxMessageId Identifier of the last read outgoing reply to the message. - * @param lastMessageId Identifier of the last reply to the message. - */ - public MessageReplyInfo(int replyCount, MessageSender[] recentReplierIds, long lastReadInboxMessageId, long lastReadOutboxMessageId, long lastMessageId) { - this.replyCount = replyCount; - this.recentReplierIds = recentReplierIds; - this.lastReadInboxMessageId = lastReadInboxMessageId; - this.lastReadOutboxMessageId = lastReadOutboxMessageId; - this.lastMessageId = lastMessageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2093702263; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains information about the message or the story a message is replying to. - */ - public abstract static class MessageReplyTo extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - MessageReplyToMessage.CONSTRUCTOR, - MessageReplyToStory.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public MessageReplyTo() { - } - } - - /** - * Describes a message replied by a given message. - */ - public static class MessageReplyToMessage extends MessageReplyTo { - /** - * The identifier of the chat to which the message belongs; may be 0 if the replied message is in unknown chat. - */ - public long chatId; - /** - * The identifier of the message; may be 0 if the replied message is in unknown chat. - */ - public long messageId; - /** - * Chosen quote from the replied message; may be null if none. - */ - @Nullable public TextQuote quote; - /** - * Identifier of the checklist task in the original message that was replied; 0 if none. - */ - public int checklistTaskId; - /** - * Information about origin of the message if the message was from another chat or topic; may be null for messages from the same chat. - */ - @Nullable public MessageOrigin origin; - /** - * Point in time (Unix timestamp) when the message was sent if the message was from another chat or topic; 0 for messages from the same chat. - */ - public int originSendDate; - /** - * Media content of the message if the message was from another chat or topic; may be null for messages from the same chat and messages without media. Can be only one of the following types: messageAnimation, messageAudio, messageChecklist, messageContact, messageDice, messageDocument, messageGame, messageGiveaway, messageGiveawayWinners, messageInvoice, messageLocation, messagePaidMedia, messagePhoto, messagePoll, messageStakeDice, messageSticker, messageStory, messageText (for link preview), messageVenue, messageVideo, messageVideoNote, or messageVoiceNote. - */ - @Nullable public MessageContent content; - - /** - * Describes a message replied by a given message. - */ - public MessageReplyToMessage() { - } - - /** - * Describes a message replied by a given message. - * - * @param chatId The identifier of the chat to which the message belongs; may be 0 if the replied message is in unknown chat. - * @param messageId The identifier of the message; may be 0 if the replied message is in unknown chat. - * @param quote Chosen quote from the replied message; may be null if none. - * @param checklistTaskId Identifier of the checklist task in the original message that was replied; 0 if none. - * @param origin Information about origin of the message if the message was from another chat or topic; may be null for messages from the same chat. - * @param originSendDate Point in time (Unix timestamp) when the message was sent if the message was from another chat or topic; 0 for messages from the same chat. - * @param content Media content of the message if the message was from another chat or topic; may be null for messages from the same chat and messages without media. Can be only one of the following types: messageAnimation, messageAudio, messageChecklist, messageContact, messageDice, messageDocument, messageGame, messageGiveaway, messageGiveawayWinners, messageInvoice, messageLocation, messagePaidMedia, messagePhoto, messagePoll, messageStakeDice, messageSticker, messageStory, messageText (for link preview), messageVenue, messageVideo, messageVideoNote, or messageVoiceNote. - */ - public MessageReplyToMessage(long chatId, long messageId, TextQuote quote, int checklistTaskId, MessageOrigin origin, int originSendDate, MessageContent content) { - this.chatId = chatId; - this.messageId = messageId; - this.quote = quote; - this.checklistTaskId = checklistTaskId; - this.origin = origin; - this.originSendDate = originSendDate; - this.content = content; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2078029945; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a story replied by a given message. - */ - public static class MessageReplyToStory extends MessageReplyTo { - /** - * The identifier of the poster of the story. - */ - public long storyPosterChatId; - /** - * The identifier of the story. - */ - public int storyId; - - /** - * Describes a story replied by a given message. - */ - public MessageReplyToStory() { - } - - /** - * Describes a story replied by a given message. - * - * @param storyPosterChatId The identifier of the poster of the story. - * @param storyId The identifier of the story. - */ - public MessageReplyToStory(long storyPosterChatId, int storyId) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -674492596; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains information about the time when a scheduled message will be sent. - */ - public abstract static class MessageSchedulingState extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - MessageSchedulingStateSendAtDate.CONSTRUCTOR, - MessageSchedulingStateSendWhenOnline.CONSTRUCTOR, - MessageSchedulingStateSendWhenVideoProcessed.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public MessageSchedulingState() { - } - } - - /** - * The message will be sent at the specified date. - */ - public static class MessageSchedulingStateSendAtDate extends MessageSchedulingState { - /** - * Point in time (Unix timestamp) when the message will be sent. The date must be within 367 days in the future. - */ - public int sendDate; - /** - * Period after which the message will be sent again; in seconds; 0 if never; for Telegram Premium users only; may be non-zero only in sendMessage and forwardMessages with one message requests; must be one of 0, 86400, 7 * 86400, 14 * 86400, 30 * 86400, 91 * 86400, 182 * 86400, 365 * 86400, or additionally 60, or 300 in the Test DC. - */ - public int repeatPeriod; - - /** - * The message will be sent at the specified date. - */ - public MessageSchedulingStateSendAtDate() { - } - - /** - * The message will be sent at the specified date. - * - * @param sendDate Point in time (Unix timestamp) when the message will be sent. The date must be within 367 days in the future. - * @param repeatPeriod Period after which the message will be sent again; in seconds; 0 if never; for Telegram Premium users only; may be non-zero only in sendMessage and forwardMessages with one message requests; must be one of 0, 86400, 7 * 86400, 14 * 86400, 30 * 86400, 91 * 86400, 182 * 86400, 365 * 86400, or additionally 60, or 300 in the Test DC. - */ - public MessageSchedulingStateSendAtDate(int sendDate, int repeatPeriod) { - this.sendDate = sendDate; - this.repeatPeriod = repeatPeriod; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1505903015; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message will be sent when the other user is online. Applicable to private chats only and when the exact online status of the other user is known. - */ - public static class MessageSchedulingStateSendWhenOnline extends MessageSchedulingState { - - /** - * The message will be sent when the other user is online. Applicable to private chats only and when the exact online status of the other user is known. - */ - public MessageSchedulingStateSendWhenOnline() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2092947464; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message will be sent when the video in the message is converted and optimized; can be used only by the server. - */ - public static class MessageSchedulingStateSendWhenVideoProcessed extends MessageSchedulingState { - /** - * Approximate point in time (Unix timestamp) when the message is expected to be sent. - */ - public int sendDate; - - /** - * The message will be sent when the video in the message is converted and optimized; can be used only by the server. - */ - public MessageSchedulingStateSendWhenVideoProcessed() { - } - - /** - * The message will be sent when the video in the message is converted and optimized; can be used only by the server. - * - * @param sendDate Approximate point in time (Unix timestamp) when the message is expected to be sent. - */ - public MessageSchedulingStateSendWhenVideoProcessed(int sendDate) { - this.sendDate = sendDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2101578734; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes when a message will be self-destructed. - */ - public abstract static class MessageSelfDestructType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - MessageSelfDestructTypeTimer.CONSTRUCTOR, - MessageSelfDestructTypeImmediately.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public MessageSelfDestructType() { - } - } - - /** - * The message will be self-destructed in the specified time after its content was opened. - */ - public static class MessageSelfDestructTypeTimer extends MessageSelfDestructType { - /** - * The message's self-destruct time, in seconds; must be between 0 and 60 in private chats. - */ - public int selfDestructTime; - - /** - * The message will be self-destructed in the specified time after its content was opened. - */ - public MessageSelfDestructTypeTimer() { - } - - /** - * The message will be self-destructed in the specified time after its content was opened. - * - * @param selfDestructTime The message's self-destruct time, in seconds; must be between 0 and 60 in private chats. - */ - public MessageSelfDestructTypeTimer(int selfDestructTime) { - this.selfDestructTime = selfDestructTime; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1351440333; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message can be opened only once and will be self-destructed once closed. - */ - public static class MessageSelfDestructTypeImmediately extends MessageSelfDestructType { - - /** - * The message can be opened only once and will be self-destructed once closed. - */ - public MessageSelfDestructTypeImmediately() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1036218363; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Options to be used when a message is sent. - */ - public static class MessageSendOptions extends Object { - /** - * Information about the suggested post; pass null if none. For messages to channel direct messages chat only. Applicable only to sendMessage and addOffer. - */ - public InputSuggestedPostInfo suggestedPostInfo; - /** - * Pass true to disable notification for the message. - */ - public boolean disableNotification; - /** - * Pass true if the message is sent from the background. - */ - public boolean fromBackground; - /** - * Pass true if the content of the message must be protected from forwarding and saving; for bots only. - */ - public boolean protectContent; - /** - * Pass true to allow the message to ignore regular broadcast limits for a small fee; for bots only. - */ - public boolean allowPaidBroadcast; - /** - * The number of Telegram Stars the user agreed to pay to send the messages. - */ - public long paidMessageStarCount; - /** - * Pass true if the user explicitly chosen a sticker or a custom emoji from an installed sticker set; applicable only to sendMessage and sendMessageAlbum. - */ - public boolean updateOrderOfInstalledStickerSets; - /** - * Message scheduling state; pass null to send message immediately. Messages sent to a secret chat, to a chat with paid messages, to a channel direct messages chat, live location messages and self-destructing messages can't be scheduled. - */ - public MessageSchedulingState schedulingState; - /** - * Identifier of the effect to apply to the message; pass 0 if none; applicable only to sendMessage, sendMessageAlbum in private chats and forwardMessages with one message to private chats. - */ - public long effectId; - /** - * Non-persistent identifier, which will be returned back in messageSendingStatePending object and can be used to match sent messages and corresponding updateNewMessage updates. - */ - public int sendingId; - /** - * Pass true to get a fake message instead of actually sending them. - */ - public boolean onlyPreview; - - /** - * Options to be used when a message is sent. - */ - public MessageSendOptions() { - } - - /** - * Options to be used when a message is sent. - * - * @param suggestedPostInfo Information about the suggested post; pass null if none. For messages to channel direct messages chat only. Applicable only to sendMessage and addOffer. - * @param disableNotification Pass true to disable notification for the message. - * @param fromBackground Pass true if the message is sent from the background. - * @param protectContent Pass true if the content of the message must be protected from forwarding and saving; for bots only. - * @param allowPaidBroadcast Pass true to allow the message to ignore regular broadcast limits for a small fee; for bots only. - * @param paidMessageStarCount The number of Telegram Stars the user agreed to pay to send the messages. - * @param updateOrderOfInstalledStickerSets Pass true if the user explicitly chosen a sticker or a custom emoji from an installed sticker set; applicable only to sendMessage and sendMessageAlbum. - * @param schedulingState Message scheduling state; pass null to send message immediately. Messages sent to a secret chat, to a chat with paid messages, to a channel direct messages chat, live location messages and self-destructing messages can't be scheduled. - * @param effectId Identifier of the effect to apply to the message; pass 0 if none; applicable only to sendMessage, sendMessageAlbum in private chats and forwardMessages with one message to private chats. - * @param sendingId Non-persistent identifier, which will be returned back in messageSendingStatePending object and can be used to match sent messages and corresponding updateNewMessage updates. - * @param onlyPreview Pass true to get a fake message instead of actually sending them. - */ - public MessageSendOptions(InputSuggestedPostInfo suggestedPostInfo, boolean disableNotification, boolean fromBackground, boolean protectContent, boolean allowPaidBroadcast, long paidMessageStarCount, boolean updateOrderOfInstalledStickerSets, MessageSchedulingState schedulingState, long effectId, int sendingId, boolean onlyPreview) { - this.suggestedPostInfo = suggestedPostInfo; - this.disableNotification = disableNotification; - this.fromBackground = fromBackground; - this.protectContent = protectContent; - this.allowPaidBroadcast = allowPaidBroadcast; - this.paidMessageStarCount = paidMessageStarCount; - this.updateOrderOfInstalledStickerSets = updateOrderOfInstalledStickerSets; - this.schedulingState = schedulingState; - this.effectId = effectId; - this.sendingId = sendingId; - this.onlyPreview = onlyPreview; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1725581906; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains information about the sender of a message. - */ - public abstract static class MessageSender extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - MessageSenderUser.CONSTRUCTOR, - MessageSenderChat.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public MessageSender() { - } - } - - /** - * The message was sent by a known user. - */ - public static class MessageSenderUser extends MessageSender { - /** - * Identifier of the user who sent the message. - */ - public long userId; - - /** - * The message was sent by a known user. - */ - public MessageSenderUser() { - } - - /** - * The message was sent by a known user. - * - * @param userId Identifier of the user who sent the message. - */ - public MessageSenderUser(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -336109341; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message was sent on behalf of a chat. - */ - public static class MessageSenderChat extends MessageSender { - /** - * Identifier of the chat that sent the message. - */ - public long chatId; - - /** - * The message was sent on behalf of a chat. - */ - public MessageSenderChat() { - } - - /** - * The message was sent on behalf of a chat. - * - * @param chatId Identifier of the chat that sent the message. - */ - public MessageSenderChat(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -239660751; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of message senders. - */ - public static class MessageSenders extends Object { - /** - * Approximate total number of message senders found. - */ - public int totalCount; - /** - * List of message senders. - */ - public MessageSender[] senders; - - /** - * Represents a list of message senders. - */ - public MessageSenders() { - } - - /** - * Represents a list of message senders. - * - * @param totalCount Approximate total number of message senders found. - * @param senders List of message senders. - */ - public MessageSenders(int totalCount, MessageSender[] senders) { - this.totalCount = totalCount; - this.senders = senders; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -690158467; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains information about the sending state of the message. - */ - public abstract static class MessageSendingState extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - MessageSendingStatePending.CONSTRUCTOR, - MessageSendingStateFailed.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public MessageSendingState() { - } - } - - /** - * The message is being sent now, but has not yet been delivered to the server. - */ - public static class MessageSendingStatePending extends MessageSendingState { - /** - * Non-persistent message sending identifier, specified by the application. - */ - public int sendingId; - - /** - * The message is being sent now, but has not yet been delivered to the server. - */ - public MessageSendingStatePending() { - } - - /** - * The message is being sent now, but has not yet been delivered to the server. - * - * @param sendingId Non-persistent message sending identifier, specified by the application. - */ - public MessageSendingStatePending(int sendingId) { - this.sendingId = sendingId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -215260236; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message failed to be sent. - */ - public static class MessageSendingStateFailed extends MessageSendingState { - /** - * The cause of the message sending failure. - */ - public Error error; - /** - * True, if the message can be re-sent using resendMessages or readdQuickReplyShortcutMessages. - */ - public boolean canRetry; - /** - * True, if the message can be re-sent only on behalf of a different sender. - */ - public boolean needAnotherSender; - /** - * True, if the message can be re-sent only if another quote is chosen in the message that is replied by the given message. - */ - public boolean needAnotherReplyQuote; - /** - * True, if the message can be re-sent only if the message to be replied is removed. This will be done automatically by resendMessages. - */ - public boolean needDropReply; - /** - * The number of Telegram Stars that must be paid to send the message; 0 if the current amount is correct. - */ - public long requiredPaidMessageStarCount; - /** - * Time left before the message can be re-sent, in seconds. No update is sent when this field changes. - */ - public double retryAfter; - - /** - * The message failed to be sent. - */ - public MessageSendingStateFailed() { - } - - /** - * The message failed to be sent. - * - * @param error The cause of the message sending failure. - * @param canRetry True, if the message can be re-sent using resendMessages or readdQuickReplyShortcutMessages. - * @param needAnotherSender True, if the message can be re-sent only on behalf of a different sender. - * @param needAnotherReplyQuote True, if the message can be re-sent only if another quote is chosen in the message that is replied by the given message. - * @param needDropReply True, if the message can be re-sent only if the message to be replied is removed. This will be done automatically by resendMessages. - * @param requiredPaidMessageStarCount The number of Telegram Stars that must be paid to send the message; 0 if the current amount is correct. - * @param retryAfter Time left before the message can be re-sent, in seconds. No update is sent when this field changes. - */ - public MessageSendingStateFailed(Error error, boolean canRetry, boolean needAnotherSender, boolean needAnotherReplyQuote, boolean needDropReply, long requiredPaidMessageStarCount, double retryAfter) { - this.error = error; - this.canRetry = canRetry; - this.needAnotherSender = needAnotherSender; - this.needAnotherReplyQuote = needAnotherReplyQuote; - this.needDropReply = needDropReply; - this.requiredPaidMessageStarCount = requiredPaidMessageStarCount; - this.retryAfter = retryAfter; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -777630522; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes source of a message. - */ - public abstract static class MessageSource extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - MessageSourceChatHistory.CONSTRUCTOR, - MessageSourceMessageThreadHistory.CONSTRUCTOR, - MessageSourceForumTopicHistory.CONSTRUCTOR, - MessageSourceDirectMessagesChatTopicHistory.CONSTRUCTOR, - MessageSourceHistoryPreview.CONSTRUCTOR, - MessageSourceChatList.CONSTRUCTOR, - MessageSourceSearch.CONSTRUCTOR, - MessageSourceChatEventLog.CONSTRUCTOR, - MessageSourceNotification.CONSTRUCTOR, - MessageSourceScreenshot.CONSTRUCTOR, - MessageSourceOther.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public MessageSource() { - } - } - - /** - * The message is from a chat history. - */ - public static class MessageSourceChatHistory extends MessageSource { - - /** - * The message is from a chat history. - */ - public MessageSourceChatHistory() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1090386116; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message is from history of a message thread. - */ - public static class MessageSourceMessageThreadHistory extends MessageSource { - - /** - * The message is from history of a message thread. - */ - public MessageSourceMessageThreadHistory() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 290427142; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message is from history of a forum topic. - */ - public static class MessageSourceForumTopicHistory extends MessageSource { - - /** - * The message is from history of a forum topic. - */ - public MessageSourceForumTopicHistory() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1518064457; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message is from history of a topic in a channel direct messages chat administered by the current user. - */ - public static class MessageSourceDirectMessagesChatTopicHistory extends MessageSource { - - /** - * The message is from history of a topic in a channel direct messages chat administered by the current user. - */ - public MessageSourceDirectMessagesChatTopicHistory() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1869256503; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message is from chat, message thread or forum topic history preview. - */ - public static class MessageSourceHistoryPreview extends MessageSource { - - /** - * The message is from chat, message thread or forum topic history preview. - */ - public MessageSourceHistoryPreview() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1024254993; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message is from a chat list or a forum topic list. - */ - public static class MessageSourceChatList extends MessageSource { - - /** - * The message is from a chat list or a forum topic list. - */ - public MessageSourceChatList() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2047406102; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message is from search results, including file downloads, local file list, outgoing document messages, calendar. - */ - public static class MessageSourceSearch extends MessageSource { - - /** - * The message is from search results, including file downloads, local file list, outgoing document messages, calendar. - */ - public MessageSourceSearch() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1921333105; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message is from a chat event log. - */ - public static class MessageSourceChatEventLog extends MessageSource { - - /** - * The message is from a chat event log. - */ - public MessageSourceChatEventLog() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1028777540; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message is from a notification. - */ - public static class MessageSourceNotification extends MessageSource { - - /** - * The message is from a notification. - */ - public MessageSourceNotification() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1046406163; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message was screenshotted; the source must be used only if the message content was visible during the screenshot. - */ - public static class MessageSourceScreenshot extends MessageSource { - - /** - * The message was screenshotted; the source must be used only if the message content was visible during the screenshot. - */ - public MessageSourceScreenshot() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 469982474; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message is from some other source. - */ - public static class MessageSourceOther extends MessageSource { - - /** - * The message is from some other source. - */ - public MessageSourceOther() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 901818114; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A detailed statistics about a message. - */ - public static class MessageStatistics extends Object { - /** - * A graph containing number of message views and shares. - */ - public StatisticalGraph messageInteractionGraph; - /** - * A graph containing number of message reactions. - */ - public StatisticalGraph messageReactionGraph; - - /** - * A detailed statistics about a message. - */ - public MessageStatistics() { - } - - /** - * A detailed statistics about a message. - * - * @param messageInteractionGraph A graph containing number of message views and shares. - * @param messageReactionGraph A graph containing number of message reactions. - */ - public MessageStatistics(StatisticalGraph messageInteractionGraph, StatisticalGraph messageReactionGraph) { - this.messageInteractionGraph = messageInteractionGraph; - this.messageReactionGraph = messageReactionGraph; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1563537657; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a message thread. - */ - public static class MessageThreadInfo extends Object { - /** - * Identifier of the chat to which the message thread belongs. - */ - public long chatId; - /** - * Message thread identifier, unique within the chat. - */ - public long messageThreadId; - /** - * Information about the message thread; may be null for forum topic threads. - */ - @Nullable public MessageReplyInfo replyInfo; - /** - * Approximate number of unread messages in the message thread. - */ - public int unreadMessageCount; - /** - * The messages from which the thread starts. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). - */ - public Message[] messages; - /** - * A draft of a message in the message thread; may be null if none. - */ - @Nullable public DraftMessage draftMessage; - - /** - * Contains information about a message thread. - */ - public MessageThreadInfo() { - } - - /** - * Contains information about a message thread. - * - * @param chatId Identifier of the chat to which the message thread belongs. - * @param messageThreadId Message thread identifier, unique within the chat. - * @param replyInfo Information about the message thread; may be null for forum topic threads. - * @param unreadMessageCount Approximate number of unread messages in the message thread. - * @param messages The messages from which the thread starts. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). - * @param draftMessage A draft of a message in the message thread; may be null if none. - */ - public MessageThreadInfo(long chatId, long messageThreadId, MessageReplyInfo replyInfo, int unreadMessageCount, Message[] messages, DraftMessage draftMessage) { - this.chatId = chatId; - this.messageThreadId = messageThreadId; - this.replyInfo = replyInfo; - this.unreadMessageCount = unreadMessageCount; - this.messages = messages; - this.draftMessage = draftMessage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -248536056; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a topic of messages in a chat. - */ - public abstract static class MessageTopic extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - MessageTopicThread.CONSTRUCTOR, - MessageTopicForum.CONSTRUCTOR, - MessageTopicDirectMessages.CONSTRUCTOR, - MessageTopicSavedMessages.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public MessageTopic() { - } - } - - /** - * A topic in a non-forum supergroup chat. - */ - public static class MessageTopicThread extends MessageTopic { - /** - * Unique identifier of the message thread. - */ - public long messageThreadId; - - /** - * A topic in a non-forum supergroup chat. - */ - public MessageTopicThread() { - } - - /** - * A topic in a non-forum supergroup chat. - * - * @param messageThreadId Unique identifier of the message thread. - */ - public MessageTopicThread(long messageThreadId) { - this.messageThreadId = messageThreadId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1360920071; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A topic in a forum supergroup chat or a chat with a bot. - */ - public static class MessageTopicForum extends MessageTopic { - /** - * Unique identifier of the forum topic. - */ - public int forumTopicId; - - /** - * A topic in a forum supergroup chat or a chat with a bot. - */ - public MessageTopicForum() { - } - - /** - * A topic in a forum supergroup chat or a chat with a bot. - * - * @param forumTopicId Unique identifier of the forum topic. - */ - public MessageTopicForum(int forumTopicId) { - this.forumTopicId = forumTopicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2119440112; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A topic in a channel direct messages chat administered by the current user. - */ - public static class MessageTopicDirectMessages extends MessageTopic { - /** - * Unique identifier of the topic. - */ - public long directMessagesChatTopicId; - - /** - * A topic in a channel direct messages chat administered by the current user. - */ - public MessageTopicDirectMessages() { - } - - /** - * A topic in a channel direct messages chat administered by the current user. - * - * @param directMessagesChatTopicId Unique identifier of the topic. - */ - public MessageTopicDirectMessages(long directMessagesChatTopicId) { - this.directMessagesChatTopicId = directMessagesChatTopicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1285378599; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A topic in Saved Messages chat. - */ - public static class MessageTopicSavedMessages extends MessageTopic { - /** - * Unique identifier of the Saved Messages topic. - */ - public long savedMessagesTopicId; - - /** - * A topic in Saved Messages chat. - */ - public MessageTopicSavedMessages() { - } - - /** - * A topic in Saved Messages chat. - * - * @param savedMessagesTopicId Unique identifier of the Saved Messages topic. - */ - public MessageTopicSavedMessages(long savedMessagesTopicId) { - this.savedMessagesTopicId = savedMessagesTopicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 588026991; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a viewer of a message. - */ - public static class MessageViewer extends Object { - /** - * User identifier of the viewer. - */ - public long userId; - /** - * Approximate point in time (Unix timestamp) when the message was viewed. - */ - public int viewDate; - - /** - * Represents a viewer of a message. - */ - public MessageViewer() { - } - - /** - * Represents a viewer of a message. - * - * @param userId User identifier of the viewer. - * @param viewDate Approximate point in time (Unix timestamp) when the message was viewed. - */ - public MessageViewer(long userId, int viewDate) { - this.userId = userId; - this.viewDate = viewDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1458639309; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of message viewers. - */ - public static class MessageViewers extends Object { - /** - * List of message viewers. - */ - public MessageViewer[] viewers; - - /** - * Represents a list of message viewers. - */ - public MessageViewers() { - } - - /** - * Represents a list of message viewers. - * - * @param viewers List of message viewers. - */ - public MessageViewers(MessageViewer[] viewers) { - this.viewers = viewers; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2116480287; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of messages. - */ - public static class Messages extends Object { - /** - * Approximate total number of messages found. - */ - public int totalCount; - /** - * List of messages; messages may be null. - */ - public Message[] messages; - - /** - * Contains a list of messages. - */ - public Messages() { - } - - /** - * Contains a list of messages. - * - * @param totalCount Approximate total number of messages found. - * @param messages List of messages; messages may be null. - */ - public Messages(int totalCount, Message[] messages) { - this.totalCount = totalCount; - this.messages = messages; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -16498159; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Thumbnail image of a very poor quality and low resolution. - */ - public static class Minithumbnail extends Object { - /** - * Thumbnail width, usually doesn't exceed 40. - */ - public int width; - /** - * Thumbnail height, usually doesn't exceed 40. - */ - public int height; - /** - * The thumbnail in JPEG format. - */ - public byte[] data; - - /** - * Thumbnail image of a very poor quality and low resolution. - */ - public Minithumbnail() { - } - - /** - * Thumbnail image of a very poor quality and low resolution. - * - * @param width Thumbnail width, usually doesn't exceed 40. - * @param height Thumbnail height, usually doesn't exceed 40. - * @param data The thumbnail in JPEG format. - */ - public Minithumbnail(int width, int height, byte[] data) { - this.width = width; - this.height = height; - this.data = data; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -328540758; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A full list of available network statistic entries. - */ - public static class NetworkStatistics extends Object { - /** - * Point in time (Unix timestamp) from which the statistics are collected. - */ - public int sinceDate; - /** - * Network statistics entries. - */ - public NetworkStatisticsEntry[] entries; - - /** - * A full list of available network statistic entries. - */ - public NetworkStatistics() { - } - - /** - * A full list of available network statistic entries. - * - * @param sinceDate Point in time (Unix timestamp) from which the statistics are collected. - * @param entries Network statistics entries. - */ - public NetworkStatistics(int sinceDate, NetworkStatisticsEntry[] entries) { - this.sinceDate = sinceDate; - this.entries = entries; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1615554212; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains statistics about network usage. - */ - public abstract static class NetworkStatisticsEntry extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - NetworkStatisticsEntryFile.CONSTRUCTOR, - NetworkStatisticsEntryCall.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public NetworkStatisticsEntry() { - } - } - - /** - * Contains information about the total amount of data that was used to send and receive files. - */ - public static class NetworkStatisticsEntryFile extends NetworkStatisticsEntry { - /** - * Type of the file the data is part of; pass null if the data isn't related to files. - */ - public FileType fileType; - /** - * Type of the network the data was sent through. Call setNetworkType to maintain the actual network type. - */ - public NetworkType networkType; - /** - * Total number of bytes sent. - */ - public long sentBytes; - /** - * Total number of bytes received. - */ - public long receivedBytes; - - /** - * Contains information about the total amount of data that was used to send and receive files. - */ - public NetworkStatisticsEntryFile() { - } - - /** - * Contains information about the total amount of data that was used to send and receive files. - * - * @param fileType Type of the file the data is part of; pass null if the data isn't related to files. - * @param networkType Type of the network the data was sent through. Call setNetworkType to maintain the actual network type. - * @param sentBytes Total number of bytes sent. - * @param receivedBytes Total number of bytes received. - */ - public NetworkStatisticsEntryFile(FileType fileType, NetworkType networkType, long sentBytes, long receivedBytes) { - this.fileType = fileType; - this.networkType = networkType; - this.sentBytes = sentBytes; - this.receivedBytes = receivedBytes; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 188452706; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about the total amount of data that was used for calls. - */ - public static class NetworkStatisticsEntryCall extends NetworkStatisticsEntry { - /** - * Type of the network the data was sent through. Call setNetworkType to maintain the actual network type. - */ - public NetworkType networkType; - /** - * Total number of bytes sent. - */ - public long sentBytes; - /** - * Total number of bytes received. - */ - public long receivedBytes; - /** - * Total call duration, in seconds. - */ - public double duration; - - /** - * Contains information about the total amount of data that was used for calls. - */ - public NetworkStatisticsEntryCall() { - } - - /** - * Contains information about the total amount of data that was used for calls. - * - * @param networkType Type of the network the data was sent through. Call setNetworkType to maintain the actual network type. - * @param sentBytes Total number of bytes sent. - * @param receivedBytes Total number of bytes received. - * @param duration Total call duration, in seconds. - */ - public NetworkStatisticsEntryCall(NetworkType networkType, long sentBytes, long receivedBytes, double duration) { - this.networkType = networkType; - this.sentBytes = sentBytes; - this.receivedBytes = receivedBytes; - this.duration = duration; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 737000365; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents the type of network. - */ - public abstract static class NetworkType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - NetworkTypeNone.CONSTRUCTOR, - NetworkTypeMobile.CONSTRUCTOR, - NetworkTypeMobileRoaming.CONSTRUCTOR, - NetworkTypeWiFi.CONSTRUCTOR, - NetworkTypeOther.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public NetworkType() { - } - } - - /** - * The network is not available. - */ - public static class NetworkTypeNone extends NetworkType { - - /** - * The network is not available. - */ - public NetworkTypeNone() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1971691759; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A mobile network. - */ - public static class NetworkTypeMobile extends NetworkType { - - /** - * A mobile network. - */ - public NetworkTypeMobile() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 819228239; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A mobile roaming network. - */ - public static class NetworkTypeMobileRoaming extends NetworkType { - - /** - * A mobile roaming network. - */ - public NetworkTypeMobileRoaming() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1435199760; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Wi-Fi network. - */ - public static class NetworkTypeWiFi extends NetworkType { - - /** - * A Wi-Fi network. - */ - public NetworkTypeWiFi() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -633872070; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A different network type (e.g., Ethernet network). - */ - public static class NetworkTypeOther extends NetworkType { - - /** - * A different network type (e.g., Ethernet network). - */ - public NetworkTypeOther() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1942128539; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains privacy settings for chats with non-contacts. - */ - public static class NewChatPrivacySettings extends Object { - /** - * True, if non-contacts users are able to write first to the current user. Telegram Premium subscribers are able to write first regardless of this setting. - */ - public boolean allowNewChatsFromUnknownUsers; - /** - * Number of Telegram Stars that must be paid for every incoming private message by non-contacts; 0-getOption("paid_message_star_count_max"). If positive, then allowNewChatsFromUnknownUsers must be true. The current user will receive getOption("paid_message_earnings_per_mille") Telegram Stars for each 1000 Telegram Stars paid for message sending. Can be positive, only if getOption("can_enable_paid_messages") is true. - */ - public long incomingPaidMessageStarCount; - - /** - * Contains privacy settings for chats with non-contacts. - */ - public NewChatPrivacySettings() { - } - - /** - * Contains privacy settings for chats with non-contacts. - * - * @param allowNewChatsFromUnknownUsers True, if non-contacts users are able to write first to the current user. Telegram Premium subscribers are able to write first regardless of this setting. - * @param incomingPaidMessageStarCount Number of Telegram Stars that must be paid for every incoming private message by non-contacts; 0-getOption("paid_message_star_count_max"). If positive, then allowNewChatsFromUnknownUsers must be true. The current user will receive getOption("paid_message_earnings_per_mille") Telegram Stars for each 1000 Telegram Stars paid for message sending. Can be positive, only if getOption("can_enable_paid_messages") is true. - */ - public NewChatPrivacySettings(boolean allowNewChatsFromUnknownUsers, long incomingPaidMessageStarCount) { - this.allowNewChatsFromUnknownUsers = allowNewChatsFromUnknownUsers; - this.incomingPaidMessageStarCount = incomingPaidMessageStarCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 123716192; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a notification. - */ - public static class Notification extends Object { - /** - * Unique persistent identifier of this notification. - */ - public int id; - /** - * Notification date. - */ - public int date; - /** - * True, if the notification was explicitly sent without sound. - */ - public boolean isSilent; - /** - * Notification type. - */ - public NotificationType type; - - /** - * Contains information about a notification. - */ - public Notification() { - } - - /** - * Contains information about a notification. - * - * @param id Unique persistent identifier of this notification. - * @param date Notification date. - * @param isSilent True, if the notification was explicitly sent without sound. - * @param type Notification type. - */ - public Notification(int id, int date, boolean isSilent, NotificationType type) { - this.id = id; - this.date = date; - this.isSilent = isSilent; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 788743120; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a group of notifications. - */ - public static class NotificationGroup extends Object { - /** - * Unique persistent auto-incremented from 1 identifier of the notification group. - */ - public int id; - /** - * Type of the group. - */ - public NotificationGroupType type; - /** - * Identifier of a chat to which all notifications in the group belong. - */ - public long chatId; - /** - * Total number of active notifications in the group. - */ - public int totalCount; - /** - * The list of active notifications. - */ - public Notification[] notifications; - - /** - * Describes a group of notifications. - */ - public NotificationGroup() { - } - - /** - * Describes a group of notifications. - * - * @param id Unique persistent auto-incremented from 1 identifier of the notification group. - * @param type Type of the group. - * @param chatId Identifier of a chat to which all notifications in the group belong. - * @param totalCount Total number of active notifications in the group. - * @param notifications The list of active notifications. - */ - public NotificationGroup(int id, NotificationGroupType type, long chatId, int totalCount, Notification[] notifications) { - this.id = id; - this.type = type; - this.chatId = chatId; - this.totalCount = totalCount; - this.notifications = notifications; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 780691541; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the type of notifications in a notification group. - */ - public abstract static class NotificationGroupType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - NotificationGroupTypeMessages.CONSTRUCTOR, - NotificationGroupTypeMentions.CONSTRUCTOR, - NotificationGroupTypeSecretChat.CONSTRUCTOR, - NotificationGroupTypeCalls.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public NotificationGroupType() { - } - } - - /** - * A group containing notifications of type notificationTypeNewMessage and notificationTypeNewPushMessage with ordinary unread messages. - */ - public static class NotificationGroupTypeMessages extends NotificationGroupType { - - /** - * A group containing notifications of type notificationTypeNewMessage and notificationTypeNewPushMessage with ordinary unread messages. - */ - public NotificationGroupTypeMessages() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1702481123; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A group containing notifications of type notificationTypeNewMessage and notificationTypeNewPushMessage with unread mentions of the current user, replies to their messages, or a pinned message. - */ - public static class NotificationGroupTypeMentions extends NotificationGroupType { - - /** - * A group containing notifications of type notificationTypeNewMessage and notificationTypeNewPushMessage with unread mentions of the current user, replies to their messages, or a pinned message. - */ - public NotificationGroupTypeMentions() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2050324051; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A group containing a notification of type notificationTypeNewSecretChat. - */ - public static class NotificationGroupTypeSecretChat extends NotificationGroupType { - - /** - * A group containing a notification of type notificationTypeNewSecretChat. - */ - public NotificationGroupTypeSecretChat() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1390759476; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A group containing notifications of type notificationTypeNewCall. - */ - public static class NotificationGroupTypeCalls extends NotificationGroupType { - - /** - * A group containing notifications of type notificationTypeNewCall. - */ - public NotificationGroupTypeCalls() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1379123538; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the types of chats to which notification settings are relevant. - */ - public abstract static class NotificationSettingsScope extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - NotificationSettingsScopePrivateChats.CONSTRUCTOR, - NotificationSettingsScopeGroupChats.CONSTRUCTOR, - NotificationSettingsScopeChannelChats.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public NotificationSettingsScope() { - } - } - - /** - * Notification settings applied to all private and secret chats when the corresponding chat setting has a default value. - */ - public static class NotificationSettingsScopePrivateChats extends NotificationSettingsScope { - - /** - * Notification settings applied to all private and secret chats when the corresponding chat setting has a default value. - */ - public NotificationSettingsScopePrivateChats() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 937446759; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Notification settings applied to all basic group and supergroup chats when the corresponding chat setting has a default value. - */ - public static class NotificationSettingsScopeGroupChats extends NotificationSettingsScope { - - /** - * Notification settings applied to all basic group and supergroup chats when the corresponding chat setting has a default value. - */ - public NotificationSettingsScopeGroupChats() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1212142067; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Notification settings applied to all channel chats when the corresponding chat setting has a default value. - */ - public static class NotificationSettingsScopeChannelChats extends NotificationSettingsScope { - - /** - * Notification settings applied to all channel chats when the corresponding chat setting has a default value. - */ - public NotificationSettingsScopeChannelChats() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 548013448; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a notification sound in MP3 format. - */ - public static class NotificationSound extends Object { - /** - * Unique identifier of the notification sound. - */ - public long id; - /** - * Duration of the sound, in seconds. - */ - public int duration; - /** - * Point in time (Unix timestamp) when the sound was created. - */ - public int date; - /** - * Title of the notification sound. - */ - public String title; - /** - * Arbitrary data, defined while the sound was uploaded. - */ - public String data; - /** - * File containing the sound. - */ - public File sound; - - /** - * Describes a notification sound in MP3 format. - */ - public NotificationSound() { - } - - /** - * Describes a notification sound in MP3 format. - * - * @param id Unique identifier of the notification sound. - * @param duration Duration of the sound, in seconds. - * @param date Point in time (Unix timestamp) when the sound was created. - * @param title Title of the notification sound. - * @param data Arbitrary data, defined while the sound was uploaded. - * @param sound File containing the sound. - */ - public NotificationSound(long id, int duration, int date, String title, String data, File sound) { - this.id = id; - this.duration = duration; - this.date = date; - this.title = title; - this.data = data; - this.sound = sound; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -185638601; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of notification sounds. - */ - public static class NotificationSounds extends Object { - /** - * A list of notification sounds. - */ - public NotificationSound[] notificationSounds; - - /** - * Contains a list of notification sounds. - */ - public NotificationSounds() { - } - - /** - * Contains a list of notification sounds. - * - * @param notificationSounds A list of notification sounds. - */ - public NotificationSounds(NotificationSound[] notificationSounds) { - this.notificationSounds = notificationSounds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -630813169; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains detailed information about a notification. - */ - public abstract static class NotificationType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - NotificationTypeNewMessage.CONSTRUCTOR, - NotificationTypeNewSecretChat.CONSTRUCTOR, - NotificationTypeNewCall.CONSTRUCTOR, - NotificationTypeNewPushMessage.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public NotificationType() { - } - } - - /** - * New message was received. - */ - public static class NotificationTypeNewMessage extends NotificationType { - /** - * The message. - */ - public Message message; - /** - * True, if message content must be displayed in notifications. - */ - public boolean showPreview; - - /** - * New message was received. - */ - public NotificationTypeNewMessage() { - } - - /** - * New message was received. - * - * @param message The message. - * @param showPreview True, if message content must be displayed in notifications. - */ - public NotificationTypeNewMessage(Message message, boolean showPreview) { - this.message = message; - this.showPreview = showPreview; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -254745614; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * New secret chat was created. - */ - public static class NotificationTypeNewSecretChat extends NotificationType { - - /** - * New secret chat was created. - */ - public NotificationTypeNewSecretChat() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1198638768; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * New call was received. - */ - public static class NotificationTypeNewCall extends NotificationType { - /** - * Call identifier. - */ - public int callId; - - /** - * New call was received. - */ - public NotificationTypeNewCall() { - } - - /** - * New call was received. - * - * @param callId Call identifier. - */ - public NotificationTypeNewCall(int callId) { - this.callId = callId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1712734585; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * New message was received through a push notification. - */ - public static class NotificationTypeNewPushMessage extends NotificationType { - /** - * The message identifier. The message will not be available in the chat history, but the identifier can be used in viewMessages, or as a message to be replied in the same chat. - */ - public long messageId; - /** - * Identifier of the sender of the message. Corresponding user or chat may be inaccessible. - */ - public MessageSender senderId; - /** - * Name of the sender. - */ - public String senderName; - /** - * True, if the message is outgoing. - */ - public boolean isOutgoing; - /** - * Push message content. - */ - public PushMessageContent content; - - /** - * New message was received through a push notification. - */ - public NotificationTypeNewPushMessage() { - } - - /** - * New message was received through a push notification. - * - * @param messageId The message identifier. The message will not be available in the chat history, but the identifier can be used in viewMessages, or as a message to be replied in the same chat. - * @param senderId Identifier of the sender of the message. Corresponding user or chat may be inaccessible. - * @param senderName Name of the sender. - * @param isOutgoing True, if the message is outgoing. - * @param content Push message content. - */ - public NotificationTypeNewPushMessage(long messageId, MessageSender senderId, String senderName, boolean isOutgoing, PushMessageContent content) { - this.messageId = messageId; - this.senderId = senderId; - this.senderName = senderName; - this.isOutgoing = isOutgoing; - this.content = content; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -711680462; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Information about the OAuth authorization. - */ - public static class OauthLinkInfo extends Object { - /** - * Identifier of the user for which the link was generated; may be 0 if unknown. The corresponding user may be unknown. If the user is logged in the app, then they must be chosen for authorization by default. - */ - public long userId; - /** - * An HTTP URL where the user authorizes. - */ - public String url; - /** - * A domain of the URL. - */ - public String domain; - /** - * User identifier of a bot linked with the website. - */ - public long botUserId; - /** - * True, if the user must be asked for the permission to the bot to send them messages. - */ - public boolean requestWriteAccess; - /** - * True, if the user must be asked for the permission to share their phone number. - */ - public boolean requestPhoneNumberAccess; - /** - * The version of a browser used for the authorization. - */ - public String browser; - /** - * Operating system the browser is running on. - */ - public String platform; - /** - * IP address from which the authorization is performed, in human-readable format. - */ - public String ipAddress; - /** - * Human-readable description of a country and a region from which the authorization is performed, based on the IP address. - */ - public String location; - /** - * True, if code matching dialog must be shown first and checkOauthRequestMatchCode must be called before acceptOauthRequest. Otherwise, checkOauthRequestMatchCode must not be called. - */ - public boolean matchCodeFirst; - /** - * The list of codes to match; may be empty if irrelevant. - */ - public String[] matchCodes; - - /** - * Information about the OAuth authorization. - */ - public OauthLinkInfo() { - } - - /** - * Information about the OAuth authorization. - * - * @param userId Identifier of the user for which the link was generated; may be 0 if unknown. The corresponding user may be unknown. If the user is logged in the app, then they must be chosen for authorization by default. - * @param url An HTTP URL where the user authorizes. - * @param domain A domain of the URL. - * @param botUserId User identifier of a bot linked with the website. - * @param requestWriteAccess True, if the user must be asked for the permission to the bot to send them messages. - * @param requestPhoneNumberAccess True, if the user must be asked for the permission to share their phone number. - * @param browser The version of a browser used for the authorization. - * @param platform Operating system the browser is running on. - * @param ipAddress IP address from which the authorization is performed, in human-readable format. - * @param location Human-readable description of a country and a region from which the authorization is performed, based on the IP address. - * @param matchCodeFirst True, if code matching dialog must be shown first and checkOauthRequestMatchCode must be called before acceptOauthRequest. Otherwise, checkOauthRequestMatchCode must not be called. - * @param matchCodes The list of codes to match; may be empty if irrelevant. - */ - public OauthLinkInfo(long userId, String url, String domain, long botUserId, boolean requestWriteAccess, boolean requestPhoneNumberAccess, String browser, String platform, String ipAddress, String location, boolean matchCodeFirst, String[] matchCodes) { - this.userId = userId; - this.url = url; - this.domain = domain; - this.botUserId = botUserId; - this.requestWriteAccess = requestWriteAccess; - this.requestPhoneNumberAccess = requestPhoneNumberAccess; - this.browser = browser; - this.platform = platform; - this.ipAddress = ipAddress; - this.location = location; - this.matchCodeFirst = matchCodeFirst; - this.matchCodes = matchCodes; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1916199178; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An object of this type is returned on a successful function call for certain functions. - */ - public static class Ok extends Object { - - /** - * An object of this type is returned on a successful function call for certain functions. - */ - public Ok() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -722616727; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents the value of an option. - */ - public abstract static class OptionValue extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - OptionValueBoolean.CONSTRUCTOR, - OptionValueEmpty.CONSTRUCTOR, - OptionValueInteger.CONSTRUCTOR, - OptionValueString.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public OptionValue() { - } - } - - /** - * Represents a boolean option. - */ - public static class OptionValueBoolean extends OptionValue { - /** - * The value of the option. - */ - public boolean value; - - /** - * Represents a boolean option. - */ - public OptionValueBoolean() { - } - - /** - * Represents a boolean option. - * - * @param value The value of the option. - */ - public OptionValueBoolean(boolean value) { - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 63135518; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents an unknown option or an option which has a default value. - */ - public static class OptionValueEmpty extends OptionValue { - - /** - * Represents an unknown option or an option which has a default value. - */ - public OptionValueEmpty() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 918955155; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents an integer option. - */ - public static class OptionValueInteger extends OptionValue { - /** - * The value of the option. - */ - public long value; - - /** - * Represents an integer option. - */ - public OptionValueInteger() { - } - - /** - * Represents an integer option. - * - * @param value The value of the option. - */ - public OptionValueInteger(long value) { - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -186858780; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a string option. - */ - public static class OptionValueString extends OptionValue { - /** - * The value of the option. - */ - public String value; - - /** - * Represents a string option. - */ - public OptionValueString() { - } - - /** - * Represents a string option. - * - * @param value The value of the option. - */ - public OptionValueString(String value) { - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 756248212; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Order information. - */ - public static class OrderInfo extends Object { - /** - * Name of the user. - */ - public String name; - /** - * Phone number of the user. - */ - public String phoneNumber; - /** - * Email address of the user. - */ - public String emailAddress; - /** - * Shipping address for this order; may be null. - */ - @Nullable public Address shippingAddress; - - /** - * Order information. - */ - public OrderInfo() { - } - - /** - * Order information. - * - * @param name Name of the user. - * @param phoneNumber Phone number of the user. - * @param emailAddress Email address of the user. - * @param shippingAddress Shipping address for this order; may be null. - */ - public OrderInfo(String name, String phoneNumber, String emailAddress, Address shippingAddress) { - this.name = name; - this.phoneNumber = phoneNumber; - this.emailAddress = emailAddress; - this.shippingAddress = shippingAddress; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 783997294; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents outline of an image. - */ - public static class Outline extends Object { - /** - * The list of closed vector paths. - */ - public ClosedVectorPath[] paths; - - /** - * Represents outline of an image. - */ - public Outline() { - } - - /** - * Represents outline of an image. - * - * @param paths The list of closed vector paths. - */ - public Outline(ClosedVectorPath[] paths) { - this.paths = paths; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -161506702; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a block of an instant view for a web page. - */ - public abstract static class PageBlock extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PageBlockTitle.CONSTRUCTOR, - PageBlockSubtitle.CONSTRUCTOR, - PageBlockAuthorDate.CONSTRUCTOR, - PageBlockHeader.CONSTRUCTOR, - PageBlockSubheader.CONSTRUCTOR, - PageBlockKicker.CONSTRUCTOR, - PageBlockParagraph.CONSTRUCTOR, - PageBlockPreformatted.CONSTRUCTOR, - PageBlockFooter.CONSTRUCTOR, - PageBlockDivider.CONSTRUCTOR, - PageBlockAnchor.CONSTRUCTOR, - PageBlockList.CONSTRUCTOR, - PageBlockBlockQuote.CONSTRUCTOR, - PageBlockPullQuote.CONSTRUCTOR, - PageBlockAnimation.CONSTRUCTOR, - PageBlockAudio.CONSTRUCTOR, - PageBlockPhoto.CONSTRUCTOR, - PageBlockVideo.CONSTRUCTOR, - PageBlockVoiceNote.CONSTRUCTOR, - PageBlockCover.CONSTRUCTOR, - PageBlockEmbedded.CONSTRUCTOR, - PageBlockEmbeddedPost.CONSTRUCTOR, - PageBlockCollage.CONSTRUCTOR, - PageBlockSlideshow.CONSTRUCTOR, - PageBlockChatLink.CONSTRUCTOR, - PageBlockTable.CONSTRUCTOR, - PageBlockDetails.CONSTRUCTOR, - PageBlockRelatedArticles.CONSTRUCTOR, - PageBlockMap.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PageBlock() { - } - } - - /** - * The title of a page. - */ - public static class PageBlockTitle extends PageBlock { - /** - * Title. - */ - public RichText title; - - /** - * The title of a page. - */ - public PageBlockTitle() { - } - - /** - * The title of a page. - * - * @param title Title. - */ - public PageBlockTitle(RichText title) { - this.title = title; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1629664784; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The subtitle of a page. - */ - public static class PageBlockSubtitle extends PageBlock { - /** - * Subtitle. - */ - public RichText subtitle; - - /** - * The subtitle of a page. - */ - public PageBlockSubtitle() { - } - - /** - * The subtitle of a page. - * - * @param subtitle Subtitle. - */ - public PageBlockSubtitle(RichText subtitle) { - this.subtitle = subtitle; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 264524263; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The author and publishing date of a page. - */ - public static class PageBlockAuthorDate extends PageBlock { - /** - * Author. - */ - public RichText author; - /** - * Point in time (Unix timestamp) when the article was published; 0 if unknown. - */ - public int publishDate; - - /** - * The author and publishing date of a page. - */ - public PageBlockAuthorDate() { - } - - /** - * The author and publishing date of a page. - * - * @param author Author. - * @param publishDate Point in time (Unix timestamp) when the article was published; 0 if unknown. - */ - public PageBlockAuthorDate(RichText author, int publishDate) { - this.author = author; - this.publishDate = publishDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1300231184; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A header. - */ - public static class PageBlockHeader extends PageBlock { - /** - * Header. - */ - public RichText header; - - /** - * A header. - */ - public PageBlockHeader() { - } - - /** - * A header. - * - * @param header Header. - */ - public PageBlockHeader(RichText header) { - this.header = header; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1402854811; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A subheader. - */ - public static class PageBlockSubheader extends PageBlock { - /** - * Subheader. - */ - public RichText subheader; - - /** - * A subheader. - */ - public PageBlockSubheader() { - } - - /** - * A subheader. - * - * @param subheader Subheader. - */ - public PageBlockSubheader(RichText subheader) { - this.subheader = subheader; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1263956774; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A kicker. - */ - public static class PageBlockKicker extends PageBlock { - /** - * Kicker. - */ - public RichText kicker; - - /** - * A kicker. - */ - public PageBlockKicker() { - } - - /** - * A kicker. - * - * @param kicker Kicker. - */ - public PageBlockKicker(RichText kicker) { - this.kicker = kicker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1361282635; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A text paragraph. - */ - public static class PageBlockParagraph extends PageBlock { - /** - * Paragraph text. - */ - public RichText text; - - /** - * A text paragraph. - */ - public PageBlockParagraph() { - } - - /** - * A text paragraph. - * - * @param text Paragraph text. - */ - public PageBlockParagraph(RichText text) { - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1182402406; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A preformatted text paragraph. - */ - public static class PageBlockPreformatted extends PageBlock { - /** - * Paragraph text. - */ - public RichText text; - /** - * Programming language for which the text needs to be formatted. - */ - public String language; - - /** - * A preformatted text paragraph. - */ - public PageBlockPreformatted() { - } - - /** - * A preformatted text paragraph. - * - * @param text Paragraph text. - * @param language Programming language for which the text needs to be formatted. - */ - public PageBlockPreformatted(RichText text, String language) { - this.text = text; - this.language = language; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1066346178; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The footer of a page. - */ - public static class PageBlockFooter extends PageBlock { - /** - * Footer. - */ - public RichText footer; - - /** - * The footer of a page. - */ - public PageBlockFooter() { - } - - /** - * The footer of a page. - * - * @param footer Footer. - */ - public PageBlockFooter(RichText footer) { - this.footer = footer; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 886429480; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An empty block separating a page. - */ - public static class PageBlockDivider extends PageBlock { - - /** - * An empty block separating a page. - */ - public PageBlockDivider() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -618614392; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An invisible anchor on a page, which can be used in a URL to open the page from the specified anchor. - */ - public static class PageBlockAnchor extends PageBlock { - /** - * Name of the anchor. - */ - public String name; - - /** - * An invisible anchor on a page, which can be used in a URL to open the page from the specified anchor. - */ - public PageBlockAnchor() { - } - - /** - * An invisible anchor on a page, which can be used in a URL to open the page from the specified anchor. - * - * @param name Name of the anchor. - */ - public PageBlockAnchor(String name) { - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -837994576; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A list of data blocks. - */ - public static class PageBlockList extends PageBlock { - /** - * The items of the list. - */ - public PageBlockListItem[] items; - - /** - * A list of data blocks. - */ - public PageBlockList() { - } - - /** - * A list of data blocks. - * - * @param items The items of the list. - */ - public PageBlockList(PageBlockListItem[] items) { - this.items = items; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1037074852; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A block quote. - */ - public static class PageBlockBlockQuote extends PageBlock { - /** - * Quote text. - */ - public RichText text; - /** - * Quote credit. - */ - public RichText credit; - - /** - * A block quote. - */ - public PageBlockBlockQuote() { - } - - /** - * A block quote. - * - * @param text Quote text. - * @param credit Quote credit. - */ - public PageBlockBlockQuote(RichText text, RichText credit) { - this.text = text; - this.credit = credit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1657834142; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A pull quote. - */ - public static class PageBlockPullQuote extends PageBlock { - /** - * Quote text. - */ - public RichText text; - /** - * Quote credit. - */ - public RichText credit; - - /** - * A pull quote. - */ - public PageBlockPullQuote() { - } - - /** - * A pull quote. - * - * @param text Quote text. - * @param credit Quote credit. - */ - public PageBlockPullQuote(RichText text, RichText credit) { - this.text = text; - this.credit = credit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 490242317; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An animation. - */ - public static class PageBlockAnimation extends PageBlock { - /** - * Animation file; may be null. - */ - @Nullable public Animation animation; - /** - * Animation caption. - */ - public PageBlockCaption caption; - /** - * True, if the animation must be played automatically. - */ - public boolean needAutoplay; - - /** - * An animation. - */ - public PageBlockAnimation() { - } - - /** - * An animation. - * - * @param animation Animation file; may be null. - * @param caption Animation caption. - * @param needAutoplay True, if the animation must be played automatically. - */ - public PageBlockAnimation(Animation animation, PageBlockCaption caption, boolean needAutoplay) { - this.animation = animation; - this.caption = caption; - this.needAutoplay = needAutoplay; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1355669513; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An audio file. - */ - public static class PageBlockAudio extends PageBlock { - /** - * Audio file; may be null. - */ - @Nullable public Audio audio; - /** - * Audio file caption. - */ - public PageBlockCaption caption; - - /** - * An audio file. - */ - public PageBlockAudio() { - } - - /** - * An audio file. - * - * @param audio Audio file; may be null. - * @param caption Audio file caption. - */ - public PageBlockAudio(Audio audio, PageBlockCaption caption) { - this.audio = audio; - this.caption = caption; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -63371245; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A photo. - */ - public static class PageBlockPhoto extends PageBlock { - /** - * Photo file; may be null. - */ - @Nullable public Photo photo; - /** - * Photo caption. - */ - public PageBlockCaption caption; - /** - * URL that needs to be opened when the photo is clicked. - */ - public String url; - - /** - * A photo. - */ - public PageBlockPhoto() { - } - - /** - * A photo. - * - * @param photo Photo file; may be null. - * @param caption Photo caption. - * @param url URL that needs to be opened when the photo is clicked. - */ - public PageBlockPhoto(Photo photo, PageBlockCaption caption, String url) { - this.photo = photo; - this.caption = caption; - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 417601156; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A video. - */ - public static class PageBlockVideo extends PageBlock { - /** - * Video file; may be null. - */ - @Nullable public Video video; - /** - * Video caption. - */ - public PageBlockCaption caption; - /** - * True, if the video must be played automatically. - */ - public boolean needAutoplay; - /** - * True, if the video must be looped. - */ - public boolean isLooped; - - /** - * A video. - */ - public PageBlockVideo() { - } - - /** - * A video. - * - * @param video Video file; may be null. - * @param caption Video caption. - * @param needAutoplay True, if the video must be played automatically. - * @param isLooped True, if the video must be looped. - */ - public PageBlockVideo(Video video, PageBlockCaption caption, boolean needAutoplay, boolean isLooped) { - this.video = video; - this.caption = caption; - this.needAutoplay = needAutoplay; - this.isLooped = isLooped; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 510041394; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A voice note. - */ - public static class PageBlockVoiceNote extends PageBlock { - /** - * Voice note; may be null. - */ - @Nullable public VoiceNote voiceNote; - /** - * Voice note caption. - */ - public PageBlockCaption caption; - - /** - * A voice note. - */ - public PageBlockVoiceNote() { - } - - /** - * A voice note. - * - * @param voiceNote Voice note; may be null. - * @param caption Voice note caption. - */ - public PageBlockVoiceNote(VoiceNote voiceNote, PageBlockCaption caption) { - this.voiceNote = voiceNote; - this.caption = caption; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1823310463; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A page cover. - */ - public static class PageBlockCover extends PageBlock { - /** - * Cover. - */ - public PageBlock cover; - - /** - * A page cover. - */ - public PageBlockCover() { - } - - /** - * A page cover. - * - * @param cover Cover. - */ - public PageBlockCover(PageBlock cover) { - this.cover = cover; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 972174080; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An embedded web page. - */ - public static class PageBlockEmbedded extends PageBlock { - /** - * URL of the embedded page, if available. - */ - public String url; - /** - * HTML-markup of the embedded page. - */ - public String html; - /** - * Poster photo, if available; may be null. - */ - @Nullable public Photo posterPhoto; - /** - * Block width; 0 if unknown. - */ - public int width; - /** - * Block height; 0 if unknown. - */ - public int height; - /** - * Block caption. - */ - public PageBlockCaption caption; - /** - * True, if the block must be full width. - */ - public boolean isFullWidth; - /** - * True, if scrolling needs to be allowed. - */ - public boolean allowScrolling; - - /** - * An embedded web page. - */ - public PageBlockEmbedded() { - } - - /** - * An embedded web page. - * - * @param url URL of the embedded page, if available. - * @param html HTML-markup of the embedded page. - * @param posterPhoto Poster photo, if available; may be null. - * @param width Block width; 0 if unknown. - * @param height Block height; 0 if unknown. - * @param caption Block caption. - * @param isFullWidth True, if the block must be full width. - * @param allowScrolling True, if scrolling needs to be allowed. - */ - public PageBlockEmbedded(String url, String html, Photo posterPhoto, int width, int height, PageBlockCaption caption, boolean isFullWidth, boolean allowScrolling) { - this.url = url; - this.html = html; - this.posterPhoto = posterPhoto; - this.width = width; - this.height = height; - this.caption = caption; - this.isFullWidth = isFullWidth; - this.allowScrolling = allowScrolling; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1942577763; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An embedded post. - */ - public static class PageBlockEmbeddedPost extends PageBlock { - /** - * URL of the embedded post. - */ - public String url; - /** - * Post author. - */ - public String author; - /** - * Post author photo; may be null. - */ - @Nullable public Photo authorPhoto; - /** - * Point in time (Unix timestamp) when the post was created; 0 if unknown. - */ - public int date; - /** - * Post content. - */ - public PageBlock[] pageBlocks; - /** - * Post caption. - */ - public PageBlockCaption caption; - - /** - * An embedded post. - */ - public PageBlockEmbeddedPost() { - } - - /** - * An embedded post. - * - * @param url URL of the embedded post. - * @param author Post author. - * @param authorPhoto Post author photo; may be null. - * @param date Point in time (Unix timestamp) when the post was created; 0 if unknown. - * @param pageBlocks Post content. - * @param caption Post caption. - */ - public PageBlockEmbeddedPost(String url, String author, Photo authorPhoto, int date, PageBlock[] pageBlocks, PageBlockCaption caption) { - this.url = url; - this.author = author; - this.authorPhoto = authorPhoto; - this.date = date; - this.pageBlocks = pageBlocks; - this.caption = caption; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 397600949; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A collage. - */ - public static class PageBlockCollage extends PageBlock { - /** - * Collage item contents. - */ - public PageBlock[] pageBlocks; - /** - * Block caption. - */ - public PageBlockCaption caption; - - /** - * A collage. - */ - public PageBlockCollage() { - } - - /** - * A collage. - * - * @param pageBlocks Collage item contents. - * @param caption Block caption. - */ - public PageBlockCollage(PageBlock[] pageBlocks, PageBlockCaption caption) { - this.pageBlocks = pageBlocks; - this.caption = caption; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1163760110; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A slideshow. - */ - public static class PageBlockSlideshow extends PageBlock { - /** - * Slideshow item contents. - */ - public PageBlock[] pageBlocks; - /** - * Block caption. - */ - public PageBlockCaption caption; - - /** - * A slideshow. - */ - public PageBlockSlideshow() { - } - - /** - * A slideshow. - * - * @param pageBlocks Slideshow item contents. - * @param caption Block caption. - */ - public PageBlockSlideshow(PageBlock[] pageBlocks, PageBlockCaption caption) { - this.pageBlocks = pageBlocks; - this.caption = caption; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 539217375; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A link to a chat. - */ - public static class PageBlockChatLink extends PageBlock { - /** - * Chat title. - */ - public String title; - /** - * Chat photo; may be null. - */ - @Nullable public ChatPhotoInfo photo; - /** - * Identifier of the accent color for chat title and background of chat photo. - */ - public int accentColorId; - /** - * Chat username by which all other information about the chat can be resolved. - */ - public String username; - - /** - * A link to a chat. - */ - public PageBlockChatLink() { - } - - /** - * A link to a chat. - * - * @param title Chat title. - * @param photo Chat photo; may be null. - * @param accentColorId Identifier of the accent color for chat title and background of chat photo. - * @param username Chat username by which all other information about the chat can be resolved. - */ - public PageBlockChatLink(String title, ChatPhotoInfo photo, int accentColorId, String username) { - this.title = title; - this.photo = photo; - this.accentColorId = accentColorId; - this.username = username; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1646188731; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A table. - */ - public static class PageBlockTable extends PageBlock { - /** - * Table caption. - */ - public RichText caption; - /** - * Table cells. - */ - public PageBlockTableCell[][] cells; - /** - * True, if the table is bordered. - */ - public boolean isBordered; - /** - * True, if the table is striped. - */ - public boolean isStriped; - - /** - * A table. - */ - public PageBlockTable() { - } - - /** - * A table. - * - * @param caption Table caption. - * @param cells Table cells. - * @param isBordered True, if the table is bordered. - * @param isStriped True, if the table is striped. - */ - public PageBlockTable(RichText caption, PageBlockTableCell[][] cells, boolean isBordered, boolean isStriped) { - this.caption = caption; - this.cells = cells; - this.isBordered = isBordered; - this.isStriped = isStriped; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -942649288; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A collapsible block. - */ - public static class PageBlockDetails extends PageBlock { - /** - * Always visible heading for the block. - */ - public RichText header; - /** - * Block contents. - */ - public PageBlock[] pageBlocks; - /** - * True, if the block is open by default. - */ - public boolean isOpen; - - /** - * A collapsible block. - */ - public PageBlockDetails() { - } - - /** - * A collapsible block. - * - * @param header Always visible heading for the block. - * @param pageBlocks Block contents. - * @param isOpen True, if the block is open by default. - */ - public PageBlockDetails(RichText header, PageBlock[] pageBlocks, boolean isOpen) { - this.header = header; - this.pageBlocks = pageBlocks; - this.isOpen = isOpen; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1599869809; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Related articles. - */ - public static class PageBlockRelatedArticles extends PageBlock { - /** - * Block header. - */ - public RichText header; - /** - * List of related articles. - */ - public PageBlockRelatedArticle[] articles; - - /** - * Related articles. - */ - public PageBlockRelatedArticles() { - } - - /** - * Related articles. - * - * @param header Block header. - * @param articles List of related articles. - */ - public PageBlockRelatedArticles(RichText header, PageBlockRelatedArticle[] articles) { - this.header = header; - this.articles = articles; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1807324374; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A map. - */ - public static class PageBlockMap extends PageBlock { - /** - * Location of the map center. - */ - public Location location; - /** - * Map zoom level. - */ - public int zoom; - /** - * Map width. - */ - public int width; - /** - * Map height. - */ - public int height; - /** - * Block caption. - */ - public PageBlockCaption caption; - - /** - * A map. - */ - public PageBlockMap() { - } - - /** - * A map. - * - * @param location Location of the map center. - * @param zoom Map zoom level. - * @param width Map width. - * @param height Map height. - * @param caption Block caption. - */ - public PageBlockMap(Location location, int zoom, int width, int height, PageBlockCaption caption) { - this.location = location; - this.zoom = zoom; - this.width = width; - this.height = height; - this.caption = caption; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1510961171; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a caption of another block. - */ - public static class PageBlockCaption extends Object { - /** - * Content of the caption. - */ - public RichText text; - /** - * Block credit (like HTML tag <cite>). - */ - public RichText credit; - - /** - * Contains a caption of another block. - */ - public PageBlockCaption() { - } - - /** - * Contains a caption of another block. - * - * @param text Content of the caption. - * @param credit Block credit (like HTML tag <cite>). - */ - public PageBlockCaption(RichText text, RichText credit) { - this.text = text; - this.credit = credit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1180064650; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a horizontal alignment of a table cell content. - */ - public abstract static class PageBlockHorizontalAlignment extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PageBlockHorizontalAlignmentLeft.CONSTRUCTOR, - PageBlockHorizontalAlignmentCenter.CONSTRUCTOR, - PageBlockHorizontalAlignmentRight.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PageBlockHorizontalAlignment() { - } - } - - /** - * The content must be left-aligned. - */ - public static class PageBlockHorizontalAlignmentLeft extends PageBlockHorizontalAlignment { - - /** - * The content must be left-aligned. - */ - public PageBlockHorizontalAlignmentLeft() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 848701417; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The content must be center-aligned. - */ - public static class PageBlockHorizontalAlignmentCenter extends PageBlockHorizontalAlignment { - - /** - * The content must be center-aligned. - */ - public PageBlockHorizontalAlignmentCenter() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1009203990; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The content must be right-aligned. - */ - public static class PageBlockHorizontalAlignmentRight extends PageBlockHorizontalAlignment { - - /** - * The content must be right-aligned. - */ - public PageBlockHorizontalAlignmentRight() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1371369214; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an item of a list page block. - */ - public static class PageBlockListItem extends Object { - /** - * Item label. - */ - public String label; - /** - * Item blocks. - */ - public PageBlock[] pageBlocks; - - /** - * Describes an item of a list page block. - */ - public PageBlockListItem() { - } - - /** - * Describes an item of a list page block. - * - * @param label Item label. - * @param pageBlocks Item blocks. - */ - public PageBlockListItem(String label, PageBlock[] pageBlocks) { - this.label = label; - this.pageBlocks = pageBlocks; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 323186259; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a related article. - */ - public static class PageBlockRelatedArticle extends Object { - /** - * Related article URL. - */ - public String url; - /** - * Article title; may be empty. - */ - public String title; - /** - * Article description; may be empty. - */ - public String description; - /** - * Article photo; may be null. - */ - @Nullable public Photo photo; - /** - * Article author; may be empty. - */ - public String author; - /** - * Point in time (Unix timestamp) when the article was published; 0 if unknown. - */ - public int publishDate; - - /** - * Contains information about a related article. - */ - public PageBlockRelatedArticle() { - } - - /** - * Contains information about a related article. - * - * @param url Related article URL. - * @param title Article title; may be empty. - * @param description Article description; may be empty. - * @param photo Article photo; may be null. - * @param author Article author; may be empty. - * @param publishDate Point in time (Unix timestamp) when the article was published; 0 if unknown. - */ - public PageBlockRelatedArticle(String url, String title, String description, Photo photo, String author, int publishDate) { - this.url = url; - this.title = title; - this.description = description; - this.photo = photo; - this.author = author; - this.publishDate = publishDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 481199251; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a cell of a table. - */ - public static class PageBlockTableCell extends Object { - /** - * Cell text; may be null. If the text is null, then the cell must be invisible. - */ - @Nullable public RichText text; - /** - * True, if it is a header cell. - */ - public boolean isHeader; - /** - * The number of columns the cell spans. - */ - public int colspan; - /** - * The number of rows the cell spans. - */ - public int rowspan; - /** - * Horizontal cell content alignment. - */ - public PageBlockHorizontalAlignment align; - /** - * Vertical cell content alignment. - */ - public PageBlockVerticalAlignment valign; - - /** - * Represents a cell of a table. - */ - public PageBlockTableCell() { - } - - /** - * Represents a cell of a table. - * - * @param text Cell text; may be null. If the text is null, then the cell must be invisible. - * @param isHeader True, if it is a header cell. - * @param colspan The number of columns the cell spans. - * @param rowspan The number of rows the cell spans. - * @param align Horizontal cell content alignment. - * @param valign Vertical cell content alignment. - */ - public PageBlockTableCell(RichText text, boolean isHeader, int colspan, int rowspan, PageBlockHorizontalAlignment align, PageBlockVerticalAlignment valign) { - this.text = text; - this.isHeader = isHeader; - this.colspan = colspan; - this.rowspan = rowspan; - this.align = align; - this.valign = valign; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1417658214; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a Vertical alignment of a table cell content. - */ - public abstract static class PageBlockVerticalAlignment extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PageBlockVerticalAlignmentTop.CONSTRUCTOR, - PageBlockVerticalAlignmentMiddle.CONSTRUCTOR, - PageBlockVerticalAlignmentBottom.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PageBlockVerticalAlignment() { - } - } - - /** - * The content must be top-aligned. - */ - public static class PageBlockVerticalAlignmentTop extends PageBlockVerticalAlignment { - - /** - * The content must be top-aligned. - */ - public PageBlockVerticalAlignmentTop() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 195500454; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The content must be middle-aligned. - */ - public static class PageBlockVerticalAlignmentMiddle extends PageBlockVerticalAlignment { - - /** - * The content must be middle-aligned. - */ - public PageBlockVerticalAlignmentMiddle() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2123096587; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The content must be bottom-aligned. - */ - public static class PageBlockVerticalAlignmentBottom extends PageBlockVerticalAlignment { - - /** - * The content must be bottom-aligned. - */ - public PageBlockVerticalAlignmentBottom() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2092531158; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a paid media. - */ - public abstract static class PaidMedia extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PaidMediaPreview.CONSTRUCTOR, - PaidMediaPhoto.CONSTRUCTOR, - PaidMediaVideo.CONSTRUCTOR, - PaidMediaUnsupported.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PaidMedia() { - } - } - - /** - * The media is hidden until the invoice is paid. - */ - public static class PaidMediaPreview extends PaidMedia { - /** - * Media width; 0 if unknown. - */ - public int width; - /** - * Media height; 0 if unknown. - */ - public int height; - /** - * Media duration, in seconds; 0 if unknown. - */ - public int duration; - /** - * Media minithumbnail; may be null. - */ - @Nullable public Minithumbnail minithumbnail; - - /** - * The media is hidden until the invoice is paid. - */ - public PaidMediaPreview() { - } - - /** - * The media is hidden until the invoice is paid. - * - * @param width Media width; 0 if unknown. - * @param height Media height; 0 if unknown. - * @param duration Media duration, in seconds; 0 if unknown. - * @param minithumbnail Media minithumbnail; may be null. - */ - public PaidMediaPreview(int width, int height, int duration, Minithumbnail minithumbnail) { - this.width = width; - this.height = height; - this.duration = duration; - this.minithumbnail = minithumbnail; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1128151948; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The media is a photo. - */ - public static class PaidMediaPhoto extends PaidMedia { - /** - * The photo. - */ - public Photo photo; - - /** - * The media is a photo. - */ - public PaidMediaPhoto() { - } - - /** - * The media is a photo. - * - * @param photo The photo. - */ - public PaidMediaPhoto(Photo photo) { - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1165863654; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The media is a video. - */ - public static class PaidMediaVideo extends PaidMedia { - /** - * The video. - */ - public Video video; - /** - * Cover of the video; may be null if none. - */ - @Nullable public Photo cover; - /** - * Timestamp from which the video playing must start, in seconds. - */ - public int startTimestamp; - - /** - * The media is a video. - */ - public PaidMediaVideo() { - } - - /** - * The media is a video. - * - * @param video The video. - * @param cover Cover of the video; may be null if none. - * @param startTimestamp Timestamp from which the video playing must start, in seconds. - */ - public PaidMediaVideo(Video video, Photo cover, int startTimestamp) { - this.video = video; - this.cover = cover; - this.startTimestamp = startTimestamp; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 870838318; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The media is unsupported. - */ - public static class PaidMediaUnsupported extends PaidMedia { - - /** - * The media is unsupported. - */ - public PaidMediaUnsupported() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 112999974; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of paid message reaction. - */ - public abstract static class PaidReactionType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PaidReactionTypeRegular.CONSTRUCTOR, - PaidReactionTypeAnonymous.CONSTRUCTOR, - PaidReactionTypeChat.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PaidReactionType() { - } - } - - /** - * A paid reaction on behalf of the current user. - */ - public static class PaidReactionTypeRegular extends PaidReactionType { - - /** - * A paid reaction on behalf of the current user. - */ - public PaidReactionTypeRegular() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1199187333; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An anonymous paid reaction. - */ - public static class PaidReactionTypeAnonymous extends PaidReactionType { - - /** - * An anonymous paid reaction. - */ - public PaidReactionTypeAnonymous() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 47892621; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A paid reaction on behalf of an owned chat. - */ - public static class PaidReactionTypeChat extends PaidReactionType { - /** - * Identifier of the chat. - */ - public long chatId; - - /** - * A paid reaction on behalf of an owned chat. - */ - public PaidReactionTypeChat() { - } - - /** - * A paid reaction on behalf of an owned chat. - * - * @param chatId Identifier of the chat. - */ - public PaidReactionTypeChat(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -675782044; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a user who added paid reactions. - */ - public static class PaidReactor extends Object { - /** - * Identifier of the user or chat that added the reactions; may be null for anonymous reactors that aren't the current user. - */ - @Nullable public MessageSender senderId; - /** - * Number of Telegram Stars added. - */ - public long starCount; - /** - * True, if the reactor is one of the most active reactors; may be false if the reactor is the current user. - */ - public boolean isTop; - /** - * True, if the paid reaction was added by the current user. - */ - public boolean isMe; - /** - * True, if the reactor is anonymous. - */ - public boolean isAnonymous; - - /** - * Contains information about a user who added paid reactions. - */ - public PaidReactor() { - } - - /** - * Contains information about a user who added paid reactions. - * - * @param senderId Identifier of the user or chat that added the reactions; may be null for anonymous reactors that aren't the current user. - * @param starCount Number of Telegram Stars added. - * @param isTop True, if the reactor is one of the most active reactors; may be false if the reactor is the current user. - * @param isMe True, if the paid reaction was added by the current user. - * @param isAnonymous True, if the reactor is anonymous. - */ - public PaidReactor(MessageSender senderId, long starCount, boolean isTop, boolean isMe, boolean isAnonymous) { - this.senderId = senderId; - this.starCount = starCount; - this.isTop = isTop; - this.isMe = isMe; - this.isAnonymous = isAnonymous; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -748917113; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a passkey. - */ - public static class Passkey extends Object { - /** - * Unique identifier of the passkey. - */ - public String id; - /** - * Name of the passkey. - */ - public String name; - /** - * Point in time (Unix timestamp) when the passkey was added. - */ - public int additionDate; - /** - * Point in time (Unix timestamp) when the passkey was used last time; 0 if never. - */ - public int lastUsageDate; - /** - * Identifier of the custom emoji that is used as the icon of the software, which created the passkey; 0 if unknown. - */ - public long softwareIconCustomEmojiId; - - /** - * Describes a passkey. - */ - public Passkey() { - } - - /** - * Describes a passkey. - * - * @param id Unique identifier of the passkey. - * @param name Name of the passkey. - * @param additionDate Point in time (Unix timestamp) when the passkey was added. - * @param lastUsageDate Point in time (Unix timestamp) when the passkey was used last time; 0 if never. - * @param softwareIconCustomEmojiId Identifier of the custom emoji that is used as the icon of the software, which created the passkey; 0 if unknown. - */ - public Passkey(String id, String name, int additionDate, int lastUsageDate, long softwareIconCustomEmojiId) { - this.id = id; - this.name = name; - this.additionDate = additionDate; - this.lastUsageDate = lastUsageDate; - this.softwareIconCustomEmojiId = softwareIconCustomEmojiId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1200601505; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of passkeys. - */ - public static class Passkeys extends Object { - /** - * List of passkeys. - */ - public Passkey[] passkeys; - - /** - * Contains a list of passkeys. - */ - public Passkeys() { - } - - /** - * Contains a list of passkeys. - * - * @param passkeys List of passkeys. - */ - public Passkeys(Passkey[] passkeys) { - this.passkeys = passkeys; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 601084419; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a Telegram Passport authorization form that was requested. - */ - public static class PassportAuthorizationForm extends Object { - /** - * Unique identifier of the authorization form. - */ - public int id; - /** - * Telegram Passport elements that must be provided to complete the form. - */ - public PassportRequiredElement[] requiredElements; - /** - * URL for the privacy policy of the service; may be empty. - */ - public String privacyPolicyUrl; - - /** - * Contains information about a Telegram Passport authorization form that was requested. - */ - public PassportAuthorizationForm() { - } - - /** - * Contains information about a Telegram Passport authorization form that was requested. - * - * @param id Unique identifier of the authorization form. - * @param requiredElements Telegram Passport elements that must be provided to complete the form. - * @param privacyPolicyUrl URL for the privacy policy of the service; may be empty. - */ - public PassportAuthorizationForm(int id, PassportRequiredElement[] requiredElements, String privacyPolicyUrl) { - this.id = id; - this.requiredElements = requiredElements; - this.privacyPolicyUrl = privacyPolicyUrl; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1070673218; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains information about a Telegram Passport element. - */ - public abstract static class PassportElement extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PassportElementPersonalDetails.CONSTRUCTOR, - PassportElementPassport.CONSTRUCTOR, - PassportElementDriverLicense.CONSTRUCTOR, - PassportElementIdentityCard.CONSTRUCTOR, - PassportElementInternalPassport.CONSTRUCTOR, - PassportElementAddress.CONSTRUCTOR, - PassportElementUtilityBill.CONSTRUCTOR, - PassportElementBankStatement.CONSTRUCTOR, - PassportElementRentalAgreement.CONSTRUCTOR, - PassportElementPassportRegistration.CONSTRUCTOR, - PassportElementTemporaryRegistration.CONSTRUCTOR, - PassportElementPhoneNumber.CONSTRUCTOR, - PassportElementEmailAddress.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PassportElement() { - } - } - - /** - * A Telegram Passport element containing the user's personal details. - */ - public static class PassportElementPersonalDetails extends PassportElement { - /** - * Personal details of the user. - */ - public PersonalDetails personalDetails; - - /** - * A Telegram Passport element containing the user's personal details. - */ - public PassportElementPersonalDetails() { - } - - /** - * A Telegram Passport element containing the user's personal details. - * - * @param personalDetails Personal details of the user. - */ - public PassportElementPersonalDetails(PersonalDetails personalDetails) { - this.personalDetails = personalDetails; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1217724035; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's passport. - */ - public static class PassportElementPassport extends PassportElement { - /** - * Passport. - */ - public IdentityDocument passport; - - /** - * A Telegram Passport element containing the user's passport. - */ - public PassportElementPassport() { - } - - /** - * A Telegram Passport element containing the user's passport. - * - * @param passport Passport. - */ - public PassportElementPassport(IdentityDocument passport) { - this.passport = passport; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -263985373; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's driver license. - */ - public static class PassportElementDriverLicense extends PassportElement { - /** - * Driver license. - */ - public IdentityDocument driverLicense; - - /** - * A Telegram Passport element containing the user's driver license. - */ - public PassportElementDriverLicense() { - } - - /** - * A Telegram Passport element containing the user's driver license. - * - * @param driverLicense Driver license. - */ - public PassportElementDriverLicense(IdentityDocument driverLicense) { - this.driverLicense = driverLicense; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1643580589; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's identity card. - */ - public static class PassportElementIdentityCard extends PassportElement { - /** - * Identity card. - */ - public IdentityDocument identityCard; - - /** - * A Telegram Passport element containing the user's identity card. - */ - public PassportElementIdentityCard() { - } - - /** - * A Telegram Passport element containing the user's identity card. - * - * @param identityCard Identity card. - */ - public PassportElementIdentityCard(IdentityDocument identityCard) { - this.identityCard = identityCard; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2083775797; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's internal passport. - */ - public static class PassportElementInternalPassport extends PassportElement { - /** - * Internal passport. - */ - public IdentityDocument internalPassport; - - /** - * A Telegram Passport element containing the user's internal passport. - */ - public PassportElementInternalPassport() { - } - - /** - * A Telegram Passport element containing the user's internal passport. - * - * @param internalPassport Internal passport. - */ - public PassportElementInternalPassport(IdentityDocument internalPassport) { - this.internalPassport = internalPassport; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 36220295; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's address. - */ - public static class PassportElementAddress extends PassportElement { - /** - * Address. - */ - public Address address; - - /** - * A Telegram Passport element containing the user's address. - */ - public PassportElementAddress() { - } - - /** - * A Telegram Passport element containing the user's address. - * - * @param address Address. - */ - public PassportElementAddress(Address address) { - this.address = address; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -782625232; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's utility bill. - */ - public static class PassportElementUtilityBill extends PassportElement { - /** - * Utility bill. - */ - public PersonalDocument utilityBill; - - /** - * A Telegram Passport element containing the user's utility bill. - */ - public PassportElementUtilityBill() { - } - - /** - * A Telegram Passport element containing the user's utility bill. - * - * @param utilityBill Utility bill. - */ - public PassportElementUtilityBill(PersonalDocument utilityBill) { - this.utilityBill = utilityBill; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -234611246; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's bank statement. - */ - public static class PassportElementBankStatement extends PassportElement { - /** - * Bank statement. - */ - public PersonalDocument bankStatement; - - /** - * A Telegram Passport element containing the user's bank statement. - */ - public PassportElementBankStatement() { - } - - /** - * A Telegram Passport element containing the user's bank statement. - * - * @param bankStatement Bank statement. - */ - public PassportElementBankStatement(PersonalDocument bankStatement) { - this.bankStatement = bankStatement; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -366464408; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's rental agreement. - */ - public static class PassportElementRentalAgreement extends PassportElement { - /** - * Rental agreement. - */ - public PersonalDocument rentalAgreement; - - /** - * A Telegram Passport element containing the user's rental agreement. - */ - public PassportElementRentalAgreement() { - } - - /** - * A Telegram Passport element containing the user's rental agreement. - * - * @param rentalAgreement Rental agreement. - */ - public PassportElementRentalAgreement(PersonalDocument rentalAgreement) { - this.rentalAgreement = rentalAgreement; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -290141400; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's passport registration pages. - */ - public static class PassportElementPassportRegistration extends PassportElement { - /** - * Passport registration pages. - */ - public PersonalDocument passportRegistration; - - /** - * A Telegram Passport element containing the user's passport registration pages. - */ - public PassportElementPassportRegistration() { - } - - /** - * A Telegram Passport element containing the user's passport registration pages. - * - * @param passportRegistration Passport registration pages. - */ - public PassportElementPassportRegistration(PersonalDocument passportRegistration) { - this.passportRegistration = passportRegistration; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 618323071; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's temporary registration. - */ - public static class PassportElementTemporaryRegistration extends PassportElement { - /** - * Temporary registration. - */ - public PersonalDocument temporaryRegistration; - - /** - * A Telegram Passport element containing the user's temporary registration. - */ - public PassportElementTemporaryRegistration() { - } - - /** - * A Telegram Passport element containing the user's temporary registration. - * - * @param temporaryRegistration Temporary registration. - */ - public PassportElementTemporaryRegistration(PersonalDocument temporaryRegistration) { - this.temporaryRegistration = temporaryRegistration; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1237626864; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's phone number. - */ - public static class PassportElementPhoneNumber extends PassportElement { - /** - * Phone number. - */ - public String phoneNumber; - - /** - * A Telegram Passport element containing the user's phone number. - */ - public PassportElementPhoneNumber() { - } - - /** - * A Telegram Passport element containing the user's phone number. - * - * @param phoneNumber Phone number. - */ - public PassportElementPhoneNumber(String phoneNumber) { - this.phoneNumber = phoneNumber; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1320118375; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's email address. - */ - public static class PassportElementEmailAddress extends PassportElement { - /** - * Email address. - */ - public String emailAddress; - - /** - * A Telegram Passport element containing the user's email address. - */ - public PassportElementEmailAddress() { - } - - /** - * A Telegram Passport element containing the user's email address. - * - * @param emailAddress Email address. - */ - public PassportElementEmailAddress(String emailAddress) { - this.emailAddress = emailAddress; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1528129531; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains the description of an error in a Telegram Passport element. - */ - public static class PassportElementError extends Object { - /** - * Type of the Telegram Passport element which has the error. - */ - public PassportElementType type; - /** - * Error message. - */ - public String message; - /** - * Error source. - */ - public PassportElementErrorSource source; - - /** - * Contains the description of an error in a Telegram Passport element. - */ - public PassportElementError() { - } - - /** - * Contains the description of an error in a Telegram Passport element. - * - * @param type Type of the Telegram Passport element which has the error. - * @param message Error message. - * @param source Error source. - */ - public PassportElementError(PassportElementType type, String message, PassportElementErrorSource source) { - this.type = type; - this.message = message; - this.source = source; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1861902395; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains the description of an error in a Telegram Passport element. - */ - public abstract static class PassportElementErrorSource extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PassportElementErrorSourceUnspecified.CONSTRUCTOR, - PassportElementErrorSourceDataField.CONSTRUCTOR, - PassportElementErrorSourceFrontSide.CONSTRUCTOR, - PassportElementErrorSourceReverseSide.CONSTRUCTOR, - PassportElementErrorSourceSelfie.CONSTRUCTOR, - PassportElementErrorSourceTranslationFile.CONSTRUCTOR, - PassportElementErrorSourceTranslationFiles.CONSTRUCTOR, - PassportElementErrorSourceFile.CONSTRUCTOR, - PassportElementErrorSourceFiles.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PassportElementErrorSource() { - } - } - - /** - * The element contains an error in an unspecified place. The error will be considered resolved when new data is added. - */ - public static class PassportElementErrorSourceUnspecified extends PassportElementErrorSource { - - /** - * The element contains an error in an unspecified place. The error will be considered resolved when new data is added. - */ - public PassportElementErrorSourceUnspecified() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -378320830; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * One of the data fields contains an error. The error will be considered resolved when the value of the field changes. - */ - public static class PassportElementErrorSourceDataField extends PassportElementErrorSource { - /** - * Field name. - */ - public String fieldName; - - /** - * One of the data fields contains an error. The error will be considered resolved when the value of the field changes. - */ - public PassportElementErrorSourceDataField() { - } - - /** - * One of the data fields contains an error. The error will be considered resolved when the value of the field changes. - * - * @param fieldName Field name. - */ - public PassportElementErrorSourceDataField(String fieldName) { - this.fieldName = fieldName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -308650776; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The front side of the document contains an error. The error will be considered resolved when the file with the front side changes. - */ - public static class PassportElementErrorSourceFrontSide extends PassportElementErrorSource { - - /** - * The front side of the document contains an error. The error will be considered resolved when the file with the front side changes. - */ - public PassportElementErrorSourceFrontSide() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1895658292; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The reverse side of the document contains an error. The error will be considered resolved when the file with the reverse side changes. - */ - public static class PassportElementErrorSourceReverseSide extends PassportElementErrorSource { - - /** - * The reverse side of the document contains an error. The error will be considered resolved when the file with the reverse side changes. - */ - public PassportElementErrorSourceReverseSide() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1918630391; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The selfie with the document contains an error. The error will be considered resolved when the file with the selfie changes. - */ - public static class PassportElementErrorSourceSelfie extends PassportElementErrorSource { - - /** - * The selfie with the document contains an error. The error will be considered resolved when the file with the selfie changes. - */ - public PassportElementErrorSourceSelfie() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -797043672; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * One of files with the translation of the document contains an error. The error will be considered resolved when the file changes. - */ - public static class PassportElementErrorSourceTranslationFile extends PassportElementErrorSource { - /** - * Index of a file with the error. - */ - public int fileIndex; - - /** - * One of files with the translation of the document contains an error. The error will be considered resolved when the file changes. - */ - public PassportElementErrorSourceTranslationFile() { - } - - /** - * One of files with the translation of the document contains an error. The error will be considered resolved when the file changes. - * - * @param fileIndex Index of a file with the error. - */ - public PassportElementErrorSourceTranslationFile(int fileIndex) { - this.fileIndex = fileIndex; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -689621228; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The translation of the document contains an error. The error will be considered resolved when the list of translation files changes. - */ - public static class PassportElementErrorSourceTranslationFiles extends PassportElementErrorSource { - - /** - * The translation of the document contains an error. The error will be considered resolved when the list of translation files changes. - */ - public PassportElementErrorSourceTranslationFiles() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 581280796; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file contains an error. The error will be considered resolved when the file changes. - */ - public static class PassportElementErrorSourceFile extends PassportElementErrorSource { - /** - * Index of a file with the error. - */ - public int fileIndex; - - /** - * The file contains an error. The error will be considered resolved when the file changes. - */ - public PassportElementErrorSourceFile() { - } - - /** - * The file contains an error. The error will be considered resolved when the file changes. - * - * @param fileIndex Index of a file with the error. - */ - public PassportElementErrorSourceFile(int fileIndex) { - this.fileIndex = fileIndex; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2020358960; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of attached files contains an error. The error will be considered resolved when the list of files changes. - */ - public static class PassportElementErrorSourceFiles extends PassportElementErrorSource { - - /** - * The list of attached files contains an error. The error will be considered resolved when the list of files changes. - */ - public PassportElementErrorSourceFiles() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1894164178; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains the type of Telegram Passport element. - */ - public abstract static class PassportElementType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PassportElementTypePersonalDetails.CONSTRUCTOR, - PassportElementTypePassport.CONSTRUCTOR, - PassportElementTypeDriverLicense.CONSTRUCTOR, - PassportElementTypeIdentityCard.CONSTRUCTOR, - PassportElementTypeInternalPassport.CONSTRUCTOR, - PassportElementTypeAddress.CONSTRUCTOR, - PassportElementTypeUtilityBill.CONSTRUCTOR, - PassportElementTypeBankStatement.CONSTRUCTOR, - PassportElementTypeRentalAgreement.CONSTRUCTOR, - PassportElementTypePassportRegistration.CONSTRUCTOR, - PassportElementTypeTemporaryRegistration.CONSTRUCTOR, - PassportElementTypePhoneNumber.CONSTRUCTOR, - PassportElementTypeEmailAddress.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PassportElementType() { - } - } - - /** - * A Telegram Passport element containing the user's personal details. - */ - public static class PassportElementTypePersonalDetails extends PassportElementType { - - /** - * A Telegram Passport element containing the user's personal details. - */ - public PassportElementTypePersonalDetails() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1032136365; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's passport. - */ - public static class PassportElementTypePassport extends PassportElementType { - - /** - * A Telegram Passport element containing the user's passport. - */ - public PassportElementTypePassport() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -436360376; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's driver license. - */ - public static class PassportElementTypeDriverLicense extends PassportElementType { - - /** - * A Telegram Passport element containing the user's driver license. - */ - public PassportElementTypeDriverLicense() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1827298379; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's identity card. - */ - public static class PassportElementTypeIdentityCard extends PassportElementType { - - /** - * A Telegram Passport element containing the user's identity card. - */ - public PassportElementTypeIdentityCard() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -502356132; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's internal passport. - */ - public static class PassportElementTypeInternalPassport extends PassportElementType { - - /** - * A Telegram Passport element containing the user's internal passport. - */ - public PassportElementTypeInternalPassport() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -793781959; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's address. - */ - public static class PassportElementTypeAddress extends PassportElementType { - - /** - * A Telegram Passport element containing the user's address. - */ - public PassportElementTypeAddress() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 496327874; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's utility bill. - */ - public static class PassportElementTypeUtilityBill extends PassportElementType { - - /** - * A Telegram Passport element containing the user's utility bill. - */ - public PassportElementTypeUtilityBill() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 627084906; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's bank statement. - */ - public static class PassportElementTypeBankStatement extends PassportElementType { - - /** - * A Telegram Passport element containing the user's bank statement. - */ - public PassportElementTypeBankStatement() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 574095667; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's rental agreement. - */ - public static class PassportElementTypeRentalAgreement extends PassportElementType { - - /** - * A Telegram Passport element containing the user's rental agreement. - */ - public PassportElementTypeRentalAgreement() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2060583280; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the registration page of the user's passport. - */ - public static class PassportElementTypePassportRegistration extends PassportElementType { - - /** - * A Telegram Passport element containing the registration page of the user's passport. - */ - public PassportElementTypePassportRegistration() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -159478209; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's temporary registration. - */ - public static class PassportElementTypeTemporaryRegistration extends PassportElementType { - - /** - * A Telegram Passport element containing the user's temporary registration. - */ - public PassportElementTypeTemporaryRegistration() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1092498527; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's phone number. - */ - public static class PassportElementTypePhoneNumber extends PassportElementType { - - /** - * A Telegram Passport element containing the user's phone number. - */ - public PassportElementTypePhoneNumber() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -995361172; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A Telegram Passport element containing the user's email address. - */ - public static class PassportElementTypeEmailAddress extends PassportElementType { - - /** - * A Telegram Passport element containing the user's email address. - */ - public PassportElementTypeEmailAddress() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -79321405; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about saved Telegram Passport elements. - */ - public static class PassportElements extends Object { - /** - * Telegram Passport elements. - */ - public PassportElement[] elements; - - /** - * Contains information about saved Telegram Passport elements. - */ - public PassportElements() { - } - - /** - * Contains information about saved Telegram Passport elements. - * - * @param elements Telegram Passport elements. - */ - public PassportElements(PassportElement[] elements) { - this.elements = elements; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1264617556; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a Telegram Passport elements and corresponding errors. - */ - public static class PassportElementsWithErrors extends Object { - /** - * Telegram Passport elements. - */ - public PassportElement[] elements; - /** - * Errors in the elements that are already available. - */ - public PassportElementError[] errors; - - /** - * Contains information about a Telegram Passport elements and corresponding errors. - */ - public PassportElementsWithErrors() { - } - - /** - * Contains information about a Telegram Passport elements and corresponding errors. - * - * @param elements Telegram Passport elements. - * @param errors Errors in the elements that are already available. - */ - public PassportElementsWithErrors(PassportElement[] elements, PassportElementError[] errors) { - this.elements = elements; - this.errors = errors; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1308923044; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a description of the required Telegram Passport element that was requested by a service. - */ - public static class PassportRequiredElement extends Object { - /** - * List of Telegram Passport elements any of which is enough to provide. - */ - public PassportSuitableElement[] suitableElements; - - /** - * Contains a description of the required Telegram Passport element that was requested by a service. - */ - public PassportRequiredElement() { - } - - /** - * Contains a description of the required Telegram Passport element that was requested by a service. - * - * @param suitableElements List of Telegram Passport elements any of which is enough to provide. - */ - public PassportRequiredElement(PassportSuitableElement[] suitableElements) { - this.suitableElements = suitableElements; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1983641651; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a Telegram Passport element that was requested by a service. - */ - public static class PassportSuitableElement extends Object { - /** - * Type of the element. - */ - public PassportElementType type; - /** - * True, if a selfie is required with the identity document. - */ - public boolean isSelfieRequired; - /** - * True, if a certified English translation is required with the document. - */ - public boolean isTranslationRequired; - /** - * True, if personal details must include the user's name in the language of their country of residence. - */ - public boolean isNativeNameRequired; - - /** - * Contains information about a Telegram Passport element that was requested by a service. - */ - public PassportSuitableElement() { - } - - /** - * Contains information about a Telegram Passport element that was requested by a service. - * - * @param type Type of the element. - * @param isSelfieRequired True, if a selfie is required with the identity document. - * @param isTranslationRequired True, if a certified English translation is required with the document. - * @param isNativeNameRequired True, if personal details must include the user's name in the language of their country of residence. - */ - public PassportSuitableElement(PassportElementType type, boolean isSelfieRequired, boolean isTranslationRequired, boolean isNativeNameRequired) { - this.type = type; - this.isSelfieRequired = isSelfieRequired; - this.isTranslationRequired = isTranslationRequired; - this.isNativeNameRequired = isNativeNameRequired; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -789019876; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents the current state of 2-step verification. - */ - public static class PasswordState extends Object { - /** - * True, if a 2-step verification password is set. - */ - public boolean hasPassword; - /** - * Hint for the password; may be empty. - */ - public String passwordHint; - /** - * True, if a recovery email is set. - */ - public boolean hasRecoveryEmailAddress; - /** - * True, if some Telegram Passport elements were saved. - */ - public boolean hasPassportData; - /** - * Information about the recovery email address to which the confirmation email was sent; may be null. - */ - @Nullable public EmailAddressAuthenticationCodeInfo recoveryEmailAddressCodeInfo; - /** - * Pattern of the email address set up for logging in. - */ - public String loginEmailAddressPattern; - /** - * If not 0, point in time (Unix timestamp) after which the 2-step verification password can be reset immediately using resetPassword. - */ - public int pendingResetDate; - - /** - * Represents the current state of 2-step verification. - */ - public PasswordState() { - } - - /** - * Represents the current state of 2-step verification. - * - * @param hasPassword True, if a 2-step verification password is set. - * @param passwordHint Hint for the password; may be empty. - * @param hasRecoveryEmailAddress True, if a recovery email is set. - * @param hasPassportData True, if some Telegram Passport elements were saved. - * @param recoveryEmailAddressCodeInfo Information about the recovery email address to which the confirmation email was sent; may be null. - * @param loginEmailAddressPattern Pattern of the email address set up for logging in. - * @param pendingResetDate If not 0, point in time (Unix timestamp) after which the 2-step verification password can be reset immediately using resetPassword. - */ - public PasswordState(boolean hasPassword, String passwordHint, boolean hasRecoveryEmailAddress, boolean hasPassportData, EmailAddressAuthenticationCodeInfo recoveryEmailAddressCodeInfo, String loginEmailAddressPattern, int pendingResetDate) { - this.hasPassword = hasPassword; - this.passwordHint = passwordHint; - this.hasRecoveryEmailAddress = hasRecoveryEmailAddress; - this.hasPassportData = hasPassportData; - this.recoveryEmailAddressCodeInfo = recoveryEmailAddressCodeInfo; - this.loginEmailAddressPattern = loginEmailAddressPattern; - this.pendingResetDate = pendingResetDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 483801128; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about an invoice payment form. - */ - public static class PaymentForm extends Object { - /** - * The payment form identifier. - */ - public long id; - /** - * Type of the payment form. - */ - public PaymentFormType type; - /** - * User identifier of the seller bot. - */ - public long sellerBotUserId; - /** - * Information about the product. - */ - public ProductInfo productInfo; - - /** - * Contains information about an invoice payment form. - */ - public PaymentForm() { - } - - /** - * Contains information about an invoice payment form. - * - * @param id The payment form identifier. - * @param type Type of the payment form. - * @param sellerBotUserId User identifier of the seller bot. - * @param productInfo Information about the product. - */ - public PaymentForm(long id, PaymentFormType type, long sellerBotUserId, ProductInfo productInfo) { - this.id = id; - this.type = type; - this.sellerBotUserId = sellerBotUserId; - this.productInfo = productInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1998651315; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of payment form. - */ - public abstract static class PaymentFormType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PaymentFormTypeRegular.CONSTRUCTOR, - PaymentFormTypeStars.CONSTRUCTOR, - PaymentFormTypeStarSubscription.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PaymentFormType() { - } - } - - /** - * The payment form is for a regular payment. - */ - public static class PaymentFormTypeRegular extends PaymentFormType { - /** - * Full information about the invoice. - */ - public Invoice invoice; - /** - * User identifier of the payment provider bot. - */ - public long paymentProviderUserId; - /** - * Information about the payment provider. - */ - public PaymentProvider paymentProvider; - /** - * The list of additional payment options. - */ - public PaymentOption[] additionalPaymentOptions; - /** - * Saved server-side order information; may be null. - */ - @Nullable public OrderInfo savedOrderInfo; - /** - * The list of saved payment credentials. - */ - public SavedCredentials[] savedCredentials; - /** - * True, if the user can choose to save credentials. - */ - public boolean canSaveCredentials; - /** - * True, if the user will be able to save credentials, if sets up a 2-step verification password. - */ - public boolean needPassword; - - /** - * The payment form is for a regular payment. - */ - public PaymentFormTypeRegular() { - } - - /** - * The payment form is for a regular payment. - * - * @param invoice Full information about the invoice. - * @param paymentProviderUserId User identifier of the payment provider bot. - * @param paymentProvider Information about the payment provider. - * @param additionalPaymentOptions The list of additional payment options. - * @param savedOrderInfo Saved server-side order information; may be null. - * @param savedCredentials The list of saved payment credentials. - * @param canSaveCredentials True, if the user can choose to save credentials. - * @param needPassword True, if the user will be able to save credentials, if sets up a 2-step verification password. - */ - public PaymentFormTypeRegular(Invoice invoice, long paymentProviderUserId, PaymentProvider paymentProvider, PaymentOption[] additionalPaymentOptions, OrderInfo savedOrderInfo, SavedCredentials[] savedCredentials, boolean canSaveCredentials, boolean needPassword) { - this.invoice = invoice; - this.paymentProviderUserId = paymentProviderUserId; - this.paymentProvider = paymentProvider; - this.additionalPaymentOptions = additionalPaymentOptions; - this.savedOrderInfo = savedOrderInfo; - this.savedCredentials = savedCredentials; - this.canSaveCredentials = canSaveCredentials; - this.needPassword = needPassword; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -615089778; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The payment form is for a payment in Telegram Stars. - */ - public static class PaymentFormTypeStars extends PaymentFormType { - /** - * Number of Telegram Stars that will be paid. - */ - public long starCount; - - /** - * The payment form is for a payment in Telegram Stars. - */ - public PaymentFormTypeStars() { - } - - /** - * The payment form is for a payment in Telegram Stars. - * - * @param starCount Number of Telegram Stars that will be paid. - */ - public PaymentFormTypeStars(long starCount) { - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 90938685; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The payment form is for a payment in Telegram Stars for subscription. - */ - public static class PaymentFormTypeStarSubscription extends PaymentFormType { - /** - * Information about subscription plan. - */ - public StarSubscriptionPricing pricing; - - /** - * The payment form is for a payment in Telegram Stars for subscription. - */ - public PaymentFormTypeStarSubscription() { - } - - /** - * The payment form is for a payment in Telegram Stars for subscription. - * - * @param pricing Information about subscription plan. - */ - public PaymentFormTypeStarSubscription(StarSubscriptionPricing pricing) { - this.pricing = pricing; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 271444827; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an additional payment option. - */ - public static class PaymentOption extends Object { - /** - * Title for the payment option. - */ - public String title; - /** - * Payment form URL to be opened in a web view. - */ - public String url; - - /** - * Describes an additional payment option. - */ - public PaymentOption() { - } - - /** - * Describes an additional payment option. - * - * @param title Title for the payment option. - * @param url Payment form URL to be opened in a web view. - */ - public PaymentOption(String title, String url) { - this.title = title; - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -294020965; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains information about a payment provider. - */ - public abstract static class PaymentProvider extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PaymentProviderSmartGlocal.CONSTRUCTOR, - PaymentProviderStripe.CONSTRUCTOR, - PaymentProviderOther.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PaymentProvider() { - } - } - - /** - * Smart Glocal payment provider. - */ - public static class PaymentProviderSmartGlocal extends PaymentProvider { - /** - * Public payment token. - */ - public String publicToken; - /** - * URL for sending card tokenization requests. - */ - public String tokenizeUrl; - - /** - * Smart Glocal payment provider. - */ - public PaymentProviderSmartGlocal() { - } - - /** - * Smart Glocal payment provider. - * - * @param publicToken Public payment token. - * @param tokenizeUrl URL for sending card tokenization requests. - */ - public PaymentProviderSmartGlocal(String publicToken, String tokenizeUrl) { - this.publicToken = publicToken; - this.tokenizeUrl = tokenizeUrl; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1174112396; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Stripe payment provider. - */ - public static class PaymentProviderStripe extends PaymentProvider { - /** - * Stripe API publishable key. - */ - public String publishableKey; - /** - * True, if the user country must be provided. - */ - public boolean needCountry; - /** - * True, if the user ZIP/postal code must be provided. - */ - public boolean needPostalCode; - /** - * True, if the cardholder name must be provided. - */ - public boolean needCardholderName; - - /** - * Stripe payment provider. - */ - public PaymentProviderStripe() { - } - - /** - * Stripe payment provider. - * - * @param publishableKey Stripe API publishable key. - * @param needCountry True, if the user country must be provided. - * @param needPostalCode True, if the user ZIP/postal code must be provided. - * @param needCardholderName True, if the cardholder name must be provided. - */ - public PaymentProviderStripe(String publishableKey, boolean needCountry, boolean needPostalCode, boolean needCardholderName) { - this.publishableKey = publishableKey; - this.needCountry = needCountry; - this.needPostalCode = needPostalCode; - this.needCardholderName = needCardholderName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 370467227; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Some other payment provider, for which a web payment form must be shown. - */ - public static class PaymentProviderOther extends PaymentProvider { - /** - * Payment form URL. - */ - public String url; - - /** - * Some other payment provider, for which a web payment form must be shown. - */ - public PaymentProviderOther() { - } - - /** - * Some other payment provider, for which a web payment form must be shown. - * - * @param url Payment form URL. - */ - public PaymentProviderOther(String url) { - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1336876828; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a successful payment. - */ - public static class PaymentReceipt extends Object { - /** - * Information about the product. - */ - public ProductInfo productInfo; - /** - * Point in time (Unix timestamp) when the payment was made. - */ - public int date; - /** - * User identifier of the seller bot. - */ - public long sellerBotUserId; - /** - * Type of the payment receipt. - */ - public PaymentReceiptType type; - - /** - * Contains information about a successful payment. - */ - public PaymentReceipt() { - } - - /** - * Contains information about a successful payment. - * - * @param productInfo Information about the product. - * @param date Point in time (Unix timestamp) when the payment was made. - * @param sellerBotUserId User identifier of the seller bot. - * @param type Type of the payment receipt. - */ - public PaymentReceipt(ProductInfo productInfo, int date, long sellerBotUserId, PaymentReceiptType type) { - this.productInfo = productInfo; - this.date = date; - this.sellerBotUserId = sellerBotUserId; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 758199186; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of successful payment. - */ - public abstract static class PaymentReceiptType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PaymentReceiptTypeRegular.CONSTRUCTOR, - PaymentReceiptTypeStars.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PaymentReceiptType() { - } - } - - /** - * The payment was done using a third-party payment provider. - */ - public static class PaymentReceiptTypeRegular extends PaymentReceiptType { - /** - * User identifier of the payment provider bot. - */ - public long paymentProviderUserId; - /** - * Information about the invoice. - */ - public Invoice invoice; - /** - * Order information; may be null. - */ - @Nullable public OrderInfo orderInfo; - /** - * Chosen shipping option; may be null. - */ - @Nullable public ShippingOption shippingOption; - /** - * Title of the saved credentials chosen by the buyer. - */ - public String credentialsTitle; - /** - * The amount of tip chosen by the buyer in the smallest units of the currency. - */ - public long tipAmount; - - /** - * The payment was done using a third-party payment provider. - */ - public PaymentReceiptTypeRegular() { - } - - /** - * The payment was done using a third-party payment provider. - * - * @param paymentProviderUserId User identifier of the payment provider bot. - * @param invoice Information about the invoice. - * @param orderInfo Order information; may be null. - * @param shippingOption Chosen shipping option; may be null. - * @param credentialsTitle Title of the saved credentials chosen by the buyer. - * @param tipAmount The amount of tip chosen by the buyer in the smallest units of the currency. - */ - public PaymentReceiptTypeRegular(long paymentProviderUserId, Invoice invoice, OrderInfo orderInfo, ShippingOption shippingOption, String credentialsTitle, long tipAmount) { - this.paymentProviderUserId = paymentProviderUserId; - this.invoice = invoice; - this.orderInfo = orderInfo; - this.shippingOption = shippingOption; - this.credentialsTitle = credentialsTitle; - this.tipAmount = tipAmount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1636362826; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The payment was done using Telegram Stars. - */ - public static class PaymentReceiptTypeStars extends PaymentReceiptType { - /** - * Number of Telegram Stars that were paid. - */ - public long starCount; - /** - * Unique identifier of the transaction that can be used to dispute it. - */ - public String transactionId; - - /** - * The payment was done using Telegram Stars. - */ - public PaymentReceiptTypeStars() { - } - - /** - * The payment was done using Telegram Stars. - * - * @param starCount Number of Telegram Stars that were paid. - * @param transactionId Unique identifier of the transaction that can be used to dispute it. - */ - public PaymentReceiptTypeStars(long starCount, String transactionId) { - this.starCount = starCount; - this.transactionId = transactionId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 294913868; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains the result of a payment request. - */ - public static class PaymentResult extends Object { - /** - * True, if the payment request was successful; otherwise, the verificationUrl will be non-empty. - */ - public boolean success; - /** - * URL for additional payment credentials verification. - */ - public String verificationUrl; - - /** - * Contains the result of a payment request. - */ - public PaymentResult() { - } - - /** - * Contains the result of a payment request. - * - * @param success True, if the payment request was successful; otherwise, the verificationUrl will be non-empty. - * @param verificationUrl URL for additional payment credentials verification. - */ - public PaymentResult(boolean success, String verificationUrl) { - this.success = success; - this.verificationUrl = verificationUrl; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -804263843; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains the user's personal details. - */ - public static class PersonalDetails extends Object { - /** - * First name of the user written in English; 1-255 characters. - */ - public String firstName; - /** - * Middle name of the user written in English; 0-255 characters. - */ - public String middleName; - /** - * Last name of the user written in English; 1-255 characters. - */ - public String lastName; - /** - * Native first name of the user; 1-255 characters. - */ - public String nativeFirstName; - /** - * Native middle name of the user; 0-255 characters. - */ - public String nativeMiddleName; - /** - * Native last name of the user; 1-255 characters. - */ - public String nativeLastName; - /** - * Birthdate of the user. - */ - public Date birthdate; - /** - * Gender of the user, "male" or "female". - */ - public String gender; - /** - * A two-letter ISO 3166-1 alpha-2 country code of the user's country. - */ - public String countryCode; - /** - * A two-letter ISO 3166-1 alpha-2 country code of the user's residence country. - */ - public String residenceCountryCode; - - /** - * Contains the user's personal details. - */ - public PersonalDetails() { - } - - /** - * Contains the user's personal details. - * - * @param firstName First name of the user written in English; 1-255 characters. - * @param middleName Middle name of the user written in English; 0-255 characters. - * @param lastName Last name of the user written in English; 1-255 characters. - * @param nativeFirstName Native first name of the user; 1-255 characters. - * @param nativeMiddleName Native middle name of the user; 0-255 characters. - * @param nativeLastName Native last name of the user; 1-255 characters. - * @param birthdate Birthdate of the user. - * @param gender Gender of the user, "male" or "female". - * @param countryCode A two-letter ISO 3166-1 alpha-2 country code of the user's country. - * @param residenceCountryCode A two-letter ISO 3166-1 alpha-2 country code of the user's residence country. - */ - public PersonalDetails(String firstName, String middleName, String lastName, String nativeFirstName, String nativeMiddleName, String nativeLastName, Date birthdate, String gender, String countryCode, String residenceCountryCode) { - this.firstName = firstName; - this.middleName = middleName; - this.lastName = lastName; - this.nativeFirstName = nativeFirstName; - this.nativeMiddleName = nativeMiddleName; - this.nativeLastName = nativeLastName; - this.birthdate = birthdate; - this.gender = gender; - this.countryCode = countryCode; - this.residenceCountryCode = residenceCountryCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1061656137; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A personal document, containing some information about a user. - */ - public static class PersonalDocument extends Object { - /** - * List of files containing the pages of the document. - */ - public DatedFile[] files; - /** - * List of files containing a certified English translation of the document. - */ - public DatedFile[] translation; - - /** - * A personal document, containing some information about a user. - */ - public PersonalDocument() { - } - - /** - * A personal document, containing some information about a user. - * - * @param files List of files containing the pages of the document. - * @param translation List of files containing a certified English translation of the document. - */ - public PersonalDocument(DatedFile[] files, DatedFile[] translation) { - this.files = files; - this.translation = translation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1011634661; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains settings for the authentication of the user's phone number. - */ - public static class PhoneNumberAuthenticationSettings extends Object { - /** - * Pass true if the authentication code may be sent via a flash call to the specified phone number. - */ - public boolean allowFlashCall; - /** - * Pass true if the authentication code may be sent via a missed call to the specified phone number. - */ - public boolean allowMissedCall; - /** - * Pass true if the authenticated phone number is used on the current device. - */ - public boolean isCurrentPhoneNumber; - /** - * Pass true if there is a SIM card in the current device, but it is not possible to check whether phone number matches. - */ - public boolean hasUnknownPhoneNumber; - /** - * For official applications only. True, if the application can use Android SMS Retriever API (requires Google Play Services >= 10.2) to automatically receive the authentication code from the SMS. See https://developers.google.com/identity/sms-retriever/ for more details. - */ - public boolean allowSmsRetrieverApi; - /** - * For official Android and iOS applications only; pass null otherwise. Settings for Firebase Authentication. - */ - public FirebaseAuthenticationSettings firebaseAuthenticationSettings; - /** - * List of up to 20 authentication tokens, recently received in updateOption("authentication_token") in previously logged out sessions; for setAuthenticationPhoneNumber only. - */ - public String[] authenticationTokens; - - /** - * Contains settings for the authentication of the user's phone number. - */ - public PhoneNumberAuthenticationSettings() { - } - - /** - * Contains settings for the authentication of the user's phone number. - * - * @param allowFlashCall Pass true if the authentication code may be sent via a flash call to the specified phone number. - * @param allowMissedCall Pass true if the authentication code may be sent via a missed call to the specified phone number. - * @param isCurrentPhoneNumber Pass true if the authenticated phone number is used on the current device. - * @param hasUnknownPhoneNumber Pass true if there is a SIM card in the current device, but it is not possible to check whether phone number matches. - * @param allowSmsRetrieverApi For official applications only. True, if the application can use Android SMS Retriever API (requires Google Play Services >= 10.2) to automatically receive the authentication code from the SMS. See https://developers.google.com/identity/sms-retriever/ for more details. - * @param firebaseAuthenticationSettings For official Android and iOS applications only; pass null otherwise. Settings for Firebase Authentication. - * @param authenticationTokens List of up to 20 authentication tokens, recently received in updateOption("authentication_token") in previously logged out sessions; for setAuthenticationPhoneNumber only. - */ - public PhoneNumberAuthenticationSettings(boolean allowFlashCall, boolean allowMissedCall, boolean isCurrentPhoneNumber, boolean hasUnknownPhoneNumber, boolean allowSmsRetrieverApi, FirebaseAuthenticationSettings firebaseAuthenticationSettings, String[] authenticationTokens) { - this.allowFlashCall = allowFlashCall; - this.allowMissedCall = allowMissedCall; - this.isCurrentPhoneNumber = isCurrentPhoneNumber; - this.hasUnknownPhoneNumber = hasUnknownPhoneNumber; - this.allowSmsRetrieverApi = allowSmsRetrieverApi; - this.firebaseAuthenticationSettings = firebaseAuthenticationSettings; - this.authenticationTokens = authenticationTokens; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1881885547; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of the request for which a code is sent to a phone number. - */ - public abstract static class PhoneNumberCodeType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PhoneNumberCodeTypeChange.CONSTRUCTOR, - PhoneNumberCodeTypeVerify.CONSTRUCTOR, - PhoneNumberCodeTypeConfirmOwnership.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PhoneNumberCodeType() { - } - } - - /** - * Checks ownership of a new phone number to change the user's authentication phone number; for official Android and iOS applications only. - */ - public static class PhoneNumberCodeTypeChange extends PhoneNumberCodeType { - - /** - * Checks ownership of a new phone number to change the user's authentication phone number; for official Android and iOS applications only. - */ - public PhoneNumberCodeTypeChange() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 87144986; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Verifies ownership of a phone number to be added to the user's Telegram Passport. - */ - public static class PhoneNumberCodeTypeVerify extends PhoneNumberCodeType { - - /** - * Verifies ownership of a phone number to be added to the user's Telegram Passport. - */ - public PhoneNumberCodeTypeVerify() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1029402661; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Confirms ownership of a phone number to prevent account deletion while handling links of the type internalLinkTypePhoneNumberConfirmation. - */ - public static class PhoneNumberCodeTypeConfirmOwnership extends PhoneNumberCodeType { - /** - * Hash value from the link. - */ - public String hash; - - /** - * Confirms ownership of a phone number to prevent account deletion while handling links of the type internalLinkTypePhoneNumberConfirmation. - */ - public PhoneNumberCodeTypeConfirmOwnership() { - } - - /** - * Confirms ownership of a phone number to prevent account deletion while handling links of the type internalLinkTypePhoneNumberConfirmation. - * - * @param hash Hash value from the link. - */ - public PhoneNumberCodeTypeConfirmOwnership(String hash) { - this.hash = hash; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -485404696; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a phone number. - */ - public static class PhoneNumberInfo extends Object { - /** - * Information about the country to which the phone number belongs; may be null. - */ - @Nullable public CountryInfo country; - /** - * The part of the phone number denoting country calling code or its part. - */ - public String countryCallingCode; - /** - * The phone number without country calling code formatted accordingly to local rules. Expected digits are returned as '-', but even more digits might be entered by the user. - */ - public String formattedPhoneNumber; - /** - * True, if the phone number was bought at https://fragment.com and isn't tied to a SIM card. Information about the phone number can be received using getCollectibleItemInfo. - */ - public boolean isAnonymous; - - /** - * Contains information about a phone number. - */ - public PhoneNumberInfo() { - } - - /** - * Contains information about a phone number. - * - * @param country Information about the country to which the phone number belongs; may be null. - * @param countryCallingCode The part of the phone number denoting country calling code or its part. - * @param formattedPhoneNumber The phone number without country calling code formatted accordingly to local rules. Expected digits are returned as '-', but even more digits might be entered by the user. - * @param isAnonymous True, if the phone number was bought at https://fragment.com and isn't tied to a SIM card. Information about the phone number can be received using getCollectibleItemInfo. - */ - public PhoneNumberInfo(CountryInfo country, String countryCallingCode, String formattedPhoneNumber, boolean isAnonymous) { - this.country = country; - this.countryCallingCode = countryCallingCode; - this.formattedPhoneNumber = formattedPhoneNumber; - this.isAnonymous = isAnonymous; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -758933343; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a photo. - */ - public static class Photo extends Object { - /** - * True, if stickers were added to the photo. The list of corresponding sticker sets can be received using getAttachedStickerSets. - */ - public boolean hasStickers; - /** - * Photo minithumbnail; may be null. - */ - @Nullable public Minithumbnail minithumbnail; - /** - * Available variants of the photo, in different sizes. - */ - public PhotoSize[] sizes; - - /** - * Describes a photo. - */ - public Photo() { - } - - /** - * Describes a photo. - * - * @param hasStickers True, if stickers were added to the photo. The list of corresponding sticker sets can be received using getAttachedStickerSets. - * @param minithumbnail Photo minithumbnail; may be null. - * @param sizes Available variants of the photo, in different sizes. - */ - public Photo(boolean hasStickers, Minithumbnail minithumbnail, PhotoSize[] sizes) { - this.hasStickers = hasStickers; - this.minithumbnail = minithumbnail; - this.sizes = sizes; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2022871583; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an image in JPEG format. - */ - public static class PhotoSize extends Object { - /** - * Image type (see https://core.telegram.org/constructor/photoSize). - */ - public String type; - /** - * Information about the image file. - */ - public File photo; - /** - * Image width. - */ - public int width; - /** - * Image height. - */ - public int height; - /** - * Sizes of progressive JPEG file prefixes, which can be used to preliminarily show the image; in bytes. - */ - public int[] progressiveSizes; - - /** - * Describes an image in JPEG format. - */ - public PhotoSize() { - } - - /** - * Describes an image in JPEG format. - * - * @param type Image type (see https://core.telegram.org/constructor/photoSize). - * @param photo Information about the image file. - * @param width Image width. - * @param height Image height. - * @param progressiveSizes Sizes of progressive JPEG file prefixes, which can be used to preliminarily show the image; in bytes. - */ - public PhotoSize(String type, File photo, int width, int height, int[] progressiveSizes) { - this.type = type; - this.photo = photo; - this.width = width; - this.height = height; - this.progressiveSizes = progressiveSizes; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1609182352; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A point on a Cartesian plane. - */ - public static class Point extends Object { - /** - * The point's first coordinate. - */ - public double x; - /** - * The point's second coordinate. - */ - public double y; - - /** - * A point on a Cartesian plane. - */ - public Point() { - } - - /** - * A point on a Cartesian plane. - * - * @param x The point's first coordinate. - * @param y The point's second coordinate. - */ - public Point(double x, double y) { - this.x = x; - this.y = y; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 437515705; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a poll. - */ - public static class Poll extends Object { - /** - * Unique poll identifier. - */ - public long id; - /** - * Poll question; 1-300 characters. Only custom emoji entities are allowed. - */ - public FormattedText question; - /** - * List of poll answer options. - */ - public PollOption[] options; - /** - * Total number of voters, participating in the poll. - */ - public int totalVoterCount; - /** - * Identifiers of recent voters, if the poll is non-anonymous. - */ - public MessageSender[] recentVoterIds; - /** - * True, if the poll is anonymous. - */ - public boolean isAnonymous; - /** - * Type of the poll. - */ - public PollType type; - /** - * Amount of time the poll will be active after creation, in seconds. - */ - public int openPeriod; - /** - * Point in time (Unix timestamp) when the poll will automatically be closed. - */ - public int closeDate; - /** - * True, if the poll is closed. - */ - public boolean isClosed; - - /** - * Describes a poll. - */ - public Poll() { - } - - /** - * Describes a poll. - * - * @param id Unique poll identifier. - * @param question Poll question; 1-300 characters. Only custom emoji entities are allowed. - * @param options List of poll answer options. - * @param totalVoterCount Total number of voters, participating in the poll. - * @param recentVoterIds Identifiers of recent voters, if the poll is non-anonymous. - * @param isAnonymous True, if the poll is anonymous. - * @param type Type of the poll. - * @param openPeriod Amount of time the poll will be active after creation, in seconds. - * @param closeDate Point in time (Unix timestamp) when the poll will automatically be closed. - * @param isClosed True, if the poll is closed. - */ - public Poll(long id, FormattedText question, PollOption[] options, int totalVoterCount, MessageSender[] recentVoterIds, boolean isAnonymous, PollType type, int openPeriod, int closeDate, boolean isClosed) { - this.id = id; - this.question = question; - this.options = options; - this.totalVoterCount = totalVoterCount; - this.recentVoterIds = recentVoterIds; - this.isAnonymous = isAnonymous; - this.type = type; - this.openPeriod = openPeriod; - this.closeDate = closeDate; - this.isClosed = isClosed; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1913016502; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes one answer option of a poll. - */ - public static class PollOption extends Object { - /** - * Option text; 1-100 characters. Only custom emoji entities are allowed. - */ - public FormattedText text; - /** - * Number of voters for this option, available only for closed or voted polls. - */ - public int voterCount; - /** - * The percentage of votes for this option; 0-100. - */ - public int votePercentage; - /** - * True, if the option was chosen by the user. - */ - public boolean isChosen; - /** - * True, if the option is being chosen by a pending setPollAnswer request. - */ - public boolean isBeingChosen; - - /** - * Describes one answer option of a poll. - */ - public PollOption() { - } - - /** - * Describes one answer option of a poll. - * - * @param text Option text; 1-100 characters. Only custom emoji entities are allowed. - * @param voterCount Number of voters for this option, available only for closed or voted polls. - * @param votePercentage The percentage of votes for this option; 0-100. - * @param isChosen True, if the option was chosen by the user. - * @param isBeingChosen True, if the option is being chosen by a pending setPollAnswer request. - */ - public PollOption(FormattedText text, int voterCount, int votePercentage, boolean isChosen, boolean isBeingChosen) { - this.text = text; - this.voterCount = voterCount; - this.votePercentage = votePercentage; - this.isChosen = isChosen; - this.isBeingChosen = isBeingChosen; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1676243088; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the type of poll. - */ - public abstract static class PollType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PollTypeRegular.CONSTRUCTOR, - PollTypeQuiz.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PollType() { - } - } - - /** - * A regular poll. - */ - public static class PollTypeRegular extends PollType { - /** - * True, if multiple answer options can be chosen simultaneously. - */ - public boolean allowMultipleAnswers; - - /** - * A regular poll. - */ - public PollTypeRegular() { - } - - /** - * A regular poll. - * - * @param allowMultipleAnswers True, if multiple answer options can be chosen simultaneously. - */ - public PollTypeRegular(boolean allowMultipleAnswers) { - this.allowMultipleAnswers = allowMultipleAnswers; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 641265698; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A poll in quiz mode, which has exactly one correct answer option and can be answered only once. - */ - public static class PollTypeQuiz extends PollType { - /** - * 0-based identifier of the correct answer option; -1 for a yet unanswered poll. - */ - public int correctOptionId; - /** - * Text that is shown when the user chooses an incorrect answer or taps on the lamp icon; 0-200 characters with at most 2 line feeds; empty for a yet unanswered poll. - */ - public FormattedText explanation; - - /** - * A poll in quiz mode, which has exactly one correct answer option and can be answered only once. - */ - public PollTypeQuiz() { - } - - /** - * A poll in quiz mode, which has exactly one correct answer option and can be answered only once. - * - * @param correctOptionId 0-based identifier of the correct answer option; -1 for a yet unanswered poll. - * @param explanation Text that is shown when the user chooses an incorrect answer or taps on the lamp icon; 0-200 characters with at most 2 line feeds; empty for a yet unanswered poll. - */ - public PollTypeQuiz(int correctOptionId, FormattedText explanation) { - this.correctOptionId = correctOptionId; - this.explanation = explanation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 657013913; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a poll voter. - */ - public static class PollVoter extends Object { - /** - * The voter identifier. - */ - public MessageSender voterId; - /** - * Point in time (Unix timestamp) when the vote was added. - */ - public int date; - - /** - * Represents a poll voter. - */ - public PollVoter() { - } - - /** - * Represents a poll voter. - * - * @param voterId The voter identifier. - * @param date Point in time (Unix timestamp) when the vote was added. - */ - public PollVoter(MessageSender voterId, int date) { - this.voterId = voterId; - this.date = date; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1354417305; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of poll voters. - */ - public static class PollVoters extends Object { - /** - * Approximate total number of poll voters found. - */ - public int totalCount; - /** - * List of poll voters. - */ - public PollVoter[] voters; - - /** - * Represents a list of poll voters. - */ - public PollVoters() { - } - - /** - * Represents a list of poll voters. - * - * @param totalCount Approximate total number of poll voters found. - * @param voters List of poll voters. - */ - public PollVoters(int totalCount, PollVoter[] voters) { - this.totalCount = totalCount; - this.voters = voters; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1255612789; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a feature available to Premium users. - */ - public abstract static class PremiumFeature extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PremiumFeatureIncreasedLimits.CONSTRUCTOR, - PremiumFeatureIncreasedUploadFileSize.CONSTRUCTOR, - PremiumFeatureImprovedDownloadSpeed.CONSTRUCTOR, - PremiumFeatureVoiceRecognition.CONSTRUCTOR, - PremiumFeatureDisabledAds.CONSTRUCTOR, - PremiumFeatureUniqueReactions.CONSTRUCTOR, - PremiumFeatureUniqueStickers.CONSTRUCTOR, - PremiumFeatureCustomEmoji.CONSTRUCTOR, - PremiumFeatureAdvancedChatManagement.CONSTRUCTOR, - PremiumFeatureProfileBadge.CONSTRUCTOR, - PremiumFeatureEmojiStatus.CONSTRUCTOR, - PremiumFeatureAnimatedProfilePhoto.CONSTRUCTOR, - PremiumFeatureForumTopicIcon.CONSTRUCTOR, - PremiumFeatureAppIcons.CONSTRUCTOR, - PremiumFeatureRealTimeChatTranslation.CONSTRUCTOR, - PremiumFeatureUpgradedStories.CONSTRUCTOR, - PremiumFeatureChatBoost.CONSTRUCTOR, - PremiumFeatureAccentColor.CONSTRUCTOR, - PremiumFeatureBackgroundForBoth.CONSTRUCTOR, - PremiumFeatureSavedMessagesTags.CONSTRUCTOR, - PremiumFeatureMessagePrivacy.CONSTRUCTOR, - PremiumFeatureLastSeenTimes.CONSTRUCTOR, - PremiumFeatureBusiness.CONSTRUCTOR, - PremiumFeatureMessageEffects.CONSTRUCTOR, - PremiumFeatureChecklists.CONSTRUCTOR, - PremiumFeaturePaidMessages.CONSTRUCTOR, - PremiumFeatureProtectPrivateChatContent.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PremiumFeature() { - } - } - - /** - * Increased limits. - */ - public static class PremiumFeatureIncreasedLimits extends PremiumFeature { - - /** - * Increased limits. - */ - public PremiumFeatureIncreasedLimits() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1785455031; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Increased maximum upload file size. - */ - public static class PremiumFeatureIncreasedUploadFileSize extends PremiumFeature { - - /** - * Increased maximum upload file size. - */ - public PremiumFeatureIncreasedUploadFileSize() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1825367155; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Improved download speed. - */ - public static class PremiumFeatureImprovedDownloadSpeed extends PremiumFeature { - - /** - * Improved download speed. - */ - public PremiumFeatureImprovedDownloadSpeed() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -267695554; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to convert voice notes to text. - */ - public static class PremiumFeatureVoiceRecognition extends PremiumFeature { - - /** - * The ability to convert voice notes to text. - */ - public PremiumFeatureVoiceRecognition() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1288216542; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Disabled ads. - */ - public static class PremiumFeatureDisabledAds extends PremiumFeature { - - /** - * Disabled ads. - */ - public PremiumFeatureDisabledAds() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2008587702; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Allowed to use more reactions. - */ - public static class PremiumFeatureUniqueReactions extends PremiumFeature { - - /** - * Allowed to use more reactions. - */ - public PremiumFeatureUniqueReactions() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 766750743; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Allowed to use premium stickers with unique effects. - */ - public static class PremiumFeatureUniqueStickers extends PremiumFeature { - - /** - * Allowed to use premium stickers with unique effects. - */ - public PremiumFeatureUniqueStickers() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2101773312; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Allowed to use custom emoji stickers in message texts and captions. - */ - public static class PremiumFeatureCustomEmoji extends PremiumFeature { - - /** - * Allowed to use custom emoji stickers in message texts and captions. - */ - public PremiumFeatureCustomEmoji() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1332599628; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Ability to change position of the main chat list, archive and mute all new chats from non-contacts, and completely disable notifications about the user's contacts joined Telegram. - */ - public static class PremiumFeatureAdvancedChatManagement extends PremiumFeature { - - /** - * Ability to change position of the main chat list, archive and mute all new chats from non-contacts, and completely disable notifications about the user's contacts joined Telegram. - */ - public PremiumFeatureAdvancedChatManagement() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 796347674; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A badge in the user's profile. - */ - public static class PremiumFeatureProfileBadge extends PremiumFeature { - - /** - * A badge in the user's profile. - */ - public PremiumFeatureProfileBadge() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 233648322; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to show an emoji status along with the user's name. - */ - public static class PremiumFeatureEmojiStatus extends PremiumFeature { - - /** - * The ability to show an emoji status along with the user's name. - */ - public PremiumFeatureEmojiStatus() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -36516639; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Profile photo animation on message and chat screens. - */ - public static class PremiumFeatureAnimatedProfilePhoto extends PremiumFeature { - - /** - * Profile photo animation on message and chat screens. - */ - public PremiumFeatureAnimatedProfilePhoto() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -100741914; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to set a custom emoji as a forum topic icon. - */ - public static class PremiumFeatureForumTopicIcon extends PremiumFeature { - - /** - * The ability to set a custom emoji as a forum topic icon. - */ - public PremiumFeatureForumTopicIcon() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -823172286; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Allowed to set a premium application icons. - */ - public static class PremiumFeatureAppIcons extends PremiumFeature { - - /** - * Allowed to set a premium application icons. - */ - public PremiumFeatureAppIcons() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1585050761; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Allowed to translate chat messages real-time. - */ - public static class PremiumFeatureRealTimeChatTranslation extends PremiumFeature { - - /** - * Allowed to translate chat messages real-time. - */ - public PremiumFeatureRealTimeChatTranslation() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1143471488; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Allowed to use many additional features for stories. - */ - public static class PremiumFeatureUpgradedStories extends PremiumFeature { - - /** - * Allowed to use many additional features for stories. - */ - public PremiumFeatureUpgradedStories() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1878522597; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to boost chats. - */ - public static class PremiumFeatureChatBoost extends PremiumFeature { - - /** - * The ability to boost chats. - */ - public PremiumFeatureChatBoost() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1576574747; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to choose accent color for replies and user profile. - */ - public static class PremiumFeatureAccentColor extends PremiumFeature { - - /** - * The ability to choose accent color for replies and user profile. - */ - public PremiumFeatureAccentColor() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 907724190; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to set private chat background for both users. - */ - public static class PremiumFeatureBackgroundForBoth extends PremiumFeature { - - /** - * The ability to set private chat background for both users. - */ - public PremiumFeatureBackgroundForBoth() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 575074042; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to use tags in Saved Messages. - */ - public static class PremiumFeatureSavedMessagesTags extends PremiumFeature { - - /** - * The ability to use tags in Saved Messages. - */ - public PremiumFeatureSavedMessagesTags() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1003219334; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to disallow incoming voice and video note messages in private chats using setUserPrivacySettingRules with userPrivacySettingAllowPrivateVoiceAndVideoNoteMessages and to restrict incoming messages from non-contacts using setNewChatPrivacySettings. - */ - public static class PremiumFeatureMessagePrivacy extends PremiumFeature { - - /** - * The ability to disallow incoming voice and video note messages in private chats using setUserPrivacySettingRules with userPrivacySettingAllowPrivateVoiceAndVideoNoteMessages and to restrict incoming messages from non-contacts using setNewChatPrivacySettings. - */ - public PremiumFeatureMessagePrivacy() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 802322678; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to view last seen and read times of other users even if they can't view last seen or read time for the current user. - */ - public static class PremiumFeatureLastSeenTimes extends PremiumFeature { - - /** - * The ability to view last seen and read times of other users even if they can't view last seen or read time for the current user. - */ - public PremiumFeatureLastSeenTimes() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -762230129; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to use Business features. - */ - public static class PremiumFeatureBusiness extends PremiumFeature { - - /** - * The ability to use Business features. - */ - public PremiumFeatureBusiness() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1503619324; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to use all available message effects. - */ - public static class PremiumFeatureMessageEffects extends PremiumFeature { - - /** - * The ability to use all available message effects. - */ - public PremiumFeatureMessageEffects() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -723300255; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to create and use checklist messages. - */ - public static class PremiumFeatureChecklists extends PremiumFeature { - - /** - * The ability to create and use checklist messages. - */ - public PremiumFeatureChecklists() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1128709251; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to require a payment for incoming messages in new chats. - */ - public static class PremiumFeaturePaidMessages extends PremiumFeature { - - /** - * The ability to require a payment for incoming messages in new chats. - */ - public PremiumFeaturePaidMessages() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2063708431; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to enable content protection in private chats. - */ - public static class PremiumFeatureProtectPrivateChatContent extends PremiumFeature { - - /** - * The ability to enable content protection in private chats. - */ - public PremiumFeatureProtectPrivateChatContent() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -565938675; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a promotion animation for a Premium feature. - */ - public static class PremiumFeaturePromotionAnimation extends Object { - /** - * Premium feature. - */ - public PremiumFeature feature; - /** - * Promotion animation for the feature. - */ - public Animation animation; - - /** - * Describes a promotion animation for a Premium feature. - */ - public PremiumFeaturePromotionAnimation() { - } - - /** - * Describes a promotion animation for a Premium feature. - * - * @param feature Premium feature. - * @param animation Promotion animation for the feature. - */ - public PremiumFeaturePromotionAnimation(PremiumFeature feature, Animation animation) { - this.feature = feature; - this.animation = animation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1986155748; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about features, available to Premium users. - */ - public static class PremiumFeatures extends Object { - /** - * The list of available features. - */ - public PremiumFeature[] features; - /** - * The list of limits, increased for Premium users. - */ - public PremiumLimit[] limits; - /** - * An internal link to be opened to pay for Telegram Premium if store payment isn't possible; may be null if direct payment isn't available. - */ - @Nullable public InternalLinkType paymentLink; - - /** - * Contains information about features, available to Premium users. - */ - public PremiumFeatures() { - } - - /** - * Contains information about features, available to Premium users. - * - * @param features The list of available features. - * @param limits The list of limits, increased for Premium users. - * @param paymentLink An internal link to be opened to pay for Telegram Premium if store payment isn't possible; may be null if direct payment isn't available. - */ - public PremiumFeatures(PremiumFeature[] features, PremiumLimit[] limits, InternalLinkType paymentLink) { - this.features = features; - this.limits = limits; - this.paymentLink = paymentLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1875162172; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a Telegram Premium gift code. - */ - public static class PremiumGiftCodeInfo extends Object { - /** - * Identifier of a chat or a user who created the gift code; may be null if unknown. If null and the code is from messagePremiumGiftCode message, then creatorId from the message can be used. - */ - @Nullable public MessageSender creatorId; - /** - * Point in time (Unix timestamp) when the code was created. - */ - public int creationDate; - /** - * True, if the gift code was created for a giveaway. - */ - public boolean isFromGiveaway; - /** - * Identifier of the corresponding giveaway message in the creatorId chat; may be 0 or an identifier of a deleted message. - */ - public long giveawayMessageId; - /** - * Number of months the Telegram Premium subscription will be active after code activation; 0 if the number of months isn't integer. - */ - public int monthCount; - /** - * Number of days the Telegram Premium subscription will be active after code activation. - */ - public int dayCount; - /** - * Identifier of a user for which the code was created; 0 if none. - */ - public long userId; - /** - * Point in time (Unix timestamp) when the code was activated; 0 if none. - */ - public int useDate; - - /** - * Contains information about a Telegram Premium gift code. - */ - public PremiumGiftCodeInfo() { - } - - /** - * Contains information about a Telegram Premium gift code. - * - * @param creatorId Identifier of a chat or a user who created the gift code; may be null if unknown. If null and the code is from messagePremiumGiftCode message, then creatorId from the message can be used. - * @param creationDate Point in time (Unix timestamp) when the code was created. - * @param isFromGiveaway True, if the gift code was created for a giveaway. - * @param giveawayMessageId Identifier of the corresponding giveaway message in the creatorId chat; may be 0 or an identifier of a deleted message. - * @param monthCount Number of months the Telegram Premium subscription will be active after code activation; 0 if the number of months isn't integer. - * @param dayCount Number of days the Telegram Premium subscription will be active after code activation. - * @param userId Identifier of a user for which the code was created; 0 if none. - * @param useDate Point in time (Unix timestamp) when the code was activated; 0 if none. - */ - public PremiumGiftCodeInfo(MessageSender creatorId, int creationDate, boolean isFromGiveaway, long giveawayMessageId, int monthCount, int dayCount, long userId, int useDate) { - this.creatorId = creatorId; - this.creationDate = creationDate; - this.isFromGiveaway = isFromGiveaway; - this.giveawayMessageId = giveawayMessageId; - this.monthCount = monthCount; - this.dayCount = dayCount; - this.userId = userId; - this.useDate = useDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -262674203; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an option for gifting Telegram Premium to a user. Use telegramPaymentPurposePremiumGift for out-of-store payments or payments in Telegram Stars. - */ - public static class PremiumGiftPaymentOption extends Object { - /** - * ISO 4217 currency code for the payment. - */ - public String currency; - /** - * The amount to pay, in the smallest units of the currency. - */ - public long amount; - /** - * The alternative Telegram Star amount to pay; 0 if payment in Telegram Stars is not possible. - */ - public long starCount; - /** - * The discount associated with this option, as a percentage. - */ - public int discountPercentage; - /** - * Number of months the Telegram Premium subscription will be active. - */ - public int monthCount; - /** - * Identifier of the store product associated with the option. - */ - public String storeProductId; - /** - * A sticker to be shown along with the option; may be null if unknown. - */ - @Nullable public Sticker sticker; - - /** - * Describes an option for gifting Telegram Premium to a user. Use telegramPaymentPurposePremiumGift for out-of-store payments or payments in Telegram Stars. - */ - public PremiumGiftPaymentOption() { - } - - /** - * Describes an option for gifting Telegram Premium to a user. Use telegramPaymentPurposePremiumGift for out-of-store payments or payments in Telegram Stars. - * - * @param currency ISO 4217 currency code for the payment. - * @param amount The amount to pay, in the smallest units of the currency. - * @param starCount The alternative Telegram Star amount to pay; 0 if payment in Telegram Stars is not possible. - * @param discountPercentage The discount associated with this option, as a percentage. - * @param monthCount Number of months the Telegram Premium subscription will be active. - * @param storeProductId Identifier of the store product associated with the option. - * @param sticker A sticker to be shown along with the option; may be null if unknown. - */ - public PremiumGiftPaymentOption(String currency, long amount, long starCount, int discountPercentage, int monthCount, String storeProductId, Sticker sticker) { - this.currency = currency; - this.amount = amount; - this.starCount = starCount; - this.discountPercentage = discountPercentage; - this.monthCount = monthCount; - this.storeProductId = storeProductId; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -338085027; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of options for gifting Telegram Premium to a user. - */ - public static class PremiumGiftPaymentOptions extends Object { - /** - * The list of options sorted by Telegram Premium subscription duration. - */ - public PremiumGiftPaymentOption[] options; - - /** - * Contains a list of options for gifting Telegram Premium to a user. - */ - public PremiumGiftPaymentOptions() { - } - - /** - * Contains a list of options for gifting Telegram Premium to a user. - * - * @param options The list of options sorted by Telegram Premium subscription duration. - */ - public PremiumGiftPaymentOptions(PremiumGiftPaymentOption[] options) { - this.options = options; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1347543032; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an option for creating of Telegram Premium giveaway or manual distribution of Telegram Premium among chat members. Use telegramPaymentPurposePremiumGiftCodes or telegramPaymentPurposePremiumGiveaway for out-of-store payments. - */ - public static class PremiumGiveawayPaymentOption extends Object { - /** - * ISO 4217 currency code for Telegram Premium gift code payment. - */ - public String currency; - /** - * The amount to pay, in the smallest units of the currency. - */ - public long amount; - /** - * Number of users which will be able to activate the gift codes. - */ - public int winnerCount; - /** - * Number of months the Telegram Premium subscription will be active. - */ - public int monthCount; - /** - * Identifier of the store product associated with the option; may be empty if none. - */ - public String storeProductId; - /** - * Number of times the store product must be paid. - */ - public int storeProductQuantity; - - /** - * Describes an option for creating of Telegram Premium giveaway or manual distribution of Telegram Premium among chat members. Use telegramPaymentPurposePremiumGiftCodes or telegramPaymentPurposePremiumGiveaway for out-of-store payments. - */ - public PremiumGiveawayPaymentOption() { - } - - /** - * Describes an option for creating of Telegram Premium giveaway or manual distribution of Telegram Premium among chat members. Use telegramPaymentPurposePremiumGiftCodes or telegramPaymentPurposePremiumGiveaway for out-of-store payments. - * - * @param currency ISO 4217 currency code for Telegram Premium gift code payment. - * @param amount The amount to pay, in the smallest units of the currency. - * @param winnerCount Number of users which will be able to activate the gift codes. - * @param monthCount Number of months the Telegram Premium subscription will be active. - * @param storeProductId Identifier of the store product associated with the option; may be empty if none. - * @param storeProductQuantity Number of times the store product must be paid. - */ - public PremiumGiveawayPaymentOption(String currency, long amount, int winnerCount, int monthCount, String storeProductId, int storeProductQuantity) { - this.currency = currency; - this.amount = amount; - this.winnerCount = winnerCount; - this.monthCount = monthCount; - this.storeProductId = storeProductId; - this.storeProductQuantity = storeProductQuantity; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1099221896; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of options for creating of Telegram Premium giveaway or manual distribution of Telegram Premium among chat members. - */ - public static class PremiumGiveawayPaymentOptions extends Object { - /** - * The list of options. - */ - public PremiumGiveawayPaymentOption[] options; - - /** - * Contains a list of options for creating of Telegram Premium giveaway or manual distribution of Telegram Premium among chat members. - */ - public PremiumGiveawayPaymentOptions() { - } - - /** - * Contains a list of options for creating of Telegram Premium giveaway or manual distribution of Telegram Premium among chat members. - * - * @param options The list of options. - */ - public PremiumGiveawayPaymentOptions(PremiumGiveawayPaymentOption[] options) { - this.options = options; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1587397823; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a limit, increased for Premium users. - */ - public static class PremiumLimit extends Object { - /** - * The type of the limit. - */ - public PremiumLimitType type; - /** - * Default value of the limit. - */ - public int defaultValue; - /** - * Value of the limit for Premium users. - */ - public int premiumValue; - - /** - * Contains information about a limit, increased for Premium users. - */ - public PremiumLimit() { - } - - /** - * Contains information about a limit, increased for Premium users. - * - * @param type The type of the limit. - * @param defaultValue Default value of the limit. - * @param premiumValue Value of the limit for Premium users. - */ - public PremiumLimit(PremiumLimitType type, int defaultValue, int premiumValue) { - this.type = type; - this.defaultValue = defaultValue; - this.premiumValue = premiumValue; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2127786726; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of limit, increased for Premium users. - */ - public abstract static class PremiumLimitType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PremiumLimitTypeSupergroupCount.CONSTRUCTOR, - PremiumLimitTypePinnedChatCount.CONSTRUCTOR, - PremiumLimitTypeCreatedPublicChatCount.CONSTRUCTOR, - PremiumLimitTypeSavedAnimationCount.CONSTRUCTOR, - PremiumLimitTypeFavoriteStickerCount.CONSTRUCTOR, - PremiumLimitTypeChatFolderCount.CONSTRUCTOR, - PremiumLimitTypeChatFolderChosenChatCount.CONSTRUCTOR, - PremiumLimitTypePinnedArchivedChatCount.CONSTRUCTOR, - PremiumLimitTypePinnedSavedMessagesTopicCount.CONSTRUCTOR, - PremiumLimitTypeCaptionLength.CONSTRUCTOR, - PremiumLimitTypeBioLength.CONSTRUCTOR, - PremiumLimitTypeChatFolderInviteLinkCount.CONSTRUCTOR, - PremiumLimitTypeShareableChatFolderCount.CONSTRUCTOR, - PremiumLimitTypeActiveStoryCount.CONSTRUCTOR, - PremiumLimitTypeWeeklyPostedStoryCount.CONSTRUCTOR, - PremiumLimitTypeMonthlyPostedStoryCount.CONSTRUCTOR, - PremiumLimitTypeStoryCaptionLength.CONSTRUCTOR, - PremiumLimitTypeStorySuggestedReactionAreaCount.CONSTRUCTOR, - PremiumLimitTypeSimilarChatCount.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PremiumLimitType() { - } - } - - /** - * The maximum number of joined supergroups and channels. - */ - public static class PremiumLimitTypeSupergroupCount extends PremiumLimitType { - - /** - * The maximum number of joined supergroups and channels. - */ - public PremiumLimitTypeSupergroupCount() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -247467131; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum number of pinned chats in the main chat list. - */ - public static class PremiumLimitTypePinnedChatCount extends PremiumLimitType { - - /** - * The maximum number of pinned chats in the main chat list. - */ - public PremiumLimitTypePinnedChatCount() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -998947871; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum number of created public chats. - */ - public static class PremiumLimitTypeCreatedPublicChatCount extends PremiumLimitType { - - /** - * The maximum number of created public chats. - */ - public PremiumLimitTypeCreatedPublicChatCount() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 446086841; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum number of saved animations. - */ - public static class PremiumLimitTypeSavedAnimationCount extends PremiumLimitType { - - /** - * The maximum number of saved animations. - */ - public PremiumLimitTypeSavedAnimationCount() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -19759735; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum number of favorite stickers. - */ - public static class PremiumLimitTypeFavoriteStickerCount extends PremiumLimitType { - - /** - * The maximum number of favorite stickers. - */ - public PremiumLimitTypeFavoriteStickerCount() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 639754787; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum number of chat folders. - */ - public static class PremiumLimitTypeChatFolderCount extends PremiumLimitType { - - /** - * The maximum number of chat folders. - */ - public PremiumLimitTypeChatFolderCount() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 377489774; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum number of pinned and always included, or always excluded chats in a chat folder. - */ - public static class PremiumLimitTypeChatFolderChosenChatCount extends PremiumLimitType { - - /** - * The maximum number of pinned and always included, or always excluded chats in a chat folder. - */ - public PremiumLimitTypeChatFolderChosenChatCount() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1691435861; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum number of pinned chats in the archive chat list. - */ - public static class PremiumLimitTypePinnedArchivedChatCount extends PremiumLimitType { - - /** - * The maximum number of pinned chats in the archive chat list. - */ - public PremiumLimitTypePinnedArchivedChatCount() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1485515276; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum number of pinned Saved Messages topics. - */ - public static class PremiumLimitTypePinnedSavedMessagesTopicCount extends PremiumLimitType { - - /** - * The maximum number of pinned Saved Messages topics. - */ - public PremiumLimitTypePinnedSavedMessagesTopicCount() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1544854305; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum length of sent media caption. - */ - public static class PremiumLimitTypeCaptionLength extends PremiumLimitType { - - /** - * The maximum length of sent media caption. - */ - public PremiumLimitTypeCaptionLength() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 293984314; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum length of the user's bio. - */ - public static class PremiumLimitTypeBioLength extends PremiumLimitType { - - /** - * The maximum length of the user's bio. - */ - public PremiumLimitTypeBioLength() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1146976765; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum number of invite links for a chat folder. - */ - public static class PremiumLimitTypeChatFolderInviteLinkCount extends PremiumLimitType { - - /** - * The maximum number of invite links for a chat folder. - */ - public PremiumLimitTypeChatFolderInviteLinkCount() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -128702950; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum number of added shareable chat folders. - */ - public static class PremiumLimitTypeShareableChatFolderCount extends PremiumLimitType { - - /** - * The maximum number of added shareable chat folders. - */ - public PremiumLimitTypeShareableChatFolderCount() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1612625095; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum number of active stories. - */ - public static class PremiumLimitTypeActiveStoryCount extends PremiumLimitType { - - /** - * The maximum number of active stories. - */ - public PremiumLimitTypeActiveStoryCount() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1926486372; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum number of stories posted per week. - */ - public static class PremiumLimitTypeWeeklyPostedStoryCount extends PremiumLimitType { - - /** - * The maximum number of stories posted per week. - */ - public PremiumLimitTypeWeeklyPostedStoryCount() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -506354313; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum number of stories posted per month. - */ - public static class PremiumLimitTypeMonthlyPostedStoryCount extends PremiumLimitType { - - /** - * The maximum number of stories posted per month. - */ - public PremiumLimitTypeMonthlyPostedStoryCount() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 26329490; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum length of captions of posted stories. - */ - public static class PremiumLimitTypeStoryCaptionLength extends PremiumLimitType { - - /** - * The maximum length of captions of posted stories. - */ - public PremiumLimitTypeStoryCaptionLength() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1093324030; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum number of suggested reaction areas on a story. - */ - public static class PremiumLimitTypeStorySuggestedReactionAreaCount extends PremiumLimitType { - - /** - * The maximum number of suggested reaction areas on a story. - */ - public PremiumLimitTypeStorySuggestedReactionAreaCount() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1170032633; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The maximum number of received similar chats. - */ - public static class PremiumLimitTypeSimilarChatCount extends PremiumLimitType { - - /** - * The maximum number of received similar chats. - */ - public PremiumLimitTypeSimilarChatCount() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1563549935; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an option for buying Telegram Premium to a user. - */ - public static class PremiumPaymentOption extends Object { - /** - * ISO 4217 currency code for Telegram Premium subscription payment. - */ - public String currency; - /** - * The amount to pay, in the smallest units of the currency. - */ - public long amount; - /** - * The discount associated with this option, as a percentage. - */ - public int discountPercentage; - /** - * Number of months the Telegram Premium subscription will be active. Use getPremiumInfoSticker to get the sticker to be used as representation of the Telegram Premium subscription. - */ - public int monthCount; - /** - * Identifier of the store product associated with the option. - */ - public String storeProductId; - /** - * An internal link to be opened for buying Telegram Premium to the user if store payment isn't possible; may be null if direct payment isn't available. - */ - @Nullable public InternalLinkType paymentLink; - - /** - * Describes an option for buying Telegram Premium to a user. - */ - public PremiumPaymentOption() { - } - - /** - * Describes an option for buying Telegram Premium to a user. - * - * @param currency ISO 4217 currency code for Telegram Premium subscription payment. - * @param amount The amount to pay, in the smallest units of the currency. - * @param discountPercentage The discount associated with this option, as a percentage. - * @param monthCount Number of months the Telegram Premium subscription will be active. Use getPremiumInfoSticker to get the sticker to be used as representation of the Telegram Premium subscription. - * @param storeProductId Identifier of the store product associated with the option. - * @param paymentLink An internal link to be opened for buying Telegram Premium to the user if store payment isn't possible; may be null if direct payment isn't available. - */ - public PremiumPaymentOption(String currency, long amount, int discountPercentage, int monthCount, String storeProductId, InternalLinkType paymentLink) { - this.currency = currency; - this.amount = amount; - this.discountPercentage = discountPercentage; - this.monthCount = monthCount; - this.storeProductId = storeProductId; - this.paymentLink = paymentLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1945346126; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a source from which the Premium features screen is opened. - */ - public abstract static class PremiumSource extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PremiumSourceLimitExceeded.CONSTRUCTOR, - PremiumSourceFeature.CONSTRUCTOR, - PremiumSourceBusinessFeature.CONSTRUCTOR, - PremiumSourceStoryFeature.CONSTRUCTOR, - PremiumSourceLink.CONSTRUCTOR, - PremiumSourceSettings.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PremiumSource() { - } - } - - /** - * A limit was exceeded. - */ - public static class PremiumSourceLimitExceeded extends PremiumSource { - /** - * Type of the exceeded limit. - */ - public PremiumLimitType limitType; - - /** - * A limit was exceeded. - */ - public PremiumSourceLimitExceeded() { - } - - /** - * A limit was exceeded. - * - * @param limitType Type of the exceeded limit. - */ - public PremiumSourceLimitExceeded(PremiumLimitType limitType) { - this.limitType = limitType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2052159742; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A user tried to use a Premium feature. - */ - public static class PremiumSourceFeature extends PremiumSource { - /** - * The used feature. - */ - public PremiumFeature feature; - - /** - * A user tried to use a Premium feature. - */ - public PremiumSourceFeature() { - } - - /** - * A user tried to use a Premium feature. - * - * @param feature The used feature. - */ - public PremiumSourceFeature(PremiumFeature feature) { - this.feature = feature; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 445813541; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A user tried to use a Business feature. - */ - public static class PremiumSourceBusinessFeature extends PremiumSource { - /** - * The used feature; pass null if none specific feature was used. - */ - public BusinessFeature feature; - - /** - * A user tried to use a Business feature. - */ - public PremiumSourceBusinessFeature() { - } - - /** - * A user tried to use a Business feature. - * - * @param feature The used feature; pass null if none specific feature was used. - */ - public PremiumSourceBusinessFeature(BusinessFeature feature) { - this.feature = feature; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1492946340; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A user tried to use a Premium story feature. - */ - public static class PremiumSourceStoryFeature extends PremiumSource { - /** - * The used feature. - */ - public PremiumStoryFeature feature; - - /** - * A user tried to use a Premium story feature. - */ - public PremiumSourceStoryFeature() { - } - - /** - * A user tried to use a Premium story feature. - * - * @param feature The used feature. - */ - public PremiumSourceStoryFeature(PremiumStoryFeature feature) { - this.feature = feature; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1030737556; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A user opened an internal link of the type internalLinkTypePremiumFeaturesPage. - */ - public static class PremiumSourceLink extends PremiumSource { - /** - * The referrer from the link. - */ - public String referrer; - - /** - * A user opened an internal link of the type internalLinkTypePremiumFeaturesPage. - */ - public PremiumSourceLink() { - } - - /** - * A user opened an internal link of the type internalLinkTypePremiumFeaturesPage. - * - * @param referrer The referrer from the link. - */ - public PremiumSourceLink(String referrer) { - this.referrer = referrer; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2135071132; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A user opened the Premium features screen from settings. - */ - public static class PremiumSourceSettings extends PremiumSource { - - /** - * A user opened the Premium features screen from settings. - */ - public PremiumSourceSettings() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -285702859; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains state of Telegram Premium subscription and promotion videos for Premium features. - */ - public static class PremiumState extends Object { - /** - * Text description of the state of the current Premium subscription; may be empty if the current user has no Telegram Premium subscription. - */ - public FormattedText state; - /** - * The list of available options for buying Telegram Premium. - */ - public PremiumStatePaymentOption[] paymentOptions; - /** - * The list of available promotion animations for Premium features. - */ - public PremiumFeaturePromotionAnimation[] animations; - /** - * The list of available promotion animations for Business features. - */ - public BusinessFeaturePromotionAnimation[] businessAnimations; - - /** - * Contains state of Telegram Premium subscription and promotion videos for Premium features. - */ - public PremiumState() { - } - - /** - * Contains state of Telegram Premium subscription and promotion videos for Premium features. - * - * @param state Text description of the state of the current Premium subscription; may be empty if the current user has no Telegram Premium subscription. - * @param paymentOptions The list of available options for buying Telegram Premium. - * @param animations The list of available promotion animations for Premium features. - * @param businessAnimations The list of available promotion animations for Business features. - */ - public PremiumState(FormattedText state, PremiumStatePaymentOption[] paymentOptions, PremiumFeaturePromotionAnimation[] animations, BusinessFeaturePromotionAnimation[] businessAnimations) { - this.state = state; - this.paymentOptions = paymentOptions; - this.animations = animations; - this.businessAnimations = businessAnimations; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1772082178; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an option for buying or upgrading Telegram Premium for self. - */ - public static class PremiumStatePaymentOption extends Object { - /** - * Information about the payment option. - */ - public PremiumPaymentOption paymentOption; - /** - * True, if this is the currently used Telegram Premium subscription option. - */ - public boolean isCurrent; - /** - * True, if the payment option can be used to upgrade the existing Telegram Premium subscription. - */ - public boolean isUpgrade; - /** - * Identifier of the last in-store transaction for the currently used option. - */ - public String lastTransactionId; - - /** - * Describes an option for buying or upgrading Telegram Premium for self. - */ - public PremiumStatePaymentOption() { - } - - /** - * Describes an option for buying or upgrading Telegram Premium for self. - * - * @param paymentOption Information about the payment option. - * @param isCurrent True, if this is the currently used Telegram Premium subscription option. - * @param isUpgrade True, if the payment option can be used to upgrade the existing Telegram Premium subscription. - * @param lastTransactionId Identifier of the last in-store transaction for the currently used option. - */ - public PremiumStatePaymentOption(PremiumPaymentOption paymentOption, boolean isCurrent, boolean isUpgrade, String lastTransactionId) { - this.paymentOption = paymentOption; - this.isCurrent = isCurrent; - this.isUpgrade = isUpgrade; - this.lastTransactionId = lastTransactionId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2097591673; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a story feature available to Premium users. - */ - public abstract static class PremiumStoryFeature extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PremiumStoryFeaturePriorityOrder.CONSTRUCTOR, - PremiumStoryFeatureStealthMode.CONSTRUCTOR, - PremiumStoryFeaturePermanentViewsHistory.CONSTRUCTOR, - PremiumStoryFeatureCustomExpirationDuration.CONSTRUCTOR, - PremiumStoryFeatureSaveStories.CONSTRUCTOR, - PremiumStoryFeatureLinksAndFormatting.CONSTRUCTOR, - PremiumStoryFeatureVideoQuality.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PremiumStoryFeature() { - } - } - - /** - * Stories of the current user are displayed before stories of non-Premium contacts, supergroups, and channels. - */ - public static class PremiumStoryFeaturePriorityOrder extends PremiumStoryFeature { - - /** - * Stories of the current user are displayed before stories of non-Premium contacts, supergroups, and channels. - */ - public PremiumStoryFeaturePriorityOrder() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1880001849; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to hide the fact that the user viewed other's stories. - */ - public static class PremiumStoryFeatureStealthMode extends PremiumStoryFeature { - - /** - * The ability to hide the fact that the user viewed other's stories. - */ - public PremiumStoryFeatureStealthMode() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1194605988; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to check who opened the current user's stories after they expire. - */ - public static class PremiumStoryFeaturePermanentViewsHistory extends PremiumStoryFeature { - - /** - * The ability to check who opened the current user's stories after they expire. - */ - public PremiumStoryFeaturePermanentViewsHistory() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1029683296; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to set custom expiration duration for stories. - */ - public static class PremiumStoryFeatureCustomExpirationDuration extends PremiumStoryFeature { - - /** - * The ability to set custom expiration duration for stories. - */ - public PremiumStoryFeatureCustomExpirationDuration() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -593229162; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to save other's unprotected stories. - */ - public static class PremiumStoryFeatureSaveStories extends PremiumStoryFeature { - - /** - * The ability to save other's unprotected stories. - */ - public PremiumStoryFeatureSaveStories() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1501286467; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to use links and formatting in story caption, and use inputStoryAreaTypeLink areas. - */ - public static class PremiumStoryFeatureLinksAndFormatting extends PremiumStoryFeature { - - /** - * The ability to use links and formatting in story caption, and use inputStoryAreaTypeLink areas. - */ - public PremiumStoryFeatureLinksAndFormatting() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -622623753; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The ability to choose better quality for viewed stories. - */ - public static class PremiumStoryFeatureVideoQuality extends PremiumStoryFeature { - - /** - * The ability to choose better quality for viewed stories. - */ - public PremiumStoryFeatureVideoQuality() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1162887511; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a prepaid giveaway. - */ - public static class PrepaidGiveaway extends Object { - /** - * Unique identifier of the prepaid giveaway. - */ - public long id; - /** - * Number of users which will receive giveaway prize. - */ - public int winnerCount; - /** - * Prize of the giveaway. - */ - public GiveawayPrize prize; - /** - * The number of boosts received by the chat from the giveaway; for Telegram Star giveaways only. - */ - public int boostCount; - /** - * Point in time (Unix timestamp) when the giveaway was paid. - */ - public int paymentDate; - - /** - * Describes a prepaid giveaway. - */ - public PrepaidGiveaway() { - } - - /** - * Describes a prepaid giveaway. - * - * @param id Unique identifier of the prepaid giveaway. - * @param winnerCount Number of users which will receive giveaway prize. - * @param prize Prize of the giveaway. - * @param boostCount The number of boosts received by the chat from the giveaway; for Telegram Star giveaways only. - * @param paymentDate Point in time (Unix timestamp) when the giveaway was paid. - */ - public PrepaidGiveaway(long id, int winnerCount, GiveawayPrize prize, int boostCount, int paymentDate) { - this.id = id; - this.winnerCount = winnerCount; - this.prize = prize; - this.boostCount = boostCount; - this.paymentDate = paymentDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -277859441; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a ready to send inline message. Use sendInlineQueryResultMessage to send the message. - */ - public static class PreparedInlineMessage extends Object { - /** - * Unique identifier of the inline query to pass to sendInlineQueryResultMessage. - */ - public long inlineQueryId; - /** - * Resulted inline message of the query. - */ - public InlineQueryResult result; - /** - * Types of the chats to which the message can be sent. - */ - public TargetChatTypes chatTypes; - - /** - * Represents a ready to send inline message. Use sendInlineQueryResultMessage to send the message. - */ - public PreparedInlineMessage() { - } - - /** - * Represents a ready to send inline message. Use sendInlineQueryResultMessage to send the message. - * - * @param inlineQueryId Unique identifier of the inline query to pass to sendInlineQueryResultMessage. - * @param result Resulted inline message of the query. - * @param chatTypes Types of the chats to which the message can be sent. - */ - public PreparedInlineMessage(long inlineQueryId, InlineQueryResult result, TargetChatTypes chatTypes) { - this.inlineQueryId = inlineQueryId; - this.result = result; - this.chatTypes = chatTypes; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1808892734; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents an inline message that can be sent via the bot. - */ - public static class PreparedInlineMessageId extends Object { - /** - * Unique identifier for the message. - */ - public String id; - /** - * Point in time (Unix timestamp) when the message can't be used anymore. - */ - public int expirationDate; - - /** - * Represents an inline message that can be sent via the bot. - */ - public PreparedInlineMessageId() { - } - - /** - * Represents an inline message that can be sent via the bot. - * - * @param id Unique identifier for the message. - * @param expirationDate Point in time (Unix timestamp) when the message can't be used anymore. - */ - public PreparedInlineMessageId(String id, int expirationDate) { - this.id = id; - this.expirationDate = expirationDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 940415972; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a product that can be paid with invoice. - */ - public static class ProductInfo extends Object { - /** - * Product title. - */ - public String title; - /** - * Product description. - */ - public FormattedText description; - /** - * Product photo; may be null. - */ - @Nullable public Photo photo; - - /** - * Contains information about a product that can be paid with invoice. - */ - public ProductInfo() { - } - - /** - * Contains information about a product that can be paid with invoice. - * - * @param title Product title. - * @param description Product description. - * @param photo Product photo; may be null. - */ - public ProductInfo(String title, FormattedText description, Photo photo) { - this.title = title; - this.description = description; - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2015069020; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about supported accent color for user profile photo background. - */ - public static class ProfileAccentColor extends Object { - /** - * Profile accent color identifier. - */ - public int id; - /** - * Accent colors expected to be used in light themes. - */ - public ProfileAccentColors lightThemeColors; - /** - * Accent colors expected to be used in dark themes. - */ - public ProfileAccentColors darkThemeColors; - /** - * The minimum chat boost level required to use the color in a supergroup chat. - */ - public int minSupergroupChatBoostLevel; - /** - * The minimum chat boost level required to use the color in a channel chat. - */ - public int minChannelChatBoostLevel; - - /** - * Contains information about supported accent color for user profile photo background. - */ - public ProfileAccentColor() { - } - - /** - * Contains information about supported accent color for user profile photo background. - * - * @param id Profile accent color identifier. - * @param lightThemeColors Accent colors expected to be used in light themes. - * @param darkThemeColors Accent colors expected to be used in dark themes. - * @param minSupergroupChatBoostLevel The minimum chat boost level required to use the color in a supergroup chat. - * @param minChannelChatBoostLevel The minimum chat boost level required to use the color in a channel chat. - */ - public ProfileAccentColor(int id, ProfileAccentColors lightThemeColors, ProfileAccentColors darkThemeColors, int minSupergroupChatBoostLevel, int minChannelChatBoostLevel) { - this.id = id; - this.lightThemeColors = lightThemeColors; - this.darkThemeColors = darkThemeColors; - this.minSupergroupChatBoostLevel = minSupergroupChatBoostLevel; - this.minChannelChatBoostLevel = minChannelChatBoostLevel; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 557679253; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about supported accent colors for user profile photo background in RGB format. - */ - public static class ProfileAccentColors extends Object { - /** - * The list of 1-2 colors in RGB format, describing the colors, as expected to be shown in the color palette settings. - */ - public int[] paletteColors; - /** - * The list of 1-2 colors in RGB format, describing the colors, as expected to be used for the profile photo background. - */ - public int[] backgroundColors; - /** - * The list of 2 colors in RGB format, describing the colors of the gradient to be used for the unread active story indicator around profile photo. - */ - public int[] storyColors; - - /** - * Contains information about supported accent colors for user profile photo background in RGB format. - */ - public ProfileAccentColors() { - } - - /** - * Contains information about supported accent colors for user profile photo background in RGB format. - * - * @param paletteColors The list of 1-2 colors in RGB format, describing the colors, as expected to be shown in the color palette settings. - * @param backgroundColors The list of 1-2 colors in RGB format, describing the colors, as expected to be used for the profile photo background. - * @param storyColors The list of 2 colors in RGB format, describing the colors of the gradient to be used for the unread active story indicator around profile photo. - */ - public ProfileAccentColors(int[] paletteColors, int[] backgroundColors, int[] storyColors) { - this.paletteColors = paletteColors; - this.backgroundColors = backgroundColors; - this.storyColors = storyColors; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -596042431; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a user profile photo. - */ - public static class ProfilePhoto extends Object { - /** - * Photo identifier; 0 for an empty photo. Can be used to find a photo in a list of user profile photos. - */ - public long id; - /** - * A small (160x160) user profile photo. The file can be downloaded only before the photo is changed. - */ - public File small; - /** - * A big (640x640) user profile photo. The file can be downloaded only before the photo is changed. - */ - public File big; - /** - * User profile photo minithumbnail; may be null. - */ - @Nullable public Minithumbnail minithumbnail; - /** - * True, if the photo has animated variant. - */ - public boolean hasAnimation; - /** - * True, if the photo is visible only for the current user. - */ - public boolean isPersonal; - - /** - * Describes a user profile photo. - */ - public ProfilePhoto() { - } - - /** - * Describes a user profile photo. - * - * @param id Photo identifier; 0 for an empty photo. Can be used to find a photo in a list of user profile photos. - * @param small A small (160x160) user profile photo. The file can be downloaded only before the photo is changed. - * @param big A big (640x640) user profile photo. The file can be downloaded only before the photo is changed. - * @param minithumbnail User profile photo minithumbnail; may be null. - * @param hasAnimation True, if the photo has animated variant. - * @param isPersonal True, if the photo is visible only for the current user. - */ - public ProfilePhoto(long id, File small, File big, Minithumbnail minithumbnail, boolean hasAnimation, boolean isPersonal) { - this.id = id; - this.small = small; - this.big = big; - this.minithumbnail = minithumbnail; - this.hasAnimation = hasAnimation; - this.isPersonal = isPersonal; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1025754018; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a tab shown in a user or a chat profile. - */ - public abstract static class ProfileTab extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ProfileTabPosts.CONSTRUCTOR, - ProfileTabGifts.CONSTRUCTOR, - ProfileTabMedia.CONSTRUCTOR, - ProfileTabFiles.CONSTRUCTOR, - ProfileTabLinks.CONSTRUCTOR, - ProfileTabMusic.CONSTRUCTOR, - ProfileTabVoice.CONSTRUCTOR, - ProfileTabGifs.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ProfileTab() { - } - } - - /** - * A tab with stories posted by the user or the channel chat and saved to profile. - */ - public static class ProfileTabPosts extends ProfileTab { - - /** - * A tab with stories posted by the user or the channel chat and saved to profile. - */ - public ProfileTabPosts() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1181952362; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A tab with gifts received by the user or the channel chat. - */ - public static class ProfileTabGifts extends ProfileTab { - - /** - * A tab with gifts received by the user or the channel chat. - */ - public ProfileTabGifts() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1296815210; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A tab with photos and videos posted by the channel. - */ - public static class ProfileTabMedia extends ProfileTab { - - /** - * A tab with photos and videos posted by the channel. - */ - public ProfileTabMedia() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1925597525; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A tab with documents posted by the channel. - */ - public static class ProfileTabFiles extends ProfileTab { - - /** - * A tab with documents posted by the channel. - */ - public ProfileTabFiles() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1422681088; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A tab with messages posted by the channel and containing links. - */ - public static class ProfileTabLinks extends ProfileTab { - - /** - * A tab with messages posted by the channel and containing links. - */ - public ProfileTabLinks() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -748329831; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A tab with audio messages posted by the channel. - */ - public static class ProfileTabMusic extends ProfileTab { - - /** - * A tab with audio messages posted by the channel. - */ - public ProfileTabMusic() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1624780178; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A tab with voice notes posted by the channel. - */ - public static class ProfileTabVoice extends ProfileTab { - - /** - * A tab with voice notes posted by the channel. - */ - public ProfileTabVoice() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -461960914; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A tab with animations posted by the channel. - */ - public static class ProfileTabGifs extends ProfileTab { - - /** - * A tab with animations posted by the channel. - */ - public ProfileTabGifs() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1564412267; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a proxy server. - */ - public static class Proxy extends Object { - /** - * Proxy server domain or IP address. - */ - public String server; - /** - * Proxy server port. - */ - public int port; - /** - * Type of the proxy. - */ - public ProxyType type; - - /** - * Describes a proxy server. - */ - public Proxy() { - } - - /** - * Describes a proxy server. - * - * @param server Proxy server domain or IP address. - * @param port Proxy server port. - * @param type Type of the proxy. - */ - public Proxy(String server, int port, ProxyType type) { - this.server = server; - this.port = port; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1636386947; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the type of proxy server. - */ - public abstract static class ProxyType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ProxyTypeSocks5.CONSTRUCTOR, - ProxyTypeHttp.CONSTRUCTOR, - ProxyTypeMtproto.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ProxyType() { - } - } - - /** - * A SOCKS5 proxy server. - */ - public static class ProxyTypeSocks5 extends ProxyType { - /** - * Username for logging in; may be empty. - */ - public String username; - /** - * Password for logging in; may be empty. - */ - public String password; - - /** - * A SOCKS5 proxy server. - */ - public ProxyTypeSocks5() { - } - - /** - * A SOCKS5 proxy server. - * - * @param username Username for logging in; may be empty. - * @param password Password for logging in; may be empty. - */ - public ProxyTypeSocks5(String username, String password) { - this.username = username; - this.password = password; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -890027341; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A HTTP transparent proxy server. - */ - public static class ProxyTypeHttp extends ProxyType { - /** - * Username for logging in; may be empty. - */ - public String username; - /** - * Password for logging in; may be empty. - */ - public String password; - /** - * Pass true if the proxy supports only HTTP requests and doesn't support transparent TCP connections via HTTP CONNECT method. - */ - public boolean httpOnly; - - /** - * A HTTP transparent proxy server. - */ - public ProxyTypeHttp() { - } - - /** - * A HTTP transparent proxy server. - * - * @param username Username for logging in; may be empty. - * @param password Password for logging in; may be empty. - * @param httpOnly Pass true if the proxy supports only HTTP requests and doesn't support transparent TCP connections via HTTP CONNECT method. - */ - public ProxyTypeHttp(String username, String password, boolean httpOnly) { - this.username = username; - this.password = password; - this.httpOnly = httpOnly; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1547188361; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An MTProto proxy server. - */ - public static class ProxyTypeMtproto extends ProxyType { - /** - * The proxy's secret in hexadecimal encoding. - */ - public String secret; - - /** - * An MTProto proxy server. - */ - public ProxyTypeMtproto() { - } - - /** - * An MTProto proxy server. - * - * @param secret The proxy's secret in hexadecimal encoding. - */ - public ProxyTypeMtproto(String secret) { - this.secret = secret; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1964826627; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of public chat. - */ - public abstract static class PublicChatType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PublicChatTypeHasUsername.CONSTRUCTOR, - PublicChatTypeIsLocationBased.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PublicChatType() { - } - } - - /** - * The chat is public, because it has an active username. - */ - public static class PublicChatTypeHasUsername extends PublicChatType { - - /** - * The chat is public, because it has an active username. - */ - public PublicChatTypeHasUsername() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 350789758; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat is public, because it is a location-based supergroup. - */ - public static class PublicChatTypeIsLocationBased extends PublicChatType { - - /** - * The chat is public, because it is a location-based supergroup. - */ - public PublicChatTypeIsLocationBased() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1183735952; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a public forward or repost of a story. - */ - public abstract static class PublicForward extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PublicForwardMessage.CONSTRUCTOR, - PublicForwardStory.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PublicForward() { - } - } - - /** - * Contains a public forward as a message. - */ - public static class PublicForwardMessage extends PublicForward { - /** - * Information about the message. - */ - public Message message; - - /** - * Contains a public forward as a message. - */ - public PublicForwardMessage() { - } - - /** - * Contains a public forward as a message. - * - * @param message Information about the message. - */ - public PublicForwardMessage(Message message) { - this.message = message; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 51885010; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a public repost to a story. - */ - public static class PublicForwardStory extends PublicForward { - /** - * Information about the story. - */ - public Story story; - - /** - * Contains a public repost to a story. - */ - public PublicForwardStory() { - } - - /** - * Contains a public repost to a story. - * - * @param story Information about the story. - */ - public PublicForwardStory(Story story) { - this.story = story; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2145330863; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of public forwards and reposts as a story of a message or a story. - */ - public static class PublicForwards extends Object { - /** - * Approximate total number of messages and stories found. - */ - public int totalCount; - /** - * List of found public forwards and reposts. - */ - public PublicForward[] forwards; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Represents a list of public forwards and reposts as a story of a message or a story. - */ - public PublicForwards() { - } - - /** - * Represents a list of public forwards and reposts as a story of a message or a story. - * - * @param totalCount Approximate total number of messages and stories found. - * @param forwards List of found public forwards and reposts. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public PublicForwards(int totalCount, PublicForward[] forwards, String nextOffset) { - this.totalCount = totalCount; - this.forwards = forwards; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2011272719; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about public post search limits. - */ - public static class PublicPostSearchLimits extends Object { - /** - * Number of queries that can be sent daily for free. - */ - public int dailyFreeQueryCount; - /** - * Number of remaining free queries today. - */ - public int remainingFreeQueryCount; - /** - * Amount of time till the next free query can be sent; 0 if it can be sent now. - */ - public int nextFreeQueryIn; - /** - * Number of Telegram Stars that must be paid for each non-free query. - */ - public long starCount; - /** - * True, if the search for the specified query isn't charged. - */ - public boolean isCurrentQueryFree; - - /** - * Contains information about public post search limits. - */ - public PublicPostSearchLimits() { - } - - /** - * Contains information about public post search limits. - * - * @param dailyFreeQueryCount Number of queries that can be sent daily for free. - * @param remainingFreeQueryCount Number of remaining free queries today. - * @param nextFreeQueryIn Amount of time till the next free query can be sent; 0 if it can be sent now. - * @param starCount Number of Telegram Stars that must be paid for each non-free query. - * @param isCurrentQueryFree True, if the search for the specified query isn't charged. - */ - public PublicPostSearchLimits(int dailyFreeQueryCount, int remainingFreeQueryCount, int nextFreeQueryIn, long starCount, boolean isCurrentQueryFree) { - this.dailyFreeQueryCount = dailyFreeQueryCount; - this.remainingFreeQueryCount = remainingFreeQueryCount; - this.nextFreeQueryIn = nextFreeQueryIn; - this.starCount = starCount; - this.isCurrentQueryFree = isCurrentQueryFree; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 42358064; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains content of a push message notification. - */ - public abstract static class PushMessageContent extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - PushMessageContentHidden.CONSTRUCTOR, - PushMessageContentAnimation.CONSTRUCTOR, - PushMessageContentAudio.CONSTRUCTOR, - PushMessageContentContact.CONSTRUCTOR, - PushMessageContentContactRegistered.CONSTRUCTOR, - PushMessageContentDocument.CONSTRUCTOR, - PushMessageContentGame.CONSTRUCTOR, - PushMessageContentGameScore.CONSTRUCTOR, - PushMessageContentInvoice.CONSTRUCTOR, - PushMessageContentLocation.CONSTRUCTOR, - PushMessageContentPaidMedia.CONSTRUCTOR, - PushMessageContentPhoto.CONSTRUCTOR, - PushMessageContentPoll.CONSTRUCTOR, - PushMessageContentPremiumGiftCode.CONSTRUCTOR, - PushMessageContentGiveaway.CONSTRUCTOR, - PushMessageContentGift.CONSTRUCTOR, - PushMessageContentUpgradedGift.CONSTRUCTOR, - PushMessageContentScreenshotTaken.CONSTRUCTOR, - PushMessageContentSticker.CONSTRUCTOR, - PushMessageContentStory.CONSTRUCTOR, - PushMessageContentText.CONSTRUCTOR, - PushMessageContentChecklist.CONSTRUCTOR, - PushMessageContentVideo.CONSTRUCTOR, - PushMessageContentVideoNote.CONSTRUCTOR, - PushMessageContentVoiceNote.CONSTRUCTOR, - PushMessageContentBasicGroupChatCreate.CONSTRUCTOR, - PushMessageContentVideoChatStarted.CONSTRUCTOR, - PushMessageContentVideoChatEnded.CONSTRUCTOR, - PushMessageContentInviteVideoChatParticipants.CONSTRUCTOR, - PushMessageContentChatAddMembers.CONSTRUCTOR, - PushMessageContentChatChangePhoto.CONSTRUCTOR, - PushMessageContentChatChangeTitle.CONSTRUCTOR, - PushMessageContentChatSetBackground.CONSTRUCTOR, - PushMessageContentChatSetTheme.CONSTRUCTOR, - PushMessageContentChatDeleteMember.CONSTRUCTOR, - PushMessageContentChatJoinByLink.CONSTRUCTOR, - PushMessageContentChatJoinByRequest.CONSTRUCTOR, - PushMessageContentRecurringPayment.CONSTRUCTOR, - PushMessageContentSuggestProfilePhoto.CONSTRUCTOR, - PushMessageContentSuggestBirthdate.CONSTRUCTOR, - PushMessageContentProximityAlertTriggered.CONSTRUCTOR, - PushMessageContentChecklistTasksAdded.CONSTRUCTOR, - PushMessageContentChecklistTasksDone.CONSTRUCTOR, - PushMessageContentMessageForwards.CONSTRUCTOR, - PushMessageContentMediaAlbum.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public PushMessageContent() { - } - } - - /** - * A general message with hidden content. - */ - public static class PushMessageContentHidden extends PushMessageContent { - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A general message with hidden content. - */ - public PushMessageContentHidden() { - } - - /** - * A general message with hidden content. - * - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentHidden(boolean isPinned) { - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -316950436; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An animation message (GIF-style). - */ - public static class PushMessageContentAnimation extends PushMessageContent { - /** - * Message content; may be null. - */ - @Nullable public Animation animation; - /** - * Animation caption. - */ - public String caption; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * An animation message (GIF-style). - */ - public PushMessageContentAnimation() { - } - - /** - * An animation message (GIF-style). - * - * @param animation Message content; may be null. - * @param caption Animation caption. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentAnimation(Animation animation, String caption, boolean isPinned) { - this.animation = animation; - this.caption = caption; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1034215396; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An audio message. - */ - public static class PushMessageContentAudio extends PushMessageContent { - /** - * Message content; may be null. - */ - @Nullable public Audio audio; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * An audio message. - */ - public PushMessageContentAudio() { - } - - /** - * An audio message. - * - * @param audio Message content; may be null. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentAudio(Audio audio, boolean isPinned) { - this.audio = audio; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 381581426; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a user contact. - */ - public static class PushMessageContentContact extends PushMessageContent { - /** - * Contact's name. - */ - public String name; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A message with a user contact. - */ - public PushMessageContentContact() { - } - - /** - * A message with a user contact. - * - * @param name Contact's name. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentContact(String name, boolean isPinned) { - this.name = name; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -12219820; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A contact has registered with Telegram. - */ - public static class PushMessageContentContactRegistered extends PushMessageContent { - /** - * True, if the user joined Telegram as a Telegram Premium account. - */ - public boolean asPremiumAccount; - - /** - * A contact has registered with Telegram. - */ - public PushMessageContentContactRegistered() { - } - - /** - * A contact has registered with Telegram. - * - * @param asPremiumAccount True, if the user joined Telegram as a Telegram Premium account. - */ - public PushMessageContentContactRegistered(boolean asPremiumAccount) { - this.asPremiumAccount = asPremiumAccount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1233778465; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A document message (a general file). - */ - public static class PushMessageContentDocument extends PushMessageContent { - /** - * Message content; may be null. - */ - @Nullable public Document document; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A document message (a general file). - */ - public PushMessageContentDocument() { - } - - /** - * A document message (a general file). - * - * @param document Message content; may be null. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentDocument(Document document, boolean isPinned) { - this.document = document; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -458379775; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a game. - */ - public static class PushMessageContentGame extends PushMessageContent { - /** - * Game title, empty for pinned game message. - */ - public String title; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A message with a game. - */ - public PushMessageContentGame() { - } - - /** - * A message with a game. - * - * @param title Game title, empty for pinned game message. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentGame(String title, boolean isPinned) { - this.title = title; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -515131109; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new high score was achieved in a game. - */ - public static class PushMessageContentGameScore extends PushMessageContent { - /** - * Game title, empty for pinned message. - */ - public String title; - /** - * New score, 0 for pinned message. - */ - public int score; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A new high score was achieved in a game. - */ - public PushMessageContentGameScore() { - } - - /** - * A new high score was achieved in a game. - * - * @param title Game title, empty for pinned message. - * @param score New score, 0 for pinned message. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentGameScore(String title, int score, boolean isPinned) { - this.title = title; - this.score = score; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 901303688; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with an invoice from a bot. - */ - public static class PushMessageContentInvoice extends PushMessageContent { - /** - * Product price. - */ - public String price; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A message with an invoice from a bot. - */ - public PushMessageContentInvoice() { - } - - /** - * A message with an invoice from a bot. - * - * @param price Product price. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentInvoice(String price, boolean isPinned) { - this.price = price; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1731687492; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a location. - */ - public static class PushMessageContentLocation extends PushMessageContent { - /** - * True, if the location is live. - */ - public boolean isLive; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A message with a location. - */ - public PushMessageContentLocation() { - } - - /** - * A message with a location. - * - * @param isLive True, if the location is live. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentLocation(boolean isLive, boolean isPinned) { - this.isLive = isLive; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1288005709; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with paid media. - */ - public static class PushMessageContentPaidMedia extends PushMessageContent { - /** - * Number of Telegram Stars needed to buy access to the media in the message; 0 for pinned message. - */ - public long starCount; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A message with paid media. - */ - public PushMessageContentPaidMedia() { - } - - /** - * A message with paid media. - * - * @param starCount Number of Telegram Stars needed to buy access to the media in the message; 0 for pinned message. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentPaidMedia(long starCount, boolean isPinned) { - this.starCount = starCount; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1252595894; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A photo message. - */ - public static class PushMessageContentPhoto extends PushMessageContent { - /** - * Message content; may be null. - */ - @Nullable public Photo photo; - /** - * Photo caption. - */ - public String caption; - /** - * True, if the photo is secret. - */ - public boolean isSecret; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A photo message. - */ - public PushMessageContentPhoto() { - } - - /** - * A photo message. - * - * @param photo Message content; may be null. - * @param caption Photo caption. - * @param isSecret True, if the photo is secret. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentPhoto(Photo photo, String caption, boolean isSecret, boolean isPinned) { - this.photo = photo; - this.caption = caption; - this.isSecret = isSecret; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 140631122; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a poll. - */ - public static class PushMessageContentPoll extends PushMessageContent { - /** - * Poll question. - */ - public String question; - /** - * True, if the poll is regular and not in quiz mode. - */ - public boolean isRegular; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A message with a poll. - */ - public PushMessageContentPoll() { - } - - /** - * A message with a poll. - * - * @param question Poll question. - * @param isRegular True, if the poll is regular and not in quiz mode. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentPoll(String question, boolean isRegular, boolean isPinned) { - this.question = question; - this.isRegular = isRegular; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -44403654; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a Telegram Premium gift code created for the user. - */ - public static class PushMessageContentPremiumGiftCode extends PushMessageContent { - /** - * Number of months the Telegram Premium subscription will be active after code activation. - */ - public int monthCount; - - /** - * A message with a Telegram Premium gift code created for the user. - */ - public PushMessageContentPremiumGiftCode() { - } - - /** - * A message with a Telegram Premium gift code created for the user. - * - * @param monthCount Number of months the Telegram Premium subscription will be active after code activation. - */ - public PushMessageContentPremiumGiftCode(int monthCount) { - this.monthCount = monthCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 413224997; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a giveaway. - */ - public static class PushMessageContentGiveaway extends PushMessageContent { - /** - * Number of users which will receive giveaway prizes; 0 for pinned message. - */ - public int winnerCount; - /** - * Prize of the giveaway; may be null for pinned message. - */ - @Nullable public GiveawayPrize prize; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A message with a giveaway. - */ - public PushMessageContentGiveaway() { - } - - /** - * A message with a giveaway. - * - * @param winnerCount Number of users which will receive giveaway prizes; 0 for pinned message. - * @param prize Prize of the giveaway; may be null for pinned message. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentGiveaway(int winnerCount, GiveawayPrize prize, boolean isPinned) { - this.winnerCount = winnerCount; - this.prize = prize; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -700547186; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a gift. - */ - public static class PushMessageContentGift extends PushMessageContent { - /** - * Number of Telegram Stars that sender paid for the gift. - */ - public long starCount; - /** - * True, if the message is about prepaid upgrade of the gift by another user instead of actual receiving of a new gift. - */ - public boolean isPrepaidUpgrade; - - /** - * A message with a gift. - */ - public PushMessageContentGift() { - } - - /** - * A message with a gift. - * - * @param starCount Number of Telegram Stars that sender paid for the gift. - * @param isPrepaidUpgrade True, if the message is about prepaid upgrade of the gift by another user instead of actual receiving of a new gift. - */ - public PushMessageContentGift(long starCount, boolean isPrepaidUpgrade) { - this.starCount = starCount; - this.isPrepaidUpgrade = isPrepaidUpgrade; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1721859295; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with an upgraded gift. - */ - public static class PushMessageContentUpgradedGift extends PushMessageContent { - /** - * True, if the gift was obtained by upgrading of a previously received gift; otherwise, if isPrepaidUpgrade == false, then this is a transferred or resold gift. - */ - public boolean isUpgrade; - /** - * True, if the message is about completion of prepaid upgrade of the gift instead of actual receiving of a new gift. - */ - public boolean isPrepaidUpgrade; - - /** - * A message with an upgraded gift. - */ - public PushMessageContentUpgradedGift() { - } - - /** - * A message with an upgraded gift. - * - * @param isUpgrade True, if the gift was obtained by upgrading of a previously received gift; otherwise, if isPrepaidUpgrade == false, then this is a transferred or resold gift. - * @param isPrepaidUpgrade True, if the message is about completion of prepaid upgrade of the gift instead of actual receiving of a new gift. - */ - public PushMessageContentUpgradedGift(boolean isUpgrade, boolean isPrepaidUpgrade) { - this.isUpgrade = isUpgrade; - this.isPrepaidUpgrade = isPrepaidUpgrade; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1287092226; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A screenshot of a message in the chat has been taken. - */ - public static class PushMessageContentScreenshotTaken extends PushMessageContent { - - /** - * A screenshot of a message in the chat has been taken. - */ - public PushMessageContentScreenshotTaken() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 214245369; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a sticker. - */ - public static class PushMessageContentSticker extends PushMessageContent { - /** - * Message content; may be null. - */ - @Nullable public Sticker sticker; - /** - * Emoji corresponding to the sticker; may be empty. - */ - public String emoji; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A message with a sticker. - */ - public PushMessageContentSticker() { - } - - /** - * A message with a sticker. - * - * @param sticker Message content; may be null. - * @param emoji Emoji corresponding to the sticker; may be empty. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentSticker(Sticker sticker, String emoji, boolean isPinned) { - this.sticker = sticker; - this.emoji = emoji; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1553513939; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a story. - */ - public static class PushMessageContentStory extends PushMessageContent { - /** - * True, if the user was mentioned in the story. - */ - public boolean isMention; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A message with a story. - */ - public PushMessageContentStory() { - } - - /** - * A message with a story. - * - * @param isMention True, if the user was mentioned in the story. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentStory(boolean isMention, boolean isPinned) { - this.isMention = isMention; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 599622223; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A text message. - */ - public static class PushMessageContentText extends PushMessageContent { - /** - * Message text. - */ - public String text; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A text message. - */ - public PushMessageContentText() { - } - - /** - * A text message. - * - * @param text Message text. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentText(String text, boolean isPinned) { - this.text = text; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 274587305; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a checklist. - */ - public static class PushMessageContentChecklist extends PushMessageContent { - /** - * Checklist title. - */ - public String title; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A message with a checklist. - */ - public PushMessageContentChecklist() { - } - - /** - * A message with a checklist. - * - * @param title Checklist title. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentChecklist(String title, boolean isPinned) { - this.title = title; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 212274252; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A video message. - */ - public static class PushMessageContentVideo extends PushMessageContent { - /** - * Message content; may be null. - */ - @Nullable public Video video; - /** - * Video caption. - */ - public String caption; - /** - * True, if the video is secret. - */ - public boolean isSecret; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A video message. - */ - public PushMessageContentVideo() { - } - - /** - * A video message. - * - * @param video Message content; may be null. - * @param caption Video caption. - * @param isSecret True, if the video is secret. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentVideo(Video video, String caption, boolean isSecret, boolean isPinned) { - this.video = video; - this.caption = caption; - this.isSecret = isSecret; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 310038831; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A video note message. - */ - public static class PushMessageContentVideoNote extends PushMessageContent { - /** - * Message content; may be null. - */ - @Nullable public VideoNote videoNote; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A video note message. - */ - public PushMessageContentVideoNote() { - } - - /** - * A video note message. - * - * @param videoNote Message content; may be null. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentVideoNote(VideoNote videoNote, boolean isPinned) { - this.videoNote = videoNote; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1122764417; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A voice note message. - */ - public static class PushMessageContentVoiceNote extends PushMessageContent { - /** - * Message content; may be null. - */ - @Nullable public VoiceNote voiceNote; - /** - * True, if the message is a pinned message with the specified content. - */ - public boolean isPinned; - - /** - * A voice note message. - */ - public PushMessageContentVoiceNote() { - } - - /** - * A voice note message. - * - * @param voiceNote Message content; may be null. - * @param isPinned True, if the message is a pinned message with the specified content. - */ - public PushMessageContentVoiceNote(VoiceNote voiceNote, boolean isPinned) { - this.voiceNote = voiceNote; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 88910987; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A newly created basic group. - */ - public static class PushMessageContentBasicGroupChatCreate extends PushMessageContent { - - /** - * A newly created basic group. - */ - public PushMessageContentBasicGroupChatCreate() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2114855172; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A video chat or live stream was started. - */ - public static class PushMessageContentVideoChatStarted extends PushMessageContent { - - /** - * A video chat or live stream was started. - */ - public PushMessageContentVideoChatStarted() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -566547393; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A video chat or live stream has ended. - */ - public static class PushMessageContentVideoChatEnded extends PushMessageContent { - - /** - * A video chat or live stream has ended. - */ - public PushMessageContentVideoChatEnded() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1250265885; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An invitation of participants to a video chat or live stream. - */ - public static class PushMessageContentInviteVideoChatParticipants extends PushMessageContent { - /** - * True, if the current user was invited to the video chat or the live stream. - */ - public boolean isCurrentUser; - - /** - * An invitation of participants to a video chat or live stream. - */ - public PushMessageContentInviteVideoChatParticipants() { - } - - /** - * An invitation of participants to a video chat or live stream. - * - * @param isCurrentUser True, if the current user was invited to the video chat or the live stream. - */ - public PushMessageContentInviteVideoChatParticipants(boolean isCurrentUser) { - this.isCurrentUser = isCurrentUser; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 517620365; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * New chat members were invited to a group. - */ - public static class PushMessageContentChatAddMembers extends PushMessageContent { - /** - * Name of the added member. - */ - public String memberName; - /** - * True, if the current user was added to the group. - */ - public boolean isCurrentUser; - /** - * True, if the user has returned to the group themselves. - */ - public boolean isReturned; - - /** - * New chat members were invited to a group. - */ - public PushMessageContentChatAddMembers() { - } - - /** - * New chat members were invited to a group. - * - * @param memberName Name of the added member. - * @param isCurrentUser True, if the current user was added to the group. - * @param isReturned True, if the user has returned to the group themselves. - */ - public PushMessageContentChatAddMembers(String memberName, boolean isCurrentUser, boolean isReturned) { - this.memberName = memberName; - this.isCurrentUser = isCurrentUser; - this.isReturned = isReturned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1087145158; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat photo was edited. - */ - public static class PushMessageContentChatChangePhoto extends PushMessageContent { - - /** - * A chat photo was edited. - */ - public PushMessageContentChatChangePhoto() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1114222051; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat title was edited. - */ - public static class PushMessageContentChatChangeTitle extends PushMessageContent { - /** - * New chat title. - */ - public String title; - - /** - * A chat title was edited. - */ - public PushMessageContentChatChangeTitle() { - } - - /** - * A chat title was edited. - * - * @param title New chat title. - */ - public PushMessageContentChatChangeTitle(String title) { - this.title = title; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1964902749; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat background was edited. - */ - public static class PushMessageContentChatSetBackground extends PushMessageContent { - /** - * True, if the set background is the same as the background of the current user. - */ - public boolean isSame; - - /** - * A chat background was edited. - */ - public PushMessageContentChatSetBackground() { - } - - /** - * A chat background was edited. - * - * @param isSame True, if the set background is the same as the background of the current user. - */ - public PushMessageContentChatSetBackground(boolean isSame) { - this.isSame = isSame; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1490331933; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat theme was edited. - */ - public static class PushMessageContentChatSetTheme extends PushMessageContent { - /** - * If non-empty, human-readable name of the new theme. Otherwise, the chat theme was reset to the default one. - */ - public String name; - - /** - * A chat theme was edited. - */ - public PushMessageContentChatSetTheme() { - } - - /** - * A chat theme was edited. - * - * @param name If non-empty, human-readable name of the new theme. Otherwise, the chat theme was reset to the default one. - */ - public PushMessageContentChatSetTheme(String name) { - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1605251024; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat member was deleted. - */ - public static class PushMessageContentChatDeleteMember extends PushMessageContent { - /** - * Name of the deleted member. - */ - public String memberName; - /** - * True, if the current user was deleted from the group. - */ - public boolean isCurrentUser; - /** - * True, if the user has left the group themselves. - */ - public boolean isLeft; - - /** - * A chat member was deleted. - */ - public PushMessageContentChatDeleteMember() { - } - - /** - * A chat member was deleted. - * - * @param memberName Name of the deleted member. - * @param isCurrentUser True, if the current user was deleted from the group. - * @param isLeft True, if the user has left the group themselves. - */ - public PushMessageContentChatDeleteMember(String memberName, boolean isCurrentUser, boolean isLeft) { - this.memberName = memberName; - this.isCurrentUser = isCurrentUser; - this.isLeft = isLeft; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 598714783; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new member joined the chat via an invite link. - */ - public static class PushMessageContentChatJoinByLink extends PushMessageContent { - - /** - * A new member joined the chat via an invite link. - */ - public PushMessageContentChatJoinByLink() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1553719113; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new member was accepted to the chat by an administrator. - */ - public static class PushMessageContentChatJoinByRequest extends PushMessageContent { - - /** - * A new member was accepted to the chat by an administrator. - */ - public PushMessageContentChatJoinByRequest() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -205823627; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new recurring payment was made by the current user. - */ - public static class PushMessageContentRecurringPayment extends PushMessageContent { - /** - * The paid amount. - */ - public String amount; - - /** - * A new recurring payment was made by the current user. - */ - public PushMessageContentRecurringPayment() { - } - - /** - * A new recurring payment was made by the current user. - * - * @param amount The paid amount. - */ - public PushMessageContentRecurringPayment(String amount) { - this.amount = amount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1619211802; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A profile photo was suggested to the user. - */ - public static class PushMessageContentSuggestProfilePhoto extends PushMessageContent { - - /** - * A profile photo was suggested to the user. - */ - public PushMessageContentSuggestProfilePhoto() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2104225963; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A birthdate was suggested to be set. - */ - public static class PushMessageContentSuggestBirthdate extends PushMessageContent { - - /** - * A birthdate was suggested to be set. - */ - public PushMessageContentSuggestBirthdate() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -899891750; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A user in the chat came within proximity alert range from the current user. - */ - public static class PushMessageContentProximityAlertTriggered extends PushMessageContent { - /** - * The distance to the user. - */ - public int distance; - - /** - * A user in the chat came within proximity alert range from the current user. - */ - public PushMessageContentProximityAlertTriggered() { - } - - /** - * A user in the chat came within proximity alert range from the current user. - * - * @param distance The distance to the user. - */ - public PushMessageContentProximityAlertTriggered(int distance) { - this.distance = distance; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -264601594; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Some tasks were added to a checklist. - */ - public static class PushMessageContentChecklistTasksAdded extends PushMessageContent { - /** - * Number of added tasks. - */ - public int taskCount; - - /** - * Some tasks were added to a checklist. - */ - public PushMessageContentChecklistTasksAdded() { - } - - /** - * Some tasks were added to a checklist. - * - * @param taskCount Number of added tasks. - */ - public PushMessageContentChecklistTasksAdded(int taskCount) { - this.taskCount = taskCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2141595022; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Some tasks from a checklist were marked as done or not done. - */ - public static class PushMessageContentChecklistTasksDone extends PushMessageContent { - /** - * Number of changed tasks. - */ - public int taskCount; - - /** - * Some tasks from a checklist were marked as done or not done. - */ - public PushMessageContentChecklistTasksDone() { - } - - /** - * Some tasks from a checklist were marked as done or not done. - * - * @param taskCount Number of changed tasks. - */ - public PushMessageContentChecklistTasksDone(int taskCount) { - this.taskCount = taskCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1187614554; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A forwarded messages. - */ - public static class PushMessageContentMessageForwards extends PushMessageContent { - /** - * Number of forwarded messages. - */ - public int totalCount; - - /** - * A forwarded messages. - */ - public PushMessageContentMessageForwards() { - } - - /** - * A forwarded messages. - * - * @param totalCount Number of forwarded messages. - */ - public PushMessageContentMessageForwards(int totalCount) { - this.totalCount = totalCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1913083876; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A media album. - */ - public static class PushMessageContentMediaAlbum extends PushMessageContent { - /** - * Number of messages in the album. - */ - public int totalCount; - /** - * True, if the album has at least one photo. - */ - public boolean hasPhotos; - /** - * True, if the album has at least one video file. - */ - public boolean hasVideos; - /** - * True, if the album has at least one audio file. - */ - public boolean hasAudios; - /** - * True, if the album has at least one document. - */ - public boolean hasDocuments; - - /** - * A media album. - */ - public PushMessageContentMediaAlbum() { - } - - /** - * A media album. - * - * @param totalCount Number of messages in the album. - * @param hasPhotos True, if the album has at least one photo. - * @param hasVideos True, if the album has at least one video file. - * @param hasAudios True, if the album has at least one audio file. - * @param hasDocuments True, if the album has at least one document. - */ - public PushMessageContentMediaAlbum(int totalCount, boolean hasPhotos, boolean hasVideos, boolean hasAudios, boolean hasDocuments) { - this.totalCount = totalCount; - this.hasPhotos = hasPhotos; - this.hasVideos = hasVideos; - this.hasAudios = hasAudios; - this.hasDocuments = hasDocuments; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -748426897; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a globally unique push receiver identifier, which can be used to identify which account has received a push notification. - */ - public static class PushReceiverId extends Object { - /** - * The globally unique identifier of push notification subscription. - */ - public long id; - - /** - * Contains a globally unique push receiver identifier, which can be used to identify which account has received a push notification. - */ - public PushReceiverId() { - } - - /** - * Contains a globally unique push receiver identifier, which can be used to identify which account has received a push notification. - * - * @param id The globally unique identifier of push notification subscription. - */ - public PushReceiverId(long id) { - this.id = id; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 371056428; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a message that can be used for quick reply. - */ - public static class QuickReplyMessage extends Object { - /** - * Unique message identifier among all quick replies. - */ - public long id; - /** - * The sending state of the message; may be null if the message isn't being sent and didn't fail to be sent. - */ - @Nullable public MessageSendingState sendingState; - /** - * True, if the message can be edited. - */ - public boolean canBeEdited; - /** - * The identifier of the quick reply message to which the message replies; 0 if none. - */ - public long replyToMessageId; - /** - * If non-zero, the user identifier of the bot through which this message was sent. - */ - public long viaBotUserId; - /** - * Unique identifier of an album this message belongs to; 0 if none. Only audios, documents, photos and videos can be grouped together in albums. - */ - public long mediaAlbumId; - /** - * Content of the message. - */ - public MessageContent content; - /** - * Inline keyboard reply markup for the message; may be null if none. - */ - @Nullable public ReplyMarkup replyMarkup; - - /** - * Describes a message that can be used for quick reply. - */ - public QuickReplyMessage() { - } - - /** - * Describes a message that can be used for quick reply. - * - * @param id Unique message identifier among all quick replies. - * @param sendingState The sending state of the message; may be null if the message isn't being sent and didn't fail to be sent. - * @param canBeEdited True, if the message can be edited. - * @param replyToMessageId The identifier of the quick reply message to which the message replies; 0 if none. - * @param viaBotUserId If non-zero, the user identifier of the bot through which this message was sent. - * @param mediaAlbumId Unique identifier of an album this message belongs to; 0 if none. Only audios, documents, photos and videos can be grouped together in albums. - * @param content Content of the message. - * @param replyMarkup Inline keyboard reply markup for the message; may be null if none. - */ - public QuickReplyMessage(long id, MessageSendingState sendingState, boolean canBeEdited, long replyToMessageId, long viaBotUserId, long mediaAlbumId, MessageContent content, ReplyMarkup replyMarkup) { - this.id = id; - this.sendingState = sendingState; - this.canBeEdited = canBeEdited; - this.replyToMessageId = replyToMessageId; - this.viaBotUserId = viaBotUserId; - this.mediaAlbumId = mediaAlbumId; - this.content = content; - this.replyMarkup = replyMarkup; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1090965757; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of quick reply messages. - */ - public static class QuickReplyMessages extends Object { - /** - * List of quick reply messages; messages may be null. - */ - public QuickReplyMessage[] messages; - - /** - * Contains a list of quick reply messages. - */ - public QuickReplyMessages() { - } - - /** - * Contains a list of quick reply messages. - * - * @param messages List of quick reply messages; messages may be null. - */ - public QuickReplyMessages(QuickReplyMessage[] messages) { - this.messages = messages; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 743214375; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a shortcut that can be used for a quick reply. - */ - public static class QuickReplyShortcut extends Object { - /** - * Unique shortcut identifier. - */ - public int id; - /** - * The name of the shortcut that can be used to use the shortcut. - */ - public String name; - /** - * The first shortcut message. - */ - public QuickReplyMessage firstMessage; - /** - * The total number of messages in the shortcut. - */ - public int messageCount; - - /** - * Describes a shortcut that can be used for a quick reply. - */ - public QuickReplyShortcut() { - } - - /** - * Describes a shortcut that can be used for a quick reply. - * - * @param id Unique shortcut identifier. - * @param name The name of the shortcut that can be used to use the shortcut. - * @param firstMessage The first shortcut message. - * @param messageCount The total number of messages in the shortcut. - */ - public QuickReplyShortcut(int id, String name, QuickReplyMessage firstMessage, int messageCount) { - this.id = id; - this.name = name; - this.firstMessage = firstMessage; - this.messageCount = messageCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1107453291; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about notification settings for reactions. - */ - public static class ReactionNotificationSettings extends Object { - /** - * Source of message reactions for which notifications are shown. - */ - public ReactionNotificationSource messageReactionSource; - /** - * Source of story reactions for which notifications are shown. - */ - public ReactionNotificationSource storyReactionSource; - /** - * Identifier of the notification sound to be played; 0 if sound is disabled. - */ - public long soundId; - /** - * True, if reaction sender and emoji must be displayed in notifications. - */ - public boolean showPreview; - - /** - * Contains information about notification settings for reactions. - */ - public ReactionNotificationSettings() { - } - - /** - * Contains information about notification settings for reactions. - * - * @param messageReactionSource Source of message reactions for which notifications are shown. - * @param storyReactionSource Source of story reactions for which notifications are shown. - * @param soundId Identifier of the notification sound to be played; 0 if sound is disabled. - * @param showPreview True, if reaction sender and emoji must be displayed in notifications. - */ - public ReactionNotificationSettings(ReactionNotificationSource messageReactionSource, ReactionNotificationSource storyReactionSource, long soundId, boolean showPreview) { - this.messageReactionSource = messageReactionSource; - this.storyReactionSource = storyReactionSource; - this.soundId = soundId; - this.showPreview = showPreview; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 733017684; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes sources of reactions for which notifications will be shown. - */ - public abstract static class ReactionNotificationSource extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ReactionNotificationSourceNone.CONSTRUCTOR, - ReactionNotificationSourceContacts.CONSTRUCTOR, - ReactionNotificationSourceAll.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ReactionNotificationSource() { - } - } - - /** - * Notifications for reactions are disabled. - */ - public static class ReactionNotificationSourceNone extends ReactionNotificationSource { - - /** - * Notifications for reactions are disabled. - */ - public ReactionNotificationSourceNone() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 366374940; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Notifications for reactions are shown only for reactions from contacts. - */ - public static class ReactionNotificationSourceContacts extends ReactionNotificationSource { - - /** - * Notifications for reactions are shown only for reactions from contacts. - */ - public ReactionNotificationSourceContacts() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 555501621; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Notifications for reactions are shown for all reactions. - */ - public static class ReactionNotificationSourceAll extends ReactionNotificationSource { - - /** - * Notifications for reactions are shown for all reactions. - */ - public ReactionNotificationSourceAll() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1241689234; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of message reaction. - */ - public abstract static class ReactionType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ReactionTypeEmoji.CONSTRUCTOR, - ReactionTypeCustomEmoji.CONSTRUCTOR, - ReactionTypePaid.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ReactionType() { - } - } - - /** - * A reaction with an emoji. - */ - public static class ReactionTypeEmoji extends ReactionType { - /** - * Text representation of the reaction. - */ - public String emoji; - - /** - * A reaction with an emoji. - */ - public ReactionTypeEmoji() { - } - - /** - * A reaction with an emoji. - * - * @param emoji Text representation of the reaction. - */ - public ReactionTypeEmoji(String emoji) { - this.emoji = emoji; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1942084920; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A reaction with a custom emoji. - */ - public static class ReactionTypeCustomEmoji extends ReactionType { - /** - * Unique identifier of the custom emoji. - */ - public long customEmojiId; - - /** - * A reaction with a custom emoji. - */ - public ReactionTypeCustomEmoji() { - } - - /** - * A reaction with a custom emoji. - * - * @param customEmojiId Unique identifier of the custom emoji. - */ - public ReactionTypeCustomEmoji(long customEmojiId) { - this.customEmojiId = customEmojiId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -989117709; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The paid reaction in a channel chat. - */ - public static class ReactionTypePaid extends ReactionType { - - /** - * The paid reaction in a channel chat. - */ - public ReactionTypePaid() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 436294381; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes why the current user can't add reactions to the message, despite some other users can. - */ - public abstract static class ReactionUnavailabilityReason extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ReactionUnavailabilityReasonAnonymousAdministrator.CONSTRUCTOR, - ReactionUnavailabilityReasonGuest.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ReactionUnavailabilityReason() { - } - } - - /** - * The user is an anonymous administrator in the supergroup, but isn't a creator of it, so they can't vote on behalf of the supergroup. - */ - public static class ReactionUnavailabilityReasonAnonymousAdministrator extends ReactionUnavailabilityReason { - - /** - * The user is an anonymous administrator in the supergroup, but isn't a creator of it, so they can't vote on behalf of the supergroup. - */ - public ReactionUnavailabilityReasonAnonymousAdministrator() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -499612677; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user isn't a member of the supergroup and can't send messages and reactions there without joining. - */ - public static class ReactionUnavailabilityReasonGuest extends ReactionUnavailabilityReason { - - /** - * The user isn't a member of the supergroup and can't send messages and reactions there without joining. - */ - public ReactionUnavailabilityReasonGuest() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1357861444; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains privacy settings for message read date in private chats. Read dates are always shown to the users that can see online status of the current user regardless of this setting. - */ - public static class ReadDatePrivacySettings extends Object { - /** - * True, if message read date is shown to other users in private chats. If false and the current user isn't a Telegram Premium user, then they will not be able to see other's message read date. - */ - public boolean showReadDate; - - /** - * Contains privacy settings for message read date in private chats. Read dates are always shown to the users that can see online status of the current user regardless of this setting. - */ - public ReadDatePrivacySettings() { - } - - /** - * Contains privacy settings for message read date in private chats. Read dates are always shown to the users that can see online status of the current user regardless of this setting. - * - * @param showReadDate True, if message read date is shown to other users in private chats. If false and the current user isn't a Telegram Premium user, then they will not be able to see other's message read date. - */ - public ReadDatePrivacySettings(boolean showReadDate) { - this.showReadDate = showReadDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1654842920; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a gift received by a user or a chat. - */ - public static class ReceivedGift extends Object { - /** - * Unique identifier of the received gift for the current user; only for the receiver of the gift. - */ - public String receivedGiftId; - /** - * Identifier of a user or a chat that sent the gift; may be null if unknown. - */ - @Nullable public MessageSender senderId; - /** - * Message added to the gift. - */ - public FormattedText text; - /** - * Unique number of the gift among gifts upgraded from the same gift after upgrade; 0 if yet unassigned. - */ - public int uniqueGiftNumber; - /** - * True, if the sender and gift text are shown only to the gift receiver; otherwise, everyone are able to see them. - */ - public boolean isPrivate; - /** - * True, if the gift is displayed on the chat's profile page; only for the receiver of the gift. - */ - public boolean isSaved; - /** - * True, if the gift is pinned to the top of the chat's profile page. - */ - public boolean isPinned; - /** - * True, if the gift is a regular gift that can be upgraded to a unique gift; only for the receiver of the gift. - */ - public boolean canBeUpgraded; - /** - * True, if the gift is an upgraded gift that can be transferred to another owner; only for the receiver of the gift. - */ - public boolean canBeTransferred; - /** - * True, if the gift was refunded and isn't available anymore. - */ - public boolean wasRefunded; - /** - * Point in time (Unix timestamp) when the gift was sent. - */ - public int date; - /** - * The gift. - */ - public SentGift gift; - /** - * Identifiers of collections to which the gift is added; only for the receiver of the gift. - */ - public int[] collectionIds; - /** - * Number of Telegram Stars that can be claimed by the receiver instead of the regular gift; 0 if the gift can't be sold by the current user. - */ - public long sellStarCount; - /** - * Number of Telegram Stars that were paid by the sender for the ability to upgrade the gift. - */ - public long prepaidUpgradeStarCount; - /** - * True, if the upgrade was bought after the gift was sent. In this case, prepaid upgrade cost must not be added to the gift cost. - */ - public boolean isUpgradeSeparate; - /** - * Number of Telegram Stars that must be paid to transfer the upgraded gift; only for the receiver of the gift. - */ - public long transferStarCount; - /** - * Number of Telegram Stars that must be paid to drop original details of the upgraded gift; 0 if not available; only for the receiver of the gift. - */ - public long dropOriginalDetailsStarCount; - /** - * Point in time (Unix timestamp) when the gift can be transferred to another owner; can be in the past; 0 if the gift can be transferred immediately or transfer isn't possible; only for the receiver of the gift. - */ - public int nextTransferDate; - /** - * Point in time (Unix timestamp) when the gift can be resold to another user; can be in the past; 0 if the gift can't be resold; only for the receiver of the gift. - */ - public int nextResaleDate; - /** - * Point in time (Unix timestamp) when the upgraded gift can be transferred to the TON blockchain as an NFT; can be in the past; 0 if NFT export isn't possible; only for the receiver of the gift. - */ - public int exportDate; - /** - * If non-empty, then the user can pay for an upgrade of the gift using buyGiftUpgrade. - */ - public String prepaidUpgradeHash; - /** - * Point in time (Unix timestamp) when the gift can be used to craft another gift can be in the past; only for the receiver of the gift. - */ - public int craftDate; - - /** - * Represents a gift received by a user or a chat. - */ - public ReceivedGift() { - } - - /** - * Represents a gift received by a user or a chat. - * - * @param receivedGiftId Unique identifier of the received gift for the current user; only for the receiver of the gift. - * @param senderId Identifier of a user or a chat that sent the gift; may be null if unknown. - * @param text Message added to the gift. - * @param uniqueGiftNumber Unique number of the gift among gifts upgraded from the same gift after upgrade; 0 if yet unassigned. - * @param isPrivate True, if the sender and gift text are shown only to the gift receiver; otherwise, everyone are able to see them. - * @param isSaved True, if the gift is displayed on the chat's profile page; only for the receiver of the gift. - * @param isPinned True, if the gift is pinned to the top of the chat's profile page. - * @param canBeUpgraded True, if the gift is a regular gift that can be upgraded to a unique gift; only for the receiver of the gift. - * @param canBeTransferred True, if the gift is an upgraded gift that can be transferred to another owner; only for the receiver of the gift. - * @param wasRefunded True, if the gift was refunded and isn't available anymore. - * @param date Point in time (Unix timestamp) when the gift was sent. - * @param gift The gift. - * @param collectionIds Identifiers of collections to which the gift is added; only for the receiver of the gift. - * @param sellStarCount Number of Telegram Stars that can be claimed by the receiver instead of the regular gift; 0 if the gift can't be sold by the current user. - * @param prepaidUpgradeStarCount Number of Telegram Stars that were paid by the sender for the ability to upgrade the gift. - * @param isUpgradeSeparate True, if the upgrade was bought after the gift was sent. In this case, prepaid upgrade cost must not be added to the gift cost. - * @param transferStarCount Number of Telegram Stars that must be paid to transfer the upgraded gift; only for the receiver of the gift. - * @param dropOriginalDetailsStarCount Number of Telegram Stars that must be paid to drop original details of the upgraded gift; 0 if not available; only for the receiver of the gift. - * @param nextTransferDate Point in time (Unix timestamp) when the gift can be transferred to another owner; can be in the past; 0 if the gift can be transferred immediately or transfer isn't possible; only for the receiver of the gift. - * @param nextResaleDate Point in time (Unix timestamp) when the gift can be resold to another user; can be in the past; 0 if the gift can't be resold; only for the receiver of the gift. - * @param exportDate Point in time (Unix timestamp) when the upgraded gift can be transferred to the TON blockchain as an NFT; can be in the past; 0 if NFT export isn't possible; only for the receiver of the gift. - * @param prepaidUpgradeHash If non-empty, then the user can pay for an upgrade of the gift using buyGiftUpgrade. - * @param craftDate Point in time (Unix timestamp) when the gift can be used to craft another gift can be in the past; only for the receiver of the gift. - */ - public ReceivedGift(String receivedGiftId, MessageSender senderId, FormattedText text, int uniqueGiftNumber, boolean isPrivate, boolean isSaved, boolean isPinned, boolean canBeUpgraded, boolean canBeTransferred, boolean wasRefunded, int date, SentGift gift, int[] collectionIds, long sellStarCount, long prepaidUpgradeStarCount, boolean isUpgradeSeparate, long transferStarCount, long dropOriginalDetailsStarCount, int nextTransferDate, int nextResaleDate, int exportDate, String prepaidUpgradeHash, int craftDate) { - this.receivedGiftId = receivedGiftId; - this.senderId = senderId; - this.text = text; - this.uniqueGiftNumber = uniqueGiftNumber; - this.isPrivate = isPrivate; - this.isSaved = isSaved; - this.isPinned = isPinned; - this.canBeUpgraded = canBeUpgraded; - this.canBeTransferred = canBeTransferred; - this.wasRefunded = wasRefunded; - this.date = date; - this.gift = gift; - this.collectionIds = collectionIds; - this.sellStarCount = sellStarCount; - this.prepaidUpgradeStarCount = prepaidUpgradeStarCount; - this.isUpgradeSeparate = isUpgradeSeparate; - this.transferStarCount = transferStarCount; - this.dropOriginalDetailsStarCount = dropOriginalDetailsStarCount; - this.nextTransferDate = nextTransferDate; - this.nextResaleDate = nextResaleDate; - this.exportDate = exportDate; - this.prepaidUpgradeHash = prepaidUpgradeHash; - this.craftDate = craftDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -389770324; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of gifts received by a user or a chat. - */ - public static class ReceivedGifts extends Object { - /** - * The total number of received gifts. - */ - public int totalCount; - /** - * The list of gifts. - */ - public ReceivedGift[] gifts; - /** - * True, if notifications about new gifts of the owner are enabled. - */ - public boolean areNotificationsEnabled; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Represents a list of gifts received by a user or a chat. - */ - public ReceivedGifts() { - } - - /** - * Represents a list of gifts received by a user or a chat. - * - * @param totalCount The total number of received gifts. - * @param gifts The list of gifts. - * @param areNotificationsEnabled True, if notifications about new gifts of the owner are enabled. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public ReceivedGifts(int totalCount, ReceivedGift[] gifts, boolean areNotificationsEnabled, String nextOffset) { - this.totalCount = totalCount; - this.gifts = gifts; - this.areNotificationsEnabled = areNotificationsEnabled; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1237114400; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a recommended chat folder. - */ - public static class RecommendedChatFolder extends Object { - /** - * The chat folder. - */ - public ChatFolder folder; - /** - * Chat folder description. - */ - public String description; - - /** - * Describes a recommended chat folder. - */ - public RecommendedChatFolder() { - } - - /** - * Describes a recommended chat folder. - * - * @param folder The chat folder. - * @param description Chat folder description. - */ - public RecommendedChatFolder(ChatFolder folder, String description) { - this.folder = folder; - this.description = description; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2116569930; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of recommended chat folders. - */ - public static class RecommendedChatFolders extends Object { - /** - * List of recommended chat folders. - */ - public RecommendedChatFolder[] chatFolders; - - /** - * Contains a list of recommended chat folders. - */ - public RecommendedChatFolders() { - } - - /** - * Contains a list of recommended chat folders. - * - * @param chatFolders List of recommended chat folders. - */ - public RecommendedChatFolders(RecommendedChatFolder[] chatFolders) { - this.chatFolders = chatFolders; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -739217656; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about the current recovery email address. - */ - public static class RecoveryEmailAddress extends Object { - /** - * Recovery email address. - */ - public String recoveryEmailAddress; - - /** - * Contains information about the current recovery email address. - */ - public RecoveryEmailAddress() { - } - - /** - * Contains information about the current recovery email address. - * - * @param recoveryEmailAddress Recovery email address. - */ - public RecoveryEmailAddress(String recoveryEmailAddress) { - this.recoveryEmailAddress = recoveryEmailAddress; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1290526187; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a remote file. - */ - public static class RemoteFile extends Object { - /** - * Remote file identifier; may be empty. Can be used by the current user across application restarts or even from other devices. Uniquely identifies a file, but a file can have a lot of different valid identifiers. If the identifier starts with "http://" or "https://", it represents the HTTP URL of the file. TDLib is currently unable to download files if only their URL is known. If downloadFile/addFileToDownloads is called on such a file or if it is sent to a secret chat, TDLib starts a file generation process by sending updateFileGenerationStart to the application with the HTTP URL in the originalPath and "#url#" as the conversion string. Application must generate the file by downloading it to the specified location. - */ - public String id; - /** - * Unique file identifier; may be empty if unknown. The unique file identifier which is the same for the same file even for different users and is persistent over time. - */ - public String uniqueId; - /** - * True, if the file is currently being uploaded (or a remote copy is being generated by some other means). - */ - public boolean isUploadingActive; - /** - * True, if a remote copy is fully available. - */ - public boolean isUploadingCompleted; - /** - * Size of the remote available part of the file, in bytes; 0 if unknown. - */ - public long uploadedSize; - - /** - * Represents a remote file. - */ - public RemoteFile() { - } - - /** - * Represents a remote file. - * - * @param id Remote file identifier; may be empty. Can be used by the current user across application restarts or even from other devices. Uniquely identifies a file, but a file can have a lot of different valid identifiers. If the identifier starts with "http://" or "https://", it represents the HTTP URL of the file. TDLib is currently unable to download files if only their URL is known. If downloadFile/addFileToDownloads is called on such a file or if it is sent to a secret chat, TDLib starts a file generation process by sending updateFileGenerationStart to the application with the HTTP URL in the originalPath and "#url#" as the conversion string. Application must generate the file by downloading it to the specified location. - * @param uniqueId Unique file identifier; may be empty if unknown. The unique file identifier which is the same for the same file even for different users and is persistent over time. - * @param isUploadingActive True, if the file is currently being uploaded (or a remote copy is being generated by some other means). - * @param isUploadingCompleted True, if a remote copy is fully available. - * @param uploadedSize Size of the remote available part of the file, in bytes; 0 if unknown. - */ - public RemoteFile(String id, String uniqueId, boolean isUploadingActive, boolean isUploadingCompleted, long uploadedSize) { - this.id = id; - this.uniqueId = uniqueId; - this.isUploadingActive = isUploadingActive; - this.isUploadingCompleted = isUploadingCompleted; - this.uploadedSize = uploadedSize; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 747731030; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains a description of a custom keyboard and actions that can be done with it to quickly reply to bots. - */ - public abstract static class ReplyMarkup extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ReplyMarkupRemoveKeyboard.CONSTRUCTOR, - ReplyMarkupForceReply.CONSTRUCTOR, - ReplyMarkupShowKeyboard.CONSTRUCTOR, - ReplyMarkupInlineKeyboard.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ReplyMarkup() { - } - } - - /** - * Instructs application to remove the keyboard once this message has been received. This kind of keyboard can't be received in an incoming message; instead, updateChatReplyMarkup with replyMarkupMessage == null will be sent. - */ - public static class ReplyMarkupRemoveKeyboard extends ReplyMarkup { - /** - * True, if the keyboard is removed only for the mentioned users or the target user of a reply. - */ - public boolean isPersonal; - - /** - * Instructs application to remove the keyboard once this message has been received. This kind of keyboard can't be received in an incoming message; instead, updateChatReplyMarkup with replyMarkupMessage == null will be sent. - */ - public ReplyMarkupRemoveKeyboard() { - } - - /** - * Instructs application to remove the keyboard once this message has been received. This kind of keyboard can't be received in an incoming message; instead, updateChatReplyMarkup with replyMarkupMessage == null will be sent. - * - * @param isPersonal True, if the keyboard is removed only for the mentioned users or the target user of a reply. - */ - public ReplyMarkupRemoveKeyboard(boolean isPersonal) { - this.isPersonal = isPersonal; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -691252879; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Instructs application to force a reply to this message. - */ - public static class ReplyMarkupForceReply extends ReplyMarkup { - /** - * True, if a forced reply must automatically be shown to the current user. For outgoing messages, specify true to show the forced reply only for the mentioned users and for the target user of a reply. - */ - public boolean isPersonal; - /** - * If non-empty, the placeholder to be shown in the input field when the reply is active; 0-64 characters. - */ - public String inputFieldPlaceholder; - - /** - * Instructs application to force a reply to this message. - */ - public ReplyMarkupForceReply() { - } - - /** - * Instructs application to force a reply to this message. - * - * @param isPersonal True, if a forced reply must automatically be shown to the current user. For outgoing messages, specify true to show the forced reply only for the mentioned users and for the target user of a reply. - * @param inputFieldPlaceholder If non-empty, the placeholder to be shown in the input field when the reply is active; 0-64 characters. - */ - public ReplyMarkupForceReply(boolean isPersonal, String inputFieldPlaceholder) { - this.isPersonal = isPersonal; - this.inputFieldPlaceholder = inputFieldPlaceholder; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1101461919; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a custom keyboard layout to quickly reply to bots. - */ - public static class ReplyMarkupShowKeyboard extends ReplyMarkup { - /** - * A list of rows of bot keyboard buttons. - */ - public KeyboardButton[][] rows; - /** - * True, if the keyboard is expected to always be shown when the ordinary keyboard is hidden. - */ - public boolean isPersistent; - /** - * True, if the application needs to resize the keyboard vertically. - */ - public boolean resizeKeyboard; - /** - * True, if the application needs to hide the keyboard after use. - */ - public boolean oneTime; - /** - * True, if the keyboard must automatically be shown to the current user. For outgoing messages, specify true to show the keyboard only for the mentioned users and for the target user of a reply. - */ - public boolean isPersonal; - /** - * If non-empty, the placeholder to be shown in the input field when the keyboard is active; 0-64 characters. - */ - public String inputFieldPlaceholder; - - /** - * Contains a custom keyboard layout to quickly reply to bots. - */ - public ReplyMarkupShowKeyboard() { - } - - /** - * Contains a custom keyboard layout to quickly reply to bots. - * - * @param rows A list of rows of bot keyboard buttons. - * @param isPersistent True, if the keyboard is expected to always be shown when the ordinary keyboard is hidden. - * @param resizeKeyboard True, if the application needs to resize the keyboard vertically. - * @param oneTime True, if the application needs to hide the keyboard after use. - * @param isPersonal True, if the keyboard must automatically be shown to the current user. For outgoing messages, specify true to show the keyboard only for the mentioned users and for the target user of a reply. - * @param inputFieldPlaceholder If non-empty, the placeholder to be shown in the input field when the keyboard is active; 0-64 characters. - */ - public ReplyMarkupShowKeyboard(KeyboardButton[][] rows, boolean isPersistent, boolean resizeKeyboard, boolean oneTime, boolean isPersonal, String inputFieldPlaceholder) { - this.rows = rows; - this.isPersistent = isPersistent; - this.resizeKeyboard = resizeKeyboard; - this.oneTime = oneTime; - this.isPersonal = isPersonal; - this.inputFieldPlaceholder = inputFieldPlaceholder; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -791495984; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains an inline keyboard layout. - */ - public static class ReplyMarkupInlineKeyboard extends ReplyMarkup { - /** - * A list of rows of inline keyboard buttons. - */ - public InlineKeyboardButton[][] rows; - - /** - * Contains an inline keyboard layout. - */ - public ReplyMarkupInlineKeyboard() { - } - - /** - * Contains an inline keyboard layout. - * - * @param rows A list of rows of inline keyboard buttons. - */ - public ReplyMarkupInlineKeyboard(InlineKeyboardButton[][] rows) { - this.rows = rows; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -619317658; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes result of chat report. - */ - public abstract static class ReportChatResult extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ReportChatResultOk.CONSTRUCTOR, - ReportChatResultOptionRequired.CONSTRUCTOR, - ReportChatResultTextRequired.CONSTRUCTOR, - ReportChatResultMessagesRequired.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ReportChatResult() { - } - } - - /** - * The chat was reported successfully. - */ - public static class ReportChatResultOk extends ReportChatResult { - - /** - * The chat was reported successfully. - */ - public ReportChatResultOk() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1209685373; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user must choose an option to report the chat and repeat request with the chosen option. - */ - public static class ReportChatResultOptionRequired extends ReportChatResult { - /** - * Title for the option choice. - */ - public String title; - /** - * List of available options. - */ - public ReportOption[] options; - - /** - * The user must choose an option to report the chat and repeat request with the chosen option. - */ - public ReportChatResultOptionRequired() { - } - - /** - * The user must choose an option to report the chat and repeat request with the chosen option. - * - * @param title Title for the option choice. - * @param options List of available options. - */ - public ReportChatResultOptionRequired(String title, ReportOption[] options) { - this.title = title; - this.options = options; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -881375669; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user must add additional text details to the report. - */ - public static class ReportChatResultTextRequired extends ReportChatResult { - /** - * Option identifier for the next reportChat request. - */ - public byte[] optionId; - /** - * True, if the user can skip text adding. - */ - public boolean isOptional; - - /** - * The user must add additional text details to the report. - */ - public ReportChatResultTextRequired() { - } - - /** - * The user must add additional text details to the report. - * - * @param optionId Option identifier for the next reportChat request. - * @param isOptional True, if the user can skip text adding. - */ - public ReportChatResultTextRequired(byte[] optionId, boolean isOptional) { - this.optionId = optionId; - this.isOptional = isOptional; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1949552447; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user must choose messages to report and repeat the reportChat request with the chosen messages. - */ - public static class ReportChatResultMessagesRequired extends ReportChatResult { - - /** - * The user must choose messages to report and repeat the reportChat request with the chosen messages. - */ - public ReportChatResultMessagesRequired() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 106043280; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an option to report an entity to Telegram. - */ - public static class ReportOption extends Object { - /** - * Unique identifier of the option. - */ - public byte[] id; - /** - * Text of the option. - */ - public String text; - - /** - * Describes an option to report an entity to Telegram. - */ - public ReportOption() { - } - - /** - * Describes an option to report an entity to Telegram. - * - * @param id Unique identifier of the option. - * @param text Text of the option. - */ - public ReportOption(byte[] id, String text) { - this.id = id; - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1106390048; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the reason why a chat is reported. - */ - public abstract static class ReportReason extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ReportReasonSpam.CONSTRUCTOR, - ReportReasonViolence.CONSTRUCTOR, - ReportReasonPornography.CONSTRUCTOR, - ReportReasonChildAbuse.CONSTRUCTOR, - ReportReasonCopyright.CONSTRUCTOR, - ReportReasonUnrelatedLocation.CONSTRUCTOR, - ReportReasonFake.CONSTRUCTOR, - ReportReasonIllegalDrugs.CONSTRUCTOR, - ReportReasonPersonalDetails.CONSTRUCTOR, - ReportReasonCustom.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ReportReason() { - } - } - - /** - * The chat contains spam messages. - */ - public static class ReportReasonSpam extends ReportReason { - - /** - * The chat contains spam messages. - */ - public ReportReasonSpam() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1207032897; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat promotes violence. - */ - public static class ReportReasonViolence extends ReportReason { - - /** - * The chat promotes violence. - */ - public ReportReasonViolence() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2038679353; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat contains pornographic messages. - */ - public static class ReportReasonPornography extends ReportReason { - - /** - * The chat contains pornographic messages. - */ - public ReportReasonPornography() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1306467575; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat has child abuse related content. - */ - public static class ReportReasonChildAbuse extends ReportReason { - - /** - * The chat has child abuse related content. - */ - public ReportReasonChildAbuse() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 761086718; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat contains copyrighted content. - */ - public static class ReportReasonCopyright extends ReportReason { - - /** - * The chat contains copyrighted content. - */ - public ReportReasonCopyright() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1474441135; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The location-based chat is unrelated to its stated location. - */ - public static class ReportReasonUnrelatedLocation extends ReportReason { - - /** - * The location-based chat is unrelated to its stated location. - */ - public ReportReasonUnrelatedLocation() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 87562288; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat represents a fake account. - */ - public static class ReportReasonFake extends ReportReason { - - /** - * The chat represents a fake account. - */ - public ReportReasonFake() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 352862176; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat has illegal drugs related content. - */ - public static class ReportReasonIllegalDrugs extends ReportReason { - - /** - * The chat has illegal drugs related content. - */ - public ReportReasonIllegalDrugs() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -61599200; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat contains messages with personal details. - */ - public static class ReportReasonPersonalDetails extends ReportReason { - - /** - * The chat contains messages with personal details. - */ - public ReportReasonPersonalDetails() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1588882414; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A custom reason provided by the user. - */ - public static class ReportReasonCustom extends ReportReason { - - /** - * A custom reason provided by the user. - */ - public ReportReasonCustom() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1380459917; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes result of sponsored message or chat report. - */ - public abstract static class ReportSponsoredResult extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ReportSponsoredResultOk.CONSTRUCTOR, - ReportSponsoredResultFailed.CONSTRUCTOR, - ReportSponsoredResultOptionRequired.CONSTRUCTOR, - ReportSponsoredResultAdsHidden.CONSTRUCTOR, - ReportSponsoredResultPremiumRequired.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ReportSponsoredResult() { - } - } - - /** - * The message was reported successfully. - */ - public static class ReportSponsoredResultOk extends ReportSponsoredResult { - - /** - * The message was reported successfully. - */ - public ReportSponsoredResultOk() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -128473456; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The sponsored message is too old or not found. - */ - public static class ReportSponsoredResultFailed extends ReportSponsoredResult { - - /** - * The sponsored message is too old or not found. - */ - public ReportSponsoredResultFailed() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1231714278; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user must choose an option to report the message and repeat request with the chosen option. - */ - public static class ReportSponsoredResultOptionRequired extends ReportSponsoredResult { - /** - * Title for the option choice. - */ - public String title; - /** - * List of available options. - */ - public ReportOption[] options; - - /** - * The user must choose an option to report the message and repeat request with the chosen option. - */ - public ReportSponsoredResultOptionRequired() { - } - - /** - * The user must choose an option to report the message and repeat request with the chosen option. - * - * @param title Title for the option choice. - * @param options List of available options. - */ - public ReportSponsoredResultOptionRequired(String title, ReportOption[] options) { - this.title = title; - this.options = options; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1646687318; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sponsored messages were hidden for the user in all chats. - */ - public static class ReportSponsoredResultAdsHidden extends ReportSponsoredResult { - - /** - * Sponsored messages were hidden for the user in all chats. - */ - public ReportSponsoredResultAdsHidden() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -372279531; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user asked to hide sponsored messages, but Telegram Premium is required for this. - */ - public static class ReportSponsoredResultPremiumRequired extends ReportSponsoredResult { - - /** - * The user asked to hide sponsored messages, but Telegram Premium is required for this. - */ - public ReportSponsoredResultPremiumRequired() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -55411887; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes result of story report. - */ - public abstract static class ReportStoryResult extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ReportStoryResultOk.CONSTRUCTOR, - ReportStoryResultOptionRequired.CONSTRUCTOR, - ReportStoryResultTextRequired.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ReportStoryResult() { - } - } - - /** - * The story was reported successfully. - */ - public static class ReportStoryResultOk extends ReportStoryResult { - - /** - * The story was reported successfully. - */ - public ReportStoryResultOk() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1405328461; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user must choose an option to report the story and repeat request with the chosen option. - */ - public static class ReportStoryResultOptionRequired extends ReportStoryResult { - /** - * Title for the option choice. - */ - public String title; - /** - * List of available options. - */ - public ReportOption[] options; - - /** - * The user must choose an option to report the story and repeat request with the chosen option. - */ - public ReportStoryResultOptionRequired() { - } - - /** - * The user must choose an option to report the story and repeat request with the chosen option. - * - * @param title Title for the option choice. - * @param options List of available options. - */ - public ReportStoryResultOptionRequired(String title, ReportOption[] options) { - this.title = title; - this.options = options; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1632974839; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user must add additional text details to the report. - */ - public static class ReportStoryResultTextRequired extends ReportStoryResult { - /** - * Option identifier for the next reportStory request. - */ - public byte[] optionId; - /** - * True, if the user can skip text adding. - */ - public boolean isOptional; - - /** - * The user must add additional text details to the report. - */ - public ReportStoryResultTextRequired() { - } - - /** - * The user must add additional text details to the report. - * - * @param optionId Option identifier for the next reportStory request. - * @param isOptional True, if the user can skip text adding. - */ - public ReportStoryResultTextRequired(byte[] optionId, boolean isOptional) { - this.optionId = optionId; - this.isOptional = isOptional; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 334339473; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the reason why a code needs to be re-sent. - */ - public abstract static class ResendCodeReason extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ResendCodeReasonUserRequest.CONSTRUCTOR, - ResendCodeReasonVerificationFailed.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ResendCodeReason() { - } - } - - /** - * The user requested to resend the code. - */ - public static class ResendCodeReasonUserRequest extends ResendCodeReason { - - /** - * The user requested to resend the code. - */ - public ResendCodeReasonUserRequest() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -441923456; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The code is re-sent, because device verification has failed. - */ - public static class ResendCodeReasonVerificationFailed extends ResendCodeReason { - /** - * Cause of the verification failure, for example, "PLAY_SERVICES_NOT_AVAILABLE", "APNS_RECEIVE_TIMEOUT", or "APNS_INIT_FAILED". - */ - public String errorMessage; - - /** - * The code is re-sent, because device verification has failed. - */ - public ResendCodeReasonVerificationFailed() { - } - - /** - * The code is re-sent, because device verification has failed. - * - * @param errorMessage Cause of the verification failure, for example, "PLAY_SERVICES_NOT_AVAILABLE", "APNS_RECEIVE_TIMEOUT", or "APNS_INIT_FAILED". - */ - public ResendCodeReasonVerificationFailed(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 529870273; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents result of 2-step verification password reset. - */ - public abstract static class ResetPasswordResult extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ResetPasswordResultOk.CONSTRUCTOR, - ResetPasswordResultPending.CONSTRUCTOR, - ResetPasswordResultDeclined.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ResetPasswordResult() { - } - } - - /** - * The password was reset. - */ - public static class ResetPasswordResultOk extends ResetPasswordResult { - - /** - * The password was reset. - */ - public ResetPasswordResultOk() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1397267463; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The password reset request is pending. - */ - public static class ResetPasswordResultPending extends ResetPasswordResult { - /** - * Point in time (Unix timestamp) after which the password can be reset immediately using resetPassword. - */ - public int pendingResetDate; - - /** - * The password reset request is pending. - */ - public ResetPasswordResultPending() { - } - - /** - * The password reset request is pending. - * - * @param pendingResetDate Point in time (Unix timestamp) after which the password can be reset immediately using resetPassword. - */ - public ResetPasswordResultPending(int pendingResetDate) { - this.pendingResetDate = pendingResetDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1193925721; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The password reset request was declined. - */ - public static class ResetPasswordResultDeclined extends ResetPasswordResult { - /** - * Point in time (Unix timestamp) when the password reset can be retried. - */ - public int retryDate; - - /** - * The password reset request was declined. - */ - public ResetPasswordResultDeclined() { - } - - /** - * The password reset request was declined. - * - * @param retryDate Point in time (Unix timestamp) when the password reset can be retried. - */ - public ResetPasswordResultDeclined(int retryDate) { - this.retryDate = retryDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1202200373; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about restrictions that must be applied to a chat or a message. - */ - public static class RestrictionInfo extends Object { - /** - * A human-readable description of the reason why access to the content must be restricted. If empty, then the content can be accessed, but may be covered by hidden with 18+ spoiler anyway. - */ - public String restrictionReason; - /** - * True, if media content of the messages must be hidden with 18+ spoiler. Use value of the option "can_ignore_sensitive_content_restrictions" to check whether the current user can ignore the restriction. If age verification parameters were received in updateAgeVerificationParameters, then the user must complete age verification to ignore the restriction. Set the option "ignore_sensitive_content_restrictions" to true if the user passes age verification. - */ - public boolean hasSensitiveContent; - - /** - * Contains information about restrictions that must be applied to a chat or a message. - */ - public RestrictionInfo() { - } - - /** - * Contains information about restrictions that must be applied to a chat or a message. - * - * @param restrictionReason A human-readable description of the reason why access to the content must be restricted. If empty, then the content can be accessed, but may be covered by hidden with 18+ spoiler anyway. - * @param hasSensitiveContent True, if media content of the messages must be hidden with 18+ spoiler. Use value of the option "can_ignore_sensitive_content_restrictions" to check whether the current user can ignore the restriction. If age verification parameters were received in updateAgeVerificationParameters, then the user must complete age verification to ignore the restriction. Set the option "ignore_sensitive_content_restrictions" to true if the user passes age verification. - */ - public RestrictionInfo(String restrictionReason, boolean hasSensitiveContent) { - this.restrictionReason = restrictionReason; - this.hasSensitiveContent = hasSensitiveContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1980541683; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes state of a revenue withdrawal. - */ - public abstract static class RevenueWithdrawalState extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - RevenueWithdrawalStatePending.CONSTRUCTOR, - RevenueWithdrawalStateSucceeded.CONSTRUCTOR, - RevenueWithdrawalStateFailed.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public RevenueWithdrawalState() { - } - } - - /** - * Withdrawal is pending. - */ - public static class RevenueWithdrawalStatePending extends RevenueWithdrawalState { - - /** - * Withdrawal is pending. - */ - public RevenueWithdrawalStatePending() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1563512741; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Withdrawal succeeded. - */ - public static class RevenueWithdrawalStateSucceeded extends RevenueWithdrawalState { - /** - * Point in time (Unix timestamp) when the withdrawal was completed. - */ - public int date; - /** - * The URL where the withdrawal transaction can be viewed. - */ - public String url; - - /** - * Withdrawal succeeded. - */ - public RevenueWithdrawalStateSucceeded() { - } - - /** - * Withdrawal succeeded. - * - * @param date Point in time (Unix timestamp) when the withdrawal was completed. - * @param url The URL where the withdrawal transaction can be viewed. - */ - public RevenueWithdrawalStateSucceeded(int date, String url) { - this.date = date; - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 265375242; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Withdrawal failed. - */ - public static class RevenueWithdrawalStateFailed extends RevenueWithdrawalState { - - /** - * Withdrawal failed. - */ - public RevenueWithdrawalStateFailed() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -12504951; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a formatted text object. - */ - public abstract static class RichText extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - RichTextPlain.CONSTRUCTOR, - RichTextBold.CONSTRUCTOR, - RichTextItalic.CONSTRUCTOR, - RichTextUnderline.CONSTRUCTOR, - RichTextStrikethrough.CONSTRUCTOR, - RichTextFixed.CONSTRUCTOR, - RichTextUrl.CONSTRUCTOR, - RichTextEmailAddress.CONSTRUCTOR, - RichTextSubscript.CONSTRUCTOR, - RichTextSuperscript.CONSTRUCTOR, - RichTextMarked.CONSTRUCTOR, - RichTextPhoneNumber.CONSTRUCTOR, - RichTextIcon.CONSTRUCTOR, - RichTextReference.CONSTRUCTOR, - RichTextAnchor.CONSTRUCTOR, - RichTextAnchorLink.CONSTRUCTOR, - RichTexts.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public RichText() { - } - } - - /** - * A plain text. - */ - public static class RichTextPlain extends RichText { - /** - * Text. - */ - public String text; - - /** - * A plain text. - */ - public RichTextPlain() { - } - - /** - * A plain text. - * - * @param text Text. - */ - public RichTextPlain(String text) { - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 482617702; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A bold rich text. - */ - public static class RichTextBold extends RichText { - /** - * Text. - */ - public RichText text; - - /** - * A bold rich text. - */ - public RichTextBold() { - } - - /** - * A bold rich text. - * - * @param text Text. - */ - public RichTextBold(RichText text) { - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1670844268; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An italicized rich text. - */ - public static class RichTextItalic extends RichText { - /** - * Text. - */ - public RichText text; - - /** - * An italicized rich text. - */ - public RichTextItalic() { - } - - /** - * An italicized rich text. - * - * @param text Text. - */ - public RichTextItalic(RichText text) { - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1853354047; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An underlined rich text. - */ - public static class RichTextUnderline extends RichText { - /** - * Text. - */ - public RichText text; - - /** - * An underlined rich text. - */ - public RichTextUnderline() { - } - - /** - * An underlined rich text. - * - * @param text Text. - */ - public RichTextUnderline(RichText text) { - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -536019572; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A strikethrough rich text. - */ - public static class RichTextStrikethrough extends RichText { - /** - * Text. - */ - public RichText text; - - /** - * A strikethrough rich text. - */ - public RichTextStrikethrough() { - } - - /** - * A strikethrough rich text. - * - * @param text Text. - */ - public RichTextStrikethrough(RichText text) { - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 723413585; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A fixed-width rich text. - */ - public static class RichTextFixed extends RichText { - /** - * Text. - */ - public RichText text; - - /** - * A fixed-width rich text. - */ - public RichTextFixed() { - } - - /** - * A fixed-width rich text. - * - * @param text Text. - */ - public RichTextFixed(RichText text) { - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1271496249; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A rich text URL link. - */ - public static class RichTextUrl extends RichText { - /** - * Text. - */ - public RichText text; - /** - * URL. - */ - public String url; - /** - * True, if the URL has cached instant view server-side. - */ - public boolean isCached; - - /** - * A rich text URL link. - */ - public RichTextUrl() { - } - - /** - * A rich text URL link. - * - * @param text Text. - * @param url URL. - * @param isCached True, if the URL has cached instant view server-side. - */ - public RichTextUrl(RichText text, String url, boolean isCached) { - this.text = text; - this.url = url; - this.isCached = isCached; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 83939092; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A rich text email link. - */ - public static class RichTextEmailAddress extends RichText { - /** - * Text. - */ - public RichText text; - /** - * Email address. - */ - public String emailAddress; - - /** - * A rich text email link. - */ - public RichTextEmailAddress() { - } - - /** - * A rich text email link. - * - * @param text Text. - * @param emailAddress Email address. - */ - public RichTextEmailAddress(RichText text, String emailAddress) { - this.text = text; - this.emailAddress = emailAddress; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 40018679; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A subscript rich text. - */ - public static class RichTextSubscript extends RichText { - /** - * Text. - */ - public RichText text; - - /** - * A subscript rich text. - */ - public RichTextSubscript() { - } - - /** - * A subscript rich text. - * - * @param text Text. - */ - public RichTextSubscript(RichText text) { - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -868197812; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A superscript rich text. - */ - public static class RichTextSuperscript extends RichText { - /** - * Text. - */ - public RichText text; - - /** - * A superscript rich text. - */ - public RichTextSuperscript() { - } - - /** - * A superscript rich text. - * - * @param text Text. - */ - public RichTextSuperscript(RichText text) { - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -382241437; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A marked rich text. - */ - public static class RichTextMarked extends RichText { - /** - * Text. - */ - public RichText text; - - /** - * A marked rich text. - */ - public RichTextMarked() { - } - - /** - * A marked rich text. - * - * @param text Text. - */ - public RichTextMarked(RichText text) { - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1271999614; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A rich text phone number. - */ - public static class RichTextPhoneNumber extends RichText { - /** - * Text. - */ - public RichText text; - /** - * Phone number. - */ - public String phoneNumber; - - /** - * A rich text phone number. - */ - public RichTextPhoneNumber() { - } - - /** - * A rich text phone number. - * - * @param text Text. - * @param phoneNumber Phone number. - */ - public RichTextPhoneNumber(RichText text, String phoneNumber) { - this.text = text; - this.phoneNumber = phoneNumber; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 128521539; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A small image inside the text. - */ - public static class RichTextIcon extends RichText { - /** - * The image represented as a document. The image can be in GIF, JPEG or PNG format. - */ - public Document document; - /** - * Width of a bounding box in which the image must be shown; 0 if unknown. - */ - public int width; - /** - * Height of a bounding box in which the image must be shown; 0 if unknown. - */ - public int height; - - /** - * A small image inside the text. - */ - public RichTextIcon() { - } - - /** - * A small image inside the text. - * - * @param document The image represented as a document. The image can be in GIF, JPEG or PNG format. - * @param width Width of a bounding box in which the image must be shown; 0 if unknown. - * @param height Height of a bounding box in which the image must be shown; 0 if unknown. - */ - public RichTextIcon(Document document, int width, int height) { - this.document = document; - this.width = width; - this.height = height; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1480316158; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A reference to a richTexts object on the same page. - */ - public static class RichTextReference extends RichText { - /** - * The text. - */ - public RichText text; - /** - * The name of a richTextAnchor object, which is the first element of the target richTexts object. - */ - public String anchorName; - /** - * An HTTP URL, opening the reference. - */ - public String url; - - /** - * A reference to a richTexts object on the same page. - */ - public RichTextReference() { - } - - /** - * A reference to a richTexts object on the same page. - * - * @param text The text. - * @param anchorName The name of a richTextAnchor object, which is the first element of the target richTexts object. - * @param url An HTTP URL, opening the reference. - */ - public RichTextReference(RichText text, String anchorName, String url) { - this.text = text; - this.anchorName = anchorName; - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1147530634; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An anchor. - */ - public static class RichTextAnchor extends RichText { - /** - * Anchor name. - */ - public String name; - - /** - * An anchor. - */ - public RichTextAnchor() { - } - - /** - * An anchor. - * - * @param name Anchor name. - */ - public RichTextAnchor(String name) { - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1316950068; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A link to an anchor on the same page. - */ - public static class RichTextAnchorLink extends RichText { - /** - * The link text. - */ - public RichText text; - /** - * The anchor name. If the name is empty, the link must bring back to top. - */ - public String anchorName; - /** - * An HTTP URL, opening the anchor. - */ - public String url; - - /** - * A link to an anchor on the same page. - */ - public RichTextAnchorLink() { - } - - /** - * A link to an anchor on the same page. - * - * @param text The link text. - * @param anchorName The anchor name. If the name is empty, the link must bring back to top. - * @param url An HTTP URL, opening the anchor. - */ - public RichTextAnchorLink(RichText text, String anchorName, String url) { - this.text = text; - this.anchorName = anchorName; - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1541418282; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A concatenation of rich texts. - */ - public static class RichTexts extends RichText { - /** - * Texts. - */ - public RichText[] texts; - - /** - * A concatenation of rich texts. - */ - public RichTexts() { - } - - /** - * A concatenation of rich texts. - * - * @param texts Texts. - */ - public RichTexts(RichText[] texts) { - this.texts = texts; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1647457821; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents an RTMP URL. - */ - public static class RtmpUrl extends Object { - /** - * The URL. - */ - public String url; - /** - * Stream key. - */ - public String streamKey; - - /** - * Represents an RTMP URL. - */ - public RtmpUrl() { - } - - /** - * Represents an RTMP URL. - * - * @param url The URL. - * @param streamKey Stream key. - */ - public RtmpUrl(String url, String streamKey) { - this.url = url; - this.streamKey = streamKey; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1009302613; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about saved payment credentials. - */ - public static class SavedCredentials extends Object { - /** - * Unique identifier of the saved credentials. - */ - public String id; - /** - * Title of the saved credentials. - */ - public String title; - - /** - * Contains information about saved payment credentials. - */ - public SavedCredentials() { - } - - /** - * Contains information about saved payment credentials. - * - * @param id Unique identifier of the saved credentials. - * @param title Title of the saved credentials. - */ - public SavedCredentials(String id, String title) { - this.id = id; - this.title = title; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -370273060; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a tag used in Saved Messages or a Saved Messages topic. - */ - public static class SavedMessagesTag extends Object { - /** - * The tag. - */ - public ReactionType tag; - /** - * Label of the tag; 0-12 characters. Always empty if the tag is returned for a Saved Messages topic. - */ - public String label; - /** - * Number of times the tag was used; may be 0 if the tag has non-empty label. - */ - public int count; - - /** - * Represents a tag used in Saved Messages or a Saved Messages topic. - */ - public SavedMessagesTag() { - } - - /** - * Represents a tag used in Saved Messages or a Saved Messages topic. - * - * @param tag The tag. - * @param label Label of the tag; 0-12 characters. Always empty if the tag is returned for a Saved Messages topic. - * @param count Number of times the tag was used; may be 0 if the tag has non-empty label. - */ - public SavedMessagesTag(ReactionType tag, String label, int count) { - this.tag = tag; - this.label = label; - this.count = count; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1785183329; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of tags used in Saved Messages. - */ - public static class SavedMessagesTags extends Object { - /** - * List of tags. - */ - public SavedMessagesTag[] tags; - - /** - * Contains a list of tags used in Saved Messages. - */ - public SavedMessagesTags() { - } - - /** - * Contains a list of tags used in Saved Messages. - * - * @param tags List of tags. - */ - public SavedMessagesTags(SavedMessagesTag[] tags) { - this.tags = tags; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1749291430; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a Saved Messages topic. - */ - public static class SavedMessagesTopic extends Object { - /** - * Unique topic identifier. - */ - public long id; - /** - * Type of the topic. - */ - public SavedMessagesTopicType type; - /** - * True, if the topic is pinned. - */ - public boolean isPinned; - /** - * A parameter used to determine order of the topic in the topic list. Topics must be sorted by the order in descending order. - */ - public long order; - /** - * Last message in the topic; may be null if none or unknown. - */ - @Nullable public Message lastMessage; - /** - * A draft of a message in the topic; may be null if none. - */ - @Nullable public DraftMessage draftMessage; - - /** - * Contains information about a Saved Messages topic. - */ - public SavedMessagesTopic() { - } - - /** - * Contains information about a Saved Messages topic. - * - * @param id Unique topic identifier. - * @param type Type of the topic. - * @param isPinned True, if the topic is pinned. - * @param order A parameter used to determine order of the topic in the topic list. Topics must be sorted by the order in descending order. - * @param lastMessage Last message in the topic; may be null if none or unknown. - * @param draftMessage A draft of a message in the topic; may be null if none. - */ - public SavedMessagesTopic(long id, SavedMessagesTopicType type, boolean isPinned, long order, Message lastMessage, DraftMessage draftMessage) { - this.id = id; - this.type = type; - this.isPinned = isPinned; - this.order = order; - this.lastMessage = lastMessage; - this.draftMessage = draftMessage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -760684124; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of Saved Messages topic. - */ - public abstract static class SavedMessagesTopicType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - SavedMessagesTopicTypeMyNotes.CONSTRUCTOR, - SavedMessagesTopicTypeAuthorHidden.CONSTRUCTOR, - SavedMessagesTopicTypeSavedFromChat.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public SavedMessagesTopicType() { - } - } - - /** - * Topic containing messages sent by the current user of forwarded from an unknown chat. - */ - public static class SavedMessagesTopicTypeMyNotes extends SavedMessagesTopicType { - - /** - * Topic containing messages sent by the current user of forwarded from an unknown chat. - */ - public SavedMessagesTopicTypeMyNotes() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1282784779; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Topic containing messages forwarded from a user with hidden privacy. - */ - public static class SavedMessagesTopicTypeAuthorHidden extends SavedMessagesTopicType { - - /** - * Topic containing messages forwarded from a user with hidden privacy. - */ - public SavedMessagesTopicTypeAuthorHidden() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1882997141; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Topic containing messages forwarded from a specific chat. - */ - public static class SavedMessagesTopicTypeSavedFromChat extends SavedMessagesTopicType { - /** - * Identifier of the chat. - */ - public long chatId; - - /** - * Topic containing messages forwarded from a specific chat. - */ - public SavedMessagesTopicTypeSavedFromChat() { - } - - /** - * Topic containing messages forwarded from a specific chat. - * - * @param chatId Identifier of the chat. - */ - public SavedMessagesTopicTypeSavedFromChat(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1723880104; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains autosave settings for an autosave settings scope. - */ - public static class ScopeAutosaveSettings extends Object { - /** - * True, if photo autosave is enabled. - */ - public boolean autosavePhotos; - /** - * True, if video autosave is enabled. - */ - public boolean autosaveVideos; - /** - * The maximum size of a video file to be autosaved, in bytes; 512 KB - 4000 MB. - */ - public long maxVideoFileSize; - - /** - * Contains autosave settings for an autosave settings scope. - */ - public ScopeAutosaveSettings() { - } - - /** - * Contains autosave settings for an autosave settings scope. - * - * @param autosavePhotos True, if photo autosave is enabled. - * @param autosaveVideos True, if video autosave is enabled. - * @param maxVideoFileSize The maximum size of a video file to be autosaved, in bytes; 512 KB - 4000 MB. - */ - public ScopeAutosaveSettings(boolean autosavePhotos, boolean autosaveVideos, long maxVideoFileSize) { - this.autosavePhotos = autosavePhotos; - this.autosaveVideos = autosaveVideos; - this.maxVideoFileSize = maxVideoFileSize; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1546821427; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about notification settings for several chats. - */ - public static class ScopeNotificationSettings extends Object { - /** - * Time left before notifications will be unmuted, in seconds. - */ - public int muteFor; - /** - * Identifier of the notification sound to be played; 0 if sound is disabled. - */ - public long soundId; - /** - * True, if message content must be displayed in notifications. - */ - public boolean showPreview; - /** - * If true, story notifications are received only for the first 5 chats from topChatCategoryUsers regardless of the value of muteStories. - */ - public boolean useDefaultMuteStories; - /** - * True, if story notifications are disabled. - */ - public boolean muteStories; - /** - * Identifier of the notification sound to be played for stories; 0 if sound is disabled. - */ - public long storySoundId; - /** - * True, if the chat that posted a story must be displayed in notifications. - */ - public boolean showStoryPoster; - /** - * True, if notifications for incoming pinned messages will be created as for an ordinary unread message. - */ - public boolean disablePinnedMessageNotifications; - /** - * True, if notifications for messages with mentions will be created as for an ordinary unread message. - */ - public boolean disableMentionNotifications; - - /** - * Contains information about notification settings for several chats. - */ - public ScopeNotificationSettings() { - } - - /** - * Contains information about notification settings for several chats. - * - * @param muteFor Time left before notifications will be unmuted, in seconds. - * @param soundId Identifier of the notification sound to be played; 0 if sound is disabled. - * @param showPreview True, if message content must be displayed in notifications. - * @param useDefaultMuteStories If true, story notifications are received only for the first 5 chats from topChatCategoryUsers regardless of the value of muteStories. - * @param muteStories True, if story notifications are disabled. - * @param storySoundId Identifier of the notification sound to be played for stories; 0 if sound is disabled. - * @param showStoryPoster True, if the chat that posted a story must be displayed in notifications. - * @param disablePinnedMessageNotifications True, if notifications for incoming pinned messages will be created as for an ordinary unread message. - * @param disableMentionNotifications True, if notifications for messages with mentions will be created as for an ordinary unread message. - */ - public ScopeNotificationSettings(int muteFor, long soundId, boolean showPreview, boolean useDefaultMuteStories, boolean muteStories, long storySoundId, boolean showStoryPoster, boolean disablePinnedMessageNotifications, boolean disableMentionNotifications) { - this.muteFor = muteFor; - this.soundId = soundId; - this.showPreview = showPreview; - this.useDefaultMuteStories = useDefaultMuteStories; - this.muteStories = muteStories; - this.storySoundId = storySoundId; - this.showStoryPoster = showStoryPoster; - this.disablePinnedMessageNotifications = disablePinnedMessageNotifications; - this.disableMentionNotifications = disableMentionNotifications; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 88369150; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents a filter for type of the chats in which to search messages. - */ - public abstract static class SearchMessagesChatTypeFilter extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - SearchMessagesChatTypeFilterPrivate.CONSTRUCTOR, - SearchMessagesChatTypeFilterGroup.CONSTRUCTOR, - SearchMessagesChatTypeFilterChannel.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public SearchMessagesChatTypeFilter() { - } - } - - /** - * Returns only messages in private chats. - */ - public static class SearchMessagesChatTypeFilterPrivate extends SearchMessagesChatTypeFilter { - - /** - * Returns only messages in private chats. - */ - public SearchMessagesChatTypeFilterPrivate() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1169248975; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only messages in basic group and supergroup chats. - */ - public static class SearchMessagesChatTypeFilterGroup extends SearchMessagesChatTypeFilter { - - /** - * Returns only messages in basic group and supergroup chats. - */ - public SearchMessagesChatTypeFilterGroup() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2059426022; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only messages in channel chats. - */ - public static class SearchMessagesChatTypeFilterChannel extends SearchMessagesChatTypeFilter { - - /** - * Returns only messages in channel chats. - */ - public SearchMessagesChatTypeFilterChannel() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -773540139; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents a filter for message search results. - */ - public abstract static class SearchMessagesFilter extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - SearchMessagesFilterEmpty.CONSTRUCTOR, - SearchMessagesFilterAnimation.CONSTRUCTOR, - SearchMessagesFilterAudio.CONSTRUCTOR, - SearchMessagesFilterDocument.CONSTRUCTOR, - SearchMessagesFilterPhoto.CONSTRUCTOR, - SearchMessagesFilterVideo.CONSTRUCTOR, - SearchMessagesFilterVoiceNote.CONSTRUCTOR, - SearchMessagesFilterPhotoAndVideo.CONSTRUCTOR, - SearchMessagesFilterUrl.CONSTRUCTOR, - SearchMessagesFilterChatPhoto.CONSTRUCTOR, - SearchMessagesFilterVideoNote.CONSTRUCTOR, - SearchMessagesFilterVoiceAndVideoNote.CONSTRUCTOR, - SearchMessagesFilterMention.CONSTRUCTOR, - SearchMessagesFilterUnreadMention.CONSTRUCTOR, - SearchMessagesFilterUnreadReaction.CONSTRUCTOR, - SearchMessagesFilterFailedToSend.CONSTRUCTOR, - SearchMessagesFilterPinned.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public SearchMessagesFilter() { - } - } - - /** - * Returns all found messages, no filter is applied. - */ - public static class SearchMessagesFilterEmpty extends SearchMessagesFilter { - - /** - * Returns all found messages, no filter is applied. - */ - public SearchMessagesFilterEmpty() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -869395657; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only animation messages. - */ - public static class SearchMessagesFilterAnimation extends SearchMessagesFilter { - - /** - * Returns only animation messages. - */ - public SearchMessagesFilterAnimation() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -155713339; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only audio messages. - */ - public static class SearchMessagesFilterAudio extends SearchMessagesFilter { - - /** - * Returns only audio messages. - */ - public SearchMessagesFilterAudio() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 867505275; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only document messages. - */ - public static class SearchMessagesFilterDocument extends SearchMessagesFilter { - - /** - * Returns only document messages. - */ - public SearchMessagesFilterDocument() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1526331215; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only photo messages. - */ - public static class SearchMessagesFilterPhoto extends SearchMessagesFilter { - - /** - * Returns only photo messages. - */ - public SearchMessagesFilterPhoto() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 925932293; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only video messages. - */ - public static class SearchMessagesFilterVideo extends SearchMessagesFilter { - - /** - * Returns only video messages. - */ - public SearchMessagesFilterVideo() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 115538222; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only voice note messages. - */ - public static class SearchMessagesFilterVoiceNote extends SearchMessagesFilter { - - /** - * Returns only voice note messages. - */ - public SearchMessagesFilterVoiceNote() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1841439357; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only photo and video messages. - */ - public static class SearchMessagesFilterPhotoAndVideo extends SearchMessagesFilter { - - /** - * Returns only photo and video messages. - */ - public SearchMessagesFilterPhotoAndVideo() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1352130963; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only messages containing URLs. - */ - public static class SearchMessagesFilterUrl extends SearchMessagesFilter { - - /** - * Returns only messages containing URLs. - */ - public SearchMessagesFilterUrl() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1828724341; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only messages containing chat photos. - */ - public static class SearchMessagesFilterChatPhoto extends SearchMessagesFilter { - - /** - * Returns only messages containing chat photos. - */ - public SearchMessagesFilterChatPhoto() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1247751329; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only video note messages. - */ - public static class SearchMessagesFilterVideoNote extends SearchMessagesFilter { - - /** - * Returns only video note messages. - */ - public SearchMessagesFilterVideoNote() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 564323321; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only voice and video note messages. - */ - public static class SearchMessagesFilterVoiceAndVideoNote extends SearchMessagesFilter { - - /** - * Returns only voice and video note messages. - */ - public SearchMessagesFilterVoiceAndVideoNote() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 664174819; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only messages with mentions of the current user, or messages that are replies to their messages. - */ - public static class SearchMessagesFilterMention extends SearchMessagesFilter { - - /** - * Returns only messages with mentions of the current user, or messages that are replies to their messages. - */ - public SearchMessagesFilterMention() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2001258652; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only messages with unread mentions of the current user, or messages that are replies to their messages. When using this filter the results can't be additionally filtered by a query, a message thread or by the sending user. - */ - public static class SearchMessagesFilterUnreadMention extends SearchMessagesFilter { - - /** - * Returns only messages with unread mentions of the current user, or messages that are replies to their messages. When using this filter the results can't be additionally filtered by a query, a message thread or by the sending user. - */ - public SearchMessagesFilterUnreadMention() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -95769149; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only messages with unread reactions for the current user. When using this filter the results can't be additionally filtered by a query, a message thread or by the sending user. - */ - public static class SearchMessagesFilterUnreadReaction extends SearchMessagesFilter { - - /** - * Returns only messages with unread reactions for the current user. When using this filter the results can't be additionally filtered by a query, a message thread or by the sending user. - */ - public SearchMessagesFilterUnreadReaction() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1379651328; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only failed to send messages. This filter can be used only if the message database is used. - */ - public static class SearchMessagesFilterFailedToSend extends SearchMessagesFilter { - - /** - * Returns only failed to send messages. This filter can be used only if the message database is used. - */ - public SearchMessagesFilterFailedToSend() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -596322564; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns only pinned messages. - */ - public static class SearchMessagesFilterPinned extends SearchMessagesFilter { - - /** - * Returns only pinned messages. - */ - public SearchMessagesFilterPinned() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 371805512; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a value representing a number of seconds. - */ - public static class Seconds extends Object { - /** - * Number of seconds. - */ - public double seconds; - - /** - * Contains a value representing a number of seconds. - */ - public Seconds() { - } - - /** - * Contains a value representing a number of seconds. - * - * @param seconds Number of seconds. - */ - public Seconds(double seconds) { - this.seconds = seconds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 959899022; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a secret chat. - */ - public static class SecretChat extends Object { - /** - * Secret chat identifier. - */ - public int id; - /** - * Identifier of the chat partner. - */ - public long userId; - /** - * State of the secret chat. - */ - public SecretChatState state; - /** - * True, if the chat was created by the current user; false otherwise. - */ - public boolean isOutbound; - /** - * Hash of the currently used key for comparison with the hash of the chat partner's key. This is a string of 36 little-endian bytes, which must be split into groups of 2 bits, each denoting a pixel of one of 4 colors FFFFFF, D5E6F3, 2D5775, and 2F99C9. The pixels must be used to make a 12x12 square image filled from left to right, top to bottom. Alternatively, the first 32 bytes of the hash can be converted to the hexadecimal format and printed as 32 2-digit hex numbers. - */ - public byte[] keyHash; - /** - * Secret chat layer; determines features supported by the chat partner's application. Nested text entities and underline and strikethrough entities are supported if the layer >= 101, files bigger than 2000MB are supported if the layer >= 143, spoiler and custom emoji text entities are supported if the layer >= 144. - */ - public int layer; - - /** - * Represents a secret chat. - */ - public SecretChat() { - } - - /** - * Represents a secret chat. - * - * @param id Secret chat identifier. - * @param userId Identifier of the chat partner. - * @param state State of the secret chat. - * @param isOutbound True, if the chat was created by the current user; false otherwise. - * @param keyHash Hash of the currently used key for comparison with the hash of the chat partner's key. This is a string of 36 little-endian bytes, which must be split into groups of 2 bits, each denoting a pixel of one of 4 colors FFFFFF, D5E6F3, 2D5775, and 2F99C9. The pixels must be used to make a 12x12 square image filled from left to right, top to bottom. Alternatively, the first 32 bytes of the hash can be converted to the hexadecimal format and printed as 32 2-digit hex numbers. - * @param layer Secret chat layer; determines features supported by the chat partner's application. Nested text entities and underline and strikethrough entities are supported if the layer >= 101, files bigger than 2000MB are supported if the layer >= 143, spoiler and custom emoji text entities are supported if the layer >= 144. - */ - public SecretChat(int id, long userId, SecretChatState state, boolean isOutbound, byte[] keyHash, int layer) { - this.id = id; - this.userId = userId; - this.state = state; - this.isOutbound = isOutbound; - this.keyHash = keyHash; - this.layer = layer; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -676918325; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the current secret chat state. - */ - public abstract static class SecretChatState extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - SecretChatStatePending.CONSTRUCTOR, - SecretChatStateReady.CONSTRUCTOR, - SecretChatStateClosed.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public SecretChatState() { - } - } - - /** - * The secret chat is not yet created; waiting for the other user to get online. - */ - public static class SecretChatStatePending extends SecretChatState { - - /** - * The secret chat is not yet created; waiting for the other user to get online. - */ - public SecretChatStatePending() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1637050756; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The secret chat is ready to use. - */ - public static class SecretChatStateReady extends SecretChatState { - - /** - * The secret chat is ready to use. - */ - public SecretChatStateReady() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1611352087; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The secret chat is closed. - */ - public static class SecretChatStateClosed extends SecretChatState { - - /** - * The secret chat is closed. - */ - public SecretChatStateClosed() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1945106707; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents content of a gift received by a user or a channel chat. - */ - public abstract static class SentGift extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - SentGiftRegular.CONSTRUCTOR, - SentGiftUpgraded.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public SentGift() { - } - } - - /** - * Regular gift. - */ - public static class SentGiftRegular extends SentGift { - /** - * The gift. - */ - public Gift gift; - - /** - * Regular gift. - */ - public SentGiftRegular() { - } - - /** - * Regular gift. - * - * @param gift The gift. - */ - public SentGiftRegular(Gift gift) { - this.gift = gift; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 594062617; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Upgraded gift. - */ - public static class SentGiftUpgraded extends SentGift { - /** - * The gift. - */ - public UpgradedGift gift; - - /** - * Upgraded gift. - */ - public SentGiftUpgraded() { - } - - /** - * Upgraded gift. - * - * @param gift The gift. - */ - public SentGiftUpgraded(UpgradedGift gift) { - this.gift = gift; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 627524736; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Information about the message sent by answerWebAppQuery. - */ - public static class SentWebAppMessage extends Object { - /** - * Identifier of the sent inline message, if known. - */ - public String inlineMessageId; - - /** - * Information about the message sent by answerWebAppQuery. - */ - public SentWebAppMessage() { - } - - /** - * Information about the message sent by answerWebAppQuery. - * - * @param inlineMessageId Identifier of the sent inline message, if known. - */ - public SentWebAppMessage(String inlineMessageId) { - this.inlineMessageId = inlineMessageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1243934400; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about one session in a Telegram application used by the current user. Sessions must be shown to the user in the returned order. - */ - public static class Session extends Object { - /** - * Session identifier. - */ - public long id; - /** - * True, if this session is the current session. - */ - public boolean isCurrent; - /** - * True, if a 2-step verification password is needed to complete authorization of the session. - */ - public boolean isPasswordPending; - /** - * True, if the session wasn't confirmed from another session. - */ - public boolean isUnconfirmed; - /** - * True, if incoming secret chats can be accepted by the session. - */ - public boolean canAcceptSecretChats; - /** - * True, if incoming calls can be accepted by the session. - */ - public boolean canAcceptCalls; - /** - * Session type based on the system and application version, which can be used to display a corresponding icon. - */ - public SessionType type; - /** - * Telegram API identifier, as provided by the application. - */ - public int apiId; - /** - * Name of the application, as provided by the application. - */ - public String applicationName; - /** - * The version of the application, as provided by the application. - */ - public String applicationVersion; - /** - * True, if the application is an official application or uses the apiId of an official application. - */ - public boolean isOfficialApplication; - /** - * Model of the device the application has been run or is running on, as provided by the application. - */ - public String deviceModel; - /** - * Operating system the application has been run or is running on, as provided by the application. - */ - public String platform; - /** - * Version of the operating system the application has been run or is running on, as provided by the application. - */ - public String systemVersion; - /** - * Point in time (Unix timestamp) when the user has logged in. - */ - public int logInDate; - /** - * Point in time (Unix timestamp) when the session was last used. - */ - public int lastActiveDate; - /** - * IP address from which the session was created, in human-readable format. - */ - public String ipAddress; - /** - * A human-readable description of the location from which the session was created, based on the IP address. - */ - public String location; - - /** - * Contains information about one session in a Telegram application used by the current user. Sessions must be shown to the user in the returned order. - */ - public Session() { - } - - /** - * Contains information about one session in a Telegram application used by the current user. Sessions must be shown to the user in the returned order. - * - * @param id Session identifier. - * @param isCurrent True, if this session is the current session. - * @param isPasswordPending True, if a 2-step verification password is needed to complete authorization of the session. - * @param isUnconfirmed True, if the session wasn't confirmed from another session. - * @param canAcceptSecretChats True, if incoming secret chats can be accepted by the session. - * @param canAcceptCalls True, if incoming calls can be accepted by the session. - * @param type Session type based on the system and application version, which can be used to display a corresponding icon. - * @param apiId Telegram API identifier, as provided by the application. - * @param applicationName Name of the application, as provided by the application. - * @param applicationVersion The version of the application, as provided by the application. - * @param isOfficialApplication True, if the application is an official application or uses the apiId of an official application. - * @param deviceModel Model of the device the application has been run or is running on, as provided by the application. - * @param platform Operating system the application has been run or is running on, as provided by the application. - * @param systemVersion Version of the operating system the application has been run or is running on, as provided by the application. - * @param logInDate Point in time (Unix timestamp) when the user has logged in. - * @param lastActiveDate Point in time (Unix timestamp) when the session was last used. - * @param ipAddress IP address from which the session was created, in human-readable format. - * @param location A human-readable description of the location from which the session was created, based on the IP address. - */ - public Session(long id, boolean isCurrent, boolean isPasswordPending, boolean isUnconfirmed, boolean canAcceptSecretChats, boolean canAcceptCalls, SessionType type, int apiId, String applicationName, String applicationVersion, boolean isOfficialApplication, String deviceModel, String platform, String systemVersion, int logInDate, int lastActiveDate, String ipAddress, String location) { - this.id = id; - this.isCurrent = isCurrent; - this.isPasswordPending = isPasswordPending; - this.isUnconfirmed = isUnconfirmed; - this.canAcceptSecretChats = canAcceptSecretChats; - this.canAcceptCalls = canAcceptCalls; - this.type = type; - this.apiId = apiId; - this.applicationName = applicationName; - this.applicationVersion = applicationVersion; - this.isOfficialApplication = isOfficialApplication; - this.deviceModel = deviceModel; - this.platform = platform; - this.systemVersion = systemVersion; - this.logInDate = logInDate; - this.lastActiveDate = lastActiveDate; - this.ipAddress = ipAddress; - this.location = location; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 158702140; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents the type of session. - */ - public abstract static class SessionType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - SessionTypeAndroid.CONSTRUCTOR, - SessionTypeApple.CONSTRUCTOR, - SessionTypeBrave.CONSTRUCTOR, - SessionTypeChrome.CONSTRUCTOR, - SessionTypeEdge.CONSTRUCTOR, - SessionTypeFirefox.CONSTRUCTOR, - SessionTypeIpad.CONSTRUCTOR, - SessionTypeIphone.CONSTRUCTOR, - SessionTypeLinux.CONSTRUCTOR, - SessionTypeMac.CONSTRUCTOR, - SessionTypeOpera.CONSTRUCTOR, - SessionTypeSafari.CONSTRUCTOR, - SessionTypeUbuntu.CONSTRUCTOR, - SessionTypeUnknown.CONSTRUCTOR, - SessionTypeVivaldi.CONSTRUCTOR, - SessionTypeWindows.CONSTRUCTOR, - SessionTypeXbox.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public SessionType() { - } - } - - /** - * The session is running on an Android device. - */ - public static class SessionTypeAndroid extends SessionType { - - /** - * The session is running on an Android device. - */ - public SessionTypeAndroid() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2071764840; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The session is running on a generic Apple device. - */ - public static class SessionTypeApple extends SessionType { - - /** - * The session is running on a generic Apple device. - */ - public SessionTypeApple() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1818635701; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The session is running on the Brave browser. - */ - public static class SessionTypeBrave extends SessionType { - - /** - * The session is running on the Brave browser. - */ - public SessionTypeBrave() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1216812563; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The session is running on the Chrome browser. - */ - public static class SessionTypeChrome extends SessionType { - - /** - * The session is running on the Chrome browser. - */ - public SessionTypeChrome() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1573464425; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The session is running on the Edge browser. - */ - public static class SessionTypeEdge extends SessionType { - - /** - * The session is running on the Edge browser. - */ - public SessionTypeEdge() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -538916005; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The session is running on the Firefox browser. - */ - public static class SessionTypeFirefox extends SessionType { - - /** - * The session is running on the Firefox browser. - */ - public SessionTypeFirefox() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2122579364; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The session is running on an iPad device. - */ - public static class SessionTypeIpad extends SessionType { - - /** - * The session is running on an iPad device. - */ - public SessionTypeIpad() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1294647023; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The session is running on an iPhone device. - */ - public static class SessionTypeIphone extends SessionType { - - /** - * The session is running on an iPhone device. - */ - public SessionTypeIphone() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 97616573; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The session is running on a Linux device. - */ - public static class SessionTypeLinux extends SessionType { - - /** - * The session is running on a Linux device. - */ - public SessionTypeLinux() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1487422871; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The session is running on a Mac device. - */ - public static class SessionTypeMac extends SessionType { - - /** - * The session is running on a Mac device. - */ - public SessionTypeMac() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -612250975; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The session is running on the Opera browser. - */ - public static class SessionTypeOpera extends SessionType { - - /** - * The session is running on the Opera browser. - */ - public SessionTypeOpera() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1463673734; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The session is running on the Safari browser. - */ - public static class SessionTypeSafari extends SessionType { - - /** - * The session is running on the Safari browser. - */ - public SessionTypeSafari() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 710646873; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The session is running on an Ubuntu device. - */ - public static class SessionTypeUbuntu extends SessionType { - - /** - * The session is running on an Ubuntu device. - */ - public SessionTypeUbuntu() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1569680069; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The session is running on an unknown type of device. - */ - public static class SessionTypeUnknown extends SessionType { - - /** - * The session is running on an unknown type of device. - */ - public SessionTypeUnknown() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 233926704; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The session is running on the Vivaldi browser. - */ - public static class SessionTypeVivaldi extends SessionType { - - /** - * The session is running on the Vivaldi browser. - */ - public SessionTypeVivaldi() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1120503279; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The session is running on a Windows device. - */ - public static class SessionTypeWindows extends SessionType { - - /** - * The session is running on a Windows device. - */ - public SessionTypeWindows() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1676512600; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The session is running on an Xbox console. - */ - public static class SessionTypeXbox extends SessionType { - - /** - * The session is running on an Xbox console. - */ - public SessionTypeXbox() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1856216492; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of sessions. - */ - public static class Sessions extends Object { - /** - * List of sessions. - */ - public Session[] sessions; - /** - * Number of days of inactivity before sessions will automatically be terminated; 1-366 days. - */ - public int inactiveSessionTtlDays; - - /** - * Contains a list of sessions. - */ - public Sessions() { - } - - /** - * Contains a list of sessions. - * - * @param sessions List of sessions. - * @param inactiveSessionTtlDays Number of days of inactivity before sessions will automatically be terminated; 1-366 days. - */ - public Sessions(Session[] sessions, int inactiveSessionTtlDays) { - this.sessions = sessions; - this.inactiveSessionTtlDays = inactiveSessionTtlDays; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 842912274; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a section of the application settings. - */ - public abstract static class SettingsSection extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - SettingsSectionAppearance.CONSTRUCTOR, - SettingsSectionAskQuestion.CONSTRUCTOR, - SettingsSectionBusiness.CONSTRUCTOR, - SettingsSectionChatFolders.CONSTRUCTOR, - SettingsSectionDataAndStorage.CONSTRUCTOR, - SettingsSectionDevices.CONSTRUCTOR, - SettingsSectionEditProfile.CONSTRUCTOR, - SettingsSectionFaq.CONSTRUCTOR, - SettingsSectionFeatures.CONSTRUCTOR, - SettingsSectionInAppBrowser.CONSTRUCTOR, - SettingsSectionLanguage.CONSTRUCTOR, - SettingsSectionMyStars.CONSTRUCTOR, - SettingsSectionMyToncoins.CONSTRUCTOR, - SettingsSectionNotifications.CONSTRUCTOR, - SettingsSectionPowerSaving.CONSTRUCTOR, - SettingsSectionPremium.CONSTRUCTOR, - SettingsSectionPrivacyAndSecurity.CONSTRUCTOR, - SettingsSectionPrivacyPolicy.CONSTRUCTOR, - SettingsSectionQrCode.CONSTRUCTOR, - SettingsSectionSearch.CONSTRUCTOR, - SettingsSectionSendGift.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public SettingsSection() { - } - } - - /** - * The appearance section. - */ - public static class SettingsSectionAppearance extends SettingsSection { - /** - * Subsection of the section; may be one of "", "themes", "themes/edit", "themes/create", "wallpapers", "wallpapers/edit", "wallpapers/set", "wallpapers/choose-photo", "your-color/profile", "your-color/profile/add-icons", "your-color/profile/use-gift", "your-color/profile/reset", "your-color/name", "your-color/name/add-icons", "your-color/name/use-gift", "night-mode", "auto-night-mode", "text-size", "text-size/use-system", "message-corners", "animations", "stickers-and-emoji", "stickers-and-emoji/edit", "stickers-and-emoji/trending", "stickers-and-emoji/archived", "stickers-and-emoji/archived/edit", "stickers-and-emoji/emoji", "stickers-and-emoji/emoji/edit", "stickers-and-emoji/emoji/archived", "stickers-and-emoji/emoji/archived/edit", "stickers-and-emoji/emoji/suggest", "stickers-and-emoji/emoji/quick-reaction", "stickers-and-emoji/emoji/quick-reaction/choose", "stickers-and-emoji/suggest-by-emoji", "stickers-and-emoji/large-emoji", "stickers-and-emoji/dynamic-order", "stickers-and-emoji/emoji/show-more", "app-icon", "tap-for-next-media". - */ - public String subsection; - - /** - * The appearance section. - */ - public SettingsSectionAppearance() { - } - - /** - * The appearance section. - * - * @param subsection Subsection of the section; may be one of "", "themes", "themes/edit", "themes/create", "wallpapers", "wallpapers/edit", "wallpapers/set", "wallpapers/choose-photo", "your-color/profile", "your-color/profile/add-icons", "your-color/profile/use-gift", "your-color/profile/reset", "your-color/name", "your-color/name/add-icons", "your-color/name/use-gift", "night-mode", "auto-night-mode", "text-size", "text-size/use-system", "message-corners", "animations", "stickers-and-emoji", "stickers-and-emoji/edit", "stickers-and-emoji/trending", "stickers-and-emoji/archived", "stickers-and-emoji/archived/edit", "stickers-and-emoji/emoji", "stickers-and-emoji/emoji/edit", "stickers-and-emoji/emoji/archived", "stickers-and-emoji/emoji/archived/edit", "stickers-and-emoji/emoji/suggest", "stickers-and-emoji/emoji/quick-reaction", "stickers-and-emoji/emoji/quick-reaction/choose", "stickers-and-emoji/suggest-by-emoji", "stickers-and-emoji/large-emoji", "stickers-and-emoji/dynamic-order", "stickers-and-emoji/emoji/show-more", "app-icon", "tap-for-next-media". - */ - public SettingsSectionAppearance(String subsection) { - this.subsection = subsection; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 946479657; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The "Ask a question" section. - */ - public static class SettingsSectionAskQuestion extends SettingsSection { - - /** - * The "Ask a question" section. - */ - public SettingsSectionAskQuestion() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -977295684; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The "Telegram Business" section. - */ - public static class SettingsSectionBusiness extends SettingsSection { - /** - * Subsection of the section; may be one of "", "do-not-hide-ads". - */ - public String subsection; - - /** - * The "Telegram Business" section. - */ - public SettingsSectionBusiness() { - } - - /** - * The "Telegram Business" section. - * - * @param subsection Subsection of the section; may be one of "", "do-not-hide-ads". - */ - public SettingsSectionBusiness(String subsection) { - this.subsection = subsection; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2035727714; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat folder settings section. - */ - public static class SettingsSectionChatFolders extends SettingsSection { - /** - * Subsection of the section; may be one of "", "edit", "create", "add-recommended", "show-tags", "tab-view". - */ - public String subsection; - - /** - * The chat folder settings section. - */ - public SettingsSectionChatFolders() { - } - - /** - * The chat folder settings section. - * - * @param subsection Subsection of the section; may be one of "", "edit", "create", "add-recommended", "show-tags", "tab-view". - */ - public SettingsSectionChatFolders(String subsection) { - this.subsection = subsection; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1689092795; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The data and storage settings section. - */ - public static class SettingsSectionDataAndStorage extends SettingsSection { - /** - * Subsection of the section; may be one of "", "storage", "storage/edit", "storage/auto-remove", "storage/clear-cache", "storage/max-cache", "usage", "usage/mobile", "usage/wifi", "usage/reset", "usage/roaming", "auto-download/mobile", "auto-download/mobile/enable", "auto-download/mobile/usage", "auto-download/mobile/photos", "auto-download/mobile/stories", "auto-download/mobile/videos", "auto-download/mobile/files", "auto-download/wifi", "auto-download/wifi/enable", "auto-download/wifi/usage", "auto-download/wifi/photos", "auto-download/wifi/stories", "auto-download/wifi/videos", "auto-download/wifi/files", "auto-download/roaming", "auto-download/roaming/enable", "auto-download/roaming/usage", "auto-download/roaming/photos", "auto-download/roaming/stories", "auto-download/roaming/videos", "auto-download/roaming/files", "auto-download/reset", "save-to-photos/chats", "save-to-photos/chats/max-video-size", "save-to-photos/chats/add-exception", "save-to-photos/chats/delete-all", "save-to-photos/groups", "save-to-photos/groups/max-video-size", "save-to-photos/groups/add-exception", "save-to-photos/groups/delete-all", "save-to-photos/channels", "save-to-photos/channels/max-video-size", "save-to-photos/channels/add-exception", "save-to-photos/channels/delete-all", "less-data-calls", "open-links", "share-sheet", "share-sheet/suggested-chats", "share-sheet/suggest-by", "share-sheet/reset", "saved-edited-photos", "pause-music", "raise-to-listen", "raise-to-speak", "show-18-content", "proxy", "proxy/edit", "proxy/use-proxy", "proxy/add-proxy", "proxy/share-list", "proxy/use-for-calls". - */ - public String subsection; - - /** - * The data and storage settings section. - */ - public SettingsSectionDataAndStorage() { - } - - /** - * The data and storage settings section. - * - * @param subsection Subsection of the section; may be one of "", "storage", "storage/edit", "storage/auto-remove", "storage/clear-cache", "storage/max-cache", "usage", "usage/mobile", "usage/wifi", "usage/reset", "usage/roaming", "auto-download/mobile", "auto-download/mobile/enable", "auto-download/mobile/usage", "auto-download/mobile/photos", "auto-download/mobile/stories", "auto-download/mobile/videos", "auto-download/mobile/files", "auto-download/wifi", "auto-download/wifi/enable", "auto-download/wifi/usage", "auto-download/wifi/photos", "auto-download/wifi/stories", "auto-download/wifi/videos", "auto-download/wifi/files", "auto-download/roaming", "auto-download/roaming/enable", "auto-download/roaming/usage", "auto-download/roaming/photos", "auto-download/roaming/stories", "auto-download/roaming/videos", "auto-download/roaming/files", "auto-download/reset", "save-to-photos/chats", "save-to-photos/chats/max-video-size", "save-to-photos/chats/add-exception", "save-to-photos/chats/delete-all", "save-to-photos/groups", "save-to-photos/groups/max-video-size", "save-to-photos/groups/add-exception", "save-to-photos/groups/delete-all", "save-to-photos/channels", "save-to-photos/channels/max-video-size", "save-to-photos/channels/add-exception", "save-to-photos/channels/delete-all", "less-data-calls", "open-links", "share-sheet", "share-sheet/suggested-chats", "share-sheet/suggest-by", "share-sheet/reset", "saved-edited-photos", "pause-music", "raise-to-listen", "raise-to-speak", "show-18-content", "proxy", "proxy/edit", "proxy/use-proxy", "proxy/add-proxy", "proxy/share-list", "proxy/use-for-calls". - */ - public SettingsSectionDataAndStorage(String subsection) { - this.subsection = subsection; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -677345873; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The Devices section. - */ - public static class SettingsSectionDevices extends SettingsSection { - /** - * Subsection of the section; may be one of "", "edit", "link-desktop", "terminate-sessions", "auto-terminate". - */ - public String subsection; - - /** - * The Devices section. - */ - public SettingsSectionDevices() { - } - - /** - * The Devices section. - * - * @param subsection Subsection of the section; may be one of "", "edit", "link-desktop", "terminate-sessions", "auto-terminate". - */ - public SettingsSectionDevices(String subsection) { - this.subsection = subsection; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1987641411; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The profile edit section. - */ - public static class SettingsSectionEditProfile extends SettingsSection { - /** - * Subsection of the section; may be one of "", "set-photo", "first-name", "last-name", "emoji-status", "bio", "birthday", "change-number", "username", "your-color", "channel", "add-account", "log-out", "profile-color/profile", "profile-color/profile/add-icons", "profile-color/profile/use-gift", "profile-color/name", "profile-color/name/add-icons", "profile-color/name/use-gift", "profile-photo/use-emoji". - */ - public String subsection; - - /** - * The profile edit section. - */ - public SettingsSectionEditProfile() { - } - - /** - * The profile edit section. - * - * @param subsection Subsection of the section; may be one of "", "set-photo", "first-name", "last-name", "emoji-status", "bio", "birthday", "change-number", "username", "your-color", "channel", "add-account", "log-out", "profile-color/profile", "profile-color/profile/add-icons", "profile-color/profile/use-gift", "profile-color/name", "profile-color/name/add-icons", "profile-color/name/use-gift", "profile-photo/use-emoji". - */ - public SettingsSectionEditProfile(String subsection) { - this.subsection = subsection; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 654959232; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The FAQ section. - */ - public static class SettingsSectionFaq extends SettingsSection { - - /** - * The FAQ section. - */ - public SettingsSectionFaq() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 689162381; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The "Telegram Features" section. - */ - public static class SettingsSectionFeatures extends SettingsSection { - - /** - * The "Telegram Features" section. - */ - public SettingsSectionFeatures() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 434930782; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The in-app browser settings section. - */ - public static class SettingsSectionInAppBrowser extends SettingsSection { - /** - * Subsection of the section; may be one of "", "enable-browser", "clear-cookies", "clear-cache", "history", "clear-history", "never-open", "clear-list", "search". - */ - public String subsection; - - /** - * The in-app browser settings section. - */ - public SettingsSectionInAppBrowser() { - } - - /** - * The in-app browser settings section. - * - * @param subsection Subsection of the section; may be one of "", "enable-browser", "clear-cookies", "clear-cache", "history", "clear-history", "never-open", "clear-list", "search". - */ - public SettingsSectionInAppBrowser(String subsection) { - this.subsection = subsection; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1762505859; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The application language section. - */ - public static class SettingsSectionLanguage extends SettingsSection { - /** - * Subsection of the section; may be one of "", "show-button" for Show Translate Button toggle, "translate-chats" for Translate Entire Chats toggle, "do-not-translate" - for Do Not Translate language list. - */ - public String subsection; - - /** - * The application language section. - */ - public SettingsSectionLanguage() { - } - - /** - * The application language section. - * - * @param subsection Subsection of the section; may be one of "", "show-button" for Show Translate Button toggle, "translate-chats" for Translate Entire Chats toggle, "do-not-translate" - for Do Not Translate language list. - */ - public SettingsSectionLanguage(String subsection) { - this.subsection = subsection; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2102087062; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The Telegram Star balance and transaction section. - */ - public static class SettingsSectionMyStars extends SettingsSection { - /** - * Subsection of the section; may be one of "", "top-up", "stats", "gift", "earn". - */ - public String subsection; - - /** - * The Telegram Star balance and transaction section. - */ - public SettingsSectionMyStars() { - } - - /** - * The Telegram Star balance and transaction section. - * - * @param subsection Subsection of the section; may be one of "", "top-up", "stats", "gift", "earn". - */ - public SettingsSectionMyStars(String subsection) { - this.subsection = subsection; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 324987676; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The Toncoin balance and transaction section. - */ - public static class SettingsSectionMyToncoins extends SettingsSection { - - /** - * The Toncoin balance and transaction section. - */ - public SettingsSectionMyToncoins() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1628818474; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The notification settings section. - */ - public static class SettingsSectionNotifications extends SettingsSection { - /** - * Subsection of the section; may be one of "", "accounts", "private-chats", "private-chats/edit", "private-chats/show", "private-chats/preview", "private-chats/sound", "private-chats/add-exception", "private-chats/delete-exceptions", "private-chats/light-color", "private-chats/vibrate", "private-chats/priority", "groups", "groups/edit", "groups/show", "groups/preview", "groups/sound", "groups/add-exception", "groups/delete-exceptions", "groups/light-color", "groups/vibrate", "groups/priority", "channels", "channels/edit", "channels/show", "channels/preview", "channels/sound", "channels/add-exception", "channels/delete-exceptions", "channels/light-color", "channels/vibrate", "channels/priority", "stories", "stories/new", "stories/important", "stories/show-sender", "stories/sound", "stories/add-exception", "stories/delete-exceptions", "stories/light-color", "stories/vibrate", "stories/priority", "reactions", "reactions/messages", "reactions/stories", "reactions/show-sender", "reactions/sound", "reactions/light-color", "reactions/vibrate", "reactions/priority", "in-app-sounds", "in-app-vibrate", "in-app-preview", "in-chat-sounds", "in-app-popup", "lock-screen-names", "include-channels", "include-muted-chats", "count-unread-messages", "new-contacts", "pinned-messages", "reset", "web". - */ - public String subsection; - - /** - * The notification settings section. - */ - public SettingsSectionNotifications() { - } - - /** - * The notification settings section. - * - * @param subsection Subsection of the section; may be one of "", "accounts", "private-chats", "private-chats/edit", "private-chats/show", "private-chats/preview", "private-chats/sound", "private-chats/add-exception", "private-chats/delete-exceptions", "private-chats/light-color", "private-chats/vibrate", "private-chats/priority", "groups", "groups/edit", "groups/show", "groups/preview", "groups/sound", "groups/add-exception", "groups/delete-exceptions", "groups/light-color", "groups/vibrate", "groups/priority", "channels", "channels/edit", "channels/show", "channels/preview", "channels/sound", "channels/add-exception", "channels/delete-exceptions", "channels/light-color", "channels/vibrate", "channels/priority", "stories", "stories/new", "stories/important", "stories/show-sender", "stories/sound", "stories/add-exception", "stories/delete-exceptions", "stories/light-color", "stories/vibrate", "stories/priority", "reactions", "reactions/messages", "reactions/stories", "reactions/show-sender", "reactions/sound", "reactions/light-color", "reactions/vibrate", "reactions/priority", "in-app-sounds", "in-app-vibrate", "in-app-preview", "in-chat-sounds", "in-app-popup", "lock-screen-names", "include-channels", "include-muted-chats", "count-unread-messages", "new-contacts", "pinned-messages", "reset", "web". - */ - public SettingsSectionNotifications(String subsection) { - this.subsection = subsection; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1517744502; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The power saving settings section. - */ - public static class SettingsSectionPowerSaving extends SettingsSection { - /** - * Subsection of the section; may be one of "", "videos", "gifs", "stickers", "emoji", "effects", "preload", "background", "call-animations", "particles", "transitions". - */ - public String subsection; - - /** - * The power saving settings section. - */ - public SettingsSectionPowerSaving() { - } - - /** - * The power saving settings section. - * - * @param subsection Subsection of the section; may be one of "", "videos", "gifs", "stickers", "emoji", "effects", "preload", "background", "call-animations", "particles", "transitions". - */ - public SettingsSectionPowerSaving(String subsection) { - this.subsection = subsection; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1041090092; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The "Telegram Premium" section. - */ - public static class SettingsSectionPremium extends SettingsSection { - - /** - * The "Telegram Premium" section. - */ - public SettingsSectionPremium() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1635573221; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The privacy and security section. - */ - public static class SettingsSectionPrivacyAndSecurity extends SettingsSection { - /** - * Subsection of the section; may be one of "", "blocked", "blocked/edit", "blocked/block-user", "blocked/block-user/chats", "blocked/block-user/contacts", "active-websites", "active-websites/edit", "active-websites/disconnect-all", "passcode", "passcode/disable", "passcode/change", "passcode/auto-lock", "passcode/face-id", "passcode/fingerprint", "2sv", "2sv/change", "2sv/disable", "2sv/change-email", "passkey", "passkey/create", "auto-delete", "auto-delete/set-custom", "login-email", "phone-number", "phone-number/never", "phone-number/always", "last-seen", "last-seen/never", "last-seen/always", "last-seen/hide-read-time", "profile-photos", "profile-photos/never", "profile-photos/always", "profile-photos/set-public", "profile-photos/update-public", "profile-photos/remove-public", "bio", "bio/never", "bio/always", "gifts", "gifts/show-icon", "gifts/never", "gifts/always", "gifts/accepted-types", "birthday", "birthday/add", "birthday/never", "birthday/always", "saved-music", "saved-music/never", "saved-music/always", "forwards", "forwards/never", "forwards/always", "calls", "calls/never", "calls/always", "calls/p2p", "calls/p2p/never", "calls/p2p/always", "calls/ios-integration", "voice", "voice/never", "voice/always", "messages", "messages/set-price", "messages/exceptions", "invites", "invites/never", "invites/always", "self-destruct", "data-settings", "data-settings/sync-contacts", "data-settings/delete-synced", "data-settings/suggest-contacts", "data-settings/delete-cloud-drafts", "data-settings/clear-payment-info", "data-settings/link-previews", "data-settings/bot-settings", "data-settings/map-provider", "archive-and-mute". - */ - public String subsection; - - /** - * The privacy and security section. - */ - public SettingsSectionPrivacyAndSecurity() { - } - - /** - * The privacy and security section. - * - * @param subsection Subsection of the section; may be one of "", "blocked", "blocked/edit", "blocked/block-user", "blocked/block-user/chats", "blocked/block-user/contacts", "active-websites", "active-websites/edit", "active-websites/disconnect-all", "passcode", "passcode/disable", "passcode/change", "passcode/auto-lock", "passcode/face-id", "passcode/fingerprint", "2sv", "2sv/change", "2sv/disable", "2sv/change-email", "passkey", "passkey/create", "auto-delete", "auto-delete/set-custom", "login-email", "phone-number", "phone-number/never", "phone-number/always", "last-seen", "last-seen/never", "last-seen/always", "last-seen/hide-read-time", "profile-photos", "profile-photos/never", "profile-photos/always", "profile-photos/set-public", "profile-photos/update-public", "profile-photos/remove-public", "bio", "bio/never", "bio/always", "gifts", "gifts/show-icon", "gifts/never", "gifts/always", "gifts/accepted-types", "birthday", "birthday/add", "birthday/never", "birthday/always", "saved-music", "saved-music/never", "saved-music/always", "forwards", "forwards/never", "forwards/always", "calls", "calls/never", "calls/always", "calls/p2p", "calls/p2p/never", "calls/p2p/always", "calls/ios-integration", "voice", "voice/never", "voice/always", "messages", "messages/set-price", "messages/exceptions", "invites", "invites/never", "invites/always", "self-destruct", "data-settings", "data-settings/sync-contacts", "data-settings/delete-synced", "data-settings/suggest-contacts", "data-settings/delete-cloud-drafts", "data-settings/clear-payment-info", "data-settings/link-previews", "data-settings/bot-settings", "data-settings/map-provider", "archive-and-mute". - */ - public SettingsSectionPrivacyAndSecurity(String subsection) { - this.subsection = subsection; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1251665482; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The "Privacy Policy" section. - */ - public static class SettingsSectionPrivacyPolicy extends SettingsSection { - - /** - * The "Privacy Policy" section. - */ - public SettingsSectionPrivacyPolicy() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2068087969; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The current user's QR code section. - */ - public static class SettingsSectionQrCode extends SettingsSection { - /** - * Subsection of the section; may be one of "", "share", "scan". - */ - public String subsection; - - /** - * The current user's QR code section. - */ - public SettingsSectionQrCode() { - } - - /** - * The current user's QR code section. - * - * @param subsection Subsection of the section; may be one of "", "share", "scan". - */ - public SettingsSectionQrCode(String subsection) { - this.subsection = subsection; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1816314456; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Search in Settings. - */ - public static class SettingsSectionSearch extends SettingsSection { - - /** - * Search in Settings. - */ - public SettingsSectionSearch() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 686700184; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The "Send a gift" section. - */ - public static class SettingsSectionSendGift extends SettingsSection { - /** - * Subsection of the section; may be one of "", "self". - */ - public String subsection; - - /** - * The "Send a gift" section. - */ - public SettingsSectionSendGift() { - } - - /** - * The "Send a gift" section. - * - * @param subsection Subsection of the section; may be one of "", "self". - */ - public SettingsSectionSendGift(String subsection) { - this.subsection = subsection; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -326078; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a chat shared with a bot. - */ - public static class SharedChat extends Object { - /** - * Chat identifier. - */ - public long chatId; - /** - * Title of the chat; for bots only. - */ - public String title; - /** - * Username of the chat; for bots only. - */ - public String username; - /** - * Photo of the chat; for bots only; may be null. - */ - @Nullable public Photo photo; - - /** - * Contains information about a chat shared with a bot. - */ - public SharedChat() { - } - - /** - * Contains information about a chat shared with a bot. - * - * @param chatId Chat identifier. - * @param title Title of the chat; for bots only. - * @param username Username of the chat; for bots only. - * @param photo Photo of the chat; for bots only; may be null. - */ - public SharedChat(long chatId, String title, String username, Photo photo) { - this.chatId = chatId; - this.title = title; - this.username = username; - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1250406426; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a user shared with a bot. - */ - public static class SharedUser extends Object { - /** - * User identifier. - */ - public long userId; - /** - * First name of the user; for bots only. - */ - public String firstName; - /** - * Last name of the user; for bots only. - */ - public String lastName; - /** - * Username of the user; for bots only. - */ - public String username; - /** - * Profile photo of the user; for bots only; may be null. - */ - @Nullable public Photo photo; - - /** - * Contains information about a user shared with a bot. - */ - public SharedUser() { - } - - /** - * Contains information about a user shared with a bot. - * - * @param userId User identifier. - * @param firstName First name of the user; for bots only. - * @param lastName Last name of the user; for bots only. - * @param username Username of the user; for bots only. - * @param photo Profile photo of the user; for bots only; may be null. - */ - public SharedUser(long userId, String firstName, String lastName, String username, Photo photo) { - this.userId = userId; - this.firstName = firstName; - this.lastName = lastName; - this.username = username; - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 293020919; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * One shipping option. - */ - public static class ShippingOption extends Object { - /** - * Shipping option identifier. - */ - public String id; - /** - * Option title. - */ - public String title; - /** - * A list of objects used to calculate the total shipping costs. - */ - public LabeledPricePart[] priceParts; - - /** - * One shipping option. - */ - public ShippingOption() { - } - - /** - * One shipping option. - * - * @param id Shipping option identifier. - * @param title Option title. - * @param priceParts A list of objects used to calculate the total shipping costs. - */ - public ShippingOption(String id, String title, LabeledPricePart[] priceParts) { - this.id = id; - this.title = title; - this.priceParts = priceParts; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1425690001; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes result of speech recognition in a voice note. - */ - public abstract static class SpeechRecognitionResult extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - SpeechRecognitionResultPending.CONSTRUCTOR, - SpeechRecognitionResultText.CONSTRUCTOR, - SpeechRecognitionResultError.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public SpeechRecognitionResult() { - } - } - - /** - * The speech recognition is ongoing. - */ - public static class SpeechRecognitionResultPending extends SpeechRecognitionResult { - /** - * Partially recognized text. - */ - public String partialText; - - /** - * The speech recognition is ongoing. - */ - public SpeechRecognitionResultPending() { - } - - /** - * The speech recognition is ongoing. - * - * @param partialText Partially recognized text. - */ - public SpeechRecognitionResultPending(String partialText) { - this.partialText = partialText; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1631810048; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The speech recognition successfully finished. - */ - public static class SpeechRecognitionResultText extends SpeechRecognitionResult { - /** - * Recognized text. - */ - public String text; - - /** - * The speech recognition successfully finished. - */ - public SpeechRecognitionResultText() { - } - - /** - * The speech recognition successfully finished. - * - * @param text Recognized text. - */ - public SpeechRecognitionResultText(String text) { - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2132377123; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The speech recognition failed. - */ - public static class SpeechRecognitionResultError extends SpeechRecognitionResult { - /** - * Recognition error. An error with a message "MSG_VOICE_TOO_LONG" is returned when media duration is too big to be recognized. - */ - public Error error; - - /** - * The speech recognition failed. - */ - public SpeechRecognitionResultError() { - } - - /** - * The speech recognition failed. - * - * @param error Recognition error. An error with a message "MSG_VOICE_TOO_LONG" is returned when media duration is too big to be recognized. - */ - public SpeechRecognitionResultError(Error error) { - this.error = error; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 164774908; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a sponsored chat. - */ - public static class SponsoredChat extends Object { - /** - * Unique identifier of this result. - */ - public long uniqueId; - /** - * Chat identifier. - */ - public long chatId; - /** - * Additional optional information about the sponsor to be shown along with the chat. - */ - public String sponsorInfo; - /** - * If non-empty, additional information about the sponsored chat to be shown along with the chat. - */ - public String additionalInfo; - - /** - * Describes a sponsored chat. - */ - public SponsoredChat() { - } - - /** - * Describes a sponsored chat. - * - * @param uniqueId Unique identifier of this result. - * @param chatId Chat identifier. - * @param sponsorInfo Additional optional information about the sponsor to be shown along with the chat. - * @param additionalInfo If non-empty, additional information about the sponsored chat to be shown along with the chat. - */ - public SponsoredChat(long uniqueId, long chatId, String sponsorInfo, String additionalInfo) { - this.uniqueId = uniqueId; - this.chatId = chatId; - this.sponsorInfo = sponsorInfo; - this.additionalInfo = additionalInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -325763489; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of sponsored chats. - */ - public static class SponsoredChats extends Object { - /** - * List of sponsored chats. - */ - public SponsoredChat[] chats; - - /** - * Contains a list of sponsored chats. - */ - public SponsoredChats() { - } - - /** - * Contains a list of sponsored chats. - * - * @param chats List of sponsored chats. - */ - public SponsoredChats(SponsoredChat[] chats) { - this.chats = chats; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 536300641; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a sponsored message. - */ - public static class SponsoredMessage extends Object { - /** - * Message identifier; unique for the chat to which the sponsored message belongs among both ordinary and sponsored messages. - */ - public long messageId; - /** - * True, if the message needs to be labeled as "recommended" instead of "sponsored". - */ - public boolean isRecommended; - /** - * True, if the message can be reported to Telegram moderators through reportChatSponsoredMessage. - */ - public boolean canBeReported; - /** - * Content of the message. Currently, can be only of the types messageText, messageAnimation, messagePhoto, or messageVideo. Video messages can be viewed fullscreen. - */ - public MessageContent content; - /** - * Information about the sponsor of the message. - */ - public AdvertisementSponsor sponsor; - /** - * Title of the sponsored message. - */ - public String title; - /** - * Text for the message action button. - */ - public String buttonText; - /** - * Identifier of the accent color for title, button text and message background. - */ - public int accentColorId; - /** - * Identifier of a custom emoji to be shown on the message background; 0 if none. - */ - public long backgroundCustomEmojiId; - /** - * If non-empty, additional information about the sponsored message to be shown along with the message. - */ - public String additionalInfo; - - /** - * Describes a sponsored message. - */ - public SponsoredMessage() { - } - - /** - * Describes a sponsored message. - * - * @param messageId Message identifier; unique for the chat to which the sponsored message belongs among both ordinary and sponsored messages. - * @param isRecommended True, if the message needs to be labeled as "recommended" instead of "sponsored". - * @param canBeReported True, if the message can be reported to Telegram moderators through reportChatSponsoredMessage. - * @param content Content of the message. Currently, can be only of the types messageText, messageAnimation, messagePhoto, or messageVideo. Video messages can be viewed fullscreen. - * @param sponsor Information about the sponsor of the message. - * @param title Title of the sponsored message. - * @param buttonText Text for the message action button. - * @param accentColorId Identifier of the accent color for title, button text and message background. - * @param backgroundCustomEmojiId Identifier of a custom emoji to be shown on the message background; 0 if none. - * @param additionalInfo If non-empty, additional information about the sponsored message to be shown along with the message. - */ - public SponsoredMessage(long messageId, boolean isRecommended, boolean canBeReported, MessageContent content, AdvertisementSponsor sponsor, String title, String buttonText, int accentColorId, long backgroundCustomEmojiId, String additionalInfo) { - this.messageId = messageId; - this.isRecommended = isRecommended; - this.canBeReported = canBeReported; - this.content = content; - this.sponsor = sponsor; - this.title = title; - this.buttonText = buttonText; - this.accentColorId = accentColorId; - this.backgroundCustomEmojiId = backgroundCustomEmojiId; - this.additionalInfo = additionalInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1521782216; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of sponsored messages. - */ - public static class SponsoredMessages extends Object { - /** - * List of sponsored messages. - */ - public SponsoredMessage[] messages; - /** - * The minimum number of messages between shown sponsored messages, or 0 if only one sponsored message must be shown after all ordinary messages. - */ - public int messagesBetween; - - /** - * Contains a list of sponsored messages. - */ - public SponsoredMessages() { - } - - /** - * Contains a list of sponsored messages. - * - * @param messages List of sponsored messages. - * @param messagesBetween The minimum number of messages between shown sponsored messages, or 0 if only one sponsored message must be shown after all ordinary messages. - */ - public SponsoredMessages(SponsoredMessage[] messages, int messagesBetween) { - this.messages = messages; - this.messagesBetween = messagesBetween; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -537674389; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes state of the stake dice. - */ - public static class StakeDiceState extends Object { - /** - * Hash of the state to use for sending the next dice; may be empty if the stake dice can't be sent by the current user. - */ - public String stateHash; - /** - * The Toncoin amount that was staked in the previous roll; in the smallest units of the currency. - */ - public long stakeToncoinAmount; - /** - * The amounts of Toncoins that are suggested to be staked; in the smallest units of the currency. - */ - public long[] suggestedStakeToncoinAmounts; - /** - * The number of rolled sixes towards the streak; 0-2. - */ - public int currentStreak; - /** - * The number of Toncoins received by the user for each 1000 Toncoins staked if the dice outcome is 1-6 correspondingly; may be empty if the stake dice can't be sent by the current user. - */ - public int[] prizePerMille; - /** - * The number of Toncoins received by the user for each 1000 Toncoins staked if the dice outcome is 6 three times in a row with the same stake. - */ - public int streakPrizePerMille; - - /** - * Describes state of the stake dice. - */ - public StakeDiceState() { - } - - /** - * Describes state of the stake dice. - * - * @param stateHash Hash of the state to use for sending the next dice; may be empty if the stake dice can't be sent by the current user. - * @param stakeToncoinAmount The Toncoin amount that was staked in the previous roll; in the smallest units of the currency. - * @param suggestedStakeToncoinAmounts The amounts of Toncoins that are suggested to be staked; in the smallest units of the currency. - * @param currentStreak The number of rolled sixes towards the streak; 0-2. - * @param prizePerMille The number of Toncoins received by the user for each 1000 Toncoins staked if the dice outcome is 1-6 correspondingly; may be empty if the stake dice can't be sent by the current user. - * @param streakPrizePerMille The number of Toncoins received by the user for each 1000 Toncoins staked if the dice outcome is 6 three times in a row with the same stake. - */ - public StakeDiceState(String stateHash, long stakeToncoinAmount, long[] suggestedStakeToncoinAmounts, int currentStreak, int[] prizePerMille, int streakPrizePerMille) { - this.stateHash = stateHash; - this.stakeToncoinAmount = stakeToncoinAmount; - this.suggestedStakeToncoinAmounts = suggestedStakeToncoinAmounts; - this.currentStreak = currentStreak; - this.prizePerMille = prizePerMille; - this.streakPrizePerMille = streakPrizePerMille; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2004711564; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a possibly non-integer Telegram Star amount. - */ - public static class StarAmount extends Object { - /** - * The integer Telegram Star amount rounded to 0. - */ - public long starCount; - /** - * The number of 1/1000000000 shares of Telegram Stars; from -999999999 to 999999999. - */ - public int nanostarCount; - - /** - * Describes a possibly non-integer Telegram Star amount. - */ - public StarAmount() { - } - - /** - * Describes a possibly non-integer Telegram Star amount. - * - * @param starCount The integer Telegram Star amount rounded to 0. - * @param nanostarCount The number of 1/1000000000 shares of Telegram Stars; from -999999999 to 999999999. - */ - public StarAmount(long starCount, int nanostarCount) { - this.starCount = starCount; - this.nanostarCount = nanostarCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1863216512; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a number of Telegram Stars. - */ - public static class StarCount extends Object { - /** - * Number of Telegram Stars. - */ - public long starCount; - - /** - * Contains a number of Telegram Stars. - */ - public StarCount() { - } - - /** - * Contains a number of Telegram Stars. - * - * @param starCount Number of Telegram Stars. - */ - public StarCount(long starCount) { - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1566395144; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an option for creating of Telegram Star giveaway. Use telegramPaymentPurposeStarGiveaway for out-of-store payments. - */ - public static class StarGiveawayPaymentOption extends Object { - /** - * ISO 4217 currency code for the payment. - */ - public String currency; - /** - * The amount to pay, in the smallest units of the currency. - */ - public long amount; - /** - * Number of Telegram Stars that will be distributed among winners. - */ - public long starCount; - /** - * Identifier of the store product associated with the option; may be empty if none. - */ - public String storeProductId; - /** - * Number of times the chat will be boosted for one year if the option is chosen. - */ - public int yearlyBoostCount; - /** - * Allowed options for the number of giveaway winners. - */ - public StarGiveawayWinnerOption[] winnerOptions; - /** - * True, if the option must be chosen by default. - */ - public boolean isDefault; - /** - * True, if the option must be shown only in the full list of payment options. - */ - public boolean isAdditional; - - /** - * Describes an option for creating of Telegram Star giveaway. Use telegramPaymentPurposeStarGiveaway for out-of-store payments. - */ - public StarGiveawayPaymentOption() { - } - - /** - * Describes an option for creating of Telegram Star giveaway. Use telegramPaymentPurposeStarGiveaway for out-of-store payments. - * - * @param currency ISO 4217 currency code for the payment. - * @param amount The amount to pay, in the smallest units of the currency. - * @param starCount Number of Telegram Stars that will be distributed among winners. - * @param storeProductId Identifier of the store product associated with the option; may be empty if none. - * @param yearlyBoostCount Number of times the chat will be boosted for one year if the option is chosen. - * @param winnerOptions Allowed options for the number of giveaway winners. - * @param isDefault True, if the option must be chosen by default. - * @param isAdditional True, if the option must be shown only in the full list of payment options. - */ - public StarGiveawayPaymentOption(String currency, long amount, long starCount, String storeProductId, int yearlyBoostCount, StarGiveawayWinnerOption[] winnerOptions, boolean isDefault, boolean isAdditional) { - this.currency = currency; - this.amount = amount; - this.starCount = starCount; - this.storeProductId = storeProductId; - this.yearlyBoostCount = yearlyBoostCount; - this.winnerOptions = winnerOptions; - this.isDefault = isDefault; - this.isAdditional = isAdditional; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 565089625; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of options for creating of Telegram Star giveaway. - */ - public static class StarGiveawayPaymentOptions extends Object { - /** - * The list of options. - */ - public StarGiveawayPaymentOption[] options; - - /** - * Contains a list of options for creating of Telegram Star giveaway. - */ - public StarGiveawayPaymentOptions() { - } - - /** - * Contains a list of options for creating of Telegram Star giveaway. - * - * @param options The list of options. - */ - public StarGiveawayPaymentOptions(StarGiveawayPaymentOption[] options) { - this.options = options; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1216716679; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an option for the number of winners of a Telegram Star giveaway. - */ - public static class StarGiveawayWinnerOption extends Object { - /** - * The number of users that will be chosen as winners. - */ - public int winnerCount; - /** - * The number of Telegram Stars that will be won by the winners of the giveaway. - */ - public long wonStarCount; - /** - * True, if the option must be chosen by default. - */ - public boolean isDefault; - - /** - * Describes an option for the number of winners of a Telegram Star giveaway. - */ - public StarGiveawayWinnerOption() { - } - - /** - * Describes an option for the number of winners of a Telegram Star giveaway. - * - * @param winnerCount The number of users that will be chosen as winners. - * @param wonStarCount The number of Telegram Stars that will be won by the winners of the giveaway. - * @param isDefault True, if the option must be chosen by default. - */ - public StarGiveawayWinnerOption(int winnerCount, long wonStarCount, boolean isDefault) { - this.winnerCount = winnerCount; - this.wonStarCount = wonStarCount; - this.isDefault = isDefault; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -865888761; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an option for buying Telegram Stars. Use telegramPaymentPurposeStars for out-of-store payments. - */ - public static class StarPaymentOption extends Object { - /** - * ISO 4217 currency code for the payment. - */ - public String currency; - /** - * The amount to pay, in the smallest units of the currency. - */ - public long amount; - /** - * Number of Telegram Stars that will be purchased. - */ - public long starCount; - /** - * Identifier of the store product associated with the option; may be empty if none. - */ - public String storeProductId; - /** - * True, if the option must be shown only in the full list of payment options. - */ - public boolean isAdditional; - - /** - * Describes an option for buying Telegram Stars. Use telegramPaymentPurposeStars for out-of-store payments. - */ - public StarPaymentOption() { - } - - /** - * Describes an option for buying Telegram Stars. Use telegramPaymentPurposeStars for out-of-store payments. - * - * @param currency ISO 4217 currency code for the payment. - * @param amount The amount to pay, in the smallest units of the currency. - * @param starCount Number of Telegram Stars that will be purchased. - * @param storeProductId Identifier of the store product associated with the option; may be empty if none. - * @param isAdditional True, if the option must be shown only in the full list of payment options. - */ - public StarPaymentOption(String currency, long amount, long starCount, String storeProductId, boolean isAdditional) { - this.currency = currency; - this.amount = amount; - this.starCount = starCount; - this.storeProductId = storeProductId; - this.isAdditional = isAdditional; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1364056047; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of options for buying Telegram Stars. - */ - public static class StarPaymentOptions extends Object { - /** - * The list of options. - */ - public StarPaymentOption[] options; - - /** - * Contains a list of options for buying Telegram Stars. - */ - public StarPaymentOptions() { - } - - /** - * Contains a list of options for buying Telegram Stars. - * - * @param options The list of options. - */ - public StarPaymentOptions(StarPaymentOption[] options) { - this.options = options; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -423720498; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A detailed statistics about Telegram Stars earned by a user or a chat. - */ - public static class StarRevenueStatistics extends Object { - /** - * A graph containing amount of revenue in a given day. - */ - public StatisticalGraph revenueByDayGraph; - /** - * Telegram Star revenue status. - */ - public StarRevenueStatus status; - /** - * Current conversion rate of a Telegram Star to USD. - */ - public double usdRate; - - /** - * A detailed statistics about Telegram Stars earned by a user or a chat. - */ - public StarRevenueStatistics() { - } - - /** - * A detailed statistics about Telegram Stars earned by a user or a chat. - * - * @param revenueByDayGraph A graph containing amount of revenue in a given day. - * @param status Telegram Star revenue status. - * @param usdRate Current conversion rate of a Telegram Star to USD. - */ - public StarRevenueStatistics(StatisticalGraph revenueByDayGraph, StarRevenueStatus status, double usdRate) { - this.revenueByDayGraph = revenueByDayGraph; - this.status = status; - this.usdRate = usdRate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1121086889; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about Telegram Stars earned by a user or a chat. - */ - public static class StarRevenueStatus extends Object { - /** - * Total Telegram Star amount earned. - */ - public StarAmount totalAmount; - /** - * The Telegram Star amount that isn't withdrawn yet. - */ - public StarAmount currentAmount; - /** - * The Telegram Star amount that is available for withdrawal. - */ - public StarAmount availableAmount; - /** - * True, if Telegram Stars can be withdrawn now or later. - */ - public boolean withdrawalEnabled; - /** - * Time left before the next withdrawal can be started, in seconds; 0 if withdrawal can be started now. - */ - public int nextWithdrawalIn; - - /** - * Contains information about Telegram Stars earned by a user or a chat. - */ - public StarRevenueStatus() { - } - - /** - * Contains information about Telegram Stars earned by a user or a chat. - * - * @param totalAmount Total Telegram Star amount earned. - * @param currentAmount The Telegram Star amount that isn't withdrawn yet. - * @param availableAmount The Telegram Star amount that is available for withdrawal. - * @param withdrawalEnabled True, if Telegram Stars can be withdrawn now or later. - * @param nextWithdrawalIn Time left before the next withdrawal can be started, in seconds; 0 if withdrawal can be started now. - */ - public StarRevenueStatus(StarAmount totalAmount, StarAmount currentAmount, StarAmount availableAmount, boolean withdrawalEnabled, int nextWithdrawalIn) { - this.totalAmount = totalAmount; - this.currentAmount = currentAmount; - this.availableAmount = availableAmount; - this.withdrawalEnabled = withdrawalEnabled; - this.nextWithdrawalIn = nextWithdrawalIn; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2006266600; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about subscription to a channel chat, a bot, or a business account that was paid in Telegram Stars. - */ - public static class StarSubscription extends Object { - /** - * Unique identifier of the subscription. - */ - public String id; - /** - * Identifier of the chat that is subscribed. - */ - public long chatId; - /** - * Point in time (Unix timestamp) when the subscription will expire or expired. - */ - public int expirationDate; - /** - * True, if the subscription was canceled. - */ - public boolean isCanceled; - /** - * True, if the subscription expires soon and there are no enough Telegram Stars on the user's balance to extend it. - */ - public boolean isExpiring; - /** - * The subscription plan. - */ - public StarSubscriptionPricing pricing; - /** - * Type of the subscription. - */ - public StarSubscriptionType type; - - /** - * Contains information about subscription to a channel chat, a bot, or a business account that was paid in Telegram Stars. - */ - public StarSubscription() { - } - - /** - * Contains information about subscription to a channel chat, a bot, or a business account that was paid in Telegram Stars. - * - * @param id Unique identifier of the subscription. - * @param chatId Identifier of the chat that is subscribed. - * @param expirationDate Point in time (Unix timestamp) when the subscription will expire or expired. - * @param isCanceled True, if the subscription was canceled. - * @param isExpiring True, if the subscription expires soon and there are no enough Telegram Stars on the user's balance to extend it. - * @param pricing The subscription plan. - * @param type Type of the subscription. - */ - public StarSubscription(String id, long chatId, int expirationDate, boolean isCanceled, boolean isExpiring, StarSubscriptionPricing pricing, StarSubscriptionType type) { - this.id = id; - this.chatId = chatId; - this.expirationDate = expirationDate; - this.isCanceled = isCanceled; - this.isExpiring = isExpiring; - this.pricing = pricing; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 976753141; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes subscription plan paid in Telegram Stars. - */ - public static class StarSubscriptionPricing extends Object { - /** - * The number of seconds between consecutive Telegram Star debiting. - */ - public int period; - /** - * The Telegram Star amount that must be paid for each period. - */ - public long starCount; - - /** - * Describes subscription plan paid in Telegram Stars. - */ - public StarSubscriptionPricing() { - } - - /** - * Describes subscription plan paid in Telegram Stars. - * - * @param period The number of seconds between consecutive Telegram Star debiting. - * @param starCount The Telegram Star amount that must be paid for each period. - */ - public StarSubscriptionPricing(int period, long starCount) { - this.period = period; - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1767733162; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of subscription paid in Telegram Stars. - */ - public abstract static class StarSubscriptionType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - StarSubscriptionTypeChannel.CONSTRUCTOR, - StarSubscriptionTypeBot.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public StarSubscriptionType() { - } - } - - /** - * Describes a subscription to a channel chat. - */ - public static class StarSubscriptionTypeChannel extends StarSubscriptionType { - /** - * True, if the subscription is active and the user can use the method reuseStarSubscription to join the subscribed chat again. - */ - public boolean canReuse; - /** - * The invite link that can be used to renew the subscription if it has been expired; may be empty, if the link isn't available anymore. - */ - public String inviteLink; - - /** - * Describes a subscription to a channel chat. - */ - public StarSubscriptionTypeChannel() { - } - - /** - * Describes a subscription to a channel chat. - * - * @param canReuse True, if the subscription is active and the user can use the method reuseStarSubscription to join the subscribed chat again. - * @param inviteLink The invite link that can be used to renew the subscription if it has been expired; may be empty, if the link isn't available anymore. - */ - public StarSubscriptionTypeChannel(boolean canReuse, String inviteLink) { - this.canReuse = canReuse; - this.inviteLink = inviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1030048011; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a subscription in a bot or a business account. - */ - public static class StarSubscriptionTypeBot extends StarSubscriptionType { - /** - * True, if the subscription was canceled by the bot and can't be extended. - */ - public boolean isCanceledByBot; - /** - * Subscription invoice title. - */ - public String title; - /** - * Subscription invoice photo. - */ - public Photo photo; - /** - * The link to the subscription invoice. - */ - public String invoiceLink; - - /** - * Describes a subscription in a bot or a business account. - */ - public StarSubscriptionTypeBot() { - } - - /** - * Describes a subscription in a bot or a business account. - * - * @param isCanceledByBot True, if the subscription was canceled by the bot and can't be extended. - * @param title Subscription invoice title. - * @param photo Subscription invoice photo. - * @param invoiceLink The link to the subscription invoice. - */ - public StarSubscriptionTypeBot(boolean isCanceledByBot, String title, Photo photo, String invoiceLink) { - this.isCanceledByBot = isCanceledByBot; - this.title = title; - this.photo = photo; - this.invoiceLink = invoiceLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 226024914; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of Telegram Star subscriptions. - */ - public static class StarSubscriptions extends Object { - /** - * The amount of owned Telegram Stars. - */ - public StarAmount starAmount; - /** - * List of subscriptions for Telegram Stars. - */ - public StarSubscription[] subscriptions; - /** - * The number of Telegram Stars required to buy to extend subscriptions expiring soon. - */ - public long requiredStarCount; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Represents a list of Telegram Star subscriptions. - */ - public StarSubscriptions() { - } - - /** - * Represents a list of Telegram Star subscriptions. - * - * @param starAmount The amount of owned Telegram Stars. - * @param subscriptions List of subscriptions for Telegram Stars. - * @param requiredStarCount The number of Telegram Stars required to buy to extend subscriptions expiring soon. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public StarSubscriptions(StarAmount starAmount, StarSubscription[] subscriptions, long requiredStarCount, String nextOffset) { - this.starAmount = starAmount; - this.subscriptions = subscriptions; - this.requiredStarCount = requiredStarCount; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 151169395; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a transaction changing the amount of owned Telegram Stars. - */ - public static class StarTransaction extends Object { - /** - * Unique identifier of the transaction. - */ - public String id; - /** - * The amount of added owned Telegram Stars; negative for outgoing transactions. - */ - public StarAmount starAmount; - /** - * True, if the transaction is a refund of a previous transaction. - */ - public boolean isRefund; - /** - * Point in time (Unix timestamp) when the transaction was completed. - */ - public int date; - /** - * Type of the transaction. - */ - public StarTransactionType type; - - /** - * Represents a transaction changing the amount of owned Telegram Stars. - */ - public StarTransaction() { - } - - /** - * Represents a transaction changing the amount of owned Telegram Stars. - * - * @param id Unique identifier of the transaction. - * @param starAmount The amount of added owned Telegram Stars; negative for outgoing transactions. - * @param isRefund True, if the transaction is a refund of a previous transaction. - * @param date Point in time (Unix timestamp) when the transaction was completed. - * @param type Type of the transaction. - */ - public StarTransaction(String id, StarAmount starAmount, boolean isRefund, int date, StarTransactionType type) { - this.id = id; - this.starAmount = starAmount; - this.isRefund = isRefund; - this.date = date; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2139228816; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of transaction with Telegram Stars. - */ - public abstract static class StarTransactionType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - StarTransactionTypePremiumBotDeposit.CONSTRUCTOR, - StarTransactionTypeAppStoreDeposit.CONSTRUCTOR, - StarTransactionTypeGooglePlayDeposit.CONSTRUCTOR, - StarTransactionTypeFragmentDeposit.CONSTRUCTOR, - StarTransactionTypeUserDeposit.CONSTRUCTOR, - StarTransactionTypeGiveawayDeposit.CONSTRUCTOR, - StarTransactionTypeFragmentWithdrawal.CONSTRUCTOR, - StarTransactionTypeTelegramAdsWithdrawal.CONSTRUCTOR, - StarTransactionTypeTelegramApiUsage.CONSTRUCTOR, - StarTransactionTypeBotPaidMediaPurchase.CONSTRUCTOR, - StarTransactionTypeBotPaidMediaSale.CONSTRUCTOR, - StarTransactionTypeChannelPaidMediaPurchase.CONSTRUCTOR, - StarTransactionTypeChannelPaidMediaSale.CONSTRUCTOR, - StarTransactionTypeBotInvoicePurchase.CONSTRUCTOR, - StarTransactionTypeBotInvoiceSale.CONSTRUCTOR, - StarTransactionTypeBotSubscriptionPurchase.CONSTRUCTOR, - StarTransactionTypeBotSubscriptionSale.CONSTRUCTOR, - StarTransactionTypeChannelSubscriptionPurchase.CONSTRUCTOR, - StarTransactionTypeChannelSubscriptionSale.CONSTRUCTOR, - StarTransactionTypeGiftAuctionBid.CONSTRUCTOR, - StarTransactionTypeGiftPurchase.CONSTRUCTOR, - StarTransactionTypeGiftPurchaseOffer.CONSTRUCTOR, - StarTransactionTypeGiftTransfer.CONSTRUCTOR, - StarTransactionTypeGiftOriginalDetailsDrop.CONSTRUCTOR, - StarTransactionTypeGiftSale.CONSTRUCTOR, - StarTransactionTypeGiftUpgrade.CONSTRUCTOR, - StarTransactionTypeGiftUpgradePurchase.CONSTRUCTOR, - StarTransactionTypeUpgradedGiftPurchase.CONSTRUCTOR, - StarTransactionTypeUpgradedGiftSale.CONSTRUCTOR, - StarTransactionTypeChannelPaidReactionSend.CONSTRUCTOR, - StarTransactionTypeChannelPaidReactionReceive.CONSTRUCTOR, - StarTransactionTypeAffiliateProgramCommission.CONSTRUCTOR, - StarTransactionTypePaidMessageSend.CONSTRUCTOR, - StarTransactionTypePaidMessageReceive.CONSTRUCTOR, - StarTransactionTypePaidGroupCallMessageSend.CONSTRUCTOR, - StarTransactionTypePaidGroupCallMessageReceive.CONSTRUCTOR, - StarTransactionTypePaidGroupCallReactionSend.CONSTRUCTOR, - StarTransactionTypePaidGroupCallReactionReceive.CONSTRUCTOR, - StarTransactionTypeSuggestedPostPaymentSend.CONSTRUCTOR, - StarTransactionTypeSuggestedPostPaymentReceive.CONSTRUCTOR, - StarTransactionTypePremiumPurchase.CONSTRUCTOR, - StarTransactionTypeBusinessBotTransferSend.CONSTRUCTOR, - StarTransactionTypeBusinessBotTransferReceive.CONSTRUCTOR, - StarTransactionTypePublicPostSearch.CONSTRUCTOR, - StarTransactionTypeUnsupported.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public StarTransactionType() { - } - } - - /** - * The transaction is a deposit of Telegram Stars from the Premium bot; relevant for regular users only. - */ - public static class StarTransactionTypePremiumBotDeposit extends StarTransactionType { - - /** - * The transaction is a deposit of Telegram Stars from the Premium bot; relevant for regular users only. - */ - public StarTransactionTypePremiumBotDeposit() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -663156466; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a deposit of Telegram Stars from App Store; relevant for regular users only. - */ - public static class StarTransactionTypeAppStoreDeposit extends StarTransactionType { - - /** - * The transaction is a deposit of Telegram Stars from App Store; relevant for regular users only. - */ - public StarTransactionTypeAppStoreDeposit() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 136853825; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a deposit of Telegram Stars from Google Play; relevant for regular users only. - */ - public static class StarTransactionTypeGooglePlayDeposit extends StarTransactionType { - - /** - * The transaction is a deposit of Telegram Stars from Google Play; relevant for regular users only. - */ - public StarTransactionTypeGooglePlayDeposit() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -323111338; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a deposit of Telegram Stars from Fragment; relevant for regular users and bots only. - */ - public static class StarTransactionTypeFragmentDeposit extends StarTransactionType { - - /** - * The transaction is a deposit of Telegram Stars from Fragment; relevant for regular users and bots only. - */ - public StarTransactionTypeFragmentDeposit() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 123887172; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a deposit of Telegram Stars by another user; relevant for regular users only. - */ - public static class StarTransactionTypeUserDeposit extends StarTransactionType { - /** - * Identifier of the user who gifted Telegram Stars; 0 if the user was anonymous. - */ - public long userId; - /** - * The sticker to be shown in the transaction information; may be null if unknown. - */ - @Nullable public Sticker sticker; - - /** - * The transaction is a deposit of Telegram Stars by another user; relevant for regular users only. - */ - public StarTransactionTypeUserDeposit() { - } - - /** - * The transaction is a deposit of Telegram Stars by another user; relevant for regular users only. - * - * @param userId Identifier of the user who gifted Telegram Stars; 0 if the user was anonymous. - * @param sticker The sticker to be shown in the transaction information; may be null if unknown. - */ - public StarTransactionTypeUserDeposit(long userId, Sticker sticker) { - this.userId = userId; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 204085481; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a deposit of Telegram Stars from a giveaway; relevant for regular users only. - */ - public static class StarTransactionTypeGiveawayDeposit extends StarTransactionType { - /** - * Identifier of a supergroup or a channel chat that created the giveaway. - */ - public long chatId; - /** - * Identifier of the message with the giveaway; may be 0 or an identifier of a deleted message. - */ - public long giveawayMessageId; - - /** - * The transaction is a deposit of Telegram Stars from a giveaway; relevant for regular users only. - */ - public StarTransactionTypeGiveawayDeposit() { - } - - /** - * The transaction is a deposit of Telegram Stars from a giveaway; relevant for regular users only. - * - * @param chatId Identifier of a supergroup or a channel chat that created the giveaway. - * @param giveawayMessageId Identifier of the message with the giveaway; may be 0 or an identifier of a deleted message. - */ - public StarTransactionTypeGiveawayDeposit(long chatId, long giveawayMessageId) { - this.chatId = chatId; - this.giveawayMessageId = giveawayMessageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1318977338; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a withdrawal of earned Telegram Stars to Fragment; relevant for regular users, bots, supergroup and channel chats only. - */ - public static class StarTransactionTypeFragmentWithdrawal extends StarTransactionType { - /** - * State of the withdrawal; may be null for refunds from Fragment. - */ - @Nullable public RevenueWithdrawalState withdrawalState; - - /** - * The transaction is a withdrawal of earned Telegram Stars to Fragment; relevant for regular users, bots, supergroup and channel chats only. - */ - public StarTransactionTypeFragmentWithdrawal() { - } - - /** - * The transaction is a withdrawal of earned Telegram Stars to Fragment; relevant for regular users, bots, supergroup and channel chats only. - * - * @param withdrawalState State of the withdrawal; may be null for refunds from Fragment. - */ - public StarTransactionTypeFragmentWithdrawal(RevenueWithdrawalState withdrawalState) { - this.withdrawalState = withdrawalState; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1355142766; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a withdrawal of earned Telegram Stars to Telegram Ad platform; relevant for bots and channel chats only. - */ - public static class StarTransactionTypeTelegramAdsWithdrawal extends StarTransactionType { - - /** - * The transaction is a withdrawal of earned Telegram Stars to Telegram Ad platform; relevant for bots and channel chats only. - */ - public StarTransactionTypeTelegramAdsWithdrawal() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1517386647; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a payment for Telegram API usage; relevant for bots only. - */ - public static class StarTransactionTypeTelegramApiUsage extends StarTransactionType { - /** - * The number of billed requests. - */ - public int requestCount; - - /** - * The transaction is a payment for Telegram API usage; relevant for bots only. - */ - public StarTransactionTypeTelegramApiUsage() { - } - - /** - * The transaction is a payment for Telegram API usage; relevant for bots only. - * - * @param requestCount The number of billed requests. - */ - public StarTransactionTypeTelegramApiUsage(int requestCount) { - this.requestCount = requestCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 665332478; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a purchase of paid media from a bot or a business account by the current user; relevant for regular users only. - */ - public static class StarTransactionTypeBotPaidMediaPurchase extends StarTransactionType { - /** - * Identifier of the bot or the business account user who sent the paid media. - */ - public long userId; - /** - * The bought media if the transaction wasn't refunded. - */ - public PaidMedia[] media; - - /** - * The transaction is a purchase of paid media from a bot or a business account by the current user; relevant for regular users only. - */ - public StarTransactionTypeBotPaidMediaPurchase() { - } - - /** - * The transaction is a purchase of paid media from a bot or a business account by the current user; relevant for regular users only. - * - * @param userId Identifier of the bot or the business account user who sent the paid media. - * @param media The bought media if the transaction wasn't refunded. - */ - public StarTransactionTypeBotPaidMediaPurchase(long userId, PaidMedia[] media) { - this.userId = userId; - this.media = media; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 976645509; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a sale of paid media by the bot or a business account managed by the bot; relevant for bots only. - */ - public static class StarTransactionTypeBotPaidMediaSale extends StarTransactionType { - /** - * Identifier of the user who bought the media. - */ - public long userId; - /** - * The bought media. - */ - public PaidMedia[] media; - /** - * Bot-provided payload. - */ - public String payload; - /** - * Information about the affiliate which received commission from the transaction; may be null if none. - */ - @Nullable public AffiliateInfo affiliate; - - /** - * The transaction is a sale of paid media by the bot or a business account managed by the bot; relevant for bots only. - */ - public StarTransactionTypeBotPaidMediaSale() { - } - - /** - * The transaction is a sale of paid media by the bot or a business account managed by the bot; relevant for bots only. - * - * @param userId Identifier of the user who bought the media. - * @param media The bought media. - * @param payload Bot-provided payload. - * @param affiliate Information about the affiliate which received commission from the transaction; may be null if none. - */ - public StarTransactionTypeBotPaidMediaSale(long userId, PaidMedia[] media, String payload, AffiliateInfo affiliate) { - this.userId = userId; - this.media = media; - this.payload = payload; - this.affiliate = affiliate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1034408372; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a purchase of paid media from a channel by the current user; relevant for regular users only. - */ - public static class StarTransactionTypeChannelPaidMediaPurchase extends StarTransactionType { - /** - * Identifier of the channel chat that sent the paid media. - */ - public long chatId; - /** - * Identifier of the corresponding message with paid media; may be 0 or an identifier of a deleted message. - */ - public long messageId; - /** - * The bought media if the transaction wasn't refunded. - */ - public PaidMedia[] media; - - /** - * The transaction is a purchase of paid media from a channel by the current user; relevant for regular users only. - */ - public StarTransactionTypeChannelPaidMediaPurchase() { - } - - /** - * The transaction is a purchase of paid media from a channel by the current user; relevant for regular users only. - * - * @param chatId Identifier of the channel chat that sent the paid media. - * @param messageId Identifier of the corresponding message with paid media; may be 0 or an identifier of a deleted message. - * @param media The bought media if the transaction wasn't refunded. - */ - public StarTransactionTypeChannelPaidMediaPurchase(long chatId, long messageId, PaidMedia[] media) { - this.chatId = chatId; - this.messageId = messageId; - this.media = media; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1321281338; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a sale of paid media by the channel chat; relevant for channel chats only. - */ - public static class StarTransactionTypeChannelPaidMediaSale extends StarTransactionType { - /** - * Identifier of the user who bought the media. - */ - public long userId; - /** - * Identifier of the corresponding message with paid media; may be 0 or an identifier of a deleted message. - */ - public long messageId; - /** - * The bought media. - */ - public PaidMedia[] media; - - /** - * The transaction is a sale of paid media by the channel chat; relevant for channel chats only. - */ - public StarTransactionTypeChannelPaidMediaSale() { - } - - /** - * The transaction is a sale of paid media by the channel chat; relevant for channel chats only. - * - * @param userId Identifier of the user who bought the media. - * @param messageId Identifier of the corresponding message with paid media; may be 0 or an identifier of a deleted message. - * @param media The bought media. - */ - public StarTransactionTypeChannelPaidMediaSale(long userId, long messageId, PaidMedia[] media) { - this.userId = userId; - this.messageId = messageId; - this.media = media; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 52587085; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a purchase of a product from a bot or a business account by the current user; relevant for regular users only. - */ - public static class StarTransactionTypeBotInvoicePurchase extends StarTransactionType { - /** - * Identifier of the bot or the business account user who created the invoice. - */ - public long userId; - /** - * Information about the bought product. - */ - public ProductInfo productInfo; - - /** - * The transaction is a purchase of a product from a bot or a business account by the current user; relevant for regular users only. - */ - public StarTransactionTypeBotInvoicePurchase() { - } - - /** - * The transaction is a purchase of a product from a bot or a business account by the current user; relevant for regular users only. - * - * @param userId Identifier of the bot or the business account user who created the invoice. - * @param productInfo Information about the bought product. - */ - public StarTransactionTypeBotInvoicePurchase(long userId, ProductInfo productInfo) { - this.userId = userId; - this.productInfo = productInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 501066764; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a sale of a product by the bot; relevant for bots only. - */ - public static class StarTransactionTypeBotInvoiceSale extends StarTransactionType { - /** - * Identifier of the user who bought the product. - */ - public long userId; - /** - * Information about the bought product. - */ - public ProductInfo productInfo; - /** - * Invoice payload. - */ - public byte[] invoicePayload; - /** - * Information about the affiliate which received commission from the transaction; may be null if none. - */ - @Nullable public AffiliateInfo affiliate; - - /** - * The transaction is a sale of a product by the bot; relevant for bots only. - */ - public StarTransactionTypeBotInvoiceSale() { - } - - /** - * The transaction is a sale of a product by the bot; relevant for bots only. - * - * @param userId Identifier of the user who bought the product. - * @param productInfo Information about the bought product. - * @param invoicePayload Invoice payload. - * @param affiliate Information about the affiliate which received commission from the transaction; may be null if none. - */ - public StarTransactionTypeBotInvoiceSale(long userId, ProductInfo productInfo, byte[] invoicePayload, AffiliateInfo affiliate) { - this.userId = userId; - this.productInfo = productInfo; - this.invoicePayload = invoicePayload; - this.affiliate = affiliate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1534954799; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a purchase of a subscription from a bot or a business account by the current user; relevant for regular users only. - */ - public static class StarTransactionTypeBotSubscriptionPurchase extends StarTransactionType { - /** - * Identifier of the bot or the business account user who created the subscription link. - */ - public long userId; - /** - * The number of seconds between consecutive Telegram Star debitings. - */ - public int subscriptionPeriod; - /** - * Information about the bought subscription. - */ - public ProductInfo productInfo; - - /** - * The transaction is a purchase of a subscription from a bot or a business account by the current user; relevant for regular users only. - */ - public StarTransactionTypeBotSubscriptionPurchase() { - } - - /** - * The transaction is a purchase of a subscription from a bot or a business account by the current user; relevant for regular users only. - * - * @param userId Identifier of the bot or the business account user who created the subscription link. - * @param subscriptionPeriod The number of seconds between consecutive Telegram Star debitings. - * @param productInfo Information about the bought subscription. - */ - public StarTransactionTypeBotSubscriptionPurchase(long userId, int subscriptionPeriod, ProductInfo productInfo) { - this.userId = userId; - this.subscriptionPeriod = subscriptionPeriod; - this.productInfo = productInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1086264149; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a sale of a subscription by the bot; relevant for bots only. - */ - public static class StarTransactionTypeBotSubscriptionSale extends StarTransactionType { - /** - * Identifier of the user who bought the subscription. - */ - public long userId; - /** - * The number of seconds between consecutive Telegram Star debitings. - */ - public int subscriptionPeriod; - /** - * Information about the bought subscription. - */ - public ProductInfo productInfo; - /** - * Invoice payload. - */ - public byte[] invoicePayload; - /** - * Information about the affiliate which received commission from the transaction; may be null if none. - */ - @Nullable public AffiliateInfo affiliate; - - /** - * The transaction is a sale of a subscription by the bot; relevant for bots only. - */ - public StarTransactionTypeBotSubscriptionSale() { - } - - /** - * The transaction is a sale of a subscription by the bot; relevant for bots only. - * - * @param userId Identifier of the user who bought the subscription. - * @param subscriptionPeriod The number of seconds between consecutive Telegram Star debitings. - * @param productInfo Information about the bought subscription. - * @param invoicePayload Invoice payload. - * @param affiliate Information about the affiliate which received commission from the transaction; may be null if none. - */ - public StarTransactionTypeBotSubscriptionSale(long userId, int subscriptionPeriod, ProductInfo productInfo, byte[] invoicePayload, AffiliateInfo affiliate) { - this.userId = userId; - this.subscriptionPeriod = subscriptionPeriod; - this.productInfo = productInfo; - this.invoicePayload = invoicePayload; - this.affiliate = affiliate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 526936201; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a purchase of a subscription to a channel chat by the current user; relevant for regular users only. - */ - public static class StarTransactionTypeChannelSubscriptionPurchase extends StarTransactionType { - /** - * Identifier of the channel chat that created the subscription. - */ - public long chatId; - /** - * The number of seconds between consecutive Telegram Star debitings. - */ - public int subscriptionPeriod; - - /** - * The transaction is a purchase of a subscription to a channel chat by the current user; relevant for regular users only. - */ - public StarTransactionTypeChannelSubscriptionPurchase() { - } - - /** - * The transaction is a purchase of a subscription to a channel chat by the current user; relevant for regular users only. - * - * @param chatId Identifier of the channel chat that created the subscription. - * @param subscriptionPeriod The number of seconds between consecutive Telegram Star debitings. - */ - public StarTransactionTypeChannelSubscriptionPurchase(long chatId, int subscriptionPeriod) { - this.chatId = chatId; - this.subscriptionPeriod = subscriptionPeriod; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 940487633; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a sale of a subscription by the channel chat; relevant for channel chats only. - */ - public static class StarTransactionTypeChannelSubscriptionSale extends StarTransactionType { - /** - * Identifier of the user who bought the subscription. - */ - public long userId; - /** - * The number of seconds between consecutive Telegram Star debitings. - */ - public int subscriptionPeriod; - - /** - * The transaction is a sale of a subscription by the channel chat; relevant for channel chats only. - */ - public StarTransactionTypeChannelSubscriptionSale() { - } - - /** - * The transaction is a sale of a subscription by the channel chat; relevant for channel chats only. - * - * @param userId Identifier of the user who bought the subscription. - * @param subscriptionPeriod The number of seconds between consecutive Telegram Star debitings. - */ - public StarTransactionTypeChannelSubscriptionSale(long userId, int subscriptionPeriod) { - this.userId = userId; - this.subscriptionPeriod = subscriptionPeriod; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -32342910; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a bid on a gift auction; relevant for regular users only. - */ - public static class StarTransactionTypeGiftAuctionBid extends StarTransactionType { - /** - * Identifier of the user who will receive the gift. - */ - public MessageSender ownerId; - /** - * The gift. - */ - public Gift gift; - - /** - * The transaction is a bid on a gift auction; relevant for regular users only. - */ - public StarTransactionTypeGiftAuctionBid() { - } - - /** - * The transaction is a bid on a gift auction; relevant for regular users only. - * - * @param ownerId Identifier of the user who will receive the gift. - * @param gift The gift. - */ - public StarTransactionTypeGiftAuctionBid(MessageSender ownerId, Gift gift) { - this.ownerId = ownerId; - this.gift = gift; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1557306224; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a purchase of a regular gift; relevant for regular users and bots only. - */ - public static class StarTransactionTypeGiftPurchase extends StarTransactionType { - /** - * Identifier of the user or the channel that received the gift. - */ - public MessageSender ownerId; - /** - * The gift. - */ - public Gift gift; - - /** - * The transaction is a purchase of a regular gift; relevant for regular users and bots only. - */ - public StarTransactionTypeGiftPurchase() { - } - - /** - * The transaction is a purchase of a regular gift; relevant for regular users and bots only. - * - * @param ownerId Identifier of the user or the channel that received the gift. - * @param gift The gift. - */ - public StarTransactionTypeGiftPurchase(MessageSender ownerId, Gift gift) { - this.ownerId = ownerId; - this.gift = gift; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1819045664; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is an offer of gift purchase; relevant for regular users only. - */ - public static class StarTransactionTypeGiftPurchaseOffer extends StarTransactionType { - /** - * The gift. - */ - public UpgradedGift gift; - - /** - * The transaction is an offer of gift purchase; relevant for regular users only. - */ - public StarTransactionTypeGiftPurchaseOffer() { - } - - /** - * The transaction is an offer of gift purchase; relevant for regular users only. - * - * @param gift The gift. - */ - public StarTransactionTypeGiftPurchaseOffer(UpgradedGift gift) { - this.gift = gift; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1220117354; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a transfer of an upgraded gift; relevant for regular users only. - */ - public static class StarTransactionTypeGiftTransfer extends StarTransactionType { - /** - * Identifier of the user or the channel that received the gift. - */ - public MessageSender ownerId; - /** - * The gift. - */ - public UpgradedGift gift; - - /** - * The transaction is a transfer of an upgraded gift; relevant for regular users only. - */ - public StarTransactionTypeGiftTransfer() { - } - - /** - * The transaction is a transfer of an upgraded gift; relevant for regular users only. - * - * @param ownerId Identifier of the user or the channel that received the gift. - * @param gift The gift. - */ - public StarTransactionTypeGiftTransfer(MessageSender ownerId, UpgradedGift gift) { - this.ownerId = ownerId; - this.gift = gift; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 9835767; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a drop of original details of an upgraded gift; relevant for regular users only. - */ - public static class StarTransactionTypeGiftOriginalDetailsDrop extends StarTransactionType { - /** - * Identifier of the user or the channel that owns the gift. - */ - public MessageSender ownerId; - /** - * The gift. - */ - public UpgradedGift gift; - - /** - * The transaction is a drop of original details of an upgraded gift; relevant for regular users only. - */ - public StarTransactionTypeGiftOriginalDetailsDrop() { - } - - /** - * The transaction is a drop of original details of an upgraded gift; relevant for regular users only. - * - * @param ownerId Identifier of the user or the channel that owns the gift. - * @param gift The gift. - */ - public StarTransactionTypeGiftOriginalDetailsDrop(MessageSender ownerId, UpgradedGift gift) { - this.ownerId = ownerId; - this.gift = gift; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1676911485; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a sale of a received gift; relevant for regular users and channel chats only. - */ - public static class StarTransactionTypeGiftSale extends StarTransactionType { - /** - * Identifier of the user who sent the gift. - */ - public long userId; - /** - * The gift. - */ - public Gift gift; - - /** - * The transaction is a sale of a received gift; relevant for regular users and channel chats only. - */ - public StarTransactionTypeGiftSale() { - } - - /** - * The transaction is a sale of a received gift; relevant for regular users and channel chats only. - * - * @param userId Identifier of the user who sent the gift. - * @param gift The gift. - */ - public StarTransactionTypeGiftSale(long userId, Gift gift) { - this.userId = userId; - this.gift = gift; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1691750743; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is an upgrade of a gift; relevant for regular users only. - */ - public static class StarTransactionTypeGiftUpgrade extends StarTransactionType { - /** - * Identifier of the user who initially sent the gift. - */ - public long userId; - /** - * The upgraded gift. - */ - public UpgradedGift gift; - - /** - * The transaction is an upgrade of a gift; relevant for regular users only. - */ - public StarTransactionTypeGiftUpgrade() { - } - - /** - * The transaction is an upgrade of a gift; relevant for regular users only. - * - * @param userId Identifier of the user who initially sent the gift. - * @param gift The upgraded gift. - */ - public StarTransactionTypeGiftUpgrade(long userId, UpgradedGift gift) { - this.userId = userId; - this.gift = gift; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -632388839; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a purchase of an upgrade of a gift owned by another user or channel; relevant for regular users only. - */ - public static class StarTransactionTypeGiftUpgradePurchase extends StarTransactionType { - /** - * Owner of the upgraded gift. - */ - public MessageSender ownerId; - /** - * The gift. - */ - public Gift gift; - - /** - * The transaction is a purchase of an upgrade of a gift owned by another user or channel; relevant for regular users only. - */ - public StarTransactionTypeGiftUpgradePurchase() { - } - - /** - * The transaction is a purchase of an upgrade of a gift owned by another user or channel; relevant for regular users only. - * - * @param ownerId Owner of the upgraded gift. - * @param gift The gift. - */ - public StarTransactionTypeGiftUpgradePurchase(MessageSender ownerId, Gift gift) { - this.ownerId = ownerId; - this.gift = gift; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -869970174; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a purchase of an upgraded gift for some user or channel; relevant for regular users only. - */ - public static class StarTransactionTypeUpgradedGiftPurchase extends StarTransactionType { - /** - * Identifier of the user who sold the gift. - */ - public long userId; - /** - * The gift. - */ - public UpgradedGift gift; - - /** - * The transaction is a purchase of an upgraded gift for some user or channel; relevant for regular users only. - */ - public StarTransactionTypeUpgradedGiftPurchase() { - } - - /** - * The transaction is a purchase of an upgraded gift for some user or channel; relevant for regular users only. - * - * @param userId Identifier of the user who sold the gift. - * @param gift The gift. - */ - public StarTransactionTypeUpgradedGiftPurchase(long userId, UpgradedGift gift) { - this.userId = userId; - this.gift = gift; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -59050247; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a sale of an upgraded gift; relevant for regular users only. - */ - public static class StarTransactionTypeUpgradedGiftSale extends StarTransactionType { - /** - * Identifier of the user who bought the gift. - */ - public long userId; - /** - * The gift. - */ - public UpgradedGift gift; - /** - * The number of Telegram Stars received by the Telegram for each 1000 Telegram Stars received by the seller of the gift. - */ - public int commissionPerMille; - /** - * The Telegram Star amount that was received by Telegram; can be negative for refunds. - */ - public StarAmount commissionStarAmount; - /** - * True, if the gift was sold through a purchase offer. - */ - public boolean viaOffer; - - /** - * The transaction is a sale of an upgraded gift; relevant for regular users only. - */ - public StarTransactionTypeUpgradedGiftSale() { - } - - /** - * The transaction is a sale of an upgraded gift; relevant for regular users only. - * - * @param userId Identifier of the user who bought the gift. - * @param gift The gift. - * @param commissionPerMille The number of Telegram Stars received by the Telegram for each 1000 Telegram Stars received by the seller of the gift. - * @param commissionStarAmount The Telegram Star amount that was received by Telegram; can be negative for refunds. - * @param viaOffer True, if the gift was sold through a purchase offer. - */ - public StarTransactionTypeUpgradedGiftSale(long userId, UpgradedGift gift, int commissionPerMille, StarAmount commissionStarAmount, boolean viaOffer) { - this.userId = userId; - this.gift = gift; - this.commissionPerMille = commissionPerMille; - this.commissionStarAmount = commissionStarAmount; - this.viaOffer = viaOffer; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1004166760; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a sending of a paid reaction to a message in a channel chat by the current user; relevant for regular users only. - */ - public static class StarTransactionTypeChannelPaidReactionSend extends StarTransactionType { - /** - * Identifier of the channel chat. - */ - public long chatId; - /** - * Identifier of the reacted message; may be 0 or an identifier of a deleted message. - */ - public long messageId; - - /** - * The transaction is a sending of a paid reaction to a message in a channel chat by the current user; relevant for regular users only. - */ - public StarTransactionTypeChannelPaidReactionSend() { - } - - /** - * The transaction is a sending of a paid reaction to a message in a channel chat by the current user; relevant for regular users only. - * - * @param chatId Identifier of the channel chat. - * @param messageId Identifier of the reacted message; may be 0 or an identifier of a deleted message. - */ - public StarTransactionTypeChannelPaidReactionSend(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1071224896; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a receiving of a paid reaction to a message by the channel chat; relevant for channel chats only. - */ - public static class StarTransactionTypeChannelPaidReactionReceive extends StarTransactionType { - /** - * Identifier of the user who added the paid reaction. - */ - public long userId; - /** - * Identifier of the reacted message; may be 0 or an identifier of a deleted message. - */ - public long messageId; - - /** - * The transaction is a receiving of a paid reaction to a message by the channel chat; relevant for channel chats only. - */ - public StarTransactionTypeChannelPaidReactionReceive() { - } - - /** - * The transaction is a receiving of a paid reaction to a message by the channel chat; relevant for channel chats only. - * - * @param userId Identifier of the user who added the paid reaction. - * @param messageId Identifier of the reacted message; may be 0 or an identifier of a deleted message. - */ - public StarTransactionTypeChannelPaidReactionReceive(long userId, long messageId) { - this.userId = userId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 601291243; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a receiving of a commission from an affiliate program; relevant for regular users, bots and channel chats only. - */ - public static class StarTransactionTypeAffiliateProgramCommission extends StarTransactionType { - /** - * Identifier of the chat that created the affiliate program. - */ - public long chatId; - /** - * The number of Telegram Stars received by the affiliate for each 1000 Telegram Stars received by the program owner. - */ - public int commissionPerMille; - - /** - * The transaction is a receiving of a commission from an affiliate program; relevant for regular users, bots and channel chats only. - */ - public StarTransactionTypeAffiliateProgramCommission() { - } - - /** - * The transaction is a receiving of a commission from an affiliate program; relevant for regular users, bots and channel chats only. - * - * @param chatId Identifier of the chat that created the affiliate program. - * @param commissionPerMille The number of Telegram Stars received by the affiliate for each 1000 Telegram Stars received by the program owner. - */ - public StarTransactionTypeAffiliateProgramCommission(long chatId, int commissionPerMille) { - this.chatId = chatId; - this.commissionPerMille = commissionPerMille; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1704757901; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a sending of a paid message; relevant for regular users only. - */ - public static class StarTransactionTypePaidMessageSend extends StarTransactionType { - /** - * Identifier of the chat that received the payment. - */ - public long chatId; - /** - * Number of sent paid messages. - */ - public int messageCount; - - /** - * The transaction is a sending of a paid message; relevant for regular users only. - */ - public StarTransactionTypePaidMessageSend() { - } - - /** - * The transaction is a sending of a paid message; relevant for regular users only. - * - * @param chatId Identifier of the chat that received the payment. - * @param messageCount Number of sent paid messages. - */ - public StarTransactionTypePaidMessageSend(long chatId, int messageCount) { - this.chatId = chatId; - this.messageCount = messageCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1709611931; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a receiving of a paid message; relevant for regular users, supergroup and channel chats only. - */ - public static class StarTransactionTypePaidMessageReceive extends StarTransactionType { - /** - * Identifier of the sender of the message. - */ - public MessageSender senderId; - /** - * Number of received paid messages. - */ - public int messageCount; - /** - * The number of Telegram Stars received by the Telegram for each 1000 Telegram Stars paid for message sending. - */ - public int commissionPerMille; - /** - * The Telegram Star amount that was received by Telegram; can be negative for refunds. - */ - public StarAmount commissionStarAmount; - - /** - * The transaction is a receiving of a paid message; relevant for regular users, supergroup and channel chats only. - */ - public StarTransactionTypePaidMessageReceive() { - } - - /** - * The transaction is a receiving of a paid message; relevant for regular users, supergroup and channel chats only. - * - * @param senderId Identifier of the sender of the message. - * @param messageCount Number of received paid messages. - * @param commissionPerMille The number of Telegram Stars received by the Telegram for each 1000 Telegram Stars paid for message sending. - * @param commissionStarAmount The Telegram Star amount that was received by Telegram; can be negative for refunds. - */ - public StarTransactionTypePaidMessageReceive(MessageSender senderId, int messageCount, int commissionPerMille, StarAmount commissionStarAmount) { - this.senderId = senderId; - this.messageCount = messageCount; - this.commissionPerMille = commissionPerMille; - this.commissionStarAmount = commissionStarAmount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -676839994; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a sending of a paid group call message; relevant for regular users only. - */ - public static class StarTransactionTypePaidGroupCallMessageSend extends StarTransactionType { - /** - * Identifier of the chat that received the payment. - */ - public long chatId; - - /** - * The transaction is a sending of a paid group call message; relevant for regular users only. - */ - public StarTransactionTypePaidGroupCallMessageSend() { - } - - /** - * The transaction is a sending of a paid group call message; relevant for regular users only. - * - * @param chatId Identifier of the chat that received the payment. - */ - public StarTransactionTypePaidGroupCallMessageSend(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -655578726; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a receiving of a paid group call message; relevant for regular users and channel chats only. - */ - public static class StarTransactionTypePaidGroupCallMessageReceive extends StarTransactionType { - /** - * Identifier of the sender of the message. - */ - public MessageSender senderId; - /** - * The number of Telegram Stars received by the Telegram for each 1000 Telegram Stars paid for message sending. - */ - public int commissionPerMille; - /** - * The Telegram Star amount that was received by Telegram; can be negative for refunds. - */ - public StarAmount commissionStarAmount; - - /** - * The transaction is a receiving of a paid group call message; relevant for regular users and channel chats only. - */ - public StarTransactionTypePaidGroupCallMessageReceive() { - } - - /** - * The transaction is a receiving of a paid group call message; relevant for regular users and channel chats only. - * - * @param senderId Identifier of the sender of the message. - * @param commissionPerMille The number of Telegram Stars received by the Telegram for each 1000 Telegram Stars paid for message sending. - * @param commissionStarAmount The Telegram Star amount that was received by Telegram; can be negative for refunds. - */ - public StarTransactionTypePaidGroupCallMessageReceive(MessageSender senderId, int commissionPerMille, StarAmount commissionStarAmount) { - this.senderId = senderId; - this.commissionPerMille = commissionPerMille; - this.commissionStarAmount = commissionStarAmount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 197238067; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a sending of a paid group reaction; relevant for regular users only. - */ - public static class StarTransactionTypePaidGroupCallReactionSend extends StarTransactionType { - /** - * Identifier of the chat that received the payment. - */ - public long chatId; - - /** - * The transaction is a sending of a paid group reaction; relevant for regular users only. - */ - public StarTransactionTypePaidGroupCallReactionSend() { - } - - /** - * The transaction is a sending of a paid group reaction; relevant for regular users only. - * - * @param chatId Identifier of the chat that received the payment. - */ - public StarTransactionTypePaidGroupCallReactionSend(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1410716443; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a receiving of a paid group call reaction; relevant for regular users and channel chats only. - */ - public static class StarTransactionTypePaidGroupCallReactionReceive extends StarTransactionType { - /** - * Identifier of the sender of the reaction. - */ - public MessageSender senderId; - /** - * The number of Telegram Stars received by the Telegram for each 1000 Telegram Stars paid for reaction sending. - */ - public int commissionPerMille; - /** - * The Telegram Star amount that was received by Telegram; can be negative for refunds. - */ - public StarAmount commissionStarAmount; - - /** - * The transaction is a receiving of a paid group call reaction; relevant for regular users and channel chats only. - */ - public StarTransactionTypePaidGroupCallReactionReceive() { - } - - /** - * The transaction is a receiving of a paid group call reaction; relevant for regular users and channel chats only. - * - * @param senderId Identifier of the sender of the reaction. - * @param commissionPerMille The number of Telegram Stars received by the Telegram for each 1000 Telegram Stars paid for reaction sending. - * @param commissionStarAmount The Telegram Star amount that was received by Telegram; can be negative for refunds. - */ - public StarTransactionTypePaidGroupCallReactionReceive(MessageSender senderId, int commissionPerMille, StarAmount commissionStarAmount) { - this.senderId = senderId; - this.commissionPerMille = commissionPerMille; - this.commissionStarAmount = commissionStarAmount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1410001679; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a payment for a suggested post; relevant for regular users only. - */ - public static class StarTransactionTypeSuggestedPostPaymentSend extends StarTransactionType { - /** - * Identifier of the channel chat that posted the post. - */ - public long chatId; - - /** - * The transaction is a payment for a suggested post; relevant for regular users only. - */ - public StarTransactionTypeSuggestedPostPaymentSend() { - } - - /** - * The transaction is a payment for a suggested post; relevant for regular users only. - * - * @param chatId Identifier of the channel chat that posted the post. - */ - public StarTransactionTypeSuggestedPostPaymentSend(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 508845173; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a receiving of a payment for a suggested post by the channel chat; relevant for channel chats only. - */ - public static class StarTransactionTypeSuggestedPostPaymentReceive extends StarTransactionType { - /** - * Identifier of the user who paid for the suggested post. - */ - public long userId; - - /** - * The transaction is a receiving of a payment for a suggested post by the channel chat; relevant for channel chats only. - */ - public StarTransactionTypeSuggestedPostPaymentReceive() { - } - - /** - * The transaction is a receiving of a payment for a suggested post by the channel chat; relevant for channel chats only. - * - * @param userId Identifier of the user who paid for the suggested post. - */ - public StarTransactionTypeSuggestedPostPaymentReceive(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 480833401; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a purchase of Telegram Premium subscription; relevant for regular users and bots only. - */ - public static class StarTransactionTypePremiumPurchase extends StarTransactionType { - /** - * Identifier of the user who received the Telegram Premium subscription. - */ - public long userId; - /** - * Number of months the Telegram Premium subscription will be active. - */ - public int monthCount; - /** - * A sticker to be shown in the transaction information; may be null if unknown. - */ - @Nullable public Sticker sticker; - - /** - * The transaction is a purchase of Telegram Premium subscription; relevant for regular users and bots only. - */ - public StarTransactionTypePremiumPurchase() { - } - - /** - * The transaction is a purchase of Telegram Premium subscription; relevant for regular users and bots only. - * - * @param userId Identifier of the user who received the Telegram Premium subscription. - * @param monthCount Number of months the Telegram Premium subscription will be active. - * @param sticker A sticker to be shown in the transaction information; may be null if unknown. - */ - public StarTransactionTypePremiumPurchase(long userId, int monthCount, Sticker sticker) { - this.userId = userId; - this.monthCount = monthCount; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 998094851; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a transfer of Telegram Stars to a business bot; relevant for regular users only. - */ - public static class StarTransactionTypeBusinessBotTransferSend extends StarTransactionType { - /** - * Identifier of the bot that received Telegram Stars. - */ - public long userId; - - /** - * The transaction is a transfer of Telegram Stars to a business bot; relevant for regular users only. - */ - public StarTransactionTypeBusinessBotTransferSend() { - } - - /** - * The transaction is a transfer of Telegram Stars to a business bot; relevant for regular users only. - * - * @param userId Identifier of the bot that received Telegram Stars. - */ - public StarTransactionTypeBusinessBotTransferSend(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1221227814; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a transfer of Telegram Stars from a business account; relevant for bots only. - */ - public static class StarTransactionTypeBusinessBotTransferReceive extends StarTransactionType { - /** - * Identifier of the user who sent Telegram Stars. - */ - public long userId; - - /** - * The transaction is a transfer of Telegram Stars from a business account; relevant for bots only. - */ - public StarTransactionTypeBusinessBotTransferReceive() { - } - - /** - * The transaction is a transfer of Telegram Stars from a business account; relevant for bots only. - * - * @param userId Identifier of the user who sent Telegram Stars. - */ - public StarTransactionTypeBusinessBotTransferReceive(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 532496778; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a payment for search of posts in public Telegram channels; relevant for regular users only. - */ - public static class StarTransactionTypePublicPostSearch extends StarTransactionType { - - /** - * The transaction is a payment for search of posts in public Telegram channels; relevant for regular users only. - */ - public StarTransactionTypePublicPostSearch() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1390533454; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a transaction of an unsupported type. - */ - public static class StarTransactionTypeUnsupported extends StarTransactionType { - - /** - * The transaction is a transaction of an unsupported type. - */ - public StarTransactionTypeUnsupported() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1993329330; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of Telegram Star transactions. - */ - public static class StarTransactions extends Object { - /** - * The amount of owned Telegram Stars. - */ - public StarAmount starAmount; - /** - * List of transactions with Telegram Stars. - */ - public StarTransaction[] transactions; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Represents a list of Telegram Star transactions. - */ - public StarTransactions() { - } - - /** - * Represents a list of Telegram Star transactions. - * - * @param starAmount The amount of owned Telegram Stars. - * @param transactions List of transactions with Telegram Stars. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public StarTransactions(StarAmount starAmount, StarTransaction[] transactions, String nextOffset) { - this.starAmount = starAmount; - this.transactions = transactions; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1218437859; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents result of starting a live story. - */ - public abstract static class StartLiveStoryResult extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - StartLiveStoryResultOk.CONSTRUCTOR, - StartLiveStoryResultFail.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public StartLiveStoryResult() { - } - } - - /** - * The live story was successfully posted. - */ - public static class StartLiveStoryResultOk extends StartLiveStoryResult { - /** - * The live story. - */ - public Story story; - - /** - * The live story was successfully posted. - */ - public StartLiveStoryResultOk() { - } - - /** - * The live story was successfully posted. - * - * @param story The live story. - */ - public StartLiveStoryResultOk(Story story) { - this.story = story; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -387759428; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The live story failed to post with an error to be handled. - */ - public static class StartLiveStoryResultFail extends StartLiveStoryResult { - /** - * Type of the error; other error types may be returned as regular errors. - */ - public CanPostStoryResult errorType; - - /** - * The live story failed to post with an error to be handled. - */ - public StartLiveStoryResultFail() { - } - - /** - * The live story failed to post with an error to be handled. - * - * @param errorType Type of the error; other error types may be returned as regular errors. - */ - public StartLiveStoryResultFail(CanPostStoryResult errorType) { - this.errorType = errorType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 495261112; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a statistical graph. - */ - public abstract static class StatisticalGraph extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - StatisticalGraphData.CONSTRUCTOR, - StatisticalGraphAsync.CONSTRUCTOR, - StatisticalGraphError.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public StatisticalGraph() { - } - } - - /** - * A graph data. - */ - public static class StatisticalGraphData extends StatisticalGraph { - /** - * Graph data in JSON format. - */ - public String jsonData; - /** - * If non-empty, a token which can be used to receive a zoomed in graph. - */ - public String zoomToken; - - /** - * A graph data. - */ - public StatisticalGraphData() { - } - - /** - * A graph data. - * - * @param jsonData Graph data in JSON format. - * @param zoomToken If non-empty, a token which can be used to receive a zoomed in graph. - */ - public StatisticalGraphData(String jsonData, String zoomToken) { - this.jsonData = jsonData; - this.zoomToken = zoomToken; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1988940244; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The graph data to be asynchronously loaded through getStatisticalGraph. - */ - public static class StatisticalGraphAsync extends StatisticalGraph { - /** - * The token to use for data loading. - */ - public String token; - - /** - * The graph data to be asynchronously loaded through getStatisticalGraph. - */ - public StatisticalGraphAsync() { - } - - /** - * The graph data to be asynchronously loaded through getStatisticalGraph. - * - * @param token The token to use for data loading. - */ - public StatisticalGraphAsync(String token) { - this.token = token; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 435891103; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An error message to be shown to the user instead of the graph. - */ - public static class StatisticalGraphError extends StatisticalGraph { - /** - * The error message. - */ - public String errorMessage; - - /** - * An error message to be shown to the user instead of the graph. - */ - public StatisticalGraphError() { - } - - /** - * An error message to be shown to the user instead of the graph. - * - * @param errorMessage The error message. - */ - public StatisticalGraphError(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1006788526; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A value with information about its recent changes. - */ - public static class StatisticalValue extends Object { - /** - * The current value. - */ - public double value; - /** - * The value for the previous day. - */ - public double previousValue; - /** - * The growth rate of the value, as a percentage. - */ - public double growthRatePercentage; - - /** - * A value with information about its recent changes. - */ - public StatisticalValue() { - } - - /** - * A value with information about its recent changes. - * - * @param value The current value. - * @param previousValue The value for the previous day. - * @param growthRatePercentage The growth rate of the value, as a percentage. - */ - public StatisticalValue(double value, double previousValue, double growthRatePercentage) { - this.value = value; - this.previousValue = previousValue; - this.growthRatePercentage = growthRatePercentage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1651337846; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a sticker. - */ - public static class Sticker extends Object { - /** - * Unique sticker identifier within the set; 0 if none. - */ - public long id; - /** - * Identifier of the sticker set to which the sticker belongs; 0 if none. - */ - public long setId; - /** - * Sticker width; as defined by the sender. - */ - public int width; - /** - * Sticker height; as defined by the sender. - */ - public int height; - /** - * Emoji corresponding to the sticker; may be empty if unknown. - */ - public String emoji; - /** - * Sticker format. - */ - public StickerFormat format; - /** - * Sticker's full type. - */ - public StickerFullType fullType; - /** - * Sticker thumbnail in WEBP or JPEG format; may be null. - */ - @Nullable public Thumbnail thumbnail; - /** - * File containing the sticker. - */ - public File sticker; - - /** - * Describes a sticker. - */ - public Sticker() { - } - - /** - * Describes a sticker. - * - * @param id Unique sticker identifier within the set; 0 if none. - * @param setId Identifier of the sticker set to which the sticker belongs; 0 if none. - * @param width Sticker width; as defined by the sender. - * @param height Sticker height; as defined by the sender. - * @param emoji Emoji corresponding to the sticker; may be empty if unknown. - * @param format Sticker format. - * @param fullType Sticker's full type. - * @param thumbnail Sticker thumbnail in WEBP or JPEG format; may be null. - * @param sticker File containing the sticker. - */ - public Sticker(long id, long setId, int width, int height, String emoji, StickerFormat format, StickerFullType fullType, Thumbnail thumbnail, File sticker) { - this.id = id; - this.setId = setId; - this.width = width; - this.height = height; - this.emoji = emoji; - this.format = format; - this.fullType = fullType; - this.thumbnail = thumbnail; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -647013057; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes format of a sticker. - */ - public abstract static class StickerFormat extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - StickerFormatWebp.CONSTRUCTOR, - StickerFormatTgs.CONSTRUCTOR, - StickerFormatWebm.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public StickerFormat() { - } - } - - /** - * The sticker is an image in WEBP format. - */ - public static class StickerFormatWebp extends StickerFormat { - - /** - * The sticker is an image in WEBP format. - */ - public StickerFormatWebp() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2123043040; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The sticker is an animation in TGS format. - */ - public static class StickerFormatTgs extends StickerFormat { - - /** - * The sticker is an animation in TGS format. - */ - public StickerFormatTgs() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1614588662; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The sticker is a video in WEBM format. - */ - public static class StickerFormatWebm extends StickerFormat { - - /** - * The sticker is a video in WEBM format. - */ - public StickerFormatWebm() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2070162097; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains full information about sticker type. - */ - public abstract static class StickerFullType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - StickerFullTypeRegular.CONSTRUCTOR, - StickerFullTypeMask.CONSTRUCTOR, - StickerFullTypeCustomEmoji.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public StickerFullType() { - } - } - - /** - * The sticker is a regular sticker. - */ - public static class StickerFullTypeRegular extends StickerFullType { - /** - * Premium animation of the sticker; may be null. If present, only Telegram Premium users can use the sticker. - */ - @Nullable public File premiumAnimation; - - /** - * The sticker is a regular sticker. - */ - public StickerFullTypeRegular() { - } - - /** - * The sticker is a regular sticker. - * - * @param premiumAnimation Premium animation of the sticker; may be null. If present, only Telegram Premium users can use the sticker. - */ - public StickerFullTypeRegular(File premiumAnimation) { - this.premiumAnimation = premiumAnimation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2006425865; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The sticker is a mask in WEBP format to be placed on photos or videos. - */ - public static class StickerFullTypeMask extends StickerFullType { - /** - * Position where the mask is placed; may be null. - */ - @Nullable public MaskPosition maskPosition; - - /** - * The sticker is a mask in WEBP format to be placed on photos or videos. - */ - public StickerFullTypeMask() { - } - - /** - * The sticker is a mask in WEBP format to be placed on photos or videos. - * - * @param maskPosition Position where the mask is placed; may be null. - */ - public StickerFullTypeMask(MaskPosition maskPosition) { - this.maskPosition = maskPosition; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 652197687; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The sticker is a custom emoji to be used inside message text and caption. Currently, only Telegram Premium users can use custom emoji. - */ - public static class StickerFullTypeCustomEmoji extends StickerFullType { - /** - * Identifier of the custom emoji. - */ - public long customEmojiId; - /** - * True, if the sticker must be repainted to a text color in messages, the color of the Telegram Premium badge in emoji status, white color on chat photos, or another appropriate color in other places. - */ - public boolean needsRepainting; - - /** - * The sticker is a custom emoji to be used inside message text and caption. Currently, only Telegram Premium users can use custom emoji. - */ - public StickerFullTypeCustomEmoji() { - } - - /** - * The sticker is a custom emoji to be used inside message text and caption. Currently, only Telegram Premium users can use custom emoji. - * - * @param customEmojiId Identifier of the custom emoji. - * @param needsRepainting True, if the sticker must be repainted to a text color in messages, the color of the Telegram Premium badge in emoji status, white color on chat photos, or another appropriate color in other places. - */ - public StickerFullTypeCustomEmoji(long customEmojiId, boolean needsRepainting) { - this.customEmojiId = customEmojiId; - this.needsRepainting = needsRepainting; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1015085653; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a sticker set. - */ - public static class StickerSet extends Object { - /** - * Identifier of the sticker set. - */ - public long id; - /** - * Title of the sticker set. - */ - public String title; - /** - * Name of the sticker set. - */ - public String name; - /** - * Sticker set thumbnail in WEBP, TGS, or WEBM format with width and height 100; may be null. The file can be downloaded only before the thumbnail is changed. - */ - @Nullable public Thumbnail thumbnail; - /** - * Sticker set thumbnail's outline; may be null if unknown. - */ - @Nullable public Outline thumbnailOutline; - /** - * True, if the sticker set is owned by the current user. - */ - public boolean isOwned; - /** - * True, if the sticker set has been installed by the current user. - */ - public boolean isInstalled; - /** - * True, if the sticker set has been archived. A sticker set can't be installed and archived simultaneously. - */ - public boolean isArchived; - /** - * True, if the sticker set is official. - */ - public boolean isOfficial; - /** - * Type of the stickers in the set. - */ - public StickerType stickerType; - /** - * True, if stickers in the sticker set are custom emoji that must be repainted; for custom emoji sticker sets only. - */ - public boolean needsRepainting; - /** - * True, if stickers in the sticker set are custom emoji that can be used as chat emoji status; for custom emoji sticker sets only. - */ - public boolean isAllowedAsChatEmojiStatus; - /** - * True for already viewed trending sticker sets. - */ - public boolean isViewed; - /** - * List of stickers in this set. - */ - public Sticker[] stickers; - /** - * A list of emojis corresponding to the stickers in the same order. The list is only for informational purposes, because a sticker is always sent with a fixed emoji from the corresponding Sticker object. - */ - public Emojis[] emojis; - - /** - * Represents a sticker set. - */ - public StickerSet() { - } - - /** - * Represents a sticker set. - * - * @param id Identifier of the sticker set. - * @param title Title of the sticker set. - * @param name Name of the sticker set. - * @param thumbnail Sticker set thumbnail in WEBP, TGS, or WEBM format with width and height 100; may be null. The file can be downloaded only before the thumbnail is changed. - * @param thumbnailOutline Sticker set thumbnail's outline; may be null if unknown. - * @param isOwned True, if the sticker set is owned by the current user. - * @param isInstalled True, if the sticker set has been installed by the current user. - * @param isArchived True, if the sticker set has been archived. A sticker set can't be installed and archived simultaneously. - * @param isOfficial True, if the sticker set is official. - * @param stickerType Type of the stickers in the set. - * @param needsRepainting True, if stickers in the sticker set are custom emoji that must be repainted; for custom emoji sticker sets only. - * @param isAllowedAsChatEmojiStatus True, if stickers in the sticker set are custom emoji that can be used as chat emoji status; for custom emoji sticker sets only. - * @param isViewed True for already viewed trending sticker sets. - * @param stickers List of stickers in this set. - * @param emojis A list of emojis corresponding to the stickers in the same order. The list is only for informational purposes, because a sticker is always sent with a fixed emoji from the corresponding Sticker object. - */ - public StickerSet(long id, String title, String name, Thumbnail thumbnail, Outline thumbnailOutline, boolean isOwned, boolean isInstalled, boolean isArchived, boolean isOfficial, StickerType stickerType, boolean needsRepainting, boolean isAllowedAsChatEmojiStatus, boolean isViewed, Sticker[] stickers, Emojis[] emojis) { - this.id = id; - this.title = title; - this.name = name; - this.thumbnail = thumbnail; - this.thumbnailOutline = thumbnailOutline; - this.isOwned = isOwned; - this.isInstalled = isInstalled; - this.isArchived = isArchived; - this.isOfficial = isOfficial; - this.stickerType = stickerType; - this.needsRepainting = needsRepainting; - this.isAllowedAsChatEmojiStatus = isAllowedAsChatEmojiStatus; - this.isViewed = isViewed; - this.stickers = stickers; - this.emojis = emojis; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1783150210; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents short information about a sticker set. - */ - public static class StickerSetInfo extends Object { - /** - * Identifier of the sticker set. - */ - public long id; - /** - * Title of the sticker set. - */ - public String title; - /** - * Name of the sticker set. - */ - public String name; - /** - * Sticker set thumbnail in WEBP, TGS, or WEBM format with width and height 100; may be null. The file can be downloaded only before the thumbnail is changed. - */ - @Nullable public Thumbnail thumbnail; - /** - * Sticker set thumbnail's outline; may be null if unknown. - */ - @Nullable public Outline thumbnailOutline; - /** - * True, if the sticker set is owned by the current user. - */ - public boolean isOwned; - /** - * True, if the sticker set has been installed by the current user. - */ - public boolean isInstalled; - /** - * True, if the sticker set has been archived. A sticker set can't be installed and archived simultaneously. - */ - public boolean isArchived; - /** - * True, if the sticker set is official. - */ - public boolean isOfficial; - /** - * Type of the stickers in the set. - */ - public StickerType stickerType; - /** - * True, if stickers in the sticker set are custom emoji that must be repainted; for custom emoji sticker sets only. - */ - public boolean needsRepainting; - /** - * True, if stickers in the sticker set are custom emoji that can be used as chat emoji status; for custom emoji sticker sets only. - */ - public boolean isAllowedAsChatEmojiStatus; - /** - * True for already viewed trending sticker sets. - */ - public boolean isViewed; - /** - * Total number of stickers in the set. - */ - public int size; - /** - * Up to the first 5 stickers from the set, depending on the context. If the application needs more stickers the full sticker set needs to be requested. - */ - public Sticker[] covers; - - /** - * Represents short information about a sticker set. - */ - public StickerSetInfo() { - } - - /** - * Represents short information about a sticker set. - * - * @param id Identifier of the sticker set. - * @param title Title of the sticker set. - * @param name Name of the sticker set. - * @param thumbnail Sticker set thumbnail in WEBP, TGS, or WEBM format with width and height 100; may be null. The file can be downloaded only before the thumbnail is changed. - * @param thumbnailOutline Sticker set thumbnail's outline; may be null if unknown. - * @param isOwned True, if the sticker set is owned by the current user. - * @param isInstalled True, if the sticker set has been installed by the current user. - * @param isArchived True, if the sticker set has been archived. A sticker set can't be installed and archived simultaneously. - * @param isOfficial True, if the sticker set is official. - * @param stickerType Type of the stickers in the set. - * @param needsRepainting True, if stickers in the sticker set are custom emoji that must be repainted; for custom emoji sticker sets only. - * @param isAllowedAsChatEmojiStatus True, if stickers in the sticker set are custom emoji that can be used as chat emoji status; for custom emoji sticker sets only. - * @param isViewed True for already viewed trending sticker sets. - * @param size Total number of stickers in the set. - * @param covers Up to the first 5 stickers from the set, depending on the context. If the application needs more stickers the full sticker set needs to be requested. - */ - public StickerSetInfo(long id, String title, String name, Thumbnail thumbnail, Outline thumbnailOutline, boolean isOwned, boolean isInstalled, boolean isArchived, boolean isOfficial, StickerType stickerType, boolean needsRepainting, boolean isAllowedAsChatEmojiStatus, boolean isViewed, int size, Sticker[] covers) { - this.id = id; - this.title = title; - this.name = name; - this.thumbnail = thumbnail; - this.thumbnailOutline = thumbnailOutline; - this.isOwned = isOwned; - this.isInstalled = isInstalled; - this.isArchived = isArchived; - this.isOfficial = isOfficial; - this.stickerType = stickerType; - this.needsRepainting = needsRepainting; - this.isAllowedAsChatEmojiStatus = isAllowedAsChatEmojiStatus; - this.isViewed = isViewed; - this.size = size; - this.covers = covers; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1649074729; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of sticker sets. - */ - public static class StickerSets extends Object { - /** - * Approximate total number of sticker sets found. - */ - public int totalCount; - /** - * List of sticker sets. - */ - public StickerSetInfo[] sets; - - /** - * Represents a list of sticker sets. - */ - public StickerSets() { - } - - /** - * Represents a list of sticker sets. - * - * @param totalCount Approximate total number of sticker sets found. - * @param sets List of sticker sets. - */ - public StickerSets(int totalCount, StickerSetInfo[] sets) { - this.totalCount = totalCount; - this.sets = sets; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1883828812; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of sticker. - */ - public abstract static class StickerType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - StickerTypeRegular.CONSTRUCTOR, - StickerTypeMask.CONSTRUCTOR, - StickerTypeCustomEmoji.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public StickerType() { - } - } - - /** - * The sticker is a regular sticker. - */ - public static class StickerTypeRegular extends StickerType { - - /** - * The sticker is a regular sticker. - */ - public StickerTypeRegular() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 56345973; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The sticker is a mask in WEBP format to be placed on photos or videos. - */ - public static class StickerTypeMask extends StickerType { - - /** - * The sticker is a mask in WEBP format to be placed on photos or videos. - */ - public StickerTypeMask() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1765394796; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The sticker is a custom emoji to be used inside message text and caption. - */ - public static class StickerTypeCustomEmoji extends StickerType { - - /** - * The sticker is a custom emoji to be used inside message text and caption. - */ - public StickerTypeCustomEmoji() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -120752249; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of stickers. - */ - public static class Stickers extends Object { - /** - * List of stickers. - */ - public Sticker[] stickers; - - /** - * Represents a list of stickers. - */ - public Stickers() { - } - - /** - * Represents a list of stickers. - * - * @param stickers List of stickers. - */ - public Stickers(Sticker[] stickers) { - this.stickers = stickers; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1974859260; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains the exact storage usage statistics split by chats and file type. - */ - public static class StorageStatistics extends Object { - /** - * Total size of files, in bytes. - */ - public long size; - /** - * Total number of files. - */ - public int count; - /** - * Statistics split by chats. - */ - public StorageStatisticsByChat[] byChat; - - /** - * Contains the exact storage usage statistics split by chats and file type. - */ - public StorageStatistics() { - } - - /** - * Contains the exact storage usage statistics split by chats and file type. - * - * @param size Total size of files, in bytes. - * @param count Total number of files. - * @param byChat Statistics split by chats. - */ - public StorageStatistics(long size, int count, StorageStatisticsByChat[] byChat) { - this.size = size; - this.count = count; - this.byChat = byChat; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 217237013; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains the storage usage statistics for a specific chat. - */ - public static class StorageStatisticsByChat extends Object { - /** - * Chat identifier; 0 if none. - */ - public long chatId; - /** - * Total size of the files in the chat, in bytes. - */ - public long size; - /** - * Total number of files in the chat. - */ - public int count; - /** - * Statistics split by file types. - */ - public StorageStatisticsByFileType[] byFileType; - - /** - * Contains the storage usage statistics for a specific chat. - */ - public StorageStatisticsByChat() { - } - - /** - * Contains the storage usage statistics for a specific chat. - * - * @param chatId Chat identifier; 0 if none. - * @param size Total size of the files in the chat, in bytes. - * @param count Total number of files in the chat. - * @param byFileType Statistics split by file types. - */ - public StorageStatisticsByChat(long chatId, long size, int count, StorageStatisticsByFileType[] byFileType) { - this.chatId = chatId; - this.size = size; - this.count = count; - this.byFileType = byFileType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 635434531; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains the storage usage statistics for a specific file type. - */ - public static class StorageStatisticsByFileType extends Object { - /** - * File type. - */ - public FileType fileType; - /** - * Total size of the files, in bytes. - */ - public long size; - /** - * Total number of files. - */ - public int count; - - /** - * Contains the storage usage statistics for a specific file type. - */ - public StorageStatisticsByFileType() { - } - - /** - * Contains the storage usage statistics for a specific file type. - * - * @param fileType File type. - * @param size Total size of the files, in bytes. - * @param count Total number of files. - */ - public StorageStatisticsByFileType(FileType fileType, long size, int count) { - this.fileType = fileType; - this.size = size; - this.count = count; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 714012840; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains approximate storage usage statistics, excluding files of unknown file type. - */ - public static class StorageStatisticsFast extends Object { - /** - * Approximate total size of files, in bytes. - */ - public long filesSize; - /** - * Approximate number of files. - */ - public int fileCount; - /** - * Size of the database. - */ - public long databaseSize; - /** - * Size of the language pack database. - */ - public long languagePackDatabaseSize; - /** - * Size of the TDLib internal log. - */ - public long logSize; - - /** - * Contains approximate storage usage statistics, excluding files of unknown file type. - */ - public StorageStatisticsFast() { - } - - /** - * Contains approximate storage usage statistics, excluding files of unknown file type. - * - * @param filesSize Approximate total size of files, in bytes. - * @param fileCount Approximate number of files. - * @param databaseSize Size of the database. - * @param languagePackDatabaseSize Size of the language pack database. - * @param logSize Size of the TDLib internal log. - */ - public StorageStatisticsFast(long filesSize, int fileCount, long databaseSize, long languagePackDatabaseSize, long logSize) { - this.filesSize = filesSize; - this.fileCount = fileCount; - this.databaseSize = databaseSize; - this.languagePackDatabaseSize = languagePackDatabaseSize; - this.logSize = logSize; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -884922271; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a purpose of an in-store payment. - */ - public abstract static class StorePaymentPurpose extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - StorePaymentPurposePremiumSubscription.CONSTRUCTOR, - StorePaymentPurposePremiumGift.CONSTRUCTOR, - StorePaymentPurposePremiumGiftCodes.CONSTRUCTOR, - StorePaymentPurposePremiumGiveaway.CONSTRUCTOR, - StorePaymentPurposeStarGiveaway.CONSTRUCTOR, - StorePaymentPurposeStars.CONSTRUCTOR, - StorePaymentPurposeGiftedStars.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public StorePaymentPurpose() { - } - } - - /** - * The user subscribing to Telegram Premium. - */ - public static class StorePaymentPurposePremiumSubscription extends StorePaymentPurpose { - /** - * Pass true if this is a restore of a Telegram Premium purchase; only for App Store. - */ - public boolean isRestore; - /** - * Pass true if this is an upgrade from a monthly subscription to early subscription; only for App Store. - */ - public boolean isUpgrade; - - /** - * The user subscribing to Telegram Premium. - */ - public StorePaymentPurposePremiumSubscription() { - } - - /** - * The user subscribing to Telegram Premium. - * - * @param isRestore Pass true if this is a restore of a Telegram Premium purchase; only for App Store. - * @param isUpgrade Pass true if this is an upgrade from a monthly subscription to early subscription; only for App Store. - */ - public StorePaymentPurposePremiumSubscription(boolean isRestore, boolean isUpgrade) { - this.isRestore = isRestore; - this.isUpgrade = isUpgrade; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1263894804; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user gifting Telegram Premium to another user. - */ - public static class StorePaymentPurposePremiumGift extends StorePaymentPurpose { - /** - * ISO 4217 currency code of the payment currency. - */ - public String currency; - /** - * Paid amount, in the smallest units of the currency. - */ - public long amount; - /** - * Identifiers of the user which will receive Telegram Premium. - */ - public long userId; - /** - * Text to show along with the gift codes; 0-getOption("gift_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed. - */ - public FormattedText text; - - /** - * The user gifting Telegram Premium to another user. - */ - public StorePaymentPurposePremiumGift() { - } - - /** - * The user gifting Telegram Premium to another user. - * - * @param currency ISO 4217 currency code of the payment currency. - * @param amount Paid amount, in the smallest units of the currency. - * @param userId Identifiers of the user which will receive Telegram Premium. - * @param text Text to show along with the gift codes; 0-getOption("gift_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed. - */ - public StorePaymentPurposePremiumGift(String currency, long amount, long userId, FormattedText text) { - this.currency = currency; - this.amount = amount; - this.userId = userId; - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -39502443; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user boosting a chat by creating Telegram Premium gift codes for other users. - */ - public static class StorePaymentPurposePremiumGiftCodes extends StorePaymentPurpose { - /** - * Identifier of the supergroup or channel chat, which will be automatically boosted by the users for duration of the Premium subscription and which is administered by the user. - */ - public long boostedChatId; - /** - * ISO 4217 currency code of the payment currency. - */ - public String currency; - /** - * Paid amount, in the smallest units of the currency. - */ - public long amount; - /** - * Identifiers of the users which can activate the gift codes. - */ - public long[] userIds; - /** - * Text to show along with the gift codes; 0-getOption("gift_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed. - */ - public FormattedText text; - - /** - * The user boosting a chat by creating Telegram Premium gift codes for other users. - */ - public StorePaymentPurposePremiumGiftCodes() { - } - - /** - * The user boosting a chat by creating Telegram Premium gift codes for other users. - * - * @param boostedChatId Identifier of the supergroup or channel chat, which will be automatically boosted by the users for duration of the Premium subscription and which is administered by the user. - * @param currency ISO 4217 currency code of the payment currency. - * @param amount Paid amount, in the smallest units of the currency. - * @param userIds Identifiers of the users which can activate the gift codes. - * @param text Text to show along with the gift codes; 0-getOption("gift_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed. - */ - public StorePaymentPurposePremiumGiftCodes(long boostedChatId, String currency, long amount, long[] userIds, FormattedText text) { - this.boostedChatId = boostedChatId; - this.currency = currency; - this.amount = amount; - this.userIds = userIds; - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1072286736; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user creating a Telegram Premium giveaway. - */ - public static class StorePaymentPurposePremiumGiveaway extends StorePaymentPurpose { - /** - * Giveaway parameters. - */ - public GiveawayParameters parameters; - /** - * ISO 4217 currency code of the payment currency. - */ - public String currency; - /** - * Paid amount, in the smallest units of the currency. - */ - public long amount; - - /** - * The user creating a Telegram Premium giveaway. - */ - public StorePaymentPurposePremiumGiveaway() { - } - - /** - * The user creating a Telegram Premium giveaway. - * - * @param parameters Giveaway parameters. - * @param currency ISO 4217 currency code of the payment currency. - * @param amount Paid amount, in the smallest units of the currency. - */ - public StorePaymentPurposePremiumGiveaway(GiveawayParameters parameters, String currency, long amount) { - this.parameters = parameters; - this.currency = currency; - this.amount = amount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1302624938; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user creating a Telegram Star giveaway. - */ - public static class StorePaymentPurposeStarGiveaway extends StorePaymentPurpose { - /** - * Giveaway parameters. - */ - public GiveawayParameters parameters; - /** - * ISO 4217 currency code of the payment currency. - */ - public String currency; - /** - * Paid amount, in the smallest units of the currency. - */ - public long amount; - /** - * The number of users to receive Telegram Stars. - */ - public int winnerCount; - /** - * The number of Telegram Stars to be distributed through the giveaway. - */ - public long starCount; - - /** - * The user creating a Telegram Star giveaway. - */ - public StorePaymentPurposeStarGiveaway() { - } - - /** - * The user creating a Telegram Star giveaway. - * - * @param parameters Giveaway parameters. - * @param currency ISO 4217 currency code of the payment currency. - * @param amount Paid amount, in the smallest units of the currency. - * @param winnerCount The number of users to receive Telegram Stars. - * @param starCount The number of Telegram Stars to be distributed through the giveaway. - */ - public StorePaymentPurposeStarGiveaway(GiveawayParameters parameters, String currency, long amount, int winnerCount, long starCount) { - this.parameters = parameters; - this.currency = currency; - this.amount = amount; - this.winnerCount = winnerCount; - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 211212441; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user buying Telegram Stars. - */ - public static class StorePaymentPurposeStars extends StorePaymentPurpose { - /** - * ISO 4217 currency code of the payment currency. - */ - public String currency; - /** - * Paid amount, in the smallest units of the currency. - */ - public long amount; - /** - * Number of bought Telegram Stars. - */ - public long starCount; - /** - * Identifier of the chat that is supposed to receive the Telegram Stars; pass 0 if none. - */ - public long chatId; - - /** - * The user buying Telegram Stars. - */ - public StorePaymentPurposeStars() { - } - - /** - * The user buying Telegram Stars. - * - * @param currency ISO 4217 currency code of the payment currency. - * @param amount Paid amount, in the smallest units of the currency. - * @param starCount Number of bought Telegram Stars. - * @param chatId Identifier of the chat that is supposed to receive the Telegram Stars; pass 0 if none. - */ - public StorePaymentPurposeStars(String currency, long amount, long starCount, long chatId) { - this.currency = currency; - this.amount = amount; - this.starCount = starCount; - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 410189263; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user buying Telegram Stars for other users. - */ - public static class StorePaymentPurposeGiftedStars extends StorePaymentPurpose { - /** - * Identifier of the user to which Telegram Stars are gifted. - */ - public long userId; - /** - * ISO 4217 currency code of the payment currency. - */ - public String currency; - /** - * Paid amount, in the smallest units of the currency. - */ - public long amount; - /** - * Number of bought Telegram Stars. - */ - public long starCount; - - /** - * The user buying Telegram Stars for other users. - */ - public StorePaymentPurposeGiftedStars() { - } - - /** - * The user buying Telegram Stars for other users. - * - * @param userId Identifier of the user to which Telegram Stars are gifted. - * @param currency ISO 4217 currency code of the payment currency. - * @param amount Paid amount, in the smallest units of the currency. - * @param starCount Number of bought Telegram Stars. - */ - public StorePaymentPurposeGiftedStars(long userId, String currency, long amount, long starCount) { - this.userId = userId; - this.currency = currency; - this.amount = amount; - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 893691428; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes an in-store transaction. - */ - public abstract static class StoreTransaction extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - StoreTransactionAppStore.CONSTRUCTOR, - StoreTransactionGooglePlay.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public StoreTransaction() { - } - } - - /** - * A purchase through App Store. - */ - public static class StoreTransactionAppStore extends StoreTransaction { - /** - * App Store receipt. - */ - public byte[] receipt; - - /** - * A purchase through App Store. - */ - public StoreTransactionAppStore() { - } - - /** - * A purchase through App Store. - * - * @param receipt App Store receipt. - */ - public StoreTransactionAppStore(byte[] receipt) { - this.receipt = receipt; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1625562441; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A purchase through Google Play. - */ - public static class StoreTransactionGooglePlay extends StoreTransaction { - /** - * Application package name. - */ - public String packageName; - /** - * Identifier of the purchased store product. - */ - public String storeProductId; - /** - * Google Play purchase token. - */ - public String purchaseToken; - - /** - * A purchase through Google Play. - */ - public StoreTransactionGooglePlay() { - } - - /** - * A purchase through Google Play. - * - * @param packageName Application package name. - * @param storeProductId Identifier of the purchased store product. - * @param purchaseToken Google Play purchase token. - */ - public StoreTransactionGooglePlay(String packageName, String storeProductId, String purchaseToken) { - this.packageName = packageName; - this.storeProductId = storeProductId; - this.purchaseToken = purchaseToken; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1094018617; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of stories. - */ - public static class Stories extends Object { - /** - * Approximate total number of stories found. - */ - public int totalCount; - /** - * The list of stories. - */ - public Story[] stories; - /** - * Identifiers of the pinned stories; returned only in getChatPostedToChatPageStories with fromStoryId == 0. - */ - public int[] pinnedStoryIds; - - /** - * Represents a list of stories. - */ - public Stories() { - } - - /** - * Represents a list of stories. - * - * @param totalCount Approximate total number of stories found. - * @param stories The list of stories. - * @param pinnedStoryIds Identifiers of the pinned stories; returned only in getChatPostedToChatPageStories with fromStoryId == 0. - */ - public Stories(int totalCount, Story[] stories, int[] pinnedStoryIds) { - this.totalCount = totalCount; - this.stories = stories; - this.pinnedStoryIds = pinnedStoryIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 670157595; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a story. - */ - public static class Story extends Object { - /** - * Unique story identifier among stories posted by the given chat. - */ - public int id; - /** - * Identifier of the chat that posted the story. - */ - public long posterChatId; - /** - * Identifier of the user or chat that posted the story; may be null if the story is posted on behalf of the posterChatId. - */ - @Nullable public MessageSender posterId; - /** - * Point in time (Unix timestamp) when the story was published. - */ - public int date; - /** - * True, if the story is being posted by the current user. - */ - public boolean isBeingPosted; - /** - * True, if the story is being edited by the current user. - */ - public boolean isBeingEdited; - /** - * True, if the story was edited. - */ - public boolean isEdited; - /** - * True, if the story is saved in the profile of the chat that posted it and will be available there after expiration. - */ - public boolean isPostedToChatPage; - /** - * True, if the story is visible only for the current user. - */ - public boolean isVisibleOnlyForSelf; - /** - * True, if the story can be added to an album using createStoryAlbum and addStoryAlbumStories. - */ - public boolean canBeAddedToAlbum; - /** - * True, if the story can be deleted. - */ - public boolean canBeDeleted; - /** - * True, if the story can be edited. - */ - public boolean canBeEdited; - /** - * True, if the story can be forwarded as a message or reposted as a story. Otherwise, screenshotting and saving of the story content must be also forbidden. - */ - public boolean canBeForwarded; - /** - * True, if the story can be replied in the chat with the user who posted the story. - */ - public boolean canBeReplied; - /** - * True, if the story privacy settings can be changed. - */ - public boolean canSetPrivacySettings; - /** - * True, if the story's isPostedToChatPage value can be changed. - */ - public boolean canToggleIsPostedToChatPage; - /** - * True, if the story statistics are available through getStoryStatistics. - */ - public boolean canGetStatistics; - /** - * True, if interactions with the story can be received through getStoryInteractions. - */ - public boolean canGetInteractions; - /** - * True, if users viewed the story can't be received, because the story has expired more than getOption("story_viewers_expiration_delay") seconds ago. - */ - public boolean hasExpiredViewers; - /** - * Information about the original story; may be null if the story wasn't reposted. - */ - @Nullable public StoryRepostInfo repostInfo; - /** - * Information about interactions with the story; may be null if the story isn't owned or there were no interactions. - */ - @Nullable public StoryInteractionInfo interactionInfo; - /** - * Type of the chosen reaction; may be null if none. - */ - @Nullable public ReactionType chosenReactionType; - /** - * Privacy rules affecting story visibility; may be approximate for non-owned stories. - */ - public StoryPrivacySettings privacySettings; - /** - * Content of the story. - */ - public StoryContent content; - /** - * Clickable areas to be shown on the story content. - */ - public StoryArea[] areas; - /** - * Caption of the story. - */ - public FormattedText caption; - /** - * Identifiers of story albums to which the story is added; only for manageable stories. - */ - public int[] albumIds; - - /** - * Represents a story. - */ - public Story() { - } - - /** - * Represents a story. - * - * @param id Unique story identifier among stories posted by the given chat. - * @param posterChatId Identifier of the chat that posted the story. - * @param posterId Identifier of the user or chat that posted the story; may be null if the story is posted on behalf of the posterChatId. - * @param date Point in time (Unix timestamp) when the story was published. - * @param isBeingPosted True, if the story is being posted by the current user. - * @param isBeingEdited True, if the story is being edited by the current user. - * @param isEdited True, if the story was edited. - * @param isPostedToChatPage True, if the story is saved in the profile of the chat that posted it and will be available there after expiration. - * @param isVisibleOnlyForSelf True, if the story is visible only for the current user. - * @param canBeAddedToAlbum True, if the story can be added to an album using createStoryAlbum and addStoryAlbumStories. - * @param canBeDeleted True, if the story can be deleted. - * @param canBeEdited True, if the story can be edited. - * @param canBeForwarded True, if the story can be forwarded as a message or reposted as a story. Otherwise, screenshotting and saving of the story content must be also forbidden. - * @param canBeReplied True, if the story can be replied in the chat with the user who posted the story. - * @param canSetPrivacySettings True, if the story privacy settings can be changed. - * @param canToggleIsPostedToChatPage True, if the story's isPostedToChatPage value can be changed. - * @param canGetStatistics True, if the story statistics are available through getStoryStatistics. - * @param canGetInteractions True, if interactions with the story can be received through getStoryInteractions. - * @param hasExpiredViewers True, if users viewed the story can't be received, because the story has expired more than getOption("story_viewers_expiration_delay") seconds ago. - * @param repostInfo Information about the original story; may be null if the story wasn't reposted. - * @param interactionInfo Information about interactions with the story; may be null if the story isn't owned or there were no interactions. - * @param chosenReactionType Type of the chosen reaction; may be null if none. - * @param privacySettings Privacy rules affecting story visibility; may be approximate for non-owned stories. - * @param content Content of the story. - * @param areas Clickable areas to be shown on the story content. - * @param caption Caption of the story. - * @param albumIds Identifiers of story albums to which the story is added; only for manageable stories. - */ - public Story(int id, long posterChatId, MessageSender posterId, int date, boolean isBeingPosted, boolean isBeingEdited, boolean isEdited, boolean isPostedToChatPage, boolean isVisibleOnlyForSelf, boolean canBeAddedToAlbum, boolean canBeDeleted, boolean canBeEdited, boolean canBeForwarded, boolean canBeReplied, boolean canSetPrivacySettings, boolean canToggleIsPostedToChatPage, boolean canGetStatistics, boolean canGetInteractions, boolean hasExpiredViewers, StoryRepostInfo repostInfo, StoryInteractionInfo interactionInfo, ReactionType chosenReactionType, StoryPrivacySettings privacySettings, StoryContent content, StoryArea[] areas, FormattedText caption, int[] albumIds) { - this.id = id; - this.posterChatId = posterChatId; - this.posterId = posterId; - this.date = date; - this.isBeingPosted = isBeingPosted; - this.isBeingEdited = isBeingEdited; - this.isEdited = isEdited; - this.isPostedToChatPage = isPostedToChatPage; - this.isVisibleOnlyForSelf = isVisibleOnlyForSelf; - this.canBeAddedToAlbum = canBeAddedToAlbum; - this.canBeDeleted = canBeDeleted; - this.canBeEdited = canBeEdited; - this.canBeForwarded = canBeForwarded; - this.canBeReplied = canBeReplied; - this.canSetPrivacySettings = canSetPrivacySettings; - this.canToggleIsPostedToChatPage = canToggleIsPostedToChatPage; - this.canGetStatistics = canGetStatistics; - this.canGetInteractions = canGetInteractions; - this.hasExpiredViewers = hasExpiredViewers; - this.repostInfo = repostInfo; - this.interactionInfo = interactionInfo; - this.chosenReactionType = chosenReactionType; - this.privacySettings = privacySettings; - this.content = content; - this.areas = areas; - this.caption = caption; - this.albumIds = albumIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1551193142; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes album of stories. - */ - public static class StoryAlbum extends Object { - /** - * Unique identifier of the album. - */ - public int id; - /** - * Name of the album. - */ - public String name; - /** - * Icon of the album; may be null if none. - */ - @Nullable public Photo photoIcon; - /** - * Video icon of the album; may be null if none. - */ - @Nullable public Video videoIcon; - - /** - * Describes album of stories. - */ - public StoryAlbum() { - } - - /** - * Describes album of stories. - * - * @param id Unique identifier of the album. - * @param name Name of the album. - * @param photoIcon Icon of the album; may be null if none. - * @param videoIcon Video icon of the album; may be null if none. - */ - public StoryAlbum(int id, String name, Photo photoIcon, Video videoIcon) { - this.id = id; - this.name = name; - this.photoIcon = photoIcon; - this.videoIcon = videoIcon; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -346189829; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of story albums. - */ - public static class StoryAlbums extends Object { - /** - * List of story albums. - */ - public StoryAlbum[] albums; - - /** - * Represents a list of story albums. - */ - public StoryAlbums() { - } - - /** - * Represents a list of story albums. - * - * @param albums List of story albums. - */ - public StoryAlbums(StoryAlbum[] albums) { - this.albums = albums; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2123240062; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a clickable rectangle area on a story media. - */ - public static class StoryArea extends Object { - /** - * Position of the area. - */ - public StoryAreaPosition position; - /** - * Type of the area. - */ - public StoryAreaType type; - - /** - * Describes a clickable rectangle area on a story media. - */ - public StoryArea() { - } - - /** - * Describes a clickable rectangle area on a story media. - * - * @param position Position of the area. - * @param type Type of the area. - */ - public StoryArea(StoryAreaPosition position, StoryAreaType type) { - this.position = position; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -906033314; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes position of a clickable rectangle area on a story media. - */ - public static class StoryAreaPosition extends Object { - /** - * The abscissa of the rectangle's center, as a percentage of the media width. - */ - public double xPercentage; - /** - * The ordinate of the rectangle's center, as a percentage of the media height. - */ - public double yPercentage; - /** - * The width of the rectangle, as a percentage of the media width. - */ - public double widthPercentage; - /** - * The height of the rectangle, as a percentage of the media height. - */ - public double heightPercentage; - /** - * Clockwise rotation angle of the rectangle, in degrees; 0-360. - */ - public double rotationAngle; - /** - * The radius of the rectangle corner rounding, as a percentage of the media width. - */ - public double cornerRadiusPercentage; - - /** - * Describes position of a clickable rectangle area on a story media. - */ - public StoryAreaPosition() { - } - - /** - * Describes position of a clickable rectangle area on a story media. - * - * @param xPercentage The abscissa of the rectangle's center, as a percentage of the media width. - * @param yPercentage The ordinate of the rectangle's center, as a percentage of the media height. - * @param widthPercentage The width of the rectangle, as a percentage of the media width. - * @param heightPercentage The height of the rectangle, as a percentage of the media height. - * @param rotationAngle Clockwise rotation angle of the rectangle, in degrees; 0-360. - * @param cornerRadiusPercentage The radius of the rectangle corner rounding, as a percentage of the media width. - */ - public StoryAreaPosition(double xPercentage, double yPercentage, double widthPercentage, double heightPercentage, double rotationAngle, double cornerRadiusPercentage) { - this.xPercentage = xPercentage; - this.yPercentage = yPercentage; - this.widthPercentage = widthPercentage; - this.heightPercentage = heightPercentage; - this.rotationAngle = rotationAngle; - this.cornerRadiusPercentage = cornerRadiusPercentage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1533023124; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of clickable area on a story media. - */ - public abstract static class StoryAreaType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - StoryAreaTypeLocation.CONSTRUCTOR, - StoryAreaTypeVenue.CONSTRUCTOR, - StoryAreaTypeSuggestedReaction.CONSTRUCTOR, - StoryAreaTypeMessage.CONSTRUCTOR, - StoryAreaTypeLink.CONSTRUCTOR, - StoryAreaTypeWeather.CONSTRUCTOR, - StoryAreaTypeUpgradedGift.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public StoryAreaType() { - } - } - - /** - * An area pointing to a location. - */ - public static class StoryAreaTypeLocation extends StoryAreaType { - /** - * The location. - */ - public Location location; - /** - * Address of the location; may be null if unknown. - */ - @Nullable public LocationAddress address; - - /** - * An area pointing to a location. - */ - public StoryAreaTypeLocation() { - } - - /** - * An area pointing to a location. - * - * @param location The location. - * @param address Address of the location; may be null if unknown. - */ - public StoryAreaTypeLocation(Location location, LocationAddress address) { - this.location = location; - this.address = address; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1464612189; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An area pointing to a venue. - */ - public static class StoryAreaTypeVenue extends StoryAreaType { - /** - * Information about the venue. - */ - public Venue venue; - - /** - * An area pointing to a venue. - */ - public StoryAreaTypeVenue() { - } - - /** - * An area pointing to a venue. - * - * @param venue Information about the venue. - */ - public StoryAreaTypeVenue(Venue venue) { - this.venue = venue; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 414076166; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An area pointing to a suggested reaction. App needs to show a clickable reaction on the area and call setStoryReaction when the are is clicked. - */ - public static class StoryAreaTypeSuggestedReaction extends StoryAreaType { - /** - * Type of the reaction. - */ - public ReactionType reactionType; - /** - * Number of times the reaction was added. - */ - public int totalCount; - /** - * True, if reaction has a dark background. - */ - public boolean isDark; - /** - * True, if reaction corner is flipped. - */ - public boolean isFlipped; - - /** - * An area pointing to a suggested reaction. App needs to show a clickable reaction on the area and call setStoryReaction when the are is clicked. - */ - public StoryAreaTypeSuggestedReaction() { - } - - /** - * An area pointing to a suggested reaction. App needs to show a clickable reaction on the area and call setStoryReaction when the are is clicked. - * - * @param reactionType Type of the reaction. - * @param totalCount Number of times the reaction was added. - * @param isDark True, if reaction has a dark background. - * @param isFlipped True, if reaction corner is flipped. - */ - public StoryAreaTypeSuggestedReaction(ReactionType reactionType, int totalCount, boolean isDark, boolean isFlipped) { - this.reactionType = reactionType; - this.totalCount = totalCount; - this.isDark = isDark; - this.isFlipped = isFlipped; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -111177092; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An area pointing to a message. - */ - public static class StoryAreaTypeMessage extends StoryAreaType { - /** - * Identifier of the chat with the message. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - - /** - * An area pointing to a message. - */ - public StoryAreaTypeMessage() { - } - - /** - * An area pointing to a message. - * - * @param chatId Identifier of the chat with the message. - * @param messageId Identifier of the message. - */ - public StoryAreaTypeMessage(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1074825548; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An area pointing to a HTTP or tg:// link. - */ - public static class StoryAreaTypeLink extends StoryAreaType { - /** - * HTTP or tg:// URL to be opened when the area is clicked. - */ - public String url; - - /** - * An area pointing to a HTTP or tg:// link. - */ - public StoryAreaTypeLink() { - } - - /** - * An area pointing to a HTTP or tg:// link. - * - * @param url HTTP or tg:// URL to be opened when the area is clicked. - */ - public StoryAreaTypeLink(String url) { - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -127770235; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An area with information about weather. - */ - public static class StoryAreaTypeWeather extends StoryAreaType { - /** - * Temperature, in degree Celsius. - */ - public double temperature; - /** - * Emoji representing the weather. - */ - public String emoji; - /** - * A color of the area background in the ARGB format. - */ - public int backgroundColor; - - /** - * An area with information about weather. - */ - public StoryAreaTypeWeather() { - } - - /** - * An area with information about weather. - * - * @param temperature Temperature, in degree Celsius. - * @param emoji Emoji representing the weather. - * @param backgroundColor A color of the area background in the ARGB format. - */ - public StoryAreaTypeWeather(double temperature, String emoji, int backgroundColor) { - this.temperature = temperature; - this.emoji = emoji; - this.backgroundColor = backgroundColor; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1504150082; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An area with an upgraded gift. - */ - public static class StoryAreaTypeUpgradedGift extends StoryAreaType { - /** - * Unique name of the upgraded gift. - */ - public String giftName; - - /** - * An area with an upgraded gift. - */ - public StoryAreaTypeUpgradedGift() { - } - - /** - * An area with an upgraded gift. - * - * @param giftName Unique name of the upgraded gift. - */ - public StoryAreaTypeUpgradedGift(String giftName) { - this.giftName = giftName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 760281479; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains the content of a story. - */ - public abstract static class StoryContent extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - StoryContentPhoto.CONSTRUCTOR, - StoryContentVideo.CONSTRUCTOR, - StoryContentLive.CONSTRUCTOR, - StoryContentUnsupported.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public StoryContent() { - } - } - - /** - * A photo story. - */ - public static class StoryContentPhoto extends StoryContent { - /** - * The photo. - */ - public Photo photo; - - /** - * A photo story. - */ - public StoryContentPhoto() { - } - - /** - * A photo story. - * - * @param photo The photo. - */ - public StoryContentPhoto(Photo photo) { - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -731971504; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A video story. - */ - public static class StoryContentVideo extends StoryContent { - /** - * The video in MPEG4 format. - */ - public StoryVideo video; - /** - * Alternative version of the video in MPEG4 format, encoded with H.264 codec; may be null. - */ - @Nullable public StoryVideo alternativeVideo; - - /** - * A video story. - */ - public StoryContentVideo() { - } - - /** - * A video story. - * - * @param video The video in MPEG4 format. - * @param alternativeVideo Alternative version of the video in MPEG4 format, encoded with H.264 codec; may be null. - */ - public StoryContentVideo(StoryVideo video, StoryVideo alternativeVideo) { - this.video = video; - this.alternativeVideo = alternativeVideo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1291754842; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A live story. - */ - public static class StoryContentLive extends StoryContent { - /** - * Identifier of the corresponding group call. The group call can be received through the method getGroupCall. - */ - public int groupCallId; - /** - * True, if the call is an RTMP stream instead of an ordinary group call. - */ - public boolean isRtmpStream; - - /** - * A live story. - */ - public StoryContentLive() { - } - - /** - * A live story. - * - * @param groupCallId Identifier of the corresponding group call. The group call can be received through the method getGroupCall. - * @param isRtmpStream True, if the call is an RTMP stream instead of an ordinary group call. - */ - public StoryContentLive(int groupCallId, boolean isRtmpStream) { - this.groupCallId = groupCallId; - this.isRtmpStream = isRtmpStream; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1192628634; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A story content that is not supported in the current TDLib version. - */ - public static class StoryContentUnsupported extends StoryContent { - - /** - * A story content that is not supported in the current TDLib version. - */ - public StoryContentUnsupported() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2033715858; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains the type of the content of a story. - */ - public abstract static class StoryContentType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - StoryContentTypePhoto.CONSTRUCTOR, - StoryContentTypeVideo.CONSTRUCTOR, - StoryContentTypeLive.CONSTRUCTOR, - StoryContentTypeUnsupported.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public StoryContentType() { - } - } - - /** - * A photo story. - */ - public static class StoryContentTypePhoto extends StoryContentType { - - /** - * A photo story. - */ - public StoryContentTypePhoto() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1568510965; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A video story. - */ - public static class StoryContentTypeVideo extends StoryContentType { - - /** - * A video story. - */ - public StoryContentTypeVideo() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -573976899; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A live story. - */ - public static class StoryContentTypeLive extends StoryContentType { - - /** - * A live story. - */ - public StoryContentTypeLive() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -659651117; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A story of unknown content type. - */ - public static class StoryContentTypeUnsupported extends StoryContentType { - - /** - * A story of unknown content type. - */ - public StoryContentTypeUnsupported() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 642311105; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains identifier of a story along with identifier of the chat that posted it. - */ - public static class StoryFullId extends Object { - /** - * Identifier of the chat that posted the story. - */ - public long posterChatId; - /** - * Unique story identifier among stories of the chat. - */ - public int storyId; - - /** - * Contains identifier of a story along with identifier of the chat that posted it. - */ - public StoryFullId() { - } - - /** - * Contains identifier of a story along with identifier of the chat that posted it. - * - * @param posterChatId Identifier of the chat that posted the story. - * @param storyId Unique story identifier among stories of the chat. - */ - public StoryFullId(long posterChatId, int storyId) { - this.posterChatId = posterChatId; - this.storyId = storyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 765952419; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains basic information about a story. - */ - public static class StoryInfo extends Object { - /** - * Unique story identifier among stories of the chat. - */ - public int storyId; - /** - * Point in time (Unix timestamp) when the story was published. - */ - public int date; - /** - * True, if the story is available only to close friends. - */ - public boolean isForCloseFriends; - /** - * True, if the story is a live story. - */ - public boolean isLive; - - /** - * Contains basic information about a story. - */ - public StoryInfo() { - } - - /** - * Contains basic information about a story. - * - * @param storyId Unique story identifier among stories of the chat. - * @param date Point in time (Unix timestamp) when the story was published. - * @param isForCloseFriends True, if the story is available only to close friends. - * @param isLive True, if the story is a live story. - */ - public StoryInfo(int storyId, int date, boolean isForCloseFriends, boolean isLive) { - this.storyId = storyId; - this.date = date; - this.isForCloseFriends = isForCloseFriends; - this.isLive = isLive; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 182159362; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents interaction with a story. - */ - public static class StoryInteraction extends Object { - /** - * Identifier of the user or chat that made the interaction. - */ - public MessageSender actorId; - /** - * Approximate point in time (Unix timestamp) when the interaction happened. - */ - public int interactionDate; - /** - * Block list to which the actor is added; may be null if none or for chat stories. - */ - @Nullable public BlockList blockList; - /** - * Type of the interaction. - */ - public StoryInteractionType type; - - /** - * Represents interaction with a story. - */ - public StoryInteraction() { - } - - /** - * Represents interaction with a story. - * - * @param actorId Identifier of the user or chat that made the interaction. - * @param interactionDate Approximate point in time (Unix timestamp) when the interaction happened. - * @param blockList Block list to which the actor is added; may be null if none or for chat stories. - * @param type Type of the interaction. - */ - public StoryInteraction(MessageSender actorId, int interactionDate, BlockList blockList, StoryInteractionType type) { - this.actorId = actorId; - this.interactionDate = interactionDate; - this.blockList = blockList; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -702229982; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about interactions with a story. - */ - public static class StoryInteractionInfo extends Object { - /** - * Number of times the story was viewed. - */ - public int viewCount; - /** - * Number of times the story was forwarded; 0 if none or unknown. - */ - public int forwardCount; - /** - * Number of reactions added to the story; 0 if none or unknown. - */ - public int reactionCount; - /** - * Identifiers of at most 3 recent viewers of the story. - */ - public long[] recentViewerUserIds; - - /** - * Contains information about interactions with a story. - */ - public StoryInteractionInfo() { - } - - /** - * Contains information about interactions with a story. - * - * @param viewCount Number of times the story was viewed. - * @param forwardCount Number of times the story was forwarded; 0 if none or unknown. - * @param reactionCount Number of reactions added to the story; 0 if none or unknown. - * @param recentViewerUserIds Identifiers of at most 3 recent viewers of the story. - */ - public StoryInteractionInfo(int viewCount, int forwardCount, int reactionCount, long[] recentViewerUserIds) { - this.viewCount = viewCount; - this.forwardCount = forwardCount; - this.reactionCount = reactionCount; - this.recentViewerUserIds = recentViewerUserIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -846542065; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of interaction with a story. - */ - public abstract static class StoryInteractionType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - StoryInteractionTypeView.CONSTRUCTOR, - StoryInteractionTypeForward.CONSTRUCTOR, - StoryInteractionTypeRepost.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public StoryInteractionType() { - } - } - - /** - * A view of the story. - */ - public static class StoryInteractionTypeView extends StoryInteractionType { - /** - * Type of the reaction that was chosen by the viewer; may be null if none. - */ - @Nullable public ReactionType chosenReactionType; - - /** - * A view of the story. - */ - public StoryInteractionTypeView() { - } - - /** - * A view of the story. - * - * @param chosenReactionType Type of the reaction that was chosen by the viewer; may be null if none. - */ - public StoryInteractionTypeView(ReactionType chosenReactionType) { - this.chosenReactionType = chosenReactionType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1407399888; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A forward of the story as a message. - */ - public static class StoryInteractionTypeForward extends StoryInteractionType { - /** - * The message with story forward. - */ - public Message message; - - /** - * A forward of the story as a message. - */ - public StoryInteractionTypeForward() { - } - - /** - * A forward of the story as a message. - * - * @param message The message with story forward. - */ - public StoryInteractionTypeForward(Message message) { - this.message = message; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 668089599; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A repost of the story as a story. - */ - public static class StoryInteractionTypeRepost extends StoryInteractionType { - /** - * The reposted story. - */ - public Story story; - - /** - * A repost of the story as a story. - */ - public StoryInteractionTypeRepost() { - } - - /** - * A repost of the story as a story. - * - * @param story The reposted story. - */ - public StoryInteractionTypeRepost(Story story) { - this.story = story; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1021150780; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of interactions with a story. - */ - public static class StoryInteractions extends Object { - /** - * Approximate total number of interactions found. - */ - public int totalCount; - /** - * Approximate total number of found forwards and reposts; always 0 for chat stories. - */ - public int totalForwardCount; - /** - * Approximate total number of found reactions; always 0 for chat stories. - */ - public int totalReactionCount; - /** - * List of story interactions. - */ - public StoryInteraction[] interactions; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Represents a list of interactions with a story. - */ - public StoryInteractions() { - } - - /** - * Represents a list of interactions with a story. - * - * @param totalCount Approximate total number of interactions found. - * @param totalForwardCount Approximate total number of found forwards and reposts; always 0 for chat stories. - * @param totalReactionCount Approximate total number of found reactions; always 0 for chat stories. - * @param interactions List of story interactions. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public StoryInteractions(int totalCount, int totalForwardCount, int totalReactionCount, StoryInteraction[] interactions, String nextOffset) { - this.totalCount = totalCount; - this.totalForwardCount = totalForwardCount; - this.totalReactionCount = totalReactionCount; - this.interactions = interactions; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1537062962; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a list of stories. - */ - public abstract static class StoryList extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - StoryListMain.CONSTRUCTOR, - StoryListArchive.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public StoryList() { - } - } - - /** - * The list of stories, shown in the main chat list and folder chat lists. - */ - public static class StoryListMain extends StoryList { - - /** - * The list of stories, shown in the main chat list and folder chat lists. - */ - public StoryListMain() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -672222209; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of stories, shown in the Arvhive chat list. - */ - public static class StoryListArchive extends StoryList { - - /** - * The list of stories, shown in the Arvhive chat list. - */ - public StoryListArchive() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -41900223; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains information about the origin of a story that was reposted. - */ - public abstract static class StoryOrigin extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - StoryOriginPublicStory.CONSTRUCTOR, - StoryOriginHiddenUser.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public StoryOrigin() { - } - } - - /** - * The original story was a public story that was posted by a known chat. - */ - public static class StoryOriginPublicStory extends StoryOrigin { - /** - * Identifier of the chat that posted original story. - */ - public long chatId; - /** - * Story identifier of the original story. - */ - public int storyId; - - /** - * The original story was a public story that was posted by a known chat. - */ - public StoryOriginPublicStory() { - } - - /** - * The original story was a public story that was posted by a known chat. - * - * @param chatId Identifier of the chat that posted original story. - * @param storyId Story identifier of the original story. - */ - public StoryOriginPublicStory(long chatId, int storyId) { - this.chatId = chatId; - this.storyId = storyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 741842878; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The original story was posted by an unknown user. - */ - public static class StoryOriginHiddenUser extends StoryOrigin { - /** - * Name of the user or the chat that posted the story. - */ - public String posterName; - - /** - * The original story was posted by an unknown user. - */ - public StoryOriginHiddenUser() { - } - - /** - * The original story was posted by an unknown user. - * - * @param posterName Name of the user or the chat that posted the story. - */ - public StoryOriginHiddenUser(String posterName) { - this.posterName = posterName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -96348585; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes privacy settings of a story. - */ - public abstract static class StoryPrivacySettings extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - StoryPrivacySettingsEveryone.CONSTRUCTOR, - StoryPrivacySettingsContacts.CONSTRUCTOR, - StoryPrivacySettingsCloseFriends.CONSTRUCTOR, - StoryPrivacySettingsSelectedUsers.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public StoryPrivacySettings() { - } - } - - /** - * The story can be viewed by everyone. - */ - public static class StoryPrivacySettingsEveryone extends StoryPrivacySettings { - /** - * Identifiers of the users that can't see the story; always unknown and empty for non-owned stories. - */ - public long[] exceptUserIds; - - /** - * The story can be viewed by everyone. - */ - public StoryPrivacySettingsEveryone() { - } - - /** - * The story can be viewed by everyone. - * - * @param exceptUserIds Identifiers of the users that can't see the story; always unknown and empty for non-owned stories. - */ - public StoryPrivacySettingsEveryone(long[] exceptUserIds) { - this.exceptUserIds = exceptUserIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 890847843; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The story can be viewed by all contacts except chosen users. - */ - public static class StoryPrivacySettingsContacts extends StoryPrivacySettings { - /** - * User identifiers of the contacts that can't see the story; always unknown and empty for non-owned stories. - */ - public long[] exceptUserIds; - - /** - * The story can be viewed by all contacts except chosen users. - */ - public StoryPrivacySettingsContacts() { - } - - /** - * The story can be viewed by all contacts except chosen users. - * - * @param exceptUserIds User identifiers of the contacts that can't see the story; always unknown and empty for non-owned stories. - */ - public StoryPrivacySettingsContacts(long[] exceptUserIds) { - this.exceptUserIds = exceptUserIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 50285309; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The story can be viewed by all close friends. - */ - public static class StoryPrivacySettingsCloseFriends extends StoryPrivacySettings { - - /** - * The story can be viewed by all close friends. - */ - public StoryPrivacySettingsCloseFriends() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2097122144; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The story can be viewed by certain specified users. - */ - public static class StoryPrivacySettingsSelectedUsers extends StoryPrivacySettings { - /** - * Identifiers of the users; always unknown and empty for non-owned stories. - */ - public long[] userIds; - - /** - * The story can be viewed by certain specified users. - */ - public StoryPrivacySettingsSelectedUsers() { - } - - /** - * The story can be viewed by certain specified users. - * - * @param userIds Identifiers of the users; always unknown and empty for non-owned stories. - */ - public StoryPrivacySettingsSelectedUsers(long[] userIds) { - this.userIds = userIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1885772602; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about original story that was reposted. - */ - public static class StoryRepostInfo extends Object { - /** - * Origin of the story that was reposted. - */ - public StoryOrigin origin; - /** - * True, if story content was modified during reposting; otherwise, story wasn't modified. - */ - public boolean isContentModified; - - /** - * Contains information about original story that was reposted. - */ - public StoryRepostInfo() { - } - - /** - * Contains information about original story that was reposted. - * - * @param origin Origin of the story that was reposted. - * @param isContentModified True, if story content was modified during reposting; otherwise, story wasn't modified. - */ - public StoryRepostInfo(StoryOrigin origin, boolean isContentModified) { - this.origin = origin; - this.isContentModified = isContentModified; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -8412096; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A detailed statistics about a story. - */ - public static class StoryStatistics extends Object { - /** - * A graph containing number of story views and shares. - */ - public StatisticalGraph storyInteractionGraph; - /** - * A graph containing number of story reactions. - */ - public StatisticalGraph storyReactionGraph; - - /** - * A detailed statistics about a story. - */ - public StoryStatistics() { - } - - /** - * A detailed statistics about a story. - * - * @param storyInteractionGraph A graph containing number of story views and shares. - * @param storyReactionGraph A graph containing number of story reactions. - */ - public StoryStatistics(StatisticalGraph storyInteractionGraph, StatisticalGraph storyReactionGraph) { - this.storyInteractionGraph = storyInteractionGraph; - this.storyReactionGraph = storyReactionGraph; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1178897259; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a video file posted as a story. - */ - public static class StoryVideo extends Object { - /** - * Duration of the video, in seconds. - */ - public double duration; - /** - * Video width. - */ - public int width; - /** - * Video height. - */ - public int height; - /** - * True, if stickers were added to the video. The list of corresponding sticker sets can be received using getAttachedStickerSets. - */ - public boolean hasStickers; - /** - * True, if the video has no sound. - */ - public boolean isAnimation; - /** - * Video minithumbnail; may be null. - */ - @Nullable public Minithumbnail minithumbnail; - /** - * Video thumbnail in JPEG or MPEG4 format; may be null. - */ - @Nullable public Thumbnail thumbnail; - /** - * Size of file prefix, which is expected to be preloaded, in bytes. - */ - public int preloadPrefixSize; - /** - * Timestamp of the frame used as video thumbnail. - */ - public double coverFrameTimestamp; - /** - * File containing the video. - */ - public File video; - - /** - * Describes a video file posted as a story. - */ - public StoryVideo() { - } - - /** - * Describes a video file posted as a story. - * - * @param duration Duration of the video, in seconds. - * @param width Video width. - * @param height Video height. - * @param hasStickers True, if stickers were added to the video. The list of corresponding sticker sets can be received using getAttachedStickerSets. - * @param isAnimation True, if the video has no sound. - * @param minithumbnail Video minithumbnail; may be null. - * @param thumbnail Video thumbnail in JPEG or MPEG4 format; may be null. - * @param preloadPrefixSize Size of file prefix, which is expected to be preloaded, in bytes. - * @param coverFrameTimestamp Timestamp of the frame used as video thumbnail. - * @param video File containing the video. - */ - public StoryVideo(double duration, int width, int height, boolean hasStickers, boolean isAnimation, Minithumbnail minithumbnail, Thumbnail thumbnail, int preloadPrefixSize, double coverFrameTimestamp, File video) { - this.duration = duration; - this.width = width; - this.height = height; - this.hasStickers = hasStickers; - this.isAnimation = isAnimation; - this.minithumbnail = minithumbnail; - this.thumbnail = thumbnail; - this.preloadPrefixSize = preloadPrefixSize; - this.coverFrameTimestamp = coverFrameTimestamp; - this.video = video; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1445661253; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes an action suggested to the current user. - */ - public abstract static class SuggestedAction extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - SuggestedActionEnableArchiveAndMuteNewChats.CONSTRUCTOR, - SuggestedActionCheckPassword.CONSTRUCTOR, - SuggestedActionCheckPhoneNumber.CONSTRUCTOR, - SuggestedActionViewChecksHint.CONSTRUCTOR, - SuggestedActionConvertToBroadcastGroup.CONSTRUCTOR, - SuggestedActionSetPassword.CONSTRUCTOR, - SuggestedActionUpgradePremium.CONSTRUCTOR, - SuggestedActionRestorePremium.CONSTRUCTOR, - SuggestedActionSubscribeToAnnualPremium.CONSTRUCTOR, - SuggestedActionGiftPremiumForChristmas.CONSTRUCTOR, - SuggestedActionSetBirthdate.CONSTRUCTOR, - SuggestedActionSetProfilePhoto.CONSTRUCTOR, - SuggestedActionExtendPremium.CONSTRUCTOR, - SuggestedActionExtendStarSubscriptions.CONSTRUCTOR, - SuggestedActionCustom.CONSTRUCTOR, - SuggestedActionSetLoginEmailAddress.CONSTRUCTOR, - SuggestedActionAddLoginPasskey.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public SuggestedAction() { - } - } - - /** - * Suggests the user to enable archiveAndMuteNewChatsFromUnknownUsers setting in archiveChatListSettings. - */ - public static class SuggestedActionEnableArchiveAndMuteNewChats extends SuggestedAction { - - /** - * Suggests the user to enable archiveAndMuteNewChatsFromUnknownUsers setting in archiveChatListSettings. - */ - public SuggestedActionEnableArchiveAndMuteNewChats() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2017586255; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Suggests the user to check whether they still remember their 2-step verification password. - */ - public static class SuggestedActionCheckPassword extends SuggestedAction { - - /** - * Suggests the user to check whether they still remember their 2-step verification password. - */ - public SuggestedActionCheckPassword() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1910534839; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Suggests the user to check whether authorization phone number is correct and change the phone number if it is inaccessible. - */ - public static class SuggestedActionCheckPhoneNumber extends SuggestedAction { - - /** - * Suggests the user to check whether authorization phone number is correct and change the phone number if it is inaccessible. - */ - public SuggestedActionCheckPhoneNumber() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 648771563; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Suggests the user to view a hint about the meaning of one and two check marks on sent messages. - */ - public static class SuggestedActionViewChecksHint extends SuggestedAction { - - /** - * Suggests the user to view a hint about the meaning of one and two check marks on sent messages. - */ - public SuggestedActionViewChecksHint() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 891303239; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Suggests the user to convert specified supergroup to a broadcast group. - */ - public static class SuggestedActionConvertToBroadcastGroup extends SuggestedAction { - /** - * Supergroup identifier. - */ - public long supergroupId; - - /** - * Suggests the user to convert specified supergroup to a broadcast group. - */ - public SuggestedActionConvertToBroadcastGroup() { - } - - /** - * Suggests the user to convert specified supergroup to a broadcast group. - * - * @param supergroupId Supergroup identifier. - */ - public SuggestedActionConvertToBroadcastGroup(long supergroupId) { - this.supergroupId = supergroupId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -965071304; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Suggests the user to set a 2-step verification password to be able to log in again. - */ - public static class SuggestedActionSetPassword extends SuggestedAction { - /** - * The number of days to pass between consecutive authorizations if the user declines to set password; if 0, then the user is advised to set the password for security reasons. - */ - public int authorizationDelay; - - /** - * Suggests the user to set a 2-step verification password to be able to log in again. - */ - public SuggestedActionSetPassword() { - } - - /** - * Suggests the user to set a 2-step verification password to be able to log in again. - * - * @param authorizationDelay The number of days to pass between consecutive authorizations if the user declines to set password; if 0, then the user is advised to set the password for security reasons. - */ - public SuggestedActionSetPassword(int authorizationDelay) { - this.authorizationDelay = authorizationDelay; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1863613848; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Suggests the user to upgrade the Premium subscription from monthly payments to annual payments. - */ - public static class SuggestedActionUpgradePremium extends SuggestedAction { - - /** - * Suggests the user to upgrade the Premium subscription from monthly payments to annual payments. - */ - public SuggestedActionUpgradePremium() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1890220539; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Suggests the user to restore a recently expired Premium subscription. - */ - public static class SuggestedActionRestorePremium extends SuggestedAction { - - /** - * Suggests the user to restore a recently expired Premium subscription. - */ - public SuggestedActionRestorePremium() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -385229468; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Suggests the user to subscribe to the Premium subscription with annual payments. - */ - public static class SuggestedActionSubscribeToAnnualPremium extends SuggestedAction { - - /** - * Suggests the user to subscribe to the Premium subscription with annual payments. - */ - public SuggestedActionSubscribeToAnnualPremium() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 373913787; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Suggests the user to gift Telegram Premium to friends for Christmas. - */ - public static class SuggestedActionGiftPremiumForChristmas extends SuggestedAction { - - /** - * Suggests the user to gift Telegram Premium to friends for Christmas. - */ - public SuggestedActionGiftPremiumForChristmas() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1816924561; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Suggests the user to set birthdate. - */ - public static class SuggestedActionSetBirthdate extends SuggestedAction { - - /** - * Suggests the user to set birthdate. - */ - public SuggestedActionSetBirthdate() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -356672766; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Suggests the user to set profile photo. - */ - public static class SuggestedActionSetProfilePhoto extends SuggestedAction { - - /** - * Suggests the user to set profile photo. - */ - public SuggestedActionSetProfilePhoto() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1612563093; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Suggests the user to extend their expiring Telegram Premium subscription. - */ - public static class SuggestedActionExtendPremium extends SuggestedAction { - /** - * A URL for managing Telegram Premium subscription. - */ - public String managePremiumSubscriptionUrl; - - /** - * Suggests the user to extend their expiring Telegram Premium subscription. - */ - public SuggestedActionExtendPremium() { - } - - /** - * Suggests the user to extend their expiring Telegram Premium subscription. - * - * @param managePremiumSubscriptionUrl A URL for managing Telegram Premium subscription. - */ - public SuggestedActionExtendPremium(String managePremiumSubscriptionUrl) { - this.managePremiumSubscriptionUrl = managePremiumSubscriptionUrl; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -566207286; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Suggests the user to extend their expiring Telegram Star subscriptions. Call getStarSubscriptions with onlyExpiring == true to get the number of expiring subscriptions and the number of required to buy Telegram Stars. - */ - public static class SuggestedActionExtendStarSubscriptions extends SuggestedAction { - - /** - * Suggests the user to extend their expiring Telegram Star subscriptions. Call getStarSubscriptions with onlyExpiring == true to get the number of expiring subscriptions and the number of required to buy Telegram Stars. - */ - public SuggestedActionExtendStarSubscriptions() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -47000234; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A custom suggestion to be shown at the top of the chat list. - */ - public static class SuggestedActionCustom extends SuggestedAction { - /** - * Unique name of the suggestion. - */ - public String name; - /** - * Title of the suggestion. - */ - public FormattedText title; - /** - * Description of the suggestion. - */ - public FormattedText description; - /** - * The link to open when the suggestion is clicked. - */ - public String url; - - /** - * A custom suggestion to be shown at the top of the chat list. - */ - public SuggestedActionCustom() { - } - - /** - * A custom suggestion to be shown at the top of the chat list. - * - * @param name Unique name of the suggestion. - * @param title Title of the suggestion. - * @param description Description of the suggestion. - * @param url The link to open when the suggestion is clicked. - */ - public SuggestedActionCustom(String name, FormattedText title, FormattedText description, String url) { - this.name = name; - this.title = title; - this.description = description; - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2092876611; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Suggests the user to add login email address. Call isLoginEmailAddressRequired, and then setLoginEmailAddress or checkLoginEmailAddressCode to change the login email address. - */ - public static class SuggestedActionSetLoginEmailAddress extends SuggestedAction { - /** - * True, if the suggested action can be hidden using hideSuggestedAction. Otherwise, the user must not be able to use the app without setting up the email address. - */ - public boolean canBeHidden; - - /** - * Suggests the user to add login email address. Call isLoginEmailAddressRequired, and then setLoginEmailAddress or checkLoginEmailAddressCode to change the login email address. - */ - public SuggestedActionSetLoginEmailAddress() { - } - - /** - * Suggests the user to add login email address. Call isLoginEmailAddressRequired, and then setLoginEmailAddress or checkLoginEmailAddressCode to change the login email address. - * - * @param canBeHidden True, if the suggested action can be hidden using hideSuggestedAction. Otherwise, the user must not be able to use the app without setting up the email address. - */ - public SuggestedActionSetLoginEmailAddress(boolean canBeHidden) { - this.canBeHidden = canBeHidden; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1557625160; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Suggests the user to add a passkey for login using addLoginPasskey. - */ - public static class SuggestedActionAddLoginPasskey extends SuggestedAction { - - /** - * Suggests the user to add a passkey for login using addLoginPasskey. - */ - public SuggestedActionAddLoginPasskey() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1186248690; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a suggested post. If the post can be approved or declined, then changes to the post can be also suggested. Use sendMessage with reply to the message and suggested post information to suggest message changes. Use addOffer to suggest price or time changes. - */ - public static class SuggestedPostInfo extends Object { - /** - * Price of the suggested post; may be null if the post is non-paid. - */ - @Nullable public SuggestedPostPrice price; - /** - * Point in time (Unix timestamp) when the post is expected to be published; 0 if the specific date isn't set yet. - */ - public int sendDate; - /** - * State of the post. - */ - public SuggestedPostState state; - /** - * True, if the suggested post can be approved by the current user using approveSuggestedPost; updates aren't sent when value of this field changes. - */ - public boolean canBeApproved; - /** - * True, if the suggested post can be declined by the current user using declineSuggestedPost; updates aren't sent when value of this field changes. - */ - public boolean canBeDeclined; - - /** - * Contains information about a suggested post. If the post can be approved or declined, then changes to the post can be also suggested. Use sendMessage with reply to the message and suggested post information to suggest message changes. Use addOffer to suggest price or time changes. - */ - public SuggestedPostInfo() { - } - - /** - * Contains information about a suggested post. If the post can be approved or declined, then changes to the post can be also suggested. Use sendMessage with reply to the message and suggested post information to suggest message changes. Use addOffer to suggest price or time changes. - * - * @param price Price of the suggested post; may be null if the post is non-paid. - * @param sendDate Point in time (Unix timestamp) when the post is expected to be published; 0 if the specific date isn't set yet. - * @param state State of the post. - * @param canBeApproved True, if the suggested post can be approved by the current user using approveSuggestedPost; updates aren't sent when value of this field changes. - * @param canBeDeclined True, if the suggested post can be declined by the current user using declineSuggestedPost; updates aren't sent when value of this field changes. - */ - public SuggestedPostInfo(SuggestedPostPrice price, int sendDate, SuggestedPostState state, boolean canBeApproved, boolean canBeDeclined) { - this.price = price; - this.sendDate = sendDate; - this.state = state; - this.canBeApproved = canBeApproved; - this.canBeDeclined = canBeDeclined; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1088331710; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes price of a suggested post. - */ - public abstract static class SuggestedPostPrice extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - SuggestedPostPriceStar.CONSTRUCTOR, - SuggestedPostPriceTon.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public SuggestedPostPrice() { - } - } - - /** - * Describes price of a suggested post in Telegram Stars. - */ - public static class SuggestedPostPriceStar extends SuggestedPostPrice { - /** - * The Telegram Star amount expected to be paid for the post; getOption("suggested_post_star_count_min")-getOption("suggested_post_star_count_max"). - */ - public long starCount; - - /** - * Describes price of a suggested post in Telegram Stars. - */ - public SuggestedPostPriceStar() { - } - - /** - * Describes price of a suggested post in Telegram Stars. - * - * @param starCount The Telegram Star amount expected to be paid for the post; getOption("suggested_post_star_count_min")-getOption("suggested_post_star_count_max"). - */ - public SuggestedPostPriceStar(long starCount) { - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 216488903; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes price of a suggested post in Toncoins. - */ - public static class SuggestedPostPriceTon extends SuggestedPostPrice { - /** - * The amount of 1/100 of Toncoin expected to be paid for the post; getOption("suggested_post_toncoin_cent_count_min")-getOption("suggested_post_toncoin_cent_count_max"). - */ - public long toncoinCentCount; - - /** - * Describes price of a suggested post in Toncoins. - */ - public SuggestedPostPriceTon() { - } - - /** - * Describes price of a suggested post in Toncoins. - * - * @param toncoinCentCount The amount of 1/100 of Toncoin expected to be paid for the post; getOption("suggested_post_toncoin_cent_count_min")-getOption("suggested_post_toncoin_cent_count_max"). - */ - public SuggestedPostPriceTon(long toncoinCentCount) { - this.toncoinCentCount = toncoinCentCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1095222334; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes reason for refund of the payment for a suggested post. - */ - public abstract static class SuggestedPostRefundReason extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - SuggestedPostRefundReasonPostDeleted.CONSTRUCTOR, - SuggestedPostRefundReasonPaymentRefunded.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public SuggestedPostRefundReason() { - } - } - - /** - * The post was refunded, because it was deleted by channel administrators in less than getOption("suggested_post_lifetime_min") seconds. - */ - public static class SuggestedPostRefundReasonPostDeleted extends SuggestedPostRefundReason { - - /** - * The post was refunded, because it was deleted by channel administrators in less than getOption("suggested_post_lifetime_min") seconds. - */ - public SuggestedPostRefundReasonPostDeleted() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1657796126; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The post was refunded, because the payment for the post was refunded. - */ - public static class SuggestedPostRefundReasonPaymentRefunded extends SuggestedPostRefundReason { - - /** - * The post was refunded, because the payment for the post was refunded. - */ - public SuggestedPostRefundReasonPaymentRefunded() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 755739598; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes state of a suggested post. - */ - public abstract static class SuggestedPostState extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - SuggestedPostStatePending.CONSTRUCTOR, - SuggestedPostStateApproved.CONSTRUCTOR, - SuggestedPostStateDeclined.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public SuggestedPostState() { - } - } - - /** - * The post must be approved or declined. - */ - public static class SuggestedPostStatePending extends SuggestedPostState { - - /** - * The post must be approved or declined. - */ - public SuggestedPostStatePending() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 232632669; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The post was approved. - */ - public static class SuggestedPostStateApproved extends SuggestedPostState { - - /** - * The post was approved. - */ - public SuggestedPostStateApproved() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -782541552; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The post was declined. - */ - public static class SuggestedPostStateDeclined extends SuggestedPostState { - - /** - * The post was declined. - */ - public SuggestedPostStateDeclined() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 318192794; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a supergroup or channel with zero or more members (subscribers in the case of channels). From the point of view of the system, a channel is a special kind of a supergroup: only administrators can post and see the list of members, and posts from all administrators use the name and photo of the channel instead of individual names and profile photos. Unlike supergroups, channels can have an unlimited number of subscribers. - */ - public static class Supergroup extends Object { - /** - * Supergroup or channel identifier. - */ - public long id; - /** - * Usernames of the supergroup or channel; may be null. - */ - @Nullable public Usernames usernames; - /** - * Point in time (Unix timestamp) when the current user joined, or the point in time when the supergroup or channel was created, in case the user is not a member. - */ - public int date; - /** - * Status of the current user in the supergroup or channel. - */ - public ChatMemberStatus status; - /** - * Number of members in the supergroup or channel; 0 if unknown. Currently, it is guaranteed to be known only if the supergroup or channel was received through getChatSimilarChats, getChatsToPostStories, getCreatedPublicChats, getGroupsInCommon, getInactiveSupergroupChats, getRecommendedChats, getSuitableDiscussionChats, getUserPrivacySettingRules, getVideoChatAvailableParticipants, searchPublicChats, or in chatFolderInviteLinkInfo.missingChatIds, or in userFullInfo.personalChatId, or for chats with messages or stories from publicForwards and foundStories. - */ - public int memberCount; - /** - * Approximate boost level for the chat. - */ - public int boostLevel; - /** - * True, if automatic translation of messages is enabled in the channel. - */ - public boolean hasAutomaticTranslation; - /** - * True, if the channel has a discussion group, or the supergroup is the designated discussion group for a channel. - */ - public boolean hasLinkedChat; - /** - * True, if the supergroup is connected to a location, i.e. the supergroup is a location-based supergroup. - */ - public boolean hasLocation; - /** - * True, if messages sent to the channel contains name of the sender. This field is only applicable to channels. - */ - public boolean signMessages; - /** - * True, if messages sent to the channel have information about the sender user. This field is only applicable to channels. - */ - public boolean showMessageSender; - /** - * True, if users need to join the supergroup before they can send messages. May be false only for discussion supergroups and channel direct messages groups. - */ - public boolean joinToSendMessages; - /** - * True, if all users directly joining the supergroup need to be approved by supergroup administrators. May be true only for non-broadcast supergroups with username, location, or a linked chat. - */ - public boolean joinByRequest; - /** - * True, if the slow mode is enabled in the supergroup. - */ - public boolean isSlowModeEnabled; - /** - * True, if the supergroup is a channel. - */ - public boolean isChannel; - /** - * True, if the supergroup is a broadcast group, i.e. only administrators can send messages and there is no limit on the number of members. - */ - public boolean isBroadcastGroup; - /** - * True, if the supergroup is a forum with topics. - */ - public boolean isForum; - /** - * True, if the supergroup is a direct message group for a channel chat. - */ - public boolean isDirectMessagesGroup; - /** - * True, if the supergroup is a direct messages group for a channel chat that is administered by the current user. - */ - public boolean isAdministeredDirectMessagesGroup; - /** - * Information about verification status of the supergroup or channel; may be null if none. - */ - @Nullable public VerificationStatus verificationStatus; - /** - * True, if the channel has direct messages group. - */ - public boolean hasDirectMessagesGroup; - /** - * True, if the supergroup is a forum, which topics are shown in the same way as in channel direct messages groups. - */ - public boolean hasForumTabs; - /** - * Information about the restrictions that must be applied to the corresponding supergroup or channel chat; may be null if none. - */ - @Nullable public RestrictionInfo restrictionInfo; - /** - * Number of Telegram Stars that must be paid by non-administrator users of the supergroup chat for each sent message. - */ - public long paidMessageStarCount; - /** - * State of active stories of the supergroup or channel; may be null if there are no active stories. - */ - @Nullable public ActiveStoryState activeStoryState; - - /** - * Represents a supergroup or channel with zero or more members (subscribers in the case of channels). From the point of view of the system, a channel is a special kind of a supergroup: only administrators can post and see the list of members, and posts from all administrators use the name and photo of the channel instead of individual names and profile photos. Unlike supergroups, channels can have an unlimited number of subscribers. - */ - public Supergroup() { - } - - /** - * Represents a supergroup or channel with zero or more members (subscribers in the case of channels). From the point of view of the system, a channel is a special kind of a supergroup: only administrators can post and see the list of members, and posts from all administrators use the name and photo of the channel instead of individual names and profile photos. Unlike supergroups, channels can have an unlimited number of subscribers. - * - * @param id Supergroup or channel identifier. - * @param usernames Usernames of the supergroup or channel; may be null. - * @param date Point in time (Unix timestamp) when the current user joined, or the point in time when the supergroup or channel was created, in case the user is not a member. - * @param status Status of the current user in the supergroup or channel. - * @param memberCount Number of members in the supergroup or channel; 0 if unknown. Currently, it is guaranteed to be known only if the supergroup or channel was received through getChatSimilarChats, getChatsToPostStories, getCreatedPublicChats, getGroupsInCommon, getInactiveSupergroupChats, getRecommendedChats, getSuitableDiscussionChats, getUserPrivacySettingRules, getVideoChatAvailableParticipants, searchPublicChats, or in chatFolderInviteLinkInfo.missingChatIds, or in userFullInfo.personalChatId, or for chats with messages or stories from publicForwards and foundStories. - * @param boostLevel Approximate boost level for the chat. - * @param hasAutomaticTranslation True, if automatic translation of messages is enabled in the channel. - * @param hasLinkedChat True, if the channel has a discussion group, or the supergroup is the designated discussion group for a channel. - * @param hasLocation True, if the supergroup is connected to a location, i.e. the supergroup is a location-based supergroup. - * @param signMessages True, if messages sent to the channel contains name of the sender. This field is only applicable to channels. - * @param showMessageSender True, if messages sent to the channel have information about the sender user. This field is only applicable to channels. - * @param joinToSendMessages True, if users need to join the supergroup before they can send messages. May be false only for discussion supergroups and channel direct messages groups. - * @param joinByRequest True, if all users directly joining the supergroup need to be approved by supergroup administrators. May be true only for non-broadcast supergroups with username, location, or a linked chat. - * @param isSlowModeEnabled True, if the slow mode is enabled in the supergroup. - * @param isChannel True, if the supergroup is a channel. - * @param isBroadcastGroup True, if the supergroup is a broadcast group, i.e. only administrators can send messages and there is no limit on the number of members. - * @param isForum True, if the supergroup is a forum with topics. - * @param isDirectMessagesGroup True, if the supergroup is a direct message group for a channel chat. - * @param isAdministeredDirectMessagesGroup True, if the supergroup is a direct messages group for a channel chat that is administered by the current user. - * @param verificationStatus Information about verification status of the supergroup or channel; may be null if none. - * @param hasDirectMessagesGroup True, if the channel has direct messages group. - * @param hasForumTabs True, if the supergroup is a forum, which topics are shown in the same way as in channel direct messages groups. - * @param restrictionInfo Information about the restrictions that must be applied to the corresponding supergroup or channel chat; may be null if none. - * @param paidMessageStarCount Number of Telegram Stars that must be paid by non-administrator users of the supergroup chat for each sent message. - * @param activeStoryState State of active stories of the supergroup or channel; may be null if there are no active stories. - */ - public Supergroup(long id, Usernames usernames, int date, ChatMemberStatus status, int memberCount, int boostLevel, boolean hasAutomaticTranslation, boolean hasLinkedChat, boolean hasLocation, boolean signMessages, boolean showMessageSender, boolean joinToSendMessages, boolean joinByRequest, boolean isSlowModeEnabled, boolean isChannel, boolean isBroadcastGroup, boolean isForum, boolean isDirectMessagesGroup, boolean isAdministeredDirectMessagesGroup, VerificationStatus verificationStatus, boolean hasDirectMessagesGroup, boolean hasForumTabs, RestrictionInfo restrictionInfo, long paidMessageStarCount, ActiveStoryState activeStoryState) { - this.id = id; - this.usernames = usernames; - this.date = date; - this.status = status; - this.memberCount = memberCount; - this.boostLevel = boostLevel; - this.hasAutomaticTranslation = hasAutomaticTranslation; - this.hasLinkedChat = hasLinkedChat; - this.hasLocation = hasLocation; - this.signMessages = signMessages; - this.showMessageSender = showMessageSender; - this.joinToSendMessages = joinToSendMessages; - this.joinByRequest = joinByRequest; - this.isSlowModeEnabled = isSlowModeEnabled; - this.isChannel = isChannel; - this.isBroadcastGroup = isBroadcastGroup; - this.isForum = isForum; - this.isDirectMessagesGroup = isDirectMessagesGroup; - this.isAdministeredDirectMessagesGroup = isAdministeredDirectMessagesGroup; - this.verificationStatus = verificationStatus; - this.hasDirectMessagesGroup = hasDirectMessagesGroup; - this.hasForumTabs = hasForumTabs; - this.restrictionInfo = restrictionInfo; - this.paidMessageStarCount = paidMessageStarCount; - this.activeStoryState = activeStoryState; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1134998957; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains full information about a supergroup or channel. - */ - public static class SupergroupFullInfo extends Object { - /** - * Chat photo; may be null if empty or unknown. If non-null, then it is the same photo as in chat.photo. - */ - @Nullable public ChatPhoto photo; - /** - * Supergroup or channel description. - */ - public String description; - /** - * Number of members in the supergroup or channel; 0 if unknown. - */ - public int memberCount; - /** - * Number of privileged users in the supergroup or channel; 0 if unknown. - */ - public int administratorCount; - /** - * Number of restricted users in the supergroup; 0 if unknown. - */ - public int restrictedCount; - /** - * Number of users banned from chat; 0 if unknown. - */ - public int bannedCount; - /** - * Chat identifier of a discussion group for the channel, or a channel, for which the supergroup is the designated discussion group; 0 if none or unknown. - */ - public long linkedChatId; - /** - * Chat identifier of a direct messages group for the channel, or a channel, for which the supergroup is the designated direct messages group; 0 if none. - */ - public long directMessagesChatId; - /** - * Delay between consecutive sent messages for non-administrator supergroup members, in seconds. - */ - public int slowModeDelay; - /** - * Time left before next message can be sent in the supergroup, in seconds. An updateSupergroupFullInfo update is not triggered when value of this field changes, but both new and old values are non-zero. - */ - public double slowModeDelayExpiresIn; - /** - * True, if paid messages can be enabled in the supergroup chat; for supergroup only. - */ - public boolean canEnablePaidMessages; - /** - * True, if paid reaction can be enabled in the channel chat; for channels only. - */ - public boolean canEnablePaidReaction; - /** - * True, if members of the chat can be retrieved via getSupergroupMembers or searchChatMembers. - */ - public boolean canGetMembers; - /** - * True, if non-administrators can receive only administrators and bots using getSupergroupMembers or searchChatMembers. - */ - public boolean hasHiddenMembers; - /** - * True, if non-administrators and non-bots can be hidden in responses to getSupergroupMembers and searchChatMembers for non-administrators. - */ - public boolean canHideMembers; - /** - * True, if the supergroup sticker set can be changed. - */ - public boolean canSetStickerSet; - /** - * True, if the supergroup location can be changed. - */ - public boolean canSetLocation; - /** - * True, if the supergroup or channel statistics are available. - */ - public boolean canGetStatistics; - /** - * True, if the supergroup or channel revenue statistics are available. - */ - public boolean canGetRevenueStatistics; - /** - * True, if the supergroup or channel Telegram Star revenue statistics are available. - */ - public boolean canGetStarRevenueStatistics; - /** - * True, if the user can send a gift to the supergroup or channel using sendGift or transferGift. - */ - public boolean canSendGift; - /** - * True, if aggressive anti-spam checks can be enabled or disabled in the supergroup. - */ - public boolean canToggleAggressiveAntiSpam; - /** - * True, if new chat members will have access to old messages. In public, discussion, of forum groups and all channels, old messages are always available, so this option affects only private non-forum supergroups without a linked chat. The value of this field is only available to chat administrators. - */ - public boolean isAllHistoryAvailable; - /** - * True, if the chat can have sponsored messages. The value of this field is only available to the owner of the chat. - */ - public boolean canHaveSponsoredMessages; - /** - * True, if aggressive anti-spam checks are enabled in the supergroup. The value of this field is only available to chat administrators. - */ - public boolean hasAggressiveAntiSpamEnabled; - /** - * True, if paid media can be sent and forwarded to the channel chat; for channels only. - */ - public boolean hasPaidMediaAllowed; - /** - * True, if the supergroup or channel has pinned stories. - */ - public boolean hasPinnedStories; - /** - * Number of saved to profile gifts for channels without canPostMessages administrator right, otherwise, the total number of received gifts. - */ - public int giftCount; - /** - * Number of times the current user boosted the supergroup or channel. - */ - public int myBoostCount; - /** - * Number of times the supergroup must be boosted by a user to ignore slow mode and chat permission restrictions; 0 if unspecified. - */ - public int unrestrictBoostCount; - /** - * Number of Telegram Stars that must be paid by the current user for each sent message to the supergroup. - */ - public long outgoingPaidMessageStarCount; - /** - * Identifier of the supergroup sticker set that must be shown before user sticker sets; 0 if none. - */ - public long stickerSetId; - /** - * Identifier of the custom emoji sticker set that can be used in the supergroup without Telegram Premium subscription; 0 if none. - */ - public long customEmojiStickerSetId; - /** - * Location to which the supergroup is connected; may be null if none. - */ - @Nullable public ChatLocation location; - /** - * Primary invite link for the chat; may be null. For chat administrators with canInviteUsers right only. - */ - @Nullable public ChatInviteLink inviteLink; - /** - * List of commands of bots in the group. - */ - public BotCommands[] botCommands; - /** - * Information about verification status of the supergroup or the channel provided by a bot; may be null if none or unknown. - */ - @Nullable public BotVerification botVerification; - /** - * The main tab chosen by the administrators of the channel; may be null if not chosen manually. - */ - @Nullable public ProfileTab mainProfileTab; - /** - * Identifier of the basic group from which supergroup was upgraded; 0 if none. - */ - public long upgradedFromBasicGroupId; - /** - * Identifier of the last message in the basic group from which supergroup was upgraded; 0 if none. - */ - public long upgradedFromMaxMessageId; - - /** - * Contains full information about a supergroup or channel. - */ - public SupergroupFullInfo() { - } - - /** - * Contains full information about a supergroup or channel. - * - * @param photo Chat photo; may be null if empty or unknown. If non-null, then it is the same photo as in chat.photo. - * @param description Supergroup or channel description. - * @param memberCount Number of members in the supergroup or channel; 0 if unknown. - * @param administratorCount Number of privileged users in the supergroup or channel; 0 if unknown. - * @param restrictedCount Number of restricted users in the supergroup; 0 if unknown. - * @param bannedCount Number of users banned from chat; 0 if unknown. - * @param linkedChatId Chat identifier of a discussion group for the channel, or a channel, for which the supergroup is the designated discussion group; 0 if none or unknown. - * @param directMessagesChatId Chat identifier of a direct messages group for the channel, or a channel, for which the supergroup is the designated direct messages group; 0 if none. - * @param slowModeDelay Delay between consecutive sent messages for non-administrator supergroup members, in seconds. - * @param slowModeDelayExpiresIn Time left before next message can be sent in the supergroup, in seconds. An updateSupergroupFullInfo update is not triggered when value of this field changes, but both new and old values are non-zero. - * @param canEnablePaidMessages True, if paid messages can be enabled in the supergroup chat; for supergroup only. - * @param canEnablePaidReaction True, if paid reaction can be enabled in the channel chat; for channels only. - * @param canGetMembers True, if members of the chat can be retrieved via getSupergroupMembers or searchChatMembers. - * @param hasHiddenMembers True, if non-administrators can receive only administrators and bots using getSupergroupMembers or searchChatMembers. - * @param canHideMembers True, if non-administrators and non-bots can be hidden in responses to getSupergroupMembers and searchChatMembers for non-administrators. - * @param canSetStickerSet True, if the supergroup sticker set can be changed. - * @param canSetLocation True, if the supergroup location can be changed. - * @param canGetStatistics True, if the supergroup or channel statistics are available. - * @param canGetRevenueStatistics True, if the supergroup or channel revenue statistics are available. - * @param canGetStarRevenueStatistics True, if the supergroup or channel Telegram Star revenue statistics are available. - * @param canSendGift True, if the user can send a gift to the supergroup or channel using sendGift or transferGift. - * @param canToggleAggressiveAntiSpam True, if aggressive anti-spam checks can be enabled or disabled in the supergroup. - * @param isAllHistoryAvailable True, if new chat members will have access to old messages. In public, discussion, of forum groups and all channels, old messages are always available, so this option affects only private non-forum supergroups without a linked chat. The value of this field is only available to chat administrators. - * @param canHaveSponsoredMessages True, if the chat can have sponsored messages. The value of this field is only available to the owner of the chat. - * @param hasAggressiveAntiSpamEnabled True, if aggressive anti-spam checks are enabled in the supergroup. The value of this field is only available to chat administrators. - * @param hasPaidMediaAllowed True, if paid media can be sent and forwarded to the channel chat; for channels only. - * @param hasPinnedStories True, if the supergroup or channel has pinned stories. - * @param giftCount Number of saved to profile gifts for channels without canPostMessages administrator right, otherwise, the total number of received gifts. - * @param myBoostCount Number of times the current user boosted the supergroup or channel. - * @param unrestrictBoostCount Number of times the supergroup must be boosted by a user to ignore slow mode and chat permission restrictions; 0 if unspecified. - * @param outgoingPaidMessageStarCount Number of Telegram Stars that must be paid by the current user for each sent message to the supergroup. - * @param stickerSetId Identifier of the supergroup sticker set that must be shown before user sticker sets; 0 if none. - * @param customEmojiStickerSetId Identifier of the custom emoji sticker set that can be used in the supergroup without Telegram Premium subscription; 0 if none. - * @param location Location to which the supergroup is connected; may be null if none. - * @param inviteLink Primary invite link for the chat; may be null. For chat administrators with canInviteUsers right only. - * @param botCommands List of commands of bots in the group. - * @param botVerification Information about verification status of the supergroup or the channel provided by a bot; may be null if none or unknown. - * @param mainProfileTab The main tab chosen by the administrators of the channel; may be null if not chosen manually. - * @param upgradedFromBasicGroupId Identifier of the basic group from which supergroup was upgraded; 0 if none. - * @param upgradedFromMaxMessageId Identifier of the last message in the basic group from which supergroup was upgraded; 0 if none. - */ - public SupergroupFullInfo(ChatPhoto photo, String description, int memberCount, int administratorCount, int restrictedCount, int bannedCount, long linkedChatId, long directMessagesChatId, int slowModeDelay, double slowModeDelayExpiresIn, boolean canEnablePaidMessages, boolean canEnablePaidReaction, boolean canGetMembers, boolean hasHiddenMembers, boolean canHideMembers, boolean canSetStickerSet, boolean canSetLocation, boolean canGetStatistics, boolean canGetRevenueStatistics, boolean canGetStarRevenueStatistics, boolean canSendGift, boolean canToggleAggressiveAntiSpam, boolean isAllHistoryAvailable, boolean canHaveSponsoredMessages, boolean hasAggressiveAntiSpamEnabled, boolean hasPaidMediaAllowed, boolean hasPinnedStories, int giftCount, int myBoostCount, int unrestrictBoostCount, long outgoingPaidMessageStarCount, long stickerSetId, long customEmojiStickerSetId, ChatLocation location, ChatInviteLink inviteLink, BotCommands[] botCommands, BotVerification botVerification, ProfileTab mainProfileTab, long upgradedFromBasicGroupId, long upgradedFromMaxMessageId) { - this.photo = photo; - this.description = description; - this.memberCount = memberCount; - this.administratorCount = administratorCount; - this.restrictedCount = restrictedCount; - this.bannedCount = bannedCount; - this.linkedChatId = linkedChatId; - this.directMessagesChatId = directMessagesChatId; - this.slowModeDelay = slowModeDelay; - this.slowModeDelayExpiresIn = slowModeDelayExpiresIn; - this.canEnablePaidMessages = canEnablePaidMessages; - this.canEnablePaidReaction = canEnablePaidReaction; - this.canGetMembers = canGetMembers; - this.hasHiddenMembers = hasHiddenMembers; - this.canHideMembers = canHideMembers; - this.canSetStickerSet = canSetStickerSet; - this.canSetLocation = canSetLocation; - this.canGetStatistics = canGetStatistics; - this.canGetRevenueStatistics = canGetRevenueStatistics; - this.canGetStarRevenueStatistics = canGetStarRevenueStatistics; - this.canSendGift = canSendGift; - this.canToggleAggressiveAntiSpam = canToggleAggressiveAntiSpam; - this.isAllHistoryAvailable = isAllHistoryAvailable; - this.canHaveSponsoredMessages = canHaveSponsoredMessages; - this.hasAggressiveAntiSpamEnabled = hasAggressiveAntiSpamEnabled; - this.hasPaidMediaAllowed = hasPaidMediaAllowed; - this.hasPinnedStories = hasPinnedStories; - this.giftCount = giftCount; - this.myBoostCount = myBoostCount; - this.unrestrictBoostCount = unrestrictBoostCount; - this.outgoingPaidMessageStarCount = outgoingPaidMessageStarCount; - this.stickerSetId = stickerSetId; - this.customEmojiStickerSetId = customEmojiStickerSetId; - this.location = location; - this.inviteLink = inviteLink; - this.botCommands = botCommands; - this.botVerification = botVerification; - this.mainProfileTab = mainProfileTab; - this.upgradedFromBasicGroupId = upgradedFromBasicGroupId; - this.upgradedFromMaxMessageId = upgradedFromMaxMessageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -497664769; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Specifies the kind of chat members to return in getSupergroupMembers. - */ - public abstract static class SupergroupMembersFilter extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - SupergroupMembersFilterRecent.CONSTRUCTOR, - SupergroupMembersFilterContacts.CONSTRUCTOR, - SupergroupMembersFilterAdministrators.CONSTRUCTOR, - SupergroupMembersFilterSearch.CONSTRUCTOR, - SupergroupMembersFilterRestricted.CONSTRUCTOR, - SupergroupMembersFilterBanned.CONSTRUCTOR, - SupergroupMembersFilterMention.CONSTRUCTOR, - SupergroupMembersFilterBots.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public SupergroupMembersFilter() { - } - } - - /** - * Returns recently active users in reverse chronological order. - */ - public static class SupergroupMembersFilterRecent extends SupergroupMembersFilter { - - /** - * Returns recently active users in reverse chronological order. - */ - public SupergroupMembersFilterRecent() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1178199509; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns contacts of the user, which are members of the supergroup or channel. - */ - public static class SupergroupMembersFilterContacts extends SupergroupMembersFilter { - /** - * Query to search for. - */ - public String query; - - /** - * Returns contacts of the user, which are members of the supergroup or channel. - */ - public SupergroupMembersFilterContacts() { - } - - /** - * Returns contacts of the user, which are members of the supergroup or channel. - * - * @param query Query to search for. - */ - public SupergroupMembersFilterContacts(String query) { - this.query = query; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1282910856; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the owner and administrators. - */ - public static class SupergroupMembersFilterAdministrators extends SupergroupMembersFilter { - - /** - * Returns the owner and administrators. - */ - public SupergroupMembersFilterAdministrators() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2097380265; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Used to search for supergroup or channel members via a (string) query. - */ - public static class SupergroupMembersFilterSearch extends SupergroupMembersFilter { - /** - * Query to search for. - */ - public String query; - - /** - * Used to search for supergroup or channel members via a (string) query. - */ - public SupergroupMembersFilterSearch() { - } - - /** - * Used to search for supergroup or channel members via a (string) query. - * - * @param query Query to search for. - */ - public SupergroupMembersFilterSearch(String query) { - this.query = query; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1696358469; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns restricted supergroup members; can be used only by administrators. - */ - public static class SupergroupMembersFilterRestricted extends SupergroupMembersFilter { - /** - * Query to search for. - */ - public String query; - - /** - * Returns restricted supergroup members; can be used only by administrators. - */ - public SupergroupMembersFilterRestricted() { - } - - /** - * Returns restricted supergroup members; can be used only by administrators. - * - * @param query Query to search for. - */ - public SupergroupMembersFilterRestricted(String query) { - this.query = query; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1107800034; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns users banned from the supergroup or channel; can be used only by administrators. - */ - public static class SupergroupMembersFilterBanned extends SupergroupMembersFilter { - /** - * Query to search for. - */ - public String query; - - /** - * Returns users banned from the supergroup or channel; can be used only by administrators. - */ - public SupergroupMembersFilterBanned() { - } - - /** - * Returns users banned from the supergroup or channel; can be used only by administrators. - * - * @param query Query to search for. - */ - public SupergroupMembersFilterBanned(String query) { - this.query = query; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1210621683; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns users which can be mentioned in the supergroup. - */ - public static class SupergroupMembersFilterMention extends SupergroupMembersFilter { - /** - * Query to search for. - */ - public String query; - /** - * Identifier of the topic in which the users will be mentioned; pass null if none. - */ - public MessageTopic topicId; - - /** - * Returns users which can be mentioned in the supergroup. - */ - public SupergroupMembersFilterMention() { - } - - /** - * Returns users which can be mentioned in the supergroup. - * - * @param query Query to search for. - * @param topicId Identifier of the topic in which the users will be mentioned; pass null if none. - */ - public SupergroupMembersFilterMention(String query, MessageTopic topicId) { - this.query = query; - this.topicId = topicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1151301973; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns bot members of the supergroup or channel. - */ - public static class SupergroupMembersFilterBots extends SupergroupMembersFilter { - - /** - * Returns bot members of the supergroup or channel. - */ - public SupergroupMembersFilterBots() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 492138918; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a URL linking to an internal Telegram entity. - */ - public static class TMeUrl extends Object { - /** - * URL. - */ - public String url; - /** - * Type of the URL. - */ - public TMeUrlType type; - - /** - * Represents a URL linking to an internal Telegram entity. - */ - public TMeUrl() { - } - - /** - * Represents a URL linking to an internal Telegram entity. - * - * @param url URL. - * @param type Type of the URL. - */ - public TMeUrl(String url, TMeUrlType type) { - this.url = url; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1140786622; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the type of URL linking to an internal Telegram entity. - */ - public abstract static class TMeUrlType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - TMeUrlTypeUser.CONSTRUCTOR, - TMeUrlTypeSupergroup.CONSTRUCTOR, - TMeUrlTypeChatInvite.CONSTRUCTOR, - TMeUrlTypeStickerSet.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public TMeUrlType() { - } - } - - /** - * A URL linking to a user. - */ - public static class TMeUrlTypeUser extends TMeUrlType { - /** - * Identifier of the user. - */ - public long userId; - - /** - * A URL linking to a user. - */ - public TMeUrlTypeUser() { - } - - /** - * A URL linking to a user. - * - * @param userId Identifier of the user. - */ - public TMeUrlTypeUser(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 125336602; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A URL linking to a public supergroup or channel. - */ - public static class TMeUrlTypeSupergroup extends TMeUrlType { - /** - * Identifier of the supergroup or channel. - */ - public long supergroupId; - - /** - * A URL linking to a public supergroup or channel. - */ - public TMeUrlTypeSupergroup() { - } - - /** - * A URL linking to a public supergroup or channel. - * - * @param supergroupId Identifier of the supergroup or channel. - */ - public TMeUrlTypeSupergroup(long supergroupId) { - this.supergroupId = supergroupId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1353369944; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat invite link. - */ - public static class TMeUrlTypeChatInvite extends TMeUrlType { - /** - * Information about the chat invite link. - */ - public ChatInviteLinkInfo info; - - /** - * A chat invite link. - */ - public TMeUrlTypeChatInvite() { - } - - /** - * A chat invite link. - * - * @param info Information about the chat invite link. - */ - public TMeUrlTypeChatInvite(ChatInviteLinkInfo info) { - this.info = info; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 313907785; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A URL linking to a sticker set. - */ - public static class TMeUrlTypeStickerSet extends TMeUrlType { - /** - * Identifier of the sticker set. - */ - public long stickerSetId; - - /** - * A URL linking to a sticker set. - */ - public TMeUrlTypeStickerSet() { - } - - /** - * A URL linking to a sticker set. - * - * @param stickerSetId Identifier of the sticker set. - */ - public TMeUrlTypeStickerSet(long stickerSetId) { - this.stickerSetId = stickerSetId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1602473196; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of t.me URLs. - */ - public static class TMeUrls extends Object { - /** - * List of URLs. - */ - public TMeUrl[] urls; - - /** - * Contains a list of t.me URLs. - */ - public TMeUrls() { - } - - /** - * Contains a list of t.me URLs. - * - * @param urls List of URLs. - */ - public TMeUrls(TMeUrl[] urls) { - this.urls = urls; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1130595098; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the target chat to be opened. - */ - public abstract static class TargetChat extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - TargetChatCurrent.CONSTRUCTOR, - TargetChatChosen.CONSTRUCTOR, - TargetChatInternalLink.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public TargetChat() { - } - } - - /** - * The currently opened chat and forum topic must be kept. - */ - public static class TargetChatCurrent extends TargetChat { - - /** - * The currently opened chat and forum topic must be kept. - */ - public TargetChatCurrent() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -416689904; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat needs to be chosen by the user among chats of the specified types. - */ - public static class TargetChatChosen extends TargetChat { - /** - * Allowed types for the chat. - */ - public TargetChatTypes types; - - /** - * The chat needs to be chosen by the user among chats of the specified types. - */ - public TargetChatChosen() { - } - - /** - * The chat needs to be chosen by the user among chats of the specified types. - * - * @param types Allowed types for the chat. - */ - public TargetChatChosen(TargetChatTypes types) { - this.types = types; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1392978522; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat needs to be open with the provided internal link. - */ - public static class TargetChatInternalLink extends TargetChat { - /** - * An internal link pointing to the chat. - */ - public InternalLinkType link; - - /** - * The chat needs to be open with the provided internal link. - */ - public TargetChatInternalLink() { - } - - /** - * The chat needs to be open with the provided internal link. - * - * @param link An internal link pointing to the chat. - */ - public TargetChatInternalLink(InternalLinkType link) { - this.link = link; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -579301408; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes allowed types for the target chat. - */ - public static class TargetChatTypes extends Object { - /** - * True, if private chats with ordinary users are allowed. - */ - public boolean allowUserChats; - /** - * True, if private chats with other bots are allowed. - */ - public boolean allowBotChats; - /** - * True, if basic group and supergroup chats are allowed. - */ - public boolean allowGroupChats; - /** - * True, if channel chats are allowed. - */ - public boolean allowChannelChats; - - /** - * Describes allowed types for the target chat. - */ - public TargetChatTypes() { - } - - /** - * Describes allowed types for the target chat. - * - * @param allowUserChats True, if private chats with ordinary users are allowed. - * @param allowBotChats True, if private chats with other bots are allowed. - * @param allowGroupChats True, if basic group and supergroup chats are allowed. - * @param allowChannelChats True, if channel chats are allowed. - */ - public TargetChatTypes(boolean allowUserChats, boolean allowBotChats, boolean allowGroupChats, boolean allowChannelChats) { - this.allowUserChats = allowUserChats; - this.allowBotChats = allowBotChats; - this.allowGroupChats = allowGroupChats; - this.allowChannelChats = allowChannelChats; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1513098833; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes a purpose of a payment toward Telegram. - */ - public abstract static class TelegramPaymentPurpose extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - TelegramPaymentPurposePremiumGift.CONSTRUCTOR, - TelegramPaymentPurposePremiumGiftCodes.CONSTRUCTOR, - TelegramPaymentPurposePremiumGiveaway.CONSTRUCTOR, - TelegramPaymentPurposeStars.CONSTRUCTOR, - TelegramPaymentPurposeGiftedStars.CONSTRUCTOR, - TelegramPaymentPurposeStarGiveaway.CONSTRUCTOR, - TelegramPaymentPurposeJoinChat.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public TelegramPaymentPurpose() { - } - } - - /** - * The user gifting Telegram Premium to another user. - */ - public static class TelegramPaymentPurposePremiumGift extends TelegramPaymentPurpose { - /** - * ISO 4217 currency code of the payment currency, or "XTR" for payments in Telegram Stars. - */ - public String currency; - /** - * Paid amount, in the smallest units of the currency. - */ - public long amount; - /** - * Identifier of the user which will receive Telegram Premium. - */ - public long userId; - /** - * Number of months the Telegram Premium subscription will be active for the user. - */ - public int monthCount; - /** - * Text to show to the user receiving Telegram Premium; 0-getOption("gift_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed. - */ - public FormattedText text; - - /** - * The user gifting Telegram Premium to another user. - */ - public TelegramPaymentPurposePremiumGift() { - } - - /** - * The user gifting Telegram Premium to another user. - * - * @param currency ISO 4217 currency code of the payment currency, or "XTR" for payments in Telegram Stars. - * @param amount Paid amount, in the smallest units of the currency. - * @param userId Identifier of the user which will receive Telegram Premium. - * @param monthCount Number of months the Telegram Premium subscription will be active for the user. - * @param text Text to show to the user receiving Telegram Premium; 0-getOption("gift_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed. - */ - public TelegramPaymentPurposePremiumGift(String currency, long amount, long userId, int monthCount, FormattedText text) { - this.currency = currency; - this.amount = amount; - this.userId = userId; - this.monthCount = monthCount; - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1600286150; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user boosting a chat by creating Telegram Premium gift codes for other users. - */ - public static class TelegramPaymentPurposePremiumGiftCodes extends TelegramPaymentPurpose { - /** - * Identifier of the supergroup or channel chat, which will be automatically boosted by the users for duration of the Premium subscription and which is administered by the user. - */ - public long boostedChatId; - /** - * ISO 4217 currency code of the payment currency. - */ - public String currency; - /** - * Paid amount, in the smallest units of the currency. - */ - public long amount; - /** - * Identifiers of the users which can activate the gift codes. - */ - public long[] userIds; - /** - * Number of months the Telegram Premium subscription will be active for the users. - */ - public int monthCount; - /** - * Text to show along with the gift codes; 0-getOption("gift_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed. - */ - public FormattedText text; - - /** - * The user boosting a chat by creating Telegram Premium gift codes for other users. - */ - public TelegramPaymentPurposePremiumGiftCodes() { - } - - /** - * The user boosting a chat by creating Telegram Premium gift codes for other users. - * - * @param boostedChatId Identifier of the supergroup or channel chat, which will be automatically boosted by the users for duration of the Premium subscription and which is administered by the user. - * @param currency ISO 4217 currency code of the payment currency. - * @param amount Paid amount, in the smallest units of the currency. - * @param userIds Identifiers of the users which can activate the gift codes. - * @param monthCount Number of months the Telegram Premium subscription will be active for the users. - * @param text Text to show along with the gift codes; 0-getOption("gift_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed. - */ - public TelegramPaymentPurposePremiumGiftCodes(long boostedChatId, String currency, long amount, long[] userIds, int monthCount, FormattedText text) { - this.boostedChatId = boostedChatId; - this.currency = currency; - this.amount = amount; - this.userIds = userIds; - this.monthCount = monthCount; - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1863495348; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user creating a Telegram Premium giveaway. - */ - public static class TelegramPaymentPurposePremiumGiveaway extends TelegramPaymentPurpose { - /** - * Giveaway parameters. - */ - public GiveawayParameters parameters; - /** - * ISO 4217 currency code of the payment currency. - */ - public String currency; - /** - * Paid amount, in the smallest units of the currency. - */ - public long amount; - /** - * Number of users which will be able to activate the gift codes. - */ - public int winnerCount; - /** - * Number of months the Telegram Premium subscription will be active for the users. - */ - public int monthCount; - - /** - * The user creating a Telegram Premium giveaway. - */ - public TelegramPaymentPurposePremiumGiveaway() { - } - - /** - * The user creating a Telegram Premium giveaway. - * - * @param parameters Giveaway parameters. - * @param currency ISO 4217 currency code of the payment currency. - * @param amount Paid amount, in the smallest units of the currency. - * @param winnerCount Number of users which will be able to activate the gift codes. - * @param monthCount Number of months the Telegram Premium subscription will be active for the users. - */ - public TelegramPaymentPurposePremiumGiveaway(GiveawayParameters parameters, String currency, long amount, int winnerCount, int monthCount) { - this.parameters = parameters; - this.currency = currency; - this.amount = amount; - this.winnerCount = winnerCount; - this.monthCount = monthCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -760757441; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user buying Telegram Stars. - */ - public static class TelegramPaymentPurposeStars extends TelegramPaymentPurpose { - /** - * ISO 4217 currency code of the payment currency. - */ - public String currency; - /** - * Paid amount, in the smallest units of the currency. - */ - public long amount; - /** - * Number of bought Telegram Stars. - */ - public long starCount; - /** - * Identifier of the chat that is supposed to receive the Telegram Stars; pass 0 if none. - */ - public long chatId; - - /** - * The user buying Telegram Stars. - */ - public TelegramPaymentPurposeStars() { - } - - /** - * The user buying Telegram Stars. - * - * @param currency ISO 4217 currency code of the payment currency. - * @param amount Paid amount, in the smallest units of the currency. - * @param starCount Number of bought Telegram Stars. - * @param chatId Identifier of the chat that is supposed to receive the Telegram Stars; pass 0 if none. - */ - public TelegramPaymentPurposeStars(String currency, long amount, long starCount, long chatId) { - this.currency = currency; - this.amount = amount; - this.starCount = starCount; - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1204968037; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user buying Telegram Stars for other users. - */ - public static class TelegramPaymentPurposeGiftedStars extends TelegramPaymentPurpose { - /** - * Identifier of the user to which Telegram Stars are gifted. - */ - public long userId; - /** - * ISO 4217 currency code of the payment currency. - */ - public String currency; - /** - * Paid amount, in the smallest units of the currency. - */ - public long amount; - /** - * Number of bought Telegram Stars. - */ - public long starCount; - - /** - * The user buying Telegram Stars for other users. - */ - public TelegramPaymentPurposeGiftedStars() { - } - - /** - * The user buying Telegram Stars for other users. - * - * @param userId Identifier of the user to which Telegram Stars are gifted. - * @param currency ISO 4217 currency code of the payment currency. - * @param amount Paid amount, in the smallest units of the currency. - * @param starCount Number of bought Telegram Stars. - */ - public TelegramPaymentPurposeGiftedStars(long userId, String currency, long amount, long starCount) { - this.userId = userId; - this.currency = currency; - this.amount = amount; - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1850308042; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user creating a Telegram Star giveaway. - */ - public static class TelegramPaymentPurposeStarGiveaway extends TelegramPaymentPurpose { - /** - * Giveaway parameters. - */ - public GiveawayParameters parameters; - /** - * ISO 4217 currency code of the payment currency. - */ - public String currency; - /** - * Paid amount, in the smallest units of the currency. - */ - public long amount; - /** - * The number of users to receive Telegram Stars. - */ - public int winnerCount; - /** - * The number of Telegram Stars to be distributed through the giveaway. - */ - public long starCount; - - /** - * The user creating a Telegram Star giveaway. - */ - public TelegramPaymentPurposeStarGiveaway() { - } - - /** - * The user creating a Telegram Star giveaway. - * - * @param parameters Giveaway parameters. - * @param currency ISO 4217 currency code of the payment currency. - * @param amount Paid amount, in the smallest units of the currency. - * @param winnerCount The number of users to receive Telegram Stars. - * @param starCount The number of Telegram Stars to be distributed through the giveaway. - */ - public TelegramPaymentPurposeStarGiveaway(GiveawayParameters parameters, String currency, long amount, int winnerCount, long starCount) { - this.parameters = parameters; - this.currency = currency; - this.amount = amount; - this.winnerCount = winnerCount; - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1014604689; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user joins a chat and subscribes to regular payments in Telegram Stars. - */ - public static class TelegramPaymentPurposeJoinChat extends TelegramPaymentPurpose { - /** - * Invite link to use. - */ - public String inviteLink; - - /** - * The user joins a chat and subscribes to regular payments in Telegram Stars. - */ - public TelegramPaymentPurposeJoinChat() { - } - - /** - * The user joins a chat and subscribes to regular payments in Telegram Stars. - * - * @param inviteLink Invite link to use. - */ - public TelegramPaymentPurposeJoinChat(String inviteLink) { - this.inviteLink = inviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1914869880; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about the availability of a temporary password, which can be used for payments. - */ - public static class TemporaryPasswordState extends Object { - /** - * True, if a temporary password is available. - */ - public boolean hasPassword; - /** - * Time left before the temporary password expires, in seconds. - */ - public int validFor; - - /** - * Returns information about the availability of a temporary password, which can be used for payments. - */ - public TemporaryPasswordState() { - } - - /** - * Returns information about the availability of a temporary password, which can be used for payments. - * - * @param hasPassword True, if a temporary password is available. - * @param validFor Time left before the temporary password expires, in seconds. - */ - public TemporaryPasswordState(boolean hasPassword, int validFor) { - this.hasPassword = hasPassword; - this.validFor = validFor; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 939837410; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains Telegram terms of service. - */ - public static class TermsOfService extends Object { - /** - * Text of the terms of service. - */ - public FormattedText text; - /** - * The minimum age of a user to be able to accept the terms; 0 if age isn't restricted. - */ - public int minUserAge; - /** - * True, if a blocking popup with terms of service must be shown to the user. - */ - public boolean showPopup; - - /** - * Contains Telegram terms of service. - */ - public TermsOfService() { - } - - /** - * Contains Telegram terms of service. - * - * @param text Text of the terms of service. - * @param minUserAge The minimum age of a user to be able to accept the terms; 0 if age isn't restricted. - * @param showPopup True, if a blocking popup with terms of service must be shown to the user. - */ - public TermsOfService(FormattedText text, int minUserAge, boolean showPopup) { - this.text = text; - this.minUserAge = minUserAge; - this.showPopup = showPopup; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 739422597; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A simple object containing a sequence of bytes; for testing only. - */ - public static class TestBytes extends Object { - /** - * Bytes. - */ - public byte[] value; - - /** - * A simple object containing a sequence of bytes; for testing only. - */ - public TestBytes() { - } - - /** - * A simple object containing a sequence of bytes; for testing only. - * - * @param value Bytes. - */ - public TestBytes(byte[] value) { - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1541225250; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A simple object containing a number; for testing only. - */ - public static class TestInt extends Object { - /** - * Number. - */ - public int value; - - /** - * A simple object containing a number; for testing only. - */ - public TestInt() { - } - - /** - * A simple object containing a number; for testing only. - * - * @param value Number. - */ - public TestInt(int value) { - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -574804983; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A simple object containing a string; for testing only. - */ - public static class TestString extends Object { - /** - * String. - */ - public String value; - - /** - * A simple object containing a string; for testing only. - */ - public TestString() { - } - - /** - * A simple object containing a string; for testing only. - * - * @param value String. - */ - public TestString(String value) { - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -27891572; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A simple object containing a vector of numbers; for testing only. - */ - public static class TestVectorInt extends Object { - /** - * Vector of numbers. - */ - public int[] value; - - /** - * A simple object containing a vector of numbers; for testing only. - */ - public TestVectorInt() { - } - - /** - * A simple object containing a vector of numbers; for testing only. - * - * @param value Vector of numbers. - */ - public TestVectorInt(int[] value) { - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 593682027; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A simple object containing a vector of objects that hold a number; for testing only. - */ - public static class TestVectorIntObject extends Object { - /** - * Vector of objects. - */ - public TestInt[] value; - - /** - * A simple object containing a vector of objects that hold a number; for testing only. - */ - public TestVectorIntObject() { - } - - /** - * A simple object containing a vector of objects that hold a number; for testing only. - * - * @param value Vector of objects. - */ - public TestVectorIntObject(TestInt[] value) { - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 125891546; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A simple object containing a vector of strings; for testing only. - */ - public static class TestVectorString extends Object { - /** - * Vector of strings. - */ - public String[] value; - - /** - * A simple object containing a vector of strings; for testing only. - */ - public TestVectorString() { - } - - /** - * A simple object containing a vector of strings; for testing only. - * - * @param value Vector of strings. - */ - public TestVectorString(String[] value) { - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 79339995; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A simple object containing a vector of objects that hold a string; for testing only. - */ - public static class TestVectorStringObject extends Object { - /** - * Vector of objects. - */ - public TestString[] value; - - /** - * A simple object containing a vector of objects that hold a string; for testing only. - */ - public TestVectorStringObject() { - } - - /** - * A simple object containing a vector of objects that hold a string; for testing only. - * - * @param value Vector of objects. - */ - public TestVectorStringObject(TestString[] value) { - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 80780537; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains some text. - */ - public static class Text extends Object { - /** - * Text. - */ - public String text; - - /** - * Contains some text. - */ - public Text() { - } - - /** - * Contains some text. - * - * @param text Text. - */ - public Text(String text) { - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 578181272; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of text entities. - */ - public static class TextEntities extends Object { - /** - * List of text entities. - */ - public TextEntity[] entities; - - /** - * Contains a list of text entities. - */ - public TextEntities() { - } - - /** - * Contains a list of text entities. - * - * @param entities List of text entities. - */ - public TextEntities(TextEntity[] entities) { - this.entities = entities; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -933199172; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a part of the text that needs to be formatted in some unusual way. - */ - public static class TextEntity extends Object { - /** - * Offset of the entity, in UTF-16 code units. - */ - public int offset; - /** - * Length of the entity, in UTF-16 code units. - */ - public int length; - /** - * Type of the entity. - */ - public TextEntityType type; - - /** - * Represents a part of the text that needs to be formatted in some unusual way. - */ - public TextEntity() { - } - - /** - * Represents a part of the text that needs to be formatted in some unusual way. - * - * @param offset Offset of the entity, in UTF-16 code units. - * @param length Length of the entity, in UTF-16 code units. - * @param type Type of the entity. - */ - public TextEntity(int offset, int length, TextEntityType type) { - this.offset = offset; - this.length = length; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1951688280; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents a part of the text which must be formatted differently. - */ - public abstract static class TextEntityType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - TextEntityTypeMention.CONSTRUCTOR, - TextEntityTypeHashtag.CONSTRUCTOR, - TextEntityTypeCashtag.CONSTRUCTOR, - TextEntityTypeBotCommand.CONSTRUCTOR, - TextEntityTypeUrl.CONSTRUCTOR, - TextEntityTypeEmailAddress.CONSTRUCTOR, - TextEntityTypePhoneNumber.CONSTRUCTOR, - TextEntityTypeBankCardNumber.CONSTRUCTOR, - TextEntityTypeBold.CONSTRUCTOR, - TextEntityTypeItalic.CONSTRUCTOR, - TextEntityTypeUnderline.CONSTRUCTOR, - TextEntityTypeStrikethrough.CONSTRUCTOR, - TextEntityTypeSpoiler.CONSTRUCTOR, - TextEntityTypeCode.CONSTRUCTOR, - TextEntityTypePre.CONSTRUCTOR, - TextEntityTypePreCode.CONSTRUCTOR, - TextEntityTypeBlockQuote.CONSTRUCTOR, - TextEntityTypeExpandableBlockQuote.CONSTRUCTOR, - TextEntityTypeTextUrl.CONSTRUCTOR, - TextEntityTypeMentionName.CONSTRUCTOR, - TextEntityTypeCustomEmoji.CONSTRUCTOR, - TextEntityTypeMediaTimestamp.CONSTRUCTOR, - TextEntityTypeDateTime.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public TextEntityType() { - } - } - - /** - * A mention of a user, a supergroup, or a channel by their username. - */ - public static class TextEntityTypeMention extends TextEntityType { - - /** - * A mention of a user, a supergroup, or a channel by their username. - */ - public TextEntityTypeMention() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 934535013; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A hashtag text, beginning with "#" and optionally containing a chat username at the end. - */ - public static class TextEntityTypeHashtag extends TextEntityType { - - /** - * A hashtag text, beginning with "#" and optionally containing a chat username at the end. - */ - public TextEntityTypeHashtag() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1023958307; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A cashtag text, beginning with "$", consisting of capital English letters (e.g., "$USD"), and optionally containing a chat username at the end. - */ - public static class TextEntityTypeCashtag extends TextEntityType { - - /** - * A cashtag text, beginning with "$", consisting of capital English letters (e.g., "$USD"), and optionally containing a chat username at the end. - */ - public TextEntityTypeCashtag() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1222915915; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A bot command, beginning with "/". - */ - public static class TextEntityTypeBotCommand extends TextEntityType { - - /** - * A bot command, beginning with "/". - */ - public TextEntityTypeBotCommand() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1150997581; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An HTTP URL. - */ - public static class TextEntityTypeUrl extends TextEntityType { - - /** - * An HTTP URL. - */ - public TextEntityTypeUrl() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1312762756; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An email address. - */ - public static class TextEntityTypeEmailAddress extends TextEntityType { - - /** - * An email address. - */ - public TextEntityTypeEmailAddress() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1425545249; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A phone number. - */ - public static class TextEntityTypePhoneNumber extends TextEntityType { - - /** - * A phone number. - */ - public TextEntityTypePhoneNumber() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1160140246; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A bank card number. The getBankCardInfo method can be used to get information about the bank card. - */ - public static class TextEntityTypeBankCardNumber extends TextEntityType { - - /** - * A bank card number. The getBankCardInfo method can be used to get information about the bank card. - */ - public TextEntityTypeBankCardNumber() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 105986320; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A bold text. - */ - public static class TextEntityTypeBold extends TextEntityType { - - /** - * A bold text. - */ - public TextEntityTypeBold() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1128210000; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An italic text. - */ - public static class TextEntityTypeItalic extends TextEntityType { - - /** - * An italic text. - */ - public TextEntityTypeItalic() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -118253987; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An underlined text. - */ - public static class TextEntityTypeUnderline extends TextEntityType { - - /** - * An underlined text. - */ - public TextEntityTypeUnderline() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 792317842; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A strikethrough text. - */ - public static class TextEntityTypeStrikethrough extends TextEntityType { - - /** - * A strikethrough text. - */ - public TextEntityTypeStrikethrough() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 961529082; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A spoiler text. - */ - public static class TextEntityTypeSpoiler extends TextEntityType { - - /** - * A spoiler text. - */ - public TextEntityTypeSpoiler() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 544019899; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Text that must be formatted as if inside a code HTML tag. - */ - public static class TextEntityTypeCode extends TextEntityType { - - /** - * Text that must be formatted as if inside a code HTML tag. - */ - public TextEntityTypeCode() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -974534326; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Text that must be formatted as if inside a pre HTML tag. - */ - public static class TextEntityTypePre extends TextEntityType { - - /** - * Text that must be formatted as if inside a pre HTML tag. - */ - public TextEntityTypePre() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1648958606; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Text that must be formatted as if inside pre, and code HTML tags. - */ - public static class TextEntityTypePreCode extends TextEntityType { - /** - * Programming language of the code; as defined by the sender. - */ - public String language; - - /** - * Text that must be formatted as if inside pre, and code HTML tags. - */ - public TextEntityTypePreCode() { - } - - /** - * Text that must be formatted as if inside pre, and code HTML tags. - * - * @param language Programming language of the code; as defined by the sender. - */ - public TextEntityTypePreCode(String language) { - this.language = language; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -945325397; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Text that must be formatted as if inside a blockquote HTML tag; not supported in secret chats. - */ - public static class TextEntityTypeBlockQuote extends TextEntityType { - - /** - * Text that must be formatted as if inside a blockquote HTML tag; not supported in secret chats. - */ - public TextEntityTypeBlockQuote() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1003999032; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Text that must be formatted as if inside a blockquote HTML tag and collapsed by default to 3 lines with the ability to show full text; not supported in secret chats. - */ - public static class TextEntityTypeExpandableBlockQuote extends TextEntityType { - - /** - * Text that must be formatted as if inside a blockquote HTML tag and collapsed by default to 3 lines with the ability to show full text; not supported in secret chats. - */ - public TextEntityTypeExpandableBlockQuote() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 36572261; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A text description shown instead of a raw URL. - */ - public static class TextEntityTypeTextUrl extends TextEntityType { - /** - * HTTP or tg:// URL to be opened when the link is clicked. - */ - public String url; - - /** - * A text description shown instead of a raw URL. - */ - public TextEntityTypeTextUrl() { - } - - /** - * A text description shown instead of a raw URL. - * - * @param url HTTP or tg:// URL to be opened when the link is clicked. - */ - public TextEntityTypeTextUrl(String url) { - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 445719651; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A text shows instead of a raw mention of the user (e.g., when the user has no username). - */ - public static class TextEntityTypeMentionName extends TextEntityType { - /** - * Identifier of the mentioned user. - */ - public long userId; - - /** - * A text shows instead of a raw mention of the user (e.g., when the user has no username). - */ - public TextEntityTypeMentionName() { - } - - /** - * A text shows instead of a raw mention of the user (e.g., when the user has no username). - * - * @param userId Identifier of the mentioned user. - */ - public TextEntityTypeMentionName(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1570974289; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A custom emoji. The text behind a custom emoji must be an emoji. Only premium users can use premium custom emoji. - */ - public static class TextEntityTypeCustomEmoji extends TextEntityType { - /** - * Unique identifier of the custom emoji. - */ - public long customEmojiId; - - /** - * A custom emoji. The text behind a custom emoji must be an emoji. Only premium users can use premium custom emoji. - */ - public TextEntityTypeCustomEmoji() { - } - - /** - * A custom emoji. The text behind a custom emoji must be an emoji. Only premium users can use premium custom emoji. - * - * @param customEmojiId Unique identifier of the custom emoji. - */ - public TextEntityTypeCustomEmoji(long customEmojiId) { - this.customEmojiId = customEmojiId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1724820677; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A media timestamp. - */ - public static class TextEntityTypeMediaTimestamp extends TextEntityType { - /** - * Timestamp from which a video/audio/video note/voice note/story playing must start, in seconds. The media can be in the content or the link preview of the current message, or in the same places in the replied message. - */ - public int mediaTimestamp; - - /** - * A media timestamp. - */ - public TextEntityTypeMediaTimestamp() { - } - - /** - * A media timestamp. - * - * @param mediaTimestamp Timestamp from which a video/audio/video note/voice note/story playing must start, in seconds. The media can be in the content or the link preview of the current message, or in the same places in the replied message. - */ - public TextEntityTypeMediaTimestamp(int mediaTimestamp) { - this.mediaTimestamp = mediaTimestamp; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1841898992; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A date and time. - */ - public static class TextEntityTypeDateTime extends TextEntityType { - /** - * Point in time (Unix timestamp) representing the date and time. - */ - public int unixTime; - /** - * Date and time formatting type; may be null if none and the original text must not be changed. - */ - @Nullable public DateTimeFormattingType formattingType; - - /** - * A date and time. - */ - public TextEntityTypeDateTime() { - } - - /** - * A date and time. - * - * @param unixTime Point in time (Unix timestamp) representing the date and time. - * @param formattingType Date and time formatting type; may be null if none and the original text must not be changed. - */ - public TextEntityTypeDateTime(int unixTime, DateTimeFormattingType formattingType) { - this.unixTime = unixTime; - this.formattingType = formattingType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1544268588; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the way the text needs to be parsed for text entities. - */ - public abstract static class TextParseMode extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - TextParseModeMarkdown.CONSTRUCTOR, - TextParseModeHTML.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public TextParseMode() { - } - } - - /** - * The text uses Markdown-style formatting. - */ - public static class TextParseModeMarkdown extends TextParseMode { - /** - * Version of the parser: 0 or 1 - Telegram Bot API "Markdown" parse mode, 2 - Telegram Bot API "MarkdownV2" parse mode. - */ - public int version; - - /** - * The text uses Markdown-style formatting. - */ - public TextParseModeMarkdown() { - } - - /** - * The text uses Markdown-style formatting. - * - * @param version Version of the parser: 0 or 1 - Telegram Bot API "Markdown" parse mode, 2 - Telegram Bot API "MarkdownV2" parse mode. - */ - public TextParseModeMarkdown(int version) { - this.version = version; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 360073407; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The text uses HTML-style formatting. The same as Telegram Bot API "HTML" parse mode. - */ - public static class TextParseModeHTML extends TextParseMode { - - /** - * The text uses HTML-style formatting. The same as Telegram Bot API "HTML" parse mode. - */ - public TextParseModeHTML() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1660208627; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes manually or automatically chosen quote from another message. - */ - public static class TextQuote extends Object { - /** - * Text of the quote. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities can be present in the text. - */ - public FormattedText text; - /** - * Approximate quote position in the original message in UTF-16 code units as specified by the message sender. - */ - public int position; - /** - * True, if the quote was manually chosen by the message sender. - */ - public boolean isManual; - - /** - * Describes manually or automatically chosen quote from another message. - */ - public TextQuote() { - } - - /** - * Describes manually or automatically chosen quote from another message. - * - * @param text Text of the quote. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities can be present in the text. - * @param position Approximate quote position in the original message in UTF-16 code units as specified by the message sender. - * @param isManual True, if the quote was manually chosen by the message sender. - */ - public TextQuote(FormattedText text, int position, boolean isManual) { - this.text = text; - this.position = position; - this.isManual = isManual; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2039105358; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains parameters of the application theme. - */ - public static class ThemeParameters extends Object { - /** - * A color of the background in the RGB format. - */ - public int backgroundColor; - /** - * A secondary color for the background in the RGB format. - */ - public int secondaryBackgroundColor; - /** - * A color of the header background in the RGB format. - */ - public int headerBackgroundColor; - /** - * A color of the bottom bar background in the RGB format. - */ - public int bottomBarBackgroundColor; - /** - * A color of the section background in the RGB format. - */ - public int sectionBackgroundColor; - /** - * A color of the section separator in the RGB format. - */ - public int sectionSeparatorColor; - /** - * A color of text in the RGB format. - */ - public int textColor; - /** - * An accent color of the text in the RGB format. - */ - public int accentTextColor; - /** - * A color of text on the section headers in the RGB format. - */ - public int sectionHeaderTextColor; - /** - * A color of the subtitle text in the RGB format. - */ - public int subtitleTextColor; - /** - * A color of the text for destructive actions in the RGB format. - */ - public int destructiveTextColor; - /** - * A color of hints in the RGB format. - */ - public int hintColor; - /** - * A color of links in the RGB format. - */ - public int linkColor; - /** - * A color of the buttons in the RGB format. - */ - public int buttonColor; - /** - * A color of text on the buttons in the RGB format. - */ - public int buttonTextColor; - - /** - * Contains parameters of the application theme. - */ - public ThemeParameters() { - } - - /** - * Contains parameters of the application theme. - * - * @param backgroundColor A color of the background in the RGB format. - * @param secondaryBackgroundColor A secondary color for the background in the RGB format. - * @param headerBackgroundColor A color of the header background in the RGB format. - * @param bottomBarBackgroundColor A color of the bottom bar background in the RGB format. - * @param sectionBackgroundColor A color of the section background in the RGB format. - * @param sectionSeparatorColor A color of the section separator in the RGB format. - * @param textColor A color of text in the RGB format. - * @param accentTextColor An accent color of the text in the RGB format. - * @param sectionHeaderTextColor A color of text on the section headers in the RGB format. - * @param subtitleTextColor A color of the subtitle text in the RGB format. - * @param destructiveTextColor A color of the text for destructive actions in the RGB format. - * @param hintColor A color of hints in the RGB format. - * @param linkColor A color of links in the RGB format. - * @param buttonColor A color of the buttons in the RGB format. - * @param buttonTextColor A color of text on the buttons in the RGB format. - */ - public ThemeParameters(int backgroundColor, int secondaryBackgroundColor, int headerBackgroundColor, int bottomBarBackgroundColor, int sectionBackgroundColor, int sectionSeparatorColor, int textColor, int accentTextColor, int sectionHeaderTextColor, int subtitleTextColor, int destructiveTextColor, int hintColor, int linkColor, int buttonColor, int buttonTextColor) { - this.backgroundColor = backgroundColor; - this.secondaryBackgroundColor = secondaryBackgroundColor; - this.headerBackgroundColor = headerBackgroundColor; - this.bottomBarBackgroundColor = bottomBarBackgroundColor; - this.sectionBackgroundColor = sectionBackgroundColor; - this.sectionSeparatorColor = sectionSeparatorColor; - this.textColor = textColor; - this.accentTextColor = accentTextColor; - this.sectionHeaderTextColor = sectionHeaderTextColor; - this.subtitleTextColor = subtitleTextColor; - this.destructiveTextColor = destructiveTextColor; - this.hintColor = hintColor; - this.linkColor = linkColor; - this.buttonColor = buttonColor; - this.buttonTextColor = buttonTextColor; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -276589137; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes theme settings. - */ - public static class ThemeSettings extends Object { - /** - * Base theme for this theme. - */ - public BuiltInTheme baseTheme; - /** - * Theme accent color in ARGB format. - */ - public int accentColor; - /** - * The background to be used in chats; may be null. - */ - @Nullable public Background background; - /** - * The fill to be used as a background for outgoing messages; may be null if the fill from the base theme must be used instead. - */ - @Nullable public BackgroundFill outgoingMessageFill; - /** - * If true, the freeform gradient fill needs to be animated on every sent message. - */ - public boolean animateOutgoingMessageFill; - /** - * Accent color of outgoing messages in ARGB format. - */ - public int outgoingMessageAccentColor; - - /** - * Describes theme settings. - */ - public ThemeSettings() { - } - - /** - * Describes theme settings. - * - * @param baseTheme Base theme for this theme. - * @param accentColor Theme accent color in ARGB format. - * @param background The background to be used in chats; may be null. - * @param outgoingMessageFill The fill to be used as a background for outgoing messages; may be null if the fill from the base theme must be used instead. - * @param animateOutgoingMessageFill If true, the freeform gradient fill needs to be animated on every sent message. - * @param outgoingMessageAccentColor Accent color of outgoing messages in ARGB format. - */ - public ThemeSettings(BuiltInTheme baseTheme, int accentColor, Background background, BackgroundFill outgoingMessageFill, boolean animateOutgoingMessageFill, int outgoingMessageAccentColor) { - this.baseTheme = baseTheme; - this.accentColor = accentColor; - this.background = background; - this.outgoingMessageFill = outgoingMessageFill; - this.animateOutgoingMessageFill = animateOutgoingMessageFill; - this.outgoingMessageAccentColor = outgoingMessageAccentColor; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1935106938; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a thumbnail. - */ - public static class Thumbnail extends Object { - /** - * Thumbnail format. - */ - public ThumbnailFormat format; - /** - * Thumbnail width. - */ - public int width; - /** - * Thumbnail height. - */ - public int height; - /** - * The thumbnail. - */ - public File file; - - /** - * Represents a thumbnail. - */ - public Thumbnail() { - } - - /** - * Represents a thumbnail. - * - * @param format Thumbnail format. - * @param width Thumbnail width. - * @param height Thumbnail height. - * @param file The thumbnail. - */ - public Thumbnail(ThumbnailFormat format, int width, int height, File file) { - this.format = format; - this.width = width; - this.height = height; - this.file = file; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1243275371; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes format of a thumbnail. - */ - public abstract static class ThumbnailFormat extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - ThumbnailFormatJpeg.CONSTRUCTOR, - ThumbnailFormatGif.CONSTRUCTOR, - ThumbnailFormatMpeg4.CONSTRUCTOR, - ThumbnailFormatPng.CONSTRUCTOR, - ThumbnailFormatTgs.CONSTRUCTOR, - ThumbnailFormatWebm.CONSTRUCTOR, - ThumbnailFormatWebp.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public ThumbnailFormat() { - } - } - - /** - * The thumbnail is in JPEG format. - */ - public static class ThumbnailFormatJpeg extends ThumbnailFormat { - - /** - * The thumbnail is in JPEG format. - */ - public ThumbnailFormatJpeg() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -653503352; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The thumbnail is in static GIF format. It will be used only for some bot inline query results. - */ - public static class ThumbnailFormatGif extends ThumbnailFormat { - - /** - * The thumbnail is in static GIF format. It will be used only for some bot inline query results. - */ - public ThumbnailFormatGif() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1252205962; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The thumbnail is in MPEG4 format. It will be used only for some animations and videos. - */ - public static class ThumbnailFormatMpeg4 extends ThumbnailFormat { - - /** - * The thumbnail is in MPEG4 format. It will be used only for some animations and videos. - */ - public ThumbnailFormatMpeg4() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 278616062; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The thumbnail is in PNG format. It will be used only for background patterns. - */ - public static class ThumbnailFormatPng extends ThumbnailFormat { - - /** - * The thumbnail is in PNG format. It will be used only for background patterns. - */ - public ThumbnailFormatPng() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1577490421; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The thumbnail is in TGS format. It will be used only for sticker sets. - */ - public static class ThumbnailFormatTgs extends ThumbnailFormat { - - /** - * The thumbnail is in TGS format. It will be used only for sticker sets. - */ - public ThumbnailFormatTgs() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1315522642; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The thumbnail is in WEBM format. It will be used only for sticker sets. - */ - public static class ThumbnailFormatWebm extends ThumbnailFormat { - - /** - * The thumbnail is in WEBM format. It will be used only for sticker sets. - */ - public ThumbnailFormatWebm() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -660084953; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The thumbnail is in WEBP format. It will be used only for some stickers and sticker sets. - */ - public static class ThumbnailFormatWebp extends ThumbnailFormat { - - /** - * The thumbnail is in WEBP format. It will be used only for some stickers and sticker sets. - */ - public ThumbnailFormatWebp() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -53588974; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a time zone. - */ - public static class TimeZone extends Object { - /** - * Unique time zone identifier. - */ - public String id; - /** - * Time zone name. - */ - public String name; - /** - * Current UTC time offset for the time zone. - */ - public int utcTimeOffset; - - /** - * Describes a time zone. - */ - public TimeZone() { - } - - /** - * Describes a time zone. - * - * @param id Unique time zone identifier. - * @param name Time zone name. - * @param utcTimeOffset Current UTC time offset for the time zone. - */ - public TimeZone(String id, String name, int utcTimeOffset) { - this.id = id; - this.name = name; - this.utcTimeOffset = utcTimeOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1189481763; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of time zones. - */ - public static class TimeZones extends Object { - /** - * A list of time zones. - */ - public TimeZone[] timeZones; - - /** - * Contains a list of time zones. - */ - public TimeZones() { - } - - /** - * Contains a list of time zones. - * - * @param timeZones A list of time zones. - */ - public TimeZones(TimeZone[] timeZones) { - this.timeZones = timeZones; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -334655570; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A detailed statistics about Toncoins earned by the current user. - */ - public static class TonRevenueStatistics extends Object { - /** - * A graph containing amount of revenue in a given day. - */ - public StatisticalGraph revenueByDayGraph; - /** - * Amount of earned revenue. - */ - public TonRevenueStatus status; - /** - * Current conversion rate of nanotoncoin to USD cents. - */ - public double usdRate; - - /** - * A detailed statistics about Toncoins earned by the current user. - */ - public TonRevenueStatistics() { - } - - /** - * A detailed statistics about Toncoins earned by the current user. - * - * @param revenueByDayGraph A graph containing amount of revenue in a given day. - * @param status Amount of earned revenue. - * @param usdRate Current conversion rate of nanotoncoin to USD cents. - */ - public TonRevenueStatistics(StatisticalGraph revenueByDayGraph, TonRevenueStatus status, double usdRate) { - this.revenueByDayGraph = revenueByDayGraph; - this.status = status; - this.usdRate = usdRate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 565933594; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about Toncoins earned by the current user. - */ - public static class TonRevenueStatus extends Object { - /** - * Total Toncoin amount earned; in the smallest units of the cryptocurrency. - */ - public long totalAmount; - /** - * The Toncoin amount that isn't withdrawn yet; in the smallest units of the cryptocurrency. - */ - public long balanceAmount; - /** - * The Toncoin amount that is available for withdrawal; in the smallest units of the cryptocurrency. - */ - public long availableAmount; - /** - * True, if Toncoins can be withdrawn. - */ - public boolean withdrawalEnabled; - - /** - * Contains information about Toncoins earned by the current user. - */ - public TonRevenueStatus() { - } - - /** - * Contains information about Toncoins earned by the current user. - * - * @param totalAmount Total Toncoin amount earned; in the smallest units of the cryptocurrency. - * @param balanceAmount The Toncoin amount that isn't withdrawn yet; in the smallest units of the cryptocurrency. - * @param availableAmount The Toncoin amount that is available for withdrawal; in the smallest units of the cryptocurrency. - * @param withdrawalEnabled True, if Toncoins can be withdrawn. - */ - public TonRevenueStatus(long totalAmount, long balanceAmount, long availableAmount, boolean withdrawalEnabled) { - this.totalAmount = totalAmount; - this.balanceAmount = balanceAmount; - this.availableAmount = availableAmount; - this.withdrawalEnabled = withdrawalEnabled; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1437514030; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a transaction changing the amount of owned Toncoins. - */ - public static class TonTransaction extends Object { - /** - * Unique identifier of the transaction. - */ - public String id; - /** - * The amount of added owned Toncoins; negative for outgoing transactions. - */ - public long tonAmount; - /** - * True, if the transaction is a refund of a previous transaction. - */ - public boolean isRefund; - /** - * Point in time (Unix timestamp) when the transaction was completed. - */ - public int date; - /** - * Type of the transaction. - */ - public TonTransactionType type; - - /** - * Represents a transaction changing the amount of owned Toncoins. - */ - public TonTransaction() { - } - - /** - * Represents a transaction changing the amount of owned Toncoins. - * - * @param id Unique identifier of the transaction. - * @param tonAmount The amount of added owned Toncoins; negative for outgoing transactions. - * @param isRefund True, if the transaction is a refund of a previous transaction. - * @param date Point in time (Unix timestamp) when the transaction was completed. - * @param type Type of the transaction. - */ - public TonTransaction(String id, long tonAmount, boolean isRefund, int date, TonTransactionType type) { - this.id = id; - this.tonAmount = tonAmount; - this.isRefund = isRefund; - this.date = date; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1562036527; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes type of transaction with Toncoins. - */ - public abstract static class TonTransactionType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - TonTransactionTypeFragmentDeposit.CONSTRUCTOR, - TonTransactionTypeFragmentWithdrawal.CONSTRUCTOR, - TonTransactionTypeSuggestedPostPayment.CONSTRUCTOR, - TonTransactionTypeGiftPurchaseOffer.CONSTRUCTOR, - TonTransactionTypeUpgradedGiftPurchase.CONSTRUCTOR, - TonTransactionTypeUpgradedGiftSale.CONSTRUCTOR, - TonTransactionTypeStakeDiceStake.CONSTRUCTOR, - TonTransactionTypeStakeDicePayout.CONSTRUCTOR, - TonTransactionTypeUnsupported.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public TonTransactionType() { - } - } - - /** - * The transaction is a deposit of Toncoins from Fragment. - */ - public static class TonTransactionTypeFragmentDeposit extends TonTransactionType { - /** - * True, if the transaction is a gift from another user. - */ - public boolean isGift; - /** - * The sticker to be shown in the transaction information; may be null if unknown. - */ - @Nullable public Sticker sticker; - - /** - * The transaction is a deposit of Toncoins from Fragment. - */ - public TonTransactionTypeFragmentDeposit() { - } - - /** - * The transaction is a deposit of Toncoins from Fragment. - * - * @param isGift True, if the transaction is a gift from another user. - * @param sticker The sticker to be shown in the transaction information; may be null if unknown. - */ - public TonTransactionTypeFragmentDeposit(boolean isGift, Sticker sticker) { - this.isGift = isGift; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1395530668; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a withdrawal of earned Toncoins to Fragment. - */ - public static class TonTransactionTypeFragmentWithdrawal extends TonTransactionType { - /** - * State of the withdrawal; may be null for refunds from Fragment. - */ - @Nullable public RevenueWithdrawalState withdrawalState; - - /** - * The transaction is a withdrawal of earned Toncoins to Fragment. - */ - public TonTransactionTypeFragmentWithdrawal() { - } - - /** - * The transaction is a withdrawal of earned Toncoins to Fragment. - * - * @param withdrawalState State of the withdrawal; may be null for refunds from Fragment. - */ - public TonTransactionTypeFragmentWithdrawal(RevenueWithdrawalState withdrawalState) { - this.withdrawalState = withdrawalState; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1410960428; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a payment for a suggested post. - */ - public static class TonTransactionTypeSuggestedPostPayment extends TonTransactionType { - /** - * Identifier of the channel chat that posted the post. - */ - public long chatId; - - /** - * The transaction is a payment for a suggested post. - */ - public TonTransactionTypeSuggestedPostPayment() { - } - - /** - * The transaction is a payment for a suggested post. - * - * @param chatId Identifier of the channel chat that posted the post. - */ - public TonTransactionTypeSuggestedPostPayment(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -396472561; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is an offer of gift purchase. - */ - public static class TonTransactionTypeGiftPurchaseOffer extends TonTransactionType { - /** - * The gift. - */ - public UpgradedGift gift; - - /** - * The transaction is an offer of gift purchase. - */ - public TonTransactionTypeGiftPurchaseOffer() { - } - - /** - * The transaction is an offer of gift purchase. - * - * @param gift The gift. - */ - public TonTransactionTypeGiftPurchaseOffer(UpgradedGift gift) { - this.gift = gift; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1754409273; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a purchase of an upgraded gift for some user or channel. - */ - public static class TonTransactionTypeUpgradedGiftPurchase extends TonTransactionType { - /** - * Identifier of the user who sold the gift. - */ - public long userId; - /** - * The gift. - */ - public UpgradedGift gift; - - /** - * The transaction is a purchase of an upgraded gift for some user or channel. - */ - public TonTransactionTypeUpgradedGiftPurchase() { - } - - /** - * The transaction is a purchase of an upgraded gift for some user or channel. - * - * @param userId Identifier of the user who sold the gift. - * @param gift The gift. - */ - public TonTransactionTypeUpgradedGiftPurchase(long userId, UpgradedGift gift) { - this.userId = userId; - this.gift = gift; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2007364707; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a sale of an upgraded gift. - */ - public static class TonTransactionTypeUpgradedGiftSale extends TonTransactionType { - /** - * Identifier of the user who bought the gift. - */ - public long userId; - /** - * The gift. - */ - public UpgradedGift gift; - /** - * The number of Toncoins received by the Telegram for each 1000 Toncoins received by the seller of the gift. - */ - public int commissionPerMille; - /** - * The Toncoin amount that was received by the Telegram; in the smallest units of the currency. - */ - public long commissionToncoinAmount; - /** - * True, if the gift was sold through a purchase offer. - */ - public boolean viaOffer; - - /** - * The transaction is a sale of an upgraded gift. - */ - public TonTransactionTypeUpgradedGiftSale() { - } - - /** - * The transaction is a sale of an upgraded gift. - * - * @param userId Identifier of the user who bought the gift. - * @param gift The gift. - * @param commissionPerMille The number of Toncoins received by the Telegram for each 1000 Toncoins received by the seller of the gift. - * @param commissionToncoinAmount The Toncoin amount that was received by the Telegram; in the smallest units of the currency. - * @param viaOffer True, if the gift was sold through a purchase offer. - */ - public TonTransactionTypeUpgradedGiftSale(long userId, UpgradedGift gift, int commissionPerMille, long commissionToncoinAmount, boolean viaOffer) { - this.userId = userId; - this.gift = gift; - this.commissionPerMille = commissionPerMille; - this.commissionToncoinAmount = commissionToncoinAmount; - this.viaOffer = viaOffer; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1162099275; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a payment for stake dice throw. - */ - public static class TonTransactionTypeStakeDiceStake extends TonTransactionType { - - /** - * The transaction is a payment for stake dice throw. - */ - public TonTransactionTypeStakeDiceStake() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1789542822; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a payment for successful stake dice throw. - */ - public static class TonTransactionTypeStakeDicePayout extends TonTransactionType { - - /** - * The transaction is a payment for successful stake dice throw. - */ - public TonTransactionTypeStakeDicePayout() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -25462760; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is a transaction of an unsupported type. - */ - public static class TonTransactionTypeUnsupported extends TonTransactionType { - - /** - * The transaction is a transaction of an unsupported type. - */ - public TonTransactionTypeUnsupported() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1747387269; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of Toncoin transactions. - */ - public static class TonTransactions extends Object { - /** - * The total amount of owned Toncoins. - */ - public long tonAmount; - /** - * List of Toncoin transactions. - */ - public TonTransaction[] transactions; - /** - * The offset for the next request. If empty, then there are no more results. - */ - public String nextOffset; - - /** - * Represents a list of Toncoin transactions. - */ - public TonTransactions() { - } - - /** - * Represents a list of Toncoin transactions. - * - * @param tonAmount The total amount of owned Toncoins. - * @param transactions List of Toncoin transactions. - * @param nextOffset The offset for the next request. If empty, then there are no more results. - */ - public TonTransactions(long tonAmount, TonTransaction[] transactions, String nextOffset) { - this.tonAmount = tonAmount; - this.transactions = transactions; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1317235021; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents the categories of chats for which a list of frequently used chats can be retrieved. - */ - public abstract static class TopChatCategory extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - TopChatCategoryUsers.CONSTRUCTOR, - TopChatCategoryBots.CONSTRUCTOR, - TopChatCategoryGroups.CONSTRUCTOR, - TopChatCategoryChannels.CONSTRUCTOR, - TopChatCategoryInlineBots.CONSTRUCTOR, - TopChatCategoryWebAppBots.CONSTRUCTOR, - TopChatCategoryCalls.CONSTRUCTOR, - TopChatCategoryForwardChats.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public TopChatCategory() { - } - } - - /** - * A category containing frequently used private chats with non-bot users. - */ - public static class TopChatCategoryUsers extends TopChatCategory { - - /** - * A category containing frequently used private chats with non-bot users. - */ - public TopChatCategoryUsers() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1026706816; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A category containing frequently used private chats with bot users. - */ - public static class TopChatCategoryBots extends TopChatCategory { - - /** - * A category containing frequently used private chats with bot users. - */ - public TopChatCategoryBots() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1577129195; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A category containing frequently used basic groups and supergroups. - */ - public static class TopChatCategoryGroups extends TopChatCategory { - - /** - * A category containing frequently used basic groups and supergroups. - */ - public TopChatCategoryGroups() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1530056846; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A category containing frequently used channels. - */ - public static class TopChatCategoryChannels extends TopChatCategory { - - /** - * A category containing frequently used channels. - */ - public TopChatCategoryChannels() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -500825885; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A category containing frequently used chats with inline bots sorted by their usage in inline mode. - */ - public static class TopChatCategoryInlineBots extends TopChatCategory { - - /** - * A category containing frequently used chats with inline bots sorted by their usage in inline mode. - */ - public TopChatCategoryInlineBots() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 377023356; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A category containing frequently used chats with bots, which Web Apps were opened. - */ - public static class TopChatCategoryWebAppBots extends TopChatCategory { - - /** - * A category containing frequently used chats with bots, which Web Apps were opened. - */ - public TopChatCategoryWebAppBots() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 100062973; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A category containing frequently used chats used for calls. - */ - public static class TopChatCategoryCalls extends TopChatCategory { - - /** - * A category containing frequently used chats used for calls. - */ - public TopChatCategoryCalls() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 356208861; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A category containing frequently used chats used to forward messages. - */ - public static class TopChatCategoryForwardChats extends TopChatCategory { - - /** - * A category containing frequently used chats used to forward messages. - */ - public TopChatCategoryForwardChats() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1695922133; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes direction of transactions in a transaction list. - */ - public abstract static class TransactionDirection extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - TransactionDirectionIncoming.CONSTRUCTOR, - TransactionDirectionOutgoing.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public TransactionDirection() { - } - } - - /** - * The transaction is incoming and increases the amount of owned currency. - */ - public static class TransactionDirectionIncoming extends TransactionDirection { - - /** - * The transaction is incoming and increases the amount of owned currency. - */ - public TransactionDirectionIncoming() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -271074103; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The transaction is outgoing and decreases the amount of owned currency. - */ - public static class TransactionDirectionOutgoing extends TransactionDirection { - - /** - * The transaction is outgoing and decreases the amount of owned currency. - */ - public TransactionDirectionOutgoing() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1638241254; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of trending sticker sets. - */ - public static class TrendingStickerSets extends Object { - /** - * Approximate total number of trending sticker sets. - */ - public int totalCount; - /** - * List of trending sticker sets. - */ - public StickerSetInfo[] sets; - /** - * True, if the list contains sticker sets with premium stickers. - */ - public boolean isPremium; - - /** - * Represents a list of trending sticker sets. - */ - public TrendingStickerSets() { - } - - /** - * Represents a list of trending sticker sets. - * - * @param totalCount Approximate total number of trending sticker sets. - * @param sets List of trending sticker sets. - * @param isPremium True, if the list contains sticker sets with premium stickers. - */ - public TrendingStickerSets(int totalCount, StickerSetInfo[] sets, boolean isPremium) { - this.totalCount = totalCount; - this.sets = sets; - this.isPremium = isPremium; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 41028940; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about an unconfirmed session. - */ - public static class UnconfirmedSession extends Object { - /** - * Session identifier. - */ - public long id; - /** - * Point in time (Unix timestamp) when the user has logged in. - */ - public int logInDate; - /** - * Model of the device that was used for the session creation, as provided by the application. - */ - public String deviceModel; - /** - * A human-readable description of the location from which the session was created, based on the IP address. - */ - public String location; - - /** - * Contains information about an unconfirmed session. - */ - public UnconfirmedSession() { - } - - /** - * Contains information about an unconfirmed session. - * - * @param id Session identifier. - * @param logInDate Point in time (Unix timestamp) when the user has logged in. - * @param deviceModel Model of the device that was used for the session creation, as provided by the application. - * @param location A human-readable description of the location from which the session was created, based on the IP address. - */ - public UnconfirmedSession(long id, int logInDate, String deviceModel, String location) { - this.id = id; - this.logInDate = logInDate; - this.deviceModel = deviceModel; - this.location = location; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2062726663; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about an unread reaction to a message. - */ - public static class UnreadReaction extends Object { - /** - * Type of the reaction. - */ - public ReactionType type; - /** - * Identifier of the sender, added the reaction. - */ - public MessageSender senderId; - /** - * True, if the reaction was added with a big animation. - */ - public boolean isBig; - - /** - * Contains information about an unread reaction to a message. - */ - public UnreadReaction() { - } - - /** - * Contains information about an unread reaction to a message. - * - * @param type Type of the reaction. - * @param senderId Identifier of the sender, added the reaction. - * @param isBig True, if the reaction was added with a big animation. - */ - public UnreadReaction(ReactionType type, MessageSender senderId, boolean isBig) { - this.type = type; - this.senderId = senderId; - this.isBig = isBig; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1940178046; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains notifications about data changes. - */ - public abstract static class Update extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - UpdateAuthorizationState.CONSTRUCTOR, - UpdateNewMessage.CONSTRUCTOR, - UpdateMessageSendAcknowledged.CONSTRUCTOR, - UpdateMessageSendSucceeded.CONSTRUCTOR, - UpdateMessageSendFailed.CONSTRUCTOR, - UpdateMessageContent.CONSTRUCTOR, - UpdateMessageEdited.CONSTRUCTOR, - UpdateMessageIsPinned.CONSTRUCTOR, - UpdateMessageInteractionInfo.CONSTRUCTOR, - UpdateMessageContentOpened.CONSTRUCTOR, - UpdateMessageMentionRead.CONSTRUCTOR, - UpdateMessageUnreadReactions.CONSTRUCTOR, - UpdateMessageFactCheck.CONSTRUCTOR, - UpdateMessageSuggestedPostInfo.CONSTRUCTOR, - UpdateMessageLiveLocationViewed.CONSTRUCTOR, - UpdateVideoPublished.CONSTRUCTOR, - UpdateNewChat.CONSTRUCTOR, - UpdateChatTitle.CONSTRUCTOR, - UpdateChatPhoto.CONSTRUCTOR, - UpdateChatAccentColors.CONSTRUCTOR, - UpdateChatPermissions.CONSTRUCTOR, - UpdateChatLastMessage.CONSTRUCTOR, - UpdateChatPosition.CONSTRUCTOR, - UpdateChatAddedToList.CONSTRUCTOR, - UpdateChatRemovedFromList.CONSTRUCTOR, - UpdateChatReadInbox.CONSTRUCTOR, - UpdateChatReadOutbox.CONSTRUCTOR, - UpdateChatActionBar.CONSTRUCTOR, - UpdateChatBusinessBotManageBar.CONSTRUCTOR, - UpdateChatAvailableReactions.CONSTRUCTOR, - UpdateChatDraftMessage.CONSTRUCTOR, - UpdateChatEmojiStatus.CONSTRUCTOR, - UpdateChatMessageSender.CONSTRUCTOR, - UpdateChatMessageAutoDeleteTime.CONSTRUCTOR, - UpdateChatNotificationSettings.CONSTRUCTOR, - UpdateChatPendingJoinRequests.CONSTRUCTOR, - UpdateChatReplyMarkup.CONSTRUCTOR, - UpdateChatBackground.CONSTRUCTOR, - UpdateChatTheme.CONSTRUCTOR, - UpdateChatUnreadMentionCount.CONSTRUCTOR, - UpdateChatUnreadReactionCount.CONSTRUCTOR, - UpdateChatVideoChat.CONSTRUCTOR, - UpdateChatDefaultDisableNotification.CONSTRUCTOR, - UpdateChatHasProtectedContent.CONSTRUCTOR, - UpdateChatIsTranslatable.CONSTRUCTOR, - UpdateChatIsMarkedAsUnread.CONSTRUCTOR, - UpdateChatViewAsTopics.CONSTRUCTOR, - UpdateChatBlockList.CONSTRUCTOR, - UpdateChatHasScheduledMessages.CONSTRUCTOR, - UpdateChatFolders.CONSTRUCTOR, - UpdateChatOnlineMemberCount.CONSTRUCTOR, - UpdateSavedMessagesTopic.CONSTRUCTOR, - UpdateSavedMessagesTopicCount.CONSTRUCTOR, - UpdateDirectMessagesChatTopic.CONSTRUCTOR, - UpdateTopicMessageCount.CONSTRUCTOR, - UpdateQuickReplyShortcut.CONSTRUCTOR, - UpdateQuickReplyShortcutDeleted.CONSTRUCTOR, - UpdateQuickReplyShortcuts.CONSTRUCTOR, - UpdateQuickReplyShortcutMessages.CONSTRUCTOR, - UpdateForumTopicInfo.CONSTRUCTOR, - UpdateForumTopic.CONSTRUCTOR, - UpdateScopeNotificationSettings.CONSTRUCTOR, - UpdateReactionNotificationSettings.CONSTRUCTOR, - UpdateNotification.CONSTRUCTOR, - UpdateNotificationGroup.CONSTRUCTOR, - UpdateActiveNotifications.CONSTRUCTOR, - UpdateHavePendingNotifications.CONSTRUCTOR, - UpdateDeleteMessages.CONSTRUCTOR, - UpdateChatAction.CONSTRUCTOR, - UpdatePendingTextMessage.CONSTRUCTOR, - UpdateUserStatus.CONSTRUCTOR, - UpdateUser.CONSTRUCTOR, - UpdateBasicGroup.CONSTRUCTOR, - UpdateSupergroup.CONSTRUCTOR, - UpdateSecretChat.CONSTRUCTOR, - UpdateUserFullInfo.CONSTRUCTOR, - UpdateBasicGroupFullInfo.CONSTRUCTOR, - UpdateSupergroupFullInfo.CONSTRUCTOR, - UpdateServiceNotification.CONSTRUCTOR, - UpdateNewOauthRequest.CONSTRUCTOR, - UpdateFile.CONSTRUCTOR, - UpdateFileGenerationStart.CONSTRUCTOR, - UpdateFileGenerationStop.CONSTRUCTOR, - UpdateFileDownloads.CONSTRUCTOR, - UpdateFileAddedToDownloads.CONSTRUCTOR, - UpdateFileDownload.CONSTRUCTOR, - UpdateFileRemovedFromDownloads.CONSTRUCTOR, - UpdateApplicationVerificationRequired.CONSTRUCTOR, - UpdateApplicationRecaptchaVerificationRequired.CONSTRUCTOR, - UpdateCall.CONSTRUCTOR, - UpdateGroupCall.CONSTRUCTOR, - UpdateGroupCallParticipant.CONSTRUCTOR, - UpdateGroupCallParticipants.CONSTRUCTOR, - UpdateGroupCallVerificationState.CONSTRUCTOR, - UpdateNewGroupCallMessage.CONSTRUCTOR, - UpdateNewGroupCallPaidReaction.CONSTRUCTOR, - UpdateGroupCallMessageSendFailed.CONSTRUCTOR, - UpdateGroupCallMessagesDeleted.CONSTRUCTOR, - UpdateLiveStoryTopDonors.CONSTRUCTOR, - UpdateNewCallSignalingData.CONSTRUCTOR, - UpdateGiftAuctionState.CONSTRUCTOR, - UpdateActiveGiftAuctions.CONSTRUCTOR, - UpdateUserPrivacySettingRules.CONSTRUCTOR, - UpdateUnreadMessageCount.CONSTRUCTOR, - UpdateUnreadChatCount.CONSTRUCTOR, - UpdateStory.CONSTRUCTOR, - UpdateStoryDeleted.CONSTRUCTOR, - UpdateStoryPostSucceeded.CONSTRUCTOR, - UpdateStoryPostFailed.CONSTRUCTOR, - UpdateChatActiveStories.CONSTRUCTOR, - UpdateStoryListChatCount.CONSTRUCTOR, - UpdateStoryStealthMode.CONSTRUCTOR, - UpdateTrustedMiniAppBots.CONSTRUCTOR, - UpdateOption.CONSTRUCTOR, - UpdateStickerSet.CONSTRUCTOR, - UpdateInstalledStickerSets.CONSTRUCTOR, - UpdateTrendingStickerSets.CONSTRUCTOR, - UpdateRecentStickers.CONSTRUCTOR, - UpdateFavoriteStickers.CONSTRUCTOR, - UpdateSavedAnimations.CONSTRUCTOR, - UpdateSavedNotificationSounds.CONSTRUCTOR, - UpdateDefaultBackground.CONSTRUCTOR, - UpdateEmojiChatThemes.CONSTRUCTOR, - UpdateAccentColors.CONSTRUCTOR, - UpdateProfileAccentColors.CONSTRUCTOR, - UpdateLanguagePackStrings.CONSTRUCTOR, - UpdateConnectionState.CONSTRUCTOR, - UpdateFreezeState.CONSTRUCTOR, - UpdateAgeVerificationParameters.CONSTRUCTOR, - UpdateTermsOfService.CONSTRUCTOR, - UpdateUnconfirmedSession.CONSTRUCTOR, - UpdateAttachmentMenuBots.CONSTRUCTOR, - UpdateWebAppMessageSent.CONSTRUCTOR, - UpdateActiveEmojiReactions.CONSTRUCTOR, - UpdateAvailableMessageEffects.CONSTRUCTOR, - UpdateDefaultReactionType.CONSTRUCTOR, - UpdateDefaultPaidReactionType.CONSTRUCTOR, - UpdateSavedMessagesTags.CONSTRUCTOR, - UpdateActiveLiveLocationMessages.CONSTRUCTOR, - UpdateOwnedStarCount.CONSTRUCTOR, - UpdateOwnedTonCount.CONSTRUCTOR, - UpdateChatRevenueAmount.CONSTRUCTOR, - UpdateStarRevenueStatus.CONSTRUCTOR, - UpdateTonRevenueStatus.CONSTRUCTOR, - UpdateSpeechRecognitionTrial.CONSTRUCTOR, - UpdateGroupCallMessageLevels.CONSTRUCTOR, - UpdateDiceEmojis.CONSTRUCTOR, - UpdateStakeDiceState.CONSTRUCTOR, - UpdateAnimatedEmojiMessageClicked.CONSTRUCTOR, - UpdateAnimationSearchParameters.CONSTRUCTOR, - UpdateSuggestedActions.CONSTRUCTOR, - UpdateSpeedLimitNotification.CONSTRUCTOR, - UpdateContactCloseBirthdays.CONSTRUCTOR, - UpdateAutosaveSettings.CONSTRUCTOR, - UpdateBusinessConnection.CONSTRUCTOR, - UpdateNewBusinessMessage.CONSTRUCTOR, - UpdateBusinessMessageEdited.CONSTRUCTOR, - UpdateBusinessMessagesDeleted.CONSTRUCTOR, - UpdateNewInlineQuery.CONSTRUCTOR, - UpdateNewChosenInlineResult.CONSTRUCTOR, - UpdateNewCallbackQuery.CONSTRUCTOR, - UpdateNewInlineCallbackQuery.CONSTRUCTOR, - UpdateNewBusinessCallbackQuery.CONSTRUCTOR, - UpdateNewShippingQuery.CONSTRUCTOR, - UpdateNewPreCheckoutQuery.CONSTRUCTOR, - UpdateNewCustomEvent.CONSTRUCTOR, - UpdateNewCustomQuery.CONSTRUCTOR, - UpdatePoll.CONSTRUCTOR, - UpdatePollAnswer.CONSTRUCTOR, - UpdateChatMember.CONSTRUCTOR, - UpdateNewChatJoinRequest.CONSTRUCTOR, - UpdateChatBoost.CONSTRUCTOR, - UpdateMessageReaction.CONSTRUCTOR, - UpdateMessageReactions.CONSTRUCTOR, - UpdatePaidMediaPurchased.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public Update() { - } - } - - /** - * The user authorization state has changed. - */ - public static class UpdateAuthorizationState extends Update { - /** - * New authorization state. - */ - public AuthorizationState authorizationState; - - /** - * The user authorization state has changed. - */ - public UpdateAuthorizationState() { - } - - /** - * The user authorization state has changed. - * - * @param authorizationState New authorization state. - */ - public UpdateAuthorizationState(AuthorizationState authorizationState) { - this.authorizationState = authorizationState; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1622347490; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new message was received; can also be an outgoing message. - */ - public static class UpdateNewMessage extends Update { - /** - * The new message. - */ - public Message message; - - /** - * A new message was received; can also be an outgoing message. - */ - public UpdateNewMessage() { - } - - /** - * A new message was received; can also be an outgoing message. - * - * @param message The new message. - */ - public UpdateNewMessage(Message message) { - this.message = message; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -563105266; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A request to send a message has reached the Telegram server. This doesn't mean that the message will be sent successfully. This update is sent only if the option "use_quick_ack" is set to true. This update may be sent multiple times for the same message. - */ - public static class UpdateMessageSendAcknowledged extends Update { - /** - * The chat identifier of the sent message. - */ - public long chatId; - /** - * A temporary message identifier. - */ - public long messageId; - - /** - * A request to send a message has reached the Telegram server. This doesn't mean that the message will be sent successfully. This update is sent only if the option "use_quick_ack" is set to true. This update may be sent multiple times for the same message. - */ - public UpdateMessageSendAcknowledged() { - } - - /** - * A request to send a message has reached the Telegram server. This doesn't mean that the message will be sent successfully. This update is sent only if the option "use_quick_ack" is set to true. This update may be sent multiple times for the same message. - * - * @param chatId The chat identifier of the sent message. - * @param messageId A temporary message identifier. - */ - public UpdateMessageSendAcknowledged(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1302843961; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message has been successfully sent. - */ - public static class UpdateMessageSendSucceeded extends Update { - /** - * The sent message. Almost any field of the new message can be different from the corresponding field of the original message. For example, the field schedulingState may change, making the message scheduled, or non-scheduled. - */ - public Message message; - /** - * The previous temporary message identifier. - */ - public long oldMessageId; - - /** - * A message has been successfully sent. - */ - public UpdateMessageSendSucceeded() { - } - - /** - * A message has been successfully sent. - * - * @param message The sent message. Almost any field of the new message can be different from the corresponding field of the original message. For example, the field schedulingState may change, making the message scheduled, or non-scheduled. - * @param oldMessageId The previous temporary message identifier. - */ - public UpdateMessageSendSucceeded(Message message, long oldMessageId) { - this.message = message; - this.oldMessageId = oldMessageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1815715197; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message failed to send. Be aware that some messages being sent can be irrecoverably deleted, in which case updateDeleteMessages will be received instead of this update. - */ - public static class UpdateMessageSendFailed extends Update { - /** - * The failed to send message. - */ - public Message message; - /** - * The previous temporary message identifier. - */ - public long oldMessageId; - /** - * The cause of the message sending failure. - */ - public Error error; - - /** - * A message failed to send. Be aware that some messages being sent can be irrecoverably deleted, in which case updateDeleteMessages will be received instead of this update. - */ - public UpdateMessageSendFailed() { - } - - /** - * A message failed to send. Be aware that some messages being sent can be irrecoverably deleted, in which case updateDeleteMessages will be received instead of this update. - * - * @param message The failed to send message. - * @param oldMessageId The previous temporary message identifier. - * @param error The cause of the message sending failure. - */ - public UpdateMessageSendFailed(Message message, long oldMessageId, Error error) { - this.message = message; - this.oldMessageId = oldMessageId; - this.error = error; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -635701017; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message content has changed. - */ - public static class UpdateMessageContent extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - /** - * New message content. - */ - public MessageContent newContent; - - /** - * The message content has changed. - */ - public UpdateMessageContent() { - } - - /** - * The message content has changed. - * - * @param chatId Chat identifier. - * @param messageId Message identifier. - * @param newContent New message content. - */ - public UpdateMessageContent(long chatId, long messageId, MessageContent newContent) { - this.chatId = chatId; - this.messageId = messageId; - this.newContent = newContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 506903332; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message was edited. Changes in the message content will come in a separate updateMessageContent. - */ - public static class UpdateMessageEdited extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - /** - * Point in time (Unix timestamp) when the message was edited. - */ - public int editDate; - /** - * New message reply markup; may be null. - */ - @Nullable public ReplyMarkup replyMarkup; - - /** - * A message was edited. Changes in the message content will come in a separate updateMessageContent. - */ - public UpdateMessageEdited() { - } - - /** - * A message was edited. Changes in the message content will come in a separate updateMessageContent. - * - * @param chatId Chat identifier. - * @param messageId Message identifier. - * @param editDate Point in time (Unix timestamp) when the message was edited. - * @param replyMarkup New message reply markup; may be null. - */ - public UpdateMessageEdited(long chatId, long messageId, int editDate, ReplyMarkup replyMarkup) { - this.chatId = chatId; - this.messageId = messageId; - this.editDate = editDate; - this.replyMarkup = replyMarkup; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -559545626; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message pinned state was changed. - */ - public static class UpdateMessageIsPinned extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The message identifier. - */ - public long messageId; - /** - * True, if the message is pinned. - */ - public boolean isPinned; - - /** - * The message pinned state was changed. - */ - public UpdateMessageIsPinned() { - } - - /** - * The message pinned state was changed. - * - * @param chatId Chat identifier. - * @param messageId The message identifier. - * @param isPinned True, if the message is pinned. - */ - public UpdateMessageIsPinned(long chatId, long messageId, boolean isPinned) { - this.chatId = chatId; - this.messageId = messageId; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1102848829; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The information about interactions with a message has changed. - */ - public static class UpdateMessageInteractionInfo extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - /** - * New information about interactions with the message; may be null. - */ - @Nullable public MessageInteractionInfo interactionInfo; - - /** - * The information about interactions with a message has changed. - */ - public UpdateMessageInteractionInfo() { - } - - /** - * The information about interactions with a message has changed. - * - * @param chatId Chat identifier. - * @param messageId Message identifier. - * @param interactionInfo New information about interactions with the message; may be null. - */ - public UpdateMessageInteractionInfo(long chatId, long messageId, MessageInteractionInfo interactionInfo) { - this.chatId = chatId; - this.messageId = messageId; - this.interactionInfo = interactionInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1417659394; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message content was opened. Updates voice note messages to "listened", video note messages to "viewed" and starts the self-destruct timer. - */ - public static class UpdateMessageContentOpened extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - - /** - * The message content was opened. Updates voice note messages to "listened", video note messages to "viewed" and starts the self-destruct timer. - */ - public UpdateMessageContentOpened() { - } - - /** - * The message content was opened. Updates voice note messages to "listened", video note messages to "viewed" and starts the self-destruct timer. - * - * @param chatId Chat identifier. - * @param messageId Message identifier. - */ - public UpdateMessageContentOpened(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1520523131; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with an unread mention was read. - */ - public static class UpdateMessageMentionRead extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - /** - * The new number of unread mention messages left in the chat. - */ - public int unreadMentionCount; - - /** - * A message with an unread mention was read. - */ - public UpdateMessageMentionRead() { - } - - /** - * A message with an unread mention was read. - * - * @param chatId Chat identifier. - * @param messageId Message identifier. - * @param unreadMentionCount The new number of unread mention messages left in the chat. - */ - public UpdateMessageMentionRead(long chatId, long messageId, int unreadMentionCount) { - this.chatId = chatId; - this.messageId = messageId; - this.unreadMentionCount = unreadMentionCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -252228282; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of unread reactions added to a message was changed. - */ - public static class UpdateMessageUnreadReactions extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - /** - * The new list of unread reactions. - */ - public UnreadReaction[] unreadReactions; - /** - * The new number of messages with unread reactions left in the chat. - */ - public int unreadReactionCount; - - /** - * The list of unread reactions added to a message was changed. - */ - public UpdateMessageUnreadReactions() { - } - - /** - * The list of unread reactions added to a message was changed. - * - * @param chatId Chat identifier. - * @param messageId Message identifier. - * @param unreadReactions The new list of unread reactions. - * @param unreadReactionCount The new number of messages with unread reactions left in the chat. - */ - public UpdateMessageUnreadReactions(long chatId, long messageId, UnreadReaction[] unreadReactions, int unreadReactionCount) { - this.chatId = chatId; - this.messageId = messageId; - this.unreadReactions = unreadReactions; - this.unreadReactionCount = unreadReactionCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 942840008; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A fact-check added to a message was changed. - */ - public static class UpdateMessageFactCheck extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - /** - * The new fact-check. - */ - public FactCheck factCheck; - - /** - * A fact-check added to a message was changed. - */ - public UpdateMessageFactCheck() { - } - - /** - * A fact-check added to a message was changed. - * - * @param chatId Chat identifier. - * @param messageId Message identifier. - * @param factCheck The new fact-check. - */ - public UpdateMessageFactCheck(long chatId, long messageId, FactCheck factCheck) { - this.chatId = chatId; - this.messageId = messageId; - this.factCheck = factCheck; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1014561538; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Information about suggested post of a message was changed. - */ - public static class UpdateMessageSuggestedPostInfo extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - /** - * The new information about the suggested post. - */ - public SuggestedPostInfo suggestedPostInfo; - - /** - * Information about suggested post of a message was changed. - */ - public UpdateMessageSuggestedPostInfo() { - } - - /** - * Information about suggested post of a message was changed. - * - * @param chatId Chat identifier. - * @param messageId Message identifier. - * @param suggestedPostInfo The new information about the suggested post. - */ - public UpdateMessageSuggestedPostInfo(long chatId, long messageId, SuggestedPostInfo suggestedPostInfo) { - this.chatId = chatId; - this.messageId = messageId; - this.suggestedPostInfo = suggestedPostInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 194418186; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message with a live location was viewed. When the update is received, the application is expected to update the live location. - */ - public static class UpdateMessageLiveLocationViewed extends Update { - /** - * Identifier of the chat with the live location message. - */ - public long chatId; - /** - * Identifier of the message with live location. - */ - public long messageId; - - /** - * A message with a live location was viewed. When the update is received, the application is expected to update the live location. - */ - public UpdateMessageLiveLocationViewed() { - } - - /** - * A message with a live location was viewed. When the update is received, the application is expected to update the live location. - * - * @param chatId Identifier of the chat with the live location message. - * @param messageId Identifier of the message with live location. - */ - public UpdateMessageLiveLocationViewed(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1308260971; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An automatically scheduled message with video has been successfully sent after conversion. - */ - public static class UpdateVideoPublished extends Update { - /** - * Identifier of the chat with the message. - */ - public long chatId; - /** - * Identifier of the sent message. - */ - public long messageId; - - /** - * An automatically scheduled message with video has been successfully sent after conversion. - */ - public UpdateVideoPublished() { - } - - /** - * An automatically scheduled message with video has been successfully sent after conversion. - * - * @param chatId Identifier of the chat with the message. - * @param messageId Identifier of the sent message. - */ - public UpdateVideoPublished(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -352575406; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new chat has been loaded/created. This update is guaranteed to come before the chat identifier is returned to the application. The chat field changes will be reported through separate updates. - */ - public static class UpdateNewChat extends Update { - /** - * The chat. - */ - public Chat chat; - - /** - * A new chat has been loaded/created. This update is guaranteed to come before the chat identifier is returned to the application. The chat field changes will be reported through separate updates. - */ - public UpdateNewChat() { - } - - /** - * A new chat has been loaded/created. This update is guaranteed to come before the chat identifier is returned to the application. The chat field changes will be reported through separate updates. - * - * @param chat The chat. - */ - public UpdateNewChat(Chat chat) { - this.chat = chat; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2075757773; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The title of a chat was changed. - */ - public static class UpdateChatTitle extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The new chat title. - */ - public String title; - - /** - * The title of a chat was changed. - */ - public UpdateChatTitle() { - } - - /** - * The title of a chat was changed. - * - * @param chatId Chat identifier. - * @param title The new chat title. - */ - public UpdateChatTitle(long chatId, String title) { - this.chatId = chatId; - this.title = title; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -175405660; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat photo was changed. - */ - public static class UpdateChatPhoto extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The new chat photo; may be null. - */ - @Nullable public ChatPhotoInfo photo; - - /** - * A chat photo was changed. - */ - public UpdateChatPhoto() { - } - - /** - * A chat photo was changed. - * - * @param chatId Chat identifier. - * @param photo The new chat photo; may be null. - */ - public UpdateChatPhoto(long chatId, ChatPhotoInfo photo) { - this.chatId = chatId; - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -324713921; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Chat accent colors have changed. - */ - public static class UpdateChatAccentColors extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The new chat accent color identifier. - */ - public int accentColorId; - /** - * The new identifier of a custom emoji to be shown on the reply header and link preview background; 0 if none. - */ - public long backgroundCustomEmojiId; - /** - * Color scheme based on an upgraded gift to be used for the chat instead of accentColorId and backgroundCustomEmojiId; may be null if none. - */ - @Nullable public UpgradedGiftColors upgradedGiftColors; - /** - * The new chat profile accent color identifier; -1 if none. - */ - public int profileAccentColorId; - /** - * The new identifier of a custom emoji to be shown on the profile background; 0 if none. - */ - public long profileBackgroundCustomEmojiId; - - /** - * Chat accent colors have changed. - */ - public UpdateChatAccentColors() { - } - - /** - * Chat accent colors have changed. - * - * @param chatId Chat identifier. - * @param accentColorId The new chat accent color identifier. - * @param backgroundCustomEmojiId The new identifier of a custom emoji to be shown on the reply header and link preview background; 0 if none. - * @param upgradedGiftColors Color scheme based on an upgraded gift to be used for the chat instead of accentColorId and backgroundCustomEmojiId; may be null if none. - * @param profileAccentColorId The new chat profile accent color identifier; -1 if none. - * @param profileBackgroundCustomEmojiId The new identifier of a custom emoji to be shown on the profile background; 0 if none. - */ - public UpdateChatAccentColors(long chatId, int accentColorId, long backgroundCustomEmojiId, UpgradedGiftColors upgradedGiftColors, int profileAccentColorId, long profileBackgroundCustomEmojiId) { - this.chatId = chatId; - this.accentColorId = accentColorId; - this.backgroundCustomEmojiId = backgroundCustomEmojiId; - this.upgradedGiftColors = upgradedGiftColors; - this.profileAccentColorId = profileAccentColorId; - this.profileBackgroundCustomEmojiId = profileBackgroundCustomEmojiId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 874004198; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Chat permissions were changed. - */ - public static class UpdateChatPermissions extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The new chat permissions. - */ - public ChatPermissions permissions; - - /** - * Chat permissions were changed. - */ - public UpdateChatPermissions() { - } - - /** - * Chat permissions were changed. - * - * @param chatId Chat identifier. - * @param permissions The new chat permissions. - */ - public UpdateChatPermissions(long chatId, ChatPermissions permissions) { - this.chatId = chatId; - this.permissions = permissions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1622010003; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The last message of a chat was changed. - */ - public static class UpdateChatLastMessage extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The new last message in the chat; may be null if the last message became unknown. While the last message is unknown, new messages can be added to the chat without corresponding updateNewMessage update. - */ - @Nullable public Message lastMessage; - /** - * The new chat positions in the chat lists. - */ - public ChatPosition[] positions; - - /** - * The last message of a chat was changed. - */ - public UpdateChatLastMessage() { - } - - /** - * The last message of a chat was changed. - * - * @param chatId Chat identifier. - * @param lastMessage The new last message in the chat; may be null if the last message became unknown. While the last message is unknown, new messages can be added to the chat without corresponding updateNewMessage update. - * @param positions The new chat positions in the chat lists. - */ - public UpdateChatLastMessage(long chatId, Message lastMessage, ChatPosition[] positions) { - this.chatId = chatId; - this.lastMessage = lastMessage; - this.positions = positions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -923244537; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The position of a chat in a chat list has changed. An updateChatLastMessage or updateChatDraftMessage update might be sent instead of the update. - */ - public static class UpdateChatPosition extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * New chat position. If new order is 0, then the chat needs to be removed from the list. - */ - public ChatPosition position; - - /** - * The position of a chat in a chat list has changed. An updateChatLastMessage or updateChatDraftMessage update might be sent instead of the update. - */ - public UpdateChatPosition() { - } - - /** - * The position of a chat in a chat list has changed. An updateChatLastMessage or updateChatDraftMessage update might be sent instead of the update. - * - * @param chatId Chat identifier. - * @param position New chat position. If new order is 0, then the chat needs to be removed from the list. - */ - public UpdateChatPosition(long chatId, ChatPosition position) { - this.chatId = chatId; - this.position = position; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -8979849; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat was added to a chat list. - */ - public static class UpdateChatAddedToList extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The chat list to which the chat was added. - */ - public ChatList chatList; - - /** - * A chat was added to a chat list. - */ - public UpdateChatAddedToList() { - } - - /** - * A chat was added to a chat list. - * - * @param chatId Chat identifier. - * @param chatList The chat list to which the chat was added. - */ - public UpdateChatAddedToList(long chatId, ChatList chatList) { - this.chatId = chatId; - this.chatList = chatList; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1418722068; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat was removed from a chat list. - */ - public static class UpdateChatRemovedFromList extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The chat list from which the chat was removed. - */ - public ChatList chatList; - - /** - * A chat was removed from a chat list. - */ - public UpdateChatRemovedFromList() { - } - - /** - * A chat was removed from a chat list. - * - * @param chatId Chat identifier. - * @param chatList The chat list from which the chat was removed. - */ - public UpdateChatRemovedFromList(long chatId, ChatList chatList) { - this.chatId = chatId; - this.chatList = chatList; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1294647836; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Incoming messages were read or the number of unread messages has been changed. - */ - public static class UpdateChatReadInbox extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the last read incoming message. - */ - public long lastReadInboxMessageId; - /** - * The number of unread messages left in the chat. - */ - public int unreadCount; - - /** - * Incoming messages were read or the number of unread messages has been changed. - */ - public UpdateChatReadInbox() { - } - - /** - * Incoming messages were read or the number of unread messages has been changed. - * - * @param chatId Chat identifier. - * @param lastReadInboxMessageId Identifier of the last read incoming message. - * @param unreadCount The number of unread messages left in the chat. - */ - public UpdateChatReadInbox(long chatId, long lastReadInboxMessageId, int unreadCount) { - this.chatId = chatId; - this.lastReadInboxMessageId = lastReadInboxMessageId; - this.unreadCount = unreadCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -797952281; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Outgoing messages were read. - */ - public static class UpdateChatReadOutbox extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of last read outgoing message. - */ - public long lastReadOutboxMessageId; - - /** - * Outgoing messages were read. - */ - public UpdateChatReadOutbox() { - } - - /** - * Outgoing messages were read. - * - * @param chatId Chat identifier. - * @param lastReadOutboxMessageId Identifier of last read outgoing message. - */ - public UpdateChatReadOutbox(long chatId, long lastReadOutboxMessageId) { - this.chatId = chatId; - this.lastReadOutboxMessageId = lastReadOutboxMessageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 708334213; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat action bar was changed. - */ - public static class UpdateChatActionBar extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The new value of the action bar; may be null. - */ - @Nullable public ChatActionBar actionBar; - - /** - * The chat action bar was changed. - */ - public UpdateChatActionBar() { - } - - /** - * The chat action bar was changed. - * - * @param chatId Chat identifier. - * @param actionBar The new value of the action bar; may be null. - */ - public UpdateChatActionBar(long chatId, ChatActionBar actionBar) { - this.chatId = chatId; - this.actionBar = actionBar; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -643671870; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The bar for managing business bot was changed in a chat. - */ - public static class UpdateChatBusinessBotManageBar extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The new value of the business bot manage bar; may be null. - */ - @Nullable public BusinessBotManageBar businessBotManageBar; - - /** - * The bar for managing business bot was changed in a chat. - */ - public UpdateChatBusinessBotManageBar() { - } - - /** - * The bar for managing business bot was changed in a chat. - * - * @param chatId Chat identifier. - * @param businessBotManageBar The new value of the business bot manage bar; may be null. - */ - public UpdateChatBusinessBotManageBar(long chatId, BusinessBotManageBar businessBotManageBar) { - this.chatId = chatId; - this.businessBotManageBar = businessBotManageBar; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1104091145; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat available reactions were changed. - */ - public static class UpdateChatAvailableReactions extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The new reactions, available in the chat. - */ - public ChatAvailableReactions availableReactions; - - /** - * The chat available reactions were changed. - */ - public UpdateChatAvailableReactions() { - } - - /** - * The chat available reactions were changed. - * - * @param chatId Chat identifier. - * @param availableReactions The new reactions, available in the chat. - */ - public UpdateChatAvailableReactions(long chatId, ChatAvailableReactions availableReactions) { - this.chatId = chatId; - this.availableReactions = availableReactions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1967909895; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat draft has changed. Be aware that the update may come in the currently opened chat but with old content of the draft. If the user has changed the content of the draft, this update mustn't be applied. - */ - public static class UpdateChatDraftMessage extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The new draft message; may be null if none. - */ - @Nullable public DraftMessage draftMessage; - /** - * The new chat positions in the chat lists. - */ - public ChatPosition[] positions; - - /** - * A chat draft has changed. Be aware that the update may come in the currently opened chat but with old content of the draft. If the user has changed the content of the draft, this update mustn't be applied. - */ - public UpdateChatDraftMessage() { - } - - /** - * A chat draft has changed. Be aware that the update may come in the currently opened chat but with old content of the draft. If the user has changed the content of the draft, this update mustn't be applied. - * - * @param chatId Chat identifier. - * @param draftMessage The new draft message; may be null if none. - * @param positions The new chat positions in the chat lists. - */ - public UpdateChatDraftMessage(long chatId, DraftMessage draftMessage, ChatPosition[] positions) { - this.chatId = chatId; - this.draftMessage = draftMessage; - this.positions = positions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1455190380; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Chat emoji status has changed. - */ - public static class UpdateChatEmojiStatus extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The new chat emoji status; may be null. - */ - @Nullable public EmojiStatus emojiStatus; - - /** - * Chat emoji status has changed. - */ - public UpdateChatEmojiStatus() { - } - - /** - * Chat emoji status has changed. - * - * @param chatId Chat identifier. - * @param emojiStatus The new chat emoji status; may be null. - */ - public UpdateChatEmojiStatus(long chatId, EmojiStatus emojiStatus) { - this.chatId = chatId; - this.emojiStatus = emojiStatus; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2004444432; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message sender that is selected to send messages in a chat has changed. - */ - public static class UpdateChatMessageSender extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * New value of messageSenderId; may be null if the user can't change message sender. - */ - @Nullable public MessageSender messageSenderId; - - /** - * The message sender that is selected to send messages in a chat has changed. - */ - public UpdateChatMessageSender() { - } - - /** - * The message sender that is selected to send messages in a chat has changed. - * - * @param chatId Chat identifier. - * @param messageSenderId New value of messageSenderId; may be null if the user can't change message sender. - */ - public UpdateChatMessageSender(long chatId, MessageSender messageSenderId) { - this.chatId = chatId; - this.messageSenderId = messageSenderId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2003849793; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The message auto-delete or self-destruct timer setting for a chat was changed. - */ - public static class UpdateChatMessageAutoDeleteTime extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * New value of messageAutoDeleteTime. - */ - public int messageAutoDeleteTime; - - /** - * The message auto-delete or self-destruct timer setting for a chat was changed. - */ - public UpdateChatMessageAutoDeleteTime() { - } - - /** - * The message auto-delete or self-destruct timer setting for a chat was changed. - * - * @param chatId Chat identifier. - * @param messageAutoDeleteTime New value of messageAutoDeleteTime. - */ - public UpdateChatMessageAutoDeleteTime(long chatId, int messageAutoDeleteTime) { - this.chatId = chatId; - this.messageAutoDeleteTime = messageAutoDeleteTime; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1900174821; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Notification settings for a chat were changed. - */ - public static class UpdateChatNotificationSettings extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The new notification settings. - */ - public ChatNotificationSettings notificationSettings; - - /** - * Notification settings for a chat were changed. - */ - public UpdateChatNotificationSettings() { - } - - /** - * Notification settings for a chat were changed. - * - * @param chatId Chat identifier. - * @param notificationSettings The new notification settings. - */ - public UpdateChatNotificationSettings(long chatId, ChatNotificationSettings notificationSettings) { - this.chatId = chatId; - this.notificationSettings = notificationSettings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -803163050; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat pending join requests were changed. - */ - public static class UpdateChatPendingJoinRequests extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The new data about pending join requests; may be null. - */ - @Nullable public ChatJoinRequestsInfo pendingJoinRequests; - - /** - * The chat pending join requests were changed. - */ - public UpdateChatPendingJoinRequests() { - } - - /** - * The chat pending join requests were changed. - * - * @param chatId Chat identifier. - * @param pendingJoinRequests The new data about pending join requests; may be null. - */ - public UpdateChatPendingJoinRequests(long chatId, ChatJoinRequestsInfo pendingJoinRequests) { - this.chatId = chatId; - this.pendingJoinRequests = pendingJoinRequests; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 348578785; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat reply markup was changed. - */ - public static class UpdateChatReplyMarkup extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The message from which the reply markup must be used; may be null if there is no default reply markup in the chat. - */ - @Nullable public Message replyMarkupMessage; - - /** - * The chat reply markup was changed. - */ - public UpdateChatReplyMarkup() { - } - - /** - * The chat reply markup was changed. - * - * @param chatId Chat identifier. - * @param replyMarkupMessage The message from which the reply markup must be used; may be null if there is no default reply markup in the chat. - */ - public UpdateChatReplyMarkup(long chatId, Message replyMarkupMessage) { - this.chatId = chatId; - this.replyMarkupMessage = replyMarkupMessage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -714111887; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat background was changed. - */ - public static class UpdateChatBackground extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The new chat background; may be null if background was reset to default. - */ - @Nullable public ChatBackground background; - - /** - * The chat background was changed. - */ - public UpdateChatBackground() { - } - - /** - * The chat background was changed. - * - * @param chatId Chat identifier. - * @param background The new chat background; may be null if background was reset to default. - */ - public UpdateChatBackground(long chatId, ChatBackground background) { - this.chatId = chatId; - this.background = background; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -6473549; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat theme was changed. - */ - public static class UpdateChatTheme extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The new theme of the chat; may be null if theme was reset to default. - */ - @Nullable public ChatTheme theme; - - /** - * The chat theme was changed. - */ - public UpdateChatTheme() { - } - - /** - * The chat theme was changed. - * - * @param chatId Chat identifier. - * @param theme The new theme of the chat; may be null if theme was reset to default. - */ - public UpdateChatTheme(long chatId, ChatTheme theme) { - this.chatId = chatId; - this.theme = theme; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1625214435; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat unreadMentionCount has changed. - */ - public static class UpdateChatUnreadMentionCount extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The number of unread mention messages left in the chat. - */ - public int unreadMentionCount; - - /** - * The chat unreadMentionCount has changed. - */ - public UpdateChatUnreadMentionCount() { - } - - /** - * The chat unreadMentionCount has changed. - * - * @param chatId Chat identifier. - * @param unreadMentionCount The number of unread mention messages left in the chat. - */ - public UpdateChatUnreadMentionCount(long chatId, int unreadMentionCount) { - this.chatId = chatId; - this.unreadMentionCount = unreadMentionCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2131461348; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The chat unreadReactionCount has changed. - */ - public static class UpdateChatUnreadReactionCount extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The number of messages with unread reactions left in the chat. - */ - public int unreadReactionCount; - - /** - * The chat unreadReactionCount has changed. - */ - public UpdateChatUnreadReactionCount() { - } - - /** - * The chat unreadReactionCount has changed. - * - * @param chatId Chat identifier. - * @param unreadReactionCount The number of messages with unread reactions left in the chat. - */ - public UpdateChatUnreadReactionCount(long chatId, int unreadReactionCount) { - this.chatId = chatId; - this.unreadReactionCount = unreadReactionCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2124399395; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat video chat state has changed. - */ - public static class UpdateChatVideoChat extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * New value of videoChat. - */ - public VideoChat videoChat; - - /** - * A chat video chat state has changed. - */ - public UpdateChatVideoChat() { - } - - /** - * A chat video chat state has changed. - * - * @param chatId Chat identifier. - * @param videoChat New value of videoChat. - */ - public UpdateChatVideoChat(long chatId, VideoChat videoChat) { - this.chatId = chatId; - this.videoChat = videoChat; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 637226150; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The value of the default disableNotification parameter, used when a message is sent to the chat, was changed. - */ - public static class UpdateChatDefaultDisableNotification extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The new defaultDisableNotification value. - */ - public boolean defaultDisableNotification; - - /** - * The value of the default disableNotification parameter, used when a message is sent to the chat, was changed. - */ - public UpdateChatDefaultDisableNotification() { - } - - /** - * The value of the default disableNotification parameter, used when a message is sent to the chat, was changed. - * - * @param chatId Chat identifier. - * @param defaultDisableNotification The new defaultDisableNotification value. - */ - public UpdateChatDefaultDisableNotification(long chatId, boolean defaultDisableNotification) { - this.chatId = chatId; - this.defaultDisableNotification = defaultDisableNotification; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 464087707; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat content was allowed or restricted for saving. - */ - public static class UpdateChatHasProtectedContent extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * New value of hasProtectedContent. - */ - public boolean hasProtectedContent; - - /** - * A chat content was allowed or restricted for saving. - */ - public UpdateChatHasProtectedContent() { - } - - /** - * A chat content was allowed or restricted for saving. - * - * @param chatId Chat identifier. - * @param hasProtectedContent New value of hasProtectedContent. - */ - public UpdateChatHasProtectedContent(long chatId, boolean hasProtectedContent) { - this.chatId = chatId; - this.hasProtectedContent = hasProtectedContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1800406811; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Translation of chat messages was enabled or disabled. - */ - public static class UpdateChatIsTranslatable extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * New value of isTranslatable. - */ - public boolean isTranslatable; - - /** - * Translation of chat messages was enabled or disabled. - */ - public UpdateChatIsTranslatable() { - } - - /** - * Translation of chat messages was enabled or disabled. - * - * @param chatId Chat identifier. - * @param isTranslatable New value of isTranslatable. - */ - public UpdateChatIsTranslatable(long chatId, boolean isTranslatable) { - this.chatId = chatId; - this.isTranslatable = isTranslatable; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2063799831; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat was marked as unread or was read. - */ - public static class UpdateChatIsMarkedAsUnread extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * New value of isMarkedAsUnread. - */ - public boolean isMarkedAsUnread; - - /** - * A chat was marked as unread or was read. - */ - public UpdateChatIsMarkedAsUnread() { - } - - /** - * A chat was marked as unread or was read. - * - * @param chatId Chat identifier. - * @param isMarkedAsUnread New value of isMarkedAsUnread. - */ - public UpdateChatIsMarkedAsUnread(long chatId, boolean isMarkedAsUnread) { - this.chatId = chatId; - this.isMarkedAsUnread = isMarkedAsUnread; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1468347188; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat default appearance has changed. - */ - public static class UpdateChatViewAsTopics extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * New value of viewAsTopics. - */ - public boolean viewAsTopics; - - /** - * A chat default appearance has changed. - */ - public UpdateChatViewAsTopics() { - } - - /** - * A chat default appearance has changed. - * - * @param chatId Chat identifier. - * @param viewAsTopics New value of viewAsTopics. - */ - public UpdateChatViewAsTopics(long chatId, boolean viewAsTopics) { - this.chatId = chatId; - this.viewAsTopics = viewAsTopics; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1543444029; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat was blocked or unblocked. - */ - public static class UpdateChatBlockList extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Block list to which the chat is added; may be null if none. - */ - @Nullable public BlockList blockList; - - /** - * A chat was blocked or unblocked. - */ - public UpdateChatBlockList() { - } - - /** - * A chat was blocked or unblocked. - * - * @param chatId Chat identifier. - * @param blockList Block list to which the chat is added; may be null if none. - */ - public UpdateChatBlockList(long chatId, BlockList blockList) { - this.chatId = chatId; - this.blockList = blockList; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2027228018; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat's hasScheduledMessages field has changed. - */ - public static class UpdateChatHasScheduledMessages extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * New value of hasScheduledMessages. - */ - public boolean hasScheduledMessages; - - /** - * A chat's hasScheduledMessages field has changed. - */ - public UpdateChatHasScheduledMessages() { - } - - /** - * A chat's hasScheduledMessages field has changed. - * - * @param chatId Chat identifier. - * @param hasScheduledMessages New value of hasScheduledMessages. - */ - public UpdateChatHasScheduledMessages(long chatId, boolean hasScheduledMessages) { - this.chatId = chatId; - this.hasScheduledMessages = hasScheduledMessages; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2064958167; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of chat folders or a chat folder has changed. - */ - public static class UpdateChatFolders extends Update { - /** - * The new list of chat folders. - */ - public ChatFolderInfo[] chatFolders; - /** - * Position of the main chat list among chat folders, 0-based. - */ - public int mainChatListPosition; - /** - * True, if folder tags are enabled. - */ - public boolean areTagsEnabled; - - /** - * The list of chat folders or a chat folder has changed. - */ - public UpdateChatFolders() { - } - - /** - * The list of chat folders or a chat folder has changed. - * - * @param chatFolders The new list of chat folders. - * @param mainChatListPosition Position of the main chat list among chat folders, 0-based. - * @param areTagsEnabled True, if folder tags are enabled. - */ - public UpdateChatFolders(ChatFolderInfo[] chatFolders, int mainChatListPosition, boolean areTagsEnabled) { - this.chatFolders = chatFolders; - this.mainChatListPosition = mainChatListPosition; - this.areTagsEnabled = areTagsEnabled; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1998101395; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The number of online group members has changed. This update with non-zero number of online group members is sent only for currently opened chats. There is no guarantee that it is sent just after the number of online users has changed. - */ - public static class UpdateChatOnlineMemberCount extends Update { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * New number of online members in the chat, or 0 if unknown. - */ - public int onlineMemberCount; - - /** - * The number of online group members has changed. This update with non-zero number of online group members is sent only for currently opened chats. There is no guarantee that it is sent just after the number of online users has changed. - */ - public UpdateChatOnlineMemberCount() { - } - - /** - * The number of online group members has changed. This update with non-zero number of online group members is sent only for currently opened chats. There is no guarantee that it is sent just after the number of online users has changed. - * - * @param chatId Identifier of the chat. - * @param onlineMemberCount New number of online members in the chat, or 0 if unknown. - */ - public UpdateChatOnlineMemberCount(long chatId, int onlineMemberCount) { - this.chatId = chatId; - this.onlineMemberCount = onlineMemberCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 487369373; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Basic information about a Saved Messages topic has changed. This update is guaranteed to come before the topic identifier is returned to the application. - */ - public static class UpdateSavedMessagesTopic extends Update { - /** - * New data about the topic. - */ - public SavedMessagesTopic topic; - - /** - * Basic information about a Saved Messages topic has changed. This update is guaranteed to come before the topic identifier is returned to the application. - */ - public UpdateSavedMessagesTopic() { - } - - /** - * Basic information about a Saved Messages topic has changed. This update is guaranteed to come before the topic identifier is returned to the application. - * - * @param topic New data about the topic. - */ - public UpdateSavedMessagesTopic(SavedMessagesTopic topic) { - this.topic = topic; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1618855120; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Number of Saved Messages topics has changed. - */ - public static class UpdateSavedMessagesTopicCount extends Update { - /** - * Approximate total number of Saved Messages topics. - */ - public int topicCount; - - /** - * Number of Saved Messages topics has changed. - */ - public UpdateSavedMessagesTopicCount() { - } - - /** - * Number of Saved Messages topics has changed. - * - * @param topicCount Approximate total number of Saved Messages topics. - */ - public UpdateSavedMessagesTopicCount(int topicCount) { - this.topicCount = topicCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -70092335; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Basic information about a topic in a channel direct messages chat administered by the current user has changed. This update is guaranteed to come before the topic identifier is returned to the application. - */ - public static class UpdateDirectMessagesChatTopic extends Update { - /** - * New data about the topic. - */ - public DirectMessagesChatTopic topic; - - /** - * Basic information about a topic in a channel direct messages chat administered by the current user has changed. This update is guaranteed to come before the topic identifier is returned to the application. - */ - public UpdateDirectMessagesChatTopic() { - } - - /** - * Basic information about a topic in a channel direct messages chat administered by the current user has changed. This update is guaranteed to come before the topic identifier is returned to the application. - * - * @param topic New data about the topic. - */ - public UpdateDirectMessagesChatTopic(DirectMessagesChatTopic topic) { - this.topic = topic; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -683346963; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Number of messages in a topic has changed; for Saved Messages and channel direct messages chat topics only. - */ - public static class UpdateTopicMessageCount extends Update { - /** - * Identifier of the chat in topic of which the number of messages has changed. - */ - public long chatId; - /** - * Identifier of the topic. - */ - public MessageTopic topicId; - /** - * Approximate number of messages in the topic. - */ - public int messageCount; - - /** - * Number of messages in a topic has changed; for Saved Messages and channel direct messages chat topics only. - */ - public UpdateTopicMessageCount() { - } - - /** - * Number of messages in a topic has changed; for Saved Messages and channel direct messages chat topics only. - * - * @param chatId Identifier of the chat in topic of which the number of messages has changed. - * @param topicId Identifier of the topic. - * @param messageCount Approximate number of messages in the topic. - */ - public UpdateTopicMessageCount(long chatId, MessageTopic topicId, int messageCount) { - this.chatId = chatId; - this.topicId = topicId; - this.messageCount = messageCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1591525479; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Basic information about a quick reply shortcut has changed. This update is guaranteed to come before the quick shortcut name is returned to the application. - */ - public static class UpdateQuickReplyShortcut extends Update { - /** - * New data about the shortcut. - */ - public QuickReplyShortcut shortcut; - - /** - * Basic information about a quick reply shortcut has changed. This update is guaranteed to come before the quick shortcut name is returned to the application. - */ - public UpdateQuickReplyShortcut() { - } - - /** - * Basic information about a quick reply shortcut has changed. This update is guaranteed to come before the quick shortcut name is returned to the application. - * - * @param shortcut New data about the shortcut. - */ - public UpdateQuickReplyShortcut(QuickReplyShortcut shortcut) { - this.shortcut = shortcut; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -963430193; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A quick reply shortcut and all its messages were deleted. - */ - public static class UpdateQuickReplyShortcutDeleted extends Update { - /** - * The identifier of the deleted shortcut. - */ - public int shortcutId; - - /** - * A quick reply shortcut and all its messages were deleted. - */ - public UpdateQuickReplyShortcutDeleted() { - } - - /** - * A quick reply shortcut and all its messages were deleted. - * - * @param shortcutId The identifier of the deleted shortcut. - */ - public UpdateQuickReplyShortcutDeleted(int shortcutId) { - this.shortcutId = shortcutId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -390480838; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of quick reply shortcuts has changed. - */ - public static class UpdateQuickReplyShortcuts extends Update { - /** - * The new list of identifiers of quick reply shortcuts. - */ - public int[] shortcutIds; - - /** - * The list of quick reply shortcuts has changed. - */ - public UpdateQuickReplyShortcuts() { - } - - /** - * The list of quick reply shortcuts has changed. - * - * @param shortcutIds The new list of identifiers of quick reply shortcuts. - */ - public UpdateQuickReplyShortcuts(int[] shortcutIds) { - this.shortcutIds = shortcutIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1994849731; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of quick reply shortcut messages has changed. - */ - public static class UpdateQuickReplyShortcutMessages extends Update { - /** - * The identifier of the shortcut. - */ - public int shortcutId; - /** - * The new list of quick reply messages for the shortcut in order from the first to the last sent. - */ - public QuickReplyMessage[] messages; - - /** - * The list of quick reply shortcut messages has changed. - */ - public UpdateQuickReplyShortcutMessages() { - } - - /** - * The list of quick reply shortcut messages has changed. - * - * @param shortcutId The identifier of the shortcut. - * @param messages The new list of quick reply messages for the shortcut in order from the first to the last sent. - */ - public UpdateQuickReplyShortcutMessages(int shortcutId, QuickReplyMessage[] messages) { - this.shortcutId = shortcutId; - this.messages = messages; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1396685225; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Basic information about a topic in a forum chat was changed. - */ - public static class UpdateForumTopicInfo extends Update { - /** - * New information about the topic. - */ - public ForumTopicInfo info; - - /** - * Basic information about a topic in a forum chat was changed. - */ - public UpdateForumTopicInfo() { - } - - /** - * Basic information about a topic in a forum chat was changed. - * - * @param info New information about the topic. - */ - public UpdateForumTopicInfo(ForumTopicInfo info) { - this.info = info; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1420762696; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Information about a topic in a forum chat was changed. - */ - public static class UpdateForumTopic extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Forum topic identifier of the topic. - */ - public int forumTopicId; - /** - * True, if the topic is pinned in the topic list. - */ - public boolean isPinned; - /** - * Identifier of the last read incoming message. - */ - public long lastReadInboxMessageId; - /** - * Identifier of the last read outgoing message. - */ - public long lastReadOutboxMessageId; - /** - * Number of unread messages with a mention/reply in the topic. - */ - public int unreadMentionCount; - /** - * Number of messages with unread reactions in the topic. - */ - public int unreadReactionCount; - /** - * Notification settings for the topic. - */ - public ChatNotificationSettings notificationSettings; - /** - * A draft of a message in the topic; may be null if none. - */ - @Nullable public DraftMessage draftMessage; - - /** - * Information about a topic in a forum chat was changed. - */ - public UpdateForumTopic() { - } - - /** - * Information about a topic in a forum chat was changed. - * - * @param chatId Chat identifier. - * @param forumTopicId Forum topic identifier of the topic. - * @param isPinned True, if the topic is pinned in the topic list. - * @param lastReadInboxMessageId Identifier of the last read incoming message. - * @param lastReadOutboxMessageId Identifier of the last read outgoing message. - * @param unreadMentionCount Number of unread messages with a mention/reply in the topic. - * @param unreadReactionCount Number of messages with unread reactions in the topic. - * @param notificationSettings Notification settings for the topic. - * @param draftMessage A draft of a message in the topic; may be null if none. - */ - public UpdateForumTopic(long chatId, int forumTopicId, boolean isPinned, long lastReadInboxMessageId, long lastReadOutboxMessageId, int unreadMentionCount, int unreadReactionCount, ChatNotificationSettings notificationSettings, DraftMessage draftMessage) { - this.chatId = chatId; - this.forumTopicId = forumTopicId; - this.isPinned = isPinned; - this.lastReadInboxMessageId = lastReadInboxMessageId; - this.lastReadOutboxMessageId = lastReadOutboxMessageId; - this.unreadMentionCount = unreadMentionCount; - this.unreadReactionCount = unreadReactionCount; - this.notificationSettings = notificationSettings; - this.draftMessage = draftMessage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1803842990; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Notification settings for some type of chats were updated. - */ - public static class UpdateScopeNotificationSettings extends Update { - /** - * Types of chats for which notification settings were updated. - */ - public NotificationSettingsScope scope; - /** - * The new notification settings. - */ - public ScopeNotificationSettings notificationSettings; - - /** - * Notification settings for some type of chats were updated. - */ - public UpdateScopeNotificationSettings() { - } - - /** - * Notification settings for some type of chats were updated. - * - * @param scope Types of chats for which notification settings were updated. - * @param notificationSettings The new notification settings. - */ - public UpdateScopeNotificationSettings(NotificationSettingsScope scope, ScopeNotificationSettings notificationSettings) { - this.scope = scope; - this.notificationSettings = notificationSettings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1203975309; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Notification settings for reactions were updated. - */ - public static class UpdateReactionNotificationSettings extends Update { - /** - * The new notification settings. - */ - public ReactionNotificationSettings notificationSettings; - - /** - * Notification settings for reactions were updated. - */ - public UpdateReactionNotificationSettings() { - } - - /** - * Notification settings for reactions were updated. - * - * @param notificationSettings The new notification settings. - */ - public UpdateReactionNotificationSettings(ReactionNotificationSettings notificationSettings) { - this.notificationSettings = notificationSettings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -447932436; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A notification was changed. - */ - public static class UpdateNotification extends Update { - /** - * Unique notification group identifier. - */ - public int notificationGroupId; - /** - * Changed notification. - */ - public Notification notification; - - /** - * A notification was changed. - */ - public UpdateNotification() { - } - - /** - * A notification was changed. - * - * @param notificationGroupId Unique notification group identifier. - * @param notification Changed notification. - */ - public UpdateNotification(int notificationGroupId, Notification notification) { - this.notificationGroupId = notificationGroupId; - this.notification = notification; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1897496876; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A list of active notifications in a notification group has changed. - */ - public static class UpdateNotificationGroup extends Update { - /** - * Unique notification group identifier. - */ - public int notificationGroupId; - /** - * New type of the notification group. - */ - public NotificationGroupType type; - /** - * Identifier of a chat to which all notifications in the group belong. - */ - public long chatId; - /** - * Chat identifier, which notification settings must be applied to the added notifications. - */ - public long notificationSettingsChatId; - /** - * Identifier of the notification sound to be played; 0 if sound is disabled. - */ - public long notificationSoundId; - /** - * Total number of unread notifications in the group, can be bigger than number of active notifications. - */ - public int totalCount; - /** - * List of added group notifications, sorted by notification identifier. - */ - public Notification[] addedNotifications; - /** - * Identifiers of removed group notifications, sorted by notification identifier. - */ - public int[] removedNotificationIds; - - /** - * A list of active notifications in a notification group has changed. - */ - public UpdateNotificationGroup() { - } - - /** - * A list of active notifications in a notification group has changed. - * - * @param notificationGroupId Unique notification group identifier. - * @param type New type of the notification group. - * @param chatId Identifier of a chat to which all notifications in the group belong. - * @param notificationSettingsChatId Chat identifier, which notification settings must be applied to the added notifications. - * @param notificationSoundId Identifier of the notification sound to be played; 0 if sound is disabled. - * @param totalCount Total number of unread notifications in the group, can be bigger than number of active notifications. - * @param addedNotifications List of added group notifications, sorted by notification identifier. - * @param removedNotificationIds Identifiers of removed group notifications, sorted by notification identifier. - */ - public UpdateNotificationGroup(int notificationGroupId, NotificationGroupType type, long chatId, long notificationSettingsChatId, long notificationSoundId, int totalCount, Notification[] addedNotifications, int[] removedNotificationIds) { - this.notificationGroupId = notificationGroupId; - this.type = type; - this.chatId = chatId; - this.notificationSettingsChatId = notificationSettingsChatId; - this.notificationSoundId = notificationSoundId; - this.totalCount = totalCount; - this.addedNotifications = addedNotifications; - this.removedNotificationIds = removedNotificationIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1381081378; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains active notifications that were shown on previous application launches. This update is sent only if the message database is used. In that case it comes once before any updateNotification and updateNotificationGroup update. - */ - public static class UpdateActiveNotifications extends Update { - /** - * Lists of active notification groups. - */ - public NotificationGroup[] groups; - - /** - * Contains active notifications that were shown on previous application launches. This update is sent only if the message database is used. In that case it comes once before any updateNotification and updateNotificationGroup update. - */ - public UpdateActiveNotifications() { - } - - /** - * Contains active notifications that were shown on previous application launches. This update is sent only if the message database is used. In that case it comes once before any updateNotification and updateNotificationGroup update. - * - * @param groups Lists of active notification groups. - */ - public UpdateActiveNotifications(NotificationGroup[] groups) { - this.groups = groups; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1306672221; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes whether there are some pending notification updates. Can be used to prevent application from killing, while there are some pending notifications. - */ - public static class UpdateHavePendingNotifications extends Update { - /** - * True, if there are some delayed notification updates, which will be sent soon. - */ - public boolean haveDelayedNotifications; - /** - * True, if there can be some yet unreceived notifications, which are being fetched from the server. - */ - public boolean haveUnreceivedNotifications; - - /** - * Describes whether there are some pending notification updates. Can be used to prevent application from killing, while there are some pending notifications. - */ - public UpdateHavePendingNotifications() { - } - - /** - * Describes whether there are some pending notification updates. Can be used to prevent application from killing, while there are some pending notifications. - * - * @param haveDelayedNotifications True, if there are some delayed notification updates, which will be sent soon. - * @param haveUnreceivedNotifications True, if there can be some yet unreceived notifications, which are being fetched from the server. - */ - public UpdateHavePendingNotifications(boolean haveDelayedNotifications, boolean haveUnreceivedNotifications) { - this.haveDelayedNotifications = haveDelayedNotifications; - this.haveUnreceivedNotifications = haveUnreceivedNotifications; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 179233243; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Some messages were deleted. - */ - public static class UpdateDeleteMessages extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifiers of the deleted messages. - */ - public long[] messageIds; - /** - * True, if the messages are permanently deleted by a user (as opposed to just becoming inaccessible). - */ - public boolean isPermanent; - /** - * True, if the messages are deleted only from the cache and can possibly be retrieved again in the future. - */ - public boolean fromCache; - - /** - * Some messages were deleted. - */ - public UpdateDeleteMessages() { - } - - /** - * Some messages were deleted. - * - * @param chatId Chat identifier. - * @param messageIds Identifiers of the deleted messages. - * @param isPermanent True, if the messages are permanently deleted by a user (as opposed to just becoming inaccessible). - * @param fromCache True, if the messages are deleted only from the cache and can possibly be retrieved again in the future. - */ - public UpdateDeleteMessages(long chatId, long[] messageIds, boolean isPermanent, boolean fromCache) { - this.chatId = chatId; - this.messageIds = messageIds; - this.isPermanent = isPermanent; - this.fromCache = fromCache; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1669252686; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message sender activity in the chat has changed. - */ - public static class UpdateChatAction extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the specific topic in which the action was performed; may be null if none. - */ - @Nullable public MessageTopic topicId; - /** - * Identifier of a message sender performing the action. - */ - public MessageSender senderId; - /** - * The action. - */ - public ChatAction action; - - /** - * A message sender activity in the chat has changed. - */ - public UpdateChatAction() { - } - - /** - * A message sender activity in the chat has changed. - * - * @param chatId Chat identifier. - * @param topicId Identifier of the specific topic in which the action was performed; may be null if none. - * @param senderId Identifier of a message sender performing the action. - * @param action The action. - */ - public UpdateChatAction(long chatId, MessageTopic topicId, MessageSender senderId, ChatAction action) { - this.chatId = chatId; - this.topicId = topicId; - this.senderId = senderId; - this.action = action; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1140846612; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new pending text message was received in a chat with a bot. The message must be shown in the chat for at most getOption("pending_text_message_period") seconds, replace any other pending message with the same draftId, and be deleted whenever any incoming message from the bot in the message thread is received. - */ - public static class UpdatePendingTextMessage extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * The forum topic identifier in which the message will be sent; 0 if none. - */ - public int forumTopicId; - /** - * Unique identifier of the message draft within the message thread. - */ - public long draftId; - /** - * Text of the pending message. - */ - public FormattedText text; - - /** - * A new pending text message was received in a chat with a bot. The message must be shown in the chat for at most getOption("pending_text_message_period") seconds, replace any other pending message with the same draftId, and be deleted whenever any incoming message from the bot in the message thread is received. - */ - public UpdatePendingTextMessage() { - } - - /** - * A new pending text message was received in a chat with a bot. The message must be shown in the chat for at most getOption("pending_text_message_period") seconds, replace any other pending message with the same draftId, and be deleted whenever any incoming message from the bot in the message thread is received. - * - * @param chatId Chat identifier. - * @param forumTopicId The forum topic identifier in which the message will be sent; 0 if none. - * @param draftId Unique identifier of the message draft within the message thread. - * @param text Text of the pending message. - */ - public UpdatePendingTextMessage(long chatId, int forumTopicId, long draftId, FormattedText text) { - this.chatId = chatId; - this.forumTopicId = forumTopicId; - this.draftId = draftId; - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1076298155; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user went online or offline. - */ - public static class UpdateUserStatus extends Update { - /** - * User identifier. - */ - public long userId; - /** - * New status of the user. - */ - public UserStatus status; - - /** - * The user went online or offline. - */ - public UpdateUserStatus() { - } - - /** - * The user went online or offline. - * - * @param userId User identifier. - * @param status New status of the user. - */ - public UpdateUserStatus(long userId, UserStatus status) { - this.userId = userId; - this.status = status; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 958468625; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Some data of a user has changed. This update is guaranteed to come before the user identifier is returned to the application. - */ - public static class UpdateUser extends Update { - /** - * New data about the user. - */ - public User user; - - /** - * Some data of a user has changed. This update is guaranteed to come before the user identifier is returned to the application. - */ - public UpdateUser() { - } - - /** - * Some data of a user has changed. This update is guaranteed to come before the user identifier is returned to the application. - * - * @param user New data about the user. - */ - public UpdateUser(User user) { - this.user = user; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1183394041; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Some data of a basic group has changed. This update is guaranteed to come before the basic group identifier is returned to the application. - */ - public static class UpdateBasicGroup extends Update { - /** - * New data about the group. - */ - public BasicGroup basicGroup; - - /** - * Some data of a basic group has changed. This update is guaranteed to come before the basic group identifier is returned to the application. - */ - public UpdateBasicGroup() { - } - - /** - * Some data of a basic group has changed. This update is guaranteed to come before the basic group identifier is returned to the application. - * - * @param basicGroup New data about the group. - */ - public UpdateBasicGroup(BasicGroup basicGroup) { - this.basicGroup = basicGroup; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1003239581; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Some data of a supergroup or a channel has changed. This update is guaranteed to come before the supergroup identifier is returned to the application. - */ - public static class UpdateSupergroup extends Update { - /** - * New data about the supergroup. - */ - public Supergroup supergroup; - - /** - * Some data of a supergroup or a channel has changed. This update is guaranteed to come before the supergroup identifier is returned to the application. - */ - public UpdateSupergroup() { - } - - /** - * Some data of a supergroup or a channel has changed. This update is guaranteed to come before the supergroup identifier is returned to the application. - * - * @param supergroup New data about the supergroup. - */ - public UpdateSupergroup(Supergroup supergroup) { - this.supergroup = supergroup; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -76782300; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Some data of a secret chat has changed. This update is guaranteed to come before the secret chat identifier is returned to the application. - */ - public static class UpdateSecretChat extends Update { - /** - * New data about the secret chat. - */ - public SecretChat secretChat; - - /** - * Some data of a secret chat has changed. This update is guaranteed to come before the secret chat identifier is returned to the application. - */ - public UpdateSecretChat() { - } - - /** - * Some data of a secret chat has changed. This update is guaranteed to come before the secret chat identifier is returned to the application. - * - * @param secretChat New data about the secret chat. - */ - public UpdateSecretChat(SecretChat secretChat) { - this.secretChat = secretChat; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1666903253; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Some data in userFullInfo has been changed. - */ - public static class UpdateUserFullInfo extends Update { - /** - * User identifier. - */ - public long userId; - /** - * New full information about the user. - */ - public UserFullInfo userFullInfo; - - /** - * Some data in userFullInfo has been changed. - */ - public UpdateUserFullInfo() { - } - - /** - * Some data in userFullInfo has been changed. - * - * @param userId User identifier. - * @param userFullInfo New full information about the user. - */ - public UpdateUserFullInfo(long userId, UserFullInfo userFullInfo) { - this.userId = userId; - this.userFullInfo = userFullInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -51197161; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Some data in basicGroupFullInfo has been changed. - */ - public static class UpdateBasicGroupFullInfo extends Update { - /** - * Identifier of a basic group. - */ - public long basicGroupId; - /** - * New full information about the group. - */ - public BasicGroupFullInfo basicGroupFullInfo; - - /** - * Some data in basicGroupFullInfo has been changed. - */ - public UpdateBasicGroupFullInfo() { - } - - /** - * Some data in basicGroupFullInfo has been changed. - * - * @param basicGroupId Identifier of a basic group. - * @param basicGroupFullInfo New full information about the group. - */ - public UpdateBasicGroupFullInfo(long basicGroupId, BasicGroupFullInfo basicGroupFullInfo) { - this.basicGroupId = basicGroupId; - this.basicGroupFullInfo = basicGroupFullInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1391881151; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Some data in supergroupFullInfo has been changed. - */ - public static class UpdateSupergroupFullInfo extends Update { - /** - * Identifier of the supergroup or channel. - */ - public long supergroupId; - /** - * New full information about the supergroup. - */ - public SupergroupFullInfo supergroupFullInfo; - - /** - * Some data in supergroupFullInfo has been changed. - */ - public UpdateSupergroupFullInfo() { - } - - /** - * Some data in supergroupFullInfo has been changed. - * - * @param supergroupId Identifier of the supergroup or channel. - * @param supergroupFullInfo New full information about the supergroup. - */ - public UpdateSupergroupFullInfo(long supergroupId, SupergroupFullInfo supergroupFullInfo) { - this.supergroupId = supergroupId; - this.supergroupFullInfo = supergroupFullInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 435539214; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A service notification from the server was received. Upon receiving this the application must show a popup with the content of the notification. - */ - public static class UpdateServiceNotification extends Update { - /** - * Notification type. If type begins with "AUTH_KEY_DROP_", then two buttons "Cancel" and "Log out" must be shown under notification; if user presses the second, all local data must be destroyed using Destroy method. - */ - public String type; - /** - * Notification content. - */ - public MessageContent content; - - /** - * A service notification from the server was received. Upon receiving this the application must show a popup with the content of the notification. - */ - public UpdateServiceNotification() { - } - - /** - * A service notification from the server was received. Upon receiving this the application must show a popup with the content of the notification. - * - * @param type Notification type. If type begins with "AUTH_KEY_DROP_", then two buttons "Cancel" and "Log out" must be shown under notification; if user presses the second, all local data must be destroyed using Destroy method. - * @param content Notification content. - */ - public UpdateServiceNotification(String type, MessageContent content) { - this.type = type; - this.content = content; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1318622637; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An OAuth authorization request was received. - */ - public static class UpdateNewOauthRequest extends Update { - /** - * A domain of the URL where the user authorizes. - */ - public String domain; - /** - * Human-readable description of a country and a region from which the authorization is performed, based on the IP address. - */ - public String location; - /** - * The URL to pass to getOauthLinkInfo; the link is valid for 60 seconds. - */ - public String url; - - /** - * An OAuth authorization request was received. - */ - public UpdateNewOauthRequest() { - } - - /** - * An OAuth authorization request was received. - * - * @param domain A domain of the URL where the user authorizes. - * @param location Human-readable description of a country and a region from which the authorization is performed, based on the IP address. - * @param url The URL to pass to getOauthLinkInfo; the link is valid for 60 seconds. - */ - public UpdateNewOauthRequest(String domain, String location, String url) { - this.domain = domain; - this.location = location; - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 248383005; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Information about a file was updated. - */ - public static class UpdateFile extends Update { - /** - * New data about the file. - */ - public File file; - - /** - * Information about a file was updated. - */ - public UpdateFile() { - } - - /** - * Information about a file was updated. - * - * @param file New data about the file. - */ - public UpdateFile(File file) { - this.file = file; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 114132831; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The file generation process needs to be started by the application. Use setFileGenerationProgress and finishFileGeneration to generate the file. - */ - public static class UpdateFileGenerationStart extends Update { - /** - * Unique identifier for the generation process. - */ - public long generationId; - /** - * The original path specified by the application in inputFileGenerated. - */ - public String originalPath; - /** - * The path to a file that must be created and where the new file must be generated by the application. If the application has no access to the path, it can use writeGeneratedFilePart to generate the file. - */ - public String destinationPath; - /** - * If the conversion is "#url#" than originalPath contains an HTTP/HTTPS URL of a file that must be downloaded by the application. Otherwise, this is the conversion specified by the application in inputFileGenerated. - */ - public String conversion; - - /** - * The file generation process needs to be started by the application. Use setFileGenerationProgress and finishFileGeneration to generate the file. - */ - public UpdateFileGenerationStart() { - } - - /** - * The file generation process needs to be started by the application. Use setFileGenerationProgress and finishFileGeneration to generate the file. - * - * @param generationId Unique identifier for the generation process. - * @param originalPath The original path specified by the application in inputFileGenerated. - * @param destinationPath The path to a file that must be created and where the new file must be generated by the application. If the application has no access to the path, it can use writeGeneratedFilePart to generate the file. - * @param conversion If the conversion is "#url#" than originalPath contains an HTTP/HTTPS URL of a file that must be downloaded by the application. Otherwise, this is the conversion specified by the application in inputFileGenerated. - */ - public UpdateFileGenerationStart(long generationId, String originalPath, String destinationPath, String conversion) { - this.generationId = generationId; - this.originalPath = originalPath; - this.destinationPath = destinationPath; - this.conversion = conversion; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 216817388; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * File generation is no longer needed. - */ - public static class UpdateFileGenerationStop extends Update { - /** - * Unique identifier for the generation process. - */ - public long generationId; - - /** - * File generation is no longer needed. - */ - public UpdateFileGenerationStop() { - } - - /** - * File generation is no longer needed. - * - * @param generationId Unique identifier for the generation process. - */ - public UpdateFileGenerationStop(long generationId) { - this.generationId = generationId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1894449685; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The state of the file download list has changed. - */ - public static class UpdateFileDownloads extends Update { - /** - * Total size of files in the file download list, in bytes. - */ - public long totalSize; - /** - * Total number of files in the file download list. - */ - public int totalCount; - /** - * Total downloaded size of files in the file download list, in bytes. - */ - public long downloadedSize; - - /** - * The state of the file download list has changed. - */ - public UpdateFileDownloads() { - } - - /** - * The state of the file download list has changed. - * - * @param totalSize Total size of files in the file download list, in bytes. - * @param totalCount Total number of files in the file download list. - * @param downloadedSize Total downloaded size of files in the file download list, in bytes. - */ - public UpdateFileDownloads(long totalSize, int totalCount, long downloadedSize) { - this.totalSize = totalSize; - this.totalCount = totalCount; - this.downloadedSize = downloadedSize; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -389213497; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A file was added to the file download list. This update is sent only after file download list is loaded for the first time. - */ - public static class UpdateFileAddedToDownloads extends Update { - /** - * The added file download. - */ - public FileDownload fileDownload; - /** - * New number of being downloaded and recently downloaded files found. - */ - public DownloadedFileCounts counts; - - /** - * A file was added to the file download list. This update is sent only after file download list is loaded for the first time. - */ - public UpdateFileAddedToDownloads() { - } - - /** - * A file was added to the file download list. This update is sent only after file download list is loaded for the first time. - * - * @param fileDownload The added file download. - * @param counts New number of being downloaded and recently downloaded files found. - */ - public UpdateFileAddedToDownloads(FileDownload fileDownload, DownloadedFileCounts counts) { - this.fileDownload = fileDownload; - this.counts = counts; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1609929242; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A file download was changed. This update is sent only after file download list is loaded for the first time. - */ - public static class UpdateFileDownload extends Update { - /** - * File identifier. - */ - public int fileId; - /** - * Point in time (Unix timestamp) when the file downloading was completed; 0 if the file downloading isn't completed. - */ - public int completeDate; - /** - * True, if downloading of the file is paused. - */ - public boolean isPaused; - /** - * New number of being downloaded and recently downloaded files found. - */ - public DownloadedFileCounts counts; - - /** - * A file download was changed. This update is sent only after file download list is loaded for the first time. - */ - public UpdateFileDownload() { - } - - /** - * A file download was changed. This update is sent only after file download list is loaded for the first time. - * - * @param fileId File identifier. - * @param completeDate Point in time (Unix timestamp) when the file downloading was completed; 0 if the file downloading isn't completed. - * @param isPaused True, if downloading of the file is paused. - * @param counts New number of being downloaded and recently downloaded files found. - */ - public UpdateFileDownload(int fileId, int completeDate, boolean isPaused, DownloadedFileCounts counts) { - this.fileId = fileId; - this.completeDate = completeDate; - this.isPaused = isPaused; - this.counts = counts; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 875529162; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A file was removed from the file download list. This update is sent only after file download list is loaded for the first time. - */ - public static class UpdateFileRemovedFromDownloads extends Update { - /** - * File identifier. - */ - public int fileId; - /** - * New number of being downloaded and recently downloaded files found. - */ - public DownloadedFileCounts counts; - - /** - * A file was removed from the file download list. This update is sent only after file download list is loaded for the first time. - */ - public UpdateFileRemovedFromDownloads() { - } - - /** - * A file was removed from the file download list. This update is sent only after file download list is loaded for the first time. - * - * @param fileId File identifier. - * @param counts New number of being downloaded and recently downloaded files found. - */ - public UpdateFileRemovedFromDownloads(int fileId, DownloadedFileCounts counts) { - this.fileId = fileId; - this.counts = counts; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1853625576; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A request can't be completed unless application verification is performed; for official mobile applications only. The method setApplicationVerificationToken must be called once the verification is completed or failed. - */ - public static class UpdateApplicationVerificationRequired extends Update { - /** - * Unique identifier for the verification process. - */ - public long verificationId; - /** - * Unique base64url-encoded nonce for the classic Play Integrity verification (https://developer.android.com/google/play/integrity/classic) for Android, or a unique string to compare with verifyNonce field from a push notification for iOS. - */ - public String nonce; - /** - * Cloud project number to pass to the Play Integrity API on Android. - */ - public long cloudProjectNumber; - - /** - * A request can't be completed unless application verification is performed; for official mobile applications only. The method setApplicationVerificationToken must be called once the verification is completed or failed. - */ - public UpdateApplicationVerificationRequired() { - } - - /** - * A request can't be completed unless application verification is performed; for official mobile applications only. The method setApplicationVerificationToken must be called once the verification is completed or failed. - * - * @param verificationId Unique identifier for the verification process. - * @param nonce Unique base64url-encoded nonce for the classic Play Integrity verification (https://developer.android.com/google/play/integrity/classic) for Android, or a unique string to compare with verifyNonce field from a push notification for iOS. - * @param cloudProjectNumber Cloud project number to pass to the Play Integrity API on Android. - */ - public UpdateApplicationVerificationRequired(long verificationId, String nonce, long cloudProjectNumber) { - this.verificationId = verificationId; - this.nonce = nonce; - this.cloudProjectNumber = cloudProjectNumber; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -979607081; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A request can't be completed unless reCAPTCHA verification is performed; for official mobile applications only. The method setApplicationVerificationToken must be called once the verification is completed or failed. - */ - public static class UpdateApplicationRecaptchaVerificationRequired extends Update { - /** - * Unique identifier for the verification process. - */ - public long verificationId; - /** - * The action for the check. - */ - public String action; - /** - * Identifier of the reCAPTCHA key. - */ - public String recaptchaKeyId; - - /** - * A request can't be completed unless reCAPTCHA verification is performed; for official mobile applications only. The method setApplicationVerificationToken must be called once the verification is completed or failed. - */ - public UpdateApplicationRecaptchaVerificationRequired() { - } - - /** - * A request can't be completed unless reCAPTCHA verification is performed; for official mobile applications only. The method setApplicationVerificationToken must be called once the verification is completed or failed. - * - * @param verificationId Unique identifier for the verification process. - * @param action The action for the check. - * @param recaptchaKeyId Identifier of the reCAPTCHA key. - */ - public UpdateApplicationRecaptchaVerificationRequired(long verificationId, String action, String recaptchaKeyId) { - this.verificationId = verificationId; - this.action = action; - this.recaptchaKeyId = recaptchaKeyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1796351554; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * New call was created or information about a call was updated. - */ - public static class UpdateCall extends Update { - /** - * New data about a call. - */ - public Call call; - - /** - * New call was created or information about a call was updated. - */ - public UpdateCall() { - } - - /** - * New call was created or information about a call was updated. - * - * @param call New data about a call. - */ - public UpdateCall(Call call) { - this.call = call; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1337184477; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Information about a group call was updated. - */ - public static class UpdateGroupCall extends Update { - /** - * New data about the group call. - */ - public GroupCall groupCall; - - /** - * Information about a group call was updated. - */ - public UpdateGroupCall() { - } - - /** - * Information about a group call was updated. - * - * @param groupCall New data about the group call. - */ - public UpdateGroupCall(GroupCall groupCall) { - this.groupCall = groupCall; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 808603136; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Information about a group call participant was changed. The updates are sent only after the group call is received through getGroupCall and only if the call is joined or being joined. - */ - public static class UpdateGroupCallParticipant extends Update { - /** - * Identifier of the group call. - */ - public int groupCallId; - /** - * New data about the participant. - */ - public GroupCallParticipant participant; - - /** - * Information about a group call participant was changed. The updates are sent only after the group call is received through getGroupCall and only if the call is joined or being joined. - */ - public UpdateGroupCallParticipant() { - } - - /** - * Information about a group call participant was changed. The updates are sent only after the group call is received through getGroupCall and only if the call is joined or being joined. - * - * @param groupCallId Identifier of the group call. - * @param participant New data about the participant. - */ - public UpdateGroupCallParticipant(int groupCallId, GroupCallParticipant participant) { - this.groupCallId = groupCallId; - this.participant = participant; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -803128071; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of group call participants that can send and receive encrypted call data has changed; for group calls not bound to a chat only. - */ - public static class UpdateGroupCallParticipants extends Update { - /** - * Identifier of the group call. - */ - public int groupCallId; - /** - * New list of group call participant user identifiers. The identifiers may be invalid or the corresponding users may be unknown. The participants must be shown in the list of group call participants even if there is no information about them. - */ - public long[] participantUserIds; - - /** - * The list of group call participants that can send and receive encrypted call data has changed; for group calls not bound to a chat only. - */ - public UpdateGroupCallParticipants() { - } - - /** - * The list of group call participants that can send and receive encrypted call data has changed; for group calls not bound to a chat only. - * - * @param groupCallId Identifier of the group call. - * @param participantUserIds New list of group call participant user identifiers. The identifiers may be invalid or the corresponding users may be unknown. The participants must be shown in the list of group call participants even if there is no information about them. - */ - public UpdateGroupCallParticipants(int groupCallId, long[] participantUserIds) { - this.groupCallId = groupCallId; - this.participantUserIds = participantUserIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1874006374; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The verification state of an encrypted group call has changed; for group calls not bound to a chat only. - */ - public static class UpdateGroupCallVerificationState extends Update { - /** - * Identifier of the group call. - */ - public int groupCallId; - /** - * The call state generation to which the emoji corresponds. If generation is different for two users, then their emoji may be also different. - */ - public int generation; - /** - * Group call state fingerprint represented as 4 emoji; may be empty if the state isn't verified yet. - */ - public String[] emojis; - - /** - * The verification state of an encrypted group call has changed; for group calls not bound to a chat only. - */ - public UpdateGroupCallVerificationState() { - } - - /** - * The verification state of an encrypted group call has changed; for group calls not bound to a chat only. - * - * @param groupCallId Identifier of the group call. - * @param generation The call state generation to which the emoji corresponds. If generation is different for two users, then their emoji may be also different. - * @param emojis Group call state fingerprint represented as 4 emoji; may be empty if the state isn't verified yet. - */ - public UpdateGroupCallVerificationState(int groupCallId, int generation, String[] emojis) { - this.groupCallId = groupCallId; - this.generation = generation; - this.emojis = emojis; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 682965060; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new message was received in a group call. - */ - public static class UpdateNewGroupCallMessage extends Update { - /** - * Identifier of the group call. - */ - public int groupCallId; - /** - * The message. - */ - public GroupCallMessage message; - - /** - * A new message was received in a group call. - */ - public UpdateNewGroupCallMessage() { - } - - /** - * A new message was received in a group call. - * - * @param groupCallId Identifier of the group call. - * @param message The message. - */ - public UpdateNewGroupCallMessage(int groupCallId, GroupCallMessage message) { - this.groupCallId = groupCallId; - this.message = message; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2072291743; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new paid reaction was received in a live story group call. - */ - public static class UpdateNewGroupCallPaidReaction extends Update { - /** - * Identifier of the group call. - */ - public int groupCallId; - /** - * Identifier of the sender of the reaction. - */ - public MessageSender senderId; - /** - * The number of Telegram Stars that were paid to send the reaction. - */ - public long starCount; - - /** - * A new paid reaction was received in a live story group call. - */ - public UpdateNewGroupCallPaidReaction() { - } - - /** - * A new paid reaction was received in a live story group call. - * - * @param groupCallId Identifier of the group call. - * @param senderId Identifier of the sender of the reaction. - * @param starCount The number of Telegram Stars that were paid to send the reaction. - */ - public UpdateNewGroupCallPaidReaction(int groupCallId, MessageSender senderId, long starCount) { - this.groupCallId = groupCallId; - this.senderId = senderId; - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -189233012; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A group call message failed to send. - */ - public static class UpdateGroupCallMessageSendFailed extends Update { - /** - * Identifier of the group call. - */ - public int groupCallId; - /** - * Message identifier. - */ - public int messageId; - /** - * The cause of the message sending failure. - */ - public Error error; - - /** - * A group call message failed to send. - */ - public UpdateGroupCallMessageSendFailed() { - } - - /** - * A group call message failed to send. - * - * @param groupCallId Identifier of the group call. - * @param messageId Message identifier. - * @param error The cause of the message sending failure. - */ - public UpdateGroupCallMessageSendFailed(int groupCallId, int messageId, Error error) { - this.groupCallId = groupCallId; - this.messageId = messageId; - this.error = error; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 472432559; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Some group call messages were deleted. - */ - public static class UpdateGroupCallMessagesDeleted extends Update { - /** - * Identifier of the group call. - */ - public int groupCallId; - /** - * Identifiers of the deleted messages. - */ - public int[] messageIds; - - /** - * Some group call messages were deleted. - */ - public UpdateGroupCallMessagesDeleted() { - } - - /** - * Some group call messages were deleted. - * - * @param groupCallId Identifier of the group call. - * @param messageIds Identifiers of the deleted messages. - */ - public UpdateGroupCallMessagesDeleted(int groupCallId, int[] messageIds) { - this.groupCallId = groupCallId; - this.messageIds = messageIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1275517315; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of top donors in live story group call has changed. - */ - public static class UpdateLiveStoryTopDonors extends Update { - /** - * Identifier of the group call. - */ - public int groupCallId; - /** - * New list of live story donors. - */ - public LiveStoryDonors donors; - - /** - * The list of top donors in live story group call has changed. - */ - public UpdateLiveStoryTopDonors() { - } - - /** - * The list of top donors in live story group call has changed. - * - * @param groupCallId Identifier of the group call. - * @param donors New list of live story donors. - */ - public UpdateLiveStoryTopDonors(int groupCallId, LiveStoryDonors donors) { - this.groupCallId = groupCallId; - this.donors = donors; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -715693884; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * New call signaling data arrived. - */ - public static class UpdateNewCallSignalingData extends Update { - /** - * The call identifier. - */ - public int callId; - /** - * The data. - */ - public byte[] data; - - /** - * New call signaling data arrived. - */ - public UpdateNewCallSignalingData() { - } - - /** - * New call signaling data arrived. - * - * @param callId The call identifier. - * @param data The data. - */ - public UpdateNewCallSignalingData(int callId, byte[] data) { - this.callId = callId; - this.data = data; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 583634317; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * State of a gift auction was updated. - */ - public static class UpdateGiftAuctionState extends Update { - /** - * New state of the auction. - */ - public GiftAuctionState state; - - /** - * State of a gift auction was updated. - */ - public UpdateGiftAuctionState() { - } - - /** - * State of a gift auction was updated. - * - * @param state New state of the auction. - */ - public UpdateGiftAuctionState(GiftAuctionState state) { - this.state = state; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1864542270; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of auctions in which participate the current user has changed. - */ - public static class UpdateActiveGiftAuctions extends Update { - /** - * New states of the auctions. - */ - public GiftAuctionState[] states; - - /** - * The list of auctions in which participate the current user has changed. - */ - public UpdateActiveGiftAuctions() { - } - - /** - * The list of auctions in which participate the current user has changed. - * - * @param states New states of the auctions. - */ - public UpdateActiveGiftAuctions(GiftAuctionState[] states) { - this.states = states; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -521505204; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Some privacy setting rules have been changed. - */ - public static class UpdateUserPrivacySettingRules extends Update { - /** - * The privacy setting. - */ - public UserPrivacySetting setting; - /** - * New privacy rules. - */ - public UserPrivacySettingRules rules; - - /** - * Some privacy setting rules have been changed. - */ - public UpdateUserPrivacySettingRules() { - } - - /** - * Some privacy setting rules have been changed. - * - * @param setting The privacy setting. - * @param rules New privacy rules. - */ - public UpdateUserPrivacySettingRules(UserPrivacySetting setting, UserPrivacySettingRules rules) { - this.setting = setting; - this.rules = rules; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -912960778; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Number of unread messages in a chat list has changed. This update is sent only if the message database is used. - */ - public static class UpdateUnreadMessageCount extends Update { - /** - * The chat list with changed number of unread messages. - */ - public ChatList chatList; - /** - * Total number of unread messages. - */ - public int unreadCount; - /** - * Total number of unread messages in unmuted chats. - */ - public int unreadUnmutedCount; - - /** - * Number of unread messages in a chat list has changed. This update is sent only if the message database is used. - */ - public UpdateUnreadMessageCount() { - } - - /** - * Number of unread messages in a chat list has changed. This update is sent only if the message database is used. - * - * @param chatList The chat list with changed number of unread messages. - * @param unreadCount Total number of unread messages. - * @param unreadUnmutedCount Total number of unread messages in unmuted chats. - */ - public UpdateUnreadMessageCount(ChatList chatList, int unreadCount, int unreadUnmutedCount) { - this.chatList = chatList; - this.unreadCount = unreadCount; - this.unreadUnmutedCount = unreadUnmutedCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 78987721; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Number of unread chats, i.e. with unread messages or marked as unread, has changed. This update is sent only if the message database is used. - */ - public static class UpdateUnreadChatCount extends Update { - /** - * The chat list with changed number of unread messages. - */ - public ChatList chatList; - /** - * Approximate total number of chats in the chat list. - */ - public int totalCount; - /** - * Total number of unread chats. - */ - public int unreadCount; - /** - * Total number of unread unmuted chats. - */ - public int unreadUnmutedCount; - /** - * Total number of chats marked as unread. - */ - public int markedAsUnreadCount; - /** - * Total number of unmuted chats marked as unread. - */ - public int markedAsUnreadUnmutedCount; - - /** - * Number of unread chats, i.e. with unread messages or marked as unread, has changed. This update is sent only if the message database is used. - */ - public UpdateUnreadChatCount() { - } - - /** - * Number of unread chats, i.e. with unread messages or marked as unread, has changed. This update is sent only if the message database is used. - * - * @param chatList The chat list with changed number of unread messages. - * @param totalCount Approximate total number of chats in the chat list. - * @param unreadCount Total number of unread chats. - * @param unreadUnmutedCount Total number of unread unmuted chats. - * @param markedAsUnreadCount Total number of chats marked as unread. - * @param markedAsUnreadUnmutedCount Total number of unmuted chats marked as unread. - */ - public UpdateUnreadChatCount(ChatList chatList, int totalCount, int unreadCount, int unreadUnmutedCount, int markedAsUnreadCount, int markedAsUnreadUnmutedCount) { - this.chatList = chatList; - this.totalCount = totalCount; - this.unreadCount = unreadCount; - this.unreadUnmutedCount = unreadUnmutedCount; - this.markedAsUnreadCount = markedAsUnreadCount; - this.markedAsUnreadUnmutedCount = markedAsUnreadUnmutedCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1994494530; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A story was changed. - */ - public static class UpdateStory extends Update { - /** - * The new information about the story. - */ - public Story story; - - /** - * A story was changed. - */ - public UpdateStory() { - } - - /** - * A story was changed. - * - * @param story The new information about the story. - */ - public UpdateStory(Story story) { - this.story = story; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 419845935; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A story became inaccessible. - */ - public static class UpdateStoryDeleted extends Update { - /** - * Identifier of the chat that posted the story. - */ - public long storyPosterChatId; - /** - * Story identifier. - */ - public int storyId; - - /** - * A story became inaccessible. - */ - public UpdateStoryDeleted() { - } - - /** - * A story became inaccessible. - * - * @param storyPosterChatId Identifier of the chat that posted the story. - * @param storyId Story identifier. - */ - public UpdateStoryDeleted(long storyPosterChatId, int storyId) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -582743166; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A story has been successfully posted. - */ - public static class UpdateStoryPostSucceeded extends Update { - /** - * The posted story. - */ - public Story story; - /** - * The previous temporary story identifier. - */ - public int oldStoryId; - - /** - * A story has been successfully posted. - */ - public UpdateStoryPostSucceeded() { - } - - /** - * A story has been successfully posted. - * - * @param story The posted story. - * @param oldStoryId The previous temporary story identifier. - */ - public UpdateStoryPostSucceeded(Story story, int oldStoryId) { - this.story = story; - this.oldStoryId = oldStoryId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1712432318; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A story failed to post. If the story posting is canceled, then updateStoryDeleted will be received instead of this update. - */ - public static class UpdateStoryPostFailed extends Update { - /** - * The failed to post story. - */ - public Story story; - /** - * The cause of the story posting failure. - */ - public Error error; - /** - * Type of the error; may be null if unknown. - */ - @Nullable public CanPostStoryResult errorType; - - /** - * A story failed to post. If the story posting is canceled, then updateStoryDeleted will be received instead of this update. - */ - public UpdateStoryPostFailed() { - } - - /** - * A story failed to post. If the story posting is canceled, then updateStoryDeleted will be received instead of this update. - * - * @param story The failed to post story. - * @param error The cause of the story posting failure. - * @param errorType Type of the error; may be null if unknown. - */ - public UpdateStoryPostFailed(Story story, Error error, CanPostStoryResult errorType) { - this.story = story; - this.error = error; - this.errorType = errorType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1248168444; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of active stories posted by a specific chat has changed. - */ - public static class UpdateChatActiveStories extends Update { - /** - * The new list of active stories. - */ - public ChatActiveStories activeStories; - - /** - * The list of active stories posted by a specific chat has changed. - */ - public UpdateChatActiveStories() { - } - - /** - * The list of active stories posted by a specific chat has changed. - * - * @param activeStories The new list of active stories. - */ - public UpdateChatActiveStories(ChatActiveStories activeStories) { - this.activeStories = activeStories; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2037935148; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Number of chats in a story list has changed. - */ - public static class UpdateStoryListChatCount extends Update { - /** - * The story list. - */ - public StoryList storyList; - /** - * Approximate total number of chats with active stories in the list. - */ - public int chatCount; - - /** - * Number of chats in a story list has changed. - */ - public UpdateStoryListChatCount() { - } - - /** - * Number of chats in a story list has changed. - * - * @param storyList The story list. - * @param chatCount Approximate total number of chats with active stories in the list. - */ - public UpdateStoryListChatCount(StoryList storyList, int chatCount) { - this.storyList = storyList; - this.chatCount = chatCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2009871041; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Story stealth mode settings have changed. - */ - public static class UpdateStoryStealthMode extends Update { - /** - * Point in time (Unix timestamp) until stealth mode is active; 0 if it is disabled. - */ - public int activeUntilDate; - /** - * Point in time (Unix timestamp) when stealth mode can be enabled again; 0 if there is no active cooldown. - */ - public int cooldownUntilDate; - - /** - * Story stealth mode settings have changed. - */ - public UpdateStoryStealthMode() { - } - - /** - * Story stealth mode settings have changed. - * - * @param activeUntilDate Point in time (Unix timestamp) until stealth mode is active; 0 if it is disabled. - * @param cooldownUntilDate Point in time (Unix timestamp) when stealth mode can be enabled again; 0 if there is no active cooldown. - */ - public UpdateStoryStealthMode(int activeUntilDate, int cooldownUntilDate) { - this.activeUntilDate = activeUntilDate; - this.cooldownUntilDate = cooldownUntilDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1878506778; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Lists of bots which Mini Apps must be allowed to read text from clipboard and must be opened without a warning. - */ - public static class UpdateTrustedMiniAppBots extends Update { - /** - * List of user identifiers of the bots; the corresponding users may not be sent using updateUser updates and may not be accessible. - */ - public long[] botUserIds; - - /** - * Lists of bots which Mini Apps must be allowed to read text from clipboard and must be opened without a warning. - */ - public UpdateTrustedMiniAppBots() { - } - - /** - * Lists of bots which Mini Apps must be allowed to read text from clipboard and must be opened without a warning. - * - * @param botUserIds List of user identifiers of the bots; the corresponding users may not be sent using updateUser updates and may not be accessible. - */ - public UpdateTrustedMiniAppBots(long[] botUserIds) { - this.botUserIds = botUserIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1733723438; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * An option changed its value. - */ - public static class UpdateOption extends Update { - /** - * The option name. - */ - public String name; - /** - * The new option value. - */ - public OptionValue value; - - /** - * An option changed its value. - */ - public UpdateOption() { - } - - /** - * An option changed its value. - * - * @param name The option name. - * @param value The new option value. - */ - public UpdateOption(String name, OptionValue value) { - this.name = name; - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 900822020; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A sticker set has changed. - */ - public static class UpdateStickerSet extends Update { - /** - * The sticker set. - */ - public StickerSet stickerSet; - - /** - * A sticker set has changed. - */ - public UpdateStickerSet() { - } - - /** - * A sticker set has changed. - * - * @param stickerSet The sticker set. - */ - public UpdateStickerSet(StickerSet stickerSet) { - this.stickerSet = stickerSet; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1879268812; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of installed sticker sets was updated. - */ - public static class UpdateInstalledStickerSets extends Update { - /** - * Type of the affected stickers. - */ - public StickerType stickerType; - /** - * The new list of installed ordinary sticker sets. - */ - public long[] stickerSetIds; - - /** - * The list of installed sticker sets was updated. - */ - public UpdateInstalledStickerSets() { - } - - /** - * The list of installed sticker sets was updated. - * - * @param stickerType Type of the affected stickers. - * @param stickerSetIds The new list of installed ordinary sticker sets. - */ - public UpdateInstalledStickerSets(StickerType stickerType, long[] stickerSetIds) { - this.stickerType = stickerType; - this.stickerSetIds = stickerSetIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1735084182; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of trending sticker sets was updated or some of them were viewed. - */ - public static class UpdateTrendingStickerSets extends Update { - /** - * Type of the affected stickers. - */ - public StickerType stickerType; - /** - * The prefix of the list of trending sticker sets with the newest trending sticker sets. - */ - public TrendingStickerSets stickerSets; - - /** - * The list of trending sticker sets was updated or some of them were viewed. - */ - public UpdateTrendingStickerSets() { - } - - /** - * The list of trending sticker sets was updated or some of them were viewed. - * - * @param stickerType Type of the affected stickers. - * @param stickerSets The prefix of the list of trending sticker sets with the newest trending sticker sets. - */ - public UpdateTrendingStickerSets(StickerType stickerType, TrendingStickerSets stickerSets) { - this.stickerType = stickerType; - this.stickerSets = stickerSets; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1266307239; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of recently used stickers was updated. - */ - public static class UpdateRecentStickers extends Update { - /** - * True, if the list of stickers attached to photo or video files was updated; otherwise, the list of sent stickers is updated. - */ - public boolean isAttached; - /** - * The new list of file identifiers of recently used stickers. - */ - public int[] stickerIds; - - /** - * The list of recently used stickers was updated. - */ - public UpdateRecentStickers() { - } - - /** - * The list of recently used stickers was updated. - * - * @param isAttached True, if the list of stickers attached to photo or video files was updated; otherwise, the list of sent stickers is updated. - * @param stickerIds The new list of file identifiers of recently used stickers. - */ - public UpdateRecentStickers(boolean isAttached, int[] stickerIds) { - this.isAttached = isAttached; - this.stickerIds = stickerIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1906403540; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of favorite stickers was updated. - */ - public static class UpdateFavoriteStickers extends Update { - /** - * The new list of file identifiers of favorite stickers. - */ - public int[] stickerIds; - - /** - * The list of favorite stickers was updated. - */ - public UpdateFavoriteStickers() { - } - - /** - * The list of favorite stickers was updated. - * - * @param stickerIds The new list of file identifiers of favorite stickers. - */ - public UpdateFavoriteStickers(int[] stickerIds) { - this.stickerIds = stickerIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1662240999; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of saved animations was updated. - */ - public static class UpdateSavedAnimations extends Update { - /** - * The new list of file identifiers of saved animations. - */ - public int[] animationIds; - - /** - * The list of saved animations was updated. - */ - public UpdateSavedAnimations() { - } - - /** - * The list of saved animations was updated. - * - * @param animationIds The new list of file identifiers of saved animations. - */ - public UpdateSavedAnimations(int[] animationIds) { - this.animationIds = animationIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 65563814; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of saved notification sounds was updated. This update may not be sent until information about a notification sound was requested for the first time. - */ - public static class UpdateSavedNotificationSounds extends Update { - /** - * The new list of identifiers of saved notification sounds. - */ - public long[] notificationSoundIds; - - /** - * The list of saved notification sounds was updated. This update may not be sent until information about a notification sound was requested for the first time. - */ - public UpdateSavedNotificationSounds() { - } - - /** - * The list of saved notification sounds was updated. This update may not be sent until information about a notification sound was requested for the first time. - * - * @param notificationSoundIds The new list of identifiers of saved notification sounds. - */ - public UpdateSavedNotificationSounds(long[] notificationSoundIds) { - this.notificationSoundIds = notificationSoundIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1052725698; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The default background has changed. - */ - public static class UpdateDefaultBackground extends Update { - /** - * True, if default background for dark theme has changed. - */ - public boolean forDarkTheme; - /** - * The new default background; may be null. - */ - @Nullable public Background background; - - /** - * The default background has changed. - */ - public UpdateDefaultBackground() { - } - - /** - * The default background has changed. - * - * @param forDarkTheme True, if default background for dark theme has changed. - * @param background The new default background; may be null. - */ - public UpdateDefaultBackground(boolean forDarkTheme, Background background) { - this.forDarkTheme = forDarkTheme; - this.background = background; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -716139217; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of available emoji chat themes has changed. - */ - public static class UpdateEmojiChatThemes extends Update { - /** - * The new list of emoji chat themes. - */ - public EmojiChatTheme[] chatThemes; - - /** - * The list of available emoji chat themes has changed. - */ - public UpdateEmojiChatThemes() { - } - - /** - * The list of available emoji chat themes has changed. - * - * @param chatThemes The new list of emoji chat themes. - */ - public UpdateEmojiChatThemes(EmojiChatTheme[] chatThemes) { - this.chatThemes = chatThemes; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1021628745; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of supported accent colors has changed. - */ - public static class UpdateAccentColors extends Update { - /** - * Information about supported colors; colors with identifiers 0 (red), 1 (orange), 2 (purple/violet), 3 (green), 4 (cyan), 5 (blue), 6 (pink) must always be supported and aren't included in the list. The exact colors for the accent colors with identifiers 0-6 must be taken from the app theme. - */ - public AccentColor[] colors; - /** - * The list of accent color identifiers, which can be set through setAccentColor and setChatAccentColor. The colors must be shown in the specified order. - */ - public int[] availableAccentColorIds; - - /** - * The list of supported accent colors has changed. - */ - public UpdateAccentColors() { - } - - /** - * The list of supported accent colors has changed. - * - * @param colors Information about supported colors; colors with identifiers 0 (red), 1 (orange), 2 (purple/violet), 3 (green), 4 (cyan), 5 (blue), 6 (pink) must always be supported and aren't included in the list. The exact colors for the accent colors with identifiers 0-6 must be taken from the app theme. - * @param availableAccentColorIds The list of accent color identifiers, which can be set through setAccentColor and setChatAccentColor. The colors must be shown in the specified order. - */ - public UpdateAccentColors(AccentColor[] colors, int[] availableAccentColorIds) { - this.colors = colors; - this.availableAccentColorIds = availableAccentColorIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1197047738; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of supported accent colors for user profiles has changed. - */ - public static class UpdateProfileAccentColors extends Update { - /** - * Information about supported colors. - */ - public ProfileAccentColor[] colors; - /** - * The list of accent color identifiers, which can be set through setProfileAccentColor and setChatProfileAccentColor. The colors must be shown in the specified order. - */ - public int[] availableAccentColorIds; - - /** - * The list of supported accent colors for user profiles has changed. - */ - public UpdateProfileAccentColors() { - } - - /** - * The list of supported accent colors for user profiles has changed. - * - * @param colors Information about supported colors. - * @param availableAccentColorIds The list of accent color identifiers, which can be set through setProfileAccentColor and setChatProfileAccentColor. The colors must be shown in the specified order. - */ - public UpdateProfileAccentColors(ProfileAccentColor[] colors, int[] availableAccentColorIds) { - this.colors = colors; - this.availableAccentColorIds = availableAccentColorIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 605202104; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Some language pack strings have been updated. - */ - public static class UpdateLanguagePackStrings extends Update { - /** - * Localization target to which the language pack belongs. - */ - public String localizationTarget; - /** - * Identifier of the updated language pack. - */ - public String languagePackId; - /** - * List of changed language pack strings; empty if all strings have changed. - */ - public LanguagePackString[] strings; - - /** - * Some language pack strings have been updated. - */ - public UpdateLanguagePackStrings() { - } - - /** - * Some language pack strings have been updated. - * - * @param localizationTarget Localization target to which the language pack belongs. - * @param languagePackId Identifier of the updated language pack. - * @param strings List of changed language pack strings; empty if all strings have changed. - */ - public UpdateLanguagePackStrings(String localizationTarget, String languagePackId, LanguagePackString[] strings) { - this.localizationTarget = localizationTarget; - this.languagePackId = languagePackId; - this.strings = strings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1056319886; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The connection state has changed. This update must be used only to show a human-readable description of the connection state. - */ - public static class UpdateConnectionState extends Update { - /** - * The new connection state. - */ - public ConnectionState state; - - /** - * The connection state has changed. This update must be used only to show a human-readable description of the connection state. - */ - public UpdateConnectionState() { - } - - /** - * The connection state has changed. This update must be used only to show a human-readable description of the connection state. - * - * @param state The new connection state. - */ - public UpdateConnectionState(ConnectionState state) { - this.state = state; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1469292078; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The freeze state of the current user's account has changed. - */ - public static class UpdateFreezeState extends Update { - /** - * True, if the account is frozen. - */ - public boolean isFrozen; - /** - * Point in time (Unix timestamp) when the account was frozen; 0 if the account isn't frozen. - */ - public int freezingDate; - /** - * Point in time (Unix timestamp) when the account will be deleted and can't be unfrozen; 0 if the account isn't frozen. - */ - public int deletionDate; - /** - * The link to open to send an appeal to unfreeze the account. - */ - public String appealLink; - - /** - * The freeze state of the current user's account has changed. - */ - public UpdateFreezeState() { - } - - /** - * The freeze state of the current user's account has changed. - * - * @param isFrozen True, if the account is frozen. - * @param freezingDate Point in time (Unix timestamp) when the account was frozen; 0 if the account isn't frozen. - * @param deletionDate Point in time (Unix timestamp) when the account will be deleted and can't be unfrozen; 0 if the account isn't frozen. - * @param appealLink The link to open to send an appeal to unfreeze the account. - */ - public UpdateFreezeState(boolean isFrozen, int freezingDate, int deletionDate, String appealLink) { - this.isFrozen = isFrozen; - this.freezingDate = freezingDate; - this.deletionDate = deletionDate; - this.appealLink = appealLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1692410540; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The parameters for age verification of the current user's account has changed. - */ - public static class UpdateAgeVerificationParameters extends Update { - /** - * Parameters for the age verification; may be null if age verification isn't needed. - */ - @Nullable public AgeVerificationParameters parameters; - - /** - * The parameters for age verification of the current user's account has changed. - */ - public UpdateAgeVerificationParameters() { - } - - /** - * The parameters for age verification of the current user's account has changed. - * - * @param parameters Parameters for the age verification; may be null if age verification isn't needed. - */ - public UpdateAgeVerificationParameters(AgeVerificationParameters parameters) { - this.parameters = parameters; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -49283131; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * New terms of service must be accepted by the user. If the terms of service are declined, then the deleteAccount method must be called with the reason "Decline ToS update". - */ - public static class UpdateTermsOfService extends Update { - /** - * Identifier of the terms of service. - */ - public String termsOfServiceId; - /** - * The new terms of service. - */ - public TermsOfService termsOfService; - - /** - * New terms of service must be accepted by the user. If the terms of service are declined, then the deleteAccount method must be called with the reason "Decline ToS update". - */ - public UpdateTermsOfService() { - } - - /** - * New terms of service must be accepted by the user. If the terms of service are declined, then the deleteAccount method must be called with the reason "Decline ToS update". - * - * @param termsOfServiceId Identifier of the terms of service. - * @param termsOfService The new terms of service. - */ - public UpdateTermsOfService(String termsOfServiceId, TermsOfService termsOfService) { - this.termsOfServiceId = termsOfServiceId; - this.termsOfService = termsOfService; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1304640162; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The first unconfirmed session has changed. - */ - public static class UpdateUnconfirmedSession extends Update { - /** - * The unconfirmed session; may be null if none. - */ - @Nullable public UnconfirmedSession session; - - /** - * The first unconfirmed session has changed. - */ - public UpdateUnconfirmedSession() { - } - - /** - * The first unconfirmed session has changed. - * - * @param session The unconfirmed session; may be null if none. - */ - public UpdateUnconfirmedSession(UnconfirmedSession session) { - this.session = session; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -22673268; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of bots added to attachment or side menu has changed. - */ - public static class UpdateAttachmentMenuBots extends Update { - /** - * The new list of bots. The bots must not be shown on scheduled messages screen. - */ - public AttachmentMenuBot[] bots; - - /** - * The list of bots added to attachment or side menu has changed. - */ - public UpdateAttachmentMenuBots() { - } - - /** - * The list of bots added to attachment or side menu has changed. - * - * @param bots The new list of bots. The bots must not be shown on scheduled messages screen. - */ - public UpdateAttachmentMenuBots(AttachmentMenuBot[] bots) { - this.bots = bots; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 291369922; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message was sent by an opened Web App, so the Web App needs to be closed. - */ - public static class UpdateWebAppMessageSent extends Update { - /** - * Identifier of Web App launch. - */ - public long webAppLaunchId; - - /** - * A message was sent by an opened Web App, so the Web App needs to be closed. - */ - public UpdateWebAppMessageSent() { - } - - /** - * A message was sent by an opened Web App, so the Web App needs to be closed. - * - * @param webAppLaunchId Identifier of Web App launch. - */ - public UpdateWebAppMessageSent(long webAppLaunchId) { - this.webAppLaunchId = webAppLaunchId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1480790569; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of active emoji reactions has changed. - */ - public static class UpdateActiveEmojiReactions extends Update { - /** - * The new list of active emoji reactions. - */ - public String[] emojis; - - /** - * The list of active emoji reactions has changed. - */ - public UpdateActiveEmojiReactions() { - } - - /** - * The list of active emoji reactions has changed. - * - * @param emojis The new list of active emoji reactions. - */ - public UpdateActiveEmojiReactions(String[] emojis) { - this.emojis = emojis; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 77556818; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of available message effects has changed. - */ - public static class UpdateAvailableMessageEffects extends Update { - /** - * The new list of available message effects from emoji reactions. - */ - public long[] reactionEffectIds; - /** - * The new list of available message effects from Premium stickers. - */ - public long[] stickerEffectIds; - - /** - * The list of available message effects has changed. - */ - public UpdateAvailableMessageEffects() { - } - - /** - * The list of available message effects has changed. - * - * @param reactionEffectIds The new list of available message effects from emoji reactions. - * @param stickerEffectIds The new list of available message effects from Premium stickers. - */ - public UpdateAvailableMessageEffects(long[] reactionEffectIds, long[] stickerEffectIds) { - this.reactionEffectIds = reactionEffectIds; - this.stickerEffectIds = stickerEffectIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1964701061; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The type of default reaction has changed. - */ - public static class UpdateDefaultReactionType extends Update { - /** - * The new type of the default reaction. - */ - public ReactionType reactionType; - - /** - * The type of default reaction has changed. - */ - public UpdateDefaultReactionType() { - } - - /** - * The type of default reaction has changed. - * - * @param reactionType The new type of the default reaction. - */ - public UpdateDefaultReactionType(ReactionType reactionType) { - this.reactionType = reactionType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1264668933; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The type of default paid reaction has changed. - */ - public static class UpdateDefaultPaidReactionType extends Update { - /** - * The new type of the default paid reaction. - */ - public PaidReactionType type; - - /** - * The type of default paid reaction has changed. - */ - public UpdateDefaultPaidReactionType() { - } - - /** - * The type of default paid reaction has changed. - * - * @param type The new type of the default paid reaction. - */ - public UpdateDefaultPaidReactionType(PaidReactionType type) { - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 38198599; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Tags used in Saved Messages or a Saved Messages topic have changed. - */ - public static class UpdateSavedMessagesTags extends Update { - /** - * Identifier of Saved Messages topic which tags were changed; 0 if tags for the whole chat has changed. - */ - public long savedMessagesTopicId; - /** - * The new tags. - */ - public SavedMessagesTags tags; - - /** - * Tags used in Saved Messages or a Saved Messages topic have changed. - */ - public UpdateSavedMessagesTags() { - } - - /** - * Tags used in Saved Messages or a Saved Messages topic have changed. - * - * @param savedMessagesTopicId Identifier of Saved Messages topic which tags were changed; 0 if tags for the whole chat has changed. - * @param tags The new tags. - */ - public UpdateSavedMessagesTags(long savedMessagesTopicId, SavedMessagesTags tags) { - this.savedMessagesTopicId = savedMessagesTopicId; - this.tags = tags; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1938178634; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of messages with active live location that need to be updated by the application has changed. The list is persistent across application restarts only if the message database is used. - */ - public static class UpdateActiveLiveLocationMessages extends Update { - /** - * The list of messages with active live locations. - */ - public Message[] messages; - - /** - * The list of messages with active live location that need to be updated by the application has changed. The list is persistent across application restarts only if the message database is used. - */ - public UpdateActiveLiveLocationMessages() { - } - - /** - * The list of messages with active live location that need to be updated by the application has changed. The list is persistent across application restarts only if the message database is used. - * - * @param messages The list of messages with active live locations. - */ - public UpdateActiveLiveLocationMessages(Message[] messages) { - this.messages = messages; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1308142440; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The number of Telegram Stars owned by the current user has changed. - */ - public static class UpdateOwnedStarCount extends Update { - /** - * The new amount of owned Telegram Stars. - */ - public StarAmount starAmount; - - /** - * The number of Telegram Stars owned by the current user has changed. - */ - public UpdateOwnedStarCount() { - } - - /** - * The number of Telegram Stars owned by the current user has changed. - * - * @param starAmount The new amount of owned Telegram Stars. - */ - public UpdateOwnedStarCount(StarAmount starAmount) { - this.starAmount = starAmount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1350647928; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The number of Toncoins owned by the current user has changed. - */ - public static class UpdateOwnedTonCount extends Update { - /** - * The new amount of owned Toncoins; in the smallest units of the cryptocurrency. - */ - public long tonAmount; - - /** - * The number of Toncoins owned by the current user has changed. - */ - public UpdateOwnedTonCount() { - } - - /** - * The number of Toncoins owned by the current user has changed. - * - * @param tonAmount The new amount of owned Toncoins; in the smallest units of the cryptocurrency. - */ - public UpdateOwnedTonCount(long tonAmount) { - this.tonAmount = tonAmount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1102136345; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The revenue earned from sponsored messages in a chat has changed. If chat revenue screen is opened, then getChatRevenueTransactions may be called to fetch new transactions. - */ - public static class UpdateChatRevenueAmount extends Update { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * New amount of earned revenue. - */ - public ChatRevenueAmount revenueAmount; - - /** - * The revenue earned from sponsored messages in a chat has changed. If chat revenue screen is opened, then getChatRevenueTransactions may be called to fetch new transactions. - */ - public UpdateChatRevenueAmount() { - } - - /** - * The revenue earned from sponsored messages in a chat has changed. If chat revenue screen is opened, then getChatRevenueTransactions may be called to fetch new transactions. - * - * @param chatId Identifier of the chat. - * @param revenueAmount New amount of earned revenue. - */ - public UpdateChatRevenueAmount(long chatId, ChatRevenueAmount revenueAmount) { - this.chatId = chatId; - this.revenueAmount = revenueAmount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -959857468; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The Telegram Star revenue earned by a user or a chat has changed. If Telegram Star transaction screen of the chat is opened, then getStarTransactions may be called to fetch new transactions. - */ - public static class UpdateStarRevenueStatus extends Update { - /** - * Identifier of the owner of the Telegram Stars. - */ - public MessageSender ownerId; - /** - * New Telegram Star revenue status. - */ - public StarRevenueStatus status; - - /** - * The Telegram Star revenue earned by a user or a chat has changed. If Telegram Star transaction screen of the chat is opened, then getStarTransactions may be called to fetch new transactions. - */ - public UpdateStarRevenueStatus() { - } - - /** - * The Telegram Star revenue earned by a user or a chat has changed. If Telegram Star transaction screen of the chat is opened, then getStarTransactions may be called to fetch new transactions. - * - * @param ownerId Identifier of the owner of the Telegram Stars. - * @param status New Telegram Star revenue status. - */ - public UpdateStarRevenueStatus(MessageSender ownerId, StarRevenueStatus status) { - this.ownerId = ownerId; - this.status = status; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -280232757; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The Toncoin revenue earned by the current user has changed. If Toncoin transaction screen of the chat is opened, then getTonTransactions may be called to fetch new transactions. - */ - public static class UpdateTonRevenueStatus extends Update { - /** - * New Toncoin revenue status. - */ - public TonRevenueStatus status; - - /** - * The Toncoin revenue earned by the current user has changed. If Toncoin transaction screen of the chat is opened, then getTonTransactions may be called to fetch new transactions. - */ - public UpdateTonRevenueStatus() { - } - - /** - * The Toncoin revenue earned by the current user has changed. If Toncoin transaction screen of the chat is opened, then getTonTransactions may be called to fetch new transactions. - * - * @param status New Toncoin revenue status. - */ - public UpdateTonRevenueStatus(TonRevenueStatus status) { - this.status = status; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1832579994; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The parameters of speech recognition without Telegram Premium subscription has changed. - */ - public static class UpdateSpeechRecognitionTrial extends Update { - /** - * The maximum allowed duration of media for speech recognition without Telegram Premium subscription, in seconds. - */ - public int maxMediaDuration; - /** - * The total number of allowed speech recognitions per week; 0 if none. - */ - public int weeklyCount; - /** - * Number of left speech recognition attempts this week. - */ - public int leftCount; - /** - * Point in time (Unix timestamp) when the weekly number of tries will reset; 0 if unknown. - */ - public int nextResetDate; - - /** - * The parameters of speech recognition without Telegram Premium subscription has changed. - */ - public UpdateSpeechRecognitionTrial() { - } - - /** - * The parameters of speech recognition without Telegram Premium subscription has changed. - * - * @param maxMediaDuration The maximum allowed duration of media for speech recognition without Telegram Premium subscription, in seconds. - * @param weeklyCount The total number of allowed speech recognitions per week; 0 if none. - * @param leftCount Number of left speech recognition attempts this week. - * @param nextResetDate Point in time (Unix timestamp) when the weekly number of tries will reset; 0 if unknown. - */ - public UpdateSpeechRecognitionTrial(int maxMediaDuration, int weeklyCount, int leftCount, int nextResetDate) { - this.maxMediaDuration = maxMediaDuration; - this.weeklyCount = weeklyCount; - this.leftCount = leftCount; - this.nextResetDate = nextResetDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -11600703; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The levels of live story group call messages have changed. - */ - public static class UpdateGroupCallMessageLevels extends Update { - /** - * New description of the levels in decreasing order of groupCallMessageLevel.minStarCount. - */ - public GroupCallMessageLevel[] levels; - - /** - * The levels of live story group call messages have changed. - */ - public UpdateGroupCallMessageLevels() { - } - - /** - * The levels of live story group call messages have changed. - * - * @param levels New description of the levels in decreasing order of groupCallMessageLevel.minStarCount. - */ - public UpdateGroupCallMessageLevels(GroupCallMessageLevel[] levels) { - this.levels = levels; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -882998951; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of supported dice emojis has changed. - */ - public static class UpdateDiceEmojis extends Update { - /** - * The new list of supported dice emojis. - */ - public String[] emojis; - - /** - * The list of supported dice emojis has changed. - */ - public UpdateDiceEmojis() { - } - - /** - * The list of supported dice emojis has changed. - * - * @param emojis The new list of supported dice emojis. - */ - public UpdateDiceEmojis(String[] emojis) { - this.emojis = emojis; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1069066940; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The stake dice state has changed. - */ - public static class UpdateStakeDiceState extends Update { - /** - * The new state. The state can be used only if it was received recently enough. Otherwise, a new state must be requested using getStakeDiceState. - */ - public StakeDiceState state; - - /** - * The stake dice state has changed. - */ - public UpdateStakeDiceState() { - } - - /** - * The stake dice state has changed. - * - * @param state The new state. The state can be used only if it was received recently enough. Otherwise, a new state must be requested using getStakeDiceState. - */ - public UpdateStakeDiceState(StakeDiceState state) { - this.state = state; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -739631973; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Some animated emoji message was clicked and a big animated sticker must be played if the message is visible on the screen. chatActionWatchingAnimations with the text of the message needs to be sent if the sticker is played. - */ - public static class UpdateAnimatedEmojiMessageClicked extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - /** - * The animated sticker to be played. - */ - public Sticker sticker; - - /** - * Some animated emoji message was clicked and a big animated sticker must be played if the message is visible on the screen. chatActionWatchingAnimations with the text of the message needs to be sent if the sticker is played. - */ - public UpdateAnimatedEmojiMessageClicked() { - } - - /** - * Some animated emoji message was clicked and a big animated sticker must be played if the message is visible on the screen. chatActionWatchingAnimations with the text of the message needs to be sent if the sticker is played. - * - * @param chatId Chat identifier. - * @param messageId Message identifier. - * @param sticker The animated sticker to be played. - */ - public UpdateAnimatedEmojiMessageClicked(long chatId, long messageId, Sticker sticker) { - this.chatId = chatId; - this.messageId = messageId; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1558809595; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The parameters of animation search through getOption("animation_search_bot_username") bot has changed. - */ - public static class UpdateAnimationSearchParameters extends Update { - /** - * Name of the animation search provider. - */ - public String provider; - /** - * The new list of emojis suggested for searching. - */ - public String[] emojis; - - /** - * The parameters of animation search through getOption("animation_search_bot_username") bot has changed. - */ - public UpdateAnimationSearchParameters() { - } - - /** - * The parameters of animation search through getOption("animation_search_bot_username") bot has changed. - * - * @param provider Name of the animation search provider. - * @param emojis The new list of emojis suggested for searching. - */ - public UpdateAnimationSearchParameters(String provider, String[] emojis) { - this.provider = provider; - this.emojis = emojis; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1144983202; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of suggested to the user actions has changed. - */ - public static class UpdateSuggestedActions extends Update { - /** - * Added suggested actions. - */ - public SuggestedAction[] addedActions; - /** - * Removed suggested actions. - */ - public SuggestedAction[] removedActions; - - /** - * The list of suggested to the user actions has changed. - */ - public UpdateSuggestedActions() { - } - - /** - * The list of suggested to the user actions has changed. - * - * @param addedActions Added suggested actions. - * @param removedActions Removed suggested actions. - */ - public UpdateSuggestedActions(SuggestedAction[] addedActions, SuggestedAction[] removedActions) { - this.addedActions = addedActions; - this.removedActions = removedActions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1459452346; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Download or upload file speed for the user was limited, but it can be restored by subscription to Telegram Premium. The notification can be postponed until a being downloaded or uploaded file is visible to the user. Use getOption("premium_download_speedup") or getOption("premium_upload_speedup") to get expected speedup after subscription to Telegram Premium. - */ - public static class UpdateSpeedLimitNotification extends Update { - /** - * True, if upload speed was limited; false, if download speed was limited. - */ - public boolean isUpload; - - /** - * Download or upload file speed for the user was limited, but it can be restored by subscription to Telegram Premium. The notification can be postponed until a being downloaded or uploaded file is visible to the user. Use getOption("premium_download_speedup") or getOption("premium_upload_speedup") to get expected speedup after subscription to Telegram Premium. - */ - public UpdateSpeedLimitNotification() { - } - - /** - * Download or upload file speed for the user was limited, but it can be restored by subscription to Telegram Premium. The notification can be postponed until a being downloaded or uploaded file is visible to the user. Use getOption("premium_download_speedup") or getOption("premium_upload_speedup") to get expected speedup after subscription to Telegram Premium. - * - * @param isUpload True, if upload speed was limited; false, if download speed was limited. - */ - public UpdateSpeedLimitNotification(boolean isUpload) { - this.isUpload = isUpload; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -964437912; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The list of contacts that had birthdays recently or will have birthday soon has changed. - */ - public static class UpdateContactCloseBirthdays extends Update { - /** - * List of contact users with close birthday. - */ - public CloseBirthdayUser[] closeBirthdayUsers; - - /** - * The list of contacts that had birthdays recently or will have birthday soon has changed. - */ - public UpdateContactCloseBirthdays() { - } - - /** - * The list of contacts that had birthdays recently or will have birthday soon has changed. - * - * @param closeBirthdayUsers List of contact users with close birthday. - */ - public UpdateContactCloseBirthdays(CloseBirthdayUser[] closeBirthdayUsers) { - this.closeBirthdayUsers = closeBirthdayUsers; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -36007873; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Autosave settings for some type of chats were updated. - */ - public static class UpdateAutosaveSettings extends Update { - /** - * Type of chats for which autosave settings were updated. - */ - public AutosaveSettingsScope scope; - /** - * The new autosave settings; may be null if the settings are reset to default. - */ - @Nullable public ScopeAutosaveSettings settings; - - /** - * Autosave settings for some type of chats were updated. - */ - public UpdateAutosaveSettings() { - } - - /** - * Autosave settings for some type of chats were updated. - * - * @param scope Type of chats for which autosave settings were updated. - * @param settings The new autosave settings; may be null if the settings are reset to default. - */ - public UpdateAutosaveSettings(AutosaveSettingsScope scope, ScopeAutosaveSettings settings) { - this.scope = scope; - this.settings = settings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -634958069; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A business connection has changed; for bots only. - */ - public static class UpdateBusinessConnection extends Update { - /** - * New data about the connection. - */ - public BusinessConnection connection; - - /** - * A business connection has changed; for bots only. - */ - public UpdateBusinessConnection() { - } - - /** - * A business connection has changed; for bots only. - * - * @param connection New data about the connection. - */ - public UpdateBusinessConnection(BusinessConnection connection) { - this.connection = connection; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2043480970; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new message was added to a business account; for bots only. - */ - public static class UpdateNewBusinessMessage extends Update { - /** - * Unique identifier of the business connection. - */ - public String connectionId; - /** - * The new message. - */ - public BusinessMessage message; - - /** - * A new message was added to a business account; for bots only. - */ - public UpdateNewBusinessMessage() { - } - - /** - * A new message was added to a business account; for bots only. - * - * @param connectionId Unique identifier of the business connection. - * @param message The new message. - */ - public UpdateNewBusinessMessage(String connectionId, BusinessMessage message) { - this.connectionId = connectionId; - this.message = message; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2034350524; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A message in a business account was edited; for bots only. - */ - public static class UpdateBusinessMessageEdited extends Update { - /** - * Unique identifier of the business connection. - */ - public String connectionId; - /** - * The edited message. - */ - public BusinessMessage message; - - /** - * A message in a business account was edited; for bots only. - */ - public UpdateBusinessMessageEdited() { - } - - /** - * A message in a business account was edited; for bots only. - * - * @param connectionId Unique identifier of the business connection. - * @param message The edited message. - */ - public UpdateBusinessMessageEdited(String connectionId, BusinessMessage message) { - this.connectionId = connectionId; - this.message = message; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2119799415; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Messages in a business account were deleted; for bots only. - */ - public static class UpdateBusinessMessagesDeleted extends Update { - /** - * Unique identifier of the business connection. - */ - public String connectionId; - /** - * Identifier of a chat in the business account in which messages were deleted. - */ - public long chatId; - /** - * Unique message identifiers of the deleted messages. - */ - public long[] messageIds; - - /** - * Messages in a business account were deleted; for bots only. - */ - public UpdateBusinessMessagesDeleted() { - } - - /** - * Messages in a business account were deleted; for bots only. - * - * @param connectionId Unique identifier of the business connection. - * @param chatId Identifier of a chat in the business account in which messages were deleted. - * @param messageIds Unique message identifiers of the deleted messages. - */ - public UpdateBusinessMessagesDeleted(String connectionId, long chatId, long[] messageIds) { - this.connectionId = connectionId; - this.chatId = chatId; - this.messageIds = messageIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1106703050; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new incoming inline query; for bots only. - */ - public static class UpdateNewInlineQuery extends Update { - /** - * Unique query identifier. - */ - public long id; - /** - * Identifier of the user who sent the query. - */ - public long senderUserId; - /** - * User location; may be null. - */ - @Nullable public Location userLocation; - /** - * The type of the chat from which the query originated; may be null if unknown. - */ - @Nullable public ChatType chatType; - /** - * Text of the query. - */ - public String query; - /** - * Offset of the first entry to return. - */ - public String offset; - - /** - * A new incoming inline query; for bots only. - */ - public UpdateNewInlineQuery() { - } - - /** - * A new incoming inline query; for bots only. - * - * @param id Unique query identifier. - * @param senderUserId Identifier of the user who sent the query. - * @param userLocation User location; may be null. - * @param chatType The type of the chat from which the query originated; may be null if unknown. - * @param query Text of the query. - * @param offset Offset of the first entry to return. - */ - public UpdateNewInlineQuery(long id, long senderUserId, Location userLocation, ChatType chatType, String query, String offset) { - this.id = id; - this.senderUserId = senderUserId; - this.userLocation = userLocation; - this.chatType = chatType; - this.query = query; - this.offset = offset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1903279924; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user has chosen a result of an inline query; for bots only. - */ - public static class UpdateNewChosenInlineResult extends Update { - /** - * Identifier of the user who sent the query. - */ - public long senderUserId; - /** - * User location; may be null. - */ - @Nullable public Location userLocation; - /** - * Text of the query. - */ - public String query; - /** - * Identifier of the chosen result. - */ - public String resultId; - /** - * Identifier of the sent inline message, if known. - */ - public String inlineMessageId; - - /** - * The user has chosen a result of an inline query; for bots only. - */ - public UpdateNewChosenInlineResult() { - } - - /** - * The user has chosen a result of an inline query; for bots only. - * - * @param senderUserId Identifier of the user who sent the query. - * @param userLocation User location; may be null. - * @param query Text of the query. - * @param resultId Identifier of the chosen result. - * @param inlineMessageId Identifier of the sent inline message, if known. - */ - public UpdateNewChosenInlineResult(long senderUserId, Location userLocation, String query, String resultId, String inlineMessageId) { - this.senderUserId = senderUserId; - this.userLocation = userLocation; - this.query = query; - this.resultId = resultId; - this.inlineMessageId = inlineMessageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -884191395; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new incoming callback query; for bots only. - */ - public static class UpdateNewCallbackQuery extends Update { - /** - * Unique query identifier. - */ - public long id; - /** - * Identifier of the user who sent the query. - */ - public long senderUserId; - /** - * Identifier of the chat where the query was sent. - */ - public long chatId; - /** - * Identifier of the message from which the query originated. - */ - public long messageId; - /** - * Identifier that uniquely corresponds to the chat to which the message was sent. - */ - public long chatInstance; - /** - * Query payload. - */ - public CallbackQueryPayload payload; - - /** - * A new incoming callback query; for bots only. - */ - public UpdateNewCallbackQuery() { - } - - /** - * A new incoming callback query; for bots only. - * - * @param id Unique query identifier. - * @param senderUserId Identifier of the user who sent the query. - * @param chatId Identifier of the chat where the query was sent. - * @param messageId Identifier of the message from which the query originated. - * @param chatInstance Identifier that uniquely corresponds to the chat to which the message was sent. - * @param payload Query payload. - */ - public UpdateNewCallbackQuery(long id, long senderUserId, long chatId, long messageId, long chatInstance, CallbackQueryPayload payload) { - this.id = id; - this.senderUserId = senderUserId; - this.chatId = chatId; - this.messageId = messageId; - this.chatInstance = chatInstance; - this.payload = payload; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1989881762; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new incoming callback query from a message sent via a bot; for bots only. - */ - public static class UpdateNewInlineCallbackQuery extends Update { - /** - * Unique query identifier. - */ - public long id; - /** - * Identifier of the user who sent the query. - */ - public long senderUserId; - /** - * Identifier of the inline message from which the query originated. - */ - public String inlineMessageId; - /** - * An identifier uniquely corresponding to the chat a message was sent to. - */ - public long chatInstance; - /** - * Query payload. - */ - public CallbackQueryPayload payload; - - /** - * A new incoming callback query from a message sent via a bot; for bots only. - */ - public UpdateNewInlineCallbackQuery() { - } - - /** - * A new incoming callback query from a message sent via a bot; for bots only. - * - * @param id Unique query identifier. - * @param senderUserId Identifier of the user who sent the query. - * @param inlineMessageId Identifier of the inline message from which the query originated. - * @param chatInstance An identifier uniquely corresponding to the chat a message was sent to. - * @param payload Query payload. - */ - public UpdateNewInlineCallbackQuery(long id, long senderUserId, String inlineMessageId, long chatInstance, CallbackQueryPayload payload) { - this.id = id; - this.senderUserId = senderUserId; - this.inlineMessageId = inlineMessageId; - this.chatInstance = chatInstance; - this.payload = payload; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -319212358; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new incoming callback query from a business message; for bots only. - */ - public static class UpdateNewBusinessCallbackQuery extends Update { - /** - * Unique query identifier. - */ - public long id; - /** - * Identifier of the user who sent the query. - */ - public long senderUserId; - /** - * Unique identifier of the business connection. - */ - public String connectionId; - /** - * The message from the business account from which the query originated. - */ - public BusinessMessage message; - /** - * An identifier uniquely corresponding to the chat a message was sent to. - */ - public long chatInstance; - /** - * Query payload. - */ - public CallbackQueryPayload payload; - - /** - * A new incoming callback query from a business message; for bots only. - */ - public UpdateNewBusinessCallbackQuery() { - } - - /** - * A new incoming callback query from a business message; for bots only. - * - * @param id Unique query identifier. - * @param senderUserId Identifier of the user who sent the query. - * @param connectionId Unique identifier of the business connection. - * @param message The message from the business account from which the query originated. - * @param chatInstance An identifier uniquely corresponding to the chat a message was sent to. - * @param payload Query payload. - */ - public UpdateNewBusinessCallbackQuery(long id, long senderUserId, String connectionId, BusinessMessage message, long chatInstance, CallbackQueryPayload payload) { - this.id = id; - this.senderUserId = senderUserId; - this.connectionId = connectionId; - this.message = message; - this.chatInstance = chatInstance; - this.payload = payload; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 336745316; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new incoming shipping query; for bots only. Only for invoices with flexible price. - */ - public static class UpdateNewShippingQuery extends Update { - /** - * Unique query identifier. - */ - public long id; - /** - * Identifier of the user who sent the query. - */ - public long senderUserId; - /** - * Invoice payload. - */ - public String invoicePayload; - /** - * User shipping address. - */ - public Address shippingAddress; - - /** - * A new incoming shipping query; for bots only. Only for invoices with flexible price. - */ - public UpdateNewShippingQuery() { - } - - /** - * A new incoming shipping query; for bots only. Only for invoices with flexible price. - * - * @param id Unique query identifier. - * @param senderUserId Identifier of the user who sent the query. - * @param invoicePayload Invoice payload. - * @param shippingAddress User shipping address. - */ - public UpdateNewShippingQuery(long id, long senderUserId, String invoicePayload, Address shippingAddress) { - this.id = id; - this.senderUserId = senderUserId; - this.invoicePayload = invoicePayload; - this.shippingAddress = shippingAddress; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 693651058; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new incoming pre-checkout query; for bots only. Contains full information about a checkout. - */ - public static class UpdateNewPreCheckoutQuery extends Update { - /** - * Unique query identifier. - */ - public long id; - /** - * Identifier of the user who sent the query. - */ - public long senderUserId; - /** - * Currency for the product price. - */ - public String currency; - /** - * Total price for the product, in the smallest units of the currency. - */ - public long totalAmount; - /** - * Invoice payload. - */ - public byte[] invoicePayload; - /** - * Identifier of a shipping option chosen by the user; may be empty if not applicable. - */ - public String shippingOptionId; - /** - * Information about the order; may be null. - */ - @Nullable public OrderInfo orderInfo; - - /** - * A new incoming pre-checkout query; for bots only. Contains full information about a checkout. - */ - public UpdateNewPreCheckoutQuery() { - } - - /** - * A new incoming pre-checkout query; for bots only. Contains full information about a checkout. - * - * @param id Unique query identifier. - * @param senderUserId Identifier of the user who sent the query. - * @param currency Currency for the product price. - * @param totalAmount Total price for the product, in the smallest units of the currency. - * @param invoicePayload Invoice payload. - * @param shippingOptionId Identifier of a shipping option chosen by the user; may be empty if not applicable. - * @param orderInfo Information about the order; may be null. - */ - public UpdateNewPreCheckoutQuery(long id, long senderUserId, String currency, long totalAmount, byte[] invoicePayload, String shippingOptionId, OrderInfo orderInfo) { - this.id = id; - this.senderUserId = senderUserId; - this.currency = currency; - this.totalAmount = totalAmount; - this.invoicePayload = invoicePayload; - this.shippingOptionId = shippingOptionId; - this.orderInfo = orderInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 708342217; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new incoming event; for bots only. - */ - public static class UpdateNewCustomEvent extends Update { - /** - * A JSON-serialized event. - */ - public String event; - - /** - * A new incoming event; for bots only. - */ - public UpdateNewCustomEvent() { - } - - /** - * A new incoming event; for bots only. - * - * @param event A JSON-serialized event. - */ - public UpdateNewCustomEvent(String event) { - this.event = event; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1994222092; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A new incoming query; for bots only. - */ - public static class UpdateNewCustomQuery extends Update { - /** - * The query identifier. - */ - public long id; - /** - * JSON-serialized query data. - */ - public String data; - /** - * Query timeout. - */ - public int timeout; - - /** - * A new incoming query; for bots only. - */ - public UpdateNewCustomQuery() { - } - - /** - * A new incoming query; for bots only. - * - * @param id The query identifier. - * @param data JSON-serialized query data. - * @param timeout Query timeout. - */ - public UpdateNewCustomQuery(long id, String data, int timeout) { - this.id = id; - this.data = data; - this.timeout = timeout; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -687670874; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A poll was updated; for bots only. - */ - public static class UpdatePoll extends Update { - /** - * New data about the poll. - */ - public Poll poll; - - /** - * A poll was updated; for bots only. - */ - public UpdatePoll() { - } - - /** - * A poll was updated; for bots only. - * - * @param poll New data about the poll. - */ - public UpdatePoll(Poll poll) { - this.poll = poll; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1771342902; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A user changed the answer to a poll; for bots only. - */ - public static class UpdatePollAnswer extends Update { - /** - * Unique poll identifier. - */ - public long pollId; - /** - * Identifier of the message sender that changed the answer to the poll. - */ - public MessageSender voterId; - /** - * 0-based identifiers of answer options, chosen by the user. - */ - public int[] optionIds; - - /** - * A user changed the answer to a poll; for bots only. - */ - public UpdatePollAnswer() { - } - - /** - * A user changed the answer to a poll; for bots only. - * - * @param pollId Unique poll identifier. - * @param voterId Identifier of the message sender that changed the answer to the poll. - * @param optionIds 0-based identifiers of answer options, chosen by the user. - */ - public UpdatePollAnswer(long pollId, MessageSender voterId, int[] optionIds) { - this.pollId = pollId; - this.voterId = voterId; - this.optionIds = optionIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1104905219; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * User rights changed in a chat; for bots only. - */ - public static class UpdateChatMember extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the user, changing the rights. - */ - public long actorUserId; - /** - * Point in time (Unix timestamp) when the user rights were changed. - */ - public int date; - /** - * If user has joined the chat using an invite link, the invite link; may be null. - */ - @Nullable public ChatInviteLink inviteLink; - /** - * True, if the user has joined the chat after sending a join request and being approved by an administrator. - */ - public boolean viaJoinRequest; - /** - * True, if the user has joined the chat using an invite link for a chat folder. - */ - public boolean viaChatFolderInviteLink; - /** - * Previous chat member. - */ - public ChatMember oldChatMember; - /** - * New chat member. - */ - public ChatMember newChatMember; - - /** - * User rights changed in a chat; for bots only. - */ - public UpdateChatMember() { - } - - /** - * User rights changed in a chat; for bots only. - * - * @param chatId Chat identifier. - * @param actorUserId Identifier of the user, changing the rights. - * @param date Point in time (Unix timestamp) when the user rights were changed. - * @param inviteLink If user has joined the chat using an invite link, the invite link; may be null. - * @param viaJoinRequest True, if the user has joined the chat after sending a join request and being approved by an administrator. - * @param viaChatFolderInviteLink True, if the user has joined the chat using an invite link for a chat folder. - * @param oldChatMember Previous chat member. - * @param newChatMember New chat member. - */ - public UpdateChatMember(long chatId, long actorUserId, int date, ChatInviteLink inviteLink, boolean viaJoinRequest, boolean viaChatFolderInviteLink, ChatMember oldChatMember, ChatMember newChatMember) { - this.chatId = chatId; - this.actorUserId = actorUserId; - this.date = date; - this.inviteLink = inviteLink; - this.viaJoinRequest = viaJoinRequest; - this.viaChatFolderInviteLink = viaChatFolderInviteLink; - this.oldChatMember = oldChatMember; - this.newChatMember = newChatMember; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1736025145; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A user sent a join request to a chat; for bots only. - */ - public static class UpdateNewChatJoinRequest extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Join request. - */ - public ChatJoinRequest request; - /** - * Chat identifier of the private chat with the user. - */ - public long userChatId; - /** - * The invite link, which was used to send join request; may be null. - */ - @Nullable public ChatInviteLink inviteLink; - - /** - * A user sent a join request to a chat; for bots only. - */ - public UpdateNewChatJoinRequest() { - } - - /** - * A user sent a join request to a chat; for bots only. - * - * @param chatId Chat identifier. - * @param request Join request. - * @param userChatId Chat identifier of the private chat with the user. - * @param inviteLink The invite link, which was used to send join request; may be null. - */ - public UpdateNewChatJoinRequest(long chatId, ChatJoinRequest request, long userChatId, ChatInviteLink inviteLink) { - this.chatId = chatId; - this.request = request; - this.userChatId = userChatId; - this.inviteLink = inviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2118694979; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A chat boost has changed; for bots only. - */ - public static class UpdateChatBoost extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * New information about the boost. - */ - public ChatBoost boost; - - /** - * A chat boost has changed; for bots only. - */ - public UpdateChatBoost() { - } - - /** - * A chat boost has changed; for bots only. - * - * @param chatId Chat identifier. - * @param boost New information about the boost. - */ - public UpdateChatBoost(long chatId, ChatBoost boost) { - this.chatId = chatId; - this.boost = boost; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1349680676; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * User changed its reactions on a message with public reactions; for bots only. - */ - public static class UpdateMessageReaction extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - /** - * Identifier of the user or chat that changed reactions. - */ - public MessageSender actorId; - /** - * Point in time (Unix timestamp) when the reactions were changed. - */ - public int date; - /** - * Old list of chosen reactions. - */ - public ReactionType[] oldReactionTypes; - /** - * New list of chosen reactions. - */ - public ReactionType[] newReactionTypes; - - /** - * User changed its reactions on a message with public reactions; for bots only. - */ - public UpdateMessageReaction() { - } - - /** - * User changed its reactions on a message with public reactions; for bots only. - * - * @param chatId Chat identifier. - * @param messageId Message identifier. - * @param actorId Identifier of the user or chat that changed reactions. - * @param date Point in time (Unix timestamp) when the reactions were changed. - * @param oldReactionTypes Old list of chosen reactions. - * @param newReactionTypes New list of chosen reactions. - */ - public UpdateMessageReaction(long chatId, long messageId, MessageSender actorId, int date, ReactionType[] oldReactionTypes, ReactionType[] newReactionTypes) { - this.chatId = chatId; - this.messageId = messageId; - this.actorId = actorId; - this.date = date; - this.oldReactionTypes = oldReactionTypes; - this.newReactionTypes = newReactionTypes; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1084895706; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Reactions added to a message with anonymous reactions have changed; for bots only. - */ - public static class UpdateMessageReactions extends Update { - /** - * Chat identifier. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - /** - * Point in time (Unix timestamp) when the reactions were changed. - */ - public int date; - /** - * The list of reactions added to the message. - */ - public MessageReaction[] reactions; - - /** - * Reactions added to a message with anonymous reactions have changed; for bots only. - */ - public UpdateMessageReactions() { - } - - /** - * Reactions added to a message with anonymous reactions have changed; for bots only. - * - * @param chatId Chat identifier. - * @param messageId Message identifier. - * @param date Point in time (Unix timestamp) when the reactions were changed. - * @param reactions The list of reactions added to the message. - */ - public UpdateMessageReactions(long chatId, long messageId, int date, MessageReaction[] reactions) { - this.chatId = chatId; - this.messageId = messageId; - this.date = date; - this.reactions = reactions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 955237189; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Paid media were purchased by a user; for bots only. - */ - public static class UpdatePaidMediaPurchased extends Update { - /** - * User identifier. - */ - public long userId; - /** - * Bot-specified payload for the paid media. - */ - public String payload; - - /** - * Paid media were purchased by a user; for bots only. - */ - public UpdatePaidMediaPurchased() { - } - - /** - * Paid media were purchased by a user; for bots only. - * - * @param userId User identifier. - * @param payload Bot-specified payload for the paid media. - */ - public UpdatePaidMediaPurchased(long userId, String payload) { - this.userId = userId; - this.payload = payload; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1542396325; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of updates. - */ - public static class Updates extends Object { - /** - * List of updates. - */ - public Update[] updates; - - /** - * Contains a list of updates. - */ - public Updates() { - } - - /** - * Contains a list of updates. - * - * @param updates List of updates. - */ - public Updates(Update[] updates) { - this.updates = updates; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 475842347; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains result of gift upgrading. - */ - public static class UpgradeGiftResult extends Object { - /** - * The upgraded gift. - */ - public UpgradedGift gift; - /** - * Unique identifier of the received gift for the current user. - */ - public String receivedGiftId; - /** - * True, if the gift is displayed on the user's or the channel's profile page. - */ - public boolean isSaved; - /** - * True, if the gift can be transferred to another owner. - */ - public boolean canBeTransferred; - /** - * Number of Telegram Stars that must be paid to transfer the upgraded gift. - */ - public long transferStarCount; - /** - * Number of Telegram Stars that must be paid to drop original details of the upgraded gift; 0 if not available. - */ - public long dropOriginalDetailsStarCount; - /** - * Point in time (Unix timestamp) when the gift can be transferred to another owner; can be in the past; 0 if the gift can be transferred immediately or transfer isn't possible. - */ - public int nextTransferDate; - /** - * Point in time (Unix timestamp) when the gift can be resold to another user; can be in the past; 0 if the gift can't be resold; only for the receiver of the gift. - */ - public int nextResaleDate; - /** - * Point in time (Unix timestamp) when the gift can be transferred to the TON blockchain as an NFT; can be in the past. - */ - public int exportDate; - - /** - * Contains result of gift upgrading. - */ - public UpgradeGiftResult() { - } - - /** - * Contains result of gift upgrading. - * - * @param gift The upgraded gift. - * @param receivedGiftId Unique identifier of the received gift for the current user. - * @param isSaved True, if the gift is displayed on the user's or the channel's profile page. - * @param canBeTransferred True, if the gift can be transferred to another owner. - * @param transferStarCount Number of Telegram Stars that must be paid to transfer the upgraded gift. - * @param dropOriginalDetailsStarCount Number of Telegram Stars that must be paid to drop original details of the upgraded gift; 0 if not available. - * @param nextTransferDate Point in time (Unix timestamp) when the gift can be transferred to another owner; can be in the past; 0 if the gift can be transferred immediately or transfer isn't possible. - * @param nextResaleDate Point in time (Unix timestamp) when the gift can be resold to another user; can be in the past; 0 if the gift can't be resold; only for the receiver of the gift. - * @param exportDate Point in time (Unix timestamp) when the gift can be transferred to the TON blockchain as an NFT; can be in the past. - */ - public UpgradeGiftResult(UpgradedGift gift, String receivedGiftId, boolean isSaved, boolean canBeTransferred, long transferStarCount, long dropOriginalDetailsStarCount, int nextTransferDate, int nextResaleDate, int exportDate) { - this.gift = gift; - this.receivedGiftId = receivedGiftId; - this.isSaved = isSaved; - this.canBeTransferred = canBeTransferred; - this.transferStarCount = transferStarCount; - this.dropOriginalDetailsStarCount = dropOriginalDetailsStarCount; - this.nextTransferDate = nextTransferDate; - this.nextResaleDate = nextResaleDate; - this.exportDate = exportDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 965145418; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an upgraded gift that can be transferred to another owner or transferred to the TON blockchain as an NFT. - */ - public static class UpgradedGift extends Object { - /** - * Unique identifier of the gift. - */ - public long id; - /** - * Unique identifier of the regular gift from which the gift was upgraded; may be 0 for short period of time for old gifts from database. - */ - public long regularGiftId; - /** - * Identifier of the chat that published the gift; 0 if none. - */ - public long publisherChatId; - /** - * The title of the upgraded gift. - */ - public String title; - /** - * Unique name of the upgraded gift that can be used with internalLinkTypeUpgradedGift or sendResoldGift. - */ - public String name; - /** - * Unique number of the upgraded gift among gifts upgraded from the same gift. - */ - public int number; - /** - * Total number of gifts that were upgraded from the same gift. - */ - public int totalUpgradedCount; - /** - * The maximum number of gifts that can be upgraded from the same gift. - */ - public int maxUpgradedCount; - /** - * True, if the gift was used to craft another gift. - */ - public boolean isBurned; - /** - * True, if the gift was craft from another gifts. - */ - public boolean isCrafted; - /** - * True, if the original gift could have been bought only by Telegram Premium subscribers. - */ - public boolean isPremium; - /** - * True, if the gift can be used to set a theme in a chat. - */ - public boolean isThemeAvailable; - /** - * Identifier of the chat for which the gift is used to set a theme; 0 if none or the gift isn't owned by the current user. - */ - public long usedThemeChatId; - /** - * Identifier of the user or the chat to which the upgraded gift was assigned from blockchain; may be null if none or unknown. - */ - @Nullable public MessageSender hostId; - /** - * Identifier of the user or the chat that owns the upgraded gift; may be null if none or unknown. - */ - @Nullable public MessageSender ownerId; - /** - * Address of the gift NFT owner in TON blockchain; may be empty if none. Append the address to getOption("ton_blockchain_explorer_url") to get a link with information about the address. - */ - public String ownerAddress; - /** - * Name of the owner for the case when owner identifier and address aren't known. - */ - public String ownerName; - /** - * Address of the gift NFT in TON blockchain; may be empty if none. Append the address to getOption("ton_blockchain_explorer_url") to get a link with information about the address. - */ - public String giftAddress; - /** - * Model of the upgraded gift. - */ - public UpgradedGiftModel model; - /** - * Symbol of the upgraded gift. - */ - public UpgradedGiftSymbol symbol; - /** - * Backdrop of the upgraded gift. - */ - public UpgradedGiftBackdrop backdrop; - /** - * Information about the originally sent gift; may be null if unknown. - */ - @Nullable public UpgradedGiftOriginalDetails originalDetails; - /** - * Colors that can be set for user's name, background of empty chat photo, replies to messages and link previews; may be null if none or unknown. - */ - @Nullable public UpgradedGiftColors colors; - /** - * Resale parameters of the gift; may be null if resale isn't possible. - */ - @Nullable public GiftResaleParameters resaleParameters; - /** - * True, if an offer to purchase the gift can be sent using sendGiftPurchaseOffer. - */ - public boolean canSendPurchaseOffer; - /** - * Probability that the gift adds to the chance of successful crafting of a new gift; 0 if the gift can't be used for crafting. - */ - public int craftProbabilityPerMille; - /** - * ISO 4217 currency code of the currency in which value of the gift is represented; may be empty if unavailable. - */ - public String valueCurrency; - /** - * Estimated value of the gift; in the smallest units of the currency; 0 if unavailable. - */ - public long valueAmount; - /** - * Estimated value of the gift in USD; in USD cents; 0 if unavailable. - */ - public long valueUsdAmount; - - /** - * Describes an upgraded gift that can be transferred to another owner or transferred to the TON blockchain as an NFT. - */ - public UpgradedGift() { - } - - /** - * Describes an upgraded gift that can be transferred to another owner or transferred to the TON blockchain as an NFT. - * - * @param id Unique identifier of the gift. - * @param regularGiftId Unique identifier of the regular gift from which the gift was upgraded; may be 0 for short period of time for old gifts from database. - * @param publisherChatId Identifier of the chat that published the gift; 0 if none. - * @param title The title of the upgraded gift. - * @param name Unique name of the upgraded gift that can be used with internalLinkTypeUpgradedGift or sendResoldGift. - * @param number Unique number of the upgraded gift among gifts upgraded from the same gift. - * @param totalUpgradedCount Total number of gifts that were upgraded from the same gift. - * @param maxUpgradedCount The maximum number of gifts that can be upgraded from the same gift. - * @param isBurned True, if the gift was used to craft another gift. - * @param isCrafted True, if the gift was craft from another gifts. - * @param isPremium True, if the original gift could have been bought only by Telegram Premium subscribers. - * @param isThemeAvailable True, if the gift can be used to set a theme in a chat. - * @param usedThemeChatId Identifier of the chat for which the gift is used to set a theme; 0 if none or the gift isn't owned by the current user. - * @param hostId Identifier of the user or the chat to which the upgraded gift was assigned from blockchain; may be null if none or unknown. - * @param ownerId Identifier of the user or the chat that owns the upgraded gift; may be null if none or unknown. - * @param ownerAddress Address of the gift NFT owner in TON blockchain; may be empty if none. Append the address to getOption("ton_blockchain_explorer_url") to get a link with information about the address. - * @param ownerName Name of the owner for the case when owner identifier and address aren't known. - * @param giftAddress Address of the gift NFT in TON blockchain; may be empty if none. Append the address to getOption("ton_blockchain_explorer_url") to get a link with information about the address. - * @param model Model of the upgraded gift. - * @param symbol Symbol of the upgraded gift. - * @param backdrop Backdrop of the upgraded gift. - * @param originalDetails Information about the originally sent gift; may be null if unknown. - * @param colors Colors that can be set for user's name, background of empty chat photo, replies to messages and link previews; may be null if none or unknown. - * @param resaleParameters Resale parameters of the gift; may be null if resale isn't possible. - * @param canSendPurchaseOffer True, if an offer to purchase the gift can be sent using sendGiftPurchaseOffer. - * @param craftProbabilityPerMille Probability that the gift adds to the chance of successful crafting of a new gift; 0 if the gift can't be used for crafting. - * @param valueCurrency ISO 4217 currency code of the currency in which value of the gift is represented; may be empty if unavailable. - * @param valueAmount Estimated value of the gift; in the smallest units of the currency; 0 if unavailable. - * @param valueUsdAmount Estimated value of the gift in USD; in USD cents; 0 if unavailable. - */ - public UpgradedGift(long id, long regularGiftId, long publisherChatId, String title, String name, int number, int totalUpgradedCount, int maxUpgradedCount, boolean isBurned, boolean isCrafted, boolean isPremium, boolean isThemeAvailable, long usedThemeChatId, MessageSender hostId, MessageSender ownerId, String ownerAddress, String ownerName, String giftAddress, UpgradedGiftModel model, UpgradedGiftSymbol symbol, UpgradedGiftBackdrop backdrop, UpgradedGiftOriginalDetails originalDetails, UpgradedGiftColors colors, GiftResaleParameters resaleParameters, boolean canSendPurchaseOffer, int craftProbabilityPerMille, String valueCurrency, long valueAmount, long valueUsdAmount) { - this.id = id; - this.regularGiftId = regularGiftId; - this.publisherChatId = publisherChatId; - this.title = title; - this.name = name; - this.number = number; - this.totalUpgradedCount = totalUpgradedCount; - this.maxUpgradedCount = maxUpgradedCount; - this.isBurned = isBurned; - this.isCrafted = isCrafted; - this.isPremium = isPremium; - this.isThemeAvailable = isThemeAvailable; - this.usedThemeChatId = usedThemeChatId; - this.hostId = hostId; - this.ownerId = ownerId; - this.ownerAddress = ownerAddress; - this.ownerName = ownerName; - this.giftAddress = giftAddress; - this.model = model; - this.symbol = symbol; - this.backdrop = backdrop; - this.originalDetails = originalDetails; - this.colors = colors; - this.resaleParameters = resaleParameters; - this.canSendPurchaseOffer = canSendPurchaseOffer; - this.craftProbabilityPerMille = craftProbabilityPerMille; - this.valueCurrency = valueCurrency; - this.valueAmount = valueAmount; - this.valueUsdAmount = valueUsdAmount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 239775652; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Contains identifier of an upgraded gift attribute to search for. - */ - public abstract static class UpgradedGiftAttributeId extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - UpgradedGiftAttributeIdModel.CONSTRUCTOR, - UpgradedGiftAttributeIdSymbol.CONSTRUCTOR, - UpgradedGiftAttributeIdBackdrop.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public UpgradedGiftAttributeId() { - } - } - - /** - * Identifier of a gift model. - */ - public static class UpgradedGiftAttributeIdModel extends UpgradedGiftAttributeId { - /** - * Identifier of the sticker representing the model. - */ - public long stickerId; - - /** - * Identifier of a gift model. - */ - public UpgradedGiftAttributeIdModel() { - } - - /** - * Identifier of a gift model. - * - * @param stickerId Identifier of the sticker representing the model. - */ - public UpgradedGiftAttributeIdModel(long stickerId) { - this.stickerId = stickerId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1053287307; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Identifier of a gift symbol. - */ - public static class UpgradedGiftAttributeIdSymbol extends UpgradedGiftAttributeId { - /** - * Identifier of the sticker representing the symbol. - */ - public long stickerId; - - /** - * Identifier of a gift symbol. - */ - public UpgradedGiftAttributeIdSymbol() { - } - - /** - * Identifier of a gift symbol. - * - * @param stickerId Identifier of the sticker representing the symbol. - */ - public UpgradedGiftAttributeIdSymbol(long stickerId) { - this.stickerId = stickerId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1188205608; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Identifier of a gift backdrop. - */ - public static class UpgradedGiftAttributeIdBackdrop extends UpgradedGiftAttributeId { - /** - * Identifier of the backdrop. - */ - public int backdropId; - - /** - * Identifier of a gift backdrop. - */ - public UpgradedGiftAttributeIdBackdrop() { - } - - /** - * Identifier of a gift backdrop. - * - * @param backdropId Identifier of the backdrop. - */ - public UpgradedGiftAttributeIdBackdrop(int backdropId) { - this.backdropId = backdropId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1461997935; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes rarity of an upgraded gift attribute. - */ - public abstract static class UpgradedGiftAttributeRarity extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - UpgradedGiftAttributeRarityPerMille.CONSTRUCTOR, - UpgradedGiftAttributeRarityUncommon.CONSTRUCTOR, - UpgradedGiftAttributeRarityRare.CONSTRUCTOR, - UpgradedGiftAttributeRarityEpic.CONSTRUCTOR, - UpgradedGiftAttributeRarityLegendary.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public UpgradedGiftAttributeRarity() { - } - } - - /** - * The rarity is represented as the numeric frequence of the model. - */ - public static class UpgradedGiftAttributeRarityPerMille extends UpgradedGiftAttributeRarity { - /** - * The number of upgraded gifts that receive this attribute for each 1000 gifts upgraded; if 0, then it can be shown as "<0.1%". - */ - public int perMille; - - /** - * The rarity is represented as the numeric frequence of the model. - */ - public UpgradedGiftAttributeRarityPerMille() { - } - - /** - * The rarity is represented as the numeric frequence of the model. - * - * @param perMille The number of upgraded gifts that receive this attribute for each 1000 gifts upgraded; if 0, then it can be shown as "<0.1%". - */ - public UpgradedGiftAttributeRarityPerMille(int perMille) { - this.perMille = perMille; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1306052575; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The attribute is uncommon. - */ - public static class UpgradedGiftAttributeRarityUncommon extends UpgradedGiftAttributeRarity { - - /** - * The attribute is uncommon. - */ - public UpgradedGiftAttributeRarityUncommon() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -203711025; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The attribute is rare. - */ - public static class UpgradedGiftAttributeRarityRare extends UpgradedGiftAttributeRarity { - - /** - * The attribute is rare. - */ - public UpgradedGiftAttributeRarityRare() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1676142893; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The attribute is epic. - */ - public static class UpgradedGiftAttributeRarityEpic extends UpgradedGiftAttributeRarity { - - /** - * The attribute is epic. - */ - public UpgradedGiftAttributeRarityEpic() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1206252713; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The attribute is legendary. - */ - public static class UpgradedGiftAttributeRarityLegendary extends UpgradedGiftAttributeRarity { - - /** - * The attribute is legendary. - */ - public UpgradedGiftAttributeRarityLegendary() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 85089455; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a backdrop of an upgraded gift. - */ - public static class UpgradedGiftBackdrop extends Object { - /** - * Unique identifier of the backdrop. - */ - public int id; - /** - * Name of the backdrop. - */ - public String name; - /** - * Colors of the backdrop. - */ - public UpgradedGiftBackdropColors colors; - /** - * The rarity of the backdrop. - */ - public UpgradedGiftAttributeRarity rarity; - - /** - * Describes a backdrop of an upgraded gift. - */ - public UpgradedGiftBackdrop() { - } - - /** - * Describes a backdrop of an upgraded gift. - * - * @param id Unique identifier of the backdrop. - * @param name Name of the backdrop. - * @param colors Colors of the backdrop. - * @param rarity The rarity of the backdrop. - */ - public UpgradedGiftBackdrop(int id, String name, UpgradedGiftBackdropColors colors, UpgradedGiftAttributeRarity rarity) { - this.id = id; - this.name = name; - this.colors = colors; - this.rarity = rarity; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -775752215; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes colors of a backdrop of an upgraded gift. - */ - public static class UpgradedGiftBackdropColors extends Object { - /** - * A color in the center of the backdrop in the RGB format. - */ - public int centerColor; - /** - * A color on the edges of the backdrop in the RGB format. - */ - public int edgeColor; - /** - * A color to be applied for the symbol in the RGB format. - */ - public int symbolColor; - /** - * A color for the text on the backdrop in the RGB format. - */ - public int textColor; - - /** - * Describes colors of a backdrop of an upgraded gift. - */ - public UpgradedGiftBackdropColors() { - } - - /** - * Describes colors of a backdrop of an upgraded gift. - * - * @param centerColor A color in the center of the backdrop in the RGB format. - * @param edgeColor A color on the edges of the backdrop in the RGB format. - * @param symbolColor A color to be applied for the symbol in the RGB format. - * @param textColor A color for the text on the backdrop in the RGB format. - */ - public UpgradedGiftBackdropColors(int centerColor, int edgeColor, int symbolColor, int textColor) { - this.centerColor = centerColor; - this.edgeColor = edgeColor; - this.symbolColor = symbolColor; - this.textColor = textColor; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 4227529; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a backdrop of an upgraded gift. - */ - public static class UpgradedGiftBackdropCount extends Object { - /** - * The backdrop. - */ - public UpgradedGiftBackdrop backdrop; - /** - * Total number of gifts with the symbol. - */ - public int totalCount; - - /** - * Describes a backdrop of an upgraded gift. - */ - public UpgradedGiftBackdropCount() { - } - - /** - * Describes a backdrop of an upgraded gift. - * - * @param backdrop The backdrop. - * @param totalCount Total number of gifts with the symbol. - */ - public UpgradedGiftBackdropCount(UpgradedGiftBackdrop backdrop, int totalCount) { - this.backdrop = backdrop; - this.totalCount = totalCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -562274120; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about color scheme for user's name, background of empty chat photo, replies to messages and link previews. - */ - public static class UpgradedGiftColors extends Object { - /** - * Unique identifier of the upgraded gift colors. - */ - public long id; - /** - * Custom emoji identifier of the model of the upgraded gift. - */ - public long modelCustomEmojiId; - /** - * Custom emoji identifier of the symbol of the upgraded gift. - */ - public long symbolCustomEmojiId; - /** - * Accent color to use in light themes in RGB format. - */ - public int lightThemeAccentColor; - /** - * The list of 1-3 colors in RGB format, describing the accent color, as expected to be shown in light themes. - */ - public int[] lightThemeColors; - /** - * Accent color to use in dark themes in RGB format. - */ - public int darkThemeAccentColor; - /** - * The list of 1-3 colors in RGB format, describing the accent color, as expected to be shown in dark themes. - */ - public int[] darkThemeColors; - - /** - * Contains information about color scheme for user's name, background of empty chat photo, replies to messages and link previews. - */ - public UpgradedGiftColors() { - } - - /** - * Contains information about color scheme for user's name, background of empty chat photo, replies to messages and link previews. - * - * @param id Unique identifier of the upgraded gift colors. - * @param modelCustomEmojiId Custom emoji identifier of the model of the upgraded gift. - * @param symbolCustomEmojiId Custom emoji identifier of the symbol of the upgraded gift. - * @param lightThemeAccentColor Accent color to use in light themes in RGB format. - * @param lightThemeColors The list of 1-3 colors in RGB format, describing the accent color, as expected to be shown in light themes. - * @param darkThemeAccentColor Accent color to use in dark themes in RGB format. - * @param darkThemeColors The list of 1-3 colors in RGB format, describing the accent color, as expected to be shown in dark themes. - */ - public UpgradedGiftColors(long id, long modelCustomEmojiId, long symbolCustomEmojiId, int lightThemeAccentColor, int[] lightThemeColors, int darkThemeAccentColor, int[] darkThemeColors) { - this.id = id; - this.modelCustomEmojiId = modelCustomEmojiId; - this.symbolCustomEmojiId = symbolCustomEmojiId; - this.lightThemeAccentColor = lightThemeAccentColor; - this.lightThemeColors = lightThemeColors; - this.darkThemeAccentColor = darkThemeAccentColor; - this.darkThemeColors = darkThemeColors; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 743567702; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a model of an upgraded gift. - */ - public static class UpgradedGiftModel extends Object { - /** - * Name of the model. - */ - public String name; - /** - * The sticker representing the upgraded gift. - */ - public Sticker sticker; - /** - * The rarity of the model. - */ - public UpgradedGiftAttributeRarity rarity; - /** - * True, if the model can be obtained only through gift crafting. - */ - public boolean isCrafted; - - /** - * Describes a model of an upgraded gift. - */ - public UpgradedGiftModel() { - } - - /** - * Describes a model of an upgraded gift. - * - * @param name Name of the model. - * @param sticker The sticker representing the upgraded gift. - * @param rarity The rarity of the model. - * @param isCrafted True, if the model can be obtained only through gift crafting. - */ - public UpgradedGiftModel(String name, Sticker sticker, UpgradedGiftAttributeRarity rarity, boolean isCrafted) { - this.name = name; - this.sticker = sticker; - this.rarity = rarity; - this.isCrafted = isCrafted; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1451554959; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a model of an upgraded gift with the number of gifts found. - */ - public static class UpgradedGiftModelCount extends Object { - /** - * The model. - */ - public UpgradedGiftModel model; - /** - * Total number of gifts with the model. - */ - public int totalCount; - - /** - * Describes a model of an upgraded gift with the number of gifts found. - */ - public UpgradedGiftModelCount() { - } - - /** - * Describes a model of an upgraded gift with the number of gifts found. - * - * @param model The model. - * @param totalCount Total number of gifts with the model. - */ - public UpgradedGiftModelCount(UpgradedGiftModel model, int totalCount) { - this.model = model; - this.totalCount = totalCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1127238023; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes origin from which the upgraded gift was obtained. - */ - public abstract static class UpgradedGiftOrigin extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - UpgradedGiftOriginUpgrade.CONSTRUCTOR, - UpgradedGiftOriginTransfer.CONSTRUCTOR, - UpgradedGiftOriginResale.CONSTRUCTOR, - UpgradedGiftOriginBlockchain.CONSTRUCTOR, - UpgradedGiftOriginPrepaidUpgrade.CONSTRUCTOR, - UpgradedGiftOriginOffer.CONSTRUCTOR, - UpgradedGiftOriginCraft.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public UpgradedGiftOrigin() { - } - } - - /** - * The gift was obtained by upgrading of a previously received gift. - */ - public static class UpgradedGiftOriginUpgrade extends UpgradedGiftOrigin { - /** - * Identifier of the message with the regular gift that was upgraded; may be 0 or an identifier of a deleted message. - */ - public long giftMessageId; - - /** - * The gift was obtained by upgrading of a previously received gift. - */ - public UpgradedGiftOriginUpgrade() { - } - - /** - * The gift was obtained by upgrading of a previously received gift. - * - * @param giftMessageId Identifier of the message with the regular gift that was upgraded; may be 0 or an identifier of a deleted message. - */ - public UpgradedGiftOriginUpgrade(long giftMessageId) { - this.giftMessageId = giftMessageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 530003363; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The gift was transferred from another owner. - */ - public static class UpgradedGiftOriginTransfer extends UpgradedGiftOrigin { - - /** - * The gift was transferred from another owner. - */ - public UpgradedGiftOriginTransfer() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 331458658; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The gift was bought from another user. - */ - public static class UpgradedGiftOriginResale extends UpgradedGiftOrigin { - /** - * Price paid for the gift. - */ - public GiftResalePrice price; - - /** - * The gift was bought from another user. - */ - public UpgradedGiftOriginResale() { - } - - /** - * The gift was bought from another user. - * - * @param price Price paid for the gift. - */ - public UpgradedGiftOriginResale(GiftResalePrice price) { - this.price = price; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -989020635; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The gift was assigned from blockchain and isn't owned by the current user. The gift can't be transferred, resold or withdrawn to blockchain. - */ - public static class UpgradedGiftOriginBlockchain extends UpgradedGiftOrigin { - - /** - * The gift was assigned from blockchain and isn't owned by the current user. The gift can't be transferred, resold or withdrawn to blockchain. - */ - public UpgradedGiftOriginBlockchain() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2133095888; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The sender or receiver of the message has paid for upgraid of the gift, which has been completed. - */ - public static class UpgradedGiftOriginPrepaidUpgrade extends UpgradedGiftOrigin { - - /** - * The sender or receiver of the message has paid for upgraid of the gift, which has been completed. - */ - public UpgradedGiftOriginPrepaidUpgrade() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 619653731; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The gift was bought through an offer. - */ - public static class UpgradedGiftOriginOffer extends UpgradedGiftOrigin { - /** - * Price paid for the gift. - */ - public GiftResalePrice price; - - /** - * The gift was bought through an offer. - */ - public UpgradedGiftOriginOffer() { - } - - /** - * The gift was bought through an offer. - * - * @param price Price paid for the gift. - */ - public UpgradedGiftOriginOffer(GiftResalePrice price) { - this.price = price; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -182289662; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The gift was crafted from other gifts. - */ - public static class UpgradedGiftOriginCraft extends UpgradedGiftOrigin { - - /** - * The gift was crafted from other gifts. - */ - public UpgradedGiftOriginCraft() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1827738024; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes the original details about the gift. - */ - public static class UpgradedGiftOriginalDetails extends Object { - /** - * Identifier of the user or the chat that sent the gift; may be null if the gift was private. - */ - @Nullable public MessageSender senderId; - /** - * Identifier of the user or the chat that received the gift. - */ - public MessageSender receiverId; - /** - * Message added to the gift. - */ - public FormattedText text; - /** - * Point in time (Unix timestamp) when the gift was sent. - */ - public int date; - - /** - * Describes the original details about the gift. - */ - public UpgradedGiftOriginalDetails() { - } - - /** - * Describes the original details about the gift. - * - * @param senderId Identifier of the user or the chat that sent the gift; may be null if the gift was private. - * @param receiverId Identifier of the user or the chat that received the gift. - * @param text Message added to the gift. - * @param date Point in time (Unix timestamp) when the gift was sent. - */ - public UpgradedGiftOriginalDetails(MessageSender senderId, MessageSender receiverId, FormattedText text, int date) { - this.senderId = senderId; - this.receiverId = receiverId; - this.text = text; - this.date = date; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 55247728; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a symbol shown on the pattern of an upgraded gift. - */ - public static class UpgradedGiftSymbol extends Object { - /** - * Name of the symbol. - */ - public String name; - /** - * The sticker representing the symbol. - */ - public Sticker sticker; - /** - * The rarity of the symbol. - */ - public UpgradedGiftAttributeRarity rarity; - - /** - * Describes a symbol shown on the pattern of an upgraded gift. - */ - public UpgradedGiftSymbol() { - } - - /** - * Describes a symbol shown on the pattern of an upgraded gift. - * - * @param name Name of the symbol. - * @param sticker The sticker representing the symbol. - * @param rarity The rarity of the symbol. - */ - public UpgradedGiftSymbol(String name, Sticker sticker, UpgradedGiftAttributeRarity rarity) { - this.name = name; - this.sticker = sticker; - this.rarity = rarity; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 744249151; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a symbol shown on the pattern of an upgraded gift. - */ - public static class UpgradedGiftSymbolCount extends Object { - /** - * The symbol. - */ - public UpgradedGiftSymbol symbol; - /** - * Total number of gifts with the symbol. - */ - public int totalCount; - - /** - * Describes a symbol shown on the pattern of an upgraded gift. - */ - public UpgradedGiftSymbolCount() { - } - - /** - * Describes a symbol shown on the pattern of an upgraded gift. - * - * @param symbol The symbol. - * @param totalCount Total number of gifts with the symbol. - */ - public UpgradedGiftSymbolCount(UpgradedGiftSymbol symbol, int totalCount) { - this.symbol = symbol; - this.totalCount = totalCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -773579874; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about value of an upgraded gift. - */ - public static class UpgradedGiftValueInfo extends Object { - /** - * ISO 4217 currency code of the currency in which the prices are represented. - */ - public String currency; - /** - * Estimated value of the gift; in the smallest units of the currency. - */ - public long value; - /** - * True, if the value is calculated as average value of similar sold gifts. Otherwise, it is based on the sale price of the gift. - */ - public boolean isValueAverage; - /** - * Point in time (Unix timestamp) when the corresponding regular gift was originally purchased. - */ - public int initialSaleDate; - /** - * The Telegram Star amount that was paid for the gift. - */ - public long initialSaleStarCount; - /** - * Initial price of the gift; in the smallest units of the currency. - */ - public long initialSalePrice; - /** - * Point in time (Unix timestamp) when the upgraded gift was purchased last time; 0 if never. - */ - public int lastSaleDate; - /** - * Last purchase price of the gift; in the smallest units of the currency; 0 if the gift has never been resold. - */ - public long lastSalePrice; - /** - * True, if the last sale was completed on Fragment. - */ - public boolean isLastSaleOnFragment; - /** - * The current minimum price of gifts upgraded from the same gift; in the smallest units of the currency; 0 if there are no such gifts. - */ - public long minimumPrice; - /** - * The average sale price in the last month of gifts upgraded from the same gift; in the smallest units of the currency; 0 if there were no such sales. - */ - public long averageSalePrice; - /** - * Number of gifts upgraded from the same gift being resold on Telegram. - */ - public int telegramListedGiftCount; - /** - * Number of gifts upgraded from the same gift being resold on Fragment. - */ - public int fragmentListedGiftCount; - /** - * The HTTPS link to the Fragment for the gift; may be empty if there are no such gifts being sold on Fragment. - */ - public String fragmentUrl; - - /** - * Contains information about value of an upgraded gift. - */ - public UpgradedGiftValueInfo() { - } - - /** - * Contains information about value of an upgraded gift. - * - * @param currency ISO 4217 currency code of the currency in which the prices are represented. - * @param value Estimated value of the gift; in the smallest units of the currency. - * @param isValueAverage True, if the value is calculated as average value of similar sold gifts. Otherwise, it is based on the sale price of the gift. - * @param initialSaleDate Point in time (Unix timestamp) when the corresponding regular gift was originally purchased. - * @param initialSaleStarCount The Telegram Star amount that was paid for the gift. - * @param initialSalePrice Initial price of the gift; in the smallest units of the currency. - * @param lastSaleDate Point in time (Unix timestamp) when the upgraded gift was purchased last time; 0 if never. - * @param lastSalePrice Last purchase price of the gift; in the smallest units of the currency; 0 if the gift has never been resold. - * @param isLastSaleOnFragment True, if the last sale was completed on Fragment. - * @param minimumPrice The current minimum price of gifts upgraded from the same gift; in the smallest units of the currency; 0 if there are no such gifts. - * @param averageSalePrice The average sale price in the last month of gifts upgraded from the same gift; in the smallest units of the currency; 0 if there were no such sales. - * @param telegramListedGiftCount Number of gifts upgraded from the same gift being resold on Telegram. - * @param fragmentListedGiftCount Number of gifts upgraded from the same gift being resold on Fragment. - * @param fragmentUrl The HTTPS link to the Fragment for the gift; may be empty if there are no such gifts being sold on Fragment. - */ - public UpgradedGiftValueInfo(String currency, long value, boolean isValueAverage, int initialSaleDate, long initialSaleStarCount, long initialSalePrice, int lastSaleDate, long lastSalePrice, boolean isLastSaleOnFragment, long minimumPrice, long averageSalePrice, int telegramListedGiftCount, int fragmentListedGiftCount, String fragmentUrl) { - this.currency = currency; - this.value = value; - this.isValueAverage = isValueAverage; - this.initialSaleDate = initialSaleDate; - this.initialSaleStarCount = initialSaleStarCount; - this.initialSalePrice = initialSalePrice; - this.lastSaleDate = lastSaleDate; - this.lastSalePrice = lastSalePrice; - this.isLastSaleOnFragment = isLastSaleOnFragment; - this.minimumPrice = minimumPrice; - this.averageSalePrice = averageSalePrice; - this.telegramListedGiftCount = telegramListedGiftCount; - this.fragmentListedGiftCount = fragmentListedGiftCount; - this.fragmentUrl = fragmentUrl; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1729877677; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a user. - */ - public static class User extends Object { - /** - * User identifier. - */ - public long id; - /** - * First name of the user. - */ - public String firstName; - /** - * Last name of the user. - */ - public String lastName; - /** - * Usernames of the user; may be null. - */ - @Nullable public Usernames usernames; - /** - * Phone number of the user. - */ - public String phoneNumber; - /** - * Current online status of the user. - */ - public UserStatus status; - /** - * Profile photo of the user; may be null. - */ - @Nullable public ProfilePhoto profilePhoto; - /** - * Identifier of the accent color for name, and backgrounds of profile photo, reply header, and link preview. - */ - public int accentColorId; - /** - * Identifier of a custom emoji to be shown on the reply header and link preview background; 0 if none. - */ - public long backgroundCustomEmojiId; - /** - * Color scheme based on an upgraded gift to be used for the user instead of accentColorId and backgroundCustomEmojiId; may be null if none. - */ - @Nullable public UpgradedGiftColors upgradedGiftColors; - /** - * Identifier of the accent color for the user's profile; -1 if none. - */ - public int profileAccentColorId; - /** - * Identifier of a custom emoji to be shown on the background of the user's profile; 0 if none. - */ - public long profileBackgroundCustomEmojiId; - /** - * Emoji status to be shown instead of the default Telegram Premium badge; may be null. - */ - @Nullable public EmojiStatus emojiStatus; - /** - * The user is a contact of the current user. - */ - public boolean isContact; - /** - * The user is a contact of the current user and the current user is a contact of the user. - */ - public boolean isMutualContact; - /** - * The user is a close friend of the current user; implies that the user is a contact. - */ - public boolean isCloseFriend; - /** - * Information about verification status of the user; may be null if none. - */ - @Nullable public VerificationStatus verificationStatus; - /** - * True, if the user is a Telegram Premium user. - */ - public boolean isPremium; - /** - * True, if the user is Telegram support account. - */ - public boolean isSupport; - /** - * Information about restrictions that must be applied to the corresponding private chat; may be null if none. - */ - @Nullable public RestrictionInfo restrictionInfo; - /** - * State of active stories of the user; may be null if the user has no active stories. - */ - @Nullable public ActiveStoryState activeStoryState; - /** - * True, if the user may restrict new chats with non-contacts. Use canSendMessageToUser to check whether the current user can message the user or try to create a chat with them. - */ - public boolean restrictsNewChats; - /** - * Number of Telegram Stars that must be paid by general user for each sent message to the user. If positive and userFullInfo is unknown, use canSendMessageToUser to check whether the current user must pay. - */ - public long paidMessageStarCount; - /** - * If false, the user is inaccessible, and the only information known about the user is inside this class. Identifier of the user can't be passed to any method. - */ - public boolean haveAccess; - /** - * Type of the user. - */ - public UserType type; - /** - * IETF language tag of the user's language; only available to bots. - */ - public String languageCode; - /** - * True, if the user added the current bot to attachment menu; only available to bots. - */ - public boolean addedToAttachmentMenu; - - /** - * Represents a user. - */ - public User() { - } - - /** - * Represents a user. - * - * @param id User identifier. - * @param firstName First name of the user. - * @param lastName Last name of the user. - * @param usernames Usernames of the user; may be null. - * @param phoneNumber Phone number of the user. - * @param status Current online status of the user. - * @param profilePhoto Profile photo of the user; may be null. - * @param accentColorId Identifier of the accent color for name, and backgrounds of profile photo, reply header, and link preview. - * @param backgroundCustomEmojiId Identifier of a custom emoji to be shown on the reply header and link preview background; 0 if none. - * @param upgradedGiftColors Color scheme based on an upgraded gift to be used for the user instead of accentColorId and backgroundCustomEmojiId; may be null if none. - * @param profileAccentColorId Identifier of the accent color for the user's profile; -1 if none. - * @param profileBackgroundCustomEmojiId Identifier of a custom emoji to be shown on the background of the user's profile; 0 if none. - * @param emojiStatus Emoji status to be shown instead of the default Telegram Premium badge; may be null. - * @param isContact The user is a contact of the current user. - * @param isMutualContact The user is a contact of the current user and the current user is a contact of the user. - * @param isCloseFriend The user is a close friend of the current user; implies that the user is a contact. - * @param verificationStatus Information about verification status of the user; may be null if none. - * @param isPremium True, if the user is a Telegram Premium user. - * @param isSupport True, if the user is Telegram support account. - * @param restrictionInfo Information about restrictions that must be applied to the corresponding private chat; may be null if none. - * @param activeStoryState State of active stories of the user; may be null if the user has no active stories. - * @param restrictsNewChats True, if the user may restrict new chats with non-contacts. Use canSendMessageToUser to check whether the current user can message the user or try to create a chat with them. - * @param paidMessageStarCount Number of Telegram Stars that must be paid by general user for each sent message to the user. If positive and userFullInfo is unknown, use canSendMessageToUser to check whether the current user must pay. - * @param haveAccess If false, the user is inaccessible, and the only information known about the user is inside this class. Identifier of the user can't be passed to any method. - * @param type Type of the user. - * @param languageCode IETF language tag of the user's language; only available to bots. - * @param addedToAttachmentMenu True, if the user added the current bot to attachment menu; only available to bots. - */ - public User(long id, String firstName, String lastName, Usernames usernames, String phoneNumber, UserStatus status, ProfilePhoto profilePhoto, int accentColorId, long backgroundCustomEmojiId, UpgradedGiftColors upgradedGiftColors, int profileAccentColorId, long profileBackgroundCustomEmojiId, EmojiStatus emojiStatus, boolean isContact, boolean isMutualContact, boolean isCloseFriend, VerificationStatus verificationStatus, boolean isPremium, boolean isSupport, RestrictionInfo restrictionInfo, ActiveStoryState activeStoryState, boolean restrictsNewChats, long paidMessageStarCount, boolean haveAccess, UserType type, String languageCode, boolean addedToAttachmentMenu) { - this.id = id; - this.firstName = firstName; - this.lastName = lastName; - this.usernames = usernames; - this.phoneNumber = phoneNumber; - this.status = status; - this.profilePhoto = profilePhoto; - this.accentColorId = accentColorId; - this.backgroundCustomEmojiId = backgroundCustomEmojiId; - this.upgradedGiftColors = upgradedGiftColors; - this.profileAccentColorId = profileAccentColorId; - this.profileBackgroundCustomEmojiId = profileBackgroundCustomEmojiId; - this.emojiStatus = emojiStatus; - this.isContact = isContact; - this.isMutualContact = isMutualContact; - this.isCloseFriend = isCloseFriend; - this.verificationStatus = verificationStatus; - this.isPremium = isPremium; - this.isSupport = isSupport; - this.restrictionInfo = restrictionInfo; - this.activeStoryState = activeStoryState; - this.restrictsNewChats = restrictsNewChats; - this.paidMessageStarCount = paidMessageStarCount; - this.haveAccess = haveAccess; - this.type = type; - this.languageCode = languageCode; - this.addedToAttachmentMenu = addedToAttachmentMenu; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1874921182; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a bid of the current user in an auction. - */ - public static class UserAuctionBid extends Object { - /** - * The number of Telegram Stars that were put in the bid. - */ - public long starCount; - /** - * Point in time (Unix timestamp) when the bid was made. - */ - public int bidDate; - /** - * The minimum number of Telegram Stars that can be put for the next bid. - */ - public long nextBidStarCount; - /** - * Identifier of the user or the chat that will receive the auctioned item. If the auction is opened in context of another user or chat, then a warning is supposed to be shown to the current user. - */ - public MessageSender ownerId; - /** - * True, if the bid was returned to the user, because it was outbid and can't win anymore. - */ - public boolean wasReturned; - - /** - * Describes a bid of the current user in an auction. - */ - public UserAuctionBid() { - } - - /** - * Describes a bid of the current user in an auction. - * - * @param starCount The number of Telegram Stars that were put in the bid. - * @param bidDate Point in time (Unix timestamp) when the bid was made. - * @param nextBidStarCount The minimum number of Telegram Stars that can be put for the next bid. - * @param ownerId Identifier of the user or the chat that will receive the auctioned item. If the auction is opened in context of another user or chat, then a warning is supposed to be shown to the current user. - * @param wasReturned True, if the bid was returned to the user, because it was outbid and can't win anymore. - */ - public UserAuctionBid(long starCount, int bidDate, long nextBidStarCount, MessageSender ownerId, boolean wasReturned) { - this.starCount = starCount; - this.bidDate = bidDate; - this.nextBidStarCount = nextBidStarCount; - this.ownerId = ownerId; - this.wasReturned = wasReturned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 538448225; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains full information about a user. - */ - public static class UserFullInfo extends Object { - /** - * User profile photo set by the current user for the contact; may be null. If null and user.profilePhoto is null, then the photo is empty; otherwise, it is unknown. If non-null, then it is the same photo as in user.profilePhoto and chat.photo. This photo isn't returned in the list of user photos. - */ - @Nullable public ChatPhoto personalPhoto; - /** - * User profile photo; may be null. If null and user.profilePhoto is null, then the photo is empty; otherwise, it is unknown. If non-null and personalPhoto is null, then it is the same photo as in user.profilePhoto and chat.photo. - */ - @Nullable public ChatPhoto photo; - /** - * User profile photo visible if the main photo is hidden by privacy settings; may be null. If null and user.profilePhoto is null, then the photo is empty; otherwise, it is unknown. If non-null and both photo and personalPhoto are null, then it is the same photo as in user.profilePhoto and chat.photo. This photo isn't returned in the list of user photos. - */ - @Nullable public ChatPhoto publicPhoto; - /** - * Block list to which the user is added; may be null if none. - */ - @Nullable public BlockList blockList; - /** - * True, if the user can be called. - */ - public boolean canBeCalled; - /** - * True, if a video call can be created with the user. - */ - public boolean supportsVideoCalls; - /** - * True, if the user can't be called due to their privacy settings. - */ - public boolean hasPrivateCalls; - /** - * True, if the user can't be linked in forwarded messages due to their privacy settings. - */ - public boolean hasPrivateForwards; - /** - * True, if voice and video notes can't be sent or forwarded to the user. - */ - public boolean hasRestrictedVoiceAndVideoNoteMessages; - /** - * True, if the user has posted to profile stories. - */ - public boolean hasPostedToProfileStories; - /** - * True, if the user always enabled sponsored messages; known only for the current user. - */ - public boolean hasSponsoredMessagesEnabled; - /** - * True, if the current user needs to explicitly allow to share their phone number with the user when the method addContact is used. - */ - public boolean needPhoneNumberPrivacyException; - /** - * True, if the user set chat background for both chat users and it wasn't reverted yet. - */ - public boolean setChatBackground; - /** - * A short user bio; may be null for bots. - */ - @Nullable public FormattedText bio; - /** - * Birthdate of the user; may be null if unknown. - */ - @Nullable public Birthdate birthdate; - /** - * Identifier of the personal chat of the user; 0 if none. - */ - public long personalChatId; - /** - * Number of saved to profile gifts for other users or the total number of received gifts for the current user. - */ - public int giftCount; - /** - * Number of group chats where both the other user and the current user are a member; 0 for the current user. - */ - public int groupInCommonCount; - /** - * Number of Telegram Stars that must be paid by the user for each sent message to the current user. - */ - public long incomingPaidMessageStarCount; - /** - * Number of Telegram Stars that must be paid by the current user for each sent message to the user. - */ - public long outgoingPaidMessageStarCount; - /** - * Settings for gift receiving for the user. - */ - public GiftSettings giftSettings; - /** - * Information about verification status of the user provided by a bot; may be null if none or unknown. - */ - @Nullable public BotVerification botVerification; - /** - * The main tab chosen by the user; may be null if not chosen manually. - */ - @Nullable public ProfileTab mainProfileTab; - /** - * The first audio file added to the user's profile; may be null if none. - */ - @Nullable public Audio firstProfileAudio; - /** - * The current rating of the user; may be null if none. - */ - @Nullable public UserRating rating; - /** - * The rating of the user after the next change; may be null if the user isn't the current user or there are no pending rating changes. - */ - @Nullable public UserRating pendingRating; - /** - * Unix timestamp when rating of the user will change to pendingRating; 0 if the user isn't the current user or there are no pending rating changes. - */ - public int pendingRatingDate; - /** - * Note added to the user's contact; may be null if none. - */ - @Nullable public FormattedText note; - /** - * Information about business settings for Telegram Business accounts; may be null if none. - */ - @Nullable public BusinessInfo businessInfo; - /** - * For bots, information about the bot; may be null if the user isn't a bot. - */ - @Nullable public BotInfo botInfo; - - /** - * Contains full information about a user. - */ - public UserFullInfo() { - } - - /** - * Contains full information about a user. - * - * @param personalPhoto User profile photo set by the current user for the contact; may be null. If null and user.profilePhoto is null, then the photo is empty; otherwise, it is unknown. If non-null, then it is the same photo as in user.profilePhoto and chat.photo. This photo isn't returned in the list of user photos. - * @param photo User profile photo; may be null. If null and user.profilePhoto is null, then the photo is empty; otherwise, it is unknown. If non-null and personalPhoto is null, then it is the same photo as in user.profilePhoto and chat.photo. - * @param publicPhoto User profile photo visible if the main photo is hidden by privacy settings; may be null. If null and user.profilePhoto is null, then the photo is empty; otherwise, it is unknown. If non-null and both photo and personalPhoto are null, then it is the same photo as in user.profilePhoto and chat.photo. This photo isn't returned in the list of user photos. - * @param blockList Block list to which the user is added; may be null if none. - * @param canBeCalled True, if the user can be called. - * @param supportsVideoCalls True, if a video call can be created with the user. - * @param hasPrivateCalls True, if the user can't be called due to their privacy settings. - * @param hasPrivateForwards True, if the user can't be linked in forwarded messages due to their privacy settings. - * @param hasRestrictedVoiceAndVideoNoteMessages True, if voice and video notes can't be sent or forwarded to the user. - * @param hasPostedToProfileStories True, if the user has posted to profile stories. - * @param hasSponsoredMessagesEnabled True, if the user always enabled sponsored messages; known only for the current user. - * @param needPhoneNumberPrivacyException True, if the current user needs to explicitly allow to share their phone number with the user when the method addContact is used. - * @param setChatBackground True, if the user set chat background for both chat users and it wasn't reverted yet. - * @param bio A short user bio; may be null for bots. - * @param birthdate Birthdate of the user; may be null if unknown. - * @param personalChatId Identifier of the personal chat of the user; 0 if none. - * @param giftCount Number of saved to profile gifts for other users or the total number of received gifts for the current user. - * @param groupInCommonCount Number of group chats where both the other user and the current user are a member; 0 for the current user. - * @param incomingPaidMessageStarCount Number of Telegram Stars that must be paid by the user for each sent message to the current user. - * @param outgoingPaidMessageStarCount Number of Telegram Stars that must be paid by the current user for each sent message to the user. - * @param giftSettings Settings for gift receiving for the user. - * @param botVerification Information about verification status of the user provided by a bot; may be null if none or unknown. - * @param mainProfileTab The main tab chosen by the user; may be null if not chosen manually. - * @param firstProfileAudio The first audio file added to the user's profile; may be null if none. - * @param rating The current rating of the user; may be null if none. - * @param pendingRating The rating of the user after the next change; may be null if the user isn't the current user or there are no pending rating changes. - * @param pendingRatingDate Unix timestamp when rating of the user will change to pendingRating; 0 if the user isn't the current user or there are no pending rating changes. - * @param note Note added to the user's contact; may be null if none. - * @param businessInfo Information about business settings for Telegram Business accounts; may be null if none. - * @param botInfo For bots, information about the bot; may be null if the user isn't a bot. - */ - public UserFullInfo(ChatPhoto personalPhoto, ChatPhoto photo, ChatPhoto publicPhoto, BlockList blockList, boolean canBeCalled, boolean supportsVideoCalls, boolean hasPrivateCalls, boolean hasPrivateForwards, boolean hasRestrictedVoiceAndVideoNoteMessages, boolean hasPostedToProfileStories, boolean hasSponsoredMessagesEnabled, boolean needPhoneNumberPrivacyException, boolean setChatBackground, FormattedText bio, Birthdate birthdate, long personalChatId, int giftCount, int groupInCommonCount, long incomingPaidMessageStarCount, long outgoingPaidMessageStarCount, GiftSettings giftSettings, BotVerification botVerification, ProfileTab mainProfileTab, Audio firstProfileAudio, UserRating rating, UserRating pendingRating, int pendingRatingDate, FormattedText note, BusinessInfo businessInfo, BotInfo botInfo) { - this.personalPhoto = personalPhoto; - this.photo = photo; - this.publicPhoto = publicPhoto; - this.blockList = blockList; - this.canBeCalled = canBeCalled; - this.supportsVideoCalls = supportsVideoCalls; - this.hasPrivateCalls = hasPrivateCalls; - this.hasPrivateForwards = hasPrivateForwards; - this.hasRestrictedVoiceAndVideoNoteMessages = hasRestrictedVoiceAndVideoNoteMessages; - this.hasPostedToProfileStories = hasPostedToProfileStories; - this.hasSponsoredMessagesEnabled = hasSponsoredMessagesEnabled; - this.needPhoneNumberPrivacyException = needPhoneNumberPrivacyException; - this.setChatBackground = setChatBackground; - this.bio = bio; - this.birthdate = birthdate; - this.personalChatId = personalChatId; - this.giftCount = giftCount; - this.groupInCommonCount = groupInCommonCount; - this.incomingPaidMessageStarCount = incomingPaidMessageStarCount; - this.outgoingPaidMessageStarCount = outgoingPaidMessageStarCount; - this.giftSettings = giftSettings; - this.botVerification = botVerification; - this.mainProfileTab = mainProfileTab; - this.firstProfileAudio = firstProfileAudio; - this.rating = rating; - this.pendingRating = pendingRating; - this.pendingRatingDate = pendingRatingDate; - this.note = note; - this.businessInfo = businessInfo; - this.botInfo = botInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2128551190; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains an HTTPS URL, which can be used to get information about a user. - */ - public static class UserLink extends Object { - /** - * The URL. - */ - public String url; - /** - * Left time for which the link is valid, in seconds; 0 if the link is a public username link. - */ - public int expiresIn; - - /** - * Contains an HTTPS URL, which can be used to get information about a user. - */ - public UserLink() { - } - - /** - * Contains an HTTPS URL, which can be used to get information about a user. - * - * @param url The URL. - * @param expiresIn Left time for which the link is valid, in seconds; 0 if the link is a public username link. - */ - public UserLink(String url, int expiresIn) { - this.url = url; - this.expiresIn = expiresIn; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 498138872; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes available user privacy settings. - */ - public abstract static class UserPrivacySetting extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - UserPrivacySettingShowStatus.CONSTRUCTOR, - UserPrivacySettingShowProfilePhoto.CONSTRUCTOR, - UserPrivacySettingShowLinkInForwardedMessages.CONSTRUCTOR, - UserPrivacySettingShowPhoneNumber.CONSTRUCTOR, - UserPrivacySettingShowBio.CONSTRUCTOR, - UserPrivacySettingShowBirthdate.CONSTRUCTOR, - UserPrivacySettingShowProfileAudio.CONSTRUCTOR, - UserPrivacySettingAllowChatInvites.CONSTRUCTOR, - UserPrivacySettingAllowCalls.CONSTRUCTOR, - UserPrivacySettingAllowPeerToPeerCalls.CONSTRUCTOR, - UserPrivacySettingAllowFindingByPhoneNumber.CONSTRUCTOR, - UserPrivacySettingAllowPrivateVoiceAndVideoNoteMessages.CONSTRUCTOR, - UserPrivacySettingAutosaveGifts.CONSTRUCTOR, - UserPrivacySettingAllowUnpaidMessages.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public UserPrivacySetting() { - } - } - - /** - * A privacy setting for managing whether the user's online status is visible. - */ - public static class UserPrivacySettingShowStatus extends UserPrivacySetting { - - /** - * A privacy setting for managing whether the user's online status is visible. - */ - public UserPrivacySettingShowStatus() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1862829310; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A privacy setting for managing whether the user's profile photo is visible. - */ - public static class UserPrivacySettingShowProfilePhoto extends UserPrivacySetting { - - /** - * A privacy setting for managing whether the user's profile photo is visible. - */ - public UserPrivacySettingShowProfilePhoto() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1408485877; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A privacy setting for managing whether a link to the user's account is included in forwarded messages. - */ - public static class UserPrivacySettingShowLinkInForwardedMessages extends UserPrivacySetting { - - /** - * A privacy setting for managing whether a link to the user's account is included in forwarded messages. - */ - public UserPrivacySettingShowLinkInForwardedMessages() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 592688870; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A privacy setting for managing whether the user's phone number is visible. - */ - public static class UserPrivacySettingShowPhoneNumber extends UserPrivacySetting { - - /** - * A privacy setting for managing whether the user's phone number is visible. - */ - public UserPrivacySettingShowPhoneNumber() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -791567831; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A privacy setting for managing whether the user's bio is visible. - */ - public static class UserPrivacySettingShowBio extends UserPrivacySetting { - - /** - * A privacy setting for managing whether the user's bio is visible. - */ - public UserPrivacySettingShowBio() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 959981409; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A privacy setting for managing whether the user's birthdate is visible. - */ - public static class UserPrivacySettingShowBirthdate extends UserPrivacySetting { - - /** - * A privacy setting for managing whether the user's birthdate is visible. - */ - public UserPrivacySettingShowBirthdate() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1167504607; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A privacy setting for managing whether the user's profile audio files are visible. - */ - public static class UserPrivacySettingShowProfileAudio extends UserPrivacySetting { - - /** - * A privacy setting for managing whether the user's profile audio files are visible. - */ - public UserPrivacySettingShowProfileAudio() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 610353549; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A privacy setting for managing whether the user can be invited to chats. - */ - public static class UserPrivacySettingAllowChatInvites extends UserPrivacySetting { - - /** - * A privacy setting for managing whether the user can be invited to chats. - */ - public UserPrivacySettingAllowChatInvites() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1271668007; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A privacy setting for managing whether the user can be called. - */ - public static class UserPrivacySettingAllowCalls extends UserPrivacySetting { - - /** - * A privacy setting for managing whether the user can be called. - */ - public UserPrivacySettingAllowCalls() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -906967291; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A privacy setting for managing whether peer-to-peer connections can be used for calls. - */ - public static class UserPrivacySettingAllowPeerToPeerCalls extends UserPrivacySetting { - - /** - * A privacy setting for managing whether peer-to-peer connections can be used for calls. - */ - public UserPrivacySettingAllowPeerToPeerCalls() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 352500032; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A privacy setting for managing whether the user can be found by their phone number. Checked only if the phone number is not known to the other user. Can be set only to "Allow contacts" or "Allow all". - */ - public static class UserPrivacySettingAllowFindingByPhoneNumber extends UserPrivacySetting { - - /** - * A privacy setting for managing whether the user can be found by their phone number. Checked only if the phone number is not known to the other user. Can be set only to "Allow contacts" or "Allow all". - */ - public UserPrivacySettingAllowFindingByPhoneNumber() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1846645423; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A privacy setting for managing whether the user can receive voice and video messages in private chats; for Telegram Premium users only. - */ - public static class UserPrivacySettingAllowPrivateVoiceAndVideoNoteMessages extends UserPrivacySetting { - - /** - * A privacy setting for managing whether the user can receive voice and video messages in private chats; for Telegram Premium users only. - */ - public UserPrivacySettingAllowPrivateVoiceAndVideoNoteMessages() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 338112060; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A privacy setting for managing whether received gifts are automatically shown on the user's profile page. - */ - public static class UserPrivacySettingAutosaveGifts extends UserPrivacySetting { - - /** - * A privacy setting for managing whether received gifts are automatically shown on the user's profile page. - */ - public UserPrivacySettingAutosaveGifts() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1889167821; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A privacy setting for managing whether the user can receive messages without additional payment. - */ - public static class UserPrivacySettingAllowUnpaidMessages extends UserPrivacySetting { - - /** - * A privacy setting for managing whether the user can receive messages without additional payment. - */ - public UserPrivacySettingAllowUnpaidMessages() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1430051047; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents a single rule for managing user privacy settings. - */ - public abstract static class UserPrivacySettingRule extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - UserPrivacySettingRuleAllowAll.CONSTRUCTOR, - UserPrivacySettingRuleAllowContacts.CONSTRUCTOR, - UserPrivacySettingRuleAllowBots.CONSTRUCTOR, - UserPrivacySettingRuleAllowPremiumUsers.CONSTRUCTOR, - UserPrivacySettingRuleAllowUsers.CONSTRUCTOR, - UserPrivacySettingRuleAllowChatMembers.CONSTRUCTOR, - UserPrivacySettingRuleRestrictAll.CONSTRUCTOR, - UserPrivacySettingRuleRestrictContacts.CONSTRUCTOR, - UserPrivacySettingRuleRestrictBots.CONSTRUCTOR, - UserPrivacySettingRuleRestrictUsers.CONSTRUCTOR, - UserPrivacySettingRuleRestrictChatMembers.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public UserPrivacySettingRule() { - } - } - - /** - * A rule to allow all users to do something. - */ - public static class UserPrivacySettingRuleAllowAll extends UserPrivacySettingRule { - - /** - * A rule to allow all users to do something. - */ - public UserPrivacySettingRuleAllowAll() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1967186881; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A rule to allow all contacts of the user to do something. - */ - public static class UserPrivacySettingRuleAllowContacts extends UserPrivacySettingRule { - - /** - * A rule to allow all contacts of the user to do something. - */ - public UserPrivacySettingRuleAllowContacts() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1892733680; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A rule to allow all bots to do something. - */ - public static class UserPrivacySettingRuleAllowBots extends UserPrivacySettingRule { - - /** - * A rule to allow all bots to do something. - */ - public UserPrivacySettingRuleAllowBots() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1404208925; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A rule to allow all Premium Users to do something; currently, allowed only for userPrivacySettingAllowChatInvites. - */ - public static class UserPrivacySettingRuleAllowPremiumUsers extends UserPrivacySettingRule { - - /** - * A rule to allow all Premium Users to do something; currently, allowed only for userPrivacySettingAllowChatInvites. - */ - public UserPrivacySettingRuleAllowPremiumUsers() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1624147265; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A rule to allow certain specified users to do something. - */ - public static class UserPrivacySettingRuleAllowUsers extends UserPrivacySettingRule { - /** - * The user identifiers, total number of users in all rules must not exceed 1000. - */ - public long[] userIds; - - /** - * A rule to allow certain specified users to do something. - */ - public UserPrivacySettingRuleAllowUsers() { - } - - /** - * A rule to allow certain specified users to do something. - * - * @param userIds The user identifiers, total number of users in all rules must not exceed 1000. - */ - public UserPrivacySettingRuleAllowUsers(long[] userIds) { - this.userIds = userIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1110988334; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A rule to allow all members of certain specified basic groups and supergroups to doing something. - */ - public static class UserPrivacySettingRuleAllowChatMembers extends UserPrivacySettingRule { - /** - * The chat identifiers, total number of chats in all rules must not exceed 20. - */ - public long[] chatIds; - - /** - * A rule to allow all members of certain specified basic groups and supergroups to doing something. - */ - public UserPrivacySettingRuleAllowChatMembers() { - } - - /** - * A rule to allow all members of certain specified basic groups and supergroups to doing something. - * - * @param chatIds The chat identifiers, total number of chats in all rules must not exceed 20. - */ - public UserPrivacySettingRuleAllowChatMembers(long[] chatIds) { - this.chatIds = chatIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2048749863; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A rule to restrict all users from doing something. - */ - public static class UserPrivacySettingRuleRestrictAll extends UserPrivacySettingRule { - - /** - * A rule to restrict all users from doing something. - */ - public UserPrivacySettingRuleRestrictAll() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1406495408; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A rule to restrict all contacts of the user from doing something. - */ - public static class UserPrivacySettingRuleRestrictContacts extends UserPrivacySettingRule { - - /** - * A rule to restrict all contacts of the user from doing something. - */ - public UserPrivacySettingRuleRestrictContacts() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1008389378; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A rule to restrict all bots from doing something. - */ - public static class UserPrivacySettingRuleRestrictBots extends UserPrivacySettingRule { - - /** - * A rule to restrict all bots from doing something. - */ - public UserPrivacySettingRuleRestrictBots() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1902547363; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A rule to restrict all specified users from doing something. - */ - public static class UserPrivacySettingRuleRestrictUsers extends UserPrivacySettingRule { - /** - * The user identifiers, total number of users in all rules must not exceed 1000. - */ - public long[] userIds; - - /** - * A rule to restrict all specified users from doing something. - */ - public UserPrivacySettingRuleRestrictUsers() { - } - - /** - * A rule to restrict all specified users from doing something. - * - * @param userIds The user identifiers, total number of users in all rules must not exceed 1000. - */ - public UserPrivacySettingRuleRestrictUsers(long[] userIds) { - this.userIds = userIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 622796522; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A rule to restrict all members of specified basic groups and supergroups from doing something. - */ - public static class UserPrivacySettingRuleRestrictChatMembers extends UserPrivacySettingRule { - /** - * The chat identifiers, total number of chats in all rules must not exceed 20. - */ - public long[] chatIds; - - /** - * A rule to restrict all members of specified basic groups and supergroups from doing something. - */ - public UserPrivacySettingRuleRestrictChatMembers() { - } - - /** - * A rule to restrict all members of specified basic groups and supergroups from doing something. - * - * @param chatIds The chat identifiers, total number of chats in all rules must not exceed 20. - */ - public UserPrivacySettingRuleRestrictChatMembers(long[] chatIds) { - this.chatIds = chatIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 392530897; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A list of privacy rules. Rules are matched in the specified order. The first matched rule defines the privacy setting for a given user. If no rule matches, the action is not allowed. - */ - public static class UserPrivacySettingRules extends Object { - /** - * A list of rules. - */ - public UserPrivacySettingRule[] rules; - - /** - * A list of privacy rules. Rules are matched in the specified order. The first matched rule defines the privacy setting for a given user. If no rule matches, the action is not allowed. - */ - public UserPrivacySettingRules() { - } - - /** - * A list of privacy rules. Rules are matched in the specified order. The first matched rule defines the privacy setting for a given user. If no rule matches, the action is not allowed. - * - * @param rules A list of rules. - */ - public UserPrivacySettingRules(UserPrivacySettingRule[] rules) { - this.rules = rules; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 322477541; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains description of user rating. - */ - public static class UserRating extends Object { - /** - * The level of the user; may be negative. - */ - public int level; - /** - * True, if the maximum level is reached. - */ - public boolean isMaximumLevelReached; - /** - * Numerical value of the rating. - */ - public long rating; - /** - * The rating required for the current level. - */ - public long currentLevelRating; - /** - * The rating required for the next level; 0 if the maximum level is reached. - */ - public long nextLevelRating; - - /** - * Contains description of user rating. - */ - public UserRating() { - } - - /** - * Contains description of user rating. - * - * @param level The level of the user; may be negative. - * @param isMaximumLevelReached True, if the maximum level is reached. - * @param rating Numerical value of the rating. - * @param currentLevelRating The rating required for the current level. - * @param nextLevelRating The rating required for the next level; 0 if the maximum level is reached. - */ - public UserRating(int level, boolean isMaximumLevelReached, long rating, long currentLevelRating, long nextLevelRating) { - this.level = level; - this.isMaximumLevelReached = isMaximumLevelReached; - this.rating = rating; - this.currentLevelRating = currentLevelRating; - this.nextLevelRating = nextLevelRating; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 532047235; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes the last time the user was online. - */ - public abstract static class UserStatus extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - UserStatusEmpty.CONSTRUCTOR, - UserStatusOnline.CONSTRUCTOR, - UserStatusOffline.CONSTRUCTOR, - UserStatusRecently.CONSTRUCTOR, - UserStatusLastWeek.CONSTRUCTOR, - UserStatusLastMonth.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public UserStatus() { - } - } - - /** - * The user's status has never been changed. - */ - public static class UserStatusEmpty extends UserStatus { - - /** - * The user's status has never been changed. - */ - public UserStatusEmpty() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 164646985; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is online. - */ - public static class UserStatusOnline extends UserStatus { - /** - * Point in time (Unix timestamp) when the user's online status will expire. - */ - public int expires; - - /** - * The user is online. - */ - public UserStatusOnline() { - } - - /** - * The user is online. - * - * @param expires Point in time (Unix timestamp) when the user's online status will expire. - */ - public UserStatusOnline(int expires) { - this.expires = expires; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1529460876; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is offline. - */ - public static class UserStatusOffline extends UserStatus { - /** - * Point in time (Unix timestamp) when the user was last online. - */ - public int wasOnline; - - /** - * The user is offline. - */ - public UserStatusOffline() { - } - - /** - * The user is offline. - * - * @param wasOnline Point in time (Unix timestamp) when the user was last online. - */ - public UserStatusOffline(int wasOnline) { - this.wasOnline = wasOnline; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -759984891; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user was online recently. - */ - public static class UserStatusRecently extends UserStatus { - /** - * Exact user's status is hidden because the current user enabled userPrivacySettingShowStatus privacy setting for the user and has no Telegram Premium. - */ - public boolean byMyPrivacySettings; - - /** - * The user was online recently. - */ - public UserStatusRecently() { - } - - /** - * The user was online recently. - * - * @param byMyPrivacySettings Exact user's status is hidden because the current user enabled userPrivacySettingShowStatus privacy setting for the user and has no Telegram Premium. - */ - public UserStatusRecently(boolean byMyPrivacySettings) { - this.byMyPrivacySettings = byMyPrivacySettings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 262824117; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is offline, but was online last week. - */ - public static class UserStatusLastWeek extends UserStatus { - /** - * Exact user's status is hidden because the current user enabled userPrivacySettingShowStatus privacy setting for the user and has no Telegram Premium. - */ - public boolean byMyPrivacySettings; - - /** - * The user is offline, but was online last week. - */ - public UserStatusLastWeek() { - } - - /** - * The user is offline, but was online last week. - * - * @param byMyPrivacySettings Exact user's status is hidden because the current user enabled userPrivacySettingShowStatus privacy setting for the user and has no Telegram Premium. - */ - public UserStatusLastWeek(boolean byMyPrivacySettings) { - this.byMyPrivacySettings = byMyPrivacySettings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 310385495; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The user is offline, but was online last month. - */ - public static class UserStatusLastMonth extends UserStatus { - /** - * Exact user's status is hidden because the current user enabled userPrivacySettingShowStatus privacy setting for the user and has no Telegram Premium. - */ - public boolean byMyPrivacySettings; - - /** - * The user is offline, but was online last month. - */ - public UserStatusLastMonth() { - } - - /** - * The user is offline, but was online last month. - * - * @param byMyPrivacySettings Exact user's status is hidden because the current user enabled userPrivacySettingShowStatus privacy setting for the user and has no Telegram Premium. - */ - public UserStatusLastMonth(boolean byMyPrivacySettings) { - this.byMyPrivacySettings = byMyPrivacySettings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1194644996; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains custom information about the user. - */ - public static class UserSupportInfo extends Object { - /** - * Information message. - */ - public FormattedText message; - /** - * Information author. - */ - public String author; - /** - * Information change date. - */ - public int date; - - /** - * Contains custom information about the user. - */ - public UserSupportInfo() { - } - - /** - * Contains custom information about the user. - * - * @param message Information message. - * @param author Information author. - * @param date Information change date. - */ - public UserSupportInfo(FormattedText message, String author, int date) { - this.message = message; - this.author = author; - this.date = date; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1257366487; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents the type of user. The following types are possible: regular users, deleted users and bots. - */ - public abstract static class UserType extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - UserTypeRegular.CONSTRUCTOR, - UserTypeDeleted.CONSTRUCTOR, - UserTypeBot.CONSTRUCTOR, - UserTypeUnknown.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public UserType() { - } - } - - /** - * A regular user. - */ - public static class UserTypeRegular extends UserType { - - /** - * A regular user. - */ - public UserTypeRegular() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -598644325; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A deleted user or deleted bot. No information on the user besides the user identifier is available. It is not possible to perform any active actions on this type of user. - */ - public static class UserTypeDeleted extends UserType { - - /** - * A deleted user or deleted bot. No information on the user besides the user identifier is available. It is not possible to perform any active actions on this type of user. - */ - public UserTypeDeleted() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1807729372; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A bot (see https://core.telegram.org/bots). - */ - public static class UserTypeBot extends UserType { - /** - * True, if the bot is owned by the current user and can be edited using the methods toggleBotUsernameIsActive, reorderBotActiveUsernames, setBotProfilePhoto, setBotName, setBotInfoDescription, and setBotInfoShortDescription. - */ - public boolean canBeEdited; - /** - * True, if the bot can be invited to basic group and supergroup chats. - */ - public boolean canJoinGroups; - /** - * True, if the bot can read all messages in basic group or supergroup chats and not just those addressed to the bot. In private and channel chats a bot can always read all messages. - */ - public boolean canReadAllGroupMessages; - /** - * True, if the bot has the main Web App. - */ - public boolean hasMainWebApp; - /** - * True, if the bot has topics. - */ - public boolean hasTopics; - /** - * True, if users can create and delete topics in the chat with the bot. - */ - public boolean allowsUsersToCreateTopics; - /** - * True, if the bot supports inline queries. - */ - public boolean isInline; - /** - * Placeholder for inline queries (displayed on the application input field). - */ - public String inlineQueryPlaceholder; - /** - * True, if the location of the user is expected to be sent with every inline query to this bot. - */ - public boolean needLocation; - /** - * True, if the bot supports connection to Telegram Business accounts. - */ - public boolean canConnectToBusiness; - /** - * True, if the bot can be added to attachment or side menu. - */ - public boolean canBeAddedToAttachmentMenu; - /** - * The number of recently active users of the bot. - */ - public int activeUserCount; - - /** - * A bot (see https://core.telegram.org/bots). - */ - public UserTypeBot() { - } - - /** - * A bot (see https://core.telegram.org/bots). - * - * @param canBeEdited True, if the bot is owned by the current user and can be edited using the methods toggleBotUsernameIsActive, reorderBotActiveUsernames, setBotProfilePhoto, setBotName, setBotInfoDescription, and setBotInfoShortDescription. - * @param canJoinGroups True, if the bot can be invited to basic group and supergroup chats. - * @param canReadAllGroupMessages True, if the bot can read all messages in basic group or supergroup chats and not just those addressed to the bot. In private and channel chats a bot can always read all messages. - * @param hasMainWebApp True, if the bot has the main Web App. - * @param hasTopics True, if the bot has topics. - * @param allowsUsersToCreateTopics True, if users can create and delete topics in the chat with the bot. - * @param isInline True, if the bot supports inline queries. - * @param inlineQueryPlaceholder Placeholder for inline queries (displayed on the application input field). - * @param needLocation True, if the location of the user is expected to be sent with every inline query to this bot. - * @param canConnectToBusiness True, if the bot supports connection to Telegram Business accounts. - * @param canBeAddedToAttachmentMenu True, if the bot can be added to attachment or side menu. - * @param activeUserCount The number of recently active users of the bot. - */ - public UserTypeBot(boolean canBeEdited, boolean canJoinGroups, boolean canReadAllGroupMessages, boolean hasMainWebApp, boolean hasTopics, boolean allowsUsersToCreateTopics, boolean isInline, String inlineQueryPlaceholder, boolean needLocation, boolean canConnectToBusiness, boolean canBeAddedToAttachmentMenu, int activeUserCount) { - this.canBeEdited = canBeEdited; - this.canJoinGroups = canJoinGroups; - this.canReadAllGroupMessages = canReadAllGroupMessages; - this.hasMainWebApp = hasMainWebApp; - this.hasTopics = hasTopics; - this.allowsUsersToCreateTopics = allowsUsersToCreateTopics; - this.isInline = isInline; - this.inlineQueryPlaceholder = inlineQueryPlaceholder; - this.needLocation = needLocation; - this.canConnectToBusiness = canConnectToBusiness; - this.canBeAddedToAttachmentMenu = canBeAddedToAttachmentMenu; - this.activeUserCount = activeUserCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -890772118; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * No information on the user besides the user identifier is available, yet this user has not been deleted. This object is extremely rare and must be handled like a deleted user. It is not possible to perform any actions on users of this type. - */ - public static class UserTypeUnknown extends UserType { - - /** - * No information on the user besides the user identifier is available, yet this user has not been deleted. This object is extremely rare and must be handled like a deleted user. It is not possible to perform any actions on users of this type. - */ - public UserTypeUnknown() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -724541123; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes usernames assigned to a user, a supergroup, or a channel. - */ - public static class Usernames extends Object { - /** - * List of active usernames; the first one must be shown as the primary username. The order of active usernames can be changed with reorderActiveUsernames, reorderBotActiveUsernames or reorderSupergroupActiveUsernames. - */ - public String[] activeUsernames; - /** - * List of currently disabled usernames; the username can be activated with toggleUsernameIsActive, toggleBotUsernameIsActive, or toggleSupergroupUsernameIsActive. - */ - public String[] disabledUsernames; - /** - * Active or disabled username, which may be changed with setUsername or setSupergroupUsername. - */ - public String editableUsername; - /** - * Collectible usernames that were purchased at https://fragment.com and can be passed to getCollectibleItemInfo for more details. - */ - public String[] collectibleUsernames; - - /** - * Describes usernames assigned to a user, a supergroup, or a channel. - */ - public Usernames() { - } - - /** - * Describes usernames assigned to a user, a supergroup, or a channel. - * - * @param activeUsernames List of active usernames; the first one must be shown as the primary username. The order of active usernames can be changed with reorderActiveUsernames, reorderBotActiveUsernames or reorderSupergroupActiveUsernames. - * @param disabledUsernames List of currently disabled usernames; the username can be activated with toggleUsernameIsActive, toggleBotUsernameIsActive, or toggleSupergroupUsernameIsActive. - * @param editableUsername Active or disabled username, which may be changed with setUsername or setSupergroupUsername. - * @param collectibleUsernames Collectible usernames that were purchased at https://fragment.com and can be passed to getCollectibleItemInfo for more details. - */ - public Usernames(String[] activeUsernames, String[] disabledUsernames, String editableUsername, String[] collectibleUsernames) { - this.activeUsernames = activeUsernames; - this.disabledUsernames = disabledUsernames; - this.editableUsername = editableUsername; - this.collectibleUsernames = collectibleUsernames; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1263390614; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Represents a list of users. - */ - public static class Users extends Object { - /** - * Approximate total number of users found. - */ - public int totalCount; - /** - * A list of user identifiers. - */ - public long[] userIds; - - /** - * Represents a list of users. - */ - public Users() { - } - - /** - * Represents a list of users. - * - * @param totalCount Approximate total number of users found. - * @param userIds A list of user identifiers. - */ - public Users(int totalCount, long[] userIds) { - this.totalCount = totalCount; - this.userIds = userIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 171203420; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a temporary identifier of validated order information, which is stored for one hour, and the available shipping options. - */ - public static class ValidatedOrderInfo extends Object { - /** - * Temporary identifier of the order information. - */ - public String orderInfoId; - /** - * Available shipping options. - */ - public ShippingOption[] shippingOptions; - - /** - * Contains a temporary identifier of validated order information, which is stored for one hour, and the available shipping options. - */ - public ValidatedOrderInfo() { - } - - /** - * Contains a temporary identifier of validated order information, which is stored for one hour, and the available shipping options. - * - * @param orderInfoId Temporary identifier of the order information. - * @param shippingOptions Available shipping options. - */ - public ValidatedOrderInfo(String orderInfoId, ShippingOption[] shippingOptions) { - this.orderInfoId = orderInfoId; - this.shippingOptions = shippingOptions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1511451484; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Represents a vector path command. - */ - public abstract static class VectorPathCommand extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - VectorPathCommandLine.CONSTRUCTOR, - VectorPathCommandCubicBezierCurve.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public VectorPathCommand() { - } - } - - /** - * A straight line to a given point. - */ - public static class VectorPathCommandLine extends VectorPathCommand { - /** - * The end point of the straight line. - */ - public Point endPoint; - - /** - * A straight line to a given point. - */ - public VectorPathCommandLine() { - } - - /** - * A straight line to a given point. - * - * @param endPoint The end point of the straight line. - */ - public VectorPathCommandLine(Point endPoint) { - this.endPoint = endPoint; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -614056822; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * A cubic Bézier curve to a given point. - */ - public static class VectorPathCommandCubicBezierCurve extends VectorPathCommand { - /** - * The start control point of the curve. - */ - public Point startControlPoint; - /** - * The end control point of the curve. - */ - public Point endControlPoint; - /** - * The end point of the curve. - */ - public Point endPoint; - - /** - * A cubic Bézier curve to a given point. - */ - public VectorPathCommandCubicBezierCurve() { - } - - /** - * A cubic Bézier curve to a given point. - * - * @param startControlPoint The start control point of the curve. - * @param endControlPoint The end control point of the curve. - * @param endPoint The end point of the curve. - */ - public VectorPathCommandCubicBezierCurve(Point startControlPoint, Point endControlPoint, Point endPoint) { - this.startControlPoint = startControlPoint; - this.endControlPoint = endControlPoint; - this.endPoint = endPoint; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1229733434; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a venue. - */ - public static class Venue extends Object { - /** - * Venue location; as defined by the sender. - */ - public Location location; - /** - * Venue name; as defined by the sender. - */ - public String title; - /** - * Venue address; as defined by the sender. - */ - public String address; - /** - * Provider of the venue database; as defined by the sender. Currently, only "foursquare" and "gplaces" (Google Places) need to be supported. - */ - public String provider; - /** - * Identifier of the venue in the provider database; as defined by the sender. - */ - public String id; - /** - * Type of the venue in the provider database; as defined by the sender. - */ - public String type; - - /** - * Describes a venue. - */ - public Venue() { - } - - /** - * Describes a venue. - * - * @param location Venue location; as defined by the sender. - * @param title Venue name; as defined by the sender. - * @param address Venue address; as defined by the sender. - * @param provider Provider of the venue database; as defined by the sender. Currently, only "foursquare" and "gplaces" (Google Places) need to be supported. - * @param id Identifier of the venue in the provider database; as defined by the sender. - * @param type Type of the venue in the provider database; as defined by the sender. - */ - public Venue(Location location, String title, String address, String provider, String id, String type) { - this.location = location; - this.title = title; - this.address = address; - this.provider = provider; - this.id = id; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1070406393; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about verification status of a chat or a user. - */ - public static class VerificationStatus extends Object { - /** - * True, if the chat or the user is verified by Telegram. - */ - public boolean isVerified; - /** - * True, if the chat or the user is marked as scam by Telegram. - */ - public boolean isScam; - /** - * True, if the chat or the user is marked as fake by Telegram. - */ - public boolean isFake; - /** - * Identifier of the custom emoji to be shown as verification sign provided by a bot for the user; 0 if none. - */ - public long botVerificationIconCustomEmojiId; - - /** - * Contains information about verification status of a chat or a user. - */ - public VerificationStatus() { - } - - /** - * Contains information about verification status of a chat or a user. - * - * @param isVerified True, if the chat or the user is verified by Telegram. - * @param isScam True, if the chat or the user is marked as scam by Telegram. - * @param isFake True, if the chat or the user is marked as fake by Telegram. - * @param botVerificationIconCustomEmojiId Identifier of the custom emoji to be shown as verification sign provided by a bot for the user; 0 if none. - */ - public VerificationStatus(boolean isVerified, boolean isScam, boolean isFake, long botVerificationIconCustomEmojiId) { - this.isVerified = isVerified; - this.isScam = isScam; - this.isFake = isFake; - this.botVerificationIconCustomEmojiId = botVerificationIconCustomEmojiId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 988193164; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a video file. - */ - public static class Video extends Object { - /** - * Duration of the video, in seconds; as defined by the sender. - */ - public int duration; - /** - * Video width; as defined by the sender. - */ - public int width; - /** - * Video height; as defined by the sender. - */ - public int height; - /** - * Original name of the file; as defined by the sender. - */ - public String fileName; - /** - * MIME type of the file; as defined by the sender. - */ - public String mimeType; - /** - * True, if stickers were added to the video. The list of corresponding sticker sets can be received using getAttachedStickerSets. - */ - public boolean hasStickers; - /** - * True, if the video is expected to be streamed. - */ - public boolean supportsStreaming; - /** - * Video minithumbnail; may be null. - */ - @Nullable public Minithumbnail minithumbnail; - /** - * Video thumbnail in JPEG or MPEG4 format; as defined by the sender; may be null. - */ - @Nullable public Thumbnail thumbnail; - /** - * File containing the video. - */ - public File video; - - /** - * Describes a video file. - */ - public Video() { - } - - /** - * Describes a video file. - * - * @param duration Duration of the video, in seconds; as defined by the sender. - * @param width Video width; as defined by the sender. - * @param height Video height; as defined by the sender. - * @param fileName Original name of the file; as defined by the sender. - * @param mimeType MIME type of the file; as defined by the sender. - * @param hasStickers True, if stickers were added to the video. The list of corresponding sticker sets can be received using getAttachedStickerSets. - * @param supportsStreaming True, if the video is expected to be streamed. - * @param minithumbnail Video minithumbnail; may be null. - * @param thumbnail Video thumbnail in JPEG or MPEG4 format; as defined by the sender; may be null. - * @param video File containing the video. - */ - public Video(int duration, int width, int height, String fileName, String mimeType, boolean hasStickers, boolean supportsStreaming, Minithumbnail minithumbnail, Thumbnail thumbnail, File video) { - this.duration = duration; - this.width = width; - this.height = height; - this.fileName = fileName; - this.mimeType = mimeType; - this.hasStickers = hasStickers; - this.supportsStreaming = supportsStreaming; - this.minithumbnail = minithumbnail; - this.thumbnail = thumbnail; - this.video = video; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 832856268; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a video chat, i.e. a group call bound to a chat. - */ - public static class VideoChat extends Object { - /** - * Group call identifier of an active video chat; 0 if none. Full information about the video chat can be received through the method getGroupCall. - */ - public int groupCallId; - /** - * True, if the video chat has participants. - */ - public boolean hasParticipants; - /** - * Default group call participant identifier to join the video chat; may be null. - */ - @Nullable public MessageSender defaultParticipantId; - - /** - * Describes a video chat, i.e. a group call bound to a chat. - */ - public VideoChat() { - } - - /** - * Describes a video chat, i.e. a group call bound to a chat. - * - * @param groupCallId Group call identifier of an active video chat; 0 if none. Full information about the video chat can be received through the method getGroupCall. - * @param hasParticipants True, if the video chat has participants. - * @param defaultParticipantId Default group call participant identifier to join the video chat; may be null. - */ - public VideoChat(int groupCallId, boolean hasParticipants, MessageSender defaultParticipantId) { - this.groupCallId = groupCallId; - this.hasParticipants = hasParticipants; - this.defaultParticipantId = defaultParticipantId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1374319320; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an advertisent to be shown while a video from a message is watched. - */ - public static class VideoMessageAdvertisement extends Object { - /** - * Unique identifier of this result. - */ - public long uniqueId; - /** - * Text of the advertisement. - */ - public String text; - /** - * The minimum amount of time the advertisement must be displayed before it can be hidden by the user, in seconds. - */ - public int minDisplayDuration; - /** - * The maximum amount of time the advertisement must be displayed before it must be automatically hidden, in seconds. - */ - public int maxDisplayDuration; - /** - * True, if the advertisement can be reported to Telegram moderators through reportVideoMessageAdvertisement. - */ - public boolean canBeReported; - /** - * Information about the sponsor of the advertisement. - */ - public AdvertisementSponsor sponsor; - /** - * Title of the sponsored message. - */ - public String title; - /** - * If non-empty, additional information about the sponsored message to be shown along with the message. - */ - public String additionalInfo; - - /** - * Describes an advertisent to be shown while a video from a message is watched. - */ - public VideoMessageAdvertisement() { - } - - /** - * Describes an advertisent to be shown while a video from a message is watched. - * - * @param uniqueId Unique identifier of this result. - * @param text Text of the advertisement. - * @param minDisplayDuration The minimum amount of time the advertisement must be displayed before it can be hidden by the user, in seconds. - * @param maxDisplayDuration The maximum amount of time the advertisement must be displayed before it must be automatically hidden, in seconds. - * @param canBeReported True, if the advertisement can be reported to Telegram moderators through reportVideoMessageAdvertisement. - * @param sponsor Information about the sponsor of the advertisement. - * @param title Title of the sponsored message. - * @param additionalInfo If non-empty, additional information about the sponsored message to be shown along with the message. - */ - public VideoMessageAdvertisement(long uniqueId, String text, int minDisplayDuration, int maxDisplayDuration, boolean canBeReported, AdvertisementSponsor sponsor, String title, String additionalInfo) { - this.uniqueId = uniqueId; - this.text = text; - this.minDisplayDuration = minDisplayDuration; - this.maxDisplayDuration = maxDisplayDuration; - this.canBeReported = canBeReported; - this.sponsor = sponsor; - this.title = title; - this.additionalInfo = additionalInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -112391535; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains a list of advertisements to be shown while a video from a message is watched. - */ - public static class VideoMessageAdvertisements extends Object { - /** - * List of advertisements. - */ - public VideoMessageAdvertisement[] advertisements; - /** - * Delay before the first advertisement is shown, in seconds. - */ - public int startDelay; - /** - * Delay between consecutive advertisements, in seconds. - */ - public int betweenDelay; - - /** - * Contains a list of advertisements to be shown while a video from a message is watched. - */ - public VideoMessageAdvertisements() { - } - - /** - * Contains a list of advertisements to be shown while a video from a message is watched. - * - * @param advertisements List of advertisements. - * @param startDelay Delay before the first advertisement is shown, in seconds. - * @param betweenDelay Delay between consecutive advertisements, in seconds. - */ - public VideoMessageAdvertisements(VideoMessageAdvertisement[] advertisements, int startDelay, int betweenDelay) { - this.advertisements = advertisements; - this.startDelay = startDelay; - this.betweenDelay = betweenDelay; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1776370217; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a video note. The video must be equal in width and height, cropped to a circle, and stored in MPEG4 format. - */ - public static class VideoNote extends Object { - /** - * Duration of the video, in seconds; as defined by the sender. - */ - public int duration; - /** - * A waveform representation of the video note's audio in 5-bit format; may be empty if unknown. - */ - public byte[] waveform; - /** - * Video width and height; as defined by the sender. - */ - public int length; - /** - * Video minithumbnail; may be null. - */ - @Nullable public Minithumbnail minithumbnail; - /** - * Video thumbnail in JPEG format; as defined by the sender; may be null. - */ - @Nullable public Thumbnail thumbnail; - /** - * Result of speech recognition in the video note; may be null. - */ - @Nullable public SpeechRecognitionResult speechRecognitionResult; - /** - * File containing the video. - */ - public File video; - - /** - * Describes a video note. The video must be equal in width and height, cropped to a circle, and stored in MPEG4 format. - */ - public VideoNote() { - } - - /** - * Describes a video note. The video must be equal in width and height, cropped to a circle, and stored in MPEG4 format. - * - * @param duration Duration of the video, in seconds; as defined by the sender. - * @param waveform A waveform representation of the video note's audio in 5-bit format; may be empty if unknown. - * @param length Video width and height; as defined by the sender. - * @param minithumbnail Video minithumbnail; may be null. - * @param thumbnail Video thumbnail in JPEG format; as defined by the sender; may be null. - * @param speechRecognitionResult Result of speech recognition in the video note; may be null. - * @param video File containing the video. - */ - public VideoNote(int duration, byte[] waveform, int length, Minithumbnail minithumbnail, Thumbnail thumbnail, SpeechRecognitionResult speechRecognitionResult, File video) { - this.duration = duration; - this.waveform = waveform; - this.length = length; - this.minithumbnail = minithumbnail; - this.thumbnail = thumbnail; - this.speechRecognitionResult = speechRecognitionResult; - this.video = video; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2062096581; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a storyboard for a video. - */ - public static class VideoStoryboard extends Object { - /** - * A JPEG file that contains tiled previews of video. - */ - public File storyboardFile; - /** - * Width of a tile. - */ - public int width; - /** - * Height of a tile. - */ - public int height; - /** - * File that describes mapping of position in the video to a tile in the JPEG file. - */ - public File mapFile; - - /** - * Describes a storyboard for a video. - */ - public VideoStoryboard() { - } - - /** - * Describes a storyboard for a video. - * - * @param storyboardFile A JPEG file that contains tiled previews of video. - * @param width Width of a tile. - * @param height Height of a tile. - * @param mapFile File that describes mapping of position in the video to a tile in the JPEG file. - */ - public VideoStoryboard(File storyboardFile, int width, int height, File mapFile) { - this.storyboardFile = storyboardFile; - this.width = width; - this.height = height; - this.mapFile = mapFile; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1731320034; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a voice note. - */ - public static class VoiceNote extends Object { - /** - * Duration of the voice note, in seconds; as defined by the sender. - */ - public int duration; - /** - * A waveform representation of the voice note in 5-bit format. - */ - public byte[] waveform; - /** - * MIME type of the file; as defined by the sender. Usually, one of "audio/ogg" for Opus in an OGG container, "audio/mpeg" for an MP3 audio, or "audio/mp4" for an M4A audio. - */ - public String mimeType; - /** - * Result of speech recognition in the voice note; may be null. - */ - @Nullable public SpeechRecognitionResult speechRecognitionResult; - /** - * File containing the voice note. - */ - public File voice; - - /** - * Describes a voice note. - */ - public VoiceNote() { - } - - /** - * Describes a voice note. - * - * @param duration Duration of the voice note, in seconds; as defined by the sender. - * @param waveform A waveform representation of the voice note in 5-bit format. - * @param mimeType MIME type of the file; as defined by the sender. Usually, one of "audio/ogg" for Opus in an OGG container, "audio/mpeg" for an MP3 audio, or "audio/mp4" for an M4A audio. - * @param speechRecognitionResult Result of speech recognition in the voice note; may be null. - * @param voice File containing the voice note. - */ - public VoiceNote(int duration, byte[] waveform, String mimeType, SpeechRecognitionResult speechRecognitionResult, File voice) { - this.duration = duration; - this.waveform = waveform; - this.mimeType = mimeType; - this.speechRecognitionResult = speechRecognitionResult; - this.voice = voice; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1175302923; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes a Web App. Use getInternalLink with internalLinkTypeWebApp to share the Web App. - */ - public static class WebApp extends Object { - /** - * Web App short name. - */ - public String shortName; - /** - * Web App title. - */ - public String title; - /** - * Web App description. - */ - public String description; - /** - * Web App photo. - */ - public Photo photo; - /** - * Web App animation; may be null. - */ - @Nullable public Animation animation; - - /** - * Describes a Web App. Use getInternalLink with internalLinkTypeWebApp to share the Web App. - */ - public WebApp() { - } - - /** - * Describes a Web App. Use getInternalLink with internalLinkTypeWebApp to share the Web App. - * - * @param shortName Web App short name. - * @param title Web App title. - * @param description Web App description. - * @param photo Web App photo. - * @param animation Web App animation; may be null. - */ - public WebApp(String shortName, String title, String description, Photo photo, Animation animation) { - this.shortName = shortName; - this.title = title; - this.description = description; - this.photo = photo; - this.animation = animation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1616619763; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Contains information about a Web App. - */ - public static class WebAppInfo extends Object { - /** - * Unique identifier for the Web App launch. - */ - public long launchId; - /** - * A Web App URL to open in a web view. - */ - public String url; - - /** - * Contains information about a Web App. - */ - public WebAppInfo() { - } - - /** - * Contains information about a Web App. - * - * @param launchId Unique identifier for the Web App launch. - * @param url A Web App URL to open in a web view. - */ - public WebAppInfo(long launchId, String url) { - this.launchId = launchId; - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 788378344; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * This class is an abstract base class. - * Describes mode in which a Web App is opened. - */ - public abstract static class WebAppOpenMode extends Object { - /** - * Describes possible values returned by getConstructor(). - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - WebAppOpenModeCompact.CONSTRUCTOR, - WebAppOpenModeFullSize.CONSTRUCTOR, - WebAppOpenModeFullScreen.CONSTRUCTOR - }) - public @interface Constructors {} - - /** - * @return identifier uniquely determining type of the object. - */ - @Constructors - @Override - public abstract int getConstructor(); - /** - * Default class constructor. - */ - public WebAppOpenMode() { - } - } - - /** - * The Web App is opened in the compact mode. - */ - public static class WebAppOpenModeCompact extends WebAppOpenMode { - - /** - * The Web App is opened in the compact mode. - */ - public WebAppOpenModeCompact() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1711603675; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The Web App is opened in the full-size mode. - */ - public static class WebAppOpenModeFullSize extends WebAppOpenMode { - - /** - * The Web App is opened in the full-size mode. - */ - public WebAppOpenModeFullSize() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 189320513; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * The Web App is opened in the full-screen mode. - */ - public static class WebAppOpenModeFullScreen extends WebAppOpenMode { - - /** - * The Web App is opened in the full-screen mode. - */ - public WebAppOpenModeFullScreen() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1871315357; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Options to be used when a Web App is opened. - */ - public static class WebAppOpenParameters extends Object { - /** - * Preferred Web App theme; pass null to use the default theme. - */ - public ThemeParameters theme; - /** - * Short name of the current application; 0-64 English letters, digits, and underscores. - */ - public String applicationName; - /** - * The mode in which the Web App is opened; pass null to open in webAppOpenModeFullSize. - */ - public WebAppOpenMode mode; - - /** - * Options to be used when a Web App is opened. - */ - public WebAppOpenParameters() { - } - - /** - * Options to be used when a Web App is opened. - * - * @param theme Preferred Web App theme; pass null to use the default theme. - * @param applicationName Short name of the current application; 0-64 English letters, digits, and underscores. - * @param mode The mode in which the Web App is opened; pass null to open in webAppOpenModeFullSize. - */ - public WebAppOpenParameters(ThemeParameters theme, String applicationName, WebAppOpenMode mode) { - this.theme = theme; - this.applicationName = applicationName; - this.mode = mode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1375356527; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Describes an instant view page for a web page. - */ - public static class WebPageInstantView extends Object { - /** - * Content of the instant view page. - */ - public PageBlock[] pageBlocks; - /** - * Number of the instant view views; 0 if unknown. - */ - public int viewCount; - /** - * Version of the instant view; currently, can be 1 or 2. - */ - public int version; - /** - * True, if the instant view must be shown from right to left. - */ - public boolean isRtl; - /** - * True, if the instant view contains the full page. A network request might be needed to get the full instant view. - */ - public boolean isFull; - /** - * An internal link to be opened to leave feedback about the instant view. - */ - public InternalLinkType feedbackLink; - - /** - * Describes an instant view page for a web page. - */ - public WebPageInstantView() { - } - - /** - * Describes an instant view page for a web page. - * - * @param pageBlocks Content of the instant view page. - * @param viewCount Number of the instant view views; 0 if unknown. - * @param version Version of the instant view; currently, can be 1 or 2. - * @param isRtl True, if the instant view must be shown from right to left. - * @param isFull True, if the instant view contains the full page. A network request might be needed to get the full instant view. - * @param feedbackLink An internal link to be opened to leave feedback about the instant view. - */ - public WebPageInstantView(PageBlock[] pageBlocks, int viewCount, int version, boolean isRtl, boolean isFull, InternalLinkType feedbackLink) { - this.pageBlocks = pageBlocks; - this.viewCount = viewCount; - this.version = version; - this.isRtl = isRtl; - this.isFull = isFull; - this.feedbackLink = feedbackLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 778202453; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Accepts an incoming call. - * - *

Returns {@link Ok Ok}

- */ - public static class AcceptCall extends Function { - /** - * Call identifier. - */ - public int callId; - /** - * The call protocols supported by the application. - */ - public CallProtocol protocol; - - /** - * Default constructor for a function, which accepts an incoming call. - * - *

Returns {@link Ok Ok}

- */ - public AcceptCall() { - } - - /** - * Creates a function, which accepts an incoming call. - * - *

Returns {@link Ok Ok}

- * - * @param callId Call identifier. - * @param protocol The call protocols supported by the application. - */ - public AcceptCall(int callId, CallProtocol protocol) { - this.callId = callId; - this.protocol = protocol; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -646618416; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Accepts an OAuth authorization request. Returns an HTTP URL to open after successful authorization. May return an empty link if just a toast about successful login has to be shown. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public static class AcceptOauthRequest extends Function { - /** - * URL of the OAuth deep link. - */ - public String url; - /** - * The matching code chosen by the user. - */ - public String matchCode; - /** - * Pass true if the current user allowed the bot that was returned in getOauthLinkInfo, to send them messages. - */ - public boolean allowWriteAccess; - /** - * Pass true if the current user allowed the bot that was returned in getOauthLinkInfo, to access their phone number. - */ - public boolean allowPhoneNumberAccess; - - /** - * Default constructor for a function, which accepts an OAuth authorization request. Returns an HTTP URL to open after successful authorization. May return an empty link if just a toast about successful login has to be shown. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public AcceptOauthRequest() { - } - - /** - * Creates a function, which accepts an OAuth authorization request. Returns an HTTP URL to open after successful authorization. May return an empty link if just a toast about successful login has to be shown. - * - *

Returns {@link HttpUrl HttpUrl}

- * - * @param url URL of the OAuth deep link. - * @param matchCode The matching code chosen by the user. - * @param allowWriteAccess Pass true if the current user allowed the bot that was returned in getOauthLinkInfo, to send them messages. - * @param allowPhoneNumberAccess Pass true if the current user allowed the bot that was returned in getOauthLinkInfo, to access their phone number. - */ - public AcceptOauthRequest(String url, String matchCode, boolean allowWriteAccess, boolean allowPhoneNumberAccess) { - this.url = url; - this.matchCode = matchCode; - this.allowWriteAccess = allowWriteAccess; - this.allowPhoneNumberAccess = allowPhoneNumberAccess; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -427442108; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Accepts Telegram terms of services. - * - *

Returns {@link Ok Ok}

- */ - public static class AcceptTermsOfService extends Function { - /** - * Terms of service identifier. - */ - public String termsOfServiceId; - - /** - * Default constructor for a function, which accepts Telegram terms of services. - * - *

Returns {@link Ok Ok}

- */ - public AcceptTermsOfService() { - } - - /** - * Creates a function, which accepts Telegram terms of services. - * - *

Returns {@link Ok Ok}

- * - * @param termsOfServiceId Terms of service identifier. - */ - public AcceptTermsOfService(String termsOfServiceId) { - this.termsOfServiceId = termsOfServiceId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2130576356; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Activates stealth mode for stories, which hides all views of stories from the current user in the last "story_stealth_mode_past_period" seconds and for the next "story_stealth_mode_future_period" seconds; for Telegram Premium users only. - * - *

Returns {@link Ok Ok}

- */ - public static class ActivateStoryStealthMode extends Function { - - /** - * Default constructor for a function, which activates stealth mode for stories, which hides all views of stories from the current user in the last "story_stealth_mode_past_period" seconds and for the next "story_stealth_mode_future_period" seconds; for Telegram Premium users only. - * - *

Returns {@link Ok Ok}

- */ - public ActivateStoryStealthMode() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1009023855; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a new media preview to the beginning of the list of media previews of a bot. Returns the added preview after addition is completed server-side. The total number of previews must not exceed getOption("bot_media_preview_count_max") for the given language. - * - *

Returns {@link BotMediaPreview BotMediaPreview}

- */ - public static class AddBotMediaPreview extends Function { - /** - * Identifier of the target bot. The bot must be owned and must have the main Web App. - */ - public long botUserId; - /** - * A two-letter ISO 639-1 language code for which preview is added. If empty, then the preview will be shown to all users for whose languages there are no dedicated previews. If non-empty, then there must be an official language pack of the same name, which is returned by getLocalizationTargetInfo. - */ - public String languageCode; - /** - * Content of the added preview. - */ - public InputStoryContent content; - - /** - * Default constructor for a function, which adds a new media preview to the beginning of the list of media previews of a bot. Returns the added preview after addition is completed server-side. The total number of previews must not exceed getOption("bot_media_preview_count_max") for the given language. - * - *

Returns {@link BotMediaPreview BotMediaPreview}

- */ - public AddBotMediaPreview() { - } - - /** - * Creates a function, which adds a new media preview to the beginning of the list of media previews of a bot. Returns the added preview after addition is completed server-side. The total number of previews must not exceed getOption("bot_media_preview_count_max") for the given language. - * - *

Returns {@link BotMediaPreview BotMediaPreview}

- * - * @param botUserId Identifier of the target bot. The bot must be owned and must have the main Web App. - * @param languageCode A two-letter ISO 639-1 language code for which preview is added. If empty, then the preview will be shown to all users for whose languages there are no dedicated previews. If non-empty, then there must be an official language pack of the same name, which is returned by getLocalizationTargetInfo. - * @param content Content of the added preview. - */ - public AddBotMediaPreview(long botUserId, String languageCode, InputStoryContent content) { - this.botUserId = botUserId; - this.languageCode = languageCode; - this.content = content; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1347126571; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a chat folder by an invite link. - * - *

Returns {@link Ok Ok}

- */ - public static class AddChatFolderByInviteLink extends Function { - /** - * Invite link for the chat folder. - */ - public String inviteLink; - /** - * Identifiers of the chats added to the chat folder. The chats are automatically joined if they aren't joined yet. - */ - public long[] chatIds; - - /** - * Default constructor for a function, which adds a chat folder by an invite link. - * - *

Returns {@link Ok Ok}

- */ - public AddChatFolderByInviteLink() { - } - - /** - * Creates a function, which adds a chat folder by an invite link. - * - *

Returns {@link Ok Ok}

- * - * @param inviteLink Invite link for the chat folder. - * @param chatIds Identifiers of the chats added to the chat folder. The chats are automatically joined if they aren't joined yet. - */ - public AddChatFolderByInviteLink(String inviteLink, long[] chatIds) { - this.inviteLink = inviteLink; - this.chatIds = chatIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -858593816; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a new member to a chat; requires canInviteUsers member right. Members can't be added to private or secret chats. Returns information about members that weren't added. - * - *

Returns {@link FailedToAddMembers FailedToAddMembers}

- */ - public static class AddChatMember extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the user. - */ - public long userId; - /** - * The number of earlier messages from the chat to be forwarded to the new member; up to 100. Ignored for supergroups and channels, or if the added user is a bot. - */ - public int forwardLimit; - - /** - * Default constructor for a function, which adds a new member to a chat; requires canInviteUsers member right. Members can't be added to private or secret chats. Returns information about members that weren't added. - * - *

Returns {@link FailedToAddMembers FailedToAddMembers}

- */ - public AddChatMember() { - } - - /** - * Creates a function, which adds a new member to a chat; requires canInviteUsers member right. Members can't be added to private or secret chats. Returns information about members that weren't added. - * - *

Returns {@link FailedToAddMembers FailedToAddMembers}

- * - * @param chatId Chat identifier. - * @param userId Identifier of the user. - * @param forwardLimit The number of earlier messages from the chat to be forwarded to the new member; up to 100. Ignored for supergroups and channels, or if the added user is a bot. - */ - public AddChatMember(long chatId, long userId, int forwardLimit) { - this.chatId = chatId; - this.userId = userId; - this.forwardLimit = forwardLimit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1720144407; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds multiple new members to a chat; requires canInviteUsers member right. Currently, this method is only available for supergroups and channels. This method can't be used to join a chat. Members can't be added to a channel if it has more than 200 members. Returns information about members that weren't added. - * - *

Returns {@link FailedToAddMembers FailedToAddMembers}

- */ - public static class AddChatMembers extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifiers of the users to be added to the chat. The maximum number of added users is 20 for supergroups and 100 for channels. - */ - public long[] userIds; - - /** - * Default constructor for a function, which adds multiple new members to a chat; requires canInviteUsers member right. Currently, this method is only available for supergroups and channels. This method can't be used to join a chat. Members can't be added to a channel if it has more than 200 members. Returns information about members that weren't added. - * - *

Returns {@link FailedToAddMembers FailedToAddMembers}

- */ - public AddChatMembers() { - } - - /** - * Creates a function, which adds multiple new members to a chat; requires canInviteUsers member right. Currently, this method is only available for supergroups and channels. This method can't be used to join a chat. Members can't be added to a channel if it has more than 200 members. Returns information about members that weren't added. - * - *

Returns {@link FailedToAddMembers FailedToAddMembers}

- * - * @param chatId Chat identifier. - * @param userIds Identifiers of the users to be added to the chat. The maximum number of added users is 20 for supergroups and 100 for channels. - */ - public AddChatMembers(long chatId, long[] userIds) { - this.chatId = chatId; - this.userIds = userIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1675991329; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a chat to a chat list. A chat can't be simultaneously in Main and Archive chat lists, so it is automatically removed from another one if needed. - * - *

Returns {@link Ok Ok}

- */ - public static class AddChatToList extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * The chat list. Use getChatListsToAddChat to get suitable chat lists. - */ - public ChatList chatList; - - /** - * Default constructor for a function, which adds a chat to a chat list. A chat can't be simultaneously in Main and Archive chat lists, so it is automatically removed from another one if needed. - * - *

Returns {@link Ok Ok}

- */ - public AddChatToList() { - } - - /** - * Creates a function, which adds a chat to a chat list. A chat can't be simultaneously in Main and Archive chat lists, so it is automatically removed from another one if needed. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param chatList The chat list. Use getChatListsToAddChat to get suitable chat lists. - */ - public AddChatToList(long chatId, ChatList chatList) { - this.chatId = chatId; - this.chatList = chatList; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -80523595; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds tasks to a checklist in a message. - * - *

Returns {@link Ok Ok}

- */ - public static class AddChecklistTasks extends Function { - /** - * Identifier of the chat with the message. - */ - public long chatId; - /** - * Identifier of the message containing the checklist. Use messageProperties.canAddTasks to check whether the tasks can be added. - */ - public long messageId; - /** - * List of added tasks. - */ - public InputChecklistTask[] tasks; - - /** - * Default constructor for a function, which adds tasks to a checklist in a message. - * - *

Returns {@link Ok Ok}

- */ - public AddChecklistTasks() { - } - - /** - * Creates a function, which adds tasks to a checklist in a message. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat with the message. - * @param messageId Identifier of the message containing the checklist. Use messageProperties.canAddTasks to check whether the tasks can be added. - * @param tasks List of added tasks. - */ - public AddChecklistTasks(long chatId, long messageId, InputChecklistTask[] tasks) { - this.chatId = chatId; - this.messageId = messageId; - this.tasks = tasks; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1554619499; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a user to the contact list or edits an existing contact by their user identifier. - * - *

Returns {@link Ok Ok}

- */ - public static class AddContact extends Function { - /** - * Identifier of the user. - */ - public long userId; - /** - * The contact to add or edit; phone number may be empty and needs to be specified only if known. - */ - public ImportedContact contact; - /** - * Pass true to share the current user's phone number with the new contact. A corresponding rule to userPrivacySettingShowPhoneNumber will be added if needed. Use the field userFullInfo.needPhoneNumberPrivacyException to check whether the current user needs to be asked to share their phone number. - */ - public boolean sharePhoneNumber; - - /** - * Default constructor for a function, which adds a user to the contact list or edits an existing contact by their user identifier. - * - *

Returns {@link Ok Ok}

- */ - public AddContact() { - } - - /** - * Creates a function, which adds a user to the contact list or edits an existing contact by their user identifier. - * - *

Returns {@link Ok Ok}

- * - * @param userId Identifier of the user. - * @param contact The contact to add or edit; phone number may be empty and needs to be specified only if known. - * @param sharePhoneNumber Pass true to share the current user's phone number with the new contact. A corresponding rule to userPrivacySettingShowPhoneNumber will be added if needed. Use the field userFullInfo.needPhoneNumberPrivacyException to check whether the current user needs to be asked to share their phone number. - */ - public AddContact(long userId, ImportedContact contact, boolean sharePhoneNumber) { - this.userId = userId; - this.contact = contact; - this.sharePhoneNumber = sharePhoneNumber; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2098628252; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a custom server language pack to the list of installed language packs in current localization target. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class AddCustomServerLanguagePack extends Function { - /** - * Identifier of a language pack to be added. - */ - public String languagePackId; - - /** - * Default constructor for a function, which adds a custom server language pack to the list of installed language packs in current localization target. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public AddCustomServerLanguagePack() { - } - - /** - * Creates a function, which adds a custom server language pack to the list of installed language packs in current localization target. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- * - * @param languagePackId Identifier of a language pack to be added. - */ - public AddCustomServerLanguagePack(String languagePackId) { - this.languagePackId = languagePackId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 4492771; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a new sticker to the list of favorite stickers. The new sticker is added to the top of the list. If the sticker was already in the list, it is removed from the list first. Only stickers belonging to a sticker set or in WEBP or WEBM format can be added to this list. Emoji stickers can't be added to favorite stickers. - * - *

Returns {@link Ok Ok}

- */ - public static class AddFavoriteSticker extends Function { - /** - * Sticker file to add. - */ - public InputFile sticker; - - /** - * Default constructor for a function, which adds a new sticker to the list of favorite stickers. The new sticker is added to the top of the list. If the sticker was already in the list, it is removed from the list first. Only stickers belonging to a sticker set or in WEBP or WEBM format can be added to this list. Emoji stickers can't be added to favorite stickers. - * - *

Returns {@link Ok Ok}

- */ - public AddFavoriteSticker() { - } - - /** - * Creates a function, which adds a new sticker to the list of favorite stickers. The new sticker is added to the top of the list. If the sticker was already in the list, it is removed from the list first. Only stickers belonging to a sticker set or in WEBP or WEBM format can be added to this list. Emoji stickers can't be added to favorite stickers. - * - *

Returns {@link Ok Ok}

- * - * @param sticker Sticker file to add. - */ - public AddFavoriteSticker(InputFile sticker) { - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 324504799; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a file from a message to the list of file downloads. Download progress and completion of the download will be notified through updateFile updates. If message database is used, the list of file downloads is persistent across application restarts. The downloading is independent of download using downloadFile, i.e. it continues if downloadFile is canceled or is used to download a part of the file. - * - *

Returns {@link File File}

- */ - public static class AddFileToDownloads extends Function { - /** - * Identifier of the file to download. - */ - public int fileId; - /** - * Chat identifier of the message with the file. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - /** - * Priority of the download (1-32). The higher the priority, the earlier the file will be downloaded. If the priorities of two files are equal, then the last one for which downloadFile/addFileToDownloads was called will be downloaded first. - */ - public int priority; - - /** - * Default constructor for a function, which adds a file from a message to the list of file downloads. Download progress and completion of the download will be notified through updateFile updates. If message database is used, the list of file downloads is persistent across application restarts. The downloading is independent of download using downloadFile, i.e. it continues if downloadFile is canceled or is used to download a part of the file. - * - *

Returns {@link File File}

- */ - public AddFileToDownloads() { - } - - /** - * Creates a function, which adds a file from a message to the list of file downloads. Download progress and completion of the download will be notified through updateFile updates. If message database is used, the list of file downloads is persistent across application restarts. The downloading is independent of download using downloadFile, i.e. it continues if downloadFile is canceled or is used to download a part of the file. - * - *

Returns {@link File File}

- * - * @param fileId Identifier of the file to download. - * @param chatId Chat identifier of the message with the file. - * @param messageId Message identifier. - * @param priority Priority of the download (1-32). The higher the priority, the earlier the file will be downloaded. If the priorities of two files are equal, then the last one for which downloadFile/addFileToDownloads was called will be downloaded first. - */ - public AddFileToDownloads(int fileId, long chatId, long messageId, int priority) { - this.fileId = fileId; - this.chatId = chatId; - this.messageId = messageId; - this.priority = priority; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 867533751; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds gifts to the beginning of a previously created collection. If the collection is owned by a channel chat, then requires canPostMessages administrator right in the channel chat. Returns the changed collection. - * - *

Returns {@link GiftCollection GiftCollection}

- */ - public static class AddGiftCollectionGifts extends Function { - /** - * Identifier of the user or the channel chat that owns the collection. - */ - public MessageSender ownerId; - /** - * Identifier of the gift collection. - */ - public int collectionId; - /** - * Identifier of the gifts to add to the collection; 1-getOption("gift_collection_size_max") identifiers. If after addition the collection has more than getOption("gift_collection_size_max") gifts, then the last one are removed from the collection. - */ - public String[] receivedGiftIds; - - /** - * Default constructor for a function, which adds gifts to the beginning of a previously created collection. If the collection is owned by a channel chat, then requires canPostMessages administrator right in the channel chat. Returns the changed collection. - * - *

Returns {@link GiftCollection GiftCollection}

- */ - public AddGiftCollectionGifts() { - } - - /** - * Creates a function, which adds gifts to the beginning of a previously created collection. If the collection is owned by a channel chat, then requires canPostMessages administrator right in the channel chat. Returns the changed collection. - * - *

Returns {@link GiftCollection GiftCollection}

- * - * @param ownerId Identifier of the user or the channel chat that owns the collection. - * @param collectionId Identifier of the gift collection. - * @param receivedGiftIds Identifier of the gifts to add to the collection; 1-getOption("gift_collection_size_max") identifiers. If after addition the collection has more than getOption("gift_collection_size_max") gifts, then the last one are removed from the collection. - */ - public AddGiftCollectionGifts(MessageSender ownerId, int collectionId, String[] receivedGiftIds) { - this.ownerId = ownerId; - this.collectionId = collectionId; - this.receivedGiftIds = receivedGiftIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -263464606; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a local message to a chat. The message is persistent across application restarts only if the message database is used. Returns the added message. - * - *

Returns {@link Message Message}

- */ - public static class AddLocalMessage extends Function { - /** - * Target chat; channel direct messages chats aren't supported. - */ - public long chatId; - /** - * Identifier of the sender of the message. - */ - public MessageSender senderId; - /** - * Information about the message or story to be replied; pass null if none. - */ - public InputMessageReplyTo replyTo; - /** - * Pass true to disable notification for the message. - */ - public boolean disableNotification; - /** - * The content of the message to be added. - */ - public InputMessageContent inputMessageContent; - - /** - * Default constructor for a function, which adds a local message to a chat. The message is persistent across application restarts only if the message database is used. Returns the added message. - * - *

Returns {@link Message Message}

- */ - public AddLocalMessage() { - } - - /** - * Creates a function, which adds a local message to a chat. The message is persistent across application restarts only if the message database is used. Returns the added message. - * - *

Returns {@link Message Message}

- * - * @param chatId Target chat; channel direct messages chats aren't supported. - * @param senderId Identifier of the sender of the message. - * @param replyTo Information about the message or story to be replied; pass null if none. - * @param disableNotification Pass true to disable notification for the message. - * @param inputMessageContent The content of the message to be added. - */ - public AddLocalMessage(long chatId, MessageSender senderId, InputMessageReplyTo replyTo, boolean disableNotification, InputMessageContent inputMessageContent) { - this.chatId = chatId; - this.senderId = senderId; - this.replyTo = replyTo; - this.disableNotification = disableNotification; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -166217823; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a message to TDLib internal log. Can be called synchronously. - * - *

Returns {@link Ok Ok}

- */ - public static class AddLogMessage extends Function { - /** - * The minimum verbosity level needed for the message to be logged; 0-1023. - */ - public int verbosityLevel; - /** - * Text of a message to log. - */ - public String text; - - /** - * Default constructor for a function, which adds a message to TDLib internal log. Can be called synchronously. - * - *

Returns {@link Ok Ok}

- */ - public AddLogMessage() { - } - - /** - * Creates a function, which adds a message to TDLib internal log. Can be called synchronously. - * - *

Returns {@link Ok Ok}

- * - * @param verbosityLevel The minimum verbosity level needed for the message to be logged; 0-1023. - * @param text Text of a message to log. - */ - public AddLogMessage(int verbosityLevel, String text) { - this.verbosityLevel = verbosityLevel; - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1597427692; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a passkey allowed to be used for the login by the current user and returns the added passkey. Call getPasskeyParameters to get parameters for creating of the passkey. - * - *

Returns {@link Passkey Passkey}

- */ - public static class AddLoginPasskey extends Function { - /** - * JSON-encoded client data. - */ - public String clientData; - /** - * Passkey attestation object. - */ - public byte[] attestationObject; - - /** - * Default constructor for a function, which adds a passkey allowed to be used for the login by the current user and returns the added passkey. Call getPasskeyParameters to get parameters for creating of the passkey. - * - *

Returns {@link Passkey Passkey}

- */ - public AddLoginPasskey() { - } - - /** - * Creates a function, which adds a passkey allowed to be used for the login by the current user and returns the added passkey. Call getPasskeyParameters to get parameters for creating of the passkey. - * - *

Returns {@link Passkey Passkey}

- * - * @param clientData JSON-encoded client data. - * @param attestationObject Passkey attestation object. - */ - public AddLoginPasskey(String clientData, byte[] attestationObject) { - this.clientData = clientData; - this.attestationObject = attestationObject; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1838899694; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a reaction or a tag to a message. Use getMessageAvailableReactions to receive the list of available reactions for the message. - * - *

Returns {@link Ok Ok}

- */ - public static class AddMessageReaction extends Function { - /** - * Identifier of the chat to which the message belongs. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * Type of the reaction to add. Use addPendingPaidMessageReaction instead to add the paid reaction. - */ - public ReactionType reactionType; - /** - * Pass true if the reaction is added with a big animation. - */ - public boolean isBig; - /** - * Pass true if the reaction needs to be added to recent reactions; tags are never added to the list of recent reactions. - */ - public boolean updateRecentReactions; - - /** - * Default constructor for a function, which adds a reaction or a tag to a message. Use getMessageAvailableReactions to receive the list of available reactions for the message. - * - *

Returns {@link Ok Ok}

- */ - public AddMessageReaction() { - } - - /** - * Creates a function, which adds a reaction or a tag to a message. Use getMessageAvailableReactions to receive the list of available reactions for the message. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat to which the message belongs. - * @param messageId Identifier of the message. - * @param reactionType Type of the reaction to add. Use addPendingPaidMessageReaction instead to add the paid reaction. - * @param isBig Pass true if the reaction is added with a big animation. - * @param updateRecentReactions Pass true if the reaction needs to be added to recent reactions; tags are never added to the list of recent reactions. - */ - public AddMessageReaction(long chatId, long messageId, ReactionType reactionType, boolean isBig, boolean updateRecentReactions) { - this.chatId = chatId; - this.messageId = messageId; - this.reactionType = reactionType; - this.isBig = isBig; - this.updateRecentReactions = updateRecentReactions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1419269613; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds the specified data to data usage statistics. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class AddNetworkStatistics extends Function { - /** - * The network statistics entry with the data to be added to statistics. - */ - public NetworkStatisticsEntry entry; - - /** - * Default constructor for a function, which adds the specified data to data usage statistics. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public AddNetworkStatistics() { - } - - /** - * Creates a function, which adds the specified data to data usage statistics. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- * - * @param entry The network statistics entry with the data to be added to statistics. - */ - public AddNetworkStatistics(NetworkStatisticsEntry entry) { - this.entry = entry; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1264825305; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends a suggested post based on a previously sent message in a channel direct messages chat. Can be also used to suggest price or time change for an existing suggested post. Returns the sent message. - * - *

Returns {@link Message Message}

- */ - public static class AddOffer extends Function { - /** - * Identifier of the channel direct messages chat. - */ - public long chatId; - /** - * Identifier of the message in the chat which will be sent as suggested post. Use messageProperties.canAddOffer to check whether an offer can be added or messageProperties.canEditSuggestedPostInfo to check whether price or time of sending of the post can be changed. - */ - public long messageId; - /** - * Options to be used to send the message. New information about the suggested post must always be specified. - */ - public MessageSendOptions options; - - /** - * Default constructor for a function, which sends a suggested post based on a previously sent message in a channel direct messages chat. Can be also used to suggest price or time change for an existing suggested post. Returns the sent message. - * - *

Returns {@link Message Message}

- */ - public AddOffer() { - } - - /** - * Creates a function, which sends a suggested post based on a previously sent message in a channel direct messages chat. Can be also used to suggest price or time change for an existing suggested post. Returns the sent message. - * - *

Returns {@link Message Message}

- * - * @param chatId Identifier of the channel direct messages chat. - * @param messageId Identifier of the message in the chat which will be sent as suggested post. Use messageProperties.canAddOffer to check whether an offer can be added or messageProperties.canEditSuggestedPostInfo to check whether price or time of sending of the post can be changed. - * @param options Options to be used to send the message. New information about the suggested post must always be specified. - */ - public AddOffer(long chatId, long messageId, MessageSendOptions options) { - this.chatId = chatId; - this.messageId = messageId; - this.options = options; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 682451739; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds pending paid reaction in a live story group call. Can't be used in live stories posted by the current user. Call commitPendingLiveStoryReactions or removePendingLiveStoryReactions to actually send all pending reactions when the undo timer is over or abort the sending. - * - *

Returns {@link Ok Ok}

- */ - public static class AddPendingLiveStoryReaction extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Number of Telegram Stars to be used for the reaction. The total number of pending paid reactions must not exceed getOption("paid_group_call_message_star_count_max"). - */ - public long starCount; - - /** - * Default constructor for a function, which adds pending paid reaction in a live story group call. Can't be used in live stories posted by the current user. Call commitPendingLiveStoryReactions or removePendingLiveStoryReactions to actually send all pending reactions when the undo timer is over or abort the sending. - * - *

Returns {@link Ok Ok}

- */ - public AddPendingLiveStoryReaction() { - } - - /** - * Creates a function, which adds pending paid reaction in a live story group call. Can't be used in live stories posted by the current user. Call commitPendingLiveStoryReactions or removePendingLiveStoryReactions to actually send all pending reactions when the undo timer is over or abort the sending. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param starCount Number of Telegram Stars to be used for the reaction. The total number of pending paid reactions must not exceed getOption("paid_group_call_message_star_count_max"). - */ - public AddPendingLiveStoryReaction(int groupCallId, long starCount) { - this.groupCallId = groupCallId; - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 661166197; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds the paid message reaction to a message. Use getMessageAvailableReactions to check whether the reaction is available for the message. - * - *

Returns {@link Ok Ok}

- */ - public static class AddPendingPaidMessageReaction extends Function { - /** - * Identifier of the chat to which the message belongs. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * Number of Telegram Stars to be used for the reaction. The total number of pending paid reactions must not exceed getOption("paid_reaction_star_count_max"). - */ - public long starCount; - /** - * Type of the paid reaction; pass null if the user didn't choose reaction type explicitly, for example, the reaction is set from the message bubble. - */ - public PaidReactionType type; - - /** - * Default constructor for a function, which adds the paid message reaction to a message. Use getMessageAvailableReactions to check whether the reaction is available for the message. - * - *

Returns {@link Ok Ok}

- */ - public AddPendingPaidMessageReaction() { - } - - /** - * Creates a function, which adds the paid message reaction to a message. Use getMessageAvailableReactions to check whether the reaction is available for the message. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat to which the message belongs. - * @param messageId Identifier of the message. - * @param starCount Number of Telegram Stars to be used for the reaction. The total number of pending paid reactions must not exceed getOption("paid_reaction_star_count_max"). - * @param type Type of the paid reaction; pass null if the user didn't choose reaction type explicitly, for example, the reaction is set from the message bubble. - */ - public AddPendingPaidMessageReaction(long chatId, long messageId, long starCount, PaidReactionType type) { - this.chatId = chatId; - this.messageId = messageId; - this.starCount = starCount; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -342110765; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds an audio file to the beginning of the profile audio files of the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class AddProfileAudio extends Function { - /** - * Identifier of the audio file to be added. The file must have been uploaded to the server. - */ - public int fileId; - - /** - * Default constructor for a function, which adds an audio file to the beginning of the profile audio files of the current user. - * - *

Returns {@link Ok Ok}

- */ - public AddProfileAudio() { - } - - /** - * Creates a function, which adds an audio file to the beginning of the profile audio files of the current user. - * - *

Returns {@link Ok Ok}

- * - * @param fileId Identifier of the audio file to be added. The file must have been uploaded to the server. - */ - public AddProfileAudio(int fileId) { - this.fileId = fileId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 393218847; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a proxy server for network requests. Can be called before authorization. - * - *

Returns {@link AddedProxy AddedProxy}

- */ - public static class AddProxy extends Function { - /** - * The proxy to add. - */ - public Proxy proxy; - /** - * Pass true to immediately enable the proxy. - */ - public boolean enable; - - /** - * Default constructor for a function, which adds a proxy server for network requests. Can be called before authorization. - * - *

Returns {@link AddedProxy AddedProxy}

- */ - public AddProxy() { - } - - /** - * Creates a function, which adds a proxy server for network requests. Can be called before authorization. - * - *

Returns {@link AddedProxy AddedProxy}

- * - * @param proxy The proxy to add. - * @param enable Pass true to immediately enable the proxy. - */ - public AddProxy(Proxy proxy, boolean enable) { - this.proxy = proxy; - this.enable = enable; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 471098860; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a message to a quick reply shortcut via inline bot. If shortcut doesn't exist and there are less than getOption("quick_reply_shortcut_count_max") shortcuts, then a new shortcut is created. The shortcut must not contain more than getOption("quick_reply_shortcut_message_count_max") messages after adding the new message. Returns the added message. - * - *

Returns {@link QuickReplyMessage QuickReplyMessage}

- */ - public static class AddQuickReplyShortcutInlineQueryResultMessage extends Function { - /** - * Name of the target shortcut. - */ - public String shortcutName; - /** - * Identifier of a quick reply message in the same shortcut to be replied; pass 0 if none. - */ - public long replyToMessageId; - /** - * Identifier of the inline query. - */ - public long queryId; - /** - * Identifier of the inline query result. - */ - public String resultId; - /** - * Pass true to hide the bot, via which the message is sent. Can be used only for bots getOption("animation_search_bot_username"), getOption("photo_search_bot_username"), and getOption("venue_search_bot_username"). - */ - public boolean hideViaBot; - - /** - * Default constructor for a function, which adds a message to a quick reply shortcut via inline bot. If shortcut doesn't exist and there are less than getOption("quick_reply_shortcut_count_max") shortcuts, then a new shortcut is created. The shortcut must not contain more than getOption("quick_reply_shortcut_message_count_max") messages after adding the new message. Returns the added message. - * - *

Returns {@link QuickReplyMessage QuickReplyMessage}

- */ - public AddQuickReplyShortcutInlineQueryResultMessage() { - } - - /** - * Creates a function, which adds a message to a quick reply shortcut via inline bot. If shortcut doesn't exist and there are less than getOption("quick_reply_shortcut_count_max") shortcuts, then a new shortcut is created. The shortcut must not contain more than getOption("quick_reply_shortcut_message_count_max") messages after adding the new message. Returns the added message. - * - *

Returns {@link QuickReplyMessage QuickReplyMessage}

- * - * @param shortcutName Name of the target shortcut. - * @param replyToMessageId Identifier of a quick reply message in the same shortcut to be replied; pass 0 if none. - * @param queryId Identifier of the inline query. - * @param resultId Identifier of the inline query result. - * @param hideViaBot Pass true to hide the bot, via which the message is sent. Can be used only for bots getOption("animation_search_bot_username"), getOption("photo_search_bot_username"), and getOption("venue_search_bot_username"). - */ - public AddQuickReplyShortcutInlineQueryResultMessage(String shortcutName, long replyToMessageId, long queryId, String resultId, boolean hideViaBot) { - this.shortcutName = shortcutName; - this.replyToMessageId = replyToMessageId; - this.queryId = queryId; - this.resultId = resultId; - this.hideViaBot = hideViaBot; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2017449468; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a message to a quick reply shortcut. If shortcut doesn't exist and there are less than getOption("quick_reply_shortcut_count_max") shortcuts, then a new shortcut is created. The shortcut must not contain more than getOption("quick_reply_shortcut_message_count_max") messages after adding the new message. Returns the added message. - * - *

Returns {@link QuickReplyMessage QuickReplyMessage}

- */ - public static class AddQuickReplyShortcutMessage extends Function { - /** - * Name of the target shortcut. - */ - public String shortcutName; - /** - * Identifier of a quick reply message in the same shortcut to be replied; pass 0 if none. - */ - public long replyToMessageId; - /** - * The content of the message to be added; inputMessagePaidMedia, inputMessageForwarded and inputMessageLocation with livePeriod aren't supported. - */ - public InputMessageContent inputMessageContent; - - /** - * Default constructor for a function, which adds a message to a quick reply shortcut. If shortcut doesn't exist and there are less than getOption("quick_reply_shortcut_count_max") shortcuts, then a new shortcut is created. The shortcut must not contain more than getOption("quick_reply_shortcut_message_count_max") messages after adding the new message. Returns the added message. - * - *

Returns {@link QuickReplyMessage QuickReplyMessage}

- */ - public AddQuickReplyShortcutMessage() { - } - - /** - * Creates a function, which adds a message to a quick reply shortcut. If shortcut doesn't exist and there are less than getOption("quick_reply_shortcut_count_max") shortcuts, then a new shortcut is created. The shortcut must not contain more than getOption("quick_reply_shortcut_message_count_max") messages after adding the new message. Returns the added message. - * - *

Returns {@link QuickReplyMessage QuickReplyMessage}

- * - * @param shortcutName Name of the target shortcut. - * @param replyToMessageId Identifier of a quick reply message in the same shortcut to be replied; pass 0 if none. - * @param inputMessageContent The content of the message to be added; inputMessagePaidMedia, inputMessageForwarded and inputMessageLocation with livePeriod aren't supported. - */ - public AddQuickReplyShortcutMessage(String shortcutName, long replyToMessageId, InputMessageContent inputMessageContent) { - this.shortcutName = shortcutName; - this.replyToMessageId = replyToMessageId; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1058573098; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds 2-10 messages grouped together into an album to a quick reply shortcut. Currently, only audio, document, photo and video messages can be grouped into an album. Documents and audio files can be only grouped in an album with messages of the same type. Returns sent messages. - * - *

Returns {@link QuickReplyMessages QuickReplyMessages}

- */ - public static class AddQuickReplyShortcutMessageAlbum extends Function { - /** - * Name of the target shortcut. - */ - public String shortcutName; - /** - * Identifier of a quick reply message in the same shortcut to be replied; pass 0 if none. - */ - public long replyToMessageId; - /** - * Contents of messages to be sent. At most 10 messages can be added to an album. All messages must have the same value of showCaptionAboveMedia. - */ - public InputMessageContent[] inputMessageContents; - - /** - * Default constructor for a function, which adds 2-10 messages grouped together into an album to a quick reply shortcut. Currently, only audio, document, photo and video messages can be grouped into an album. Documents and audio files can be only grouped in an album with messages of the same type. Returns sent messages. - * - *

Returns {@link QuickReplyMessages QuickReplyMessages}

- */ - public AddQuickReplyShortcutMessageAlbum() { - } - - /** - * Creates a function, which adds 2-10 messages grouped together into an album to a quick reply shortcut. Currently, only audio, document, photo and video messages can be grouped into an album. Documents and audio files can be only grouped in an album with messages of the same type. Returns sent messages. - * - *

Returns {@link QuickReplyMessages QuickReplyMessages}

- * - * @param shortcutName Name of the target shortcut. - * @param replyToMessageId Identifier of a quick reply message in the same shortcut to be replied; pass 0 if none. - * @param inputMessageContents Contents of messages to be sent. At most 10 messages can be added to an album. All messages must have the same value of showCaptionAboveMedia. - */ - public AddQuickReplyShortcutMessageAlbum(String shortcutName, long replyToMessageId, InputMessageContent[] inputMessageContents) { - this.shortcutName = shortcutName; - this.replyToMessageId = replyToMessageId; - this.inputMessageContents = inputMessageContents; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1348436244; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Manually adds a new sticker to the list of recently used stickers. The new sticker is added to the top of the list. If the sticker was already in the list, it is removed from the list first. Only stickers belonging to a sticker set or in WEBP or WEBM format can be added to this list. Emoji stickers can't be added to recent stickers. - * - *

Returns {@link Stickers Stickers}

- */ - public static class AddRecentSticker extends Function { - /** - * Pass true to add the sticker to the list of stickers recently attached to photo or video files; pass false to add the sticker to the list of recently sent stickers. - */ - public boolean isAttached; - /** - * Sticker file to add. - */ - public InputFile sticker; - - /** - * Default constructor for a function, which manually adds a new sticker to the list of recently used stickers. The new sticker is added to the top of the list. If the sticker was already in the list, it is removed from the list first. Only stickers belonging to a sticker set or in WEBP or WEBM format can be added to this list. Emoji stickers can't be added to recent stickers. - * - *

Returns {@link Stickers Stickers}

- */ - public AddRecentSticker() { - } - - /** - * Creates a function, which manually adds a new sticker to the list of recently used stickers. The new sticker is added to the top of the list. If the sticker was already in the list, it is removed from the list first. Only stickers belonging to a sticker set or in WEBP or WEBM format can be added to this list. Emoji stickers can't be added to recent stickers. - * - *

Returns {@link Stickers Stickers}

- * - * @param isAttached Pass true to add the sticker to the list of stickers recently attached to photo or video files; pass false to add the sticker to the list of recently sent stickers. - * @param sticker Sticker file to add. - */ - public AddRecentSticker(boolean isAttached, InputFile sticker) { - this.isAttached = isAttached; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1478109026; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a chat to the list of recently found chats. The chat is added to the beginning of the list. If the chat is already in the list, it will be removed from the list first. - * - *

Returns {@link Ok Ok}

- */ - public static class AddRecentlyFoundChat extends Function { - /** - * Identifier of the chat to add. - */ - public long chatId; - - /** - * Default constructor for a function, which adds a chat to the list of recently found chats. The chat is added to the beginning of the list. If the chat is already in the list, it will be removed from the list first. - * - *

Returns {@link Ok Ok}

- */ - public AddRecentlyFoundChat() { - } - - /** - * Creates a function, which adds a chat to the list of recently found chats. The chat is added to the beginning of the list. If the chat is already in the list, it will be removed from the list first. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat to add. - */ - public AddRecentlyFoundChat(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1746396787; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Manually adds a new animation to the list of saved animations. The new animation is added to the beginning of the list. If the animation was already in the list, it is removed first. Only non-secret video animations with MIME type "video/mp4" can be added to the list. - * - *

Returns {@link Ok Ok}

- */ - public static class AddSavedAnimation extends Function { - /** - * The animation file to be added. Only animations known to the server (i.e., successfully sent via a message) can be added to the list. - */ - public InputFile animation; - - /** - * Default constructor for a function, which manually adds a new animation to the list of saved animations. The new animation is added to the beginning of the list. If the animation was already in the list, it is removed first. Only non-secret video animations with MIME type "video/mp4" can be added to the list. - * - *

Returns {@link Ok Ok}

- */ - public AddSavedAnimation() { - } - - /** - * Creates a function, which manually adds a new animation to the list of saved animations. The new animation is added to the beginning of the list. If the animation was already in the list, it is removed first. Only non-secret video animations with MIME type "video/mp4" can be added to the list. - * - *

Returns {@link Ok Ok}

- * - * @param animation The animation file to be added. Only animations known to the server (i.e., successfully sent via a message) can be added to the list. - */ - public AddSavedAnimation(InputFile animation) { - this.animation = animation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1538525088; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a new notification sound to the list of saved notification sounds. The new notification sound is added to the top of the list. If it is already in the list, its position isn't changed. - * - *

Returns {@link NotificationSound NotificationSound}

- */ - public static class AddSavedNotificationSound extends Function { - /** - * Notification sound file to add. - */ - public InputFile sound; - - /** - * Default constructor for a function, which adds a new notification sound to the list of saved notification sounds. The new notification sound is added to the top of the list. If it is already in the list, its position isn't changed. - * - *

Returns {@link NotificationSound NotificationSound}

- */ - public AddSavedNotificationSound() { - } - - /** - * Creates a function, which adds a new notification sound to the list of saved notification sounds. The new notification sound is added to the top of the list. If it is already in the list, its position isn't changed. - * - *

Returns {@link NotificationSound NotificationSound}

- * - * @param sound Notification sound file to add. - */ - public AddSavedNotificationSound(InputFile sound) { - this.sound = sound; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1043956975; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds a new sticker to a set. - * - *

Returns {@link Ok Ok}

- */ - public static class AddStickerToSet extends Function { - /** - * Sticker set owner; ignored for regular users. - */ - public long userId; - /** - * Sticker set name. The sticker set must be owned by the current user, and contain less than 200 stickers for custom emoji sticker sets and less than 120 otherwise. - */ - public String name; - /** - * Sticker to add to the set. - */ - public InputSticker sticker; - - /** - * Default constructor for a function, which adds a new sticker to a set. - * - *

Returns {@link Ok Ok}

- */ - public AddStickerToSet() { - } - - /** - * Creates a function, which adds a new sticker to a set. - * - *

Returns {@link Ok Ok}

- * - * @param userId Sticker set owner; ignored for regular users. - * @param name Sticker set name. The sticker set must be owned by the current user, and contain less than 200 stickers for custom emoji sticker sets and less than 120 otherwise. - * @param sticker Sticker to add to the set. - */ - public AddStickerToSet(long userId, String name, InputSticker sticker) { - this.userId = userId; - this.name = name; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1457266235; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds stories to the beginning of a previously created story album. If the album is owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. Returns the changed album. - * - *

Returns {@link StoryAlbum StoryAlbum}

- */ - public static class AddStoryAlbumStories extends Function { - /** - * Identifier of the chat that owns the stories. - */ - public long chatId; - /** - * Identifier of the story album. - */ - public int storyAlbumId; - /** - * Identifier of the stories to add to the album; 1-getOption("story_album_size_max") identifiers. If after addition the album has more than getOption("story_album_size_max") stories, then the last one are removed from the album. - */ - public int[] storyIds; - - /** - * Default constructor for a function, which adds stories to the beginning of a previously created story album. If the album is owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. Returns the changed album. - * - *

Returns {@link StoryAlbum StoryAlbum}

- */ - public AddStoryAlbumStories() { - } - - /** - * Creates a function, which adds stories to the beginning of a previously created story album. If the album is owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. Returns the changed album. - * - *

Returns {@link StoryAlbum StoryAlbum}

- * - * @param chatId Identifier of the chat that owns the stories. - * @param storyAlbumId Identifier of the story album. - * @param storyIds Identifier of the stories to add to the album; 1-getOption("story_album_size_max") identifiers. If after addition the album has more than getOption("story_album_size_max") stories, then the last one are removed from the album. - */ - public AddStoryAlbumStories(long chatId, int storyAlbumId, int[] storyIds) { - this.chatId = chatId; - this.storyAlbumId = storyAlbumId; - this.storyIds = storyIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -537692984; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Allows the specified bot to send messages to the user. - * - *

Returns {@link Ok Ok}

- */ - public static class AllowBotToSendMessages extends Function { - /** - * Identifier of the target bot. - */ - public long botUserId; - - /** - * Default constructor for a function, which allows the specified bot to send messages to the user. - * - *

Returns {@link Ok Ok}

- */ - public AllowBotToSendMessages() { - } - - /** - * Creates a function, which allows the specified bot to send messages to the user. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId Identifier of the target bot. - */ - public AllowBotToSendMessages(long botUserId) { - this.botUserId = botUserId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1776928142; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Allows the specified user to send unpaid private messages to the current user by adding a rule to userPrivacySettingAllowUnpaidMessages. - * - *

Returns {@link Ok Ok}

- */ - public static class AllowUnpaidMessagesFromUser extends Function { - /** - * Identifier of the user. - */ - public long userId; - /** - * Pass true to refund the user previously paid messages. - */ - public boolean refundPayments; - - /** - * Default constructor for a function, which allows the specified user to send unpaid private messages to the current user by adding a rule to userPrivacySettingAllowUnpaidMessages. - * - *

Returns {@link Ok Ok}

- */ - public AllowUnpaidMessagesFromUser() { - } - - /** - * Creates a function, which allows the specified user to send unpaid private messages to the current user by adding a rule to userPrivacySettingAllowUnpaidMessages. - * - *

Returns {@link Ok Ok}

- * - * @param userId Identifier of the user. - * @param refundPayments Pass true to refund the user previously paid messages. - */ - public AllowUnpaidMessagesFromUser(long userId, boolean refundPayments) { - this.userId = userId; - this.refundPayments = refundPayments; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 803569495; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets the result of a callback query; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class AnswerCallbackQuery extends Function { - /** - * Identifier of the callback query. - */ - public long callbackQueryId; - /** - * Text of the answer. - */ - public String text; - /** - * Pass true to show an alert to the user instead of a toast notification. - */ - public boolean showAlert; - /** - * URL to be opened. - */ - public String url; - /** - * Time during which the result of the query can be cached, in seconds. - */ - public int cacheTime; - - /** - * Default constructor for a function, which sets the result of a callback query; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public AnswerCallbackQuery() { - } - - /** - * Creates a function, which sets the result of a callback query; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param callbackQueryId Identifier of the callback query. - * @param text Text of the answer. - * @param showAlert Pass true to show an alert to the user instead of a toast notification. - * @param url URL to be opened. - * @param cacheTime Time during which the result of the query can be cached, in seconds. - */ - public AnswerCallbackQuery(long callbackQueryId, String text, boolean showAlert, String url, int cacheTime) { - this.callbackQueryId = callbackQueryId; - this.text = text; - this.showAlert = showAlert; - this.url = url; - this.cacheTime = cacheTime; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1153028490; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Answers a custom query; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class AnswerCustomQuery extends Function { - /** - * Identifier of a custom query. - */ - public long customQueryId; - /** - * JSON-serialized answer to the query. - */ - public String data; - - /** - * Default constructor for a function, which answers a custom query; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public AnswerCustomQuery() { - } - - /** - * Creates a function, which answers a custom query; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param customQueryId Identifier of a custom query. - * @param data JSON-serialized answer to the query. - */ - public AnswerCustomQuery(long customQueryId, String data) { - this.customQueryId = customQueryId; - this.data = data; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1293603521; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets the result of an inline query; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class AnswerInlineQuery extends Function { - /** - * Identifier of the inline query. - */ - public long inlineQueryId; - /** - * Pass true if results may be cached and returned only for the user who sent the query. By default, results may be returned to any user who sends the same query. - */ - public boolean isPersonal; - /** - * Button to be shown above inline query results; pass null if none. - */ - public InlineQueryResultsButton button; - /** - * The results of the query. - */ - public InputInlineQueryResult[] results; - /** - * Allowed time to cache the results of the query, in seconds. - */ - public int cacheTime; - /** - * Offset for the next inline query; pass an empty string if there are no more results. - */ - public String nextOffset; - - /** - * Default constructor for a function, which sets the result of an inline query; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public AnswerInlineQuery() { - } - - /** - * Creates a function, which sets the result of an inline query; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param inlineQueryId Identifier of the inline query. - * @param isPersonal Pass true if results may be cached and returned only for the user who sent the query. By default, results may be returned to any user who sends the same query. - * @param button Button to be shown above inline query results; pass null if none. - * @param results The results of the query. - * @param cacheTime Allowed time to cache the results of the query, in seconds. - * @param nextOffset Offset for the next inline query; pass an empty string if there are no more results. - */ - public AnswerInlineQuery(long inlineQueryId, boolean isPersonal, InlineQueryResultsButton button, InputInlineQueryResult[] results, int cacheTime, String nextOffset) { - this.inlineQueryId = inlineQueryId; - this.isPersonal = isPersonal; - this.button = button; - this.results = results; - this.cacheTime = cacheTime; - this.nextOffset = nextOffset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1343853844; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets the result of a pre-checkout query; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class AnswerPreCheckoutQuery extends Function { - /** - * Identifier of the pre-checkout query. - */ - public long preCheckoutQueryId; - /** - * An error message, empty on success. - */ - public String errorMessage; - - /** - * Default constructor for a function, which sets the result of a pre-checkout query; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public AnswerPreCheckoutQuery() { - } - - /** - * Creates a function, which sets the result of a pre-checkout query; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param preCheckoutQueryId Identifier of the pre-checkout query. - * @param errorMessage An error message, empty on success. - */ - public AnswerPreCheckoutQuery(long preCheckoutQueryId, String errorMessage) { - this.preCheckoutQueryId = preCheckoutQueryId; - this.errorMessage = errorMessage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1486789653; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets the result of a shipping query; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class AnswerShippingQuery extends Function { - /** - * Identifier of the shipping query. - */ - public long shippingQueryId; - /** - * Available shipping options. - */ - public ShippingOption[] shippingOptions; - /** - * An error message, empty on success. - */ - public String errorMessage; - - /** - * Default constructor for a function, which sets the result of a shipping query; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public AnswerShippingQuery() { - } - - /** - * Creates a function, which sets the result of a shipping query; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param shippingQueryId Identifier of the shipping query. - * @param shippingOptions Available shipping options. - * @param errorMessage An error message, empty on success. - */ - public AnswerShippingQuery(long shippingQueryId, ShippingOption[] shippingOptions, String errorMessage) { - this.shippingQueryId = shippingQueryId; - this.shippingOptions = shippingOptions; - this.errorMessage = errorMessage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -434601324; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets the result of interaction with a Web App and sends corresponding message on behalf of the user to the chat from which the query originated; for bots only. - * - *

Returns {@link SentWebAppMessage SentWebAppMessage}

- */ - public static class AnswerWebAppQuery extends Function { - /** - * Identifier of the Web App query. - */ - public String webAppQueryId; - /** - * The result of the query. - */ - public InputInlineQueryResult result; - - /** - * Default constructor for a function, which sets the result of interaction with a Web App and sends corresponding message on behalf of the user to the chat from which the query originated; for bots only. - * - *

Returns {@link SentWebAppMessage SentWebAppMessage}

- */ - public AnswerWebAppQuery() { - } - - /** - * Creates a function, which sets the result of interaction with a Web App and sends corresponding message on behalf of the user to the chat from which the query originated; for bots only. - * - *

Returns {@link SentWebAppMessage SentWebAppMessage}

- * - * @param webAppQueryId Identifier of the Web App query. - * @param result The result of the query. - */ - public AnswerWebAppQuery(String webAppQueryId, InputInlineQueryResult result) { - this.webAppQueryId = webAppQueryId; - this.result = result; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1598776079; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Applies a Telegram Premium gift code. - * - *

Returns {@link Ok Ok}

- */ - public static class ApplyPremiumGiftCode extends Function { - /** - * The code to apply. - */ - public String code; - - /** - * Default constructor for a function, which applies a Telegram Premium gift code. - * - *

Returns {@link Ok Ok}

- */ - public ApplyPremiumGiftCode() { - } - - /** - * Creates a function, which applies a Telegram Premium gift code. - * - *

Returns {@link Ok Ok}

- * - * @param code The code to apply. - */ - public ApplyPremiumGiftCode(String code) { - this.code = code; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1347138530; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Approves a suggested post in a channel direct messages chat. - * - *

Returns {@link Ok Ok}

- */ - public static class ApproveSuggestedPost extends Function { - /** - * Chat identifier of the channel direct messages chat. - */ - public long chatId; - /** - * Identifier of the message with the suggested post. Use messageProperties.canBeApproved to check whether the suggested post can be approved. - */ - public long messageId; - /** - * Point in time (Unix timestamp) when the post is expected to be published; pass 0 if the date has already been chosen. If specified, then the date must be in the future, but at most getOption("suggested_post_send_delay_max") seconds in the future. - */ - public int sendDate; - - /** - * Default constructor for a function, which approves a suggested post in a channel direct messages chat. - * - *

Returns {@link Ok Ok}

- */ - public ApproveSuggestedPost() { - } - - /** - * Creates a function, which approves a suggested post in a channel direct messages chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier of the channel direct messages chat. - * @param messageId Identifier of the message with the suggested post. Use messageProperties.canBeApproved to check whether the suggested post can be approved. - * @param sendDate Point in time (Unix timestamp) when the post is expected to be published; pass 0 if the date has already been chosen. If specified, then the date must be in the future, but at most getOption("suggested_post_send_delay_max") seconds in the future. - */ - public ApproveSuggestedPost(long chatId, long messageId, int sendDate) { - this.chatId = chatId; - this.messageId = messageId; - this.sendDate = sendDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -924807202; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs server about an in-store purchase. For official applications only. - * - *

Returns {@link Ok Ok}

- */ - public static class AssignStoreTransaction extends Function { - /** - * Information about the transaction. - */ - public StoreTransaction transaction; - /** - * Transaction purpose. - */ - public StorePaymentPurpose purpose; - - /** - * Default constructor for a function, which informs server about an in-store purchase. For official applications only. - * - *

Returns {@link Ok Ok}

- */ - public AssignStoreTransaction() { - } - - /** - * Creates a function, which informs server about an in-store purchase. For official applications only. - * - *

Returns {@link Ok Ok}

- * - * @param transaction Information about the transaction. - * @param purpose Transaction purpose. - */ - public AssignStoreTransaction(StoreTransaction transaction, StorePaymentPurpose purpose) { - this.transaction = transaction; - this.purpose = purpose; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2046202900; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Bans a member in a chat; requires canRestrictMembers administrator right. Members can't be banned in private or secret chats. In supergroups and channels, the user will not be able to return to the group on their own using invite links, etc., unless unbanned first. - * - *

Returns {@link Ok Ok}

- */ - public static class BanChatMember extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Member identifier. - */ - public MessageSender memberId; - /** - * Point in time (Unix timestamp) when the user will be unbanned; 0 if never. If the user is banned for more than 366 days or for less than 30 seconds from the current time, the user is considered to be banned forever. Ignored in basic groups and if a chat is banned. - */ - public int bannedUntilDate; - /** - * Pass true to delete all messages in the chat for the user who is being removed. Always true for supergroups and channels. - */ - public boolean revokeMessages; - - /** - * Default constructor for a function, which bans a member in a chat; requires canRestrictMembers administrator right. Members can't be banned in private or secret chats. In supergroups and channels, the user will not be able to return to the group on their own using invite links, etc., unless unbanned first. - * - *

Returns {@link Ok Ok}

- */ - public BanChatMember() { - } - - /** - * Creates a function, which bans a member in a chat; requires canRestrictMembers administrator right. Members can't be banned in private or secret chats. In supergroups and channels, the user will not be able to return to the group on their own using invite links, etc., unless unbanned first. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param memberId Member identifier. - * @param bannedUntilDate Point in time (Unix timestamp) when the user will be unbanned; 0 if never. If the user is banned for more than 366 days or for less than 30 seconds from the current time, the user is considered to be banned forever. Ignored in basic groups and if a chat is banned. - * @param revokeMessages Pass true to delete all messages in the chat for the user who is being removed. Always true for supergroups and channels. - */ - public BanChatMember(long chatId, MessageSender memberId, int bannedUntilDate, boolean revokeMessages) { - this.chatId = chatId; - this.memberId = memberId; - this.bannedUntilDate = bannedUntilDate; - this.revokeMessages = revokeMessages; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -888111748; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Bans users from a group call not bound to a chat; requires groupCall.isOwned. Only the owner of the group call can invite the banned users back. - * - *

Returns {@link Ok Ok}

- */ - public static class BanGroupCallParticipants extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Identifiers of group call participants to ban; identifiers of unknown users from the update updateGroupCallParticipants can be also passed to the method. - */ - public long[] userIds; - - /** - * Default constructor for a function, which bans users from a group call not bound to a chat; requires groupCall.isOwned. Only the owner of the group call can invite the banned users back. - * - *

Returns {@link Ok Ok}

- */ - public BanGroupCallParticipants() { - } - - /** - * Creates a function, which bans users from a group call not bound to a chat; requires groupCall.isOwned. Only the owner of the group call can invite the banned users back. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param userIds Identifiers of group call participants to ban; identifiers of unknown users from the update updateGroupCallParticipants can be also passed to the method. - */ - public BanGroupCallParticipants(int groupCallId, long[] userIds) { - this.groupCallId = groupCallId; - this.userIds = userIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 624883173; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Blocks an original sender of a message in the Replies chat. - * - *

Returns {@link Ok Ok}

- */ - public static class BlockMessageSenderFromReplies extends Function { - /** - * The identifier of an incoming message in the Replies chat. - */ - public long messageId; - /** - * Pass true to delete the message. - */ - public boolean deleteMessage; - /** - * Pass true to delete all messages from the same sender. - */ - public boolean deleteAllMessages; - /** - * Pass true to report the sender to the Telegram moderators. - */ - public boolean reportSpam; - - /** - * Default constructor for a function, which blocks an original sender of a message in the Replies chat. - * - *

Returns {@link Ok Ok}

- */ - public BlockMessageSenderFromReplies() { - } - - /** - * Creates a function, which blocks an original sender of a message in the Replies chat. - * - *

Returns {@link Ok Ok}

- * - * @param messageId The identifier of an incoming message in the Replies chat. - * @param deleteMessage Pass true to delete the message. - * @param deleteAllMessages Pass true to delete all messages from the same sender. - * @param reportSpam Pass true to report the sender to the Telegram moderators. - */ - public BlockMessageSenderFromReplies(long messageId, boolean deleteMessage, boolean deleteAllMessages, boolean reportSpam) { - this.messageId = messageId; - this.deleteMessage = deleteMessage; - this.deleteAllMessages = deleteAllMessages; - this.reportSpam = reportSpam; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1214384757; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Boosts a chat and returns the list of available chat boost slots for the current user after the boost. - * - *

Returns {@link ChatBoostSlots ChatBoostSlots}

- */ - public static class BoostChat extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * Identifiers of boost slots of the current user from which to apply boosts to the chat. - */ - public int[] slotIds; - - /** - * Default constructor for a function, which boosts a chat and returns the list of available chat boost slots for the current user after the boost. - * - *

Returns {@link ChatBoostSlots ChatBoostSlots}

- */ - public BoostChat() { - } - - /** - * Creates a function, which boosts a chat and returns the list of available chat boost slots for the current user after the boost. - * - *

Returns {@link ChatBoostSlots ChatBoostSlots}

- * - * @param chatId Identifier of the chat. - * @param slotIds Identifiers of boost slots of the current user from which to apply boosts to the chat. - */ - public BoostChat(long chatId, int[] slotIds) { - this.chatId = chatId; - this.slotIds = slotIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1945750252; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Pays for upgrade of a regular gift that is owned by another user or channel chat. - * - *

Returns {@link Ok Ok}

- */ - public static class BuyGiftUpgrade extends Function { - /** - * Identifier of the user or the channel chat that owns the gift. - */ - public MessageSender ownerId; - /** - * Prepaid upgrade hash as received along with the gift. - */ - public String prepaidUpgradeHash; - /** - * The Telegram Star amount the user agreed to pay for the upgrade; must be equal to gift.upgradeStarCount. - */ - public long starCount; - - /** - * Default constructor for a function, which pays for upgrade of a regular gift that is owned by another user or channel chat. - * - *

Returns {@link Ok Ok}

- */ - public BuyGiftUpgrade() { - } - - /** - * Creates a function, which pays for upgrade of a regular gift that is owned by another user or channel chat. - * - *

Returns {@link Ok Ok}

- * - * @param ownerId Identifier of the user or the channel chat that owns the gift. - * @param prepaidUpgradeHash Prepaid upgrade hash as received along with the gift. - * @param starCount The Telegram Star amount the user agreed to pay for the upgrade; must be equal to gift.upgradeStarCount. - */ - public BuyGiftUpgrade(MessageSender ownerId, String prepaidUpgradeHash, long starCount) { - this.ownerId = ownerId; - this.prepaidUpgradeHash = prepaidUpgradeHash; - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 154296026; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks whether the specified bot can send messages to the user. Returns a 404 error if can't and the access can be granted by call to allowBotToSendMessages. - * - *

Returns {@link Ok Ok}

- */ - public static class CanBotSendMessages extends Function { - /** - * Identifier of the target bot. - */ - public long botUserId; - - /** - * Default constructor for a function, which checks whether the specified bot can send messages to the user. Returns a 404 error if can't and the access can be granted by call to allowBotToSendMessages. - * - *

Returns {@link Ok Ok}

- */ - public CanBotSendMessages() { - } - - /** - * Creates a function, which checks whether the specified bot can send messages to the user. Returns a 404 error if can't and the access can be granted by call to allowBotToSendMessages. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId Identifier of the target bot. - */ - public CanBotSendMessages(long botUserId) { - this.botUserId = botUserId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 544052364; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks whether the current user can post a story on behalf of a chat; requires canPostStories administrator right for supergroup and channel chats. - * - *

Returns {@link CanPostStoryResult CanPostStoryResult}

- */ - public static class CanPostStory extends Function { - /** - * Chat identifier. Pass Saved Messages chat identifier when posting a story on behalf of the current user. - */ - public long chatId; - - /** - * Default constructor for a function, which checks whether the current user can post a story on behalf of a chat; requires canPostStories administrator right for supergroup and channel chats. - * - *

Returns {@link CanPostStoryResult CanPostStoryResult}

- */ - public CanPostStory() { - } - - /** - * Creates a function, which checks whether the current user can post a story on behalf of a chat; requires canPostStories administrator right for supergroup and channel chats. - * - *

Returns {@link CanPostStoryResult CanPostStoryResult}

- * - * @param chatId Chat identifier. Pass Saved Messages chat identifier when posting a story on behalf of the current user. - */ - public CanPostStory(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 668621518; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks whether an in-store purchase is possible. Must be called before any in-store purchase. For official applications only. - * - *

Returns {@link Ok Ok}

- */ - public static class CanPurchaseFromStore extends Function { - /** - * Transaction purpose. - */ - public StorePaymentPurpose purpose; - - /** - * Default constructor for a function, which checks whether an in-store purchase is possible. Must be called before any in-store purchase. For official applications only. - * - *

Returns {@link Ok Ok}

- */ - public CanPurchaseFromStore() { - } - - /** - * Creates a function, which checks whether an in-store purchase is possible. Must be called before any in-store purchase. For official applications only. - * - *

Returns {@link Ok Ok}

- * - * @param purpose Transaction purpose. - */ - public CanPurchaseFromStore(StorePaymentPurpose purpose) { - this.purpose = purpose; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1017811816; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks whether a gift with nextSendDate in the future can be sent already. - * - *

Returns {@link CanSendGiftResult CanSendGiftResult}

- */ - public static class CanSendGift extends Function { - /** - * Identifier of the gift to send. - */ - public long giftId; - - /** - * Default constructor for a function, which checks whether a gift with nextSendDate in the future can be sent already. - * - *

Returns {@link CanSendGiftResult CanSendGiftResult}

- */ - public CanSendGift() { - } - - /** - * Creates a function, which checks whether a gift with nextSendDate in the future can be sent already. - * - *

Returns {@link CanSendGiftResult CanSendGiftResult}

- * - * @param giftId Identifier of the gift to send. - */ - public CanSendGift(long giftId) { - this.giftId = giftId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1307059830; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks whether the current user can message another user or try to create a chat with them. - * - *

Returns {@link CanSendMessageToUserResult CanSendMessageToUserResult}

- */ - public static class CanSendMessageToUser extends Function { - /** - * Identifier of the other user. - */ - public long userId; - /** - * Pass true to get only locally available information without sending network requests. - */ - public boolean onlyLocal; - - /** - * Default constructor for a function, which checks whether the current user can message another user or try to create a chat with them. - * - *

Returns {@link CanSendMessageToUserResult CanSendMessageToUserResult}

- */ - public CanSendMessageToUser() { - } - - /** - * Creates a function, which checks whether the current user can message another user or try to create a chat with them. - * - *

Returns {@link CanSendMessageToUserResult CanSendMessageToUserResult}

- * - * @param userId Identifier of the other user. - * @param onlyLocal Pass true to get only locally available information without sending network requests. - */ - public CanSendMessageToUser(long userId, boolean onlyLocal) { - this.userId = userId; - this.onlyLocal = onlyLocal; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1529489462; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks whether the current session can be used to transfer a chat ownership to another user. - * - *

Returns {@link CanTransferOwnershipResult CanTransferOwnershipResult}

- */ - public static class CanTransferOwnership extends Function { - - /** - * Default constructor for a function, which checks whether the current session can be used to transfer a chat ownership to another user. - * - *

Returns {@link CanTransferOwnershipResult CanTransferOwnershipResult}

- */ - public CanTransferOwnership() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 634602508; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Stops the downloading of a file. If a file has already been downloaded, does nothing. - * - *

Returns {@link Ok Ok}

- */ - public static class CancelDownloadFile extends Function { - /** - * Identifier of a file to stop downloading. - */ - public int fileId; - /** - * Pass true to stop downloading only if it hasn't been started, i.e. request hasn't been sent to server. - */ - public boolean onlyIfPending; - - /** - * Default constructor for a function, which stops the downloading of a file. If a file has already been downloaded, does nothing. - * - *

Returns {@link Ok Ok}

- */ - public CancelDownloadFile() { - } - - /** - * Creates a function, which stops the downloading of a file. If a file has already been downloaded, does nothing. - * - *

Returns {@link Ok Ok}

- * - * @param fileId Identifier of a file to stop downloading. - * @param onlyIfPending Pass true to stop downloading only if it hasn't been started, i.e. request hasn't been sent to server. - */ - public CancelDownloadFile(int fileId, boolean onlyIfPending) { - this.fileId = fileId; - this.onlyIfPending = onlyIfPending; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1954524450; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Cancels reset of 2-step verification password. The method can be called if passwordState.pendingResetDate > 0. - * - *

Returns {@link Ok Ok}

- */ - public static class CancelPasswordReset extends Function { - - /** - * Default constructor for a function, which cancels reset of 2-step verification password. The method can be called if passwordState.pendingResetDate > 0. - * - *

Returns {@link Ok Ok}

- */ - public CancelPasswordReset() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 940733538; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Stops the preliminary uploading of a file. Supported only for files uploaded by using preliminaryUploadFile. - * - *

Returns {@link Ok Ok}

- */ - public static class CancelPreliminaryUploadFile extends Function { - /** - * Identifier of the file to stop uploading. - */ - public int fileId; - - /** - * Default constructor for a function, which stops the preliminary uploading of a file. Supported only for files uploaded by using preliminaryUploadFile. - * - *

Returns {@link Ok Ok}

- */ - public CancelPreliminaryUploadFile() { - } - - /** - * Creates a function, which stops the preliminary uploading of a file. Supported only for files uploaded by using preliminaryUploadFile. - * - *

Returns {@link Ok Ok}

- * - * @param fileId Identifier of the file to stop uploading. - */ - public CancelPreliminaryUploadFile(int fileId) { - this.fileId = fileId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 823412414; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Cancels verification of the 2-step verification recovery email address. - * - *

Returns {@link PasswordState PasswordState}

- */ - public static class CancelRecoveryEmailAddressVerification extends Function { - - /** - * Default constructor for a function, which cancels verification of the 2-step verification recovery email address. - * - *

Returns {@link PasswordState PasswordState}

- */ - public CancelRecoveryEmailAddressVerification() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1516728691; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes imported contacts using the list of contacts saved on the device. Imports newly added contacts and, if at least the file database is enabled, deletes recently deleted contacts. Query result depends on the result of the previous query, so only one query is possible at the same time. - * - *

Returns {@link ImportedContacts ImportedContacts}

- */ - public static class ChangeImportedContacts extends Function { - /** - * The new list of contacts to import. - */ - public ImportedContact[] contacts; - - /** - * Default constructor for a function, which changes imported contacts using the list of contacts saved on the device. Imports newly added contacts and, if at least the file database is enabled, deletes recently deleted contacts. Query result depends on the result of the previous query, so only one query is possible at the same time. - * - *

Returns {@link ImportedContacts ImportedContacts}

- */ - public ChangeImportedContacts() { - } - - /** - * Creates a function, which changes imported contacts using the list of contacts saved on the device. Imports newly added contacts and, if at least the file database is enabled, deletes recently deleted contacts. Query result depends on the result of the previous query, so only one query is possible at the same time. - * - *

Returns {@link ImportedContacts ImportedContacts}

- * - * @param contacts The new list of contacts to import. - */ - public ChangeImportedContacts(ImportedContact[] contacts) { - this.contacts = contacts; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1119625871; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Installs/uninstalls or activates/archives a sticker set. - * - *

Returns {@link Ok Ok}

- */ - public static class ChangeStickerSet extends Function { - /** - * Identifier of the sticker set. - */ - public long setId; - /** - * The new value of isInstalled. - */ - public boolean isInstalled; - /** - * The new value of isArchived. A sticker set can't be installed and archived simultaneously. - */ - public boolean isArchived; - - /** - * Default constructor for a function, which installs/uninstalls or activates/archives a sticker set. - * - *

Returns {@link Ok Ok}

- */ - public ChangeStickerSet() { - } - - /** - * Creates a function, which installs/uninstalls or activates/archives a sticker set. - * - *

Returns {@link Ok Ok}

- * - * @param setId Identifier of the sticker set. - * @param isInstalled The new value of isInstalled. - * @param isArchived The new value of isArchived. A sticker set can't be installed and archived simultaneously. - */ - public ChangeStickerSet(long setId, boolean isInstalled, boolean isArchived) { - this.setId = setId; - this.isInstalled = isInstalled; - this.isArchived = isArchived; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 449357293; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks the authentication token of a bot; to log in as a bot. Works only when the current authorization state is authorizationStateWaitPhoneNumber. Can be used instead of setAuthenticationPhoneNumber and checkAuthenticationCode to log in. - * - *

Returns {@link Ok Ok}

- */ - public static class CheckAuthenticationBotToken extends Function { - /** - * The bot token. - */ - public String token; - - /** - * Default constructor for a function, which checks the authentication token of a bot; to log in as a bot. Works only when the current authorization state is authorizationStateWaitPhoneNumber. Can be used instead of setAuthenticationPhoneNumber and checkAuthenticationCode to log in. - * - *

Returns {@link Ok Ok}

- */ - public CheckAuthenticationBotToken() { - } - - /** - * Creates a function, which checks the authentication token of a bot; to log in as a bot. Works only when the current authorization state is authorizationStateWaitPhoneNumber. Can be used instead of setAuthenticationPhoneNumber and checkAuthenticationCode to log in. - * - *

Returns {@link Ok Ok}

- * - * @param token The bot token. - */ - public CheckAuthenticationBotToken(String token) { - this.token = token; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 639321206; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks the authentication code. Works only when the current authorization state is authorizationStateWaitCode. - * - *

Returns {@link Ok Ok}

- */ - public static class CheckAuthenticationCode extends Function { - /** - * Authentication code to check. - */ - public String code; - - /** - * Default constructor for a function, which checks the authentication code. Works only when the current authorization state is authorizationStateWaitCode. - * - *

Returns {@link Ok Ok}

- */ - public CheckAuthenticationCode() { - } - - /** - * Creates a function, which checks the authentication code. Works only when the current authorization state is authorizationStateWaitCode. - * - *

Returns {@link Ok Ok}

- * - * @param code Authentication code to check. - */ - public CheckAuthenticationCode(String code) { - this.code = code; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -302103382; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks the authentication of an email address. Works only when the current authorization state is authorizationStateWaitEmailCode. - * - *

Returns {@link Ok Ok}

- */ - public static class CheckAuthenticationEmailCode extends Function { - /** - * Email address authentication to check. - */ - public EmailAddressAuthentication code; - - /** - * Default constructor for a function, which checks the authentication of an email address. Works only when the current authorization state is authorizationStateWaitEmailCode. - * - *

Returns {@link Ok Ok}

- */ - public CheckAuthenticationEmailCode() { - } - - /** - * Creates a function, which checks the authentication of an email address. Works only when the current authorization state is authorizationStateWaitEmailCode. - * - *

Returns {@link Ok Ok}

- * - * @param code Email address authentication to check. - */ - public CheckAuthenticationEmailCode(EmailAddressAuthentication code) { - this.code = code; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -582827361; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks a passkey to log in to the corresponding account. Call getAuthenticationPasskeyParameters to get parameters for the passkey. Works only when the current authorization state is authorizationStateWaitPhoneNumber or authorizationStateWaitOtherDeviceConfirmation, or if there is no pending authentication query and the current authorization state is authorizationStateWaitPremiumPurchase, authorizationStateWaitEmailAddress, authorizationStateWaitEmailCode, authorizationStateWaitCode, authorizationStateWaitRegistration, or authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- */ - public static class CheckAuthenticationPasskey extends Function { - /** - * Base64url-encoded identifier of the credential. - */ - public String credentialId; - /** - * JSON-encoded client data. - */ - public String clientData; - /** - * Authenticator data of the application that created the credential. - */ - public byte[] authenticatorData; - /** - * Cryptographic signature of the credential. - */ - public byte[] signature; - /** - * User handle of the passkey. - */ - public byte[] userHandle; - - /** - * Default constructor for a function, which checks a passkey to log in to the corresponding account. Call getAuthenticationPasskeyParameters to get parameters for the passkey. Works only when the current authorization state is authorizationStateWaitPhoneNumber or authorizationStateWaitOtherDeviceConfirmation, or if there is no pending authentication query and the current authorization state is authorizationStateWaitPremiumPurchase, authorizationStateWaitEmailAddress, authorizationStateWaitEmailCode, authorizationStateWaitCode, authorizationStateWaitRegistration, or authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- */ - public CheckAuthenticationPasskey() { - } - - /** - * Creates a function, which checks a passkey to log in to the corresponding account. Call getAuthenticationPasskeyParameters to get parameters for the passkey. Works only when the current authorization state is authorizationStateWaitPhoneNumber or authorizationStateWaitOtherDeviceConfirmation, or if there is no pending authentication query and the current authorization state is authorizationStateWaitPremiumPurchase, authorizationStateWaitEmailAddress, authorizationStateWaitEmailCode, authorizationStateWaitCode, authorizationStateWaitRegistration, or authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- * - * @param credentialId Base64url-encoded identifier of the credential. - * @param clientData JSON-encoded client data. - * @param authenticatorData Authenticator data of the application that created the credential. - * @param signature Cryptographic signature of the credential. - * @param userHandle User handle of the passkey. - */ - public CheckAuthenticationPasskey(String credentialId, String clientData, byte[] authenticatorData, byte[] signature, byte[] userHandle) { - this.credentialId = credentialId; - this.clientData = clientData; - this.authenticatorData = authenticatorData; - this.signature = signature; - this.userHandle = userHandle; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1225325317; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks the 2-step verification password for correctness. Works only when the current authorization state is authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- */ - public static class CheckAuthenticationPassword extends Function { - /** - * The 2-step verification password to check. - */ - public String password; - - /** - * Default constructor for a function, which checks the 2-step verification password for correctness. Works only when the current authorization state is authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- */ - public CheckAuthenticationPassword() { - } - - /** - * Creates a function, which checks the 2-step verification password for correctness. Works only when the current authorization state is authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- * - * @param password The 2-step verification password to check. - */ - public CheckAuthenticationPassword(String password) { - this.password = password; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2025698400; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks whether a 2-step verification password recovery code sent to an email address is valid. Works only when the current authorization state is authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- */ - public static class CheckAuthenticationPasswordRecoveryCode extends Function { - /** - * Recovery code to check. - */ - public String recoveryCode; - - /** - * Default constructor for a function, which checks whether a 2-step verification password recovery code sent to an email address is valid. Works only when the current authorization state is authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- */ - public CheckAuthenticationPasswordRecoveryCode() { - } - - /** - * Creates a function, which checks whether a 2-step verification password recovery code sent to an email address is valid. Works only when the current authorization state is authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- * - * @param recoveryCode Recovery code to check. - */ - public CheckAuthenticationPasswordRecoveryCode(String recoveryCode) { - this.recoveryCode = recoveryCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -603309083; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks whether an in-store purchase of Telegram Premium is possible before authorization. Works only when the current authorization state is authorizationStateWaitPremiumPurchase. - * - *

Returns {@link Ok Ok}

- */ - public static class CheckAuthenticationPremiumPurchase extends Function { - /** - * ISO 4217 currency code of the payment currency. - */ - public String currency; - /** - * Paid amount, in the smallest units of the currency. - */ - public long amount; - - /** - * Default constructor for a function, which checks whether an in-store purchase of Telegram Premium is possible before authorization. Works only when the current authorization state is authorizationStateWaitPremiumPurchase. - * - *

Returns {@link Ok Ok}

- */ - public CheckAuthenticationPremiumPurchase() { - } - - /** - * Creates a function, which checks whether an in-store purchase of Telegram Premium is possible before authorization. Works only when the current authorization state is authorizationStateWaitPremiumPurchase. - * - *

Returns {@link Ok Ok}

- * - * @param currency ISO 4217 currency code of the payment currency. - * @param amount Paid amount, in the smallest units of the currency. - */ - public CheckAuthenticationPremiumPurchase(String currency, long amount) { - this.currency = currency; - this.amount = amount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1588959934; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks the validity of an invite link for a chat folder and returns information about the corresponding chat folder. - * - *

Returns {@link ChatFolderInviteLinkInfo ChatFolderInviteLinkInfo}

- */ - public static class CheckChatFolderInviteLink extends Function { - /** - * Invite link to be checked. - */ - public String inviteLink; - - /** - * Default constructor for a function, which checks the validity of an invite link for a chat folder and returns information about the corresponding chat folder. - * - *

Returns {@link ChatFolderInviteLinkInfo ChatFolderInviteLinkInfo}

- */ - public CheckChatFolderInviteLink() { - } - - /** - * Creates a function, which checks the validity of an invite link for a chat folder and returns information about the corresponding chat folder. - * - *

Returns {@link ChatFolderInviteLinkInfo ChatFolderInviteLinkInfo}

- * - * @param inviteLink Invite link to be checked. - */ - public CheckChatFolderInviteLink(String inviteLink) { - this.inviteLink = inviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 522557851; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks the validity of an invite link for a chat and returns information about the corresponding chat. - * - *

Returns {@link ChatInviteLinkInfo ChatInviteLinkInfo}

- */ - public static class CheckChatInviteLink extends Function { - /** - * Invite link to be checked. - */ - public String inviteLink; - - /** - * Default constructor for a function, which checks the validity of an invite link for a chat and returns information about the corresponding chat. - * - *

Returns {@link ChatInviteLinkInfo ChatInviteLinkInfo}

- */ - public CheckChatInviteLink() { - } - - /** - * Creates a function, which checks the validity of an invite link for a chat and returns information about the corresponding chat. - * - *

Returns {@link ChatInviteLinkInfo ChatInviteLinkInfo}

- * - * @param inviteLink Invite link to be checked. - */ - public CheckChatInviteLink(String inviteLink) { - this.inviteLink = inviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -496940997; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks whether a username can be set for a chat. - * - *

Returns {@link CheckChatUsernameResult CheckChatUsernameResult}

- */ - public static class CheckChatUsername extends Function { - /** - * Chat identifier; must be identifier of a supergroup chat, or a channel chat, or a private chat with self, or 0 if the chat is being created. - */ - public long chatId; - /** - * Username to be checked. - */ - public String username; - - /** - * Default constructor for a function, which checks whether a username can be set for a chat. - * - *

Returns {@link CheckChatUsernameResult CheckChatUsernameResult}

- */ - public CheckChatUsername() { - } - - /** - * Creates a function, which checks whether a username can be set for a chat. - * - *

Returns {@link CheckChatUsernameResult CheckChatUsernameResult}

- * - * @param chatId Chat identifier; must be identifier of a supergroup chat, or a channel chat, or a private chat with self, or 0 if the chat is being created. - * @param username Username to be checked. - */ - public CheckChatUsername(long chatId, String username) { - this.chatId = chatId; - this.username = username; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -119119344; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks whether the maximum number of owned public chats has been reached. Returns corresponding error if the limit was reached. The limit can be increased with Telegram Premium. - * - *

Returns {@link Ok Ok}

- */ - public static class CheckCreatedPublicChatsLimit extends Function { - /** - * Type of the public chats, for which to check the limit. - */ - public PublicChatType type; - - /** - * Default constructor for a function, which checks whether the maximum number of owned public chats has been reached. Returns corresponding error if the limit was reached. The limit can be increased with Telegram Premium. - * - *

Returns {@link Ok Ok}

- */ - public CheckCreatedPublicChatsLimit() { - } - - /** - * Creates a function, which checks whether the maximum number of owned public chats has been reached. Returns corresponding error if the limit was reached. The limit can be increased with Telegram Premium. - * - *

Returns {@link Ok Ok}

- * - * @param type Type of the public chats, for which to check the limit. - */ - public CheckCreatedPublicChatsLimit(PublicChatType type) { - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -445546591; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks the email address verification code for Telegram Passport. - * - *

Returns {@link Ok Ok}

- */ - public static class CheckEmailAddressVerificationCode extends Function { - /** - * Verification code to check. - */ - public String code; - - /** - * Default constructor for a function, which checks the email address verification code for Telegram Passport. - * - *

Returns {@link Ok Ok}

- */ - public CheckEmailAddressVerificationCode() { - } - - /** - * Creates a function, which checks the email address verification code for Telegram Passport. - * - *

Returns {@link Ok Ok}

- * - * @param code Verification code to check. - */ - public CheckEmailAddressVerificationCode(String code) { - this.code = code; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -426386685; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks the login email address authentication. - * - *

Returns {@link Ok Ok}

- */ - public static class CheckLoginEmailAddressCode extends Function { - /** - * Email address authentication to check. - */ - public EmailAddressAuthentication code; - - /** - * Default constructor for a function, which checks the login email address authentication. - * - *

Returns {@link Ok Ok}

- */ - public CheckLoginEmailAddressCode() { - } - - /** - * Creates a function, which checks the login email address authentication. - * - *

Returns {@link Ok Ok}

- * - * @param code Email address authentication to check. - */ - public CheckLoginEmailAddressCode(EmailAddressAuthentication code) { - this.code = code; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1454244766; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks a match-code for an OAuth authorization request. If fails, then the authorization request has failed. Otherwise, authorization confirmation dialog must be shown and the link must be processed using acceptOauthRequest or declineOauthRequest. - * - *

Returns {@link Ok Ok}

- */ - public static class CheckOauthRequestMatchCode extends Function { - /** - * URL of the OAuth deep link. - */ - public String url; - /** - * The matching code chosen by the user. - */ - public String matchCode; - - /** - * Default constructor for a function, which checks a match-code for an OAuth authorization request. If fails, then the authorization request has failed. Otherwise, authorization confirmation dialog must be shown and the link must be processed using acceptOauthRequest or declineOauthRequest. - * - *

Returns {@link Ok Ok}

- */ - public CheckOauthRequestMatchCode() { - } - - /** - * Creates a function, which checks a match-code for an OAuth authorization request. If fails, then the authorization request has failed. Otherwise, authorization confirmation dialog must be shown and the link must be processed using acceptOauthRequest or declineOauthRequest. - * - *

Returns {@link Ok Ok}

- * - * @param url URL of the OAuth deep link. - * @param matchCode The matching code chosen by the user. - */ - public CheckOauthRequestMatchCode(String url, String matchCode) { - this.url = url; - this.matchCode = matchCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1383896724; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks whether a 2-step verification password recovery code sent to an email address is valid. - * - *

Returns {@link Ok Ok}

- */ - public static class CheckPasswordRecoveryCode extends Function { - /** - * Recovery code to check. - */ - public String recoveryCode; - - /** - * Default constructor for a function, which checks whether a 2-step verification password recovery code sent to an email address is valid. - * - *

Returns {@link Ok Ok}

- */ - public CheckPasswordRecoveryCode() { - } - - /** - * Creates a function, which checks whether a 2-step verification password recovery code sent to an email address is valid. - * - *

Returns {@link Ok Ok}

- * - * @param recoveryCode Recovery code to check. - */ - public CheckPasswordRecoveryCode(String recoveryCode) { - this.recoveryCode = recoveryCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -200794600; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks the authentication code and completes the request for which the code was sent if appropriate. - * - *

Returns {@link Ok Ok}

- */ - public static class CheckPhoneNumberCode extends Function { - /** - * Authentication code to check. - */ - public String code; - - /** - * Default constructor for a function, which checks the authentication code and completes the request for which the code was sent if appropriate. - * - *

Returns {@link Ok Ok}

- */ - public CheckPhoneNumberCode() { - } - - /** - * Creates a function, which checks the authentication code and completes the request for which the code was sent if appropriate. - * - *

Returns {@link Ok Ok}

- * - * @param code Authentication code to check. - */ - public CheckPhoneNumberCode(String code) { - this.code = code; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -603626079; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a Telegram Premium gift code. - * - *

Returns {@link PremiumGiftCodeInfo PremiumGiftCodeInfo}

- */ - public static class CheckPremiumGiftCode extends Function { - /** - * The code to check. - */ - public String code; - - /** - * Default constructor for a function, which returns information about a Telegram Premium gift code. - * - *

Returns {@link PremiumGiftCodeInfo PremiumGiftCodeInfo}

- */ - public CheckPremiumGiftCode() { - } - - /** - * Creates a function, which returns information about a Telegram Premium gift code. - * - *

Returns {@link PremiumGiftCodeInfo PremiumGiftCodeInfo}

- * - * @param code The code to check. - */ - public CheckPremiumGiftCode(String code) { - this.code = code; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1786063260; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks validness of a name for a quick reply shortcut. Can be called synchronously. - * - *

Returns {@link Ok Ok}

- */ - public static class CheckQuickReplyShortcutName extends Function { - /** - * The name of the shortcut; 1-32 characters. - */ - public String name; - - /** - * Default constructor for a function, which checks validness of a name for a quick reply shortcut. Can be called synchronously. - * - *

Returns {@link Ok Ok}

- */ - public CheckQuickReplyShortcutName() { - } - - /** - * Creates a function, which checks validness of a name for a quick reply shortcut. Can be called synchronously. - * - *

Returns {@link Ok Ok}

- * - * @param name The name of the shortcut; 1-32 characters. - */ - public CheckQuickReplyShortcutName(String name) { - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2101203241; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks the 2-step verification recovery email address verification code. - * - *

Returns {@link PasswordState PasswordState}

- */ - public static class CheckRecoveryEmailAddressCode extends Function { - /** - * Verification code to check. - */ - public String code; - - /** - * Default constructor for a function, which checks the 2-step verification recovery email address verification code. - * - *

Returns {@link PasswordState PasswordState}

- */ - public CheckRecoveryEmailAddressCode() { - } - - /** - * Creates a function, which checks the 2-step verification recovery email address verification code. - * - *

Returns {@link PasswordState PasswordState}

- * - * @param code Verification code to check. - */ - public CheckRecoveryEmailAddressCode(String code) { - this.code = code; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1997039589; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks whether a name can be used for a new sticker set. - * - *

Returns {@link CheckStickerSetNameResult CheckStickerSetNameResult}

- */ - public static class CheckStickerSetName extends Function { - /** - * Name to be checked. - */ - public String name; - - /** - * Default constructor for a function, which checks whether a name can be used for a new sticker set. - * - *

Returns {@link CheckStickerSetNameResult CheckStickerSetNameResult}

- */ - public CheckStickerSetName() { - } - - /** - * Creates a function, which checks whether a name can be used for a new sticker set. - * - *

Returns {@link CheckStickerSetNameResult CheckStickerSetNameResult}

- * - * @param name Name to be checked. - */ - public CheckStickerSetName(String name) { - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1789392642; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks whether a file can be downloaded and saved locally by Web App request. - * - *

Returns {@link Ok Ok}

- */ - public static class CheckWebAppFileDownload extends Function { - /** - * Identifier of the bot, providing the Web App. - */ - public long botUserId; - /** - * Name of the file. - */ - public String fileName; - /** - * URL of the file. - */ - public String url; - - /** - * Default constructor for a function, which checks whether a file can be downloaded and saved locally by Web App request. - * - *

Returns {@link Ok Ok}

- */ - public CheckWebAppFileDownload() { - } - - /** - * Creates a function, which checks whether a file can be downloaded and saved locally by Web App request. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId Identifier of the bot, providing the Web App. - * @param fileName Name of the file. - * @param url URL of the file. - */ - public CheckWebAppFileDownload(long botUserId, String fileName, String url) { - this.botUserId = botUserId; - this.fileName = fileName; - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -389397278; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes potentially dangerous characters from the name of a file. Returns an empty string on failure. Can be called synchronously. - * - *

Returns {@link Text Text}

- */ - public static class CleanFileName extends Function { - /** - * File name or path to the file. - */ - public String fileName; - - /** - * Default constructor for a function, which removes potentially dangerous characters from the name of a file. Returns an empty string on failure. Can be called synchronously. - * - *

Returns {@link Text Text}

- */ - public CleanFileName() { - } - - /** - * Creates a function, which removes potentially dangerous characters from the name of a file. Returns an empty string on failure. Can be called synchronously. - * - *

Returns {@link Text Text}

- * - * @param fileName File name or path to the file. - */ - public CleanFileName(String fileName) { - this.fileName = fileName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 967964667; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Clears message drafts in all chats. - * - *

Returns {@link Ok Ok}

- */ - public static class ClearAllDraftMessages extends Function { - /** - * Pass true to keep local message drafts in secret chats. - */ - public boolean excludeSecretChats; - - /** - * Default constructor for a function, which clears message drafts in all chats. - * - *

Returns {@link Ok Ok}

- */ - public ClearAllDraftMessages() { - } - - /** - * Creates a function, which clears message drafts in all chats. - * - *

Returns {@link Ok Ok}

- * - * @param excludeSecretChats Pass true to keep local message drafts in secret chats. - */ - public ClearAllDraftMessages(boolean excludeSecretChats) { - this.excludeSecretChats = excludeSecretChats; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -46369573; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Clears the list of all autosave settings exceptions. The method is guaranteed to work only after at least one call to getAutosaveSettings. - * - *

Returns {@link Ok Ok}

- */ - public static class ClearAutosaveSettingsExceptions extends Function { - - /** - * Default constructor for a function, which clears the list of all autosave settings exceptions. The method is guaranteed to work only after at least one call to getAutosaveSettings. - * - *

Returns {@link Ok Ok}

- */ - public ClearAutosaveSettingsExceptions() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1475109874; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Clears all imported contacts, contact list remains unchanged. - * - *

Returns {@link Ok Ok}

- */ - public static class ClearImportedContacts extends Function { - - /** - * Default constructor for a function, which clears all imported contacts, contact list remains unchanged. - * - *

Returns {@link Ok Ok}

- */ - public ClearImportedContacts() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 869503298; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Clears the list of recently used emoji statuses for self status. - * - *

Returns {@link Ok Ok}

- */ - public static class ClearRecentEmojiStatuses extends Function { - - /** - * Default constructor for a function, which clears the list of recently used emoji statuses for self status. - * - *

Returns {@link Ok Ok}

- */ - public ClearRecentEmojiStatuses() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -428749986; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Clears the list of recently used reactions. - * - *

Returns {@link Ok Ok}

- */ - public static class ClearRecentReactions extends Function { - - /** - * Default constructor for a function, which clears the list of recently used reactions. - * - *

Returns {@link Ok Ok}

- */ - public ClearRecentReactions() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1298253650; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Clears the list of recently used stickers. - * - *

Returns {@link Ok Ok}

- */ - public static class ClearRecentStickers extends Function { - /** - * Pass true to clear the list of stickers recently attached to photo or video files; pass false to clear the list of recently sent stickers. - */ - public boolean isAttached; - - /** - * Default constructor for a function, which clears the list of recently used stickers. - * - *

Returns {@link Ok Ok}

- */ - public ClearRecentStickers() { - } - - /** - * Creates a function, which clears the list of recently used stickers. - * - *

Returns {@link Ok Ok}

- * - * @param isAttached Pass true to clear the list of stickers recently attached to photo or video files; pass false to clear the list of recently sent stickers. - */ - public ClearRecentStickers(boolean isAttached) { - this.isAttached = isAttached; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -321242684; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Clears the list of recently found chats. - * - *

Returns {@link Ok Ok}

- */ - public static class ClearRecentlyFoundChats extends Function { - - /** - * Default constructor for a function, which clears the list of recently found chats. - * - *

Returns {@link Ok Ok}

- */ - public ClearRecentlyFoundChats() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -285582542; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Clears the list of recently searched for hashtags or cashtags. - * - *

Returns {@link Ok Ok}

- */ - public static class ClearSearchedForTags extends Function { - /** - * Pass true to clear the list of recently searched for cashtags; otherwise, the list of recently searched for hashtags will be cleared. - */ - public boolean clearCashtags; - - /** - * Default constructor for a function, which clears the list of recently searched for hashtags or cashtags. - * - *

Returns {@link Ok Ok}

- */ - public ClearSearchedForTags() { - } - - /** - * Creates a function, which clears the list of recently searched for hashtags or cashtags. - * - *

Returns {@link Ok Ok}

- * - * @param clearCashtags Pass true to clear the list of recently searched for cashtags; otherwise, the list of recently searched for hashtags will be cleared. - */ - public ClearSearchedForTags(boolean clearCashtags) { - this.clearCashtags = clearCashtags; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 512017238; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that a message with an animated emoji was clicked by the user. Returns a big animated sticker to be played or a 404 error if usual animation needs to be played. - * - *

Returns {@link Sticker Sticker}

- */ - public static class ClickAnimatedEmojiMessage extends Function { - /** - * Chat identifier of the message. - */ - public long chatId; - /** - * Identifier of the clicked message. - */ - public long messageId; - - /** - * Default constructor for a function, which informs TDLib that a message with an animated emoji was clicked by the user. Returns a big animated sticker to be played or a 404 error if usual animation needs to be played. - * - *

Returns {@link Sticker Sticker}

- */ - public ClickAnimatedEmojiMessage() { - } - - /** - * Creates a function, which informs TDLib that a message with an animated emoji was clicked by the user. Returns a big animated sticker to be played or a 404 error if usual animation needs to be played. - * - *

Returns {@link Sticker Sticker}

- * - * @param chatId Chat identifier of the message. - * @param messageId Identifier of the clicked message. - */ - public ClickAnimatedEmojiMessage(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 196179554; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that the user opened the sponsored chat via the button, the name, the chat photo, a mention in the sponsored message text, or the media in the sponsored message. - * - *

Returns {@link Ok Ok}

- */ - public static class ClickChatSponsoredMessage extends Function { - /** - * Chat identifier of the sponsored message. - */ - public long chatId; - /** - * Identifier of the sponsored message. - */ - public long messageId; - /** - * Pass true if the media was clicked in the sponsored message. - */ - public boolean isMediaClick; - /** - * Pass true if the user expanded the video from the sponsored message fullscreen before the click. - */ - public boolean fromFullscreen; - - /** - * Default constructor for a function, which informs TDLib that the user opened the sponsored chat via the button, the name, the chat photo, a mention in the sponsored message text, or the media in the sponsored message. - * - *

Returns {@link Ok Ok}

- */ - public ClickChatSponsoredMessage() { - } - - /** - * Creates a function, which informs TDLib that the user opened the sponsored chat via the button, the name, the chat photo, a mention in the sponsored message text, or the media in the sponsored message. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier of the sponsored message. - * @param messageId Identifier of the sponsored message. - * @param isMediaClick Pass true if the media was clicked in the sponsored message. - * @param fromFullscreen Pass true if the user expanded the video from the sponsored message fullscreen before the click. - */ - public ClickChatSponsoredMessage(long chatId, long messageId, boolean isMediaClick, boolean fromFullscreen) { - this.chatId = chatId; - this.messageId = messageId; - this.isMediaClick = isMediaClick; - this.fromFullscreen = fromFullscreen; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 971995671; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that the user clicked Premium subscription button on the Premium features screen. - * - *

Returns {@link Ok Ok}

- */ - public static class ClickPremiumSubscriptionButton extends Function { - - /** - * Default constructor for a function, which informs TDLib that the user clicked Premium subscription button on the Premium features screen. - * - *

Returns {@link Ok Ok}

- */ - public ClickPremiumSubscriptionButton() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -369319162; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that the user clicked a video message advertisement. - * - *

Returns {@link Ok Ok}

- */ - public static class ClickVideoMessageAdvertisement extends Function { - /** - * Unique identifier of the advertisement. - */ - public long advertisementUniqueId; - - /** - * Default constructor for a function, which informs TDLib that the user clicked a video message advertisement. - * - *

Returns {@link Ok Ok}

- */ - public ClickVideoMessageAdvertisement() { - } - - /** - * Creates a function, which informs TDLib that the user clicked a video message advertisement. - * - *

Returns {@link Ok Ok}

- * - * @param advertisementUniqueId Unique identifier of the advertisement. - */ - public ClickVideoMessageAdvertisement(long advertisementUniqueId) { - this.advertisementUniqueId = advertisementUniqueId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1367156622; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Closes the TDLib instance. All databases will be flushed to disk and properly closed. After the close completes, updateAuthorizationState with authorizationStateClosed will be sent. Can be called before initialization. - * - *

Returns {@link Ok Ok}

- */ - public static class Close extends Function { - - /** - * Default constructor for a function, which closes the TDLib instance. All databases will be flushed to disk and properly closed. After the close completes, updateAuthorizationState with authorizationStateClosed will be sent. Can be called before initialization. - * - *

Returns {@link Ok Ok}

- */ - public Close() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1187782273; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that the chat is closed by the user. Many useful activities depend on the chat being opened or closed. - * - *

Returns {@link Ok Ok}

- */ - public static class CloseChat extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which informs TDLib that the chat is closed by the user. Many useful activities depend on the chat being opened or closed. - * - *

Returns {@link Ok Ok}

- */ - public CloseChat() { - } - - /** - * Creates a function, which informs TDLib that the chat is closed by the user. Many useful activities depend on the chat being opened or closed. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - */ - public CloseChat(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 39749353; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that a gift auction was closed by the user. - * - *

Returns {@link Ok Ok}

- */ - public static class CloseGiftAuction extends Function { - /** - * Identifier of the gift, which auction was closed. - */ - public long giftId; - - /** - * Default constructor for a function, which informs TDLib that a gift auction was closed by the user. - * - *

Returns {@link Ok Ok}

- */ - public CloseGiftAuction() { - } - - /** - * Creates a function, which informs TDLib that a gift auction was closed by the user. - * - *

Returns {@link Ok Ok}

- * - * @param giftId Identifier of the gift, which auction was closed. - */ - public CloseGiftAuction(long giftId) { - this.giftId = giftId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 115495644; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Closes a secret chat, effectively transferring its state to secretChatStateClosed. - * - *

Returns {@link Ok Ok}

- */ - public static class CloseSecretChat extends Function { - /** - * Secret chat identifier. - */ - public int secretChatId; - - /** - * Default constructor for a function, which closes a secret chat, effectively transferring its state to secretChatStateClosed. - * - *

Returns {@link Ok Ok}

- */ - public CloseSecretChat() { - } - - /** - * Creates a function, which closes a secret chat, effectively transferring its state to secretChatStateClosed. - * - *

Returns {@link Ok Ok}

- * - * @param secretChatId Secret chat identifier. - */ - public CloseSecretChat(int secretChatId) { - this.secretChatId = secretChatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -471006133; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that a story is closed by the user. - * - *

Returns {@link Ok Ok}

- */ - public static class CloseStory extends Function { - /** - * The identifier of the poster of the story to close. - */ - public long storyPosterChatId; - /** - * The identifier of the story. - */ - public int storyId; - - /** - * Default constructor for a function, which informs TDLib that a story is closed by the user. - * - *

Returns {@link Ok Ok}

- */ - public CloseStory() { - } - - /** - * Creates a function, which informs TDLib that a story is closed by the user. - * - *

Returns {@link Ok Ok}

- * - * @param storyPosterChatId The identifier of the poster of the story to close. - * @param storyId The identifier of the story. - */ - public CloseStory(long storyPosterChatId, int storyId) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1553967851; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that a previously opened Web App was closed. - * - *

Returns {@link Ok Ok}

- */ - public static class CloseWebApp extends Function { - /** - * Identifier of Web App launch, received from openWebApp. - */ - public long webAppLaunchId; - - /** - * Default constructor for a function, which informs TDLib that a previously opened Web App was closed. - * - *

Returns {@link Ok Ok}

- */ - public CloseWebApp() { - } - - /** - * Creates a function, which informs TDLib that a previously opened Web App was closed. - * - *

Returns {@link Ok Ok}

- * - * @param webAppLaunchId Identifier of Web App launch, received from openWebApp. - */ - public CloseWebApp(long webAppLaunchId) { - this.webAppLaunchId = webAppLaunchId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1755391174; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Applies all pending paid reactions in a live story group call. - * - *

Returns {@link Ok Ok}

- */ - public static class CommitPendingLiveStoryReactions extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - - /** - * Default constructor for a function, which applies all pending paid reactions in a live story group call. - * - *

Returns {@link Ok Ok}

- */ - public CommitPendingLiveStoryReactions() { - } - - /** - * Creates a function, which applies all pending paid reactions in a live story group call. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - */ - public CommitPendingLiveStoryReactions(int groupCallId) { - this.groupCallId = groupCallId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1786229016; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Applies all pending paid reactions on a message. - * - *

Returns {@link Ok Ok}

- */ - public static class CommitPendingPaidMessageReactions extends Function { - /** - * Identifier of the chat to which the message belongs. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - - /** - * Default constructor for a function, which applies all pending paid reactions on a message. - * - *

Returns {@link Ok Ok}

- */ - public CommitPendingPaidMessageReactions() { - } - - /** - * Creates a function, which applies all pending paid reactions on a message. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat to which the message belongs. - * @param messageId Identifier of the message. - */ - public CommitPendingPaidMessageReactions(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -171354618; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Confirms QR code authentication on another device. Returns created session on success. - * - *

Returns {@link Session Session}

- */ - public static class ConfirmQrCodeAuthentication extends Function { - /** - * A link from a QR code. The link must be scanned by the in-app camera. - */ - public String link; - - /** - * Default constructor for a function, which confirms QR code authentication on another device. Returns created session on success. - * - *

Returns {@link Session Session}

- */ - public ConfirmQrCodeAuthentication() { - } - - /** - * Creates a function, which confirms QR code authentication on another device. Returns created session on success. - * - *

Returns {@link Session Session}

- * - * @param link A link from a QR code. The link must be scanned by the in-app camera. - */ - public ConfirmQrCodeAuthentication(String link) { - this.link = link; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -376199379; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Confirms an unconfirmed session of the current user from another device. - * - *

Returns {@link Ok Ok}

- */ - public static class ConfirmSession extends Function { - /** - * Session identifier. - */ - public long sessionId; - - /** - * Default constructor for a function, which confirms an unconfirmed session of the current user from another device. - * - *

Returns {@link Ok Ok}

- */ - public ConfirmSession() { - } - - /** - * Creates a function, which confirms an unconfirmed session of the current user from another device. - * - *

Returns {@link Ok Ok}

- * - * @param sessionId Session identifier. - */ - public ConfirmSession(long sessionId) { - this.sessionId = sessionId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -674647009; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Connects an affiliate program to the given affiliate. Returns information about the connected affiliate program. - * - *

Returns {@link ConnectedAffiliateProgram ConnectedAffiliateProgram}

- */ - public static class ConnectAffiliateProgram extends Function { - /** - * The affiliate to which the affiliate program will be connected. - */ - public AffiliateType affiliate; - /** - * Identifier of the bot, which affiliate program is connected. - */ - public long botUserId; - - /** - * Default constructor for a function, which connects an affiliate program to the given affiliate. Returns information about the connected affiliate program. - * - *

Returns {@link ConnectedAffiliateProgram ConnectedAffiliateProgram}

- */ - public ConnectAffiliateProgram() { - } - - /** - * Creates a function, which connects an affiliate program to the given affiliate. Returns information about the connected affiliate program. - * - *

Returns {@link ConnectedAffiliateProgram ConnectedAffiliateProgram}

- * - * @param affiliate The affiliate to which the affiliate program will be connected. - * @param botUserId Identifier of the bot, which affiliate program is connected. - */ - public ConnectAffiliateProgram(AffiliateType affiliate, long botUserId) { - this.affiliate = affiliate; - this.botUserId = botUserId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1661392684; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Crafts a new gift from other gifts that will be permanently lost. - * - *

Returns {@link CraftGiftResult CraftGiftResult}

- */ - public static class CraftGift extends Function { - /** - * Identifier of the gifts to use for crafting. In the case of a successful craft, the resulting gift will have the number of the first gift. Consequently, the first gift must not have been withdrawn to the TON blockchain as an NFT and must have an empty giftAddress. - */ - public String[] receivedGiftIds; - - /** - * Default constructor for a function, which crafts a new gift from other gifts that will be permanently lost. - * - *

Returns {@link CraftGiftResult CraftGiftResult}

- */ - public CraftGift() { - } - - /** - * Creates a function, which crafts a new gift from other gifts that will be permanently lost. - * - *

Returns {@link CraftGiftResult CraftGiftResult}

- * - * @param receivedGiftIds Identifier of the gifts to use for crafting. In the case of a successful craft, the resulting gift will have the number of the first gift. Consequently, the first gift must not have been withdrawn to the TON blockchain as an NFT and must have an empty giftAddress. - */ - public CraftGift(String[] receivedGiftIds) { - this.receivedGiftIds = receivedGiftIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2124593259; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an existing chat corresponding to a known basic group. - * - *

Returns {@link Chat Chat}

- */ - public static class CreateBasicGroupChat extends Function { - /** - * Basic group identifier. - */ - public long basicGroupId; - /** - * Pass true to create the chat without a network request. In this case all information about the chat except its type, title and photo can be incorrect. - */ - public boolean force; - - /** - * Default constructor for a function, which returns an existing chat corresponding to a known basic group. - * - *

Returns {@link Chat Chat}

- */ - public CreateBasicGroupChat() { - } - - /** - * Creates a function, which returns an existing chat corresponding to a known basic group. - * - *

Returns {@link Chat Chat}

- * - * @param basicGroupId Basic group identifier. - * @param force Pass true to create the chat without a network request. In this case all information about the chat except its type, title and photo can be incorrect. - */ - public CreateBasicGroupChat(long basicGroupId, boolean force) { - this.basicGroupId = basicGroupId; - this.force = force; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1972024548; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates a business chat link for the current account. Requires Telegram Business subscription. There can be up to getOption("business_chat_link_count_max") links created. Returns the created link. - * - *

Returns {@link BusinessChatLink BusinessChatLink}

- */ - public static class CreateBusinessChatLink extends Function { - /** - * Information about the link to create. - */ - public InputBusinessChatLink linkInfo; - - /** - * Default constructor for a function, which creates a business chat link for the current account. Requires Telegram Business subscription. There can be up to getOption("business_chat_link_count_max") links created. Returns the created link. - * - *

Returns {@link BusinessChatLink BusinessChatLink}

- */ - public CreateBusinessChatLink() { - } - - /** - * Creates a function, which creates a business chat link for the current account. Requires Telegram Business subscription. There can be up to getOption("business_chat_link_count_max") links created. Returns the created link. - * - *

Returns {@link BusinessChatLink BusinessChatLink}

- * - * @param linkInfo Information about the link to create. - */ - public CreateBusinessChatLink(InputBusinessChatLink linkInfo) { - this.linkInfo = linkInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1861018304; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates a new call. - * - *

Returns {@link CallId CallId}

- */ - public static class CreateCall extends Function { - /** - * Identifier of the user to be called. - */ - public long userId; - /** - * The call protocols supported by the application. - */ - public CallProtocol protocol; - /** - * Pass true to create a video call. - */ - public boolean isVideo; - - /** - * Default constructor for a function, which creates a new call. - * - *

Returns {@link CallId CallId}

- */ - public CreateCall() { - } - - /** - * Creates a function, which creates a new call. - * - *

Returns {@link CallId CallId}

- * - * @param userId Identifier of the user to be called. - * @param protocol The call protocols supported by the application. - * @param isVideo Pass true to create a video call. - */ - public CreateCall(long userId, CallProtocol protocol, boolean isVideo) { - this.userId = userId; - this.protocol = protocol; - this.isVideo = isVideo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1104663024; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates new chat folder. Returns information about the created chat folder. There can be up to getOption("chat_folder_count_max") chat folders, but the limit can be increased with Telegram Premium. - * - *

Returns {@link ChatFolderInfo ChatFolderInfo}

- */ - public static class CreateChatFolder extends Function { - /** - * The new chat folder. - */ - public ChatFolder folder; - - /** - * Default constructor for a function, which creates new chat folder. Returns information about the created chat folder. There can be up to getOption("chat_folder_count_max") chat folders, but the limit can be increased with Telegram Premium. - * - *

Returns {@link ChatFolderInfo ChatFolderInfo}

- */ - public CreateChatFolder() { - } - - /** - * Creates a function, which creates new chat folder. Returns information about the created chat folder. There can be up to getOption("chat_folder_count_max") chat folders, but the limit can be increased with Telegram Premium. - * - *

Returns {@link ChatFolderInfo ChatFolderInfo}

- * - * @param folder The new chat folder. - */ - public CreateChatFolder(ChatFolder folder) { - this.folder = folder; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1015399680; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates a new invite link for a chat folder. A link can be created for a chat folder if it has only pinned and included chats. - * - *

Returns {@link ChatFolderInviteLink ChatFolderInviteLink}

- */ - public static class CreateChatFolderInviteLink extends Function { - /** - * Chat folder identifier. - */ - public int chatFolderId; - /** - * Name of the link; 0-32 characters. - */ - public String name; - /** - * Identifiers of chats to be accessible by the invite link. Use getChatsForChatFolderInviteLink to get suitable chats. Basic groups will be automatically converted to supergroups before link creation. - */ - public long[] chatIds; - - /** - * Default constructor for a function, which creates a new invite link for a chat folder. A link can be created for a chat folder if it has only pinned and included chats. - * - *

Returns {@link ChatFolderInviteLink ChatFolderInviteLink}

- */ - public CreateChatFolderInviteLink() { - } - - /** - * Creates a function, which creates a new invite link for a chat folder. A link can be created for a chat folder if it has only pinned and included chats. - * - *

Returns {@link ChatFolderInviteLink ChatFolderInviteLink}

- * - * @param chatFolderId Chat folder identifier. - * @param name Name of the link; 0-32 characters. - * @param chatIds Identifiers of chats to be accessible by the invite link. Use getChatsForChatFolderInviteLink to get suitable chats. Basic groups will be automatically converted to supergroups before link creation. - */ - public CreateChatFolderInviteLink(int chatFolderId, String name, long[] chatIds) { - this.chatFolderId = chatFolderId; - this.name = name; - this.chatIds = chatIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2037911099; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates a new invite link for a chat. Available for basic groups, supergroups, and channels. Requires administrator privileges and canInviteUsers right in the chat. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- */ - public static class CreateChatInviteLink extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Invite link name; 0-32 characters. - */ - public String name; - /** - * Point in time (Unix timestamp) when the link will expire; pass 0 if never. - */ - public int expirationDate; - /** - * The maximum number of chat members that can join the chat via the link simultaneously; 0-99999; pass 0 if not limited. - */ - public int memberLimit; - /** - * Pass true if users joining the chat via the link need to be approved by chat administrators. In this case, memberLimit must be 0. - */ - public boolean createsJoinRequest; - - /** - * Default constructor for a function, which creates a new invite link for a chat. Available for basic groups, supergroups, and channels. Requires administrator privileges and canInviteUsers right in the chat. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- */ - public CreateChatInviteLink() { - } - - /** - * Creates a function, which creates a new invite link for a chat. Available for basic groups, supergroups, and channels. Requires administrator privileges and canInviteUsers right in the chat. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- * - * @param chatId Chat identifier. - * @param name Invite link name; 0-32 characters. - * @param expirationDate Point in time (Unix timestamp) when the link will expire; pass 0 if never. - * @param memberLimit The maximum number of chat members that can join the chat via the link simultaneously; 0-99999; pass 0 if not limited. - * @param createsJoinRequest Pass true if users joining the chat via the link need to be approved by chat administrators. In this case, memberLimit must be 0. - */ - public CreateChatInviteLink(long chatId, String name, int expirationDate, int memberLimit, boolean createsJoinRequest) { - this.chatId = chatId; - this.name = name; - this.expirationDate = expirationDate; - this.memberLimit = memberLimit; - this.createsJoinRequest = createsJoinRequest; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 287744833; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates a new subscription invite link for a channel chat. Requires canInviteUsers right in the chat. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- */ - public static class CreateChatSubscriptionInviteLink extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Invite link name; 0-32 characters. - */ - public String name; - /** - * Information about subscription plan that will be applied to the users joining the chat via the link. Subscription period must be 2592000 in production environment, and 60 or 300 if Telegram test environment is used. - */ - public StarSubscriptionPricing subscriptionPricing; - - /** - * Default constructor for a function, which creates a new subscription invite link for a channel chat. Requires canInviteUsers right in the chat. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- */ - public CreateChatSubscriptionInviteLink() { - } - - /** - * Creates a function, which creates a new subscription invite link for a channel chat. Requires canInviteUsers right in the chat. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- * - * @param chatId Chat identifier. - * @param name Invite link name; 0-32 characters. - * @param subscriptionPricing Information about subscription plan that will be applied to the users joining the chat via the link. Subscription period must be 2592000 in production environment, and 60 or 300 if Telegram test environment is used. - */ - public CreateChatSubscriptionInviteLink(long chatId, String name, StarSubscriptionPricing subscriptionPricing) { - this.chatId = chatId; - this.name = name; - this.subscriptionPricing = subscriptionPricing; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2255717; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates a topic in a forum supergroup chat or a chat with a bot with topics; requires canManageTopics administrator or canCreateTopics member right in the supergroup. - * - *

Returns {@link ForumTopicInfo ForumTopicInfo}

- */ - public static class CreateForumTopic extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * Name of the topic; 1-128 characters. - */ - public String name; - /** - * Pass true if the name of the topic wasn't entered explicitly; for chats with bots only. - */ - public boolean isNameImplicit; - /** - * Icon of the topic. Icon color must be one of 0x6FB9F0, 0xFFD67E, 0xCB86DB, 0x8EEE98, 0xFF93B2, or 0xFB6F5F. Telegram Premium users can use any custom emoji as topic icon, other users can use only a custom emoji returned by getForumTopicDefaultIcons. - */ - public ForumTopicIcon icon; - - /** - * Default constructor for a function, which creates a topic in a forum supergroup chat or a chat with a bot with topics; requires canManageTopics administrator or canCreateTopics member right in the supergroup. - * - *

Returns {@link ForumTopicInfo ForumTopicInfo}

- */ - public CreateForumTopic() { - } - - /** - * Creates a function, which creates a topic in a forum supergroup chat or a chat with a bot with topics; requires canManageTopics administrator or canCreateTopics member right in the supergroup. - * - *

Returns {@link ForumTopicInfo ForumTopicInfo}

- * - * @param chatId Identifier of the chat. - * @param name Name of the topic; 1-128 characters. - * @param isNameImplicit Pass true if the name of the topic wasn't entered explicitly; for chats with bots only. - * @param icon Icon of the topic. Icon color must be one of 0x6FB9F0, 0xFFD67E, 0xCB86DB, 0x8EEE98, 0xFF93B2, or 0xFB6F5F. Telegram Premium users can use any custom emoji as topic icon, other users can use only a custom emoji returned by getForumTopicDefaultIcons. - */ - public CreateForumTopic(long chatId, String name, boolean isNameImplicit, ForumTopicIcon icon) { - this.chatId = chatId; - this.name = name; - this.isNameImplicit = isNameImplicit; - this.icon = icon; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -15242103; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates a collection from gifts on the current user's or a channel's profile page; requires canPostMessages administrator right in the channel chat. An owner can have up to getOption("gift_collection_count_max") gift collections. The new collection will be added to the end of the gift collection list of the owner. Returns the created collection. - * - *

Returns {@link GiftCollection GiftCollection}

- */ - public static class CreateGiftCollection extends Function { - /** - * Identifier of the user or the channel chat that received the gifts. - */ - public MessageSender ownerId; - /** - * Name of the collection; 1-12 characters. - */ - public String name; - /** - * Identifier of the gifts to add to the collection; 0-getOption("gift_collection_size_max") identifiers. - */ - public String[] receivedGiftIds; - - /** - * Default constructor for a function, which creates a collection from gifts on the current user's or a channel's profile page; requires canPostMessages administrator right in the channel chat. An owner can have up to getOption("gift_collection_count_max") gift collections. The new collection will be added to the end of the gift collection list of the owner. Returns the created collection. - * - *

Returns {@link GiftCollection GiftCollection}

- */ - public CreateGiftCollection() { - } - - /** - * Creates a function, which creates a collection from gifts on the current user's or a channel's profile page; requires canPostMessages administrator right in the channel chat. An owner can have up to getOption("gift_collection_count_max") gift collections. The new collection will be added to the end of the gift collection list of the owner. Returns the created collection. - * - *

Returns {@link GiftCollection GiftCollection}

- * - * @param ownerId Identifier of the user or the channel chat that received the gifts. - * @param name Name of the collection; 1-12 characters. - * @param receivedGiftIds Identifier of the gifts to add to the collection; 0-getOption("gift_collection_size_max") identifiers. - */ - public CreateGiftCollection(MessageSender ownerId, String name, String[] receivedGiftIds) { - this.ownerId = ownerId; - this.name = name; - this.receivedGiftIds = receivedGiftIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -397088099; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates a new group call that isn't bound to a chat. - * - *

Returns {@link GroupCallInfo GroupCallInfo}

- */ - public static class CreateGroupCall extends Function { - /** - * Parameters to join the call; pass null to only create call link without joining the call. - */ - public GroupCallJoinParameters joinParameters; - - /** - * Default constructor for a function, which creates a new group call that isn't bound to a chat. - * - *

Returns {@link GroupCallInfo GroupCallInfo}

- */ - public CreateGroupCall() { - } - - /** - * Creates a function, which creates a new group call that isn't bound to a chat. - * - *

Returns {@link GroupCallInfo GroupCallInfo}

- * - * @param joinParameters Parameters to join the call; pass null to only create call link without joining the call. - */ - public CreateGroupCall(GroupCallJoinParameters joinParameters) { - this.joinParameters = joinParameters; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1930068672; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates a link for the given invoice; for bots only. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public static class CreateInvoiceLink extends Function { - /** - * Unique identifier of business connection on behalf of which to send the request. - */ - public String businessConnectionId; - /** - * Information about the invoice of the type inputMessageInvoice. - */ - public InputMessageContent invoice; - - /** - * Default constructor for a function, which creates a link for the given invoice; for bots only. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public CreateInvoiceLink() { - } - - /** - * Creates a function, which creates a link for the given invoice; for bots only. - * - *

Returns {@link HttpUrl HttpUrl}

- * - * @param businessConnectionId Unique identifier of business connection on behalf of which to send the request. - * @param invoice Information about the invoice of the type inputMessageInvoice. - */ - public CreateInvoiceLink(String businessConnectionId, InputMessageContent invoice) { - this.businessConnectionId = businessConnectionId; - this.invoice = invoice; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -814692249; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates a new basic group and sends a corresponding messageBasicGroupChatCreate. Returns information about the newly created chat. - * - *

Returns {@link CreatedBasicGroupChat CreatedBasicGroupChat}

- */ - public static class CreateNewBasicGroupChat extends Function { - /** - * Identifiers of users to be added to the basic group; may be empty to create a basic group without other members. - */ - public long[] userIds; - /** - * Title of the new basic group; 1-128 characters. - */ - public String title; - /** - * Message auto-delete time value, in seconds; must be from 0 up to 365 * 86400 and be divisible by 86400. If 0, then messages aren't deleted automatically. - */ - public int messageAutoDeleteTime; - - /** - * Default constructor for a function, which creates a new basic group and sends a corresponding messageBasicGroupChatCreate. Returns information about the newly created chat. - * - *

Returns {@link CreatedBasicGroupChat CreatedBasicGroupChat}

- */ - public CreateNewBasicGroupChat() { - } - - /** - * Creates a function, which creates a new basic group and sends a corresponding messageBasicGroupChatCreate. Returns information about the newly created chat. - * - *

Returns {@link CreatedBasicGroupChat CreatedBasicGroupChat}

- * - * @param userIds Identifiers of users to be added to the basic group; may be empty to create a basic group without other members. - * @param title Title of the new basic group; 1-128 characters. - * @param messageAutoDeleteTime Message auto-delete time value, in seconds; must be from 0 up to 365 * 86400 and be divisible by 86400. If 0, then messages aren't deleted automatically. - */ - public CreateNewBasicGroupChat(long[] userIds, String title, int messageAutoDeleteTime) { - this.userIds = userIds; - this.title = title; - this.messageAutoDeleteTime = messageAutoDeleteTime; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1806454709; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates a new secret chat. Returns the newly created chat. - * - *

Returns {@link Chat Chat}

- */ - public static class CreateNewSecretChat extends Function { - /** - * Identifier of the target user. - */ - public long userId; - - /** - * Default constructor for a function, which creates a new secret chat. Returns the newly created chat. - * - *

Returns {@link Chat Chat}

- */ - public CreateNewSecretChat() { - } - - /** - * Creates a function, which creates a new secret chat. Returns the newly created chat. - * - *

Returns {@link Chat Chat}

- * - * @param userId Identifier of the target user. - */ - public CreateNewSecretChat(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -620682651; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates a new sticker set. Returns the newly created sticker set. - * - *

Returns {@link StickerSet StickerSet}

- */ - public static class CreateNewStickerSet extends Function { - /** - * Sticker set owner; ignored for regular users. - */ - public long userId; - /** - * Sticker set title; 1-64 characters. - */ - public String title; - /** - * Sticker set name. Can contain only English letters, digits and underscores. Must end with *"_by_<bot username>"* (*<botUsername>* is case insensitive) for bots; 0-64 characters. If empty, then the name returned by getSuggestedStickerSetName will be used automatically. - */ - public String name; - /** - * Type of the stickers in the set. - */ - public StickerType stickerType; - /** - * Pass true if stickers in the sticker set must be repainted; for custom emoji sticker sets only. - */ - public boolean needsRepainting; - /** - * List of stickers to be added to the set; 1-200 stickers for custom emoji sticker sets, and 1-120 stickers otherwise. For TGS stickers, uploadStickerFile must be used before the sticker is shown. - */ - public InputSticker[] stickers; - /** - * Source of the sticker set; may be empty if unknown. - */ - public String source; - - /** - * Default constructor for a function, which creates a new sticker set. Returns the newly created sticker set. - * - *

Returns {@link StickerSet StickerSet}

- */ - public CreateNewStickerSet() { - } - - /** - * Creates a function, which creates a new sticker set. Returns the newly created sticker set. - * - *

Returns {@link StickerSet StickerSet}

- * - * @param userId Sticker set owner; ignored for regular users. - * @param title Sticker set title; 1-64 characters. - * @param name Sticker set name. Can contain only English letters, digits and underscores. Must end with *"_by_<bot username>"* (*<botUsername>* is case insensitive) for bots; 0-64 characters. If empty, then the name returned by getSuggestedStickerSetName will be used automatically. - * @param stickerType Type of the stickers in the set. - * @param needsRepainting Pass true if stickers in the sticker set must be repainted; for custom emoji sticker sets only. - * @param stickers List of stickers to be added to the set; 1-200 stickers for custom emoji sticker sets, and 1-120 stickers otherwise. For TGS stickers, uploadStickerFile must be used before the sticker is shown. - * @param source Source of the sticker set; may be empty if unknown. - */ - public CreateNewStickerSet(long userId, String title, String name, StickerType stickerType, boolean needsRepainting, InputSticker[] stickers, String source) { - this.userId = userId; - this.title = title; - this.name = name; - this.stickerType = stickerType; - this.needsRepainting = needsRepainting; - this.stickers = stickers; - this.source = source; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -481065727; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates a new supergroup or channel and sends a corresponding messageSupergroupChatCreate. Returns the newly created chat. - * - *

Returns {@link Chat Chat}

- */ - public static class CreateNewSupergroupChat extends Function { - /** - * Title of the new chat; 1-128 characters. - */ - public String title; - /** - * Pass true to create a forum supergroup chat. - */ - public boolean isForum; - /** - * Pass true to create a channel chat; ignored if a forum is created. - */ - public boolean isChannel; - /** - * Chat description; 0-255 characters. - */ - public String description; - /** - * Chat location if a location-based supergroup is being created; pass null to create an ordinary supergroup chat. - */ - public ChatLocation location; - /** - * Message auto-delete time value, in seconds; must be from 0 up to 365 * 86400 and be divisible by 86400. If 0, then messages aren't deleted automatically. - */ - public int messageAutoDeleteTime; - /** - * Pass true to create a supergroup for importing messages using importMessages. - */ - public boolean forImport; - - /** - * Default constructor for a function, which creates a new supergroup or channel and sends a corresponding messageSupergroupChatCreate. Returns the newly created chat. - * - *

Returns {@link Chat Chat}

- */ - public CreateNewSupergroupChat() { - } - - /** - * Creates a function, which creates a new supergroup or channel and sends a corresponding messageSupergroupChatCreate. Returns the newly created chat. - * - *

Returns {@link Chat Chat}

- * - * @param title Title of the new chat; 1-128 characters. - * @param isForum Pass true to create a forum supergroup chat. - * @param isChannel Pass true to create a channel chat; ignored if a forum is created. - * @param description Chat description; 0-255 characters. - * @param location Chat location if a location-based supergroup is being created; pass null to create an ordinary supergroup chat. - * @param messageAutoDeleteTime Message auto-delete time value, in seconds; must be from 0 up to 365 * 86400 and be divisible by 86400. If 0, then messages aren't deleted automatically. - * @param forImport Pass true to create a supergroup for importing messages using importMessages. - */ - public CreateNewSupergroupChat(String title, boolean isForum, boolean isChannel, String description, ChatLocation location, int messageAutoDeleteTime, boolean forImport) { - this.title = title; - this.isForum = isForum; - this.isChannel = isChannel; - this.description = description; - this.location = location; - this.messageAutoDeleteTime = messageAutoDeleteTime; - this.forImport = forImport; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 804058822; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an existing chat corresponding to a given user. - * - *

Returns {@link Chat Chat}

- */ - public static class CreatePrivateChat extends Function { - /** - * User identifier. - */ - public long userId; - /** - * Pass true to create the chat without a network request. In this case all information about the chat except its type, title and photo can be incorrect. - */ - public boolean force; - - /** - * Default constructor for a function, which returns an existing chat corresponding to a given user. - * - *

Returns {@link Chat Chat}

- */ - public CreatePrivateChat() { - } - - /** - * Creates a function, which returns an existing chat corresponding to a given user. - * - *

Returns {@link Chat Chat}

- * - * @param userId User identifier. - * @param force Pass true to create the chat without a network request. In this case all information about the chat except its type, title and photo can be incorrect. - */ - public CreatePrivateChat(long userId, boolean force) { - this.userId = userId; - this.force = force; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -947758327; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an existing chat corresponding to a known secret chat. - * - *

Returns {@link Chat Chat}

- */ - public static class CreateSecretChat extends Function { - /** - * Secret chat identifier. - */ - public int secretChatId; - - /** - * Default constructor for a function, which returns an existing chat corresponding to a known secret chat. - * - *

Returns {@link Chat Chat}

- */ - public CreateSecretChat() { - } - - /** - * Creates a function, which returns an existing chat corresponding to a known secret chat. - * - *

Returns {@link Chat Chat}

- * - * @param secretChatId Secret chat identifier. - */ - public CreateSecretChat(int secretChatId) { - this.secretChatId = secretChatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1930285615; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates an album of stories; requires canEditStories administrator right for supergroup and channel chats. - * - *

Returns {@link StoryAlbum StoryAlbum}

- */ - public static class CreateStoryAlbum extends Function { - /** - * Identifier of the chat that posted the stories. - */ - public long storyPosterChatId; - /** - * Name of the album; 1-12 characters. - */ - public String name; - /** - * Identifiers of stories to add to the album; 0-getOption("story_album_size_max") identifiers. - */ - public int[] storyIds; - - /** - * Default constructor for a function, which creates an album of stories; requires canEditStories administrator right for supergroup and channel chats. - * - *

Returns {@link StoryAlbum StoryAlbum}

- */ - public CreateStoryAlbum() { - } - - /** - * Creates a function, which creates an album of stories; requires canEditStories administrator right for supergroup and channel chats. - * - *

Returns {@link StoryAlbum StoryAlbum}

- * - * @param storyPosterChatId Identifier of the chat that posted the stories. - * @param name Name of the album; 1-12 characters. - * @param storyIds Identifiers of stories to add to the album; 0-getOption("story_album_size_max") identifiers. - */ - public CreateStoryAlbum(long storyPosterChatId, String name, int[] storyIds) { - this.storyPosterChatId = storyPosterChatId; - this.name = name; - this.storyIds = storyIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -804362185; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an existing chat corresponding to a known supergroup or channel. - * - *

Returns {@link Chat Chat}

- */ - public static class CreateSupergroupChat extends Function { - /** - * Supergroup or channel identifier. - */ - public long supergroupId; - /** - * Pass true to create the chat without a network request. In this case all information about the chat except its type, title and photo can be incorrect. - */ - public boolean force; - - /** - * Default constructor for a function, which returns an existing chat corresponding to a known supergroup or channel. - * - *

Returns {@link Chat Chat}

- */ - public CreateSupergroupChat() { - } - - /** - * Creates a function, which returns an existing chat corresponding to a known supergroup or channel. - * - *

Returns {@link Chat Chat}

- * - * @param supergroupId Supergroup or channel identifier. - * @param force Pass true to create the chat without a network request. In this case all information about the chat except its type, title and photo can be incorrect. - */ - public CreateSupergroupChat(long supergroupId, boolean force) { - this.supergroupId = supergroupId; - this.force = force; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1187475691; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates a new temporary password for processing payments. - * - *

Returns {@link TemporaryPasswordState TemporaryPasswordState}

- */ - public static class CreateTemporaryPassword extends Function { - /** - * The 2-step verification password of the current user. - */ - public String password; - /** - * Time during which the temporary password will be valid, in seconds; must be between 60 and 86400. - */ - public int validFor; - - /** - * Default constructor for a function, which creates a new temporary password for processing payments. - * - *

Returns {@link TemporaryPasswordState TemporaryPasswordState}

- */ - public CreateTemporaryPassword() { - } - - /** - * Creates a function, which creates a new temporary password for processing payments. - * - *

Returns {@link TemporaryPasswordState TemporaryPasswordState}

- * - * @param password The 2-step verification password of the current user. - * @param validFor Time during which the temporary password will be valid, in seconds; must be between 60 and 86400. - */ - public CreateTemporaryPassword(String password, int validFor) { - this.password = password; - this.validFor = validFor; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1626509434; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates a video chat (a group call bound to a chat); for basic groups, supergroups and channels only; requires canManageVideoChats administrator right. - * - *

Returns {@link GroupCallId GroupCallId}

- */ - public static class CreateVideoChat extends Function { - /** - * Identifier of a chat in which the video chat will be created. - */ - public long chatId; - /** - * Group call title; if empty, chat title will be used. - */ - public String title; - /** - * Point in time (Unix timestamp) when the group call is expected to be started by an administrator; 0 to start the video chat immediately. The date must be at least 10 seconds and at most 8 days in the future. - */ - public int startDate; - /** - * Pass true to create an RTMP stream instead of an ordinary video chat. - */ - public boolean isRtmpStream; - - /** - * Default constructor for a function, which creates a video chat (a group call bound to a chat); for basic groups, supergroups and channels only; requires canManageVideoChats administrator right. - * - *

Returns {@link GroupCallId GroupCallId}

- */ - public CreateVideoChat() { - } - - /** - * Creates a function, which creates a video chat (a group call bound to a chat); for basic groups, supergroups and channels only; requires canManageVideoChats administrator right. - * - *

Returns {@link GroupCallId GroupCallId}

- * - * @param chatId Identifier of a chat in which the video chat will be created. - * @param title Group call title; if empty, chat title will be used. - * @param startDate Point in time (Unix timestamp) when the group call is expected to be started by an administrator; 0 to start the video chat immediately. The date must be at least 10 seconds and at most 8 days in the future. - * @param isRtmpStream Pass true to create an RTMP stream instead of an ordinary video chat. - */ - public CreateVideoChat(long chatId, String title, int startDate, boolean isRtmpStream) { - this.chatId = chatId; - this.title = title; - this.startDate = startDate; - this.isRtmpStream = isRtmpStream; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2124715405; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Declines an invitation to an active group call via messageGroupCall. Can be called both by the sender and the receiver of the invitation. - * - *

Returns {@link Ok Ok}

- */ - public static class DeclineGroupCallInvitation extends Function { - /** - * Identifier of the chat with the message. - */ - public long chatId; - /** - * Identifier of the message of the type messageGroupCall. - */ - public long messageId; - - /** - * Default constructor for a function, which declines an invitation to an active group call via messageGroupCall. Can be called both by the sender and the receiver of the invitation. - * - *

Returns {@link Ok Ok}

- */ - public DeclineGroupCallInvitation() { - } - - /** - * Creates a function, which declines an invitation to an active group call via messageGroupCall. Can be called both by the sender and the receiver of the invitation. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat with the message. - * @param messageId Identifier of the message of the type messageGroupCall. - */ - public DeclineGroupCallInvitation(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1843919377; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Declines an OAuth authorization request. - * - *

Returns {@link Ok Ok}

- */ - public static class DeclineOauthRequest extends Function { - /** - * URL of the OAuth deep link. - */ - public String url; - - /** - * Default constructor for a function, which declines an OAuth authorization request. - * - *

Returns {@link Ok Ok}

- */ - public DeclineOauthRequest() { - } - - /** - * Creates a function, which declines an OAuth authorization request. - * - *

Returns {@link Ok Ok}

- * - * @param url URL of the OAuth deep link. - */ - public DeclineOauthRequest(String url) { - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 420650996; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Declines a suggested post in a channel direct messages chat. - * - *

Returns {@link Ok Ok}

- */ - public static class DeclineSuggestedPost extends Function { - /** - * Chat identifier of the channel direct messages chat. - */ - public long chatId; - /** - * Identifier of the message with the suggested post. Use messageProperties.canBeDeclined to check whether the suggested post can be declined. - */ - public long messageId; - /** - * Comment for the creator of the suggested post; 0-128 characters. - */ - public String comment; - - /** - * Default constructor for a function, which declines a suggested post in a channel direct messages chat. - * - *

Returns {@link Ok Ok}

- */ - public DeclineSuggestedPost() { - } - - /** - * Creates a function, which declines a suggested post in a channel direct messages chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier of the channel direct messages chat. - * @param messageId Identifier of the message with the suggested post. Use messageProperties.canBeDeclined to check whether the suggested post can be declined. - * @param comment Comment for the creator of the suggested post; 0-128 characters. - */ - public DeclineSuggestedPost(long chatId, long messageId, String comment) { - this.chatId = chatId; - this.messageId = messageId; - this.comment = comment; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1758260609; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Decrypts group call data received by tgcalls. - * - *

Returns {@link Data Data}

- */ - public static class DecryptGroupCallData extends Function { - /** - * Group call identifier. The call must not be a video chat. - */ - public int groupCallId; - /** - * Identifier of the group call participant, which sent the data. - */ - public MessageSender participantId; - /** - * Data channel for which data was encrypted; pass null if unknown. - */ - public GroupCallDataChannel dataChannel; - /** - * Data to decrypt. - */ - public byte[] data; - - /** - * Default constructor for a function, which decrypts group call data received by tgcalls. - * - *

Returns {@link Data Data}

- */ - public DecryptGroupCallData() { - } - - /** - * Creates a function, which decrypts group call data received by tgcalls. - * - *

Returns {@link Data Data}

- * - * @param groupCallId Group call identifier. The call must not be a video chat. - * @param participantId Identifier of the group call participant, which sent the data. - * @param dataChannel Data channel for which data was encrypted; pass null if unknown. - * @param data Data to decrypt. - */ - public DecryptGroupCallData(int groupCallId, MessageSender participantId, GroupCallDataChannel dataChannel, byte[] data) { - this.groupCallId = groupCallId; - this.participantId = participantId; - this.dataChannel = dataChannel; - this.data = data; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1781743076; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes the account of the current user, deleting all information associated with the user from the server. The phone number of the account can be used to create a new account. Can be called before authorization when the current authorization state is authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteAccount extends Function { - /** - * The reason why the account was deleted; optional. - */ - public String reason; - /** - * The 2-step verification password of the current user. If the current user isn't authorized, then an empty string can be passed and account deletion can be canceled within one week. - */ - public String password; - - /** - * Default constructor for a function, which deletes the account of the current user, deleting all information associated with the user from the server. The phone number of the account can be used to create a new account. Can be called before authorization when the current authorization state is authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- */ - public DeleteAccount() { - } - - /** - * Creates a function, which deletes the account of the current user, deleting all information associated with the user from the server. The phone number of the account can be used to create a new account. Can be called before authorization when the current authorization state is authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- * - * @param reason The reason why the account was deleted; optional. - * @param password The 2-step verification password of the current user. If the current user isn't authorized, then an empty string can be passed and account deletion can be canceled within one week. - */ - public DeleteAccount(String reason, String password) { - this.reason = reason; - this.password = password; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1395816134; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes all call messages. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteAllCallMessages extends Function { - /** - * Pass true to delete the messages for all users. - */ - public boolean revoke; - - /** - * Default constructor for a function, which deletes all call messages. - * - *

Returns {@link Ok Ok}

- */ - public DeleteAllCallMessages() { - } - - /** - * Creates a function, which deletes all call messages. - * - *

Returns {@link Ok Ok}

- * - * @param revoke Pass true to delete the messages for all users. - */ - public DeleteAllCallMessages(boolean revoke) { - this.revoke = revoke; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1466445325; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes all revoked chat invite links created by a given chat administrator. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteAllRevokedChatInviteLinks extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * User identifier of a chat administrator, which links will be deleted. Must be an identifier of the current user for non-owner. - */ - public long creatorUserId; - - /** - * Default constructor for a function, which deletes all revoked chat invite links created by a given chat administrator. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. - * - *

Returns {@link Ok Ok}

- */ - public DeleteAllRevokedChatInviteLinks() { - } - - /** - * Creates a function, which deletes all revoked chat invite links created by a given chat administrator. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param creatorUserId User identifier of a chat administrator, which links will be deleted. Must be an identifier of the current user for non-owner. - */ - public DeleteAllRevokedChatInviteLinks(long chatId, long creatorUserId) { - this.chatId = chatId; - this.creatorUserId = creatorUserId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1112020698; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes media previews from the list of media previews of a bot. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteBotMediaPreviews extends Function { - /** - * Identifier of the target bot. The bot must be owned and must have the main Web App. - */ - public long botUserId; - /** - * Language code of the media previews to delete. - */ - public String languageCode; - /** - * File identifiers of the media to delete. - */ - public int[] fileIds; - - /** - * Default constructor for a function, which deletes media previews from the list of media previews of a bot. - * - *

Returns {@link Ok Ok}

- */ - public DeleteBotMediaPreviews() { - } - - /** - * Creates a function, which deletes media previews from the list of media previews of a bot. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId Identifier of the target bot. The bot must be owned and must have the main Web App. - * @param languageCode Language code of the media previews to delete. - * @param fileIds File identifiers of the media to delete. - */ - public DeleteBotMediaPreviews(long botUserId, String languageCode, int[] fileIds) { - this.botUserId = botUserId; - this.languageCode = languageCode; - this.fileIds = fileIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1397512722; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes a business chat link of the current account. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteBusinessChatLink extends Function { - /** - * The link to delete. - */ - public String link; - - /** - * Default constructor for a function, which deletes a business chat link of the current account. - * - *

Returns {@link Ok Ok}

- */ - public DeleteBusinessChatLink() { - } - - /** - * Creates a function, which deletes a business chat link of the current account. - * - *

Returns {@link Ok Ok}

- * - * @param link The link to delete. - */ - public DeleteBusinessChatLink(String link) { - this.link = link; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1101895865; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes the business bot that is connected to the current user account. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteBusinessConnectedBot extends Function { - /** - * Unique user identifier for the bot. - */ - public long botUserId; - - /** - * Default constructor for a function, which deletes the business bot that is connected to the current user account. - * - *

Returns {@link Ok Ok}

- */ - public DeleteBusinessConnectedBot() { - } - - /** - * Creates a function, which deletes the business bot that is connected to the current user account. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId Unique user identifier for the bot. - */ - public DeleteBusinessConnectedBot(long botUserId) { - this.botUserId = botUserId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1633976747; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes messages on behalf of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteBusinessMessages extends Function { - /** - * Unique identifier of business connection through which the messages were received. - */ - public String businessConnectionId; - /** - * Identifier of the messages. - */ - public long[] messageIds; - - /** - * Default constructor for a function, which deletes messages on behalf of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public DeleteBusinessMessages() { - } - - /** - * Creates a function, which deletes messages on behalf of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param businessConnectionId Unique identifier of business connection through which the messages were received. - * @param messageIds Identifier of the messages. - */ - public DeleteBusinessMessages(String businessConnectionId, long[] messageIds) { - this.businessConnectionId = businessConnectionId; - this.messageIds = messageIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1425721828; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes a story posted by the bot on behalf of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteBusinessStory extends Function { - /** - * Unique identifier of business connection. - */ - public String businessConnectionId; - /** - * Identifier of the story to delete. - */ - public int storyId; - - /** - * Default constructor for a function, which deletes a story posted by the bot on behalf of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public DeleteBusinessStory() { - } - - /** - * Creates a function, which deletes a story posted by the bot on behalf of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param businessConnectionId Unique identifier of business connection. - * @param storyId Identifier of the story to delete. - */ - public DeleteBusinessStory(String businessConnectionId, int storyId) { - this.businessConnectionId = businessConnectionId; - this.storyId = storyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1024585042; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes a chat along with all messages in the corresponding chat for all chat members. For group chats this will release the usernames and remove all members. Use the field chat.canBeDeletedForAllUsers to find whether the method can be applied to the chat. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteChat extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which deletes a chat along with all messages in the corresponding chat for all chat members. For group chats this will release the usernames and remove all members. Use the field chat.canBeDeletedForAllUsers to find whether the method can be applied to the chat. - * - *

Returns {@link Ok Ok}

- */ - public DeleteChat() { - } - - /** - * Creates a function, which deletes a chat along with all messages in the corresponding chat for all chat members. For group chats this will release the usernames and remove all members. Use the field chat.canBeDeletedForAllUsers to find whether the method can be applied to the chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - */ - public DeleteChat(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -171253666; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes background in a specific chat. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteChatBackground extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Pass true to restore previously set background. Can be used only in private and secret chats with non-deleted users if userFullInfo.setChatBackground == true. Supposed to be used from messageChatSetBackground messages with the currently set background that was set for both sides by the other user. - */ - public boolean restorePrevious; - - /** - * Default constructor for a function, which deletes background in a specific chat. - * - *

Returns {@link Ok Ok}

- */ - public DeleteChatBackground() { - } - - /** - * Creates a function, which deletes background in a specific chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param restorePrevious Pass true to restore previously set background. Can be used only in private and secret chats with non-deleted users if userFullInfo.setChatBackground == true. Supposed to be used from messageChatSetBackground messages with the currently set background that was set for both sides by the other user. - */ - public DeleteChatBackground(long chatId, boolean restorePrevious) { - this.chatId = chatId; - this.restorePrevious = restorePrevious; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 320267896; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes existing chat folder. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteChatFolder extends Function { - /** - * Chat folder identifier. - */ - public int chatFolderId; - /** - * Identifiers of the chats to leave. The chats must be pinned or always included in the folder. - */ - public long[] leaveChatIds; - - /** - * Default constructor for a function, which deletes existing chat folder. - * - *

Returns {@link Ok Ok}

- */ - public DeleteChatFolder() { - } - - /** - * Creates a function, which deletes existing chat folder. - * - *

Returns {@link Ok Ok}

- * - * @param chatFolderId Chat folder identifier. - * @param leaveChatIds Identifiers of the chats to leave. The chats must be pinned or always included in the folder. - */ - public DeleteChatFolder(int chatFolderId, long[] leaveChatIds) { - this.chatFolderId = chatFolderId; - this.leaveChatIds = leaveChatIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1956364551; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes an invite link for a chat folder. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteChatFolderInviteLink extends Function { - /** - * Chat folder identifier. - */ - public int chatFolderId; - /** - * Invite link to be deleted. - */ - public String inviteLink; - - /** - * Default constructor for a function, which deletes an invite link for a chat folder. - * - *

Returns {@link Ok Ok}

- */ - public DeleteChatFolderInviteLink() { - } - - /** - * Creates a function, which deletes an invite link for a chat folder. - * - *

Returns {@link Ok Ok}

- * - * @param chatFolderId Chat folder identifier. - * @param inviteLink Invite link to be deleted. - */ - public DeleteChatFolderInviteLink(int chatFolderId, String inviteLink) { - this.chatFolderId = chatFolderId; - this.inviteLink = inviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -930057858; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes all messages in the chat. Use chat.canBeDeletedOnlyForSelf and chat.canBeDeletedForAllUsers fields to find whether and how the method can be applied to the chat. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteChatHistory extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Pass true to remove the chat from all chat lists. - */ - public boolean removeFromChatList; - /** - * Pass true to delete chat history for all users. - */ - public boolean revoke; - - /** - * Default constructor for a function, which deletes all messages in the chat. Use chat.canBeDeletedOnlyForSelf and chat.canBeDeletedForAllUsers fields to find whether and how the method can be applied to the chat. - * - *

Returns {@link Ok Ok}

- */ - public DeleteChatHistory() { - } - - /** - * Creates a function, which deletes all messages in the chat. Use chat.canBeDeletedOnlyForSelf and chat.canBeDeletedForAllUsers fields to find whether and how the method can be applied to the chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param removeFromChatList Pass true to remove the chat from all chat lists. - * @param revoke Pass true to delete chat history for all users. - */ - public DeleteChatHistory(long chatId, boolean removeFromChatList, boolean revoke) { - this.chatId = chatId; - this.removeFromChatList = removeFromChatList; - this.revoke = revoke; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1472081761; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes all messages between the specified dates in a chat. Supported only for private chats and basic groups. Messages sent in the last 30 seconds will not be deleted. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteChatMessagesByDate extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * The minimum date of the messages to delete. - */ - public int minDate; - /** - * The maximum date of the messages to delete. - */ - public int maxDate; - /** - * Pass true to delete chat messages for all users; private chats only. - */ - public boolean revoke; - - /** - * Default constructor for a function, which deletes all messages between the specified dates in a chat. Supported only for private chats and basic groups. Messages sent in the last 30 seconds will not be deleted. - * - *

Returns {@link Ok Ok}

- */ - public DeleteChatMessagesByDate() { - } - - /** - * Creates a function, which deletes all messages between the specified dates in a chat. Supported only for private chats and basic groups. Messages sent in the last 30 seconds will not be deleted. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param minDate The minimum date of the messages to delete. - * @param maxDate The maximum date of the messages to delete. - * @param revoke Pass true to delete chat messages for all users; private chats only. - */ - public DeleteChatMessagesByDate(long chatId, int minDate, int maxDate, boolean revoke) { - this.chatId = chatId; - this.minDate = minDate; - this.maxDate = maxDate; - this.revoke = revoke; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1639653185; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes all messages sent by the specified message sender in a chat. Supported only for supergroups; requires canDeleteMessages administrator right. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteChatMessagesBySender extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the sender of messages to delete. - */ - public MessageSender senderId; - - /** - * Default constructor for a function, which deletes all messages sent by the specified message sender in a chat. Supported only for supergroups; requires canDeleteMessages administrator right. - * - *

Returns {@link Ok Ok}

- */ - public DeleteChatMessagesBySender() { - } - - /** - * Creates a function, which deletes all messages sent by the specified message sender in a chat. Supported only for supergroups; requires canDeleteMessages administrator right. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param senderId Identifier of the sender of messages to delete. - */ - public DeleteChatMessagesBySender(long chatId, MessageSender senderId) { - this.chatId = chatId; - this.senderId = senderId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1164235161; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes the default reply markup from a chat. Must be called after a one-time keyboard or a replyMarkupForceReply reply markup has been used or dismissed. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteChatReplyMarkup extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * The message identifier of the used keyboard. - */ - public long messageId; - - /** - * Default constructor for a function, which deletes the default reply markup from a chat. Must be called after a one-time keyboard or a replyMarkupForceReply reply markup has been used or dismissed. - * - *

Returns {@link Ok Ok}

- */ - public DeleteChatReplyMarkup() { - } - - /** - * Creates a function, which deletes the default reply markup from a chat. Must be called after a one-time keyboard or a replyMarkupForceReply reply markup has been used or dismissed. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param messageId The message identifier of the used keyboard. - */ - public DeleteChatReplyMarkup(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 100637531; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes commands supported by the bot for the given user scope and language; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteCommands extends Function { - /** - * The scope to which the commands are relevant; pass null to delete commands in the default bot command scope. - */ - public BotCommandScope scope; - /** - * A two-letter ISO 639-1 language code or an empty string. - */ - public String languageCode; - - /** - * Default constructor for a function, which deletes commands supported by the bot for the given user scope and language; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public DeleteCommands() { - } - - /** - * Creates a function, which deletes commands supported by the bot for the given user scope and language; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param scope The scope to which the commands are relevant; pass null to delete commands in the default bot command scope. - * @param languageCode A two-letter ISO 639-1 language code or an empty string. - */ - public DeleteCommands(BotCommandScope scope, String languageCode) { - this.scope = scope; - this.languageCode = languageCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1002732586; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes default background for chats. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteDefaultBackground extends Function { - /** - * Pass true if the background is deleted for a dark theme. - */ - public boolean forDarkTheme; - - /** - * Default constructor for a function, which deletes default background for chats. - * - *

Returns {@link Ok Ok}

- */ - public DeleteDefaultBackground() { - } - - /** - * Creates a function, which deletes default background for chats. - * - *

Returns {@link Ok Ok}

- * - * @param forDarkTheme Pass true if the background is deleted for a dark theme. - */ - public DeleteDefaultBackground(boolean forDarkTheme) { - this.forDarkTheme = forDarkTheme; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1297814210; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes all messages in the topic in a channel direct messages chat administered by the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteDirectMessagesChatTopicHistory extends Function { - /** - * Chat identifier of the channel direct messages chat. - */ - public long chatId; - /** - * Identifier of the topic which messages will be deleted. - */ - public long topicId; - - /** - * Default constructor for a function, which deletes all messages in the topic in a channel direct messages chat administered by the current user. - * - *

Returns {@link Ok Ok}

- */ - public DeleteDirectMessagesChatTopicHistory() { - } - - /** - * Creates a function, which deletes all messages in the topic in a channel direct messages chat administered by the current user. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier of the channel direct messages chat. - * @param topicId Identifier of the topic which messages will be deleted. - */ - public DeleteDirectMessagesChatTopicHistory(long chatId, long topicId) { - this.chatId = chatId; - this.topicId = topicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1906080196; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes all messages between the specified dates in the topic in a channel direct messages chat administered by the current user. Messages sent in the last 30 seconds will not be deleted. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteDirectMessagesChatTopicMessagesByDate extends Function { - /** - * Chat identifier of the channel direct messages chat. - */ - public long chatId; - /** - * Identifier of the topic which messages will be deleted. - */ - public long topicId; - /** - * The minimum date of the messages to delete. - */ - public int minDate; - /** - * The maximum date of the messages to delete. - */ - public int maxDate; - - /** - * Default constructor for a function, which deletes all messages between the specified dates in the topic in a channel direct messages chat administered by the current user. Messages sent in the last 30 seconds will not be deleted. - * - *

Returns {@link Ok Ok}

- */ - public DeleteDirectMessagesChatTopicMessagesByDate() { - } - - /** - * Creates a function, which deletes all messages between the specified dates in the topic in a channel direct messages chat administered by the current user. Messages sent in the last 30 seconds will not be deleted. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier of the channel direct messages chat. - * @param topicId Identifier of the topic which messages will be deleted. - * @param minDate The minimum date of the messages to delete. - * @param maxDate The maximum date of the messages to delete. - */ - public DeleteDirectMessagesChatTopicMessagesByDate(long chatId, long topicId, int minDate, int maxDate) { - this.chatId = chatId; - this.topicId = topicId; - this.minDate = minDate; - this.maxDate = maxDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 945080841; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes a file from the TDLib file cache. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteFile extends Function { - /** - * Identifier of the file to delete. - */ - public int fileId; - - /** - * Default constructor for a function, which deletes a file from the TDLib file cache. - * - *

Returns {@link Ok Ok}

- */ - public DeleteFile() { - } - - /** - * Creates a function, which deletes a file from the TDLib file cache. - * - *

Returns {@link Ok Ok}

- * - * @param fileId Identifier of the file to delete. - */ - public DeleteFile(int fileId) { - this.fileId = fileId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1807653676; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes all messages from a topic in a forum supergroup chat or a chat with a bot with topics; requires canDeleteMessages administrator right in the supergroup unless the user is creator of the topic, the topic has no messages from other users and has at most 11 messages. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteForumTopic extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * Forum topic identifier. - */ - public int forumTopicId; - - /** - * Default constructor for a function, which deletes all messages from a topic in a forum supergroup chat or a chat with a bot with topics; requires canDeleteMessages administrator right in the supergroup unless the user is creator of the topic, the topic has no messages from other users and has at most 11 messages. - * - *

Returns {@link Ok Ok}

- */ - public DeleteForumTopic() { - } - - /** - * Creates a function, which deletes all messages from a topic in a forum supergroup chat or a chat with a bot with topics; requires canDeleteMessages administrator right in the supergroup unless the user is creator of the topic, the topic has no messages from other users and has at most 11 messages. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat. - * @param forumTopicId Forum topic identifier. - */ - public DeleteForumTopic(long chatId, int forumTopicId) { - this.chatId = chatId; - this.forumTopicId = forumTopicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2121212039; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes a gift collection. If the collection is owned by a channel chat, then requires canPostMessages administrator right in the channel chat. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteGiftCollection extends Function { - /** - * Identifier of the user or the channel chat that owns the collection. - */ - public MessageSender ownerId; - /** - * Identifier of the gift collection. - */ - public int collectionId; - - /** - * Default constructor for a function, which deletes a gift collection. If the collection is owned by a channel chat, then requires canPostMessages administrator right in the channel chat. - * - *

Returns {@link Ok Ok}

- */ - public DeleteGiftCollection() { - } - - /** - * Creates a function, which deletes a gift collection. If the collection is owned by a channel chat, then requires canPostMessages administrator right in the channel chat. - * - *

Returns {@link Ok Ok}

- * - * @param ownerId Identifier of the user or the channel chat that owns the collection. - * @param collectionId Identifier of the gift collection. - */ - public DeleteGiftCollection(MessageSender ownerId, int collectionId) { - this.ownerId = ownerId; - this.collectionId = collectionId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -183749499; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes messages in a group call; for live story calls only. Requires groupCallMessage.canBeDeleted right. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteGroupCallMessages extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Identifiers of the messages to be deleted. - */ - public int[] messageIds; - /** - * Pass true to report the messages as spam. - */ - public boolean reportSpam; - - /** - * Default constructor for a function, which deletes messages in a group call; for live story calls only. Requires groupCallMessage.canBeDeleted right. - * - *

Returns {@link Ok Ok}

- */ - public DeleteGroupCallMessages() { - } - - /** - * Creates a function, which deletes messages in a group call; for live story calls only. Requires groupCallMessage.canBeDeleted right. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param messageIds Identifiers of the messages to be deleted. - * @param reportSpam Pass true to report the messages as spam. - */ - public DeleteGroupCallMessages(int groupCallId, int[] messageIds, boolean reportSpam) { - this.groupCallId = groupCallId; - this.messageIds = messageIds; - this.reportSpam = reportSpam; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 339562398; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes all messages sent by the specified message sender in a group call; for live story calls only. Requires groupCall.canDeleteMessages right. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteGroupCallMessagesBySender extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Identifier of the sender of messages to delete. - */ - public MessageSender senderId; - /** - * Pass true to report the messages as spam. - */ - public boolean reportSpam; - - /** - * Default constructor for a function, which deletes all messages sent by the specified message sender in a group call; for live story calls only. Requires groupCall.canDeleteMessages right. - * - *

Returns {@link Ok Ok}

- */ - public DeleteGroupCallMessagesBySender() { - } - - /** - * Creates a function, which deletes all messages sent by the specified message sender in a group call; for live story calls only. Requires groupCall.canDeleteMessages right. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param senderId Identifier of the sender of messages to delete. - * @param reportSpam Pass true to report the messages as spam. - */ - public DeleteGroupCallMessagesBySender(int groupCallId, MessageSender senderId, boolean reportSpam) { - this.groupCallId = groupCallId; - this.senderId = senderId; - this.reportSpam = reportSpam; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1677247618; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes all information about a language pack in the current localization target. The language pack which is currently in use (including base language pack) or is being synchronized can't be deleted. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteLanguagePack extends Function { - /** - * Identifier of the language pack to delete. - */ - public String languagePackId; - - /** - * Default constructor for a function, which deletes all information about a language pack in the current localization target. The language pack which is currently in use (including base language pack) or is being synchronized can't be deleted. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public DeleteLanguagePack() { - } - - /** - * Creates a function, which deletes all information about a language pack in the current localization target. The language pack which is currently in use (including base language pack) or is being synchronized can't be deleted. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- * - * @param languagePackId Identifier of the language pack to delete. - */ - public DeleteLanguagePack(String languagePackId) { - this.languagePackId = languagePackId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2108761026; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes messages. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteMessages extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifiers of the messages to be deleted. Use messageProperties.canBeDeletedOnlyForSelf and messageProperties.canBeDeletedForAllUsers to get suitable messages. - */ - public long[] messageIds; - /** - * Pass true to delete messages for all chat members. Always true for supergroups, channels and secret chats. - */ - public boolean revoke; - - /** - * Default constructor for a function, which deletes messages. - * - *

Returns {@link Ok Ok}

- */ - public DeleteMessages() { - } - - /** - * Creates a function, which deletes messages. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param messageIds Identifiers of the messages to be deleted. Use messageProperties.canBeDeletedOnlyForSelf and messageProperties.canBeDeletedForAllUsers to get suitable messages. - * @param revoke Pass true to delete messages for all chat members. Always true for supergroups, channels and secret chats. - */ - public DeleteMessages(long chatId, long[] messageIds, boolean revoke) { - this.chatId = chatId; - this.messageIds = messageIds; - this.revoke = revoke; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1130090173; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes a Telegram Passport element. - * - *

Returns {@link Ok Ok}

- */ - public static class DeletePassportElement extends Function { - /** - * Element type. - */ - public PassportElementType type; - - /** - * Default constructor for a function, which deletes a Telegram Passport element. - * - *

Returns {@link Ok Ok}

- */ - public DeletePassportElement() { - } - - /** - * Creates a function, which deletes a Telegram Passport element. - * - *

Returns {@link Ok Ok}

- * - * @param type Element type. - */ - public DeletePassportElement(PassportElementType type) { - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1719555468; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes a profile photo. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteProfilePhoto extends Function { - /** - * Identifier of the profile photo to delete. - */ - public long profilePhotoId; - - /** - * Default constructor for a function, which deletes a profile photo. - * - *

Returns {@link Ok Ok}

- */ - public DeleteProfilePhoto() { - } - - /** - * Creates a function, which deletes a profile photo. - * - *

Returns {@link Ok Ok}

- * - * @param profilePhotoId Identifier of the profile photo to delete. - */ - public DeleteProfilePhoto(long profilePhotoId) { - this.profilePhotoId = profilePhotoId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1319794625; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes a quick reply shortcut. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteQuickReplyShortcut extends Function { - /** - * Unique identifier of the quick reply shortcut. - */ - public int shortcutId; - - /** - * Default constructor for a function, which deletes a quick reply shortcut. - * - *

Returns {@link Ok Ok}

- */ - public DeleteQuickReplyShortcut() { - } - - /** - * Creates a function, which deletes a quick reply shortcut. - * - *

Returns {@link Ok Ok}

- * - * @param shortcutId Unique identifier of the quick reply shortcut. - */ - public DeleteQuickReplyShortcut(int shortcutId) { - this.shortcutId = shortcutId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -246911978; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes specified quick reply messages. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteQuickReplyShortcutMessages extends Function { - /** - * Unique identifier of the quick reply shortcut to which the messages belong. - */ - public int shortcutId; - /** - * Unique identifiers of the messages. - */ - public long[] messageIds; - - /** - * Default constructor for a function, which deletes specified quick reply messages. - * - *

Returns {@link Ok Ok}

- */ - public DeleteQuickReplyShortcutMessages() { - } - - /** - * Creates a function, which deletes specified quick reply messages. - * - *

Returns {@link Ok Ok}

- * - * @param shortcutId Unique identifier of the quick reply shortcut to which the messages belong. - * @param messageIds Unique identifiers of the messages. - */ - public DeleteQuickReplyShortcutMessages(int shortcutId, long[] messageIds) { - this.shortcutId = shortcutId; - this.messageIds = messageIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -40522947; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes revoked chat invite links. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteRevokedChatInviteLink extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Invite link to revoke. - */ - public String inviteLink; - - /** - * Default constructor for a function, which deletes revoked chat invite links. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. - * - *

Returns {@link Ok Ok}

- */ - public DeleteRevokedChatInviteLink() { - } - - /** - * Creates a function, which deletes revoked chat invite links. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param inviteLink Invite link to revoke. - */ - public DeleteRevokedChatInviteLink(long chatId, String inviteLink) { - this.chatId = chatId; - this.inviteLink = inviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1859711873; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes saved credentials for all payment provider bots. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteSavedCredentials extends Function { - - /** - * Default constructor for a function, which deletes saved credentials for all payment provider bots. - * - *

Returns {@link Ok Ok}

- */ - public DeleteSavedCredentials() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 826300114; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes all messages in a Saved Messages topic. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteSavedMessagesTopicHistory extends Function { - /** - * Identifier of Saved Messages topic which messages will be deleted. - */ - public long savedMessagesTopicId; - - /** - * Default constructor for a function, which deletes all messages in a Saved Messages topic. - * - *

Returns {@link Ok Ok}

- */ - public DeleteSavedMessagesTopicHistory() { - } - - /** - * Creates a function, which deletes all messages in a Saved Messages topic. - * - *

Returns {@link Ok Ok}

- * - * @param savedMessagesTopicId Identifier of Saved Messages topic which messages will be deleted. - */ - public DeleteSavedMessagesTopicHistory(long savedMessagesTopicId) { - this.savedMessagesTopicId = savedMessagesTopicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1776237930; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes all messages between the specified dates in a Saved Messages topic. Messages sent in the last 30 seconds will not be deleted. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteSavedMessagesTopicMessagesByDate extends Function { - /** - * Identifier of Saved Messages topic which messages will be deleted. - */ - public long savedMessagesTopicId; - /** - * The minimum date of the messages to delete. - */ - public int minDate; - /** - * The maximum date of the messages to delete. - */ - public int maxDate; - - /** - * Default constructor for a function, which deletes all messages between the specified dates in a Saved Messages topic. Messages sent in the last 30 seconds will not be deleted. - * - *

Returns {@link Ok Ok}

- */ - public DeleteSavedMessagesTopicMessagesByDate() { - } - - /** - * Creates a function, which deletes all messages between the specified dates in a Saved Messages topic. Messages sent in the last 30 seconds will not be deleted. - * - *

Returns {@link Ok Ok}

- * - * @param savedMessagesTopicId Identifier of Saved Messages topic which messages will be deleted. - * @param minDate The minimum date of the messages to delete. - * @param maxDate The maximum date of the messages to delete. - */ - public DeleteSavedMessagesTopicMessagesByDate(long savedMessagesTopicId, int minDate, int maxDate) { - this.savedMessagesTopicId = savedMessagesTopicId; - this.minDate = minDate; - this.maxDate = maxDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1444389; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes saved order information. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteSavedOrderInfo extends Function { - - /** - * Default constructor for a function, which deletes saved order information. - * - *

Returns {@link Ok Ok}

- */ - public DeleteSavedOrderInfo() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1629058164; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Completely deletes a sticker set. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteStickerSet extends Function { - /** - * Sticker set name. The sticker set must be owned by the current user. - */ - public String name; - - /** - * Default constructor for a function, which completely deletes a sticker set. - * - *

Returns {@link Ok Ok}

- */ - public DeleteStickerSet() { - } - - /** - * Creates a function, which completely deletes a sticker set. - * - *

Returns {@link Ok Ok}

- * - * @param name Sticker set name. The sticker set must be owned by the current user. - */ - public DeleteStickerSet(String name) { - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1577745325; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes a previously posted story. Can be called only if story.canBeDeleted == true. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteStory extends Function { - /** - * Identifier of the chat that posted the story. - */ - public long storyPosterChatId; - /** - * Identifier of the story to delete. - */ - public int storyId; - - /** - * Default constructor for a function, which deletes a previously posted story. Can be called only if story.canBeDeleted == true. - * - *

Returns {@link Ok Ok}

- */ - public DeleteStory() { - } - - /** - * Creates a function, which deletes a previously posted story. Can be called only if story.canBeDeleted == true. - * - *

Returns {@link Ok Ok}

- * - * @param storyPosterChatId Identifier of the chat that posted the story. - * @param storyId Identifier of the story to delete. - */ - public DeleteStory(long storyPosterChatId, int storyId) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2020144472; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Deletes a story album. If the album is owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. - * - *

Returns {@link Ok Ok}

- */ - public static class DeleteStoryAlbum extends Function { - /** - * Identifier of the chat that owns the stories. - */ - public long chatId; - /** - * Identifier of the story album. - */ - public int storyAlbumId; - - /** - * Default constructor for a function, which deletes a story album. If the album is owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. - * - *

Returns {@link Ok Ok}

- */ - public DeleteStoryAlbum() { - } - - /** - * Creates a function, which deletes a story album. If the album is owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat that owns the stories. - * @param storyAlbumId Identifier of the story album. - */ - public DeleteStoryAlbum(long chatId, int storyAlbumId) { - this.chatId = chatId; - this.storyAlbumId = storyAlbumId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -658327628; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Closes the TDLib instance, destroying all local data without a proper logout. The current user session will remain in the list of all active sessions. All local data will be destroyed. After the destruction completes updateAuthorizationState with authorizationStateClosed will be sent. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class Destroy extends Function { - - /** - * Default constructor for a function, which closes the TDLib instance, destroying all local data without a proper logout. The current user session will remain in the list of all active sessions. All local data will be destroyed. After the destruction completes updateAuthorizationState with authorizationStateClosed will be sent. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public Destroy() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 685331274; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Disables all active non-editable usernames of a supergroup or channel, requires owner privileges in the supergroup or channel. - * - *

Returns {@link Ok Ok}

- */ - public static class DisableAllSupergroupUsernames extends Function { - /** - * Identifier of the supergroup or channel. - */ - public long supergroupId; - - /** - * Default constructor for a function, which disables all active non-editable usernames of a supergroup or channel, requires owner privileges in the supergroup or channel. - * - *

Returns {@link Ok Ok}

- */ - public DisableAllSupergroupUsernames() { - } - - /** - * Creates a function, which disables all active non-editable usernames of a supergroup or channel, requires owner privileges in the supergroup or channel. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId Identifier of the supergroup or channel. - */ - public DisableAllSupergroupUsernames(long supergroupId) { - this.supergroupId = supergroupId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 843511216; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Disables the currently enabled proxy. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class DisableProxy extends Function { - - /** - * Default constructor for a function, which disables the currently enabled proxy. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public DisableProxy() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2100095102; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Discards a call. - * - *

Returns {@link Ok Ok}

- */ - public static class DiscardCall extends Function { - /** - * Call identifier. - */ - public int callId; - /** - * Pass true if the user was disconnected. - */ - public boolean isDisconnected; - /** - * If the call was upgraded to a group call, pass invite link to the group call. - */ - public String inviteLink; - /** - * The call duration, in seconds. - */ - public int duration; - /** - * Pass true if the call was a video call. - */ - public boolean isVideo; - /** - * Identifier of the connection used during the call. - */ - public long connectionId; - - /** - * Default constructor for a function, which discards a call. - * - *

Returns {@link Ok Ok}

- */ - public DiscardCall() { - } - - /** - * Creates a function, which discards a call. - * - *

Returns {@link Ok Ok}

- * - * @param callId Call identifier. - * @param isDisconnected Pass true if the user was disconnected. - * @param inviteLink If the call was upgraded to a group call, pass invite link to the group call. - * @param duration The call duration, in seconds. - * @param isVideo Pass true if the call was a video call. - * @param connectionId Identifier of the connection used during the call. - */ - public DiscardCall(int callId, boolean isDisconnected, String inviteLink, int duration, boolean isVideo, long connectionId) { - this.callId = callId; - this.isDisconnected = isDisconnected; - this.inviteLink = inviteLink; - this.duration = duration; - this.isVideo = isVideo; - this.connectionId = connectionId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1545983346; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Disconnects an affiliate program from the given affiliate and immediately deactivates its referral link. Returns updated information about the disconnected affiliate program. - * - *

Returns {@link ConnectedAffiliateProgram ConnectedAffiliateProgram}

- */ - public static class DisconnectAffiliateProgram extends Function { - /** - * The affiliate to which the affiliate program is connected. - */ - public AffiliateType affiliate; - /** - * The referral link of the affiliate program. - */ - public String url; - - /** - * Default constructor for a function, which disconnects an affiliate program from the given affiliate and immediately deactivates its referral link. Returns updated information about the disconnected affiliate program. - * - *

Returns {@link ConnectedAffiliateProgram ConnectedAffiliateProgram}

- */ - public DisconnectAffiliateProgram() { - } - - /** - * Creates a function, which disconnects an affiliate program from the given affiliate and immediately deactivates its referral link. Returns updated information about the disconnected affiliate program. - * - *

Returns {@link ConnectedAffiliateProgram ConnectedAffiliateProgram}

- * - * @param affiliate The affiliate to which the affiliate program is connected. - * @param url The referral link of the affiliate program. - */ - public DisconnectAffiliateProgram(AffiliateType affiliate, String url) { - this.affiliate = affiliate; - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -105831172; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Disconnects all websites from the current user's Telegram account. - * - *

Returns {@link Ok Ok}

- */ - public static class DisconnectAllWebsites extends Function { - - /** - * Default constructor for a function, which disconnects all websites from the current user's Telegram account. - * - *

Returns {@link Ok Ok}

- */ - public DisconnectAllWebsites() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1082985981; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Disconnects website from the current user's Telegram account. - * - *

Returns {@link Ok Ok}

- */ - public static class DisconnectWebsite extends Function { - /** - * Website identifier. - */ - public long websiteId; - - /** - * Default constructor for a function, which disconnects website from the current user's Telegram account. - * - *

Returns {@link Ok Ok}

- */ - public DisconnectWebsite() { - } - - /** - * Creates a function, which disconnects website from the current user's Telegram account. - * - *

Returns {@link Ok Ok}

- * - * @param websiteId Website identifier. - */ - public DisconnectWebsite(long websiteId) { - this.websiteId = websiteId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -778767395; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Downloads a file from the cloud. Download progress and completion of the download will be notified through updateFile updates. - * - *

Returns {@link File File}

- */ - public static class DownloadFile extends Function { - /** - * Identifier of the file to download. - */ - public int fileId; - /** - * Priority of the download (1-32). The higher the priority, the earlier the file will be downloaded. If the priorities of two files are equal, then the last one for which downloadFile/addFileToDownloads was called will be downloaded first. - */ - public int priority; - /** - * The starting position from which the file needs to be downloaded. - */ - public long offset; - /** - * Number of bytes which need to be downloaded starting from the "offset" position before the download will automatically be canceled; use 0 to download without a limit. - */ - public long limit; - /** - * Pass true to return response only after the file download has succeeded, has failed, has been canceled, or a new downloadFile request with different offset/limit parameters was sent; pass false to return file state immediately, just after the download has been started. - */ - public boolean synchronous; - - /** - * Default constructor for a function, which downloads a file from the cloud. Download progress and completion of the download will be notified through updateFile updates. - * - *

Returns {@link File File}

- */ - public DownloadFile() { - } - - /** - * Creates a function, which downloads a file from the cloud. Download progress and completion of the download will be notified through updateFile updates. - * - *

Returns {@link File File}

- * - * @param fileId Identifier of the file to download. - * @param priority Priority of the download (1-32). The higher the priority, the earlier the file will be downloaded. If the priorities of two files are equal, then the last one for which downloadFile/addFileToDownloads was called will be downloaded first. - * @param offset The starting position from which the file needs to be downloaded. - * @param limit Number of bytes which need to be downloaded starting from the "offset" position before the download will automatically be canceled; use 0 to download without a limit. - * @param synchronous Pass true to return response only after the file download has succeeded, has failed, has been canceled, or a new downloadFile request with different offset/limit parameters was sent; pass false to return file state immediately, just after the download has been started. - */ - public DownloadFile(int fileId, int priority, long offset, long limit, boolean synchronous) { - this.fileId = fileId; - this.priority = priority; - this.offset = offset; - this.limit = limit; - this.synchronous = synchronous; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1059402292; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Drops original details for an upgraded gift. - * - *

Returns {@link Ok Ok}

- */ - public static class DropGiftOriginalDetails extends Function { - /** - * Identifier of the gift. - */ - public String receivedGiftId; - /** - * The Telegram Star amount required to pay for the operation. - */ - public long starCount; - - /** - * Default constructor for a function, which drops original details for an upgraded gift. - * - *

Returns {@link Ok Ok}

- */ - public DropGiftOriginalDetails() { - } - - /** - * Creates a function, which drops original details for an upgraded gift. - * - *

Returns {@link Ok Ok}

- * - * @param receivedGiftId Identifier of the gift. - * @param starCount The Telegram Star amount required to pay for the operation. - */ - public DropGiftOriginalDetails(String receivedGiftId, long starCount) { - this.receivedGiftId = receivedGiftId; - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1394445843; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Replaces media preview in the list of media previews of a bot. Returns the new preview after edit is completed server-side. - * - *

Returns {@link BotMediaPreview BotMediaPreview}

- */ - public static class EditBotMediaPreview extends Function { - /** - * Identifier of the target bot. The bot must be owned and must have the main Web App. - */ - public long botUserId; - /** - * Language code of the media preview to edit. - */ - public String languageCode; - /** - * File identifier of the media to replace. - */ - public int fileId; - /** - * Content of the new preview. - */ - public InputStoryContent content; - - /** - * Default constructor for a function, which replaces media preview in the list of media previews of a bot. Returns the new preview after edit is completed server-side. - * - *

Returns {@link BotMediaPreview BotMediaPreview}

- */ - public EditBotMediaPreview() { - } - - /** - * Creates a function, which replaces media preview in the list of media previews of a bot. Returns the new preview after edit is completed server-side. - * - *

Returns {@link BotMediaPreview BotMediaPreview}

- * - * @param botUserId Identifier of the target bot. The bot must be owned and must have the main Web App. - * @param languageCode Language code of the media preview to edit. - * @param fileId File identifier of the media to replace. - * @param content Content of the new preview. - */ - public EditBotMediaPreview(long botUserId, String languageCode, int fileId, InputStoryContent content) { - this.botUserId = botUserId; - this.languageCode = languageCode; - this.fileId = fileId; - this.content = content; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2037031582; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits a business chat link of the current account. Requires Telegram Business subscription. Returns the edited link. - * - *

Returns {@link BusinessChatLink BusinessChatLink}

- */ - public static class EditBusinessChatLink extends Function { - /** - * The link to edit. - */ - public String link; - /** - * New description of the link. - */ - public InputBusinessChatLink linkInfo; - - /** - * Default constructor for a function, which edits a business chat link of the current account. Requires Telegram Business subscription. Returns the edited link. - * - *

Returns {@link BusinessChatLink BusinessChatLink}

- */ - public EditBusinessChatLink() { - } - - /** - * Creates a function, which edits a business chat link of the current account. Requires Telegram Business subscription. Returns the edited link. - * - *

Returns {@link BusinessChatLink BusinessChatLink}

- * - * @param link The link to edit. - * @param linkInfo New description of the link. - */ - public EditBusinessChatLink(String link, InputBusinessChatLink linkInfo) { - this.link = link; - this.linkInfo = linkInfo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1594947110; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the caption of a message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- */ - public static class EditBusinessMessageCaption extends Function { - /** - * Unique identifier of business connection on behalf of which the message was sent. - */ - public String businessConnectionId; - /** - * The chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * The new message reply markup; pass null if none. - */ - public ReplyMarkup replyMarkup; - /** - * New message content caption; pass null to remove caption; 0-getOption("message_caption_length_max") characters. - */ - public FormattedText caption; - /** - * Pass true to show the caption above the media; otherwise, the caption will be shown below the media. May be true only for animation, photo, and video messages. - */ - public boolean showCaptionAboveMedia; - - /** - * Default constructor for a function, which edits the caption of a message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- */ - public EditBusinessMessageCaption() { - } - - /** - * Creates a function, which edits the caption of a message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- * - * @param businessConnectionId Unique identifier of business connection on behalf of which the message was sent. - * @param chatId The chat the message belongs to. - * @param messageId Identifier of the message. - * @param replyMarkup The new message reply markup; pass null if none. - * @param caption New message content caption; pass null to remove caption; 0-getOption("message_caption_length_max") characters. - * @param showCaptionAboveMedia Pass true to show the caption above the media; otherwise, the caption will be shown below the media. May be true only for animation, photo, and video messages. - */ - public EditBusinessMessageCaption(String businessConnectionId, long chatId, long messageId, ReplyMarkup replyMarkup, FormattedText caption, boolean showCaptionAboveMedia) { - this.businessConnectionId = businessConnectionId; - this.chatId = chatId; - this.messageId = messageId; - this.replyMarkup = replyMarkup; - this.caption = caption; - this.showCaptionAboveMedia = showCaptionAboveMedia; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1071562045; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the content of a checklist in a message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- */ - public static class EditBusinessMessageChecklist extends Function { - /** - * Unique identifier of business connection on behalf of which the message was sent. - */ - public String businessConnectionId; - /** - * The chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * The new message reply markup; pass null if none. - */ - public ReplyMarkup replyMarkup; - /** - * The new checklist. If some tasks were completed, this information will be kept. - */ - public InputChecklist checklist; - - /** - * Default constructor for a function, which edits the content of a checklist in a message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- */ - public EditBusinessMessageChecklist() { - } - - /** - * Creates a function, which edits the content of a checklist in a message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- * - * @param businessConnectionId Unique identifier of business connection on behalf of which the message was sent. - * @param chatId The chat the message belongs to. - * @param messageId Identifier of the message. - * @param replyMarkup The new message reply markup; pass null if none. - * @param checklist The new checklist. If some tasks were completed, this information will be kept. - */ - public EditBusinessMessageChecklist(String businessConnectionId, long chatId, long messageId, ReplyMarkup replyMarkup, InputChecklist checklist) { - this.businessConnectionId = businessConnectionId; - this.chatId = chatId; - this.messageId = messageId; - this.replyMarkup = replyMarkup; - this.checklist = checklist; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -445013904; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the content of a live location in a message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- */ - public static class EditBusinessMessageLiveLocation extends Function { - /** - * Unique identifier of business connection on behalf of which the message was sent. - */ - public String businessConnectionId; - /** - * The chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * The new message reply markup; pass null if none. - */ - public ReplyMarkup replyMarkup; - /** - * New location content of the message; pass null to stop sharing the live location. - */ - public Location location; - /** - * New time relative to the message send date, for which the location can be updated, in seconds. If 0x7FFFFFFF specified, then the location can be updated forever. Otherwise, must not exceed the current livePeriod by more than a day, and the live location expiration date must remain in the next 90 days. Pass 0 to keep the current livePeriod. - */ - public int livePeriod; - /** - * The new direction in which the location moves, in degrees; 1-360. Pass 0 if unknown. - */ - public int heading; - /** - * The new maximum distance for proximity alerts, in meters (0-100000). Pass 0 if the notification is disabled. - */ - public int proximityAlertRadius; - - /** - * Default constructor for a function, which edits the content of a live location in a message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- */ - public EditBusinessMessageLiveLocation() { - } - - /** - * Creates a function, which edits the content of a live location in a message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- * - * @param businessConnectionId Unique identifier of business connection on behalf of which the message was sent. - * @param chatId The chat the message belongs to. - * @param messageId Identifier of the message. - * @param replyMarkup The new message reply markup; pass null if none. - * @param location New location content of the message; pass null to stop sharing the live location. - * @param livePeriod New time relative to the message send date, for which the location can be updated, in seconds. If 0x7FFFFFFF specified, then the location can be updated forever. Otherwise, must not exceed the current livePeriod by more than a day, and the live location expiration date must remain in the next 90 days. Pass 0 to keep the current livePeriod. - * @param heading The new direction in which the location moves, in degrees; 1-360. Pass 0 if unknown. - * @param proximityAlertRadius The new maximum distance for proximity alerts, in meters (0-100000). Pass 0 if the notification is disabled. - */ - public EditBusinessMessageLiveLocation(String businessConnectionId, long chatId, long messageId, ReplyMarkup replyMarkup, Location location, int livePeriod, int heading, int proximityAlertRadius) { - this.businessConnectionId = businessConnectionId; - this.chatId = chatId; - this.messageId = messageId; - this.replyMarkup = replyMarkup; - this.location = location; - this.livePeriod = livePeriod; - this.heading = heading; - this.proximityAlertRadius = proximityAlertRadius; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 494972447; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the media content of a message with a text, an animation, an audio, a document, a photo or a video in a message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- */ - public static class EditBusinessMessageMedia extends Function { - /** - * Unique identifier of business connection on behalf of which the message was sent. - */ - public String businessConnectionId; - /** - * The chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * The new message reply markup; pass null if none; for bots only. - */ - public ReplyMarkup replyMarkup; - /** - * New content of the message. Must be one of the following types: inputMessageAnimation, inputMessageAudio, inputMessageDocument, inputMessagePhoto or inputMessageVideo. - */ - public InputMessageContent inputMessageContent; - - /** - * Default constructor for a function, which edits the media content of a message with a text, an animation, an audio, a document, a photo or a video in a message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- */ - public EditBusinessMessageMedia() { - } - - /** - * Creates a function, which edits the media content of a message with a text, an animation, an audio, a document, a photo or a video in a message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- * - * @param businessConnectionId Unique identifier of business connection on behalf of which the message was sent. - * @param chatId The chat the message belongs to. - * @param messageId Identifier of the message. - * @param replyMarkup The new message reply markup; pass null if none; for bots only. - * @param inputMessageContent New content of the message. Must be one of the following types: inputMessageAnimation, inputMessageAudio, inputMessageDocument, inputMessagePhoto or inputMessageVideo. - */ - public EditBusinessMessageMedia(String businessConnectionId, long chatId, long messageId, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.businessConnectionId = businessConnectionId; - this.chatId = chatId; - this.messageId = messageId; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -60733576; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the reply markup of a message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- */ - public static class EditBusinessMessageReplyMarkup extends Function { - /** - * Unique identifier of business connection on behalf of which the message was sent. - */ - public String businessConnectionId; - /** - * The chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * The new message reply markup; pass null if none. - */ - public ReplyMarkup replyMarkup; - - /** - * Default constructor for a function, which edits the reply markup of a message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- */ - public EditBusinessMessageReplyMarkup() { - } - - /** - * Creates a function, which edits the reply markup of a message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- * - * @param businessConnectionId Unique identifier of business connection on behalf of which the message was sent. - * @param chatId The chat the message belongs to. - * @param messageId Identifier of the message. - * @param replyMarkup The new message reply markup; pass null if none. - */ - public EditBusinessMessageReplyMarkup(String businessConnectionId, long chatId, long messageId, ReplyMarkup replyMarkup) { - this.businessConnectionId = businessConnectionId; - this.chatId = chatId; - this.messageId = messageId; - this.replyMarkup = replyMarkup; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 701787159; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the text of a text or game message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- */ - public static class EditBusinessMessageText extends Function { - /** - * Unique identifier of business connection on behalf of which the message was sent. - */ - public String businessConnectionId; - /** - * The chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * The new message reply markup; pass null if none. - */ - public ReplyMarkup replyMarkup; - /** - * New text content of the message. Must be of type inputMessageText. - */ - public InputMessageContent inputMessageContent; - - /** - * Default constructor for a function, which edits the text of a text or game message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- */ - public EditBusinessMessageText() { - } - - /** - * Creates a function, which edits the text of a text or game message sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- * - * @param businessConnectionId Unique identifier of business connection on behalf of which the message was sent. - * @param chatId The chat the message belongs to. - * @param messageId Identifier of the message. - * @param replyMarkup The new message reply markup; pass null if none. - * @param inputMessageContent New text content of the message. Must be of type inputMessageText. - */ - public EditBusinessMessageText(String businessConnectionId, long chatId, long messageId, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.businessConnectionId = businessConnectionId; - this.chatId = chatId; - this.messageId = messageId; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1149169252; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes a story posted by the bot on behalf of a business account; for bots only. - * - *

Returns {@link Story Story}

- */ - public static class EditBusinessStory extends Function { - /** - * Identifier of the chat that posted the story. - */ - public long storyPosterChatId; - /** - * Identifier of the story to edit. - */ - public int storyId; - /** - * New content of the story. - */ - public InputStoryContent content; - /** - * New clickable rectangle areas to be shown on the story media. - */ - public InputStoryAreas areas; - /** - * New story caption. - */ - public FormattedText caption; - /** - * The new privacy settings for the story. - */ - public StoryPrivacySettings privacySettings; - - /** - * Default constructor for a function, which changes a story posted by the bot on behalf of a business account; for bots only. - * - *

Returns {@link Story Story}

- */ - public EditBusinessStory() { - } - - /** - * Creates a function, which changes a story posted by the bot on behalf of a business account; for bots only. - * - *

Returns {@link Story Story}

- * - * @param storyPosterChatId Identifier of the chat that posted the story. - * @param storyId Identifier of the story to edit. - * @param content New content of the story. - * @param areas New clickable rectangle areas to be shown on the story media. - * @param caption New story caption. - * @param privacySettings The new privacy settings for the story. - */ - public EditBusinessStory(long storyPosterChatId, int storyId, InputStoryContent content, InputStoryAreas areas, FormattedText caption, StoryPrivacySettings privacySettings) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - this.content = content; - this.areas = areas; - this.caption = caption; - this.privacySettings = privacySettings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 472538940; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits existing chat folder. Returns information about the edited chat folder. - * - *

Returns {@link ChatFolderInfo ChatFolderInfo}

- */ - public static class EditChatFolder extends Function { - /** - * Chat folder identifier. - */ - public int chatFolderId; - /** - * The edited chat folder. - */ - public ChatFolder folder; - - /** - * Default constructor for a function, which edits existing chat folder. Returns information about the edited chat folder. - * - *

Returns {@link ChatFolderInfo ChatFolderInfo}

- */ - public EditChatFolder() { - } - - /** - * Creates a function, which edits existing chat folder. Returns information about the edited chat folder. - * - *

Returns {@link ChatFolderInfo ChatFolderInfo}

- * - * @param chatFolderId Chat folder identifier. - * @param folder The edited chat folder. - */ - public EditChatFolder(int chatFolderId, ChatFolder folder) { - this.chatFolderId = chatFolderId; - this.folder = folder; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 53672754; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits an invite link for a chat folder. - * - *

Returns {@link ChatFolderInviteLink ChatFolderInviteLink}

- */ - public static class EditChatFolderInviteLink extends Function { - /** - * Chat folder identifier. - */ - public int chatFolderId; - /** - * Invite link to be edited. - */ - public String inviteLink; - /** - * New name of the link; 0-32 characters. - */ - public String name; - /** - * New identifiers of chats to be accessible by the invite link. Use getChatsForChatFolderInviteLink to get suitable chats. Basic groups will be automatically converted to supergroups before link editing. - */ - public long[] chatIds; - - /** - * Default constructor for a function, which edits an invite link for a chat folder. - * - *

Returns {@link ChatFolderInviteLink ChatFolderInviteLink}

- */ - public EditChatFolderInviteLink() { - } - - /** - * Creates a function, which edits an invite link for a chat folder. - * - *

Returns {@link ChatFolderInviteLink ChatFolderInviteLink}

- * - * @param chatFolderId Chat folder identifier. - * @param inviteLink Invite link to be edited. - * @param name New name of the link; 0-32 characters. - * @param chatIds New identifiers of chats to be accessible by the invite link. Use getChatsForChatFolderInviteLink to get suitable chats. Basic groups will be automatically converted to supergroups before link editing. - */ - public EditChatFolderInviteLink(int chatFolderId, String inviteLink, String name, long[] chatIds) { - this.chatFolderId = chatFolderId; - this.inviteLink = inviteLink; - this.name = name; - this.chatIds = chatIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2141872095; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits a non-primary invite link for a chat. Available for basic groups, supergroups, and channels. If the link creates a subscription, then expirationDate, memberLimit and createsJoinRequest must not be used. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- */ - public static class EditChatInviteLink extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Invite link to be edited. - */ - public String inviteLink; - /** - * Invite link name; 0-32 characters. - */ - public String name; - /** - * Point in time (Unix timestamp) when the link will expire; pass 0 if never. - */ - public int expirationDate; - /** - * The maximum number of chat members that can join the chat via the link simultaneously; 0-99999; pass 0 if not limited. - */ - public int memberLimit; - /** - * Pass true if users joining the chat via the link need to be approved by chat administrators. In this case, memberLimit must be 0. - */ - public boolean createsJoinRequest; - - /** - * Default constructor for a function, which edits a non-primary invite link for a chat. Available for basic groups, supergroups, and channels. If the link creates a subscription, then expirationDate, memberLimit and createsJoinRequest must not be used. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- */ - public EditChatInviteLink() { - } - - /** - * Creates a function, which edits a non-primary invite link for a chat. Available for basic groups, supergroups, and channels. If the link creates a subscription, then expirationDate, memberLimit and createsJoinRequest must not be used. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- * - * @param chatId Chat identifier. - * @param inviteLink Invite link to be edited. - * @param name Invite link name; 0-32 characters. - * @param expirationDate Point in time (Unix timestamp) when the link will expire; pass 0 if never. - * @param memberLimit The maximum number of chat members that can join the chat via the link simultaneously; 0-99999; pass 0 if not limited. - * @param createsJoinRequest Pass true if users joining the chat via the link need to be approved by chat administrators. In this case, memberLimit must be 0. - */ - public EditChatInviteLink(long chatId, String inviteLink, String name, int expirationDate, int memberLimit, boolean createsJoinRequest) { - this.chatId = chatId; - this.inviteLink = inviteLink; - this.name = name; - this.expirationDate = expirationDate; - this.memberLimit = memberLimit; - this.createsJoinRequest = createsJoinRequest; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1320303996; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits a subscription invite link for a channel chat. Requires canInviteUsers right in the chat for own links and owner privileges for other links. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- */ - public static class EditChatSubscriptionInviteLink extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Invite link to be edited. - */ - public String inviteLink; - /** - * Invite link name; 0-32 characters. - */ - public String name; - - /** - * Default constructor for a function, which edits a subscription invite link for a channel chat. Requires canInviteUsers right in the chat for own links and owner privileges for other links. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- */ - public EditChatSubscriptionInviteLink() { - } - - /** - * Creates a function, which edits a subscription invite link for a channel chat. Requires canInviteUsers right in the chat for own links and owner privileges for other links. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- * - * @param chatId Chat identifier. - * @param inviteLink Invite link to be edited. - * @param name Invite link name; 0-32 characters. - */ - public EditChatSubscriptionInviteLink(long chatId, String inviteLink, String name) { - this.chatId = chatId; - this.inviteLink = inviteLink; - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -951826989; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits information about a custom local language pack in the current localization target. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class EditCustomLanguagePackInfo extends Function { - /** - * New information about the custom local language pack. - */ - public LanguagePackInfo info; - - /** - * Default constructor for a function, which edits information about a custom local language pack in the current localization target. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public EditCustomLanguagePackInfo() { - } - - /** - * Creates a function, which edits information about a custom local language pack in the current localization target. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- * - * @param info New information about the custom local language pack. - */ - public EditCustomLanguagePackInfo(LanguagePackInfo info) { - this.info = info; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1320751257; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits title and icon of a topic in a forum supergroup chat or a chat with a bot with topics; for supergroup chats requires canManageTopics administrator right unless the user is creator of the topic. - * - *

Returns {@link Ok Ok}

- */ - public static class EditForumTopic extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * Forum topic identifier. - */ - public int forumTopicId; - /** - * New name of the topic; 0-128 characters. If empty, the previous topic name is kept. - */ - public String name; - /** - * Pass true to edit the icon of the topic. Icon of the General topic can't be edited. - */ - public boolean editIconCustomEmoji; - /** - * Identifier of the new custom emoji for topic icon; pass 0 to remove the custom emoji. Ignored if editIconCustomEmoji is false. Telegram Premium users can use any custom emoji, other users can use only a custom emoji returned by getForumTopicDefaultIcons. - */ - public long iconCustomEmojiId; - - /** - * Default constructor for a function, which edits title and icon of a topic in a forum supergroup chat or a chat with a bot with topics; for supergroup chats requires canManageTopics administrator right unless the user is creator of the topic. - * - *

Returns {@link Ok Ok}

- */ - public EditForumTopic() { - } - - /** - * Creates a function, which edits title and icon of a topic in a forum supergroup chat or a chat with a bot with topics; for supergroup chats requires canManageTopics administrator right unless the user is creator of the topic. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat. - * @param forumTopicId Forum topic identifier. - * @param name New name of the topic; 0-128 characters. If empty, the previous topic name is kept. - * @param editIconCustomEmoji Pass true to edit the icon of the topic. Icon of the General topic can't be edited. - * @param iconCustomEmojiId Identifier of the new custom emoji for topic icon; pass 0 to remove the custom emoji. Ignored if editIconCustomEmoji is false. Telegram Premium users can use any custom emoji, other users can use only a custom emoji returned by getForumTopicDefaultIcons. - */ - public EditForumTopic(long chatId, int forumTopicId, String name, boolean editIconCustomEmoji, long iconCustomEmojiId) { - this.chatId = chatId; - this.forumTopicId = forumTopicId; - this.name = name; - this.editIconCustomEmoji = editIconCustomEmoji; - this.iconCustomEmojiId = iconCustomEmojiId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1112389547; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the caption of an inline message sent via a bot; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class EditInlineMessageCaption extends Function { - /** - * Inline message identifier. - */ - public String inlineMessageId; - /** - * The new message reply markup; pass null if none. - */ - public ReplyMarkup replyMarkup; - /** - * New message content caption; pass null to remove caption; 0-getOption("message_caption_length_max") characters. - */ - public FormattedText caption; - /** - * Pass true to show the caption above the media; otherwise, the caption will be shown below the media. May be true only for animation, photo, and video messages. - */ - public boolean showCaptionAboveMedia; - - /** - * Default constructor for a function, which edits the caption of an inline message sent via a bot; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public EditInlineMessageCaption() { - } - - /** - * Creates a function, which edits the caption of an inline message sent via a bot; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param inlineMessageId Inline message identifier. - * @param replyMarkup The new message reply markup; pass null if none. - * @param caption New message content caption; pass null to remove caption; 0-getOption("message_caption_length_max") characters. - * @param showCaptionAboveMedia Pass true to show the caption above the media; otherwise, the caption will be shown below the media. May be true only for animation, photo, and video messages. - */ - public EditInlineMessageCaption(String inlineMessageId, ReplyMarkup replyMarkup, FormattedText caption, boolean showCaptionAboveMedia) { - this.inlineMessageId = inlineMessageId; - this.replyMarkup = replyMarkup; - this.caption = caption; - this.showCaptionAboveMedia = showCaptionAboveMedia; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1409762552; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the content of a live location in an inline message sent via a bot; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class EditInlineMessageLiveLocation extends Function { - /** - * Inline message identifier. - */ - public String inlineMessageId; - /** - * The new message reply markup; pass null if none. - */ - public ReplyMarkup replyMarkup; - /** - * New location content of the message; pass null to stop sharing the live location. - */ - public Location location; - /** - * New time relative to the message send date, for which the location can be updated, in seconds. If 0x7FFFFFFF specified, then the location can be updated forever. Otherwise, must not exceed the current livePeriod by more than a day, and the live location expiration date must remain in the next 90 days. Pass 0 to keep the current livePeriod. - */ - public int livePeriod; - /** - * The new direction in which the location moves, in degrees; 1-360. Pass 0 if unknown. - */ - public int heading; - /** - * The new maximum distance for proximity alerts, in meters (0-100000). Pass 0 if the notification is disabled. - */ - public int proximityAlertRadius; - - /** - * Default constructor for a function, which edits the content of a live location in an inline message sent via a bot; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public EditInlineMessageLiveLocation() { - } - - /** - * Creates a function, which edits the content of a live location in an inline message sent via a bot; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param inlineMessageId Inline message identifier. - * @param replyMarkup The new message reply markup; pass null if none. - * @param location New location content of the message; pass null to stop sharing the live location. - * @param livePeriod New time relative to the message send date, for which the location can be updated, in seconds. If 0x7FFFFFFF specified, then the location can be updated forever. Otherwise, must not exceed the current livePeriod by more than a day, and the live location expiration date must remain in the next 90 days. Pass 0 to keep the current livePeriod. - * @param heading The new direction in which the location moves, in degrees; 1-360. Pass 0 if unknown. - * @param proximityAlertRadius The new maximum distance for proximity alerts, in meters (0-100000). Pass 0 if the notification is disabled. - */ - public EditInlineMessageLiveLocation(String inlineMessageId, ReplyMarkup replyMarkup, Location location, int livePeriod, int heading, int proximityAlertRadius) { - this.inlineMessageId = inlineMessageId; - this.replyMarkup = replyMarkup; - this.location = location; - this.livePeriod = livePeriod; - this.heading = heading; - this.proximityAlertRadius = proximityAlertRadius; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2134352044; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the media content of a message with a text, an animation, an audio, a document, a photo or a video in an inline message sent via a bot; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class EditInlineMessageMedia extends Function { - /** - * Inline message identifier. - */ - public String inlineMessageId; - /** - * The new message reply markup; pass null if none; for bots only. - */ - public ReplyMarkup replyMarkup; - /** - * New content of the message. Must be one of the following types: inputMessageAnimation, inputMessageAudio, inputMessageDocument, inputMessagePhoto or inputMessageVideo. - */ - public InputMessageContent inputMessageContent; - - /** - * Default constructor for a function, which edits the media content of a message with a text, an animation, an audio, a document, a photo or a video in an inline message sent via a bot; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public EditInlineMessageMedia() { - } - - /** - * Creates a function, which edits the media content of a message with a text, an animation, an audio, a document, a photo or a video in an inline message sent via a bot; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param inlineMessageId Inline message identifier. - * @param replyMarkup The new message reply markup; pass null if none; for bots only. - * @param inputMessageContent New content of the message. Must be one of the following types: inputMessageAnimation, inputMessageAudio, inputMessageDocument, inputMessagePhoto or inputMessageVideo. - */ - public EditInlineMessageMedia(String inlineMessageId, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.inlineMessageId = inlineMessageId; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 23553921; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the reply markup of an inline message sent via a bot; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class EditInlineMessageReplyMarkup extends Function { - /** - * Inline message identifier. - */ - public String inlineMessageId; - /** - * The new message reply markup; pass null if none. - */ - public ReplyMarkup replyMarkup; - - /** - * Default constructor for a function, which edits the reply markup of an inline message sent via a bot; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public EditInlineMessageReplyMarkup() { - } - - /** - * Creates a function, which edits the reply markup of an inline message sent via a bot; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param inlineMessageId Inline message identifier. - * @param replyMarkup The new message reply markup; pass null if none. - */ - public EditInlineMessageReplyMarkup(String inlineMessageId, ReplyMarkup replyMarkup) { - this.inlineMessageId = inlineMessageId; - this.replyMarkup = replyMarkup; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -67565858; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the text of an inline text or game message sent via a bot; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class EditInlineMessageText extends Function { - /** - * Inline message identifier. - */ - public String inlineMessageId; - /** - * The new message reply markup; pass null if none. - */ - public ReplyMarkup replyMarkup; - /** - * New text content of the message. Must be of type inputMessageText. - */ - public InputMessageContent inputMessageContent; - - /** - * Default constructor for a function, which edits the text of an inline text or game message sent via a bot; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public EditInlineMessageText() { - } - - /** - * Creates a function, which edits the text of an inline text or game message sent via a bot; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param inlineMessageId Inline message identifier. - * @param replyMarkup The new message reply markup; pass null if none. - * @param inputMessageContent New text content of the message. Must be of type inputMessageText. - */ - public EditInlineMessageText(String inlineMessageId, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.inlineMessageId = inlineMessageId; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -855457307; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the message content caption. Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- */ - public static class EditMessageCaption extends Function { - /** - * The chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message. Use messageProperties.canBeEdited to check whether the message can be edited. - */ - public long messageId; - /** - * The new message reply markup; pass null if none; for bots only. - */ - public ReplyMarkup replyMarkup; - /** - * New message content caption; 0-getOption("message_caption_length_max") characters; pass null to remove caption. - */ - public FormattedText caption; - /** - * Pass true to show the caption above the media; otherwise, the caption will be shown below the media. May be true only for animation, photo, and video messages. - */ - public boolean showCaptionAboveMedia; - - /** - * Default constructor for a function, which edits the message content caption. Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- */ - public EditMessageCaption() { - } - - /** - * Creates a function, which edits the message content caption. Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- * - * @param chatId The chat the message belongs to. - * @param messageId Identifier of the message. Use messageProperties.canBeEdited to check whether the message can be edited. - * @param replyMarkup The new message reply markup; pass null if none; for bots only. - * @param caption New message content caption; 0-getOption("message_caption_length_max") characters; pass null to remove caption. - * @param showCaptionAboveMedia Pass true to show the caption above the media; otherwise, the caption will be shown below the media. May be true only for animation, photo, and video messages. - */ - public EditMessageCaption(long chatId, long messageId, ReplyMarkup replyMarkup, FormattedText caption, boolean showCaptionAboveMedia) { - this.chatId = chatId; - this.messageId = messageId; - this.replyMarkup = replyMarkup; - this.caption = caption; - this.showCaptionAboveMedia = showCaptionAboveMedia; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2020117951; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the message content of a checklist. Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- */ - public static class EditMessageChecklist extends Function { - /** - * The chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message. Use messageProperties.canBeEdited to check whether the message can be edited. - */ - public long messageId; - /** - * The new message reply markup; pass null if none; for bots only. - */ - public ReplyMarkup replyMarkup; - /** - * The new checklist. If some tasks were completed, this information will be kept. - */ - public InputChecklist checklist; - - /** - * Default constructor for a function, which edits the message content of a checklist. Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- */ - public EditMessageChecklist() { - } - - /** - * Creates a function, which edits the message content of a checklist. Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- * - * @param chatId The chat the message belongs to. - * @param messageId Identifier of the message. Use messageProperties.canBeEdited to check whether the message can be edited. - * @param replyMarkup The new message reply markup; pass null if none; for bots only. - * @param checklist The new checklist. If some tasks were completed, this information will be kept. - */ - public EditMessageChecklist(long chatId, long messageId, ReplyMarkup replyMarkup, InputChecklist checklist) { - this.chatId = chatId; - this.messageId = messageId; - this.replyMarkup = replyMarkup; - this.checklist = checklist; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1497856700; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the message content of a live location. Messages can be edited for a limited period of time specified in the live location. Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- */ - public static class EditMessageLiveLocation extends Function { - /** - * The chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message. Use messageProperties.canBeEdited to check whether the message can be edited. - */ - public long messageId; - /** - * The new message reply markup; pass null if none; for bots only. - */ - public ReplyMarkup replyMarkup; - /** - * New location content of the message; pass null to stop sharing the live location. - */ - public Location location; - /** - * New time relative to the message send date, for which the location can be updated, in seconds. If 0x7FFFFFFF specified, then the location can be updated forever. Otherwise, must not exceed the current livePeriod by more than a day, and the live location expiration date must remain in the next 90 days. Pass 0 to keep the current livePeriod. - */ - public int livePeriod; - /** - * The new direction in which the location moves, in degrees; 1-360. Pass 0 if unknown. - */ - public int heading; - /** - * The new maximum distance for proximity alerts, in meters (0-100000). Pass 0 if the notification is disabled. - */ - public int proximityAlertRadius; - - /** - * Default constructor for a function, which edits the message content of a live location. Messages can be edited for a limited period of time specified in the live location. Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- */ - public EditMessageLiveLocation() { - } - - /** - * Creates a function, which edits the message content of a live location. Messages can be edited for a limited period of time specified in the live location. Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- * - * @param chatId The chat the message belongs to. - * @param messageId Identifier of the message. Use messageProperties.canBeEdited to check whether the message can be edited. - * @param replyMarkup The new message reply markup; pass null if none; for bots only. - * @param location New location content of the message; pass null to stop sharing the live location. - * @param livePeriod New time relative to the message send date, for which the location can be updated, in seconds. If 0x7FFFFFFF specified, then the location can be updated forever. Otherwise, must not exceed the current livePeriod by more than a day, and the live location expiration date must remain in the next 90 days. Pass 0 to keep the current livePeriod. - * @param heading The new direction in which the location moves, in degrees; 1-360. Pass 0 if unknown. - * @param proximityAlertRadius The new maximum distance for proximity alerts, in meters (0-100000). Pass 0 if the notification is disabled. - */ - public EditMessageLiveLocation(long chatId, long messageId, ReplyMarkup replyMarkup, Location location, int livePeriod, int heading, int proximityAlertRadius) { - this.chatId = chatId; - this.messageId = messageId; - this.replyMarkup = replyMarkup; - this.location = location; - this.livePeriod = livePeriod; - this.heading = heading; - this.proximityAlertRadius = proximityAlertRadius; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1890511980; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the media content of a message, including message caption. If only the caption needs to be edited, use editMessageCaption instead. The type of message content in an album can't be changed with exception of replacing a photo with a video or vice versa. Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- */ - public static class EditMessageMedia extends Function { - /** - * The chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message. Use messageProperties.canEditMedia to check whether the message can be edited. - */ - public long messageId; - /** - * The new message reply markup; pass null if none; for bots only. - */ - public ReplyMarkup replyMarkup; - /** - * New content of the message. Must be one of the following types: inputMessageAnimation, inputMessageAudio, inputMessageDocument, inputMessagePhoto or inputMessageVideo. - */ - public InputMessageContent inputMessageContent; - - /** - * Default constructor for a function, which edits the media content of a message, including message caption. If only the caption needs to be edited, use editMessageCaption instead. The type of message content in an album can't be changed with exception of replacing a photo with a video or vice versa. Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- */ - public EditMessageMedia() { - } - - /** - * Creates a function, which edits the media content of a message, including message caption. If only the caption needs to be edited, use editMessageCaption instead. The type of message content in an album can't be changed with exception of replacing a photo with a video or vice versa. Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- * - * @param chatId The chat the message belongs to. - * @param messageId Identifier of the message. Use messageProperties.canEditMedia to check whether the message can be edited. - * @param replyMarkup The new message reply markup; pass null if none; for bots only. - * @param inputMessageContent New content of the message. Must be one of the following types: inputMessageAnimation, inputMessageAudio, inputMessageDocument, inputMessagePhoto or inputMessageVideo. - */ - public EditMessageMedia(long chatId, long messageId, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.chatId = chatId; - this.messageId = messageId; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1152678125; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the message reply markup; for bots only. Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- */ - public static class EditMessageReplyMarkup extends Function { - /** - * The chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message. Use messageProperties.canBeEdited to check whether the message can be edited. - */ - public long messageId; - /** - * The new message reply markup; pass null if none. - */ - public ReplyMarkup replyMarkup; - - /** - * Default constructor for a function, which edits the message reply markup; for bots only. Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- */ - public EditMessageReplyMarkup() { - } - - /** - * Creates a function, which edits the message reply markup; for bots only. Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- * - * @param chatId The chat the message belongs to. - * @param messageId Identifier of the message. Use messageProperties.canBeEdited to check whether the message can be edited. - * @param replyMarkup The new message reply markup; pass null if none. - */ - public EditMessageReplyMarkup(long chatId, long messageId, ReplyMarkup replyMarkup) { - this.chatId = chatId; - this.messageId = messageId; - this.replyMarkup = replyMarkup; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 332127881; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the time when a scheduled message will be sent. Scheduling state of all messages in the same album or forwarded together with the message will be also changed. - * - *

Returns {@link Ok Ok}

- */ - public static class EditMessageSchedulingState extends Function { - /** - * The chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message. Use messageProperties.canEditSchedulingState to check whether the message is suitable. - */ - public long messageId; - /** - * The new message scheduling state; pass null to send the message immediately. Must be null for messages in the state messageSchedulingStateSendWhenVideoProcessed. - */ - public MessageSchedulingState schedulingState; - - /** - * Default constructor for a function, which edits the time when a scheduled message will be sent. Scheduling state of all messages in the same album or forwarded together with the message will be also changed. - * - *

Returns {@link Ok Ok}

- */ - public EditMessageSchedulingState() { - } - - /** - * Creates a function, which edits the time when a scheduled message will be sent. Scheduling state of all messages in the same album or forwarded together with the message will be also changed. - * - *

Returns {@link Ok Ok}

- * - * @param chatId The chat the message belongs to. - * @param messageId Identifier of the message. Use messageProperties.canEditSchedulingState to check whether the message is suitable. - * @param schedulingState The new message scheduling state; pass null to send the message immediately. Must be null for messages in the state messageSchedulingStateSendWhenVideoProcessed. - */ - public EditMessageSchedulingState(long chatId, long messageId, MessageSchedulingState schedulingState) { - this.chatId = chatId; - this.messageId = messageId; - this.schedulingState = schedulingState; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1372976192; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits the text of a message (or a text of a game message). Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- */ - public static class EditMessageText extends Function { - /** - * The chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message. Use messageProperties.canBeEdited to check whether the message can be edited. - */ - public long messageId; - /** - * The new message reply markup; pass null if none; for bots only. - */ - public ReplyMarkup replyMarkup; - /** - * New text content of the message. Must be of type inputMessageText. - */ - public InputMessageContent inputMessageContent; - - /** - * Default constructor for a function, which edits the text of a message (or a text of a game message). Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- */ - public EditMessageText() { - } - - /** - * Creates a function, which edits the text of a message (or a text of a game message). Returns the edited message after the edit is completed on the server side. - * - *

Returns {@link Message Message}

- * - * @param chatId The chat the message belongs to. - * @param messageId Identifier of the message. Use messageProperties.canBeEdited to check whether the message can be edited. - * @param replyMarkup The new message reply markup; pass null if none; for bots only. - * @param inputMessageContent New text content of the message. Must be of type inputMessageText. - */ - public EditMessageText(long chatId, long messageId, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.chatId = chatId; - this.messageId = messageId; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 196272567; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Edits an existing proxy server for network requests. Can be called before authorization. - * - *

Returns {@link AddedProxy AddedProxy}

- */ - public static class EditProxy extends Function { - /** - * Proxy identifier. - */ - public int proxyId; - /** - * The new information about the proxy. - */ - public Proxy proxy; - /** - * Pass true to immediately enable the proxy. - */ - public boolean enable; - - /** - * Default constructor for a function, which edits an existing proxy server for network requests. Can be called before authorization. - * - *

Returns {@link AddedProxy AddedProxy}

- */ - public EditProxy() { - } - - /** - * Creates a function, which edits an existing proxy server for network requests. Can be called before authorization. - * - *

Returns {@link AddedProxy AddedProxy}

- * - * @param proxyId Proxy identifier. - * @param proxy The new information about the proxy. - * @param enable Pass true to immediately enable the proxy. - */ - public EditProxy(int proxyId, Proxy proxy, boolean enable) { - this.proxyId = proxyId; - this.proxy = proxy; - this.enable = enable; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1648824814; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Asynchronously edits the text, media or caption of a quick reply message. Use quickReplyMessage.canBeEdited to check whether a message can be edited. Media message can be edited only to a media message. Checklist messages can be edited only to a checklist message. The type of message content in an album can't be changed with exception of replacing a photo with a video or vice versa. - * - *

Returns {@link Ok Ok}

- */ - public static class EditQuickReplyMessage extends Function { - /** - * Unique identifier of the quick reply shortcut with the message. - */ - public int shortcutId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * New content of the message. Must be one of the following types: inputMessageAnimation, inputMessageAudio, inputMessageChecklist, inputMessageDocument, inputMessagePhoto, inputMessageText, or inputMessageVideo. - */ - public InputMessageContent inputMessageContent; - - /** - * Default constructor for a function, which asynchronously edits the text, media or caption of a quick reply message. Use quickReplyMessage.canBeEdited to check whether a message can be edited. Media message can be edited only to a media message. Checklist messages can be edited only to a checklist message. The type of message content in an album can't be changed with exception of replacing a photo with a video or vice versa. - * - *

Returns {@link Ok Ok}

- */ - public EditQuickReplyMessage() { - } - - /** - * Creates a function, which asynchronously edits the text, media or caption of a quick reply message. Use quickReplyMessage.canBeEdited to check whether a message can be edited. Media message can be edited only to a media message. Checklist messages can be edited only to a checklist message. The type of message content in an album can't be changed with exception of replacing a photo with a video or vice versa. - * - *

Returns {@link Ok Ok}

- * - * @param shortcutId Unique identifier of the quick reply shortcut with the message. - * @param messageId Identifier of the message. - * @param inputMessageContent New content of the message. Must be one of the following types: inputMessageAnimation, inputMessageAudio, inputMessageChecklist, inputMessageDocument, inputMessagePhoto, inputMessageText, or inputMessageVideo. - */ - public EditQuickReplyMessage(int shortcutId, long messageId, InputMessageContent inputMessageContent) { - this.shortcutId = shortcutId; - this.messageId = messageId; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 80517006; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Cancels or re-enables Telegram Star subscription. - * - *

Returns {@link Ok Ok}

- */ - public static class EditStarSubscription extends Function { - /** - * Identifier of the subscription to change. - */ - public String subscriptionId; - /** - * New value of isCanceled. - */ - public boolean isCanceled; - - /** - * Default constructor for a function, which cancels or re-enables Telegram Star subscription. - * - *

Returns {@link Ok Ok}

- */ - public EditStarSubscription() { - } - - /** - * Creates a function, which cancels or re-enables Telegram Star subscription. - * - *

Returns {@link Ok Ok}

- * - * @param subscriptionId Identifier of the subscription to change. - * @param isCanceled New value of isCanceled. - */ - public EditStarSubscription(String subscriptionId, boolean isCanceled) { - this.subscriptionId = subscriptionId; - this.isCanceled = isCanceled; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2048538904; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes content and caption of a story. Can be called only if story.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- */ - public static class EditStory extends Function { - /** - * Identifier of the chat that posted the story. - */ - public long storyPosterChatId; - /** - * Identifier of the story to edit. - */ - public int storyId; - /** - * New content of the story; pass null to keep the current content. - */ - public InputStoryContent content; - /** - * New clickable rectangle areas to be shown on the story media; pass null to keep the current areas. Areas can't be edited if story content isn't changed. - */ - public InputStoryAreas areas; - /** - * New story caption; pass null to keep the current caption. - */ - public FormattedText caption; - - /** - * Default constructor for a function, which changes content and caption of a story. Can be called only if story.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- */ - public EditStory() { - } - - /** - * Creates a function, which changes content and caption of a story. Can be called only if story.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- * - * @param storyPosterChatId Identifier of the chat that posted the story. - * @param storyId Identifier of the story to edit. - * @param content New content of the story; pass null to keep the current content. - * @param areas New clickable rectangle areas to be shown on the story media; pass null to keep the current areas. Areas can't be edited if story content isn't changed. - * @param caption New story caption; pass null to keep the current caption. - */ - public EditStory(long storyPosterChatId, int storyId, InputStoryContent content, InputStoryAreas areas, FormattedText caption) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - this.content = content; - this.areas = areas; - this.caption = caption; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 355296788; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes cover of a video story. Can be called only if story.canBeEdited == true and the story isn't being edited now. - * - *

Returns {@link Ok Ok}

- */ - public static class EditStoryCover extends Function { - /** - * Identifier of the chat that posted the story. - */ - public long storyPosterChatId; - /** - * Identifier of the story to edit. - */ - public int storyId; - /** - * New timestamp of the frame, which will be used as video thumbnail. - */ - public double coverFrameTimestamp; - - /** - * Default constructor for a function, which changes cover of a video story. Can be called only if story.canBeEdited == true and the story isn't being edited now. - * - *

Returns {@link Ok Ok}

- */ - public EditStoryCover() { - } - - /** - * Creates a function, which changes cover of a video story. Can be called only if story.canBeEdited == true and the story isn't being edited now. - * - *

Returns {@link Ok Ok}

- * - * @param storyPosterChatId Identifier of the chat that posted the story. - * @param storyId Identifier of the story to edit. - * @param coverFrameTimestamp New timestamp of the frame, which will be used as video thumbnail. - */ - public EditStoryCover(long storyPosterChatId, int storyId, double coverFrameTimestamp) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - this.coverFrameTimestamp = coverFrameTimestamp; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1035823266; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Cancels or re-enables Telegram Star subscription for a user; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class EditUserStarSubscription extends Function { - /** - * User identifier. - */ - public long userId; - /** - * Telegram payment identifier of the subscription. - */ - public String telegramPaymentChargeId; - /** - * Pass true to cancel the subscription; pass false to allow the user to enable it. - */ - public boolean isCanceled; - - /** - * Default constructor for a function, which cancels or re-enables Telegram Star subscription for a user; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public EditUserStarSubscription() { - } - - /** - * Creates a function, which cancels or re-enables Telegram Star subscription for a user; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param userId User identifier. - * @param telegramPaymentChargeId Telegram payment identifier of the subscription. - * @param isCanceled Pass true to cancel the subscription; pass false to allow the user to enable it. - */ - public EditUserStarSubscription(long userId, String telegramPaymentChargeId, boolean isCanceled) { - this.userId = userId; - this.telegramPaymentChargeId = telegramPaymentChargeId; - this.isCanceled = isCanceled; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1370582665; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Enables a proxy. Only one proxy can be enabled at a time. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class EnableProxy extends Function { - /** - * Proxy identifier. - */ - public int proxyId; - - /** - * Default constructor for a function, which enables a proxy. Only one proxy can be enabled at a time. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public EnableProxy() { - } - - /** - * Creates a function, which enables a proxy. Only one proxy can be enabled at a time. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- * - * @param proxyId Proxy identifier. - */ - public EnableProxy(int proxyId) { - this.proxyId = proxyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1494450838; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Encrypts group call data before sending them over network using tgcalls. - * - *

Returns {@link Data Data}

- */ - public static class EncryptGroupCallData extends Function { - /** - * Group call identifier. The call must not be a video chat. - */ - public int groupCallId; - /** - * Data channel for which data is encrypted. - */ - public GroupCallDataChannel dataChannel; - /** - * Data to encrypt. - */ - public byte[] data; - /** - * Size of data prefix that must be kept unencrypted. - */ - public int unencryptedPrefixSize; - - /** - * Default constructor for a function, which encrypts group call data before sending them over network using tgcalls. - * - *

Returns {@link Data Data}

- */ - public EncryptGroupCallData() { - } - - /** - * Creates a function, which encrypts group call data before sending them over network using tgcalls. - * - *

Returns {@link Data Data}

- * - * @param groupCallId Group call identifier. The call must not be a video chat. - * @param dataChannel Data channel for which data is encrypted. - * @param data Data to encrypt. - * @param unencryptedPrefixSize Size of data prefix that must be kept unencrypted. - */ - public EncryptGroupCallData(int groupCallId, GroupCallDataChannel dataChannel, byte[] data, int unencryptedPrefixSize) { - this.groupCallId = groupCallId; - this.dataChannel = dataChannel; - this.data = data; - this.unencryptedPrefixSize = unencryptedPrefixSize; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -377997690; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Ends a group call. Requires groupCall.canBeManaged right for video chats and live stories or groupCall.isOwned otherwise. - * - *

Returns {@link Ok Ok}

- */ - public static class EndGroupCall extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - - /** - * Default constructor for a function, which ends a group call. Requires groupCall.canBeManaged right for video chats and live stories or groupCall.isOwned otherwise. - * - *

Returns {@link Ok Ok}

- */ - public EndGroupCall() { - } - - /** - * Creates a function, which ends a group call. Requires groupCall.canBeManaged right for video chats and live stories or groupCall.isOwned otherwise. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - */ - public EndGroupCall(int groupCallId) { - this.groupCallId = groupCallId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 573131959; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Ends recording of an active group call; for video chats only. Requires groupCall.canBeManaged right. - * - *

Returns {@link Ok Ok}

- */ - public static class EndGroupCallRecording extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - - /** - * Default constructor for a function, which ends recording of an active group call; for video chats only. Requires groupCall.canBeManaged right. - * - *

Returns {@link Ok Ok}

- */ - public EndGroupCallRecording() { - } - - /** - * Creates a function, which ends recording of an active group call; for video chats only. Requires groupCall.canBeManaged right. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - */ - public EndGroupCallRecording(int groupCallId) { - this.groupCallId = groupCallId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -75799927; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Ends screen sharing in a joined group call; not supported in live stories. - * - *

Returns {@link Ok Ok}

- */ - public static class EndGroupCallScreenSharing extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - - /** - * Default constructor for a function, which ends screen sharing in a joined group call; not supported in live stories. - * - *

Returns {@link Ok Ok}

- */ - public EndGroupCallScreenSharing() { - } - - /** - * Creates a function, which ends screen sharing in a joined group call; not supported in live stories. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - */ - public EndGroupCallScreenSharing(int groupCallId) { - this.groupCallId = groupCallId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2047599540; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Finishes the file generation. - * - *

Returns {@link Ok Ok}

- */ - public static class FinishFileGeneration extends Function { - /** - * The identifier of the generation process. - */ - public long generationId; - /** - * If passed, the file generation has failed and must be terminated; pass null if the file generation succeeded. - */ - public Error error; - - /** - * Default constructor for a function, which finishes the file generation. - * - *

Returns {@link Ok Ok}

- */ - public FinishFileGeneration() { - } - - /** - * Creates a function, which finishes the file generation. - * - *

Returns {@link Ok Ok}

- * - * @param generationId The identifier of the generation process. - * @param error If passed, the file generation has failed and must be terminated; pass null if the file generation succeeded. - */ - public FinishFileGeneration(long generationId, Error error) { - this.generationId = generationId; - this.error = error; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1055060835; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Forwards previously sent messages. Returns the forwarded messages in the same order as the message identifiers passed in messageIds. If a message can't be forwarded, null will be returned instead of the message. - * - *

Returns {@link Messages Messages}

- */ - public static class ForwardMessages extends Function { - /** - * Identifier of the chat to which to forward messages. - */ - public long chatId; - /** - * Topic in which the messages will be forwarded; message threads aren't supported; pass null if none. - */ - public MessageTopic topicId; - /** - * Identifier of the chat from which to forward messages. - */ - public long fromChatId; - /** - * Identifiers of the messages to forward. Message identifiers must be in a strictly increasing order. At most 100 messages can be forwarded simultaneously. A message can be forwarded only if messageProperties.canBeForwarded. - */ - public long[] messageIds; - /** - * Options to be used to send the messages; pass null to use default options. - */ - public MessageSendOptions options; - /** - * Pass true to copy content of the messages without reference to the original sender. Always true if the messages are forwarded to a secret chat or are local. Use messageProperties.canBeCopied and messageProperties.canBeCopiedToSecretChat to check whether the message is suitable. - */ - public boolean sendCopy; - /** - * Pass true to remove media captions of message copies. Ignored if sendCopy is false. - */ - public boolean removeCaption; - - /** - * Default constructor for a function, which forwards previously sent messages. Returns the forwarded messages in the same order as the message identifiers passed in messageIds. If a message can't be forwarded, null will be returned instead of the message. - * - *

Returns {@link Messages Messages}

- */ - public ForwardMessages() { - } - - /** - * Creates a function, which forwards previously sent messages. Returns the forwarded messages in the same order as the message identifiers passed in messageIds. If a message can't be forwarded, null will be returned instead of the message. - * - *

Returns {@link Messages Messages}

- * - * @param chatId Identifier of the chat to which to forward messages. - * @param topicId Topic in which the messages will be forwarded; message threads aren't supported; pass null if none. - * @param fromChatId Identifier of the chat from which to forward messages. - * @param messageIds Identifiers of the messages to forward. Message identifiers must be in a strictly increasing order. At most 100 messages can be forwarded simultaneously. A message can be forwarded only if messageProperties.canBeForwarded. - * @param options Options to be used to send the messages; pass null to use default options. - * @param sendCopy Pass true to copy content of the messages without reference to the original sender. Always true if the messages are forwarded to a secret chat or are local. Use messageProperties.canBeCopied and messageProperties.canBeCopiedToSecretChat to check whether the message is suitable. - * @param removeCaption Pass true to remove media captions of message copies. Ignored if sendCopy is false. - */ - public ForwardMessages(long chatId, MessageTopic topicId, long fromChatId, long[] messageIds, MessageSendOptions options, boolean sendCopy, boolean removeCaption) { - this.chatId = chatId; - this.topicId = topicId; - this.fromChatId = fromChatId; - this.messageIds = messageIds; - this.options = options; - this.sendCopy = sendCopy; - this.removeCaption = removeCaption; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -247889118; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the period of inactivity after which the account of the current user will automatically be deleted. - * - *

Returns {@link AccountTtl AccountTtl}

- */ - public static class GetAccountTtl extends Function { - - /** - * Default constructor for a function, which returns the period of inactivity after which the account of the current user will automatically be deleted. - * - *

Returns {@link AccountTtl AccountTtl}

- */ - public GetAccountTtl() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -443905161; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns all active sessions of the current user. - * - *

Returns {@link Sessions Sessions}

- */ - public static class GetActiveSessions extends Function { - - /** - * Default constructor for a function, which returns all active sessions of the current user. - * - *

Returns {@link Sessions Sessions}

- */ - public GetActiveSessions() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1119710526; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns all available Telegram Passport elements. - * - *

Returns {@link PassportElements PassportElements}

- */ - public static class GetAllPassportElements extends Function { - /** - * The 2-step verification password of the current user. - */ - public String password; - - /** - * Default constructor for a function, which returns all available Telegram Passport elements. - * - *

Returns {@link PassportElements PassportElements}

- */ - public GetAllPassportElements() { - } - - /** - * Creates a function, which returns all available Telegram Passport elements. - * - *

Returns {@link PassportElements PassportElements}

- * - * @param password The 2-step verification password of the current user. - */ - public GetAllPassportElements(String password) { - this.password = password; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2038945045; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns unique emoji that correspond to stickers to be found by the getStickers(stickerType, query, 1000000, chatId). - * - *

Returns {@link Emojis Emojis}

- */ - public static class GetAllStickerEmojis extends Function { - /** - * Type of the stickers to search for. - */ - public StickerType stickerType; - /** - * Search query. - */ - public String query; - /** - * Chat identifier for which to find stickers. - */ - public long chatId; - /** - * Pass true if only main emoji for each found sticker must be included in the result. - */ - public boolean returnOnlyMainEmoji; - - /** - * Default constructor for a function, which returns unique emoji that correspond to stickers to be found by the getStickers(stickerType, query, 1000000, chatId). - * - *

Returns {@link Emojis Emojis}

- */ - public GetAllStickerEmojis() { - } - - /** - * Creates a function, which returns unique emoji that correspond to stickers to be found by the getStickers(stickerType, query, 1000000, chatId). - * - *

Returns {@link Emojis Emojis}

- * - * @param stickerType Type of the stickers to search for. - * @param query Search query. - * @param chatId Chat identifier for which to find stickers. - * @param returnOnlyMainEmoji Pass true if only main emoji for each found sticker must be included in the result. - */ - public GetAllStickerEmojis(StickerType stickerType, String query, long chatId, boolean returnOnlyMainEmoji) { - this.stickerType = stickerType; - this.query = query; - this.chatId = chatId; - this.returnOnlyMainEmoji = returnOnlyMainEmoji; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 296562224; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an animated emoji corresponding to a given emoji. Returns a 404 error if the emoji has no animated emoji. - * - *

Returns {@link AnimatedEmoji AnimatedEmoji}

- */ - public static class GetAnimatedEmoji extends Function { - /** - * The emoji. - */ - public String emoji; - - /** - * Default constructor for a function, which returns an animated emoji corresponding to a given emoji. Returns a 404 error if the emoji has no animated emoji. - * - *

Returns {@link AnimatedEmoji AnimatedEmoji}

- */ - public GetAnimatedEmoji() { - } - - /** - * Creates a function, which returns an animated emoji corresponding to a given emoji. Returns a 404 error if the emoji has no animated emoji. - * - *

Returns {@link AnimatedEmoji AnimatedEmoji}

- * - * @param emoji The emoji. - */ - public GetAnimatedEmoji(String emoji) { - this.emoji = emoji; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1065635702; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns application config, provided by the server. Can be called before authorization. - * - *

Returns {@link JsonValue JsonValue}

- */ - public static class GetApplicationConfig extends Function { - - /** - * Default constructor for a function, which returns application config, provided by the server. Can be called before authorization. - * - *

Returns {@link JsonValue JsonValue}

- */ - public GetApplicationConfig() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1823144318; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the link for downloading official Telegram application to be used when the current user invites friends to Telegram. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public static class GetApplicationDownloadLink extends Function { - - /** - * Default constructor for a function, which returns the link for downloading official Telegram application to be used when the current user invites friends to Telegram. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public GetApplicationDownloadLink() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 112013252; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns settings for automatic moving of chats to and from the Archive chat lists. - * - *

Returns {@link ArchiveChatListSettings ArchiveChatListSettings}

- */ - public static class GetArchiveChatListSettings extends Function { - - /** - * Default constructor for a function, which returns settings for automatic moving of chats to and from the Archive chat lists. - * - *

Returns {@link ArchiveChatListSettings ArchiveChatListSettings}

- */ - public GetArchiveChatListSettings() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2087874976; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a list of archived sticker sets. - * - *

Returns {@link StickerSets StickerSets}

- */ - public static class GetArchivedStickerSets extends Function { - /** - * Type of the sticker sets to return. - */ - public StickerType stickerType; - /** - * Identifier of the sticker set from which to return the result; use 0 to get results from the beginning. - */ - public long offsetStickerSetId; - /** - * The maximum number of sticker sets to return; up to 100. - */ - public int limit; - - /** - * Default constructor for a function, which returns a list of archived sticker sets. - * - *

Returns {@link StickerSets StickerSets}

- */ - public GetArchivedStickerSets() { - } - - /** - * Creates a function, which returns a list of archived sticker sets. - * - *

Returns {@link StickerSets StickerSets}

- * - * @param stickerType Type of the sticker sets to return. - * @param offsetStickerSetId Identifier of the sticker set from which to return the result; use 0 to get results from the beginning. - * @param limit The maximum number of sticker sets to return; up to 100. - */ - public GetArchivedStickerSets(StickerType stickerType, long offsetStickerSetId, int limit) { - this.stickerType = stickerType; - this.offsetStickerSetId = offsetStickerSetId; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1001931341; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a list of sticker sets attached to a file, including regular, mask, and emoji sticker sets. Currently, only animations, photos, and videos can have attached sticker sets. - * - *

Returns {@link StickerSets StickerSets}

- */ - public static class GetAttachedStickerSets extends Function { - /** - * File identifier. - */ - public int fileId; - - /** - * Default constructor for a function, which returns a list of sticker sets attached to a file, including regular, mask, and emoji sticker sets. Currently, only animations, photos, and videos can have attached sticker sets. - * - *

Returns {@link StickerSets StickerSets}

- */ - public GetAttachedStickerSets() { - } - - /** - * Creates a function, which returns a list of sticker sets attached to a file, including regular, mask, and emoji sticker sets. Currently, only animations, photos, and videos can have attached sticker sets. - * - *

Returns {@link StickerSets StickerSets}

- * - * @param fileId File identifier. - */ - public GetAttachedStickerSets(int fileId) { - this.fileId = fileId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1302172429; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a bot that can be added to attachment or side menu. - * - *

Returns {@link AttachmentMenuBot AttachmentMenuBot}

- */ - public static class GetAttachmentMenuBot extends Function { - /** - * Bot's user identifier. - */ - public long botUserId; - - /** - * Default constructor for a function, which returns information about a bot that can be added to attachment or side menu. - * - *

Returns {@link AttachmentMenuBot AttachmentMenuBot}

- */ - public GetAttachmentMenuBot() { - } - - /** - * Creates a function, which returns information about a bot that can be added to attachment or side menu. - * - *

Returns {@link AttachmentMenuBot AttachmentMenuBot}

- * - * @param botUserId Bot's user identifier. - */ - public GetAttachmentMenuBot(long botUserId) { - this.botUserId = botUserId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1034248699; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns parameters for authentication using a passkey as JSON-serialized string. - * - *

Returns {@link Text Text}

- */ - public static class GetAuthenticationPasskeyParameters extends Function { - - /** - * Default constructor for a function, which returns parameters for authentication using a passkey as JSON-serialized string. - * - *

Returns {@link Text Text}

- */ - public GetAuthenticationPasskeyParameters() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -686037865; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the current authorization state. This is an offline method. For informational purposes only. Use updateAuthorizationState instead to maintain the current authorization state. Can be called before initialization. - * - *

Returns {@link AuthorizationState AuthorizationState}

- */ - public static class GetAuthorizationState extends Function { - - /** - * Default constructor for a function, which returns the current authorization state. This is an offline method. For informational purposes only. Use updateAuthorizationState instead to maintain the current authorization state. Can be called before initialization. - * - *

Returns {@link AuthorizationState AuthorizationState}

- */ - public GetAuthorizationState() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1949154877; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns auto-download settings presets for the current user. - * - *

Returns {@link AutoDownloadSettingsPresets AutoDownloadSettingsPresets}

- */ - public static class GetAutoDownloadSettingsPresets extends Function { - - /** - * Default constructor for a function, which returns auto-download settings presets for the current user. - * - *

Returns {@link AutoDownloadSettingsPresets AutoDownloadSettingsPresets}

- */ - public GetAutoDownloadSettingsPresets() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1721088201; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns autosave settings for the current user. - * - *

Returns {@link AutosaveSettings AutosaveSettings}

- */ - public static class GetAutosaveSettings extends Function { - - /** - * Default constructor for a function, which returns autosave settings for the current user. - * - *

Returns {@link AutosaveSettings AutosaveSettings}

- */ - public GetAutosaveSettings() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2136207914; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of available chat boost slots for the current user. - * - *

Returns {@link ChatBoostSlots ChatBoostSlots}

- */ - public static class GetAvailableChatBoostSlots extends Function { - - /** - * Default constructor for a function, which returns the list of available chat boost slots for the current user. - * - *

Returns {@link ChatBoostSlots ChatBoostSlots}

- */ - public GetAvailableChatBoostSlots() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1929898965; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns gifts that can be sent to other users and channel chats. - * - *

Returns {@link AvailableGifts AvailableGifts}

- */ - public static class GetAvailableGifts extends Function { - - /** - * Default constructor for a function, which returns gifts that can be sent to other users and channel chats. - * - *

Returns {@link AvailableGifts AvailableGifts}

- */ - public GetAvailableGifts() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -4559695; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Constructs a persistent HTTP URL for a background. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public static class GetBackgroundUrl extends Function { - /** - * Background name. - */ - public String name; - /** - * Background type; backgroundTypeChatTheme isn't supported. - */ - public BackgroundType type; - - /** - * Default constructor for a function, which constructs a persistent HTTP URL for a background. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public GetBackgroundUrl() { - } - - /** - * Creates a function, which constructs a persistent HTTP URL for a background. - * - *

Returns {@link HttpUrl HttpUrl}

- * - * @param name Background name. - * @param type Background type; backgroundTypeChatTheme isn't supported. - */ - public GetBackgroundUrl(String name, BackgroundType type) { - this.name = name; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 733769682; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a bank card. - * - *

Returns {@link BankCardInfo BankCardInfo}

- */ - public static class GetBankCardInfo extends Function { - /** - * The bank card number. - */ - public String bankCardNumber; - - /** - * Default constructor for a function, which returns information about a bank card. - * - *

Returns {@link BankCardInfo BankCardInfo}

- */ - public GetBankCardInfo() { - } - - /** - * Creates a function, which returns information about a bank card. - * - *

Returns {@link BankCardInfo BankCardInfo}

- * - * @param bankCardNumber The bank card number. - */ - public GetBankCardInfo(String bankCardNumber) { - this.bankCardNumber = bankCardNumber; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1310515792; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a basic group by its identifier. This is an offline method if the current user is not a bot. - * - *

Returns {@link BasicGroup BasicGroup}

- */ - public static class GetBasicGroup extends Function { - /** - * Basic group identifier. - */ - public long basicGroupId; - - /** - * Default constructor for a function, which returns information about a basic group by its identifier. This is an offline method if the current user is not a bot. - * - *

Returns {@link BasicGroup BasicGroup}

- */ - public GetBasicGroup() { - } - - /** - * Creates a function, which returns information about a basic group by its identifier. This is an offline method if the current user is not a bot. - * - *

Returns {@link BasicGroup BasicGroup}

- * - * @param basicGroupId Basic group identifier. - */ - public GetBasicGroup(long basicGroupId) { - this.basicGroupId = basicGroupId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1635174828; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns full information about a basic group by its identifier. - * - *

Returns {@link BasicGroupFullInfo BasicGroupFullInfo}

- */ - public static class GetBasicGroupFullInfo extends Function { - /** - * Basic group identifier. - */ - public long basicGroupId; - - /** - * Default constructor for a function, which returns full information about a basic group by its identifier. - * - *

Returns {@link BasicGroupFullInfo BasicGroupFullInfo}

- */ - public GetBasicGroupFullInfo() { - } - - /** - * Creates a function, which returns full information about a basic group by its identifier. - * - *

Returns {@link BasicGroupFullInfo BasicGroupFullInfo}

- * - * @param basicGroupId Basic group identifier. - */ - public GetBasicGroupFullInfo(long basicGroupId) { - this.basicGroupId = basicGroupId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1822039253; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns users and chats that were blocked by the current user. - * - *

Returns {@link MessageSenders MessageSenders}

- */ - public static class GetBlockedMessageSenders extends Function { - /** - * Block list from which to return users. - */ - public BlockList blockList; - /** - * Number of users and chats to skip in the result; must be non-negative. - */ - public int offset; - /** - * The maximum number of users and chats to return; up to 100. - */ - public int limit; - - /** - * Default constructor for a function, which returns users and chats that were blocked by the current user. - * - *

Returns {@link MessageSenders MessageSenders}

- */ - public GetBlockedMessageSenders() { - } - - /** - * Creates a function, which returns users and chats that were blocked by the current user. - * - *

Returns {@link MessageSenders MessageSenders}

- * - * @param blockList Block list from which to return users. - * @param offset Number of users and chats to skip in the result; must be non-negative. - * @param limit The maximum number of users and chats to return; up to 100. - */ - public GetBlockedMessageSenders(BlockList blockList, int offset, int limit) { - this.blockList = blockList; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1931137258; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the text shown in the chat with a bot if the chat is empty in the given language. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Text Text}

- */ - public static class GetBotInfoDescription extends Function { - /** - * Identifier of the target bot. - */ - public long botUserId; - /** - * A two-letter ISO 639-1 language code or an empty string. - */ - public String languageCode; - - /** - * Default constructor for a function, which returns the text shown in the chat with a bot if the chat is empty in the given language. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Text Text}

- */ - public GetBotInfoDescription() { - } - - /** - * Creates a function, which returns the text shown in the chat with a bot if the chat is empty in the given language. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Text Text}

- * - * @param botUserId Identifier of the target bot. - * @param languageCode A two-letter ISO 639-1 language code or an empty string. - */ - public GetBotInfoDescription(long botUserId, String languageCode) { - this.botUserId = botUserId; - this.languageCode = languageCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -762841035; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the text shown on a bot's profile page and sent together with the link when users share the bot in the given language. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Text Text}

- */ - public static class GetBotInfoShortDescription extends Function { - /** - * Identifier of the target bot. - */ - public long botUserId; - /** - * A two-letter ISO 639-1 language code or an empty string. - */ - public String languageCode; - - /** - * Default constructor for a function, which returns the text shown on a bot's profile page and sent together with the link when users share the bot in the given language. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Text Text}

- */ - public GetBotInfoShortDescription() { - } - - /** - * Creates a function, which returns the text shown on a bot's profile page and sent together with the link when users share the bot in the given language. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Text Text}

- * - * @param botUserId Identifier of the target bot. - * @param languageCode A two-letter ISO 639-1 language code or an empty string. - */ - public GetBotInfoShortDescription(long botUserId, String languageCode) { - this.botUserId = botUserId; - this.languageCode = languageCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1243358740; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of media previews for the given language and the list of languages for which the bot has dedicated previews. - * - *

Returns {@link BotMediaPreviewInfo BotMediaPreviewInfo}

- */ - public static class GetBotMediaPreviewInfo extends Function { - /** - * Identifier of the target bot. The bot must be owned and must have the main Web App. - */ - public long botUserId; - /** - * A two-letter ISO 639-1 language code for which to get previews. If empty, then default previews are returned. - */ - public String languageCode; - - /** - * Default constructor for a function, which returns the list of media previews for the given language and the list of languages for which the bot has dedicated previews. - * - *

Returns {@link BotMediaPreviewInfo BotMediaPreviewInfo}

- */ - public GetBotMediaPreviewInfo() { - } - - /** - * Creates a function, which returns the list of media previews for the given language and the list of languages for which the bot has dedicated previews. - * - *

Returns {@link BotMediaPreviewInfo BotMediaPreviewInfo}

- * - * @param botUserId Identifier of the target bot. The bot must be owned and must have the main Web App. - * @param languageCode A two-letter ISO 639-1 language code for which to get previews. If empty, then default previews are returned. - */ - public GetBotMediaPreviewInfo(long botUserId, String languageCode) { - this.botUserId = botUserId; - this.languageCode = languageCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1358299446; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of media previews of a bot. - * - *

Returns {@link BotMediaPreviews BotMediaPreviews}

- */ - public static class GetBotMediaPreviews extends Function { - /** - * Identifier of the target bot. The bot must have the main Web App. - */ - public long botUserId; - - /** - * Default constructor for a function, which returns the list of media previews of a bot. - * - *

Returns {@link BotMediaPreviews BotMediaPreviews}

- */ - public GetBotMediaPreviews() { - } - - /** - * Creates a function, which returns the list of media previews of a bot. - * - *

Returns {@link BotMediaPreviews BotMediaPreviews}

- * - * @param botUserId Identifier of the target bot. The bot must have the main Web App. - */ - public GetBotMediaPreviews(long botUserId) { - this.botUserId = botUserId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 577131608; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the name of a bot in the given language. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Text Text}

- */ - public static class GetBotName extends Function { - /** - * Identifier of the target bot. - */ - public long botUserId; - /** - * A two-letter ISO 639-1 language code or an empty string. - */ - public String languageCode; - - /** - * Default constructor for a function, which returns the name of a bot in the given language. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Text Text}

- */ - public GetBotName() { - } - - /** - * Creates a function, which returns the name of a bot in the given language. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Text Text}

- * - * @param botUserId Identifier of the target bot. - * @param languageCode A two-letter ISO 639-1 language code or an empty string. - */ - public GetBotName(long botUserId, String languageCode) { - this.botUserId = botUserId; - this.languageCode = languageCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1707118036; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns approximate number of bots similar to the given bot. - * - *

Returns {@link Count Count}

- */ - public static class GetBotSimilarBotCount extends Function { - /** - * User identifier of the target bot. - */ - public long botUserId; - /** - * Pass true to get the number of bots without sending network requests, or -1 if the number of bots is unknown locally. - */ - public boolean returnLocal; - - /** - * Default constructor for a function, which returns approximate number of bots similar to the given bot. - * - *

Returns {@link Count Count}

- */ - public GetBotSimilarBotCount() { - } - - /** - * Creates a function, which returns approximate number of bots similar to the given bot. - * - *

Returns {@link Count Count}

- * - * @param botUserId User identifier of the target bot. - * @param returnLocal Pass true to get the number of bots without sending network requests, or -1 if the number of bots is unknown locally. - */ - public GetBotSimilarBotCount(long botUserId, boolean returnLocal) { - this.botUserId = botUserId; - this.returnLocal = returnLocal; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1271545369; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a list of bots similar to the given bot. - * - *

Returns {@link Users Users}

- */ - public static class GetBotSimilarBots extends Function { - /** - * User identifier of the target bot. - */ - public long botUserId; - - /** - * Default constructor for a function, which returns a list of bots similar to the given bot. - * - *

Returns {@link Users Users}

- */ - public GetBotSimilarBots() { - } - - /** - * Creates a function, which returns a list of bots similar to the given bot. - * - *

Returns {@link Users Users}

- * - * @param botUserId User identifier of the target bot. - */ - public GetBotSimilarBots(long botUserId) { - this.botUserId = botUserId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -825139275; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the Telegram Star amount owned by a business account; for bots only. - * - *

Returns {@link StarAmount StarAmount}

- */ - public static class GetBusinessAccountStarAmount extends Function { - /** - * Unique identifier of business connection. - */ - public String businessConnectionId; - - /** - * Default constructor for a function, which returns the Telegram Star amount owned by a business account; for bots only. - * - *

Returns {@link StarAmount StarAmount}

- */ - public GetBusinessAccountStarAmount() { - } - - /** - * Creates a function, which returns the Telegram Star amount owned by a business account; for bots only. - * - *

Returns {@link StarAmount StarAmount}

- * - * @param businessConnectionId Unique identifier of business connection. - */ - public GetBusinessAccountStarAmount(String businessConnectionId) { - this.businessConnectionId = businessConnectionId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1817136693; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a business chat link. - * - *

Returns {@link BusinessChatLinkInfo BusinessChatLinkInfo}

- */ - public static class GetBusinessChatLinkInfo extends Function { - /** - * Name of the link. - */ - public String linkName; - - /** - * Default constructor for a function, which returns information about a business chat link. - * - *

Returns {@link BusinessChatLinkInfo BusinessChatLinkInfo}

- */ - public GetBusinessChatLinkInfo() { - } - - /** - * Creates a function, which returns information about a business chat link. - * - *

Returns {@link BusinessChatLinkInfo BusinessChatLinkInfo}

- * - * @param linkName Name of the link. - */ - public GetBusinessChatLinkInfo(String linkName) { - this.linkName = linkName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 797670986; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns business chat links created for the current account. - * - *

Returns {@link BusinessChatLinks BusinessChatLinks}

- */ - public static class GetBusinessChatLinks extends Function { - - /** - * Default constructor for a function, which returns business chat links created for the current account. - * - *

Returns {@link BusinessChatLinks BusinessChatLinks}

- */ - public GetBusinessChatLinks() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 710287703; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the business bot that is connected to the current user account. Returns a 404 error if there is no connected bot. - * - *

Returns {@link BusinessConnectedBot BusinessConnectedBot}

- */ - public static class GetBusinessConnectedBot extends Function { - - /** - * Default constructor for a function, which returns the business bot that is connected to the current user account. Returns a 404 error if there is no connected bot. - * - *

Returns {@link BusinessConnectedBot BusinessConnectedBot}

- */ - public GetBusinessConnectedBot() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 911058883; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a business connection by its identifier; for bots only. - * - *

Returns {@link BusinessConnection BusinessConnection}

- */ - public static class GetBusinessConnection extends Function { - /** - * Identifier of the business connection to return. - */ - public String connectionId; - - /** - * Default constructor for a function, which returns information about a business connection by its identifier; for bots only. - * - *

Returns {@link BusinessConnection BusinessConnection}

- */ - public GetBusinessConnection() { - } - - /** - * Creates a function, which returns information about a business connection by its identifier; for bots only. - * - *

Returns {@link BusinessConnection BusinessConnection}

- * - * @param connectionId Identifier of the business connection to return. - */ - public GetBusinessConnection(String connectionId) { - this.connectionId = connectionId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2114706400; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about features, available to Business users. - * - *

Returns {@link BusinessFeatures BusinessFeatures}

- */ - public static class GetBusinessFeatures extends Function { - /** - * Source of the request; pass null if the method is called from settings or some non-standard source. - */ - public BusinessFeature source; - - /** - * Default constructor for a function, which returns information about features, available to Business users. - * - *

Returns {@link BusinessFeatures BusinessFeatures}

- */ - public GetBusinessFeatures() { - } - - /** - * Creates a function, which returns information about features, available to Business users. - * - *

Returns {@link BusinessFeatures BusinessFeatures}

- * - * @param source Source of the request; pass null if the method is called from settings or some non-standard source. - */ - public GetBusinessFeatures(BusinessFeature source) { - this.source = source; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -997171199; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends a callback query to a bot and returns an answer. Returns an error with code 502 if the bot fails to answer the query before the query timeout expires. - * - *

Returns {@link CallbackQueryAnswer CallbackQueryAnswer}

- */ - public static class GetCallbackQueryAnswer extends Function { - /** - * Identifier of the chat with the message. - */ - public long chatId; - /** - * Identifier of the message from which the query originated. The message must not be scheduled. - */ - public long messageId; - /** - * Query payload. - */ - public CallbackQueryPayload payload; - - /** - * Default constructor for a function, which sends a callback query to a bot and returns an answer. Returns an error with code 502 if the bot fails to answer the query before the query timeout expires. - * - *

Returns {@link CallbackQueryAnswer CallbackQueryAnswer}

- */ - public GetCallbackQueryAnswer() { - } - - /** - * Creates a function, which sends a callback query to a bot and returns an answer. Returns an error with code 502 if the bot fails to answer the query before the query timeout expires. - * - *

Returns {@link CallbackQueryAnswer CallbackQueryAnswer}

- * - * @param chatId Identifier of the chat with the message. - * @param messageId Identifier of the message from which the query originated. The message must not be scheduled. - * @param payload Query payload. - */ - public GetCallbackQueryAnswer(long chatId, long messageId, CallbackQueryPayload payload) { - this.chatId = chatId; - this.messageId = messageId; - this.payload = payload; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 116357727; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a message with the callback button that originated a callback query; for bots only. - * - *

Returns {@link Message Message}

- */ - public static class GetCallbackQueryMessage extends Function { - /** - * Identifier of the chat the message belongs to. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - /** - * Identifier of the callback query. - */ - public long callbackQueryId; - - /** - * Default constructor for a function, which returns information about a message with the callback button that originated a callback query; for bots only. - * - *

Returns {@link Message Message}

- */ - public GetCallbackQueryMessage() { - } - - /** - * Creates a function, which returns information about a message with the callback button that originated a callback query; for bots only. - * - *

Returns {@link Message Message}

- * - * @param chatId Identifier of the chat the message belongs to. - * @param messageId Message identifier. - * @param callbackQueryId Identifier of the callback query. - */ - public GetCallbackQueryMessage(long chatId, long messageId, long callbackQueryId) { - this.chatId = chatId; - this.messageId = messageId; - this.callbackQueryId = callbackQueryId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1121939086; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a chat by its identifier. This is an offline method if the current user is not a bot. - * - *

Returns {@link Chat Chat}

- */ - public static class GetChat extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which returns information about a chat by its identifier. This is an offline method if the current user is not a bot. - * - *

Returns {@link Chat Chat}

- */ - public GetChat() { - } - - /** - * Creates a function, which returns information about a chat by its identifier. This is an offline method if the current user is not a bot. - * - *

Returns {@link Chat Chat}

- * - * @param chatId Chat identifier. - */ - public GetChat(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1866601536; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of active stories posted by the given chat. - * - *

Returns {@link ChatActiveStories ChatActiveStories}

- */ - public static class GetChatActiveStories extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which returns the list of active stories posted by the given chat. - * - *

Returns {@link ChatActiveStories ChatActiveStories}

- */ - public GetChatActiveStories() { - } - - /** - * Creates a function, which returns the list of active stories posted by the given chat. - * - *

Returns {@link ChatActiveStories ChatActiveStories}

- * - * @param chatId Chat identifier. - */ - public GetChatActiveStories(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 776993781; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a list of administrators of the chat with their custom titles. - * - *

Returns {@link ChatAdministrators ChatAdministrators}

- */ - public static class GetChatAdministrators extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which returns a list of administrators of the chat with their custom titles. - * - *

Returns {@link ChatAdministrators ChatAdministrators}

- */ - public GetChatAdministrators() { - } - - /** - * Creates a function, which returns a list of administrators of the chat with their custom titles. - * - *

Returns {@link ChatAdministrators ChatAdministrators}

- * - * @param chatId Chat identifier. - */ - public GetChatAdministrators(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1544468155; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of all stories posted by the given chat; requires canEditStories administrator right in the chat. The stories are returned in reverse chronological order (i.e., in order of decreasing storyId). For optimal performance, the number of returned stories is chosen by TDLib. - * - *

Returns {@link Stories Stories}

- */ - public static class GetChatArchivedStories extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the story starting from which stories must be returned; use 0 to get results from the last story. - */ - public int fromStoryId; - /** - * The maximum number of stories to be returned. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which returns the list of all stories posted by the given chat; requires canEditStories administrator right in the chat. The stories are returned in reverse chronological order (i.e., in order of decreasing storyId). For optimal performance, the number of returned stories is chosen by TDLib. - * - *

Returns {@link Stories Stories}

- */ - public GetChatArchivedStories() { - } - - /** - * Creates a function, which returns the list of all stories posted by the given chat; requires canEditStories administrator right in the chat. The stories are returned in reverse chronological order (i.e., in order of decreasing storyId). For optimal performance, the number of returned stories is chosen by TDLib. - * - *

Returns {@link Stories Stories}

- * - * @param chatId Chat identifier. - * @param fromStoryId Identifier of the story starting from which stories must be returned; use 0 to get results from the last story. - * @param limit The maximum number of stories to be returned. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - */ - public GetChatArchivedStories(long chatId, int fromStoryId, int limit) { - this.chatId = chatId; - this.fromStoryId = fromStoryId; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1356950392; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of message sender identifiers, which can be used to send messages in a chat. - * - *

Returns {@link ChatMessageSenders ChatMessageSenders}

- */ - public static class GetChatAvailableMessageSenders extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which returns the list of message sender identifiers, which can be used to send messages in a chat. - * - *

Returns {@link ChatMessageSenders ChatMessageSenders}

- */ - public GetChatAvailableMessageSenders() { - } - - /** - * Creates a function, which returns the list of message sender identifiers, which can be used to send messages in a chat. - * - *

Returns {@link ChatMessageSenders ChatMessageSenders}

- * - * @param chatId Chat identifier. - */ - public GetChatAvailableMessageSenders(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1158670635; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of message sender identifiers, which can be used to send a paid reaction in a chat. - * - *

Returns {@link MessageSenders MessageSenders}

- */ - public static class GetChatAvailablePaidMessageReactionSenders extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which returns the list of message sender identifiers, which can be used to send a paid reaction in a chat. - * - *

Returns {@link MessageSenders MessageSenders}

- */ - public GetChatAvailablePaidMessageReactionSenders() { - } - - /** - * Creates a function, which returns the list of message sender identifiers, which can be used to send a paid reaction in a chat. - * - *

Returns {@link MessageSenders MessageSenders}

- * - * @param chatId Chat identifier. - */ - public GetChatAvailablePaidMessageReactionSenders(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1244619639; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of features available for different chat boost levels. This is an offline method. - * - *

Returns {@link ChatBoostFeatures ChatBoostFeatures}

- */ - public static class GetChatBoostFeatures extends Function { - /** - * Pass true to get the list of features for channels; pass false to get the list of features for supergroups. - */ - public boolean isChannel; - - /** - * Default constructor for a function, which returns the list of features available for different chat boost levels. This is an offline method. - * - *

Returns {@link ChatBoostFeatures ChatBoostFeatures}

- */ - public GetChatBoostFeatures() { - } - - /** - * Creates a function, which returns the list of features available for different chat boost levels. This is an offline method. - * - *

Returns {@link ChatBoostFeatures ChatBoostFeatures}

- * - * @param isChannel Pass true to get the list of features for channels; pass false to get the list of features for supergroups. - */ - public GetChatBoostFeatures(boolean isChannel) { - this.isChannel = isChannel; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -389994336; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of features available on the specific chat boost level. This is an offline method. - * - *

Returns {@link ChatBoostLevelFeatures ChatBoostLevelFeatures}

- */ - public static class GetChatBoostLevelFeatures extends Function { - /** - * Pass true to get the list of features for channels; pass false to get the list of features for supergroups. - */ - public boolean isChannel; - /** - * Chat boost level. - */ - public int level; - - /** - * Default constructor for a function, which returns the list of features available on the specific chat boost level. This is an offline method. - * - *

Returns {@link ChatBoostLevelFeatures ChatBoostLevelFeatures}

- */ - public GetChatBoostLevelFeatures() { - } - - /** - * Creates a function, which returns the list of features available on the specific chat boost level. This is an offline method. - * - *

Returns {@link ChatBoostLevelFeatures ChatBoostLevelFeatures}

- * - * @param isChannel Pass true to get the list of features for channels; pass false to get the list of features for supergroups. - * @param level Chat boost level. - */ - public GetChatBoostLevelFeatures(boolean isChannel, int level) { - this.isChannel = isChannel; - this.level = level; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1172717195; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an HTTPS link to boost the specified supergroup or channel chat. - * - *

Returns {@link ChatBoostLink ChatBoostLink}

- */ - public static class GetChatBoostLink extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - - /** - * Default constructor for a function, which returns an HTTPS link to boost the specified supergroup or channel chat. - * - *

Returns {@link ChatBoostLink ChatBoostLink}

- */ - public GetChatBoostLink() { - } - - /** - * Creates a function, which returns an HTTPS link to boost the specified supergroup or channel chat. - * - *

Returns {@link ChatBoostLink ChatBoostLink}

- * - * @param chatId Identifier of the chat. - */ - public GetChatBoostLink(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1458662533; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a link to boost a chat. Can be called for any internal link of the type internalLinkTypeChatBoost. - * - *

Returns {@link ChatBoostLinkInfo ChatBoostLinkInfo}

- */ - public static class GetChatBoostLinkInfo extends Function { - /** - * The link to boost a chat. - */ - public String url; - - /** - * Default constructor for a function, which returns information about a link to boost a chat. Can be called for any internal link of the type internalLinkTypeChatBoost. - * - *

Returns {@link ChatBoostLinkInfo ChatBoostLinkInfo}

- */ - public GetChatBoostLinkInfo() { - } - - /** - * Creates a function, which returns information about a link to boost a chat. Can be called for any internal link of the type internalLinkTypeChatBoost. - * - *

Returns {@link ChatBoostLinkInfo ChatBoostLinkInfo}

- * - * @param url The link to boost a chat. - */ - public GetChatBoostLinkInfo(String url) { - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 654068572; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the current boost status for a supergroup or a channel chat. - * - *

Returns {@link ChatBoostStatus ChatBoostStatus}

- */ - public static class GetChatBoostStatus extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - - /** - * Default constructor for a function, which returns the current boost status for a supergroup or a channel chat. - * - *

Returns {@link ChatBoostStatus ChatBoostStatus}

- */ - public GetChatBoostStatus() { - } - - /** - * Creates a function, which returns the current boost status for a supergroup or a channel chat. - * - *

Returns {@link ChatBoostStatus ChatBoostStatus}

- * - * @param chatId Identifier of the chat. - */ - public GetChatBoostStatus(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -810775857; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of boosts applied to a chat; requires administrator rights in the chat. - * - *

Returns {@link FoundChatBoosts FoundChatBoosts}

- */ - public static class GetChatBoosts extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * Pass true to receive only boosts received from gift codes and giveaways created by the chat. - */ - public boolean onlyGiftCodes; - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of boosts to be returned; up to 100. For optimal performance, the number of returned boosts can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which returns the list of boosts applied to a chat; requires administrator rights in the chat. - * - *

Returns {@link FoundChatBoosts FoundChatBoosts}

- */ - public GetChatBoosts() { - } - - /** - * Creates a function, which returns the list of boosts applied to a chat; requires administrator rights in the chat. - * - *

Returns {@link FoundChatBoosts FoundChatBoosts}

- * - * @param chatId Identifier of the chat. - * @param onlyGiftCodes Pass true to receive only boosts received from gift codes and giveaways created by the chat. - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of boosts to be returned; up to 100. For optimal performance, the number of returned boosts can be smaller than the specified limit. - */ - public GetChatBoosts(long chatId, boolean onlyGiftCodes, String offset, int limit) { - this.chatId = chatId; - this.onlyGiftCodes = onlyGiftCodes; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1419859400; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a list of service actions taken by chat members and administrators in the last 48 hours. Available only for supergroups and channels. Requires administrator rights. Returns results in reverse chronological order (i.e., in order of decreasing eventId). - * - *

Returns {@link ChatEvents ChatEvents}

- */ - public static class GetChatEventLog extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Search query by which to filter events. - */ - public String query; - /** - * Identifier of an event from which to return results. Use 0 to get results from the latest events. - */ - public long fromEventId; - /** - * The maximum number of events to return; up to 100. - */ - public int limit; - /** - * The types of events to return; pass null to get chat events of all types. - */ - public ChatEventLogFilters filters; - /** - * User identifiers by which to filter events. By default, events relating to all users will be returned. - */ - public long[] userIds; - - /** - * Default constructor for a function, which returns a list of service actions taken by chat members and administrators in the last 48 hours. Available only for supergroups and channels. Requires administrator rights. Returns results in reverse chronological order (i.e., in order of decreasing eventId). - * - *

Returns {@link ChatEvents ChatEvents}

- */ - public GetChatEventLog() { - } - - /** - * Creates a function, which returns a list of service actions taken by chat members and administrators in the last 48 hours. Available only for supergroups and channels. Requires administrator rights. Returns results in reverse chronological order (i.e., in order of decreasing eventId). - * - *

Returns {@link ChatEvents ChatEvents}

- * - * @param chatId Chat identifier. - * @param query Search query by which to filter events. - * @param fromEventId Identifier of an event from which to return results. Use 0 to get results from the latest events. - * @param limit The maximum number of events to return; up to 100. - * @param filters The types of events to return; pass null to get chat events of all types. - * @param userIds User identifiers by which to filter events. By default, events relating to all users will be returned. - */ - public GetChatEventLog(long chatId, String query, long fromEventId, int limit, ChatEventLogFilters filters, long[] userIds) { - this.chatId = chatId; - this.query = query; - this.fromEventId = fromEventId; - this.limit = limit; - this.filters = filters; - this.userIds = userIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1281344669; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a chat folder by its identifier. - * - *

Returns {@link ChatFolder ChatFolder}

- */ - public static class GetChatFolder extends Function { - /** - * Chat folder identifier. - */ - public int chatFolderId; - - /** - * Default constructor for a function, which returns information about a chat folder by its identifier. - * - *

Returns {@link ChatFolder ChatFolder}

- */ - public GetChatFolder() { - } - - /** - * Creates a function, which returns information about a chat folder by its identifier. - * - *

Returns {@link ChatFolder ChatFolder}

- * - * @param chatFolderId Chat folder identifier. - */ - public GetChatFolder(int chatFolderId) { - this.chatFolderId = chatFolderId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 92809880; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns approximate number of chats in a being created chat folder. Main and archive chat lists must be fully preloaded for this function to work correctly. - * - *

Returns {@link Count Count}

- */ - public static class GetChatFolderChatCount extends Function { - /** - * The new chat folder. - */ - public ChatFolder folder; - - /** - * Default constructor for a function, which returns approximate number of chats in a being created chat folder. Main and archive chat lists must be fully preloaded for this function to work correctly. - * - *

Returns {@link Count Count}

- */ - public GetChatFolderChatCount() { - } - - /** - * Creates a function, which returns approximate number of chats in a being created chat folder. Main and archive chat lists must be fully preloaded for this function to work correctly. - * - *

Returns {@link Count Count}

- * - * @param folder The new chat folder. - */ - public GetChatFolderChatCount(ChatFolder folder) { - this.folder = folder; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2111097790; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns identifiers of pinned or always included chats from a chat folder, which are suggested to be left when the chat folder is deleted. - * - *

Returns {@link Chats Chats}

- */ - public static class GetChatFolderChatsToLeave extends Function { - /** - * Chat folder identifier. - */ - public int chatFolderId; - - /** - * Default constructor for a function, which returns identifiers of pinned or always included chats from a chat folder, which are suggested to be left when the chat folder is deleted. - * - *

Returns {@link Chats Chats}

- */ - public GetChatFolderChatsToLeave() { - } - - /** - * Creates a function, which returns identifiers of pinned or always included chats from a chat folder, which are suggested to be left when the chat folder is deleted. - * - *

Returns {@link Chats Chats}

- * - * @param chatFolderId Chat folder identifier. - */ - public GetChatFolderChatsToLeave(int chatFolderId) { - this.chatFolderId = chatFolderId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1916672337; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns default icon name for a folder. Can be called synchronously. - * - *

Returns {@link ChatFolderIcon ChatFolderIcon}

- */ - public static class GetChatFolderDefaultIconName extends Function { - /** - * Chat folder. - */ - public ChatFolder folder; - - /** - * Default constructor for a function, which returns default icon name for a folder. Can be called synchronously. - * - *

Returns {@link ChatFolderIcon ChatFolderIcon}

- */ - public GetChatFolderDefaultIconName() { - } - - /** - * Creates a function, which returns default icon name for a folder. Can be called synchronously. - * - *

Returns {@link ChatFolderIcon ChatFolderIcon}

- * - * @param folder Chat folder. - */ - public GetChatFolderDefaultIconName(ChatFolder folder) { - this.folder = folder; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 754425959; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns invite links created by the current user for a shareable chat folder. - * - *

Returns {@link ChatFolderInviteLinks ChatFolderInviteLinks}

- */ - public static class GetChatFolderInviteLinks extends Function { - /** - * Chat folder identifier. - */ - public int chatFolderId; - - /** - * Default constructor for a function, which returns invite links created by the current user for a shareable chat folder. - * - *

Returns {@link ChatFolderInviteLinks ChatFolderInviteLinks}

- */ - public GetChatFolderInviteLinks() { - } - - /** - * Creates a function, which returns invite links created by the current user for a shareable chat folder. - * - *

Returns {@link ChatFolderInviteLinks ChatFolderInviteLinks}

- * - * @param chatFolderId Chat folder identifier. - */ - public GetChatFolderInviteLinks(int chatFolderId) { - this.chatFolderId = chatFolderId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 329079776; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns new chats added to a shareable chat folder by its owner. The method must be called at most once in getOption("chat_folder_new_chats_update_period") for the given chat folder. - * - *

Returns {@link Chats Chats}

- */ - public static class GetChatFolderNewChats extends Function { - /** - * Chat folder identifier. - */ - public int chatFolderId; - - /** - * Default constructor for a function, which returns new chats added to a shareable chat folder by its owner. The method must be called at most once in getOption("chat_folder_new_chats_update_period") for the given chat folder. - * - *

Returns {@link Chats Chats}

- */ - public GetChatFolderNewChats() { - } - - /** - * Creates a function, which returns new chats added to a shareable chat folder by its owner. The method must be called at most once in getOption("chat_folder_new_chats_update_period") for the given chat folder. - * - *

Returns {@link Chats Chats}

- * - * @param chatFolderId Chat folder identifier. - */ - public GetChatFolderNewChats(int chatFolderId) { - this.chatFolderId = chatFolderId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2123181260; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns messages in a chat. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). For optimal performance, the number of returned messages is chosen by TDLib. This is an offline method if onlyLocal is true. - * - *

Returns {@link Messages Messages}

- */ - public static class GetChatHistory extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the message starting from which history must be fetched; use 0 to get results from the last message. - */ - public long fromMessageId; - /** - * Specify 0 to get results from exactly the message fromMessageId or a negative number from -99 to -1 to get additionally -offset newer messages. - */ - public int offset; - /** - * The maximum number of messages to be returned; must be positive and can't be greater than 100. If the offset is negative, then the limit must be greater than or equal to -offset. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - /** - * Pass true to get only messages that are available without sending network requests. - */ - public boolean onlyLocal; - - /** - * Default constructor for a function, which returns messages in a chat. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). For optimal performance, the number of returned messages is chosen by TDLib. This is an offline method if onlyLocal is true. - * - *

Returns {@link Messages Messages}

- */ - public GetChatHistory() { - } - - /** - * Creates a function, which returns messages in a chat. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). For optimal performance, the number of returned messages is chosen by TDLib. This is an offline method if onlyLocal is true. - * - *

Returns {@link Messages Messages}

- * - * @param chatId Chat identifier. - * @param fromMessageId Identifier of the message starting from which history must be fetched; use 0 to get results from the last message. - * @param offset Specify 0 to get results from exactly the message fromMessageId or a negative number from -99 to -1 to get additionally -offset newer messages. - * @param limit The maximum number of messages to be returned; must be positive and can't be greater than 100. If the offset is negative, then the limit must be greater than or equal to -offset. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * @param onlyLocal Pass true to get only messages that are available without sending network requests. - */ - public GetChatHistory(long chatId, long fromMessageId, int offset, int limit, boolean onlyLocal) { - this.chatId = chatId; - this.fromMessageId = fromMessageId; - this.offset = offset; - this.limit = limit; - this.onlyLocal = onlyLocal; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -799960451; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about an invite link. Requires administrator privileges and canInviteUsers right in the chat to get own links and owner privileges to get other links. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- */ - public static class GetChatInviteLink extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Invite link to get. - */ - public String inviteLink; - - /** - * Default constructor for a function, which returns information about an invite link. Requires administrator privileges and canInviteUsers right in the chat to get own links and owner privileges to get other links. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- */ - public GetChatInviteLink() { - } - - /** - * Creates a function, which returns information about an invite link. Requires administrator privileges and canInviteUsers right in the chat to get own links and owner privileges to get other links. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- * - * @param chatId Chat identifier. - * @param inviteLink Invite link to get. - */ - public GetChatInviteLink(long chatId, String inviteLink) { - this.chatId = chatId; - this.inviteLink = inviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -479575555; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of chat administrators with number of their invite links. Requires owner privileges in the chat. - * - *

Returns {@link ChatInviteLinkCounts ChatInviteLinkCounts}

- */ - public static class GetChatInviteLinkCounts extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which returns the list of chat administrators with number of their invite links. Requires owner privileges in the chat. - * - *

Returns {@link ChatInviteLinkCounts ChatInviteLinkCounts}

- */ - public GetChatInviteLinkCounts() { - } - - /** - * Creates a function, which returns the list of chat administrators with number of their invite links. Requires owner privileges in the chat. - * - *

Returns {@link ChatInviteLinkCounts ChatInviteLinkCounts}

- * - * @param chatId Chat identifier. - */ - public GetChatInviteLinkCounts(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 890299025; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns chat members joined a chat via an invite link. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. - * - *

Returns {@link ChatInviteLinkMembers ChatInviteLinkMembers}

- */ - public static class GetChatInviteLinkMembers extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Invite link for which to return chat members. - */ - public String inviteLink; - /** - * Pass true if the link is a subscription link and only members with expired subscription must be returned. - */ - public boolean onlyWithExpiredSubscription; - /** - * A chat member from which to return next chat members; pass null to get results from the beginning. - */ - public ChatInviteLinkMember offsetMember; - /** - * The maximum number of chat members to return; up to 100. - */ - public int limit; - - /** - * Default constructor for a function, which returns chat members joined a chat via an invite link. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. - * - *

Returns {@link ChatInviteLinkMembers ChatInviteLinkMembers}

- */ - public GetChatInviteLinkMembers() { - } - - /** - * Creates a function, which returns chat members joined a chat via an invite link. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. - * - *

Returns {@link ChatInviteLinkMembers ChatInviteLinkMembers}

- * - * @param chatId Chat identifier. - * @param inviteLink Invite link for which to return chat members. - * @param onlyWithExpiredSubscription Pass true if the link is a subscription link and only members with expired subscription must be returned. - * @param offsetMember A chat member from which to return next chat members; pass null to get results from the beginning. - * @param limit The maximum number of chat members to return; up to 100. - */ - public GetChatInviteLinkMembers(long chatId, String inviteLink, boolean onlyWithExpiredSubscription, ChatInviteLinkMember offsetMember, int limit) { - this.chatId = chatId; - this.inviteLink = inviteLink; - this.onlyWithExpiredSubscription = onlyWithExpiredSubscription; - this.offsetMember = offsetMember; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1728376124; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns invite links for a chat created by specified administrator. Requires administrator privileges and canInviteUsers right in the chat to get own links and owner privileges to get other links. - * - *

Returns {@link ChatInviteLinks ChatInviteLinks}

- */ - public static class GetChatInviteLinks extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * User identifier of a chat administrator. Must be an identifier of the current user for non-owner. - */ - public long creatorUserId; - /** - * Pass true if revoked links needs to be returned instead of active or expired. - */ - public boolean isRevoked; - /** - * Creation date of an invite link starting after which to return invite links; use 0 to get results from the beginning. - */ - public int offsetDate; - /** - * Invite link starting after which to return invite links; use empty string to get results from the beginning. - */ - public String offsetInviteLink; - /** - * The maximum number of invite links to return; up to 100. - */ - public int limit; - - /** - * Default constructor for a function, which returns invite links for a chat created by specified administrator. Requires administrator privileges and canInviteUsers right in the chat to get own links and owner privileges to get other links. - * - *

Returns {@link ChatInviteLinks ChatInviteLinks}

- */ - public GetChatInviteLinks() { - } - - /** - * Creates a function, which returns invite links for a chat created by specified administrator. Requires administrator privileges and canInviteUsers right in the chat to get own links and owner privileges to get other links. - * - *

Returns {@link ChatInviteLinks ChatInviteLinks}

- * - * @param chatId Chat identifier. - * @param creatorUserId User identifier of a chat administrator. Must be an identifier of the current user for non-owner. - * @param isRevoked Pass true if revoked links needs to be returned instead of active or expired. - * @param offsetDate Creation date of an invite link starting after which to return invite links; use 0 to get results from the beginning. - * @param offsetInviteLink Invite link starting after which to return invite links; use empty string to get results from the beginning. - * @param limit The maximum number of invite links to return; up to 100. - */ - public GetChatInviteLinks(long chatId, long creatorUserId, boolean isRevoked, int offsetDate, String offsetInviteLink, int limit) { - this.chatId = chatId; - this.creatorUserId = creatorUserId; - this.isRevoked = isRevoked; - this.offsetDate = offsetDate; - this.offsetInviteLink = offsetInviteLink; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 883252396; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns pending join requests in a chat. - * - *

Returns {@link ChatJoinRequests ChatJoinRequests}

- */ - public static class GetChatJoinRequests extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Invite link for which to return join requests. If empty, all join requests will be returned. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. - */ - public String inviteLink; - /** - * A query to search for in the first names, last names and usernames of the users to return. - */ - public String query; - /** - * A chat join request from which to return next requests; pass null to get results from the beginning. - */ - public ChatJoinRequest offsetRequest; - /** - * The maximum number of requests to join the chat to return. - */ - public int limit; - - /** - * Default constructor for a function, which returns pending join requests in a chat. - * - *

Returns {@link ChatJoinRequests ChatJoinRequests}

- */ - public GetChatJoinRequests() { - } - - /** - * Creates a function, which returns pending join requests in a chat. - * - *

Returns {@link ChatJoinRequests ChatJoinRequests}

- * - * @param chatId Chat identifier. - * @param inviteLink Invite link for which to return join requests. If empty, all join requests will be returned. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. - * @param query A query to search for in the first names, last names and usernames of the users to return. - * @param offsetRequest A chat join request from which to return next requests; pass null to get results from the beginning. - * @param limit The maximum number of requests to join the chat to return. - */ - public GetChatJoinRequests(long chatId, String inviteLink, String query, ChatJoinRequest offsetRequest, int limit) { - this.chatId = chatId; - this.inviteLink = inviteLink; - this.query = query; - this.offsetRequest = offsetRequest; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -388428126; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns chat lists to which the chat can be added. This is an offline method. - * - *

Returns {@link ChatLists ChatLists}

- */ - public static class GetChatListsToAddChat extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which returns chat lists to which the chat can be added. This is an offline method. - * - *

Returns {@link ChatLists ChatLists}

- */ - public GetChatListsToAddChat() { - } - - /** - * Creates a function, which returns chat lists to which the chat can be added. This is an offline method. - * - *

Returns {@link ChatLists ChatLists}

- * - * @param chatId Chat identifier. - */ - public GetChatListsToAddChat(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 654956193; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a single member of a chat. - * - *

Returns {@link ChatMember ChatMember}

- */ - public static class GetChatMember extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Member identifier. - */ - public MessageSender memberId; - - /** - * Default constructor for a function, which returns information about a single member of a chat. - * - *

Returns {@link ChatMember ChatMember}

- */ - public GetChatMember() { - } - - /** - * Creates a function, which returns information about a single member of a chat. - * - *

Returns {@link ChatMember ChatMember}

- * - * @param chatId Chat identifier. - * @param memberId Member identifier. - */ - public GetChatMember(long chatId, MessageSender memberId) { - this.chatId = chatId; - this.memberId = memberId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -792636814; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the last message sent in a chat no later than the specified date. Returns a 404 error if such message doesn't exist. - * - *

Returns {@link Message Message}

- */ - public static class GetChatMessageByDate extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Point in time (Unix timestamp) relative to which to search for messages. - */ - public int date; - - /** - * Default constructor for a function, which returns the last message sent in a chat no later than the specified date. Returns a 404 error if such message doesn't exist. - * - *

Returns {@link Message Message}

- */ - public GetChatMessageByDate() { - } - - /** - * Creates a function, which returns the last message sent in a chat no later than the specified date. Returns a 404 error if such message doesn't exist. - * - *

Returns {@link Message Message}

- * - * @param chatId Chat identifier. - * @param date Point in time (Unix timestamp) relative to which to search for messages. - */ - public GetChatMessageByDate(long chatId, int date) { - this.chatId = chatId; - this.date = date; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1062564150; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about the next messages of the specified type in the chat split by days. Returns the results in reverse chronological order. Can return partial result for the last returned day. Behavior of this method depends on the value of the option "utc_time_offset". - * - *

Returns {@link MessageCalendar MessageCalendar}

- */ - public static class GetChatMessageCalendar extends Function { - /** - * Identifier of the chat in which to return information about messages. - */ - public long chatId; - /** - * Pass topic identifier to get the result only in specific topic; pass null to get the result in all topics; forum topics and message threads aren't supported. - */ - public MessageTopic topicId; - /** - * Filter for message content. Filters searchMessagesFilterEmpty, searchMessagesFilterMention, searchMessagesFilterUnreadMention, and searchMessagesFilterUnreadReaction are unsupported in this function. - */ - public SearchMessagesFilter filter; - /** - * The message identifier from which to return information about messages; use 0 to get results from the last message. - */ - public long fromMessageId; - - /** - * Default constructor for a function, which returns information about the next messages of the specified type in the chat split by days. Returns the results in reverse chronological order. Can return partial result for the last returned day. Behavior of this method depends on the value of the option "utc_time_offset". - * - *

Returns {@link MessageCalendar MessageCalendar}

- */ - public GetChatMessageCalendar() { - } - - /** - * Creates a function, which returns information about the next messages of the specified type in the chat split by days. Returns the results in reverse chronological order. Can return partial result for the last returned day. Behavior of this method depends on the value of the option "utc_time_offset". - * - *

Returns {@link MessageCalendar MessageCalendar}

- * - * @param chatId Identifier of the chat in which to return information about messages. - * @param topicId Pass topic identifier to get the result only in specific topic; pass null to get the result in all topics; forum topics and message threads aren't supported. - * @param filter Filter for message content. Filters searchMessagesFilterEmpty, searchMessagesFilterMention, searchMessagesFilterUnreadMention, and searchMessagesFilterUnreadReaction are unsupported in this function. - * @param fromMessageId The message identifier from which to return information about messages; use 0 to get results from the last message. - */ - public GetChatMessageCalendar(long chatId, MessageTopic topicId, SearchMessagesFilter filter, long fromMessageId) { - this.chatId = chatId; - this.topicId = topicId; - this.filter = filter; - this.fromMessageId = fromMessageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1644001372; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns approximate number of messages of the specified type in the chat or its topic. - * - *

Returns {@link Count Count}

- */ - public static class GetChatMessageCount extends Function { - /** - * Identifier of the chat in which to count messages. - */ - public long chatId; - /** - * Pass topic identifier to get number of messages only in specific topic; pass null to get number of messages in all topics; message threads aren't supported. - */ - public MessageTopic topicId; - /** - * Filter for message content; searchMessagesFilterEmpty is unsupported in this function. - */ - public SearchMessagesFilter filter; - /** - * Pass true to get the number of messages without sending network requests, or -1 if the number of messages is unknown locally. - */ - public boolean returnLocal; - - /** - * Default constructor for a function, which returns approximate number of messages of the specified type in the chat or its topic. - * - *

Returns {@link Count Count}

- */ - public GetChatMessageCount() { - } - - /** - * Creates a function, which returns approximate number of messages of the specified type in the chat or its topic. - * - *

Returns {@link Count Count}

- * - * @param chatId Identifier of the chat in which to count messages. - * @param topicId Pass topic identifier to get number of messages only in specific topic; pass null to get number of messages in all topics; message threads aren't supported. - * @param filter Filter for message content; searchMessagesFilterEmpty is unsupported in this function. - * @param returnLocal Pass true to get the number of messages without sending network requests, or -1 if the number of messages is unknown locally. - */ - public GetChatMessageCount(long chatId, MessageTopic topicId, SearchMessagesFilter filter, boolean returnLocal) { - this.chatId = chatId; - this.topicId = topicId; - this.filter = filter; - this.returnLocal = returnLocal; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1641001101; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns approximate 1-based position of a message among messages, which can be found by the specified filter in the chat and topic. Cannot be used in secret chats. - * - *

Returns {@link Count Count}

- */ - public static class GetChatMessagePosition extends Function { - /** - * Identifier of the chat in which to find message position. - */ - public long chatId; - /** - * Pass topic identifier to get position among messages only in specific topic; pass null to get position among all chat messages; message threads aren't supported. - */ - public MessageTopic topicId; - /** - * Filter for message content; searchMessagesFilterEmpty, searchMessagesFilterUnreadMention, searchMessagesFilterUnreadReaction, and searchMessagesFilterFailedToSend are unsupported in this function. - */ - public SearchMessagesFilter filter; - /** - * Message identifier. - */ - public long messageId; - - /** - * Default constructor for a function, which returns approximate 1-based position of a message among messages, which can be found by the specified filter in the chat and topic. Cannot be used in secret chats. - * - *

Returns {@link Count Count}

- */ - public GetChatMessagePosition() { - } - - /** - * Creates a function, which returns approximate 1-based position of a message among messages, which can be found by the specified filter in the chat and topic. Cannot be used in secret chats. - * - *

Returns {@link Count Count}

- * - * @param chatId Identifier of the chat in which to find message position. - * @param topicId Pass topic identifier to get position among messages only in specific topic; pass null to get position among all chat messages; message threads aren't supported. - * @param filter Filter for message content; searchMessagesFilterEmpty, searchMessagesFilterUnreadMention, searchMessagesFilterUnreadReaction, and searchMessagesFilterFailedToSend are unsupported in this function. - * @param messageId Message identifier. - */ - public GetChatMessagePosition(long chatId, MessageTopic topicId, SearchMessagesFilter filter, long messageId) { - this.chatId = chatId; - this.topicId = topicId; - this.filter = filter; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1468174577; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of chats with non-default notification settings for new messages. - * - *

Returns {@link Chats Chats}

- */ - public static class GetChatNotificationSettingsExceptions extends Function { - /** - * If specified, only chats from the scope will be returned; pass null to return chats from all scopes. - */ - public NotificationSettingsScope scope; - /** - * Pass true to include in the response chats with only non-default sound. - */ - public boolean compareSound; - - /** - * Default constructor for a function, which returns the list of chats with non-default notification settings for new messages. - * - *

Returns {@link Chats Chats}

- */ - public GetChatNotificationSettingsExceptions() { - } - - /** - * Creates a function, which returns the list of chats with non-default notification settings for new messages. - * - *

Returns {@link Chats Chats}

- * - * @param scope If specified, only chats from the scope will be returned; pass null to return chats from all scopes. - * @param compareSound Pass true to include in the response chats with only non-default sound. - */ - public GetChatNotificationSettingsExceptions(NotificationSettingsScope scope, boolean compareSound) { - this.scope = scope; - this.compareSound = compareSound; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 201199121; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the user who will become the owner of the chat after 7 days if the current user does not return to the supergroup or channel during that period or immediately for basic groups; requires owner privileges in the chat. Available only for supergroups and channel chats. - * - *

Returns {@link User User}

- */ - public static class GetChatOwnerAfterLeaving extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which returns the user who will become the owner of the chat after 7 days if the current user does not return to the supergroup or channel during that period or immediately for basic groups; requires owner privileges in the chat. Available only for supergroups and channel chats. - * - *

Returns {@link User User}

- */ - public GetChatOwnerAfterLeaving() { - } - - /** - * Creates a function, which returns the user who will become the owner of the chat after 7 days if the current user does not return to the supergroup or channel during that period or immediately for basic groups; requires owner privileges in the chat. Available only for supergroups and channel chats. - * - *

Returns {@link User User}

- * - * @param chatId Chat identifier. - */ - public GetChatOwnerAfterLeaving(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1637776102; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a newest pinned message in the chat. Returns a 404 error if the message doesn't exist. - * - *

Returns {@link Message Message}

- */ - public static class GetChatPinnedMessage extends Function { - /** - * Identifier of the chat the message belongs to. - */ - public long chatId; - - /** - * Default constructor for a function, which returns information about a newest pinned message in the chat. Returns a 404 error if the message doesn't exist. - * - *

Returns {@link Message Message}

- */ - public GetChatPinnedMessage() { - } - - /** - * Creates a function, which returns information about a newest pinned message in the chat. Returns a 404 error if the message doesn't exist. - * - *

Returns {@link Message Message}

- * - * @param chatId Identifier of the chat the message belongs to. - */ - public GetChatPinnedMessage(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 359865008; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of stories that posted by the given chat to its chat page. If fromStoryId == 0, then pinned stories are returned first. Then, stories are returned in reverse chronological order (i.e., in order of decreasing storyId). For optimal performance, the number of returned stories is chosen by TDLib. - * - *

Returns {@link Stories Stories}

- */ - public static class GetChatPostedToChatPageStories extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the story starting from which stories must be returned; use 0 to get results from pinned and the newest story. - */ - public int fromStoryId; - /** - * The maximum number of stories to be returned. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which returns the list of stories that posted by the given chat to its chat page. If fromStoryId == 0, then pinned stories are returned first. Then, stories are returned in reverse chronological order (i.e., in order of decreasing storyId). For optimal performance, the number of returned stories is chosen by TDLib. - * - *

Returns {@link Stories Stories}

- */ - public GetChatPostedToChatPageStories() { - } - - /** - * Creates a function, which returns the list of stories that posted by the given chat to its chat page. If fromStoryId == 0, then pinned stories are returned first. Then, stories are returned in reverse chronological order (i.e., in order of decreasing storyId). For optimal performance, the number of returned stories is chosen by TDLib. - * - *

Returns {@link Stories Stories}

- * - * @param chatId Chat identifier. - * @param fromStoryId Identifier of the story starting from which stories must be returned; use 0 to get results from pinned and the newest story. - * @param limit The maximum number of stories to be returned. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - */ - public GetChatPostedToChatPageStories(long chatId, int fromStoryId, int limit) { - this.chatId = chatId; - this.fromStoryId = fromStoryId; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -46414037; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns detailed revenue statistics about a chat. Currently, this method can be used only for channels if supergroupFullInfo.canGetRevenueStatistics == true or bots if userFullInfo.botInfo.canGetRevenueStatistics == true. - * - *

Returns {@link ChatRevenueStatistics ChatRevenueStatistics}

- */ - public static class GetChatRevenueStatistics extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Pass true if a dark theme is used by the application. - */ - public boolean isDark; - - /** - * Default constructor for a function, which returns detailed revenue statistics about a chat. Currently, this method can be used only for channels if supergroupFullInfo.canGetRevenueStatistics == true or bots if userFullInfo.botInfo.canGetRevenueStatistics == true. - * - *

Returns {@link ChatRevenueStatistics ChatRevenueStatistics}

- */ - public GetChatRevenueStatistics() { - } - - /** - * Creates a function, which returns detailed revenue statistics about a chat. Currently, this method can be used only for channels if supergroupFullInfo.canGetRevenueStatistics == true or bots if userFullInfo.botInfo.canGetRevenueStatistics == true. - * - *

Returns {@link ChatRevenueStatistics ChatRevenueStatistics}

- * - * @param chatId Chat identifier. - * @param isDark Pass true if a dark theme is used by the application. - */ - public GetChatRevenueStatistics(long chatId, boolean isDark) { - this.chatId = chatId; - this.isDark = isDark; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 701995836; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of revenue transactions for a chat. Currently, this method can be used only for channels if supergroupFullInfo.canGetRevenueStatistics == true or bots if userFullInfo.botInfo.canGetRevenueStatistics == true. - * - *

Returns {@link ChatRevenueTransactions ChatRevenueTransactions}

- */ - public static class GetChatRevenueTransactions extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Offset of the first transaction to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of transactions to be returned; up to 100. - */ - public int limit; - - /** - * Default constructor for a function, which returns the list of revenue transactions for a chat. Currently, this method can be used only for channels if supergroupFullInfo.canGetRevenueStatistics == true or bots if userFullInfo.botInfo.canGetRevenueStatistics == true. - * - *

Returns {@link ChatRevenueTransactions ChatRevenueTransactions}

- */ - public GetChatRevenueTransactions() { - } - - /** - * Creates a function, which returns the list of revenue transactions for a chat. Currently, this method can be used only for channels if supergroupFullInfo.canGetRevenueStatistics == true or bots if userFullInfo.botInfo.canGetRevenueStatistics == true. - * - *

Returns {@link ChatRevenueTransactions ChatRevenueTransactions}

- * - * @param chatId Chat identifier. - * @param offset Offset of the first transaction to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of transactions to be returned; up to 100. - */ - public GetChatRevenueTransactions(long chatId, String offset, int limit) { - this.chatId = chatId; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1120110117; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a URL for chat revenue withdrawal; requires owner privileges in the channel chat or the bot. Currently, this method can be used only if getOption("can_withdraw_chat_revenue") for channels with supergroupFullInfo.canGetRevenueStatistics == true or bots with userFullInfo.botInfo.canGetRevenueStatistics == true. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public static class GetChatRevenueWithdrawalUrl extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * The 2-step verification password of the current user. - */ - public String password; - - /** - * Default constructor for a function, which returns a URL for chat revenue withdrawal; requires owner privileges in the channel chat or the bot. Currently, this method can be used only if getOption("can_withdraw_chat_revenue") for channels with supergroupFullInfo.canGetRevenueStatistics == true or bots with userFullInfo.botInfo.canGetRevenueStatistics == true. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public GetChatRevenueWithdrawalUrl() { - } - - /** - * Creates a function, which returns a URL for chat revenue withdrawal; requires owner privileges in the channel chat or the bot. Currently, this method can be used only if getOption("can_withdraw_chat_revenue") for channels with supergroupFullInfo.canGetRevenueStatistics == true or bots with userFullInfo.botInfo.canGetRevenueStatistics == true. - * - *

Returns {@link HttpUrl HttpUrl}

- * - * @param chatId Chat identifier. - * @param password The 2-step verification password of the current user. - */ - public GetChatRevenueWithdrawalUrl(long chatId, String password) { - this.chatId = chatId; - this.password = password; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 506595104; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns all scheduled messages in a chat. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). - * - *

Returns {@link Messages Messages}

- */ - public static class GetChatScheduledMessages extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which returns all scheduled messages in a chat. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). - * - *

Returns {@link Messages Messages}

- */ - public GetChatScheduledMessages() { - } - - /** - * Creates a function, which returns all scheduled messages in a chat. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). - * - *

Returns {@link Messages Messages}

- * - * @param chatId Chat identifier. - */ - public GetChatScheduledMessages(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -549638149; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns approximate number of chats similar to the given chat. - * - *

Returns {@link Count Count}

- */ - public static class GetChatSimilarChatCount extends Function { - /** - * Identifier of the target chat; must be an identifier of a channel chat. - */ - public long chatId; - /** - * Pass true to get the number of chats without sending network requests, or -1 if the number of chats is unknown locally. - */ - public boolean returnLocal; - - /** - * Default constructor for a function, which returns approximate number of chats similar to the given chat. - * - *

Returns {@link Count Count}

- */ - public GetChatSimilarChatCount() { - } - - /** - * Creates a function, which returns approximate number of chats similar to the given chat. - * - *

Returns {@link Count Count}

- * - * @param chatId Identifier of the target chat; must be an identifier of a channel chat. - * @param returnLocal Pass true to get the number of chats without sending network requests, or -1 if the number of chats is unknown locally. - */ - public GetChatSimilarChatCount(long chatId, boolean returnLocal) { - this.chatId = chatId; - this.returnLocal = returnLocal; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1178506894; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a list of chats similar to the given chat. - * - *

Returns {@link Chats Chats}

- */ - public static class GetChatSimilarChats extends Function { - /** - * Identifier of the target chat; must be an identifier of a channel chat. - */ - public long chatId; - - /** - * Default constructor for a function, which returns a list of chats similar to the given chat. - * - *

Returns {@link Chats Chats}

- */ - public GetChatSimilarChats() { - } - - /** - * Creates a function, which returns a list of chats similar to the given chat. - * - *

Returns {@link Chats Chats}

- * - * @param chatId Identifier of the target chat; must be an identifier of a channel chat. - */ - public GetChatSimilarChats(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1152348285; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns sparse positions of messages of the specified type in the chat to be used for shared media scroll implementation. Returns the results in reverse chronological order (i.e., in order of decreasing messageId). Cannot be used in secret chats or with searchMessagesFilterFailedToSend filter without an enabled message database. - * - *

Returns {@link MessagePositions MessagePositions}

- */ - public static class GetChatSparseMessagePositions extends Function { - /** - * Identifier of the chat in which to return information about message positions. - */ - public long chatId; - /** - * Filter for message content. Filters searchMessagesFilterEmpty, searchMessagesFilterMention, searchMessagesFilterUnreadMention, and searchMessagesFilterUnreadReaction are unsupported in this function. - */ - public SearchMessagesFilter filter; - /** - * The message identifier from which to return information about message positions. - */ - public long fromMessageId; - /** - * The expected number of message positions to be returned; 50-2000. A smaller number of positions can be returned, if there are not enough appropriate messages. - */ - public int limit; - /** - * If not 0, only messages in the specified Saved Messages topic will be considered; pass 0 to consider all messages, or for chats other than Saved Messages. - */ - public long savedMessagesTopicId; - - /** - * Default constructor for a function, which returns sparse positions of messages of the specified type in the chat to be used for shared media scroll implementation. Returns the results in reverse chronological order (i.e., in order of decreasing messageId). Cannot be used in secret chats or with searchMessagesFilterFailedToSend filter without an enabled message database. - * - *

Returns {@link MessagePositions MessagePositions}

- */ - public GetChatSparseMessagePositions() { - } - - /** - * Creates a function, which returns sparse positions of messages of the specified type in the chat to be used for shared media scroll implementation. Returns the results in reverse chronological order (i.e., in order of decreasing messageId). Cannot be used in secret chats or with searchMessagesFilterFailedToSend filter without an enabled message database. - * - *

Returns {@link MessagePositions MessagePositions}

- * - * @param chatId Identifier of the chat in which to return information about message positions. - * @param filter Filter for message content. Filters searchMessagesFilterEmpty, searchMessagesFilterMention, searchMessagesFilterUnreadMention, and searchMessagesFilterUnreadReaction are unsupported in this function. - * @param fromMessageId The message identifier from which to return information about message positions. - * @param limit The expected number of message positions to be returned; 50-2000. A smaller number of positions can be returned, if there are not enough appropriate messages. - * @param savedMessagesTopicId If not 0, only messages in the specified Saved Messages topic will be considered; pass 0 to consider all messages, or for chats other than Saved Messages. - */ - public GetChatSparseMessagePositions(long chatId, SearchMessagesFilter filter, long fromMessageId, int limit, long savedMessagesTopicId) { - this.chatId = chatId; - this.filter = filter; - this.fromMessageId = fromMessageId; - this.limit = limit; - this.savedMessagesTopicId = savedMessagesTopicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 994389757; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns sponsored messages to be shown in a chat; for channel chats and chats with bots only. - * - *

Returns {@link SponsoredMessages SponsoredMessages}

- */ - public static class GetChatSponsoredMessages extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - - /** - * Default constructor for a function, which returns sponsored messages to be shown in a chat; for channel chats and chats with bots only. - * - *

Returns {@link SponsoredMessages SponsoredMessages}

- */ - public GetChatSponsoredMessages() { - } - - /** - * Creates a function, which returns sponsored messages to be shown in a chat; for channel chats and chats with bots only. - * - *

Returns {@link SponsoredMessages SponsoredMessages}

- * - * @param chatId Identifier of the chat. - */ - public GetChatSponsoredMessages(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1353203864; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns detailed statistics about a chat. Currently, this method can be used only for supergroups and channels. Can be used only if supergroupFullInfo.canGetStatistics == true. - * - *

Returns {@link ChatStatistics ChatStatistics}

- */ - public static class GetChatStatistics extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Pass true if a dark theme is used by the application. - */ - public boolean isDark; - - /** - * Default constructor for a function, which returns detailed statistics about a chat. Currently, this method can be used only for supergroups and channels. Can be used only if supergroupFullInfo.canGetStatistics == true. - * - *

Returns {@link ChatStatistics ChatStatistics}

- */ - public GetChatStatistics() { - } - - /** - * Creates a function, which returns detailed statistics about a chat. Currently, this method can be used only for supergroups and channels. Can be used only if supergroupFullInfo.canGetStatistics == true. - * - *

Returns {@link ChatStatistics ChatStatistics}

- * - * @param chatId Chat identifier. - * @param isDark Pass true if a dark theme is used by the application. - */ - public GetChatStatistics(long chatId, boolean isDark) { - this.chatId = chatId; - this.isDark = isDark; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 327057816; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of story albums owned by the given chat. - * - *

Returns {@link StoryAlbums StoryAlbums}

- */ - public static class GetChatStoryAlbums extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which returns the list of story albums owned by the given chat. - * - *

Returns {@link StoryAlbums StoryAlbums}

- */ - public GetChatStoryAlbums() { - } - - /** - * Creates a function, which returns the list of story albums owned by the given chat. - * - *

Returns {@link StoryAlbums StoryAlbums}

- * - * @param chatId Chat identifier. - */ - public GetChatStoryAlbums(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1559582892; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns interactions with a story posted in a chat. Can be used only if story is posted on behalf of a chat and the user is an administrator in the chat. - * - *

Returns {@link StoryInteractions StoryInteractions}

- */ - public static class GetChatStoryInteractions extends Function { - /** - * The identifier of the poster of the story. - */ - public long storyPosterChatId; - /** - * Story identifier. - */ - public int storyId; - /** - * Pass the default heart reaction or a suggested reaction type to receive only interactions with the specified reaction type; pass null to receive all interactions; reactionTypePaid isn't supported. - */ - public ReactionType reactionType; - /** - * Pass true to get forwards and reposts first, then reactions, then other views; pass false to get interactions sorted just by interaction date. - */ - public boolean preferForwards; - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of story interactions to return. - */ - public int limit; - - /** - * Default constructor for a function, which returns interactions with a story posted in a chat. Can be used only if story is posted on behalf of a chat and the user is an administrator in the chat. - * - *

Returns {@link StoryInteractions StoryInteractions}

- */ - public GetChatStoryInteractions() { - } - - /** - * Creates a function, which returns interactions with a story posted in a chat. Can be used only if story is posted on behalf of a chat and the user is an administrator in the chat. - * - *

Returns {@link StoryInteractions StoryInteractions}

- * - * @param storyPosterChatId The identifier of the poster of the story. - * @param storyId Story identifier. - * @param reactionType Pass the default heart reaction or a suggested reaction type to receive only interactions with the specified reaction type; pass null to receive all interactions; reactionTypePaid isn't supported. - * @param preferForwards Pass true to get forwards and reposts first, then reactions, then other views; pass false to get interactions sorted just by interaction date. - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of story interactions to return. - */ - public GetChatStoryInteractions(long storyPosterChatId, int storyId, ReactionType reactionType, boolean preferForwards, String offset, int limit) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - this.reactionType = reactionType; - this.preferForwards = preferForwards; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 354545268; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an ordered list of chats from the beginning of a chat list. For informational purposes only. Use loadChats and updates processing instead to maintain chat lists in a consistent state. - * - *

Returns {@link Chats Chats}

- */ - public static class GetChats extends Function { - /** - * The chat list in which to return chats; pass null to get chats from the main chat list. - */ - public ChatList chatList; - /** - * The maximum number of chats to be returned. - */ - public int limit; - - /** - * Default constructor for a function, which returns an ordered list of chats from the beginning of a chat list. For informational purposes only. Use loadChats and updates processing instead to maintain chat lists in a consistent state. - * - *

Returns {@link Chats Chats}

- */ - public GetChats() { - } - - /** - * Creates a function, which returns an ordered list of chats from the beginning of a chat list. For informational purposes only. Use loadChats and updates processing instead to maintain chat lists in a consistent state. - * - *

Returns {@link Chats Chats}

- * - * @param chatList The chat list in which to return chats; pass null to get chats from the main chat list. - * @param limit The maximum number of chats to be returned. - */ - public GetChats(ChatList chatList, int limit) { - this.chatList = chatList; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -972768574; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns identifiers of chats from a chat folder, suitable for adding to a chat folder invite link. - * - *

Returns {@link Chats Chats}

- */ - public static class GetChatsForChatFolderInviteLink extends Function { - /** - * Chat folder identifier. - */ - public int chatFolderId; - - /** - * Default constructor for a function, which returns identifiers of chats from a chat folder, suitable for adding to a chat folder invite link. - * - *

Returns {@link Chats Chats}

- */ - public GetChatsForChatFolderInviteLink() { - } - - /** - * Creates a function, which returns identifiers of chats from a chat folder, suitable for adding to a chat folder invite link. - * - *

Returns {@link Chats Chats}

- * - * @param chatFolderId Chat folder identifier. - */ - public GetChatsForChatFolderInviteLink(int chatFolderId) { - this.chatFolderId = chatFolderId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1873561929; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns supergroup and channel chats in which the current user has the right to post stories. The chats must be rechecked with canPostStory before actually trying to post a story there. - * - *

Returns {@link Chats Chats}

- */ - public static class GetChatsToPostStories extends Function { - - /** - * Default constructor for a function, which returns supergroup and channel chats in which the current user has the right to post stories. The chats must be rechecked with canPostStory before actually trying to post a story there. - * - *

Returns {@link Chats Chats}

- */ - public GetChatsToPostStories() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1893901427; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns all close friends of the current user. - * - *

Returns {@link Users Users}

- */ - public static class GetCloseFriends extends Function { - - /** - * Default constructor for a function, which returns all close friends of the current user. - * - *

Returns {@link Users Users}

- */ - public GetCloseFriends() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1445628722; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a given collectible item that was purchased at https://fragment.com. - * - *

Returns {@link CollectibleItemInfo CollectibleItemInfo}

- */ - public static class GetCollectibleItemInfo extends Function { - /** - * Type of the collectible item. The item must be used by a user and must be visible to the current user. - */ - public CollectibleItemType type; - - /** - * Default constructor for a function, which returns information about a given collectible item that was purchased at https://fragment.com. - * - *

Returns {@link CollectibleItemInfo CollectibleItemInfo}

- */ - public GetCollectibleItemInfo() { - } - - /** - * Creates a function, which returns information about a given collectible item that was purchased at https://fragment.com. - * - *

Returns {@link CollectibleItemInfo CollectibleItemInfo}

- * - * @param type Type of the collectible item. The item must be used by a user and must be visible to the current user. - */ - public GetCollectibleItemInfo(CollectibleItemType type) { - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -217797238; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of commands supported by the bot for the given user scope and language; for bots only. - * - *

Returns {@link BotCommands BotCommands}

- */ - public static class GetCommands extends Function { - /** - * The scope to which the commands are relevant; pass null to get commands in the default bot command scope. - */ - public BotCommandScope scope; - /** - * A two-letter ISO 639-1 language code or an empty string. - */ - public String languageCode; - - /** - * Default constructor for a function, which returns the list of commands supported by the bot for the given user scope and language; for bots only. - * - *

Returns {@link BotCommands BotCommands}

- */ - public GetCommands() { - } - - /** - * Creates a function, which returns the list of commands supported by the bot for the given user scope and language; for bots only. - * - *

Returns {@link BotCommands BotCommands}

- * - * @param scope The scope to which the commands are relevant; pass null to get commands in the default bot command scope. - * @param languageCode A two-letter ISO 639-1 language code or an empty string. - */ - public GetCommands(BotCommandScope scope, String languageCode) { - this.scope = scope; - this.languageCode = languageCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1488621559; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an affiliate program that was connected to the given affiliate by identifier of the bot that created the program. - * - *

Returns {@link ConnectedAffiliateProgram ConnectedAffiliateProgram}

- */ - public static class GetConnectedAffiliateProgram extends Function { - /** - * The affiliate to which the affiliate program will be connected. - */ - public AffiliateType affiliate; - /** - * Identifier of the bot that created the program. - */ - public long botUserId; - - /** - * Default constructor for a function, which returns an affiliate program that was connected to the given affiliate by identifier of the bot that created the program. - * - *

Returns {@link ConnectedAffiliateProgram ConnectedAffiliateProgram}

- */ - public GetConnectedAffiliateProgram() { - } - - /** - * Creates a function, which returns an affiliate program that was connected to the given affiliate by identifier of the bot that created the program. - * - *

Returns {@link ConnectedAffiliateProgram ConnectedAffiliateProgram}

- * - * @param affiliate The affiliate to which the affiliate program will be connected. - * @param botUserId Identifier of the bot that created the program. - */ - public GetConnectedAffiliateProgram(AffiliateType affiliate, long botUserId) { - this.affiliate = affiliate; - this.botUserId = botUserId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1755191440; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns affiliate programs that were connected to the given affiliate. - * - *

Returns {@link ConnectedAffiliatePrograms ConnectedAffiliatePrograms}

- */ - public static class GetConnectedAffiliatePrograms extends Function { - /** - * The affiliate to which the affiliate program were connected. - */ - public AffiliateType affiliate; - /** - * Offset of the first affiliate program to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of affiliate programs to return. - */ - public int limit; - - /** - * Default constructor for a function, which returns affiliate programs that were connected to the given affiliate. - * - *

Returns {@link ConnectedAffiliatePrograms ConnectedAffiliatePrograms}

- */ - public GetConnectedAffiliatePrograms() { - } - - /** - * Creates a function, which returns affiliate programs that were connected to the given affiliate. - * - *

Returns {@link ConnectedAffiliatePrograms ConnectedAffiliatePrograms}

- * - * @param affiliate The affiliate to which the affiliate program were connected. - * @param offset Offset of the first affiliate program to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of affiliate programs to return. - */ - public GetConnectedAffiliatePrograms(AffiliateType affiliate, String offset, int limit) { - this.affiliate = affiliate; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1960029582; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns all website where the current user used Telegram to log in. - * - *

Returns {@link ConnectedWebsites ConnectedWebsites}

- */ - public static class GetConnectedWebsites extends Function { - - /** - * Default constructor for a function, which returns all website where the current user used Telegram to log in. - * - *

Returns {@link ConnectedWebsites ConnectedWebsites}

- */ - public GetConnectedWebsites() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -170536110; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns all contacts of the user. - * - *

Returns {@link Users Users}

- */ - public static class GetContacts extends Function { - - /** - * Default constructor for a function, which returns all contacts of the user. - * - *

Returns {@link Users Users}

- */ - public GetContacts() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1417722768; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about existing countries. Can be called before authorization. - * - *

Returns {@link Countries Countries}

- */ - public static class GetCountries extends Function { - - /** - * Default constructor for a function, which returns information about existing countries. Can be called before authorization. - * - *

Returns {@link Countries Countries}

- */ - public GetCountries() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -51902050; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Uses the current IP address to find the current country. Returns two-letter ISO 3166-1 alpha-2 country code. Can be called before authorization. - * - *

Returns {@link Text Text}

- */ - public static class GetCountryCode extends Function { - - /** - * Default constructor for a function, which uses the current IP address to find the current country. Returns two-letter ISO 3166-1 alpha-2 country code. Can be called before authorization. - * - *

Returns {@link Text Text}

- */ - public GetCountryCode() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1540593906; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an emoji for the given country. Returns an empty string on failure. Can be called synchronously. - * - *

Returns {@link Text Text}

- */ - public static class GetCountryFlagEmoji extends Function { - /** - * A two-letter ISO 3166-1 alpha-2 country code as received from getCountries. - */ - public String countryCode; - - /** - * Default constructor for a function, which returns an emoji for the given country. Returns an empty string on failure. Can be called synchronously. - * - *

Returns {@link Text Text}

- */ - public GetCountryFlagEmoji() { - } - - /** - * Creates a function, which returns an emoji for the given country. Returns an empty string on failure. Can be called synchronously. - * - *

Returns {@link Text Text}

- * - * @param countryCode A two-letter ISO 3166-1 alpha-2 country code as received from getCountries. - */ - public GetCountryFlagEmoji(String countryCode) { - this.countryCode = countryCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 981871098; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a list of public chats of the specified type, owned by the user. - * - *

Returns {@link Chats Chats}

- */ - public static class GetCreatedPublicChats extends Function { - /** - * Type of the public chats to return. - */ - public PublicChatType type; - - /** - * Default constructor for a function, which returns a list of public chats of the specified type, owned by the user. - * - *

Returns {@link Chats Chats}

- */ - public GetCreatedPublicChats() { - } - - /** - * Creates a function, which returns a list of public chats of the specified type, owned by the user. - * - *

Returns {@link Chats Chats}

- * - * @param type Type of the public chats to return. - */ - public GetCreatedPublicChats(PublicChatType type) { - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 710354415; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns all updates needed to restore current TDLib state, i.e. all actual updateAuthorizationState/updateUser/updateNewChat and others. This is especially useful if TDLib is run in a separate process. Can be called before initialization. - * - *

Returns {@link Updates Updates}

- */ - public static class GetCurrentState extends Function { - - /** - * Default constructor for a function, which returns all updates needed to restore current TDLib state, i.e. all actual updateAuthorizationState/updateUser/updateNewChat and others. This is especially useful if TDLib is run in a separate process. Can be called before initialization. - * - *

Returns {@link Updates Updates}

- */ - public GetCurrentState() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1191417719; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the current weather in the given location. - * - *

Returns {@link CurrentWeather CurrentWeather}

- */ - public static class GetCurrentWeather extends Function { - /** - * The location. - */ - public Location location; - - /** - * Default constructor for a function, which returns the current weather in the given location. - * - *

Returns {@link CurrentWeather CurrentWeather}

- */ - public GetCurrentWeather() { - } - - /** - * Creates a function, which returns the current weather in the given location. - * - *

Returns {@link CurrentWeather CurrentWeather}

- * - * @param location The location. - */ - public GetCurrentWeather(Location location) { - this.location = location; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1965384759; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns TGS stickers with generic animations for custom emoji reactions. - * - *

Returns {@link Stickers Stickers}

- */ - public static class GetCustomEmojiReactionAnimations extends Function { - - /** - * Default constructor for a function, which returns TGS stickers with generic animations for custom emoji reactions. - * - *

Returns {@link Stickers Stickers}

- */ - public GetCustomEmojiReactionAnimations() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1232375250; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of custom emoji stickers by their identifiers. Stickers are returned in arbitrary order. Only found stickers are returned. - * - *

Returns {@link Stickers Stickers}

- */ - public static class GetCustomEmojiStickers extends Function { - /** - * Identifiers of custom emoji stickers. At most 200 custom emoji stickers can be received simultaneously. - */ - public long[] customEmojiIds; - - /** - * Default constructor for a function, which returns the list of custom emoji stickers by their identifiers. Stickers are returned in arbitrary order. Only found stickers are returned. - * - *

Returns {@link Stickers Stickers}

- */ - public GetCustomEmojiStickers() { - } - - /** - * Creates a function, which returns the list of custom emoji stickers by their identifiers. Stickers are returned in arbitrary order. Only found stickers are returned. - * - *

Returns {@link Stickers Stickers}

- * - * @param customEmojiIds Identifiers of custom emoji stickers. At most 200 custom emoji stickers can be received simultaneously. - */ - public GetCustomEmojiStickers(long[] customEmojiIds) { - this.customEmojiIds = customEmojiIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2127427955; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns database statistics. - * - *

Returns {@link DatabaseStatistics DatabaseStatistics}

- */ - public static class GetDatabaseStatistics extends Function { - - /** - * Default constructor for a function, which returns database statistics. - * - *

Returns {@link DatabaseStatistics DatabaseStatistics}

- */ - public GetDatabaseStatistics() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1942760263; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a tg:// deep link. Use "tg://need_update_for_some_feature" or "tg:someUnsupportedFeature" for testing. Returns a 404 error for unknown links. Can be called before authorization. - * - *

Returns {@link DeepLinkInfo DeepLinkInfo}

- */ - public static class GetDeepLinkInfo extends Function { - /** - * The link. - */ - public String link; - - /** - * Default constructor for a function, which returns information about a tg:// deep link. Use "tg://need_update_for_some_feature" or "tg:someUnsupportedFeature" for testing. Returns a 404 error for unknown links. Can be called before authorization. - * - *

Returns {@link DeepLinkInfo DeepLinkInfo}

- */ - public GetDeepLinkInfo() { - } - - /** - * Creates a function, which returns information about a tg:// deep link. Use "tg://need_update_for_some_feature" or "tg:someUnsupportedFeature" for testing. Returns a 404 error for unknown links. Can be called before authorization. - * - *

Returns {@link DeepLinkInfo DeepLinkInfo}

- * - * @param link The link. - */ - public GetDeepLinkInfo(String link) { - this.link = link; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 680673150; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns default list of custom emoji stickers for reply background. - * - *

Returns {@link Stickers Stickers}

- */ - public static class GetDefaultBackgroundCustomEmojiStickers extends Function { - - /** - * Default constructor for a function, which returns default list of custom emoji stickers for reply background. - * - *

Returns {@link Stickers Stickers}

- */ - public GetDefaultBackgroundCustomEmojiStickers() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 485910542; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns default emoji statuses for chats. - * - *

Returns {@link EmojiStatusCustomEmojis EmojiStatusCustomEmojis}

- */ - public static class GetDefaultChatEmojiStatuses extends Function { - - /** - * Default constructor for a function, which returns default emoji statuses for chats. - * - *

Returns {@link EmojiStatusCustomEmojis EmojiStatusCustomEmojis}

- */ - public GetDefaultChatEmojiStatuses() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1553698018; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns default list of custom emoji stickers for placing on a chat photo. - * - *

Returns {@link Stickers Stickers}

- */ - public static class GetDefaultChatPhotoCustomEmojiStickers extends Function { - - /** - * Default constructor for a function, which returns default list of custom emoji stickers for placing on a chat photo. - * - *

Returns {@link Stickers Stickers}

- */ - public GetDefaultChatPhotoCustomEmojiStickers() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -376342683; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns default emoji statuses for self status. - * - *

Returns {@link EmojiStatusCustomEmojis EmojiStatusCustomEmojis}

- */ - public static class GetDefaultEmojiStatuses extends Function { - - /** - * Default constructor for a function, which returns default emoji statuses for self status. - * - *

Returns {@link EmojiStatusCustomEmojis EmojiStatusCustomEmojis}

- */ - public GetDefaultEmojiStatuses() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -539392025; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns default message auto-delete time setting for new chats. - * - *

Returns {@link MessageAutoDeleteTime MessageAutoDeleteTime}

- */ - public static class GetDefaultMessageAutoDeleteTime extends Function { - - /** - * Default constructor for a function, which returns default message auto-delete time setting for new chats. - * - *

Returns {@link MessageAutoDeleteTime MessageAutoDeleteTime}

- */ - public GetDefaultMessageAutoDeleteTime() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -450857574; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns default list of custom emoji stickers for placing on a profile photo. - * - *

Returns {@link Stickers Stickers}

- */ - public static class GetDefaultProfilePhotoCustomEmojiStickers extends Function { - - /** - * Default constructor for a function, which returns default list of custom emoji stickers for placing on a profile photo. - * - *

Returns {@link Stickers Stickers}

- */ - public GetDefaultProfilePhotoCustomEmojiStickers() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1280041655; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about the topic in a channel direct messages chat administered by the current user. - * - *

Returns {@link DirectMessagesChatTopic DirectMessagesChatTopic}

- */ - public static class GetDirectMessagesChatTopic extends Function { - /** - * Chat identifier of the channel direct messages chat. - */ - public long chatId; - /** - * Identifier of the topic to get. - */ - public long topicId; - - /** - * Default constructor for a function, which returns information about the topic in a channel direct messages chat administered by the current user. - * - *

Returns {@link DirectMessagesChatTopic DirectMessagesChatTopic}

- */ - public GetDirectMessagesChatTopic() { - } - - /** - * Creates a function, which returns information about the topic in a channel direct messages chat administered by the current user. - * - *

Returns {@link DirectMessagesChatTopic DirectMessagesChatTopic}

- * - * @param chatId Chat identifier of the channel direct messages chat. - * @param topicId Identifier of the topic to get. - */ - public GetDirectMessagesChatTopic(long chatId, long topicId) { - this.chatId = chatId; - this.topicId = topicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1990530052; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns messages in the topic in a channel direct messages chat administered by the current user. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). - * - *

Returns {@link Messages Messages}

- */ - public static class GetDirectMessagesChatTopicHistory extends Function { - /** - * Chat identifier of the channel direct messages chat. - */ - public long chatId; - /** - * Identifier of the topic which messages will be fetched. - */ - public long topicId; - /** - * Identifier of the message starting from which messages must be fetched; use 0 to get results from the last message. - */ - public long fromMessageId; - /** - * Specify 0 to get results from exactly the message fromMessageId or a negative number from -99 to -1 to get additionally -offset newer messages. - */ - public int offset; - /** - * The maximum number of messages to be returned; must be positive and can't be greater than 100. If the offset is negative, then the limit must be greater than or equal to -offset. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which returns messages in the topic in a channel direct messages chat administered by the current user. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). - * - *

Returns {@link Messages Messages}

- */ - public GetDirectMessagesChatTopicHistory() { - } - - /** - * Creates a function, which returns messages in the topic in a channel direct messages chat administered by the current user. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). - * - *

Returns {@link Messages Messages}

- * - * @param chatId Chat identifier of the channel direct messages chat. - * @param topicId Identifier of the topic which messages will be fetched. - * @param fromMessageId Identifier of the message starting from which messages must be fetched; use 0 to get results from the last message. - * @param offset Specify 0 to get results from exactly the message fromMessageId or a negative number from -99 to -1 to get additionally -offset newer messages. - * @param limit The maximum number of messages to be returned; must be positive and can't be greater than 100. If the offset is negative, then the limit must be greater than or equal to -offset. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public GetDirectMessagesChatTopicHistory(long chatId, long topicId, long fromMessageId, int offset, int limit) { - this.chatId = chatId; - this.topicId = topicId; - this.fromMessageId = fromMessageId; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1035221188; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the last message sent in the topic in a channel direct messages chat administered by the current user no later than the specified date. - * - *

Returns {@link Message Message}

- */ - public static class GetDirectMessagesChatTopicMessageByDate extends Function { - /** - * Chat identifier of the channel direct messages chat. - */ - public long chatId; - /** - * Identifier of the topic which messages will be fetched. - */ - public long topicId; - /** - * Point in time (Unix timestamp) relative to which to search for messages. - */ - public int date; - - /** - * Default constructor for a function, which returns the last message sent in the topic in a channel direct messages chat administered by the current user no later than the specified date. - * - *

Returns {@link Message Message}

- */ - public GetDirectMessagesChatTopicMessageByDate() { - } - - /** - * Creates a function, which returns the last message sent in the topic in a channel direct messages chat administered by the current user no later than the specified date. - * - *

Returns {@link Message Message}

- * - * @param chatId Chat identifier of the channel direct messages chat. - * @param topicId Identifier of the topic which messages will be fetched. - * @param date Point in time (Unix timestamp) relative to which to search for messages. - */ - public GetDirectMessagesChatTopicMessageByDate(long chatId, long topicId, int date) { - this.chatId = chatId; - this.topicId = topicId; - this.date = date; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1837500879; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the total number of Telegram Stars received by the channel chat for direct messages from the given topic. - * - *

Returns {@link StarCount StarCount}

- */ - public static class GetDirectMessagesChatTopicRevenue extends Function { - /** - * Chat identifier of the channel direct messages chat administered by the current user. - */ - public long chatId; - /** - * Identifier of the topic. - */ - public long topicId; - - /** - * Default constructor for a function, which returns the total number of Telegram Stars received by the channel chat for direct messages from the given topic. - * - *

Returns {@link StarCount StarCount}

- */ - public GetDirectMessagesChatTopicRevenue() { - } - - /** - * Creates a function, which returns the total number of Telegram Stars received by the channel chat for direct messages from the given topic. - * - *

Returns {@link StarCount StarCount}

- * - * @param chatId Chat identifier of the channel direct messages chat administered by the current user. - * @param topicId Identifier of the topic. - */ - public GetDirectMessagesChatTopicRevenue(long chatId, long topicId) { - this.chatId = chatId; - this.topicId = topicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -792382961; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of emoji statuses, which can't be used as chat emoji status, even if they are from a sticker set with isAllowedAsChatEmojiStatus == true. - * - *

Returns {@link EmojiStatusCustomEmojis EmojiStatusCustomEmojis}

- */ - public static class GetDisallowedChatEmojiStatuses extends Function { - - /** - * Default constructor for a function, which returns the list of emoji statuses, which can't be used as chat emoji status, even if they are from a sticker set with isAllowedAsChatEmojiStatus == true. - * - *

Returns {@link EmojiStatusCustomEmojis EmojiStatusCustomEmojis}

- */ - public GetDisallowedChatEmojiStatuses() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2004787831; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns available emoji categories. - * - *

Returns {@link EmojiCategories EmojiCategories}

- */ - public static class GetEmojiCategories extends Function { - /** - * Type of emoji categories to return; pass null to get default emoji categories. - */ - public EmojiCategoryType type; - - /** - * Default constructor for a function, which returns available emoji categories. - * - *

Returns {@link EmojiCategories EmojiCategories}

- */ - public GetEmojiCategories() { - } - - /** - * Creates a function, which returns available emoji categories. - * - *

Returns {@link EmojiCategories EmojiCategories}

- * - * @param type Type of emoji categories to return; pass null to get default emoji categories. - */ - public GetEmojiCategories(EmojiCategoryType type) { - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2139537774; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about an emoji reaction. Returns a 404 error if the reaction is not found. - * - *

Returns {@link EmojiReaction EmojiReaction}

- */ - public static class GetEmojiReaction extends Function { - /** - * Text representation of the reaction. - */ - public String emoji; - - /** - * Default constructor for a function, which returns information about an emoji reaction. Returns a 404 error if the reaction is not found. - * - *

Returns {@link EmojiReaction EmojiReaction}

- */ - public GetEmojiReaction() { - } - - /** - * Creates a function, which returns information about an emoji reaction. Returns a 404 error if the reaction is not found. - * - *

Returns {@link EmojiReaction EmojiReaction}

- * - * @param emoji Text representation of the reaction. - */ - public GetEmojiReaction(String emoji) { - this.emoji = emoji; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -449572388; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an HTTP URL which can be used to automatically log in to the translation platform and suggest new emoji replacements. The URL will be valid for 30 seconds after generation. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public static class GetEmojiSuggestionsUrl extends Function { - /** - * Language code for which the emoji replacements will be suggested. - */ - public String languageCode; - - /** - * Default constructor for a function, which returns an HTTP URL which can be used to automatically log in to the translation platform and suggest new emoji replacements. The URL will be valid for 30 seconds after generation. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public GetEmojiSuggestionsUrl() { - } - - /** - * Creates a function, which returns an HTTP URL which can be used to automatically log in to the translation platform and suggest new emoji replacements. The URL will be valid for 30 seconds after generation. - * - *

Returns {@link HttpUrl HttpUrl}

- * - * @param languageCode Language code for which the emoji replacements will be suggested. - */ - public GetEmojiSuggestionsUrl(String languageCode) { - this.languageCode = languageCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1404101841; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an HTTP URL which can be used to automatically authorize the current user on a website after clicking an HTTP link. Use the method getExternalLinkInfo to find whether a prior user confirmation is needed. May return an empty link if just a toast about successful login has to be shown. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public static class GetExternalLink extends Function { - /** - * The HTTP link. - */ - public String link; - /** - * Pass true if the current user allowed the bot that was returned in getExternalLinkInfo, to send them messages. - */ - public boolean allowWriteAccess; - - /** - * Default constructor for a function, which returns an HTTP URL which can be used to automatically authorize the current user on a website after clicking an HTTP link. Use the method getExternalLinkInfo to find whether a prior user confirmation is needed. May return an empty link if just a toast about successful login has to be shown. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public GetExternalLink() { - } - - /** - * Creates a function, which returns an HTTP URL which can be used to automatically authorize the current user on a website after clicking an HTTP link. Use the method getExternalLinkInfo to find whether a prior user confirmation is needed. May return an empty link if just a toast about successful login has to be shown. - * - *

Returns {@link HttpUrl HttpUrl}

- * - * @param link The HTTP link. - * @param allowWriteAccess Pass true if the current user allowed the bot that was returned in getExternalLinkInfo, to send them messages. - */ - public GetExternalLink(String link, boolean allowWriteAccess) { - this.link = link; - this.allowWriteAccess = allowWriteAccess; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1586688235; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about an action to be done when the current user clicks an external link. Don't use this method for links from secret chats if link preview is disabled in secret chats. - * - *

Returns {@link LoginUrlInfo LoginUrlInfo}

- */ - public static class GetExternalLinkInfo extends Function { - /** - * The link. - */ - public String link; - - /** - * Default constructor for a function, which returns information about an action to be done when the current user clicks an external link. Don't use this method for links from secret chats if link preview is disabled in secret chats. - * - *

Returns {@link LoginUrlInfo LoginUrlInfo}

- */ - public GetExternalLinkInfo() { - } - - /** - * Creates a function, which returns information about an action to be done when the current user clicks an external link. Don't use this method for links from secret chats if link preview is disabled in secret chats. - * - *

Returns {@link LoginUrlInfo LoginUrlInfo}

- * - * @param link The link. - */ - public GetExternalLinkInfo(String link) { - this.link = link; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1175288383; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns favorite stickers. - * - *

Returns {@link Stickers Stickers}

- */ - public static class GetFavoriteStickers extends Function { - - /** - * Default constructor for a function, which returns favorite stickers. - * - *

Returns {@link Stickers Stickers}

- */ - public GetFavoriteStickers() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -338964672; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a file. This is an offline method. - * - *

Returns {@link File File}

- */ - public static class GetFile extends Function { - /** - * Identifier of the file to get. - */ - public int fileId; - - /** - * Default constructor for a function, which returns information about a file. This is an offline method. - * - *

Returns {@link File File}

- */ - public GetFile() { - } - - /** - * Creates a function, which returns information about a file. This is an offline method. - * - *

Returns {@link File File}

- * - * @param fileId Identifier of the file to get. - */ - public GetFile(int fileId) { - this.fileId = fileId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1553923406; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns file downloaded prefix size from a given offset, in bytes. - * - *

Returns {@link FileDownloadedPrefixSize FileDownloadedPrefixSize}

- */ - public static class GetFileDownloadedPrefixSize extends Function { - /** - * Identifier of the file. - */ - public int fileId; - /** - * Offset from which downloaded prefix size needs to be calculated. - */ - public long offset; - - /** - * Default constructor for a function, which returns file downloaded prefix size from a given offset, in bytes. - * - *

Returns {@link FileDownloadedPrefixSize FileDownloadedPrefixSize}

- */ - public GetFileDownloadedPrefixSize() { - } - - /** - * Creates a function, which returns file downloaded prefix size from a given offset, in bytes. - * - *

Returns {@link FileDownloadedPrefixSize FileDownloadedPrefixSize}

- * - * @param fileId Identifier of the file. - * @param offset Offset from which downloaded prefix size needs to be calculated. - */ - public GetFileDownloadedPrefixSize(int fileId, long offset) { - this.fileId = fileId; - this.offset = offset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 855948589; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the extension of a file, guessed by its MIME type. Returns an empty string on failure. Can be called synchronously. - * - *

Returns {@link Text Text}

- */ - public static class GetFileExtension extends Function { - /** - * The MIME type of the file. - */ - public String mimeType; - - /** - * Default constructor for a function, which returns the extension of a file, guessed by its MIME type. Returns an empty string on failure. Can be called synchronously. - * - *

Returns {@link Text Text}

- */ - public GetFileExtension() { - } - - /** - * Creates a function, which returns the extension of a file, guessed by its MIME type. Returns an empty string on failure. Can be called synchronously. - * - *

Returns {@link Text Text}

- * - * @param mimeType The MIME type of the file. - */ - public GetFileExtension(String mimeType) { - this.mimeType = mimeType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -106055372; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the MIME type of a file, guessed by its extension. Returns an empty string on failure. Can be called synchronously. - * - *

Returns {@link Text Text}

- */ - public static class GetFileMimeType extends Function { - /** - * The name of the file or path to the file. - */ - public String fileName; - - /** - * Default constructor for a function, which returns the MIME type of a file, guessed by its extension. Returns an empty string on failure. Can be called synchronously. - * - *

Returns {@link Text Text}

- */ - public GetFileMimeType() { - } - - /** - * Creates a function, which returns the MIME type of a file, guessed by its extension. Returns an empty string on failure. Can be called synchronously. - * - *

Returns {@link Text Text}

- * - * @param fileName The name of the file or path to the file. - */ - public GetFileMimeType(String fileName) { - this.fileName = fileName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2073879671; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a topic in a forum supergroup chat or a chat with a bot with topics. - * - *

Returns {@link ForumTopic ForumTopic}

- */ - public static class GetForumTopic extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * Forum topic identifier. - */ - public int forumTopicId; - - /** - * Default constructor for a function, which returns information about a topic in a forum supergroup chat or a chat with a bot with topics. - * - *

Returns {@link ForumTopic ForumTopic}

- */ - public GetForumTopic() { - } - - /** - * Creates a function, which returns information about a topic in a forum supergroup chat or a chat with a bot with topics. - * - *

Returns {@link ForumTopic ForumTopic}

- * - * @param chatId Identifier of the chat. - * @param forumTopicId Forum topic identifier. - */ - public GetForumTopic(long chatId, int forumTopicId) { - this.chatId = chatId; - this.forumTopicId = forumTopicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1931459984; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of custom emoji, which can be used as forum topic icon by all users. - * - *

Returns {@link Stickers Stickers}

- */ - public static class GetForumTopicDefaultIcons extends Function { - - /** - * Default constructor for a function, which returns the list of custom emoji, which can be used as forum topic icon by all users. - * - *

Returns {@link Stickers Stickers}

- */ - public GetForumTopicDefaultIcons() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1479898332; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns messages in a topic in a forum supergroup chat or a chat with a bot with topics. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). For optimal performance, the number of returned messages is chosen by TDLib. - * - *

Returns {@link Messages Messages}

- */ - public static class GetForumTopicHistory extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Forum topic identifier. - */ - public int forumTopicId; - /** - * Identifier of the message starting from which history must be fetched; use 0 to get results from the last message. - */ - public long fromMessageId; - /** - * Specify 0 to get results from exactly the message fromMessageId or a negative number from -99 to -1 to get additionally -offset newer messages. - */ - public int offset; - /** - * The maximum number of messages to be returned; must be positive and can't be greater than 100. If the offset is negative, then the limit must be greater than or equal to -offset. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which returns messages in a topic in a forum supergroup chat or a chat with a bot with topics. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). For optimal performance, the number of returned messages is chosen by TDLib. - * - *

Returns {@link Messages Messages}

- */ - public GetForumTopicHistory() { - } - - /** - * Creates a function, which returns messages in a topic in a forum supergroup chat or a chat with a bot with topics. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). For optimal performance, the number of returned messages is chosen by TDLib. - * - *

Returns {@link Messages Messages}

- * - * @param chatId Chat identifier. - * @param forumTopicId Forum topic identifier. - * @param fromMessageId Identifier of the message starting from which history must be fetched; use 0 to get results from the last message. - * @param offset Specify 0 to get results from exactly the message fromMessageId or a negative number from -99 to -1 to get additionally -offset newer messages. - * @param limit The maximum number of messages to be returned; must be positive and can't be greater than 100. If the offset is negative, then the limit must be greater than or equal to -offset. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public GetForumTopicHistory(long chatId, int forumTopicId, long fromMessageId, int offset, int limit) { - this.chatId = chatId; - this.forumTopicId = forumTopicId; - this.fromMessageId = fromMessageId; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -339129791; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an HTTPS link to a topic in a forum supergroup chat. This is an offline method. - * - *

Returns {@link MessageLink MessageLink}

- */ - public static class GetForumTopicLink extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * Forum topic identifier. - */ - public int forumTopicId; - - /** - * Default constructor for a function, which returns an HTTPS link to a topic in a forum supergroup chat. This is an offline method. - * - *

Returns {@link MessageLink MessageLink}

- */ - public GetForumTopicLink() { - } - - /** - * Creates a function, which returns an HTTPS link to a topic in a forum supergroup chat. This is an offline method. - * - *

Returns {@link MessageLink MessageLink}

- * - * @param chatId Identifier of the chat. - * @param forumTopicId Forum topic identifier. - */ - public GetForumTopicLink(long chatId, int forumTopicId) { - this.chatId = chatId; - this.forumTopicId = forumTopicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 330405972; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns found forum topics in a forum supergroup chat or a chat with a bot with topics. This is a temporary method for getting information about topic list from the server. - * - *

Returns {@link ForumTopics ForumTopics}

- */ - public static class GetForumTopics extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * Query to search for in the forum topic's name. - */ - public String query; - /** - * The date starting from which the results need to be fetched. Use 0 or any date in the future to get results from the last topic. - */ - public int offsetDate; - /** - * The message identifier of the last message in the last found topic, or 0 for the first request. - */ - public long offsetMessageId; - /** - * The forum topic identifier of the last found topic, or 0 for the first request. - */ - public int offsetForumTopicId; - /** - * The maximum number of forum topics to be returned; up to 100. For optimal performance, the number of returned forum topics is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which returns found forum topics in a forum supergroup chat or a chat with a bot with topics. This is a temporary method for getting information about topic list from the server. - * - *

Returns {@link ForumTopics ForumTopics}

- */ - public GetForumTopics() { - } - - /** - * Creates a function, which returns found forum topics in a forum supergroup chat or a chat with a bot with topics. This is a temporary method for getting information about topic list from the server. - * - *

Returns {@link ForumTopics ForumTopics}

- * - * @param chatId Identifier of the chat. - * @param query Query to search for in the forum topic's name. - * @param offsetDate The date starting from which the results need to be fetched. Use 0 or any date in the future to get results from the last topic. - * @param offsetMessageId The message identifier of the last message in the last found topic, or 0 for the first request. - * @param offsetForumTopicId The forum topic identifier of the last found topic, or 0 for the first request. - * @param limit The maximum number of forum topics to be returned; up to 100. For optimal performance, the number of returned forum topics is chosen by TDLib and can be smaller than the specified limit. - */ - public GetForumTopics(long chatId, String query, int offsetDate, long offsetMessageId, int offsetForumTopicId, int limit) { - this.chatId = chatId; - this.query = query; - this.offsetDate = offsetDate; - this.offsetMessageId = offsetMessageId; - this.offsetForumTopicId = offsetForumTopicId; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1368275676; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the high scores for a game and some part of the high score table in the range of the specified user; for bots only. - * - *

Returns {@link GameHighScores GameHighScores}

- */ - public static class GetGameHighScores extends Function { - /** - * The chat that contains the message with the game. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * User identifier. - */ - public long userId; - - /** - * Default constructor for a function, which returns the high scores for a game and some part of the high score table in the range of the specified user; for bots only. - * - *

Returns {@link GameHighScores GameHighScores}

- */ - public GetGameHighScores() { - } - - /** - * Creates a function, which returns the high scores for a game and some part of the high score table in the range of the specified user; for bots only. - * - *

Returns {@link GameHighScores GameHighScores}

- * - * @param chatId The chat that contains the message with the game. - * @param messageId Identifier of the message. - * @param userId User identifier. - */ - public GetGameHighScores(long chatId, long messageId, long userId) { - this.chatId = chatId; - this.messageId = messageId; - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 15746459; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the gifts that were acquired by the current user on a gift auction. - * - *

Returns {@link GiftAuctionAcquiredGifts GiftAuctionAcquiredGifts}

- */ - public static class GetGiftAuctionAcquiredGifts extends Function { - /** - * Identifier of the auctioned gift. - */ - public long giftId; - - /** - * Default constructor for a function, which returns the gifts that were acquired by the current user on a gift auction. - * - *

Returns {@link GiftAuctionAcquiredGifts GiftAuctionAcquiredGifts}

- */ - public GetGiftAuctionAcquiredGifts() { - } - - /** - * Creates a function, which returns the gifts that were acquired by the current user on a gift auction. - * - *

Returns {@link GiftAuctionAcquiredGifts GiftAuctionAcquiredGifts}

- * - * @param giftId Identifier of the auctioned gift. - */ - public GetGiftAuctionAcquiredGifts(long giftId) { - this.giftId = giftId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -937975215; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns auction state for a gift. - * - *

Returns {@link GiftAuctionState GiftAuctionState}

- */ - public static class GetGiftAuctionState extends Function { - /** - * Unique identifier of the auction. - */ - public String auctionId; - - /** - * Default constructor for a function, which returns auction state for a gift. - * - *

Returns {@link GiftAuctionState GiftAuctionState}

- */ - public GetGiftAuctionState() { - } - - /** - * Creates a function, which returns auction state for a gift. - * - *

Returns {@link GiftAuctionState GiftAuctionState}

- * - * @param auctionId Unique identifier of the auction. - */ - public GetGiftAuctionState(String auctionId) { - this.auctionId = auctionId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 989210247; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns available to the current user gift chat themes. - * - *

Returns {@link GiftChatThemes GiftChatThemes}

- */ - public static class GetGiftChatThemes extends Function { - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of chat themes to return. - */ - public int limit; - - /** - * Default constructor for a function, which returns available to the current user gift chat themes. - * - *

Returns {@link GiftChatThemes GiftChatThemes}

- */ - public GetGiftChatThemes() { - } - - /** - * Creates a function, which returns available to the current user gift chat themes. - * - *

Returns {@link GiftChatThemes GiftChatThemes}

- * - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of chat themes to return. - */ - public GetGiftChatThemes(String offset, int limit) { - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1051327876; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns collections of gifts owned by the given user or chat. - * - *

Returns {@link GiftCollections GiftCollections}

- */ - public static class GetGiftCollections extends Function { - /** - * Identifier of the user or the channel chat that received the gifts. - */ - public MessageSender ownerId; - - /** - * Default constructor for a function, which returns collections of gifts owned by the given user or chat. - * - *

Returns {@link GiftCollections GiftCollections}

- */ - public GetGiftCollections() { - } - - /** - * Creates a function, which returns collections of gifts owned by the given user or chat. - * - *

Returns {@link GiftCollections GiftCollections}

- * - * @param ownerId Identifier of the user or the channel chat that received the gifts. - */ - public GetGiftCollections(MessageSender ownerId) { - this.ownerId = ownerId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1533138835; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns examples of possible upgraded gifts for a regular gift. - * - *

Returns {@link GiftUpgradePreview GiftUpgradePreview}

- */ - public static class GetGiftUpgradePreview extends Function { - /** - * Identifier of the regular gift. - */ - public long regularGiftId; - - /** - * Default constructor for a function, which returns examples of possible upgraded gifts for a regular gift. - * - *

Returns {@link GiftUpgradePreview GiftUpgradePreview}

- */ - public GetGiftUpgradePreview() { - } - - /** - * Creates a function, which returns examples of possible upgraded gifts for a regular gift. - * - *

Returns {@link GiftUpgradePreview GiftUpgradePreview}

- * - * @param regularGiftId Identifier of the regular gift. - */ - public GetGiftUpgradePreview(long regularGiftId) { - this.regularGiftId = regularGiftId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1303475628; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns upgraded gifts of the current user who can be used to craft another gifts. - * - *

Returns {@link GiftsForCrafting GiftsForCrafting}

- */ - public static class GetGiftsForCrafting extends Function { - /** - * Identifier of the regular gift that will be used for crafting. - */ - public long regularGiftId; - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of gifts to be returned; must be positive and can't be greater than 100. For optimal performance, the number of returned objects is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which returns upgraded gifts of the current user who can be used to craft another gifts. - * - *

Returns {@link GiftsForCrafting GiftsForCrafting}

- */ - public GetGiftsForCrafting() { - } - - /** - * Creates a function, which returns upgraded gifts of the current user who can be used to craft another gifts. - * - *

Returns {@link GiftsForCrafting GiftsForCrafting}

- * - * @param regularGiftId Identifier of the regular gift that will be used for crafting. - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of gifts to be returned; must be positive and can't be greater than 100. For optimal performance, the number of returned objects is chosen by TDLib and can be smaller than the specified limit. - */ - public GetGiftsForCrafting(long regularGiftId, String offset, int limit) { - this.regularGiftId = regularGiftId; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1571822730; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a giveaway. - * - *

Returns {@link GiveawayInfo GiveawayInfo}

- */ - public static class GetGiveawayInfo extends Function { - /** - * Identifier of the channel chat which started the giveaway. - */ - public long chatId; - /** - * Identifier of the giveaway or a giveaway winners message in the chat. - */ - public long messageId; - - /** - * Default constructor for a function, which returns information about a giveaway. - * - *

Returns {@link GiveawayInfo GiveawayInfo}

- */ - public GetGiveawayInfo() { - } - - /** - * Creates a function, which returns information about a giveaway. - * - *

Returns {@link GiveawayInfo GiveawayInfo}

- * - * @param chatId Identifier of the channel chat which started the giveaway. - * @param messageId Identifier of the giveaway or a giveaway winners message in the chat. - */ - public GetGiveawayInfo(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1215852357; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns greeting stickers from regular sticker sets that can be used for the start page of other users. - * - *

Returns {@link Stickers Stickers}

- */ - public static class GetGreetingStickers extends Function { - - /** - * Default constructor for a function, which returns greeting stickers from regular sticker sets that can be used for the start page of other users. - * - *

Returns {@link Stickers Stickers}

- */ - public GetGreetingStickers() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 374873372; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the most grossing Web App bots. - * - *

Returns {@link FoundUsers FoundUsers}

- */ - public static class GetGrossingWebAppBots extends Function { - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of bots to be returned; up to 100. - */ - public int limit; - - /** - * Default constructor for a function, which returns the most grossing Web App bots. - * - *

Returns {@link FoundUsers FoundUsers}

- */ - public GetGrossingWebAppBots() { - } - - /** - * Creates a function, which returns the most grossing Web App bots. - * - *

Returns {@link FoundUsers FoundUsers}

- * - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of bots to be returned; up to 100. - */ - public GetGrossingWebAppBots(String offset, int limit) { - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1696779802; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a group call. - * - *

Returns {@link GroupCall GroupCall}

- */ - public static class GetGroupCall extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - - /** - * Default constructor for a function, which returns information about a group call. - * - *

Returns {@link GroupCall GroupCall}

- */ - public GetGroupCall() { - } - - /** - * Creates a function, which returns information about a group call. - * - *

Returns {@link GroupCall GroupCall}

- * - * @param groupCallId Group call identifier. - */ - public GetGroupCall(int groupCallId) { - this.groupCallId = groupCallId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1468491406; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about participants of a non-joined group call that is not bound to a chat. - * - *

Returns {@link GroupCallParticipants GroupCallParticipants}

- */ - public static class GetGroupCallParticipants extends Function { - /** - * The group call which participants will be returned. - */ - public InputGroupCall inputGroupCall; - /** - * The maximum number of participants to return; must be positive. - */ - public int limit; - - /** - * Default constructor for a function, which returns information about participants of a non-joined group call that is not bound to a chat. - * - *

Returns {@link GroupCallParticipants GroupCallParticipants}

- */ - public GetGroupCallParticipants() { - } - - /** - * Creates a function, which returns information about participants of a non-joined group call that is not bound to a chat. - * - *

Returns {@link GroupCallParticipants GroupCallParticipants}

- * - * @param inputGroupCall The group call which participants will be returned. - * @param limit The maximum number of participants to return; must be positive. - */ - public GetGroupCallParticipants(InputGroupCall inputGroupCall, int limit) { - this.inputGroupCall = inputGroupCall; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1986739394; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a file with a segment of a video chat or live story in a modified OGG format for audio or MPEG-4 format for video. - * - *

Returns {@link Data Data}

- */ - public static class GetGroupCallStreamSegment extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Point in time when the stream segment begins; Unix timestamp in milliseconds. - */ - public long timeOffset; - /** - * Segment duration scale; 0-1. Segment's duration is 1000/(2**scale) milliseconds. - */ - public int scale; - /** - * Identifier of an audio/video channel to get as received from tgcalls. - */ - public int channelId; - /** - * Video quality as received from tgcalls; pass null to get the worst available quality. - */ - public GroupCallVideoQuality videoQuality; - - /** - * Default constructor for a function, which returns a file with a segment of a video chat or live story in a modified OGG format for audio or MPEG-4 format for video. - * - *

Returns {@link Data Data}

- */ - public GetGroupCallStreamSegment() { - } - - /** - * Creates a function, which returns a file with a segment of a video chat or live story in a modified OGG format for audio or MPEG-4 format for video. - * - *

Returns {@link Data Data}

- * - * @param groupCallId Group call identifier. - * @param timeOffset Point in time when the stream segment begins; Unix timestamp in milliseconds. - * @param scale Segment duration scale; 0-1. Segment's duration is 1000/(2**scale) milliseconds. - * @param channelId Identifier of an audio/video channel to get as received from tgcalls. - * @param videoQuality Video quality as received from tgcalls; pass null to get the worst available quality. - */ - public GetGroupCallStreamSegment(int groupCallId, long timeOffset, int scale, int channelId, GroupCallVideoQuality videoQuality) { - this.groupCallId = groupCallId; - this.timeOffset = timeOffset; - this.scale = scale; - this.channelId = channelId; - this.videoQuality = videoQuality; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -502273424; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about available streams in a video chat or a live story. - * - *

Returns {@link GroupCallStreams GroupCallStreams}

- */ - public static class GetGroupCallStreams extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - - /** - * Default constructor for a function, which returns information about available streams in a video chat or a live story. - * - *

Returns {@link GroupCallStreams GroupCallStreams}

- */ - public GetGroupCallStreams() { - } - - /** - * Creates a function, which returns information about available streams in a video chat or a live story. - * - *

Returns {@link GroupCallStreams GroupCallStreams}

- * - * @param groupCallId Group call identifier. - */ - public GetGroupCallStreams(int groupCallId) { - this.groupCallId = groupCallId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1619226268; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a list of common group chats with a given user. Chats are sorted by their type and creation date. - * - *

Returns {@link Chats Chats}

- */ - public static class GetGroupsInCommon extends Function { - /** - * User identifier. - */ - public long userId; - /** - * Chat identifier starting from which to return chats; use 0 for the first request. - */ - public long offsetChatId; - /** - * The maximum number of chats to be returned; up to 100. - */ - public int limit; - - /** - * Default constructor for a function, which returns a list of common group chats with a given user. Chats are sorted by their type and creation date. - * - *

Returns {@link Chats Chats}

- */ - public GetGroupsInCommon() { - } - - /** - * Creates a function, which returns a list of common group chats with a given user. Chats are sorted by their type and creation date. - * - *

Returns {@link Chats Chats}

- * - * @param userId User identifier. - * @param offsetChatId Chat identifier starting from which to return chats; use 0 for the first request. - * @param limit The maximum number of chats to be returned; up to 100. - */ - public GetGroupsInCommon(long userId, long offsetChatId, int limit) { - this.userId = userId; - this.offsetChatId = offsetChatId; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 381539178; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the total number of imported contacts. - * - *

Returns {@link Count Count}

- */ - public static class GetImportedContactCount extends Function { - - /** - * Default constructor for a function, which returns the total number of imported contacts. - * - *

Returns {@link Count Count}

- */ - public GetImportedContactCount() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -656336346; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a list of recently inactive supergroups and channels. Can be used when user reaches limit on the number of joined supergroups and channels and receives the error "CHANNELS_TOO_MUCH". Also, the limit can be increased with Telegram Premium. - * - *

Returns {@link Chats Chats}

- */ - public static class GetInactiveSupergroupChats extends Function { - - /** - * Default constructor for a function, which returns a list of recently inactive supergroups and channels. Can be used when user reaches limit on the number of joined supergroups and channels and receives the error "CHANNELS_TOO_MUCH". Also, the limit can be increased with Telegram Premium. - * - *

Returns {@link Chats Chats}

- */ - public GetInactiveSupergroupChats() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -657720907; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns game high scores and some part of the high score table in the range of the specified user; for bots only. - * - *

Returns {@link GameHighScores GameHighScores}

- */ - public static class GetInlineGameHighScores extends Function { - /** - * Inline message identifier. - */ - public String inlineMessageId; - /** - * User identifier. - */ - public long userId; - - /** - * Default constructor for a function, which returns game high scores and some part of the high score table in the range of the specified user; for bots only. - * - *

Returns {@link GameHighScores GameHighScores}

- */ - public GetInlineGameHighScores() { - } - - /** - * Creates a function, which returns game high scores and some part of the high score table in the range of the specified user; for bots only. - * - *

Returns {@link GameHighScores GameHighScores}

- * - * @param inlineMessageId Inline message identifier. - * @param userId User identifier. - */ - public GetInlineGameHighScores(String inlineMessageId, long userId) { - this.inlineMessageId = inlineMessageId; - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -533107798; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends an inline query to a bot and returns its results. Returns an error with code 502 if the bot fails to answer the query before the query timeout expires. - * - *

Returns {@link InlineQueryResults InlineQueryResults}

- */ - public static class GetInlineQueryResults extends Function { - /** - * Identifier of the target bot. - */ - public long botUserId; - /** - * Identifier of the chat where the query was sent. - */ - public long chatId; - /** - * Location of the user; pass null if unknown or the bot doesn't need user's location. - */ - public Location userLocation; - /** - * Text of the query. - */ - public String query; - /** - * Offset of the first entry to return; use empty string to get the first chunk of results. - */ - public String offset; - - /** - * Default constructor for a function, which sends an inline query to a bot and returns its results. Returns an error with code 502 if the bot fails to answer the query before the query timeout expires. - * - *

Returns {@link InlineQueryResults InlineQueryResults}

- */ - public GetInlineQueryResults() { - } - - /** - * Creates a function, which sends an inline query to a bot and returns its results. Returns an error with code 502 if the bot fails to answer the query before the query timeout expires. - * - *

Returns {@link InlineQueryResults InlineQueryResults}

- * - * @param botUserId Identifier of the target bot. - * @param chatId Identifier of the chat where the query was sent. - * @param userLocation Location of the user; pass null if unknown or the bot doesn't need user's location. - * @param query Text of the query. - * @param offset Offset of the first entry to return; use empty string to get the first chunk of results. - */ - public GetInlineQueryResults(long botUserId, long chatId, Location userLocation, String query, String offset) { - this.botUserId = botUserId; - this.chatId = chatId; - this.userLocation = userLocation; - this.query = query; - this.offset = offset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2044524652; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns backgrounds installed by the user. - * - *

Returns {@link Backgrounds Backgrounds}

- */ - public static class GetInstalledBackgrounds extends Function { - /** - * Pass true to order returned backgrounds for a dark theme. - */ - public boolean forDarkTheme; - - /** - * Default constructor for a function, which returns backgrounds installed by the user. - * - *

Returns {@link Backgrounds Backgrounds}

- */ - public GetInstalledBackgrounds() { - } - - /** - * Creates a function, which returns backgrounds installed by the user. - * - *

Returns {@link Backgrounds Backgrounds}

- * - * @param forDarkTheme Pass true to order returned backgrounds for a dark theme. - */ - public GetInstalledBackgrounds(boolean forDarkTheme) { - this.forDarkTheme = forDarkTheme; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1051406241; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a list of installed sticker sets. - * - *

Returns {@link StickerSets StickerSets}

- */ - public static class GetInstalledStickerSets extends Function { - /** - * Type of the sticker sets to return. - */ - public StickerType stickerType; - - /** - * Default constructor for a function, which returns a list of installed sticker sets. - * - *

Returns {@link StickerSets StickerSets}

- */ - public GetInstalledStickerSets() { - } - - /** - * Creates a function, which returns a list of installed sticker sets. - * - *

Returns {@link StickerSets StickerSets}

- * - * @param stickerType Type of the sticker sets to return. - */ - public GetInstalledStickerSets(StickerType stickerType) { - this.stickerType = stickerType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1630467830; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an HTTPS or a tg: link with the given type. Can be called before authorization. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public static class GetInternalLink extends Function { - /** - * Expected type of the link. - */ - public InternalLinkType type; - /** - * Pass true to create an HTTPS link (only available for some link types); pass false to create a tg: link. - */ - public boolean isHttp; - - /** - * Default constructor for a function, which returns an HTTPS or a tg: link with the given type. Can be called before authorization. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public GetInternalLink() { - } - - /** - * Creates a function, which returns an HTTPS or a tg: link with the given type. Can be called before authorization. - * - *

Returns {@link HttpUrl HttpUrl}

- * - * @param type Expected type of the link. - * @param isHttp Pass true to create an HTTPS link (only available for some link types); pass false to create a tg: link. - */ - public GetInternalLink(InternalLinkType type, boolean isHttp) { - this.type = type; - this.isHttp = isHttp; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 962654640; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about the type of internal link. Returns a 404 error if the link is not internal. Can be called before authorization. - * - *

Returns {@link InternalLinkType InternalLinkType}

- */ - public static class GetInternalLinkType extends Function { - /** - * The link. - */ - public String link; - - /** - * Default constructor for a function, which returns information about the type of internal link. Returns a 404 error if the link is not internal. Can be called before authorization. - * - *

Returns {@link InternalLinkType InternalLinkType}

- */ - public GetInternalLinkType() { - } - - /** - * Creates a function, which returns information about the type of internal link. Returns a 404 error if the link is not internal. Can be called before authorization. - * - *

Returns {@link InternalLinkType InternalLinkType}

- * - * @param link The link. - */ - public GetInternalLinkType(String link) { - this.link = link; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1948428535; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Converts a JsonValue object to corresponding JSON-serialized string. Can be called synchronously. - * - *

Returns {@link Text Text}

- */ - public static class GetJsonString extends Function { - /** - * The JsonValue object. - */ - public JsonValue jsonValue; - - /** - * Default constructor for a function, which converts a JsonValue object to corresponding JSON-serialized string. Can be called synchronously. - * - *

Returns {@link Text Text}

- */ - public GetJsonString() { - } - - /** - * Creates a function, which converts a JsonValue object to corresponding JSON-serialized string. Can be called synchronously. - * - *

Returns {@link Text Text}

- * - * @param jsonValue The JsonValue object. - */ - public GetJsonString(JsonValue jsonValue) { - this.jsonValue = jsonValue; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 663458849; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Converts a JSON-serialized string to corresponding JsonValue object. Can be called synchronously. - * - *

Returns {@link JsonValue JsonValue}

- */ - public static class GetJsonValue extends Function { - /** - * The JSON-serialized string. - */ - public String json; - - /** - * Default constructor for a function, which converts a JSON-serialized string to corresponding JsonValue object. Can be called synchronously. - * - *

Returns {@link JsonValue JsonValue}

- */ - public GetJsonValue() { - } - - /** - * Creates a function, which converts a JSON-serialized string to corresponding JsonValue object. Can be called synchronously. - * - *

Returns {@link JsonValue JsonValue}

- * - * @param json The JSON-serialized string. - */ - public GetJsonValue(String json) { - this.json = json; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1829086715; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns emojis matching the keyword. Supported only if the file database is enabled. Order of results is unspecified. - * - *

Returns {@link Emojis Emojis}

- */ - public static class GetKeywordEmojis extends Function { - /** - * Text to search for. - */ - public String text; - /** - * List of possible IETF language tags of the user's input language; may be empty if unknown. - */ - public String[] inputLanguageCodes; - - /** - * Default constructor for a function, which returns emojis matching the keyword. Supported only if the file database is enabled. Order of results is unspecified. - * - *

Returns {@link Emojis Emojis}

- */ - public GetKeywordEmojis() { - } - - /** - * Creates a function, which returns emojis matching the keyword. Supported only if the file database is enabled. Order of results is unspecified. - * - *

Returns {@link Emojis Emojis}

- * - * @param text Text to search for. - * @param inputLanguageCodes List of possible IETF language tags of the user's input language; may be empty if unknown. - */ - public GetKeywordEmojis(String text, String[] inputLanguageCodes) { - this.text = text; - this.inputLanguageCodes = inputLanguageCodes; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1969795990; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a language pack. Returned language pack identifier may be different from a provided one. Can be called before authorization. - * - *

Returns {@link LanguagePackInfo LanguagePackInfo}

- */ - public static class GetLanguagePackInfo extends Function { - /** - * Language pack identifier. - */ - public String languagePackId; - - /** - * Default constructor for a function, which returns information about a language pack. Returned language pack identifier may be different from a provided one. Can be called before authorization. - * - *

Returns {@link LanguagePackInfo LanguagePackInfo}

- */ - public GetLanguagePackInfo() { - } - - /** - * Creates a function, which returns information about a language pack. Returned language pack identifier may be different from a provided one. Can be called before authorization. - * - *

Returns {@link LanguagePackInfo LanguagePackInfo}

- * - * @param languagePackId Language pack identifier. - */ - public GetLanguagePackInfo(String languagePackId) { - this.languagePackId = languagePackId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2077809320; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a string stored in the local database from the specified localization target and language pack by its key. Returns a 404 error if the string is not found. Can be called synchronously. - * - *

Returns {@link LanguagePackStringValue LanguagePackStringValue}

- */ - public static class GetLanguagePackString extends Function { - /** - * Path to the language pack database in which strings are stored. - */ - public String languagePackDatabasePath; - /** - * Localization target to which the language pack belongs. - */ - public String localizationTarget; - /** - * Language pack identifier. - */ - public String languagePackId; - /** - * Language pack key of the string to be returned. - */ - public String key; - - /** - * Default constructor for a function, which returns a string stored in the local database from the specified localization target and language pack by its key. Returns a 404 error if the string is not found. Can be called synchronously. - * - *

Returns {@link LanguagePackStringValue LanguagePackStringValue}

- */ - public GetLanguagePackString() { - } - - /** - * Creates a function, which returns a string stored in the local database from the specified localization target and language pack by its key. Returns a 404 error if the string is not found. Can be called synchronously. - * - *

Returns {@link LanguagePackStringValue LanguagePackStringValue}

- * - * @param languagePackDatabasePath Path to the language pack database in which strings are stored. - * @param localizationTarget Localization target to which the language pack belongs. - * @param languagePackId Language pack identifier. - * @param key Language pack key of the string to be returned. - */ - public GetLanguagePackString(String languagePackDatabasePath, String localizationTarget, String languagePackId, String key) { - this.languagePackDatabasePath = languagePackDatabasePath; - this.localizationTarget = localizationTarget; - this.languagePackId = languagePackId; - this.key = key; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 150789747; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns strings from a language pack in the current localization target by their keys. Can be called before authorization. - * - *

Returns {@link LanguagePackStrings LanguagePackStrings}

- */ - public static class GetLanguagePackStrings extends Function { - /** - * Language pack identifier of the strings to be returned. - */ - public String languagePackId; - /** - * Language pack keys of the strings to be returned; leave empty to request all available strings. - */ - public String[] keys; - - /** - * Default constructor for a function, which returns strings from a language pack in the current localization target by their keys. Can be called before authorization. - * - *

Returns {@link LanguagePackStrings LanguagePackStrings}

- */ - public GetLanguagePackStrings() { - } - - /** - * Creates a function, which returns strings from a language pack in the current localization target by their keys. Can be called before authorization. - * - *

Returns {@link LanguagePackStrings LanguagePackStrings}

- * - * @param languagePackId Language pack identifier of the strings to be returned. - * @param keys Language pack keys of the strings to be returned; leave empty to request all available strings. - */ - public GetLanguagePackStrings(String languagePackId, String[] keys) { - this.languagePackId = languagePackId; - this.keys = keys; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1246259088; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a link preview by the text of a message. Do not call this function too often. Returns a 404 error if the text has no link preview. - * - *

Returns {@link LinkPreview LinkPreview}

- */ - public static class GetLinkPreview extends Function { - /** - * Message text with formatting. - */ - public FormattedText text; - /** - * Options to be used for generation of the link preview; pass null to use default link preview options. - */ - public LinkPreviewOptions linkPreviewOptions; - - /** - * Default constructor for a function, which returns a link preview by the text of a message. Do not call this function too often. Returns a 404 error if the text has no link preview. - * - *

Returns {@link LinkPreview LinkPreview}

- */ - public GetLinkPreview() { - } - - /** - * Creates a function, which returns a link preview by the text of a message. Do not call this function too often. Returns a 404 error if the text has no link preview. - * - *

Returns {@link LinkPreview LinkPreview}

- * - * @param text Message text with formatting. - * @param linkPreviewOptions Options to be used for generation of the link preview; pass null to use default link preview options. - */ - public GetLinkPreview(FormattedText text, LinkPreviewOptions linkPreviewOptions) { - this.text = text; - this.linkPreviewOptions = linkPreviewOptions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1039572191; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of message sender identifiers, on whose behalf messages can be sent to a live story. - * - *

Returns {@link ChatMessageSenders ChatMessageSenders}

- */ - public static class GetLiveStoryAvailableMessageSenders extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - - /** - * Default constructor for a function, which returns the list of message sender identifiers, on whose behalf messages can be sent to a live story. - * - *

Returns {@link ChatMessageSenders ChatMessageSenders}

- */ - public GetLiveStoryAvailableMessageSenders() { - } - - /** - * Creates a function, which returns the list of message sender identifiers, on whose behalf messages can be sent to a live story. - * - *

Returns {@link ChatMessageSenders ChatMessageSenders}

- * - * @param groupCallId Group call identifier. - */ - public GetLiveStoryAvailableMessageSenders(int groupCallId) { - this.groupCallId = groupCallId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1252390532; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns RTMP URL for streaming to a live story; requires canPostStories administrator right for channel chats. - * - *

Returns {@link RtmpUrl RtmpUrl}

- */ - public static class GetLiveStoryRtmpUrl extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which returns RTMP URL for streaming to a live story; requires canPostStories administrator right for channel chats. - * - *

Returns {@link RtmpUrl RtmpUrl}

- */ - public GetLiveStoryRtmpUrl() { - } - - /** - * Creates a function, which returns RTMP URL for streaming to a live story; requires canPostStories administrator right for channel chats. - * - *

Returns {@link RtmpUrl RtmpUrl}

- * - * @param chatId Chat identifier. - */ - public GetLiveStoryRtmpUrl(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1267168178; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about the user or the chat that streams to a live story; for live stories that aren't an RTMP stream only. - * - *

Returns {@link GroupCallParticipant GroupCallParticipant}

- */ - public static class GetLiveStoryStreamer extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - - /** - * Default constructor for a function, which returns information about the user or the chat that streams to a live story; for live stories that aren't an RTMP stream only. - * - *

Returns {@link GroupCallParticipant GroupCallParticipant}

- */ - public GetLiveStoryStreamer() { - } - - /** - * Creates a function, which returns information about the user or the chat that streams to a live story; for live stories that aren't an RTMP stream only. - * - *

Returns {@link GroupCallParticipant GroupCallParticipant}

- * - * @param groupCallId Group call identifier. - */ - public GetLiveStoryStreamer(int groupCallId) { - this.groupCallId = groupCallId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -718164721; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of top live story donors. - * - *

Returns {@link LiveStoryDonors LiveStoryDonors}

- */ - public static class GetLiveStoryTopDonors extends Function { - /** - * Group call identifier of the live story. - */ - public int groupCallId; - - /** - * Default constructor for a function, which returns the list of top live story donors. - * - *

Returns {@link LiveStoryDonors LiveStoryDonors}

- */ - public GetLiveStoryTopDonors() { - } - - /** - * Creates a function, which returns the list of top live story donors. - * - *

Returns {@link LiveStoryDonors LiveStoryDonors}

- * - * @param groupCallId Group call identifier of the live story. - */ - public GetLiveStoryTopDonors(int groupCallId) { - this.groupCallId = groupCallId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -700264064; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about the current localization target. This is an offline method if onlyLocal is true. Can be called before authorization. - * - *

Returns {@link LocalizationTargetInfo LocalizationTargetInfo}

- */ - public static class GetLocalizationTargetInfo extends Function { - /** - * Pass true to get only locally available information without sending network requests. - */ - public boolean onlyLocal; - - /** - * Default constructor for a function, which returns information about the current localization target. This is an offline method if onlyLocal is true. Can be called before authorization. - * - *

Returns {@link LocalizationTargetInfo LocalizationTargetInfo}

- */ - public GetLocalizationTargetInfo() { - } - - /** - * Creates a function, which returns information about the current localization target. This is an offline method if onlyLocal is true. Can be called before authorization. - * - *

Returns {@link LocalizationTargetInfo LocalizationTargetInfo}

- * - * @param onlyLocal Pass true to get only locally available information without sending network requests. - */ - public GetLocalizationTargetInfo(boolean onlyLocal) { - this.onlyLocal = onlyLocal; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1849499526; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about currently used log stream for internal logging of TDLib. Can be called synchronously. - * - *

Returns {@link LogStream LogStream}

- */ - public static class GetLogStream extends Function { - - /** - * Default constructor for a function, which returns information about currently used log stream for internal logging of TDLib. Can be called synchronously. - * - *

Returns {@link LogStream LogStream}

- */ - public GetLogStream() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1167608667; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns current verbosity level for a specified TDLib internal log tag. Can be called synchronously. - * - *

Returns {@link LogVerbosityLevel LogVerbosityLevel}

- */ - public static class GetLogTagVerbosityLevel extends Function { - /** - * Logging tag to change verbosity level. - */ - public String tag; - - /** - * Default constructor for a function, which returns current verbosity level for a specified TDLib internal log tag. Can be called synchronously. - * - *

Returns {@link LogVerbosityLevel LogVerbosityLevel}

- */ - public GetLogTagVerbosityLevel() { - } - - /** - * Creates a function, which returns current verbosity level for a specified TDLib internal log tag. Can be called synchronously. - * - *

Returns {@link LogVerbosityLevel LogVerbosityLevel}

- * - * @param tag Logging tag to change verbosity level. - */ - public GetLogTagVerbosityLevel(String tag) { - this.tag = tag; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 951004547; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of available TDLib internal log tags, for example, ["actor", "binlog", "connections", "notifications", "proxy"]. Can be called synchronously. - * - *

Returns {@link LogTags LogTags}

- */ - public static class GetLogTags extends Function { - - /** - * Default constructor for a function, which returns the list of available TDLib internal log tags, for example, ["actor", "binlog", "connections", "notifications", "proxy"]. Can be called synchronously. - * - *

Returns {@link LogTags LogTags}

- */ - public GetLogTags() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -254449190; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns current verbosity level of the internal logging of TDLib. Can be called synchronously. - * - *

Returns {@link LogVerbosityLevel LogVerbosityLevel}

- */ - public static class GetLogVerbosityLevel extends Function { - - /** - * Default constructor for a function, which returns current verbosity level of the internal logging of TDLib. Can be called synchronously. - * - *

Returns {@link LogVerbosityLevel LogVerbosityLevel}

- */ - public GetLogVerbosityLevel() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 594057956; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of passkeys allowed to be used for the login by the current user. - * - *

Returns {@link Passkeys Passkeys}

- */ - public static class GetLoginPasskeys extends Function { - - /** - * Default constructor for a function, which returns the list of passkeys allowed to be used for the login by the current user. - * - *

Returns {@link Passkeys Passkeys}

- */ - public GetLoginPasskeys() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -165927873; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an HTTP URL which can be used to automatically authorize the user on a website after clicking an inline button of type inlineKeyboardButtonTypeLoginUrl. Use the method getLoginUrlInfo to find whether a prior user confirmation is needed. If an error is returned, then the button must be handled as an ordinary URL button. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public static class GetLoginUrl extends Function { - /** - * Chat identifier of the message with the button. - */ - public long chatId; - /** - * Message identifier of the message with the button. - */ - public long messageId; - /** - * Button identifier. - */ - public long buttonId; - /** - * Pass true to allow the bot to send messages to the current user. Phone number access can't be requested using the button. - */ - public boolean allowWriteAccess; - - /** - * Default constructor for a function, which returns an HTTP URL which can be used to automatically authorize the user on a website after clicking an inline button of type inlineKeyboardButtonTypeLoginUrl. Use the method getLoginUrlInfo to find whether a prior user confirmation is needed. If an error is returned, then the button must be handled as an ordinary URL button. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public GetLoginUrl() { - } - - /** - * Creates a function, which returns an HTTP URL which can be used to automatically authorize the user on a website after clicking an inline button of type inlineKeyboardButtonTypeLoginUrl. Use the method getLoginUrlInfo to find whether a prior user confirmation is needed. If an error is returned, then the button must be handled as an ordinary URL button. - * - *

Returns {@link HttpUrl HttpUrl}

- * - * @param chatId Chat identifier of the message with the button. - * @param messageId Message identifier of the message with the button. - * @param buttonId Button identifier. - * @param allowWriteAccess Pass true to allow the bot to send messages to the current user. Phone number access can't be requested using the button. - */ - public GetLoginUrl(long chatId, long messageId, long buttonId, boolean allowWriteAccess) { - this.chatId = chatId; - this.messageId = messageId; - this.buttonId = buttonId; - this.allowWriteAccess = allowWriteAccess; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 791844305; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a button of type inlineKeyboardButtonTypeLoginUrl. The method needs to be called when the user presses the button. - * - *

Returns {@link LoginUrlInfo LoginUrlInfo}

- */ - public static class GetLoginUrlInfo extends Function { - /** - * Chat identifier of the message with the button. - */ - public long chatId; - /** - * Message identifier of the message with the button. The message must not be scheduled. - */ - public long messageId; - /** - * Button identifier. - */ - public long buttonId; - - /** - * Default constructor for a function, which returns information about a button of type inlineKeyboardButtonTypeLoginUrl. The method needs to be called when the user presses the button. - * - *

Returns {@link LoginUrlInfo LoginUrlInfo}

- */ - public GetLoginUrlInfo() { - } - - /** - * Creates a function, which returns information about a button of type inlineKeyboardButtonTypeLoginUrl. The method needs to be called when the user presses the button. - * - *

Returns {@link LoginUrlInfo LoginUrlInfo}

- * - * @param chatId Chat identifier of the message with the button. - * @param messageId Message identifier of the message with the button. The message must not be scheduled. - * @param buttonId Button identifier. - */ - public GetLoginUrlInfo(long chatId, long messageId, long buttonId) { - this.chatId = chatId; - this.messageId = messageId; - this.buttonId = buttonId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -859202125; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information needed to open the main Web App of a bot. - * - *

Returns {@link MainWebApp MainWebApp}

- */ - public static class GetMainWebApp extends Function { - /** - * Identifier of the chat in which the Web App is opened; pass 0 if none. - */ - public long chatId; - /** - * Identifier of the target bot. If the bot is restricted for the current user, then show an error instead of calling the method. - */ - public long botUserId; - /** - * Start parameter from internalLinkTypeMainWebApp. - */ - public String startParameter; - /** - * Parameters to use to open the Web App. - */ - public WebAppOpenParameters parameters; - - /** - * Default constructor for a function, which returns information needed to open the main Web App of a bot. - * - *

Returns {@link MainWebApp MainWebApp}

- */ - public GetMainWebApp() { - } - - /** - * Creates a function, which returns information needed to open the main Web App of a bot. - * - *

Returns {@link MainWebApp MainWebApp}

- * - * @param chatId Identifier of the chat in which the Web App is opened; pass 0 if none. - * @param botUserId Identifier of the target bot. If the bot is restricted for the current user, then show an error instead of calling the method. - * @param startParameter Start parameter from internalLinkTypeMainWebApp. - * @param parameters Parameters to use to open the Web App. - */ - public GetMainWebApp(long chatId, long botUserId, String startParameter, WebAppOpenParameters parameters) { - this.chatId = chatId; - this.botUserId = botUserId; - this.startParameter = startParameter; - this.parameters = parameters; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 594050214; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a file with a map thumbnail in PNG format. Only map thumbnail files with size less than 1MB can be downloaded. - * - *

Returns {@link File File}

- */ - public static class GetMapThumbnailFile extends Function { - /** - * Location of the map center. - */ - public Location location; - /** - * Map zoom level; 13-20. - */ - public int zoom; - /** - * Map width in pixels before applying scale; 16-1024. - */ - public int width; - /** - * Map height in pixels before applying scale; 16-1024. - */ - public int height; - /** - * Map scale; 1-3. - */ - public int scale; - /** - * Identifier of a chat in which the thumbnail will be shown. Use 0 if unknown. - */ - public long chatId; - - /** - * Default constructor for a function, which returns information about a file with a map thumbnail in PNG format. Only map thumbnail files with size less than 1MB can be downloaded. - * - *

Returns {@link File File}

- */ - public GetMapThumbnailFile() { - } - - /** - * Creates a function, which returns information about a file with a map thumbnail in PNG format. Only map thumbnail files with size less than 1MB can be downloaded. - * - *

Returns {@link File File}

- * - * @param location Location of the map center. - * @param zoom Map zoom level; 13-20. - * @param width Map width in pixels before applying scale; 16-1024. - * @param height Map height in pixels before applying scale; 16-1024. - * @param scale Map scale; 1-3. - * @param chatId Identifier of a chat in which the thumbnail will be shown. Use 0 if unknown. - */ - public GetMapThumbnailFile(Location location, int zoom, int width, int height, int scale, long chatId) { - this.location = location; - this.zoom = zoom; - this.width = width; - this.height = height; - this.scale = scale; - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -152660070; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Replaces text entities with Markdown formatting in a human-friendly format. Entities that can't be represented in Markdown unambiguously are kept as is. Can be called synchronously. - * - *

Returns {@link FormattedText FormattedText}

- */ - public static class GetMarkdownText extends Function { - /** - * The text. - */ - public FormattedText text; - - /** - * Default constructor for a function, which replaces text entities with Markdown formatting in a human-friendly format. Entities that can't be represented in Markdown unambiguously are kept as is. Can be called synchronously. - * - *

Returns {@link FormattedText FormattedText}

- */ - public GetMarkdownText() { - } - - /** - * Creates a function, which replaces text entities with Markdown formatting in a human-friendly format. Entities that can't be represented in Markdown unambiguously are kept as is. Can be called synchronously. - * - *

Returns {@link FormattedText FormattedText}

- * - * @param text The text. - */ - public GetMarkdownText(FormattedText text) { - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 164524584; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the current user. - * - *

Returns {@link User User}

- */ - public static class GetMe extends Function { - - /** - * Default constructor for a function, which returns the current user. - * - *

Returns {@link User User}

- */ - public GetMe() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -191516033; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns menu button set by the bot for the given user; for bots only. - * - *

Returns {@link BotMenuButton BotMenuButton}

- */ - public static class GetMenuButton extends Function { - /** - * Identifier of the user or 0 to get the default menu button. - */ - public long userId; - - /** - * Default constructor for a function, which returns menu button set by the bot for the given user; for bots only. - * - *

Returns {@link BotMenuButton BotMenuButton}

- */ - public GetMenuButton() { - } - - /** - * Creates a function, which returns menu button set by the bot for the given user; for bots only. - * - *

Returns {@link BotMenuButton BotMenuButton}

- * - * @param userId Identifier of the user or 0 to get the default menu button. - */ - public GetMenuButton(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -437324736; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a message. Returns a 404 error if the message doesn't exist. - * - *

Returns {@link Message Message}

- */ - public static class GetMessage extends Function { - /** - * Identifier of the chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message to get. - */ - public long messageId; - - /** - * Default constructor for a function, which returns information about a message. Returns a 404 error if the message doesn't exist. - * - *

Returns {@link Message Message}

- */ - public GetMessage() { - } - - /** - * Creates a function, which returns information about a message. Returns a 404 error if the message doesn't exist. - * - *

Returns {@link Message Message}

- * - * @param chatId Identifier of the chat the message belongs to. - * @param messageId Identifier of the message to get. - */ - public GetMessage(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1821196160; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns reactions added for a message, along with their sender. - * - *

Returns {@link AddedReactions AddedReactions}

- */ - public static class GetMessageAddedReactions extends Function { - /** - * Identifier of the chat to which the message belongs. - */ - public long chatId; - /** - * Identifier of the message. Use message.interactionInfo.reactions.canGetAddedReactions to check whether added reactions can be received for the message. - */ - public long messageId; - /** - * Type of the reactions to return; pass null to return all added reactions; reactionTypePaid isn't supported. - */ - public ReactionType reactionType; - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of reactions to be returned; must be positive and can't be greater than 100. - */ - public int limit; - - /** - * Default constructor for a function, which returns reactions added for a message, along with their sender. - * - *

Returns {@link AddedReactions AddedReactions}

- */ - public GetMessageAddedReactions() { - } - - /** - * Creates a function, which returns reactions added for a message, along with their sender. - * - *

Returns {@link AddedReactions AddedReactions}

- * - * @param chatId Identifier of the chat to which the message belongs. - * @param messageId Identifier of the message. Use message.interactionInfo.reactions.canGetAddedReactions to check whether added reactions can be received for the message. - * @param reactionType Type of the reactions to return; pass null to return all added reactions; reactionTypePaid isn't supported. - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of reactions to be returned; must be positive and can't be greater than 100. - */ - public GetMessageAddedReactions(long chatId, long messageId, ReactionType reactionType, String offset, int limit) { - this.chatId = chatId; - this.messageId = messageId; - this.reactionType = reactionType; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2110172754; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about actual author of a message sent on behalf of a channel. The method can be called if messageProperties.canGetAuthor == true. - * - *

Returns {@link User User}

- */ - public static class GetMessageAuthor extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - - /** - * Default constructor for a function, which returns information about actual author of a message sent on behalf of a channel. The method can be called if messageProperties.canGetAuthor == true. - * - *

Returns {@link User User}

- */ - public GetMessageAuthor() { - } - - /** - * Creates a function, which returns information about actual author of a message sent on behalf of a channel. The method can be called if messageProperties.canGetAuthor == true. - * - *

Returns {@link User User}

- * - * @param chatId Chat identifier. - * @param messageId Identifier of the message. - */ - public GetMessageAuthor(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1890166449; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns reactions, which can be added to a message. The list can change after updateActiveEmojiReactions, updateChatAvailableReactions for the chat, or updateMessageInteractionInfo for the message. - * - *

Returns {@link AvailableReactions AvailableReactions}

- */ - public static class GetMessageAvailableReactions extends Function { - /** - * Identifier of the chat to which the message belongs. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * Number of reaction per row, 5-25. - */ - public int rowSize; - - /** - * Default constructor for a function, which returns reactions, which can be added to a message. The list can change after updateActiveEmojiReactions, updateChatAvailableReactions for the chat, or updateMessageInteractionInfo for the message. - * - *

Returns {@link AvailableReactions AvailableReactions}

- */ - public GetMessageAvailableReactions() { - } - - /** - * Creates a function, which returns reactions, which can be added to a message. The list can change after updateActiveEmojiReactions, updateChatAvailableReactions for the chat, or updateMessageInteractionInfo for the message. - * - *

Returns {@link AvailableReactions AvailableReactions}

- * - * @param chatId Identifier of the chat to which the message belongs. - * @param messageId Identifier of the message. - * @param rowSize Number of reaction per row, 5-25. - */ - public GetMessageAvailableReactions(long chatId, long messageId, int rowSize) { - this.chatId = chatId; - this.messageId = messageId; - this.rowSize = rowSize; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1994098354; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a message effect. Returns a 404 error if the effect is not found. - * - *

Returns {@link MessageEffect MessageEffect}

- */ - public static class GetMessageEffect extends Function { - /** - * Unique identifier of the effect. - */ - public long effectId; - - /** - * Default constructor for a function, which returns information about a message effect. Returns a 404 error if the effect is not found. - * - *

Returns {@link MessageEffect MessageEffect}

- */ - public GetMessageEffect() { - } - - /** - * Creates a function, which returns information about a message effect. Returns a 404 error if the effect is not found. - * - *

Returns {@link MessageEffect MessageEffect}

- * - * @param effectId Unique identifier of the effect. - */ - public GetMessageEffect(long effectId) { - this.effectId = effectId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1638843116; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an HTML code for embedding the message. Available only if messageProperties.canGetEmbeddingCode. - * - *

Returns {@link Text Text}

- */ - public static class GetMessageEmbeddingCode extends Function { - /** - * Identifier of the chat to which the message belongs. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * Pass true to return an HTML code for embedding of the whole media album. - */ - public boolean forAlbum; - - /** - * Default constructor for a function, which returns an HTML code for embedding the message. Available only if messageProperties.canGetEmbeddingCode. - * - *

Returns {@link Text Text}

- */ - public GetMessageEmbeddingCode() { - } - - /** - * Creates a function, which returns an HTML code for embedding the message. Available only if messageProperties.canGetEmbeddingCode. - * - *

Returns {@link Text Text}

- * - * @param chatId Identifier of the chat to which the message belongs. - * @param messageId Identifier of the message. - * @param forAlbum Pass true to return an HTML code for embedding of the whole media album. - */ - public GetMessageEmbeddingCode(long chatId, long messageId, boolean forAlbum) { - this.chatId = chatId; - this.messageId = messageId; - this.forAlbum = forAlbum; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1654967561; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a file with messages exported from another application. - * - *

Returns {@link MessageFileType MessageFileType}

- */ - public static class GetMessageFileType extends Function { - /** - * Beginning of the message file; up to 100 first lines. - */ - public String messageFileHead; - - /** - * Default constructor for a function, which returns information about a file with messages exported from another application. - * - *

Returns {@link MessageFileType MessageFileType}

- */ - public GetMessageFileType() { - } - - /** - * Creates a function, which returns information about a file with messages exported from another application. - * - *

Returns {@link MessageFileType MessageFileType}

- * - * @param messageFileHead Beginning of the message file; up to 100 first lines. - */ - public GetMessageFileType(String messageFileHead) { - this.messageFileHead = messageFileHead; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -490270764; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a confirmation text to be shown to the user before starting message import. - * - *

Returns {@link Text Text}

- */ - public static class GetMessageImportConfirmationText extends Function { - /** - * Identifier of a chat to which the messages will be imported. It must be an identifier of a private chat with a mutual contact or an identifier of a supergroup chat with canChangeInfo member right. - */ - public long chatId; - - /** - * Default constructor for a function, which returns a confirmation text to be shown to the user before starting message import. - * - *

Returns {@link Text Text}

- */ - public GetMessageImportConfirmationText() { - } - - /** - * Creates a function, which returns a confirmation text to be shown to the user before starting message import. - * - *

Returns {@link Text Text}

- * - * @param chatId Identifier of a chat to which the messages will be imported. It must be an identifier of a private chat with a mutual contact or an identifier of a supergroup chat with canChangeInfo member right. - */ - public GetMessageImportConfirmationText(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 390627752; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an HTTPS link to a message in a chat. Available only if messageProperties.canGetLink, or if messageProperties.canGetMediaTimestampLinks and a media timestamp link is generated. This is an offline method. - * - *

Returns {@link MessageLink MessageLink}

- */ - public static class GetMessageLink extends Function { - /** - * Identifier of the chat to which the message belongs. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * If not 0, timestamp from which the video/audio/video note/voice note/story playing must start, in seconds. The media can be in the message content or in its link preview. - */ - public int mediaTimestamp; - /** - * Pass true to create a link for the whole media album. - */ - public boolean forAlbum; - /** - * Pass true to create a link to the message as a channel post comment, in a message thread, or a forum topic. - */ - public boolean inMessageThread; - - /** - * Default constructor for a function, which returns an HTTPS link to a message in a chat. Available only if messageProperties.canGetLink, or if messageProperties.canGetMediaTimestampLinks and a media timestamp link is generated. This is an offline method. - * - *

Returns {@link MessageLink MessageLink}

- */ - public GetMessageLink() { - } - - /** - * Creates a function, which returns an HTTPS link to a message in a chat. Available only if messageProperties.canGetLink, or if messageProperties.canGetMediaTimestampLinks and a media timestamp link is generated. This is an offline method. - * - *

Returns {@link MessageLink MessageLink}

- * - * @param chatId Identifier of the chat to which the message belongs. - * @param messageId Identifier of the message. - * @param mediaTimestamp If not 0, timestamp from which the video/audio/video note/voice note/story playing must start, in seconds. The media can be in the message content or in its link preview. - * @param forAlbum Pass true to create a link for the whole media album. - * @param inMessageThread Pass true to create a link to the message as a channel post comment, in a message thread, or a forum topic. - */ - public GetMessageLink(long chatId, long messageId, int mediaTimestamp, boolean forAlbum, boolean inMessageThread) { - this.chatId = chatId; - this.messageId = messageId; - this.mediaTimestamp = mediaTimestamp; - this.forAlbum = forAlbum; - this.inMessageThread = inMessageThread; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -984158342; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a public or private message link. Can be called for any internal link of the type internalLinkTypeMessage. - * - *

Returns {@link MessageLinkInfo MessageLinkInfo}

- */ - public static class GetMessageLinkInfo extends Function { - /** - * The message link. - */ - public String url; - - /** - * Default constructor for a function, which returns information about a public or private message link. Can be called for any internal link of the type internalLinkTypeMessage. - * - *

Returns {@link MessageLinkInfo MessageLinkInfo}

- */ - public GetMessageLinkInfo() { - } - - /** - * Creates a function, which returns information about a public or private message link. Can be called for any internal link of the type internalLinkTypeMessage. - * - *

Returns {@link MessageLinkInfo MessageLinkInfo}

- * - * @param url The message link. - */ - public GetMessageLinkInfo(String url) { - this.url = url; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -700533672; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a message, if it is available without sending network request. Returns a 404 error if message isn't available locally. This is an offline method. - * - *

Returns {@link Message Message}

- */ - public static class GetMessageLocally extends Function { - /** - * Identifier of the chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message to get. - */ - public long messageId; - - /** - * Default constructor for a function, which returns information about a message, if it is available without sending network request. Returns a 404 error if message isn't available locally. This is an offline method. - * - *

Returns {@link Message Message}

- */ - public GetMessageLocally() { - } - - /** - * Creates a function, which returns information about a message, if it is available without sending network request. Returns a 404 error if message isn't available locally. This is an offline method. - * - *

Returns {@link Message Message}

- * - * @param chatId Identifier of the chat the message belongs to. - * @param messageId Identifier of the message to get. - */ - public GetMessageLocally(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -603575444; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns properties of a message. This is an offline method. - * - *

Returns {@link MessageProperties MessageProperties}

- */ - public static class GetMessageProperties extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - - /** - * Default constructor for a function, which returns properties of a message. This is an offline method. - * - *

Returns {@link MessageProperties MessageProperties}

- */ - public GetMessageProperties() { - } - - /** - * Creates a function, which returns properties of a message. This is an offline method. - * - *

Returns {@link MessageProperties MessageProperties}

- * - * @param chatId Chat identifier. - * @param messageId Identifier of the message. - */ - public GetMessageProperties(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 773382571; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns forwarded copies of a channel message to different public channels and public reposts as a story. Can be used only if messageProperties.canGetStatistics == true. For optimal performance, the number of returned messages and stories is chosen by TDLib. - * - *

Returns {@link PublicForwards PublicForwards}

- */ - public static class GetMessagePublicForwards extends Function { - /** - * Chat identifier of the message. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of messages and stories to be returned; must be positive and can't be greater than 100. For optimal performance, the number of returned objects is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which returns forwarded copies of a channel message to different public channels and public reposts as a story. Can be used only if messageProperties.canGetStatistics == true. For optimal performance, the number of returned messages and stories is chosen by TDLib. - * - *

Returns {@link PublicForwards PublicForwards}

- */ - public GetMessagePublicForwards() { - } - - /** - * Creates a function, which returns forwarded copies of a channel message to different public channels and public reposts as a story. Can be used only if messageProperties.canGetStatistics == true. For optimal performance, the number of returned messages and stories is chosen by TDLib. - * - *

Returns {@link PublicForwards PublicForwards}

- * - * @param chatId Chat identifier of the message. - * @param messageId Message identifier. - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of messages and stories to be returned; must be positive and can't be greater than 100. For optimal performance, the number of returned objects is chosen by TDLib and can be smaller than the specified limit. - */ - public GetMessagePublicForwards(long chatId, long messageId, String offset, int limit) { - this.chatId = chatId; - this.messageId = messageId; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1369285812; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns read date of a recent outgoing message in a private chat. The method can be called if messageProperties.canGetReadDate == true. - * - *

Returns {@link MessageReadDate MessageReadDate}

- */ - public static class GetMessageReadDate extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - - /** - * Default constructor for a function, which returns read date of a recent outgoing message in a private chat. The method can be called if messageProperties.canGetReadDate == true. - * - *

Returns {@link MessageReadDate MessageReadDate}

- */ - public GetMessageReadDate() { - } - - /** - * Creates a function, which returns read date of a recent outgoing message in a private chat. The method can be called if messageProperties.canGetReadDate == true. - * - *

Returns {@link MessageReadDate MessageReadDate}

- * - * @param chatId Chat identifier. - * @param messageId Identifier of the message. - */ - public GetMessageReadDate(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1484455101; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns detailed statistics about a message. Can be used only if messageProperties.canGetStatistics == true. - * - *

Returns {@link MessageStatistics MessageStatistics}

- */ - public static class GetMessageStatistics extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - /** - * Pass true if a dark theme is used by the application. - */ - public boolean isDark; - - /** - * Default constructor for a function, which returns detailed statistics about a message. Can be used only if messageProperties.canGetStatistics == true. - * - *

Returns {@link MessageStatistics MessageStatistics}

- */ - public GetMessageStatistics() { - } - - /** - * Creates a function, which returns detailed statistics about a message. Can be used only if messageProperties.canGetStatistics == true. - * - *

Returns {@link MessageStatistics MessageStatistics}

- * - * @param chatId Chat identifier. - * @param messageId Message identifier. - * @param isDark Pass true if a dark theme is used by the application. - */ - public GetMessageStatistics(long chatId, long messageId, boolean isDark) { - this.chatId = chatId; - this.messageId = messageId; - this.isDark = isDark; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1270194648; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a message thread. Can be used only if messageProperties.canGetMessageThread == true. - * - *

Returns {@link MessageThreadInfo MessageThreadInfo}

- */ - public static class GetMessageThread extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - - /** - * Default constructor for a function, which returns information about a message thread. Can be used only if messageProperties.canGetMessageThread == true. - * - *

Returns {@link MessageThreadInfo MessageThreadInfo}

- */ - public GetMessageThread() { - } - - /** - * Creates a function, which returns information about a message thread. Can be used only if messageProperties.canGetMessageThread == true. - * - *

Returns {@link MessageThreadInfo MessageThreadInfo}

- * - * @param chatId Chat identifier. - * @param messageId Identifier of the message. - */ - public GetMessageThread(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2062695998; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns messages in a message thread of a message. Can be used only if messageProperties.canGetMessageThread == true. Message thread of a channel message is in the channel's linked supergroup. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). For optimal performance, the number of returned messages is chosen by TDLib. - * - *

Returns {@link Messages Messages}

- */ - public static class GetMessageThreadHistory extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Message identifier, which thread history needs to be returned. - */ - public long messageId; - /** - * Identifier of the message starting from which history must be fetched; use 0 to get results from the last message. - */ - public long fromMessageId; - /** - * Specify 0 to get results from exactly the message fromMessageId or a negative number from -99 to -1 to get additionally -offset newer messages. - */ - public int offset; - /** - * The maximum number of messages to be returned; must be positive and can't be greater than 100. If the offset is negative, then the limit must be greater than or equal to -offset. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which returns messages in a message thread of a message. Can be used only if messageProperties.canGetMessageThread == true. Message thread of a channel message is in the channel's linked supergroup. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). For optimal performance, the number of returned messages is chosen by TDLib. - * - *

Returns {@link Messages Messages}

- */ - public GetMessageThreadHistory() { - } - - /** - * Creates a function, which returns messages in a message thread of a message. Can be used only if messageProperties.canGetMessageThread == true. Message thread of a channel message is in the channel's linked supergroup. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). For optimal performance, the number of returned messages is chosen by TDLib. - * - *

Returns {@link Messages Messages}

- * - * @param chatId Chat identifier. - * @param messageId Message identifier, which thread history needs to be returned. - * @param fromMessageId Identifier of the message starting from which history must be fetched; use 0 to get results from the last message. - * @param offset Specify 0 to get results from exactly the message fromMessageId or a negative number from -99 to -1 to get additionally -offset newer messages. - * @param limit The maximum number of messages to be returned; must be positive and can't be greater than 100. If the offset is negative, then the limit must be greater than or equal to -offset. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public GetMessageThreadHistory(long chatId, long messageId, long fromMessageId, int offset, int limit) { - this.chatId = chatId; - this.messageId = messageId; - this.fromMessageId = fromMessageId; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1808411608; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns viewers of a recent outgoing message in a basic group or a supergroup chat. For video notes and voice notes only users, opened content of the message, are returned. The method can be called if messageProperties.canGetViewers == true. - * - *

Returns {@link MessageViewers MessageViewers}

- */ - public static class GetMessageViewers extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - - /** - * Default constructor for a function, which returns viewers of a recent outgoing message in a basic group or a supergroup chat. For video notes and voice notes only users, opened content of the message, are returned. The method can be called if messageProperties.canGetViewers == true. - * - *

Returns {@link MessageViewers MessageViewers}

- */ - public GetMessageViewers() { - } - - /** - * Creates a function, which returns viewers of a recent outgoing message in a basic group or a supergroup chat. For video notes and voice notes only users, opened content of the message, are returned. The method can be called if messageProperties.canGetViewers == true. - * - *

Returns {@link MessageViewers MessageViewers}

- * - * @param chatId Chat identifier. - * @param messageId Identifier of the message. - */ - public GetMessageViewers(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1584457010; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about messages. If a message is not found, returns null on the corresponding position of the result. - * - *

Returns {@link Messages Messages}

- */ - public static class GetMessages extends Function { - /** - * Identifier of the chat the messages belong to. - */ - public long chatId; - /** - * Identifiers of the messages to get. - */ - public long[] messageIds; - - /** - * Default constructor for a function, which returns information about messages. If a message is not found, returns null on the corresponding position of the result. - * - *

Returns {@link Messages Messages}

- */ - public GetMessages() { - } - - /** - * Creates a function, which returns information about messages. If a message is not found, returns null on the corresponding position of the result. - * - *

Returns {@link Messages Messages}

- * - * @param chatId Identifier of the chat the messages belong to. - * @param messageIds Identifiers of the messages to get. - */ - public GetMessages(long chatId, long[] messageIds) { - this.chatId = chatId; - this.messageIds = messageIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 425299338; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns network data usage statistics. Can be called before authorization. - * - *

Returns {@link NetworkStatistics NetworkStatistics}

- */ - public static class GetNetworkStatistics extends Function { - /** - * Pass true to get statistics only for the current library launch. - */ - public boolean onlyCurrent; - - /** - * Default constructor for a function, which returns network data usage statistics. Can be called before authorization. - * - *

Returns {@link NetworkStatistics NetworkStatistics}

- */ - public GetNetworkStatistics() { - } - - /** - * Creates a function, which returns network data usage statistics. Can be called before authorization. - * - *

Returns {@link NetworkStatistics NetworkStatistics}

- * - * @param onlyCurrent Pass true to get statistics only for the current library launch. - */ - public GetNetworkStatistics(boolean onlyCurrent) { - this.onlyCurrent = onlyCurrent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -986228706; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns privacy settings for new chat creation. - * - *

Returns {@link NewChatPrivacySettings NewChatPrivacySettings}

- */ - public static class GetNewChatPrivacySettings extends Function { - - /** - * Default constructor for a function, which returns privacy settings for new chat creation. - * - *

Returns {@link NewChatPrivacySettings NewChatPrivacySettings}

- */ - public GetNewChatPrivacySettings() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1295299657; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about an OAuth deep link. Use checkOauthRequestMatchCode, acceptOauthRequest or declineOauthRequest to process the link. - * - *

Returns {@link OauthLinkInfo OauthLinkInfo}

- */ - public static class GetOauthLinkInfo extends Function { - /** - * URL of the link. - */ - public String url; - /** - * Origin of the OAuth request if the request was received from the in-app browser; pass an empty string otherwise. - */ - public String inAppOrigin; - - /** - * Default constructor for a function, which returns information about an OAuth deep link. Use checkOauthRequestMatchCode, acceptOauthRequest or declineOauthRequest to process the link. - * - *

Returns {@link OauthLinkInfo OauthLinkInfo}

- */ - public GetOauthLinkInfo() { - } - - /** - * Creates a function, which returns information about an OAuth deep link. Use checkOauthRequestMatchCode, acceptOauthRequest or declineOauthRequest to process the link. - * - *

Returns {@link OauthLinkInfo OauthLinkInfo}

- * - * @param url URL of the link. - * @param inAppOrigin Origin of the OAuth request if the request was received from the in-app browser; pass an empty string otherwise. - */ - public GetOauthLinkInfo(String url, String inAppOrigin) { - this.url = url; - this.inAppOrigin = inAppOrigin; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1235634833; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the value of an option by its name. (Check the list of available options on https://core.telegram.org/tdlib/options.) Can be called before authorization. Can be called synchronously for options "version" and "commit_hash". - * - *

Returns {@link OptionValue OptionValue}

- */ - public static class GetOption extends Function { - /** - * The name of the option. - */ - public String name; - - /** - * Default constructor for a function, which returns the value of an option by its name. (Check the list of available options on https://core.telegram.org/tdlib/options.) Can be called before authorization. Can be called synchronously for options "version" and "commit_hash". - * - *

Returns {@link OptionValue OptionValue}

- */ - public GetOption() { - } - - /** - * Creates a function, which returns the value of an option by its name. (Check the list of available options on https://core.telegram.org/tdlib/options.) Can be called before authorization. Can be called synchronously for options "version" and "commit_hash". - * - *

Returns {@link OptionValue OptionValue}

- * - * @param name The name of the option. - */ - public GetOption(String name) { - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1572495746; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of bots owned by the current user. - * - *

Returns {@link Users Users}

- */ - public static class GetOwnedBots extends Function { - - /** - * Default constructor for a function, which returns the list of bots owned by the current user. - * - *

Returns {@link Users Users}

- */ - public GetOwnedBots() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1954035715; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns sticker sets owned by the current user. - * - *

Returns {@link StickerSets StickerSets}

- */ - public static class GetOwnedStickerSets extends Function { - /** - * Identifier of the sticker set from which to return owned sticker sets; use 0 to get results from the beginning. - */ - public long offsetStickerSetId; - /** - * The maximum number of sticker sets to be returned; must be positive and can't be greater than 100. For optimal performance, the number of returned objects is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which returns sticker sets owned by the current user. - * - *

Returns {@link StickerSets StickerSets}

- */ - public GetOwnedStickerSets() { - } - - /** - * Creates a function, which returns sticker sets owned by the current user. - * - *

Returns {@link StickerSets StickerSets}

- * - * @param offsetStickerSetId Identifier of the sticker set from which to return owned sticker sets; use 0 to get results from the beginning. - * @param limit The maximum number of sticker sets to be returned; must be positive and can't be greater than 100. For optimal performance, the number of returned objects is chosen by TDLib and can be smaller than the specified limit. - */ - public GetOwnedStickerSets(long offsetStickerSetId, int limit) { - this.offsetStickerSetId = offsetStickerSetId; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1493074208; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the total number of Telegram Stars received by the current user for paid messages from the given user. - * - *

Returns {@link StarCount StarCount}

- */ - public static class GetPaidMessageRevenue extends Function { - /** - * Identifier of the user. - */ - public long userId; - - /** - * Default constructor for a function, which returns the total number of Telegram Stars received by the current user for paid messages from the given user. - * - *

Returns {@link StarCount StarCount}

- */ - public GetPaidMessageRevenue() { - } - - /** - * Creates a function, which returns the total number of Telegram Stars received by the current user for paid messages from the given user. - * - *

Returns {@link StarCount StarCount}

- * - * @param userId Identifier of the user. - */ - public GetPaidMessageRevenue(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1976589102; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns parameters for creating of a new passkey as JSON-serialized string. - * - *

Returns {@link Text Text}

- */ - public static class GetPasskeyParameters extends Function { - - /** - * Default constructor for a function, which returns parameters for creating of a new passkey as JSON-serialized string. - * - *

Returns {@link Text Text}

- */ - public GetPasskeyParameters() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -680161058; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a Telegram Passport authorization form for sharing data with a service. - * - *

Returns {@link PassportAuthorizationForm PassportAuthorizationForm}

- */ - public static class GetPassportAuthorizationForm extends Function { - /** - * User identifier of the service's bot. - */ - public long botUserId; - /** - * Telegram Passport element types requested by the service. - */ - public String scope; - /** - * Service's public key. - */ - public String publicKey; - /** - * Unique request identifier provided by the service. - */ - public String nonce; - - /** - * Default constructor for a function, which returns a Telegram Passport authorization form for sharing data with a service. - * - *

Returns {@link PassportAuthorizationForm PassportAuthorizationForm}

- */ - public GetPassportAuthorizationForm() { - } - - /** - * Creates a function, which returns a Telegram Passport authorization form for sharing data with a service. - * - *

Returns {@link PassportAuthorizationForm PassportAuthorizationForm}

- * - * @param botUserId User identifier of the service's bot. - * @param scope Telegram Passport element types requested by the service. - * @param publicKey Service's public key. - * @param nonce Unique request identifier provided by the service. - */ - public GetPassportAuthorizationForm(long botUserId, String scope, String publicKey, String nonce) { - this.botUserId = botUserId; - this.scope = scope; - this.publicKey = publicKey; - this.nonce = nonce; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1636107398; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns already available Telegram Passport elements suitable for completing a Telegram Passport authorization form. Result can be received only once for each authorization form. - * - *

Returns {@link PassportElementsWithErrors PassportElementsWithErrors}

- */ - public static class GetPassportAuthorizationFormAvailableElements extends Function { - /** - * Authorization form identifier. - */ - public int authorizationFormId; - /** - * The 2-step verification password of the current user. - */ - public String password; - - /** - * Default constructor for a function, which returns already available Telegram Passport elements suitable for completing a Telegram Passport authorization form. Result can be received only once for each authorization form. - * - *

Returns {@link PassportElementsWithErrors PassportElementsWithErrors}

- */ - public GetPassportAuthorizationFormAvailableElements() { - } - - /** - * Creates a function, which returns already available Telegram Passport elements suitable for completing a Telegram Passport authorization form. Result can be received only once for each authorization form. - * - *

Returns {@link PassportElementsWithErrors PassportElementsWithErrors}

- * - * @param authorizationFormId Authorization form identifier. - * @param password The 2-step verification password of the current user. - */ - public GetPassportAuthorizationFormAvailableElements(int authorizationFormId, String password) { - this.authorizationFormId = authorizationFormId; - this.password = password; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1068700924; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns one of the available Telegram Passport elements. - * - *

Returns {@link PassportElement PassportElement}

- */ - public static class GetPassportElement extends Function { - /** - * Telegram Passport element type. - */ - public PassportElementType type; - /** - * The 2-step verification password of the current user. - */ - public String password; - - /** - * Default constructor for a function, which returns one of the available Telegram Passport elements. - * - *

Returns {@link PassportElement PassportElement}

- */ - public GetPassportElement() { - } - - /** - * Creates a function, which returns one of the available Telegram Passport elements. - * - *

Returns {@link PassportElement PassportElement}

- * - * @param type Telegram Passport element type. - * @param password The 2-step verification password of the current user. - */ - public GetPassportElement(PassportElementType type, String password) { - this.type = type; - this.password = password; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1882398342; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the current state of 2-step verification. - * - *

Returns {@link PasswordState PasswordState}

- */ - public static class GetPasswordState extends Function { - - /** - * Default constructor for a function, which returns the current state of 2-step verification. - * - *

Returns {@link PasswordState PasswordState}

- */ - public GetPasswordState() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -174752904; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an invoice payment form. This method must be called when the user presses inline button of the type inlineKeyboardButtonTypeBuy, or wants to buy access to media in a messagePaidMedia message. - * - *

Returns {@link PaymentForm PaymentForm}

- */ - public static class GetPaymentForm extends Function { - /** - * The invoice. - */ - public InputInvoice inputInvoice; - /** - * Preferred payment form theme; pass null to use the default theme. - */ - public ThemeParameters theme; - - /** - * Default constructor for a function, which returns an invoice payment form. This method must be called when the user presses inline button of the type inlineKeyboardButtonTypeBuy, or wants to buy access to media in a messagePaidMedia message. - * - *

Returns {@link PaymentForm PaymentForm}

- */ - public GetPaymentForm() { - } - - /** - * Creates a function, which returns an invoice payment form. This method must be called when the user presses inline button of the type inlineKeyboardButtonTypeBuy, or wants to buy access to media in a messagePaidMedia message. - * - *

Returns {@link PaymentForm PaymentForm}

- * - * @param inputInvoice The invoice. - * @param theme Preferred payment form theme; pass null to use the default theme. - */ - public GetPaymentForm(InputInvoice inputInvoice, ThemeParameters theme) { - this.inputInvoice = inputInvoice; - this.theme = theme; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1924172076; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a successful payment. - * - *

Returns {@link PaymentReceipt PaymentReceipt}

- */ - public static class GetPaymentReceipt extends Function { - /** - * Chat identifier of the messagePaymentSuccessful message. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - - /** - * Default constructor for a function, which returns information about a successful payment. - * - *

Returns {@link PaymentReceipt PaymentReceipt}

- */ - public GetPaymentReceipt() { - } - - /** - * Creates a function, which returns information about a successful payment. - * - *

Returns {@link PaymentReceipt PaymentReceipt}

- * - * @param chatId Chat identifier of the messagePaymentSuccessful message. - * @param messageId Message identifier. - */ - public GetPaymentReceipt(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1013758294; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a phone number by its prefix. Can be called before authorization. - * - *

Returns {@link PhoneNumberInfo PhoneNumberInfo}

- */ - public static class GetPhoneNumberInfo extends Function { - /** - * The phone number prefix. - */ - public String phoneNumberPrefix; - - /** - * Default constructor for a function, which returns information about a phone number by its prefix. Can be called before authorization. - * - *

Returns {@link PhoneNumberInfo PhoneNumberInfo}

- */ - public GetPhoneNumberInfo() { - } - - /** - * Creates a function, which returns information about a phone number by its prefix. Can be called before authorization. - * - *

Returns {@link PhoneNumberInfo PhoneNumberInfo}

- * - * @param phoneNumberPrefix The phone number prefix. - */ - public GetPhoneNumberInfo(String phoneNumberPrefix) { - this.phoneNumberPrefix = phoneNumberPrefix; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1608344583; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a phone number by its prefix synchronously. getCountries must be called at least once after changing localization to the specified language if properly localized country information is expected. Can be called synchronously. - * - *

Returns {@link PhoneNumberInfo PhoneNumberInfo}

- */ - public static class GetPhoneNumberInfoSync extends Function { - /** - * A two-letter ISO 639-1 language code for country information localization. - */ - public String languageCode; - /** - * The phone number prefix. - */ - public String phoneNumberPrefix; - - /** - * Default constructor for a function, which returns information about a phone number by its prefix synchronously. getCountries must be called at least once after changing localization to the specified language if properly localized country information is expected. Can be called synchronously. - * - *

Returns {@link PhoneNumberInfo PhoneNumberInfo}

- */ - public GetPhoneNumberInfoSync() { - } - - /** - * Creates a function, which returns information about a phone number by its prefix synchronously. getCountries must be called at least once after changing localization to the specified language if properly localized country information is expected. Can be called synchronously. - * - *

Returns {@link PhoneNumberInfo PhoneNumberInfo}

- * - * @param languageCode A two-letter ISO 639-1 language code for country information localization. - * @param phoneNumberPrefix The phone number prefix. - */ - public GetPhoneNumberInfoSync(String languageCode, String phoneNumberPrefix) { - this.languageCode = languageCode; - this.phoneNumberPrefix = phoneNumberPrefix; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 547061048; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns message senders voted for the specified option in a non-anonymous polls. For optimal performance, the number of returned users is chosen by TDLib. - * - *

Returns {@link PollVoters PollVoters}

- */ - public static class GetPollVoters extends Function { - /** - * Identifier of the chat to which the poll belongs. - */ - public long chatId; - /** - * Identifier of the message containing the poll. - */ - public long messageId; - /** - * 0-based identifier of the answer option. - */ - public int optionId; - /** - * Number of voters to skip in the result; must be non-negative. - */ - public int offset; - /** - * The maximum number of voters to be returned; must be positive and can't be greater than 50. For optimal performance, the number of returned voters is chosen by TDLib and can be smaller than the specified limit, even if the end of the voter list has not been reached. - */ - public int limit; - - /** - * Default constructor for a function, which returns message senders voted for the specified option in a non-anonymous polls. For optimal performance, the number of returned users is chosen by TDLib. - * - *

Returns {@link PollVoters PollVoters}

- */ - public GetPollVoters() { - } - - /** - * Creates a function, which returns message senders voted for the specified option in a non-anonymous polls. For optimal performance, the number of returned users is chosen by TDLib. - * - *

Returns {@link PollVoters PollVoters}

- * - * @param chatId Identifier of the chat to which the poll belongs. - * @param messageId Identifier of the message containing the poll. - * @param optionId 0-based identifier of the answer option. - * @param offset Number of voters to skip in the result; must be non-negative. - * @param limit The maximum number of voters to be returned; must be positive and can't be greater than 50. For optimal performance, the number of returned voters is chosen by TDLib and can be smaller than the specified limit, even if the end of the voter list has not been reached. - */ - public GetPollVoters(long chatId, long messageId, int optionId, int offset, int limit) { - this.chatId = chatId; - this.messageId = messageId; - this.optionId = optionId; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1602915575; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an IETF language tag of the language preferred in the country, which must be used to fill native fields in Telegram Passport personal details. Returns a 404 error if unknown. - * - *

Returns {@link Text Text}

- */ - public static class GetPreferredCountryLanguage extends Function { - /** - * A two-letter ISO 3166-1 alpha-2 country code. - */ - public String countryCode; - - /** - * Default constructor for a function, which returns an IETF language tag of the language preferred in the country, which must be used to fill native fields in Telegram Passport personal details. Returns a 404 error if unknown. - * - *

Returns {@link Text Text}

- */ - public GetPreferredCountryLanguage() { - } - - /** - * Creates a function, which returns an IETF language tag of the language preferred in the country, which must be used to fill native fields in Telegram Passport personal details. Returns a 404 error if unknown. - * - *

Returns {@link Text Text}

- * - * @param countryCode A two-letter ISO 3166-1 alpha-2 country code. - */ - public GetPreferredCountryLanguage(String countryCode) { - this.countryCode = countryCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -933049386; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about features, available to Premium users. - * - *

Returns {@link PremiumFeatures PremiumFeatures}

- */ - public static class GetPremiumFeatures extends Function { - /** - * Source of the request; pass null if the method is called from some non-standard source. - */ - public PremiumSource source; - - /** - * Default constructor for a function, which returns information about features, available to Premium users. - * - *

Returns {@link PremiumFeatures PremiumFeatures}

- */ - public GetPremiumFeatures() { - } - - /** - * Creates a function, which returns information about features, available to Premium users. - * - *

Returns {@link PremiumFeatures PremiumFeatures}

- * - * @param source Source of the request; pass null if the method is called from some non-standard source. - */ - public GetPremiumFeatures(PremiumSource source) { - this.source = source; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1260640695; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns available options for gifting Telegram Premium to a user. - * - *

Returns {@link PremiumGiftPaymentOptions PremiumGiftPaymentOptions}

- */ - public static class GetPremiumGiftPaymentOptions extends Function { - - /** - * Default constructor for a function, which returns available options for gifting Telegram Premium to a user. - * - *

Returns {@link PremiumGiftPaymentOptions PremiumGiftPaymentOptions}

- */ - public GetPremiumGiftPaymentOptions() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -480334244; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns available options for creating of Telegram Premium giveaway or manual distribution of Telegram Premium among chat members. - * - *

Returns {@link PremiumGiveawayPaymentOptions PremiumGiveawayPaymentOptions}

- */ - public static class GetPremiumGiveawayPaymentOptions extends Function { - /** - * Identifier of the supergroup or channel chat, which will be automatically boosted by receivers of the gift codes and which is administered by the user. - */ - public long boostedChatId; - - /** - * Default constructor for a function, which returns available options for creating of Telegram Premium giveaway or manual distribution of Telegram Premium among chat members. - * - *

Returns {@link PremiumGiveawayPaymentOptions PremiumGiveawayPaymentOptions}

- */ - public GetPremiumGiveawayPaymentOptions() { - } - - /** - * Creates a function, which returns available options for creating of Telegram Premium giveaway or manual distribution of Telegram Premium among chat members. - * - *

Returns {@link PremiumGiveawayPaymentOptions PremiumGiveawayPaymentOptions}

- * - * @param boostedChatId Identifier of the supergroup or channel chat, which will be automatically boosted by receivers of the gift codes and which is administered by the user. - */ - public GetPremiumGiveawayPaymentOptions(long boostedChatId) { - this.boostedChatId = boostedChatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1222168073; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the sticker to be used as representation of the Telegram Premium subscription. - * - *

Returns {@link Sticker Sticker}

- */ - public static class GetPremiumInfoSticker extends Function { - /** - * Number of months the Telegram Premium subscription will be active. - */ - public int monthCount; - - /** - * Default constructor for a function, which returns the sticker to be used as representation of the Telegram Premium subscription. - * - *

Returns {@link Sticker Sticker}

- */ - public GetPremiumInfoSticker() { - } - - /** - * Creates a function, which returns the sticker to be used as representation of the Telegram Premium subscription. - * - *

Returns {@link Sticker Sticker}

- * - * @param monthCount Number of months the Telegram Premium subscription will be active. - */ - public GetPremiumInfoSticker(int monthCount) { - this.monthCount = monthCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2043562651; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a limit, increased for Premium users. Returns a 404 error if the limit is unknown. - * - *

Returns {@link PremiumLimit PremiumLimit}

- */ - public static class GetPremiumLimit extends Function { - /** - * Type of the limit. - */ - public PremiumLimitType limitType; - - /** - * Default constructor for a function, which returns information about a limit, increased for Premium users. Returns a 404 error if the limit is unknown. - * - *

Returns {@link PremiumLimit PremiumLimit}

- */ - public GetPremiumLimit() { - } - - /** - * Creates a function, which returns information about a limit, increased for Premium users. Returns a 404 error if the limit is unknown. - * - *

Returns {@link PremiumLimit PremiumLimit}

- * - * @param limitType Type of the limit. - */ - public GetPremiumLimit(PremiumLimitType limitType) { - this.limitType = limitType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1075313898; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns state of Telegram Premium subscription and promotion videos for Premium features. - * - *

Returns {@link PremiumState PremiumState}

- */ - public static class GetPremiumState extends Function { - - /** - * Default constructor for a function, which returns state of Telegram Premium subscription and promotion videos for Premium features. - * - *

Returns {@link PremiumState PremiumState}

- */ - public GetPremiumState() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 663632610; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns examples of premium stickers for demonstration purposes. - * - *

Returns {@link Stickers Stickers}

- */ - public static class GetPremiumStickerExamples extends Function { - - /** - * Default constructor for a function, which returns examples of premium stickers for demonstration purposes. - * - *

Returns {@link Stickers Stickers}

- */ - public GetPremiumStickerExamples() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1399442328; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns premium stickers from regular sticker sets. - * - *

Returns {@link Stickers Stickers}

- */ - public static class GetPremiumStickers extends Function { - /** - * The maximum number of stickers to be returned; 0-100. - */ - public int limit; - - /** - * Default constructor for a function, which returns premium stickers from regular sticker sets. - * - *

Returns {@link Stickers Stickers}

- */ - public GetPremiumStickers() { - } - - /** - * Creates a function, which returns premium stickers from regular sticker sets. - * - *

Returns {@link Stickers Stickers}

- * - * @param limit The maximum number of stickers to be returned; 0-100. - */ - public GetPremiumStickers(int limit) { - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -280950192; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Saves an inline message to be sent by the given user. - * - *

Returns {@link PreparedInlineMessage PreparedInlineMessage}

- */ - public static class GetPreparedInlineMessage extends Function { - /** - * Identifier of the bot that created the message. - */ - public long botUserId; - /** - * Identifier of the prepared message. - */ - public String preparedMessageId; - - /** - * Default constructor for a function, which saves an inline message to be sent by the given user. - * - *

Returns {@link PreparedInlineMessage PreparedInlineMessage}

- */ - public GetPreparedInlineMessage() { - } - - /** - * Creates a function, which saves an inline message to be sent by the given user. - * - *

Returns {@link PreparedInlineMessage PreparedInlineMessage}

- * - * @param botUserId Identifier of the bot that created the message. - * @param preparedMessageId Identifier of the prepared message. - */ - public GetPreparedInlineMessage(long botUserId, String preparedMessageId) { - this.botUserId = botUserId; - this.preparedMessageId = preparedMessageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -83179701; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of proxies that are currently set up. Can be called before authorization. - * - *

Returns {@link AddedProxies AddedProxies}

- */ - public static class GetProxies extends Function { - - /** - * Default constructor for a function, which returns the list of proxies that are currently set up. Can be called before authorization. - * - *

Returns {@link AddedProxies AddedProxies}

- */ - public GetProxies() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1234066431; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks public post search limits without actually performing the search. - * - *

Returns {@link PublicPostSearchLimits PublicPostSearchLimits}

- */ - public static class GetPublicPostSearchLimits extends Function { - /** - * Query that will be searched for. - */ - public String query; - - /** - * Default constructor for a function, which checks public post search limits without actually performing the search. - * - *

Returns {@link PublicPostSearchLimits PublicPostSearchLimits}

- */ - public GetPublicPostSearchLimits() { - } - - /** - * Creates a function, which checks public post search limits without actually performing the search. - * - *

Returns {@link PublicPostSearchLimits PublicPostSearchLimits}

- * - * @param query Query that will be searched for. - */ - public GetPublicPostSearchLimits(String query) { - this.query = query; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1724216773; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a globally unique push notification subscription identifier for identification of an account, which has received a push notification. Can be called synchronously. - * - *

Returns {@link PushReceiverId PushReceiverId}

- */ - public static class GetPushReceiverId extends Function { - /** - * JSON-encoded push notification payload. - */ - public String payload; - - /** - * Default constructor for a function, which returns a globally unique push notification subscription identifier for identification of an account, which has received a push notification. Can be called synchronously. - * - *

Returns {@link PushReceiverId PushReceiverId}

- */ - public GetPushReceiverId() { - } - - /** - * Creates a function, which returns a globally unique push notification subscription identifier for identification of an account, which has received a push notification. Can be called synchronously. - * - *

Returns {@link PushReceiverId PushReceiverId}

- * - * @param payload JSON-encoded push notification payload. - */ - public GetPushReceiverId(String payload) { - this.payload = payload; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -286505294; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns privacy settings for message read date. - * - *

Returns {@link ReadDatePrivacySettings ReadDatePrivacySettings}

- */ - public static class GetReadDatePrivacySettings extends Function { - - /** - * Default constructor for a function, which returns privacy settings for message read date. - * - *

Returns {@link ReadDatePrivacySettings ReadDatePrivacySettings}

- */ - public GetReadDatePrivacySettings() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 451435451; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a received gift. - * - *

Returns {@link ReceivedGift ReceivedGift}

- */ - public static class GetReceivedGift extends Function { - /** - * Identifier of the gift. - */ - public String receivedGiftId; - - /** - * Default constructor for a function, which returns information about a received gift. - * - *

Returns {@link ReceivedGift ReceivedGift}

- */ - public GetReceivedGift() { - } - - /** - * Creates a function, which returns information about a received gift. - * - *

Returns {@link ReceivedGift ReceivedGift}

- * - * @param receivedGiftId Identifier of the gift. - */ - public GetReceivedGift(String receivedGiftId) { - this.receivedGiftId = receivedGiftId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -446535239; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns gifts received by the given user or chat. - * - *

Returns {@link ReceivedGifts ReceivedGifts}

- */ - public static class GetReceivedGifts extends Function { - /** - * Unique identifier of business connection on behalf of which to send the request; for bots only. - */ - public String businessConnectionId; - /** - * Identifier of the gift receiver. - */ - public MessageSender ownerId; - /** - * Pass collection identifier to get gifts only from the specified collection; pass 0 to get gifts regardless of collections. - */ - public int collectionId; - /** - * Pass true to exclude gifts that aren't saved to the chat's profile page. Always true for gifts received by other users and channel chats without canPostMessages administrator right. - */ - public boolean excludeUnsaved; - /** - * Pass true to exclude gifts that are saved to the chat's profile page. Always false for gifts received by other users and channel chats without canPostMessages administrator right. - */ - public boolean excludeSaved; - /** - * Pass true to exclude gifts that can be purchased unlimited number of times. - */ - public boolean excludeUnlimited; - /** - * Pass true to exclude gifts that can be purchased limited number of times and can be upgraded. - */ - public boolean excludeUpgradable; - /** - * Pass true to exclude gifts that can be purchased limited number of times and can't be upgraded. - */ - public boolean excludeNonUpgradable; - /** - * Pass true to exclude upgraded gifts. - */ - public boolean excludeUpgraded; - /** - * Pass true to exclude gifts that can't be used in setUpgradedGiftColors. - */ - public boolean excludeWithoutColors; - /** - * Pass true to exclude gifts that are just hosted and are not owned by the owner. - */ - public boolean excludeHosted; - /** - * Pass true to sort results by gift price instead of send date. - */ - public boolean sortByPrice; - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of gifts to be returned; must be positive and can't be greater than 100. For optimal performance, the number of returned objects is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which returns gifts received by the given user or chat. - * - *

Returns {@link ReceivedGifts ReceivedGifts}

- */ - public GetReceivedGifts() { - } - - /** - * Creates a function, which returns gifts received by the given user or chat. - * - *

Returns {@link ReceivedGifts ReceivedGifts}

- * - * @param businessConnectionId Unique identifier of business connection on behalf of which to send the request; for bots only. - * @param ownerId Identifier of the gift receiver. - * @param collectionId Pass collection identifier to get gifts only from the specified collection; pass 0 to get gifts regardless of collections. - * @param excludeUnsaved Pass true to exclude gifts that aren't saved to the chat's profile page. Always true for gifts received by other users and channel chats without canPostMessages administrator right. - * @param excludeSaved Pass true to exclude gifts that are saved to the chat's profile page. Always false for gifts received by other users and channel chats without canPostMessages administrator right. - * @param excludeUnlimited Pass true to exclude gifts that can be purchased unlimited number of times. - * @param excludeUpgradable Pass true to exclude gifts that can be purchased limited number of times and can be upgraded. - * @param excludeNonUpgradable Pass true to exclude gifts that can be purchased limited number of times and can't be upgraded. - * @param excludeUpgraded Pass true to exclude upgraded gifts. - * @param excludeWithoutColors Pass true to exclude gifts that can't be used in setUpgradedGiftColors. - * @param excludeHosted Pass true to exclude gifts that are just hosted and are not owned by the owner. - * @param sortByPrice Pass true to sort results by gift price instead of send date. - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of gifts to be returned; must be positive and can't be greater than 100. For optimal performance, the number of returned objects is chosen by TDLib and can be smaller than the specified limit. - */ - public GetReceivedGifts(String businessConnectionId, MessageSender ownerId, int collectionId, boolean excludeUnsaved, boolean excludeSaved, boolean excludeUnlimited, boolean excludeUpgradable, boolean excludeNonUpgradable, boolean excludeUpgraded, boolean excludeWithoutColors, boolean excludeHosted, boolean sortByPrice, String offset, int limit) { - this.businessConnectionId = businessConnectionId; - this.ownerId = ownerId; - this.collectionId = collectionId; - this.excludeUnsaved = excludeUnsaved; - this.excludeSaved = excludeSaved; - this.excludeUnlimited = excludeUnlimited; - this.excludeUpgradable = excludeUpgradable; - this.excludeNonUpgradable = excludeNonUpgradable; - this.excludeUpgraded = excludeUpgraded; - this.excludeWithoutColors = excludeWithoutColors; - this.excludeHosted = excludeHosted; - this.sortByPrice = sortByPrice; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1411782110; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns recent emoji statuses for self status. - * - *

Returns {@link EmojiStatuses EmojiStatuses}

- */ - public static class GetRecentEmojiStatuses extends Function { - - /** - * Default constructor for a function, which returns recent emoji statuses for self status. - * - *

Returns {@link EmojiStatuses EmojiStatuses}

- */ - public GetRecentEmojiStatuses() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1371914967; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns up to 20 recently used inline bots in the order of their last usage. - * - *

Returns {@link Users Users}

- */ - public static class GetRecentInlineBots extends Function { - - /** - * Default constructor for a function, which returns up to 20 recently used inline bots in the order of their last usage. - * - *

Returns {@link Users Users}

- */ - public GetRecentInlineBots() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1437823548; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a list of recently used stickers. - * - *

Returns {@link Stickers Stickers}

- */ - public static class GetRecentStickers extends Function { - /** - * Pass true to return stickers and masks that were recently attached to photos or video files; pass false to return recently sent stickers. - */ - public boolean isAttached; - - /** - * Default constructor for a function, which returns a list of recently used stickers. - * - *

Returns {@link Stickers Stickers}

- */ - public GetRecentStickers() { - } - - /** - * Creates a function, which returns a list of recently used stickers. - * - *

Returns {@link Stickers Stickers}

- * - * @param isAttached Pass true to return stickers and masks that were recently attached to photos or video files; pass false to return recently sent stickers. - */ - public GetRecentStickers(boolean isAttached) { - this.isAttached = isAttached; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -579622241; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns recently opened chats. This is an offline method. Returns chats in the order of last opening. - * - *

Returns {@link Chats Chats}

- */ - public static class GetRecentlyOpenedChats extends Function { - /** - * The maximum number of chats to be returned. - */ - public int limit; - - /** - * Default constructor for a function, which returns recently opened chats. This is an offline method. Returns chats in the order of last opening. - * - *

Returns {@link Chats Chats}

- */ - public GetRecentlyOpenedChats() { - } - - /** - * Creates a function, which returns recently opened chats. This is an offline method. Returns chats in the order of last opening. - * - *

Returns {@link Chats Chats}

- * - * @param limit The maximum number of chats to be returned. - */ - public GetRecentlyOpenedChats(int limit) { - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1924156893; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns t.me URLs recently visited by a newly registered user. - * - *

Returns {@link TMeUrls TMeUrls}

- */ - public static class GetRecentlyVisitedTMeUrls extends Function { - /** - * Google Play referrer to identify the user. - */ - public String referrer; - - /** - * Default constructor for a function, which returns t.me URLs recently visited by a newly registered user. - * - *

Returns {@link TMeUrls TMeUrls}

- */ - public GetRecentlyVisitedTMeUrls() { - } - - /** - * Creates a function, which returns t.me URLs recently visited by a newly registered user. - * - *

Returns {@link TMeUrls TMeUrls}

- * - * @param referrer Google Play referrer to identify the user. - */ - public GetRecentlyVisitedTMeUrls(String referrer) { - this.referrer = referrer; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 806754961; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns recommended chat folders for the current user. - * - *

Returns {@link RecommendedChatFolders RecommendedChatFolders}

- */ - public static class GetRecommendedChatFolders extends Function { - - /** - * Default constructor for a function, which returns recommended chat folders for the current user. - * - *

Returns {@link RecommendedChatFolders RecommendedChatFolders}

- */ - public GetRecommendedChatFolders() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -145540217; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a list of channel chats recommended to the current user. - * - *

Returns {@link Chats Chats}

- */ - public static class GetRecommendedChats extends Function { - - /** - * Default constructor for a function, which returns a list of channel chats recommended to the current user. - * - *

Returns {@link Chats Chats}

- */ - public GetRecommendedChats() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -649884303; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a 2-step verification recovery email address that was previously set up. This method can be used to verify a password provided by the user. - * - *

Returns {@link RecoveryEmailAddress RecoveryEmailAddress}

- */ - public static class GetRecoveryEmailAddress extends Function { - /** - * The 2-step verification password for the current user. - */ - public String password; - - /** - * Default constructor for a function, which returns a 2-step verification recovery email address that was previously set up. This method can be used to verify a password provided by the user. - * - *

Returns {@link RecoveryEmailAddress RecoveryEmailAddress}

- */ - public GetRecoveryEmailAddress() { - } - - /** - * Creates a function, which returns a 2-step verification recovery email address that was previously set up. This method can be used to verify a password provided by the user. - * - *

Returns {@link RecoveryEmailAddress RecoveryEmailAddress}

- * - * @param password The 2-step verification password for the current user. - */ - public GetRecoveryEmailAddress(String password) { - this.password = password; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1594770947; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a file by its remote identifier. This is an offline method. Can be used to register a URL as a file for further uploading, or sending as a message. Even the request succeeds, the file can be used only if it is still accessible to the user. For example, if the file is from a message, then the message must be not deleted and accessible to the user. If the file database is disabled, then the corresponding object with the file must be preloaded by the application. - * - *

Returns {@link File File}

- */ - public static class GetRemoteFile extends Function { - /** - * Remote identifier of the file to get. - */ - public String remoteFileId; - /** - * File type; pass null if unknown. - */ - public FileType fileType; - - /** - * Default constructor for a function, which returns information about a file by its remote identifier. This is an offline method. Can be used to register a URL as a file for further uploading, or sending as a message. Even the request succeeds, the file can be used only if it is still accessible to the user. For example, if the file is from a message, then the message must be not deleted and accessible to the user. If the file database is disabled, then the corresponding object with the file must be preloaded by the application. - * - *

Returns {@link File File}

- */ - public GetRemoteFile() { - } - - /** - * Creates a function, which returns information about a file by its remote identifier. This is an offline method. Can be used to register a URL as a file for further uploading, or sending as a message. Even the request succeeds, the file can be used only if it is still accessible to the user. For example, if the file is from a message, then the message must be not deleted and accessible to the user. If the file database is disabled, then the corresponding object with the file must be preloaded by the application. - * - *

Returns {@link File File}

- * - * @param remoteFileId Remote identifier of the file to get. - * @param fileType File type; pass null if unknown. - */ - public GetRemoteFile(String remoteFileId, FileType fileType) { - this.remoteFileId = remoteFileId; - this.fileType = fileType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2137204530; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a non-bundled message that is replied by a given message. Also, returns the pinned message for messagePinMessage, the game message for messageGameScore, the invoice message for messagePaymentSuccessful, the message with a previously set same background for messageChatSetBackground, the giveaway message for messageGiveawayCompleted, the checklist message for messageChecklistTasksDone, messageChecklistTasksAdded, the message with suggested post information for messageSuggestedPostApprovalFailed, messageSuggestedPostApproved, messageSuggestedPostDeclined, messageSuggestedPostPaid, messageSuggestedPostRefunded, the message with the regular gift that was upgraded for messageUpgradedGift with origin of the type upgradedGiftOriginUpgrade, the message with gift purchase offer for messageUpgradedGiftPurchaseOfferRejected, the message with the request to disable content protection for messageChatHasProtectedContentToggled, and the topic creation message for topic messages without non-bundled replied message. Returns a 404 error if the message doesn't exist. - * - *

Returns {@link Message Message}

- */ - public static class GetRepliedMessage extends Function { - /** - * Identifier of the chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the reply message. - */ - public long messageId; - - /** - * Default constructor for a function, which returns information about a non-bundled message that is replied by a given message. Also, returns the pinned message for messagePinMessage, the game message for messageGameScore, the invoice message for messagePaymentSuccessful, the message with a previously set same background for messageChatSetBackground, the giveaway message for messageGiveawayCompleted, the checklist message for messageChecklistTasksDone, messageChecklistTasksAdded, the message with suggested post information for messageSuggestedPostApprovalFailed, messageSuggestedPostApproved, messageSuggestedPostDeclined, messageSuggestedPostPaid, messageSuggestedPostRefunded, the message with the regular gift that was upgraded for messageUpgradedGift with origin of the type upgradedGiftOriginUpgrade, the message with gift purchase offer for messageUpgradedGiftPurchaseOfferRejected, the message with the request to disable content protection for messageChatHasProtectedContentToggled, and the topic creation message for topic messages without non-bundled replied message. Returns a 404 error if the message doesn't exist. - * - *

Returns {@link Message Message}

- */ - public GetRepliedMessage() { - } - - /** - * Creates a function, which returns information about a non-bundled message that is replied by a given message. Also, returns the pinned message for messagePinMessage, the game message for messageGameScore, the invoice message for messagePaymentSuccessful, the message with a previously set same background for messageChatSetBackground, the giveaway message for messageGiveawayCompleted, the checklist message for messageChecklistTasksDone, messageChecklistTasksAdded, the message with suggested post information for messageSuggestedPostApprovalFailed, messageSuggestedPostApproved, messageSuggestedPostDeclined, messageSuggestedPostPaid, messageSuggestedPostRefunded, the message with the regular gift that was upgraded for messageUpgradedGift with origin of the type upgradedGiftOriginUpgrade, the message with gift purchase offer for messageUpgradedGiftPurchaseOfferRejected, the message with the request to disable content protection for messageChatHasProtectedContentToggled, and the topic creation message for topic messages without non-bundled replied message. Returns a 404 error if the message doesn't exist. - * - *

Returns {@link Message Message}

- * - * @param chatId Identifier of the chat the message belongs to. - * @param messageId Identifier of the reply message. - */ - public GetRepliedMessage(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -641918531; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns saved animations. - * - *

Returns {@link Animations Animations}

- */ - public static class GetSavedAnimations extends Function { - - /** - * Default constructor for a function, which returns saved animations. - * - *

Returns {@link Animations Animations}

- */ - public GetSavedAnimations() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 7051032; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns tags used in Saved Messages or a Saved Messages topic. - * - *

Returns {@link SavedMessagesTags SavedMessagesTags}

- */ - public static class GetSavedMessagesTags extends Function { - /** - * Identifier of Saved Messages topic which tags will be returned; pass 0 to get all Saved Messages tags. - */ - public long savedMessagesTopicId; - - /** - * Default constructor for a function, which returns tags used in Saved Messages or a Saved Messages topic. - * - *

Returns {@link SavedMessagesTags SavedMessagesTags}

- */ - public GetSavedMessagesTags() { - } - - /** - * Creates a function, which returns tags used in Saved Messages or a Saved Messages topic. - * - *

Returns {@link SavedMessagesTags SavedMessagesTags}

- * - * @param savedMessagesTopicId Identifier of Saved Messages topic which tags will be returned; pass 0 to get all Saved Messages tags. - */ - public GetSavedMessagesTags(long savedMessagesTopicId) { - this.savedMessagesTopicId = savedMessagesTopicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1932105815; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns messages in a Saved Messages topic. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). - * - *

Returns {@link Messages Messages}

- */ - public static class GetSavedMessagesTopicHistory extends Function { - /** - * Identifier of Saved Messages topic which messages will be fetched. - */ - public long savedMessagesTopicId; - /** - * Identifier of the message starting from which messages must be fetched; use 0 to get results from the last message. - */ - public long fromMessageId; - /** - * Specify 0 to get results from exactly the message fromMessageId or a negative number from -99 to -1 to get additionally -offset newer messages. - */ - public int offset; - /** - * The maximum number of messages to be returned; must be positive and can't be greater than 100. If the offset is negative, then the limit must be greater than or equal to -offset. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which returns messages in a Saved Messages topic. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). - * - *

Returns {@link Messages Messages}

- */ - public GetSavedMessagesTopicHistory() { - } - - /** - * Creates a function, which returns messages in a Saved Messages topic. The messages are returned in reverse chronological order (i.e., in order of decreasing messageId). - * - *

Returns {@link Messages Messages}

- * - * @param savedMessagesTopicId Identifier of Saved Messages topic which messages will be fetched. - * @param fromMessageId Identifier of the message starting from which messages must be fetched; use 0 to get results from the last message. - * @param offset Specify 0 to get results from exactly the message fromMessageId or a negative number from -99 to -1 to get additionally -offset newer messages. - * @param limit The maximum number of messages to be returned; must be positive and can't be greater than 100. If the offset is negative, then the limit must be greater than or equal to -offset. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public GetSavedMessagesTopicHistory(long savedMessagesTopicId, long fromMessageId, int offset, int limit) { - this.savedMessagesTopicId = savedMessagesTopicId; - this.fromMessageId = fromMessageId; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2011552360; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the last message sent in a Saved Messages topic no later than the specified date. - * - *

Returns {@link Message Message}

- */ - public static class GetSavedMessagesTopicMessageByDate extends Function { - /** - * Identifier of Saved Messages topic which message will be returned. - */ - public long savedMessagesTopicId; - /** - * Point in time (Unix timestamp) relative to which to search for messages. - */ - public int date; - - /** - * Default constructor for a function, which returns the last message sent in a Saved Messages topic no later than the specified date. - * - *

Returns {@link Message Message}

- */ - public GetSavedMessagesTopicMessageByDate() { - } - - /** - * Creates a function, which returns the last message sent in a Saved Messages topic no later than the specified date. - * - *

Returns {@link Message Message}

- * - * @param savedMessagesTopicId Identifier of Saved Messages topic which message will be returned. - * @param date Point in time (Unix timestamp) relative to which to search for messages. - */ - public GetSavedMessagesTopicMessageByDate(long savedMessagesTopicId, int date) { - this.savedMessagesTopicId = savedMessagesTopicId; - this.date = date; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1050786176; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns saved notification sound by its identifier. Returns a 404 error if there is no saved notification sound with the specified identifier. - * - *

Returns {@link NotificationSounds NotificationSounds}

- */ - public static class GetSavedNotificationSound extends Function { - /** - * Identifier of the notification sound. - */ - public long notificationSoundId; - - /** - * Default constructor for a function, which returns saved notification sound by its identifier. Returns a 404 error if there is no saved notification sound with the specified identifier. - * - *

Returns {@link NotificationSounds NotificationSounds}

- */ - public GetSavedNotificationSound() { - } - - /** - * Creates a function, which returns saved notification sound by its identifier. Returns a 404 error if there is no saved notification sound with the specified identifier. - * - *

Returns {@link NotificationSounds NotificationSounds}

- * - * @param notificationSoundId Identifier of the notification sound. - */ - public GetSavedNotificationSound(long notificationSoundId) { - this.notificationSoundId = notificationSoundId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 459569431; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of saved notification sounds. If a sound isn't in the list, then default sound needs to be used. - * - *

Returns {@link NotificationSounds NotificationSounds}

- */ - public static class GetSavedNotificationSounds extends Function { - - /** - * Default constructor for a function, which returns the list of saved notification sounds. If a sound isn't in the list, then default sound needs to be used. - * - *

Returns {@link NotificationSounds NotificationSounds}

- */ - public GetSavedNotificationSounds() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1070305368; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns saved order information. Returns a 404 error if there is no saved order information. - * - *

Returns {@link OrderInfo OrderInfo}

- */ - public static class GetSavedOrderInfo extends Function { - - /** - * Default constructor for a function, which returns saved order information. Returns a 404 error if there is no saved order information. - * - *

Returns {@link OrderInfo OrderInfo}

- */ - public GetSavedOrderInfo() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1152016675; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the notification settings for chats of a given type. - * - *

Returns {@link ScopeNotificationSettings ScopeNotificationSettings}

- */ - public static class GetScopeNotificationSettings extends Function { - /** - * Types of chats for which to return the notification settings information. - */ - public NotificationSettingsScope scope; - - /** - * Default constructor for a function, which returns the notification settings for chats of a given type. - * - *

Returns {@link ScopeNotificationSettings ScopeNotificationSettings}

- */ - public GetScopeNotificationSettings() { - } - - /** - * Creates a function, which returns the notification settings for chats of a given type. - * - *

Returns {@link ScopeNotificationSettings ScopeNotificationSettings}

- * - * @param scope Types of chats for which to return the notification settings information. - */ - public GetScopeNotificationSettings(NotificationSettingsScope scope) { - this.scope = scope; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -995613361; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns sponsored chats to be shown in the search results. - * - *

Returns {@link SponsoredChats SponsoredChats}

- */ - public static class GetSearchSponsoredChats extends Function { - /** - * Query the user searches for. - */ - public String query; - - /** - * Default constructor for a function, which returns sponsored chats to be shown in the search results. - * - *

Returns {@link SponsoredChats SponsoredChats}

- */ - public GetSearchSponsoredChats() { - } - - /** - * Creates a function, which returns sponsored chats to be shown in the search results. - * - *

Returns {@link SponsoredChats SponsoredChats}

- * - * @param query Query the user searches for. - */ - public GetSearchSponsoredChats(String query) { - this.query = query; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1568505164; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns recently searched for hashtags or cashtags by their prefix. - * - *

Returns {@link Hashtags Hashtags}

- */ - public static class GetSearchedForTags extends Function { - /** - * Prefix of hashtags or cashtags to return. - */ - public String tagPrefix; - /** - * The maximum number of items to be returned. - */ - public int limit; - - /** - * Default constructor for a function, which returns recently searched for hashtags or cashtags by their prefix. - * - *

Returns {@link Hashtags Hashtags}

- */ - public GetSearchedForTags() { - } - - /** - * Creates a function, which returns recently searched for hashtags or cashtags by their prefix. - * - *

Returns {@link Hashtags Hashtags}

- * - * @param tagPrefix Prefix of hashtags or cashtags to return. - * @param limit The maximum number of items to be returned. - */ - public GetSearchedForTags(String tagPrefix, int limit) { - this.tagPrefix = tagPrefix; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1692716851; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a secret chat by its identifier. This is an offline method. - * - *

Returns {@link SecretChat SecretChat}

- */ - public static class GetSecretChat extends Function { - /** - * Secret chat identifier. - */ - public int secretChatId; - - /** - * Default constructor for a function, which returns information about a secret chat by its identifier. This is an offline method. - * - *

Returns {@link SecretChat SecretChat}

- */ - public GetSecretChat() { - } - - /** - * Creates a function, which returns information about a secret chat by its identifier. This is an offline method. - * - *

Returns {@link SecretChat SecretChat}

- * - * @param secretChatId Secret chat identifier. - */ - public GetSecretChat(int secretChatId) { - this.secretChatId = secretChatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 40599169; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the current state of stake dice. - * - *

Returns {@link StakeDiceState StakeDiceState}

- */ - public static class GetStakeDiceState extends Function { - - /** - * Default constructor for a function, which returns the current state of stake dice. - * - *

Returns {@link StakeDiceState StakeDiceState}

- */ - public GetStakeDiceState() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1389168065; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a URL for a Telegram Ad platform account that can be used to set up advertisements for the chat paid in the owned Telegram Stars. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public static class GetStarAdAccountUrl extends Function { - /** - * Identifier of the owner of the Telegram Stars; can be identifier of an owned bot, or identifier of an owned channel chat. - */ - public MessageSender ownerId; - - /** - * Default constructor for a function, which returns a URL for a Telegram Ad platform account that can be used to set up advertisements for the chat paid in the owned Telegram Stars. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public GetStarAdAccountUrl() { - } - - /** - * Creates a function, which returns a URL for a Telegram Ad platform account that can be used to set up advertisements for the chat paid in the owned Telegram Stars. - * - *

Returns {@link HttpUrl HttpUrl}

- * - * @param ownerId Identifier of the owner of the Telegram Stars; can be identifier of an owned bot, or identifier of an owned channel chat. - */ - public GetStarAdAccountUrl(MessageSender ownerId) { - this.ownerId = ownerId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1940473181; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns available options for Telegram Stars gifting. - * - *

Returns {@link StarPaymentOptions StarPaymentOptions}

- */ - public static class GetStarGiftPaymentOptions extends Function { - /** - * Identifier of the user who will receive Telegram Stars; pass 0 to get options for an unspecified user. - */ - public long userId; - - /** - * Default constructor for a function, which returns available options for Telegram Stars gifting. - * - *

Returns {@link StarPaymentOptions StarPaymentOptions}

- */ - public GetStarGiftPaymentOptions() { - } - - /** - * Creates a function, which returns available options for Telegram Stars gifting. - * - *

Returns {@link StarPaymentOptions StarPaymentOptions}

- * - * @param userId Identifier of the user who will receive Telegram Stars; pass 0 to get options for an unspecified user. - */ - public GetStarGiftPaymentOptions(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -500735773; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns available options for Telegram Star giveaway creation. - * - *

Returns {@link StarGiveawayPaymentOptions StarGiveawayPaymentOptions}

- */ - public static class GetStarGiveawayPaymentOptions extends Function { - - /** - * Default constructor for a function, which returns available options for Telegram Star giveaway creation. - * - *

Returns {@link StarGiveawayPaymentOptions StarGiveawayPaymentOptions}

- */ - public GetStarGiveawayPaymentOptions() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -883172578; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns available options for Telegram Stars purchase. - * - *

Returns {@link StarPaymentOptions StarPaymentOptions}

- */ - public static class GetStarPaymentOptions extends Function { - - /** - * Default constructor for a function, which returns available options for Telegram Stars purchase. - * - *

Returns {@link StarPaymentOptions StarPaymentOptions}

- */ - public GetStarPaymentOptions() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1838351940; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns detailed Telegram Star revenue statistics. - * - *

Returns {@link StarRevenueStatistics StarRevenueStatistics}

- */ - public static class GetStarRevenueStatistics extends Function { - /** - * Identifier of the owner of the Telegram Stars; can be identifier of the current user, an owned bot, or a supergroup or a channel chat with supergroupFullInfo.canGetStarRevenueStatistics == true. - */ - public MessageSender ownerId; - /** - * Pass true if a dark theme is used by the application. - */ - public boolean isDark; - - /** - * Default constructor for a function, which returns detailed Telegram Star revenue statistics. - * - *

Returns {@link StarRevenueStatistics StarRevenueStatistics}

- */ - public GetStarRevenueStatistics() { - } - - /** - * Creates a function, which returns detailed Telegram Star revenue statistics. - * - *

Returns {@link StarRevenueStatistics StarRevenueStatistics}

- * - * @param ownerId Identifier of the owner of the Telegram Stars; can be identifier of the current user, an owned bot, or a supergroup or a channel chat with supergroupFullInfo.canGetStarRevenueStatistics == true. - * @param isDark Pass true if a dark theme is used by the application. - */ - public GetStarRevenueStatistics(MessageSender ownerId, boolean isDark) { - this.ownerId = ownerId; - this.isDark = isDark; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -260356841; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of Telegram Star subscriptions for the current user. - * - *

Returns {@link StarSubscriptions StarSubscriptions}

- */ - public static class GetStarSubscriptions extends Function { - /** - * Pass true to receive only expiring subscriptions for which there are no enough Telegram Stars to extend. - */ - public boolean onlyExpiring; - /** - * Offset of the first subscription to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - - /** - * Default constructor for a function, which returns the list of Telegram Star subscriptions for the current user. - * - *

Returns {@link StarSubscriptions StarSubscriptions}

- */ - public GetStarSubscriptions() { - } - - /** - * Creates a function, which returns the list of Telegram Star subscriptions for the current user. - * - *

Returns {@link StarSubscriptions StarSubscriptions}

- * - * @param onlyExpiring Pass true to receive only expiring subscriptions for which there are no enough Telegram Stars to extend. - * @param offset Offset of the first subscription to return as received from the previous request; use empty string to get the first chunk of results. - */ - public GetStarSubscriptions(boolean onlyExpiring, String offset) { - this.onlyExpiring = onlyExpiring; - this.offset = offset; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -641223956; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of Telegram Star transactions for the specified owner. - * - *

Returns {@link StarTransactions StarTransactions}

- */ - public static class GetStarTransactions extends Function { - /** - * Identifier of the owner of the Telegram Stars; can be the identifier of the current user, identifier of an owned bot, or identifier of a supergroup or a channel chat with supergroupFullInfo.canGetStarRevenueStatistics == true. - */ - public MessageSender ownerId; - /** - * If non-empty, only transactions related to the Star Subscription will be returned. - */ - public String subscriptionId; - /** - * Direction of the transactions to receive; pass null to get all transactions. - */ - public TransactionDirection direction; - /** - * Offset of the first transaction to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of transactions to return. - */ - public int limit; - - /** - * Default constructor for a function, which returns the list of Telegram Star transactions for the specified owner. - * - *

Returns {@link StarTransactions StarTransactions}

- */ - public GetStarTransactions() { - } - - /** - * Creates a function, which returns the list of Telegram Star transactions for the specified owner. - * - *

Returns {@link StarTransactions StarTransactions}

- * - * @param ownerId Identifier of the owner of the Telegram Stars; can be the identifier of the current user, identifier of an owned bot, or identifier of a supergroup or a channel chat with supergroupFullInfo.canGetStarRevenueStatistics == true. - * @param subscriptionId If non-empty, only transactions related to the Star Subscription will be returned. - * @param direction Direction of the transactions to receive; pass null to get all transactions. - * @param offset Offset of the first transaction to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of transactions to return. - */ - public GetStarTransactions(MessageSender ownerId, String subscriptionId, TransactionDirection direction, String offset, int limit) { - this.ownerId = ownerId; - this.subscriptionId = subscriptionId; - this.direction = direction; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -304141747; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a URL for Telegram Star withdrawal. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public static class GetStarWithdrawalUrl extends Function { - /** - * Identifier of the owner of the Telegram Stars; can be identifier of the current user, an owned bot, or an owned supergroup or channel chat. - */ - public MessageSender ownerId; - /** - * The number of Telegram Stars to withdraw; must be between getOption("star_withdrawal_count_min") and getOption("star_withdrawal_count_max"). - */ - public long starCount; - /** - * The 2-step verification password of the current user. - */ - public String password; - - /** - * Default constructor for a function, which returns a URL for Telegram Star withdrawal. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public GetStarWithdrawalUrl() { - } - - /** - * Creates a function, which returns a URL for Telegram Star withdrawal. - * - *

Returns {@link HttpUrl HttpUrl}

- * - * @param ownerId Identifier of the owner of the Telegram Stars; can be identifier of the current user, an owned bot, or an owned supergroup or channel chat. - * @param starCount The number of Telegram Stars to withdraw; must be between getOption("star_withdrawal_count_min") and getOption("star_withdrawal_count_max"). - * @param password The 2-step verification password of the current user. - */ - public GetStarWithdrawalUrl(MessageSender ownerId, long starCount, String password) { - this.ownerId = ownerId; - this.starCount = starCount; - this.password = password; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1445841134; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Loads an asynchronous or a zoomed in statistical graph. - * - *

Returns {@link StatisticalGraph StatisticalGraph}

- */ - public static class GetStatisticalGraph extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * The token for graph loading. - */ - public String token; - /** - * X-value for zoomed in graph or 0 otherwise. - */ - public long x; - - /** - * Default constructor for a function, which loads an asynchronous or a zoomed in statistical graph. - * - *

Returns {@link StatisticalGraph StatisticalGraph}

- */ - public GetStatisticalGraph() { - } - - /** - * Creates a function, which loads an asynchronous or a zoomed in statistical graph. - * - *

Returns {@link StatisticalGraph StatisticalGraph}

- * - * @param chatId Chat identifier. - * @param token The token for graph loading. - * @param x X-value for zoomed in graph or 0 otherwise. - */ - public GetStatisticalGraph(long chatId, String token, long x) { - this.chatId = chatId; - this.token = token; - this.x = x; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1100975515; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns emoji corresponding to a sticker. The list is only for informational purposes, because a sticker is always sent with a fixed emoji from the corresponding Sticker object. - * - *

Returns {@link Emojis Emojis}

- */ - public static class GetStickerEmojis extends Function { - /** - * Sticker file identifier. - */ - public InputFile sticker; - - /** - * Default constructor for a function, which returns emoji corresponding to a sticker. The list is only for informational purposes, because a sticker is always sent with a fixed emoji from the corresponding Sticker object. - * - *

Returns {@link Emojis Emojis}

- */ - public GetStickerEmojis() { - } - - /** - * Creates a function, which returns emoji corresponding to a sticker. The list is only for informational purposes, because a sticker is always sent with a fixed emoji from the corresponding Sticker object. - * - *

Returns {@link Emojis Emojis}

- * - * @param sticker Sticker file identifier. - */ - public GetStickerEmojis(InputFile sticker) { - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1895508665; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns outline of a sticker. This is an offline method. Returns a 404 error if the outline isn't known. - * - *

Returns {@link Outline Outline}

- */ - public static class GetStickerOutline extends Function { - /** - * File identifier of the sticker. - */ - public int stickerFileId; - /** - * Pass true to get the outline scaled for animated emoji. - */ - public boolean forAnimatedEmoji; - /** - * Pass true to get the outline scaled for clicked animated emoji message. - */ - public boolean forClickedAnimatedEmojiMessage; - - /** - * Default constructor for a function, which returns outline of a sticker. This is an offline method. Returns a 404 error if the outline isn't known. - * - *

Returns {@link Outline Outline}

- */ - public GetStickerOutline() { - } - - /** - * Creates a function, which returns outline of a sticker. This is an offline method. Returns a 404 error if the outline isn't known. - * - *

Returns {@link Outline Outline}

- * - * @param stickerFileId File identifier of the sticker. - * @param forAnimatedEmoji Pass true to get the outline scaled for animated emoji. - * @param forClickedAnimatedEmojiMessage Pass true to get the outline scaled for clicked animated emoji message. - */ - public GetStickerOutline(int stickerFileId, boolean forAnimatedEmoji, boolean forClickedAnimatedEmojiMessage) { - this.stickerFileId = stickerFileId; - this.forAnimatedEmoji = forAnimatedEmoji; - this.forClickedAnimatedEmojiMessage = forClickedAnimatedEmojiMessage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1550504539; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns outline of a sticker as an SVG path. This is an offline method. Returns an empty string if the outline isn't known. - * - *

Returns {@link Text Text}

- */ - public static class GetStickerOutlineSvgPath extends Function { - /** - * File identifier of the sticker. - */ - public int stickerFileId; - /** - * Pass true to get the outline scaled for animated emoji. - */ - public boolean forAnimatedEmoji; - /** - * Pass true to get the outline scaled for clicked animated emoji message. - */ - public boolean forClickedAnimatedEmojiMessage; - - /** - * Default constructor for a function, which returns outline of a sticker as an SVG path. This is an offline method. Returns an empty string if the outline isn't known. - * - *

Returns {@link Text Text}

- */ - public GetStickerOutlineSvgPath() { - } - - /** - * Creates a function, which returns outline of a sticker as an SVG path. This is an offline method. Returns an empty string if the outline isn't known. - * - *

Returns {@link Text Text}

- * - * @param stickerFileId File identifier of the sticker. - * @param forAnimatedEmoji Pass true to get the outline scaled for animated emoji. - * @param forClickedAnimatedEmojiMessage Pass true to get the outline scaled for clicked animated emoji message. - */ - public GetStickerOutlineSvgPath(int stickerFileId, boolean forAnimatedEmoji, boolean forClickedAnimatedEmojiMessage) { - this.stickerFileId = stickerFileId; - this.forAnimatedEmoji = forAnimatedEmoji; - this.forClickedAnimatedEmojiMessage = forClickedAnimatedEmojiMessage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1615497803; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a sticker set by its identifier. - * - *

Returns {@link StickerSet StickerSet}

- */ - public static class GetStickerSet extends Function { - /** - * Identifier of the sticker set. - */ - public long setId; - - /** - * Default constructor for a function, which returns information about a sticker set by its identifier. - * - *

Returns {@link StickerSet StickerSet}

- */ - public GetStickerSet() { - } - - /** - * Creates a function, which returns information about a sticker set by its identifier. - * - *

Returns {@link StickerSet StickerSet}

- * - * @param setId Identifier of the sticker set. - */ - public GetStickerSet(long setId) { - this.setId = setId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1052318659; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns name of a sticker set by its identifier. - * - *

Returns {@link Text Text}

- */ - public static class GetStickerSetName extends Function { - /** - * Identifier of the sticker set. - */ - public long setId; - - /** - * Default constructor for a function, which returns name of a sticker set by its identifier. - * - *

Returns {@link Text Text}

- */ - public GetStickerSetName() { - } - - /** - * Creates a function, which returns name of a sticker set by its identifier. - * - *

Returns {@link Text Text}

- * - * @param setId Identifier of the sticker set. - */ - public GetStickerSetName(long setId) { - this.setId = setId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1039849089; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns stickers from the installed sticker sets that correspond to any of the given emoji or can be found by sticker-specific keywords. If the query is non-empty, then favorite, recently used or trending stickers may also be returned. - * - *

Returns {@link Stickers Stickers}

- */ - public static class GetStickers extends Function { - /** - * Type of the stickers to return. - */ - public StickerType stickerType; - /** - * Search query; a space-separated list of emojis or a keyword prefix. If empty, returns all known installed stickers. - */ - public String query; - /** - * The maximum number of stickers to be returned. - */ - public int limit; - /** - * Chat identifier for which to return stickers. Available custom emoji stickers may be different for different chats. - */ - public long chatId; - - /** - * Default constructor for a function, which returns stickers from the installed sticker sets that correspond to any of the given emoji or can be found by sticker-specific keywords. If the query is non-empty, then favorite, recently used or trending stickers may also be returned. - * - *

Returns {@link Stickers Stickers}

- */ - public GetStickers() { - } - - /** - * Creates a function, which returns stickers from the installed sticker sets that correspond to any of the given emoji or can be found by sticker-specific keywords. If the query is non-empty, then favorite, recently used or trending stickers may also be returned. - * - *

Returns {@link Stickers Stickers}

- * - * @param stickerType Type of the stickers to return. - * @param query Search query; a space-separated list of emojis or a keyword prefix. If empty, returns all known installed stickers. - * @param limit The maximum number of stickers to be returned. - * @param chatId Chat identifier for which to return stickers. Available custom emoji stickers may be different for different chats. - */ - public GetStickers(StickerType stickerType, String query, int limit, long chatId) { - this.stickerType = stickerType; - this.query = query; - this.limit = limit; - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1158058819; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns storage usage statistics. Can be called before authorization. - * - *

Returns {@link StorageStatistics StorageStatistics}

- */ - public static class GetStorageStatistics extends Function { - /** - * The maximum number of chats with the largest storage usage for which separate statistics need to be returned. All other chats will be grouped in entries with chatId == 0. If the chat info database is not used, the chatLimit is ignored and is always set to 0. - */ - public int chatLimit; - - /** - * Default constructor for a function, which returns storage usage statistics. Can be called before authorization. - * - *

Returns {@link StorageStatistics StorageStatistics}

- */ - public GetStorageStatistics() { - } - - /** - * Creates a function, which returns storage usage statistics. Can be called before authorization. - * - *

Returns {@link StorageStatistics StorageStatistics}

- * - * @param chatLimit The maximum number of chats with the largest storage usage for which separate statistics need to be returned. All other chats will be grouped in entries with chatId == 0. If the chat info database is not used, the chatLimit is ignored and is always set to 0. - */ - public GetStorageStatistics(int chatLimit) { - this.chatLimit = chatLimit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -853193929; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Quickly returns approximate storage usage statistics. Can be called before authorization. - * - *

Returns {@link StorageStatisticsFast StorageStatisticsFast}

- */ - public static class GetStorageStatisticsFast extends Function { - - /** - * Default constructor for a function, which quickly returns approximate storage usage statistics. Can be called before authorization. - * - *

Returns {@link StorageStatisticsFast StorageStatisticsFast}

- */ - public GetStorageStatisticsFast() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 61368066; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a story. - * - *

Returns {@link Story Story}

- */ - public static class GetStory extends Function { - /** - * Identifier of the chat that posted the story. - */ - public long storyPosterChatId; - /** - * Story identifier. - */ - public int storyId; - /** - * Pass true to get only locally available information without sending network requests. - */ - public boolean onlyLocal; - - /** - * Default constructor for a function, which returns a story. - * - *

Returns {@link Story Story}

- */ - public GetStory() { - } - - /** - * Creates a function, which returns a story. - * - *

Returns {@link Story Story}

- * - * @param storyPosterChatId Identifier of the chat that posted the story. - * @param storyId Story identifier. - * @param onlyLocal Pass true to get only locally available information without sending network requests. - */ - public GetStory(long storyPosterChatId, int storyId, boolean onlyLocal) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - this.onlyLocal = onlyLocal; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2011076366; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of stories added to the given story album. For optimal performance, the number of returned stories is chosen by TDLib. - * - *

Returns {@link Stories Stories}

- */ - public static class GetStoryAlbumStories extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Story album identifier. - */ - public int storyAlbumId; - /** - * Offset of the first entry to return; use 0 to get results from the first album story. - */ - public int offset; - /** - * The maximum number of stories to be returned. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which returns the list of stories added to the given story album. For optimal performance, the number of returned stories is chosen by TDLib. - * - *

Returns {@link Stories Stories}

- */ - public GetStoryAlbumStories() { - } - - /** - * Creates a function, which returns the list of stories added to the given story album. For optimal performance, the number of returned stories is chosen by TDLib. - * - *

Returns {@link Stories Stories}

- * - * @param chatId Chat identifier. - * @param storyAlbumId Story album identifier. - * @param offset Offset of the first entry to return; use 0 to get results from the first album story. - * @param limit The maximum number of stories to be returned. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - */ - public GetStoryAlbumStories(long chatId, int storyAlbumId, int offset, int limit) { - this.chatId = chatId; - this.storyAlbumId = storyAlbumId; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1915090076; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns reactions, which can be chosen for a story. - * - *

Returns {@link AvailableReactions AvailableReactions}

- */ - public static class GetStoryAvailableReactions extends Function { - /** - * Number of reaction per row, 5-25. - */ - public int rowSize; - - /** - * Default constructor for a function, which returns reactions, which can be chosen for a story. - * - *

Returns {@link AvailableReactions AvailableReactions}

- */ - public GetStoryAvailableReactions() { - } - - /** - * Creates a function, which returns reactions, which can be chosen for a story. - * - *

Returns {@link AvailableReactions AvailableReactions}

- * - * @param rowSize Number of reaction per row, 5-25. - */ - public GetStoryAvailableReactions(int rowSize) { - this.rowSize = rowSize; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 595938619; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns interactions with a story. The method can be called only for stories posted on behalf of the current user. - * - *

Returns {@link StoryInteractions StoryInteractions}

- */ - public static class GetStoryInteractions extends Function { - /** - * Story identifier. - */ - public int storyId; - /** - * Query to search for in names, usernames and titles; may be empty to get all relevant interactions. - */ - public String query; - /** - * Pass true to get only interactions by contacts; pass false to get all relevant interactions. - */ - public boolean onlyContacts; - /** - * Pass true to get forwards and reposts first, then reactions, then other views; pass false to get interactions sorted just by interaction date. - */ - public boolean preferForwards; - /** - * Pass true to get interactions with reaction first; pass false to get interactions sorted just by interaction date. Ignored if preferForwards == true. - */ - public boolean preferWithReaction; - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of story interactions to return. - */ - public int limit; - - /** - * Default constructor for a function, which returns interactions with a story. The method can be called only for stories posted on behalf of the current user. - * - *

Returns {@link StoryInteractions StoryInteractions}

- */ - public GetStoryInteractions() { - } - - /** - * Creates a function, which returns interactions with a story. The method can be called only for stories posted on behalf of the current user. - * - *

Returns {@link StoryInteractions StoryInteractions}

- * - * @param storyId Story identifier. - * @param query Query to search for in names, usernames and titles; may be empty to get all relevant interactions. - * @param onlyContacts Pass true to get only interactions by contacts; pass false to get all relevant interactions. - * @param preferForwards Pass true to get forwards and reposts first, then reactions, then other views; pass false to get interactions sorted just by interaction date. - * @param preferWithReaction Pass true to get interactions with reaction first; pass false to get interactions sorted just by interaction date. Ignored if preferForwards == true. - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of story interactions to return. - */ - public GetStoryInteractions(int storyId, String query, boolean onlyContacts, boolean preferForwards, boolean preferWithReaction, String offset, int limit) { - this.storyId = storyId; - this.query = query; - this.onlyContacts = onlyContacts; - this.preferForwards = preferForwards; - this.preferWithReaction = preferWithReaction; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 483475469; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of chats with non-default notification settings for stories. - * - *

Returns {@link Chats Chats}

- */ - public static class GetStoryNotificationSettingsExceptions extends Function { - - /** - * Default constructor for a function, which returns the list of chats with non-default notification settings for stories. - * - *

Returns {@link Chats Chats}

- */ - public GetStoryNotificationSettingsExceptions() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 627715760; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns forwards of a story as a message to public chats and reposts by public channels. Can be used only if the story is posted on behalf of the current user or story.canGetStatistics == true. For optimal performance, the number of returned messages and stories is chosen by TDLib. - * - *

Returns {@link PublicForwards PublicForwards}

- */ - public static class GetStoryPublicForwards extends Function { - /** - * The identifier of the poster of the story. - */ - public long storyPosterChatId; - /** - * The identifier of the story. - */ - public int storyId; - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of messages and stories to be returned; must be positive and can't be greater than 100. For optimal performance, the number of returned objects is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which returns forwards of a story as a message to public chats and reposts by public channels. Can be used only if the story is posted on behalf of the current user or story.canGetStatistics == true. For optimal performance, the number of returned messages and stories is chosen by TDLib. - * - *

Returns {@link PublicForwards PublicForwards}

- */ - public GetStoryPublicForwards() { - } - - /** - * Creates a function, which returns forwards of a story as a message to public chats and reposts by public channels. Can be used only if the story is posted on behalf of the current user or story.canGetStatistics == true. For optimal performance, the number of returned messages and stories is chosen by TDLib. - * - *

Returns {@link PublicForwards PublicForwards}

- * - * @param storyPosterChatId The identifier of the poster of the story. - * @param storyId The identifier of the story. - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of messages and stories to be returned; must be positive and can't be greater than 100. For optimal performance, the number of returned objects is chosen by TDLib and can be smaller than the specified limit. - */ - public GetStoryPublicForwards(long storyPosterChatId, int storyId, String offset, int limit) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1810378546; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns detailed statistics about a story. Can be used only if story.canGetStatistics == true. - * - *

Returns {@link StoryStatistics StoryStatistics}

- */ - public static class GetStoryStatistics extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Story identifier. - */ - public int storyId; - /** - * Pass true if a dark theme is used by the application. - */ - public boolean isDark; - - /** - * Default constructor for a function, which returns detailed statistics about a story. Can be used only if story.canGetStatistics == true. - * - *

Returns {@link StoryStatistics StoryStatistics}

- */ - public GetStoryStatistics() { - } - - /** - * Creates a function, which returns detailed statistics about a story. Can be used only if story.canGetStatistics == true. - * - *

Returns {@link StoryStatistics StoryStatistics}

- * - * @param chatId Chat identifier. - * @param storyId Story identifier. - * @param isDark Pass true if a dark theme is used by the application. - */ - public GetStoryStatistics(long chatId, int storyId, boolean isDark) { - this.chatId = chatId; - this.storyId = storyId; - this.isDark = isDark; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 982926146; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns suggested name for saving a file in a given directory. - * - *

Returns {@link Text Text}

- */ - public static class GetSuggestedFileName extends Function { - /** - * Identifier of the file. - */ - public int fileId; - /** - * Directory in which the file is expected to be saved. - */ - public String directory; - - /** - * Default constructor for a function, which returns suggested name for saving a file in a given directory. - * - *

Returns {@link Text Text}

- */ - public GetSuggestedFileName() { - } - - /** - * Creates a function, which returns suggested name for saving a file in a given directory. - * - *

Returns {@link Text Text}

- * - * @param fileId Identifier of the file. - * @param directory Directory in which the file is expected to be saved. - */ - public GetSuggestedFileName(int fileId, String directory) { - this.fileId = fileId; - this.directory = directory; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2049399674; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a suggested name for a new sticker set with a given title. - * - *

Returns {@link Text Text}

- */ - public static class GetSuggestedStickerSetName extends Function { - /** - * Sticker set title; 1-64 characters. - */ - public String title; - - /** - * Default constructor for a function, which returns a suggested name for a new sticker set with a given title. - * - *

Returns {@link Text Text}

- */ - public GetSuggestedStickerSetName() { - } - - /** - * Creates a function, which returns a suggested name for a new sticker set with a given title. - * - *

Returns {@link Text Text}

- * - * @param title Sticker set title; 1-64 characters. - */ - public GetSuggestedStickerSetName(String title) { - this.title = title; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1340995520; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a list of basic group and supergroup chats, which can be used as a discussion group for a channel. Returned basic group chats must be first upgraded to supergroups before they can be set as a discussion group. To set a returned supergroup as a discussion group, access to its old messages must be enabled using toggleSupergroupIsAllHistoryAvailable first. - * - *

Returns {@link Chats Chats}

- */ - public static class GetSuitableDiscussionChats extends Function { - - /** - * Default constructor for a function, which returns a list of basic group and supergroup chats, which can be used as a discussion group for a channel. Returned basic group chats must be first upgraded to supergroups before they can be set as a discussion group. To set a returned supergroup as a discussion group, access to its old messages must be enabled using toggleSupergroupIsAllHistoryAvailable first. - * - *

Returns {@link Chats Chats}

- */ - public GetSuitableDiscussionChats() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 49044982; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a list of channel chats, which can be used as a personal chat. - * - *

Returns {@link Chats Chats}

- */ - public static class GetSuitablePersonalChats extends Function { - - /** - * Default constructor for a function, which returns a list of channel chats, which can be used as a personal chat. - * - *

Returns {@link Chats Chats}

- */ - public GetSuitablePersonalChats() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1870357515; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a supergroup or a channel by its identifier. This is an offline method if the current user is not a bot. - * - *

Returns {@link Supergroup Supergroup}

- */ - public static class GetSupergroup extends Function { - /** - * Supergroup or channel identifier. - */ - public long supergroupId; - - /** - * Default constructor for a function, which returns information about a supergroup or a channel by its identifier. This is an offline method if the current user is not a bot. - * - *

Returns {@link Supergroup Supergroup}

- */ - public GetSupergroup() { - } - - /** - * Creates a function, which returns information about a supergroup or a channel by its identifier. This is an offline method if the current user is not a bot. - * - *

Returns {@link Supergroup Supergroup}

- * - * @param supergroupId Supergroup or channel identifier. - */ - public GetSupergroup(long supergroupId) { - this.supergroupId = supergroupId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 989663458; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns full information about a supergroup or a channel by its identifier, cached for up to 1 minute. - * - *

Returns {@link SupergroupFullInfo SupergroupFullInfo}

- */ - public static class GetSupergroupFullInfo extends Function { - /** - * Supergroup or channel identifier. - */ - public long supergroupId; - - /** - * Default constructor for a function, which returns full information about a supergroup or a channel by its identifier, cached for up to 1 minute. - * - *

Returns {@link SupergroupFullInfo SupergroupFullInfo}

- */ - public GetSupergroupFullInfo() { - } - - /** - * Creates a function, which returns full information about a supergroup or a channel by its identifier, cached for up to 1 minute. - * - *

Returns {@link SupergroupFullInfo SupergroupFullInfo}

- * - * @param supergroupId Supergroup or channel identifier. - */ - public GetSupergroupFullInfo(long supergroupId) { - this.supergroupId = supergroupId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1099776056; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about members or banned users in a supergroup or channel. Can be used only if supergroupFullInfo.canGetMembers == true; additionally, administrator privileges may be required for some filters. - * - *

Returns {@link ChatMembers ChatMembers}

- */ - public static class GetSupergroupMembers extends Function { - /** - * Identifier of the supergroup or channel. - */ - public long supergroupId; - /** - * The type of users to return; pass null to use supergroupMembersFilterRecent. - */ - public SupergroupMembersFilter filter; - /** - * Number of users to skip. - */ - public int offset; - /** - * The maximum number of users to be returned; up to 200. - */ - public int limit; - - /** - * Default constructor for a function, which returns information about members or banned users in a supergroup or channel. Can be used only if supergroupFullInfo.canGetMembers == true; additionally, administrator privileges may be required for some filters. - * - *

Returns {@link ChatMembers ChatMembers}

- */ - public GetSupergroupMembers() { - } - - /** - * Creates a function, which returns information about members or banned users in a supergroup or channel. Can be used only if supergroupFullInfo.canGetMembers == true; additionally, administrator privileges may be required for some filters. - * - *

Returns {@link ChatMembers ChatMembers}

- * - * @param supergroupId Identifier of the supergroup or channel. - * @param filter The type of users to return; pass null to use supergroupMembersFilterRecent. - * @param offset Number of users to skip. - * @param limit The maximum number of users to be returned; up to 200. - */ - public GetSupergroupMembers(long supergroupId, SupergroupMembersFilter filter, int offset, int limit) { - this.supergroupId = supergroupId; - this.filter = filter; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -570940984; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns localized name of the Telegram support user; for Telegram support only. - * - *

Returns {@link Text Text}

- */ - public static class GetSupportName extends Function { - - /** - * Default constructor for a function, which returns localized name of the Telegram support user; for Telegram support only. - * - *

Returns {@link Text Text}

- */ - public GetSupportName() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1302205794; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a user who can be contacted to get support. - * - *

Returns {@link User User}

- */ - public static class GetSupportUser extends Function { - - /** - * Default constructor for a function, which returns a user who can be contacted to get support. - * - *

Returns {@link User User}

- */ - public GetSupportUser() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1733497700; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about the current temporary password. - * - *

Returns {@link TemporaryPasswordState TemporaryPasswordState}

- */ - public static class GetTemporaryPasswordState extends Function { - - /** - * Default constructor for a function, which returns information about the current temporary password. - * - *

Returns {@link TemporaryPasswordState TemporaryPasswordState}

- */ - public GetTemporaryPasswordState() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -12670830; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns all entities (mentions, hashtags, cashtags, bot commands, bank card numbers, URLs, and email addresses) found in the text. Can be called synchronously. - * - *

Returns {@link TextEntities TextEntities}

- */ - public static class GetTextEntities extends Function { - /** - * The text in which to look for entities. - */ - public String text; - - /** - * Default constructor for a function, which returns all entities (mentions, hashtags, cashtags, bot commands, bank card numbers, URLs, and email addresses) found in the text. Can be called synchronously. - * - *

Returns {@link TextEntities TextEntities}

- */ - public GetTextEntities() { - } - - /** - * Creates a function, which returns all entities (mentions, hashtags, cashtags, bot commands, bank card numbers, URLs, and email addresses) found in the text. Can be called synchronously. - * - *

Returns {@link TextEntities TextEntities}

- * - * @param text The text in which to look for entities. - */ - public GetTextEntities(String text) { - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -341490693; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Converts a themeParameters object to corresponding JSON-serialized string. Can be called synchronously. - * - *

Returns {@link Text Text}

- */ - public static class GetThemeParametersJsonString extends Function { - /** - * Theme parameters to convert to JSON. - */ - public ThemeParameters theme; - - /** - * Default constructor for a function, which converts a themeParameters object to corresponding JSON-serialized string. Can be called synchronously. - * - *

Returns {@link Text Text}

- */ - public GetThemeParametersJsonString() { - } - - /** - * Creates a function, which converts a themeParameters object to corresponding JSON-serialized string. Can be called synchronously. - * - *

Returns {@link Text Text}

- * - * @param theme Theme parameters to convert to JSON. - */ - public GetThemeParametersJsonString(ThemeParameters theme) { - this.theme = theme; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1850145288; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns up to 8 emoji statuses, which must be shown in the emoji status list for chats. - * - *

Returns {@link EmojiStatusCustomEmojis EmojiStatusCustomEmojis}

- */ - public static class GetThemedChatEmojiStatuses extends Function { - - /** - * Default constructor for a function, which returns up to 8 emoji statuses, which must be shown in the emoji status list for chats. - * - *

Returns {@link EmojiStatusCustomEmojis EmojiStatusCustomEmojis}

- */ - public GetThemedChatEmojiStatuses() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1924568314; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns up to 8 emoji statuses, which must be shown right after the default Premium Badge in the emoji status list for self status. - * - *

Returns {@link EmojiStatusCustomEmojis EmojiStatusCustomEmojis}

- */ - public static class GetThemedEmojiStatuses extends Function { - - /** - * Default constructor for a function, which returns up to 8 emoji statuses, which must be shown right after the default Premium Badge in the emoji status list for self status. - * - *

Returns {@link EmojiStatusCustomEmojis EmojiStatusCustomEmojis}

- */ - public GetThemedEmojiStatuses() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1468220543; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of supported time zones. - * - *

Returns {@link TimeZones TimeZones}

- */ - public static class GetTimeZones extends Function { - - /** - * Default constructor for a function, which returns the list of supported time zones. - * - *

Returns {@link TimeZones TimeZones}

- */ - public GetTimeZones() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1340268632; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns detailed Toncoin revenue statistics of the current user. - * - *

Returns {@link TonRevenueStatistics TonRevenueStatistics}

- */ - public static class GetTonRevenueStatistics extends Function { - /** - * Pass true if a dark theme is used by the application. - */ - public boolean isDark; - - /** - * Default constructor for a function, which returns detailed Toncoin revenue statistics of the current user. - * - *

Returns {@link TonRevenueStatistics TonRevenueStatistics}

- */ - public GetTonRevenueStatistics() { - } - - /** - * Creates a function, which returns detailed Toncoin revenue statistics of the current user. - * - *

Returns {@link TonRevenueStatistics TonRevenueStatistics}

- * - * @param isDark Pass true if a dark theme is used by the application. - */ - public GetTonRevenueStatistics(boolean isDark) { - this.isDark = isDark; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1315591160; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of Toncoin transactions of the current user. - * - *

Returns {@link TonTransactions TonTransactions}

- */ - public static class GetTonTransactions extends Function { - /** - * Direction of the transactions to receive; pass null to get all transactions. - */ - public TransactionDirection direction; - /** - * Offset of the first transaction to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of transactions to return. - */ - public int limit; - - /** - * Default constructor for a function, which returns the list of Toncoin transactions of the current user. - * - *

Returns {@link TonTransactions TonTransactions}

- */ - public GetTonTransactions() { - } - - /** - * Creates a function, which returns the list of Toncoin transactions of the current user. - * - *

Returns {@link TonTransactions TonTransactions}

- * - * @param direction Direction of the transactions to receive; pass null to get all transactions. - * @param offset Offset of the first transaction to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of transactions to return. - */ - public GetTonTransactions(TransactionDirection direction, String offset, int limit) { - this.direction = direction; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1935011115; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a URL for Toncoin withdrawal from the current user's account. The user must have at least 10 toncoins to withdraw and can withdraw up to 100000 Toncoins in one transaction. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public static class GetTonWithdrawalUrl extends Function { - /** - * The 2-step verification password of the current user. - */ - public String password; - - /** - * Default constructor for a function, which returns a URL for Toncoin withdrawal from the current user's account. The user must have at least 10 toncoins to withdraw and can withdraw up to 100000 Toncoins in one transaction. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public GetTonWithdrawalUrl() { - } - - /** - * Creates a function, which returns a URL for Toncoin withdrawal from the current user's account. The user must have at least 10 toncoins to withdraw and can withdraw up to 100000 Toncoins in one transaction. - * - *

Returns {@link HttpUrl HttpUrl}

- * - * @param password The 2-step verification password of the current user. - */ - public GetTonWithdrawalUrl(String password) { - this.password = password; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1482519601; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a list of frequently used chats. - * - *

Returns {@link Chats Chats}

- */ - public static class GetTopChats extends Function { - /** - * Category of chats to be returned. - */ - public TopChatCategory category; - /** - * The maximum number of chats to be returned; up to 30. - */ - public int limit; - - /** - * Default constructor for a function, which returns a list of frequently used chats. - * - *

Returns {@link Chats Chats}

- */ - public GetTopChats() { - } - - /** - * Creates a function, which returns a list of frequently used chats. - * - *

Returns {@link Chats Chats}

- * - * @param category Category of chats to be returned. - * @param limit The maximum number of chats to be returned; up to 30. - */ - public GetTopChats(TopChatCategory category, int limit) { - this.category = category; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -388410847; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a list of trending sticker sets. For optimal performance, the number of returned sticker sets is chosen by TDLib. - * - *

Returns {@link TrendingStickerSets TrendingStickerSets}

- */ - public static class GetTrendingStickerSets extends Function { - /** - * Type of the sticker sets to return. - */ - public StickerType stickerType; - /** - * The offset from which to return the sticker sets; must be non-negative. - */ - public int offset; - /** - * The maximum number of sticker sets to be returned; up to 100. For optimal performance, the number of returned sticker sets is chosen by TDLib and can be smaller than the specified limit, even if the end of the list has not been reached. - */ - public int limit; - - /** - * Default constructor for a function, which returns a list of trending sticker sets. For optimal performance, the number of returned sticker sets is chosen by TDLib. - * - *

Returns {@link TrendingStickerSets TrendingStickerSets}

- */ - public GetTrendingStickerSets() { - } - - /** - * Creates a function, which returns a list of trending sticker sets. For optimal performance, the number of returned sticker sets is chosen by TDLib. - * - *

Returns {@link TrendingStickerSets TrendingStickerSets}

- * - * @param stickerType Type of the sticker sets to return. - * @param offset The offset from which to return the sticker sets; must be non-negative. - * @param limit The maximum number of sticker sets to be returned; up to 100. For optimal performance, the number of returned sticker sets is chosen by TDLib and can be smaller than the specified limit, even if the end of the list has not been reached. - */ - public GetTrendingStickerSets(StickerType stickerType, int offset, int limit) { - this.stickerType = stickerType; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -531085986; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about an upgraded gift by its name. - * - *

Returns {@link UpgradedGift UpgradedGift}

- */ - public static class GetUpgradedGift extends Function { - /** - * Unique name of the upgraded gift. - */ - public String name; - - /** - * Default constructor for a function, which returns information about an upgraded gift by its name. - * - *

Returns {@link UpgradedGift UpgradedGift}

- */ - public GetUpgradedGift() { - } - - /** - * Creates a function, which returns information about an upgraded gift by its name. - * - *

Returns {@link UpgradedGift UpgradedGift}

- * - * @param name Unique name of the upgraded gift. - */ - public GetUpgradedGift(String name) { - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1331821135; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns available upgraded gift emoji statuses for self status. - * - *

Returns {@link EmojiStatuses EmojiStatuses}

- */ - public static class GetUpgradedGiftEmojiStatuses extends Function { - - /** - * Default constructor for a function, which returns available upgraded gift emoji statuses for self status. - * - *

Returns {@link EmojiStatuses EmojiStatuses}

- */ - public GetUpgradedGiftEmojiStatuses() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1748975723; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about value of an upgraded gift by its name. - * - *

Returns {@link UpgradedGiftValueInfo UpgradedGiftValueInfo}

- */ - public static class GetUpgradedGiftValueInfo extends Function { - /** - * Unique name of the upgraded gift. - */ - public String name; - - /** - * Default constructor for a function, which returns information about value of an upgraded gift by its name. - * - *

Returns {@link UpgradedGiftValueInfo UpgradedGiftValueInfo}

- */ - public GetUpgradedGiftValueInfo() { - } - - /** - * Creates a function, which returns information about value of an upgraded gift by its name. - * - *

Returns {@link UpgradedGiftValueInfo UpgradedGiftValueInfo}

- * - * @param name Unique name of the upgraded gift. - */ - public GetUpgradedGiftValueInfo(String name) { - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1818813417; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns all possible variants of upgraded gifts for a regular gift. - * - *

Returns {@link GiftUpgradeVariants GiftUpgradeVariants}

- */ - public static class GetUpgradedGiftVariants extends Function { - /** - * Identifier of the regular gift. - */ - public long regularGiftId; - /** - * Pass true to get models that can be obtained by upgrading a regular gift. - */ - public boolean returnUpgradeModels; - /** - * Pass true to get models that can be obtained by crafting a gift from upgraded gifts. - */ - public boolean returnCraftModels; - - /** - * Default constructor for a function, which returns all possible variants of upgraded gifts for a regular gift. - * - *

Returns {@link GiftUpgradeVariants GiftUpgradeVariants}

- */ - public GetUpgradedGiftVariants() { - } - - /** - * Creates a function, which returns all possible variants of upgraded gifts for a regular gift. - * - *

Returns {@link GiftUpgradeVariants GiftUpgradeVariants}

- * - * @param regularGiftId Identifier of the regular gift. - * @param returnUpgradeModels Pass true to get models that can be obtained by upgrading a regular gift. - * @param returnCraftModels Pass true to get models that can be obtained by crafting a gift from upgraded gifts. - */ - public GetUpgradedGiftVariants(long regularGiftId, boolean returnUpgradeModels, boolean returnCraftModels) { - this.regularGiftId = regularGiftId; - this.returnUpgradeModels = returnUpgradeModels; - this.returnCraftModels = returnCraftModels; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1388671540; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a URL for upgraded gift withdrawal in the TON blockchain as an NFT; requires owner privileges for gifts owned by a chat. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public static class GetUpgradedGiftWithdrawalUrl extends Function { - /** - * Identifier of the gift. - */ - public String receivedGiftId; - /** - * The 2-step verification password of the current user. - */ - public String password; - - /** - * Default constructor for a function, which returns a URL for upgraded gift withdrawal in the TON blockchain as an NFT; requires owner privileges for gifts owned by a chat. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public GetUpgradedGiftWithdrawalUrl() { - } - - /** - * Creates a function, which returns a URL for upgraded gift withdrawal in the TON blockchain as an NFT; requires owner privileges for gifts owned by a chat. - * - *

Returns {@link HttpUrl HttpUrl}

- * - * @param receivedGiftId Identifier of the gift. - * @param password The 2-step verification password of the current user. - */ - public GetUpgradedGiftWithdrawalUrl(String receivedGiftId, String password) { - this.receivedGiftId = receivedGiftId; - this.password = password; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -784331188; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns promotional anumation for upgraded gifts. - * - *

Returns {@link Animation Animation}

- */ - public static class GetUpgradedGiftsPromotionalAnimation extends Function { - - /** - * Default constructor for a function, which returns promotional anumation for upgraded gifts. - * - *

Returns {@link Animation Animation}

- */ - public GetUpgradedGiftsPromotionalAnimation() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1944094513; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a user by their identifier. This is an offline method if the current user is not a bot. - * - *

Returns {@link User User}

- */ - public static class GetUser extends Function { - /** - * User identifier. - */ - public long userId; - - /** - * Default constructor for a function, which returns information about a user by their identifier. This is an offline method if the current user is not a bot. - * - *

Returns {@link User User}

- */ - public GetUser() { - } - - /** - * Creates a function, which returns information about a user by their identifier. This is an offline method if the current user is not a bot. - * - *

Returns {@link User User}

- * - * @param userId User identifier. - */ - public GetUser(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1117363211; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of boosts applied to a chat by a given user; requires administrator rights in the chat; for bots only. - * - *

Returns {@link FoundChatBoosts FoundChatBoosts}

- */ - public static class GetUserChatBoosts extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * Identifier of the user. - */ - public long userId; - - /** - * Default constructor for a function, which returns the list of boosts applied to a chat by a given user; requires administrator rights in the chat; for bots only. - * - *

Returns {@link FoundChatBoosts FoundChatBoosts}

- */ - public GetUserChatBoosts() { - } - - /** - * Creates a function, which returns the list of boosts applied to a chat by a given user; requires administrator rights in the chat; for bots only. - * - *

Returns {@link FoundChatBoosts FoundChatBoosts}

- * - * @param chatId Identifier of the chat. - * @param userId Identifier of the user. - */ - public GetUserChatBoosts(long chatId, long userId) { - this.chatId = chatId; - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1190205543; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns full information about a user by their identifier. - * - *

Returns {@link UserFullInfo UserFullInfo}

- */ - public static class GetUserFullInfo extends Function { - /** - * User identifier. - */ - public long userId; - - /** - * Default constructor for a function, which returns full information about a user by their identifier. - * - *

Returns {@link UserFullInfo UserFullInfo}

- */ - public GetUserFullInfo() { - } - - /** - * Creates a function, which returns full information about a user by their identifier. - * - *

Returns {@link UserFullInfo UserFullInfo}

- * - * @param userId User identifier. - */ - public GetUserFullInfo(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -776823720; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an HTTPS link, which can be used to get information about the current user. - * - *

Returns {@link UserLink UserLink}

- */ - public static class GetUserLink extends Function { - - /** - * Default constructor for a function, which returns an HTTPS link, which can be used to get information about the current user. - * - *

Returns {@link UserLink UserLink}

- */ - public GetUserLink() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1226839270; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the current privacy settings. - * - *

Returns {@link UserPrivacySettingRules UserPrivacySettingRules}

- */ - public static class GetUserPrivacySettingRules extends Function { - /** - * The privacy setting. - */ - public UserPrivacySetting setting; - - /** - * Default constructor for a function, which returns the current privacy settings. - * - *

Returns {@link UserPrivacySettingRules UserPrivacySettingRules}

- */ - public GetUserPrivacySettingRules() { - } - - /** - * Creates a function, which returns the current privacy settings. - * - *

Returns {@link UserPrivacySettingRules UserPrivacySettingRules}

- * - * @param setting The privacy setting. - */ - public GetUserPrivacySettingRules(UserPrivacySetting setting) { - this.setting = setting; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2077223311; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of profile audio files of a user. - * - *

Returns {@link Audios Audios}

- */ - public static class GetUserProfileAudios extends Function { - /** - * User identifier. - */ - public long userId; - /** - * The number of audio files to skip; must be non-negative. - */ - public int offset; - /** - * The maximum number of audio files to be returned; up to 100. - */ - public int limit; - - /** - * Default constructor for a function, which returns the list of profile audio files of a user. - * - *

Returns {@link Audios Audios}

- */ - public GetUserProfileAudios() { - } - - /** - * Creates a function, which returns the list of profile audio files of a user. - * - *

Returns {@link Audios Audios}

- * - * @param userId User identifier. - * @param offset The number of audio files to skip; must be non-negative. - * @param limit The maximum number of audio files to be returned; up to 100. - */ - public GetUserProfileAudios(long userId, int offset, int limit) { - this.userId = userId; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -208876086; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the profile photos of a user. Personal and public photo aren't returned. - * - *

Returns {@link ChatPhotos ChatPhotos}

- */ - public static class GetUserProfilePhotos extends Function { - /** - * User identifier. - */ - public long userId; - /** - * The number of photos to skip; must be non-negative. - */ - public int offset; - /** - * The maximum number of photos to be returned; up to 100. - */ - public int limit; - - /** - * Default constructor for a function, which returns the profile photos of a user. Personal and public photo aren't returned. - * - *

Returns {@link ChatPhotos ChatPhotos}

- */ - public GetUserProfilePhotos() { - } - - /** - * Creates a function, which returns the profile photos of a user. Personal and public photo aren't returned. - * - *

Returns {@link ChatPhotos ChatPhotos}

- * - * @param userId User identifier. - * @param offset The number of photos to skip; must be non-negative. - * @param limit The maximum number of photos to be returned; up to 100. - */ - public GetUserProfilePhotos(long userId, int offset, int limit) { - this.userId = userId; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -908132798; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns support information for the given user; for Telegram support only. - * - *

Returns {@link UserSupportInfo UserSupportInfo}

- */ - public static class GetUserSupportInfo extends Function { - /** - * User identifier. - */ - public long userId; - - /** - * Default constructor for a function, which returns support information for the given user; for Telegram support only. - * - *

Returns {@link UserSupportInfo UserSupportInfo}

- */ - public GetUserSupportInfo() { - } - - /** - * Creates a function, which returns support information for the given user; for Telegram support only. - * - *

Returns {@link UserSupportInfo UserSupportInfo}

- * - * @param userId User identifier. - */ - public GetUserSupportInfo(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1957008133; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the list of participant identifiers, on whose behalf a video chat in the chat can be joined. - * - *

Returns {@link MessageSenders MessageSenders}

- */ - public static class GetVideoChatAvailableParticipants extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which returns the list of participant identifiers, on whose behalf a video chat in the chat can be joined. - * - *

Returns {@link MessageSenders MessageSenders}

- */ - public GetVideoChatAvailableParticipants() { - } - - /** - * Creates a function, which returns the list of participant identifiers, on whose behalf a video chat in the chat can be joined. - * - *

Returns {@link MessageSenders MessageSenders}

- * - * @param chatId Chat identifier. - */ - public GetVideoChatAvailableParticipants(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1000496379; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns invite link to a video chat in a public chat. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public static class GetVideoChatInviteLink extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Pass true if the invite link needs to contain an invite hash, passing which to joinVideoChat would allow the invited user to unmute themselves. Requires groupCall.canBeManaged right. - */ - public boolean canSelfUnmute; - - /** - * Default constructor for a function, which returns invite link to a video chat in a public chat. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public GetVideoChatInviteLink() { - } - - /** - * Creates a function, which returns invite link to a video chat in a public chat. - * - *

Returns {@link HttpUrl HttpUrl}

- * - * @param groupCallId Group call identifier. - * @param canSelfUnmute Pass true if the invite link needs to contain an invite hash, passing which to joinVideoChat would allow the invited user to unmute themselves. Requires groupCall.canBeManaged right. - */ - public GetVideoChatInviteLink(int groupCallId, boolean canSelfUnmute) { - this.groupCallId = groupCallId; - this.canSelfUnmute = canSelfUnmute; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1394707321; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns RTMP URL for streaming to the video chat of a chat; requires canManageVideoChats administrator right. - * - *

Returns {@link RtmpUrl RtmpUrl}

- */ - public static class GetVideoChatRtmpUrl extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which returns RTMP URL for streaming to the video chat of a chat; requires canManageVideoChats administrator right. - * - *

Returns {@link RtmpUrl RtmpUrl}

- */ - public GetVideoChatRtmpUrl() { - } - - /** - * Creates a function, which returns RTMP URL for streaming to the video chat of a chat; requires canManageVideoChats administrator right. - * - *

Returns {@link RtmpUrl RtmpUrl}

- * - * @param chatId Chat identifier. - */ - public GetVideoChatRtmpUrl(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1210784543; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns advertisements to be shown while a video from a message is watched. Available only if messageProperties.canGetVideoAdvertisements. - * - *

Returns {@link VideoMessageAdvertisements VideoMessageAdvertisements}

- */ - public static class GetVideoMessageAdvertisements extends Function { - /** - * Identifier of the chat with the message. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - - /** - * Default constructor for a function, which returns advertisements to be shown while a video from a message is watched. Available only if messageProperties.canGetVideoAdvertisements. - * - *

Returns {@link VideoMessageAdvertisements VideoMessageAdvertisements}

- */ - public GetVideoMessageAdvertisements() { - } - - /** - * Creates a function, which returns advertisements to be shown while a video from a message is watched. Available only if messageProperties.canGetVideoAdvertisements. - * - *

Returns {@link VideoMessageAdvertisements VideoMessageAdvertisements}

- * - * @param chatId Identifier of the chat with the message. - * @param messageId Identifier of the message. - */ - public GetVideoMessageAdvertisements(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -285681331; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an HTTPS URL of a Web App to open after a link of the type internalLinkTypeWebApp is clicked. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public static class GetWebAppLinkUrl extends Function { - /** - * Identifier of the chat in which the link was clicked; pass 0 if none. - */ - public long chatId; - /** - * Identifier of the target bot. - */ - public long botUserId; - /** - * Short name of the Web App. - */ - public String webAppShortName; - /** - * Start parameter from internalLinkTypeWebApp. - */ - public String startParameter; - /** - * Pass true if the current user allowed the bot to send them messages. - */ - public boolean allowWriteAccess; - /** - * Parameters to use to open the Web App. - */ - public WebAppOpenParameters parameters; - - /** - * Default constructor for a function, which returns an HTTPS URL of a Web App to open after a link of the type internalLinkTypeWebApp is clicked. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public GetWebAppLinkUrl() { - } - - /** - * Creates a function, which returns an HTTPS URL of a Web App to open after a link of the type internalLinkTypeWebApp is clicked. - * - *

Returns {@link HttpUrl HttpUrl}

- * - * @param chatId Identifier of the chat in which the link was clicked; pass 0 if none. - * @param botUserId Identifier of the target bot. - * @param webAppShortName Short name of the Web App. - * @param startParameter Start parameter from internalLinkTypeWebApp. - * @param allowWriteAccess Pass true if the current user allowed the bot to send them messages. - * @param parameters Parameters to use to open the Web App. - */ - public GetWebAppLinkUrl(long chatId, long botUserId, String webAppShortName, String startParameter, boolean allowWriteAccess, WebAppOpenParameters parameters) { - this.chatId = chatId; - this.botUserId = botUserId; - this.webAppShortName = webAppShortName; - this.startParameter = startParameter; - this.allowWriteAccess = allowWriteAccess; - this.parameters = parameters; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1627284161; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns a default placeholder for Web Apps of a bot. This is an offline method. Returns a 404 error if the placeholder isn't known. - * - *

Returns {@link Outline Outline}

- */ - public static class GetWebAppPlaceholder extends Function { - /** - * Identifier of the target bot. - */ - public long botUserId; - - /** - * Default constructor for a function, which returns a default placeholder for Web Apps of a bot. This is an offline method. Returns a 404 error if the placeholder isn't known. - * - *

Returns {@link Outline Outline}

- */ - public GetWebAppPlaceholder() { - } - - /** - * Creates a function, which returns a default placeholder for Web Apps of a bot. This is an offline method. Returns a 404 error if the placeholder isn't known. - * - *

Returns {@link Outline Outline}

- * - * @param botUserId Identifier of the target bot. - */ - public GetWebAppPlaceholder(long botUserId) { - this.botUserId = botUserId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 583470479; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an HTTPS URL of a Web App to open from the side menu, a keyboardButtonTypeWebApp button, or an inlineQueryResultsButtonTypeWebApp button. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public static class GetWebAppUrl extends Function { - /** - * Identifier of the target bot. If the bot is restricted for the current user, then show an error instead of calling the method. - */ - public long botUserId; - /** - * The URL from a keyboardButtonTypeWebApp button, inlineQueryResultsButtonTypeWebApp button, or an empty string when the bot is opened from the side menu. - */ - public String url; - /** - * Parameters to use to open the Web App. - */ - public WebAppOpenParameters parameters; - - /** - * Default constructor for a function, which returns an HTTPS URL of a Web App to open from the side menu, a keyboardButtonTypeWebApp button, or an inlineQueryResultsButtonTypeWebApp button. - * - *

Returns {@link HttpUrl HttpUrl}

- */ - public GetWebAppUrl() { - } - - /** - * Creates a function, which returns an HTTPS URL of a Web App to open from the side menu, a keyboardButtonTypeWebApp button, or an inlineQueryResultsButtonTypeWebApp button. - * - *

Returns {@link HttpUrl HttpUrl}

- * - * @param botUserId Identifier of the target bot. If the bot is restricted for the current user, then show an error instead of calling the method. - * @param url The URL from a keyboardButtonTypeWebApp button, inlineQueryResultsButtonTypeWebApp button, or an empty string when the bot is opened from the side menu. - * @param parameters Parameters to use to open the Web App. - */ - public GetWebAppUrl(long botUserId, String url, WebAppOpenParameters parameters) { - this.botUserId = botUserId; - this.url = url; - this.parameters = parameters; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1526784188; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns an instant view version of a web page if available. This is an offline method if onlyLocal is true. Returns a 404 error if the web page has no instant view page. - * - *

Returns {@link WebPageInstantView WebPageInstantView}

- */ - public static class GetWebPageInstantView extends Function { - /** - * The web page URL. - */ - public String url; - /** - * Pass true to get only locally available information without sending network requests. - */ - public boolean onlyLocal; - - /** - * Default constructor for a function, which returns an instant view version of a web page if available. This is an offline method if onlyLocal is true. Returns a 404 error if the web page has no instant view page. - * - *

Returns {@link WebPageInstantView WebPageInstantView}

- */ - public GetWebPageInstantView() { - } - - /** - * Creates a function, which returns an instant view version of a web page if available. This is an offline method if onlyLocal is true. Returns a 404 error if the web page has no instant view page. - * - *

Returns {@link WebPageInstantView WebPageInstantView}

- * - * @param url The web page URL. - * @param onlyLocal Pass true to get only locally available information without sending network requests. - */ - public GetWebPageInstantView(String url, boolean onlyLocal) { - this.url = url; - this.onlyLocal = onlyLocal; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1741395197; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Allows to buy a Telegram Premium subscription for another user with payment in Telegram Stars; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class GiftPremiumWithStars extends Function { - /** - * Identifier of the user which will receive Telegram Premium. - */ - public long userId; - /** - * The number of Telegram Stars to pay for subscription. - */ - public long starCount; - /** - * Number of months the Telegram Premium subscription will be active for the user. - */ - public int monthCount; - /** - * Text to show to the user receiving Telegram Premium; 0-getOption("gift_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed. - */ - public FormattedText text; - - /** - * Default constructor for a function, which allows to buy a Telegram Premium subscription for another user with payment in Telegram Stars; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public GiftPremiumWithStars() { - } - - /** - * Creates a function, which allows to buy a Telegram Premium subscription for another user with payment in Telegram Stars; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param userId Identifier of the user which will receive Telegram Premium. - * @param starCount The number of Telegram Stars to pay for subscription. - * @param monthCount Number of months the Telegram Premium subscription will be active for the user. - * @param text Text to show to the user receiving Telegram Premium; 0-getOption("gift_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed. - */ - public GiftPremiumWithStars(long userId, long starCount, int monthCount, FormattedText text) { - this.userId = userId; - this.starCount = starCount; - this.monthCount = monthCount; - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2058395432; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Hides the list of contacts that have close birthdays for 24 hours. - * - *

Returns {@link Ok Ok}

- */ - public static class HideContactCloseBirthdays extends Function { - - /** - * Default constructor for a function, which hides the list of contacts that have close birthdays for 24 hours. - * - *

Returns {@link Ok Ok}

- */ - public HideContactCloseBirthdays() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1163065221; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Hides a suggested action. - * - *

Returns {@link Ok Ok}

- */ - public static class HideSuggestedAction extends Function { - /** - * Suggested action to hide. - */ - public SuggestedAction action; - - /** - * Default constructor for a function, which hides a suggested action. - * - *

Returns {@link Ok Ok}

- */ - public HideSuggestedAction() { - } - - /** - * Creates a function, which hides a suggested action. - * - *

Returns {@link Ok Ok}

- * - * @param action Suggested action to hide. - */ - public HideSuggestedAction(SuggestedAction action) { - this.action = action; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1561384065; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds new contacts or edits existing contacts by their phone numbers; contacts' user identifiers are ignored. - * - *

Returns {@link ImportedContacts ImportedContacts}

- */ - public static class ImportContacts extends Function { - /** - * The list of contacts to import or edit. - */ - public ImportedContact[] contacts; - - /** - * Default constructor for a function, which adds new contacts or edits existing contacts by their phone numbers; contacts' user identifiers are ignored. - * - *

Returns {@link ImportedContacts ImportedContacts}

- */ - public ImportContacts() { - } - - /** - * Creates a function, which adds new contacts or edits existing contacts by their phone numbers; contacts' user identifiers are ignored. - * - *

Returns {@link ImportedContacts ImportedContacts}

- * - * @param contacts The list of contacts to import or edit. - */ - public ImportContacts(ImportedContact[] contacts) { - this.contacts = contacts; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -662555959; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Imports messages exported from another app. - * - *

Returns {@link Ok Ok}

- */ - public static class ImportMessages extends Function { - /** - * Identifier of a chat to which the messages will be imported. It must be an identifier of a private chat with a mutual contact or an identifier of a supergroup chat with canChangeInfo member right. - */ - public long chatId; - /** - * File with messages to import. Only inputFileLocal and inputFileGenerated are supported. The file must not be previously uploaded. - */ - public InputFile messageFile; - /** - * Files used in the imported messages. Only inputFileLocal and inputFileGenerated are supported. The files must not be previously uploaded. - */ - public InputFile[] attachedFiles; - - /** - * Default constructor for a function, which imports messages exported from another app. - * - *

Returns {@link Ok Ok}

- */ - public ImportMessages() { - } - - /** - * Creates a function, which imports messages exported from another app. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of a chat to which the messages will be imported. It must be an identifier of a private chat with a mutual contact or an identifier of a supergroup chat with canChangeInfo member right. - * @param messageFile File with messages to import. Only inputFileLocal and inputFileGenerated are supported. The file must not be previously uploaded. - * @param attachedFiles Files used in the imported messages. Only inputFileLocal and inputFileGenerated are supported. The files must not be previously uploaded. - */ - public ImportMessages(long chatId, InputFile messageFile, InputFile[] attachedFiles) { - this.chatId = chatId; - this.messageFile = messageFile; - this.attachedFiles = attachedFiles; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1864116784; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Increases a bid for an auction gift without changing gift text and receiver. - * - *

Returns {@link Ok Ok}

- */ - public static class IncreaseGiftAuctionBid extends Function { - /** - * Identifier of the gift to put the bid on. - */ - public long giftId; - /** - * The number of Telegram Stars to put in the bid. - */ - public long starCount; - - /** - * Default constructor for a function, which increases a bid for an auction gift without changing gift text and receiver. - * - *

Returns {@link Ok Ok}

- */ - public IncreaseGiftAuctionBid() { - } - - /** - * Creates a function, which increases a bid for an auction gift without changing gift text and receiver. - * - *

Returns {@link Ok Ok}

- * - * @param giftId Identifier of the gift to put the bid on. - * @param starCount The number of Telegram Stars to put in the bid. - */ - public IncreaseGiftAuctionBid(long giftId, long starCount) { - this.giftId = giftId; - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -493509001; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Invites a user to an active group call; for group calls not bound to a chat only. Sends a service message of the type messageGroupCall. The group call can have at most getOption("group_call_participant_count_max") participants. - * - *

Returns {@link InviteGroupCallParticipantResult InviteGroupCallParticipantResult}

- */ - public static class InviteGroupCallParticipant extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * User identifier. - */ - public long userId; - /** - * Pass true if the group call is a video call. - */ - public boolean isVideo; - - /** - * Default constructor for a function, which invites a user to an active group call; for group calls not bound to a chat only. Sends a service message of the type messageGroupCall. The group call can have at most getOption("group_call_participant_count_max") participants. - * - *

Returns {@link InviteGroupCallParticipantResult InviteGroupCallParticipantResult}

- */ - public InviteGroupCallParticipant() { - } - - /** - * Creates a function, which invites a user to an active group call; for group calls not bound to a chat only. Sends a service message of the type messageGroupCall. The group call can have at most getOption("group_call_participant_count_max") participants. - * - *

Returns {@link InviteGroupCallParticipantResult InviteGroupCallParticipantResult}

- * - * @param groupCallId Group call identifier. - * @param userId User identifier. - * @param isVideo Pass true if the group call is a video call. - */ - public InviteGroupCallParticipant(int groupCallId, long userId, boolean isVideo) { - this.groupCallId = groupCallId; - this.userId = userId; - this.isVideo = isVideo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -631535414; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Invites users to an active video chat. Sends a service message of the type messageInviteVideoChatParticipants to the chat bound to the group call. - * - *

Returns {@link Ok Ok}

- */ - public static class InviteVideoChatParticipants extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * User identifiers. At most 10 users can be invited simultaneously. - */ - public long[] userIds; - - /** - * Default constructor for a function, which invites users to an active video chat. Sends a service message of the type messageInviteVideoChatParticipants to the chat bound to the group call. - * - *

Returns {@link Ok Ok}

- */ - public InviteVideoChatParticipants() { - } - - /** - * Creates a function, which invites users to an active video chat. Sends a service message of the type messageInviteVideoChatParticipants to the chat bound to the group call. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param userIds User identifiers. At most 10 users can be invited simultaneously. - */ - public InviteVideoChatParticipants(int groupCallId, long[] userIds) { - this.groupCallId = groupCallId; - this.userIds = userIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -473149298; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks whether the current user is required to set login email address. - * - *

Returns {@link Ok Ok}

- */ - public static class IsLoginEmailAddressRequired extends Function { - - /** - * Default constructor for a function, which checks whether the current user is required to set login email address. - * - *

Returns {@link Ok Ok}

- */ - public IsLoginEmailAddressRequired() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -874594326; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Checks whether a file is in the profile audio files of the current user. Returns a 404 error if it isn't. - * - *

Returns {@link Ok Ok}

- */ - public static class IsProfileAudio extends Function { - /** - * Identifier of the audio file to check. - */ - public int fileId; - - /** - * Default constructor for a function, which checks whether a file is in the profile audio files of the current user. Returns a 404 error if it isn't. - * - *

Returns {@link Ok Ok}

- */ - public IsProfileAudio() { - } - - /** - * Creates a function, which checks whether a file is in the profile audio files of the current user. Returns a 404 error if it isn't. - * - *

Returns {@link Ok Ok}

- * - * @param fileId Identifier of the audio file to check. - */ - public IsProfileAudio(int fileId) { - this.fileId = fileId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -245729314; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds the current user as a new member to a chat. Private and secret chats can't be joined using this method. May return an error with a message "INVITE_REQUEST_SENT" if only a join request was created. - * - *

Returns {@link Ok Ok}

- */ - public static class JoinChat extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which adds the current user as a new member to a chat. Private and secret chats can't be joined using this method. May return an error with a message "INVITE_REQUEST_SENT" if only a join request was created. - * - *

Returns {@link Ok Ok}

- */ - public JoinChat() { - } - - /** - * Creates a function, which adds the current user as a new member to a chat. Private and secret chats can't be joined using this method. May return an error with a message "INVITE_REQUEST_SENT" if only a join request was created. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - */ - public JoinChat(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 326769313; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Uses an invite link to add the current user to the chat if possible. May return an error with a message "INVITE_REQUEST_SENT" if only a join request was created. - * - *

Returns {@link Chat Chat}

- */ - public static class JoinChatByInviteLink extends Function { - /** - * Invite link to use. - */ - public String inviteLink; - - /** - * Default constructor for a function, which uses an invite link to add the current user to the chat if possible. May return an error with a message "INVITE_REQUEST_SENT" if only a join request was created. - * - *

Returns {@link Chat Chat}

- */ - public JoinChatByInviteLink() { - } - - /** - * Creates a function, which uses an invite link to add the current user to the chat if possible. May return an error with a message "INVITE_REQUEST_SENT" if only a join request was created. - * - *

Returns {@link Chat Chat}

- * - * @param inviteLink Invite link to use. - */ - public JoinChatByInviteLink(String inviteLink) { - this.inviteLink = inviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1049973882; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Joins a regular group call that is not bound to a chat. - * - *

Returns {@link GroupCallInfo GroupCallInfo}

- */ - public static class JoinGroupCall extends Function { - /** - * The group call to join. - */ - public InputGroupCall inputGroupCall; - /** - * Parameters to join the call. - */ - public GroupCallJoinParameters joinParameters; - - /** - * Default constructor for a function, which joins a regular group call that is not bound to a chat. - * - *

Returns {@link GroupCallInfo GroupCallInfo}

- */ - public JoinGroupCall() { - } - - /** - * Creates a function, which joins a regular group call that is not bound to a chat. - * - *

Returns {@link GroupCallInfo GroupCallInfo}

- * - * @param inputGroupCall The group call to join. - * @param joinParameters Parameters to join the call. - */ - public JoinGroupCall(InputGroupCall inputGroupCall, GroupCallJoinParameters joinParameters) { - this.inputGroupCall = inputGroupCall; - this.joinParameters = joinParameters; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2026079917; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Joins a group call of an active live story. Returns join response payload for tgcalls. - * - *

Returns {@link Text Text}

- */ - public static class JoinLiveStory extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Parameters to join the call. - */ - public GroupCallJoinParameters joinParameters; - - /** - * Default constructor for a function, which joins a group call of an active live story. Returns join response payload for tgcalls. - * - *

Returns {@link Text Text}

- */ - public JoinLiveStory() { - } - - /** - * Creates a function, which joins a group call of an active live story. Returns join response payload for tgcalls. - * - *

Returns {@link Text Text}

- * - * @param groupCallId Group call identifier. - * @param joinParameters Parameters to join the call. - */ - public JoinLiveStory(int groupCallId, GroupCallJoinParameters joinParameters) { - this.groupCallId = groupCallId; - this.joinParameters = joinParameters; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 227825676; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Joins an active video chat. Returns join response payload for tgcalls. - * - *

Returns {@link Text Text}

- */ - public static class JoinVideoChat extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Identifier of a group call participant, which will be used to join the call; pass null to join as self. - */ - public MessageSender participantId; - /** - * Parameters to join the call. - */ - public GroupCallJoinParameters joinParameters; - /** - * Invite hash as received from internalLinkTypeVideoChat. - */ - public String inviteHash; - - /** - * Default constructor for a function, which joins an active video chat. Returns join response payload for tgcalls. - * - *

Returns {@link Text Text}

- */ - public JoinVideoChat() { - } - - /** - * Creates a function, which joins an active video chat. Returns join response payload for tgcalls. - * - *

Returns {@link Text Text}

- * - * @param groupCallId Group call identifier. - * @param participantId Identifier of a group call participant, which will be used to join the call; pass null to join as self. - * @param joinParameters Parameters to join the call. - * @param inviteHash Invite hash as received from internalLinkTypeVideoChat. - */ - public JoinVideoChat(int groupCallId, MessageSender participantId, GroupCallJoinParameters joinParameters, String inviteHash) { - this.groupCallId = groupCallId; - this.participantId = participantId; - this.joinParameters = joinParameters; - this.inviteHash = inviteHash; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1322989999; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Launches a prepaid giveaway. - * - *

Returns {@link Ok Ok}

- */ - public static class LaunchPrepaidGiveaway extends Function { - /** - * Unique identifier of the prepaid giveaway. - */ - public long giveawayId; - /** - * Giveaway parameters. - */ - public GiveawayParameters parameters; - /** - * The number of users to receive giveaway prize. - */ - public int winnerCount; - /** - * The number of Telegram Stars to be distributed through the giveaway; pass 0 for Telegram Premium giveaways. - */ - public long starCount; - - /** - * Default constructor for a function, which launches a prepaid giveaway. - * - *

Returns {@link Ok Ok}

- */ - public LaunchPrepaidGiveaway() { - } - - /** - * Creates a function, which launches a prepaid giveaway. - * - *

Returns {@link Ok Ok}

- * - * @param giveawayId Unique identifier of the prepaid giveaway. - * @param parameters Giveaway parameters. - * @param winnerCount The number of users to receive giveaway prize. - * @param starCount The number of Telegram Stars to be distributed through the giveaway; pass 0 for Telegram Premium giveaways. - */ - public LaunchPrepaidGiveaway(long giveawayId, GiveawayParameters parameters, int winnerCount, long starCount) { - this.giveawayId = giveawayId; - this.parameters = parameters; - this.winnerCount = winnerCount; - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 639465530; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes the current user from chat members. Private and secret chats can't be left using this method. - * - *

Returns {@link Ok Ok}

- */ - public static class LeaveChat extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which removes the current user from chat members. Private and secret chats can't be left using this method. - * - *

Returns {@link Ok Ok}

- */ - public LeaveChat() { - } - - /** - * Creates a function, which removes the current user from chat members. Private and secret chats can't be left using this method. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - */ - public LeaveChat(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1825080735; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Leaves a group call. - * - *

Returns {@link Ok Ok}

- */ - public static class LeaveGroupCall extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - - /** - * Default constructor for a function, which leaves a group call. - * - *

Returns {@link Ok Ok}

- */ - public LeaveGroupCall() { - } - - /** - * Creates a function, which leaves a group call. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - */ - public LeaveGroupCall(int groupCallId) { - this.groupCallId = groupCallId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 980152233; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Loads more active stories from a story list. The loaded stories will be sent through updates. Active stories are sorted by the pair (activeStories.order, activeStories.storyPosterChatId) in descending order. Returns a 404 error if all active stories have been loaded. - * - *

Returns {@link Ok Ok}

- */ - public static class LoadActiveStories extends Function { - /** - * The story list in which to load active stories. - */ - public StoryList storyList; - - /** - * Default constructor for a function, which loads more active stories from a story list. The loaded stories will be sent through updates. Active stories are sorted by the pair (activeStories.order, activeStories.storyPosterChatId) in descending order. Returns a 404 error if all active stories have been loaded. - * - *

Returns {@link Ok Ok}

- */ - public LoadActiveStories() { - } - - /** - * Creates a function, which loads more active stories from a story list. The loaded stories will be sent through updates. Active stories are sorted by the pair (activeStories.order, activeStories.storyPosterChatId) in descending order. Returns a 404 error if all active stories have been loaded. - * - *

Returns {@link Ok Ok}

- * - * @param storyList The story list in which to load active stories. - */ - public LoadActiveStories(StoryList storyList) { - this.storyList = storyList; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2106390328; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Loads more chats from a chat list. The loaded chats and their positions in the chat list will be sent through updates. Chats are sorted by the pair (chat.position.order, chat.id) in descending order. Returns a 404 error if all chats have been loaded. - * - *

Returns {@link Ok Ok}

- */ - public static class LoadChats extends Function { - /** - * The chat list in which to load chats; pass null to load chats from the main chat list. - */ - public ChatList chatList; - /** - * The maximum number of chats to be loaded. For optimal performance, the number of loaded chats is chosen by TDLib and can be smaller than the specified limit, even if the end of the list is not reached. - */ - public int limit; - - /** - * Default constructor for a function, which loads more chats from a chat list. The loaded chats and their positions in the chat list will be sent through updates. Chats are sorted by the pair (chat.position.order, chat.id) in descending order. Returns a 404 error if all chats have been loaded. - * - *

Returns {@link Ok Ok}

- */ - public LoadChats() { - } - - /** - * Creates a function, which loads more chats from a chat list. The loaded chats and their positions in the chat list will be sent through updates. Chats are sorted by the pair (chat.position.order, chat.id) in descending order. Returns a 404 error if all chats have been loaded. - * - *

Returns {@link Ok Ok}

- * - * @param chatList The chat list in which to load chats; pass null to load chats from the main chat list. - * @param limit The maximum number of chats to be loaded. For optimal performance, the number of loaded chats is chosen by TDLib and can be smaller than the specified limit, even if the end of the list is not reached. - */ - public LoadChats(ChatList chatList, int limit) { - this.chatList = chatList; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1885635205; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Loads more topics in a channel direct messages chat administered by the current user. The loaded topics will be sent through updateDirectMessagesChatTopic. Topics are sorted by their topic.order in descending order. Returns a 404 error if all topics have been loaded. - * - *

Returns {@link Ok Ok}

- */ - public static class LoadDirectMessagesChatTopics extends Function { - /** - * Chat identifier of the channel direct messages chat. - */ - public long chatId; - /** - * The maximum number of topics to be loaded. For optimal performance, the number of loaded topics is chosen by TDLib and can be smaller than the specified limit, even if the end of the list is not reached. - */ - public int limit; - - /** - * Default constructor for a function, which loads more topics in a channel direct messages chat administered by the current user. The loaded topics will be sent through updateDirectMessagesChatTopic. Topics are sorted by their topic.order in descending order. Returns a 404 error if all topics have been loaded. - * - *

Returns {@link Ok Ok}

- */ - public LoadDirectMessagesChatTopics() { - } - - /** - * Creates a function, which loads more topics in a channel direct messages chat administered by the current user. The loaded topics will be sent through updateDirectMessagesChatTopic. Topics are sorted by their topic.order in descending order. Returns a 404 error if all topics have been loaded. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier of the channel direct messages chat. - * @param limit The maximum number of topics to be loaded. For optimal performance, the number of loaded topics is chosen by TDLib and can be smaller than the specified limit, even if the end of the list is not reached. - */ - public LoadDirectMessagesChatTopics(long chatId, int limit) { - this.chatId = chatId; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1488065975; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Loads more participants of a group call; not supported in live stories. The loaded participants will be received through updates. Use the field groupCall.loadedAllParticipants to check whether all participants have already been loaded. - * - *

Returns {@link Ok Ok}

- */ - public static class LoadGroupCallParticipants extends Function { - /** - * Group call identifier. The group call must be previously received through getGroupCall and must be joined or being joined. - */ - public int groupCallId; - /** - * The maximum number of participants to load; up to 100. - */ - public int limit; - - /** - * Default constructor for a function, which loads more participants of a group call; not supported in live stories. The loaded participants will be received through updates. Use the field groupCall.loadedAllParticipants to check whether all participants have already been loaded. - * - *

Returns {@link Ok Ok}

- */ - public LoadGroupCallParticipants() { - } - - /** - * Creates a function, which loads more participants of a group call; not supported in live stories. The loaded participants will be received through updates. Use the field groupCall.loadedAllParticipants to check whether all participants have already been loaded. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. The group call must be previously received through getGroupCall and must be joined or being joined. - * @param limit The maximum number of participants to load; up to 100. - */ - public LoadGroupCallParticipants(int groupCallId, int limit) { - this.groupCallId = groupCallId; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 938720974; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Loads quick reply messages that can be sent by a given quick reply shortcut. The loaded messages will be sent through updateQuickReplyShortcutMessages. - * - *

Returns {@link Ok Ok}

- */ - public static class LoadQuickReplyShortcutMessages extends Function { - /** - * Unique identifier of the quick reply shortcut. - */ - public int shortcutId; - - /** - * Default constructor for a function, which loads quick reply messages that can be sent by a given quick reply shortcut. The loaded messages will be sent through updateQuickReplyShortcutMessages. - * - *

Returns {@link Ok Ok}

- */ - public LoadQuickReplyShortcutMessages() { - } - - /** - * Creates a function, which loads quick reply messages that can be sent by a given quick reply shortcut. The loaded messages will be sent through updateQuickReplyShortcutMessages. - * - *

Returns {@link Ok Ok}

- * - * @param shortcutId Unique identifier of the quick reply shortcut. - */ - public LoadQuickReplyShortcutMessages(int shortcutId) { - this.shortcutId = shortcutId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -46092588; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Loads quick reply shortcuts created by the current user. The loaded data will be sent through updateQuickReplyShortcut and updateQuickReplyShortcuts. - * - *

Returns {@link Ok Ok}

- */ - public static class LoadQuickReplyShortcuts extends Function { - - /** - * Default constructor for a function, which loads quick reply shortcuts created by the current user. The loaded data will be sent through updateQuickReplyShortcut and updateQuickReplyShortcuts. - * - *

Returns {@link Ok Ok}

- */ - public LoadQuickReplyShortcuts() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1016614243; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Loads more Saved Messages topics. The loaded topics will be sent through updateSavedMessagesTopic. Topics are sorted by their topic.order in descending order. Returns a 404 error if all topics have been loaded. - * - *

Returns {@link Ok Ok}

- */ - public static class LoadSavedMessagesTopics extends Function { - /** - * The maximum number of topics to be loaded. For optimal performance, the number of loaded topics is chosen by TDLib and can be smaller than the specified limit, even if the end of the list is not reached. - */ - public int limit; - - /** - * Default constructor for a function, which loads more Saved Messages topics. The loaded topics will be sent through updateSavedMessagesTopic. Topics are sorted by their topic.order in descending order. Returns a 404 error if all topics have been loaded. - * - *

Returns {@link Ok Ok}

- */ - public LoadSavedMessagesTopics() { - } - - /** - * Creates a function, which loads more Saved Messages topics. The loaded topics will be sent through updateSavedMessagesTopic. Topics are sorted by their topic.order in descending order. Returns a 404 error if all topics have been loaded. - * - *

Returns {@link Ok Ok}

- * - * @param limit The maximum number of topics to be loaded. For optimal performance, the number of loaded topics is chosen by TDLib and can be smaller than the specified limit, even if the end of the list is not reached. - */ - public LoadSavedMessagesTopics(int limit) { - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 289855160; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Closes the TDLib instance after a proper logout. Requires an available network connection. All local data will be destroyed. After the logout completes, updateAuthorizationState with authorizationStateClosed will be sent. - * - *

Returns {@link Ok Ok}

- */ - public static class LogOut extends Function { - - /** - * Default constructor for a function, which closes the TDLib instance after a proper logout. Requires an available network connection. All local data will be destroyed. After the logout completes, updateAuthorizationState with authorizationStateClosed will be sent. - * - *

Returns {@link Ok Ok}

- */ - public LogOut() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1581923301; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds tasks of a checklist in a message as done or not done. - * - *

Returns {@link Ok Ok}

- */ - public static class MarkChecklistTasksAsDone extends Function { - /** - * Identifier of the chat with the message. - */ - public long chatId; - /** - * Identifier of the message containing the checklist. Use messageProperties.canMarkTasksAsDone to check whether the tasks can be marked as done or not done. - */ - public long messageId; - /** - * Identifiers of tasks that were marked as done. - */ - public int[] markedAsDoneTaskIds; - /** - * Identifiers of tasks that were marked as not done. - */ - public int[] markedAsNotDoneTaskIds; - - /** - * Default constructor for a function, which adds tasks of a checklist in a message as done or not done. - * - *

Returns {@link Ok Ok}

- */ - public MarkChecklistTasksAsDone() { - } - - /** - * Creates a function, which adds tasks of a checklist in a message as done or not done. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat with the message. - * @param messageId Identifier of the message containing the checklist. Use messageProperties.canMarkTasksAsDone to check whether the tasks can be marked as done or not done. - * @param markedAsDoneTaskIds Identifiers of tasks that were marked as done. - * @param markedAsNotDoneTaskIds Identifiers of tasks that were marked as not done. - */ - public MarkChecklistTasksAsDone(long chatId, long messageId, int[] markedAsDoneTaskIds, int[] markedAsNotDoneTaskIds) { - this.chatId = chatId; - this.messageId = messageId; - this.markedAsDoneTaskIds = markedAsDoneTaskIds; - this.markedAsNotDoneTaskIds = markedAsNotDoneTaskIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 386950739; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that a bot was opened from the list of similar bots. - * - *

Returns {@link Ok Ok}

- */ - public static class OpenBotSimilarBot extends Function { - /** - * Identifier of the original bot, which similar bots were requested. - */ - public long botUserId; - /** - * Identifier of the opened bot. - */ - public long openedBotUserId; - - /** - * Default constructor for a function, which informs TDLib that a bot was opened from the list of similar bots. - * - *

Returns {@link Ok Ok}

- */ - public OpenBotSimilarBot() { - } - - /** - * Creates a function, which informs TDLib that a bot was opened from the list of similar bots. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId Identifier of the original bot, which similar bots were requested. - * @param openedBotUserId Identifier of the opened bot. - */ - public OpenBotSimilarBot(long botUserId, long openedBotUserId) { - this.botUserId = botUserId; - this.openedBotUserId = openedBotUserId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -369688872; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that the chat is opened by the user. Many useful activities depend on the chat being opened or closed (e.g., in supergroups and channels all updates are received only for opened chats). - * - *

Returns {@link Ok Ok}

- */ - public static class OpenChat extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which informs TDLib that the chat is opened by the user. Many useful activities depend on the chat being opened or closed (e.g., in supergroups and channels all updates are received only for opened chats). - * - *

Returns {@link Ok Ok}

- */ - public OpenChat() { - } - - /** - * Creates a function, which informs TDLib that the chat is opened by the user. Many useful activities depend on the chat being opened or closed (e.g., in supergroups and channels all updates are received only for opened chats). - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - */ - public OpenChat(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -323371509; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that a chat was opened from the list of similar chats. The method is independent of openChat and closeChat methods. - * - *

Returns {@link Ok Ok}

- */ - public static class OpenChatSimilarChat extends Function { - /** - * Identifier of the original chat, which similar chats were requested. - */ - public long chatId; - /** - * Identifier of the opened chat. - */ - public long openedChatId; - - /** - * Default constructor for a function, which informs TDLib that a chat was opened from the list of similar chats. The method is independent of openChat and closeChat methods. - * - *

Returns {@link Ok Ok}

- */ - public OpenChatSimilarChat() { - } - - /** - * Creates a function, which informs TDLib that a chat was opened from the list of similar chats. The method is independent of openChat and closeChat methods. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the original chat, which similar chats were requested. - * @param openedChatId Identifier of the opened chat. - */ - public OpenChatSimilarChat(long chatId, long openedChatId) { - this.chatId = chatId; - this.openedChatId = openedChatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1884883949; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that a gift auction was opened by the user. - * - *

Returns {@link Ok Ok}

- */ - public static class OpenGiftAuction extends Function { - /** - * Identifier of the gift, which auction was opened. - */ - public long giftId; - - /** - * Default constructor for a function, which informs TDLib that a gift auction was opened by the user. - * - *

Returns {@link Ok Ok}

- */ - public OpenGiftAuction() { - } - - /** - * Creates a function, which informs TDLib that a gift auction was opened by the user. - * - *

Returns {@link Ok Ok}

- * - * @param giftId Identifier of the gift, which auction was opened. - */ - public OpenGiftAuction(long giftId) { - this.giftId = giftId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -694137370; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that the message content has been opened (e.g., the user has opened a photo, video, document, location or venue, or has listened to an audio file or voice note message). An updateMessageContentOpened update will be generated if something has changed. - * - *

Returns {@link Ok Ok}

- */ - public static class OpenMessageContent extends Function { - /** - * Chat identifier of the message. - */ - public long chatId; - /** - * Identifier of the message with the opened content. - */ - public long messageId; - - /** - * Default constructor for a function, which informs TDLib that the message content has been opened (e.g., the user has opened a photo, video, document, location or venue, or has listened to an audio file or voice note message). An updateMessageContentOpened update will be generated if something has changed. - * - *

Returns {@link Ok Ok}

- */ - public OpenMessageContent() { - } - - /** - * Creates a function, which informs TDLib that the message content has been opened (e.g., the user has opened a photo, video, document, location or venue, or has listened to an audio file or voice note message). An updateMessageContentOpened update will be generated if something has changed. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier of the message. - * @param messageId Identifier of the message with the opened content. - */ - public OpenMessageContent(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -739088005; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that the user opened a sponsored chat. - * - *

Returns {@link Ok Ok}

- */ - public static class OpenSponsoredChat extends Function { - /** - * Unique identifier of the sponsored chat. - */ - public long sponsoredChatUniqueId; - - /** - * Default constructor for a function, which informs TDLib that the user opened a sponsored chat. - * - *

Returns {@link Ok Ok}

- */ - public OpenSponsoredChat() { - } - - /** - * Creates a function, which informs TDLib that the user opened a sponsored chat. - * - *

Returns {@link Ok Ok}

- * - * @param sponsoredChatUniqueId Unique identifier of the sponsored chat. - */ - public OpenSponsoredChat(long sponsoredChatUniqueId) { - this.sponsoredChatUniqueId = sponsoredChatUniqueId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 865985573; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that a story is opened and is being viewed by the user. - * - *

Returns {@link Ok Ok}

- */ - public static class OpenStory extends Function { - /** - * The identifier of the chat that posted the opened story. - */ - public long storyPosterChatId; - /** - * The identifier of the story. - */ - public int storyId; - - /** - * Default constructor for a function, which informs TDLib that a story is opened and is being viewed by the user. - * - *

Returns {@link Ok Ok}

- */ - public OpenStory() { - } - - /** - * Creates a function, which informs TDLib that a story is opened and is being viewed by the user. - * - *

Returns {@link Ok Ok}

- * - * @param storyPosterChatId The identifier of the chat that posted the opened story. - * @param storyId The identifier of the story. - */ - public OpenStory(long storyPosterChatId, int storyId) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -696723005; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that a Web App is being opened from the attachment menu, a botMenuButton button, an internalLinkTypeAttachmentMenuBot link, or an inlineKeyboardButtonTypeWebApp button. For each bot, a confirmation alert about data sent to the bot must be shown once. - * - *

Returns {@link WebAppInfo WebAppInfo}

- */ - public static class OpenWebApp extends Function { - /** - * Identifier of the chat in which the Web App is opened. The Web App can't be opened in secret chats. - */ - public long chatId; - /** - * Identifier of the bot, providing the Web App. If the bot is restricted for the current user, then show an error instead of calling the method. - */ - public long botUserId; - /** - * The URL from an inlineKeyboardButtonTypeWebApp button, a botMenuButton button, an internalLinkTypeAttachmentMenuBot link, or an empty string otherwise. - */ - public String url; - /** - * Topic in which the message will be sent; pass null if none. - */ - public MessageTopic topicId; - /** - * Information about the message or story to be replied in the message sent by the Web App; pass null if none. - */ - public InputMessageReplyTo replyTo; - /** - * Parameters to use to open the Web App. - */ - public WebAppOpenParameters parameters; - - /** - * Default constructor for a function, which informs TDLib that a Web App is being opened from the attachment menu, a botMenuButton button, an internalLinkTypeAttachmentMenuBot link, or an inlineKeyboardButtonTypeWebApp button. For each bot, a confirmation alert about data sent to the bot must be shown once. - * - *

Returns {@link WebAppInfo WebAppInfo}

- */ - public OpenWebApp() { - } - - /** - * Creates a function, which informs TDLib that a Web App is being opened from the attachment menu, a botMenuButton button, an internalLinkTypeAttachmentMenuBot link, or an inlineKeyboardButtonTypeWebApp button. For each bot, a confirmation alert about data sent to the bot must be shown once. - * - *

Returns {@link WebAppInfo WebAppInfo}

- * - * @param chatId Identifier of the chat in which the Web App is opened. The Web App can't be opened in secret chats. - * @param botUserId Identifier of the bot, providing the Web App. If the bot is restricted for the current user, then show an error instead of calling the method. - * @param url The URL from an inlineKeyboardButtonTypeWebApp button, a botMenuButton button, an internalLinkTypeAttachmentMenuBot link, or an empty string otherwise. - * @param topicId Topic in which the message will be sent; pass null if none. - * @param replyTo Information about the message or story to be replied in the message sent by the Web App; pass null if none. - * @param parameters Parameters to use to open the Web App. - */ - public OpenWebApp(long chatId, long botUserId, String url, MessageTopic topicId, InputMessageReplyTo replyTo, WebAppOpenParameters parameters) { - this.chatId = chatId; - this.botUserId = botUserId; - this.url = url; - this.topicId = topicId; - this.replyTo = replyTo; - this.parameters = parameters; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -950685122; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Optimizes storage usage, i.e. deletes some files and returns new storage usage statistics. Secret thumbnails can't be deleted. - * - *

Returns {@link StorageStatistics StorageStatistics}

- */ - public static class OptimizeStorage extends Function { - /** - * Limit on the total size of files after deletion, in bytes. Pass -1 to use the default limit. - */ - public long size; - /** - * Limit on the time that has passed since the last time a file was accessed (or creation time for some filesystems). Pass -1 to use the default limit. - */ - public int ttl; - /** - * Limit on the total number of files after deletion. Pass -1 to use the default limit. - */ - public int count; - /** - * The amount of time after the creation of a file during which it can't be deleted, in seconds. Pass -1 to use the default value. - */ - public int immunityDelay; - /** - * If non-empty, only files with the given types are considered. By default, all types except thumbnails, profile photos, stickers and wallpapers are deleted. - */ - public FileType[] fileTypes; - /** - * If non-empty, only files from the given chats are considered. Use 0 as chat identifier to delete files not belonging to any chat (e.g., profile photos). - */ - public long[] chatIds; - /** - * If non-empty, files from the given chats are excluded. Use 0 as chat identifier to exclude all files not belonging to any chat (e.g., profile photos). - */ - public long[] excludeChatIds; - /** - * Pass true if statistics about the files that were deleted must be returned instead of the whole storage usage statistics. Affects only returned statistics. - */ - public boolean returnDeletedFileStatistics; - /** - * Same as in getStorageStatistics. Affects only returned statistics. - */ - public int chatLimit; - - /** - * Default constructor for a function, which optimizes storage usage, i.e. deletes some files and returns new storage usage statistics. Secret thumbnails can't be deleted. - * - *

Returns {@link StorageStatistics StorageStatistics}

- */ - public OptimizeStorage() { - } - - /** - * Creates a function, which optimizes storage usage, i.e. deletes some files and returns new storage usage statistics. Secret thumbnails can't be deleted. - * - *

Returns {@link StorageStatistics StorageStatistics}

- * - * @param size Limit on the total size of files after deletion, in bytes. Pass -1 to use the default limit. - * @param ttl Limit on the time that has passed since the last time a file was accessed (or creation time for some filesystems). Pass -1 to use the default limit. - * @param count Limit on the total number of files after deletion. Pass -1 to use the default limit. - * @param immunityDelay The amount of time after the creation of a file during which it can't be deleted, in seconds. Pass -1 to use the default value. - * @param fileTypes If non-empty, only files with the given types are considered. By default, all types except thumbnails, profile photos, stickers and wallpapers are deleted. - * @param chatIds If non-empty, only files from the given chats are considered. Use 0 as chat identifier to delete files not belonging to any chat (e.g., profile photos). - * @param excludeChatIds If non-empty, files from the given chats are excluded. Use 0 as chat identifier to exclude all files not belonging to any chat (e.g., profile photos). - * @param returnDeletedFileStatistics Pass true if statistics about the files that were deleted must be returned instead of the whole storage usage statistics. Affects only returned statistics. - * @param chatLimit Same as in getStorageStatistics. Affects only returned statistics. - */ - public OptimizeStorage(long size, int ttl, int count, int immunityDelay, FileType[] fileTypes, long[] chatIds, long[] excludeChatIds, boolean returnDeletedFileStatistics, int chatLimit) { - this.size = size; - this.ttl = ttl; - this.count = count; - this.immunityDelay = immunityDelay; - this.fileTypes = fileTypes; - this.chatIds = chatIds; - this.excludeChatIds = excludeChatIds; - this.returnDeletedFileStatistics = returnDeletedFileStatistics; - this.chatLimit = chatLimit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 853186759; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Parses Markdown entities in a human-friendly format, ignoring markup errors. Can be called synchronously. - * - *

Returns {@link FormattedText FormattedText}

- */ - public static class ParseMarkdown extends Function { - /** - * The text to parse. For example, "__italic__ ~~strikethrough~~ ||spoiler|| **bold** `code` ```pre``` __[italic__ textUrl](telegram.org) __italic**bold italic__bold**". - */ - public FormattedText text; - - /** - * Default constructor for a function, which parses Markdown entities in a human-friendly format, ignoring markup errors. Can be called synchronously. - * - *

Returns {@link FormattedText FormattedText}

- */ - public ParseMarkdown() { - } - - /** - * Creates a function, which parses Markdown entities in a human-friendly format, ignoring markup errors. Can be called synchronously. - * - *

Returns {@link FormattedText FormattedText}

- * - * @param text The text to parse. For example, "__italic__ ~~strikethrough~~ ||spoiler|| **bold** `code` ```pre``` __[italic__ textUrl](telegram.org) __italic**bold italic__bold**". - */ - public ParseMarkdown(FormattedText text) { - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 756366063; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Parses Bold, Italic, Underline, Strikethrough, Spoiler, CustomEmoji, BlockQuote, ExpandableBlockQuote, Code, Pre, PreCode, TextUrl and MentionName entities from a marked-up text. Can be called synchronously. - * - *

Returns {@link FormattedText FormattedText}

- */ - public static class ParseTextEntities extends Function { - /** - * The text to parse. - */ - public String text; - /** - * Text parse mode. - */ - public TextParseMode parseMode; - - /** - * Default constructor for a function, which parses Bold, Italic, Underline, Strikethrough, Spoiler, CustomEmoji, BlockQuote, ExpandableBlockQuote, Code, Pre, PreCode, TextUrl and MentionName entities from a marked-up text. Can be called synchronously. - * - *

Returns {@link FormattedText FormattedText}

- */ - public ParseTextEntities() { - } - - /** - * Creates a function, which parses Bold, Italic, Underline, Strikethrough, Spoiler, CustomEmoji, BlockQuote, ExpandableBlockQuote, Code, Pre, PreCode, TextUrl and MentionName entities from a marked-up text. Can be called synchronously. - * - *

Returns {@link FormattedText FormattedText}

- * - * @param text The text to parse. - * @param parseMode Text parse mode. - */ - public ParseTextEntities(String text, TextParseMode parseMode) { - this.text = text; - this.parseMode = parseMode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1709194593; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Pins a message in a chat. A message can be pinned only if messageProperties.canBePinned. - * - *

Returns {@link Ok Ok}

- */ - public static class PinChatMessage extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * Identifier of the new pinned message. - */ - public long messageId; - /** - * Pass true to disable notification about the pinned message. Notifications are always disabled in channels and private chats. - */ - public boolean disableNotification; - /** - * Pass true to pin the message only for self; private chats only. - */ - public boolean onlyForSelf; - - /** - * Default constructor for a function, which pins a message in a chat. A message can be pinned only if messageProperties.canBePinned. - * - *

Returns {@link Ok Ok}

- */ - public PinChatMessage() { - } - - /** - * Creates a function, which pins a message in a chat. A message can be pinned only if messageProperties.canBePinned. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat. - * @param messageId Identifier of the new pinned message. - * @param disableNotification Pass true to disable notification about the pinned message. Notifications are always disabled in channels and private chats. - * @param onlyForSelf Pass true to pin the message only for self; private chats only. - */ - public PinChatMessage(long chatId, long messageId, boolean disableNotification, boolean onlyForSelf) { - this.chatId = chatId; - this.messageId = messageId; - this.disableNotification = disableNotification; - this.onlyForSelf = onlyForSelf; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2034719663; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Computes time needed to receive a response from a Telegram server through a proxy. Can be called before authorization. - * - *

Returns {@link Seconds Seconds}

- */ - public static class PingProxy extends Function { - /** - * The proxy to test; pass null to ping a Telegram server without a proxy. - */ - public Proxy proxy; - - /** - * Default constructor for a function, which computes time needed to receive a response from a Telegram server through a proxy. Can be called before authorization. - * - *

Returns {@link Seconds Seconds}

- */ - public PingProxy() { - } - - /** - * Creates a function, which computes time needed to receive a response from a Telegram server through a proxy. Can be called before authorization. - * - *

Returns {@link Seconds Seconds}

- * - * @param proxy The proxy to test; pass null to ping a Telegram server without a proxy. - */ - public PingProxy(Proxy proxy) { - this.proxy = proxy; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2144501959; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Places a bid on an auction gift. - * - *

Returns {@link Ok Ok}

- */ - public static class PlaceGiftAuctionBid extends Function { - /** - * Identifier of the gift to place the bid on. - */ - public long giftId; - /** - * The number of Telegram Stars to place in the bid. - */ - public long starCount; - /** - * Identifier of the user who will receive the gift. - */ - public long userId; - /** - * Text to show along with the gift; 0-getOption("gift_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed. Must be empty if the receiver enabled paid messages. - */ - public FormattedText text; - /** - * Pass true to show gift text and sender only to the gift receiver; otherwise, everyone will be able to see them. - */ - public boolean isPrivate; - - /** - * Default constructor for a function, which places a bid on an auction gift. - * - *

Returns {@link Ok Ok}

- */ - public PlaceGiftAuctionBid() { - } - - /** - * Creates a function, which places a bid on an auction gift. - * - *

Returns {@link Ok Ok}

- * - * @param giftId Identifier of the gift to place the bid on. - * @param starCount The number of Telegram Stars to place in the bid. - * @param userId Identifier of the user who will receive the gift. - * @param text Text to show along with the gift; 0-getOption("gift_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed. Must be empty if the receiver enabled paid messages. - * @param isPrivate Pass true to show gift text and sender only to the gift receiver; otherwise, everyone will be able to see them. - */ - public PlaceGiftAuctionBid(long giftId, long starCount, long userId, FormattedText text, boolean isPrivate) { - this.giftId = giftId; - this.starCount = starCount; - this.userId = userId; - this.text = text; - this.isPrivate = isPrivate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1437176980; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Posts a new story on behalf of a chat; requires canPostStories administrator right for supergroup and channel chats. Returns a temporary story. - * - *

Returns {@link Story Story}

- */ - public static class PostStory extends Function { - /** - * Identifier of the chat that will post the story. Pass Saved Messages chat identifier when posting a story on behalf of the current user. - */ - public long chatId; - /** - * Content of the story. - */ - public InputStoryContent content; - /** - * Clickable rectangle areas to be shown on the story media; pass null if none. - */ - public InputStoryAreas areas; - /** - * Story caption; pass null to use an empty caption; 0-getOption("story_caption_length_max") characters; can have entities only if getOption("can_use_text_entities_in_story_caption"). - */ - public FormattedText caption; - /** - * The privacy settings for the story; ignored for stories posted on behalf of supergroup and channel chats. - */ - public StoryPrivacySettings privacySettings; - /** - * Identifiers of story albums to which the story will be added upon posting. An album can have up to getOption("story_album_size_max") stories. - */ - public int[] albumIds; - /** - * Period after which the story is moved to archive, in seconds; must be one of 6 * 3600, 12 * 3600, 86400, or 2 * 86400 for Telegram Premium users, and 86400 otherwise. - */ - public int activePeriod; - /** - * Full identifier of the original story, which content was used to create the story; pass null if the story isn't repost of another story. - */ - public StoryFullId fromStoryFullId; - /** - * Pass true to keep the story accessible after expiration. - */ - public boolean isPostedToChatPage; - /** - * Pass true if the content of the story must be protected from forwarding and screenshotting. - */ - public boolean protectContent; - - /** - * Default constructor for a function, which posts a new story on behalf of a chat; requires canPostStories administrator right for supergroup and channel chats. Returns a temporary story. - * - *

Returns {@link Story Story}

- */ - public PostStory() { - } - - /** - * Creates a function, which posts a new story on behalf of a chat; requires canPostStories administrator right for supergroup and channel chats. Returns a temporary story. - * - *

Returns {@link Story Story}

- * - * @param chatId Identifier of the chat that will post the story. Pass Saved Messages chat identifier when posting a story on behalf of the current user. - * @param content Content of the story. - * @param areas Clickable rectangle areas to be shown on the story media; pass null if none. - * @param caption Story caption; pass null to use an empty caption; 0-getOption("story_caption_length_max") characters; can have entities only if getOption("can_use_text_entities_in_story_caption"). - * @param privacySettings The privacy settings for the story; ignored for stories posted on behalf of supergroup and channel chats. - * @param albumIds Identifiers of story albums to which the story will be added upon posting. An album can have up to getOption("story_album_size_max") stories. - * @param activePeriod Period after which the story is moved to archive, in seconds; must be one of 6 * 3600, 12 * 3600, 86400, or 2 * 86400 for Telegram Premium users, and 86400 otherwise. - * @param fromStoryFullId Full identifier of the original story, which content was used to create the story; pass null if the story isn't repost of another story. - * @param isPostedToChatPage Pass true to keep the story accessible after expiration. - * @param protectContent Pass true if the content of the story must be protected from forwarding and screenshotting. - */ - public PostStory(long chatId, InputStoryContent content, InputStoryAreas areas, FormattedText caption, StoryPrivacySettings privacySettings, int[] albumIds, int activePeriod, StoryFullId fromStoryFullId, boolean isPostedToChatPage, boolean protectContent) { - this.chatId = chatId; - this.content = content; - this.areas = areas; - this.caption = caption; - this.privacySettings = privacySettings; - this.albumIds = albumIds; - this.activePeriod = activePeriod; - this.fromStoryFullId = fromStoryFullId; - this.isPostedToChatPage = isPostedToChatPage; - this.protectContent = protectContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1725643742; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Preliminarily uploads a file to the cloud before sending it in a message, which can be useful for uploading of being recorded voice and video notes. In all other cases there is no need to preliminary upload a file. Updates updateFile will be used to notify about upload progress. The upload will not be completed until the file is sent in a message. - * - *

Returns {@link File File}

- */ - public static class PreliminaryUploadFile extends Function { - /** - * File to upload. - */ - public InputFile file; - /** - * File type; pass null if unknown. - */ - public FileType fileType; - /** - * Priority of the upload (1-32). The higher the priority, the earlier the file will be uploaded. If the priorities of two files are equal, then the first one for which preliminaryUploadFile was called will be uploaded first. - */ - public int priority; - - /** - * Default constructor for a function, which preliminarily uploads a file to the cloud before sending it in a message, which can be useful for uploading of being recorded voice and video notes. In all other cases there is no need to preliminary upload a file. Updates updateFile will be used to notify about upload progress. The upload will not be completed until the file is sent in a message. - * - *

Returns {@link File File}

- */ - public PreliminaryUploadFile() { - } - - /** - * Creates a function, which preliminarily uploads a file to the cloud before sending it in a message, which can be useful for uploading of being recorded voice and video notes. In all other cases there is no need to preliminary upload a file. Updates updateFile will be used to notify about upload progress. The upload will not be completed until the file is sent in a message. - * - *

Returns {@link File File}

- * - * @param file File to upload. - * @param fileType File type; pass null if unknown. - * @param priority Priority of the upload (1-32). The higher the priority, the earlier the file will be uploaded. If the priorities of two files are equal, then the first one for which preliminaryUploadFile was called will be uploaded first. - */ - public PreliminaryUploadFile(InputFile file, FileType fileType, int priority) { - this.file = file; - this.fileType = fileType; - this.priority = priority; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1894239129; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Process new chats added to a shareable chat folder by its owner. - * - *

Returns {@link Ok Ok}

- */ - public static class ProcessChatFolderNewChats extends Function { - /** - * Chat folder identifier. - */ - public int chatFolderId; - /** - * Identifiers of the new chats, which are added to the chat folder. The chats are automatically joined if they aren't joined yet. - */ - public long[] addedChatIds; - - /** - * Default constructor for a function, which process new chats added to a shareable chat folder by its owner. - * - *

Returns {@link Ok Ok}

- */ - public ProcessChatFolderNewChats() { - } - - /** - * Creates a function, which process new chats added to a shareable chat folder by its owner. - * - *

Returns {@link Ok Ok}

- * - * @param chatFolderId Chat folder identifier. - * @param addedChatIds Identifiers of the new chats, which are added to the chat folder. The chats are automatically joined if they aren't joined yet. - */ - public ProcessChatFolderNewChats(int chatFolderId, long[] addedChatIds) { - this.chatFolderId = chatFolderId; - this.addedChatIds = addedChatIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1498280672; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Processes request to disable hasProtectedContent in a chat. - * - *

Returns {@link Ok Ok}

- */ - public static class ProcessChatHasProtectedContentDisableRequest extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the message with the request. The message must be incoming and has content of the type messageChatHasProtectedContentDisableRequested. - */ - public long requestMessageId; - /** - * Pass true to approve the request; pass false to reject the request. - */ - public boolean approve; - - /** - * Default constructor for a function, which processes request to disable hasProtectedContent in a chat. - * - *

Returns {@link Ok Ok}

- */ - public ProcessChatHasProtectedContentDisableRequest() { - } - - /** - * Creates a function, which processes request to disable hasProtectedContent in a chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param requestMessageId Identifier of the message with the request. The message must be incoming and has content of the type messageChatHasProtectedContentDisableRequested. - * @param approve Pass true to approve the request; pass false to reject the request. - */ - public ProcessChatHasProtectedContentDisableRequest(long chatId, long requestMessageId, boolean approve) { - this.chatId = chatId; - this.requestMessageId = requestMessageId; - this.approve = approve; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2078059411; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Handles a pending join request in a chat. - * - *

Returns {@link Ok Ok}

- */ - public static class ProcessChatJoinRequest extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the user who sent the request. - */ - public long userId; - /** - * Pass true to approve the request; pass false to decline it. - */ - public boolean approve; - - /** - * Default constructor for a function, which handles a pending join request in a chat. - * - *

Returns {@link Ok Ok}

- */ - public ProcessChatJoinRequest() { - } - - /** - * Creates a function, which handles a pending join request in a chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param userId Identifier of the user who sent the request. - * @param approve Pass true to approve the request; pass false to decline it. - */ - public ProcessChatJoinRequest(long chatId, long userId, boolean approve) { - this.chatId = chatId; - this.userId = userId; - this.approve = approve; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1004876963; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Handles all pending join requests for a given link in a chat. - * - *

Returns {@link Ok Ok}

- */ - public static class ProcessChatJoinRequests extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Invite link for which to process join requests. If empty, all join requests will be processed. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. - */ - public String inviteLink; - /** - * Pass true to approve all requests; pass false to decline them. - */ - public boolean approve; - - /** - * Default constructor for a function, which handles all pending join requests for a given link in a chat. - * - *

Returns {@link Ok Ok}

- */ - public ProcessChatJoinRequests() { - } - - /** - * Creates a function, which handles all pending join requests for a given link in a chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param inviteLink Invite link for which to process join requests. If empty, all join requests will be processed. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. - * @param approve Pass true to approve all requests; pass false to decline them. - */ - public ProcessChatJoinRequests(long chatId, String inviteLink, boolean approve) { - this.chatId = chatId; - this.inviteLink = inviteLink; - this.approve = approve; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1048722894; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Handles a pending gift purchase offer. - * - *

Returns {@link Ok Ok}

- */ - public static class ProcessGiftPurchaseOffer extends Function { - /** - * Identifier of the message with the gift purchase offer. - */ - public long messageId; - /** - * Pass true to accept the request; pass false to reject it. - */ - public boolean accept; - - /** - * Default constructor for a function, which handles a pending gift purchase offer. - * - *

Returns {@link Ok Ok}

- */ - public ProcessGiftPurchaseOffer() { - } - - /** - * Creates a function, which handles a pending gift purchase offer. - * - *

Returns {@link Ok Ok}

- * - * @param messageId Identifier of the message with the gift purchase offer. - * @param accept Pass true to accept the request; pass false to reject it. - */ - public ProcessGiftPurchaseOffer(long messageId, boolean accept) { - this.messageId = messageId; - this.accept = accept; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1177407462; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Handles a push notification. Returns error with code 406 if the push notification is not supported and connection to the server is required to fetch new data. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class ProcessPushNotification extends Function { - /** - * JSON-encoded push notification payload with all fields sent by the server, and "google.sentTime" and "google.notification.sound" fields added. - */ - public String payload; - - /** - * Default constructor for a function, which handles a push notification. Returns error with code 406 if the push notification is not supported and connection to the server is required to fetch new data. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public ProcessPushNotification() { - } - - /** - * Creates a function, which handles a push notification. Returns error with code 406 if the push notification is not supported and connection to the server is required to fetch new data. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- * - * @param payload JSON-encoded push notification payload with all fields sent by the server, and "google.sentTime" and "google.notification.sound" fields added. - */ - public ProcessPushNotification(String payload) { - this.payload = payload; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 786679952; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Rates recognized speech in a video note or a voice note message. - * - *

Returns {@link Ok Ok}

- */ - public static class RateSpeechRecognition extends Function { - /** - * Identifier of the chat to which the message belongs. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * Pass true if the speech recognition is good. - */ - public boolean isGood; - - /** - * Default constructor for a function, which rates recognized speech in a video note or a voice note message. - * - *

Returns {@link Ok Ok}

- */ - public RateSpeechRecognition() { - } - - /** - * Creates a function, which rates recognized speech in a video note or a voice note message. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat to which the message belongs. - * @param messageId Identifier of the message. - * @param isGood Pass true if the speech recognition is good. - */ - public RateSpeechRecognition(long chatId, long messageId, boolean isGood) { - this.chatId = chatId; - this.messageId = messageId; - this.isGood = isGood; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -287521867; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Marks all mentions in a chat as read. - * - *

Returns {@link Ok Ok}

- */ - public static class ReadAllChatMentions extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which marks all mentions in a chat as read. - * - *

Returns {@link Ok Ok}

- */ - public ReadAllChatMentions() { - } - - /** - * Creates a function, which marks all mentions in a chat as read. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - */ - public ReadAllChatMentions(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1357558453; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Marks all reactions in a chat as read. - * - *

Returns {@link Ok Ok}

- */ - public static class ReadAllChatReactions extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which marks all reactions in a chat as read. - * - *

Returns {@link Ok Ok}

- */ - public ReadAllChatReactions() { - } - - /** - * Creates a function, which marks all reactions in a chat as read. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - */ - public ReadAllChatReactions(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1421973357; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes all unread reactions in the topic in a channel direct messages chat administered by the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class ReadAllDirectMessagesChatTopicReactions extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * Topic identifier. - */ - public long topicId; - - /** - * Default constructor for a function, which removes all unread reactions in the topic in a channel direct messages chat administered by the current user. - * - *

Returns {@link Ok Ok}

- */ - public ReadAllDirectMessagesChatTopicReactions() { - } - - /** - * Creates a function, which removes all unread reactions in the topic in a channel direct messages chat administered by the current user. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat. - * @param topicId Topic identifier. - */ - public ReadAllDirectMessagesChatTopicReactions(long chatId, long topicId) { - this.chatId = chatId; - this.topicId = topicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1154665542; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Marks all mentions in a topic in a forum supergroup chat as read. - * - *

Returns {@link Ok Ok}

- */ - public static class ReadAllForumTopicMentions extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Forum topic identifier in which mentions are marked as read. - */ - public int forumTopicId; - - /** - * Default constructor for a function, which marks all mentions in a topic in a forum supergroup chat as read. - * - *

Returns {@link Ok Ok}

- */ - public ReadAllForumTopicMentions() { - } - - /** - * Creates a function, which marks all mentions in a topic in a forum supergroup chat as read. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param forumTopicId Forum topic identifier in which mentions are marked as read. - */ - public ReadAllForumTopicMentions(long chatId, int forumTopicId) { - this.chatId = chatId; - this.forumTopicId = forumTopicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -996864148; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Marks all reactions in a topic in a forum supergroup chat or a chat with a bot with topics as read. - * - *

Returns {@link Ok Ok}

- */ - public static class ReadAllForumTopicReactions extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Forum topic identifier in which reactions are marked as read. - */ - public int forumTopicId; - - /** - * Default constructor for a function, which marks all reactions in a topic in a forum supergroup chat or a chat with a bot with topics as read. - * - *

Returns {@link Ok Ok}

- */ - public ReadAllForumTopicReactions() { - } - - /** - * Creates a function, which marks all reactions in a topic in a forum supergroup chat or a chat with a bot with topics as read. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param forumTopicId Forum topic identifier in which reactions are marked as read. - */ - public ReadAllForumTopicReactions(long chatId, int forumTopicId) { - this.chatId = chatId; - this.forumTopicId = forumTopicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1986498949; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Reads a message on behalf of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class ReadBusinessMessage extends Function { - /** - * Unique identifier of business connection through which the message was received. - */ - public String businessConnectionId; - /** - * The chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - - /** - * Default constructor for a function, which reads a message on behalf of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public ReadBusinessMessage() { - } - - /** - * Creates a function, which reads a message on behalf of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param businessConnectionId Unique identifier of business connection through which the message was received. - * @param chatId The chat the message belongs to. - * @param messageId Identifier of the message. - */ - public ReadBusinessMessage(String businessConnectionId, long chatId, long messageId) { - this.businessConnectionId = businessConnectionId; - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1723531538; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Traverses all chats in a chat list and marks all messages in the chats as read. - * - *

Returns {@link Ok Ok}

- */ - public static class ReadChatList extends Function { - /** - * Chat list in which to mark all chats as read. - */ - public ChatList chatList; - - /** - * Default constructor for a function, which traverses all chats in a chat list and marks all messages in the chats as read. - * - *

Returns {@link Ok Ok}

- */ - public ReadChatList() { - } - - /** - * Creates a function, which traverses all chats in a chat list and marks all messages in the chats as read. - * - *

Returns {@link Ok Ok}

- * - * @param chatList Chat list in which to mark all chats as read. - */ - public ReadChatList(ChatList chatList) { - this.chatList = chatList; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1117480790; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Reads a part of a file from the TDLib file cache and returns read bytes. This method is intended to be used only if the application has no direct access to TDLib's file system, because it is usually slower than a direct read from the file. - * - *

Returns {@link Data Data}

- */ - public static class ReadFilePart extends Function { - /** - * Identifier of the file. The file must be located in the TDLib file cache. - */ - public int fileId; - /** - * The offset from which to read the file. - */ - public long offset; - /** - * Number of bytes to read. An error will be returned if there are not enough bytes available in the file from the specified position. Pass 0 to read all available data from the specified position. - */ - public long count; - - /** - * Default constructor for a function, which reads a part of a file from the TDLib file cache and returns read bytes. This method is intended to be used only if the application has no direct access to TDLib's file system, because it is usually slower than a direct read from the file. - * - *

Returns {@link Data Data}

- */ - public ReadFilePart() { - } - - /** - * Creates a function, which reads a part of a file from the TDLib file cache and returns read bytes. This method is intended to be used only if the application has no direct access to TDLib's file system, because it is usually slower than a direct read from the file. - * - *

Returns {@link Data Data}

- * - * @param fileId Identifier of the file. The file must be located in the TDLib file cache. - * @param offset The offset from which to read the file. - * @param count Number of bytes to read. An error will be returned if there are not enough bytes available in the file from the specified position. Pass 0 to read all available data from the specified position. - */ - public ReadFilePart(int fileId, long offset, long count) { - this.fileId = fileId; - this.offset = offset; - this.count = count; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -174576822; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Readds quick reply messages which failed to add. Can be called only for messages for which messageSendingStateFailed.canRetry is true and after specified in messageSendingStateFailed.retryAfter time passed. If a message is readded, the corresponding failed to send message is deleted. Returns the sent messages in the same order as the message identifiers passed in messageIds. If a message can't be readded, null will be returned instead of the message. - * - *

Returns {@link QuickReplyMessages QuickReplyMessages}

- */ - public static class ReaddQuickReplyShortcutMessages extends Function { - /** - * Name of the target shortcut. - */ - public String shortcutName; - /** - * Identifiers of the quick reply messages to readd. Message identifiers must be in a strictly increasing order. - */ - public long[] messageIds; - - /** - * Default constructor for a function, which readds quick reply messages which failed to add. Can be called only for messages for which messageSendingStateFailed.canRetry is true and after specified in messageSendingStateFailed.retryAfter time passed. If a message is readded, the corresponding failed to send message is deleted. Returns the sent messages in the same order as the message identifiers passed in messageIds. If a message can't be readded, null will be returned instead of the message. - * - *

Returns {@link QuickReplyMessages QuickReplyMessages}

- */ - public ReaddQuickReplyShortcutMessages() { - } - - /** - * Creates a function, which readds quick reply messages which failed to add. Can be called only for messages for which messageSendingStateFailed.canRetry is true and after specified in messageSendingStateFailed.retryAfter time passed. If a message is readded, the corresponding failed to send message is deleted. Returns the sent messages in the same order as the message identifiers passed in messageIds. If a message can't be readded, null will be returned instead of the message. - * - *

Returns {@link QuickReplyMessages QuickReplyMessages}

- * - * @param shortcutName Name of the target shortcut. - * @param messageIds Identifiers of the quick reply messages to readd. Message identifiers must be in a strictly increasing order. - */ - public ReaddQuickReplyShortcutMessages(String shortcutName, long[] messageIds) { - this.shortcutName = shortcutName; - this.messageIds = messageIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 387399566; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Recognizes speech in a video note or a voice note message. - * - *

Returns {@link Ok Ok}

- */ - public static class RecognizeSpeech extends Function { - /** - * Identifier of the chat to which the message belongs. - */ - public long chatId; - /** - * Identifier of the message. Use messageProperties.canRecognizeSpeech to check whether the message is suitable. - */ - public long messageId; - - /** - * Default constructor for a function, which recognizes speech in a video note or a voice note message. - * - *

Returns {@link Ok Ok}

- */ - public RecognizeSpeech() { - } - - /** - * Creates a function, which recognizes speech in a video note or a voice note message. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat to which the message belongs. - * @param messageId Identifier of the message. Use messageProperties.canRecognizeSpeech to check whether the message is suitable. - */ - public RecognizeSpeech(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1741947577; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Recovers the 2-step verification password with a password recovery code sent to an email address that was previously set up. Works only when the current authorization state is authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- */ - public static class RecoverAuthenticationPassword extends Function { - /** - * Recovery code to check. - */ - public String recoveryCode; - /** - * New 2-step verification password of the user; may be empty to remove the password. - */ - public String newPassword; - /** - * New password hint; may be empty. - */ - public String newHint; - - /** - * Default constructor for a function, which recovers the 2-step verification password with a password recovery code sent to an email address that was previously set up. Works only when the current authorization state is authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- */ - public RecoverAuthenticationPassword() { - } - - /** - * Creates a function, which recovers the 2-step verification password with a password recovery code sent to an email address that was previously set up. Works only when the current authorization state is authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- * - * @param recoveryCode Recovery code to check. - * @param newPassword New 2-step verification password of the user; may be empty to remove the password. - * @param newHint New password hint; may be empty. - */ - public RecoverAuthenticationPassword(String recoveryCode, String newPassword, String newHint) { - this.recoveryCode = recoveryCode; - this.newPassword = newPassword; - this.newHint = newHint; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -131001053; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Recovers the 2-step verification password using a recovery code sent to an email address that was previously set up. - * - *

Returns {@link PasswordState PasswordState}

- */ - public static class RecoverPassword extends Function { - /** - * Recovery code to check. - */ - public String recoveryCode; - /** - * New 2-step verification password of the user; may be empty to remove the password. - */ - public String newPassword; - /** - * New password hint; may be empty. - */ - public String newHint; - - /** - * Default constructor for a function, which recovers the 2-step verification password using a recovery code sent to an email address that was previously set up. - * - *

Returns {@link PasswordState PasswordState}

- */ - public RecoverPassword() { - } - - /** - * Creates a function, which recovers the 2-step verification password using a recovery code sent to an email address that was previously set up. - * - *

Returns {@link PasswordState PasswordState}

- * - * @param recoveryCode Recovery code to check. - * @param newPassword New 2-step verification password of the user; may be empty to remove the password. - * @param newHint New password hint; may be empty. - */ - public RecoverPassword(String recoveryCode, String newPassword, String newHint) { - this.recoveryCode = recoveryCode; - this.newPassword = newPassword; - this.newHint = newHint; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1524262541; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Refunds a previously done payment in Telegram Stars; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class RefundStarPayment extends Function { - /** - * Identifier of the user who did the payment. - */ - public long userId; - /** - * Telegram payment identifier. - */ - public String telegramPaymentChargeId; - - /** - * Default constructor for a function, which refunds a previously done payment in Telegram Stars; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public RefundStarPayment() { - } - - /** - * Creates a function, which refunds a previously done payment in Telegram Stars; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param userId Identifier of the user who did the payment. - * @param telegramPaymentChargeId Telegram payment identifier. - */ - public RefundStarPayment(long userId, String telegramPaymentChargeId) { - this.userId = userId; - this.telegramPaymentChargeId = telegramPaymentChargeId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1804165035; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Registers the currently used device for receiving push notifications. Returns a globally unique identifier of the push notification subscription. - * - *

Returns {@link PushReceiverId PushReceiverId}

- */ - public static class RegisterDevice extends Function { - /** - * Device token. - */ - public DeviceToken deviceToken; - /** - * List of user identifiers of other users currently using the application. - */ - public long[] otherUserIds; - - /** - * Default constructor for a function, which registers the currently used device for receiving push notifications. Returns a globally unique identifier of the push notification subscription. - * - *

Returns {@link PushReceiverId PushReceiverId}

- */ - public RegisterDevice() { - } - - /** - * Creates a function, which registers the currently used device for receiving push notifications. Returns a globally unique identifier of the push notification subscription. - * - *

Returns {@link PushReceiverId PushReceiverId}

- * - * @param deviceToken Device token. - * @param otherUserIds List of user identifiers of other users currently using the application. - */ - public RegisterDevice(DeviceToken deviceToken, long[] otherUserIds) { - this.deviceToken = deviceToken; - this.otherUserIds = otherUserIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 366088823; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Finishes user registration. Works only when the current authorization state is authorizationStateWaitRegistration. - * - *

Returns {@link Ok Ok}

- */ - public static class RegisterUser extends Function { - /** - * The first name of the user; 1-64 characters. - */ - public String firstName; - /** - * The last name of the user; 0-64 characters. - */ - public String lastName; - /** - * Pass true to disable notification about the current user joining Telegram for other users that added them to contact list. - */ - public boolean disableNotification; - - /** - * Default constructor for a function, which finishes user registration. Works only when the current authorization state is authorizationStateWaitRegistration. - * - *

Returns {@link Ok Ok}

- */ - public RegisterUser() { - } - - /** - * Creates a function, which finishes user registration. Works only when the current authorization state is authorizationStateWaitRegistration. - * - *

Returns {@link Ok Ok}

- * - * @param firstName The first name of the user; 1-64 characters. - * @param lastName The last name of the user; 0-64 characters. - * @param disableNotification Pass true to disable notification about the current user joining Telegram for other users that added them to contact list. - */ - public RegisterUser(String firstName, String lastName, boolean disableNotification) { - this.firstName = firstName; - this.lastName = lastName; - this.disableNotification = disableNotification; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1012247828; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes all files from the file download list. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveAllFilesFromDownloads extends Function { - /** - * Pass true to remove only active downloads, including paused. - */ - public boolean onlyActive; - /** - * Pass true to remove only completed downloads. - */ - public boolean onlyCompleted; - /** - * Pass true to delete the file from the TDLib file cache. - */ - public boolean deleteFromCache; - - /** - * Default constructor for a function, which removes all files from the file download list. - * - *

Returns {@link Ok Ok}

- */ - public RemoveAllFilesFromDownloads() { - } - - /** - * Creates a function, which removes all files from the file download list. - * - *

Returns {@link Ok Ok}

- * - * @param onlyActive Pass true to remove only active downloads, including paused. - * @param onlyCompleted Pass true to remove only completed downloads. - * @param deleteFromCache Pass true to delete the file from the TDLib file cache. - */ - public RemoveAllFilesFromDownloads(boolean onlyActive, boolean onlyCompleted, boolean deleteFromCache) { - this.onlyActive = onlyActive; - this.onlyCompleted = onlyCompleted; - this.deleteFromCache = deleteFromCache; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1186433402; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes the connected business bot from a specific chat by adding the chat to businessRecipients.excludedChatIds. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveBusinessConnectedBotFromChat extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which removes the connected business bot from a specific chat by adding the chat to businessRecipients.excludedChatIds. - * - *

Returns {@link Ok Ok}

- */ - public RemoveBusinessConnectedBotFromChat() { - } - - /** - * Creates a function, which removes the connected business bot from a specific chat by adding the chat to businessRecipients.excludedChatIds. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - */ - public RemoveBusinessConnectedBotFromChat(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2020766707; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes a chat action bar without any other action. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveChatActionBar extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which removes a chat action bar without any other action. - * - *

Returns {@link Ok Ok}

- */ - public RemoveChatActionBar() { - } - - /** - * Creates a function, which removes a chat action bar without any other action. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - */ - public RemoveChatActionBar(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1650968070; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes users from the contact list. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveContacts extends Function { - /** - * Identifiers of users to be deleted. - */ - public long[] userIds; - - /** - * Default constructor for a function, which removes users from the contact list. - * - *

Returns {@link Ok Ok}

- */ - public RemoveContacts() { - } - - /** - * Creates a function, which removes users from the contact list. - * - *

Returns {@link Ok Ok}

- * - * @param userIds Identifiers of users to be deleted. - */ - public RemoveContacts(long[] userIds) { - this.userIds = userIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1943858054; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes a sticker from the list of favorite stickers. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveFavoriteSticker extends Function { - /** - * Sticker file to delete from the list. - */ - public InputFile sticker; - - /** - * Default constructor for a function, which removes a sticker from the list of favorite stickers. - * - *

Returns {@link Ok Ok}

- */ - public RemoveFavoriteSticker() { - } - - /** - * Creates a function, which removes a sticker from the list of favorite stickers. - * - *

Returns {@link Ok Ok}

- * - * @param sticker Sticker file to delete from the list. - */ - public RemoveFavoriteSticker(InputFile sticker) { - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1152945264; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes a file from the file download list. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveFileFromDownloads extends Function { - /** - * Identifier of the downloaded file. - */ - public int fileId; - /** - * Pass true to delete the file from the TDLib file cache. - */ - public boolean deleteFromCache; - - /** - * Default constructor for a function, which removes a file from the file download list. - * - *

Returns {@link Ok Ok}

- */ - public RemoveFileFromDownloads() { - } - - /** - * Creates a function, which removes a file from the file download list. - * - *

Returns {@link Ok Ok}

- * - * @param fileId Identifier of the downloaded file. - * @param deleteFromCache Pass true to delete the file from the TDLib file cache. - */ - public RemoveFileFromDownloads(int fileId, boolean deleteFromCache) { - this.fileId = fileId; - this.deleteFromCache = deleteFromCache; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1460060142; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes gifts from a collection. If the collection is owned by a channel chat, then requires canPostMessages administrator right in the channel chat. Returns the changed collection. - * - *

Returns {@link GiftCollection GiftCollection}

- */ - public static class RemoveGiftCollectionGifts extends Function { - /** - * Identifier of the user or the channel chat that owns the collection. - */ - public MessageSender ownerId; - /** - * Identifier of the gift collection. - */ - public int collectionId; - /** - * Identifier of the gifts to remove from the collection. - */ - public String[] receivedGiftIds; - - /** - * Default constructor for a function, which removes gifts from a collection. If the collection is owned by a channel chat, then requires canPostMessages administrator right in the channel chat. Returns the changed collection. - * - *

Returns {@link GiftCollection GiftCollection}

- */ - public RemoveGiftCollectionGifts() { - } - - /** - * Creates a function, which removes gifts from a collection. If the collection is owned by a channel chat, then requires canPostMessages administrator right in the channel chat. Returns the changed collection. - * - *

Returns {@link GiftCollection GiftCollection}

- * - * @param ownerId Identifier of the user or the channel chat that owns the collection. - * @param collectionId Identifier of the gift collection. - * @param receivedGiftIds Identifier of the gifts to remove from the collection. - */ - public RemoveGiftCollectionGifts(MessageSender ownerId, int collectionId, String[] receivedGiftIds) { - this.ownerId = ownerId; - this.collectionId = collectionId; - this.receivedGiftIds = receivedGiftIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -692316949; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes background from the list of installed backgrounds. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveInstalledBackground extends Function { - /** - * The background identifier. - */ - public long backgroundId; - - /** - * Default constructor for a function, which removes background from the list of installed backgrounds. - * - *

Returns {@link Ok Ok}

- */ - public RemoveInstalledBackground() { - } - - /** - * Creates a function, which removes background from the list of installed backgrounds. - * - *

Returns {@link Ok Ok}

- * - * @param backgroundId The background identifier. - */ - public RemoveInstalledBackground(long backgroundId) { - this.backgroundId = backgroundId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1346446652; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes a passkey from the list of passkeys allowed to be used for the login by the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveLoginPasskey extends Function { - /** - * Unique identifier of the passkey to remove. - */ - public String passkeyId; - - /** - * Default constructor for a function, which removes a passkey from the list of passkeys allowed to be used for the login by the current user. - * - *

Returns {@link Ok Ok}

- */ - public RemoveLoginPasskey() { - } - - /** - * Creates a function, which removes a passkey from the list of passkeys allowed to be used for the login by the current user. - * - *

Returns {@link Ok Ok}

- * - * @param passkeyId Unique identifier of the passkey to remove. - */ - public RemoveLoginPasskey(String passkeyId) { - this.passkeyId = passkeyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1728940387; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes a reaction from a message. A chosen reaction can always be removed. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveMessageReaction extends Function { - /** - * Identifier of the chat to which the message belongs. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * Type of the reaction to remove. The paid reaction can't be removed. - */ - public ReactionType reactionType; - - /** - * Default constructor for a function, which removes a reaction from a message. A chosen reaction can always be removed. - * - *

Returns {@link Ok Ok}

- */ - public RemoveMessageReaction() { - } - - /** - * Creates a function, which removes a reaction from a message. A chosen reaction can always be removed. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat to which the message belongs. - * @param messageId Identifier of the message. - * @param reactionType Type of the reaction to remove. The paid reaction can't be removed. - */ - public RemoveMessageReaction(long chatId, long messageId, ReactionType reactionType) { - this.chatId = chatId; - this.messageId = messageId; - this.reactionType = reactionType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1756934789; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes the verification status of a user or a chat by an owned bot. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveMessageSenderBotVerification extends Function { - /** - * Identifier of the owned bot, which verified the user or the chat. - */ - public long botUserId; - /** - * Identifier of the user or the supergroup or channel chat, which verification is removed. - */ - public MessageSender verifiedId; - - /** - * Default constructor for a function, which removes the verification status of a user or a chat by an owned bot. - * - *

Returns {@link Ok Ok}

- */ - public RemoveMessageSenderBotVerification() { - } - - /** - * Creates a function, which removes the verification status of a user or a chat by an owned bot. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId Identifier of the owned bot, which verified the user or the chat. - * @param verifiedId Identifier of the user or the supergroup or channel chat, which verification is removed. - */ - public RemoveMessageSenderBotVerification(long botUserId, MessageSender verifiedId) { - this.botUserId = botUserId; - this.verifiedId = verifiedId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1710174374; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes an active notification from notification list. Needs to be called only if the notification is removed by the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveNotification extends Function { - /** - * Identifier of notification group to which the notification belongs. - */ - public int notificationGroupId; - /** - * Identifier of removed notification. - */ - public int notificationId; - - /** - * Default constructor for a function, which removes an active notification from notification list. Needs to be called only if the notification is removed by the current user. - * - *

Returns {@link Ok Ok}

- */ - public RemoveNotification() { - } - - /** - * Creates a function, which removes an active notification from notification list. Needs to be called only if the notification is removed by the current user. - * - *

Returns {@link Ok Ok}

- * - * @param notificationGroupId Identifier of notification group to which the notification belongs. - * @param notificationId Identifier of removed notification. - */ - public RemoveNotification(int notificationGroupId, int notificationId) { - this.notificationGroupId = notificationGroupId; - this.notificationId = notificationId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 862630734; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes a group of active notifications. Needs to be called only if the notification group is removed by the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveNotificationGroup extends Function { - /** - * Notification group identifier. - */ - public int notificationGroupId; - /** - * The maximum identifier of removed notifications. - */ - public int maxNotificationId; - - /** - * Default constructor for a function, which removes a group of active notifications. Needs to be called only if the notification group is removed by the current user. - * - *

Returns {@link Ok Ok}

- */ - public RemoveNotificationGroup() { - } - - /** - * Creates a function, which removes a group of active notifications. Needs to be called only if the notification group is removed by the current user. - * - *

Returns {@link Ok Ok}

- * - * @param notificationGroupId Notification group identifier. - * @param maxNotificationId The maximum identifier of removed notifications. - */ - public RemoveNotificationGroup(int notificationGroupId, int maxNotificationId) { - this.notificationGroupId = notificationGroupId; - this.maxNotificationId = maxNotificationId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1713005454; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes all pending paid reactions in a live story group call. - * - *

Returns {@link Ok Ok}

- */ - public static class RemovePendingLiveStoryReactions extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - - /** - * Default constructor for a function, which removes all pending paid reactions in a live story group call. - * - *

Returns {@link Ok Ok}

- */ - public RemovePendingLiveStoryReactions() { - } - - /** - * Creates a function, which removes all pending paid reactions in a live story group call. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - */ - public RemovePendingLiveStoryReactions(int groupCallId) { - this.groupCallId = groupCallId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 868601112; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes all pending paid reactions on a message. - * - *

Returns {@link Ok Ok}

- */ - public static class RemovePendingPaidMessageReactions extends Function { - /** - * Identifier of the chat to which the message belongs. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - - /** - * Default constructor for a function, which removes all pending paid reactions on a message. - * - *

Returns {@link Ok Ok}

- */ - public RemovePendingPaidMessageReactions() { - } - - /** - * Creates a function, which removes all pending paid reactions on a message. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat to which the message belongs. - * @param messageId Identifier of the message. - */ - public RemovePendingPaidMessageReactions(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1100258555; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes an audio file from the profile audio files of the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveProfileAudio extends Function { - /** - * Identifier of the audio file to be removed. - */ - public int fileId; - - /** - * Default constructor for a function, which removes an audio file from the profile audio files of the current user. - * - *

Returns {@link Ok Ok}

- */ - public RemoveProfileAudio() { - } - - /** - * Creates a function, which removes an audio file from the profile audio files of the current user. - * - *

Returns {@link Ok Ok}

- * - * @param fileId Identifier of the audio file to be removed. - */ - public RemoveProfileAudio(int fileId) { - this.fileId = fileId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1292263034; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes a proxy server. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveProxy extends Function { - /** - * Proxy identifier. - */ - public int proxyId; - - /** - * Default constructor for a function, which removes a proxy server. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public RemoveProxy() { - } - - /** - * Creates a function, which removes a proxy server. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- * - * @param proxyId Proxy identifier. - */ - public RemoveProxy(int proxyId) { - this.proxyId = proxyId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1369219847; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes a hashtag from the list of recently used hashtags. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveRecentHashtag extends Function { - /** - * Hashtag to delete. - */ - public String hashtag; - - /** - * Default constructor for a function, which removes a hashtag from the list of recently used hashtags. - * - *

Returns {@link Ok Ok}

- */ - public RemoveRecentHashtag() { - } - - /** - * Creates a function, which removes a hashtag from the list of recently used hashtags. - * - *

Returns {@link Ok Ok}

- * - * @param hashtag Hashtag to delete. - */ - public RemoveRecentHashtag(String hashtag) { - this.hashtag = hashtag; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1013735260; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes a sticker from the list of recently used stickers. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveRecentSticker extends Function { - /** - * Pass true to remove the sticker from the list of stickers recently attached to photo or video files; pass false to remove the sticker from the list of recently sent stickers. - */ - public boolean isAttached; - /** - * Sticker file to delete. - */ - public InputFile sticker; - - /** - * Default constructor for a function, which removes a sticker from the list of recently used stickers. - * - *

Returns {@link Ok Ok}

- */ - public RemoveRecentSticker() { - } - - /** - * Creates a function, which removes a sticker from the list of recently used stickers. - * - *

Returns {@link Ok Ok}

- * - * @param isAttached Pass true to remove the sticker from the list of stickers recently attached to photo or video files; pass false to remove the sticker from the list of recently sent stickers. - * @param sticker Sticker file to delete. - */ - public RemoveRecentSticker(boolean isAttached, InputFile sticker) { - this.isAttached = isAttached; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1246577677; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes a chat from the list of recently found chats. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveRecentlyFoundChat extends Function { - /** - * Identifier of the chat to be removed. - */ - public long chatId; - - /** - * Default constructor for a function, which removes a chat from the list of recently found chats. - * - *

Returns {@link Ok Ok}

- */ - public RemoveRecentlyFoundChat() { - } - - /** - * Creates a function, which removes a chat from the list of recently found chats. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat to be removed. - */ - public RemoveRecentlyFoundChat(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 717340444; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes an animation from the list of saved animations. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveSavedAnimation extends Function { - /** - * Animation file to be removed. - */ - public InputFile animation; - - /** - * Default constructor for a function, which removes an animation from the list of saved animations. - * - *

Returns {@link Ok Ok}

- */ - public RemoveSavedAnimation() { - } - - /** - * Creates a function, which removes an animation from the list of saved animations. - * - *

Returns {@link Ok Ok}

- * - * @param animation Animation file to be removed. - */ - public RemoveSavedAnimation(InputFile animation) { - this.animation = animation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -495605479; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes a notification sound from the list of saved notification sounds. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveSavedNotificationSound extends Function { - /** - * Identifier of the notification sound. - */ - public long notificationSoundId; - - /** - * Default constructor for a function, which removes a notification sound from the list of saved notification sounds. - * - *

Returns {@link Ok Ok}

- */ - public RemoveSavedNotificationSound() { - } - - /** - * Creates a function, which removes a notification sound from the list of saved notification sounds. - * - *

Returns {@link Ok Ok}

- * - * @param notificationSoundId Identifier of the notification sound. - */ - public RemoveSavedNotificationSound(long notificationSoundId) { - this.notificationSoundId = notificationSoundId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -480032946; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes a hashtag or a cashtag from the list of recently searched for hashtags or cashtags. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveSearchedForTag extends Function { - /** - * Hashtag or cashtag to delete. - */ - public String tag; - - /** - * Default constructor for a function, which removes a hashtag or a cashtag from the list of recently searched for hashtags or cashtags. - * - *

Returns {@link Ok Ok}

- */ - public RemoveSearchedForTag() { - } - - /** - * Creates a function, which removes a hashtag or a cashtag from the list of recently searched for hashtags or cashtags. - * - *

Returns {@link Ok Ok}

- * - * @param tag Hashtag or cashtag to delete. - */ - public RemoveSearchedForTag(String tag) { - this.tag = tag; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 891382730; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes a sticker from the set to which it belongs. The sticker set must be owned by the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveStickerFromSet extends Function { - /** - * Sticker to remove from the set. - */ - public InputFile sticker; - - /** - * Default constructor for a function, which removes a sticker from the set to which it belongs. The sticker set must be owned by the current user. - * - *

Returns {@link Ok Ok}

- */ - public RemoveStickerFromSet() { - } - - /** - * Creates a function, which removes a sticker from the set to which it belongs. The sticker set must be owned by the current user. - * - *

Returns {@link Ok Ok}

- * - * @param sticker Sticker to remove from the set. - */ - public RemoveStickerFromSet(InputFile sticker) { - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1642196644; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes stories from an album. If the album is owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. Returns the changed album. - * - *

Returns {@link StoryAlbum StoryAlbum}

- */ - public static class RemoveStoryAlbumStories extends Function { - /** - * Identifier of the chat that owns the stories. - */ - public long chatId; - /** - * Identifier of the story album. - */ - public int storyAlbumId; - /** - * Identifier of the stories to remove from the album. - */ - public int[] storyIds; - - /** - * Default constructor for a function, which removes stories from an album. If the album is owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. Returns the changed album. - * - *

Returns {@link StoryAlbum StoryAlbum}

- */ - public RemoveStoryAlbumStories() { - } - - /** - * Creates a function, which removes stories from an album. If the album is owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. Returns the changed album. - * - *

Returns {@link StoryAlbum StoryAlbum}

- * - * @param chatId Identifier of the chat that owns the stories. - * @param storyAlbumId Identifier of the story album. - * @param storyIds Identifier of the stories to remove from the album. - */ - public RemoveStoryAlbumStories(long chatId, int storyAlbumId, int[] storyIds) { - this.chatId = chatId; - this.storyAlbumId = storyAlbumId; - this.storyIds = storyIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1901872465; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes a chat from the list of frequently used chats. Supported only if the chat info database is enabled. - * - *

Returns {@link Ok Ok}

- */ - public static class RemoveTopChat extends Function { - /** - * Category of frequently used chats. - */ - public TopChatCategory category; - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which removes a chat from the list of frequently used chats. Supported only if the chat info database is enabled. - * - *

Returns {@link Ok Ok}

- */ - public RemoveTopChat() { - } - - /** - * Creates a function, which removes a chat from the list of frequently used chats. Supported only if the chat info database is enabled. - * - *

Returns {@link Ok Ok}

- * - * @param category Category of frequently used chats. - * @param chatId Chat identifier. - */ - public RemoveTopChat(TopChatCategory category, long chatId) { - this.category = category; - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1907876267; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes order of active usernames of the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class ReorderActiveUsernames extends Function { - /** - * The new order of active usernames. All currently active usernames must be specified. - */ - public String[] usernames; - - /** - * Default constructor for a function, which changes order of active usernames of the current user. - * - *

Returns {@link Ok Ok}

- */ - public ReorderActiveUsernames() { - } - - /** - * Creates a function, which changes order of active usernames of the current user. - * - *

Returns {@link Ok Ok}

- * - * @param usernames The new order of active usernames. All currently active usernames must be specified. - */ - public ReorderActiveUsernames(String[] usernames) { - this.usernames = usernames; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -455399375; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes order of active usernames of a bot. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- */ - public static class ReorderBotActiveUsernames extends Function { - /** - * Identifier of the target bot. - */ - public long botUserId; - /** - * The new order of active usernames. All currently active usernames must be specified. - */ - public String[] usernames; - - /** - * Default constructor for a function, which changes order of active usernames of a bot. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- */ - public ReorderBotActiveUsernames() { - } - - /** - * Creates a function, which changes order of active usernames of a bot. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId Identifier of the target bot. - * @param usernames The new order of active usernames. All currently active usernames must be specified. - */ - public ReorderBotActiveUsernames(long botUserId, String[] usernames) { - this.botUserId = botUserId; - this.usernames = usernames; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1602301664; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes order of media previews in the list of media previews of a bot. - * - *

Returns {@link Ok Ok}

- */ - public static class ReorderBotMediaPreviews extends Function { - /** - * Identifier of the target bot. The bot must be owned and must have the main Web App. - */ - public long botUserId; - /** - * Language code of the media previews to reorder. - */ - public String languageCode; - /** - * File identifiers of the media in the new order. - */ - public int[] fileIds; - - /** - * Default constructor for a function, which changes order of media previews in the list of media previews of a bot. - * - *

Returns {@link Ok Ok}

- */ - public ReorderBotMediaPreviews() { - } - - /** - * Creates a function, which changes order of media previews in the list of media previews of a bot. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId Identifier of the target bot. The bot must be owned and must have the main Web App. - * @param languageCode Language code of the media previews to reorder. - * @param fileIds File identifiers of the media in the new order. - */ - public ReorderBotMediaPreviews(long botUserId, String languageCode, int[] fileIds) { - this.botUserId = botUserId; - this.languageCode = languageCode; - this.fileIds = fileIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 630851043; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the order of chat folders. - * - *

Returns {@link Ok Ok}

- */ - public static class ReorderChatFolders extends Function { - /** - * Identifiers of chat folders in the new correct order. - */ - public int[] chatFolderIds; - /** - * Position of the main chat list among chat folders, 0-based. Can be non-zero only for Premium users. - */ - public int mainChatListPosition; - - /** - * Default constructor for a function, which changes the order of chat folders. - * - *

Returns {@link Ok Ok}

- */ - public ReorderChatFolders() { - } - - /** - * Creates a function, which changes the order of chat folders. - * - *

Returns {@link Ok Ok}

- * - * @param chatFolderIds Identifiers of chat folders in the new correct order. - * @param mainChatListPosition Position of the main chat list among chat folders, 0-based. Can be non-zero only for Premium users. - */ - public ReorderChatFolders(int[] chatFolderIds, int mainChatListPosition) { - this.chatFolderIds = chatFolderIds; - this.mainChatListPosition = mainChatListPosition; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1665299546; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes order of gifts in a collection. If the collection is owned by a channel chat, then requires canPostMessages administrator right in the channel chat. Returns the changed collection. - * - *

Returns {@link GiftCollection GiftCollection}

- */ - public static class ReorderGiftCollectionGifts extends Function { - /** - * Identifier of the user or the channel chat that owns the collection. - */ - public MessageSender ownerId; - /** - * Identifier of the gift collection. - */ - public int collectionId; - /** - * Identifier of the gifts to move to the beginning of the collection. All other gifts are placed in the current order after the specified gifts. - */ - public String[] receivedGiftIds; - - /** - * Default constructor for a function, which changes order of gifts in a collection. If the collection is owned by a channel chat, then requires canPostMessages administrator right in the channel chat. Returns the changed collection. - * - *

Returns {@link GiftCollection GiftCollection}

- */ - public ReorderGiftCollectionGifts() { - } - - /** - * Creates a function, which changes order of gifts in a collection. If the collection is owned by a channel chat, then requires canPostMessages administrator right in the channel chat. Returns the changed collection. - * - *

Returns {@link GiftCollection GiftCollection}

- * - * @param ownerId Identifier of the user or the channel chat that owns the collection. - * @param collectionId Identifier of the gift collection. - * @param receivedGiftIds Identifier of the gifts to move to the beginning of the collection. All other gifts are placed in the current order after the specified gifts. - */ - public ReorderGiftCollectionGifts(MessageSender ownerId, int collectionId, String[] receivedGiftIds) { - this.ownerId = ownerId; - this.collectionId = collectionId; - this.receivedGiftIds = receivedGiftIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1545340419; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes order of gift collections. If the collections are owned by a channel chat, then requires canPostMessages administrator right in the channel chat. - * - *

Returns {@link Ok Ok}

- */ - public static class ReorderGiftCollections extends Function { - /** - * Identifier of the user or the channel chat that owns the collection. - */ - public MessageSender ownerId; - /** - * New order of gift collections. - */ - public int[] collectionIds; - - /** - * Default constructor for a function, which changes order of gift collections. If the collections are owned by a channel chat, then requires canPostMessages administrator right in the channel chat. - * - *

Returns {@link Ok Ok}

- */ - public ReorderGiftCollections() { - } - - /** - * Creates a function, which changes order of gift collections. If the collections are owned by a channel chat, then requires canPostMessages administrator right in the channel chat. - * - *

Returns {@link Ok Ok}

- * - * @param ownerId Identifier of the user or the channel chat that owns the collection. - * @param collectionIds New order of gift collections. - */ - public ReorderGiftCollections(MessageSender ownerId, int[] collectionIds) { - this.ownerId = ownerId; - this.collectionIds = collectionIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1607216912; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the order of installed sticker sets. - * - *

Returns {@link Ok Ok}

- */ - public static class ReorderInstalledStickerSets extends Function { - /** - * Type of the sticker sets to reorder. - */ - public StickerType stickerType; - /** - * Identifiers of installed sticker sets in the new correct order. - */ - public long[] stickerSetIds; - - /** - * Default constructor for a function, which changes the order of installed sticker sets. - * - *

Returns {@link Ok Ok}

- */ - public ReorderInstalledStickerSets() { - } - - /** - * Creates a function, which changes the order of installed sticker sets. - * - *

Returns {@link Ok Ok}

- * - * @param stickerType Type of the sticker sets to reorder. - * @param stickerSetIds Identifiers of installed sticker sets in the new correct order. - */ - public ReorderInstalledStickerSets(StickerType stickerType, long[] stickerSetIds) { - this.stickerType = stickerType; - this.stickerSetIds = stickerSetIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1074928158; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the order of quick reply shortcuts. - * - *

Returns {@link Ok Ok}

- */ - public static class ReorderQuickReplyShortcuts extends Function { - /** - * The new order of quick reply shortcuts. - */ - public int[] shortcutIds; - - /** - * Default constructor for a function, which changes the order of quick reply shortcuts. - * - *

Returns {@link Ok Ok}

- */ - public ReorderQuickReplyShortcuts() { - } - - /** - * Creates a function, which changes the order of quick reply shortcuts. - * - *

Returns {@link Ok Ok}

- * - * @param shortcutIds The new order of quick reply shortcuts. - */ - public ReorderQuickReplyShortcuts(int[] shortcutIds) { - this.shortcutIds = shortcutIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2052799232; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes order of stories in an album. If the album is owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. Returns the changed album. - * - *

Returns {@link StoryAlbum StoryAlbum}

- */ - public static class ReorderStoryAlbumStories extends Function { - /** - * Identifier of the chat that owns the stories. - */ - public long chatId; - /** - * Identifier of the story album. - */ - public int storyAlbumId; - /** - * Identifier of the stories to move to the beginning of the album. All other stories are placed in the current order after the specified stories. - */ - public int[] storyIds; - - /** - * Default constructor for a function, which changes order of stories in an album. If the album is owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. Returns the changed album. - * - *

Returns {@link StoryAlbum StoryAlbum}

- */ - public ReorderStoryAlbumStories() { - } - - /** - * Creates a function, which changes order of stories in an album. If the album is owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. Returns the changed album. - * - *

Returns {@link StoryAlbum StoryAlbum}

- * - * @param chatId Identifier of the chat that owns the stories. - * @param storyAlbumId Identifier of the story album. - * @param storyIds Identifier of the stories to move to the beginning of the album. All other stories are placed in the current order after the specified stories. - */ - public ReorderStoryAlbumStories(long chatId, int storyAlbumId, int[] storyIds) { - this.chatId = chatId; - this.storyAlbumId = storyAlbumId; - this.storyIds = storyIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 438104756; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes order of story albums. If the albums are owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. - * - *

Returns {@link Ok Ok}

- */ - public static class ReorderStoryAlbums extends Function { - /** - * Identifier of the chat that owns the stories. - */ - public long chatId; - /** - * New order of story albums. - */ - public int[] storyAlbumIds; - - /** - * Default constructor for a function, which changes order of story albums. If the albums are owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. - * - *

Returns {@link Ok Ok}

- */ - public ReorderStoryAlbums() { - } - - /** - * Creates a function, which changes order of story albums. If the albums are owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat that owns the stories. - * @param storyAlbumIds New order of story albums. - */ - public ReorderStoryAlbums(long chatId, int[] storyAlbumIds) { - this.chatId = chatId; - this.storyAlbumIds = storyAlbumIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 514423948; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes order of active usernames of a supergroup or channel, requires owner privileges in the supergroup or channel. - * - *

Returns {@link Ok Ok}

- */ - public static class ReorderSupergroupActiveUsernames extends Function { - /** - * Identifier of the supergroup or channel. - */ - public long supergroupId; - /** - * The new order of active usernames. All currently active usernames must be specified. - */ - public String[] usernames; - - /** - * Default constructor for a function, which changes order of active usernames of a supergroup or channel, requires owner privileges in the supergroup or channel. - * - *

Returns {@link Ok Ok}

- */ - public ReorderSupergroupActiveUsernames() { - } - - /** - * Creates a function, which changes order of active usernames of a supergroup or channel, requires owner privileges in the supergroup or channel. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId Identifier of the supergroup or channel. - * @param usernames The new order of active usernames. All currently active usernames must be specified. - */ - public ReorderSupergroupActiveUsernames(long supergroupId, String[] usernames) { - this.supergroupId = supergroupId; - this.usernames = usernames; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1962466095; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Replaces the current RTMP URL for streaming to a live story; requires owner privileges for channel chats. - * - *

Returns {@link RtmpUrl RtmpUrl}

- */ - public static class ReplaceLiveStoryRtmpUrl extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which replaces the current RTMP URL for streaming to a live story; requires owner privileges for channel chats. - * - *

Returns {@link RtmpUrl RtmpUrl}

- */ - public ReplaceLiveStoryRtmpUrl() { - } - - /** - * Creates a function, which replaces the current RTMP URL for streaming to a live story; requires owner privileges for channel chats. - * - *

Returns {@link RtmpUrl RtmpUrl}

- * - * @param chatId Chat identifier. - */ - public ReplaceLiveStoryRtmpUrl(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 585361229; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Replaces current primary invite link for a chat with a new primary invite link. Available for basic groups, supergroups, and channels. Requires administrator privileges and canInviteUsers right. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- */ - public static class ReplacePrimaryChatInviteLink extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which replaces current primary invite link for a chat with a new primary invite link. Available for basic groups, supergroups, and channels. Requires administrator privileges and canInviteUsers right. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- */ - public ReplacePrimaryChatInviteLink() { - } - - /** - * Creates a function, which replaces current primary invite link for a chat with a new primary invite link. Available for basic groups, supergroups, and channels. Requires administrator privileges and canInviteUsers right. - * - *

Returns {@link ChatInviteLink ChatInviteLink}

- * - * @param chatId Chat identifier. - */ - public ReplacePrimaryChatInviteLink(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1067350941; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Replaces existing sticker in a set. The function is equivalent to removeStickerFromSet, then addStickerToSet, then setStickerPositionInSet. - * - *

Returns {@link Ok Ok}

- */ - public static class ReplaceStickerInSet extends Function { - /** - * Sticker set owner; ignored for regular users. - */ - public long userId; - /** - * Sticker set name. The sticker set must be owned by the current user. - */ - public String name; - /** - * Sticker to remove from the set. - */ - public InputFile oldSticker; - /** - * Sticker to add to the set. - */ - public InputSticker newSticker; - - /** - * Default constructor for a function, which replaces existing sticker in a set. The function is equivalent to removeStickerFromSet, then addStickerToSet, then setStickerPositionInSet. - * - *

Returns {@link Ok Ok}

- */ - public ReplaceStickerInSet() { - } - - /** - * Creates a function, which replaces existing sticker in a set. The function is equivalent to removeStickerFromSet, then addStickerToSet, then setStickerPositionInSet. - * - *

Returns {@link Ok Ok}

- * - * @param userId Sticker set owner; ignored for regular users. - * @param name Sticker set name. The sticker set must be owned by the current user. - * @param oldSticker Sticker to remove from the set. - * @param newSticker Sticker to add to the set. - */ - public ReplaceStickerInSet(long userId, String name, InputFile oldSticker, InputSticker newSticker) { - this.userId = userId; - this.name = name; - this.oldSticker = oldSticker; - this.newSticker = newSticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -406311399; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Replaces the current RTMP URL for streaming to the video chat of a chat; requires owner privileges in the chat. - * - *

Returns {@link RtmpUrl RtmpUrl}

- */ - public static class ReplaceVideoChatRtmpUrl extends Function { - /** - * Chat identifier. - */ - public long chatId; - - /** - * Default constructor for a function, which replaces the current RTMP URL for streaming to the video chat of a chat; requires owner privileges in the chat. - * - *

Returns {@link RtmpUrl RtmpUrl}

- */ - public ReplaceVideoChatRtmpUrl() { - } - - /** - * Creates a function, which replaces the current RTMP URL for streaming to the video chat of a chat; requires owner privileges in the chat. - * - *

Returns {@link RtmpUrl RtmpUrl}

- * - * @param chatId Chat identifier. - */ - public ReplaceVideoChatRtmpUrl(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 558862304; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Reports that authentication code wasn't delivered via SMS; for official mobile applications only. Works only when the current authorization state is authorizationStateWaitCode. - * - *

Returns {@link Ok Ok}

- */ - public static class ReportAuthenticationCodeMissing extends Function { - /** - * Current mobile network code. - */ - public String mobileNetworkCode; - - /** - * Default constructor for a function, which reports that authentication code wasn't delivered via SMS; for official mobile applications only. Works only when the current authorization state is authorizationStateWaitCode. - * - *

Returns {@link Ok Ok}

- */ - public ReportAuthenticationCodeMissing() { - } - - /** - * Creates a function, which reports that authentication code wasn't delivered via SMS; for official mobile applications only. Works only when the current authorization state is authorizationStateWaitCode. - * - *

Returns {@link Ok Ok}

- * - * @param mobileNetworkCode Current mobile network code. - */ - public ReportAuthenticationCodeMissing(String mobileNetworkCode) { - this.mobileNetworkCode = mobileNetworkCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1846555064; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Reports a chat to the Telegram moderators. A chat can be reported only from the chat action bar, or if chat.canBeReported. - * - *

Returns {@link ReportChatResult ReportChatResult}

- */ - public static class ReportChat extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Option identifier chosen by the user; leave empty for the initial request. - */ - public byte[] optionId; - /** - * Identifiers of reported messages. Use messageProperties.canReportChat to check whether the message can be reported. - */ - public long[] messageIds; - /** - * Additional report details if asked by the server; 0-1024 characters; leave empty for the initial request. - */ - public String text; - - /** - * Default constructor for a function, which reports a chat to the Telegram moderators. A chat can be reported only from the chat action bar, or if chat.canBeReported. - * - *

Returns {@link ReportChatResult ReportChatResult}

- */ - public ReportChat() { - } - - /** - * Creates a function, which reports a chat to the Telegram moderators. A chat can be reported only from the chat action bar, or if chat.canBeReported. - * - *

Returns {@link ReportChatResult ReportChatResult}

- * - * @param chatId Chat identifier. - * @param optionId Option identifier chosen by the user; leave empty for the initial request. - * @param messageIds Identifiers of reported messages. Use messageProperties.canReportChat to check whether the message can be reported. - * @param text Additional report details if asked by the server; 0-1024 characters; leave empty for the initial request. - */ - public ReportChat(long chatId, byte[] optionId, long[] messageIds, String text) { - this.chatId = chatId; - this.optionId = optionId; - this.messageIds = messageIds; - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1058475058; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Reports a chat photo to the Telegram moderators. A chat photo can be reported only if chat.canBeReported. - * - *

Returns {@link Ok Ok}

- */ - public static class ReportChatPhoto extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the photo to report. Only full photos from chatPhoto can be reported. - */ - public int fileId; - /** - * The reason for reporting the chat photo. - */ - public ReportReason reason; - /** - * Additional report details; 0-1024 characters. - */ - public String text; - - /** - * Default constructor for a function, which reports a chat photo to the Telegram moderators. A chat photo can be reported only if chat.canBeReported. - * - *

Returns {@link Ok Ok}

- */ - public ReportChatPhoto() { - } - - /** - * Creates a function, which reports a chat photo to the Telegram moderators. A chat photo can be reported only if chat.canBeReported. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param fileId Identifier of the photo to report. Only full photos from chatPhoto can be reported. - * @param reason The reason for reporting the chat photo. - * @param text Additional report details; 0-1024 characters. - */ - public ReportChatPhoto(long chatId, int fileId, ReportReason reason, String text) { - this.chatId = chatId; - this.fileId = fileId; - this.reason = reason; - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -646966648; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Reports a sponsored message to Telegram moderators. - * - *

Returns {@link ReportSponsoredResult ReportSponsoredResult}

- */ - public static class ReportChatSponsoredMessage extends Function { - /** - * Chat identifier of the sponsored message. - */ - public long chatId; - /** - * Identifier of the sponsored message. - */ - public long messageId; - /** - * Option identifier chosen by the user; leave empty for the initial request. - */ - public byte[] optionId; - - /** - * Default constructor for a function, which reports a sponsored message to Telegram moderators. - * - *

Returns {@link ReportSponsoredResult ReportSponsoredResult}

- */ - public ReportChatSponsoredMessage() { - } - - /** - * Creates a function, which reports a sponsored message to Telegram moderators. - * - *

Returns {@link ReportSponsoredResult ReportSponsoredResult}

- * - * @param chatId Chat identifier of the sponsored message. - * @param messageId Identifier of the sponsored message. - * @param optionId Option identifier chosen by the user; leave empty for the initial request. - */ - public ReportChatSponsoredMessage(long chatId, long messageId, byte[] optionId) { - this.chatId = chatId; - this.messageId = messageId; - this.optionId = optionId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -979984820; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Reports reactions set on a message to the Telegram moderators. Reactions on a message can be reported only if messageProperties.canReportReactions. - * - *

Returns {@link Ok Ok}

- */ - public static class ReportMessageReactions extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Message identifier. - */ - public long messageId; - /** - * Identifier of the sender, which added the reaction. - */ - public MessageSender senderId; - - /** - * Default constructor for a function, which reports reactions set on a message to the Telegram moderators. Reactions on a message can be reported only if messageProperties.canReportReactions. - * - *

Returns {@link Ok Ok}

- */ - public ReportMessageReactions() { - } - - /** - * Creates a function, which reports reactions set on a message to the Telegram moderators. Reactions on a message can be reported only if messageProperties.canReportReactions. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param messageId Message identifier. - * @param senderId Identifier of the sender, which added the reaction. - */ - public ReportMessageReactions(long chatId, long messageId, MessageSender senderId) { - this.chatId = chatId; - this.messageId = messageId; - this.senderId = senderId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 919111719; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Reports that authentication code wasn't delivered via SMS to the specified phone number; for official mobile applications only. - * - *

Returns {@link Ok Ok}

- */ - public static class ReportPhoneNumberCodeMissing extends Function { - /** - * Current mobile network code. - */ - public String mobileNetworkCode; - - /** - * Default constructor for a function, which reports that authentication code wasn't delivered via SMS to the specified phone number; for official mobile applications only. - * - *

Returns {@link Ok Ok}

- */ - public ReportPhoneNumberCodeMissing() { - } - - /** - * Creates a function, which reports that authentication code wasn't delivered via SMS to the specified phone number; for official mobile applications only. - * - *

Returns {@link Ok Ok}

- * - * @param mobileNetworkCode Current mobile network code. - */ - public ReportPhoneNumberCodeMissing(String mobileNetworkCode) { - this.mobileNetworkCode = mobileNetworkCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -895175341; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Reports a sponsored chat to Telegram moderators. - * - *

Returns {@link ReportSponsoredResult ReportSponsoredResult}

- */ - public static class ReportSponsoredChat extends Function { - /** - * Unique identifier of the sponsored chat. - */ - public long sponsoredChatUniqueId; - /** - * Option identifier chosen by the user; leave empty for the initial request. - */ - public byte[] optionId; - - /** - * Default constructor for a function, which reports a sponsored chat to Telegram moderators. - * - *

Returns {@link ReportSponsoredResult ReportSponsoredResult}

- */ - public ReportSponsoredChat() { - } - - /** - * Creates a function, which reports a sponsored chat to Telegram moderators. - * - *

Returns {@link ReportSponsoredResult ReportSponsoredResult}

- * - * @param sponsoredChatUniqueId Unique identifier of the sponsored chat. - * @param optionId Option identifier chosen by the user; leave empty for the initial request. - */ - public ReportSponsoredChat(long sponsoredChatUniqueId, byte[] optionId) { - this.sponsoredChatUniqueId = sponsoredChatUniqueId; - this.optionId = optionId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -902673019; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Reports a story to the Telegram moderators. - * - *

Returns {@link ReportStoryResult ReportStoryResult}

- */ - public static class ReportStory extends Function { - /** - * The identifier of the poster of the story to report. - */ - public long storyPosterChatId; - /** - * The identifier of the story to report. - */ - public int storyId; - /** - * Option identifier chosen by the user; leave empty for the initial request. - */ - public byte[] optionId; - /** - * Additional report details; 0-1024 characters; leave empty for the initial request. - */ - public String text; - - /** - * Default constructor for a function, which reports a story to the Telegram moderators. - * - *

Returns {@link ReportStoryResult ReportStoryResult}

- */ - public ReportStory() { - } - - /** - * Creates a function, which reports a story to the Telegram moderators. - * - *

Returns {@link ReportStoryResult ReportStoryResult}

- * - * @param storyPosterChatId The identifier of the poster of the story to report. - * @param storyId The identifier of the story to report. - * @param optionId Option identifier chosen by the user; leave empty for the initial request. - * @param text Additional report details; 0-1024 characters; leave empty for the initial request. - */ - public ReportStory(long storyPosterChatId, int storyId, byte[] optionId, String text) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - this.optionId = optionId; - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1823256372; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Reports a false deletion of a message by aggressive anti-spam checks; requires administrator rights in the supergroup. Can be called only for messages from chatEventMessageDeleted with canReportAntiSpamFalsePositive == true. - * - *

Returns {@link Ok Ok}

- */ - public static class ReportSupergroupAntiSpamFalsePositive extends Function { - /** - * Supergroup identifier. - */ - public long supergroupId; - /** - * Identifier of the erroneously deleted message from chatEventMessageDeleted. - */ - public long messageId; - - /** - * Default constructor for a function, which reports a false deletion of a message by aggressive anti-spam checks; requires administrator rights in the supergroup. Can be called only for messages from chatEventMessageDeleted with canReportAntiSpamFalsePositive == true. - * - *

Returns {@link Ok Ok}

- */ - public ReportSupergroupAntiSpamFalsePositive() { - } - - /** - * Creates a function, which reports a false deletion of a message by aggressive anti-spam checks; requires administrator rights in the supergroup. Can be called only for messages from chatEventMessageDeleted with canReportAntiSpamFalsePositive == true. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId Supergroup identifier. - * @param messageId Identifier of the erroneously deleted message from chatEventMessageDeleted. - */ - public ReportSupergroupAntiSpamFalsePositive(long supergroupId, long messageId) { - this.supergroupId = supergroupId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -516050872; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Reports messages in a supergroup as spam; requires administrator rights in the supergroup. - * - *

Returns {@link Ok Ok}

- */ - public static class ReportSupergroupSpam extends Function { - /** - * Supergroup identifier. - */ - public long supergroupId; - /** - * Identifiers of messages to report. Use messageProperties.canReportSupergroupSpam to check whether the message can be reported. - */ - public long[] messageIds; - - /** - * Default constructor for a function, which reports messages in a supergroup as spam; requires administrator rights in the supergroup. - * - *

Returns {@link Ok Ok}

- */ - public ReportSupergroupSpam() { - } - - /** - * Creates a function, which reports messages in a supergroup as spam; requires administrator rights in the supergroup. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId Supergroup identifier. - * @param messageIds Identifiers of messages to report. Use messageProperties.canReportSupergroupSpam to check whether the message can be reported. - */ - public ReportSupergroupSpam(long supergroupId, long[] messageIds) { - this.supergroupId = supergroupId; - this.messageIds = messageIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -94825000; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Reports a video message advertisement to Telegram moderators. - * - *

Returns {@link ReportSponsoredResult ReportSponsoredResult}

- */ - public static class ReportVideoMessageAdvertisement extends Function { - /** - * Unique identifier of the advertisement. - */ - public long advertisementUniqueId; - /** - * Option identifier chosen by the user; leave empty for the initial request. - */ - public byte[] optionId; - - /** - * Default constructor for a function, which reports a video message advertisement to Telegram moderators. - * - *

Returns {@link ReportSponsoredResult ReportSponsoredResult}

- */ - public ReportVideoMessageAdvertisement() { - } - - /** - * Creates a function, which reports a video message advertisement to Telegram moderators. - * - *

Returns {@link ReportSponsoredResult ReportSponsoredResult}

- * - * @param advertisementUniqueId Unique identifier of the advertisement. - * @param optionId Option identifier chosen by the user; leave empty for the initial request. - */ - public ReportVideoMessageAdvertisement(long advertisementUniqueId, byte[] optionId) { - this.advertisementUniqueId = advertisementUniqueId; - this.optionId = optionId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 617137942; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Requests to send a 2-step verification password recovery code to an email address that was previously set up. Works only when the current authorization state is authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- */ - public static class RequestAuthenticationPasswordRecovery extends Function { - - /** - * Default constructor for a function, which requests to send a 2-step verification password recovery code to an email address that was previously set up. Works only when the current authorization state is authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- */ - public RequestAuthenticationPasswordRecovery() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1393896118; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Requests to send a 2-step verification password recovery code to an email address that was previously set up. - * - *

Returns {@link EmailAddressAuthenticationCodeInfo EmailAddressAuthenticationCodeInfo}

- */ - public static class RequestPasswordRecovery extends Function { - - /** - * Default constructor for a function, which requests to send a 2-step verification password recovery code to an email address that was previously set up. - * - *

Returns {@link EmailAddressAuthenticationCodeInfo EmailAddressAuthenticationCodeInfo}

- */ - public RequestPasswordRecovery() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -13777582; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Requests QR code authentication by scanning a QR code on another logged in device. Works only when the current authorization state is authorizationStateWaitPhoneNumber, or if there is no pending authentication query and the current authorization state is authorizationStateWaitPremiumPurchase, authorizationStateWaitEmailAddress, authorizationStateWaitEmailCode, authorizationStateWaitCode, authorizationStateWaitRegistration, or authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- */ - public static class RequestQrCodeAuthentication extends Function { - /** - * List of user identifiers of other users currently using the application. - */ - public long[] otherUserIds; - - /** - * Default constructor for a function, which requests QR code authentication by scanning a QR code on another logged in device. Works only when the current authorization state is authorizationStateWaitPhoneNumber, or if there is no pending authentication query and the current authorization state is authorizationStateWaitPremiumPurchase, authorizationStateWaitEmailAddress, authorizationStateWaitEmailCode, authorizationStateWaitCode, authorizationStateWaitRegistration, or authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- */ - public RequestQrCodeAuthentication() { - } - - /** - * Creates a function, which requests QR code authentication by scanning a QR code on another logged in device. Works only when the current authorization state is authorizationStateWaitPhoneNumber, or if there is no pending authentication query and the current authorization state is authorizationStateWaitPremiumPurchase, authorizationStateWaitEmailAddress, authorizationStateWaitEmailCode, authorizationStateWaitCode, authorizationStateWaitRegistration, or authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- * - * @param otherUserIds List of user identifiers of other users currently using the application. - */ - public RequestQrCodeAuthentication(long[] otherUserIds) { - this.otherUserIds = otherUserIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1363496527; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Resends an authentication code to the user. Works only when the current authorization state is authorizationStateWaitCode, the nextCodeType of the result is not null and the server-specified timeout has passed, or when the current authorization state is authorizationStateWaitEmailCode. - * - *

Returns {@link Ok Ok}

- */ - public static class ResendAuthenticationCode extends Function { - /** - * Reason of code resending; pass null if unknown. - */ - public ResendCodeReason reason; - - /** - * Default constructor for a function, which resends an authentication code to the user. Works only when the current authorization state is authorizationStateWaitCode, the nextCodeType of the result is not null and the server-specified timeout has passed, or when the current authorization state is authorizationStateWaitEmailCode. - * - *

Returns {@link Ok Ok}

- */ - public ResendAuthenticationCode() { - } - - /** - * Creates a function, which resends an authentication code to the user. Works only when the current authorization state is authorizationStateWaitCode, the nextCodeType of the result is not null and the server-specified timeout has passed, or when the current authorization state is authorizationStateWaitEmailCode. - * - *

Returns {@link Ok Ok}

- * - * @param reason Reason of code resending; pass null if unknown. - */ - public ResendAuthenticationCode(ResendCodeReason reason) { - this.reason = reason; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1506755656; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Resends the code to verify an email address to be added to a user's Telegram Passport. - * - *

Returns {@link EmailAddressAuthenticationCodeInfo EmailAddressAuthenticationCodeInfo}

- */ - public static class ResendEmailAddressVerificationCode extends Function { - - /** - * Default constructor for a function, which resends the code to verify an email address to be added to a user's Telegram Passport. - * - *

Returns {@link EmailAddressAuthenticationCodeInfo EmailAddressAuthenticationCodeInfo}

- */ - public ResendEmailAddressVerificationCode() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1872416732; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Resends the login email address verification code. - * - *

Returns {@link EmailAddressAuthenticationCodeInfo EmailAddressAuthenticationCodeInfo}

- */ - public static class ResendLoginEmailAddressCode extends Function { - - /** - * Default constructor for a function, which resends the login email address verification code. - * - *

Returns {@link EmailAddressAuthenticationCodeInfo EmailAddressAuthenticationCodeInfo}

- */ - public ResendLoginEmailAddressCode() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 292966933; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Resends messages which failed to send. Can be called only for messages for which messageSendingStateFailed.canRetry is true and after specified in messageSendingStateFailed.retryAfter time passed. If a message is re-sent, the corresponding failed to send message is deleted. Returns the sent messages in the same order as the message identifiers passed in messageIds. If a message can't be re-sent, null will be returned instead of the message. - * - *

Returns {@link Messages Messages}

- */ - public static class ResendMessages extends Function { - /** - * Identifier of the chat to send messages. - */ - public long chatId; - /** - * Identifiers of the messages to resend. Message identifiers must be in a strictly increasing order. - */ - public long[] messageIds; - /** - * New manually chosen quote from the message to be replied; pass null if none. Ignored if more than one message is re-sent, or if messageSendingStateFailed.needAnotherReplyQuote == false. - */ - public InputTextQuote quote; - /** - * The number of Telegram Stars the user agreed to pay to send the messages. Ignored if messageSendingStateFailed.requiredPaidMessageStarCount == 0. - */ - public long paidMessageStarCount; - - /** - * Default constructor for a function, which resends messages which failed to send. Can be called only for messages for which messageSendingStateFailed.canRetry is true and after specified in messageSendingStateFailed.retryAfter time passed. If a message is re-sent, the corresponding failed to send message is deleted. Returns the sent messages in the same order as the message identifiers passed in messageIds. If a message can't be re-sent, null will be returned instead of the message. - * - *

Returns {@link Messages Messages}

- */ - public ResendMessages() { - } - - /** - * Creates a function, which resends messages which failed to send. Can be called only for messages for which messageSendingStateFailed.canRetry is true and after specified in messageSendingStateFailed.retryAfter time passed. If a message is re-sent, the corresponding failed to send message is deleted. Returns the sent messages in the same order as the message identifiers passed in messageIds. If a message can't be re-sent, null will be returned instead of the message. - * - *

Returns {@link Messages Messages}

- * - * @param chatId Identifier of the chat to send messages. - * @param messageIds Identifiers of the messages to resend. Message identifiers must be in a strictly increasing order. - * @param quote New manually chosen quote from the message to be replied; pass null if none. Ignored if more than one message is re-sent, or if messageSendingStateFailed.needAnotherReplyQuote == false. - * @param paidMessageStarCount The number of Telegram Stars the user agreed to pay to send the messages. Ignored if messageSendingStateFailed.requiredPaidMessageStarCount == 0. - */ - public ResendMessages(long chatId, long[] messageIds, InputTextQuote quote, long paidMessageStarCount) { - this.chatId = chatId; - this.messageIds = messageIds; - this.quote = quote; - this.paidMessageStarCount = paidMessageStarCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 526374678; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Resends the authentication code sent to a phone number. Works only if the previously received authenticationCodeInfo nextCodeType was not null and the server-specified timeout has passed. - * - *

Returns {@link AuthenticationCodeInfo AuthenticationCodeInfo}

- */ - public static class ResendPhoneNumberCode extends Function { - /** - * Reason of code resending; pass null if unknown. - */ - public ResendCodeReason reason; - - /** - * Default constructor for a function, which resends the authentication code sent to a phone number. Works only if the previously received authenticationCodeInfo nextCodeType was not null and the server-specified timeout has passed. - * - *

Returns {@link AuthenticationCodeInfo AuthenticationCodeInfo}

- */ - public ResendPhoneNumberCode() { - } - - /** - * Creates a function, which resends the authentication code sent to a phone number. Works only if the previously received authenticationCodeInfo nextCodeType was not null and the server-specified timeout has passed. - * - *

Returns {@link AuthenticationCodeInfo AuthenticationCodeInfo}

- * - * @param reason Reason of code resending; pass null if unknown. - */ - public ResendPhoneNumberCode(ResendCodeReason reason) { - this.reason = reason; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1808704551; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Resends the 2-step verification recovery email address verification code. - * - *

Returns {@link PasswordState PasswordState}

- */ - public static class ResendRecoveryEmailAddressCode extends Function { - - /** - * Default constructor for a function, which resends the 2-step verification recovery email address verification code. - * - *

Returns {@link PasswordState PasswordState}

- */ - public ResendRecoveryEmailAddressCode() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 433483548; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Resets all chat and scope notification settings to their default values. By default, all chats are unmuted and message previews are shown. - * - *

Returns {@link Ok Ok}

- */ - public static class ResetAllNotificationSettings extends Function { - - /** - * Default constructor for a function, which resets all chat and scope notification settings to their default values. By default, all chats are unmuted and message previews are shown. - * - *

Returns {@link Ok Ok}

- */ - public ResetAllNotificationSettings() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -174020359; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Resets the login email address. May return an error with a message "TASK_ALREADY_EXISTS" if reset is still pending. Works only when the current authorization state is authorizationStateWaitEmailCode and authorizationState.canResetEmailAddress == true. - * - *

Returns {@link Ok Ok}

- */ - public static class ResetAuthenticationEmailAddress extends Function { - - /** - * Default constructor for a function, which resets the login email address. May return an error with a message "TASK_ALREADY_EXISTS" if reset is still pending. Works only when the current authorization state is authorizationStateWaitEmailCode and authorizationState.canResetEmailAddress == true. - * - *

Returns {@link Ok Ok}

- */ - public ResetAuthenticationEmailAddress() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -415075796; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Resets list of installed backgrounds to its default value. - * - *

Returns {@link Ok Ok}

- */ - public static class ResetInstalledBackgrounds extends Function { - - /** - * Default constructor for a function, which resets list of installed backgrounds to its default value. - * - *

Returns {@link Ok Ok}

- */ - public ResetInstalledBackgrounds() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1884553559; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Resets all network data usage statistics to zero. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class ResetNetworkStatistics extends Function { - - /** - * Default constructor for a function, which resets all network data usage statistics to zero. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public ResetNetworkStatistics() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1646452102; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes 2-step verification password without previous password and access to recovery email address. The password can't be reset immediately and the request needs to be repeated after the specified time. - * - *

Returns {@link ResetPasswordResult ResetPasswordResult}

- */ - public static class ResetPassword extends Function { - - /** - * Default constructor for a function, which removes 2-step verification password without previous password and access to recovery email address. The password can't be reset immediately and the request needs to be repeated after the specified time. - * - *

Returns {@link ResetPasswordResult ResetPasswordResult}

- */ - public ResetPassword() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -593589091; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Reuses an active Telegram Star subscription to a channel chat and joins the chat again. - * - *

Returns {@link Ok Ok}

- */ - public static class ReuseStarSubscription extends Function { - /** - * Identifier of the subscription. - */ - public String subscriptionId; - - /** - * Default constructor for a function, which reuses an active Telegram Star subscription to a channel chat and joins the chat again. - * - *

Returns {@link Ok Ok}

- */ - public ReuseStarSubscription() { - } - - /** - * Creates a function, which reuses an active Telegram Star subscription to a channel chat and joins the chat again. - * - *

Returns {@link Ok Ok}

- * - * @param subscriptionId Identifier of the subscription. - */ - public ReuseStarSubscription(String subscriptionId) { - this.subscriptionId = subscriptionId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 778531905; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Revokes invite link for a chat. Available for basic groups, supergroups, and channels. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. If a primary link is revoked, then additionally to the revoked link returns new primary link. - * - *

Returns {@link ChatInviteLinks ChatInviteLinks}

- */ - public static class RevokeChatInviteLink extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Invite link to be revoked. - */ - public String inviteLink; - - /** - * Default constructor for a function, which revokes invite link for a chat. Available for basic groups, supergroups, and channels. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. If a primary link is revoked, then additionally to the revoked link returns new primary link. - * - *

Returns {@link ChatInviteLinks ChatInviteLinks}

- */ - public RevokeChatInviteLink() { - } - - /** - * Creates a function, which revokes invite link for a chat. Available for basic groups, supergroups, and channels. Requires administrator privileges and canInviteUsers right in the chat for own links and owner privileges for other links. If a primary link is revoked, then additionally to the revoked link returns new primary link. - * - *

Returns {@link ChatInviteLinks ChatInviteLinks}

- * - * @param chatId Chat identifier. - * @param inviteLink Invite link to be revoked. - */ - public RevokeChatInviteLink(long chatId, String inviteLink) { - this.chatId = chatId; - this.inviteLink = inviteLink; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -776514135; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Revokes invite link for a group call. Requires groupCall.canBeManaged right for video chats or groupCall.isOwned otherwise. - * - *

Returns {@link Ok Ok}

- */ - public static class RevokeGroupCallInviteLink extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - - /** - * Default constructor for a function, which revokes invite link for a group call. Requires groupCall.canBeManaged right for video chats or groupCall.isOwned otherwise. - * - *

Returns {@link Ok Ok}

- */ - public RevokeGroupCallInviteLink() { - } - - /** - * Creates a function, which revokes invite link for a group call. Requires groupCall.canBeManaged right for video chats or groupCall.isOwned otherwise. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - */ - public RevokeGroupCallInviteLink(int groupCallId) { - this.groupCallId = groupCallId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 501589140; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Saves application log event on the server. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class SaveApplicationLogEvent extends Function { - /** - * Event type. - */ - public String type; - /** - * Optional chat identifier, associated with the event. - */ - public long chatId; - /** - * The log event data. - */ - public JsonValue data; - - /** - * Default constructor for a function, which saves application log event on the server. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public SaveApplicationLogEvent() { - } - - /** - * Creates a function, which saves application log event on the server. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- * - * @param type Event type. - * @param chatId Optional chat identifier, associated with the event. - * @param data The log event data. - */ - public SaveApplicationLogEvent(String type, long chatId, JsonValue data) { - this.type = type; - this.chatId = chatId; - this.data = data; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -811154930; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Saves an inline message to be sent by the given user; for bots only. - * - *

Returns {@link PreparedInlineMessageId PreparedInlineMessageId}

- */ - public static class SavePreparedInlineMessage extends Function { - /** - * Identifier of the user. - */ - public long userId; - /** - * The description of the message. - */ - public InputInlineQueryResult result; - /** - * Types of the chats to which the message can be sent. - */ - public TargetChatTypes chatTypes; - - /** - * Default constructor for a function, which saves an inline message to be sent by the given user; for bots only. - * - *

Returns {@link PreparedInlineMessageId PreparedInlineMessageId}

- */ - public SavePreparedInlineMessage() { - } - - /** - * Creates a function, which saves an inline message to be sent by the given user; for bots only. - * - *

Returns {@link PreparedInlineMessageId PreparedInlineMessageId}

- * - * @param userId Identifier of the user. - * @param result The description of the message. - * @param chatTypes Types of the chats to which the message can be sent. - */ - public SavePreparedInlineMessage(long userId, InputInlineQueryResult result, TargetChatTypes chatTypes) { - this.userId = userId; - this.result = result; - this.chatTypes = chatTypes; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -954963751; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches affiliate programs that can be connected to the given affiliate. - * - *

Returns {@link FoundAffiliatePrograms FoundAffiliatePrograms}

- */ - public static class SearchAffiliatePrograms extends Function { - /** - * The affiliate for which affiliate programs are searched for. - */ - public AffiliateType affiliate; - /** - * Sort order for the results. - */ - public AffiliateProgramSortOrder sortOrder; - /** - * Offset of the first affiliate program to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of affiliate programs to return. - */ - public int limit; - - /** - * Default constructor for a function, which searches affiliate programs that can be connected to the given affiliate. - * - *

Returns {@link FoundAffiliatePrograms FoundAffiliatePrograms}

- */ - public SearchAffiliatePrograms() { - } - - /** - * Creates a function, which searches affiliate programs that can be connected to the given affiliate. - * - *

Returns {@link FoundAffiliatePrograms FoundAffiliatePrograms}

- * - * @param affiliate The affiliate for which affiliate programs are searched for. - * @param sortOrder Sort order for the results. - * @param offset Offset of the first affiliate program to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of affiliate programs to return. - */ - public SearchAffiliatePrograms(AffiliateType affiliate, AffiliateProgramSortOrder sortOrder, String offset, int limit) { - this.affiliate = affiliate; - this.sortOrder = sortOrder; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 681156625; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for a background by its name. - * - *

Returns {@link Background Background}

- */ - public static class SearchBackground extends Function { - /** - * The name of the background. - */ - public String name; - - /** - * Default constructor for a function, which searches for a background by its name. - * - *

Returns {@link Background Background}

- */ - public SearchBackground() { - } - - /** - * Creates a function, which searches for a background by its name. - * - *

Returns {@link Background Background}

- * - * @param name The name of the background. - */ - public SearchBackground(String name) { - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2130996959; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for call and group call messages. Returns the results in reverse chronological order (i.e., in order of decreasing messageId). For optimal performance, the number of returned messages is chosen by TDLib. - * - *

Returns {@link FoundMessages FoundMessages}

- */ - public static class SearchCallMessages extends Function { - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of messages to be returned; up to 100. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - /** - * Pass true to search only for messages with missed/declined calls. - */ - public boolean onlyMissed; - - /** - * Default constructor for a function, which searches for call and group call messages. Returns the results in reverse chronological order (i.e., in order of decreasing messageId). For optimal performance, the number of returned messages is chosen by TDLib. - * - *

Returns {@link FoundMessages FoundMessages}

- */ - public SearchCallMessages() { - } - - /** - * Creates a function, which searches for call and group call messages. Returns the results in reverse chronological order (i.e., in order of decreasing messageId). For optimal performance, the number of returned messages is chosen by TDLib. - * - *

Returns {@link FoundMessages FoundMessages}

- * - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of messages to be returned; up to 100. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * @param onlyMissed Pass true to search only for messages with missed/declined calls. - */ - public SearchCallMessages(String offset, int limit, boolean onlyMissed) { - this.offset = offset; - this.limit = limit; - this.onlyMissed = onlyMissed; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1942229221; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches a chat with an affiliate program. Returns the chat if found and the program is active. - * - *

Returns {@link Chat Chat}

- */ - public static class SearchChatAffiliateProgram extends Function { - /** - * Username of the chat. - */ - public String username; - /** - * The referrer from an internalLinkTypeChatAffiliateProgram link. - */ - public String referrer; - - /** - * Default constructor for a function, which searches a chat with an affiliate program. Returns the chat if found and the program is active. - * - *

Returns {@link Chat Chat}

- */ - public SearchChatAffiliateProgram() { - } - - /** - * Creates a function, which searches a chat with an affiliate program. Returns the chat if found and the program is active. - * - *

Returns {@link Chat Chat}

- * - * @param username Username of the chat. - * @param referrer The referrer from an internalLinkTypeChatAffiliateProgram link. - */ - public SearchChatAffiliateProgram(String username, String referrer) { - this.username = username; - this.referrer = referrer; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1339291206; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for a specified query in the first name, last name and usernames of the members of a specified chat. Requires administrator rights if the chat is a channel. - * - *

Returns {@link ChatMembers ChatMembers}

- */ - public static class SearchChatMembers extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Query to search for. - */ - public String query; - /** - * The maximum number of users to be returned; up to 200. - */ - public int limit; - /** - * The type of users to search for; pass null to search among all chat members. - */ - public ChatMembersFilter filter; - - /** - * Default constructor for a function, which searches for a specified query in the first name, last name and usernames of the members of a specified chat. Requires administrator rights if the chat is a channel. - * - *

Returns {@link ChatMembers ChatMembers}

- */ - public SearchChatMembers() { - } - - /** - * Creates a function, which searches for a specified query in the first name, last name and usernames of the members of a specified chat. Requires administrator rights if the chat is a channel. - * - *

Returns {@link ChatMembers ChatMembers}

- * - * @param chatId Chat identifier. - * @param query Query to search for. - * @param limit The maximum number of users to be returned; up to 200. - * @param filter The type of users to search for; pass null to search among all chat members. - */ - public SearchChatMembers(long chatId, String query, int limit, ChatMembersFilter filter) { - this.chatId = chatId; - this.query = query; - this.limit = limit; - this.filter = filter; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -445823291; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for messages with given words in the chat. Returns the results in reverse chronological order, i.e. in order of decreasing messageId. Cannot be used in secret chats with a non-empty query (searchSecretMessages must be used instead), or without an enabled message database. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. A combination of query, senderId, filter and topicId search criteria is expected to be supported, only if it is required for Telegram official application implementation. - * - *

Returns {@link FoundChatMessages FoundChatMessages}

- */ - public static class SearchChatMessages extends Function { - /** - * Identifier of the chat in which to search messages. - */ - public long chatId; - /** - * Pass topic identifier to search messages only in specific topic; pass null to search for messages in all topics. - */ - public MessageTopic topicId; - /** - * Query to search for. - */ - public String query; - /** - * Identifier of the sender of messages to search for; pass null to search for messages from any sender. Not supported in secret chats. - */ - public MessageSender senderId; - /** - * Identifier of the message starting from which history must be fetched; use 0 to get results from the last message. - */ - public long fromMessageId; - /** - * Specify 0 to get results from exactly the message fromMessageId or a negative number to get the specified message and some newer messages. - */ - public int offset; - /** - * The maximum number of messages to be returned; must be positive and can't be greater than 100. If the offset is negative, then the limit must be greater than -offset. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - /** - * Additional filter for messages to search; pass null to search for all messages. - */ - public SearchMessagesFilter filter; - - /** - * Default constructor for a function, which searches for messages with given words in the chat. Returns the results in reverse chronological order, i.e. in order of decreasing messageId. Cannot be used in secret chats with a non-empty query (searchSecretMessages must be used instead), or without an enabled message database. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. A combination of query, senderId, filter and topicId search criteria is expected to be supported, only if it is required for Telegram official application implementation. - * - *

Returns {@link FoundChatMessages FoundChatMessages}

- */ - public SearchChatMessages() { - } - - /** - * Creates a function, which searches for messages with given words in the chat. Returns the results in reverse chronological order, i.e. in order of decreasing messageId. Cannot be used in secret chats with a non-empty query (searchSecretMessages must be used instead), or without an enabled message database. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. A combination of query, senderId, filter and topicId search criteria is expected to be supported, only if it is required for Telegram official application implementation. - * - *

Returns {@link FoundChatMessages FoundChatMessages}

- * - * @param chatId Identifier of the chat in which to search messages. - * @param topicId Pass topic identifier to search messages only in specific topic; pass null to search for messages in all topics. - * @param query Query to search for. - * @param senderId Identifier of the sender of messages to search for; pass null to search for messages from any sender. Not supported in secret chats. - * @param fromMessageId Identifier of the message starting from which history must be fetched; use 0 to get results from the last message. - * @param offset Specify 0 to get results from exactly the message fromMessageId or a negative number to get the specified message and some newer messages. - * @param limit The maximum number of messages to be returned; must be positive and can't be greater than 100. If the offset is negative, then the limit must be greater than -offset. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * @param filter Additional filter for messages to search; pass null to search for all messages. - */ - public SearchChatMessages(long chatId, MessageTopic topicId, String query, MessageSender senderId, long fromMessageId, int offset, int limit, SearchMessagesFilter filter) { - this.chatId = chatId; - this.topicId = topicId; - this.query = query; - this.senderId = senderId; - this.fromMessageId = fromMessageId; - this.offset = offset; - this.limit = limit; - this.filter = filter; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1072442212; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about the recent locations of chat members that were sent to the chat. Returns up to 1 location message per user. - * - *

Returns {@link Messages Messages}

- */ - public static class SearchChatRecentLocationMessages extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * The maximum number of messages to be returned. - */ - public int limit; - - /** - * Default constructor for a function, which returns information about the recent locations of chat members that were sent to the chat. Returns up to 1 location message per user. - * - *

Returns {@link Messages Messages}

- */ - public SearchChatRecentLocationMessages() { - } - - /** - * Creates a function, which returns information about the recent locations of chat members that were sent to the chat. Returns up to 1 location message per user. - * - *

Returns {@link Messages Messages}

- * - * @param chatId Chat identifier. - * @param limit The maximum number of messages to be returned. - */ - public SearchChatRecentLocationMessages(long chatId, int limit) { - this.chatId = chatId; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 950238950; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for the specified query in the title and username of already known chats. This is an offline method. Returns chats in the order seen in the main chat list. - * - *

Returns {@link Chats Chats}

- */ - public static class SearchChats extends Function { - /** - * Query to search for. If the query is empty, returns up to 50 recently found chats. - */ - public String query; - /** - * The maximum number of chats to be returned. - */ - public int limit; - - /** - * Default constructor for a function, which searches for the specified query in the title and username of already known chats. This is an offline method. Returns chats in the order seen in the main chat list. - * - *

Returns {@link Chats Chats}

- */ - public SearchChats() { - } - - /** - * Creates a function, which searches for the specified query in the title and username of already known chats. This is an offline method. Returns chats in the order seen in the main chat list. - * - *

Returns {@link Chats Chats}

- * - * @param query Query to search for. If the query is empty, returns up to 50 recently found chats. - * @param limit The maximum number of chats to be returned. - */ - public SearchChats(String query, int limit) { - this.query = query; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1879787060; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for the specified query in the title and username of already known chats via request to the server. Returns chats in the order seen in the main chat list. - * - *

Returns {@link Chats Chats}

- */ - public static class SearchChatsOnServer extends Function { - /** - * Query to search for. - */ - public String query; - /** - * The maximum number of chats to be returned. - */ - public int limit; - - /** - * Default constructor for a function, which searches for the specified query in the title and username of already known chats via request to the server. Returns chats in the order seen in the main chat list. - * - *

Returns {@link Chats Chats}

- */ - public SearchChatsOnServer() { - } - - /** - * Creates a function, which searches for the specified query in the title and username of already known chats via request to the server. Returns chats in the order seen in the main chat list. - * - *

Returns {@link Chats Chats}

- * - * @param query Query to search for. - * @param limit The maximum number of chats to be returned. - */ - public SearchChatsOnServer(String query, int limit) { - this.query = query; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1158402188; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for the specified query in the first names, last names and usernames of the known user contacts. - * - *

Returns {@link Users Users}

- */ - public static class SearchContacts extends Function { - /** - * Query to search for; may be empty to return all contacts. - */ - public String query; - /** - * The maximum number of users to be returned. - */ - public int limit; - - /** - * Default constructor for a function, which searches for the specified query in the first names, last names and usernames of the known user contacts. - * - *

Returns {@link Users Users}

- */ - public SearchContacts() { - } - - /** - * Creates a function, which searches for the specified query in the first names, last names and usernames of the known user contacts. - * - *

Returns {@link Users Users}

- * - * @param query Query to search for; may be empty to return all contacts. - * @param limit The maximum number of users to be returned. - */ - public SearchContacts(String query, int limit) { - this.query = query; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1794690715; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for emojis by keywords. Supported only if the file database is enabled. Order of results is unspecified. - * - *

Returns {@link EmojiKeywords EmojiKeywords}

- */ - public static class SearchEmojis extends Function { - /** - * Text to search for. - */ - public String text; - /** - * List of possible IETF language tags of the user's input language; may be empty if unknown. - */ - public String[] inputLanguageCodes; - - /** - * Default constructor for a function, which searches for emojis by keywords. Supported only if the file database is enabled. Order of results is unspecified. - * - *

Returns {@link EmojiKeywords EmojiKeywords}

- */ - public SearchEmojis() { - } - - /** - * Creates a function, which searches for emojis by keywords. Supported only if the file database is enabled. Order of results is unspecified. - * - *

Returns {@link EmojiKeywords EmojiKeywords}

- * - * @param text Text to search for. - * @param inputLanguageCodes List of possible IETF language tags of the user's input language; may be empty if unknown. - */ - public SearchEmojis(String text, String[] inputLanguageCodes) { - this.text = text; - this.inputLanguageCodes = inputLanguageCodes; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1456187668; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for files in the file download list or recently downloaded files from the list. - * - *

Returns {@link FoundFileDownloads FoundFileDownloads}

- */ - public static class SearchFileDownloads extends Function { - /** - * Query to search for; may be empty to return all downloaded files. - */ - public String query; - /** - * Pass true to search only for active downloads, including paused. - */ - public boolean onlyActive; - /** - * Pass true to search only for completed downloads. - */ - public boolean onlyCompleted; - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of files to be returned. - */ - public int limit; - - /** - * Default constructor for a function, which searches for files in the file download list or recently downloaded files from the list. - * - *

Returns {@link FoundFileDownloads FoundFileDownloads}

- */ - public SearchFileDownloads() { - } - - /** - * Creates a function, which searches for files in the file download list or recently downloaded files from the list. - * - *

Returns {@link FoundFileDownloads FoundFileDownloads}

- * - * @param query Query to search for; may be empty to return all downloaded files. - * @param onlyActive Pass true to search only for active downloads, including paused. - * @param onlyCompleted Pass true to search only for completed downloads. - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of files to be returned. - */ - public SearchFileDownloads(String query, boolean onlyActive, boolean onlyCompleted, String offset, int limit) { - this.query = query; - this.onlyActive = onlyActive; - this.onlyCompleted = onlyCompleted; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 706611286; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns upgraded gifts that can be bought from other owners using sendResoldGift. - * - *

Returns {@link GiftsForResale GiftsForResale}

- */ - public static class SearchGiftsForResale extends Function { - /** - * Identifier of the regular gift that was upgraded to a unique gift. - */ - public long giftId; - /** - * Order in which the results will be sorted. - */ - public GiftForResaleOrder order; - /** - * Pass true to get only gifts suitable for crafting. - */ - public boolean forCrafting; - /** - * Attributes used to filter received gifts. If multiple attributes of the same type are specified, then all of them are allowed. If none attributes of specific type are specified, then all values for this attribute type are allowed. - */ - public UpgradedGiftAttributeId[] attributes; - /** - * Offset of the first entry to return as received from the previous request with the same order and attributes; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of gifts to return. - */ - public int limit; - - /** - * Default constructor for a function, which returns upgraded gifts that can be bought from other owners using sendResoldGift. - * - *

Returns {@link GiftsForResale GiftsForResale}

- */ - public SearchGiftsForResale() { - } - - /** - * Creates a function, which returns upgraded gifts that can be bought from other owners using sendResoldGift. - * - *

Returns {@link GiftsForResale GiftsForResale}

- * - * @param giftId Identifier of the regular gift that was upgraded to a unique gift. - * @param order Order in which the results will be sorted. - * @param forCrafting Pass true to get only gifts suitable for crafting. - * @param attributes Attributes used to filter received gifts. If multiple attributes of the same type are specified, then all of them are allowed. If none attributes of specific type are specified, then all values for this attribute type are allowed. - * @param offset Offset of the first entry to return as received from the previous request with the same order and attributes; use empty string to get the first chunk of results. - * @param limit The maximum number of gifts to return. - */ - public SearchGiftsForResale(long giftId, GiftForResaleOrder order, boolean forCrafting, UpgradedGiftAttributeId[] attributes, String offset, int limit) { - this.giftId = giftId; - this.order = order; - this.forCrafting = forCrafting; - this.attributes = attributes; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1886868338; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for recently used hashtags by their prefix. - * - *

Returns {@link Hashtags Hashtags}

- */ - public static class SearchHashtags extends Function { - /** - * Hashtag prefix to search for. - */ - public String prefix; - /** - * The maximum number of hashtags to be returned. - */ - public int limit; - - /** - * Default constructor for a function, which searches for recently used hashtags by their prefix. - * - *

Returns {@link Hashtags Hashtags}

- */ - public SearchHashtags() { - } - - /** - * Creates a function, which searches for recently used hashtags by their prefix. - * - *

Returns {@link Hashtags Hashtags}

- * - * @param prefix Hashtag prefix to search for. - * @param limit The maximum number of hashtags to be returned. - */ - public SearchHashtags(String prefix, int limit) { - this.prefix = prefix; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1043637617; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for installed sticker sets by looking for specified query in their title and name. - * - *

Returns {@link StickerSets StickerSets}

- */ - public static class SearchInstalledStickerSets extends Function { - /** - * Type of the sticker sets to search for. - */ - public StickerType stickerType; - /** - * Query to search for. - */ - public String query; - /** - * The maximum number of sticker sets to return. - */ - public int limit; - - /** - * Default constructor for a function, which searches for installed sticker sets by looking for specified query in their title and name. - * - *

Returns {@link StickerSets StickerSets}

- */ - public SearchInstalledStickerSets() { - } - - /** - * Creates a function, which searches for installed sticker sets by looking for specified query in their title and name. - * - *

Returns {@link StickerSets StickerSets}

- * - * @param stickerType Type of the sticker sets to search for. - * @param query Query to search for. - * @param limit The maximum number of sticker sets to return. - */ - public SearchInstalledStickerSets(StickerType stickerType, String query, int limit) { - this.stickerType = stickerType; - this.query = query; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2120122276; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for messages in all chats except secret chats. Returns the results in reverse chronological order (i.e., in order of decreasing (date, chatId, messageId)). For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundMessages FoundMessages}

- */ - public static class SearchMessages extends Function { - /** - * Chat list in which to search messages; pass null to search in all chats regardless of their chat list. Only Main and Archive chat lists are supported. - */ - public ChatList chatList; - /** - * Query to search for. - */ - public String query; - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of messages to be returned; up to 100. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - /** - * Additional filter for messages to search; pass null to search for all messages. Filters searchMessagesFilterMention, searchMessagesFilterUnreadMention, searchMessagesFilterUnreadReaction, searchMessagesFilterFailedToSend, and searchMessagesFilterPinned are unsupported in this function. - */ - public SearchMessagesFilter filter; - /** - * Additional filter for type of the chat of the searched messages; pass null to search for messages in all chats. - */ - public SearchMessagesChatTypeFilter chatTypeFilter; - /** - * If not 0, the minimum date of the messages to return. - */ - public int minDate; - /** - * If not 0, the maximum date of the messages to return. - */ - public int maxDate; - - /** - * Default constructor for a function, which searches for messages in all chats except secret chats. Returns the results in reverse chronological order (i.e., in order of decreasing (date, chatId, messageId)). For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundMessages FoundMessages}

- */ - public SearchMessages() { - } - - /** - * Creates a function, which searches for messages in all chats except secret chats. Returns the results in reverse chronological order (i.e., in order of decreasing (date, chatId, messageId)). For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundMessages FoundMessages}

- * - * @param chatList Chat list in which to search messages; pass null to search in all chats regardless of their chat list. Only Main and Archive chat lists are supported. - * @param query Query to search for. - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of messages to be returned; up to 100. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * @param filter Additional filter for messages to search; pass null to search for all messages. Filters searchMessagesFilterMention, searchMessagesFilterUnreadMention, searchMessagesFilterUnreadReaction, searchMessagesFilterFailedToSend, and searchMessagesFilterPinned are unsupported in this function. - * @param chatTypeFilter Additional filter for type of the chat of the searched messages; pass null to search for messages in all chats. - * @param minDate If not 0, the minimum date of the messages to return. - * @param maxDate If not 0, the maximum date of the messages to return. - */ - public SearchMessages(ChatList chatList, String query, String offset, int limit, SearchMessagesFilter filter, SearchMessagesChatTypeFilter chatTypeFilter, int minDate, int maxDate) { - this.chatList = chatList; - this.query = query; - this.offset = offset; - this.limit = limit; - this.filter = filter; - this.chatTypeFilter = chatTypeFilter; - this.minDate = minDate; - this.maxDate = maxDate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1225448885; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for outgoing messages with content of the type messageDocument in all chats except secret chats. Returns the results in reverse chronological order. - * - *

Returns {@link FoundMessages FoundMessages}

- */ - public static class SearchOutgoingDocumentMessages extends Function { - /** - * Query to search for in document file name and message caption. - */ - public String query; - /** - * The maximum number of messages to be returned; up to 100. - */ - public int limit; - - /** - * Default constructor for a function, which searches for outgoing messages with content of the type messageDocument in all chats except secret chats. Returns the results in reverse chronological order. - * - *

Returns {@link FoundMessages FoundMessages}

- */ - public SearchOutgoingDocumentMessages() { - } - - /** - * Creates a function, which searches for outgoing messages with content of the type messageDocument in all chats except secret chats. Returns the results in reverse chronological order. - * - *

Returns {@link FoundMessages FoundMessages}

- * - * @param query Query to search for in document file name and message caption. - * @param limit The maximum number of messages to be returned; up to 100. - */ - public SearchOutgoingDocumentMessages(String query, int limit) { - this.query = query; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1071397762; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches a public chat by its username. Currently, only private chats, supergroups and channels can be public. Returns the chat if found; otherwise, an error is returned. - * - *

Returns {@link Chat Chat}

- */ - public static class SearchPublicChat extends Function { - /** - * Username to be resolved. - */ - public String username; - - /** - * Default constructor for a function, which searches a public chat by its username. Currently, only private chats, supergroups and channels can be public. Returns the chat if found; otherwise, an error is returned. - * - *

Returns {@link Chat Chat}

- */ - public SearchPublicChat() { - } - - /** - * Creates a function, which searches a public chat by its username. Currently, only private chats, supergroups and channels can be public. Returns the chat if found; otherwise, an error is returned. - * - *

Returns {@link Chat Chat}

- * - * @param username Username to be resolved. - */ - public SearchPublicChat(String username) { - this.username = username; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 857135533; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches public chats by looking for specified query in their username and title. Currently, only private chats, supergroups and channels can be public. Returns a meaningful number of results. Excludes private chats with contacts and chats from the chat list from the results. - * - *

Returns {@link Chats Chats}

- */ - public static class SearchPublicChats extends Function { - /** - * Query to search for. - */ - public String query; - - /** - * Default constructor for a function, which searches public chats by looking for specified query in their username and title. Currently, only private chats, supergroups and channels can be public. Returns a meaningful number of results. Excludes private chats with contacts and chats from the chat list from the results. - * - *

Returns {@link Chats Chats}

- */ - public SearchPublicChats() { - } - - /** - * Creates a function, which searches public chats by looking for specified query in their username and title. Currently, only private chats, supergroups and channels can be public. Returns a meaningful number of results. Excludes private chats with contacts and chats from the chat list from the results. - * - *

Returns {@link Chats Chats}

- * - * @param query Query to search for. - */ - public SearchPublicChats(String query) { - this.query = query; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 970385337; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for public channel posts containing the given hashtag or cashtag. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundMessages FoundMessages}

- */ - public static class SearchPublicMessagesByTag extends Function { - /** - * Hashtag or cashtag to search for. - */ - public String tag; - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of messages to be returned; up to 100. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which searches for public channel posts containing the given hashtag or cashtag. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundMessages FoundMessages}

- */ - public SearchPublicMessagesByTag() { - } - - /** - * Creates a function, which searches for public channel posts containing the given hashtag or cashtag. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundMessages FoundMessages}

- * - * @param tag Hashtag or cashtag to search for. - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of messages to be returned; up to 100. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public SearchPublicMessagesByTag(String tag, String offset, int limit) { - this.tag = tag; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 630680746; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for public channel posts using the given query. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundPublicPosts FoundPublicPosts}

- */ - public static class SearchPublicPosts extends Function { - /** - * Query to search for. - */ - public String query; - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of messages to be returned; up to 100. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - /** - * The Telegram Star amount the user agreed to pay for the search; pass 0 for free searches. - */ - public long starCount; - - /** - * Default constructor for a function, which searches for public channel posts using the given query. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundPublicPosts FoundPublicPosts}

- */ - public SearchPublicPosts() { - } - - /** - * Creates a function, which searches for public channel posts using the given query. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundPublicPosts FoundPublicPosts}

- * - * @param query Query to search for. - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of messages to be returned; up to 100. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * @param starCount The Telegram Star amount the user agreed to pay for the search; pass 0 for free searches. - */ - public SearchPublicPosts(String query, String offset, int limit, long starCount) { - this.query = query; - this.offset = offset; - this.limit = limit; - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 618133347; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for public stories by the given address location. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundStories FoundStories}

- */ - public static class SearchPublicStoriesByLocation extends Function { - /** - * Address of the location. - */ - public LocationAddress address; - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of stories to be returned; up to 100. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which searches for public stories by the given address location. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundStories FoundStories}

- */ - public SearchPublicStoriesByLocation() { - } - - /** - * Creates a function, which searches for public stories by the given address location. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundStories FoundStories}

- * - * @param address Address of the location. - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of stories to be returned; up to 100. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - */ - public SearchPublicStoriesByLocation(LocationAddress address, String offset, int limit) { - this.address = address; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1596709256; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for public stories containing the given hashtag or cashtag. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundStories FoundStories}

- */ - public static class SearchPublicStoriesByTag extends Function { - /** - * Identifier of the chat that posted the stories to search for; pass 0 to search stories in all chats. - */ - public long storyPosterChatId; - /** - * Hashtag or cashtag to search for. - */ - public String tag; - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of stories to be returned; up to 100. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which searches for public stories containing the given hashtag or cashtag. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundStories FoundStories}

- */ - public SearchPublicStoriesByTag() { - } - - /** - * Creates a function, which searches for public stories containing the given hashtag or cashtag. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundStories FoundStories}

- * - * @param storyPosterChatId Identifier of the chat that posted the stories to search for; pass 0 to search stories in all chats. - * @param tag Hashtag or cashtag to search for. - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of stories to be returned; up to 100. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - */ - public SearchPublicStoriesByTag(long storyPosterChatId, String tag, String offset, int limit) { - this.storyPosterChatId = storyPosterChatId; - this.tag = tag; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1778102602; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for public stories from the given venue. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundStories FoundStories}

- */ - public static class SearchPublicStoriesByVenue extends Function { - /** - * Provider of the venue. - */ - public String venueProvider; - /** - * Identifier of the venue in the provider database. - */ - public String venueId; - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of stories to be returned; up to 100. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which searches for public stories from the given venue. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundStories FoundStories}

- */ - public SearchPublicStoriesByVenue() { - } - - /** - * Creates a function, which searches for public stories from the given venue. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundStories FoundStories}

- * - * @param venueProvider Provider of the venue. - * @param venueId Identifier of the venue in the provider database. - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of stories to be returned; up to 100. For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit. - */ - public SearchPublicStoriesByVenue(String venueProvider, String venueId, String offset, int limit) { - this.venueProvider = venueProvider; - this.venueId = venueId; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -686136790; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for a given quote in a text. Returns found quote start position in UTF-16 code units. Returns a 404 error if the quote is not found. Can be called synchronously. - * - *

Returns {@link FoundPosition FoundPosition}

- */ - public static class SearchQuote extends Function { - /** - * Text in which to search for the quote. - */ - public FormattedText text; - /** - * Quote to search for. - */ - public FormattedText quote; - /** - * Approximate quote position in UTF-16 code units. - */ - public int quotePosition; - - /** - * Default constructor for a function, which searches for a given quote in a text. Returns found quote start position in UTF-16 code units. Returns a 404 error if the quote is not found. Can be called synchronously. - * - *

Returns {@link FoundPosition FoundPosition}

- */ - public SearchQuote() { - } - - /** - * Creates a function, which searches for a given quote in a text. Returns found quote start position in UTF-16 code units. Returns a 404 error if the quote is not found. Can be called synchronously. - * - *

Returns {@link FoundPosition FoundPosition}

- * - * @param text Text in which to search for the quote. - * @param quote Quote to search for. - * @param quotePosition Approximate quote position in UTF-16 code units. - */ - public SearchQuote(FormattedText text, FormattedText quote, int quotePosition) { - this.text = text; - this.quote = quote; - this.quotePosition = quotePosition; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1751384351; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for the specified query in the title and username of up to 50 recently found chats. This is an offline method. - * - *

Returns {@link Chats Chats}

- */ - public static class SearchRecentlyFoundChats extends Function { - /** - * Query to search for. - */ - public String query; - /** - * The maximum number of chats to be returned. - */ - public int limit; - - /** - * Default constructor for a function, which searches for the specified query in the title and username of up to 50 recently found chats. This is an offline method. - * - *

Returns {@link Chats Chats}

- */ - public SearchRecentlyFoundChats() { - } - - /** - * Creates a function, which searches for the specified query in the title and username of up to 50 recently found chats. This is an offline method. - * - *

Returns {@link Chats Chats}

- * - * @param query Query to search for. - * @param limit The maximum number of chats to be returned. - */ - public SearchRecentlyFoundChats(String query, int limit) { - this.query = query; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1647445393; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for messages tagged by the given reaction and with the given words in the Saved Messages chat; for Telegram Premium users only. Returns the results in reverse chronological order, i.e. in order of decreasing messageId. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundChatMessages FoundChatMessages}

- */ - public static class SearchSavedMessages extends Function { - /** - * If not 0, only messages in the specified Saved Messages topic will be considered; pass 0 to consider all messages. - */ - public long savedMessagesTopicId; - /** - * Tag to search for; pass null to return all suitable messages. - */ - public ReactionType tag; - /** - * Query to search for. - */ - public String query; - /** - * Identifier of the message starting from which messages must be fetched; use 0 to get results from the last message. - */ - public long fromMessageId; - /** - * Specify 0 to get results from exactly the message fromMessageId or a negative number to get the specified message and some newer messages. - */ - public int offset; - /** - * The maximum number of messages to be returned; must be positive and can't be greater than 100. If the offset is negative, then the limit must be greater than -offset. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - - /** - * Default constructor for a function, which searches for messages tagged by the given reaction and with the given words in the Saved Messages chat; for Telegram Premium users only. Returns the results in reverse chronological order, i.e. in order of decreasing messageId. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundChatMessages FoundChatMessages}

- */ - public SearchSavedMessages() { - } - - /** - * Creates a function, which searches for messages tagged by the given reaction and with the given words in the Saved Messages chat; for Telegram Premium users only. Returns the results in reverse chronological order, i.e. in order of decreasing messageId. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * - *

Returns {@link FoundChatMessages FoundChatMessages}

- * - * @param savedMessagesTopicId If not 0, only messages in the specified Saved Messages topic will be considered; pass 0 to consider all messages. - * @param tag Tag to search for; pass null to return all suitable messages. - * @param query Query to search for. - * @param fromMessageId Identifier of the message starting from which messages must be fetched; use 0 to get results from the last message. - * @param offset Specify 0 to get results from exactly the message fromMessageId or a negative number to get the specified message and some newer messages. - * @param limit The maximum number of messages to be returned; must be positive and can't be greater than 100. If the offset is negative, then the limit must be greater than -offset. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public SearchSavedMessages(long savedMessagesTopicId, ReactionType tag, String query, long fromMessageId, int offset, int limit) { - this.savedMessagesTopicId = savedMessagesTopicId; - this.tag = tag; - this.query = query; - this.fromMessageId = fromMessageId; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1969512554; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for messages in secret chats. Returns the results in reverse chronological order. For optimal performance, the number of returned messages is chosen by TDLib. - * - *

Returns {@link FoundMessages FoundMessages}

- */ - public static class SearchSecretMessages extends Function { - /** - * Identifier of the chat in which to search. Specify 0 to search in all secret chats. - */ - public long chatId; - /** - * Query to search for. If empty, searchChatMessages must be used instead. - */ - public String query; - /** - * Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - */ - public String offset; - /** - * The maximum number of messages to be returned; up to 100. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - */ - public int limit; - /** - * Additional filter for messages to search; pass null to search for all messages. - */ - public SearchMessagesFilter filter; - - /** - * Default constructor for a function, which searches for messages in secret chats. Returns the results in reverse chronological order. For optimal performance, the number of returned messages is chosen by TDLib. - * - *

Returns {@link FoundMessages FoundMessages}

- */ - public SearchSecretMessages() { - } - - /** - * Creates a function, which searches for messages in secret chats. Returns the results in reverse chronological order. For optimal performance, the number of returned messages is chosen by TDLib. - * - *

Returns {@link FoundMessages FoundMessages}

- * - * @param chatId Identifier of the chat in which to search. Specify 0 to search in all secret chats. - * @param query Query to search for. If empty, searchChatMessages must be used instead. - * @param offset Offset of the first entry to return as received from the previous request; use empty string to get the first chunk of results. - * @param limit The maximum number of messages to be returned; up to 100. For optimal performance, the number of returned messages is chosen by TDLib and can be smaller than the specified limit. - * @param filter Additional filter for messages to search; pass null to search for all messages. - */ - public SearchSecretMessages(long chatId, String query, String offset, int limit, SearchMessagesFilter filter) { - this.chatId = chatId; - this.query = query; - this.offset = offset; - this.limit = limit; - this.filter = filter; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -852865892; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for a sticker set by its name. - * - *

Returns {@link StickerSet StickerSet}

- */ - public static class SearchStickerSet extends Function { - /** - * Name of the sticker set. - */ - public String name; - /** - * Pass true to ignore local cache of sticker sets and always send a network request. - */ - public boolean ignoreCache; - - /** - * Default constructor for a function, which searches for a sticker set by its name. - * - *

Returns {@link StickerSet StickerSet}

- */ - public SearchStickerSet() { - } - - /** - * Creates a function, which searches for a sticker set by its name. - * - *

Returns {@link StickerSet StickerSet}

- * - * @param name Name of the sticker set. - * @param ignoreCache Pass true to ignore local cache of sticker sets and always send a network request. - */ - public SearchStickerSet(String name, boolean ignoreCache) { - this.name = name; - this.ignoreCache = ignoreCache; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1676592898; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for sticker sets by looking for specified query in their title and name. Excludes installed sticker sets from the results. - * - *

Returns {@link StickerSets StickerSets}

- */ - public static class SearchStickerSets extends Function { - /** - * Type of the sticker sets to return. - */ - public StickerType stickerType; - /** - * Query to search for. - */ - public String query; - - /** - * Default constructor for a function, which searches for sticker sets by looking for specified query in their title and name. Excludes installed sticker sets from the results. - * - *

Returns {@link StickerSets StickerSets}

- */ - public SearchStickerSets() { - } - - /** - * Creates a function, which searches for sticker sets by looking for specified query in their title and name. Excludes installed sticker sets from the results. - * - *

Returns {@link StickerSets StickerSets}

- * - * @param stickerType Type of the sticker sets to return. - * @param query Query to search for. - */ - public SearchStickerSets(StickerType stickerType, String query) { - this.stickerType = stickerType; - this.query = query; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 262801004; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches for stickers from public sticker sets that correspond to any of the given emoji. - * - *

Returns {@link Stickers Stickers}

- */ - public static class SearchStickers extends Function { - /** - * Type of the stickers to return. - */ - public StickerType stickerType; - /** - * Space-separated list of emojis to search for. - */ - public String emojis; - /** - * Query to search for; may be empty to search for emoji only. - */ - public String query; - /** - * List of possible IETF language tags of the user's input language; may be empty if unknown. - */ - public String[] inputLanguageCodes; - /** - * The offset from which to return the stickers; must be non-negative. - */ - public int offset; - /** - * The maximum number of stickers to be returned; 0-100. - */ - public int limit; - - /** - * Default constructor for a function, which searches for stickers from public sticker sets that correspond to any of the given emoji. - * - *

Returns {@link Stickers Stickers}

- */ - public SearchStickers() { - } - - /** - * Creates a function, which searches for stickers from public sticker sets that correspond to any of the given emoji. - * - *

Returns {@link Stickers Stickers}

- * - * @param stickerType Type of the stickers to return. - * @param emojis Space-separated list of emojis to search for. - * @param query Query to search for; may be empty to search for emoji only. - * @param inputLanguageCodes List of possible IETF language tags of the user's input language; may be empty if unknown. - * @param offset The offset from which to return the stickers; must be non-negative. - * @param limit The maximum number of stickers to be returned; 0-100. - */ - public SearchStickers(StickerType stickerType, String emojis, String query, String[] inputLanguageCodes, int offset, int limit) { - this.stickerType = stickerType; - this.emojis = emojis; - this.query = query; - this.inputLanguageCodes = inputLanguageCodes; - this.offset = offset; - this.limit = limit; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1856294754; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches specified query by word prefixes in the provided strings. Returns 0-based positions of strings that matched. Can be called synchronously. - * - *

Returns {@link FoundPositions FoundPositions}

- */ - public static class SearchStringsByPrefix extends Function { - /** - * The strings to search in for the query. - */ - public String[] strings; - /** - * Query to search for. - */ - public String query; - /** - * The maximum number of objects to return. - */ - public int limit; - /** - * Pass true to receive no results for an empty query. - */ - public boolean returnNoneForEmptyQuery; - - /** - * Default constructor for a function, which searches specified query by word prefixes in the provided strings. Returns 0-based positions of strings that matched. Can be called synchronously. - * - *

Returns {@link FoundPositions FoundPositions}

- */ - public SearchStringsByPrefix() { - } - - /** - * Creates a function, which searches specified query by word prefixes in the provided strings. Returns 0-based positions of strings that matched. Can be called synchronously. - * - *

Returns {@link FoundPositions FoundPositions}

- * - * @param strings The strings to search in for the query. - * @param query Query to search for. - * @param limit The maximum number of objects to return. - * @param returnNoneForEmptyQuery Pass true to receive no results for an empty query. - */ - public SearchStringsByPrefix(String[] strings, String query, int limit, boolean returnNoneForEmptyQuery) { - this.strings = strings; - this.query = query; - this.limit = limit; - this.returnNoneForEmptyQuery = returnNoneForEmptyQuery; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2023251463; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches a user by their phone number. Returns a 404 error if the user can't be found. - * - *

Returns {@link User User}

- */ - public static class SearchUserByPhoneNumber extends Function { - /** - * Phone number to search for. - */ - public String phoneNumber; - /** - * Pass true to get only locally available information without sending network requests. - */ - public boolean onlyLocal; - - /** - * Default constructor for a function, which searches a user by their phone number. Returns a 404 error if the user can't be found. - * - *

Returns {@link User User}

- */ - public SearchUserByPhoneNumber() { - } - - /** - * Creates a function, which searches a user by their phone number. Returns a 404 error if the user can't be found. - * - *

Returns {@link User User}

- * - * @param phoneNumber Phone number to search for. - * @param onlyLocal Pass true to get only locally available information without sending network requests. - */ - public SearchUserByPhoneNumber(String phoneNumber, boolean onlyLocal) { - this.phoneNumber = phoneNumber; - this.onlyLocal = onlyLocal; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -343757368; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Searches a user by a token from the user's link. - * - *

Returns {@link User User}

- */ - public static class SearchUserByToken extends Function { - /** - * Token to search for. - */ - public String token; - - /** - * Default constructor for a function, which searches a user by a token from the user's link. - * - *

Returns {@link User User}

- */ - public SearchUserByToken() { - } - - /** - * Creates a function, which searches a user by a token from the user's link. - * - *

Returns {@link User User}

- * - * @param token Token to search for. - */ - public SearchUserByToken(String token) { - this.token = token; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -666766282; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns information about a Web App by its short name. Returns a 404 error if the Web App is not found. - * - *

Returns {@link FoundWebApp FoundWebApp}

- */ - public static class SearchWebApp extends Function { - /** - * Identifier of the target bot. - */ - public long botUserId; - /** - * Short name of the Web App. - */ - public String webAppShortName; - - /** - * Default constructor for a function, which returns information about a Web App by its short name. Returns a 404 error if the Web App is not found. - * - *

Returns {@link FoundWebApp FoundWebApp}

- */ - public SearchWebApp() { - } - - /** - * Creates a function, which returns information about a Web App by its short name. Returns a 404 error if the Web App is not found. - * - *

Returns {@link FoundWebApp FoundWebApp}

- * - * @param botUserId Identifier of the target bot. - * @param webAppShortName Short name of the Web App. - */ - public SearchWebApp(long botUserId, String webAppShortName) { - this.botUserId = botUserId; - this.webAppShortName = webAppShortName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1241740747; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sells a gift for Telegram Stars; requires owner privileges for gifts owned by a chat. - * - *

Returns {@link Ok Ok}

- */ - public static class SellGift extends Function { - /** - * Unique identifier of business connection on behalf of which to send the request; for bots only. - */ - public String businessConnectionId; - /** - * Identifier of the gift. - */ - public String receivedGiftId; - - /** - * Default constructor for a function, which sells a gift for Telegram Stars; requires owner privileges for gifts owned by a chat. - * - *

Returns {@link Ok Ok}

- */ - public SellGift() { - } - - /** - * Creates a function, which sells a gift for Telegram Stars; requires owner privileges for gifts owned by a chat. - * - *

Returns {@link Ok Ok}

- * - * @param businessConnectionId Unique identifier of business connection on behalf of which to send the request; for bots only. - * @param receivedGiftId Identifier of the gift. - */ - public SellGift(String businessConnectionId, String receivedGiftId) { - this.businessConnectionId = businessConnectionId; - this.receivedGiftId = receivedGiftId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -298298375; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends Firebase Authentication SMS to the phone number of the user. Works only when the current authorization state is authorizationStateWaitCode and the server returned code of the type authenticationCodeTypeFirebaseAndroid or authenticationCodeTypeFirebaseIos. - * - *

Returns {@link Ok Ok}

- */ - public static class SendAuthenticationFirebaseSms extends Function { - /** - * Play Integrity API or SafetyNet Attestation API token for the Android application, or secret from push notification for the iOS application. - */ - public String token; - - /** - * Default constructor for a function, which sends Firebase Authentication SMS to the phone number of the user. Works only when the current authorization state is authorizationStateWaitCode and the server returned code of the type authenticationCodeTypeFirebaseAndroid or authenticationCodeTypeFirebaseIos. - * - *

Returns {@link Ok Ok}

- */ - public SendAuthenticationFirebaseSms() { - } - - /** - * Creates a function, which sends Firebase Authentication SMS to the phone number of the user. Works only when the current authorization state is authorizationStateWaitCode and the server returned code of the type authenticationCodeTypeFirebaseAndroid or authenticationCodeTypeFirebaseIos. - * - *

Returns {@link Ok Ok}

- * - * @param token Play Integrity API or SafetyNet Attestation API token for the Android application, or secret from push notification for the iOS application. - */ - public SendAuthenticationFirebaseSms(String token) { - this.token = token; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 364994111; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Invites a bot to a chat (if it is not yet a member) and sends it the /start command; requires canInviteUsers member right. Bots can't be invited to a private chat other than the chat with the bot. Bots can't be invited to channels (although they can be added as admins) and secret chats. Returns the sent message. - * - *

Returns {@link Message Message}

- */ - public static class SendBotStartMessage extends Function { - /** - * Identifier of the bot. - */ - public long botUserId; - /** - * Identifier of the target chat. - */ - public long chatId; - /** - * A hidden parameter sent to the bot for deep linking purposes (https://core.telegram.org/bots#deep-linking). - */ - public String parameter; - - /** - * Default constructor for a function, which invites a bot to a chat (if it is not yet a member) and sends it the /start command; requires canInviteUsers member right. Bots can't be invited to a private chat other than the chat with the bot. Bots can't be invited to channels (although they can be added as admins) and secret chats. Returns the sent message. - * - *

Returns {@link Message Message}

- */ - public SendBotStartMessage() { - } - - /** - * Creates a function, which invites a bot to a chat (if it is not yet a member) and sends it the /start command; requires canInviteUsers member right. Bots can't be invited to a private chat other than the chat with the bot. Bots can't be invited to channels (although they can be added as admins) and secret chats. Returns the sent message. - * - *

Returns {@link Message Message}

- * - * @param botUserId Identifier of the bot. - * @param chatId Identifier of the target chat. - * @param parameter A hidden parameter sent to the bot for deep linking purposes (https://core.telegram.org/bots#deep-linking). - */ - public SendBotStartMessage(long botUserId, long chatId, String parameter) { - this.botUserId = botUserId; - this.chatId = chatId; - this.parameter = parameter; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1435877650; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends a message on behalf of a business account; for bots only. Returns the message after it was sent. - * - *

Returns {@link BusinessMessage BusinessMessage}

- */ - public static class SendBusinessMessage extends Function { - /** - * Unique identifier of business connection on behalf of which to send the request. - */ - public String businessConnectionId; - /** - * Target chat. - */ - public long chatId; - /** - * Information about the message to be replied; pass null if none. - */ - public InputMessageReplyTo replyTo; - /** - * Pass true to disable notification for the message. - */ - public boolean disableNotification; - /** - * Pass true if the content of the message must be protected from forwarding and saving. - */ - public boolean protectContent; - /** - * Identifier of the effect to apply to the message. - */ - public long effectId; - /** - * Markup for replying to the message; pass null if none. - */ - public ReplyMarkup replyMarkup; - /** - * The content of the message to be sent. - */ - public InputMessageContent inputMessageContent; - - /** - * Default constructor for a function, which sends a message on behalf of a business account; for bots only. Returns the message after it was sent. - * - *

Returns {@link BusinessMessage BusinessMessage}

- */ - public SendBusinessMessage() { - } - - /** - * Creates a function, which sends a message on behalf of a business account; for bots only. Returns the message after it was sent. - * - *

Returns {@link BusinessMessage BusinessMessage}

- * - * @param businessConnectionId Unique identifier of business connection on behalf of which to send the request. - * @param chatId Target chat. - * @param replyTo Information about the message to be replied; pass null if none. - * @param disableNotification Pass true to disable notification for the message. - * @param protectContent Pass true if the content of the message must be protected from forwarding and saving. - * @param effectId Identifier of the effect to apply to the message. - * @param replyMarkup Markup for replying to the message; pass null if none. - * @param inputMessageContent The content of the message to be sent. - */ - public SendBusinessMessage(String businessConnectionId, long chatId, InputMessageReplyTo replyTo, boolean disableNotification, boolean protectContent, long effectId, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.businessConnectionId = businessConnectionId; - this.chatId = chatId; - this.replyTo = replyTo; - this.disableNotification = disableNotification; - this.protectContent = protectContent; - this.effectId = effectId; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 159888387; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends 2-10 messages grouped together into an album on behalf of a business account; for bots only. Currently, only audio, document, photo and video messages can be grouped into an album. Documents and audio files can be only grouped in an album with messages of the same type. Returns sent messages. - * - *

Returns {@link BusinessMessages BusinessMessages}

- */ - public static class SendBusinessMessageAlbum extends Function { - /** - * Unique identifier of business connection on behalf of which to send the request. - */ - public String businessConnectionId; - /** - * Target chat. - */ - public long chatId; - /** - * Information about the message to be replied; pass null if none. - */ - public InputMessageReplyTo replyTo; - /** - * Pass true to disable notification for the message. - */ - public boolean disableNotification; - /** - * Pass true if the content of the message must be protected from forwarding and saving. - */ - public boolean protectContent; - /** - * Identifier of the effect to apply to the message. - */ - public long effectId; - /** - * Contents of messages to be sent. At most 10 messages can be added to an album. All messages must have the same value of showCaptionAboveMedia. - */ - public InputMessageContent[] inputMessageContents; - - /** - * Default constructor for a function, which sends 2-10 messages grouped together into an album on behalf of a business account; for bots only. Currently, only audio, document, photo and video messages can be grouped into an album. Documents and audio files can be only grouped in an album with messages of the same type. Returns sent messages. - * - *

Returns {@link BusinessMessages BusinessMessages}

- */ - public SendBusinessMessageAlbum() { - } - - /** - * Creates a function, which sends 2-10 messages grouped together into an album on behalf of a business account; for bots only. Currently, only audio, document, photo and video messages can be grouped into an album. Documents and audio files can be only grouped in an album with messages of the same type. Returns sent messages. - * - *

Returns {@link BusinessMessages BusinessMessages}

- * - * @param businessConnectionId Unique identifier of business connection on behalf of which to send the request. - * @param chatId Target chat. - * @param replyTo Information about the message to be replied; pass null if none. - * @param disableNotification Pass true to disable notification for the message. - * @param protectContent Pass true if the content of the message must be protected from forwarding and saving. - * @param effectId Identifier of the effect to apply to the message. - * @param inputMessageContents Contents of messages to be sent. At most 10 messages can be added to an album. All messages must have the same value of showCaptionAboveMedia. - */ - public SendBusinessMessageAlbum(String businessConnectionId, long chatId, InputMessageReplyTo replyTo, boolean disableNotification, boolean protectContent, long effectId, InputMessageContent[] inputMessageContents) { - this.businessConnectionId = businessConnectionId; - this.chatId = chatId; - this.replyTo = replyTo; - this.disableNotification = disableNotification; - this.protectContent = protectContent; - this.effectId = effectId; - this.inputMessageContents = inputMessageContents; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 788608366; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends debug information for a call to Telegram servers. - * - *

Returns {@link Ok Ok}

- */ - public static class SendCallDebugInformation extends Function { - /** - * Call identifier. - */ - public InputCall callId; - /** - * Debug information in application-specific format. - */ - public String debugInformation; - - /** - * Default constructor for a function, which sends debug information for a call to Telegram servers. - * - *

Returns {@link Ok Ok}

- */ - public SendCallDebugInformation() { - } - - /** - * Creates a function, which sends debug information for a call to Telegram servers. - * - *

Returns {@link Ok Ok}

- * - * @param callId Call identifier. - * @param debugInformation Debug information in application-specific format. - */ - public SendCallDebugInformation(InputCall callId, String debugInformation) { - this.callId = callId; - this.debugInformation = debugInformation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1671879106; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends log file for a call to Telegram servers. - * - *

Returns {@link Ok Ok}

- */ - public static class SendCallLog extends Function { - /** - * Call identifier. - */ - public InputCall callId; - /** - * Call log file. Only inputFileLocal and inputFileGenerated are supported. - */ - public InputFile logFile; - - /** - * Default constructor for a function, which sends log file for a call to Telegram servers. - * - *

Returns {@link Ok Ok}

- */ - public SendCallLog() { - } - - /** - * Creates a function, which sends log file for a call to Telegram servers. - * - *

Returns {@link Ok Ok}

- * - * @param callId Call identifier. - * @param logFile Call log file. Only inputFileLocal and inputFileGenerated are supported. - */ - public SendCallLog(InputCall callId, InputFile logFile) { - this.callId = callId; - this.logFile = logFile; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -608809175; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends a call rating. - * - *

Returns {@link Ok Ok}

- */ - public static class SendCallRating extends Function { - /** - * Call identifier. - */ - public InputCall callId; - /** - * Call rating; 1-5. - */ - public int rating; - /** - * An optional user comment if the rating is less than 5. - */ - public String comment; - /** - * List of the exact types of problems with the call, specified by the user. - */ - public CallProblem[] problems; - - /** - * Default constructor for a function, which sends a call rating. - * - *

Returns {@link Ok Ok}

- */ - public SendCallRating() { - } - - /** - * Creates a function, which sends a call rating. - * - *

Returns {@link Ok Ok}

- * - * @param callId Call identifier. - * @param rating Call rating; 1-5. - * @param comment An optional user comment if the rating is less than 5. - * @param problems List of the exact types of problems with the call, specified by the user. - */ - public SendCallRating(InputCall callId, int rating, String comment, CallProblem[] problems) { - this.callId = callId; - this.rating = rating; - this.comment = comment; - this.problems = problems; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -158354447; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends call signaling data. - * - *

Returns {@link Ok Ok}

- */ - public static class SendCallSignalingData extends Function { - /** - * Call identifier. - */ - public int callId; - /** - * The data. - */ - public byte[] data; - - /** - * Default constructor for a function, which sends call signaling data. - * - *

Returns {@link Ok Ok}

- */ - public SendCallSignalingData() { - } - - /** - * Creates a function, which sends call signaling data. - * - *

Returns {@link Ok Ok}

- * - * @param callId Call identifier. - * @param data The data. - */ - public SendCallSignalingData(int callId, byte[] data) { - this.callId = callId; - this.data = data; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1412280732; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends a notification about user activity in a chat. - * - *

Returns {@link Ok Ok}

- */ - public static class SendChatAction extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the topic in which the action is performed; pass null if none. - */ - public MessageTopic topicId; - /** - * Unique identifier of business connection on behalf of which to send the request; for bots only. - */ - public String businessConnectionId; - /** - * The action description; pass null to cancel the currently active action. - */ - public ChatAction action; - - /** - * Default constructor for a function, which sends a notification about user activity in a chat. - * - *

Returns {@link Ok Ok}

- */ - public SendChatAction() { - } - - /** - * Creates a function, which sends a notification about user activity in a chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param topicId Identifier of the topic in which the action is performed; pass null if none. - * @param businessConnectionId Unique identifier of business connection on behalf of which to send the request; for bots only. - * @param action The action description; pass null to cancel the currently active action. - */ - public SendChatAction(long chatId, MessageTopic topicId, String businessConnectionId, ChatAction action) { - this.chatId = chatId; - this.topicId = topicId; - this.businessConnectionId = businessConnectionId; - this.action = action; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1586808788; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends a custom request; for bots only. - * - *

Returns {@link CustomRequestResult CustomRequestResult}

- */ - public static class SendCustomRequest extends Function { - /** - * The method name. - */ - public String method; - /** - * JSON-serialized method parameters. - */ - public String parameters; - - /** - * Default constructor for a function, which sends a custom request; for bots only. - * - *

Returns {@link CustomRequestResult CustomRequestResult}

- */ - public SendCustomRequest() { - } - - /** - * Creates a function, which sends a custom request; for bots only. - * - *

Returns {@link CustomRequestResult CustomRequestResult}

- * - * @param method The method name. - * @param parameters JSON-serialized method parameters. - */ - public SendCustomRequest(String method, String parameters) { - this.method = method; - this.parameters = parameters; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 285045153; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends a code to verify an email address to be added to a user's Telegram Passport. - * - *

Returns {@link EmailAddressAuthenticationCodeInfo EmailAddressAuthenticationCodeInfo}

- */ - public static class SendEmailAddressVerificationCode extends Function { - /** - * Email address. - */ - public String emailAddress; - - /** - * Default constructor for a function, which sends a code to verify an email address to be added to a user's Telegram Passport. - * - *

Returns {@link EmailAddressAuthenticationCodeInfo EmailAddressAuthenticationCodeInfo}

- */ - public SendEmailAddressVerificationCode() { - } - - /** - * Creates a function, which sends a code to verify an email address to be added to a user's Telegram Passport. - * - *

Returns {@link EmailAddressAuthenticationCodeInfo EmailAddressAuthenticationCodeInfo}

- * - * @param emailAddress Email address. - */ - public SendEmailAddressVerificationCode(String emailAddress) { - this.emailAddress = emailAddress; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -221621379; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends a gift to another user or channel chat. May return an error with a message "STARGIFT_USAGE_LIMITED" if the gift was sold out. - * - *

Returns {@link Ok Ok}

- */ - public static class SendGift extends Function { - /** - * Identifier of the gift to send. - */ - public long giftId; - /** - * Identifier of the user or the channel chat that will receive the gift; limited gifts can't be sent to channel chats. - */ - public MessageSender ownerId; - /** - * Text to show along with the gift; 0-getOption("gift_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed. Must be empty if the receiver enabled paid messages. - */ - public FormattedText text; - /** - * Pass true to show gift text and sender only to the gift receiver; otherwise, everyone will be able to see them. - */ - public boolean isPrivate; - /** - * Pass true to additionally pay for the gift upgrade and allow the receiver to upgrade it for free. - */ - public boolean payForUpgrade; - - /** - * Default constructor for a function, which sends a gift to another user or channel chat. May return an error with a message "STARGIFT_USAGE_LIMITED" if the gift was sold out. - * - *

Returns {@link Ok Ok}

- */ - public SendGift() { - } - - /** - * Creates a function, which sends a gift to another user or channel chat. May return an error with a message "STARGIFT_USAGE_LIMITED" if the gift was sold out. - * - *

Returns {@link Ok Ok}

- * - * @param giftId Identifier of the gift to send. - * @param ownerId Identifier of the user or the channel chat that will receive the gift; limited gifts can't be sent to channel chats. - * @param text Text to show along with the gift; 0-getOption("gift_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed. Must be empty if the receiver enabled paid messages. - * @param isPrivate Pass true to show gift text and sender only to the gift receiver; otherwise, everyone will be able to see them. - * @param payForUpgrade Pass true to additionally pay for the gift upgrade and allow the receiver to upgrade it for free. - */ - public SendGift(long giftId, MessageSender ownerId, FormattedText text, boolean isPrivate, boolean payForUpgrade) { - this.giftId = giftId; - this.ownerId = ownerId; - this.text = text; - this.isPrivate = isPrivate; - this.payForUpgrade = payForUpgrade; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1199356118; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends an offer to purchase an upgraded gift. - * - *

Returns {@link Ok Ok}

- */ - public static class SendGiftPurchaseOffer extends Function { - /** - * Identifier of the user or the channel chat that currently owns the gift and will receive the offer. - */ - public MessageSender ownerId; - /** - * Name of the upgraded gift. - */ - public String giftName; - /** - * The price that the user agreed to pay for the gift. - */ - public GiftResalePrice price; - /** - * Duration of the offer, in seconds; must be one of 21600, 43200, 86400, 129600, 172800, or 259200. Can also be 120 if Telegram test environment is used. - */ - public int duration; - /** - * The number of Telegram Stars the user agreed to pay additionally for sending of the offer message to the current gift owner; pass userFullInfo.outgoingPaidMessageStarCount for users and 0 otherwise. - */ - public long paidMessageStarCount; - - /** - * Default constructor for a function, which sends an offer to purchase an upgraded gift. - * - *

Returns {@link Ok Ok}

- */ - public SendGiftPurchaseOffer() { - } - - /** - * Creates a function, which sends an offer to purchase an upgraded gift. - * - *

Returns {@link Ok Ok}

- * - * @param ownerId Identifier of the user or the channel chat that currently owns the gift and will receive the offer. - * @param giftName Name of the upgraded gift. - * @param price The price that the user agreed to pay for the gift. - * @param duration Duration of the offer, in seconds; must be one of 21600, 43200, 86400, 129600, 172800, or 259200. Can also be 120 if Telegram test environment is used. - * @param paidMessageStarCount The number of Telegram Stars the user agreed to pay additionally for sending of the offer message to the current gift owner; pass userFullInfo.outgoingPaidMessageStarCount for users and 0 otherwise. - */ - public SendGiftPurchaseOffer(MessageSender ownerId, String giftName, GiftResalePrice price, int duration, long paidMessageStarCount) { - this.ownerId = ownerId; - this.giftName = giftName; - this.price = price; - this.duration = duration; - this.paidMessageStarCount = paidMessageStarCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 917878931; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends a message to other participants of a group call. Requires groupCall.canSendMessages right. - * - *

Returns {@link Ok Ok}

- */ - public static class SendGroupCallMessage extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Text of the message to send; 1-getOption("group_call_message_text_length_max") characters for non-live-stories; see updateGroupCallMessageLevels for live story restrictions, which depends on paidMessageStarCount. Can't contain line feeds for live stories. - */ - public FormattedText text; - /** - * The number of Telegram Stars the user agreed to pay to send the message; for live stories only; 0-getOption("paid_group_call_message_star_count_max"). Must be 0 for messages sent to live stories posted by the current user. - */ - public long paidMessageStarCount; - - /** - * Default constructor for a function, which sends a message to other participants of a group call. Requires groupCall.canSendMessages right. - * - *

Returns {@link Ok Ok}

- */ - public SendGroupCallMessage() { - } - - /** - * Creates a function, which sends a message to other participants of a group call. Requires groupCall.canSendMessages right. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param text Text of the message to send; 1-getOption("group_call_message_text_length_max") characters for non-live-stories; see updateGroupCallMessageLevels for live story restrictions, which depends on paidMessageStarCount. Can't contain line feeds for live stories. - * @param paidMessageStarCount The number of Telegram Stars the user agreed to pay to send the message; for live stories only; 0-getOption("paid_group_call_message_star_count_max"). Must be 0 for messages sent to live stories posted by the current user. - */ - public SendGroupCallMessage(int groupCallId, FormattedText text, long paidMessageStarCount) { - this.groupCallId = groupCallId; - this.text = text; - this.paidMessageStarCount = paidMessageStarCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2133590097; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends the result of an inline query as a message. Returns the sent message. Always clears a chat draft message. - * - *

Returns {@link Message Message}

- */ - public static class SendInlineQueryResultMessage extends Function { - /** - * Target chat. - */ - public long chatId; - /** - * Topic in which the message will be sent; pass null if none. - */ - public MessageTopic topicId; - /** - * Information about the message or story to be replied; pass null if none. - */ - public InputMessageReplyTo replyTo; - /** - * Options to be used to send the message; pass null to use default options. - */ - public MessageSendOptions options; - /** - * Identifier of the inline query. - */ - public long queryId; - /** - * Identifier of the inline query result. - */ - public String resultId; - /** - * Pass true to hide the bot, via which the message is sent. Can be used only for bots getOption("animation_search_bot_username"), getOption("photo_search_bot_username"), and getOption("venue_search_bot_username"). - */ - public boolean hideViaBot; - - /** - * Default constructor for a function, which sends the result of an inline query as a message. Returns the sent message. Always clears a chat draft message. - * - *

Returns {@link Message Message}

- */ - public SendInlineQueryResultMessage() { - } - - /** - * Creates a function, which sends the result of an inline query as a message. Returns the sent message. Always clears a chat draft message. - * - *

Returns {@link Message Message}

- * - * @param chatId Target chat. - * @param topicId Topic in which the message will be sent; pass null if none. - * @param replyTo Information about the message or story to be replied; pass null if none. - * @param options Options to be used to send the message; pass null to use default options. - * @param queryId Identifier of the inline query. - * @param resultId Identifier of the inline query result. - * @param hideViaBot Pass true to hide the bot, via which the message is sent. Can be used only for bots getOption("animation_search_bot_username"), getOption("photo_search_bot_username"), and getOption("venue_search_bot_username"). - */ - public SendInlineQueryResultMessage(long chatId, MessageTopic topicId, InputMessageReplyTo replyTo, MessageSendOptions options, long queryId, String resultId, boolean hideViaBot) { - this.chatId = chatId; - this.topicId = topicId; - this.replyTo = replyTo; - this.options = options; - this.queryId = queryId; - this.resultId = resultId; - this.hideViaBot = hideViaBot; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1445935970; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends a message. Returns the sent message. - * - *

Returns {@link Message Message}

- */ - public static class SendMessage extends Function { - /** - * Target chat. - */ - public long chatId; - /** - * Topic in which the message will be sent; pass null if none. - */ - public MessageTopic topicId; - /** - * Information about the message or story to be replied; pass null if none. - */ - public InputMessageReplyTo replyTo; - /** - * Options to be used to send the message; pass null to use default options. - */ - public MessageSendOptions options; - /** - * Markup for replying to the message; pass null if none; for bots only. - */ - public ReplyMarkup replyMarkup; - /** - * The content of the message to be sent. - */ - public InputMessageContent inputMessageContent; - - /** - * Default constructor for a function, which sends a message. Returns the sent message. - * - *

Returns {@link Message Message}

- */ - public SendMessage() { - } - - /** - * Creates a function, which sends a message. Returns the sent message. - * - *

Returns {@link Message Message}

- * - * @param chatId Target chat. - * @param topicId Topic in which the message will be sent; pass null if none. - * @param replyTo Information about the message or story to be replied; pass null if none. - * @param options Options to be used to send the message; pass null to use default options. - * @param replyMarkup Markup for replying to the message; pass null if none; for bots only. - * @param inputMessageContent The content of the message to be sent. - */ - public SendMessage(long chatId, MessageTopic topicId, InputMessageReplyTo replyTo, MessageSendOptions options, ReplyMarkup replyMarkup, InputMessageContent inputMessageContent) { - this.chatId = chatId; - this.topicId = topicId; - this.replyTo = replyTo; - this.options = options; - this.replyMarkup = replyMarkup; - this.inputMessageContent = inputMessageContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 964116012; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends 2-10 messages grouped together into an album. Currently, only audio, document, photo and video messages can be grouped into an album. Documents and audio files can be only grouped in an album with messages of the same type. Returns sent messages. - * - *

Returns {@link Messages Messages}

- */ - public static class SendMessageAlbum extends Function { - /** - * Target chat. - */ - public long chatId; - /** - * Topic in which the messages will be sent; pass null if none. - */ - public MessageTopic topicId; - /** - * Information about the message or story to be replied; pass null if none. - */ - public InputMessageReplyTo replyTo; - /** - * Options to be used to send the messages; pass null to use default options. - */ - public MessageSendOptions options; - /** - * Contents of messages to be sent. At most 10 messages can be added to an album. All messages must have the same value of showCaptionAboveMedia. - */ - public InputMessageContent[] inputMessageContents; - - /** - * Default constructor for a function, which sends 2-10 messages grouped together into an album. Currently, only audio, document, photo and video messages can be grouped into an album. Documents and audio files can be only grouped in an album with messages of the same type. Returns sent messages. - * - *

Returns {@link Messages Messages}

- */ - public SendMessageAlbum() { - } - - /** - * Creates a function, which sends 2-10 messages grouped together into an album. Currently, only audio, document, photo and video messages can be grouped into an album. Documents and audio files can be only grouped in an album with messages of the same type. Returns sent messages. - * - *

Returns {@link Messages Messages}

- * - * @param chatId Target chat. - * @param topicId Topic in which the messages will be sent; pass null if none. - * @param replyTo Information about the message or story to be replied; pass null if none. - * @param options Options to be used to send the messages; pass null to use default options. - * @param inputMessageContents Contents of messages to be sent. At most 10 messages can be added to an album. All messages must have the same value of showCaptionAboveMedia. - */ - public SendMessageAlbum(long chatId, MessageTopic topicId, InputMessageReplyTo replyTo, MessageSendOptions options, InputMessageContent[] inputMessageContents) { - this.chatId = chatId; - this.topicId = topicId; - this.replyTo = replyTo; - this.options = options; - this.inputMessageContents = inputMessageContents; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1488607732; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends a Telegram Passport authorization form, effectively sharing data with the service. This method must be called after getPassportAuthorizationFormAvailableElements if some previously available elements are going to be reused. - * - *

Returns {@link Ok Ok}

- */ - public static class SendPassportAuthorizationForm extends Function { - /** - * Authorization form identifier. - */ - public int authorizationFormId; - /** - * Types of Telegram Passport elements chosen by user to complete the authorization form. - */ - public PassportElementType[] types; - - /** - * Default constructor for a function, which sends a Telegram Passport authorization form, effectively sharing data with the service. This method must be called after getPassportAuthorizationFormAvailableElements if some previously available elements are going to be reused. - * - *

Returns {@link Ok Ok}

- */ - public SendPassportAuthorizationForm() { - } - - /** - * Creates a function, which sends a Telegram Passport authorization form, effectively sharing data with the service. This method must be called after getPassportAuthorizationFormAvailableElements if some previously available elements are going to be reused. - * - *

Returns {@link Ok Ok}

- * - * @param authorizationFormId Authorization form identifier. - * @param types Types of Telegram Passport elements chosen by user to complete the authorization form. - */ - public SendPassportAuthorizationForm(int authorizationFormId, PassportElementType[] types) { - this.authorizationFormId = authorizationFormId; - this.types = types; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 652160701; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends a filled-out payment form to the bot for final verification. - * - *

Returns {@link PaymentResult PaymentResult}

- */ - public static class SendPaymentForm extends Function { - /** - * The invoice. - */ - public InputInvoice inputInvoice; - /** - * Payment form identifier returned by getPaymentForm. - */ - public long paymentFormId; - /** - * Identifier returned by validateOrderInfo, or an empty string. - */ - public String orderInfoId; - /** - * Identifier of a chosen shipping option, if applicable. - */ - public String shippingOptionId; - /** - * The credentials chosen by user for payment; pass null for a payment in Telegram Stars. - */ - public InputCredentials credentials; - /** - * Chosen by the user amount of tip in the smallest units of the currency. - */ - public long tipAmount; - - /** - * Default constructor for a function, which sends a filled-out payment form to the bot for final verification. - * - *

Returns {@link PaymentResult PaymentResult}

- */ - public SendPaymentForm() { - } - - /** - * Creates a function, which sends a filled-out payment form to the bot for final verification. - * - *

Returns {@link PaymentResult PaymentResult}

- * - * @param inputInvoice The invoice. - * @param paymentFormId Payment form identifier returned by getPaymentForm. - * @param orderInfoId Identifier returned by validateOrderInfo, or an empty string. - * @param shippingOptionId Identifier of a chosen shipping option, if applicable. - * @param credentials The credentials chosen by user for payment; pass null for a payment in Telegram Stars. - * @param tipAmount Chosen by the user amount of tip in the smallest units of the currency. - */ - public SendPaymentForm(InputInvoice inputInvoice, long paymentFormId, String orderInfoId, String shippingOptionId, InputCredentials credentials, long tipAmount) { - this.inputInvoice = inputInvoice; - this.paymentFormId = paymentFormId; - this.orderInfoId = orderInfoId; - this.shippingOptionId = shippingOptionId; - this.credentials = credentials; - this.tipAmount = tipAmount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -965855094; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends a code to the specified phone number. Aborts previous phone number verification if there was one. On success, returns information about the sent code. - * - *

Returns {@link AuthenticationCodeInfo AuthenticationCodeInfo}

- */ - public static class SendPhoneNumberCode extends Function { - /** - * The phone number, in international format. - */ - public String phoneNumber; - /** - * Settings for the authentication of the user's phone number; pass null to use default settings. - */ - public PhoneNumberAuthenticationSettings settings; - /** - * Type of the request for which the code is sent. - */ - public PhoneNumberCodeType type; - - /** - * Default constructor for a function, which sends a code to the specified phone number. Aborts previous phone number verification if there was one. On success, returns information about the sent code. - * - *

Returns {@link AuthenticationCodeInfo AuthenticationCodeInfo}

- */ - public SendPhoneNumberCode() { - } - - /** - * Creates a function, which sends a code to the specified phone number. Aborts previous phone number verification if there was one. On success, returns information about the sent code. - * - *

Returns {@link AuthenticationCodeInfo AuthenticationCodeInfo}

- * - * @param phoneNumber The phone number, in international format. - * @param settings Settings for the authentication of the user's phone number; pass null to use default settings. - * @param type Type of the request for which the code is sent. - */ - public SendPhoneNumberCode(String phoneNumber, PhoneNumberAuthenticationSettings settings, PhoneNumberCodeType type) { - this.phoneNumber = phoneNumber; - this.settings = settings; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1084112144; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends Firebase Authentication SMS to the specified phone number. Works only when received a code of the type authenticationCodeTypeFirebaseAndroid or authenticationCodeTypeFirebaseIos. - * - *

Returns {@link Ok Ok}

- */ - public static class SendPhoneNumberFirebaseSms extends Function { - /** - * Play Integrity API or SafetyNet Attestation API token for the Android application, or secret from push notification for the iOS application. - */ - public String token; - - /** - * Default constructor for a function, which sends Firebase Authentication SMS to the specified phone number. Works only when received a code of the type authenticationCodeTypeFirebaseAndroid or authenticationCodeTypeFirebaseIos. - * - *

Returns {@link Ok Ok}

- */ - public SendPhoneNumberFirebaseSms() { - } - - /** - * Creates a function, which sends Firebase Authentication SMS to the specified phone number. Works only when received a code of the type authenticationCodeTypeFirebaseAndroid or authenticationCodeTypeFirebaseIos. - * - *

Returns {@link Ok Ok}

- * - * @param token Play Integrity API or SafetyNet Attestation API token for the Android application, or secret from push notification for the iOS application. - */ - public SendPhoneNumberFirebaseSms(String token) { - this.token = token; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 261910660; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends messages from a quick reply shortcut. Requires Telegram Business subscription. Can't be used to send paid messages. - * - *

Returns {@link Messages Messages}

- */ - public static class SendQuickReplyShortcutMessages extends Function { - /** - * Identifier of the chat to which to send messages. The chat must be a private chat with a regular user. - */ - public long chatId; - /** - * Unique identifier of the quick reply shortcut. - */ - public int shortcutId; - /** - * Non-persistent identifier, which will be returned back in messageSendingStatePending object and can be used to match sent messages and corresponding updateNewMessage updates. - */ - public int sendingId; - - /** - * Default constructor for a function, which sends messages from a quick reply shortcut. Requires Telegram Business subscription. Can't be used to send paid messages. - * - *

Returns {@link Messages Messages}

- */ - public SendQuickReplyShortcutMessages() { - } - - /** - * Creates a function, which sends messages from a quick reply shortcut. Requires Telegram Business subscription. Can't be used to send paid messages. - * - *

Returns {@link Messages Messages}

- * - * @param chatId Identifier of the chat to which to send messages. The chat must be a private chat with a regular user. - * @param shortcutId Unique identifier of the quick reply shortcut. - * @param sendingId Non-persistent identifier, which will be returned back in messageSendingStatePending object and can be used to match sent messages and corresponding updateNewMessage updates. - */ - public SendQuickReplyShortcutMessages(long chatId, int shortcutId, int sendingId) { - this.chatId = chatId; - this.shortcutId = shortcutId; - this.sendingId = sendingId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 232068765; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends an upgraded gift that is available for resale to another user or channel chat; gifts already owned by the current user must be transferred using transferGift and can't be passed to the method. - * - *

Returns {@link GiftResaleResult GiftResaleResult}

- */ - public static class SendResoldGift extends Function { - /** - * Name of the upgraded gift to send. - */ - public String giftName; - /** - * Identifier of the user or the channel chat that will receive the gift. - */ - public MessageSender ownerId; - /** - * The price that the user agreed to pay for the gift. - */ - public GiftResalePrice price; - - /** - * Default constructor for a function, which sends an upgraded gift that is available for resale to another user or channel chat; gifts already owned by the current user must be transferred using transferGift and can't be passed to the method. - * - *

Returns {@link GiftResaleResult GiftResaleResult}

- */ - public SendResoldGift() { - } - - /** - * Creates a function, which sends an upgraded gift that is available for resale to another user or channel chat; gifts already owned by the current user must be transferred using transferGift and can't be passed to the method. - * - *

Returns {@link GiftResaleResult GiftResaleResult}

- * - * @param giftName Name of the upgraded gift to send. - * @param ownerId Identifier of the user or the channel chat that will receive the gift. - * @param price The price that the user agreed to pay for the gift. - */ - public SendResoldGift(String giftName, MessageSender ownerId, GiftResalePrice price) { - this.giftName = giftName; - this.ownerId = ownerId; - this.price = price; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1427446834; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends a draft for a being generated text message; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class SendTextMessageDraft extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * The forum topic identifier in which the message will be sent; pass 0 if none. - */ - public int forumTopicId; - /** - * Unique identifier of the draft. - */ - public long draftId; - /** - * Draft text of the message. - */ - public FormattedText text; - - /** - * Default constructor for a function, which sends a draft for a being generated text message; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public SendTextMessageDraft() { - } - - /** - * Creates a function, which sends a draft for a being generated text message; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param forumTopicId The forum topic identifier in which the message will be sent; pass 0 if none. - * @param draftId Unique identifier of the draft. - * @param text Draft text of the message. - */ - public SendTextMessageDraft(long chatId, int forumTopicId, long draftId, FormattedText text) { - this.chatId = chatId; - this.forumTopicId = forumTopicId; - this.draftId = draftId; - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2121571326; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends a custom request from a Web App. - * - *

Returns {@link CustomRequestResult CustomRequestResult}

- */ - public static class SendWebAppCustomRequest extends Function { - /** - * Identifier of the bot. - */ - public long botUserId; - /** - * The method name. - */ - public String method; - /** - * JSON-serialized method parameters. - */ - public String parameters; - - /** - * Default constructor for a function, which sends a custom request from a Web App. - * - *

Returns {@link CustomRequestResult CustomRequestResult}

- */ - public SendWebAppCustomRequest() { - } - - /** - * Creates a function, which sends a custom request from a Web App. - * - *

Returns {@link CustomRequestResult CustomRequestResult}

- * - * @param botUserId Identifier of the bot. - * @param method The method name. - * @param parameters JSON-serialized method parameters. - */ - public SendWebAppCustomRequest(long botUserId, String method, String parameters) { - this.botUserId = botUserId; - this.method = method; - this.parameters = parameters; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 922705352; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends data received from a keyboardButtonTypeWebApp Web App to a bot. - * - *

Returns {@link Ok Ok}

- */ - public static class SendWebAppData extends Function { - /** - * Identifier of the target bot. - */ - public long botUserId; - /** - * Text of the keyboardButtonTypeWebApp button, which opened the Web App. - */ - public String buttonText; - /** - * The data. - */ - public String data; - - /** - * Default constructor for a function, which sends data received from a keyboardButtonTypeWebApp Web App to a bot. - * - *

Returns {@link Ok Ok}

- */ - public SendWebAppData() { - } - - /** - * Creates a function, which sends data received from a keyboardButtonTypeWebApp Web App to a bot. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId Identifier of the target bot. - * @param buttonText Text of the keyboardButtonTypeWebApp button, which opened the Web App. - * @param data The data. - */ - public SendWebAppData(long botUserId, String buttonText, String data) { - this.botUserId = botUserId; - this.buttonText = buttonText; - this.data = data; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1423978996; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes accent color and background custom emoji for the current user; for Telegram Premium users only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetAccentColor extends Function { - /** - * Identifier of the accent color to use. - */ - public int accentColorId; - /** - * Identifier of a custom emoji to be shown on the reply header and link preview background; 0 if none. - */ - public long backgroundCustomEmojiId; - - /** - * Default constructor for a function, which changes accent color and background custom emoji for the current user; for Telegram Premium users only. - * - *

Returns {@link Ok Ok}

- */ - public SetAccentColor() { - } - - /** - * Creates a function, which changes accent color and background custom emoji for the current user; for Telegram Premium users only. - * - *

Returns {@link Ok Ok}

- * - * @param accentColorId Identifier of the accent color to use. - * @param backgroundCustomEmojiId Identifier of a custom emoji to be shown on the reply header and link preview background; 0 if none. - */ - public SetAccentColor(int accentColorId, long backgroundCustomEmojiId) { - this.accentColorId = accentColorId; - this.backgroundCustomEmojiId = backgroundCustomEmojiId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1669974841; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the period of inactivity after which the account of the current user will automatically be deleted. - * - *

Returns {@link Ok Ok}

- */ - public static class SetAccountTtl extends Function { - /** - * New account TTL. - */ - public AccountTtl ttl; - - /** - * Default constructor for a function, which changes the period of inactivity after which the account of the current user will automatically be deleted. - * - *

Returns {@link Ok Ok}

- */ - public SetAccountTtl() { - } - - /** - * Creates a function, which changes the period of inactivity after which the account of the current user will automatically be deleted. - * - *

Returns {@link Ok Ok}

- * - * @param ttl New account TTL. - */ - public SetAccountTtl(AccountTtl ttl) { - this.ttl = ttl; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 701389032; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Succeeds after a specified amount of time has passed. Can be called before initialization. - * - *

Returns {@link Ok Ok}

- */ - public static class SetAlarm extends Function { - /** - * Number of seconds before the function returns. - */ - public double seconds; - - /** - * Default constructor for a function, which succeeds after a specified amount of time has passed. Can be called before initialization. - * - *

Returns {@link Ok Ok}

- */ - public SetAlarm() { - } - - /** - * Creates a function, which succeeds after a specified amount of time has passed. Can be called before initialization. - * - *

Returns {@link Ok Ok}

- * - * @param seconds Number of seconds before the function returns. - */ - public SetAlarm(double seconds) { - this.seconds = seconds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -873497067; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that application or reCAPTCHA verification has been completed. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class SetApplicationVerificationToken extends Function { - /** - * Unique identifier for the verification process as received from updateApplicationVerificationRequired or updateApplicationRecaptchaVerificationRequired. - */ - public long verificationId; - /** - * Play Integrity API token for the Android application, or secret from push notification for the iOS application for application verification, or reCAPTCHA token for reCAPTCHA verifications; pass an empty string to abort verification and receive the error "VERIFICATION_FAILED" for the request. - */ - public String token; - - /** - * Default constructor for a function, which informs TDLib that application or reCAPTCHA verification has been completed. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public SetApplicationVerificationToken() { - } - - /** - * Creates a function, which informs TDLib that application or reCAPTCHA verification has been completed. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- * - * @param verificationId Unique identifier for the verification process as received from updateApplicationVerificationRequired or updateApplicationRecaptchaVerificationRequired. - * @param token Play Integrity API token for the Android application, or secret from push notification for the iOS application for application verification, or reCAPTCHA token for reCAPTCHA verifications; pass an empty string to abort verification and receive the error "VERIFICATION_FAILED" for the request. - */ - public SetApplicationVerificationToken(long verificationId, String token) { - this.verificationId = verificationId; - this.token = token; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 927248261; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes settings for automatic moving of chats to and from the Archive chat lists. - * - *

Returns {@link Ok Ok}

- */ - public static class SetArchiveChatListSettings extends Function { - /** - * New settings. - */ - public ArchiveChatListSettings settings; - - /** - * Default constructor for a function, which changes settings for automatic moving of chats to and from the Archive chat lists. - * - *

Returns {@link Ok Ok}

- */ - public SetArchiveChatListSettings() { - } - - /** - * Creates a function, which changes settings for automatic moving of chats to and from the Archive chat lists. - * - *

Returns {@link Ok Ok}

- * - * @param settings New settings. - */ - public SetArchiveChatListSettings(ArchiveChatListSettings settings) { - this.settings = settings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -884650998; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets the email address of the user and sends an authentication code to the email address. Works only when the current authorization state is authorizationStateWaitEmailAddress. - * - *

Returns {@link Ok Ok}

- */ - public static class SetAuthenticationEmailAddress extends Function { - /** - * The email address of the user. - */ - public String emailAddress; - - /** - * Default constructor for a function, which sets the email address of the user and sends an authentication code to the email address. Works only when the current authorization state is authorizationStateWaitEmailAddress. - * - *

Returns {@link Ok Ok}

- */ - public SetAuthenticationEmailAddress() { - } - - /** - * Creates a function, which sets the email address of the user and sends an authentication code to the email address. Works only when the current authorization state is authorizationStateWaitEmailAddress. - * - *

Returns {@link Ok Ok}

- * - * @param emailAddress The email address of the user. - */ - public SetAuthenticationEmailAddress(String emailAddress) { - this.emailAddress = emailAddress; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1773323522; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets the phone number of the user and sends an authentication code to the user. Works only when the current authorization state is authorizationStateWaitPhoneNumber, or if there is no pending authentication query and the current authorization state is authorizationStateWaitPremiumPurchase, authorizationStateWaitEmailAddress, authorizationStateWaitEmailCode, authorizationStateWaitCode, authorizationStateWaitRegistration, or authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- */ - public static class SetAuthenticationPhoneNumber extends Function { - /** - * The phone number of the user, in international format. - */ - public String phoneNumber; - /** - * Settings for the authentication of the user's phone number; pass null to use default settings. - */ - public PhoneNumberAuthenticationSettings settings; - - /** - * Default constructor for a function, which sets the phone number of the user and sends an authentication code to the user. Works only when the current authorization state is authorizationStateWaitPhoneNumber, or if there is no pending authentication query and the current authorization state is authorizationStateWaitPremiumPurchase, authorizationStateWaitEmailAddress, authorizationStateWaitEmailCode, authorizationStateWaitCode, authorizationStateWaitRegistration, or authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- */ - public SetAuthenticationPhoneNumber() { - } - - /** - * Creates a function, which sets the phone number of the user and sends an authentication code to the user. Works only when the current authorization state is authorizationStateWaitPhoneNumber, or if there is no pending authentication query and the current authorization state is authorizationStateWaitPremiumPurchase, authorizationStateWaitEmailAddress, authorizationStateWaitEmailCode, authorizationStateWaitCode, authorizationStateWaitRegistration, or authorizationStateWaitPassword. - * - *

Returns {@link Ok Ok}

- * - * @param phoneNumber The phone number of the user, in international format. - * @param settings Settings for the authentication of the user's phone number; pass null to use default settings. - */ - public SetAuthenticationPhoneNumber(String phoneNumber, PhoneNumberAuthenticationSettings settings) { - this.phoneNumber = phoneNumber; - this.settings = settings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 868276259; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs server about an in-store purchase of Telegram Premium before authorization. Works only when the current authorization state is authorizationStateWaitPremiumPurchase. - * - *

Returns {@link Ok Ok}

- */ - public static class SetAuthenticationPremiumPurchaseTransaction extends Function { - /** - * Information about the transaction. - */ - public StoreTransaction transaction; - /** - * Pass true if this is a restore of a Telegram Premium purchase; only for App Store. - */ - public boolean isRestore; - /** - * ISO 4217 currency code of the payment currency. - */ - public String currency; - /** - * Paid amount, in the smallest units of the currency. - */ - public long amount; - - /** - * Default constructor for a function, which informs server about an in-store purchase of Telegram Premium before authorization. Works only when the current authorization state is authorizationStateWaitPremiumPurchase. - * - *

Returns {@link Ok Ok}

- */ - public SetAuthenticationPremiumPurchaseTransaction() { - } - - /** - * Creates a function, which informs server about an in-store purchase of Telegram Premium before authorization. Works only when the current authorization state is authorizationStateWaitPremiumPurchase. - * - *

Returns {@link Ok Ok}

- * - * @param transaction Information about the transaction. - * @param isRestore Pass true if this is a restore of a Telegram Premium purchase; only for App Store. - * @param currency ISO 4217 currency code of the payment currency. - * @param amount Paid amount, in the smallest units of the currency. - */ - public SetAuthenticationPremiumPurchaseTransaction(StoreTransaction transaction, boolean isRestore, String currency, long amount) { - this.transaction = transaction; - this.isRestore = isRestore; - this.currency = currency; - this.amount = amount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -450986887; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets auto-download settings. - * - *

Returns {@link Ok Ok}

- */ - public static class SetAutoDownloadSettings extends Function { - /** - * New user auto-download settings. - */ - public AutoDownloadSettings settings; - /** - * Type of the network for which the new settings are relevant. - */ - public NetworkType type; - - /** - * Default constructor for a function, which sets auto-download settings. - * - *

Returns {@link Ok Ok}

- */ - public SetAutoDownloadSettings() { - } - - /** - * Creates a function, which sets auto-download settings. - * - *

Returns {@link Ok Ok}

- * - * @param settings New user auto-download settings. - * @param type Type of the network for which the new settings are relevant. - */ - public SetAutoDownloadSettings(AutoDownloadSettings settings, NetworkType type) { - this.settings = settings; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -353671948; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets autosave settings for the given scope. The method is guaranteed to work only after at least one call to getAutosaveSettings. - * - *

Returns {@link Ok Ok}

- */ - public static class SetAutosaveSettings extends Function { - /** - * Autosave settings scope. - */ - public AutosaveSettingsScope scope; - /** - * New autosave settings for the scope; pass null to set autosave settings to default. - */ - public ScopeAutosaveSettings settings; - - /** - * Default constructor for a function, which sets autosave settings for the given scope. The method is guaranteed to work only after at least one call to getAutosaveSettings. - * - *

Returns {@link Ok Ok}

- */ - public SetAutosaveSettings() { - } - - /** - * Creates a function, which sets autosave settings for the given scope. The method is guaranteed to work only after at least one call to getAutosaveSettings. - * - *

Returns {@link Ok Ok}

- * - * @param scope Autosave settings scope. - * @param settings New autosave settings for the scope; pass null to set autosave settings to default. - */ - public SetAutosaveSettings(AutosaveSettingsScope scope, ScopeAutosaveSettings settings) { - this.scope = scope; - this.settings = settings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 6846656; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the bio of the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBio extends Function { - /** - * The new value of the user bio; 0-getOption("bio_length_max") characters without line feeds. - */ - public String bio; - - /** - * Default constructor for a function, which changes the bio of the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetBio() { - } - - /** - * Creates a function, which changes the bio of the current user. - * - *

Returns {@link Ok Ok}

- * - * @param bio The new value of the user bio; 0-getOption("bio_length_max") characters without line feeds. - */ - public SetBio(String bio) { - this.bio = bio; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1619582124; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the birthdate of the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBirthdate extends Function { - /** - * The new value of the current user's birthdate; pass null to remove the birthdate. - */ - public Birthdate birthdate; - - /** - * Default constructor for a function, which changes the birthdate of the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetBirthdate() { - } - - /** - * Creates a function, which changes the birthdate of the current user. - * - *

Returns {@link Ok Ok}

- * - * @param birthdate The new value of the current user's birthdate; pass null to remove the birthdate. - */ - public SetBirthdate(Birthdate birthdate) { - this.birthdate = birthdate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1319755160; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets the text shown in the chat with a bot if the chat is empty. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBotInfoDescription extends Function { - /** - * Identifier of the target bot. - */ - public long botUserId; - /** - * A two-letter ISO 639-1 language code. If empty, the description will be shown to all users for whose languages there is no dedicated description. - */ - public String languageCode; - /** - * New bot's description on the specified language. - */ - public String description; - - /** - * Default constructor for a function, which sets the text shown in the chat with a bot if the chat is empty. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- */ - public SetBotInfoDescription() { - } - - /** - * Creates a function, which sets the text shown in the chat with a bot if the chat is empty. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId Identifier of the target bot. - * @param languageCode A two-letter ISO 639-1 language code. If empty, the description will be shown to all users for whose languages there is no dedicated description. - * @param description New bot's description on the specified language. - */ - public SetBotInfoDescription(long botUserId, String languageCode, String description) { - this.botUserId = botUserId; - this.languageCode = languageCode; - this.description = description; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 693574984; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets the text shown on a bot's profile page and sent together with the link when users share the bot. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBotInfoShortDescription extends Function { - /** - * Identifier of the target bot. - */ - public long botUserId; - /** - * A two-letter ISO 639-1 language code. If empty, the short description will be shown to all users for whose languages there is no dedicated description. - */ - public String languageCode; - /** - * New bot's short description on the specified language. - */ - public String shortDescription; - - /** - * Default constructor for a function, which sets the text shown on a bot's profile page and sent together with the link when users share the bot. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- */ - public SetBotInfoShortDescription() { - } - - /** - * Creates a function, which sets the text shown on a bot's profile page and sent together with the link when users share the bot. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId Identifier of the target bot. - * @param languageCode A two-letter ISO 639-1 language code. If empty, the short description will be shown to all users for whose languages there is no dedicated description. - * @param shortDescription New bot's short description on the specified language. - */ - public SetBotInfoShortDescription(long botUserId, String languageCode, String shortDescription) { - this.botUserId = botUserId; - this.languageCode = languageCode; - this.shortDescription = shortDescription; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 982956771; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets the name of a bot. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBotName extends Function { - /** - * Identifier of the target bot. - */ - public long botUserId; - /** - * A two-letter ISO 639-1 language code. If empty, the name will be shown to all users for whose languages there is no dedicated name. - */ - public String languageCode; - /** - * New bot's name on the specified language; 0-64 characters; must be non-empty if language code is empty. - */ - public String name; - - /** - * Default constructor for a function, which sets the name of a bot. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- */ - public SetBotName() { - } - - /** - * Creates a function, which sets the name of a bot. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId Identifier of the target bot. - * @param languageCode A two-letter ISO 639-1 language code. If empty, the name will be shown to all users for whose languages there is no dedicated name. - * @param name New bot's name on the specified language; 0-64 characters; must be non-empty if language code is empty. - */ - public SetBotName(long botUserId, String languageCode, String name) { - this.botUserId = botUserId; - this.languageCode = languageCode; - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -761922959; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes a profile photo for a bot. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBotProfilePhoto extends Function { - /** - * Identifier of the target bot. - */ - public long botUserId; - /** - * Profile photo to set; pass null to delete the chat photo. - */ - public InputChatPhoto photo; - - /** - * Default constructor for a function, which changes a profile photo for a bot. - * - *

Returns {@link Ok Ok}

- */ - public SetBotProfilePhoto() { - } - - /** - * Creates a function, which changes a profile photo for a bot. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId Identifier of the target bot. - * @param photo Profile photo to set; pass null to delete the chat photo. - */ - public SetBotProfilePhoto(long botUserId, InputChatPhoto photo) { - this.botUserId = botUserId; - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1115272346; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs the server about the number of pending bot updates if they haven't been processed for a long time; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBotUpdatesStatus extends Function { - /** - * The number of pending updates. - */ - public int pendingUpdateCount; - /** - * The last error message. - */ - public String errorMessage; - - /** - * Default constructor for a function, which informs the server about the number of pending bot updates if they haven't been processed for a long time; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public SetBotUpdatesStatus() { - } - - /** - * Creates a function, which informs the server about the number of pending bot updates if they haven't been processed for a long time; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param pendingUpdateCount The number of pending updates. - * @param errorMessage The last error message. - */ - public SetBotUpdatesStatus(int pendingUpdateCount, String errorMessage) { - this.pendingUpdateCount = pendingUpdateCount; - this.errorMessage = errorMessage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1154926191; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the bio of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBusinessAccountBio extends Function { - /** - * Unique identifier of business connection. - */ - public String businessConnectionId; - /** - * The new value of the bio; 0-getOption("bio_length_max") characters without line feeds. - */ - public String bio; - - /** - * Default constructor for a function, which changes the bio of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public SetBusinessAccountBio() { - } - - /** - * Creates a function, which changes the bio of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param businessConnectionId Unique identifier of business connection. - * @param bio The new value of the bio; 0-getOption("bio_length_max") characters without line feeds. - */ - public SetBusinessAccountBio(String businessConnectionId, String bio) { - this.businessConnectionId = businessConnectionId; - this.bio = bio; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1698538041; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes settings for gift receiving of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBusinessAccountGiftSettings extends Function { - /** - * Unique identifier of business connection. - */ - public String businessConnectionId; - /** - * The new settings. - */ - public GiftSettings settings; - - /** - * Default constructor for a function, which changes settings for gift receiving of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public SetBusinessAccountGiftSettings() { - } - - /** - * Creates a function, which changes settings for gift receiving of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param businessConnectionId Unique identifier of business connection. - * @param settings The new settings. - */ - public SetBusinessAccountGiftSettings(String businessConnectionId, GiftSettings settings) { - this.businessConnectionId = businessConnectionId; - this.settings = settings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1757763090; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the first and last name of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBusinessAccountName extends Function { - /** - * Unique identifier of business connection. - */ - public String businessConnectionId; - /** - * The new value of the first name for the business account; 1-64 characters. - */ - public String firstName; - /** - * The new value of the optional last name for the business account; 0-64 characters. - */ - public String lastName; - - /** - * Default constructor for a function, which changes the first and last name of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public SetBusinessAccountName() { - } - - /** - * Creates a function, which changes the first and last name of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param businessConnectionId Unique identifier of business connection. - * @param firstName The new value of the first name for the business account; 1-64 characters. - * @param lastName The new value of the optional last name for the business account; 0-64 characters. - */ - public SetBusinessAccountName(String businessConnectionId, String firstName, String lastName) { - this.businessConnectionId = businessConnectionId; - this.firstName = firstName; - this.lastName = lastName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 999582546; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes a profile photo of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBusinessAccountProfilePhoto extends Function { - /** - * Unique identifier of business connection. - */ - public String businessConnectionId; - /** - * Profile photo to set; pass null to remove the photo. - */ - public InputChatPhoto photo; - /** - * Pass true to set the public photo, which will be visible even if the main photo is hidden by privacy settings. - */ - public boolean isPublic; - - /** - * Default constructor for a function, which changes a profile photo of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public SetBusinessAccountProfilePhoto() { - } - - /** - * Creates a function, which changes a profile photo of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param businessConnectionId Unique identifier of business connection. - * @param photo Profile photo to set; pass null to remove the photo. - * @param isPublic Pass true to set the public photo, which will be visible even if the main photo is hidden by privacy settings. - */ - public SetBusinessAccountProfilePhoto(String businessConnectionId, InputChatPhoto photo, boolean isPublic) { - this.businessConnectionId = businessConnectionId; - this.photo = photo; - this.isPublic = isPublic; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1174440149; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the editable username of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBusinessAccountUsername extends Function { - /** - * Unique identifier of business connection. - */ - public String businessConnectionId; - /** - * The new value of the username. - */ - public String username; - - /** - * Default constructor for a function, which changes the editable username of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public SetBusinessAccountUsername() { - } - - /** - * Creates a function, which changes the editable username of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param businessConnectionId Unique identifier of business connection. - * @param username The new value of the username. - */ - public SetBusinessAccountUsername(String businessConnectionId, String username) { - this.businessConnectionId = businessConnectionId; - this.username = username; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1520126367; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the business away message settings of the current user. Requires Telegram Business subscription. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBusinessAwayMessageSettings extends Function { - /** - * The new settings for the away message of the business; pass null to disable the away message. - */ - public BusinessAwayMessageSettings awayMessageSettings; - - /** - * Default constructor for a function, which changes the business away message settings of the current user. Requires Telegram Business subscription. - * - *

Returns {@link Ok Ok}

- */ - public SetBusinessAwayMessageSettings() { - } - - /** - * Creates a function, which changes the business away message settings of the current user. Requires Telegram Business subscription. - * - *

Returns {@link Ok Ok}

- * - * @param awayMessageSettings The new settings for the away message of the business; pass null to disable the away message. - */ - public SetBusinessAwayMessageSettings(BusinessAwayMessageSettings awayMessageSettings) { - this.awayMessageSettings = awayMessageSettings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1232357484; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds or changes business bot that is connected to the current user account. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBusinessConnectedBot extends Function { - /** - * Connection settings for the bot. - */ - public BusinessConnectedBot bot; - - /** - * Default constructor for a function, which adds or changes business bot that is connected to the current user account. - * - *

Returns {@link Ok Ok}

- */ - public SetBusinessConnectedBot() { - } - - /** - * Creates a function, which adds or changes business bot that is connected to the current user account. - * - *

Returns {@link Ok Ok}

- * - * @param bot Connection settings for the bot. - */ - public SetBusinessConnectedBot(BusinessConnectedBot bot) { - this.bot = bot; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1393459472; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the business greeting message settings of the current user. Requires Telegram Business subscription. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBusinessGreetingMessageSettings extends Function { - /** - * The new settings for the greeting message of the business; pass null to disable the greeting message. - */ - public BusinessGreetingMessageSettings greetingMessageSettings; - - /** - * Default constructor for a function, which changes the business greeting message settings of the current user. Requires Telegram Business subscription. - * - *

Returns {@link Ok Ok}

- */ - public SetBusinessGreetingMessageSettings() { - } - - /** - * Creates a function, which changes the business greeting message settings of the current user. Requires Telegram Business subscription. - * - *

Returns {@link Ok Ok}

- * - * @param greetingMessageSettings The new settings for the greeting message of the business; pass null to disable the greeting message. - */ - public SetBusinessGreetingMessageSettings(BusinessGreetingMessageSettings greetingMessageSettings) { - this.greetingMessageSettings = greetingMessageSettings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -873120707; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the business location of the current user. Requires Telegram Business subscription. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBusinessLocation extends Function { - /** - * The new location of the business; pass null to remove the location. - */ - public BusinessLocation location; - - /** - * Default constructor for a function, which changes the business location of the current user. Requires Telegram Business subscription. - * - *

Returns {@link Ok Ok}

- */ - public SetBusinessLocation() { - } - - /** - * Creates a function, which changes the business location of the current user. Requires Telegram Business subscription. - * - *

Returns {@link Ok Ok}

- * - * @param location The new location of the business; pass null to remove the location. - */ - public SetBusinessLocation(BusinessLocation location) { - this.location = location; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -344717547; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Pins or unpins a message sent on behalf of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBusinessMessageIsPinned extends Function { - /** - * Unique identifier of business connection on behalf of which the message was sent. - */ - public String businessConnectionId; - /** - * The chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * Pass true to pin the message, pass false to unpin it. - */ - public boolean isPinned; - - /** - * Default constructor for a function, which pins or unpins a message sent on behalf of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public SetBusinessMessageIsPinned() { - } - - /** - * Creates a function, which pins or unpins a message sent on behalf of a business account; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param businessConnectionId Unique identifier of business connection on behalf of which the message was sent. - * @param chatId The chat the message belongs to. - * @param messageId Identifier of the message. - * @param isPinned Pass true to pin the message, pass false to unpin it. - */ - public SetBusinessMessageIsPinned(String businessConnectionId, long chatId, long messageId, boolean isPinned) { - this.businessConnectionId = businessConnectionId; - this.chatId = chatId; - this.messageId = messageId; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -15403536; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the business opening hours of the current user. Requires Telegram Business subscription. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBusinessOpeningHours extends Function { - /** - * The new opening hours of the business; pass null to remove the opening hours; up to 28 time intervals can be specified. - */ - public BusinessOpeningHours openingHours; - - /** - * Default constructor for a function, which changes the business opening hours of the current user. Requires Telegram Business subscription. - * - *

Returns {@link Ok Ok}

- */ - public SetBusinessOpeningHours() { - } - - /** - * Creates a function, which changes the business opening hours of the current user. Requires Telegram Business subscription. - * - *

Returns {@link Ok Ok}

- * - * @param openingHours The new opening hours of the business; pass null to remove the opening hours; up to 28 time intervals can be specified. - */ - public SetBusinessOpeningHours(BusinessOpeningHours openingHours) { - this.openingHours = openingHours; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -462379918; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the business start page of the current user. Requires Telegram Business subscription. - * - *

Returns {@link Ok Ok}

- */ - public static class SetBusinessStartPage extends Function { - /** - * The new start page of the business; pass null to remove custom start page. - */ - public InputBusinessStartPage startPage; - - /** - * Default constructor for a function, which changes the business start page of the current user. Requires Telegram Business subscription. - * - *

Returns {@link Ok Ok}

- */ - public SetBusinessStartPage() { - } - - /** - * Creates a function, which changes the business start page of the current user. Requires Telegram Business subscription. - * - *

Returns {@link Ok Ok}

- * - * @param startPage The new start page of the business; pass null to remove custom start page. - */ - public SetBusinessStartPage(InputBusinessStartPage startPage) { - this.startPage = startPage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1628616290; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes accent color and background custom emoji of a channel chat. Requires canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatAccentColor extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the accent color to use. The chat must have at least accentColor.minChannelChatBoostLevel boost level to pass the corresponding color. - */ - public int accentColorId; - /** - * Identifier of a custom emoji to be shown on the reply header and link preview background; 0 if none. Use chatBoostLevelFeatures.canSetBackgroundCustomEmoji to check whether a custom emoji can be set. - */ - public long backgroundCustomEmojiId; - - /** - * Default constructor for a function, which changes accent color and background custom emoji of a channel chat. Requires canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- */ - public SetChatAccentColor() { - } - - /** - * Creates a function, which changes accent color and background custom emoji of a channel chat. Requires canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param accentColorId Identifier of the accent color to use. The chat must have at least accentColor.minChannelChatBoostLevel boost level to pass the corresponding color. - * @param backgroundCustomEmojiId Identifier of a custom emoji to be shown on the reply header and link preview background; 0 if none. Use chatBoostLevelFeatures.canSetBackgroundCustomEmoji to check whether a custom emoji can be set. - */ - public SetChatAccentColor(long chatId, int accentColorId, long backgroundCustomEmojiId) { - this.chatId = chatId; - this.accentColorId = accentColorId; - this.backgroundCustomEmojiId = backgroundCustomEmojiId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 882857930; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes story list in which stories from the chat are shown. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatActiveStoriesList extends Function { - /** - * Identifier of the chat that posted stories. - */ - public long chatId; - /** - * New list for active stories posted by the chat. - */ - public StoryList storyList; - - /** - * Default constructor for a function, which changes story list in which stories from the chat are shown. - * - *

Returns {@link Ok Ok}

- */ - public SetChatActiveStoriesList() { - } - - /** - * Creates a function, which changes story list in which stories from the chat are shown. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat that posted stories. - * @param storyList New list for active stories posted by the chat. - */ - public SetChatActiveStoriesList(long chatId, StoryList storyList) { - this.chatId = chatId; - this.storyList = storyList; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -521970415; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes affiliate program for a bot. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatAffiliateProgram extends Function { - /** - * Identifier of the chat with an owned bot for which affiliate program is changed. - */ - public long chatId; - /** - * Parameters of the affiliate program; pass null to close the currently active program. If there is an active program, then commission and program duration can only be increased. If the active program is scheduled to be closed, then it can't be changed anymore. - */ - public AffiliateProgramParameters parameters; - - /** - * Default constructor for a function, which changes affiliate program for a bot. - * - *

Returns {@link Ok Ok}

- */ - public SetChatAffiliateProgram() { - } - - /** - * Creates a function, which changes affiliate program for a bot. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat with an owned bot for which affiliate program is changed. - * @param parameters Parameters of the affiliate program; pass null to close the currently active program. If there is an active program, then commission and program duration can only be increased. If the active program is scheduled to be closed, then it can't be changed anymore. - */ - public SetChatAffiliateProgram(long chatId, AffiliateProgramParameters parameters) { - this.chatId = chatId; - this.parameters = parameters; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 14680631; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes reactions, available in a chat. Available for basic groups, supergroups, and channels. Requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatAvailableReactions extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * Reactions available in the chat. All explicitly specified emoji reactions must be active. In channel chats up to the chat's boost level custom emoji reactions can be explicitly specified. - */ - public ChatAvailableReactions availableReactions; - - /** - * Default constructor for a function, which changes reactions, available in a chat. Available for basic groups, supergroups, and channels. Requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- */ - public SetChatAvailableReactions() { - } - - /** - * Creates a function, which changes reactions, available in a chat. Available for basic groups, supergroups, and channels. Requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat. - * @param availableReactions Reactions available in the chat. All explicitly specified emoji reactions must be active. In channel chats up to the chat's boost level custom emoji reactions can be explicitly specified. - */ - public SetChatAvailableReactions(long chatId, ChatAvailableReactions availableReactions) { - this.chatId = chatId; - this.availableReactions = availableReactions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 267075078; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets the background in a specific chat. Supported only in private and secret chats with non-deleted users, and in chats with sufficient boost level and canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatBackground extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * The input background to use; pass null to create a new filled or chat theme background. - */ - public InputBackground background; - /** - * Background type; pass null to use default background type for the chosen background; backgroundTypeChatTheme isn't supported for private and secret chats. Use chatBoostLevelFeatures.chatThemeBackgroundCount and chatBoostLevelFeatures.canSetCustomBackground to check whether the background type can be set in the boosted chat. - */ - public BackgroundType type; - /** - * Dimming of the background in dark themes, as a percentage; 0-100. Applied only to Wallpaper and Fill types of background. - */ - public int darkThemeDimming; - /** - * Pass true to set background only for self; pass false to set background for all chat users. Always false for backgrounds set in boosted chats. Background can be set for both users only by Telegram Premium users and if set background isn't of the type inputBackgroundPrevious. - */ - public boolean onlyForSelf; - - /** - * Default constructor for a function, which sets the background in a specific chat. Supported only in private and secret chats with non-deleted users, and in chats with sufficient boost level and canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- */ - public SetChatBackground() { - } - - /** - * Creates a function, which sets the background in a specific chat. Supported only in private and secret chats with non-deleted users, and in chats with sufficient boost level and canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param background The input background to use; pass null to create a new filled or chat theme background. - * @param type Background type; pass null to use default background type for the chosen background; backgroundTypeChatTheme isn't supported for private and secret chats. Use chatBoostLevelFeatures.chatThemeBackgroundCount and chatBoostLevelFeatures.canSetCustomBackground to check whether the background type can be set in the boosted chat. - * @param darkThemeDimming Dimming of the background in dark themes, as a percentage; 0-100. Applied only to Wallpaper and Fill types of background. - * @param onlyForSelf Pass true to set background only for self; pass false to set background for all chat users. Always false for backgrounds set in boosted chats. Background can be set for both users only by Telegram Premium users and if set background isn't of the type inputBackgroundPrevious. - */ - public SetChatBackground(long chatId, InputBackground background, BackgroundType type, int darkThemeDimming, boolean onlyForSelf) { - this.chatId = chatId; - this.background = background; - this.type = type; - this.darkThemeDimming = darkThemeDimming; - this.onlyForSelf = onlyForSelf; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 246727678; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes application-specific data associated with a chat. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatClientData extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * New value of clientData. - */ - public String clientData; - - /** - * Default constructor for a function, which changes application-specific data associated with a chat. - * - *

Returns {@link Ok Ok}

- */ - public SetChatClientData() { - } - - /** - * Creates a function, which changes application-specific data associated with a chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param clientData New value of clientData. - */ - public SetChatClientData(long chatId, String clientData) { - this.chatId = chatId; - this.clientData = clientData; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -827119811; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes information about a chat. Available for basic groups, supergroups, and channels. Requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatDescription extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * New chat description; 0-255 characters. - */ - public String description; - - /** - * Default constructor for a function, which changes information about a chat. Available for basic groups, supergroups, and channels. Requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- */ - public SetChatDescription() { - } - - /** - * Creates a function, which changes information about a chat. Available for basic groups, supergroups, and channels. Requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat. - * @param description New chat description; 0-255 characters. - */ - public SetChatDescription(long chatId, String description) { - this.chatId = chatId; - this.description = description; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1957213277; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes direct messages group settings for a channel chat; requires owner privileges in the chat. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatDirectMessagesGroup extends Function { - /** - * Identifier of the channel chat. - */ - public long chatId; - /** - * Pass true if the direct messages group is enabled for the channel chat; pass false otherwise. - */ - public boolean isEnabled; - /** - * The new number of Telegram Stars that must be paid for each message that is sent to the direct messages chat unless the sender is an administrator of the channel chat; 0-getOption("paid_message_star_count_max"). The channel will receive getOption("paid_message_earnings_per_mille") Telegram Stars for each 1000 Telegram Stars paid for message sending. Requires supergroupFullInfo.canEnablePaidMessages for positive amounts. - */ - public long paidMessageStarCount; - - /** - * Default constructor for a function, which changes direct messages group settings for a channel chat; requires owner privileges in the chat. - * - *

Returns {@link Ok Ok}

- */ - public SetChatDirectMessagesGroup() { - } - - /** - * Creates a function, which changes direct messages group settings for a channel chat; requires owner privileges in the chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the channel chat. - * @param isEnabled Pass true if the direct messages group is enabled for the channel chat; pass false otherwise. - * @param paidMessageStarCount The new number of Telegram Stars that must be paid for each message that is sent to the direct messages chat unless the sender is an administrator of the channel chat; 0-getOption("paid_message_star_count_max"). The channel will receive getOption("paid_message_earnings_per_mille") Telegram Stars for each 1000 Telegram Stars paid for message sending. Requires supergroupFullInfo.canEnablePaidMessages for positive amounts. - */ - public SetChatDirectMessagesGroup(long chatId, boolean isEnabled, long paidMessageStarCount) { - this.chatId = chatId; - this.isEnabled = isEnabled; - this.paidMessageStarCount = paidMessageStarCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1633150115; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the discussion group of a channel chat; requires canChangeInfo administrator right in the channel if it is specified. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatDiscussionGroup extends Function { - /** - * Identifier of the channel chat. Pass 0 to remove a link from the supergroup passed in the second argument to a linked channel chat (requires canPinMessages member right in the supergroup). - */ - public long chatId; - /** - * Identifier of a new channel's discussion group. Use 0 to remove the discussion group. Use the method getSuitableDiscussionChats to find all suitable groups. Basic group chats must be first upgraded to supergroup chats. If new chat members don't have access to old messages in the supergroup, then toggleSupergroupIsAllHistoryAvailable must be used first to change that. - */ - public long discussionChatId; - - /** - * Default constructor for a function, which changes the discussion group of a channel chat; requires canChangeInfo administrator right in the channel if it is specified. - * - *

Returns {@link Ok Ok}

- */ - public SetChatDiscussionGroup() { - } - - /** - * Creates a function, which changes the discussion group of a channel chat; requires canChangeInfo administrator right in the channel if it is specified. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the channel chat. Pass 0 to remove a link from the supergroup passed in the second argument to a linked channel chat (requires canPinMessages member right in the supergroup). - * @param discussionChatId Identifier of a new channel's discussion group. Use 0 to remove the discussion group. Use the method getSuitableDiscussionChats to find all suitable groups. Basic group chats must be first upgraded to supergroup chats. If new chat members don't have access to old messages in the supergroup, then toggleSupergroupIsAllHistoryAvailable must be used first to change that. - */ - public SetChatDiscussionGroup(long chatId, long discussionChatId) { - this.chatId = chatId; - this.discussionChatId = discussionChatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -918801736; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the draft message in a chat or a topic. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatDraftMessage extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Topic in which the draft will be changed; pass null to change the draft for the chat itself. - */ - public MessageTopic topicId; - /** - * New draft message; pass null to remove the draft. All files in draft message content must be of the type inputFileLocal. Media thumbnails and captions are ignored. - */ - public DraftMessage draftMessage; - - /** - * Default constructor for a function, which changes the draft message in a chat or a topic. - * - *

Returns {@link Ok Ok}

- */ - public SetChatDraftMessage() { - } - - /** - * Creates a function, which changes the draft message in a chat or a topic. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param topicId Topic in which the draft will be changed; pass null to change the draft for the chat itself. - * @param draftMessage New draft message; pass null to remove the draft. All files in draft message content must be of the type inputFileLocal. Media thumbnails and captions are ignored. - */ - public SetChatDraftMessage(long chatId, MessageTopic topicId, DraftMessage draftMessage) { - this.chatId = chatId; - this.topicId = topicId; - this.draftMessage = draftMessage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -555614927; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the emoji status of a chat. Use chatBoostLevelFeatures.canSetEmojiStatus to check whether an emoji status can be set. Requires canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatEmojiStatus extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * New emoji status; pass null to remove emoji status. - */ - public EmojiStatus emojiStatus; - - /** - * Default constructor for a function, which changes the emoji status of a chat. Use chatBoostLevelFeatures.canSetEmojiStatus to check whether an emoji status can be set. Requires canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- */ - public SetChatEmojiStatus() { - } - - /** - * Creates a function, which changes the emoji status of a chat. Use chatBoostLevelFeatures.canSetEmojiStatus to check whether an emoji status can be set. Requires canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param emojiStatus New emoji status; pass null to remove emoji status. - */ - public SetChatEmojiStatus(long chatId, EmojiStatus emojiStatus) { - this.chatId = chatId; - this.emojiStatus = emojiStatus; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1434982674; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the location of a chat. Available only for some location-based supergroups, use supergroupFullInfo.canSetLocation to check whether the method is allowed to use. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatLocation extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * New location for the chat; must be valid and not null. - */ - public ChatLocation location; - - /** - * Default constructor for a function, which changes the location of a chat. Available only for some location-based supergroups, use supergroupFullInfo.canSetLocation to check whether the method is allowed to use. - * - *

Returns {@link Ok Ok}

- */ - public SetChatLocation() { - } - - /** - * Creates a function, which changes the location of a chat. Available only for some location-based supergroups, use supergroupFullInfo.canSetLocation to check whether the method is allowed to use. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param location New location for the chat; must be valid and not null. - */ - public SetChatLocation(long chatId, ChatLocation location) { - this.chatId = chatId; - this.location = location; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -767091286; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the status of a chat member; requires canInviteUsers member right to add a chat member, canPromoteMembers administrator right to change administrator rights of the member, and canRestrictMembers administrator right to change restrictions of a user. This function is currently not suitable for transferring chat ownership; use transferChatOwnership instead. Use addChatMember or banChatMember if some additional parameters needs to be passed. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatMemberStatus extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Member identifier. Chats can be only banned and unbanned in supergroups and channels. - */ - public MessageSender memberId; - /** - * The new status of the member in the chat. - */ - public ChatMemberStatus status; - - /** - * Default constructor for a function, which changes the status of a chat member; requires canInviteUsers member right to add a chat member, canPromoteMembers administrator right to change administrator rights of the member, and canRestrictMembers administrator right to change restrictions of a user. This function is currently not suitable for transferring chat ownership; use transferChatOwnership instead. Use addChatMember or banChatMember if some additional parameters needs to be passed. - * - *

Returns {@link Ok Ok}

- */ - public SetChatMemberStatus() { - } - - /** - * Creates a function, which changes the status of a chat member; requires canInviteUsers member right to add a chat member, canPromoteMembers administrator right to change administrator rights of the member, and canRestrictMembers administrator right to change restrictions of a user. This function is currently not suitable for transferring chat ownership; use transferChatOwnership instead. Use addChatMember or banChatMember if some additional parameters needs to be passed. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param memberId Member identifier. Chats can be only banned and unbanned in supergroups and channels. - * @param status The new status of the member in the chat. - */ - public SetChatMemberStatus(long chatId, MessageSender memberId, ChatMemberStatus status) { - this.chatId = chatId; - this.memberId = memberId; - this.status = status; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 81794847; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the tag or custom title of a chat member; requires canManageTags administrator right to change tag of other users; for basic groups and supergroups only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatMemberTag extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the user, which tag is changed. Chats can't have member tags. - */ - public long userId; - /** - * The new tag of the member in the chat; 0-16 characters without emoji. - */ - public String tag; - - /** - * Default constructor for a function, which changes the tag or custom title of a chat member; requires canManageTags administrator right to change tag of other users; for basic groups and supergroups only. - * - *

Returns {@link Ok Ok}

- */ - public SetChatMemberTag() { - } - - /** - * Creates a function, which changes the tag or custom title of a chat member; requires canManageTags administrator right to change tag of other users; for basic groups and supergroups only. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param userId Identifier of the user, which tag is changed. Chats can't have member tags. - * @param tag The new tag of the member in the chat; 0-16 characters without emoji. - */ - public SetChatMemberTag(long chatId, long userId, String tag) { - this.chatId = chatId; - this.userId = userId; - this.tag = tag; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 937859366; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the message auto-delete or self-destruct (for secret chats) time in a chat. Requires changeInfo administrator right in basic groups, supergroups and channels. Message auto-delete time can't be changed in a chat with the current user (Saved Messages) and the chat 777000 (Telegram). - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatMessageAutoDeleteTime extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * New time value, in seconds; unless the chat is secret, it must be from 0 up to 365 * 86400 and be divisible by 86400. If 0, then messages aren't deleted automatically. - */ - public int messageAutoDeleteTime; - - /** - * Default constructor for a function, which changes the message auto-delete or self-destruct (for secret chats) time in a chat. Requires changeInfo administrator right in basic groups, supergroups and channels. Message auto-delete time can't be changed in a chat with the current user (Saved Messages) and the chat 777000 (Telegram). - * - *

Returns {@link Ok Ok}

- */ - public SetChatMessageAutoDeleteTime() { - } - - /** - * Creates a function, which changes the message auto-delete or self-destruct (for secret chats) time in a chat. Requires changeInfo administrator right in basic groups, supergroups and channels. Message auto-delete time can't be changed in a chat with the current user (Saved Messages) and the chat 777000 (Telegram). - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param messageAutoDeleteTime New time value, in seconds; unless the chat is secret, it must be from 0 up to 365 * 86400 and be divisible by 86400. If 0, then messages aren't deleted automatically. - */ - public SetChatMessageAutoDeleteTime(long chatId, int messageAutoDeleteTime) { - this.chatId = chatId; - this.messageAutoDeleteTime = messageAutoDeleteTime; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1505643265; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Selects a message sender to send messages in a chat. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatMessageSender extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * New message sender for the chat. - */ - public MessageSender messageSenderId; - - /** - * Default constructor for a function, which selects a message sender to send messages in a chat. - * - *

Returns {@link Ok Ok}

- */ - public SetChatMessageSender() { - } - - /** - * Creates a function, which selects a message sender to send messages in a chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param messageSenderId New message sender for the chat. - */ - public SetChatMessageSender(long chatId, MessageSender messageSenderId) { - this.chatId = chatId; - this.messageSenderId = messageSenderId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1421513858; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the notification settings of a chat. Notification settings of a chat with the current user (Saved Messages) can't be changed. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatNotificationSettings extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * New notification settings for the chat. If the chat is muted for more than 366 days, it is considered to be muted forever. - */ - public ChatNotificationSettings notificationSettings; - - /** - * Default constructor for a function, which changes the notification settings of a chat. Notification settings of a chat with the current user (Saved Messages) can't be changed. - * - *

Returns {@link Ok Ok}

- */ - public SetChatNotificationSettings() { - } - - /** - * Creates a function, which changes the notification settings of a chat. Notification settings of a chat with the current user (Saved Messages) can't be changed. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param notificationSettings New notification settings for the chat. If the chat is muted for more than 366 days, it is considered to be muted forever. - */ - public SetChatNotificationSettings(long chatId, ChatNotificationSettings notificationSettings) { - this.chatId = chatId; - this.notificationSettings = notificationSettings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 777199614; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the Telegram Star amount that must be paid to send a message to a supergroup chat; requires canRestrictMembers administrator right and supergroupFullInfo.canEnablePaidMessages. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatPaidMessageStarCount extends Function { - /** - * Identifier of the supergroup chat. - */ - public long chatId; - /** - * The new number of Telegram Stars that must be paid for each message that is sent to the supergroup chat unless the sender is an administrator of the chat; 0-getOption("paid_message_star_count_max"). The supergroup will receive getOption("paid_message_earnings_per_mille") Telegram Stars for each 1000 Telegram Stars paid for message sending. - */ - public long paidMessageStarCount; - - /** - * Default constructor for a function, which changes the Telegram Star amount that must be paid to send a message to a supergroup chat; requires canRestrictMembers administrator right and supergroupFullInfo.canEnablePaidMessages. - * - *

Returns {@link Ok Ok}

- */ - public SetChatPaidMessageStarCount() { - } - - /** - * Creates a function, which changes the Telegram Star amount that must be paid to send a message to a supergroup chat; requires canRestrictMembers administrator right and supergroupFullInfo.canEnablePaidMessages. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the supergroup chat. - * @param paidMessageStarCount The new number of Telegram Stars that must be paid for each message that is sent to the supergroup chat unless the sender is an administrator of the chat; 0-getOption("paid_message_star_count_max"). The supergroup will receive getOption("paid_message_earnings_per_mille") Telegram Stars for each 1000 Telegram Stars paid for message sending. - */ - public SetChatPaidMessageStarCount(long chatId, long paidMessageStarCount) { - this.chatId = chatId; - this.paidMessageStarCount = paidMessageStarCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1187053289; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the chat members permissions. Supported only for basic groups and supergroups. Requires canRestrictMembers administrator right. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatPermissions extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * New non-administrator members permissions in the chat. - */ - public ChatPermissions permissions; - - /** - * Default constructor for a function, which changes the chat members permissions. Supported only for basic groups and supergroups. Requires canRestrictMembers administrator right. - * - *

Returns {@link Ok Ok}

- */ - public SetChatPermissions() { - } - - /** - * Creates a function, which changes the chat members permissions. Supported only for basic groups and supergroups. Requires canRestrictMembers administrator right. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param permissions New non-administrator members permissions in the chat. - */ - public SetChatPermissions(long chatId, ChatPermissions permissions) { - this.chatId = chatId; - this.permissions = permissions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2138507006; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the photo of a chat. Supported only for basic groups, supergroups and channels. Requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatPhoto extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * New chat photo; pass null to delete the chat photo. - */ - public InputChatPhoto photo; - - /** - * Default constructor for a function, which changes the photo of a chat. Supported only for basic groups, supergroups and channels. Requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- */ - public SetChatPhoto() { - } - - /** - * Creates a function, which changes the photo of a chat. Supported only for basic groups, supergroups and channels. Requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param photo New chat photo; pass null to delete the chat photo. - */ - public SetChatPhoto(long chatId, InputChatPhoto photo) { - this.chatId = chatId; - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -377778941; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the list of pinned stories on a chat page; requires canEditStories administrator right in the chat. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatPinnedStories extends Function { - /** - * Identifier of the chat that posted the stories. - */ - public long chatId; - /** - * New list of pinned stories. All stories must be posted to the chat page first. There can be up to getOption("pinned_story_count_max") pinned stories on a chat page. - */ - public int[] storyIds; - - /** - * Default constructor for a function, which changes the list of pinned stories on a chat page; requires canEditStories administrator right in the chat. - * - *

Returns {@link Ok Ok}

- */ - public SetChatPinnedStories() { - } - - /** - * Creates a function, which changes the list of pinned stories on a chat page; requires canEditStories administrator right in the chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat that posted the stories. - * @param storyIds New list of pinned stories. All stories must be posted to the chat page first. There can be up to getOption("pinned_story_count_max") pinned stories on a chat page. - */ - public SetChatPinnedStories(long chatId, int[] storyIds) { - this.chatId = chatId; - this.storyIds = storyIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -669062355; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes accent color and background custom emoji for profile of a supergroup or channel chat. Requires canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatProfileAccentColor extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the accent color to use for profile; pass -1 if none. The chat must have at least profileAccentColor.minSupergroupChatBoostLevel for supergroups or profileAccentColor.minChannelChatBoostLevel for channels boost level to pass the corresponding color. - */ - public int profileAccentColorId; - /** - * Identifier of a custom emoji to be shown on the chat's profile photo background; 0 if none. Use chatBoostLevelFeatures.canSetProfileBackgroundCustomEmoji to check whether a custom emoji can be set. - */ - public long profileBackgroundCustomEmojiId; - - /** - * Default constructor for a function, which changes accent color and background custom emoji for profile of a supergroup or channel chat. Requires canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- */ - public SetChatProfileAccentColor() { - } - - /** - * Creates a function, which changes accent color and background custom emoji for profile of a supergroup or channel chat. Requires canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param profileAccentColorId Identifier of the accent color to use for profile; pass -1 if none. The chat must have at least profileAccentColor.minSupergroupChatBoostLevel for supergroups or profileAccentColor.minChannelChatBoostLevel for channels boost level to pass the corresponding color. - * @param profileBackgroundCustomEmojiId Identifier of a custom emoji to be shown on the chat's profile photo background; 0 if none. Use chatBoostLevelFeatures.canSetProfileBackgroundCustomEmoji to check whether a custom emoji can be set. - */ - public SetChatProfileAccentColor(long chatId, int profileAccentColorId, long profileBackgroundCustomEmojiId) { - this.chatId = chatId; - this.profileAccentColorId = profileAccentColorId; - this.profileBackgroundCustomEmojiId = profileBackgroundCustomEmojiId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1109896826; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the slow mode delay of a chat. Available only for supergroups; requires canRestrictMembers administrator right. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatSlowModeDelay extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * New slow mode delay for the chat, in seconds; must be one of 0, 5, 10, 30, 60, 300, 900, 3600. - */ - public int slowModeDelay; - - /** - * Default constructor for a function, which changes the slow mode delay of a chat. Available only for supergroups; requires canRestrictMembers administrator right. - * - *

Returns {@link Ok Ok}

- */ - public SetChatSlowModeDelay() { - } - - /** - * Creates a function, which changes the slow mode delay of a chat. Available only for supergroups; requires canRestrictMembers administrator right. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param slowModeDelay New slow mode delay for the chat, in seconds; must be one of 0, 5, 10, 30, 60, 300, 900, 3600. - */ - public SetChatSlowModeDelay(long chatId, int slowModeDelay) { - this.chatId = chatId; - this.slowModeDelay = slowModeDelay; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -540350914; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the chat theme. Supported only in private and secret chats. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatTheme extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * New chat theme; pass null to return the default theme. - */ - public InputChatTheme theme; - - /** - * Default constructor for a function, which changes the chat theme. Supported only in private and secret chats. - * - *

Returns {@link Ok Ok}

- */ - public SetChatTheme() { - } - - /** - * Creates a function, which changes the chat theme. Supported only in private and secret chats. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param theme New chat theme; pass null to return the default theme. - */ - public SetChatTheme(long chatId, InputChatTheme theme) { - this.chatId = chatId; - this.theme = theme; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1474791506; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the chat title. Supported only for basic groups, supergroups and channels. Requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- */ - public static class SetChatTitle extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * New title of the chat; 1-128 characters. - */ - public String title; - - /** - * Default constructor for a function, which changes the chat title. Supported only for basic groups, supergroups and channels. Requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- */ - public SetChatTitle() { - } - - /** - * Creates a function, which changes the chat title. Supported only for basic groups, supergroups and channels. Requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param title New title of the chat; 1-128 characters. - */ - public SetChatTitle(long chatId, String title) { - this.chatId = chatId; - this.title = title; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 164282047; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the list of close friends of the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetCloseFriends extends Function { - /** - * User identifiers of close friends; the users must be contacts of the current user. - */ - public long[] userIds; - - /** - * Default constructor for a function, which changes the list of close friends of the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetCloseFriends() { - } - - /** - * Creates a function, which changes the list of close friends of the current user. - * - *

Returns {@link Ok Ok}

- * - * @param userIds User identifiers of close friends; the users must be contacts of the current user. - */ - public SetCloseFriends(long[] userIds) { - this.userIds = userIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1908013258; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets the list of commands supported by the bot for the given user scope and language; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetCommands extends Function { - /** - * The scope to which the commands are relevant; pass null to change commands in the default bot command scope. - */ - public BotCommandScope scope; - /** - * A two-letter ISO 639-1 language code. If empty, the commands will be applied to all users from the given scope, for which language there are no dedicated commands. - */ - public String languageCode; - /** - * List of the bot's commands. - */ - public BotCommand[] commands; - - /** - * Default constructor for a function, which sets the list of commands supported by the bot for the given user scope and language; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public SetCommands() { - } - - /** - * Creates a function, which sets the list of commands supported by the bot for the given user scope and language; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param scope The scope to which the commands are relevant; pass null to change commands in the default bot command scope. - * @param languageCode A two-letter ISO 639-1 language code. If empty, the commands will be applied to all users from the given scope, for which language there are no dedicated commands. - * @param commands List of the bot's commands. - */ - public SetCommands(BotCommandScope scope, String languageCode, BotCommand[] commands) { - this.scope = scope; - this.languageCode = languageCode; - this.commands = commands; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -907165606; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets a custom emoji sticker set thumbnail. - * - *

Returns {@link Ok Ok}

- */ - public static class SetCustomEmojiStickerSetThumbnail extends Function { - /** - * Sticker set name. The sticker set must be owned by the current user. - */ - public String name; - /** - * Identifier of the custom emoji from the sticker set, which will be set as sticker set thumbnail; pass 0 to remove the sticker set thumbnail. - */ - public long customEmojiId; - - /** - * Default constructor for a function, which sets a custom emoji sticker set thumbnail. - * - *

Returns {@link Ok Ok}

- */ - public SetCustomEmojiStickerSetThumbnail() { - } - - /** - * Creates a function, which sets a custom emoji sticker set thumbnail. - * - *

Returns {@link Ok Ok}

- * - * @param name Sticker set name. The sticker set must be owned by the current user. - * @param customEmojiId Identifier of the custom emoji from the sticker set, which will be set as sticker set thumbnail; pass 0 to remove the sticker set thumbnail. - */ - public SetCustomEmojiStickerSetThumbnail(String name, long customEmojiId) { - this.name = name; - this.customEmojiId = customEmojiId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1122836246; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds or changes a custom local language pack to the current localization target. - * - *

Returns {@link Ok Ok}

- */ - public static class SetCustomLanguagePack extends Function { - /** - * Information about the language pack. Language pack identifier must start with 'X', consist only of English letters, digits and hyphens, and must not exceed 64 characters. Can be called before authorization. - */ - public LanguagePackInfo info; - /** - * Strings of the new language pack. - */ - public LanguagePackString[] strings; - - /** - * Default constructor for a function, which adds or changes a custom local language pack to the current localization target. - * - *

Returns {@link Ok Ok}

- */ - public SetCustomLanguagePack() { - } - - /** - * Creates a function, which adds or changes a custom local language pack to the current localization target. - * - *

Returns {@link Ok Ok}

- * - * @param info Information about the language pack. Language pack identifier must start with 'X', consist only of English letters, digits and hyphens, and must not exceed 64 characters. Can be called before authorization. - * @param strings Strings of the new language pack. - */ - public SetCustomLanguagePack(LanguagePackInfo info, LanguagePackString[] strings) { - this.info = info; - this.strings = strings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -296742819; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds, edits or deletes a string in a custom local language pack. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class SetCustomLanguagePackString extends Function { - /** - * Identifier of a previously added custom local language pack in the current localization target. - */ - public String languagePackId; - /** - * New language pack string. - */ - public LanguagePackString newString; - - /** - * Default constructor for a function, which adds, edits or deletes a string in a custom local language pack. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public SetCustomLanguagePackString() { - } - - /** - * Creates a function, which adds, edits or deletes a string in a custom local language pack. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- * - * @param languagePackId Identifier of a previously added custom local language pack in the current localization target. - * @param newString New language pack string. - */ - public SetCustomLanguagePackString(String languagePackId, LanguagePackString newString) { - this.languagePackId = languagePackId; - this.newString = newString; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1316365592; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the database encryption key. Usually the encryption key is never changed and is stored in some OS keychain. - * - *

Returns {@link Ok Ok}

- */ - public static class SetDatabaseEncryptionKey extends Function { - /** - * New encryption key. - */ - public byte[] newEncryptionKey; - - /** - * Default constructor for a function, which changes the database encryption key. Usually the encryption key is never changed and is stored in some OS keychain. - * - *

Returns {@link Ok Ok}

- */ - public SetDatabaseEncryptionKey() { - } - - /** - * Creates a function, which changes the database encryption key. Usually the encryption key is never changed and is stored in some OS keychain. - * - *

Returns {@link Ok Ok}

- * - * @param newEncryptionKey New encryption key. - */ - public SetDatabaseEncryptionKey(byte[] newEncryptionKey) { - this.newEncryptionKey = newEncryptionKey; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1204599371; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets default background for chats; adds the background to the list of installed backgrounds. - * - *

Returns {@link Background Background}

- */ - public static class SetDefaultBackground extends Function { - /** - * The input background to use; pass null to create a new filled background. - */ - public InputBackground background; - /** - * Background type; pass null to use the default type of the remote background; backgroundTypeChatTheme isn't supported. - */ - public BackgroundType type; - /** - * Pass true if the background is set for a dark theme. - */ - public boolean forDarkTheme; - - /** - * Default constructor for a function, which sets default background for chats; adds the background to the list of installed backgrounds. - * - *

Returns {@link Background Background}

- */ - public SetDefaultBackground() { - } - - /** - * Creates a function, which sets default background for chats; adds the background to the list of installed backgrounds. - * - *

Returns {@link Background Background}

- * - * @param background The input background to use; pass null to create a new filled background. - * @param type Background type; pass null to use the default type of the remote background; backgroundTypeChatTheme isn't supported. - * @param forDarkTheme Pass true if the background is set for a dark theme. - */ - public SetDefaultBackground(InputBackground background, BackgroundType type, boolean forDarkTheme) { - this.background = background; - this.type = type; - this.forDarkTheme = forDarkTheme; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1982748511; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets default administrator rights for adding the bot to channel chats; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetDefaultChannelAdministratorRights extends Function { - /** - * Default administrator rights for adding the bot to channels; pass null to remove default rights. - */ - public ChatAdministratorRights defaultChannelAdministratorRights; - - /** - * Default constructor for a function, which sets default administrator rights for adding the bot to channel chats; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public SetDefaultChannelAdministratorRights() { - } - - /** - * Creates a function, which sets default administrator rights for adding the bot to channel chats; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param defaultChannelAdministratorRights Default administrator rights for adding the bot to channels; pass null to remove default rights. - */ - public SetDefaultChannelAdministratorRights(ChatAdministratorRights defaultChannelAdministratorRights) { - this.defaultChannelAdministratorRights = defaultChannelAdministratorRights; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -234004967; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets default administrator rights for adding the bot to basic group and supergroup chats; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetDefaultGroupAdministratorRights extends Function { - /** - * Default administrator rights for adding the bot to basic group and supergroup chats; pass null to remove default rights. - */ - public ChatAdministratorRights defaultGroupAdministratorRights; - - /** - * Default constructor for a function, which sets default administrator rights for adding the bot to basic group and supergroup chats; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public SetDefaultGroupAdministratorRights() { - } - - /** - * Creates a function, which sets default administrator rights for adding the bot to basic group and supergroup chats; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param defaultGroupAdministratorRights Default administrator rights for adding the bot to basic group and supergroup chats; pass null to remove default rights. - */ - public SetDefaultGroupAdministratorRights(ChatAdministratorRights defaultGroupAdministratorRights) { - this.defaultGroupAdministratorRights = defaultGroupAdministratorRights; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1700231016; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the default message auto-delete time for new chats. - * - *

Returns {@link Ok Ok}

- */ - public static class SetDefaultMessageAutoDeleteTime extends Function { - /** - * New default message auto-delete time; must be from 0 up to 365 * 86400 and be divisible by 86400. If 0, then messages aren't deleted automatically. - */ - public MessageAutoDeleteTime messageAutoDeleteTime; - - /** - * Default constructor for a function, which changes the default message auto-delete time for new chats. - * - *

Returns {@link Ok Ok}

- */ - public SetDefaultMessageAutoDeleteTime() { - } - - /** - * Creates a function, which changes the default message auto-delete time for new chats. - * - *

Returns {@link Ok Ok}

- * - * @param messageAutoDeleteTime New default message auto-delete time; must be from 0 up to 365 * 86400 and be divisible by 86400. If 0, then messages aren't deleted automatically. - */ - public SetDefaultMessageAutoDeleteTime(MessageAutoDeleteTime messageAutoDeleteTime) { - this.messageAutoDeleteTime = messageAutoDeleteTime; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1772301460; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes type of default reaction for the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetDefaultReactionType extends Function { - /** - * New type of the default reaction. The paid reaction can't be set as default. - */ - public ReactionType reactionType; - - /** - * Default constructor for a function, which changes type of default reaction for the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetDefaultReactionType() { - } - - /** - * Creates a function, which changes type of default reaction for the current user. - * - *

Returns {@link Ok Ok}

- * - * @param reactionType New type of the default reaction. The paid reaction can't be set as default. - */ - public SetDefaultReactionType(ReactionType reactionType) { - this.reactionType = reactionType; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1694730813; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the marked as unread state of the topic in a channel direct messages chat administered by the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetDirectMessagesChatTopicIsMarkedAsUnread extends Function { - /** - * Chat identifier of the channel direct messages chat. - */ - public long chatId; - /** - * Topic identifier. - */ - public long topicId; - /** - * New value of isMarkedAsUnread. - */ - public boolean isMarkedAsUnread; - - /** - * Default constructor for a function, which changes the marked as unread state of the topic in a channel direct messages chat administered by the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetDirectMessagesChatTopicIsMarkedAsUnread() { - } - - /** - * Creates a function, which changes the marked as unread state of the topic in a channel direct messages chat administered by the current user. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier of the channel direct messages chat. - * @param topicId Topic identifier. - * @param isMarkedAsUnread New value of isMarkedAsUnread. - */ - public SetDirectMessagesChatTopicIsMarkedAsUnread(long chatId, long topicId, boolean isMarkedAsUnread) { - this.chatId = chatId; - this.topicId = topicId; - this.isMarkedAsUnread = isMarkedAsUnread; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1569655059; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the emoji status of the current user; for Telegram Premium users only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetEmojiStatus extends Function { - /** - * New emoji status; pass null to switch to the default badge. - */ - public EmojiStatus emojiStatus; - - /** - * Default constructor for a function, which changes the emoji status of the current user; for Telegram Premium users only. - * - *

Returns {@link Ok Ok}

- */ - public SetEmojiStatus() { - } - - /** - * Creates a function, which changes the emoji status of the current user; for Telegram Premium users only. - * - *

Returns {@link Ok Ok}

- * - * @param emojiStatus New emoji status; pass null to switch to the default badge. - */ - public SetEmojiStatus(EmojiStatus emojiStatus) { - this.emojiStatus = emojiStatus; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1829224867; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib on a file generation progress. - * - *

Returns {@link Ok Ok}

- */ - public static class SetFileGenerationProgress extends Function { - /** - * The identifier of the generation process. - */ - public long generationId; - /** - * Expected size of the generated file, in bytes; 0 if unknown. - */ - public long expectedSize; - /** - * The number of bytes already generated. - */ - public long localPrefixSize; - - /** - * Default constructor for a function, which informs TDLib on a file generation progress. - * - *

Returns {@link Ok Ok}

- */ - public SetFileGenerationProgress() { - } - - /** - * Creates a function, which informs TDLib on a file generation progress. - * - *

Returns {@link Ok Ok}

- * - * @param generationId The identifier of the generation process. - * @param expectedSize Expected size of the generated file, in bytes; 0 if unknown. - * @param localPrefixSize The number of bytes already generated. - */ - public SetFileGenerationProgress(long generationId, long expectedSize, long localPrefixSize) { - this.generationId = generationId; - this.expectedSize = expectedSize; - this.localPrefixSize = localPrefixSize; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1836403518; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the notification settings of a forum topic in a forum supergroup chat or a chat with a bot with topics. - * - *

Returns {@link Ok Ok}

- */ - public static class SetForumTopicNotificationSettings extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Forum topic identifier. - */ - public int forumTopicId; - /** - * New notification settings for the forum topic. If the topic is muted for more than 366 days, it is considered to be muted forever. - */ - public ChatNotificationSettings notificationSettings; - - /** - * Default constructor for a function, which changes the notification settings of a forum topic in a forum supergroup chat or a chat with a bot with topics. - * - *

Returns {@link Ok Ok}

- */ - public SetForumTopicNotificationSettings() { - } - - /** - * Creates a function, which changes the notification settings of a forum topic in a forum supergroup chat or a chat with a bot with topics. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param forumTopicId Forum topic identifier. - * @param notificationSettings New notification settings for the forum topic. If the topic is muted for more than 366 days, it is considered to be muted forever. - */ - public SetForumTopicNotificationSettings(long chatId, int forumTopicId, ChatNotificationSettings notificationSettings) { - this.chatId = chatId; - this.forumTopicId = forumTopicId; - this.notificationSettings = notificationSettings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1989500300; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Updates the game score of the specified user in the game; for bots only. - * - *

Returns {@link Message Message}

- */ - public static class SetGameScore extends Function { - /** - * The chat to which the message with the game belongs. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * Pass true to edit the game message to include the current scoreboard. - */ - public boolean editMessage; - /** - * User identifier. - */ - public long userId; - /** - * The new score. - */ - public int score; - /** - * Pass true to update the score even if it decreases. If the score is 0, the user will be deleted from the high score table. - */ - public boolean force; - - /** - * Default constructor for a function, which updates the game score of the specified user in the game; for bots only. - * - *

Returns {@link Message Message}

- */ - public SetGameScore() { - } - - /** - * Creates a function, which updates the game score of the specified user in the game; for bots only. - * - *

Returns {@link Message Message}

- * - * @param chatId The chat to which the message with the game belongs. - * @param messageId Identifier of the message. - * @param editMessage Pass true to edit the game message to include the current scoreboard. - * @param userId User identifier. - * @param score The new score. - * @param force Pass true to update the score even if it decreases. If the score is 0, the user will be deleted from the high score table. - */ - public SetGameScore(long chatId, long messageId, boolean editMessage, long userId, int score, boolean force) { - this.chatId = chatId; - this.messageId = messageId; - this.editMessage = editMessage; - this.userId = userId; - this.score = score; - this.force = force; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2127359430; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes name of a gift collection. If the collection is owned by a channel chat, then requires canPostMessages administrator right in the channel chat. Returns the changed collection. - * - *

Returns {@link GiftCollection GiftCollection}

- */ - public static class SetGiftCollectionName extends Function { - /** - * Identifier of the user or the channel chat that owns the collection. - */ - public MessageSender ownerId; - /** - * Identifier of the gift collection. - */ - public int collectionId; - /** - * New name of the collection; 1-12 characters. - */ - public String name; - - /** - * Default constructor for a function, which changes name of a gift collection. If the collection is owned by a channel chat, then requires canPostMessages administrator right in the channel chat. Returns the changed collection. - * - *

Returns {@link GiftCollection GiftCollection}

- */ - public SetGiftCollectionName() { - } - - /** - * Creates a function, which changes name of a gift collection. If the collection is owned by a channel chat, then requires canPostMessages administrator right in the channel chat. Returns the changed collection. - * - *

Returns {@link GiftCollection GiftCollection}

- * - * @param ownerId Identifier of the user or the channel chat that owns the collection. - * @param collectionId Identifier of the gift collection. - * @param name New name of the collection; 1-12 characters. - */ - public SetGiftCollectionName(MessageSender ownerId, int collectionId, String name) { - this.ownerId = ownerId; - this.collectionId = collectionId; - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1108355593; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes resale price of a unique gift owned by the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetGiftResalePrice extends Function { - /** - * Identifier of the unique gift. - */ - public String receivedGiftId; - /** - * The new price for the unique gift; pass null to disallow gift resale. The current user will receive getOption("gift_resale_star_earnings_per_mille") Telegram Stars for each 1000 Telegram Stars paid for the gift if the gift price is in Telegram Stars or getOption("gift_resale_ton_earnings_per_mille") Toncoins for each 1000 Toncoins paid for the gift if the gift price is in Toncoins. - */ - public GiftResalePrice price; - - /** - * Default constructor for a function, which changes resale price of a unique gift owned by the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetGiftResalePrice() { - } - - /** - * Creates a function, which changes resale price of a unique gift owned by the current user. - * - *

Returns {@link Ok Ok}

- * - * @param receivedGiftId Identifier of the unique gift. - * @param price The new price for the unique gift; pass null to disallow gift resale. The current user will receive getOption("gift_resale_star_earnings_per_mille") Telegram Stars for each 1000 Telegram Stars paid for the gift if the gift price is in Telegram Stars or getOption("gift_resale_ton_earnings_per_mille") Toncoins for each 1000 Toncoins paid for the gift if the gift price is in Toncoins. - */ - public SetGiftResalePrice(String receivedGiftId, GiftResalePrice price) { - this.receivedGiftId = receivedGiftId; - this.price = price; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 373916170; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes settings for gift receiving for the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetGiftSettings extends Function { - /** - * The new settings. - */ - public GiftSettings settings; - - /** - * Default constructor for a function, which changes settings for gift receiving for the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetGiftSettings() { - } - - /** - * Creates a function, which changes settings for gift receiving for the current user. - * - *

Returns {@link Ok Ok}

- * - * @param settings The new settings. - */ - public SetGiftSettings(GiftSettings settings) { - this.settings = settings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -519330046; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the minimum number of Telegram Stars that must be paid by general participant for each sent message to a live story call. Requires groupCall.canBeManaged right. - * - *

Returns {@link Ok Ok}

- */ - public static class SetGroupCallPaidMessageStarCount extends Function { - /** - * Group call identifier; must be an identifier of a live story call. - */ - public int groupCallId; - /** - * The new minimum number of Telegram Stars; 0-getOption("paid_group_call_message_star_count_max"). - */ - public long paidMessageStarCount; - - /** - * Default constructor for a function, which changes the minimum number of Telegram Stars that must be paid by general participant for each sent message to a live story call. Requires groupCall.canBeManaged right. - * - *

Returns {@link Ok Ok}

- */ - public SetGroupCallPaidMessageStarCount() { - } - - /** - * Creates a function, which changes the minimum number of Telegram Stars that must be paid by general participant for each sent message to a live story call. Requires groupCall.canBeManaged right. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier; must be an identifier of a live story call. - * @param paidMessageStarCount The new minimum number of Telegram Stars; 0-getOption("paid_group_call_message_star_count_max"). - */ - public SetGroupCallPaidMessageStarCount(int groupCallId, long paidMessageStarCount) { - this.groupCallId = groupCallId; - this.paidMessageStarCount = paidMessageStarCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1764341527; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that speaking state of a participant of an active group call has changed. Returns identifier of the participant if it is found. - * - *

Returns {@link MessageSender MessageSender}

- */ - public static class SetGroupCallParticipantIsSpeaking extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Group call participant's synchronization audio source identifier, or 0 for the current user. - */ - public int audioSource; - /** - * Pass true if the user is speaking. - */ - public boolean isSpeaking; - - /** - * Default constructor for a function, which informs TDLib that speaking state of a participant of an active group call has changed. Returns identifier of the participant if it is found. - * - *

Returns {@link MessageSender MessageSender}

- */ - public SetGroupCallParticipantIsSpeaking() { - } - - /** - * Creates a function, which informs TDLib that speaking state of a participant of an active group call has changed. Returns identifier of the participant if it is found. - * - *

Returns {@link MessageSender MessageSender}

- * - * @param groupCallId Group call identifier. - * @param audioSource Group call participant's synchronization audio source identifier, or 0 for the current user. - * @param isSpeaking Pass true if the user is speaking. - */ - public SetGroupCallParticipantIsSpeaking(int groupCallId, int audioSource, boolean isSpeaking) { - this.groupCallId = groupCallId; - this.audioSource = audioSource; - this.isSpeaking = isSpeaking; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1019676164; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes volume level of a participant of an active group call; not supported for live stories. If the current user can manage the group call or is the owner of the group call, then the participant's volume level will be changed for all users with the default volume level. - * - *

Returns {@link Ok Ok}

- */ - public static class SetGroupCallParticipantVolumeLevel extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Participant identifier. - */ - public MessageSender participantId; - /** - * New participant's volume level; 1-20000 in hundreds of percents. - */ - public int volumeLevel; - - /** - * Default constructor for a function, which changes volume level of a participant of an active group call; not supported for live stories. If the current user can manage the group call or is the owner of the group call, then the participant's volume level will be changed for all users with the default volume level. - * - *

Returns {@link Ok Ok}

- */ - public SetGroupCallParticipantVolumeLevel() { - } - - /** - * Creates a function, which changes volume level of a participant of an active group call; not supported for live stories. If the current user can manage the group call or is the owner of the group call, then the participant's volume level will be changed for all users with the default volume level. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param participantId Participant identifier. - * @param volumeLevel New participant's volume level; 1-20000 in hundreds of percents. - */ - public SetGroupCallParticipantVolumeLevel(int groupCallId, MessageSender participantId, int volumeLevel) { - this.groupCallId = groupCallId; - this.participantId = participantId; - this.volumeLevel = volumeLevel; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1753769944; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the period of inactivity after which sessions will automatically be terminated. - * - *

Returns {@link Ok Ok}

- */ - public static class SetInactiveSessionTtl extends Function { - /** - * New number of days of inactivity before sessions will be automatically terminated; 1-366 days. - */ - public int inactiveSessionTtlDays; - - /** - * Default constructor for a function, which changes the period of inactivity after which sessions will automatically be terminated. - * - *

Returns {@link Ok Ok}

- */ - public SetInactiveSessionTtl() { - } - - /** - * Creates a function, which changes the period of inactivity after which sessions will automatically be terminated. - * - *

Returns {@link Ok Ok}

- * - * @param inactiveSessionTtlDays New number of days of inactivity before sessions will be automatically terminated; 1-366 days. - */ - public SetInactiveSessionTtl(int inactiveSessionTtlDays) { - this.inactiveSessionTtlDays = inactiveSessionTtlDays; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1570548048; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Updates the game score of the specified user in a game; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetInlineGameScore extends Function { - /** - * Inline message identifier. - */ - public String inlineMessageId; - /** - * Pass true to edit the game message to include the current scoreboard. - */ - public boolean editMessage; - /** - * User identifier. - */ - public long userId; - /** - * The new score. - */ - public int score; - /** - * Pass true to update the score even if it decreases. If the score is 0, the user will be deleted from the high score table. - */ - public boolean force; - - /** - * Default constructor for a function, which updates the game score of the specified user in a game; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public SetInlineGameScore() { - } - - /** - * Creates a function, which updates the game score of the specified user in a game; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param inlineMessageId Inline message identifier. - * @param editMessage Pass true to edit the game message to include the current scoreboard. - * @param userId User identifier. - * @param score The new score. - * @param force Pass true to update the score even if it decreases. If the score is 0, the user will be deleted from the high score table. - */ - public SetInlineGameScore(String inlineMessageId, boolean editMessage, long userId, int score, boolean force) { - this.inlineMessageId = inlineMessageId; - this.editMessage = editMessage; - this.userId = userId; - this.score = score; - this.force = force; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -948871797; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Selects a message sender to send messages in a live story call. - * - *

Returns {@link Ok Ok}

- */ - public static class SetLiveStoryMessageSender extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * New message sender for the group call. - */ - public MessageSender messageSenderId; - - /** - * Default constructor for a function, which selects a message sender to send messages in a live story call. - * - *

Returns {@link Ok Ok}

- */ - public SetLiveStoryMessageSender() { - } - - /** - * Creates a function, which selects a message sender to send messages in a live story call. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param messageSenderId New message sender for the group call. - */ - public SetLiveStoryMessageSender(int groupCallId, MessageSender messageSenderId) { - this.groupCallId = groupCallId; - this.messageSenderId = messageSenderId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1855297410; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets new log stream for internal logging of TDLib. Can be called synchronously. - * - *

Returns {@link Ok Ok}

- */ - public static class SetLogStream extends Function { - /** - * New log stream. - */ - public LogStream logStream; - - /** - * Default constructor for a function, which sets new log stream for internal logging of TDLib. Can be called synchronously. - * - *

Returns {@link Ok Ok}

- */ - public SetLogStream() { - } - - /** - * Creates a function, which sets new log stream for internal logging of TDLib. Can be called synchronously. - * - *

Returns {@link Ok Ok}

- * - * @param logStream New log stream. - */ - public SetLogStream(LogStream logStream) { - this.logStream = logStream; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1364199535; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets the verbosity level for a specified TDLib internal log tag. Can be called synchronously. - * - *

Returns {@link Ok Ok}

- */ - public static class SetLogTagVerbosityLevel extends Function { - /** - * Logging tag to change verbosity level. - */ - public String tag; - /** - * New verbosity level; 1-1024. - */ - public int newVerbosityLevel; - - /** - * Default constructor for a function, which sets the verbosity level for a specified TDLib internal log tag. Can be called synchronously. - * - *

Returns {@link Ok Ok}

- */ - public SetLogTagVerbosityLevel() { - } - - /** - * Creates a function, which sets the verbosity level for a specified TDLib internal log tag. Can be called synchronously. - * - *

Returns {@link Ok Ok}

- * - * @param tag Logging tag to change verbosity level. - * @param newVerbosityLevel New verbosity level; 1-1024. - */ - public SetLogTagVerbosityLevel(String tag, int newVerbosityLevel) { - this.tag = tag; - this.newVerbosityLevel = newVerbosityLevel; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2095589738; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets the verbosity level of the internal logging of TDLib. Can be called synchronously. - * - *

Returns {@link Ok Ok}

- */ - public static class SetLogVerbosityLevel extends Function { - /** - * New value of the verbosity level for logging. Value 0 corresponds to fatal errors, value 1 corresponds to errors, value 2 corresponds to warnings and debug warnings, value 3 corresponds to informational, value 4 corresponds to debug, value 5 corresponds to verbose debug, value greater than 5 and up to 1023 can be used to enable even more logging. - */ - public int newVerbosityLevel; - - /** - * Default constructor for a function, which sets the verbosity level of the internal logging of TDLib. Can be called synchronously. - * - *

Returns {@link Ok Ok}

- */ - public SetLogVerbosityLevel() { - } - - /** - * Creates a function, which sets the verbosity level of the internal logging of TDLib. Can be called synchronously. - * - *

Returns {@link Ok Ok}

- * - * @param newVerbosityLevel New value of the verbosity level for logging. Value 0 corresponds to fatal errors, value 1 corresponds to errors, value 2 corresponds to warnings and debug warnings, value 3 corresponds to informational, value 4 corresponds to debug, value 5 corresponds to verbose debug, value greater than 5 and up to 1023 can be used to enable even more logging. - */ - public SetLogVerbosityLevel(int newVerbosityLevel) { - this.newVerbosityLevel = newVerbosityLevel; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -303429678; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the login email address of the user. The email address can be changed only if the current user already has login email and passwordState.loginEmailAddressPattern is non-empty, or the user received suggestedActionSetLoginEmailAddress and isLoginEmailAddressRequired succeeds. The change will not be applied until the new login email address is confirmed with checkLoginEmailAddressCode. To use Apple ID/Google ID instead of an email address, call checkLoginEmailAddressCode directly. - * - *

Returns {@link EmailAddressAuthenticationCodeInfo EmailAddressAuthenticationCodeInfo}

- */ - public static class SetLoginEmailAddress extends Function { - /** - * New login email address. - */ - public String newLoginEmailAddress; - - /** - * Default constructor for a function, which changes the login email address of the user. The email address can be changed only if the current user already has login email and passwordState.loginEmailAddressPattern is non-empty, or the user received suggestedActionSetLoginEmailAddress and isLoginEmailAddressRequired succeeds. The change will not be applied until the new login email address is confirmed with checkLoginEmailAddressCode. To use Apple ID/Google ID instead of an email address, call checkLoginEmailAddressCode directly. - * - *

Returns {@link EmailAddressAuthenticationCodeInfo EmailAddressAuthenticationCodeInfo}

- */ - public SetLoginEmailAddress() { - } - - /** - * Creates a function, which changes the login email address of the user. The email address can be changed only if the current user already has login email and passwordState.loginEmailAddressPattern is non-empty, or the user received suggestedActionSetLoginEmailAddress and isLoginEmailAddressRequired succeeds. The change will not be applied until the new login email address is confirmed with checkLoginEmailAddressCode. To use Apple ID/Google ID instead of an email address, call checkLoginEmailAddressCode directly. - * - *

Returns {@link EmailAddressAuthenticationCodeInfo EmailAddressAuthenticationCodeInfo}

- * - * @param newLoginEmailAddress New login email address. - */ - public SetLoginEmailAddress(String newLoginEmailAddress) { - this.newLoginEmailAddress = newLoginEmailAddress; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 935019476; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the main profile tab of the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetMainProfileTab extends Function { - /** - * The new value of the main profile tab. - */ - public ProfileTab mainProfileTab; - - /** - * Default constructor for a function, which changes the main profile tab of the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetMainProfileTab() { - } - - /** - * Creates a function, which changes the main profile tab of the current user. - * - *

Returns {@link Ok Ok}

- * - * @param mainProfileTab The new value of the main profile tab. - */ - public SetMainProfileTab(ProfileTab mainProfileTab) { - this.mainProfileTab = mainProfileTab; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1663496423; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets menu button for the given user or for all users; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetMenuButton extends Function { - /** - * Identifier of the user or 0 to set menu button for all users. - */ - public long userId; - /** - * New menu button. - */ - public BotMenuButton menuButton; - - /** - * Default constructor for a function, which sets menu button for the given user or for all users; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public SetMenuButton() { - } - - /** - * Creates a function, which sets menu button for the given user or for all users; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param userId Identifier of the user or 0 to set menu button for all users. - * @param menuButton New menu button. - */ - public SetMenuButton(long userId, BotMenuButton menuButton) { - this.userId = userId; - this.menuButton = menuButton; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1269841599; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the fact-check of a message. Can be only used if messageProperties.canSetFactCheck == true. - * - *

Returns {@link Ok Ok}

- */ - public static class SetMessageFactCheck extends Function { - /** - * The channel chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * New text of the fact-check; 0-getOption("fact_check_length_max") characters; pass null to remove it. Only Bold, Italic, and TextUrl entities with https://t.me/ links are supported. - */ - public FormattedText text; - - /** - * Default constructor for a function, which changes the fact-check of a message. Can be only used if messageProperties.canSetFactCheck == true. - * - *

Returns {@link Ok Ok}

- */ - public SetMessageFactCheck() { - } - - /** - * Creates a function, which changes the fact-check of a message. Can be only used if messageProperties.canSetFactCheck == true. - * - *

Returns {@link Ok Ok}

- * - * @param chatId The channel chat the message belongs to. - * @param messageId Identifier of the message. - * @param text New text of the fact-check; 0-getOption("fact_check_length_max") characters; pass null to remove it. Only Bold, Italic, and TextUrl entities with https://t.me/ links are supported. - */ - public SetMessageFactCheck(long chatId, long messageId, FormattedText text) { - this.chatId = chatId; - this.messageId = messageId; - this.text = text; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -4309752; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets reactions on a message; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetMessageReactions extends Function { - /** - * Identifier of the chat to which the message belongs. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * Types of the reaction to set; pass an empty list to remove the reactions. - */ - public ReactionType[] reactionTypes; - /** - * Pass true if the reactions are added with a big animation. - */ - public boolean isBig; - - /** - * Default constructor for a function, which sets reactions on a message; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public SetMessageReactions() { - } - - /** - * Creates a function, which sets reactions on a message; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat to which the message belongs. - * @param messageId Identifier of the message. - * @param reactionTypes Types of the reaction to set; pass an empty list to remove the reactions. - * @param isBig Pass true if the reactions are added with a big animation. - */ - public SetMessageReactions(long chatId, long messageId, ReactionType[] reactionTypes, boolean isBig) { - this.chatId = chatId; - this.messageId = messageId; - this.reactionTypes = reactionTypes; - this.isBig = isBig; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -372524900; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the block list of a message sender. Currently, only users and supergroup chats can be blocked. - * - *

Returns {@link Ok Ok}

- */ - public static class SetMessageSenderBlockList extends Function { - /** - * Identifier of a message sender to block/unblock. - */ - public MessageSender senderId; - /** - * New block list for the message sender; pass null to unblock the message sender. - */ - public BlockList blockList; - - /** - * Default constructor for a function, which changes the block list of a message sender. Currently, only users and supergroup chats can be blocked. - * - *

Returns {@link Ok Ok}

- */ - public SetMessageSenderBlockList() { - } - - /** - * Creates a function, which changes the block list of a message sender. Currently, only users and supergroup chats can be blocked. - * - *

Returns {@link Ok Ok}

- * - * @param senderId Identifier of a message sender to block/unblock. - * @param blockList New block list for the message sender; pass null to unblock the message sender. - */ - public SetMessageSenderBlockList(MessageSender senderId, BlockList blockList) { - this.senderId = senderId; - this.blockList = blockList; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1987355503; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the verification status of a user or a chat by an owned bot. - * - *

Returns {@link Ok Ok}

- */ - public static class SetMessageSenderBotVerification extends Function { - /** - * Identifier of the owned bot, which will verify the user or the chat. - */ - public long botUserId; - /** - * Identifier of the user or the supergroup or channel chat, which will be verified by the bot. - */ - public MessageSender verifiedId; - /** - * Custom description of verification reason; 0-getOption("bot_verification_custom_description_length_max"). If empty, then "was verified by organization "organization_name"" will be used as description. Can be specified only if the bot is allowed to provide custom description. - */ - public String customDescription; - - /** - * Default constructor for a function, which changes the verification status of a user or a chat by an owned bot. - * - *

Returns {@link Ok Ok}

- */ - public SetMessageSenderBotVerification() { - } - - /** - * Creates a function, which changes the verification status of a user or a chat by an owned bot. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId Identifier of the owned bot, which will verify the user or the chat. - * @param verifiedId Identifier of the user or the supergroup or channel chat, which will be verified by the bot. - * @param customDescription Custom description of verification reason; 0-getOption("bot_verification_custom_description_length_max"). If empty, then "was verified by organization "organization_name"" will be used as description. Can be specified only if the bot is allowed to provide custom description. - */ - public SetMessageSenderBotVerification(long botUserId, MessageSender verifiedId, String customDescription) { - this.botUserId = botUserId; - this.verifiedId = verifiedId; - this.customDescription = customDescription; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1262364086; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the first and last name of the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetName extends Function { - /** - * The new value of the first name for the current user; 1-64 characters. - */ - public String firstName; - /** - * The new value of the optional last name for the current user; 0-64 characters. - */ - public String lastName; - - /** - * Default constructor for a function, which changes the first and last name of the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetName() { - } - - /** - * Creates a function, which changes the first and last name of the current user. - * - *

Returns {@link Ok Ok}

- * - * @param firstName The new value of the first name for the current user; 1-64 characters. - * @param lastName The new value of the optional last name for the current user; 0-64 characters. - */ - public SetName(String firstName, String lastName) { - this.firstName = firstName; - this.lastName = lastName; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1711693584; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets the current network type. Can be called before authorization. Calling this method forces all network connections to reopen, mitigating the delay in switching between different networks, so it must be called whenever the network is changed, even if the network type remains the same. Network type is used to check whether the library can use the network at all and also for collecting detailed network data usage statistics. - * - *

Returns {@link Ok Ok}

- */ - public static class SetNetworkType extends Function { - /** - * The new network type; pass null to set network type to networkTypeOther. - */ - public NetworkType type; - - /** - * Default constructor for a function, which sets the current network type. Can be called before authorization. Calling this method forces all network connections to reopen, mitigating the delay in switching between different networks, so it must be called whenever the network is changed, even if the network type remains the same. Network type is used to check whether the library can use the network at all and also for collecting detailed network data usage statistics. - * - *

Returns {@link Ok Ok}

- */ - public SetNetworkType() { - } - - /** - * Creates a function, which sets the current network type. Can be called before authorization. Calling this method forces all network connections to reopen, mitigating the delay in switching between different networks, so it must be called whenever the network is changed, even if the network type remains the same. Network type is used to check whether the library can use the network at all and also for collecting detailed network data usage statistics. - * - *

Returns {@link Ok Ok}

- * - * @param type The new network type; pass null to set network type to networkTypeOther. - */ - public SetNetworkType(NetworkType type) { - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -701635234; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes privacy settings for new chat creation; can be used only if getOption("can_set_new_chat_privacy_settings"). - * - *

Returns {@link Ok Ok}

- */ - public static class SetNewChatPrivacySettings extends Function { - /** - * New settings. - */ - public NewChatPrivacySettings settings; - - /** - * Default constructor for a function, which changes privacy settings for new chat creation; can be used only if getOption("can_set_new_chat_privacy_settings"). - * - *

Returns {@link Ok Ok}

- */ - public SetNewChatPrivacySettings() { - } - - /** - * Creates a function, which changes privacy settings for new chat creation; can be used only if getOption("can_set_new_chat_privacy_settings"). - * - *

Returns {@link Ok Ok}

- * - * @param settings New settings. - */ - public SetNewChatPrivacySettings(NewChatPrivacySettings settings) { - this.settings = settings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1774139215; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets the value of an option. (Check the list of available options on https://core.telegram.org/tdlib/options.) Only writable options can be set. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class SetOption extends Function { - /** - * The name of the option. - */ - public String name; - /** - * The new value of the option; pass null to reset option value to a default value. - */ - public OptionValue value; - - /** - * Default constructor for a function, which sets the value of an option. (Check the list of available options on https://core.telegram.org/tdlib/options.) Only writable options can be set. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public SetOption() { - } - - /** - * Creates a function, which sets the value of an option. (Check the list of available options on https://core.telegram.org/tdlib/options.) Only writable options can be set. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- * - * @param name The name of the option. - * @param value The new value of the option; pass null to reset option value to a default value. - */ - public SetOption(String name, OptionValue value) { - this.name = name; - this.value = value; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2114670322; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes type of paid message reaction of the current user on a message. The message must have paid reaction added by the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetPaidMessageReactionType extends Function { - /** - * Identifier of the chat to which the message belongs. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * New type of the paid reaction. - */ - public PaidReactionType type; - - /** - * Default constructor for a function, which changes type of paid message reaction of the current user on a message. The message must have paid reaction added by the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetPaidMessageReactionType() { - } - - /** - * Creates a function, which changes type of paid message reaction of the current user on a message. The message must have paid reaction added by the current user. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat to which the message belongs. - * @param messageId Identifier of the message. - * @param type New type of the paid reaction. - */ - public SetPaidMessageReactionType(long chatId, long messageId, PaidReactionType type) { - this.chatId = chatId; - this.messageId = messageId; - this.type = type; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -829934930; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds an element to the user's Telegram Passport. May return an error with a message "PHONE_VERIFICATION_NEEDED" or "EMAIL_VERIFICATION_NEEDED" if the chosen phone number or the chosen email address must be verified first. - * - *

Returns {@link PassportElement PassportElement}

- */ - public static class SetPassportElement extends Function { - /** - * Input Telegram Passport element. - */ - public InputPassportElement element; - /** - * The 2-step verification password of the current user. - */ - public String password; - - /** - * Default constructor for a function, which adds an element to the user's Telegram Passport. May return an error with a message "PHONE_VERIFICATION_NEEDED" or "EMAIL_VERIFICATION_NEEDED" if the chosen phone number or the chosen email address must be verified first. - * - *

Returns {@link PassportElement PassportElement}

- */ - public SetPassportElement() { - } - - /** - * Creates a function, which adds an element to the user's Telegram Passport. May return an error with a message "PHONE_VERIFICATION_NEEDED" or "EMAIL_VERIFICATION_NEEDED" if the chosen phone number or the chosen email address must be verified first. - * - *

Returns {@link PassportElement PassportElement}

- * - * @param element Input Telegram Passport element. - * @param password The 2-step verification password of the current user. - */ - public SetPassportElement(InputPassportElement element, String password) { - this.element = element; - this.password = password; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2068173212; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs the user who some of the elements in their Telegram Passport contain errors; for bots only. The user will not be able to resend the elements, until the errors are fixed. - * - *

Returns {@link Ok Ok}

- */ - public static class SetPassportElementErrors extends Function { - /** - * User identifier. - */ - public long userId; - /** - * The errors. - */ - public InputPassportElementError[] errors; - - /** - * Default constructor for a function, which informs the user who some of the elements in their Telegram Passport contain errors; for bots only. The user will not be able to resend the elements, until the errors are fixed. - * - *

Returns {@link Ok Ok}

- */ - public SetPassportElementErrors() { - } - - /** - * Creates a function, which informs the user who some of the elements in their Telegram Passport contain errors; for bots only. The user will not be able to resend the elements, until the errors are fixed. - * - *

Returns {@link Ok Ok}

- * - * @param userId User identifier. - * @param errors The errors. - */ - public SetPassportElementErrors(long userId, InputPassportElementError[] errors) { - this.userId = userId; - this.errors = errors; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2056754881; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the 2-step verification password for the current user. If a new recovery email address is specified, then the change will not be applied until the new recovery email address is confirmed. - * - *

Returns {@link PasswordState PasswordState}

- */ - public static class SetPassword extends Function { - /** - * Previous 2-step verification password of the user. - */ - public String oldPassword; - /** - * New 2-step verification password of the user; may be empty to remove the password. - */ - public String newPassword; - /** - * New password hint; may be empty. - */ - public String newHint; - /** - * Pass true to change also the recovery email address. - */ - public boolean setRecoveryEmailAddress; - /** - * New recovery email address; may be empty. - */ - public String newRecoveryEmailAddress; - - /** - * Default constructor for a function, which changes the 2-step verification password for the current user. If a new recovery email address is specified, then the change will not be applied until the new recovery email address is confirmed. - * - *

Returns {@link PasswordState PasswordState}

- */ - public SetPassword() { - } - - /** - * Creates a function, which changes the 2-step verification password for the current user. If a new recovery email address is specified, then the change will not be applied until the new recovery email address is confirmed. - * - *

Returns {@link PasswordState PasswordState}

- * - * @param oldPassword Previous 2-step verification password of the user. - * @param newPassword New 2-step verification password of the user; may be empty to remove the password. - * @param newHint New password hint; may be empty. - * @param setRecoveryEmailAddress Pass true to change also the recovery email address. - * @param newRecoveryEmailAddress New recovery email address; may be empty. - */ - public SetPassword(String oldPassword, String newPassword, String newHint, boolean setRecoveryEmailAddress, String newRecoveryEmailAddress) { - this.oldPassword = oldPassword; - this.newPassword = newPassword; - this.newHint = newHint; - this.setRecoveryEmailAddress = setRecoveryEmailAddress; - this.newRecoveryEmailAddress = newRecoveryEmailAddress; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1193589027; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the personal chat of the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetPersonalChat extends Function { - /** - * Identifier of the new personal chat; pass 0 to remove the chat. Use getSuitablePersonalChats to get suitable chats. - */ - public long chatId; - - /** - * Default constructor for a function, which changes the personal chat of the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetPersonalChat() { - } - - /** - * Creates a function, which changes the personal chat of the current user. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the new personal chat; pass 0 to remove the chat. Use getSuitablePersonalChats to get suitable chats. - */ - public SetPersonalChat(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1068782668; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the order of pinned chats. - * - *

Returns {@link Ok Ok}

- */ - public static class SetPinnedChats extends Function { - /** - * Chat list in which to change the order of pinned chats. - */ - public ChatList chatList; - /** - * The new list of pinned chats. - */ - public long[] chatIds; - - /** - * Default constructor for a function, which changes the order of pinned chats. - * - *

Returns {@link Ok Ok}

- */ - public SetPinnedChats() { - } - - /** - * Creates a function, which changes the order of pinned chats. - * - *

Returns {@link Ok Ok}

- * - * @param chatList Chat list in which to change the order of pinned chats. - * @param chatIds The new list of pinned chats. - */ - public SetPinnedChats(ChatList chatList, long[] chatIds) { - this.chatList = chatList; - this.chatIds = chatIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -695640000; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the order of pinned topics in a forum supergroup chat or a chat with a bot with topics; requires canManageTopics administrator right in the supergroup. - * - *

Returns {@link Ok Ok}

- */ - public static class SetPinnedForumTopics extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * The new list of identifiers of the pinned forum topics. - */ - public int[] forumTopicIds; - - /** - * Default constructor for a function, which changes the order of pinned topics in a forum supergroup chat or a chat with a bot with topics; requires canManageTopics administrator right in the supergroup. - * - *

Returns {@link Ok Ok}

- */ - public SetPinnedForumTopics() { - } - - /** - * Creates a function, which changes the order of pinned topics in a forum supergroup chat or a chat with a bot with topics; requires canManageTopics administrator right in the supergroup. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param forumTopicIds The new list of identifiers of the pinned forum topics. - */ - public SetPinnedForumTopics(long chatId, int[] forumTopicIds) { - this.chatId = chatId; - this.forumTopicIds = forumTopicIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1871668497; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the list of pinned gifts on the current user's or the channel's profile page; requires canPostMessages administrator right in the channel chat. - * - *

Returns {@link Ok Ok}

- */ - public static class SetPinnedGifts extends Function { - /** - * Identifier of the user or the channel chat that received the gifts. - */ - public MessageSender ownerId; - /** - * New list of pinned gifts. All gifts must be upgraded and saved on the profile page first. There can be up to getOption("pinned_gift_count_max") pinned gifts. - */ - public String[] receivedGiftIds; - - /** - * Default constructor for a function, which changes the list of pinned gifts on the current user's or the channel's profile page; requires canPostMessages administrator right in the channel chat. - * - *

Returns {@link Ok Ok}

- */ - public SetPinnedGifts() { - } - - /** - * Creates a function, which changes the list of pinned gifts on the current user's or the channel's profile page; requires canPostMessages administrator right in the channel chat. - * - *

Returns {@link Ok Ok}

- * - * @param ownerId Identifier of the user or the channel chat that received the gifts. - * @param receivedGiftIds New list of pinned gifts. All gifts must be upgraded and saved on the profile page first. There can be up to getOption("pinned_gift_count_max") pinned gifts. - */ - public SetPinnedGifts(MessageSender ownerId, String[] receivedGiftIds) { - this.ownerId = ownerId; - this.receivedGiftIds = receivedGiftIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1613526306; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the order of pinned Saved Messages topics. - * - *

Returns {@link Ok Ok}

- */ - public static class SetPinnedSavedMessagesTopics extends Function { - /** - * Identifiers of the new pinned Saved Messages topics. - */ - public long[] savedMessagesTopicIds; - - /** - * Default constructor for a function, which changes the order of pinned Saved Messages topics. - * - *

Returns {@link Ok Ok}

- */ - public SetPinnedSavedMessagesTopics() { - } - - /** - * Creates a function, which changes the order of pinned Saved Messages topics. - * - *

Returns {@link Ok Ok}

- * - * @param savedMessagesTopicIds Identifiers of the new pinned Saved Messages topics. - */ - public SetPinnedSavedMessagesTopics(long[] savedMessagesTopicIds) { - this.savedMessagesTopicIds = savedMessagesTopicIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -194818924; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the user answer to a poll. A poll in quiz mode can be answered only once. - * - *

Returns {@link Ok Ok}

- */ - public static class SetPollAnswer extends Function { - /** - * Identifier of the chat to which the poll belongs. - */ - public long chatId; - /** - * Identifier of the message containing the poll. - */ - public long messageId; - /** - * 0-based identifiers of answer options, chosen by the user. User can choose more than 1 answer option only is the poll allows multiple answers. - */ - public int[] optionIds; - - /** - * Default constructor for a function, which changes the user answer to a poll. A poll in quiz mode can be answered only once. - * - *

Returns {@link Ok Ok}

- */ - public SetPollAnswer() { - } - - /** - * Creates a function, which changes the user answer to a poll. A poll in quiz mode can be answered only once. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat to which the poll belongs. - * @param messageId Identifier of the message containing the poll. - * @param optionIds 0-based identifiers of answer options, chosen by the user. User can choose more than 1 answer option only is the poll allows multiple answers. - */ - public SetPollAnswer(long chatId, long messageId, int[] optionIds) { - this.chatId = chatId; - this.messageId = messageId; - this.optionIds = optionIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1399388792; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes accent color and background custom emoji for profile of the current user; for Telegram Premium users only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetProfileAccentColor extends Function { - /** - * Identifier of the accent color to use for profile; pass -1 if none. - */ - public int profileAccentColorId; - /** - * Identifier of a custom emoji to be shown on the user's profile photo background; 0 if none. - */ - public long profileBackgroundCustomEmojiId; - - /** - * Default constructor for a function, which changes accent color and background custom emoji for profile of the current user; for Telegram Premium users only. - * - *

Returns {@link Ok Ok}

- */ - public SetProfileAccentColor() { - } - - /** - * Creates a function, which changes accent color and background custom emoji for profile of the current user; for Telegram Premium users only. - * - *

Returns {@link Ok Ok}

- * - * @param profileAccentColorId Identifier of the accent color to use for profile; pass -1 if none. - * @param profileBackgroundCustomEmojiId Identifier of a custom emoji to be shown on the user's profile photo background; 0 if none. - */ - public SetProfileAccentColor(int profileAccentColorId, long profileBackgroundCustomEmojiId) { - this.profileAccentColorId = profileAccentColorId; - this.profileBackgroundCustomEmojiId = profileBackgroundCustomEmojiId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1986281112; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes position of an audio file in the profile audio files of the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetProfileAudioPosition extends Function { - /** - * Identifier of the file from profile audio files, which position will be changed. - */ - public int fileId; - /** - * Identifier of the file from profile audio files after which the file will be positioned; pass 0 to move the file to the beginning of the list. - */ - public int afterFileId; - - /** - * Default constructor for a function, which changes position of an audio file in the profile audio files of the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetProfileAudioPosition() { - } - - /** - * Creates a function, which changes position of an audio file in the profile audio files of the current user. - * - *

Returns {@link Ok Ok}

- * - * @param fileId Identifier of the file from profile audio files, which position will be changed. - * @param afterFileId Identifier of the file from profile audio files after which the file will be positioned; pass 0 to move the file to the beginning of the list. - */ - public SetProfileAudioPosition(int fileId, int afterFileId) { - this.fileId = fileId; - this.afterFileId = afterFileId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1209963614; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes a profile photo for the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetProfilePhoto extends Function { - /** - * Profile photo to set. - */ - public InputChatPhoto photo; - /** - * Pass true to set the public photo, which will be visible even if the main photo is hidden by privacy settings. - */ - public boolean isPublic; - - /** - * Default constructor for a function, which changes a profile photo for the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetProfilePhoto() { - } - - /** - * Creates a function, which changes a profile photo for the current user. - * - *

Returns {@link Ok Ok}

- * - * @param photo Profile photo to set. - * @param isPublic Pass true to set the public photo, which will be visible even if the main photo is hidden by privacy settings. - */ - public SetProfilePhoto(InputChatPhoto photo, boolean isPublic) { - this.photo = photo; - this.isPublic = isPublic; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2048260627; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes name of a quick reply shortcut. - * - *

Returns {@link Ok Ok}

- */ - public static class SetQuickReplyShortcutName extends Function { - /** - * Unique identifier of the quick reply shortcut. - */ - public int shortcutId; - /** - * New name for the shortcut. Use checkQuickReplyShortcutName to check its validness. - */ - public String name; - - /** - * Default constructor for a function, which changes name of a quick reply shortcut. - * - *

Returns {@link Ok Ok}

- */ - public SetQuickReplyShortcutName() { - } - - /** - * Creates a function, which changes name of a quick reply shortcut. - * - *

Returns {@link Ok Ok}

- * - * @param shortcutId Unique identifier of the quick reply shortcut. - * @param name New name for the shortcut. Use checkQuickReplyShortcutName to check its validness. - */ - public SetQuickReplyShortcutName(int shortcutId, String name) { - this.shortcutId = shortcutId; - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 186709105; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes notification settings for reactions. - * - *

Returns {@link Ok Ok}

- */ - public static class SetReactionNotificationSettings extends Function { - /** - * The new notification settings for reactions. - */ - public ReactionNotificationSettings notificationSettings; - - /** - * Default constructor for a function, which changes notification settings for reactions. - * - *

Returns {@link Ok Ok}

- */ - public SetReactionNotificationSettings() { - } - - /** - * Creates a function, which changes notification settings for reactions. - * - *

Returns {@link Ok Ok}

- * - * @param notificationSettings The new notification settings for reactions. - */ - public SetReactionNotificationSettings(ReactionNotificationSettings notificationSettings) { - this.notificationSettings = notificationSettings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1186124949; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes privacy settings for message read date. - * - *

Returns {@link Ok Ok}

- */ - public static class SetReadDatePrivacySettings extends Function { - /** - * New settings. - */ - public ReadDatePrivacySettings settings; - - /** - * Default constructor for a function, which changes privacy settings for message read date. - * - *

Returns {@link Ok Ok}

- */ - public SetReadDatePrivacySettings() { - } - - /** - * Creates a function, which changes privacy settings for message read date. - * - *

Returns {@link Ok Ok}

- * - * @param settings New settings. - */ - public SetReadDatePrivacySettings(ReadDatePrivacySettings settings) { - this.settings = settings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 493913782; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the 2-step verification recovery email address of the user. If a new recovery email address is specified, then the change will not be applied until the new recovery email address is confirmed. If newRecoveryEmailAddress is the same as the email address that is currently set up, this call succeeds immediately and aborts all other requests waiting for an email confirmation. - * - *

Returns {@link PasswordState PasswordState}

- */ - public static class SetRecoveryEmailAddress extends Function { - /** - * The 2-step verification password of the current user. - */ - public String password; - /** - * New recovery email address. - */ - public String newRecoveryEmailAddress; - - /** - * Default constructor for a function, which changes the 2-step verification recovery email address of the user. If a new recovery email address is specified, then the change will not be applied until the new recovery email address is confirmed. If newRecoveryEmailAddress is the same as the email address that is currently set up, this call succeeds immediately and aborts all other requests waiting for an email confirmation. - * - *

Returns {@link PasswordState PasswordState}

- */ - public SetRecoveryEmailAddress() { - } - - /** - * Creates a function, which changes the 2-step verification recovery email address of the user. If a new recovery email address is specified, then the change will not be applied until the new recovery email address is confirmed. If newRecoveryEmailAddress is the same as the email address that is currently set up, this call succeeds immediately and aborts all other requests waiting for an email confirmation. - * - *

Returns {@link PasswordState PasswordState}

- * - * @param password The 2-step verification password of the current user. - * @param newRecoveryEmailAddress New recovery email address. - */ - public SetRecoveryEmailAddress(String password, String newRecoveryEmailAddress) { - this.password = password; - this.newRecoveryEmailAddress = newRecoveryEmailAddress; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1981836385; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes label of a Saved Messages tag; for Telegram Premium users only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetSavedMessagesTagLabel extends Function { - /** - * The tag which label will be changed. - */ - public ReactionType tag; - /** - * New label for the tag; 0-12 characters. - */ - public String label; - - /** - * Default constructor for a function, which changes label of a Saved Messages tag; for Telegram Premium users only. - * - *

Returns {@link Ok Ok}

- */ - public SetSavedMessagesTagLabel() { - } - - /** - * Creates a function, which changes label of a Saved Messages tag; for Telegram Premium users only. - * - *

Returns {@link Ok Ok}

- * - * @param tag The tag which label will be changed. - * @param label New label for the tag; 0-12 characters. - */ - public SetSavedMessagesTagLabel(ReactionType tag, String label) { - this.tag = tag; - this.label = label; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1338323696; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes notification settings for chats of a given type. - * - *

Returns {@link Ok Ok}

- */ - public static class SetScopeNotificationSettings extends Function { - /** - * Types of chats for which to change the notification settings. - */ - public NotificationSettingsScope scope; - /** - * The new notification settings for the given scope. - */ - public ScopeNotificationSettings notificationSettings; - - /** - * Default constructor for a function, which changes notification settings for chats of a given type. - * - *

Returns {@link Ok Ok}

- */ - public SetScopeNotificationSettings() { - } - - /** - * Creates a function, which changes notification settings for chats of a given type. - * - *

Returns {@link Ok Ok}

- * - * @param scope Types of chats for which to change the notification settings. - * @param notificationSettings The new notification settings for the given scope. - */ - public SetScopeNotificationSettings(NotificationSettingsScope scope, ScopeNotificationSettings notificationSettings) { - this.scope = scope; - this.notificationSettings = notificationSettings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2049984966; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the list of emojis corresponding to a sticker. The sticker must belong to a regular or custom emoji sticker set that is owned by the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetStickerEmojis extends Function { - /** - * Sticker. - */ - public InputFile sticker; - /** - * New string with 1-20 emoji corresponding to the sticker. - */ - public String emojis; - - /** - * Default constructor for a function, which changes the list of emojis corresponding to a sticker. The sticker must belong to a regular or custom emoji sticker set that is owned by the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetStickerEmojis() { - } - - /** - * Creates a function, which changes the list of emojis corresponding to a sticker. The sticker must belong to a regular or custom emoji sticker set that is owned by the current user. - * - *

Returns {@link Ok Ok}

- * - * @param sticker Sticker. - * @param emojis New string with 1-20 emoji corresponding to the sticker. - */ - public SetStickerEmojis(InputFile sticker, String emojis) { - this.sticker = sticker; - this.emojis = emojis; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -638843855; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the list of keywords of a sticker. The sticker must belong to a regular or custom emoji sticker set that is owned by the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetStickerKeywords extends Function { - /** - * Sticker. - */ - public InputFile sticker; - /** - * List of up to 20 keywords with total length up to 64 characters, which can be used to find the sticker. - */ - public String[] keywords; - - /** - * Default constructor for a function, which changes the list of keywords of a sticker. The sticker must belong to a regular or custom emoji sticker set that is owned by the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetStickerKeywords() { - } - - /** - * Creates a function, which changes the list of keywords of a sticker. The sticker must belong to a regular or custom emoji sticker set that is owned by the current user. - * - *

Returns {@link Ok Ok}

- * - * @param sticker Sticker. - * @param keywords List of up to 20 keywords with total length up to 64 characters, which can be used to find the sticker. - */ - public SetStickerKeywords(InputFile sticker, String[] keywords) { - this.sticker = sticker; - this.keywords = keywords; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 137223565; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the mask position of a mask sticker. The sticker must belong to a mask sticker set that is owned by the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetStickerMaskPosition extends Function { - /** - * Sticker. - */ - public InputFile sticker; - /** - * Position where the mask is placed; pass null to remove mask position. - */ - public MaskPosition maskPosition; - - /** - * Default constructor for a function, which changes the mask position of a mask sticker. The sticker must belong to a mask sticker set that is owned by the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetStickerMaskPosition() { - } - - /** - * Creates a function, which changes the mask position of a mask sticker. The sticker must belong to a mask sticker set that is owned by the current user. - * - *

Returns {@link Ok Ok}

- * - * @param sticker Sticker. - * @param maskPosition Position where the mask is placed; pass null to remove mask position. - */ - public SetStickerMaskPosition(InputFile sticker, MaskPosition maskPosition) { - this.sticker = sticker; - this.maskPosition = maskPosition; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1202280912; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the position of a sticker in the set to which it belongs. The sticker set must be owned by the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetStickerPositionInSet extends Function { - /** - * Sticker. - */ - public InputFile sticker; - /** - * New position of the sticker in the set, 0-based. - */ - public int position; - - /** - * Default constructor for a function, which changes the position of a sticker in the set to which it belongs. The sticker set must be owned by the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetStickerPositionInSet() { - } - - /** - * Creates a function, which changes the position of a sticker in the set to which it belongs. The sticker set must be owned by the current user. - * - *

Returns {@link Ok Ok}

- * - * @param sticker Sticker. - * @param position New position of the sticker in the set, 0-based. - */ - public SetStickerPositionInSet(InputFile sticker, int position) { - this.sticker = sticker; - this.position = position; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2075281185; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets a sticker set thumbnail. - * - *

Returns {@link Ok Ok}

- */ - public static class SetStickerSetThumbnail extends Function { - /** - * Sticker set owner; ignored for regular users. - */ - public long userId; - /** - * Sticker set name. The sticker set must be owned by the current user. - */ - public String name; - /** - * Thumbnail to set; pass null to remove the sticker set thumbnail. - */ - public InputFile thumbnail; - /** - * Format of the thumbnail; pass null if thumbnail is removed. - */ - public StickerFormat format; - - /** - * Default constructor for a function, which sets a sticker set thumbnail. - * - *

Returns {@link Ok Ok}

- */ - public SetStickerSetThumbnail() { - } - - /** - * Creates a function, which sets a sticker set thumbnail. - * - *

Returns {@link Ok Ok}

- * - * @param userId Sticker set owner; ignored for regular users. - * @param name Sticker set name. The sticker set must be owned by the current user. - * @param thumbnail Thumbnail to set; pass null to remove the sticker set thumbnail. - * @param format Format of the thumbnail; pass null if thumbnail is removed. - */ - public SetStickerSetThumbnail(long userId, String name, InputFile thumbnail, StickerFormat format) { - this.userId = userId; - this.name = name; - this.thumbnail = thumbnail; - this.format = format; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1677617458; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets a sticker set title. - * - *

Returns {@link Ok Ok}

- */ - public static class SetStickerSetTitle extends Function { - /** - * Sticker set name. The sticker set must be owned by the current user. - */ - public String name; - /** - * New sticker set title. - */ - public String title; - - /** - * Default constructor for a function, which sets a sticker set title. - * - *

Returns {@link Ok Ok}

- */ - public SetStickerSetTitle() { - } - - /** - * Creates a function, which sets a sticker set title. - * - *

Returns {@link Ok Ok}

- * - * @param name Sticker set name. The sticker set must be owned by the current user. - * @param title New sticker set title. - */ - public SetStickerSetTitle(String name, String title) { - this.name = name; - this.title = title; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1693004706; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes name of an album of stories. If the album is owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. Returns the changed album. - * - *

Returns {@link StoryAlbum StoryAlbum}

- */ - public static class SetStoryAlbumName extends Function { - /** - * Identifier of the chat that owns the stories. - */ - public long chatId; - /** - * Identifier of the story album. - */ - public int storyAlbumId; - /** - * New name of the album; 1-12 characters. - */ - public String name; - - /** - * Default constructor for a function, which changes name of an album of stories. If the album is owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. Returns the changed album. - * - *

Returns {@link StoryAlbum StoryAlbum}

- */ - public SetStoryAlbumName() { - } - - /** - * Creates a function, which changes name of an album of stories. If the album is owned by a supergroup or a channel chat, then requires canEditStories administrator right in the chat. Returns the changed album. - * - *

Returns {@link StoryAlbum StoryAlbum}

- * - * @param chatId Identifier of the chat that owns the stories. - * @param storyAlbumId Identifier of the story album. - * @param name New name of the album; 1-12 characters. - */ - public SetStoryAlbumName(long chatId, int storyAlbumId, String name) { - this.chatId = chatId; - this.storyAlbumId = storyAlbumId; - this.name = name; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1143129794; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes privacy settings of a story. The method can be called only for stories posted on behalf of the current user and if story.canSetPrivacySettings == true. - * - *

Returns {@link Ok Ok}

- */ - public static class SetStoryPrivacySettings extends Function { - /** - * Identifier of the story. - */ - public int storyId; - /** - * The new privacy settings for the story. - */ - public StoryPrivacySettings privacySettings; - - /** - * Default constructor for a function, which changes privacy settings of a story. The method can be called only for stories posted on behalf of the current user and if story.canSetPrivacySettings == true. - * - *

Returns {@link Ok Ok}

- */ - public SetStoryPrivacySettings() { - } - - /** - * Creates a function, which changes privacy settings of a story. The method can be called only for stories posted on behalf of the current user and if story.canSetPrivacySettings == true. - * - *

Returns {@link Ok Ok}

- * - * @param storyId Identifier of the story. - * @param privacySettings The new privacy settings for the story. - */ - public SetStoryPrivacySettings(int storyId, StoryPrivacySettings privacySettings) { - this.storyId = storyId; - this.privacySettings = privacySettings; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -655801550; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes chosen reaction on a story that has already been sent; not supported for live stories. - * - *

Returns {@link Ok Ok}

- */ - public static class SetStoryReaction extends Function { - /** - * The identifier of the poster of the story. - */ - public long storyPosterChatId; - /** - * The identifier of the story. - */ - public int storyId; - /** - * Type of the reaction to set; pass null to remove the reaction. Custom emoji reactions can be used only by Telegram Premium users. Paid reactions can't be set. - */ - public ReactionType reactionType; - /** - * Pass true if the reaction needs to be added to recent reactions. - */ - public boolean updateRecentReactions; - - /** - * Default constructor for a function, which changes chosen reaction on a story that has already been sent; not supported for live stories. - * - *

Returns {@link Ok Ok}

- */ - public SetStoryReaction() { - } - - /** - * Creates a function, which changes chosen reaction on a story that has already been sent; not supported for live stories. - * - *

Returns {@link Ok Ok}

- * - * @param storyPosterChatId The identifier of the poster of the story. - * @param storyId The identifier of the story. - * @param reactionType Type of the reaction to set; pass null to remove the reaction. Custom emoji reactions can be used only by Telegram Premium users. Paid reactions can't be set. - * @param updateRecentReactions Pass true if the reaction needs to be added to recent reactions. - */ - public SetStoryReaction(long storyPosterChatId, int storyId, ReactionType reactionType, boolean updateRecentReactions) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - this.reactionType = reactionType; - this.updateRecentReactions = updateRecentReactions; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 250731529; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the custom emoji sticker set of a supergroup; requires canChangeInfo administrator right. The chat must have at least chatBoostFeatures.minCustomEmojiStickerSetBoostLevel boost level to pass the corresponding color. - * - *

Returns {@link Ok Ok}

- */ - public static class SetSupergroupCustomEmojiStickerSet extends Function { - /** - * Identifier of the supergroup. - */ - public long supergroupId; - /** - * New value of the custom emoji sticker set identifier for the supergroup. Use 0 to remove the custom emoji sticker set in the supergroup. - */ - public long customEmojiStickerSetId; - - /** - * Default constructor for a function, which changes the custom emoji sticker set of a supergroup; requires canChangeInfo administrator right. The chat must have at least chatBoostFeatures.minCustomEmojiStickerSetBoostLevel boost level to pass the corresponding color. - * - *

Returns {@link Ok Ok}

- */ - public SetSupergroupCustomEmojiStickerSet() { - } - - /** - * Creates a function, which changes the custom emoji sticker set of a supergroup; requires canChangeInfo administrator right. The chat must have at least chatBoostFeatures.minCustomEmojiStickerSetBoostLevel boost level to pass the corresponding color. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId Identifier of the supergroup. - * @param customEmojiStickerSetId New value of the custom emoji sticker set identifier for the supergroup. Use 0 to remove the custom emoji sticker set in the supergroup. - */ - public SetSupergroupCustomEmojiStickerSet(long supergroupId, long customEmojiStickerSetId) { - this.supergroupId = supergroupId; - this.customEmojiStickerSetId = customEmojiStickerSetId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1328894639; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the main profile tab of the channel; requires canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- */ - public static class SetSupergroupMainProfileTab extends Function { - /** - * Identifier of the channel. - */ - public long supergroupId; - /** - * The new value of the main profile tab. - */ - public ProfileTab mainProfileTab; - - /** - * Default constructor for a function, which changes the main profile tab of the channel; requires canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- */ - public SetSupergroupMainProfileTab() { - } - - /** - * Creates a function, which changes the main profile tab of the channel; requires canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId Identifier of the channel. - * @param mainProfileTab The new value of the main profile tab. - */ - public SetSupergroupMainProfileTab(long supergroupId, ProfileTab mainProfileTab) { - this.supergroupId = supergroupId; - this.mainProfileTab = mainProfileTab; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1314899548; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the sticker set of a supergroup; requires canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- */ - public static class SetSupergroupStickerSet extends Function { - /** - * Identifier of the supergroup. - */ - public long supergroupId; - /** - * New value of the supergroup sticker set identifier. Use 0 to remove the supergroup sticker set. - */ - public long stickerSetId; - - /** - * Default constructor for a function, which changes the sticker set of a supergroup; requires canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- */ - public SetSupergroupStickerSet() { - } - - /** - * Creates a function, which changes the sticker set of a supergroup; requires canChangeInfo administrator right. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId Identifier of the supergroup. - * @param stickerSetId New value of the supergroup sticker set identifier. Use 0 to remove the supergroup sticker set. - */ - public SetSupergroupStickerSet(long supergroupId, long stickerSetId) { - this.supergroupId = supergroupId; - this.stickerSetId = stickerSetId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2056344215; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the number of times the supergroup must be boosted by a user to ignore slow mode and chat permission restrictions; requires canRestrictMembers administrator right. - * - *

Returns {@link Ok Ok}

- */ - public static class SetSupergroupUnrestrictBoostCount extends Function { - /** - * Identifier of the supergroup. - */ - public long supergroupId; - /** - * New value of the unrestrictBoostCount supergroup setting; 0-8. Use 0 to remove the setting. - */ - public int unrestrictBoostCount; - - /** - * Default constructor for a function, which changes the number of times the supergroup must be boosted by a user to ignore slow mode and chat permission restrictions; requires canRestrictMembers administrator right. - * - *

Returns {@link Ok Ok}

- */ - public SetSupergroupUnrestrictBoostCount() { - } - - /** - * Creates a function, which changes the number of times the supergroup must be boosted by a user to ignore slow mode and chat permission restrictions; requires canRestrictMembers administrator right. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId Identifier of the supergroup. - * @param unrestrictBoostCount New value of the unrestrictBoostCount supergroup setting; 0-8. Use 0 to remove the setting. - */ - public SetSupergroupUnrestrictBoostCount(long supergroupId, int unrestrictBoostCount) { - this.supergroupId = supergroupId; - this.unrestrictBoostCount = unrestrictBoostCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 969814179; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the editable username of a supergroup or channel, requires owner privileges in the supergroup or channel. - * - *

Returns {@link Ok Ok}

- */ - public static class SetSupergroupUsername extends Function { - /** - * Identifier of the supergroup or channel. - */ - public long supergroupId; - /** - * New value of the username. Use an empty string to remove the username. The username can't be completely removed if there is another active or disabled username. - */ - public String username; - - /** - * Default constructor for a function, which changes the editable username of a supergroup or channel, requires owner privileges in the supergroup or channel. - * - *

Returns {@link Ok Ok}

- */ - public SetSupergroupUsername() { - } - - /** - * Creates a function, which changes the editable username of a supergroup or channel, requires owner privileges in the supergroup or channel. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId Identifier of the supergroup or channel. - * @param username New value of the username. Use an empty string to remove the username. The username can't be completely removed if there is another active or disabled username. - */ - public SetSupergroupUsername(long supergroupId, String username) { - this.supergroupId = supergroupId; - this.username = username; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1346325252; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets the parameters for TDLib initialization. Works only when the current authorization state is authorizationStateWaitTdlibParameters. - * - *

Returns {@link Ok Ok}

- */ - public static class SetTdlibParameters extends Function { - /** - * Pass true to use Telegram test environment instead of the production environment. - */ - public boolean useTestDc; - /** - * The path to the directory for the persistent database; if empty, the current working directory will be used. - */ - public String databaseDirectory; - /** - * The path to the directory for storing files; if empty, databaseDirectory will be used. - */ - public String filesDirectory; - /** - * Encryption key for the database. If the encryption key is invalid, then an error with code 401 will be returned. - */ - public byte[] databaseEncryptionKey; - /** - * Pass true to keep information about downloaded and uploaded files between application restarts. - */ - public boolean useFileDatabase; - /** - * Pass true to keep cache of users, basic groups, supergroups, channels and secret chats between restarts. Implies useFileDatabase. - */ - public boolean useChatInfoDatabase; - /** - * Pass true to keep cache of chats and messages between restarts. Implies useChatInfoDatabase. - */ - public boolean useMessageDatabase; - /** - * Pass true to enable support for secret chats. - */ - public boolean useSecretChats; - /** - * Application identifier for Telegram API access, which can be obtained at https://my.telegram.org. - */ - public int apiId; - /** - * Application identifier hash for Telegram API access, which can be obtained at https://my.telegram.org. - */ - public String apiHash; - /** - * IETF language tag of the user's operating system language; must be non-empty. - */ - public String systemLanguageCode; - /** - * Model of the device the application is being run on; must be non-empty. - */ - public String deviceModel; - /** - * Version of the operating system the application is being run on. If empty, the version is automatically detected by TDLib. - */ - public String systemVersion; - /** - * Application version; must be non-empty. - */ - public String applicationVersion; - - /** - * Default constructor for a function, which sets the parameters for TDLib initialization. Works only when the current authorization state is authorizationStateWaitTdlibParameters. - * - *

Returns {@link Ok Ok}

- */ - public SetTdlibParameters() { - } - - /** - * Creates a function, which sets the parameters for TDLib initialization. Works only when the current authorization state is authorizationStateWaitTdlibParameters. - * - *

Returns {@link Ok Ok}

- * - * @param useTestDc Pass true to use Telegram test environment instead of the production environment. - * @param databaseDirectory The path to the directory for the persistent database; if empty, the current working directory will be used. - * @param filesDirectory The path to the directory for storing files; if empty, databaseDirectory will be used. - * @param databaseEncryptionKey Encryption key for the database. If the encryption key is invalid, then an error with code 401 will be returned. - * @param useFileDatabase Pass true to keep information about downloaded and uploaded files between application restarts. - * @param useChatInfoDatabase Pass true to keep cache of users, basic groups, supergroups, channels and secret chats between restarts. Implies useFileDatabase. - * @param useMessageDatabase Pass true to keep cache of chats and messages between restarts. Implies useChatInfoDatabase. - * @param useSecretChats Pass true to enable support for secret chats. - * @param apiId Application identifier for Telegram API access, which can be obtained at https://my.telegram.org. - * @param apiHash Application identifier hash for Telegram API access, which can be obtained at https://my.telegram.org. - * @param systemLanguageCode IETF language tag of the user's operating system language; must be non-empty. - * @param deviceModel Model of the device the application is being run on; must be non-empty. - * @param systemVersion Version of the operating system the application is being run on. If empty, the version is automatically detected by TDLib. - * @param applicationVersion Application version; must be non-empty. - */ - public SetTdlibParameters(boolean useTestDc, String databaseDirectory, String filesDirectory, byte[] databaseEncryptionKey, boolean useFileDatabase, boolean useChatInfoDatabase, boolean useMessageDatabase, boolean useSecretChats, int apiId, String apiHash, String systemLanguageCode, String deviceModel, String systemVersion, String applicationVersion) { - this.useTestDc = useTestDc; - this.databaseDirectory = databaseDirectory; - this.filesDirectory = filesDirectory; - this.databaseEncryptionKey = databaseEncryptionKey; - this.useFileDatabase = useFileDatabase; - this.useChatInfoDatabase = useChatInfoDatabase; - this.useMessageDatabase = useMessageDatabase; - this.useSecretChats = useSecretChats; - this.apiId = apiId; - this.apiHash = apiHash; - this.systemLanguageCode = systemLanguageCode; - this.deviceModel = deviceModel; - this.systemVersion = systemVersion; - this.applicationVersion = applicationVersion; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -775883218; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes color scheme for the current user based on an owned or a hosted upgraded gift; for Telegram Premium users only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetUpgradedGiftColors extends Function { - /** - * Identifier of the upgradedGiftColors scheme to use. - */ - public long upgradedGiftColorsId; - - /** - * Default constructor for a function, which changes color scheme for the current user based on an owned or a hosted upgraded gift; for Telegram Premium users only. - * - *

Returns {@link Ok Ok}

- */ - public SetUpgradedGiftColors() { - } - - /** - * Creates a function, which changes color scheme for the current user based on an owned or a hosted upgraded gift; for Telegram Premium users only. - * - *

Returns {@link Ok Ok}

- * - * @param upgradedGiftColorsId Identifier of the upgradedGiftColors scheme to use. - */ - public SetUpgradedGiftColors(long upgradedGiftColorsId) { - this.upgradedGiftColorsId = upgradedGiftColorsId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -966832402; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the emoji status of a user; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class SetUserEmojiStatus extends Function { - /** - * Identifier of the user. - */ - public long userId; - /** - * New emoji status; pass null to switch to the default badge. - */ - public EmojiStatus emojiStatus; - - /** - * Default constructor for a function, which changes the emoji status of a user; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public SetUserEmojiStatus() { - } - - /** - * Creates a function, which changes the emoji status of a user; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param userId Identifier of the user. - * @param emojiStatus New emoji status; pass null to switch to the default badge. - */ - public SetUserEmojiStatus(long userId, EmojiStatus emojiStatus) { - this.userId = userId; - this.emojiStatus = emojiStatus; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -451519541; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes a note of a contact user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetUserNote extends Function { - /** - * User identifier. - */ - public long userId; - /** - * Note to set for the user; 0-getOption("user_note_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed. - */ - public FormattedText note; - - /** - * Default constructor for a function, which changes a note of a contact user. - * - *

Returns {@link Ok Ok}

- */ - public SetUserNote() { - } - - /** - * Creates a function, which changes a note of a contact user. - * - *

Returns {@link Ok Ok}

- * - * @param userId User identifier. - * @param note Note to set for the user; 0-getOption("user_note_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed. - */ - public SetUserNote(long userId, FormattedText note) { - this.userId = userId; - this.note = note; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -351487655; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes a personal profile photo of a contact user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetUserPersonalProfilePhoto extends Function { - /** - * User identifier. - */ - public long userId; - /** - * Profile photo to set; pass null to delete the photo; inputChatPhotoPrevious isn't supported in this function. - */ - public InputChatPhoto photo; - - /** - * Default constructor for a function, which changes a personal profile photo of a contact user. - * - *

Returns {@link Ok Ok}

- */ - public SetUserPersonalProfilePhoto() { - } - - /** - * Creates a function, which changes a personal profile photo of a contact user. - * - *

Returns {@link Ok Ok}

- * - * @param userId User identifier. - * @param photo Profile photo to set; pass null to delete the photo; inputChatPhotoPrevious isn't supported in this function. - */ - public SetUserPersonalProfilePhoto(long userId, InputChatPhoto photo) { - this.userId = userId; - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 464136438; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes user privacy settings. - * - *

Returns {@link Ok Ok}

- */ - public static class SetUserPrivacySettingRules extends Function { - /** - * The privacy setting. - */ - public UserPrivacySetting setting; - /** - * The new privacy rules. - */ - public UserPrivacySettingRules rules; - - /** - * Default constructor for a function, which changes user privacy settings. - * - *

Returns {@link Ok Ok}

- */ - public SetUserPrivacySettingRules() { - } - - /** - * Creates a function, which changes user privacy settings. - * - *

Returns {@link Ok Ok}

- * - * @param setting The privacy setting. - * @param rules The new privacy rules. - */ - public SetUserPrivacySettingRules(UserPrivacySetting setting, UserPrivacySettingRules rules) { - this.setting = setting; - this.rules = rules; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -473812741; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets support information for the given user; for Telegram support only. - * - *

Returns {@link UserSupportInfo UserSupportInfo}

- */ - public static class SetUserSupportInfo extends Function { - /** - * User identifier. - */ - public long userId; - /** - * New information message. - */ - public FormattedText message; - - /** - * Default constructor for a function, which sets support information for the given user; for Telegram support only. - * - *

Returns {@link UserSupportInfo UserSupportInfo}

- */ - public SetUserSupportInfo() { - } - - /** - * Creates a function, which sets support information for the given user; for Telegram support only. - * - *

Returns {@link UserSupportInfo UserSupportInfo}

- * - * @param userId User identifier. - * @param message New information message. - */ - public SetUserSupportInfo(long userId, FormattedText message) { - this.userId = userId; - this.message = message; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2088986621; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the editable username of the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class SetUsername extends Function { - /** - * The new value of the username. Use an empty string to remove the username. The username can't be completely removed if there is another active or disabled username. - */ - public String username; - - /** - * Default constructor for a function, which changes the editable username of the current user. - * - *

Returns {@link Ok Ok}

- */ - public SetUsername() { - } - - /** - * Creates a function, which changes the editable username of the current user. - * - *

Returns {@link Ok Ok}

- * - * @param username The new value of the username. Use an empty string to remove the username. The username can't be completely removed if there is another active or disabled username. - */ - public SetUsername(String username) { - this.username = username; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 439901214; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes default participant identifier, on whose behalf a video chat in the chat will be joined. - * - *

Returns {@link Ok Ok}

- */ - public static class SetVideoChatDefaultParticipant extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Default group call participant identifier to join the video chats in the chat. - */ - public MessageSender defaultParticipantId; - - /** - * Default constructor for a function, which changes default participant identifier, on whose behalf a video chat in the chat will be joined. - * - *

Returns {@link Ok Ok}

- */ - public SetVideoChatDefaultParticipant() { - } - - /** - * Creates a function, which changes default participant identifier, on whose behalf a video chat in the chat will be joined. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param defaultParticipantId Default group call participant identifier to join the video chats in the chat. - */ - public SetVideoChatDefaultParticipant(long chatId, MessageSender defaultParticipantId) { - this.chatId = chatId; - this.defaultParticipantId = defaultParticipantId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -240749901; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sets title of a video chat; requires groupCall.canBeManaged right. - * - *

Returns {@link Ok Ok}

- */ - public static class SetVideoChatTitle extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * New group call title; 1-64 characters. - */ - public String title; - - /** - * Default constructor for a function, which sets title of a video chat; requires groupCall.canBeManaged right. - * - *

Returns {@link Ok Ok}

- */ - public SetVideoChatTitle() { - } - - /** - * Creates a function, which sets title of a video chat; requires groupCall.canBeManaged right. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param title New group call title; 1-64 characters. - */ - public SetVideoChatTitle(int groupCallId, String title) { - this.groupCallId = groupCallId; - this.title = title; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1915482994; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Shares a chat after pressing a keyboardButtonTypeRequestChat button with the bot. - * - *

Returns {@link Ok Ok}

- */ - public static class ShareChatWithBot extends Function { - /** - * Identifier of the chat with the bot. - */ - public long chatId; - /** - * Identifier of the message with the button. - */ - public long messageId; - /** - * Identifier of the button. - */ - public int buttonId; - /** - * Identifier of the shared chat. - */ - public long sharedChatId; - /** - * Pass true to check that the chat can be shared by the button instead of actually sharing it. Doesn't check botIsMember and botAdministratorRights restrictions. If the bot must be a member, then all chats from getGroupsInCommon and all chats, where the user can add the bot, are suitable. In the latter case the bot will be automatically added to the chat. If the bot must be an administrator, then all chats, where the bot already has requested rights or can be added to administrators by the user, are suitable. In the latter case the bot will be automatically granted requested rights. - */ - public boolean onlyCheck; - - /** - * Default constructor for a function, which shares a chat after pressing a keyboardButtonTypeRequestChat button with the bot. - * - *

Returns {@link Ok Ok}

- */ - public ShareChatWithBot() { - } - - /** - * Creates a function, which shares a chat after pressing a keyboardButtonTypeRequestChat button with the bot. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat with the bot. - * @param messageId Identifier of the message with the button. - * @param buttonId Identifier of the button. - * @param sharedChatId Identifier of the shared chat. - * @param onlyCheck Pass true to check that the chat can be shared by the button instead of actually sharing it. Doesn't check botIsMember and botAdministratorRights restrictions. If the bot must be a member, then all chats from getGroupsInCommon and all chats, where the user can add the bot, are suitable. In the latter case the bot will be automatically added to the chat. If the bot must be an administrator, then all chats, where the bot already has requested rights or can be added to administrators by the user, are suitable. In the latter case the bot will be automatically granted requested rights. - */ - public ShareChatWithBot(long chatId, long messageId, int buttonId, long sharedChatId, boolean onlyCheck) { - this.chatId = chatId; - this.messageId = messageId; - this.buttonId = buttonId; - this.sharedChatId = sharedChatId; - this.onlyCheck = onlyCheck; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1504507166; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Shares the phone number of the current user with a mutual contact. Supposed to be called when the user clicks on chatActionBarSharePhoneNumber. - * - *

Returns {@link Ok Ok}

- */ - public static class SharePhoneNumber extends Function { - /** - * Identifier of the user with whom to share the phone number. The user must be a mutual contact. - */ - public long userId; - - /** - * Default constructor for a function, which shares the phone number of the current user with a mutual contact. Supposed to be called when the user clicks on chatActionBarSharePhoneNumber. - * - *

Returns {@link Ok Ok}

- */ - public SharePhoneNumber() { - } - - /** - * Creates a function, which shares the phone number of the current user with a mutual contact. Supposed to be called when the user clicks on chatActionBarSharePhoneNumber. - * - *

Returns {@link Ok Ok}

- * - * @param userId Identifier of the user with whom to share the phone number. The user must be a mutual contact. - */ - public SharePhoneNumber(long userId) { - this.userId = userId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1097130069; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Shares users after pressing a keyboardButtonTypeRequestUsers button with the bot. - * - *

Returns {@link Ok Ok}

- */ - public static class ShareUsersWithBot extends Function { - /** - * Identifier of the chat with the bot. - */ - public long chatId; - /** - * Identifier of the message with the button. - */ - public long messageId; - /** - * Identifier of the button. - */ - public int buttonId; - /** - * Identifiers of the shared users. - */ - public long[] sharedUserIds; - /** - * Pass true to check that the users can be shared by the button instead of actually sharing them. - */ - public boolean onlyCheck; - - /** - * Default constructor for a function, which shares users after pressing a keyboardButtonTypeRequestUsers button with the bot. - * - *

Returns {@link Ok Ok}

- */ - public ShareUsersWithBot() { - } - - /** - * Creates a function, which shares users after pressing a keyboardButtonTypeRequestUsers button with the bot. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat with the bot. - * @param messageId Identifier of the message with the button. - * @param buttonId Identifier of the button. - * @param sharedUserIds Identifiers of the shared users. - * @param onlyCheck Pass true to check that the users can be shared by the button instead of actually sharing them. - */ - public ShareUsersWithBot(long chatId, long messageId, int buttonId, long[] sharedUserIds, boolean onlyCheck) { - this.chatId = chatId; - this.messageId = messageId; - this.buttonId = buttonId; - this.sharedUserIds = sharedUserIds; - this.onlyCheck = onlyCheck; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1574608333; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Starts recording of an active group call; for video chats only. Requires groupCall.canBeManaged right. - * - *

Returns {@link Ok Ok}

- */ - public static class StartGroupCallRecording extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Group call recording title; 0-64 characters. - */ - public String title; - /** - * Pass true to record a video file instead of an audio file. - */ - public boolean recordVideo; - /** - * Pass true to use portrait orientation for video instead of landscape one. - */ - public boolean usePortraitOrientation; - - /** - * Default constructor for a function, which starts recording of an active group call; for video chats only. Requires groupCall.canBeManaged right. - * - *

Returns {@link Ok Ok}

- */ - public StartGroupCallRecording() { - } - - /** - * Creates a function, which starts recording of an active group call; for video chats only. Requires groupCall.canBeManaged right. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param title Group call recording title; 0-64 characters. - * @param recordVideo Pass true to record a video file instead of an audio file. - * @param usePortraitOrientation Pass true to use portrait orientation for video instead of landscape one. - */ - public StartGroupCallRecording(int groupCallId, String title, boolean recordVideo, boolean usePortraitOrientation) { - this.groupCallId = groupCallId; - this.title = title; - this.recordVideo = recordVideo; - this.usePortraitOrientation = usePortraitOrientation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1757774971; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Starts screen sharing in a joined group call; not supported in live stories. Returns join response payload for tgcalls. - * - *

Returns {@link Text Text}

- */ - public static class StartGroupCallScreenSharing extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Screen sharing audio channel synchronization source identifier; received from tgcalls. - */ - public int audioSourceId; - /** - * Group call join payload; received from tgcalls. - */ - public String payload; - - /** - * Default constructor for a function, which starts screen sharing in a joined group call; not supported in live stories. Returns join response payload for tgcalls. - * - *

Returns {@link Text Text}

- */ - public StartGroupCallScreenSharing() { - } - - /** - * Creates a function, which starts screen sharing in a joined group call; not supported in live stories. Returns join response payload for tgcalls. - * - *

Returns {@link Text Text}

- * - * @param groupCallId Group call identifier. - * @param audioSourceId Screen sharing audio channel synchronization source identifier; received from tgcalls. - * @param payload Group call join payload; received from tgcalls. - */ - public StartGroupCallScreenSharing(int groupCallId, int audioSourceId, String payload) { - this.groupCallId = groupCallId; - this.audioSourceId = audioSourceId; - this.payload = payload; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -884068051; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Starts a new live story on behalf of a chat; requires canPostStories administrator right for channel chats. - * - *

Returns {@link StartLiveStoryResult StartLiveStoryResult}

- */ - public static class StartLiveStory extends Function { - /** - * Identifier of the chat that will start the live story. Pass Saved Messages chat identifier when starting a live story on behalf of the current user, or a channel chat identifier. - */ - public long chatId; - /** - * The privacy settings for the story; ignored for stories posted on behalf of channel chats. - */ - public StoryPrivacySettings privacySettings; - /** - * Pass true if the content of the story must be protected from screenshotting. - */ - public boolean protectContent; - /** - * Pass true to create an RTMP stream instead of an ordinary group call. - */ - public boolean isRtmpStream; - /** - * Pass true to allow viewers of the story to send messages. - */ - public boolean enableMessages; - /** - * The minimum number of Telegram Stars that must be paid by viewers for each sent message to the call; 0-getOption("paid_group_call_message_star_count_max"). - */ - public long paidMessageStarCount; - - /** - * Default constructor for a function, which starts a new live story on behalf of a chat; requires canPostStories administrator right for channel chats. - * - *

Returns {@link StartLiveStoryResult StartLiveStoryResult}

- */ - public StartLiveStory() { - } - - /** - * Creates a function, which starts a new live story on behalf of a chat; requires canPostStories administrator right for channel chats. - * - *

Returns {@link StartLiveStoryResult StartLiveStoryResult}

- * - * @param chatId Identifier of the chat that will start the live story. Pass Saved Messages chat identifier when starting a live story on behalf of the current user, or a channel chat identifier. - * @param privacySettings The privacy settings for the story; ignored for stories posted on behalf of channel chats. - * @param protectContent Pass true if the content of the story must be protected from screenshotting. - * @param isRtmpStream Pass true to create an RTMP stream instead of an ordinary group call. - * @param enableMessages Pass true to allow viewers of the story to send messages. - * @param paidMessageStarCount The minimum number of Telegram Stars that must be paid by viewers for each sent message to the call; 0-getOption("paid_group_call_message_star_count_max"). - */ - public StartLiveStory(long chatId, StoryPrivacySettings privacySettings, boolean protectContent, boolean isRtmpStream, boolean enableMessages, long paidMessageStarCount) { - this.chatId = chatId; - this.privacySettings = privacySettings; - this.protectContent = protectContent; - this.isRtmpStream = isRtmpStream; - this.enableMessages = enableMessages; - this.paidMessageStarCount = paidMessageStarCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1253467958; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Starts a scheduled video chat. - * - *

Returns {@link Ok Ok}

- */ - public static class StartScheduledVideoChat extends Function { - /** - * Group call identifier of the video chat. - */ - public int groupCallId; - - /** - * Default constructor for a function, which starts a scheduled video chat. - * - *

Returns {@link Ok Ok}

- */ - public StartScheduledVideoChat() { - } - - /** - * Creates a function, which starts a scheduled video chat. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier of the video chat. - */ - public StartScheduledVideoChat(int groupCallId) { - this.groupCallId = groupCallId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1300829822; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Stops a poll sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- */ - public static class StopBusinessPoll extends Function { - /** - * Unique identifier of business connection on behalf of which the message with the poll was sent. - */ - public String businessConnectionId; - /** - * The chat the message belongs to. - */ - public long chatId; - /** - * Identifier of the message containing the poll. - */ - public long messageId; - /** - * The new message reply markup; pass null if none. - */ - public ReplyMarkup replyMarkup; - - /** - * Default constructor for a function, which stops a poll sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- */ - public StopBusinessPoll() { - } - - /** - * Creates a function, which stops a poll sent on behalf of a business account; for bots only. - * - *

Returns {@link BusinessMessage BusinessMessage}

- * - * @param businessConnectionId Unique identifier of business connection on behalf of which the message with the poll was sent. - * @param chatId The chat the message belongs to. - * @param messageId Identifier of the message containing the poll. - * @param replyMarkup The new message reply markup; pass null if none. - */ - public StopBusinessPoll(String businessConnectionId, long chatId, long messageId, ReplyMarkup replyMarkup) { - this.businessConnectionId = businessConnectionId; - this.chatId = chatId; - this.messageId = messageId; - this.replyMarkup = replyMarkup; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1142218400; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Stops a poll. - * - *

Returns {@link Ok Ok}

- */ - public static class StopPoll extends Function { - /** - * Identifier of the chat to which the poll belongs. - */ - public long chatId; - /** - * Identifier of the message containing the poll. Use messageProperties.canBeEdited to check whether the poll can be stopped. - */ - public long messageId; - /** - * The new message reply markup; pass null if none; for bots only. - */ - public ReplyMarkup replyMarkup; - - /** - * Default constructor for a function, which stops a poll. - * - *

Returns {@link Ok Ok}

- */ - public StopPoll() { - } - - /** - * Creates a function, which stops a poll. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat to which the poll belongs. - * @param messageId Identifier of the message containing the poll. Use messageProperties.canBeEdited to check whether the poll can be stopped. - * @param replyMarkup The new message reply markup; pass null if none; for bots only. - */ - public StopPoll(long chatId, long messageId, ReplyMarkup replyMarkup) { - this.chatId = chatId; - this.messageId = messageId; - this.replyMarkup = replyMarkup; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1659374253; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Suggests a birthdate to another regular user with common messages and allowing non-paid messages. - * - *

Returns {@link Ok Ok}

- */ - public static class SuggestUserBirthdate extends Function { - /** - * User identifier. - */ - public long userId; - /** - * Birthdate to suggest. - */ - public Birthdate birthdate; - - /** - * Default constructor for a function, which suggests a birthdate to another regular user with common messages and allowing non-paid messages. - * - *

Returns {@link Ok Ok}

- */ - public SuggestUserBirthdate() { - } - - /** - * Creates a function, which suggests a birthdate to another regular user with common messages and allowing non-paid messages. - * - *

Returns {@link Ok Ok}

- * - * @param userId User identifier. - * @param birthdate Birthdate to suggest. - */ - public SuggestUserBirthdate(long userId, Birthdate birthdate) { - this.userId = userId; - this.birthdate = birthdate; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 39506613; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Suggests a profile photo to another regular user with common messages and allowing non-paid messages. - * - *

Returns {@link Ok Ok}

- */ - public static class SuggestUserProfilePhoto extends Function { - /** - * User identifier. - */ - public long userId; - /** - * Profile photo to suggest; inputChatPhotoPrevious isn't supported in this function. - */ - public InputChatPhoto photo; - - /** - * Default constructor for a function, which suggests a profile photo to another regular user with common messages and allowing non-paid messages. - * - *

Returns {@link Ok Ok}

- */ - public SuggestUserProfilePhoto() { - } - - /** - * Creates a function, which suggests a profile photo to another regular user with common messages and allowing non-paid messages. - * - *

Returns {@link Ok Ok}

- * - * @param userId User identifier. - * @param photo Profile photo to suggest; inputChatPhotoPrevious isn't supported in this function. - */ - public SuggestUserProfilePhoto(long userId, InputChatPhoto photo) { - this.userId = userId; - this.photo = photo; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1788742557; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Summarizes content of the message with non-empty summaryLanguageCode. - * - *

Returns {@link FormattedText FormattedText}

- */ - public static class SummarizeMessage extends Function { - /** - * Identifier of the chat to which the message belongs. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * Pass a language code to which the summary will be translated; may be empty if translation isn't needed. See translateText.toLanguageCode for the list of supported values. - */ - public String translateToLanguageCode; - - /** - * Default constructor for a function, which summarizes content of the message with non-empty summaryLanguageCode. - * - *

Returns {@link FormattedText FormattedText}

- */ - public SummarizeMessage() { - } - - /** - * Creates a function, which summarizes content of the message with non-empty summaryLanguageCode. - * - *

Returns {@link FormattedText FormattedText}

- * - * @param chatId Identifier of the chat to which the message belongs. - * @param messageId Identifier of the message. - * @param translateToLanguageCode Pass a language code to which the summary will be translated; may be empty if translation isn't needed. See translateText.toLanguageCode for the list of supported values. - */ - public SummarizeMessage(long chatId, long messageId, String translateToLanguageCode) { - this.chatId = chatId; - this.messageId = messageId; - this.translateToLanguageCode = translateToLanguageCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1405194782; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Fetches the latest versions of all strings from a language pack in the current localization target from the server. This method doesn't need to be called explicitly for the current used/base language packs. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class SynchronizeLanguagePack extends Function { - /** - * Language pack identifier. - */ - public String languagePackId; - - /** - * Default constructor for a function, which fetches the latest versions of all strings from a language pack in the current localization target from the server. This method doesn't need to be called explicitly for the current used/base language packs. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public SynchronizeLanguagePack() { - } - - /** - * Creates a function, which fetches the latest versions of all strings from a language pack in the current localization target from the server. This method doesn't need to be called explicitly for the current used/base language packs. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- * - * @param languagePackId Language pack identifier. - */ - public SynchronizeLanguagePack(String languagePackId) { - this.languagePackId = languagePackId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2065307858; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Terminates all other sessions of the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class TerminateAllOtherSessions extends Function { - - /** - * Default constructor for a function, which terminates all other sessions of the current user. - * - *

Returns {@link Ok Ok}

- */ - public TerminateAllOtherSessions() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1874485523; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Terminates a session of the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class TerminateSession extends Function { - /** - * Session identifier. - */ - public long sessionId; - - /** - * Default constructor for a function, which terminates a session of the current user. - * - *

Returns {@link Ok Ok}

- */ - public TerminateSession() { - } - - /** - * Creates a function, which terminates a session of the current user. - * - *

Returns {@link Ok Ok}

- * - * @param sessionId Session identifier. - */ - public TerminateSession(long sessionId) { - this.sessionId = sessionId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -407385812; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the received bytes; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestBytes TestBytes}

- */ - public static class TestCallBytes extends Function { - /** - * Bytes to return. - */ - public byte[] x; - - /** - * Default constructor for a function, which returns the received bytes; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestBytes TestBytes}

- */ - public TestCallBytes() { - } - - /** - * Creates a function, which returns the received bytes; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestBytes TestBytes}

- * - * @param x Bytes to return. - */ - public TestCallBytes(byte[] x) { - this.x = x; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -736011607; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Does nothing; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class TestCallEmpty extends Function { - - /** - * Default constructor for a function, which does nothing; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public TestCallEmpty() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -627291626; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the received string; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestString TestString}

- */ - public static class TestCallString extends Function { - /** - * String to return. - */ - public String x; - - /** - * Default constructor for a function, which returns the received string; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestString TestString}

- */ - public TestCallString() { - } - - /** - * Creates a function, which returns the received string; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestString TestString}

- * - * @param x String to return. - */ - public TestCallString(String x) { - this.x = x; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1732818385; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the received vector of numbers; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestVectorInt TestVectorInt}

- */ - public static class TestCallVectorInt extends Function { - /** - * Vector of numbers to return. - */ - public int[] x; - - /** - * Default constructor for a function, which returns the received vector of numbers; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestVectorInt TestVectorInt}

- */ - public TestCallVectorInt() { - } - - /** - * Creates a function, which returns the received vector of numbers; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestVectorInt TestVectorInt}

- * - * @param x Vector of numbers to return. - */ - public TestCallVectorInt(int[] x) { - this.x = x; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2137277793; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the received vector of objects containing a number; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestVectorIntObject TestVectorIntObject}

- */ - public static class TestCallVectorIntObject extends Function { - /** - * Vector of objects to return. - */ - public TestInt[] x; - - /** - * Default constructor for a function, which returns the received vector of objects containing a number; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestVectorIntObject TestVectorIntObject}

- */ - public TestCallVectorIntObject() { - } - - /** - * Creates a function, which returns the received vector of objects containing a number; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestVectorIntObject TestVectorIntObject}

- * - * @param x Vector of objects to return. - */ - public TestCallVectorIntObject(TestInt[] x) { - this.x = x; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1825428218; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the received vector of strings; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestVectorString TestVectorString}

- */ - public static class TestCallVectorString extends Function { - /** - * Vector of strings to return. - */ - public String[] x; - - /** - * Default constructor for a function, which returns the received vector of strings; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestVectorString TestVectorString}

- */ - public TestCallVectorString() { - } - - /** - * Creates a function, which returns the received vector of strings; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestVectorString TestVectorString}

- * - * @param x Vector of strings to return. - */ - public TestCallVectorString(String[] x) { - this.x = x; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -408600900; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the received vector of objects containing a string; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestVectorStringObject TestVectorStringObject}

- */ - public static class TestCallVectorStringObject extends Function { - /** - * Vector of objects to return. - */ - public TestString[] x; - - /** - * Default constructor for a function, which returns the received vector of objects containing a string; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestVectorStringObject TestVectorStringObject}

- */ - public TestCallVectorStringObject() { - } - - /** - * Creates a function, which returns the received vector of objects containing a string; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestVectorStringObject TestVectorStringObject}

- * - * @param x Vector of objects to return. - */ - public TestCallVectorStringObject(TestString[] x) { - this.x = x; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1527666429; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Forces an updates.getDifference call to the Telegram servers; for testing only. - * - *

Returns {@link Ok Ok}

- */ - public static class TestGetDifference extends Function { - - /** - * Default constructor for a function, which forces an updates.getDifference call to the Telegram servers; for testing only. - * - *

Returns {@link Ok Ok}

- */ - public TestGetDifference() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1747084069; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends a simple network request to the Telegram servers; for testing only. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class TestNetwork extends Function { - - /** - * Default constructor for a function, which sends a simple network request to the Telegram servers; for testing only. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public TestNetwork() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1343998901; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends a simple network request to the Telegram servers via proxy; for testing only. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public static class TestProxy extends Function { - /** - * The proxy to test. - */ - public Proxy proxy; - /** - * Identifier of a datacenter with which to test connection. - */ - public int dcId; - /** - * The maximum overall timeout for the request. - */ - public double timeout; - - /** - * Default constructor for a function, which sends a simple network request to the Telegram servers via proxy; for testing only. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- */ - public TestProxy() { - } - - /** - * Creates a function, which sends a simple network request to the Telegram servers via proxy; for testing only. Can be called before authorization. - * - *

Returns {@link Ok Ok}

- * - * @param proxy The proxy to test. - * @param dcId Identifier of a datacenter with which to test connection. - * @param timeout The maximum overall timeout for the request. - */ - public TestProxy(Proxy proxy, int dcId, double timeout) { - this.proxy = proxy; - this.dcId = dcId; - this.timeout = timeout; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2057109116; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the specified error and ensures that the Error object is used; for testing only. Can be called synchronously. - * - *

Returns {@link Error Error}

- */ - public static class TestReturnError extends Function { - /** - * The error to be returned. - */ - public Error error; - - /** - * Default constructor for a function, which returns the specified error and ensures that the Error object is used; for testing only. Can be called synchronously. - * - *

Returns {@link Error Error}

- */ - public TestReturnError() { - } - - /** - * Creates a function, which returns the specified error and ensures that the Error object is used; for testing only. Can be called synchronously. - * - *

Returns {@link Error Error}

- * - * @param error The error to be returned. - */ - public TestReturnError(Error error) { - this.error = error; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 455179506; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Returns the squared received number; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestInt TestInt}

- */ - public static class TestSquareInt extends Function { - /** - * Number to square. - */ - public int x; - - /** - * Default constructor for a function, which returns the squared received number; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestInt TestInt}

- */ - public TestSquareInt() { - } - - /** - * Creates a function, which returns the squared received number; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link TestInt TestInt}

- * - * @param x Number to square. - */ - public TestSquareInt(int x) { - this.x = x; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -60135024; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Does nothing and ensures that the Update object is used; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link Update Update}

- */ - public static class TestUseUpdate extends Function { - - /** - * Default constructor for a function, which does nothing and ensures that the Update object is used; for testing only. This is an offline method. Can be called before authorization. - * - *

Returns {@link Update Update}

- */ - public TestUseUpdate() { - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 717094686; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes pause state of all files in the file download list. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleAllDownloadsArePaused extends Function { - /** - * Pass true to pause all downloads; pass false to unpause them. - */ - public boolean arePaused; - - /** - * Default constructor for a function, which changes pause state of all files in the file download list. - * - *

Returns {@link Ok Ok}

- */ - public ToggleAllDownloadsArePaused() { - } - - /** - * Creates a function, which changes pause state of all files in the file download list. - * - *

Returns {@link Ok Ok}

- * - * @param arePaused Pass true to pause all downloads; pass false to unpause them. - */ - public ToggleAllDownloadsArePaused(boolean arePaused) { - this.arePaused = arePaused; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1251512322; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether the bot can manage emoji status of the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleBotCanManageEmojiStatus extends Function { - /** - * User identifier of the bot. - */ - public long botUserId; - /** - * Pass true if the bot is allowed to change emoji status of the user; pass false otherwise. - */ - public boolean canManageEmojiStatus; - - /** - * Default constructor for a function, which toggles whether the bot can manage emoji status of the current user. - * - *

Returns {@link Ok Ok}

- */ - public ToggleBotCanManageEmojiStatus() { - } - - /** - * Creates a function, which toggles whether the bot can manage emoji status of the current user. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId User identifier of the bot. - * @param canManageEmojiStatus Pass true if the bot is allowed to change emoji status of the user; pass false otherwise. - */ - public ToggleBotCanManageEmojiStatus(long botUserId, boolean canManageEmojiStatus) { - this.botUserId = botUserId; - this.canManageEmojiStatus = canManageEmojiStatus; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 622495770; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Adds or removes a bot to attachment and side menu. Bot can be added to the menu, only if userTypeBot.canBeAddedToAttachmentMenu == true. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleBotIsAddedToAttachmentMenu extends Function { - /** - * Bot's user identifier. - */ - public long botUserId; - /** - * Pass true to add the bot to attachment menu; pass false to remove the bot from attachment menu. - */ - public boolean isAdded; - /** - * Pass true if the current user allowed the bot to send them messages. Ignored if isAdded is false. - */ - public boolean allowWriteAccess; - - /** - * Default constructor for a function, which adds or removes a bot to attachment and side menu. Bot can be added to the menu, only if userTypeBot.canBeAddedToAttachmentMenu == true. - * - *

Returns {@link Ok Ok}

- */ - public ToggleBotIsAddedToAttachmentMenu() { - } - - /** - * Creates a function, which adds or removes a bot to attachment and side menu. Bot can be added to the menu, only if userTypeBot.canBeAddedToAttachmentMenu == true. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId Bot's user identifier. - * @param isAdded Pass true to add the bot to attachment menu; pass false to remove the bot from attachment menu. - * @param allowWriteAccess Pass true if the current user allowed the bot to send them messages. Ignored if isAdded is false. - */ - public ToggleBotIsAddedToAttachmentMenu(long botUserId, boolean isAdded, boolean allowWriteAccess) { - this.botUserId = botUserId; - this.isAdded = isAdded; - this.allowWriteAccess = allowWriteAccess; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1906712934; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes active state for a username of a bot. The editable username can be disabled only if there are other active usernames. May return an error with a message "USERNAMES_ACTIVE_TOO_MUCH" if the maximum number of active usernames has been reached. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleBotUsernameIsActive extends Function { - /** - * Identifier of the target bot. - */ - public long botUserId; - /** - * The username to change. - */ - public String username; - /** - * Pass true to activate the username; pass false to disable it. - */ - public boolean isActive; - - /** - * Default constructor for a function, which changes active state for a username of a bot. The editable username can be disabled only if there are other active usernames. May return an error with a message "USERNAMES_ACTIVE_TOO_MUCH" if the maximum number of active usernames has been reached. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- */ - public ToggleBotUsernameIsActive() { - } - - /** - * Creates a function, which changes active state for a username of a bot. The editable username can be disabled only if there are other active usernames. May return an error with a message "USERNAMES_ACTIVE_TOO_MUCH" if the maximum number of active usernames has been reached. Can be called only if userTypeBot.canBeEdited == true. - * - *

Returns {@link Ok Ok}

- * - * @param botUserId Identifier of the target bot. - * @param username The username to change. - * @param isActive Pass true to activate the username; pass false to disable it. - */ - public ToggleBotUsernameIsActive(long botUserId, String username, boolean isActive) { - this.botUserId = botUserId; - this.username = username; - this.isActive = isActive; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2036569097; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Pauses or resumes the connected business bot in a specific chat. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleBusinessConnectedBotChatIsPaused extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Pass true to pause the connected bot in the chat; pass false to resume the bot. - */ - public boolean isPaused; - - /** - * Default constructor for a function, which pauses or resumes the connected business bot in a specific chat. - * - *

Returns {@link Ok Ok}

- */ - public ToggleBusinessConnectedBotChatIsPaused() { - } - - /** - * Creates a function, which pauses or resumes the connected business bot in a specific chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param isPaused Pass true to pause the connected bot in the chat; pass false to resume the bot. - */ - public ToggleBusinessConnectedBotChatIsPaused(long chatId, boolean isPaused) { - this.chatId = chatId; - this.isPaused = isPaused; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1328957509; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the value of the default disableNotification parameter, used when a message is sent to a chat. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleChatDefaultDisableNotification extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * New value of defaultDisableNotification. - */ - public boolean defaultDisableNotification; - - /** - * Default constructor for a function, which changes the value of the default disableNotification parameter, used when a message is sent to a chat. - * - *

Returns {@link Ok Ok}

- */ - public ToggleChatDefaultDisableNotification() { - } - - /** - * Creates a function, which changes the value of the default disableNotification parameter, used when a message is sent to a chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param defaultDisableNotification New value of defaultDisableNotification. - */ - public ToggleChatDefaultDisableNotification(long chatId, boolean defaultDisableNotification) { - this.chatId = chatId; - this.defaultDisableNotification = defaultDisableNotification; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 314794002; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether chat folder tags are enabled. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleChatFolderTags extends Function { - /** - * Pass true to enable folder tags; pass false to disable them. - */ - public boolean areTagsEnabled; - - /** - * Default constructor for a function, which toggles whether chat folder tags are enabled. - * - *

Returns {@link Ok Ok}

- */ - public ToggleChatFolderTags() { - } - - /** - * Creates a function, which toggles whether chat folder tags are enabled. - * - *

Returns {@link Ok Ok}

- * - * @param areTagsEnabled Pass true to enable folder tags; pass false to disable them. - */ - public ToggleChatFolderTags(boolean areTagsEnabled) { - this.areTagsEnabled = areTagsEnabled; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2092209084; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether notifications for new gifts received by a channel chat are sent to the current user; requires canPostMessages administrator right in the chat. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleChatGiftNotifications extends Function { - /** - * Identifier of the channel chat. - */ - public long chatId; - /** - * Pass true to enable notifications about new gifts owned by the channel chat; pass false to disable the notifications. - */ - public boolean areEnabled; - - /** - * Default constructor for a function, which toggles whether notifications for new gifts received by a channel chat are sent to the current user; requires canPostMessages administrator right in the chat. - * - *

Returns {@link Ok Ok}

- */ - public ToggleChatGiftNotifications() { - } - - /** - * Creates a function, which toggles whether notifications for new gifts received by a channel chat are sent to the current user; requires canPostMessages administrator right in the chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the channel chat. - * @param areEnabled Pass true to enable notifications about new gifts owned by the channel chat; pass false to disable the notifications. - */ - public ToggleChatGiftNotifications(long chatId, boolean areEnabled) { - this.chatId = chatId; - this.areEnabled = areEnabled; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2069429154; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the ability of users to save, forward, or copy chat content. Requires owner privileges in basic groups, supergroups and channels. Requires Telegram Premium to enable protected content in private chats. Not available in Saved Messages and private chats with bots or support accounts. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleChatHasProtectedContent extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * New value of hasProtectedContent. - */ - public boolean hasProtectedContent; - - /** - * Default constructor for a function, which changes the ability of users to save, forward, or copy chat content. Requires owner privileges in basic groups, supergroups and channels. Requires Telegram Premium to enable protected content in private chats. Not available in Saved Messages and private chats with bots or support accounts. - * - *

Returns {@link Ok Ok}

- */ - public ToggleChatHasProtectedContent() { - } - - /** - * Creates a function, which changes the ability of users to save, forward, or copy chat content. Requires owner privileges in basic groups, supergroups and channels. Requires Telegram Premium to enable protected content in private chats. Not available in Saved Messages and private chats with bots or support accounts. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param hasProtectedContent New value of hasProtectedContent. - */ - public ToggleChatHasProtectedContent(long chatId, boolean hasProtectedContent) { - this.chatId = chatId; - this.hasProtectedContent = hasProtectedContent; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 975231309; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the marked as unread state of a chat. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleChatIsMarkedAsUnread extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * New value of isMarkedAsUnread. - */ - public boolean isMarkedAsUnread; - - /** - * Default constructor for a function, which changes the marked as unread state of a chat. - * - *

Returns {@link Ok Ok}

- */ - public ToggleChatIsMarkedAsUnread() { - } - - /** - * Creates a function, which changes the marked as unread state of a chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param isMarkedAsUnread New value of isMarkedAsUnread. - */ - public ToggleChatIsMarkedAsUnread(long chatId, boolean isMarkedAsUnread) { - this.chatId = chatId; - this.isMarkedAsUnread = isMarkedAsUnread; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -986129697; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the pinned state of a chat. There can be up to getOption("pinned_chat_count_max")/getOption("pinned_archived_chat_count_max") pinned non-secret chats and the same number of secret chats in the main/archive chat list. The limit can be increased with Telegram Premium. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleChatIsPinned extends Function { - /** - * Chat list in which to change the pinned state of the chat. - */ - public ChatList chatList; - /** - * Chat identifier. - */ - public long chatId; - /** - * Pass true to pin the chat; pass false to unpin it. - */ - public boolean isPinned; - - /** - * Default constructor for a function, which changes the pinned state of a chat. There can be up to getOption("pinned_chat_count_max")/getOption("pinned_archived_chat_count_max") pinned non-secret chats and the same number of secret chats in the main/archive chat list. The limit can be increased with Telegram Premium. - * - *

Returns {@link Ok Ok}

- */ - public ToggleChatIsPinned() { - } - - /** - * Creates a function, which changes the pinned state of a chat. There can be up to getOption("pinned_chat_count_max")/getOption("pinned_archived_chat_count_max") pinned non-secret chats and the same number of secret chats in the main/archive chat list. The limit can be increased with Telegram Premium. - * - *

Returns {@link Ok Ok}

- * - * @param chatList Chat list in which to change the pinned state of the chat. - * @param chatId Chat identifier. - * @param isPinned Pass true to pin the chat; pass false to unpin it. - */ - public ToggleChatIsPinned(ChatList chatList, long chatId, boolean isPinned) { - this.chatList = chatList; - this.chatId = chatId; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1485429186; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the translatable state of a chat. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleChatIsTranslatable extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * New value of isTranslatable. - */ - public boolean isTranslatable; - - /** - * Default constructor for a function, which changes the translatable state of a chat. - * - *

Returns {@link Ok Ok}

- */ - public ToggleChatIsTranslatable() { - } - - /** - * Creates a function, which changes the translatable state of a chat. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param isTranslatable New value of isTranslatable. - */ - public ToggleChatIsTranslatable(long chatId, boolean isTranslatable) { - this.chatId = chatId; - this.isTranslatable = isTranslatable; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1812345889; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the viewAsTopics setting of a forum chat or Saved Messages. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleChatViewAsTopics extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * New value of viewAsTopics. - */ - public boolean viewAsTopics; - - /** - * Default constructor for a function, which changes the viewAsTopics setting of a forum chat or Saved Messages. - * - *

Returns {@link Ok Ok}

- */ - public ToggleChatViewAsTopics() { - } - - /** - * Creates a function, which changes the viewAsTopics setting of a forum chat or Saved Messages. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param viewAsTopics New value of viewAsTopics. - */ - public ToggleChatViewAsTopics(long chatId, boolean viewAsTopics) { - this.chatId = chatId; - this.viewAsTopics = viewAsTopics; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 724009948; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Allows to send unpaid messages to the given topic of the channel direct messages chat administered by the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleDirectMessagesChatTopicCanSendUnpaidMessages extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the topic. - */ - public long topicId; - /** - * Pass true to allow unpaid messages; pass false to disallow unpaid messages. - */ - public boolean canSendUnpaidMessages; - /** - * Pass true to refund the user previously paid messages. - */ - public boolean refundPayments; - - /** - * Default constructor for a function, which allows to send unpaid messages to the given topic of the channel direct messages chat administered by the current user. - * - *

Returns {@link Ok Ok}

- */ - public ToggleDirectMessagesChatTopicCanSendUnpaidMessages() { - } - - /** - * Creates a function, which allows to send unpaid messages to the given topic of the channel direct messages chat administered by the current user. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param topicId Identifier of the topic. - * @param canSendUnpaidMessages Pass true to allow unpaid messages; pass false to disallow unpaid messages. - * @param refundPayments Pass true to refund the user previously paid messages. - */ - public ToggleDirectMessagesChatTopicCanSendUnpaidMessages(long chatId, long topicId, boolean canSendUnpaidMessages, boolean refundPayments) { - this.chatId = chatId; - this.topicId = topicId; - this.canSendUnpaidMessages = canSendUnpaidMessages; - this.refundPayments = refundPayments; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -335898703; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes pause state of a file in the file download list. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleDownloadIsPaused extends Function { - /** - * Identifier of the downloaded file. - */ - public int fileId; - /** - * Pass true if the download is paused. - */ - public boolean isPaused; - - /** - * Default constructor for a function, which changes pause state of a file in the file download list. - * - *

Returns {@link Ok Ok}

- */ - public ToggleDownloadIsPaused() { - } - - /** - * Creates a function, which changes pause state of a file in the file download list. - * - *

Returns {@link Ok Ok}

- * - * @param fileId Identifier of the downloaded file. - * @param isPaused Pass true if the download is paused. - */ - public ToggleDownloadIsPaused(int fileId, boolean isPaused) { - this.fileId = fileId; - this.isPaused = isPaused; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -947493099; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether a topic is closed in a forum supergroup chat; requires canManageTopics administrator right in the supergroup unless the user is creator of the topic. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleForumTopicIsClosed extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * Forum topic identifier. - */ - public int forumTopicId; - /** - * Pass true to close the topic; pass false to reopen it. - */ - public boolean isClosed; - - /** - * Default constructor for a function, which toggles whether a topic is closed in a forum supergroup chat; requires canManageTopics administrator right in the supergroup unless the user is creator of the topic. - * - *

Returns {@link Ok Ok}

- */ - public ToggleForumTopicIsClosed() { - } - - /** - * Creates a function, which toggles whether a topic is closed in a forum supergroup chat; requires canManageTopics administrator right in the supergroup unless the user is creator of the topic. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat. - * @param forumTopicId Forum topic identifier. - * @param isClosed Pass true to close the topic; pass false to reopen it. - */ - public ToggleForumTopicIsClosed(long chatId, int forumTopicId, boolean isClosed) { - this.chatId = chatId; - this.forumTopicId = forumTopicId; - this.isClosed = isClosed; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 982153376; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the pinned state of a topic in a forum supergroup chat or a chat with a bot with topics; requires canManageTopics administrator right in the supergroup. There can be up to getOption("pinned_forum_topic_count_max") pinned forum topics. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleForumTopicIsPinned extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Forum topic identifier. - */ - public int forumTopicId; - /** - * Pass true to pin the topic; pass false to unpin it. - */ - public boolean isPinned; - - /** - * Default constructor for a function, which changes the pinned state of a topic in a forum supergroup chat or a chat with a bot with topics; requires canManageTopics administrator right in the supergroup. There can be up to getOption("pinned_forum_topic_count_max") pinned forum topics. - * - *

Returns {@link Ok Ok}

- */ - public ToggleForumTopicIsPinned() { - } - - /** - * Creates a function, which changes the pinned state of a topic in a forum supergroup chat or a chat with a bot with topics; requires canManageTopics administrator right in the supergroup. There can be up to getOption("pinned_forum_topic_count_max") pinned forum topics. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param forumTopicId Forum topic identifier. - * @param isPinned Pass true to pin the topic; pass false to unpin it. - */ - public ToggleForumTopicIsPinned(long chatId, int forumTopicId, boolean isPinned) { - this.chatId = chatId; - this.forumTopicId = forumTopicId; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1474651795; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether a General topic is hidden in a forum supergroup chat; requires canManageTopics administrator right in the supergroup. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleGeneralForumTopicIsHidden extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * Pass true to hide and close the General topic; pass false to unhide it. - */ - public boolean isHidden; - - /** - * Default constructor for a function, which toggles whether a General topic is hidden in a forum supergroup chat; requires canManageTopics administrator right in the supergroup. - * - *

Returns {@link Ok Ok}

- */ - public ToggleGeneralForumTopicIsHidden() { - } - - /** - * Creates a function, which toggles whether a General topic is hidden in a forum supergroup chat; requires canManageTopics administrator right in the supergroup. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat. - * @param isHidden Pass true to hide and close the General topic; pass false to unhide it. - */ - public ToggleGeneralForumTopicIsHidden(long chatId, boolean isHidden) { - this.chatId = chatId; - this.isHidden = isHidden; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1595741256; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether a gift is shown on the current user's or the channel's profile page; requires canPostMessages administrator right in the channel chat. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleGiftIsSaved extends Function { - /** - * Identifier of the gift. - */ - public String receivedGiftId; - /** - * Pass true to display the gift on the user's or the channel's profile page; pass false to remove it from the profile page. - */ - public boolean isSaved; - - /** - * Default constructor for a function, which toggles whether a gift is shown on the current user's or the channel's profile page; requires canPostMessages administrator right in the channel chat. - * - *

Returns {@link Ok Ok}

- */ - public ToggleGiftIsSaved() { - } - - /** - * Creates a function, which toggles whether a gift is shown on the current user's or the channel's profile page; requires canPostMessages administrator right in the channel chat. - * - *

Returns {@link Ok Ok}

- * - * @param receivedGiftId Identifier of the gift. - * @param isSaved Pass true to display the gift on the user's or the channel's profile page; pass false to remove it from the profile page. - */ - public ToggleGiftIsSaved(String receivedGiftId, boolean isSaved) { - this.receivedGiftId = receivedGiftId; - this.isSaved = isSaved; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 693198065; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether participants of a group call can send messages there. Requires groupCall.canToggleAreMessagesAllowed right. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleGroupCallAreMessagesAllowed extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * New value of the areMessagesAllowed setting. - */ - public boolean areMessagesAllowed; - - /** - * Default constructor for a function, which toggles whether participants of a group call can send messages there. Requires groupCall.canToggleAreMessagesAllowed right. - * - *

Returns {@link Ok Ok}

- */ - public ToggleGroupCallAreMessagesAllowed() { - } - - /** - * Creates a function, which toggles whether participants of a group call can send messages there. Requires groupCall.canToggleAreMessagesAllowed right. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param areMessagesAllowed New value of the areMessagesAllowed setting. - */ - public ToggleGroupCallAreMessagesAllowed(int groupCallId, boolean areMessagesAllowed) { - this.groupCallId = groupCallId; - this.areMessagesAllowed = areMessagesAllowed; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1535668758; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether current user's video is enabled. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleGroupCallIsMyVideoEnabled extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Pass true if the current user's video is enabled. - */ - public boolean isMyVideoEnabled; - - /** - * Default constructor for a function, which toggles whether current user's video is enabled. - * - *

Returns {@link Ok Ok}

- */ - public ToggleGroupCallIsMyVideoEnabled() { - } - - /** - * Creates a function, which toggles whether current user's video is enabled. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param isMyVideoEnabled Pass true if the current user's video is enabled. - */ - public ToggleGroupCallIsMyVideoEnabled(int groupCallId, boolean isMyVideoEnabled) { - this.groupCallId = groupCallId; - this.isMyVideoEnabled = isMyVideoEnabled; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1624289030; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether current user's video is paused. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleGroupCallIsMyVideoPaused extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Pass true if the current user's video is paused. - */ - public boolean isMyVideoPaused; - - /** - * Default constructor for a function, which toggles whether current user's video is paused. - * - *

Returns {@link Ok Ok}

- */ - public ToggleGroupCallIsMyVideoPaused() { - } - - /** - * Creates a function, which toggles whether current user's video is paused. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param isMyVideoPaused Pass true if the current user's video is paused. - */ - public ToggleGroupCallIsMyVideoPaused(int groupCallId, boolean isMyVideoPaused) { - this.groupCallId = groupCallId; - this.isMyVideoPaused = isMyVideoPaused; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -478875239; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether a group call participant hand is rased; for video chats only. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleGroupCallParticipantIsHandRaised extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Participant identifier. - */ - public MessageSender participantId; - /** - * Pass true if the user's hand needs to be raised. Only self hand can be raised. Requires groupCall.canBeManaged right to lower other's hand. - */ - public boolean isHandRaised; - - /** - * Default constructor for a function, which toggles whether a group call participant hand is rased; for video chats only. - * - *

Returns {@link Ok Ok}

- */ - public ToggleGroupCallParticipantIsHandRaised() { - } - - /** - * Creates a function, which toggles whether a group call participant hand is rased; for video chats only. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param participantId Participant identifier. - * @param isHandRaised Pass true if the user's hand needs to be raised. Only self hand can be raised. Requires groupCall.canBeManaged right to lower other's hand. - */ - public ToggleGroupCallParticipantIsHandRaised(int groupCallId, MessageSender participantId, boolean isHandRaised) { - this.groupCallId = groupCallId; - this.participantId = participantId; - this.isHandRaised = isHandRaised; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1896127519; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether a participant of an active group call is muted, unmuted, or allowed to unmute themselves; not supported for live stories. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleGroupCallParticipantIsMuted extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Participant identifier. - */ - public MessageSender participantId; - /** - * Pass true to mute the user; pass false to unmute them. - */ - public boolean isMuted; - - /** - * Default constructor for a function, which toggles whether a participant of an active group call is muted, unmuted, or allowed to unmute themselves; not supported for live stories. - * - *

Returns {@link Ok Ok}

- */ - public ToggleGroupCallParticipantIsMuted() { - } - - /** - * Creates a function, which toggles whether a participant of an active group call is muted, unmuted, or allowed to unmute themselves; not supported for live stories. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param participantId Participant identifier. - * @param isMuted Pass true to mute the user; pass false to unmute them. - */ - public ToggleGroupCallParticipantIsMuted(int groupCallId, MessageSender participantId, boolean isMuted) { - this.groupCallId = groupCallId; - this.participantId = participantId; - this.isMuted = isMuted; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1308093433; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Pauses or unpauses screen sharing in a joined group call; not supported in live stories. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleGroupCallScreenSharingIsPaused extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * Pass true to pause screen sharing; pass false to unpause it. - */ - public boolean isPaused; - - /** - * Default constructor for a function, which pauses or unpauses screen sharing in a joined group call; not supported in live stories. - * - *

Returns {@link Ok Ok}

- */ - public ToggleGroupCallScreenSharingIsPaused() { - } - - /** - * Creates a function, which pauses or unpauses screen sharing in a joined group call; not supported in live stories. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param isPaused Pass true to pause screen sharing; pass false to unpause it. - */ - public ToggleGroupCallScreenSharingIsPaused(int groupCallId, boolean isPaused) { - this.groupCallId = groupCallId; - this.isPaused = isPaused; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1602530464; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether the current user has sponsored messages enabled. The setting has no effect for users without Telegram Premium for which sponsored messages are always enabled. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleHasSponsoredMessagesEnabled extends Function { - /** - * Pass true to enable sponsored messages for the current user; false to disable them. - */ - public boolean hasSponsoredMessagesEnabled; - - /** - * Default constructor for a function, which toggles whether the current user has sponsored messages enabled. The setting has no effect for users without Telegram Premium for which sponsored messages are always enabled. - * - *

Returns {@link Ok Ok}

- */ - public ToggleHasSponsoredMessagesEnabled() { - } - - /** - * Creates a function, which toggles whether the current user has sponsored messages enabled. The setting has no effect for users without Telegram Premium for which sponsored messages are always enabled. - * - *

Returns {@link Ok Ok}

- * - * @param hasSponsoredMessagesEnabled Pass true to enable sponsored messages for the current user; false to disable them. - */ - public ToggleHasSponsoredMessagesEnabled(boolean hasSponsoredMessagesEnabled) { - this.hasSponsoredMessagesEnabled = hasSponsoredMessagesEnabled; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1963285740; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the pinned state of a Saved Messages topic. There can be up to getOption("pinned_saved_messages_topic_count_max") pinned topics. The limit can be increased with Telegram Premium. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleSavedMessagesTopicIsPinned extends Function { - /** - * Identifier of Saved Messages topic to pin or unpin. - */ - public long savedMessagesTopicId; - /** - * Pass true to pin the topic; pass false to unpin it. - */ - public boolean isPinned; - - /** - * Default constructor for a function, which changes the pinned state of a Saved Messages topic. There can be up to getOption("pinned_saved_messages_topic_count_max") pinned topics. The limit can be increased with Telegram Premium. - * - *

Returns {@link Ok Ok}

- */ - public ToggleSavedMessagesTopicIsPinned() { - } - - /** - * Creates a function, which changes the pinned state of a Saved Messages topic. There can be up to getOption("pinned_saved_messages_topic_count_max") pinned topics. The limit can be increased with Telegram Premium. - * - *

Returns {@link Ok Ok}

- * - * @param savedMessagesTopicId Identifier of Saved Messages topic to pin or unpin. - * @param isPinned Pass true to pin the topic; pass false to unpin it. - */ - public ToggleSavedMessagesTopicIsPinned(long savedMessagesTopicId, boolean isPinned) { - this.savedMessagesTopicId = savedMessagesTopicId; - this.isPinned = isPinned; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1588378164; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether a session can accept incoming calls. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleSessionCanAcceptCalls extends Function { - /** - * Session identifier. - */ - public long sessionId; - /** - * Pass true to allow accepting incoming calls by the session; pass false otherwise. - */ - public boolean canAcceptCalls; - - /** - * Default constructor for a function, which toggles whether a session can accept incoming calls. - * - *

Returns {@link Ok Ok}

- */ - public ToggleSessionCanAcceptCalls() { - } - - /** - * Creates a function, which toggles whether a session can accept incoming calls. - * - *

Returns {@link Ok Ok}

- * - * @param sessionId Session identifier. - * @param canAcceptCalls Pass true to allow accepting incoming calls by the session; pass false otherwise. - */ - public ToggleSessionCanAcceptCalls(long sessionId, boolean canAcceptCalls) { - this.sessionId = sessionId; - this.canAcceptCalls = canAcceptCalls; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1819027208; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether a session can accept incoming secret chats. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleSessionCanAcceptSecretChats extends Function { - /** - * Session identifier. - */ - public long sessionId; - /** - * Pass true to allow accepting secret chats by the session; pass false otherwise. - */ - public boolean canAcceptSecretChats; - - /** - * Default constructor for a function, which toggles whether a session can accept incoming secret chats. - * - *

Returns {@link Ok Ok}

- */ - public ToggleSessionCanAcceptSecretChats() { - } - - /** - * Creates a function, which toggles whether a session can accept incoming secret chats. - * - *

Returns {@link Ok Ok}

- * - * @param sessionId Session identifier. - * @param canAcceptSecretChats Pass true to allow accepting secret chats by the session; pass false otherwise. - */ - public ToggleSessionCanAcceptSecretChats(long sessionId, boolean canAcceptSecretChats) { - this.sessionId = sessionId; - this.canAcceptSecretChats = canAcceptSecretChats; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1000843390; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether a story is accessible after expiration. Can be called only if story.canToggleIsPostedToChatPage == true. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleStoryIsPostedToChatPage extends Function { - /** - * Identifier of the chat that posted the story. - */ - public long storyPosterChatId; - /** - * Identifier of the story. - */ - public int storyId; - /** - * Pass true to make the story accessible after expiration; pass false to make it private. - */ - public boolean isPostedToChatPage; - - /** - * Default constructor for a function, which toggles whether a story is accessible after expiration. Can be called only if story.canToggleIsPostedToChatPage == true. - * - *

Returns {@link Ok Ok}

- */ - public ToggleStoryIsPostedToChatPage() { - } - - /** - * Creates a function, which toggles whether a story is accessible after expiration. Can be called only if story.canToggleIsPostedToChatPage == true. - * - *

Returns {@link Ok Ok}

- * - * @param storyPosterChatId Identifier of the chat that posted the story. - * @param storyId Identifier of the story. - * @param isPostedToChatPage Pass true to make the story accessible after expiration; pass false to make it private. - */ - public ToggleStoryIsPostedToChatPage(long storyPosterChatId, int storyId, boolean isPostedToChatPage) { - this.storyPosterChatId = storyPosterChatId; - this.storyId = storyId; - this.isPostedToChatPage = isPostedToChatPage; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -2141806228; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether sponsored messages are shown in the channel chat; requires owner privileges in the channel. The chat must have at least chatBoostFeatures.minSponsoredMessageDisableBoostLevel boost level to disable sponsored messages. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleSupergroupCanHaveSponsoredMessages extends Function { - /** - * The identifier of the channel. - */ - public long supergroupId; - /** - * The new value of canHaveSponsoredMessages. - */ - public boolean canHaveSponsoredMessages; - - /** - * Default constructor for a function, which toggles whether sponsored messages are shown in the channel chat; requires owner privileges in the channel. The chat must have at least chatBoostFeatures.minSponsoredMessageDisableBoostLevel boost level to disable sponsored messages. - * - *

Returns {@link Ok Ok}

- */ - public ToggleSupergroupCanHaveSponsoredMessages() { - } - - /** - * Creates a function, which toggles whether sponsored messages are shown in the channel chat; requires owner privileges in the channel. The chat must have at least chatBoostFeatures.minSponsoredMessageDisableBoostLevel boost level to disable sponsored messages. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId The identifier of the channel. - * @param canHaveSponsoredMessages The new value of canHaveSponsoredMessages. - */ - public ToggleSupergroupCanHaveSponsoredMessages(long supergroupId, boolean canHaveSponsoredMessages) { - this.supergroupId = supergroupId; - this.canHaveSponsoredMessages = canHaveSponsoredMessages; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1098204302; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether aggressive anti-spam checks are enabled in the supergroup. Can be called only if supergroupFullInfo.canToggleAggressiveAntiSpam == true. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleSupergroupHasAggressiveAntiSpamEnabled extends Function { - /** - * The identifier of the supergroup, which isn't a broadcast group. - */ - public long supergroupId; - /** - * The new value of hasAggressiveAntiSpamEnabled. - */ - public boolean hasAggressiveAntiSpamEnabled; - - /** - * Default constructor for a function, which toggles whether aggressive anti-spam checks are enabled in the supergroup. Can be called only if supergroupFullInfo.canToggleAggressiveAntiSpam == true. - * - *

Returns {@link Ok Ok}

- */ - public ToggleSupergroupHasAggressiveAntiSpamEnabled() { - } - - /** - * Creates a function, which toggles whether aggressive anti-spam checks are enabled in the supergroup. Can be called only if supergroupFullInfo.canToggleAggressiveAntiSpam == true. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId The identifier of the supergroup, which isn't a broadcast group. - * @param hasAggressiveAntiSpamEnabled The new value of hasAggressiveAntiSpamEnabled. - */ - public ToggleSupergroupHasAggressiveAntiSpamEnabled(long supergroupId, boolean hasAggressiveAntiSpamEnabled) { - this.supergroupId = supergroupId; - this.hasAggressiveAntiSpamEnabled = hasAggressiveAntiSpamEnabled; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1748956943; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether messages are automatically translated in the channel chat; requires canChangeInfo administrator right in the channel. The chat must have at least chatBoostFeatures.minAutomaticTranslationBoostLevel boost level to enable automatic translation. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleSupergroupHasAutomaticTranslation extends Function { - /** - * The identifier of the channel. - */ - public long supergroupId; - /** - * The new value of hasAutomaticTranslation. - */ - public boolean hasAutomaticTranslation; - - /** - * Default constructor for a function, which toggles whether messages are automatically translated in the channel chat; requires canChangeInfo administrator right in the channel. The chat must have at least chatBoostFeatures.minAutomaticTranslationBoostLevel boost level to enable automatic translation. - * - *

Returns {@link Ok Ok}

- */ - public ToggleSupergroupHasAutomaticTranslation() { - } - - /** - * Creates a function, which toggles whether messages are automatically translated in the channel chat; requires canChangeInfo administrator right in the channel. The chat must have at least chatBoostFeatures.minAutomaticTranslationBoostLevel boost level to enable automatic translation. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId The identifier of the channel. - * @param hasAutomaticTranslation The new value of hasAutomaticTranslation. - */ - public ToggleSupergroupHasAutomaticTranslation(long supergroupId, boolean hasAutomaticTranslation) { - this.supergroupId = supergroupId; - this.hasAutomaticTranslation = hasAutomaticTranslation; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -184993048; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether non-administrators can receive only administrators and bots using getSupergroupMembers or searchChatMembers. Can be called only if supergroupFullInfo.canHideMembers == true. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleSupergroupHasHiddenMembers extends Function { - /** - * Identifier of the supergroup. - */ - public long supergroupId; - /** - * New value of hasHiddenMembers. - */ - public boolean hasHiddenMembers; - - /** - * Default constructor for a function, which toggles whether non-administrators can receive only administrators and bots using getSupergroupMembers or searchChatMembers. Can be called only if supergroupFullInfo.canHideMembers == true. - * - *

Returns {@link Ok Ok}

- */ - public ToggleSupergroupHasHiddenMembers() { - } - - /** - * Creates a function, which toggles whether non-administrators can receive only administrators and bots using getSupergroupMembers or searchChatMembers. Can be called only if supergroupFullInfo.canHideMembers == true. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId Identifier of the supergroup. - * @param hasHiddenMembers New value of hasHiddenMembers. - */ - public ToggleSupergroupHasHiddenMembers(long supergroupId, boolean hasHiddenMembers) { - this.supergroupId = supergroupId; - this.hasHiddenMembers = hasHiddenMembers; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1537892918; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether the message history of a supergroup is available to new members; requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleSupergroupIsAllHistoryAvailable extends Function { - /** - * The identifier of the supergroup. - */ - public long supergroupId; - /** - * The new value of isAllHistoryAvailable. - */ - public boolean isAllHistoryAvailable; - - /** - * Default constructor for a function, which toggles whether the message history of a supergroup is available to new members; requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- */ - public ToggleSupergroupIsAllHistoryAvailable() { - } - - /** - * Creates a function, which toggles whether the message history of a supergroup is available to new members; requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId The identifier of the supergroup. - * @param isAllHistoryAvailable The new value of isAllHistoryAvailable. - */ - public ToggleSupergroupIsAllHistoryAvailable(long supergroupId, boolean isAllHistoryAvailable) { - this.supergroupId = supergroupId; - this.isAllHistoryAvailable = isAllHistoryAvailable; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1155110478; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Upgrades supergroup to a broadcast group; requires owner privileges in the supergroup. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleSupergroupIsBroadcastGroup extends Function { - /** - * Identifier of the supergroup. - */ - public long supergroupId; - - /** - * Default constructor for a function, which upgrades supergroup to a broadcast group; requires owner privileges in the supergroup. - * - *

Returns {@link Ok Ok}

- */ - public ToggleSupergroupIsBroadcastGroup() { - } - - /** - * Creates a function, which upgrades supergroup to a broadcast group; requires owner privileges in the supergroup. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId Identifier of the supergroup. - */ - public ToggleSupergroupIsBroadcastGroup(long supergroupId) { - this.supergroupId = supergroupId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 884089365; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether the supergroup is a forum; requires owner privileges in the supergroup. Discussion supergroups can't be converted to forums. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleSupergroupIsForum extends Function { - /** - * Identifier of the supergroup. - */ - public long supergroupId; - /** - * New value of isForum. - */ - public boolean isForum; - /** - * New value of hasForumTabs; ignored if isForum is false. - */ - public boolean hasForumTabs; - - /** - * Default constructor for a function, which toggles whether the supergroup is a forum; requires owner privileges in the supergroup. Discussion supergroups can't be converted to forums. - * - *

Returns {@link Ok Ok}

- */ - public ToggleSupergroupIsForum() { - } - - /** - * Creates a function, which toggles whether the supergroup is a forum; requires owner privileges in the supergroup. Discussion supergroups can't be converted to forums. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId Identifier of the supergroup. - * @param isForum New value of isForum. - * @param hasForumTabs New value of hasForumTabs; ignored if isForum is false. - */ - public ToggleSupergroupIsForum(long supergroupId, boolean isForum, boolean hasForumTabs) { - this.supergroupId = supergroupId; - this.isForum = isForum; - this.hasForumTabs = hasForumTabs; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 371064337; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether all users directly joining the supergroup need to be approved by supergroup administrators; requires canRestrictMembers administrator right. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleSupergroupJoinByRequest extends Function { - /** - * Identifier of the supergroup that isn't a broadcast group and isn't a channel direct message group. - */ - public long supergroupId; - /** - * New value of joinByRequest. - */ - public boolean joinByRequest; - - /** - * Default constructor for a function, which toggles whether all users directly joining the supergroup need to be approved by supergroup administrators; requires canRestrictMembers administrator right. - * - *

Returns {@link Ok Ok}

- */ - public ToggleSupergroupJoinByRequest() { - } - - /** - * Creates a function, which toggles whether all users directly joining the supergroup need to be approved by supergroup administrators; requires canRestrictMembers administrator right. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId Identifier of the supergroup that isn't a broadcast group and isn't a channel direct message group. - * @param joinByRequest New value of joinByRequest. - */ - public ToggleSupergroupJoinByRequest(long supergroupId, boolean joinByRequest) { - this.supergroupId = supergroupId; - this.joinByRequest = joinByRequest; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2111807454; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether joining is mandatory to send messages to a discussion supergroup; requires canRestrictMembers administrator right. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleSupergroupJoinToSendMessages extends Function { - /** - * Identifier of the supergroup that isn't a broadcast group. - */ - public long supergroupId; - /** - * New value of joinToSendMessages. - */ - public boolean joinToSendMessages; - - /** - * Default constructor for a function, which toggles whether joining is mandatory to send messages to a discussion supergroup; requires canRestrictMembers administrator right. - * - *

Returns {@link Ok Ok}

- */ - public ToggleSupergroupJoinToSendMessages() { - } - - /** - * Creates a function, which toggles whether joining is mandatory to send messages to a discussion supergroup; requires canRestrictMembers administrator right. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId Identifier of the supergroup that isn't a broadcast group. - * @param joinToSendMessages New value of joinToSendMessages. - */ - public ToggleSupergroupJoinToSendMessages(long supergroupId, boolean joinToSendMessages) { - this.supergroupId = supergroupId; - this.joinToSendMessages = joinToSendMessages; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -182022642; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether sender signature or link to the account is added to sent messages in a channel; requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleSupergroupSignMessages extends Function { - /** - * Identifier of the channel. - */ - public long supergroupId; - /** - * New value of signMessages. - */ - public boolean signMessages; - /** - * New value of showMessageSender. - */ - public boolean showMessageSender; - - /** - * Default constructor for a function, which toggles whether sender signature or link to the account is added to sent messages in a channel; requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- */ - public ToggleSupergroupSignMessages() { - } - - /** - * Creates a function, which toggles whether sender signature or link to the account is added to sent messages in a channel; requires canChangeInfo member right. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId Identifier of the channel. - * @param signMessages New value of signMessages. - * @param showMessageSender New value of showMessageSender. - */ - public ToggleSupergroupSignMessages(long supergroupId, boolean signMessages, boolean showMessageSender) { - this.supergroupId = supergroupId; - this.signMessages = signMessages; - this.showMessageSender = showMessageSender; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 572268491; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes active state for a username of a supergroup or channel, requires owner privileges in the supergroup or channel. The editable username can't be disabled. May return an error with a message "USERNAMES_ACTIVE_TOO_MUCH" if the maximum number of active usernames has been reached. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleSupergroupUsernameIsActive extends Function { - /** - * Identifier of the supergroup or channel. - */ - public long supergroupId; - /** - * The username to change. - */ - public String username; - /** - * Pass true to activate the username; pass false to disable it. - */ - public boolean isActive; - - /** - * Default constructor for a function, which changes active state for a username of a supergroup or channel, requires owner privileges in the supergroup or channel. The editable username can't be disabled. May return an error with a message "USERNAMES_ACTIVE_TOO_MUCH" if the maximum number of active usernames has been reached. - * - *

Returns {@link Ok Ok}

- */ - public ToggleSupergroupUsernameIsActive() { - } - - /** - * Creates a function, which changes active state for a username of a supergroup or channel, requires owner privileges in the supergroup or channel. The editable username can't be disabled. May return an error with a message "USERNAMES_ACTIVE_TOO_MUCH" if the maximum number of active usernames has been reached. - * - *

Returns {@link Ok Ok}

- * - * @param supergroupId Identifier of the supergroup or channel. - * @param username The username to change. - * @param isActive Pass true to activate the username; pass false to disable it. - */ - public ToggleSupergroupUsernameIsActive(long supergroupId, String username, boolean isActive) { - this.supergroupId = supergroupId; - this.username = username; - this.isActive = isActive; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1500811777; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes active state for a username of the current user. The editable username can't be disabled. May return an error with a message "USERNAMES_ACTIVE_TOO_MUCH" if the maximum number of active usernames has been reached. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleUsernameIsActive extends Function { - /** - * The username to change. - */ - public String username; - /** - * Pass true to activate the username; pass false to disable it. - */ - public boolean isActive; - - /** - * Default constructor for a function, which changes active state for a username of the current user. The editable username can't be disabled. May return an error with a message "USERNAMES_ACTIVE_TOO_MUCH" if the maximum number of active usernames has been reached. - * - *

Returns {@link Ok Ok}

- */ - public ToggleUsernameIsActive() { - } - - /** - * Creates a function, which changes active state for a username of the current user. The editable username can't be disabled. May return an error with a message "USERNAMES_ACTIVE_TOO_MUCH" if the maximum number of active usernames has been reached. - * - *

Returns {@link Ok Ok}

- * - * @param username The username to change. - * @param isActive Pass true to activate the username; pass false to disable it. - */ - public ToggleUsernameIsActive(String username, boolean isActive) { - this.username = username; - this.isActive = isActive; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1244098019; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether the current user will receive a notification when the video chat starts; for scheduled video chats only. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleVideoChatEnabledStartNotification extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * New value of the enabledStartNotification setting. - */ - public boolean enabledStartNotification; - - /** - * Default constructor for a function, which toggles whether the current user will receive a notification when the video chat starts; for scheduled video chats only. - * - *

Returns {@link Ok Ok}

- */ - public ToggleVideoChatEnabledStartNotification() { - } - - /** - * Creates a function, which toggles whether the current user will receive a notification when the video chat starts; for scheduled video chats only. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param enabledStartNotification New value of the enabledStartNotification setting. - */ - public ToggleVideoChatEnabledStartNotification(int groupCallId, boolean enabledStartNotification) { - this.groupCallId = groupCallId; - this.enabledStartNotification = enabledStartNotification; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1851489086; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Toggles whether new participants of a video chat can be unmuted only by administrators of the video chat. Requires groupCall.canToggleMuteNewParticipants right. - * - *

Returns {@link Ok Ok}

- */ - public static class ToggleVideoChatMuteNewParticipants extends Function { - /** - * Group call identifier. - */ - public int groupCallId; - /** - * New value of the muteNewParticipants setting. - */ - public boolean muteNewParticipants; - - /** - * Default constructor for a function, which toggles whether new participants of a video chat can be unmuted only by administrators of the video chat. Requires groupCall.canToggleMuteNewParticipants right. - * - *

Returns {@link Ok Ok}

- */ - public ToggleVideoChatMuteNewParticipants() { - } - - /** - * Creates a function, which toggles whether new participants of a video chat can be unmuted only by administrators of the video chat. Requires groupCall.canToggleMuteNewParticipants right. - * - *

Returns {@link Ok Ok}

- * - * @param groupCallId Group call identifier. - * @param muteNewParticipants New value of the muteNewParticipants setting. - */ - public ToggleVideoChatMuteNewParticipants(int groupCallId, boolean muteNewParticipants) { - this.groupCallId = groupCallId; - this.muteNewParticipants = muteNewParticipants; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 987023756; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Transfers Telegram Stars from the business account to the business bot; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public static class TransferBusinessAccountStars extends Function { - /** - * Unique identifier of business connection. - */ - public String businessConnectionId; - /** - * Number of Telegram Stars to transfer. - */ - public long starCount; - - /** - * Default constructor for a function, which transfers Telegram Stars from the business account to the business bot; for bots only. - * - *

Returns {@link Ok Ok}

- */ - public TransferBusinessAccountStars() { - } - - /** - * Creates a function, which transfers Telegram Stars from the business account to the business bot; for bots only. - * - *

Returns {@link Ok Ok}

- * - * @param businessConnectionId Unique identifier of business connection. - * @param starCount Number of Telegram Stars to transfer. - */ - public TransferBusinessAccountStars(String businessConnectionId, long starCount) { - this.businessConnectionId = businessConnectionId; - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 732562464; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Changes the owner of a chat; for basic groups, supergroups and channel chats only; requires owner privileges in the chat. Use the method canTransferOwnership to check whether the ownership can be transferred from the current session. - * - *

Returns {@link Ok Ok}

- */ - public static class TransferChatOwnership extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * Identifier of the user to which transfer the ownership. The ownership can't be transferred to a bot or to a deleted user. - */ - public long userId; - /** - * The 2-step verification password of the current user. - */ - public String password; - - /** - * Default constructor for a function, which changes the owner of a chat; for basic groups, supergroups and channel chats only; requires owner privileges in the chat. Use the method canTransferOwnership to check whether the ownership can be transferred from the current session. - * - *

Returns {@link Ok Ok}

- */ - public TransferChatOwnership() { - } - - /** - * Creates a function, which changes the owner of a chat; for basic groups, supergroups and channel chats only; requires owner privileges in the chat. Use the method canTransferOwnership to check whether the ownership can be transferred from the current session. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param userId Identifier of the user to which transfer the ownership. The ownership can't be transferred to a bot or to a deleted user. - * @param password The 2-step verification password of the current user. - */ - public TransferChatOwnership(long chatId, long userId, String password) { - this.chatId = chatId; - this.userId = userId; - this.password = password; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2006977043; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Sends an upgraded gift to another user or channel chat. - * - *

Returns {@link Ok Ok}

- */ - public static class TransferGift extends Function { - /** - * Unique identifier of business connection on behalf of which to send the request; for bots only. - */ - public String businessConnectionId; - /** - * Identifier of the gift. - */ - public String receivedGiftId; - /** - * Identifier of the user or the channel chat that will receive the gift. - */ - public MessageSender newOwnerId; - /** - * The Telegram Star amount required to pay for the transfer. - */ - public long starCount; - - /** - * Default constructor for a function, which sends an upgraded gift to another user or channel chat. - * - *

Returns {@link Ok Ok}

- */ - public TransferGift() { - } - - /** - * Creates a function, which sends an upgraded gift to another user or channel chat. - * - *

Returns {@link Ok Ok}

- * - * @param businessConnectionId Unique identifier of business connection on behalf of which to send the request; for bots only. - * @param receivedGiftId Identifier of the gift. - * @param newOwnerId Identifier of the user or the channel chat that will receive the gift. - * @param starCount The Telegram Star amount required to pay for the transfer. - */ - public TransferGift(String businessConnectionId, String receivedGiftId, MessageSender newOwnerId, long starCount) { - this.businessConnectionId = businessConnectionId; - this.receivedGiftId = receivedGiftId; - this.newOwnerId = newOwnerId; - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1167293126; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Extracts text or caption of the given message and translates it to the given language. If the current user is a Telegram Premium user, then text formatting is preserved. - * - *

Returns {@link FormattedText FormattedText}

- */ - public static class TranslateMessageText extends Function { - /** - * Identifier of the chat to which the message belongs. - */ - public long chatId; - /** - * Identifier of the message. - */ - public long messageId; - /** - * Language code of the language to which the message is translated. See translateText.toLanguageCode for the list of supported values. - */ - public String toLanguageCode; - - /** - * Default constructor for a function, which extracts text or caption of the given message and translates it to the given language. If the current user is a Telegram Premium user, then text formatting is preserved. - * - *

Returns {@link FormattedText FormattedText}

- */ - public TranslateMessageText() { - } - - /** - * Creates a function, which extracts text or caption of the given message and translates it to the given language. If the current user is a Telegram Premium user, then text formatting is preserved. - * - *

Returns {@link FormattedText FormattedText}

- * - * @param chatId Identifier of the chat to which the message belongs. - * @param messageId Identifier of the message. - * @param toLanguageCode Language code of the language to which the message is translated. See translateText.toLanguageCode for the list of supported values. - */ - public TranslateMessageText(long chatId, long messageId, String toLanguageCode) { - this.chatId = chatId; - this.messageId = messageId; - this.toLanguageCode = toLanguageCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1405427410; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Translates a text to the given language. If the current user is a Telegram Premium user, then text formatting is preserved. - * - *

Returns {@link FormattedText FormattedText}

- */ - public static class TranslateText extends Function { - /** - * Text to translate. - */ - public FormattedText text; - /** - * Language code of the language to which the message is translated. Must be one of "af", "sq", "am", "ar", "hy", "az", "eu", "be", "bn", "bs", "bg", "ca", "ceb", "zh-CN", "zh", "zh-Hans", "zh-TW", "zh-Hant", "co", "hr", "cs", "da", "nl", "en", "eo", "et", "fi", "fr", "fy", "gl", "ka", "de", "el", "gu", "ht", "ha", "haw", "he", "iw", "hi", "hmn", "hu", "is", "ig", "id", "in", "ga", "it", "ja", "jv", "kn", "kk", "km", "rw", "ko", "ku", "ky", "lo", "la", "lv", "lt", "lb", "mk", "mg", "ms", "ml", "mt", "mi", "mr", "mn", "my", "ne", "no", "ny", "or", "ps", "fa", "pl", "pt", "pa", "ro", "ru", "sm", "gd", "sr", "st", "sn", "sd", "si", "sk", "sl", "so", "es", "su", "sw", "sv", "tl", "tg", "ta", "tt", "te", "th", "tr", "tk", "uk", "ur", "ug", "uz", "vi", "cy", "xh", "yi", "ji", "yo", "zu". - */ - public String toLanguageCode; - - /** - * Default constructor for a function, which translates a text to the given language. If the current user is a Telegram Premium user, then text formatting is preserved. - * - *

Returns {@link FormattedText FormattedText}

- */ - public TranslateText() { - } - - /** - * Creates a function, which translates a text to the given language. If the current user is a Telegram Premium user, then text formatting is preserved. - * - *

Returns {@link FormattedText FormattedText}

- * - * @param text Text to translate. - * @param toLanguageCode Language code of the language to which the message is translated. Must be one of "af", "sq", "am", "ar", "hy", "az", "eu", "be", "bn", "bs", "bg", "ca", "ceb", "zh-CN", "zh", "zh-Hans", "zh-TW", "zh-Hant", "co", "hr", "cs", "da", "nl", "en", "eo", "et", "fi", "fr", "fy", "gl", "ka", "de", "el", "gu", "ht", "ha", "haw", "he", "iw", "hi", "hmn", "hu", "is", "ig", "id", "in", "ga", "it", "ja", "jv", "kn", "kk", "km", "rw", "ko", "ku", "ky", "lo", "la", "lv", "lt", "lb", "mk", "mg", "ms", "ml", "mt", "mi", "mr", "mn", "my", "ne", "no", "ny", "or", "ps", "fa", "pl", "pt", "pa", "ro", "ru", "sm", "gd", "sr", "st", "sn", "sd", "si", "sk", "sl", "so", "es", "su", "sw", "sv", "tl", "tg", "ta", "tt", "te", "th", "tr", "tk", "uk", "ur", "ug", "uz", "vi", "cy", "xh", "yi", "ji", "yo", "zu". - */ - public TranslateText(FormattedText text, String toLanguageCode) { - this.text = text; - this.toLanguageCode = toLanguageCode; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 623011058; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes all pinned messages from a chat; requires canPinMessages member right if the chat is a basic group or supergroup, or canEditMessages administrator right if the chat is a channel. - * - *

Returns {@link Ok Ok}

- */ - public static class UnpinAllChatMessages extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - - /** - * Default constructor for a function, which removes all pinned messages from a chat; requires canPinMessages member right if the chat is a basic group or supergroup, or canEditMessages administrator right if the chat is a channel. - * - *

Returns {@link Ok Ok}

- */ - public UnpinAllChatMessages() { - } - - /** - * Creates a function, which removes all pinned messages from a chat; requires canPinMessages member right if the chat is a basic group or supergroup, or canEditMessages administrator right if the chat is a channel. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat. - */ - public UnpinAllChatMessages(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1437805385; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes all pinned messages from the topic in a channel direct messages chat administered by the current user. - * - *

Returns {@link Ok Ok}

- */ - public static class UnpinAllDirectMessagesChatTopicMessages extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * Topic identifier. - */ - public long topicId; - - /** - * Default constructor for a function, which removes all pinned messages from the topic in a channel direct messages chat administered by the current user. - * - *

Returns {@link Ok Ok}

- */ - public UnpinAllDirectMessagesChatTopicMessages() { - } - - /** - * Creates a function, which removes all pinned messages from the topic in a channel direct messages chat administered by the current user. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat. - * @param topicId Topic identifier. - */ - public UnpinAllDirectMessagesChatTopicMessages(long chatId, long topicId) { - this.chatId = chatId; - this.topicId = topicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 89671100; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes all pinned messages from a topic in a forum supergroup chat or a chat with a bot with topics; requires canPinMessages member right in the supergroup. - * - *

Returns {@link Ok Ok}

- */ - public static class UnpinAllForumTopicMessages extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * Forum topic identifier in which messages will be unpinned. - */ - public int forumTopicId; - - /** - * Default constructor for a function, which removes all pinned messages from a topic in a forum supergroup chat or a chat with a bot with topics; requires canPinMessages member right in the supergroup. - * - *

Returns {@link Ok Ok}

- */ - public UnpinAllForumTopicMessages() { - } - - /** - * Creates a function, which removes all pinned messages from a topic in a forum supergroup chat or a chat with a bot with topics; requires canPinMessages member right in the supergroup. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat. - * @param forumTopicId Forum topic identifier in which messages will be unpinned. - */ - public UnpinAllForumTopicMessages(long chatId, int forumTopicId) { - this.chatId = chatId; - this.forumTopicId = forumTopicId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1113340771; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Removes a pinned message from a chat; requires canPinMessages member right if the chat is a basic group or supergroup, or canEditMessages administrator right if the chat is a channel. - * - *

Returns {@link Ok Ok}

- */ - public static class UnpinChatMessage extends Function { - /** - * Identifier of the chat. - */ - public long chatId; - /** - * Identifier of the removed pinned message. - */ - public long messageId; - - /** - * Default constructor for a function, which removes a pinned message from a chat; requires canPinMessages member right if the chat is a basic group or supergroup, or canEditMessages administrator right if the chat is a channel. - * - *

Returns {@link Ok Ok}

- */ - public UnpinChatMessage() { - } - - /** - * Creates a function, which removes a pinned message from a chat; requires canPinMessages member right if the chat is a basic group or supergroup, or canEditMessages administrator right if the chat is a channel. - * - *

Returns {@link Ok Ok}

- * - * @param chatId Identifier of the chat. - * @param messageId Identifier of the removed pinned message. - */ - public UnpinChatMessage(long chatId, long messageId) { - this.chatId = chatId; - this.messageId = messageId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 2065448670; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Creates a new supergroup from an existing basic group and sends a corresponding messageChatUpgradeTo and messageChatUpgradeFrom; requires owner privileges. Deactivates the original basic group. - * - *

Returns {@link Chat Chat}

- */ - public static class UpgradeBasicGroupChatToSupergroupChat extends Function { - /** - * Identifier of the chat to upgrade. - */ - public long chatId; - - /** - * Default constructor for a function, which creates a new supergroup from an existing basic group and sends a corresponding messageChatUpgradeTo and messageChatUpgradeFrom; requires owner privileges. Deactivates the original basic group. - * - *

Returns {@link Chat Chat}

- */ - public UpgradeBasicGroupChatToSupergroupChat() { - } - - /** - * Creates a function, which creates a new supergroup from an existing basic group and sends a corresponding messageChatUpgradeTo and messageChatUpgradeFrom; requires owner privileges. Deactivates the original basic group. - * - *

Returns {@link Chat Chat}

- * - * @param chatId Identifier of the chat to upgrade. - */ - public UpgradeBasicGroupChatToSupergroupChat(long chatId) { - this.chatId = chatId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 300488122; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Upgrades a regular gift. - * - *

Returns {@link UpgradeGiftResult UpgradeGiftResult}

- */ - public static class UpgradeGift extends Function { - /** - * Unique identifier of business connection on behalf of which to send the request; for bots only. - */ - public String businessConnectionId; - /** - * Identifier of the gift. - */ - public String receivedGiftId; - /** - * Pass true to keep the original gift text, sender and receiver in the upgraded gift. - */ - public boolean keepOriginalDetails; - /** - * The Telegram Star amount required to pay for the upgrade. It the gift has prepaidUpgradeStarCount > 0, then pass 0, otherwise, pass gift.upgradeStarCount. - */ - public long starCount; - - /** - * Default constructor for a function, which upgrades a regular gift. - * - *

Returns {@link UpgradeGiftResult UpgradeGiftResult}

- */ - public UpgradeGift() { - } - - /** - * Creates a function, which upgrades a regular gift. - * - *

Returns {@link UpgradeGiftResult UpgradeGiftResult}

- * - * @param businessConnectionId Unique identifier of business connection on behalf of which to send the request; for bots only. - * @param receivedGiftId Identifier of the gift. - * @param keepOriginalDetails Pass true to keep the original gift text, sender and receiver in the upgraded gift. - * @param starCount The Telegram Star amount required to pay for the upgrade. It the gift has prepaidUpgradeStarCount > 0, then pass 0, otherwise, pass gift.upgradeStarCount. - */ - public UpgradeGift(String businessConnectionId, String receivedGiftId, boolean keepOriginalDetails, long starCount) { - this.businessConnectionId = businessConnectionId; - this.receivedGiftId = receivedGiftId; - this.keepOriginalDetails = keepOriginalDetails; - this.starCount = starCount; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1782136103; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Uploads a file with a sticker; returns the uploaded file. - * - *

Returns {@link File File}

- */ - public static class UploadStickerFile extends Function { - /** - * Sticker file owner; ignored for regular users. - */ - public long userId; - /** - * Sticker format. - */ - public StickerFormat stickerFormat; - /** - * File file to upload; must fit in a 512x512 square. For WEBP stickers the file must be in WEBP or PNG format, which will be converted to WEBP server-side. See https://core.telegram.org/animated_stickers#technical-requirements for technical requirements. - */ - public InputFile sticker; - - /** - * Default constructor for a function, which uploads a file with a sticker; returns the uploaded file. - * - *

Returns {@link File File}

- */ - public UploadStickerFile() { - } - - /** - * Creates a function, which uploads a file with a sticker; returns the uploaded file. - * - *

Returns {@link File File}

- * - * @param userId Sticker file owner; ignored for regular users. - * @param stickerFormat Sticker format. - * @param sticker File file to upload; must fit in a 512x512 square. For WEBP stickers the file must be in WEBP or PNG format, which will be converted to WEBP server-side. See https://core.telegram.org/animated_stickers#technical-requirements for technical requirements. - */ - public UploadStickerFile(long userId, StickerFormat stickerFormat, InputFile sticker) { - this.userId = userId; - this.stickerFormat = stickerFormat; - this.sticker = sticker; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 647385283; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Validates the order information provided by a user and returns the available shipping options for a flexible invoice. - * - *

Returns {@link ValidatedOrderInfo ValidatedOrderInfo}

- */ - public static class ValidateOrderInfo extends Function { - /** - * The invoice. - */ - public InputInvoice inputInvoice; - /** - * The order information, provided by the user; pass null if empty. - */ - public OrderInfo orderInfo; - /** - * Pass true to save the order information. - */ - public boolean allowSave; - - /** - * Default constructor for a function, which validates the order information provided by a user and returns the available shipping options for a flexible invoice. - * - *

Returns {@link ValidatedOrderInfo ValidatedOrderInfo}

- */ - public ValidateOrderInfo() { - } - - /** - * Creates a function, which validates the order information provided by a user and returns the available shipping options for a flexible invoice. - * - *

Returns {@link ValidatedOrderInfo ValidatedOrderInfo}

- * - * @param inputInvoice The invoice. - * @param orderInfo The order information, provided by the user; pass null if empty. - * @param allowSave Pass true to save the order information. - */ - public ValidateOrderInfo(InputInvoice inputInvoice, OrderInfo orderInfo, boolean allowSave) { - this.inputInvoice = inputInvoice; - this.orderInfo = orderInfo; - this.allowSave = allowSave; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -1248305201; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that messages are being viewed by the user. Sponsored messages must be marked as viewed only when the entire text of the message is shown on the screen (excluding the button). Many useful activities depend on whether the messages are currently being viewed or not (e.g., marking messages as read, incrementing a view counter, updating a view counter, removing deleted messages in supergroups and channels). - * - *

Returns {@link Ok Ok}

- */ - public static class ViewMessages extends Function { - /** - * Chat identifier. - */ - public long chatId; - /** - * The identifiers of the messages being viewed. - */ - public long[] messageIds; - /** - * Source of the message view; pass null to guess the source based on chat open state. - */ - public MessageSource source; - /** - * Pass true to mark as read the specified messages even if the chat is closed. - */ - public boolean forceRead; - - /** - * Default constructor for a function, which informs TDLib that messages are being viewed by the user. Sponsored messages must be marked as viewed only when the entire text of the message is shown on the screen (excluding the button). Many useful activities depend on whether the messages are currently being viewed or not (e.g., marking messages as read, incrementing a view counter, updating a view counter, removing deleted messages in supergroups and channels). - * - *

Returns {@link Ok Ok}

- */ - public ViewMessages() { - } - - /** - * Creates a function, which informs TDLib that messages are being viewed by the user. Sponsored messages must be marked as viewed only when the entire text of the message is shown on the screen (excluding the button). Many useful activities depend on whether the messages are currently being viewed or not (e.g., marking messages as read, incrementing a view counter, updating a view counter, removing deleted messages in supergroups and channels). - * - *

Returns {@link Ok Ok}

- * - * @param chatId Chat identifier. - * @param messageIds The identifiers of the messages being viewed. - * @param source Source of the message view; pass null to guess the source based on chat open state. - * @param forceRead Pass true to mark as read the specified messages even if the chat is closed. - */ - public ViewMessages(long chatId, long[] messageIds, MessageSource source, boolean forceRead) { - this.chatId = chatId; - this.messageIds = messageIds; - this.source = source; - this.forceRead = forceRead; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 960236656; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that the user viewed detailed information about a Premium feature on the Premium features screen. - * - *

Returns {@link Ok Ok}

- */ - public static class ViewPremiumFeature extends Function { - /** - * The viewed premium feature. - */ - public PremiumFeature feature; - - /** - * Default constructor for a function, which informs TDLib that the user viewed detailed information about a Premium feature on the Premium features screen. - * - *

Returns {@link Ok Ok}

- */ - public ViewPremiumFeature() { - } - - /** - * Creates a function, which informs TDLib that the user viewed detailed information about a Premium feature on the Premium features screen. - * - *

Returns {@link Ok Ok}

- * - * @param feature The viewed premium feature. - */ - public ViewPremiumFeature(PremiumFeature feature) { - this.feature = feature; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 192950706; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that the user fully viewed a sponsored chat. - * - *

Returns {@link Ok Ok}

- */ - public static class ViewSponsoredChat extends Function { - /** - * Unique identifier of the sponsored chat. - */ - public long sponsoredChatUniqueId; - - /** - * Default constructor for a function, which informs TDLib that the user fully viewed a sponsored chat. - * - *

Returns {@link Ok Ok}

- */ - public ViewSponsoredChat() { - } - - /** - * Creates a function, which informs TDLib that the user fully viewed a sponsored chat. - * - *

Returns {@link Ok Ok}

- * - * @param sponsoredChatUniqueId Unique identifier of the sponsored chat. - */ - public ViewSponsoredChat(long sponsoredChatUniqueId) { - this.sponsoredChatUniqueId = sponsoredChatUniqueId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 1722644778; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs the server that some trending sticker sets have been viewed by the user. - * - *

Returns {@link Ok Ok}

- */ - public static class ViewTrendingStickerSets extends Function { - /** - * Identifiers of viewed trending sticker sets. - */ - public long[] stickerSetIds; - - /** - * Default constructor for a function, which informs the server that some trending sticker sets have been viewed by the user. - * - *

Returns {@link Ok Ok}

- */ - public ViewTrendingStickerSets() { - } - - /** - * Creates a function, which informs the server that some trending sticker sets have been viewed by the user. - * - *

Returns {@link Ok Ok}

- * - * @param stickerSetIds Identifiers of viewed trending sticker sets. - */ - public ViewTrendingStickerSets(long[] stickerSetIds) { - this.stickerSetIds = stickerSetIds; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -952416520; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Informs TDLib that the user viewed a video message advertisement. - * - *

Returns {@link Ok Ok}

- */ - public static class ViewVideoMessageAdvertisement extends Function { - /** - * Unique identifier of the advertisement. - */ - public long advertisementUniqueId; - - /** - * Default constructor for a function, which informs TDLib that the user viewed a video message advertisement. - * - *

Returns {@link Ok Ok}

- */ - public ViewVideoMessageAdvertisement() { - } - - /** - * Creates a function, which informs TDLib that the user viewed a video message advertisement. - * - *

Returns {@link Ok Ok}

- * - * @param advertisementUniqueId Unique identifier of the advertisement. - */ - public ViewVideoMessageAdvertisement(long advertisementUniqueId) { - this.advertisementUniqueId = advertisementUniqueId; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = -808563006; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - - /** - * Writes a part of a generated file. This method is intended to be used only if the application has no direct access to TDLib's file system, because it is usually slower than a direct write to the destination file. - * - *

Returns {@link Ok Ok}

- */ - public static class WriteGeneratedFilePart extends Function { - /** - * The identifier of the generation process. - */ - public long generationId; - /** - * The offset from which to write the data to the file. - */ - public long offset; - /** - * The data to write. - */ - public byte[] data; - - /** - * Default constructor for a function, which writes a part of a generated file. This method is intended to be used only if the application has no direct access to TDLib's file system, because it is usually slower than a direct write to the destination file. - * - *

Returns {@link Ok Ok}

- */ - public WriteGeneratedFilePart() { - } - - /** - * Creates a function, which writes a part of a generated file. This method is intended to be used only if the application has no direct access to TDLib's file system, because it is usually slower than a direct write to the destination file. - * - *

Returns {@link Ok Ok}

- * - * @param generationId The identifier of the generation process. - * @param offset The offset from which to write the data to the file. - * @param data The data to write. - */ - public WriteGeneratedFilePart(long generationId, long offset, byte[] data) { - this.generationId = generationId; - this.offset = offset; - this.data = data; - } - - /** - * Identifier uniquely determining type of the object. - */ - public static final int CONSTRUCTOR = 214474389; - - /** - * @return this.CONSTRUCTOR - */ - @Override - public int getConstructor() { - return CONSTRUCTOR; - } - } - -} diff --git a/data/src/main/java/org/monogram/data/chats/ChatCache.kt b/data/src/main/java/org/monogram/data/chats/ChatCache.kt deleted file mode 100644 index dcfc4031..00000000 --- a/data/src/main/java/org/monogram/data/chats/ChatCache.kt +++ /dev/null @@ -1,450 +0,0 @@ -package org.monogram.data.chats - -import org.drinkless.tdlib.TdApi -import org.monogram.data.datasource.cache.ChatsCacheDataSource -import org.monogram.data.datasource.cache.UserCacheDataSource -import java.util.concurrent.ConcurrentHashMap - -class ChatCache : ChatsCacheDataSource, UserCacheDataSource { - // Chats and their positions in lists - val allChats = ConcurrentHashMap() - val activeListPositions = ConcurrentHashMap() - val authoritativeActiveListChatIds = ConcurrentHashMap.newKeySet() - val protectedPinnedChatIds = ConcurrentHashMap.newKeySet() - val onlineMemberCount = ConcurrentHashMap() - - // Messages: ChatId -> (MessageId -> Message) - private val messages = ConcurrentHashMap>() - - // Users and their full info - val usersCache = ConcurrentHashMap() - val userFullInfoCache = ConcurrentHashMap() - - // Groups and Supergroups - val basicGroups = ConcurrentHashMap() - val basicGroupFullInfoCache = ConcurrentHashMap() - val supergroups = ConcurrentHashMap() - val supergroupFullInfoCache = ConcurrentHashMap() - val secretChats = ConcurrentHashMap() - - // Files - val fileCache = ConcurrentHashMap() - - // Permissions and Member Status - val chatPermissionsCache = ConcurrentHashMap() - val myChatMemberCache = ConcurrentHashMap() - - // Pending requests tracking - val pendingChats = ConcurrentHashMap.newKeySet() - val pendingUsers = ConcurrentHashMap.newKeySet() - val pendingUserFullInfo = ConcurrentHashMap.newKeySet() - val pendingBasicGroups = ConcurrentHashMap.newKeySet() - val pendingBasicGroupFullInfo = ConcurrentHashMap.newKeySet() - val pendingSupergroups = ConcurrentHashMap.newKeySet() - val pendingSupergroupFullInfo = ConcurrentHashMap.newKeySet() - val pendingSecretChats = ConcurrentHashMap.newKeySet() - val pendingChatPermissions = ConcurrentHashMap.newKeySet() - val pendingMyChatMember = ConcurrentHashMap.newKeySet() - - override fun getChat(chatId: Long): TdApi.Chat? = allChats[chatId] - override fun putChat(chat: TdApi.Chat) { - val existing = allChats[chat.id] - if (existing != null) { - synchronized(existing) { - existing.title = chat.title - if (chat.photo != null || existing.photo == null) { - existing.photo = chat.photo - } - existing.permissions = chat.permissions - existing.lastMessage = chat.lastMessage - - val newPositions = chat.positions.toMutableList() - existing.positions.forEach { oldPos -> - if (newPositions.none { isSameChatList(it.list, oldPos.list) }) { - newPositions.add(oldPos) - } - } - existing.positions = newPositions.toTypedArray() - - existing.unreadCount = chat.unreadCount - existing.unreadMentionCount = chat.unreadMentionCount - existing.unreadReactionCount = chat.unreadReactionCount - existing.notificationSettings = chat.notificationSettings - existing.draftMessage = chat.draftMessage - existing.clientData = chat.clientData - existing.isMarkedAsUnread = chat.isMarkedAsUnread - existing.isTranslatable = chat.isTranslatable - existing.hasProtectedContent = chat.hasProtectedContent - existing.viewAsTopics = chat.viewAsTopics - existing.accentColorId = chat.accentColorId - existing.backgroundCustomEmojiId = chat.backgroundCustomEmojiId - existing.profileAccentColorId = chat.profileAccentColorId - existing.profileBackgroundCustomEmojiId = chat.profileBackgroundCustomEmojiId - existing.emojiStatus = chat.emojiStatus - existing.messageAutoDeleteTime = chat.messageAutoDeleteTime - existing.videoChat = chat.videoChat - existing.pendingJoinRequests = chat.pendingJoinRequests - existing.replyMarkupMessageId = chat.replyMarkupMessageId - existing.messageSenderId = chat.messageSenderId - existing.blockList = chat.blockList - existing.canBeDeletedOnlyForSelf = chat.canBeDeletedOnlyForSelf - existing.canBeDeletedForAllUsers = chat.canBeDeletedForAllUsers - existing.canBeReported = chat.canBeReported - existing.defaultDisableNotification = chat.defaultDisableNotification - existing.lastReadInboxMessageId = chat.lastReadInboxMessageId - existing.lastReadOutboxMessageId = chat.lastReadOutboxMessageId - } - } else { - allChats[chat.id] = chat - } - } - - private fun isSameChatList(a: TdApi.ChatList?, b: TdApi.ChatList?): Boolean { - if (a === b) return true - if (a == null || b == null) return false - if (a.constructor != b.constructor) return false - if (a is TdApi.ChatListFolder && b is TdApi.ChatListFolder) { - return a.chatFolderId == b.chatFolderId - } - return true - } - - override fun getUser(userId: Long): TdApi.User? = usersCache[userId] - override fun putUser(user: TdApi.User) { - val existing = usersCache[user.id] - if (existing != null) { - synchronized(existing) { - existing.firstName = user.firstName - existing.lastName = user.lastName - existing.usernames = user.usernames - existing.phoneNumber = user.phoneNumber - existing.status = user.status - if (user.profilePhoto != null || existing.profilePhoto == null) { - existing.profilePhoto = user.profilePhoto - } - existing.emojiStatus = user.emojiStatus - existing.isPremium = user.isPremium - existing.verificationStatus = user.verificationStatus - existing.isSupport = user.isSupport - existing.haveAccess = user.haveAccess - existing.type = user.type - existing.languageCode = user.languageCode - existing.addedToAttachmentMenu = user.addedToAttachmentMenu - existing.isContact = user.isContact - existing.isMutualContact = user.isMutualContact - existing.isCloseFriend = user.isCloseFriend - } - } else { - usersCache[user.id] = user - } - } - - override fun getUserFullInfo(userId: Long): TdApi.UserFullInfo? = userFullInfoCache[userId] - override fun putUserFullInfo(userId: Long, userFullInfo: TdApi.UserFullInfo) { - userFullInfoCache[userId] = userFullInfo - } - - override fun getSupergroup(supergroupId: Long): TdApi.Supergroup? = supergroups[supergroupId] - override fun putSupergroup(supergroup: TdApi.Supergroup) { - supergroups[supergroup.id] = supergroup - } - - override fun getBasicGroup(basicGroupId: Long): TdApi.BasicGroup? = basicGroups[basicGroupId] - override fun putBasicGroup(basicGroup: TdApi.BasicGroup) { - basicGroups[basicGroup.id] = basicGroup - } - - override fun getSupergroupFullInfo(supergroupId: Long): TdApi.SupergroupFullInfo? = - supergroupFullInfoCache[supergroupId] - - override fun putSupergroupFullInfo(supergroupId: Long, supergroupFullInfo: TdApi.SupergroupFullInfo) { - supergroupFullInfoCache[supergroupId] = supergroupFullInfo - } - - override fun getBasicGroupFullInfo(basicGroupId: Long): TdApi.BasicGroupFullInfo? = - basicGroupFullInfoCache[basicGroupId] - - override fun putBasicGroupFullInfo(basicGroupId: Long, basicGroupFullInfo: TdApi.BasicGroupFullInfo) { - basicGroupFullInfoCache[basicGroupId] = basicGroupFullInfo - } - - override fun getChatPermissions(chatId: Long): TdApi.ChatPermissions? = chatPermissionsCache[chatId] - override fun putChatPermissions(chatId: Long, permissions: TdApi.ChatPermissions) { - chatPermissionsCache[chatId] = permissions - } - - override fun getMyChatMember(chatId: Long): TdApi.ChatMember? = myChatMemberCache[chatId] - override fun putMyChatMember(chatId: Long, chatMember: TdApi.ChatMember) { - myChatMemberCache[chatId] = chatMember - } - - override fun getOnlineMemberCount(chatId: Long): Int? = onlineMemberCount[chatId] - override fun putOnlineMemberCount(chatId: Long, count: Int) { - onlineMemberCount[chatId] = count - } - - override fun getSecretChat(secretChatId: Long): TdApi.SecretChat? = secretChats[secretChatId.toInt()] - override fun putSecretChat(secretChat: TdApi.SecretChat) { - secretChats[secretChat.id] = secretChat - } - - override fun getMessage(chatId: Long, messageId: Long): TdApi.Message? = messages[chatId]?.get(messageId) - override fun putMessage(message: TdApi.Message) { - val chatMessages = messages.getOrPut(message.chatId) { ConcurrentHashMap() } - val existing = chatMessages[message.id] - if (existing != null) { - synchronized(existing) { - existing.senderId = message.senderId - existing.date = message.date - existing.editDate = message.editDate - if (message.forwardInfo != null || existing.forwardInfo == null) { - existing.forwardInfo = message.forwardInfo - } - if (message.interactionInfo != null || existing.interactionInfo == null) { - existing.interactionInfo = message.interactionInfo - } - if (message.replyTo != null || existing.replyTo == null) { - existing.replyTo = message.replyTo - } - existing.selfDestructIn = message.selfDestructIn - existing.content = message.content - existing.replyMarkup = message.replyMarkup - existing.isOutgoing = message.isOutgoing - existing.hasTimestampedMedia = message.hasTimestampedMedia - existing.isChannelPost = message.isChannelPost - existing.containsUnreadMention = message.containsUnreadMention - existing.sendingState = message.sendingState - existing.schedulingState = message.schedulingState - } - } else { - chatMessages[message.id] = message - } - } - - override fun removeMessage(chatId: Long, messageId: Long) { - messages[chatId]?.remove(messageId) - } - - fun updateChat(chatId: Long, action: (TdApi.Chat) -> Unit) { - allChats[chatId]?.let { synchronized(it) { action(it) } } - } - - fun updateUser(userId: Long, action: (TdApi.User) -> Unit) { - usersCache[userId]?.let { synchronized(it) { action(it) } } - } - - fun removeMessages(chatId: Long, messageIds: List) { - val chatMessages = messages[chatId] ?: return - messageIds.forEach { chatMessages.remove(it) } - } - - fun clearMessages(chatId: Long) { - messages.remove(chatId) - } - - fun updateMessageId(chatId: Long, oldId: Long, newId: Long) { - val chatMessages = messages[chatId] ?: return - val message = chatMessages.remove(oldId) ?: return - message.id = newId - chatMessages[newId] = message - } - - override fun clearAll() { - allChats.clear() - activeListPositions.clear() - authoritativeActiveListChatIds.clear() - protectedPinnedChatIds.clear() - onlineMemberCount.clear() - messages.clear() - usersCache.clear() - userFullInfoCache.clear() - basicGroups.clear() - basicGroupFullInfoCache.clear() - supergroups.clear() - supergroupFullInfoCache.clear() - secretChats.clear() - fileCache.clear() - chatPermissionsCache.clear() - myChatMemberCache.clear() - - pendingChats.clear() - pendingUsers.clear() - pendingUserFullInfo.clear() - pendingBasicGroups.clear() - pendingBasicGroupFullInfo.clear() - pendingSupergroups.clear() - pendingSupergroupFullInfo.clear() - pendingSecretChats.clear() - pendingChatPermissions.clear() - pendingMyChatMember.clear() - } - - fun putChatFromEntity(entity: org.monogram.data.db.model.ChatEntity) { - val chatList = if (entity.isArchived) TdApi.ChatListArchive() else TdApi.ChatListMain() - val cachedPositions = parsePositionsCache(entity.positionsCache) - val restoredLastMessageDate = when { - entity.lastMessageDate > 0L -> entity.lastMessageDate - else -> entity.lastMessageTime.toLongOrNull() ?: 0L - } - val chat = TdApi.Chat().apply { - id = entity.id - title = entity.title - unreadCount = entity.unreadCount - unreadMentionCount = entity.unreadMentionCount - unreadReactionCount = entity.unreadReactionCount - photo = entity.avatarPath?.let { path -> - TdApi.ChatPhotoInfo().apply { - small = TdApi.File().apply { - id = entity.photoId - local = TdApi.LocalFile().apply { this.path = path } - } - } - } ?: entity.photoId.takeIf { it != 0 }?.let { photoId -> - TdApi.ChatPhotoInfo().apply { - small = TdApi.File().apply { - id = photoId - local = TdApi.LocalFile().apply { this.path = "" } - } - } - } - lastMessage = TdApi.Message().apply { - content = when (entity.lastMessageContentType) { - "photo" -> TdApi.MessagePhoto().apply { - photo = TdApi.Photo().apply { sizes = emptyArray(); minithumbnail = null; hasStickers = false } - caption = TdApi.FormattedText(entity.lastMessageText, emptyArray()) - isSecret = false - showCaptionAboveMedia = false - selfDestructType = null - } - - "video" -> TdApi.MessageVideo().apply { - video = TdApi.Video() - caption = TdApi.FormattedText(entity.lastMessageText, emptyArray()) - showCaptionAboveMedia = false - isSecret = false - selfDestructType = null - } - - "voice" -> TdApi.MessageVoiceNote().apply { - voiceNote = TdApi.VoiceNote() - caption = TdApi.FormattedText(entity.lastMessageText, emptyArray()) - isListened = false - } - - "sticker" -> TdApi.MessageSticker().apply { - sticker = TdApi.Sticker() - isPremium = false - } - - else -> TdApi.MessageText() - .apply { text = TdApi.FormattedText(entity.lastMessageText, emptyArray()) } - } - date = restoredLastMessageDate.toInt() - id = entity.lastMessageId - isOutgoing = entity.isLastMessageOutgoing - } - positions = cachedPositions ?: arrayOf(TdApi.ChatPosition(chatList, entity.order, entity.isPinned, null)) - notificationSettings = TdApi.ChatNotificationSettings().apply { - muteFor = if (entity.isMuted) Int.MAX_VALUE else 0 - } - type = when (entity.type) { - "PRIVATE" -> TdApi.ChatTypePrivate().apply { - userId = if (entity.privateUserId != 0L) entity.privateUserId else (entity.messageSenderId ?: 0L) - } - "BASIC_GROUP" -> TdApi.ChatTypeBasicGroup().apply { - basicGroupId = entity.basicGroupId - } - "SUPERGROUP" -> TdApi.ChatTypeSupergroup(entity.supergroupId, entity.isChannel) - "SECRET" -> TdApi.ChatTypeSecret().apply { - secretChatId = entity.secretChatId - } - else -> TdApi.ChatTypePrivate().apply { userId = entity.privateUserId } - } - isMarkedAsUnread = entity.isMarkedAsUnread - hasProtectedContent = entity.hasProtectedContent - isTranslatable = entity.isTranslatable - viewAsTopics = entity.viewAsTopics - accentColorId = entity.accentColorId - profileAccentColorId = entity.profileAccentColorId - backgroundCustomEmojiId = entity.backgroundCustomEmojiId - messageAutoDeleteTime = entity.messageAutoDeleteTime - canBeDeletedOnlyForSelf = entity.canBeDeletedOnlyForSelf - canBeDeletedForAllUsers = entity.canBeDeletedForAllUsers - canBeReported = entity.canBeReported - lastReadInboxMessageId = entity.lastReadInboxMessageId - lastReadOutboxMessageId = entity.lastReadOutboxMessageId - replyMarkupMessageId = entity.replyMarkupMessageId - messageSenderId = entity.messageSenderId?.let { sender -> - TdApi.MessageSenderUser(sender) - } - blockList = if (entity.blockList) TdApi.BlockListMain() else null - permissions = TdApi.ChatPermissions( - entity.permissionCanSendBasicMessages, - entity.permissionCanSendAudios, - entity.permissionCanSendDocuments, - entity.permissionCanSendPhotos, - entity.permissionCanSendVideos, - entity.permissionCanSendVideoNotes, - entity.permissionCanSendVoiceNotes, - entity.permissionCanSendPolls, - entity.permissionCanSendOtherMessages, - entity.permissionCanAddLinkPreviews, - entity.permissionCanEditTag, - entity.permissionCanChangeInfo, - entity.permissionCanInviteUsers, - entity.permissionCanPinMessages, - entity.permissionCanCreateTopics - ) - clientData = "mc:${entity.memberCount};oc:${entity.onlineCount}" - } - if (entity.photoId != 0) { - fileCache[entity.photoId] = TdApi.File().apply { - id = entity.photoId - local = TdApi.LocalFile().apply { - this.path = entity.avatarPath.orEmpty() - } - } - } - chatPermissionsCache[entity.id] = chat.permissions - onlineMemberCount[entity.id] = entity.onlineCount - putChat(chat) - } - - private fun parsePositionsCache(raw: String?): Array? { - if (raw.isNullOrBlank()) return null - - val parsed = raw.split("|").mapNotNull { token -> - val parts = token.split(":") - when (parts.firstOrNull()) { - "m" -> { - if (parts.size < 3) return@mapNotNull null - val order = parts[1].toLongOrNull() ?: return@mapNotNull null - if (order == 0L) return@mapNotNull null - val pinned = parts[2] == "1" - TdApi.ChatPosition(TdApi.ChatListMain(), order, pinned, null) - } - - "a" -> { - if (parts.size < 3) return@mapNotNull null - val order = parts[1].toLongOrNull() ?: return@mapNotNull null - if (order == 0L) return@mapNotNull null - val pinned = parts[2] == "1" - TdApi.ChatPosition(TdApi.ChatListArchive(), order, pinned, null) - } - - "f" -> { - if (parts.size < 4) return@mapNotNull null - val folderId = parts[1].toIntOrNull() ?: return@mapNotNull null - val order = parts[2].toLongOrNull() ?: return@mapNotNull null - if (order == 0L) return@mapNotNull null - val pinned = parts[3] == "1" - TdApi.ChatPosition(TdApi.ChatListFolder(folderId), order, pinned, null) - } - - else -> null - } - } - - return parsed.takeIf { it.isNotEmpty() }?.toTypedArray() - } -} diff --git a/data/src/main/java/org/monogram/data/chats/ChatFileManager.kt b/data/src/main/java/org/monogram/data/chats/ChatFileManager.kt deleted file mode 100644 index a199e115..00000000 --- a/data/src/main/java/org/monogram/data/chats/ChatFileManager.kt +++ /dev/null @@ -1,97 +0,0 @@ -package org.monogram.data.chats - -import org.monogram.data.core.coRunCatching -import kotlinx.coroutines.launch -import org.drinkless.tdlib.TdApi -import org.monogram.core.DispatcherProvider -import org.monogram.core.ScopeProvider -import org.monogram.data.gateway.TelegramGateway -import org.monogram.data.infra.FileDownloadQueue -import java.util.* -import java.util.concurrent.ConcurrentHashMap - - -class ChatFileManager( - private val gateway: TelegramGateway, - private val dispatchers: DispatcherProvider, - private val fileQueue: FileDownloadQueue, - scopeProvider: ScopeProvider, - private val onUpdate: () -> Unit -) { - private val scope = scopeProvider.appScope - - private val downloadingFiles: MutableSet = Collections.newSetFromMap(ConcurrentHashMap()) - private val loadingEmojis: MutableSet = Collections.newSetFromMap(ConcurrentHashMap()) - private val filePaths = ConcurrentHashMap() - private val emojiPathsCache = ConcurrentHashMap() - private val fileIdToEmojiId = ConcurrentHashMap() - private val chatPhotoIds = ConcurrentHashMap() - private val trackedFileIds = Collections.newSetFromMap(ConcurrentHashMap()) - - fun getFilePath(fileId: Int): String? = filePaths[fileId] - fun getEmojiPath(emojiId: Long): String? = emojiPathsCache[emojiId] - fun getChatIdByPhotoId(fileId: Int): Long? = chatPhotoIds[fileId] - - fun registerChatPhoto(fileId: Int, chatId: Long) { - chatPhotoIds[fileId] = chatId - } - - fun registerTrackedFile(fileId: Int) { - if (fileId != 0) trackedFileIds.add(fileId) - } - - fun handleFileUpdate(file: TdApi.File): Boolean { - if (file.local.isDownloadingCompleted) { - filePaths[file.id] = file.local.path - return handleFileUpdated(file.id, file.local.path) - } - return false - } - - private fun handleFileUpdated(fileId: Int, path: String): Boolean { - if (path.isEmpty()) return false - var updated = false - fileIdToEmojiId[fileId]?.let { emojiId -> - emojiPathsCache[emojiId] = path - updated = true - } - if (chatPhotoIds.containsKey(fileId)) updated = true - if (trackedFileIds.remove(fileId)) updated = true - return updated - } - - fun downloadFile(fileId: Int, priority: Int, offset: Long = 0, limit: Long = 0, synchronous: Boolean = true) { - if (fileId == 0) return - val effectivePriority = if (priority <= 1) 16 else priority - fileQueue.enqueue(fileId, effectivePriority, FileDownloadQueue.DownloadType.DEFAULT, offset, limit, synchronous) - if (synchronous) { - scope.launch(dispatchers.io) { - coRunCatching { - fileQueue.waitForDownload(fileId).await() - } - } - } - } - - fun loadEmoji(emojiId: Long) { - if (emojiId == 0L || emojiPathsCache.containsKey(emojiId)) return - if (loadingEmojis.add(emojiId)) { - scope.launch(dispatchers.io) { - coRunCatching { - val result = gateway.execute(TdApi.GetCustomEmojiStickers(longArrayOf(emojiId))) - val sticker = result.stickers.firstOrNull() ?: return@launch - val file = sticker.sticker - val path = file.local.path.ifEmpty { filePaths[file.id] ?: "" } - fileIdToEmojiId[file.id] = emojiId - if (path.isNotEmpty()) { - emojiPathsCache[emojiId] = path - onUpdate() - } else { - downloadFile(file.id, 32) - } - } - loadingEmojis.remove(emojiId) - } - } - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/chats/ChatFolderManager.kt b/data/src/main/java/org/monogram/data/chats/ChatFolderManager.kt deleted file mode 100644 index 2212df88..00000000 --- a/data/src/main/java/org/monogram/data/chats/ChatFolderManager.kt +++ /dev/null @@ -1,203 +0,0 @@ -package org.monogram.data.chats - -import android.util.Log -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch -import kotlinx.serialization.json.Json -import org.drinkless.tdlib.TdApi -import org.monogram.core.DispatcherProvider -import org.monogram.core.ScopeProvider -import org.monogram.data.core.coRunCatching -import org.monogram.data.db.dao.ChatFolderDao -import org.monogram.data.db.model.ChatFolderEntity -import org.monogram.data.gateway.TelegramGateway -import org.monogram.domain.models.FolderModel -import org.monogram.domain.repository.CacheProvider -import java.util.concurrent.ConcurrentHashMap - -private const val TAG = "ChatFolderManager" - -class ChatFolderManager( - private val gateway: TelegramGateway, - private val dispatchers: DispatcherProvider, - scopeProvider: ScopeProvider, - private val foldersFlow: MutableStateFlow>, - private val cacheProvider: CacheProvider, - private val chatFolderDao: ChatFolderDao -) { - private val scope = scopeProvider.appScope - - private val chatUnreadCounts = ConcurrentHashMap() - private val folderChatIds = ConcurrentHashMap>() - private val folderPinnedChatIds = ConcurrentHashMap>() - - init { - val cachedFolders = cacheProvider.chatFolders.value - if (cachedFolders.isNotEmpty()) { - foldersFlow.update { cachedFolders } - cachedFolders.forEach { folder -> - if (folder.id > 0) { - folderChatIds[folder.id] = folder.includedChatIds - folderPinnedChatIds[folder.id] = folder.pinnedChatIds - } - } - } - - scope.launch { - chatFolderDao.getChatFolders().collect { entities -> - val folders = entities.mapNotNull { - try { - Json.decodeFromString(it.data) - } catch (e: Exception) { - null - } - } - if (folders.isNotEmpty()) { - foldersFlow.update { folders } - cacheProvider.setChatFolders(folders) - folders.forEach { folder -> - if (folder.id > 0) { - folderChatIds[folder.id] = folder.includedChatIds - folderPinnedChatIds[folder.id] = folder.pinnedChatIds - } - } - } - } - } - } - - fun handleChatFoldersUpdate(update: TdApi.UpdateChatFolders) { - val folderInfos = update.chatFolders - Log.d(TAG, "handleChatFoldersUpdate: ${folderInfos.size} folders") - - val currentFolders = foldersFlow.value - val newFolders = listOf(FolderModel(-1, "", "All")) + - folderInfos.map { info -> - val existing = currentFolders.find { it.id == info.id } - FolderModel( - id = info.id, - title = info.name.text.text, - iconName = info.icon?.name, - unreadCount = existing?.unreadCount ?: 0, - includedChatIds = existing?.includedChatIds ?: emptyList(), - pinnedChatIds = existing?.pinnedChatIds ?: emptyList() - ) - } - - foldersFlow.update { newFolders } - cacheProvider.setChatFolders(newFolders) - saveFoldersToDb(newFolders) - - folderInfos.forEach { info -> - scope.launch(dispatchers.io) { - coRunCatching { - val result = gateway.execute(TdApi.GetChatFolder(info.id)) - val chatIds = result.includedChatIds.toList() - val pinnedIds = result.pinnedChatIds.toList() - folderChatIds[info.id] = chatIds - folderPinnedChatIds[info.id] = pinnedIds - Log.d(TAG, "Folder ${info.id} (${info.name.text.text}) has ${chatIds.size} chats, ${pinnedIds.size} pinned") - - foldersFlow.update { current -> - val updated = current.map { folder -> - if (folder.id == info.id) folder.copy( - unreadCount = chatIds.sumOf { chatUnreadCounts[it] ?: 0 }, - includedChatIds = chatIds, - pinnedChatIds = pinnedIds - ) else folder - } - cacheProvider.setChatFolders(updated) - saveFoldersToDb(updated) - updated - } - }.onFailure { e -> - Log.e(TAG, "Failed to fetch folder ${info.id}", e) - } - } - } - } - - private fun saveFoldersToDb(folders: List) { - scope.launch(dispatchers.io) { - val entities = folders.mapIndexed { index, folder -> - ChatFolderEntity(folder.id, Json.encodeToString(folder), index) - } - chatFolderDao.clearAll() - chatFolderDao.insertChatFolders(entities) - } - } - - fun handleUpdateChatUnreadCount(chatId: Long, unreadMentionCount: Int) { - Log.d(TAG, "handleUpdateChatUnreadCount: chatId=$chatId, count=$unreadMentionCount") - chatUnreadCounts[chatId] = unreadMentionCount - folderChatIds.forEach { (folderId, chatIds) -> - if (chatIds.contains(chatId)) refreshFolderUnreadCount(folderId) - } - refreshFolderUnreadCount(-1) - } - - private fun refreshFolderUnreadCount(folderId: Int) { - foldersFlow.update { current -> - current.map { folder -> - if (folder.id != folderId) return@map folder - val count = if (folderId == -1) { - chatUnreadCounts.values.sum() - } else { - folderChatIds[folderId]?.sumOf { chatUnreadCounts[it] ?: 0 } ?: 0 - } - Log.d(TAG, "refreshFolderUnreadCount: folderId=$folderId, count=$count") - folder.copy(unreadCount = count) - } - } - } - - suspend fun createFolder(title: String, iconName: String?, includedChatIds: List) { - Log.d(TAG, "createFolder: title=$title, chatsCount=${includedChatIds.size}") - val folder = TdApi.ChatFolder().apply { - name = TdApi.ChatFolderName().apply { - text = TdApi.FormattedText().apply { text = title } - } - icon = if (!iconName.isNullOrEmpty()) TdApi.ChatFolderIcon(iconName) else null - this.includedChatIds = includedChatIds.toLongArray() - excludedChatIds = LongArray(0) - pinnedChatIds = LongArray(0) - } - gateway.execute(TdApi.CreateChatFolder(folder)) - } - - suspend fun updateFolder(folderId: Int, title: String, iconName: String?, includedChatIds: List) { - Log.d(TAG, "updateFolder: folderId=$folderId, title=$title") - val result = gateway.execute(TdApi.GetChatFolder(folderId)) - result.name = TdApi.ChatFolderName().apply { - text = TdApi.FormattedText().apply { text = title } - } - result.icon = if (!iconName.isNullOrEmpty()) TdApi.ChatFolderIcon(iconName) else null - result.includedChatIds = includedChatIds.toLongArray() - gateway.execute(TdApi.EditChatFolder(folderId, result)) - } - - suspend fun reorderFolders(folderIds: List) { - Log.d(TAG, "reorderFolders: $folderIds") - val userFolderIdsOnly = folderIds.filter { it > 0 } - foldersFlow.update { current -> - val system = current.filter { it.id < 0 } - val user = current.filter { it.id > 0 } - val sorted = userFolderIdsOnly.mapNotNull { id -> user.find { it.id == id } } - val remaining = user.filter { it.id !in userFolderIdsOnly } - val newList = system + sorted + remaining - cacheProvider.setChatFolders(newList) - saveFoldersToDb(newList) - newList - } - gateway.execute(TdApi.ReorderChatFolders(userFolderIdsOnly.toIntArray(), 0)) - } - - fun getPinnedChatIds(folderId: Int): List { - return folderPinnedChatIds[folderId] ?: emptyList() - } - - fun getIncludedChatIds(folderId: Int): List { - return folderChatIds[folderId] ?: emptyList() - } -} diff --git a/data/src/main/java/org/monogram/data/chats/ChatListManager.kt b/data/src/main/java/org/monogram/data/chats/ChatListManager.kt deleted file mode 100644 index a75e1f4e..00000000 --- a/data/src/main/java/org/monogram/data/chats/ChatListManager.kt +++ /dev/null @@ -1,203 +0,0 @@ -package org.monogram.data.chats - -import android.util.Log -import org.drinkless.tdlib.TdApi - -class ChatListManager( - private val cache: ChatCache, - private val onChatNeeded: (Long) -> Unit -) { - private val tag = "PinnedDiag" - - fun rebuildChatList( - limit: Int = Int.MAX_VALUE, - excludedChatIds: List = emptyList(), - mapChat: (TdApi.Chat, Long, Boolean) -> org.monogram.domain.models.ChatModel? - ): List { - val excludedSet = if (excludedChatIds.isEmpty()) emptySet() else excludedChatIds.toHashSet() - val pinnedEntries = ArrayList>() - val otherEntries = ArrayList>() - - cache.activeListPositions.forEach { (chatId, position) -> - if (chatId in excludedSet) return@forEach - val entry = chatId to position - if (position.isPinned) { - pinnedEntries.add(entry) - } else { - otherEntries.add(entry) - } - } - - pinnedEntries.sortWith( - compareByDescending> { it.second.order } - .thenByDescending { it.first } - ) - otherEntries.sortWith( - compareByDescending> { (chatId, _) -> - cache.allChats[chatId]?.lastMessage?.date?.toLong() ?: 0L - } - .thenByDescending { it.second.order } - .thenByDescending { it.first } - ) - - fun mapEntry(chatId: Long, position: TdApi.ChatPosition): org.monogram.domain.models.ChatModel? { - val chat = cache.allChats[chatId] - if (chat == null) { - if (position.order != 0L) onChatNeeded(chatId) - return null - } - return mapChat(chat, position.order, position.isPinned) - } - - val result = ArrayList() - var pinnedMapped = 0 - val missingPinnedIds = ArrayList() - pinnedEntries.forEach { (chatId, position) -> - val mapped = mapEntry(chatId, position) - if (mapped != null) { - result.add(mapped) - pinnedMapped += 1 - } else { - missingPinnedIds.add(chatId) - } - } - - if (pinnedEntries.isNotEmpty()) { - Log.d( - tag, - "rebuild pinned: total=${pinnedEntries.size} mapped=$pinnedMapped missing=${missingPinnedIds.size} missingIds=${ - missingPinnedIds.take( - 10 - ) - } active=${cache.activeListPositions.size} chats=${cache.allChats.size}" - ) - } - - val othersLimit = (limit - result.size).coerceAtLeast(0) - if (othersLimit == 0) return result - - var loadedOthers = 0 - for ((chatId, position) in otherEntries) { - val model = mapEntry(chatId, position) ?: continue - result.add(model) - loadedOthers += 1 - if (loadedOthers >= othersLimit) break - } - - return result - } - - fun updateChatPositionInCache( - chatId: Long, - newPosition: TdApi.ChatPosition, - activeChatList: TdApi.ChatList - ): Boolean { - val isForActiveList = isSameChatList(newPosition.list, activeChatList) - val chat = cache.allChats[chatId] - var activeListChanged = false - - if (chat != null) { - synchronized(chat) { - val oldPositions = chat.positions - val index = oldPositions.indexOfFirst { isSameChatList(it.list, newPosition.list) } - - if (newPosition.order == 0L) { - if (index != -1) { - chat.positions = oldPositions.filterIndexed { i, _ -> i != index }.toTypedArray() - } - } else { - if (index != -1) { - val oldPos = oldPositions[index] - if (oldPos.order != newPosition.order || oldPos.isPinned != newPosition.isPinned) { - val nextPositions = oldPositions.copyOf() - nextPositions[index] = newPosition - chat.positions = nextPositions - } - } else { - chat.positions = oldPositions + newPosition - } - } - } - } else if (newPosition.order != 0L && isForActiveList) { - onChatNeeded(chatId) - } - - if (isForActiveList) { - val currentPos = cache.activeListPositions[chatId] - if (newPosition.order == 0L) { - val shouldProtectPinned = currentPos?.isPinned == true && cache.protectedPinnedChatIds.contains(chatId) - if (currentPos?.isPinned == true || cache.protectedPinnedChatIds.contains(chatId)) { - Log.w( - tag, - "updatePosition order=0 for pinned-like chatId=$chatId currentPinned=${currentPos?.isPinned} protected=${ - cache.protectedPinnedChatIds.contains( - chatId - ) - } authoritative=${cache.authoritativeActiveListChatIds.contains(chatId)}" - ) - } - if (!shouldProtectPinned) { - if (cache.activeListPositions.remove(chatId) != null) activeListChanged = true - cache.authoritativeActiveListChatIds.remove(chatId) - cache.protectedPinnedChatIds.remove(chatId) - } - } else { - val oldPos = cache.activeListPositions.put(chatId, newPosition) - cache.authoritativeActiveListChatIds.add(chatId) - if (newPosition.isPinned) { - Log.d( - tag, - "updatePosition pinned set chatId=$chatId order=${newPosition.order} oldPinned=${oldPos?.isPinned}" - ) - cache.protectedPinnedChatIds.add(chatId) - } else { - cache.protectedPinnedChatIds.remove(chatId) - } - if (oldPos == null || oldPos.order != newPosition.order || oldPos.isPinned != newPosition.isPinned) { - activeListChanged = true - } - } - } - - return activeListChanged - } - - fun updateActiveListPositions( - chatId: Long, - positions: Array, - activeChatList: TdApi.ChatList - ): Boolean { - val newPos = positions.find { isSameChatList(it.list, activeChatList) } - return if (newPos != null && newPos.order != 0L) { - val oldPos = cache.activeListPositions.put(chatId, newPos) - if (newPos.isPinned) { - cache.protectedPinnedChatIds.add(chatId) - } else { - cache.protectedPinnedChatIds.remove(chatId) - } - oldPos == null || oldPos.order != newPos.order || oldPos.isPinned != newPos.isPinned - } else { - if (cache.protectedPinnedChatIds.contains(chatId)) { - Log.d(tag, "updateActivePositions skip remove protected pinned chatId=$chatId") - return false - } - if (cache.authoritativeActiveListChatIds.contains(chatId)) { - if (cache.activeListPositions[chatId]?.isPinned == true) { - Log.d(tag, "updateActivePositions skip remove authoritative pinned chatId=$chatId") - } - return false - } - cache.activeListPositions.remove(chatId) != null - } - } - - fun isSameChatList(a: TdApi.ChatList?, b: TdApi.ChatList?): Boolean { - if (a === b) return true - if (a == null || b == null) return false - if (a.constructor != b.constructor) return false - if (a is TdApi.ChatListFolder && b is TdApi.ChatListFolder) { - return a.chatFolderId == b.chatFolderId - } - return true - } -} diff --git a/data/src/main/java/org/monogram/data/chats/ChatModelFactory.kt b/data/src/main/java/org/monogram/data/chats/ChatModelFactory.kt deleted file mode 100644 index 7525b38b..00000000 --- a/data/src/main/java/org/monogram/data/chats/ChatModelFactory.kt +++ /dev/null @@ -1,319 +0,0 @@ -package org.monogram.data.chats - -import org.monogram.data.core.coRunCatching -import kotlinx.coroutines.launch -import org.drinkless.tdlib.TdApi -import org.monogram.core.DispatcherProvider -import org.monogram.core.ScopeProvider -import org.monogram.data.gateway.TelegramGateway -import org.monogram.data.mapper.ChatMapper -import org.monogram.data.mapper.isForcedVerifiedChat -import org.monogram.data.mapper.isForcedVerifiedUser -import org.monogram.data.mapper.isSponsoredUser -import org.monogram.domain.models.ChatModel -import org.monogram.domain.models.UsernamesModel -import org.monogram.domain.repository.AppPreferencesProvider -import java.io.File -import java.util.concurrent.ConcurrentHashMap - -class ChatModelFactory( - private val gateway: TelegramGateway, - private val dispatchers: DispatcherProvider, - scopeProvider: ScopeProvider, - private val cache: ChatCache, - private val chatMapper: ChatMapper, - private val fileManager: ChatFileManager, - private val typingManager: ChatTypingManager, - private val appPreferences: AppPreferencesProvider, - private val triggerUpdate: (Long?) -> Unit, - private val fetchUser: (Long) -> Unit -) { - private val scope = scopeProvider.appScope - private val missingUserFullInfoUntilMs = ConcurrentHashMap() - - fun mapChatToModel(chat: TdApi.Chat, order: Long, isPinned: Boolean): ChatModel { - val cachedCounts = parseCachedCounts(chat.clientData) - var smallPhoto = chat.photo?.small - var photoId = smallPhoto?.id ?: 0 - var isSupergroup = false - var isChannel = false - var memberCount = cachedCounts?.first ?: 0 - var onlineCount = cache.onlineMemberCount[chat.id] ?: cachedCounts?.second ?: 0 - var isOnline = false - var userStatus = "" - var isVerified = isForcedVerifiedChat(chat.id) - var isForum = false - var isBot = false - var isMember = true - var isAdmin = false - var isSponsor = false - var username: String? = null - var usernames: UsernamesModel? = null - var description: String? = null - var inviteLink: String? = null - var hasAutomaticTranslation = false - var personalAvatarPath: String? = null - - val isArchived = chat.positions.any { it.list is TdApi.ChatListArchive } - - when (val type = chat.type) { - is TdApi.ChatTypeBasicGroup -> { - cache.basicGroups[type.basicGroupId]?.let { - memberCount = it.memberCount - isMember = it.status !is TdApi.ChatMemberStatusLeft - isAdmin = it.status is TdApi.ChatMemberStatusAdministrator || - it.status is TdApi.ChatMemberStatusCreator - } ?: lazyLoad(cache.pendingBasicGroups, type.basicGroupId) { - if (type.basicGroupId == 0L) return@lazyLoad - val result = gateway.execute(TdApi.GetBasicGroup(type.basicGroupId)) - cache.basicGroups[result.id] = result - triggerUpdate(chat.id) - } - - cache.basicGroupFullInfoCache[type.basicGroupId]?.let { fullInfo -> - description = fullInfo.description - inviteLink = fullInfo.inviteLink?.inviteLink - personalAvatarPath = null - } ?: lazyLoad(cache.pendingBasicGroupFullInfo, type.basicGroupId) { - if (type.basicGroupId == 0L) return@lazyLoad - val result = gateway.execute(TdApi.GetBasicGroupFullInfo(type.basicGroupId)) - cache.basicGroupFullInfoCache[type.basicGroupId] = result - triggerUpdate(chat.id) - } - } - - is TdApi.ChatTypeSupergroup -> { - isSupergroup = true - isChannel = type.isChannel - val supergroup = cache.supergroups[type.supergroupId] - supergroup?.let { - memberCount = it.memberCount - isVerified = (it.verificationStatus?.isVerified ?: false) || isForcedVerifiedChat(chat.id) - isForum = it.isForum - isMember = it.status !is TdApi.ChatMemberStatusLeft - isAdmin = it.status is TdApi.ChatMemberStatusAdministrator || - it.status is TdApi.ChatMemberStatusCreator - username = it.usernames?.activeUsernames?.firstOrNull() - usernames = it.usernames?.toDomain() - hasAutomaticTranslation = it.hasAutomaticTranslation - } ?: lazyLoad(cache.pendingSupergroups, type.supergroupId) { - if (type.supergroupId == 0L) return@lazyLoad - val result = gateway.execute(TdApi.GetSupergroup(type.supergroupId)) - cache.supergroups[result.id] = result - triggerUpdate(chat.id) - } - - val canLoadSupergroupFullInfo = supergroup?.status?.let { - it !is TdApi.ChatMemberStatusLeft && it !is TdApi.ChatMemberStatusBanned - } == true - - if (canLoadSupergroupFullInfo) { - cache.supergroupFullInfoCache[type.supergroupId]?.let { fullInfo -> - description = fullInfo.description - inviteLink = fullInfo.inviteLink?.inviteLink - personalAvatarPath = null - } ?: lazyLoad(cache.pendingSupergroupFullInfo, type.supergroupId) { - if (type.supergroupId == 0L) return@lazyLoad - val result = gateway.execute(TdApi.GetSupergroupFullInfo(type.supergroupId)) - cache.supergroupFullInfoCache[type.supergroupId] = result - triggerUpdate(chat.id) - } - } - } - - is TdApi.ChatTypePrivate -> { - cache.usersCache[type.userId]?.let { user -> - isBot = user.type is TdApi.UserTypeBot - isOnline = !isBot && user.status is TdApi.UserStatusOnline - if (isOnline) onlineCount = 1 - userStatus = chatMapper.formatUserStatus(user.status, isBot) - isVerified = (user.verificationStatus?.isVerified ?: false) || isForcedVerifiedUser(user.id) - isSponsor = isSponsoredUser(user.id) - username = user.usernames?.activeUsernames?.firstOrNull() - usernames = user.usernames?.toDomain() - if (smallPhoto == null) { - smallPhoto = user.profilePhoto?.small - photoId = smallPhoto?.id ?: 0 - } - } ?: run { fetchUser(type.userId) } - - cache.userFullInfoCache[type.userId]?.let { fullInfo -> - description = fullInfo.bio?.text - personalAvatarPath = resolvePhotoPath(fullInfo.personalPhoto, chat.id) - } ?: run { - if (!isUserFullInfoTemporarilyMissing(type.userId)) { - lazyLoad(cache.pendingUserFullInfo, type.userId) { - if (type.userId == 0L) return@lazyLoad - val result = coRunCatching { gateway.execute(TdApi.GetUserFullInfo(type.userId)) }.getOrNull() - if (result != null) { - cache.userFullInfoCache[type.userId] = result - missingUserFullInfoUntilMs.remove(type.userId) - triggerUpdate(chat.id) - } else { - rememberMissingUserFullInfo(type.userId) - } - } - } - } - } - - else -> {} - } - - if (cache.chatPermissionsCache[chat.id] == null) { - lazyLoad(cache.pendingChatPermissions, chat.id) { - val result = gateway.execute(TdApi.GetChat(chat.id)) - cache.chatPermissionsCache[chat.id] = result.permissions - triggerUpdate(chat.id) - } - } - - if (cache.myChatMemberCache[chat.id] == null) { - val canGetMember = when (val type = chat.type) { - is TdApi.ChatTypePrivate, is TdApi.ChatTypeBasicGroup -> true - is TdApi.ChatTypeSupergroup -> !type.isChannel || - cache.supergroups[type.supergroupId]?.status.let { - it is TdApi.ChatMemberStatusAdministrator || it is TdApi.ChatMemberStatusCreator - } - else -> false - } - if (canGetMember) { - lazyLoad(cache.pendingMyChatMember, chat.id) { - val me = gateway.execute(TdApi.GetMe()) - val member = gateway.execute( - TdApi.GetChatMember(chat.id, TdApi.MessageSenderUser(me.id)) - ) - cache.myChatMemberCache[chat.id] = member - triggerUpdate(chat.id) - } - } - } - - val finalPath = resolvePhotoPath(smallPhoto, chat.id) - - val emojiStatusId = (chat.emojiStatus?.type as? TdApi.EmojiStatusTypeCustomEmoji)?.customEmojiId ?: 0L - var emojiPath: String? = null - if (emojiStatusId != 0L) { - emojiPath = fileManager.getEmojiPath(emojiStatusId) - if (emojiPath == null) fileManager.loadEmoji(emojiStatusId) - } - - val (txt, entities, time) = chatMapper.formatMessageInfo(chat.lastMessage, chat) { userId -> - cache.usersCache[userId]?.firstName ?: run { fetchUser(userId); null } - } - - val isMuted = when { - chat.notificationSettings.muteFor > 0 -> true - chat.notificationSettings.useDefaultMuteFor -> when { - isChannel -> !appPreferences.channelsNotifications.value - isSupergroup || chat.type is TdApi.ChatTypeBasicGroup -> !appPreferences.groupsNotifications.value - else -> !appPreferences.privateChatsNotifications.value - } - else -> false - } - - return chatMapper.mapChatToModel( - chat = chat, - order = order, - isPinned = isPinned, - isArchived = isArchived, - smallPhotoPath = finalPath, - photoId = photoId, - isOnline = isOnline, - userStatus = userStatus, - isVerified = isVerified, - isSponsor = isSponsor, - isForum = isForum, - isBot = isBot, - memberCount = memberCount, - onlineCount = onlineCount, - emojiPath = emojiPath, - typingAction = typingManager.formatTypingAction(chat.id), - lastMessageText = txt, - lastMessageEntities = entities, - lastMessageTime = time, - lastMessageDate = chat.lastMessage?.date?.toLong() ?: 0L, - isMuted = isMuted, - isAdmin = isAdmin, - isMember = isMember, - username = username, - usernames = usernames, - description = description, - inviteLink = inviteLink, - hasAutomaticTranslation = hasAutomaticTranslation, - personalAvatarPath = personalAvatarPath - ) - } - - private fun lazyLoad(pendingSet: MutableSet, key: K, block: suspend () -> Unit) { - if (pendingSet.add(key)) { - scope.launch(dispatchers.io) { - coRunCatching { block() } - pendingSet.remove(key) - } - } - } - - private fun isUserFullInfoTemporarilyMissing(userId: Long): Boolean { - if (userId <= 0L) return true - val until = missingUserFullInfoUntilMs[userId] ?: return false - if (until > System.currentTimeMillis()) return true - missingUserFullInfoUntilMs.remove(userId, until) - return false - } - - private fun rememberMissingUserFullInfo(userId: Long) { - if (userId <= 0L) return - missingUserFullInfoUntilMs[userId] = System.currentTimeMillis() + USER_FULL_INFO_RETRY_TTL_MS - } - - private fun resolvePhotoPath(photoFile: TdApi.File?, chatId: Long): String? { - if (photoFile == null) return null - if (photoFile.id != 0) { - fileManager.registerChatPhoto(photoFile.id, chatId) - } - - val localPath = photoFile.local.path - if (isValidPath(localPath)) { - return localPath - } - - val cachedPath = photoFile.id.takeIf { it != 0 }?.let { fileManager.getFilePath(it) } - if (isValidPath(cachedPath)) { - return cachedPath - } - - if (photoFile.id != 0) { - fileManager.downloadFile(photoFile.id, 24, offset = 0, limit = 0, synchronous = false) - } - return null - } - - private fun resolvePhotoPath(chatPhoto: TdApi.ChatPhoto?, chatId: Long): String? { - if (chatPhoto == null) return null - return resolvePhotoPath(chatPhoto.animation?.file, chatId) - ?: resolvePhotoPath(chatPhoto.sizes.lastOrNull()?.photo, chatId) - } - - private fun TdApi.Usernames.toDomain() = UsernamesModel( - activeUsernames = activeUsernames.toList(), - disabledUsernames = disabledUsernames.toList(), - collectibleUsernames = collectibleUsernames.toList() - ) - - private fun parseCachedCounts(clientData: String?): Pair? { - if (clientData.isNullOrBlank()) return null - val memberCount = Regex("""mc:(\d+)""").find(clientData)?.groupValues?.getOrNull(1)?.toIntOrNull() - val onlineCount = Regex("""oc:(\d+)""").find(clientData)?.groupValues?.getOrNull(1)?.toIntOrNull() - if (memberCount == null && onlineCount == null) return null - return (memberCount ?: 0) to (onlineCount ?: 0) - } - - private fun isValidPath(path: String?): Boolean { - return !path.isNullOrBlank() && File(path).exists() - } - - companion object { - private const val USER_FULL_INFO_RETRY_TTL_MS = 5 * 60 * 1000L - } -} diff --git a/data/src/main/java/org/monogram/data/chats/ChatTypingManager.kt b/data/src/main/java/org/monogram/data/chats/ChatTypingManager.kt deleted file mode 100644 index c6265c3f..00000000 --- a/data/src/main/java/org/monogram/data/chats/ChatTypingManager.kt +++ /dev/null @@ -1,109 +0,0 @@ -package org.monogram.data.chats - -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Job -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import org.drinkless.tdlib.TdApi -import org.monogram.domain.repository.StringProvider -import java.util.concurrent.ConcurrentHashMap - -class ChatTypingManager( - private val scope: CoroutineScope, - private val usersCache: Map, - private val allChats: Map, - private val stringProvider: StringProvider, - private val onUpdate: () -> Unit, - private val onUserNeeded: (Long) -> Unit -) { - private val typingStates = ConcurrentHashMap>() - private val typingJobs = ConcurrentHashMap>() - - fun handleChatAction(update: TdApi.UpdateChatAction) { - val chatId = update.chatId - val action = update.action - val senderId = update.senderId - if (senderId !is TdApi.MessageSenderUser) return - val userId = senderId.userId - - if (action is TdApi.ChatActionCancel) { - removeTypingUser(chatId, userId) - onUpdate() - return - } - - val actionStringRes = when (action) { - is TdApi.ChatActionTyping -> "typing_typing" - is TdApi.ChatActionRecordingVideo -> "typing_recording_video" - is TdApi.ChatActionRecordingVoiceNote -> "typing_recording_voice" - is TdApi.ChatActionUploadingPhoto -> "typing_uploading_photo" - is TdApi.ChatActionUploadingVideo -> "typing_uploading_video" - is TdApi.ChatActionUploadingDocument -> "typing_uploading_document" - is TdApi.ChatActionChoosingSticker -> "typing_choosing_sticker" - is TdApi.ChatActionStartPlayingGame -> "typing_playing_game" - else -> null - } - - if (actionStringRes == null) return - - if (usersCache[userId] == null) { - onUserNeeded(userId) - } - - val chatTyping = typingStates.getOrPut(chatId) { ConcurrentHashMap() } - chatTyping[userId] = actionStringRes - val chatJobs = typingJobs.getOrPut(chatId) { ConcurrentHashMap() } - chatJobs[userId]?.cancel() - chatJobs[userId] = scope.launch { - delay(6000) - removeTypingUser(chatId, userId) - onUpdate() - } - onUpdate() - } - - fun removeTypingUser(chatId: Long, userId: Long) { - typingStates[chatId]?.remove(userId) - typingJobs[chatId]?.remove(userId)?.cancel() - } - - fun formatTypingAction(chatId: Long): String? { - val users = typingStates[chatId] ?: return null - val activeUserIds = users.keys.toList() - if (activeUserIds.isEmpty()) return null - val chat = allChats[chatId] ?: return null - if (chat.type is TdApi.ChatTypePrivate) { - return stringProvider.getString(users[activeUserIds[0]]!!) - } - return when (val count = activeUserIds.size) { - 1 -> { - val user = usersCache[activeUserIds[0]] - val action = stringProvider.getString(users[activeUserIds[0]]!!) - if (user != null) "${user.firstName} $action" - else "${stringProvider.getString("typing_someone")} $action" - } - - 2 -> { - val user1 = usersCache[activeUserIds[0]] - val user2 = usersCache[activeUserIds[1]] - val action = stringProvider.getString("typing_multi_typing") - val and = stringProvider.getString("typing_and") - if (user1 != null && user2 != null) "${user1.firstName} $and ${user2.firstName} $action" - else stringProvider.getQuantityString("typing_multi_people", 2, 2) - } - - else -> { - val user1 = usersCache[activeUserIds[0]] - val andMore = stringProvider.getString("typing_and_more", count - 1) - val action = stringProvider.getString("typing_multi_typing") - if (user1 != null) "${user1.firstName} $andMore $action" - else stringProvider.getQuantityString("typing_multi_people", count, count) - } - } - } - - fun clearTypingStatus(chatId: Long) { - typingStates.remove(chatId) - typingJobs.remove(chatId)?.values?.forEach { it.cancel() } - } -} diff --git a/data/src/main/java/org/monogram/data/core/CoroutineCatching.kt b/data/src/main/java/org/monogram/data/core/CoroutineCatching.kt deleted file mode 100644 index cacf8f67..00000000 --- a/data/src/main/java/org/monogram/data/core/CoroutineCatching.kt +++ /dev/null @@ -1,25 +0,0 @@ -package org.monogram.data.core - -import kotlinx.coroutines.CancellationException - -inline fun coRunCatching(block: () -> R): Result { - return try { - Result.success(block()) - } catch (e: Throwable) { - if (e is CancellationException) { - throw e - } - Result.failure(e) - } -} - -inline fun T.coRunCatching(block: T.() -> R): Result { - return try { - Result.success(block()) - } catch (e: Throwable) { - if (e is CancellationException) { - throw e - } - Result.failure(e) - } -} diff --git a/data/src/main/java/org/monogram/data/datasource/FileDataSource.kt b/data/src/main/java/org/monogram/data/datasource/FileDataSource.kt deleted file mode 100644 index 7c873bb6..00000000 --- a/data/src/main/java/org/monogram/data/datasource/FileDataSource.kt +++ /dev/null @@ -1,13 +0,0 @@ -package org.monogram.data.datasource - -import kotlinx.coroutines.CompletableDeferred -import org.drinkless.tdlib.TdApi - -interface FileDataSource { - suspend fun downloadFile(fileId: Int, priority: Int, offset: Long, limit: Long, synchronous: Boolean): TdApi.File? - suspend fun cancelDownload(fileId: Int): TdApi.Ok? - suspend fun getFile(fileId: Int): TdApi.File? - suspend fun getFileDownloadedPrefixSize(fileId: Int, offset: Long): TdApi.FileDownloadedPrefixSize? - suspend fun readFilePart(fileId: Int, offset: Long, count: Long): TdApi.Data? - fun waitForUpload(fileId: Int): CompletableDeferred -} diff --git a/data/src/main/java/org/monogram/data/datasource/PlayerDataSourceFactoryImpl.kt b/data/src/main/java/org/monogram/data/datasource/PlayerDataSourceFactoryImpl.kt deleted file mode 100644 index 7359bd1c..00000000 --- a/data/src/main/java/org/monogram/data/datasource/PlayerDataSourceFactoryImpl.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.monogram.data.datasource - -import org.monogram.domain.repository.PlayerDataSourceFactory - -class PlayerDataSourceFactoryImpl( - private val fileDataSource: FileDataSource -) : PlayerDataSourceFactory { - - override fun createPayload(fileId: Int): Any { - return TelegramStreamingDataSource.Factory(fileDataSource, fileId) - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/TdFileDataSource.kt b/data/src/main/java/org/monogram/data/datasource/TdFileDataSource.kt deleted file mode 100644 index 4ef0730a..00000000 --- a/data/src/main/java/org/monogram/data/datasource/TdFileDataSource.kt +++ /dev/null @@ -1,51 +0,0 @@ -package org.monogram.data.datasource - -import kotlinx.coroutines.CompletableDeferred -import org.drinkless.tdlib.TdApi -import org.monogram.data.core.coRunCatching -import org.monogram.data.gateway.TelegramGateway -import org.monogram.data.infra.FileDownloadQueue - -class TdFileDataSource( - private val gateway: TelegramGateway, - private val fileDownloadQueue: FileDownloadQueue -) : FileDataSource { - override suspend fun downloadFile(fileId: Int, priority: Int, offset: Long, limit: Long, synchronous: Boolean): TdApi.File? { - fileDownloadQueue.clearSuppression(fileId) - fileDownloadQueue.enqueue( - fileId, - priority, - FileDownloadQueue.DownloadType.DEFAULT, - offset, - limit, - synchronous, - ignoreSuppression = true - ) - if (synchronous) { - coRunCatching { fileDownloadQueue.waitForDownload(fileId).await() } - } - return getFile(fileId) - } - - override suspend fun cancelDownload(fileId: Int): TdApi.Ok? { - fileDownloadQueue.cancelDownload(fileId, force = true) - val result = gateway.execute(TdApi.CancelDownloadFile(fileId, false)) - return if (result is TdApi.Ok) result else null - } - - override suspend fun getFile(fileId: Int): TdApi.File? { - return coRunCatching { gateway.execute(TdApi.GetFile(fileId)) }.getOrNull() - } - - override suspend fun getFileDownloadedPrefixSize(fileId: Int, offset: Long): TdApi.FileDownloadedPrefixSize? { - return coRunCatching { gateway.execute(TdApi.GetFileDownloadedPrefixSize(fileId, offset)) }.getOrNull() - } - - override suspend fun readFilePart(fileId: Int, offset: Long, count: Long): TdApi.Data? { - return coRunCatching { gateway.execute(TdApi.ReadFilePart(fileId, offset, count)) }.getOrNull() - } - - override fun waitForUpload(fileId: Int): CompletableDeferred { - return fileDownloadQueue.waitForUpload(fileId) - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/TelegramStreamingDataSource.kt b/data/src/main/java/org/monogram/data/datasource/TelegramStreamingDataSource.kt deleted file mode 100644 index f8d6f80d..00000000 --- a/data/src/main/java/org/monogram/data/datasource/TelegramStreamingDataSource.kt +++ /dev/null @@ -1,148 +0,0 @@ -package org.monogram.data.datasource - -import android.net.Uri -import androidx.annotation.OptIn -import androidx.media3.common.C -import androidx.media3.common.util.UnstableApi -import androidx.media3.datasource.BaseDataSource -import androidx.media3.datasource.DataSource -import androidx.media3.datasource.DataSpec -import kotlinx.coroutines.runBlocking -import org.drinkless.tdlib.TdApi -import java.io.IOException - -@OptIn(UnstableApi::class) -class TelegramStreamingDataSource( - private val fileDataSource: FileDataSource, - private val fileId: Int -) : BaseDataSource(true) { - - class Factory( - private val fileDataSource: FileDataSource, - private val fileId: Int - ) : DataSource.Factory { - override fun createDataSource(): DataSource = - TelegramStreamingDataSource(fileDataSource, fileId) - } - - private var dataSpec: DataSpec? = null - private var file: TdApi.File? = null - private var position: Long = 0 - private var bytesRemaining: Long = 0 - private var opened = false - - private var internalBuffer: ByteArray? = null - private var bufferOffset: Int = 0 - private var bufferLength: Int = 0 - - private val PREFETCH_SIZE = 512 * 1024L - - override fun open(dataSpec: DataSpec): Long { - this.dataSpec = dataSpec - this.position = dataSpec.position - - transferInitializing(dataSpec) - - file = runBlocking { fileDataSource.getFile(fileId) } - val f = file ?: throw IOException("File not found for fileId: $fileId") - - val totalSize = kotlin.math.max(f.size, f.expectedSize) - if (totalSize <= 0) { - throw IOException("Failed to get file size for fileId: $fileId") - } - - bytesRemaining = if (dataSpec.length != C.LENGTH_UNSET.toLong()) { - dataSpec.length - } else { - totalSize - dataSpec.position - } - - if (bytesRemaining > 0) { - runBlocking { - fileDataSource.downloadFile( - fileId = fileId, - priority = 16, - offset = position, - limit = kotlin.math.min(PREFETCH_SIZE, bytesRemaining), - synchronous = false - ) - } - } - - opened = true - transferStarted(dataSpec) - return bytesRemaining - } - - override fun read(buffer: ByteArray, offset: Int, readLength: Int): Int { - if (readLength == 0) return 0 - if (bytesRemaining <= 0L) return C.RESULT_END_OF_INPUT - - if (internalBuffer == null || bufferOffset >= bufferLength) { - val bytesToFetch = kotlin.math.min(PREFETCH_SIZE, bytesRemaining).toInt() - - runBlocking { - try { - val targetSize = bytesToFetch.toLong() - val prefix = fileDataSource.getFileDownloadedPrefixSize(fileId, position) - val downloadedPrefix = prefix?.size ?: 0L - val availableFromPosition = (downloadedPrefix - position).coerceAtLeast(0L) - - if (availableFromPosition < targetSize) { - fileDataSource.downloadFile(fileId, 24, position, targetSize, synchronous = false) - if (availableFromPosition == 0L) { - fileDataSource.downloadFile(fileId, 32, position, targetSize, synchronous = true) - } - } - - var filePart = fileDataSource.readFilePart(fileId, position, targetSize) - if (filePart?.data?.isEmpty() != false) { - fileDataSource.downloadFile(fileId, 32, position, targetSize, synchronous = true) - filePart = fileDataSource.readFilePart(fileId, position, targetSize) - } - - internalBuffer = filePart?.data - bufferOffset = 0 - bufferLength = internalBuffer?.size ?: 0 - - if (bufferLength > 0 && bytesRemaining > bufferLength) { - val nextOffset = position + bufferLength - val nextLimit = kotlin.math.min(PREFETCH_SIZE, bytesRemaining - bufferLength) - if (nextLimit > 0) { - fileDataSource.downloadFile(fileId, 16, nextOffset, nextLimit, synchronous = false) - } - } - } catch (e: Exception) { - throw IOException("Error reading file part: ${e.message}", e) - } - } - } - - if (bufferLength == 0 || internalBuffer == null) return C.RESULT_END_OF_INPUT - - val bytesToRead = kotlin.math.min(readLength, bufferLength - bufferOffset) - System.arraycopy(internalBuffer!!, bufferOffset, buffer, offset, bytesToRead) - - bufferOffset += bytesToRead - position += bytesToRead - bytesRemaining -= bytesToRead - bytesTransferred(bytesToRead) - - return bytesToRead - } - - override fun getUri(): Uri? = dataSpec?.uri - - override fun close() { - if (opened) { - opened = false - transferEnded() - } - dataSpec = null - file = null - - internalBuffer = null - bufferOffset = 0 - bufferLength = 0 - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/cache/ChatLocalDataSource.kt b/data/src/main/java/org/monogram/data/datasource/cache/ChatLocalDataSource.kt deleted file mode 100644 index 43f8fffe..00000000 --- a/data/src/main/java/org/monogram/data/datasource/cache/ChatLocalDataSource.kt +++ /dev/null @@ -1,52 +0,0 @@ -package org.monogram.data.datasource.cache - -import kotlinx.coroutines.flow.Flow -import org.monogram.data.db.model.ChatEntity -import org.monogram.data.db.model.ChatFullInfoEntity -import org.monogram.data.db.model.MessageEntity -import org.monogram.data.db.model.TopicEntity - -interface ChatLocalDataSource { - fun getAllChats(): Flow> - suspend fun getChat(chatId: Long): ChatEntity? - suspend fun insertChat(chat: ChatEntity) - suspend fun insertChats(chats: List) - suspend fun deleteChat(chatId: Long) - suspend fun clearAllChats() - suspend fun clearAll() - - fun getMessagesForChat(chatId: Long): Flow> - suspend fun getMessagesOlder(chatId: Long, fromMessageId: Long, limit: Int): List - suspend fun getMessagesNewer(chatId: Long, fromMessageId: Long, limit: Int): List - suspend fun getLatestMessages(chatId: Long, limit: Int): List - suspend fun insertMessage(message: MessageEntity) - suspend fun insertMessages(messages: List) - suspend fun markAsRead(chatId: Long, upToMessageId: Long) - suspend fun updateMessageContent( - messageId: Long, - content: String, - contentType: String, - contentMeta: String?, - mediaFileId: Int, - mediaPath: String?, - editDate: Int - ) - - suspend fun updateMediaPath(fileId: Int, path: String) - - suspend fun updateInteractionInfo(messageId: Long, viewCount: Int, forwardCount: Int, replyCount: Int) - suspend fun deleteMessage(messageId: Long) - suspend fun clearMessagesForChat(chatId: Long) - - suspend fun getChatFullInfo(chatId: Long): ChatFullInfoEntity? - suspend fun insertChatFullInfo(info: ChatFullInfoEntity) - suspend fun deleteChatFullInfo(chatId: Long) - - fun getTopicsForChat(chatId: Long): Flow> - suspend fun insertTopic(topic: TopicEntity) - suspend fun insertTopics(topics: List) - suspend fun deleteTopic(chatId: Long, topicId: Int) - suspend fun clearTopicsForChat(chatId: Long) - - suspend fun deleteExpired(timestamp: Long) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/cache/ChatsCacheDataSource.kt b/data/src/main/java/org/monogram/data/datasource/cache/ChatsCacheDataSource.kt deleted file mode 100644 index 85ddb196..00000000 --- a/data/src/main/java/org/monogram/data/datasource/cache/ChatsCacheDataSource.kt +++ /dev/null @@ -1,25 +0,0 @@ -package org.monogram.data.datasource.cache - -import org.drinkless.tdlib.TdApi - -interface ChatsCacheDataSource { - fun getChat(chatId: Long): TdApi.Chat? - fun putChat(chat: TdApi.Chat) - fun getSupergroup(supergroupId: Long): TdApi.Supergroup? - fun putSupergroup(supergroup: TdApi.Supergroup) - fun getBasicGroup(basicGroupId: Long): TdApi.BasicGroup? - fun putBasicGroup(basicGroup: TdApi.BasicGroup) - fun getSupergroupFullInfo(supergroupId: Long): TdApi.SupergroupFullInfo? - fun putSupergroupFullInfo(supergroupId: Long, supergroupFullInfo: TdApi.SupergroupFullInfo) - fun getBasicGroupFullInfo(basicGroupId: Long): TdApi.BasicGroupFullInfo? - fun putBasicGroupFullInfo(basicGroupId: Long, basicGroupFullInfo: TdApi.BasicGroupFullInfo) - fun getChatPermissions(chatId: Long): TdApi.ChatPermissions? - fun putChatPermissions(chatId: Long, permissions: TdApi.ChatPermissions) - fun getMyChatMember(chatId: Long): TdApi.ChatMember? - fun putMyChatMember(chatId: Long, chatMember: TdApi.ChatMember) - fun getOnlineMemberCount(chatId: Long): Int? - fun putOnlineMemberCount(chatId: Long, count: Int) - fun getSecretChat(secretChatId: Long): TdApi.SecretChat? - fun putSecretChat(secretChat: TdApi.SecretChat) - fun clearAll() -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/cache/InMemoryChatLocalDataSource.kt b/data/src/main/java/org/monogram/data/datasource/cache/InMemoryChatLocalDataSource.kt deleted file mode 100644 index c591c47c..00000000 --- a/data/src/main/java/org/monogram/data/datasource/cache/InMemoryChatLocalDataSource.kt +++ /dev/null @@ -1,192 +0,0 @@ -package org.monogram.data.datasource.cache - -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.update -import org.monogram.data.db.model.ChatEntity -import org.monogram.data.db.model.ChatFullInfoEntity -import org.monogram.data.db.model.MessageEntity -import org.monogram.data.db.model.TopicEntity -import java.util.concurrent.ConcurrentHashMap - -class InMemoryChatLocalDataSource : ChatLocalDataSource { - private val chats = MutableStateFlow>(emptyMap()) - private val messages = ConcurrentHashMap>>() - private val fullInfos = ConcurrentHashMap() - private val topics = ConcurrentHashMap>>() - - override fun getAllChats(): Flow> = - chats.map { - it.values.sortedWith( - compareByDescending { chat -> chat.isPinned } - .thenByDescending { chat -> chat.order } - ) - } - - override suspend fun getChat(chatId: Long): ChatEntity? = chats.value[chatId] - - override suspend fun insertChat(chat: ChatEntity) { - chats.update { it + (chat.id to chat) } - } - - override suspend fun insertChats(chats: List) { - this.chats.update { it + chats.associateBy { chat -> chat.id } } - } - - override suspend fun deleteChat(chatId: Long) { - chats.update { it - chatId } - } - - override suspend fun clearAllChats() { - chats.value = emptyMap() - } - - override suspend fun clearAll() { - chats.value = emptyMap() - messages.clear() - fullInfos.clear() - topics.clear() - } - - override fun getMessagesForChat(chatId: Long): Flow> = - messages.getOrPut(chatId) { MutableStateFlow(emptyMap()) } - .map { it.values.sortedByDescending { msg -> msg.date } } - - override suspend fun getMessagesOlder(chatId: Long, fromMessageId: Long, limit: Int): List { - val chatMessages = messages[chatId]?.value?.values ?: return emptyList() - return chatMessages.filter { it.id < fromMessageId } - .sortedByDescending { it.date } - .take(limit) - } - - override suspend fun getMessagesNewer(chatId: Long, fromMessageId: Long, limit: Int): List { - val chatMessages = messages[chatId]?.value?.values ?: return emptyList() - return chatMessages.filter { it.id > fromMessageId } - .sortedBy { it.date } - .take(limit) - } - - override suspend fun getLatestMessages(chatId: Long, limit: Int): List { - val chatMessages = messages[chatId]?.value?.values ?: return emptyList() - return chatMessages.sortedByDescending { it.date }.take(limit) - } - - override suspend fun insertMessage(message: MessageEntity) { - messages.getOrPut(message.chatId) { MutableStateFlow(emptyMap()) } - .update { it + (message.id to message) } - } - - override suspend fun insertMessages(messages: List) { - messages.forEach { insertMessage(it) } - } - - override suspend fun markAsRead(chatId: Long, upToMessageId: Long) { - messages[chatId]?.update { current -> - current.mapValues { (_, msg) -> - if (msg.id <= upToMessageId && !msg.isRead) msg.copy(isRead = true) else msg - } - } - } - - override suspend fun updateMessageContent( - messageId: Long, - content: String, - contentType: String, - contentMeta: String?, - mediaFileId: Int, - mediaPath: String?, - editDate: Int - ) { - messages.values.forEach { flow -> - val current = flow.value[messageId] ?: return@forEach - flow.update { - it + (messageId to current.copy( - content = content, - contentType = contentType, - contentMeta = contentMeta, - mediaFileId = mediaFileId, - mediaPath = mediaPath, - editDate = editDate - )) - } - } - } - - override suspend fun updateMediaPath(fileId: Int, path: String) { - messages.values.forEach { flow -> - flow.update { current -> - current.mapValues { (_, message) -> - if (message.mediaFileId == fileId) { - message.copy(mediaPath = path) - } else { - message - } - } - } - } - } - - override suspend fun updateInteractionInfo(messageId: Long, viewCount: Int, forwardCount: Int, replyCount: Int) { - messages.values.forEach { flow -> - val current = flow.value[messageId] ?: return@forEach - flow.update { - it + (messageId to current.copy(viewCount = viewCount, forwardCount = forwardCount, replyCount = replyCount)) - } - } - } - - override suspend fun deleteMessage(messageId: Long) { - messages.values.forEach { flow -> - if (flow.value.containsKey(messageId)) { - flow.update { it - messageId } - } - } - } - - override suspend fun clearMessagesForChat(chatId: Long) { - messages[chatId]?.value = emptyMap() - } - - override suspend fun getChatFullInfo(chatId: Long): ChatFullInfoEntity? = fullInfos[chatId] - - override suspend fun insertChatFullInfo(info: ChatFullInfoEntity) { - fullInfos[info.chatId] = info - } - - override suspend fun deleteChatFullInfo(chatId: Long) { - fullInfos.remove(chatId) - } - - override fun getTopicsForChat(chatId: Long): Flow> = - topics.getOrPut(chatId) { MutableStateFlow(emptyMap()) } - .map { it.values.sortedByDescending { topic -> topic.order } } - - override suspend fun insertTopic(topic: TopicEntity) { - topics.getOrPut(topic.chatId) { MutableStateFlow(emptyMap()) } - .update { it + (topic.id to topic) } - } - - override suspend fun insertTopics(topics: List) { - topics.forEach { insertTopic(it) } - } - - override suspend fun deleteTopic(chatId: Long, topicId: Int) { - topics[chatId]?.update { it - topicId } - } - - override suspend fun clearTopicsForChat(chatId: Long) { - topics[chatId]?.value = emptyMap() - } - - override suspend fun deleteExpired(timestamp: Long) { - chats.update { it.filterValues { chat -> chat.createdAt >= timestamp } } - messages.values.forEach { flow -> - flow.update { it.filterValues { msg -> msg.createdAt >= timestamp } } - } - fullInfos.values.removeIf { it.createdAt < timestamp } - topics.values.forEach { flow -> - flow.update { it.filterValues { topic -> topic.createdAt >= timestamp } } - } - } -} diff --git a/data/src/main/java/org/monogram/data/datasource/cache/InMemoryChatsCacheDataSource.kt b/data/src/main/java/org/monogram/data/datasource/cache/InMemoryChatsCacheDataSource.kt deleted file mode 100644 index a29ff50d..00000000 --- a/data/src/main/java/org/monogram/data/datasource/cache/InMemoryChatsCacheDataSource.kt +++ /dev/null @@ -1,54 +0,0 @@ -package org.monogram.data.datasource.cache - -import org.drinkless.tdlib.TdApi -import java.util.concurrent.ConcurrentHashMap - -class InMemoryChatsCacheDataSource : ChatsCacheDataSource { - private val cache = ConcurrentHashMap() - - private inline fun get(key: String): T? = cache[key] as? T - - private fun put(key: String, value: Any) { - cache[key] = value - } - - override fun getChat(chatId: Long): TdApi.Chat? = get("chat_$chatId") - - override fun putChat(chat: TdApi.Chat) = put("chat_${chat.id}", chat) - - override fun getSupergroup(supergroupId: Long): TdApi.Supergroup? = get("supergroup_$supergroupId") - - override fun putSupergroup(supergroup: TdApi.Supergroup) = put("supergroup_${supergroup.id}", supergroup) - - override fun getBasicGroup(basicGroupId: Long): TdApi.BasicGroup? = get("basicGroup_$basicGroupId") - - override fun putBasicGroup(basicGroup: TdApi.BasicGroup) = put("basicGroup_${basicGroup.id}", basicGroup) - - override fun getSupergroupFullInfo(supergroupId: Long): TdApi.SupergroupFullInfo? = get("supergroupFullInfo_$supergroupId") - - override fun putSupergroupFullInfo(supergroupId: Long, supergroupFullInfo: TdApi.SupergroupFullInfo) = put("supergroupFullInfo_$supergroupId", supergroupFullInfo) - - override fun getBasicGroupFullInfo(basicGroupId: Long): TdApi.BasicGroupFullInfo? = get("basicGroupFullInfo_$basicGroupId") - - override fun putBasicGroupFullInfo(basicGroupId: Long, basicGroupFullInfo: TdApi.BasicGroupFullInfo) = put("basicGroupFullInfo_$basicGroupId", basicGroupFullInfo) - - override fun getChatPermissions(chatId: Long): TdApi.ChatPermissions? = get("chatPermissions_$chatId") - - override fun putChatPermissions(chatId: Long, permissions: TdApi.ChatPermissions) = put("chatPermissions_$chatId", permissions) - - override fun getMyChatMember(chatId: Long): TdApi.ChatMember? = get("myChatMember_$chatId") - - override fun putMyChatMember(chatId: Long, chatMember: TdApi.ChatMember) = put("myChatMember_$chatId", chatMember) - - override fun getOnlineMemberCount(chatId: Long): Int? = get("onlineMemberCount_$chatId") - - override fun putOnlineMemberCount(chatId: Long, count: Int) = put("onlineMemberCount_$chatId", count) - - override fun getSecretChat(secretChatId: Long): TdApi.SecretChat? = get("secretChat_$secretChatId") - - override fun putSecretChat(secretChat: TdApi.SecretChat) = put("secretChat_${secretChat.id.toLong()}", secretChat) - - override fun clearAll() { - cache.clear() - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/cache/InMemorySettingsCacheDataSource.kt b/data/src/main/java/org/monogram/data/datasource/cache/InMemorySettingsCacheDataSource.kt deleted file mode 100644 index ee6184cd..00000000 --- a/data/src/main/java/org/monogram/data/datasource/cache/InMemorySettingsCacheDataSource.kt +++ /dev/null @@ -1,30 +0,0 @@ -package org.monogram.data.datasource.cache - -import org.drinkless.tdlib.TdApi -import java.util.concurrent.ConcurrentHashMap - -class InMemorySettingsCacheDataSource : SettingsCacheDataSource { - private val cache = ConcurrentHashMap() - - private inline fun get(key: String): T? = cache[key] as? T - - private fun put(key: String, value: Any) { - cache[key] = value - } - - override fun getChat(chatId: Long): TdApi.Chat? = get("chat_$chatId") - - override fun putChat(chat: TdApi.Chat) { - put("chat_${chat.id}", chat) - } - - override fun getAttachMenuBots(): List? = get("attachMenuBots") - - override fun putAttachMenuBots(bots: Array) { - put("attachMenuBots", bots.toList()) - } - - override fun clearAll() { - cache.clear() - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/cache/InMemoryUserCacheDataSource.kt b/data/src/main/java/org/monogram/data/datasource/cache/InMemoryUserCacheDataSource.kt deleted file mode 100644 index fceb7133..00000000 --- a/data/src/main/java/org/monogram/data/datasource/cache/InMemoryUserCacheDataSource.kt +++ /dev/null @@ -1,70 +0,0 @@ -package org.monogram.data.datasource.cache - -import org.drinkless.tdlib.TdApi -import java.util.concurrent.ConcurrentHashMap - -class InMemoryUserCacheDataSource : UserCacheDataSource { - private val userCache = ConcurrentHashMap() - private val userFullInfoCache = ConcurrentHashMap() - private val supergroupFullInfoCache = ConcurrentHashMap() - private val basicGroupFullInfoCache = ConcurrentHashMap() - private val supergroupCache = ConcurrentHashMap() - private val chatCache = ConcurrentHashMap() - private val messageCache = ConcurrentHashMap, TdApi.Message>() - - override fun getUser(userId: Long): TdApi.User? = userCache[userId] - - override fun putUser(user: TdApi.User) { - userCache[user.id] = user - } - - override fun getUserFullInfo(userId: Long): TdApi.UserFullInfo? = userFullInfoCache[userId] - - override fun putUserFullInfo(userId: Long, userFullInfo: TdApi.UserFullInfo) { - userFullInfoCache[userId] = userFullInfo - } - - override fun getSupergroupFullInfo(supergroupId: Long): TdApi.SupergroupFullInfo? = supergroupFullInfoCache[supergroupId] - - override fun putSupergroupFullInfo(supergroupId: Long, supergroupFullInfo: TdApi.SupergroupFullInfo) { - supergroupFullInfoCache[supergroupId] = supergroupFullInfo - } - - override fun getBasicGroupFullInfo(basicGroupId: Long): TdApi.BasicGroupFullInfo? = basicGroupFullInfoCache[basicGroupId] - - override fun putBasicGroupFullInfo(basicGroupId: Long, basicGroupFullInfo: TdApi.BasicGroupFullInfo) { - basicGroupFullInfoCache[basicGroupId] = basicGroupFullInfo - } - - override fun getSupergroup(supergroupId: Long): TdApi.Supergroup? = supergroupCache[supergroupId] - - override fun putSupergroup(supergroup: TdApi.Supergroup) { - supergroupCache[supergroup.id] = supergroup - } - - override fun getChat(chatId: Long): TdApi.Chat? = chatCache[chatId] - - override fun putChat(chat: TdApi.Chat) { - chatCache[chat.id] = chat - } - - override fun getMessage(chatId: Long, messageId: Long): TdApi.Message? = messageCache[chatId to messageId] - - override fun putMessage(message: TdApi.Message) { - messageCache[message.chatId to message.id] = message - } - - override fun removeMessage(chatId: Long, messageId: Long) { - messageCache.remove(chatId to messageId) - } - - override fun clearAll() { - userCache.clear() - userFullInfoCache.clear() - supergroupFullInfoCache.clear() - basicGroupFullInfoCache.clear() - supergroupCache.clear() - chatCache.clear() - messageCache.clear() - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/cache/InMemoryUserLocalDataSource.kt b/data/src/main/java/org/monogram/data/datasource/cache/InMemoryUserLocalDataSource.kt deleted file mode 100644 index e201eb3f..00000000 --- a/data/src/main/java/org/monogram/data/datasource/cache/InMemoryUserLocalDataSource.kt +++ /dev/null @@ -1,41 +0,0 @@ -package org.monogram.data.datasource.cache - -import org.drinkless.tdlib.TdApi -import org.monogram.data.db.model.UserFullInfoEntity -import java.util.concurrent.ConcurrentHashMap - -class InMemoryUserLocalDataSource : UserLocalDataSource { - private val users = ConcurrentHashMap() - private val fullInfos = ConcurrentHashMap() - private val fullInfoEntities = ConcurrentHashMap() - - override suspend fun getUser(userId: Long): TdApi.User? = users[userId] - - override suspend fun putUser(user: TdApi.User) { - users[user.id] = user - } - - override suspend fun getUserFullInfo(userId: Long): TdApi.UserFullInfo? = fullInfos[userId] - - override suspend fun putUserFullInfo(userId: Long, info: TdApi.UserFullInfo) { - fullInfos[userId] = info - } - - override suspend fun getAllUsers(): Collection = users.values - - override suspend fun clearAll() { - users.clear() - fullInfos.clear() - fullInfoEntities.clear() - } - - override suspend fun getFullInfoEntity(userId: Long): UserFullInfoEntity? = fullInfoEntities[userId] - - override suspend fun saveFullInfoEntity(info: UserFullInfoEntity) { - fullInfoEntities[info.userId] = info - } - - override suspend fun deleteExpired(timestamp: Long) { - fullInfoEntities.values.removeIf { it.createdAt < timestamp } - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/cache/RoomChatLocalDataSource.kt b/data/src/main/java/org/monogram/data/datasource/cache/RoomChatLocalDataSource.kt deleted file mode 100644 index 8f810893..00000000 --- a/data/src/main/java/org/monogram/data/datasource/cache/RoomChatLocalDataSource.kt +++ /dev/null @@ -1,100 +0,0 @@ -package org.monogram.data.datasource.cache - -import androidx.room.withTransaction -import kotlinx.coroutines.flow.Flow -import org.monogram.data.db.MonogramDatabase -import org.monogram.data.db.dao.ChatDao -import org.monogram.data.db.dao.ChatFullInfoDao -import org.monogram.data.db.dao.MessageDao -import org.monogram.data.db.dao.TopicDao -import org.monogram.data.db.model.ChatEntity -import org.monogram.data.db.model.ChatFullInfoEntity -import org.monogram.data.db.model.MessageEntity -import org.monogram.data.db.model.TopicEntity - -class RoomChatLocalDataSource( - private val database: MonogramDatabase, - private val chatDao: ChatDao, - private val messageDao: MessageDao, - private val chatFullInfoDao: ChatFullInfoDao, - private val topicDao: TopicDao -) : ChatLocalDataSource { - override fun getAllChats(): Flow> = chatDao.getAllChats() - - override suspend fun getChat(chatId: Long): ChatEntity? = chatDao.getChat(chatId) - - override suspend fun insertChat(chat: ChatEntity) = chatDao.insertChat(chat) - - override suspend fun insertChats(chats: List) = chatDao.insertChats(chats) - - override suspend fun deleteChat(chatId: Long) = chatDao.deleteChat(chatId) - - override suspend fun clearAllChats() = chatDao.clearAll() - - override suspend fun clearAll() { - database.withTransaction { - chatDao.clearAll() - messageDao.clearAll() - chatFullInfoDao.clearAll() - topicDao.clearAll() - } - } - - override fun getMessagesForChat(chatId: Long): Flow> = messageDao.getMessagesForChat(chatId) - - override suspend fun getMessagesOlder(chatId: Long, fromMessageId: Long, limit: Int) = messageDao.getMessagesOlder(chatId, fromMessageId, limit) - - override suspend fun getMessagesNewer(chatId: Long, fromMessageId: Long, limit: Int) = messageDao.getMessagesNewer(chatId, fromMessageId, limit) - - override suspend fun getLatestMessages(chatId: Long, limit: Int) = messageDao.getLatestMessages(chatId, limit) - - override suspend fun insertMessage(message: MessageEntity) = messageDao.insertMessage(message) - - override suspend fun insertMessages(messages: List) = messageDao.insertMessages(messages) - - override suspend fun markAsRead(chatId: Long, upToMessageId: Long) = messageDao.markAsRead(chatId, upToMessageId) - - override suspend fun updateMessageContent( - messageId: Long, - content: String, - contentType: String, - contentMeta: String?, - mediaFileId: Int, - mediaPath: String?, - editDate: Int - ) = messageDao.updateContent(messageId, content, contentType, contentMeta, mediaFileId, mediaPath, editDate) - - override suspend fun updateMediaPath(fileId: Int, path: String) = messageDao.updateMediaPath(fileId, path) - - override suspend fun updateInteractionInfo(messageId: Long, viewCount: Int, forwardCount: Int, replyCount: Int) = - messageDao.updateInteractionInfo(messageId, viewCount, forwardCount, replyCount) - - override suspend fun deleteMessage(messageId: Long) = messageDao.deleteMessage(messageId) - - override suspend fun clearMessagesForChat(chatId: Long) = messageDao.clearMessagesForChat(chatId) - - override suspend fun getChatFullInfo(chatId: Long): ChatFullInfoEntity? = chatFullInfoDao.getChatFullInfo(chatId) - - override suspend fun insertChatFullInfo(info: ChatFullInfoEntity) = chatFullInfoDao.insertChatFullInfo(info) - - override suspend fun deleteChatFullInfo(chatId: Long) = chatFullInfoDao.deleteChatFullInfo(chatId) - - override fun getTopicsForChat(chatId: Long): Flow> = topicDao.getTopicsForChat(chatId) - - override suspend fun insertTopic(topic: TopicEntity) = topicDao.insertTopic(topic) - - override suspend fun insertTopics(topics: List) = topicDao.insertTopics(topics) - - override suspend fun deleteTopic(chatId: Long, topicId: Int) = topicDao.deleteTopic(chatId, topicId) - - override suspend fun clearTopicsForChat(chatId: Long) = topicDao.clearTopicsForChat(chatId) - - override suspend fun deleteExpired(timestamp: Long) { - database.withTransaction { - chatDao.deleteExpired(timestamp) - messageDao.deleteExpired(timestamp) - chatFullInfoDao.deleteExpired(timestamp) - topicDao.deleteExpired(timestamp) - } - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/cache/RoomUserLocalDataSource.kt b/data/src/main/java/org/monogram/data/datasource/cache/RoomUserLocalDataSource.kt deleted file mode 100644 index bfea263a..00000000 --- a/data/src/main/java/org/monogram/data/datasource/cache/RoomUserLocalDataSource.kt +++ /dev/null @@ -1,143 +0,0 @@ -package org.monogram.data.datasource.cache - -import org.drinkless.tdlib.TdApi -import org.monogram.data.db.dao.UserDao -import org.monogram.data.db.dao.UserFullInfoDao -import org.monogram.data.db.model.UserEntity -import org.monogram.data.db.model.UserFullInfoEntity -import org.monogram.data.mapper.user.toEntity -import org.monogram.data.mapper.user.toTdApi -import java.util.concurrent.ConcurrentHashMap - -class RoomUserLocalDataSource( - private val userDao: UserDao, - private val userFullInfoDao: UserFullInfoDao -) : UserLocalDataSource { - private val fullInfos = ConcurrentHashMap() - private val users = ConcurrentHashMap() - - override suspend fun getUser(userId: Long): TdApi.User? { - users[userId]?.let { return it } - val dbUser = userDao.getUser(userId)?.toTdApi() ?: return null - users[userId] = dbUser - return dbUser - } - - override suspend fun putUser(user: TdApi.User) { - users[user.id] = user - val personalAvatarPath = fullInfos[user.id]?.extractPersonalAvatarPath() - ?: userFullInfoDao.getUserFullInfo(user.id)?.personalPhotoPath?.ifBlank { null } - userDao.insertUser(user.toEntity(personalAvatarPath)) - } - - override suspend fun getUserFullInfo(userId: Long): TdApi.UserFullInfo? { - fullInfos[userId]?.let { return it } - val dbInfo = userFullInfoDao.getUserFullInfo(userId)?.toTdApi() ?: return null - fullInfos[userId] = dbInfo - return dbInfo - } - - override suspend fun putUserFullInfo(userId: Long, info: TdApi.UserFullInfo) { - fullInfos[userId] = info - userFullInfoDao.insertUserFullInfo(info.toEntity(userId)) - val personalAvatarPath = info.extractPersonalAvatarPath() - if (!personalAvatarPath.isNullOrBlank()) { - userDao.getUser(userId)?.let { existing -> - if (existing.personalAvatarPath != personalAvatarPath) { - userDao.insertUser(existing.copy(personalAvatarPath = personalAvatarPath)) - } - } - } - } - - override suspend fun getAllUsers(): Collection { - val dbUsers = userDao.getAllUsers().map { it.toTdApi() } - dbUsers.forEach { users[it.id] = it } - return users.values - } - - override suspend fun clearAll() { - fullInfos.clear() - users.clear() - } - - override suspend fun getFullInfoEntity(userId: Long): UserFullInfoEntity? = userFullInfoDao.getUserFullInfo(userId) - - override suspend fun saveFullInfoEntity(info: UserFullInfoEntity) = userFullInfoDao.insertUserFullInfo(info) - - override suspend fun deleteExpired(timestamp: Long) { - userDao.deleteExpired(timestamp) - userFullInfoDao.deleteExpired(timestamp) - } - - suspend fun saveUser(user: UserEntity) = userDao.insertUser(user) - suspend fun loadUser(userId: Long): UserEntity? { - val entity = userDao.getUser(userId) - entity?.let { users[it.id] = it.toTdApi() } - return entity - } - suspend fun deleteUser(userId: Long) = userDao.deleteUser(userId) - suspend fun clearDatabase() { - userDao.clearAll() - userFullInfoDao.clearAll() - } - - private fun TdApi.User.toEntity(personalAvatarPath: String?): UserEntity { - val usernamesData = buildString { - append(usernames?.activeUsernames?.joinToString("|").orEmpty()) - append('\n') - append(usernames?.disabledUsernames?.joinToString("|").orEmpty()) - append('\n') - append(usernames?.editableUsername.orEmpty()) - append('\n') - append(usernames?.collectibleUsernames?.joinToString("|").orEmpty()) - } - - val statusType = when (status) { - is TdApi.UserStatusOnline -> "ONLINE" - is TdApi.UserStatusRecently -> "RECENTLY" - is TdApi.UserStatusLastWeek -> "LAST_WEEK" - is TdApi.UserStatusLastMonth -> "LAST_MONTH" - else -> "OFFLINE" - } - - val statusEmojiId = when (val type = emojiStatus?.type) { - is TdApi.EmojiStatusTypeCustomEmoji -> type.customEmojiId - is TdApi.EmojiStatusTypeUpgradedGift -> type.modelCustomEmojiId - else -> 0L - } - - return UserEntity( - id = id, - firstName = firstName, - lastName = lastName.ifEmpty { null }, - phoneNumber = phoneNumber.ifEmpty { null }, - avatarPath = profilePhoto?.big?.local?.path?.ifEmpty { null } - ?: profilePhoto?.small?.local?.path?.ifEmpty { null }, - personalAvatarPath = personalAvatarPath, - isPremium = isPremium, - isVerified = verificationStatus?.isVerified ?: false, - isSupport = isSupport, - isContact = isContact, - isMutualContact = isMutualContact, - isCloseFriend = isCloseFriend, - haveAccess = haveAccess, - username = usernames?.activeUsernames?.firstOrNull(), - usernamesData = usernamesData, - statusType = statusType, - accentColorId = accentColorId, - profileAccentColorId = profileAccentColorId, - statusEmojiId = statusEmojiId, - languageCode = languageCode.ifEmpty { null }, - lastSeen = (status as? TdApi.UserStatusOffline)?.wasOnline?.toLong() ?: 0L, - createdAt = System.currentTimeMillis() - ) - } - - private fun TdApi.UserFullInfo.extractPersonalAvatarPath(): String? { - val bestPhotoSize = personalPhoto?.sizes?.maxByOrNull { it.width.toLong() * it.height.toLong() } - ?: personalPhoto?.sizes?.lastOrNull() - return personalPhoto?.animation?.file?.local?.path?.ifEmpty { null } - ?: bestPhotoSize?.photo?.local?.path?.ifEmpty { null } - } -} diff --git a/data/src/main/java/org/monogram/data/datasource/cache/SettingsCacheDataSource.kt b/data/src/main/java/org/monogram/data/datasource/cache/SettingsCacheDataSource.kt deleted file mode 100644 index 879f9e9c..00000000 --- a/data/src/main/java/org/monogram/data/datasource/cache/SettingsCacheDataSource.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.monogram.data.datasource.cache - -import org.drinkless.tdlib.TdApi - -interface SettingsCacheDataSource { - fun getChat(chatId: Long): TdApi.Chat? - fun putChat(chat: TdApi.Chat) - fun getAttachMenuBots(): List? - fun putAttachMenuBots(bots: Array) - fun clearAll() -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/cache/UserCacheDataSource.kt b/data/src/main/java/org/monogram/data/datasource/cache/UserCacheDataSource.kt deleted file mode 100644 index ec730bea..00000000 --- a/data/src/main/java/org/monogram/data/datasource/cache/UserCacheDataSource.kt +++ /dev/null @@ -1,29 +0,0 @@ -package org.monogram.data.datasource.cache - -import org.drinkless.tdlib.TdApi - -interface UserCacheDataSource { - fun getUser(userId: Long): TdApi.User? - fun putUser(user: TdApi.User) - - fun getUserFullInfo(userId: Long): TdApi.UserFullInfo? - fun putUserFullInfo(userId: Long, userFullInfo: TdApi.UserFullInfo) - - fun getSupergroupFullInfo(supergroupId: Long): TdApi.SupergroupFullInfo? - fun putSupergroupFullInfo(supergroupId: Long, supergroupFullInfo: TdApi.SupergroupFullInfo) - - fun getBasicGroupFullInfo(basicGroupId: Long): TdApi.BasicGroupFullInfo? - fun putBasicGroupFullInfo(basicGroupId: Long, basicGroupFullInfo: TdApi.BasicGroupFullInfo) - - fun getSupergroup(supergroupId: Long): TdApi.Supergroup? - fun putSupergroup(supergroup: TdApi.Supergroup) - - fun getChat(chatId: Long): TdApi.Chat? - fun putChat(chat: TdApi.Chat) - - fun getMessage(chatId: Long, messageId: Long): TdApi.Message? - fun putMessage(message: TdApi.Message) - fun removeMessage(chatId: Long, messageId: Long) - - fun clearAll() -} diff --git a/data/src/main/java/org/monogram/data/datasource/cache/UserLocalDataSource.kt b/data/src/main/java/org/monogram/data/datasource/cache/UserLocalDataSource.kt deleted file mode 100644 index f95dc07e..00000000 --- a/data/src/main/java/org/monogram/data/datasource/cache/UserLocalDataSource.kt +++ /dev/null @@ -1,17 +0,0 @@ -package org.monogram.data.datasource.cache - -import org.drinkless.tdlib.TdApi -import org.monogram.data.db.model.UserFullInfoEntity - -interface UserLocalDataSource { - suspend fun getUser(userId: Long): TdApi.User? - suspend fun putUser(user: TdApi.User) - suspend fun getUserFullInfo(userId: Long): TdApi.UserFullInfo? - suspend fun putUserFullInfo(userId: Long, info: TdApi.UserFullInfo) - suspend fun getAllUsers(): Collection - suspend fun clearAll() - - suspend fun getFullInfoEntity(userId: Long): UserFullInfoEntity? - suspend fun saveFullInfoEntity(info: UserFullInfoEntity) - suspend fun deleteExpired(timestamp: Long) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/remote/AuthRemoteDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/AuthRemoteDataSource.kt deleted file mode 100644 index bcb6c7c4..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/AuthRemoteDataSource.kt +++ /dev/null @@ -1,13 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.drinkless.tdlib.TdApi - -interface AuthRemoteDataSource { - suspend fun setTdlibParameters(parameters: TdApi.SetTdlibParameters) - suspend fun setPhoneNumber(phone: String) - suspend fun resendCode() - suspend fun setAuthCode(code: String) - suspend fun checkEmailCode(code: String) - suspend fun checkPassword(password: String) - suspend fun logout() -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/remote/ChatRemoteSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/ChatRemoteSource.kt deleted file mode 100644 index 61e63423..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/ChatRemoteSource.kt +++ /dev/null @@ -1,43 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.drinkless.tdlib.TdApi -import org.monogram.domain.models.ChatPermissionsModel - -interface ChatRemoteSource { - suspend fun loadChats(chatList: TdApi.ChatList, limit: Int) - suspend fun searchChats(query: String, limit: Int): TdApi.Chats? - suspend fun searchPublicChats(query: String): TdApi.Chats? - suspend fun searchMessages(query: String, offset: String, limit: Int): TdApi.FoundMessages? - suspend fun getChat(chatId: Long): TdApi.Chat? - suspend fun createGroup(title: String, userIds: List, messageAutoDeleteTime: Int): Long - suspend fun createChannel(title: String, description: String, isMegagroup: Boolean, messageAutoDeleteTime: Int): Long - suspend fun setChatPhoto(chatId: Long, photoPath: String) - suspend fun setChatTitle(chatId: Long, title: String) - suspend fun setChatDescription(chatId: Long, description: String) - suspend fun setChatUsername(chatId: Long, username: String) - suspend fun setChatPermissions(chatId: Long, permissions: ChatPermissionsModel) - suspend fun setChatSlowModeDelay(chatId: Long, slowModeDelay: Int) - suspend fun toggleChatIsForum(chatId: Long, isForum: Boolean) - suspend fun toggleChatIsTranslatable(chatId: Long, isTranslatable: Boolean) - suspend fun getChatLink(chatId: Long): String? - suspend fun deleteFolder(folderId: Int) - suspend fun muteChat(chatId: Long, muteFor: Int) - suspend fun archiveChat(chatId: Long, archive: Boolean) - suspend fun toggleChatIsPinned(chatList: TdApi.ChatList, chatId: Long, isPinned: Boolean) - suspend fun toggleChatIsMarkedAsUnread(chatId: Long, isMarkedAsUnread: Boolean) - suspend fun deleteChat(chatId: Long) - suspend fun leaveChat(chatId: Long) - suspend fun clearChatHistory(chatId: Long, revoke: Boolean) - suspend fun reportChat(chatId: Long, reason: String, messageIds: List) - suspend fun getMyUserId(): Long - suspend fun setNetworkType(): Boolean - suspend fun getConnectionState(): TdApi.ConnectionState? - suspend fun getForumTopics( - chatId: Long, - query: String, - offsetDate: Int, - offsetMessageId: Long, - offsetForumTopicId: Int, - limit: Int - ): TdApi.ForumTopics? -} diff --git a/data/src/main/java/org/monogram/data/datasource/remote/ChatsRemoteDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/ChatsRemoteDataSource.kt deleted file mode 100644 index 2aa4127c..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/ChatsRemoteDataSource.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.drinkless.tdlib.TdApi - -interface ChatsRemoteDataSource { - suspend fun getChat(chatId: Long): TdApi.Chat? - suspend fun searchChats(query: String, limit: Int): TdApi.Chats? - suspend fun searchPublicChats(query: String): TdApi.Chats? - suspend fun getChatNotificationSettingsExceptions(scope: TdApi.NotificationSettingsScope, compareSound: Boolean): TdApi.Chats? - suspend fun getForumTopics(chatId: Long, query: String, offsetDate: Int, offsetMessageId: Long, offsetForumTopicId: Int, limit: Int): TdApi.ForumTopics? -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/remote/ExternalProxyDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/ExternalProxyDataSource.kt deleted file mode 100644 index c8de2a0e..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/ExternalProxyDataSource.kt +++ /dev/null @@ -1,5 +0,0 @@ -package org.monogram.data.datasource.remote - -interface ExternalProxyDataSource { - suspend fun fetchProxyUrls(): List -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/remote/HttpExternalProxyDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/HttpExternalProxyDataSource.kt deleted file mode 100644 index 060e8896..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/HttpExternalProxyDataSource.kt +++ /dev/null @@ -1,55 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.monogram.core.DispatcherProvider -import kotlinx.coroutines.withContext -import kotlinx.serialization.InternalSerializationApi -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.Json -import java.net.HttpURLConnection -import java.net.URL -import java.util.zip.GZIPInputStream - -class HttpExternalProxyDataSource( - private val dispatchers: DispatcherProvider -) : ExternalProxyDataSource { - - private val json = Json { - ignoreUnknownKeys = true - coerceInputValues = true - isLenient = true - } - - @OptIn(InternalSerializationApi::class) - override suspend fun fetchProxyUrls(): List = withContext(dispatchers.io) { - var connection: HttpURLConnection? = null - try { - val url = URL("https://api.telega.info/v1/auth/proxy") - connection = (url.openConnection() as HttpURLConnection).apply { - requestMethod = "GET" - connectTimeout = 15_000 - readTimeout = 15_000 - instanceFollowRedirects = true - setRequestProperty("User-Agent", "DAHL-Mobile-App") - setRequestProperty("Accept", "application/json") - setRequestProperty("Accept-Encoding", "gzip") - } - - if (connection.responseCode != HttpURLConnection.HTTP_OK) return@withContext emptyList() - - val stream = if ("gzip".equals(connection.contentEncoding, ignoreCase = true)) { - GZIPInputStream(connection.inputStream) - } else { - connection.inputStream - } - - json.decodeFromString(stream.bufferedReader().use { it.readText() }).proxies - } catch (e: Exception) { - emptyList() - } finally { - connection?.disconnect() - } - } -} -@Serializable -@InternalSerializationApi -private data class ProxyResponse(val proxies: List = emptyList()) \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/remote/MessageFileApi.kt b/data/src/main/java/org/monogram/data/datasource/remote/MessageFileApi.kt deleted file mode 100644 index 2f7d000c..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/MessageFileApi.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.monogram.data.datasource.remote - -interface MessageFileApi { - fun registerFileForMessage(fileId: Int, chatId: Long, messageId: Long) - fun enqueueDownload( - fileId: Int, - priority: Int = 1, - type: TdMessageRemoteDataSource.DownloadType = TdMessageRemoteDataSource.DownloadType.DEFAULT, - offset: Long = 0, - limit: Long = 0, - synchronous: Boolean = false - ) - fun isFileQueued(fileId: Int): Boolean -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/remote/MessageFileCoordinator.kt b/data/src/main/java/org/monogram/data/datasource/remote/MessageFileCoordinator.kt deleted file mode 100644 index c4f6f403..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/MessageFileCoordinator.kt +++ /dev/null @@ -1,35 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.monogram.data.infra.FileDownloadQueue -import org.monogram.data.mapper.toDomain - -class MessageFileCoordinator( - private val fileDownloadQueue: FileDownloadQueue -) : MessageFileApi { - - override fun registerFileForMessage(fileId: Int, chatId: Long, messageId: Long) { - fileDownloadQueue.registry.register(fileId, chatId, messageId) - } - - override fun enqueueDownload( - fileId: Int, - priority: Int, - type: TdMessageRemoteDataSource.DownloadType, - offset: Long, - limit: Long, - synchronous: Boolean - ) { - fileDownloadQueue.enqueue( - fileId = fileId, - priority = priority, - type = type.toDomain(), - offset = offset, - limit = limit, - synchronous = synchronous - ) - } - - override fun isFileQueued(fileId: Int): Boolean { - return fileDownloadQueue.isFileQueued(fileId) - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/remote/MessageRemoteDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/MessageRemoteDataSource.kt deleted file mode 100644 index 74100ccf..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/MessageRemoteDataSource.kt +++ /dev/null @@ -1,181 +0,0 @@ -package org.monogram.data.datasource.remote - -import kotlinx.coroutines.flow.Flow -import org.drinkless.tdlib.TdApi -import org.monogram.data.datasource.remote.TdMessageRemoteDataSource.DownloadType -import org.monogram.domain.models.* -import org.monogram.domain.models.webapp.ThemeParams -import org.monogram.domain.models.webapp.WebAppInfoModel -import org.monogram.domain.repository.OlderMessagesPage -import org.monogram.domain.repository.ReadUpdate -import org.monogram.domain.repository.SearchChatMessagesResult - -interface MessageRemoteDataSource { - val newMessageFlow: Flow - val messageEditedFlow: Flow - val messageReadFlow: Flow - val messageUploadProgressFlow: Flow> - val messageDownloadProgressFlow: Flow> - val messageDownloadCancelledFlow: Flow - val messageDeletedFlow: Flow>> - val messageIdUpdateFlow: Flow> - val messageDownloadCompletedFlow: Flow> - val pinnedMessageFlow: Flow - val mediaUpdateFlow: Flow - fun registerFileForMessage(fileId: Int, chatId: Long, messageId: Long) - fun isFileQueued(fileId: Int): Boolean - suspend fun handleUpdate(update: TdApi.Update) - fun setChatOpened(chatId: Long) - fun setChatClosed(chatId: Long) - fun enqueueDownload(fileId: Int, priority: Int = 1, type: DownloadType = DownloadType.DEFAULT, offset: Long = 0, limit: Long = 0, synchronous: Boolean = false) - suspend fun forwardMessage(toChatId: Long, fromChatId: Long, messageId: Long) - suspend fun getMessage(chatId: Long, messageId: Long): TdApi.Message? - suspend fun getMessages(chatId: Long, fromMessageId: Long, offset: Int, limit: Int, threadId: Long?): TdApi.Messages? - suspend fun getChatHistory(chatId: Long, fromMessageId: Long, offset: Int, limit: Int): TdApi.Messages? - suspend fun searchChatMessages(chatId: Long, query: String, fromMessageId: Long, limit: Int, filter: TdApi.SearchMessagesFilter, threadId: Long?): TdApi.FoundChatMessages? - suspend fun getChatPinnedMessage(chatId: Long): TdApi.Message? - suspend fun getPollVoters(chatId: Long, messageId: Long, optionId: Int, offset: Int, limit: Int): TdApi.PollVoters? - suspend fun getMessageViewers(chatId: Long, messageId: Long): TdApi.MessageViewers? - suspend fun sendMessage( - chatId: Long, - text: String, - replyToMsgId: Long?, - entities: List, - threadId: Long?, - sendOptions: MessageSendOptions - ): TdApi.Message? - - suspend fun sendPhoto( - chatId: Long, - photoPath: String, - caption: String, - captionEntities: List, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ): TdApi.Message? - - suspend fun sendVideo( - chatId: Long, - videoPath: String, - caption: String, - captionEntities: List, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ): TdApi.Message? - - suspend fun sendDocument( - chatId: Long, - documentPath: String, - caption: String, - captionEntities: List, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ): TdApi.Message? - - suspend fun sendSticker(chatId: Long, stickerPath: String, replyToMsgId: Long?, threadId: Long?): TdApi.Message? - suspend fun sendGif( - chatId: Long, - gifId: String, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ): TdApi.Message? - - suspend fun sendGifFile( - chatId: Long, - gifPath: String, - caption: String, - captionEntities: List, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ): TdApi.Message? - - suspend fun sendAlbum( - chatId: Long, - paths: List, - caption: String, - captionEntities: List, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ): TdApi.Messages? - suspend fun sendVideoNote(chatId: Long, videoPath: String, duration: Int, length: Int): TdApi.Message? - suspend fun sendVoiceNote(chatId: Long, voicePath: String, duration: Int, waveform: ByteArray): TdApi.Message? - suspend fun forwardMessages(toChatId: Long, fromChatId: Long, messageIds: LongArray, removeCaption: Boolean, sendCopy: Boolean): TdApi.Messages? - suspend fun deleteMessages(chatId: Long, messageIds: LongArray, revoke: Boolean): TdApi.Ok? - suspend fun editMessageText(chatId: Long, messageId: Long, text: String, entities: List): TdApi.Message? - suspend fun viewMessages(chatId: Long, messageIds: LongArray, forceRead: Boolean): TdApi.Ok? - suspend fun readAllChatMentions(chatId: Long): TdApi.Ok? - suspend fun readAllChatReactions(chatId: Long): TdApi.Ok? - suspend fun setChatDraftMessage(chatId: Long, messageThreadId: Long, draftMessage: TdApi.DraftMessage?): TdApi.Ok? - suspend fun pinChatMessage(chatId: Long, messageId: Long, disableNotification: Boolean, onlyForSelf: Boolean): TdApi.Ok? - suspend fun unpinChatMessage(chatId: Long, messageId: Long): TdApi.Ok? - suspend fun addMessageReaction(chatId: Long, messageId: Long, reaction: String): TdApi.Ok? - suspend fun removeMessageReaction(chatId: Long, messageId: Long, reaction: String): TdApi.Ok? - suspend fun setPollAnswer(chatId: Long, messageId: Long, optionIds: IntArray): TdApi.Ok? - suspend fun stopPoll(chatId: Long, messageId: Long): TdApi.Poll? - suspend fun sendChatAction(chatId: Long, messageThreadId: Long, action: TdApi.ChatAction): TdApi.Ok? - suspend fun getCallbackQueryAnswer(chatId: Long, messageId: Long, payload: TdApi.CallbackQueryPayload): TdApi.CallbackQueryAnswer? - suspend fun openWebApp(chatId: Long, botUserId: Long, url: String, theme: ThemeParams?): WebAppInfoModel? - suspend fun closeWebApp(webAppLaunchId: Long): TdApi.Ok? - suspend fun getPaymentForm(inputInvoice: TdApi.InputInvoice): TdApi.PaymentForm? - suspend fun sendWebAppData(botUserId: Long, buttonText: String, data: String): TdApi.Ok? - suspend fun markAsRead(chatId: Long, messageId: Long) - suspend fun markAllReactionsAsRead(chatId: Long) - suspend fun markAllMentionsAsRead(chatId: Long) - suspend fun pinMessage(chatId: Long, messageId: Long, disableNotification: Boolean) - suspend fun unpinMessage(chatId: Long, messageId: Long) - suspend fun saveChatDraft(chatId: Long, draft: TdApi.DraftMessage?, replyToMsgId: Long?, threadId: Long? = null) - suspend fun getChatDraft(chatId: Long, threadId: Long? = null): String? - fun updateVisibleRange(chatId: Long, visibleIds: List, nearbyIds: List) - suspend fun onCallbackQueryBuy(chatId: Long, messageId: Long) - suspend fun sendWebAppResult(botUserId: Long, data: String, buttonText: String = "") - suspend fun onCallbackQuery(chatId: Long, messageId: Long, data: ByteArray) - suspend fun searchMessages( - chatId: Long, - query: String, - fromMessageId: Long, - limit: Int, - threadId: Long? - ): SearchChatMessagesResult - - suspend fun getPollVotersModels( - chatId: Long, - messageId: Long, - optionId: Int, - offset: Int, - limit: Int - ): List - suspend fun getMessageViewersModels(chatId: Long, messageId: Long): List - - suspend fun getMessagesOlder( - chatId: Long, - fromMessageId: Long, - limit: Int, - threadId: Long? = null - ): OlderMessagesPage - - suspend fun getMessagesNewer( - chatId: Long, - fromMessageId: Long, - limit: Int, - threadId: Long? = null - ): List - - suspend fun getMessagesAround( - chatId: Long, - messageId: Long, - limit: Int, - threadId: Long? = null - ): List - - suspend fun getPinnedMessageModel(chatId: Long, threadId: Long? = null): MessageModel? - suspend fun getAllPinnedMessages(chatId: Long, threadId: Long? = null): List - suspend fun getPinnedMessageCount(chatId: Long, threadId: Long? = null): Int - suspend fun getScheduledMessages(chatId: Long): List - suspend fun sendScheduledNow(chatId: Long, messageId: Long) -} diff --git a/data/src/main/java/org/monogram/data/datasource/remote/PrivacyRemoteDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/PrivacyRemoteDataSource.kt deleted file mode 100644 index 19389d85..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/PrivacyRemoteDataSource.kt +++ /dev/null @@ -1,17 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.drinkless.tdlib.TdApi - -interface PrivacyRemoteDataSource { - suspend fun getPrivacyRules(setting: TdApi.UserPrivacySetting): List - suspend fun setPrivacyRules(setting: TdApi.UserPrivacySetting, rules: TdApi.UserPrivacySettingRules) - suspend fun getBlockedUsers(): List - suspend fun blockUser(userId: Long) - suspend fun unblockUser(userId: Long) - suspend fun deleteAccount(reason: String, password: String) - suspend fun getAccountTtl(): Int - suspend fun setAccountTtl(days: Int) - suspend fun getPasswordState(): Boolean - suspend fun getOption(name: String): Boolean - suspend fun setOption(name: String, value: Boolean) -} diff --git a/data/src/main/java/org/monogram/data/datasource/remote/ProxyRemoteDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/ProxyRemoteDataSource.kt deleted file mode 100644 index 6b009067..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/ProxyRemoteDataSource.kt +++ /dev/null @@ -1,17 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.drinkless.tdlib.TdApi -import org.monogram.domain.models.ProxyModel -import org.monogram.domain.models.ProxyTypeModel - -interface ProxyRemoteDataSource { - suspend fun getProxies(): List - suspend fun addProxy(server: String, port: Int, enable: Boolean, type: ProxyTypeModel): ProxyModel - suspend fun editProxy(proxyId: Int, server: String, port: Int, enable: Boolean, type: ProxyTypeModel): ProxyModel - suspend fun enableProxy(proxyId: Int): Boolean - suspend fun disableProxy() - suspend fun removeProxy(proxyId: Int) - suspend fun pingProxy(server: String, port: Int, type: ProxyTypeModel): Long - suspend fun testProxy(server: String, port: Int, type: ProxyTypeModel): Long - suspend fun setOption(key: String, value: TdApi.OptionValue) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/remote/SettingsRemoteDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/SettingsRemoteDataSource.kt deleted file mode 100644 index 6503514b..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/SettingsRemoteDataSource.kt +++ /dev/null @@ -1,44 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.drinkless.tdlib.TdApi - -interface SettingsRemoteDataSource { - // Getters - suspend fun getScopeNotificationSettings(scope: TdApi.NotificationSettingsScope): TdApi.ScopeNotificationSettings? - suspend fun getActiveSessions(): TdApi.Sessions? - suspend fun getInstalledBackgrounds(forDarkTheme: Boolean): TdApi.Backgrounds? - suspend fun getStorageStatistics(chatLimit: Int): TdApi.StorageStatistics? - suspend fun getNetworkStatistics(): TdApi.NetworkStatistics? - suspend fun getOption(name: String): TdApi.OptionValue? - suspend fun getChatNotificationSettingsExceptions( - scope: TdApi.NotificationSettingsScope, - compareSound: Boolean - ): TdApi.Chats? - - // Setters - suspend fun setScopeNotificationSettings( - scope: TdApi.NotificationSettingsScope, - settings: TdApi.ScopeNotificationSettings - ) - suspend fun setChatNotificationSettings(chatId: Long, settings: TdApi.ChatNotificationSettings) - suspend fun setOption(name: String, value: TdApi.OptionValue) - - // Sessions - suspend fun terminateSession(sessionId: Long): Boolean - suspend fun confirmQrCode(link: String): Boolean - - // Storage - suspend fun optimizeStorage( - size: Long, - ttl: Int, - count: Int, - immunityDelay: Int, - chatIds: LongArray?, - returnDeletedFileStatistics: Boolean, - chatLimit: Int - ): Boolean - suspend fun resetNetworkStatistics(): Boolean - - // Files - suspend fun downloadFile(fileId: Int, priority: Int) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/remote/StickerRemoteSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/StickerRemoteSource.kt deleted file mode 100644 index 1d8c466b..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/StickerRemoteSource.kt +++ /dev/null @@ -1,27 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.monogram.domain.models.GifModel -import org.monogram.domain.models.StickerModel -import org.monogram.domain.models.StickerSetModel -import org.monogram.domain.models.StickerType - -interface StickerRemoteSource { - suspend fun getInstalledStickerSets(type: StickerType): List - suspend fun getArchivedStickerSets(type: StickerType): List - suspend fun getStickerSet(setId: Long): StickerSetModel? - suspend fun getStickerSetByName(name: String): StickerSetModel? - suspend fun getRecentStickers(): List - suspend fun toggleStickerSetInstalled(setId: Long, isInstalled: Boolean) - suspend fun toggleStickerSetArchived(setId: Long, isArchived: Boolean) - suspend fun reorderStickerSets(type: StickerType, setIds: List) - suspend fun getEmojiCategories(): List - suspend fun getMessageAvailableReactions(chatId: Long, messageId: Long): List - suspend fun searchEmojis(query: String): List - suspend fun searchCustomEmojis(query: String): List - suspend fun searchStickers(query: String): List - suspend fun searchStickerSets(query: String): List - suspend fun getSavedGifs(): List - suspend fun addSavedGif(path: String) - suspend fun searchGifs(query: String): List - suspend fun clearRecentStickers() -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/remote/TdAuthRemoteDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/TdAuthRemoteDataSource.kt deleted file mode 100644 index e494abf1..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/TdAuthRemoteDataSource.kt +++ /dev/null @@ -1,43 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.drinkless.tdlib.TdApi -import org.monogram.data.gateway.TelegramGateway - -class TdAuthRemoteDataSource( - private val gateway: TelegramGateway -) : AuthRemoteDataSource { - - override suspend fun setTdlibParameters(parameters: TdApi.SetTdlibParameters) { - gateway.execute(parameters) - } - - override suspend fun setPhoneNumber(phone: String) { - val settings = TdApi.PhoneNumberAuthenticationSettings().apply { - isCurrentPhoneNumber = false - allowFlashCall = false - allowMissedCall = false - allowSmsRetrieverApi = false - } - gateway.execute(TdApi.SetAuthenticationPhoneNumber(phone, settings)) - } - - override suspend fun resendCode() { - gateway.execute(TdApi.ResendAuthenticationCode()) - } - - override suspend fun setAuthCode(code: String) { - gateway.execute(TdApi.CheckAuthenticationCode(code)) - } - - override suspend fun checkEmailCode(code: String) { - gateway.execute(TdApi.CheckAuthenticationEmailCode(TdApi.EmailAddressAuthenticationCode(code))) - } - - override suspend fun checkPassword(password: String) { - gateway.execute(TdApi.CheckAuthenticationPassword(password)) - } - - override suspend fun logout() { - gateway.execute(TdApi.LogOut()) - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/remote/TdChatRemoteDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/TdChatRemoteDataSource.kt deleted file mode 100644 index 811d5b45..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/TdChatRemoteDataSource.kt +++ /dev/null @@ -1,293 +0,0 @@ -package org.monogram.data.datasource.remote - -import android.net.ConnectivityManager -import android.net.NetworkCapabilities -import android.os.Build -import org.drinkless.tdlib.TdApi -import org.monogram.data.core.coRunCatching -import org.monogram.data.gateway.TelegramGateway -import org.monogram.domain.models.ChatPermissionsModel - -class TdChatRemoteSource( - private val gateway: TelegramGateway, - private val connectivityManager: ConnectivityManager -) : ChatRemoteSource { - - override suspend fun loadChats(chatList: TdApi.ChatList, limit: Int) { - coRunCatching { gateway.execute(TdApi.LoadChats(chatList, limit)) } - } - - override suspend fun searchChats(query: String, limit: Int): TdApi.Chats? { - return coRunCatching { gateway.execute(TdApi.SearchChats(query, limit)) }.getOrNull() - } - - override suspend fun searchPublicChats(query: String): TdApi.Chats? { - return coRunCatching { gateway.execute(TdApi.SearchPublicChats(query)) }.getOrNull() - } - - override suspend fun searchMessages(query: String, offset: String, limit: Int): TdApi.FoundMessages? { - return coRunCatching { - gateway.execute( - TdApi.SearchMessages(null, query, offset, limit, TdApi.SearchMessagesFilterEmpty(), null, 0, 0) - ) - }.getOrNull() - } - - override suspend fun getChat(chatId: Long): TdApi.Chat? { - return coRunCatching { gateway.execute(TdApi.GetChat(chatId)) }.getOrNull() - } - - override suspend fun createGroup(title: String, userIds: List, messageAutoDeleteTime: Int): Long { - return coRunCatching { - gateway.execute(TdApi.CreateNewBasicGroupChat(userIds.toLongArray(), title, messageAutoDeleteTime)).chatId - }.getOrDefault(0L) - } - - override suspend fun createChannel( - title: String, - description: String, - isMegagroup: Boolean, - messageAutoDeleteTime: Int - ): Long { - return coRunCatching { - gateway.execute( - TdApi.CreateNewSupergroupChat(title, isMegagroup, !isMegagroup, description, null, messageAutoDeleteTime, false) - ).id - }.getOrDefault(0L) - } - - override suspend fun setChatPhoto(chatId: Long, photoPath: String) { - coRunCatching { - gateway.execute(TdApi.SetChatPhoto(chatId, TdApi.InputChatPhotoStatic(TdApi.InputFileLocal(photoPath)))) - } - } - - override suspend fun setChatTitle(chatId: Long, title: String) { - coRunCatching { gateway.execute(TdApi.SetChatTitle(chatId, title)) } - } - - override suspend fun setChatDescription(chatId: Long, description: String) { - coRunCatching { - val chat = gateway.execute(TdApi.GetChat(chatId)) - val groupId = when (val type = chat.type) { - is TdApi.ChatTypeSupergroup -> type.supergroupId - is TdApi.ChatTypeBasicGroup -> type.basicGroupId - else -> return - } - gateway.execute(TdApi.SetChatDescription(groupId, description)) - } - } - - override suspend fun setChatUsername(chatId: Long, username: String) { - coRunCatching { - val chat = gateway.execute(TdApi.GetChat(chatId)) - val type = chat.type as? TdApi.ChatTypeSupergroup ?: return - gateway.execute(TdApi.SetSupergroupUsername(type.supergroupId, username)) - } - } - - override suspend fun setChatPermissions(chatId: Long, permissions: ChatPermissionsModel) { - coRunCatching { - gateway.execute(TdApi.SetChatPermissions(chatId, permissions.toTd())) - } - } - - override suspend fun setChatSlowModeDelay(chatId: Long, slowModeDelay: Int) { - coRunCatching { - val chat = gateway.execute(TdApi.GetChat(chatId)) - val supergroupId = (chat.type as? TdApi.ChatTypeSupergroup)?.supergroupId ?: chatId - gateway.execute(TdApi.SetChatSlowModeDelay(supergroupId, slowModeDelay)) - } - } - - override suspend fun toggleChatIsForum(chatId: Long, isForum: Boolean) { - coRunCatching { - val chat = gateway.execute(TdApi.GetChat(chatId)) - val type = chat.type as? TdApi.ChatTypeSupergroup ?: return - gateway.execute(TdApi.ToggleSupergroupIsForum(type.supergroupId, isForum, isForum)) - } - } - - override suspend fun toggleChatIsTranslatable(chatId: Long, isTranslatable: Boolean) { - coRunCatching { - val chat = gateway.execute(TdApi.GetChat(chatId)) - if (chat.type is TdApi.ChatTypeSupergroup) { - val supergroupId = (chat.type as TdApi.ChatTypeSupergroup).supergroupId - gateway.execute(TdApi.ToggleSupergroupHasAutomaticTranslation(supergroupId, isTranslatable)) - } else { - gateway.execute(TdApi.ToggleChatIsTranslatable(chatId, isTranslatable)) - } - } - } - - override suspend fun getChatLink(chatId: Long): String? { - return coRunCatching { - val chat = gateway.execute(TdApi.GetChat(chatId)) - when (val type = chat.type) { - is TdApi.ChatTypePrivate -> { - val user = gateway.execute(TdApi.GetUser(type.userId)) - user.usernames?.activeUsernames?.firstOrNull()?.let { "https://t.me/$it" } - } - is TdApi.ChatTypeSupergroup -> { - if (type.supergroupId == 0L) return@coRunCatching null - val sg = gateway.execute(TdApi.GetSupergroup(type.supergroupId)) - sg.usernames?.activeUsernames?.firstOrNull()?.let { "https://t.me/$it" } - } - else -> null - } - }.getOrNull() - } - - override suspend fun deleteFolder(folderId: Int) { - coRunCatching { gateway.execute(TdApi.DeleteChatFolder(folderId, longArrayOf())) } - } - - override suspend fun muteChat(chatId: Long, muteFor: Int) { - coRunCatching { - val settings = TdApi.ChatNotificationSettings( - false, muteFor, false, 0L, - false, false, false, false, - false, 0L, false, false, - false, false, false, false - ) - gateway.execute(TdApi.SetChatNotificationSettings(chatId, settings)) - } - } - - override suspend fun archiveChat(chatId: Long, archive: Boolean) { - coRunCatching { - val list = if (archive) TdApi.ChatListArchive() else TdApi.ChatListMain() - gateway.execute(TdApi.AddChatToList(chatId, list)) - } - } - - override suspend fun toggleChatIsPinned(chatList: TdApi.ChatList, chatId: Long, isPinned: Boolean) { - coRunCatching { - gateway.execute(TdApi.ToggleChatIsPinned(chatList, chatId, isPinned)) - } - } - - override suspend fun toggleChatIsMarkedAsUnread(chatId: Long, isMarkedAsUnread: Boolean) { - coRunCatching { - gateway.execute(TdApi.ToggleChatIsMarkedAsUnread(chatId, isMarkedAsUnread)) - } - } - - override suspend fun deleteChat(chatId: Long) { - coRunCatching { gateway.execute(TdApi.DeleteChat(chatId)) } - } - - override suspend fun leaveChat(chatId: Long) { - coRunCatching { gateway.execute(TdApi.LeaveChat(chatId)) } - } - - override suspend fun clearChatHistory(chatId: Long, revoke: Boolean) { - coRunCatching { gateway.execute(TdApi.DeleteChatHistory(chatId, false, revoke)) } - } - - override suspend fun reportChat(chatId: Long, reason: String, messageIds: List) { - coRunCatching { - val msgArray = messageIds.toLongArray() - val predefined = setOf( - "spam", "violence", "pornography", "child_abuse", - "copyright", "fake", "illegal_drugs", "personal_details", "unrelated_location" - ) - val isCustom = reason !in predefined - val reportText = if (isCustom) reason else "" - - val first = gateway.execute(TdApi.ReportChat(chatId, null, msgArray, reportText)) - if (first is TdApi.ReportChatResultOptionRequired) { - val option = if (isCustom) first.options.lastOrNull() - else first.options.find { it.text.contains(reason, ignoreCase = true) } - ?: first.options.firstOrNull() - option?.let { gateway.execute(TdApi.ReportChat(chatId, it.id, msgArray, reportText)) } - } - } - } - - override suspend fun getMyUserId(): Long { - return coRunCatching { gateway.execute(TdApi.GetMe()).id }.getOrDefault(0L) - } - - override suspend fun setNetworkType(): Boolean { - val networkType = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - val activeNetwork = connectivityManager.activeNetwork - val capabilities = connectivityManager.getNetworkCapabilities(activeNetwork) - when { - capabilities == null -> TdApi.NetworkTypeNone() - capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> TdApi.NetworkTypeWiFi() - capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - // Check for roaming if possible, otherwise default to Mobile - TdApi.NetworkTypeMobile() - } else { - TdApi.NetworkTypeMobile() - } - } - - else -> TdApi.NetworkTypeOther() - } - } else { - @Suppress("DEPRECATION") - val activeNetworkInfo = connectivityManager.activeNetworkInfo - when (activeNetworkInfo?.type) { - ConnectivityManager.TYPE_WIFI -> TdApi.NetworkTypeWiFi() - ConnectivityManager.TYPE_MOBILE -> TdApi.NetworkTypeMobile() - else -> TdApi.NetworkTypeOther() - } - } - return coRunCatching { gateway.execute(TdApi.SetNetworkType(networkType)) }.isSuccess - } - - override suspend fun getConnectionState(): TdApi.ConnectionState? { - val option = coRunCatching { gateway.execute(TdApi.GetOption("connection_state")) }.getOrNull() ?: return null - - val normalized = when (option) { - is TdApi.OptionValueString -> option.value.lowercase() - is TdApi.OptionValueInteger -> option.value.toString() - else -> return null - } - - return when { - normalized == "4" || normalized.contains("ready") -> TdApi.ConnectionStateReady() - normalized == "3" || normalized.contains("updating") -> TdApi.ConnectionStateUpdating() - normalized == "2" || normalized.contains("proxy") -> TdApi.ConnectionStateConnectingToProxy() - normalized == "1" || normalized.contains("network") -> TdApi.ConnectionStateWaitingForNetwork() - normalized == "0" || normalized.contains("connecting") -> TdApi.ConnectionStateConnecting() - else -> null - } - } - - override suspend fun getForumTopics( - chatId: Long, - query: String, - offsetDate: Int, - offsetMessageId: Long, - offsetForumTopicId: Int, - limit: Int - ): TdApi.ForumTopics? { - return coRunCatching { - gateway.execute( - TdApi.GetForumTopics(chatId, query, offsetDate, offsetMessageId, offsetForumTopicId, limit) - ) - }.getOrNull() - } - - private fun ChatPermissionsModel.toTd() = TdApi.ChatPermissions( - canSendBasicMessages, - canSendAudios, - canSendDocuments, - canSendPhotos, - canSendVideos, - canSendVideoNotes, - canSendVoiceNotes, - canSendPolls, - canSendOtherMessages, - canAddLinkPreviews, - canEditTag, - canChangeInfo, - canInviteUsers, - canPinMessages, - canCreateTopics - ) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/remote/TdChatsRemoteDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/TdChatsRemoteDataSource.kt deleted file mode 100644 index 54440d6c..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/TdChatsRemoteDataSource.kt +++ /dev/null @@ -1,51 +0,0 @@ -package org.monogram.data.datasource.remote - -import android.util.Log -import org.drinkless.tdlib.TdApi -import org.monogram.data.gateway.TelegramGateway - -class TdChatsRemoteDataSource( - private val gateway: TelegramGateway -) : ChatsRemoteDataSource { - - private suspend fun safeExecute(function: TdApi.Function): T? { - return try { - gateway.execute(function) - } catch (e: Exception) { - Log.e("TdChatsRemote", "Error executing ${function.javaClass.simpleName}", e) - null - } - } - - override suspend fun getChat(chatId: Long): TdApi.Chat? { - val chat = safeExecute(TdApi.GetChat(chatId)) - if (chat == null && chatId > 0) { - // Try to create private chat if it's a user ID and not found - return safeExecute(TdApi.CreatePrivateChat(chatId, false)) - } - return chat - } - - override suspend fun searchChats(query: String, limit: Int): TdApi.Chats? = - safeExecute(TdApi.SearchChats(query, limit)) - - override suspend fun searchPublicChats(query: String): TdApi.Chats? = - safeExecute(TdApi.SearchPublicChats(query)) - - override suspend fun getChatNotificationSettingsExceptions( - scope: TdApi.NotificationSettingsScope, - compareSound: Boolean - ): TdApi.Chats? = - safeExecute(TdApi.GetChatNotificationSettingsExceptions(scope, compareSound)) - - override suspend fun getForumTopics( - chatId: Long, - query: String, - offsetDate: Int, - offsetMessageId: Long, - offsetForumTopicId: Int, - limit: Int - ): TdApi.ForumTopics? = safeExecute( - TdApi.GetForumTopics(chatId, query, offsetDate, offsetMessageId, offsetForumTopicId, limit) - ) -} diff --git a/data/src/main/java/org/monogram/data/datasource/remote/TdMessageRemoteDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/TdMessageRemoteDataSource.kt deleted file mode 100644 index 48efb3be..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/TdMessageRemoteDataSource.kt +++ /dev/null @@ -1,1484 +0,0 @@ -package org.monogram.data.datasource.remote - -import android.os.Build -import android.util.Log -import kotlinx.coroutines.* -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.flow.MutableSharedFlow -import org.drinkless.tdlib.TdApi -import org.monogram.core.DispatcherProvider -import org.monogram.core.ScopeProvider -import org.monogram.data.chats.ChatCache -import org.monogram.data.di.TdLibException -import org.monogram.data.gateway.TelegramGateway -import org.monogram.data.infra.FileDownloadQueue -import org.monogram.data.mapper.MessageMapper -import org.monogram.data.mapper.toApi -import org.monogram.domain.models.* -import org.monogram.domain.models.webapp.ThemeParams -import org.monogram.domain.models.webapp.WebAppInfoModel -import org.monogram.domain.repository.* -import java.util.concurrent.ConcurrentHashMap - -class TdMessageRemoteDataSource( - private val gateway: TelegramGateway, - private val messageMapper: MessageMapper, - private val userRepository: UserRepository, - private val chatsListRepository: ChatsListRepository, - private val cache: ChatCache, - private val pollRepository: PollRepository, - private val fileDownloadQueue: FileDownloadQueue, - private val dispatcherProvider: DispatcherProvider, - scopeProvider: ScopeProvider -) : MessageRemoteDataSource { - - val scope = scopeProvider.appScope - private val chatRequests = ConcurrentHashMap>() - private val messageRequests = ConcurrentHashMap, Deferred>() - private val refreshJobs = ConcurrentHashMap, Job>() - private val sendQueue = Channel Unit>(Channel.BUFFERED) - override val newMessageFlow = MutableSharedFlow() - override val messageEditedFlow = MutableSharedFlow() - override val messageReadFlow = MutableSharedFlow( - replay = 1, - extraBufferCapacity = 100, - onBufferOverflow = kotlinx.coroutines.channels.BufferOverflow.SUSPEND - ) - override val messageUploadProgressFlow = MutableSharedFlow>() - override val messageDownloadProgressFlow = MutableSharedFlow>() - override val messageDownloadCancelledFlow = MutableSharedFlow() - override val messageDeletedFlow = MutableSharedFlow>>( - extraBufferCapacity = 100, - onBufferOverflow = kotlinx.coroutines.channels.BufferOverflow.SUSPEND - ) - override val messageIdUpdateFlow = MutableSharedFlow>( - extraBufferCapacity = 100, - onBufferOverflow = kotlinx.coroutines.channels.BufferOverflow.SUSPEND - ) - override val messageDownloadCompletedFlow = MutableSharedFlow>() - override val pinnedMessageFlow = MutableSharedFlow( - extraBufferCapacity = 10, - onBufferOverflow = kotlinx.coroutines.channels.BufferOverflow.SUSPEND - ) - override val mediaUpdateFlow = MutableSharedFlow( - replay = 0, - extraBufferCapacity = 10, - onBufferOverflow = kotlinx.coroutines.channels.BufferOverflow.DROP_OLDEST - ) - - enum class DownloadType { VIDEO, GIF, STICKER, VIDEO_NOTE, DEFAULT } - - private val fileIdToMessageMap = fileDownloadQueue.registry.fileIdToMessageMap - val customEmojiPaths = ConcurrentHashMap() - val fileIdToCustomEmojiId = ConcurrentHashMap() - private val messageUpdateJobs = ConcurrentHashMap, Job>() - private val lastProgressMap = ConcurrentHashMap() - private val lastDownloadActiveMap = ConcurrentHashMap() - - init { - scope.launch { - for (task in sendQueue) { - try { - task() - } catch (e: Exception) { - Log.e("TdMessageRemote", "Error in sendQueue", e) - } - } - } - } - - private suspend fun safeExecute(function: TdApi.Function): T? { - return try { - gateway.execute(function) - } catch (e: Exception) { - Log.e("TdMessageRemote", "Error executing ${function.javaClass.simpleName}", e) - null - } - } - - - override suspend fun getMessage(chatId: Long, messageId: Long): TdApi.Message? { - cache.getMessage(chatId, messageId)?.let { return it } - val key = chatId to messageId - val deferred = messageRequests.getOrPut(key) { - scope.async { - val result = safeExecute(TdApi.GetMessage(chatId, messageId)) - if (result != null) cache.putMessage(result) - result - } - } - return try { - deferred.await() - } catch (e: Exception) { - null - } finally { - messageRequests.remove(key) - } - } - - suspend fun getChat(chatId: Long): TdApi.Chat? { - cache.getChat(chatId)?.let { return it } - val deferred = chatRequests.getOrPut(chatId) { - scope.async { - val result = safeExecute(TdApi.GetChat(chatId)) - if (result != null) cache.putChat(result) - result - } - } - return try { - deferred.await() - } catch (e: Exception) { - null - } finally { - chatRequests.remove(chatId) - } - } - - override suspend fun getMessagesOlder(chatId: Long, fromMessageId: Long, limit: Int, threadId: Long?): OlderMessagesPage { - if (fromMessageId == 0L) { - val messages = loadMessages(chatId, fromMessageId, 0, limit, threadId) - val page = OlderMessagesPage( - messages = messages, - reachedOldest = messages.isEmpty(), - isRemote = true - ) - return page - } - - val messages = loadMessages(chatId, fromMessageId, 0, limit + 1, threadId) - val filtered = messages.filter { it.id != fromMessageId }.take(limit) - val page = OlderMessagesPage( - messages = filtered, - reachedOldest = filtered.isEmpty(), - isRemote = true - ) - return page - } - - override suspend fun getMessagesNewer(chatId: Long, fromMessageId: Long, limit: Int, threadId: Long?): List { - return loadMessages(chatId, fromMessageId, -limit, limit, threadId) - } - - override suspend fun getMessagesAround(chatId: Long, messageId: Long, limit: Int, threadId: Long?): List { - return loadMessages(chatId, messageId, -limit / 2, limit, threadId) - } - - override suspend fun getChatPinnedMessage(chatId: Long): TdApi.Message? = - safeExecute(TdApi.GetChatPinnedMessage(chatId)) - - override suspend fun getPinnedMessageModel(chatId: Long, threadId: Long?): MessageModel? { - val chat = getChat(chatId) ?: return null - - if (threadId != null) { - if (chat.viewAsTopics) { - val topic = safeExecute(TdApi.GetForumTopic(chatId, threadId.toInt())) - if (topic != null) return searchPinnedMessage(chatId, threadId.toInt()) - return null - } - } - - val result = getChatPinnedMessage(chatId) - return if (result != null) { - cache.putMessage(result) - messageMapper.mapMessageToModel(result, isChatOpen = true) - } else null - } - - override suspend fun getAllPinnedMessages(chatId: Long, threadId: Long?): List { - val allPinnedMessages = mutableListOf() - var offsetMessageId = 0L - var totalCount = Int.MAX_VALUE - - while (allPinnedMessages.size < totalCount) { - val batch = getPinnedMessagesPage(chatId, threadId, offsetMessageId) - - if (batch.totalCount == 0 || batch.messages.isEmpty()) { - break - } - - totalCount = batch.totalCount - - var addedCount = 0 - for (message in batch.messages) { - if (allPinnedMessages.none { it.id == message.id }) { - cache.putMessage(message) - val model = messageMapper.mapMessageToModel(message, isChatOpen = true) - allPinnedMessages.add(model) - addedCount++ - } - } - - if (addedCount == 0) { - break - } - - offsetMessageId = batch.messages.last().id - } - - return allPinnedMessages - } - - override suspend fun getPinnedMessageCount(chatId: Long, threadId: Long?): Int { - val request = TdApi.SearchChatMessages().apply { - this.chatId = chatId - this.query = "" - this.senderId = null - this.fromMessageId = 0 - this.offset = 0 - this.limit = 1 - this.filter = TdApi.SearchMessagesFilterPinned() - this.topicId = if (threadId != null) { - TdApi.MessageTopicForum(threadId.toInt()) - } else { - null - } - } - - val result = safeExecute(request) - return if (result is TdApi.FoundChatMessages) { - result.totalCount - } else { - 0 - } - } - - override suspend fun getScheduledMessages(chatId: Long): List { - val result = safeExecute(TdApi.GetChatScheduledMessages(chatId)) ?: return emptyList() - if (result !is TdApi.Messages) return emptyList() - - return result.messages - .onEach { cache.putMessage(it) } - .map { messageMapper.mapMessageToModel(it, isChatOpen = true) } - .sortedBy { it.date } - } - - override suspend fun sendScheduledNow(chatId: Long, messageId: Long) { - safeExecute( - TdApi.EditMessageSchedulingState( - chatId, - messageId, - null - ) - ) - } - - private suspend fun getPinnedMessagesPage( - chatId: Long, - threadId: Long?, - fromMessageId: Long - ): TdApi.FoundChatMessages { - val request = TdApi.SearchChatMessages().apply { - this.chatId = chatId - this.query = "" - this.senderId = null - this.fromMessageId = fromMessageId - this.offset = 0 - this.limit = 100 - this.filter = TdApi.SearchMessagesFilterPinned() - this.topicId = if (threadId != null) { - TdApi.MessageTopicForum(threadId.toInt()) - } else { - null - } - } - - val result = safeExecute(request) - return result ?: TdApi.FoundChatMessages(0, emptyArray(), 0L) - } - - private suspend fun searchPinnedMessage(chatId: Long, threadId: Int): MessageModel? { - val request = TdApi.SearchChatMessages().apply { - this.chatId = chatId - this.topicId = TdApi.MessageTopicForum(threadId) - this.query = "" - this.senderId = null - this.fromMessageId = 0 - this.offset = 0 - this.limit = 1 - this.filter = TdApi.SearchMessagesFilterPinned() - } - val result = safeExecute(request) - return if (result != null && result.messages.isNotEmpty()) { - val msg = result.messages.first() - cache.putMessage(msg) - messageMapper.mapMessageToModel(msg, isChatOpen = true) - } else null - } - - override suspend fun getPollVoters(chatId: Long, messageId: Long, optionId: Int, offset: Int, limit: Int): TdApi.PollVoters? = - safeExecute(TdApi.GetPollVoters(chatId, messageId, optionId, offset, limit)) - - override suspend fun getMessageViewers(chatId: Long, messageId: Long): TdApi.MessageViewers? = - safeExecute(TdApi.GetMessageViewers(chatId, messageId)) - - override suspend fun getPollVotersModels(chatId: Long, messageId: Long, optionId: Int, offset: Int, limit: Int): List { - val result = getPollVoters(chatId, messageId, optionId, offset, limit) ?: return emptyList() - return result.voters.mapNotNull { pollVoter -> - when (val sender = pollVoter.voterId) { - is TdApi.MessageSenderUser -> userRepository.getUser(sender.userId) - is TdApi.MessageSenderChat -> { - val cachedChat = cache.getChat(sender.chatId) - if (cachedChat != null) { - UserModel(id = cachedChat.id, firstName = cachedChat.title, lastName = "", username = null, avatarPath = cachedChat.photo?.small?.local?.path) - } else { - val chat = chatsListRepository.getChatById(sender.chatId) - if (chat != null) UserModel(id = chat.id, firstName = chat.title, lastName = "", username = null, avatarPath = chat.avatarPath) - else null - } - } - else -> null - } - } - } - - override suspend fun getMessageViewersModels(chatId: Long, messageId: Long): List { - val result = getMessageViewers(chatId, messageId) ?: return emptyList() - return result.viewers.mapNotNull { viewer -> - val user = userRepository.getUser(viewer.userId) ?: return@mapNotNull null - MessageViewerModel( - user = user, - viewedDate = viewer.viewDate - ) - } - } - - override suspend fun searchChatMessages(chatId: Long, query: String, fromMessageId: Long, limit: Int, filter: TdApi.SearchMessagesFilter, threadId: Long?): TdApi.FoundChatMessages? { - val request = TdApi.SearchChatMessages().apply { - this.chatId = chatId - this.topicId = if (threadId != null) TdApi.MessageTopicForum(threadId.toInt()) else null - this.query = query - this.senderId = null - this.fromMessageId = fromMessageId - this.offset = 0 - this.limit = limit - this.filter = filter - } - return safeExecute(request) - } - - override suspend fun searchMessages(chatId: Long, query: String, fromMessageId: Long, limit: Int, threadId: Long?): SearchChatMessagesResult { - val result = searchChatMessages(chatId, query, fromMessageId, limit, TdApi.SearchMessagesFilterEmpty(), threadId) - if (result != null) { - val chat = getChat(chatId) - val lastReadInbox = chat?.lastReadInboxMessageId ?: 0L - val lastReadOutbox = chat?.lastReadOutboxMessageId ?: 0L - val models = result.messages.map { msg -> - cache.putMessage(msg) - scope.async { - try { - withTimeout(5000) { messageMapper.mapMessageToModelSync(msg, lastReadInbox, lastReadOutbox, isChatOpen = true) } - } catch (e: Exception) { - Log.e("TdMessageRemote", "Error mapping search message ${msg.id}", e) - createFallbackMessage(msg) - } - } - }.awaitAll() - return SearchChatMessagesResult(models, result.totalCount, result.nextFromMessageId) - } else return SearchChatMessagesResult(emptyList(), 0, 0L) - } - - private suspend fun loadMessages(chatId: Long, fromMessageId: Long, offset: Int, limit: Int, threadId: Long? = null): List = withContext(dispatcherProvider.io) { - val historyResult = getChatHistoryInternal(chatId, fromMessageId, offset, limit, threadId) - ?: throw IllegalStateException( - "Failed to load history for chatId=$chatId fromMessageId=$fromMessageId offset=$offset limit=$limit threadId=$threadId" - ) - val chat = getChat(chatId) - val lastReadInbox = chat?.lastReadInboxMessageId ?: 0L - val lastReadOutbox = chat?.lastReadOutboxMessageId ?: 0L - val messages = when (historyResult) { - is TdApi.Messages -> historyResult.messages - is TdApi.MessageThreadInfo -> historyResult.messages - else -> emptyArray() - } - messages.map { msg -> - cache.putMessage(msg) - async { - try { - withTimeout(5000) { messageMapper.mapMessageToModelSync(msg, lastReadInbox, lastReadOutbox, isChatOpen = true) } - } catch (e: Exception) { - Log.e("TdMessageRemote", "Error mapping message ${msg.id}", e) - createFallbackMessage(msg) - } - } - }.awaitAll() - } - - private suspend fun getChatHistoryInternal(chatId: Long, fromMessageId: Long, offset: Int, limit: Int, threadId: Long? = null): TdApi.Object? { - return if (threadId != null) { - val chat = getChat(chatId) - if (chat != null) { - if (chat.viewAsTopics) { - val req = TdApi.GetForumTopicHistory().apply { - this.chatId = chatId - this.forumTopicId = threadId.toInt() - this.fromMessageId = fromMessageId - this.offset = offset - this.limit = limit - } - safeExecute(req) - } else { - val req = TdApi.GetMessageThreadHistory().apply { - this.chatId = chatId - this.messageId = threadId - this.fromMessageId = fromMessageId - this.offset = offset - this.limit = limit - } - safeExecute(req) - } - } else null - } else { - val req = TdApi.GetChatHistory().apply { - this.chatId = chatId - this.fromMessageId = fromMessageId - this.offset = offset - this.limit = limit - this.onlyLocal = false - } - safeExecute(req) - } - } - - override suspend fun getChatHistory(chatId: Long, fromMessageId: Long, offset: Int, limit: Int): TdApi.Messages? { - val req = TdApi.GetChatHistory().apply { - this.chatId = chatId - this.fromMessageId = fromMessageId - this.offset = offset - this.limit = limit - this.onlyLocal = false - } - return safeExecute(req) - } - - override suspend fun getMessages(chatId: Long, fromMessageId: Long, offset: Int, limit: Int, threadId: Long?): TdApi.Messages? { - return when (val result = getChatHistoryInternal(chatId, fromMessageId, offset, limit, threadId)) { - is TdApi.Messages -> result - is TdApi.MessageThreadInfo -> TdApi.Messages(result.messages.size, result.messages) - else -> null - } - } - - private fun createFallbackMessage(msg: TdApi.Message): MessageModel = MessageModel( - id = msg.id, date = msg.date, isOutgoing = msg.isOutgoing, senderName = "Unknown", chatId = msg.chatId, - content = MessageContent.Text("Error loading message"), senderId = 0L, senderAvatar = null, isRead = false, - replyToMsgId = null, replyToMsg = null, forwardInfo = null, views = null, viewCount = null, mediaAlbumId = 0L, - editDate = 0, sendingState = null, readDate = 0, reactions = emptyList(), isSenderVerified = false, - threadId = null, replyCount = 0, canGetMessageThread = false, replyMarkup = null - ) - - override suspend fun sendMessage( - chatId: Long, - text: String, - replyToMsgId: Long?, - entities: List, - threadId: Long?, - sendOptions: MessageSendOptions - ): TdApi.Message? { - val parsedText = TdApi.FormattedText( - text, - entities.toTdTextEntities(text) - ) - val content = TdApi.InputMessageText().apply { - this.text = parsedText - this.clearDraft = true - } - val replyTo = if (replyToMsgId != null && replyToMsgId != 0L) TdApi.InputMessageReplyToMessage(replyToMsgId, null, 0) else null - val topicId = if (threadId != null && threadId != 0L) TdApi.MessageTopicThread(threadId) else null - val req = TdApi.SendMessage().apply { - this.chatId = chatId - this.topicId = topicId - this.replyTo = replyTo - this.inputMessageContent = content - this.options = sendOptions.toTdMessageSendOptions() - } - return safeExecute(req) - } - - override suspend fun sendPhoto( - chatId: Long, - photoPath: String, - caption: String, - captionEntities: List, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ): TdApi.Message? { - val content = TdApi.InputMessagePhoto().apply { - this.photo = TdApi.InputFileLocal(photoPath) - this.caption = TdApi.FormattedText(caption, captionEntities.toTdTextEntities(caption)) - } - val replyTo = if (replyToMsgId != null && replyToMsgId != 0L) TdApi.InputMessageReplyToMessage(replyToMsgId, null, 0) else null - val topicId = if (threadId != null && threadId != 0L) TdApi.MessageTopicThread(threadId) else null - val req = TdApi.SendMessage().apply { - this.chatId = chatId - this.topicId = topicId - this.replyTo = replyTo - this.inputMessageContent = content - this.options = sendOptions.toTdMessageSendOptions() - } - val response = safeExecute(req) - if (response?.content is TdApi.MessagePhoto) { - val fileId = (response.content as TdApi.MessagePhoto).photo.sizes.lastOrNull()?.photo?.id - if (fileId != null) { - registerFileForMessage(fileId, chatId, response.id) - waitForUpload(fileId).await() - } - } - return response - } - - override suspend fun sendVideo( - chatId: Long, - videoPath: String, - caption: String, - captionEntities: List, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ): TdApi.Message? { - val content = TdApi.InputMessageVideo().apply { - this.video = TdApi.InputFileLocal(videoPath) - this.caption = TdApi.FormattedText(caption, captionEntities.toTdTextEntities(caption)) - } - val replyTo = if (replyToMsgId != null && replyToMsgId != 0L) TdApi.InputMessageReplyToMessage(replyToMsgId, null, 0) else null - val topicId = if (threadId != null && threadId != 0L) TdApi.MessageTopicThread(threadId) else null - val req = TdApi.SendMessage().apply { - this.chatId = chatId - this.topicId = topicId - this.replyTo = replyTo - this.inputMessageContent = content - this.options = sendOptions.toTdMessageSendOptions() - } - val response = safeExecute(req) - if (response?.content is TdApi.MessageVideo) { - val fileId = (response.content as TdApi.MessageVideo).video.video.id - registerFileForMessage(fileId, chatId, response.id) - waitForUpload(fileId).await() - } - return response - } - - override suspend fun sendDocument( - chatId: Long, - documentPath: String, - caption: String, - captionEntities: List, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ): TdApi.Message? { - val content = TdApi.InputMessageDocument().apply { - this.document = TdApi.InputFileLocal(documentPath) - this.caption = TdApi.FormattedText(caption, captionEntities.toTdTextEntities(caption)) - } - val replyTo = if (replyToMsgId != null && replyToMsgId != 0L) TdApi.InputMessageReplyToMessage(replyToMsgId, null, 0) else null - val topicId = if (threadId != null && threadId != 0L) TdApi.MessageTopicThread(threadId) else null - val req = TdApi.SendMessage().apply { - this.chatId = chatId - this.topicId = topicId - this.replyTo = replyTo - this.inputMessageContent = content - this.options = sendOptions.toTdMessageSendOptions() - } - val response = safeExecute(req) - if (response?.content is TdApi.MessageDocument) { - val fileId = (response.content as TdApi.MessageDocument).document.document.id - registerFileForMessage(fileId, chatId, response.id) - waitForUpload(fileId).await() - } - return response - } - - override suspend fun sendSticker(chatId: Long, stickerPath: String, replyToMsgId: Long?, threadId: Long?): TdApi.Message? { - val content = TdApi.InputMessageSticker().apply { - this.sticker = TdApi.InputFileLocal(stickerPath) - this.width = 512 - this.height = 512 - } - val replyTo = if (replyToMsgId != null && replyToMsgId != 0L) TdApi.InputMessageReplyToMessage(replyToMsgId, null, 0) else null - val topicId = if (threadId != null && threadId != 0L) TdApi.MessageTopicThread(threadId) else null - val req = TdApi.SendMessage().apply { - this.chatId = chatId - this.topicId = topicId - this.replyTo = replyTo - this.inputMessageContent = content - } - val response = safeExecute(req) - if (response?.content is TdApi.MessageSticker) { - waitForUpload((response.content as TdApi.MessageSticker).sticker.sticker.id).await() - } - return response - } - - override suspend fun sendGif( - chatId: Long, - gifId: String, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ): TdApi.Message? { - val content = TdApi.InputMessageAnimation().apply { - this.animation = TdApi.InputFileId(gifId.toInt()) - } - val replyTo = if (replyToMsgId != null && replyToMsgId != 0L) TdApi.InputMessageReplyToMessage(replyToMsgId, null, 0) else null - val topicId = if (threadId != null && threadId != 0L) TdApi.MessageTopicThread(threadId) else null - val req = TdApi.SendMessage().apply { - this.chatId = chatId - this.topicId = topicId - this.replyTo = replyTo - this.inputMessageContent = content - this.options = sendOptions.toTdMessageSendOptions() - } - return safeExecute(req) - } - - override suspend fun sendGifFile( - chatId: Long, - gifPath: String, - caption: String, - captionEntities: List, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ): TdApi.Message? { - val content = TdApi.InputMessageAnimation().apply { - this.animation = TdApi.InputFileLocal(gifPath) - this.caption = TdApi.FormattedText(caption, captionEntities.toTdTextEntities(caption)) - } - val replyTo = if (replyToMsgId != null && replyToMsgId != 0L) TdApi.InputMessageReplyToMessage(replyToMsgId, null, 0) else null - val topicId = if (threadId != null && threadId != 0L) TdApi.MessageTopicThread(threadId) else null - val req = TdApi.SendMessage().apply { - this.chatId = chatId - this.topicId = topicId - this.replyTo = replyTo - this.inputMessageContent = content - this.options = sendOptions.toTdMessageSendOptions() - } - val response = safeExecute(req) - if (response?.content is TdApi.MessageAnimation) { - val fileId = (response.content as TdApi.MessageAnimation).animation.animation.id - registerFileForMessage(fileId, chatId, response.id) - waitForUpload(fileId).await() - } - return response - } - - override suspend fun sendAlbum( - chatId: Long, - paths: List, - caption: String, - captionEntities: List, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ): TdApi.Messages? { - val inputMessageContents = paths.mapIndexed { index, path -> - val isVideo = path.endsWith(".mp4", ignoreCase = true) - val cap = if (index == 0) TdApi.FormattedText(caption, captionEntities.toTdTextEntities(caption)) else null - if (isVideo) TdApi.InputMessageVideo().apply { - this.video = TdApi.InputFileLocal(path) - this.caption = cap - } - else TdApi.InputMessagePhoto().apply { - this.photo = TdApi.InputFileLocal(path) - this.caption = cap - } - }.toTypedArray() - val replyTo = if (replyToMsgId != null && replyToMsgId != 0L) TdApi.InputMessageReplyToMessage(replyToMsgId, null, 0) else null - val topicId = if (threadId != null && threadId != 0L) TdApi.MessageTopicThread(threadId) else null - val req = TdApi.SendMessageAlbum().apply { - this.chatId = chatId - this.topicId = topicId - this.replyTo = replyTo - this.inputMessageContents = inputMessageContents - this.options = sendOptions.toTdMessageSendOptions() - } - val result = safeExecute(req) - result?.messages?.forEach { msg -> - val fileId = when (val c = msg.content) { - is TdApi.MessagePhoto -> c.photo.sizes.lastOrNull()?.photo?.id - is TdApi.MessageVideo -> c.video.video.id - else -> null - } - if (fileId != null) { - registerFileForMessage(fileId, chatId, msg.id) - waitForUpload(fileId).await() - } - } - return result - } - - override suspend fun sendVideoNote(chatId: Long, videoPath: String, duration: Int, length: Int): TdApi.Message? { - val content = TdApi.InputMessageVideoNote().apply { - this.videoNote = TdApi.InputFileLocal(videoPath) - this.duration = duration - this.length = length - } - val req = TdApi.SendMessage().apply { - this.chatId = chatId - this.inputMessageContent = content - } - val response = safeExecute(req) - if (response?.content is TdApi.MessageVideoNote) waitForUpload((response.content as TdApi.MessageVideoNote).videoNote.video.id).await() - return response - } - - override suspend fun sendVoiceNote( - chatId: Long, - voicePath: String, - duration: Int, - waveform: ByteArray - ): TdApi.Message? { - val content = TdApi.InputMessageVoiceNote().apply { - this.voiceNote = TdApi.InputFileLocal(voicePath) - this.duration = duration - this.waveform = waveform - } - val req = TdApi.SendMessage().apply { - this.chatId = chatId - this.inputMessageContent = content - } - val response = safeExecute(req) - if (response?.content is TdApi.MessageVoiceNote) waitForUpload((response.content as TdApi.MessageVoiceNote).voiceNote.voice.id).await() - return response - } - - override suspend fun forwardMessages(toChatId: Long, fromChatId: Long, messageIds: LongArray, removeCaption: Boolean, sendCopy: Boolean): TdApi.Messages? { - val options = TdApi.MessageSendOptions().apply { - this.disableNotification = false - this.fromBackground = false - } - val req = TdApi.ForwardMessages().apply { - this.chatId = toChatId - this.fromChatId = fromChatId - this.messageIds = messageIds - this.options = options - this.removeCaption = removeCaption - this.sendCopy = sendCopy - } - return safeExecute(req) - } - - override suspend fun deleteMessages(chatId: Long, messageIds: LongArray, revoke: Boolean): TdApi.Ok? { - val req = TdApi.DeleteMessages().apply { - this.chatId = chatId - this.messageIds = messageIds - this.revoke = revoke - } - return safeExecute(req) - } - - override suspend fun editMessageText(chatId: Long, messageId: Long, text: String, entities: List): TdApi.Message? { - val parsedText = TdApi.FormattedText( - text, - entities.toTdTextEntities(text) - ) - val content = TdApi.InputMessageText().apply { - this.text = parsedText - } - val req = TdApi.EditMessageText().apply { - this.chatId = chatId - this.messageId = messageId - this.inputMessageContent = content - } - return safeExecute(req) - } - - private fun List.toTdTextEntities(text: String): Array { - if (isEmpty()) return emptyArray() - - return this - .mapNotNull { it.toTdTextEntity(text) } - .sortedWith(compareBy { it.offset }.thenByDescending { it.length }) - .toTypedArray() - } - - private fun MessageEntity.toTdTextEntity(text: String): TdApi.TextEntity? { - val start = offset.coerceIn(0, text.length) - val end = (offset + length).coerceIn(0, text.length) - val safeLength = end - start - if (safeLength <= 0) return null - - val tdType: TdApi.TextEntityType = when (val value = type) { - is MessageEntityType.Bold -> TdApi.TextEntityTypeBold() - is MessageEntityType.Italic -> TdApi.TextEntityTypeItalic() - is MessageEntityType.Underline -> TdApi.TextEntityTypeUnderline() - is MessageEntityType.Strikethrough -> TdApi.TextEntityTypeStrikethrough() - is MessageEntityType.Spoiler -> TdApi.TextEntityTypeSpoiler() - is MessageEntityType.Code -> TdApi.TextEntityTypeCode() - is MessageEntityType.Pre -> { - if (value.language.isBlank()) TdApi.TextEntityTypePre() - else TdApi.TextEntityTypePreCode(value.language) - } - - is MessageEntityType.TextUrl -> TdApi.TextEntityTypeTextUrl(value.url) - is MessageEntityType.Mention -> TdApi.TextEntityTypeMention() - is MessageEntityType.TextMention -> TdApi.TextEntityTypeMentionName(value.userId) - is MessageEntityType.Hashtag -> TdApi.TextEntityTypeHashtag() - is MessageEntityType.BotCommand -> TdApi.TextEntityTypeBotCommand() - is MessageEntityType.Url -> TdApi.TextEntityTypeUrl() - is MessageEntityType.Email -> TdApi.TextEntityTypeEmailAddress() - is MessageEntityType.PhoneNumber -> TdApi.TextEntityTypePhoneNumber() - is MessageEntityType.BankCardNumber -> TdApi.TextEntityTypeBankCardNumber() - is MessageEntityType.CustomEmoji -> TdApi.TextEntityTypeCustomEmoji(value.emojiId) - is MessageEntityType.Other -> return null - } - - return TdApi.TextEntity(start, safeLength, tdType) - } - - private fun MessageSendOptions.toTdMessageSendOptions(): TdApi.MessageSendOptions { - return TdApi.MessageSendOptions().apply { - this.disableNotification = silent - this.fromBackground = false - this.schedulingState = scheduleDate - ?.takeIf { it > 0 } - ?.let { TdApi.MessageSchedulingStateSendAtDate(it, 0) } - } - } - - override suspend fun viewMessages(chatId: Long, messageIds: LongArray, forceRead: Boolean): TdApi.Ok? { - val req = TdApi.ViewMessages().apply { - this.chatId = chatId - this.messageIds = messageIds - this.forceRead = forceRead - } - return safeExecute(req) - } - - override suspend fun readAllChatMentions(chatId: Long): TdApi.Ok? = safeExecute(TdApi.ReadAllChatMentions(chatId)) - override suspend fun readAllChatReactions(chatId: Long): TdApi.Ok? = safeExecute(TdApi.ReadAllChatReactions(chatId)) - override suspend fun setChatDraftMessage(chatId: Long, messageThreadId: Long, draftMessage: TdApi.DraftMessage?): TdApi.Ok? { - val req = TdApi.SetChatDraftMessage().apply { - this.chatId = chatId - this.draftMessage = draftMessage - } - return safeExecute(req) - } - - override suspend fun pinChatMessage(chatId: Long, messageId: Long, disableNotification: Boolean, onlyForSelf: Boolean): TdApi.Ok? { - val req = TdApi.PinChatMessage().apply { - this.chatId = chatId - this.messageId = messageId - this.disableNotification = disableNotification - this.onlyForSelf = onlyForSelf - } - return safeExecute(req) - } - - override suspend fun unpinChatMessage(chatId: Long, messageId: Long): TdApi.Ok? { - val req = TdApi.UnpinChatMessage().apply { - this.chatId = chatId - this.messageId = messageId - } - return safeExecute(req) - } - - override suspend fun addMessageReaction(chatId: Long, messageId: Long, reaction: String): TdApi.Ok? { - val reactionType = if (reaction.all { it.isDigit() }) { - TdApi.ReactionTypeCustomEmoji(reaction.toLong()) - } else { - TdApi.ReactionTypeEmoji(reaction) - } - - val request = TdApi.AddMessageReaction().apply { - this.chatId = chatId - this.messageId = messageId - this.reactionType = reactionType - this.isBig = false - this.updateRecentReactions = true - } - return safeExecute(request) - } - - override suspend fun removeMessageReaction(chatId: Long, messageId: Long, reaction: String): TdApi.Ok? { - val reactionType = if (reaction.all { it.isDigit() }) { - TdApi.ReactionTypeCustomEmoji(reaction.toLong()) - } else { - TdApi.ReactionTypeEmoji(reaction) - } - - val request = TdApi.RemoveMessageReaction().apply { - this.chatId = chatId - this.messageId = messageId - this.reactionType = reactionType - } - return safeExecute(request) - } - - override suspend fun setPollAnswer(chatId: Long, messageId: Long, optionIds: IntArray): TdApi.Ok? { - val req = TdApi.SetPollAnswer().apply { - this.chatId = chatId - this.messageId = messageId - this.optionIds = optionIds - } - return safeExecute(req) - } - - override suspend fun stopPoll(chatId: Long, messageId: Long): TdApi.Poll? { - val req = TdApi.StopPoll().apply { - this.chatId = chatId - this.messageId = messageId - } - return safeExecute(req) as TdApi.Poll? - } - - override suspend fun sendChatAction(chatId: Long, messageThreadId: Long, action: TdApi.ChatAction): TdApi.Ok? { - val req = TdApi.SendChatAction().apply { - this.chatId = chatId - this.action = action - this.topicId = if (messageThreadId != 0L) TdApi.MessageTopicThread(messageThreadId) else null - } - return safeExecute(req) - } - - override suspend fun getCallbackQueryAnswer(chatId: Long, messageId: Long, payload: TdApi.CallbackQueryPayload): TdApi.CallbackQueryAnswer? { - val req = TdApi.GetCallbackQueryAnswer().apply { - this.chatId = chatId - this.messageId = messageId - this.payload = payload - } - return safeExecute(req) - } - - override suspend fun openWebApp( - chatId: Long, - botUserId: Long, - url: String, - theme: ThemeParams? - ): WebAppInfoModel? { - val parameters = TdApi.WebAppOpenParameters().apply { - this.applicationName = "android" - this.mode = TdApi.WebAppOpenModeFullSize() - this.theme = theme?.toApi() - } - - val isMenuUrl = url.startsWith("menu://") - val normalizedUrl = if (isMenuUrl) url.removePrefix("menu://") else url - val botPrivateChatId = if (isMenuUrl) { - try { - gateway.execute(TdApi.CreatePrivateChat(botUserId, false))?.id - } catch (_: Exception) { - null - } - } else { - null - } - - val attempts = linkedSetOf>().apply { - add(chatId to url) - if (normalizedUrl != url) add(chatId to normalizedUrl) - if (botPrivateChatId != null && botPrivateChatId != chatId) { - add(botPrivateChatId to url) - if (normalizedUrl != url) add(botPrivateChatId to normalizedUrl) - } - } - - var lastError: Throwable? = null - - for ((targetChatId, targetUrl) in attempts) { - try { - val result = gateway.execute( - TdApi.OpenWebApp(targetChatId, botUserId, targetUrl, null, null, parameters) - ) - if (result is TdApi.WebAppInfo) { - return WebAppInfoModel(result.launchId, result.url) - } - } catch (e: TdLibException) { - lastError = e - } catch (e: Exception) { - lastError = e - } - } - - if (lastError != null) { - Log.e("TdMessageRemote", "Error executing OpenWebApp", lastError) - } - - return null - } - - override suspend fun onCallbackQueryBuy(chatId: Long, messageId: Long) { - val request = TdApi.GetPaymentForm().apply { - this.inputInvoice = TdApi.InputInvoiceMessage(chatId, messageId) - } - val result = safeExecute(request) - Log.d("MessageActionApi", "GetPaymentForm result: $result") - } - - override suspend fun onCallbackQuery(chatId: Long, messageId: Long, data: ByteArray) { - val request = TdApi.GetCallbackQueryAnswer().apply { - this.chatId = chatId - this.messageId = messageId - this.payload = TdApi.CallbackQueryPayloadData(data) - } - safeExecute(request) - } - - override suspend fun sendWebAppResult(botUserId: Long, data: String, buttonText: String) { - val request = TdApi.SendWebAppData(botUserId, buttonText, data) - safeExecute(request) - } - - override suspend fun closeWebApp(webAppLaunchId: Long): TdApi.Ok? { - val req = TdApi.CloseWebApp().apply { - this.webAppLaunchId = webAppLaunchId - } - return safeExecute(req) - } - - override suspend fun getPaymentForm(inputInvoice: TdApi.InputInvoice): TdApi.PaymentForm? { - val req = TdApi.GetPaymentForm().apply { - this.inputInvoice = inputInvoice - this.theme = TdApi.ThemeParameters() - } - return safeExecute(req) - } - - override suspend fun sendWebAppData(botUserId: Long, buttonText: String, data: String): TdApi.Ok? { - val req = TdApi.SendWebAppData().apply { - this.botUserId = botUserId - this.buttonText = buttonText - this.data = data - } - return safeExecute(req) - } - - override suspend fun handleUpdate(update: TdApi.Update) { - try { - processUpdate(update) - } catch (e: Exception) { - Log.e("TdMessageRemote", "CRASH in handleUpdate: ${e.message}", e) - } - } - - override suspend fun markAsRead(chatId: Long, messageId: Long) { - safeExecute(TdApi.ViewMessages(chatId, longArrayOf(messageId), null, true)) - } - - override suspend fun markAllMentionsAsRead(chatId: Long) { - safeExecute(TdApi.ReadAllChatMentions(chatId)) - } - - override suspend fun markAllReactionsAsRead(chatId: Long) { - safeExecute(TdApi.ReadAllChatReactions(chatId)) - } - - override suspend fun pinMessage(chatId: Long, messageId: Long, disableNotification: Boolean) { - val request = TdApi.PinChatMessage().apply { - this.chatId = chatId - this.messageId = messageId - this.disableNotification = disableNotification - this.onlyForSelf = false - } - safeExecute(request) - } - - override suspend fun unpinMessage(chatId: Long, messageId: Long) { - val request = TdApi.UnpinChatMessage().apply { - this.chatId = chatId - this.messageId = messageId - } - safeExecute(request) - } - - override suspend fun saveChatDraft(chatId: Long, draft: TdApi.DraftMessage?, replyToMsgId: Long?, threadId: Long?) { - val request = TdApi.SetChatDraftMessage().apply { - this.chatId = chatId - this.draftMessage = draft - if (threadId != null && threadId != 0L) { - this.topicId = TdApi.MessageTopicThread(threadId) - } - } - safeExecute(request) - } - - override suspend fun getChatDraft(chatId: Long, threadId: Long?): String? { - if (threadId != null && threadId != 0L) { - val result = safeExecute(TdApi.GetForumTopic(chatId, threadId.toInt())) - if (result is TdApi.ForumTopic) { - val draft = result.draftMessage - if (draft != null) { - val content = draft.inputMessageText - return if (content is TdApi.InputMessageText) { - content.text.text - } else { - null - } - } else { - return null - } - } else { - return null - } - } else { - val cachedChat = cache.getChat(chatId) - if (cachedChat != null) { - val draft = cachedChat.draftMessage - if (draft != null) { - val content = draft.inputMessageText - if (content is TdApi.InputMessageText) { - return content.text.text - } - } - } - - val result = safeExecute(TdApi.GetChat(chatId)) - if (result is TdApi.Chat) { - cache.putChat(result) - val draft = result.draftMessage - if (draft != null) { - val content = draft.inputMessageText - return if (content is TdApi.InputMessageText) { - content.text.text - } else { - null - } - } else { - return null - } - } else { - return null - } - } - } - - - private suspend fun processUpdate(update: TdApi.Update) { - when (update) { - is TdApi.UpdateNewMessage -> { - val message = update.message - cache.putMessage(message) - if (message.content is TdApi.MessagePoll) { - val poll = (message.content as TdApi.MessagePoll).poll - pollRepository.mapPollIdToMessage(poll.id, message.chatId, message.id) - } - scope.launch(dispatcherProvider.io) { - try { - val model = mapMessageToModel(message) - newMessageFlow.emit(model) - } catch (e: Exception) { Log.e("TdMessageRemote", "Error mapping NewMessage", e) } - } - } - is TdApi.UpdateMessageSendSucceeded -> { - val message = update.message - cache.removeMessage(message.chatId, update.oldMessageId) - cache.putMessage(message) - updateMessageIdInCache(message.chatId, update.oldMessageId, message.id) - if (message.content is TdApi.MessagePoll) { - val poll = (message.content as TdApi.MessagePoll).poll - pollRepository.mapPollIdToMessage(poll.id, message.chatId, message.id) - } - scope.launch(dispatcherProvider.io) { - try { - val model = mapMessageToModel(message) - messageIdUpdateFlow.emit(Triple(message.chatId, update.oldMessageId, model)) - } catch (e: Exception) { Log.e("TdMessageRemote", "Error handling SendSucceeded", e) } - } - } - is TdApi.UpdateMessageSendFailed -> { - cache.putMessage(update.message) - scope.launch(dispatcherProvider.io) { - val model = mapMessageToModel(update.message) - messageEditedFlow.emit(model) - } - } - is TdApi.UpdateMessageContent -> { - if (update.newContent is TdApi.MessagePoll) { - val poll = (update.newContent as TdApi.MessagePoll).poll - pollRepository.mapPollIdToMessage(poll.id, update.chatId, update.messageId) - } - cache.removeMessage(update.chatId, update.messageId) - refreshMessageDebounced(update.chatId, update.messageId) - } - is TdApi.UpdateMessageEdited -> { - cache.removeMessage(update.chatId, update.messageId) - refreshMessageDebounced(update.chatId, update.messageId) - } - is TdApi.UpdateMessageInteractionInfo -> { - cache.removeMessage(update.chatId, update.messageId) - refreshMessageDebounced(update.chatId, update.messageId) - } - is TdApi.UpdateMessageReaction -> { - cache.removeMessage(update.chatId, update.messageId) - } - is TdApi.UpdateMessageReactions -> { - cache.removeMessage(update.chatId, update.messageId) - refreshMessageDebounced(update.chatId, update.messageId) - } - is TdApi.UpdateMessageMentionRead -> { - cache.removeMessage(update.chatId, update.messageId) - cache.updateChat(update.chatId) { it.unreadMentionCount = update.unreadMentionCount } - refreshMessageDebounced(update.chatId, update.messageId) - } - is TdApi.UpdateFile -> { - scope.launch(dispatcherProvider.io) { handleFileUpdate(update.file) } - } - is TdApi.UpdatePollAnswer -> { - scope.launch(dispatcherProvider.io) { - pollRepository.getMessageIdByPollId(update.pollId)?.let { (chatId, messageId) -> - cache.removeMessage(chatId, messageId) - refreshAndEmitMessage(chatId, messageId) - } - } - } - is TdApi.UpdateChatReadOutbox -> { - cache.updateChat(update.chatId) { it.lastReadOutboxMessageId = update.lastReadOutboxMessageId } - scope.launch(dispatcherProvider.io) { - messageReadFlow.emit(ReadUpdate.Outbox(update.chatId, update.lastReadOutboxMessageId)) - refreshAndEmitMessage(update.chatId, update.lastReadOutboxMessageId) - } - } - is TdApi.UpdateChatReadInbox -> { - cache.updateChat(update.chatId) { it.lastReadInboxMessageId = update.lastReadInboxMessageId } - scope.launch(dispatcherProvider.io) { messageReadFlow.emit(ReadUpdate.Inbox(update.chatId, update.lastReadInboxMessageId)) } - } - is TdApi.UpdateDeleteMessages -> { - if (!update.fromCache) { - val messageIds = update.messageIds.toList() - scope.launch(dispatcherProvider.io) { - messageIds.forEach { cache.removeMessage(update.chatId, it) } - removeMessagesFromCache(update.chatId, messageIds) - messageDeletedFlow.emit(update.chatId to messageIds) - } - } - } - is TdApi.UpdateMessageIsPinned -> { scope.launch(dispatcherProvider.io) { pinnedMessageFlow.emit(update.chatId) } } - is TdApi.UpdateChatUnreadMentionCount -> { - cache.updateChat(update.chatId) { it.unreadMentionCount = update.unreadMentionCount } - } - - is TdApi.UpdateChatUnreadReactionCount -> { - cache.updateChat(update.chatId) { it.unreadReactionCount = update.unreadReactionCount } - } - else -> {} - } - } - - private fun refreshMessageDebounced(chatId: Long, messageId: Long) { - if (messageId == 0L) return - val key = chatId to messageId - refreshJobs[key]?.cancel() - val job = scope.launch(dispatcherProvider.io) { - delay(200) - try { refreshAndEmitMessage(chatId, messageId) } - finally { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) refreshJobs.remove(key, coroutineContext[Job]) - else refreshJobs.remove(key) - } - } - refreshJobs[key] = job - } - - private suspend fun refreshAndEmitMessage(chatId: Long, messageId: Long) { - if (messageId == 0L) return - val msg = getMessage(chatId, messageId) ?: return - val model = mapMessageToModel(msg) - messageEditedFlow.emit(model) - } - - private suspend fun mapMessageToModel(message: TdApi.Message): MessageModel { - val chat = getChat(message.chatId) - val model = if (chat != null) { - messageMapper.mapMessageToModelSync(message, chat.lastReadInboxMessageId, chat.lastReadOutboxMessageId, isChatOpen = true) - } else { - messageMapper.mapMessageToModel(message, isChatOpen = true) - } - val readDate = if (message.isOutgoing && model.isRead) messageMapper.getMessageReadDate(message.chatId, message.id, message.date) else 0 - return model.copy(readDate = readDate) - } - - override fun updateVisibleRange(chatId: Long, visibleIds: List, nearbyIds: List) { - fileDownloadQueue.updateVisibleRange(chatId, visibleIds, nearbyIds) - } - - override fun setChatOpened(chatId: Long) { fileDownloadQueue.setChatOpened(chatId) } - override fun setChatClosed(chatId: Long) { - fileDownloadQueue.setChatClosed(chatId) - } - - override fun enqueueDownload(fileId: Int, priority: Int, type: DownloadType, offset: Long, limit: Long, synchronous: Boolean) { - fileDownloadQueue.enqueue( - fileId, - priority, - when (type) { - DownloadType.VIDEO -> FileDownloadQueue.DownloadType.VIDEO - DownloadType.GIF -> FileDownloadQueue.DownloadType.GIF - DownloadType.STICKER -> FileDownloadQueue.DownloadType.STICKER - DownloadType.VIDEO_NOTE -> FileDownloadQueue.DownloadType.VIDEO_NOTE - DownloadType.DEFAULT -> FileDownloadQueue.DownloadType.DEFAULT - }, - offset, - limit, - synchronous - ) - } - - override suspend fun forwardMessage( - toChatId: Long, - fromChatId: Long, - messageId: Long - ) { - val request = TdApi.ForwardMessages().apply { - this.chatId = toChatId - this.fromChatId = fromChatId - this.messageIds = longArrayOf(messageId) - this.removeCaption = false - this.sendCopy = false - } - safeExecute(request) - } - - fun waitForUpload(fileId: Int): CompletableDeferred = fileDownloadQueue.waitForUpload(fileId) - - fun handleFileUpdate(file: TdApi.File) { - fileDownloadQueue.updateFileCache(file) - val isDC = file.local?.isDownloadingCompleted == true - val isD = file.local?.isDownloadingActive == true - val wasDownloading = lastDownloadActiveMap[file.id] == true - if (isD) { - lastDownloadActiveMap[file.id] = true - } else { - lastDownloadActiveMap.remove(file.id) - } - val isCancelled = wasDownloading && !isD && !isDC - val isUC = file.remote?.isUploadingCompleted == true - val isU = file.remote?.isUploadingActive == true - - if (isD || isDC || isCancelled) { - Log.d( - "DownloadDebug", - "td.updateFile: fileId=${file.id} isD=$isD isDC=$isDC isCancelled=$isCancelled downloaded=${file.local?.downloadedSize ?: 0}/${file.size} pathEmpty=${file.local?.path.isNullOrEmpty()}" - ) - } - - if (isDC) { - fileDownloadQueue.notifyDownloadComplete(file.id) - lastProgressMap.remove(file.id) - fileIdToCustomEmojiId[file.id]?.let { customEmojiId -> - customEmojiPaths[customEmojiId] = file.local?.path ?: "" - } - - val entries = fileIdToMessageMap[file.id] - if (!entries.isNullOrEmpty()) { - scope.launch { - entries.forEach { (_, messageId) -> - messageDownloadCompletedFlow.emit( - Triple(messageId, file.id, file.local?.path ?: "") - ) - messageDownloadProgressFlow.emit(messageId to 1.0f) - } - } - } else if (fileDownloadQueue.registry.standaloneFileIds.contains(file.id)) { - scope.launch { - messageDownloadCompletedFlow.emit( - Triple(file.id.toLong(), file.id, file.local?.path ?: "") - ) - messageDownloadProgressFlow.emit(file.id.toLong() to 1.0f) - } - fileDownloadQueue.registry.standaloneFileIds.remove(file.id) - } - updateMessageWithFile(file.id) - } else if (isD) { - val p = - if (file.size > 0 && file.local != null) file.local.downloadedSize.toFloat() / file.size.toFloat() else 0f - val pInt = (p * 100).toInt() - if (lastProgressMap[file.id] != pInt) { - lastProgressMap[file.id] = pInt - val entries = fileIdToMessageMap[file.id] - if (!entries.isNullOrEmpty()) { - scope.launch { - entries.forEach { (_, messageId) -> - messageDownloadProgressFlow.emit(messageId to p) - } - } - } else if (fileDownloadQueue.registry.standaloneFileIds.contains(file.id)) { - scope.launch { messageDownloadProgressFlow.emit(file.id.toLong() to p) } - } - } - } else if (isCancelled) { - lastProgressMap.remove(file.id) - Log.d("DownloadDebug", "td.downloadCancelled.emit: fileId=${file.id}") - val entries = fileIdToMessageMap[file.id] - if (!entries.isNullOrEmpty()) { - scope.launch { - entries.forEach { (_, messageId) -> - messageDownloadCancelledFlow.emit(messageId) - } - } - } else if (fileDownloadQueue.registry.standaloneFileIds.contains(file.id)) { - scope.launch { messageDownloadCancelledFlow.emit(file.id.toLong()) } - } - } - - if (isUC) { - fileDownloadQueue.notifyUploadComplete(file.id) - lastProgressMap.remove(file.id xor 0x55555555) - val entries = fileIdToMessageMap[file.id] - if (!entries.isNullOrEmpty()) { - scope.launch { - entries.forEach { (_, messageId) -> - messageUploadProgressFlow.emit(messageId to 1.0f) - } - } - } - updateMessageWithFile(file.id) - } else if (isU) { - val p = - if (file.size > 0 && file.remote != null) file.remote.uploadedSize.toFloat() / file.size.toFloat() else 0f - val pInt = (p * 100).toInt() - if (lastProgressMap[file.id xor 0x55555555] != pInt) { - lastProgressMap[file.id xor 0x55555555] = pInt - val entries = fileIdToMessageMap[file.id] - if (!entries.isNullOrEmpty()) { - scope.launch { - entries.forEach { (_, messageId) -> - messageUploadProgressFlow.emit(messageId to p) - } - } - } - } - } - } - - override fun registerFileForMessage(fileId: Int, chatId: Long, messageId: Long) { - fileDownloadQueue.registry.register(fileId, chatId, messageId) - } - - private fun removeMessagesFromCache(chatId: Long, messageIds: List) { - fileDownloadQueue.registry.removeMessages(chatId, messageIds) - } - - private fun updateMessageIdInCache(chatId: Long, oldMId: Long, newMId: Long) { - fileDownloadQueue.registry.updateMessageId(chatId, oldMId, newMId) - } - - override fun isFileQueued(fileId: Int): Boolean = fileDownloadQueue.isFileQueued(fileId) - - private fun updateMessageWithFile(fileId: Int) { - val entries = fileIdToMessageMap[fileId] ?: return - entries.toList().forEach { (chatId, messageId) -> - val key = chatId to messageId - messageUpdateJobs[key]?.cancel() - val job = scope.launch { - delay(150) - val msg = getMessage(chatId, messageId) ?: return@launch - try { - messageEditedFlow.emit(mapMessageToModel(msg)) - } catch (e: CancellationException) { - throw e - } catch (e: Exception) { - Log.e("TdMessageRemote", "Error emitting edited message", e) - } - } - job.invokeOnCompletion { messageUpdateJobs.remove(key, job) } - messageUpdateJobs[key] = job - } - } - - fun clear() { - refreshJobs.values.forEach { it.cancel() }; refreshJobs.clear() - messageUpdateJobs.values.forEach { it.cancel() }; messageUpdateJobs.clear() - lastProgressMap.clear() - } -} diff --git a/data/src/main/java/org/monogram/data/datasource/remote/TdPrivacyRemoteDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/TdPrivacyRemoteDataSource.kt deleted file mode 100644 index b049a27d..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/TdPrivacyRemoteDataSource.kt +++ /dev/null @@ -1,70 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.monogram.data.core.coRunCatching -import org.drinkless.tdlib.TdApi -import org.monogram.data.gateway.TelegramGateway - -class TdPrivacyRemoteDataSource( - private val gateway: TelegramGateway -) : PrivacyRemoteDataSource { - - override suspend fun getPrivacyRules( - setting: TdApi.UserPrivacySetting - ): List = - coRunCatching { - gateway.execute(TdApi.GetUserPrivacySettingRules(setting)).rules.toList() - }.getOrDefault(emptyList()) - - override suspend fun setPrivacyRules( - setting: TdApi.UserPrivacySetting, - rules: TdApi.UserPrivacySettingRules - ) { - gateway.execute(TdApi.SetUserPrivacySettingRules(setting, rules)) - } - - override suspend fun getBlockedUsers(): List = - coRunCatching { - gateway.execute(TdApi.GetBlockedMessageSenders(TdApi.BlockListMain(), 0, 100)) - .senders - .mapNotNull { (it as? TdApi.MessageSenderUser)?.userId } - }.getOrDefault(emptyList()) - - override suspend fun blockUser(userId: Long) { - gateway.execute( - TdApi.SetMessageSenderBlockList(TdApi.MessageSenderUser(userId), TdApi.BlockListMain()) - ) - } - - override suspend fun unblockUser(userId: Long) { - gateway.execute( - TdApi.SetMessageSenderBlockList(TdApi.MessageSenderUser(userId), null) - ) - } - - override suspend fun deleteAccount(reason: String, password: String) { - gateway.execute(TdApi.DeleteAccount(reason, password)) - } - - override suspend fun getAccountTtl(): Int = - coRunCatching { - gateway.execute(TdApi.GetAccountTtl()).days - }.getOrDefault(180) - - override suspend fun setAccountTtl(days: Int) { - gateway.execute(TdApi.SetAccountTtl(TdApi.AccountTtl(days))) - } - - override suspend fun getPasswordState(): Boolean = - coRunCatching { - gateway.execute(TdApi.GetPasswordState()).hasPassword - }.getOrDefault(false) - - override suspend fun getOption(name: String): Boolean = - coRunCatching { - (gateway.execute(TdApi.GetOption(name)) as? TdApi.OptionValueBoolean)?.value ?: false - }.getOrDefault(false) - - override suspend fun setOption(name: String, value: Boolean) { - gateway.execute(TdApi.SetOption(name, TdApi.OptionValueBoolean(value))) - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/remote/TdProxyRemoteDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/TdProxyRemoteDataSource.kt deleted file mode 100644 index fbeac836..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/TdProxyRemoteDataSource.kt +++ /dev/null @@ -1,52 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.monogram.data.core.coRunCatching -import org.drinkless.tdlib.TdApi -import org.monogram.data.gateway.TelegramGateway -import org.monogram.data.mapper.toApi -import org.monogram.data.mapper.toDomain -import org.monogram.domain.models.ProxyModel -import org.monogram.domain.models.ProxyTypeModel - -class TdProxyRemoteDataSource( - private val gateway: TelegramGateway -) : ProxyRemoteDataSource { - override suspend fun getProxies(): List = - gateway.execute(TdApi.GetProxies()).proxies.map { it.toDomain() } - - override suspend fun addProxy( - server: String, port: Int, enable: Boolean, type: ProxyTypeModel - ): ProxyModel = gateway.execute(TdApi.AddProxy(TdApi.Proxy(server, port, type.toApi()), enable)).toDomain() - - override suspend fun editProxy( - proxyId: Int, server: String, port: Int, enable: Boolean, type: ProxyTypeModel - ): ProxyModel = gateway.execute(TdApi.EditProxy(proxyId, TdApi.Proxy(server, port, type.toApi()), enable)).toDomain() - - override suspend fun enableProxy(proxyId: Int) : Boolean { - val result = coRunCatching { gateway.execute(TdApi.EnableProxy(proxyId)) } - return result.isSuccess - } - - override suspend fun disableProxy() { - gateway.execute(TdApi.DisableProxy()) - } - - override suspend fun removeProxy(proxyId: Int) { - gateway.execute(TdApi.RemoveProxy(proxyId)) - } - - override suspend fun pingProxy(server: String, port: Int, type: ProxyTypeModel): Long { - val result = gateway.execute(TdApi.PingProxy(TdApi.Proxy(server, port, type.toApi()))) - return (result.seconds * 1000).toLong() - } - - override suspend fun testProxy(server: String, port: Int, type: ProxyTypeModel): Long { - val start = System.currentTimeMillis() - gateway.execute(TdApi.TestProxy(TdApi.Proxy(server, port, type.toApi()), 0, 10.0)) - return System.currentTimeMillis() - start - } - - override suspend fun setOption(key: String, value: TdApi.OptionValue) { - gateway.execute(TdApi.SetOption(key, value)) - } -} diff --git a/data/src/main/java/org/monogram/data/datasource/remote/TdSettingsRemoteDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/TdSettingsRemoteDataSource.kt deleted file mode 100644 index 56d27828..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/TdSettingsRemoteDataSource.kt +++ /dev/null @@ -1,126 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.monogram.data.core.coRunCatching -import android.util.Log -import org.drinkless.tdlib.TdApi -import org.monogram.data.gateway.TelegramGateway -import org.monogram.data.infra.FileDownloadQueue - -class TdSettingsRemoteDataSource( - private val gateway: TelegramGateway, - private val fileQueue: FileDownloadQueue -) : SettingsRemoteDataSource { - - override suspend fun getScopeNotificationSettings( - scope: TdApi.NotificationSettingsScope - ): TdApi.ScopeNotificationSettings? = - coRunCatching { gateway.execute(TdApi.GetScopeNotificationSettings(scope)) }.getOrNull() - - override suspend fun getActiveSessions(): TdApi.Sessions? = - coRunCatching { gateway.execute(TdApi.GetActiveSessions()) }.getOrNull() - - override suspend fun getInstalledBackgrounds(forDarkTheme: Boolean): TdApi.Backgrounds? = - coRunCatching { - val result = gateway.execute(TdApi.GetInstalledBackgrounds(forDarkTheme)) - result.backgrounds.forEach { bg -> - bg.document?.thumbnail?.file?.let { file -> - if (file.local.path.isEmpty()) { - fileQueue.enqueue(file.id, 1, FileDownloadQueue.DownloadType.DEFAULT) - } - } - } - result - }.getOrNull() - - override suspend fun getStorageStatistics(chatLimit: Int): TdApi.StorageStatistics? = - coRunCatching { gateway.execute(TdApi.GetStorageStatistics(chatLimit)) }.getOrNull() - - override suspend fun getNetworkStatistics(): TdApi.NetworkStatistics? = - coRunCatching { - Log.d("NetworkStats", "Fetching network statistics...") - val stats = gateway.execute(TdApi.GetNetworkStatistics(true)) - Log.d("NetworkStats", "Received stats with ${stats.entries.size} entries") - stats.entries.forEachIndexed { index, entry -> - when (entry) { - is TdApi.NetworkStatisticsEntryFile -> { - Log.d( - "NetworkStats", - "Entry $index: File - Type: ${entry.fileType}, Network: ${entry.networkType}, Sent: ${entry.sentBytes}, Received: ${entry.receivedBytes}" - ) - } - - is TdApi.NetworkStatisticsEntryCall -> { - Log.d( - "NetworkStats", - "Entry $index: Call - Network: ${entry.networkType}, Sent: ${entry.sentBytes}, Received: ${entry.receivedBytes}, Duration: ${entry.duration}" - ) - } - } - } - stats - }.onFailure { - Log.e("NetworkStats", "Failed to fetch network statistics", it) - }.getOrNull() - - override suspend fun getOption(name: String): TdApi.OptionValue? = - coRunCatching { gateway.execute(TdApi.GetOption(name)) }.getOrNull() - - override suspend fun getChatNotificationSettingsExceptions( - scope: TdApi.NotificationSettingsScope, - compareSound: Boolean - ): TdApi.Chats? = - coRunCatching { - gateway.execute(TdApi.GetChatNotificationSettingsExceptions(scope, compareSound)) - }.getOrNull() - - override suspend fun setScopeNotificationSettings( - scope: TdApi.NotificationSettingsScope, - settings: TdApi.ScopeNotificationSettings - ) { - coRunCatching { gateway.execute(TdApi.SetScopeNotificationSettings(scope, settings)) } - } - - override suspend fun setChatNotificationSettings( - chatId: Long, - settings: TdApi.ChatNotificationSettings - ) { - coRunCatching { gateway.execute(TdApi.SetChatNotificationSettings(chatId, settings)) } - } - - override suspend fun setOption(name: String, value: TdApi.OptionValue) { - coRunCatching { gateway.execute(TdApi.SetOption(name, value)) } - } - - override suspend fun terminateSession(sessionId: Long): Boolean = - coRunCatching { gateway.execute(TdApi.TerminateSession(sessionId)); true }.getOrDefault(false) - - override suspend fun confirmQrCode(link: String): Boolean = - coRunCatching { gateway.execute(TdApi.ConfirmQrCodeAuthentication(link)); true }.getOrDefault(false) - - override suspend fun optimizeStorage( - size: Long, - ttl: Int, - count: Int, - immunityDelay: Int, - chatIds: LongArray?, - returnDeletedFileStatistics: Boolean, - chatLimit: Int - ): Boolean = - coRunCatching { - gateway.execute( - TdApi.OptimizeStorage(size, ttl, count, immunityDelay, null, chatIds, null, returnDeletedFileStatistics, chatLimit) - ) - true - }.getOrDefault(false) - - override suspend fun resetNetworkStatistics(): Boolean = - coRunCatching { - Log.d("NetworkStats", "Resetting network statistics...") - gateway.execute(TdApi.ResetNetworkStatistics()) - true - }.getOrDefault(false) - - override suspend fun downloadFile(fileId: Int, priority: Int) { - fileQueue.enqueue(fileId, priority, FileDownloadQueue.DownloadType.DEFAULT) - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/remote/TdStickerRemoteSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/TdStickerRemoteSource.kt deleted file mode 100644 index ab5c3697..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/TdStickerRemoteSource.kt +++ /dev/null @@ -1,183 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.monogram.data.core.coRunCatching -import kotlinx.coroutines.async -import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.coroutineScope -import org.drinkless.tdlib.TdApi -import org.monogram.data.gateway.TelegramGateway -import org.monogram.data.mapper.toApi -import org.monogram.data.mapper.toDomain -import org.monogram.domain.models.GifModel -import org.monogram.domain.models.StickerModel -import org.monogram.domain.models.StickerSetModel -import org.monogram.domain.models.StickerType - -class TdStickerRemoteSource( - private val gateway: TelegramGateway -) : StickerRemoteSource { - override suspend fun getInstalledStickerSets(type: StickerType): List { - return coRunCatching { - gateway.execute(TdApi.GetInstalledStickerSets(type.toApi())) - .sets - .mapNotNull { getStickerSet(it.id) } - }.getOrDefault(emptyList()) - } - - override suspend fun getArchivedStickerSets(type: StickerType): List { - return coRunCatching { - gateway.execute(TdApi.GetArchivedStickerSets(type.toApi(), 0, 100)) - .sets - .mapNotNull { getStickerSet(it.id) } - }.getOrDefault(emptyList()) - } - - override suspend fun getStickerSet(setId: Long): StickerSetModel? { - return coRunCatching { - gateway.execute(TdApi.GetStickerSet(setId)).toDomain() - }.getOrNull() - } - - override suspend fun getStickerSetByName(name: String): StickerSetModel? { - return coRunCatching { - gateway.execute(TdApi.SearchStickerSet(name, false)).toDomain() - }.getOrNull() - } - - override suspend fun getRecentStickers(): List { - return coRunCatching { - gateway.execute(TdApi.GetRecentStickers(false)) - .stickers - .map { it.toDomain() } - }.getOrDefault(emptyList()) - } - - override suspend fun toggleStickerSetInstalled(setId: Long, isInstalled: Boolean) { - coRunCatching { gateway.execute(TdApi.ChangeStickerSet(setId, isInstalled, false)) } - } - - override suspend fun toggleStickerSetArchived(setId: Long, isArchived: Boolean) { - coRunCatching { gateway.execute(TdApi.ChangeStickerSet(setId, false, isArchived)) } - } - - override suspend fun reorderStickerSets(type: StickerType, setIds: List) { - coRunCatching { - gateway.execute(TdApi.ReorderInstalledStickerSets(type.toApi(), setIds.toLongArray())) - } - } - - override suspend fun getEmojiCategories(): List { - val types = listOf( - TdApi.EmojiCategoryTypeDefault(), - TdApi.EmojiCategoryTypeRegularStickers(), - TdApi.EmojiCategoryTypeEmojiStatus(), - TdApi.EmojiCategoryTypeChatPhoto() - ) - return coroutineScope { - types - .map { type -> async { coRunCatching { gateway.execute(TdApi.GetEmojiCategories(type)) }.getOrNull() } } - .awaitAll() - .asSequence() - .filterNotNull() - .flatMap { it.categories.asSequence() } - .mapNotNull { it.source as? TdApi.EmojiCategorySourceSearch } - .flatMap { it.emojis.asSequence() } - .toList() - } - } - - override suspend fun getMessageAvailableReactions(chatId: Long, messageId: Long): List { - return coRunCatching { - val result = gateway.execute(TdApi.GetMessageAvailableReactions(chatId, messageId, 32)) - buildSet { - result.topReactions.forEach { (it.type as? TdApi.ReactionTypeEmoji)?.let { r -> add(r.emoji) } } - result.recentReactions.forEach { (it.type as? TdApi.ReactionTypeEmoji)?.let { r -> add(r.emoji) } } - result.popularReactions.forEach { (it.type as? TdApi.ReactionTypeEmoji)?.let { r -> add(r.emoji) } } - }.toList() - }.getOrDefault(emptyList()) - } - - override suspend fun searchEmojis(query: String): List { - return coRunCatching { - gateway.execute(TdApi.SearchEmojis(query, emptyArray())) - .emojiKeywords - .map { it.emoji } - }.getOrDefault(emptyList()) - } - - override suspend fun searchCustomEmojis(query: String): List { - return coRunCatching { - gateway.execute( - TdApi.SearchStickers(TdApi.StickerTypeCustomEmoji(), "", query, emptyArray(), 0, 100) - ).stickers.map { it.toDomain() } - }.getOrDefault(emptyList()) - } - - override suspend fun searchStickers(query: String): List { - return coRunCatching { - gateway.execute( - TdApi.SearchStickers(TdApi.StickerTypeRegular(), "", query, emptyArray(), 0, 100) - ).stickers.map { it.toDomain() } - }.getOrDefault(emptyList()) - } - - override suspend fun searchStickerSets(query: String): List { - return coRunCatching { - gateway.execute(TdApi.SearchStickerSets(TdApi.StickerTypeRegular(), query)) - .sets - .mapNotNull { getStickerSet(it.id) } - }.getOrDefault(emptyList()) - } - - override suspend fun getSavedGifs(): List { - return coRunCatching { - val recentGifs = coRunCatching { - gateway.execute(TdApi.GetSavedAnimations()) - .animations - .map { animation -> - GifModel( - id = animation.animation.remote?.id?.takeIf { it.isNotEmpty() } ?: animation.animation.id.toString(), - fileId = animation.animation.id.toLong(), - thumbFileId = animation.thumbnail?.file?.id?.toLong(), - width = animation.width, - height = animation.height - ) - } - }.getOrDefault(emptyList()) - - when { - recentGifs.isNotEmpty() -> { - return@coRunCatching recentGifs - } - else -> return searchGifs("") - } - }.getOrDefault(emptyList()) - } - - override suspend fun addSavedGif(path: String) { - coRunCatching { gateway.execute(TdApi.AddSavedAnimation(TdApi.InputFileLocal(path))) } - } - - override suspend fun searchGifs(query: String): List { - return coRunCatching { - val chat = gateway.execute(TdApi.SearchPublicChat("gif")) - val type = chat.type as? TdApi.ChatTypePrivate ?: return emptyList() - gateway.execute(TdApi.GetInlineQueryResults(type.userId, chat.id, null, query, "")) - .results - .mapNotNull { item -> - if (item !is TdApi.InlineQueryResultAnimation) return@mapNotNull null - GifModel( - id = item.id, - fileId = item.animation.animation.id.toLong(), - thumbFileId = item.animation.thumbnail?.file?.id?.toLong(), - width = item.animation.width, - height = item.animation.height - ) - } - }.getOrDefault(emptyList()) - } - - override suspend fun clearRecentStickers() { - coRunCatching { gateway.execute(TdApi.ClearRecentStickers()) } - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/remote/TdUpdateRemoteDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/TdUpdateRemoteDataSource.kt deleted file mode 100644 index 7b14bd8e..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/TdUpdateRemoteDataSource.kt +++ /dev/null @@ -1,53 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.monogram.data.core.coRunCatching -import android.util.Log -import org.drinkless.tdlib.TdApi -import org.monogram.data.gateway.TelegramGateway -import org.monogram.data.mapper.toUpdateInfo -import org.monogram.domain.models.UpdateInfo - -class TdUpdateRemoteDataSource( - private val gateway: TelegramGateway, - private val channelId: Long = -1003566234286L -) : UpdateRemoteDateSource { - - private val tag = "TdUpdateRemote" - private val channelUsername = "monogram_apks" - - override suspend fun fetchLatestUpdate(): UpdateInfo? { - return coRunCatching { - val resolvedChatId = resolveUpdateChatId() - val messages = gateway.execute(TdApi.GetChatHistory(resolvedChatId, 0, 0, 1, false)) - val doc = messages.messages - .firstOrNull() - ?.content as? TdApi.MessageDocument - doc?.toUpdateInfo() - }.getOrNull() - } - - private suspend fun resolveUpdateChatId(): Long { - val chat = coRunCatching { - gateway.execute(TdApi.SearchPublicChat(channelUsername)) as? TdApi.Chat - }.getOrNull() - - return if (chat?.id != null) { - chat.id - } else { - Log.w(tag, "Unable to resolve @$channelUsername, using fallback chatId=$channelId") - channelId - } - } - - override suspend fun getTdLibVersion(): String { - return coRunCatching { - (gateway.execute(TdApi.GetOption("version")) as? TdApi.OptionValueString)?.value - }.getOrNull() ?: "Unknown" - } - - override suspend fun getTdLibCommitHash(): String { - return coRunCatching { - (gateway.execute(TdApi.GetOption("commit_hash")) as? TdApi.OptionValueString)?.value - }.getOrNull() ?: "" - } -} diff --git a/data/src/main/java/org/monogram/data/datasource/remote/TdUserRemoteDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/TdUserRemoteDataSource.kt deleted file mode 100644 index 0d74961b..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/TdUserRemoteDataSource.kt +++ /dev/null @@ -1,217 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.drinkless.tdlib.TdApi -import org.monogram.data.core.coRunCatching -import org.monogram.data.gateway.TelegramGateway - -class TdUserRemoteDataSource( - private val gateway: TelegramGateway -) : UserRemoteDataSource { - - override suspend fun getUser(userId: Long): TdApi.User? { - if (userId == 0L) return null - return coRunCatching { gateway.execute(TdApi.GetUser(userId)) }.getOrNull() - } - - override suspend fun getMe(): TdApi.User? = - coRunCatching { gateway.execute(TdApi.GetMe()) }.getOrNull() - - override suspend fun getUserFullInfo(userId: Long): TdApi.UserFullInfo? { - if (userId == 0L) return null - return coRunCatching { gateway.execute(TdApi.GetUserFullInfo(userId)) }.getOrNull() - } - - override suspend fun getSupergroupFullInfo(supergroupId: Long): TdApi.SupergroupFullInfo? { - if (supergroupId == 0L) return null - return coRunCatching { gateway.execute(TdApi.GetSupergroupFullInfo(supergroupId)) }.getOrNull() - } - - override suspend fun getBasicGroupFullInfo(basicGroupId: Long): TdApi.BasicGroupFullInfo? = - coRunCatching { gateway.execute(TdApi.GetBasicGroupFullInfo(basicGroupId)) }.getOrNull() - - override suspend fun getSupergroup(supergroupId: Long): TdApi.Supergroup? { - if (supergroupId == 0L) return null - return coRunCatching { gateway.execute(TdApi.GetSupergroup(supergroupId)) }.getOrNull() - } - - override suspend fun getChat(chatId: Long): TdApi.Chat? { - if (chatId == 0L) return null - return coRunCatching { gateway.execute(TdApi.GetChat(chatId)) }.getOrNull() - } - - override suspend fun getMessage(chatId: Long, messageId: Long): TdApi.Message? = - coRunCatching { gateway.execute(TdApi.GetMessage(chatId, messageId)) }.getOrNull() - - override suspend fun getUserProfilePhotos( - userId: Long, - offset: Int, - limit: Int - ): TdApi.ChatPhotos? = - coRunCatching { gateway.execute(TdApi.GetUserProfilePhotos(userId, offset, limit)) }.getOrNull() - - override suspend fun getContacts(): TdApi.Users? = - coRunCatching { gateway.execute(TdApi.GetContacts()) }.getOrNull() - - override suspend fun searchContacts(query: String): TdApi.Users? = - coRunCatching { gateway.execute(TdApi.SearchContacts(query, 50)) }.getOrNull() - - override suspend fun addContact(userId: Long, contact: TdApi.ImportedContact, sharePhoneNumber: Boolean) { - coRunCatching { - gateway.execute(TdApi.AddContact(userId, contact, sharePhoneNumber)) - }.getOrThrow() - } - - override suspend fun removeContacts(userIds: LongArray) { - coRunCatching { - gateway.execute(TdApi.RemoveContacts(userIds)) - } - } - - override suspend fun searchPublicChat(username: String): TdApi.Chat? = - coRunCatching { gateway.execute(TdApi.SearchPublicChat(username)) }.getOrNull() - - override suspend fun getChatMember(chatId: Long, userId: Long): TdApi.ChatMember? = - coRunCatching { - val chat = gateway.execute(TdApi.GetChat(chatId)) - val me = gateway.execute(TdApi.GetMe()) - val requestingOtherUser = userId != me.id - val type = chat.type - if (requestingOtherUser && type is TdApi.ChatTypeBasicGroup) { - if (type.basicGroupId == 0L) return@coRunCatching null - val basicGroup = gateway.execute(TdApi.GetBasicGroup(type.basicGroupId)) - val canGetOthers = basicGroup.status is TdApi.ChatMemberStatusAdministrator || - basicGroup.status is TdApi.ChatMemberStatusCreator - if (!canGetOthers) return@coRunCatching null - } - if (type is TdApi.ChatTypeSupergroup) { - if (type.supergroupId == 0L) return@coRunCatching null - val supergroup = gateway.execute(TdApi.GetSupergroup(type.supergroupId)) - val isMember = supergroup.status !is TdApi.ChatMemberStatusLeft && - supergroup.status !is TdApi.ChatMemberStatusBanned - if (!isMember) return@coRunCatching null - - if (!requestingOtherUser) { - return@coRunCatching gateway.execute(TdApi.GetChatMember(chatId, TdApi.MessageSenderUser(userId))) - } - - val status = supergroup.status - val canGetOthers = status is TdApi.ChatMemberStatusAdministrator || - status is TdApi.ChatMemberStatusCreator - if (!canGetOthers) return@coRunCatching null - } - gateway.execute(TdApi.GetChatMember(chatId, TdApi.MessageSenderUser(userId))) - }.getOrElse { e -> - // Handle 400 CHANNEL_PRIVATE and other errors gracefully - null - } - - override suspend fun getSupergroupMembers( - supergroupId: Long, - filter: TdApi.SupergroupMembersFilter, - offset: Int, - limit: Int - ): TdApi.ChatMembers? = - coRunCatching { - gateway.execute(TdApi.GetSupergroupMembers(supergroupId, filter, offset, limit)) - }.getOrNull() - - override suspend fun getBasicGroupMembers(basicGroupId: Long): TdApi.BasicGroupFullInfo? = - coRunCatching { gateway.execute(TdApi.GetBasicGroupFullInfo(basicGroupId)) }.getOrNull() - - override suspend fun getPremiumState(): TdApi.PremiumState? = - coRunCatching { gateway.execute(TdApi.GetPremiumState()) }.getOrNull() - - override suspend fun getPremiumFeatures(source: TdApi.PremiumSource): TdApi.PremiumFeatures? = - coRunCatching { gateway.execute(TdApi.GetPremiumFeatures(source)) }.getOrNull() - - override suspend fun getPremiumLimit(limitType: TdApi.PremiumLimitType): TdApi.PremiumLimit? = - coRunCatching { gateway.execute(TdApi.GetPremiumLimit(limitType)) }.getOrNull() - - override suspend fun getBotFullInfo(userId: Long): TdApi.UserFullInfo? { - if (userId == 0L) return null - return coRunCatching { gateway.execute(TdApi.GetUserFullInfo(userId)) }.getOrNull() - } - - override suspend fun getChatStatistics(chatId: Long, isDark: Boolean): TdApi.ChatStatistics? = - coRunCatching { gateway.execute(TdApi.GetChatStatistics(chatId, isDark)) }.getOrNull() - - override suspend fun getChatRevenueStatistics( - chatId: Long, - isDark: Boolean - ): TdApi.ChatRevenueStatistics? = - coRunCatching { - gateway.execute(TdApi.GetChatRevenueStatistics(chatId, isDark)) - }.getOrNull() - - override suspend fun getStatisticsGraph( - chatId: Long, - token: String, - x: Long - ): TdApi.StatisticalGraph? = - coRunCatching { gateway.execute(TdApi.GetStatisticalGraph(chatId, token, x)) }.getOrNull() - - override suspend fun logout() { - gateway.execute(TdApi.LogOut()) - } - - override suspend fun setName(firstName: String, lastName: String) { - gateway.execute(TdApi.SetName(firstName, lastName)) - } - - override suspend fun setBio(bio: String) { - gateway.execute(TdApi.SetBio(bio)) - } - - override suspend fun setUsername(username: String) { - gateway.execute(TdApi.SetUsername(username)) - } - - override suspend fun setEmojiStatus(customEmojiId: Long?) { - val status = customEmojiId?.let { - TdApi.EmojiStatus(TdApi.EmojiStatusTypeCustomEmoji(it), 0) - } - gateway.execute(TdApi.SetEmojiStatus(status)) - } - - override suspend fun setProfilePhoto(path: String) { - gateway.execute( - TdApi.SetProfilePhoto(TdApi.InputChatPhotoStatic(TdApi.InputFileLocal(path)), true) - ) - } - - override suspend fun setBirthdate(birthdate: TdApi.Birthdate?) { - gateway.execute(TdApi.SetBirthdate(birthdate)) - } - - override suspend fun setPersonalChat(chatId: Long) { - gateway.execute(TdApi.SetPersonalChat(chatId)) - } - - override suspend fun setBusinessBio(bio: String) { - gateway.execute(TdApi.SetBusinessAccountBio("", bio)) - } - - override suspend fun setBusinessLocation(location: TdApi.BusinessLocation?) { - gateway.execute(TdApi.SetBusinessLocation(location)) - } - - override suspend fun setBusinessOpeningHours(hours: TdApi.BusinessOpeningHours?) { - gateway.execute(TdApi.SetBusinessOpeningHours(hours)) - } - - override suspend fun toggleUsernameIsActive(username: String, isActive: Boolean) { - gateway.execute(TdApi.ToggleUsernameIsActive(username, isActive)) - } - - override suspend fun reorderActiveUsernames(usernames: Array) { - gateway.execute(TdApi.ReorderActiveUsernames(usernames)) - } - - override suspend fun setChatMemberStatus( - chatId: Long, - userId: Long, - status: TdApi.ChatMemberStatus - ) { - gateway.execute(TdApi.SetChatMemberStatus(chatId, TdApi.MessageSenderUser(userId), status)) - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/remote/UpdateRemoteDateSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/UpdateRemoteDateSource.kt deleted file mode 100644 index b2dade11..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/UpdateRemoteDateSource.kt +++ /dev/null @@ -1,9 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.monogram.domain.models.UpdateInfo - -interface UpdateRemoteDateSource { - suspend fun fetchLatestUpdate(): UpdateInfo? - suspend fun getTdLibVersion(): String - suspend fun getTdLibCommitHash(): String -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/datasource/remote/UserRemoteDataSource.kt b/data/src/main/java/org/monogram/data/datasource/remote/UserRemoteDataSource.kt deleted file mode 100644 index 59e8e4e1..00000000 --- a/data/src/main/java/org/monogram/data/datasource/remote/UserRemoteDataSource.kt +++ /dev/null @@ -1,54 +0,0 @@ -package org.monogram.data.datasource.remote - -import org.drinkless.tdlib.TdApi - -interface UserRemoteDataSource { - suspend fun getUser(userId: Long): TdApi.User? - suspend fun getMe(): TdApi.User? - suspend fun getUserFullInfo(userId: Long): TdApi.UserFullInfo? - suspend fun getSupergroupFullInfo(supergroupId: Long): TdApi.SupergroupFullInfo? - suspend fun getBasicGroupFullInfo(basicGroupId: Long): TdApi.BasicGroupFullInfo? - suspend fun getSupergroup(supergroupId: Long): TdApi.Supergroup? - suspend fun getChat(chatId: Long): TdApi.Chat? - suspend fun getMessage(chatId: Long, messageId: Long): TdApi.Message? - suspend fun getUserProfilePhotos(userId: Long, offset: Int, limit: Int): TdApi.ChatPhotos? - suspend fun getContacts(): TdApi.Users? - suspend fun searchContacts(query: String): TdApi.Users? - suspend fun addContact(userId: Long, contact: TdApi.ImportedContact, sharePhoneNumber: Boolean) - suspend fun removeContacts(userIds: LongArray) - suspend fun searchPublicChat(username: String): TdApi.Chat? - suspend fun getChatMember(chatId: Long, userId: Long): TdApi.ChatMember? - suspend fun getSupergroupMembers( - supergroupId: Long, - filter: TdApi.SupergroupMembersFilter, - offset: Int, - limit: Int - ): TdApi.ChatMembers? - suspend fun getBasicGroupMembers(basicGroupId: Long): TdApi.BasicGroupFullInfo? - suspend fun getPremiumState(): TdApi.PremiumState? - suspend fun getPremiumFeatures(source: TdApi.PremiumSource): TdApi.PremiumFeatures? - suspend fun getPremiumLimit(limitType: TdApi.PremiumLimitType): TdApi.PremiumLimit? - suspend fun getBotFullInfo(userId: Long): TdApi.UserFullInfo? - suspend fun getChatStatistics(chatId: Long, isDark: Boolean): TdApi.ChatStatistics? - suspend fun getChatRevenueStatistics(chatId: Long, isDark: Boolean): TdApi.ChatRevenueStatistics? - suspend fun getStatisticsGraph(chatId: Long, token: String, x: Long): TdApi.StatisticalGraph? - - suspend fun logout() - suspend fun setName(firstName: String, lastName: String) - suspend fun setBio(bio: String) - suspend fun setUsername(username: String) - suspend fun setEmojiStatus(customEmojiId: Long?) - suspend fun setProfilePhoto(path: String) - suspend fun setBirthdate(birthdate: TdApi.Birthdate?) - suspend fun setPersonalChat(chatId: Long) - suspend fun setBusinessBio(bio: String) - suspend fun setBusinessLocation(location: TdApi.BusinessLocation?) - suspend fun setBusinessOpeningHours(hours: TdApi.BusinessOpeningHours?) - suspend fun toggleUsernameIsActive(username: String, isActive: Boolean) - suspend fun reorderActiveUsernames(usernames: Array) - suspend fun setChatMemberStatus( - chatId: Long, - userId: Long, - status: TdApi.ChatMemberStatus - ) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/db/MonogramDatabase.kt b/data/src/main/java/org/monogram/data/db/MonogramDatabase.kt deleted file mode 100644 index 7c7bd316..00000000 --- a/data/src/main/java/org/monogram/data/db/MonogramDatabase.kt +++ /dev/null @@ -1,47 +0,0 @@ -package org.monogram.data.db - -import androidx.room.Database -import androidx.room.RoomDatabase -import org.monogram.data.db.dao.* -import org.monogram.data.db.model.* - -@Database( - entities = [ - ChatEntity::class, - MessageEntity::class, - UserEntity::class, - ChatFullInfoEntity::class, - TopicEntity::class, - UserFullInfoEntity::class, - StickerSetEntity::class, - RecentEmojiEntity::class, - SearchHistoryEntity::class, - ChatFolderEntity::class, - AttachBotEntity::class, - KeyValueEntity::class, - NotificationSettingEntity::class, - WallpaperEntity::class, - StickerPathEntity::class, - SponsorEntity::class - ], - version = 26, - exportSchema = false -) -abstract class MonogramDatabase : RoomDatabase() { - abstract fun chatDao(): ChatDao - abstract fun messageDao(): MessageDao - abstract fun userDao(): UserDao - abstract fun chatFullInfoDao(): ChatFullInfoDao - abstract fun topicDao(): TopicDao - abstract fun userFullInfoDao(): UserFullInfoDao - abstract fun stickerSetDao(): StickerSetDao - abstract fun recentEmojiDao(): RecentEmojiDao - abstract fun searchHistoryDao(): SearchHistoryDao - abstract fun chatFolderDao(): ChatFolderDao - abstract fun attachBotDao(): AttachBotDao - abstract fun keyValueDao(): KeyValueDao - abstract fun notificationSettingDao(): NotificationSettingDao - abstract fun wallpaperDao(): WallpaperDao - abstract fun stickerPathDao(): StickerPathDao - abstract fun sponsorDao(): SponsorDao -} diff --git a/data/src/main/java/org/monogram/data/db/dao/AttachBotDao.kt b/data/src/main/java/org/monogram/data/db/dao/AttachBotDao.kt deleted file mode 100644 index 44a37d43..00000000 --- a/data/src/main/java/org/monogram/data/db/dao/AttachBotDao.kt +++ /dev/null @@ -1,20 +0,0 @@ -package org.monogram.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import kotlinx.coroutines.flow.Flow -import org.monogram.data.db.model.AttachBotEntity - -@Dao -interface AttachBotDao { - @Query("SELECT * FROM attach_bots") - fun getAttachBots(): Flow> - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertAttachBots(bots: List) - - @Query("DELETE FROM attach_bots") - suspend fun clearAll() -} diff --git a/data/src/main/java/org/monogram/data/db/dao/ChatDao.kt b/data/src/main/java/org/monogram/data/db/dao/ChatDao.kt deleted file mode 100644 index 3d5ad8ce..00000000 --- a/data/src/main/java/org/monogram/data/db/dao/ChatDao.kt +++ /dev/null @@ -1,38 +0,0 @@ -package org.monogram.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import kotlinx.coroutines.flow.Flow -import org.monogram.data.db.model.ChatEntity - -@Dao -interface ChatDao { - @Query("SELECT * FROM chats ORDER BY isPinned DESC, `order` DESC") - fun getAllChats(): Flow> - - @Query("SELECT * FROM chats WHERE id = :chatId") - suspend fun getChat(chatId: Long): ChatEntity? - - @Query("SELECT id FROM chats") - suspend fun getAllChatIds(): List - - @Query("SELECT * FROM chats ORDER BY isPinned DESC, `order` DESC LIMIT :limit") - suspend fun getTopChats(limit: Int): List - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertChat(chat: ChatEntity) - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertChats(chats: List) - - @Query("DELETE FROM chats WHERE id = :chatId") - suspend fun deleteChat(chatId: Long) - - @Query("DELETE FROM chats") - suspend fun clearAll() - - @Query("DELETE FROM chats WHERE createdAt < :timestamp") - suspend fun deleteExpired(timestamp: Long) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/db/dao/ChatFolderDao.kt b/data/src/main/java/org/monogram/data/db/dao/ChatFolderDao.kt deleted file mode 100644 index 17e3917d..00000000 --- a/data/src/main/java/org/monogram/data/db/dao/ChatFolderDao.kt +++ /dev/null @@ -1,20 +0,0 @@ -package org.monogram.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import kotlinx.coroutines.flow.Flow -import org.monogram.data.db.model.ChatFolderEntity - -@Dao -interface ChatFolderDao { - @Query("SELECT * FROM chat_folders ORDER BY `order` ASC") - fun getChatFolders(): Flow> - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertChatFolders(folders: List) - - @Query("DELETE FROM chat_folders") - suspend fun clearAll() -} diff --git a/data/src/main/java/org/monogram/data/db/dao/ChatFullInfoDao.kt b/data/src/main/java/org/monogram/data/db/dao/ChatFullInfoDao.kt deleted file mode 100644 index 55ff38fa..00000000 --- a/data/src/main/java/org/monogram/data/db/dao/ChatFullInfoDao.kt +++ /dev/null @@ -1,28 +0,0 @@ -package org.monogram.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import org.monogram.data.db.model.ChatFullInfoEntity - -@Dao -interface ChatFullInfoDao { - @Query("SELECT * FROM chat_full_info WHERE chatId = :chatId") - suspend fun getChatFullInfo(chatId: Long): ChatFullInfoEntity? - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertChatFullInfo(info: ChatFullInfoEntity) - - @Query("SELECT * FROM chat_full_info WHERE chatId IN (:chatIds)") - suspend fun getChatFullInfos(chatIds: List): List - - @Query("DELETE FROM chat_full_info WHERE chatId = :chatId") - suspend fun deleteChatFullInfo(chatId: Long) - - @Query("DELETE FROM chat_full_info") - suspend fun clearAll() - - @Query("DELETE FROM chat_full_info WHERE createdAt < :timestamp") - suspend fun deleteExpired(timestamp: Long) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/db/dao/KeyValueDao.kt b/data/src/main/java/org/monogram/data/db/dao/KeyValueDao.kt deleted file mode 100644 index ad22c516..00000000 --- a/data/src/main/java/org/monogram/data/db/dao/KeyValueDao.kt +++ /dev/null @@ -1,23 +0,0 @@ -package org.monogram.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import kotlinx.coroutines.flow.Flow -import org.monogram.data.db.model.KeyValueEntity - -@Dao -interface KeyValueDao { - @Query("SELECT * FROM key_value WHERE `key` = :key") - suspend fun getValue(key: String): KeyValueEntity? - - @Query("SELECT * FROM key_value WHERE `key` = :key") - fun observeValue(key: String): Flow - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertValue(entity: KeyValueEntity) - - @Query("DELETE FROM key_value WHERE `key` = :key") - suspend fun deleteValue(key: String) -} diff --git a/data/src/main/java/org/monogram/data/db/dao/MessageDao.kt b/data/src/main/java/org/monogram/data/db/dao/MessageDao.kt deleted file mode 100644 index 520e3da3..00000000 --- a/data/src/main/java/org/monogram/data/db/dao/MessageDao.kt +++ /dev/null @@ -1,75 +0,0 @@ -package org.monogram.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import kotlinx.coroutines.flow.Flow -import org.monogram.data.db.model.MessageEntity - -@Dao -interface MessageDao { - @Query("SELECT * FROM messages WHERE chatId = :chatId ORDER BY date DESC") - fun getMessagesForChat(chatId: Long): Flow> - - @Query("SELECT * FROM messages WHERE chatId = :chatId AND id < :fromMessageId ORDER BY date DESC LIMIT :limit") - suspend fun getMessagesOlder(chatId: Long, fromMessageId: Long, limit: Int): List - - @Query("SELECT * FROM messages WHERE chatId = :chatId AND id > :fromMessageId ORDER BY date ASC LIMIT :limit") - suspend fun getMessagesNewer(chatId: Long, fromMessageId: Long, limit: Int): List - - @Query("SELECT * FROM messages WHERE chatId = :chatId ORDER BY date DESC LIMIT :limit") - suspend fun getLatestMessages(chatId: Long, limit: Int): List - - @Query("UPDATE messages SET isRead = 1 WHERE chatId = :chatId AND id <= :upToMessageId AND isRead = 0") - suspend fun markAsRead(chatId: Long, upToMessageId: Long) - - @Query( - "UPDATE messages SET content = :content, contentType = :contentType, contentMeta = :contentMeta, mediaFileId = :mediaFileId, mediaPath = :mediaPath, editDate = :editDate WHERE id = :messageId" - ) - suspend fun updateContent( - messageId: Long, - content: String, - contentType: String, - contentMeta: String?, - mediaFileId: Int, - mediaPath: String?, - editDate: Int - ) - - @Query("UPDATE messages SET mediaPath = :path WHERE mediaFileId = :fileId AND mediaFileId != 0") - suspend fun updateMediaPath(fileId: Int, path: String) - - @Query("UPDATE messages SET viewCount = :viewCount, forwardCount = :forwardCount, replyCount = :replyCount WHERE id = :messageId") - suspend fun updateInteractionInfo(messageId: Long, viewCount: Int, forwardCount: Int, replyCount: Int) - - @Query( - """ - DELETE FROM messages - WHERE chatId = :chatId - AND id NOT IN ( - SELECT id FROM messages WHERE chatId = :chatId ORDER BY date DESC LIMIT :keepCount - ) - AND createdAt < :olderThan - """ - ) - suspend fun cleanupChat(chatId: Long, keepCount: Int, olderThan: Long) - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertMessage(message: MessageEntity) - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertMessages(messages: List) - - @Query("DELETE FROM messages WHERE id = :messageId") - suspend fun deleteMessage(messageId: Long) - - @Query("DELETE FROM messages WHERE chatId = :chatId") - suspend fun clearMessagesForChat(chatId: Long) - - @Query("DELETE FROM messages") - suspend fun clearAll() - - @Query("DELETE FROM messages WHERE createdAt < :timestamp") - suspend fun deleteExpired(timestamp: Long) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/db/dao/NotificationSettingDao.kt b/data/src/main/java/org/monogram/data/db/dao/NotificationSettingDao.kt deleted file mode 100644 index b85aff19..00000000 --- a/data/src/main/java/org/monogram/data/db/dao/NotificationSettingDao.kt +++ /dev/null @@ -1,28 +0,0 @@ -package org.monogram.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import org.monogram.data.db.model.NotificationSettingEntity - -@Dao -interface NotificationSettingDao { - @Query("SELECT * FROM notification_settings") - suspend fun getAll(): List - - @Query("SELECT * FROM notification_settings WHERE chatId = :chatId") - suspend fun getByChatId(chatId: Long): NotificationSettingEntity? - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insert(entity: NotificationSettingEntity) - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertAll(entities: List) - - @Query("DELETE FROM notification_settings WHERE chatId = :chatId") - suspend fun deleteByChatId(chatId: Long) - - @Query("DELETE FROM notification_settings") - suspend fun clearAll() -} diff --git a/data/src/main/java/org/monogram/data/db/dao/RecentEmojiDao.kt b/data/src/main/java/org/monogram/data/db/dao/RecentEmojiDao.kt deleted file mode 100644 index 9def6de0..00000000 --- a/data/src/main/java/org/monogram/data/db/dao/RecentEmojiDao.kt +++ /dev/null @@ -1,23 +0,0 @@ -package org.monogram.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import kotlinx.coroutines.flow.Flow -import org.monogram.data.db.model.RecentEmojiEntity - -@Dao -interface RecentEmojiDao { - @Query("SELECT * FROM recent_emojis ORDER BY timestamp DESC LIMIT 50") - fun getRecentEmojis(): Flow> - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertRecentEmoji(emoji: RecentEmojiEntity) - - @Query("DELETE FROM recent_emojis WHERE emoji = :emoji AND stickerId = :stickerId") - suspend fun deleteRecentEmoji(emoji: String, stickerId: Long?) - - @Query("DELETE FROM recent_emojis") - suspend fun clearAll() -} diff --git a/data/src/main/java/org/monogram/data/db/dao/SearchHistoryDao.kt b/data/src/main/java/org/monogram/data/db/dao/SearchHistoryDao.kt deleted file mode 100644 index 38141c0f..00000000 --- a/data/src/main/java/org/monogram/data/db/dao/SearchHistoryDao.kt +++ /dev/null @@ -1,23 +0,0 @@ -package org.monogram.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import kotlinx.coroutines.flow.Flow -import org.monogram.data.db.model.SearchHistoryEntity - -@Dao -interface SearchHistoryDao { - @Query("SELECT * FROM search_history ORDER BY timestamp DESC LIMIT 40") - fun getSearchHistory(): Flow> - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertSearchChatId(entity: SearchHistoryEntity) - - @Query("DELETE FROM search_history WHERE chatId = :chatId") - suspend fun deleteSearchChatId(chatId: Long) - - @Query("DELETE FROM search_history") - suspend fun clearAll() -} diff --git a/data/src/main/java/org/monogram/data/db/dao/SponsorDao.kt b/data/src/main/java/org/monogram/data/db/dao/SponsorDao.kt deleted file mode 100644 index 8c2f531d..00000000 --- a/data/src/main/java/org/monogram/data/db/dao/SponsorDao.kt +++ /dev/null @@ -1,25 +0,0 @@ -package org.monogram.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import org.monogram.data.db.model.SponsorEntity - -@Dao -interface SponsorDao { - @Query("SELECT userId FROM sponsors") - suspend fun getAllIds(): List - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertAll(items: List) - - @Query("DELETE FROM sponsors") - suspend fun clearAll() - - @Query("DELETE FROM sponsors WHERE userId NOT IN (:ids)") - suspend fun deleteNotIn(ids: List) - - @Query("SELECT MAX(updatedAt) FROM sponsors") - suspend fun getLatestUpdatedAt(): Long? -} diff --git a/data/src/main/java/org/monogram/data/db/dao/StickerPathDao.kt b/data/src/main/java/org/monogram/data/db/dao/StickerPathDao.kt deleted file mode 100644 index 160933a7..00000000 --- a/data/src/main/java/org/monogram/data/db/dao/StickerPathDao.kt +++ /dev/null @@ -1,22 +0,0 @@ -package org.monogram.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import org.monogram.data.db.model.StickerPathEntity - -@Dao -interface StickerPathDao { - @Query("SELECT path FROM sticker_paths WHERE fileId = :fileId") - suspend fun getPath(fileId: Long): String? - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertPath(entity: StickerPathEntity) - - @Query("DELETE FROM sticker_paths WHERE fileId = :fileId") - suspend fun deletePath(fileId: Long) - - @Query("DELETE FROM sticker_paths") - suspend fun clearAll() -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/db/dao/StickerSetDao.kt b/data/src/main/java/org/monogram/data/db/dao/StickerSetDao.kt deleted file mode 100644 index 3f16d746..00000000 --- a/data/src/main/java/org/monogram/data/db/dao/StickerSetDao.kt +++ /dev/null @@ -1,35 +0,0 @@ -package org.monogram.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import kotlinx.coroutines.flow.Flow -import org.monogram.data.db.model.StickerSetEntity - -@Dao -interface StickerSetDao { - @Query("SELECT * FROM sticker_sets WHERE type = :type AND isInstalled = 1 AND isArchived = 0 ORDER BY createdAt DESC") - fun getInstalledStickerSetsByType(type: String): Flow> - - @Query("SELECT * FROM sticker_sets WHERE type = :type AND isArchived = 1 ORDER BY createdAt DESC") - fun getArchivedStickerSetsByType(type: String): Flow> - - @Query("SELECT * FROM sticker_sets WHERE id = :id") - suspend fun getStickerSetById(id: Long): StickerSetEntity? - - @Query("SELECT * FROM sticker_sets WHERE name = :name") - suspend fun getStickerSetByName(name: String): StickerSetEntity? - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertStickerSets(sets: List) - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertStickerSet(set: StickerSetEntity) - - @Query("DELETE FROM sticker_sets WHERE type = :type AND isInstalled = :isInstalled AND isArchived = :isArchived") - suspend fun deleteStickerSets(type: String, isInstalled: Boolean, isArchived: Boolean) - - @Query("DELETE FROM sticker_sets") - suspend fun clearAll() -} diff --git a/data/src/main/java/org/monogram/data/db/dao/TopicDao.kt b/data/src/main/java/org/monogram/data/db/dao/TopicDao.kt deleted file mode 100644 index 2d625b7a..00000000 --- a/data/src/main/java/org/monogram/data/db/dao/TopicDao.kt +++ /dev/null @@ -1,32 +0,0 @@ -package org.monogram.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import kotlinx.coroutines.flow.Flow -import org.monogram.data.db.model.TopicEntity - -@Dao -interface TopicDao { - @Query("SELECT * FROM topics WHERE chatId = :chatId ORDER BY `order` DESC") - fun getTopicsForChat(chatId: Long): Flow> - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertTopic(topic: TopicEntity) - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertTopics(topics: List) - - @Query("DELETE FROM topics WHERE chatId = :chatId AND id = :topicId") - suspend fun deleteTopic(chatId: Long, topicId: Int) - - @Query("DELETE FROM topics WHERE chatId = :chatId") - suspend fun clearTopicsForChat(chatId: Long) - - @Query("DELETE FROM topics") - suspend fun clearAll() - - @Query("DELETE FROM topics WHERE createdAt < :timestamp") - suspend fun deleteExpired(timestamp: Long) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/db/dao/UserDao.kt b/data/src/main/java/org/monogram/data/db/dao/UserDao.kt deleted file mode 100644 index 9ad1a9f4..00000000 --- a/data/src/main/java/org/monogram/data/db/dao/UserDao.kt +++ /dev/null @@ -1,31 +0,0 @@ -package org.monogram.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import org.monogram.data.db.model.UserEntity - -@Dao -interface UserDao { - @Query("SELECT * FROM users WHERE id = :userId") - suspend fun getUser(userId: Long): UserEntity? - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertUser(user: UserEntity) - - @Query("SELECT * FROM users") - suspend fun getAllUsers(): List - - @Query("SELECT * FROM users WHERE id IN (:userIds)") - suspend fun getUsersByIds(userIds: List): List - - @Query("DELETE FROM users WHERE id = :userId") - suspend fun deleteUser(userId: Long) - - @Query("DELETE FROM users") - suspend fun clearAll() - - @Query("DELETE FROM users WHERE createdAt < :timestamp") - suspend fun deleteExpired(timestamp: Long) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/db/dao/UserFullInfoDao.kt b/data/src/main/java/org/monogram/data/db/dao/UserFullInfoDao.kt deleted file mode 100644 index be16ec18..00000000 --- a/data/src/main/java/org/monogram/data/db/dao/UserFullInfoDao.kt +++ /dev/null @@ -1,28 +0,0 @@ -package org.monogram.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import org.monogram.data.db.model.UserFullInfoEntity - -@Dao -interface UserFullInfoDao { - @Query("SELECT * FROM user_full_info WHERE userId = :userId") - suspend fun getUserFullInfo(userId: Long): UserFullInfoEntity? - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertUserFullInfo(info: UserFullInfoEntity) - - @Query("SELECT * FROM user_full_info WHERE userId IN (:userIds)") - suspend fun getUserFullInfos(userIds: List): List - - @Query("DELETE FROM user_full_info WHERE userId = :userId") - suspend fun deleteUserFullInfo(userId: Long) - - @Query("DELETE FROM user_full_info") - suspend fun clearAll() - - @Query("DELETE FROM user_full_info WHERE createdAt < :timestamp") - suspend fun deleteExpired(timestamp: Long) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/db/dao/WallpaperDao.kt b/data/src/main/java/org/monogram/data/db/dao/WallpaperDao.kt deleted file mode 100644 index d3f0f77b..00000000 --- a/data/src/main/java/org/monogram/data/db/dao/WallpaperDao.kt +++ /dev/null @@ -1,20 +0,0 @@ -package org.monogram.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import kotlinx.coroutines.flow.Flow -import org.monogram.data.db.model.WallpaperEntity - -@Dao -interface WallpaperDao { - @Query("SELECT * FROM wallpapers") - fun getWallpapers(): Flow> - - @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertWallpapers(wallpapers: List) - - @Query("DELETE FROM wallpapers") - suspend fun clearAll() -} diff --git a/data/src/main/java/org/monogram/data/db/model/AttachBotEntity.kt b/data/src/main/java/org/monogram/data/db/model/AttachBotEntity.kt deleted file mode 100644 index 63847f44..00000000 --- a/data/src/main/java/org/monogram/data/db/model/AttachBotEntity.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.monogram.data.db.model - -import androidx.room.Entity -import androidx.room.PrimaryKey - -@Entity(tableName = "attach_bots") -data class AttachBotEntity( - @PrimaryKey val botUserId: Long, - val data: String -) diff --git a/data/src/main/java/org/monogram/data/db/model/ChatEntity.kt b/data/src/main/java/org/monogram/data/db/model/ChatEntity.kt deleted file mode 100644 index 8bab18c6..00000000 --- a/data/src/main/java/org/monogram/data/db/model/ChatEntity.kt +++ /dev/null @@ -1,83 +0,0 @@ -package org.monogram.data.db.model - -import androidx.room.Entity -import androidx.room.PrimaryKey - -@Entity(tableName = "chats") -data class ChatEntity( - @PrimaryKey val id: Long, - val title: String, - val unreadCount: Int, - val avatarPath: String?, - val lastMessageText: String, - val lastMessageTime: String, - val lastMessageDate: Long = 0L, - val order: Long, - val isPinned: Boolean, - val isMuted: Boolean, - val isChannel: Boolean, - val isGroup: Boolean, - val type: String, - val privateUserId: Long = 0L, - val basicGroupId: Long = 0L, - val supergroupId: Long = 0L, - val secretChatId: Int = 0, - val positionsCache: String? = null, - val isArchived: Boolean, - val memberCount: Int, - val onlineCount: Int, - val unreadMentionCount: Int = 0, - val unreadReactionCount: Int = 0, - val isMarkedAsUnread: Boolean = false, - val hasProtectedContent: Boolean = false, - val isTranslatable: Boolean = false, - val hasAutomaticTranslation: Boolean = false, - val messageAutoDeleteTime: Int = 0, - val canBeDeletedOnlyForSelf: Boolean = false, - val canBeDeletedForAllUsers: Boolean = false, - val canBeReported: Boolean = false, - val lastReadInboxMessageId: Long = 0L, - val lastReadOutboxMessageId: Long = 0L, - val lastMessageId: Long = 0L, - val isLastMessageOutgoing: Boolean = false, - val replyMarkupMessageId: Long = 0L, - val messageSenderId: Long? = null, - val blockList: Boolean = false, - val emojiStatusId: Long? = null, - val accentColorId: Int = 0, - val profileAccentColorId: Int = -1, - val backgroundCustomEmojiId: Long = 0L, - val photoId: Int = 0, - val isSupergroup: Boolean = false, - val isAdmin: Boolean = false, - val isOnline: Boolean = false, - val typingAction: String? = null, - val draftMessage: String? = null, - val isVerified: Boolean = false, - val isSponsor: Boolean = false, - val viewAsTopics: Boolean = false, - val isForum: Boolean = false, - val isBot: Boolean = false, - val isMember: Boolean = true, - val username: String? = null, - val description: String? = null, - val inviteLink: String? = null, - val permissionCanSendBasicMessages: Boolean = true, - val permissionCanSendAudios: Boolean = true, - val permissionCanSendDocuments: Boolean = true, - val permissionCanSendPhotos: Boolean = true, - val permissionCanSendVideos: Boolean = true, - val permissionCanSendVideoNotes: Boolean = true, - val permissionCanSendVoiceNotes: Boolean = true, - val permissionCanSendPolls: Boolean = true, - val permissionCanSendOtherMessages: Boolean = true, - val permissionCanAddLinkPreviews: Boolean = true, - val permissionCanEditTag: Boolean = false, - val permissionCanChangeInfo: Boolean = false, - val permissionCanInviteUsers: Boolean = false, - val permissionCanPinMessages: Boolean = false, - val permissionCanCreateTopics: Boolean = false, - val lastMessageContentType: String = "text", - val lastMessageSenderName: String = "", - val createdAt: Long = System.currentTimeMillis() -) \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/db/model/ChatFolderEntity.kt b/data/src/main/java/org/monogram/data/db/model/ChatFolderEntity.kt deleted file mode 100644 index f88529ac..00000000 --- a/data/src/main/java/org/monogram/data/db/model/ChatFolderEntity.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.monogram.data.db.model - -import androidx.room.Entity -import androidx.room.PrimaryKey - -@Entity(tableName = "chat_folders") -data class ChatFolderEntity( - @PrimaryKey val id: Int, - val data: String, - val order: Int -) diff --git a/data/src/main/java/org/monogram/data/db/model/ChatFullInfoEntity.kt b/data/src/main/java/org/monogram/data/db/model/ChatFullInfoEntity.kt deleted file mode 100644 index 1a72d4a1..00000000 --- a/data/src/main/java/org/monogram/data/db/model/ChatFullInfoEntity.kt +++ /dev/null @@ -1,39 +0,0 @@ -package org.monogram.data.db.model - -import androidx.room.Entity -import androidx.room.PrimaryKey - -@Entity(tableName = "chat_full_info") -data class ChatFullInfoEntity( - @PrimaryKey val chatId: Long, - val description: String?, - val inviteLink: String?, - val memberCount: Int, - val onlineCount: Int, - val administratorCount: Int, - val restrictedCount: Int, - val bannedCount: Int, - val commonGroupsCount: Int, - val giftCount: Int = 0, - val isBlocked: Boolean, - val botInfo: String?, - val slowModeDelay: Int, - val locationAddress: String?, - val canSetStickerSet: Boolean, - val canSetLocation: Boolean, - val canGetMembers: Boolean, - val canGetStatistics: Boolean, - val canGetRevenueStatistics: Boolean = false, - val linkedChatId: Long, - val note: String?, - val canBeCalled: Boolean, - val supportsVideoCalls: Boolean, - val hasPrivateCalls: Boolean, - val hasPrivateForwards: Boolean, - val hasRestrictedVoiceAndVideoNoteMessages: Boolean = false, - val hasPostedToProfileStories: Boolean = false, - val setChatBackground: Boolean = false, - val incomingPaidMessageStarCount: Long = 0L, - val outgoingPaidMessageStarCount: Long = 0L, - val createdAt: Long = System.currentTimeMillis() -) \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/db/model/KeyValueEntity.kt b/data/src/main/java/org/monogram/data/db/model/KeyValueEntity.kt deleted file mode 100644 index df9eb4de..00000000 --- a/data/src/main/java/org/monogram/data/db/model/KeyValueEntity.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.monogram.data.db.model - -import androidx.room.Entity -import androidx.room.PrimaryKey - -@Entity(tableName = "key_value") -data class KeyValueEntity( - @PrimaryKey val key: String, - val value: String? -) diff --git a/data/src/main/java/org/monogram/data/db/model/MessageEntity.kt b/data/src/main/java/org/monogram/data/db/model/MessageEntity.kt deleted file mode 100644 index 8cf3fb5c..00000000 --- a/data/src/main/java/org/monogram/data/db/model/MessageEntity.kt +++ /dev/null @@ -1,47 +0,0 @@ -package org.monogram.data.db.model - -import androidx.room.Entity -import androidx.room.Index -import androidx.room.PrimaryKey - -@Entity( - tableName = "messages", - indices = [ - Index(value = ["chatId", "date"]), - Index(value = ["chatId", "id"]), - Index(value = ["createdAt"]) - ] -) -data class MessageEntity( - @PrimaryKey val id: Long, - val chatId: Long, - val senderId: Long, - val senderName: String = "", - val content: String, - val contentType: String = "text", - val contentMeta: String? = null, - val mediaFileId: Int = 0, - val mediaPath: String? = null, - val mediaThumbnailPath: String? = null, - val minithumbnail: ByteArray? = null, - val date: Int, - val isOutgoing: Boolean, - val isRead: Boolean, - val replyToMessageId: Long = 0L, - val replyToPreview: String? = null, - val replyToPreviewType: String? = null, - val replyToPreviewText: String? = null, - val replyToPreviewSenderName: String? = null, - val replyCount: Int = 0, - val forwardFromName: String? = null, - val forwardFromId: Long = 0L, - val forwardOriginChatId: Long? = null, - val forwardOriginMessageId: Long? = null, - val forwardDate: Int = 0, - val editDate: Int = 0, - val mediaAlbumId: Long = 0L, - val entities: String? = null, - val viewCount: Int = 0, - val forwardCount: Int = 0, - val createdAt: Long = System.currentTimeMillis() -) \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/db/model/NotificationSettingEntity.kt b/data/src/main/java/org/monogram/data/db/model/NotificationSettingEntity.kt deleted file mode 100644 index 5cfcabfa..00000000 --- a/data/src/main/java/org/monogram/data/db/model/NotificationSettingEntity.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.monogram.data.db.model - -import androidx.room.Entity -import androidx.room.PrimaryKey - -@Entity(tableName = "notification_settings") -data class NotificationSettingEntity( - @PrimaryKey val chatId: Long, - val muteFor: Int, - val useDefault: Boolean -) diff --git a/data/src/main/java/org/monogram/data/db/model/RecentEmojiEntity.kt b/data/src/main/java/org/monogram/data/db/model/RecentEmojiEntity.kt deleted file mode 100644 index 81e06565..00000000 --- a/data/src/main/java/org/monogram/data/db/model/RecentEmojiEntity.kt +++ /dev/null @@ -1,13 +0,0 @@ -package org.monogram.data.db.model - -import androidx.room.Entity -import androidx.room.PrimaryKey - -@Entity(tableName = "recent_emojis") -data class RecentEmojiEntity( - @PrimaryKey(autoGenerate = true) val id: Int = 0, - val emoji: String, - val stickerId: Long?, - val data: String, - val timestamp: Long = System.currentTimeMillis() -) diff --git a/data/src/main/java/org/monogram/data/db/model/SearchHistoryEntity.kt b/data/src/main/java/org/monogram/data/db/model/SearchHistoryEntity.kt deleted file mode 100644 index f16976fe..00000000 --- a/data/src/main/java/org/monogram/data/db/model/SearchHistoryEntity.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.monogram.data.db.model - -import androidx.room.Entity -import androidx.room.PrimaryKey - -@Entity(tableName = "search_history") -data class SearchHistoryEntity( - @PrimaryKey val chatId: Long, - val timestamp: Long = System.currentTimeMillis() -) diff --git a/data/src/main/java/org/monogram/data/db/model/SponsorEntity.kt b/data/src/main/java/org/monogram/data/db/model/SponsorEntity.kt deleted file mode 100644 index 1c585713..00000000 --- a/data/src/main/java/org/monogram/data/db/model/SponsorEntity.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.monogram.data.db.model - -import androidx.room.Entity -import androidx.room.PrimaryKey - -@Entity(tableName = "sponsors") -data class SponsorEntity( - @PrimaryKey val userId: Long, - val sourceChannelId: Long, - val updatedAt: Long = System.currentTimeMillis() -) diff --git a/data/src/main/java/org/monogram/data/db/model/StickerPathEntity.kt b/data/src/main/java/org/monogram/data/db/model/StickerPathEntity.kt deleted file mode 100644 index e626895b..00000000 --- a/data/src/main/java/org/monogram/data/db/model/StickerPathEntity.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.monogram.data.db.model - -import androidx.room.Entity -import androidx.room.PrimaryKey - -@Entity(tableName = "sticker_paths") -data class StickerPathEntity( - @PrimaryKey - val fileId: Long, - val path: String -) \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/db/model/StickerSetEntity.kt b/data/src/main/java/org/monogram/data/db/model/StickerSetEntity.kt deleted file mode 100644 index 9aed4ef8..00000000 --- a/data/src/main/java/org/monogram/data/db/model/StickerSetEntity.kt +++ /dev/null @@ -1,19 +0,0 @@ -package org.monogram.data.db.model - -import androidx.room.Entity -import androidx.room.Index -import androidx.room.PrimaryKey - -@Entity( - tableName = "sticker_sets", - indices = [Index(value = ["name"])] -) -data class StickerSetEntity( - @PrimaryKey val id: Long, - val name: String, - val type: String, // "REGULAR", "CUSTOM_EMOJI", "MASK" - val isInstalled: Boolean, - val isArchived: Boolean, - val data: String, - val createdAt: Long = System.currentTimeMillis() -) diff --git a/data/src/main/java/org/monogram/data/db/model/TopicEntity.kt b/data/src/main/java/org/monogram/data/db/model/TopicEntity.kt deleted file mode 100644 index 1aac3846..00000000 --- a/data/src/main/java/org/monogram/data/db/model/TopicEntity.kt +++ /dev/null @@ -1,20 +0,0 @@ -package org.monogram.data.db.model - -import androidx.room.Entity - -@Entity(tableName = "topics", primaryKeys = ["chatId", "id"]) -data class TopicEntity( - val chatId: Long, - val id: Int, - val name: String, - val iconCustomEmojiId: Long, - val iconColor: Int, - val isClosed: Boolean, - val isPinned: Boolean, - val unreadCount: Int, - val lastMessageText: String, - val lastMessageTime: String, - val order: Long, - val lastMessageSenderName: String?, - val createdAt: Long = System.currentTimeMillis() -) \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/db/model/UserEntity.kt b/data/src/main/java/org/monogram/data/db/model/UserEntity.kt deleted file mode 100644 index 1f8959eb..00000000 --- a/data/src/main/java/org/monogram/data/db/model/UserEntity.kt +++ /dev/null @@ -1,37 +0,0 @@ -package org.monogram.data.db.model - -import androidx.room.Entity -import androidx.room.Index -import androidx.room.PrimaryKey - -@Entity( - tableName = "users", - indices = [ - Index(value = ["username"]), - Index(value = ["createdAt"]) - ] -) -data class UserEntity( - @PrimaryKey val id: Long, - val firstName: String, - val lastName: String?, - val phoneNumber: String?, - val avatarPath: String?, - val personalAvatarPath: String? = null, - val isPremium: Boolean, - val isVerified: Boolean, - val isSupport: Boolean = false, - val isContact: Boolean = false, - val isMutualContact: Boolean = false, - val isCloseFriend: Boolean = false, - val haveAccess: Boolean = true, - val username: String?, - val usernamesData: String? = null, - val statusType: String = "OFFLINE", - val accentColorId: Int = 0, - val profileAccentColorId: Int = -1, - val statusEmojiId: Long = 0L, - val languageCode: String? = null, - val lastSeen: Long, - val createdAt: Long = System.currentTimeMillis() -) \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/db/model/UserFullInfoEntity.kt b/data/src/main/java/org/monogram/data/db/model/UserFullInfoEntity.kt deleted file mode 100644 index 7278a176..00000000 --- a/data/src/main/java/org/monogram/data/db/model/UserFullInfoEntity.kt +++ /dev/null @@ -1,38 +0,0 @@ -package org.monogram.data.db.model - -import androidx.room.Entity -import androidx.room.PrimaryKey - -@Entity(tableName = "user_full_info") -data class UserFullInfoEntity( - @PrimaryKey val userId: Long, - val bio: String?, - val commonGroupsCount: Int, - val giftCount: Int = 0, - val botInfoDescription: String? = null, - val personalChatId: Long = 0L, - val birthdateDay: Int = 0, - val birthdateMonth: Int = 0, - val birthdateYear: Int = 0, - val businessLocationAddress: String? = null, - val businessLocationLatitude: Double = 0.0, - val businessLocationLongitude: Double = 0.0, - val businessOpeningHoursTimeZone: String? = null, - val businessNextOpenIn: Int = 0, - val businessNextCloseIn: Int = 0, - val businessStartPageTitle: String? = null, - val businessStartPageMessage: String? = null, - val personalPhotoPath: String? = null, - val isBlocked: Boolean, - val canBeCalled: Boolean, - val supportsVideoCalls: Boolean, - val hasPrivateCalls: Boolean, - val hasPrivateForwards: Boolean, - val hasRestrictedVoiceAndVideoNoteMessages: Boolean = false, - val hasPostedToProfileStories: Boolean = false, - val setChatBackground: Boolean = false, - val canGetRevenueStatistics: Boolean = false, - val incomingPaidMessageStarCount: Long = 0L, - val outgoingPaidMessageStarCount: Long = 0L, - val createdAt: Long = System.currentTimeMillis() -) \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/db/model/WallpaperEntity.kt b/data/src/main/java/org/monogram/data/db/model/WallpaperEntity.kt deleted file mode 100644 index 77782767..00000000 --- a/data/src/main/java/org/monogram/data/db/model/WallpaperEntity.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.monogram.data.db.model - -import androidx.room.Entity -import androidx.room.PrimaryKey - -@Entity(tableName = "wallpapers") -data class WallpaperEntity( - @PrimaryKey val id: Long, - val data: String -) diff --git a/data/src/main/java/org/monogram/data/di/TdLibClient.kt b/data/src/main/java/org/monogram/data/di/TdLibClient.kt deleted file mode 100644 index 73ea4b8e..00000000 --- a/data/src/main/java/org/monogram/data/di/TdLibClient.kt +++ /dev/null @@ -1,139 +0,0 @@ -package org.monogram.data.di - -import android.content.Context -import android.util.Log -import kotlinx.coroutines.delay -import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.suspendCancellableCoroutine -import org.drinkless.tdlib.Client -import org.drinkless.tdlib.TdApi -import java.util.concurrent.atomic.AtomicLong -import kotlin.coroutines.resume -import kotlin.coroutines.resumeWithException - -class TdLibException(val error: TdApi.Error) : Exception(error.message) - -class TdLibClient(private val context: Context) { - private val TAG = "TdLibClient" - private val globalRetryAfterUntilMs = AtomicLong(0L) - - private val _isAuthenticated = MutableStateFlow(false) - val isAuthenticated = _isAuthenticated.asStateFlow() - - init { - try { - Client.execute(TdApi.SetLogVerbosityLevel(0)) - Client.execute(TdApi.SetLogStream(TdApi.LogStreamEmpty())) - } catch (e: Exception) { - Log.e(TAG, "Failed to disable TDLib logs", e) - } - } - - private val _updates = MutableSharedFlow( - replay = 10, - extraBufferCapacity = 1000, - onBufferOverflow = BufferOverflow.DROP_OLDEST - ) - val updates = _updates - - private val client = Client.create( - { result -> - if (result is TdApi.Update) { - if (result is TdApi.UpdateAuthorizationState) { - _isAuthenticated.value = result.authorizationState is TdApi.AuthorizationStateReady - } - _updates.tryEmit(result) - } - }, - { error -> - Log.e(TAG, "Update exception handler", error) - }, - { error -> - Log.e(TAG, "Default exception handler", error) - } - ) - - fun send(function: TdApi.Function, callback: (TdApi.Object) -> Unit = {}) { - client.send(function) { result -> - if (result is TdApi.Error) { - if (result.code != 404) { - Log.e(TAG, "Error in send $function: ${result.code} ${result.message}") - } else { - Log.w(TAG, "Not found in send $function: ${result.message}") - } - } - callback(result) - } - } - - suspend fun sendSuspend(function: TdApi.Function): T { - var retries = 0 - while (true) { - waitForGlobalRetryWindow() - val result = awaitResult(function) - - if (result !is TdApi.Error) { - @Suppress("UNCHECKED_CAST") - return result as T - } - - if (result.code == 429 && retries < 3) { - retries++ - val retryAfterMs = parseRetryAfterMs(result.message) - updateGlobalRetryWindow(retryAfterMs) - Log.w(TAG, "Rate limited for $function, retrying in ${retryAfterMs}ms (attempt $retries)") - continue - } - - val isExpectedUserFullInfoMiss = - function is TdApi.GetUserFullInfo && - result.code == 400 && - result.message.contains("user not found", ignoreCase = true) - - if (isExpectedUserFullInfoMiss) { - Log.w(TAG, "User not found in sendSuspend $function: ${result.code} ${result.message}") - } else if (result.code != 404) { - Log.e(TAG, "Error in sendSuspend $function: ${result.code} ${result.message}") - } else { - Log.w(TAG, "Not found in sendSuspend $function: ${result.message}") - } - throw TdLibException(result) - } - } - - private suspend fun awaitResult(function: TdApi.Function): TdApi.Object = - suspendCancellableCoroutine { cont -> - client.send(function) { result -> - if (cont.isActive) cont.resume(result) - } - } - - private suspend fun waitForGlobalRetryWindow() { - val waitMs = (globalRetryAfterUntilMs.get() - System.currentTimeMillis()).coerceAtLeast(0L) - if (waitMs > 0L) delay(waitMs) - } - - private fun updateGlobalRetryWindow(retryAfterMs: Long) { - val target = System.currentTimeMillis() + retryAfterMs - while (true) { - val current = globalRetryAfterUntilMs.get() - if (target <= current) return - if (globalRetryAfterUntilMs.compareAndSet(current, target)) return - } - } - - private fun parseRetryAfterMs(message: String?): Long { - val seconds = Regex("retry after\\s+(\\d+)", RegexOption.IGNORE_CASE) - .find(message.orEmpty()) - ?.groupValues - ?.getOrNull(1) - ?.toLongOrNull() - ?: 1L - return (seconds * 1000L).coerceAtMost(60_000L) - } - - fun getContext() = context -} diff --git a/data/src/main/java/org/monogram/data/di/TdNotificationManager.kt b/data/src/main/java/org/monogram/data/di/TdNotificationManager.kt deleted file mode 100644 index 54525069..00000000 --- a/data/src/main/java/org/monogram/data/di/TdNotificationManager.kt +++ /dev/null @@ -1,873 +0,0 @@ -package org.monogram.data.di - -import org.monogram.data.core.coRunCatching -import android.Manifest -import android.app.NotificationChannel -import android.app.NotificationChannelGroup -import android.app.NotificationManager -import android.app.PendingIntent -import android.content.Context -import android.content.Intent -import android.content.pm.PackageManager -import android.graphics.* -import android.os.Build -import android.text.SpannableStringBuilder -import android.text.Spanned -import android.text.style.StyleSpan -import android.util.Log -import android.util.LruCache -import androidx.core.app.* -import androidx.core.graphics.createBitmap -import androidx.core.graphics.drawable.IconCompat -import androidx.core.graphics.drawable.toBitmap -import com.google.firebase.messaging.FirebaseMessaging -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.launch -import org.drinkless.tdlib.TdApi -import org.monogram.data.db.dao.NotificationSettingDao -import org.monogram.data.db.model.NotificationSettingEntity -import org.monogram.data.infra.FileDownloadQueue -import org.monogram.data.service.NotificationDismissReceiver -import org.monogram.data.service.NotificationReadReceiver -import org.monogram.data.service.NotificationReplyReceiver -import org.monogram.domain.repository.AppPreferencesProvider -import org.monogram.domain.repository.PushProvider -import org.monogram.domain.repository.SettingsRepository -import org.monogram.domain.repository.SettingsRepository.TdNotificationScope -import java.util.concurrent.ConcurrentHashMap -import kotlin.math.min - -class TdNotificationManager( - private val context: Context, - private val tdLibClient: TdLibClient, - private val appPreferences: AppPreferencesProvider, - private val settingsRepository: SettingsRepository, - private val notificationSettingDao: NotificationSettingDao, - private val fileQueue: FileDownloadQueue -) { - private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default) - private val notificationManager = NotificationManagerCompat.from(context) - private val userCache = ConcurrentHashMap() - private val chatCache = ConcurrentHashMap() - private val messagesHistory = ConcurrentHashMap>>() - private val lastMessageIds = ConcurrentHashMap() - private val activeNotifications = ConcurrentHashMap>() - private val bitmapCache = object : LruCache(5 * 1024 * 1024) { - override fun sizeOf(key: Int, value: Bitmap): Int { - return value.byteCount - } - } - private val activeDownloads = ConcurrentHashMap Unit>>() - private val notificationSettingsCache = ConcurrentHashMap() - private val scopeNotificationsEnabled = ConcurrentHashMap() - private val loadedScopeSettings = ConcurrentHashMap.newKeySet() - - private enum class NotificationScopeKey { - PRIVATE, - GROUPS, - CHANNELS - } - - companion object { - private const val TAG = "TdNotificationManager" - const val GROUP_CHATS = "group_chats" - const val GROUP_OTHER = "group_other" - - const val CHANNEL_PRIVATE = "channel_private_chats" - const val CHANNEL_GROUPS = "channel_groups" - const val CHANNEL_CHANNELS = "channel_channels" - const val CHANNEL_OTHER = "channel_other" - - const val SUMMARY_ID = 0 - const val KEY_TEXT_REPLY = "key_text_reply" - } - - init { - createNotificationChannels() - loadSettingsFromDb() - observeUpdates() - } - - private fun loadSettingsFromDb() { - scope.launch(Dispatchers.IO) { - val settings = notificationSettingDao.getAll() - settings.forEach { - notificationSettingsCache[it.chatId] = it - } - } - } - - private fun observeUpdates() { - scope.launch { - tdLibClient.isAuthenticated.collect { authenticated -> - if (authenticated) { - loadedScopeSettings.clear() - scopeNotificationsEnabled.clear() - fetchScopeNotificationSettings() - fetchInitialExceptions() - updatePushRegistration() - } - } - } - - scope.launch { - tdLibClient.updates.collect { update -> - when (update) { - is TdApi.UpdateNewMessage -> handleNewMessage(update.message) - is TdApi.UpdateUser -> userCache[update.user.id] = update.user - is TdApi.UpdateFile -> { - val file = update.file - if (file.local.isDownloadingCompleted && file.local.path.isNotEmpty()) { - val callbacks = synchronized(activeDownloads) { - activeDownloads.remove(file.id) - } - if (callbacks != null) { - scope.launch(Dispatchers.IO) { - val bitmap = try { - BitmapFactory.decodeFile(file.local.path) - } catch (e: Exception) { - null - } - if (bitmap != null) { - bitmapCache.put(file.id, bitmap) - } - callbacks.forEach { it(bitmap) } - } - } - } - } - is TdApi.UpdateChatNotificationSettings -> { - updateChatNotificationSettings(update.chatId, update.notificationSettings) - chatCache[update.chatId]?.let { chat -> - chatCache[update.chatId] = chat.apply { - notificationSettings = update.notificationSettings - } - } - } - is TdApi.UpdateChatReadInbox -> { - clearHistory(update.chatId) - updateSummary() - } - is TdApi.UpdateOption -> { - if (update.name == "is_authenticated" && (update.value as? TdApi.OptionValueBoolean)?.value == true) { - updatePushRegistration() - } - } - else -> {} - } - } - } - - scope.launch { - appPreferences.pushProvider.collect { - updatePushRegistration() - } - } - } - - private fun updateChatNotificationSettings(chatId: Long, settings: TdApi.ChatNotificationSettings) { - val entity = NotificationSettingEntity( - chatId = chatId, - muteFor = settings.muteFor, - useDefault = settings.useDefaultMuteFor - ) - notificationSettingsCache[chatId] = entity - scope.launch(Dispatchers.IO) { - notificationSettingDao.insert(entity) - } - } - - private fun updatePushRegistration() { - if (!tdLibClient.isAuthenticated.value) return - - when (appPreferences.pushProvider.value) { - PushProvider.FCM -> { - try { - FirebaseMessaging.getInstance().token.addOnCompleteListener { task -> - if (task.isSuccessful) { - val token = task.result - tdLibClient.send( - TdApi.RegisterDevice( - TdApi.DeviceTokenFirebaseCloudMessaging(token, true), - longArrayOf() - ) - ) - } - } - } catch (e: Exception) { - Log.e(TAG, "FCM registration failed", e) - } - } - - PushProvider.GMS_LESS -> { - tdLibClient.send( - TdApi.RegisterDevice( - TdApi.DeviceTokenFirebaseCloudMessaging("", false), - longArrayOf() - ) - ) - } - } - } - - private fun fetchInitialExceptions() { - if (!tdLibClient.isAuthenticated.value) return - - val scopes = listOf( - TdApi.NotificationSettingsScopePrivateChats(), - TdApi.NotificationSettingsScopeGroupChats(), - TdApi.NotificationSettingsScopeChannelChats() - ) - - scopes.forEach { scope -> - tdLibClient.send(TdApi.GetChatNotificationSettingsExceptions(scope, true)) { result -> - if (result is TdApi.Chats) { - result.chatIds.forEach { chatId -> - getChat(chatId) { chat -> - updateChatNotificationSettings(chat.id, chat.notificationSettings) - } - } - } - } - } - } - - private suspend fun fetchScopeNotificationSettings() { - if (!tdLibClient.isAuthenticated.value) return - - val scopes = listOf( - NotificationScopeKey.PRIVATE to TdNotificationScope.PRIVATE_CHATS, - NotificationScopeKey.GROUPS to TdNotificationScope.GROUPS, - NotificationScopeKey.CHANNELS to TdNotificationScope.CHANNELS - ) - - scopes.forEach { (key, scope) -> - val enabled = coRunCatching { settingsRepository.getNotificationSettings(scope) } - .getOrDefault(false) - - scopeNotificationsEnabled[key] = enabled - loadedScopeSettings.add(key) - - when (key) { - NotificationScopeKey.PRIVATE -> appPreferences.setPrivateChatsNotifications(enabled) - NotificationScopeKey.GROUPS -> appPreferences.setGroupsNotifications(enabled) - NotificationScopeKey.CHANNELS -> appPreferences.setChannelsNotifications(enabled) - } - } - } - - fun isChatMuted(chat: TdApi.Chat): Boolean { - val cached = notificationSettingsCache[chat.id] - val muteFor = cached?.muteFor ?: chat.notificationSettings.muteFor - val useDefault = cached?.useDefault ?: chat.notificationSettings.useDefaultMuteFor - - return if (useDefault) { - val scopeKey = when (chat.type) { - is TdApi.ChatTypePrivate -> NotificationScopeKey.PRIVATE - is TdApi.ChatTypeBasicGroup -> NotificationScopeKey.GROUPS - is TdApi.ChatTypeSupergroup -> { - if ((chat.type as TdApi.ChatTypeSupergroup).isChannel) NotificationScopeKey.CHANNELS else NotificationScopeKey.GROUPS - } - - else -> null - } - - if (scopeKey == null || !loadedScopeSettings.contains(scopeKey)) { - return true - } - - val globalEnabled = scopeNotificationsEnabled[scopeKey] ?: false - !globalEnabled - } else { - muteFor > 0 - } - } - - fun clearHistory(chatId: Long) { - messagesHistory.remove(chatId) - lastMessageIds.remove(chatId) - activeNotifications.remove(chatId)?.forEach { notificationId -> - notificationManager.cancel(notificationId) - } - notificationManager.cancel(chatId.toInt()) - updateSummary() - } - - fun removeNotification(chatId: Long, notificationId: Int) { - activeNotifications[chatId]?.remove(notificationId) - notificationManager.cancel(notificationId) - - if (notificationId == chatId.toInt()) { - messagesHistory.remove(chatId) - activeNotifications.remove(chatId) - } else { - val history = messagesHistory[chatId] - if (history != null) { - history.removeAll { it.first == notificationId.toLong() } - if (history.isEmpty()) { - messagesHistory.remove(chatId) - activeNotifications.remove(chatId) - } - } - } - updateSummary() - } - - private fun handleNewMessage(message: TdApi.Message) { - if (message.isOutgoing) return - - val lastId = lastMessageIds[message.chatId] - if (lastId != null && message.id <= lastId) { - return - } - lastMessageIds[message.chatId] = message.id - - getChat(message.chatId) { chat -> - checkMembership(chat) { isMember -> - if (!isMember) { - Log.d(TAG, "Skipping notification for chat ${chat.id}: user is not a member") - return@checkMembership - } - - if (isChatMuted(chat)) return@checkMembership - - val contentText = - if (appPreferences.showSenderOnly.value) "Новое сообщение" else getMessageText(message.content) - - if (contentText.isBlank()) return@checkMembership - - val timestamp = message.date.toLong() * 1000 - - val shouldDownloadAvatar = - !appPreferences.isPowerSavingMode.value && !appPreferences.batteryOptimizationEnabled.value - - resolveSender(message.senderId, chat, !shouldDownloadAvatar) { senderName, senderBitmap -> - if (shouldDownloadAvatar) { - downloadAvatar(chat.photo, false) { chatIcon -> - appendMessageToNotification( - chatId = chat.id, - messageId = message.id, - chatType = chat.type, - senderName = senderName, - senderBitmap = senderBitmap, - chatIcon = chatIcon ?: senderBitmap, - text = contentText, - timestamp = timestamp - ) - } - } else { - appendMessageToNotification( - chatId = chat.id, - messageId = message.id, - chatType = chat.type, - senderName = senderName, - senderBitmap = senderBitmap, - chatIcon = senderBitmap, - text = contentText, - timestamp = timestamp - ) - } - } - } - } - } - - private fun checkMembership(chat: TdApi.Chat, callback: (Boolean) -> Unit) { - when (val type = chat.type) { - is TdApi.ChatTypePrivate -> callback(true) - is TdApi.ChatTypeBasicGroup -> { - if (type.basicGroupId == 0L) { - callback(true) - return - } - tdLibClient.send(TdApi.GetBasicGroup(type.basicGroupId)) { result -> - if (result is TdApi.BasicGroup) { - callback(result.status is TdApi.ChatMemberStatusMember || result.status is TdApi.ChatMemberStatusCreator || result.status is TdApi.ChatMemberStatusAdministrator) - } else { - callback(true) - } - } - } - is TdApi.ChatTypeSupergroup -> { - if (type.supergroupId == 0L) { - callback(true) - return - } - tdLibClient.send(TdApi.GetSupergroup(type.supergroupId)) { result -> - if (result is TdApi.Supergroup) { - callback(result.status is TdApi.ChatMemberStatusMember || result.status is TdApi.ChatMemberStatusCreator || result.status is TdApi.ChatMemberStatusAdministrator) - } else { - callback(true) - } - } - } - else -> callback(true) - } - } - - fun appendMessageToNotification( - chatId: Long, - messageId: Long, - chatType: TdApi.ChatType, - senderName: String, - senderBitmap: Bitmap?, - chatIcon: Bitmap?, - text: String, - timestamp: Long - ) { - if (text.isBlank()) return - - if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { - return - } - - val channelId = when (chatType) { - is TdApi.ChatTypePrivate -> CHANNEL_PRIVATE - is TdApi.ChatTypeBasicGroup -> CHANNEL_GROUPS - is TdApi.ChatTypeSupergroup -> if (chatType.isChannel) CHANNEL_CHANNELS else CHANNEL_GROUPS - else -> CHANNEL_OTHER - } - - val personBuilder = Person.Builder() - .setName(senderName) - .setKey(senderName) - - if (senderBitmap != null) { - personBuilder.setIcon(IconCompat.createWithBitmap(getCircularBitmap(senderBitmap))) - } - - val sender = personBuilder.build() - - val styleMessage = NotificationCompat.MessagingStyle.Message( - text, - timestamp, - sender - ) - - val history = messagesHistory.getOrPut(chatId) { mutableListOf() } - history.add(messageId to styleMessage) - if (history.size > 10) { - history.removeAt(0) - } - - val notificationId = chatId.toInt() - activeNotifications.getOrPut(chatId) { ConcurrentHashMap.newKeySet() }.add(notificationId) - - val intent = context.packageManager.getLaunchIntentForPackage(context.packageName)?.apply { - flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK - putExtra("chat_id", chatId) - } - val pendingIntent = PendingIntent.getActivity( - context, - notificationId, - intent, - PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT - ) - - val dismissIntent = Intent(context, NotificationDismissReceiver::class.java).apply { - putExtra("chat_id", chatId) - putExtra("notification_id", notificationId) - } - val dismissPendingIntent = PendingIntent.getBroadcast( - context, - notificationId, - dismissIntent, - PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT - ) - - val remoteInput = RemoteInput.Builder(KEY_TEXT_REPLY) - .setLabel("Ответить") - .build() - - val replyIntent = Intent(context, NotificationReplyReceiver::class.java).apply { - putExtra("chat_id", chatId) - putExtra("notification_id", notificationId) - } - val replyPendingIntent = PendingIntent.getBroadcast( - context, - notificationId, - replyIntent, - PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT - ) - - val readIntent = Intent(context, NotificationReadReceiver::class.java).apply { - putExtra("chat_id", chatId) - putExtra("notification_id", notificationId) - } - val readPendingIntent = PendingIntent.getBroadcast( - context, - notificationId, - readIntent, - PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT - ) - - - val replyAction = NotificationCompat.Action.Builder( - android.R.drawable.ic_menu_send, - "Ответить", - replyPendingIntent - ).addRemoteInput(remoteInput).build() - - val readAction = NotificationCompat.Action.Builder( - android.R.drawable.ic_menu_view, - "Прочитано", - readPendingIntent - ).build() - - - val myself = Person.Builder().setName("Я").build() - val messagingStyle = NotificationCompat.MessagingStyle(myself) - history.forEach { (_, msg) -> - messagingStyle.addMessage(msg) - } - - val isGroup = chatType !is TdApi.ChatTypePrivate - messagingStyle.isGroupConversation = isGroup - - val chatTitle = chatCache[chatId]?.title ?: senderName - if (isGroup) { - messagingStyle.conversationTitle = chatTitle - } - - val priority = when (appPreferences.notificationPriority.value) { - 0 -> NotificationCompat.PRIORITY_LOW - 2 -> NotificationCompat.PRIORITY_HIGH - else -> NotificationCompat.PRIORITY_DEFAULT - } - - val builder = NotificationCompat.Builder(context, channelId) - .setSmallIcon(org.monogram.data.R.drawable.message_outline) - .setStyle(messagingStyle) - .setPriority(priority) - .setContentIntent(pendingIntent) - .setDeleteIntent(dismissPendingIntent) - .addAction(replyAction) - .addAction(readAction) - .setGroup(GROUP_CHATS) - .setCategory(NotificationCompat.CATEGORY_MESSAGE) - .setAutoCancel(true) - .setShortcutId(chatId.toString()) - .setLocusId(androidx.core.content.LocusIdCompat(chatId.toString())) - .setOnlyAlertOnce(true) - - builder.setContentTitle(chatTitle) - builder.setContentText(text) - - if (appPreferences.inAppSounds.value) { - builder.setDefaults(NotificationCompat.DEFAULT_SOUND) - } else { - builder.setSilent(true) - } - - if (appPreferences.inAppVibrate.value) { - when (appPreferences.notificationVibrationPattern.value) { - "short" -> builder.setVibrate(longArrayOf(0, 100, 50, 100)) - "long" -> builder.setVibrate(longArrayOf(0, 500, 200, 500)) - "disabled" -> builder.setVibrate(longArrayOf(0)) - else -> builder.setDefaults(NotificationCompat.DEFAULT_VIBRATE) - } - } - - if (!appPreferences.inAppPreview.value) { - builder.setContentText("Новое сообщение") - } - - if (chatIcon != null) { - Log.d("TdNotificationManager", "Setting chat icon to $chatTitle") - builder.setLargeIcon(getCircularBitmap(chatIcon)) - } - - notificationManager.notify(notificationId, builder.build()) - updateSummary() - } - - private fun getCircularBitmap(bitmap: Bitmap): Bitmap { - val size = min(bitmap.width, bitmap.height) - - val output = createBitmap(size, size) - val canvas = Canvas(output) - - val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { - shader = BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP).apply { - if (bitmap.width != bitmap.height) { - val dx = (size - bitmap.width) / 2f - val dy = (size - bitmap.height) / 2f - setLocalMatrix(Matrix().apply { setTranslate(dx, dy) }) - } - } - } - - val radius = size / 2f - canvas.drawCircle(radius, radius, radius, paint) - - return output - } - - private fun updateSummary() { - if (ActivityCompat.checkSelfPermission( - context, - Manifest.permission.POST_NOTIFICATIONS - ) != PackageManager.PERMISSION_GRANTED - ) { - return - } - - val activeChatsCount = messagesHistory.size - if (activeChatsCount == 0) { - notificationManager.cancel(SUMMARY_ID) - return - } - - val allMessages = messagesHistory.flatMap { (chatId, messages) -> - messages.map { (_, message) -> - Triple(chatId, message, message.timestamp) - } - }.sortedByDescending { it.third } - - val totalMessagesCount = allMessages.size - val inboxStyle = NotificationCompat.InboxStyle() - - allMessages.take(5).forEach { (chatId, message, _) -> - val chat = chatCache[chatId] - val senderName = message.person?.name ?: "Unknown" - val chatTitle = chat?.title ?: senderName - - val sb = SpannableStringBuilder() - val title = if (chatTitle != senderName) "$chatTitle ($senderName)" else senderName - - sb.append(title, StyleSpan(Typeface.BOLD), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) - sb.append(" ") - sb.append(message.text) - - inboxStyle.addLine(sb) - } - - val summaryTitle = "$totalMessagesCount сообщений из $activeChatsCount чатов" - inboxStyle.setSummaryText("$activeChatsCount чатов") - inboxStyle.setBigContentTitle(summaryTitle) - - val builder = NotificationCompat.Builder(context, CHANNEL_PRIVATE) - .setSmallIcon(org.monogram.data.R.drawable.message_outline) - .setStyle(inboxStyle) - .setGroup(GROUP_CHATS) - .setGroupSummary(true) - .setPriority(NotificationCompat.PRIORITY_LOW) - .setOnlyAlertOnce(true) - .setContentTitle(summaryTitle) - - val latestMessageTriple = allMessages.firstOrNull() - if (latestMessageTriple != null) { - val (_, message, _) = latestMessageTriple - val iconCompat = message.person?.icon - if (iconCompat != null) { - val drawable = iconCompat.loadDrawable(context) - if (drawable != null) { - builder.setLargeIcon(drawable.toBitmap()) - } - } - } - - notificationManager.notify(SUMMARY_ID, builder.build()) - } - - private fun createNotificationChannels() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - - manager.createNotificationChannelGroups( - listOf( - NotificationChannelGroup(GROUP_CHATS, "Чаты"), - NotificationChannelGroup(GROUP_OTHER, "Прочее") - ) - ) - - val channels = listOf( - NotificationChannel(CHANNEL_PRIVATE, "Личные чаты", NotificationManager.IMPORTANCE_HIGH).apply { - description = "Уведомления из личных переписок" - group = GROUP_CHATS - enableVibration(true) - setShowBadge(true) - lockscreenVisibility = NotificationCompat.VISIBILITY_PRIVATE - }, - NotificationChannel(CHANNEL_GROUPS, "Группы", NotificationManager.IMPORTANCE_DEFAULT).apply { - description = "Уведомления из групп" - group = GROUP_CHATS - enableVibration(true) - setShowBadge(true) - lockscreenVisibility = NotificationCompat.VISIBILITY_PRIVATE - }, - NotificationChannel(CHANNEL_CHANNELS, "Каналы", NotificationManager.IMPORTANCE_LOW).apply { - description = "Уведомления из каналов" - group = GROUP_CHATS - enableVibration(false) - setShowBadge(true) - }, - NotificationChannel(CHANNEL_OTHER, "Другое", NotificationManager.IMPORTANCE_LOW).apply { - description = "Прочие уведомления" - group = GROUP_OTHER - } - ) - - manager.createNotificationChannels(channels) - } - } - - private fun getMessageText(content: TdApi.MessageContent): String { - return when (content) { - is TdApi.MessageText -> sanitizeSpoilers(content.text) - is TdApi.MessagePhoto -> "📷 Фотография ${sanitizeSpoilers(content.caption)}" - is TdApi.MessageVideo -> "📹 Видео ${sanitizeSpoilers(content.caption)}" - is TdApi.MessageVoiceNote -> "🎤 Голосовое сообщение" - is TdApi.MessageSticker -> "Стикер" - is TdApi.MessageAnimation -> "GIF" - is TdApi.MessageAudio -> "🎵 Аудио ${content.audio.title}" - is TdApi.MessageDocument -> "📄 Файл ${content.document.fileName}" - is TdApi.MessageLocation -> "📍 Локация ${content.location.latitude}, ${content.location.longitude}" - is TdApi.MessageContact -> "👤 Контакт ${content.contact.firstName} ${content.contact.lastName}" - is TdApi.MessagePoll -> "📊 Опрос ${content.poll.question.text}" - else -> "Сообщение" - } - } - - private fun sanitizeSpoilers(formattedText: TdApi.FormattedText?): String { - if (formattedText == null) return "" - val text = formattedText.text.orEmpty() - val spoilerEntities = formattedText.entities - ?.filter { it.type is TdApi.TextEntityTypeSpoiler } - .orEmpty() - - if (spoilerEntities.isEmpty()) return text - - val builder = StringBuilder(text) - spoilerEntities - .sortedByDescending { it.offset } - .forEach { entity -> - val start = entity.offset.coerceIn(0, builder.length) - val end = (entity.offset + entity.length).coerceIn(start, builder.length) - if (start < end) { - builder.replace(start, end, "[spoiler]") - } - } - - return builder.toString() - } - - fun getChat(chatId: Long, callback: (TdApi.Chat) -> Unit) { - chatCache[chatId]?.let { - callback(it) - return - } - tdLibClient.send(TdApi.GetChat(chatId)) { result -> - if (result is TdApi.Chat) { - chatCache[chatId] = result - callback(result) - } - } - } - - private fun getUser(userId: Long, callback: (TdApi.User) -> Unit) { - if (userId == 0L) return - userCache[userId]?.let { - callback(it) - return - } - tdLibClient.send(TdApi.GetUser(userId)) { result -> - if (result is TdApi.User) { - userCache[result.id] = result - callback(result) - } - } - } - - - private fun resolveSender( - senderId: TdApi.MessageSender, - chat: TdApi.Chat, - onlyIfLocal: Boolean = false, - callback: (String, Bitmap?) -> Unit - ) { - when (senderId) { - is TdApi.MessageSenderUser -> { - getUser(senderId.userId) { user -> - val name = - if (chat.type is TdApi.ChatTypePrivate) chat.title else "${user.firstName} ${user.lastName}".trim() - val file = - user.profilePhoto?.small ?: if (chat.type is TdApi.ChatTypePrivate) chat.photo?.small else null - downloadFile(file, onlyIfLocal) { bitmap -> - callback(name, bitmap) - } - } - } - - is TdApi.MessageSenderChat -> { - getChat(senderId.chatId) { senderChat -> - val name = senderChat.title - downloadFile(senderChat.photo?.small, onlyIfLocal) { bitmap -> - callback(name, bitmap) - } - } - } - - else -> { - val name = chat.title - downloadFile(chat.photo?.small, onlyIfLocal) { bitmap -> - callback(name, bitmap) - } - } - } - } - - private fun downloadAvatar( - fileInfo: TdApi.ChatPhotoInfo?, - onlyIfLocal: Boolean = false, - callback: (Bitmap?) -> Unit - ) { - downloadFile(fileInfo?.small, onlyIfLocal, callback) - } - - private fun downloadFile(file: TdApi.File?, onlyIfLocal: Boolean = false, callback: (Bitmap?) -> Unit) { - if (file == null) { - callback(null) - return - } - - val cachedBitmap = bitmapCache.get(file.id) - if (cachedBitmap != null) { - callback(cachedBitmap) - return - } - - if (file.local.isDownloadingCompleted && file.local.path.isNotEmpty()) { - val bitmap = try { - BitmapFactory.decodeFile(file.local.path) - } catch (e: Exception) { - Log.e(TAG, "Error decoding file: ${file.local.path}", e) - null - } - - if (bitmap != null) { - bitmapCache.put(file.id, bitmap) - callback(bitmap) - return - } - } - - if (onlyIfLocal) { - callback(null) - return - } - - synchronized(activeDownloads) { - val callbacks = activeDownloads[file.id] - if (callbacks != null) { - callbacks.add(callback) - return - } - activeDownloads[file.id] = mutableListOf(callback) - } - - fileQueue.enqueue(file.id, 32, FileDownloadQueue.DownloadType.DEFAULT, synchronous = true) - } -} diff --git a/data/src/main/java/org/monogram/data/di/dataModule.kt b/data/src/main/java/org/monogram/data/di/dataModule.kt deleted file mode 100644 index 00a909cc..00000000 --- a/data/src/main/java/org/monogram/data/di/dataModule.kt +++ /dev/null @@ -1,434 +0,0 @@ -package org.monogram.data.di - -import android.content.Context -import android.net.ConnectivityManager -import androidx.room.Room -import androidx.room.RoomDatabase -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import org.koin.android.ext.koin.androidContext -import org.koin.dsl.module -import org.monogram.core.DispatcherProvider -import org.monogram.core.ScopeProvider -import org.monogram.data.chats.ChatCache -import org.monogram.data.datasource.FileDataSource -import org.monogram.data.datasource.PlayerDataSourceFactoryImpl -import org.monogram.data.datasource.TdFileDataSource -import org.monogram.data.datasource.cache.* -import org.monogram.data.datasource.remote.* -import org.monogram.data.db.MonogramDatabase -import org.monogram.data.gateway.TelegramGateway -import org.monogram.data.gateway.TelegramGatewayImpl -import org.monogram.data.gateway.UpdateDispatcher -import org.monogram.data.gateway.UpdateDispatcherImpl -import org.monogram.data.infra.* -import org.monogram.data.mapper.ChatMapper -import org.monogram.data.mapper.MessageMapper -import org.monogram.data.mapper.NetworkMapper -import org.monogram.data.mapper.StorageMapper -import org.monogram.data.repository.* -import org.monogram.domain.repository.* - -val dataModule = module { - single { CoroutineScope(SupervisorJob() + Dispatchers.IO) } - - single { TdLibClient(androidContext()) } - - single { DefaultDispatcherProvider() } - single { DefaultScopeProvider(get()) } - single { AndroidStringProvider(androidContext()) } - single(createdAtStart = true) { - OfflineWarmup( - scopeProvider = get(), - dispatchers = get(), - gateway = get(), - chatDao = get(), - messageDao = get(), - userDao = get(), - userFullInfoDao = get(), - chatFullInfoDao = get(), - messageMapper = get(), - chatCache = get(), - stickerRepository = get() - ) - } - single(createdAtStart = true) { - SponsorSyncManager( - scopeProvider = get(), - gateway = get(), - sponsorDao = get(), - authRepository = get() - ) - } - - single { ChatCache() } - single { - TelegramGatewayImpl(get()) - } - single { - UpdateDispatcherImpl( - gateway = get() - ) - } - single { - TdFileDataSource( - gateway = get(), - fileDownloadQueue = get() - ) - } - - factory { - TdAuthRemoteDataSource( - gateway = get() - ) - } - - factory { - PlayerDataSourceFactoryImpl( - fileDataSource = get() - ) - } - - single { - AuthRepositoryImpl( - remote = get(), - updates = get(), - tdLibClient = get(), - scopeProvider = get() - ) - } - - factory { - TdUserRemoteDataSource( - gateway = get() - ) - } - - // Database - single { - Room.databaseBuilder( - androidContext(), - MonogramDatabase::class.java, - "monogram_db" - ) - .setJournalMode(RoomDatabase.JournalMode.WRITE_AHEAD_LOGGING) - .fallbackToDestructiveMigration(dropAllTables = true) - .build() - } - single { get().chatDao() } - single { get().messageDao() } - single { get().userDao() } - single { get().chatFullInfoDao() } - single { get().topicDao() } - single { get().userFullInfoDao() } - single { get().stickerSetDao() } - single { get().recentEmojiDao() } - single { get().searchHistoryDao() } - single { get().chatFolderDao() } - single { get().attachBotDao() } - single { get().keyValueDao() } - single { get().notificationSettingDao() } - single { get().wallpaperDao() } - single { get().stickerPathDao() } - single { get().sponsorDao() } - - single { - RoomUserLocalDataSource( - userDao = get(), - userFullInfoDao = get() - ) - } - - single { - RoomChatLocalDataSource( - database = get(), - chatDao = get(), - messageDao = get(), - chatFullInfoDao = get(), - topicDao = get() - ) - } - - single { - UserRepositoryImpl( - remote = get(), - userLocal = get(), - chatLocal = get(), - updates = get(), - scopeProvider = get(), - gateway = get(), - fileQueue = get(), - keyValueDao = get(), - sponsorSyncManager = get() - ) - } - - factory { - TdChatsRemoteDataSource( - gateway = get() - ) - } - - single { - get() - } - - single { - TdChatRemoteSource( - gateway = get(), - connectivityManager = androidContext().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager, - ) - } - - factory { - TdProxyRemoteDataSource( - gateway = get() - ) - } - - single { - ChatMapper(get()) - } - - single { - StorageMapper(get()) - } - - single { - NetworkMapper(get(), get()) - } - - single { - MessageFileCoordinator( - fileDownloadQueue = get() - ) - } - - single { - get() - } - - single { - MessageMapper( - connectivityManager = androidContext().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager, - gateway = get(), - userRepository = get(), - customEmojiPaths = get().customEmojiPaths, - fileIdToCustomEmojiId = get().fileIdToCustomEmojiId, - fileApi = get(), - settingsRepository = get(), - cache = get(), - scopeProvider = get() - ) - } - - single { - ConnectionManager( - chatRemoteSource = get(), - proxyRemoteSource = get(), - updates = get(), - appPreferences = get(), - dispatchers = get(), - connectivityManager = androidContext().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager, - scopeProvider = get() - ) - } - - single { - ChatsListRepositoryImpl( - remoteDataSource = get(), - cacheDataSource = get(), - chatRemoteSource = get(), - proxyRemoteSource = get(), - updates = get(), - appPreferences = get(), - cacheProvider = get(), - dispatchers = get(), - cache = get(), - chatMapper = get(), - messageMapper = get(), - gateway = get(), - scopeProvider = get(), - chatLocalDataSource = get(), - connectionManager = get(), - databaseFile = androidContext().getDatabasePath("monogram_db"), - searchHistoryDao = get(), - chatFolderDao = get(), - fileQueue = get(), - stringProvider = get() - ) - } - - factory { - TdSettingsRemoteDataSource( - gateway = get(), - fileQueue = get() - ) - } - - single { - InMemorySettingsCacheDataSource() - } - - single { - SettingsRepositoryImpl( - remote = get(), - cache = get(), - chatsRemote = get(), - updates = get(), - appPreferences = get(), - cacheProvider = get(), - scopeProvider = get(), - dispatchers = get(), - attachBotDao = get(), - keyValueDao = get(), - wallpaperDao = get(), - storageMapper = get(), - stringProvider = get(), - networkMapper = get() - ) - } - single { - PollRepositoryImpl() - } - - single { - TdMessageRemoteDataSource( - gateway = get(), - messageMapper = get(), - userRepository = get(), - chatsListRepository = get(), - cache = get(), - pollRepository = get(), - fileDownloadQueue = get(), - dispatcherProvider = get(), - scopeProvider = get() - ) - } - - single { - MessageRepositoryImpl( - context = androidContext(), - gateway = get(), - messageMapper = get(), - messageRemoteDataSource = get(), - cache = get(), - dispatcherProvider = get(), - scopeProvider = get(), - fileDataSource = get(), - chatLocalDataSource = get(), - userLocalDataSource = get(), - fileUpdateHandler = get() - ) - } - - factory { - TdStickerRemoteSource( - gateway = get() - ) - } - - single { - FileMessageRegistry() - } - - single { - FileDownloadQueue( - gateway = get(), - registry = get(), - cache = get(), - scope = get(), - dispatcherProvider = get() - ) - } - - single { - FileUpdateHandler( - registry = get(), - queue = get(), - updates = get(), - scope = get() - ) - } - - single { - StickerRepositoryImpl( - remote = get(), - fileQueue = get(), - fileUpdateHandler = get(), - updates = get(), - cacheProvider = get(), - dispatchers = get(), - context = androidContext(), - scopeProvider = get(), - stickerSetDao = get(), - recentEmojiDao = get(), - stickerPathDao = get() - ) - } - - factory { - TdPrivacyRemoteDataSource( - gateway = get() - ) - } - - single { - PrivacyRepositoryImpl( - remote = get(), - updates = get(), - scopeProvider = get() - ) - } - - single { - LinkHandlerRepositoryImpl(get(), get(), get(), get()) - } - - single { - StreamingRepositoryImpl( - fileDataSource = get(), - updates = get(), - scopeProvider = get() - ) - } - - factory { - HttpExternalProxyDataSource( - dispatchers = get() - ) - } - - single { - ExternalProxyRepositoryImpl( - remote = get(), - externalSource = get(), - dispatchers = get(), - appPreferences = get() - ) - } - - single { - LocationRepositoryImpl() - } - - factory { - TdUpdateRemoteDataSource( - gateway = get() - ) - } - - single { - UpdateRepositoryImpl( - context = androidContext(), - remote = get(), - fileQueue = get(), - fileUpdateHandler = get(), - authRepository = get(), - scopeProvider = get(), - ) - } - - single { TdNotificationManager(androidContext(), get(), get(), get(), get(), get()) } -} diff --git a/data/src/main/java/org/monogram/data/gateway/TelegramGateway.kt b/data/src/main/java/org/monogram/data/gateway/TelegramGateway.kt deleted file mode 100644 index 6c10f9c4..00000000 --- a/data/src/main/java/org/monogram/data/gateway/TelegramGateway.kt +++ /dev/null @@ -1,9 +0,0 @@ -package org.monogram.data.gateway - -import kotlinx.coroutines.flow.SharedFlow -import org.drinkless.tdlib.TdApi - -interface TelegramGateway { - suspend fun execute(function: TdApi.Function): T - val updates: SharedFlow -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/gateway/TelegramGatewayImpl.kt b/data/src/main/java/org/monogram/data/gateway/TelegramGatewayImpl.kt deleted file mode 100644 index 8580b943..00000000 --- a/data/src/main/java/org/monogram/data/gateway/TelegramGatewayImpl.kt +++ /dev/null @@ -1,15 +0,0 @@ -package org.monogram.data.gateway - -import kotlinx.coroutines.flow.SharedFlow -import org.drinkless.tdlib.TdApi -import org.monogram.data.di.TdLibClient - -class TelegramGatewayImpl( - private val client: TdLibClient -) : TelegramGateway { - override suspend fun execute(function: TdApi.Function): T = - client.sendSuspend(function) - - override val updates: SharedFlow - get() = client.updates -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/gateway/UpdateDispatcher.kt b/data/src/main/java/org/monogram/data/gateway/UpdateDispatcher.kt deleted file mode 100644 index 4e70f139..00000000 --- a/data/src/main/java/org/monogram/data/gateway/UpdateDispatcher.kt +++ /dev/null @@ -1,50 +0,0 @@ -package org.monogram.data.gateway - -import kotlinx.coroutines.flow.Flow -import org.drinkless.tdlib.TdApi - -interface UpdateDispatcher { - // Auth - val authorizationState: Flow - - // Messages - val newMessage: Flow - val messageEdited: Flow - val messageContent: Flow - val messageSendSucceeded: Flow - val messageSendFailed: Flow - val messageDeleted: Flow - val messagePinned: Flow - val messageInteractionInfo: Flow - - // Chats - val chatLastMessage: Flow - val chatPosition: Flow - val chatReadInbox: Flow - val chatReadOutbox: Flow - val chatUnreadMentionCount: Flow - val chatNotificationSettings: Flow - val chatTitle: Flow - val chatPhoto: Flow - val chatPermissions: Flow - val chatDraftMessage: Flow - val chatAction: Flow - val chatOnlineMemberCount: Flow - val chatFolders: Flow - - // Users - val userStatus: Flow - val user: Flow - val userPrivacySettingRules: Flow - - // Files - val file: Flow - - // Connection - val connectionState: Flow - val installedStickerSets: Flow - val newChat: Flow - val attachmentMenuBots: Flow - - val chatsListUpdates: Flow -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/gateway/UpdateDispatcherImpl.kt b/data/src/main/java/org/monogram/data/gateway/UpdateDispatcherImpl.kt deleted file mode 100644 index b367dbd6..00000000 --- a/data/src/main/java/org/monogram/data/gateway/UpdateDispatcherImpl.kt +++ /dev/null @@ -1,83 +0,0 @@ -package org.monogram.data.gateway - -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.flow.filterIsInstance -import org.drinkless.tdlib.TdApi - -class UpdateDispatcherImpl( - gateway: TelegramGateway -) : UpdateDispatcher { - private val updates = gateway.updates - - private inline fun flow(): Flow = - updates.filterIsInstance() - - override val authorizationState = flow() - - override val newMessage = flow() - override val messageEdited = flow() - override val messageContent = flow() - override val messageSendSucceeded = flow() - override val messageSendFailed = flow() - override val messageDeleted = flow() - override val messagePinned = flow() - override val messageInteractionInfo = flow() - - override val chatLastMessage = flow() - override val chatPosition = flow() - override val chatReadInbox = flow() - override val chatReadOutbox = flow() - override val chatUnreadMentionCount = flow() - override val chatNotificationSettings = flow() - override val chatTitle = flow() - override val chatPhoto = flow() - override val chatPermissions = flow() - override val chatDraftMessage = flow() - override val chatAction = flow() - override val chatOnlineMemberCount = flow() - override val chatFolders = flow() - - override val userStatus = flow() - override val user = flow() - override val userPrivacySettingRules = flow() - - override val file = flow() - - override val connectionState = flow() - override val installedStickerSets = flow() - override val newChat = flow() - override val attachmentMenuBots = flow() - override val chatsListUpdates = updates.filter { - it is TdApi.UpdateNewChat || - it is TdApi.UpdateChatTitle || - it is TdApi.UpdateChatPhoto || - it is TdApi.UpdateChatLastMessage || - it is TdApi.UpdateChatPosition || - it is TdApi.UpdateChatReadInbox || - it is TdApi.UpdateChatReadOutbox || - it is TdApi.UpdateChatUnreadMentionCount || - it is TdApi.UpdateChatUnreadReactionCount || - it is TdApi.UpdateChatDraftMessage || - it is TdApi.UpdateChatNotificationSettings || - it is TdApi.UpdateChatPermissions || - it is TdApi.UpdateChatViewAsTopics || - it is TdApi.UpdateChatIsTranslatable || - it is TdApi.UpdateChatOnlineMemberCount || - it is TdApi.UpdateChatFolders || - it is TdApi.UpdateUserStatus || - it is TdApi.UpdateUser || - it is TdApi.UpdateSupergroup || - it is TdApi.UpdateBasicGroup || - it is TdApi.UpdateSupergroupFullInfo || - it is TdApi.UpdateBasicGroupFullInfo || - it is TdApi.UpdateSecretChat || - it is TdApi.UpdateChatAction || - it is TdApi.UpdateFile || - it is TdApi.UpdateDeleteMessages || - it is TdApi.UpdateMessageMentionRead || - it is TdApi.UpdateMessageReactions || - it is TdApi.UpdateAuthorizationState || - it is TdApi.UpdateConnectionState - } -} diff --git a/data/src/main/java/org/monogram/data/infra/AndroidStringProvider.kt b/data/src/main/java/org/monogram/data/infra/AndroidStringProvider.kt deleted file mode 100644 index d7a31430..00000000 --- a/data/src/main/java/org/monogram/data/infra/AndroidStringProvider.kt +++ /dev/null @@ -1,21 +0,0 @@ -package org.monogram.data.infra - -import android.content.Context -import org.monogram.domain.repository.StringProvider - -class AndroidStringProvider(private val context: Context) : StringProvider { - override fun getString(resName: String): String { - val resId = context.resources.getIdentifier(resName, "string", context.packageName) - return if (resId != 0) context.getString(resId) else resName - } - - override fun getString(resName: String, vararg formatArgs: Any): String { - val resId = context.resources.getIdentifier(resName, "string", context.packageName) - return if (resId != 0) context.getString(resId, *formatArgs) else resName - } - - override fun getQuantityString(resName: String, quantity: Int, vararg formatArgs: Any): String { - val resId = context.resources.getIdentifier(resName, "plurals", context.packageName) - return if (resId != 0) context.resources.getQuantityString(resId, quantity, *formatArgs) else resName - } -} diff --git a/data/src/main/java/org/monogram/data/infra/ConnectionManager.kt b/data/src/main/java/org/monogram/data/infra/ConnectionManager.kt deleted file mode 100644 index df929ed2..00000000 --- a/data/src/main/java/org/monogram/data/infra/ConnectionManager.kt +++ /dev/null @@ -1,373 +0,0 @@ -package org.monogram.data.infra - -import org.monogram.data.core.coRunCatching -import android.net.ConnectivityManager -import android.net.Network -import android.net.NetworkRequest -import android.net.Uri -import android.os.Build -import android.util.Log -import kotlinx.coroutines.* -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import org.drinkless.tdlib.TdApi -import org.monogram.core.DispatcherProvider -import org.monogram.core.ScopeProvider -import org.monogram.data.datasource.remote.ChatRemoteSource -import org.monogram.data.datasource.remote.ProxyRemoteDataSource -import org.monogram.data.gateway.UpdateDispatcher -import org.monogram.domain.repository.AppPreferencesProvider -import org.monogram.domain.repository.ConnectionStatus -import kotlin.random.Random - -class ConnectionManager( - private val chatRemoteSource: ChatRemoteSource, - private val proxyRemoteSource: ProxyRemoteDataSource, - private val updates: UpdateDispatcher, - private val appPreferences: AppPreferencesProvider, - private val dispatchers: DispatcherProvider, - private val connectivityManager: ConnectivityManager, - scopeProvider: ScopeProvider -) { - private val TAG = "ConnectionManager" - private val scope = scopeProvider.appScope - - private val _connectionStateFlow = MutableStateFlow(ConnectionStatus.Connecting) - val connectionStateFlow = _connectionStateFlow.asStateFlow() - - private var retryJob: Job? = null - private var proxyModeWatcherJob: Job? = null - private var autoBestJob: Job? = null - private var telegaSwitchJob: Job? = null - private var watchdogJob: Job? = null - private var networkCallback: ConnectivityManager.NetworkCallback? = null - private var reconnectAttempts = 0 - private var lastRetryAtMs = 0L - private var lastStateChangeAtMs = System.currentTimeMillis() - - private val minRetryIntervalMs = 1_200L - private val maxRetryDelayMs = 60_000L - - init { - scope.launch { - updates.connectionState.collect { update -> handleConnectionState(update.state, "update") } - } - - scope.launch { - updates.authorizationState.collect { update -> - if (update.authorizationState is TdApi.AuthorizationStateReady) { - runReconnectAttempt("auth_ready", force = true) - syncConnectionStateFromTdlib("auth_ready") - } - } - } - - registerNetworkCallback() - startWatchdog() - startProxyManagement() - - scope.launch(dispatchers.default) { - runReconnectAttempt("bootstrap", force = true) - syncConnectionStateFromTdlib("bootstrap") - } - } - - private fun handleConnectionState(state: TdApi.ConnectionState, source: String) { - val status = when (state) { - is TdApi.ConnectionStateReady -> ConnectionStatus.Connected - is TdApi.ConnectionStateConnecting -> ConnectionStatus.Connecting - is TdApi.ConnectionStateUpdating -> ConnectionStatus.Updating - is TdApi.ConnectionStateWaitingForNetwork -> ConnectionStatus.WaitingForNetwork - is TdApi.ConnectionStateConnectingToProxy -> ConnectionStatus.ConnectingToProxy - else -> ConnectionStatus.Connecting - } - - val previous = _connectionStateFlow.value - if (previous != status) { - lastStateChangeAtMs = System.currentTimeMillis() - Log.d(TAG, "Connection state changed: $previous -> $status ($source)") - } - - _connectionStateFlow.value = status - - when (status) { - is ConnectionStatus.Connected -> { - reconnectAttempts = 0 - retryJob?.cancel() - retryJob = null - } - - is ConnectionStatus.Connecting, - is ConnectionStatus.Updating, - is ConnectionStatus.WaitingForNetwork, - is ConnectionStatus.ConnectingToProxy -> startRetryLoop() - } - } - - fun retryConnection() { - scope.launch(dispatchers.default) { - runReconnectAttempt("manual", force = true) - syncConnectionStateFromTdlib("manual") - } - } - - private fun startRetryLoop() { - if (retryJob?.isActive == true) return - retryJob = scope.launch(dispatchers.default) { - runReconnectAttempt("state_change", force = true) - syncConnectionStateFromTdlib("state_change") - - while (isActive && _connectionStateFlow.value !is ConnectionStatus.Connected) { - delay(calculateRetryDelayMs(_connectionStateFlow.value, reconnectAttempts)) - if (!isActive || _connectionStateFlow.value is ConnectionStatus.Connected) break - - runReconnectAttempt("scheduled") - syncConnectionStateFromTdlib("scheduled") - } - } - } - - private suspend fun runReconnectAttempt(reason: String, force: Boolean = false) { - val now = System.currentTimeMillis() - if (!force && now - lastRetryAtMs < minRetryIntervalMs) return - lastRetryAtMs = now - reconnectAttempts++ - - Log.d(TAG, "Reconnect attempt #$reconnectAttempts ($reason), state=${_connectionStateFlow.value}") - - val networkTypeUpdated = coRunCatching { - withContext(dispatchers.io) { - chatRemoteSource.setNetworkType() - } - }.getOrElse { error -> - Log.e(TAG, "Reconnect attempt failed", error) - false - } - - if (!networkTypeUpdated) { - Log.w(TAG, "Reconnect attempt did not update network type") - } - - coRunCatching { - withContext(dispatchers.io) { - proxyRemoteSource.setOption("online", TdApi.OptionValueBoolean(true)) - } - } - - maybeAdjustProxyOnFailures(force = force || !networkTypeUpdated) - } - - private suspend fun syncConnectionStateFromTdlib(reason: String) { - val state = withTimeoutOrNull(4_000L) { - withContext(dispatchers.io) { - chatRemoteSource.getConnectionState() - } - } - - if (state == null) { - if (!hasActiveNetwork()) { - handleConnectionState(TdApi.ConnectionStateWaitingForNetwork(), "probe:$reason:fallback") - } - return - } - - handleConnectionState(state, "probe:$reason") - } - - private suspend fun maybeAdjustProxyOnFailures(force: Boolean = false) { - val isTelegaEnabled = appPreferences.isTelegaProxyEnabled.value - val isAutoBestEnabled = appPreferences.isAutoBestProxyEnabled.value - if (!isAutoBestEnabled && !isTelegaEnabled) return - - if (!force) { - if (reconnectAttempts < 4) return - if (reconnectAttempts % 3 != 0) return - } - - coRunCatching { selectBestProxy(telegaOnly = isTelegaEnabled) } - .onFailure { Log.e(TAG, "Proxy fallback failed during reconnect", it) } - } - - private fun calculateRetryDelayMs(status: ConnectionStatus, attempts: Int): Long { - val base = when (status) { - is ConnectionStatus.WaitingForNetwork -> 2_500L - is ConnectionStatus.ConnectingToProxy -> 3_500L - is ConnectionStatus.Updating -> 2_000L - is ConnectionStatus.Connecting -> 1_500L - is ConnectionStatus.Connected -> 1_000L - } - val backoff = (base * (1L shl attempts.coerceAtMost(5))).coerceAtMost(maxRetryDelayMs) - val jitter = Random.nextLong(200L, 1_200L) - return backoff + jitter - } - - private fun startProxyManagement() { - proxyModeWatcherJob?.cancel() - proxyModeWatcherJob = scope.launch { - appPreferences.enabledProxyId.value?.let { proxyId -> - if (!proxyRemoteSource.enableProxy(proxyId)) { - appPreferences.setEnabledProxyId(null) - coRunCatching { selectBestProxy(telegaOnly = appPreferences.isTelegaProxyEnabled.value) } - } - } - - combine( - appPreferences.isAutoBestProxyEnabled, - appPreferences.isTelegaProxyEnabled - ) { autoBest, telega -> autoBest to telega } - .distinctUntilChanged() - .collect { (autoBest, telega) -> - autoBestJob?.cancel() - telegaSwitchJob?.cancel() - - if (telega) { - telegaSwitchJob = launchTelegaSwitchLoop() - } else if (autoBest) { - autoBestJob = launchAutoBestLoop() - } - } - } - } - - private fun launchAutoBestLoop(): Job = scope.launch(dispatchers.default) { - while (isActive) { - coRunCatching { selectBestProxy(telegaOnly = false) } - .onFailure { Log.e(TAG, "Error selecting best proxy", it) } - delay(300_000L) - } - } - - private fun launchTelegaSwitchLoop(): Job = scope.launch(dispatchers.default) { - while (isActive) { - coRunCatching { selectBestProxy(telegaOnly = true) } - .onFailure { Log.e(TAG, "Error selecting telega proxy", it) } - delay(60_000L) - } - } - - private suspend fun selectBestProxy(telegaOnly: Boolean = false) { - val allProxies = proxyRemoteSource.getProxies() - val proxies = if (telegaOnly) { - val telegaIds = getTelegaIdentifiers() - allProxies.filter { "${it.server}:${it.port}" in telegaIds } - } else { - allProxies - } - - if (proxies.isEmpty()) return - - val best = coroutineScope { - proxies.map { proxy -> - async { - val ping = withTimeoutOrNull(4_000L) { - proxyRemoteSource.pingProxy(proxy.server, proxy.port, proxy.type) - } ?: Long.MAX_VALUE - proxy to ping - } - }.awaitAll() - }.minByOrNull { it.second } ?: return - - if (best.second == Long.MAX_VALUE) { - Log.w(TAG, "All candidate proxies are unreachable, switching to direct connection") - coRunCatching { - proxyRemoteSource.disableProxy() - appPreferences.setEnabledProxyId(null) - }.onFailure { Log.e(TAG, "Failed to switch to direct connection", it) } - return - } - - val currentEnabled = proxies.find { it.isEnabled } - if (best.first.id != currentEnabled?.id) { - Log.d(TAG, "Switching to better proxy: ${best.first.server}:${best.first.port} (ping: ${best.second}ms)") - if (proxyRemoteSource.enableProxy(best.first.id)) { - appPreferences.setEnabledProxyId(best.first.id) - } - } - } - - private fun getTelegaIdentifiers(): Set { - return appPreferences.telegaProxyUrls.value.mapNotNull { parseTelegaIdentifier(it) }.toSet() - } - - private fun parseTelegaIdentifier(url: String): String? { - val normalized = url.replace("t.me/proxy", "tg://proxy") - val uri = runCatching { Uri.parse(normalized) }.getOrNull() - val server = uri?.getQueryParameter("server") - val port = uri?.getQueryParameter("port") ?: "443" - if (!server.isNullOrBlank()) return "$server:$port" - - val serverMatch = Regex("server=([^&]+)").find(url)?.groupValues?.get(1) - val regexPort = Regex("port=([^&]+)").find(url)?.groupValues?.get(1) ?: "443" - return serverMatch?.let { "$it:$regexPort" } - } - - private fun startWatchdog() { - watchdogJob?.cancel() - watchdogJob = scope.launch(dispatchers.default) { - while (isActive) { - delay(15_000L) - if (_connectionStateFlow.value is ConnectionStatus.Connected) continue - - val stuckForMs = System.currentTimeMillis() - lastStateChangeAtMs - if (stuckForMs >= 20_000L) { - runReconnectAttempt("watchdog", force = true) - syncConnectionStateFromTdlib("watchdog") - } - - if (stuckForMs >= 120_000L) { - maybeAdjustProxyOnFailures(force = true) - } - } - } - } - - private fun registerNetworkCallback() { - if (networkCallback != null) return - - val callback = object : ConnectivityManager.NetworkCallback() { - override fun onAvailable(network: Network) { - onNetworkChanged("available") - } - - override fun onLost(network: Network) { - onNetworkChanged("lost") - } - } - - val registered = coRunCatching { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - connectivityManager.registerDefaultNetworkCallback(callback) - } else { - connectivityManager.registerNetworkCallback(NetworkRequest.Builder().build(), callback) - } - true - }.getOrElse { - Log.w(TAG, "Failed to register network callback", it) - false - } - - if (registered) { - networkCallback = callback - } - } - - private fun onNetworkChanged(reason: String) { - scope.launch(dispatchers.default) { - runReconnectAttempt("network_$reason", force = true) - syncConnectionStateFromTdlib("network_$reason") - } - } - - private fun hasActiveNetwork(): Boolean { - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - val active = connectivityManager.activeNetwork ?: return false - val capabilities = connectivityManager.getNetworkCapabilities(active) ?: return false - capabilities.hasCapability(android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET) - } else { - @Suppress("DEPRECATION") - connectivityManager.activeNetworkInfo?.isConnected == true - } - } -} diff --git a/data/src/main/java/org/monogram/data/infra/DefaultDispatcherProvider.kt b/data/src/main/java/org/monogram/data/infra/DefaultDispatcherProvider.kt deleted file mode 100644 index a2404179..00000000 --- a/data/src/main/java/org/monogram/data/infra/DefaultDispatcherProvider.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.monogram.data.infra - -import org.monogram.core.DispatcherProvider -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers - -class DefaultDispatcherProvider : DispatcherProvider { - override val main: CoroutineDispatcher = Dispatchers.Main - override val io: CoroutineDispatcher = Dispatchers.IO - override val default: CoroutineDispatcher = Dispatchers.Default - override val mainImmediate: CoroutineDispatcher = Dispatchers.Main.immediate -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/infra/DefaultScopeProvider.kt b/data/src/main/java/org/monogram/data/infra/DefaultScopeProvider.kt deleted file mode 100644 index ae4b3fd8..00000000 --- a/data/src/main/java/org/monogram/data/infra/DefaultScopeProvider.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.monogram.data.infra - -import org.monogram.core.DispatcherProvider -import org.monogram.core.ScopeProvider -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.SupervisorJob - -class DefaultScopeProvider( - dispatcherProvider: DispatcherProvider -) : ScopeProvider { - override val appScope: CoroutineScope = CoroutineScope( - SupervisorJob() + dispatcherProvider.default - ) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/infra/EmojiLoader.kt b/data/src/main/java/org/monogram/data/infra/EmojiLoader.kt deleted file mode 100644 index b5aa5931..00000000 --- a/data/src/main/java/org/monogram/data/infra/EmojiLoader.kt +++ /dev/null @@ -1,48 +0,0 @@ -package org.monogram.data.infra - -import android.content.Context -import android.graphics.Paint -import android.graphics.Typeface -import java.io.File - -object EmojiLoader { - private val EMOJI_RANGES = listOf( - 0x1F600..0x1F64F, // Emoticons - 0x1F300..0x1F5FF, // Misc Symbols and Pictographs - 0x1F680..0x1F6FF, // Transport and Map - 0x1F1E6..0x1F1FF, // Flags (Regional Indicator Symbols) - 0x1F900..0x1F9FF, // Supplemental Symbols and Pictographs - 0x2600..0x26FF, // Misc symbols - 0x2700..0x27BF, // Dingbats - 0x1F700..0x1F77F, // Alchemical - 0x1F780..0x1F7FF, // Geometric Shapes Ext - 0x1F800..0x1F8FF // Supplemental Arrows - ) - - private var cachedEmojiList: List? = null - - fun getSupportedEmojis(context: Context): List { - cachedEmojiList?.let { return it } - - val appleFile = File(context.filesDir, "fonts/apple.ttf") - val typeface = if (appleFile.exists()) { - Typeface.createFromFile(appleFile) - } else { - Typeface.DEFAULT - } - - val paint = Paint().apply { this.typeface = typeface } - val result = ArrayList(1200) - val vs16 = "\uFE0F" - for (range in EMOJI_RANGES) { - for (code in range) { - val char = String(Character.toChars(code)) - when { - paint.hasGlyph(char + vs16) -> result.add(char + vs16) - paint.hasGlyph(char) -> result.add(char) - } - } - } - return result.distinct().also { cachedEmojiList = it } - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/infra/FileDownloadQueue.kt b/data/src/main/java/org/monogram/data/infra/FileDownloadQueue.kt deleted file mode 100644 index 4a685b1c..00000000 --- a/data/src/main/java/org/monogram/data/infra/FileDownloadQueue.kt +++ /dev/null @@ -1,751 +0,0 @@ -package org.monogram.data.infra - -import android.util.Log -import kotlinx.coroutines.* -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import org.drinkless.tdlib.TdApi -import org.monogram.core.DispatcherProvider -import org.monogram.core.ScopeProvider -import org.monogram.data.chats.ChatCache -import org.monogram.data.core.coRunCatching -import org.monogram.data.di.TdLibException -import org.monogram.data.gateway.TelegramGateway -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.TimeUnit -import kotlin.random.Random - -class FileDownloadQueue( - private val gateway: TelegramGateway, - val registry: FileMessageRegistry, - private val cache: ChatCache, - private val scope: ScopeProvider, - private val dispatcherProvider: DispatcherProvider -) { - enum class DownloadType { VIDEO, GIF, STICKER, VIDEO_NOTE, DEFAULT } - - private data class DownloadRequest( - val fileId: Int, - val priority: Int, - val type: DownloadType, - val offset: Long = 0, - val limit: Long = 0, - val synchronous: Boolean = false, - val createdAt: Long = System.currentTimeMillis(), - val availableAt: Long = System.currentTimeMillis(), - val isManual: Boolean = false, - val retryCount: Int = 0 - ) : Comparable { - override fun compareTo(other: DownloadRequest): Int { - if (this.isManual != other.isManual) return if (this.isManual) -1 else 1 - val p = other.priority.compareTo(priority) - if (p != 0) return p - val a = availableAt.compareTo(other.availableAt) - return if (a != 0) a else createdAt.compareTo(other.createdAt) - } - } - - private val stateMutex = Mutex() - private val pendingRequests = ConcurrentHashMap() - private val activeRequests = ConcurrentHashMap() - private val failedRequests = ConcurrentHashMap() - private val notFoundCooldownUntil = ConcurrentHashMap() - - private val fileDownloadTypes = ConcurrentHashMap() - private val manualDownloadIds = ConcurrentHashMap.newKeySet() - private val suppressedAutoDownloadIds = ConcurrentHashMap.newKeySet() - private val downloadWaiters = ConcurrentHashMap>() - private val uploadWaiters = ConcurrentHashMap>() - private val lastProgressAt = ConcurrentHashMap() - private val stalledRecoveryAt = ConcurrentHashMap() - - private val openChatIds = ConcurrentHashMap.newKeySet() - private val visibleMessageIds = ConcurrentHashMap>() - private val nearbyMessageIds = ConcurrentHashMap>() - - @Volatile - private var activeChatId: Long = 0L - @Volatile - private var lastTaskStartAt: Long = 0L - - private val startGapMs = 160L - private val notFoundCooldownMs = TimeUnit.MINUTES.toMillis(2) - private val maxTotalParallelDownloads = 10 - private val maxVideoParallelDownloads = 3 - private val maxGifParallelDownloads = 2 - private val maxDefaultParallelDownloads = 4 - private val maxPendingDefaultAutoDownloads = 20 - private val maxStickerParallelDownloads = 5 - private val stickerStallMs = 20_000L - private val defaultStallMs = 35_000L - private val stalledRecoveryCooldownMs = 12_000L - - private val trigger = Channel(Channel.CONFLATED) - - init { - scope.appScope.launch(dispatcherProvider.default) { - while (isActive) { - trigger.receive() - coRunCatching { dispatchTasks() } - .onFailure { Log.e("FileDownloadQueue", "dispatchTasks failed", it) } - } - } - - scope.appScope.launch(dispatcherProvider.default) { - while (isActive) { - delay(TimeUnit.MINUTES.toMillis(1)) - coRunCatching { retryFailedDownloads() } - .onFailure { Log.e("FileDownloadQueue", "retryFailedDownloads failed", it) } - } - } - - scope.appScope.launch(dispatcherProvider.default) { - while (isActive) { - delay(15_000) - coRunCatching { recoverStalledDownloads() } - .onFailure { Log.e("FileDownloadQueue", "recoverStalledDownloads failed", it) } - } - } - - scope.appScope.launch(dispatcherProvider.default) { - while (isActive) { - delay(TimeUnit.MINUTES.toMillis(5)) - coRunCatching { cleanupDeadState() } - .onFailure { Log.e("FileDownloadQueue", "cleanupDeadState failed", it) } - } - } - } - - private suspend fun dispatchTasks() { - val tasksToStart = mutableListOf() - val now = System.currentTimeMillis() - - stateMutex.withLock { - var vCount = - activeRequests.values.count { it.type == DownloadType.VIDEO || it.type == DownloadType.VIDEO_NOTE } - var gCount = activeRequests.values.count { it.type == DownloadType.GIF } - var dCount = activeRequests.values.count { it.type == DownloadType.DEFAULT } - var sCount = activeRequests.values.count { it.type == DownloadType.STICKER } - var totalCount = activeRequests.size - - val candidates = pendingRequests.values - .filter { it.availableAt <= now } - .sorted() - - for (req in candidates) { - if (totalCount >= maxTotalParallelDownloads) break - var canStart = false - when (req.type) { - DownloadType.VIDEO, DownloadType.VIDEO_NOTE -> if (vCount < maxVideoParallelDownloads) { - vCount++; canStart = true - } - - DownloadType.GIF -> if (gCount < maxGifParallelDownloads) { - gCount++; canStart = true - } - - DownloadType.DEFAULT -> if (dCount < maxDefaultParallelDownloads) { - dCount++; canStart = true - } - - DownloadType.STICKER -> if (sCount < maxStickerParallelDownloads) { - sCount++; canStart = true - } - } - - if (canStart) { - totalCount++ - pendingRequests.remove(req.fileId) - activeRequests[req.fileId] = req - tasksToStart.add(req) - } - } - } - - for (task in tasksToStart) { - throttleTaskStart() - scope.appScope.launch(dispatcherProvider.io) { - processDownload(task) - } - } - } - - private suspend fun throttleTaskStart() { - val now = System.currentTimeMillis() - val waitMs = (lastTaskStartAt + startGapMs - now).coerceAtLeast(0L) - if (waitMs > 0) delay(waitMs) - lastTaskStartAt = System.currentTimeMillis() - } - - private suspend fun processDownload(req: DownloadRequest) { - val fileId = req.fileId - - if (!isStillRelevant(fileId)) { - finishTask(fileId) - return - } - - val deferred = downloadWaiters.getOrPut(fileId) { CompletableDeferred() } - - try { - val cached = cache.fileCache[fileId] - if (cached?.local?.isDownloadingCompleted == true) { - deferred.complete(Unit) - return - } - - lastProgressAt[fileId] = System.currentTimeMillis() - - val started = withTimeoutOrNull(30000) { - gateway.execute(TdApi.DownloadFile(fileId, req.priority, req.offset, req.limit, req.synchronous)) - } - if (started == null) { - handleDownloadFailure(req) - return - } - - val timeoutMs = when (req.type) { - DownloadType.VIDEO -> TimeUnit.MINUTES.toMillis(10) - DownloadType.STICKER -> TimeUnit.SECONDS.toMillis(90) - DownloadType.VIDEO_NOTE -> TimeUnit.MINUTES.toMillis(2) - DownloadType.GIF -> TimeUnit.MINUTES.toMillis(3) - DownloadType.DEFAULT -> TimeUnit.MINUTES.toMillis(3) - } - - val completed = withTimeoutOrNull(timeoutMs) { - deferred.await() - } - - if (completed == null) { - handleDownloadFailure(req) - } - } catch (e: Exception) { - if (e !is CancellationException) { - Log.e("FileDownloadQueue", "Download failed for $fileId: ${e.message}") - val tdErrorCode = (e as? TdLibException)?.error?.code - if (tdErrorCode == 404 && req.type == DownloadType.STICKER) { - handleNotFoundDownloadFailure(req) - } else { - handleDownloadFailure(req, tdErrorCode) - } - } - } finally { - finishTask(fileId) - - try { - val finalFile = withTimeoutOrNull(10000) { gateway.execute(TdApi.GetFile(fileId)) } - if (finalFile != null) { - cache.fileCache[fileId] = finalFile - if (finalFile.local.isDownloadingCompleted) { - notifyDownloadComplete(fileId) - } else if (!finalFile.local.isDownloadingActive && !hasPendingOrActiveRequest(fileId)) { - notifyDownloadCancelled(fileId) - } - } else if (!hasPendingOrActiveRequest(fileId)) { - notifyDownloadCancelled(fileId) - } - } catch (_: Exception) { - if (!hasPendingOrActiveRequest(fileId)) { - notifyDownloadCancelled(fileId) - } - } - } - } - - private suspend fun hasPendingOrActiveRequest(fileId: Int): Boolean { - return stateMutex.withLock { - pendingRequests.containsKey(fileId) || activeRequests.containsKey(fileId) - } - } - - private suspend fun handleDownloadFailure(req: DownloadRequest, errorCode: Int? = null) { - val nextRetry = req.retryCount + 1 - val maxRetries = when (req.type) { - DownloadType.VIDEO -> 4 - DownloadType.GIF -> 5 - DownloadType.STICKER, DownloadType.VIDEO_NOTE -> 6 - DownloadType.DEFAULT -> 5 - } - - if (nextRetry <= maxRetries) { - val backoffMs = calculateBackoffMs(req, nextRetry, errorCode) - val nextReq = req.copy( - retryCount = nextRetry, - availableAt = System.currentTimeMillis() + backoffMs - ) - stateMutex.withLock { - pendingRequests[req.fileId] = nextReq - failedRequests.remove(req.fileId) - } - trigger.trySend(Unit) - scope.appScope.launch(dispatcherProvider.default) { - delay(backoffMs) - trigger.trySend(Unit) - } - } else { - val cooldownMs = TimeUnit.MINUTES.toMillis(5) - failedRequests[req.fileId] = req.copy(availableAt = System.currentTimeMillis() + cooldownMs) - downloadWaiters.remove(req.fileId)?.cancel() - } - } - - private suspend fun handleNotFoundDownloadFailure(req: DownloadRequest) { - val nextRetry = req.retryCount + 1 - val maxRetries = if (req.type == DownloadType.STICKER) 10 else 4 - val cooldownMs = (notFoundCooldownMs * nextRetry.coerceAtMost(6)).coerceAtMost(TimeUnit.MINUTES.toMillis(15)) - val availableAt = System.currentTimeMillis() + cooldownMs - notFoundCooldownUntil[req.fileId] = availableAt - - if (nextRetry <= maxRetries) { - val nextReq = req.copy(retryCount = nextRetry, availableAt = availableAt) - stateMutex.withLock { - pendingRequests[req.fileId] = nextReq - failedRequests.remove(req.fileId) - } - trigger.trySend(Unit) - scope.appScope.launch(dispatcherProvider.default) { - delay(cooldownMs) - trigger.trySend(Unit) - } - } else { - failedRequests[req.fileId] = req.copy(availableAt = availableAt) - downloadWaiters.remove(req.fileId)?.cancel() - } - } - - private fun calculateBackoffMs(req: DownloadRequest, attempt: Int, errorCode: Int?): Long { - val baseMs = when { - errorCode == 429 -> 10_000L - req.type == DownloadType.VIDEO -> 8_000L - req.type == DownloadType.GIF -> 6_000L - else -> 4_000L - } - val capMs = when (req.type) { - DownloadType.VIDEO -> TimeUnit.MINUTES.toMillis(3) - DownloadType.STICKER, DownloadType.VIDEO_NOTE -> TimeUnit.MINUTES.toMillis(2) - else -> TimeUnit.MINUTES.toMillis(5) - } - val scaled = (baseMs * attempt.coerceAtMost(8)).coerceAtMost(capMs) - val jitter = Random.nextLong(250L, 1_250L) - return scaled + jitter - } - - private fun retryFailedDownloads() { - val now = System.currentTimeMillis() - val toRetry = failedRequests.filter { it.value.availableAt <= now } - toRetry.forEach { (id, req) -> - failedRequests.remove(id) - enqueue(id, req.priority, req.type, req.offset, req.limit, req.synchronous) - } - } - - private fun cleanupDeadState() { - val now = System.currentTimeMillis() - - notFoundCooldownUntil.entries.removeIf { it.value <= now } - failedRequests.entries.removeIf { now - it.value.availableAt > TimeUnit.MINUTES.toMillis(30) } - - val live = HashSet(pendingRequests.size + activeRequests.size + failedRequests.size) - live.addAll(pendingRequests.keys) - live.addAll(activeRequests.keys) - live.addAll(failedRequests.keys) - - fileDownloadTypes.entries.removeIf { it.key !in live } - lastProgressAt.entries.removeIf { !activeRequests.containsKey(it.key) } - stalledRecoveryAt.entries.removeIf { !activeRequests.containsKey(it.key) } - - val completedStandalone = registry.standaloneFileIds.filter { fileId -> - cache.fileCache[fileId]?.local?.isDownloadingCompleted == true - } - completedStandalone.forEach { registry.standaloneFileIds.remove(it) } - } - - private fun recoverStalledDownloads() { - val now = System.currentTimeMillis() - activeRequests.values.forEach { req -> - val timeoutMs = when (req.type) { - DownloadType.STICKER -> stickerStallMs - DownloadType.DEFAULT, DownloadType.GIF, DownloadType.VIDEO_NOTE -> defaultStallMs - DownloadType.VIDEO -> TimeUnit.MINUTES.toMillis(2) - } - val lastProgress = lastProgressAt[req.fileId] ?: req.createdAt - if (now - lastProgress >= timeoutMs) { - val recoveredAt = stalledRecoveryAt[req.fileId] ?: 0L - if (now - recoveredAt < stalledRecoveryCooldownMs) return@forEach - stalledRecoveryAt[req.fileId] = now - - scope.appScope.launch(dispatcherProvider.default) { - val recovered = stateMutex.withLock { - val active = activeRequests[req.fileId] ?: return@withLock false - if (active.createdAt != req.createdAt || active.availableAt != req.availableAt) return@withLock false - - activeRequests.remove(req.fileId) - pendingRequests[req.fileId] = mergeRequests( - pendingRequests[req.fileId] ?: req, - req.copy( - priority = if (req.type == DownloadType.STICKER) maxOf(req.priority, 32) else maxOf(req.priority, 16), - availableAt = System.currentTimeMillis() + 250L, - createdAt = System.currentTimeMillis() - ) - ) - true - } - - if (recovered) { - coRunCatching { - withContext(dispatcherProvider.io) { - gateway.execute(TdApi.CancelDownloadFile(req.fileId, false)) - } - } - lastProgressAt[req.fileId] = System.currentTimeMillis() - trigger.trySend(Unit) - } - } - } - } - } - - private suspend fun finishTask(fileId: Int) { - stateMutex.withLock { - activeRequests.remove(fileId) - } - stalledRecoveryAt.remove(fileId) - trigger.trySend(Unit) - } - - fun updateFileCache(file: TdApi.File) { - val oldFile = cache.fileCache[file.id] - cache.fileCache[file.id] = file - val now = System.currentTimeMillis() - if (file.local.downloadedSize > (oldFile?.local?.downloadedSize ?: -1)) { - lastProgressAt[file.id] = now - } - if (file.local.isDownloadingActive || file.local.isDownloadingCompleted) { - notFoundCooldownUntil.remove(file.id) - lastProgressAt[file.id] = now - } - - if (file.local.isDownloadingCompleted) { - manualDownloadIds.remove(file.id) - failedRequests.remove(file.id) - stalledRecoveryAt.remove(file.id) - lastProgressAt.remove(file.id) - scope.appScope.launch { - stateMutex.withLock { pendingRequests.remove(file.id) } - } - notifyDownloadComplete(file.id) - } else if (oldFile?.local?.isDownloadingActive == true && !file.local.isDownloadingActive) { - val type = fileDownloadTypes[file.id] - if (type == DownloadType.STICKER || manualDownloadIds.contains(file.id)) { - scope.appScope.launch(dispatcherProvider.default) { - enqueue( - fileId = file.id, - priority = if (type == DownloadType.STICKER) 32 else calculatePriority(file.id), - type = type ?: DownloadType.DEFAULT - ) - } - } else { - manualDownloadIds.remove(file.id) - } - } - - if (file.remote.isUploadingCompleted) { - notifyUploadComplete(file.id) - } - } - - fun isFileQueued(fileId: Int) = pendingRequests.containsKey(fileId) || activeRequests.containsKey(fileId) - - fun setChatOpened(chatId: Long) { - openChatIds.add(chatId) - activeChatId = chatId - flushIrrelevantBackgroundDownloads() - } - - fun setChatClosed(chatId: Long) { - openChatIds.remove(chatId) - visibleMessageIds.remove(chatId) - nearbyMessageIds.remove(chatId) - if (activeChatId == chatId) activeChatId = 0L - registry.unregisterChat(chatId) - cancelIrrelevantDownloads() - } - - fun updateVisibleRange(chatId: Long, visible: List, nearby: List) { - visibleMessageIds[chatId] = visible.toSet() - nearbyMessageIds[chatId] = nearby.toSet() - activeChatId = chatId - - scope.appScope.launch(dispatcherProvider.default) { - cancelIrrelevantDownloads() - (visible + nearby).forEach { messageId -> - registry.getFileIdsForMessage(chatId, messageId).forEach { fileId -> - fileDownloadTypes[fileId]?.let { type -> - enqueue(fileId, calculatePriority(fileId), type) - } - } - } - } - } - - fun enqueue( - fileId: Int, - priority: Int = 1, - type: DownloadType = DownloadType.DEFAULT, - offset: Long = 0, - limit: Long = 0, - synchronous: Boolean = false, - ignoreSuppression: Boolean = false - ) { - scope.appScope.launch(dispatcherProvider.default) { - if (!ignoreSuppression && suppressedAutoDownloadIds.contains(fileId)) { - return@launch - } - - val isManualRequest = priority >= 32 - if (isManualRequest) manualDownloadIds.add(fileId) - - val cooldownUntil = notFoundCooldownUntil[fileId] - if (!isManualRequest && cooldownUntil != null && cooldownUntil > System.currentTimeMillis()) { - return@launch - } - if (cooldownUntil != null && cooldownUntil <= System.currentTimeMillis()) { - notFoundCooldownUntil.remove(fileId) - } - - if (registry.getMessages(fileId).isEmpty()) registry.standaloneFileIds.add(fileId) - if (type != DownloadType.DEFAULT || !fileDownloadTypes.containsKey(fileId)) { - fileDownloadTypes[fileId] = type - } - - val cached = cache.fileCache[fileId] - if (cached?.local?.isDownloadingCompleted == true) { - notifyDownloadComplete(fileId) - manualDownloadIds.remove(fileId) - return@launch - } - - val resolvedType = if (type == DownloadType.DEFAULT) { - fileDownloadTypes[fileId] ?: DownloadType.DEFAULT - } else { - type - } - - val finalOffset = if (resolvedType == DownloadType.STICKER || resolvedType == DownloadType.VIDEO_NOTE) 0L else offset - val finalLimit = if (resolvedType == DownloadType.STICKER || resolvedType == DownloadType.VIDEO_NOTE) 0L else limit - - val prio = calculatePriority(fileId).coerceAtLeast(priority) - val isManual = manualDownloadIds.contains(fileId) - val req = DownloadRequest( - fileId = fileId, - priority = prio, - type = resolvedType, - offset = finalOffset, - limit = finalLimit, - synchronous = synchronous, - createdAt = System.currentTimeMillis(), - availableAt = System.currentTimeMillis(), - isManual = isManual - ) - - stateMutex.withLock { - val active = activeRequests[fileId] - if (active != null) { - val merged = mergeRequests(active, req) - val shouldKick = merged != active || cache.fileCache[fileId]?.local?.isDownloadingActive != true - if (shouldKick) { - activeRequests[fileId] = merged - scope.appScope.launch(dispatcherProvider.io) { - try { - gateway.execute( - TdApi.DownloadFile( - fileId, - merged.priority, - merged.offset, - merged.limit, - merged.synchronous - ) - ) - } catch (_: Exception) { - } - } - } - return@launch - } - - val pending = pendingRequests[fileId] - if (pending != null) { - pendingRequests[fileId] = mergeRequests(pending, req) - } else { - if (!isManual && resolvedType == DownloadType.DEFAULT) { - val pendingDefaultCount = pendingRequests.values.count { - !it.isManual && it.type == DownloadType.DEFAULT - } - if (pendingDefaultCount >= maxPendingDefaultAutoDownloads) { - return@launch - } - } - pendingRequests[fileId] = req - } - } - trigger.trySend(Unit) - } - } - - fun cancelDownload(fileId: Int, force: Boolean = false, suppress: Boolean = true) { - if (!force && manualDownloadIds.contains(fileId)) return - - if (suppress) { - suppressedAutoDownloadIds.add(fileId) - } - - scope.appScope.launch(dispatcherProvider.io) { - try { - gateway.execute(TdApi.CancelDownloadFile(fileId, false)) - } catch (_: Exception) { - } - - stateMutex.withLock { - pendingRequests.remove(fileId) - activeRequests.remove(fileId) - failedRequests.remove(fileId) - } - Log.d("DownloadDebug", "queue.cancel.cleared: fileId=$fileId") - notifyDownloadCancelled(fileId) - } - } - - fun clearSuppression(fileId: Int) { - if (suppressedAutoDownloadIds.remove(fileId)) { - Log.d("DownloadDebug", "queue.suppression.cleared: fileId=$fileId") - } - } - - fun waitForDownload(fileId: Int): CompletableDeferred { - val cached = cache.fileCache[fileId] - if (cached?.local?.isDownloadingCompleted == true) return CompletableDeferred(Unit) - return downloadWaiters.getOrPut(fileId) { CompletableDeferred() } - } - - fun waitForUpload(fileId: Int): CompletableDeferred { - if (cache.fileCache[fileId]?.remote?.isUploadingCompleted == true) return CompletableDeferred(Unit) - return uploadWaiters.getOrPut(fileId) { CompletableDeferred() } - } - - fun notifyDownloadComplete(fileId: Int) { - downloadWaiters.remove(fileId)?.complete(Unit) - } - - fun notifyDownloadCancelled(fileId: Int) { - downloadWaiters.remove(fileId)?.cancel() - } - - fun notifyUploadComplete(fileId: Int) { - uploadWaiters.remove(fileId)?.complete(Unit) - } - - fun notifyUploadCancelled(fileId: Int) { - uploadWaiters.remove(fileId)?.cancel() - } - - private fun isStillRelevant(fileId: Int): Boolean { - if (manualDownloadIds.contains(fileId)) return true - if (registry.standaloneFileIds.contains(fileId)) return true - val type = fileDownloadTypes[fileId] - if (type == DownloadType.STICKER || type == DownloadType.VIDEO_NOTE) return true - - return registry.getMessages(fileId).any { (chatId, msgId) -> - openChatIds.contains(chatId) && - (visibleMessageIds[chatId]?.contains(msgId) == true || - nearbyMessageIds[chatId]?.contains(msgId) == true) - } - } - - private fun calculatePriority(fileId: Int): Int { - if (manualDownloadIds.contains(fileId)) return 32 - - val messages = registry.getMessages(fileId) - var max = 1 - val type = fileDownloadTypes[fileId] - - if (type == DownloadType.STICKER || type == DownloadType.VIDEO_NOTE) { - max = 32 - } - - messages.forEach { (chatId, msgId) -> - val isVisible = visibleMessageIds[chatId]?.contains(msgId) == true - val isNearby = nearbyMessageIds[chatId]?.contains(msgId) == true - - var p = 1 - if (isVisible) { - p = if (chatId == activeChatId) 32 else 24 - } else if (isNearby) { - p = if (chatId == activeChatId) 16 else 8 - } - - max = maxOf(max, p) - } - return max - } - - private fun mergeRequests(old: DownloadRequest, new: DownloadRequest): DownloadRequest { - val p = maxOf(old.priority, new.priority) - val isManual = old.isManual || new.isManual - - val curEnd = if (old.limit == 0L) Long.MAX_VALUE else old.offset + old.limit - val newEnd = if (new.limit == 0L) Long.MAX_VALUE else new.offset + new.limit - val start = minOf(old.offset, new.offset) - val end = if (curEnd == Long.MAX_VALUE || newEnd == Long.MAX_VALUE) Long.MAX_VALUE else maxOf(curEnd, newEnd) - val limit = if (end == Long.MAX_VALUE) 0L else end - start - - return old.copy( - priority = p, - isManual = isManual, - offset = start, - limit = limit, - availableAt = minOf(old.availableAt, new.availableAt) - ) - } - - private fun cancelIrrelevantDownloads() { - scope.appScope.launch(dispatcherProvider.default) { - val toCancel = mutableListOf() - - for ((fileId, _) in pendingRequests) { - if (!isStillRelevant(fileId)) toCancel.add(fileId) - } - - toCancel.forEach { fileId -> cancelDownload(fileId, force = false, suppress = false) } - } - } - - private fun flushIrrelevantBackgroundDownloads() { - scope.appScope.launch(dispatcherProvider.default) { - val toCancel = mutableListOf() - - stateMutex.withLock { - val candidateIds = HashSet(pendingRequests.size + activeRequests.size) - candidateIds.addAll(pendingRequests.keys) - candidateIds.addAll(activeRequests.keys) - - candidateIds.forEach { fileId -> - if (manualDownloadIds.contains(fileId)) return@forEach - - val type = fileDownloadTypes[fileId] - if (type == DownloadType.STICKER || type == DownloadType.VIDEO_NOTE) return@forEach - - val belongsToOpenChat = registry.getMessages(fileId).any { (chatId, _) -> - openChatIds.contains(chatId) - } - - if (!belongsToOpenChat) { - toCancel.add(fileId) - } - } - } - - toCancel.forEach { fileId -> cancelDownload(fileId, force = false, suppress = false) } - } - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/infra/FileMessageRegistry.kt b/data/src/main/java/org/monogram/data/infra/FileMessageRegistry.kt deleted file mode 100644 index d2d9fe3b..00000000 --- a/data/src/main/java/org/monogram/data/infra/FileMessageRegistry.kt +++ /dev/null @@ -1,64 +0,0 @@ -package org.monogram.data.infra - -import java.util.concurrent.ConcurrentHashMap - -class FileMessageRegistry { - val fileIdToMessageMap = ConcurrentHashMap>>() - private val messageToFileMap = ConcurrentHashMap, MutableSet>() - val standaloneFileIds = ConcurrentHashMap.newKeySet() - - fun register(fileId: Int, chatId: Long, messageId: Long) { - val key = chatId to messageId - fileIdToMessageMap.computeIfAbsent(fileId) { ConcurrentHashMap.newKeySet() }.add(key) - messageToFileMap.computeIfAbsent(key) { ConcurrentHashMap.newKeySet() }.add(fileId) - } - - fun removeMessages(chatId: Long, messageIds: List) { - messageIds.forEach { messageId -> - val key = chatId to messageId - messageToFileMap.remove(key)?.forEach { fileId -> - fileIdToMessageMap[fileId]?.let { set -> - set.remove(key) - if (set.isEmpty()) fileIdToMessageMap.remove(fileId) - } - } - } - } - - fun unregisterChat(chatId: Long) { - val it = messageToFileMap.entries.iterator() - while (it.hasNext()) { - val entry = it.next() - if (entry.key.first == chatId) { - val key = entry.key - val fileIds = entry.value - fileIds.forEach { fileId -> - fileIdToMessageMap[fileId]?.let { set -> - set.remove(key) - if (set.isEmpty()) fileIdToMessageMap.remove(fileId) - } - } - it.remove() - } - } - } - - fun updateMessageId(chatId: Long, oldId: Long, newId: Long) { - val oldKey = chatId to oldId - val newKey = chatId to newId - val fileIds = messageToFileMap.remove(oldKey) ?: return - messageToFileMap.computeIfAbsent(newKey) { ConcurrentHashMap.newKeySet() }.addAll(fileIds) - fileIds.forEach { fileId -> - fileIdToMessageMap[fileId]?.let { set -> - set.remove(oldKey) - set.add(newKey) - } - } - } - - fun getMessages(fileId: Int): Set> = - fileIdToMessageMap[fileId] ?: emptySet() - - fun getFileIdsForMessage(chatId: Long, messageId: Long): Set = - messageToFileMap[chatId to messageId] ?: emptySet() -} diff --git a/data/src/main/java/org/monogram/data/infra/FileUpdateHandler.kt b/data/src/main/java/org/monogram/data/infra/FileUpdateHandler.kt deleted file mode 100644 index 9002a3e9..00000000 --- a/data/src/main/java/org/monogram/data/infra/FileUpdateHandler.kt +++ /dev/null @@ -1,107 +0,0 @@ -package org.monogram.data.infra - -import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.asSharedFlow -import kotlinx.coroutines.launch -import org.drinkless.tdlib.TdApi -import org.monogram.core.ScopeProvider -import org.monogram.data.gateway.UpdateDispatcher -import java.util.concurrent.ConcurrentHashMap - -class FileUpdateHandler( - private val registry: FileMessageRegistry, - private val queue: FileDownloadQueue, - private val updates: UpdateDispatcher, - private val scope: ScopeProvider -) { - val customEmojiPaths = ConcurrentHashMap() - val fileIdToCustomEmojiId = ConcurrentHashMap() - - private val _downloadProgress = MutableSharedFlow>(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) - private val _downloadCompleted = MutableSharedFlow>(extraBufferCapacity = 64, onBufferOverflow = BufferOverflow.DROP_OLDEST) - private val _fileDownloadProgress = - MutableSharedFlow>(extraBufferCapacity = 64, onBufferOverflow = BufferOverflow.DROP_OLDEST) - private val _fileDownloadCompleted = - MutableSharedFlow>(extraBufferCapacity = 64, onBufferOverflow = BufferOverflow.DROP_OLDEST) - private val _uploadProgress = MutableSharedFlow>(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) - - val downloadProgress = _downloadProgress.asSharedFlow() - val downloadCompleted = _downloadCompleted.asSharedFlow() - val fileDownloadProgress = _fileDownloadProgress.asSharedFlow() - val fileDownloadCompleted = _fileDownloadCompleted.asSharedFlow() - val uploadProgress = _uploadProgress.asSharedFlow() - - init { - scope.appScope.launch { - updates.file.collect { update -> handle(update.file) } - } - } - - private fun handle(file: TdApi.File) { - queue.updateFileCache(file) - - val downloading = file.local?.isDownloadingActive == true - val downloadDone = file.local?.isDownloadingCompleted == true - val uploading = file.remote?.isUploadingActive == true - val uploadDone = file.remote?.isUploadingCompleted == true - - if (downloadDone) queue.notifyDownloadComplete(file.id) - - if (uploadDone) queue.notifyUploadComplete(file.id) - - val entries = registry.getMessages(file.id) - if (entries.isNotEmpty()) { - scope.appScope.launch { - if (downloadDone) { - handleCustomEmoji(file.id, file.local?.path ?: "") - _fileDownloadCompleted.emit(file.id.toLong() to (file.local?.path ?: "")) - _fileDownloadProgress.emit(file.id.toLong() to 1f) - entries.forEach { (_, msgId) -> - _downloadCompleted.emit(msgId to (file.local?.path ?: "")) - _downloadProgress.emit(msgId to 1f) - } - } else if (downloading) { - val progress = if (file.size > 0) file.local!!.downloadedSize.toFloat() / file.size else 0f - _fileDownloadProgress.emit(file.id.toLong() to progress) - entries.forEach { (_, msgId) -> _downloadProgress.emit(msgId to progress) } - } - if (uploadDone) { - entries.forEach { (_, msgId) -> _uploadProgress.emit(msgId to 1f) } - } else if (uploading) { - val progress = if (file.size > 0) file.remote!!.uploadedSize.toFloat() / file.size else 0f - entries.forEach { (_, msgId) -> _uploadProgress.emit(msgId to progress) } - } - } - } else if (registry.standaloneFileIds.contains(file.id)) { - scope.appScope.launch { - if (downloadDone) { - _fileDownloadCompleted.emit(file.id.toLong() to (file.local?.path ?: "")) - _fileDownloadProgress.emit(file.id.toLong() to 1f) - _downloadCompleted.emit(file.id.toLong() to (file.local?.path ?: "")) - _downloadProgress.emit(file.id.toLong() to 1f) - registry.standaloneFileIds.remove(file.id) - } else if (downloading) { - val progress = if (file.size > 0) file.local!!.downloadedSize.toFloat() / file.size else 0f - _fileDownloadProgress.emit(file.id.toLong() to progress) - _downloadProgress.emit(file.id.toLong() to progress) - } - } - } else { - scope.appScope.launch { - if (downloadDone) { - _fileDownloadCompleted.emit(file.id.toLong() to (file.local?.path ?: "")) - _fileDownloadProgress.emit(file.id.toLong() to 1f) - } else if (downloading) { - val progress = if (file.size > 0) file.local!!.downloadedSize.toFloat() / file.size else 0f - _fileDownloadProgress.emit(file.id.toLong() to progress) - } - } - } - } - - private fun handleCustomEmoji(fileId: Int, path: String) { - val emojiId = fileIdToCustomEmojiId[fileId] ?: return - customEmojiPaths[emojiId] = path - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/infra/OfflineWarmup.kt b/data/src/main/java/org/monogram/data/infra/OfflineWarmup.kt deleted file mode 100644 index 262cc08b..00000000 --- a/data/src/main/java/org/monogram/data/infra/OfflineWarmup.kt +++ /dev/null @@ -1,259 +0,0 @@ -package org.monogram.data.infra - -import org.monogram.data.core.coRunCatching -import android.util.Log -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import org.drinkless.tdlib.TdApi -import org.monogram.core.DispatcherProvider -import org.monogram.core.ScopeProvider -import org.monogram.data.chats.ChatCache -import org.monogram.data.db.dao.* -import org.monogram.data.db.model.ChatEntity -import org.monogram.data.db.model.UserEntity -import org.monogram.data.gateway.TelegramGateway -import org.monogram.data.mapper.MessageMapper -import org.monogram.data.mapper.user.toEntity -import org.monogram.domain.repository.StickerRepository - -private const val TAG = "OfflineWarmup" - -class OfflineWarmup( - private val scopeProvider: ScopeProvider, - private val dispatchers: DispatcherProvider, - private val gateway: TelegramGateway, - private val chatDao: ChatDao, - private val messageDao: MessageDao, - private val userDao: UserDao, - private val userFullInfoDao: UserFullInfoDao, - private val chatFullInfoDao: ChatFullInfoDao, - private val messageMapper: MessageMapper, - private val chatCache: ChatCache, - private val stickerRepository: StickerRepository -) { - private val scope = scopeProvider.appScope - - init { - scope.launch(dispatchers.io) { - delay(1800) - coRunCatching { warmup() } - .onFailure { Log.e(TAG, "Offline warmup failed", it) } - } - } - - private suspend fun warmup() { - val topChats = chatDao.getTopChats(limit = 100) - if (topChats.isEmpty()) return - - warmupStickers() - warmupUsers(topChats) - warmupChatFullInfo(topChats) - warmupMessages(topChats) - } - - private suspend fun warmupStickers() { - coRunCatching { stickerRepository.loadInstalledStickerSets() } - coRunCatching { stickerRepository.loadCustomEmojiStickerSets() } - } - - private suspend fun warmupUsers(chats: List) { - val userIds = LinkedHashSet() - chats.forEach { chat -> - if (chat.privateUserId != 0L) userIds.add(chat.privateUserId) - chat.messageSenderId?.takeIf { it > 0 }?.let { userIds.add(it) } - messageDao.getLatestMessages(chat.id, 20) - .asSequence() - .map { it.senderId } - .filter { it > 0L } - .forEach { userIds.add(it) } - } - if (userIds.isEmpty()) return - - val limited = userIds.take(80) - val existingUsers = userDao.getUsersByIds(limited).associateBy { it.id } - val existingFullInfos = userFullInfoDao.getUserFullInfos(limited).associateBy { it.userId } - val now = System.currentTimeMillis() - - for (userId in limited) { - val cachedUser = existingUsers[userId] - var hasUser = cachedUser != null - if (cachedUser == null || now - cachedUser.createdAt > ONE_DAY_MS) { - val user = coRunCatching { gateway.execute(TdApi.GetUser(userId)) as? TdApi.User }.getOrNull() - if (user != null) { - val personalAvatarPath = existingFullInfos[userId]?.personalPhotoPath?.ifBlank { null } - userDao.insertUser(user.toUserEntity(personalAvatarPath)) - chatCache.putUser(user) - hasUser = true - } else if (cachedUser == null) { - hasUser = false - } - } - - if (!hasUser) { - delay(25) - continue - } - - val cachedFullInfo = existingFullInfos[userId] - if (cachedFullInfo == null || now - cachedFullInfo.createdAt > SEVEN_DAYS_MS) { - val fullInfo = coRunCatching { - gateway.execute(TdApi.GetUserFullInfo(userId)) as? TdApi.UserFullInfo - }.getOrNull() - if (fullInfo != null) { - userFullInfoDao.insertUserFullInfo(fullInfo.toEntity(userId)) - val personalAvatarPath = fullInfo.extractPersonalAvatarPath() - if (!personalAvatarPath.isNullOrBlank()) { - userDao.getUser(userId)?.let { existing -> - if (existing.personalAvatarPath != personalAvatarPath) { - userDao.insertUser(existing.copy(personalAvatarPath = personalAvatarPath)) - } - } - } - chatCache.putUserFullInfo(userId, fullInfo) - } - } - delay(25) - } - } - - private suspend fun warmupChatFullInfo(chats: List) { - val targetChats = chats.take(50) - val existing = chatFullInfoDao.getChatFullInfos(targetChats.map { it.id }).associateBy { it.chatId } - val now = System.currentTimeMillis() - - for (chat in targetChats) { - val cached = existing[chat.id] - if (cached != null && now - cached.createdAt <= SEVEN_DAYS_MS) { - continue - } - - when { - chat.supergroupId != 0L -> { - val supergroupInfo = gateway.execute(TdApi.GetSupergroupFullInfo(chat.supergroupId)) as? TdApi.SupergroupFullInfo - if (supergroupInfo != null) { - chatFullInfoDao.insertChatFullInfo(supergroupInfo.toEntity(chat.id)) - val supergroup = gateway.execute(TdApi.GetSupergroup(chat.supergroupId)) as? TdApi.Supergroup - if (supergroup != null) { - chatCache.putSupergroup(supergroup) - chatCache.putSupergroupFullInfo(chat.supergroupId, supergroupInfo) - } - } - } - - chat.basicGroupId != 0L -> { - val basicGroupInfo = gateway.execute(TdApi.GetBasicGroupFullInfo(chat.basicGroupId)) as? TdApi.BasicGroupFullInfo - if (basicGroupInfo != null) { - chatFullInfoDao.insertChatFullInfo(basicGroupInfo.toEntity(chat.id)) - val basicGroup = gateway.execute(TdApi.GetBasicGroup(chat.basicGroupId)) as? TdApi.BasicGroup - if (basicGroup != null) { - chatCache.putBasicGroup(basicGroup) - chatCache.putBasicGroupFullInfo(chat.basicGroupId, basicGroupInfo) - } - } - } - } - delay(30) - } - } - - private suspend fun warmupMessages(chats: List) { - val targetChats = chats.take(30) - for (chat in targetChats) { - val alreadyCachedCount = messageDao.getLatestMessages(chat.id, 25).size - if (alreadyCachedCount >= 25) { - continue - } - - val history = gateway.execute( - TdApi.GetChatHistory( - chat.id, - 0L, - 0, - 60, - false - ) - ) as? TdApi.Messages ?: continue - - if (history.messages.isEmpty()) { - continue - } - - history.messages.forEach { message -> chatCache.putMessage(message) } - val entities = history.messages.map { message -> - messageMapper.mapToEntity(message) { senderId -> - chatCache.getUser(senderId)?.let { cachedUser -> - listOfNotNull( - cachedUser.firstName.takeIf { it.isNotBlank() }, - cachedUser.lastName.takeIf { !it.isNullOrBlank() } - ).joinToString(" ") - } - } - } - messageDao.insertMessages(entities) - delay(40) - } - } - - private fun TdApi.User.toUserEntity(personalAvatarPath: String?): UserEntity { - val usernamesData = buildString { - append(usernames?.activeUsernames?.joinToString("|").orEmpty()) - append('\n') - append(usernames?.disabledUsernames?.joinToString("|").orEmpty()) - append('\n') - append(usernames?.editableUsername.orEmpty()) - append('\n') - append(usernames?.collectibleUsernames?.joinToString("|").orEmpty()) - } - - val statusType = when (status) { - is TdApi.UserStatusOnline -> "ONLINE" - is TdApi.UserStatusRecently -> "RECENTLY" - is TdApi.UserStatusLastWeek -> "LAST_WEEK" - is TdApi.UserStatusLastMonth -> "LAST_MONTH" - else -> "OFFLINE" - } - - val statusEmojiId = when (val type = emojiStatus?.type) { - is TdApi.EmojiStatusTypeCustomEmoji -> type.customEmojiId - is TdApi.EmojiStatusTypeUpgradedGift -> type.modelCustomEmojiId - else -> 0L - } - - return UserEntity( - id = id, - firstName = firstName, - lastName = lastName.ifEmpty { null }, - phoneNumber = phoneNumber.ifEmpty { null }, - avatarPath = profilePhoto?.small?.local?.path?.ifEmpty { null }, - personalAvatarPath = personalAvatarPath, - isPremium = isPremium, - isVerified = verificationStatus?.isVerified ?: false, - isSupport = isSupport, - isContact = isContact, - isMutualContact = isMutualContact, - isCloseFriend = isCloseFriend, - haveAccess = haveAccess, - username = usernames?.activeUsernames?.firstOrNull(), - usernamesData = usernamesData, - statusType = statusType, - accentColorId = accentColorId, - profileAccentColorId = profileAccentColorId, - statusEmojiId = statusEmojiId, - languageCode = languageCode.ifEmpty { null }, - lastSeen = (status as? TdApi.UserStatusOffline)?.wasOnline?.toLong() ?: 0L, - createdAt = System.currentTimeMillis() - ) - } - - private fun TdApi.UserFullInfo.extractPersonalAvatarPath(): String? { - val bestPhotoSize = personalPhoto?.sizes?.maxByOrNull { it.width.toLong() * it.height.toLong() } - ?: personalPhoto?.sizes?.lastOrNull() - return personalPhoto?.animation?.file?.local?.path?.ifEmpty { null } - ?: bestPhotoSize?.photo?.local?.path?.ifEmpty { null } - } - - private companion object { - private const val ONE_DAY_MS = 24L * 60 * 60 * 1000 - private const val SEVEN_DAYS_MS = 7L * ONE_DAY_MS - } -} diff --git a/data/src/main/java/org/monogram/data/infra/SponsorSyncManager.kt b/data/src/main/java/org/monogram/data/infra/SponsorSyncManager.kt deleted file mode 100644 index d6f20302..00000000 --- a/data/src/main/java/org/monogram/data/infra/SponsorSyncManager.kt +++ /dev/null @@ -1,240 +0,0 @@ -package org.monogram.data.infra - -import org.monogram.data.core.coRunCatching -import android.util.Log -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import org.drinkless.tdlib.TdApi -import org.monogram.core.ScopeProvider -import org.monogram.data.db.dao.SponsorDao -import org.monogram.data.db.model.SponsorEntity -import org.monogram.data.gateway.TelegramGateway -import org.monogram.data.mapper.updateSponsorIds -import org.monogram.domain.repository.AuthRepository -import org.monogram.domain.repository.AuthStep -import java.util.concurrent.atomic.AtomicBoolean - -private const val TAG = "SponsorSync" -private const val SPONSOR_CHANNEL_ID = -1003640797855L -private const val SPONSOR_CHANNEL_USERNAME = "ahhfjfbdnejjfbfjdjdj" -private const val HISTORY_LIMIT = 100 -private const val HISTORY_BATCHES_LIMIT = 20 -private const val SINGLE_RESULT_RETRY_DELAY_MS = 1500L -private const val AUTH_CHECK_INTERVAL_MS = 5L * 60L * 1000L -private const val POST_LOGIN_SYNC_DELAY_MS = 60L * 1000L -private const val ONE_DAY_MS = 24L * 60L * 60L * 1000L - -class SponsorSyncManager( - private val scopeProvider: ScopeProvider, - private val gateway: TelegramGateway, - private val sponsorDao: SponsorDao, - private val authRepository: AuthRepository -) { - private val started = AtomicBoolean(false) - private val syncInProgress = AtomicBoolean(false) - - init { - start() - } - - fun start() { - if (!started.compareAndSet(false, true)) return - - scopeProvider.appScope.launch(Dispatchers.IO) { - loadFromDatabase() - - var wasAuthorized = authRepository.authState.value is AuthStep.Ready - if (wasAuthorized) { - syncOnce(force = true) - } - - while (true) { - val isAuthorized = authRepository.authState.value is AuthStep.Ready - if (!isAuthorized) { - wasAuthorized = false - delay(AUTH_CHECK_INTERVAL_MS) - continue - } - - if (!wasAuthorized) { - wasAuthorized = true - Log.d(TAG, "User authorized, delaying sponsor sync for app init") - delay(POST_LOGIN_SYNC_DELAY_MS) - syncOnce(force = true) - continue - } - - if (sponsorDao.getAllIds().isEmpty()) { - Log.d(TAG, "No sponsors in DB, syncing immediately") - syncOnce(force = true) - continue - } - - delay(ONE_DAY_MS) - syncOnce(force = false) - } - } - } - - fun forceSync() { - scopeProvider.appScope.launch(Dispatchers.IO) { - syncOnce(force = true) - } - } - - private suspend fun loadFromDatabase() { - val cachedIds = sponsorDao.getAllIds().toSet() - updateSponsorIds(cachedIds) - Log.d(TAG, "Loaded ${cachedIds.size} sponsor ids from DB") - } - - private suspend fun syncOnce(force: Boolean) { - if (!syncInProgress.compareAndSet(false, true)) return - - try { - if (authRepository.authState.value !is AuthStep.Ready) { - Log.d(TAG, "Skipping sponsor sync: user is not authorized") - return - } - - val latestUpdatedAt = sponsorDao.getLatestUpdatedAt() ?: 0L - val age = System.currentTimeMillis() - latestUpdatedAt - if (!force && latestUpdatedAt > 0L && age < ONE_DAY_MS) { - Log.d(TAG, "Skipping sync: last sync ${age}ms ago") - return - } - - Log.d(TAG, "Sponsor sync started (force=$force)") - val sponsorChatId = resolveSponsorChatId() - var historyMessages = loadSponsorHistoryMessages(sponsorChatId) ?: run { - Log.e(TAG, "Sponsor sync failed: unable to load sponsor history") - return - } - - var parsedIds = parseSponsorIds(historyMessages) - if (parsedIds.size == 1) { - Log.w(TAG, "Only one sponsor id parsed, retrying history load") - delay(SINGLE_RESULT_RETRY_DELAY_MS) - val retryMessages = loadSponsorHistoryMessages(sponsorChatId) - if (retryMessages != null) { - val retryParsedIds = parseSponsorIds(retryMessages) - if (retryParsedIds.size > parsedIds.size) { - historyMessages = retryMessages - parsedIds = retryParsedIds - Log.d(TAG, "Retry loaded more sponsor ids: ${parsedIds.size}") - } else { - Log.w(TAG, "Retry didn't improve sponsor ids: ${retryParsedIds.size}") - } - } - } - - val oldIds = sponsorDao.getAllIds().toSet() - - val now = System.currentTimeMillis() - val actualIds = when { - parsedIds.isEmpty() && oldIds.isNotEmpty() -> { - Log.w(TAG, "Parsed empty sponsor list, keeping existing ${oldIds.size} ids") - oldIds - } - parsedIds.isEmpty() -> { - sponsorDao.clearAll() - emptySet() - } - else -> { - sponsorDao.insertAll(parsedIds.map { userId -> - SponsorEntity( - userId = userId, - sourceChannelId = sponsorChatId, - updatedAt = now - ) - }) - sponsorDao.deleteNotIn(parsedIds.toList()) - parsedIds - } - } - - updateSponsorIds(actualIds) - - val added = actualIds - oldIds - val removed = oldIds - actualIds - Log.d( - TAG, - "Sponsor sync finished: messages=${historyMessages.size}, ids=${actualIds.size}, added=${added.size}, removed=${removed.size}" - ) - } catch (t: Throwable) { - Log.e(TAG, "Sponsor sync failed", t) - } finally { - syncInProgress.set(false) - } - } - - private suspend fun resolveSponsorChatId(): Long { - val chat = coRunCatching { - gateway.execute(TdApi.SearchPublicChat(SPONSOR_CHANNEL_USERNAME)) as? TdApi.Chat - }.getOrNull() - - return if (chat?.id != null) { - chat.id - } else { - Log.w(TAG, "Unable to resolve @$SPONSOR_CHANNEL_USERNAME, using fallback chatId=$SPONSOR_CHANNEL_ID") - SPONSOR_CHANNEL_ID - } - } - - private suspend fun loadSponsorHistoryMessages(chatId: Long): List? { - val result = mutableListOf() - val seenIds = HashSet() - var fromMessageId = 0L - - repeat(HISTORY_BATCHES_LIMIT) { - val batch = gateway.execute( - TdApi.GetChatHistory(chatId, fromMessageId, 0, HISTORY_LIMIT, false) - ) as? TdApi.Messages ?: return null - - if (batch.messages.isEmpty()) { - return result - } - - var oldestInBatch = Long.MAX_VALUE - batch.messages.forEach { message -> - if (seenIds.add(message.id)) { - result.add(message) - } - if (message.id in 1 until oldestInBatch) { - oldestInBatch = message.id - } - } - - if (batch.messages.size < HISTORY_LIMIT || oldestInBatch == Long.MAX_VALUE || oldestInBatch == fromMessageId) { - return result - } - - fromMessageId = oldestInBatch - } - - return result - } - - private fun parseSponsorIds(messages: List): Set { - val idRegex = Regex("\\b\\d{5,20}\\b") - return messages.asSequence() - .mapNotNull { message -> extractText(message.content) } - .flatMap { text -> idRegex.findAll(text).map { it.value } } - .mapNotNull { it.toLongOrNull() } - .toSet() - } - - private fun extractText(content: TdApi.MessageContent): String? { - return when (content) { - is TdApi.MessageText -> content.text.text - is TdApi.MessagePhoto -> content.caption.text - is TdApi.MessageVideo -> content.caption.text - is TdApi.MessageDocument -> content.caption.text - is TdApi.MessageAudio -> content.caption.text - is TdApi.MessageAnimation -> content.caption.text - is TdApi.MessageVoiceNote -> content.caption.text - else -> null - } - } -} diff --git a/data/src/main/java/org/monogram/data/mapper/AttachmentMenuBotMapper.kt b/data/src/main/java/org/monogram/data/mapper/AttachmentMenuBotMapper.kt deleted file mode 100644 index 97ea7d88..00000000 --- a/data/src/main/java/org/monogram/data/mapper/AttachmentMenuBotMapper.kt +++ /dev/null @@ -1,18 +0,0 @@ -package org.monogram.data.mapper - -import org.drinkless.tdlib.TdApi -import org.monogram.domain.models.AttachMenuBotIconModel -import org.monogram.domain.models.AttachMenuBotModel - -fun TdApi.AttachmentMenuBot.toDomain(): AttachMenuBotModel { - return AttachMenuBotModel( - botUserId = this.botUserId, - name = this.name, - icon = AttachMenuBotIconModel(name = this.name, icon = this.androidSideMenuIcon?.toDomain()), - requestWriteAccess = this.requestWriteAccess, - isAdded = this.isAdded, - showInSideMenu = this.showInSideMenu, - showInAttachMenu = this.showInAttachmentMenu, - showInDefaultMenu = this.showInSideMenu - ) -} diff --git a/data/src/main/java/org/monogram/data/mapper/AuthMapper.kt b/data/src/main/java/org/monogram/data/mapper/AuthMapper.kt deleted file mode 100644 index e570b5f0..00000000 --- a/data/src/main/java/org/monogram/data/mapper/AuthMapper.kt +++ /dev/null @@ -1,47 +0,0 @@ -package org.monogram.data.mapper - -import org.drinkless.tdlib.TdApi -import org.monogram.domain.repository.AuthStep - -fun TdApi.AuthorizationState.toDomain(): AuthStep = - when (this) { - is TdApi.AuthorizationStateReady -> - AuthStep.Ready - - is TdApi.AuthorizationStateWaitPhoneNumber -> - AuthStep.InputPhone - - is TdApi.AuthorizationStateWaitCode -> - AuthStep.InputCode( - codeType = this.codeInfo.type.javaClass.simpleName, - codeLength = this.codeInfo.type.let { type -> - when (type) { - is TdApi.AuthenticationCodeTypeTelegramMessage -> type.length - is TdApi.AuthenticationCodeTypeSms -> type.length - is TdApi.AuthenticationCodeTypeCall -> type.length - is TdApi.AuthenticationCodeTypeFlashCall -> 0 - is TdApi.AuthenticationCodeTypeMissedCall -> type.length - else -> 5 - } - }, - nextType = this.codeInfo.nextType?.javaClass?.simpleName, - timeout = this.codeInfo.timeout - ) - - is TdApi.AuthorizationStateWaitEmailCode -> - AuthStep.InputCode( - codeType = "Email", - codeLength = this.codeInfo.length, - isEmailCode = true, - emailPattern = this.codeInfo.emailAddressPattern - ) - - is TdApi.AuthorizationStateWaitPassword -> - AuthStep.InputPassword - - is TdApi.AuthorizationStateWaitTdlibParameters -> - AuthStep.WaitParameters - - else -> - AuthStep.Loading - } \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/mapper/ChatMapper.kt b/data/src/main/java/org/monogram/data/mapper/ChatMapper.kt deleted file mode 100644 index 26dc88ef..00000000 --- a/data/src/main/java/org/monogram/data/mapper/ChatMapper.kt +++ /dev/null @@ -1,586 +0,0 @@ -package org.monogram.data.mapper - -import android.text.format.DateUtils -import org.drinkless.tdlib.TdApi -import org.monogram.data.db.model.ChatEntity -import org.monogram.domain.models.* -import org.monogram.domain.repository.StringProvider -import java.text.SimpleDateFormat -import java.util.* - -class ChatMapper(private val stringProvider: StringProvider) { - fun mapChatToModel( - chat: TdApi.Chat, - order: Long, - isPinned: Boolean, - isArchived: Boolean, - smallPhotoPath: String?, - photoId: Int, - isOnline: Boolean, - userStatus: String, - isVerified: Boolean, - isSponsor: Boolean, - isForum: Boolean, - isBot: Boolean, - memberCount: Int, - onlineCount: Int, - emojiPath: String?, - typingAction: String?, - lastMessageText: String, - lastMessageEntities: List, - lastMessageTime: String, - lastMessageDate: Long, - isMuted: Boolean, - isAdmin: Boolean, - isMember: Boolean, - username: String? = null, - usernames: UsernamesModel? = null, - description: String? = null, - inviteLink: String? = null, - hasAutomaticTranslation: Boolean = false, - personalAvatarPath: String? = null - ): ChatModel { - val p = chat.permissions ?: TdApi.ChatPermissions() - val permissions = ChatPermissionsModel( - canSendBasicMessages = p.canSendBasicMessages, - canSendAudios = p.canSendAudios, - canSendDocuments = p.canSendDocuments, - canSendPhotos = p.canSendPhotos, - canSendVideos = p.canSendVideos, - canSendVideoNotes = p.canSendVideoNotes, - canSendVoiceNotes = p.canSendVoiceNotes, - canSendPolls = p.canSendPolls, - canSendOtherMessages = p.canSendOtherMessages, - canAddLinkPreviews = p.canAddLinkPreviews, - canEditTag = p.canEditTag, - canChangeInfo = p.canChangeInfo, - canInviteUsers = p.canInviteUsers, - canPinMessages = p.canPinMessages, - canCreateTopics = p.canCreateTopics, - ) - - val isChannel = (chat.type as? TdApi.ChatTypeSupergroup)?.isChannel ?: false - - val draft = chat.draftMessage?.inputMessageText as? TdApi.InputMessageText - val draftText = draft?.text?.text - val draftEntities = draft?.text?.entities?.map { mapEntity(it) } ?: emptyList() - - return ChatModel( - id = chat.id, - title = chat.title, - unreadCount = chat.unreadCount, - unreadMentionCount = chat.unreadMentionCount, - unreadReactionCount = chat.unreadReactionCount, - avatarPath = smallPhotoPath, - personalAvatarPath = personalAvatarPath, - lastMessageText = lastMessageText, - lastMessageEntities = lastMessageEntities, - lastMessageTime = lastMessageTime, - lastMessageDate = lastMessageDate, - order = order, - isGroup = chat.type is TdApi.ChatTypeBasicGroup || (chat.type is TdApi.ChatTypeSupergroup && !isChannel), - isSupergroup = chat.type is TdApi.ChatTypeSupergroup, - isChannel = isChannel, - memberCount = memberCount, - onlineCount = onlineCount, - photoId = photoId, - isPinned = isPinned, - isArchived = isArchived, - accentColorId = chat.accentColorId, - profileAccentColorId = chat.profileAccentColorId, - backgroundCustomEmojiId = chat.backgroundCustomEmojiId, - emojiStatusId = (chat.emojiStatus?.type as? TdApi.EmojiStatusTypeCustomEmoji)?.customEmojiId, - emojiStatusPath = emojiPath, - isAdmin = isAdmin, - isOnline = isOnline, - userStatus = userStatus, - typingAction = typingAction, - draftMessage = draftText, - draftMessageEntities = draftEntities, - isMuted = isMuted, - isMarkedAsUnread = chat.isMarkedAsUnread, - hasProtectedContent = chat.hasProtectedContent, - isTranslatable = chat.isTranslatable, - hasAutomaticTranslation = hasAutomaticTranslation, - messageAutoDeleteTime = chat.messageAutoDeleteTime, - canBeDeletedOnlyForSelf = chat.canBeDeletedOnlyForSelf, - canBeDeletedForAllUsers = chat.canBeDeletedForAllUsers, - canBeReported = chat.canBeReported, - lastReadInboxMessageId = chat.lastReadInboxMessageId, - lastReadOutboxMessageId = chat.lastReadOutboxMessageId, - lastMessageId = chat.lastMessage?.id ?: 0L, - isLastMessageOutgoing = chat.lastMessage?.isOutgoing ?: false, - replyMarkupMessageId = chat.replyMarkupMessageId, - messageSenderId = when (val sender = chat.messageSenderId) { - is TdApi.MessageSenderUser -> sender.userId - is TdApi.MessageSenderChat -> sender.chatId - else -> null - }, - blockList = chat.blockList != null, - isVerified = isVerified || isForcedVerifiedChat(chat.id), - isSponsor = isSponsor, - viewAsTopics = chat.viewAsTopics, - isForum = isForum, - isBot = isBot, - username = username, - usernames = usernames, - description = description, - inviteLink = inviteLink, - type = when (chat.type) { - is TdApi.ChatTypePrivate -> ChatType.PRIVATE - is TdApi.ChatTypeBasicGroup -> ChatType.BASIC_GROUP - is TdApi.ChatTypeSupergroup -> ChatType.SUPERGROUP - is TdApi.ChatTypeSecret -> ChatType.SECRET - else -> ChatType.PRIVATE - }, - permissions = permissions, - isMember = isMember - ) - } - - fun mapToDomain(entity: ChatEntity): ChatModel { - return ChatModel( - id = entity.id, - title = entity.title, - unreadCount = entity.unreadCount, - avatarPath = entity.avatarPath, - lastMessageText = entity.lastMessageText, - lastMessageTime = entity.lastMessageTime, - lastMessageDate = entity.lastMessageDate, - order = entity.order, - isPinned = entity.isPinned, - isMuted = entity.isMuted, - isChannel = entity.isChannel, - isGroup = entity.isGroup, - type = ChatType.valueOf(entity.type), - isArchived = entity.isArchived, - memberCount = entity.memberCount, - onlineCount = entity.onlineCount, - unreadMentionCount = entity.unreadMentionCount, - unreadReactionCount = entity.unreadReactionCount, - isMarkedAsUnread = entity.isMarkedAsUnread, - hasProtectedContent = entity.hasProtectedContent, - isTranslatable = entity.isTranslatable, - hasAutomaticTranslation = entity.hasAutomaticTranslation, - messageAutoDeleteTime = entity.messageAutoDeleteTime, - canBeDeletedOnlyForSelf = entity.canBeDeletedOnlyForSelf, - canBeDeletedForAllUsers = entity.canBeDeletedForAllUsers, - canBeReported = entity.canBeReported, - lastReadInboxMessageId = entity.lastReadInboxMessageId, - lastReadOutboxMessageId = entity.lastReadOutboxMessageId, - lastMessageId = entity.lastMessageId, - isLastMessageOutgoing = entity.isLastMessageOutgoing, - replyMarkupMessageId = entity.replyMarkupMessageId, - messageSenderId = entity.messageSenderId, - blockList = entity.blockList, - emojiStatusId = entity.emojiStatusId, - accentColorId = entity.accentColorId, - profileAccentColorId = entity.profileAccentColorId, - backgroundCustomEmojiId = entity.backgroundCustomEmojiId, - photoId = entity.photoId, - isSupergroup = entity.isSupergroup, - isAdmin = entity.isAdmin, - isOnline = entity.isOnline, - typingAction = entity.typingAction, - draftMessage = entity.draftMessage, - isVerified = entity.isVerified || isForcedVerifiedChat(entity.id), - isSponsor = entity.isSponsor || (entity.privateUserId != 0L && isSponsoredUser(entity.privateUserId)), - viewAsTopics = entity.viewAsTopics, - isForum = entity.isForum, - isBot = entity.isBot, - isMember = entity.isMember, - username = entity.username, - description = entity.description, - inviteLink = entity.inviteLink, - permissions = ChatPermissionsModel( - canSendBasicMessages = entity.permissionCanSendBasicMessages, - canSendAudios = entity.permissionCanSendAudios, - canSendDocuments = entity.permissionCanSendDocuments, - canSendPhotos = entity.permissionCanSendPhotos, - canSendVideos = entity.permissionCanSendVideos, - canSendVideoNotes = entity.permissionCanSendVideoNotes, - canSendVoiceNotes = entity.permissionCanSendVoiceNotes, - canSendPolls = entity.permissionCanSendPolls, - canSendOtherMessages = entity.permissionCanSendOtherMessages, - canAddLinkPreviews = entity.permissionCanAddLinkPreviews, - canEditTag = entity.permissionCanEditTag, - canChangeInfo = entity.permissionCanChangeInfo, - canInviteUsers = entity.permissionCanInviteUsers, - canPinMessages = entity.permissionCanPinMessages, - canCreateTopics = entity.permissionCanCreateTopics - ) - ) - } - - fun mapToEntity(domain: ChatModel): ChatEntity { - return ChatEntity( - id = domain.id, - title = domain.title, - unreadCount = domain.unreadCount, - avatarPath = domain.avatarPath, - lastMessageText = domain.lastMessageText, - lastMessageTime = domain.lastMessageTime, - lastMessageDate = domain.lastMessageDate, - order = domain.order, - isPinned = domain.isPinned, - isMuted = domain.isMuted, - isChannel = domain.isChannel, - isGroup = domain.isGroup, - type = domain.type.name, - privateUserId = 0L, - basicGroupId = 0L, - supergroupId = 0L, - secretChatId = 0, - positionsCache = null, - isArchived = domain.isArchived, - memberCount = domain.memberCount, - onlineCount = domain.onlineCount, - unreadMentionCount = domain.unreadMentionCount, - unreadReactionCount = domain.unreadReactionCount, - isMarkedAsUnread = domain.isMarkedAsUnread, - hasProtectedContent = domain.hasProtectedContent, - isTranslatable = domain.isTranslatable, - hasAutomaticTranslation = domain.hasAutomaticTranslation, - messageAutoDeleteTime = domain.messageAutoDeleteTime, - canBeDeletedOnlyForSelf = domain.canBeDeletedOnlyForSelf, - canBeDeletedForAllUsers = domain.canBeDeletedForAllUsers, - canBeReported = domain.canBeReported, - lastReadInboxMessageId = domain.lastReadInboxMessageId, - lastReadOutboxMessageId = domain.lastReadOutboxMessageId, - lastMessageId = domain.lastMessageId, - isLastMessageOutgoing = domain.isLastMessageOutgoing, - replyMarkupMessageId = domain.replyMarkupMessageId, - messageSenderId = domain.messageSenderId, - blockList = domain.blockList, - emojiStatusId = domain.emojiStatusId, - accentColorId = domain.accentColorId, - profileAccentColorId = domain.profileAccentColorId, - backgroundCustomEmojiId = domain.backgroundCustomEmojiId, - photoId = domain.photoId, - isSupergroup = domain.isSupergroup, - isAdmin = domain.isAdmin, - isOnline = domain.isOnline, - typingAction = domain.typingAction, - draftMessage = domain.draftMessage, - isVerified = domain.isVerified || isForcedVerifiedChat(domain.id), - isSponsor = domain.isSponsor, - viewAsTopics = domain.viewAsTopics, - isForum = domain.isForum, - isBot = domain.isBot, - isMember = domain.isMember, - username = domain.username, - description = domain.description, - inviteLink = domain.inviteLink, - permissionCanSendBasicMessages = domain.permissions.canSendBasicMessages, - permissionCanSendAudios = domain.permissions.canSendAudios, - permissionCanSendDocuments = domain.permissions.canSendDocuments, - permissionCanSendPhotos = domain.permissions.canSendPhotos, - permissionCanSendVideos = domain.permissions.canSendVideos, - permissionCanSendVideoNotes = domain.permissions.canSendVideoNotes, - permissionCanSendVoiceNotes = domain.permissions.canSendVoiceNotes, - permissionCanSendPolls = domain.permissions.canSendPolls, - permissionCanSendOtherMessages = domain.permissions.canSendOtherMessages, - permissionCanAddLinkPreviews = domain.permissions.canAddLinkPreviews, - permissionCanEditTag = domain.permissions.canEditTag, - permissionCanChangeInfo = domain.permissions.canChangeInfo, - permissionCanInviteUsers = domain.permissions.canInviteUsers, - permissionCanPinMessages = domain.permissions.canPinMessages, - permissionCanCreateTopics = domain.permissions.canCreateTopics, - lastMessageContentType = "text", - lastMessageSenderName = "", - createdAt = System.currentTimeMillis() - ) - } - - fun mapToEntity(chat: TdApi.Chat, domain: ChatModel): ChatEntity { - val privateUserId: Long - val basicGroupId: Long - val supergroupId: Long - val secretChatId: Int - when (val t = chat.type) { - is TdApi.ChatTypePrivate -> { - privateUserId = t.userId - basicGroupId = 0L - supergroupId = 0L - secretChatId = 0 - } - is TdApi.ChatTypeBasicGroup -> { - privateUserId = 0L - basicGroupId = t.basicGroupId - supergroupId = 0L - secretChatId = 0 - } - is TdApi.ChatTypeSupergroup -> { - privateUserId = 0L - basicGroupId = 0L - supergroupId = t.supergroupId - secretChatId = 0 - } - is TdApi.ChatTypeSecret -> { - privateUserId = 0L - basicGroupId = 0L - supergroupId = 0L - secretChatId = t.secretChatId - } - else -> { - privateUserId = 0L - basicGroupId = 0L - supergroupId = 0L - secretChatId = 0 - } - } - val encodedPositions = encodePositions(chat.positions) - val (lastMessageContentType, lastMessageSenderName) = chat.lastMessage?.let { message -> - val type = when (message.content) { - is TdApi.MessageText -> "text" - is TdApi.MessagePhoto -> "photo" - is TdApi.MessageVideo -> "video" - is TdApi.MessageVoiceNote -> "voice" - is TdApi.MessageVideoNote -> "video_note" - is TdApi.MessageSticker -> "sticker" - is TdApi.MessageDocument -> "document" - is TdApi.MessageAudio -> "audio" - is TdApi.MessageAnimation -> "gif" - is TdApi.MessageContact -> "contact" - is TdApi.MessagePoll -> "poll" - is TdApi.MessageLocation -> "location" - is TdApi.MessageVenue -> "location" - is TdApi.MessageCall -> "call" - is TdApi.MessageGame -> "game" - is TdApi.MessageInvoice -> "invoice" - is TdApi.MessageStory -> "story" - is TdApi.MessagePinMessage -> "pinned" - else -> "message" - } - val sender = "" - type to sender - } ?: ("text" to "") - - return mapToEntity(domain).copy( - privateUserId = privateUserId, - basicGroupId = basicGroupId, - supergroupId = supergroupId, - secretChatId = secretChatId, - positionsCache = encodedPositions, - lastMessageDate = chat.lastMessage?.date?.toLong() ?: domain.lastMessageDate, - lastMessageContentType = lastMessageContentType, - lastMessageSenderName = lastMessageSenderName - ) - } - - private fun encodePositions(positions: Array): String? { - if (positions.isEmpty()) return null - - val encoded = positions.mapNotNull { pos -> - if (pos.order == 0L) return@mapNotNull null - val pinned = if (pos.isPinned) 1 else 0 - when (val list = pos.list) { - is TdApi.ChatListMain -> "m:${pos.order}:$pinned" - is TdApi.ChatListArchive -> "a:${pos.order}:$pinned" - is TdApi.ChatListFolder -> "f:${list.chatFolderId}:${pos.order}:$pinned" - else -> null - } - } - - return if (encoded.isEmpty()) null else encoded.joinToString("|") - } - - fun formatMessageInfo( - lastMsg: TdApi.Message?, - chat: TdApi.Chat?, - getUserName: (Long) -> String? - ): Triple, String> { - if (lastMsg == null) return Triple("", emptyList(), "") - var entities = emptyList() - - fun captionOrFallback(caption: TdApi.FormattedText?, emojiPrefix: String, fallbackKey: String): String { - val text = caption?.text?.trim().orEmpty() - if (text.isNotEmpty()) { - entities = caption?.entities?.map { mapEntity(it) } ?: emptyList() - return "$emojiPrefix$text" - } - return stringProvider.getString(fallbackKey) - } - - var txt = when (val c = lastMsg.content) { - is TdApi.MessageText -> { - entities = c.text.entities.map { mapEntity(it) } - c.text.text - } - is TdApi.MessagePhoto -> captionOrFallback(c.caption, "📷 ", "chat_mapper_photo") - is TdApi.MessageVideo -> captionOrFallback(c.caption, "📹 ", "chat_mapper_video") - is TdApi.MessageDocument -> { - val fileName = c.document.fileName?.trim().orEmpty() - val captionText = captionOrFallback(c.caption, "📎 ", "chat_mapper_document") - if (c.caption.text.trim().isNotEmpty()) { - captionText - } else if (fileName.isNotEmpty()) { - "📎 $fileName" - } else { - captionText - } - } - - is TdApi.MessageAudio -> { - val title = c.audio.title?.trim().orEmpty() - val captionText = captionOrFallback(c.caption, "🎵 ", "chat_mapper_audio") - if (c.caption.text.trim().isNotEmpty()) { - captionText - } else if (title.isNotEmpty()) { - "🎵 $title" - } else { - captionText - } - } - - is TdApi.MessageAnimation -> captionOrFallback(c.caption, "GIF · ", "chat_mapper_gif") - is TdApi.MessageVoiceNote -> stringProvider.getString("chat_mapper_voice") - is TdApi.MessageVideoNote -> stringProvider.getString("chat_mapper_video_note") - is TdApi.MessageSticker -> stringProvider.getString("chat_mapper_sticker") - is TdApi.MessageContact -> { - val fullName = listOf(c.contact.firstName, c.contact.lastName) - .filter { it.isNotBlank() } - .joinToString(" ") - if (fullName.isNotBlank()) "👤 $fullName" else stringProvider.getString("chat_mapper_contact") - } - - is TdApi.MessagePoll -> { - val question = c.poll.question.text.trim() - if (question.isNotEmpty()) "📊 $question" else stringProvider.getString("chat_mapper_poll") - } - - is TdApi.MessageLocation -> stringProvider.getString("chat_mapper_location") - is TdApi.MessageVenue -> { - val title = c.venue.title.trim() - if (title.isNotEmpty()) "📍 $title" else stringProvider.getString("chat_mapper_location") - } - - is TdApi.MessageCall -> stringProvider.getString("chat_mapper_call") - is TdApi.MessageGame -> { - val title = c.game.title.trim() - if (title.isNotEmpty()) "🎮 $title" else stringProvider.getString("chat_mapper_game") - } - - is TdApi.MessageInvoice -> { - val title = c.productInfo.title.trim() - if (title.isNotEmpty()) "💳 $title" else stringProvider.getString("chat_mapper_invoice") - } - - is TdApi.MessageStory -> stringProvider.getString("chat_mapper_story") - is TdApi.MessagePinMessage -> stringProvider.getString("chat_mapper_pinned") - else -> stringProvider.getString("chat_mapper_message") - }.replace("\n", " ") - - if (chat != null && !lastMsg.isOutgoing) { - if (chat.type !is TdApi.ChatTypePrivate) { - val senderId = lastMsg.senderId - if (senderId is TdApi.MessageSenderUser) { - val userName = getUserName(senderId.userId) - if (userName != null) { - val prefix = "$userName: " - txt = prefix + txt - entities = entities.map { it.copy(offset = it.offset + prefix.length) } - } - } - } - } - - if (entities.any { it.type is MessageEntityType.Spoiler }) { - txt = maskSpoilerText(txt, entities) - } - - val date = lastMsg.date - val timeFormat = SimpleDateFormat("HH:mm", Locale.getDefault()) - val time = if (date > 0) timeFormat.format(Date(date.toLong() * 1000)) else "" - return Triple(txt, entities, time) - } - - private fun maskSpoilerText(text: String, entities: List): String { - if (text.isEmpty()) return text - val chars = text.toCharArray() - entities.forEach { entity -> - if (entity.type is MessageEntityType.Spoiler) { - val start = entity.offset.coerceIn(0, chars.size) - val end = (entity.offset + entity.length).coerceIn(start, chars.size) - for (i in start until end) { - chars[i] = '•' - } - } - } - return String(chars) - } - - private fun mapEntity(entity: TdApi.TextEntity): MessageEntity { - return MessageEntity( - offset = entity.offset, - length = entity.length, - type = when (entity.type) { - is TdApi.TextEntityTypeBold -> MessageEntityType.Bold - is TdApi.TextEntityTypeItalic -> MessageEntityType.Italic - is TdApi.TextEntityTypeUnderline -> MessageEntityType.Underline - is TdApi.TextEntityTypeStrikethrough -> MessageEntityType.Strikethrough - is TdApi.TextEntityTypeSpoiler -> MessageEntityType.Spoiler - is TdApi.TextEntityTypeCode -> MessageEntityType.Code - is TdApi.TextEntityTypePre -> MessageEntityType.Pre() - is TdApi.TextEntityTypeTextUrl -> MessageEntityType.TextUrl((entity.type as TdApi.TextEntityTypeTextUrl).url) - is TdApi.TextEntityTypeMention -> MessageEntityType.Mention - is TdApi.TextEntityTypeMentionName -> MessageEntityType.TextMention((entity.type as TdApi.TextEntityTypeMentionName).userId) - is TdApi.TextEntityTypeHashtag -> MessageEntityType.Hashtag - is TdApi.TextEntityTypeBotCommand -> MessageEntityType.BotCommand - is TdApi.TextEntityTypeUrl -> MessageEntityType.Url - is TdApi.TextEntityTypeEmailAddress -> MessageEntityType.Email - is TdApi.TextEntityTypePhoneNumber -> MessageEntityType.PhoneNumber - is TdApi.TextEntityTypeBankCardNumber -> MessageEntityType.BankCardNumber - is TdApi.TextEntityTypeCustomEmoji -> MessageEntityType.CustomEmoji((entity.type as TdApi.TextEntityTypeCustomEmoji).customEmojiId) - else -> MessageEntityType.Other - } - ) - } - - fun formatUserStatus(status: TdApi.UserStatus, isBot: Boolean = false): String { - if (isBot) return stringProvider.getString("chat_mapper_bot") - return when (status) { - is TdApi.UserStatusOnline -> stringProvider.getString("chat_mapper_online") - is TdApi.UserStatusOffline -> { - val wasOnline = status.wasOnline.toLong() * 1000L - if (wasOnline == 0L) return stringProvider.getString("chat_mapper_offline") - val now = System.currentTimeMillis() - val diff = now - wasOnline - when { - diff < 60 * 1000 -> stringProvider.getString("chat_mapper_seen_just_now") - diff < 60 * 60 * 1000 -> { - val minutes = diff / (60 * 1000L) - if (minutes == 1L) stringProvider.getString("chat_mapper_seen_minutes_ago", 1) - else stringProvider.getString("chat_mapper_seen_minutes_ago_plural", minutes) - } - DateUtils.isToday(wasOnline) -> { - val date = Date(wasOnline) - val format = SimpleDateFormat("HH:mm", Locale.getDefault()) - stringProvider.getString("chat_mapper_seen_at", format.format(date)) - } - - isYesterday(wasOnline) -> { - val date = Date(wasOnline) - val format = SimpleDateFormat("HH:mm", Locale.getDefault()) - stringProvider.getString("chat_mapper_seen_yesterday", format.format(date)) - } - else -> { - val date = Date(wasOnline) - val format = SimpleDateFormat("dd.MM.yy", Locale.getDefault()) - stringProvider.getString("chat_mapper_seen_date", format.format(date)) - } - } - } - - is TdApi.UserStatusRecently -> stringProvider.getString("chat_mapper_seen_recently") - is TdApi.UserStatusLastWeek -> stringProvider.getString("chat_mapper_seen_week") - is TdApi.UserStatusLastMonth -> stringProvider.getString("chat_mapper_seen_month") - is TdApi.UserStatusEmpty -> stringProvider.getString("chat_mapper_offline") - else -> "" - } - } - - private fun isYesterday(timestamp: Long): Boolean { - return DateUtils.isToday(timestamp + DateUtils.DAY_IN_MILLIS) - } -} diff --git a/data/src/main/java/org/monogram/data/mapper/FileMapper.kt b/data/src/main/java/org/monogram/data/mapper/FileMapper.kt deleted file mode 100644 index 1068ea30..00000000 --- a/data/src/main/java/org/monogram/data/mapper/FileMapper.kt +++ /dev/null @@ -1,51 +0,0 @@ -package org.monogram.data.mapper - -import org.drinkless.tdlib.TdApi -import org.monogram.data.datasource.remote.TdMessageRemoteDataSource -import org.monogram.data.infra.FileDownloadQueue -import org.monogram.domain.models.FileModel -import org.monogram.domain.models.FileLocalModel -import org.monogram.domain.models.FileRemoteModel - -fun TdApi.File.toDomain(): FileModel { - return FileModel( - id = this.id, - size = this.size, - expectedSize = this.expectedSize, - local = this.local.toDomain(), - remote = this.remote.toDomain() - ) -} - -fun TdApi.LocalFile.toDomain(): FileLocalModel { - return FileLocalModel( - path = this.path, - canBeDownloaded = this.canBeDownloaded, - canBeDeleted = this.canBeDeleted, - isDownloadingActive = this.isDownloadingActive, - isDownloadingCompleted = this.isDownloadingCompleted, - downloadOffset = this.downloadOffset, - downloadedPrefixSize = this.downloadedPrefixSize, - downloadedSize = this.downloadedSize - ) -} - -fun TdApi.RemoteFile.toDomain(): FileRemoteModel { - return FileRemoteModel( - id = this.id, - uniqueId = this.uniqueId, - isUploadingActive = this.isUploadingActive, - isUploadingCompleted = this.isUploadingCompleted, - uploadedSize = this.uploadedSize - ) -} - -fun TdMessageRemoteDataSource.DownloadType.toDomain() : FileDownloadQueue.DownloadType { - return when (this) { - TdMessageRemoteDataSource.DownloadType.DEFAULT -> FileDownloadQueue.DownloadType.DEFAULT - TdMessageRemoteDataSource.DownloadType.VIDEO -> FileDownloadQueue.DownloadType.VIDEO - TdMessageRemoteDataSource.DownloadType.GIF -> FileDownloadQueue.DownloadType.GIF - TdMessageRemoteDataSource.DownloadType.STICKER -> FileDownloadQueue.DownloadType.STICKER - TdMessageRemoteDataSource.DownloadType.VIDEO_NOTE -> FileDownloadQueue.DownloadType.VIDEO_NOTE - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/mapper/InstantViewMapper.kt b/data/src/main/java/org/monogram/data/mapper/InstantViewMapper.kt deleted file mode 100644 index 5651929b..00000000 --- a/data/src/main/java/org/monogram/data/mapper/InstantViewMapper.kt +++ /dev/null @@ -1,185 +0,0 @@ -package org.monogram.data.mapper - -import org.drinkless.tdlib.TdApi -import org.monogram.domain.models.WebPage -import org.monogram.domain.models.webapp.* - -fun map(iv: TdApi.WebPageInstantView, url: String): InstantViewModel { - return iv.toInstantViewModel(url) -} - -private fun TdApi.WebPageInstantView.toInstantViewModel(url: String): InstantViewModel { - return InstantViewModel( - pageBlocks = pageBlocks.mapNotNull { it.toPageBlock() }, - viewCount = viewCount, - version = version, - isRtl = isRtl, - isFull = isFull, - url = url - ) -} - -private fun TdApi.PageBlock.toPageBlock(): PageBlock? { - return when (this) { - is TdApi.PageBlockTitle -> PageBlock.Title(title.toRichText()) - is TdApi.PageBlockSubtitle -> PageBlock.Subtitle(subtitle.toRichText()) - is TdApi.PageBlockAuthorDate -> PageBlock.AuthorDate(author.toRichText(), publishDate) - is TdApi.PageBlockHeader -> PageBlock.Header(header.toRichText()) - is TdApi.PageBlockSubheader -> PageBlock.Subheader(subheader.toRichText()) - is TdApi.PageBlockKicker -> PageBlock.Kicker(kicker.toRichText()) - is TdApi.PageBlockParagraph -> PageBlock.Paragraph(text.toRichText()) - is TdApi.PageBlockPreformatted -> PageBlock.Preformatted(text.toRichText(), language) - is TdApi.PageBlockFooter -> PageBlock.Footer(footer.toRichText()) - is TdApi.PageBlockDivider -> PageBlock.Divider - is TdApi.PageBlockAnchor -> PageBlock.Anchor(name) - is TdApi.PageBlockList -> PageBlock.ListBlock(items.map { it.toPageBlockListItem() }) - is TdApi.PageBlockBlockQuote -> PageBlock.BlockQuote(text.toRichText(), credit.toRichText()) - is TdApi.PageBlockPullQuote -> PageBlock.PullQuote(text.toRichText(), credit.toRichText()) - is TdApi.PageBlockAnimation -> animation?.let { PageBlock.AnimationBlock(it.toAnimation(), caption.toCaption(), needAutoplay) } - is TdApi.PageBlockAudio -> audio?.let { PageBlock.AudioBlock(it.toAudio(), caption.toCaption()) } - is TdApi.PageBlockPhoto -> photo?.let { PageBlock.PhotoBlock(it.toPhoto(), caption.toCaption(), url) } - is TdApi.PageBlockVideo -> video?.let { PageBlock.VideoBlock(it.toVideo(), caption.toCaption(), needAutoplay, isLooped) } - is TdApi.PageBlockCover -> PageBlock.Cover(cover.toPageBlock() ?: PageBlock.Divider) - is TdApi.PageBlockEmbedded -> PageBlock.Embedded( - url = url, - html = html, - posterPhoto = posterPhoto?.toPhoto(), - width = width, - height = height, - caption = caption.toCaption(), - isFullWidth = isFullWidth, - allowScrolling = allowScrolling - ) - is TdApi.PageBlockEmbeddedPost -> PageBlock.EmbeddedPost( - url = url, - author = author, - authorPhoto = authorPhoto?.toPhoto(), - date = date, - pageBlocks = pageBlocks.mapNotNull { it.toPageBlock() }, - caption = caption.toCaption() - ) - is TdApi.PageBlockCollage -> PageBlock.Collage(pageBlocks.mapNotNull { it.toPageBlock() }, caption.toCaption()) - is TdApi.PageBlockSlideshow -> PageBlock.Slideshow(pageBlocks.mapNotNull { it.toPageBlock() }, caption.toCaption()) - is TdApi.PageBlockChatLink -> PageBlock.ChatLink(title, username) - is TdApi.PageBlockTable -> PageBlock.Table( - caption = caption.toRichText(), - cells = cells.map { row -> row.map { it.toTableCell() } }, - isBordered = isBordered, - isStriped = isStriped - ) - is TdApi.PageBlockDetails -> PageBlock.Details(header.toRichText(), pageBlocks.mapNotNull { it.toPageBlock() }, isOpen) - is TdApi.PageBlockRelatedArticles -> PageBlock.RelatedArticles(header.toRichText(), articles.map { it.toRelatedArticle() }) - is TdApi.PageBlockMap -> PageBlock.MapBlock( - location = Location(location.latitude, location.longitude), - zoom = zoom, - width = width, - height = height, - caption = caption.toCaption() - ) - else -> null - } -} - -private fun TdApi.RichText.toRichText(): RichText { - return when (this) { - is TdApi.RichTextPlain -> RichText.Plain(text) - is TdApi.RichTextBold -> RichText.Bold(text.toRichText()) - is TdApi.RichTextItalic -> RichText.Italic(text.toRichText()) - is TdApi.RichTextUnderline -> RichText.Underline(text.toRichText()) - is TdApi.RichTextStrikethrough -> RichText.Strikethrough(text.toRichText()) - is TdApi.RichTextFixed -> RichText.Fixed(text.toRichText()) - is TdApi.RichTextUrl -> RichText.Url(text.toRichText(), url, isCached) - is TdApi.RichTextEmailAddress -> RichText.EmailAddress(text.toRichText(), emailAddress) - is TdApi.RichTextSubscript -> RichText.Subscript(text.toRichText()) - is TdApi.RichTextSuperscript -> RichText.Superscript(text.toRichText()) - is TdApi.RichTextMarked -> RichText.Marked(text.toRichText()) - is TdApi.RichTextPhoneNumber -> RichText.PhoneNumber(text.toRichText(), phoneNumber) - is TdApi.RichTextIcon -> document?.let { RichText.Icon(it.toDocument(), width, height) } ?: RichText.Plain("") - is TdApi.RichTextReference -> RichText.Reference(text.toRichText(), anchorName, url) - is TdApi.RichTextAnchor -> RichText.Anchor(name) - is TdApi.RichTextAnchorLink -> RichText.AnchorLink(text.toRichText(), anchorName, url) - is TdApi.RichTexts -> RichText.Texts(texts.map { it.toRichText() }) - else -> RichText.Plain("") - } -} - -private fun TdApi.PageBlockListItem.toPageBlockListItem() = PageBlockListItem(label, pageBlocks.mapNotNull { it.toPageBlock() }) - -private fun TdApi.PageBlockCaption.toCaption() = PageBlockCaption(text.toRichText(), credit.toRichText()) - -private fun TdApi.PageBlockTableCell.toTableCell() = PageBlockTableCell( - text = text?.toRichText() ?: RichText.Plain(""), - isHeader = isHeader, - colspan = colspan, - rowspan = rowspan, - align = align.toHorizontalAlignment(), - valign = valign.toVerticalAlignment() -) - -private fun TdApi.PageBlockHorizontalAlignment.toHorizontalAlignment(): HorizontalAlignment { - return when (this) { - is TdApi.PageBlockHorizontalAlignmentCenter -> HorizontalAlignment.CENTER - is TdApi.PageBlockHorizontalAlignmentRight -> HorizontalAlignment.RIGHT - else -> HorizontalAlignment.LEFT - } -} - -private fun TdApi.PageBlockVerticalAlignment.toVerticalAlignment(): VerticalAlignment { - return when (this) { - is TdApi.PageBlockVerticalAlignmentMiddle -> VerticalAlignment.MIDDLE - is TdApi.PageBlockVerticalAlignmentBottom -> VerticalAlignment.BOTTOM - else -> VerticalAlignment.TOP - } -} - -private fun TdApi.PageBlockRelatedArticle.toRelatedArticle() = PageBlockRelatedArticle( - url = url, - title = title, - description = description, - photo = photo?.toPhoto(), - author = author, - publishDate = publishDate -) - -private fun TdApi.Photo.toPhoto(): WebPage.Photo { - val size = sizes.lastOrNull() - return WebPage.Photo( - path = size?.photo?.local?.path?.ifEmpty { null }, - width = size?.width ?: 0, - height = size?.height ?: 0, - fileId = size?.photo?.id ?: 0, - minithumbnail = minithumbnail?.data - ) -} - -private fun TdApi.Animation.toAnimation() = WebPage.Animation( - path = animation.local.path.ifEmpty { null }, - width = width, - height = height, - duration = duration, - fileId = animation.id -) - -private fun TdApi.Audio.toAudio() = WebPage.Audio( - path = audio.local.path.ifEmpty { null }, - duration = duration, - title = title, - performer = performer, - fileId = audio.id -) - -private fun TdApi.Video.toVideo() = WebPage.Video( - path = video.local.path.ifEmpty { null }, - width = width, - height = height, - duration = duration, - fileId = video.id -) - -private fun TdApi.Document.toDocument() = WebPage.Document( - path = document.local.path.ifEmpty { null }, - fileName = fileName, - mimeType = mimeType, - size = document.size, - fileId = document.id -) diff --git a/data/src/main/java/org/monogram/data/mapper/MessageMapper.kt b/data/src/main/java/org/monogram/data/mapper/MessageMapper.kt deleted file mode 100644 index b853edfb..00000000 --- a/data/src/main/java/org/monogram/data/mapper/MessageMapper.kt +++ /dev/null @@ -1,2153 +0,0 @@ -package org.monogram.data.mapper - -import android.net.ConnectivityManager -import android.net.NetworkCapabilities -import kotlinx.coroutines.* -import kotlinx.coroutines.flow.Flow -import org.drinkless.tdlib.TdApi -import org.monogram.core.ScopeProvider -import org.monogram.data.chats.ChatCache -import org.monogram.data.datasource.remote.MessageFileApi -import org.monogram.data.datasource.remote.TdMessageRemoteDataSource -import org.monogram.data.gateway.TelegramGateway -import org.monogram.domain.models.* -import org.monogram.domain.repository.SettingsRepository -import org.monogram.domain.repository.UserRepository -import java.io.File -import java.util.concurrent.ConcurrentHashMap - -class MessageMapper( - private val connectivityManager: ConnectivityManager, - private val gateway: TelegramGateway, - private val userRepository: UserRepository, - private val customEmojiPaths: ConcurrentHashMap, - private val fileIdToCustomEmojiId: ConcurrentHashMap, - private val fileApi: MessageFileApi, - private val settingsRepository: SettingsRepository, - private val cache: ChatCache, - scopeProvider: ScopeProvider -) { - val scope = scopeProvider.appScope - - private data class SenderUserSnapshot( - val name: String, - val avatar: String?, - val personalAvatar: String?, - val isVerified: Boolean, - val isPremium: Boolean, - val statusEmojiId: Long, - val statusEmojiPath: String? - ) - - private data class SenderChatSnapshot( - val name: String, - val avatar: String? - ) - - private val senderUserSnapshotCache = ConcurrentHashMap() - private val senderChatSnapshotCache = ConcurrentHashMap() - private val senderRankCache = ConcurrentHashMap() - private val queuedAvatarDownloads = ConcurrentHashMap.newKeySet() - - val senderUpdateFlow: Flow - get() = userRepository.anyUserUpdateFlow - - fun invalidateSenderCache(userId: Long) { - if (userId <= 0L) return - senderUserSnapshotCache.remove(userId) - senderChatSnapshotCache.remove(userId) - senderRankCache.entries.removeIf { it.key.endsWith(":$userId") } - } - - private companion object { - private const val NO_RANK_SENTINEL = "__NO_RANK__" - private const val META_SEPARATOR = '\u001F' - private const val MESSAGE_MAP_TIMEOUT_MS = 2500L - } - - private fun getCurrentNetworkType(): TdApi.NetworkType { - val activeNetwork = connectivityManager.activeNetwork - val capabilities = connectivityManager.getNetworkCapabilities(activeNetwork) - - return when { - capabilities == null -> TdApi.NetworkTypeNone() - capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> TdApi.NetworkTypeWiFi() - capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> { - if (connectivityManager.isDefaultNetworkActive && capabilities.hasCapability( - NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING) - .not() - ) { - TdApi.NetworkTypeMobileRoaming() - } else { - TdApi.NetworkTypeMobile() - } - } - else -> TdApi.NetworkTypeNone() - } - } - - private fun isNetworkAutoDownloadEnabled(): Boolean { - return when (getCurrentNetworkType()) { - is TdApi.NetworkTypeWiFi -> settingsRepository.autoDownloadWifi.value - is TdApi.NetworkTypeMobile -> settingsRepository.autoDownloadMobile.value - is TdApi.NetworkTypeMobileRoaming -> settingsRepository.autoDownloadRoaming.value - else -> settingsRepository.autoDownloadWifi.value - } - } - - private fun isValidPath(path: String?): Boolean { - return !path.isNullOrEmpty() && File(path).exists() - } - - private fun encodeMeta(vararg parts: Any?): String { - return parts.joinToString(META_SEPARATOR.toString()) { it?.toString().orEmpty() } - } - - private fun decodeMeta(raw: String?): List { - if (raw.isNullOrBlank()) return emptyList() - return if (raw.contains(META_SEPARATOR)) raw.split(META_SEPARATOR) else raw.split('|') - } - - private fun resolveLegacyMediaFromMeta(contentType: String, meta: List): Pair { - return when (contentType) { - "photo" -> (meta.getOrNull(2)?.toIntOrNull() ?: 0) to meta.getOrNull(3) - "video" -> (meta.getOrNull(3)?.toIntOrNull() ?: 0) to meta.getOrNull(4) - "voice" -> (meta.getOrNull(1)?.toIntOrNull() ?: 0) to meta.getOrNull(2) - "video_note" -> (meta.getOrNull(2)?.toIntOrNull() ?: 0) to meta.getOrNull(3) - "sticker" -> (meta.getOrNull(4)?.toIntOrNull() ?: 0) to meta.getOrNull(6) - "document" -> (meta.getOrNull(3)?.toIntOrNull() ?: 0) to meta.getOrNull(4) - "audio" -> (meta.getOrNull(4)?.toIntOrNull() ?: 0) to meta.getOrNull(5) - "gif" -> (meta.getOrNull(3)?.toIntOrNull() ?: 0) to meta.getOrNull(4) - else -> 0 to null - } - } - - private fun resolveCachedPath(fileId: Int, storedPath: String?): String? { - val fromCache = fileId.takeIf { it != 0 } - ?.let { cache.fileCache[it]?.local?.path } - ?.takeIf { isValidPath(it) } - if (fromCache != null) return fromCache - - return storedPath?.takeIf { it.isNotBlank() }?.takeIf { isValidPath(it) } - } - - private fun registerCachedFile(fileId: Int, chatId: Long, messageId: Long) { - if (fileId != 0) { - fileApi.registerFileForMessage(fileId, chatId, messageId) - } - } - - private fun resolveLocalFilePath(file: TdApi.File?): String? { - if (file == null) return null - val directPath = file.local.path.takeIf { isValidPath(it) } - if (directPath != null) return directPath - - return cache.fileCache[file.id]?.local?.path?.takeIf { isValidPath(it) } - } - - private fun resolveSenderNameFromCache(senderId: Long, fallback: String): String { - val user = cache.getUser(senderId) - if (user != null) { - return listOfNotNull( - user.firstName.takeIf { it.isNotBlank() }, - user.lastName?.takeIf { it.isNotBlank() } - ).joinToString(" ").ifBlank { fallback.ifBlank { "User" } } - } - - val chat = cache.getChat(senderId) - if (chat != null) { - return chat.title.takeIf { it.isNotBlank() } ?: fallback.ifBlank { "User" } - } - - return fallback.ifBlank { "User" } - } - - private fun findBestAvailablePath(mainFile: TdApi.File?, sizes: Array? = null): String? { - if (mainFile != null && isValidPath(mainFile.local.path)) { - return mainFile.local.path - } - - if (sizes != null) { - return sizes.sortedByDescending { it.width } - .map { getUpdatedFile(it.photo) } - .firstOrNull { isValidPath(it.local.path) } - ?.local?.path - } - return null - } - - private fun resolveFallbackSender(msg: TdApi.Message): Triple { - return when (val sender = msg.senderId) { - is TdApi.MessageSenderUser -> { - val senderId = sender.userId - val snapshot = senderUserSnapshotCache[senderId] - if (snapshot != null) { - val avatar = snapshot.avatar ?: snapshot.personalAvatar - Triple(senderId, snapshot.name.ifBlank { "User" }, avatar) - } else { - val user = cache.getUser(senderId) - val fallbackName = if (user != null) { - listOfNotNull( - user.firstName.takeIf { it.isNotBlank() }, - user.lastName?.takeIf { it.isNotBlank() } - ).joinToString(" ").ifBlank { "User" } - } else { - "User" - } - val avatar = user?.profilePhoto?.small?.local?.path?.takeIf { isValidPath(it) } - ?: user?.profilePhoto?.big?.local?.path?.takeIf { isValidPath(it) } - Triple(senderId, fallbackName, avatar) - } - } - - is TdApi.MessageSenderChat -> { - val senderId = sender.chatId - val snapshot = senderChatSnapshotCache[senderId] - if (snapshot != null) { - Triple(senderId, snapshot.name.ifBlank { "User" }, snapshot.avatar) - } else { - val chat = cache.getChat(senderId) - val fallbackName = chat?.title?.takeIf { it.isNotBlank() } ?: "User" - val avatar = chat?.photo?.small?.local?.path?.takeIf { isValidPath(it) } - Triple(senderId, fallbackName, avatar) - } - } - - else -> Triple(0L, "User", null) - } - } - - private fun mapMessageToModelFallback( - msg: TdApi.Message, - isChatOpen: Boolean, - isReply: Boolean - ): MessageModel { - val (senderId, senderName, senderAvatar) = resolveFallbackSender(msg) - return createMessageModel( - msg = msg, - senderName = senderName, - senderId = senderId, - senderAvatar = senderAvatar, - isChatOpen = isChatOpen, - isReply = isReply - ) - } - - suspend fun mapMessageToModel( - msg: TdApi.Message, - isChatOpen: Boolean = false, - isReply: Boolean = false - ): MessageModel = coroutineScope { - withTimeoutOrNull(MESSAGE_MAP_TIMEOUT_MS) { - var senderName = "User" - var senderAvatar: String? = null - var senderPersonalAvatar: String? = null - var senderCustomTitle: String? = null - var isSenderVerified = false - var isSenderPremium = false - var senderStatusEmojiId = 0L - var senderStatusEmojiPath: String? = null - val senderId: Long - - when (val sender = msg.senderId) { - is TdApi.MessageSenderUser -> { - senderId = sender.userId - val cachedSnapshot = senderUserSnapshotCache[senderId] - if (cachedSnapshot != null) { - senderName = cachedSnapshot.name - senderAvatar = cachedSnapshot.avatar - senderPersonalAvatar = cachedSnapshot.personalAvatar - isSenderVerified = cachedSnapshot.isVerified - isSenderPremium = cachedSnapshot.isPremium - senderStatusEmojiId = cachedSnapshot.statusEmojiId - senderStatusEmojiPath = cachedSnapshot.statusEmojiPath - } else { - val user = try { - withTimeout(500) { userRepository.getUser(senderId) } - } catch (e: Exception) { - null - } - if (user != null) { - senderName = listOfNotNull( - user.firstName.takeIf { it.isNotBlank() }, - user.lastName?.takeIf { it.isNotBlank() } - ).joinToString(" ") - - if (senderName.isBlank()) senderName = "User" - - senderAvatar = user.avatarPath.takeIf { isValidPath(it) } - senderPersonalAvatar = user.personalAvatarPath.takeIf { isValidPath(it) } - isSenderVerified = user.isVerified - isSenderPremium = user.isPremium - senderStatusEmojiId = user.statusEmojiId - senderStatusEmojiPath = user.statusEmojiPath - - senderUserSnapshotCache[senderId] = SenderUserSnapshot( - name = senderName, - avatar = senderAvatar, - personalAvatar = senderPersonalAvatar, - isVerified = isSenderVerified, - isPremium = isSenderPremium, - statusEmojiId = senderStatusEmojiId, - statusEmojiPath = senderStatusEmojiPath - ) - } - } - - val chat = cache.getChat(msg.chatId) - val canGetMember = when (chat?.type) { - is TdApi.ChatTypePrivate, is TdApi.ChatTypeSecret -> true - is TdApi.ChatTypeBasicGroup -> true - is TdApi.ChatTypeSupergroup -> { - val supergroup = (chat.type as TdApi.ChatTypeSupergroup) - val cachedSupergroup = cache.getSupergroup(supergroup.supergroupId) - !(cachedSupergroup?.isChannel ?: false) || (chat.permissions?.canSendBasicMessages ?: false) - } - else -> false - } - - if (canGetMember) { - val rankKey = "${msg.chatId}:$senderId" - val cachedRank = senderRankCache[rankKey] - if (cachedRank != null) { - senderCustomTitle = cachedRank.takeUnless { it == NO_RANK_SENTINEL } - } else { - val member = try { - withTimeout(500) { userRepository.getChatMember(msg.chatId, senderId) } - } catch (e: Exception) { - null - } - senderCustomTitle = member?.rank - senderRankCache[rankKey] = senderCustomTitle ?: NO_RANK_SENTINEL - } - } - } - - is TdApi.MessageSenderChat -> { - senderId = sender.chatId - val cachedSnapshot = senderChatSnapshotCache[senderId] - if (cachedSnapshot != null) { - senderName = cachedSnapshot.name - senderAvatar = cachedSnapshot.avatar - } else { - val chat = try { - withTimeout(500) { - cache.getChat(senderId) ?: gateway.execute(TdApi.GetChat(senderId)).also { cache.putChat(it) } - } - } catch (e: Exception) { - null - } - if (chat != null) { - senderName = chat.title - val photo = chat.photo?.small - if (photo != null) { - senderAvatar = photo.local.path.takeIf { isValidPath(it) } - if (senderAvatar.isNullOrEmpty() && queuedAvatarDownloads.add(photo.id)) { - fileApi.enqueueDownload( - photo.id, - 16, - TdMessageRemoteDataSource.DownloadType.DEFAULT, - 0, - 0, - false - ) - } - } - - senderChatSnapshotCache[senderId] = SenderChatSnapshot( - name = senderName, - avatar = senderAvatar - ) - } - } - } - - else -> senderId = 0L - } - - var replyToMsgId: Long? = null - var replyToMsg: MessageModel? = null - - if (!isReply && msg.replyTo != null) { - val replyTo = msg.replyTo - if (replyTo is TdApi.MessageReplyToMessage) { - replyToMsgId = replyTo.messageId - - val repliedMessage = try { - withTimeout(500) { - cache.getMessage(msg.chatId, replyToMsgId) - ?: gateway.execute(TdApi.GetMessage(msg.chatId, replyToMsgId)).also { cache.putMessage(it) } - } - } catch (e: Exception) { - null - } - if (repliedMessage != null) { - replyToMsg = - mapMessageToModel( - repliedMessage, - isChatOpen, - isReply = true - ).copy(replyToMsg = null, replyToMsgId = null) - } - } - } - - var forwardInfo: ForwardInfo? = null - if (msg.forwardInfo != null) { - val fwd = msg.forwardInfo - val origin = fwd?.origin - var originName = "Unknown" - var originPeerId = 0L - var originChatId: Long? = null - var originMessageId: Long? = null - - when (origin) { - is TdApi.MessageOriginUser -> { - originPeerId = origin.senderUserId - val user = try { - withTimeout(500) { userRepository.getUser(originPeerId) } - } catch (e: Exception) { - null - } - - if (user != null) { - val first = user.firstName.takeIf { it.isNotBlank() } - val last = user.lastName?.takeIf { it.isNotBlank() } - val username = user.username?.takeIf { it.isNotBlank() } - - val baseName = listOfNotNull(first, last).joinToString(" ") - - originName = if (baseName.isNotBlank()) { - if (username != null) "$baseName (@$username)" else baseName - } else { - username?.let { "@$it" } ?: "Unknown" - } - } - } - - is TdApi.MessageOriginChat -> { - originPeerId = origin.senderChatId - val chat = try { - withTimeout(500) { - cache.getChat(originPeerId) ?: gateway.execute(TdApi.GetChat(originPeerId)) - .also { cache.putChat(it) } - } - } catch (e: Exception) { - null - } - if (chat != null) { - originName = chat.title - } - } - - is TdApi.MessageOriginChannel -> { - originPeerId = origin.chatId - originChatId = origin.chatId - originMessageId = origin.messageId - val chat = try { - withTimeout(500) { - cache.getChat(originPeerId) ?: gateway.execute(TdApi.GetChat(originPeerId)) - .also { cache.putChat(it) } - } - } catch (e: Exception) { - null - } - if (chat != null) { - originName = chat.title - } - } - - is TdApi.MessageOriginHiddenUser -> { - originName = origin.senderName - } - } - forwardInfo = - ForwardInfo(fwd?.date ?: 0, originPeerId, originName, originChatId, originMessageId) - } - - val views = msg.interactionInfo?.viewCount - val replyCount = msg.interactionInfo?.replyInfo?.replyCount ?: 0 - - val sendingState = when (val state = msg.sendingState) { - is TdApi.MessageSendingStatePending -> MessageSendingState.Pending - is TdApi.MessageSendingStateFailed -> MessageSendingState.Failed( - state.error.code, - state.error.message - ) - - else -> null - } - - val reactions = - if (isReply) emptyList() else msg.interactionInfo?.reactions?.reactions?.map { reaction -> - async { - val recentSenders = try { - withTimeout(1000) { - reaction.recentSenderIds.map { senderId -> - async { - when (senderId) { - is TdApi.MessageSenderUser -> { - val user = try { - withTimeout(500) { userRepository.getUser(senderId.userId) } - } catch (e: Exception) { - null - } - ReactionSender( - id = senderId.userId, - name = listOfNotNull( - user?.firstName, - user?.lastName - ).joinToString(" "), - avatar = user?.avatarPath.takeIf { isValidPath(it) } - ) - } - - is TdApi.MessageSenderChat -> { - val chat = try { - withTimeout(500) { - cache.getChat(senderId.chatId) ?: gateway.execute( - TdApi.GetChat( - senderId.chatId - ) - ).also { cache.putChat(it) } - } - } catch (e: Exception) { - null - } - ReactionSender( - id = senderId.chatId, - name = chat?.title ?: "", - avatar = chat?.photo?.small?.local?.path.takeIf { isValidPath(it) } - ) - } - - else -> ReactionSender(0) - } - } - }.awaitAll() - } - } catch (e: Exception) { - emptyList() - } - - when (val type = reaction.type) { - is TdApi.ReactionTypeEmoji -> { - MessageReactionModel( - emoji = type.emoji, - count = reaction.totalCount, - isChosen = reaction.isChosen, - recentSenders = recentSenders - ) - } - - is TdApi.ReactionTypeCustomEmoji -> { - val emojiId = type.customEmojiId - val path = customEmojiPaths[emojiId].takeIf { isValidPath(it) } - if (path == null) { - loadCustomEmoji( - emojiId, - msg.chatId, - msg.id, - isChatOpen && isNetworkAutoDownloadEnabled() - ) - } - MessageReactionModel( - customEmojiId = emojiId, - customEmojiPath = path, - count = reaction.totalCount, - isChosen = reaction.isChosen, - recentSenders = recentSenders - ) - } - - else -> null - } - } - }?.awaitAll()?.filterNotNull() ?: emptyList() - - val threadId = when (val topic = msg.topicId) { - is TdApi.MessageTopicForum -> topic.forumTopicId - else -> null - } - - var viaBotName: String? = null - if (msg.viaBotUserId != 0L) { - val bot = try { - withTimeout(500) { userRepository.getUser(msg.viaBotUserId) } - } catch (e: Exception) { - null - } - viaBotName = bot?.username ?: bot?.firstName - } - - createMessageModel( - msg, - senderName, - senderId, - senderAvatar, - isReadOverride = false, - replyToMsgId = replyToMsgId, - replyToMsg = replyToMsg, - forwardInfo = forwardInfo, - views = views, - viewCount = views, - mediaAlbumId = msg.mediaAlbumId, - sendingState = sendingState, - isChatOpen = isChatOpen, - readDate = 0, - reactions = reactions, - isSenderVerified = isSenderVerified, - threadId = threadId, - replyCount = replyCount, - isReply = isReply, - viaBotUserId = msg.viaBotUserId, - viaBotName = viaBotName, - senderPersonalAvatar = senderPersonalAvatar, - senderCustomTitle = senderCustomTitle, - isSenderPremium = isSenderPremium, - senderStatusEmojiId = senderStatusEmojiId, - senderStatusEmojiPath = senderStatusEmojiPath - ) - } ?: mapMessageToModelFallback(msg, isChatOpen, isReply) - } - - suspend fun getMessageReadDate(chatId: Long, messageId: Long, messageDate: Int): Int { - val chat = cache.getChat(chatId) - if (chat?.type !is TdApi.ChatTypePrivate) { - return 0 - } - - val sevenDaysAgo = (System.currentTimeMillis() / 1000) - (7 * 24 * 60 * 60) - if (messageDate < sevenDaysAgo) { - return 0 - } - - return try { - val result = gateway.execute(TdApi.GetMessageReadDate(chatId, messageId)) - if (result is TdApi.MessageReadDateRead) { - result.readDate - } else { - 0 - } - } catch (e: Exception) { - 0 - } - } - - suspend fun mapMessageToModelSync( - msg: TdApi.Message, - inboxLimit: Long, - outboxLimit: Long, - isChatOpen: Boolean = false, - isReply: Boolean = false - ): MessageModel { - val isRead = if (msg.isOutgoing) msg.id <= outboxLimit else msg.id <= inboxLimit - val baseModel = mapMessageToModel(msg, isChatOpen, isReply) - return baseModel.copy(isRead = isRead) - } - - private fun getUpdatedFile(file: TdApi.File): TdApi.File { - return cache.fileCache[file.id] ?: file - } - - private fun mapEntities( - entities: Array, - chatId: Long, - messageId: Long, - networkAutoDownload: Boolean - ): List { - return entities.map { entity -> - val type = when (val entityType = entity.type) { - is TdApi.TextEntityTypeBold -> MessageEntityType.Bold - is TdApi.TextEntityTypeItalic -> MessageEntityType.Italic - is TdApi.TextEntityTypeUnderline -> MessageEntityType.Underline - is TdApi.TextEntityTypeStrikethrough -> MessageEntityType.Strikethrough - is TdApi.TextEntityTypeSpoiler -> MessageEntityType.Spoiler - is TdApi.TextEntityTypeCode -> MessageEntityType.Code - is TdApi.TextEntityTypePre -> MessageEntityType.Pre() - is TdApi.TextEntityTypePreCode -> MessageEntityType.Pre(entityType.language) - is TdApi.TextEntityTypeUrl -> MessageEntityType.Url - is TdApi.TextEntityTypeTextUrl -> MessageEntityType.TextUrl(entityType.url) - is TdApi.TextEntityTypeMention -> MessageEntityType.Mention - is TdApi.TextEntityTypeMentionName -> MessageEntityType.Mention - is TdApi.TextEntityTypeHashtag -> MessageEntityType.Hashtag - is TdApi.TextEntityTypeBotCommand -> MessageEntityType.BotCommand - is TdApi.TextEntityTypeEmailAddress -> MessageEntityType.Email - is TdApi.TextEntityTypePhoneNumber -> MessageEntityType.PhoneNumber - is TdApi.TextEntityTypeBankCardNumber -> MessageEntityType.BankCardNumber - is TdApi.TextEntityTypeCustomEmoji -> { - val emojiId = entityType.customEmojiId - val path = customEmojiPaths[emojiId].takeIf { isValidPath(it) } - if (path == null) { - scope.launch { - loadCustomEmoji(emojiId, chatId, messageId, networkAutoDownload) - } - } - MessageEntityType.CustomEmoji(emojiId, path) - } - - else -> MessageEntityType.Other - } - MessageEntity(entity.offset, entity.length, type) - } - } - - private fun mapWebPage( - webPage: TdApi.LinkPreview?, - chatId: Long, - messageId: Long, - networkAutoDownload: Boolean - ): WebPage? { - if (webPage == null) return null - - var photoObj: TdApi.Photo? = null - var videoObj: TdApi.Video? = null - var audioObj: TdApi.Audio? = null - var documentObj: TdApi.Document? = null - var stickerObj: TdApi.Sticker? = null - var animationObj: TdApi.Animation? = null - var duration = 0 - - val linkPreviewType = when (val t = webPage.type) { - is TdApi.LinkPreviewTypePhoto -> { - photoObj = t.photo - WebPage.LinkPreviewType.Photo - } - - is TdApi.LinkPreviewTypeVideo -> { - videoObj = t.video - WebPage.LinkPreviewType.Video - } - - is TdApi.LinkPreviewTypeAnimation -> { - animationObj = t.animation - WebPage.LinkPreviewType.Animation - } - - is TdApi.LinkPreviewTypeAudio -> { - audioObj = t.audio - WebPage.LinkPreviewType.Audio - } - - is TdApi.LinkPreviewTypeDocument -> { - documentObj = t.document - WebPage.LinkPreviewType.Document - } - - is TdApi.LinkPreviewTypeSticker -> { - stickerObj = t.sticker - WebPage.LinkPreviewType.Sticker - } - - is TdApi.LinkPreviewTypeVideoNote -> WebPage.LinkPreviewType.VideoNote - is TdApi.LinkPreviewTypeVoiceNote -> WebPage.LinkPreviewType.VoiceNote - is TdApi.LinkPreviewTypeAlbum -> WebPage.LinkPreviewType.Album - is TdApi.LinkPreviewTypeArticle -> WebPage.LinkPreviewType.Article - is TdApi.LinkPreviewTypeApp -> WebPage.LinkPreviewType.App - is TdApi.LinkPreviewTypeExternalVideo -> { - duration = t.duration - WebPage.LinkPreviewType.ExternalVideo(t.url) - } - - is TdApi.LinkPreviewTypeExternalAudio -> { - duration = t.duration - WebPage.LinkPreviewType.ExternalAudio(t.url) - } - - is TdApi.LinkPreviewTypeEmbeddedVideoPlayer -> { - duration = t.duration - WebPage.LinkPreviewType.EmbeddedVideo(t.url) - } - - is TdApi.LinkPreviewTypeEmbeddedAudioPlayer -> { - duration = t.duration - WebPage.LinkPreviewType.EmbeddedAudio(t.url) - } - - is TdApi.LinkPreviewTypeEmbeddedAnimationPlayer -> { - duration = t.duration - WebPage.LinkPreviewType.EmbeddedAnimation(t.url) - } - is TdApi.LinkPreviewTypeUser -> WebPage.LinkPreviewType.User(0) - is TdApi.LinkPreviewTypeChat -> WebPage.LinkPreviewType.Chat(0) - is TdApi.LinkPreviewTypeStory -> WebPage.LinkPreviewType.Story(t.storyPosterChatId, t.storyId) - is TdApi.LinkPreviewTypeTheme -> WebPage.LinkPreviewType.Theme - is TdApi.LinkPreviewTypeBackground -> WebPage.LinkPreviewType.Background - is TdApi.LinkPreviewTypeInvoice -> WebPage.LinkPreviewType.Invoice - is TdApi.LinkPreviewTypeMessage -> WebPage.LinkPreviewType.Message - else -> WebPage.LinkPreviewType.Unknown - } - - fun processTdFile( - file: TdApi.File, - downloadType: TdMessageRemoteDataSource.DownloadType, - supportsStreaming: Boolean = false - ): TdApi.File { - val updatedFile = getUpdatedFile(file) - fileApi.registerFileForMessage(updatedFile.id, chatId, messageId) - - val autoDownload = when (downloadType) { - TdMessageRemoteDataSource.DownloadType.VIDEO -> supportsStreaming && networkAutoDownload - TdMessageRemoteDataSource.DownloadType.DEFAULT -> { - if (linkPreviewType == WebPage.LinkPreviewType.Document) false else networkAutoDownload - } - TdMessageRemoteDataSource.DownloadType.STICKER -> networkAutoDownload && settingsRepository.autoDownloadStickers.value - TdMessageRemoteDataSource.DownloadType.VIDEO_NOTE -> networkAutoDownload && settingsRepository.autoDownloadVideoNotes.value - else -> networkAutoDownload - } - - if (!isValidPath(updatedFile.local.path) && autoDownload) { - fileApi.enqueueDownload(updatedFile.id, 1, downloadType, 0, 0, false) - } - return updatedFile - } - - val photo = photoObj?.let { p -> - val size = p.sizes.firstOrNull() - if (size != null) { - val f = processTdFile(size.photo, TdMessageRemoteDataSource.DownloadType.DEFAULT) - val bestPath = findBestAvailablePath(f, p.sizes) - - WebPage.Photo( - path = bestPath, - width = size.width, - height = size.height, - fileId = f.id, - minithumbnail = p.minithumbnail?.data - ) - } else null - } - - val video = videoObj?.let { v -> - val f = processTdFile(v.video, TdMessageRemoteDataSource.DownloadType.VIDEO, v.supportsStreaming) - WebPage.Video(f.local.path.takeIf { isValidPath(it) }, v.width, v.height, v.duration, f.id, v.supportsStreaming) - } - - val audio = audioObj?.let { a -> - val f = processTdFile(a.audio, TdMessageRemoteDataSource.DownloadType.DEFAULT) - WebPage.Audio(a.audio.local.path.takeIf { isValidPath(it) }, a.duration, a.title, a.performer, f.id) - } - - val document = documentObj?.let { d -> - val f = processTdFile(d.document, TdMessageRemoteDataSource.DownloadType.DEFAULT) - WebPage.Document(d.document.local.path.takeIf { isValidPath(it) }, d.fileName, d.mimeType, f.size, f.id) - } - - val sticker = stickerObj?.let { s -> - val f = processTdFile(s.sticker, TdMessageRemoteDataSource.DownloadType.STICKER) - WebPage.Sticker(s.sticker.local.path.takeIf { isValidPath(it) }, s.width, s.height, s.emoji, f.id) - } - - val animation = animationObj?.let { anim -> - val f = processTdFile(anim.animation, TdMessageRemoteDataSource.DownloadType.GIF) - WebPage.Animation(anim.animation.local.path.takeIf { isValidPath(it) }, anim.width, anim.height, anim.duration, f.id) - } - - return WebPage( - url = webPage.url, - displayUrl = webPage.displayUrl, - type = linkPreviewType, - siteName = webPage.siteName, - title = webPage.title, - description = webPage.description?.text, - photo = photo, - embedUrl = null, - embedType = null, - embedWidth = 0, - embedHeight = 0, - duration = duration, - author = webPage.author, - video = video, - audio = audio, - document = document, - sticker = sticker, - animation = animation, - instantViewVersion = webPage.instantViewVersion - ) - } - - private fun mapReplyMarkup(markup: TdApi.ReplyMarkup?): ReplyMarkupModel? { - return when (markup) { - is TdApi.ReplyMarkupInlineKeyboard -> { - ReplyMarkupModel.InlineKeyboard( - rows = markup.rows.map { row -> - row.map { button -> - InlineKeyboardButtonModel( - text = button.text, - type = when (val type = button.type) { - is TdApi.InlineKeyboardButtonTypeUrl -> InlineKeyboardButtonType.Url( - type.url - ) - - is TdApi.InlineKeyboardButtonTypeCallback -> InlineKeyboardButtonType.Callback( - type.data - ) - - is TdApi.InlineKeyboardButtonTypeWebApp -> InlineKeyboardButtonType.WebApp( - type.url - ) - - is TdApi.InlineKeyboardButtonTypeLoginUrl -> InlineKeyboardButtonType.LoginUrl( - type.url, - type.id - ) - - is TdApi.InlineKeyboardButtonTypeSwitchInline -> InlineKeyboardButtonType.SwitchInline( - query = type.query - ) - - is TdApi.InlineKeyboardButtonTypeBuy -> InlineKeyboardButtonType.Buy() - is TdApi.InlineKeyboardButtonTypeUser -> InlineKeyboardButtonType.User( - type.userId - ) - - else -> InlineKeyboardButtonType.Unsupported - } - ) - } - } - ) - } - - is TdApi.ReplyMarkupShowKeyboard -> { - ReplyMarkupModel.ShowKeyboard( - rows = markup.rows.map { row -> - row.map { button -> - KeyboardButtonModel( - text = button.text, - type = when (val type = button.type) { - is TdApi.KeyboardButtonTypeText -> KeyboardButtonType.Text - is TdApi.KeyboardButtonTypeRequestPhoneNumber -> KeyboardButtonType.RequestPhoneNumber - is TdApi.KeyboardButtonTypeRequestLocation -> KeyboardButtonType.RequestLocation - is TdApi.KeyboardButtonTypeRequestPoll -> KeyboardButtonType.RequestPoll( - type.forceQuiz, - type.forceRegular - ) - - is TdApi.KeyboardButtonTypeWebApp -> KeyboardButtonType.WebApp( - type.url - ) - - is TdApi.KeyboardButtonTypeRequestUsers -> KeyboardButtonType.RequestUsers( - type.id - ) - - is TdApi.KeyboardButtonTypeRequestChat -> KeyboardButtonType.RequestChat( - type.id - ) - - else -> KeyboardButtonType.Unsupported - } - ) - } - }, - isPersistent = markup.isPersistent, - resizeKeyboard = markup.resizeKeyboard, - oneTime = markup.oneTime, - isPersonal = markup.isPersonal, - inputFieldPlaceholder = markup.inputFieldPlaceholder - ) - } - - is TdApi.ReplyMarkupRemoveKeyboard -> ReplyMarkupModel.RemoveKeyboard(markup.isPersonal) - is TdApi.ReplyMarkupForceReply -> ReplyMarkupModel.ForceReply( - markup.isPersonal, - markup.inputFieldPlaceholder - ) - - else -> null - } - } - - fun createMessageModel( - msg: TdApi.Message, - senderName: String, - senderId: Long, - senderAvatar: String?, - isReadOverride: Boolean = false, - replyToMsgId: Long? = null, - replyToMsg: MessageModel? = null, - forwardInfo: ForwardInfo? = null, - views: Int? = null, - viewCount: Int? = null, - mediaAlbumId: Long = 0L, - sendingState: MessageSendingState? = null, - isChatOpen: Boolean = false, - readDate: Int = 0, - reactions: List = emptyList(), - isSenderVerified: Boolean = false, - threadId: Int? = null, - replyCount: Int = 0, - isReply: Boolean = false, - viaBotUserId: Long = 0L, - viaBotName: String? = null, - senderPersonalAvatar: String? = null, - senderCustomTitle: String? = null, - isSenderPremium: Boolean = false, - senderStatusEmojiId: Long = 0L, - senderStatusEmojiPath: String? = null - ): MessageModel { - val networkAutoDownload = isChatOpen && isNetworkAutoDownloadEnabled() - val isActuallyUploading = msg.sendingState is TdApi.MessageSendingStatePending - - val content = when (val c = msg.content) { - is TdApi.MessageText -> { - val entities = mapEntities(c.text.entities, msg.chatId, msg.id, networkAutoDownload) - val webPage = mapWebPage(c.linkPreview, msg.chatId, msg.id, networkAutoDownload) - MessageContent.Text(c.text.text, entities, webPage) - } - - is TdApi.MessagePhoto -> { - - val sizes = c.photo.sizes - val photoSize = sizes.find { it.type == "x" } - ?: sizes.find { it.type == "m" } - ?: sizes.getOrNull(sizes.size / 2) - ?: sizes.lastOrNull() - val thumbnailSize = sizes.find { it.type == "m" } - ?: sizes.find { it.type == "s" } - ?: sizes.firstOrNull() - - val photoFile = photoSize?.photo?.let { getUpdatedFile(it) } - val thumbnailFile = thumbnailSize?.photo?.let { getUpdatedFile(it) } - - val path = findBestAvailablePath(photoFile, sizes) - val thumbnailPath = resolveLocalFilePath(thumbnailFile) - - if (photoFile != null) { - fileApi.registerFileForMessage(photoFile.id, msg.chatId, msg.id) - if (path == null && networkAutoDownload) { - fileApi.enqueueDownload(photoFile.id, 1, TdMessageRemoteDataSource.DownloadType.DEFAULT, 0, 0, false) - } - } - if (thumbnailFile != null) { - fileApi.registerFileForMessage(thumbnailFile.id, msg.chatId, msg.id) - if (thumbnailPath == null && networkAutoDownload) { - fileApi.enqueueDownload( - thumbnailFile.id, - 1, - TdMessageRemoteDataSource.DownloadType.DEFAULT, - 0, - 0, - false - ) - } - } - val isDownloading = photoFile?.local?.isDownloadingActive ?: false - val isQueued = photoFile?.let { fileApi.isFileQueued(it.id) } ?: false - val downloadProgress = if ((photoFile?.size ?: 0) > 0) { - photoFile!!.local.downloadedSize.toFloat() / photoFile.size.toFloat() - } else 0f - - MessageContent.Photo( - path = path, - thumbnailPath = thumbnailPath, - width = photoSize?.width ?: 0, - height = photoSize?.height ?: 0, - caption = c.caption.text, - entities = mapEntities(c.caption.entities, msg.chatId, msg.id, networkAutoDownload), - isUploading = isActuallyUploading && (photoFile?.remote?.isUploadingActive ?: false), - uploadProgress = if ((photoFile?.size ?: 0) > 0) photoFile!!.remote.uploadedSize.toFloat() / photoFile.size.toFloat() else 0f, - isDownloading = isDownloading || isQueued, - downloadProgress = downloadProgress, - fileId = photoFile?.id ?: 0, - minithumbnail = c.photo.minithumbnail?.data - ) - } - - is TdApi.MessageVideo -> { - val video = c.video - val videoFile = getUpdatedFile(video.video) - val path = videoFile.local.path.takeIf { isValidPath(it) } - fileApi.registerFileForMessage(videoFile.id, msg.chatId, msg.id) - - val thumbFile = video.thumbnail?.file?.let { getUpdatedFile(it) } - val thumbnailPath = resolveLocalFilePath(thumbFile) - - if (thumbFile != null) { - fileApi.registerFileForMessage(thumbFile.id, msg.chatId, msg.id) - if (thumbnailPath == null && networkAutoDownload) { - fileApi.enqueueDownload(thumbFile.id, 1, TdMessageRemoteDataSource.DownloadType.DEFAULT, 0, 0, false) - } - } - - if (path == null && networkAutoDownload && video.supportsStreaming) { - fileApi.enqueueDownload(videoFile.id, 1, TdMessageRemoteDataSource.DownloadType.VIDEO, 0, 0, false) - } - - val isDownloading = videoFile.local.isDownloadingActive - val isQueued = fileApi.isFileQueued(videoFile.id) - val downloadProgress = if (videoFile.size > 0) { - videoFile.local.downloadedSize.toFloat() / videoFile.size.toFloat() - } else 0f - - MessageContent.Video( - path = path, - thumbnailPath = thumbnailPath, - width = video.width, - height = video.height, - duration = video.duration, - caption = c.caption.text, - entities = mapEntities(c.caption.entities, msg.chatId, msg.id, networkAutoDownload), - isUploading = isActuallyUploading && videoFile.remote.isUploadingActive, - uploadProgress = if (videoFile.size > 0) videoFile.remote.uploadedSize.toFloat() / videoFile.size.toFloat() else 0f, - isDownloading = isDownloading || isQueued, - downloadProgress = downloadProgress, - fileId = videoFile.id, - minithumbnail = video.minithumbnail?.data, - supportsStreaming = video.supportsStreaming - ) - } - - is TdApi.MessageVoiceNote -> { - val voice = c.voiceNote - val voiceFile = getUpdatedFile(voice.voice) - val path = voiceFile.local.path.takeIf { isValidPath(it) } - fileApi.registerFileForMessage(voiceFile.id, msg.chatId, msg.id) - if (path == null && networkAutoDownload) { - fileApi.enqueueDownload(voiceFile.id, 1, TdMessageRemoteDataSource.DownloadType.DEFAULT, 0, 0, false) - } - val isDownloading = voiceFile.local.isDownloadingActive - val isQueued = fileApi.isFileQueued(voiceFile.id) - val downloadProgress = if (voiceFile.size > 0) { - voiceFile.local.downloadedSize.toFloat() / voiceFile.size.toFloat() - } else 0f - - MessageContent.Voice( - path = path, - duration = voice.duration, - waveform = voice.waveform, - isUploading = isActuallyUploading && voiceFile.remote.isUploadingActive, - uploadProgress = if (voiceFile.size > 0) voiceFile.remote.uploadedSize.toFloat() / voiceFile.size.toFloat() else 0f, - isDownloading = isDownloading || isQueued, - downloadProgress = downloadProgress, - fileId = voiceFile.id - ) - } - - is TdApi.MessageVideoNote -> { - val note = c.videoNote - val videoFile = getUpdatedFile(note.video) - val videoPath = videoFile.local.path.takeIf { isValidPath(it) } - fileApi.registerFileForMessage(videoFile.id, msg.chatId, msg.id) - - if (videoPath == null && networkAutoDownload && settingsRepository.autoDownloadVideoNotes.value) { - fileApi.enqueueDownload(videoFile.id, 1, TdMessageRemoteDataSource.DownloadType.VIDEO_NOTE, 0, 0, false) - } - - val thumbFile = note.thumbnail?.file?.let { getUpdatedFile(it) } - val thumbPath = thumbFile?.local?.path?.takeIf { isValidPath(it) } - if (thumbFile != null) { - fileApi.registerFileForMessage(thumbFile.id, msg.chatId, msg.id) - if (thumbPath == null && networkAutoDownload) { - fileApi.enqueueDownload(thumbFile.id, 1, TdMessageRemoteDataSource.DownloadType.DEFAULT, 0, 0, false) - } - } - val isUploading = isActuallyUploading && videoFile.remote.isUploadingActive - val progress = if (videoFile.size > 0) { - videoFile.remote.uploadedSize.toFloat() / videoFile.size.toFloat() - } else 0f - - val isDownloading = videoFile.local.isDownloadingActive - val isQueued = fileApi.isFileQueued(videoFile.id) - val downloadProgress = if (videoFile.size > 0) { - videoFile.local.downloadedSize.toFloat() / videoFile.size.toFloat() - } else 0f - - MessageContent.VideoNote( - path = videoPath, - thumbnail = thumbPath, - duration = note.duration, - length = note.length, - isUploading = isUploading, - uploadProgress = progress, - isDownloading = isDownloading || isQueued, - downloadProgress = downloadProgress, - fileId = videoFile.id - ) - } - - is TdApi.MessageSticker -> { - val sticker = c.sticker - val stickerFile = getUpdatedFile(sticker.sticker) - val path = stickerFile.local.path.takeIf { isValidPath(it) } - - fileApi.registerFileForMessage(stickerFile.id, msg.chatId, msg.id) - if (path == null && networkAutoDownload && settingsRepository.autoDownloadStickers.value) { - fileApi.enqueueDownload(stickerFile.id, 1, TdMessageRemoteDataSource.DownloadType.STICKER, 0, 0, false) - } - - val format = when (sticker.format) { - is TdApi.StickerFormatWebp -> StickerFormat.STATIC - is TdApi.StickerFormatTgs -> StickerFormat.ANIMATED - is TdApi.StickerFormatWebm -> StickerFormat.VIDEO - else -> StickerFormat.UNKNOWN - } - - val isDownloading = stickerFile.local.isDownloadingActive - val isQueued = fileApi.isFileQueued(stickerFile.id) - val downloadProgress = if (stickerFile.size > 0) { - stickerFile.local.downloadedSize.toFloat() / stickerFile.size.toFloat() - } else 0f - - MessageContent.Sticker( - id = sticker.sticker.id.toLong(), - setId = sticker.setId, - path = path, - width = sticker.width, - height = sticker.height, - emoji = sticker.emoji, - format = format, - isDownloading = isDownloading || isQueued, - downloadProgress = downloadProgress, - fileId = stickerFile.id - ) - } - - is TdApi.MessageAnimation -> { - val animation = c.animation - val animationFile = getUpdatedFile(animation.animation) - val path = animationFile.local.path.takeIf { isValidPath(it) } - fileApi.registerFileForMessage(animationFile.id, msg.chatId, msg.id) - if (path == null && networkAutoDownload) { - fileApi.enqueueDownload(animationFile.id, 1, TdMessageRemoteDataSource.DownloadType.GIF, 0, 0, false) - } - - val thumbFile = animation.thumbnail?.file?.let { getUpdatedFile(it) } - if (thumbFile != null) { - fileApi.registerFileForMessage(thumbFile.id, msg.chatId, msg.id) - if (!isValidPath(thumbFile.local.path) && networkAutoDownload) { - fileApi.enqueueDownload(thumbFile.id, 1, TdMessageRemoteDataSource.DownloadType.DEFAULT, 0, 0, false) - } - } - - val isDownloading = animationFile.local.isDownloadingActive - val isQueued = fileApi.isFileQueued(animationFile.id) - val downloadProgress = if (animationFile.size > 0) { - animationFile.local.downloadedSize.toFloat() / animationFile.size.toFloat() - } else 0f - - MessageContent.Gif( - path = path, - width = animation.width, - height = animation.height, - caption = c.caption.text, - entities = mapEntities(c.caption.entities, msg.chatId, msg.id, networkAutoDownload), - isUploading = isActuallyUploading && animationFile.remote.isUploadingActive, - uploadProgress = if (animationFile.size > 0) animationFile.remote.uploadedSize.toFloat() / animationFile.size.toFloat() else 0f, - isDownloading = isDownloading || isQueued, - downloadProgress = downloadProgress, - fileId = animationFile.id, - minithumbnail = animation.minithumbnail?.data - ) - } - - is TdApi.MessageAnimatedEmoji -> MessageContent.Text(c.emoji) - is TdApi.MessageDice -> { - val valueStr = if (c.value != 0) " (Result: ${c.value})" else "" - MessageContent.Text("${c.emoji}$valueStr") - } - - is TdApi.MessageDocument -> { - val doc = c.document - val docFile = getUpdatedFile(doc.document) - val path = docFile.local.path.takeIf { isValidPath(it) } - fileApi.registerFileForMessage(docFile.id, msg.chatId, msg.id) - - val thumbFile = doc.thumbnail?.file?.let { getUpdatedFile(it) } - if (thumbFile != null) { - fileApi.registerFileForMessage(thumbFile.id, msg.chatId, msg.id) - if (!isValidPath(thumbFile.local.path) && networkAutoDownload) { - fileApi.enqueueDownload(thumbFile.id, 1, TdMessageRemoteDataSource.DownloadType.DEFAULT, 0, 0, false) - } - } - - val isDownloading = docFile.local.isDownloadingActive - val isQueued = fileApi.isFileQueued(docFile.id) - val downloadProgress = if (docFile.size > 0) { - docFile.local.downloadedSize.toFloat() / docFile.size.toFloat() - } else 0f - - MessageContent.Document( - path = path, - fileName = doc.fileName, - mimeType = doc.mimeType, - size = docFile.size, - caption = c.caption.text, - entities = mapEntities(c.caption.entities, msg.chatId, msg.id, networkAutoDownload), - isUploading = isActuallyUploading && docFile.remote.isUploadingActive, - uploadProgress = if (docFile.size > 0) docFile.remote.uploadedSize.toFloat() / docFile.size.toFloat() else 0f, - isDownloading = isDownloading || isQueued, - downloadProgress = downloadProgress, - fileId = docFile.id - ) - } - - is TdApi.MessageAudio -> { - val audio = c.audio - val audioFile = getUpdatedFile(audio.audio) - val path = audioFile.local.path.takeIf { isValidPath(it) } - fileApi.registerFileForMessage(audioFile.id, msg.chatId, msg.id) - - if (path == null && networkAutoDownload) { - fileApi.enqueueDownload( - audioFile.id, - 1, - TdMessageRemoteDataSource.DownloadType.DEFAULT, - 0, - 0, - false - ) - } - - val isDownloading = audioFile.local.isDownloadingActive - val isQueued = fileApi.isFileQueued(audioFile.id) - val downloadProgress = if (audioFile.size > 0) { - audioFile.local.downloadedSize.toFloat() / audioFile.size.toFloat() - } else 0f - - MessageContent.Audio( - path = path, - duration = audio.duration, - title = audio.title ?: "Unknown", - performer = audio.performer ?: "Unknown", - fileName = audio.fileName ?: "audio.mp3", - mimeType = audio.mimeType ?: "audio/mpeg", - size = audioFile.size, - caption = c.caption.text, - entities = mapEntities(c.caption.entities, msg.chatId, msg.id, networkAutoDownload), - isUploading = isActuallyUploading && audioFile.remote.isUploadingActive, - uploadProgress = if (audioFile.size > 0) audioFile.remote.uploadedSize.toFloat() / audioFile.size.toFloat() else 0f, - isDownloading = isDownloading || isQueued, - downloadProgress = downloadProgress, - fileId = audioFile.id - ) - } - - is TdApi.MessageCall -> MessageContent.Text("📞 Call (${c.duration}s)") - is TdApi.MessageContact -> { - val contact = c.contact - MessageContent.Contact( - phoneNumber = contact.phoneNumber, - firstName = contact.firstName, - lastName = contact.lastName, - vcard = contact.vcard, - userId = contact.userId - ) - } - is TdApi.MessageLocation -> { - val loc = c.location - MessageContent.Location( - latitude = loc.latitude, - longitude = loc.longitude, - horizontalAccuracy = loc.horizontalAccuracy, - livePeriod = c.livePeriod, - heading = c.heading, - proximityAlertRadius = c.proximityAlertRadius - ) - } - - is TdApi.MessageVenue -> { - val v = c.venue - MessageContent.Venue( - latitude = v.location.latitude, - longitude = v.location.longitude, - title = v.title, - address = v.address, - provider = v.provider, - venueId = v.id, - venueType = v.type - ) - } - is TdApi.MessagePoll -> { - val poll = c.poll - val type = when (val pollType = poll.type) { - is TdApi.PollTypeRegular -> PollType.Regular(pollType.allowMultipleAnswers) - is TdApi.PollTypeQuiz -> PollType.Quiz(pollType.correctOptionId, pollType.explanation?.text) - else -> PollType.Regular(false) - } - MessageContent.Poll( - id = poll.id, - question = poll.question.text, - options = poll.options.map { option -> - PollOption( - text = option.text.text, - voterCount = option.voterCount, - votePercentage = option.votePercentage, - isChosen = option.isChosen, - isBeingChosen = false - ) - }, - totalVoterCount = poll.totalVoterCount, - isClosed = poll.isClosed, - isAnonymous = poll.isAnonymous, - type = type, - openPeriod = poll.openPeriod, - closeDate = poll.closeDate - ) - } - is TdApi.MessageGame -> MessageContent.Text("🎮 Game: ${c.game.title}") - is TdApi.MessageInvoice -> { - val productInfo = c.productInfo - MessageContent.Text("💳 Invoice: ${productInfo.title}") - } - is TdApi.MessageStory -> MessageContent.Text("📖 Story") - is TdApi.MessageExpiredPhoto -> MessageContent.Text("📷 Photo has expired") - is TdApi.MessageExpiredVideo -> MessageContent.Text("📹 Video has expired") - - is TdApi.MessageChatJoinByLink -> MessageContent.Service("$senderName has joined the group via invite link") - is TdApi.MessageChatAddMembers -> MessageContent.Service("$senderName added members") - is TdApi.MessageChatDeleteMember -> MessageContent.Service("$senderName left the chat") - is TdApi.MessagePinMessage -> MessageContent.Service("$senderName pinned a message") - is TdApi.MessageChatChangeTitle -> MessageContent.Service("$senderName changed group name to \"${c.title}\"") - is TdApi.MessageChatChangePhoto -> MessageContent.Service("$senderName changed group photo") - is TdApi.MessageChatDeletePhoto -> MessageContent.Service("$senderName removed group photo") - is TdApi.MessageScreenshotTaken -> MessageContent.Service("$senderName took a screenshot") - is TdApi.MessageContactRegistered -> MessageContent.Service("$senderName joined Telegram!") - is TdApi.MessageChatUpgradeTo -> MessageContent.Service("$senderName upgraded to supergroup") - is TdApi.MessageChatUpgradeFrom -> MessageContent.Service("group created") - is TdApi.MessageBasicGroupChatCreate -> MessageContent.Service("created the group \"${c.title}\"") - is TdApi.MessageSupergroupChatCreate -> MessageContent.Service("created the supergroup \"${c.title}\"") - is TdApi.MessagePaymentSuccessful -> MessageContent.Service("Payment successful: ${c.currency} ${c.totalAmount}") - is TdApi.MessagePaymentSuccessfulBot -> MessageContent.Service("Payment successful") - is TdApi.MessagePassportDataSent -> MessageContent.Service("Passport data sent") - is TdApi.MessagePassportDataReceived -> MessageContent.Service("Passport data received") - is TdApi.MessageProximityAlertTriggered -> MessageContent.Service("is within ${c.distance}m") - is TdApi.MessageForumTopicCreated -> MessageContent.Service("$senderName created topic \"${c.name}\"") - is TdApi.MessageForumTopicEdited -> MessageContent.Service("$senderName edited topic") - is TdApi.MessageForumTopicIsClosedToggled -> MessageContent.Service("$senderName toggled topic closed status") - is TdApi.MessageForumTopicIsHiddenToggled -> MessageContent.Service("$senderName toggled topic hidden status") - is TdApi.MessageSuggestProfilePhoto -> MessageContent.Service("$senderName suggested a profile photo") - is TdApi.MessageCustomServiceAction -> MessageContent.Service(c.text) - is TdApi.MessageChatBoost -> MessageContent.Service("Chat boost: ${c.boostCount}") - is TdApi.MessageChatSetTheme -> MessageContent.Service("Chat theme changed to ${c.theme}") - is TdApi.MessageGameScore -> MessageContent.Service("Game score: ${c.score}") - is TdApi.MessageVideoChatScheduled -> MessageContent.Service("Video chat scheduled for ${c.startDate}") - is TdApi.MessageVideoChatStarted -> MessageContent.Service("Video chat started") - is TdApi.MessageVideoChatEnded -> MessageContent.Service("Video chat ended") - is TdApi.MessageChatSetBackground -> MessageContent.Service("Chat background changed") - else -> MessageContent.Text("ℹ️ Unsupported message type: ${c.javaClass.simpleName}") - } - - val isServiceMessage = content is MessageContent.Service - - val canEdit = msg.isOutgoing && !isServiceMessage - val canForward = !isServiceMessage - val canSave = !isServiceMessage - - val hasInteraction = msg.interactionInfo != null - - return MessageModel( - id = msg.id, - date = resolveMessageDate(msg), - isOutgoing = msg.isOutgoing, - senderName = senderName, - chatId = msg.chatId, - content = content, - senderId = senderId, - senderAvatar = senderAvatar, - senderPersonalAvatar = senderPersonalAvatar, - senderCustomTitle = senderCustomTitle, - isRead = isReadOverride, - replyToMsgId = replyToMsgId, - replyToMsg = replyToMsg, - forwardInfo = forwardInfo, - views = views, - viewCount = views, - mediaAlbumId = msg.mediaAlbumId, - editDate = msg.editDate, - sendingState = sendingState, - readDate = readDate, - reactions = reactions, - isSenderVerified = isSenderVerified, - threadId = threadId, - replyCount = replyCount, - canBeEdited = canEdit, - canBeForwarded = canForward, - canBeDeletedOnlyForSelf = true, - canBeDeletedForAllUsers = msg.isOutgoing, - canBeSaved = canSave, - canGetMessageThread = msg.interactionInfo?.replyInfo != null, - canGetStatistics = hasInteraction, - canGetReadReceipts = hasInteraction, - canGetViewers = hasInteraction, - replyMarkup = if (isReply) null else mapReplyMarkup(msg.replyMarkup), - viaBotUserId = viaBotUserId, - viaBotName = viaBotName, - isSenderPremium = isSenderPremium, - senderStatusEmojiId = senderStatusEmojiId, - senderStatusEmojiPath = senderStatusEmojiPath - ) - } - - data class CachedMessageContent( - val type: String, - val text: String, - val meta: String?, - val fileId: Int = 0, - val path: String? = null, - val thumbnailPath: String? = null, - val minithumbnail: ByteArray? = null - ) - - private data class CachedReplyPreview( - val senderName: String, - val contentType: String, - val text: String - ) - - private data class CachedForwardOrigin( - val fromName: String, - val fromId: Long, - val originChatId: Long? = null, - val originMessageId: Long? = null - ) - - fun mapToEntity( - msg: TdApi.Message, - getSenderName: ((Long) -> String?)? = null - ): org.monogram.data.db.model.MessageEntity { - val senderId = when (val sender = msg.senderId) { - is TdApi.MessageSenderUser -> sender.userId - is TdApi.MessageSenderChat -> sender.chatId - else -> 0L - } - val senderName = getSenderName?.invoke(senderId).orEmpty() - val content = extractCachedContent(msg.content) - val entitiesEncoded = encodeEntities(msg.content) - val replyToMessageId = (msg.replyTo as? TdApi.MessageReplyToMessage)?.messageId ?: 0L - val replyToPreview = buildReplyPreview(msg) - val forwardOrigin = msg.forwardInfo?.origin?.let(::extractForwardOrigin) - - return org.monogram.data.db.model.MessageEntity( - id = msg.id, - chatId = msg.chatId, - senderId = senderId, - senderName = senderName, - content = content.text, - contentType = content.type, - contentMeta = content.meta, - mediaFileId = content.fileId, - mediaPath = content.path, - mediaThumbnailPath = content.thumbnailPath, - minithumbnail = content.minithumbnail, - date = resolveMessageDate(msg), - isOutgoing = msg.isOutgoing, - isRead = false, - replyToMessageId = replyToMessageId, - replyToPreview = replyToPreview?.let(::encodeReplyPreview), - replyToPreviewType = replyToPreview?.contentType, - replyToPreviewText = replyToPreview?.text, - replyToPreviewSenderName = replyToPreview?.senderName, - replyCount = msg.interactionInfo?.replyInfo?.replyCount ?: 0, - forwardFromName = forwardOrigin?.fromName, - forwardFromId = forwardOrigin?.fromId ?: 0L, - forwardOriginChatId = forwardOrigin?.originChatId, - forwardOriginMessageId = forwardOrigin?.originMessageId, - forwardDate = msg.forwardInfo?.date ?: 0, - editDate = msg.editDate, - mediaAlbumId = msg.mediaAlbumId, - entities = entitiesEncoded, - viewCount = msg.interactionInfo?.viewCount ?: 0, - forwardCount = msg.interactionInfo?.forwardCount ?: 0, - createdAt = System.currentTimeMillis() - ) - } - - fun extractCachedContent(content: TdApi.MessageContent): CachedMessageContent { - return when (content) { - is TdApi.MessageText -> CachedMessageContent("text", content.text.text, null) - is TdApi.MessagePhoto -> { - val sizes = content.photo.sizes - val best = sizes.find { it.type == "x" } - ?: sizes.find { it.type == "m" } - ?: sizes.getOrNull(sizes.size / 2) - ?: sizes.lastOrNull() - val thumbnail = sizes.find { it.type == "m" } - ?: sizes.find { it.type == "s" } - val fileId = best?.photo?.id ?: 0 - val path = best?.photo?.local?.path?.takeIf { it.isNotBlank() } - val thumbnailPath = thumbnail?.photo?.local?.path?.takeIf { it.isNotBlank() } - CachedMessageContent( - "photo", - content.caption?.text.orEmpty(), - encodeMeta(best?.width ?: 0, best?.height ?: 0), - fileId = fileId, - path = path, - thumbnailPath = thumbnailPath, - minithumbnail = content.photo.minithumbnail?.data - ) - } - - is TdApi.MessageVideo -> { - val fileId = content.video.video.id - val path = content.video.video.local?.path?.takeIf { it.isNotBlank() } - CachedMessageContent( - "video", - content.caption?.text.orEmpty(), - encodeMeta( - content.video.width, - content.video.height, - content.video.duration, - content.video.thumbnail?.file?.local?.path.orEmpty(), - if (content.video.supportsStreaming) 1 else 0 - ), - fileId = fileId, - path = path, - thumbnailPath = content.video.thumbnail?.file?.local?.path?.takeIf { it.isNotBlank() }, - minithumbnail = content.video.minithumbnail?.data - ) - } - - is TdApi.MessageVoiceNote -> CachedMessageContent( - "voice", - content.caption?.text.orEmpty(), - encodeMeta(content.voiceNote.duration), - fileId = content.voiceNote.voice.id, - path = content.voiceNote.voice.local?.path?.takeIf { it.isNotBlank() } - ) - - is TdApi.MessageVideoNote -> CachedMessageContent( - "video_note", - "", - encodeMeta( - content.videoNote.duration, - content.videoNote.length, - content.videoNote.thumbnail?.file?.local?.path.orEmpty() - ), - fileId = content.videoNote.video.id, - path = content.videoNote.video.local?.path?.takeIf { it.isNotBlank() } - ) - - is TdApi.MessageSticker -> { - val format = when (content.sticker.format) { - is TdApi.StickerFormatWebp -> "webp" - is TdApi.StickerFormatTgs -> "tgs" - is TdApi.StickerFormatWebm -> "webm" - else -> "unknown" - } - CachedMessageContent( - "sticker", - content.sticker.emoji, - encodeMeta( - content.sticker.setId, - content.sticker.emoji, - content.sticker.width, - content.sticker.height, - format - ), - fileId = content.sticker.sticker.id, - path = content.sticker.sticker.local?.path?.takeIf { it.isNotBlank() } - ) - } - - is TdApi.MessageDocument -> CachedMessageContent( - "document", - content.caption?.text.orEmpty(), - encodeMeta(content.document.fileName, content.document.mimeType, content.document.document.size), - fileId = content.document.document.id, - path = content.document.document.local?.path?.takeIf { it.isNotBlank() } - ) - - is TdApi.MessageAudio -> CachedMessageContent( - "audio", - content.caption?.text.orEmpty(), - encodeMeta( - content.audio.duration, - content.audio.title.orEmpty(), - content.audio.performer.orEmpty(), - content.audio.fileName.orEmpty() - ), - fileId = content.audio.audio.id, - path = content.audio.audio.local?.path?.takeIf { it.isNotBlank() } - ) - - is TdApi.MessageAnimation -> CachedMessageContent( - "gif", - content.caption?.text.orEmpty(), - encodeMeta( - content.animation.width, - content.animation.height, - content.animation.duration, - content.animation.thumbnail?.file?.local?.path.orEmpty() - ), - fileId = content.animation.animation.id, - path = content.animation.animation.local?.path?.takeIf { it.isNotBlank() } - ) - - is TdApi.MessagePoll -> CachedMessageContent( - "poll", - content.poll.question.text, - encodeMeta(content.poll.options.size, if (content.poll.isClosed) 1 else 0) - ) - - is TdApi.MessageContact -> CachedMessageContent( - "contact", - listOf(content.contact.firstName, content.contact.lastName).filter { it.isNotBlank() } - .joinToString(" "), - encodeMeta( - content.contact.phoneNumber, - content.contact.firstName, - content.contact.lastName, - content.contact.userId - ) - ) - - is TdApi.MessageLocation -> CachedMessageContent( - "location", - "", - encodeMeta(content.location.latitude, content.location.longitude, content.livePeriod) - ) - - is TdApi.MessageCall -> CachedMessageContent("service", "Call (${content.duration}s)", null) - is TdApi.MessagePinMessage -> CachedMessageContent("service", "Pinned a message", null) - is TdApi.MessageChatAddMembers -> CachedMessageContent("service", "Added members", null) - is TdApi.MessageChatDeleteMember -> CachedMessageContent("service", "Removed a member", null) - is TdApi.MessageChatChangeTitle -> CachedMessageContent("service", "Changed title", null) - is TdApi.MessageAnimatedEmoji -> CachedMessageContent("text", content.emoji, null) - is TdApi.MessageDice -> CachedMessageContent("text", content.emoji, null) - else -> CachedMessageContent("unsupported", "", null) - } - } - - fun mapEntityToModel(entity: org.monogram.data.db.model.MessageEntity): MessageModel { - val meta = decodeMeta(entity.contentMeta) - val usesLegacyEmbeddedMedia = entity.mediaFileId == 0 && entity.mediaPath.isNullOrBlank() - val (legacyFileId, legacyPath) = if (usesLegacyEmbeddedMedia) { - resolveLegacyMediaFromMeta(entity.contentType, meta) - } else { - 0 to null - } - val mediaFileId = entity.mediaFileId.takeIf { it != 0 } ?: legacyFileId - val mediaPath = entity.mediaPath?.takeIf { it.isNotBlank() } ?: legacyPath - val replyToMsgId = entity.replyToMessageId.takeIf { it != 0L } - val replyPreview = resolveReplyPreview(entity) - val replyPreviewModel = - if (replyToMsgId != null && replyPreview != null) createReplyPreviewModel(entity, replyToMsgId, replyPreview) else null - - val cachedSenderUser = entity.senderId.takeIf { it > 0L }?.let { cache.getUser(it) } - val cachedSenderChat = if (cachedSenderUser == null && entity.senderId > 0L) { - cache.getChat(entity.senderId) - } else { - null - } - - val resolvedSenderName = resolveSenderNameFromCache(entity.senderId, entity.senderName) - val resolvedSenderAvatar = when { - cachedSenderUser != null -> resolveLocalFilePath(cachedSenderUser.profilePhoto?.small) - cachedSenderChat != null -> resolveLocalFilePath(cachedSenderChat.photo?.small) - else -> null - } - val resolvedSenderPersonalAvatar = cache.getUserFullInfo(entity.senderId) - ?.personalPhoto - ?.sizes - ?.firstOrNull() - ?.photo - ?.let { resolveLocalFilePath(it) } - - val senderStatusEmojiId = when (val type = cachedSenderUser?.emojiStatus?.type) { - is TdApi.EmojiStatusTypeCustomEmoji -> type.customEmojiId - is TdApi.EmojiStatusTypeUpgradedGift -> type.modelCustomEmojiId - else -> 0L - } - - val forwardInfo = entity.forwardFromName - ?.takeIf { it.isNotBlank() } - ?.let { fromName -> - ForwardInfo( - date = entity.forwardDate.takeIf { it > 0 } ?: entity.date, - fromId = entity.forwardFromId, - fromName = fromName, - originChatId = entity.forwardOriginChatId, - originMessageId = entity.forwardOriginMessageId - ) - } - - val content: MessageContent = when (entity.contentType) { - "text" -> MessageContent.Text(entity.content) - - "photo" -> { - val fileId = mediaFileId - registerCachedFile(fileId, entity.chatId, entity.id) - MessageContent.Photo( - path = resolveCachedPath(fileId, mediaPath), - thumbnailPath = entity.mediaThumbnailPath?.takeIf { isValidPath(it) }, - width = meta.getOrNull(0)?.toIntOrNull() ?: 0, - height = meta.getOrNull(1)?.toIntOrNull() ?: 0, - caption = entity.content, - fileId = fileId, - minithumbnail = entity.minithumbnail - ) - } - - "video" -> { - val fileId = mediaFileId - val supportsStreaming = if (usesLegacyEmbeddedMedia) { - (meta.getOrNull(6)?.toIntOrNull() ?: 0) == 1 - } else { - (meta.getOrNull(4)?.toIntOrNull() ?: 0) == 1 - } - registerCachedFile(fileId, entity.chatId, entity.id) - MessageContent.Video( - path = resolveCachedPath(fileId, mediaPath), - thumbnailPath = ( - entity.mediaThumbnailPath?.takeIf { isValidPath(it) } - ?: meta.getOrNull(3) - )?.takeIf { isValidPath(it) }, - width = meta.getOrNull(0)?.toIntOrNull() ?: 0, - height = meta.getOrNull(1)?.toIntOrNull() ?: 0, - duration = meta.getOrNull(2)?.toIntOrNull() ?: 0, - caption = entity.content, - fileId = fileId, - supportsStreaming = supportsStreaming, - minithumbnail = entity.minithumbnail - ) - } - - "voice" -> { - val fileId = mediaFileId - registerCachedFile(fileId, entity.chatId, entity.id) - MessageContent.Voice( - path = resolveCachedPath(fileId, mediaPath), - duration = meta.getOrNull(0)?.toIntOrNull() ?: 0, - fileId = fileId - ) - } - - "video_note" -> { - val fileId = mediaFileId - val storedThumbPath = if (usesLegacyEmbeddedMedia) meta.getOrNull(4) else meta.getOrNull(2) - registerCachedFile(fileId, entity.chatId, entity.id) - MessageContent.VideoNote( - path = resolveCachedPath(fileId, mediaPath), - thumbnail = storedThumbPath?.takeIf { isValidPath(it) }, - duration = meta.getOrNull(0)?.toIntOrNull() ?: 0, - length = meta.getOrNull(1)?.toIntOrNull() ?: 0, - fileId = fileId - ) - } - - "sticker" -> { - val fileId = mediaFileId - registerCachedFile(fileId, entity.chatId, entity.id) - MessageContent.Sticker( - id = 0L, - setId = meta.getOrNull(0)?.toLongOrNull() ?: 0L, - path = resolveCachedPath(fileId, mediaPath), - width = meta.getOrNull(2)?.toIntOrNull() ?: 0, - height = meta.getOrNull(3)?.toIntOrNull() ?: 0, - emoji = entity.content, - fileId = fileId - ) - } - - "document" -> { - val fileId = mediaFileId - registerCachedFile(fileId, entity.chatId, entity.id) - MessageContent.Document( - path = resolveCachedPath(fileId, mediaPath), - fileName = meta.getOrNull(0).orEmpty(), - mimeType = meta.getOrNull(1).orEmpty(), - size = meta.getOrNull(2)?.toLongOrNull() ?: 0L, - caption = entity.content, - fileId = fileId - ) - } - - "audio" -> { - val fileId = mediaFileId - registerCachedFile(fileId, entity.chatId, entity.id) - MessageContent.Audio( - path = resolveCachedPath(fileId, mediaPath), - duration = meta.getOrNull(0)?.toIntOrNull() ?: 0, - title = meta.getOrNull(1).orEmpty(), - performer = meta.getOrNull(2).orEmpty(), - fileName = meta.getOrNull(3).orEmpty(), - mimeType = "", - size = 0L, - caption = entity.content, - fileId = fileId - ) - } - - "gif" -> { - val fileId = mediaFileId - registerCachedFile(fileId, entity.chatId, entity.id) - MessageContent.Gif( - path = resolveCachedPath(fileId, mediaPath), - width = meta.getOrNull(0)?.toIntOrNull() ?: 0, - height = meta.getOrNull(1)?.toIntOrNull() ?: 0, - caption = entity.content, - fileId = fileId - ) - } - - "poll" -> MessageContent.Poll( - id = 0L, - question = entity.content, - options = emptyList(), - totalVoterCount = 0, - isClosed = (meta.getOrNull(1)?.toIntOrNull() ?: 0) == 1, - isAnonymous = true, - type = PollType.Regular(false), - openPeriod = 0, - closeDate = 0 - ) - - "contact" -> MessageContent.Contact( - phoneNumber = meta.getOrNull(0).orEmpty(), - firstName = meta.getOrNull(1).orEmpty(), - lastName = meta.getOrNull(2).orEmpty(), - vcard = "", - userId = meta.getOrNull(3)?.toLongOrNull() ?: 0L - ) - - "location" -> MessageContent.Location( - latitude = meta.getOrNull(0)?.toDoubleOrNull() ?: 0.0, - longitude = meta.getOrNull(1)?.toDoubleOrNull() ?: 0.0, - livePeriod = meta.getOrNull(2)?.toIntOrNull() ?: 0 - ) - - "service" -> MessageContent.Service(entity.content) - else -> MessageContent.Text(entity.content) - } - - return MessageModel( - id = entity.id, - date = entity.date, - isOutgoing = entity.isOutgoing, - senderName = resolvedSenderName, - chatId = entity.chatId, - content = content, - senderId = entity.senderId, - senderAvatar = resolvedSenderAvatar, - senderPersonalAvatar = resolvedSenderPersonalAvatar, - isRead = entity.isRead, - replyToMsgId = replyToMsgId, - replyToMsg = replyPreviewModel, - forwardInfo = forwardInfo, - mediaAlbumId = entity.mediaAlbumId, - editDate = entity.editDate, - views = entity.viewCount, - viewCount = entity.viewCount, - replyCount = entity.replyCount, - isSenderVerified = cachedSenderUser?.verificationStatus?.isVerified ?: false, - isSenderPremium = cachedSenderUser?.isPremium ?: false, - senderStatusEmojiId = senderStatusEmojiId - ) - } - - private fun buildReplyPreview(msg: TdApi.Message): CachedReplyPreview? { - val reply = msg.replyTo as? TdApi.MessageReplyToMessage ?: return null - val replied = cache.getMessage(msg.chatId, reply.messageId) ?: return null - val replySenderName = when (val sender = replied.senderId) { - is TdApi.MessageSenderUser -> { - val user = cache.getUser(sender.userId) - listOfNotNull(user?.firstName?.takeIf { it.isNotBlank() }, user?.lastName?.takeIf { it.isNotBlank() }) - .joinToString(" ") - } - - is TdApi.MessageSenderChat -> cache.getChat(sender.chatId)?.title.orEmpty() - else -> "" - } - val extracted = extractCachedContent(replied.content) - return CachedReplyPreview( - senderName = replySenderName, - contentType = extracted.type, - text = extracted.text.take(100) - ) - } - - private fun encodeReplyPreview(preview: CachedReplyPreview): String { - return "${preview.senderName}|${preview.contentType}|${preview.text}" - } - - private fun parseReplyPreview(raw: String?): CachedReplyPreview? { - if (raw.isNullOrBlank()) return null - val firstSeparator = raw.indexOf('|') - val secondSeparator = raw.indexOf('|', firstSeparator + 1) - if (firstSeparator < 0 || secondSeparator <= firstSeparator) return null - - val senderName = raw.substring(0, firstSeparator) - val contentType = raw.substring(firstSeparator + 1, secondSeparator) - val text = raw.substring(secondSeparator + 1) - if (contentType.isBlank()) return null - - return CachedReplyPreview(senderName = senderName, contentType = contentType, text = text) - } - - private fun resolveReplyPreview(entity: org.monogram.data.db.model.MessageEntity): CachedReplyPreview? { - val encodedPreview = parseReplyPreview(entity.replyToPreview) - val senderName = entity.replyToPreviewSenderName ?: encodedPreview?.senderName - val contentType = entity.replyToPreviewType ?: encodedPreview?.contentType - val text = entity.replyToPreviewText ?: encodedPreview?.text ?: "" - - if (senderName.isNullOrBlank() && contentType.isNullOrBlank() && text.isBlank()) { - return null - } - - return CachedReplyPreview( - senderName = senderName.orEmpty(), - contentType = contentType?.ifBlank { "text" } ?: "text", - text = text - ) - } - - private fun createReplyPreviewModel( - entity: org.monogram.data.db.model.MessageEntity, - replyToMsgId: Long, - preview: CachedReplyPreview - ): MessageModel { - return MessageModel( - id = replyToMsgId, - date = entity.date, - isOutgoing = false, - senderName = preview.senderName.ifBlank { "Unknown" }, - chatId = entity.chatId, - content = mapReplyPreviewContent(preview), - senderId = 0L, - isRead = true - ) - } - - private fun mapReplyPreviewContent(preview: CachedReplyPreview): MessageContent { - return when (preview.contentType) { - "photo" -> MessageContent.Photo(path = null, width = 0, height = 0, caption = preview.text) - "video" -> MessageContent.Video(path = null, width = 0, height = 0, duration = 0, caption = preview.text) - "voice" -> MessageContent.Voice(path = null, duration = 0) - "video_note" -> MessageContent.VideoNote(path = null, thumbnail = null, duration = 0, length = 0) - "sticker" -> MessageContent.Sticker(id = 0L, setId = 0L, path = null, width = 0, height = 0, emoji = preview.text) - "document" -> MessageContent.Document(path = null, fileName = "", mimeType = "", size = 0L, caption = preview.text) - "audio" -> MessageContent.Audio( - path = null, - duration = 0, - title = "", - performer = "", - fileName = "", - mimeType = "", - size = 0L, - caption = preview.text - ) - "gif" -> MessageContent.Gif(path = null, width = 0, height = 0, caption = preview.text) - "poll" -> MessageContent.Poll( - id = 0L, - question = preview.text, - options = emptyList(), - totalVoterCount = 0, - isClosed = false, - isAnonymous = true, - type = PollType.Regular(false), - openPeriod = 0, - closeDate = 0 - ) - "contact" -> MessageContent.Contact( - phoneNumber = "", - firstName = preview.text, - lastName = "", - vcard = "", - userId = 0L - ) - "location" -> MessageContent.Location(latitude = 0.0, longitude = 0.0) - "service" -> MessageContent.Service(preview.text) - else -> MessageContent.Text(preview.text) - } - } - - private fun extractForwardOrigin(origin: TdApi.MessageOrigin): CachedForwardOrigin { - return when (origin) { - is TdApi.MessageOriginUser -> { - val user = cache.getUser(origin.senderUserId) - val name = listOfNotNull(user?.firstName?.takeIf { it.isNotBlank() }, user?.lastName?.takeIf { it.isNotBlank() }) - .joinToString(" ") - .ifBlank { "User" } - CachedForwardOrigin(fromName = name, fromId = origin.senderUserId) - } - - is TdApi.MessageOriginChat -> CachedForwardOrigin( - fromName = cache.getChat(origin.senderChatId)?.title ?: "Chat", - fromId = origin.senderChatId - ) - - is TdApi.MessageOriginChannel -> CachedForwardOrigin( - fromName = cache.getChat(origin.chatId)?.title ?: "Channel", - fromId = origin.chatId, - originChatId = origin.chatId, - originMessageId = origin.messageId - ) - - is TdApi.MessageOriginHiddenUser -> CachedForwardOrigin( - fromName = origin.senderName.ifBlank { "Hidden user" }, - fromId = 0L - ) - - else -> CachedForwardOrigin(fromName = "Unknown", fromId = 0L) - } - } - - private fun encodeEntities(content: TdApi.MessageContent): String? { - val formatted = when (content) { - is TdApi.MessageText -> content.text - is TdApi.MessagePhoto -> content.caption - is TdApi.MessageVideo -> content.caption - is TdApi.MessageDocument -> content.caption - is TdApi.MessageAudio -> content.caption - is TdApi.MessageAnimation -> content.caption - is TdApi.MessageVoiceNote -> content.caption - else -> null - } ?: return null - - if (formatted.entities.isNullOrEmpty()) return null - - return buildString { - formatted.entities.forEachIndexed { index, entity -> - if (index > 0) append('|') - append(entity.offset).append(',').append(entity.length).append(',') - when (val type = entity.type) { - is TdApi.TextEntityTypeBold -> append("b") - is TdApi.TextEntityTypeItalic -> append("i") - is TdApi.TextEntityTypeUnderline -> append("u") - is TdApi.TextEntityTypeStrikethrough -> append("s") - is TdApi.TextEntityTypeSpoiler -> append("sp") - is TdApi.TextEntityTypeCode -> append("c") - is TdApi.TextEntityTypePre -> append("p") - is TdApi.TextEntityTypeUrl -> append("url") - is TdApi.TextEntityTypeTextUrl -> append("turl,").append(type.url) - is TdApi.TextEntityTypeMention -> append("m") - is TdApi.TextEntityTypeMentionName -> append("mn,").append(type.userId) - is TdApi.TextEntityTypeHashtag -> append("h") - is TdApi.TextEntityTypeBotCommand -> append("bc") - is TdApi.TextEntityTypeCustomEmoji -> append("ce,").append(type.customEmojiId) - is TdApi.TextEntityTypeEmailAddress -> append("em") - is TdApi.TextEntityTypePhoneNumber -> append("ph") - else -> append("?") - } - } - } - } - - private fun resolveMessageDate(msg: TdApi.Message): Int { - return when (val schedulingState = msg.schedulingState) { - is TdApi.MessageSchedulingStateSendAtDate -> schedulingState.sendDate - else -> msg.date - } - } - - private suspend fun loadCustomEmoji(emojiId: Long, chatId: Long, messageId: Long, autoDownload: Boolean) { - val result = gateway.execute(TdApi.GetCustomEmojiStickers(longArrayOf(emojiId))) - - if (result is TdApi.Stickers && result.stickers.isNotEmpty()) { - val fileToUse = result.stickers.first().sticker - - fileIdToCustomEmojiId[fileToUse.id] = emojiId - fileApi.registerFileForMessage(fileToUse.id, chatId, messageId) - - if (!isValidPath(fileToUse.local.path)) { - if (autoDownload) { - fileApi.enqueueDownload(fileToUse.id, 32, TdMessageRemoteDataSource.DownloadType.DEFAULT, 0, 0, false) - } - } else { - customEmojiPaths[emojiId] = fileToUse.local.path - } - } - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/mapper/NetworkMapper.kt b/data/src/main/java/org/monogram/data/mapper/NetworkMapper.kt deleted file mode 100644 index 1aba48ce..00000000 --- a/data/src/main/java/org/monogram/data/mapper/NetworkMapper.kt +++ /dev/null @@ -1,95 +0,0 @@ -package org.monogram.data.mapper - -import android.util.Log -import org.drinkless.tdlib.TdApi -import org.monogram.domain.models.NetworkTypeUsage -import org.monogram.domain.models.NetworkUsageCategory -import org.monogram.domain.models.NetworkUsageModel -import org.monogram.domain.repository.StringProvider - -class NetworkMapper( - private val stringProvider: StringProvider, - private val storageMapper: StorageMapper -) { - fun mapToDomain(statistics: TdApi.NetworkStatistics): NetworkUsageModel { - val mobileDetails = mutableMapOf>() - val wifiDetails = mutableMapOf>() - val roamingDetails = mutableMapOf>() - val otherDetails = mutableMapOf>() - - var mobileSent = 0L - var mobileReceived = 0L - var wifiSent = 0L - var wifiReceived = 0L - var roamingSent = 0L - var roamingReceived = 0L - var otherSent = 0L - var otherReceived = 0L - - statistics.entries.forEachIndexed { index, entry -> - val categoryName = if (entry is TdApi.NetworkStatisticsEntryFile) { - storageMapper.mapFileTypeToDomain(entry.fileType) - } else { - stringProvider.getString("network_calls") - } - val sent = if (entry is TdApi.NetworkStatisticsEntryFile) entry.sentBytes else if (entry is TdApi.NetworkStatisticsEntryCall) entry.sentBytes else 0L - val received = if (entry is TdApi.NetworkStatisticsEntryFile) entry.receivedBytes else if (entry is TdApi.NetworkStatisticsEntryCall) entry.receivedBytes else 0L - - val networkType = when (entry) { - is TdApi.NetworkStatisticsEntryFile -> entry.networkType - is TdApi.NetworkStatisticsEntryCall -> entry.networkType - else -> null - } - - Log.d( - "NetworkMapper", - "Processing entry $index: category=$categoryName, sent=$sent, received=$received, type=${networkType?.javaClass?.simpleName}" - ) - - when (networkType) { - is TdApi.NetworkTypeMobile -> { - mobileSent += sent - mobileReceived += received - val current = mobileDetails[categoryName] ?: (0L to 0L) - mobileDetails[categoryName] = (current.first + sent) to (current.second + received) - Log.d("NetworkMapper", "-> Added to Mobile") - } - is TdApi.NetworkTypeWiFi -> { - wifiSent += sent - wifiReceived += received - val current = wifiDetails[categoryName] ?: (0L to 0L) - wifiDetails[categoryName] = (current.first + sent) to (current.second + received) - Log.d("NetworkMapper", "-> Added to WiFi") - } - is TdApi.NetworkTypeMobileRoaming -> { - roamingSent += sent - roamingReceived += received - val current = roamingDetails[categoryName] ?: (0L to 0L) - roamingDetails[categoryName] = (current.first + sent) to (current.second + received) - Log.d("NetworkMapper", "-> Added to Roaming") - } - - else -> { - otherSent += sent - otherReceived += received - val current = otherDetails[categoryName] ?: (0L to 0L) - otherDetails[categoryName] = (current.first + sent) to (current.second + received) - Log.d("NetworkMapper", "-> Added to Other (type was ${networkType?.javaClass?.simpleName})") - } - } - } - - return NetworkUsageModel( - mobile = NetworkTypeUsage(mobileSent, mobileReceived, mobileDetails.map { (k, v) -> NetworkUsageCategory(k, v.first, v.second) }), - wifi = NetworkTypeUsage(wifiSent, wifiReceived, wifiDetails.map { (k, v) -> NetworkUsageCategory(k, v.first, v.second) }), - roaming = NetworkTypeUsage( - roamingSent, - roamingReceived, - roamingDetails.map { (k, v) -> NetworkUsageCategory(k, v.first, v.second) }), - other = NetworkTypeUsage( - otherSent, - otherReceived, - otherDetails.map { (k, v) -> NetworkUsageCategory(k, v.first, v.second) }) - ) - } -} diff --git a/data/src/main/java/org/monogram/data/mapper/PrivacyMapper.kt b/data/src/main/java/org/monogram/data/mapper/PrivacyMapper.kt deleted file mode 100644 index 37d6cb3a..00000000 --- a/data/src/main/java/org/monogram/data/mapper/PrivacyMapper.kt +++ /dev/null @@ -1,39 +0,0 @@ -package org.monogram.data.mapper - -import org.drinkless.tdlib.TdApi -import org.monogram.domain.models.PrivacyRule -import org.monogram.domain.repository.PrivacyKey - -fun PrivacyKey.toApi(): TdApi.UserPrivacySetting = when (this) { - PrivacyKey.PHONE_NUMBER -> TdApi.UserPrivacySettingShowPhoneNumber() - PrivacyKey.PHONE_NUMBER_SEARCH -> TdApi.UserPrivacySettingAllowFindingByPhoneNumber() - PrivacyKey.LAST_SEEN -> TdApi.UserPrivacySettingShowStatus() - PrivacyKey.PROFILE_PHOTO -> TdApi.UserPrivacySettingShowProfilePhoto() - PrivacyKey.BIO -> TdApi.UserPrivacySettingShowBio() - PrivacyKey.FORWARDED_MESSAGES -> TdApi.UserPrivacySettingShowLinkInForwardedMessages() - PrivacyKey.CALLS -> TdApi.UserPrivacySettingAllowCalls() - PrivacyKey.GROUPS_AND_CHANNELS -> TdApi.UserPrivacySettingAllowChatInvites() -} - -fun TdApi.UserPrivacySettingRule.toDomain(): PrivacyRule = when (this) { - is TdApi.UserPrivacySettingRuleAllowAll -> PrivacyRule.AllowAll - is TdApi.UserPrivacySettingRuleAllowContacts -> PrivacyRule.AllowContacts - is TdApi.UserPrivacySettingRuleAllowUsers -> PrivacyRule.AllowUsers(userIds.toList()) - is TdApi.UserPrivacySettingRuleAllowChatMembers -> PrivacyRule.AllowChatMembers(chatIds.toList()) - is TdApi.UserPrivacySettingRuleRestrictAll -> PrivacyRule.AllowNone - is TdApi.UserPrivacySettingRuleRestrictContacts -> PrivacyRule.DisallowContacts - is TdApi.UserPrivacySettingRuleRestrictUsers -> PrivacyRule.DisallowUsers(userIds.toList()) - is TdApi.UserPrivacySettingRuleRestrictChatMembers -> PrivacyRule.DisallowChatMembers(chatIds.toList()) - else -> PrivacyRule.AllowNone -} - -fun PrivacyRule.toApi(): TdApi.UserPrivacySettingRule = when (this) { - is PrivacyRule.AllowAll -> TdApi.UserPrivacySettingRuleAllowAll() - is PrivacyRule.AllowContacts -> TdApi.UserPrivacySettingRuleAllowContacts() - is PrivacyRule.AllowNone -> TdApi.UserPrivacySettingRuleRestrictAll() - is PrivacyRule.AllowUsers -> TdApi.UserPrivacySettingRuleAllowUsers(userIds.toLongArray()) - is PrivacyRule.AllowChatMembers -> TdApi.UserPrivacySettingRuleAllowChatMembers(chatIds.toLongArray()) - is PrivacyRule.DisallowContacts -> TdApi.UserPrivacySettingRuleRestrictContacts() - is PrivacyRule.DisallowUsers -> TdApi.UserPrivacySettingRuleRestrictUsers(userIds.toLongArray()) - is PrivacyRule.DisallowChatMembers -> TdApi.UserPrivacySettingRuleRestrictChatMembers(chatIds.toLongArray()) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/mapper/ProxyMapper.kt b/data/src/main/java/org/monogram/data/mapper/ProxyMapper.kt deleted file mode 100644 index 87018d60..00000000 --- a/data/src/main/java/org/monogram/data/mapper/ProxyMapper.kt +++ /dev/null @@ -1,27 +0,0 @@ -package org.monogram.data.mapper - -import org.drinkless.tdlib.TdApi -import org.monogram.domain.models.ProxyModel -import org.monogram.domain.models.ProxyTypeModel - -fun TdApi.AddedProxy.toDomain(): ProxyModel = ProxyModel( - id = id, - server = proxy.server, - port = proxy.port, - lastUsedDate = lastUsedDate, - isEnabled = isEnabled, - type = proxy.type.toDomain() -) - -fun TdApi.ProxyType.toDomain(): ProxyTypeModel = when (this) { - is TdApi.ProxyTypeSocks5 -> ProxyTypeModel.Socks5(username, password) - is TdApi.ProxyTypeHttp -> ProxyTypeModel.Http(username, password, httpOnly) - is TdApi.ProxyTypeMtproto -> ProxyTypeModel.Mtproto(secret) - else -> throw IllegalArgumentException("Unknown proxy type: $this") -} - -fun ProxyTypeModel.toApi(): TdApi.ProxyType = when (this) { - is ProxyTypeModel.Socks5 -> TdApi.ProxyTypeSocks5(username, password) - is ProxyTypeModel.Http -> TdApi.ProxyTypeHttp(username, password, httpOnly) - is ProxyTypeModel.Mtproto -> TdApi.ProxyTypeMtproto(secret) -} diff --git a/data/src/main/java/org/monogram/data/mapper/SessionMapper.kt b/data/src/main/java/org/monogram/data/mapper/SessionMapper.kt deleted file mode 100644 index 9248e35c..00000000 --- a/data/src/main/java/org/monogram/data/mapper/SessionMapper.kt +++ /dev/null @@ -1,47 +0,0 @@ -package org.monogram.data.mapper - -import org.drinkless.tdlib.TdApi -import org.monogram.domain.models.SessionModel -import org.monogram.domain.models.SessionType - -fun TdApi.Session.toDomain(): SessionModel { - return SessionModel( - id = this.id, - isCurrent = this.isCurrent, - isPasswordPending = this.isPasswordPending, - isUnconfirmed = this.isUnconfirmed, - applicationName = this.applicationName, - applicationVersion = this.applicationVersion, - deviceModel = this.deviceModel, - platform = this.platform, - systemVersion = this.systemVersion, - logInDate = this.logInDate, - lastActiveDate = this.lastActiveDate, - ipAddress = this.ipAddress, - location = this.location, - isOfficial = this.isOfficialApplication, - type = this.type.toDomain() - ) -} - -fun TdApi.SessionType.toDomain(): SessionType { - return when (this) { - is TdApi.SessionTypeAndroid -> SessionType.Android - is TdApi.SessionTypeApple -> SessionType.Apple - is TdApi.SessionTypeBrave -> SessionType.Brave - is TdApi.SessionTypeChrome -> SessionType.Chrome - is TdApi.SessionTypeEdge -> SessionType.Edge - is TdApi.SessionTypeFirefox -> SessionType.Firefox - is TdApi.SessionTypeIpad -> SessionType.Ipad - is TdApi.SessionTypeIphone -> SessionType.Iphone - is TdApi.SessionTypeLinux -> SessionType.Linux - is TdApi.SessionTypeMac -> SessionType.Mac - is TdApi.SessionTypeOpera -> SessionType.Opera - is TdApi.SessionTypeSafari -> SessionType.Safari - is TdApi.SessionTypeUbuntu -> SessionType.Ubuntu - is TdApi.SessionTypeVivaldi -> SessionType.Vivaldi - is TdApi.SessionTypeWindows -> SessionType.Windows - is TdApi.SessionTypeXbox -> SessionType.Xbox - else -> SessionType.Unknown - } -} diff --git a/data/src/main/java/org/monogram/data/mapper/SettingsMapper.kt b/data/src/main/java/org/monogram/data/mapper/SettingsMapper.kt deleted file mode 100644 index ef258966..00000000 --- a/data/src/main/java/org/monogram/data/mapper/SettingsMapper.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.monogram.data.mapper - -import org.drinkless.tdlib.TdApi -import org.monogram.domain.repository.SettingsRepository.TdNotificationScope - -fun TdNotificationScope.toApi(): TdApi.NotificationSettingsScope = when (this) { - TdNotificationScope.PRIVATE_CHATS -> TdApi.NotificationSettingsScopePrivateChats() - TdNotificationScope.GROUPS -> TdApi.NotificationSettingsScopeGroupChats() - TdNotificationScope.CHANNELS -> TdApi.NotificationSettingsScopeChannelChats() -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/mapper/SponsorRegistry.kt b/data/src/main/java/org/monogram/data/mapper/SponsorRegistry.kt deleted file mode 100644 index c4b5cc9f..00000000 --- a/data/src/main/java/org/monogram/data/mapper/SponsorRegistry.kt +++ /dev/null @@ -1,13 +0,0 @@ -package org.monogram.data.mapper - -import java.util.concurrent.atomic.AtomicReference - -private val sponsorIdsRef = AtomicReference>(emptySet()) - -fun updateSponsorIds(ids: Set) { - sponsorIdsRef.set(ids) -} - -fun isSponsoredUser(userId: Long): Boolean { - return userId in sponsorIdsRef.get() -} diff --git a/data/src/main/java/org/monogram/data/mapper/StickersMapper.kt b/data/src/main/java/org/monogram/data/mapper/StickersMapper.kt deleted file mode 100644 index 5ff71c4e..00000000 --- a/data/src/main/java/org/monogram/data/mapper/StickersMapper.kt +++ /dev/null @@ -1,56 +0,0 @@ -package org.monogram.data.mapper - -import org.drinkless.tdlib.TdApi -import org.monogram.domain.models.StickerFormat -import org.monogram.domain.models.StickerModel -import org.monogram.domain.models.StickerSetModel -import org.monogram.domain.models.StickerType - -fun TdApi.Sticker.toDomain(): StickerModel = StickerModel( - id = sticker.id.toLong(), - customEmojiId = (fullType as? TdApi.StickerFullTypeCustomEmoji)?.customEmojiId, - width = width, - height = height, - emoji = emoji, - path = sticker.local.path.ifEmpty { null }, - format = format.toDomain() -) - -fun TdApi.StickerSet.toDomain(): StickerSetModel = StickerSetModel( - id = id, - title = title, - name = name, - stickers = stickers.map { it.toDomain() }, - thumbnail = thumbnail?.let { thumb -> - StickerModel( - id = thumb.file.id.toLong(), - width = thumb.width, - height = thumb.height, - emoji = "", - path = thumb.file.local.path.ifEmpty { null }, - format = stickers.firstOrNull()?.format.toDomain() - ) - }, - isInstalled = isInstalled, - isArchived = isArchived, - isOfficial = isOfficial, - stickerType = when (stickerType) { - is TdApi.StickerTypeRegular -> StickerType.REGULAR - is TdApi.StickerTypeMask -> StickerType.MASK - is TdApi.StickerTypeCustomEmoji -> StickerType.CUSTOM_EMOJI - else -> StickerType.REGULAR - } -) - -fun TdApi.StickerFormat?.toDomain(): StickerFormat = when (this) { - is TdApi.StickerFormatWebp -> StickerFormat.STATIC - is TdApi.StickerFormatTgs -> StickerFormat.ANIMATED - is TdApi.StickerFormatWebm -> StickerFormat.VIDEO - else -> StickerFormat.UNKNOWN -} - -fun StickerType.toApi(): TdApi.StickerType = when (this) { - StickerType.REGULAR -> TdApi.StickerTypeRegular() - StickerType.MASK -> TdApi.StickerTypeMask() - StickerType.CUSTOM_EMOJI -> TdApi.StickerTypeCustomEmoji() -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/mapper/StorageMapper.kt b/data/src/main/java/org/monogram/data/mapper/StorageMapper.kt deleted file mode 100644 index 47cecab6..00000000 --- a/data/src/main/java/org/monogram/data/mapper/StorageMapper.kt +++ /dev/null @@ -1,62 +0,0 @@ -package org.monogram.data.mapper - -import org.drinkless.tdlib.TdApi -import org.monogram.domain.models.ChatStorageUsageModel -import org.monogram.domain.models.FileTypeStorageUsageModel -import org.monogram.domain.models.StorageUsageModel -import org.monogram.domain.repository.StringProvider - -class StorageMapper(private val stringProvider: StringProvider) { - fun mapToDomain(_statistics: TdApi.StorageStatistics, chatStats: List): StorageUsageModel { - val filteredChats = chatStats.filter { it.size > 0L } - return StorageUsageModel( - totalSize = filteredChats.sumOf { it.size }, - fileCount = filteredChats.sumOf { it.fileCount }, - chatStats = filteredChats - ) - } - - fun mapChatStatsToDomain(stats: TdApi.StorageStatisticsByChat, chatTitle: String): ChatStorageUsageModel { - val removableStats = stats.byFileType.filterNot { isNonRemovableFileType(it.fileType) } - val mappedFileTypes = removableStats.map { mapFileTypeStatsToDomain(it) } - return ChatStorageUsageModel( - chatId = stats.chatId, - chatTitle = chatTitle, - size = mappedFileTypes.sumOf { it.size }, - fileCount = mappedFileTypes.sumOf { it.fileCount }, - byFileType = mappedFileTypes - ) - } - - fun mapFileTypeStatsToDomain(stats: TdApi.StorageStatisticsByFileType): FileTypeStorageUsageModel { - return FileTypeStorageUsageModel( - fileType = mapFileTypeToDomain(stats.fileType), - size = stats.size, - fileCount = stats.count - ) - } - - private fun isNonRemovableFileType(fileType: TdApi.FileType): Boolean { - return when (fileType) { - is TdApi.FileTypeSticker, - is TdApi.FileTypeThumbnail, - is TdApi.FileTypeProfilePhoto, - is TdApi.FileTypeWallpaper -> true - - else -> false - } - } - - fun mapFileTypeToDomain(fileType: TdApi.FileType): String { - return when (fileType) { - is TdApi.FileTypePhoto -> stringProvider.getString("storage_photos") - is TdApi.FileTypeVideo -> stringProvider.getString("storage_videos") - is TdApi.FileTypeDocument -> stringProvider.getString("storage_documents") - is TdApi.FileTypeSticker -> stringProvider.getString("storage_stickers") - is TdApi.FileTypeAudio -> stringProvider.getString("storage_music") - is TdApi.FileTypeVoiceNote -> stringProvider.getString("storage_voice_messages") - is TdApi.FileTypeVideoNote -> stringProvider.getString("storage_video_messages") - else -> stringProvider.getString("storage_other_files") - } - } -} diff --git a/data/src/main/java/org/monogram/data/mapper/ThemeMapper.kt b/data/src/main/java/org/monogram/data/mapper/ThemeMapper.kt deleted file mode 100644 index e0757ff2..00000000 --- a/data/src/main/java/org/monogram/data/mapper/ThemeMapper.kt +++ /dev/null @@ -1,30 +0,0 @@ -package org.monogram.data.mapper - -import androidx.core.graphics.toColorInt -import org.drinkless.tdlib.TdApi -import org.monogram.domain.models.webapp.ThemeParams - -fun ThemeParams.toApi(): TdApi.ThemeParameters { - return TdApi.ThemeParameters( - fromHex(backgroundColor), - fromHex(secondaryBackgroundColor), - fromHex(headerBackgroundColor), - fromHex(bottomBarBackgroundColor), - fromHex(sectionBackgroundColor), - fromHex(sectionSeparatorColor), - fromHex(textColor), - fromHex(accentTextColor), - fromHex(sectionHeaderTextColor), - fromHex(subtitleTextColor), - fromHex(destructiveTextColor), - fromHex(hintColor), - fromHex(linkColor), - fromHex(buttonColor), - fromHex(buttonTextColor) - ) -} - -private fun fromHex(hex: String?): Int { - if (hex.isNullOrBlank()) return 0 - return hex.toColorInt() -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/mapper/UpdateMapper.kt b/data/src/main/java/org/monogram/data/mapper/UpdateMapper.kt deleted file mode 100644 index 906d43db..00000000 --- a/data/src/main/java/org/monogram/data/mapper/UpdateMapper.kt +++ /dev/null @@ -1,83 +0,0 @@ -package org.monogram.data.mapper - -import org.drinkless.tdlib.TdApi -import org.monogram.domain.models.MessageEntity -import org.monogram.domain.models.MessageEntityType -import org.monogram.domain.models.RichText -import org.monogram.domain.models.UpdateInfo - -fun TdApi.FormattedText.toChangelog(): List { - val text = this.text - val markerIndex = text.indexOf("Changelog:", ignoreCase = true) - .takeIf { it != -1 } ?: return emptyList() - - val changelogText = text.substring(markerIndex + "Changelog:".length).trimStart() - val actualStart = text.indexOf(changelogText, markerIndex + "Changelog:".length) - var currentOffset = actualStart - - return changelogText.lines().mapNotNull { line -> - val trimmed = line.trim() - val lineStart = text.indexOf(line, currentOffset) - val trimmedStart = lineStart + line.indexOf(trimmed) - currentOffset = lineStart + line.length - - if (trimmed.isEmpty()) return@mapNotNull null - - val numberingMatch = Regex("""^\d+\.\s*""").find(trimmed) - val (finalText, finalStart) = if (numberingMatch != null) { - trimmed.substring(numberingMatch.value.length) to (trimmedStart + numberingMatch.value.length) - } else { - trimmed to trimmedStart - } - - val entities = this.entities?.mapNotNull { entity -> - val overlapStart = maxOf(entity.offset, finalStart) - val overlapEnd = minOf(entity.offset + entity.length, finalStart + finalText.length) - if (overlapStart >= overlapEnd) return@mapNotNull null - entity.toDomain()?.copy( - offset = overlapStart - finalStart, - length = overlapEnd - overlapStart - ) - } ?: emptyList() - - RichText(finalText, entities) - } -} - -fun TdApi.TextEntity.toDomain(): MessageEntity? { - val type = when (val t = this.type) { - is TdApi.TextEntityTypeBold -> MessageEntityType.Bold - is TdApi.TextEntityTypeItalic -> MessageEntityType.Italic - is TdApi.TextEntityTypeUnderline -> MessageEntityType.Underline - is TdApi.TextEntityTypeStrikethrough -> MessageEntityType.Strikethrough - is TdApi.TextEntityTypeSpoiler -> MessageEntityType.Spoiler - is TdApi.TextEntityTypeCode -> MessageEntityType.Code - is TdApi.TextEntityTypePre -> MessageEntityType.Pre() - is TdApi.TextEntityTypeTextUrl -> MessageEntityType.TextUrl(t.url) - is TdApi.TextEntityTypeMention -> MessageEntityType.Mention - is TdApi.TextEntityTypeMentionName -> MessageEntityType.TextMention(t.userId) - is TdApi.TextEntityTypeHashtag -> MessageEntityType.Hashtag - is TdApi.TextEntityTypeBotCommand -> MessageEntityType.BotCommand - is TdApi.TextEntityTypeUrl -> MessageEntityType.Url - is TdApi.TextEntityTypeEmailAddress -> MessageEntityType.Email - is TdApi.TextEntityTypePhoneNumber -> MessageEntityType.PhoneNumber - is TdApi.TextEntityTypeBankCardNumber -> MessageEntityType.BankCardNumber - is TdApi.TextEntityTypeCustomEmoji -> MessageEntityType.CustomEmoji(t.customEmojiId) - else -> return null - } - return MessageEntity(this.offset, this.length, type) -} - -fun TdApi.MessageDocument.toUpdateInfo(): UpdateInfo? { - val text = this.caption.text - val match = Regex("""(\d+\.\d+\.\d+)\s*\((\d+)\)""").find(text) ?: return null - return UpdateInfo( - version = match.groupValues[1], - versionCode = match.groupValues[2].toInt(), - description = text, - changelog = this.caption.toChangelog(), - fileId = this.document.document.id, - fileName = this.document.fileName, - fileSize = this.document.document.size - ) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/mapper/VerifiedOverrides.kt b/data/src/main/java/org/monogram/data/mapper/VerifiedOverrides.kt deleted file mode 100644 index 29f7f49d..00000000 --- a/data/src/main/java/org/monogram/data/mapper/VerifiedOverrides.kt +++ /dev/null @@ -1,20 +0,0 @@ -package org.monogram.data.mapper - -private val VERIFIED_CHAT_IDS = setOf( - -1003615282448L, - -1003768707135L, - -1003566234286L, - -1001270834900L, - -1001336987857L -) - -private val VERIFIED_USER_IDS = setOf( - 453024846L, - 665275967L, - 1250144551L, - 454755463L -) - -fun isForcedVerifiedChat(chatId: Long): Boolean = chatId in VERIFIED_CHAT_IDS - -fun isForcedVerifiedUser(userId: Long): Boolean = userId in VERIFIED_USER_IDS diff --git a/data/src/main/java/org/monogram/data/mapper/WallpaperMapper.kt b/data/src/main/java/org/monogram/data/mapper/WallpaperMapper.kt deleted file mode 100644 index d4bfee65..00000000 --- a/data/src/main/java/org/monogram/data/mapper/WallpaperMapper.kt +++ /dev/null @@ -1,94 +0,0 @@ -package org.monogram.data.mapper - -import org.drinkless.tdlib.TdApi -import org.monogram.domain.models.ThumbnailModel -import org.monogram.domain.models.WallpaperModel -import org.monogram.domain.models.WallpaperSettings - -fun mapBackgrounds(backgrounds: Array): List { - val defaultWallpapers = listOf( - WallpaperModel( - id = -1, - slug = "default_blue", - title = "Default Blue", - pattern = false, - documentId = 0, - thumbnail = null, - settings = WallpaperSettings( - backgroundColor = 0x1E3557, - secondBackgroundColor = 0x2D4A77, - thirdBackgroundColor = null, - fourthBackgroundColor = null, - intensity = null, - rotation = 45, - isInverted = null - ), - isDownloaded = true, - localPath = null, - isDefault = true - ) - ) - return defaultWallpapers + backgrounds.map { it.toDomain() } -} - -fun TdApi.Background.toDomain(): WallpaperModel { - val doc = this.document - val file = doc?.document - return WallpaperModel( - id = this.id, - slug = this.name, - title = this.name, - pattern = this.type is TdApi.BackgroundTypePattern, - documentId = doc?.document?.id?.toLong() ?: 0L, - thumbnail = doc?.thumbnail?.toDomain(), - settings = this.type.toWallpaperSettings(), - isDownloaded = file?.local?.isDownloadingCompleted == true, - localPath = file?.local?.path?.ifEmpty { null }, - isDefault = this.isDefault - ) -} - -fun TdApi.Thumbnail.toDomain(): ThumbnailModel = ThumbnailModel( - fileId = this.file.id, - width = this.width, - height = this.height, - localPath = this.file.local.path -) - -fun TdApi.BackgroundType.toWallpaperSettings(): WallpaperSettings? = when (this) { - is TdApi.BackgroundTypePattern -> fill.toWallpaperSettings() - ?.copy(intensity = intensity, isInverted = isInverted) - is TdApi.BackgroundTypeFill -> fill.toWallpaperSettings() - else -> null -} - -fun TdApi.BackgroundFill.toWallpaperSettings(): WallpaperSettings? = when (this) { - is TdApi.BackgroundFillSolid -> WallpaperSettings( - backgroundColor = color, - secondBackgroundColor = null, - thirdBackgroundColor = null, - fourthBackgroundColor = null, - intensity = null, - rotation = null, - isInverted = null - ) - is TdApi.BackgroundFillGradient -> WallpaperSettings( - backgroundColor = topColor, - secondBackgroundColor = bottomColor, - thirdBackgroundColor = null, - fourthBackgroundColor = null, - intensity = null, - rotation = rotationAngle, - isInverted = null - ) - is TdApi.BackgroundFillFreeformGradient -> WallpaperSettings( - backgroundColor = colors.getOrNull(0), - secondBackgroundColor = colors.getOrNull(1), - thirdBackgroundColor = colors.getOrNull(2), - fourthBackgroundColor = colors.getOrNull(3), - intensity = null, - rotation = null, - isInverted = null - ) - else -> null -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/mapper/user/PremiumMapper.kt b/data/src/main/java/org/monogram/data/mapper/user/PremiumMapper.kt deleted file mode 100644 index 6a02a256..00000000 --- a/data/src/main/java/org/monogram/data/mapper/user/PremiumMapper.kt +++ /dev/null @@ -1,56 +0,0 @@ -package org.monogram.data.mapper.user - -import org.drinkless.tdlib.TdApi -import org.monogram.domain.models.PremiumFeatureType -import org.monogram.domain.models.PremiumLimitType -import org.monogram.domain.models.PremiumPaymentOptionModel -import org.monogram.domain.models.PremiumSource -import org.monogram.domain.models.PremiumStateModel - -fun TdApi.PremiumState.toDomain() : PremiumStateModel = - PremiumStateModel( - state = this.state.text, - animations = this.animations.map { it.feature.toDomain() }, - paymentOptions = this.paymentOptions.map { option -> - PremiumPaymentOptionModel( - currency = option.paymentOption.currency, - amount = option.paymentOption.amount, - monthCount = option.paymentOption.monthCount, - storeProductId = option.paymentOption.storeProductId, - paymentLink = option.paymentOption.paymentLink?.toString() - ) - } - ) - -fun TdApi.PremiumFeature.toDomain() : PremiumFeatureType = when (this) { - is TdApi.PremiumFeatureIncreasedLimits -> PremiumFeatureType.DOUBLE_LIMITS - is TdApi.PremiumFeatureVoiceRecognition -> PremiumFeatureType.VOICE_TO_TEXT - is TdApi.PremiumFeatureImprovedDownloadSpeed -> PremiumFeatureType.FASTER_DOWNLOAD - is TdApi.PremiumFeatureRealTimeChatTranslation -> PremiumFeatureType.TRANSLATION - is TdApi.PremiumFeatureCustomEmoji -> PremiumFeatureType.ANIMATED_EMOJI - is TdApi.PremiumFeatureAdvancedChatManagement -> PremiumFeatureType.ADVANCED_CHAT_MANAGEMENT - is TdApi.PremiumFeatureDisabledAds -> PremiumFeatureType.NO_ADS - is TdApi.PremiumFeatureUniqueReactions -> PremiumFeatureType.INFINITE_REACTIONS - is TdApi.PremiumFeatureAppIcons -> PremiumFeatureType.APP_ICONS - is TdApi.PremiumFeatureEmojiStatus -> PremiumFeatureType.PROFILE_BADGE - else -> PremiumFeatureType.UNKNOWN -} - -fun PremiumSource.toApi(): TdApi.PremiumSource? = when (this) { - PremiumSource.SETTINGS -> TdApi.PremiumSourceSettings() - PremiumSource.LIMIT_EXCEEDED -> TdApi.PremiumSourceLimitExceeded() - PremiumSource.STORY_STATUS -> TdApi.PremiumSourceStoryFeature() - PremiumSource.LINK -> TdApi.PremiumSourceLink() - else -> null -} - -fun PremiumLimitType.toApi(): TdApi.PremiumLimitType? = when (this) { - PremiumLimitType.SUPERGROUP_COUNT -> TdApi.PremiumLimitTypeSupergroupCount() - PremiumLimitType.CHAT_FOLDER_COUNT -> TdApi.PremiumLimitTypeChatFolderCount() - PremiumLimitType.PINNED_CHAT_COUNT -> TdApi.PremiumLimitTypePinnedChatCount() - PremiumLimitType.CREATED_PUBLIC_CHAT_COUNT -> TdApi.PremiumLimitTypeCreatedPublicChatCount() - PremiumLimitType.CHAT_FOLDER_INVITE_LINK_COUNT -> TdApi.PremiumLimitTypeChatFolderInviteLinkCount() - PremiumLimitType.SHAREABLE_CHAT_FOLDER_COUNT -> TdApi.PremiumLimitTypeShareableChatFolderCount() - PremiumLimitType.ACTIVE_STORY_COUNT -> TdApi.PremiumLimitTypeActiveStoryCount() - else -> null -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/mapper/user/StatisticsMapper.kt b/data/src/main/java/org/monogram/data/mapper/user/StatisticsMapper.kt deleted file mode 100644 index 42a8b6ad..00000000 --- a/data/src/main/java/org/monogram/data/mapper/user/StatisticsMapper.kt +++ /dev/null @@ -1,111 +0,0 @@ -package org.monogram.data.mapper.user - -import org.drinkless.tdlib.TdApi -import org.monogram.domain.models.* - -fun TdApi.ChatStatistics.toDomain(): ChatStatisticsModel = when (this) { - is TdApi.ChatStatisticsSupergroup -> ChatStatisticsModel( - type = StatisticsType.SUPERGROUP, - period = DateRangeModel(period.startDate, period.endDate), - memberCount = memberCount.toDomain(), - messageCount = messageCount.toDomain(), - viewerCount = viewerCount.toDomain(), - senderCount = senderCount.toDomain(), - topSenders = topSenders.map { - TopSenderModel(it.userId, it.sentMessageCount, it.averageCharacterCount) - }, - topAdministrators = topAdministrators.map { - TopAdministratorModel( - it.userId, - it.deletedMessageCount, - it.bannedUserCount, - it.restrictedUserCount - ) - }, - topInviters = topInviters.map { - TopInviterModel(it.userId, it.addedMemberCount) - }, - memberCountGraph = memberCountGraph.toDomain(), - joinGraph = joinGraph.toDomain(), - muteGraph = joinBySourceGraph.toDomain(), - joinBySourceGraph = joinBySourceGraph.toDomain(), - languageGraph = languageGraph.toDomain(), - messageContentGraph = messageContentGraph.toDomain(), - actionGraph = actionGraph.toDomain(), - dayGraph = dayGraph.toDomain(), - weekGraph = weekGraph.toDomain() - ) - is TdApi.ChatStatisticsChannel -> ChatStatisticsModel( - type = StatisticsType.CHANNEL, - period = DateRangeModel(period.startDate, period.endDate), - memberCount = memberCount.toDomain(), - meanViewCount = meanMessageViewCount.toDomain(), - meanShareCount = meanMessageShareCount.toDomain(), - meanReactionCount = meanMessageReactionCount.toDomain(), - meanStoryViewCount = meanStoryViewCount.toDomain(), - meanStoryShareCount = meanStoryShareCount.toDomain(), - meanStoryReactionCount = meanStoryReactionCount.toDomain(), - enabledNotificationsPercentage = enabledNotificationsPercentage, - memberCountGraph = memberCountGraph.toDomain(), - joinGraph = joinGraph.toDomain(), - muteGraph = muteGraph.toDomain(), - viewCountByHourGraph = viewCountByHourGraph.toDomain(), - viewCountBySourceGraph = viewCountBySourceGraph.toDomain(), - joinBySourceGraph = joinBySourceGraph.toDomain(), - languageGraph = languageGraph.toDomain(), - messageContentGraph = messageInteractionGraph.toDomain(), - actionGraph = instantViewInteractionGraph.toDomain(), - messageReactionGraph = messageReactionGraph.toDomain(), - storyInteractionGraph = storyInteractionGraph.toDomain(), - storyReactionGraph = storyReactionGraph.toDomain(), - recentInteractions = recentInteractions.map { it.toDomain() } - ) - else -> ChatStatisticsModel( - type = StatisticsType.SUPERGROUP, - period = DateRangeModel(0, 0), - memberCount = StatisticsValueModel(0.0, 0.0, 0.0) - ) -} - -fun TdApi.ChatRevenueStatistics.toDomain(): ChatRevenueStatisticsModel { - return ChatRevenueStatisticsModel( - revenueByHourGraph = revenueByHourGraph.toDomain(), - revenueGraph = revenueGraph.toDomain(), - revenueAmount = RevenueAmountModel( - revenueAmount.cryptocurrency, - revenueAmount.balanceAmount, - revenueAmount.availableAmount - ), - usdRate = usdRate - ) -} - -fun TdApi.StatisticalGraph.toDomain(): StatisticsGraphModel = when (this) { - is TdApi.StatisticalGraphData -> StatisticsGraphModel.Data(jsonData, zoomToken) - is TdApi.StatisticalGraphAsync -> StatisticsGraphModel.Async(token) - is TdApi.StatisticalGraphError -> StatisticsGraphModel.Error(errorMessage) - else -> StatisticsGraphModel.Error("Unknown graph type") -} - -private fun TdApi.StatisticalValue.toDomain(): StatisticsValueModel = - StatisticsValueModel(value, previousValue, growthRatePercentage) - -private fun TdApi.ChatStatisticsInteractionInfo.toDomain(): ChatInteractionInfoModel { - val objectId = when (val type = objectType) { - is TdApi.ChatStatisticsObjectTypeMessage -> type.messageId - is TdApi.ChatStatisticsObjectTypeStory -> type.storyId.toLong() - else -> 0L - } - val interactionType = when (objectType) { - is TdApi.ChatStatisticsObjectTypeMessage -> ChatInteractionType.MESSAGE - is TdApi.ChatStatisticsObjectTypeStory -> ChatInteractionType.STORY - else -> ChatInteractionType.MESSAGE - } - return ChatInteractionInfoModel( - objectId = objectId, - type = interactionType, - viewCount = viewCount, - forwardCount = forwardCount, - reactionCount = reactionCount - ) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/mapper/user/UserMapper.kt b/data/src/main/java/org/monogram/data/mapper/user/UserMapper.kt deleted file mode 100644 index 652e2d39..00000000 --- a/data/src/main/java/org/monogram/data/mapper/user/UserMapper.kt +++ /dev/null @@ -1,688 +0,0 @@ -package org.monogram.data.mapper.user - -import org.drinkless.tdlib.TdApi -import org.monogram.data.db.model.ChatEntity -import org.monogram.data.db.model.ChatFullInfoEntity -import org.monogram.data.db.model.UserEntity -import org.monogram.data.db.model.UserFullInfoEntity -import org.monogram.data.mapper.isForcedVerifiedUser -import org.monogram.data.mapper.isSponsoredUser -import org.monogram.domain.models.* -import org.monogram.domain.repository.ChatMemberStatus -import org.monogram.domain.repository.ChatMembersFilter - -fun TdApi.User.toDomain( - fullInfo: TdApi.UserFullInfo? = null, - customEmojiPath: String? = null -): UserModel { - val emojiStatusId = this.getEmojiStatusId() - val username = usernames?.activeUsernames?.firstOrNull() - - val personalAvatarPath = fullInfo?.personalPhoto?.let { personalPhoto -> - val bestPhotoSize = personalPhoto.sizes.maxByOrNull { it.width.toLong() * it.height.toLong() } - ?: personalPhoto.sizes.lastOrNull() - personalPhoto.animation?.file?.local?.path?.ifEmpty { null } - ?: bestPhotoSize?.photo?.local?.path?.ifEmpty { null } - } - - val lastSeen = (status as? TdApi.UserStatusOffline) - ?.wasOnline?.toLong()?.times(1000L) ?: 0L - - return UserModel( - id = id, - firstName = firstName, - lastName = lastName.ifEmpty { null }, - phoneNumber = phoneNumber.ifEmpty { null }, - avatarPath = this.resolveAvatarPath(), - personalAvatarPath = personalAvatarPath, - isPremium = isPremium, - isVerified = (verificationStatus?.isVerified ?: false) || isForcedVerifiedUser(id), - isSponsor = isSponsoredUser(id), - isSupport = isSupport, - type = type.toDomain(), - statusEmojiId = emojiStatusId, - statusEmojiPath = customEmojiPath, - username = username, - usernames = usernames?.let { usernames!!.toDomain() }, - userStatus = if (type is TdApi.UserTypeBot) UserStatusType.OFFLINE - else status.toDomain(), - isContact = isContact, - isMutualContact = isMutualContact, - isCloseFriend = isCloseFriend, - haveAccess = haveAccess, - languageCode = languageCode, - lastSeen = lastSeen - ) -} - -fun TdApi.ChatMember.toDomain(user: UserModel): GroupMemberModel { - val rank = when (this.status) { - is TdApi.ChatMemberStatusCreator -> "Owner" - is TdApi.ChatMemberStatusAdministrator -> "Admin" - else -> null - } - return GroupMemberModel( - user = user, - rank = rank, - status = this.status.toDomain() - ) -} - -fun TdApi.UserFullInfo.mapUserFullInfoToChat(): ChatFullInfoModel { - val birthdate = birthdate?.let { date -> - BirthdateModel(date.day, date.month, if (date.year > 0) date.year else null) - } - return ChatFullInfoModel( - description = bio?.text?.ifEmpty { null }, - commonGroupsCount = groupInCommonCount, - giftCount = giftCount, - birthdate = birthdate, - isBlocked = blockList != null, - botInfo = botInfo?.description?.ifEmpty { null }, - canGetRevenueStatistics = botInfo?.canGetRevenueStatistics ?: false, - linkedChatId = personalChatId, - businessInfo = businessInfo?.let { businessInfo!!.toDomain() }, - canBeCalled = canBeCalled, - supportsVideoCalls = supportsVideoCalls, - hasPrivateCalls = hasPrivateCalls, - hasPrivateForwards = hasPrivateForwards, - hasRestrictedVoiceAndVideoNoteMessages = hasRestrictedVoiceAndVideoNoteMessages, - hasPostedToProfileStories = hasPostedToProfileStories, - setChatBackground = setChatBackground - ) -} - -fun TdApi.SupergroupFullInfo.mapSupergroupFullInfoToChat( - supergroup: TdApi.Supergroup? -): ChatFullInfoModel { - val link = inviteLink?.inviteLink - ?: supergroup?.usernames?.activeUsernames?.firstOrNull()?.let { "t.me/$it" } - return ChatFullInfoModel( - description = description.ifEmpty { null }, - inviteLink = link, - memberCount = memberCount, - administratorCount = administratorCount, - restrictedCount = restrictedCount, - bannedCount = bannedCount, - slowModeDelay = slowModeDelay, - locationAddress = location?.address?.ifEmpty { null }, - giftCount = giftCount, - canSetStickerSet = canSetStickerSet, - canSetLocation = canSetLocation, - canGetMembers = canGetMembers, - canGetStatistics = canGetStatistics, - canGetRevenueStatistics = canGetRevenueStatistics, - linkedChatId = linkedChatId - ) -} - -fun TdApi.BasicGroupFullInfo.mapBasicGroupFullInfoToChat(): ChatFullInfoModel { - return ChatFullInfoModel( - description = description.ifEmpty { null }, - inviteLink = inviteLink?.inviteLink, - memberCount = members.size - ) -} - -fun TdApi.ChatMemberStatus.toDomain(): ChatMemberStatus { - return when (this) { - is TdApi.ChatMemberStatusCreator -> ChatMemberStatus.Creator - is TdApi.ChatMemberStatusAdministrator -> ChatMemberStatus.Administrator( - customTitle = "", - canBeEdited = canBeEdited, - canManageChat = rights.canManageChat, - canChangeInfo = rights.canChangeInfo, - canPostMessages = rights.canPostMessages, - canEditMessages = rights.canEditMessages, - canDeleteMessages = rights.canDeleteMessages, - canInviteUsers = rights.canInviteUsers, - canRestrictMembers = rights.canRestrictMembers, - canPinMessages = rights.canPinMessages, - canManageTopics = rights.canManageTopics, - canPromoteMembers = rights.canPromoteMembers, - canManageVideoChats = rights.canManageVideoChats, - canPostStories = rights.canPostStories, - canEditStories = rights.canEditStories, - canDeleteStories = rights.canDeleteStories, - canManageDirectMessages = rights.canManageDirectMessages, - isAnonymous = rights.isAnonymous - ) - is TdApi.ChatMemberStatusRestricted -> ChatMemberStatus.Restricted( - isMember = isMember, - restrictedUntilDate = restrictedUntilDate, - permissions = permissions.toDomain() - ) - is TdApi.ChatMemberStatusBanned -> ChatMemberStatus.Banned(bannedUntilDate) - is TdApi.ChatMemberStatusLeft -> ChatMemberStatus.Left - else -> ChatMemberStatus.Member - } -} - -fun TdApi.Chat.toDomain(): ChatModel { - val isChannel = type is TdApi.ChatTypeSupergroup && - (type as TdApi.ChatTypeSupergroup).isChannel - return ChatModel( - id = id, - title = title, - avatarPath = photo?.small?.local?.path?.ifEmpty { null }, - unreadCount = unreadCount, - isMuted = notificationSettings.muteFor > 0, - isChannel = isChannel, - isGroup = type is TdApi.ChatTypeBasicGroup || - (type is TdApi.ChatTypeSupergroup && !isChannel), - type = type.toDomain(), - lastMessageText = (lastMessage?.content as? TdApi.MessageText)?.text?.text ?: "" - ) -} - -fun ChatMembersFilter.toApi(): TdApi.SupergroupMembersFilter { - return when (this) { - is ChatMembersFilter.Recent -> TdApi.SupergroupMembersFilterRecent() - is ChatMembersFilter.Administrators -> TdApi.SupergroupMembersFilterAdministrators() - is ChatMembersFilter.Banned -> TdApi.SupergroupMembersFilterBanned() - is ChatMembersFilter.Restricted -> TdApi.SupergroupMembersFilterRestricted() - is ChatMembersFilter.Bots -> TdApi.SupergroupMembersFilterBots() - is ChatMembersFilter.Search -> TdApi.SupergroupMembersFilterSearch(this.query) - } -} - -fun ChatMemberStatus.toApi(): TdApi.ChatMemberStatus { - return when (this) { - is ChatMemberStatus.Member -> TdApi.ChatMemberStatusMember() - is ChatMemberStatus.Administrator -> TdApi.ChatMemberStatusAdministrator( - canBeEdited, - TdApi.ChatAdministratorRights( - canManageChat, - canChangeInfo, - canPostMessages, - canEditMessages, - canDeleteMessages, - canInviteUsers, - canRestrictMembers, - canPinMessages, - canManageTopics, - canPromoteMembers, - canManageVideoChats, - canPostStories, - canEditStories, - canDeleteStories, - canManageDirectMessages, - false, - isAnonymous - ) - ) - is ChatMemberStatus.Restricted -> TdApi.ChatMemberStatusRestricted( - isMember, - restrictedUntilDate, - permissions.toApi() - ) - is ChatMemberStatus.Left -> TdApi.ChatMemberStatusLeft() - is ChatMemberStatus.Banned -> TdApi.ChatMemberStatusBanned(bannedUntilDate) - is ChatMemberStatus.Creator -> TdApi.ChatMemberStatusCreator(false, true) - } -} - -private fun TdApi.ChatType.toDomain(): ChatType = when (this) { - is TdApi.ChatTypePrivate -> ChatType.PRIVATE - is TdApi.ChatTypeBasicGroup -> ChatType.BASIC_GROUP - is TdApi.ChatTypeSupergroup -> ChatType.SUPERGROUP - is TdApi.ChatTypeSecret -> ChatType.SECRET - else -> ChatType.PRIVATE -} - -private fun TdApi.User.resolveAvatarPath(): String? { - val big = profilePhoto?.big?.local?.path?.ifEmpty { null } - val small = profilePhoto?.small?.local?.path?.ifEmpty { null } - return big ?: small -} - -private fun TdApi.User.getEmojiStatusId(): Long { - return when (val type = emojiStatus?.type) { - is TdApi.EmojiStatusTypeCustomEmoji -> type.customEmojiId - is TdApi.EmojiStatusTypeUpgradedGift -> type.modelCustomEmojiId - else -> 0L - } -} - -private fun TdApi.Usernames.toDomain(): UsernamesModel { - return UsernamesModel( - activeUsernames = activeUsernames.toList(), - disabledUsernames = disabledUsernames.toList(), - collectibleUsernames = collectibleUsernames.toList() - ) -} - -private fun TdApi.UserType?.toDomain(): UserTypeEnum { - return when (this) { - is TdApi.UserTypeRegular -> UserTypeEnum.REGULAR - is TdApi.UserTypeBot -> UserTypeEnum.BOT - is TdApi.UserTypeDeleted -> UserTypeEnum.DELETED - else -> UserTypeEnum.UNKNOWN - } -} - -private fun TdApi.UserStatus?.toDomain(): UserStatusType { - return when (this) { - is TdApi.UserStatusOnline -> UserStatusType.ONLINE - is TdApi.UserStatusRecently -> UserStatusType.RECENTLY - is TdApi.UserStatusLastWeek -> UserStatusType.LAST_WEEK - is TdApi.UserStatusLastMonth -> UserStatusType.LAST_MONTH - else -> UserStatusType.OFFLINE - } -} - -private fun TdApi.BusinessInfo.toDomain(): BusinessInfoModel { - return BusinessInfoModel( - location = location?.let { - BusinessLocationModel( - it.location!!.latitude, - it.location!!.longitude, - it.address - ) - }, - openingHours = openingHours?.let { - BusinessOpeningHoursModel( - it.timeZoneId, - it.openingHours.map { interval -> - BusinessOpeningHoursIntervalModel(interval.startMinute, interval.endMinute) - } - ) - }, - startPage = startPage?.let { - BusinessStartPageModel(it.title, it.message, it.sticker?.sticker?.local?.path) - }, - nextOpenIn = nextOpenIn, - nextCloseIn = nextCloseIn - ) -} - -private fun TdApi.ChatPermissions.toDomain(): ChatPermissionsModel { - return ChatPermissionsModel( - canSendBasicMessages = canSendBasicMessages, - canSendAudios = canSendAudios, - canSendDocuments = canSendDocuments, - canSendPhotos = canSendPhotos, - canSendVideos = canSendVideos, - canSendVideoNotes = canSendVideoNotes, - canSendVoiceNotes = canSendVoiceNotes, - canSendPolls = canSendPolls, - canSendOtherMessages = canSendOtherMessages, - canAddLinkPreviews = canAddLinkPreviews, - canChangeInfo = canChangeInfo, - canInviteUsers = canInviteUsers, - canPinMessages = canPinMessages, - canCreateTopics = canCreateTopics - ) -} - -private fun ChatPermissionsModel.toApi(): TdApi.ChatPermissions { - return TdApi.ChatPermissions( - canSendBasicMessages, - canSendAudios, - canSendDocuments, - canSendPhotos, - canSendVideos, - canSendVideoNotes, - canSendVoiceNotes, - canSendPolls, - canSendOtherMessages, - canAddLinkPreviews, - canEditTag, - canChangeInfo, - canInviteUsers, - canPinMessages, - canCreateTopics - ) -} - -fun TdApi.UserFullInfo.toEntity(userId: Long): UserFullInfoEntity { - val businessLocation = businessInfo?.location - val businessOpeningHours = businessInfo?.openingHours - val businessStartPage = businessInfo?.startPage - val birth = birthdate - val personalPhotoPath = personalPhoto?.animation?.file?.local?.path?.ifEmpty { null } - ?: (personalPhoto?.sizes?.maxByOrNull { it.width.toLong() * it.height.toLong() } - ?: personalPhoto?.sizes?.lastOrNull())?.photo?.local?.path?.ifEmpty { null } - - return UserFullInfoEntity( - userId = userId, - bio = bio?.text?.ifEmpty { null }, - commonGroupsCount = groupInCommonCount, - giftCount = giftCount, - botInfoDescription = botInfo?.description?.ifEmpty { null }, - personalChatId = personalChatId, - birthdateDay = birth?.day ?: 0, - birthdateMonth = birth?.month ?: 0, - birthdateYear = birth?.year ?: 0, - businessLocationAddress = businessLocation?.address?.ifEmpty { null }, - businessLocationLatitude = businessLocation?.location?.latitude ?: 0.0, - businessLocationLongitude = businessLocation?.location?.longitude ?: 0.0, - businessOpeningHoursTimeZone = businessOpeningHours?.timeZoneId, - businessNextOpenIn = businessInfo?.nextOpenIn ?: 0, - businessNextCloseIn = businessInfo?.nextCloseIn ?: 0, - businessStartPageTitle = businessStartPage?.title?.ifEmpty { null }, - businessStartPageMessage = businessStartPage?.message?.ifEmpty { null }, - personalPhotoPath = personalPhotoPath, - isBlocked = blockList != null, - canBeCalled = canBeCalled, - supportsVideoCalls = supportsVideoCalls, - hasPrivateCalls = hasPrivateCalls, - hasPrivateForwards = hasPrivateForwards, - hasRestrictedVoiceAndVideoNoteMessages = hasRestrictedVoiceAndVideoNoteMessages, - hasPostedToProfileStories = hasPostedToProfileStories, - setChatBackground = setChatBackground, - canGetRevenueStatistics = botInfo?.canGetRevenueStatistics ?: false, - createdAt = System.currentTimeMillis() - ) -} - -fun TdApi.SupergroupFullInfo.toEntity(chatId: Long): ChatFullInfoEntity { - return ChatFullInfoEntity( - chatId = chatId, - description = description.ifEmpty { null }, - inviteLink = inviteLink?.inviteLink, - memberCount = memberCount, - onlineCount = 0, - administratorCount = administratorCount, - restrictedCount = restrictedCount, - bannedCount = bannedCount, - commonGroupsCount = 0, - giftCount = giftCount, - isBlocked = false, - botInfo = null, - slowModeDelay = slowModeDelay, - locationAddress = location?.address?.ifEmpty { null }, - canSetStickerSet = canSetStickerSet, - canSetLocation = canSetLocation, - canGetMembers = canGetMembers, - canGetStatistics = canGetStatistics, - canGetRevenueStatistics = canGetRevenueStatistics, - linkedChatId = linkedChatId, - note = null, - canBeCalled = false, - supportsVideoCalls = false, - hasPrivateCalls = false, - hasPrivateForwards = false, - hasRestrictedVoiceAndVideoNoteMessages = false, - hasPostedToProfileStories = false, - setChatBackground = false, - incomingPaidMessageStarCount = 0, - outgoingPaidMessageStarCount = outgoingPaidMessageStarCount, - createdAt = System.currentTimeMillis() - ) -} - -fun TdApi.BasicGroupFullInfo.toEntity(chatId: Long): ChatFullInfoEntity { - return ChatFullInfoEntity( - chatId = chatId, - description = description.ifEmpty { null }, - inviteLink = inviteLink?.inviteLink, - memberCount = members.size, - onlineCount = 0, - administratorCount = 0, - restrictedCount = 0, - bannedCount = 0, - commonGroupsCount = 0, - giftCount = 0, - isBlocked = false, - botInfo = null, - slowModeDelay = 0, - locationAddress = null, - canSetStickerSet = false, - canSetLocation = false, - canGetMembers = false, - canGetStatistics = false, - canGetRevenueStatistics = false, - linkedChatId = 0, - note = null, - canBeCalled = false, - supportsVideoCalls = false, - hasPrivateCalls = false, - hasPrivateForwards = false, - hasRestrictedVoiceAndVideoNoteMessages = false, - hasPostedToProfileStories = false, - setChatBackground = false, - incomingPaidMessageStarCount = 0, - outgoingPaidMessageStarCount = 0, - createdAt = System.currentTimeMillis() - ) -} - -fun UserEntity.toTdApi(): TdApi.User { - return TdApi.User().apply { - id = this@toTdApi.id - firstName = this@toTdApi.firstName - lastName = this@toTdApi.lastName ?: "" - phoneNumber = this@toTdApi.phoneNumber ?: "" - isPremium = this@toTdApi.isPremium - isSupport = this@toTdApi.isSupport - isContact = this@toTdApi.isContact - isMutualContact = this@toTdApi.isMutualContact - isCloseFriend = this@toTdApi.isCloseFriend - haveAccess = this@toTdApi.haveAccess - languageCode = this@toTdApi.languageCode ?: "" - accentColorId = this@toTdApi.accentColorId - profileAccentColorId = this@toTdApi.profileAccentColorId - verificationStatus = if (isVerified) TdApi.VerificationStatus(true, false, false, 0L) else null - val (active, disabled, editable, collectible) = decodeUsernames( - this@toTdApi.usernamesData, - this@toTdApi.username - ) - usernames = TdApi.Usernames(active, disabled, editable, collectible) - emojiStatus = this@toTdApi.statusEmojiId.takeIf { it != 0L }?.let { - TdApi.EmojiStatus(TdApi.EmojiStatusTypeCustomEmoji(it), 0) - } - status = when (this@toTdApi.statusType) { - "ONLINE" -> TdApi.UserStatusOnline(0) - "RECENTLY" -> TdApi.UserStatusRecently() - "LAST_WEEK" -> TdApi.UserStatusLastWeek() - "LAST_MONTH" -> TdApi.UserStatusLastMonth() - else -> TdApi.UserStatusOffline(lastSeen.toInt()) - } - profilePhoto = avatarPath?.let { path -> - TdApi.ProfilePhoto().apply { - small = TdApi.File().apply { local = TdApi.LocalFile().apply { this.path = path } } - } - } - } -} - -fun UserFullInfoEntity.toTdApi(): TdApi.UserFullInfo { - return TdApi.UserFullInfo().apply { - bio = this@toTdApi.bio?.let { TdApi.FormattedText(it, emptyArray()) } - groupInCommonCount = commonGroupsCount - giftCount = this@toTdApi.giftCount - personalChatId = this@toTdApi.personalChatId - birthdate = if (birthdateDay > 0 && birthdateMonth > 0) { - TdApi.Birthdate(birthdateDay, birthdateMonth, birthdateYear) - } else { - null - } - botInfo = botInfoDescription?.let { text -> - TdApi.BotInfo().apply { - description = text - canGetRevenueStatistics = canGetRevenueStatistics - } - } - businessInfo = if ( - businessLocationAddress != null || - businessOpeningHoursTimeZone != null || - businessStartPageTitle != null || - businessStartPageMessage != null - ) { - TdApi.BusinessInfo().apply { - location = businessLocationAddress?.let { address -> - TdApi.BusinessLocation( - TdApi.Location(businessLocationLatitude, businessLocationLongitude, 0.0), - address - ) - } - openingHours = businessOpeningHoursTimeZone?.let { tz -> - TdApi.BusinessOpeningHours(tz, emptyArray()) - } - startPage = if (businessStartPageTitle != null || businessStartPageMessage != null) { - TdApi.BusinessStartPage( - businessStartPageTitle.orEmpty(), - businessStartPageMessage.orEmpty(), - null - ) - } else { - null - } - nextOpenIn = businessNextOpenIn - nextCloseIn = businessNextCloseIn - } - } else { - null - } - personalPhoto = personalPhotoPath?.let { path -> - TdApi.ChatPhoto().apply { - sizes = arrayOf( - TdApi.PhotoSize().apply { - type = "x" - width = 0 - height = 0 - photo = TdApi.File().apply { local = TdApi.LocalFile().apply { this.path = path } } - } - ) - } - } - blockList = if (isBlocked) TdApi.BlockListMain() else null - canBeCalled = this@toTdApi.canBeCalled - supportsVideoCalls = this@toTdApi.supportsVideoCalls - hasPrivateCalls = this@toTdApi.hasPrivateCalls - hasPrivateForwards = this@toTdApi.hasPrivateForwards - hasRestrictedVoiceAndVideoNoteMessages = this@toTdApi.hasRestrictedVoiceAndVideoNoteMessages - hasPostedToProfileStories = this@toTdApi.hasPostedToProfileStories - setChatBackground = this@toTdApi.setChatBackground - incomingPaidMessageStarCount = this@toTdApi.incomingPaidMessageStarCount - outgoingPaidMessageStarCount = this@toTdApi.outgoingPaidMessageStarCount - } -} - -private fun decodeUsernames(data: String?, fallbackUsername: String?): QuadUsernames { - if (data.isNullOrEmpty()) { - val active = fallbackUsername?.takeIf { it.isNotBlank() }?.let { arrayOf(it) } ?: emptyArray() - return QuadUsernames(active, emptyArray(), fallbackUsername.orEmpty(), emptyArray()) - } - val parts = data.split("\n", limit = 4) - val active = parts.getOrNull(0).orEmpty().split('|').filter { it.isNotBlank() }.toTypedArray() - val disabled = parts.getOrNull(1).orEmpty().split('|').filter { it.isNotBlank() }.toTypedArray() - val editable = parts.getOrNull(2).orEmpty() - val collectible = parts.getOrNull(3).orEmpty().split('|').filter { it.isNotBlank() }.toTypedArray() - return QuadUsernames(active, disabled, editable, collectible) -} - -private data class QuadUsernames( - val active: Array, - val disabled: Array, - val editable: String, - val collectible: Array -) - -fun ChatEntity.toTdApiChat(): TdApi.Chat { - return TdApi.Chat().apply { - id = this@toTdApiChat.id - title = this@toTdApiChat.title - unreadCount = this@toTdApiChat.unreadCount - unreadMentionCount = this@toTdApiChat.unreadMentionCount - unreadReactionCount = this@toTdApiChat.unreadReactionCount - photo = avatarPath?.let { path -> - TdApi.ChatPhotoInfo().apply { - small = TdApi.File().apply { local = TdApi.LocalFile().apply { this.path = path } } - } - } - lastMessage = TdApi.Message().apply { - content = TdApi.MessageText().apply { text = TdApi.FormattedText(lastMessageText, emptyArray()) } - date = lastMessageTime.toIntOrNull() ?: 0 - id = this@toTdApiChat.lastMessageId - isOutgoing = this@toTdApiChat.isLastMessageOutgoing - } - positions = arrayOf(TdApi.ChatPosition(TdApi.ChatListMain(), order, isPinned, null)) - notificationSettings = TdApi.ChatNotificationSettings().apply { - muteFor = if (isMuted) Int.MAX_VALUE else 0 - } - type = when (this@toTdApiChat.type) { - "PRIVATE" -> TdApi.ChatTypePrivate().apply { - userId = if (this@toTdApiChat.privateUserId != 0L) this@toTdApiChat.privateUserId else (this@toTdApiChat.messageSenderId ?: 0L) - } - "BASIC_GROUP" -> TdApi.ChatTypeBasicGroup().apply { - basicGroupId = this@toTdApiChat.basicGroupId - } - "SUPERGROUP" -> TdApi.ChatTypeSupergroup(this@toTdApiChat.supergroupId, isChannel) - "SECRET" -> TdApi.ChatTypeSecret().apply { - secretChatId = this@toTdApiChat.secretChatId - } - else -> TdApi.ChatTypePrivate().apply { userId = this@toTdApiChat.privateUserId } - } - isMarkedAsUnread = this@toTdApiChat.isMarkedAsUnread - hasProtectedContent = this@toTdApiChat.hasProtectedContent - isTranslatable = this@toTdApiChat.isTranslatable - viewAsTopics = this@toTdApiChat.viewAsTopics - accentColorId = this@toTdApiChat.accentColorId - profileAccentColorId = this@toTdApiChat.profileAccentColorId - backgroundCustomEmojiId = this@toTdApiChat.backgroundCustomEmojiId - messageAutoDeleteTime = this@toTdApiChat.messageAutoDeleteTime - canBeDeletedOnlyForSelf = this@toTdApiChat.canBeDeletedOnlyForSelf - canBeDeletedForAllUsers = this@toTdApiChat.canBeDeletedForAllUsers - canBeReported = this@toTdApiChat.canBeReported - lastReadInboxMessageId = this@toTdApiChat.lastReadInboxMessageId - lastReadOutboxMessageId = this@toTdApiChat.lastReadOutboxMessageId - replyMarkupMessageId = this@toTdApiChat.replyMarkupMessageId - messageSenderId = this@toTdApiChat.messageSenderId?.let { TdApi.MessageSenderUser(it) } - blockList = if (this@toTdApiChat.blockList) TdApi.BlockListMain() else null - permissions = TdApi.ChatPermissions( - this@toTdApiChat.permissionCanSendBasicMessages, - this@toTdApiChat.permissionCanSendAudios, - this@toTdApiChat.permissionCanSendDocuments, - this@toTdApiChat.permissionCanSendPhotos, - this@toTdApiChat.permissionCanSendVideos, - this@toTdApiChat.permissionCanSendVideoNotes, - this@toTdApiChat.permissionCanSendVoiceNotes, - this@toTdApiChat.permissionCanSendPolls, - this@toTdApiChat.permissionCanSendOtherMessages, - this@toTdApiChat.permissionCanAddLinkPreviews, - this@toTdApiChat.permissionCanEditTag, - this@toTdApiChat.permissionCanChangeInfo, - this@toTdApiChat.permissionCanInviteUsers, - this@toTdApiChat.permissionCanPinMessages, - this@toTdApiChat.permissionCanCreateTopics - ) - clientData = "mc:${this@toTdApiChat.memberCount};oc:${this@toTdApiChat.onlineCount}" - } -} - -fun ChatFullInfoEntity.toDomain(): ChatFullInfoModel { - return ChatFullInfoModel( - description = description, - inviteLink = inviteLink, - memberCount = memberCount, - onlineCount = onlineCount, - administratorCount = administratorCount, - restrictedCount = restrictedCount, - bannedCount = bannedCount, - commonGroupsCount = commonGroupsCount, - giftCount = giftCount, - isBlocked = isBlocked, - botInfo = botInfo, - canGetRevenueStatistics = canGetRevenueStatistics, - linkedChatId = linkedChatId, - businessInfo = null, - note = note, - canBeCalled = canBeCalled, - supportsVideoCalls = supportsVideoCalls, - hasPrivateCalls = hasPrivateCalls, - hasPrivateForwards = hasPrivateForwards, - hasRestrictedVoiceAndVideoNoteMessages = hasRestrictedVoiceAndVideoNoteMessages, - hasPostedToProfileStories = hasPostedToProfileStories, - setChatBackground = setChatBackground, - slowModeDelay = slowModeDelay, - locationAddress = locationAddress, - canSetStickerSet = canSetStickerSet, - canSetLocation = canSetLocation, - canGetMembers = canGetMembers, - canGetStatistics = canGetStatistics, - incomingPaidMessageStarCount = incomingPaidMessageStarCount, - outgoingPaidMessageStarCount = outgoingPaidMessageStarCount - ) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/repository/AuthRepositoryImpl.kt b/data/src/main/java/org/monogram/data/repository/AuthRepositoryImpl.kt deleted file mode 100644 index 0514eeb1..00000000 --- a/data/src/main/java/org/monogram/data/repository/AuthRepositoryImpl.kt +++ /dev/null @@ -1,113 +0,0 @@ -package org.monogram.data.repository - -import org.monogram.data.core.coRunCatching -import android.os.Build -import org.monogram.core.ScopeProvider -import kotlinx.coroutines.flow.* -import kotlinx.coroutines.launch -import org.drinkless.tdlib.TdApi -import org.monogram.data.BuildConfig -import org.monogram.data.datasource.remote.AuthRemoteDataSource -import org.monogram.data.di.TdLibClient -import org.monogram.data.di.TdLibException -import org.monogram.data.gateway.UpdateDispatcher -import org.monogram.data.mapper.toDomain -import org.monogram.domain.repository.AuthRepository -import org.monogram.domain.repository.AuthStep -import java.io.File -import java.util.* - -class AuthRepositoryImpl( - private val remote: AuthRemoteDataSource, - private val updates: UpdateDispatcher, - private val tdLibClient: TdLibClient, - scopeProvider: ScopeProvider -) : AuthRepository { - - private val scope = scopeProvider.appScope - private val context = tdLibClient.getContext() - - private val _authState = MutableStateFlow(AuthStep.Loading) - override val authState = _authState.asStateFlow() - - private val _errors = MutableSharedFlow(extraBufferCapacity = 1) - override val errors = _errors.asSharedFlow() - - init { - scope.launch { - updates.authorizationState.collect { update -> - if (update.authorizationState is TdApi.AuthorizationStateWaitTdlibParameters) { - sendTdLibParameters() - } - val domainState = update.authorizationState.toDomain() - _authState.update { domainState } - } - } - } - - private suspend fun sendTdLibParameters() { - coRunCatching { - val parameters = TdApi.SetTdlibParameters().apply { - databaseDirectory = File(context.filesDir, "td-db").absolutePath - filesDirectory = File(context.filesDir, "td-files").absolutePath - databaseEncryptionKey = byteArrayOf() - apiId = BuildConfig.API_ID - apiHash = BuildConfig.API_HASH - systemLanguageCode = Locale.getDefault().language - deviceModel = "${Build.MANUFACTURER} ${Build.MODEL}" - systemVersion = Build.VERSION.RELEASE - applicationVersion = try { - context.packageManager.getPackageInfo(context.packageName, 0).versionName - } catch (e: Exception) { - "1.0" - } - useMessageDatabase = true - useFileDatabase = true - useChatInfoDatabase = true - } - remote.setTdlibParameters(parameters) - }.onFailure { emitError(it) } - } - - override fun sendPhone(phone: String) { - scope.launch { - coRunCatching { remote.setPhoneNumber(phone) } - .onFailure { emitError(it) } - } - } - - override fun resendCode() { - scope.launch { - coRunCatching { remote.resendCode() } - .onFailure { emitError(it) } - } - } - - override fun sendCode(code: String) { - scope.launch { - val isEmail = (_authState.value as? AuthStep.InputCode)?.isEmailCode == true - coRunCatching { - if (isEmail) remote.checkEmailCode(code) else remote.setAuthCode(code) - }.onFailure { emitError(it) } - } - } - - override fun sendPassword(password: String) { - scope.launch { - coRunCatching { remote.checkPassword(password) } - .onFailure { emitError(it) } - } - } - - override fun reset() { - _authState.update { AuthStep.InputPhone } - } - - private fun emitError(t: Throwable) { - val error = (t as? TdLibException)?.error - val errorMessage = error?.message ?: "" - - val message = errorMessage.ifEmpty { t.message ?: "Unknown error" } - _errors.tryEmit(message) - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/repository/ChatsListRepositoryImpl.kt b/data/src/main/java/org/monogram/data/repository/ChatsListRepositoryImpl.kt deleted file mode 100644 index 0794ba0a..00000000 --- a/data/src/main/java/org/monogram/data/repository/ChatsListRepositoryImpl.kt +++ /dev/null @@ -1,1025 +0,0 @@ -package org.monogram.data.repository - -import android.util.Log -import kotlinx.coroutines.* -import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.flow.* -import org.drinkless.tdlib.TdApi -import org.monogram.core.DispatcherProvider -import org.monogram.core.ScopeProvider -import org.monogram.data.chats.* -import org.monogram.data.core.coRunCatching -import org.monogram.data.datasource.cache.ChatLocalDataSource -import org.monogram.data.datasource.cache.ChatsCacheDataSource -import org.monogram.data.datasource.remote.ChatRemoteSource -import org.monogram.data.datasource.remote.ChatsRemoteDataSource -import org.monogram.data.datasource.remote.ProxyRemoteDataSource -import org.monogram.data.db.dao.ChatFolderDao -import org.monogram.data.db.dao.SearchHistoryDao -import org.monogram.data.db.model.ChatEntity -import org.monogram.data.db.model.SearchHistoryEntity -import org.monogram.data.db.model.TopicEntity -import org.monogram.data.gateway.TelegramGateway -import org.monogram.data.gateway.UpdateDispatcher -import org.monogram.data.infra.ConnectionManager -import org.monogram.data.infra.FileDownloadQueue -import org.monogram.data.mapper.ChatMapper -import org.monogram.data.mapper.MessageMapper -import org.monogram.data.mapper.user.toEntity -import org.monogram.domain.models.ChatModel -import org.monogram.domain.models.ChatPermissionsModel -import org.monogram.domain.models.FolderModel -import org.monogram.domain.models.TopicModel -import org.monogram.domain.repository.* -import java.io.File -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.atomic.AtomicLong - -class ChatsListRepositoryImpl( - private val remoteDataSource: ChatsRemoteDataSource, - private val cacheDataSource: ChatsCacheDataSource, - private val chatRemoteSource: ChatRemoteSource, - private val proxyRemoteSource: ProxyRemoteDataSource, - private val updates: UpdateDispatcher, - private val appPreferences: AppPreferencesProvider, - private val cacheProvider: CacheProvider, - private val dispatchers: DispatcherProvider, - private val cache: ChatCache, - private val chatMapper: ChatMapper, - private val messageMapper: MessageMapper, - private val gateway: TelegramGateway, - scopeProvider: ScopeProvider, - private val chatLocalDataSource: ChatLocalDataSource, - private val connectionManager: ConnectionManager, - private val databaseFile: File, - private val searchHistoryDao: SearchHistoryDao, - private val chatFolderDao: ChatFolderDao, - private val fileQueue: FileDownloadQueue, - private val stringProvider: StringProvider -) : ChatsListRepository { - - private val TAG = "ChatsListRepo" - private val scope = scopeProvider.appScope - - private val fileManager = ChatFileManager( - gateway = gateway, - dispatchers = dispatchers, - scopeProvider = scopeProvider, - fileQueue = fileQueue, - onUpdate = { triggerUpdate(); refreshActiveForumTopics() } - ) - private val typingManager = ChatTypingManager( - scope = scope, - usersCache = cache.usersCache, - allChats = cache.allChats, - stringProvider = stringProvider, - onUpdate = { triggerUpdate() }, - onUserNeeded = { userId -> fetchUser(userId) } - ) - private val listManager = ChatListManager(cache) { chatId -> - if (cache.pendingChats.add(chatId)) { - scope.launch { refreshChat(chatId); cache.pendingChats.remove(chatId) } - } - } - private val modelFactory = ChatModelFactory( - gateway = gateway, - dispatchers = dispatchers, - scopeProvider = scopeProvider, - cache = cache, - chatMapper = chatMapper, - fileManager = fileManager, - typingManager = typingManager, - appPreferences = appPreferences, - triggerUpdate = { chatId -> triggerUpdate(chatId) }, - fetchUser = { userId -> fetchUser(userId) } - ) - - private val _chatListFlow = MutableStateFlow>(emptyList()) - override val chatListFlow = _chatListFlow.asStateFlow() - - private val _folderChatsFlow = MutableSharedFlow( - replay = 1, - extraBufferCapacity = 10, - onBufferOverflow = BufferOverflow.DROP_OLDEST - ) - override val folderChatsFlow: Flow = _folderChatsFlow.asSharedFlow() - - private val _foldersFlow = MutableStateFlow(listOf(FolderModel(-1, ""))) - override val foldersFlow = _foldersFlow.asStateFlow() - - private val _isLoadingFlow = MutableStateFlow(false) - override val isLoadingFlow = _isLoadingFlow.asStateFlow() - - private val _folderLoadingFlow = MutableSharedFlow( - replay = 1, - extraBufferCapacity = 10, - onBufferOverflow = BufferOverflow.DROP_OLDEST - ) - override val folderLoadingFlow: Flow = _folderLoadingFlow.asSharedFlow() - - override val connectionStateFlow = connectionManager.connectionStateFlow - - private val _forumTopicsFlow = MutableSharedFlow>>( - replay = 1, extraBufferCapacity = 10, onBufferOverflow = BufferOverflow.DROP_OLDEST - ) - override val forumTopicsFlow = _forumTopicsFlow.asSharedFlow() - - private val folderManager = ChatFolderManager( - gateway = gateway, - dispatchers = dispatchers, - scopeProvider = scopeProvider, - foldersFlow = _foldersFlow, - cacheProvider = cacheProvider, - chatFolderDao = chatFolderDao - ) - override val isArchivePinned = appPreferences.isArchivePinned - override val isArchiveAlwaysVisible = appPreferences.isArchiveAlwaysVisible - override val searchHistory: Flow> = cacheProvider.searchHistory.map { ids -> - coroutineScope { - ids.map { id -> async { getChatById(id) } }.awaitAll().filterNotNull() - } - } - - private var activeForumChatId: Long? = null - private var myUserId: Long = 0L - - @Volatile - private var activeFolderId: Int = -1 - @Volatile private var activeChatList: TdApi.ChatList = TdApi.ChatListMain() - @Volatile - private var activeRequestId: Long = 0L - private val requestIdGenerator = AtomicLong(0L) - private val cacheHydrated = CompletableDeferred() - private val updateChannel = Channel(Channel.CONFLATED) - private var pendingSelectFolderJob: Job? = null - private val maxChatListLimit = 10_000 - private var currentLimit = 50 - - private val lastSavedEntities = ConcurrentHashMap() - private val pendingSaveJobs = ConcurrentHashMap() - private val modelCache = ConcurrentHashMap() - private val invalidatedModels = ConcurrentHashMap.newKeySet() - private var lastList: List? = null - private var lastListFolderId: Int = -1 - - private val mainChatList = TdApi.ChatListMain() - - init { - scope.launch(dispatchers.io) { - myUserId = chatRemoteSource.getMyUserId() - } - - scope.launch(dispatchers.io) { - coRunCatching { - val entities = chatLocalDataSource.getAllChats().first() - if (entities.isNotEmpty()) { - entities.forEach { entity -> - cache.putChatFromEntity(entity) - lastSavedEntities[entity.id] = entity - } - updateActiveListPositionsFromCache() - triggerUpdate() - } - }.onFailure { e -> - Log.e(TAG, "Failed to hydrate chat cache", e) - } - - if (!cacheHydrated.isCompleted) { - cacheHydrated.complete(Unit) - } - } - - scope.launch(dispatchers.io) { - for (u in updateChannel) { - rebuildAndEmit() - delay(250) - } - } - - scope.launch { - updates.chatsListUpdates.collect { update -> handleUpdate(update) } - } - - scope.launch { - updates.chatFolders.collect { update -> - Log.d(TAG, "UpdateChatFolders received via dedicated flow") - folderManager.handleChatFoldersUpdate(update) - triggerUpdate() - } - } - - scope.launch { - searchHistoryDao.getSearchHistory().collect { entities -> - cacheProvider.setSearchHistory(entities.map { it.chatId }) - } - } - } - - private suspend fun rebuildAndEmit() { - coRunCatching { - activeRequestId - val folderIdAtStart = activeFolderId - val limitAtStart = maxOf(currentLimit, cache.activeListPositions.size) - .coerceAtMost(maxChatListLimit) - - val newList = listManager.rebuildChatList(limitAtStart, emptyList()) { chat, order, isPinned -> - val cached = modelCache[chat.id] - if (cached != null && cached.order == order && cached.isPinned == isPinned && !invalidatedModels.contains( - chat.id - ) - ) { - cached - } else { - modelFactory.mapChatToModel(chat, order, isPinned).also { - modelCache[chat.id] = it - invalidatedModels.remove(chat.id) - } - } - } - - if (folderIdAtStart != activeFolderId) { - return@coRunCatching - } - - val folderChanged = folderIdAtStart != lastListFolderId - if (folderChanged || newList != lastList) { - val pinnedInPositions = cache.activeListPositions.entries - .asSequence() - .filter { it.value.isPinned } - .map { it.key } - .toSet() - val pinnedInList = newList.asSequence().filter { it.isPinned }.map { it.id }.toSet() - if (pinnedInPositions.size != pinnedInList.size) { - Log.w( - "PinnedDiag", - "emit mismatch folder=$folderIdAtStart pinnedPositions=${pinnedInPositions.size} pinnedList=${pinnedInList.size} missingInList=${ - (pinnedInPositions - pinnedInList).take( - 10 - ) - }" - ) - } - _chatListFlow.value = newList - _folderChatsFlow.tryEmit(FolderChatsUpdate(folderIdAtStart, newList)) - lastList = newList - lastListFolderId = folderIdAtStart - - val toSave = newList.map { model -> - val chat = cache.getChat(model.id) - if (chat != null) { - val persistPosition = resolvePersistPosition(chat) - val mapped = chatMapper.mapToEntity(chat, model) - if (persistPosition != null && - (persistPosition.order != mapped.order || persistPosition.isPinned != mapped.isPinned) - ) { - mapped.copy(order = persistPosition.order, isPinned = persistPosition.isPinned) - } else { - mapped - } - } - else chatMapper.mapToEntity(model) - } - .filter { entity -> - val last = lastSavedEntities[entity.id] - if (last == null || isEntityChanged(last, entity)) { - lastSavedEntities[entity.id] = entity - true - } else { - false - } - } - - if (toSave.isNotEmpty()) { - chatLocalDataSource.insertChats(toSave) - } - } - }.onFailure { e -> - Log.e(TAG, "Error rebuilding chat list", e) - } - } - - private fun handleUpdate(update: TdApi.Update) { - when (update) { - is TdApi.UpdateNewChat -> { - cache.putChat(update.chat) - listManager.updateActiveListPositions(update.chat.id, update.chat.positions, activeChatList) - saveChatToDb(update.chat.id) - triggerUpdate(update.chat.id) - } - is TdApi.UpdateChatTitle -> { - cache.updateChat(update.chatId) { it.title = update.title } - saveChatToDb(update.chatId) - triggerUpdate(update.chatId) - } - is TdApi.UpdateChatPhoto -> { - cache.updateChat(update.chatId) { it.photo = update.photo } - saveChatToDb(update.chatId) - triggerUpdate(update.chatId) - } - is TdApi.UpdateChatEmojiStatus -> { - cache.updateChat(update.chatId) { it.emojiStatus = update.emojiStatus } - saveChatToDb(update.chatId) - triggerUpdate(update.chatId) - } - is TdApi.UpdateChatDraftMessage -> { - cache.updateChat(update.chatId) { chat -> - chat.draftMessage = update.draftMessage - if (!update.positions.isNullOrEmpty()) { - chat.positions = update.positions - listManager.updateActiveListPositions(update.chatId, update.positions, activeChatList) - } - } - saveChatToDb(update.chatId) - triggerUpdate(update.chatId) - } - is TdApi.UpdateChatPosition -> { - if (listManager.updateChatPositionInCache(update.chatId, update.position, activeChatList)) { - saveChatToDb(update.chatId) - triggerUpdate(update.chatId) - } - } - is TdApi.UpdateChatLastMessage -> { - cache.updateChat(update.chatId) { chat -> - chat.lastMessage = update.lastMessage - if (!update.positions.isNullOrEmpty()) { - chat.positions = update.positions - listManager.updateActiveListPositions(update.chatId, update.positions, activeChatList) - } - typingManager.clearTypingStatus(update.chatId) - } - saveChatToDb(update.chatId) - triggerUpdate(update.chatId) - } - is TdApi.UpdateChatReadInbox -> { - cache.updateChat(update.chatId) { it.unreadCount = update.unreadCount } - saveChatToDb(update.chatId) - triggerUpdate(update.chatId) - } - is TdApi.UpdateChatReadOutbox -> { - cache.updateChat(update.chatId) { it.lastReadOutboxMessageId = update.lastReadOutboxMessageId } - saveChatToDb(update.chatId) - triggerUpdate(update.chatId) - } - is TdApi.UpdateChatUnreadMentionCount -> { - cache.updateChat(update.chatId) { it.unreadMentionCount = update.unreadMentionCount } - folderManager.handleUpdateChatUnreadCount(update.chatId, update.unreadMentionCount) - saveChatToDb(update.chatId) - triggerUpdate(update.chatId) - } - is TdApi.UpdateChatUnreadReactionCount -> { - cache.updateChat(update.chatId) { it.unreadReactionCount = update.unreadReactionCount } - saveChatToDb(update.chatId) - triggerUpdate(update.chatId) - } - is TdApi.UpdateMessageMentionRead -> { - cache.updateChat(update.chatId) { it.unreadMentionCount = update.unreadMentionCount } - folderManager.handleUpdateChatUnreadCount(update.chatId, update.unreadMentionCount) - saveChatToDb(update.chatId) - triggerUpdate(update.chatId) - } - is TdApi.UpdateMessageReactions -> { - saveChatToDb(update.chatId) - triggerUpdate(update.chatId) - } - is TdApi.UpdateFile -> { - if (fileManager.handleFileUpdate(update.file)) { - val chatId = fileManager.getChatIdByPhotoId(update.file.id) - triggerUpdate(chatId) - refreshActiveForumTopics() - } - } - is TdApi.UpdateDeleteMessages -> { - if (update.isPermanent || update.fromCache) { - scope.launch { refreshChat(update.chatId) } - } - } - is TdApi.UpdateChatFolders -> { - Log.d(TAG, "UpdateChatFolders received in handleUpdate") - folderManager.handleChatFoldersUpdate(update) - triggerUpdate() - } - is TdApi.UpdateUserStatus -> { - cache.updateUser(update.userId) { it.status = update.status } - triggerUpdate() - } - is TdApi.UpdateUser -> { - cache.putUser(update.user) - if (update.user.id == myUserId) myUserId = update.user.id - triggerUpdate() - refreshActiveForumTopics() - } - is TdApi.UpdateSupergroup -> { - cache.putSupergroup(update.supergroup) - saveChatsBySupergroupId(update.supergroup.id) - triggerUpdate() - } - is TdApi.UpdateBasicGroup -> { - cache.putBasicGroup(update.basicGroup) - saveChatsByBasicGroupId(update.basicGroup.id) - triggerUpdate() - } - is TdApi.UpdateSupergroupFullInfo -> { - cache.putSupergroupFullInfo(update.supergroupId, update.supergroupFullInfo) - scope.launch(dispatchers.io) { - val chatId = - cache.allChats.values.find { (it.type as? TdApi.ChatTypeSupergroup)?.supergroupId == update.supergroupId }?.id - if (chatId != null) { - chatLocalDataSource.insertChatFullInfo(update.supergroupFullInfo.toEntity(chatId)) - } - } - triggerUpdate() - } - is TdApi.UpdateBasicGroupFullInfo -> { - cache.putBasicGroupFullInfo(update.basicGroupId, update.basicGroupFullInfo) - scope.launch(dispatchers.io) { - val chatId = - cache.allChats.values.find { (it.type as? TdApi.ChatTypeBasicGroup)?.basicGroupId == update.basicGroupId }?.id - if (chatId != null) { - chatLocalDataSource.insertChatFullInfo(update.basicGroupFullInfo.toEntity(chatId)) - } - } - triggerUpdate() - } - is TdApi.UpdateSecretChat -> { - cache.putSecretChat(update.secretChat); triggerUpdate() - } - is TdApi.UpdateChatAction -> typingManager.handleChatAction(update) - is TdApi.UpdateChatNotificationSettings -> { - cache.updateChat(update.chatId) { it.notificationSettings = update.notificationSettings } - saveChatToDb(update.chatId) - triggerUpdate(update.chatId) - } - is TdApi.UpdateChatViewAsTopics -> { - cache.updateChat(update.chatId) { it.viewAsTopics = update.viewAsTopics } - saveChatToDb(update.chatId) - triggerUpdate(update.chatId) - } - is TdApi.UpdateChatIsTranslatable -> { - cache.updateChat(update.chatId) { it.isTranslatable = update.isTranslatable } - saveChatToDb(update.chatId) - triggerUpdate(update.chatId) - } - is TdApi.UpdateChatPermissions -> { - cache.putChatPermissions(update.chatId, update.permissions) - cache.updateChat(update.chatId) { it.permissions = update.permissions } - saveChatToDb(update.chatId) - triggerUpdate(update.chatId) - } - is TdApi.UpdateChatMember -> { - val memberId = update.newChatMember.memberId - if (memberId is TdApi.MessageSenderUser && memberId.userId == myUserId) { - cache.putMyChatMember(update.chatId, update.newChatMember) - triggerUpdate(update.chatId) - } - } - is TdApi.UpdateChatOnlineMemberCount -> { - cache.putOnlineMemberCount(update.chatId, update.onlineMemberCount) - saveChatToDb(update.chatId) - triggerUpdate(update.chatId) - } - is TdApi.UpdateAuthorizationState -> { - Log.d(TAG, "UpdateAuthorizationState: ${update.authorizationState}") - if (update.authorizationState is TdApi.AuthorizationStateLoggingOut || - update.authorizationState is TdApi.AuthorizationStateClosed - ) { - cache.clearAll() - modelCache.clear() - invalidatedModels.clear() - lastSavedEntities.clear() - scope.launch { chatLocalDataSource.clearAll() } - } - } - else -> {} - } - } - - private fun saveChatToDb(chatId: Long) { - val chat = cache.getChat(chatId) ?: return - - pendingSaveJobs[chatId]?.cancel() - pendingSaveJobs[chatId] = scope.launch(dispatchers.io) { - delay(2000) - val position = resolvePersistPosition(chat) - - val model = modelFactory.mapChatToModel(chat, position?.order ?: 0L, position?.isPinned ?: false) - val entity = chatMapper.mapToEntity(chat, model) - - val last = lastSavedEntities[chatId] - if (last == null || isEntityChanged(last, entity)) { - chatLocalDataSource.insertChat(entity) - lastSavedEntities[chatId] = entity - } - pendingSaveJobs.remove(chatId) - } - } - - private fun isEntityChanged(old: ChatEntity, new: ChatEntity): Boolean { - return old.title != new.title || - old.unreadCount != new.unreadCount || - old.unreadMentionCount != new.unreadMentionCount || - old.unreadReactionCount != new.unreadReactionCount || - old.avatarPath != new.avatarPath || - old.lastMessageText != new.lastMessageText || - old.lastMessageTime != new.lastMessageTime || - old.lastMessageDate != new.lastMessageDate || - old.order != new.order || - old.isPinned != new.isPinned || - old.isMuted != new.isMuted || - old.isChannel != new.isChannel || - old.isGroup != new.isGroup || - old.type != new.type || - old.privateUserId != new.privateUserId || - old.basicGroupId != new.basicGroupId || - old.supergroupId != new.supergroupId || - old.secretChatId != new.secretChatId || - old.positionsCache != new.positionsCache || - old.isArchived != new.isArchived || - old.memberCount != new.memberCount || - old.onlineCount != new.onlineCount || - old.isMarkedAsUnread != new.isMarkedAsUnread || - old.hasProtectedContent != new.hasProtectedContent || - old.isTranslatable != new.isTranslatable || - old.hasAutomaticTranslation != new.hasAutomaticTranslation || - old.messageAutoDeleteTime != new.messageAutoDeleteTime || - old.canBeDeletedOnlyForSelf != new.canBeDeletedOnlyForSelf || - old.canBeDeletedForAllUsers != new.canBeDeletedForAllUsers || - old.canBeReported != new.canBeReported || - old.lastReadInboxMessageId != new.lastReadInboxMessageId || - old.lastReadOutboxMessageId != new.lastReadOutboxMessageId || - old.lastMessageId != new.lastMessageId || - old.isLastMessageOutgoing != new.isLastMessageOutgoing || - old.replyMarkupMessageId != new.replyMarkupMessageId || - old.messageSenderId != new.messageSenderId || - old.blockList != new.blockList || - old.emojiStatusId != new.emojiStatusId || - old.accentColorId != new.accentColorId || - old.profileAccentColorId != new.profileAccentColorId || - old.backgroundCustomEmojiId != new.backgroundCustomEmojiId || - old.photoId != new.photoId || - old.isSupergroup != new.isSupergroup || - old.isAdmin != new.isAdmin || - old.isOnline != new.isOnline || - old.typingAction != new.typingAction || - old.draftMessage != new.draftMessage || - old.isVerified != new.isVerified || - old.isSponsor != new.isSponsor || - old.viewAsTopics != new.viewAsTopics || - old.isForum != new.isForum || - old.isBot != new.isBot || - old.isMember != new.isMember || - old.username != new.username || - old.description != new.description || - old.inviteLink != new.inviteLink || - old.permissionCanSendBasicMessages != new.permissionCanSendBasicMessages || - old.permissionCanSendAudios != new.permissionCanSendAudios || - old.permissionCanSendDocuments != new.permissionCanSendDocuments || - old.permissionCanSendPhotos != new.permissionCanSendPhotos || - old.permissionCanSendVideos != new.permissionCanSendVideos || - old.permissionCanSendVideoNotes != new.permissionCanSendVideoNotes || - old.permissionCanSendVoiceNotes != new.permissionCanSendVoiceNotes || - old.permissionCanSendPolls != new.permissionCanSendPolls || - old.permissionCanSendOtherMessages != new.permissionCanSendOtherMessages || - old.permissionCanAddLinkPreviews != new.permissionCanAddLinkPreviews || - old.permissionCanEditTag != new.permissionCanEditTag || - old.permissionCanChangeInfo != new.permissionCanChangeInfo || - old.permissionCanInviteUsers != new.permissionCanInviteUsers || - old.permissionCanPinMessages != new.permissionCanPinMessages || - old.permissionCanCreateTopics != new.permissionCanCreateTopics || - old.lastMessageContentType != new.lastMessageContentType || - old.lastMessageSenderName != new.lastMessageSenderName - } - - private fun resolvePersistPosition(chat: TdApi.Chat): TdApi.ChatPosition? { - return chat.positions.find { pos -> - pos.order != 0L && listManager.isSameChatList(pos.list, mainChatList) - } - ?: chat.positions.find { pos -> - pos.order != 0L && listManager.isSameChatList(pos.list, activeChatList) - } - ?: chat.positions.firstOrNull { it.order != 0L } - } - - private fun triggerUpdate(chatId: Long? = null) { - if (chatId == null) { - invalidatedModels.addAll(cache.activeListPositions.keys) - } else { - invalidatedModels.add(chatId) - } - updateChannel.trySend(Unit) - } - - private fun isRequestActive(folderId: Int, requestId: Long): Boolean { - return activeFolderId == folderId && activeRequestId == requestId - } - - private fun setLoadingState(folderId: Int, requestId: Long, isLoading: Boolean) { - if (!isRequestActive(folderId, requestId)) return - _isLoadingFlow.value = isLoading - _folderLoadingFlow.tryEmit(FolderLoadingUpdate(folderId, isLoading)) - } - - private fun refreshActiveForumTopics() { - val chatId = activeForumChatId ?: return - scope.launch { getForumTopics(chatId) } - } - - override fun retryConnection() { - connectionManager.retryConnection() - } - - override fun selectFolder(folderId: Int) { - if (!cacheHydrated.isCompleted) { - pendingSelectFolderJob?.cancel() - pendingSelectFolderJob = scope.launch(dispatchers.io) { - coRunCatching { cacheHydrated.await() } - .onSuccess { selectFolder(folderId) } - } - return - } - - pendingSelectFolderJob = null - Log.d(TAG, "selectFolder: folderId=$folderId") - val newList: TdApi.ChatList = when (folderId) { - -1 -> TdApi.ChatListMain() - -2 -> TdApi.ChatListArchive() - else -> TdApi.ChatListFolder(folderId) - } - if (folderId == activeFolderId && - listManager.isSameChatList(newList, activeChatList) && - activeRequestId != 0L - ) { - Log.d(TAG, "selectFolder: already initialized for this folder, skipping") - return - } - - activeFolderId = folderId - activeChatList = newList - updateActiveListPositionsFromCache() - val cachedChatsCount = cache.activeListPositions.size - val initialLoadLimit = cachedChatsCount.coerceAtLeast(50).coerceAtMost(maxChatListLimit) - currentLimit = initialLoadLimit - - val requestId = requestIdGenerator.incrementAndGet() - activeRequestId = requestId - Log.d( - TAG, - "selectFolder: cache positions=$cachedChatsCount, initialLoadLimit=$initialLoadLimit" - ) - setLoadingState(folderId, requestId, true) - triggerUpdate() - - scope.launch(dispatchers.io) { - Log.d(TAG, "selectFolder: calling loadChats for $newList with limit=$initialLoadLimit") - chatRemoteSource.loadChats(newList, initialLoadLimit) - val discoveredPositions = cache.activeListPositions.size - val expandedLimit = maxOf(currentLimit, discoveredPositions).coerceAtMost(maxChatListLimit) - if (expandedLimit != currentLimit) { - currentLimit = expandedLimit - } - setLoadingState(folderId, requestId, false) - Log.d(TAG, "selectFolder: loadChats completed") - if (isRequestActive(folderId, requestId)) { - triggerUpdate() - } - } - } - - private fun updateActiveListPositionsFromCache() { - cache.activeListPositions.clear() - cache.authoritativeActiveListChatIds.clear() - cache.protectedPinnedChatIds.clear() - cache.allChats.values.forEach { chat -> - chat.positions.find { listManager.isSameChatList(it.list, activeChatList) }?.let { - if (it.order != 0L) { - cache.activeListPositions[chat.id] = it - if (it.isPinned) { - cache.protectedPinnedChatIds.add(chat.id) - } - } - } - } - } - - override fun refresh() { - if (!cacheHydrated.isCompleted) { - scope.launch(dispatchers.io) { - coRunCatching { cacheHydrated.await() } - .onSuccess { refresh() } - } - return - } - - retryConnection() - updateActiveListPositionsFromCache() - triggerUpdate() - - val folderId = activeFolderId - val requestId = activeRequestId - val chatList = activeChatList - scope.launch(dispatchers.io) { - val limit = currentLimit.coerceAtLeast(50).coerceAtMost(maxChatListLimit) - chatRemoteSource.loadChats(chatList, limit) - if (isRequestActive(folderId, requestId)) { - triggerUpdate() - } - } - } - - override fun loadNextChunk(limit: Int) { - if (!cacheHydrated.isCompleted) return - if (_isLoadingFlow.value || currentLimit >= maxChatListLimit) return - Log.d(TAG, "loadNextChunk: limit=$limit") - - val folderId = activeFolderId - val requestId = activeRequestId - val chatList = activeChatList - currentLimit = (currentLimit + limit).coerceAtMost(maxChatListLimit) - setLoadingState(folderId, requestId, true) - - scope.launch(dispatchers.io) { - if (!isRequestActive(folderId, requestId)) { - return@launch - } - - val currentCount = _chatListFlow.value.size - if (currentCount < currentLimit) { - val totalAvailable = cache.activeListPositions.size - if (totalAvailable > currentCount) { - triggerUpdate() - } - } - - chatRemoteSource.loadChats(chatList, limit) - setLoadingState(folderId, requestId, false) - if (isRequestActive(folderId, requestId)) { - triggerUpdate() - } - } - } - - override suspend fun getChatById(chatId: Long): ChatModel? { - val chatObj = cache.getChat(chatId) - ?: chatLocalDataSource.getChat(chatId)?.let { entity -> - cache.putChatFromEntity(entity) - lastSavedEntities[entity.id] = entity - cache.getChat(chatId) - } - ?: remoteDataSource.getChat(chatId)?.also { - cache.putChat(it) - listManager.updateActiveListPositions(it.id, it.positions, activeChatList) - saveChatToDb(it.id) - } ?: return null - - val position = chatObj.positions.find { listManager.isSameChatList(it.list, activeChatList) } - return coRunCatching { - modelFactory.mapChatToModel(chatObj, position?.order ?: 0L, position?.isPinned ?: false) - }.getOrNull() - } - - override suspend fun searchChats(query: String): List { - if (query.isBlank()) return emptyList() - val result = chatRemoteSource.searchChats(query, 50) ?: return emptyList() - return coroutineScope { - result.chatIds.map { id -> async { getChatById(id) } }.awaitAll().filterNotNull() - } - } - - override suspend fun searchPublicChats(query: String): List { - if (query.isBlank()) return emptyList() - val result = chatRemoteSource.searchPublicChats(query) ?: return emptyList() - return coroutineScope { - result.chatIds.map { id -> async { getChatById(id) } }.awaitAll().filterNotNull() - } - } - - override suspend fun searchMessages(query: String, offset: String, limit: Int): SearchMessagesResult { - val result = chatRemoteSource.searchMessages(query, offset, limit) ?: return SearchMessagesResult(emptyList(), "") - val models = coroutineScope { - result.messages.map { msg -> async { messageMapper.mapMessageToModel(msg, isChatOpen = false) } }.awaitAll() - } - return SearchMessagesResult(models, result.nextOffset) - } - - override fun toggleMuteChats(chatIds: Set, mute: Boolean) { - val muteFor = if (mute) Int.MAX_VALUE else 0 - chatIds.forEach { chatId -> scope.launch(dispatchers.io) { chatRemoteSource.muteChat(chatId, muteFor) } } - } - - override fun toggleArchiveChats(chatIds: Set, archive: Boolean) { - chatIds.forEach { chatId -> scope.launch(dispatchers.io) { chatRemoteSource.archiveChat(chatId, archive) } } - } - - override fun togglePinChats(chatIds: Set, pin: Boolean, folderId: Int) { - val chatList: TdApi.ChatList = when (folderId) { - -1 -> TdApi.ChatListMain() - -2 -> TdApi.ChatListArchive() - else -> TdApi.ChatListFolder(folderId) - } - chatIds.forEach { chatId -> - scope.launch(dispatchers.io) { - chatRemoteSource.toggleChatIsPinned(chatList, chatId, pin) - } - } - } - - override fun toggleReadChats(chatIds: Set, markAsUnread: Boolean) { - chatIds.forEach { chatId -> - scope.launch(dispatchers.io) { - chatRemoteSource.toggleChatIsMarkedAsUnread(chatId, markAsUnread) - } - } - } - - override fun deleteChats(chatIds: Set) { - chatIds.forEach { chatId -> scope.launch(dispatchers.io) { chatRemoteSource.deleteChat(chatId) } } - } - - override fun leaveChat(chatId: Long) { - scope.launch(dispatchers.io) { chatRemoteSource.leaveChat(chatId) } - } - - override fun setArchivePinned(pinned: Boolean) { appPreferences.setArchivePinned(pinned) } - - override suspend fun createFolder(title: String, iconName: String?, includedChatIds: List) = - folderManager.createFolder(title, iconName, includedChatIds) - - override suspend fun deleteFolder(folderId: Int) = chatRemoteSource.deleteFolder(folderId) - - override suspend fun updateFolder(folderId: Int, title: String, iconName: String?, includedChatIds: List) = - folderManager.updateFolder(folderId, title, iconName, includedChatIds) - - override suspend fun reorderFolders(folderIds: List) = folderManager.reorderFolders(folderIds) - - override suspend fun getForumTopics( - chatId: Long, query: String, offsetDate: Int, - offsetMessageId: Long, offsetForumTopicId: Int, limit: Int - ): List { - activeForumChatId = chatId - val result = chatRemoteSource.getForumTopics(chatId, query, offsetDate, offsetMessageId, offsetForumTopicId, limit) - ?: return emptyList() - - val models = result.topics.map { topic -> - val (txt, entities, time) = chatMapper.formatMessageInfo(topic.lastMessage, null) { userId -> - cache.usersCache[userId]?.firstName ?: run { fetchUser(userId); null } - } - val emojiId = topic.info.icon.customEmojiId - var emojiPath: String? = null - if (emojiId != 0L) { - emojiPath = fileManager.getEmojiPath(emojiId) - if (emojiPath == null) fileManager.loadEmoji(emojiId) - } - - var senderName: String? = null - var senderAvatar: String? = null - when (val senderId = topic.lastMessage?.senderId) { - is TdApi.MessageSenderUser -> { - cache.usersCache[senderId.userId]?.let { user -> - senderName = user.firstName - user.profilePhoto?.small?.let { small -> - fileManager.registerTrackedFile(small.id) - senderAvatar = small.local.path.ifEmpty { fileManager.getFilePath(small.id) } - if (senderAvatar.isNullOrEmpty()) fileManager.downloadFile(small.id, 24, synchronous = false) - } - } ?: fetchUser(senderId.userId) - } - is TdApi.MessageSenderChat -> cache.getChat(senderId.chatId)?.let { chat -> - senderName = chat.title - chat.photo?.small?.let { small -> - fileManager.registerTrackedFile(small.id) - senderAvatar = small.local.path.ifEmpty { fileManager.getFilePath(small.id) } - if (senderAvatar.isNullOrEmpty()) fileManager.downloadFile(small.id, 24, synchronous = false) - } - } - else -> {} - } - - TopicModel( - topic.info.forumTopicId, topic.info.name, emojiId, emojiPath, - topic.info.icon.color, topic.info.isClosed, topic.isPinned, - topic.unreadCount, txt, entities, time, topic.order, senderName, senderAvatar - ) - } - - scope.launch(dispatchers.io) { - chatLocalDataSource.insertTopics(result.topics.map { topic -> - val (txt, _, time) = chatMapper.formatMessageInfo(topic.lastMessage, null) { null } - TopicEntity( - chatId = chatId, - id = topic.info.forumTopicId, - name = topic.info.name, - iconCustomEmojiId = topic.info.icon.customEmojiId, - iconColor = topic.info.icon.color, - isClosed = topic.info.isClosed, - isPinned = topic.isPinned, - unreadCount = topic.unreadCount, - lastMessageText = txt, - lastMessageTime = time, - order = topic.order, - lastMessageSenderName = null - ) - }) - } - - _forumTopicsFlow.tryEmit(chatId to models) - return models - } - - override fun clearChatHistory(chatId: Long, revoke: Boolean) { - scope.launch(dispatchers.io) { chatRemoteSource.clearChatHistory(chatId, revoke) } - } - - override suspend fun getChatLink(chatId: Long) = chatRemoteSource.getChatLink(chatId) - - override fun reportChat(chatId: Long, reason: String, messageIds: List) { - scope.launch(dispatchers.io) { chatRemoteSource.reportChat(chatId, reason, messageIds) } - } - - override fun addSearchChatId(chatId: Long) { - cacheProvider.addSearchChatId(chatId) - scope.launch(dispatchers.io) { - searchHistoryDao.insertSearchChatId(SearchHistoryEntity(chatId)) - } - } - - override fun removeSearchChatId(chatId: Long) { - cacheProvider.removeSearchChatId(chatId) - scope.launch(dispatchers.io) { - searchHistoryDao.deleteSearchChatId(chatId) - } - } - - override fun clearSearchHistory() { - cacheProvider.clearSearchHistory() - scope.launch(dispatchers.io) { - searchHistoryDao.clearAll() - } - } - - override suspend fun createGroup(title: String, userIds: List, messageAutoDeleteTime: Int) = - chatRemoteSource.createGroup(title, userIds, messageAutoDeleteTime) - - override suspend fun createChannel(title: String, description: String, isMegagroup: Boolean, messageAutoDeleteTime: Int) = - chatRemoteSource.createChannel(title, description, isMegagroup, messageAutoDeleteTime) - - override suspend fun setChatPhoto(chatId: Long, photoPath: String) = chatRemoteSource.setChatPhoto(chatId, photoPath) - override suspend fun setChatTitle(chatId: Long, title: String) = chatRemoteSource.setChatTitle(chatId, title) - override suspend fun setChatDescription(chatId: Long, description: String) = chatRemoteSource.setChatDescription(chatId, description) - override suspend fun setChatUsername(chatId: Long, username: String) = chatRemoteSource.setChatUsername(chatId, username) - override suspend fun setChatPermissions(chatId: Long, permissions: ChatPermissionsModel) = chatRemoteSource.setChatPermissions(chatId, permissions) - override suspend fun setChatSlowModeDelay(chatId: Long, slowModeDelay: Int) = chatRemoteSource.setChatSlowModeDelay(chatId, slowModeDelay) - override suspend fun toggleChatIsForum(chatId: Long, isForum: Boolean) = chatRemoteSource.toggleChatIsForum(chatId, isForum) - override suspend fun toggleChatIsTranslatable(chatId: Long, isTranslatable: Boolean) = chatRemoteSource.toggleChatIsTranslatable(chatId, isTranslatable) - - override fun getDatabaseSize(): Long { - return if (databaseFile.exists()) databaseFile.length() else 0L - } - - override fun clearDatabase() { - scope.launch(dispatchers.io) { - chatLocalDataSource.clearAll() - lastSavedEntities.clear() - modelCache.clear() - invalidatedModels.clear() - triggerUpdate() - } - } - - private fun fetchUser(userId: Long) { - if (userId == 0L) return - if (cache.pendingUsers.add(userId)) { - scope.launch(dispatchers.io) { - coRunCatching { - val user = gateway.execute(TdApi.GetUser(userId)) - cache.putUser(user) - triggerUpdate() - } - cache.pendingUsers.remove(userId) - } - } - } - - private suspend fun refreshChat(chatId: Long) { - val chatObj = remoteDataSource.getChat(chatId) ?: return - cache.putChat(chatObj) - listManager.updateActiveListPositions(chatObj.id, chatObj.positions, activeChatList) - saveChatToDb(chatObj.id) - triggerUpdate(chatObj.id) - } - - private fun saveChatsBySupergroupId(supergroupId: Long) { - cache.allChats.values - .asSequence() - .filter { (it.type as? TdApi.ChatTypeSupergroup)?.supergroupId == supergroupId } - .map { it.id } - .forEach { saveChatToDb(it) } - } - - private fun saveChatsByBasicGroupId(basicGroupId: Long) { - cache.allChats.values - .asSequence() - .filter { (it.type as? TdApi.ChatTypeBasicGroup)?.basicGroupId == basicGroupId } - .map { it.id } - .forEach { saveChatToDb(it) } - } -} diff --git a/data/src/main/java/org/monogram/data/repository/ExternalProxyRepositoryImpl.kt b/data/src/main/java/org/monogram/data/repository/ExternalProxyRepositoryImpl.kt deleted file mode 100644 index 95ec6f75..00000000 --- a/data/src/main/java/org/monogram/data/repository/ExternalProxyRepositoryImpl.kt +++ /dev/null @@ -1,114 +0,0 @@ -package org.monogram.data.repository - -import org.monogram.data.core.coRunCatching -import org.monogram.domain.models.ProxyModel -import org.monogram.domain.models.ProxyTypeModel -import org.monogram.domain.repository.AppPreferencesProvider -import org.monogram.domain.repository.ExternalProxyRepository -import kotlinx.coroutines.* -import androidx.core.net.toUri -import org.monogram.core.DispatcherProvider -import org.monogram.data.datasource.remote.ExternalProxyDataSource -import org.monogram.data.datasource.remote.ProxyRemoteDataSource - -class ExternalProxyRepositoryImpl( - private val remote: ProxyRemoteDataSource, - private val externalSource: ExternalProxyDataSource, - private val appPreferences: AppPreferencesProvider, - private val dispatchers: DispatcherProvider -) : ExternalProxyRepository { - - override suspend fun fetchExternalProxies(): List = withContext(dispatchers.io) { - if (!appPreferences.isTelegaProxyEnabled.value) return@withContext emptyList() - - val urls = externalSource.fetchProxyUrls().distinct() - if (urls.isEmpty()) return@withContext emptyList() - - val parsed = urls.mapNotNull { url -> - parseProxyUrl(url)?.let { (server, port, secret) -> - Triple(url, server to port, ProxyTypeModel.Mtproto(secret)) - } - } - - val oldIdentifiers = appPreferences.telegaProxyUrls.value - .mapNotNull { parseProxyUrl(it)?.let { (s, p, _) -> "$s:$p" } } - .toSet() - - val newIdentifiers = parsed.map { (_, sp, _) -> "${sp.first}:${sp.second}" }.toSet() - appPreferences.setTelegaProxyUrls(parsed.map { it.first }.toSet()) - - val added = parsed.mapNotNull { (_, sp, type) -> - coRunCatching { remote.addProxy(sp.first, sp.second, false, type) }.getOrNull() - } - - remote.getProxies().forEach { proxy -> - val iden = "${proxy.server}:${proxy.port}" - if (iden in oldIdentifiers && iden !in newIdentifiers && !proxy.isEnabled) { - coRunCatching { remote.removeProxy(proxy.id) } - } - } - - added - } - - override suspend fun getProxies(): List = remote.getProxies() - - override suspend fun addProxy( - server: String, port: Int, enable: Boolean, type: ProxyTypeModel - ): ProxyModel? = coRunCatching { - val proxy = remote.addProxy(server, port, enable, type) - if (enable) appPreferences.setEnabledProxyId(proxy.id) - proxy - }.getOrNull() - - override suspend fun editProxy( - proxyId: Int, server: String, port: Int, enable: Boolean, type: ProxyTypeModel - ): ProxyModel? = coRunCatching { - val proxy = remote.editProxy(proxyId, server, port, enable, type) - if (enable) appPreferences.setEnabledProxyId(proxy.id) - proxy - }.getOrNull() - - override suspend fun enableProxy(proxyId: Int): Boolean = coRunCatching { - remote.enableProxy(proxyId) - appPreferences.setEnabledProxyId(proxyId) - true - }.getOrDefault(false) - - override suspend fun disableProxy(): Boolean = coRunCatching { - remote.disableProxy() - appPreferences.setEnabledProxyId(null) - true - }.getOrDefault(false) - - override suspend fun removeProxy(proxyId: Int): Boolean = coRunCatching { - remote.removeProxy(proxyId) - if (appPreferences.enabledProxyId.value == proxyId) appPreferences.setEnabledProxyId(null) - true - }.getOrDefault(false) - - override suspend fun pingProxy(proxyId: Int): Long? = withTimeoutOrNull(10_000L) { - coRunCatching { - val proxy = remote.getProxies().find { it.id == proxyId } ?: return@withTimeoutOrNull null - remote.pingProxy(proxy.server, proxy.port, proxy.type) - }.getOrNull() - } - - override suspend fun testProxy(server: String, port: Int, type: ProxyTypeModel): Long? = - withTimeoutOrNull(10_000L) { - coRunCatching { remote.testProxy(server, port, type) }.getOrNull() - } - - override fun setPreferIpv6(enabled: Boolean) { - appPreferences.setPreferIpv6(enabled) - } - - private fun parseProxyUrl(url: String): Triple? = - coRunCatching { - val uri = url.toUri() - val server = uri.getQueryParameter("server") ?: return null - val port = uri.getQueryParameter("port")?.toIntOrNull() ?: 443 - val secret = uri.getQueryParameter("secret") ?: "" - Triple(server, port, secret) - }.getOrNull() -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/repository/LinkHandlerRepositoryImpl.kt b/data/src/main/java/org/monogram/data/repository/LinkHandlerRepositoryImpl.kt deleted file mode 100644 index 8a82d342..00000000 --- a/data/src/main/java/org/monogram/data/repository/LinkHandlerRepositoryImpl.kt +++ /dev/null @@ -1,307 +0,0 @@ -package org.monogram.data.repository - -import org.monogram.data.core.coRunCatching -import androidx.core.net.toUri -import org.drinkless.tdlib.TdApi -import org.monogram.data.gateway.TelegramGateway -import org.monogram.data.infra.FileDownloadQueue -import org.monogram.domain.models.ProxyTypeModel -import org.monogram.domain.repository.ChatsListRepository -import org.monogram.domain.repository.LinkAction -import org.monogram.domain.repository.LinkHandlerRepository -import org.monogram.domain.repository.UserRepository - -class LinkHandlerRepositoryImpl( - private val gateway: TelegramGateway, - private val chatsListRepository: ChatsListRepository, - private val userRepository: UserRepository, - private val fileQueue: FileDownloadQueue -) : LinkHandlerRepository { - - override suspend fun handleLink(link: String): LinkAction { - val normalized = normalizeLink(link) - - tryParseProxyLink(normalized)?.let { return it } - tryParseUserLink(normalized)?.let { return it } - - return coRunCatching { - when (val result = gateway.execute(TdApi.GetInternalLinkType(normalized))) { - is TdApi.InternalLinkTypePublicChat -> - handlePublicChat(result.chatUsername) - - is TdApi.InternalLinkTypeMessage -> { - val info = coRunCatching { - gateway.execute(TdApi.GetMessageLinkInfo(result.url)) - }.getOrNull() - when { - info == null || info.chatId == 0L -> LinkAction.ShowToast("Message not found") - info.message != null -> LinkAction.OpenMessage(info.chatId, info.message!!.id) - else -> LinkAction.OpenChat(info.chatId) - } - } - - is TdApi.InternalLinkTypeSettings -> - LinkAction.OpenSettings(result.section.toDomain()) - - is TdApi.InternalLinkTypeStickerSet -> - LinkAction.OpenStickerSet(result.stickerSetName) - - is TdApi.InternalLinkTypeChatInvite -> { - val inviteInfo = coRunCatching { - gateway.execute(TdApi.CheckChatInviteLink(result.inviteLink)) - }.getOrNull() - - if (inviteInfo == null) return LinkAction.JoinChat(result.inviteLink) - - val photo = inviteInfo.photo?.small ?: inviteInfo.photo?.big - if (photo != null && photo.local.path.isEmpty()) { - fileQueue.enqueue(photo.id, 1, FileDownloadQueue.DownloadType.DEFAULT, synchronous = false) - coRunCatching { fileQueue.waitForDownload(photo.id).await() } - } - - LinkAction.ConfirmJoinInviteLink( - inviteLink = result.inviteLink, - title = inviteInfo.title, - description = inviteInfo.description, - memberCount = inviteInfo.memberCount, - avatarPath = photo?.local?.path?.ifEmpty { null }, - isChannel = inviteInfo.type is TdApi.InviteLinkChatTypeChannel - ) - } - - is TdApi.InternalLinkTypeBotStart -> - handlePublicChat(result.botUsername) - - is TdApi.InternalLinkTypeBotStartInGroup -> - handlePublicChat(result.botUsername) - - is TdApi.InternalLinkTypeVideoChat -> - handlePublicChat(result.chatUsername) - - is TdApi.InternalLinkTypeStory -> - handlePublicChat(result.storyPosterUsername) - - is TdApi.InternalLinkTypeStoryAlbum -> - handlePublicChat(result.storyAlbumOwnerUsername) - - is TdApi.InternalLinkTypeMyProfilePage -> - handleMyProfileLink() - - is TdApi.InternalLinkTypeSavedMessages -> - handleSavedMessagesLink() - - is TdApi.InternalLinkTypeUserPhoneNumber -> - handleUserPhoneNumberLink(result.phoneNumber, result.openProfile) - - is TdApi.InternalLinkTypeUserToken -> - handleUserTokenLink(result.token) - - is TdApi.InternalLinkTypePremiumFeaturesPage, - is TdApi.InternalLinkTypePremiumGiftCode, - is TdApi.InternalLinkTypePremiumGiftPurchase, - is TdApi.InternalLinkTypeStarPurchase, - is TdApi.InternalLinkTypeRestorePurchases -> - LinkAction.OpenSettings(LinkAction.SettingsType.PREMIUM) - - is TdApi.InternalLinkTypeWebApp -> - LinkAction.OpenWebApp(0L, result.webAppShortName) - - is TdApi.InternalLinkTypeProxy -> { - val proxy = result.proxy ?: return LinkAction.ShowToast("Unsupported proxy type") - val type = proxy.type.toDomain() - ?: return LinkAction.ShowToast("Unsupported proxy type") - LinkAction.AddProxy(proxy.server, proxy.port, type) - } - - is TdApi.InternalLinkTypeUnknownDeepLink -> - handleExternalOrUnknownLink(result.link) - - else -> handleExternalOrUnknownLink(normalized) - } - }.getOrElse { - handleExternalOrUnknownLink(normalized) - } - } - - override suspend fun joinChat(inviteLink: String): Long? = - coRunCatching { - gateway.execute(TdApi.JoinChatByInviteLink(inviteLink)).id - }.getOrNull() - - private suspend fun handlePublicChat(username: String): LinkAction { - val chat = coRunCatching { - gateway.execute(TdApi.SearchPublicChat(username)) - }.getOrNull() ?: return LinkAction.ShowToast("Chat not found") - return resolveChatAction(chat) - } - - private suspend fun handleMyProfileLink(): LinkAction { - val me = coRunCatching { gateway.execute(TdApi.GetMe()) }.getOrNull() - ?: return LinkAction.ShowToast("User not found") - return LinkAction.OpenUser(me.id) - } - - private suspend fun handleSavedMessagesLink(): LinkAction { - val me = coRunCatching { gateway.execute(TdApi.GetMe()) }.getOrNull() - ?: return LinkAction.ShowToast("Chat not found") - val chat = coRunCatching { - gateway.execute(TdApi.CreatePrivateChat(me.id, false)) - }.getOrNull() ?: return LinkAction.ShowToast("Chat not found") - return LinkAction.OpenChat(chat.id) - } - - private suspend fun handleUserPhoneNumberLink(phoneNumber: String, openProfile: Boolean): LinkAction { - val user = coRunCatching { - gateway.execute(TdApi.SearchUserByPhoneNumber(phoneNumber, true)) - }.getOrNull() ?: return LinkAction.ShowToast("User not found") - - if (openProfile) return LinkAction.OpenUser(user.id) - - val chat = coRunCatching { - gateway.execute(TdApi.CreatePrivateChat(user.id, false)) - }.getOrNull() - return if (chat != null) LinkAction.OpenChat(chat.id) else LinkAction.OpenUser(user.id) - } - - private suspend fun handleUserTokenLink(token: String): LinkAction { - val user = coRunCatching { - gateway.execute(TdApi.SearchUserByToken(token)) - }.getOrNull() ?: return LinkAction.ShowToast("User not found") - - val chat = coRunCatching { - gateway.execute(TdApi.CreatePrivateChat(user.id, false)) - }.getOrNull() - return if (chat != null) LinkAction.OpenChat(chat.id) else LinkAction.OpenUser(user.id) - } - - private suspend fun resolveChatAction(chat: TdApi.Chat): LinkAction { - val needsConfirm = chat.type is TdApi.ChatTypeSupergroup && chat.positions.isEmpty() - if (!needsConfirm) return LinkAction.OpenChat(chat.id) - - val chatModel = chatsListRepository.getChatById(chat.id) - val fullInfo = userRepository.getChatFullInfo(chat.id) - return if (chatModel != null && fullInfo != null) { - LinkAction.ConfirmJoinChat(chatModel, fullInfo) - } else { - LinkAction.OpenChat(chat.id) - } - } - - private suspend fun handleExternalOrUnknownLink(link: String): LinkAction { - val uri = coRunCatching { link.toUri() }.getOrNull() - - if (uri != null && uri.scheme.equals("tg", ignoreCase = true)) { - if (uri.host.equals("resolve", ignoreCase = true)) { - uri.getQueryParameter("user_id")?.toLongOrNull()?.let { return LinkAction.OpenUser(it) } - - uri.getQueryParameter("phone")?.takeIf { it.isNotBlank() }?.let { - return handleUserPhoneNumberLink(it, openProfile = false) - } - - val username = uri.getQueryParameter("domain")?.takeIf { it.isNotBlank() } - if (username != null) { - val hasMessageTarget = uri.getQueryParameter("post") != null || - uri.getQueryParameter("thread") != null || - uri.getQueryParameter("comment") != null - if (!hasMessageTarget) { - return handlePublicChat(username) - } - } - } - - return LinkAction.None - } - - if (uri != null && (uri.scheme.equals("https", ignoreCase = true) || uri.scheme.equals("http", ignoreCase = true))) { - val host = uri.host?.lowercase() - val pathSegments = uri.pathSegments.orEmpty() - - if (host == "t.me" || host == "www.t.me" || host == "telegram.me" || host == "www.telegram.me") { - val first = pathSegments.firstOrNull() - val second = pathSegments.getOrNull(1) - - if (!first.isNullOrBlank()) { - if (first == "joinchat" && !second.isNullOrBlank()) { - return LinkAction.JoinChat("https://t.me/joinchat/$second") - } - - if (first.startsWith("+")) { - return LinkAction.JoinChat("https://t.me/$first") - } - - if (pathSegments.size == 1) { - return handlePublicChat(first) - } - } - } - } - - return if (link.startsWith("http://") || link.startsWith("https://")) LinkAction.OpenExternalLink(link) else LinkAction.None - } - - private fun normalizeLink(link: String): String = when { - link.startsWith("tg://") -> link - link.startsWith("https://t.me/") -> link - link.startsWith("http://t.me/") -> link.replace("http://", "https://") - link.startsWith("t.me/") -> "https://$link" - else -> link - } - - private fun tryParseProxyLink(link: String): LinkAction? { - val uri = coRunCatching { link.toUri() }.getOrNull() ?: return null - - val isProxy = link.contains("/proxy?") || link.startsWith("tg://proxy") - val isSocks = link.contains("/socks?") || link.startsWith("tg://socks") - val isHttp = link.contains("/http?") || link.startsWith("tg://http") - if (!isProxy && !isSocks && !isHttp) return null - - val server = uri.getQueryParameter("server") ?: return null - val port = uri.getQueryParameter("port")?.toIntOrNull() ?: return null - val secret = uri.getQueryParameter("secret") - val user = uri.getQueryParameter("user") - val pass = uri.getQueryParameter("pass") - - val type = when { - secret != null -> ProxyTypeModel.Mtproto(secret) - isHttp -> ProxyTypeModel.Http(user ?: "", pass ?: "", false) - else -> ProxyTypeModel.Socks5(user ?: "", pass ?: "") - } - return LinkAction.AddProxy(server, port, type) - } - - private fun tryParseUserLink(link: String): LinkAction? { - val uri = coRunCatching { link.toUri() }.getOrNull() ?: return null - if (!uri.scheme.equals("tg", ignoreCase = true)) return null - - val userId = when { - uri.host.equals("user", ignoreCase = true) -> - uri.getQueryParameter("id")?.toLongOrNull() - - uri.host.equals("openmessage", ignoreCase = true) -> - uri.getQueryParameter("user_id")?.toLongOrNull() - - else -> null - } ?: return null - - return LinkAction.OpenUser(userId) - } - - private fun TdApi.SettingsSection?.toDomain(): LinkAction.SettingsType = when (this) { - is TdApi.SettingsSectionPrivacyAndSecurity -> LinkAction.SettingsType.PRIVACY - is TdApi.SettingsSectionDevices -> LinkAction.SettingsType.SESSIONS - is TdApi.SettingsSectionChatFolders -> LinkAction.SettingsType.FOLDERS - is TdApi.SettingsSectionAppearance, - is TdApi.SettingsSectionNotifications -> LinkAction.SettingsType.CHAT - is TdApi.SettingsSectionDataAndStorage -> LinkAction.SettingsType.DATA_STORAGE - is TdApi.SettingsSectionPowerSaving -> LinkAction.SettingsType.POWER_SAVING - is TdApi.SettingsSectionPremium -> LinkAction.SettingsType.PREMIUM - else -> LinkAction.SettingsType.MAIN - } - - private fun TdApi.ProxyType?.toDomain(): ProxyTypeModel? = when (this) { - is TdApi.ProxyTypeMtproto -> ProxyTypeModel.Mtproto(secret) - is TdApi.ProxyTypeSocks5 -> ProxyTypeModel.Socks5(username, password) - is TdApi.ProxyTypeHttp -> ProxyTypeModel.Http(username, password, httpOnly) - else -> null - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/repository/LocationRepositoryImpl.kt b/data/src/main/java/org/monogram/data/repository/LocationRepositoryImpl.kt deleted file mode 100644 index a3c2775f..00000000 --- a/data/src/main/java/org/monogram/data/repository/LocationRepositoryImpl.kt +++ /dev/null @@ -1,85 +0,0 @@ -package org.monogram.data.repository - -import android.util.Log -import org.monogram.domain.models.webapp.OSMReverseResponse -import org.monogram.domain.repository.LocationRepository -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import kotlinx.serialization.json.Json -import java.net.HttpURLConnection -import java.net.URL -import java.net.URLEncoder -import java.nio.charset.StandardCharsets - -class LocationRepositoryImpl : LocationRepository { - private val json = Json { - ignoreUnknownKeys = true - coerceInputValues = true - isLenient = true - } - - private val userAgent = "MonoGram-Android-App/1.0" - - override suspend fun reverseGeocode(lat: Double, lon: Double): OSMReverseResponse? { - val url = "https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=$lat&lon=$lon&addressdetails=1" - - return try { - val responseText = makeHttpRequest(url) - if (responseText != null) { - json.decodeFromString(responseText) - } else { - null - } - } catch (e: Exception) { - Log.e("LocationRepo", "Error parsing reverse geocode", e) - null - } - } - - override suspend fun searchLocation(query: String): List { - return try { - val encodedQuery = withContext(Dispatchers.IO) { - URLEncoder.encode(query, StandardCharsets.UTF_8.toString()) - } - val url = - "https://nominatim.openstreetmap.org/search?q=$encodedQuery&format=jsonv2&addressdetails=1&limit=10" - - val responseText = makeHttpRequest(url) - if (responseText != null) { - json.decodeFromString>(responseText) - } else { - emptyList() - } - } catch (e: Exception) { - Log.e("LocationRepo", "Error parsing search results", e) - emptyList() - } - } - - private suspend fun makeHttpRequest(urlString: String): String? = withContext(Dispatchers.IO) { - var connection: HttpURLConnection? = null - try { - val url = URL(urlString) - connection = (url.openConnection() as HttpURLConnection).apply { - requestMethod = "GET" - connectTimeout = 15_000 - readTimeout = 15_000 - setRequestProperty("User-Agent", userAgent) - setRequestProperty("Accept", "application/json") - } - - val responseCode = connection.responseCode - if (responseCode == HttpURLConnection.HTTP_OK) { - connection.inputStream.bufferedReader().use { it.readText() } - } else { - Log.e("LocationRepo", "Nominatim Error: $responseCode for URL: $urlString") - null - } - } catch (e: Exception) { - Log.e("LocationRepo", "Network error", e) - null - } finally { - connection?.disconnect() - } - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/repository/MessageRepositoryImpl.kt b/data/src/main/java/org/monogram/data/repository/MessageRepositoryImpl.kt deleted file mode 100644 index 5da0bd81..00000000 --- a/data/src/main/java/org/monogram/data/repository/MessageRepositoryImpl.kt +++ /dev/null @@ -1,1307 +0,0 @@ -package org.monogram.data.repository - -import android.content.Context -import android.util.Log -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.drinkless.tdlib.TdApi -import org.monogram.core.DispatcherProvider -import org.monogram.core.ScopeProvider -import org.monogram.data.chats.ChatCache -import org.monogram.data.core.coRunCatching -import org.monogram.data.datasource.FileDataSource -import org.monogram.data.datasource.cache.ChatLocalDataSource -import org.monogram.data.datasource.cache.UserLocalDataSource -import org.monogram.data.datasource.remote.MessageRemoteDataSource -import org.monogram.data.gateway.TelegramGateway -import org.monogram.data.infra.FileUpdateHandler -import org.monogram.data.mapper.MessageMapper -import org.monogram.data.mapper.map -import org.monogram.data.mapper.toDomain -import org.monogram.domain.models.* -import org.monogram.domain.models.webapp.InstantViewModel -import org.monogram.domain.models.webapp.InvoiceModel -import org.monogram.domain.models.webapp.ThemeParams -import org.monogram.domain.models.webapp.WebAppInfoModel -import org.monogram.domain.repository.* -import java.io.File - -class MessageRepositoryImpl( - private val context: Context, - private val gateway: TelegramGateway, - private val messageMapper: MessageMapper, - private val messageRemoteDataSource: MessageRemoteDataSource, - private val cache: ChatCache, - private val fileDataSource: FileDataSource, - private val dispatcherProvider: DispatcherProvider, - scopeProvider: ScopeProvider, - private val chatLocalDataSource: ChatLocalDataSource, - private val userLocalDataSource: UserLocalDataSource, - private val fileUpdateHandler: FileUpdateHandler -) : MessageRepository { - private val scope = scopeProvider.appScope - - override val newMessageFlow = messageRemoteDataSource.newMessageFlow - override val senderUpdateFlow = messageMapper.senderUpdateFlow - override val messageEditedFlow = messageRemoteDataSource.messageEditedFlow - override val messageUploadProgressFlow = messageRemoteDataSource.messageUploadProgressFlow - override val messageDownloadProgressFlow = messageRemoteDataSource.messageDownloadProgressFlow - override val messageDownloadCancelledFlow = messageRemoteDataSource.messageDownloadCancelledFlow - override val messageReadFlow = messageRemoteDataSource.messageReadFlow - override val messageDownloadCompletedFlow = messageRemoteDataSource.messageDownloadCompletedFlow - override val messageDeletedFlow = messageRemoteDataSource.messageDeletedFlow - override val messageIdUpdateFlow = messageRemoteDataSource.messageIdUpdateFlow - override val pinnedMessageFlow = messageRemoteDataSource.pinnedMessageFlow - override val mediaUpdateFlow = messageRemoteDataSource.mediaUpdateFlow - - init { - scope.launch { - try { - gateway.updates.collect { update -> - messageRemoteDataSource.handleUpdate(update) - when (update) { - is TdApi.UpdateNewMessage -> { - val entity = messageMapper.mapToEntity(update.message, ::resolveSenderName) - chatLocalDataSource.insertMessage(entity) - } - - is TdApi.UpdateMessageContent -> { - val extracted = messageMapper.extractCachedContent(update.newContent) - chatLocalDataSource.updateMessageContent( - messageId = update.messageId, - content = extracted.text, - contentType = extracted.type, - contentMeta = extracted.meta, - mediaFileId = extracted.fileId, - mediaPath = extracted.path, - editDate = 0 - ) - } - - is TdApi.UpdateMessageEdited -> { - val updated = messageRemoteDataSource.getMessage(update.chatId, update.messageId) - if (updated != null) { - chatLocalDataSource.insertMessage( - messageMapper.mapToEntity( - updated, - ::resolveSenderName - ) - ) - } - } - - is TdApi.UpdateMessageInteractionInfo -> { - chatLocalDataSource.updateInteractionInfo( - messageId = update.messageId, - viewCount = update.interactionInfo?.viewCount ?: 0, - forwardCount = update.interactionInfo?.forwardCount ?: 0, - replyCount = update.interactionInfo?.replyInfo?.replyCount ?: 0 - ) - } - - is TdApi.UpdateChatReadInbox -> { - chatLocalDataSource.markAsRead(update.chatId, update.lastReadInboxMessageId) - } - - is TdApi.UpdateDeleteMessages -> { - if (update.isPermanent) { - update.messageIds.forEach { messageId -> - chatLocalDataSource.deleteMessage(messageId) - } - } - } - } - } - } catch (e: Exception) { - Log.e("TdLibUpdates", "CRITICAL: Update loop died", e) - } - } - - scope.launch(dispatcherProvider.io) { - val ninetyDaysAgo = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000) - chatLocalDataSource.deleteExpired(ninetyDaysAgo) - } - - scope.launch { - fileUpdateHandler.fileDownloadCompleted.collect { (fileIdLong, path) -> - val fileId = fileIdLong.toInt() - if (fileId != 0 && path.isNotBlank()) { - chatLocalDataSource.updateMediaPath(fileId, path) - } - } - } - } - - override suspend fun openChat(chatId: Long) { - messageRemoteDataSource.setChatOpened(chatId) - try { - gateway.execute(TdApi.OpenChat(chatId)) - } catch (e: Exception) { - Log.e("MessageRepository", "Error opening chat $chatId", e) - if (chatId > 0) { - try { - gateway.execute(TdApi.CreatePrivateChat(chatId, false)) - gateway.execute(TdApi.OpenChat(chatId)) - } catch (e2: Exception) { - Log.e("MessageRepository", "Failed to create and open private chat $chatId", e2) - } - } - } - } - - override suspend fun closeChat(chatId: Long) { - messageRemoteDataSource.setChatClosed(chatId) - try { - gateway.execute(TdApi.CloseChat(chatId)) - } catch (e: Exception) { - Log.e("MessageRepository", "Error closing chat $chatId", e) - } - } - - override suspend fun sendMessage( - chatId: Long, - text: String, - replyToMsgId: Long?, - entities: List, - threadId: Long?, - sendOptions: MessageSendOptions - ) { - messageRemoteDataSource.sendMessage(chatId, text, replyToMsgId, entities, threadId, sendOptions) - } - - override suspend fun sendSticker(chatId: Long, stickerPath: String, replyToMsgId: Long?, threadId: Long?) { - messageRemoteDataSource.sendSticker(chatId, stickerPath, replyToMsgId, threadId) - } - - override suspend fun sendPhoto( - chatId: Long, - photoPath: String, - caption: String, - captionEntities: List, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ) { - messageRemoteDataSource.sendPhoto( - chatId = chatId, - photoPath = photoPath, - caption = caption, - captionEntities = captionEntities, - replyToMsgId = replyToMsgId, - threadId = threadId, - sendOptions = sendOptions - ) - } - - override suspend fun sendVideo( - chatId: Long, - videoPath: String, - caption: String, - captionEntities: List, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ) { - messageRemoteDataSource.sendVideo( - chatId = chatId, - videoPath = videoPath, - caption = caption, - captionEntities = captionEntities, - replyToMsgId = replyToMsgId, - threadId = threadId, - sendOptions = sendOptions - ) - } - - override suspend fun sendDocument( - chatId: Long, - documentPath: String, - caption: String, - captionEntities: List, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ) { - messageRemoteDataSource.sendDocument( - chatId = chatId, - documentPath = documentPath, - caption = caption, - captionEntities = captionEntities, - replyToMsgId = replyToMsgId, - threadId = threadId, - sendOptions = sendOptions - ) - } - - override suspend fun sendGif( - chatId: Long, - gifId: String, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ) { - messageRemoteDataSource.sendGif(chatId, gifId, replyToMsgId, threadId, sendOptions) - } - - override suspend fun sendGifFile( - chatId: Long, - gifPath: String, - caption: String, - captionEntities: List, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ) { - messageRemoteDataSource.sendGifFile( - chatId = chatId, - gifPath = gifPath, - caption = caption, - captionEntities = captionEntities, - replyToMsgId = replyToMsgId, - threadId = threadId, - sendOptions = sendOptions - ) - } - - override suspend fun sendAlbum( - chatId: Long, - paths: List, - caption: String, - captionEntities: List, - replyToMsgId: Long?, - threadId: Long?, - sendOptions: MessageSendOptions - ) { - messageRemoteDataSource.sendAlbum( - chatId = chatId, - paths = paths, - caption = caption, - captionEntities = captionEntities, - replyToMsgId = replyToMsgId, - threadId = threadId, - sendOptions = sendOptions - ) - } - - override suspend fun sendVideoNote(chatId: Long, videoPath: String, duration: Int, length: Int) { - messageRemoteDataSource.sendVideoNote(chatId, videoPath, duration, length) - } - - override suspend fun sendVoiceNote(chatId: Long, voicePath: String, duration: Int, waveform: ByteArray) { - messageRemoteDataSource.sendVoiceNote(chatId, voicePath, duration, waveform) - } - - override suspend fun forwardMessage(toChatId: Long, fromChatId: Long, messageId: Long) { - messageRemoteDataSource.forwardMessages(toChatId, fromChatId, longArrayOf(messageId), false, false) - } - - override suspend fun deleteMessage(chatId: Long, messageIds: List, revoke: Boolean) { - messageRemoteDataSource.deleteMessages(chatId, messageIds.toLongArray(), revoke) - messageIds.forEach { chatLocalDataSource.deleteMessage(it) } - } - - override suspend fun editMessage(chatId: Long, messageId: Long, newText: String, entities: List) { - messageRemoteDataSource.editMessageText(chatId, messageId, newText, entities) - } - - override suspend fun markAsRead(chatId: Long, messageId: Long) { - messageRemoteDataSource.markAsRead(chatId, messageId) - } - - override suspend fun markAllMentionsAsRead(chatId: Long) { - messageRemoteDataSource.markAllMentionsAsRead(chatId) - } - - override suspend fun markAllReactionsAsRead(chatId: Long) { - messageRemoteDataSource.markAllReactionsAsRead(chatId) - } - - - override suspend fun getMessagesOlder( - chatId: Long, - fromMessageId: Long, - limit: Int, - threadId: Long? - ): OlderMessagesPage = - withContext(dispatcherProvider.io) { - val cached = if (fromMessageId == 0L) { - val cachedEntities = chatLocalDataSource.getLatestMessages(chatId, limit) - mapLocalMessages(cachedEntities) - } else { - emptyList() - } - - try { - val remotePage = messageRemoteDataSource.getMessagesOlder(chatId, fromMessageId, limit, threadId) - persistRemoteMessages(chatId, remotePage.messages) - remotePage - } catch (e: Exception) { - val fallbackMessages = if (cached.isNotEmpty()) { - cached - } else { - val local = chatLocalDataSource.getMessagesOlder(chatId, fromMessageId, limit) - mapLocalMessages(local) - } - OlderMessagesPage( - messages = fallbackMessages, - reachedOldest = false, - isRemote = false - ) - } - } - - override suspend fun getCachedMessages(chatId: Long, limit: Int): List = - withContext(dispatcherProvider.io) { - val local = chatLocalDataSource.getLatestMessages(chatId, limit) - mapLocalMessages(local) - } - - override suspend fun getMessagesNewer( - chatId: Long, - fromMessageId: Long, - limit: Int, - threadId: Long? - ): List = - withContext(dispatcherProvider.io) { - try { - val remoteMessages = messageRemoteDataSource.getMessagesNewer(chatId, fromMessageId, limit, threadId) - persistRemoteMessages(chatId, remoteMessages) - remoteMessages - } catch (e: Exception) { - chatLocalDataSource.getMessagesNewer(chatId, fromMessageId, limit) - .let { mapLocalMessages(it) } - } - } - - override suspend fun getMessagesAround( - chatId: Long, - messageId: Long, - limit: Int, - threadId: Long? - ): List = - withContext(dispatcherProvider.io) { - try { - val remoteMessages = messageRemoteDataSource.getMessagesAround(chatId, messageId, limit, threadId) - persistRemoteMessages(chatId, remoteMessages) - remoteMessages - } catch (e: Exception) { - val local = chatLocalDataSource.getLatestMessages(chatId, limit) - mapLocalMessages(local) - } - } - - @Deprecated("Use getMessagesOlder instead") - override suspend fun getMessages(chatId: Long, fromMessageId: Long, limit: Int): List = - withContext(dispatcherProvider.io) { - getMessagesOlder(chatId, fromMessageId, limit).messages - } - - override suspend fun getChatDraft(chatId: Long, threadId: Long?): String? = - withContext(dispatcherProvider.io) { - messageRemoteDataSource.getChatDraft(chatId, threadId) - } - - override suspend fun saveChatDraft(chatId: Long, text: String, replyToMsgId: Long?, threadId: Long?) { - val draft = if (text.isNotEmpty()) { - val inputMessageText = TdApi.InputMessageText().apply { - this.text = TdApi.FormattedText(text, null) - } - TdApi.DraftMessage().apply { - this.inputMessageText = inputMessageText - this.date = (System.currentTimeMillis() / 1000).toInt() - - if (replyToMsgId != null && replyToMsgId != 0L) { - this.replyTo = TdApi.InputMessageReplyToMessage().apply { - this.messageId = replyToMsgId - this.quote = null - this.checklistTaskId = 0 - } - } - } - } else { - null - } - withContext(dispatcherProvider.io) { - messageRemoteDataSource.saveChatDraft(chatId, draft, replyToMsgId, threadId) - - cache.updateChat(chatId) { chat -> - chat.draftMessage = draft - } - } - } - - override suspend fun pinMessage(chatId: Long, messageId: Long, disableNotification: Boolean) { - messageRemoteDataSource.pinMessage(chatId, messageId, disableNotification) - } - - override suspend fun unpinMessage(chatId: Long, messageId: Long) { - messageRemoteDataSource.unpinMessage(chatId, messageId) - } - - override suspend fun getPinnedMessage(chatId: Long, threadId: Long?): MessageModel? = - withContext(dispatcherProvider.io) { - messageRemoteDataSource.getPinnedMessageModel(chatId, threadId) - } - - override suspend fun getAllPinnedMessages(chatId: Long, threadId: Long?): List = - withContext(dispatcherProvider.io) { - messageRemoteDataSource.getAllPinnedMessages(chatId, threadId) - } - - override suspend fun getPinnedMessageCount(chatId: Long, threadId: Long?): Int = - withContext(dispatcherProvider.io) { - messageRemoteDataSource.getPinnedMessageCount(chatId, threadId) - } - - override suspend fun getScheduledMessages(chatId: Long): List = - withContext(dispatcherProvider.io) { - messageRemoteDataSource.getScheduledMessages(chatId) - } - - override suspend fun sendScheduledNow(chatId: Long, messageId: Long) { - withContext(dispatcherProvider.io) { - messageRemoteDataSource.sendScheduledNow(chatId, messageId) - } - } - - override fun downloadFile(fileId: Int, priority: Int, offset: Long, limit: Long, synchronous: Boolean) { - scope.launch { - fileDataSource.downloadFile(fileId, priority, offset, limit, synchronous) - } - } - - override fun invalidateSenderCache(userId: Long) { - messageMapper.invalidateSenderCache(userId) - } - - override suspend fun cancelDownloadFile(fileId: Int) { - fileDataSource.cancelDownload(fileId) - } - - override suspend fun sendChatAction(chatId: Long, action: MessageRepository.ChatAction, threadId: Long?) { - val tdAction = when (action) { - MessageRepository.ChatAction.Typing -> TdApi.ChatActionTyping() - MessageRepository.ChatAction.RecordingVideo -> TdApi.ChatActionRecordingVideo() - MessageRepository.ChatAction.RecordingVoice -> TdApi.ChatActionRecordingVoiceNote() - MessageRepository.ChatAction.UploadingPhoto -> TdApi.ChatActionUploadingPhoto(0) - MessageRepository.ChatAction.UploadingVideo -> TdApi.ChatActionUploadingVideo(0) - MessageRepository.ChatAction.UploadingDocument -> TdApi.ChatActionUploadingDocument(0) - MessageRepository.ChatAction.ChoosingSticker -> TdApi.ChatActionChoosingSticker() - MessageRepository.ChatAction.Cancel -> TdApi.ChatActionCancel() - } - messageRemoteDataSource.sendChatAction(chatId, threadId?: 0L, tdAction) - } - - override suspend fun getMessageReadDate(chatId: Long, messageId: Long, messageDate: Int): Int = withContext(dispatcherProvider.io) { - messageMapper.getMessageReadDate(chatId, messageId, messageDate) - } - - override suspend fun getMessageViewers(chatId: Long, messageId: Long): List = - withContext(dispatcherProvider.io) { - messageRemoteDataSource.getMessageViewersModels(chatId, messageId) - } - - override suspend fun summarizeMessage(chatId: Long, messageId: Long, toLanguageCode: String): String? = - withContext(dispatcherProvider.io) { - when (val result = gateway.execute(TdApi.SummarizeMessage(chatId, messageId, toLanguageCode))) { - is TdApi.FormattedText -> result.text - else -> null - } - } - - override suspend fun translateMessage(chatId: Long, messageId: Long, toLanguageCode: String): String? = - withContext(dispatcherProvider.io) { - when (val result = gateway.execute(TdApi.TranslateMessageText(chatId, messageId, toLanguageCode))) { - is TdApi.FormattedText -> result.text - else -> null - } - } - - override suspend fun addMessageReaction(chatId: Long, messageId: Long, reaction: String) { - messageRemoteDataSource.addMessageReaction(chatId, messageId, reaction) - } - - override suspend fun removeMessageReaction(chatId: Long, messageId: Long, reaction: String) { - messageRemoteDataSource.removeMessageReaction(chatId, messageId, reaction) - } - - override suspend fun stopPoll(chatId: Long, messageId: Long) { - messageRemoteDataSource.stopPoll(chatId, messageId) - } - - override suspend fun setPollAnswer(chatId: Long, messageId: Long, optionIds: List) { - messageRemoteDataSource.setPollAnswer(chatId, messageId, optionIds.toIntArray()) - } - - override suspend fun getPollVoters( - chatId: Long, - messageId: Long, - optionId: Int, - offset: Int, - limit: Int - ): List = withContext(dispatcherProvider.io) { - messageRemoteDataSource.getPollVotersModels(chatId, messageId, optionId, offset, limit) - } - - override suspend fun getWebPageInstantView(url: String, forceFull: Boolean): InstantViewModel? { - val result = gateway.execute(TdApi.GetWebPageInstantView(url, forceFull)) - return if (result is TdApi.WebPageInstantView) { - map(result, url) - } else { - null - } - } - - override suspend fun searchMessages( - chatId: Long, - query: String, - fromMessageId: Long, - limit: Int, - threadId: Long? - ): SearchChatMessagesResult = withContext(dispatcherProvider.io) { - messageRemoteDataSource.searchMessages(chatId, query, fromMessageId, limit, threadId) - } - - override fun updateVisibleRange(chatId: Long, visibleMessageIds: List, nearbyMessageIds: List) { - messageRemoteDataSource.updateVisibleRange(chatId, visibleMessageIds, nearbyMessageIds) - } - - override suspend fun onCallbackQuery(chatId: Long, messageId: Long, data: ByteArray) { - messageRemoteDataSource.onCallbackQuery(chatId, messageId, data) - } - - override suspend fun openWebApp( - chatId: Long, - botUserId: Long, - url: String, - themeParams: ThemeParams? - ): WebAppInfoModel? = withContext(dispatcherProvider.io) { - messageRemoteDataSource.openWebApp(chatId, botUserId, url, themeParams) - } - - override suspend fun closeWebApp(launchId: Long) { - messageRemoteDataSource.closeWebApp(launchId) - } - - override suspend fun getInvoice(slug: String?, chatId: Long?, messageId: Long?): InvoiceModel? { - val inputInvoice = when { - slug != null -> TdApi.InputInvoiceName(slug) - chatId != null && messageId != null -> TdApi.InputInvoiceMessage(chatId, messageId) - else -> { - return null - } - } - - val result = gateway.execute(TdApi.GetPaymentForm(inputInvoice, TdApi.ThemeParameters())) - if (result is TdApi.PaymentForm) { - val productInfo = result.productInfo - - val formType = result.type - - if (formType is TdApi.PaymentFormTypeRegular) { - val invoice = formType.invoice - - val photo = productInfo.photo?.sizes?.lastOrNull()?.photo - if (photo != null) { - // No cache access here, this is a temporary solution - } - - return InvoiceModel( - title = productInfo.title, - description = productInfo.description.text, - currency = invoice.currency, - totalAmount = invoice.priceParts.sumOf { it.amount }, - photoUrl = photo?.id?.toString(), - isTest = invoice.isTest, - slug = slug - ) - - } else { - return null - } - } else { - return null - } - } - - override suspend fun payInvoice(slug: String?, chatId: Long?, messageId: Long?): Boolean { - val inputInvoice = when { - slug != null -> TdApi.InputInvoiceName(slug) - chatId != null && messageId != null -> TdApi.InputInvoiceMessage(chatId, messageId) - else -> { - return false - } - } - val result = gateway.execute(TdApi.GetPaymentForm(inputInvoice, TdApi.ThemeParameters())) - return result is TdApi.PaymentForm - } - - override suspend fun getFilePath(fileId: Int): String? { - val result = coRunCatching { gateway.execute(TdApi.GetFile(fileId)) }.getOrNull() - return if (result is TdApi.File) { - result.local.path.ifEmpty { null } - } else { - null - } - } - - override suspend fun onCallbackQueryBuy(chatId: Long, messageId: Long) { - messageRemoteDataSource.onCallbackQueryBuy(chatId, messageId) - } - - override suspend fun sendWebAppResult(launchId: Long, queryId: String) { - messageRemoteDataSource.sendWebAppResult(launchId, queryId) - } - - override suspend fun getProfileMedia( - chatId: Long, - filter: ProfileMediaFilter, - fromMessageId: Long, - limit: Int - ): List = withContext(dispatcherProvider.io) { - val tdFilter = when (filter) { - ProfileMediaFilter.MEDIA -> TdApi.SearchMessagesFilterPhotoAndVideo() - ProfileMediaFilter.FILES -> TdApi.SearchMessagesFilterDocument() - ProfileMediaFilter.AUDIO -> TdApi.SearchMessagesFilterAudio() - ProfileMediaFilter.VOICE -> TdApi.SearchMessagesFilterVoiceAndVideoNote() - ProfileMediaFilter.LINKS -> TdApi.SearchMessagesFilterUrl() - ProfileMediaFilter.GIFS -> TdApi.SearchMessagesFilterAnimation() - } - - val request = TdApi.SearchChatMessages() - request.chatId = chatId - request.query = "" - request.senderId = null - request.fromMessageId = fromMessageId - request.offset = 0 - request.limit = limit - request.filter = tdFilter - - try { - val result = gateway.execute(request) - result.messages.mapNotNull { msg -> - cache.putMessage(msg) - triggerFileDownload(msg) - coRunCatching { - messageMapper.mapMessageToModel(msg) - }.getOrNull() - } - } catch (e: Exception) { - emptyList() - } - } - - private suspend fun triggerFileDownload(msg: TdApi.Message) { - val lowQualityFile = when (val content = msg.content) { - is TdApi.MessagePhoto -> { - content.photo.sizes.find { it.type == "m" }?.photo - ?: content.photo.sizes.find { it.type == "s" }?.photo - ?: content.photo.sizes.firstOrNull()?.photo - } - - is TdApi.MessageVideo -> content.video.thumbnail?.file - is TdApi.MessageDocument -> content.document.thumbnail?.file - is TdApi.MessageAnimation -> content.animation.thumbnail?.file - else -> null - } - - if (lowQualityFile != null && lowQualityFile.local.path.isEmpty()) { - fileDataSource.downloadFile(lowQualityFile.id, 32, 0, 0, false) - } - - triggerFullQualityDownload(msg) - } - - private suspend fun triggerFullQualityDownload(msg: TdApi.Message) { - val file = when (val content = msg.content) { - is TdApi.MessagePhoto -> { - content.photo.sizes.find { it.type == "x" }?.photo - ?: content.photo.sizes.find { it.type == "m" }?.photo - ?: content.photo.sizes.lastOrNull()?.photo - } - - is TdApi.MessageVideo -> content.video.video - is TdApi.MessageAnimation -> content.animation.animation - else -> null - } - - if (file != null && file.local.path.isEmpty()) { - fileDataSource.downloadFile(file.id, 16, 0, 0, false) - } - } - - override suspend fun joinChat(chatId: Long) { - gateway.execute(TdApi.JoinChat(chatId)) - } - - override suspend fun restrictChatMember( - chatId: Long, - userId: Long, - permissions: ChatPermissionsModel, - untilDate: Int - ) { - val tdPermissions = TdApi.ChatPermissions( - permissions.canSendBasicMessages, - permissions.canSendAudios, - permissions.canSendDocuments, - permissions.canSendPhotos, - permissions.canSendVideos, - permissions.canSendVideoNotes, - permissions.canSendVoiceNotes, - permissions.canSendPolls, - permissions.canSendOtherMessages, - permissions.canAddLinkPreviews, - permissions.canEditTag, - permissions.canChangeInfo, - permissions.canInviteUsers, - permissions.canPinMessages, - permissions.canCreateTopics - ) - gateway.execute( - TdApi.SetChatMemberStatus( - chatId, - TdApi.MessageSenderUser(userId), - TdApi.ChatMemberStatusRestricted(false, untilDate, tdPermissions) - ) - ) - return - } - - override suspend fun getInlineBotResults( - botUserId: Long, - chatId: Long, - query: String, - offset: String - ): InlineBotResultsModel? { - val result = gateway.execute(TdApi.GetInlineQueryResults(botUserId, chatId, null, query, offset)) - if (result is TdApi.InlineQueryResults) { - return InlineBotResultsModel( - queryId = result.inlineQueryId, - nextOffset = result.nextOffset, - results = result.results.map { res -> - fun getThumbFileId(thumbnail: TdApi.Thumbnail?): Int { - return thumbnail?.file?.id ?: 0 - } - - fun getPath(thumbnail: TdApi.Thumbnail?): String? { - if (thumbnail == null) return null - val file = thumbnail.file - val updated = cache.fileCache[file.id] ?: file - if (updated.local.path.isNotEmpty()) return updated.local.path - scope.launch { - fileDataSource.downloadFile(updated.id, 32, 0, 0, false) - } - return null - } - - fun makePath(thumbnail: TdApi.Minithumbnail?): String? { - val data = thumbnail?.data ?: return null - return try { - val file = File.createTempFile( - "mini_${System.currentTimeMillis()}", - ".webp", - context.cacheDir - ) - file.writeBytes(data) - file.absolutePath - } catch (e: Exception) { - null - } - } - - val photoResult = res as? TdApi.InlineQueryResultPhoto - val selectedPhotoSize = photoResult - ?.photo - ?.sizes - ?.sortedBy { it.width * it.height } - ?.lastOrNull { size -> maxOf(size.width, size.height) <= 1280 } - ?: photoResult?.photo?.sizes?.lastOrNull() - - InlineQueryResultModel( - id = when (res) { - is TdApi.InlineQueryResultArticle -> res.id - is TdApi.InlineQueryResultPhoto -> res.id - is TdApi.InlineQueryResultVideo -> res.id - is TdApi.InlineQueryResultAudio -> res.id - is TdApi.InlineQueryResultDocument -> res.id - is TdApi.InlineQueryResultLocation -> res.id - is TdApi.InlineQueryResultVenue -> res.id - is TdApi.InlineQueryResultGame -> res.id - is TdApi.InlineQueryResultAnimation -> res.id - is TdApi.InlineQueryResultSticker -> res.id - is TdApi.InlineQueryResultVoiceNote -> res.id - is TdApi.InlineQueryResultContact -> res.id - else -> "" - }, - type = when (res) { - is TdApi.InlineQueryResultArticle -> "article" - is TdApi.InlineQueryResultPhoto -> "photo" - is TdApi.InlineQueryResultVideo -> "video" - is TdApi.InlineQueryResultAudio -> "audio" - is TdApi.InlineQueryResultDocument -> "document" - is TdApi.InlineQueryResultLocation -> "location" - is TdApi.InlineQueryResultVenue -> "venue" - is TdApi.InlineQueryResultGame -> "game" - is TdApi.InlineQueryResultAnimation -> "gif" - is TdApi.InlineQueryResultSticker -> "sticker" - is TdApi.InlineQueryResultVoiceNote -> "voice" - is TdApi.InlineQueryResultContact -> "contact" - else -> res.javaClass.simpleName - }, - title = when (res) { - is TdApi.InlineQueryResultArticle -> res.title - is TdApi.InlineQueryResultPhoto -> res.title - is TdApi.InlineQueryResultVideo -> res.title - is TdApi.InlineQueryResultAudio -> res.audio.title - is TdApi.InlineQueryResultDocument -> res.title - is TdApi.InlineQueryResultLocation -> res.title - is TdApi.InlineQueryResultVenue -> res.venue.title - is TdApi.InlineQueryResultGame -> res.game.title - else -> null - }, - description = when (res) { - is TdApi.InlineQueryResultArticle -> res.description - is TdApi.InlineQueryResultPhoto -> res.description - is TdApi.InlineQueryResultVideo -> res.description - is TdApi.InlineQueryResultDocument -> res.description - else -> null - }, - thumbFileId = when (res) { - is TdApi.InlineQueryResultArticle -> getThumbFileId(res.thumbnail) - is TdApi.InlineQueryResultPhoto -> selectedPhotoSize?.photo?.id ?: 0 - is TdApi.InlineQueryResultVideo -> getThumbFileId(res.video.thumbnail) - is TdApi.InlineQueryResultDocument -> getThumbFileId(res.document.thumbnail) - is TdApi.InlineQueryResultAnimation -> getThumbFileId(res.animation.thumbnail) - is TdApi.InlineQueryResultSticker -> getThumbFileId(res.sticker.thumbnail) - else -> 0 - }, - thumbUrl = when (res) { - is TdApi.InlineQueryResultArticle -> getPath(res.thumbnail) - is TdApi.InlineQueryResultPhoto -> { - val photo = res.photo - val path = selectedPhotoSize?.photo?.let { file -> - val updated = cache.fileCache[file.id] ?: file - if (updated.local.path.isNotEmpty()) { - updated.local.path - } else { - scope.launch { - fileDataSource.downloadFile(updated.id, 32, 0, 0, false) - } - null - } - } - path ?: makePath(photo.minithumbnail) - } - - is TdApi.InlineQueryResultVideo -> - getPath(res.video.thumbnail) ?: makePath(res.video.minithumbnail) - - is TdApi.InlineQueryResultDocument -> - getPath(res.document.thumbnail) ?: makePath(res.document.minithumbnail) - - is TdApi.InlineQueryResultAnimation -> - getPath(res.animation.thumbnail) ?: makePath(res.animation.minithumbnail) - is TdApi.InlineQueryResultSticker -> getPath(res.sticker.thumbnail) - else -> null - }, - width = when (res) { - is TdApi.InlineQueryResultPhoto -> selectedPhotoSize?.width - ?: res.photo.minithumbnail?.width ?: 0 - is TdApi.InlineQueryResultVideo -> res.video.width - is TdApi.InlineQueryResultAnimation -> res.animation.width - is TdApi.InlineQueryResultSticker -> res.sticker.width - else -> 0 - }, - height = when (res) { - is TdApi.InlineQueryResultPhoto -> selectedPhotoSize?.height - ?: res.photo.minithumbnail?.height ?: 0 - is TdApi.InlineQueryResultVideo -> res.video.height - is TdApi.InlineQueryResultAnimation -> res.animation.height - is TdApi.InlineQueryResultSticker -> res.sticker.height - else -> 0 - } - ) - }, - switchPmText = null, - switchPmParameter = null - ) - } else { - return null - } - } - - override suspend fun sendInlineBotResult( - chatId: Long, - queryId: Long, - resultId: String, - replyToMsgId: Long?, - threadId: Long? - ) { - val replyTo = if (replyToMsgId != null) - TdApi.InputMessageReplyToMessage(replyToMsgId, null, 0) - else null - - val topicId = if (threadId != null) { - TdApi.MessageTopicForum(threadId.toInt()) - } else { - null - } - - gateway.execute( - TdApi.SendInlineQueryResultMessage( - chatId, - topicId, - replyTo, - null, - queryId, - resultId, - false - ) - ) - } - - override suspend fun getChatEventLog( - chatId: Long, - query: String, - fromEventId: Long, - limit: Int, - filters: ChatEventLogFiltersModel, - userIds: List - ): List = - withContext(dispatcherProvider.io) { - val tdFilters = TdApi.ChatEventLogFilters( - filters.messageEdits, - filters.messageDeletions, - filters.messagePins, - filters.memberJoins, - filters.memberLeaves, - filters.memberInvites, - filters.memberPromotions, - filters.memberRestrictions, - false, - filters.infoChanges, - filters.settingChanges, - filters.inviteLinkChanges, - filters.videoChatChanges, - filters.forumChanges, - filters.subscriptionExtensions - ) - val result = gateway.execute( - TdApi.GetChatEventLog( - chatId, - query, - fromEventId, - limit, - tdFilters, - userIds.toLongArray() - ) - ) - if (result is TdApi.ChatEvents) { - val events = result.events.map { event -> - val senderId = when (val sender = event.memberId) { - is TdApi.MessageSenderUser -> sender.userId - else -> 0L - } - ChatEventModel( - id = event.id, - date = event.date, - memberId = when (val sender = event.memberId) { - is TdApi.MessageSenderUser -> MessageSenderModel.User(sender.userId) - is TdApi.MessageSenderChat -> MessageSenderModel.Chat(sender.chatId) - else -> MessageSenderModel.User(0) - }, - action = when (val action = event.action) { - is TdApi.ChatEventMessageEdited -> ChatEventActionModel.MessageEdited( - oldMessage = messageMapper.mapMessageToModel(action.oldMessage), - newMessage = messageMapper.mapMessageToModel(action.newMessage) - ) - - is TdApi.ChatEventMessageDeleted -> ChatEventActionModel.MessageDeleted( - message = messageMapper.mapMessageToModel(action.message) - ) - - is TdApi.ChatEventMessagePinned -> ChatEventActionModel.MessagePinned( - message = messageMapper.mapMessageToModel(action.message) - ) - - is TdApi.ChatEventMessageUnpinned -> ChatEventActionModel.MessageUnpinned( - message = messageMapper.mapMessageToModel(action.message) - ) - - is TdApi.ChatEventMemberJoined -> ChatEventActionModel.MemberJoined( - senderId - ) - - is TdApi.ChatEventMemberLeft -> ChatEventActionModel.MemberLeft( - senderId - ) - - is TdApi.ChatEventMemberInvited -> ChatEventActionModel.MemberInvited( - action.userId, - action.status.toString() - ) - - is TdApi.ChatEventMemberPromoted -> ChatEventActionModel.MemberPromoted( - action.userId, - action.oldStatus.toString(), - action.newStatus.toString() - ) - - is TdApi.ChatEventMemberRestricted -> { - val oldStatus = action.oldStatus - val newStatus = action.newStatus - ChatEventActionModel.MemberRestricted( - userId = when (val m = action.memberId) { - is TdApi.MessageSenderUser -> m.userId - else -> 0 - }, - oldStatus = oldStatus.toString(), - newStatus = newStatus.toString(), - untilDate = (newStatus as? TdApi.ChatMemberStatusRestricted)?.restrictedUntilDate - ?: 0, - oldPermissions = (oldStatus as? TdApi.ChatMemberStatusRestricted)?.permissions?.let { p -> - ChatPermissionsModel( - canSendBasicMessages = p.canSendBasicMessages, - canSendAudios = p.canSendAudios, - canSendDocuments = p.canSendDocuments, - canSendPhotos = p.canSendPhotos, - canSendVideos = p.canSendVideos, - canSendVideoNotes = p.canSendVideoNotes, - canSendVoiceNotes = p.canSendVoiceNotes, - canSendPolls = p.canSendPolls, - canSendOtherMessages = p.canSendOtherMessages, - canAddLinkPreviews = p.canAddLinkPreviews, - canEditTag = p.canEditTag, - canChangeInfo = p.canChangeInfo, - canInviteUsers = p.canInviteUsers, - canPinMessages = p.canPinMessages, - canCreateTopics = p.canCreateTopics - ) - }, - newPermissions = (newStatus as? TdApi.ChatMemberStatusRestricted)?.permissions?.let { p -> - ChatPermissionsModel( - canSendBasicMessages = p.canSendBasicMessages, - canSendAudios = p.canSendAudios, - canSendDocuments = p.canSendDocuments, - canSendPhotos = p.canSendPhotos, - canSendVideos = p.canSendVideos, - canSendVideoNotes = p.canSendVideoNotes, - canSendVoiceNotes = p.canSendVoiceNotes, - canSendPolls = p.canSendPolls, - canSendOtherMessages = p.canSendOtherMessages, - canAddLinkPreviews = p.canAddLinkPreviews, - canEditTag = p.canEditTag, - canChangeInfo = p.canChangeInfo, - canInviteUsers = p.canInviteUsers, - canPinMessages = p.canPinMessages, - canCreateTopics = p.canCreateTopics - ) - } - ) - } - - is TdApi.ChatEventTitleChanged -> ChatEventActionModel.TitleChanged( - action.oldTitle, - action.newTitle - ) - - is TdApi.ChatEventDescriptionChanged -> ChatEventActionModel.DescriptionChanged( - action.oldDescription, - action.newDescription - ) - - is TdApi.ChatEventUsernameChanged -> ChatEventActionModel.UsernameChanged( - action.oldUsername, - action.newUsername - ) - - is TdApi.ChatEventPhotoChanged -> ChatEventActionModel.PhotoChanged( - null, - null - ) - - is TdApi.ChatEventInviteLinkEdited -> ChatEventActionModel.InviteLinkEdited( - action.oldInviteLink.inviteLink, - action.newInviteLink.inviteLink - ) - - is TdApi.ChatEventInviteLinkRevoked -> ChatEventActionModel.InviteLinkRevoked( - action.inviteLink.inviteLink - ) - - is TdApi.ChatEventInviteLinkDeleted -> ChatEventActionModel.InviteLinkDeleted( - action.inviteLink.inviteLink - ) - - is TdApi.ChatEventVideoChatCreated -> ChatEventActionModel.VideoChatCreated( - action.groupCallId - ) - - is TdApi.ChatEventVideoChatEnded -> ChatEventActionModel.VideoChatEnded( - action.groupCallId - ) - - else -> ChatEventActionModel.Unknown(action.javaClass.simpleName) - } - ) - } - return@withContext events - } - else return@withContext emptyList() - } - - override suspend fun getFileInfo(fileId: Int): FileModel? { - val result = coRunCatching { gateway.execute(TdApi.GetFile(fileId)) }.getOrNull() - if (result is TdApi.File) { - val model = FileModel( - id = result.id, - size = result.size, - expectedSize = result.expectedSize, - local = result.local.toDomain(), - remote = result.remote.toDomain() - ) - return model - } else { - return null - } - } - - override suspend fun getHighResFileId(chatId: Long, messageId: Long): Int? { - return try { - val result = gateway.execute(TdApi.GetMessage(chatId, messageId)) - if (result is TdApi.Message && result.content is TdApi.MessagePhoto) { - val photo = (result.content as TdApi.MessagePhoto).photo - val bestSize = photo.sizes.maxByOrNull { it.width.toLong() * it.height.toLong() } - ?: photo.sizes.lastOrNull() - val fileId = bestSize?.photo?.id ?: return null - messageRemoteDataSource.registerFileForMessage(fileId, chatId, messageId) - fileId - } else { - null - } - } catch (e: Exception) { - Log.w( - "MessageRepositoryImpl", - "Failed to resolve high-res file id for chatId=$chatId, messageId=$messageId: ${e.message}" - ) - null - } - } - - override fun clearMessages(chatId: Long) { - cache.clearMessages(chatId) - scope.launch(dispatcherProvider.io) { - chatLocalDataSource.clearMessagesForChat(chatId) - } - } - - override fun clearAllCache() { - cache.clearAll() - scope.launch(dispatcherProvider.io) { - chatLocalDataSource.clearAll() - } - } - - private fun persistRemoteMessages(chatId: Long, remoteMessages: List) { - scope.launch(dispatcherProvider.io) { - val entities = remoteMessages.mapNotNull { model -> - messageRemoteDataSource.getMessage(chatId, model.id)?.let { message -> - messageMapper.mapToEntity(message, ::resolveSenderName) - } - } - if (entities.isNotEmpty()) { - chatLocalDataSource.insertMessages(entities) - } - } - } - - private fun resolveSenderName(senderId: Long): String? { - val user = cache.getUser(senderId) - if (user != null) { - return listOfNotNull(user.firstName.takeIf { it.isNotBlank() }, user.lastName?.takeIf { it.isNotBlank() }) - .joinToString(" ") - .ifBlank { null } - } - return cache.getChat(senderId)?.title - } - - private suspend fun mapLocalMessages( - entities: List - ): List { - prewarmCachedSenders(entities) - return entities.map { entity -> - val model = messageMapper.mapEntityToModel(entity) - enrichSenderFromCache(model) - } - } - - private suspend fun prewarmCachedSenders( - entities: List - ) { - val senderIds = entities.asSequence() - .map { it.senderId } - .filter { it > 0L } - .distinct() - .toList() - - senderIds.forEach { senderId -> - if (cache.getUser(senderId) != null) return@forEach - val localUser = coRunCatching { userLocalDataSource.getUser(senderId) }.getOrNull() ?: return@forEach - cache.putUser(localUser) - } - } - - private fun enrichSenderFromCache(model: MessageModel): MessageModel { - val senderId = model.senderId - if (senderId <= 0L) return model - - val cachedUser = cache.getUser(senderId) - if (cachedUser != null) { - val resolvedName = listOfNotNull( - cachedUser.firstName.takeIf { it.isNotBlank() }, - cachedUser.lastName?.takeIf { it.isNotBlank() } - ).joinToString(" ").ifBlank { model.senderName } - - val resolvedAvatar = resolveFilePath(cachedUser.profilePhoto?.small) - if (resolvedAvatar == null) { - cachedUser.profilePhoto?.small?.id?.takeIf { it != 0 }?.let { avatarFileId -> - messageRemoteDataSource.enqueueDownload(avatarFileId, priority = 16) - } - } - val emojiId = when (val type = cachedUser.emojiStatus?.type) { - is TdApi.EmojiStatusTypeCustomEmoji -> type.customEmojiId - is TdApi.EmojiStatusTypeUpgradedGift -> type.modelCustomEmojiId - else -> model.senderStatusEmojiId - } - - return model.copy( - senderName = resolvedName, - senderAvatar = resolvedAvatar ?: model.senderAvatar, - isSenderVerified = cachedUser.verificationStatus?.isVerified ?: model.isSenderVerified, - isSenderPremium = cachedUser.isPremium || model.isSenderPremium, - senderStatusEmojiId = emojiId - ) - } - - val cachedChat = cache.getChat(senderId) - if (cachedChat != null) { - val resolvedName = cachedChat.title.takeIf { it.isNotBlank() } ?: model.senderName - val resolvedAvatar = resolveFilePath(cachedChat.photo?.small) - return model.copy( - senderName = resolvedName, - senderAvatar = resolvedAvatar ?: model.senderAvatar - ) - } - - return model - } - - private fun resolveFilePath(file: TdApi.File?): String? { - if (file == null) return null - val directPath = file.local.path.takeIf { it.isNotBlank() && File(it).exists() } - if (directPath != null) return directPath - - val cachedPath = cache.fileCache[file.id]?.local?.path - return cachedPath?.takeIf { it.isNotBlank() && File(it).exists() } - } -} diff --git a/data/src/main/java/org/monogram/data/repository/PollRepositoryImpl.kt b/data/src/main/java/org/monogram/data/repository/PollRepositoryImpl.kt deleted file mode 100644 index 2c63ef4a..00000000 --- a/data/src/main/java/org/monogram/data/repository/PollRepositoryImpl.kt +++ /dev/null @@ -1,15 +0,0 @@ -package org.monogram.data.repository - -import org.monogram.domain.repository.PollRepository - -class PollRepositoryImpl : PollRepository { - private val pollToMessage = mutableMapOf>() - - override suspend fun mapPollIdToMessage(pollId: Long, chatId: Long, messageId: Long) { - pollToMessage[pollId] = chatId to messageId - } - - override suspend fun getMessageIdByPollId(pollId: Long): Pair? { - return pollToMessage[pollId] - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/repository/PrivacyRepositoryImpl.kt b/data/src/main/java/org/monogram/data/repository/PrivacyRepositoryImpl.kt deleted file mode 100644 index 14f52fe2..00000000 --- a/data/src/main/java/org/monogram/data/repository/PrivacyRepositoryImpl.kt +++ /dev/null @@ -1,65 +0,0 @@ -package org.monogram.data.repository - -import org.monogram.core.ScopeProvider -import org.monogram.domain.models.PrivacyRule -import org.monogram.domain.repository.PrivacyKey -import org.monogram.domain.repository.PrivacyRepository -import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.flow.* -import org.drinkless.tdlib.TdApi -import org.monogram.data.datasource.remote.PrivacyRemoteDataSource -import org.monogram.data.gateway.UpdateDispatcher -import org.monogram.data.mapper.toApi -import org.monogram.data.mapper.toDomain - -class PrivacyRepositoryImpl( - private val remote: PrivacyRemoteDataSource, - private val updates: UpdateDispatcher, - scopeProvider: ScopeProvider -) : PrivacyRepository { - - private val scope = scopeProvider.appScope - - override fun getPrivacyRules(key: PrivacyKey): Flow> = callbackFlow { - val setting = key.toApi() - - trySend(remote.getPrivacyRules(setting).map { it.toDomain() }) - - val job = updates.userPrivacySettingRules - .filter { it.setting.constructor == setting.constructor } - .onEach { update -> trySend(update.rules.rules.map { it.toDomain() }) } - .launchIn(this) - - awaitClose { job.cancel() } - } - - override suspend fun setPrivacyRule(key: PrivacyKey, rules: List) { - val setting = key.toApi() - val tdRules = TdApi.UserPrivacySettingRules(rules.map { it.toApi() }.toTypedArray()) - remote.setPrivacyRules(setting, tdRules) - } - - override suspend fun getBlockedUsers(): List = remote.getBlockedUsers() - - override suspend fun blockUser(userId: Long) = remote.blockUser(userId) - - override suspend fun unblockUser(userId: Long) = remote.unblockUser(userId) - - override suspend fun deleteAccount(reason: String, password: String) = - remote.deleteAccount(reason, password) - - override suspend fun getAccountTtl(): Int = remote.getAccountTtl() - - override suspend fun setAccountTtl(days: Int) = remote.setAccountTtl(days) - - override suspend fun getPasswordState(): Boolean = remote.getPasswordState() - - override suspend fun canShowSensitiveContent(): Boolean = - remote.getOption("can_ignore_sensitive_content_restrictions") - - override suspend fun isShowSensitiveContentEnabled(): Boolean = - remote.getOption("ignore_sensitive_content_restrictions") - - override suspend fun setShowSensitiveContent(enabled: Boolean) = - remote.setOption("ignore_sensitive_content_restrictions", enabled) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/repository/SettingsRepositoryImpl.kt b/data/src/main/java/org/monogram/data/repository/SettingsRepositoryImpl.kt deleted file mode 100644 index 761d752b..00000000 --- a/data/src/main/java/org/monogram/data/repository/SettingsRepositoryImpl.kt +++ /dev/null @@ -1,340 +0,0 @@ -package org.monogram.data.repository - -import kotlinx.coroutines.* -import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.flow.* -import kotlinx.serialization.json.Json -import org.drinkless.tdlib.TdApi -import org.monogram.core.DispatcherProvider -import org.monogram.core.ScopeProvider -import org.monogram.data.datasource.cache.SettingsCacheDataSource -import org.monogram.data.datasource.remote.ChatsRemoteDataSource -import org.monogram.data.datasource.remote.SettingsRemoteDataSource -import org.monogram.data.db.dao.AttachBotDao -import org.monogram.data.db.dao.KeyValueDao -import org.monogram.data.db.dao.WallpaperDao -import org.monogram.data.db.model.AttachBotEntity -import org.monogram.data.db.model.KeyValueEntity -import org.monogram.data.db.model.WallpaperEntity -import org.monogram.data.gateway.UpdateDispatcher -import org.monogram.data.mapper.* -import org.monogram.data.mapper.user.toDomain -import org.monogram.domain.models.* -import org.monogram.domain.repository.AppPreferencesProvider -import org.monogram.domain.repository.CacheProvider -import org.monogram.domain.repository.SettingsRepository -import org.monogram.domain.repository.SettingsRepository.TdNotificationScope -import org.monogram.domain.repository.StringProvider - - -class SettingsRepositoryImpl( - private val remote: SettingsRemoteDataSource, - private val cache: SettingsCacheDataSource, - private val chatsRemote: ChatsRemoteDataSource, - private val updates: UpdateDispatcher, - private val appPreferences: AppPreferencesProvider, - private val cacheProvider: CacheProvider, - scopeProvider: ScopeProvider, - private val dispatchers: DispatcherProvider, - private val attachBotDao: AttachBotDao, - private val keyValueDao: KeyValueDao, - private val wallpaperDao: WallpaperDao, - private val storageMapper: StorageMapper, - private val stringProvider: StringProvider, - private val networkMapper: NetworkMapper -) : SettingsRepository { - - private val scope = scopeProvider.appScope - - private val _wallpaperUpdates = MutableSharedFlow(extraBufferCapacity = 1) - private val _attachMenuBots = MutableStateFlow>(cacheProvider.attachBots.value) - private val _wallpapers = MutableStateFlow>(emptyList()) - - override val autoDownloadMobile = appPreferences.autoDownloadMobile - override val autoDownloadWifi = appPreferences.autoDownloadWifi - override val autoDownloadRoaming = appPreferences.autoDownloadRoaming - override val autoDownloadFiles = appPreferences.autoDownloadFiles - override val autoDownloadStickers = appPreferences.autoDownloadStickers - override val autoDownloadVideoNotes = appPreferences.autoDownloadVideoNotes - - init { - scope.launch { - updates.newChat.collect { update -> cache.putChat(update.chat) } - } - scope.launch { - updates.chatTitle.collect { update -> - cache.getChat(update.chatId)?.let { chat -> - synchronized(chat) { chat.title = update.title } - } - } - } - scope.launch { - updates.chatPhoto.collect { update -> - cache.getChat(update.chatId)?.let { chat -> - synchronized(chat) { chat.photo = update.photo } - } - } - } - scope.launch { - updates.chatNotificationSettings.collect { update -> - cache.getChat(update.chatId)?.let { chat -> - synchronized(chat) { chat.notificationSettings = update.notificationSettings } - } - } - } - scope.launch { - updates.attachmentMenuBots.collect { update -> - cache.putAttachMenuBots(update.bots) - val bots = update.bots.map { it.toDomain() } - _attachMenuBots.value = bots - cacheProvider.setAttachBots(bots) - - saveAttachBotsToDb(bots) - - update.bots.forEach { bot -> - bot.androidSideMenuIcon?.let { icon -> - if (icon.local.path.isEmpty()) { - remote.downloadFile(icon.id, 1) - } - } - } - } - } - scope.launch { - updates.file.collect { update -> - _wallpaperUpdates.emit(Unit) - - val currentBots = _attachMenuBots.value - if (currentBots.any { it.icon?.icon?.id == update.file.id }) { - cache.getAttachMenuBots()?.let { bots -> - val domainBots = bots.map { it.toDomain() } - _attachMenuBots.value = domainBots - cacheProvider.setAttachBots(domainBots) - saveAttachBotsToDb(domainBots) - } - } - } - } - - scope.launch { - attachBotDao.getAttachBots().collect { entities -> - val bots = entities.mapNotNull { - try { - Json.decodeFromString(it.data) - } catch (e: Exception) { - null - } - } - if (bots.isNotEmpty()) { - _attachMenuBots.value = bots - cacheProvider.setAttachBots(bots) - } - } - } - - scope.launch { - keyValueDao.observeValue("cached_sim_country_iso").collect { entity -> - cacheProvider.setCachedSimCountryIso(entity?.value) - } - } - - scope.launch { - wallpaperDao.getWallpapers().collect { entities -> - val wallpapers = entities.mapNotNull { - try { - Json.decodeFromString(it.data) - } catch (e: Exception) { - null - } - } - if (wallpapers.isNotEmpty()) { - _wallpapers.value = wallpapers - } - } - } - } - - private suspend fun saveAttachBotsToDb(bots: List) { - withContext(dispatchers.io) { - attachBotDao.clearAll() - attachBotDao.insertAttachBots(bots.map { - AttachBotEntity(it.botUserId, Json.encodeToString(it)) - }) - } - } - - private suspend fun saveWallpapersToDb(wallpapers: List) { - withContext(dispatchers.io) { - wallpaperDao.clearAll() - wallpaperDao.insertWallpapers(wallpapers.map { - WallpaperEntity(it.id, Json.encodeToString(it)) - }) - } - } - - override fun setAutoDownloadMobile(enabled: Boolean) = appPreferences.setAutoDownloadMobile(enabled) - override fun setAutoDownloadWifi(enabled: Boolean) = appPreferences.setAutoDownloadWifi(enabled) - override fun setAutoDownloadRoaming(enabled: Boolean) = appPreferences.setAutoDownloadRoaming(enabled) - override fun setAutoDownloadFiles(enabled: Boolean) = appPreferences.setAutoDownloadFiles(enabled) - override fun setAutoDownloadStickers(enabled: Boolean) = appPreferences.setAutoDownloadStickers(enabled) - override fun setAutoDownloadVideoNotes(enabled: Boolean) = appPreferences.setAutoDownloadVideoNotes(enabled) - - override suspend fun getNotificationSettings(scope: TdNotificationScope): Boolean { - val result = remote.getScopeNotificationSettings(scope.toApi()) - return result?.muteFor == 0 - } - - override suspend fun setNotificationSettings(scope: TdNotificationScope, enabled: Boolean) { - val settings = TdApi.ScopeNotificationSettings().apply { - muteFor = if (enabled) 0 else Int.MAX_VALUE - useDefaultMuteStories = false - } - remote.setScopeNotificationSettings(scope.toApi(), settings) - } - - override suspend fun getExceptions(scope: TdNotificationScope): List = coroutineScope { - val chats = remote.getChatNotificationSettingsExceptions(scope.toApi(), true) - chats?.chatIds?.map { chatId -> - async(dispatchers.io) { - cache.getChat(chatId)?.toDomain() - ?: chatsRemote.getChat(chatId)?.also { cache.putChat(it) }?.toDomain() - } - }?.awaitAll()?.filterNotNull() ?: emptyList() - } - - override suspend fun setChatNotificationSettings(chatId: Long, enabled: Boolean) { - val settings = TdApi.ChatNotificationSettings().apply { - useDefaultMuteFor = false - muteFor = if (enabled) 0 else Int.MAX_VALUE - useDefaultSound = true - useDefaultShowPreview = true - useDefaultMuteStories = true - } - remote.setChatNotificationSettings(chatId, settings) - } - - override suspend fun resetChatNotificationSettings(chatId: Long) { - val settings = TdApi.ChatNotificationSettings().apply { - useDefaultMuteFor = true - useDefaultSound = true - useDefaultShowPreview = true - useDefaultMuteStories = true - } - remote.setChatNotificationSettings(chatId, settings) - } - - override fun getAttachMenuBots(): Flow> { - return _attachMenuBots - } - - override suspend fun setCachedSimCountryIso(iso: String?) { - withContext(dispatchers.io) { - if (iso != null) { - keyValueDao.insertValue(KeyValueEntity("cached_sim_country_iso", iso)) - } else { - keyValueDao.deleteValue("cached_sim_country_iso") - } - } - } - - override suspend fun getActiveSessions(): List { - return remote.getActiveSessions()?.sessions?.map { it.toDomain() } ?: emptyList() - } - - override suspend fun terminateSession(sessionId: Long): Boolean = - remote.terminateSession(sessionId) - - override suspend fun confirmQrCode(link: String): Boolean = - remote.confirmQrCode(link) - - override fun getWallpapers(): Flow> = callbackFlow { - suspend fun fetch() { - val result = remote.getInstalledBackgrounds(false) - val wallpapers = mapBackgrounds(result?.backgrounds ?: emptyArray()) - _wallpapers.value = wallpapers - saveWallpapersToDb(wallpapers) - trySend(wallpapers) - } - - val wallpaperJob = _wallpaperUpdates - .onEach { fetch() } - .launchIn(this) - - if (_wallpapers.value.isNotEmpty()) { - trySend(_wallpapers.value) - } else { - fetch() - } - awaitClose { wallpaperJob.cancel() } - } - - override suspend fun downloadWallpaper(fileId: Int) { - remote.downloadFile(fileId, 1) - } - - override suspend fun getStorageUsage(): StorageUsageModel? = coroutineScope { - val stats = remote.getStorageStatistics(100) ?: return@coroutineScope null - val processed_chats = (stats.byChat ?: emptyArray()).map { chatStat -> - async(dispatchers.default) { - val title = when { - chatStat.chatId == 0L -> stringProvider.getString("storage_other_cache") - else -> cache.getChat(chatStat.chatId)?.title - ?: chatsRemote.getChat(chatStat.chatId)?.title - ?: stringProvider.getString("storage_chat_format", chatStat.chatId) - } - storageMapper.mapChatStatsToDomain(chatStat, title) - } - }.awaitAll() - storageMapper.mapToDomain(stats, processed_chats) - } - - override suspend fun getNetworkUsage(): NetworkUsageModel? = - remote.getNetworkStatistics()?.let { networkMapper.mapToDomain(it) } - - override suspend fun clearStorage(chatId: Long?): Boolean = - remote.optimizeStorage( - size = 0, - ttl = 0, - count = 0, - immunityDelay = 0, - chatIds = chatId?.let { longArrayOf(it) }, - returnDeletedFileStatistics = false, - chatLimit = 20 - ) - - override suspend fun resetNetworkStatistics(): Boolean = - remote.resetNetworkStatistics() - - override suspend fun setDatabaseMaintenanceSettings( - maxDatabaseSize: Long, - maxTimeFromLastAccess: Int - ): Boolean = - remote.optimizeStorage( - size = maxDatabaseSize, - ttl = maxTimeFromLastAccess, - count = -1, - immunityDelay = -1, - chatIds = null, - returnDeletedFileStatistics = true, - chatLimit = 0 - ) - - override suspend fun getNetworkStatisticsEnabled(): Boolean { - val result = remote.getOption("disable_network_statistics") - return if (result is TdApi.OptionValueBoolean) !result.value else true - } - - override suspend fun setNetworkStatisticsEnabled(enabled: Boolean) { - remote.setOption("disable_network_statistics", TdApi.OptionValueBoolean(!enabled)) - remote.setOption("disable_persistent_network_statistics", TdApi.OptionValueBoolean(!enabled)) - } - - override suspend fun getStorageOptimizerEnabled(): Boolean { - val result = remote.getOption("use_storage_optimizer") - return if (result is TdApi.OptionValueBoolean) result.value else false - } - - override suspend fun setStorageOptimizerEnabled(enabled: Boolean) { - remote.setOption("use_storage_optimizer", TdApi.OptionValueBoolean(enabled)) - } -} diff --git a/data/src/main/java/org/monogram/data/repository/StickerRepositoryImpl.kt b/data/src/main/java/org/monogram/data/repository/StickerRepositoryImpl.kt deleted file mode 100644 index 7b4d6b46..00000000 --- a/data/src/main/java/org/monogram/data/repository/StickerRepositoryImpl.kt +++ /dev/null @@ -1,529 +0,0 @@ -package org.monogram.data.repository - -import org.monogram.data.core.coRunCatching -import android.content.Context -import android.util.Log -import kotlinx.coroutines.* -import kotlinx.coroutines.flow.* -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import kotlinx.serialization.json.Json -import org.drinkless.tdlib.TdApi -import org.monogram.core.DispatcherProvider -import org.monogram.core.ScopeProvider -import org.monogram.data.datasource.remote.StickerRemoteSource -import org.monogram.data.db.dao.RecentEmojiDao -import org.monogram.data.db.dao.StickerPathDao -import org.monogram.data.db.dao.StickerSetDao -import org.monogram.data.db.model.RecentEmojiEntity -import org.monogram.data.db.model.StickerPathEntity -import org.monogram.data.db.model.StickerSetEntity -import org.monogram.data.gateway.UpdateDispatcher -import org.monogram.data.infra.EmojiLoader -import org.monogram.data.infra.FileDownloadQueue -import org.monogram.data.infra.FileUpdateHandler -import org.monogram.domain.models.* -import org.monogram.domain.repository.CacheProvider -import org.monogram.domain.repository.StickerRepository -import java.io.File -import java.io.FileInputStream -import java.util.concurrent.ConcurrentHashMap -import java.util.zip.GZIPInputStream - -class StickerRepositoryImpl( - private val remote: StickerRemoteSource, - private val fileQueue: FileDownloadQueue, - private val fileUpdateHandler: FileUpdateHandler, - private val updates: UpdateDispatcher, - private val cacheProvider: CacheProvider, - private val dispatchers: DispatcherProvider, - private val context: Context, - private val stickerSetDao: StickerSetDao, - private val recentEmojiDao: RecentEmojiDao, - private val stickerPathDao: StickerPathDao, - scopeProvider: ScopeProvider -) : StickerRepository { - - private val scope = scopeProvider.appScope - - override val installedStickerSets: StateFlow> = cacheProvider.installedStickerSets - override val customEmojiStickerSets: StateFlow> = cacheProvider.customEmojiStickerSets - - private val _archivedStickerSets = MutableStateFlow>(emptyList()) - override val archivedStickerSets = _archivedStickerSets.asStateFlow() - - private val _archivedEmojiSets = MutableStateFlow>(emptyList()) - override val archivedEmojiSets = _archivedEmojiSets.asStateFlow() - - private val regularMutex = Mutex() - private val customEmojiMutex = Mutex() - private val archivedMutex = Mutex() - private val archivedEmojiMutex = Mutex() - - @Volatile - private var lastRegularLoadTime = 0L - @Volatile - private var lastCustomEmojiLoadTime = 0L - - override val recentEmojis: Flow> = cacheProvider.recentEmojis - - private val tgsCache = mutableMapOf() - private val filePathsCache = ConcurrentHashMap() - private var cachedEmojis: List? = null - private var fallbackEmojisCache: List? = null - - init { - scope.launch { - updates.installedStickerSets.collect { update -> - when (update.stickerType) { - is TdApi.StickerTypeRegular -> loadInstalledStickerSets(force = true) - is TdApi.StickerTypeCustomEmoji -> loadCustomEmojiStickerSets(force = true) - } - } - } - - scope.launch { - stickerSetDao.getInstalledStickerSetsByType("REGULAR").collect { entities -> - if (installedStickerSets.value.isEmpty()) { - val sets = entities.mapNotNull { it.toModel() } - if (sets.isNotEmpty()) cacheProvider.setInstalledStickerSets(sets) - } - } - } - - scope.launch { - recentEmojiDao.getRecentEmojis().collect { entities -> - val models = entities.mapNotNull { - try { - Json.decodeFromString(it.data) - } catch (e: Exception) { - null - } - } - cacheProvider.setRecentEmojis(models) - } - } - - scope.launch(dispatchers.default) { - delay(60_000L) - while (isActive) { - coRunCatching { verifyInstalledStickerSets() } - .onFailure { Log.w("StickerRepo", "verifyInstalledStickerSets failed", it) } - delay(120_000L) - } - } - } - - override suspend fun loadInstalledStickerSets() = loadInstalledStickerSets(force = false) - - private suspend fun loadInstalledStickerSets(force: Boolean) = regularMutex.withLock { - val now = System.currentTimeMillis() - if (!force && installedStickerSets.value.isNotEmpty()) return@withLock - if (force && installedStickerSets.value.isNotEmpty() && now - lastRegularLoadTime < 1000) return@withLock - - val sets = remote.getInstalledStickerSets(StickerType.REGULAR) - if (force && installedStickerSets.value.map { it.id } == sets.map { it.id }) { - lastRegularLoadTime = System.currentTimeMillis() - return@withLock - } - - cacheProvider.setInstalledStickerSets(sets) - saveStickerSetsToDb(sets, "REGULAR", isInstalled = true, isArchived = false) - lastRegularLoadTime = System.currentTimeMillis() - } - - override suspend fun loadCustomEmojiStickerSets() = loadCustomEmojiStickerSets(force = false) - - private suspend fun loadCustomEmojiStickerSets(force: Boolean) = customEmojiMutex.withLock { - val now = System.currentTimeMillis() - - if (!force && customEmojiStickerSets.value.isNotEmpty()) { - val hasMissingCustomEmojiIds = customEmojiStickerSets.value.any { set -> - set.stickerType == StickerType.CUSTOM_EMOJI && set.stickers.any { it.customEmojiId == null } - } - val needsRefresh = lastCustomEmojiLoadTime == 0L || (now - lastCustomEmojiLoadTime) > 10 * 60 * 1000 - if (!hasMissingCustomEmojiIds && !needsRefresh) return@withLock - } - if (force && customEmojiStickerSets.value.isNotEmpty() && now - lastCustomEmojiLoadTime < 1000) return@withLock - - val sets = remote.getInstalledStickerSets(StickerType.CUSTOM_EMOJI) - if (sets.isNotEmpty()) { - if (force && customEmojiStickerSets.value.map { it.id } == sets.map { it.id }) { - lastCustomEmojiLoadTime = System.currentTimeMillis() - return@withLock - } - - cacheProvider.setCustomEmojiStickerSets(sets) - saveStickerSetsToDb(sets, "CUSTOM_EMOJI", isInstalled = true, isArchived = false) - lastCustomEmojiLoadTime = System.currentTimeMillis() - return@withLock - } - - if (customEmojiStickerSets.value.isEmpty()) { - val cached = stickerSetDao.getInstalledStickerSetsByType("CUSTOM_EMOJI").first().mapNotNull { it.toModel() } - if (cached.isNotEmpty()) { - cacheProvider.setCustomEmojiStickerSets(cached) - } - } - lastCustomEmojiLoadTime = System.currentTimeMillis() - } - - private suspend fun saveStickerSetsToDb( - sets: List, - type: String, - isInstalled: Boolean, - isArchived: Boolean - ) { - withContext(dispatchers.io) { - stickerSetDao.deleteStickerSets(type, isInstalled, isArchived) - stickerSetDao.insertStickerSets(sets.map { it.toEntity(type) }) - } - } - - override suspend fun loadArchivedStickerSets() = archivedMutex.withLock { - val cached = stickerSetDao.getArchivedStickerSetsByType("REGULAR").first().mapNotNull { it.toModel() } - if (cached.isNotEmpty()) _archivedStickerSets.value = cached - - val remoteSets = remote.getArchivedStickerSets(StickerType.REGULAR) - _archivedStickerSets.value = remoteSets - saveStickerSetsToDb(remoteSets, "REGULAR", isInstalled = false, isArchived = true) - } - - override suspend fun loadArchivedEmojiSets() = archivedEmojiMutex.withLock { - val cached = stickerSetDao.getArchivedStickerSetsByType("CUSTOM_EMOJI").first().mapNotNull { it.toModel() } - if (cached.isNotEmpty()) _archivedEmojiSets.value = cached - - val remoteSets = remote.getArchivedStickerSets(StickerType.CUSTOM_EMOJI) - _archivedEmojiSets.value = remoteSets - saveStickerSetsToDb(remoteSets, "CUSTOM_EMOJI", isInstalled = false, isArchived = true) - } - - override suspend fun getStickerSet(setId: Long): StickerSetModel? { - val cached = stickerSetDao.getStickerSetById(setId)?.toModel() - if (cached != null) { - prefetchStickers(cached.stickers) - scope.launch(dispatchers.default) { verifyStickerSet(cached.id) } - return cached - } - - val remoteSet = remote.getStickerSet(setId) ?: return null - withContext(dispatchers.io) { - stickerSetDao.insertStickerSet(remoteSet.toEntity(remoteSet.stickerType.name)) - } - prefetchStickers(remoteSet.stickers) - scope.launch(dispatchers.default) { verifyStickerSet(remoteSet.id) } - return remoteSet - } - - override suspend fun getStickerSetByName(name: String): StickerSetModel? { - val cached = stickerSetDao.getStickerSetByName(name)?.toModel() - if (cached != null) { - prefetchStickers(cached.stickers) - scope.launch(dispatchers.default) { verifyStickerSet(cached.id) } - return cached - } - - val remoteSet = remote.getStickerSetByName(name) ?: return null - withContext(dispatchers.io) { - stickerSetDao.insertStickerSet(remoteSet.toEntity(remoteSet.stickerType.name)) - } - prefetchStickers(remoteSet.stickers) - scope.launch(dispatchers.default) { verifyStickerSet(remoteSet.id) } - return remoteSet - } - - override suspend fun verifyStickerSet(setId: Long) { - val set = stickerSetDao.getStickerSetById(setId)?.toModel() ?: remote.getStickerSet(setId) ?: return - val missing = mutableListOf() - - for (sticker in set.stickers) { - if (!isStickerFileAvailable(sticker.id)) { - missing += sticker.id - } - } - - if (missing.isEmpty()) return - - Log.d("StickerRepo", "verifyStickerSet($setId): missing ${missing.size}/${set.stickers.size}") - missing.forEach { stickerId -> - fileQueue.enqueue(stickerId.toInt(), 32, FileDownloadQueue.DownloadType.STICKER) - } - } - - override suspend fun toggleStickerSetInstalled(setId: Long, isInstalled: Boolean) { - remote.toggleStickerSetInstalled(setId, isInstalled) - invalidateStickerSetCaches() - } - - override suspend fun toggleStickerSetArchived(setId: Long, isArchived: Boolean) { - remote.toggleStickerSetArchived(setId, isArchived) - invalidateStickerSetCaches() - scope.launch { - loadArchivedStickerSets() - loadArchivedEmojiSets() - } - } - - override suspend fun reorderStickerSets( - stickerType: StickerRepository.TdLibStickerType, - stickerSetIds: List - ) { - val type = when (stickerType) { - StickerRepository.TdLibStickerType.REGULAR -> StickerType.REGULAR - StickerRepository.TdLibStickerType.CUSTOM_EMOJI -> StickerType.CUSTOM_EMOJI - StickerRepository.TdLibStickerType.MASK -> StickerType.MASK - } - remote.reorderStickerSets(type, stickerSetIds) - } - - override suspend fun getDefaultEmojis(): List { - cachedEmojis?.let { return it } - - val fetched = remote.getEmojiCategories().toMutableSet() - if (fetched.size < 100) fetched.addAll(getFallbackEmojis()) - - return fetched.toList().also { cachedEmojis = it } - } - - override suspend fun searchEmojis(query: String) = remote.searchEmojis(query) - - override suspend fun searchCustomEmojis(query: String) = remote.searchCustomEmojis(query) - - override suspend fun getMessageAvailableReactions(chatId: Long, messageId: Long) = - remote.getMessageAvailableReactions(chatId, messageId) - - override suspend fun getRecentStickers() = remote.getRecentStickers() - - override suspend fun clearRecentStickers() = remote.clearRecentStickers() - - override suspend fun searchStickers(query: String) = remote.searchStickers(query) - - override suspend fun searchStickerSets(query: String) = remote.searchStickerSets(query) - - override suspend fun addRecentEmoji(recentEmoji: RecentEmojiModel) { - cacheProvider.addRecentEmoji(recentEmoji) - withContext(dispatchers.io) { - recentEmojiDao.deleteRecentEmoji(recentEmoji.emoji, recentEmoji.sticker?.id) - recentEmojiDao.insertRecentEmoji( - RecentEmojiEntity( - emoji = recentEmoji.emoji, - stickerId = recentEmoji.sticker?.id, - data = Json.encodeToString(recentEmoji) - ) - ) - } - } - - override suspend fun clearRecentEmojis() { - cacheProvider.clearRecentEmojis() - withContext(dispatchers.io) { - recentEmojiDao.clearAll() - } - } - - override suspend fun getSavedGifs(): List { - val cached = cacheProvider.savedGifs.value - if (cached.isNotEmpty()) return cached - - val remoteGifs = remote.getSavedGifs() - cacheProvider.setSavedGifs(remoteGifs) - return remoteGifs - } - - override suspend fun addSavedGif(path: String) { - remote.addSavedGif(path) - val remoteGifs = remote.getSavedGifs() - cacheProvider.setSavedGifs(remoteGifs) - } - - override suspend fun searchGifs(query: String) = remote.searchGifs(query) - - override fun getStickerFile(fileId: Long): Flow = flow { - filePathsCache[fileId]?.let { path -> - if (path.isNotEmpty() && File(path).exists()) { - emit(path) - return@flow - } - filePathsCache.remove(fileId) - stickerPathDao.deletePath(fileId) - } - - val dbPath = stickerPathDao.getPath(fileId) - if (!dbPath.isNullOrEmpty()) { - if (File(dbPath).exists()) { - filePathsCache[fileId] = dbPath - emit(dbPath) - return@flow - } - stickerPathDao.deletePath(fileId) - } - - val cachedPath = fileUpdateHandler.fileDownloadCompleted - .replayCache - .firstOrNull { it.first == fileId && it.second.isNotEmpty() && File(it.second).exists() } - ?.second - - if (cachedPath != null) { - filePathsCache[fileId] = cachedPath - stickerPathDao.insertPath(StickerPathEntity(fileId, cachedPath)) - emit(cachedPath) - return@flow - } - - fileQueue.enqueue(fileId.toInt(), 32, FileDownloadQueue.DownloadType.STICKER) - - val firstPath = withTimeoutOrNull(90_000L) { - fileUpdateHandler.fileDownloadCompleted - .filter { it.first == fileId } - .mapNotNull { (_, path) -> path.takeIf { it.isNotEmpty() && File(it).exists() } } - .first() - } - - val resultPath = firstPath ?: fileUpdateHandler.fileDownloadCompleted - .replayCache - .firstOrNull { it.first == fileId && it.second.isNotEmpty() && File(it.second).exists() } - ?.second - - if (!resultPath.isNullOrEmpty()) { - filePathsCache[fileId] = resultPath - stickerPathDao.insertPath(StickerPathEntity(fileId, resultPath)) - emit(resultPath) - } else { - fileQueue.enqueue(fileId.toInt(), 32, FileDownloadQueue.DownloadType.STICKER) - } - } - - private fun prefetchStickers(stickers: List) { - scope.launch(dispatchers.default) { - stickers.take(20).forEach { sticker -> - val cachedPath = filePathsCache[sticker.id] - if (!cachedPath.isNullOrEmpty() && !File(cachedPath).exists()) { - filePathsCache.remove(sticker.id) - stickerPathDao.deletePath(sticker.id) - } - - val dbPath = stickerPathDao.getPath(sticker.id) - val hasValidDbPath = !dbPath.isNullOrEmpty() && File(dbPath).exists() - if (!dbPath.isNullOrEmpty() && !hasValidDbPath) { - stickerPathDao.deletePath(sticker.id) - } - - if (filePathsCache[sticker.id].isNullOrEmpty() && !hasValidDbPath) { - fileQueue.enqueue(sticker.id.toInt(), 16, FileDownloadQueue.DownloadType.STICKER) - } - } - } - } - - private suspend fun verifyInstalledStickerSets() { - val allSets = installedStickerSets.value + customEmojiStickerSets.value - var requeued = 0 - val maxPerPass = 50 - - for (set in allSets) { - for (sticker in set.stickers) { - if (requeued >= maxPerPass) break - if (isStickerFileAvailable(sticker.id)) continue - - fileQueue.enqueue(sticker.id.toInt(), 8, FileDownloadQueue.DownloadType.STICKER) - requeued++ - } - if (requeued >= maxPerPass) break - } - - if (requeued > 0) { - Log.d("StickerRepo", "verifyInstalledStickerSets: re-enqueued $requeued stickers") - } - } - - private suspend fun isStickerFileAvailable(stickerId: Long): Boolean { - val memoryPath = filePathsCache[stickerId] - if (!memoryPath.isNullOrEmpty()) { - if (File(memoryPath).exists()) { - return true - } - filePathsCache.remove(stickerId) - stickerPathDao.deletePath(stickerId) - } - - val dbPath = stickerPathDao.getPath(stickerId) - if (!dbPath.isNullOrEmpty()) { - if (File(dbPath).exists()) { - filePathsCache[stickerId] = dbPath - return true - } - stickerPathDao.deletePath(stickerId) - } - - val completedPath = fileUpdateHandler.fileDownloadCompleted.replayCache - .firstOrNull { it.first == stickerId && it.second.isNotEmpty() && File(it.second).exists() } - ?.second - if (!completedPath.isNullOrEmpty()) { - filePathsCache[stickerId] = completedPath - stickerPathDao.insertPath(StickerPathEntity(stickerId, completedPath)) - return true - } - - return false - } - - override fun getGifFile(gif: GifModel): Flow = flow { - if (gif.fileId == 0L) { - emit(null); return@flow - } - getStickerFile(gif.fileId).collect { emit(it) } - } - - override suspend fun getTgsJson(path: String): String? = withContext(dispatchers.io) { - tgsCache[path]?.let { return@withContext it } - coRunCatching { - val file = File(path) - if (!file.exists() || file.length() == 0L) return@withContext null - GZIPInputStream(FileInputStream(file)) - .bufferedReader() - .use { it.readText() } - .also { tgsCache[path] = it } - }.getOrNull() - } - - override fun clearCache() { - tgsCache.clear() - filePathsCache.clear() - cachedEmojis = null - fallbackEmojisCache = null - invalidateStickerSetCaches() - scope.launch { - stickerPathDao.clearAll() - } - } - - private fun invalidateStickerSetCaches() { - cacheProvider.setInstalledStickerSets(emptyList()) - cacheProvider.setCustomEmojiStickerSets(emptyList()) - lastRegularLoadTime = 0 - lastCustomEmojiLoadTime = 0 - scope.launch { - stickerSetDao.clearAll() - } - } - - private suspend fun getFallbackEmojis(): List = withContext(dispatchers.default) { - fallbackEmojisCache?.let { return@withContext it } - EmojiLoader.getSupportedEmojis(context).also { fallbackEmojisCache = it } - } - - private fun StickerSetModel.toEntity(type: String) = StickerSetEntity( - id = id, - name = name, - type = type, - isInstalled = isInstalled, - isArchived = isArchived, - data = Json.encodeToString(this) - ) - - private fun StickerSetEntity.toModel(): StickerSetModel? = try { - Json.decodeFromString(data) - } catch (e: Exception) { - null - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/repository/StreamingRepositoryImpl.kt b/data/src/main/java/org/monogram/data/repository/StreamingRepositoryImpl.kt deleted file mode 100644 index 9544d3f1..00000000 --- a/data/src/main/java/org/monogram/data/repository/StreamingRepositoryImpl.kt +++ /dev/null @@ -1,49 +0,0 @@ -package org.monogram.data.repository - -import androidx.media3.datasource.DataSource -import org.monogram.core.ScopeProvider -import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.flow.* -import org.monogram.data.datasource.FileDataSource -import kotlinx.coroutines.launch -import org.monogram.data.datasource.TelegramStreamingDataSource -import org.monogram.data.gateway.UpdateDispatcher -import org.monogram.domain.repository.PlayerDataSourceFactory -import org.monogram.domain.repository.StreamingRepository - -class StreamingRepositoryImpl( - private val fileDataSource: FileDataSource, - private val updates: UpdateDispatcher, - scopeProvider: ScopeProvider -) : StreamingRepository, PlayerDataSourceFactory { - - private val scope = scopeProvider.appScope - - private val _fileProgressFlow = MutableSharedFlow>( - replay = 1, - extraBufferCapacity = 100, - onBufferOverflow = BufferOverflow.DROP_OLDEST - ) - - init { - scope.launch { - updates.file.collect { update -> - val file = update.file - if (file.size > 0) { - val progress = file.local.downloadedSize.toFloat() / file.size.toFloat() - _fileProgressFlow.emit(file.id to progress) - } - } - } - } - - override fun createPayload(fileId: Int): DataSource.Factory { - return TelegramStreamingDataSource.Factory(fileDataSource, fileId) - } - - override fun getDownloadProgress(fileId: Int): Flow { - return _fileProgressFlow - .filter { it.first == fileId } - .map { it.second } - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/repository/UpdateRepositoryImpl.kt b/data/src/main/java/org/monogram/data/repository/UpdateRepositoryImpl.kt deleted file mode 100644 index 4efbb88a..00000000 --- a/data/src/main/java/org/monogram/data/repository/UpdateRepositoryImpl.kt +++ /dev/null @@ -1,162 +0,0 @@ -package org.monogram.data.repository - -import org.monogram.data.core.coRunCatching -import android.app.PendingIntent -import android.content.Context -import android.content.Intent -import android.content.pm.PackageInstaller -import android.os.Build -import android.util.Log -import androidx.core.content.FileProvider -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.launch -import org.monogram.core.ScopeProvider -import org.monogram.data.datasource.remote.UpdateRemoteDateSource -import org.monogram.data.infra.FileDownloadQueue -import org.monogram.data.infra.FileUpdateHandler -import org.monogram.data.service.UpdateInstallReceiver -import org.monogram.domain.models.UpdateInfo -import org.monogram.domain.models.UpdateState -import org.monogram.domain.repository.AuthRepository -import org.monogram.domain.repository.AuthStep -import org.monogram.domain.repository.UpdateRepository -import java.io.File -import java.io.FileInputStream - -class UpdateRepositoryImpl( - private val context: Context, - private val remote: UpdateRemoteDateSource, - private val fileQueue: FileDownloadQueue, - private val fileUpdateHandler: FileUpdateHandler, - private val authRepository: AuthRepository, - scopeProvider: ScopeProvider -) : UpdateRepository { - - private val scope = scopeProvider.appScope - - private val _updateState = MutableStateFlow(UpdateState.Idle) - override val updateState: StateFlow = _updateState.asStateFlow() - - private var currentUpdateInfo: UpdateInfo? = null - - init { - scope.launch { - fileUpdateHandler.fileDownloadProgress.collect { (id, progress) -> - val info = currentUpdateInfo ?: return@collect - val current = _updateState.value - if (info.fileId.toLong() == id && - (current is UpdateState.Downloading || current is UpdateState.UpdateAvailable) - ) { - _updateState.value = UpdateState.Downloading(progress, info.fileSize) - } - } - } - - scope.launch { - fileUpdateHandler.fileDownloadCompleted.collect { (id, path) -> - val info = currentUpdateInfo ?: return@collect - if (info.fileId.toLong() == id) { - _updateState.value = UpdateState.ReadyToInstall(path) - } - } - } - } - - override suspend fun checkForUpdates() { - if (authRepository.authState.value !is AuthStep.Ready) return - - _updateState.value = UpdateState.Checking - - coRunCatching { - val info = remote.fetchLatestUpdate() ?: return@coRunCatching _updateState.value.let { - _updateState.value = UpdateState.Error("No update found") - } - - val currentVersionCode = try { - context.packageManager.getPackageInfo(context.packageName, 0).versionCode - } catch (e: Exception) { - 0 - } - - Log.d("UpdateRepository", "Current version code: $currentVersionCode, Latest version code: ${info.versionCode}") - - if (info.versionCode <= currentVersionCode) { - _updateState.value = UpdateState.UpToDate - return@coRunCatching - } - - currentUpdateInfo = info - _updateState.value = UpdateState.UpdateAvailable(info) - }.onFailure { - _updateState.value = UpdateState.Error(it.message ?: "Failed to check for updates") - } - } - - override fun downloadUpdate() { - val info = currentUpdateInfo ?: return - _updateState.value = UpdateState.Downloading(0f, info.fileSize) - fileQueue.enqueue( - fileId = info.fileId, - priority = 32, - type = FileDownloadQueue.DownloadType.DEFAULT, - synchronous = true - ) - } - - override fun cancelDownload() { - val info = currentUpdateInfo ?: return - fileQueue.cancelDownload(info.fileId, force = true) - _updateState.value = UpdateState.UpdateAvailable(info) - } - - override fun installUpdate() { - val state = _updateState.value as? UpdateState.ReadyToInstall ?: return - val file = File(state.filePath) - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - try { - val packageInstaller = context.packageManager.packageInstaller - val params = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL) - .apply { - setRequireUserAction(PackageInstaller.SessionParams.USER_ACTION_NOT_REQUIRED) - } - - val sessionId = packageInstaller.createSession(params) - val session = packageInstaller.openSession(sessionId) - - FileInputStream(file).use { input -> - session.openWrite("package", 0, file.length()).use { output -> - input.copyTo(output) - session.fsync(output) - } - } - - val intent = Intent(context, UpdateInstallReceiver::class.java) - val pendingIntent = PendingIntent.getBroadcast( - context, 0, intent, - PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT - ) - session.commit(pendingIntent.intentSender) - session.close() - return - } catch (e: Exception) { - Log.e("UpdateRepository", "PackageInstaller flow failed, using fallback", e) - } - } - - val uri = FileProvider.getUriForFile(context, "${context.packageName}.provider", file) - context.startActivity( - Intent(Intent.ACTION_INSTALL_PACKAGE).apply { - data = uri - addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - ) - } - - override suspend fun getTdLibVersion() = remote.getTdLibVersion() - - override suspend fun getTdLibCommitHash() = remote.getTdLibCommitHash() -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/repository/UserRepositoryImpl.kt b/data/src/main/java/org/monogram/data/repository/UserRepositoryImpl.kt deleted file mode 100644 index 95b212f3..00000000 --- a/data/src/main/java/org/monogram/data/repository/UserRepositoryImpl.kt +++ /dev/null @@ -1,869 +0,0 @@ -package org.monogram.data.repository - -import kotlinx.coroutines.* -import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.flow.* -import org.drinkless.tdlib.TdApi -import org.monogram.core.ScopeProvider -import org.monogram.data.core.coRunCatching -import org.monogram.data.datasource.cache.ChatLocalDataSource -import org.monogram.data.datasource.cache.RoomUserLocalDataSource -import org.monogram.data.datasource.cache.UserLocalDataSource -import org.monogram.data.datasource.remote.UserRemoteDataSource -import org.monogram.data.db.dao.KeyValueDao -import org.monogram.data.db.model.KeyValueEntity -import org.monogram.data.gateway.TelegramGateway -import org.monogram.data.gateway.UpdateDispatcher -import org.monogram.data.infra.FileDownloadQueue -import org.monogram.data.infra.SponsorSyncManager -import org.monogram.data.mapper.user.* -import org.monogram.domain.models.* -import org.monogram.domain.repository.ChatMemberStatus -import org.monogram.domain.repository.ChatMembersFilter -import org.monogram.domain.repository.UserRepository -import java.util.concurrent.ConcurrentHashMap - -class UserRepositoryImpl( - private val remote: UserRemoteDataSource, - private val userLocal: UserLocalDataSource, - private val chatLocal: ChatLocalDataSource, - private val gateway: TelegramGateway, - private val updates: UpdateDispatcher, - private val fileQueue: FileDownloadQueue, - private val keyValueDao: KeyValueDao, - private val sponsorSyncManager: SponsorSyncManager, - scopeProvider: ScopeProvider -) : UserRepository { - - private val scope = scopeProvider.appScope - private var currentUserId: Long = 0L - private val userRequests = ConcurrentHashMap>() - private val fullInfoRequests = ConcurrentHashMap>() - private val missingUsersUntilMs = ConcurrentHashMap() - private val missingUserFullInfoUntilMs = ConcurrentHashMap() - - private val emojiPathCache = ConcurrentHashMap() - private val fileIdToUserIdMap = ConcurrentHashMap() - private val avatarDownloadPriority = 24 - private val avatarFallbackPriority = 16 - - private val _currentUserFlow = MutableStateFlow(null) - override val currentUserFlow = _currentUserFlow.asStateFlow() - - private val _userUpdateFlow = MutableSharedFlow( - extraBufferCapacity = 10, - onBufferOverflow = BufferOverflow.DROP_OLDEST - ) - override val anyUserUpdateFlow = _userUpdateFlow.asSharedFlow() - - init { - scope.launch { - restoreCurrentUserFromLocal() - } - - scope.launch { - updates.user.collect { update -> - userLocal.putUser(update.user) - if (userLocal is RoomUserLocalDataSource) { - val personalAvatarPath = resolveStoredPersonalAvatarPath(update.user.id) - userLocal.saveUser(update.user.toEntity(personalAvatarPath)) - } - if (update.user.id == currentUserId) refreshCurrentUser() - _userUpdateFlow.emit(update.user.id) - } - } - scope.launch { - updates.userStatus.collect { update -> - userLocal.getUser(update.userId)?.let { cached -> - cached.status = update.status - if (userLocal is RoomUserLocalDataSource) { - val personalAvatarPath = resolveStoredPersonalAvatarPath(cached.id) - userLocal.saveUser(cached.toEntity(personalAvatarPath)) - } - if (update.userId == currentUserId) refreshCurrentUser() - _userUpdateFlow.emit(update.userId) - } - } - } - scope.launch { - updates.file.collect { update -> - val file = update.file - if (file.local.isDownloadingCompleted) { - userLocal.getAllUsers().forEach { user -> - val small = user.profilePhoto?.small - val big = user.profilePhoto?.big - if (small?.id == file.id || big?.id == file.id) { - _userUpdateFlow.emit(user.id) - if (user.id == currentUserId) refreshCurrentUser() - } - } - if (file.local.path.isNotEmpty()) { - val userId = fileIdToUserIdMap.remove(file.id) - if (userId != null) { - userLocal.getUser(userId)?.let { user -> - val emojiId = user.extractEmojiStatusId() - if (emojiId != 0L) { - emojiPathCache[emojiId] = file.local.path - } - } - _userUpdateFlow.emit(userId) - if (userId == currentUserId) refreshCurrentUser() - } - } - } - } - } - } - - private suspend fun restoreCurrentUserFromLocal() { - val cachedUserId = keyValueDao.getValue(KEY_CURRENT_USER_ID)?.value?.toLongOrNull() ?: return - if (cachedUserId <= 0L) return - - currentUserId = cachedUserId - val user = userLocal.getUser(cachedUserId) ?: return - val model = mapUserModel(user, userLocal.getUserFullInfo(cachedUserId)) - _currentUserFlow.value = model - } - - private fun TdApi.User.extractEmojiStatusId(): Long { - return when (val type = this.emojiStatus?.type) { - is TdApi.EmojiStatusTypeCustomEmoji -> type.customEmojiId - is TdApi.EmojiStatusTypeUpgradedGift -> type.modelCustomEmojiId - else -> 0L - } - } - - private suspend fun resolveEmojiPath(user: TdApi.User): String? { - val emojiId = user.extractEmojiStatusId() - if (emojiId == 0L) return null - - emojiPathCache[emojiId]?.let { return it } - - return try { - val result = gateway.execute(TdApi.GetCustomEmojiStickers(longArrayOf(emojiId))) - if (result is TdApi.Stickers && result.stickers.isNotEmpty()) { - val file = result.stickers.first().sticker - if (file.local.isDownloadingCompleted && file.local.path.isNotEmpty()) { - emojiPathCache[emojiId] = file.local.path - file.local.path - } else { - fileIdToUserIdMap[file.id] = user.id - fileQueue.enqueue(file.id, 1, FileDownloadQueue.DownloadType.DEFAULT, synchronous = false) - coRunCatching { fileQueue.waitForDownload(file.id).await() } - - val refreshedPath = coRunCatching { - (gateway.execute(TdApi.GetFile(file.id)) as? TdApi.File) - ?.local - ?.path - ?.takeIf { it.isNotEmpty() } - }.getOrNull() - if (refreshedPath != null) { - emojiPathCache[emojiId] = refreshedPath - } - refreshedPath - } - } else null - } catch (e: Exception) { - null - } - } - - private suspend fun refreshCurrentUser() { - val user = userLocal.getUser(currentUserId) ?: return - val model = mapUserModel(user, userLocal.getUserFullInfo(currentUserId)) - _currentUserFlow.value = model - } - - override suspend fun getMe(): UserModel { - val user = remote.getMe() ?: return UserModel(0, "Error") - currentUserId = user.id - coRunCatching { keyValueDao.insertValue(KeyValueEntity(KEY_CURRENT_USER_ID, user.id.toString())) } - userLocal.putUser(user) - if (userLocal is RoomUserLocalDataSource) { - val personalAvatarPath = resolveStoredPersonalAvatarPath(user.id) - userLocal.saveUser(user.toEntity(personalAvatarPath)) - } - val model = mapUserModel(user, userLocal.getUserFullInfo(user.id)) - _currentUserFlow.update { model } - return model - } - - override suspend fun getUser(userId: Long): UserModel? { - if (userId <= 0) return null - userLocal.getUser(userId)?.let { - return mapUserModel(it, userLocal.getUserFullInfo(userId)) - } - - if (userLocal is RoomUserLocalDataSource) { - userLocal.loadUser(userId)?.let { entity -> - val user = entity.toTdApi() - userLocal.putUser(user) - return mapUserModel(user, userLocal.getUserFullInfo(userId)) - } - } - - if (isNegativeCached(missingUsersUntilMs, userId)) return null - - val deferred = userRequests.getOrPut(userId) { - scope.async { - fetchAndCacheUser(userId)?.also { - userLocal.putUser(it) - if (userLocal is RoomUserLocalDataSource) { - val personalAvatarPath = resolveStoredPersonalAvatarPath(it.id) - userLocal.saveUser(it.toEntity(personalAvatarPath)) - } - } - } - } - return try { - deferred.await()?.let { user -> - mapUserModel(user, userLocal.getUserFullInfo(userId)) - } - } finally { - userRequests.remove(userId) - } - } - - override suspend fun getUserFullInfo(userId: Long): UserModel? { - if (userId <= 0) return null - val user = userLocal.getUser(userId) ?: fetchAndCacheUser(userId)?.also { - userLocal.putUser(it) - if (userLocal is RoomUserLocalDataSource) { - val personalAvatarPath = resolveStoredPersonalAvatarPath(it.id) - userLocal.saveUser(it.toEntity(personalAvatarPath)) - } - } ?: return null - - val cachedFullInfo = userLocal.getUserFullInfo(userId) - if (cachedFullInfo != null) return mapUserModel(user, cachedFullInfo) - - val dbFullInfo = userLocal.getFullInfoEntity(userId) - if (dbFullInfo != null) { - val fullInfo = dbFullInfo.toTdApi() - userLocal.putUserFullInfo(userId, fullInfo) - return mapUserModel(user, fullInfo) - } - - if (isNegativeCached(missingUserFullInfoUntilMs, userId)) { - return mapUserModel(user, null) - } - - val deferred = fullInfoRequests.getOrPut(userId) { - scope.async { - fetchAndCacheUserFullInfo(userId)?.also { - userLocal.putUserFullInfo(userId, it) - userLocal.saveFullInfoEntity(it.toEntity(userId)) - syncUserPersonalAvatarPath(userId, it) - } - } - } - return try { - val fullInfo = deferred.await() - mapUserModel(user, fullInfo) - } finally { - fullInfoRequests.remove(userId) - } - } - - private suspend fun mapUserModel(user: TdApi.User, fullInfo: TdApi.UserFullInfo?): UserModel { - val emojiPath = resolveEmojiPath(user) - val avatarPath = resolveAvatarPath(user) - val model = user.toDomain(fullInfo, emojiPath) - return if (avatarPath == null || avatarPath == model.avatarPath) model else model.copy(avatarPath = avatarPath) - } - - private suspend fun resolveAvatarPath(user: TdApi.User): String? { - val bigPhoto = user.profilePhoto?.big - val smallPhoto = user.profilePhoto?.small - val directPath = bigPhoto?.local?.path?.ifEmpty { null } ?: smallPhoto?.local?.path?.ifEmpty { null } - if (directPath != null) return directPath - - val resolvedSmallPath = resolveDownloadedFilePath(smallPhoto?.id) - if (resolvedSmallPath != null) return resolvedSmallPath - - val resolvedBigPath = resolveDownloadedFilePath(bigPhoto?.id) - if (resolvedBigPath != null) return resolvedBigPath - - bigPhoto?.id?.takeIf { it != 0 }?.let { - fileQueue.enqueue(it, avatarDownloadPriority, FileDownloadQueue.DownloadType.DEFAULT, synchronous = false) - } - smallPhoto?.id?.takeIf { it != 0 }?.let { - fileQueue.enqueue(it, avatarFallbackPriority, FileDownloadQueue.DownloadType.DEFAULT, synchronous = false) - } - - return null - } - - private suspend fun resolveDownloadedFilePath(fileId: Int?): String? { - if (fileId == null || fileId == 0) return null - val file = coRunCatching { gateway.execute(TdApi.GetFile(fileId)) }.getOrNull() ?: return null - return if (file.local.isDownloadingCompleted) file.local.path.ifEmpty { null } else null - } - - override fun getUserFlow(userId: Long): Flow = flow { - if (userId <= 0) { - emit(null) - return@flow - } - emit(getUser(userId)) - _userUpdateFlow - .filter { it == userId } - .collect { emit(getUser(userId)) } - } - - override suspend fun getUserProfilePhotos( - userId: Long, - offset: Int, - limit: Int, - ensureFullRes: Boolean - ): List { - if (userId <= 0) return emptyList() - val result = remote.getUserProfilePhotos(userId, offset, limit) ?: return emptyList() - return result.photos.mapNotNull { photo -> resolveUserProfilePhotoPath(photo, ensureFullRes) } - } - - private suspend fun resolveUserProfilePhotoPath( - photo: TdApi.ChatPhoto, - ensureFullRes: Boolean - ): String? { - val animationFile = photo.animation?.file - val animationPath = animationFile?.local?.path?.ifEmpty { null } - if (animationPath != null) return animationPath - - val bestPhotoFile = photo.sizes - .maxByOrNull { it.width.toLong() * it.height.toLong() } - ?.photo - ?: photo.sizes.lastOrNull()?.photo - ?: return null - - val directPath = bestPhotoFile.local.path.ifEmpty { null } - if (directPath != null) return directPath - - if (!ensureFullRes) return null - - val fileId = bestPhotoFile.id.takeIf { it != 0 } ?: return null - fileQueue.enqueue( - fileId = fileId, - priority = 32, - type = FileDownloadQueue.DownloadType.DEFAULT, - synchronous = false, - ignoreSuppression = true - ) - withTimeoutOrNull(15_000) { - coRunCatching { fileQueue.waitForDownload(fileId).await() } - } - return resolveDownloadedFilePath(fileId) - } - - override fun getUserProfilePhotosFlow(userId: Long): Flow> = flow { - if (userId <= 0) { - emit(emptyList()) - return@flow - } - emit(getUserProfilePhotos(userId)) - updates.file.collect { emit(getUserProfilePhotos(userId)) } - } - - override suspend fun getChatFullInfo(chatId: Long): ChatFullInfoModel? { - if (chatId == 0L) return null - - val chat = remote.getChat(chatId)?.also { chatLocal.insertChat(it.toEntity()) } - ?: chatLocal.getChat(chatId)?.let { it.toTdApiChat() } - - if (chat != null) { - val dbFullInfo = chatLocal.getChatFullInfo(chatId) - return when (val type = chat.type) { - is TdApi.ChatTypePrivate -> { - val userId = type.userId - val fullInfo = userLocal.getUserFullInfo(userId) ?: userLocal.getFullInfoEntity(userId)?.let { - val info = it.toTdApi() - userLocal.putUserFullInfo(userId, info) - info - } ?: fetchAndCacheUserFullInfo(userId)?.also { - userLocal.putUserFullInfo(userId, it) - userLocal.saveFullInfoEntity(it.toEntity(userId)) - syncUserPersonalAvatarPath(userId, it) - } - fullInfo?.mapUserFullInfoToChat() ?: dbFullInfo?.toDomain() - } - - is TdApi.ChatTypeSupergroup -> { - val fullInfo = remote.getSupergroupFullInfo(type.supergroupId) - val supergroup = remote.getSupergroup(type.supergroupId) - fullInfo?.let { - chatLocal.insertChatFullInfo(it.toEntity(chatId)) - } - fullInfo?.mapSupergroupFullInfoToChat(supergroup) ?: dbFullInfo?.toDomain() - } - - is TdApi.ChatTypeBasicGroup -> { - val fullInfo = remote.getBasicGroupFullInfo(type.basicGroupId) - fullInfo?.let { - chatLocal.insertChatFullInfo(it.toEntity(chatId)) - } - fullInfo?.mapBasicGroupFullInfoToChat() ?: dbFullInfo?.toDomain() - } - - else -> dbFullInfo?.toDomain() - } - } - - val userId = chatId - val fullInfo = userLocal.getUserFullInfo(userId) ?: userLocal.getFullInfoEntity(userId)?.let { - val info = it.toTdApi() - userLocal.putUserFullInfo(userId, info) - info - } ?: fetchAndCacheUserFullInfo(userId)?.also { - userLocal.putUserFullInfo(userId, it) - userLocal.saveFullInfoEntity(it.toEntity(userId)) - syncUserPersonalAvatarPath(userId, it) - } - return fullInfo?.mapUserFullInfoToChat() - } - - private suspend fun resolveStoredPersonalAvatarPath(userId: Long): String? { - val cachedFullInfo = userLocal.getUserFullInfo(userId) - val cachedPath = cachedFullInfo?.extractPersonalAvatarPath() - if (!cachedPath.isNullOrBlank()) return cachedPath - return userLocal.getFullInfoEntity(userId)?.personalPhotoPath?.ifBlank { null } - } - - private suspend fun syncUserPersonalAvatarPath(userId: Long, fullInfo: TdApi.UserFullInfo) { - val roomUserLocal = userLocal as? RoomUserLocalDataSource ?: return - val personalAvatarPath = fullInfo.extractPersonalAvatarPath() ?: return - val existing = roomUserLocal.loadUser(userId) ?: return - if (existing.personalAvatarPath == personalAvatarPath) return - roomUserLocal.saveUser(existing.copy(personalAvatarPath = personalAvatarPath)) - } - - private fun TdApi.UserFullInfo.extractPersonalAvatarPath(): String? { - val bestPhotoSize = personalPhoto?.sizes?.maxByOrNull { it.width.toLong() * it.height.toLong() } - ?: personalPhoto?.sizes?.lastOrNull() - return personalPhoto?.animation?.file?.local?.path?.ifEmpty { null } - ?: bestPhotoSize?.photo?.local?.path?.ifEmpty { null } - } - - private suspend fun fetchAndCacheUser(userId: Long): TdApi.User? { - if (userId <= 0 || isNegativeCached(missingUsersUntilMs, userId)) return null - val user = remote.getUser(userId) - if (user != null) { - missingUsersUntilMs.remove(userId) - } else { - rememberNegative(missingUsersUntilMs, userId) - } - return user - } - - private suspend fun fetchAndCacheUserFullInfo(userId: Long): TdApi.UserFullInfo? { - if (userId <= 0 || isNegativeCached(missingUserFullInfoUntilMs, userId)) return null - val info = remote.getUserFullInfo(userId) - if (info != null) { - missingUserFullInfoUntilMs.remove(userId) - } else { - rememberNegative(missingUserFullInfoUntilMs, userId) - } - return info - } - - private fun isNegativeCached(cache: ConcurrentHashMap, id: Long): Boolean { - val until = cache[id] ?: return false - if (until > System.currentTimeMillis()) return true - cache.remove(id, until) - return false - } - - private fun rememberNegative(cache: ConcurrentHashMap, id: Long) { - cache[id] = System.currentTimeMillis() + NEGATIVE_CACHE_TTL_MS - } - - override suspend fun getContacts(): List { - val result = remote.getContacts() ?: return emptyList() - return result.userIds.map { scope.async { getUser(it) } }.awaitAll().filterNotNull() - } - - override suspend fun searchContacts(query: String): List { - val result = remote.searchContacts(query) ?: return emptyList() - return result.userIds.map { scope.async { getUser(it) } }.awaitAll().filterNotNull() - } - - override suspend fun addContact(user: UserModel) { - val contact = TdApi.ImportedContact( - user.phoneNumber.orEmpty(), - user.firstName, - user.lastName.orEmpty(), - null - ) - remote.addContact(user.id, contact, true) - - remote.getUser(user.id)?.let { refreshedUser -> - userLocal.putUser(refreshedUser) - if (userLocal is RoomUserLocalDataSource) { - val personalAvatarPath = resolveStoredPersonalAvatarPath(refreshedUser.id) - userLocal.saveUser(refreshedUser.toEntity(personalAvatarPath)) - } - } - - _userUpdateFlow.emit(user.id) - } - - override suspend fun removeContact(userId: Long) { - remote.removeContacts(longArrayOf(userId)) - _userUpdateFlow.emit(userId) - } - - override suspend fun searchPublicChat(username: String): ChatModel? { - val chat = remote.searchPublicChat(username) ?: return null - chatLocal.insertChat(chat.toEntity()) - return chat.toDomain() - } - - override suspend fun getChatMembers( - chatId: Long, - offset: Int, - limit: Int, - filter: ChatMembersFilter - ): List { - val chat = remote.getChat(chatId) ?: return emptyList() - val members: List = when (val type = chat.type) { - is TdApi.ChatTypeSupergroup -> { - val tdFilter = filter.toApi() - remote.getSupergroupMembers(type.supergroupId, tdFilter, offset, limit) - ?.members?.toList() ?: emptyList() - } - is TdApi.ChatTypeBasicGroup -> { - if (offset > 0) return emptyList() - val fullInfo = remote.getBasicGroupMembers(type.basicGroupId) ?: return emptyList() - fullInfo.members.filter { member -> - when (filter) { - is ChatMembersFilter.Administrators -> - member.status is TdApi.ChatMemberStatusAdministrator || - member.status is TdApi.ChatMemberStatusCreator - else -> true - } - } - } - else -> emptyList() - } - - return members.map { member -> - scope.async { - val sender = member.memberId as? TdApi.MessageSenderUser ?: return@async null - val user = getUser(sender.userId) ?: return@async null - member.toDomain(user) - } - }.awaitAll().filterNotNull() - } - - override suspend fun getChatMember(chatId: Long, userId: Long): GroupMemberModel? { - val member = remote.getChatMember(chatId, userId) ?: return null - val user = getUser(userId) ?: return null - return member.toDomain(user) - } - - override suspend fun setChatMemberStatus( - chatId: Long, - userId: Long, - status: ChatMemberStatus - ) { - remote.setChatMemberStatus(chatId, userId, status.toApi()) - _userUpdateFlow.emit(userId) - } - - override suspend fun getPremiumState(): PremiumStateModel? { - val state = remote.getPremiumState() ?: return null - return state.toDomain() - } - - override suspend fun getPremiumFeatures(source: PremiumSource): List { - val tdSource = source.toApi() ?: return emptyList() - val result = remote.getPremiumFeatures(tdSource) ?: return emptyList() - return result.features.map { it.toDomain() } - } - - override suspend fun getPremiumLimit(limitType: PremiumLimitType): Int { - val tdType = limitType.toApi() ?: return 0 - return remote.getPremiumLimit(tdType)?.premiumValue ?: 0 - } - - override suspend fun getBotCommands(botId: Long): List { - val fullInfo = remote.getBotFullInfo(botId) ?: return emptyList() - return fullInfo.botInfo?.commands?.map { - BotCommandModel(it.command, it.description) - } ?: emptyList() - } - - override suspend fun getBotInfo(botId: Long): BotInfoModel? { - val fullInfo = remote.getBotFullInfo(botId) ?: return null - val commands = fullInfo.botInfo?.commands?.map { - BotCommandModel(it.command, it.description) - } ?: emptyList() - val menuButton = when (val btn = fullInfo.botInfo?.menuButton) { - is TdApi.BotMenuButton -> BotMenuButtonModel.WebApp(btn.text, btn.url) - else -> BotMenuButtonModel.Default - } - return BotInfoModel(commands, menuButton) - } - - override suspend fun getChatStatistics(chatId: Long, isDark: Boolean): ChatStatisticsModel? { - val stats = remote.getChatStatistics(chatId, isDark) ?: return null - return stats.toDomain() - } - - override suspend fun getChatRevenueStatistics( - chatId: Long, - isDark: Boolean - ): ChatRevenueStatisticsModel? { - val stats = remote.getChatRevenueStatistics(chatId, isDark) ?: return null - return stats.toDomain() - } - - override suspend fun loadStatisticsGraph( - chatId: Long, - token: String, - x: Long - ): StatisticsGraphModel? { - val graph = remote.getStatisticsGraph(chatId, token, x) ?: return null - return graph.toDomain() - } - - override fun logOut() { - scope.launch { coRunCatching { remote.logout() } } - scope.launch { userLocal.clearAll() } - if (userLocal is RoomUserLocalDataSource) { - scope.launch { userLocal.clearDatabase() } - } - scope.launch { - coRunCatching { keyValueDao.deleteValue(KEY_CURRENT_USER_ID) } - currentUserId = 0L - _currentUserFlow.value = null - } - scope.launch { chatLocal.clearAll() } - } - - override suspend fun setName(firstName: String, lastName: String) = - remote.setName(firstName, lastName) - - override suspend fun setBio(bio: String) = - remote.setBio(bio) - - override suspend fun setUsername(username: String) = - remote.setUsername(username) - - override suspend fun setEmojiStatus(customEmojiId: Long?) = - remote.setEmojiStatus(customEmojiId) - - override suspend fun setProfilePhoto(path: String) = - remote.setProfilePhoto(path) - - override suspend fun setBirthdate(birthdate: BirthdateModel?) = - remote.setBirthdate(birthdate?.let { TdApi.Birthdate(it.day, it.month, it.year ?: 0) }) - - override suspend fun setPersonalChat(chatId: Long) = - remote.setPersonalChat(chatId) - - override suspend fun setBusinessBio(bio: String) = - remote.setBusinessBio(bio) - - override suspend fun setBusinessLocation(address: String, latitude: Double, longitude: Double) = - remote.setBusinessLocation( - if (address.isNotEmpty()) TdApi.BusinessLocation( - TdApi.Location(latitude, longitude, 0.0), address - ) else null - ) - - override suspend fun setBusinessOpeningHours(openingHours: BusinessOpeningHoursModel?) = - remote.setBusinessOpeningHours( - openingHours?.let { - TdApi.BusinessOpeningHours( - it.timeZoneId, - it.intervals.map { interval -> - TdApi.BusinessOpeningHoursInterval(interval.startMinute, interval.endMinute) - }.toTypedArray() - ) - } - ) - - override suspend fun toggleUsernameIsActive(username: String, isActive: Boolean) = - remote.toggleUsernameIsActive(username, isActive) - - override suspend fun reorderActiveUsernames(usernames: List) = - remote.reorderActiveUsernames(usernames.toTypedArray()) - - override fun forceSponsorSync() { - sponsorSyncManager.forceSync() - } - - private fun TdApi.Chat.toEntity(): org.monogram.data.db.model.ChatEntity { - val isChannel = (type as? TdApi.ChatTypeSupergroup)?.isChannel ?: false - val isArchived = positions.any { it.list is TdApi.ChatListArchive } - val permissions = permissions ?: TdApi.ChatPermissions() - val cachedCounts = parseCachedCounts(clientData) - val senderId = when (val sender = messageSenderId) { - is TdApi.MessageSenderUser -> sender.userId - is TdApi.MessageSenderChat -> sender.chatId - else -> null - } - val privateUserId = (type as? TdApi.ChatTypePrivate)?.userId ?: 0L - val basicGroupId = (type as? TdApi.ChatTypeBasicGroup)?.basicGroupId ?: 0L - val supergroupId = (type as? TdApi.ChatTypeSupergroup)?.supergroupId ?: 0L - val secretChatId = (type as? TdApi.ChatTypeSecret)?.secretChatId ?: 0 - return org.monogram.data.db.model.ChatEntity( - id = id, - title = title, - unreadCount = unreadCount, - avatarPath = photo?.small?.local?.path, - lastMessageText = (lastMessage?.content as? TdApi.MessageText)?.text?.text ?: "", - lastMessageTime = (lastMessage?.date?.toLong() ?: 0L).toString(), - lastMessageDate = lastMessage?.date?.toLong() ?: 0L, - order = positions.firstOrNull()?.order ?: 0L, - isPinned = positions.firstOrNull()?.isPinned ?: false, - isMuted = notificationSettings.muteFor > 0, - isChannel = isChannel, - isGroup = type is TdApi.ChatTypeBasicGroup || (type is TdApi.ChatTypeSupergroup && !isChannel), - type = when (type) { - is TdApi.ChatTypePrivate -> "PRIVATE" - is TdApi.ChatTypeBasicGroup -> "BASIC_GROUP" - is TdApi.ChatTypeSupergroup -> "SUPERGROUP" - is TdApi.ChatTypeSecret -> "SECRET" - else -> "PRIVATE" - }, - privateUserId = privateUserId, - basicGroupId = basicGroupId, - supergroupId = supergroupId, - secretChatId = secretChatId, - positionsCache = encodePositions(positions), - isArchived = isArchived, - memberCount = cachedCounts.first, - onlineCount = cachedCounts.second, - unreadMentionCount = unreadMentionCount, - unreadReactionCount = unreadReactionCount, - isMarkedAsUnread = isMarkedAsUnread, - hasProtectedContent = hasProtectedContent, - isTranslatable = isTranslatable, - hasAutomaticTranslation = false, - messageAutoDeleteTime = messageAutoDeleteTime, - canBeDeletedOnlyForSelf = canBeDeletedOnlyForSelf, - canBeDeletedForAllUsers = canBeDeletedForAllUsers, - canBeReported = canBeReported, - lastReadInboxMessageId = lastReadInboxMessageId, - lastReadOutboxMessageId = lastReadOutboxMessageId, - lastMessageId = lastMessage?.id ?: 0L, - isLastMessageOutgoing = lastMessage?.isOutgoing ?: false, - replyMarkupMessageId = replyMarkupMessageId, - messageSenderId = senderId, - blockList = blockList != null, - emojiStatusId = (emojiStatus?.type as? TdApi.EmojiStatusTypeCustomEmoji)?.customEmojiId, - accentColorId = accentColorId, - profileAccentColorId = profileAccentColorId, - backgroundCustomEmojiId = backgroundCustomEmojiId, - photoId = photo?.small?.id ?: 0, - isSupergroup = type is TdApi.ChatTypeSupergroup, - isAdmin = false, - isOnline = false, - typingAction = null, - draftMessage = (draftMessage?.inputMessageText as? TdApi.InputMessageText)?.text?.text, - isVerified = false, - viewAsTopics = viewAsTopics, - isForum = false, - isBot = false, - isMember = true, - username = null, - description = null, - inviteLink = null, - permissionCanSendBasicMessages = permissions.canSendBasicMessages, - permissionCanSendAudios = permissions.canSendAudios, - permissionCanSendDocuments = permissions.canSendDocuments, - permissionCanSendPhotos = permissions.canSendPhotos, - permissionCanSendVideos = permissions.canSendVideos, - permissionCanSendVideoNotes = permissions.canSendVideoNotes, - permissionCanSendVoiceNotes = permissions.canSendVoiceNotes, - permissionCanSendPolls = permissions.canSendPolls, - permissionCanSendOtherMessages = permissions.canSendOtherMessages, - permissionCanAddLinkPreviews = permissions.canAddLinkPreviews, - permissionCanEditTag = permissions.canEditTag, - permissionCanChangeInfo = permissions.canChangeInfo, - permissionCanInviteUsers = permissions.canInviteUsers, - permissionCanPinMessages = permissions.canPinMessages, - permissionCanCreateTopics = permissions.canCreateTopics, - createdAt = System.currentTimeMillis() - ) - } - - private fun encodePositions(positions: Array): String? { - if (positions.isEmpty()) return null - val encoded = positions.mapNotNull { pos -> - if (pos.order == 0L) return@mapNotNull null - val pinned = if (pos.isPinned) 1 else 0 - when (val list = pos.list) { - is TdApi.ChatListMain -> "m:${pos.order}:$pinned" - is TdApi.ChatListArchive -> "a:${pos.order}:$pinned" - is TdApi.ChatListFolder -> "f:${list.chatFolderId}:${pos.order}:$pinned" - else -> null - } - } - return if (encoded.isEmpty()) null else encoded.joinToString("|") - } - - private fun TdApi.User.toEntity(personalAvatarPath: String?): org.monogram.data.db.model.UserEntity { - val usernamesData = buildString { - append(usernames?.activeUsernames?.joinToString("|").orEmpty()) - append('\n') - append(usernames?.disabledUsernames?.joinToString("|").orEmpty()) - append('\n') - append(usernames?.editableUsername.orEmpty()) - append('\n') - append(usernames?.collectibleUsernames?.joinToString("|").orEmpty()) - } - - val statusType = when (status) { - is TdApi.UserStatusOnline -> "ONLINE" - is TdApi.UserStatusRecently -> "RECENTLY" - is TdApi.UserStatusLastWeek -> "LAST_WEEK" - is TdApi.UserStatusLastMonth -> "LAST_MONTH" - else -> "OFFLINE" - } - - val statusEmojiId = when (val type = emojiStatus?.type) { - is TdApi.EmojiStatusTypeCustomEmoji -> type.customEmojiId - is TdApi.EmojiStatusTypeUpgradedGift -> type.modelCustomEmojiId - else -> 0L - } - - return org.monogram.data.db.model.UserEntity( - id = id, - firstName = firstName, - lastName = lastName.ifEmpty { null }, - phoneNumber = phoneNumber.ifEmpty { null }, - avatarPath = profilePhoto?.small?.local?.path?.ifEmpty { null }, - personalAvatarPath = personalAvatarPath, - isPremium = isPremium, - isVerified = verificationStatus?.isVerified ?: false, - isSupport = isSupport, - isContact = isContact, - isMutualContact = isMutualContact, - isCloseFriend = isCloseFriend, - haveAccess = haveAccess, - username = usernames?.activeUsernames?.firstOrNull(), - usernamesData = usernamesData, - statusType = statusType, - accentColorId = accentColorId, - profileAccentColorId = profileAccentColorId, - statusEmojiId = statusEmojiId, - languageCode = languageCode.ifEmpty { null }, - lastSeen = (status as? TdApi.UserStatusOffline)?.wasOnline?.toLong() ?: 0L, - createdAt = System.currentTimeMillis() - ) - } - - private fun parseCachedCounts(clientData: String?): Pair { - if (clientData.isNullOrBlank()) return 0 to 0 - val memberCount = Regex("""mc:(\d+)""").find(clientData)?.groupValues?.getOrNull(1)?.toIntOrNull() ?: 0 - val onlineCount = Regex("""oc:(\d+)""").find(clientData)?.groupValues?.getOrNull(1)?.toIntOrNull() ?: 0 - return memberCount to onlineCount - } - - companion object { - private const val NEGATIVE_CACHE_TTL_MS = 5 * 60 * 1000L - private const val KEY_CURRENT_USER_ID = "current_user_id" - } -} diff --git a/data/src/main/java/org/monogram/data/service/Extensions.kt b/data/src/main/java/org/monogram/data/service/Extensions.kt deleted file mode 100644 index 3d4b6474..00000000 --- a/data/src/main/java/org/monogram/data/service/Extensions.kt +++ /dev/null @@ -1,23 +0,0 @@ -package org.monogram.data.service - -import android.content.BroadcastReceiver -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.launch -import kotlin.coroutines.CoroutineContext -import kotlin.coroutines.EmptyCoroutineContext - -fun BroadcastReceiver.goAsync( - context: CoroutineContext = EmptyCoroutineContext, - block: suspend CoroutineScope.() -> Unit -) { - val pendingResult = goAsync() - CoroutineScope(SupervisorJob() + Dispatchers.IO + context).launch { - try { - block() - } finally { - pendingResult.finish() - } - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/service/FcmPushService.kt b/data/src/main/java/org/monogram/data/service/FcmPushService.kt deleted file mode 100644 index 62e8a559..00000000 --- a/data/src/main/java/org/monogram/data/service/FcmPushService.kt +++ /dev/null @@ -1,80 +0,0 @@ -package org.monogram.data.service - -import android.os.PowerManager -import android.util.Log -import com.google.firebase.messaging.FirebaseMessagingService -import com.google.firebase.messaging.RemoteMessage -import kotlinx.coroutines.delay -import kotlinx.coroutines.runBlocking -import org.drinkless.tdlib.TdApi -import org.json.JSONObject -import org.koin.android.ext.android.inject -import org.monogram.data.di.TdLibClient -import org.monogram.domain.repository.AppPreferencesProvider -import org.monogram.domain.repository.PushProvider - -class FcmPushService : FirebaseMessagingService() { - private val tdLibClient: TdLibClient by inject() - private val appPreferences: AppPreferencesProvider by inject() - - override fun onNewToken(token: String) { - super.onNewToken(token) - Log.d("FcmPushService", "New FCM token: $token") - if (appPreferences.pushProvider.value == PushProvider.FCM) { - registerToken(token) - } - } - - override fun onMessageReceived(message: RemoteMessage) { - super.onMessageReceived(message) - Log.d("FcmPushService", "FCM message received: ${message.data}") - - if (appPreferences.pushProvider.value != PushProvider.FCM) return - - val data = message.data - if (data.isNotEmpty()) { - val powerManager = getSystemService(POWER_SERVICE) as PowerManager - val wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "monogram:FcmPushService") - - try { - val json = JSONObject() - for ((k, v) in data) { - json.put(k, v) - } - val jsonPayload = json.toString() - - tdLibClient.send(TdApi.ProcessPushNotification(jsonPayload)) { - Log.d("FcmPushService", "ProcessPushNotification success") - } - - runBlocking { - delay(5000) - } - } catch (e: Exception) { - Log.e("FcmPushService", "Error processing push", e) - } finally { - if (wakeLock.isHeld) { - wakeLock.release() - } - } - } - } - - override fun onDeletedMessages() { - super.onDeletedMessages() - Log.d("FcmPushService", "FCM messages deleted") - } - - private fun registerToken(token: String) { - if (!tdLibClient.isAuthenticated.value) return - - tdLibClient.send( - TdApi.RegisterDevice( - TdApi.DeviceTokenFirebaseCloudMessaging(token, true), - longArrayOf() - ) - ) { result -> - Log.d("FcmPushService", "RegisterDevice result: $result") - } - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/service/NotificationDismissReceiver.kt b/data/src/main/java/org/monogram/data/service/NotificationDismissReceiver.kt deleted file mode 100644 index 46267e7c..00000000 --- a/data/src/main/java/org/monogram/data/service/NotificationDismissReceiver.kt +++ /dev/null @@ -1,25 +0,0 @@ -package org.monogram.data.service - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import org.monogram.data.di.TdNotificationManager -import org.koin.core.component.KoinComponent -import org.koin.core.component.inject - -class NotificationDismissReceiver : BroadcastReceiver(), KoinComponent { - - private val notificationManager: TdNotificationManager by inject() - - override fun onReceive(context: Context, intent: Intent) { - val chatId = intent.getLongExtra("chat_id", 0L) - val notificationId = intent.getIntExtra("notification_id", 0) - if (chatId != 0L) { - if (notificationId != 0) { - notificationManager.removeNotification(chatId, notificationId) - } else { - notificationManager.clearHistory(chatId) - } - } - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/service/NotificationReadReceiver.kt b/data/src/main/java/org/monogram/data/service/NotificationReadReceiver.kt deleted file mode 100644 index 1578d3c4..00000000 --- a/data/src/main/java/org/monogram/data/service/NotificationReadReceiver.kt +++ /dev/null @@ -1,60 +0,0 @@ -package org.monogram.data.service - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.util.Log -import org.drinkless.tdlib.TdApi -import org.koin.core.component.KoinComponent -import org.koin.core.component.inject -import org.monogram.data.di.TdLibClient -import org.monogram.data.di.TdLibException -import org.monogram.data.di.TdNotificationManager - -class NotificationReadReceiver : BroadcastReceiver(), KoinComponent { - - private val tdLibClient: TdLibClient by inject() - private val notificationManager: TdNotificationManager by inject() - - override fun onReceive(context: Context, intent: Intent) { - val chatId = intent.getLongExtra("chat_id", 0L) - val notificationId = intent.getIntExtra("notification_id", 0) - if (chatId == 0L) return - - goAsync { - try { - if (notificationId != 0) { - notificationManager.removeNotification(chatId, notificationId) - } else { - notificationManager.clearHistory(chatId) - } - - val chat = try { - tdLibClient.sendSuspend(TdApi.GetChat(chatId)) - } catch (e: TdLibException) { - if (e.error.message == "Not Found") { - Log.w("NotificationReadReceiver", "Chat $chatId not found") - return@goAsync - } - throw e - } - - if (chat.unreadCount > 0) { - chat.lastMessage?.let { lastMessage -> - try { - tdLibClient.sendSuspend(TdApi.ViewMessages(chatId, longArrayOf(lastMessage.id), null, true)) - } catch (e: TdLibException) { - if (e.error.message == "Message is too old" || e.error.message == "Not Found") { - Log.w("NotificationReadReceiver", "Failed to mark message as read: ${e.error.message}") - } else { - throw e - } - } - } - } - } catch (e: Exception) { - Log.e("NotificationReadReceiver", "Failed to mark messages as read", e) - } - } - } -} diff --git a/data/src/main/java/org/monogram/data/service/NotificationReplyReceiver.kt b/data/src/main/java/org/monogram/data/service/NotificationReplyReceiver.kt deleted file mode 100644 index bcf4b0f6..00000000 --- a/data/src/main/java/org/monogram/data/service/NotificationReplyReceiver.kt +++ /dev/null @@ -1,74 +0,0 @@ -package org.monogram.data.service - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import androidx.core.app.RemoteInput -import org.monogram.data.di.TdLibClient -import org.monogram.data.di.TdNotificationManager -import org.drinkless.tdlib.TdApi -import org.koin.core.component.KoinComponent -import org.koin.core.component.inject - -class NotificationReplyReceiver : BroadcastReceiver(), KoinComponent { - - private val tdLibClient: TdLibClient by inject() - private val notificationManager: TdNotificationManager by inject() - - override fun onReceive(context: Context, intent: Intent) { - val chatId = intent.getLongExtra("chat_id", 0L) - val notificationId = intent.getIntExtra("notification_id", 0) - if (chatId == 0L) return - - val remoteInput = RemoteInput.getResultsFromIntent(intent) ?: return - val replyText = remoteInput.getCharSequence(TdNotificationManager.KEY_TEXT_REPLY)?.toString() ?: return - - goAsync { - try { - val actionTyping = TdApi.SendChatAction().apply { - this.chatId = chatId - this.topicId = null - this.action = TdApi.ChatActionTyping() - } - - tdLibClient.send(actionTyping) - - notificationManager.getChat(chatId) { chat -> - val inputMessageContent = TdApi.InputMessageText().apply { - this.text = TdApi.FormattedText(replyText, emptyArray()) - this.clearDraft = true - } - - val request = TdApi.SendMessage().apply { - this.chatId = chatId - this.replyTo = TdApi.InputMessageReplyToMessage() - this.options = TdApi.MessageSendOptions().apply { - this.disableNotification = false - this.fromBackground = true - } - this.inputMessageContent = inputMessageContent - } - - tdLibClient.send(request) - - if (notificationId != 0) { - notificationManager.removeNotification(chatId, notificationId) - } - - notificationManager.appendMessageToNotification( - chatId = chatId, - messageId = System.currentTimeMillis(), - chatType = chat.type, - senderName = "Вы", - senderBitmap = null, - chatIcon = null, - text = replyText, - timestamp = System.currentTimeMillis() - ) - } - } catch (e: Exception) { - e.printStackTrace() - } - } - } -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/service/TdNotificationManager.kt b/data/src/main/java/org/monogram/data/service/TdNotificationManager.kt deleted file mode 100644 index af7a5c0f..00000000 --- a/data/src/main/java/org/monogram/data/service/TdNotificationManager.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.monogram.data.service - -import kotlinx.coroutines.CoroutineScope -import org.drinkless.tdlib.TdApi - -interface TdNotificationManager { - fun observeUpdates(scope: CoroutineScope) - fun isChatMuted(chat: TdApi.Chat): Boolean - fun clearHistory(chatId: Long) - fun getChat(chatId: Long, callback: (TdApi.Chat) -> Unit) -} \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/service/TdNotificationService.kt b/data/src/main/java/org/monogram/data/service/TdNotificationService.kt deleted file mode 100644 index 1fd15fd8..00000000 --- a/data/src/main/java/org/monogram/data/service/TdNotificationService.kt +++ /dev/null @@ -1,253 +0,0 @@ -package org.monogram.data.service - -import android.app.NotificationChannel -import android.app.NotificationManager -import android.app.PendingIntent -import android.app.Service -import android.content.Intent -import android.content.pm.ServiceInfo -import android.os.Build -import android.os.IBinder -import android.os.PowerManager -import androidx.core.app.NotificationCompat -import androidx.core.app.ServiceCompat -import kotlinx.coroutines.* -import kotlinx.coroutines.flow.combine -import org.koin.android.ext.android.inject -import org.monogram.domain.repository.AppPreferencesProvider -import org.monogram.domain.repository.PushProvider -import org.monogram.domain.repository.StringProvider - -class TdNotificationService : Service() { - private val appPreferences: AppPreferencesProvider by inject() - private val stringProvider: StringProvider by inject() - - private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) - private var isServiceRunning = false - private var wakeLock: PowerManager.WakeLock? = null - private var checkJob: Job? = null - - companion object { - const val FOREGROUND_CHANNEL_ID = "tdlib_background_service" - const val FOREGROUND_ID = 999 - const val ACTION_STOP = "org.monogram.data.service.ACTION_STOP" - private const val CHECK_INTERVAL = 60_000L // 1 minute - } - - override fun onBind(intent: Intent?): IBinder? = null - - override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - if (intent?.action == ACTION_STOP) { - stopForegroundService() - return START_NOT_STICKY - } - - if (appPreferences.pushProvider.value == PushProvider.FCM) { - stopForegroundService() - return START_NOT_STICKY - } - - if (!isServiceRunning) { - isServiceRunning = true - acquireWakeLock() - startForegroundNotification() - startListeningUpdates() - startPeriodicCheck() - } - return START_STICKY - } - - private fun acquireWakeLock() { - if (appPreferences.pushProvider.value == PushProvider.FCM) return - if (appPreferences.isPowerSavingMode.value) return - if (!appPreferences.isWakeLockEnabled.value) return - - if (wakeLock == null) { - val powerManager = getSystemService(PowerManager::class.java) - wakeLock = powerManager?.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "monogram:TdNotificationServiceLock") - wakeLock?.setReferenceCounted(false) - } - if (wakeLock?.isHeld == false) { - wakeLock?.acquire(24 * 60 * 60 * 1000L) - } - } - - private fun releaseWakeLock() { - if (wakeLock?.isHeld == true) { - wakeLock?.release() - } - } - - private fun startForegroundNotification(status: String? = null) { - createForegroundChannel() - - val notificationIntent = packageManager.getLaunchIntentForPackage(packageName) - val pendingIntent = PendingIntent.getActivity( - this, - 0, - notificationIntent, - PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT - ) - - val stopIntent = Intent(this, TdNotificationService::class.java).apply { - action = ACTION_STOP - } - val stopPendingIntent = PendingIntent.getService( - this, - 1, - stopIntent, - PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT - ) - - val notificationBuilder = NotificationCompat.Builder(this, FOREGROUND_CHANNEL_ID) - .setContentTitle("MonoGram") - .setContentText(status ?: stringProvider.getString("notification_service_waiting")) - .setContentIntent(pendingIntent) - .setPriority(NotificationCompat.PRIORITY_MIN) - .setOngoing(true) - .setOnlyAlertOnce(true) - .setSmallIcon(org.monogram.data.R.drawable.message_outline) - .setCategory(NotificationCompat.CATEGORY_SERVICE) - .addAction( - android.R.drawable.ic_menu_close_clear_cancel, - stringProvider.getString("notification_service_stop"), - stopPendingIntent - ) - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - notificationBuilder.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE) - } - - val notification = notificationBuilder.build() - - val foregroundServiceType = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - ServiceInfo.FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING - } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC - } else { - 0 - } - - try { - ServiceCompat.startForeground( - this, - FOREGROUND_ID, - notification, - foregroundServiceType - ) - - if (appPreferences.hideForegroundNotification.value) { - serviceScope.launch { - delay(2000) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - stopForeground(STOP_FOREGROUND_DETACH) - } else { - @Suppress("DEPRECATION") - stopForeground(false) - } - } - } - } catch (e: Exception) { - e.printStackTrace() - stopSelf() - } - } - - private fun stopForegroundService() { - isServiceRunning = false - appPreferences.setBackgroundServiceEnabled(false) - try { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - stopForeground(STOP_FOREGROUND_REMOVE) - } else { - @Suppress("DEPRECATION") - stopForeground(true) - } - } catch (e: Exception) { - e.printStackTrace() - } - stopSelf() - } - - private fun startListeningUpdates() { - serviceScope.launch { - combine( - appPreferences.isPowerSavingMode, - appPreferences.isWakeLockEnabled, - appPreferences.batteryOptimizationEnabled, - appPreferences.pushProvider - ) { powerSaving, wakeLockEnabled, batteryOptimization, pushProvider -> - Quadruple(powerSaving, wakeLockEnabled, batteryOptimization, pushProvider) - }.collect { (isPowerSaving, isWakeLockEnabled, isBatteryOptimization, pushProvider) -> - if (pushProvider == PushProvider.FCM) { - stopForegroundService() - return@collect - } - - if (isPowerSaving || !isWakeLockEnabled || isBatteryOptimization) { - delay(5000) - releaseWakeLock() - } else { - if (isServiceRunning) { - acquireWakeLock() - } - } - } - } - } - - private fun startPeriodicCheck() { - checkJob?.cancel() - checkJob = serviceScope.launch { - while (isActive) { - if (appPreferences.pushProvider.value == PushProvider.FCM || (!appPreferences.backgroundServiceEnabled.value && appPreferences.pushProvider.value == PushProvider.GMS_LESS)) { - stopForegroundService() - break - } - - val shouldReleaseWakeLock = appPreferences.isPowerSavingMode.value || - !appPreferences.isWakeLockEnabled.value || - appPreferences.batteryOptimizationEnabled.value - - if (shouldReleaseWakeLock) { - releaseWakeLock() - } else { - if (wakeLock?.isHeld == false) { - acquireWakeLock() - } - } - - delay(CHECK_INTERVAL) - } - } - } - - private fun createForegroundChannel() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val serviceChannel = NotificationChannel( - FOREGROUND_CHANNEL_ID, - stringProvider.getString("notification_service_channel_name"), - NotificationManager.IMPORTANCE_MIN - ).apply { - description = stringProvider.getString("notification_service_channel_description") - setShowBadge(false) - } - val manager = getSystemService(NotificationManager::class.java) - manager?.createNotificationChannel(serviceChannel) - } - } - - override fun onDestroy() { - super.onDestroy() - isServiceRunning = false - serviceScope.cancel() - releaseWakeLock() - } -} - -data class Quadruple( - val first: A, - val second: B, - val third: C, - val fourth: D -) \ No newline at end of file diff --git a/data/src/main/java/org/monogram/data/service/UpdateInstallReceiver.kt b/data/src/main/java/org/monogram/data/service/UpdateInstallReceiver.kt deleted file mode 100644 index 921bbd70..00000000 --- a/data/src/main/java/org/monogram/data/service/UpdateInstallReceiver.kt +++ /dev/null @@ -1,39 +0,0 @@ -package org.monogram.data.service - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.content.pm.PackageInstaller -import android.os.Build -import android.util.Log - -class UpdateInstallReceiver : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - val status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE) - when (status) { - PackageInstaller.STATUS_PENDING_USER_ACTION -> { - val confirmationIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - intent.getParcelableExtra(Intent.EXTRA_INTENT, Intent::class.java) - } else { - @Suppress("DEPRECATION") - intent.getParcelableExtra(Intent.EXTRA_INTENT) - } - if (confirmationIntent != null) { - confirmationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - context.startActivity(confirmationIntent) - } else { - Log.e("UpdateInstallReceiver", "Missing user action intent for installation") - } - } - - PackageInstaller.STATUS_SUCCESS -> { - Log.d("UpdateInstallReceiver", "Update installed successfully") - } - - else -> { - val msg = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) - Log.e("UpdateInstallReceiver", "Update installation failed: $msg") - } - } - } -} diff --git a/data/src/main/jniLibs/arm64-v8a/libtdjni.so b/data/src/main/jniLibs/arm64-v8a/libtdjni.so deleted file mode 100644 index f951d83e..00000000 Binary files a/data/src/main/jniLibs/arm64-v8a/libtdjni.so and /dev/null differ diff --git a/data/src/main/jniLibs/armeabi-v7a/libtdjni.so b/data/src/main/jniLibs/armeabi-v7a/libtdjni.so deleted file mode 100644 index 28a99ca5..00000000 Binary files a/data/src/main/jniLibs/armeabi-v7a/libtdjni.so and /dev/null differ diff --git a/data/src/main/jniLibs/x86/libtdjni.so b/data/src/main/jniLibs/x86/libtdjni.so deleted file mode 100644 index 41cecf1a..00000000 Binary files a/data/src/main/jniLibs/x86/libtdjni.so and /dev/null differ diff --git a/data/src/main/jniLibs/x86_64/libtdjni.so b/data/src/main/jniLibs/x86_64/libtdjni.so deleted file mode 100644 index 5454a4d0..00000000 Binary files a/data/src/main/jniLibs/x86_64/libtdjni.so and /dev/null differ diff --git a/data/src/main/res/drawable/baseline_notifications_none_24.xml b/data/src/main/res/drawable/baseline_notifications_none_24.xml deleted file mode 100644 index 1fb56847..00000000 --- a/data/src/main/res/drawable/baseline_notifications_none_24.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/data/src/main/res/drawable/message_outline.xml b/data/src/main/res/drawable/message_outline.xml deleted file mode 100644 index 2373c05f..00000000 --- a/data/src/main/res/drawable/message_outline.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/domain b/domain new file mode 160000 index 00000000..19015cdc --- /dev/null +++ b/domain @@ -0,0 +1 @@ +Subproject commit 19015cdc16a161772bdcd99d7f2040c49a230908 diff --git a/domain/.gitignore b/domain/.gitignore deleted file mode 100644 index 42afabfd..00000000 --- a/domain/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/domain/build.gradle.kts b/domain/build.gradle.kts deleted file mode 100644 index 828f79c2..00000000 --- a/domain/build.gradle.kts +++ /dev/null @@ -1,14 +0,0 @@ -plugins { - kotlin("jvm") - alias(libs.plugins.kotlin.serialization) -} - -kotlin { - jvmToolchain(21) -} - -dependencies { - implementation(project(":core")) - implementation(libs.kotlinx.coroutines.core) - implementation(libs.kotlinx.serialization.json) -} \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/managers/AssetsManager.kt b/domain/src/main/java/org/monogram/domain/managers/AssetsManager.kt deleted file mode 100644 index 62bef4cb..00000000 --- a/domain/src/main/java/org/monogram/domain/managers/AssetsManager.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.monogram.domain.managers - -import java.io.File -import java.io.InputStream - -interface AssetsManager { - fun getAssets(path: String): InputStream - fun getFilesDir(): File - fun getDatabasePath(name: String): File - fun clearSharedPreferences(name: String) - fun exitProcess(status: Int) -} diff --git a/domain/src/main/java/org/monogram/domain/managers/ClipManager.kt b/domain/src/main/java/org/monogram/domain/managers/ClipManager.kt deleted file mode 100644 index 86943266..00000000 --- a/domain/src/main/java/org/monogram/domain/managers/ClipManager.kt +++ /dev/null @@ -1,5 +0,0 @@ -package org.monogram.domain.managers - -interface ClipManager { - fun copyToClipboard(tag: String, text: String) -} \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/managers/DistrManager.kt b/domain/src/main/java/org/monogram/domain/managers/DistrManager.kt deleted file mode 100644 index 70d58055..00000000 --- a/domain/src/main/java/org/monogram/domain/managers/DistrManager.kt +++ /dev/null @@ -1,6 +0,0 @@ -package org.monogram.domain.managers - -interface DistrManager { - fun isGmsAvailable(): Boolean - fun isInstalledFromGooglePlay(): Boolean -} \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/managers/DomainManager.kt b/domain/src/main/java/org/monogram/domain/managers/DomainManager.kt deleted file mode 100644 index 69596997..00000000 --- a/domain/src/main/java/org/monogram/domain/managers/DomainManager.kt +++ /dev/null @@ -1,5 +0,0 @@ -package org.monogram.domain.managers - -interface DomainManager { - fun isEnabled(): Boolean -} \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/managers/PhoneManager.kt b/domain/src/main/java/org/monogram/domain/managers/PhoneManager.kt deleted file mode 100644 index b441ce6c..00000000 --- a/domain/src/main/java/org/monogram/domain/managers/PhoneManager.kt +++ /dev/null @@ -1,5 +0,0 @@ -package org.monogram.domain.managers - -interface PhoneManager { - fun getSimCountryIso(): String? -} \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/models/AccountBadgeType.kt b/domain/src/main/java/org/monogram/domain/models/AccountBadgeType.kt deleted file mode 100644 index 7974ac5e..00000000 --- a/domain/src/main/java/org/monogram/domain/models/AccountBadgeType.kt +++ /dev/null @@ -1,6 +0,0 @@ -package org.monogram.domain.models - -enum class AccountBadgeType { - VERIFIED, - SPONSOR -} diff --git a/domain/src/main/java/org/monogram/domain/models/AttachMenuBotModel.kt b/domain/src/main/java/org/monogram/domain/models/AttachMenuBotModel.kt deleted file mode 100644 index 47ad272c..00000000 --- a/domain/src/main/java/org/monogram/domain/models/AttachMenuBotModel.kt +++ /dev/null @@ -1,21 +0,0 @@ -package org.monogram.domain.models - -import kotlinx.serialization.Serializable - -@Serializable -data class AttachMenuBotModel( - val botUserId: Long, - val name: String, - val icon: AttachMenuBotIconModel?, - val requestWriteAccess: Boolean, - val isAdded: Boolean, - val showInSideMenu: Boolean, - val showInDefaultMenu: Boolean, - val showInAttachMenu: Boolean -) - -@Serializable -data class AttachMenuBotIconModel( - val name: String, - val icon: FileModel? -) diff --git a/domain/src/main/java/org/monogram/domain/models/BirthdateModel.kt b/domain/src/main/java/org/monogram/domain/models/BirthdateModel.kt deleted file mode 100644 index 5cd6c8a8..00000000 --- a/domain/src/main/java/org/monogram/domain/models/BirthdateModel.kt +++ /dev/null @@ -1,7 +0,0 @@ -package org.monogram.domain.models - -data class BirthdateModel( - val day: Int, - val month: Int, - val year: Int? = null -) diff --git a/domain/src/main/java/org/monogram/domain/models/BotCommandModel.kt b/domain/src/main/java/org/monogram/domain/models/BotCommandModel.kt deleted file mode 100644 index a513fb19..00000000 --- a/domain/src/main/java/org/monogram/domain/models/BotCommandModel.kt +++ /dev/null @@ -1,30 +0,0 @@ -package org.monogram.domain.models - -data class BotCommandModel( - val command: String, - val description: String -) - -sealed interface BotMenuButtonModel { - object Commands : BotMenuButtonModel - data class WebApp(val text: String, val url: String) : BotMenuButtonModel - object Default : BotMenuButtonModel -} - -data class BotInfoModel( - val commands: List, - val menuButton: BotMenuButtonModel -) - -data class InlineQueryResultModel( - val id: String, - val type: String, - val title: String?, - val description: String?, - val thumbUrl: String?, - val thumbFileId: Int = 0, - val content: MessageContent? = null, - val replyMarkup: ReplyMarkupModel? = null, - val width: Int = 0, - val height: Int = 0 -) diff --git a/domain/src/main/java/org/monogram/domain/models/BusinessModels.kt b/domain/src/main/java/org/monogram/domain/models/BusinessModels.kt deleted file mode 100644 index 81fe12db..00000000 --- a/domain/src/main/java/org/monogram/domain/models/BusinessModels.kt +++ /dev/null @@ -1,31 +0,0 @@ -package org.monogram.domain.models - -data class BusinessInfoModel( - val location: BusinessLocationModel? = null, - val openingHours: BusinessOpeningHoursModel? = null, - val startPage: BusinessStartPageModel? = null, - val nextOpenIn: Int = 0, - val nextCloseIn: Int = 0 -) - -data class BusinessLocationModel( - val latitude: Double, - val longitude: Double, - val address: String -) - -data class BusinessOpeningHoursModel( - val timeZoneId: String, - val intervals: List -) - -data class BusinessOpeningHoursIntervalModel( - val startMinute: Int, - val endMinute: Int -) - -data class BusinessStartPageModel( - val title: String, - val message: String, - val stickerPath: String? = null -) \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/models/ChatEventModel.kt b/domain/src/main/java/org/monogram/domain/models/ChatEventModel.kt deleted file mode 100644 index 15bba977..00000000 --- a/domain/src/main/java/org/monogram/domain/models/ChatEventModel.kt +++ /dev/null @@ -1,61 +0,0 @@ -package org.monogram.domain.models - -data class ChatEventModel( - val id: Long, - val date: Int, - val memberId: MessageSenderModel, - val action: ChatEventActionModel -) - -sealed interface ChatEventActionModel { - data class MessageEdited(val oldMessage: MessageModel, val newMessage: MessageModel) : ChatEventActionModel - data class MessageDeleted(val message: MessageModel) : ChatEventActionModel - data class MessagePinned(val message: MessageModel) : ChatEventActionModel - data class MessageUnpinned(val message: MessageModel) : ChatEventActionModel - data class MemberJoined(val userId: Long) : ChatEventActionModel - data class MemberLeft(val userId: Long) : ChatEventActionModel - data class MemberInvited(val userId: Long, val status: String) : ChatEventActionModel - data class MemberPromoted(val userId: Long, val oldStatus: String, val newStatus: String) : ChatEventActionModel - data class MemberRestricted( - val userId: Long, - val oldStatus: String, - val newStatus: String, - val untilDate: Int = 0, - val oldPermissions: ChatPermissionsModel? = null, - val newPermissions: ChatPermissionsModel? = null - ) : ChatEventActionModel - - data class TitleChanged(val oldTitle: String, val newTitle: String) : ChatEventActionModel - data class DescriptionChanged(val oldDescription: String, val newDescription: String) : ChatEventActionModel - data class UsernameChanged(val oldUsername: String, val newUsername: String) : ChatEventActionModel - data class PhotoChanged(val oldPhotoPath: String?, val newPhotoPath: String?) : ChatEventActionModel - data class InviteLinkEdited(val oldLink: String, val newLink: String) : ChatEventActionModel - data class InviteLinkRevoked(val link: String) : ChatEventActionModel - data class InviteLinkDeleted(val link: String) : ChatEventActionModel - data class VideoChatCreated(val groupCallId: Int) : ChatEventActionModel - data class VideoChatEnded(val groupCallId: Int) : ChatEventActionModel - data class Unknown(val type: String) : ChatEventActionModel -} - -data class ChatEventLogFiltersModel( - val messageEdits: Boolean = true, - val messageDeletions: Boolean = true, - val messagePins: Boolean = true, - val memberJoins: Boolean = true, - val memberLeaves: Boolean = true, - val memberInvites: Boolean = true, - val memberPromotions: Boolean = true, - val memberRestrictions: Boolean = true, - val infoChanges: Boolean = true, - val settingChanges: Boolean = true, - val inviteLinkChanges: Boolean = true, - val videoChatChanges: Boolean = true, - val forumChanges: Boolean = true, - val subscriptionExtensions: Boolean = true, - val userIds: List = emptyList() -) - -sealed interface MessageSenderModel { - data class User(val userId: Long) : MessageSenderModel - data class Chat(val chatId: Long) : MessageSenderModel -} diff --git a/domain/src/main/java/org/monogram/domain/models/ChatFullInfoModel.kt b/domain/src/main/java/org/monogram/domain/models/ChatFullInfoModel.kt deleted file mode 100644 index f863f9a4..00000000 --- a/domain/src/main/java/org/monogram/domain/models/ChatFullInfoModel.kt +++ /dev/null @@ -1,35 +0,0 @@ -package org.monogram.domain.models - -data class ChatFullInfoModel( - val description: String? = null, - val inviteLink: String? = null, - val memberCount: Int = 0, - val onlineCount: Int = 0, - val administratorCount: Int = 0, - val restrictedCount: Int = 0, - val bannedCount: Int = 0, - val birthdate: BirthdateModel? = null, - val commonGroupsCount: Int = 0, - val giftCount: Int = 0, - val isBlocked: Boolean = false, - val botInfo: String? = null, - val slowModeDelay: Int = 0, - val locationAddress: String? = null, - val canSetStickerSet: Boolean = false, - val canSetLocation: Boolean = false, - val canGetMembers: Boolean = false, - val canGetStatistics: Boolean = false, - val canGetRevenueStatistics: Boolean = false, - val linkedChatId: Long = 0L, - val businessInfo: BusinessInfoModel? = null, - val note: String? = null, - val canBeCalled: Boolean = false, - val supportsVideoCalls: Boolean = false, - val hasPrivateCalls: Boolean = false, - val hasPrivateForwards: Boolean = false, - val hasRestrictedVoiceAndVideoNoteMessages: Boolean = false, - val hasPostedToProfileStories: Boolean = false, - val setChatBackground: Boolean = false, - val incomingPaidMessageStarCount: Long = 0L, - val outgoingPaidMessageStarCount: Long = 0L, -) \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/models/ChatModel.kt b/domain/src/main/java/org/monogram/domain/models/ChatModel.kt deleted file mode 100644 index 970a8597..00000000 --- a/domain/src/main/java/org/monogram/domain/models/ChatModel.kt +++ /dev/null @@ -1,90 +0,0 @@ -package org.monogram.domain.models - -import kotlinx.serialization.Serializable - -@Serializable -data class ChatModel( - val id: Long, - val title: String, - val unreadCount: Int, - val avatarPath: String? = null, - val personalAvatarPath: String? = null, - val lastMessageText: String = "", - val lastMessageEntities: List = emptyList(), - val lastMessageTime: String = "", - val lastMessageDate: Long = 0L, - val order: Long = 0L, - val isGroup: Boolean = false, - val memberCount: Int = 0, - val onlineCount: Int = 0, - val userStatus: String? = null, - val photoId: Int = 0, - val isPinned: Boolean = false, - val accentColorId: Int = 0, - val profileAccentColorId: Int = -1, - val backgroundCustomEmojiId: Long = 0L, - val emojiStatusPath: String? = null, - val unreadMentionCount: Int = 0, - val isChannel: Boolean = false, - val unreadReactionCount: Int = 0, - val isMarkedAsUnread: Boolean = false, - val isMuted: Boolean = false, - val hasProtectedContent: Boolean = false, - val isTranslatable: Boolean = false, - val hasAutomaticTranslation: Boolean = false, - val messageAutoDeleteTime: Int = 0, - val canBeDeletedOnlyForSelf: Boolean = false, - val canBeDeletedForAllUsers: Boolean = false, - val canBeReported: Boolean = false, - val lastReadInboxMessageId: Long = 0L, - val lastReadOutboxMessageId: Long = 0L, - val lastMessageId: Long = 0L, - val isLastMessageOutgoing: Boolean = false, - val replyMarkupMessageId: Long = 0L, - val messageSenderId: Long? = null, - val blockList: Boolean = false, - val emojiStatusId: Long? = null, - val isSupergroup: Boolean = false, - val isAdmin: Boolean = false, - val isOnline: Boolean = false, - val typingAction: String? = null, - val draftMessage: String? = null, - val draftMessageEntities: List = emptyList(), - val isVerified: Boolean = false, - val isSponsor: Boolean = false, - val viewAsTopics: Boolean = false, - val isForum: Boolean = false, - val permissions: ChatPermissionsModel = ChatPermissionsModel(), - val username: String? = null, - val usernames: UsernamesModel? = null, - val description: String? = null, - val inviteLink: String? = null, - val type: ChatType = ChatType.PRIVATE, - val isBot: Boolean = false, - val isMember: Boolean = true, - val isArchived: Boolean = false, -) - -@Serializable -enum class ChatType { - PRIVATE, BASIC_GROUP, SUPERGROUP, SECRET -} -@Serializable -data class ChatPermissionsModel( - val canSendBasicMessages: Boolean = true, - val canSendAudios: Boolean = true, - val canSendDocuments: Boolean = true, - val canSendPhotos: Boolean = true, - val canSendVideos: Boolean = true, - val canSendVideoNotes: Boolean = true, - val canSendVoiceNotes: Boolean = true, - val canSendPolls: Boolean = true, - val canSendOtherMessages: Boolean = true, - val canAddLinkPreviews: Boolean = true, - val canEditTag: Boolean = false, - val canChangeInfo: Boolean = false, - val canInviteUsers: Boolean = false, - val canPinMessages: Boolean = false, - val canCreateTopics: Boolean = false -) - diff --git a/domain/src/main/java/org/monogram/domain/models/FileModel.kt b/domain/src/main/java/org/monogram/domain/models/FileModel.kt deleted file mode 100644 index 760eec4d..00000000 --- a/domain/src/main/java/org/monogram/domain/models/FileModel.kt +++ /dev/null @@ -1,33 +0,0 @@ -package org.monogram.domain.models - -import kotlinx.serialization.Serializable - -@Serializable -data class FileModel( - val id: Int, - val size: Long, - val expectedSize: Long, - val local: FileLocalModel, - val remote: FileRemoteModel? = null -) - -@Serializable -data class FileLocalModel( - val path: String, - val isDownloadingActive: Boolean, - val canBeDownloaded: Boolean, - val isDownloadingCompleted: Boolean, - val canBeDeleted: Boolean = false, - val downloadOffset: Long = 0, - val downloadedPrefixSize: Long = 0, - val downloadedSize: Long = 0 -) - -@Serializable -data class FileRemoteModel( - val id: String, - val uniqueId: String, - val isUploadingActive: Boolean, - val isUploadingCompleted: Boolean, - val uploadedSize: Long -) diff --git a/domain/src/main/java/org/monogram/domain/models/FolderModel.kt b/domain/src/main/java/org/monogram/domain/models/FolderModel.kt deleted file mode 100644 index d526cb27..00000000 --- a/domain/src/main/java/org/monogram/domain/models/FolderModel.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.monogram.domain.models - -import kotlinx.serialization.Serializable - - -@Serializable -data class FolderModel( - val id: Int, - val title: String, - val iconName: String? = null, - val unreadCount: Int = 0, - val includedChatIds: List = emptyList(), - val pinnedChatIds: List = emptyList() -) \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/models/GroupMemberModel.kt b/domain/src/main/java/org/monogram/domain/models/GroupMemberModel.kt deleted file mode 100644 index 107634d2..00000000 --- a/domain/src/main/java/org/monogram/domain/models/GroupMemberModel.kt +++ /dev/null @@ -1,9 +0,0 @@ -package org.monogram.domain.models - -import org.monogram.domain.repository.ChatMemberStatus - -data class GroupMemberModel( - val user: UserModel, - val rank: String? = null, - val status: ChatMemberStatus? = null -) \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/models/MessageModel.kt b/domain/src/main/java/org/monogram/domain/models/MessageModel.kt deleted file mode 100644 index 11bf6fbf..00000000 --- a/domain/src/main/java/org/monogram/domain/models/MessageModel.kt +++ /dev/null @@ -1,592 +0,0 @@ -package org.monogram.domain.models - -import kotlinx.serialization.Serializable - -data class MessageModel( - val id: Long, - val date: Int, - val isOutgoing: Boolean, - val senderName: String, - val chatId: Long, - val content: MessageContent, - val senderId: Long = 0, - val senderAvatar: String? = null, - val senderPersonalAvatar: String? = null, - val senderCustomTitle: String? = null, - val isRead: Boolean = false, - val replyToMsgId: Long? = null, - val replyToMsg: MessageModel? = null, - val forwardInfo: ForwardInfo? = null, - val views: Int? = null, - val viewCount: Int? = null, - val mediaAlbumId: Long = 0L, - val editDate: Int = 0, - val sendingState: MessageSendingState? = null, - val isChosen: Boolean = false, - val readDate: Int = 0, - val reactions: List = emptyList(), - val isSenderVerified: Boolean = false, - val threadId: Int? = null, - val canBeEdited: Boolean = false, - val canBeForwarded: Boolean = true, - val canBeDeletedOnlyForSelf: Boolean = true, - val canBeDeletedForAllUsers: Boolean = false, - val canBeSaved: Boolean = true, - val canGetMessageThread: Boolean = false, - val canGetStatistics: Boolean = false, - val canGetRevenueStatistics: Boolean = false, - val canGetMediaStatistics: Boolean = false, - val canGetReadReceipts: Boolean = false, - val canGetViewers: Boolean = false, - val replyCount: Int = 0, - val replyMarkup: ReplyMarkupModel? = null, - val viaBotUserId: Long = 0L, - val viaBotName: String? = null, - val isSenderPremium: Boolean = false, - val senderStatusEmojiId: Long = 0L, - val senderStatusEmojiPath: String? = null -) - -data class ForwardInfo( - val date: Int, - val fromId: Long, - val fromName: String, - val originChatId: Long? = null, - val originMessageId: Long? = null -) - -sealed interface MessageSendingState { - object Pending : MessageSendingState - data class Failed(val errorCode: Int, val errorMessage: String) : MessageSendingState -} - -sealed interface MessageContent { - data class Text( - val text: String, - val entities: List = emptyList(), - val webPage: WebPage? = null - ) : MessageContent - - data class Service( - val text: String - ) : MessageContent - - data class Photo( - val path: String?, - val thumbnailPath: String? = null, - val width: Int, - val height: Int, - val caption: String = "", - val entities: List = emptyList(), - val isUploading: Boolean = false, - val uploadProgress: Float = 0f, - val isDownloading: Boolean = false, - val downloadProgress: Float = 0f, - val downloadError: Boolean = false, - val fileId: Int = 0, - val minithumbnail: ByteArray? = null, - val hasSpoiler: Boolean = false - ) : MessageContent { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as Photo - - if (width != other.width) return false - if (height != other.height) return false - if (isUploading != other.isUploading) return false - if (uploadProgress != other.uploadProgress) return false - if (isDownloading != other.isDownloading) return false - if (downloadProgress != other.downloadProgress) return false - if (downloadError != other.downloadError) return false - if (fileId != other.fileId) return false - if (hasSpoiler != other.hasSpoiler) return false - if (path != other.path) return false - if (thumbnailPath != other.thumbnailPath) return false - if (caption != other.caption) return false - if (entities != other.entities) return false - if (!minithumbnail.contentEquals(other.minithumbnail)) return false - - return true - } - - override fun hashCode(): Int { - var result = width - result = 31 * result + height - result = 31 * result + isUploading.hashCode() - result = 31 * result + uploadProgress.hashCode() - result = 31 * result + isDownloading.hashCode() - result = 31 * result + downloadProgress.hashCode() - result = 31 * result + downloadError.hashCode() - result = 31 * result + fileId - result = 31 * result + hasSpoiler.hashCode() - result = 31 * result + (path?.hashCode() ?: 0) - result = 31 * result + (thumbnailPath?.hashCode() ?: 0) - result = 31 * result + caption.hashCode() - result = 31 * result + entities.hashCode() - result = 31 * result + (minithumbnail?.contentHashCode() ?: 0) - return result - } - } - - data class Video( - val path: String?, - val thumbnailPath: String? = null, - val width: Int, - val height: Int, - val duration: Int, - val caption: String = "", - val entities: List = emptyList(), - val isUploading: Boolean = false, - val uploadProgress: Float = 0f, - val isDownloading: Boolean = false, - val downloadProgress: Float = 0f, - val downloadError: Boolean = false, - val fileId: Int = 0, - val minithumbnail: ByteArray? = null, - val supportsStreaming: Boolean = false, - val hasSpoiler: Boolean = false - ) : MessageContent { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as Video - - if (width != other.width) return false - if (height != other.height) return false - if (duration != other.duration) return false - if (isUploading != other.isUploading) return false - if (uploadProgress != other.uploadProgress) return false - if (isDownloading != other.isDownloading) return false - if (downloadProgress != other.downloadProgress) return false - if (downloadError != other.downloadError) return false - if (fileId != other.fileId) return false - if (supportsStreaming != other.supportsStreaming) return false - if (hasSpoiler != other.hasSpoiler) return false - if (path != other.path) return false - if (thumbnailPath != other.thumbnailPath) return false - if (caption != other.caption) return false - if (entities != other.entities) return false - if (!minithumbnail.contentEquals(other.minithumbnail)) return false - - return true - } - - override fun hashCode(): Int { - var result = width - result = 31 * result + height - result = 31 * result + duration - result = 31 * result + isUploading.hashCode() - result = 31 * result + uploadProgress.hashCode() - result = 31 * result + isDownloading.hashCode() - result = 31 * result + downloadProgress.hashCode() - result = 31 * result + downloadError.hashCode() - result = 31 * result + fileId - result = 31 * result + supportsStreaming.hashCode() - result = 31 * result + hasSpoiler.hashCode() - result = 31 * result + (path?.hashCode() ?: 0) - result = 31 * result + (thumbnailPath?.hashCode() ?: 0) - result = 31 * result + caption.hashCode() - result = 31 * result + entities.hashCode() - result = 31 * result + (minithumbnail?.contentHashCode() ?: 0) - return result - } - } - - data class Voice( - val path: String?, - val duration: Int, - val waveform: ByteArray? = null, - val isUploading: Boolean = false, - val uploadProgress: Float = 0f, - val isDownloading: Boolean = false, - val downloadProgress: Float = 0f, - val downloadError: Boolean = false, - val fileId: Int = 0 - ) : MessageContent { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as Voice - - if (duration != other.duration) return false - if (isUploading != other.isUploading) return false - if (uploadProgress != other.uploadProgress) return false - if (isDownloading != other.isDownloading) return false - if (downloadProgress != other.downloadProgress) return false - if (downloadError != other.downloadError) return false - if (fileId != other.fileId) return false - if (path != other.path) return false - if (!waveform.contentEquals(other.waveform)) return false - - return true - } - - override fun hashCode(): Int { - var result = duration - result = 31 * result + isUploading.hashCode() - result = 31 * result + uploadProgress.hashCode() - result = 31 * result + isDownloading.hashCode() - result = 31 * result + downloadProgress.hashCode() - result = 31 * result + downloadError.hashCode() - result = 31 * result + fileId - result = 31 * result + (path?.hashCode() ?: 0) - result = 31 * result + (waveform?.contentHashCode() ?: 0) - return result - } - } - - data class VideoNote( - val path: String?, - val thumbnail: String?, - val duration: Int, - val length: Int, - val isUploading: Boolean = false, - val uploadProgress: Float = 0f, - val isDownloading: Boolean = false, - val downloadProgress: Float = 0f, - val downloadError: Boolean = false, - val fileId: Int = 0 - ) : MessageContent - - data class Document( - val path: String?, - val fileName: String, - val mimeType: String, - val size: Long, - val caption: String = "", - val entities: List = emptyList(), - val isUploading: Boolean = false, - val uploadProgress: Float = 0f, - val isDownloading: Boolean = false, - val downloadProgress: Float = 0f, - val downloadError: Boolean = false, - val fileId: Int = 0 - ) : MessageContent - - data class Audio( - val path: String?, - val duration: Int, - val title: String, - val performer: String, - val fileName: String, - val mimeType: String, - val size: Long, - val caption: String = "", - val entities: List = emptyList(), - val isUploading: Boolean = false, - val uploadProgress: Float = 0f, - val isDownloading: Boolean = false, - val downloadProgress: Float = 0f, - val downloadError: Boolean = false, - val fileId: Int = 0 - ) : MessageContent - - data class Sticker( - val id: Long, - val setId: Long, - val path: String?, - val width: Int, - val height: Int, - val emoji: String = "", - val format: StickerFormat = StickerFormat.UNKNOWN, - val isDownloading: Boolean = false, - val downloadProgress: Float = 0f, - val downloadError: Boolean = false, - val fileId: Int = 0 - ) : MessageContent - - data class Gif( - val path: String?, - val width: Int, - val height: Int, - val caption: String = "", - val entities: List = emptyList(), - val isUploading: Boolean = false, - val uploadProgress: Float = 0f, - val isDownloading: Boolean = false, - val downloadProgress: Float = 0f, - val downloadError: Boolean = false, - val fileId: Int = 0, - val minithumbnail: ByteArray? = null, - val hasSpoiler: Boolean = false - ) : MessageContent { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as Gif - - if (width != other.width) return false - if (height != other.height) return false - if (isUploading != other.isUploading) return false - if (uploadProgress != other.uploadProgress) return false - if (isDownloading != other.isDownloading) return false - if (downloadProgress != other.downloadProgress) return false - if (downloadError != other.downloadError) return false - if (fileId != other.fileId) return false - if (hasSpoiler != other.hasSpoiler) return false - if (path != other.path) return false - if (caption != other.caption) return false - if (entities != other.entities) return false - if (!minithumbnail.contentEquals(other.minithumbnail)) return false - - return true - } - - override fun hashCode(): Int { - var result = width - result = 31 * result + height - result = 31 * result + isUploading.hashCode() - result = 31 * result + uploadProgress.hashCode() - result = 31 * result + isDownloading.hashCode() - result = 31 * result + downloadProgress.hashCode() - result = 31 * result + downloadError.hashCode() - result = 31 * result + fileId - result = 31 * result + hasSpoiler.hashCode() - result = 31 * result + (path?.hashCode() ?: 0) - result = 31 * result + caption.hashCode() - result = 31 * result + entities.hashCode() - result = 31 * result + (minithumbnail?.contentHashCode() ?: 0) - return result - } - } - - data class Contact( - val phoneNumber: String, - val firstName: String, - val lastName: String, - val vcard: String, - val userId: Long, - val avatarPath: String? = null - ) : MessageContent - - data class Poll( - val id: Long, - val question: String, - val options: List, - val totalVoterCount: Int, - val isClosed: Boolean, - val isAnonymous: Boolean, - val type: PollType, - val openPeriod: Int, - val closeDate: Int - ) : MessageContent - - data class Location( - val latitude: Double, - val longitude: Double, - val horizontalAccuracy: Double = 0.0, - val livePeriod: Int = 0, - val heading: Int = 0, - val proximityAlertRadius: Int = 0 - ) : MessageContent - - data class Venue( - val latitude: Double, - val longitude: Double, - val title: String, - val address: String, - val provider: String, - val venueId: String, - val venueType: String - ) : MessageContent - - object Unsupported : MessageContent -} - -data class WebPage( - val url: String?, - val displayUrl: String?, - val type: LinkPreviewType, - val siteName: String?, - val title: String?, - val description: String?, - val photo: Photo?, - val embedUrl: String?, - val embedType: String?, - val embedWidth: Int, - val embedHeight: Int, - val duration: Int, - val author: String?, - val video: Video?, - val audio: Audio?, - val document: Document?, - val sticker: Sticker?, - val animation: Animation?, - val instantViewVersion: Int = 0 -) { - sealed interface LinkPreviewType { - object Album : LinkPreviewType - object Animation : LinkPreviewType - object App : LinkPreviewType - object Article : LinkPreviewType - object Audio : LinkPreviewType - object Background : LinkPreviewType - object ChannelBoost : LinkPreviewType - data class Chat(val chatId: Long) : LinkPreviewType - object ChatFolder : LinkPreviewType - object DirectMessagesChat : LinkPreviewType - object Document : LinkPreviewType - data class EmbeddedAnimation(val url: String) : LinkPreviewType - data class EmbeddedAudio(val url: String) : LinkPreviewType - data class EmbeddedVideo(val url: String) : LinkPreviewType - data class ExternalAudio(val url: String) : LinkPreviewType - data class ExternalVideo(val url: String) : LinkPreviewType - object GiftCollection : LinkPreviewType - object GroupCall : LinkPreviewType - object Invoice : LinkPreviewType - object Message : LinkPreviewType - object Photo : LinkPreviewType - object PremiumGiftCode : LinkPreviewType - object Sticker : LinkPreviewType - object StickerSet : LinkPreviewType - data class Story(val chatId: Long, val storyId: Int) : LinkPreviewType - object StoryAlbum : LinkPreviewType - object SupergroupBoost : LinkPreviewType - object Theme : LinkPreviewType - object Unsupported : LinkPreviewType - object UpgradedGift : LinkPreviewType - data class User(val userId: Long) : LinkPreviewType - object Video : LinkPreviewType - object VideoChat : LinkPreviewType - object VideoNote : LinkPreviewType - object VoiceNote : LinkPreviewType - data class WebApp(val url: String) : LinkPreviewType - object Unknown : LinkPreviewType - object InstantView : LinkPreviewType - } - - data class Photo( - val path: String?, - val width: Int, - val height: Int, - val fileId: Int, - val minithumbnail: ByteArray? - ) { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as Photo - - if (width != other.width) return false - if (height != other.height) return false - if (fileId != other.fileId) return false - if (path != other.path) return false - if (!minithumbnail.contentEquals(other.minithumbnail)) return false - - return true - } - - override fun hashCode(): Int { - var result = width - result = 31 * result + height - result = 31 * result + fileId - result = 31 * result + (path?.hashCode() ?: 0) - result = 31 * result + (minithumbnail?.contentHashCode() ?: 0) - return result - } - } - - data class Video( - val path: String?, - val width: Int, - val height: Int, - val duration: Int, - val fileId: Int, - val supportsStreaming: Boolean = false - ) - - data class Audio( - val path: String?, - val duration: Int, - val title: String?, - val performer: String?, - val fileId: Int - ) - - data class Document( - val path: String?, - val fileName: String?, - val mimeType: String?, - val size: Long, - val fileId: Int - ) - - data class Sticker( - val path: String?, - val width: Int, - val height: Int, - val emoji: String?, - val fileId: Int - ) - - data class Animation( - val path: String?, - val width: Int, - val height: Int, - val duration: Int, - val fileId: Int - ) -} - -data class PollOption( - val text: String, - val voterCount: Int, - val votePercentage: Int, - val isChosen: Boolean, - val isBeingChosen: Boolean = false -) - -sealed interface PollType { - data class Regular(val allowMultipleAnswers: Boolean) : PollType - data class Quiz(val correctOptionId: Int, val explanation: String?) : PollType -} - -@Serializable -data class MessageEntity( - val offset: Int, - val length: Int, - val type: MessageEntityType -) - -@Serializable -sealed interface MessageEntityType { - object Bold : MessageEntityType - object Italic : MessageEntityType - object Underline : MessageEntityType - object Strikethrough : MessageEntityType - object Spoiler : MessageEntityType - object Code : MessageEntityType - data class Pre(val language: String = "") : MessageEntityType - data class TextUrl(val url: String) : MessageEntityType - object Mention : MessageEntityType - data class TextMention(val userId: Long) : MessageEntityType - object Hashtag : MessageEntityType - object BotCommand : MessageEntityType - object Url : MessageEntityType - object Email : MessageEntityType - object PhoneNumber : MessageEntityType - object BankCardNumber : MessageEntityType - data class CustomEmoji(val emojiId: Long, val path: String? = null) : MessageEntityType - object Other : MessageEntityType -} - -data class MessageReactionModel( - val emoji: String? = null, - val customEmojiId: Long? = null, - val customEmojiPath: String? = null, - val count: Int, - val isChosen: Boolean, - val recentSenders: List = emptyList() -) - -data class ReactionSender( - val id: Long, - val name: String = "", - val avatar: String? = null -) \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/models/MessageSendOptions.kt b/domain/src/main/java/org/monogram/domain/models/MessageSendOptions.kt deleted file mode 100644 index af78d88a..00000000 --- a/domain/src/main/java/org/monogram/domain/models/MessageSendOptions.kt +++ /dev/null @@ -1,6 +0,0 @@ -package org.monogram.domain.models - -data class MessageSendOptions( - val silent: Boolean = false, - val scheduleDate: Int? = null -) diff --git a/domain/src/main/java/org/monogram/domain/models/MessageViewerModel.kt b/domain/src/main/java/org/monogram/domain/models/MessageViewerModel.kt deleted file mode 100644 index d2148b85..00000000 --- a/domain/src/main/java/org/monogram/domain/models/MessageViewerModel.kt +++ /dev/null @@ -1,6 +0,0 @@ -package org.monogram.domain.models - -data class MessageViewerModel( - val user: UserModel, - val viewedDate: Int -) \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/models/NetworkUsageModel.kt b/domain/src/main/java/org/monogram/domain/models/NetworkUsageModel.kt deleted file mode 100644 index c43e36ba..00000000 --- a/domain/src/main/java/org/monogram/domain/models/NetworkUsageModel.kt +++ /dev/null @@ -1,20 +0,0 @@ -package org.monogram.domain.models - -data class NetworkUsageModel( - val mobile: NetworkTypeUsage, - val wifi: NetworkTypeUsage, - val roaming: NetworkTypeUsage, - val other: NetworkTypeUsage -) - -data class NetworkTypeUsage( - val sent: Long, - val received: Long, - val details: List -) - -data class NetworkUsageCategory( - val name: String, - val sent: Long, - val received: Long -) diff --git a/domain/src/main/java/org/monogram/domain/models/PremiumStateModel.kt b/domain/src/main/java/org/monogram/domain/models/PremiumStateModel.kt deleted file mode 100644 index 4d3a1a38..00000000 --- a/domain/src/main/java/org/monogram/domain/models/PremiumStateModel.kt +++ /dev/null @@ -1,50 +0,0 @@ -package org.monogram.domain.models - -data class PremiumStateModel( - val state: String, - val animations: List = emptyList(), - val paymentOptions: List = emptyList() -) - -enum class PremiumFeatureType { - DOUBLE_LIMITS, - VOICE_TO_TEXT, - FASTER_DOWNLOAD, - TRANSLATION, - ANIMATED_EMOJI, - ADVANCED_CHAT_MANAGEMENT, - NO_ADS, - INFINITE_REACTIONS, - BADGE, - PROFILE_BADGE, - APP_ICONS, - UNKNOWN -} - -enum class PremiumSource { - SETTINGS, - LIMIT_EXCEEDED, - VIDEO_STATUS, - STORY_STATUS, - LINK -} - -enum class PremiumLimitType { - SUPERGROUP_COUNT, - CHAT_FOLDER_COUNT, - PINNED_CHAT_COUNT, - CREATED_PUBLIC_CHAT_COUNT, - CHAT_FOLDER_INVITE_LINK_COUNT, - SHAREABLE_CHAT_FOLDER_COUNT, - ACTIVE_STORY_COUNT, - WEEKLY_SENT_MESSAGE_COUNT, - MONTHLY_SENT_MESSAGE_COUNT -} - -data class PremiumPaymentOptionModel( - val currency: String, - val amount: Long, - val monthCount: Int, - val storeProductId: String, - val paymentLink: String? -) diff --git a/domain/src/main/java/org/monogram/domain/models/PrivacyModels.kt b/domain/src/main/java/org/monogram/domain/models/PrivacyModels.kt deleted file mode 100644 index 0cf10e62..00000000 --- a/domain/src/main/java/org/monogram/domain/models/PrivacyModels.kt +++ /dev/null @@ -1,18 +0,0 @@ -package org.monogram.domain.models - -sealed class PrivacyRule { - object AllowAll : PrivacyRule() - object AllowContacts : PrivacyRule() - object AllowNone : PrivacyRule() - data class AllowUsers(val userIds: List) : PrivacyRule() - data class AllowChatMembers(val chatIds: List) : PrivacyRule() - object DisallowContacts : PrivacyRule() - data class DisallowUsers(val userIds: List) : PrivacyRule() - data class DisallowChatMembers(val chatIds: List) : PrivacyRule() -} - -enum class PrivacyValue { - EVERYBODY, - MY_CONTACTS, - NOBODY -} \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/models/ProxyModel.kt b/domain/src/main/java/org/monogram/domain/models/ProxyModel.kt deleted file mode 100644 index 57818ab6..00000000 --- a/domain/src/main/java/org/monogram/domain/models/ProxyModel.kt +++ /dev/null @@ -1,31 +0,0 @@ -package org.monogram.domain.models - -data class ProxyModel( - val id: Int, - val server: String, - val port: Int, - val lastUsedDate: Int, - val isEnabled: Boolean, - val type: ProxyTypeModel, - val ping: Long? = null -) { - val secret: String? - get() = (type as? ProxyTypeModel.Mtproto)?.secret -} - -sealed class ProxyTypeModel { - data class Socks5( - val username: String, - val password: String - ) : ProxyTypeModel() - - data class Http( - val username: String, - val password: String, - val httpOnly: Boolean - ) : ProxyTypeModel() - - data class Mtproto( - val secret: String - ) : ProxyTypeModel() -} diff --git a/domain/src/main/java/org/monogram/domain/models/ReplyMarkupModel.kt b/domain/src/main/java/org/monogram/domain/models/ReplyMarkupModel.kt deleted file mode 100644 index 93ac5914..00000000 --- a/domain/src/main/java/org/monogram/domain/models/ReplyMarkupModel.kt +++ /dev/null @@ -1,62 +0,0 @@ -package org.monogram.domain.models - -sealed interface ReplyMarkupModel { - data class InlineKeyboard(val rows: List>) : ReplyMarkupModel - data class ShowKeyboard( - val rows: List>, - val isPersistent: Boolean, - val resizeKeyboard: Boolean, - val oneTime: Boolean, - val isPersonal: Boolean, - val inputFieldPlaceholder: String - ) : ReplyMarkupModel - - data class RemoveKeyboard(val isPersonal: Boolean) : ReplyMarkupModel - data class ForceReply(val isPersonal: Boolean, val inputFieldPlaceholder: String) : ReplyMarkupModel -} - -data class InlineKeyboardButtonModel( - val text: String, - val type: InlineKeyboardButtonType -) - -sealed interface InlineKeyboardButtonType { - data class Url(val url: String) : InlineKeyboardButtonType - data class Callback(val data: ByteArray) : InlineKeyboardButtonType { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as Callback - - return data.contentEquals(other.data) - } - - override fun hashCode(): Int { - return data.contentHashCode() - } - } - - data class WebApp(val url: String) : InlineKeyboardButtonType - data class LoginUrl(val url: String, val id: Long) : InlineKeyboardButtonType - data class SwitchInline(val query: String) : InlineKeyboardButtonType - data class Buy(val slug: String? = null) : InlineKeyboardButtonType - data class User(val userId: Long) : InlineKeyboardButtonType - object Unsupported : InlineKeyboardButtonType -} - -data class KeyboardButtonModel( - val text: String, - val type: KeyboardButtonType -) - -sealed interface KeyboardButtonType { - object Text : KeyboardButtonType - object RequestPhoneNumber : KeyboardButtonType - object RequestLocation : KeyboardButtonType - data class RequestPoll(val forceQuiz: Boolean, val forceRegular: Boolean) : KeyboardButtonType - data class WebApp(val url: String) : KeyboardButtonType - data class RequestUsers(val id: Int) : KeyboardButtonType - data class RequestChat(val id: Int) : KeyboardButtonType - object Unsupported : KeyboardButtonType -} \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/models/SessionModel.kt b/domain/src/main/java/org/monogram/domain/models/SessionModel.kt deleted file mode 100644 index a0d35e94..00000000 --- a/domain/src/main/java/org/monogram/domain/models/SessionModel.kt +++ /dev/null @@ -1,25 +0,0 @@ -package org.monogram.domain.models - -data class SessionModel( - val id: Long, - val isCurrent: Boolean, - val isPasswordPending: Boolean, - val isUnconfirmed: Boolean, - val applicationName: String, - val applicationVersion: String, - val deviceModel: String, - val platform: String, - val systemVersion: String, - val logInDate: Int, - val lastActiveDate: Int, - val ipAddress: String, - val location: String, - val isOfficial: Boolean, - val type: SessionType -) - -enum class SessionType { - Android, Apple, Brave, Chrome, Edge, Firefox, - Ipad, Iphone, Linux, Mac, Opera, Safari, - Ubuntu, Unknown, Vivaldi, Windows, Xbox -} \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/models/StatisticsModels.kt b/domain/src/main/java/org/monogram/domain/models/StatisticsModels.kt deleted file mode 100644 index 22f156f9..00000000 --- a/domain/src/main/java/org/monogram/domain/models/StatisticsModels.kt +++ /dev/null @@ -1,111 +0,0 @@ -package org.monogram.domain.models - -data class ChatStatisticsModel( - val type: StatisticsType, - val period: DateRangeModel, - val memberCount: StatisticsValueModel, - val messageCount: StatisticsValueModel? = null, - val viewerCount: StatisticsValueModel? = null, - val senderCount: StatisticsValueModel? = null, - val viewCount: StatisticsValueModel? = null, - val meanViewCount: StatisticsValueModel? = null, - val meanShareCount: StatisticsValueModel? = null, - val meanReactionCount: StatisticsValueModel? = null, - val meanStoryViewCount: StatisticsValueModel? = null, - val meanStoryShareCount: StatisticsValueModel? = null, - val meanStoryReactionCount: StatisticsValueModel? = null, - val enabledNotificationsPercentage: Double? = null, - val topSenders: List = emptyList(), - val topAdministrators: List = emptyList(), - val topInviters: List = emptyList(), - val recentInteractions: List = emptyList(), - val memberCountGraph: StatisticsGraphModel? = null, - val joinGraph: StatisticsGraphModel? = null, - val muteGraph: StatisticsGraphModel? = null, - val viewCountByHourGraph: StatisticsGraphModel? = null, - val viewCountBySourceGraph: StatisticsGraphModel? = null, - val joinBySourceGraph: StatisticsGraphModel? = null, - val languageGraph: StatisticsGraphModel? = null, - val messageContentGraph: StatisticsGraphModel? = null, - val actionGraph: StatisticsGraphModel? = null, - val dayGraph: StatisticsGraphModel? = null, - val weekGraph: StatisticsGraphModel? = null, - val topHoursGraph: StatisticsGraphModel? = null, - val messageReactionGraph: StatisticsGraphModel? = null, - val storyInteractionGraph: StatisticsGraphModel? = null, - val storyReactionGraph: StatisticsGraphModel? = null -) - -enum class StatisticsType { - SUPERGROUP, CHANNEL -} - -data class ChatRevenueStatisticsModel( - val revenueByHourGraph: StatisticsGraphModel, - val revenueGraph: StatisticsGraphModel, - val revenueAmount: RevenueAmountModel, - val usdRate: Double -) - -data class DateRangeModel( - val startDate: Int, - val endDate: Int -) - -data class StatisticsValueModel( - val value: Double, - val previousValue: Double, - val growthRatePercentage: Double -) - -data class TopSenderModel( - val userId: Long, - val sentMessageCount: Int, - val averageCharacterCount: Int -) - -data class TopAdministratorModel( - val userId: Long, - val deletedMessageCount: Int, - val bannedUserCount: Int, - val restrictedUserCount: Int -) - -data class TopInviterModel( - val userId: Long, - val addedMemberCount: Int -) - -data class RevenueAmountModel( - val currency: String, - val balance: Long, - val availableBalance: Long -) - -data class ChatInteractionInfoModel( - val objectId: Long, - val type: ChatInteractionType, - val viewCount: Int, - val forwardCount: Int, - val reactionCount: Int, - val previewText: String? = null -) - -enum class ChatInteractionType { - MESSAGE, STORY -} - -sealed class StatisticsGraphModel { - data class Data( - val jsonData: String, - val zoomToken: String? - ) : StatisticsGraphModel() - - data class Async( - val token: String - ) : StatisticsGraphModel() - - data class Error( - val errorMessage: String - ) : StatisticsGraphModel() -} diff --git a/domain/src/main/java/org/monogram/domain/models/StickerSetModel.kt b/domain/src/main/java/org/monogram/domain/models/StickerSetModel.kt deleted file mode 100644 index f3a911ee..00000000 --- a/domain/src/main/java/org/monogram/domain/models/StickerSetModel.kt +++ /dev/null @@ -1,64 +0,0 @@ -package org.monogram.domain.models - -import kotlinx.serialization.Serializable - -@Serializable -data class StickerSetModel( - val id: Long, - val title: String, - val name: String, - val stickers: List, - val thumbnail: StickerModel? = null, - val isInstalled: Boolean = false, - val isArchived: Boolean = false, - val isOfficial: Boolean = false, - val stickerType: StickerType = StickerType.REGULAR -) - -@Serializable -enum class StickerType { - REGULAR, - MASK, - CUSTOM_EMOJI -} - -data class StickerSetInfoModel( - val id: Long, - val title: String, - val name: String, - val cover: StickerModel? = null -) - -@Serializable -enum class StickerFormat { - STATIC, - ANIMATED, - VIDEO, - UNKNOWN -} - -@Serializable -data class StickerModel( - val id: Long, - val customEmojiId: Long? = null, - val width: Int, - val height: Int, - val emoji: String, - val path: String?, - val format: StickerFormat -) - -@Serializable -data class GifModel( - val id: String, - val fileId: Long, - val thumbFileId: Long?, - val width: Int, - val height: Int -) - -@Serializable -data class RecentEmojiModel( - val emoji: String, - val sticker: StickerModel? = null -) diff --git a/domain/src/main/java/org/monogram/domain/models/StorageUsageModel.kt b/domain/src/main/java/org/monogram/domain/models/StorageUsageModel.kt deleted file mode 100644 index 008da11b..00000000 --- a/domain/src/main/java/org/monogram/domain/models/StorageUsageModel.kt +++ /dev/null @@ -1,21 +0,0 @@ -package org.monogram.domain.models - -data class StorageUsageModel( - val totalSize: Long, - val fileCount: Int, - val chatStats: List -) - -data class ChatStorageUsageModel( - val chatId: Long, - val chatTitle: String = "", - val size: Long, - val fileCount: Int, - val byFileType: List -) - -data class FileTypeStorageUsageModel( - val fileType: String, - val size: Long, - val fileCount: Int -) diff --git a/domain/src/main/java/org/monogram/domain/models/TopicModel.kt b/domain/src/main/java/org/monogram/domain/models/TopicModel.kt deleted file mode 100644 index fd1d0c44..00000000 --- a/domain/src/main/java/org/monogram/domain/models/TopicModel.kt +++ /dev/null @@ -1,18 +0,0 @@ -package org.monogram.domain.models - -data class TopicModel( - val id: Int, - val name: String, - val iconCustomEmojiId: Long = 0L, - val iconCustomEmojiPath: String? = null, - val iconColor: Int = 0, - val isClosed: Boolean = false, - val isPinned: Boolean = false, - val unreadCount: Int = 0, - val lastMessageText: String = "", - val lastMessageEntities: List = emptyList(), - val lastMessageTime: String = "", - val order: Long = 0L, - val lastMessageSenderName: String? = null, - val lastMessageSenderAvatar: String? = null -) \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/models/UpdateInfo.kt b/domain/src/main/java/org/monogram/domain/models/UpdateInfo.kt deleted file mode 100644 index 720a4fea..00000000 --- a/domain/src/main/java/org/monogram/domain/models/UpdateInfo.kt +++ /dev/null @@ -1,26 +0,0 @@ -package org.monogram.domain.models - -data class UpdateInfo( - val version: String, - val versionCode: Int, - val description: String, - val changelog: List, - val fileId: Int, - val fileName: String, - val fileSize: Long -) - -data class RichText( - val text: String, - val entities: List = emptyList() -) - -sealed interface UpdateState { - object Idle : UpdateState - object Checking : UpdateState - data class UpdateAvailable(val info: UpdateInfo) : UpdateState - object UpToDate : UpdateState - data class Downloading(val progress: Float, val totalSize: Long) : UpdateState - data class ReadyToInstall(val filePath: String) : UpdateState - data class Error(val message: String) : UpdateState -} diff --git a/domain/src/main/java/org/monogram/domain/models/UserModel.kt b/domain/src/main/java/org/monogram/domain/models/UserModel.kt deleted file mode 100644 index 019c302b..00000000 --- a/domain/src/main/java/org/monogram/domain/models/UserModel.kt +++ /dev/null @@ -1,36 +0,0 @@ -package org.monogram.domain.models - -data class UserModel( - val id: Long, - val firstName: String, - val lastName: String? = null, - val username: String? = "", - val usernames: UsernamesModel? = null, - val phoneNumber: String? = "", - val avatarPath: String? = null, - val personalAvatarPath: String? = null, - val accentColorId: Int = 0, - val profileAccentColorId: Int = -1, - val lastSeen: Long = 0L, - val isPremium: Boolean = false, - val isVerified: Boolean = false, - val isSponsor: Boolean = false, - val isSupport: Boolean = false, - val userStatus: UserStatusType = UserStatusType.OFFLINE, - val statusEmojiId: Long = 0L, - val statusEmojiPath: String? = null, - val isContact: Boolean = false, - val isMutualContact: Boolean = false, - val isCloseFriend: Boolean = false, - val type: UserTypeEnum = UserTypeEnum.REGULAR, - val haveAccess: Boolean = true, - val languageCode: String? = null -) - -enum class UserStatusType { - ONLINE, OFFLINE, RECENTLY, LAST_WEEK, LAST_MONTH -} - -enum class UserTypeEnum { - REGULAR, BOT, DELETED, UNKNOWN -} \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/models/UsernamesModel.kt b/domain/src/main/java/org/monogram/domain/models/UsernamesModel.kt deleted file mode 100644 index f685cb50..00000000 --- a/domain/src/main/java/org/monogram/domain/models/UsernamesModel.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.monogram.domain.models - -import kotlinx.serialization.Serializable - -@Serializable -data class UsernamesModel( - val activeUsernames: List = emptyList(), - val disabledUsernames: List = emptyList(), - val collectibleUsernames: List = emptyList() -) diff --git a/domain/src/main/java/org/monogram/domain/models/WallpaperModel.kt b/domain/src/main/java/org/monogram/domain/models/WallpaperModel.kt deleted file mode 100644 index d7f3c8ec..00000000 --- a/domain/src/main/java/org/monogram/domain/models/WallpaperModel.kt +++ /dev/null @@ -1,36 +0,0 @@ -package org.monogram.domain.models - -import kotlinx.serialization.Serializable - -@Serializable -data class WallpaperModel( - val id: Long, - val slug: String, - val title: String, - val pattern: Boolean, - val documentId: Long, - val thumbnail: ThumbnailModel?, - val settings: WallpaperSettings?, - val isDownloaded: Boolean, - val localPath: String?, - val isDefault: Boolean = false -) - -@Serializable -data class ThumbnailModel( - val fileId: Int, - val width: Int, - val height: Int, - val localPath: String? -) - -@Serializable -data class WallpaperSettings( - val backgroundColor: Int?, - val secondBackgroundColor: Int?, - val thirdBackgroundColor: Int?, - val fourthBackgroundColor: Int?, - val intensity: Int?, - val rotation: Int?, - val isInverted: Boolean? = null -) diff --git a/domain/src/main/java/org/monogram/domain/models/webapp/InstantViewModel.kt b/domain/src/main/java/org/monogram/domain/models/webapp/InstantViewModel.kt deleted file mode 100644 index 2c3c1705..00000000 --- a/domain/src/main/java/org/monogram/domain/models/webapp/InstantViewModel.kt +++ /dev/null @@ -1,129 +0,0 @@ -package org.monogram.domain.models.webapp - -import org.monogram.domain.models.WebPage - -data class InstantViewModel( - val pageBlocks: List, - val viewCount: Int, - val version: Int, - val isRtl: Boolean, - val isFull: Boolean, - val url: String -) - -sealed interface PageBlock { - data class Title(val title: RichText) : PageBlock - data class Subtitle(val subtitle: RichText) : PageBlock - data class AuthorDate(val author: RichText, val publishDate: Int) : PageBlock - data class Header(val header: RichText) : PageBlock - data class Subheader(val subheader: RichText) : PageBlock - data class Kicker(val kicker: RichText) : PageBlock - data class Paragraph(val text: RichText) : PageBlock - data class Preformatted(val text: RichText, val language: String) : PageBlock - data class Footer(val footer: RichText) : PageBlock - data object Divider : PageBlock - data class Anchor(val name: String) : PageBlock - data class ListBlock(val items: List) : PageBlock - data class BlockQuote(val text: RichText, val credit: RichText) : PageBlock - data class PullQuote(val text: RichText, val credit: RichText) : PageBlock - data class AnimationBlock( - val animation: WebPage.Animation, - val caption: PageBlockCaption, - val needAutoplay: Boolean - ) : PageBlock - - data class AudioBlock(val audio: WebPage.Audio, val caption: PageBlockCaption) : PageBlock - data class PhotoBlock(val photo: WebPage.Photo, val caption: PageBlockCaption, val url: String) : PageBlock - data class VideoBlock( - val video: WebPage.Video, - val caption: PageBlockCaption, - val needAutoplay: Boolean, - val isLooped: Boolean - ) : PageBlock - - data class Cover(val cover: PageBlock) : PageBlock - data class Embedded( - val url: String, - val html: String, - val posterPhoto: WebPage.Photo?, - val width: Int, - val height: Int, - val caption: PageBlockCaption, - val isFullWidth: Boolean, - val allowScrolling: Boolean - ) : PageBlock - - data class EmbeddedPost( - val url: String, - val author: String, - val authorPhoto: WebPage.Photo?, - val date: Int, - val pageBlocks: List, - val caption: PageBlockCaption - ) : PageBlock - - data class Collage(val pageBlocks: List, val caption: PageBlockCaption) : PageBlock - data class Slideshow(val pageBlocks: List, val caption: PageBlockCaption) : PageBlock - data class ChatLink(val title: String, val username: String) : PageBlock - data class Table( - val caption: RichText, - val cells: List>, - val isBordered: Boolean, - val isStriped: Boolean - ) : PageBlock - - data class Details(val header: RichText, val pageBlocks: List, val isOpen: Boolean) : PageBlock - data class RelatedArticles(val header: RichText, val articles: List) : PageBlock - data class MapBlock( - val location: Location, - val zoom: Int, - val width: Int, - val height: Int, - val caption: PageBlockCaption - ) : PageBlock -} - -sealed interface RichText { - data class Plain(val text: String) : RichText - data class Bold(val text: RichText) : RichText - data class Italic(val text: RichText) : RichText - data class Underline(val text: RichText) : RichText - data class Strikethrough(val text: RichText) : RichText - data class Fixed(val text: RichText) : RichText - data class Url(val text: RichText, val url: String, val isCached: Boolean) : RichText - data class EmailAddress(val text: RichText, val emailAddress: String) : RichText - data class Subscript(val text: RichText) : RichText - data class Superscript(val text: RichText) : RichText - data class Marked(val text: RichText) : RichText - data class PhoneNumber(val text: RichText, val phoneNumber: String) : RichText - data class Icon(val document: WebPage.Document, val width: Int, val height: Int) : RichText - data class Reference(val text: RichText, val anchorName: String, val url: String) : RichText - data class Anchor(val name: String) : RichText - data class AnchorLink(val text: RichText, val anchorName: String, val url: String) : RichText - data class Texts(val texts: List) : RichText -} - -data class PageBlockListItem(val label: String, val pageBlocks: List) -data class PageBlockCaption(val text: RichText, val credit: RichText) -data class PageBlockRelatedArticle( - val url: String, - val title: String, - val description: String, - val photo: WebPage.Photo?, - val author: String, - val publishDate: Int -) - -data class PageBlockTableCell( - val text: RichText, - val isHeader: Boolean, - val colspan: Int, - val rowspan: Int, - val align: HorizontalAlignment, - val valign: VerticalAlignment -) - -enum class HorizontalAlignment { LEFT, CENTER, RIGHT } -enum class VerticalAlignment { TOP, MIDDLE, BOTTOM } - -data class Location(val latitude: Double, val longitude: Double) diff --git a/domain/src/main/java/org/monogram/domain/models/webapp/OSMModels.kt b/domain/src/main/java/org/monogram/domain/models/webapp/OSMModels.kt deleted file mode 100644 index 630a1a33..00000000 --- a/domain/src/main/java/org/monogram/domain/models/webapp/OSMModels.kt +++ /dev/null @@ -1,43 +0,0 @@ -package org.monogram.domain.models.webapp - -import kotlinx.serialization.Serializable - -@Serializable -data class OSMReverseResponse( - val place_id: Long? = null, - val licence: String? = null, - val osm_type: String? = null, - val osm_id: Long? = null, - val lat: String? = null, - val lon: String? = null, - val display_name: String? = null, - val address: OSMAddress? = null, - val boundingbox: List? = null -) - -@Serializable -data class OSMAddress( - val road: String? = null, - val suburb: String? = null, - val city: String? = null, - val town: String? = null, - val village: String? = null, - val county: String? = null, - val state: String? = null, - val postcode: String? = null, - val country: String? = null, - val country_code: String? = null, - val house_number: String? = null, - val neighbourhood: String? = null -) { - val fullAddress: String - get() = listOfNotNull( - house_number, - road, - neighbourhood, - suburb, - city ?: town ?: village, - postcode, - country - ).filter { it.isNotBlank() }.joinToString(", ") -} diff --git a/domain/src/main/java/org/monogram/domain/models/webapp/WebAppEvents.kt b/domain/src/main/java/org/monogram/domain/models/webapp/WebAppEvents.kt deleted file mode 100644 index 66277c1d..00000000 --- a/domain/src/main/java/org/monogram/domain/models/webapp/WebAppEvents.kt +++ /dev/null @@ -1,92 +0,0 @@ -package org.monogram.domain.models.webapp - -sealed class WebAppEvent { - data object Ready : WebAppEvent() - data class Close(val returnBack: Boolean) : WebAppEvent() - data object Expand : WebAppEvent() - data object RequestViewport : WebAppEvent() - data object RequestTheme : WebAppEvent() - data class SetBackgroundColor(val color: String) : WebAppEvent() - data class SetHeaderColor(val colorKey: String?, val color: String?) : WebAppEvent() - data class SetHeaderText(val text: String) : WebAppEvent() - data class SetBottomBarColor(val color: String) : WebAppEvent() - data class SetupMainButton( - val isVisible: Boolean, - val isActive: Boolean, - val text: String, - val color: String?, - val textColor: String?, - val isProgressVisible: Boolean, - val hasShineEffect: Boolean - ) : WebAppEvent() - - data class SetupSecondaryButton( - val isVisible: Boolean, - val isActive: Boolean, - val text: String, - val color: String?, - val textColor: String?, - val isProgressVisible: Boolean, - val hasShineEffect: Boolean, - val position: String - ) : WebAppEvent() - - data class SetupBackButton(val isVisible: Boolean) : WebAppEvent() - data class SetupSettingsButton(val isVisible: Boolean) : WebAppEvent() - data class OpenPopup( - val title: String?, - val message: String, - val buttons: List - ) : WebAppEvent() - - data class OpenLink(val url: String, val tryBrowser: Boolean, val tryInstantView: Boolean) : WebAppEvent() - data class OpenTgLink(val pathFull: String) : WebAppEvent() - data class OpenInvoice(val slug: String) : WebAppEvent() - data class OpenScanQrPopup(val text: String?) : WebAppEvent() - data object CloseScanQrPopup : WebAppEvent() - data class SetupClosingBehavior(val needConfirmation: Boolean) : WebAppEvent() - data class SetupSwipeBehavior(val allowVerticalSwipe: Boolean) : WebAppEvent() - data class TriggerHapticFeedback(val type: String, val impactStyle: String?, val notificationType: String?) : - WebAppEvent() - - data class StartAccelerometer(val refreshRate: Long) : WebAppEvent() - data object StopAccelerometer : WebAppEvent() - data class StartGyroscope(val refreshRate: Long) : WebAppEvent() - data object StopGyroscope : WebAppEvent() - data class StartDeviceOrientation(val refreshRate: Long, val needAbsolute: Boolean) : WebAppEvent() - data object StopDeviceOrientation : WebAppEvent() - data class ToggleOrientationLock(val locked: Boolean) : WebAppEvent() - data object RequestFullscreen : WebAppEvent() - data object ExitFullscreen : WebAppEvent() - data class DataSend(val data: String) : WebAppEvent() - data class SwitchInlineQuery(val query: String, val chatTypes: List) : WebAppEvent() - data class ReadTextFromClipboard(val reqId: String) : WebAppEvent() - data object RequestWriteAccess : WebAppEvent() - data object RequestPhone : WebAppEvent() - data class InvokeCustomMethod(val reqId: String, val method: String, val params: String) : WebAppEvent() - data class SendPreparedMessage(val id: String) : WebAppEvent() - data class RequestFileDownload(val url: String, val fileName: String) : WebAppEvent() - data class DeviceStorageSave(val key: String, val value: String) : WebAppEvent() - data class DeviceStorageGet(val key: String) : WebAppEvent() - data class DeviceStorageRemove(val key: String) : WebAppEvent() - data class SecureStorageSave(val key: String, val value: String) : WebAppEvent() - data class SecureStorageGet(val key: String) : WebAppEvent() - data class SecureStorageRemove(val key: String) : WebAppEvent() - data object BiometryGetInfo : WebAppEvent() - data class BiometryRequestAccess(val reason: String?) : WebAppEvent() - data class BiometryRequestAuth(val reason: String?) : WebAppEvent() - data class BiometryUpdateToken(val token: String) : WebAppEvent() - data object BiometryOpenSettings : WebAppEvent() - data class ShareToStory(val mediaUrl: String, val text: String?, val widgetLink: String?) : WebAppEvent() - data class SetEmojiStatus(val customEmojiId: Long, val duration: Int) : WebAppEvent() - data object RequestEmojiStatusAccess : WebAppEvent() - data object AddToHomeScreen : WebAppEvent() - data object CheckHomeScreen : WebAppEvent() - data object RequestLocation : WebAppEvent() - data object CheckLocation : WebAppEvent() - data object OpenLocationSettings : WebAppEvent() - data class VerifyAge(val age: Double) : WebAppEvent() - data object RequestSafeArea : WebAppEvent() - data object RequestContentSafeArea : WebAppEvent() - data object HideKeyboard : WebAppEvent() -} diff --git a/domain/src/main/java/org/monogram/domain/models/webapp/WebAppModel.kt b/domain/src/main/java/org/monogram/domain/models/webapp/WebAppModel.kt deleted file mode 100644 index 07fe1551..00000000 --- a/domain/src/main/java/org/monogram/domain/models/webapp/WebAppModel.kt +++ /dev/null @@ -1,49 +0,0 @@ -package org.monogram.domain.models.webapp - -data class WebAppInfoModel( - val launchId: Long, - val url: String -) - -data class ThemeParams( - val colorScheme: String? = null, - val backgroundColor: String?, - val secondaryBackgroundColor: String?, - val headerBackgroundColor: String?, - val bottomBarBackgroundColor: String?, - val sectionBackgroundColor: String?, - val sectionSeparatorColor: String?, - val textColor: String?, - val accentTextColor: String?, - val sectionHeaderTextColor: String?, - val subtitleTextColor: String?, - val destructiveTextColor: String?, - val hintColor: String?, - val linkColor: String?, - val buttonColor: String?, - val buttonTextColor: String?, -) - -data class InvoiceModel( - val title: String, - val description: String, - val currency: String, - val totalAmount: Long, - val photoUrl: String? = null, - val isTest: Boolean = false, - val slug: String? = null -) - -data class WebAppPopupButton( - val id: String, - val type: String?, - val text: String, - val isDestructive: Boolean = false -) - -data class WebAppPopupState( - val title: String?, - val message: String, - val buttons: List, - val callbackId: String -) diff --git a/domain/src/main/java/org/monogram/domain/repository/AppPreferencesProvider.kt b/domain/src/main/java/org/monogram/domain/repository/AppPreferencesProvider.kt deleted file mode 100644 index 8cea1ab6..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/AppPreferencesProvider.kt +++ /dev/null @@ -1,104 +0,0 @@ -package org.monogram.domain.repository - -import kotlinx.coroutines.flow.StateFlow - -enum class PushProvider { - FCM, GMS_LESS -} - -interface AppPreferencesProvider { - val autoDownloadMobile: StateFlow - val autoDownloadWifi: StateFlow - val autoDownloadRoaming: StateFlow - val autoDownloadFiles: StateFlow - val autoDownloadStickers: StateFlow - val autoDownloadVideoNotes: StateFlow - val isArchivePinned: StateFlow - val isArchiveAlwaysVisible: StateFlow - val showLinkPreviews: StateFlow - val isChatAnimationsEnabled: StateFlow - val chatListMessageLines: StateFlow - val showChatListPhotos: StateFlow - - val privateChatsNotifications: StateFlow - val groupsNotifications: StateFlow - val channelsNotifications: StateFlow - val inAppSounds: StateFlow - val inAppVibrate: StateFlow - val inAppPreview: StateFlow - val contactJoinedNotifications: StateFlow - val pinnedMessagesNotifications: StateFlow - val backgroundServiceEnabled: StateFlow - val isPowerSavingMode: StateFlow - val isWakeLockEnabled: StateFlow - val hideForegroundNotification: StateFlow - val batteryOptimizationEnabled: StateFlow - - val notificationVibrationPattern: StateFlow // "default", "short", "long", "disabled" - val notificationPriority: StateFlow // 0: Low, 1: Default, 2: High - val repeatNotifications: StateFlow // 0: Never, 5, 10, 30, 60 minutes - val showSenderOnly: StateFlow - val pushProvider: StateFlow - - val enabledProxyId: StateFlow - val isAutoBestProxyEnabled: StateFlow - val isTelegaProxyEnabled: StateFlow - val telegaProxyUrls: StateFlow> - val preferIpv6: StateFlow - val userProxyBackups: StateFlow> - - val isBiometricEnabled: StateFlow - val passcode: StateFlow - - val isPermissionRequested: StateFlow - val isSupportViewed: StateFlow - - fun setAutoDownloadMobile(enabled: Boolean) - fun setAutoDownloadWifi(enabled: Boolean) - fun setAutoDownloadRoaming(enabled: Boolean) - fun setAutoDownloadFiles(enabled: Boolean) - fun setAutoDownloadStickers(enabled: Boolean) - fun setAutoDownloadVideoNotes(enabled: Boolean) - fun setArchivePinned(pinned: Boolean) - fun setArchiveAlwaysVisible(enabled: Boolean) - fun setShowLinkPreviews(enabled: Boolean) - fun setChatAnimationsEnabled(enabled: Boolean) - fun setChatListMessageLines(lines: Int) - fun setShowChatListPhotos(enabled: Boolean) - - fun setPrivateChatsNotifications(enabled: Boolean) - fun setGroupsNotifications(enabled: Boolean) - fun setChannelsNotifications(enabled: Boolean) - fun setInAppSounds(enabled: Boolean) - fun setInAppVibrate(enabled: Boolean) - fun setInAppPreview(enabled: Boolean) - fun setContactJoinedNotifications(enabled: Boolean) - fun setPinnedMessagesNotifications(enabled: Boolean) - fun setBackgroundServiceEnabled(enabled: Boolean) - fun setPowerSavingMode(enabled: Boolean) - fun setWakeLockEnabled(enabled: Boolean) - fun setHideForegroundNotification(enabled: Boolean) - fun setBatteryOptimizationEnabled(enabled: Boolean) - - fun setNotificationVibrationPattern(pattern: String) - fun setNotificationPriority(priority: Int) - fun setRepeatNotifications(minutes: Int) - fun setShowSenderOnly(enabled: Boolean) - fun setPushProvider(provider: PushProvider) - - fun setEnabledProxyId(proxyId: Int?) - fun setAutoBestProxyEnabled(enabled: Boolean) - fun setTelegaProxyEnabled(enabled: Boolean) - fun setTelegaProxyUrls(urls: Set) - fun setPreferIpv6(enabled: Boolean) - fun setUserProxyBackups(backups: Set) - - fun setBiometricEnabled(enabled: Boolean) - fun setPasscode(passcode: String?) - - fun setPermissionRequested(requested: Boolean) - - fun clearPreferences() - fun clearSecurePreferences() - fun setSupportViewed(viewed: Boolean) -} diff --git a/domain/src/main/java/org/monogram/domain/repository/AuthRepository.kt b/domain/src/main/java/org/monogram/domain/repository/AuthRepository.kt deleted file mode 100644 index 75690d04..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/AuthRepository.kt +++ /dev/null @@ -1,31 +0,0 @@ -package org.monogram.domain.repository - -import kotlinx.coroutines.flow.SharedFlow -import kotlinx.coroutines.flow.StateFlow - -sealed class AuthStep { - object Loading : AuthStep() - object WaitParameters : AuthStep() - object InputPhone : AuthStep() - data class InputCode( - val codeType: String, - val codeLength: Int, - val nextType: String? = null, - val timeout: Int = 0, - val isEmailCode: Boolean = false, - val emailPattern: String? = null - ) : AuthStep() - object InputPassword : AuthStep() - object Ready : AuthStep() -} - -interface AuthRepository { - val authState: StateFlow - val errors: SharedFlow - - fun sendPhone(phone: String) - fun resendCode() - fun sendCode(code: String) - fun sendPassword(password: String) - fun reset() -} diff --git a/domain/src/main/java/org/monogram/domain/repository/BotPreferencesProvider.kt b/domain/src/main/java/org/monogram/domain/repository/BotPreferencesProvider.kt deleted file mode 100644 index bcf58582..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/BotPreferencesProvider.kt +++ /dev/null @@ -1,22 +0,0 @@ -package org.monogram.domain.repository - -interface BotPreferencesProvider { - // WebApp Permissions - fun getWebappPermission(botId: Long, permission: String): Boolean - fun setWebappPermission(botId: Long, permission: String, granted: Boolean) - fun isWebappPermissionRequested(botId: Long, permission: String): Boolean - - // WebApp Storage - fun saveWebappData(key: String, value: String) - fun getWebappData(key: String): String? - fun getWebappData(keys: List): Map - fun deleteWebappData(key: String) - fun deleteWebappData(keys: List) - fun getWebappDataKeys(): List - - // WebApp Biometry - fun getWebappBiometryDeviceId(botId: Long): String? - fun saveWebappBiometryDeviceId(botId: Long, deviceId: String) - fun isWebappBiometryAccessRequested(): Boolean - fun setWebappBiometryAccessRequested(requested: Boolean) -} diff --git a/domain/src/main/java/org/monogram/domain/repository/CacheProvider.kt b/domain/src/main/java/org/monogram/domain/repository/CacheProvider.kt deleted file mode 100644 index 0cfed7fa..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/CacheProvider.kt +++ /dev/null @@ -1,43 +0,0 @@ -package org.monogram.domain.repository - -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.StateFlow -import org.monogram.domain.models.AttachMenuBotModel -import org.monogram.domain.models.FolderModel -import org.monogram.domain.models.GifModel -import org.monogram.domain.models.RecentEmojiModel -import org.monogram.domain.models.StickerSetModel - -interface CacheProvider { - val recentEmojis: Flow> - val searchHistory: Flow> - val chatFolders: StateFlow> - val attachBots: StateFlow> - val cachedSimCountryIso: StateFlow - val savedGifs: StateFlow> - val installedStickerSets: StateFlow> - val customEmojiStickerSets: StateFlow> - - fun addRecentEmoji(recentEmoji: RecentEmojiModel) - fun clearRecentEmojis() - fun setRecentEmojis(emojis: List) - - fun addSearchChatId(chatId: Long) - fun removeSearchChatId(chatId: Long) - fun clearSearchHistory() - fun setSearchHistory(history: List) - - fun setChatFolders(folders: List) - fun setAttachBots(bots: List) - fun setCachedSimCountryIso(iso: String?) - - fun saveChatScrollPosition(chatId: Long, messageId: Long) - fun getChatScrollPosition(chatId: Long): Long - - fun setSavedGifs(gifs: List) - - fun setInstalledStickerSets(sets: List) - fun setCustomEmojiStickerSets(sets: List) - - fun clearAll() -} diff --git a/domain/src/main/java/org/monogram/domain/repository/ChatsListRepository.kt b/domain/src/main/java/org/monogram/domain/repository/ChatsListRepository.kt deleted file mode 100644 index c004083a..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/ChatsListRepository.kt +++ /dev/null @@ -1,101 +0,0 @@ -package org.monogram.domain.repository - -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.StateFlow -import org.monogram.domain.models.* - -data class SearchMessagesResult( - val messages: List, - val nextOffset: String -) - -data class FolderChatsUpdate( - val folderId: Int, - val chats: List -) - -data class FolderLoadingUpdate( - val folderId: Int, - val isLoading: Boolean -) - -interface ChatsListRepository { - val chatListFlow: StateFlow> - val folderChatsFlow: Flow - val foldersFlow: StateFlow> - val isLoadingFlow: StateFlow - val folderLoadingFlow: Flow - val connectionStateFlow: StateFlow - val isArchivePinned: StateFlow - val isArchiveAlwaysVisible: StateFlow - val searchHistory: Flow> - val forumTopicsFlow: Flow>> - - fun loadNextChunk(limit: Int) - fun selectFolder(folderId: Int) - fun refresh() - suspend fun getChatById(chatId: Long): ChatModel? - - suspend fun searchChats(query: String): List - suspend fun searchPublicChats(query: String): List - suspend fun searchMessages(query: String, offset: String = "", limit: Int = 50): SearchMessagesResult - fun toggleMuteChats(chatIds: Set, mute: Boolean) - fun toggleArchiveChats(chatIds: Set, archive: Boolean) - fun togglePinChats(chatIds: Set, pin: Boolean, folderId: Int) - fun toggleReadChats(chatIds: Set, markAsUnread: Boolean) - fun deleteChats(chatIds: Set) - fun leaveChat(chatId: Long) - fun setArchivePinned(pinned: Boolean) - - fun retryConnection() - - suspend fun createFolder(title: String, iconName: String?, includedChatIds: List) - suspend fun deleteFolder(folderId: Int) - suspend fun updateFolder(folderId: Int, title: String, iconName: String?, includedChatIds: List) - suspend fun reorderFolders(folderIds: List) - - suspend fun getForumTopics( - chatId: Long, - query: String = "", - offsetDate: Int = 0, - offsetMessageId: Long = 0, - offsetForumTopicId: Int = 0, - limit: Int = 20 - ): List - - fun clearChatHistory(chatId: Long, revoke: Boolean) - suspend fun getChatLink(chatId: Long): String? - fun reportChat(chatId: Long, reason: String, messageIds: List = emptyList()) - - fun addSearchChatId(chatId: Long) - fun removeSearchChatId(chatId: Long) - fun clearSearchHistory() - - suspend fun createGroup(title: String, userIds: List, messageAutoDeleteTime: Int = 0): Long - suspend fun createChannel( - title: String, - description: String, - isMegagroup: Boolean = false, - messageAutoDeleteTime: Int = 0 - ): Long - - suspend fun setChatPhoto(chatId: Long, photoPath: String) - suspend fun setChatTitle(chatId: Long, title: String) - suspend fun setChatDescription(chatId: Long, description: String) - suspend fun setChatUsername(chatId: Long, username: String) - suspend fun setChatPermissions(chatId: Long, permissions: ChatPermissionsModel) - suspend fun setChatSlowModeDelay(chatId: Long, slowModeDelay: Int) - suspend fun toggleChatIsForum(chatId: Long, isForum: Boolean) - suspend fun toggleChatIsTranslatable(chatId: Long, isTranslatable: Boolean) - - fun getDatabaseSize(): Long - fun clearDatabase() -} - -sealed class ConnectionStatus { - data object Connected : ConnectionStatus() - data object Connecting : ConnectionStatus() - data object Updating : ConnectionStatus() - data object WaitingForNetwork : ConnectionStatus() - data object ConnectingToProxy : ConnectionStatus() -} diff --git a/domain/src/main/java/org/monogram/domain/repository/ExternalNavigator.kt b/domain/src/main/java/org/monogram/domain/repository/ExternalNavigator.kt deleted file mode 100644 index 1ac04e45..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/ExternalNavigator.kt +++ /dev/null @@ -1,8 +0,0 @@ -package org.monogram.domain.repository - -interface ExternalNavigator { - fun openUrl(url: String) - val packageName: String - fun navigateToLinkSettings() - fun openOssLicenses() -} \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/repository/ExternalProxyRepository.kt b/domain/src/main/java/org/monogram/domain/repository/ExternalProxyRepository.kt deleted file mode 100644 index 2711a13d..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/ExternalProxyRepository.kt +++ /dev/null @@ -1,17 +0,0 @@ -package org.monogram.domain.repository - -import org.monogram.domain.models.ProxyModel -import org.monogram.domain.models.ProxyTypeModel - -interface ExternalProxyRepository { - suspend fun fetchExternalProxies(): List - suspend fun getProxies(): List - suspend fun addProxy(server: String, port: Int, enable: Boolean, type: ProxyTypeModel): ProxyModel? - suspend fun editProxy(proxyId: Int, server: String, port: Int, enable: Boolean, type: ProxyTypeModel): ProxyModel? - suspend fun enableProxy(proxyId: Int): Boolean - suspend fun disableProxy(): Boolean - suspend fun removeProxy(proxyId: Int): Boolean - suspend fun pingProxy(proxyId: Int): Long? - suspend fun testProxy(server: String, port: Int, type: ProxyTypeModel): Long? - fun setPreferIpv6(enabled: Boolean) -} diff --git a/domain/src/main/java/org/monogram/domain/repository/LinkHandlerRepository.kt b/domain/src/main/java/org/monogram/domain/repository/LinkHandlerRepository.kt deleted file mode 100644 index 884a5fc8..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/LinkHandlerRepository.kt +++ /dev/null @@ -1,38 +0,0 @@ -package org.monogram.domain.repository - -import org.monogram.domain.models.ChatFullInfoModel -import org.monogram.domain.models.ChatModel -import org.monogram.domain.models.ProxyTypeModel - -interface LinkHandlerRepository { - suspend fun handleLink(link: String): LinkAction - suspend fun joinChat(inviteLink: String): Long? -} - -sealed class LinkAction { - data class OpenChat(val chatId: Long) : LinkAction() - data class OpenUser(val userId: Long) : LinkAction() - data class OpenMessage(val chatId: Long, val messageId: Long) : LinkAction() - data class OpenSettings(val settingsType: SettingsType) : LinkAction() - data class OpenStickerSet(val name: String) : LinkAction() - data class JoinChat(val inviteLink: String) : LinkAction() - data class ConfirmJoinChat(val chat: ChatModel, val fullInfo: ChatFullInfoModel) : LinkAction() - data class ConfirmJoinInviteLink( - val inviteLink: String, - val title: String, - val description: String, - val memberCount: Int, - val avatarPath: String?, - val isChannel: Boolean - ) : LinkAction() - data class OpenWebApp(val botUserId: Long, val url: String) : LinkAction() - data class OpenExternalLink(val url: String) : LinkAction() - data object OpenActiveSessions : LinkAction() - data class ShowToast(val message: String) : LinkAction() - data class AddProxy(val server: String, val port: Int, val type: ProxyTypeModel) : LinkAction() - data object None : LinkAction() - - enum class SettingsType { - MAIN, PRIVACY, SESSIONS, FOLDERS, CHAT, DATA_STORAGE, POWER_SAVING, PREMIUM - } -} \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/repository/LocationRepository.kt b/domain/src/main/java/org/monogram/domain/repository/LocationRepository.kt deleted file mode 100644 index 374f2dfd..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/LocationRepository.kt +++ /dev/null @@ -1,8 +0,0 @@ -package org.monogram.domain.repository - -import org.monogram.domain.models.webapp.OSMReverseResponse - -interface LocationRepository { - suspend fun reverseGeocode(lat: Double, lon: Double): OSMReverseResponse? - suspend fun searchLocation(query: String): List -} \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/repository/MessageDisplayer.kt b/domain/src/main/java/org/monogram/domain/repository/MessageDisplayer.kt deleted file mode 100644 index 45f9f55a..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/MessageDisplayer.kt +++ /dev/null @@ -1,5 +0,0 @@ -package org.monogram.domain.repository - -interface MessageDisplayer { - fun show(message: String) -} \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/repository/MessageRepository.kt b/domain/src/main/java/org/monogram/domain/repository/MessageRepository.kt deleted file mode 100644 index c5f5a698..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/MessageRepository.kt +++ /dev/null @@ -1,275 +0,0 @@ -package org.monogram.domain.repository - -import kotlinx.coroutines.flow.Flow -import org.monogram.domain.models.* -import org.monogram.domain.models.webapp.InstantViewModel -import org.monogram.domain.models.webapp.InvoiceModel -import org.monogram.domain.models.webapp.ThemeParams -import org.monogram.domain.models.webapp.WebAppInfoModel - -sealed interface ReadUpdate { - val chatId: Long - val messageId: Long - data class Inbox(override val chatId: Long, override val messageId: Long) : ReadUpdate - data class Outbox(override val chatId: Long, override val messageId: Long) : ReadUpdate -} -enum class ProfileMediaFilter { - MEDIA, - FILES, - AUDIO, - VOICE, - LINKS, - GIFS -} -data class SearchChatMessagesResult( - val messages: List, - val totalCount: Int, - val nextFromMessageId: Long -) - -data class OlderMessagesPage( - val messages: List, - val reachedOldest: Boolean, - val isRemote: Boolean -) - -interface MessageRepository { - val newMessageFlow: Flow - val senderUpdateFlow: Flow - val messageReadFlow: Flow - val messageUploadProgressFlow: Flow> - val messageDownloadProgressFlow: Flow> - val messageDownloadCancelledFlow: Flow - val messageDownloadCompletedFlow: Flow> - val messageDeletedFlow: Flow>> - val messageEditedFlow: Flow - val messageIdUpdateFlow: Flow> - val pinnedMessageFlow: Flow - val mediaUpdateFlow: Flow - suspend fun getHighResFileId(chatId: Long, messageId: Long): Int? - suspend fun getFileInfo(fileId: Int): FileModel? - suspend fun getProfileMedia( - chatId: Long, - filter: ProfileMediaFilter, - fromMessageId: Long, - limit: Int - ): List - suspend fun openChat(chatId: Long) - suspend fun closeChat(chatId: Long) - - suspend fun sendVideoNote(chatId: Long, videoPath: String, duration: Int, length: Int) - suspend fun sendVoiceNote(chatId: Long, voicePath: String, duration: Int, waveform: ByteArray) - - suspend fun getMessagesOlder( - chatId: Long, - fromMessageId: Long, - limit: Int, - threadId: Long? = null - ): OlderMessagesPage - - suspend fun getCachedMessages(chatId: Long, limit: Int): List - - suspend fun getMessagesNewer( - chatId: Long, - fromMessageId: Long, - limit: Int, - threadId: Long? = null - ): List - - suspend fun getMessagesAround(chatId: Long, messageId: Long, limit: Int, threadId: Long? = null): List - - @Deprecated("Use getMessagesOlder instead") - suspend fun getMessages(chatId: Long, fromMessageId: Long, limit: Int): List - - suspend fun sendMessage( - chatId: Long, - text: String, - replyToMsgId: Long? = null, - entities: List = emptyList(), - threadId: Long? = null, - sendOptions: MessageSendOptions = MessageSendOptions() - ) - - suspend fun sendSticker(chatId: Long, stickerPath: String, replyToMsgId: Long? = null, threadId: Long? = null) - suspend fun sendPhoto( - chatId: Long, - photoPath: String, - caption: String = "", - captionEntities: List = emptyList(), - replyToMsgId: Long? = null, - threadId: Long? = null, - sendOptions: MessageSendOptions = MessageSendOptions() - ) - - suspend fun sendVideo( - chatId: Long, - videoPath: String, - caption: String = "", - captionEntities: List = emptyList(), - replyToMsgId: Long? = null, - threadId: Long? = null, - sendOptions: MessageSendOptions = MessageSendOptions() - ) - - suspend fun sendDocument( - chatId: Long, - documentPath: String, - caption: String = "", - captionEntities: List = emptyList(), - replyToMsgId: Long? = null, - threadId: Long? = null, - sendOptions: MessageSendOptions = MessageSendOptions() - ) - - suspend fun sendGif( - chatId: Long, - gifId: String, - replyToMsgId: Long? = null, - threadId: Long? = null, - sendOptions: MessageSendOptions = MessageSendOptions() - ) - - suspend fun sendGifFile( - chatId: Long, - gifPath: String, - caption: String = "", - captionEntities: List = emptyList(), - replyToMsgId: Long? = null, - threadId: Long? = null, - sendOptions: MessageSendOptions = MessageSendOptions() - ) - - suspend fun sendChatAction(chatId: Long, action: ChatAction, threadId: Long? = null) - suspend fun getMessageReadDate(chatId: Long, messageId: Long, messageDate: Int): Int - suspend fun getMessageViewers(chatId: Long, messageId: Long): List - suspend fun summarizeMessage(chatId: Long, messageId: Long, toLanguageCode: String = ""): String? - suspend fun translateMessage(chatId: Long, messageId: Long, toLanguageCode: String): String? - suspend fun addMessageReaction(chatId: Long, messageId: Long, reaction: String) - suspend fun removeMessageReaction(chatId: Long, messageId: Long, reaction: String) - suspend fun setPollAnswer(chatId: Long, messageId: Long, optionIds: List) - suspend fun stopPoll(chatId: Long, messageId: Long) - suspend fun getPollVoters( - chatId: Long, - messageId: Long, - optionId: Int, - offset: Int, - limit: Int - ): List - - suspend fun getWebPageInstantView(url: String, forceFull: Boolean = false): InstantViewModel? - - suspend fun searchMessages( - chatId: Long, - query: String, - fromMessageId: Long = 0, - limit: Int = 50, - threadId: Long? = null - ): SearchChatMessagesResult - - fun updateVisibleRange(chatId: Long, visibleMessageIds: List, nearbyMessageIds: List) - - suspend fun onCallbackQuery(chatId: Long, messageId: Long, data: ByteArray) - - suspend fun openWebApp( - chatId: Long, - botUserId: Long, - url: String, - themeParams: ThemeParams? = null - ): WebAppInfoModel? - - suspend fun closeWebApp(launchId: Long) - - suspend fun getInvoice(slug: String? = null, chatId: Long? = null, messageId: Long? = null): InvoiceModel? - - suspend fun payInvoice(slug: String? = null, chatId: Long? = null, messageId: Long? = null): Boolean - - suspend fun getFilePath(fileId: Int): String? - - suspend fun onCallbackQueryBuy(chatId: Long, messageId: Long) - - suspend fun sendWebAppResult(launchId: Long, queryId: String) - - sealed interface ChatAction { - data object Typing : ChatAction - data object RecordingVideo : ChatAction - data object RecordingVoice : ChatAction - data object UploadingPhoto : ChatAction - data object UploadingVideo : ChatAction - data object UploadingDocument : ChatAction - data object ChoosingSticker : ChatAction - data object Cancel : ChatAction - } - - suspend fun sendAlbum( - chatId: Long, - paths: List, - caption: String = "", - captionEntities: List = emptyList(), - replyToMsgId: Long? = null, - threadId: Long? = null, - sendOptions: MessageSendOptions = MessageSendOptions() - ) - - suspend fun getScheduledMessages(chatId: Long): List - suspend fun sendScheduledNow(chatId: Long, messageId: Long) - - suspend fun forwardMessage(toChatId: Long, fromChatId: Long, messageId: Long) - suspend fun deleteMessage(chatId: Long, messageIds: List, revoke: Boolean = false) - suspend fun editMessage(chatId: Long, messageId: Long, newText: String, entities: List = emptyList()) - suspend fun markAsRead(chatId: Long, messageId: Long) - suspend fun markAllMentionsAsRead(chatId: Long) - suspend fun markAllReactionsAsRead(chatId: Long) - suspend fun getChatDraft(chatId: Long, threadId: Long? = null): String? - suspend fun saveChatDraft(chatId: Long, text: String, replyToMsgId: Long?, threadId: Long? = null) - suspend fun pinMessage(chatId: Long, messageId: Long, disableNotification: Boolean = false) - suspend fun unpinMessage(chatId: Long, messageId: Long) - suspend fun getPinnedMessage(chatId: Long, threadId: Long? = null): MessageModel? - suspend fun getAllPinnedMessages(chatId: Long, threadId: Long? = null): List - suspend fun getPinnedMessageCount(chatId: Long, threadId: Long? = null): Int - fun downloadFile( - fileId: Int, - priority: Int = 1, - offset: Long = 0, - limit: Long = 0, - synchronous: Boolean = false - ) - fun invalidateSenderCache(userId: Long) - suspend fun cancelDownloadFile(fileId: Int) - suspend fun joinChat(chatId: Long) - suspend fun restrictChatMember(chatId: Long, userId: Long, permissions: ChatPermissionsModel, untilDate: Int = 0) - - suspend fun getInlineBotResults( - botUserId: Long, - chatId: Long, - query: String, - offset: String = "" - ): InlineBotResultsModel? - - suspend fun sendInlineBotResult( - chatId: Long, - queryId: Long, - resultId: String, - replyToMsgId: Long? = null, - threadId: Long? = null - ) - - suspend fun getChatEventLog( - chatId: Long, - query: String = "", - fromEventId: Long = 0, - limit: Int = 50, - filters: ChatEventLogFiltersModel = ChatEventLogFiltersModel(), - userIds: List = emptyList() - ): List - - fun clearMessages(chatId: Long) - fun clearAllCache() -} - -data class InlineBotResultsModel( - val queryId: Long, - val nextOffset: String, - val results: List, - val switchPmText: String? = null, - val switchPmParameter: String? = null -) diff --git a/domain/src/main/java/org/monogram/domain/repository/PollRepository.kt b/domain/src/main/java/org/monogram/domain/repository/PollRepository.kt deleted file mode 100644 index 76842771..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/PollRepository.kt +++ /dev/null @@ -1,6 +0,0 @@ -package org.monogram.domain.repository - -interface PollRepository { - suspend fun mapPollIdToMessage(pollId: Long, chatId: Long, messageId: Long) - suspend fun getMessageIdByPollId(pollId: Long): Pair? // chatId, messageId -} \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/repository/PrivacyRepository.kt b/domain/src/main/java/org/monogram/domain/repository/PrivacyRepository.kt deleted file mode 100644 index 9a702b61..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/PrivacyRepository.kt +++ /dev/null @@ -1,35 +0,0 @@ -package org.monogram.domain.repository - -import org.monogram.domain.models.PrivacyRule -import kotlinx.coroutines.flow.Flow - -interface PrivacyRepository { - fun getPrivacyRules(key: PrivacyKey): Flow> - suspend fun setPrivacyRule(key: PrivacyKey, rules: List) - - suspend fun getBlockedUsers(): List - suspend fun blockUser(userId: Long) - suspend fun unblockUser(userId: Long) - - suspend fun deleteAccount(reason: String, password: String) - - suspend fun getAccountTtl(): Int - suspend fun setAccountTtl(days: Int) - - suspend fun getPasswordState(): Boolean - - suspend fun canShowSensitiveContent(): Boolean - suspend fun isShowSensitiveContentEnabled(): Boolean - suspend fun setShowSensitiveContent(enabled: Boolean) -} - -enum class PrivacyKey { - PHONE_NUMBER, - PHONE_NUMBER_SEARCH, - LAST_SEEN, - PROFILE_PHOTO, - BIO, - FORWARDED_MESSAGES, - CALLS, - GROUPS_AND_CHANNELS -} \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/repository/SettingsRepository.kt b/domain/src/main/java/org/monogram/domain/repository/SettingsRepository.kt deleted file mode 100644 index b47dc460..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/SettingsRepository.kt +++ /dev/null @@ -1,54 +0,0 @@ -package org.monogram.domain.repository - -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.StateFlow -import org.monogram.domain.models.* - -interface SettingsRepository { - suspend fun getActiveSessions(): List - suspend fun terminateSession(sessionId: Long): Boolean - suspend fun confirmQrCode(link: String): Boolean - fun getWallpapers(): Flow> - suspend fun downloadWallpaper(fileId: Int) - - suspend fun getStorageUsage(): StorageUsageModel? - suspend fun getNetworkUsage(): NetworkUsageModel? - suspend fun clearStorage(chatId: Long? = null): Boolean - suspend fun resetNetworkStatistics(): Boolean - suspend fun setDatabaseMaintenanceSettings(maxDatabaseSize: Long, maxTimeFromLastAccess: Int): Boolean - - suspend fun getNetworkStatisticsEnabled(): Boolean - suspend fun setNetworkStatisticsEnabled(enabled: Boolean) - - suspend fun getStorageOptimizerEnabled(): Boolean - suspend fun setStorageOptimizerEnabled(enabled: Boolean) - - val autoDownloadMobile: StateFlow - val autoDownloadWifi: StateFlow - val autoDownloadRoaming: StateFlow - val autoDownloadFiles: StateFlow - val autoDownloadStickers: StateFlow - val autoDownloadVideoNotes: StateFlow - - fun setAutoDownloadMobile(enabled: Boolean) - fun setAutoDownloadWifi(enabled: Boolean) - fun setAutoDownloadRoaming(enabled: Boolean) - fun setAutoDownloadFiles(enabled: Boolean) - fun setAutoDownloadStickers(enabled: Boolean) - fun setAutoDownloadVideoNotes(enabled: Boolean) - - suspend fun getNotificationSettings(scope: TdNotificationScope): Boolean - suspend fun setNotificationSettings(scope: TdNotificationScope, enabled: Boolean) - - suspend fun getExceptions(scope: TdNotificationScope): List - suspend fun setChatNotificationSettings(chatId: Long, enabled: Boolean) - suspend fun resetChatNotificationSettings(chatId: Long) - - fun getAttachMenuBots(): Flow> - - suspend fun setCachedSimCountryIso(iso: String?) - - enum class TdNotificationScope { - PRIVATE_CHATS, GROUPS, CHANNELS - } -} diff --git a/domain/src/main/java/org/monogram/domain/repository/StickerRepository.kt b/domain/src/main/java/org/monogram/domain/repository/StickerRepository.kt deleted file mode 100644 index 32c3946f..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/StickerRepository.kt +++ /dev/null @@ -1,51 +0,0 @@ -package org.monogram.domain.repository - -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.StateFlow -import org.monogram.domain.models.GifModel -import org.monogram.domain.models.RecentEmojiModel -import org.monogram.domain.models.StickerModel -import org.monogram.domain.models.StickerSetModel - -interface StickerRepository { - val installedStickerSets: StateFlow> - val customEmojiStickerSets: StateFlow> - val archivedStickerSets: StateFlow> - val archivedEmojiSets: StateFlow> - val recentEmojis: Flow> - - suspend fun loadInstalledStickerSets() - suspend fun loadCustomEmojiStickerSets() - suspend fun loadArchivedStickerSets() - suspend fun loadArchivedEmojiSets() - suspend fun getDefaultEmojis(): List - suspend fun getRecentStickers(): List - suspend fun addRecentEmoji(recentEmoji: RecentEmojiModel) - suspend fun clearRecentStickers() - suspend fun clearRecentEmojis() - - fun getStickerFile(fileId: Long): Flow - fun getGifFile(gif: GifModel): Flow - suspend fun searchGifs(query: String): List - suspend fun getSavedGifs(): List - suspend fun addSavedGif(path: String) - suspend fun getTgsJson(path: String): String? - fun clearCache() - suspend fun getMessageAvailableReactions(chatId: Long, messageId: Long): List - - suspend fun getStickerSet(setId: Long): StickerSetModel? - suspend fun getStickerSetByName(name: String): StickerSetModel? - suspend fun verifyStickerSet(setId: Long) - suspend fun toggleStickerSetInstalled(setId: Long, isInstalled: Boolean) - suspend fun toggleStickerSetArchived(setId: Long, isArchived: Boolean) - suspend fun reorderStickerSets(stickerType: TdLibStickerType, stickerSetIds: List) - - suspend fun searchEmojis(query: String): List - suspend fun searchCustomEmojis(query: String): List - suspend fun searchStickers(query: String): List - suspend fun searchStickerSets(query: String): List - - enum class TdLibStickerType { - REGULAR, CUSTOM_EMOJI, MASK - } -} diff --git a/domain/src/main/java/org/monogram/domain/repository/StreamingRepository.kt b/domain/src/main/java/org/monogram/domain/repository/StreamingRepository.kt deleted file mode 100644 index a44b9e7d..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/StreamingRepository.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.monogram.domain.repository - -import kotlinx.coroutines.flow.Flow - -interface StreamingRepository { - fun getDownloadProgress(fileId: Int): Flow -} - -interface PlayerDataSourceFactory { - fun createPayload(fileId: Int): Any -} \ No newline at end of file diff --git a/domain/src/main/java/org/monogram/domain/repository/StringProvider.kt b/domain/src/main/java/org/monogram/domain/repository/StringProvider.kt deleted file mode 100644 index 7210c973..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/StringProvider.kt +++ /dev/null @@ -1,7 +0,0 @@ -package org.monogram.domain.repository - -interface StringProvider { - fun getString(resName: String): String - fun getString(resName: String, vararg formatArgs: Any): String - fun getQuantityString(resName: String, quantity: Int, vararg formatArgs: Any): String -} diff --git a/domain/src/main/java/org/monogram/domain/repository/UpdateRepository.kt b/domain/src/main/java/org/monogram/domain/repository/UpdateRepository.kt deleted file mode 100644 index b62c2fed..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/UpdateRepository.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.monogram.domain.repository - -import kotlinx.coroutines.flow.StateFlow -import org.monogram.domain.models.UpdateState - -interface UpdateRepository { - val updateState: StateFlow - suspend fun checkForUpdates() - fun downloadUpdate() - fun cancelDownload() - fun installUpdate() - suspend fun getTdLibVersion(): String - suspend fun getTdLibCommitHash(): String -} diff --git a/domain/src/main/java/org/monogram/domain/repository/UserRepository.kt b/domain/src/main/java/org/monogram/domain/repository/UserRepository.kt deleted file mode 100644 index aa6f423c..00000000 --- a/domain/src/main/java/org/monogram/domain/repository/UserRepository.kt +++ /dev/null @@ -1,108 +0,0 @@ -package org.monogram.domain.repository - -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.StateFlow -import org.monogram.domain.models.* - -interface UserRepository { - val currentUserFlow: StateFlow - val anyUserUpdateFlow: Flow - suspend fun getMe(): UserModel - suspend fun getUser(userId: Long): UserModel? - suspend fun getUserFullInfo(userId: Long): UserModel? - fun getUserFlow(userId: Long): Flow - suspend fun getUserProfilePhotos( - userId: Long, - offset: Int = 0, - limit: Int = 10, - ensureFullRes: Boolean = false - ): List - fun getUserProfilePhotosFlow(userId: Long): Flow> - - suspend fun getChatFullInfo(chatId: Long): ChatFullInfoModel? - - suspend fun getPremiumState(): PremiumStateModel? - suspend fun getPremiumFeatures(source: PremiumSource): List - suspend fun getPremiumLimit(limitType: PremiumLimitType): Int - fun logOut() - - suspend fun getBotCommands(botId: Long): List - suspend fun getBotInfo(botId: Long): BotInfoModel? - - suspend fun getContacts(): List - suspend fun searchContacts(query: String): List - suspend fun addContact(user: UserModel) - suspend fun removeContact(userId: Long) - suspend fun getChatMembers( - chatId: Long, - offset: Int, - limit: Int, - filter: ChatMembersFilter = ChatMembersFilter.Recent - ): List - - suspend fun getChatMember(chatId: Long, userId: Long): GroupMemberModel? - suspend fun searchPublicChat(username: String): ChatModel? - - suspend fun setChatMemberStatus(chatId: Long, userId: Long, status: ChatMemberStatus) - - suspend fun getChatStatistics(chatId: Long, isDark: Boolean): ChatStatisticsModel? - suspend fun getChatRevenueStatistics(chatId: Long, isDark: Boolean): ChatRevenueStatisticsModel? - suspend fun loadStatisticsGraph(chatId: Long, token: String, x: Long): StatisticsGraphModel? - - suspend fun setName(firstName: String, lastName: String) - suspend fun setBio(bio: String) - suspend fun setUsername(username: String) - suspend fun setEmojiStatus(customEmojiId: Long?) - suspend fun setProfilePhoto(path: String) - suspend fun setBirthdate(birthdate: BirthdateModel?) - suspend fun setPersonalChat(chatId: Long) - suspend fun setBusinessBio(bio: String) - suspend fun setBusinessLocation(address: String, latitude: Double = 0.0, longitude: Double = 0.0) - suspend fun setBusinessOpeningHours(openingHours: BusinessOpeningHoursModel?) - suspend fun toggleUsernameIsActive(username: String, isActive: Boolean) - suspend fun reorderActiveUsernames(usernames: List) - fun forceSponsorSync() -} - -sealed class ChatMembersFilter { - data object Recent : ChatMembersFilter() - data object Administrators : ChatMembersFilter() - data object Banned : ChatMembersFilter() - data object Restricted : ChatMembersFilter() - data object Bots : ChatMembersFilter() - data class Search(val query: String) : ChatMembersFilter() -} - -sealed class ChatMemberStatus { - data object Member : ChatMemberStatus() - data class Administrator( - val customTitle: String = "", - val canBeEdited: Boolean = true, - val canManageChat: Boolean = true, - val canChangeInfo: Boolean = true, - val canPostMessages: Boolean = true, - val canEditMessages: Boolean = true, - val canDeleteMessages: Boolean = true, - val canInviteUsers: Boolean = true, - val canRestrictMembers: Boolean = true, - val canPinMessages: Boolean = true, - val canPromoteMembers: Boolean = true, - val canManageVideoChats: Boolean = true, - val canManageTopics: Boolean = true, - val canPostStories: Boolean = true, - val canEditStories: Boolean = true, - val canDeleteStories: Boolean = true, - val canManageDirectMessages: Boolean = true, - val isAnonymous: Boolean = false - ) : ChatMemberStatus() - - data class Restricted( - val isMember: Boolean = true, - val restrictedUntilDate: Int = 0, - val permissions: ChatPermissionsModel = ChatPermissionsModel() - ) : ChatMemberStatus() - - data object Left : ChatMemberStatus() - data class Banned(val bannedUntilDate: Int = 0) : ChatMemberStatus() - data object Creator : ChatMemberStatus() -} diff --git a/presentation b/presentation new file mode 160000 index 00000000..e4c0be58 --- /dev/null +++ b/presentation @@ -0,0 +1 @@ +Subproject commit e4c0be58ebd19234354bab7a6261300f42864378 diff --git a/presentation/.gitignore b/presentation/.gitignore deleted file mode 100644 index d93f3029..00000000 --- a/presentation/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/build -/src/main/cpp/libvpx_build/** \ No newline at end of file diff --git a/presentation/build.gradle.kts b/presentation/build.gradle.kts deleted file mode 100644 index 9f39f3cc..00000000 --- a/presentation/build.gradle.kts +++ /dev/null @@ -1,114 +0,0 @@ -import com.android.build.gradle.internal.tasks.factory.dependsOn -import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import org.jetbrains.kotlin.gradle.internal.ensureParentDirsCreated -import java.net.URL - -plugins { - alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.android) - alias(libs.plugins.kotlin.serialization) - alias(libs.plugins.kotlin.compose) - id("kotlin-parcelize") -} - -android { - namespace = "org.monogram.presentation" - compileSdk = 36 - - defaultConfig { - minSdk = 25 - consumerProguardFiles("consumer-rules.pro") - externalNativeBuild { - cmake { - cppFlags("-std=c++17") - } - } - ndk { - abiFilters.add("arm64-v8a") - abiFilters.add("armeabi-v7a") - abiFilters.add("x86_64") - } - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 - } - buildFeatures { - compose = true - } - kotlin { - compilerOptions { - jvmTarget = JvmTarget.JVM_17 - } - } - externalNativeBuild { - cmake { - path = file("src/main/cpp/CMakeLists.txt") - version = "3.22.1" - } - } -} -val downloadFolder = "src/main/cpp" -var vpxFolder = file("$downloadFolder/libvpx_build") -val vpxZip = file("$downloadFolder/libvpx_build.zip") - -tasks.apply { - register("downloadVpx") { - onlyIf { !vpxFolder.isDirectory } - doLast { - println("Downloading VPX libs...") - vpxFolder.ensureParentDirsCreated() - URL("https://github.com/aliveoutside/prebuilt-vpx/releases/download/v.1/libvpx_build.zip") - .openStream().use { input -> - vpxZip.outputStream() - .use { output -> input.copyTo(output) } - } - } - } - register("unzipVpx") { - dependsOn(this@apply.getByName("downloadVpx")) - onlyIf { !vpxFolder.isDirectory } - from(zipTree(vpxZip)) - into(downloadFolder) - } - register("downloadAndUnzipVpx") { - dependsOn("unzipVpx") - delete(vpxZip) - } - preBuild.dependsOn("downloadAndUnzipVpx") -} - -dependencies { - implementation(project(":core")) - implementation(project(":domain")) - - implementation(platform(libs.androidx.compose.bom)) - implementation(libs.bundles.androidx.compose) - implementation(libs.bundles.androidx.camera) - implementation(libs.bundles.androidx.media3) - - implementation(libs.bundles.coil) - implementation(libs.bundles.decompose) - implementation(libs.bundles.mvikotlin) - implementation(libs.bundles.koin) - - implementation(libs.kotlinx.serialization.json) - implementation(libs.play.services.mlkit.barcode.scanning) - implementation(libs.zxing.core) - implementation(libs.androidx.biometric) - implementation(libs.androidx.security.crypto) - implementation(libs.maplibre.compose) - implementation(libs.play.services.oss.licenses) - implementation(libs.play.services.location) - testImplementation(libs.junit) -} \ No newline at end of file diff --git a/presentation/consumer-rules.pro b/presentation/consumer-rules.pro deleted file mode 100644 index e69de29b..00000000 diff --git a/presentation/proguard-rules.pro b/presentation/proguard-rules.pro deleted file mode 100644 index 481bb434..00000000 --- a/presentation/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/presentation/src/main/AndroidManifest.xml b/presentation/src/main/AndroidManifest.xml deleted file mode 100644 index cea2e21b..00000000 --- a/presentation/src/main/AndroidManifest.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/presentation/src/main/cpp/CMakeLists.txt b/presentation/src/main/cpp/CMakeLists.txt deleted file mode 100644 index 6f8be8c9..00000000 --- a/presentation/src/main/cpp/CMakeLists.txt +++ /dev/null @@ -1,67 +0,0 @@ -cmake_minimum_required(VERSION 3.22.1) - -project("presentation") - -set(VPX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/libvpx_build/${ANDROID_ABI}") -include_directories(${VPX_PATH}/include) -add_library(libvpx STATIC IMPORTED) -set_target_properties(libvpx PROPERTIES IMPORTED_LOCATION - "${VPX_PATH}/lib/libvpx.a" -) - -add_library( - native-lib - SHARED - native-lib.cpp - VpxDecoder.cpp - RLottieDecoder.cpp - RLottieJni.cpp) - -set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) -set(LOTTIE_MODULE OFF CACHE BOOL "" FORCE) -set(LOTTIE_TEST OFF CACHE BOOL "" FORCE) -add_subdirectory(third_party/rlottie) - -target_compile_options(native-lib PRIVATE - -O3 - -fvisibility=hidden - -fdata-sections - -ffunction-sections) - -target_link_options(native-lib PRIVATE - "-Wl,-z,max-page-size=16384" - -Wl,--gc-sections) - -#if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") -# add_compile_options(-flto) -# add_link_options(-flto) -#endif() - -find_library( - log-lib - log) - -find_library( - android-lib - android) - -find_library( - egl-lib - EGL) - -find_library( - glesv2-lib - GLESv2) - -target_link_libraries( - native-lib - - libvpx - rlottie - mediandk - jnigraphics - - ${log-lib} - ${android-lib} - ${egl-lib} - ${glesv2-lib}) diff --git a/presentation/src/main/cpp/RLottieDecoder.cpp b/presentation/src/main/cpp/RLottieDecoder.cpp deleted file mode 100644 index 3eb2b5bf..00000000 --- a/presentation/src/main/cpp/RLottieDecoder.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include "RLottieDecoder.h" - -#include -#include -#include - -#include "third_party/rlottie/inc/rlottie.h" - -RLottieDecoder::RLottieDecoder() = default; -RLottieDecoder::~RLottieDecoder() = default; - -static inline uint32_t argbToRgba(uint32_t pixel) { - return (pixel & 0xFF00FF00u) - | ((pixel & 0x00FF0000u) >> 16) - | ((pixel & 0x000000FFu) << 16); -} - -static void swizzleArgbToRgba( - uint32_t *buffer, - int bitmapWidth, - int bytesPerLine, - int left, - int top, - int width, - int height -) { - if (buffer == nullptr || bitmapWidth <= 0 || bytesPerLine <= 0) { - return; - } - - const int stridePixels = bytesPerLine / static_cast(sizeof(uint32_t)); - if (stridePixels <= 0) { - return; - } - - const int right = left + width; - const int bottom = top + height; - for (int y = top; y < bottom; y++) { - auto *row = buffer + y * stridePixels; - for (int x = left; x < right; x++) { - row[x] = argbToRgba(row[x]); - } - } -} - -bool RLottieDecoder::openFromData( - const std::string &jsonData, - const std::string &cacheKey, - const std::string &resourcePath -) { - animation = rlottie::Animation::loadFromData(jsonData, cacheKey, resourcePath, false); - return animation != nullptr; -} - -bool RLottieDecoder::renderFrame( - JNIEnv *env, - jobject bitmap, - int frameNo, - int drawLeft, - int drawTop, - int drawWidth, - int drawHeight -) { - if (animation == nullptr || bitmap == nullptr) { - return false; - } - - AndroidBitmapInfo info; - if (AndroidBitmap_getInfo(env, bitmap, &info) != ANDROID_BITMAP_RESULT_SUCCESS) { - return false; - } - - if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) { - return false; - } - - void *pixels = nullptr; - if (AndroidBitmap_lockPixels(env, bitmap, &pixels) != ANDROID_BITMAP_RESULT_SUCCESS) { - return false; - } - - const auto width = static_cast(info.width); - const auto height = static_cast(info.height); - const auto bytesPerLine = static_cast(info.stride); - - auto safeDrawLeft = std::max(0, drawLeft); - auto safeDrawTop = std::max(0, drawTop); - auto safeDrawWidth = std::max(1, drawWidth); - auto safeDrawHeight = std::max(1, drawHeight); - - if (safeDrawLeft >= static_cast(width) || safeDrawTop >= static_cast(height)) { - AndroidBitmap_unlockPixels(env, bitmap); - return false; - } - - safeDrawWidth = std::min(safeDrawWidth, static_cast(width) - safeDrawLeft); - safeDrawHeight = std::min(safeDrawHeight, static_cast(height) - safeDrawTop); - - rlottie::Surface surface( - reinterpret_cast(pixels), - width, - height, - bytesPerLine - ); - surface.setDrawRegion( - static_cast(safeDrawLeft), - static_cast(safeDrawTop), - static_cast(safeDrawWidth), - static_cast(safeDrawHeight) - ); - - auto safeFrame = std::max(0, frameNo); - auto totalFrames = static_cast(animation->totalFrame()); - if (totalFrames > 0) { - safeFrame %= totalFrames; - } - - animation->renderSync(static_cast(safeFrame), surface, true); - - swizzleArgbToRgba( - reinterpret_cast(pixels), - static_cast(width), - static_cast(bytesPerLine), - safeDrawLeft, - safeDrawTop, - safeDrawWidth, - safeDrawHeight - ); - - AndroidBitmap_unlockPixels(env, bitmap); - return true; -} - -int RLottieDecoder::getWidth() const { - if (animation == nullptr) { - return 0; - } - size_t width = 0; - size_t height = 0; - animation->size(width, height); - return static_cast(width); -} - -int RLottieDecoder::getHeight() const { - if (animation == nullptr) { - return 0; - } - size_t width = 0; - size_t height = 0; - animation->size(width, height); - return static_cast(height); -} - -int RLottieDecoder::getTotalFrames() const { - if (animation == nullptr) { - return 0; - } - return static_cast(animation->totalFrame()); -} - -double RLottieDecoder::getFrameRate() const { - if (animation == nullptr) { - return 0.0; - } - return animation->frameRate(); -} - -long RLottieDecoder::getDurationMs() const { - if (animation == nullptr) { - return 0; - } - return static_cast(animation->duration() * 1000.0); -} diff --git a/presentation/src/main/cpp/RLottieDecoder.h b/presentation/src/main/cpp/RLottieDecoder.h deleted file mode 100644 index 1a659c59..00000000 --- a/presentation/src/main/cpp/RLottieDecoder.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef MONOGRAM_RLOTTIEDECODER_H -#define MONOGRAM_RLOTTIEDECODER_H - -#include -#include -#include - -namespace rlottie { -class Animation; -} - -class RLottieDecoder { -public: - RLottieDecoder(); - ~RLottieDecoder(); - - bool openFromData(const std::string &jsonData, const std::string &cacheKey, const std::string &resourcePath); - bool renderFrame(JNIEnv *env, jobject bitmap, int frameNo, int drawLeft, int drawTop, int drawWidth, int drawHeight); - - int getWidth() const; - int getHeight() const; - int getTotalFrames() const; - double getFrameRate() const; - long getDurationMs() const; - -private: - std::unique_ptr animation; -}; - -#endif diff --git a/presentation/src/main/cpp/RLottieJni.cpp b/presentation/src/main/cpp/RLottieJni.cpp deleted file mode 100644 index 73c02587..00000000 --- a/presentation/src/main/cpp/RLottieJni.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include - -#include - -#include "RLottieDecoder.h" - -extern "C" { - -JNIEXPORT jlong JNICALL -Java_org_monogram_presentation_features_stickers_core_RLottieWrapper_create(JNIEnv *, jobject) { - return reinterpret_cast(new RLottieDecoder()); -} - -JNIEXPORT jboolean JNICALL -Java_org_monogram_presentation_features_stickers_core_RLottieWrapper_openFromData( - JNIEnv *env, - jobject, - jlong ptr, - jstring json, - jstring cacheKey, - jstring resourcePath -) { - auto *decoder = reinterpret_cast(ptr); - if (decoder == nullptr || json == nullptr || cacheKey == nullptr || resourcePath == nullptr) { - return JNI_FALSE; - } - - const char *jsonChars = env->GetStringUTFChars(json, nullptr); - const char *keyChars = env->GetStringUTFChars(cacheKey, nullptr); - const char *pathChars = env->GetStringUTFChars(resourcePath, nullptr); - - const std::string jsonData(jsonChars != nullptr ? jsonChars : ""); - const std::string keyData(keyChars != nullptr ? keyChars : ""); - const std::string pathData(pathChars != nullptr ? pathChars : ""); - - if (jsonChars != nullptr) env->ReleaseStringUTFChars(json, jsonChars); - if (keyChars != nullptr) env->ReleaseStringUTFChars(cacheKey, keyChars); - if (pathChars != nullptr) env->ReleaseStringUTFChars(resourcePath, pathChars); - - return decoder->openFromData(jsonData, keyData, pathData) ? JNI_TRUE : JNI_FALSE; -} - -JNIEXPORT jboolean JNICALL -Java_org_monogram_presentation_features_stickers_core_RLottieWrapper_renderFrame( - JNIEnv *env, - jobject, - jlong ptr, - jobject bitmap, - jint frameNo, - jint drawLeft, - jint drawTop, - jint drawWidth, - jint drawHeight -) { - auto *decoder = reinterpret_cast(ptr); - if (decoder == nullptr) { - return JNI_FALSE; - } - - return decoder->renderFrame(env, bitmap, frameNo, drawLeft, drawTop, drawWidth, drawHeight) - ? JNI_TRUE - : JNI_FALSE; -} - -JNIEXPORT jint JNICALL -Java_org_monogram_presentation_features_stickers_core_RLottieWrapper_getWidth(JNIEnv *, jobject, jlong ptr) { - auto *decoder = reinterpret_cast(ptr); - return decoder == nullptr ? 0 : decoder->getWidth(); -} - -JNIEXPORT jint JNICALL -Java_org_monogram_presentation_features_stickers_core_RLottieWrapper_getHeight(JNIEnv *, jobject, jlong ptr) { - auto *decoder = reinterpret_cast(ptr); - return decoder == nullptr ? 0 : decoder->getHeight(); -} - -JNIEXPORT jint JNICALL -Java_org_monogram_presentation_features_stickers_core_RLottieWrapper_getTotalFrames(JNIEnv *, jobject, jlong ptr) { - auto *decoder = reinterpret_cast(ptr); - return decoder == nullptr ? 0 : decoder->getTotalFrames(); -} - -JNIEXPORT jdouble JNICALL -Java_org_monogram_presentation_features_stickers_core_RLottieWrapper_getFrameRate(JNIEnv *, jobject, jlong ptr) { - auto *decoder = reinterpret_cast(ptr); - return decoder == nullptr ? 0.0 : decoder->getFrameRate(); -} - -JNIEXPORT jlong JNICALL -Java_org_monogram_presentation_features_stickers_core_RLottieWrapper_getDurationMs(JNIEnv *, jobject, jlong ptr) { - auto *decoder = reinterpret_cast(ptr); - return decoder == nullptr ? 0 : decoder->getDurationMs(); -} - -JNIEXPORT void JNICALL -Java_org_monogram_presentation_features_stickers_core_RLottieWrapper_destroy(JNIEnv *, jobject, jlong ptr) { - auto *decoder = reinterpret_cast(ptr); - delete decoder; -} - -} diff --git a/presentation/src/main/cpp/VpxDecoder.cpp b/presentation/src/main/cpp/VpxDecoder.cpp deleted file mode 100644 index aab2c551..00000000 --- a/presentation/src/main/cpp/VpxDecoder.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include "VpxDecoder.h" -#include -#include - -#define LOG_TAG "VpxDecoder" -#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) - -VpxDecoder::VpxDecoder() { - inputBuffer.resize(1024 * 1024); -} - -VpxDecoder::~VpxDecoder() { - close(); -} - -bool VpxDecoder::open(int fd, off_t offset, off_t length) { - extractor = AMediaExtractor_new(); - media_status_t err = AMediaExtractor_setDataSourceFd(extractor, fd, offset, length); - - if (err != AMEDIA_OK) { - LOGE("Failed to set data source"); - return false; - } - - int numTracks = AMediaExtractor_getTrackCount(extractor); - int videoTrackIndex = -1; - - for (int i = 0; i < numTracks; i++) { - AMediaFormat* format = AMediaExtractor_getTrackFormat(extractor, i); - const char* mime; - if (AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime)) { - if (std::string(mime) == "video/x-vnd.on2.vp9") { - codec_iface = vpx_codec_vp9_dx(); - videoTrackIndex = i; - - AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &width); - AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &height); - } else if (std::string(mime) == "video/x-vnd.on2.vp8") { - codec_iface = vpx_codec_vp8_dx(); - videoTrackIndex = i; - - AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &width); - AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &height); - } - } - AMediaFormat_delete(format); - if (videoTrackIndex >= 0) break; - } - - if (videoTrackIndex < 0 || !codec_iface) { - LOGE("No VP8/VP9 track found"); - return false; - } - - AMediaExtractor_selectTrack(extractor, videoTrackIndex); - - vpx_codec_dec_cfg_t cfg = {0}; - cfg.threads = 1; - cfg.w = 0; - cfg.h = 0; - - if (vpx_codec_dec_init(&codec_ctx, codec_iface, &cfg, 0)) { - LOGE("Failed to initialize libvpx: %s", vpx_codec_error(&codec_ctx)); - return false; - } - - frameCount = 0; - isCodecInitialized = true; - return true; -} - -long VpxDecoder::decodeFrame(JNIEnv* env, jobject bitmap) { - if (!isCodecInitialized) return -1; - - int64_t currentPtsUs = AMediaExtractor_getSampleTime(extractor); - ssize_t sampleSize = AMediaExtractor_readSampleData(extractor, inputBuffer.data(), inputBuffer.size()); - - if (sampleSize < 0) { - if (frameCount <= 1) { - return -2; - } - - AMediaExtractor_seekTo(extractor, 0, AMEDIAEXTRACTOR_SEEK_PREVIOUS_SYNC); - return 0; - } - - vpx_codec_err_t err = vpx_codec_decode(&codec_ctx, inputBuffer.data(), sampleSize, nullptr, 0); - if (err) { - LOGE("Decode error: %s", vpx_codec_error(&codec_ctx)); - AMediaExtractor_advance(extractor); - return 0; - } - - vpx_codec_iter_t iter = nullptr; - vpx_image_t* img = vpx_codec_get_frame(&codec_ctx, &iter); - - long durationMs = 33; - - if (img) { - void* bitmapPixels; - if (AndroidBitmap_lockPixels(env, bitmap, &bitmapPixels) == 0) { - AndroidBitmapInfo info; - AndroidBitmap_getInfo(env, bitmap, &info); - convertYuvToRgb(img, (uint8_t*)bitmapPixels, info.stride); - AndroidBitmap_unlockPixels(env, bitmap); - } - - frameCount++; - - bool hasNext = AMediaExtractor_advance(extractor); - if (hasNext) { - int64_t nextPtsUs = AMediaExtractor_getSampleTime(extractor); - if (nextPtsUs > currentPtsUs) { - durationMs = (long)((nextPtsUs - currentPtsUs) / 1000); - } - } else { - durationMs = lastFrameDurationMs; - } - - if (durationMs > 0) lastFrameDurationMs = durationMs; - - return lastFrameDurationMs; - } - - AMediaExtractor_advance(extractor); - return 0; -} -void VpxDecoder::close() { - if (isCodecInitialized) { - vpx_codec_destroy(&codec_ctx); - isCodecInitialized = false; - } - if (extractor) { - AMediaExtractor_delete(extractor); - extractor = nullptr; - } -} - -void VpxDecoder::convertYuvToRgb(const vpx_image_t* img, uint8_t* dst, int dstStride) { - int w = img->d_w; - int h = img->d_h; - - uint8_t* yPlane = img->planes[VPX_PLANE_Y]; - uint8_t* uPlane = img->planes[VPX_PLANE_U]; - uint8_t* vPlane = img->planes[VPX_PLANE_V]; - - int yStride = img->stride[VPX_PLANE_Y]; - int uStride = img->stride[VPX_PLANE_U]; - int vStride = img->stride[VPX_PLANE_V]; - - for (int y = 0; y < h; ++y) { - uint8_t* dstRow = dst + y * dstStride; - uint8_t* yRow = yPlane + y * yStride; - uint8_t* uRow = uPlane + (y / 2) * uStride; - uint8_t* vRow = vPlane + (y / 2) * vStride; - - for (int x = 0; x < w; ++x) { - int Y = yRow[x] - 16; - int U = uRow[x / 2] - 128; - int V = vRow[x / 2] - 128; - - int Y298 = 298 * Y; - int r = (Y298 + 409 * V + 128) >> 8; - int g = (Y298 - 100 * U - 208 * V + 128) >> 8; - int b = (Y298 + 516 * U + 128) >> 8; - - dstRow[x * 4 + 0] = std::clamp(r, 0, 255); - dstRow[x * 4 + 1] = std::clamp(g, 0, 255); - dstRow[x * 4 + 2] = std::clamp(b, 0, 255); - dstRow[x * 4 + 3] = 255; - } - } -} \ No newline at end of file diff --git a/presentation/src/main/cpp/VpxDecoder.h b/presentation/src/main/cpp/VpxDecoder.h deleted file mode 100644 index 13bc6233..00000000 --- a/presentation/src/main/cpp/VpxDecoder.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include "vpx/vpx_decoder.h" -#include "vpx/vp8dx.h" - -class VpxDecoder { -public: - VpxDecoder(); - ~VpxDecoder(); - - bool open(int fd, off_t offset, off_t length); - long decodeFrame(JNIEnv* env, jobject bitmap); - void close(); - - [[nodiscard]] int getWidth() const { return width; } - [[nodiscard]] int getHeight() const { return height; } - -private: - AMediaExtractor* extractor = nullptr; - vpx_codec_ctx_t codec_ctx; - vpx_codec_iface_t* codec_iface = nullptr; - - bool isCodecInitialized = false; - int width = 0; - int height = 0; - long lastFrameDurationMs = 33; - - int frameCount = 0; - - std::vector inputBuffer; - - void convertYuvToRgb(const vpx_image_t* img, uint8_t* dstPixels, int dstStride); -}; \ No newline at end of file diff --git a/presentation/src/main/cpp/build.sh b/presentation/src/main/cpp/build.sh deleted file mode 100644 index 75ca57f5..00000000 --- a/presentation/src/main/cpp/build.sh +++ /dev/null @@ -1,101 +0,0 @@ -#!/bin/bash -set -e - -# Set ANDROID_NDK_HOME here -# ANDROID_NDK_HOME= - -if [ -z "$ANDROID_NDK_HOME" ]; then - echo "Error: ANDROID_NDK_HOME is not set." - exit 1 -fi - -API_LEVEL=24 - -LIBVPX_PATH="$(pwd)/third_party/libvpx" -DIST_DIR="$(pwd)/libvpx_build" - -HOST_OS=$(uname -s | tr '[:upper:]' '[:lower:]') -PREBUILT_HOST="${HOST_OS}-x86_64" - -echo "Using NDK: $ANDROID_NDK_HOME" -echo "Build Platform: $PREBUILT_HOST" - -build_vpx() { - ABI=$1 - TARGET_NAME=$2 - - echo "========================================" - echo "Building for $ABI ($TARGET_NAME)..." - echo "========================================" - - PREFIX="$DIST_DIR/$ABI" - - TOOLCHAIN="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/$PREBUILT_HOST" - - case $ABI in - arm64-v8a) - ARCH_TRIPLE="aarch64-linux-android" - EXTRA_CFLAGS="-O3 -march=armv8-a" - ;; - armeabi-v7a) - ARCH_TRIPLE="armv7a-linux-androideabi" - EXTRA_CFLAGS="-Os -march=armv7-a -mfloat-abi=softfp -mfpu=neon -mthumb" - ;; - x86_64) - ARCH_TRIPLE="x86_64-linux-android" - EXTRA_CFLAGS="-O3 -march=x86-64 -msse4.2 -mpopcnt -m64 -fPIC" - EXTRA_CONFIGURE_FLAGS="--disable-mmx --disable-sse --disable-sse2 --disable-sse3 --disable-ssse3 --disable-sse4_1 --disable-avx --disable-avx2" - ;; - x86) - ARCH_TRIPLE="i686-linux-android" - EXTRA_CFLAGS="-O3 -march=i686 -msse3 -mfpmath=sse -m32 -fPIC" - ;; - esac - - CC_BIN="$TOOLCHAIN/bin/${ARCH_TRIPLE}${API_LEVEL}-clang" - CXX_BIN="$TOOLCHAIN/bin/${ARCH_TRIPLE}${API_LEVEL}-clang++" - - export CC="$CC_BIN" - export CXX="$CXX_BIN" - export AS="$CC_BIN" - export LD="$CC_BIN" - export AR="$TOOLCHAIN/bin/llvm-ar" - export STRIP="$TOOLCHAIN/bin/llvm-strip" - export NM="$TOOLCHAIN/bin/llvm-nm" - - cd "$LIBVPX_PATH" - - make clean > /dev/null 2>&1 || true - - ./configure \ - --target=$TARGET_NAME \ - --prefix="$PREFIX" \ - --disable-examples \ - --disable-tools \ - --disable-docs \ - --disable-unit-tests \ - --enable-pic \ - --enable-static \ - --disable-shared \ - --enable-small \ - --enable-realtime-only \ - --enable-vp8 \ - --enable-vp9 \ - --disable-vp8-encoder \ - --disable-vp9-encoder \ - --disable-webm-io \ - --force-target=android \ - --extra-cflags="-fPIC $EXTRA_CFLAGS" \ - $EXTRA_CONFIGURE_FLAGS - - make -j$(nproc) install - - cd .. -} - -build_vpx "arm64-v8a" "arm64-android-gcc" -build_vpx "armeabi-v7a" "armv7-android-gcc --enable-neon --disable-neon-asm" -build_vpx "x86_64" "x86_64-android-gcc" - -echo "" -echo "SUCCESS! Libs are in $DIST_DIR" \ No newline at end of file diff --git a/presentation/src/main/cpp/decoder.cpp b/presentation/src/main/cpp/decoder.cpp deleted file mode 100644 index c0e773be..00000000 --- a/presentation/src/main/cpp/decoder.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include -#include - -#include "vpx/vpx_decoder.h" -#include "vpx/vp8dx.h" - -extern "C" JNIEXPORT jstring JNICALL -Java_org_monogram_presentation_MainActivity_stringFromJNI(JNIEnv* env, jobject /* this */) { - const char* vpxVersion = vpx_codec_version_str(); - - return env->NewStringUTF(vpxVersion); -} \ No newline at end of file diff --git a/presentation/src/main/cpp/native-lib.cpp b/presentation/src/main/cpp/native-lib.cpp deleted file mode 100644 index 97b29dbc..00000000 --- a/presentation/src/main/cpp/native-lib.cpp +++ /dev/null @@ -1,632 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "VpxDecoder.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define LOG_TAG "NativeVideoPlayer" -#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) - -// Vertex Shader -const char* vertexShaderCode = R"( - attribute vec4 aPosition; - varying vec2 vTexCoord; - uniform mat4 uSTMatrix; - void main() { - gl_Position = vec4(aPosition.xy, 0.0, 1.0); - vTexCoord = (uSTMatrix * vec4(aPosition.zw, 0.0, 1.0)).xy; - } -)"; - -// Fragment Shader -const char* fragmentShaderCode = R"( - #extension GL_OES_EGL_image_external : require - precision mediump float; - varying vec2 vTexCoord; - uniform samplerExternalOES sTexture; - uniform sampler2D sOverlayTexture; - uniform int uHasOverlay; - uniform int uRemoveBlackBg; - uniform mat4 uColorMatrix; - uniform vec4 uColorOffset; - - void main() { - vec4 color = texture2D(sTexture, vTexCoord); - - if (uRemoveBlackBg == 1) { - float luma = dot(color.rgb, vec3(0.299, 0.587, 0.114)); - float alpha = smoothstep(0.01, 0.1, luma); - color.a = alpha; - color.rgb = color.rgb * alpha; - } - - // Apply Color Matrix - vec4 transformed = uColorMatrix * color + uColorOffset; - color = clamp(transformed, 0.0, 1.0); - - if (uHasOverlay == 1) { - vec4 overlay = texture2D(sOverlayTexture, vTexCoord); - // Standard alpha blending: src over dst - color = vec4(overlay.rgb * overlay.a + color.rgb * (1.0 - overlay.a), 1.0); - } - - gl_FragColor = color; - } -)"; - -// Typedef for eglPresentationTimeANDROID -typedef EGLBoolean (EGLAPIENTRYP PFNEGLPRESENTATIONTIMEANDROIDPROC)(EGLDisplay display, EGLSurface surface, EGLnsecsANDROID time); - -class NativeVideoRenderer { -public: - NativeVideoRenderer(JNIEnv* env, jobject instance, jobject surface, jboolean useAlpha, jboolean removeBlackBg) - : useAlpha(useAlpha), removeBlackBg(removeBlackBg) { - env->GetJavaVM(&jvm); - javaInstance = env->NewGlobalRef(instance); - nativeWindow = ANativeWindow_fromSurface(env, surface); - - // Initialize color matrix to identity - setIdentityMatrix(); - } - - ~NativeVideoRenderer() { - stop(); - if (nativeWindow) { - ANativeWindow_release(nativeWindow); - nativeWindow = nullptr; - } - JNIEnv* env; - if (jvm->GetEnv((void**)&env, JNI_VERSION_1_6) == JNI_OK) { - env->DeleteGlobalRef(javaInstance); - } - } - - void start() { - renderThread = std::thread(&NativeVideoRenderer::renderLoop, this); - } - - void stop() { - isRunning = false; - { - std::lock_guard lock(mutex); - frameAvailable = true; // Wake up thread - } - condition.notify_one(); - if (renderThread.joinable()) { - renderThread.join(); - } - } - - void updateSize(int width, int height) { - std::lock_guard lock(mutex); - this->width = width; - this->height = height; - } - - void onFrameAvailable() { - { - std::lock_guard lock(mutex); - frameAvailable = true; - } - condition.notify_one(); - } - - void setFilter(const float* matrixData) { - std::lock_guard lock(mutex); - if (matrixData == nullptr) { - setIdentityMatrix(); - } else { - colorMatrix[0] = matrixData[0]; - colorMatrix[1] = matrixData[5]; - colorMatrix[2] = matrixData[10]; - colorMatrix[3] = matrixData[15]; - - colorMatrix[4] = matrixData[1]; - colorMatrix[5] = matrixData[6]; - colorMatrix[6] = matrixData[11]; - colorMatrix[7] = matrixData[16]; - - colorMatrix[8] = matrixData[2]; - colorMatrix[9] = matrixData[7]; - colorMatrix[10] = matrixData[12]; - colorMatrix[11] = matrixData[17]; - - colorMatrix[12] = matrixData[3]; - colorMatrix[13] = matrixData[8]; - colorMatrix[14] = matrixData[13]; - colorMatrix[15] = matrixData[18]; - - colorOffset[0] = matrixData[4] / 255.0f; - colorOffset[1] = matrixData[9] / 255.0f; - colorOffset[2] = matrixData[14] / 255.0f; - colorOffset[3] = matrixData[19] / 255.0f; - } - } - - void setOverlayTexture(int textureId) { - std::lock_guard lock(mutex); - overlayTextureId = textureId; - } - -private: - JavaVM* jvm = nullptr; - jobject javaInstance = nullptr; - ANativeWindow* nativeWindow = nullptr; - std::thread renderThread; - std::atomic isRunning{true}; - std::mutex mutex; - std::condition_variable condition; - bool frameAvailable = false; - int width = 0; - int height = 0; - bool useAlpha; - bool removeBlackBg; - - EGLDisplay eglDisplay = EGL_NO_DISPLAY; - EGLContext eglContext = EGL_NO_CONTEXT; - EGLSurface eglSurface = EGL_NO_SURFACE; - PFNEGLPRESENTATIONTIMEANDROIDPROC eglPresentationTimeANDROID = nullptr; - - GLuint program = 0; - GLuint videoTextureId = 0; - GLuint overlayTextureId = 0; - - GLint aPositionHandle = 0; - GLint uSTMatrixHandle = 0; - GLint uRemoveBlackBgHandle = 0; - GLint uColorMatrixHandle = 0; - GLint uColorOffsetHandle = 0; - GLint uOverlayTextureHandle = 0; - GLint uHasOverlayHandle = 0; - - float stMatrix[16]; - float colorMatrix[16]; - float colorOffset[4]; - - const float vertexCoords[16] = { - -1.0f, -1.0f, 0.0f, 0.0f, - 1.0f, -1.0f, 1.0f, 0.0f, - -1.0f, 1.0f, 0.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 1.0f - }; - - void setIdentityMatrix() { - for (int i = 0; i < 16; i++) colorMatrix[i] = 0.0f; - colorMatrix[0] = 1.0f; - colorMatrix[5] = 1.0f; - colorMatrix[10] = 1.0f; - colorMatrix[15] = 1.0f; - for (int i = 0; i < 4; i++) colorOffset[i] = 0.0f; - } - - void renderLoop() { - JNIEnv* env; - if (jvm->AttachCurrentThread(&env, nullptr) != JNI_OK) return; - - initGL(); - initVideoTexture(env); - - while (isRunning) { - std::unique_lock lock(mutex); - condition.wait(lock, [this] { return frameAvailable || !isRunning; }); - - if (!isRunning) break; - frameAvailable = false; - - int w = width; - int h = height; - - float currentMatrix[16]; - float currentOffset[4]; - memcpy(currentMatrix, colorMatrix, 16 * sizeof(float)); - memcpy(currentOffset, colorOffset, 4 * sizeof(float)); - - int currentOverlay = overlayTextureId; - - lock.unlock(); - - drawFrame(env, w, h, currentMatrix, currentOffset, currentOverlay); - } - - releaseGL(); - jvm->DetachCurrentThread(); - } - - void initGL() { - eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); - EGLint version[2]; - eglInitialize(eglDisplay, &version[0], &version[1]); - - const EGLint configAttribs[] = { - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, - EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 0, EGL_NONE - }; - - EGLConfig config; - EGLint numConfigs; - eglChooseConfig(eglDisplay, configAttribs, &config, 1, &numConfigs); - - const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; - eglContext = eglCreateContext(eglDisplay, config, EGL_NO_CONTEXT, contextAttribs); - - eglSurface = eglCreateWindowSurface(eglDisplay, config, nativeWindow, nullptr); - eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); - - eglPresentationTimeANDROID = (PFNEGLPRESENTATIONTIMEANDROIDPROC)eglGetProcAddress("eglPresentationTimeANDROID"); - - program = createProgram(vertexShaderCode, fragmentShaderCode); - aPositionHandle = glGetAttribLocation(program, "aPosition"); - uSTMatrixHandle = glGetUniformLocation(program, "uSTMatrix"); - uRemoveBlackBgHandle = glGetUniformLocation(program, "uRemoveBlackBg"); - uColorMatrixHandle = glGetUniformLocation(program, "uColorMatrix"); - uColorOffsetHandle = glGetUniformLocation(program, "uColorOffset"); - uOverlayTextureHandle = glGetUniformLocation(program, "sOverlayTexture"); - uHasOverlayHandle = glGetUniformLocation(program, "uHasOverlay"); - - // Set default sampler units - glUseProgram(program); - glUniform1i(glGetUniformLocation(program, "sTexture"), 0); - glUniform1i(uOverlayTextureHandle, 1); - } - - void initVideoTexture(JNIEnv* env) { - GLuint textures[1]; - glGenTextures(1, textures); - videoTextureId = textures[0]; - - glBindTexture(GL_TEXTURE_EXTERNAL_OES, videoTextureId); - glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - jclass clazz = env->GetObjectClass(javaInstance); - jmethodID method = env->GetMethodID(clazz, "onGlContextReady", "(I)V"); - env->CallVoidMethod(javaInstance, method, (jint)videoTextureId); - } - - void drawFrame(JNIEnv* env, int w, int h, float* matrix, float* offset, int overlayId) { - if (videoTextureId == 0) return; - - jclass clazz = env->GetObjectClass(javaInstance); - jmethodID method = env->GetMethodID(clazz, "updateTexture", "([F)J"); - - jfloatArray matrixArray = env->NewFloatArray(16); - jlong timestamp = env->CallLongMethod(javaInstance, method, matrixArray); - - jfloat* stM = env->GetFloatArrayElements(matrixArray, nullptr); - memcpy(stMatrix, stM, 16 * sizeof(float)); - env->ReleaseFloatArrayElements(matrixArray, stM, 0); - env->DeleteLocalRef(matrixArray); - - glViewport(0, 0, w, h); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); - glUseProgram(program); - - if (useAlpha) { - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } else { - glDisable(GL_BLEND); - } - - glVertexAttribPointer(aPositionHandle, 4, GL_FLOAT, GL_FALSE, 0, vertexCoords); - glEnableVertexAttribArray(aPositionHandle); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_EXTERNAL_OES, videoTextureId); - // sTexture uniform is set to 0 in initGL - - glUniformMatrix4fv(uSTMatrixHandle, 1, GL_FALSE, stMatrix); - glUniform1i(uRemoveBlackBgHandle, removeBlackBg ? 1 : 0); - - glUniformMatrix4fv(uColorMatrixHandle, 1, GL_FALSE, matrix); - glUniform4fv(uColorOffsetHandle, 1, offset); - - if (overlayId > 0) { - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, overlayId); - glUniform1i(uHasOverlayHandle, 1); - } else { - glUniform1i(uHasOverlayHandle, 0); - } - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - if (eglPresentationTimeANDROID && timestamp > 0) { - eglPresentationTimeANDROID(eglDisplay, eglSurface, timestamp); - } - - eglSwapBuffers(eglDisplay, eglSurface); - } - - void releaseGL() { - if (videoTextureId != 0) { - GLuint textures[1] = {videoTextureId}; - glDeleteTextures(1, textures); - } - if (program != 0) glDeleteProgram(program); - if (eglDisplay != EGL_NO_DISPLAY) { - eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - eglDestroySurface(eglDisplay, eglSurface); - eglDestroyContext(eglDisplay, eglContext); - eglTerminate(eglDisplay); - } - } - - GLuint loadShader(GLenum type, const char* shaderCode) { - GLuint shader = glCreateShader(type); - glShaderSource(shader, 1, &shaderCode, nullptr); - glCompileShader(shader); - return shader; - } - - GLuint createProgram(const char* vertexCode, const char* fragmentCode) { - GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vertexCode); - GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentCode); - GLuint prog = glCreateProgram(); - glAttachShader(prog, vertexShader); - glAttachShader(prog, fragmentShader); - glLinkProgram(prog); - return prog; - } -}; - -// --- Video Processing Logic (C++) --- - -bool processVideoNative(const char* inputPath, const char* outputPath, - long startMs, long endMs, - int targetHeight, int bitrate, bool muteAudio, - const float* filterMatrix) { - - int fd = open(inputPath, O_RDONLY); - if (fd < 0) { - LOGE("Failed to open input file: %s", inputPath); - return false; - } - - AMediaExtractor* extractor = AMediaExtractor_new(); - AMediaExtractor_setDataSourceFd(extractor, fd, 0, lseek(fd, 0, SEEK_END)); - close(fd); - - int outFd = open(outputPath, O_CREAT | O_WRONLY | O_TRUNC, 0644); - if (outFd < 0) { - LOGE("Failed to open output file: %s", outputPath); - AMediaExtractor_delete(extractor); - return false; - } - - AMediaMuxer* muxer = AMediaMuxer_new(outFd, AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4); - - int rotation = 0; - - int videoTrackIndex = -1; - int audioTrackIndex = -1; - int muxerVideoTrackIndex = -1; - int muxerAudioTrackIndex = -1; - - size_t trackCount = AMediaExtractor_getTrackCount(extractor); - for (size_t i = 0; i < trackCount; i++) { - AMediaFormat* format = AMediaExtractor_getTrackFormat(extractor, i); - const char* mime; - AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime); - - if (strncmp(mime, "video/", 6) == 0) { - videoTrackIndex = i; - - if (!AMediaFormat_getInt32(format, "rotation-degrees", &rotation)) { - rotation = 0; - } - - // If we are just remuxing (no transcoding), add track - // Note: If filterMatrix is present, we SHOULD transcode, but as per previous constraints, - // we are falling back to remuxing for stability in this snippet. - // Ideally, if filterMatrix != nullptr, we would set up the EGL pipeline. - if (targetHeight <= 0) { - AMediaExtractor_selectTrack(extractor, i); - muxerVideoTrackIndex = AMediaMuxer_addTrack(muxer, format); - } - } else if (strncmp(mime, "audio/", 6) == 0 && !muteAudio) { - audioTrackIndex = i; - AMediaExtractor_selectTrack(extractor, i); - muxerAudioTrackIndex = AMediaMuxer_addTrack(muxer, format); - } - AMediaFormat_delete(format); - } - - AMediaMuxer_setOrientationHint(muxer, rotation); - - if (targetHeight > 0 && videoTrackIndex >= 0) { - // Fallback to remuxing video track - AMediaFormat* format = AMediaExtractor_getTrackFormat(extractor, videoTrackIndex); - AMediaExtractor_selectTrack(extractor, videoTrackIndex); - muxerVideoTrackIndex = AMediaMuxer_addTrack(muxer, format); - AMediaFormat_delete(format); - } - - // If we missed adding the video track because targetHeight > 0 but we fell back, - // or if filterMatrix is present but we are skipping transcoding: - if (videoTrackIndex >= 0 && muxerVideoTrackIndex < 0) { - AMediaFormat* format = AMediaExtractor_getTrackFormat(extractor, videoTrackIndex); - AMediaExtractor_selectTrack(extractor, videoTrackIndex); - muxerVideoTrackIndex = AMediaMuxer_addTrack(muxer, format); - AMediaFormat_delete(format); - } - - AMediaMuxer_start(muxer); - - // Seek to start - int64_t startUs = startMs * 1000; - int64_t endUs = (endMs > 0) ? (endMs * 1000) : INT64_MAX; - AMediaExtractor_seekTo(extractor, startUs, AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC); - - size_t bufSize = 1024 * 1024; - uint8_t* buffer = new uint8_t[bufSize]; - - while (true) { - ssize_t sampleSize = AMediaExtractor_readSampleData(extractor, buffer, bufSize); - if (sampleSize < 0) break; - - int64_t presentationTimeUs = AMediaExtractor_getSampleTime(extractor); - if (presentationTimeUs > endUs) break; - - if (presentationTimeUs >= startUs) { - size_t trackIndex = AMediaExtractor_getSampleTrackIndex(extractor); - AMediaCodecBufferInfo info; - info.offset = 0; - info.size = sampleSize; - info.presentationTimeUs = presentationTimeUs - startUs; - info.flags = AMediaExtractor_getSampleFlags(extractor); - - if (trackIndex == videoTrackIndex && muxerVideoTrackIndex >= 0) { - AMediaMuxer_writeSampleData(muxer, muxerVideoTrackIndex, buffer, &info); - } else if (trackIndex == audioTrackIndex && muxerAudioTrackIndex >= 0) { - AMediaMuxer_writeSampleData(muxer, muxerAudioTrackIndex, buffer, &info); - } - } - - if (!AMediaExtractor_advance(extractor)) break; - } - - delete[] buffer; - AMediaMuxer_stop(muxer); - AMediaMuxer_delete(muxer); - AMediaExtractor_delete(extractor); - close(outFd); // Close the output file descriptor - - return true; -} - -extern "C" { -JNIEXPORT jlong JNICALL -Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_create( - JNIEnv* env, jobject instance, jobject surface, jboolean useAlpha, jboolean removeBlackBg) { - auto* renderer = new NativeVideoRenderer(env, instance, surface, useAlpha, removeBlackBg); - renderer->start(); - return reinterpret_cast(renderer); -} - -JNIEXPORT void JNICALL -Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_destroy( - JNIEnv* env, jobject /* this */, jlong handle) { - auto* renderer = reinterpret_cast(handle); - delete renderer; -} - -JNIEXPORT void JNICALL -Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_updateSize( - JNIEnv* env, jobject /* this */, jlong handle, jint width, jint height) { - auto* renderer = reinterpret_cast(handle); - renderer->updateSize(width, height); -} - -JNIEXPORT void JNICALL -Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_notifyFrameAvailable( - JNIEnv* env, jobject /* this */, jlong handle) { - auto* renderer = reinterpret_cast(handle); - renderer->onFrameAvailable(); -} - -JNIEXPORT void JNICALL -Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_setFilter( - JNIEnv* env, jobject /* this */, jlong handle, jfloatArray matrix) { - auto* renderer = reinterpret_cast(handle); - if (matrix == nullptr) { - renderer->setFilter(nullptr); - } else { - jfloat* elements = env->GetFloatArrayElements(matrix, nullptr); - renderer->setFilter(elements); - env->ReleaseFloatArrayElements(matrix, elements, 0); - } -} - -JNIEXPORT void JNICALL -Java_org_monogram_presentation_features_chats_currentChat_components_NativeVideoRenderer_setOverlayTexture( - JNIEnv* env, jobject /* this */, jlong handle, jint textureId) { - auto* renderer = reinterpret_cast(handle); - renderer->setOverlayTexture(textureId); -} - -JNIEXPORT jlong JNICALL - Java_org_monogram_presentation_features_stickers_core_VpxWrapper_create(JNIEnv* env, jobject thiz) { -return (jlong) new VpxDecoder(); -} - -JNIEXPORT jboolean JNICALL - Java_org_monogram_presentation_features_stickers_core_VpxWrapper_open(JNIEnv* env, jobject thiz, jlong ptr, jint fd, jlong offset, jlong length) { -auto* decoder = (VpxDecoder*) ptr; -return decoder->open(fd, offset, length); -} - -JNIEXPORT jlong JNICALL - Java_org_monogram_presentation_features_stickers_core_VpxWrapper_decodeNextFrame(JNIEnv* env, jobject thiz, jlong ptr, jobject bitmap) { -auto* decoder = (VpxDecoder*) ptr; -return decoder->decodeFrame(env, bitmap); -} - -JNIEXPORT void JNICALL -Java_org_monogram_presentation_features_stickers_core_VpxWrapper_destroy(JNIEnv* env, jobject thiz, jlong ptr) { -auto* decoder = (VpxDecoder*) ptr; -delete decoder; -} - -JNIEXPORT jint JNICALL -Java_org_monogram_presentation_features_stickers_core_VpxWrapper_getWidth(JNIEnv* env, jobject thiz, jlong ptr) { - auto* decoder = (VpxDecoder*) ptr; - if (decoder == nullptr) return 0; - return decoder->getWidth(); -} - -JNIEXPORT jint JNICALL -Java_org_monogram_presentation_features_stickers_core_VpxWrapper_getHeight(JNIEnv* env, jobject thiz, jlong ptr) { - auto* decoder = (VpxDecoder*) ptr; - if (decoder == nullptr) return 0; - return decoder->getHeight(); -} - -JNIEXPORT jboolean JNICALL -Java_org_monogram_presentation_features_chats_currentChat_editor_video_VideoEditorUtils_processVideoNative( - JNIEnv* env, jclass clazz, - jstring inputPath, jstring outputPath, - jlong startMs, jlong endMs, - jint targetHeight, jint bitrate, jboolean muteAudio, jfloatArray filterMatrix) { - - const char* inputStr = env->GetStringUTFChars(inputPath, nullptr); - const char* outputStr = env->GetStringUTFChars(outputPath, nullptr); - - float* filter = nullptr; - if (filterMatrix != nullptr) { - filter = env->GetFloatArrayElements(filterMatrix, nullptr); - } - - bool result = processVideoNative(inputStr, outputStr, startMs, endMs, targetHeight, bitrate, muteAudio, filter); - - if (filterMatrix != nullptr) { - env->ReleaseFloatArrayElements(filterMatrix, filter, 0); - } - - env->ReleaseStringUTFChars(inputPath, inputStr); - env->ReleaseStringUTFChars(outputPath, outputStr); - - return result; -} - -} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/libvpx/.clang-format b/presentation/src/main/cpp/third_party/libvpx/.clang-format deleted file mode 100644 index a8bc4967..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/.clang-format +++ /dev/null @@ -1,9 +0,0 @@ ---- -Language: Cpp -BasedOnStyle: Google -AllowShortCaseLabelsOnASingleLine: true -ConstructorInitializerAllOnOneLineOrOnePerLine: false -Cpp11BracedListStyle: false -DerivePointerAlignment: false -PointerAlignment: Right -SortIncludes: false diff --git a/presentation/src/main/cpp/third_party/libvpx/.gitattributes b/presentation/src/main/cpp/third_party/libvpx/.gitattributes deleted file mode 100644 index 8088b703..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -configure eol=lf -*.sh eol=lf diff --git a/presentation/src/main/cpp/third_party/libvpx/.gitignore b/presentation/src/main/cpp/third_party/libvpx/.gitignore deleted file mode 100644 index 99eeb92d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/.gitignore +++ /dev/null @@ -1,71 +0,0 @@ -*.S -*.a -*.asm.s -*.d -*.gcda -*.gcno -*.o -*~ -.cproject -.idea -.project -.settings -.vscode -/*-*.mk -/*.asm -/*.doxy -/*.ivf -/*.ivf.md5 -/.bins -/.deps -/.docs -/.install-* -/.libs -/Makefile -/arm_neon.h -/config.log -/config.mk -/docs/ -/doxyfile -/examples/*.dox -/examples/decode_to_md5 -/examples/decode_with_drops -/examples/decode_with_partial_drops -/examples/example_xma -/examples/postproc -/examples/resize_util -/examples/set_maps -/examples/simple_decoder -/examples/simple_encoder -/examples/twopass_encoder -/examples/vp8_multi_resolution_encoder -/examples/vp8cx_set_ref -/examples/vp9cx_set_ref -/examples/vp9_lossless_encoder -/examples/vp9_spatial_svc_encoder -/examples/vpx_temporal_svc_encoder -/ivfdec -/ivfdec.dox -/ivfenc -/ivfenc.dox -/libvpx.so* -/libvpx.ver -/samples.dox -/test_intra_pred_speed -/test_libvpx -/tools.dox -/tools/*.dox -/tools/tiny_ssim -/vp8_api1_migration.dox -/vp[89x]_rtcd.h -/vpx.pc -/vpx_config.c -/vpx_config.h -/vpx_dsp_rtcd.h -/vpx_scale_rtcd.h -/vpx_version.h -/vpxdec -/vpxdec.dox -/vpxenc -/vpxenc.dox -TAGS diff --git a/presentation/src/main/cpp/third_party/libvpx/.mailmap b/presentation/src/main/cpp/third_party/libvpx/.mailmap deleted file mode 100644 index 2fc6c7d3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/.mailmap +++ /dev/null @@ -1,58 +0,0 @@ -Adrian Grange -Aℓex Converse -Aℓex Converse -Aℓex Converse -Alexis Ballier -Alpha Lam -Angie Chiang -Bohan Li -Chris Cunningham -Chi Yo Tsai -Daniele Castagna -Deb Mukherjee -Elliott Karpilovsky -Erik Niemeyer -Fyodor Kyslov -Gregor Jasny -Gregor Jasny -Guillaume Martres -Hangyu Kuang -Hui Su -Jacky Chen -Jim Bankoski -Johann Koenig -Johann Koenig -Johann Koenig -Johann Koenig -Johann -John Koleszar -Joshua Litt -Konstantinos Margaritis -Marco Paniconi -Marco Paniconi -Martin Storsjö -Michael Horowitz -Pascal Massimino -Paul Wilkins -Peter Boström -Peter de Rivaz -Peter de Rivaz -Ralph Giles -Ralph Giles -Ronald S. Bultje -Sai Deng -Sami Pietilä -Shiyou Yin -Tamar Levy -Tamar Levy -Tero Rintaluoma -Timothy B. Terriberry -Tom Finegan -Tom Finegan -Urvang Joshi -Yaowu Xu -Yaowu Xu -Yaowu Xu -Venkatarama NG. Avadhani -Vitaly Buka -Xiwei Gu diff --git a/presentation/src/main/cpp/third_party/libvpx/AUTHORS b/presentation/src/main/cpp/third_party/libvpx/AUTHORS deleted file mode 100644 index 14d5a1c8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/AUTHORS +++ /dev/null @@ -1,242 +0,0 @@ -# This file is automatically generated from the git commit history -# by tools/gen_authors.sh. - -Aaron Watry -Abo Talib Mahfoodh -Adam B. Goode -Adrian Grange -Ahmad Sharif -Aidan Welch -Aleksey Vasenev -Alexander Potapenko -Alexander Voronov -Alexandra Hájková -Aℓex Converse -Alexis Ballier -Alok Ahuja -Alpha Lam -A.Mahfoodh -Ami Fischman -Andoni Morales Alastruey -Andres Mejia -Andrew Lewis -Andrew Russell -Andrew Salkeld -Angie Chen -Angie Chiang -Anton Venema -Anupam Pandey -Aron Rosenberg -Attila Nagy -Birk Magnussen -Bohan Li -Brian Foley -Brion Vibber -Casey Smalley -changjun.yang -Charles 'Buck' Krasic -Cheng Chen -Chen Wang -Cherma Rajan A -Chi Yo Tsai -chm -Chris Cunningham -Christian Duvivier -Chunbo Hua -Chun-Min Chang -Clement Courbet -Daniel Cheng -Daniele Castagna -Daniel Kang -Daniel Sommermann -Dan Zhu -Deb Mukherjee -Deepa K G -Dim Temp -Dmitry Kovalev -Dragan Mrdjan -Ed Baker -Ehsan Akhgari -Elliott Karpilovsky -Erik Niemeyer -Fabio Pedretti -Frank Galligan -Fredrik Söderquist -Fritz Koenig -Fyodor Kyslov -Gabriel Marin -Gaute Strokkenes -George Steed -Gerda Zsejke More -Geza Lore -Ghislain MARY -Giuseppe Scrivano -Gordana Cmiljanovic -Gregor Jasny -Guillaume Martres -Guillermo Ballester Valor -Hangyu Kuang -Hanno Böck -Han Shen -Hao Chen -Hari Limaye -Harish Mahendrakar -Henrik Lundin -Hien Ho -Hirokazu Honda -Hui Su -Ilya Kurdyukov -Ivan Krasin -Ivan Maltz -Jacek Caban -Jacky Chen -James Berry -James Touton -James Yu -James Zern -Jan Gerber -Jan Kratochvil -Janne Salonen -Jean-Yves Avenard -Jeff Faust -Jeff Muizelaar -Jeff Petkau -Jeremy Leconte -Jerome Jiang -Jia Jia -Jianhui Dai -Jian Zhou -Jim Bankoski -jinbo -Jin Bo -Jingning Han -Joel Fernandes -Joey Parrish -Johann -Johann Koenig -John Koleszar -Johnny Klonaris -John Stark -Jonathan Wright -Jon Kunkee -Jorge E. Moreira -Joshua Bleecher Snyder -Joshua Litt -Julia Robson -Justin Clift -Justin Lebar -Kaustubh Raste -KO Myung-Hun -Konstantinos Margaritis -Kyle Siefring -Lawrence Velázquez -L. E. Segovia -Linfeng Zhang -Liu Peng -Lou Quillio -Luca Barbato -Luc Trudeau -Lu Wang -Makoto Kato -Mans Rullgard -Marco Paniconi -Mark Mentovai -Martin Ettl -Martin Storsjö -Matthew Heaney -Matthias Räncker -Michael Horowitz -Michael Kohler -Mike Frysinger -Mike Hommey -Mikhal Shemer -Mikko Koivisto -Min Chen -Minghai Shang -Min Ye -Mirko Bonadei -Moriyoshi Koizumi -Morton Jonuschat -Nathan E. Egge -Neeraj Gadgil -Neil Birkbeck -Nico Weber -Niveditha Rau -Parag Salasakar -Pascal Massimino -Patrik Westin -Paul Wilkins -Pavol Rusnak -Paweł Hajdan -Pengchong Jin -Peter Boström -Peter Collingbourne -Peter de Rivaz -Peter Kasting -Philip Jägenstedt -Priit Laes -Rafael Ávila de Espíndola -Rafaël Carré -Rafael de Lucena Valle -Rahul Chaudhry -Ralph Giles -Ranjit Kumar Tulabandu -Raphael Kubo da Costa -Ravi Chaudhary -Ritu Baldwa -Rob Bradford -Ronald S. Bultje -Rui Ueyama -Sai Deng -Salome Thirot -Sami Pietilä -Sam James -Sarah Parker -Sasi Inguva -Scott Graham -Scott LaVarnway -Sean McGovern -Sergey Kolomenkin -Sergey Silkin -Sergey Ulanov -Shimon Doodkin -Shiyou Yin -Shubham Tandle -Shunyao Li -Sreerenj Balachandran -Stefan Holmer -Suman Sunkara -Supradeep T R -Sylvestre Ledru -Taekhyun Kim -Takanori MATSUURA -Tamar Levy -Tao Bai -Tero Rintaluoma -Thijs Vermeir -Tim Kopp -Timothy B. Terriberry -Tom Finegan -Tristan Matthews -Urvang Joshi -Venkatarama NG. Avadhani -Vignesh Venkatasubramanian -Vitaly Buka -Vlad Tsyrklevich -Wan-Teh Chang -Wonkap Jang -Xiahong Bao -Xiwei Gu -Yaowu Xu -Yi Luo -Yongzhe Wang -yuanhecai -Yue Chen -Yun Liu -Yunqing Wang -Yury Gitman -Zoe Liu -Zoltan Kuscsik -Google Inc. -The Mozilla Foundation -The Xiph.Org Foundation diff --git a/presentation/src/main/cpp/third_party/libvpx/CHANGELOG b/presentation/src/main/cpp/third_party/libvpx/CHANGELOG deleted file mode 100644 index 28cdcdec..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/CHANGELOG +++ /dev/null @@ -1,1117 +0,0 @@ -2025-05-28 v1.15.2 "Wigeon Duck" - This release fixes CVE-2025-5283 (bug webm:413411335), and is ABI compatible - with the previous release. - -2025-01-09 v1.15.1 "Wigeon Duck" - This release bumps up the SO major version and fixes the language about ABI - compatibility in the previous release changelog. - -2024-10-22 v1.15.0 "Wigeon Duck" - This release includes new codec control for key frame filtering, more Neon - optimizations, improvements to RTC encoding and bug fixes. - - - Upgrading: - This release is ABI incompatible with the previous release. - - It is strongly recommended to skip this release and upgrade to v1.15.1 since - the shared object was versioned incorrectly, as shown in - https://issues.webmproject.org/issues/384672478. - - Temporal filtering improvement that can be turned on with the new codec - control VP9E_SET_KEY_FRAME_FILTERING, which gives 1+% BD-rate saving with - minimal encoder time increase. - - libwebm is upgraded to libwebm-1.0.0.31-10-g3b63004 - - - Enhancement: - Neon optimization speed up - 1-3% speed up across speed 5 to 10 for RTC - 3% speed up for speed 0 and 1 for VoD in standard bitdepth - 3% and 7% speed up for speed 0 and 1 respectively for VoD in high bitdepth - Scene detection is allowed for all RTC speeds (>=5) - Support profile guided optimizations - - Delta quantization parameters for UV channels for vp8 is supported in RTC - rate control library - - Rate control parameters are reset and maximum QP is enforced on scene - changes in SVC when there is no inter-layer prediction - - - Bug fixes: - Fix to Uninitialized scalar variable in `vp9_rd_pick_inter_mode_sb()` - Fix to Integer-overflow in `resize_multistep` - Fix to Heap-buffer-overflow in `vpx_sad64x64_avx2` - Fix to Crash in `vpx_sad8x8_sse2` - Fix to Assertion in `write_modes` - Support profile guided optimizations - Fix to Integer-overflow in `encode_frame_to_data_rate` - Fix to Integer-overflow in `vp9_svc_check_reset_layer_rc_flag` - Fix to core dump error from /usr/bin/tools/tiny_ssim --help - Fix to use-of-uninitialized-value in `vp9_setup_tpl_stats` - Fix to Undefined-shift in `vp9_cyclic_refresh_setup` - Fix to redundant `&& __GNUC__` preproc check - Fix to valgrind warning in EncodeAPI.OssFuzz69906 - Fix to Index-out-of-bounds in `vp8_rd_pick_inter_mode` - Fix to Integer-overflow in `vp8_pick_frame_size` - Fix to Use-of-uninitialized-value in `vpx_codec_peek_stream_info` - Fix to log clutters with the message "Warning: Desired height too large" - Fix to Integer-overflow in `vp9_svc_adjust_avg_frame_qindex` - - Fix to integer overflows caused by huge target bitrate, frame rate, or - g_timebase numerator or denominator - - Fix to missing license headers - Fix to build failure for Android Armv7 - Fix to integer overflows in image helpers - Fix to Integer-overflow in `vp9_calc_iframe_target_size_one_pass_cbr` - Fix to Heap-buffer-overflow in `vp9_pick_inter_mode` - Fix to Segv in `vp9_multi_thread_tile_init` - Fix to Use-of-uninitialized-value in `vp9_row_mt_sync_mem_dealloc` - Fix to Crash in `mbloop_filter_vertical_edge_c` - Fix to Check failed in CheckUnwind - Fix to Heap-buffer-overflow in `write_modes_b` and `vpx_write` - Fix to Possible signed integer overflow found in `vpx_codec_encode` - Fix to build conflicts between Abseil and libaom/libvpx in Win ARM64 builds - Fix to build failures on aarch64 - Fix to Data race in libvpx ARM NEON - Fix to Heap-buffer-overflow in `scale_plane_1_to_2_phase_0` - Fix to integer overflow in `encode_mb_row` - Fix to Floating-point-exception in `vp8_pick_frame_size` - Fix to Heap-buffer-overflow in `vp9_enc_setup_mi` - Fix to build failure with --target=arm64-win64-vs17 - Fix to heap-buffer-overflow write in `vpx_img_read()` - Fix to C vs armv8-linux-gcc encode mismatches for `y4m_360p_10bit_input` - Fix to Null-dereference READ in `ml_predict_var_rd_partitioning` - Fix to Heap-buffer-overflow in `vpx_scaled_2d_ssse3` - Fix to Crash in `convolve_horiz` - Fix to Ill in `vpx_scaled_2d_ssse3` - Fix to Global-buffer-overflow in `cost_coeffs` - -2024-05-21 v1.14.1 "Venetian Duck" - This release includes enhancements and bug fixes. - - - Upgrading: - This release is ABI compatible with the previous release. - - - Enhancement: - Improved the detection of compiler support for AArch64 extensions, - particularly SVE. - - Added vpx_codec_get_global_headers() support for VP9. - - - Bug fixes: - Added buffer bounds checks to vpx_writer and vpx_write_bit_buffer. - Fix to GetSegmentationData() crash in aq_mode=0 for RTC rate control. - Fix to alloc for row_base_thresh_freq_fac. - Free row mt memory before freeing cpi->tile_data. - Fix to buffer alloc for vp9_bitstream_worker_data. - Fix to VP8 race issue for multi-thread with pnsr_calc. - Fix to uv width/height in vp9_scale_and_extend_frame_ssse3. - Fix to integer division by zero and overflow in calc_pframe_target_size(). - Fix to integer overflow in vpx_img_alloc() & vpx_img_wrap()(CVE-2024-5197). - Fix to UBSan error in vp9_rc_update_framerate(). - Fix to UBSan errors in vp8_new_framerate(). - Fix to integer overflow in vp8 encodeframe.c. - Handle EINTR from sem_wait(). - -2024-01-02 v1.14.0 "Venetian Duck" - This release drops support for old C compilers, such as Visual Studio 2012 - and older, that disallow mixing variable declarations and statements (a C99 - feature). It adds support for run-time CPU feature detection for Arm - platforms, as well as support for darwin23 (macOS 14). - - - Upgrading: - This release is ABI incompatible with the previous release. - - Various new features for rate control library for real-time: SVC parallel - encoding, loopfilter level, support for frame dropping, and screen content. - - New callback function send_tpl_gop_stats for vp9 external rate control - library, which can be used to transmit TPL stats for a group of pictures. A - public header vpx_tpl.h is added for the definition of TPL stats used in - this callback. - - libwebm is upgraded to libwebm-1.0.0.29-9-g1930e3c. - - - Enhancement: - Improvements on Neon optimizations: VoD: 12-35% speed up for bitdepth 8, - 68%-151% speed up for high bitdepth. - - Improvements on AVX2 and SSE optimizations. - Improvements on LSX optimizations for LoongArch. - 42-49% speedup on speed 0 VoD encoding. - Android API level predicates. - - - Bug fixes: - Fix to missing prototypes from the rtcd header. - Fix to segfault when total size is enlarged but width is smaller. - Fix to the build for arm64ec using MSVC. - Fix to copy BLOCK_8X8's mi to PICK_MODE_CONTEXT::mic. - Fix to -Wshadow warnings. - Fix to heap overflow in vpx_get4x4sse_cs_neon. - Fix to buffer overrun in highbd Neon subpel variance filters. - Added bitexact encode test script. - Fix to -Wl,-z,defs with Clang's sanitizers. - Fix to decoder stability after error & continued decoding. - Fix to mismatch of VP9 encode with NEON intrinsics with C only version. - Fix to Arm64 MSVC compile vpx_highbd_fdct4x4_neon. - Fix to fragments count before use. - Fix to a case where target bandwidth is 0 for SVC. - Fix mask in vp9_quantize_avx2,highbd_get_max_lane_eob. - Fix to int overflow in vp9_calc_pframe_target_size_one_pass_cbr. - Fix to integer overflow in vp8,ratectrl.c. - Fix to integer overflow in vp9 svc. - Fix to avg_frame_bandwidth overflow. - Fix to per frame qp for temporal layers. - Fix to unsigned integer overflow in sse computation. - Fix to uninitialized mesh feature for BEST mode. - Fix to overflow in highbd temporal_filter. - Fix to unaligned loads w/w==4 in vpx_convolve_copy_neon. - Skip arm64_neon.h workaround w/VS >= 2019. - Fix to c vs avx mismatch of diamond_search_sad(). - Fix to c vs intrinsic mismatch of vpx_hadamard_32x32() function. - Fix to a bug in vpx_hadamard_32x32_neon(). - Fix to Clang -Wunreachable-code-aggressive warnings. - Fix to a bug in vpx_highbd_hadamard_32x32_neon(). - Fix to -Wunreachable-code in mfqe_partition. - Force mode search on 64x64 if no mode is selected. - Fix to ubsan failure caused by left shift of negative. - Fix to integer overflow in calc_pframe_target_size. - Fix to float-cast-overflow in vp8_change_config(). - Fix to a null ptr before use. - Conditionally skip using inter frames in speed features. - Remove invalid reference frames. - Disable intra mode search speed features conditionally. - Set nonrd keyframe under dynamic change of deadline for rtc. - Fix to scaled reference offsets. - Set skip_recode=0 in nonrd_pick_sb_modes. - Fix to an edge case when downsizing to one. - Fix to a bug in frame scaling. - Fix to pred buffer stride. - Fix to a bug in simple motion search. - Update frame size in actual encoding. - -2023-09-29 v1.13.1 "Ugly Duckling" - This release contains two security related fixes. One each for VP8 and VP9. - - - Upgrading: - This release is ABI compatible with the previous release. - - - Bug fixes: - https://crbug.com/1486441 (CVE-2023-5217) - Fix to a crash related to VP9 encoding (#1642, CVE-2023-6349) - -2023-01-31 v1.13.0 "Ugly Duckling" - This release includes more Neon and AVX2 optimizations, adds a new codec - control to set per frame QP, upgrades GoogleTest to v1.12.1, and includes - numerous bug fixes. - - - Upgrading: - This release is ABI incompatible with the previous release. - - New codec control VP9E_SET_QUANTIZER_ONE_PASS to set per frame QP. - - GoogleTest is upgraded to v1.12.1. - - .clang-format is upgraded to clang-format-11. - - VPX_EXT_RATECTRL_ABI_VERSION was bumped due to incompatible changes to the - feature of using external rate control models for vp9. - - - Enhancement: - Numerous improvements on Neon optimizations. - Numerous improvements on AVX2 optimizations. - Additional ARM targets added for Visual Studio. - - - Bug fixes: - Fix to calculating internal stats when frame dropped. - Fix to segfault for external resize test in vp9. - Fix to build system with replacing egrep with grep -E. - Fix to a few bugs with external RTC rate control library. - Fix to make SVC work with VBR. - Fix to key frame setting in VP9 external RC. - Fix to -Wimplicit-int (Clang 16). - Fix to VP8 external RC for buffer levels. - Fix to VP8 external RC for dynamic update of layers. - Fix to VP9 auto level. - Fix to off-by-one error of max w/h in validate_config. - Fix to make SVC work for Profile 1. - -2022-06-17 v1.12.0 "Torrent Duck" - This release adds optimizations for Loongarch, adds support for vp8 in the - real-time rate control library, upgrades GoogleTest to v1.11.0, updates - libwebm to libwebm-1.0.0.28-20-g206d268, and includes numerous bug fixes. - - - Upgrading: - This release is ABI compatible with the previous release. - - vp8 support in the real-time rate control library. - New codec control VP8E_SET_RTC_EXTERNAL_RATECTRL is added. - - Configure support for darwin21 is added. - - GoogleTest is upgraded to v1.11.0. - - libwebm is updated to libwebm-1.0.0.28-20-g206d268. - - Allow SimpleEncode environment to take target level as input to match - the level conformance in vp9. - - - Enhancement: - Numerous improvements on checking memory allocations. - Optimizations for Loongarch. - Code clean-up. - - - Bug fixes: - Fix to a crash related to {vp8/vp9}_set_roi_map. - Fix to compiling failure with -Wformat-nonliteral. - Fix to integer overflow with vp9 with high resolution content. - Fix to AddNoiseTest failure with ARMv7. - Fix to libvpx Null-dereference READ in vp8. - -2021-09-27 v1.11.0 "Smew Duck" - This maintenance release adds support for VBR mode in VP9 rate control - interface, new codec controls to get quantization parameters and loop filter - levels, and includes several improvements to NEON and numerous bug fixes. - - - Upgrading: - This release is ABI incompatible with the previous release. - New codec control is added to get quantization parameters and loop filter - levels. - - VBR mode is supported in VP9 rate control library. - - - Enhancement: - Numerous improvements for Neon optimizations. - Code clean-up and refactoring. - Calculation of rd multiplier is changed with BDRATE gains. - - - Bug fixes: - Fix to overflow on duration. - Fix to several instances of -Wunused-but-set-variable. - Fix to avoid chroma resampling for 420mpeg2 input. - Fix to overflow in calc_iframe_target_size. - Fix to disallow skipping transform and quantization. - Fix some -Wsign-compare warnings in simple_encode. - Fix input file path in simple_encode_test. - Fix valid range for under/over_shoot pct. - -2021-03-09 v1.10.0 "Ruddy Duck" - This maintenance release adds support for darwin20 and new codec controls, as - well as numerous bug fixes. - - - Upgrading: - This release is ABI incompatible with the previous release. - New codec control is added to disable loopfilter for VP9. - - New encoder control is added to disable feature to increase Q on overshoot - detection for CBR. - - Configure support for darwin20 is added. - - New codec control is added for VP9 rate control. The control ID of this - interface is VP9E_SET_EXTERNAL_RATE_CONTROL. To make VP9 use a customized - external rate control model, users will have to implement each callback - function in vpx_rc_funcs_t and register them using libvpx API - vpx_codec_control_() with the control ID. - - - Enhancement: - Use -std=gnu++11 instead of -std=c++11 for c++ files. - - - Bug fixes: - Override assembler with --as option of configure for MSVS. - Fix several compilation issues with gcc 4.8.5. - Fix to resetting rate control for temporal layers. - Fix to the rate control stats of SVC example encoder when number of spatial - layers is 1. - Fix to reusing motion vectors from the base spatial layer in SVC. - 2 pass related flags removed from SVC example encoder. - -2020-07-29 v1.9.0 "Quacking Duck" - This release adds support for NV12, a separate library for rate control, as - well as incremental improvements. - - - Upgrading: - This release is ABI compatible with the previous release. - NV12 support is added to this release. - A new interface is added for VP9 rate control. The new library libvp9rc.a - must be linked by applications. - Googletest is updated to v1.10.0. - simple_encode.cc is compiled into a new library libsimple_encode.a with - CONFIG_RATE_CTRL. - - - Enhancement: - Various changes to improve VP9 SVC, rate control, quality and speed to real - time encoding. - - - Bug fixes: - Fix key frame update refresh simulcast flexible svc. - Fix to disable_16x16part speed feature for real time encoding. - Fix some signed integer overflows for VP9 rate control. - Fix initialization of delta_q_uv. - Fix condition in regulate_q for cyclic refresh. - Various fixes to dynamic resizing for VP9 SVC. - -2019-12-09 v1.8.2 "Pekin Duck" - This release collects incremental improvements to many aspects of the library. - - - Upgrading: - This release is ABI compatible with the previous release. - ARCH_* defines have been removed in favor of VPX_ARCH_*. - -2019-07-15 v1.8.1 "Orpington Duck" - This release collects incremental improvements to many aspects of the library. - - - Upgrading: - This release is ABI incompatible with the previous release. - VP8E_SET_CPUUSED now accepts values up to 9 for vp9. - VPX_CTRL_VP9E_SET_MAX_INTER_BITRATE_PCT had a spelling fix (was VP8E). - The --sdk-path option has been removed. If you were using it to build for - Android please read build/make/Android.mk for alternatives. - All PPC optimizations have been disabled: - https://bugs.chromium.org/p/webm/issues/detail?id=1522. - - - Enhancements: - Various changes to improve encoder rate control, quality and speed - for practically every use case. - - - Bug fixes: - vp9-rtc: Fix color artifacts for speed >= 8. - -2019-01-31 v1.8.0 "Northern Shoveler Duck" - This release focused on encoding performance for realtime and VOD use cases. - - - Upgrading: - This release is ABI incompatible with the previous release. This adds and - improves several vp9 controls. Most are related to SVC: - VP9E_SET_SVC_FRAME_DROP_LAYER: - - Frame dropping in SVC. - VP9E_SET_SVC_INTER_LAYER_PRED: - - Inter-layer prediction in SVC. - VP9E_SET_SVC_GF_TEMPORAL_REF: - - Enable long term temporal reference in SVC. - VP9E_SET_SVC_REF_FRAME_CONFIG/VP9E_GET_SVC_REF_FRAME_CONFIG: - - Extend and improve this control for better flexibility in setting SVC - pattern dynamically. - VP9E_SET_POSTENCODE_DROP: - - Allow for post-encode frame dropping (applies to non-SVC too). - VP9E_SET_SVC_SPATIAL_LAYER_SYNC: - - Enable spatial layer sync frames. - VP9E_SET_SVC_LAYER_ID: - - Extend api to specify temporal id for each spatial layers. - VP9E_SET_ROI_MAP: - - Extend Region of Interest functionality to VP9. - - - Enhancements: - 2 pass vp9 encoding has improved substantially. When using --auto-alt-ref=6, - we see approximately 8% for VBR and 10% for CQ. When using --auto-alt-ref=1, - the gains are approximately 4% for VBR and 5% for CQ. - - For real-time encoding, speed 7 has improved by ~5-10%. Encodes targeted at - screen sharing have improved when the content changes significantly (slide - sharing) or scrolls. There is a new speed 9 setting for mobile devices which - is about 10-20% faster than speed 8. - - - Bug fixes: - VP9 denoiser issue. - VP9 partition issue for 1080p. - VP9 rate control improvments. - Postprocessing Multi Frame Quality Enhancement (MFQE) issue. - VP8 multithread decoder issues. - A variety of fuzzing issues. - -2018-01-04 v1.7.0 "Mandarin Duck" - This release focused on high bit depth performance (10/12 bit) and vp9 - encoding improvements. - - - Upgrading: - This release is ABI incompatible due to new vp9 encoder features. - - Frame parallel decoding for vp9 has been removed. - - - Enhancements: - vp9 encoding supports additional threads with --row-mt. This can be greater - than the number of tiles. - - Two new vp9 encoder options have been added: - --corpus-complexity - --tune-content=film - - Additional tooling for respecting the vp9 "level" profiles has been added. - - - Bug fixes: - A variety of fuzzing issues. - vp8 threading fix for ARM. - Codec control VP9_SET_SKIP_LOOP_FILTER fixed. - Reject invalid multi resolution configurations. - -2017-01-09 v1.6.1 "Long Tailed Duck" - This release improves upon the VP9 encoder and speeds up the encoding and - decoding processes. - - - Upgrading: - This release is ABI compatible with 1.6.0. - - - Enhancements: - Faster VP9 encoding and decoding. - High bit depth builds now provide similar speed for 8 bit encode and decode - for x86 targets. Other platforms and higher bit depth improvements are in - progress. - - - Bug Fixes: - A variety of fuzzing issues. - -2016-07-20 v1.6.0 "Khaki Campbell Duck" - This release improves upon the VP9 encoder and speeds up the encoding and - decoding processes. - - - Upgrading: - This release is ABI incompatible with 1.5.0 due to a new 'color_range' enum - in vpx_image and some minor changes to the VP8_COMP structure. - - The default key frame interval for VP9 has changed from 128 to 9999. - - - Enhancement: - A core focus has been performance for low end Intel processors. SSSE3 - instructions such as 'pshufb' have been avoided and instructions have been - reordered to better accommodate the more constrained pipelines. - - As a result, devices based on Celeron processors have seen substantial - decoding improvements. From Indian Runner Duck to Javan Whistling Duck, - decoding speed improved between 10 and 30%. Between Javan Whistling Duck - and Khaki Campbell Duck, it improved another 10 to 15%. - - While Celeron benefited most, Core-i5 also improved 5% and 10% between the - respective releases. - - Realtime performance for WebRTC for both speed and quality has received a - lot of attention. - - - Bug Fixes: - A number of fuzzing issues, found variously by Mozilla, Chromium and others, - have been fixed and we strongly recommend updating. - -2015-11-09 v1.5.0 "Javan Whistling Duck" - This release improves upon the VP9 encoder and speeds up the encoding and - decoding processes. - - - Upgrading: - This release is ABI incompatible with 1.4.0. It drops deprecated VP8 - controls and adds a variety of VP9 controls for testing. - - The vpxenc utility now prefers VP9 by default. - - - Enhancements: - Faster VP9 encoding and decoding - Smaller library size by combining functions used by VP8 and VP9 - - - Bug Fixes: - A variety of fuzzing issues - -2015-04-03 v1.4.0 "Indian Runner Duck" - This release includes significant improvements to the VP9 codec. - - - Upgrading: - This release is ABI incompatible with 1.3.0. It drops the compatibility - layer, requiring VPX_IMG_FMT_* instead of IMG_FMT_*, and adds several codec - controls for VP9. - - - Enhancements: - Faster VP9 encoding and decoding - Multithreaded VP9 decoding (tile and frame-based) - Multithreaded VP9 encoding - on by default - YUV 4:2:2 and 4:4:4 support in VP9 - 10 and 12bit support in VP9 - 64bit ARM support by replacing ARM assembly with intrinsics - - - Bug Fixes: - Fixes a VP9 bitstream issue in Profile 1. This only affected non-YUV 4:2:0 - files. - - - Known Issues: - Frame Parallel decoding fails for segmented and non-420 files. - -2013-11-15 v1.3.0 "Forest" - This release introduces the VP9 codec in a backward-compatible way. - All existing users of VP8 can continue to use the library without - modification. However, some VP8 options do not map to VP9 in the same manner. - - The VP9 encoder in this release is not feature complete. Users interested in - the encoder are advised to use the git master branch and discuss issues on - libvpx mailing lists. - - - Upgrading: - This release is ABI and API compatible with Duclair (v1.0.0). Users - of older releases should refer to the Upgrading notes in this document - for that release. - - - Enhancements: - Get rid of bashisms in the main build scripts - Added usage info on command line options - Add lossless compression mode - Dll build of libvpx - Add additional Mac OS X targets: 10.7, 10.8 and 10.9 (darwin11-13) - Add option to disable documentation - configure: add --enable-external-build support - make: support V=1 as short form of verbose=yes - configure: support mingw-w64 - configure: support hardfloat armv7 CHOSTS - configure: add support for android x86 - Add estimated completion time to vpxenc - Don't exit on decode errors in vpxenc - vpxenc: support scaling prior to encoding - vpxdec: support scaling output - vpxenc: improve progress indicators with --skip - msvs: Don't link to winmm.lib - Add a new script for producing vcxproj files - Produce Visual Studio 10 and 11 project files - Produce Windows Phone project files - msvs-build: use msbuild for vs >= 2005 - configure: default configure log to config.log - Add encoding option --static-thresh - - - Speed: - Miscellaneous speed optimizations for VP8 and VP9. - - - Quality: - In general, quality is consistent with the Eider release. - - - Bug Fixes: - This release represents approximately a year of engineering effort, - and contains multiple bug fixes. Please refer to git history for details. - - -2012-12-21 v1.2.0 - This release acts as a checkpoint for a large amount of internal refactoring - and testing. It also contains a number of small bugfixes, so all users are - encouraged to upgrade. - - - Upgrading: - This release is ABI and API compatible with Duclair (v1.0.0). Users - of older releases should refer to the Upgrading notes in this - document for that release. - - - Enhancements: - VP8 optimizations for MIPS dspr2 - vpxenc: add -quiet option - - - Speed: - Encoder and decoder speed is consistent with the Eider release. - - - Quality: - In general, quality is consistent with the Eider release. - - Minor tweaks to ARNR filtering - Minor improvements to real time encoding with multiple temporal layers - - - Bug Fixes: - Fixes multithreaded encoder race condition in loopfilter - Fixes multi-resolution threaded encoding - Fix potential encoder dead-lock after picture resize - - -2012-05-09 v1.1.0 "Eider" - This introduces a number of enhancements, mostly focused on real-time - encoding. In addition, it fixes a decoder bug (first introduced in - Duclair) so all users of that release are encouraged to upgrade. - - - Upgrading: - This release is ABI and API compatible with Duclair (v1.0.0). Users - of older releases should refer to the Upgrading notes in this - document for that release. - - This release introduces a new temporal denoiser, controlled by the - VP8E_SET_NOISE_SENSITIVITY control. The temporal denoiser does not - currently take a strength parameter, so the control is effectively - a boolean - zero (off) or non-zero (on). For compatibility with - existing applications, the values accepted are the same as those - for the spatial denoiser (0-6). The temporal denoiser is enabled - by default, and the older spatial denoiser may be restored by - configuring with --disable-temporal-denoising. The temporal denoiser - is more computationally intensive than the spatial one. - - This release removes support for a legacy, decode only API that was - supported, but deprecated, at the initial release of libvpx - (v0.9.0). This is not expected to have any impact. If you are - impacted, you can apply a reversion to commit 2bf8fb58 locally. - Please update to the latest libvpx API if you are affected. - - - Enhancements: - Adds a motion compensated temporal denoiser to the encoder, which - gives higher quality than the older spatial denoiser. (See above - for notes on upgrading). - - In addition, support for new compilers and platforms were added, - including: - improved support for XCode - Android x86 NDK build - OS/2 support - SunCC support - - Changing resolution with vpx_codec_enc_config_set() is now - supported. Previously, reinitializing the codec was required to - change the input resolution. - - The vpxenc application has initial support for producing multiple - encodes from the same input in one call. Resizing is not yet - supported, but varying other codec parameters is. Use -- to - delineate output streams. Options persist from one stream to the - next. - - Also, the vpxenc application will now use a keyframe interval of - 5 seconds by default. Use the --kf-max-dist option to override. - - - Speed: - Decoder performance improved 2.5% versus Duclair. Encoder speed is - consistent with Duclair for most material. Two pass encoding of - slideshow-like material will see significant improvements. - - Large realtime encoding speed gains at a small quality expense are - possible by configuring the on-the-fly bitpacking experiment with - --enable-onthefly-bitpacking. Realtime encoder can be up to 13% - faster (ARM) depending on the number of threads and bitrate - settings. This technique sees constant gain over the 5-16 speed - range. For VC style input the loss seen is up to 0.2dB. See commit - 52cf4dca for further details. - - - Quality: - On the whole, quality is consistent with the Duclair release. Some - tweaks: - - Reduced blockiness in easy sections by applying a penalty to - intra modes. - - Improved quality of static sections (like slideshows) with - two pass encoding. - - Improved keyframe sizing with multiple temporal layers - - - Bug Fixes: - Corrected alt-ref contribution to frame rate for visible updates - to the alt-ref buffer. This affected applications making manual - usage of the frame reference flags, or temporal layers. - - Additional constraints were added to disable multi-frame quality - enhancement (MFQE) in sections of the frame where there is motion. - (#392) - - Fixed corruption issues when vpx_codec_enc_config_set() was called - with spatial resampling enabled. - - Fixed a decoder error introduced in Duclair where the segmentation - map was not being reinitialized on keyframes (#378) - - -2012-01-27 v1.0.0 "Duclair" - Our fourth named release, focused on performance and features related to - real-time encoding. It also fixes a decoder crash bug introduced in - v0.9.7, so all users of that release are encouraged to upgrade. - - - Upgrading: - This release is ABI incompatible with prior releases of libvpx, so the - "major" version number has been bumped to 1. You must recompile your - applications against the latest version of the libvpx headers. The - API remains compatible, and this should not require code changes in most - applications. - - - Enhancements: - This release introduces several substantial new features to the encoder, - of particular interest to real time streaming applications. - - Temporal scalability allows the encoder to produce a stream that can - be decimated to different frame rates, with independent rate targeting - for each substream. - - Multiframe quality enhancement postprocessing can make visual quality - more consistent in the presence of frames that are substantially - different quality than the surrounding frames, as in the temporal - scalability case and in some forced keyframe scenarios. - - Multiple-resolution encoding support allows the encoding of the - same content at different resolutions faster than encoding them - separately. - - - Speed: - Optimization targets for this release included the decoder and the real- - time modes of the encoder. Decoder speed on x86 has improved 10.5% with - this release. Encoder improvements followed a curve where speeds 1-3 - improved 4.0%-1.5%, speeds 4-8 improved <1%, and speeds 9-16 improved - 1.5% to 10.5%, respectively. "Best" mode speed is consistent with the - Cayuga release. - - - Quality: - Encoder quality in the single stream case is consistent with the Cayuga - release. - - - Bug Fixes: - This release fixes an OOB read decoder crash bug present in v0.9.7 - related to the clamping of motion vectors in SPLITMV blocks. This - behavior could be triggered by corrupt input or by starting - decoding from a P-frame. - - -2011-08-15 v0.9.7-p1 "Cayuga" patch 1 - This is an incremental bugfix release against Cayuga. All users of that - release are strongly encouraged to upgrade. - - - Fix potential OOB reads (cdae03a) - - An unbounded out of bounds read was discovered when the - decoder was requested to perform error concealment (new in - Cayuga) given a frame with corrupt partition sizes. - - A bounded out of bounds read was discovered affecting all - versions of libvpx. Given an multipartition input frame that - is truncated between the mode/mv partition and the first - residiual paritition (in the block of partition offsets), up - to 3 extra bytes could have been read from the source buffer. - The code will not take any action regardless of the contents - of these undefined bytes, as the truncated buffer is detected - immediately following the read based on the calculated - starting position of the coefficient partition. - - - Fix potential error concealment crash when the very first frame - is missing or corrupt (a609be5) - - - Fix significant artifacts in error concealment (a4c2211, 99d870a) - - - Revert 1-pass CBR rate control changes (e961317) - Further testing showed this change produced undesirable visual - artifacts, rolling back for now. - - -2011-08-02 v0.9.7 "Cayuga" - Our third named release, focused on a faster, higher quality, encoder. - - - Upgrading: - This release is backwards compatible with Aylesbury (v0.9.5) and - Bali (v0.9.6). Users of older releases should refer to the Upgrading - notes in this document for that release. - - - Enhancements: - Stereo 3D format support for vpxenc - Runtime detection of available processor cores. - Allow specifying --end-usage by enum name - vpxdec: test for frame corruption - vpxenc: add quantizer histogram display - vpxenc: add rate histogram display - Set VPX_FRAME_IS_DROPPABLE - update configure for ios sdk 4.3 - Avoid text relocations in ARM vp8 decoder - Generate a vpx.pc file for pkg-config. - New ways of passing encoded data between encoder and decoder. - - - Speed: - This release includes across-the-board speed improvements to the - encoder. On x86, these measure at approximately 11.5% in Best mode, - 21.5% in Good mode (speed 0), and 22.5% in Realtime mode (speed 6). - On ARM Cortex A9 with Neon extensions, real-time encoding of video - telephony content is 35% faster than Bali on single core and 48% - faster on multi-core. On the NVidia Tegra2 platform, real time - encoding is 40% faster than Bali. - - Decoder speed was not a priority for this release, but improved - approximately 8.4% on x86. - - Reduce motion vector search on alt-ref frame. - Encoder loopfilter running in its own thread - Reworked loopfilter to precalculate more parameters - SSE2/SSSE3 optimizations for build_predictors_mbuv{,_s}(). - Make hor UV predict ~2x faster (73 vs 132 cycles) using SSSE3. - Removed redundant checks - Reduced structure sizes - utilize preload in ARMv6 MC/LPF/Copy routines - ARM optimized quantization, dfct, variance, subtract - Increase chrow row alignment to 16 bytes. - disable trellis optimization for first pass - Write SSSE3 sub-pixel filter function - Improve SSE2 half-pixel filter funtions - Add vp8_sub_pixel_variance16x8_ssse3 function - Reduce unnecessary distortion computation - Use diamond search to replace full search - Preload reference area in sub-pixel motion search (real-time mode) - - - Quality: - This release focused primarily on one-pass use cases, including - video conferencing. Low latency data rate control was significantly - improved, improving streamability over bandwidth constrained links. - Added support for error concealment, allowing frames to maintain - visual quality in the presence of substantial packet loss. - - Add rc_max_intra_bitrate_pct control - Limit size of initial keyframe in one-pass. - Improve framerate adaptation - Improved 1-pass CBR rate control - Improved KF insertion after fades to still. - Improved key frame detection. - Improved activity masking (lower PSNR impact for same SSIM boost) - Improved interaction between GF and ARFs - Adding error-concealment to the decoder. - Adding support for independent partitions - Adjusted rate-distortion constants - - - - Bug Fixes: - Removed firstpass motion map - Fix parallel make install - Fix multithreaded encoding for 1 MB wide frame - Fixed iwalsh_neon build problems with RVDS4.1 - Fix semaphore emulation, spin-wait intrinsics on Windows - Fix build with xcode4 and simplify GLOBAL. - Mark ARM asm objects as allowing a non-executable stack. - Fix vpxenc encoding incorrect webm file header on big endian - - -2011-03-07 v0.9.6 "Bali" - Our second named release, focused on a faster, higher quality, encoder. - - - Upgrading: - This release is backwards compatible with Aylesbury (v0.9.5). Users - of older releases should refer to the Upgrading notes in this - document for that release. - - - Enhancements: - vpxenc --psnr shows a summary when encode completes - --tune=ssim option to enable activity masking - improved postproc visualizations for development - updated support for Apple iOS to SDK 4.2 - query decoder to determine which reference frames were updated - implemented error tracking in the decoder - fix pipe support on windows - - - Speed: - Primary focus was on good quality mode, speed 0. Average improvement - on x86 about 40%, up to 100% on user-generated content at that speed. - Best quality mode speed improved 35%, and realtime speed 10-20%. This - release also saw significant improvement in realtime encoding speed - on ARM platforms. - - Improved encoder threading - Dont pick encoder filter level when loopfilter is disabled. - Avoid double copying of key frames into alt and golden buffer - FDCT optimizations. - x86 sse2 temporal filter - SSSE3 version of fast quantizer - vp8_rd_pick_best_mbsegmentation code restructure - Adjusted breakout RD for SPLITMV - Changed segmentation check order - Improved rd_pick_intra4x4block - Adds armv6 optimized variance calculation - ARMv6 optimized sad16x16 - ARMv6 optimized half pixel variance calculations - Full search SAD function optimization in SSE4.1 - Improve MV prediction accuracy to achieve performance gain - Improve MV prediction in vp8_pick_inter_mode() for speed>3 - - - Quality: - Best quality mode improved PSNR 6.3%, and SSIM 6.1%. This release - also includes support for "activity masking," which greatly improves - SSIM at the expense of PSNR. For now, this feature is available with - the --tune=ssim option. Further experimentation in this area - is ongoing. This release also introduces a new rate control mode - called "CQ," which changes the allocation of bits within a clip to - the sections where they will have the most visual impact. - - Tuning for the more exact quantizer. - Relax rate control for last few frames - CQ Mode - Limit key frame quantizer for forced key frames. - KF/GF Pulsing - Add simple version of activity masking. - make rdmult adaptive for intra in quantizer RDO - cap the best quantizer for 2nd order DC - change the threshold of DC check for encode breakout - - - Bug Fixes: - Fix crash on Sparc Solaris. - Fix counter of fixed keyframe distance - ARNR filter pointer update bug fix - Fixed use of motion percentage in KF/GF group calc - Changed condition for using RD in Intra Mode - Fix encoder real-time only configuration. - Fix ARM encoder crash with multiple token partitions - Fixed bug first cluster timecode of webm file is wrong. - Fixed various encoder bugs with odd-sized images - vp8e_get_preview fixed when spatial resampling enabled - quantizer: fix assertion in fast quantizer path - Allocate source buffers to be multiples of 16 - Fix for manual Golden frame frequency - Fix drastic undershoot in long form content - - -2010-10-28 v0.9.5 "Aylesbury" - Our first named release, focused on a faster decoder, and a better encoder. - - - Upgrading: - This release incorporates backwards-incompatible changes to the - ivfenc and ivfdec tools. These tools are now called vpxenc and vpxdec. - - vpxdec - * the -q (quiet) option has been removed, and replaced with - -v (verbose). the output is quiet by default. Use -v to see - the version number of the binary. - - * The default behavior is now to write output to a single file - instead of individual frames. The -y option has been removed. - Y4M output is the default. - - * For raw I420/YV12 output instead of Y4M, the --i420 or --yv12 - options must be specified. - - $ ivfdec -o OUTPUT INPUT - $ vpxdec --i420 -o OUTPUT INPUT - - * If an output file is not specified, the default is to write - Y4M to stdout. This makes piping more natural. - - $ ivfdec -y -o - INPUT | ... - $ vpxdec INPUT | ... - - * The output file has additional flexibility for formatting the - filename. It supports escape characters for constructing a - filename from the width, height, and sequence number. This - replaces the -p option. To get the equivalent: - - $ ivfdec -p frame INPUT - $ vpxdec --i420 -o frame-%wx%h-%4.i420 INPUT - - vpxenc - * The output file must be specified with -o, rather than as the - last argument. - - $ ivfenc INPUT OUTPUT - $ vpxenc -o OUTPUT INPUT - - * The output defaults to webm. To get IVF output, use the --ivf - option. - - $ ivfenc INPUT OUTPUT.ivf - $ vpxenc -o OUTPUT.ivf --ivf INPUT - - - - Enhancements: - ivfenc and ivfdec have been renamed to vpxenc, vpxdec. - vpxdec supports .webm input - vpxdec writes .y4m by default - vpxenc writes .webm output by default - vpxenc --psnr now shows the average/overall PSNR at the end - ARM platforms now support runtime cpu detection - vpxdec visualizations added for motion vectors, block modes, references - vpxdec now silent by default - vpxdec --progress shows frame-by-frame timing information - vpxenc supports the distinction between --fps and --timebase - NASM is now a supported assembler - configure: enable PIC for shared libs by default - configure: add --enable-small - configure: support for ppc32-linux-gcc - configure: support for sparc-solaris-gcc - - - Bugs: - Improve handling of invalid frames - Fix valgrind errors in the NEON loop filters. - Fix loopfilter delta zero transitions - Fix valgrind errors in vp8_sixtap_predict8x4_armv6(). - Build fixes for darwin-icc - - - Speed: - 20-40% (average 28%) improvement in libvpx decoder speed, - including: - Rewrite vp8_short_walsh4x4_sse2() - Optimizations on the loopfilters. - Miscellaneous improvements for Atom - Add 4-tap version of 2nd-pass ARMv6 MC filter. - Improved multithread utilization - Better instruction choices on x86 - reorder data to use wider instructions - Update NEON wide idcts - Make block access to frame buffer sequential - Improved subset block search - Bilinear subpixel optimizations for ssse3. - Decrease memory footprint - - Encoder speed improvements (percentage gain not measured): - Skip unnecessary search of identical frames - Add SSE2 subtract functions - Improve bounds checking in vp8_diamond_search_sadx4() - Added vp8_fast_quantize_b_sse2 - - - Quality: - Over 7% overall PSNR improvement (6.3% SSIM) in "best" quality - encoding mode, and up to 60% improvement on very noisy, still - or slow moving source video - - Motion compensated temporal filter for Alt-Ref Noise Reduction - Improved use of trellis quantization on 2nd order Y blocks - Tune effect of motion on KF/GF boost in two pass - Allow coefficient optimization for good quality speed 0. - Improved control of active min quantizer for two pass. - Enable ARFs for non-lagged compress - -2010-09-02 v0.9.2 - - Enhancements: - Disable frame dropping by default - Improved multithreaded performance - Improved Force Key Frame Behaviour - Increased rate control buffer level precision - Fix bug in 1st pass motion compensation - ivfenc: correct fixed kf interval, --disable-kf - - Speed: - Changed above and left context data layout - Rework idct calling structure. - Removed unnecessary MB_MODE_INFO copies - x86: SSSE3 sixtap prediction - Reworked IDCT to include reconstruction (add) step - Swap alt/gold/new/last frame buffer ptrs instead of copying. - Improve SSE2 loopfilter functions - Change bitreader to use a larger window. - Avoid loopfilter reinitialization when possible - - Quality: - Normalize quantizer's zero bin and rounding factors - Add trellis quantization. - Make the quantizer exact. - Updates to ARNR filtering algorithm - Fix breakout thresh computation for golden & AltRef frames - Redo the forward 4x4 dct - Improve the accuracy of forward walsh-hadamard transform - Further adjustment of RD behaviour with Q and Zbin. - - Build System: - Allow linking of libs built with MinGW to MSVC - Fix target auto-detection on mingw32 - Allow --cpu= to work for x86. - configure: pass original arguments through to make dist - Fix builds without runtime CPU detection - msvs: fix install of codec sources - msvs: Change devenv.com command line for better msys support - msvs: Add vs9 targets. - Add x86_64-linux-icc target - - Bugs: - Potential crashes on older MinGW builds - Fix two-pass framrate for Y4M input. - Fixed simple loop filter, other crashes on ARM v6 - arm: fix missing dependency with --enable-shared - configure: support directories containing .o - Replace pinsrw (SSE) with MMX instructions - apple: include proper mach primatives - Fixed rate control bug with long key frame interval. - Fix DSO link errors on x86-64 when not using a version script - Fixed buffer selection for UV in AltRef filtering - - -2010-06-17 v0.9.1 - - Enhancements: - * ivfenc/ivfdec now support YUV4MPEG2 input and pipe I/O - * Speed optimizations - - Bugfixes: - * Rate control - * Prevent out-of-bounds accesses on invalid data - - Build system updates: - * Detect toolchain to be used automatically for native builds - * Support building shared libraries - * Better autotools emulation (--prefix, --libdir, DESTDIR) - - Updated LICENSE - * http://webmproject.blogspot.com/2010/06/changes-to-webm-open-source-license.html - - -2010-05-18 v0.9.0 - - Initial open source release. Welcome to WebM and VP8! - diff --git a/presentation/src/main/cpp/third_party/libvpx/CONTRIBUTING.md b/presentation/src/main/cpp/third_party/libvpx/CONTRIBUTING.md deleted file mode 100644 index 7a73a303..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/CONTRIBUTING.md +++ /dev/null @@ -1,29 +0,0 @@ -# How to Contribute - -We'd love to accept your patches and contributions to this project. There are -just a few small guidelines you need to follow. - -## Contributor License Agreement - -Contributions to this project must be accompanied by a Contributor License -Agreement. You (or your employer) retain the copyright to your contribution; -this simply gives us permission to use and redistribute your contributions as -part of the project. Head over to to see -your current agreements on file or to sign a new one. - -You generally only need to submit a CLA once, so if you've already submitted one -(even if it was for a different project), you probably don't need to do it -again. - -## Code reviews - -All submissions, including submissions by project members, require review. We -use a [Gerrit](https://www.gerritcodereview.com) instance hosted at -https://chromium-review.googlesource.com for this purpose. See the -[WebM Project page](https://www.webmproject.org/code/contribute/submitting-patches/) -for additional details. - -## Community Guidelines - -This project follows -[Google's Open Source Community Guidelines](https://opensource.google.com/conduct/). diff --git a/presentation/src/main/cpp/third_party/libvpx/LICENSE b/presentation/src/main/cpp/third_party/libvpx/LICENSE deleted file mode 100644 index 1ce44343..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/LICENSE +++ /dev/null @@ -1,31 +0,0 @@ -Copyright (c) 2010, The WebM Project authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * Neither the name of Google, nor the WebM Project, nor the names - of its contributors may be used to endorse or promote products - derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/presentation/src/main/cpp/third_party/libvpx/PATENTS b/presentation/src/main/cpp/third_party/libvpx/PATENTS deleted file mode 100644 index caedf607..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/PATENTS +++ /dev/null @@ -1,23 +0,0 @@ -Additional IP Rights Grant (Patents) ------------------------------------- - -"These implementations" means the copyrightable works that implement the WebM -codecs distributed by Google as part of the WebM Project. - -Google hereby grants to you a perpetual, worldwide, non-exclusive, no-charge, -royalty-free, irrevocable (except as stated in this section) patent license to -make, have made, use, offer to sell, sell, import, transfer, and otherwise -run, modify and propagate the contents of these implementations of WebM, where -such license applies only to those patent claims, both currently owned by -Google and acquired in the future, licensable by Google that are necessarily -infringed by these implementations of WebM. This grant does not include claims -that would be infringed only as a consequence of further modification of these -implementations. If you or your agent or exclusive licensee institute or order -or agree to the institution of patent litigation or any other patent -enforcement activity against any entity (including a cross-claim or -counterclaim in a lawsuit) alleging that any of these implementations of WebM -or any code incorporated within any of these implementations of WebM -constitute direct or contributory patent infringement, or inducement of -patent infringement, then any patent rights granted to you under this License -for these implementations of WebM shall terminate as of the date such -litigation is filed. diff --git a/presentation/src/main/cpp/third_party/libvpx/README b/presentation/src/main/cpp/third_party/libvpx/README deleted file mode 100644 index 9f17a63f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/README +++ /dev/null @@ -1,231 +0,0 @@ -Welcome to the WebM VP8/VP9 Codec SDK! - -COMPILING THE APPLICATIONS/LIBRARIES: - The build system used is similar to autotools. Building generally consists of - "configuring" with your desired build options, then using GNU make to build - the application. - - 1. Prerequisites - - * All x86 targets require the Yasm[1] assembler be installed[2]. - * All Windows builds require that Cygwin[3] or MSYS2[4] be installed. - * Building the documentation requires Doxygen[5]. If you do not - have this package, the install-docs option will be disabled. - * Downloading the data for the unit tests requires curl[6] and sha1sum. - sha1sum is provided via the GNU coreutils, installed by default on - many *nix platforms, as well as MinGW and Cygwin. If coreutils is not - available, a compatible version of sha1sum can be built from - source[7]. These requirements are optional if not running the unit - tests. - - [1]: http://www.tortall.net/projects/yasm - [2]: For Visual Studio the base yasm binary (not vsyasm) should be in the - PATH for Visual Studio. For VS2017 it is sufficient to rename - yasm--.exe to yasm.exe and place it in: - Program Files (x86)/Microsoft Visual Studio/2017//Common7/Tools/ - [3]: http://www.cygwin.com - [4]: http://www.msys2.org/ - [5]: http://www.doxygen.org - [6]: http://curl.haxx.se - [7]: http://www.microbrew.org/tools/md5sha1sum/ - - 2. Out-of-tree builds - Out of tree builds are a supported method of building the application. For - an out of tree build, the source tree is kept separate from the object - files produced during compilation. For instance: - - $ mkdir build - $ cd build - $ ../libvpx/configure - $ make - - 3. Configuration options - The 'configure' script supports a number of options. The --help option can be - used to get a list of supported options: - $ ../libvpx/configure --help - - 4. Compiler analyzers - Compilers have added sanitizers which instrument binaries with information - about address calculation, memory usage, threading, undefined behavior, and - other common errors. To simplify building libvpx with some of these features - use tools/set_analyzer_env.sh before running configure. It will set the - compiler and necessary flags for building as well as environment variables - read by the analyzer when testing the binaries. - $ source ../libvpx/tools/set_analyzer_env.sh address - - 5. Cross development - For cross development, the most notable option is the --target option. The - most up-to-date list of supported targets can be found at the bottom of the - --help output of the configure script. As of this writing, the list of - available targets is: - - arm64-android-gcc - arm64-darwin-gcc - arm64-darwin20-gcc - arm64-darwin21-gcc - arm64-darwin22-gcc - arm64-darwin23-gcc - arm64-darwin24-gcc - arm64-linux-gcc - arm64-win64-gcc - arm64-win64-vs15 - arm64-win64-vs16 - arm64-win64-vs16-clangcl - arm64-win64-vs17 - arm64-win64-vs17-clangcl - armv7-android-gcc - armv7-darwin-gcc - armv7-linux-rvct - armv7-linux-gcc - armv7-none-rvct - armv7-win32-gcc - armv7-win32-vs14 - armv7-win32-vs15 - armv7-win32-vs16 - armv7-win32-vs17 - armv7s-darwin-gcc - armv8-linux-gcc - loongarch32-linux-gcc - loongarch64-linux-gcc - mips32-linux-gcc - mips64-linux-gcc - ppc64le-linux-gcc - sparc-solaris-gcc - x86-android-gcc - x86-darwin8-gcc - x86-darwin8-icc - x86-darwin9-gcc - x86-darwin9-icc - x86-darwin10-gcc - x86-darwin11-gcc - x86-darwin12-gcc - x86-darwin13-gcc - x86-darwin14-gcc - x86-darwin15-gcc - x86-darwin16-gcc - x86-darwin17-gcc - x86-iphonesimulator-gcc - x86-linux-gcc - x86-linux-icc - x86-os2-gcc - x86-solaris-gcc - x86-win32-gcc - x86-win32-vs14 - x86-win32-vs15 - x86-win32-vs16 - x86-win32-vs17 - x86_64-android-gcc - x86_64-darwin9-gcc - x86_64-darwin10-gcc - x86_64-darwin11-gcc - x86_64-darwin12-gcc - x86_64-darwin13-gcc - x86_64-darwin14-gcc - x86_64-darwin15-gcc - x86_64-darwin16-gcc - x86_64-darwin17-gcc - x86_64-darwin18-gcc - x86_64-darwin19-gcc - x86_64-darwin20-gcc - x86_64-darwin21-gcc - x86_64-darwin22-gcc - x86_64-darwin23-gcc - x86_64-darwin24-gcc - x86_64-iphonesimulator-gcc - x86_64-linux-gcc - x86_64-linux-icc - x86_64-solaris-gcc - x86_64-win64-gcc - x86_64-win64-vs14 - x86_64-win64-vs15 - x86_64-win64-vs16 - x86_64-win64-vs17 - generic-gnu - - The generic-gnu target, in conjunction with the CROSS environment variable, - can be used to cross compile architectures that aren't explicitly listed, if - the toolchain is a cross GNU (gcc/binutils) toolchain. Other POSIX toolchains - will likely work as well. For instance, to build using the mipsel-linux-uclibc - toolchain, the following command could be used (note, POSIX SH syntax, adapt - to your shell as necessary): - - $ CROSS=mipsel-linux-uclibc- ../libvpx/configure - - In addition, the executables to be invoked can be overridden by specifying the - environment variables: AR, AS, CC, CXX, LD, STRIP. Additional flags can be - passed to these executables with ASFLAGS, CFLAGS, CXXFLAGS, and LDFLAGS. - - 6. Configuration errors - If the configuration step fails, the first step is to look in the error log. - This defaults to config.log. This should give a good indication of what went - wrong. If not, contact us for support. - -VP8/VP9 TEST VECTORS: - The test vectors can be downloaded and verified using the build system after - running configure. To specify an alternate directory the - LIBVPX_TEST_DATA_PATH environment variable can be used. - - $ ./configure --enable-unit-tests - $ LIBVPX_TEST_DATA_PATH=../libvpx-test-data make testdata - -CODE STYLE: - The coding style used by this project is enforced with clang-format using the - configuration contained in the .clang-format file in the root of the - repository. - - Before pushing changes for review you can format your code with: - # Apply clang-format to modified .c, .h and .cc files - $ clang-format -i --style=file \ - $(git diff --name-only --diff-filter=ACMR '*.[hc]' '*.cc') - - Check the .clang-format file for the version used to generate it if there is - any difference between your local formatting and the review system. - - See also: http://clang.llvm.org/docs/ClangFormat.html - -PROFILE GUIDED OPTIMIZATION (PGO) - Profile Guided Optimization can be enabled for Clang builds using the - commands: - - $ export CC=clang - $ export CXX=clang++ - $ ../libvpx/configure --enable-profile - $ make - - Generate one or multiple PGO profile files by running vpxdec or vpxenc. For - example: - - $ ./vpxdec ../vpx/out_ful/vp90-2-sintel_1280x546_tile_1x4_1257kbps.webm \ - -o - > /dev/null - - To convert and merge the raw profile files, use the llvm-profdata tool: - - $ llvm-profdata merge -o perf.profdata default_8382761441159425451_0.profraw - - Then, rebuild the project with the new profile file: - - $ make clean - $ ../libvpx/configure --use-profile=perf.profdata - $ make - - Note: Always use the llvm-profdata from the toolchain that is used for - compiling the PGO-enabled binary. - - To observe the improvements from a PGO-enabled build, enable and compare the - list of failed optimizations by using the -Rpass-missed compiler flag. For - example, to list the failed loop vectorizations: - - $ ../libvpx/configure --use-profile=perf.profdata \ - --extra-cflags=-Rpass-missed=loop-vectorize - - For guidance on utilizing PGO files to identify potential optimization - opportunities, see: tools/README.pgo.md - -SUPPORT - This library is an open source project supported by its community. Please - email webm-discuss@webmproject.org for help. - -BUG REPORTS - Bug reports can be filed in the libvpx issue tracker: - https://issues.webmproject.org/. - For security reports, select 'Security report' from the Template dropdown. diff --git a/presentation/src/main/cpp/third_party/libvpx/args.c b/presentation/src/main/cpp/third_party/libvpx/args.c deleted file mode 100644 index 0fb87d99..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/args.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include "args.h" - -#include "vpx/vpx_integer.h" - -#if defined(__GNUC__) -__attribute__((noreturn)) extern void die(const char *fmt, ...); -#elif defined(_MSC_VER) -__declspec(noreturn) extern void die(const char *fmt, ...); -#else -extern void die(const char *fmt, ...); -#endif - -struct arg arg_init(char **argv) { - struct arg a; - - a.argv = argv; - a.argv_step = 1; - a.name = NULL; - a.val = NULL; - a.def = NULL; - return a; -} - -int arg_match(struct arg *arg_, const struct arg_def *def, char **argv) { - struct arg arg; - - if (!argv[0] || argv[0][0] != '-') return 0; - - arg = arg_init(argv); - - if (def->short_name && strlen(arg.argv[0]) == strlen(def->short_name) + 1 && - !strcmp(arg.argv[0] + 1, def->short_name)) { - arg.name = arg.argv[0] + 1; - arg.val = def->has_val ? arg.argv[1] : NULL; - arg.argv_step = def->has_val ? 2 : 1; - } else if (def->long_name) { - const size_t name_len = strlen(def->long_name); - - if (strlen(arg.argv[0]) >= name_len + 2 && arg.argv[0][1] == '-' && - !strncmp(arg.argv[0] + 2, def->long_name, name_len) && - (arg.argv[0][name_len + 2] == '=' || - arg.argv[0][name_len + 2] == '\0')) { - arg.name = arg.argv[0] + 2; - arg.val = arg.name[name_len] == '=' ? arg.name + name_len + 1 : NULL; - arg.argv_step = 1; - } - } - - if (arg.name && !arg.val && def->has_val) - die("Error: option %s requires argument.\n", arg.name); - - if (arg.name && arg.val && !def->has_val) - die("Error: option %s requires no argument.\n", arg.name); - - if (arg.name && (arg.val || !def->has_val)) { - arg.def = def; - *arg_ = arg; - return 1; - } - - return 0; -} - -const char *arg_next(struct arg *arg) { - if (arg->argv[0]) arg->argv += arg->argv_step; - - return *arg->argv; -} - -char **argv_dup(int argc, const char **argv) { - char **new_argv = malloc((argc + 1) * sizeof(*argv)); - if (!new_argv) return NULL; - - memcpy(new_argv, argv, argc * sizeof(*argv)); - new_argv[argc] = NULL; - return new_argv; -} - -void arg_show_usage(FILE *fp, const struct arg_def *const *defs) { - char option_text[40] = { 0 }; - - for (; *defs; defs++) { - const struct arg_def *def = *defs; - char *short_val = def->has_val ? " " : ""; - char *long_val = def->has_val ? "=" : ""; - - if (def->short_name && def->long_name) { - char *comma = def->has_val ? "," : ", "; - - snprintf(option_text, 37, "-%s%s%s --%s%6s", def->short_name, short_val, - comma, def->long_name, long_val); - } else if (def->short_name) - snprintf(option_text, 37, "-%s%s", def->short_name, short_val); - else if (def->long_name) - snprintf(option_text, 37, " --%s%s", def->long_name, long_val); - - fprintf(fp, " %-37s\t%s\n", option_text, def->desc); - - if (def->enums) { - const struct arg_enum_list *listptr; - - fprintf(fp, " %-37s\t ", ""); - - for (listptr = def->enums; listptr->name; listptr++) - fprintf(fp, "%s%s", listptr->name, listptr[1].name ? ", " : "\n"); - } - } -} - -unsigned int arg_parse_uint(const struct arg *arg) { - uint32_t rawval; - char *endptr; - - rawval = (uint32_t)strtoul(arg->val, &endptr, 10); - - if (arg->val[0] != '\0' && endptr[0] == '\0') { - if (rawval <= UINT_MAX) return rawval; - - die("Option %s: Value %ld out of range for unsigned int\n", arg->name, - rawval); - } - - die("Option %s: Invalid character '%c'\n", arg->name, *endptr); -} - -int arg_parse_int(const struct arg *arg) { - int32_t rawval; - char *endptr; - - rawval = (int32_t)strtol(arg->val, &endptr, 10); - - if (arg->val[0] != '\0' && endptr[0] == '\0') { - if (rawval >= INT_MIN && rawval <= INT_MAX) return (int)rawval; - - die("Option %s: Value %ld out of range for signed int\n", arg->name, - rawval); - } - - die("Option %s: Invalid character '%c'\n", arg->name, *endptr); -} - -struct vpx_rational { - int num; /**< fraction numerator */ - int den; /**< fraction denominator */ -}; -struct vpx_rational arg_parse_rational(const struct arg *arg) { - long int rawval; - char *endptr; - struct vpx_rational rat; - - /* parse numerator */ - rawval = strtol(arg->val, &endptr, 10); - - if (arg->val[0] != '\0' && endptr[0] == '/') { - if (rawval >= INT_MIN && rawval <= INT_MAX) - rat.num = (int)rawval; - else - die("Option %s: Value %ld out of range for signed int\n", arg->name, - rawval); - } else - die("Option %s: Expected / at '%c'\n", arg->name, *endptr); - - /* parse denominator */ - rawval = strtol(endptr + 1, &endptr, 10); - - if (arg->val[0] != '\0' && endptr[0] == '\0') { - if (rawval >= INT_MIN && rawval <= INT_MAX) - rat.den = (int)rawval; - else - die("Option %s: Value %ld out of range for signed int\n", arg->name, - rawval); - } else - die("Option %s: Invalid character '%c'\n", arg->name, *endptr); - - return rat; -} - -int arg_parse_enum(const struct arg *arg) { - const struct arg_enum_list *listptr; - long int rawval; - char *endptr; - - /* First see if the value can be parsed as a raw value */ - rawval = strtol(arg->val, &endptr, 10); - if (arg->val[0] != '\0' && endptr[0] == '\0') { - /* Got a raw value, make sure it's valid */ - for (listptr = arg->def->enums; listptr->name; listptr++) - if (listptr->val == rawval) return (int)rawval; - } - - /* Next see if it can be parsed as a string */ - for (listptr = arg->def->enums; listptr->name; listptr++) - if (!strcmp(arg->val, listptr->name)) return listptr->val; - - die("Option %s: Invalid value '%s'\n", arg->name, arg->val); -} - -int arg_parse_enum_or_int(const struct arg *arg) { - if (arg->def->enums) return arg_parse_enum(arg); - return arg_parse_int(arg); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/args.h b/presentation/src/main/cpp/third_party/libvpx/args.h deleted file mode 100644 index aae8ec06..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/args.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_ARGS_H_ -#define VPX_ARGS_H_ -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct arg { - char **argv; - const char *name; - const char *val; - unsigned int argv_step; - const struct arg_def *def; -}; - -struct arg_enum_list { - const char *name; - int val; -}; -#define ARG_ENUM_LIST_END \ - { 0 } - -typedef struct arg_def { - const char *short_name; - const char *long_name; - int has_val; - const char *desc; - const struct arg_enum_list *enums; -} arg_def_t; -#define ARG_DEF(s, l, v, d) \ - { s, l, v, d, NULL } -#define ARG_DEF_ENUM(s, l, v, d, e) \ - { s, l, v, d, e } -#define ARG_DEF_LIST_END \ - { 0 } - -struct arg arg_init(char **argv); -int arg_match(struct arg *arg_, const struct arg_def *def, char **argv); -const char *arg_next(struct arg *arg); -void arg_show_usage(FILE *fp, const struct arg_def *const *defs); -char **argv_dup(int argc, const char **argv); - -unsigned int arg_parse_uint(const struct arg *arg); -int arg_parse_int(const struct arg *arg); -struct vpx_rational arg_parse_rational(const struct arg *arg); -int arg_parse_enum(const struct arg *arg); -int arg_parse_enum_or_int(const struct arg *arg); -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_ARGS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/build/make/Android.mk b/presentation/src/main/cpp/third_party/libvpx/build/make/Android.mk deleted file mode 100644 index 533f43c1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build/make/Android.mk +++ /dev/null @@ -1,216 +0,0 @@ -## -## Copyright (c) 2012 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -# Ignore this file during non-NDK builds. -ifdef NDK_ROOT -# -# This file is to be used for compiling libvpx for Android using the NDK. -# In an Android project place a libvpx checkout in the jni directory. -# Run the configure script from the jni directory. Base libvpx -# encoder/decoder configuration will look similar to: -# ./libvpx/configure --target=arm64-android-gcc --disable-examples \ -# --enable-external-build -# -# This will create .mk files that contain variables that contain the -# source files to compile. -# -# Place an Android.mk file in the jni directory that references the -# Android.mk file in the libvpx directory: -# LOCAL_PATH := $(call my-dir) -# include $(CLEAR_VARS) -# include jni/libvpx/build/make/Android.mk -# -# By default libvpx will use the 'cpufeatures' module from the NDK. This allows -# the library to be built with all available optimizations (SSE2->AVX512 for -# x86, NEON for arm, DSPr2 for mips). This can be disabled with -# --disable-runtime-cpu-detect -# but the resulting library *must* be run on devices supporting all of the -# enabled extensions. They can be disabled individually with -# --disable-{sse2, sse3, ssse3, sse4_1, avx, avx2, avx512} -# --disable-neon{, -asm, -neon-dotprod, -neon-i8mm} -# --disable-sve -# --disable-{dspr2, msa} - -# -# Running ndk-build will build libvpx and include it in your project. Set -# APP_ABI to match the --target passed to configure: -# https://developer.android.com/ndk/guides/application_mk#app_abi. -# - -CONFIG_DIR := $(LOCAL_PATH)/ -LIBVPX_PATH := $(LOCAL_PATH)/libvpx -ASM_CNV_PATH_LOCAL := $(TARGET_ARCH_ABI)/ads2gas -ASM_CNV_PATH := $(LOCAL_PATH)/$(ASM_CNV_PATH_LOCAL) -ifneq ($(V),1) - qexec := @ -endif - -# Use the makefiles generated by upstream configure to determine which files to -# build. Also set any architecture-specific flags. -ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) - include $(CONFIG_DIR)libs-armv7-android-gcc.mk - LOCAL_ARM_MODE := arm -else ifeq ($(TARGET_ARCH_ABI),arm64-v8a) - include $(CONFIG_DIR)libs-arm64-android-gcc.mk - LOCAL_ARM_MODE := arm -else ifeq ($(TARGET_ARCH_ABI),x86) - include $(CONFIG_DIR)libs-x86-android-gcc.mk -else ifeq ($(TARGET_ARCH_ABI),x86_64) - include $(CONFIG_DIR)libs-x86_64-android-gcc.mk -else ifeq ($(TARGET_ARCH_ABI),mips) - include $(CONFIG_DIR)libs-mips-android-gcc.mk -else - $(error Not a supported TARGET_ARCH_ABI: $(TARGET_ARCH_ABI)) -endif - -# Rule that is normally in Makefile created by libvpx -# configure. Used to filter out source files based on configuration. -enabled=$(filter-out $($(1)-no),$($(1)-yes)) - -# Override the relative path that is defined by the libvpx -# configure process -SRC_PATH_BARE := $(LIBVPX_PATH) - -# Include the list of files to be built -include $(LIBVPX_PATH)/libs.mk - -# Optimise the code. May want to revisit this setting in the future. -LOCAL_CFLAGS := -O3 - -# For x86, include the source code in the search path so it will find files -# like x86inc.asm and x86_abi_support.asm -LOCAL_ASMFLAGS := -I$(LIBVPX_PATH) - -.PRECIOUS: %.asm.S -$(ASM_CNV_PATH)/libvpx/%.asm.S: $(LIBVPX_PATH)/%.asm - $(qexec)mkdir -p $(dir $@) - $(qexec)$(CONFIG_DIR)$(ASM_CONVERSION) <$< > $@ - -# For building *_rtcd.h, which have rules in libs.mk -TGT_ISA:=$(word 1, $(subst -, ,$(TOOLCHAIN))) -target := libs - -LOCAL_SRC_FILES += vpx_config.c - -# Remove duplicate entries -CODEC_SRCS_UNIQUE = $(sort $(CODEC_SRCS)) - -# Pull out C files. vpx_config.c is in the immediate directory and -# so it does not need libvpx/ prefixed like the rest of the source files. -# The neon files with intrinsics need to have .neon appended so the proper -# flags are applied. -CODEC_SRCS_C = $(filter %.c, $(CODEC_SRCS_UNIQUE)) -LOCAL_NEON_SRCS_C = $(filter %_neon.c, $(CODEC_SRCS_C)) -LOCAL_CODEC_SRCS_C = $(filter-out vpx_config.c %_neon.c, $(CODEC_SRCS_C)) - -LOCAL_SRC_FILES += $(foreach file, $(LOCAL_CODEC_SRCS_C), libvpx/$(file)) -ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) - LOCAL_SRC_FILES += $(foreach file, $(LOCAL_NEON_SRCS_C), libvpx/$(file).neon) -else # If there are neon sources then we are building for arm64 and do not need to specify .neon - LOCAL_SRC_FILES += $(foreach file, $(LOCAL_NEON_SRCS_C), libvpx/$(file)) -endif - -# Pull out assembly files, splitting NEON from the rest. This is -# done to specify that the NEON assembly files use NEON assembler flags. -# x86 assembly matches %.asm, arm matches %.asm.S - -# x86: - -CODEC_SRCS_ASM_X86 = $(filter %.asm, $(CODEC_SRCS_UNIQUE)) -LOCAL_SRC_FILES += $(foreach file, $(CODEC_SRCS_ASM_X86), libvpx/$(file)) - -# arm: -CODEC_SRCS_ASM_ARM_ALL = $(filter %.asm.S, $(CODEC_SRCS_UNIQUE)) -CODEC_SRCS_ASM_ARM = $(foreach v, \ - $(CODEC_SRCS_ASM_ARM_ALL), \ - $(if $(findstring neon,$(v)),,$(v))) -CODEC_SRCS_ASM_ADS2GAS = $(patsubst %.S, \ - $(ASM_CNV_PATH_LOCAL)/libvpx/%.S, \ - $(CODEC_SRCS_ASM_ARM)) -LOCAL_SRC_FILES += $(CODEC_SRCS_ASM_ADS2GAS) - -ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) - ASM_INCLUDES := vpx_dsp/arm/idct_neon.asm.S - CODEC_SRCS_ASM_NEON = $(foreach v, \ - $(CODEC_SRCS_ASM_ARM_ALL),\ - $(if $(findstring neon,$(v)),$(v),)) - CODEC_SRCS_ASM_NEON := $(filter-out $(addprefix %, $(ASM_INCLUDES)), \ - $(CODEC_SRCS_ASM_NEON)) - CODEC_SRCS_ASM_NEON_ADS2GAS = $(patsubst %.S, \ - $(ASM_CNV_PATH_LOCAL)/libvpx/%.S, \ - $(CODEC_SRCS_ASM_NEON)) - LOCAL_SRC_FILES += $(patsubst %.S, \ - %.S.neon, \ - $(CODEC_SRCS_ASM_NEON_ADS2GAS)) - - NEON_ASM_TARGETS = $(patsubst %.S, \ - $(ASM_CNV_PATH)/libvpx/%.S, \ - $(CODEC_SRCS_ASM_NEON)) -# add a dependency to the full path to the ads2gas output to ensure the -# includes are converted first. -ifneq ($(strip $(NEON_ASM_TARGETS)),) -$(NEON_ASM_TARGETS): $(addprefix $(ASM_CNV_PATH)/libvpx/, $(ASM_INCLUDES)) -endif -endif - -LOCAL_CFLAGS += \ - -DHAVE_CONFIG_H=vpx_config.h \ - -I$(LIBVPX_PATH) \ - -I$(ASM_CNV_PATH) \ - -I$(ASM_CNV_PATH)/libvpx - -LOCAL_MODULE := libvpx -LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../LICENSE $(LOCAL_PATH)/../../PATENTS - -ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes) - LOCAL_STATIC_LIBRARIES := cpufeatures -endif - -# Add a dependency to force generation of the RTCD files. -define rtcd_dep_template -rtcd_dep_template_SRCS := $(addprefix $(LOCAL_PATH)/, $(LOCAL_SRC_FILES)) -rtcd_dep_template_SRCS := $$(rtcd_dep_template_SRCS:.neon=) -ifeq ($(CONFIG_VP8), yes) -$$(rtcd_dep_template_SRCS): vp8_rtcd.h -endif -ifeq ($(CONFIG_VP9), yes) -$$(rtcd_dep_template_SRCS): vp9_rtcd.h -endif -$$(rtcd_dep_template_SRCS): vpx_scale_rtcd.h -$$(rtcd_dep_template_SRCS): vpx_dsp_rtcd.h - -rtcd_dep_template_CONFIG_ASM_ABIS := x86 x86_64 armeabi-v7a -ifneq ($$(findstring $(TARGET_ARCH_ABI),$$(rtcd_dep_template_CONFIG_ASM_ABIS)),) -$$(rtcd_dep_template_SRCS): vpx_config.asm -endif -endef - -$(eval $(call rtcd_dep_template)) - -.PHONY: clean -clean: - @echo "Clean: ads2gas files [$(TARGET_ARCH_ABI)]" - $(qexec)$(RM) $(CODEC_SRCS_ASM_ADS2GAS) $(CODEC_SRCS_ASM_NEON_ADS2GAS) - $(qexec)$(RM) -r $(ASM_CNV_PATH) - $(qexec)$(RM) $(CLEAN-OBJS) - -ifeq ($(ENABLE_SHARED),1) - LOCAL_CFLAGS += -fPIC - include $(BUILD_SHARED_LIBRARY) -else - include $(BUILD_STATIC_LIBRARY) -endif - -ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes) -$(call import-module,android/cpufeatures) -endif -endif # NDK_ROOT diff --git a/presentation/src/main/cpp/third_party/libvpx/build/make/Makefile b/presentation/src/main/cpp/third_party/libvpx/build/make/Makefile deleted file mode 100644 index 658b3761..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build/make/Makefile +++ /dev/null @@ -1,494 +0,0 @@ -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - - -include config.mk -quiet?=true -ifeq ($(target),) -# If a target wasn't specified, invoke for all enabled targets. -.DEFAULT: - @for t in $(ALL_TARGETS); do \ - $(MAKE) --no-print-directory target=$$t $(MAKECMDGOALS) || exit $$?;\ - done -all: .DEFAULT -clean:: .DEFAULT -exampletest: .DEFAULT -install:: .DEFAULT -test: .DEFAULT -test-no-data-check: .DEFAULT -testdata: .DEFAULT -utiltest: .DEFAULT -exampletest-no-data-check utiltest-no-data-check: .DEFAULT -test_%: .DEFAULT ; - -# Note: md5sum is not installed on OS X, but openssl is. Openssl may not be -# installed on cygwin, so we need to autodetect here. -md5sum := $(firstword $(wildcard \ - $(foreach e,md5sum openssl,\ - $(foreach p,$(subst :, ,$(PATH)),$(p)/$(e)*))\ - )) -md5sum := $(if $(filter %openssl,$(md5sum)),$(md5sum) dgst -md5,$(md5sum)) - -TGT_CC:=$(word 3, $(subst -, ,$(TOOLCHAIN))) -dist: - @for t in $(ALL_TARGETS); do \ - $(MAKE) --no-print-directory target=$$t $(MAKECMDGOALS) || exit $$?;\ - done - # Run configure for the user with the current toolchain. - @if [ -d "$(DIST_DIR)/src" ]; then \ - mkdir -p "$(DIST_DIR)/build"; \ - cd "$(DIST_DIR)/build"; \ - echo "Rerunning configure $(CONFIGURE_ARGS)"; \ - ../src/configure $(CONFIGURE_ARGS); \ - $(if $(filter vs%,$(TGT_CC)),make NO_LAUNCH_DEVENV=1;) \ - fi - @if [ -d "$(DIST_DIR)" ]; then \ - echo " [MD5SUM] $(DIST_DIR)"; \ - cd $(DIST_DIR) && \ - $(md5sum) `find . -name md5sums.txt -prune -o -type f -print` \ - | sed -e 's/MD5(\(.*\))= \([0-9a-f]\{32\}\)/\2 \1/' \ - > md5sums.txt;\ - fi -endif - -# Since we invoke make recursively for multiple targets we need to include the -# .mk file for the correct target, but only when $(target) is non-empty. -ifneq ($(target),) -include $(target)-$(TOOLCHAIN).mk -endif -BUILD_ROOT?=. -VPATH=$(SRC_PATH_BARE) -CFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT) -I$(SRC_PATH) -CXXFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT) -I$(SRC_PATH) -ASFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT)/ -I$(SRC_PATH)/ -DIST_DIR?=dist -HOSTCC?=gcc -TGT_ISA:=$(word 1, $(subst -, ,$(TOOLCHAIN))) -TGT_OS:=$(word 2, $(subst -, ,$(TOOLCHAIN))) -TGT_CC:=$(word 3, $(subst -, ,$(TOOLCHAIN))) -quiet:=$(if $(or $(verbose), $(V)),, yes) -qexec=$(if $(quiet),@) - -# Cancel built-in implicit rules -%: %.o -%.asm: -%.a: -%: %.cc - -# -# Common rules" -# -.PHONY: all -all: - -.PHONY: clean -clean:: - rm -f $(OBJS-yes) $(OBJS-yes:.o=.d) $(OBJS-yes:.asm.S.o=.asm.S) - rm -f $(CLEAN-OBJS) - -.PHONY: clean -distclean: clean - if [ -z "$(target)" ]; then \ - rm -f Makefile; \ - rm -f config.log config.mk; \ - rm -f vpx_config.[hc] vpx_config.asm; \ - rm -f arm_neon.h; \ - else \ - rm -f $(target)-$(TOOLCHAIN).mk; \ - fi - -.PHONY: dist -dist: -.PHONY: exampletest -exampletest: -.PHONY: install -install:: -.PHONY: test -test: -.PHONY: testdata -testdata: -.PHONY: utiltest -utiltest: -.PHONY: test-no-data-check exampletest-no-data-check utiltest-no-data-check -test-no-data-check: -exampletest-no-data-check utiltest-no-data-check: - -# Force to realign stack always on OS/2 -ifeq ($(TOOLCHAIN), x86-os2-gcc) -CFLAGS += -mstackrealign -endif - -# x86[_64] -$(BUILD_PFX)%_mmx.c.d: CFLAGS += -mmmx -$(BUILD_PFX)%_mmx.c.o: CFLAGS += -mmmx -$(BUILD_PFX)%_sse2.c.d: CFLAGS += -msse2 -$(BUILD_PFX)%_sse2.c.o: CFLAGS += -msse2 -$(BUILD_PFX)%_sse3.c.d: CFLAGS += -msse3 -$(BUILD_PFX)%_sse3.c.o: CFLAGS += -msse3 -$(BUILD_PFX)%_ssse3.c.d: CFLAGS += -mssse3 -$(BUILD_PFX)%_ssse3.c.o: CFLAGS += -mssse3 -$(BUILD_PFX)%_sse4.c.d: CFLAGS += -msse4.1 -$(BUILD_PFX)%_sse4.c.o: CFLAGS += -msse4.1 -$(BUILD_PFX)%_avx.c.d: CFLAGS += -mavx -$(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx -$(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2 -$(BUILD_PFX)%_avx2.c.o: CFLAGS += -mavx2 -$(BUILD_PFX)%_avx512.c.d: CFLAGS += -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl -$(BUILD_PFX)%_avx512.c.o: CFLAGS += -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl - -# AARCH64 -$(BUILD_PFX)%_neon_dotprod.c.d: CFLAGS += -march=armv8.2-a+dotprod -$(BUILD_PFX)%_neon_dotprod.c.o: CFLAGS += -march=armv8.2-a+dotprod -$(BUILD_PFX)%_neon_i8mm.c.d: CFLAGS += -march=armv8.2-a+dotprod+i8mm -$(BUILD_PFX)%_neon_i8mm.c.o: CFLAGS += -march=armv8.2-a+dotprod+i8mm -$(BUILD_PFX)%_sve.c.d: CFLAGS += -march=armv8.2-a+dotprod+i8mm+sve -$(BUILD_PFX)%_sve.c.o: CFLAGS += -march=armv8.2-a+dotprod+i8mm+sve -$(BUILD_PFX)%_sve2.c.d: CFLAGS += -march=armv9-a+sve2 -$(BUILD_PFX)%_sve2.c.o: CFLAGS += -march=armv9-a+sve2 - -# POWER -$(BUILD_PFX)%_vsx.c.d: CFLAGS += -maltivec -mvsx -$(BUILD_PFX)%_vsx.c.o: CFLAGS += -maltivec -mvsx - -# MIPS -$(BUILD_PFX)%_msa.c.d: CFLAGS += -mmsa -$(BUILD_PFX)%_msa.c.o: CFLAGS += -mmsa - -# LOONGARCH -$(BUILD_PFX)%_lsx.c.d: CFLAGS += -mlsx -$(BUILD_PFX)%_lsx.c.o: CFLAGS += -mlsx -$(BUILD_PFX)%_lasx.c.d: CFLAGS += -mlasx -$(BUILD_PFX)%_lasx.c.o: CFLAGS += -mlasx - -$(BUILD_PFX)%.c.d: %.c - $(if $(quiet),@echo " [DEP] $@") - $(qexec)mkdir -p $(dir $@) - $(qexec)$(CC) $(INTERNAL_CFLAGS) $(CFLAGS) -M $< | $(fmt_deps) > $@ - -$(BUILD_PFX)%.c.o: %.c - $(if $(quiet),@echo " [CC] $@") - $(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@)) - $(qexec)$(CC) $(INTERNAL_CFLAGS) $(CFLAGS) -c -o $@ $< - -$(BUILD_PFX)%.cc.d: %.cc - $(if $(quiet),@echo " [DEP] $@") - $(qexec)mkdir -p $(dir $@) - $(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -M $< | $(fmt_deps) > $@ - -$(BUILD_PFX)%.cc.o: %.cc - $(if $(quiet),@echo " [CXX] $@") - $(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@)) - $(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -c -o $@ $< - -$(BUILD_PFX)%.cpp.d: %.cpp - $(if $(quiet),@echo " [DEP] $@") - $(qexec)mkdir -p $(dir $@) - $(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -M $< | $(fmt_deps) > $@ - -$(BUILD_PFX)%.cpp.o: %.cpp - $(if $(quiet),@echo " [CXX] $@") - $(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@)) - $(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -c -o $@ $< - -$(BUILD_PFX)%.asm.d: %.asm - $(if $(quiet),@echo " [DEP] $@") - $(qexec)mkdir -p $(dir $@) - $(qexec)$(SRC_PATH_BARE)/build/make/gen_asm_deps.sh \ - --build-pfx=$(BUILD_PFX) --depfile=$@ $(ASFLAGS) $< > $@ - -$(BUILD_PFX)%.asm.o: %.asm - $(if $(quiet),@echo " [AS] $@") - $(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@)) - $(qexec)$(AS) $(ASFLAGS) -o $@ $< - -$(BUILD_PFX)%.S.d: %.S - $(if $(quiet),@echo " [DEP] $@") - $(qexec)mkdir -p $(dir $@) - $(qexec)$(SRC_PATH_BARE)/build/make/gen_asm_deps.sh \ - --build-pfx=$(BUILD_PFX) --depfile=$@ $(ASFLAGS) $< > $@ - -$(BUILD_PFX)%.S.o: %.S - $(if $(quiet),@echo " [AS] $@") - $(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@)) - $(qexec)$(AS) $(ASFLAGS) -o $@ $< - -.PRECIOUS: %.c.S -%.c.S: CFLAGS += -DINLINE_ASM -$(BUILD_PFX)%.c.S: %.c - $(if $(quiet),@echo " [GEN] $@") - $(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@)) - $(qexec)$(CC) -S $(CFLAGS) -o $@ $< - -.PRECIOUS: %.asm.S -$(BUILD_PFX)%.asm.S: %.asm - $(if $(quiet),@echo " [ASM CONVERSION] $@") - $(qexec)mkdir -p $(dir $@) - $(qexec)$(ASM_CONVERSION) <$< >$@ - -# If we're in debug mode, pretend we don't have GNU strip, to fall back to -# the copy implementation -HAVE_GNU_STRIP := $(if $(CONFIG_DEBUG),,$(HAVE_GNU_STRIP)) -ifeq ($(HAVE_GNU_STRIP),yes) -# Older binutils strip global symbols not needed for relocation processing -# when given --strip-unneeded. Using nm and awk to identify globals and -# keep them caused command line length issues under mingw and segfaults in -# test_libvpx were observed under OS/2: simply use --strip-debug. -%.a: %_g.a - $(if $(quiet),@echo " [STRIP] $@ < $<") - $(qexec)$(STRIP) --strip-debug \ - -o $@ $< -else -%.a: %_g.a - $(if $(quiet),@echo " [CP] $@ < $<") - $(qexec)cp $< $@ -endif - -# -# Utility functions -# -pairmap=$(if $(strip $(2)),\ - $(call $(1),$(word 1,$(2)),$(word 2,$(2)))\ - $(call pairmap,$(1),$(wordlist 3,$(words $(2)),$(2)))\ -) - -enabled=$(filter-out $($(1)-no),$($(1)-yes)) -cond_enabled=$(if $(filter yes,$($(1))), $(call enabled,$(2))) - -find_file1=$(word 1,$(wildcard $(subst //,/,$(addsuffix /$(1),$(2))))) -find_file=$(foreach f,$(1),$(call find_file1,$(strip $(f)),$(strip $(2))) ) -obj_pats=.c=.c.o $(AS_SFX)=$(AS_SFX).o .cc=.cc.o .cpp=.cpp.o -objs=$(addprefix $(BUILD_PFX),$(foreach p,$(obj_pats),$(filter %.o,$(1:$(p))) )) - -install_map_templates=$(eval $(call install_map_template,$(1),$(2))) - -not=$(subst yes,no,$(1)) - -ifeq ($(CONFIG_MSVS),yes) -lib_file_name=$(1).lib -else -lib_file_name=lib$(1).a -endif -# -# Rule Templates -# -define linker_template -$(1): $(filter-out -%,$(2)) -$(1): - $(if $(quiet),@echo " [LD] $$@") - $(qexec)$$(LD) $$(strip $$(INTERNAL_LDFLAGS) $$(LDFLAGS) -o $$@ $(2) $(3) $$(extralibs)) -endef -define linkerxx_template -$(1): $(filter-out -%,$(2)) -$(1): - $(if $(quiet),@echo " [LD] $$@") - $(qexec)$$(CXX) $$(strip $$(INTERNAL_LDFLAGS) $$(LDFLAGS) -o $$@ $(2) $(3) $$(extralibs)) -endef -# make-3.80 has a bug with expanding large input strings to the eval function, -# which was triggered in some cases by the following component of -# linker_template: -# $(1): $$(call find_file, $(patsubst -l%,lib%.a,$(filter -l%,$(2))),\ -# $$(patsubst -L%,%,$$(filter -L%,$$(LDFLAGS) $(2)))) -# This may be useful to revisit in the future (it tries to locate libraries -# in a search path and add them as prerequisites - -define install_map_template -$(DIST_DIR)/$(1): $(2) - $(if $(quiet),@echo " [INSTALL] $$@") - $(qexec)mkdir -p $$(dir $$@) - $(qexec)cp -p $$< $$@ -endef - -define archive_template -# Not using a pattern rule here because we don't want to generate empty -# archives when they are listed as a dependency in files not responsible -# for creating them. -$(1): - $(if $(quiet),@echo " [AR] $$@") - $(qexec)$$(AR) $$(ARFLAGS) $$@ $$^ -endef - -# Don't use -Wl,-z,defs with Clang's sanitizers. -# -# Clang's AddressSanitizer documentation says "When linking shared libraries, -# the AddressSanitizer run-time is not linked, so -Wl,-z,defs may cause link -# errors (don't use it with AddressSanitizer)." See -# https://clang.llvm.org/docs/AddressSanitizer.html#usage. -NO_UNDEFINED := -Wl,-z,defs -ifeq ($(findstring clang,$(CC)),clang) - ifneq ($(filter -fsanitize=%,$(LDFLAGS)),) - NO_UNDEFINED := - endif -endif - -define so_template -# Not using a pattern rule here because we don't want to generate empty -# archives when they are listed as a dependency in files not responsible -# for creating them. -# -# This needs further abstraction for dealing with non-GNU linkers. -$(1): - $(if $(quiet),@echo " [LD] $$@") - $(qexec)$$(LD) -shared $$(LDFLAGS) \ - $(NO_UNDEFINED) \ - -Wl,-soname,$$(SONAME) \ - -Wl,--version-script,$$(EXPORTS_FILE) -o $$@ \ - $$(filter %.o,$$^) $$(extralibs) -endef - -define dl_template -# Not using a pattern rule here because we don't want to generate empty -# archives when they are listed as a dependency in files not responsible -# for creating them. -$(1): - $(if $(quiet),@echo " [LD] $$@") - $(qexec)$$(LD) -dynamiclib $$(LDFLAGS) \ - -exported_symbols_list $$(EXPORTS_FILE) \ - -Wl,-headerpad_max_install_names,-compatibility_version,1.0,-current_version,$$(VERSION_MAJOR) \ - -o $$@ \ - $$(filter %.o,$$^) $$(extralibs) -endef - -define dll_template -# Not using a pattern rule here because we don't want to generate empty -# archives when they are listed as a dependency in files not responsible -# for creating them. -$(1): - $(if $(quiet),@echo " [LD] $$@") - $(qexec)$$(LD) -Zdll $$(LDFLAGS) \ - -o $$@ \ - $$(filter %.o,$$^) $$(extralibs) $$(EXPORTS_FILE) -endef - - -# -# Get current configuration -# -ifneq ($(target),) -include $(SRC_PATH_BARE)/$(target:-$(TOOLCHAIN)=).mk -endif - -skip_deps := $(filter %clean,$(MAKECMDGOALS)) -skip_deps += $(findstring testdata,$(MAKECMDGOALS)) -ifeq ($(strip $(skip_deps)),) - ifeq ($(CONFIG_DEPENDENCY_TRACKING),yes) - # Older versions of make don't like -include directives with no arguments - ifneq ($(filter %.d,$(OBJS-yes:.o=.d)),) - -include $(filter %.d,$(OBJS-yes:.o=.d)) - endif - endif -endif - -# -# Configuration dependent rules -# -$(call pairmap,install_map_templates,$(INSTALL_MAPS)) - -DOCS=$(call cond_enabled,CONFIG_INSTALL_DOCS,DOCS) -.docs: $(DOCS) - @touch $@ - -INSTALL-DOCS=$(call cond_enabled,CONFIG_INSTALL_DOCS,INSTALL-DOCS) -ifeq ($(MAKECMDGOALS),dist) -INSTALL-DOCS+=$(call cond_enabled,CONFIG_INSTALL_DOCS,DIST-DOCS) -endif -.install-docs: .docs $(addprefix $(DIST_DIR)/,$(INSTALL-DOCS)) - @touch $@ - -clean:: - rm -f .docs .install-docs $(DOCS) - -BINS=$(call enabled,BINS) -.bins: $(BINS) - @touch $@ - -INSTALL-BINS=$(call cond_enabled,CONFIG_INSTALL_BINS,INSTALL-BINS) -ifeq ($(MAKECMDGOALS),dist) -INSTALL-BINS+=$(call cond_enabled,CONFIG_INSTALL_BINS,DIST-BINS) -endif -.install-bins: .bins $(addprefix $(DIST_DIR)/,$(INSTALL-BINS)) - @touch $@ - -clean:: - rm -f .bins .install-bins $(BINS) - -LIBS=$(call enabled,LIBS) -.libs: $(LIBS) - @touch $@ -$(foreach lib,$(filter %_g.a,$(LIBS)),$(eval $(call archive_template,$(lib)))) -$(foreach lib,$(filter %so.$(SO_VERSION_MAJOR).$(SO_VERSION_MINOR).$(SO_VERSION_PATCH),$(LIBS)),$(eval $(call so_template,$(lib)))) -$(foreach lib,$(filter %$(SO_VERSION_MAJOR).dylib,$(LIBS)),$(eval $(call dl_template,$(lib)))) -$(foreach lib,$(filter %$(SO_VERSION_MAJOR).dll,$(LIBS)),$(eval $(call dll_template,$(lib)))) - -INSTALL-LIBS=$(call cond_enabled,CONFIG_INSTALL_LIBS,INSTALL-LIBS) -ifeq ($(MAKECMDGOALS),dist) -INSTALL-LIBS+=$(call cond_enabled,CONFIG_INSTALL_LIBS,DIST-LIBS) -endif -.install-libs: .libs $(addprefix $(DIST_DIR)/,$(INSTALL-LIBS)) - @touch $@ - -clean:: - rm -f .libs .install-libs $(LIBS) - -ifeq ($(CONFIG_EXTERNAL_BUILD),yes) -PROJECTS=$(call enabled,PROJECTS) -.projects: $(PROJECTS) - @touch $@ - -INSTALL-PROJECTS=$(call cond_enabled,CONFIG_INSTALL_PROJECTS,INSTALL-PROJECTS) -ifeq ($(MAKECMDGOALS),dist) -INSTALL-PROJECTS+=$(call cond_enabled,CONFIG_INSTALL_PROJECTS,DIST-PROJECTS) -endif -.install-projects: .projects $(addprefix $(DIST_DIR)/,$(INSTALL-PROJECTS)) - @touch $@ - -clean:: - rm -f .projects .install-projects $(PROJECTS) -endif - -# If there are any source files to be distributed, then include the build -# system too. -ifneq ($(call enabled,DIST-SRCS),) - DIST-SRCS-yes += configure - DIST-SRCS-yes += build/make/configure.sh - DIST-SRCS-yes += build/make/gen_asm_deps.sh - DIST-SRCS-yes += build/make/Makefile - DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_def.sh - DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_sln.sh - DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_vcxproj.sh - DIST-SRCS-$(CONFIG_MSVS) += build/make/msvs_common.sh - DIST-SRCS-$(CONFIG_RVCT) += build/make/armlink_adapter.sh - DIST-SRCS-$(VPX_ARCH_ARM) += build/make/ads2gas.pl - DIST-SRCS-$(VPX_ARCH_ARM) += build/make/ads2gas_apple.pl - DIST-SRCS-$(VPX_ARCH_ARM) += build/make/ads2armasm_ms.pl - DIST-SRCS-$(VPX_ARCH_ARM) += build/make/thumb.pm - DIST-SRCS-yes += $(target:-$(TOOLCHAIN)=).mk -endif -INSTALL-SRCS := $(call cond_enabled,CONFIG_INSTALL_SRCS,INSTALL-SRCS) -ifeq ($(MAKECMDGOALS),dist) -INSTALL-SRCS += $(call cond_enabled,CONFIG_INSTALL_SRCS,DIST-SRCS) -endif -.install-srcs: $(addprefix $(DIST_DIR)/src/,$(INSTALL-SRCS)) - @touch $@ - -clean:: - rm -f .install-srcs - -ifeq ($(CONFIG_EXTERNAL_BUILD),yes) - BUILD_TARGETS += .projects - INSTALL_TARGETS += .install-projects -endif -BUILD_TARGETS += .docs .libs .bins -INSTALL_TARGETS += .install-docs .install-srcs .install-libs .install-bins -all: $(BUILD_TARGETS) -install:: $(INSTALL_TARGETS) -dist: $(INSTALL_TARGETS) -test: - -.SUFFIXES: # Delete default suffix rules diff --git a/presentation/src/main/cpp/third_party/libvpx/build/make/ads2armasm_ms.pl b/presentation/src/main/cpp/third_party/libvpx/build/make/ads2armasm_ms.pl deleted file mode 100644 index dd4e0318..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build/make/ads2armasm_ms.pl +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env perl -## -## Copyright (c) 2013 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -use FindBin; -use lib $FindBin::Bin; -use thumb; - -print "; This file was created from a .asm file\n"; -print "; using the ads2armasm_ms.pl script.\n"; - -while () -{ - undef $comment; - undef $line; - - s/REQUIRE8//; - s/PRESERVE8//; - s/^\s*ARM\s*$//; - s/AREA\s+\|\|(.*)\|\|/AREA |$1|/; - s/qsubaddx/qsax/i; - s/qaddsubx/qasx/i; - - thumb::FixThumbInstructions($_); - - s/ldrneb/ldrbne/i; - s/ldrneh/ldrhne/i; - s/^(\s*)ENDP.*/$&\n$1ALIGN 4/; - - print; -} - diff --git a/presentation/src/main/cpp/third_party/libvpx/build/make/ads2gas.pl b/presentation/src/main/cpp/third_party/libvpx/build/make/ads2gas.pl deleted file mode 100644 index c301b7f8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build/make/ads2gas.pl +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/env perl -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - - -# ads2gas.pl -# Author: Eric Fung (efung (at) acm.org) -# -# Convert ARM Developer Suite 1.0.1 syntax assembly source to GNU as format -# -# Usage: cat inputfile | perl ads2gas.pl > outputfile -# - -use FindBin; -use lib $FindBin::Bin; -use thumb; - -my $thumb = 0; -my $elf = 1; - -foreach my $arg (@ARGV) { - $thumb = 1 if ($arg eq "-thumb"); - $elf = 0 if ($arg eq "-noelf"); -} - -print "@ This file was created from a .asm file\n"; -print "@ using the ads2gas.pl script.\n"; -print ".syntax unified\n"; -if ($thumb) { - print "\t.thumb\n"; -} - -# Stack of procedure names. -@proc_stack = (); - -while () -{ - # Load and store alignment - s/@/,:/g; - - # Comment character - s/;/@/; - - # Convert ELSE to .else - s/\bELSE\b/.else/g; - - # Convert ENDIF to .endif - s/\bENDIF\b/.endif/g; - - # Convert IF to .if - if (s/\bIF\b/.if/g) { - s/=+/==/g; - } - - # Convert INCLUDE to .INCLUDE "file" - s/INCLUDE\s?(.*)$/.include \"$1\"/; - - # No AREA required - # But ALIGNs in AREA must be obeyed - s/^(\s*)\bAREA\b.*ALIGN=([0-9])$/$1.text\n$1.p2align $2/; - # If no ALIGN, strip the AREA and align to 4 bytes - s/^(\s*)\bAREA\b.*$/$1.text\n$1.p2align 2/; - - # Make function visible to linker. - if ($elf) { - s/(\s*)EXPORT\s+\|([\$\w]*)\|/$1.global $2\n$1.type $2, function/; - } else { - s/(\s*)EXPORT\s+\|([\$\w]*)\|/$1.global $2/; - } - - # No vertical bars on function names - s/^\|(\$?\w+)\|/$1/g; - - # Labels need trailing colon - s/^([a-zA-Z_0-9\$]+)/$1:/ if !/EQU/; - - # ALIGN directive - s/\bALIGN\b/.balign/g; - - if ($thumb) { - # ARM code - we force everything to thumb with the declaration in the - # header - s/\bARM\b//g; - } else { - # ARM code - s/\bARM\b/.arm/g; - } - - # push/pop - s/(push\s+)(r\d+)/stmdb sp\!, \{$2\}/g; - s/(pop\s+)(r\d+)/ldmia sp\!, \{$2\}/g; - - if ($thumb) { - thumb::FixThumbInstructions($_); - } - - # eabi_attributes numerical equivalents can be found in the - # "ARM IHI 0045C" document. - - if ($elf) { - # REQUIRE8 Stack is required to be 8-byte aligned - s/\bREQUIRE8\b/.eabi_attribute 24, 1 \@Tag_ABI_align_needed/g; - - # PRESERVE8 Stack 8-byte align is preserved - s/\bPRESERVE8\b/.eabi_attribute 25, 1 \@Tag_ABI_align_preserved/g; - } else { - s/\bREQUIRE8\b//; - s/\bPRESERVE8\b//; - } - - # Use PROC and ENDP to give the symbols a .size directive. - # This makes them show up properly in debugging tools like gdb and valgrind. - if (/\bPROC\b/) { - my $proc; - # Match the function name so it can be stored in $proc - /^([\.0-9A-Z_a-z]\w+)\b/; - $proc = $1; - push(@proc_stack, $proc) if ($proc); - s/\bPROC\b/@ $&/; - } - - if (/\bENDP\b/) { - my $proc; - s/\bENDP\b/@ $&/; - $proc = pop(@proc_stack); - $_ = ".size $proc, .-$proc".$_ if ($proc and $elf); - } - - # EQU directive - s/(\S+\s+)EQU(\s+\S+)/.equ $1, $2/; - - # Begin macro definition - if (/\bMACRO\b/) { - # Process next line down, which will be the macro definition - $_ = ; - s/^/.macro/; - s/\$//g; # Remove $ from the variables in the declaration - } - - s/\$/\\/g; # Use \ to reference formal parameters - # End macro definition - - s/\bMEND\b/.endm/; # No need to tell it where to stop assembling - next if /^\s*END\s*$/; - s/[ \t]+$//; - print; -} - -# Mark that this object doesn't need an executable stack. -printf (" .section .note.GNU-stack,\"\",\%\%progbits\n") if $elf; diff --git a/presentation/src/main/cpp/third_party/libvpx/build/make/ads2gas_apple.pl b/presentation/src/main/cpp/third_party/libvpx/build/make/ads2gas_apple.pl deleted file mode 100644 index 62491c19..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build/make/ads2gas_apple.pl +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env perl -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - - -# ads2gas_apple.pl -# Author: Eric Fung (efung (at) acm.org) -# -# Convert ARM Developer Suite 1.0.1 syntax assembly source to GNU as format -# -# Usage: cat inputfile | perl ads2gas_apple.pl > outputfile -# - -print "@ This file was created from a .asm file\n"; -print "@ using the ads2gas_apple.pl script.\n\n"; -print ".syntax unified\n"; - -my %macro_aliases; - -my @mapping_list = ("\$0", "\$1", "\$2", "\$3", "\$4", "\$5", "\$6", "\$7", "\$8", "\$9"); - -my @incoming_array; - -# Perl trim function to remove whitespace from the start and end of the string -sub trim($) -{ - my $string = shift; - $string =~ s/^\s+//; - $string =~ s/\s+$//; - return $string; -} - -while () -{ - # Load and store alignment - s/@/,:/g; - - # Comment character - s/;/@/; - - # Convert ELSE to .else - s/\bELSE\b/.else/g; - - # Convert ENDIF to .endif - s/\bENDIF\b/.endif/g; - - # Convert IF to .if - if (s/\bIF\b/.if/g) { - s/=+/==/g; - } - - # Convert INCLUDE to .INCLUDE "file" - s/INCLUDE\s?(.*)$/.include \"$1\"/; - - # No AREA required - # But ALIGNs in AREA must be obeyed - s/^(\s*)\bAREA\b.*ALIGN=([0-9])$/$1.text\n$1.p2align $2/; - # If no ALIGN, strip the AREA and align to 4 bytes - s/^(\s*)\bAREA\b.*$/$1.text\n$1.p2align 2/; - - # Make function visible to linker. - s/EXPORT\s+\|([\$\w]*)\|/.globl _$1/; - - # No vertical bars on function names - s/^\|(\$?\w+)\|/$1/g; - - # Labels and functions need a leading underscore and trailing colon - s/^([a-zA-Z_0-9\$]+)/_$1:/ if !/EQU/; - - # Branches need to call the correct, underscored, function - s/^(\s+b[egln]?[teq]?\s+)([a-zA-Z_0-9\$]+)/$1 _$2/ if !/EQU/; - - # ALIGN directive - s/\bALIGN\b/.balign/g; - - # Strip ARM - s/\s+ARM//; - - # Strip REQUIRE8 - s/\s+REQUIRE8//; - - # Strip PRESERVE8 - s/\s+PRESERVE8//; - - # Strip PROC and ENDPROC - s/\bPROC\b//g; - s/\bENDP\b//g; - - # EQU directive - s/(\S+\s+)EQU(\s+\S+)/.equ $1, $2/; - - # Begin macro definition - if (/\bMACRO\b/) { - # Process next line down, which will be the macro definition - $_ = ; - s/^/.macro/; - s/\$//g; # Remove $ from the variables in the declaration - } - - s/\$/\\/g; # Use \ to reference formal parameters - # End macro definition - - s/\bMEND\b/.endm/; # No need to tell it where to stop assembling - next if /^\s*END\s*$/; - s/[ \t]+$//; - print; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/build/make/armlink_adapter.sh b/presentation/src/main/cpp/third_party/libvpx/build/make/armlink_adapter.sh deleted file mode 100644 index 75c342e9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build/make/armlink_adapter.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - - -verbose=0 -set -- $* -for i; do - if [ "$i" = "-o" ]; then - on_of=1 - elif [ "$i" = "-v" ]; then - verbose=1 - elif [ "$i" = "-g" ]; then - args="${args} --debug" - elif [ "$on_of" = "1" ]; then - outfile=$i - on_of=0 - elif [ -f "$i" ]; then - infiles="$infiles $i" - elif [ "${i#-l}" != "$i" ]; then - libs="$libs ${i#-l}" - elif [ "${i#-L}" != "$i" ]; then - libpaths="${libpaths} ${i#-L}" - else - args="${args} ${i}" - fi - shift -done - -# Absolutize library file names -for f in $libs; do - found=0 - for d in $libpaths; do - [ -f "$d/$f" ] && infiles="$infiles $d/$f" && found=1 && break - [ -f "$d/lib${f}.so" ] && infiles="$infiles $d/lib${f}.so" && found=1 && break - [ -f "$d/lib${f}.a" ] && infiles="$infiles $d/lib${f}.a" && found=1 && break - done - [ $found -eq 0 ] && infiles="$infiles $f" -done -for d in $libpaths; do - [ -n "$libsearchpath" ] && libsearchpath="${libsearchpath}," - libsearchpath="${libsearchpath}$d" -done - -cmd="armlink $args --userlibpath=$libsearchpath --output=$outfile $infiles" -[ $verbose -eq 1 ] && echo $cmd -$cmd diff --git a/presentation/src/main/cpp/third_party/libvpx/build/make/configure.sh b/presentation/src/main/cpp/third_party/libvpx/build/make/configure.sh deleted file mode 100644 index cc5bf6ce..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build/make/configure.sh +++ /dev/null @@ -1,1781 +0,0 @@ -#!/bin/sh -## -## configure.sh -## -## This script is sourced by the main configure script and contains -## utility functions and other common bits that aren't strictly libvpx -## related. -## -## This build system is based in part on the FFmpeg configure script. -## - - -# -# Logging / Output Functions -# -die_unknown(){ - echo "Unknown option \"$1\"." - echo "See $0 --help for available options." - clean_temp_files - exit 1 -} - -die() { - echo "$@" - echo - echo "Configuration failed. This could reflect a misconfiguration of your" - echo "toolchains, improper options selected, or another problem. If you" - echo "don't see any useful error messages above, the next step is to look" - echo "at the configure error log file ($logfile) to determine what" - echo "configure was trying to do when it died." - clean_temp_files - exit 1 -} - -log(){ - echo "$@" >>$logfile -} - -log_file(){ - log BEGIN $1 - cat -n $1 >>$logfile - log END $1 -} - -log_echo() { - echo "$@" - log "$@" -} - -fwrite () { - outfile=$1 - shift - echo "$@" >> ${outfile} -} - -show_help_pre(){ - for opt in ${CMDLINE_SELECT}; do - opt2=`echo $opt | sed -e 's;_;-;g'` - if enabled $opt; then - eval "toggle_${opt}=\"--disable-${opt2}\"" - else - eval "toggle_${opt}=\"--enable-${opt2} \"" - fi - done - - cat <>${logfile} 2>&1 -} - -check_cc() { - log check_cc "$@" - cat >${TMP_C} - log_file ${TMP_C} - check_cmd ${CC} ${CFLAGS} "$@" -c -o ${TMP_O} ${TMP_C} -} - -check_cxx() { - log check_cxx "$@" - cat >${TMP_CC} - log_file ${TMP_CC} - check_cmd ${CXX} ${CXXFLAGS} "$@" -c -o ${TMP_O} ${TMP_CC} -} - -check_cpp() { - log check_cpp "$@" - cat > ${TMP_C} - log_file ${TMP_C} - check_cmd ${CC} ${CFLAGS} "$@" -E -o ${TMP_O} ${TMP_C} -} - -check_ld() { - log check_ld "$@" - check_cc $@ \ - && check_cmd ${LD} ${LDFLAGS} "$@" -o ${TMP_X} ${TMP_O} ${extralibs} -} - -check_lib() { - log check_lib "$@" - check_cc $@ \ - && check_cmd ${LD} ${LDFLAGS} -o ${TMP_X} ${TMP_O} "$@" ${extralibs} -} - -check_header(){ - log check_header "$@" - header=$1 - shift - var=`echo $header | sed 's/[^A-Za-z0-9_]/_/g'` - disable_feature $var - check_cpp "$@" <${TMP_ASM} <${TMP_X} - log_file ${TMP_X} - if ! grep -q '\.rodata .* 16$' ${TMP_X}; then - die "${AS} ${ASFLAGS} does not support section alignment (nasm <=2.08?)" - fi -} - -# tests for -m$1 toggling the feature given in $2. If $2 is empty $1 is used. -check_gcc_machine_option() { - opt="$1" - feature="$2" - [ -n "$feature" ] || feature="$opt" - - if enabled gcc && ! disabled "$feature" && ! check_cflags "-m$opt"; then - RTCD_OPTIONS="${RTCD_OPTIONS}--disable-$feature " - else - soft_enable "$feature" - fi -} - -# tests for -m$2, -m$3, -m$4... toggling the feature given in $1. -check_gcc_machine_options() { - feature="$1" - shift - flags="-m$1" - shift - for opt in $*; do - flags="$flags -m$opt" - done - - if enabled gcc && ! disabled "$feature" && ! check_cflags $flags; then - RTCD_OPTIONS="${RTCD_OPTIONS}--disable-$feature " - else - soft_enable "$feature" - fi -} - -check_neon_sve_bridge_compiles() { - if enabled sve; then - check_cc -march=armv8.2-a+dotprod+i8mm+sve < -#include -EOF - compile_result=$? - if [ ${compile_result} -eq 0 ]; then - # Check whether the compiler can compile SVE functions that require - # backup/restore of SVE registers according to AAPCS. Clang for Windows - # used to fail this, see - # https://github.com/llvm/llvm-project/issues/80009. - check_cc -march=armv8.2-a+dotprod+i8mm+sve < -void other(void); -svfloat32_t func(svfloat32_t a) { - other(); - return a; -} -EOF - compile_result=$? - fi - - if [ ${compile_result} -ne 0 ]; then - log_echo " disabling sve: arm_neon_sve_bridge.h not supported by compiler" - log_echo " disabling sve2: arm_neon_sve_bridge.h not supported by compiler" - disable_feature sve - disable_feature sve2 - RTCD_OPTIONS="${RTCD_OPTIONS}--disable-sve --disable-sve2 " - fi - fi -} - -check_gcc_avx512_compiles() { - if disabled gcc; then - return - fi - - check_cc -mavx512f < -void f(void) { - __m512i x = _mm512_set1_epi16(0); - (void)x; -} -EOF - compile_result=$? - if [ ${compile_result} -ne 0 ]; then - log_echo " disabling avx512: not supported by compiler" - disable_feature avx512 - RTCD_OPTIONS="${RTCD_OPTIONS}--disable-avx512 " - fi -} - -check_inline_asm() { - log check_inline_asm "$@" - name="$1" - code="$2" - shift 2 - disable_feature $name - check_cc "$@" <> config.mk - echo "TOOLCHAIN := ${toolchain}" >> config.mk - - case ${toolchain} in - *-linux-rvct) - echo "ALT_LIBC := ${alt_libc}" >> config.mk - ;; - esac -} - -write_common_config_targets() { - for t in ${all_targets}; do - if enabled ${t}; then - if enabled child; then - fwrite config.mk "ALL_TARGETS += ${t}-${toolchain}" - else - fwrite config.mk "ALL_TARGETS += ${t}" - fi - fi - true; - done - true -} - -write_common_target_config_mk() { - saved_CC="${CC}" - saved_CXX="${CXX}" - enabled ccache && CC="ccache ${CC}" - enabled ccache && CXX="ccache ${CXX}" - print_webm_license $1 "##" "" - - cat >> $1 << EOF -# This file automatically generated by configure. Do not edit! -SRC_PATH="$source_path_mk" -SRC_PATH_BARE=$source_path_mk -BUILD_PFX=${BUILD_PFX} -TOOLCHAIN=${toolchain} -ASM_CONVERSION=${asm_conversion_cmd:-${source_path_mk}/build/make/ads2gas.pl} -GEN_VCPROJ=${gen_vcproj_cmd} -MSVS_ARCH_DIR=${msvs_arch_dir} - -CC=${CC} -CXX=${CXX} -AR=${AR} -LD=${LD} -AS=${AS} -STRIP=${STRIP} - -CFLAGS = ${CFLAGS} -CXXFLAGS = ${CXXFLAGS} -ARFLAGS = -crs\$(if \$(quiet),,v) -LDFLAGS = ${LDFLAGS} -ASFLAGS = ${ASFLAGS} -extralibs = ${extralibs} -AS_SFX = ${AS_SFX:-.asm} -EXE_SFX = ${EXE_SFX} -VCPROJ_SFX = ${VCPROJ_SFX} -RTCD_OPTIONS = ${RTCD_OPTIONS} -LIBWEBM_CXXFLAGS = ${LIBWEBM_CXXFLAGS} -LIBYUV_CXXFLAGS = ${LIBYUV_CXXFLAGS} -EOF - - if enabled rvct; then cat >> $1 << EOF -fmt_deps = sed -e 's;^__image.axf;\${@:.d=.o} \$@;' #hide -EOF - else cat >> $1 << EOF -fmt_deps = sed -e 's;^\([a-zA-Z0-9_]*\)\.o;\${@:.d=.o} \$@;' -EOF - fi - - print_config_mk VPX_ARCH "${1}" ${ARCH_LIST} - print_config_mk HAVE "${1}" ${HAVE_LIST} - print_config_mk CONFIG "${1}" ${CONFIG_LIST} - print_config_mk HAVE "${1}" gnu_strip - - enabled msvs && echo "CONFIG_VS_VERSION=${vs_version}" >> "${1}" - - CC="${saved_CC}" - CXX="${saved_CXX}" -} - -write_common_target_config_h() { - print_webm_license ${TMP_H} "/*" " */" - cat >> ${TMP_H} << EOF -/* This file automatically generated by configure. Do not edit! */ -#ifndef VPX_CONFIG_H -#define VPX_CONFIG_H -#define RESTRICT ${RESTRICT} -#define INLINE ${INLINE} -EOF - print_config_h VPX_ARCH "${TMP_H}" ${ARCH_LIST} - print_config_h HAVE "${TMP_H}" ${HAVE_LIST} - print_config_h CONFIG "${TMP_H}" ${CONFIG_LIST} - print_config_vars_h "${TMP_H}" ${VAR_LIST} - echo "#endif /* VPX_CONFIG_H */" >> ${TMP_H} - mkdir -p `dirname "$1"` - cmp "$1" ${TMP_H} >/dev/null 2>&1 || mv ${TMP_H} "$1" -} - -write_win_arm64_neon_h_workaround() { - print_webm_license ${TMP_H} "/*" " */" - cat >> ${TMP_H} << EOF -/* This file automatically generated by configure. Do not edit! */ -#ifndef VPX_WIN_ARM_NEON_H_WORKAROUND -#define VPX_WIN_ARM_NEON_H_WORKAROUND -/* The Windows SDK has arm_neon.h, but unlike on other platforms it is - * ARM32-only. ARM64 NEON support is provided by arm64_neon.h, a proper - * superset of arm_neon.h. Work around this by providing a more local - * arm_neon.h that simply #includes arm64_neon.h. - */ -#include -#endif /* VPX_WIN_ARM_NEON_H_WORKAROUND */ -EOF - mkdir -p `dirname "$1"` - cmp "$1" ${TMP_H} >/dev/null 2>&1 || mv ${TMP_H} "$1" -} - -process_common_cmdline() { - for opt in "$@"; do - optval="${opt#*=}" - case "$opt" in - --child) - enable_feature child - ;; - --log*) - logging="$optval" - if ! disabled logging ; then - enabled logging || logfile="$logging" - else - logfile=/dev/null - fi - ;; - --target=*) - toolchain="${toolchain:-${optval}}" - ;; - --force-target=*) - toolchain="${toolchain:-${optval}}" - enable_feature force_toolchain - ;; - --cpu=*) - tune_cpu="$optval" - ;; - --extra-cflags=*) - extra_cflags="${optval}" - ;; - --extra-cxxflags=*) - extra_cxxflags="${optval}" - ;; - --use-profile=*) - pgo_file=${optval} - ;; - --enable-?*|--disable-?*) - eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'` - if is_in ${option} ${ARCH_EXT_LIST}; then - [ $action = "disable" ] && RTCD_OPTIONS="${RTCD_OPTIONS}--disable-${option} " - elif [ $action = "disable" ] && ! disabled $option ; then - is_in ${option} ${CMDLINE_SELECT} || die_unknown $opt - log_echo " disabling $option" - elif [ $action = "enable" ] && ! enabled $option ; then - is_in ${option} ${CMDLINE_SELECT} || die_unknown $opt - log_echo " enabling $option" - fi - ${action}_feature $option - ;; - --require-?*) - eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'` - if is_in ${option} ${ARCH_EXT_LIST}; then - RTCD_OPTIONS="${RTCD_OPTIONS}${opt} " - else - die_unknown $opt - fi - ;; - --force-enable-?*|--force-disable-?*) - eval `echo "$opt" | sed 's/--force-/action=/;s/-/ option=/;s/-/_/g'` - ${action}_feature $option - ;; - --libc=*) - [ -d "${optval}" ] || die "Not a directory: ${optval}" - disable_feature builtin_libc - alt_libc="${optval}" - ;; - --as=*) - [ "${optval}" = yasm ] || [ "${optval}" = nasm ] \ - || [ "${optval}" = auto ] \ - || die "Must be yasm, nasm or auto: ${optval}" - alt_as="${optval}" - ;; - --size-limit=*) - w="${optval%%x*}" - h="${optval##*x}" - VAR_LIST="DECODE_WIDTH_LIMIT ${w} DECODE_HEIGHT_LIMIT ${h}" - [ ${w} -gt 0 ] && [ ${h} -gt 0 ] || die "Invalid size-limit: too small." - [ ${w} -lt 65536 ] && [ ${h} -lt 65536 ] \ - || die "Invalid size-limit: too big." - enable_feature size_limit - ;; - --prefix=*) - prefix="${optval}" - ;; - --libdir=*) - libdir="${optval}" - ;; - --libc|--as|--prefix|--libdir) - die "Option ${opt} requires argument" - ;; - --help|-h) - show_help - ;; - *) - die_unknown $opt - ;; - esac - done -} - -process_cmdline() { - for opt do - optval="${opt#*=}" - case "$opt" in - *) - process_common_cmdline $opt - ;; - esac - done -} - -post_process_common_cmdline() { - prefix="${prefix:-/usr/local}" - prefix="${prefix%/}" - libdir="${libdir:-${prefix}/lib}" - libdir="${libdir%/}" - if [ "${libdir#${prefix}}" = "${libdir}" ]; then - die "Libdir ${libdir} must be a subdirectory of ${prefix}" - fi -} - -post_process_cmdline() { - true; -} - -setup_gnu_toolchain() { - CC=${CC:-${CROSS}gcc} - CXX=${CXX:-${CROSS}g++} - AR=${AR:-${CROSS}ar} - LD=${LD:-${CROSS}${link_with_cc:-ld}} - AS=${AS:-${CROSS}as} - STRIP=${STRIP:-${CROSS}strip} - AS_SFX=.S - EXE_SFX= -} - -# Reliably find the newest available Darwin SDKs. (Older versions of -# xcrun don't support --show-sdk-path.) -show_darwin_sdk_path() { - xcrun --sdk $1 --show-sdk-path 2>/dev/null || - xcodebuild -sdk $1 -version Path 2>/dev/null -} - -# Print the major version number of the Darwin SDK specified by $1. -show_darwin_sdk_major_version() { - xcrun --sdk $1 --show-sdk-version 2>/dev/null | cut -d. -f1 -} - -# Print the Xcode version. -show_xcode_version() { - xcodebuild -version | head -n1 | cut -d' ' -f2 -} - -# Fails when Xcode version is less than 6.3. -check_xcode_minimum_version() { - xcode_major=$(show_xcode_version | cut -f1 -d.) - xcode_minor=$(show_xcode_version | cut -f2 -d.) - xcode_min_major=6 - xcode_min_minor=3 - if [ ${xcode_major} -lt ${xcode_min_major} ]; then - return 1 - fi - if [ ${xcode_major} -eq ${xcode_min_major} ] \ - && [ ${xcode_minor} -lt ${xcode_min_minor} ]; then - return 1 - fi -} - -process_common_toolchain() { - if [ -z "$toolchain" ]; then - gcctarget="${CHOST:-$(gcc -dumpmachine 2> /dev/null)}" - # detect tgt_isa - case "$gcctarget" in - aarch64*) - tgt_isa=arm64 - ;; - armv7*-hardfloat* | armv7*-gnueabihf | arm-*-gnueabihf) - tgt_isa=armv7 - float_abi=hard - ;; - armv7*) - tgt_isa=armv7 - float_abi=softfp - ;; - *x86_64*|*amd64*) - tgt_isa=x86_64 - ;; - *i[3456]86*) - tgt_isa=x86 - ;; - *sparc*) - tgt_isa=sparc - ;; - power*64le*-*) - tgt_isa=ppc64le - ;; - *mips64el*) - tgt_isa=mips64 - ;; - *mips32el*) - tgt_isa=mips32 - ;; - loongarch32*) - tgt_isa=loongarch32 - ;; - loongarch64*) - tgt_isa=loongarch64 - ;; - esac - - # detect tgt_os - case "$gcctarget" in - *darwin1[0-9]*) - tgt_isa=x86_64 - tgt_os=`echo $gcctarget | sed 's/.*\(darwin1[0-9]\).*/\1/'` - ;; - *darwin2[0-4]*) - tgt_isa=`uname -m` - tgt_os=`echo $gcctarget | sed 's/.*\(darwin2[0-9]\).*/\1/'` - ;; - x86_64*mingw32*) - tgt_os=win64 - ;; - x86_64*cygwin*) - tgt_os=win64 - ;; - *mingw32*|*cygwin*) - [ -z "$tgt_isa" ] && tgt_isa=x86 - tgt_os=win32 - ;; - *linux*|*bsd*) - tgt_os=linux - ;; - *solaris2.10) - tgt_os=solaris - ;; - *os2*) - tgt_os=os2 - ;; - esac - - if [ -n "$tgt_isa" ] && [ -n "$tgt_os" ]; then - toolchain=${tgt_isa}-${tgt_os}-gcc - fi - fi - - toolchain=${toolchain:-generic-gnu} - - is_in ${toolchain} ${all_platforms} || enabled force_toolchain \ - || die "Unrecognized toolchain '${toolchain}'" - - enabled child || log_echo "Configuring for target '${toolchain}'" - - # - # Set up toolchain variables - # - tgt_isa=$(echo ${toolchain} | awk 'BEGIN{FS="-"}{print $1}') - tgt_os=$(echo ${toolchain} | awk 'BEGIN{FS="-"}{print $2}') - tgt_cc=$(echo ${toolchain} | awk 'BEGIN{FS="-"}{print $3}') - - # Mark the specific ISA requested as enabled - soft_enable ${tgt_isa} - enable_feature ${tgt_os} - enable_feature ${tgt_cc} - - # Enable the architecture family - case ${tgt_isa} in - arm64 | armv8) - enable_feature arm - enable_feature aarch64 - ;; - arm*) - enable_feature arm - ;; - mips*) - enable_feature mips - ;; - ppc*) - enable_feature ppc - ;; - loongarch*) - soft_enable lsx - soft_enable lasx - enable_feature loongarch - ;; - esac - - # Position independent code (PIC) is probably what we want when building - # shared libs or position independent executable (PIE) targets. - enabled shared && soft_enable pic - check_cpp << EOF || soft_enable pic -#if !(__pie__ || __PIE__) -#error Neither __pie__ or __PIE__ are set -#endif -EOF - - # Minimum iOS version for all target platforms (darwin and iphonesimulator). - # Shared library framework builds are only possible on iOS 8 and later. - if enabled shared; then - IOS_VERSION_OPTIONS="--enable-shared" - IOS_VERSION_MIN="8.0" - else - IOS_VERSION_OPTIONS="" - IOS_VERSION_MIN="7.0" - fi - - # Handle darwin variants. Newer SDKs allow targeting older - # platforms, so use the newest one available. - case ${toolchain} in - arm*-darwin-*) - add_cflags "-miphoneos-version-min=${IOS_VERSION_MIN}" - iphoneos_sdk_dir="$(show_darwin_sdk_path iphoneos)" - if [ -d "${iphoneos_sdk_dir}" ]; then - add_cflags "-isysroot ${iphoneos_sdk_dir}" - add_ldflags "-isysroot ${iphoneos_sdk_dir}" - fi - ;; - *-darwin*) - osx_sdk_dir="$(show_darwin_sdk_path macosx)" - if [ -d "${osx_sdk_dir}" ]; then - add_cflags "-isysroot ${osx_sdk_dir}" - add_ldflags "-isysroot ${osx_sdk_dir}" - fi - ;; - esac - - case ${toolchain} in - *-darwin8-*) - add_cflags "-mmacosx-version-min=10.4" - add_ldflags "-mmacosx-version-min=10.4" - ;; - *-darwin9-*) - add_cflags "-mmacosx-version-min=10.5" - add_ldflags "-mmacosx-version-min=10.5" - ;; - *-darwin10-*) - add_cflags "-mmacosx-version-min=10.6" - add_ldflags "-mmacosx-version-min=10.6" - ;; - *-darwin11-*) - add_cflags "-mmacosx-version-min=10.7" - add_ldflags "-mmacosx-version-min=10.7" - ;; - *-darwin12-*) - add_cflags "-mmacosx-version-min=10.8" - add_ldflags "-mmacosx-version-min=10.8" - ;; - *-darwin13-*) - add_cflags "-mmacosx-version-min=10.9" - add_ldflags "-mmacosx-version-min=10.9" - ;; - *-darwin14-*) - add_cflags "-mmacosx-version-min=10.10" - add_ldflags "-mmacosx-version-min=10.10" - ;; - *-darwin15-*) - add_cflags "-mmacosx-version-min=10.11" - add_ldflags "-mmacosx-version-min=10.11" - ;; - *-darwin16-*) - add_cflags "-mmacosx-version-min=10.12" - add_ldflags "-mmacosx-version-min=10.12" - ;; - *-darwin17-*) - add_cflags "-mmacosx-version-min=10.13" - add_ldflags "-mmacosx-version-min=10.13" - ;; - *-darwin18-*) - add_cflags "-mmacosx-version-min=10.14" - add_ldflags "-mmacosx-version-min=10.14" - ;; - *-darwin19-*) - add_cflags "-mmacosx-version-min=10.15" - add_ldflags "-mmacosx-version-min=10.15" - ;; - *-darwin2[0-4]-*) - add_cflags "-arch ${toolchain%%-*}" - add_ldflags "-arch ${toolchain%%-*}" - ;; - *-iphonesimulator-*) - add_cflags "-miphoneos-version-min=${IOS_VERSION_MIN}" - add_ldflags "-miphoneos-version-min=${IOS_VERSION_MIN}" - iossim_sdk_dir="$(show_darwin_sdk_path iphonesimulator)" - if [ -d "${iossim_sdk_dir}" ]; then - add_cflags "-isysroot ${iossim_sdk_dir}" - add_ldflags "-isysroot ${iossim_sdk_dir}" - fi - ;; - esac - - # Handle Solaris variants. Solaris 10 needs -lposix4 - case ${toolchain} in - sparc-solaris-*) - add_extralibs -lposix4 - ;; - *-solaris-*) - add_extralibs -lposix4 - ;; - esac - - # Process architecture variants - case ${toolchain} in - arm*) - case ${toolchain} in - armv7*-darwin*) - # Runtime cpu detection is not defined for these targets. - enabled runtime_cpu_detect && disable_feature runtime_cpu_detect - ;; - *) - soft_enable runtime_cpu_detect - ;; - esac - - if [ ${tgt_isa} = "armv7" ] || [ ${tgt_isa} = "armv7s" ]; then - soft_enable neon - # Only enable neon_asm when neon is also enabled. - enabled neon && soft_enable neon_asm - # If someone tries to force it through, die. - if disabled neon && enabled neon_asm; then - die "Disabling neon while keeping neon-asm is not supported" - fi - fi - - asm_conversion_cmd="cat" - case ${tgt_cc} in - gcc) - link_with_cc=gcc - setup_gnu_toolchain - arch_int=${tgt_isa##armv} - arch_int=${arch_int%%te} - tune_cflags="-mtune=" - if [ ${tgt_isa} = "armv7" ] || [ ${tgt_isa} = "armv7s" ]; then - if [ -z "${float_abi}" ]; then - check_cpp <&- || \ - die "Couldn't find CodeSourcery GCC from PATH" - - # Use armcc as a linker to enable translation of - # some gcc specific options such as -lm and -lpthread. - LD="armcc --translate_gcc" - - # create configuration file (uses path to CodeSourcery GCC) - armcc --arm_linux_configure --arm_linux_config_file=arm_linux.cfg - - add_cflags --arm_linux_paths --arm_linux_config_file=arm_linux.cfg - add_asflags --no_hide_all --apcs=/interwork - add_ldflags --arm_linux_paths --arm_linux_config_file=arm_linux.cfg - enabled pic && add_cflags --apcs=/fpic - enabled pic && add_asflags --apcs=/fpic - enabled shared && add_cflags --shared - fi - ;; - esac - - # AArch64 ISA extensions are treated as supersets. - if [ ${tgt_isa} = "arm64" ] || [ ${tgt_isa} = "armv8" ]; then - aarch64_arch_flag_neon="arch=armv8-a" - aarch64_arch_flag_neon_dotprod="arch=armv8.2-a+dotprod" - aarch64_arch_flag_neon_i8mm="arch=armv8.2-a+dotprod+i8mm" - aarch64_arch_flag_sve="arch=armv8.2-a+dotprod+i8mm+sve" - aarch64_arch_flag_sve2="arch=armv9-a+sve2" - for ext in ${ARCH_EXT_LIST_AARCH64}; do - if [ "$disable_exts" = "yes" ]; then - RTCD_OPTIONS="${RTCD_OPTIONS}--disable-${ext} " - soft_disable $ext - else - # Check the compiler supports the -march flag for the extension. - # This needs to happen after toolchain/OS inspection so we handle - # $CROSS etc correctly when checking for flags, else these will - # always fail. - flag="$(eval echo \$"aarch64_arch_flag_${ext}")" - check_gcc_machine_option "${flag}" "${ext}" - if ! enabled $ext; then - # Disable higher order extensions to simplify dependencies. - disable_exts="yes" - RTCD_OPTIONS="${RTCD_OPTIONS}--disable-${ext} " - soft_disable $ext - fi - fi - done - if enabled sve; then - check_neon_sve_bridge_compiles - fi - fi - - ;; - mips*) - link_with_cc=gcc - setup_gnu_toolchain - tune_cflags="-mtune=" - if enabled dspr2; then - check_add_cflags -mips32r2 -mdspr2 - fi - - if enabled runtime_cpu_detect; then - disable_feature runtime_cpu_detect - fi - - if [ -n "${tune_cpu}" ]; then - case ${tune_cpu} in - p5600) - check_add_cflags -mips32r5 -mload-store-pairs - check_add_cflags -msched-weight -mhard-float -mfp64 - check_add_asflags -mips32r5 -mhard-float -mfp64 - check_add_ldflags -mfp64 - ;; - i6400|p6600) - check_add_cflags -mips64r6 -mabi=64 -msched-weight - check_add_cflags -mload-store-pairs -mhard-float -mfp64 - check_add_asflags -mips64r6 -mabi=64 -mhard-float -mfp64 - check_add_ldflags -mips64r6 -mabi=64 -mfp64 - ;; - loongson3*) - check_cflags -march=loongson3a && soft_enable mmi \ - || disable_feature mmi - check_cflags -mmsa && soft_enable msa \ - || disable_feature msa - tgt_isa=loongson3a - ;; - esac - - if enabled mmi || enabled msa; then - soft_enable runtime_cpu_detect - fi - - if enabled msa; then - # TODO(libyuv:793) - # The new mips functions in libyuv do not build - # with the toolchains we currently use for testing. - soft_disable libyuv - fi - fi - - check_add_cflags -march=${tgt_isa} - check_add_asflags -march=${tgt_isa} - check_add_asflags -KPIC - ;; - ppc64le*) - link_with_cc=gcc - setup_gnu_toolchain - # Do not enable vsx by default. - # https://bugs.chromium.org/p/webm/issues/detail?id=1522 - enabled vsx || RTCD_OPTIONS="${RTCD_OPTIONS}--disable-vsx " - if [ -n "${tune_cpu}" ]; then - case ${tune_cpu} in - power?) - tune_cflags="-mcpu=" - ;; - esac - fi - ;; - x86*) - case ${tgt_os} in - android) - soft_enable realtime_only - ;; - win*) - enabled gcc && add_cflags -fno-common - ;; - solaris*) - CC=${CC:-${CROSS}gcc} - CXX=${CXX:-${CROSS}g++} - LD=${LD:-${CROSS}gcc} - CROSS=${CROSS-g} - ;; - os2) - disable_feature pic - AS=${AS:-nasm} - add_ldflags -Zhigh-mem - ;; - esac - - AS="${alt_as:-${AS:-auto}}" - case ${tgt_cc} in - icc*) - CC=${CC:-icc} - LD=${LD:-icc} - setup_gnu_toolchain - add_cflags -use-msasm # remove -use-msasm too? - # add -no-intel-extensions to suppress warning #10237 - # refer to http://software.intel.com/en-us/forums/topic/280199 - add_ldflags -i-static -no-intel-extensions - enabled x86_64 && add_cflags -ipo -static -O3 -no-prec-div - enabled x86_64 && AR=xiar - case ${tune_cpu} in - atom*) - tune_cflags="-x" - tune_cpu="SSE3_ATOM" - ;; - *) - tune_cflags="-march=" - ;; - esac - ;; - gcc*) - link_with_cc=gcc - tune_cflags="-march=" - setup_gnu_toolchain - #for 32 bit x86 builds, -O3 did not turn on this flag - enabled optimizations && disabled gprof && check_add_cflags -fomit-frame-pointer - ;; - vs*) - msvs_arch_dir=x86-msvs - case ${tgt_cc##vs} in - 14) - echo "${tgt_cc} does not support avx512, disabling....." - RTCD_OPTIONS="${RTCD_OPTIONS}--disable-avx512 " - soft_disable avx512 - ;; - esac - ;; - esac - - bits=32 - enabled x86_64 && bits=64 - check_cpp < sse4 - check_gcc_machine_option ${ext%_*} $ext - fi - fi - done - - if enabled external_build; then - log_echo " skipping assembler detection" - else - case "${AS}" in - auto|"") - which nasm >/dev/null 2>&1 && AS=nasm - which yasm >/dev/null 2>&1 && AS=yasm - if [ "${AS}" = nasm ] ; then - # Apple ships version 0.98 of nasm through at least Xcode 6. Revisit - # this check if they start shipping a compatible version. - apple=`nasm -v | grep "Apple"` - [ -n "${apple}" ] \ - && echo "Unsupported version of nasm: ${apple}" \ - && AS="" - fi - [ "${AS}" = auto ] || [ -z "${AS}" ] \ - && die "Neither yasm nor nasm have been found." \ - "See the prerequisites section in the README for more info." - ;; - esac - log_echo " using $AS" - fi - AS_SFX=.asm - case ${tgt_os} in - win32) - add_asflags -f win32 - enabled debug && add_asflags -g cv8 - EXE_SFX=.exe - ;; - win64) - add_asflags -f win64 - enabled debug && add_asflags -g cv8 - EXE_SFX=.exe - ;; - linux*|solaris*|android*) - add_asflags -f elf${bits} - enabled debug && [ "${AS}" = yasm ] && add_asflags -g dwarf2 - enabled debug && [ "${AS}" = nasm ] && add_asflags -g - [ "${AS##*/}" = nasm ] && check_asm_align - ;; - darwin*) - add_asflags -f macho${bits} - enabled x86 && darwin_arch="-arch i386" || darwin_arch="-arch x86_64" - add_cflags ${darwin_arch} - add_ldflags ${darwin_arch} - # -mdynamic-no-pic is still a bit of voodoo -- it was required at - # one time, but does not seem to be now, and it breaks some of the - # code that still relies on inline assembly. - # enabled icc && ! enabled pic && add_cflags -fno-pic -mdynamic-no-pic - enabled icc && ! enabled pic && add_cflags -fno-pic - ;; - iphonesimulator) - add_asflags -f macho${bits} - enabled x86 && sim_arch="-arch i386" || sim_arch="-arch x86_64" - add_cflags ${sim_arch} - add_ldflags ${sim_arch} - - if [ "$(disabled external_build)" ] && - [ "$(show_darwin_sdk_major_version iphonesimulator)" -gt 8 ]; then - # yasm v1.3.0 doesn't know what -fembed-bitcode means, so turning it - # on is pointless (unless building a C-only lib). Warn the user, but - # do nothing here. - log "Warning: Bitcode embed disabled for simulator targets." - fi - ;; - os2) - add_asflags -f aout - enabled debug && add_asflags -g - EXE_SFX=.exe - ;; - *) - log "Warning: Unknown os $tgt_os while setting up $AS flags" - ;; - esac - ;; - loongarch*) - link_with_cc=gcc - setup_gnu_toolchain - - enabled lsx && check_inline_asm lsx '"vadd.b $vr0, $vr1, $vr1"' - enabled lsx && soft_enable runtime_cpu_detect - enabled lasx && check_inline_asm lasx '"xvadd.b $xr0, $xr1, $xr1"' - enabled lasx && soft_enable runtime_cpu_detect - ;; - *-gcc|generic-gnu) - link_with_cc=gcc - enable_feature gcc - setup_gnu_toolchain - ;; - esac - - # Enable PGO - if [ -n "${pgo_file}" ]; then - check_add_cflags -fprofile-use=${pgo_file} || \ - die "-fprofile-use is not supported by compiler" - check_add_ldflags -fprofile-use=${pgo_file} || \ - die "-fprofile-use is not supported by linker" - fi - - # Try to enable CPU specific tuning - if [ -n "${tune_cpu}" ]; then - if [ -n "${tune_cflags}" ]; then - check_add_cflags ${tune_cflags}${tune_cpu} || \ - die "Requested CPU '${tune_cpu}' not supported by compiler" - fi - if [ -n "${tune_asflags}" ]; then - check_add_asflags ${tune_asflags}${tune_cpu} || \ - die "Requested CPU '${tune_cpu}' not supported by assembler" - fi - if [ -z "${tune_cflags}${tune_asflags}" ]; then - log_echo "Warning: CPU tuning not supported by this toolchain" - fi - fi - - if enabled debug; then - check_add_cflags -g && check_add_ldflags -g - else - check_add_cflags -DNDEBUG - fi - enabled profile && - check_add_cflags -fprofile-generate && - check_add_ldflags -fprofile-generate - - enabled gprof && check_add_cflags -pg && check_add_ldflags -pg - enabled gcov && - check_add_cflags -fprofile-arcs -ftest-coverage && - check_add_ldflags -fprofile-arcs -ftest-coverage - - if enabled optimizations; then - if enabled rvct; then - enabled small && check_add_cflags -Ospace || check_add_cflags -Otime - else - enabled small && check_add_cflags -O2 || check_add_cflags -O3 - fi - fi - - # Position Independent Code (PIC) support, for building relocatable - # shared objects - enabled gcc && enabled pic && check_add_cflags -fPIC - - # Work around longjmp interception on glibc >= 2.11, to improve binary - # compatibility. See http://code.google.com/p/webm/issues/detail?id=166 - enabled linux && check_add_cflags -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 - - # Check for strip utility variant - ${STRIP} -V 2>/dev/null | grep GNU >/dev/null && enable_feature gnu_strip - - # Try to determine target endianness - check_cc </dev/null 2>&1 && enable_feature big_endian - - # Try to find which inline keywords are supported - check_cc < -#include -int main(void) { return pthread_create(NULL, NULL, NULL, NULL); } -EOF - ;; - esac - fi - - # only for MIPS platforms - case ${toolchain} in - mips*) - if enabled big_endian; then - if enabled dspr2; then - echo "dspr2 optimizations are available only for little endian platforms" - disable_feature dspr2 - fi - if enabled msa; then - echo "msa optimizations are available only for little endian platforms" - disable_feature msa - fi - if enabled mmi; then - echo "mmi optimizations are available only for little endian platforms" - disable_feature mmi - fi - fi - ;; - esac - - # only for LOONGARCH platforms - case ${toolchain} in - loongarch*) - if enabled big_endian; then - if enabled lsx; then - echo "lsx optimizations are available only for little endian platforms" - disable_feature lsx - fi - if enabled lasx; then - echo "lasx optimizations are available only for little endian platforms" - disable_feature lasx - fi - fi - ;; - esac - - # glibc needs these - if enabled linux; then - add_cflags -D_LARGEFILE_SOURCE - add_cflags -D_FILE_OFFSET_BITS=64 - fi -} - -process_toolchain() { - process_common_toolchain -} - -print_config_mk() { - saved_prefix="${prefix}" - prefix=$1 - makefile=$2 - shift 2 - for cfg; do - if enabled $cfg; then - upname="`toupper $cfg`" - echo "${prefix}_${upname}=yes" >> $makefile - fi - done - prefix="${saved_prefix}" -} - -print_config_h() { - saved_prefix="${prefix}" - prefix=$1 - header=$2 - shift 2 - for cfg; do - upname="`toupper $cfg`" - if enabled $cfg; then - echo "#define ${prefix}_${upname} 1" >> $header - else - echo "#define ${prefix}_${upname} 0" >> $header - fi - done - prefix="${saved_prefix}" -} - -print_config_vars_h() { - header=$1 - shift - while [ $# -gt 0 ]; do - upname="`toupper $1`" - echo "#define ${upname} $2" >> $header - shift 2 - done -} - -print_webm_license() { - saved_prefix="${prefix}" - destination=$1 - prefix="$2" - suffix="$3" - shift 3 - cat < ${destination} -${prefix} Copyright (c) 2011 The WebM project authors. All Rights Reserved.${suffix} -${prefix} ${suffix} -${prefix} Use of this source code is governed by a BSD-style license${suffix} -${prefix} that can be found in the LICENSE file in the root of the source${suffix} -${prefix} tree. An additional intellectual property rights grant can be found${suffix} -${prefix} in the file PATENTS. All contributing project authors may${suffix} -${prefix} be found in the AUTHORS file in the root of the source tree.${suffix} -EOF - prefix="${saved_prefix}" -} - -process_targets() { - true; -} - -process_detect() { - true; -} - -enable_feature logging -logfile="config.log" -self=$0 -process() { - cmdline_args="$@" - process_cmdline "$@" - if enabled child; then - echo "# ${self} $@" >> ${logfile} - else - echo "# ${self} $@" > ${logfile} - fi - post_process_common_cmdline - post_process_cmdline - process_toolchain - process_detect - process_targets - - OOT_INSTALLS="${OOT_INSTALLS}" - if enabled source_path_used; then - # Prepare the PWD for building. - for f in ${OOT_INSTALLS}; do - install -D "${source_path}/$f" "$f" - done - fi - cp "${source_path}/build/make/Makefile" . - - clean_temp_files - true -} diff --git a/presentation/src/main/cpp/third_party/libvpx/build/make/gen_asm_deps.sh b/presentation/src/main/cpp/third_party/libvpx/build/make/gen_asm_deps.sh deleted file mode 100644 index 3bd4d125..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build/make/gen_asm_deps.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - - -self=$0 -show_help() { - echo "usage: $self [options] " - echo - echo "Generate Makefile dependency information from assembly code source" - echo - exit 1 -} -die_unknown(){ - echo "Unknown option \"$1\"." - echo "See $0 --help for available options." - exit 1 -} -for opt do - optval="${opt#*=}" - case "$opt" in - --build-pfx=*) pfx="${optval}" - ;; - --depfile=*) out="${optval}" - ;; - -I*) raw_inc_paths="${raw_inc_paths} ${opt}" - inc_path="${inc_path} ${opt#-I}" - ;; - -h|--help) show_help - ;; - *) [ -f "$opt" ] && srcfile="$opt" - ;; - esac -done - -[ -n "$srcfile" ] || show_help -sfx=${sfx:-asm} -includes=$(LC_ALL=C grep -E -i "include +\"?[a-z0-9_/]+\.${sfx}" $srcfile | - perl -p -e "s;.*?([a-z0-9_/]+.${sfx}).*;\1;") -#" restore editor state -for inc in ${includes}; do - found_inc_path= - for idir in ${inc_path}; do - [ -f "${idir}/${inc}" ] && found_inc_path="${idir}" && break - done - if [ -f `dirname $srcfile`/$inc ]; then - # Handle include files in the same directory as the source - $self --build-pfx=$pfx --depfile=$out ${raw_inc_paths} `dirname $srcfile`/$inc - elif [ -n "${found_inc_path}" ]; then - # Handle include files on the include path - $self --build-pfx=$pfx --depfile=$out ${raw_inc_paths} "${found_inc_path}/$inc" - else - # Handle generated includes in the build root (which may not exist yet) - echo ${out} ${out%d}o: "${pfx}${inc}" - fi -done -echo ${out} ${out%d}o: $srcfile diff --git a/presentation/src/main/cpp/third_party/libvpx/build/make/gen_msvs_def.sh b/presentation/src/main/cpp/third_party/libvpx/build/make/gen_msvs_def.sh deleted file mode 100644 index 4defcc2e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build/make/gen_msvs_def.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/bash -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - - -self=$0 -self_basename=${self##*/} -EOL=$'\n' - -show_help() { - cat < symbol1 [symbol2, symbol3, ...] - -where is either 'text' or 'data' - - -Options: - --help Print this message - --out=filename Write output to a file [stdout] - --name=project_name Name of the library (required) -EOF - exit 1 -} - -die() { - echo "${self_basename}: $@" - exit 1 -} - -die_unknown(){ - echo "Unknown option \"$1\"." - echo "See ${self_basename} --help for available options." - exit 1 -} - -text() { - for sym in "$@"; do - echo " $sym" >> ${outfile} - done -} - -data() { - for sym in "$@"; do - printf " %-40s DATA\n" "$sym" >> ${outfile} - done -} - -# Process command line -for opt in "$@"; do - optval="${opt#*=}" - case "$opt" in - --help|-h) show_help - ;; - --out=*) outfile="$optval" - ;; - --name=*) name="${optval}" - ;; - -*) die_unknown $opt - ;; - *) file_list[${#file_list[@]}]="$opt" - esac -done -outfile=${outfile:-/dev/stdout} -[ -n "$name" ] || die "Library name (--name) must be specified!" - -echo "LIBRARY ${name}" > ${outfile} -echo "EXPORTS" >> ${outfile} -for f in "${file_list[@]}"; do - . $f -done diff --git a/presentation/src/main/cpp/third_party/libvpx/build/make/gen_msvs_sln.sh b/presentation/src/main/cpp/third_party/libvpx/build/make/gen_msvs_sln.sh deleted file mode 100644 index 0b312850..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build/make/gen_msvs_sln.sh +++ /dev/null @@ -1,255 +0,0 @@ -#!/bin/bash -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - - -self=$0 -self_basename=${self##*/} -EOL=$'\n' -EOLDOS=$'\r' - -show_help() { - cat <&2 - [ -f "${outfile}" ] && rm -f ${outfile}{,.mk} - exit 1 -} - -die_unknown(){ - echo "Unknown option \"$1\"." >&2 - echo "See ${self_basename} --help for available options." >&2 - [ -f "${outfile}" ] && rm -f ${outfile}{,.mk} - exit 1 -} - -indent1=$'\t' -indent="" -indent_push() { - indent="${indent}${indent1}" -} -indent_pop() { - indent="${indent%${indent1}}" -} - -parse_project() { - local file=$1 - local name=`grep RootNamespace "$file" | sed 's,.*<.*>\(.*\).*,\1,'` - local guid=`grep ProjectGuid "$file" | sed 's,.*<.*>\(.*\).*,\1,'` - - # save the project GUID to a varaible, normalizing to the basename of the - # vcxproj file without the extension - local var - var=${file##*/} - var=${var%%.${sfx}} - eval "${var}_file=\"$1\"" - eval "${var}_name=$name" - eval "${var}_guid=$guid" - - cur_config_list=`grep -B1 'Label="Configuration"' $file | - grep Condition | cut -d\' -f4` - new_config_list=$(for i in $config_list $cur_config_list; do - echo $i - done | sort | uniq) - if [ "$config_list" != "" ] && [ "$config_list" != "$new_config_list" ]; then - mixed_platforms=1 - fi - config_list="$new_config_list" - eval "${var}_config_list=\"$cur_config_list\"" - proj_list="${proj_list} ${var}" -} - -process_project() { - eval "local file=\${$1_file}" - eval "local name=\${$1_name}" - eval "local guid=\${$1_guid}" - - # save the project GUID to a varaible, normalizing to the basename of the - # vcproj file without the extension - local var - var=${file##*/} - var=${var%%.${sfx}} - eval "${var}_guid=$guid" - - echo "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"$name\", \"$file\", \"$guid\"" - echo "EndProject" -} - -process_global() { - echo "Global" - indent_push - - # - # Solution Configuration Platforms - # - echo "${indent}GlobalSection(SolutionConfigurationPlatforms) = preSolution" - indent_push - IFS_bak=${IFS} - IFS=$'\r'$'\n' - if [ "$mixed_platforms" != "" ]; then - config_list=" -Release|Mixed Platforms -Debug|Mixed Platforms" - fi - for config in ${config_list}; do - echo "${indent}$config = $config" - done - IFS=${IFS_bak} - indent_pop - echo "${indent}EndGlobalSection" - - # - # Project Configuration Platforms - # - echo "${indent}GlobalSection(ProjectConfigurationPlatforms) = postSolution" - indent_push - for proj in ${proj_list}; do - eval "local proj_guid=\${${proj}_guid}" - eval "local proj_config_list=\${${proj}_config_list}" - IFS=$'\r'$'\n' - for config in ${proj_config_list}; do - if [ "$mixed_platforms" != "" ]; then - local c=${config%%|*} - echo "${indent}${proj_guid}.${c}|Mixed Platforms.ActiveCfg = ${config}" - echo "${indent}${proj_guid}.${c}|Mixed Platforms.Build.0 = ${config}" - else - echo "${indent}${proj_guid}.${config}.ActiveCfg = ${config}" - echo "${indent}${proj_guid}.${config}.Build.0 = ${config}" - fi - - done - IFS=${IFS_bak} - done - indent_pop - echo "${indent}EndGlobalSection" - - # - # Solution Properties - # - echo "${indent}GlobalSection(SolutionProperties) = preSolution" - indent_push - echo "${indent}HideSolutionNode = FALSE" - indent_pop - echo "${indent}EndGlobalSection" - - indent_pop - echo "EndGlobal" -} - -process_makefile() { - IFS_bak=${IFS} - IFS=$'\r'$'\n' - local TAB=$'\t' - cat </dev/null 2>&1 && echo yes) -.nodevenv.once: -${TAB}@echo " * \$(MSBUILD_TOOL) not found in path." -${TAB}@echo " * " -${TAB}@echo " * You will have to build all configurations manually using the" -${TAB}@echo " * Visual Studio IDE. To allow make to build them automatically," -${TAB}@echo " * add the Common7/IDE directory of your Visual Studio" -${TAB}@echo " * installation to your path, eg:" -${TAB}@echo " * C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE" -${TAB}@echo " * " -${TAB}@touch \$@ -CLEAN-OBJS += \$(if \$(found_devenv),,.nodevenv.once) - -EOF - - for sln_config in ${config_list}; do - local config=${sln_config%%|*} - local platform=${sln_config##*|} - local nows_sln_config=`echo $sln_config | sed -e 's/[^a-zA-Z0-9]/_/g'` - cat <${outfile} <>${outfile} -done -process_global >>${outfile} -process_makefile >${mkoutfile} diff --git a/presentation/src/main/cpp/third_party/libvpx/build/make/gen_msvs_vcxproj.sh b/presentation/src/main/cpp/third_party/libvpx/build/make/gen_msvs_vcxproj.sh deleted file mode 100644 index 1e1db05b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build/make/gen_msvs_vcxproj.sh +++ /dev/null @@ -1,508 +0,0 @@ -#!/bin/bash -## -## Copyright (c) 2013 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -self=$0 -self_basename=${self##*/} -self_dirname=$(dirname "$0") - -. "$self_dirname/msvs_common.sh"|| exit 127 - -show_help() { - cat <${content}" - indent_pop - else - echo "${indent}<${tag}>${content}" - fi -} - -generate_filter() { - local name=$1 - local pats=$2 - local file_list_sz - local i - local f - local saveIFS="$IFS" - local pack - echo "generating filter '$name' from ${#file_list[@]} files" >&2 - IFS=* - - file_list_sz=${#file_list[@]} - for i in ${!file_list[@]}; do - f=${file_list[i]} - for pat in ${pats//;/$IFS}; do - if [ "${f##*.}" == "$pat" ]; then - unset file_list[i] - - objf=$(echo ${f%.*}.obj \ - | sed -e "s,$src_path_bare,," \ - -e 's/^[\./]\+//g' -e 's,[:/ ],_,g') - - if ([ "$pat" == "asm" ] || [ "$pat" == "s" ] || [ "$pat" == "S" ]) && $uses_asm; then - # Avoid object file name collisions, i.e. vpx_config.c and - # vpx_config.asm produce the same object file without - # this additional suffix. - objf=${objf%.obj}_asm.obj - open_tag CustomBuild \ - Include="$f" - for plat in "${platforms[@]}"; do - for cfg in Debug Release; do - tag_content Message "Assembling %(Filename)%(Extension)" \ - Condition="'\$(Configuration)|\$(Platform)'=='$cfg|$plat'" - tag_content Command "$(eval echo \$asm_${cfg}_cmdline) -o \$(IntDir)$objf" \ - Condition="'\$(Configuration)|\$(Platform)'=='$cfg|$plat'" - tag_content Outputs "\$(IntDir)$objf" \ - Condition="'\$(Configuration)|\$(Platform)'=='$cfg|$plat'" - done - done - close_tag CustomBuild - elif [ "$pat" == "c" ] || \ - [ "$pat" == "cc" ] || [ "$pat" == "cpp" ]; then - open_tag ClCompile \ - Include="$f" - # Separate file names with Condition? - tag_content ObjectFileName "\$(IntDir)$objf" - # Check for AVX and turn it on to avoid warnings. - if [[ $f =~ avx.?\.c$ ]]; then - tag_content AdditionalOptions "/arch:AVX" - fi - close_tag ClCompile - elif [ "$pat" == "h" ] ; then - tag ClInclude \ - Include="$f" - elif [ "$pat" == "vcxproj" ] ; then - open_tag ProjectReference \ - Include="$f" - depguid=`grep ProjectGuid "$f" | sed 's,.*<.*>\(.*\).*,\1,'` - tag_content Project "$depguid" - tag_content ReferenceOutputAssembly false - close_tag ProjectReference - else - tag None \ - Include="$f" - fi - - break - fi - done - done - - IFS="$saveIFS" -} - -# Process command line -unset target -for opt in "$@"; do - optval="${opt#*=}" - case "$opt" in - --help|-h) show_help - ;; - --target=*) - target="${optval}" - platform_toolset=$(echo ${target} | awk 'BEGIN{FS="-"}{print $4}') - case "$platform_toolset" in - clangcl) platform_toolset="ClangCl" - ;; - "") - ;; - *) die Unrecognized Visual Studio Platform Toolset in $opt - ;; - esac - ;; - --out=*) outfile="$optval" - ;; - --name=*) name="${optval}" - ;; - --proj-guid=*) guid="${optval}" - ;; - --module-def=*) module_def="${optval}" - ;; - --exe) proj_kind="exe" - ;; - --dll) proj_kind="dll" - ;; - --lib) proj_kind="lib" - ;; - --as=*) as="${optval}" - ;; - --src-path-bare=*) - src_path_bare=$(fix_path "$optval") - src_path_bare=${src_path_bare%/} - ;; - --static-crt) use_static_runtime=true - ;; - --enable-werror) werror=true - ;; - --ver=*) - vs_ver="$optval" - case "$optval" in - 1[4-7]) - ;; - *) die Unrecognized Visual Studio Version in $opt - ;; - esac - ;; - -I*) - opt=${opt##-I} - opt=$(fix_path "$opt") - opt="${opt%/}" - incs="${incs}${incs:+;}"${opt}"" - yasmincs="${yasmincs} -I"${opt}"" - ;; - -D*) defines="${defines}${defines:+;}${opt##-D}" - ;; - -L*) # fudge . to $(OutDir) - if [ "${opt##-L}" == "." ]; then - libdirs="${libdirs}${libdirs:+;}"\$(OutDir)"" - else - # Also try directories for this platform/configuration - opt=${opt##-L} - opt=$(fix_path "$opt") - libdirs="${libdirs}${libdirs:+;}"${opt}"" - libdirs="${libdirs}${libdirs:+;}"${opt}/\$(PlatformName)/\$(Configuration)"" - libdirs="${libdirs}${libdirs:+;}"${opt}/\$(PlatformName)"" - fi - ;; - -l*) libs="${libs}${libs:+ }${opt##-l}.lib" - ;; - -*) die_unknown $opt - ;; - *) - # The paths in file_list are fixed outside of the loop. - file_list[${#file_list[@]}]="$opt" - case "$opt" in - *.asm|*.[Ss]) uses_asm=true - ;; - esac - ;; - esac -done - -# Make one call to fix_path for file_list to improve performance. -fix_file_list file_list - -outfile=${outfile:-/dev/stdout} -guid=${guid:-`generate_uuid`} -uses_asm=${uses_asm:-false} - -[ -n "$name" ] || die "Project name (--name) must be specified!" -[ -n "$target" ] || die "Target (--target) must be specified!" - -if ${use_static_runtime:-false}; then - release_runtime=MultiThreaded - debug_runtime=MultiThreadedDebug - lib_sfx=mt -else - release_runtime=MultiThreadedDLL - debug_runtime=MultiThreadedDebugDLL - lib_sfx=md -fi - -# Calculate debug lib names: If a lib ends in ${lib_sfx}.lib, then rename -# it to ${lib_sfx}d.lib. This precludes linking to release libs from a -# debug exe, so this may need to be refactored later. -for lib in ${libs}; do - if [ "$lib" != "${lib%${lib_sfx}.lib}" ]; then - lib=${lib%.lib}d.lib - fi - debug_libs="${debug_libs}${debug_libs:+ }${lib}" -done -debug_libs=${debug_libs// /;} -libs=${libs// /;} - - -# List of all platforms supported for this target -case "$target" in - x86_64*) - platforms[0]="x64" - asm_Debug_cmdline="${as} -Xvc -gcv8 -f win64 ${yasmincs} "%(FullPath)"" - asm_Release_cmdline="${as} -Xvc -f win64 ${yasmincs} "%(FullPath)"" - ;; - x86*) - platforms[0]="Win32" - asm_Debug_cmdline="${as} -Xvc -gcv8 -f win32 ${yasmincs} "%(FullPath)"" - asm_Release_cmdline="${as} -Xvc -f win32 ${yasmincs} "%(FullPath)"" - ;; - arm64*) - platforms[0]="ARM64" - # As of Visual Studio 2022 17.5.5, clang-cl does not support ARM64EC. - if [ "$vs_ver" -ge 17 -a "$platform_toolset" != "ClangCl" ]; then - platforms[1]="ARM64EC" - fi - asm_Debug_cmdline="armasm64 -nologo -oldit "%(FullPath)"" - asm_Release_cmdline="armasm64 -nologo -oldit "%(FullPath)"" - ;; - arm*) - platforms[0]="ARM" - asm_Debug_cmdline="armasm -nologo -oldit "%(FullPath)"" - asm_Release_cmdline="armasm -nologo -oldit "%(FullPath)"" - ;; - *) die "Unsupported target $target!" - ;; -esac - -generate_vcxproj() { - echo "" - open_tag Project \ - DefaultTargets="Build" \ - ToolsVersion="4.0" \ - xmlns="http://schemas.microsoft.com/developer/msbuild/2003" \ - - open_tag ItemGroup \ - Label="ProjectConfigurations" - for plat in "${platforms[@]}"; do - for config in Debug Release; do - open_tag ProjectConfiguration \ - Include="$config|$plat" - tag_content Configuration $config - tag_content Platform $plat - close_tag ProjectConfiguration - done - done - close_tag ItemGroup - - open_tag PropertyGroup \ - Label="Globals" - tag_content ProjectGuid "{${guid}}" - tag_content RootNamespace ${name} - tag_content Keyword ManagedCProj - if [ $vs_ver -ge 12 ] && [ "${platforms[0]}" = "ARM" ]; then - tag_content AppContainerApplication true - # The application type can be one of "Windows Store", - # "Windows Phone" or "Windows Phone Silverlight". The - # actual value doesn't matter from the libvpx point of view, - # since a static library built for one works on the others. - # The PlatformToolset field needs to be set in sync with this; - # for Windows Store and Windows Phone Silverlight it should be - # v120 while it should be v120_wp81 if the type is Windows Phone. - tag_content ApplicationType "Windows Store" - tag_content ApplicationTypeRevision 8.1 - fi - if [ "${platforms[0]}" = "ARM64" ]; then - # Require the first Visual Studio version to have ARM64 support. - tag_content MinimumVisualStudioVersion 15.9 - fi - if [ $vs_ver -eq 15 ] && [ "${platforms[0]}" = "ARM64" ]; then - # Since VS 15 does not have a 'use latest SDK version' facility, - # specifically require the contemporaneous SDK with official ARM64 - # support. - tag_content WindowsTargetPlatformVersion 10.0.17763.0 - fi - close_tag PropertyGroup - - tag Import \ - Project="\$(VCTargetsPath)\\Microsoft.Cpp.Default.props" - - for plat in "${platforms[@]}"; do - for config in Release Debug; do - open_tag PropertyGroup \ - Condition="'\$(Configuration)|\$(Platform)'=='$config|$plat'" \ - Label="Configuration" - if [ "$proj_kind" = "exe" ]; then - tag_content ConfigurationType Application - elif [ "$proj_kind" = "dll" ]; then - tag_content ConfigurationType DynamicLibrary - else - tag_content ConfigurationType StaticLibrary - fi - if [ -n "$platform_toolset" ]; then - tag_content PlatformToolset "$platform_toolset" - else - if [ "$vs_ver" = "14" ]; then - tag_content PlatformToolset v140 - fi - if [ "$vs_ver" = "15" ]; then - tag_content PlatformToolset v141 - fi - if [ "$vs_ver" = "16" ]; then - tag_content PlatformToolset v142 - fi - if [ "$vs_ver" = "17" ]; then - tag_content PlatformToolset v143 - fi - fi - tag_content CharacterSet Unicode - if [ "$config" = "Release" ]; then - tag_content WholeProgramOptimization true - fi - close_tag PropertyGroup - done - done - - tag Import \ - Project="\$(VCTargetsPath)\\Microsoft.Cpp.props" - - open_tag ImportGroup \ - Label="PropertySheets" - tag Import \ - Project="\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props" \ - Condition="exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')" \ - Label="LocalAppDataPlatform" - close_tag ImportGroup - - tag PropertyGroup \ - Label="UserMacros" - - for plat in "${platforms[@]}"; do - plat_no_ws=`echo $plat | sed 's/[^A-Za-z0-9_]/_/g'` - for config in Debug Release; do - open_tag PropertyGroup \ - Condition="'\$(Configuration)|\$(Platform)'=='$config|$plat'" - tag_content OutDir "\$(SolutionDir)$plat_no_ws\\\$(Configuration)\\" - tag_content IntDir "$plat_no_ws\\\$(Configuration)\\${name}\\" - if [ "$proj_kind" == "lib" ]; then - if [ "$config" == "Debug" ]; then - config_suffix=d - else - config_suffix="" - fi - tag_content TargetName "${name}${lib_sfx}${config_suffix}" - fi - close_tag PropertyGroup - done - done - - for plat in "${platforms[@]}"; do - for config in Debug Release; do - open_tag ItemDefinitionGroup \ - Condition="'\$(Configuration)|\$(Platform)'=='$config|$plat'" - if [ "$name" == "vpx" ]; then - hostplat=$plat - if [ "$hostplat" == "ARM" ]; then - hostplat=Win32 - fi - fi - open_tag ClCompile - if [ "$config" = "Debug" ]; then - opt=Disabled - runtime=$debug_runtime - curlibs=$debug_libs - debug=_DEBUG - else - opt=MaxSpeed - runtime=$release_runtime - curlibs=$libs - tag_content FavorSizeOrSpeed Speed - debug=NDEBUG - fi - extradefines=";$defines" - tag_content Optimization $opt - tag_content AdditionalIncludeDirectories "$incs;%(AdditionalIncludeDirectories)" - tag_content PreprocessorDefinitions "WIN32;$debug;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE$extradefines;%(PreprocessorDefinitions)" - tag_content RuntimeLibrary $runtime - tag_content WarningLevel Level3 - if ${werror:-false}; then - tag_content TreatWarningAsError true - fi - if [ $vs_ver -ge 11 ]; then - # We need to override the defaults for these settings - # if AppContainerApplication is set. - tag_content CompileAsWinRT false - tag_content PrecompiledHeader NotUsing - tag_content SDLCheck false - fi - close_tag ClCompile - case "$proj_kind" in - exe) - open_tag Link - tag_content GenerateDebugInformation true - # Console is the default normally, but if - # AppContainerApplication is set, we need to override it. - tag_content SubSystem Console - close_tag Link - ;; - dll) - open_tag Link - tag_content GenerateDebugInformation true - tag_content ModuleDefinitionFile $module_def - close_tag Link - ;; - lib) - ;; - esac - close_tag ItemDefinitionGroup - done - - done - - open_tag ItemGroup - generate_filter "Source Files" "c;cc;cpp;def;odl;idl;hpj;bat;asm;asmx;s;S" - close_tag ItemGroup - open_tag ItemGroup - generate_filter "Header Files" "h;hm;inl;inc;xsd" - close_tag ItemGroup - open_tag ItemGroup - generate_filter "Build Files" "mk" - close_tag ItemGroup - open_tag ItemGroup - generate_filter "References" "vcxproj" - close_tag ItemGroup - - tag Import \ - Project="\$(VCTargetsPath)\\Microsoft.Cpp.targets" - - open_tag ImportGroup \ - Label="ExtensionTargets" - close_tag ImportGroup - - close_tag Project - - # This must be done from within the {} subshell - echo "Ignored files list (${#file_list[@]} items) is:" >&2 - for f in "${file_list[@]}"; do - echo " $f" >&2 - done -} - -# This regexp doesn't catch most of the strings in the vcxproj format, -# since they're like path instead of -# as previously. It still seems to work ok despite this. -generate_vcxproj | - sed -e '/"/s;\([^ "]\)/;\1\\;g' | - sed -e '/xmlns/s;\\;/;g' > ${outfile} - -exit diff --git a/presentation/src/main/cpp/third_party/libvpx/build/make/ios-Info.plist b/presentation/src/main/cpp/third_party/libvpx/build/make/ios-Info.plist deleted file mode 100644 index d157b11a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build/make/ios-Info.plist +++ /dev/null @@ -1,37 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - VPX - CFBundleIdentifier - org.webmproject.VPX - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - VPX - CFBundlePackageType - FMWK - CFBundleShortVersionString - ${VERSION} - CFBundleSignature - ???? - CFBundleSupportedPlatforms - - iPhoneOS - - CFBundleVersion - ${VERSION} - MinimumOSVersion - ${IOS_VERSION_MIN} - UIDeviceFamily - - 1 - 2 - - VPXFullVersion - ${FULLVERSION} - - diff --git a/presentation/src/main/cpp/third_party/libvpx/build/make/iosbuild.sh b/presentation/src/main/cpp/third_party/libvpx/build/make/iosbuild.sh deleted file mode 100644 index 978ffbbb..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build/make/iosbuild.sh +++ /dev/null @@ -1,384 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2014 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## -## This script generates 'VPX.framework'. An iOS app can encode and decode VPx -## video by including 'VPX.framework'. -## -## Run iosbuild.sh to create 'VPX.framework' in the current directory. -## -set -e -devnull='> /dev/null 2>&1' - -BUILD_ROOT="_iosbuild" -CONFIGURE_ARGS="--disable-docs - --disable-examples - --disable-libyuv - --disable-unit-tests" -DIST_DIR="_dist" -FRAMEWORK_DIR="VPX.framework" -FRAMEWORK_LIB="VPX.framework/VPX" -HEADER_DIR="${FRAMEWORK_DIR}/Headers/vpx" -SCRIPT_DIR=$(dirname "$0") -LIBVPX_SOURCE_DIR=$(cd ${SCRIPT_DIR}/../..; pwd) -LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo) -ORIG_PWD="$(pwd)" -ARM_TARGETS="arm64-darwin-gcc - armv7-darwin-gcc - armv7s-darwin-gcc" -SIM_TARGETS="x86-iphonesimulator-gcc - x86_64-iphonesimulator-gcc" -OSX_TARGETS="x86-darwin16-gcc - x86_64-darwin16-gcc" -TARGETS="${ARM_TARGETS} ${SIM_TARGETS}" - -# Configures for the target specified by $1, and invokes make with the dist -# target using $DIST_DIR as the distribution output directory. -build_target() { - local target="$1" - local old_pwd="$(pwd)" - local target_specific_flags="" - - vlog "***Building target: ${target}***" - - case "${target}" in - x86-*) - target_specific_flags="--enable-pic" - vlog "Enabled PIC for ${target}" - ;; - esac - - mkdir "${target}" - cd "${target}" - eval "${LIBVPX_SOURCE_DIR}/configure" --target="${target}" \ - ${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS} ${target_specific_flags} \ - ${devnull} - export DIST_DIR - eval make dist ${devnull} - cd "${old_pwd}" - - vlog "***Done building target: ${target}***" -} - -# Returns the preprocessor symbol for the target specified by $1. -target_to_preproc_symbol() { - target="$1" - case "${target}" in - arm64-*) - echo "__aarch64__" - ;; - armv7-*) - echo "__ARM_ARCH_7A__" - ;; - armv7s-*) - echo "__ARM_ARCH_7S__" - ;; - x86-*) - echo "__i386__" - ;; - x86_64-*) - echo "__x86_64__" - ;; - *) - echo "#error ${target} unknown/unsupported" - return 1 - ;; - esac -} - -# Create a vpx_config.h shim that, based on preprocessor settings for the -# current target CPU, includes the real vpx_config.h for the current target. -# $1 is the list of targets. -create_vpx_framework_config_shim() { - local targets="$1" - local config_file="${HEADER_DIR}/vpx_config.h" - local preproc_symbol="" - local target="" - local include_guard="VPX_FRAMEWORK_HEADERS_VPX_VPX_CONFIG_H_" - - local file_header="/* - * Copyright (c) $(date +%Y) The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* GENERATED FILE: DO NOT EDIT! */ - -#ifndef ${include_guard} -#define ${include_guard} - -#if defined" - - printf "%s" "${file_header}" > "${config_file}" - for target in ${targets}; do - preproc_symbol=$(target_to_preproc_symbol "${target}") - printf " ${preproc_symbol}\n" >> "${config_file}" - printf "#define VPX_FRAMEWORK_TARGET \"${target}\"\n" >> "${config_file}" - printf "#include \"VPX/vpx/${target}/vpx_config.h\"\n" >> "${config_file}" - printf "#elif defined" >> "${config_file}" - mkdir "${HEADER_DIR}/${target}" - cp -p "${BUILD_ROOT}/${target}/vpx_config.h" "${HEADER_DIR}/${target}" - done - - # Consume the last line of output from the loop: We don't want it. - sed -i.bak -e '$d' "${config_file}" - rm "${config_file}.bak" - - printf "#endif\n\n" >> "${config_file}" - printf "#endif // ${include_guard}" >> "${config_file}" -} - -# Verifies that $FRAMEWORK_LIB fat library contains requested builds. -verify_framework_targets() { - local requested_cpus="" - local cpu="" - - # Extract CPU from full target name. - for target; do - cpu="${target%%-*}" - if [ "${cpu}" = "x86" ]; then - # lipo -info outputs i386 for libvpx x86 targets. - cpu="i386" - fi - requested_cpus="${requested_cpus}${cpu} " - done - - # Get target CPUs present in framework library. - local targets_built=$(${LIPO} -info ${FRAMEWORK_LIB}) - - # $LIPO -info outputs a string like the following: - # Architectures in the fat file: $FRAMEWORK_LIB - # Capture only the architecture strings. - targets_built=${targets_built##*: } - - # Sort CPU strings to make the next step a simple string compare. - local actual=$(echo ${targets_built} | tr " " "\n" | sort | tr "\n" " ") - local requested=$(echo ${requested_cpus} | tr " " "\n" | sort | tr "\n" " ") - - vlog "Requested ${FRAMEWORK_LIB} CPUs: ${requested}" - vlog "Actual ${FRAMEWORK_LIB} CPUs: ${actual}" - - if [ "${requested}" != "${actual}" ]; then - elog "Actual ${FRAMEWORK_LIB} targets do not match requested target list." - elog " Requested target CPUs: ${requested}" - elog " Actual target CPUs: ${actual}" - return 1 - fi -} - -# Configures and builds each target specified by $1, and then builds -# VPX.framework. -build_framework() { - local lib_list="" - local targets="$1" - local target="" - local target_dist_dir="" - - # Clean up from previous build(s). - rm -rf "${BUILD_ROOT}" "${FRAMEWORK_DIR}" - - # Create output dirs. - mkdir -p "${BUILD_ROOT}" - mkdir -p "${HEADER_DIR}" - - cd "${BUILD_ROOT}" - - for target in ${targets}; do - build_target "${target}" - target_dist_dir="${BUILD_ROOT}/${target}/${DIST_DIR}" - if [ "${ENABLE_SHARED}" = "yes" ]; then - local suffix="dylib" - else - local suffix="a" - fi - lib_list="${lib_list} ${target_dist_dir}/lib/libvpx.${suffix}" - done - - cd "${ORIG_PWD}" - - # The basic libvpx API includes are all the same; just grab the most recent - # set. - cp -p "${target_dist_dir}"/include/vpx/* "${HEADER_DIR}" - - # Build the fat library. - ${LIPO} -create ${lib_list} -output ${FRAMEWORK_DIR}/VPX - - # Create the vpx_config.h shim that allows usage of vpx_config.h from - # within VPX.framework. - create_vpx_framework_config_shim "${targets}" - - # Copy in vpx_version.h. - cp -p "${BUILD_ROOT}/${target}/vpx_version.h" "${HEADER_DIR}" - - if [ "${ENABLE_SHARED}" = "yes" ]; then - # Adjust the dylib's name so dynamic linking in apps works as expected. - install_name_tool -id '@rpath/VPX.framework/VPX' ${FRAMEWORK_DIR}/VPX - - # Copy in Info.plist. - cat "${SCRIPT_DIR}/ios-Info.plist" \ - | sed "s/\${FULLVERSION}/${FULLVERSION}/g" \ - | sed "s/\${VERSION}/${VERSION}/g" \ - | sed "s/\${IOS_VERSION_MIN}/${IOS_VERSION_MIN}/g" \ - > "${FRAMEWORK_DIR}/Info.plist" - fi - - # Confirm VPX.framework/VPX contains the targets requested. - verify_framework_targets ${targets} - - vlog "Created fat library ${FRAMEWORK_LIB} containing:" - for lib in ${lib_list}; do - vlog " $(echo ${lib} | awk -F / '{print $2, $NF}')" - done -} - -# Trap function. Cleans up the subtree used to build all targets contained in -# $TARGETS. -cleanup() { - local res=$? - cd "${ORIG_PWD}" - - if [ $res -ne 0 ]; then - elog "build exited with error ($res)" - fi - - if [ "${PRESERVE_BUILD_OUTPUT}" != "yes" ]; then - rm -rf "${BUILD_ROOT}" - fi -} - -print_list() { - local indent="$1" - shift - local list="$@" - for entry in ${list}; do - echo "${indent}${entry}" - done -} - -iosbuild_usage() { -cat << EOF - Usage: ${0##*/} [arguments] - --help: Display this message and exit. - --enable-shared: Build a dynamic framework for use on iOS 8 or later. - --extra-configure-args : Extra args to pass when configuring libvpx. - --macosx: Uses darwin16 targets instead of iphonesimulator targets for x86 - and x86_64. Allows linking to framework when builds target MacOSX - instead of iOS. - --preserve-build-output: Do not delete the build directory. - --show-build-output: Show output from each library build. - --targets : Override default target list. Defaults: -$(print_list " " ${TARGETS}) - --test-link: Confirms all targets can be linked. Functionally identical to - passing --enable-examples via --extra-configure-args. - --verbose: Output information about the environment and each stage of the - build. -EOF -} - -elog() { - echo "${0##*/} failed because: $@" 1>&2 -} - -vlog() { - if [ "${VERBOSE}" = "yes" ]; then - echo "$@" - fi -} - -trap cleanup EXIT - -# Parse the command line. -while [ -n "$1" ]; do - case "$1" in - --extra-configure-args) - EXTRA_CONFIGURE_ARGS="$2" - shift - ;; - --help) - iosbuild_usage - exit - ;; - --enable-shared) - ENABLE_SHARED=yes - ;; - --preserve-build-output) - PRESERVE_BUILD_OUTPUT=yes - ;; - --show-build-output) - devnull= - ;; - --test-link) - EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --enable-examples" - ;; - --targets) - TARGETS="$2" - shift - ;; - --macosx) - TARGETS="${ARM_TARGETS} ${OSX_TARGETS}" - ;; - --verbose) - VERBOSE=yes - ;; - *) - iosbuild_usage - exit 1 - ;; - esac - shift -done - -if [ "${ENABLE_SHARED}" = "yes" ]; then - CONFIGURE_ARGS="--enable-shared ${CONFIGURE_ARGS}" -fi - -FULLVERSION=$("${SCRIPT_DIR}"/version.sh --bare "${LIBVPX_SOURCE_DIR}") -VERSION=$(echo "${FULLVERSION}" | sed -E 's/^v([0-9]+\.[0-9]+\.[0-9]+).*$/\1/') - -if [ "$ENABLE_SHARED" = "yes" ]; then - IOS_VERSION_OPTIONS="--enable-shared" - IOS_VERSION_MIN="8.0" -else - IOS_VERSION_OPTIONS="" - IOS_VERSION_MIN="7.0" -fi - -if [ "${VERBOSE}" = "yes" ]; then -cat << EOF - BUILD_ROOT=${BUILD_ROOT} - DIST_DIR=${DIST_DIR} - CONFIGURE_ARGS=${CONFIGURE_ARGS} - EXTRA_CONFIGURE_ARGS=${EXTRA_CONFIGURE_ARGS} - FRAMEWORK_DIR=${FRAMEWORK_DIR} - FRAMEWORK_LIB=${FRAMEWORK_LIB} - HEADER_DIR=${HEADER_DIR} - LIBVPX_SOURCE_DIR=${LIBVPX_SOURCE_DIR} - LIPO=${LIPO} - MAKEFLAGS=${MAKEFLAGS} - ORIG_PWD=${ORIG_PWD} - PRESERVE_BUILD_OUTPUT=${PRESERVE_BUILD_OUTPUT} - TARGETS="$(print_list "" ${TARGETS})" - ENABLE_SHARED=${ENABLE_SHARED} - OSX_TARGETS="${OSX_TARGETS}" - SIM_TARGETS="${SIM_TARGETS}" - SCRIPT_DIR="${SCRIPT_DIR}" - FULLVERSION="${FULLVERSION}" - VERSION="${VERSION}" - IOS_VERSION_MIN="${IOS_VERSION_MIN}" -EOF -fi - -build_framework "${TARGETS}" -echo "Successfully built '${FRAMEWORK_DIR}' for:" -print_list "" ${TARGETS} diff --git a/presentation/src/main/cpp/third_party/libvpx/build/make/msvs_common.sh b/presentation/src/main/cpp/third_party/libvpx/build/make/msvs_common.sh deleted file mode 100644 index 3989fec0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build/make/msvs_common.sh +++ /dev/null @@ -1,124 +0,0 @@ -#!/bin/bash -## -## Copyright (c) 2014 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -shell_name="$(uname -o 2>/dev/null)" -if [[ "$shell_name" = "Cygwin" || "$shell_name" = "Msys" ]] \ - && cygpath --help >/dev/null 2>&1; then - FIXPATH='cygpath -m' -else - FIXPATH='echo_path' -fi - -die() { - echo "${self_basename}: $@" >&2 - exit 1 -} - -die_unknown(){ - echo "Unknown option \"$1\"." >&2 - echo "See ${self_basename} --help for available options." >&2 - exit 1 -} - -echo_path() { - for path; do - echo "$path" - done -} - -# Output one, possibly changed based on the system, path per line. -fix_path() { - $FIXPATH "$@" -} - -# Corrects the paths in file_list in one pass for efficiency. -# $1 is the name of the array to be modified. -fix_file_list() { - if [ "${FIXPATH}" = "echo_path" ] ; then - # When used with echo_path, fix_file_list is a no-op. Avoid warning about - # unsupported 'declare -n' when it is not important. - return 0 - elif [ "${BASH_VERSINFO}" -lt 4 ] ; then - echo "Cygwin path conversion has failed. Please use a version of bash" - echo "which supports nameref (-n), introduced in bash 4.3" - return 1 - fi - declare -n array_ref=$1 - files=$(fix_path "${array_ref[@]}") - local IFS=$'\n' - array_ref=($files) -} - -generate_uuid() { - local hex="0123456789ABCDEF" - local i - local uuid="" - local j - #93995380-89BD-4b04-88EB-625FBE52EBFB - for ((i=0; i<32; i++)); do - (( j = $RANDOM % 16 )) - uuid="${uuid}${hex:$j:1}" - done - echo "${uuid:0:8}-${uuid:8:4}-${uuid:12:4}-${uuid:16:4}-${uuid:20:12}" -} - -indent1=" " -indent="" -indent_push() { - indent="${indent}${indent1}" -} -indent_pop() { - indent="${indent%${indent1}}" -} - -tag_attributes() { - for opt in "$@"; do - optval="${opt#*=}" - [ -n "${optval}" ] || - die "Missing attribute value in '$opt' while generating $tag tag" - echo "${indent}${opt%%=*}=\"${optval}\"" - done -} - -open_tag() { - local tag=$1 - shift - if [ $# -ne 0 ]; then - echo "${indent}<${tag}" - indent_push - tag_attributes "$@" - echo "${indent}>" - else - echo "${indent}<${tag}>" - indent_push - fi -} - -close_tag() { - local tag=$1 - indent_pop - echo "${indent}" -} - -tag() { - local tag=$1 - shift - if [ $# -ne 0 ]; then - echo "${indent}<${tag}" - indent_push - tag_attributes "$@" - indent_pop - echo "${indent}/>" - else - echo "${indent}<${tag}/>" - fi -} - diff --git a/presentation/src/main/cpp/third_party/libvpx/build/make/rtcd.pl b/presentation/src/main/cpp/third_party/libvpx/build/make/rtcd.pl deleted file mode 100644 index 9f6aad8f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build/make/rtcd.pl +++ /dev/null @@ -1,545 +0,0 @@ -#!/usr/bin/env perl -## -## Copyright (c) 2017 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -no strict 'refs'; -use warnings; -use Getopt::Long; -Getopt::Long::Configure("auto_help") if $Getopt::Long::VERSION > 2.32; - -my %ALL_FUNCS = (); -my @ALL_ARCHS; -my @ALL_FORWARD_DECLS; -my @REQUIRES; - -my %opts = (); -my %disabled = (); -my %required = (); - -my @argv; -foreach (@ARGV) { - $disabled{$1} = 1, next if /--disable-(.*)/; - $required{$1} = 1, next if /--require-(.*)/; - push @argv, $_; -} - -# NB: use GetOptions() instead of GetOptionsFromArray() for compatibility. -@ARGV = @argv; -GetOptions( - \%opts, - 'arch=s', - 'sym=s', - 'config=s', -); - -foreach my $opt (qw/arch config/) { - if (!defined($opts{$opt})) { - warn "--$opt is required!\n"; - Getopt::Long::HelpMessage('-exit' => 1); - } -} - -foreach my $defs_file (@ARGV) { - if (!-f $defs_file) { - warn "$defs_file: $!\n"; - Getopt::Long::HelpMessage('-exit' => 1); - } -} - -open CONFIG_FILE, $opts{config} or - die "Error opening config file '$opts{config}': $!\n"; - -my %config = (); -while () { - next if !/^(?:CONFIG_|HAVE_)/; - chomp; - my @pair = split /=/; - $config{$pair[0]} = $pair[1]; -} -close CONFIG_FILE; - -# -# Routines for the RTCD DSL to call -# -sub vpx_config($) { - return (defined $config{$_[0]}) ? $config{$_[0]} : ""; -} - -sub specialize { - if (@_ <= 1) { - die "'specialize' must be called with a function name and at least one ", - "architecture ('C' is implied): \n@_\n"; - } - my $fn=$_[0]; - shift; - foreach my $opt (@_) { - eval "\$${fn}_${opt}=${fn}_${opt}"; - } -} - -sub add_proto { - my $fn = splice(@_, -2, 1); - $ALL_FUNCS{$fn} = \@_; - specialize $fn, "c"; -} - -sub require { - foreach my $fn (keys %ALL_FUNCS) { - foreach my $opt (@_) { - my $ofn = eval "\$${fn}_${opt}"; - next if !$ofn; - - # if we already have a default, then we can disable it, as we know - # we can do better. - my $best = eval "\$${fn}_default"; - if ($best) { - my $best_ofn = eval "\$${best}"; - if ($best_ofn && "$best_ofn" ne "$ofn") { - eval "\$${best}_link = 'false'"; - } - } - eval "\$${fn}_default=${fn}_${opt}"; - eval "\$${fn}_${opt}_link='true'"; - } - } -} - -sub forward_decls { - push @ALL_FORWARD_DECLS, @_; -} - -# -# Include the user's directives -# -foreach my $f (@ARGV) { - open FILE, "<", $f or die "cannot open $f: $!\n"; - my $contents = join('', ); - close FILE; - eval $contents or warn "eval failed: $@\n"; -} - -# -# Process the directives according to the command line -# -sub process_forward_decls() { - foreach (@ALL_FORWARD_DECLS) { - $_->(); - } -} - -sub determine_indirection { - vpx_config("CONFIG_RUNTIME_CPU_DETECT") eq "yes" or &require(@ALL_ARCHS); - foreach my $fn (keys %ALL_FUNCS) { - my $n = ""; - my @val = @{$ALL_FUNCS{$fn}}; - my $args = pop @val; - my $rtyp = "@val"; - my $dfn = eval "\$${fn}_default"; - $dfn = eval "\$${dfn}"; - foreach my $opt (@_) { - my $ofn = eval "\$${fn}_${opt}"; - next if !$ofn; - my $link = eval "\$${fn}_${opt}_link"; - next if $link && $link eq "false"; - $n .= "x"; - } - if ($n eq "x") { - eval "\$${fn}_indirect = 'false'"; - } else { - eval "\$${fn}_indirect = 'true'"; - } - } -} - -sub declare_function_pointers { - foreach my $fn (sort keys %ALL_FUNCS) { - my @val = @{$ALL_FUNCS{$fn}}; - my $args = pop @val; - my $rtyp = "@val"; - my $dfn = eval "\$${fn}_default"; - $dfn = eval "\$${dfn}"; - foreach my $opt (@_) { - my $ofn = eval "\$${fn}_${opt}"; - next if !$ofn; - print "$rtyp ${ofn}($args);\n"; - } - if (eval "\$${fn}_indirect" eq "false") { - print "#define ${fn} ${dfn}\n"; - } else { - print "RTCD_EXTERN $rtyp (*${fn})($args);\n"; - } - print "\n"; - } -} - -sub set_function_pointers { - foreach my $fn (sort keys %ALL_FUNCS) { - my @val = @{$ALL_FUNCS{$fn}}; - my $args = pop @val; - my $rtyp = "@val"; - my $dfn = eval "\$${fn}_default"; - $dfn = eval "\$${dfn}"; - if (eval "\$${fn}_indirect" eq "true") { - print " $fn = $dfn;\n"; - foreach my $opt (@_) { - my $ofn = eval "\$${fn}_${opt}"; - next if !$ofn; - next if "$ofn" eq "$dfn"; - my $link = eval "\$${fn}_${opt}_link"; - next if $link && $link eq "false"; - my $cond = eval "\$have_${opt}"; - print " if (${cond}) $fn = $ofn;\n" - } - } - } -} - -sub filter { - my @filtered; - foreach (@_) { push @filtered, $_ unless $disabled{$_}; } - return @filtered; -} - -# -# Helper functions for generating the arch specific RTCD files -# -sub common_top() { - my $include_guard = uc($opts{sym})."_H_"; - my @time = localtime; - my $year = $time[5] + 1900; - print <) { - if (/HAVE_DSPR2=yes/) { - $have_dspr2 = 1; - } - if (/HAVE_MSA=yes/) { - $have_msa = 1; - } - if (/HAVE_MMI=yes/) { - $have_mmi = 1; - } - } - close CONFIG_FILE; - if ($have_dspr2 == 1) { - @ALL_ARCHS = filter("$opts{arch}", qw/dspr2/); - } elsif ($have_msa == 1 && $have_mmi == 1) { - @ALL_ARCHS = filter("$opts{arch}", qw/mmi msa/); - } elsif ($have_msa == 1) { - @ALL_ARCHS = filter("$opts{arch}", qw/msa/); - } elsif ($have_mmi == 1) { - @ALL_ARCHS = filter("$opts{arch}", qw/mmi/); - } else { - unoptimized; - } - mips; -} elsif ($opts{arch} =~ /armv7\w?/) { - @ALL_ARCHS = filter(qw/neon_asm neon/); - arm; -} elsif ($opts{arch} eq 'armv8' || $opts{arch} eq 'arm64' ) { - @ALL_ARCHS = filter(qw/neon neon_dotprod neon_i8mm sve sve2/); - @REQUIRES = filter(qw/neon/); - &require(@REQUIRES); - arm; -} elsif ($opts{arch} =~ /^ppc/ ) { - @ALL_ARCHS = filter(qw/vsx/); - ppc; -} elsif ($opts{arch} =~ /loongarch/ ) { - @ALL_ARCHS = filter(qw/lsx lasx/); - loongarch; -} else { - unoptimized; -} - -__END__ - -=head1 NAME - -rtcd - - -=head1 SYNOPSIS - -Usage: rtcd.pl [options] FILE - -See 'perldoc rtcd.pl' for more details. - -=head1 DESCRIPTION - -Reads the Run Time CPU Detections definitions from FILE and generates a -C header file on stdout. - -=head1 OPTIONS - -Options: - --arch=ARCH Architecture to generate defs for (required) - --disable-EXT Disable support for EXT extensions - --require-EXT Require support for EXT extensions - --sym=SYMBOL Unique symbol to use for RTCD initialization function - --config=FILE File with CONFIG_FOO=yes lines to parse diff --git a/presentation/src/main/cpp/third_party/libvpx/build/make/thumb.pm b/presentation/src/main/cpp/third_party/libvpx/build/make/thumb.pm deleted file mode 100644 index ef4b3167..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build/make/thumb.pm +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env perl -## -## Copyright (c) 2013 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -package thumb; - -sub FixThumbInstructions($) -{ - # Write additions with shifts, such as "add r10, r11, lsl #8", - # in three operand form, "add r10, r10, r11, lsl #8". - s/(add\s+)(r\d+),\s*(r\d+),\s*(lsl #\d+)/$1$2, $2, $3, $4/g; - - # Convert additions with a non-constant shift into a sequence - # with left shift, addition and a right shift (to restore the - # register to the original value). Currently the right shift - # isn't necessary in the code base since the values in these - # registers aren't used, but doing the shift for consistency. - # This converts instructions such as "add r12, r12, r5, lsl r4" - # into the sequence "lsl r5, r4", "add r12, r12, r5", "lsr r5, r4". - s/^(\s*)(add)(\s+)(r\d+),\s*(r\d+),\s*(r\d+),\s*lsl (r\d+)/$1lsl$3$6, $7\n$1$2$3$4, $5, $6\n$1lsr$3$6, $7/g; - - # Convert loads with right shifts in the indexing into a - # sequence of an add, load and sub. This converts - # "ldrb r4, [r9, lr, asr #1]" into "add r9, r9, lr, asr #1", - # "ldrb r9, [r9]", "sub r9, r9, lr, asr #1". - s/^(\s*)(ldrb)(\s+)(r\d+),\s*\[(\w+),\s*(\w+),\s*(asr #\d+)\]/$1add $3$5, $5, $6, $7\n$1$2$3$4, [$5]\n$1sub $3$5, $5, $6, $7/g; - - # Convert register indexing with writeback into a separate add - # instruction. This converts "ldrb r12, [r1, r2]!" into - # "ldrb r12, [r1, r2]", "add r1, r1, r2". - s/^(\s*)(ldrb)(\s+)(r\d+),\s*\[(\w+),\s*(\w+)\]!/$1$2$3$4, [$5, $6]\n$1add $3$5, $6/g; - - # Convert negative register indexing into separate sub/add instructions. - # This converts "ldrne r4, [src, -pstep, lsl #1]" into - # "subne src, src, pstep, lsl #1", "ldrne r4, [src]", - # "addne src, src, pstep, lsl #1". In a couple of cases where - # this is used, it's used for two subsequent load instructions, - # where a hand-written version of it could merge two subsequent - # add and sub instructions. - s/^(\s*)((ldr|str|pld)(ne)?)(\s+)(r\d+,\s*)?\[(\w+), -([^\]]+)\]/$1sub$4$5$7, $7, $8\n$1$2$5$6\[$7\]\n$1add$4$5$7, $7, $8/g; - - # Convert register post indexing to a separate add instruction. - # This converts "ldrneb r9, [r0], r2" into "ldrneb r9, [r0]", - # "addne r0, r0, r2". - s/^(\s*)((ldr|str)(ne)?[bhd]?)(\s+)(\w+),(\s*\w+,)?\s*\[(\w+)\],\s*(\w+)/$1$2$5$6,$7 [$8]\n$1add$4$5$8, $8, $9/g; - - # Convert "mov pc, lr" into "bx lr", since the former only works - # for switching from arm to thumb (and only in armv7), but not - # from thumb to arm. - s/mov(\s*)pc\s*,\s*lr/bx$1lr/g; -} - -1; diff --git a/presentation/src/main/cpp/third_party/libvpx/build/make/version.sh b/presentation/src/main/cpp/third_party/libvpx/build/make/version.sh deleted file mode 100644 index 8f717cc9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build/make/version.sh +++ /dev/null @@ -1,81 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - - - -for opt in "$@"; do - optval="${opt#*=}" - case "$opt" in - --bare) bare=true ;; - *) break ;; - esac - shift -done -source_path=${1:-.} -out_file=${2} -id=${3:-VERSION_STRING} - -git_version_id="" -if [ -e "${source_path}/.git" ]; then - # Source Path is a git working copy. Check for local modifications. - # Note that git submodules may have a file as .git, not a directory. - export GIT_DIR="${source_path}/.git" - git_version_id=`git describe --match=v[0-9]* 2>/dev/null` -fi - -changelog_version="" -for p in "${source_path}" "${source_path}/.."; do - if [ -z "$git_version_id" -a -f "${p}/CHANGELOG" ]; then - changelog_version=`head -n1 "${p}/CHANGELOG" | awk '{print $2}'` - changelog_version="${changelog_version}" - break - fi -done -version_str="${changelog_version}${git_version_id}" -bare_version=${version_str#v} -major_version=${bare_version%%.*} -bare_version=${bare_version#*.} -minor_version=${bare_version%%.*} -bare_version=${bare_version#*.} -patch_version=${bare_version%%-*} -bare_version=${bare_version#${patch_version}} -extra_version=${bare_version##-} - -#since they'll be used as integers below make sure they are or force to 0 -for v in major_version minor_version patch_version; do - if eval echo \$$v |grep -E -q '[^[:digit:]]'; then - eval $v=0 - fi -done - -if [ ${bare} ]; then - echo "${changelog_version}${git_version_id}" > $$.tmp -else - cat<$$.tmp -// This file is generated. Do not edit. -#ifndef VPX_VERSION_H_ -#define VPX_VERSION_H_ -#define VERSION_MAJOR $major_version -#define VERSION_MINOR $minor_version -#define VERSION_PATCH $patch_version -#define VERSION_EXTRA "$extra_version" -#define VERSION_PACKED ((VERSION_MAJOR<<16)|(VERSION_MINOR<<8)|(VERSION_PATCH)) -#define ${id}_NOSP "${version_str}" -#define ${id} " ${version_str}" -#endif // VPX_VERSION_H_ -EOF -fi -if [ -n "$out_file" ]; then -diff $$.tmp ${out_file} >/dev/null 2>&1 || cat $$.tmp > ${out_file} -else -cat $$.tmp -fi -rm $$.tmp diff --git a/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/cur_frame_16x16.txt b/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/cur_frame_16x16.txt deleted file mode 100644 index c2646393..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/cur_frame_16x16.txt +++ /dev/null @@ -1,2 +0,0 @@ -486,720 -230,207,226,208,198,205,214,224,228,181,208,205,211,218,218,221,213,193,213,233,219,206,226,199,199,189,211,190,204,231,229,236,218,227,194,229,222,227,210,219,237,219,225,227,212,207,197,203,207,216,238,208,233,222,213,212,213,220,221,222,191,215,237,211,226,234,208,214,239,210,223,224,236,248,233,216,237,211,198,227,231,233,236,238,239,224,235,208,219,229,212,241,243,218,233,225,231,230,224,221,248,209,241,215,237,216,244,241,218,221,240,211,239,231,237,231,221,219,240,219,232,222,223,255,229,245,243,242,245,246,217,234,243,222,213,239,230,231,230,242,248,225,238,236,223,214,229,216,240,223,212,228,236,219,254,240,222,217,246,228,215,230,255,226,230,248,250,254,234,235,232,243,237,255,253,239,239,251,251,252,238,241,240,251,240,243,223,246,246,249,235,233,228,246,232,236,234,255,253,221,244,237,252,245,253,252,221,251,255,255,233,243,243,246,221,234,238,252,252,215,242,255,229,243,255,251,236,231,241,246,237,225,244,229,242,239,234,235,251,237,253,245,251,230,220,239,224,255,244,249,249,249,255,249,236,240,218,248,247,246,235,250,250,230,239,228,238,250,242,241,232,237,238,246,255,243,232,251,252,244,237,249,247,242,246,254,246,255,247,230,235,241,236,252,245,240,244,228,241,247,231,242,242,242,255,246,236,240,245,246,235,208,219,251,251,252,251,244,240,243,230,250,227,254,224,228,249,232,255,245,248,247,241,241,245,234,194,186,231,214,243,230,243,249,248,190,175,174,161,130,37,204,246,253,250,230,253,239,247,181,213,245,228,251,255,253,233,249,246,252,228,228,219,241,235,245,211,228,228,248,254,247,239,251,232,231,250,246,227,237,238,251,251,242,237,240,219,155,137,131,88,97,19,109,243,243,237,242,242,254,244,245,243,237,242,225,237,219,226,242,248,244,247,253,249,229,255,251,245,255,189,192,240,228,249,248,247,237,241,240,247,247,220,250,251,255,231,251,193,103,31,14,31,31,9,13,44,26,50,35,74,113,61,72,15,35,22,59,25,24,47,38,115,112,50,34,26,59,48,65,78,66,62,38,15,54,212,243,249,236,253,254,254,244,247,239,240,243,239,249,237,240,244,252,205,186,243,200,193,210,244,243,212,235,232,189,243,236,244,234,244,235,238,237,254,249,227,231,241,246,255,236,236,241,249,241,246,253,229,243,143,99,67,6,70,201,221,250,245,233,248,209,224,198,211,232,225,217,209,255,214,121,184,220,235,232,185,230,236,237,227,213,240,222,241,226,224,215,240,238,252,243,224,222,233,236,237,213,214,214,232,229,227,224,203,222,234,209,225,226,216,202,235,208,207,233,234,230,226,215,214,214,214,241,237,214,226,214,227,205,221,222,224,193,209,209,226,213,235,212,250,180,147,118,85,99,73,79,70,109,95,116,65,100,94,108,104,79,91,75,73,126,199,206,241,239,219,246,226,216,229,213,221,214,227,222,214,207,220,226,207,213,234,199,206,213,221,203,190,198,181,183,190,196,219,207,190,170,196,190,184,208,189,220,217,106,17,8,20,16,21,8,10,0,29,18,9,14,0,11,0,15,39,2,13,4,4,41,28,7,235,225,220,231,197,218,197,225,229,195,220,207,235,222,213,217,219,210,219,207,225,192,207,211,203,205,214,204,203,219,207,207,199,206,235,223,221,198,231,232,220,211,238,234,236,216,228,226,196,202,235,234,214,231,223,213,185,220,242,252,233,221,218,229,212,206,210,197,235,222,197,223,213,209,242,197,226,211,212,216,205,229,229,231,213,235,209,237,222,230,214,241,222,235,242,228,230,229,249,227,212,207,217,227,226,237,232,223,214,208,231,240,223,230,225,239,240,221,237,228,245,241,237,224,239,249,237,230,250,228,244,239,214,247,225,226,234,243,239,225,250,248,249,226,232,237,251,226,231,236,233,248,232,240,233,249,245,236,234,227,211,245,233,234,229,237,240,218,243,237,237,216,250,253,238,249,237,245,248,247,241,247,223,231,246,249,245,244,238,223,247,230,247,252,249,210,250,243,247,253,230,255,248,243,241,246,225,254,248,242,255,239,241,233,248,255,254,255,238,249,244,250,236,253,247,252,240,248,240,238,232,252,246,251,237,231,241,248,231,252,254,243,241,245,251,242,250,212,255,245,248,235,252,243,238,250,242,253,251,251,254,238,233,254,254,243,249,252,254,239,250,241,239,243,245,238,247,243,240,242,243,239,252,238,254,226,233,252,238,245,255,234,249,253,238,226,240,253,255,249,230,232,242,251,239,240,209,246,236,235,239,244,251,241,236,236,240,255,242,228,250,239,252,231,243,253,253,226,235,237,240,237,252,239,223,252,216,231,253,235,214,213,238,230,245,210,152,148,132,97,40,203,250,242,249,234,220,240,230,182,195,242,255,250,247,223,255,252,255,235,251,213,210,245,255,253,226,244,241,252,254,236,250,254,235,226,249,255,237,218,230,239,237,252,252,242,221,120,118,110,105,120,44,129,241,242,247,243,244,233,249,232,242,222,237,241,243,237,251,248,255,245,254,248,242,255,246,232,221,246,171,164,239,248,218,252,245,252,250,229,250,248,216,239,250,212,203,218,148,100,35,8,47,38,32,60,48,38,43,58,46,103,90,69,19,33,11,55,55,29,34,71,91,63,65,69,23,25,50,82,80,41,42,43,1,142,218,231,233,242,239,249,233,252,228,234,222,246,244,243,216,225,240,252,216,156,221,221,204,212,249,236,219,190,198,172,224,253,244,252,252,237,233,249,249,252,238,253,244,250,242,249,244,255,229,227,217,234,242,245,116,88,54,14,59,229,246,234,254,249,233,233,231,213,210,219,243,231,228,242,191,71,184,223,223,235,234,236,237,236,238,228,232,219,226,221,208,228,245,213,228,238,230,230,227,217,227,229,224,214,215,221,217,213,217,236,238,224,213,225,194,248,230,234,226,243,214,214,238,226,237,220,231,236,224,222,233,230,219,229,196,208,232,214,217,202,235,247,235,233,206,186,127,128,96,139,132,132,120,114,79,94,87,109,98,90,106,70,58,59,83,74,76,117,204,208,247,231,238,209,214,190,230,236,208,188,225,211,192,208,185,212,213,201,208,215,228,198,210,217,185,197,224,206,206,219,206,198,214,184,194,186,203,208,203,114,26,0,35,5,8,16,3,1,3,1,6,5,10,20,4,6,4,4,0,15,30,7,22,12,216,211,220,193,216,215,233,232,208,205,214,202,231,203,211,224,215,222,216,199,217,210,228,243,237,216,214,213,231,213,203,217,232,218,225,200,200,205,199,235,215,218,215,211,214,194,230,221,240,193,221,212,234,209,193,207,243,216,217,223,231,238,226,193,226,209,236,220,232,240,219,228,214,209,221,218,244,221,217,206,214,235,227,229,226,205,202,238,205,224,222,241,236,229,207,228,222,215,234,231,216,217,237,235,229,252,230,225,220,229,235,241,250,206,227,222,217,238,242,247,228,226,238,210,248,241,255,218,244,209,246,231,201,241,236,236,226,216,210,218,232,199,238,222,246,235,249,244,232,238,240,244,237,252,241,246,234,250,227,225,252,252,237,243,246,239,243,236,235,225,240,241,245,249,230,244,237,206,237,242,237,214,237,241,231,207,244,244,234,231,232,255,252,250,242,252,254,242,255,228,254,239,233,240,250,255,245,229,234,254,249,250,248,242,249,246,252,250,246,225,246,245,231,254,247,230,252,250,252,254,241,240,237,252,246,228,223,251,252,240,240,246,243,253,227,246,242,252,250,242,243,249,246,255,233,248,235,227,255,247,236,246,239,234,245,232,236,217,245,252,253,255,255,251,254,247,249,252,255,237,214,232,237,247,232,212,230,251,238,246,245,233,254,241,238,235,241,249,247,227,255,254,255,243,250,247,249,247,234,248,242,252,241,255,254,243,232,232,239,229,246,255,254,251,249,248,223,240,245,252,239,248,252,242,242,219,238,243,226,197,211,234,253,253,244,234,157,156,140,95,43,196,234,228,235,206,247,247,238,185,196,237,237,234,249,232,230,254,254,221,249,200,180,219,250,241,239,255,219,241,244,238,248,251,248,253,249,250,241,228,225,249,255,250,250,250,206,135,99,113,83,117,24,88,243,237,248,240,229,236,226,250,249,249,244,252,247,251,246,255,239,246,253,252,254,246,247,253,219,234,225,158,224,246,253,247,240,253,247,242,218,219,247,248,233,215,223,240,242,206,118,103,87,103,70,104,52,45,47,75,65,108,83,63,58,36,38,39,50,31,53,100,89,62,54,30,25,38,49,53,96,76,67,41,16,205,241,249,244,239,255,252,237,254,238,248,235,237,253,244,234,232,243,251,227,195,234,254,197,206,229,220,202,201,184,178,231,251,226,233,244,253,238,244,249,251,242,245,240,235,246,249,236,210,242,242,250,247,240,243,125,92,45,0,81,212,243,251,247,244,222,238,221,199,184,218,229,194,211,237,159,82,167,233,220,225,213,224,223,249,224,229,239,232,231,216,245,224,216,236,235,213,215,218,220,235,217,249,234,241,228,231,227,218,229,224,217,200,231,244,222,230,213,199,243,238,209,233,216,226,216,216,203,209,200,221,218,216,233,232,221,231,195,204,230,216,254,243,224,169,163,154,129,146,89,141,139,112,107,109,93,40,71,40,30,58,31,53,53,49,55,55,63,10,28,88,157,193,228,214,203,200,195,205,218,195,196,197,181,243,188,222,212,203,210,212,206,211,213,220,206,211,202,199,182,201,226,199,203,232,210,196,207,203,216,110,2,0,23,15,31,10,25,14,29,28,10,8,29,1,14,1,16,9,16,13,2,31,10,9,207,201,221,200,221,224,225,217,213,211,228,210,216,210,208,221,212,230,197,196,214,187,234,211,233,220,215,232,213,214,215,215,228,224,225,229,215,212,202,219,222,209,212,213,215,214,210,238,230,236,231,216,220,237,237,237,218,224,242,223,221,213,232,210,217,226,222,223,207,234,226,215,240,225,222,228,231,238,222,203,213,222,243,204,224,214,230,214,243,224,208,227,219,225,237,233,220,216,228,227,216,222,212,217,210,243,227,238,240,229,236,244,235,227,227,220,211,239,244,225,240,247,223,213,249,210,231,232,234,236,228,249,217,223,241,248,221,202,221,239,223,236,219,245,224,223,222,226,251,228,211,211,227,223,237,239,235,232,223,245,250,226,250,251,255,249,212,236,242,249,223,250,215,244,243,244,250,245,250,249,247,237,243,252,226,221,236,238,252,255,246,232,230,244,237,254,255,252,247,242,255,235,249,241,252,247,235,223,250,254,244,227,245,252,252,253,251,241,245,252,235,239,252,242,239,254,239,255,250,254,244,246,254,251,248,253,245,236,213,240,243,252,254,229,240,248,243,254,247,246,249,243,254,231,237,244,237,234,225,252,232,240,249,235,251,250,252,248,238,254,249,238,248,244,229,239,253,229,232,234,247,251,244,246,237,255,233,255,242,248,228,249,253,230,254,237,245,244,226,233,201,248,219,246,239,245,235,239,245,244,248,234,253,250,237,229,253,248,220,254,217,240,243,252,244,249,255,226,249,233,249,252,230,237,244,239,186,190,211,214,229,253,255,249,248,203,167,193,163,81,30,182,254,238,249,253,236,245,248,191,153,227,255,229,231,248,218,228,250,219,215,213,231,246,254,242,247,237,212,189,229,238,246,244,226,239,255,252,237,244,223,240,252,242,255,250,199,126,111,115,109,125,32,119,254,241,248,241,253,252,218,245,254,247,255,236,224,241,244,255,251,239,241,246,246,246,255,229,239,220,241,187,203,250,244,220,247,254,236,253,222,227,253,242,234,230,238,247,251,247,178,157,138,85,67,107,69,86,67,46,66,57,61,48,45,11,36,29,28,55,89,74,68,51,55,25,42,53,64,81,99,79,73,32,38,223,245,222,240,241,250,248,235,237,250,232,239,234,235,243,240,251,255,248,243,214,224,232,204,216,163,183,233,194,195,211,211,214,231,249,237,245,232,237,231,241,226,255,219,244,239,226,240,236,255,242,242,228,253,217,132,89,45,6,100,213,242,239,248,248,240,223,244,221,201,228,231,226,236,235,153,71,136,234,230,230,229,236,247,236,251,226,231,225,225,245,237,220,241,228,214,233,242,214,207,207,207,227,238,210,245,212,223,241,231,201,219,220,227,215,221,200,230,246,218,195,214,239,213,221,217,216,217,242,218,226,216,239,202,216,214,223,216,177,212,222,232,152,147,119,107,118,76,116,73,53,64,61,47,108,73,76,40,54,33,44,24,44,13,22,28,44,78,62,34,76,30,28,99,176,213,220,215,245,193,217,203,206,222,230,209,197,215,224,208,197,221,205,197,197,218,229,229,212,209,217,204,186,197,206,220,202,196,207,179,116,0,7,3,10,6,13,0,3,22,2,12,14,3,1,19,9,17,25,19,9,5,1,0,3,211,205,197,203,223,210,233,216,223,214,215,203,213,232,215,226,223,219,219,239,197,227,214,223,233,208,203,235,202,204,227,207,206,201,202,216,230,223,227,224,207,225,233,236,214,231,207,229,225,227,209,223,204,223,218,209,224,232,216,232,233,224,224,214,221,209,222,231,212,216,216,224,183,208,223,219,221,197,240,227,195,216,222,242,223,222,210,222,233,205,224,218,208,233,234,231,219,230,210,228,196,220,231,231,238,239,249,248,233,252,243,230,237,246,231,215,235,229,240,222,228,230,243,236,241,223,247,218,247,246,236,232,229,219,230,217,229,223,228,255,234,224,237,232,231,220,236,239,241,241,231,233,230,236,223,225,250,218,228,240,252,235,217,243,240,235,252,235,255,247,211,232,219,245,247,250,255,248,239,252,247,243,226,243,247,249,251,247,249,234,233,242,248,241,252,252,255,233,241,254,242,242,254,242,218,238,250,229,253,238,230,248,236,249,239,244,251,254,247,248,251,252,252,255,252,255,239,235,245,255,225,233,255,240,243,237,244,239,249,240,244,229,247,242,225,241,254,253,239,252,255,246,235,236,255,254,234,237,254,231,240,244,250,250,236,253,251,243,250,231,227,249,236,234,249,233,229,250,228,250,231,253,254,241,238,248,251,252,253,254,249,245,253,249,224,246,249,233,213,248,248,252,252,242,244,243,235,244,233,241,242,238,245,236,249,248,254,242,245,255,231,245,254,251,236,253,239,251,224,238,250,242,253,238,244,222,206,200,226,238,250,245,244,231,249,197,163,166,150,111,64,209,248,237,250,221,222,247,243,200,173,230,250,251,241,254,229,246,251,207,225,230,240,255,248,237,234,241,203,255,250,249,251,246,228,239,251,246,242,239,232,249,245,255,246,241,209,158,114,123,109,112,24,108,253,232,247,245,238,255,254,243,232,255,230,224,253,250,255,219,249,244,236,233,254,254,249,240,231,237,247,187,232,254,245,241,230,217,246,243,249,226,252,254,230,252,248,250,255,252,173,90,88,52,51,89,113,75,89,169,140,97,37,60,91,60,51,60,44,82,118,79,70,43,47,47,43,55,51,80,79,49,68,21,29,187,246,253,249,249,225,250,225,241,246,255,240,231,221,232,254,225,237,241,255,228,206,232,199,149,135,165,246,232,175,226,222,236,249,217,255,245,209,246,245,255,244,235,249,232,225,232,244,248,242,247,247,233,253,221,125,75,71,26,94,233,246,249,239,244,229,226,233,201,179,227,227,236,253,235,127,57,138,221,223,226,229,242,245,235,225,240,218,227,228,227,225,197,244,220,244,219,219,245,222,248,229,227,224,219,204,237,212,219,216,209,229,230,218,226,208,209,209,219,212,222,210,231,221,225,218,202,223,218,246,238,214,204,212,212,183,226,197,234,217,183,155,59,95,71,39,43,11,47,37,61,25,20,83,85,58,40,50,20,37,12,29,35,26,28,26,75,92,71,64,44,16,11,79,161,170,200,209,232,220,203,196,213,190,218,207,200,226,206,185,215,228,195,214,205,197,217,201,207,215,211,189,204,202,204,200,209,191,196,211,102,13,2,1,0,14,15,17,1,29,11,25,21,3,8,10,21,9,15,1,24,35,11,10,34,224,217,235,216,223,230,206,222,229,214,200,236,203,200,215,221,233,213,228,205,185,206,202,204,235,210,232,214,235,226,214,239,215,233,213,206,197,203,201,217,219,205,229,195,237,226,229,199,219,203,202,222,211,222,245,228,240,220,218,224,195,207,226,202,197,228,227,219,202,203,233,227,200,210,225,205,218,219,211,221,230,219,221,228,222,221,203,241,226,216,219,223,205,208,224,224,222,238,215,223,209,219,214,230,238,236,227,243,228,240,211,239,221,233,223,236,218,226,232,221,222,227,233,220,241,242,228,229,245,238,241,238,214,246,215,222,240,234,244,238,238,235,240,235,213,221,228,252,236,206,248,239,238,252,227,248,243,252,243,231,224,229,244,236,230,236,238,237,234,242,255,234,226,251,231,212,241,240,248,226,201,241,227,235,246,240,255,248,243,236,228,229,255,252,242,243,255,253,249,242,252,225,250,255,236,252,253,231,230,255,247,254,254,243,250,248,239,236,254,229,239,234,250,223,233,247,245,252,235,252,245,230,242,216,251,251,230,255,252,247,248,239,224,238,246,235,255,243,249,224,235,241,245,242,229,251,253,247,248,244,252,248,231,228,232,237,251,250,255,237,230,248,243,243,222,241,252,236,244,251,233,240,252,246,222,251,248,244,243,233,238,248,252,244,233,251,246,246,217,252,247,251,243,241,248,243,229,236,242,250,252,239,252,212,241,239,255,237,242,240,242,255,245,253,235,242,248,255,247,223,252,242,254,237,242,237,207,235,247,221,242,249,251,247,254,223,161,151,118,92,42,204,239,252,245,227,253,233,239,232,194,242,251,241,233,253,237,245,232,229,255,243,254,255,212,206,243,250,239,255,250,229,215,248,249,241,252,233,240,222,232,251,239,243,242,254,218,139,100,107,111,104,29,117,236,255,251,249,236,247,221,254,223,246,237,249,248,247,234,250,230,234,240,253,246,231,247,238,247,242,217,183,230,237,250,246,234,219,237,248,242,251,234,255,218,254,249,250,240,154,74,63,131,57,26,75,112,79,99,193,180,135,75,176,138,49,24,80,126,113,135,99,67,39,43,34,21,21,78,96,91,50,75,39,50,214,244,250,249,254,255,243,243,213,249,248,249,246,236,252,254,224,228,235,249,238,171,232,220,119,121,163,228,210,172,231,229,229,232,255,238,250,250,228,239,241,244,239,235,244,249,233,231,245,232,252,241,243,254,216,113,75,42,0,131,226,240,246,252,245,237,219,219,204,225,215,220,245,247,207,122,78,118,232,219,237,226,245,217,244,241,254,223,220,252,206,239,223,218,214,229,223,212,244,213,230,214,227,236,223,225,200,243,239,229,224,211,211,209,227,244,236,200,203,230,223,223,216,206,233,221,213,208,228,227,223,206,226,219,202,191,217,205,230,156,110,51,46,50,29,20,33,44,28,35,68,44,44,24,53,88,58,60,37,65,43,47,46,29,43,80,90,93,66,33,54,0,56,159,190,228,182,194,210,182,218,202,186,191,196,204,186,194,202,221,208,235,203,206,219,244,222,214,207,198,195,203,198,210,188,194,207,204,190,197,115,5,16,0,1,5,3,18,6,12,14,6,13,7,12,18,13,15,21,17,17,27,11,16,9,217,220,221,223,223,208,221,228,218,197,228,222,220,222,231,203,210,206,229,217,204,213,200,216,203,216,225,237,242,222,238,217,217,216,200,225,200,223,221,215,213,222,229,223,225,217,237,194,247,212,224,180,241,239,222,220,217,199,217,220,213,247,234,243,211,224,216,210,198,214,189,210,242,223,231,237,212,227,224,213,237,245,205,212,210,234,223,222,230,224,224,221,222,216,216,215,221,229,224,238,217,225,219,207,221,220,237,253,223,225,232,222,230,221,235,230,211,216,229,221,240,236,229,222,244,222,247,232,217,218,238,217,220,247,205,225,220,231,198,238,232,236,235,235,249,239,221,238,237,242,240,238,249,243,244,235,245,235,239,219,234,238,231,221,227,216,240,230,225,231,228,225,228,220,254,255,226,248,249,235,224,234,218,239,246,235,239,251,250,224,254,241,244,223,255,237,251,254,253,230,245,230,234,230,234,246,250,250,210,247,249,251,238,247,252,237,252,249,243,248,255,241,250,244,243,245,243,241,255,254,240,243,250,251,233,239,250,245,242,248,234,242,225,247,239,232,254,214,254,241,219,249,249,234,252,254,253,250,234,231,252,234,223,241,247,248,243,252,255,231,251,252,239,255,245,238,241,247,227,237,247,236,229,226,249,221,239,252,243,249,250,240,247,245,244,243,244,237,226,246,246,230,232,232,246,246,237,237,237,248,240,248,224,250,252,253,247,255,255,249,251,254,240,242,250,249,254,249,226,248,245,237,237,233,248,240,243,248,201,237,235,248,239,238,245,214,148,144,127,75,35,218,246,248,240,222,246,238,232,213,172,235,255,227,251,252,247,244,242,252,237,167,218,247,238,253,250,241,233,243,242,225,248,244,241,241,211,232,255,229,241,250,236,233,254,244,214,112,86,109,107,130,27,132,245,249,223,219,244,242,254,245,250,250,246,216,237,248,242,242,240,253,254,252,246,253,255,242,255,246,247,175,186,248,252,244,247,251,252,255,243,235,236,233,223,250,229,249,185,80,87,68,136,132,82,49,55,37,52,192,151,108,78,149,114,30,53,77,95,97,138,130,82,19,57,61,37,54,74,97,88,63,70,57,59,237,235,222,243,249,240,247,246,255,234,252,248,232,239,238,239,253,240,208,254,250,182,220,250,193,158,174,230,243,209,216,245,208,226,243,237,252,247,249,238,231,254,240,235,249,253,251,232,245,249,255,232,219,248,211,105,73,4,0,104,240,218,227,249,242,224,231,230,208,214,205,211,234,240,239,126,55,146,221,211,229,234,240,227,235,234,225,196,235,218,250,222,216,246,218,222,228,219,224,222,234,211,238,243,236,205,231,218,213,205,219,220,230,236,220,230,208,211,215,220,234,208,220,212,209,194,208,214,226,221,220,219,213,247,218,204,236,199,205,180,73,66,9,11,24,56,73,68,35,63,31,45,35,47,69,86,58,48,47,45,21,10,47,38,51,67,73,70,62,56,41,70,169,224,229,201,211,200,227,210,194,215,216,218,205,187,221,201,207,218,197,214,195,213,208,177,226,191,213,204,191,198,211,201,215,220,219,202,193,219,101,2,2,24,15,24,20,0,2,4,13,7,1,8,6,0,7,8,30,11,29,13,1,13,8,226,226,234,219,226,215,237,221,228,204,220,222,223,192,219,204,198,216,212,211,221,202,205,197,220,212,207,199,199,228,206,221,209,210,199,205,236,199,219,232,220,205,213,231,224,209,238,212,227,223,187,224,234,219,225,217,190,216,231,210,231,211,207,226,199,210,230,229,208,235,219,213,216,230,231,229,231,212,216,210,208,233,195,202,213,227,220,231,235,232,189,226,199,216,197,209,231,226,216,229,216,238,217,241,218,211,242,227,228,244,218,225,241,229,252,229,239,244,214,185,197,234,219,240,239,241,237,234,241,205,238,216,243,229,231,228,244,227,208,235,238,235,234,235,223,221,226,216,221,227,225,241,217,242,236,233,247,229,218,243,247,234,228,237,255,250,255,245,252,231,250,246,240,231,254,236,238,250,251,231,241,244,243,251,232,246,242,234,239,250,235,218,247,255,234,241,252,250,235,243,242,227,240,250,253,237,252,208,254,246,250,232,251,234,252,254,232,255,243,241,240,250,246,240,249,249,255,241,236,235,232,241,245,254,246,254,255,213,239,235,229,235,251,247,231,227,210,251,242,235,241,254,244,248,251,255,255,240,245,251,233,237,246,234,230,243,224,254,216,236,255,236,227,244,241,237,243,248,237,233,246,241,223,249,237,254,255,232,253,236,231,250,241,235,235,251,214,240,232,223,235,231,245,239,254,233,237,234,235,231,252,248,229,235,242,234,245,248,253,246,231,252,229,253,253,237,253,255,224,243,250,255,242,230,239,208,174,189,226,224,253,242,252,239,242,196,178,184,170,91,44,188,242,240,253,243,242,239,251,219,151,220,246,253,229,245,253,253,205,225,183,220,244,248,253,250,246,235,213,219,246,227,250,230,249,227,243,251,229,227,209,248,254,248,242,246,208,129,114,122,115,103,32,103,238,240,239,233,255,237,250,254,227,242,195,193,221,254,254,255,251,233,239,238,240,237,234,238,225,238,243,149,145,240,253,239,250,243,226,226,242,242,246,210,240,210,133,194,163,145,155,66,142,107,57,51,60,59,71,157,111,102,80,163,113,53,75,19,64,102,88,138,75,18,33,56,26,67,107,74,68,41,65,40,70,217,240,233,242,255,254,253,236,254,231,242,248,242,230,244,247,229,237,236,254,236,206,189,250,207,168,157,224,236,246,193,224,227,196,237,238,245,240,241,236,226,242,250,255,242,242,251,255,253,255,250,222,243,251,194,104,92,38,0,143,225,236,247,237,215,223,213,226,214,225,227,239,232,229,222,116,54,122,238,202,226,228,218,239,214,246,221,236,207,222,223,232,238,216,239,211,208,227,238,244,203,231,180,238,238,245,243,216,229,224,210,231,231,209,219,217,231,236,222,216,223,212,247,202,204,229,220,227,191,205,219,196,235,207,188,206,213,242,229,174,141,118,78,71,65,56,67,55,58,43,23,69,46,53,92,74,58,69,33,62,36,13,33,41,65,91,70,68,68,53,45,157,210,209,229,223,218,226,223,194,202,225,194,192,212,212,201,200,214,201,210,199,214,208,185,222,222,206,216,210,205,221,229,179,204,183,200,207,198,200,117,7,0,17,13,6,38,14,3,11,22,9,25,18,1,0,14,7,12,37,23,10,12,1,12,222,216,234,240,215,188,209,211,212,221,215,203,214,217,204,202,220,211,213,235,194,211,211,228,231,199,214,208,221,210,217,231,232,202,197,223,235,227,214,199,205,244,227,210,217,230,221,238,220,207,243,216,224,214,230,220,202,214,204,206,194,225,221,220,231,235,186,208,212,231,212,224,228,227,208,210,201,224,217,199,200,229,222,237,212,210,227,204,209,230,219,228,222,231,229,222,217,222,210,223,226,228,229,236,217,230,222,241,225,221,219,207,242,240,220,234,227,219,244,224,236,214,234,246,232,246,222,227,231,216,219,239,224,234,229,249,226,236,234,228,222,211,223,220,216,214,217,214,226,223,224,248,247,243,233,250,234,239,234,235,232,223,240,243,230,210,233,230,231,244,228,208,246,241,251,255,250,237,250,249,251,249,233,243,242,254,254,250,227,251,248,232,233,242,252,226,244,242,234,241,253,232,255,249,230,241,234,237,220,225,253,240,246,231,232,244,252,252,235,236,253,252,248,229,240,251,229,248,251,255,247,254,251,245,243,244,240,254,250,246,228,216,248,251,248,243,251,228,223,253,243,255,222,245,238,237,255,255,254,251,235,249,244,231,255,250,246,251,255,246,251,246,254,233,251,242,237,229,246,234,251,232,250,254,254,222,220,225,239,253,241,248,255,230,253,222,254,241,231,242,240,249,251,252,252,251,245,251,242,249,255,246,230,235,249,251,249,251,238,223,236,250,228,236,250,248,254,248,253,242,251,241,228,244,243,183,221,235,229,224,221,245,250,247,248,211,208,167,154,101,46,200,255,247,243,236,237,253,232,220,152,200,249,251,255,242,249,248,226,219,195,215,249,254,223,227,239,217,198,224,238,248,251,248,227,247,252,231,229,230,242,255,248,223,253,249,243,152,135,141,106,105,20,135,239,249,241,252,246,253,239,244,246,245,187,207,212,240,247,238,247,249,214,225,253,253,249,247,233,252,230,194,154,225,250,236,243,218,245,233,243,247,233,203,223,198,194,253,188,179,172,60,147,101,92,69,70,52,85,186,115,87,70,135,112,76,66,72,105,101,111,109,82,64,22,22,42,54,92,66,73,68,66,33,37,220,247,248,242,239,239,241,252,255,227,244,250,229,232,223,246,230,231,224,245,248,199,205,251,253,174,158,186,236,237,204,250,199,168,230,207,237,253,253,242,213,251,254,240,254,242,226,240,222,245,251,247,251,233,218,120,142,14,6,147,222,249,234,242,239,227,230,224,228,233,214,209,227,249,231,122,46,156,241,243,220,241,254,229,232,227,221,249,238,221,254,220,203,228,236,234,233,221,219,246,211,214,225,220,207,228,231,239,216,240,213,220,227,222,206,213,222,227,212,217,225,226,200,216,224,225,196,216,232,208,209,219,193,211,240,204,219,216,217,192,186,137,148,132,99,51,81,65,92,72,80,51,78,103,56,57,86,44,54,38,41,47,41,61,56,106,70,64,54,37,46,78,184,182,203,220,183,199,212,214,205,219,187,228,207,216,204,197,223,213,222,230,203,207,210,220,196,230,200,187,204,213,202,186,196,188,215,213,216,215,117,7,1,3,27,12,3,16,10,8,33,10,17,11,6,6,20,26,8,26,9,0,7,6,21,241,213,213,199,204,228,213,211,239,226,208,210,224,224,219,234,217,214,214,228,216,204,200,199,210,210,236,224,231,211,198,223,223,239,222,220,220,220,213,236,239,231,192,233,223,241,217,237,217,227,220,233,211,219,246,225,236,210,231,226,217,207,222,220,206,231,212,230,239,211,232,198,225,215,207,189,221,206,229,219,207,239,204,223,244,214,227,214,217,205,206,232,234,231,222,235,220,215,219,241,238,228,233,213,242,232,231,195,237,218,222,219,229,227,233,220,218,221,230,204,226,209,236,231,236,232,231,202,238,243,225,238,218,219,230,237,229,227,231,224,236,219,233,245,235,231,251,212,225,243,244,237,241,224,238,230,232,242,240,227,227,229,242,243,225,225,238,225,252,204,248,254,253,234,236,241,243,249,234,252,238,247,226,255,248,253,249,236,248,240,220,227,231,229,230,227,247,223,245,247,246,243,233,247,216,239,252,255,253,252,233,253,242,244,249,253,249,237,252,245,232,241,246,245,237,240,255,245,236,234,243,243,250,236,235,236,245,228,247,255,254,240,254,235,253,234,244,199,240,248,217,234,248,240,253,241,247,252,249,247,248,246,229,239,234,237,250,244,243,236,246,249,252,244,233,243,251,245,233,247,253,249,255,243,252,253,254,228,247,240,241,248,244,255,249,241,239,238,242,236,245,248,234,238,235,235,247,242,223,230,249,247,235,224,245,249,249,234,250,241,255,252,249,251,238,230,244,242,238,236,239,250,236,241,242,226,209,251,208,194,227,254,226,247,252,194,169,164,128,86,54,168,247,247,252,223,248,243,247,248,154,198,245,245,254,255,252,240,229,231,249,243,231,255,220,173,229,230,247,241,249,247,236,246,247,223,238,250,251,234,255,255,254,252,236,227,218,159,149,116,84,95,20,138,226,252,246,255,249,245,240,251,248,255,238,244,249,243,247,253,251,226,227,253,245,251,246,254,237,250,241,180,178,228,246,253,242,249,229,230,225,246,250,216,225,221,235,251,172,225,189,102,138,99,97,47,63,53,59,195,162,84,46,155,136,58,22,59,116,102,70,43,36,14,35,38,38,50,101,104,90,62,80,34,29,221,243,245,221,240,235,244,249,240,231,230,253,241,239,255,244,237,231,240,245,244,213,181,234,250,196,169,185,220,210,230,237,217,180,192,226,249,247,241,252,249,255,240,245,243,245,251,246,228,251,236,250,251,254,222,140,108,40,3,177,247,238,255,245,240,239,206,226,206,212,218,211,229,247,215,128,72,149,230,179,239,226,217,228,241,235,232,224,228,235,214,228,222,197,228,211,218,218,208,230,204,225,212,232,219,213,209,231,213,214,205,230,209,217,234,219,226,225,216,208,227,193,209,219,203,229,222,207,229,208,210,221,217,207,227,199,213,209,232,204,158,152,95,103,71,61,43,81,71,82,96,98,127,111,65,62,73,45,48,82,81,109,79,137,113,52,58,74,31,25,40,134,171,192,212,217,209,209,186,226,226,213,207,224,224,195,205,186,218,208,193,204,182,234,216,202,232,205,217,213,220,213,224,196,200,204,213,190,217,197,119,17,12,9,19,4,7,12,13,4,29,8,7,1,14,14,17,2,6,16,14,20,11,40,14,227,224,232,199,213,228,223,233,200,234,211,189,208,223,216,225,220,206,224,194,220,223,195,210,207,214,235,205,202,222,222,231,206,220,219,211,226,227,210,221,223,203,192,223,217,242,231,207,218,212,211,215,218,208,236,215,211,225,208,209,225,225,222,211,201,219,213,198,244,227,209,208,201,232,226,231,211,224,221,211,221,191,216,223,221,222,207,235,238,218,236,241,222,235,227,208,217,218,230,200,216,221,242,245,210,243,226,237,220,216,221,222,246,252,215,246,230,239,208,225,251,207,248,229,242,230,232,246,238,212,242,219,223,236,247,245,216,229,215,249,230,206,240,221,232,228,233,239,236,227,239,216,215,247,224,246,215,245,229,235,234,232,238,235,245,238,224,244,231,246,241,241,236,229,235,244,249,228,232,249,242,226,245,234,252,249,248,229,251,246,255,240,246,242,215,242,252,220,242,250,247,233,247,249,237,236,255,245,255,244,247,249,241,245,237,242,243,253,238,253,245,240,215,232,236,223,255,240,245,252,251,243,228,241,255,243,246,243,246,250,247,248,255,240,247,243,255,254,230,251,248,255,254,253,250,222,251,226,229,248,250,254,234,255,212,251,236,251,254,254,231,244,234,251,232,248,246,246,238,237,253,253,254,249,247,234,255,255,239,254,240,230,240,238,241,252,234,228,248,253,251,243,251,231,253,180,159,185,222,243,240,243,240,234,247,238,243,253,232,245,255,230,240,242,233,248,241,245,252,252,247,255,233,246,246,190,208,206,236,201,245,225,243,239,253,199,151,145,122,81,44,190,248,242,224,230,232,246,254,233,210,173,224,255,252,238,246,255,231,249,194,225,250,227,221,227,251,245,252,252,232,253,236,250,241,236,248,245,236,227,204,237,241,239,251,230,142,106,109,131,108,116,57,134,238,248,243,251,244,253,243,255,244,245,211,236,243,243,235,252,251,248,250,255,246,238,244,254,244,239,247,182,135,254,253,249,242,247,247,242,244,251,243,226,255,251,237,248,211,255,194,96,68,36,41,11,34,33,48,223,159,68,43,158,117,27,51,27,108,85,76,44,38,69,51,38,34,62,74,90,59,56,91,30,24,220,253,255,249,246,253,243,252,251,241,244,254,249,248,250,254,254,221,251,253,243,250,194,205,244,231,187,181,134,203,240,220,191,199,192,237,234,254,232,233,246,242,249,236,249,247,241,246,250,254,246,246,252,234,189,104,71,26,44,185,236,205,218,200,241,232,229,234,204,176,210,238,216,227,249,116,50,132,207,216,198,212,208,242,228,249,233,234,214,220,234,226,242,241,219,205,218,202,200,198,223,215,218,213,214,225,207,222,238,215,233,214,216,216,212,206,220,207,210,200,211,215,212,200,221,220,221,201,210,192,212,168,192,235,232,212,210,226,186,181,102,119,110,138,91,90,68,85,80,129,161,162,126,100,121,95,81,57,64,128,136,133,116,131,119,103,77,74,37,53,144,223,225,224,214,210,188,200,202,211,198,227,217,212,205,207,240,193,200,223,193,226,231,200,197,214,188,218,219,220,207,217,186,199,211,181,206,200,211,216,110,0,13,5,8,17,10,4,23,9,27,1,5,2,7,4,4,4,24,8,0,27,15,11,27,210,206,210,229,216,215,188,212,226,227,192,217,213,218,219,215,237,224,229,219,211,234,189,198,226,225,217,216,223,208,246,233,234,218,204,209,232,213,215,231,221,231,226,201,232,220,211,225,203,218,226,188,241,225,221,189,210,226,234,225,201,232,200,220,224,205,217,220,225,216,203,233,212,236,223,215,227,220,209,227,225,203,198,225,215,233,218,214,205,225,237,243,229,220,199,222,209,204,241,207,203,211,245,233,213,241,213,210,224,241,228,219,210,221,238,198,211,239,236,212,237,249,222,227,225,219,227,226,252,241,235,223,203,240,223,226,241,223,243,212,234,225,227,236,230,229,226,238,236,228,231,214,229,249,231,244,226,245,231,238,240,243,242,222,243,240,221,247,240,240,243,255,242,249,221,240,244,247,242,237,243,248,251,251,246,245,243,236,229,243,238,237,238,247,255,248,247,248,251,226,252,254,239,248,238,224,235,238,242,250,244,251,255,243,234,250,251,243,242,251,242,255,237,238,230,250,251,228,245,255,245,253,255,253,253,244,248,250,238,248,246,248,251,253,236,248,224,247,251,250,245,246,253,234,232,242,239,255,242,240,228,215,254,226,234,252,236,252,253,252,241,225,232,237,244,236,249,229,248,252,248,238,244,255,240,250,241,255,245,243,253,254,243,245,240,252,247,238,236,249,238,243,251,249,197,189,193,242,253,242,247,247,243,219,238,238,249,226,246,245,254,251,225,234,255,251,253,230,244,255,245,238,243,250,219,172,190,232,236,233,248,250,254,213,239,206,164,139,139,116,47,215,235,249,233,235,247,244,238,249,185,183,226,247,245,230,247,255,237,178,159,207,246,247,231,222,253,246,229,249,249,238,249,253,250,237,248,255,251,248,210,156,89,85,113,72,99,143,117,158,153,168,123,136,207,188,198,186,188,199,181,153,178,138,183,230,255,255,252,249,246,242,234,218,235,250,255,238,255,225,236,220,182,221,222,234,250,253,246,230,247,255,238,246,248,253,253,199,206,229,135,40,41,18,43,40,70,41,42,196,184,79,51,128,118,61,73,27,124,94,60,81,51,31,75,26,62,45,52,57,74,49,74,18,61,202,250,252,248,249,251,229,232,228,254,240,238,238,246,254,254,255,232,219,231,250,252,204,192,240,228,134,130,144,190,234,192,183,252,248,225,250,237,237,244,238,237,218,245,246,233,255,243,191,128,91,80,110,114,83,65,38,49,52,61,141,145,157,194,232,225,231,203,217,204,214,222,205,220,236,132,41,111,241,202,214,250,225,244,216,246,212,220,228,212,226,236,210,243,220,223,207,217,242,214,221,227,226,215,212,231,219,222,221,216,237,217,215,245,237,210,213,202,190,203,210,228,216,215,237,211,216,200,223,212,227,238,222,214,209,215,225,217,218,194,131,104,92,116,104,92,81,64,56,76,150,127,145,125,115,85,74,51,49,99,137,116,81,129,101,99,86,85,47,15,170,217,227,213,202,225,191,224,224,213,222,209,197,207,220,204,219,205,231,196,209,231,201,220,210,217,227,213,211,206,207,217,203,210,202,210,193,225,191,216,111,0,8,17,15,35,13,6,14,8,8,14,27,9,5,1,0,27,0,13,0,3,4,0,15,236,216,213,217,210,209,232,207,215,229,202,219,217,236,220,222,193,210,236,209,214,207,228,209,207,212,207,245,225,206,213,234,238,201,211,190,205,194,230,203,221,222,213,240,219,234,226,196,216,211,236,214,231,230,217,225,243,221,191,220,221,206,205,213,205,203,200,217,216,206,215,220,215,218,211,210,223,196,208,190,228,231,198,200,204,215,226,210,219,234,222,220,223,217,214,233,202,217,222,233,208,237,221,217,229,200,207,248,230,229,249,225,231,226,249,220,247,246,219,218,226,224,238,229,246,245,197,234,235,235,242,242,229,208,216,231,228,245,233,228,232,214,227,222,240,232,233,221,236,211,240,225,237,245,247,244,235,243,241,242,223,236,233,233,226,241,241,207,245,246,247,245,214,224,250,252,245,253,243,243,247,230,236,248,234,244,254,245,243,239,228,254,236,232,244,244,230,248,234,241,253,245,252,242,248,250,236,252,237,255,249,235,237,245,234,241,253,241,247,246,244,237,244,244,227,243,251,254,250,248,246,252,235,253,248,234,245,255,245,250,233,220,250,243,237,235,247,251,241,254,241,230,238,232,246,246,245,238,254,238,237,249,252,251,252,250,249,233,250,236,255,249,250,227,239,249,215,225,254,247,249,253,247,249,252,248,255,242,252,244,246,244,248,255,217,246,228,252,247,231,236,238,246,249,237,224,249,240,242,233,247,247,253,242,244,237,239,250,232,249,252,245,253,255,235,244,228,253,243,254,247,245,231,250,239,188,246,251,243,190,218,245,252,225,241,218,163,185,152,83,76,189,250,250,241,250,231,243,252,243,184,198,218,230,229,255,253,234,219,191,211,245,250,255,242,249,255,157,143,232,227,252,247,232,255,206,244,244,255,246,181,84,44,48,72,109,109,133,124,170,127,147,146,112,103,89,98,114,90,59,100,100,67,40,158,242,255,239,235,252,252,239,254,246,242,240,229,247,244,249,247,223,157,217,254,245,252,237,242,228,240,247,242,249,239,239,212,125,186,177,95,70,62,61,40,12,83,49,78,176,166,75,26,149,102,62,74,48,102,65,57,64,30,29,55,44,38,19,35,73,65,55,74,37,41,239,244,244,230,236,255,254,245,243,246,250,249,253,231,244,250,255,244,228,242,249,230,224,175,241,241,154,108,159,206,243,202,214,234,227,216,216,248,254,255,243,254,250,241,236,255,247,162,86,62,32,2,7,15,20,25,59,46,44,62,31,52,46,159,203,198,209,200,221,206,220,222,232,251,216,149,65,141,228,211,210,230,224,232,218,228,220,231,220,217,235,242,229,231,218,231,223,208,227,242,212,234,231,205,228,234,204,218,231,211,228,217,205,210,218,200,220,216,200,213,222,233,233,217,205,216,215,211,209,206,228,205,209,200,225,182,196,206,221,225,171,120,100,107,144,86,70,61,33,68,89,132,156,119,109,98,43,32,47,129,121,98,83,102,98,86,97,41,28,50,159,206,184,223,230,216,193,215,218,214,206,220,179,207,229,209,204,205,221,219,207,219,233,199,208,213,205,219,213,212,191,198,186,214,230,197,201,205,207,221,99,11,2,13,14,4,7,7,24,32,4,0,15,24,20,16,0,10,14,17,10,3,6,30,13,201,220,220,202,214,195,227,238,213,236,200,218,227,201,209,229,230,188,222,216,230,233,220,202,235,209,244,209,213,210,225,219,207,209,230,216,201,205,201,235,214,222,190,222,229,236,214,225,226,230,199,208,210,226,201,221,224,236,222,217,211,200,223,232,227,241,207,230,204,193,229,218,228,204,228,240,232,199,193,224,235,213,209,234,224,232,244,229,228,198,246,222,236,198,231,229,229,229,223,216,221,219,225,210,201,214,219,227,232,227,217,239,253,229,200,221,242,236,218,230,241,231,231,229,227,211,213,225,211,239,247,233,252,243,246,217,234,245,227,240,207,229,245,240,214,220,242,223,221,224,248,230,234,232,247,220,236,246,214,238,243,226,246,221,249,243,229,240,249,234,233,237,255,250,231,223,250,242,241,236,241,250,255,250,232,239,234,232,249,246,248,222,255,248,246,236,255,239,255,216,235,228,230,243,255,252,243,252,251,245,245,254,249,248,239,247,251,252,255,245,222,246,247,253,246,255,217,247,236,253,255,229,242,234,243,253,235,243,237,236,236,255,247,242,234,236,233,235,249,255,249,254,232,231,234,245,242,251,252,232,235,243,244,223,239,245,252,255,255,254,247,252,255,243,255,224,247,215,253,250,253,248,244,248,249,247,247,255,242,237,222,249,249,233,241,232,243,248,243,247,253,240,252,243,249,239,254,224,210,255,251,252,255,244,252,249,250,236,249,248,255,254,246,244,246,254,250,231,245,230,252,225,233,255,243,212,231,185,168,199,239,244,255,242,222,205,195,148,130,82,34,203,255,252,241,243,236,234,242,232,198,189,218,241,252,230,254,231,231,208,228,234,237,243,209,195,239,241,207,252,219,247,247,234,236,247,245,254,240,242,202,103,99,83,70,102,69,76,72,69,85,46,49,88,91,73,76,101,78,78,80,76,66,62,173,243,239,239,249,254,248,236,225,232,252,240,231,237,253,255,253,249,152,207,244,244,248,232,236,241,255,224,240,247,238,236,154,112,212,236,164,69,63,97,62,86,85,50,87,171,153,68,33,134,84,52,56,90,128,82,54,64,34,59,40,38,55,23,40,61,72,35,50,22,34,216,255,240,235,219,245,240,250,229,229,240,255,246,252,235,245,252,242,253,234,234,243,215,168,215,233,241,179,217,236,248,249,217,249,239,193,207,241,249,251,242,253,235,213,247,228,203,124,41,76,54,50,24,42,52,46,58,53,77,47,41,15,0,116,198,197,214,207,198,216,204,216,238,250,234,137,71,165,228,219,239,249,235,239,235,239,230,218,231,229,202,235,228,236,242,215,223,221,223,239,226,228,222,213,237,233,244,212,229,219,233,231,206,208,227,204,223,208,225,198,210,223,204,223,196,236,206,192,205,225,231,202,192,193,226,209,198,216,228,185,173,126,109,87,108,82,80,26,53,52,99,122,72,106,83,89,64,37,50,130,87,99,94,95,77,82,54,67,35,67,171,184,185,236,225,201,199,205,194,216,228,216,226,211,210,223,202,201,210,210,206,211,197,221,216,223,239,241,222,206,219,206,210,204,226,192,200,196,203,221,92,2,3,2,24,0,17,3,28,18,6,21,28,9,7,4,3,10,6,20,6,17,21,26,1,209,203,237,192,221,214,214,221,211,237,223,199,220,210,229,199,216,203,226,219,220,212,202,234,198,207,221,197,223,234,237,208,209,230,191,210,220,217,238,234,215,224,221,235,224,233,197,193,217,227,217,216,215,212,212,215,221,230,216,214,208,198,231,224,214,216,226,209,193,228,221,222,203,203,209,218,191,206,226,201,236,203,212,216,219,226,222,237,219,229,197,211,243,229,215,225,210,223,236,221,242,239,242,211,238,222,218,222,227,247,232,234,244,222,235,224,207,233,230,233,227,215,217,207,247,240,227,235,240,230,237,238,220,238,236,227,222,212,241,236,246,242,233,220,228,220,225,251,223,245,225,218,246,241,216,233,222,229,244,235,228,219,224,223,235,255,243,232,234,235,226,245,240,246,247,251,237,231,245,221,241,237,238,250,215,235,235,228,232,242,232,245,223,255,240,233,254,245,253,244,240,246,243,247,253,249,241,242,245,232,243,249,243,237,250,247,229,243,252,235,251,231,227,246,247,247,250,248,227,254,236,240,252,248,250,247,243,241,252,228,246,250,224,250,253,235,234,254,245,245,245,244,255,251,235,236,246,230,238,251,251,227,246,247,255,255,229,255,236,245,251,253,235,244,229,253,233,232,241,238,230,254,232,220,241,224,240,241,251,251,224,240,250,255,223,251,247,252,238,237,253,239,240,238,232,242,251,247,245,249,247,249,243,247,233,231,241,235,238,247,254,250,223,243,244,242,236,255,239,247,248,244,245,225,210,179,202,211,230,221,255,244,241,225,245,200,160,170,136,72,33,214,254,241,253,232,252,239,245,213,154,194,229,231,231,252,251,253,232,191,193,234,226,237,205,234,238,220,235,246,230,249,245,234,255,234,238,242,247,242,190,122,104,73,57,36,72,63,49,57,66,20,46,29,33,44,34,40,81,33,64,57,46,51,66,116,231,243,223,242,254,249,243,232,240,228,253,246,237,249,231,237,130,157,253,251,255,237,238,242,226,204,226,178,144,200,172,226,251,243,166,109,69,93,54,29,83,60,66,172,127,47,36,130,63,36,60,55,120,84,55,39,37,49,60,43,42,39,29,70,60,59,41,29,64,211,249,252,243,239,250,232,252,236,252,248,255,244,242,233,242,251,255,230,244,231,239,253,161,216,251,247,164,184,231,240,254,195,217,234,163,183,187,240,255,235,254,255,253,243,247,149,82,54,76,68,63,72,72,69,58,76,64,53,70,73,32,38,160,218,239,218,181,168,176,191,228,234,255,222,150,50,155,229,202,235,246,228,248,238,231,238,236,213,249,226,221,231,225,220,214,221,250,200,218,231,216,222,220,237,227,225,210,226,217,217,230,231,215,233,201,213,198,207,222,219,207,220,204,200,215,207,205,201,212,231,222,229,209,189,200,191,204,218,211,149,120,60,67,41,42,45,71,56,71,131,119,113,90,68,31,66,39,58,123,118,101,89,71,86,51,42,49,14,88,196,220,207,205,200,225,215,215,225,206,207,209,207,207,223,201,216,214,202,215,225,210,213,216,239,205,208,199,197,202,217,202,199,196,199,213,192,196,196,220,97,12,7,6,6,8,30,19,2,8,26,27,9,4,22,3,6,11,21,16,11,18,11,28,10,213,220,198,189,220,211,214,213,201,223,217,189,205,228,234,218,199,210,227,207,206,223,228,199,228,229,188,219,219,208,212,237,218,211,219,213,224,212,226,245,227,224,235,238,237,228,199,244,216,223,230,191,241,230,221,223,214,210,217,205,201,210,232,211,224,232,230,224,236,199,223,215,212,221,235,240,244,227,216,219,211,224,218,236,222,200,234,207,228,238,235,213,219,213,213,228,240,220,238,233,192,229,209,229,229,207,205,243,218,210,226,237,218,233,238,217,245,203,219,238,222,234,231,224,252,231,238,233,232,212,223,205,246,240,223,205,226,219,232,216,207,229,223,227,244,242,222,241,215,236,212,236,240,235,223,204,232,229,243,233,247,238,228,240,226,232,229,232,224,242,241,236,233,223,242,245,242,236,249,243,235,231,254,246,239,248,223,242,228,251,250,253,241,252,248,240,212,249,240,227,232,248,243,248,243,253,244,226,247,218,248,243,242,241,245,252,245,253,252,245,243,253,251,235,252,221,254,249,229,255,225,243,255,242,248,236,255,252,254,247,255,252,239,249,234,249,229,252,232,247,245,245,247,242,226,237,238,235,245,221,246,254,252,253,253,255,243,243,240,240,233,239,246,250,231,239,248,232,240,236,226,252,242,255,255,247,243,235,239,240,233,237,243,229,236,252,243,242,237,233,232,249,226,241,247,240,251,247,247,251,229,238,245,246,242,254,231,237,245,240,255,251,255,240,235,242,250,240,247,240,221,236,245,244,176,195,247,237,213,211,229,253,255,240,255,173,150,154,136,71,50,218,234,230,237,214,249,244,249,242,205,190,234,223,240,249,246,235,230,185,155,249,253,255,245,232,248,244,225,236,238,237,238,232,254,248,255,239,244,254,154,108,111,64,65,54,66,60,64,76,65,36,66,39,43,54,49,50,66,49,74,55,72,12,45,152,241,239,245,241,232,246,246,242,255,250,233,248,252,243,253,220,154,194,253,254,232,246,235,242,231,180,230,214,222,217,216,232,255,166,154,152,119,140,53,59,102,101,66,154,158,97,46,109,98,77,56,49,105,58,62,56,53,58,58,65,40,55,51,63,63,36,64,21,61,219,254,239,244,224,234,239,221,251,243,242,243,249,253,233,235,252,246,233,239,212,241,252,201,188,249,237,184,163,232,215,243,193,229,201,198,189,199,253,254,227,250,222,240,250,225,140,99,67,81,84,80,99,62,58,53,61,41,63,58,58,38,42,225,216,215,230,201,182,199,198,198,191,237,255,158,67,168,205,200,232,236,225,209,207,231,235,227,225,222,212,225,239,202,227,210,231,231,217,201,223,235,220,208,221,225,234,214,215,219,216,230,227,213,229,225,222,215,229,233,191,222,219,215,237,209,215,212,202,228,214,192,219,206,192,219,218,240,231,203,125,111,68,84,66,60,78,29,34,104,155,104,114,74,59,30,44,48,77,104,89,126,93,68,75,64,46,28,18,97,201,198,218,221,199,206,227,219,201,207,217,197,210,228,215,222,229,217,212,212,207,216,221,219,217,209,190,209,209,213,227,230,233,221,199,205,205,211,206,202,85,21,6,7,14,5,24,3,1,7,27,5,21,3,13,14,3,12,26,35,5,1,24,17,7,207,236,219,230,191,216,214,216,220,221,212,225,225,228,209,233,200,219,223,226,226,207,249,231,232,227,212,230,219,214,234,234,232,187,222,230,216,238,238,211,217,235,209,215,240,235,211,230,219,209,222,223,225,217,200,218,236,209,208,212,220,228,227,239,218,233,218,243,234,247,200,216,234,210,223,239,224,234,215,206,223,219,238,234,213,240,205,214,214,230,186,188,232,218,234,217,218,222,197,245,225,230,193,231,200,217,205,228,206,219,247,219,218,229,206,221,234,219,210,241,246,210,216,230,234,209,250,235,230,234,213,233,208,222,231,218,218,214,234,230,237,247,244,227,232,252,230,250,242,241,239,248,225,227,237,235,240,224,240,241,247,233,235,247,231,237,230,241,224,246,223,229,236,249,221,249,239,232,227,243,233,247,253,255,243,239,243,223,230,238,244,250,242,243,215,247,252,250,239,249,233,224,228,255,249,240,253,245,247,230,251,250,236,245,244,251,247,248,241,243,236,231,248,253,232,234,255,255,250,242,249,255,240,245,242,235,248,252,238,241,228,247,252,251,248,253,251,240,250,255,230,225,251,234,252,248,248,240,235,253,247,218,240,250,248,235,255,225,226,247,225,240,228,241,243,233,238,247,247,213,246,229,249,250,247,252,222,243,240,232,249,247,254,253,233,250,245,255,251,238,229,253,249,251,241,223,248,225,244,234,234,254,233,253,223,255,254,236,247,251,239,240,243,234,253,244,230,242,242,254,248,218,245,247,242,237,253,246,239,183,231,239,227,224,244,189,182,182,142,87,72,243,229,251,247,222,237,243,232,247,224,183,204,245,253,246,252,217,210,205,193,238,250,244,196,243,251,242,229,243,246,251,247,243,245,247,245,244,244,249,153,128,103,69,48,61,94,74,70,49,66,98,84,71,46,79,30,91,91,47,107,88,73,33,122,220,239,243,241,230,244,249,248,225,242,231,241,245,253,247,211,220,156,144,235,250,247,250,218,253,236,234,252,220,253,247,249,214,149,112,166,243,186,134,100,73,123,78,96,145,183,96,128,130,132,122,68,68,105,49,49,75,45,55,43,51,42,19,61,64,76,69,74,14,48,226,247,246,250,244,252,252,252,233,227,225,245,230,254,234,253,251,227,246,230,243,237,251,203,179,242,250,174,164,221,208,196,231,209,232,234,207,213,229,249,254,231,250,242,246,230,120,92,97,66,89,89,70,29,37,59,46,65,49,51,64,31,47,180,230,241,218,230,222,211,209,192,245,244,222,122,84,145,213,218,245,206,244,220,212,230,219,228,215,217,218,230,217,235,222,210,213,214,206,221,231,218,231,202,224,224,233,188,202,238,210,243,223,224,215,234,223,239,192,190,215,201,217,211,233,219,212,221,224,208,182,242,235,199,197,248,208,218,226,190,148,96,76,91,98,45,38,60,50,134,162,112,121,66,66,35,44,18,102,130,107,85,83,61,54,52,54,56,38,169,205,208,199,217,197,217,222,209,209,207,224,213,234,212,220,228,217,216,202,203,225,222,223,206,203,220,213,206,216,215,226,212,200,209,205,202,225,207,198,189,109,2,0,7,2,7,22,14,18,4,7,18,29,0,2,19,17,17,4,10,21,10,40,5,1,209,216,198,201,191,212,205,198,209,226,218,208,197,217,212,236,204,208,196,220,201,214,215,218,228,198,181,196,208,214,233,214,193,215,235,222,230,225,229,201,242,192,208,215,221,224,216,228,216,209,215,215,219,220,212,211,187,219,225,221,226,221,244,225,225,245,217,219,242,242,219,222,213,221,229,225,242,210,222,227,214,235,240,219,219,207,238,202,237,238,229,228,246,204,206,221,219,226,216,213,237,224,200,223,226,234,238,225,240,218,235,230,221,221,214,250,232,247,220,245,230,226,237,218,240,206,220,227,211,207,243,228,215,226,242,249,227,236,200,222,230,238,247,222,228,238,234,250,231,236,233,247,219,236,233,232,226,245,214,248,212,210,246,225,227,231,232,226,249,252,231,238,216,237,246,220,255,224,247,225,227,229,241,240,235,237,247,244,227,234,246,253,244,242,245,244,238,255,249,248,249,251,250,241,252,242,254,233,247,255,249,255,251,252,234,255,218,238,218,247,250,238,243,245,252,249,244,247,250,237,244,252,229,248,241,252,223,254,252,252,255,244,234,245,249,252,250,250,241,242,243,238,252,249,227,253,246,244,247,253,255,251,242,240,238,242,242,231,250,255,220,244,248,228,243,240,244,243,235,234,231,246,237,247,233,235,240,246,253,243,236,254,254,255,245,239,251,250,252,233,248,253,237,249,237,228,251,241,230,238,232,249,238,239,250,251,235,251,247,233,245,246,249,246,245,240,244,229,233,251,242,222,230,230,199,243,240,229,253,206,234,251,236,242,246,192,169,155,111,49,86,236,253,250,232,245,240,239,253,244,246,179,190,242,234,253,242,237,215,185,235,247,255,236,246,251,229,186,192,238,238,251,237,233,244,238,229,241,230,253,170,155,126,51,65,52,40,36,30,48,71,60,71,35,52,51,63,85,97,66,44,49,71,15,176,240,255,253,238,242,241,247,239,252,236,255,248,231,236,255,232,241,176,121,233,245,239,242,221,244,250,252,229,255,232,248,208,181,101,92,202,246,218,190,131,96,101,109,49,139,188,125,83,85,130,122,72,107,137,106,102,84,31,34,48,52,58,7,54,79,79,47,60,27,51,200,246,244,254,243,231,253,242,235,246,228,254,240,244,244,238,251,235,248,225,239,246,248,217,179,240,249,232,183,195,155,167,223,235,205,230,225,174,230,240,253,249,254,235,245,206,106,62,87,75,100,76,46,16,53,49,32,28,60,45,52,24,43,198,223,233,250,229,252,225,240,243,240,248,228,113,70,176,222,185,237,216,255,217,235,231,214,222,218,204,231,223,238,219,238,217,219,217,220,214,223,214,217,237,237,217,236,200,208,212,230,212,237,197,219,234,194,214,187,209,225,211,222,232,228,225,193,234,212,237,219,206,222,222,202,210,191,217,212,222,143,73,71,76,93,81,50,94,74,136,145,109,116,72,68,54,41,70,128,120,95,136,104,102,57,51,13,32,113,187,234,226,223,208,214,222,219,238,209,227,232,210,202,214,205,204,231,220,220,197,192,184,221,224,189,201,206,224,211,170,196,192,202,222,216,216,194,227,189,205,106,8,13,4,27,2,6,21,3,11,12,10,17,13,17,15,30,25,2,7,20,7,38,13,15,217,241,220,199,217,209,217,197,214,205,219,227,204,225,211,211,219,210,205,217,214,225,219,234,179,225,210,234,225,201,223,223,217,224,222,228,220,229,231,202,217,223,242,206,223,214,217,237,233,214,225,212,219,235,219,215,200,221,240,243,229,225,243,205,215,235,209,212,201,212,216,212,236,212,202,230,210,220,234,221,222,231,209,206,210,235,226,206,191,241,228,233,228,217,229,222,228,208,209,232,231,188,211,215,209,234,211,221,227,200,228,211,234,235,205,249,235,222,232,235,243,233,221,202,231,245,231,233,245,237,214,228,221,229,211,244,244,230,238,243,237,234,243,239,225,210,233,248,235,240,236,229,218,235,219,236,252,253,237,228,204,238,232,236,245,242,224,245,237,243,250,235,239,239,245,235,236,211,241,251,226,245,237,249,253,242,242,241,247,250,229,251,230,255,253,225,254,232,232,236,255,223,245,228,244,245,237,203,253,220,251,252,246,226,248,224,254,234,253,240,243,242,245,247,239,217,232,252,237,255,252,249,252,246,227,249,221,230,252,237,249,255,250,255,227,251,255,255,231,235,217,239,241,226,249,250,255,248,237,238,233,237,242,242,241,245,239,250,236,240,255,242,253,247,224,242,235,230,251,243,253,231,251,252,219,247,255,245,249,230,242,233,220,248,252,241,228,253,235,224,246,226,227,240,243,255,226,229,237,235,247,254,240,242,236,239,254,241,243,248,246,234,246,248,236,232,243,238,252,250,237,248,238,232,184,202,234,229,228,232,237,235,203,223,247,174,158,147,125,62,83,235,251,250,255,232,237,224,255,246,219,199,200,242,221,255,244,221,214,222,242,255,238,221,227,224,195,176,220,233,229,246,250,253,227,249,228,225,242,245,172,127,125,112,49,66,67,63,70,43,44,61,46,51,42,48,45,95,77,55,75,53,48,31,165,236,254,241,236,255,221,255,246,234,238,236,240,242,251,252,226,248,201,113,244,240,250,233,223,241,225,238,249,234,223,178,172,177,149,144,199,248,228,117,87,69,78,87,62,138,159,89,80,88,95,111,70,108,174,145,92,62,50,64,47,74,44,33,67,89,65,66,55,37,57,186,236,243,239,250,252,234,224,236,247,234,242,243,221,255,231,244,250,250,213,245,247,248,215,190,217,248,217,104,103,167,223,239,230,164,209,224,213,229,238,248,255,250,224,124,115,84,105,82,86,103,79,74,49,53,36,34,69,35,29,53,31,46,189,223,214,241,240,245,231,240,251,251,239,207,102,93,191,214,211,239,205,210,230,226,222,198,221,218,190,197,200,237,219,214,214,241,231,211,191,223,218,216,239,204,217,204,208,231,219,206,217,222,191,220,235,202,220,233,216,211,213,230,197,231,218,217,206,207,201,198,185,214,212,217,200,204,191,235,190,177,140,78,75,72,83,36,69,65,105,157,156,135,109,66,48,48,73,146,134,136,133,87,68,36,54,14,93,201,240,226,215,194,208,186,202,205,202,215,220,211,214,208,215,213,220,189,197,197,217,231,227,201,189,193,213,208,208,198,224,226,216,201,187,217,216,232,217,208,227,82,1,1,32,7,21,14,8,6,13,7,11,13,2,0,26,7,3,16,7,5,3,7,13,14,205,220,213,216,211,226,221,230,207,203,228,224,225,238,204,223,225,185,208,212,199,212,240,214,228,226,211,228,230,246,231,219,207,214,216,211,226,206,232,225,217,242,228,219,194,214,218,209,204,222,228,225,229,220,233,212,197,227,216,232,226,218,203,211,225,225,234,220,226,234,204,214,230,226,194,219,233,203,212,243,214,213,232,227,224,223,201,229,202,197,209,222,221,225,221,243,237,224,217,242,233,235,215,225,212,225,215,228,200,215,235,226,237,216,206,222,227,217,225,231,230,231,229,220,215,222,232,226,218,217,222,234,236,236,224,221,246,233,210,223,207,233,233,240,254,240,240,242,250,228,224,247,232,232,253,230,245,249,223,228,218,236,249,229,244,231,212,239,234,235,235,215,251,241,249,255,247,233,251,252,234,238,223,236,253,243,216,242,246,245,237,234,245,245,220,235,250,249,255,245,245,235,243,228,253,254,252,238,241,246,247,228,233,249,250,248,251,253,227,247,245,254,255,240,253,248,237,250,252,250,249,251,243,234,241,252,247,243,252,248,252,253,253,242,250,254,242,240,236,251,249,255,249,242,251,234,249,236,252,236,234,247,243,248,247,235,250,248,253,255,232,249,246,237,248,251,245,236,219,251,244,251,224,254,250,242,241,245,231,251,241,251,239,250,251,253,253,243,231,237,250,243,238,247,249,253,224,244,246,240,249,250,230,252,218,231,246,233,252,254,253,231,253,252,225,246,250,249,252,255,249,208,234,234,199,241,249,253,242,214,228,235,203,206,241,212,149,161,117,54,74,237,255,252,232,231,255,250,246,241,225,194,207,246,246,245,237,203,210,201,208,210,232,190,185,223,219,224,227,237,236,237,240,250,248,235,246,235,245,180,122,115,119,91,33,52,49,27,27,38,40,49,61,31,39,48,55,74,55,57,63,65,36,52,170,232,244,255,245,253,252,245,237,255,232,249,224,252,234,250,241,222,233,155,224,243,235,247,242,249,249,238,212,187,111,149,204,230,173,174,238,245,118,94,64,52,58,85,67,141,145,102,98,76,119,79,93,133,145,118,62,45,55,91,88,82,46,49,74,57,73,71,57,32,37,234,243,249,246,240,255,242,239,246,235,246,249,255,248,253,224,251,248,234,217,210,241,248,230,172,193,235,217,174,152,205,240,249,238,173,194,246,209,208,234,228,244,238,121,82,82,51,80,80,91,89,78,60,50,51,36,55,46,24,31,37,15,47,226,236,235,224,226,201,216,228,233,246,239,210,90,119,192,202,207,212,219,231,233,225,239,230,224,210,225,218,237,212,213,214,210,223,227,234,241,211,239,212,203,230,201,241,211,220,214,191,240,195,223,209,207,235,226,200,214,210,198,225,215,214,213,210,229,214,226,225,199,194,216,214,241,206,224,195,219,209,136,100,116,75,43,71,93,56,139,178,149,125,85,67,56,37,107,125,117,133,109,69,52,62,31,51,167,215,227,201,213,218,205,196,197,173,209,216,221,201,203,211,225,210,196,222,197,209,210,215,209,223,223,221,233,228,207,219,191,213,215,206,227,207,205,211,199,200,212,109,14,6,7,0,7,18,24,3,37,10,5,48,7,0,8,9,7,2,13,24,27,20,17,3,197,223,234,233,227,204,223,223,214,225,220,203,215,198,209,216,196,199,207,204,236,201,203,217,213,215,213,218,219,224,218,245,192,213,204,222,233,226,197,217,222,234,211,211,220,217,226,216,227,212,213,214,226,222,242,227,225,210,204,221,222,200,212,201,205,207,242,237,207,201,217,231,223,223,239,222,202,209,224,233,227,215,227,248,225,226,218,205,224,205,218,208,227,226,216,202,215,211,231,219,216,223,216,223,203,230,216,208,241,232,218,228,224,214,233,217,204,201,244,221,199,227,227,234,224,233,223,207,227,223,235,201,216,219,226,237,212,227,226,239,217,234,222,221,241,233,234,234,216,235,243,242,254,225,230,249,242,238,227,233,235,212,208,215,249,233,229,221,235,238,228,223,234,207,246,217,243,227,235,234,245,216,224,245,240,232,250,241,232,236,249,252,245,237,237,241,250,255,237,233,243,231,250,218,249,236,242,254,245,239,246,245,236,250,225,228,243,250,242,249,200,230,245,241,240,240,249,251,230,252,255,235,255,240,245,230,246,247,252,239,249,251,241,255,253,229,244,251,239,249,249,255,244,237,253,246,242,230,255,211,242,255,225,219,228,254,239,230,250,247,239,235,250,221,248,213,242,255,247,246,246,252,253,254,227,241,233,249,245,247,253,252,214,225,239,242,237,226,255,250,245,239,240,240,248,243,239,230,241,242,238,254,242,241,229,242,226,254,248,251,231,231,236,255,226,249,244,243,229,246,233,221,248,233,217,250,219,198,217,222,252,228,219,199,243,197,179,169,137,79,100,235,242,251,251,242,252,251,233,253,235,219,208,244,226,249,244,211,193,145,205,222,226,222,234,243,236,223,233,242,231,246,236,246,231,226,249,243,190,144,98,110,78,24,16,29,27,28,40,21,19,9,29,37,18,35,51,81,67,60,72,82,40,110,244,244,227,241,224,219,253,244,247,254,250,250,247,245,235,219,246,230,211,138,215,250,255,250,208,234,241,186,160,194,193,231,200,193,198,183,243,229,169,134,126,77,63,77,81,132,196,135,81,70,130,105,107,130,138,115,63,55,66,62,88,65,50,28,64,89,48,45,61,40,34,222,245,242,246,245,243,223,231,226,239,219,243,255,244,253,242,237,222,224,251,224,230,253,252,230,187,239,249,233,150,220,217,227,245,218,205,239,201,184,217,233,252,236,124,52,57,41,105,94,94,82,80,64,36,30,35,40,31,54,28,74,48,75,237,233,236,248,226,220,217,213,238,224,221,182,86,132,208,207,202,228,233,243,238,222,225,244,216,222,225,228,227,226,220,253,222,222,237,216,228,219,193,229,210,207,210,227,201,217,231,214,199,176,227,180,193,214,216,224,206,205,201,194,200,222,210,228,204,222,216,212,202,204,215,213,182,222,207,219,243,220,148,106,116,119,73,79,66,46,123,161,117,124,89,54,38,35,124,151,94,113,99,70,64,33,24,138,212,218,213,199,214,187,234,223,227,191,215,236,207,207,212,227,226,216,230,211,195,224,200,229,207,212,210,213,238,202,212,222,227,206,213,216,213,225,189,200,236,187,198,102,18,1,26,23,31,3,14,18,7,28,22,2,18,15,5,6,5,0,20,5,15,13,5,17,215,214,209,209,212,223,230,228,211,209,197,192,206,224,240,244,203,218,230,238,221,217,212,215,215,209,202,215,194,233,228,203,245,229,227,235,208,232,229,239,208,198,243,247,214,228,217,210,216,241,221,213,238,203,207,217,219,233,210,214,220,215,213,226,233,217,225,236,223,237,206,215,207,234,249,226,233,229,222,224,246,235,222,204,228,213,223,209,236,210,201,204,236,222,227,221,201,219,229,233,217,214,215,208,224,201,225,232,220,233,231,228,216,238,219,235,223,252,233,226,209,210,238,221,246,237,247,230,226,244,237,219,216,241,225,202,244,211,216,211,218,238,224,245,243,247,227,223,228,235,245,244,230,235,239,226,224,249,243,240,236,255,224,231,223,218,232,234,230,243,228,231,229,212,251,226,231,239,249,220,244,219,201,240,216,240,240,226,223,249,244,246,245,225,235,250,251,225,243,245,249,240,240,236,242,249,238,239,249,248,241,238,255,246,237,251,235,237,255,250,239,253,233,245,234,255,227,228,250,243,240,225,253,221,238,250,238,253,239,250,243,251,238,252,246,246,243,235,248,240,242,247,253,241,235,252,252,253,255,231,233,254,245,247,252,243,255,250,255,242,237,226,233,246,234,213,251,242,248,236,241,249,255,255,253,234,235,231,245,245,253,250,237,235,232,228,236,239,248,221,252,254,254,253,246,223,242,218,241,244,251,255,239,247,252,248,227,251,249,228,249,254,255,237,248,251,215,219,224,247,219,228,253,224,203,215,203,236,230,248,224,233,211,227,255,192,168,155,126,90,85,229,247,242,230,234,244,211,222,241,226,198,173,219,216,255,247,203,149,173,251,249,247,211,241,253,206,203,225,242,247,249,237,255,244,219,222,233,188,145,104,94,57,18,23,34,56,30,26,26,14,44,56,43,23,26,51,76,75,56,83,60,91,214,254,250,254,245,244,232,213,255,220,240,255,225,253,251,236,248,215,199,173,116,181,245,237,225,201,207,210,167,220,234,242,233,205,207,219,223,254,249,199,115,107,74,71,65,58,106,174,144,93,107,153,131,106,140,134,108,79,64,64,75,73,75,71,68,40,39,48,67,63,6,78,233,241,240,219,252,243,219,222,228,242,239,247,244,246,241,241,243,252,254,249,233,251,243,239,182,174,231,255,226,174,173,232,198,247,196,206,234,208,172,212,235,248,239,132,101,57,63,87,106,119,115,55,46,53,41,39,43,48,22,17,68,33,81,251,240,250,252,212,221,230,239,234,250,239,163,68,154,198,191,229,224,225,227,206,226,208,221,215,242,207,226,236,225,230,222,208,206,235,192,221,222,200,203,212,213,222,233,222,225,204,210,210,214,217,213,213,203,203,197,208,200,214,215,210,213,234,209,215,212,204,203,216,192,213,214,202,201,183,239,246,197,160,110,88,112,94,91,73,69,145,136,130,132,91,51,63,61,123,129,143,134,89,90,57,46,41,192,230,222,225,217,222,223,197,205,193,209,188,230,207,216,217,213,220,218,232,193,217,214,202,214,210,219,195,201,213,211,232,199,217,204,206,216,233,216,221,216,206,210,203,105,7,7,23,14,11,13,8,42,8,9,18,36,9,7,0,37,19,16,24,0,16,22,9,15,203,220,205,211,230,207,241,207,207,196,214,205,223,213,224,219,229,211,206,216,207,230,205,217,199,221,210,218,202,211,235,240,238,227,236,223,209,229,201,203,229,221,210,216,225,225,219,216,229,220,211,214,216,230,229,215,219,231,232,223,217,221,218,202,235,216,203,218,231,212,198,231,206,214,202,220,236,221,243,235,227,219,220,223,229,232,235,203,218,202,214,213,231,208,226,230,244,220,234,215,226,236,242,212,208,217,230,242,229,223,233,249,221,229,217,223,227,220,221,231,224,209,216,233,218,230,228,233,224,239,226,235,241,243,225,240,230,233,206,208,202,222,215,237,245,222,239,235,211,230,226,241,240,233,219,214,233,227,219,238,221,237,236,249,238,239,215,229,228,239,221,245,241,220,245,233,236,224,230,228,214,248,234,240,234,247,240,226,246,246,212,249,214,248,247,248,251,241,243,243,228,252,246,248,240,228,249,242,239,237,228,224,244,253,227,251,251,237,252,216,241,250,245,238,245,244,232,243,246,230,233,251,221,204,251,245,244,251,242,241,255,251,253,242,242,230,253,245,247,233,255,255,249,244,226,249,209,244,234,246,214,252,252,253,247,220,245,245,240,231,244,244,242,254,219,253,234,244,250,254,250,234,254,255,251,238,248,245,222,250,254,252,241,243,254,242,244,224,230,235,236,235,224,241,242,241,255,223,225,244,233,234,240,232,238,235,214,249,249,237,239,244,253,245,255,235,254,232,224,251,232,234,248,202,208,234,222,254,239,202,237,221,211,215,242,146,132,132,120,85,98,230,252,246,236,227,244,240,226,241,220,196,184,224,251,234,215,168,195,201,251,247,245,206,237,255,208,212,233,250,239,253,243,241,252,233,233,234,194,131,101,56,24,10,30,30,17,20,48,21,27,32,33,14,7,24,58,81,85,75,43,38,155,240,250,255,224,242,236,247,251,243,233,255,231,254,218,237,242,252,246,227,214,116,178,238,255,234,204,198,244,216,252,251,253,224,182,225,208,202,236,250,188,158,134,111,51,92,58,114,202,172,90,82,131,109,74,80,147,102,108,64,49,63,60,79,91,82,68,78,87,54,81,36,52,224,253,240,254,225,245,239,225,243,246,247,250,252,239,250,246,217,235,234,242,208,231,234,252,228,157,206,219,224,188,143,201,230,209,233,183,209,224,187,198,225,252,215,123,113,71,108,106,111,108,67,60,67,59,41,19,37,46,31,15,52,11,79,230,236,238,242,228,212,236,231,226,225,206,146,64,145,221,197,219,222,235,245,229,241,233,240,227,210,232,218,201,208,205,226,216,206,238,196,209,212,227,215,224,220,225,219,195,209,225,216,202,221,180,193,219,203,198,196,205,221,195,217,194,176,224,191,216,205,204,225,216,183,198,217,205,238,192,223,223,207,188,147,125,90,99,105,89,81,135,144,130,141,73,55,78,99,129,103,138,122,105,104,77,29,105,225,199,203,203,210,214,221,214,192,207,239,203,229,206,220,186,218,198,218,214,197,215,201,225,213,235,238,198,210,225,201,215,200,226,226,185,203,208,215,204,198,194,222,221,116,7,2,10,19,10,11,10,4,17,23,25,19,21,2,0,5,36,28,14,8,0,2,13,4,233,231,207,200,226,193,215,229,209,218,215,195,215,221,211,205,218,220,219,212,215,202,225,227,233,224,214,236,235,208,237,211,211,213,232,210,241,193,223,201,226,216,228,218,208,225,220,204,225,214,238,233,226,242,226,219,225,231,214,220,208,231,217,210,229,218,237,206,227,231,203,229,236,208,223,215,241,241,190,208,227,235,222,238,209,227,246,234,217,222,238,229,235,199,229,226,219,235,217,225,219,215,219,217,231,221,218,189,240,221,226,224,230,232,225,216,243,238,238,239,229,229,224,206,212,215,221,236,229,215,237,246,228,233,216,222,224,228,218,236,237,225,225,224,221,245,246,230,245,244,243,221,245,246,231,246,243,219,238,251,236,226,218,230,246,239,232,246,235,249,230,253,239,237,245,249,245,253,244,254,245,239,242,249,237,245,252,246,236,252,243,242,251,246,246,245,251,246,253,219,244,245,243,254,245,236,248,247,252,253,234,255,254,248,246,255,240,240,249,252,239,250,255,240,252,228,254,241,246,237,232,234,245,250,254,248,223,228,242,223,252,254,232,251,250,235,244,216,242,235,232,245,229,228,243,250,255,239,220,243,244,246,247,214,239,237,253,250,233,239,252,255,248,229,214,246,239,244,243,226,231,248,254,239,252,216,240,246,255,242,255,241,254,238,243,252,246,242,237,216,252,243,233,254,227,244,247,238,236,247,250,243,253,249,239,245,249,254,236,234,237,243,236,244,238,237,248,241,236,245,243,219,236,220,221,236,243,244,205,216,238,252,213,207,237,178,137,153,139,81,120,217,247,230,248,230,243,244,232,253,242,210,170,235,254,245,203,180,212,234,241,254,243,200,240,249,225,177,249,249,226,249,248,255,228,246,219,248,170,99,67,32,8,26,17,37,30,20,25,31,26,48,47,54,45,49,49,67,51,42,61,33,175,235,247,232,223,241,236,251,246,228,235,239,234,236,255,245,237,231,255,244,235,175,152,252,251,201,202,249,243,245,255,249,242,163,74,151,170,220,240,254,202,118,129,91,52,89,122,149,146,112,57,47,70,72,36,97,119,146,99,68,46,80,65,62,83,86,62,89,93,35,52,3,60,217,237,238,248,251,245,254,242,213,243,250,243,253,241,242,243,247,205,233,241,247,234,241,255,220,184,198,242,242,208,169,182,219,168,219,210,218,200,217,187,210,252,245,99,123,55,66,72,71,43,55,10,42,35,34,26,37,30,18,29,47,15,87,230,235,235,254,227,242,254,238,237,236,254,147,118,179,223,188,229,212,236,241,251,229,227,218,201,206,239,230,227,231,224,232,232,216,203,202,198,226,216,186,214,219,215,208,222,234,220,219,223,212,213,235,221,215,232,199,234,219,212,206,194,233,200,196,219,203,203,203,208,186,218,224,183,194,212,222,235,213,218,119,124,106,99,92,74,75,135,124,123,107,65,69,97,101,128,128,124,129,120,122,95,22,51,160,180,228,226,209,238,199,221,228,214,206,220,219,221,196,201,201,200,201,210,217,220,201,239,235,196,189,207,196,198,194,199,202,196,220,213,200,223,229,239,221,206,195,195,108,13,5,22,3,2,7,16,3,15,3,0,0,1,19,27,2,0,14,20,3,12,9,22,11,206,232,204,235,218,218,217,184,209,227,220,217,208,218,232,232,215,204,205,206,224,207,201,220,224,218,206,214,234,235,238,213,230,220,205,217,248,206,215,232,229,212,219,215,234,211,227,217,211,204,222,212,221,231,213,205,208,234,223,233,219,220,213,202,219,221,227,232,241,213,221,210,208,214,243,239,228,209,196,237,208,231,196,215,240,215,211,221,198,232,225,248,229,230,230,218,199,233,210,227,237,218,216,218,206,231,247,213,222,224,225,227,213,225,243,229,223,215,233,223,229,217,216,225,225,238,228,214,221,223,227,241,231,223,238,241,210,225,234,224,231,238,231,221,244,245,234,235,237,216,241,238,242,238,219,226,226,219,250,241,227,246,219,234,234,249,227,223,242,250,228,230,230,227,244,216,245,218,237,225,230,250,244,235,241,242,235,239,250,218,254,244,232,230,231,239,240,236,246,236,235,245,230,243,238,231,241,239,244,226,240,255,255,225,246,239,223,251,235,218,234,248,240,242,241,226,255,237,247,253,220,236,252,255,239,255,243,247,227,242,255,236,255,234,243,250,223,247,239,242,255,252,255,252,236,237,251,245,240,249,254,251,246,229,245,248,241,255,233,249,242,221,247,230,226,251,253,253,232,250,246,245,239,241,253,252,254,255,255,242,221,220,247,247,236,250,252,238,238,240,238,238,243,224,246,248,235,249,233,253,222,236,247,251,222,243,253,250,231,241,255,228,241,243,252,255,251,237,237,246,204,253,244,219,235,231,179,223,220,207,250,237,224,214,249,206,150,152,134,83,88,221,230,250,241,255,255,225,240,251,227,223,209,221,249,237,215,198,206,241,252,255,229,188,231,249,238,234,255,254,243,251,247,201,236,251,217,249,167,121,74,68,66,11,3,3,40,25,14,36,41,74,71,49,27,44,45,10,23,55,100,134,239,237,254,242,250,251,232,245,221,223,237,255,235,255,249,248,245,252,243,226,255,174,185,227,228,198,230,247,255,230,252,250,233,155,96,158,184,221,253,246,147,113,57,51,21,105,145,167,147,69,31,34,28,68,66,68,120,98,59,68,72,48,75,68,91,49,82,117,102,53,91,16,56,226,240,240,230,244,250,240,252,222,251,255,214,252,246,234,241,249,246,219,253,236,204,241,251,239,184,192,235,231,201,181,187,232,184,189,252,182,212,249,234,213,246,193,93,56,11,3,13,8,12,9,5,28,63,29,46,33,42,34,30,54,28,92,237,225,254,212,244,242,255,226,247,234,235,140,115,213,197,198,239,221,223,206,243,198,223,231,224,230,227,202,233,234,208,216,227,233,233,180,223,217,219,225,224,227,222,231,227,208,197,225,186,204,190,229,215,214,230,204,199,214,192,224,199,226,216,218,241,187,204,220,219,196,205,206,207,198,199,194,204,207,137,161,99,103,79,90,78,77,121,117,142,114,75,61,86,116,144,98,116,131,121,99,77,44,40,106,163,224,220,211,209,211,232,231,212,213,210,226,204,215,222,236,226,207,219,228,226,194,231,211,238,225,199,207,193,208,232,185,206,212,232,207,220,203,222,214,205,214,203,113,10,0,12,42,7,5,17,2,15,27,16,16,10,0,8,4,6,6,13,27,18,26,21,2,237,228,231,188,236,221,242,227,217,202,232,234,217,235,223,183,204,194,218,217,223,196,201,220,199,205,232,196,230,227,200,219,217,225,231,223,218,228,214,228,221,241,214,213,216,221,242,239,213,198,189,227,212,223,226,213,225,232,225,229,195,209,220,234,209,223,210,210,233,214,216,216,211,233,212,201,225,233,204,225,215,207,227,218,196,201,222,231,227,225,236,210,218,249,230,238,195,214,230,225,216,218,220,222,217,242,214,219,230,226,220,236,205,208,216,227,216,226,231,212,232,228,222,222,212,229,214,210,195,224,216,217,228,217,232,219,216,209,242,232,228,218,249,227,243,232,234,208,230,237,230,237,236,243,231,239,236,214,214,246,217,245,219,242,225,224,236,233,240,229,245,242,233,248,230,239,247,252,252,237,233,238,240,232,241,239,246,246,250,252,235,215,249,244,247,237,242,238,253,255,234,240,233,247,248,252,248,233,237,246,235,252,222,254,248,247,245,246,228,228,244,246,236,228,253,254,249,255,242,251,248,233,255,242,227,249,246,245,241,248,253,241,231,251,251,251,253,236,238,245,242,234,239,236,244,250,249,246,238,255,251,252,236,255,235,230,231,246,240,255,253,255,248,235,229,255,230,249,252,251,252,247,251,251,251,247,249,253,254,241,246,238,243,246,231,240,235,248,235,248,254,230,244,239,237,250,228,252,229,247,231,211,255,255,251,240,255,239,234,228,225,240,252,233,233,222,237,252,233,252,239,231,241,207,213,215,241,245,251,240,255,231,231,202,243,192,176,145,146,66,108,235,246,249,255,246,238,243,233,246,219,199,169,184,245,251,232,205,186,236,237,250,217,208,227,243,244,208,226,255,250,238,255,240,246,237,242,209,220,189,168,169,216,220,232,179,87,30,52,40,45,55,92,41,40,75,85,115,81,182,205,186,246,251,241,238,230,255,232,235,249,233,235,242,244,250,248,243,246,245,232,223,248,184,140,217,184,192,243,242,223,245,245,248,179,81,176,216,188,245,253,254,181,133,128,92,99,165,199,200,212,140,51,75,107,108,108,119,126,70,76,73,51,66,49,76,92,38,86,92,49,69,65,7,70,225,252,229,255,248,243,234,252,235,240,237,250,246,246,246,255,222,219,250,254,244,240,228,252,254,179,164,251,225,238,203,162,152,148,210,232,189,160,232,222,199,229,198,102,71,72,74,66,60,46,38,37,53,38,32,33,52,41,50,28,42,8,127,239,243,253,232,229,245,232,255,247,243,254,148,122,221,209,202,224,222,234,225,209,219,224,226,234,209,230,222,217,236,226,216,205,243,229,210,207,232,228,219,229,199,230,204,198,234,214,226,232,231,211,213,205,213,200,212,226,205,186,209,220,192,194,199,211,192,206,199,211,195,211,204,221,205,223,201,216,180,146,130,143,121,86,86,76,85,122,120,128,120,81,98,95,113,115,99,94,122,99,90,57,28,82,211,190,208,219,219,218,219,223,191,204,222,206,198,204,200,215,212,213,228,215,204,224,224,237,204,202,214,201,194,215,200,219,218,194,215,205,202,227,192,186,203,215,198,179,115,10,16,11,13,18,34,4,5,10,10,25,4,11,14,7,24,4,8,10,43,17,15,7,39,205,219,234,211,223,220,210,235,204,193,224,214,228,214,212,244,225,211,221,218,203,226,228,214,230,219,202,229,241,219,197,204,212,228,240,249,241,228,232,227,215,217,224,216,201,219,231,232,213,189,224,212,206,212,230,200,208,216,220,230,210,212,179,204,208,229,211,221,214,202,222,215,208,217,235,212,238,200,218,227,232,220,241,189,228,227,216,219,234,217,228,216,231,223,208,203,226,212,223,243,228,203,206,216,210,251,208,232,207,236,228,236,221,251,205,200,211,230,219,242,228,207,242,217,235,205,225,226,212,242,212,210,243,215,217,235,241,226,232,212,234,245,220,242,230,231,227,231,211,255,223,245,220,218,221,243,227,231,227,234,244,233,235,233,219,238,224,230,235,231,254,238,242,216,242,228,237,245,251,228,228,220,242,236,241,245,239,244,252,233,237,239,228,219,246,233,243,232,225,232,245,249,233,240,242,255,236,232,232,232,249,240,232,225,240,231,224,239,242,235,225,242,243,235,242,246,225,234,239,248,250,250,255,252,245,247,249,249,255,237,241,230,228,255,253,246,251,252,220,249,250,253,235,238,255,250,245,239,252,231,255,254,254,244,241,237,238,235,231,238,224,249,243,244,233,249,253,228,240,232,245,253,216,237,235,232,236,254,245,212,231,218,251,229,227,234,253,231,246,244,239,246,232,253,231,254,254,254,247,229,241,213,223,239,249,247,244,255,253,236,249,252,228,243,243,248,255,232,241,244,231,208,252,215,238,239,255,253,194,218,221,229,216,237,245,174,134,122,118,84,94,223,254,253,243,242,253,226,249,243,253,217,170,209,223,248,201,184,229,244,242,236,228,238,241,255,227,134,172,239,213,238,248,253,253,255,255,248,247,218,254,237,252,255,254,199,111,11,84,108,58,51,74,74,65,197,238,224,144,221,164,146,250,245,229,224,222,246,246,250,254,241,250,251,247,241,242,233,247,242,251,233,252,196,156,183,159,197,238,245,254,226,169,218,173,128,225,212,212,230,255,247,251,194,142,139,170,191,217,202,226,136,96,114,149,159,148,150,151,120,95,71,67,73,13,69,72,65,47,99,87,40,41,19,61,227,231,240,245,253,242,235,250,246,228,244,232,224,234,255,246,244,245,235,240,249,238,200,255,246,179,168,198,225,215,191,80,144,202,196,219,171,180,248,215,130,197,206,242,219,245,244,233,252,246,255,253,234,145,96,99,85,54,31,22,11,34,132,247,212,239,232,251,250,239,254,231,209,222,109,165,240,202,215,233,228,223,231,243,245,199,226,211,199,215,230,205,230,224,246,229,223,211,214,228,215,205,198,195,218,195,198,218,213,201,205,197,229,188,193,209,223,217,197,208,230,193,201,240,209,213,179,183,209,200,228,195,213,187,208,189,192,202,204,229,214,137,121,120,116,89,72,99,80,118,144,126,130,102,121,146,135,130,99,133,104,125,98,79,18,102,229,213,244,214,218,224,225,214,232,187,228,203,224,227,211,199,236,232,215,205,223,207,198,225,209,185,198,211,206,202,214,224,207,196,197,197,201,191,217,195,207,242,215,198,105,9,1,7,8,3,1,12,17,20,12,24,10,8,9,9,7,17,14,15,18,7,36,18,11,213,216,181,233,236,211,210,226,213,240,203,214,217,202,212,216,225,211,212,221,221,237,224,218,214,237,231,228,207,218,202,222,197,223,225,243,221,226,211,222,194,224,224,233,202,231,208,221,217,228,246,240,226,226,214,224,205,198,247,232,211,219,223,235,203,225,207,219,225,222,210,223,208,218,231,214,226,207,227,211,239,208,227,223,213,217,213,182,210,219,205,226,218,232,224,221,235,204,222,231,218,221,214,220,216,217,225,229,207,219,226,215,217,234,230,223,235,228,205,213,234,244,227,222,221,239,234,214,226,218,229,232,206,233,189,229,234,237,225,244,245,217,227,241,234,244,238,248,217,248,215,229,233,237,224,218,243,249,240,213,232,239,247,246,244,250,214,244,211,219,232,239,237,232,240,252,246,247,226,243,255,252,222,231,214,228,228,243,224,238,242,228,229,244,253,251,242,240,247,253,220,226,252,233,251,244,222,239,246,254,228,230,235,252,255,242,249,245,225,221,255,235,241,226,250,244,237,249,253,241,252,250,252,254,246,251,253,252,236,240,250,243,219,239,253,246,249,245,235,252,239,253,253,228,223,253,250,242,225,253,238,249,248,255,248,254,254,242,255,249,224,249,252,243,255,255,208,251,246,255,242,225,248,249,252,238,248,239,239,231,224,250,249,233,252,238,225,240,249,235,235,228,239,235,247,250,246,241,250,255,250,223,251,234,231,242,229,231,234,234,247,234,251,250,252,254,246,248,242,227,232,254,255,242,237,226,173,171,184,232,224,213,196,226,216,175,135,149,163,66,102,242,247,247,240,231,235,211,244,234,245,245,210,228,243,239,202,174,228,248,218,238,223,169,252,239,187,89,72,210,236,242,247,227,233,254,227,246,248,234,226,211,251,243,249,169,86,23,67,121,84,66,64,56,67,234,255,255,178,101,13,73,221,236,255,203,221,238,232,248,246,238,241,232,225,255,246,235,250,247,239,215,206,194,164,186,160,219,246,237,235,128,166,222,136,158,237,203,254,249,252,253,250,175,115,111,122,85,88,79,94,87,81,61,45,56,50,76,50,64,69,87,75,77,36,43,78,59,71,99,93,55,38,2,50,220,239,247,230,252,245,240,240,237,227,248,246,250,244,237,253,227,243,207,236,238,232,217,255,252,209,177,228,241,217,204,143,186,218,236,233,238,217,252,218,150,219,236,215,245,250,252,255,250,252,252,250,255,187,118,132,88,48,19,28,33,25,133,230,204,233,235,242,248,241,248,225,162,176,112,164,227,214,205,204,224,214,227,215,213,243,207,220,207,216,226,199,219,207,223,207,227,228,213,208,196,215,211,214,180,219,194,229,185,205,188,212,212,204,206,212,214,222,207,193,205,224,224,216,198,233,216,198,209,223,225,205,195,222,211,199,209,214,218,224,177,158,152,130,136,94,82,69,93,138,167,157,141,114,106,102,111,102,90,104,154,122,110,42,30,197,208,218,225,237,230,213,212,221,198,223,221,198,215,214,211,235,217,200,204,233,188,201,220,202,200,204,224,249,192,207,198,232,216,235,220,219,189,201,205,204,206,221,207,208,118,6,7,0,4,2,7,19,0,7,6,16,16,24,7,7,1,5,4,21,15,14,30,37,14,207,221,219,228,235,220,240,214,218,206,201,208,217,248,212,211,225,214,226,214,205,206,219,204,210,213,208,223,200,231,214,230,188,207,199,249,217,205,237,221,217,208,234,213,197,203,207,222,223,230,187,228,237,236,223,227,196,198,213,214,233,214,217,214,234,225,244,210,221,225,224,204,225,207,211,196,219,216,218,210,206,206,203,191,211,228,208,221,215,249,220,242,239,235,240,215,250,211,230,227,230,220,231,196,219,222,217,215,213,213,222,234,237,201,212,224,227,217,249,226,220,227,219,216,218,209,224,206,200,222,204,230,243,193,234,226,214,224,233,213,190,206,244,232,232,234,228,247,215,229,230,253,221,222,250,237,240,234,216,227,227,239,219,249,236,251,217,232,236,248,243,239,236,218,252,232,245,250,236,240,252,231,252,220,255,236,251,233,224,249,251,230,253,236,241,245,221,243,247,253,235,253,246,246,253,239,240,254,218,250,240,241,249,223,248,245,236,236,241,228,233,252,242,213,243,249,240,254,224,248,246,248,254,228,247,251,228,255,255,243,253,241,251,238,248,238,252,244,251,249,255,249,241,244,223,252,238,243,254,216,228,251,224,254,243,244,228,229,255,233,247,255,225,240,245,255,235,252,247,244,252,229,245,246,235,234,231,224,252,234,222,255,244,249,248,248,246,243,219,225,237,248,227,239,229,228,226,246,248,244,240,223,232,245,250,244,252,254,248,245,253,235,255,249,255,238,233,248,236,245,231,233,252,235,216,176,209,223,198,231,244,233,213,231,247,205,153,155,148,117,103,252,244,247,243,214,238,246,223,249,255,230,213,193,251,231,200,230,217,246,219,252,186,112,195,200,164,50,43,168,245,239,249,252,227,232,239,241,254,213,223,188,220,250,214,146,99,26,50,123,63,68,73,24,22,216,252,217,66,22,24,91,203,236,235,198,242,228,229,251,232,228,235,239,249,235,255,239,241,247,255,208,229,211,202,155,123,213,218,136,172,190,255,255,160,191,228,232,250,249,243,223,248,140,119,80,36,7,3,0,59,114,97,47,30,40,22,44,70,49,55,28,68,62,56,73,101,65,52,93,111,68,52,21,59,217,246,240,234,242,255,255,243,224,211,215,247,242,226,242,255,254,239,231,248,244,238,222,222,254,211,181,195,244,241,242,218,180,220,206,241,218,161,242,213,212,225,212,246,248,246,252,214,235,247,247,246,254,175,128,132,83,67,13,45,11,27,201,250,241,238,220,249,250,254,239,217,192,204,130,187,217,190,202,220,242,202,218,230,218,218,216,216,228,196,237,219,200,229,225,210,203,220,223,189,228,199,219,211,185,221,234,209,225,196,199,214,217,206,198,185,168,217,218,194,217,217,193,213,207,214,208,206,191,212,217,190,202,207,221,219,223,218,213,205,211,163,131,107,109,97,75,90,110,148,119,122,120,91,73,64,64,68,100,133,139,102,107,69,39,163,209,218,205,222,206,218,215,202,204,231,235,198,216,204,189,199,211,227,205,210,217,239,207,204,228,183,239,226,193,224,232,196,207,214,222,205,191,207,196,216,206,191,220,208,133,5,20,17,9,6,27,14,0,19,8,12,12,7,23,22,9,5,30,18,11,14,15,20,7,233,217,214,211,228,221,224,233,219,216,206,230,235,228,201,204,246,222,225,221,218,199,205,224,223,194,203,223,217,201,192,232,237,225,216,204,220,220,224,221,218,236,233,226,231,191,224,216,207,214,211,229,208,226,211,220,242,206,210,216,206,208,225,219,203,201,212,234,210,231,231,213,220,213,212,209,207,205,202,217,221,235,234,238,219,233,210,206,224,204,209,237,209,214,198,233,226,219,207,224,193,206,229,238,240,235,230,219,220,215,240,225,198,217,230,212,234,215,240,231,225,219,228,228,209,217,206,241,237,233,224,208,229,219,199,218,225,224,220,212,233,216,231,213,227,237,226,242,241,236,229,223,252,243,196,230,223,243,242,240,240,236,217,229,223,230,247,220,240,244,233,224,244,251,244,242,250,245,241,243,230,255,233,227,237,245,236,243,225,248,243,205,243,254,248,236,252,230,231,240,250,240,251,218,241,243,252,255,221,231,219,237,239,244,229,249,255,247,240,239,254,244,236,248,249,255,253,240,229,251,240,237,242,246,255,251,255,249,245,246,245,245,229,255,243,234,246,248,250,252,222,240,253,253,217,244,255,244,238,246,240,227,224,235,231,245,244,236,225,251,252,238,231,217,248,252,247,255,252,236,242,252,235,238,231,245,234,254,238,242,247,237,230,245,233,245,249,226,227,245,241,241,234,240,254,219,250,250,236,245,231,239,254,238,239,250,253,252,242,225,244,245,238,245,247,245,238,221,239,227,199,235,228,190,221,222,244,231,221,235,248,228,213,233,253,157,165,142,126,119,154,233,246,255,249,247,247,241,246,240,245,241,217,218,230,221,238,195,233,235,240,253,121,35,174,196,193,96,15,107,209,230,254,242,242,254,232,218,245,198,209,173,192,233,163,133,93,0,63,78,71,47,52,47,20,200,249,135,34,2,28,147,248,250,239,194,244,255,254,246,231,227,242,234,236,238,230,230,246,247,253,196,146,165,192,205,145,200,200,199,235,222,255,210,81,209,237,178,233,250,253,254,242,233,94,90,7,37,30,22,24,71,34,48,49,44,48,62,92,50,30,47,54,64,30,92,70,68,39,111,106,53,42,55,78,211,252,246,237,255,231,241,250,233,220,243,236,248,235,242,240,242,247,223,228,253,214,233,217,252,243,158,183,211,238,227,215,159,209,223,244,221,176,206,214,224,218,210,253,255,245,242,241,236,238,235,255,243,143,86,109,85,34,52,54,20,33,200,240,225,255,226,226,250,235,221,179,192,171,152,224,206,203,198,205,229,207,251,211,232,196,213,235,217,211,228,216,200,202,237,223,225,217,207,210,210,204,220,196,183,205,198,215,193,215,220,209,203,201,200,201,202,210,192,200,197,224,208,210,203,231,181,201,199,200,213,206,217,212,186,202,206,194,206,220,173,140,133,75,89,89,79,115,126,131,147,97,66,59,64,49,61,66,87,84,107,82,67,43,4,138,214,218,231,230,207,204,211,226,218,229,217,198,223,226,194,216,222,206,216,208,191,198,214,206,200,197,211,197,208,207,224,205,224,210,228,234,177,239,209,223,232,211,187,206,113,2,2,8,13,18,0,6,1,31,18,14,10,6,9,9,17,23,0,12,8,5,0,14,7,226,220,233,210,224,224,211,207,198,209,222,217,233,220,189,217,226,203,224,188,214,214,205,231,223,207,216,212,209,227,203,212,192,220,227,236,210,213,210,240,221,223,231,224,224,212,220,214,201,219,198,236,214,226,214,211,231,225,241,224,216,225,236,222,221,232,227,224,217,222,196,212,226,215,229,212,218,185,212,219,208,215,207,228,212,218,212,209,218,212,228,220,219,223,235,215,212,244,202,227,218,240,237,230,247,202,228,206,203,211,181,234,231,227,224,198,193,230,208,249,222,228,219,228,234,238,208,208,219,233,209,216,242,244,205,236,248,239,212,223,246,227,224,225,249,243,219,231,239,224,229,244,229,220,241,212,244,233,216,243,246,250,248,220,229,239,234,233,236,236,247,251,254,247,238,208,238,230,245,248,231,235,231,246,251,245,234,254,244,232,233,221,247,246,222,243,220,224,244,247,253,253,247,249,236,243,234,229,241,250,239,250,248,250,232,231,240,255,232,252,228,231,250,254,246,236,248,239,245,242,225,237,247,249,237,246,221,214,247,234,227,242,249,248,247,252,246,248,248,243,255,242,240,249,255,233,251,247,253,240,229,234,225,248,230,254,236,242,235,233,237,246,227,227,250,250,248,227,238,250,252,245,245,243,239,246,255,232,228,249,233,252,243,245,238,248,249,252,239,245,248,224,223,233,247,255,253,243,241,229,250,240,237,234,233,237,251,244,237,224,248,244,253,248,255,238,233,252,248,209,189,230,227,215,216,237,236,232,183,217,222,200,206,239,238,167,161,124,97,114,101,143,218,233,235,237,250,233,242,252,245,244,211,224,241,201,173,135,188,235,236,224,122,59,116,193,202,152,74,151,236,246,255,235,230,249,250,208,242,220,188,150,224,238,152,135,79,5,77,79,80,90,76,24,21,198,250,141,39,72,206,233,239,249,241,167,246,255,254,253,231,242,251,240,247,251,230,226,249,237,238,160,76,68,160,138,201,252,243,253,226,230,246,152,102,179,188,211,251,247,240,249,232,230,157,81,50,51,32,26,92,76,86,66,33,38,65,80,80,33,59,41,37,45,46,82,62,91,70,108,95,48,80,16,51,202,227,255,232,237,253,242,235,254,215,238,243,245,249,243,220,237,249,233,228,229,236,233,239,251,252,186,169,212,232,241,210,174,192,242,228,201,209,180,207,207,219,193,229,255,246,223,235,228,233,232,251,249,149,100,90,86,59,35,38,19,50,216,243,230,241,255,254,237,195,226,207,210,178,179,208,224,212,196,218,219,214,225,222,215,208,208,224,184,217,233,234,220,237,227,206,226,211,211,193,215,219,209,219,215,187,204,207,215,190,200,185,201,197,181,187,202,210,213,193,223,206,202,161,217,192,226,213,224,186,209,198,200,224,197,219,199,203,206,220,175,115,114,111,100,75,61,123,159,136,147,145,101,67,64,83,66,90,92,116,95,66,45,35,164,225,209,216,213,222,184,214,184,213,208,240,229,231,229,203,214,223,219,219,227,218,217,231,228,225,227,226,221,197,217,210,219,213,199,217,208,212,208,194,210,208,200,228,220,228,110,21,0,8,0,3,2,11,24,17,25,33,2,7,12,1,12,18,14,26,14,0,12,2,31,211,224,203,218,246,194,222,213,202,225,220,213,218,218,204,207,215,231,178,226,213,231,216,225,207,206,210,215,204,211,236,218,206,206,217,213,198,215,219,209,213,205,232,201,208,204,213,205,206,233,222,230,228,217,200,249,204,192,238,209,213,219,192,231,238,235,235,219,230,208,215,218,216,243,196,195,198,206,230,202,212,246,211,194,230,220,222,220,236,227,223,215,211,229,231,221,224,224,234,227,225,219,236,227,202,216,219,234,190,218,199,202,205,225,207,226,236,224,207,225,229,217,218,214,220,229,228,236,230,223,206,222,219,243,250,223,219,218,218,225,230,235,232,215,227,215,220,222,224,236,239,232,235,236,236,203,223,234,220,231,220,251,227,236,232,239,241,232,251,246,236,240,250,237,234,237,247,223,253,248,233,251,232,254,245,229,240,255,249,245,252,240,225,247,244,249,237,236,239,247,237,243,252,228,242,245,250,246,242,247,253,236,237,255,245,239,253,253,249,241,229,236,250,244,255,231,255,239,237,241,240,240,238,253,216,235,238,237,242,235,252,249,253,250,246,230,241,252,252,255,241,224,249,239,238,246,242,255,252,233,232,237,249,254,237,249,246,246,243,234,249,224,210,252,231,236,230,250,239,199,234,254,249,248,255,232,234,244,254,237,242,255,241,230,241,251,235,255,227,232,249,246,252,236,253,251,252,253,246,246,255,237,245,235,233,237,228,244,224,240,247,252,242,240,254,249,245,241,252,241,216,205,230,246,249,198,219,152,197,232,219,204,209,242,252,171,128,155,124,73,60,67,73,149,248,253,245,251,253,255,233,252,231,201,112,116,119,43,114,203,228,233,176,48,72,154,228,194,150,205,236,241,246,250,245,254,225,243,227,174,179,196,240,247,184,154,67,14,89,84,64,71,70,41,29,223,247,224,72,196,240,230,238,250,231,175,247,246,245,255,238,230,236,225,238,249,242,230,255,239,246,205,36,16,46,99,232,237,240,223,120,198,230,131,177,232,221,249,246,253,242,238,255,228,207,141,114,44,36,89,143,92,75,53,31,41,50,71,54,42,70,47,51,9,65,84,62,85,53,115,105,95,85,50,62,218,240,235,250,255,255,243,230,250,226,227,252,243,241,236,251,255,253,234,213,233,244,226,211,246,246,196,154,197,241,238,218,176,163,239,211,182,231,195,160,212,230,197,176,214,225,232,240,239,249,239,252,233,127,129,72,76,61,19,26,36,84,244,255,232,245,224,224,215,189,219,213,200,187,184,228,224,200,198,205,219,206,235,206,218,213,220,221,221,209,230,221,217,207,207,215,212,214,189,220,217,220,211,217,208,224,220,217,224,208,232,189,191,210,209,181,178,185,204,208,195,206,198,211,220,192,200,227,202,231,189,224,208,192,191,230,221,228,204,215,199,176,127,119,120,99,132,181,168,166,160,161,119,105,103,69,84,80,136,110,82,88,64,110,215,227,233,207,233,196,215,215,215,238,221,214,210,225,224,223,215,225,225,203,185,207,215,198,179,193,218,219,211,224,234,213,209,188,215,189,207,219,211,204,210,232,242,212,198,192,113,5,2,3,30,6,22,21,13,23,12,22,20,4,8,0,15,7,0,8,6,44,25,13,13,230,208,236,210,203,220,220,242,231,228,195,219,210,213,238,209,230,205,203,206,208,210,231,211,208,207,210,222,234,215,206,214,205,214,236,218,240,218,216,215,219,199,213,236,218,240,218,216,213,212,250,210,232,210,213,210,208,249,204,221,234,217,215,223,207,208,206,220,221,215,250,237,206,239,210,208,206,212,212,233,235,252,219,216,208,218,225,228,225,217,201,218,221,220,228,234,207,215,216,241,205,214,227,215,200,226,228,237,213,200,236,218,224,202,200,241,234,224,219,229,214,222,228,215,210,238,230,231,240,201,219,233,245,240,248,240,235,218,214,196,239,229,229,229,222,206,231,253,231,235,226,243,228,211,239,230,240,228,222,247,246,231,226,228,240,242,221,255,253,241,240,238,224,215,233,246,223,228,243,235,249,238,255,244,233,253,238,232,235,218,250,248,244,246,242,241,250,240,232,242,236,219,227,247,237,237,244,239,227,247,252,247,235,227,234,245,219,255,255,237,224,252,223,247,244,226,250,246,224,229,247,254,240,250,250,242,238,246,220,231,255,253,247,246,241,230,237,246,248,236,243,230,246,246,245,236,221,236,239,234,239,246,244,222,253,232,231,255,252,243,243,239,248,239,255,234,255,247,247,255,227,241,254,227,237,231,247,246,245,236,232,249,252,246,243,236,231,232,219,252,229,249,255,247,243,240,247,238,245,249,248,255,236,235,242,243,233,252,236,239,254,242,246,239,220,253,255,223,250,216,212,246,209,248,210,169,244,206,224,225,242,206,212,252,253,198,170,178,115,74,61,43,24,66,193,231,249,245,234,236,249,253,231,202,60,108,104,1,54,213,255,238,165,130,145,197,232,220,173,212,244,241,253,226,217,238,241,236,231,210,180,170,222,244,163,129,53,1,91,118,109,55,52,38,52,217,248,185,164,246,247,243,236,240,226,184,244,245,218,225,227,252,239,233,229,247,234,226,243,242,241,160,58,66,40,82,234,248,231,214,166,244,228,174,232,238,197,250,254,233,251,232,242,241,238,233,84,57,13,54,107,75,48,46,78,34,57,78,38,57,79,66,18,1,24,101,78,57,34,109,115,68,61,47,57,184,250,251,249,239,255,242,230,244,238,212,233,238,255,244,230,251,250,254,214,234,243,247,227,250,246,215,150,197,244,245,212,164,125,166,174,150,242,207,142,188,237,172,193,200,239,247,239,228,246,253,255,224,145,91,82,87,54,54,28,22,114,237,222,220,239,247,232,181,230,219,216,207,141,205,232,220,225,197,198,229,214,216,207,200,248,204,232,195,203,208,215,221,216,217,227,196,227,203,203,200,211,186,202,217,224,221,180,220,211,206,208,203,211,218,187,186,215,215,209,212,219,223,201,215,202,220,218,193,193,201,219,231,207,183,207,200,203,212,238,204,146,161,122,112,84,89,133,105,97,96,96,78,66,44,32,59,61,57,94,60,38,46,90,219,229,238,253,214,211,223,213,227,234,236,215,191,221,207,191,213,203,229,218,218,216,228,227,222,204,206,216,226,217,195,213,233,198,199,194,202,215,187,205,222,215,216,203,214,203,134,2,14,19,21,7,9,5,2,23,4,10,17,17,2,11,17,27,10,18,12,23,23,8,33,219,216,227,209,198,224,247,233,203,226,221,224,232,227,232,226,207,208,226,223,225,215,216,227,218,213,201,222,216,218,217,222,196,219,242,231,224,222,223,234,227,236,233,226,207,225,230,210,232,245,208,225,216,211,239,216,219,226,215,191,234,216,196,227,213,220,227,217,221,224,226,219,214,231,217,220,238,221,200,221,234,223,233,229,209,231,221,225,206,205,203,227,219,220,233,217,214,247,213,226,232,225,226,224,240,223,240,227,223,228,232,234,222,216,231,234,228,211,230,195,208,241,175,238,221,227,241,238,232,223,241,209,230,229,205,239,237,233,225,235,209,220,242,229,212,226,226,240,255,222,219,235,230,250,237,247,241,227,240,246,239,233,222,225,241,244,237,245,247,228,223,237,252,239,226,234,251,242,247,241,224,253,239,245,227,253,226,251,247,252,251,239,251,228,245,223,255,247,239,244,252,233,230,235,239,226,244,222,242,225,238,247,226,229,231,254,251,255,232,230,229,249,246,247,244,250,252,236,245,220,251,223,244,235,230,237,244,247,237,255,252,232,233,243,236,242,255,238,233,239,234,237,251,254,233,248,238,244,242,237,245,232,216,254,241,247,224,243,219,253,254,234,229,253,253,244,234,228,242,246,232,255,252,227,247,236,229,234,231,248,243,249,253,245,240,239,250,226,240,249,246,227,238,247,239,246,234,243,245,237,253,246,250,248,242,238,243,237,229,254,253,244,254,230,233,242,225,238,240,240,250,234,200,227,209,222,249,200,235,246,229,209,195,241,245,177,142,131,155,69,70,109,54,128,209,240,208,252,250,244,253,224,221,185,43,142,181,12,47,195,248,255,232,194,205,203,251,233,191,215,231,243,237,240,224,232,247,238,237,212,200,206,242,244,135,147,70,0,81,79,73,33,39,19,47,213,253,187,147,243,253,226,244,214,200,203,244,249,251,255,241,254,249,242,236,241,219,238,236,229,236,213,174,228,133,52,117,176,186,188,215,234,204,169,241,234,229,249,246,249,241,249,249,244,239,190,129,77,54,12,12,6,49,13,25,45,67,71,39,58,78,71,47,11,64,111,73,100,61,120,110,58,64,14,19,179,236,251,242,226,245,249,234,246,242,244,227,232,237,253,228,250,243,223,231,237,222,228,208,204,239,237,150,200,216,237,221,232,86,92,168,180,251,249,161,200,221,155,157,184,244,237,252,237,240,212,230,241,119,131,72,60,26,25,8,2,139,245,250,251,252,228,197,219,252,235,228,159,135,229,208,244,216,200,231,231,215,230,205,219,194,239,203,233,216,211,233,208,223,199,194,211,214,220,226,209,204,208,196,225,237,221,210,195,200,215,236,184,197,198,199,199,215,225,209,203,214,206,193,215,198,196,219,217,213,194,189,195,198,175,217,221,221,219,234,172,130,98,76,67,66,59,31,28,42,52,68,98,57,73,25,37,20,27,41,77,19,38,163,217,229,218,219,203,210,213,216,202,227,227,216,231,217,208,224,209,205,222,219,208,221,211,222,197,231,223,210,232,217,215,209,220,220,206,206,233,241,207,218,213,201,194,216,217,237,88,12,12,16,0,16,13,15,11,2,26,9,19,14,14,9,22,4,6,9,32,33,20,7,0,223,210,204,209,211,222,221,207,232,217,226,212,220,233,223,242,222,227,227,224,206,216,232,206,219,214,220,233,213,222,241,202,184,189,231,196,235,231,214,211,213,210,209,238,219,220,226,196,240,214,213,209,208,219,229,208,208,225,205,215,224,213,207,209,235,207,222,213,202,232,198,204,238,231,213,242,192,225,226,228,238,216,222,222,243,224,244,235,214,194,227,219,223,234,212,220,223,218,231,206,205,225,221,235,210,224,236,229,219,209,232,213,220,244,237,246,202,217,202,230,226,220,216,234,226,225,244,238,237,235,220,222,226,234,231,239,245,224,218,240,214,225,227,228,237,216,249,234,250,229,223,230,227,242,247,250,239,220,238,224,209,243,238,220,244,233,240,227,224,251,224,243,252,243,223,218,224,242,249,248,235,252,238,247,229,228,251,225,235,235,220,224,222,241,248,246,251,243,243,250,252,230,250,250,223,251,243,242,244,255,254,222,243,233,251,251,245,255,252,241,253,248,225,246,252,250,245,224,224,224,248,238,238,242,232,243,250,253,226,247,247,235,248,210,205,239,219,237,241,253,255,255,242,246,247,243,240,254,235,244,232,243,243,238,255,246,255,236,217,238,247,240,238,227,232,241,235,235,235,230,244,227,246,235,251,241,235,239,249,246,228,223,235,245,233,254,247,230,233,246,252,248,238,246,252,254,246,237,241,234,253,234,252,239,230,246,216,217,233,253,255,246,214,243,230,238,235,255,255,213,241,236,197,221,243,243,236,194,207,224,225,214,205,254,237,162,153,125,148,39,148,224,230,228,224,234,241,247,236,245,242,231,212,163,71,191,175,57,117,225,254,248,231,217,209,190,245,197,203,184,224,239,246,252,243,247,245,240,249,202,202,191,228,224,142,135,56,0,88,85,54,55,41,40,59,221,247,124,151,247,220,218,214,238,206,219,239,236,242,240,227,235,228,213,240,245,254,249,243,253,242,246,247,246,180,67,75,67,212,235,234,244,142,165,245,228,224,238,240,244,246,245,243,231,220,222,236,209,140,140,109,46,44,7,24,59,58,46,64,117,79,47,18,26,42,109,73,74,30,92,98,76,76,38,55,161,225,245,250,255,235,238,250,243,253,229,225,243,221,232,242,243,244,239,223,235,255,244,240,206,253,247,182,160,178,247,230,214,150,152,207,215,247,236,199,223,220,191,176,218,213,235,243,213,230,236,252,193,97,114,85,84,31,40,14,32,177,232,253,245,236,208,205,234,246,196,176,127,157,193,242,227,203,194,213,221,232,210,231,220,228,191,220,232,220,209,217,193,193,226,209,194,210,210,195,211,183,233,223,220,224,219,240,238,204,188,216,200,216,228,212,199,182,193,190,211,203,216,219,187,235,214,219,218,203,213,204,208,192,212,217,186,207,215,200,127,65,53,34,63,54,19,54,24,36,40,59,78,54,57,44,59,49,48,63,55,35,78,204,216,241,232,209,203,223,214,213,221,210,210,205,238,217,201,237,197,209,194,214,205,209,222,207,231,234,217,202,227,218,200,210,232,200,192,209,215,193,233,231,194,208,211,206,194,221,116,0,14,6,8,16,3,12,0,4,8,16,25,2,6,10,26,3,7,13,18,3,3,0,13,213,239,203,207,207,206,191,223,214,221,175,200,226,222,247,214,178,230,222,218,232,229,206,213,211,241,230,217,223,228,207,224,196,222,225,238,214,212,215,232,189,233,194,220,224,201,206,212,222,217,208,225,223,237,230,209,211,232,235,228,207,243,243,228,237,224,214,219,223,195,237,221,234,202,204,232,188,215,231,213,200,224,246,222,234,217,226,224,230,232,209,216,224,215,215,227,214,247,207,222,208,219,225,228,215,241,220,224,238,220,229,214,203,229,215,223,236,203,235,241,246,233,196,214,202,207,236,233,241,217,226,193,241,198,237,221,239,240,214,225,237,223,228,242,228,220,237,219,226,215,228,245,227,229,234,234,225,245,247,229,216,216,249,241,253,239,241,248,229,245,237,238,248,236,229,240,247,230,226,241,218,227,233,235,253,247,229,232,247,254,253,249,239,246,241,239,254,253,250,226,239,255,247,238,226,248,246,233,245,242,242,252,232,232,253,224,244,254,216,253,234,225,223,235,248,250,244,235,233,241,253,251,243,249,245,243,244,226,243,224,227,247,241,233,247,239,252,239,251,236,239,235,249,240,216,243,253,232,233,247,239,255,241,220,252,241,252,250,237,242,249,242,248,255,245,253,237,239,231,243,250,254,241,244,240,237,234,244,234,235,238,234,250,246,253,247,241,218,239,240,235,241,227,246,232,224,230,236,236,247,253,242,250,225,248,255,222,243,245,241,246,247,234,229,236,249,247,244,252,227,253,243,217,241,215,179,204,191,225,244,233,208,216,247,225,189,145,148,115,50,136,237,254,247,205,199,216,236,219,244,230,245,244,213,85,134,210,160,218,250,221,252,169,220,187,189,207,216,219,207,245,253,236,240,248,251,237,227,251,208,176,189,248,248,120,145,28,9,90,86,60,54,47,39,23,245,250,116,176,250,236,212,200,203,177,195,228,248,231,242,228,249,240,221,218,249,238,233,231,231,255,249,246,228,171,144,83,68,221,225,253,231,126,175,251,201,205,237,242,209,251,251,234,255,212,225,254,255,246,244,240,210,85,6,44,164,82,38,37,67,102,62,71,49,56,89,82,57,63,100,99,31,49,22,47,176,245,255,241,252,239,244,236,234,229,243,226,216,247,251,235,249,247,252,227,245,252,228,216,218,244,245,210,174,213,243,224,229,156,145,237,248,217,253,212,226,194,201,218,222,211,231,234,224,241,234,254,231,114,111,89,78,28,28,3,79,243,245,254,248,218,187,217,238,245,152,74,79,180,222,218,241,186,203,221,189,209,231,215,193,206,208,232,213,211,217,196,203,191,223,233,215,224,218,220,219,215,192,212,213,186,216,198,202,206,217,218,213,214,207,209,191,226,184,201,204,199,216,206,216,209,212,172,194,217,191,203,232,179,220,210,210,211,219,180,147,109,87,66,53,81,51,67,58,46,62,52,45,40,48,41,30,31,52,72,51,22,111,211,222,215,211,229,228,237,226,212,205,220,220,217,219,196,226,234,191,227,219,206,207,205,212,209,191,243,223,211,197,226,220,199,222,184,214,223,206,217,202,218,208,207,225,200,240,206,87,1,0,23,10,2,0,5,13,15,40,6,24,14,7,14,16,10,8,2,11,7,7,3,7,242,212,235,212,229,203,210,236,214,222,227,196,219,169,222,212,216,234,217,234,236,221,219,228,215,227,217,223,235,229,226,224,211,229,229,236,215,225,210,208,210,213,233,226,225,234,193,225,219,212,219,234,200,222,222,210,232,199,213,212,214,205,234,226,210,223,235,238,223,238,238,224,214,230,227,228,251,216,206,215,210,227,208,231,191,211,236,220,212,217,211,242,222,219,209,214,222,253,239,225,231,209,218,244,223,224,223,241,248,219,224,227,224,226,219,229,220,239,236,235,228,204,227,235,225,242,229,200,247,217,227,219,225,235,217,245,237,224,239,225,209,228,239,219,241,218,224,235,213,239,218,241,228,225,225,223,233,244,244,230,240,240,235,229,245,236,243,247,210,243,229,230,231,246,247,235,232,246,235,227,236,247,240,229,227,236,240,244,247,249,252,239,238,197,244,230,247,255,254,236,242,253,255,225,252,248,231,254,240,242,233,252,232,220,226,229,224,238,253,252,241,243,236,226,254,236,242,238,240,216,245,252,230,244,240,232,244,252,248,246,242,238,240,245,232,240,240,244,234,254,245,248,252,247,254,228,239,220,230,249,255,238,244,242,242,237,246,236,253,232,237,235,228,242,233,248,236,237,255,249,252,248,225,247,251,252,242,247,215,231,245,231,239,253,216,233,246,237,252,223,241,251,244,235,226,250,240,255,242,225,240,239,234,249,239,253,244,246,246,250,234,236,234,247,248,255,234,218,233,225,248,232,177,203,206,239,242,231,247,254,227,210,220,253,247,163,160,145,116,55,108,221,246,250,206,173,242,248,219,219,222,238,216,195,145,184,183,215,251,254,251,254,210,217,213,206,211,234,248,240,232,252,252,253,242,237,221,216,239,197,186,190,236,202,126,151,57,9,56,82,84,38,44,36,47,230,251,117,178,226,252,227,204,213,211,205,246,244,231,251,238,236,251,248,240,232,218,235,228,229,243,235,248,213,140,153,82,50,213,237,213,185,64,221,230,211,251,235,254,253,246,244,234,236,218,232,251,253,255,245,244,213,131,32,85,175,68,38,33,72,97,51,25,37,63,93,66,68,44,113,130,50,65,35,66,213,236,255,236,246,246,245,236,227,239,224,224,235,239,230,247,250,244,209,203,241,249,248,217,222,234,239,211,153,193,243,252,203,184,171,174,240,209,222,195,165,164,201,245,200,204,231,230,233,245,237,252,205,114,110,85,83,50,19,20,152,229,246,244,243,201,209,228,246,207,133,44,60,216,232,237,214,193,229,226,204,226,210,217,198,199,230,216,187,212,210,224,206,226,191,203,201,221,193,203,233,196,203,232,209,199,196,207,190,243,197,228,210,209,219,214,224,246,228,195,220,190,222,179,212,207,214,199,192,203,209,199,201,198,231,207,234,197,225,200,171,167,183,119,125,69,63,99,48,101,110,77,64,83,65,46,34,61,60,50,32,140,218,242,206,217,230,213,242,212,236,218,222,232,215,220,238,233,228,226,216,212,222,223,220,213,219,211,206,212,218,189,210,189,242,225,201,211,202,200,194,208,201,198,218,218,210,216,190,232,105,7,0,6,18,18,0,14,16,16,14,26,2,36,9,1,36,16,4,12,2,6,8,10,17,201,188,183,205,216,215,227,244,226,218,229,233,222,213,240,222,210,215,208,221,217,211,230,244,213,246,232,234,225,217,206,226,222,227,226,230,190,213,220,201,220,204,243,231,197,208,203,217,213,223,195,229,238,236,205,221,238,210,229,227,237,217,232,232,237,222,214,227,228,237,218,233,226,226,193,238,226,250,244,208,232,241,208,233,245,218,229,223,210,223,219,238,234,240,220,238,214,223,213,214,213,236,204,234,212,231,225,230,246,236,241,240,215,237,219,238,241,233,221,231,214,214,231,217,206,234,239,221,215,217,211,239,243,237,235,241,202,218,222,219,236,228,237,236,226,221,238,228,241,239,241,248,249,217,220,226,214,236,210,241,249,237,239,230,223,225,250,237,242,229,222,235,252,251,232,244,219,247,239,242,237,224,209,247,242,239,239,254,247,252,254,249,249,247,246,246,239,255,252,245,238,243,241,255,240,240,237,235,251,237,238,240,245,243,249,243,252,246,237,251,241,254,255,235,218,246,241,249,252,229,223,239,243,223,228,232,220,254,247,241,252,244,249,230,244,231,238,234,238,220,229,236,231,231,226,236,236,236,243,247,252,242,245,238,255,255,255,243,248,238,237,251,246,249,206,249,245,243,239,253,241,212,224,252,253,235,233,240,251,226,248,255,234,249,236,243,229,254,245,245,232,237,237,235,239,233,245,228,243,244,243,238,216,224,213,238,249,228,247,218,231,246,246,253,249,235,240,250,239,209,229,176,183,233,243,220,254,209,220,241,210,200,210,254,241,187,155,137,137,67,108,238,252,250,255,199,169,209,246,245,248,222,233,216,167,199,176,215,251,247,231,224,205,217,223,190,249,173,232,239,203,252,222,238,233,249,235,229,206,200,194,186,242,171,122,147,56,9,59,76,78,31,69,36,38,238,178,93,151,197,249,227,221,231,236,211,224,254,242,250,241,247,213,230,223,244,242,241,247,248,227,242,236,177,165,196,109,32,146,209,215,133,142,243,207,190,230,237,247,250,234,230,241,215,196,253,230,254,230,245,252,164,133,41,81,174,81,30,35,76,80,23,45,32,72,92,80,60,31,84,127,65,38,18,29,212,237,248,253,250,252,252,230,250,246,222,231,229,253,251,239,247,218,230,236,233,226,253,238,207,242,236,226,180,190,219,225,226,204,173,140,228,226,236,210,178,131,185,217,230,221,214,236,220,244,235,241,206,107,122,95,34,19,15,76,233,250,243,242,228,214,209,251,242,173,93,31,71,211,208,218,234,193,204,214,216,212,214,199,241,231,189,204,211,226,199,225,223,179,211,210,228,205,199,239,203,222,237,205,204,205,212,208,214,224,218,183,214,208,218,198,223,209,182,189,190,207,198,198,231,220,184,206,202,208,218,204,209,214,186,203,229,208,202,185,211,222,195,201,146,109,58,47,31,94,141,121,94,81,41,44,36,31,24,38,150,240,210,243,232,216,233,225,212,209,214,199,213,209,220,219,225,200,225,196,208,220,220,203,180,219,213,223,217,192,217,246,218,205,209,216,236,214,224,194,227,229,231,215,200,200,215,206,205,211,103,7,7,9,23,21,6,13,9,19,18,8,23,11,0,0,8,15,5,1,15,6,10,31,20,226,231,205,221,210,238,217,202,224,227,233,216,216,216,209,209,213,211,226,229,236,212,232,196,218,212,236,221,208,229,217,224,218,246,232,227,230,218,228,233,207,240,224,217,199,219,231,230,227,224,211,226,215,226,213,221,218,219,206,188,226,236,237,223,217,235,221,238,219,231,240,236,227,236,217,233,217,202,225,233,217,238,235,224,210,231,222,206,223,208,207,239,234,215,226,231,229,233,227,235,215,232,238,233,226,219,233,211,218,219,229,214,210,227,208,230,212,235,226,225,228,202,214,234,241,229,217,252,225,227,232,220,226,224,248,228,233,238,236,217,230,237,230,219,245,231,233,226,223,232,250,220,206,220,240,248,228,240,224,237,245,254,237,247,233,231,244,239,234,242,244,250,243,251,235,217,239,253,235,229,229,243,222,228,255,212,229,226,218,240,223,239,251,230,219,253,232,249,244,238,253,250,250,234,248,242,246,226,236,233,236,250,248,241,237,239,243,236,251,242,230,255,247,239,248,221,233,222,228,230,242,233,229,234,241,250,237,255,235,237,255,255,236,245,242,241,232,244,253,252,245,229,249,242,232,246,248,236,233,239,249,227,255,217,251,246,255,231,235,246,232,249,236,245,245,238,247,243,254,244,223,233,240,254,224,246,237,248,246,250,252,233,239,228,253,230,232,241,229,235,244,232,253,232,253,247,243,244,248,232,232,252,223,247,242,249,245,233,252,222,240,241,233,227,255,243,247,249,214,205,215,198,234,247,239,229,219,213,216,229,221,193,237,246,250,165,128,150,121,45,127,241,246,252,249,206,188,198,225,224,254,237,213,171,198,210,235,242,248,232,247,237,153,204,203,201,166,99,159,197,223,224,237,249,248,249,234,227,232,216,176,192,255,147,138,157,34,33,55,48,56,40,30,71,30,47,97,140,198,192,205,193,187,213,223,184,229,248,228,253,247,237,228,215,237,241,246,240,250,229,246,233,221,169,146,214,144,50,103,182,240,171,223,206,206,239,222,250,241,246,236,228,235,233,225,241,248,245,252,238,237,162,115,42,106,166,27,30,20,62,65,27,35,21,59,80,81,111,40,98,119,70,61,27,26,120,241,245,238,221,248,242,246,249,241,255,239,206,251,233,248,241,246,234,228,239,238,250,250,238,231,252,209,175,185,211,238,245,218,149,158,205,225,188,202,215,85,150,226,190,179,163,220,221,228,230,250,185,106,100,68,45,44,111,185,235,244,226,246,211,240,215,251,213,145,80,9,106,224,205,214,219,189,223,214,212,209,208,210,205,203,227,223,212,210,230,205,240,218,217,181,224,228,211,202,233,240,182,218,208,188,202,213,211,203,200,228,218,202,209,193,202,222,178,217,204,201,207,192,196,220,211,211,201,203,188,191,176,198,215,219,205,212,210,166,191,209,220,210,136,109,56,31,19,16,67,78,41,64,55,27,45,10,18,113,229,245,228,223,228,213,205,199,187,243,216,212,210,225,207,206,238,225,226,200,208,226,210,235,217,217,232,218,245,222,211,195,208,165,213,198,205,221,199,219,226,220,209,194,207,207,234,228,229,204,105,12,14,18,18,2,16,12,6,4,0,33,3,19,12,10,22,11,13,14,22,1,1,8,1,213,229,237,228,241,234,226,226,211,245,230,223,218,218,217,224,206,242,205,215,243,212,219,231,249,217,224,217,222,214,204,184,227,200,232,220,216,207,212,242,242,227,220,233,222,205,218,242,214,192,223,229,207,217,205,211,210,227,227,241,201,216,225,223,222,221,203,220,232,237,223,243,215,229,234,249,219,235,228,231,238,252,239,225,244,223,222,213,244,240,218,252,237,203,215,210,233,231,242,232,234,233,241,230,208,235,239,222,243,210,246,235,229,230,229,199,233,237,221,226,220,212,237,230,224,232,230,213,227,246,242,229,235,237,231,231,230,229,237,229,209,228,241,221,234,221,239,229,220,218,253,218,219,236,243,233,241,224,237,252,239,234,222,255,228,235,235,246,228,241,233,247,223,246,232,221,249,243,220,242,218,213,243,251,250,247,251,231,239,247,246,252,249,234,255,244,249,237,237,232,237,244,228,219,252,241,223,230,230,248,235,230,249,248,239,253,238,247,236,255,234,227,236,251,248,236,253,241,245,235,238,247,252,249,243,233,237,249,254,226,253,245,249,211,242,242,231,251,229,247,241,251,253,239,249,252,254,227,249,250,246,245,242,250,235,254,235,246,253,235,234,216,242,236,250,244,239,234,252,244,246,250,236,227,248,242,222,253,229,240,222,251,238,243,254,251,239,236,251,228,225,253,224,246,246,253,252,227,230,224,238,243,221,238,227,242,227,255,253,255,252,229,225,239,252,242,237,246,250,215,213,204,236,216,234,223,219,211,238,247,211,199,210,242,244,153,137,127,127,36,109,241,248,240,252,228,229,187,175,249,229,249,230,176,217,187,224,232,247,243,234,159,101,236,210,151,127,14,83,181,238,226,234,235,227,254,245,244,230,203,156,199,252,180,131,128,67,50,66,44,71,51,76,61,84,25,107,191,211,236,237,192,182,234,237,213,237,252,244,253,229,236,250,219,240,233,251,241,253,233,252,200,200,117,149,219,118,87,230,245,228,167,225,255,183,230,236,253,238,226,255,255,255,229,209,249,240,247,248,246,240,158,104,23,64,168,26,46,39,68,51,35,38,12,70,72,64,88,46,102,109,75,53,47,12,62,214,249,251,248,249,237,252,255,242,244,224,223,240,253,223,245,233,250,243,220,238,253,249,231,224,242,223,197,174,228,235,231,194,171,121,156,181,164,187,232,157,162,216,241,156,138,213,221,254,247,251,159,94,67,77,23,79,218,226,252,251,212,210,227,226,253,245,168,139,98,9,154,237,211,243,204,205,214,216,207,216,218,205,223,198,201,227,208,207,224,185,219,219,189,201,227,195,213,213,220,232,209,228,220,224,223,222,208,202,211,204,197,194,228,210,218,185,227,204,196,203,207,224,182,196,210,203,208,209,211,193,217,195,214,225,206,212,182,171,216,206,213,220,185,156,146,133,79,59,50,48,26,39,12,31,88,152,215,235,223,229,231,221,215,236,186,219,204,199,199,221,208,209,227,195,225,205,229,222,238,223,203,233,219,201,223,213,231,228,184,210,200,232,208,210,211,196,207,239,224,217,201,190,216,209,220,220,210,201,106,0,17,6,7,7,15,3,1,29,0,23,19,10,0,19,2,24,15,11,4,0,11,9,7,210,231,216,236,242,225,222,189,219,221,226,236,212,212,203,215,199,230,238,223,219,237,209,211,227,242,211,215,223,220,206,237,233,211,208,233,239,220,232,206,221,212,226,224,198,213,227,234,199,217,223,207,217,219,207,197,228,190,194,227,230,209,229,203,219,221,236,241,243,224,244,240,229,219,219,224,223,233,246,233,244,220,205,224,246,233,221,233,216,247,233,231,235,233,214,231,226,241,216,231,218,217,236,215,225,232,234,237,250,234,201,233,220,237,232,222,218,221,247,240,222,216,228,241,242,220,206,231,225,242,222,217,221,240,221,217,225,234,237,238,242,243,252,214,237,221,231,209,237,226,233,238,201,243,240,227,230,237,226,237,237,208,235,215,239,222,230,219,237,228,242,252,224,239,222,238,234,244,235,207,247,214,244,247,232,226,255,253,218,245,248,248,246,235,246,241,223,236,246,230,228,244,255,255,255,245,252,233,244,251,235,240,231,245,243,243,249,231,252,244,246,247,236,254,241,241,235,232,225,241,238,245,239,247,234,216,211,251,244,255,251,249,226,246,245,255,255,235,255,243,245,241,243,255,245,252,253,247,250,221,253,225,234,236,233,236,253,246,233,246,231,241,254,242,242,243,248,236,255,245,224,232,237,245,241,245,249,221,249,241,235,233,250,244,234,255,211,248,229,243,233,248,247,253,231,231,246,226,242,234,227,231,241,224,249,252,224,244,239,244,242,255,247,240,250,245,228,226,218,230,234,183,220,193,208,227,235,248,251,207,224,204,222,230,246,170,148,133,137,41,103,237,255,247,226,234,243,201,179,201,232,243,208,196,249,186,215,216,224,230,182,120,55,141,167,94,51,5,112,187,252,208,234,236,252,243,249,239,245,242,138,208,255,211,193,139,85,78,74,74,57,33,31,75,34,54,209,251,226,253,230,218,205,228,247,239,252,254,243,249,253,245,240,253,217,238,244,230,234,239,228,205,139,62,146,105,112,173,242,253,195,186,243,206,203,217,241,236,226,246,249,244,250,209,236,252,241,252,245,241,222,172,96,31,119,181,18,48,26,86,51,17,61,15,66,97,80,89,64,87,105,66,23,60,25,105,212,234,252,246,245,229,245,252,244,247,246,225,223,232,240,237,239,236,250,237,214,235,251,241,196,247,247,220,177,208,243,240,238,162,105,87,135,185,241,218,187,186,227,207,190,165,211,226,234,251,216,127,83,75,26,86,193,202,232,251,241,250,242,236,246,229,209,127,157,87,54,169,222,227,233,205,211,236,230,218,211,201,215,214,215,181,230,249,221,204,205,198,217,212,214,208,184,223,218,219,211,199,211,212,207,202,224,219,233,206,218,193,230,214,217,213,222,215,214,202,220,228,216,220,211,217,222,208,202,195,220,209,213,215,211,234,210,205,204,199,221,217,239,249,249,236,227,227,195,137,90,29,90,213,239,234,239,235,248,239,225,237,217,212,200,197,229,202,205,216,221,223,222,208,203,213,225,207,232,214,222,205,224,220,235,208,211,225,232,194,220,212,204,221,212,204,221,206,217,232,207,205,227,184,215,226,228,222,206,118,2,0,0,2,4,17,9,16,22,12,41,28,2,6,1,18,5,4,0,25,4,19,2,17,237,192,203,223,239,231,228,219,217,218,220,211,206,239,215,198,229,217,206,195,212,233,236,225,243,212,224,214,231,217,206,226,240,225,222,220,241,243,232,214,236,214,237,204,222,234,214,215,246,235,236,216,216,236,207,244,222,219,233,232,203,237,224,245,239,213,225,225,228,233,237,216,227,227,211,237,239,238,229,239,244,241,238,241,243,214,229,212,224,229,230,231,235,221,239,186,230,235,227,199,247,211,234,238,227,228,217,227,237,226,236,235,215,204,225,241,232,231,220,246,210,235,231,223,206,243,244,248,231,237,245,229,247,247,238,214,204,237,213,240,240,239,242,232,235,232,234,224,229,236,252,233,218,233,231,223,232,237,204,228,254,240,249,243,245,224,225,248,244,227,228,254,248,232,230,231,228,228,240,244,240,221,216,239,245,238,250,231,232,246,230,245,222,245,228,236,241,204,233,251,223,255,254,235,250,255,255,246,242,243,247,240,243,253,243,240,237,226,249,246,255,230,219,241,241,249,254,244,255,245,233,255,234,213,250,253,255,234,254,250,247,243,244,244,254,241,229,246,242,244,247,244,248,247,237,255,237,234,232,241,248,222,227,236,221,237,242,224,235,250,244,247,233,249,250,237,255,242,235,251,242,248,237,247,217,228,243,244,248,250,237,252,249,245,237,241,225,245,254,255,230,254,241,247,245,249,246,240,213,229,225,247,230,226,243,218,247,249,229,239,254,236,235,252,230,250,239,252,191,240,193,178,222,222,245,246,248,204,217,236,202,233,214,222,245,185,175,147,144,24,88,247,253,241,243,232,235,235,187,235,228,250,217,176,217,157,189,205,221,224,132,13,16,127,122,74,49,83,227,249,250,242,239,247,250,239,251,255,250,229,227,238,247,243,182,138,63,35,73,76,68,45,29,64,41,92,218,248,251,255,236,198,255,251,240,239,241,247,243,254,254,251,231,234,232,250,234,247,236,241,252,220,136,65,85,30,59,168,239,238,105,194,246,224,201,239,246,244,253,239,250,249,247,224,228,248,235,255,255,238,230,159,89,9,81,136,19,16,97,102,46,29,21,30,38,83,106,52,53,81,117,117,63,50,7,102,248,234,245,255,230,230,237,242,240,241,249,222,211,225,250,255,238,230,237,235,223,235,249,243,210,238,252,233,157,162,231,240,222,205,138,140,178,212,227,232,171,138,188,215,216,207,181,219,240,234,147,121,143,55,107,199,251,227,250,253,224,238,239,237,252,255,153,89,112,103,116,191,201,228,230,204,201,207,202,209,220,222,228,230,203,230,208,227,224,243,201,207,206,207,201,206,210,210,209,196,222,237,216,201,210,193,218,209,200,210,223,236,215,214,196,180,223,208,205,224,207,198,204,195,199,192,207,203,211,195,198,199,191,196,205,211,187,168,204,207,226,184,231,224,251,254,248,242,238,173,111,92,193,240,245,227,253,239,224,231,212,217,200,203,191,203,218,228,203,203,224,241,234,223,211,217,231,216,221,217,242,201,228,226,206,206,233,225,217,216,240,213,228,210,242,217,218,184,228,202,209,201,220,205,228,215,211,233,212,107,7,4,11,21,2,14,14,0,23,7,3,22,5,2,0,17,15,14,11,33,28,4,9,19,220,233,212,223,227,206,219,218,203,222,240,229,204,185,226,220,226,223,222,232,224,216,236,195,209,206,241,237,236,241,207,195,195,237,222,202,206,225,205,225,238,225,216,211,243,242,243,236,242,233,193,235,226,231,214,236,222,237,213,236,230,241,223,231,211,234,225,234,224,216,225,236,235,243,241,241,217,239,232,217,221,249,234,228,237,228,216,214,246,235,222,217,207,225,225,252,236,241,233,220,241,243,222,244,238,233,209,231,238,233,233,219,235,214,235,210,240,229,232,250,243,228,224,236,218,239,194,226,227,227,208,218,210,243,228,230,252,227,231,239,219,250,234,231,228,239,234,238,228,219,212,251,237,209,228,218,228,236,241,243,253,232,235,252,220,238,225,243,235,235,233,241,246,249,229,246,198,242,232,239,242,249,254,248,234,239,235,233,237,233,247,253,247,246,233,247,254,233,250,241,255,224,239,243,236,247,242,242,250,255,248,241,234,224,232,229,246,238,251,241,249,232,246,236,233,240,254,250,247,253,255,253,244,240,238,235,252,224,247,243,233,239,244,255,221,238,246,242,252,247,237,250,227,246,251,245,252,242,251,243,230,242,240,252,225,237,228,253,246,224,230,245,254,251,223,249,240,231,228,233,242,241,253,246,224,237,240,242,254,229,246,231,237,255,230,210,235,227,222,233,249,246,243,229,237,240,243,240,255,235,253,239,245,232,254,227,239,239,231,216,234,255,227,229,223,237,229,246,214,252,228,230,240,249,241,237,194,212,244,242,217,220,237,244,219,182,173,162,118,52,116,239,227,232,252,226,252,242,199,213,206,243,190,113,195,90,113,208,207,197,75,19,124,224,217,203,183,252,251,254,246,245,255,253,255,249,240,218,179,180,132,121,195,130,136,73,14,77,38,35,32,37,38,54,48,48,173,158,144,200,197,172,221,232,243,228,252,245,249,232,245,240,253,255,253,232,246,244,244,244,225,237,155,97,55,8,62,186,246,171,61,176,235,212,212,242,251,247,248,253,248,255,247,173,247,245,244,249,232,236,236,171,67,16,21,57,41,28,57,121,39,28,12,25,62,65,74,46,49,90,110,75,35,66,27,103,232,233,245,239,230,226,231,255,243,236,210,239,218,237,252,229,250,222,254,231,227,201,242,233,222,214,240,217,172,167,201,231,238,205,206,172,186,238,220,205,177,171,151,204,212,232,174,197,236,177,156,121,103,86,173,243,237,255,253,217,232,241,225,226,255,206,112,80,97,91,104,204,204,241,212,202,203,216,206,238,204,225,215,226,215,207,203,214,213,214,213,198,218,198,240,192,237,208,227,211,232,215,205,218,220,198,201,191,205,203,204,205,211,193,193,209,226,219,218,209,186,229,229,219,213,221,220,222,207,211,218,193,192,217,200,220,176,184,215,212,234,218,215,217,225,217,240,240,185,159,114,65,199,218,230,249,225,230,224,205,232,220,216,227,235,208,238,192,218,234,214,206,221,207,203,212,209,208,214,223,223,207,207,232,237,205,221,224,228,227,227,207,224,201,215,205,213,198,194,225,218,230,207,223,199,196,212,194,194,105,13,19,6,0,22,23,16,7,6,28,9,14,7,0,2,12,10,1,9,26,6,19,8,4,224,211,232,243,232,216,225,236,210,220,226,189,220,224,204,196,201,230,215,210,226,204,235,228,215,197,202,210,228,218,235,221,228,237,228,238,236,211,249,212,231,240,217,238,215,224,219,212,244,230,235,241,226,237,224,203,223,214,222,226,236,215,225,243,238,234,220,225,227,224,227,222,234,244,245,224,241,240,248,243,227,254,248,246,233,215,236,229,231,224,247,230,247,242,255,246,219,231,241,239,244,217,233,224,225,247,237,251,227,205,233,215,242,241,227,223,224,238,233,253,226,246,246,234,251,231,233,215,251,229,219,217,243,230,231,229,214,207,239,209,228,207,236,246,230,229,242,218,228,245,247,230,228,233,219,239,210,241,237,236,227,242,229,214,222,246,226,228,233,240,222,235,226,249,226,241,240,225,250,246,212,225,234,244,247,250,249,234,243,255,238,237,222,241,253,229,253,237,216,236,248,247,252,247,253,239,227,243,240,221,238,213,217,246,247,251,234,255,231,243,235,230,252,237,234,237,241,222,237,242,243,224,233,236,240,242,237,226,223,255,254,220,242,249,236,235,241,230,252,248,232,252,229,255,246,248,240,239,250,239,244,232,245,253,250,252,245,244,224,230,231,242,246,235,233,237,245,254,228,227,234,252,248,247,231,253,226,239,218,249,246,228,230,250,241,253,231,240,238,251,255,217,249,235,232,234,235,249,246,215,248,233,240,242,226,226,242,255,233,246,241,255,234,222,249,248,255,242,223,249,228,223,236,226,184,224,212,244,226,236,207,206,245,246,221,132,154,159,166,98,142,234,242,247,227,227,248,226,216,239,175,226,145,62,141,24,95,202,189,248,204,226,252,240,255,255,251,229,218,221,222,160,179,113,121,113,96,84,61,53,22,15,21,67,43,20,16,22,42,56,71,59,39,51,34,27,57,24,11,3,20,12,15,25,27,38,80,91,143,134,188,227,233,249,245,242,246,245,235,245,253,238,222,141,93,19,51,217,227,160,131,236,237,215,251,255,255,247,222,233,232,240,219,190,255,217,243,236,233,248,239,195,140,7,2,16,37,78,113,64,34,39,21,43,57,73,76,53,47,85,114,77,47,70,5,60,226,244,241,228,234,242,233,255,249,243,236,210,195,225,229,233,252,227,243,233,215,227,232,239,231,211,248,236,202,144,193,236,215,219,211,168,165,207,222,160,166,202,151,156,217,221,223,219,240,186,72,90,71,123,228,250,255,246,236,252,226,246,255,249,235,194,61,90,97,76,145,223,211,238,223,216,201,228,218,219,226,202,229,216,233,220,226,210,206,223,239,230,224,240,191,203,208,224,194,220,200,229,216,212,214,200,208,224,217,214,203,202,207,208,206,222,212,192,195,204,217,203,214,204,211,209,207,218,200,217,204,198,184,207,217,198,188,210,211,223,242,216,198,200,230,245,227,228,200,158,86,57,200,219,200,207,202,218,245,208,217,202,213,232,205,221,226,222,234,223,219,209,228,234,216,217,214,212,236,231,222,207,204,197,222,208,205,212,210,240,205,222,217,211,211,211,209,220,222,217,228,227,203,231,189,224,181,208,201,101,0,11,1,0,19,9,33,11,2,28,13,0,0,0,35,2,27,8,0,7,29,12,2,19,202,204,222,217,222,243,209,219,236,204,216,223,217,219,220,214,230,215,228,216,212,217,227,234,220,211,192,230,230,230,220,242,243,219,244,215,237,231,229,227,220,214,246,232,223,221,233,231,236,249,244,227,234,251,229,241,211,224,226,223,235,223,225,212,236,247,227,234,211,246,241,237,220,233,233,247,226,232,230,241,255,244,238,247,241,242,225,235,236,225,223,203,244,221,219,246,227,203,247,243,228,246,211,205,237,236,242,227,233,221,246,225,217,239,226,226,251,232,227,244,239,237,226,231,232,236,225,225,231,214,237,205,255,237,243,223,212,232,233,252,213,249,229,228,231,247,223,198,252,222,231,240,223,234,234,217,224,235,238,242,236,224,241,238,249,222,241,241,234,248,251,220,222,240,245,245,235,218,234,236,220,246,252,245,248,240,235,239,238,246,237,248,234,250,220,231,229,254,236,242,218,237,223,243,227,253,252,233,232,252,224,248,251,252,223,255,239,244,240,249,239,239,236,231,227,240,249,231,233,228,253,234,240,248,239,238,227,241,238,249,239,255,254,252,246,226,235,249,240,251,240,236,222,229,228,243,235,239,225,243,215,243,240,247,252,244,231,255,234,223,246,240,246,255,249,239,238,250,249,208,245,232,243,225,249,245,254,242,246,250,234,246,244,253,224,242,246,225,242,247,253,243,237,251,229,246,232,248,242,240,236,236,229,246,248,219,222,247,248,238,228,246,255,243,229,247,248,211,222,239,190,195,216,198,197,239,233,242,217,230,204,209,246,246,242,139,128,133,148,144,167,255,242,233,251,243,236,229,222,228,233,236,111,57,77,2,95,212,251,251,247,249,242,240,202,185,120,164,108,84,93,86,52,94,66,66,64,59,11,36,19,17,7,47,65,30,58,56,41,59,41,58,58,33,48,47,45,48,26,35,12,6,15,15,9,17,14,8,25,15,2,15,8,68,88,154,178,217,246,249,226,255,234,193,128,67,47,118,144,139,203,236,233,212,249,235,246,239,248,249,241,230,221,210,245,240,255,232,251,253,202,202,172,34,35,12,22,73,142,66,43,30,29,62,84,95,57,47,25,39,76,82,68,56,9,78,232,243,237,231,241,241,236,231,226,236,231,251,226,204,237,246,238,243,247,245,228,192,233,246,206,225,227,241,218,168,194,205,213,219,217,205,137,220,217,152,196,209,156,198,236,227,233,235,164,106,78,39,86,150,245,246,234,251,255,253,231,211,224,228,239,163,56,70,107,97,141,223,241,239,248,242,240,251,243,222,208,197,194,206,201,200,220,212,245,233,221,184,214,184,203,195,202,226,212,214,218,226,202,203,201,222,207,221,227,208,201,211,220,213,216,231,184,201,223,209,227,201,200,191,212,220,217,207,247,196,215,217,198,215,236,196,156,207,220,211,201,221,228,226,189,212,239,250,195,134,81,65,202,204,238,239,194,225,194,221,220,210,214,218,221,219,236,212,211,201,211,209,215,226,225,187,216,219,211,222,226,229,217,216,190,213,220,201,185,232,226,202,216,208,225,225,195,208,201,210,227,242,201,214,212,212,212,222,224,116,0,0,9,38,21,6,0,12,6,10,15,0,10,1,1,16,6,20,24,10,24,35,34,21,219,216,240,219,226,237,215,224,237,221,228,230,217,227,216,210,216,205,238,214,211,238,209,212,229,231,220,238,223,194,223,204,223,216,248,230,236,218,228,220,219,225,235,220,216,253,233,232,193,234,244,222,238,240,238,243,239,227,238,247,229,238,238,206,218,239,230,250,209,236,224,207,238,231,233,230,206,225,236,233,225,229,235,241,240,236,213,210,232,219,224,221,254,220,220,220,246,242,213,221,223,236,239,237,218,241,230,221,229,228,244,226,224,236,228,246,221,236,251,228,244,238,231,239,235,242,222,243,220,228,247,240,236,244,224,249,232,230,242,233,240,233,222,245,213,226,226,249,233,243,249,239,241,224,239,230,219,249,246,232,228,236,245,234,236,236,213,249,236,213,236,236,224,226,233,247,246,227,225,225,249,238,242,240,236,243,255,250,238,239,242,248,240,242,254,223,250,242,240,232,245,247,230,248,236,248,249,247,223,237,247,251,253,244,253,233,247,246,246,234,227,237,243,238,243,237,245,220,244,236,240,229,221,242,234,249,241,250,246,252,245,234,253,251,249,249,252,238,250,234,242,240,237,225,255,236,235,230,245,229,242,249,255,238,243,234,245,240,238,215,251,248,231,236,224,233,235,254,250,232,238,246,239,218,243,237,239,245,252,227,245,212,241,210,244,235,248,231,247,240,254,234,220,209,223,255,234,222,246,244,239,245,244,223,245,247,253,240,255,254,242,227,246,207,246,222,255,221,203,212,178,182,223,236,249,253,199,208,236,244,219,229,245,247,239,154,138,120,102,80,156,251,217,239,219,235,237,212,222,246,234,238,192,108,110,59,154,227,249,251,161,151,127,130,87,67,84,56,62,84,68,100,106,126,106,125,93,104,93,105,98,122,46,61,125,58,39,58,72,43,29,27,48,66,75,68,77,77,41,39,105,93,81,70,41,34,22,30,11,18,4,4,12,4,20,6,6,29,39,37,123,116,233,178,136,123,61,64,44,111,239,242,233,214,230,248,248,252,249,247,248,247,195,240,239,230,248,244,244,253,185,203,132,39,38,19,17,59,96,71,48,37,16,29,68,67,80,66,52,40,78,91,59,44,17,58,233,230,253,235,238,247,226,232,241,251,244,245,224,212,233,245,241,249,243,236,228,203,237,235,225,213,239,237,205,172,173,210,231,211,217,206,152,183,245,205,191,213,180,163,215,243,253,164,115,86,69,52,128,240,237,252,237,242,248,245,224,239,233,244,214,120,49,49,103,103,182,207,223,235,242,198,220,216,229,215,224,216,217,198,206,200,207,209,213,201,203,196,194,205,199,217,186,225,229,208,222,223,209,233,202,229,194,222,215,206,212,234,219,224,233,213,222,214,212,237,227,215,209,224,188,221,218,231,211,205,208,255,215,235,217,177,184,213,224,234,220,221,218,236,239,241,251,244,186,115,66,81,181,194,226,237,209,217,202,194,215,228,216,227,213,224,202,204,210,213,227,228,233,197,209,194,225,224,224,208,224,214,196,215,194,210,206,213,212,206,218,215,208,198,230,220,236,230,211,204,232,223,208,227,196,218,227,205,219,126,0,4,3,10,11,3,9,19,13,3,16,30,5,15,18,8,6,14,4,0,7,16,17,7,209,216,211,214,229,237,194,234,227,216,220,218,204,223,218,229,225,225,226,239,232,205,219,223,232,238,216,229,238,223,222,223,226,214,245,219,211,207,242,217,240,210,239,242,233,236,248,216,228,241,231,231,218,227,222,207,234,252,236,229,225,210,217,212,233,253,220,245,213,220,241,236,246,242,226,242,239,233,222,201,197,211,214,233,201,221,229,219,237,229,234,239,229,223,234,238,246,227,225,219,237,238,217,227,226,216,218,235,244,216,234,234,241,237,225,241,249,232,250,254,220,246,225,249,237,249,244,246,235,234,227,244,238,244,247,253,207,243,240,242,246,247,247,213,248,220,229,217,224,243,238,234,234,213,229,227,226,233,239,240,244,234,252,242,222,217,239,228,255,237,241,244,230,240,238,213,224,225,230,247,225,246,248,220,238,221,245,234,243,245,240,222,242,251,229,221,243,249,242,218,251,244,250,254,237,248,235,239,230,237,225,232,221,232,229,216,218,254,246,237,239,242,239,251,235,248,244,238,245,232,246,252,245,245,253,241,217,220,237,242,243,255,241,217,234,222,220,236,228,251,208,215,246,243,244,224,226,246,248,228,246,234,255,218,237,251,238,239,200,214,230,249,222,237,238,231,251,250,229,236,251,237,222,236,227,237,226,230,247,253,241,234,226,216,247,241,245,227,244,234,242,228,218,235,220,228,242,237,241,241,245,217,232,226,246,214,219,227,255,238,227,237,212,229,232,244,244,208,214,218,176,237,224,223,217,219,207,237,225,239,223,235,250,247,251,154,132,109,130,18,72,212,195,238,210,207,227,243,218,234,255,247,218,207,177,92,152,174,112,109,27,14,39,61,61,53,80,75,36,60,76,92,204,199,233,238,251,251,226,253,239,173,69,48,123,137,69,23,65,65,73,53,158,196,143,162,191,148,99,201,230,242,255,240,249,254,244,231,228,170,106,73,12,9,4,0,17,4,23,3,24,15,76,93,81,114,91,99,18,106,239,237,223,221,241,243,244,242,235,244,255,237,191,239,241,254,252,236,249,228,219,193,84,10,90,69,28,40,65,61,21,5,22,41,51,54,81,58,24,53,83,74,59,55,0,55,244,242,249,243,243,240,223,248,243,238,252,255,242,216,225,241,246,232,233,252,247,203,238,243,228,233,210,235,197,163,175,212,234,209,215,191,130,142,195,174,239,239,170,135,186,242,241,147,79,88,57,89,205,252,247,241,247,243,248,214,238,209,238,255,215,152,61,88,114,135,153,213,253,202,93,55,45,150,198,193,216,197,220,208,205,206,212,223,214,206,227,232,203,201,236,192,184,180,190,211,222,225,195,198,223,220,204,198,194,216,199,221,211,205,201,208,208,198,211,243,222,223,223,224,199,221,186,225,188,226,245,208,210,235,207,156,204,214,212,216,224,246,229,242,235,236,227,225,106,99,27,70,185,220,211,212,221,219,220,224,228,212,195,209,233,221,205,212,207,224,218,236,213,219,218,215,200,233,213,200,218,208,201,195,209,195,209,242,201,229,213,185,220,214,210,200,227,237,191,229,223,226,204,198,225,196,186,216,214,122,27,7,0,18,0,0,10,2,17,14,1,9,2,9,0,5,29,5,2,8,9,3,12,38,236,236,206,220,224,238,226,217,222,224,224,223,226,237,227,220,218,243,207,230,213,244,220,231,241,224,223,214,230,208,238,244,236,212,242,221,246,230,217,219,225,235,234,234,221,236,222,238,214,226,239,246,225,236,236,237,250,246,209,249,255,242,222,233,237,222,245,234,228,222,246,229,226,222,245,239,228,213,219,243,227,231,228,207,210,234,236,221,241,238,217,224,228,229,236,207,238,227,230,233,237,206,239,223,247,220,218,255,248,223,232,240,252,251,217,222,215,209,225,219,236,241,230,223,233,230,246,236,249,220,245,234,222,246,238,235,220,241,238,235,246,249,218,207,235,243,240,229,239,236,234,231,254,234,245,227,227,241,231,220,246,230,242,238,236,234,244,242,216,243,239,207,227,230,225,249,245,239,236,238,233,236,243,240,226,247,223,240,241,246,238,240,248,235,251,235,237,246,248,247,252,218,227,226,234,240,229,239,240,235,236,241,240,239,243,254,244,225,219,226,245,230,236,252,232,236,235,252,245,214,246,233,231,237,247,238,236,239,226,240,236,239,230,247,246,242,242,234,240,248,231,241,244,232,247,225,247,227,245,233,246,236,244,231,222,231,246,241,204,230,247,232,227,250,245,218,251,233,239,243,232,231,237,243,241,240,224,249,231,247,255,243,240,225,246,250,236,255,240,243,227,235,242,245,242,243,248,234,201,240,240,240,223,238,253,244,241,216,251,253,243,233,250,211,247,230,241,227,228,222,223,206,200,199,210,245,230,237,238,232,214,224,227,245,243,147,114,109,112,39,111,244,249,245,223,209,225,234,221,248,247,255,221,199,174,103,89,84,62,65,72,78,98,82,102,144,181,145,80,32,37,130,245,255,251,252,255,252,253,230,237,191,81,79,129,142,105,83,76,109,61,83,178,177,160,139,152,130,92,182,247,216,236,239,248,248,245,255,249,176,68,87,40,161,232,217,192,161,147,54,28,36,111,53,45,39,47,87,27,146,247,250,205,231,243,244,255,247,255,218,232,216,184,222,240,255,231,236,236,241,222,188,106,1,128,112,13,44,10,59,39,46,33,64,91,34,61,35,40,60,69,94,20,64,39,99,236,250,235,247,240,242,249,228,227,217,243,228,253,220,221,250,228,230,242,233,240,223,216,233,227,235,215,251,227,183,168,200,216,227,215,192,158,114,111,139,132,152,85,70,101,183,232,188,135,81,70,158,248,251,228,230,252,216,253,240,254,242,248,238,213,170,94,117,129,117,151,232,223,160,34,8,5,15,151,205,226,224,210,209,207,219,200,200,232,226,238,210,224,222,195,215,223,217,217,231,220,200,234,219,215,215,207,197,209,207,203,206,204,196,193,210,210,195,234,231,217,200,212,222,244,208,213,221,207,221,212,230,215,226,187,173,209,209,219,229,232,245,238,239,255,190,129,106,43,19,28,128,220,208,213,222,222,242,216,219,216,199,234,204,230,207,222,197,223,244,216,226,224,238,203,221,226,210,204,208,203,225,202,217,208,232,221,232,211,214,209,229,212,202,207,189,220,198,222,205,206,231,203,195,214,219,192,208,227,115,5,20,6,22,11,16,1,0,4,15,4,7,0,0,0,10,4,22,26,18,2,25,31,2,211,227,224,240,236,218,235,227,229,226,225,213,224,234,220,206,222,219,240,214,241,230,224,240,223,232,240,231,214,229,234,235,234,229,241,213,245,225,240,245,226,233,236,235,217,226,207,241,215,227,205,229,237,243,222,229,209,241,234,206,242,244,232,249,243,223,212,228,229,234,239,249,245,214,237,230,224,228,243,240,219,236,238,234,223,226,223,235,251,236,245,216,235,229,233,239,247,230,218,246,225,224,217,229,244,238,221,235,253,202,226,230,231,222,235,230,213,237,242,207,247,223,233,234,222,247,244,248,202,233,237,246,236,250,227,234,233,222,235,242,241,223,229,227,249,240,248,240,235,254,223,239,249,243,252,244,235,234,249,250,243,239,239,227,243,234,234,246,235,246,239,242,241,238,244,243,247,214,233,248,250,210,249,240,220,237,235,235,219,225,239,229,233,246,244,223,232,238,240,243,243,245,246,249,231,238,255,246,242,233,243,245,222,250,247,226,224,221,247,230,241,245,241,227,249,255,236,252,224,245,248,234,222,244,227,239,238,243,255,241,236,229,236,222,223,243,249,222,235,242,255,234,242,252,247,246,252,251,226,250,247,248,253,251,240,237,241,218,219,243,241,230,233,244,235,234,253,219,248,254,215,230,250,251,247,238,246,251,229,240,244,236,228,241,232,254,243,236,226,245,233,242,224,217,248,225,247,243,219,249,251,250,231,235,235,235,223,232,239,234,227,208,246,207,205,236,243,181,230,220,158,206,223,210,238,229,249,233,217,250,189,194,227,251,248,134,133,145,117,23,138,250,217,252,244,204,211,185,207,250,235,228,105,91,109,138,98,36,23,83,80,147,233,237,255,251,253,238,202,112,73,72,205,233,237,238,210,197,167,130,135,118,70,67,125,68,51,68,49,31,22,41,30,44,81,58,39,33,52,80,79,78,80,151,154,171,202,144,164,64,60,40,77,237,242,232,252,242,254,218,167,138,100,29,43,71,27,57,17,180,220,222,204,238,243,245,219,242,245,249,249,212,224,246,247,238,251,251,253,229,209,198,101,18,138,90,18,46,23,26,60,66,54,60,75,32,37,29,23,24,90,103,38,51,28,152,251,248,255,249,250,240,239,251,237,244,246,229,234,215,182,253,236,255,233,229,244,205,228,247,231,217,245,242,234,192,156,183,209,217,193,222,207,170,78,80,37,16,37,114,91,191,246,143,141,58,117,228,239,237,232,246,255,228,253,232,224,222,248,249,179,173,150,137,129,118,141,123,188,114,62,25,5,64,140,183,227,222,211,250,214,226,226,211,220,208,223,212,217,204,211,221,222,206,206,240,214,216,212,223,209,226,207,206,217,222,196,228,234,206,195,232,229,198,226,213,219,194,217,224,226,228,220,218,219,202,201,212,228,199,154,212,200,217,207,218,246,249,254,233,201,120,76,37,17,87,196,224,247,227,220,221,224,197,242,226,228,227,206,221,218,221,217,220,194,232,207,239,213,213,223,238,229,219,204,205,203,212,209,218,214,202,212,224,213,225,195,224,201,214,226,202,192,214,213,211,206,221,227,205,210,208,221,182,221,131,27,6,1,8,22,1,17,3,10,21,27,4,1,1,7,18,0,11,22,0,8,24,11,7,224,211,219,231,225,229,224,230,248,219,241,216,251,228,237,212,238,236,239,219,240,243,239,245,235,236,244,214,221,239,221,233,238,242,226,233,228,226,232,237,229,228,247,242,244,242,231,231,237,240,241,231,223,214,232,240,242,227,242,217,244,238,240,238,243,239,231,244,231,238,241,216,233,231,249,247,250,223,238,218,255,225,225,199,232,224,228,238,219,237,247,235,238,224,238,248,223,235,221,230,237,232,251,236,247,213,236,251,232,229,237,239,239,236,252,247,227,244,226,233,223,237,242,205,244,240,241,230,246,241,230,223,234,226,240,237,237,247,235,248,236,221,239,245,224,252,247,230,250,242,240,246,254,225,235,243,208,235,221,250,227,253,245,242,238,229,242,246,239,231,242,240,246,236,245,227,231,248,229,250,229,235,235,240,250,238,240,216,246,215,222,226,234,252,231,231,242,224,216,238,244,234,239,253,250,222,242,227,216,247,228,234,246,242,238,239,244,212,244,218,245,215,220,235,234,232,237,251,237,247,253,225,248,234,255,241,223,247,245,233,242,243,233,248,238,250,232,248,239,208,240,237,221,220,235,224,231,231,239,229,245,252,230,246,231,230,236,208,245,255,212,245,232,236,230,252,223,225,242,247,237,246,246,227,233,249,234,239,241,247,248,221,227,217,246,240,250,245,231,230,242,238,244,250,254,231,245,222,235,236,252,249,250,242,230,234,232,249,236,253,237,197,239,235,235,239,241,201,209,206,200,233,250,206,241,198,191,243,239,233,183,189,246,240,253,155,117,138,120,47,141,243,235,254,217,229,229,250,230,241,170,76,64,30,101,133,122,44,30,0,51,188,255,247,223,237,248,227,209,177,155,173,60,44,61,61,21,40,54,18,12,29,28,15,89,43,25,9,21,28,6,10,39,47,41,15,15,40,36,23,16,69,13,19,44,37,29,38,30,56,45,47,37,154,240,230,255,255,251,203,134,137,127,68,39,83,62,104,63,162,255,197,221,239,242,254,254,244,244,238,237,192,198,236,218,254,239,228,235,251,206,163,42,32,137,68,19,50,25,28,48,57,43,44,29,24,50,41,14,18,38,91,78,28,30,71,229,232,227,252,234,248,236,234,230,233,235,255,228,217,219,216,236,234,222,225,239,217,224,244,245,205,212,204,237,219,154,155,226,227,224,226,217,219,136,104,72,25,18,26,74,196,234,149,89,68,177,245,239,238,232,255,244,249,242,219,210,226,249,238,173,168,142,156,133,137,140,35,96,83,31,33,25,181,231,234,212,195,222,212,209,192,197,195,210,227,227,207,217,225,243,209,206,217,207,213,205,217,219,219,216,226,207,211,217,209,203,197,230,211,219,213,215,215,210,228,214,218,230,213,227,232,207,206,249,234,214,212,232,182,151,223,222,234,234,242,254,235,199,130,99,49,6,29,163,225,232,240,250,232,239,232,215,209,239,209,190,221,228,225,209,194,225,210,202,196,230,211,227,225,209,210,221,232,224,219,211,240,209,219,213,215,231,218,224,219,214,210,208,205,224,227,202,200,231,198,234,234,200,214,206,206,204,208,196,110,13,7,4,9,21,17,7,9,27,4,25,2,3,21,0,20,6,7,9,3,26,28,32,22,237,239,237,238,228,223,246,205,244,193,244,216,207,213,242,234,238,251,223,246,242,226,243,238,252,223,233,238,223,221,231,232,241,235,228,224,240,221,243,227,240,237,227,234,213,242,226,249,252,245,228,229,223,243,233,206,237,236,230,236,249,228,226,228,235,244,215,237,249,255,228,252,210,241,242,218,229,208,247,232,239,254,230,220,215,233,227,227,246,221,230,209,222,246,239,240,240,219,196,223,252,252,208,249,237,233,217,245,224,226,245,243,225,251,216,250,235,234,235,251,208,229,232,238,235,235,245,244,241,237,213,246,249,254,243,209,243,226,243,253,234,251,248,237,255,244,235,250,229,239,223,238,245,251,240,252,243,249,251,249,233,235,234,254,241,224,245,232,229,225,244,252,214,231,255,236,218,250,242,240,236,221,238,228,232,229,236,217,238,227,253,240,249,221,255,241,248,235,229,238,225,237,251,243,244,234,248,239,238,233,228,244,252,224,232,216,228,243,223,232,241,242,251,236,242,246,233,244,241,232,238,241,227,212,235,232,245,214,205,232,243,236,250,241,245,253,251,244,244,245,252,247,237,246,242,239,244,243,244,242,249,218,228,239,235,238,230,205,233,235,253,199,222,238,241,226,211,221,247,244,229,232,244,232,250,247,225,220,223,196,219,237,250,251,220,238,247,236,220,232,211,248,216,242,238,243,234,226,248,246,234,230,251,227,226,237,245,239,226,244,244,235,247,227,252,239,236,198,236,227,193,236,212,171,225,228,215,246,229,247,188,231,255,250,239,178,145,139,119,46,152,223,248,249,246,212,234,245,222,117,72,36,44,62,101,170,182,125,71,27,25,118,182,168,113,119,52,56,52,100,135,137,96,11,22,10,34,40,75,34,12,18,23,51,48,43,18,12,5,4,16,33,26,12,7,13,23,22,27,22,25,17,0,31,28,47,35,19,44,46,18,23,42,36,25,29,62,138,52,52,78,162,132,84,164,205,155,107,91,81,135,204,205,251,228,235,236,216,242,245,233,198,207,252,227,254,242,222,245,246,181,160,51,8,114,56,21,115,31,32,40,35,60,38,35,12,23,60,36,29,45,86,22,48,30,73,235,243,252,247,230,216,213,238,239,244,218,251,245,238,207,211,245,222,235,234,252,208,232,230,224,235,206,234,242,204,176,179,203,209,211,224,186,127,101,129,189,111,32,24,32,157,236,142,85,102,228,252,246,222,244,252,233,253,250,228,236,234,253,217,171,155,165,161,152,157,118,44,129,122,83,65,78,204,229,255,217,191,209,221,201,193,221,206,207,218,188,200,199,220,223,235,205,230,227,197,242,188,236,217,193,216,233,187,245,218,195,202,193,210,184,218,217,220,223,235,226,203,180,193,234,203,231,242,218,206,219,222,226,184,176,212,230,242,237,245,223,185,107,90,30,11,94,203,246,241,246,225,216,206,228,217,206,232,218,199,220,219,199,217,211,214,212,223,216,218,229,202,204,220,214,216,207,223,219,232,201,201,222,226,220,237,220,234,219,191,211,192,206,199,211,211,217,191,210,219,208,191,212,216,211,184,211,226,214,91,4,20,0,23,11,27,6,35,21,24,26,27,0,16,5,15,16,20,20,4,33,37,50,25,219,220,217,248,228,219,224,233,228,221,211,213,236,234,221,199,235,238,230,241,234,221,238,234,232,227,231,220,219,215,216,220,236,246,255,240,234,248,255,225,239,247,250,221,248,249,232,233,236,237,229,243,251,234,227,247,213,239,230,230,233,232,243,241,230,240,230,239,233,238,235,224,220,211,235,249,245,224,229,243,231,236,212,249,231,233,249,223,226,240,225,228,236,243,228,244,222,224,244,243,251,234,234,243,215,244,237,229,239,240,240,209,237,235,222,233,231,242,240,231,250,231,223,253,235,235,241,244,232,249,239,247,248,250,249,243,250,246,253,239,247,233,244,227,253,246,244,226,232,247,247,252,255,231,246,247,225,231,245,250,227,237,226,229,245,243,235,229,253,253,249,234,240,248,242,243,253,254,234,246,237,242,241,250,234,239,228,211,216,242,216,227,246,246,230,251,249,239,245,231,249,228,254,243,239,229,231,238,239,245,217,235,245,244,244,240,222,241,238,229,232,245,246,232,239,229,227,242,231,236,228,247,244,244,239,237,206,224,244,234,235,239,234,249,247,251,245,250,239,243,236,249,246,238,238,232,229,240,228,211,240,220,245,207,226,253,203,227,253,241,245,204,233,246,240,239,233,237,246,237,244,236,247,235,217,244,240,233,223,238,200,240,236,241,247,244,227,241,203,221,223,245,221,244,243,245,223,243,222,251,248,229,235,232,245,239,242,197,228,245,232,216,241,222,255,246,245,193,248,202,189,199,204,180,238,248,245,250,246,247,158,216,236,255,252,153,121,98,101,60,147,231,241,252,240,223,245,245,178,101,65,52,33,78,166,234,228,190,165,113,52,52,15,46,9,12,52,24,38,55,2,79,124,88,54,29,25,28,98,31,32,45,21,16,62,69,29,27,8,42,5,28,40,11,25,29,25,34,26,11,10,12,14,7,8,23,21,14,40,18,20,29,14,8,34,24,42,15,12,34,48,105,75,92,178,243,190,96,65,38,82,152,209,229,246,243,235,239,250,252,242,156,223,230,239,246,249,241,237,250,173,153,36,2,125,54,51,120,32,60,38,34,25,60,47,26,57,37,26,41,73,104,30,46,25,45,230,248,255,233,245,243,231,220,242,243,241,234,243,229,232,224,226,225,226,237,249,228,196,241,232,227,201,215,223,226,178,168,190,213,217,218,170,103,38,11,106,144,107,77,68,92,171,140,101,192,255,255,240,242,253,249,245,236,217,245,242,245,249,196,142,144,154,137,157,181,128,70,170,183,109,77,31,101,183,214,208,221,201,217,222,213,212,225,225,213,214,211,229,231,207,217,207,206,224,228,210,189,221,202,201,212,196,215,200,217,242,205,219,218,210,227,214,216,217,214,235,191,204,188,202,202,237,202,216,198,207,207,188,170,220,230,243,241,242,189,138,105,51,14,43,167,235,230,232,240,235,222,233,229,230,231,216,201,216,230,210,233,226,240,223,238,201,231,196,212,220,235,233,217,225,209,210,198,227,238,200,196,203,214,229,220,203,214,229,225,209,230,210,218,220,212,184,230,228,217,201,225,215,213,206,203,213,217,181,132,0,14,13,5,4,14,24,7,11,1,31,0,2,7,9,15,25,4,22,14,9,34,18,5,236,226,229,240,207,208,219,231,230,234,231,217,222,247,240,221,250,225,242,242,225,247,242,241,206,235,241,247,223,228,227,250,220,228,243,215,231,222,250,232,236,242,230,219,232,220,234,227,253,231,246,225,217,242,255,252,249,248,244,237,232,239,242,253,243,234,225,243,231,240,243,240,243,242,246,251,231,250,242,247,245,223,243,249,222,242,223,225,230,235,243,194,245,226,228,237,236,211,250,211,246,235,251,216,229,232,245,246,240,234,236,243,234,225,242,244,231,242,247,218,251,239,232,244,243,249,244,231,245,229,240,244,245,227,232,251,224,244,247,236,236,252,255,238,243,252,238,247,231,245,230,244,253,242,242,231,243,246,249,247,248,224,240,231,228,218,224,234,233,223,254,241,229,247,237,249,219,251,231,218,236,238,230,234,231,249,228,214,216,218,243,253,254,239,239,242,224,242,237,236,225,231,231,251,219,245,245,247,251,240,249,252,232,226,238,246,234,200,246,236,207,223,236,245,226,241,223,204,222,219,247,242,244,252,245,225,247,232,238,253,232,244,220,230,252,251,255,231,243,253,243,223,246,246,235,236,240,250,230,214,240,243,248,240,238,228,244,226,215,236,234,244,226,238,233,242,221,234,239,247,246,218,250,249,251,229,230,244,241,243,249,228,239,230,242,246,249,234,222,239,226,229,230,245,224,205,218,248,233,239,207,220,254,228,199,247,224,215,232,242,238,254,231,220,236,249,204,192,234,183,204,239,245,244,251,250,229,240,243,225,186,231,239,250,228,123,106,106,69,21,124,243,229,237,217,225,247,217,194,74,59,19,5,22,89,185,167,141,159,137,62,21,37,59,60,22,60,23,16,33,11,12,40,135,120,92,54,43,87,55,24,4,19,48,67,47,26,19,36,3,6,33,25,25,34,34,2,20,16,24,35,38,16,18,12,2,23,7,8,45,16,26,26,26,18,21,44,29,26,19,78,107,85,36,40,81,80,88,92,13,67,189,242,243,249,239,222,239,249,236,217,184,253,248,247,231,249,241,253,252,124,102,50,15,144,47,46,111,36,62,7,26,24,20,63,45,49,56,58,114,134,122,50,48,16,56,206,233,247,248,220,244,250,221,239,239,242,235,239,242,229,194,205,229,244,243,236,239,210,244,242,201,221,209,255,213,162,180,173,228,226,204,227,198,148,44,36,82,155,137,139,94,121,86,148,220,254,249,252,229,251,255,241,212,227,235,227,226,239,159,159,134,109,127,125,149,96,89,176,165,116,64,11,2,67,179,193,221,233,228,198,222,213,201,217,214,215,208,236,225,231,215,205,230,193,233,213,219,203,218,230,221,219,216,233,206,238,212,217,207,217,208,243,229,208,237,202,226,210,218,217,210,229,233,203,218,234,219,204,203,213,229,253,244,149,104,94,2,30,42,146,230,229,237,235,207,233,238,196,225,218,212,228,195,215,215,219,217,230,228,200,220,208,224,231,221,199,224,212,220,222,228,209,199,228,199,204,202,238,213,223,216,214,208,209,215,236,210,229,196,230,224,210,214,214,198,207,216,209,211,200,225,228,211,221,111,21,19,13,9,4,10,8,17,18,36,19,17,7,0,24,21,18,0,28,24,10,14,11,29,231,221,225,230,215,236,219,244,229,220,233,228,229,239,239,250,235,214,248,217,242,220,226,228,243,239,247,234,247,246,245,211,233,232,236,217,210,240,252,240,237,241,233,231,243,240,245,244,237,240,253,255,246,252,233,222,230,236,242,236,223,254,246,241,243,241,255,219,234,254,234,250,233,248,248,224,230,240,224,228,245,230,246,242,223,249,252,237,230,233,216,231,238,233,233,206,198,237,240,239,246,236,223,226,246,213,244,233,224,240,242,245,248,234,252,225,226,244,221,232,250,248,236,233,248,255,246,246,231,233,230,236,244,244,244,226,239,248,255,242,244,253,225,237,251,236,244,218,234,230,240,247,223,254,246,239,228,253,230,247,245,239,226,247,225,240,250,242,240,227,237,249,244,236,244,245,207,216,240,221,225,228,212,228,227,214,230,220,230,213,219,227,235,234,233,238,239,244,248,240,240,206,238,234,230,237,242,255,218,236,232,249,244,236,250,224,233,236,222,241,245,248,250,232,218,250,242,236,252,234,240,250,230,222,242,238,246,252,214,229,252,234,232,243,242,255,252,239,243,225,253,238,236,236,203,245,249,247,243,237,233,221,233,229,246,239,220,232,246,248,252,236,237,238,237,245,211,237,247,246,215,246,219,211,226,247,235,226,216,255,248,232,245,244,235,225,242,219,239,233,242,242,244,246,234,239,240,237,238,251,242,231,232,243,253,238,223,231,246,227,255,236,224,242,249,255,216,214,224,189,252,245,246,226,227,217,231,241,255,229,164,238,236,251,227,101,113,98,83,12,95,240,238,255,248,212,254,255,208,88,27,24,36,80,74,43,32,54,136,160,107,33,20,47,36,34,79,13,33,14,39,48,16,30,88,143,117,105,113,38,15,2,34,2,34,67,36,12,19,11,37,23,35,17,8,6,18,19,14,10,30,22,24,14,13,35,7,22,36,17,13,10,35,35,24,4,28,17,21,59,58,68,57,63,53,33,35,60,97,30,22,189,244,249,253,217,243,241,233,248,193,194,252,238,238,228,243,223,247,231,93,114,35,8,140,43,68,65,11,23,24,33,40,37,43,52,62,86,147,170,164,148,98,35,32,45,188,241,250,228,232,215,245,238,241,227,217,235,229,225,239,195,218,247,222,245,213,241,251,224,229,248,200,221,239,219,196,158,143,234,198,237,224,216,200,132,102,154,154,149,116,52,15,50,192,239,250,254,253,242,249,242,235,227,227,244,240,253,204,140,152,105,82,134,112,147,95,97,192,148,68,61,3,45,173,203,193,223,229,215,196,218,201,196,214,226,213,199,208,219,239,232,198,210,183,232,216,194,234,229,215,213,226,229,225,213,204,203,211,212,237,215,201,234,243,200,227,219,225,216,236,207,197,224,192,244,204,225,179,226,252,242,157,127,71,13,10,3,82,174,238,239,238,213,242,204,221,244,216,218,210,223,249,237,208,238,235,223,227,230,233,215,212,228,207,243,224,221,231,238,201,206,229,233,224,204,210,219,215,214,217,236,222,213,217,190,210,217,190,205,210,237,235,233,209,228,211,218,224,222,194,199,234,206,223,133,1,14,1,19,14,6,18,4,7,12,20,13,5,0,3,15,6,7,23,12,3,7,4,15,219,218,239,228,237,211,218,251,236,253,227,227,225,210,223,239,227,237,193,230,232,243,231,245,229,249,238,246,246,245,237,220,243,236,234,238,229,236,238,224,244,232,250,244,226,226,226,228,236,234,252,236,239,240,246,251,236,239,230,229,223,246,222,254,240,238,233,239,240,228,254,231,231,239,231,245,235,251,240,255,225,255,207,236,228,239,246,228,246,228,233,234,237,235,221,227,235,225,251,225,239,210,253,224,243,228,241,236,240,228,248,237,242,243,247,239,251,224,238,210,239,238,241,221,235,247,206,239,237,241,247,238,244,233,233,248,229,243,237,242,251,247,245,248,227,224,251,233,232,249,245,249,245,233,241,220,226,243,223,249,255,255,233,223,246,238,238,246,211,221,226,232,228,254,234,243,230,239,231,233,236,248,231,243,231,235,243,196,242,251,234,238,241,233,237,255,249,241,231,214,222,249,238,217,248,217,252,227,247,239,224,209,241,225,227,218,229,244,241,233,245,241,234,228,236,230,236,246,239,249,239,230,241,252,226,232,236,233,246,238,234,238,221,244,239,254,242,245,223,238,239,246,231,237,237,229,216,236,254,239,248,232,246,247,236,243,213,238,237,222,246,231,243,246,235,208,234,251,250,233,236,238,239,247,203,229,215,247,217,245,224,224,231,255,217,226,226,228,234,233,250,230,252,220,233,239,243,249,238,240,237,250,233,232,245,232,245,208,253,227,227,226,211,250,231,246,208,213,249,210,239,206,182,181,208,222,235,246,250,255,173,239,232,255,200,80,94,76,68,10,97,237,249,247,233,229,253,252,184,84,53,81,120,99,46,49,12,42,66,153,181,128,63,76,43,64,76,56,53,31,43,46,29,31,7,33,134,169,152,48,5,21,14,12,42,81,23,21,31,29,19,21,12,25,7,7,19,14,16,24,8,12,29,21,27,39,13,8,34,20,22,39,15,34,37,13,30,18,40,63,98,85,64,40,17,32,42,51,61,27,51,210,238,255,250,205,234,236,248,254,185,223,239,219,227,243,226,246,247,179,89,129,47,35,142,8,86,76,18,15,35,16,26,24,18,53,81,119,128,133,102,95,60,50,4,28,200,225,255,214,210,250,222,255,247,238,246,233,207,252,233,202,201,255,245,254,247,250,255,245,243,233,191,214,205,210,201,151,177,176,206,208,227,245,224,134,137,184,169,144,131,61,52,138,241,245,242,249,249,234,242,230,212,238,248,237,236,228,183,155,132,129,129,129,107,147,119,139,217,125,71,64,4,114,222,242,249,204,216,217,210,217,216,221,213,214,220,224,243,217,231,232,232,223,223,239,216,239,212,232,219,220,212,226,221,209,206,224,204,220,239,206,210,208,216,236,235,211,231,220,232,226,226,222,222,212,228,217,200,209,208,135,123,39,48,55,136,164,197,227,241,240,219,212,208,206,206,221,226,224,231,223,232,239,204,220,219,241,217,225,200,221,200,213,214,216,211,208,218,232,212,237,204,202,216,213,208,201,223,216,234,214,209,223,207,222,215,194,233,217,221,214,206,222,183,211,194,206,203,217,200,240,196,211,205,117,20,3,18,13,7,2,15,0,30,20,10,25,0,5,5,2,6,24,9,0,23,10,9,17,211,229,219,228,241,220,238,238,232,241,246,242,228,255,209,225,215,240,222,232,240,236,245,231,237,237,241,245,244,243,225,202,246,255,224,223,232,243,232,240,243,217,228,234,238,225,253,223,245,253,243,246,226,228,227,249,233,233,229,244,241,252,244,231,235,229,229,237,224,249,244,235,223,229,234,241,234,235,221,228,239,230,250,238,219,233,201,254,201,240,237,237,242,253,228,232,253,220,225,226,227,237,222,231,241,222,207,232,227,220,224,240,251,240,219,236,243,212,226,217,215,220,234,253,217,227,249,245,247,254,234,248,236,253,237,249,241,220,239,252,255,250,221,237,245,228,243,237,240,232,232,253,238,229,246,232,229,255,247,250,228,236,222,249,253,231,242,240,229,244,240,222,216,247,213,237,251,240,241,225,237,237,214,218,237,251,228,218,239,217,222,238,242,243,222,236,231,230,229,241,232,219,243,243,230,233,215,241,255,253,233,222,247,229,200,194,236,244,241,245,230,239,229,242,229,222,250,242,231,230,226,236,228,241,247,238,236,254,242,239,231,213,232,252,233,231,226,232,229,235,250,243,246,232,230,233,247,247,222,220,248,237,239,247,227,214,230,242,243,241,219,236,228,251,216,221,255,242,221,225,237,229,230,246,244,233,227,250,250,247,218,231,206,242,246,235,237,239,253,223,236,237,226,203,227,220,243,236,225,243,243,229,237,207,240,228,244,247,219,242,235,213,239,239,234,247,211,244,210,162,203,222,229,247,241,250,245,245,248,246,184,253,245,250,188,94,69,66,54,12,109,230,237,247,234,242,232,255,224,80,65,39,65,44,44,67,44,46,55,73,189,171,131,111,41,55,69,68,58,38,43,50,27,48,42,40,14,65,142,90,85,29,14,18,52,76,32,26,32,3,22,1,25,13,2,23,5,27,42,17,9,33,30,39,18,28,12,46,11,18,25,24,6,40,1,6,12,31,58,93,93,53,29,56,34,35,73,48,55,23,80,219,236,254,255,240,235,234,243,231,192,231,251,243,249,235,238,253,244,189,77,97,69,68,165,13,61,73,25,35,9,30,29,9,76,50,66,101,114,88,80,43,52,92,20,100,207,230,248,255,229,233,230,223,246,244,238,240,253,230,251,243,218,243,252,249,255,254,254,244,233,253,210,190,225,210,215,172,168,207,224,223,191,201,187,185,184,199,157,141,136,82,124,211,242,225,255,233,240,218,237,210,250,243,235,228,249,243,162,161,159,145,163,127,145,133,166,169,133,68,60,34,12,144,244,229,252,214,222,222,212,224,221,186,232,236,200,210,224,225,252,255,241,231,229,239,252,203,236,239,198,225,233,216,221,231,213,213,202,222,223,236,228,241,239,241,251,237,250,250,239,224,234,229,232,252,248,215,196,162,132,80,30,19,88,191,234,216,232,226,238,222,221,216,226,196,215,229,224,209,210,216,209,222,210,237,193,224,220,197,214,232,228,217,227,239,237,241,198,219,197,205,203,221,211,222,222,206,210,243,199,213,231,224,192,206,191,220,243,193,212,215,206,211,209,205,220,212,202,232,200,203,220,186,226,120,7,15,3,10,5,13,14,13,16,20,3,13,3,11,11,3,19,9,32,25,18,14,13,1,241,226,211,238,204,203,208,225,235,218,226,229,244,224,236,239,243,218,237,236,227,242,237,253,219,238,244,237,228,236,250,235,225,232,222,254,220,234,243,236,246,224,232,246,226,246,228,243,231,234,243,235,232,224,248,230,254,248,243,238,213,228,238,239,247,246,238,235,250,244,251,237,224,219,243,249,231,249,215,240,240,244,252,232,235,238,222,224,227,235,240,227,243,235,227,212,241,236,234,223,231,246,243,240,222,250,228,254,233,226,231,209,242,246,231,223,237,232,233,240,251,207,246,226,241,235,228,247,235,240,236,249,247,215,225,219,225,240,218,241,229,231,240,234,247,243,230,241,221,224,215,243,237,205,242,239,242,252,225,245,245,248,248,243,249,235,244,241,232,245,241,237,224,223,240,214,241,227,230,239,238,254,251,227,252,223,243,233,228,249,209,239,207,210,242,243,243,242,222,231,231,247,234,250,230,232,254,232,239,230,245,220,240,229,226,227,238,245,237,232,238,227,231,239,239,239,234,232,234,249,235,242,239,254,244,246,215,255,217,240,246,230,223,250,255,218,250,203,233,255,246,244,244,235,254,247,218,253,236,249,217,241,231,233,249,233,216,223,245,216,233,242,238,229,220,247,219,230,231,221,236,246,236,235,231,232,227,208,233,226,231,234,230,231,242,249,225,254,237,243,228,234,243,252,242,239,254,225,215,241,249,239,232,222,247,252,241,224,237,230,234,228,247,246,250,244,210,193,185,181,233,233,242,229,249,221,204,212,251,227,198,229,245,240,216,76,82,106,89,3,97,231,233,248,210,228,229,241,234,84,17,23,5,40,68,55,31,35,34,68,113,171,167,115,14,22,45,47,53,41,64,56,14,15,18,47,38,25,58,110,167,114,30,29,16,78,45,11,23,16,4,32,14,22,6,40,18,11,7,0,17,20,39,54,22,25,17,42,16,42,12,25,43,47,39,44,9,36,80,83,99,60,65,72,35,55,111,74,68,15,103,227,253,242,253,243,252,220,250,237,166,235,247,234,228,231,234,224,252,186,81,83,38,50,107,12,102,64,21,18,1,19,7,48,15,27,30,58,92,59,42,37,47,28,18,117,246,248,241,236,224,249,237,242,251,227,255,242,246,243,254,232,198,216,217,245,138,171,162,153,240,254,233,215,203,246,216,186,174,190,225,181,100,88,86,162,135,119,120,91,66,111,205,227,243,249,250,255,255,250,239,225,241,228,254,231,222,176,157,151,180,143,144,142,153,193,148,114,84,41,69,9,39,213,249,228,252,236,226,206,212,226,206,190,211,215,209,243,228,246,250,239,255,249,245,243,250,254,231,235,207,204,209,225,223,235,218,225,234,220,230,214,231,236,246,233,236,235,229,227,231,231,235,231,252,245,236,146,156,96,43,27,37,124,246,241,234,209,218,242,242,238,213,202,219,211,206,213,209,216,225,184,226,222,227,239,209,233,206,208,198,217,230,220,214,216,210,209,209,231,233,219,208,217,217,205,233,228,224,204,225,216,212,199,207,229,214,221,229,183,234,246,226,212,220,221,219,230,208,195,190,202,205,213,208,109,15,3,7,23,18,22,11,10,17,2,13,8,18,11,9,19,12,14,19,1,18,9,9,9,233,231,217,229,216,195,229,246,219,230,235,236,220,217,248,225,232,245,249,236,235,237,243,231,240,246,236,224,248,241,242,252,248,226,234,230,249,247,227,235,239,229,238,225,248,246,226,241,240,223,242,251,225,240,207,222,246,249,246,249,241,250,239,238,239,217,240,239,250,239,217,235,227,242,232,234,226,231,210,255,236,251,251,240,241,247,234,218,228,246,244,223,235,214,233,234,232,222,233,214,232,243,255,243,246,242,228,213,235,244,240,242,245,243,225,248,239,247,238,230,242,230,248,206,224,237,232,236,251,240,224,240,247,236,243,237,232,229,254,237,249,237,253,211,224,247,250,238,224,216,222,236,211,237,241,240,255,236,254,251,224,229,240,229,229,236,254,234,222,247,238,234,247,230,237,230,238,233,237,241,211,226,207,239,213,238,234,252,216,235,211,226,241,232,241,246,252,248,250,233,246,215,233,237,248,241,237,231,242,215,246,219,240,238,223,239,234,228,230,252,232,225,211,235,226,248,244,242,231,229,229,234,233,205,223,253,230,241,238,248,254,246,247,244,230,253,241,247,224,255,243,248,229,251,229,240,239,249,222,241,234,246,224,252,212,218,232,236,235,241,220,224,240,212,208,222,243,244,232,228,244,240,237,245,225,239,230,214,248,211,222,246,228,222,224,235,246,240,242,247,247,223,243,223,246,246,229,247,245,252,237,236,225,245,239,212,250,207,238,237,243,244,232,242,241,239,209,218,214,216,246,241,208,251,215,193,233,246,233,201,211,242,234,251,192,161,148,128,130,53,160,234,234,238,243,227,247,249,242,132,46,1,1,49,75,33,47,46,37,17,50,93,193,184,60,40,13,33,53,44,30,9,5,23,24,17,2,44,209,231,242,238,207,136,135,130,23,16,2,0,29,14,9,19,24,33,19,32,14,16,21,49,24,36,43,44,25,35,35,35,24,26,48,62,47,32,60,54,89,89,89,61,55,50,53,61,79,110,40,58,162,245,248,239,237,229,237,228,254,190,173,234,244,213,217,249,239,248,242,164,69,68,73,83,88,37,83,47,8,38,6,20,28,10,31,25,45,46,84,102,77,50,92,42,33,140,221,236,250,251,237,247,254,253,252,250,240,235,230,239,255,192,128,61,14,85,30,31,89,81,189,244,250,247,244,252,242,175,184,181,185,225,97,18,24,17,58,44,33,38,31,107,239,232,255,249,252,248,255,246,233,234,245,255,238,247,231,168,139,169,171,183,113,152,136,157,145,49,25,35,39,17,63,233,249,227,239,221,230,226,217,211,230,212,217,243,212,218,204,154,144,155,207,231,245,252,242,255,215,219,242,228,212,214,226,205,211,235,228,223,206,214,218,248,229,189,103,97,104,199,223,214,249,248,252,236,179,119,107,41,2,70,220,241,252,208,173,222,238,243,225,244,217,217,200,214,205,215,218,230,233,221,234,206,220,230,218,236,211,229,233,235,241,220,210,207,231,219,209,231,212,202,207,215,213,229,204,194,211,202,206,226,234,203,207,218,218,248,231,202,215,220,222,189,209,212,218,204,229,214,200,203,212,214,215,130,26,9,9,0,10,25,16,20,35,37,17,22,11,5,1,26,18,7,5,8,13,23,28,9,236,238,224,239,224,243,240,224,232,239,242,234,244,213,222,246,225,229,246,246,236,208,248,242,242,238,236,237,246,234,223,237,225,231,241,245,228,233,241,249,224,253,238,247,226,226,230,229,251,234,220,236,248,232,220,255,231,228,225,215,224,242,238,224,240,247,243,214,234,235,242,217,230,224,227,229,218,233,240,241,240,237,227,240,251,237,227,209,221,238,215,245,240,239,217,233,244,238,230,238,222,244,227,218,226,224,219,226,245,245,225,225,235,217,250,244,224,253,229,242,233,249,247,255,228,252,232,253,225,242,235,245,221,243,242,250,234,243,236,237,212,241,242,209,235,215,242,233,247,232,222,219,245,240,215,238,252,250,241,255,249,252,229,254,252,245,247,236,242,243,244,241,219,237,202,233,236,229,246,202,209,239,216,233,234,229,240,213,222,237,222,236,238,215,241,229,242,248,243,237,229,254,239,253,230,235,230,253,242,241,213,240,228,213,238,237,224,241,214,239,224,211,223,219,228,215,226,241,249,240,238,218,239,240,225,245,232,238,239,230,231,233,252,251,253,240,245,234,232,219,234,231,250,233,237,245,246,230,241,242,251,230,238,239,228,242,216,227,230,243,248,245,218,204,228,237,211,237,221,243,233,241,223,241,242,225,201,227,230,246,249,232,234,246,215,240,241,242,247,253,233,235,230,244,245,233,250,248,233,243,222,219,250,223,238,245,236,230,234,229,228,223,247,247,242,210,211,226,231,223,217,213,188,212,199,197,230,253,232,231,188,252,251,247,230,149,161,138,104,50,168,240,224,249,226,229,252,250,239,122,48,4,17,70,75,66,50,50,37,22,53,51,119,185,114,62,27,45,39,44,39,16,13,27,14,38,28,187,240,246,239,150,132,151,164,184,63,14,19,5,22,21,34,8,35,13,16,5,25,28,41,47,42,63,87,68,64,66,60,61,53,48,43,45,46,15,77,60,62,93,75,80,89,75,45,58,90,53,18,67,162,248,237,255,237,250,229,229,250,219,173,228,232,250,241,231,229,255,231,170,78,58,52,41,81,25,85,35,9,24,8,46,36,20,11,36,30,89,173,182,141,75,91,88,30,128,208,233,247,244,240,236,213,233,246,254,247,222,237,242,228,185,99,25,0,4,9,73,92,6,139,253,247,238,250,250,243,198,178,153,216,230,162,66,56,47,44,45,50,30,20,72,149,229,242,251,255,223,255,226,253,234,254,249,223,228,201,153,156,156,172,123,135,146,146,146,96,27,27,9,25,22,106,224,243,234,241,229,229,220,227,209,207,219,211,208,225,246,173,86,80,43,11,122,109,144,209,229,219,230,226,219,232,247,218,205,216,236,219,220,207,204,217,234,189,93,45,22,0,75,198,238,253,239,215,171,92,78,30,16,153,236,250,252,232,207,208,226,224,240,212,215,208,206,231,212,207,205,209,225,224,193,233,199,220,215,204,193,221,220,223,216,235,205,189,216,225,226,223,230,206,201,215,230,227,219,229,230,224,211,217,221,228,233,198,205,231,209,205,209,208,208,233,235,204,212,228,224,208,214,230,207,210,235,239,105,22,19,9,4,3,8,23,7,16,23,4,3,8,6,0,9,5,10,13,19,16,23,7,5,231,236,232,232,230,244,219,221,240,242,231,250,239,215,238,225,241,236,232,229,237,240,214,247,213,232,253,246,223,226,233,220,233,235,246,235,223,233,236,244,250,233,247,247,221,239,240,234,219,228,228,232,239,234,243,254,249,237,229,242,218,233,240,228,237,226,248,217,222,235,236,214,223,230,225,229,210,238,217,251,237,242,216,238,230,244,220,230,219,245,243,237,243,229,202,236,230,227,230,240,243,247,229,215,234,238,230,245,228,229,223,223,238,237,249,241,233,247,247,238,246,255,253,252,242,231,251,233,244,231,252,244,243,241,222,245,253,248,243,235,232,234,238,243,235,237,222,227,240,242,208,240,227,223,226,238,244,238,241,251,231,234,224,226,232,246,248,231,229,250,249,233,241,245,240,241,246,233,215,242,240,246,206,233,233,241,233,243,239,238,238,222,239,247,247,231,243,220,238,247,245,249,249,255,235,246,245,255,233,248,233,227,236,210,215,226,248,232,235,224,232,239,242,220,226,218,237,246,213,237,234,232,228,232,235,219,210,246,243,242,251,244,227,198,224,245,246,245,237,255,245,231,235,230,214,241,254,245,235,250,239,242,255,238,225,215,227,236,234,243,226,240,252,207,227,252,222,251,226,225,241,217,229,238,255,247,225,248,252,229,252,250,247,253,229,230,250,226,233,243,243,243,252,234,248,207,245,234,215,242,247,245,237,240,233,233,254,211,232,221,254,251,219,244,242,248,234,228,189,176,232,216,217,224,248,231,251,244,250,182,171,247,229,247,204,171,120,111,90,30,186,236,239,245,215,196,242,243,243,172,131,46,15,25,57,47,45,44,44,21,52,25,77,116,164,144,45,48,38,32,27,11,20,34,25,168,255,253,233,237,224,92,26,5,131,197,129,75,29,14,23,5,14,26,5,32,10,26,17,63,134,90,22,9,57,60,91,81,65,51,39,29,27,25,33,57,54,60,57,91,61,68,67,46,67,93,82,64,11,49,223,238,241,251,221,238,214,236,246,173,182,229,248,254,245,246,247,234,254,244,86,49,69,86,60,54,72,29,15,16,19,25,36,41,28,25,45,95,161,147,119,50,92,122,110,138,193,225,250,255,204,131,65,33,44,166,235,246,249,249,245,156,65,11,1,55,16,31,22,10,127,184,156,139,170,231,254,255,188,165,218,229,203,100,69,54,52,47,32,23,32,6,90,229,251,235,244,255,251,222,247,253,238,252,230,252,146,107,143,161,151,159,149,139,140,127,60,11,5,45,28,24,5,12,119,221,216,248,232,200,222,215,207,223,225,227,244,253,161,69,99,54,5,21,21,5,39,165,180,210,215,202,215,223,223,232,243,208,217,192,234,239,241,250,163,89,81,26,4,78,219,225,237,152,113,69,32,25,92,228,241,232,250,214,173,179,228,222,213,232,242,215,220,226,242,223,211,218,211,203,216,214,211,241,200,207,228,229,224,211,216,211,218,220,210,198,211,223,221,216,226,219,222,209,208,219,189,241,212,216,227,223,208,207,210,220,215,216,211,216,214,235,211,204,215,231,217,219,227,219,218,206,232,186,211,79,15,9,0,19,1,30,18,0,16,28,26,17,7,0,5,2,7,1,1,12,7,7,21,22,235,222,249,229,224,250,230,228,218,236,229,198,236,229,228,228,234,230,204,234,245,232,244,242,233,239,235,224,224,237,218,226,229,235,242,238,241,249,235,242,232,230,248,250,224,238,220,234,223,246,219,241,226,230,236,217,243,240,245,240,235,232,244,228,239,247,227,217,228,222,253,239,230,236,225,216,230,245,219,236,227,230,239,246,236,252,229,213,239,226,237,243,230,244,229,228,222,245,217,247,238,245,212,240,226,217,237,215,251,249,242,237,243,231,216,233,219,233,238,249,209,227,224,240,237,239,240,229,233,233,231,239,239,240,225,242,249,231,216,236,232,225,216,228,230,242,235,243,230,236,218,218,232,237,218,242,238,234,241,253,235,225,233,223,213,230,222,237,229,238,255,226,239,235,255,231,216,234,206,219,222,213,249,224,229,225,242,236,208,223,228,250,218,253,241,247,236,242,234,245,238,242,240,245,249,252,227,245,221,245,235,236,239,216,220,234,232,248,238,231,228,202,231,232,246,226,242,236,226,237,225,219,214,221,253,227,226,253,253,222,252,243,238,233,246,252,227,235,247,233,242,237,228,238,249,232,230,239,232,228,244,224,249,243,235,208,242,231,246,235,225,225,245,209,236,245,227,238,234,219,241,252,225,253,235,249,240,246,253,240,236,243,242,242,235,221,234,237,227,252,241,247,242,232,211,214,226,243,229,246,236,222,239,207,240,255,244,242,234,240,248,245,247,250,243,222,223,220,162,220,226,189,224,241,233,213,244,216,233,183,173,231,240,246,215,135,154,135,114,37,182,226,219,243,236,226,246,243,237,255,221,122,45,3,4,31,18,31,26,25,34,49,49,34,112,215,122,102,47,17,2,10,8,10,95,238,248,227,209,148,97,43,34,25,25,98,141,81,129,45,41,8,29,19,27,15,17,8,29,151,249,139,36,10,68,99,95,60,51,33,21,13,27,12,47,56,64,72,90,87,68,65,29,38,19,72,57,13,94,152,185,237,240,245,246,234,235,236,242,177,244,255,245,252,250,246,243,252,246,197,119,16,58,108,15,30,72,28,22,23,102,133,64,29,4,24,88,126,166,95,73,29,33,124,133,141,234,242,238,237,174,68,23,11,23,128,241,250,254,255,163,68,24,8,24,2,10,116,156,86,56,37,1,39,2,70,186,234,218,149,199,232,212,120,72,71,23,16,34,36,108,72,125,234,247,245,252,238,252,247,252,247,237,222,239,181,152,150,158,146,171,169,137,134,121,122,94,100,36,51,46,39,28,36,10,105,218,231,255,221,230,212,207,241,229,251,255,250,160,57,29,54,225,161,56,20,27,154,242,237,234,223,212,235,252,237,244,250,232,249,222,222,222,244,225,176,137,68,62,200,254,202,174,107,71,28,38,158,232,234,250,255,221,170,170,243,217,227,206,210,212,227,212,223,212,227,234,226,217,236,220,186,220,228,211,227,216,235,208,222,202,243,231,202,207,220,209,226,213,228,214,198,203,230,215,223,244,224,209,222,222,235,233,233,211,201,223,227,216,216,209,205,203,225,209,214,228,207,239,210,222,196,233,223,206,119,10,10,14,19,12,20,0,14,15,9,8,17,0,5,4,13,11,6,22,32,0,16,29,14,234,226,232,229,250,224,247,222,211,219,239,233,223,224,204,247,232,231,245,253,240,219,227,219,237,243,245,216,222,227,221,243,252,244,235,236,225,218,232,255,239,233,247,244,233,230,244,245,230,245,223,216,245,234,243,244,245,254,244,247,223,227,231,227,242,247,237,229,237,237,223,219,229,245,247,253,239,218,249,224,239,241,232,235,236,242,232,239,227,229,231,239,243,215,222,238,226,234,235,236,215,221,225,231,241,216,223,235,227,241,216,237,238,222,227,205,218,221,236,230,236,240,241,232,235,231,244,250,254,242,236,222,230,227,241,247,253,244,225,249,233,237,240,229,250,224,235,247,241,234,229,247,231,240,217,247,223,235,222,246,228,234,201,216,220,230,241,233,241,223,241,224,213,243,245,234,253,241,233,245,237,212,228,254,245,229,252,243,215,237,239,211,247,245,231,243,242,238,244,234,243,244,233,219,230,246,227,235,239,215,217,243,224,218,220,217,219,240,222,226,217,233,246,234,218,223,233,223,237,236,220,245,234,244,207,238,230,240,255,253,251,252,235,228,246,248,250,253,228,247,243,239,234,245,236,225,237,230,231,248,242,240,236,236,231,232,245,232,230,249,236,235,229,232,255,249,242,240,225,251,238,221,245,246,255,233,247,253,227,225,237,228,231,253,228,249,243,250,234,248,224,246,230,228,225,249,253,230,243,254,244,242,224,233,237,243,249,249,238,244,242,248,249,255,255,183,194,220,224,230,244,241,231,242,206,198,225,234,251,176,174,253,230,251,207,134,140,122,118,64,188,244,245,240,245,236,240,242,237,240,253,155,143,72,15,16,18,3,12,6,9,35,52,45,28,127,192,139,60,17,11,29,15,58,20,48,74,36,76,55,36,46,25,36,15,61,81,64,166,136,105,41,16,10,8,7,1,17,10,131,228,108,33,7,56,103,73,30,30,0,21,40,25,32,21,36,64,88,102,88,52,49,23,20,36,53,99,119,166,121,161,220,224,236,232,225,250,254,252,237,251,240,254,226,156,142,163,232,253,189,109,43,77,97,0,43,53,41,27,14,187,191,46,25,3,39,97,167,213,136,108,84,65,105,94,116,237,240,229,245,178,67,52,6,21,190,229,253,249,192,62,25,3,38,3,41,210,245,219,80,14,5,8,13,26,29,63,169,223,173,210,243,237,163,148,73,7,23,12,86,222,174,138,253,222,251,250,229,244,234,238,233,215,231,224,161,125,135,152,182,160,151,138,121,137,180,176,237,180,63,36,31,32,30,41,11,48,201,249,236,232,234,237,236,233,237,199,122,92,53,31,160,231,233,193,43,35,159,219,246,239,250,238,234,224,237,217,249,246,240,226,241,245,247,243,223,150,104,3,104,174,144,112,49,34,84,175,228,240,250,252,235,195,165,173,206,241,212,220,231,218,231,218,202,233,246,211,215,237,218,208,240,227,215,227,250,229,228,249,197,207,217,202,199,221,215,231,213,208,218,207,216,217,217,224,230,232,214,211,197,207,220,197,220,209,225,221,211,227,212,207,214,235,199,215,214,222,223,233,209,214,228,191,198,209,108,11,30,8,8,7,3,15,25,11,23,10,23,20,0,5,5,4,10,24,3,4,24,34,15,238,249,240,211,247,226,212,238,230,229,230,208,226,228,229,228,231,233,239,219,234,220,242,229,231,241,221,230,233,226,237,241,237,198,208,236,209,252,219,218,229,229,236,228,242,250,226,242,251,232,248,230,224,230,230,246,229,226,246,232,235,243,226,246,232,226,242,241,248,225,237,223,227,224,239,230,231,202,243,222,223,216,228,235,241,234,236,241,246,219,242,223,204,247,219,223,230,240,236,221,229,217,213,227,230,209,243,242,215,241,240,224,231,217,231,210,234,239,220,238,228,229,235,224,244,239,247,233,243,230,227,249,242,223,238,222,231,242,228,223,242,227,228,238,212,221,234,232,247,218,224,218,238,219,222,254,229,235,211,242,233,220,227,233,248,226,245,219,225,246,232,213,234,228,215,214,226,238,227,239,235,246,225,221,225,222,239,204,238,233,235,242,225,214,245,249,229,223,218,236,230,254,251,233,231,236,237,246,218,218,244,238,230,240,236,219,214,237,223,215,240,206,223,229,226,216,250,229,218,246,241,210,232,230,241,240,249,245,231,222,254,239,232,226,249,244,246,243,220,252,236,240,236,255,221,227,232,243,243,249,252,254,221,244,236,254,243,237,230,236,249,218,200,216,233,235,233,229,226,239,248,238,255,244,243,249,252,255,242,238,231,226,232,238,240,241,229,240,247,233,243,222,255,255,242,242,217,247,240,230,254,255,218,245,221,250,255,245,217,250,236,224,231,245,244,225,232,237,226,221,220,190,196,205,222,208,246,223,253,215,201,234,229,222,188,155,130,128,102,70,183,252,237,250,237,233,212,224,209,254,236,192,226,155,145,93,7,9,15,11,18,47,75,81,11,73,140,185,81,18,6,3,58,49,29,33,50,42,69,60,34,33,29,52,12,67,63,23,42,111,203,130,89,60,45,37,13,11,45,35,52,46,26,36,16,78,63,26,25,10,16,23,9,17,19,44,66,72,106,34,48,19,26,49,105,213,205,168,116,136,219,228,251,238,239,226,248,255,250,214,247,238,250,128,100,97,63,131,148,154,110,17,90,94,16,64,48,7,52,11,52,115,50,34,12,64,149,204,155,105,87,83,31,59,52,124,242,252,239,219,99,20,12,8,95,219,237,241,160,80,15,1,38,69,106,234,239,251,144,43,39,79,80,74,10,4,9,133,200,184,205,225,219,155,137,53,31,25,39,188,215,237,159,198,255,239,241,253,244,254,233,228,234,222,187,156,151,138,178,165,177,146,99,133,160,213,220,219,217,98,88,139,85,51,34,15,23,91,229,238,223,221,238,249,188,116,26,13,9,14,7,35,159,227,229,107,6,59,193,228,229,242,223,139,106,90,108,199,238,237,240,221,214,232,207,197,186,118,55,48,30,34,51,21,78,180,245,249,240,241,247,208,181,164,239,224,219,216,201,209,216,209,238,235,218,225,223,213,224,236,249,224,203,202,208,208,212,200,226,220,235,204,228,222,216,221,191,207,218,221,219,216,219,213,217,202,195,226,219,212,207,233,204,205,215,220,237,231,215,201,221,206,236,209,210,177,234,208,199,216,215,206,229,206,209,121,9,11,3,4,1,29,17,5,14,36,9,15,5,2,9,4,1,13,9,7,7,23,27,52,230,217,236,239,225,232,222,206,224,227,213,248,223,245,224,208,207,242,221,216,240,246,219,240,203,229,215,242,236,232,241,232,203,223,221,226,240,239,208,249,231,232,239,220,230,243,248,247,214,228,255,235,232,232,243,242,218,210,248,216,223,232,240,234,245,243,238,245,242,246,246,232,243,223,244,237,224,232,244,231,215,245,238,231,231,234,210,228,211,227,240,213,240,215,232,233,234,211,241,219,216,220,217,245,226,215,237,221,228,233,237,215,222,234,241,242,215,248,249,217,241,244,224,240,248,224,228,231,219,236,227,236,239,230,210,219,215,244,234,230,239,224,231,234,254,234,224,253,252,226,244,237,243,235,212,213,224,224,234,244,247,207,230,229,208,235,230,233,233,228,229,251,235,240,239,212,216,243,220,225,229,220,240,219,237,233,230,236,242,249,224,241,234,238,232,241,246,218,227,225,223,247,237,238,249,216,235,204,227,220,228,228,242,224,252,216,245,234,232,224,233,237,247,233,237,232,234,220,245,222,229,235,248,201,253,230,231,227,241,235,253,227,219,252,232,240,240,242,240,248,251,220,240,255,224,239,245,232,252,248,237,238,250,229,250,250,255,238,212,250,234,217,231,231,240,224,207,228,244,238,247,226,226,244,247,252,248,245,253,251,232,248,236,247,222,255,247,231,237,229,230,245,252,251,222,246,247,234,237,243,248,245,244,251,242,229,224,241,220,245,236,238,243,255,220,210,219,236,204,195,204,166,213,248,244,233,254,230,252,191,189,233,244,239,160,151,86,107,91,32,194,236,246,250,234,239,231,241,247,239,237,202,228,252,243,151,74,22,0,18,19,48,65,39,49,11,17,90,129,60,19,25,64,52,31,14,48,36,114,106,23,25,13,37,29,51,95,34,12,27,93,135,155,124,72,63,63,48,21,38,39,20,64,11,19,39,24,35,21,8,16,11,38,42,32,57,40,32,69,74,142,141,162,157,153,215,176,116,109,155,210,248,216,233,246,244,208,180,104,56,133,206,145,71,139,120,15,21,9,37,38,11,84,106,69,74,48,42,24,4,65,107,44,37,29,75,171,202,122,64,39,133,131,60,39,53,224,225,199,109,29,9,15,10,44,188,192,161,91,8,14,88,252,240,231,252,253,98,60,116,240,235,226,211,101,13,28,145,194,207,211,236,178,95,36,28,1,25,103,223,220,240,124,183,254,241,252,235,251,232,230,235,216,209,133,158,156,155,153,180,153,138,135,123,188,238,179,123,112,81,226,222,207,105,54,29,5,56,158,240,251,229,243,214,116,43,22,0,9,6,32,14,52,158,211,148,54,22,91,204,245,246,185,111,51,23,14,72,188,176,244,140,75,129,115,112,127,125,123,99,52,17,26,42,145,217,255,250,246,244,219,186,154,203,212,214,209,226,210,202,228,237,215,232,184,216,229,249,245,238,245,248,231,239,210,210,237,195,230,233,226,225,213,213,214,228,216,219,229,230,210,213,217,222,215,223,226,204,206,220,237,240,223,183,226,211,234,221,214,215,206,226,209,209,211,218,212,231,212,213,217,223,193,203,203,119,34,6,4,28,4,5,15,30,15,15,28,19,19,3,6,6,13,4,17,29,12,8,0,8,240,239,234,249,238,245,235,226,226,218,229,218,231,242,208,216,239,241,230,242,231,236,215,240,251,241,232,230,238,245,228,208,233,212,233,221,220,225,239,234,238,247,227,235,223,238,229,253,253,240,231,245,239,236,232,230,227,246,220,241,225,235,236,241,232,244,242,232,228,230,218,215,236,249,232,215,239,240,216,235,226,240,224,248,237,215,215,239,230,231,221,226,237,227,224,222,243,224,223,225,226,228,227,239,228,231,223,238,245,220,239,230,225,240,221,224,240,192,252,222,243,217,214,216,206,244,220,245,226,208,242,217,227,221,236,225,248,230,242,233,234,238,230,236,223,242,233,237,231,231,228,230,240,222,239,239,237,216,217,246,208,250,232,218,206,252,232,245,231,236,223,228,248,233,236,247,233,236,236,244,235,229,246,227,234,248,243,237,250,248,226,226,246,227,243,247,245,238,242,235,249,249,252,231,224,243,227,231,239,200,238,235,223,226,239,227,218,235,230,200,227,247,237,248,213,204,234,212,220,227,230,211,230,231,248,252,191,248,241,255,229,214,208,240,231,230,224,232,247,248,239,245,231,252,242,252,238,254,246,209,240,254,251,219,252,230,232,225,213,249,251,222,236,239,218,222,247,250,251,244,235,226,237,234,231,251,237,228,255,241,249,247,250,235,249,224,249,248,234,223,242,248,246,239,222,234,231,237,247,251,252,238,249,221,247,219,240,247,251,236,254,237,249,222,208,208,216,175,188,202,233,216,240,252,231,212,242,237,221,185,195,247,238,254,169,164,128,109,121,70,179,239,243,247,219,218,239,245,225,223,239,221,251,247,237,216,149,150,99,25,9,13,7,8,16,0,26,13,96,126,27,20,13,31,44,20,29,34,71,105,21,21,18,23,39,66,95,45,42,29,71,18,64,155,176,112,46,53,29,37,34,26,14,35,20,40,25,21,32,16,9,24,30,18,27,33,10,29,109,124,184,252,243,238,203,246,160,122,99,173,236,224,254,243,145,86,19,2,7,18,21,15,32,15,27,46,35,47,19,27,59,28,54,99,60,69,37,27,14,0,182,217,61,20,54,97,128,110,107,20,34,183,129,51,29,5,45,69,76,33,11,111,148,54,8,10,20,41,23,30,167,240,247,253,255,253,117,24,81,243,230,239,247,195,91,32,22,165,214,220,235,174,95,63,51,44,2,123,217,200,247,171,95,112,225,235,232,243,238,255,208,232,194,190,107,128,139,156,185,168,170,135,138,146,201,245,165,44,28,55,235,234,242,171,86,24,17,3,91,221,239,245,246,161,76,32,16,23,160,210,139,80,19,12,89,123,68,27,29,128,235,224,212,136,109,43,11,22,119,206,240,187,61,27,0,32,58,49,82,97,106,138,101,134,173,248,237,243,235,210,183,173,184,222,237,216,214,220,198,230,209,223,226,252,236,239,236,250,252,250,222,242,251,241,207,234,224,212,250,201,237,237,205,210,210,221,225,227,215,216,234,208,225,211,230,203,227,206,201,210,233,199,215,217,209,189,221,232,208,231,208,221,220,226,221,203,211,203,210,213,213,224,227,210,219,104,8,14,18,22,12,9,7,6,12,11,25,12,0,11,5,4,25,2,4,7,15,2,12,8,238,225,228,237,209,244,209,215,246,231,222,218,220,242,249,209,231,241,214,237,229,219,232,240,207,231,243,244,221,211,220,217,242,218,216,203,230,239,226,234,232,239,227,230,238,213,248,229,231,242,227,243,223,248,219,246,255,243,229,231,233,203,222,234,236,222,219,231,241,241,232,236,227,246,223,249,223,204,238,238,244,240,216,222,245,239,250,248,234,231,225,246,233,232,239,214,241,217,249,226,222,248,220,232,231,234,255,211,231,245,233,224,231,250,238,252,239,216,209,237,216,226,234,223,245,240,230,239,241,251,233,228,213,246,246,244,242,226,233,234,201,241,246,219,236,229,224,237,248,221,248,234,239,247,232,234,250,246,240,221,242,205,229,245,243,226,233,233,234,203,222,230,247,240,218,219,236,227,237,221,212,227,236,227,240,209,229,242,238,227,233,242,253,203,222,241,216,224,235,241,227,252,251,240,226,243,232,232,217,217,228,229,217,215,228,231,232,226,230,229,235,227,247,252,210,224,225,247,221,215,238,218,225,242,244,236,238,250,232,255,253,244,252,234,229,253,234,237,245,224,222,251,230,254,233,227,236,246,231,249,241,255,237,245,235,252,247,249,247,254,252,243,244,238,216,249,239,242,255,251,235,232,250,249,247,249,252,247,231,228,242,220,247,255,249,233,240,254,248,235,243,232,225,246,239,253,235,239,237,244,253,229,232,237,251,234,239,245,255,219,236,247,236,221,234,190,199,208,206,237,228,211,207,222,203,218,226,243,231,187,219,255,254,247,191,162,123,120,106,47,196,239,222,231,236,224,250,230,215,238,240,227,201,215,232,230,239,254,216,234,248,207,212,199,208,184,141,147,176,190,162,99,65,55,19,25,29,10,77,69,34,46,18,77,59,76,77,46,47,44,40,25,29,38,96,184,147,132,97,68,8,12,31,28,38,17,12,26,41,32,13,19,18,33,6,92,151,179,228,167,236,255,192,169,230,226,150,97,79,209,239,255,252,165,57,1,0,26,6,30,25,19,48,0,156,199,144,43,18,21,37,54,83,151,111,85,35,9,22,56,236,217,92,32,25,103,135,82,66,68,54,72,80,41,60,17,17,22,35,90,209,244,242,178,88,29,14,25,25,153,247,244,246,252,207,128,20,55,233,236,246,192,65,45,9,1,79,249,252,237,181,119,54,14,46,28,48,196,252,193,142,62,24,61,227,246,254,238,242,243,227,237,182,143,136,134,162,154,173,155,167,129,157,127,191,234,173,124,9,19,111,221,229,187,103,50,11,12,33,136,233,236,229,171,88,42,40,167,238,242,250,176,101,14,8,97,104,64,3,38,192,234,249,145,20,22,6,61,145,211,241,203,132,58,45,34,33,22,35,132,165,196,207,173,115,153,234,226,232,198,144,169,233,220,206,221,229,210,214,224,215,227,204,241,244,239,231,186,139,130,133,192,217,214,226,216,221,204,238,222,209,223,229,248,239,225,219,242,228,228,223,198,215,212,214,218,218,233,221,218,214,210,213,217,223,225,224,225,225,208,243,194,223,226,216,210,208,217,215,229,219,231,222,217,190,96,19,0,1,4,20,12,9,20,26,17,32,25,19,13,7,6,24,24,5,10,27,2,23,47,242,215,231,217,236,201,235,214,230,245,241,225,243,232,246,224,214,224,251,236,213,232,231,244,240,246,214,224,204,221,244,220,231,241,234,211,222,225,234,234,218,223,211,240,223,243,228,206,223,229,215,238,233,238,199,236,227,234,208,228,228,211,231,219,206,247,240,230,214,216,226,227,240,200,226,247,249,230,217,235,238,226,224,228,240,235,227,241,224,237,242,208,221,240,227,247,240,228,208,228,244,227,225,212,223,219,237,213,241,238,239,237,253,235,245,222,228,212,239,216,242,252,228,242,239,241,245,244,229,221,240,215,217,229,241,219,230,228,231,253,230,240,229,230,226,233,207,190,247,236,235,226,252,210,235,212,201,211,232,243,218,241,221,241,250,218,212,232,232,243,221,230,214,234,241,227,218,231,231,228,219,230,215,218,236,211,246,224,217,240,240,231,239,238,234,222,241,238,245,234,216,228,232,234,250,242,229,253,215,242,199,225,227,207,212,227,219,234,231,214,221,222,204,231,243,243,235,222,210,223,231,237,232,248,224,248,239,254,246,255,246,252,242,250,253,243,246,231,255,250,238,239,236,246,247,233,254,246,241,222,242,238,250,234,242,250,238,233,231,233,224,244,249,233,241,254,228,233,241,228,242,253,244,246,240,244,234,227,232,250,235,220,255,243,221,249,231,232,246,215,237,251,228,242,246,252,231,250,216,248,236,242,252,238,243,224,252,212,245,247,234,251,222,248,236,198,238,215,219,243,220,170,181,233,232,209,245,237,218,163,217,239,234,242,173,177,98,120,93,42,192,237,247,246,246,233,250,238,251,179,210,231,228,232,216,229,230,240,238,244,226,255,254,247,251,241,250,253,253,252,241,238,255,249,216,135,83,22,67,46,26,49,86,91,61,68,95,55,46,27,50,35,29,42,13,45,90,162,133,98,18,10,50,43,48,42,14,28,24,22,60,8,22,83,216,249,244,235,188,174,246,237,102,91,222,237,157,68,107,233,241,255,172,47,13,21,15,53,23,32,31,25,41,11,86,227,224,141,51,50,83,62,98,151,127,107,29,15,37,97,250,218,56,32,13,69,49,52,31,66,44,96,69,41,31,22,42,20,32,164,245,254,252,220,206,67,67,28,58,194,234,244,220,152,74,26,13,137,239,212,232,188,82,42,66,135,241,238,244,180,96,13,26,36,57,4,113,237,236,165,106,47,12,23,151,241,225,243,254,232,211,193,152,162,130,157,141,149,162,155,152,138,125,159,159,132,153,76,9,76,147,221,255,224,91,37,40,23,36,25,99,213,255,253,120,42,4,18,99,177,225,237,164,80,19,108,165,125,64,25,49,163,127,108,50,26,13,112,221,230,234,225,156,120,70,62,31,51,67,139,123,127,117,65,12,20,171,228,250,183,162,187,234,223,234,226,225,239,224,229,239,236,230,208,142,137,115,112,94,105,66,110,235,226,255,243,237,247,229,218,223,201,198,239,222,218,216,220,229,214,222,223,225,203,210,220,228,227,214,210,234,180,207,224,235,221,214,212,221,224,233,237,217,214,197,225,215,238,213,231,197,229,202,236,231,119,13,11,19,8,23,19,45,19,14,22,25,30,27,16,0,11,14,0,7,26,12,19,1,19,214,234,216,235,225,234,226,227,231,234,210,224,255,243,237,222,245,232,241,229,244,227,214,244,222,227,239,225,224,230,233,249,227,226,205,247,244,245,213,227,235,237,239,218,243,242,231,245,215,242,238,221,205,214,231,220,222,232,239,232,234,217,236,232,228,219,227,221,237,233,247,222,209,236,230,202,236,222,220,231,236,237,235,236,208,249,226,250,238,238,219,212,221,239,232,226,232,228,229,216,229,246,238,222,229,237,229,223,230,201,236,237,213,233,235,222,243,231,245,213,213,234,234,228,219,244,238,252,215,238,232,243,235,234,217,229,215,222,250,236,224,232,237,238,218,224,243,214,228,240,238,244,221,222,239,237,225,219,223,224,233,211,243,234,226,225,230,242,243,228,242,224,233,235,239,212,238,227,230,234,248,205,214,226,229,242,234,222,226,231,231,226,242,241,231,244,235,236,245,232,244,217,238,240,221,228,247,236,220,225,245,216,228,231,221,235,199,237,213,234,217,223,218,222,234,253,226,252,229,243,239,220,237,228,235,226,246,240,230,255,238,255,239,247,229,252,247,253,236,232,239,248,234,247,237,243,252,248,251,236,253,238,215,234,229,251,250,238,255,246,246,242,254,235,240,236,234,252,250,254,250,251,255,229,250,237,229,249,255,232,238,247,252,249,238,241,239,233,245,244,236,238,240,237,237,252,248,249,242,247,250,236,239,243,251,240,239,230,235,245,222,235,237,228,208,211,222,196,189,220,209,201,207,239,242,188,237,248,200,188,217,231,252,248,190,141,127,100,66,36,206,247,249,249,227,229,239,241,220,186,244,243,242,253,219,239,206,228,228,240,249,244,234,253,246,252,252,244,249,252,253,247,255,253,242,201,108,31,46,119,155,137,127,109,73,61,111,56,38,28,51,37,53,69,39,41,57,15,147,239,208,234,219,194,74,6,86,179,191,209,198,210,234,253,249,219,186,145,163,223,243,195,51,88,193,223,160,77,126,232,255,216,94,8,23,5,21,47,23,32,30,43,38,39,25,189,255,238,158,61,94,76,89,120,139,89,21,100,81,73,169,107,58,28,37,34,22,54,22,62,107,80,46,67,50,62,66,15,26,175,229,231,248,242,233,121,35,31,33,98,112,57,19,26,42,10,3,131,249,254,254,241,252,251,252,251,218,197,99,48,0,22,46,51,34,33,208,230,241,208,148,85,56,2,129,218,246,231,220,238,225,182,149,146,139,148,147,149,186,152,142,143,119,150,117,23,4,18,96,223,248,249,243,239,140,56,30,14,15,39,19,62,192,216,202,115,3,17,34,172,199,233,249,120,57,2,70,125,83,61,43,57,47,48,15,41,164,232,251,248,242,251,234,180,104,77,27,44,46,43,47,68,82,85,29,26,121,213,199,173,197,231,232,248,248,237,222,223,225,236,223,251,212,126,96,74,22,47,36,75,75,124,226,230,246,254,242,246,242,235,234,231,209,205,210,220,216,241,215,222,207,221,221,230,228,215,217,193,213,227,218,228,232,196,194,232,215,243,210,220,234,217,209,248,204,226,219,216,212,206,182,209,243,221,234,109,13,23,4,25,0,22,22,6,14,5,10,7,15,15,12,7,25,6,2,17,22,5,10,11,225,236,231,220,232,237,222,241,197,222,199,253,245,228,223,215,227,233,249,214,231,236,226,227,210,224,220,189,214,219,202,216,220,243,218,229,223,234,227,208,240,231,234,212,240,233,238,222,242,220,216,225,230,227,232,214,236,241,216,206,226,245,209,228,210,218,231,245,240,253,224,210,240,238,233,205,235,222,242,233,239,226,226,233,230,245,237,232,190,243,232,228,239,238,244,237,229,236,252,223,222,223,216,220,203,223,236,229,206,230,231,250,225,250,245,234,249,232,245,231,207,236,218,231,221,235,241,240,234,231,239,228,216,238,210,254,226,235,232,239,228,238,227,233,205,204,235,214,243,240,235,235,222,243,238,228,227,243,220,228,228,213,203,216,215,230,214,216,225,229,243,235,213,235,217,236,248,223,238,225,238,206,245,249,241,237,237,229,246,225,244,239,238,229,235,231,244,248,236,241,241,245,253,252,229,241,245,226,247,239,223,222,226,210,209,225,219,229,205,216,207,226,234,221,213,236,241,248,238,235,221,238,217,236,236,229,231,244,240,239,243,235,219,232,239,244,253,246,235,234,239,249,245,241,250,228,252,240,237,245,255,228,226,241,244,234,252,234,235,241,250,236,245,240,231,246,235,253,254,240,252,244,249,229,249,244,230,230,239,233,243,232,210,242,255,233,240,246,253,254,234,225,250,221,238,239,255,246,231,246,253,244,232,242,251,255,233,255,228,234,237,255,233,242,207,238,205,179,215,228,210,218,251,249,194,198,231,214,228,195,214,252,252,231,170,136,112,104,94,35,186,233,249,241,214,231,244,250,217,195,245,250,246,228,250,235,208,215,183,222,236,144,148,223,231,250,232,198,246,247,253,255,224,248,219,179,57,5,25,112,219,171,146,126,71,68,112,57,10,24,59,29,44,54,25,14,52,10,82,242,248,235,253,210,157,27,133,229,253,242,243,235,252,244,244,215,120,157,140,244,254,132,115,101,163,206,176,106,166,251,248,180,40,31,27,20,35,46,29,10,76,47,34,19,47,123,237,234,184,80,36,64,80,134,143,35,19,138,79,72,89,22,91,29,8,16,4,39,32,100,126,78,66,66,52,54,74,35,37,192,252,252,255,191,143,87,18,5,27,18,42,49,50,62,29,27,27,86,215,226,226,242,247,251,240,253,150,47,2,8,29,27,46,17,18,191,236,249,241,220,171,161,171,95,140,231,252,231,243,243,212,164,171,157,139,126,165,153,155,130,126,138,146,152,165,135,201,237,210,239,252,246,246,254,203,123,31,38,25,5,14,38,45,106,210,219,230,233,238,236,253,241,240,188,87,27,22,13,39,65,14,30,29,24,185,234,246,247,241,241,238,247,210,162,123,61,23,39,35,17,36,18,134,229,143,39,72,128,155,190,222,241,242,247,244,245,251,242,233,248,217,233,212,129,104,30,1,18,11,41,25,90,160,153,189,220,235,244,253,244,230,213,227,234,241,218,219,231,230,227,223,224,236,226,212,238,227,230,189,212,214,218,243,216,216,201,192,221,228,206,221,211,204,198,212,214,213,196,198,198,212,203,225,221,210,104,1,2,5,0,13,20,0,7,17,13,20,26,12,10,1,22,0,14,3,42,34,8,14,20,252,240,228,211,203,239,227,225,239,235,236,243,234,247,215,235,219,206,232,241,226,239,242,237,232,235,225,215,231,234,222,220,241,228,219,214,235,225,231,230,232,239,197,237,243,236,220,226,227,237,205,242,243,238,222,230,240,197,229,230,248,228,240,234,212,251,227,226,230,244,247,238,217,229,234,244,242,240,218,236,224,224,251,213,227,227,224,238,203,219,242,223,229,232,251,209,225,240,206,211,246,235,208,221,233,221,242,227,246,234,223,228,245,245,220,227,219,254,218,242,222,207,236,236,240,232,220,227,204,250,219,239,235,216,209,212,237,247,248,218,224,221,240,253,224,217,228,213,240,233,219,224,239,210,217,228,204,227,237,213,226,234,216,212,224,219,244,242,234,231,220,235,239,229,228,230,210,235,213,206,236,233,221,237,229,219,214,227,232,207,224,219,223,228,245,217,252,236,215,236,232,243,248,245,222,234,221,245,254,221,201,236,211,220,237,219,237,209,217,223,236,230,216,238,220,232,236,240,213,229,238,238,243,254,226,239,232,243,255,255,247,240,255,247,252,226,251,234,234,239,210,255,239,226,225,251,243,237,234,246,229,228,231,245,249,239,230,236,212,254,232,250,243,254,244,251,247,241,227,224,227,228,247,236,217,251,237,240,242,230,237,230,242,240,230,226,226,236,222,223,246,240,249,235,243,246,250,227,249,253,226,249,247,213,246,250,235,244,246,230,205,242,229,249,216,207,219,241,240,246,247,196,173,194,213,218,249,244,199,210,224,252,218,247,197,158,109,122,92,32,186,243,251,254,222,239,229,240,229,180,229,246,244,253,207,229,201,150,122,231,224,160,212,221,244,243,234,223,242,255,244,216,191,211,144,132,149,65,72,156,221,163,126,85,42,58,86,57,33,39,70,18,37,53,64,43,73,32,98,230,201,187,244,221,183,51,96,238,240,246,234,238,250,207,210,191,150,176,188,254,202,150,149,191,197,195,169,131,211,249,228,152,30,18,21,9,35,18,134,212,197,172,108,54,7,128,245,252,191,94,18,27,71,91,73,27,31,97,67,81,65,45,34,44,3,48,60,64,30,48,25,61,48,90,27,44,13,34,212,255,239,187,84,34,5,9,59,11,32,25,54,47,30,45,51,29,54,28,91,200,239,230,237,204,165,70,34,9,27,52,28,61,35,60,169,246,244,239,237,253,174,191,237,172,138,240,240,243,233,227,196,161,154,149,149,160,175,171,161,154,135,110,121,179,238,218,251,248,249,241,236,246,249,253,249,219,105,36,22,21,14,24,27,10,72,208,240,239,230,244,250,250,246,166,130,24,23,17,23,25,24,30,14,119,229,228,233,221,255,250,250,196,151,115,44,16,5,20,16,40,37,16,150,212,231,189,99,89,150,214,234,236,248,242,248,247,232,228,227,221,225,248,186,134,66,43,16,10,77,102,58,36,5,13,0,16,78,187,193,218,230,241,225,212,195,220,223,212,215,233,230,212,234,242,240,212,200,201,230,201,228,204,213,195,228,205,215,230,235,210,218,215,225,230,225,223,225,211,231,220,237,222,219,207,226,81,15,10,0,14,11,0,10,18,10,22,8,11,10,22,7,16,6,3,0,14,8,10,11,5,228,214,223,243,196,212,205,241,243,212,249,223,226,239,243,226,229,236,200,220,229,217,232,223,231,239,194,229,217,194,229,233,196,233,210,218,232,247,211,202,213,225,222,220,215,182,241,214,243,229,227,234,226,220,238,202,232,237,211,239,245,213,225,228,241,237,233,238,246,233,225,221,207,227,231,249,226,253,228,210,215,239,215,227,227,227,220,242,225,230,249,215,224,241,235,216,228,215,224,214,215,240,231,192,219,237,230,233,248,244,247,223,206,216,218,227,229,234,217,228,238,245,249,245,235,246,228,221,204,232,241,223,234,214,248,211,230,231,220,229,223,240,230,205,223,220,219,220,248,229,210,231,202,233,233,216,238,235,225,222,214,233,226,219,203,216,222,208,221,213,233,212,225,208,228,201,191,237,228,222,215,216,202,211,212,233,209,220,221,227,235,248,239,242,234,225,236,219,235,253,240,231,211,255,235,225,224,237,223,207,236,236,232,229,216,208,225,231,187,208,223,243,226,231,231,233,202,228,234,215,225,236,230,238,226,249,247,232,246,248,222,236,245,247,248,228,236,240,236,249,245,254,221,240,223,245,230,252,252,246,243,235,211,246,247,249,229,245,233,238,246,229,246,240,253,215,232,225,248,221,253,238,247,255,240,231,246,223,231,242,237,218,232,252,234,255,225,241,250,246,240,246,235,236,241,255,255,238,219,235,242,246,225,249,244,241,231,248,246,227,245,206,251,232,226,209,220,234,228,209,187,183,212,253,221,245,232,227,202,207,208,237,220,219,225,162,116,113,95,45,194,244,244,233,219,237,239,249,201,188,255,233,231,204,182,206,198,177,163,187,250,191,225,251,250,254,247,205,203,188,208,223,151,156,161,189,202,125,169,157,197,137,168,110,49,72,87,94,41,49,46,46,38,59,37,20,33,17,78,190,149,154,205,183,190,133,92,191,227,252,212,255,219,216,253,210,181,210,200,210,177,182,197,191,214,204,157,171,243,251,235,119,24,6,4,41,19,154,249,237,241,252,151,42,10,81,255,233,149,91,31,10,42,58,76,49,47,93,65,64,65,33,9,41,52,64,36,47,27,19,20,44,66,51,55,44,96,227,236,237,143,71,9,10,29,31,22,16,30,11,51,51,13,35,27,47,53,37,32,13,80,114,66,61,64,29,62,77,99,94,90,87,132,123,208,198,191,152,162,142,113,98,134,97,90,155,233,242,244,190,166,161,145,145,124,145,138,159,155,145,153,123,152,178,175,127,212,230,206,193,237,233,242,247,246,238,141,28,2,22,40,43,52,36,15,3,160,209,246,255,251,233,196,119,79,21,3,43,27,41,23,9,27,51,142,191,224,222,244,255,239,158,83,65,42,12,15,28,73,57,40,15,73,167,228,207,165,193,215,225,237,242,203,165,129,125,150,210,242,232,238,206,134,115,41,38,11,29,99,79,92,61,36,33,45,20,22,20,110,213,238,236,223,217,232,223,216,203,211,228,230,219,225,218,238,225,226,218,238,210,213,220,212,231,227,207,205,212,208,206,246,231,183,204,221,216,222,220,213,244,226,220,237,213,206,110,0,7,1,25,5,20,17,34,17,5,33,0,2,4,0,4,18,8,13,39,11,23,18,16,214,228,237,225,224,218,225,204,230,239,226,239,223,208,203,204,229,223,226,202,235,216,214,213,235,208,200,208,216,228,214,206,214,222,242,210,221,229,217,221,210,226,231,209,208,217,232,248,239,229,206,194,250,227,214,228,219,184,244,221,245,240,227,222,215,214,234,215,236,225,218,232,233,223,245,225,232,202,211,219,218,212,253,238,242,233,223,220,219,226,226,207,225,222,229,239,226,237,232,240,224,246,217,223,236,242,214,228,243,228,250,234,215,232,250,235,235,233,242,234,247,243,226,240,223,225,242,239,226,246,209,227,247,255,246,248,238,239,233,240,236,231,216,223,220,226,243,218,220,218,219,236,215,195,224,206,238,231,217,237,206,201,213,238,222,223,221,228,202,232,214,230,225,232,209,231,218,221,207,227,221,242,220,233,212,210,233,230,235,224,214,212,229,212,247,246,246,232,197,238,232,241,240,227,243,236,218,215,217,223,226,223,216,231,217,225,219,244,222,235,221,244,224,229,216,231,234,224,227,215,220,231,230,229,237,246,246,252,242,250,248,248,249,242,244,255,231,252,243,237,253,241,244,215,246,242,245,243,241,243,250,242,249,251,240,249,247,241,235,248,245,229,236,235,248,239,250,234,242,249,243,235,228,252,249,255,241,239,253,247,242,239,249,244,220,243,243,241,250,241,229,224,254,217,244,255,252,255,249,243,246,223,233,236,250,237,243,249,236,246,238,236,241,216,225,214,216,184,197,229,210,192,252,251,222,229,253,233,222,203,223,249,230,244,203,173,124,135,78,70,193,239,253,244,228,233,253,254,207,200,240,233,242,214,198,216,204,197,176,199,253,219,246,240,216,241,219,159,145,126,180,183,207,219,205,229,187,180,159,137,195,132,142,137,62,89,96,92,17,39,56,17,58,44,53,38,27,3,135,241,170,168,219,175,163,128,105,158,219,255,221,249,203,236,239,239,201,128,156,255,115,188,198,184,228,154,147,193,221,235,220,115,29,5,24,30,135,244,241,235,229,139,80,39,8,51,250,218,159,118,10,17,64,106,54,67,69,95,103,69,38,38,35,46,37,56,22,34,49,37,38,52,44,58,39,120,229,241,249,111,13,7,25,30,34,29,40,28,64,61,72,91,90,92,82,78,97,70,84,72,33,37,23,38,28,35,53,38,54,44,49,75,61,71,31,16,13,17,25,25,34,28,30,58,3,93,244,234,220,191,126,151,133,138,128,138,119,117,141,154,135,148,144,128,71,17,14,4,16,13,27,9,74,93,133,155,126,67,56,73,52,54,47,66,26,30,27,40,148,211,208,185,107,49,21,14,5,30,30,22,11,46,44,35,50,14,18,54,195,213,249,181,85,36,0,5,98,223,190,136,49,30,39,24,18,19,100,215,242,237,249,214,139,72,45,30,56,155,208,239,245,183,97,88,20,40,91,72,89,88,54,58,27,36,72,33,46,58,27,62,190,226,221,226,206,212,217,203,225,221,221,217,234,207,198,229,228,221,215,239,215,228,210,233,237,209,237,219,199,200,230,235,221,220,228,219,202,210,215,207,221,230,226,197,215,116,0,3,18,21,9,16,9,12,12,8,23,0,10,8,15,4,25,14,12,0,11,3,27,27,217,235,226,231,241,222,221,229,210,230,242,233,240,231,241,234,249,230,225,245,227,199,220,241,237,201,228,227,204,238,221,212,223,231,241,217,233,222,213,222,204,198,247,197,230,207,225,219,225,208,204,227,235,227,195,246,218,180,225,228,232,237,235,229,242,207,222,219,240,213,216,245,241,229,232,225,249,229,237,217,240,224,241,236,232,226,249,227,209,251,232,219,226,228,229,232,223,225,214,228,223,224,238,234,218,239,229,223,226,236,210,210,217,219,221,235,225,222,233,241,237,238,237,231,215,244,247,246,245,224,247,238,226,232,246,220,212,223,226,211,231,228,201,220,216,223,222,225,237,234,208,222,223,216,217,218,223,212,221,207,225,235,235,243,231,220,221,210,217,203,221,226,227,215,234,220,226,229,217,197,213,235,213,217,236,214,237,224,242,224,211,228,208,231,217,218,240,228,231,233,233,218,225,240,233,226,223,247,209,223,218,235,224,216,219,235,237,218,227,228,235,239,238,235,215,238,246,223,212,228,225,233,219,237,243,253,225,220,235,251,250,232,253,246,249,244,223,235,253,251,244,245,255,231,245,237,228,246,223,236,228,251,253,252,236,252,228,246,226,237,251,212,219,240,225,244,255,239,230,225,238,246,242,239,242,238,251,243,236,255,226,251,219,243,246,237,237,249,244,247,237,251,222,255,234,253,247,247,244,255,239,252,242,234,227,240,229,234,237,235,228,203,233,227,200,198,211,200,249,211,222,226,241,222,172,209,244,236,207,215,225,244,247,238,183,156,127,92,79,57,203,247,250,245,229,228,254,248,202,205,255,233,254,234,198,217,240,228,182,222,252,232,221,200,202,221,134,132,139,199,230,232,226,244,236,192,150,166,123,136,166,86,190,131,69,81,92,71,17,44,63,57,54,22,50,37,46,27,162,243,223,246,233,187,196,138,78,84,186,221,251,193,178,244,242,206,158,131,215,209,124,166,193,173,203,149,138,183,248,246,242,146,17,0,33,3,141,245,245,231,85,0,0,14,21,127,239,232,171,76,8,32,37,52,57,32,65,51,51,23,20,25,41,46,48,10,38,49,40,24,35,22,38,49,32,152,198,196,70,17,14,38,47,53,45,64,115,135,113,130,127,104,126,97,105,82,33,83,66,74,37,60,52,42,67,53,36,71,65,67,62,75,63,81,67,57,52,55,57,86,64,63,101,66,38,119,224,222,198,174,141,152,147,170,124,134,161,133,155,126,138,129,148,142,77,9,10,36,65,29,23,17,28,15,38,49,44,33,22,30,10,47,53,56,75,38,72,31,32,57,26,37,36,69,64,42,32,26,43,40,18,37,17,24,38,15,27,49,43,121,227,180,153,43,31,28,55,121,209,195,140,70,39,31,28,8,63,158,246,226,236,185,133,72,49,27,20,160,242,238,222,121,103,22,39,123,168,127,67,32,40,18,19,16,46,11,29,24,44,19,148,196,228,222,233,215,252,210,231,223,222,221,210,219,212,226,223,219,234,227,222,211,217,206,223,225,199,242,212,223,217,216,240,205,224,223,224,222,212,228,225,212,213,200,225,120,5,3,7,3,26,20,21,20,2,11,13,8,21,5,5,15,1,14,8,9,25,17,29,9,217,240,229,196,254,219,218,224,212,225,231,219,226,233,224,221,233,226,214,197,242,233,246,216,178,218,206,214,212,236,216,189,202,239,227,240,199,215,185,218,215,185,226,235,231,215,221,232,197,249,239,229,216,208,225,207,238,218,221,221,231,232,220,216,242,211,226,225,242,236,222,205,243,214,208,217,231,228,227,228,229,229,241,223,248,242,210,226,245,232,235,219,234,235,225,223,239,224,206,235,220,219,224,222,232,233,230,225,245,236,229,226,244,243,233,221,227,234,217,239,247,220,232,207,218,232,251,247,230,239,240,233,239,239,212,203,238,231,216,249,220,207,227,221,241,229,242,231,223,232,221,219,232,218,210,200,231,232,245,233,242,213,220,213,208,244,202,232,228,208,230,209,219,216,180,223,214,219,218,206,233,199,214,229,202,224,219,237,207,235,224,230,213,230,227,237,228,230,231,230,227,230,209,233,213,252,232,245,243,229,234,253,228,227,238,215,233,224,215,241,250,243,206,233,222,226,220,218,209,246,244,232,222,237,235,240,226,236,237,240,243,222,220,250,255,234,224,237,245,255,247,236,237,251,252,253,236,246,250,244,231,236,232,241,223,240,221,241,237,250,242,231,252,244,231,235,254,255,230,243,254,236,231,249,253,243,253,240,252,255,227,253,249,243,245,245,249,242,253,226,254,251,221,254,247,240,255,248,236,247,242,249,235,236,239,229,217,242,231,233,216,212,221,212,206,213,217,223,246,212,187,194,222,230,190,193,239,225,230,235,239,225,223,251,190,153,114,98,39,69,184,235,255,243,236,249,235,246,193,216,245,224,242,253,233,226,249,255,211,170,223,183,147,101,172,200,210,232,197,212,251,243,233,238,237,165,103,164,136,171,192,114,197,120,97,67,69,113,21,50,55,39,53,48,41,34,33,31,154,250,200,213,248,228,217,230,142,39,104,187,214,174,147,237,218,169,125,165,255,214,80,190,157,149,200,125,118,205,230,249,253,158,36,7,20,0,119,233,225,209,66,10,17,2,117,243,255,248,165,75,42,8,37,102,80,20,68,56,70,45,18,55,37,56,48,45,47,40,25,13,24,29,80,43,60,107,95,90,55,77,105,111,104,88,104,107,119,81,75,83,80,43,64,49,61,63,71,62,68,93,67,88,117,101,139,147,124,151,166,150,135,123,130,156,148,142,143,135,138,106,113,80,83,79,79,99,201,207,144,124,135,139,137,136,148,146,125,153,162,141,130,117,155,123,95,29,54,49,53,66,61,73,30,41,60,50,61,42,33,54,24,65,37,29,57,41,47,46,25,43,74,42,57,63,34,47,84,54,49,53,59,52,38,49,45,21,32,52,24,6,54,173,158,160,40,31,36,44,185,232,140,90,36,14,57,36,48,195,222,242,250,232,154,82,46,21,101,239,248,229,170,94,50,109,195,178,157,78,59,26,31,7,15,34,27,2,54,65,45,22,61,201,205,226,212,233,234,234,230,217,208,209,227,225,236,228,229,211,214,230,203,197,218,234,233,206,239,231,198,227,220,217,216,202,226,221,222,241,238,203,211,220,230,228,226,103,7,4,18,8,21,11,14,4,7,6,8,12,6,10,6,26,14,15,15,21,3,9,13,20,195,216,220,233,227,217,233,209,243,242,218,208,246,229,239,224,209,245,216,216,248,232,235,216,217,219,232,240,219,219,208,238,236,216,238,221,198,227,222,220,227,229,235,226,227,217,226,237,220,183,202,214,211,200,238,203,243,221,242,216,188,200,218,222,225,244,249,207,224,207,222,244,206,237,229,217,241,229,237,197,207,228,203,227,220,220,249,205,230,250,232,227,228,243,233,228,225,235,234,226,197,218,240,213,229,234,219,216,219,221,224,201,223,213,224,217,218,217,240,223,221,209,237,210,225,230,248,237,243,233,240,245,225,243,230,215,206,217,226,225,227,210,241,228,225,243,218,213,228,222,243,238,211,216,224,223,227,220,215,227,228,209,223,199,216,227,211,203,220,205,232,229,211,229,218,215,198,213,208,212,191,228,230,214,210,226,220,234,233,223,222,211,223,241,243,210,214,252,236,220,206,234,226,211,243,235,236,248,231,238,251,222,217,246,247,227,253,222,224,226,246,250,233,236,219,223,242,244,214,225,247,228,227,237,246,251,221,255,236,231,241,232,240,240,244,246,247,226,230,240,229,246,225,248,249,247,234,241,227,231,234,238,240,236,243,253,224,249,255,250,228,204,249,247,249,247,254,234,230,243,230,251,255,237,236,252,246,239,253,242,232,242,255,235,230,255,249,249,246,243,223,227,255,253,234,235,250,252,253,239,232,255,238,249,249,255,207,219,229,243,232,201,213,210,215,220,178,197,238,212,195,248,234,255,242,225,238,211,230,214,222,224,207,235,192,157,149,117,82,53,196,248,222,229,206,225,255,222,202,220,241,224,239,250,199,226,228,248,133,123,155,149,185,192,238,247,221,247,224,252,249,252,254,255,221,110,129,170,178,189,213,142,154,70,38,59,81,89,13,37,60,34,29,73,67,72,14,14,163,248,181,201,235,227,237,252,120,57,106,208,228,130,147,160,121,122,148,208,244,148,111,216,192,180,173,96,172,206,252,255,237,178,73,5,11,9,34,212,236,253,207,156,179,232,254,244,235,174,102,25,12,41,38,70,68,36,38,73,62,42,31,28,41,28,40,20,29,43,56,44,68,70,77,107,115,92,89,105,115,109,78,46,66,60,44,69,109,69,64,83,69,100,108,127,128,134,140,126,141,145,141,135,144,139,97,100,76,50,63,52,35,82,31,37,39,46,32,51,49,27,51,15,6,31,53,59,133,155,163,116,122,144,143,145,176,161,139,150,142,141,157,150,156,148,90,18,40,22,17,42,44,36,38,43,37,53,26,78,46,60,33,90,54,59,28,53,42,55,58,56,37,29,47,48,57,51,36,95,73,74,87,70,63,29,59,67,26,46,35,42,33,17,142,142,81,40,53,196,242,230,160,116,49,26,37,30,132,229,247,253,249,223,130,109,80,27,35,131,188,154,108,41,85,220,223,194,108,86,39,35,113,150,113,96,45,64,42,29,21,1,97,179,200,232,236,218,225,229,217,237,204,224,228,231,212,231,200,208,212,212,206,215,227,216,234,206,233,227,218,238,216,225,246,234,238,217,206,191,231,233,213,205,241,217,206,125,21,8,4,25,14,3,17,26,31,21,0,13,6,5,22,7,29,1,11,4,11,12,25,10,243,214,239,241,225,239,230,224,225,219,227,229,225,222,241,237,238,231,223,229,244,222,244,222,210,229,216,223,211,212,213,216,229,220,213,191,199,224,228,227,209,214,210,206,214,209,239,196,223,226,219,218,195,231,219,204,189,226,220,209,243,234,212,219,225,216,220,214,226,235,232,232,240,249,237,219,225,206,241,236,227,230,237,240,224,231,232,220,239,224,206,230,246,218,206,227,245,239,227,226,231,223,235,223,220,234,210,232,239,228,226,229,196,226,237,241,223,219,243,233,240,229,243,231,205,212,241,231,220,234,240,231,228,243,249,234,217,209,221,218,220,219,245,228,216,212,235,238,226,234,223,228,199,210,224,229,223,212,199,196,215,217,212,225,214,223,204,215,231,208,216,216,222,192,223,237,221,216,221,223,232,204,216,217,211,227,226,226,221,220,209,217,227,235,221,225,217,234,228,225,230,240,243,225,232,232,247,238,229,224,219,243,226,228,238,244,219,224,222,240,218,251,210,234,233,241,204,224,217,240,229,221,193,234,242,234,231,221,253,225,242,247,255,242,246,246,248,234,243,249,253,237,232,249,243,247,241,236,236,246,243,245,242,232,250,249,243,213,228,234,226,246,249,250,237,252,237,240,246,247,213,252,230,253,238,248,243,236,246,226,248,242,216,234,229,248,239,243,239,252,255,240,247,244,239,236,252,247,232,249,236,243,246,241,232,233,240,226,218,234,237,226,229,197,212,209,166,200,242,221,222,240,236,246,202,211,242,229,228,208,215,243,226,251,212,166,154,113,76,42,197,234,246,255,196,225,238,241,178,208,252,240,244,253,204,150,169,151,104,90,149,216,226,225,247,251,225,232,185,237,237,215,249,229,205,108,131,178,167,190,187,154,140,68,51,33,21,98,29,58,52,32,26,64,33,43,15,94,207,247,191,210,242,209,203,238,135,11,100,197,216,142,132,127,119,143,176,207,174,111,170,213,222,240,188,79,179,246,251,239,240,226,141,3,0,12,4,85,232,240,252,255,255,243,228,235,96,45,9,5,18,48,22,22,43,45,45,37,59,49,34,21,49,50,61,67,70,70,87,100,119,106,100,73,41,71,32,52,57,53,40,55,75,104,91,116,134,127,150,131,145,143,118,120,96,51,62,36,58,51,45,33,28,21,43,25,47,39,31,49,13,14,43,32,31,9,46,55,20,31,37,17,21,1,19,4,19,75,129,154,144,146,160,165,161,174,159,174,147,152,157,180,173,111,46,28,46,15,2,26,24,29,8,14,11,26,26,22,16,15,31,49,33,51,32,44,69,65,88,43,50,54,51,73,58,75,50,52,68,46,49,30,58,61,87,84,73,85,84,85,62,52,40,79,44,55,179,239,239,246,128,127,70,21,38,24,63,199,238,236,229,142,93,89,77,18,26,13,18,5,32,15,104,217,232,142,105,38,71,199,229,236,229,173,121,85,61,11,30,8,64,176,224,218,236,226,216,241,227,223,221,225,237,233,228,217,211,218,237,226,230,227,230,238,201,222,229,204,207,246,218,223,231,231,205,241,226,230,218,234,218,238,232,230,215,114,12,18,5,6,20,0,38,23,25,16,2,1,16,5,4,19,43,24,10,20,17,19,14,0,231,208,217,219,223,217,235,250,220,239,224,235,227,226,227,233,235,235,211,225,219,208,246,246,235,205,219,226,223,221,240,240,220,217,199,196,187,210,201,207,214,220,221,223,242,217,190,219,215,232,234,214,233,201,212,209,217,221,233,230,232,211,178,207,209,221,235,227,219,211,224,211,206,234,219,231,217,221,219,217,228,235,229,241,227,246,242,227,218,231,207,227,234,222,215,212,239,226,221,243,226,243,242,206,231,230,220,243,220,211,204,241,221,242,212,217,226,210,244,236,231,232,222,235,240,219,224,199,235,220,238,238,230,208,208,225,226,228,227,227,220,214,210,239,219,216,248,231,247,235,233,241,218,235,221,209,226,221,220,204,235,235,217,210,212,219,201,224,224,203,201,212,218,225,190,220,201,195,213,228,227,215,227,216,241,232,230,216,237,212,208,233,191,224,231,223,244,229,225,215,222,214,231,234,241,236,232,225,241,237,245,242,240,234,243,230,231,247,244,245,219,228,227,235,248,237,246,215,226,228,216,222,239,243,226,241,193,237,235,241,243,232,238,244,255,222,214,255,245,251,249,240,226,252,228,247,253,233,241,226,216,241,219,235,246,237,228,216,237,236,241,218,239,255,231,255,235,239,249,248,243,236,254,253,230,249,243,253,246,225,242,245,246,238,250,236,229,235,241,254,230,240,239,227,234,255,252,250,233,246,219,242,248,255,233,243,231,246,239,232,212,233,208,237,213,194,228,227,255,177,225,228,228,201,211,240,255,204,199,207,210,245,227,255,206,160,153,97,53,54,229,246,228,241,212,242,226,236,176,227,254,247,253,250,173,119,171,192,177,147,169,249,243,234,233,252,223,228,189,202,228,239,229,224,180,129,144,174,191,188,210,167,150,142,83,41,30,120,54,84,68,45,40,27,43,41,149,217,227,225,191,192,224,227,224,243,99,28,58,140,196,193,235,185,164,202,190,207,163,117,188,226,201,244,169,82,171,247,254,239,237,243,191,129,70,9,17,25,45,140,176,221,210,158,136,46,39,6,49,78,51,61,31,62,79,79,50,81,65,78,67,94,100,88,85,95,65,89,63,76,59,47,43,76,45,70,58,110,122,114,147,167,127,133,128,107,67,75,47,17,40,37,15,14,26,33,17,20,26,22,43,22,10,32,18,44,35,15,36,22,23,18,14,53,45,17,20,43,17,51,22,49,28,27,18,33,96,122,141,149,151,157,139,150,146,154,137,163,138,159,127,165,154,128,76,12,49,46,39,31,31,17,7,43,14,29,51,38,21,19,33,34,22,14,10,41,10,33,31,64,31,44,53,87,90,86,79,102,83,61,71,77,60,55,55,52,51,63,70,65,54,78,57,61,54,59,172,235,240,191,147,55,50,30,36,44,14,33,137,194,148,104,88,57,92,72,55,41,30,0,35,116,217,255,227,134,90,57,27,76,190,228,226,226,145,111,68,34,41,15,66,198,225,215,204,218,229,236,233,213,228,212,229,221,211,209,213,229,244,231,230,227,245,185,223,215,222,230,204,230,214,242,209,206,244,218,231,228,194,222,209,237,205,227,223,119,0,0,30,13,17,8,7,15,14,2,24,0,8,8,0,24,15,6,18,2,7,26,3,6,205,204,216,226,228,245,228,243,211,216,223,234,216,230,213,219,231,223,227,232,226,227,241,229,217,228,213,210,239,197,238,214,225,211,215,227,218,222,192,229,224,192,211,206,234,228,191,217,231,194,212,234,208,236,221,239,220,215,207,228,215,205,220,212,214,236,229,206,202,199,215,230,227,210,245,229,219,223,242,213,204,224,218,244,193,232,230,213,211,244,233,225,237,213,225,241,215,219,236,239,222,236,227,214,251,212,234,213,218,243,207,220,201,211,218,204,212,229,213,229,241,230,240,228,238,236,204,239,236,237,255,244,214,229,230,206,233,218,215,218,219,204,239,235,226,225,235,235,232,229,215,224,220,206,212,220,217,227,203,215,236,230,209,231,209,215,229,218,228,227,195,216,203,213,204,224,237,232,224,217,203,230,226,223,224,232,228,220,235,225,208,219,235,218,219,223,243,229,227,231,217,230,218,226,227,230,232,229,233,219,245,244,232,231,235,226,226,250,238,205,225,225,226,226,218,212,225,208,203,223,237,226,196,236,216,241,234,230,238,234,214,240,239,251,230,239,247,246,242,249,237,239,229,239,235,236,251,240,229,219,237,238,236,245,255,240,209,250,247,247,233,238,239,247,230,239,226,246,239,247,250,251,246,231,217,241,246,253,254,254,247,251,226,245,253,243,233,221,223,246,240,246,240,224,254,242,234,254,244,247,246,245,239,246,248,240,230,245,217,230,245,239,203,222,219,222,206,251,174,79,129,207,233,245,199,230,233,212,210,240,218,218,196,241,181,152,135,81,53,53,229,255,234,235,215,240,245,230,166,223,212,184,154,194,198,191,233,247,243,185,157,245,239,241,231,253,207,189,162,188,240,245,251,215,198,180,165,166,198,144,209,120,157,173,146,68,51,130,58,98,68,27,34,33,32,77,202,251,219,219,175,203,255,219,246,243,126,72,56,90,182,201,251,206,172,132,166,231,188,156,192,188,153,224,113,69,198,208,250,247,239,241,218,235,203,163,85,113,53,2,11,14,7,9,5,21,50,87,55,111,111,118,126,110,120,113,103,117,105,84,63,74,62,75,49,79,57,54,53,37,49,104,113,110,119,160,130,127,115,98,87,52,49,29,34,27,49,30,22,36,17,1,9,20,24,19,16,9,17,45,27,15,20,22,42,27,32,46,42,38,38,23,50,39,49,17,13,9,18,14,30,43,35,41,59,85,214,172,162,175,161,148,151,160,160,149,154,145,136,128,142,146,151,66,43,26,30,48,74,61,31,22,23,25,25,40,47,44,5,18,39,11,45,49,12,7,22,7,11,14,41,19,7,19,16,40,73,79,63,61,74,100,96,77,87,80,93,76,53,54,42,62,54,56,88,47,164,193,191,171,85,56,51,27,29,8,30,36,17,45,50,115,156,80,88,99,101,165,204,214,251,251,243,240,247,179,107,32,20,18,29,61,194,223,188,117,89,35,45,24,94,216,195,230,223,221,205,213,229,219,202,209,229,230,217,216,240,251,231,215,241,226,234,220,230,238,209,235,235,234,206,227,229,201,224,225,210,221,229,216,210,206,216,233,202,101,25,30,0,0,5,7,5,0,18,13,20,19,14,21,14,7,9,25,17,1,26,12,4,9,219,206,230,226,219,206,216,212,219,213,206,232,230,211,204,208,230,220,246,229,209,211,232,218,219,223,201,219,217,215,215,215,220,209,216,189,218,224,215,208,226,219,200,215,211,207,210,205,217,212,218,217,224,239,213,204,205,210,210,190,209,208,212,225,224,218,197,201,217,217,207,225,218,213,204,204,214,239,237,235,205,237,240,221,214,227,233,208,214,223,244,222,227,214,240,236,232,227,228,212,236,221,238,205,219,216,196,224,229,218,237,233,232,207,237,221,228,211,239,221,225,227,235,213,221,215,205,241,220,225,235,245,250,244,232,235,211,213,237,221,232,229,220,245,210,211,214,209,237,210,220,221,221,213,210,232,218,210,233,227,195,234,226,242,218,199,209,234,209,225,231,229,230,232,190,239,231,244,227,222,232,238,226,208,222,220,201,228,220,228,224,215,213,211,223,207,239,222,213,221,203,234,220,223,239,215,228,214,226,203,225,224,237,228,252,210,218,224,237,241,240,233,251,233,210,217,229,232,220,224,229,238,232,234,235,241,243,239,236,249,254,233,215,213,221,236,198,245,234,231,255,240,227,254,245,246,228,243,218,217,235,251,228,219,255,219,227,246,241,239,209,226,242,249,248,252,226,221,246,255,250,233,254,240,247,250,224,244,229,233,249,252,239,253,253,255,245,245,228,239,234,253,248,243,249,249,238,221,240,209,255,228,251,246,230,248,204,226,243,228,217,255,236,207,213,240,231,191,107,22,98,228,214,232,207,237,254,201,186,241,218,234,223,255,191,144,152,114,51,30,227,239,240,244,243,245,242,210,170,186,188,181,208,238,251,204,233,232,251,186,163,214,243,242,235,252,187,165,218,202,227,235,248,182,167,201,168,169,204,157,191,137,181,177,139,85,31,132,71,90,81,58,71,37,20,71,230,231,204,196,164,224,243,206,220,242,155,157,99,76,155,225,249,160,104,97,190,170,96,144,211,185,139,181,69,75,221,219,237,213,238,229,241,252,253,222,179,195,100,56,54,17,8,15,44,36,46,57,30,13,46,41,25,68,44,50,61,60,97,61,79,68,51,78,79,73,112,119,118,127,150,131,131,111,89,49,49,35,29,26,48,23,4,26,14,24,28,28,35,7,15,13,16,27,14,18,15,32,31,34,41,23,32,43,34,39,39,34,35,38,45,44,61,80,33,19,12,3,23,31,34,32,58,82,82,169,211,159,161,159,141,181,151,126,166,151,161,169,107,134,125,190,132,49,38,30,12,35,66,61,65,41,12,45,42,18,26,7,20,16,19,17,23,29,14,13,0,16,18,38,34,26,23,28,26,5,7,30,9,16,48,47,29,52,65,75,96,104,93,110,109,77,67,54,73,68,40,48,49,78,86,93,42,54,44,61,48,75,40,27,54,63,87,70,63,38,143,222,234,239,245,234,245,250,246,253,135,46,18,14,20,107,217,229,213,133,91,38,53,17,69,214,220,239,249,231,216,239,238,220,219,238,216,232,215,223,238,237,226,224,215,230,236,226,216,240,216,230,247,223,231,214,207,210,219,207,224,223,217,211,210,208,229,228,247,121,18,1,6,1,9,9,7,13,11,12,13,4,4,0,3,18,11,7,8,12,9,16,8,24,240,221,222,224,214,219,224,220,232,223,222,224,235,201,235,210,225,233,247,209,219,227,234,221,204,185,226,228,226,226,197,224,209,220,202,240,224,214,219,214,231,187,219,223,197,202,215,242,220,219,198,231,220,210,209,228,224,222,219,197,220,212,218,223,209,202,211,230,241,225,218,217,205,209,215,232,219,203,218,211,219,238,220,226,239,235,238,244,244,231,214,217,217,216,224,218,218,211,214,226,220,218,232,213,251,228,232,220,229,237,216,220,233,228,229,239,201,204,202,211,222,233,199,216,223,215,247,242,214,206,226,234,243,230,225,213,214,227,199,233,221,222,224,240,222,246,226,240,239,216,233,225,193,215,229,235,239,243,240,231,224,215,234,226,199,233,215,226,220,211,214,214,235,230,201,227,209,222,212,230,202,210,243,218,214,220,215,188,225,220,217,213,234,222,204,210,218,227,229,205,220,207,241,242,235,238,218,229,220,240,224,241,210,208,224,243,221,240,236,210,227,245,206,216,247,223,242,234,219,176,240,248,193,227,226,228,231,241,211,224,240,211,243,227,255,247,235,245,249,237,242,235,247,240,245,235,209,245,229,213,246,247,246,225,217,246,213,246,255,224,226,233,241,239,245,221,255,225,233,238,241,229,246,249,223,242,253,250,248,250,251,245,238,214,240,243,240,220,251,221,218,231,247,254,249,236,254,229,253,214,253,239,234,232,244,236,246,226,238,223,224,237,224,186,212,229,168,219,139,10,146,233,223,228,208,217,247,217,208,187,215,236,214,255,171,178,130,109,61,44,210,241,255,253,210,243,196,155,147,213,228,235,251,242,255,223,184,217,234,188,146,232,252,187,166,201,184,212,248,226,246,244,196,146,182,160,162,196,217,205,213,150,179,160,128,74,12,152,106,78,58,44,73,46,19,86,243,247,208,190,189,231,202,244,233,230,167,208,183,99,142,235,189,190,98,156,244,171,62,143,235,183,171,185,107,128,177,179,181,209,212,234,224,253,255,241,183,208,116,65,76,53,95,76,82,98,80,91,69,78,85,85,80,69,45,94,84,58,101,119,129,131,133,128,122,100,89,59,84,49,42,49,37,32,46,21,18,13,22,18,55,28,5,8,44,19,20,18,36,32,23,9,21,18,6,5,39,41,34,13,33,20,28,57,54,56,45,44,5,25,61,61,37,49,37,23,24,61,42,65,44,71,74,144,177,238,230,157,188,165,152,147,143,156,157,179,171,170,142,128,144,153,142,46,45,16,31,20,64,68,52,43,35,46,9,20,22,8,15,37,16,33,28,36,28,28,18,46,69,18,38,42,30,27,20,14,7,31,4,13,16,29,20,13,11,29,33,59,51,81,77,88,126,122,122,82,59,64,33,77,37,85,43,96,55,52,75,83,58,72,36,62,54,47,46,51,23,66,113,88,106,98,97,164,223,217,190,167,178,172,227,241,248,227,161,157,123,34,14,24,167,223,224,220,234,223,231,241,230,196,217,202,239,243,212,227,217,220,247,228,217,201,231,215,225,223,206,236,241,235,226,227,221,231,214,243,221,224,232,226,231,211,213,235,234,144,0,12,14,0,21,10,22,21,5,11,9,6,0,0,8,2,12,10,1,0,23,14,23,21,216,216,221,241,231,230,222,236,227,203,235,219,220,234,235,213,233,235,202,231,227,215,228,224,230,233,234,221,195,225,196,211,205,213,223,196,228,217,227,215,202,217,224,216,188,207,184,202,206,228,199,202,204,218,247,216,220,191,236,220,202,222,212,189,224,234,226,208,208,194,227,227,205,220,205,238,224,235,220,224,227,241,225,208,218,202,206,234,247,239,223,226,228,200,238,238,215,204,226,209,220,205,228,210,216,237,235,228,221,230,214,214,219,231,210,216,199,209,225,233,233,229,213,226,218,212,236,245,205,225,209,223,225,226,236,210,206,211,236,224,220,224,237,233,232,223,214,207,226,225,219,232,214,238,218,230,214,215,210,209,241,212,204,216,221,237,230,225,239,193,226,226,238,212,211,218,217,231,228,195,217,199,218,218,228,241,223,234,219,200,212,222,211,226,208,214,236,205,212,239,220,232,200,224,222,225,231,238,216,229,238,233,223,236,217,236,236,219,234,217,229,224,221,215,212,218,221,216,230,238,206,224,231,244,201,247,231,232,237,213,236,219,239,248,244,236,242,230,211,249,236,223,252,244,233,254,240,207,201,236,233,246,248,238,227,230,240,252,239,251,234,211,242,233,223,245,251,233,235,245,247,213,248,252,249,233,234,221,242,247,239,255,235,253,230,247,242,237,233,242,211,229,241,255,254,227,223,217,238,246,243,244,224,222,231,243,234,251,236,235,233,241,219,220,207,226,236,253,154,51,160,224,216,218,219,217,249,216,200,193,224,184,200,246,207,153,120,117,63,58,241,243,235,208,161,187,191,205,195,197,218,226,253,245,255,189,174,210,206,130,129,211,209,190,196,235,206,215,249,222,252,240,170,179,173,148,171,190,195,225,249,144,173,151,152,91,0,119,69,75,61,23,58,46,21,74,226,247,236,170,179,239,242,227,217,244,179,244,210,107,148,227,188,152,121,197,243,189,100,176,253,194,232,217,109,194,223,215,204,199,190,168,171,231,235,181,122,79,34,25,26,17,4,2,12,17,67,48,65,88,85,64,77,85,86,78,48,76,60,75,60,67,87,39,32,47,48,71,93,22,7,20,31,33,13,1,3,9,13,36,37,29,35,26,27,16,16,51,23,56,33,6,43,13,25,6,31,53,22,13,44,47,43,36,55,53,10,38,56,55,41,61,59,60,43,22,26,43,65,70,60,44,132,156,171,202,214,177,150,137,177,158,178,175,139,185,175,162,161,143,155,187,103,64,49,50,20,18,30,54,61,58,56,55,34,27,22,37,26,12,34,10,37,37,33,29,0,12,49,20,45,35,18,29,56,32,48,37,35,22,16,29,24,6,21,25,36,47,27,29,28,40,46,75,49,102,77,100,92,90,56,76,49,51,57,63,88,76,80,83,82,107,79,60,43,47,64,64,32,52,35,39,46,38,30,99,204,227,237,239,246,248,230,177,115,103,58,33,31,55,218,224,228,205,210,249,233,219,233,200,221,208,229,222,233,237,239,234,240,239,216,219,239,221,228,216,223,193,242,228,229,251,231,212,245,227,236,241,224,231,209,239,197,210,239,106,14,4,1,16,26,7,1,3,11,12,0,43,16,12,3,9,27,1,37,4,21,12,11,4,204,227,230,225,238,205,193,241,210,220,218,216,235,205,227,225,214,234,240,214,207,214,233,233,236,221,227,234,208,224,248,213,226,207,215,211,222,216,199,212,200,227,206,215,201,199,235,206,199,193,230,250,241,209,227,211,212,215,237,219,220,210,221,223,223,210,229,203,221,187,227,208,234,223,234,231,230,234,222,209,217,204,201,197,247,239,238,224,221,237,235,224,240,234,189,205,226,229,241,205,230,214,203,230,221,224,239,229,210,243,223,211,218,209,200,230,215,231,223,220,237,215,224,222,231,235,236,225,207,219,229,206,223,219,210,239,199,242,222,211,247,194,206,242,232,213,229,233,215,208,228,222,242,234,232,221,226,252,233,225,214,208,223,215,206,222,213,195,217,205,229,251,233,215,208,221,195,240,211,212,235,213,213,224,239,200,236,220,220,217,215,209,223,211,215,235,211,210,246,231,174,227,247,222,231,225,242,205,228,192,231,239,214,237,195,219,212,222,224,221,233,236,235,215,232,243,219,239,213,237,231,233,239,243,244,233,228,232,225,232,235,242,249,228,237,193,247,221,239,243,245,247,229,204,244,242,236,227,198,250,241,240,235,238,234,247,241,234,247,255,242,223,220,239,229,236,238,225,247,234,233,236,249,255,255,222,240,227,248,224,242,238,246,221,252,244,231,234,244,247,254,255,237,240,249,244,248,249,250,245,239,219,252,234,240,238,246,230,230,236,245,244,217,211,214,231,223,253,113,60,201,249,238,236,229,247,243,210,220,218,214,217,226,252,198,179,111,104,63,71,170,195,175,177,188,238,234,221,209,221,242,235,231,244,226,242,181,234,232,164,114,196,243,254,242,250,203,209,235,184,188,229,166,173,161,181,204,186,202,218,222,116,151,216,157,109,36,80,66,86,74,49,32,42,19,52,242,247,220,152,160,216,238,209,216,247,156,186,222,112,118,177,127,196,170,220,245,114,147,226,248,172,213,202,134,198,211,192,233,174,186,194,188,198,196,124,95,65,67,92,59,40,39,18,15,8,33,47,23,25,24,19,35,33,6,17,18,38,13,16,34,47,44,33,45,42,110,138,73,34,36,11,0,7,10,21,8,38,9,18,47,51,46,21,7,34,22,41,54,58,59,49,54,35,7,12,39,22,18,19,41,47,38,55,43,27,25,27,53,46,58,46,67,29,26,26,26,76,77,63,57,84,138,129,224,253,191,156,143,139,143,154,155,152,177,195,169,146,146,157,191,166,113,82,72,87,59,34,55,56,60,71,47,29,25,40,34,51,18,15,33,20,29,32,43,65,10,11,29,25,24,30,21,44,27,17,53,38,32,42,44,21,14,33,15,2,45,47,36,30,33,37,22,2,38,19,49,29,42,52,100,120,96,89,85,83,48,67,40,44,61,67,71,72,76,68,54,81,68,48,53,24,66,32,43,35,4,104,208,219,248,207,186,96,100,58,13,17,66,219,234,226,246,241,224,229,240,228,238,218,235,222,207,240,224,215,251,226,189,224,229,241,229,244,224,214,223,247,235,222,223,238,237,223,234,221,219,232,237,215,217,209,236,218,214,148,12,3,11,6,4,3,6,8,8,11,18,2,1,16,0,12,22,8,15,3,6,11,7,0,193,206,196,214,214,212,245,226,205,204,217,216,205,229,199,220,206,217,223,211,232,222,236,226,223,220,219,225,228,224,242,229,218,236,205,197,223,194,199,203,217,210,212,204,237,196,232,207,196,187,204,219,210,221,217,205,220,215,188,218,220,211,202,213,223,212,216,227,204,216,194,228,221,221,232,234,207,219,216,196,231,219,197,213,223,212,236,226,229,227,216,211,232,216,204,241,233,247,200,234,216,212,230,230,221,246,246,220,233,192,217,213,241,241,232,239,207,214,241,218,222,201,229,235,218,228,216,226,214,232,243,220,227,218,232,204,228,236,248,202,225,216,197,222,209,213,225,223,212,204,220,216,214,216,215,229,211,215,229,206,229,230,198,224,229,239,234,222,220,242,236,232,231,224,236,215,210,220,219,218,222,223,235,220,224,226,194,220,215,211,223,230,196,214,243,222,203,215,236,204,220,223,229,199,228,218,204,251,200,220,210,212,209,240,223,215,220,229,235,219,219,210,228,241,231,214,223,238,226,220,231,235,214,227,231,225,227,254,242,217,231,216,224,234,238,217,232,219,250,233,237,236,217,234,220,224,244,214,182,219,224,220,240,236,214,248,251,248,237,230,221,247,232,237,227,234,232,230,245,223,247,242,235,234,232,241,227,250,251,228,249,229,246,231,254,242,238,217,240,247,217,244,225,232,235,234,250,246,241,241,255,252,235,235,232,242,242,244,221,222,254,221,198,201,211,225,193,226,104,78,236,239,245,229,224,223,244,213,239,206,208,201,244,250,173,159,159,123,124,54,165,212,224,235,212,238,237,196,235,209,240,235,238,208,255,192,169,200,252,227,141,241,234,235,231,167,138,200,203,184,201,212,172,174,210,185,218,206,172,201,206,109,174,176,174,138,50,101,53,109,66,77,56,54,4,71,224,240,200,113,180,193,238,209,209,238,189,179,212,124,112,88,106,158,211,233,161,106,206,253,214,145,199,167,118,221,204,209,202,221,229,194,209,228,158,159,166,195,212,237,238,227,238,240,247,215,165,74,61,30,63,37,41,42,40,35,23,39,44,26,68,58,37,16,50,124,159,151,81,12,20,16,30,2,12,15,38,63,35,27,15,30,37,37,24,17,12,13,32,71,42,38,43,56,54,23,42,7,25,30,60,41,45,19,21,11,33,71,63,37,52,45,37,25,5,32,27,46,33,58,57,60,98,170,245,242,152,150,139,157,172,158,159,151,204,174,175,132,166,152,173,131,72,48,96,77,58,19,30,88,88,48,74,37,21,19,64,33,19,8,37,17,34,18,38,43,42,38,26,10,31,26,40,38,63,26,27,38,31,27,12,6,20,15,28,53,44,25,24,37,39,15,25,32,20,14,25,9,30,45,59,35,23,54,98,98,96,119,96,82,82,72,76,76,63,43,63,90,37,48,84,58,90,81,70,64,14,23,4,11,54,70,52,56,55,30,56,175,233,239,227,253,246,230,251,222,234,237,227,240,238,216,199,213,240,225,234,215,227,243,248,250,237,204,232,222,218,221,195,241,220,211,239,234,221,230,217,233,235,223,245,214,214,227,228,103,20,7,24,3,17,5,16,3,15,0,10,1,18,17,1,5,16,19,14,10,4,14,8,0,221,185,201,221,219,223,221,234,229,225,190,207,223,215,239,223,219,223,229,223,217,211,216,214,236,221,226,226,225,197,210,211,228,207,224,199,204,221,226,224,215,209,201,203,215,222,192,230,218,202,185,210,204,209,207,218,186,210,219,201,209,218,205,219,204,195,195,225,213,231,212,185,189,197,230,214,221,246,220,211,215,225,210,220,214,211,233,220,237,225,222,224,200,213,222,215,223,213,211,203,218,231,221,217,209,204,224,215,198,195,221,219,196,211,223,197,217,225,222,210,206,228,226,234,225,221,212,211,219,240,196,215,218,241,213,230,219,206,243,246,236,231,225,231,228,199,239,211,196,224,220,213,210,210,210,212,215,215,217,224,240,188,212,236,200,228,212,234,224,232,218,243,229,231,235,235,207,236,220,215,190,210,239,204,200,225,208,210,211,223,215,230,233,218,235,209,214,217,240,222,203,214,215,230,220,202,211,212,218,218,200,224,217,204,216,224,228,228,236,223,211,226,210,223,239,195,230,223,255,234,215,245,226,249,233,232,224,248,223,231,239,217,224,221,225,249,232,212,237,244,215,230,209,236,228,224,229,230,201,219,241,225,231,220,247,243,224,244,232,232,232,220,233,251,230,252,209,247,239,238,247,234,226,244,224,243,241,232,230,242,234,253,254,246,241,254,233,241,207,207,243,250,244,231,229,226,252,253,245,237,239,246,240,238,250,234,227,228,221,215,244,236,204,187,171,188,216,241,96,128,235,253,252,187,189,240,241,204,211,223,232,217,247,251,170,127,120,116,81,61,220,250,242,227,228,246,196,208,218,218,223,233,246,215,236,224,178,170,225,185,126,204,234,204,165,157,184,223,236,199,203,199,170,196,198,178,198,183,140,172,182,151,175,171,102,143,140,141,115,111,84,31,62,56,33,84,195,243,205,139,184,225,222,221,223,239,168,151,205,131,114,54,112,195,206,172,130,137,218,236,215,158,176,109,115,219,169,194,224,205,204,231,224,224,172,137,242,231,254,227,244,228,250,253,242,216,153,134,138,137,120,112,116,98,97,74,104,96,71,82,100,65,42,20,73,157,160,148,68,37,23,6,37,4,11,50,82,47,53,32,22,38,44,54,50,24,42,21,53,30,62,39,54,50,45,49,49,33,35,69,74,64,41,40,51,68,66,31,40,35,39,22,40,30,24,51,62,61,35,61,49,33,66,162,239,220,139,132,125,172,157,156,159,163,173,176,133,129,148,142,193,119,50,16,50,57,94,46,33,71,90,94,51,26,23,33,24,30,55,18,30,21,31,30,52,39,39,45,14,37,38,13,56,22,21,17,10,20,24,26,28,19,46,45,35,45,49,63,41,27,5,43,13,14,20,23,64,39,35,24,23,49,32,22,41,51,49,70,93,98,142,152,168,164,141,118,102,84,85,54,71,87,68,68,58,69,72,82,57,48,40,68,73,65,45,10,102,211,251,247,217,232,217,233,235,232,217,222,234,251,238,223,240,235,227,225,210,234,220,222,235,229,213,239,220,202,245,245,242,249,232,236,242,229,234,202,232,234,230,243,230,220,227,227,199,121,12,4,21,1,2,24,1,5,21,20,28,30,7,15,10,19,1,1,38,7,12,3,0,16,241,189,234,211,206,200,214,211,219,220,230,223,206,207,235,213,217,213,226,207,228,220,213,230,216,215,211,220,218,237,225,212,219,208,229,218,200,228,203,196,228,237,217,219,224,210,211,225,199,213,224,219,233,220,218,207,221,218,208,203,217,232,213,227,210,206,200,228,233,226,218,203,215,222,203,208,237,199,236,221,228,202,212,217,177,203,244,194,211,219,208,222,211,230,200,196,207,206,201,221,222,226,214,213,203,242,204,200,201,237,200,209,209,220,221,205,222,221,200,194,244,207,240,221,231,207,177,239,219,232,222,220,223,211,235,208,235,239,201,223,225,230,220,227,221,197,211,224,236,230,212,223,223,233,235,231,209,190,213,236,227,229,216,225,238,194,232,238,196,215,245,214,236,193,220,221,227,228,235,238,205,226,197,216,230,216,217,217,241,237,200,217,215,206,220,221,208,209,215,188,224,238,237,224,234,217,228,242,223,221,244,239,227,228,230,189,221,233,238,208,234,232,220,214,227,237,233,219,215,223,223,219,239,222,233,239,238,221,214,245,215,215,213,206,223,236,228,239,237,237,214,241,227,229,207,229,225,222,215,222,243,226,235,213,246,236,250,211,226,232,231,241,239,231,244,250,242,226,255,236,248,234,214,246,240,238,241,245,230,251,230,233,249,238,235,244,228,234,246,248,226,241,247,236,238,243,239,255,237,245,236,222,235,239,255,229,247,239,231,237,254,234,216,179,165,214,238,233,96,137,217,224,241,203,206,253,229,192,234,236,198,225,221,224,146,117,105,79,71,63,218,221,252,226,205,249,182,212,200,193,225,231,247,246,242,232,200,166,176,152,121,141,190,228,225,156,198,249,242,240,189,190,184,215,197,121,198,190,158,170,178,134,170,125,75,203,201,153,136,103,70,32,31,53,5,67,243,242,196,105,170,216,234,204,210,234,199,151,196,229,169,85,112,155,195,212,107,142,223,251,215,172,198,108,173,240,237,192,239,213,212,217,218,227,150,214,236,238,238,234,227,226,208,148,115,83,102,123,124,118,116,122,114,127,121,116,153,93,111,155,140,64,14,36,112,139,135,142,53,34,29,18,7,15,6,32,68,41,49,30,20,15,24,87,67,39,25,34,54,42,75,61,54,42,57,47,53,37,32,64,68,46,48,48,50,64,31,61,44,45,26,21,41,56,32,67,73,80,56,71,63,44,95,212,204,197,135,127,156,155,148,169,162,175,206,147,122,139,172,152,172,117,41,53,37,18,37,26,43,58,58,52,50,6,23,36,22,40,38,30,15,9,60,33,6,16,32,29,27,25,28,43,32,41,22,27,25,16,13,36,38,56,43,36,56,76,65,55,26,22,31,12,23,33,43,32,36,32,33,7,4,18,22,20,36,28,21,36,97,70,74,86,116,133,141,125,168,170,171,148,124,140,129,129,99,106,86,86,95,67,66,41,33,11,18,19,111,229,240,240,237,235,233,217,236,239,231,233,249,215,242,220,252,233,231,217,225,222,241,197,219,232,239,248,235,228,246,232,238,234,202,226,234,228,217,249,225,225,194,205,234,221,225,210,206,119,8,0,12,8,9,20,0,1,52,9,18,12,7,0,14,19,4,10,16,41,10,22,6,3,219,187,205,230,225,209,236,211,238,223,241,209,227,211,207,231,217,199,222,211,183,202,208,224,242,227,204,181,228,233,217,205,219,208,204,205,204,226,237,196,215,200,204,184,215,217,211,189,227,223,216,203,207,222,228,195,201,219,231,220,227,229,201,198,234,191,222,217,212,207,232,218,213,207,205,212,209,220,223,212,228,197,198,223,198,200,189,191,211,227,212,204,198,205,242,229,230,217,222,229,224,230,197,205,205,222,231,215,223,221,208,211,199,225,218,218,212,236,219,219,215,230,182,236,201,193,224,238,212,242,224,214,217,217,216,238,223,222,218,219,229,242,234,238,220,206,214,207,203,225,229,234,208,210,239,205,227,235,228,248,235,219,213,218,220,237,243,226,233,205,225,225,231,220,234,233,229,231,221,231,203,230,196,224,210,212,226,227,234,221,227,238,225,235,229,232,206,221,206,215,228,210,213,225,220,226,217,222,225,221,215,226,213,201,210,205,223,228,217,221,228,240,215,228,226,210,228,213,227,212,210,248,240,212,222,223,217,239,237,227,239,232,245,232,247,240,219,246,216,232,249,234,227,229,254,217,236,198,222,240,226,252,209,205,252,236,243,229,252,234,239,250,244,245,238,222,238,222,231,240,231,228,238,245,245,234,232,233,240,237,247,247,249,240,246,243,241,241,227,255,244,243,241,237,248,242,245,215,217,228,240,220,220,221,240,239,247,236,247,241,230,220,230,207,207,242,234,254,101,89,190,228,250,209,242,227,233,214,220,198,164,168,182,194,180,122,144,87,89,60,206,233,250,236,206,245,200,210,225,210,238,231,227,250,239,243,191,182,194,184,108,150,224,230,232,189,162,232,249,222,185,203,164,222,186,182,233,231,200,159,194,135,171,103,19,198,190,143,172,101,83,25,28,40,57,79,200,250,167,60,133,213,227,212,215,249,200,152,177,237,201,93,64,121,225,166,93,181,229,242,215,211,213,145,186,243,238,211,228,225,231,222,213,204,161,225,238,218,240,230,220,185,106,86,51,69,75,91,101,43,38,29,47,61,93,116,98,28,10,95,110,81,44,39,111,126,151,99,33,20,32,33,57,13,25,15,48,66,61,40,26,11,13,73,72,46,37,14,16,49,37,54,53,68,31,25,68,76,48,77,66,69,90,89,70,58,83,111,80,79,82,140,101,104,121,113,93,128,123,143,136,68,141,253,253,194,160,132,135,147,162,184,163,169,195,139,157,162,172,166,135,85,69,60,41,54,69,70,53,73,80,52,21,61,25,32,44,28,38,21,18,6,43,21,4,13,21,35,39,25,44,34,35,54,50,24,27,30,29,39,68,74,53,25,56,66,54,39,41,38,19,57,54,44,57,56,31,28,37,22,40,27,3,0,25,27,34,123,122,95,89,43,32,15,40,28,16,49,58,76,60,79,96,105,130,105,100,105,73,59,33,35,8,14,32,97,214,210,229,222,251,231,244,206,229,233,214,251,239,243,222,238,235,222,219,218,221,243,240,220,237,224,216,232,218,229,244,234,219,227,223,216,233,206,225,224,243,219,231,224,208,212,218,208,217,145,7,18,16,30,7,0,4,24,4,17,37,13,19,6,8,25,5,10,11,36,8,20,15,8,189,220,205,240,221,210,213,244,214,187,223,207,218,208,214,220,216,206,213,211,199,231,215,214,232,241,220,211,217,197,212,217,209,182,219,200,210,217,241,214,209,216,214,197,214,214,215,188,189,190,199,201,195,200,234,219,228,220,214,221,209,201,215,191,219,207,230,228,227,206,211,230,174,230,204,209,235,209,220,233,227,213,211,199,206,225,227,218,214,222,214,238,212,209,214,217,223,211,194,216,227,225,239,209,201,225,186,217,212,238,239,208,227,233,211,235,202,217,201,217,208,194,210,229,229,235,223,228,226,200,221,240,222,235,203,204,230,233,212,212,209,226,225,191,225,218,218,237,227,207,223,219,215,219,224,211,226,222,213,212,221,199,243,222,217,216,218,242,204,224,187,219,231,210,219,221,186,223,211,217,222,221,226,242,224,241,200,217,230,194,206,207,237,230,211,245,213,180,240,208,221,224,236,235,209,227,229,217,219,206,229,205,218,230,227,223,236,226,238,221,232,207,229,215,201,230,223,229,242,210,219,222,235,221,219,207,231,226,222,229,223,230,233,219,243,242,240,225,214,240,226,236,248,204,252,244,213,200,204,215,248,238,211,241,232,241,233,220,236,215,246,244,226,232,241,221,249,243,245,221,229,232,239,224,243,224,224,222,245,249,232,243,227,232,244,243,247,239,232,240,230,243,235,240,255,254,243,233,215,222,250,216,247,234,238,248,243,243,254,221,225,228,238,196,204,180,210,197,90,132,216,227,248,219,222,238,243,201,232,194,171,207,216,250,185,168,137,110,75,61,214,239,245,225,212,227,197,206,218,233,224,216,241,203,223,234,180,189,167,200,175,172,223,236,255,148,188,248,218,188,125,143,168,193,184,191,227,207,213,106,177,143,140,68,47,242,202,135,175,132,113,20,17,59,21,89,242,230,195,85,162,201,226,215,202,232,195,128,204,236,205,126,91,193,218,145,62,181,241,189,201,193,168,119,210,224,234,217,215,220,224,213,241,222,136,212,214,212,206,223,210,131,93,73,67,67,77,44,28,26,35,50,46,20,76,93,86,58,1,58,106,132,84,55,130,109,154,113,40,36,26,84,56,50,46,58,57,45,69,20,0,15,14,52,46,13,32,19,31,41,46,58,72,89,81,100,131,131,126,109,145,114,120,105,111,101,114,120,89,122,95,93,103,112,114,141,125,111,106,142,122,78,191,237,229,182,143,154,144,147,151,182,198,194,174,154,144,138,157,214,136,96,61,52,57,47,46,61,81,57,55,73,62,62,72,52,67,42,59,49,50,52,35,53,27,48,31,66,55,51,48,52,15,21,26,48,52,20,51,36,33,51,62,61,25,21,41,45,38,35,27,49,33,43,16,34,39,25,31,50,10,3,2,19,15,37,86,133,115,127,96,58,46,14,54,39,32,26,15,51,18,16,30,51,31,40,74,45,31,72,78,110,133,189,238,245,251,245,239,223,212,218,237,230,234,215,236,220,246,217,248,219,213,240,246,251,225,241,239,219,240,230,221,215,221,217,232,225,242,238,231,227,231,255,235,230,225,244,245,230,230,235,225,233,238,102,30,18,10,0,10,5,13,0,6,18,22,11,0,11,5,7,13,13,7,8,11,12,33,27,216,220,195,198,224,198,237,205,209,208,200,205,212,207,201,213,222,196,223,227,205,203,203,216,246,221,205,212,218,194,206,206,225,209,202,213,211,214,209,192,226,202,183,226,207,184,212,196,198,212,206,208,206,190,203,216,213,206,237,194,195,218,196,223,215,201,205,208,221,218,219,210,209,215,204,209,228,222,213,208,206,220,228,215,196,229,213,213,207,225,219,218,238,218,230,237,216,215,213,213,235,205,212,209,211,216,234,203,218,200,196,195,207,203,213,213,218,215,209,209,201,212,211,211,214,229,166,221,227,212,214,225,204,211,190,221,213,219,211,219,214,212,208,231,205,199,209,219,203,220,210,233,226,224,220,231,236,236,212,207,215,238,203,214,219,217,208,195,195,215,215,211,209,221,215,195,212,214,223,202,226,211,218,232,201,201,187,210,216,204,204,231,242,222,214,244,232,222,210,230,221,222,209,212,206,207,220,213,231,241,232,222,227,224,209,227,222,200,217,232,220,238,243,207,220,210,228,217,211,206,214,242,237,219,248,225,231,255,227,233,248,227,242,243,234,234,236,254,238,217,237,223,233,236,218,198,194,216,232,238,246,225,226,244,250,254,216,237,250,249,233,241,247,250,243,238,249,227,226,218,244,247,214,232,220,239,247,232,209,222,231,221,220,255,243,229,254,233,236,236,243,242,232,241,235,243,233,231,233,240,234,240,246,228,254,252,208,249,236,241,238,212,204,155,200,175,240,234,111,144,248,228,238,199,195,218,196,174,220,215,212,221,248,234,172,187,167,117,90,60,211,247,232,215,221,217,182,217,249,204,235,211,218,218,223,233,200,195,156,157,205,202,218,239,225,146,165,218,181,148,112,203,211,219,160,196,200,188,217,143,179,141,135,55,65,248,172,66,136,148,137,62,35,36,18,69,243,238,188,120,184,203,245,216,215,247,192,123,195,210,142,81,108,185,173,121,152,190,223,196,180,169,115,157,204,223,235,220,204,227,244,234,218,194,170,228,220,208,205,223,180,96,111,64,69,93,43,30,33,62,97,95,108,88,55,115,82,47,23,36,94,125,86,102,167,127,144,57,9,27,6,31,52,64,60,54,60,46,41,24,11,11,28,52,82,55,80,110,111,124,129,139,142,123,133,142,135,132,133,103,108,110,84,90,121,88,109,114,92,103,114,126,115,120,119,121,90,120,74,98,50,103,247,240,253,168,138,150,148,166,158,163,179,183,146,142,144,170,173,174,100,65,32,42,53,38,40,41,74,50,63,67,53,58,72,38,53,28,56,44,33,43,51,63,53,73,37,72,63,54,73,40,46,51,47,46,37,39,37,34,55,44,50,54,77,66,31,31,34,58,68,62,19,14,41,16,45,46,58,22,38,33,21,17,21,22,50,98,121,103,65,60,21,21,75,77,63,56,71,71,69,52,47,60,69,37,52,90,159,210,245,239,238,250,234,218,251,231,230,229,236,229,233,236,235,231,250,210,225,249,242,220,243,233,245,228,234,237,205,202,224,221,241,238,244,210,247,222,205,231,225,237,225,228,210,248,246,236,221,227,212,220,220,211,225,110,1,8,15,4,22,3,9,9,1,20,1,4,0,12,5,9,10,4,5,29,6,18,9,13,212,207,215,199,212,216,209,220,215,233,232,200,200,234,202,208,210,225,205,227,211,191,226,203,208,213,212,238,238,231,225,216,203,209,196,194,200,199,225,195,201,222,213,212,217,206,182,227,209,222,200,240,201,203,203,242,202,219,218,212,194,216,218,204,205,208,202,236,208,209,208,216,223,193,200,231,211,225,210,235,205,207,205,192,206,240,217,219,210,235,210,228,215,219,217,195,223,232,217,238,211,229,203,222,202,215,230,240,199,218,219,203,211,194,226,200,221,191,223,208,224,216,241,189,230,207,220,230,218,236,226,221,214,200,223,231,211,230,208,220,223,204,211,236,222,199,232,238,180,215,218,204,212,215,214,206,206,196,202,233,239,218,223,191,217,218,204,214,219,203,210,212,213,211,188,209,215,200,211,211,222,201,212,213,203,195,206,183,217,227,206,235,217,217,248,200,223,221,207,220,214,228,200,239,221,201,205,223,191,208,217,228,220,224,211,218,223,214,212,219,229,209,223,218,229,243,211,231,219,221,227,209,207,239,222,211,213,222,216,221,248,213,224,251,218,227,234,229,225,234,210,234,211,229,234,213,224,240,238,238,229,229,215,223,231,241,223,234,246,238,236,219,250,238,229,219,248,227,235,241,232,247,249,232,238,229,233,232,223,236,220,227,240,251,236,237,220,239,242,234,227,244,239,246,240,255,249,204,230,238,236,247,245,230,221,214,237,234,220,236,242,230,242,196,199,224,252,228,89,141,241,196,206,190,190,221,241,218,232,214,181,228,245,252,176,166,135,119,65,70,220,247,247,225,239,201,189,255,220,222,243,249,246,243,234,211,203,244,179,128,192,170,199,244,215,114,170,213,188,206,211,193,194,217,177,163,203,201,186,184,228,164,94,63,128,237,159,48,113,128,199,143,41,56,4,49,202,246,169,151,171,202,238,202,199,236,170,130,218,153,135,117,91,175,180,137,142,234,205,189,199,164,118,149,248,237,222,208,231,235,200,205,206,167,188,219,208,245,235,253,158,91,119,84,60,66,57,47,45,125,110,129,119,98,102,117,104,89,40,33,109,146,84,89,119,100,129,61,2,18,15,16,45,55,53,66,55,60,88,84,115,93,165,155,126,152,119,104,137,137,125,108,116,117,135,106,127,109,113,90,81,77,88,121,86,63,61,46,61,59,62,14,39,52,64,22,33,73,26,33,9,123,250,239,235,145,138,155,131,153,167,185,207,200,149,139,151,166,170,174,84,41,20,19,28,44,25,19,31,48,17,40,28,32,44,62,28,24,64,49,40,65,51,58,41,58,38,65,48,56,58,57,57,63,74,53,74,96,63,57,51,58,41,60,28,30,18,41,19,46,37,56,20,19,12,32,52,63,54,52,21,10,16,35,65,48,39,111,130,125,85,40,15,26,115,124,154,145,151,143,104,120,129,120,170,162,154,141,168,250,241,229,235,236,221,239,219,232,214,222,231,230,243,219,232,225,250,231,230,226,216,219,242,239,242,231,228,245,227,204,237,239,218,228,224,218,239,215,229,230,223,225,210,214,232,226,240,234,224,251,236,222,213,210,242,120,16,2,16,11,2,18,21,15,9,31,31,16,21,12,17,9,17,11,10,20,6,18,24,8,208,212,204,226,214,219,216,201,221,209,206,227,202,205,197,213,213,219,190,207,214,216,186,213,215,220,216,200,203,224,215,206,212,203,203,227,191,187,214,189,205,213,204,211,200,228,203,226,193,202,204,210,189,203,189,220,234,218,204,213,212,201,190,213,206,227,234,206,208,212,205,204,217,206,203,224,195,214,202,199,213,200,209,217,194,194,226,212,227,209,212,216,215,228,209,215,196,219,222,230,186,205,223,221,213,219,213,222,225,201,231,228,219,211,221,207,208,192,225,217,211,202,233,231,235,194,216,207,208,227,214,216,231,214,214,225,225,224,221,232,223,237,194,213,239,212,211,205,231,204,214,219,209,204,189,213,229,222,211,208,219,223,219,227,214,221,205,222,207,210,229,217,237,196,213,215,202,226,221,189,218,208,205,220,209,205,220,210,239,206,219,236,196,223,207,214,223,208,242,232,216,199,207,216,216,233,234,210,237,219,207,216,240,239,205,215,240,238,233,207,209,230,197,211,188,231,227,243,216,207,218,220,218,214,239,235,216,221,221,216,214,203,233,228,227,222,229,220,216,234,224,237,231,252,224,218,211,222,210,228,237,225,248,245,245,238,230,240,230,206,239,213,242,220,247,230,245,240,240,200,213,223,254,228,233,232,219,226,245,252,239,234,214,230,249,242,246,241,228,222,223,228,240,243,249,243,232,233,218,220,207,249,242,231,231,243,230,216,221,243,247,217,206,196,232,229,250,193,89,151,216,226,234,204,240,251,238,220,227,197,186,225,236,239,165,154,126,108,74,65,204,246,232,250,222,199,169,248,234,245,216,238,232,241,234,244,216,206,162,149,221,129,139,197,199,181,193,209,200,218,176,181,235,175,177,181,194,219,216,206,224,157,84,113,198,245,151,48,48,78,129,190,142,57,1,4,162,240,161,111,214,193,221,231,215,252,158,154,189,150,183,154,104,107,177,154,216,247,187,187,197,158,101,179,241,231,249,218,222,196,236,205,243,168,184,231,226,211,221,249,141,82,112,44,105,64,30,29,123,134,76,66,18,34,80,135,138,65,41,40,83,137,108,139,107,119,113,31,40,70,64,71,80,136,130,119,152,116,117,113,122,123,112,106,120,128,126,121,141,110,145,109,79,85,66,84,54,55,62,62,36,49,41,24,39,37,96,53,47,52,47,29,47,50,39,32,6,13,12,40,15,174,243,241,237,149,137,140,159,179,191,163,161,155,143,143,150,172,186,133,50,28,25,13,17,24,11,33,46,30,18,30,9,14,16,25,17,18,30,21,4,35,34,46,37,47,63,52,45,65,58,47,74,57,60,79,44,87,70,119,64,96,73,50,88,79,54,39,23,38,37,53,9,18,1,8,47,68,26,29,24,11,31,18,25,53,37,110,100,108,114,64,44,95,166,149,105,97,99,132,146,145,120,120,106,132,119,138,114,99,190,233,233,249,244,227,226,241,209,228,238,247,234,237,228,246,240,237,241,210,215,207,237,234,228,231,236,227,212,239,229,216,245,218,226,246,222,232,223,232,239,221,217,213,230,215,235,235,220,217,204,225,224,218,234,132,5,0,18,10,25,24,23,32,28,17,16,12,22,9,13,22,30,13,6,3,22,12,32,27,212,212,201,195,212,215,232,204,193,193,218,206,214,203,236,197,202,210,186,203,198,207,197,205,213,206,213,212,202,214,198,201,206,198,229,226,189,192,205,198,203,197,198,202,193,203,196,173,210,199,201,208,196,213,177,206,223,218,209,195,207,227,199,211,203,200,234,191,228,210,227,218,222,205,214,196,210,206,211,210,204,213,201,220,201,190,202,212,233,219,197,218,196,192,201,213,244,213,228,211,204,225,231,204,214,234,181,207,217,222,191,226,212,221,222,197,235,210,228,243,219,219,243,220,193,208,215,218,210,200,198,204,191,228,221,219,218,215,217,231,243,213,194,230,206,217,219,225,196,205,220,186,187,210,224,221,195,212,201,217,199,216,219,223,220,208,237,237,225,221,221,200,223,210,230,210,195,214,221,226,204,219,227,228,220,194,244,220,232,238,243,209,228,209,220,215,208,207,229,208,236,241,226,226,219,208,214,200,220,225,242,230,194,217,207,202,224,219,238,201,237,200,210,226,237,190,215,227,225,205,205,232,212,240,229,236,208,246,230,231,217,214,228,223,214,226,223,242,230,233,212,198,233,232,231,195,211,225,230,229,211,203,248,246,219,190,231,242,244,223,248,234,252,229,242,245,251,239,229,240,241,215,245,217,225,237,222,246,239,235,234,232,229,237,225,220,255,249,224,225,253,235,227,222,235,245,232,242,244,236,240,218,222,250,219,235,240,216,210,241,247,249,242,232,201,163,221,128,124,200,207,239,237,185,248,255,211,228,221,202,166,225,251,253,176,154,127,114,72,66,218,236,235,215,203,177,204,255,203,214,205,237,225,209,227,223,196,219,141,144,218,156,150,222,214,194,181,205,202,202,142,202,231,216,205,139,199,207,200,196,188,139,45,164,234,232,151,62,64,80,102,154,161,117,48,4,163,238,179,130,234,206,224,226,221,208,116,209,239,195,158,125,105,112,126,197,206,238,219,200,197,142,121,194,238,213,214,207,187,236,237,241,212,162,173,228,231,224,206,231,159,76,84,96,107,52,20,43,120,124,64,97,44,55,48,140,137,79,28,59,102,95,88,122,97,100,158,93,147,166,183,169,144,112,108,128,106,109,117,124,114,93,123,116,44,87,78,76,61,51,73,39,34,60,42,32,21,39,49,71,34,35,12,24,82,96,83,101,74,36,35,32,40,30,84,24,44,32,22,2,62,219,241,255,208,141,168,146,167,172,192,167,166,130,139,139,181,157,174,111,16,38,55,23,19,27,56,39,27,40,33,22,26,17,36,7,9,18,13,20,4,20,14,16,19,3,46,12,16,31,42,60,49,78,37,81,70,52,85,62,41,84,81,60,103,95,91,53,73,83,77,51,24,24,9,17,27,58,81,36,63,52,52,50,43,39,72,106,120,146,103,55,92,154,152,76,48,28,57,112,88,94,58,59,57,51,59,69,112,97,117,175,238,241,222,237,227,231,254,247,225,240,202,252,240,221,204,241,240,246,241,249,224,240,230,229,233,220,229,235,237,236,235,235,248,239,240,227,212,189,224,234,227,221,223,216,232,219,247,241,246,243,235,216,223,123,2,7,4,5,0,13,6,25,18,13,30,0,17,5,7,13,15,9,9,8,14,14,16,2,203,207,194,204,199,233,205,205,206,223,232,218,218,200,223,222,227,221,214,199,206,200,210,222,216,218,193,197,199,223,187,209,205,200,226,205,239,204,204,207,187,193,209,214,201,184,213,209,202,211,193,199,225,199,225,208,196,232,196,207,217,201,198,227,202,207,215,199,225,192,228,200,226,225,218,214,197,223,206,202,241,210,204,228,232,205,186,211,216,213,205,210,206,209,205,193,218,206,215,198,209,195,200,193,210,217,223,226,199,218,208,216,198,202,230,215,193,228,213,221,223,223,218,200,187,245,234,225,208,232,227,212,217,240,200,217,223,229,214,233,214,195,227,213,202,226,211,207,225,219,222,203,192,206,209,220,213,192,205,237,223,222,206,214,236,217,224,215,193,190,233,230,222,226,198,226,225,205,228,202,211,214,219,207,210,229,209,236,218,213,219,217,218,206,230,209,203,216,213,213,207,210,198,202,200,214,217,202,235,219,214,212,219,216,223,209,185,214,239,213,208,224,214,202,209,213,214,215,212,222,240,200,211,219,194,213,203,224,243,212,203,244,231,234,216,246,207,234,226,222,225,227,242,247,216,216,205,217,253,226,208,243,227,220,232,216,232,230,225,227,233,247,235,243,226,215,228,244,223,233,227,237,234,240,248,231,242,241,244,234,246,245,236,224,219,246,229,252,236,237,233,237,226,248,244,232,234,242,229,231,244,245,229,237,227,243,238,246,221,255,221,208,171,195,161,140,232,172,135,200,224,219,218,203,227,229,226,209,229,180,210,246,251,251,190,148,151,94,59,81,203,244,251,215,203,187,192,241,211,213,241,215,238,221,229,234,215,216,156,176,223,174,222,206,195,197,170,198,196,206,174,195,192,186,215,159,166,217,208,196,162,119,67,206,249,237,157,57,78,112,46,102,125,179,101,51,196,247,162,84,204,218,207,204,202,210,154,194,245,149,123,165,196,125,86,191,234,244,196,222,172,121,114,176,232,221,234,230,196,209,210,230,220,158,227,246,225,231,240,253,118,78,59,61,118,43,14,35,141,116,81,101,100,133,141,136,118,41,37,63,151,115,81,137,98,153,119,102,149,150,135,134,154,122,122,102,114,97,71,88,57,51,43,57,17,13,6,63,77,37,68,24,13,68,91,78,56,17,55,74,68,53,59,80,66,54,71,88,129,81,39,43,46,38,24,39,34,30,29,13,127,239,254,253,190,128,139,159,178,185,154,151,152,124,165,155,167,157,146,55,58,24,18,28,24,47,48,40,42,6,30,21,19,27,37,6,18,10,11,34,19,31,25,37,44,11,2,15,0,13,48,65,56,27,35,26,12,36,54,52,98,101,86,94,74,57,65,67,96,105,77,87,77,69,65,65,32,26,40,48,39,55,47,39,36,23,46,104,147,117,118,28,78,145,115,66,37,44,97,94,66,31,94,76,65,44,22,22,26,51,104,160,237,232,233,245,238,248,255,244,251,226,243,233,251,228,246,228,247,253,235,222,206,232,238,225,216,251,233,221,226,248,230,223,235,249,210,200,231,219,223,192,216,219,222,221,232,242,237,196,232,221,234,236,235,105,0,2,4,11,24,12,17,8,12,1,3,18,9,13,17,27,10,8,18,0,7,5,20,17,182,195,192,220,199,200,214,208,199,218,198,214,202,181,214,208,208,212,204,210,207,202,206,189,208,200,192,220,177,176,213,229,234,226,203,207,231,208,202,184,208,205,209,203,215,217,210,190,192,215,180,196,197,189,190,184,214,207,201,182,195,193,222,198,206,220,216,234,189,202,226,215,187,188,230,223,214,229,234,216,207,214,209,218,202,203,203,215,202,211,205,213,235,216,222,213,211,205,209,236,208,233,195,244,219,213,215,202,203,219,224,198,218,198,216,200,216,201,218,213,218,213,203,183,214,192,224,209,225,217,219,215,208,213,222,190,210,223,221,232,191,196,209,203,224,208,200,232,233,205,202,219,213,219,175,193,221,222,194,203,204,196,209,229,210,206,230,204,197,223,233,222,227,198,212,202,213,210,219,231,225,213,192,197,210,192,197,188,217,208,193,204,210,220,227,207,193,201,224,218,224,213,215,211,217,213,248,195,208,198,219,196,238,214,214,208,210,208,205,228,205,207,216,213,220,219,243,219,200,225,217,236,220,208,231,199,200,225,230,212,210,237,240,224,223,235,238,203,233,213,235,225,250,229,239,206,206,251,236,241,229,205,231,241,207,197,228,222,237,240,248,236,231,212,240,237,215,219,226,242,250,249,235,249,228,229,227,249,234,235,241,249,248,219,240,229,252,245,247,238,246,229,220,249,238,211,235,229,242,236,240,246,215,249,255,248,233,235,249,218,102,75,77,127,177,188,236,143,90,176,236,225,239,222,229,239,218,209,225,202,219,244,239,230,151,164,115,113,61,58,221,236,225,236,206,189,227,229,196,224,186,237,226,217,224,243,230,209,178,188,230,182,193,221,237,207,128,229,202,154,138,136,185,186,211,164,206,193,234,181,135,95,85,236,253,250,150,84,122,105,98,38,70,151,166,168,206,254,175,69,187,184,227,236,204,197,169,214,233,167,144,173,196,66,44,187,240,242,178,202,161,109,110,219,219,230,247,230,208,205,220,255,186,151,224,249,220,247,243,237,133,98,111,107,115,46,18,23,105,127,82,74,95,99,90,70,32,30,47,112,121,99,115,132,116,118,115,150,171,169,122,105,87,85,63,38,20,13,24,10,27,14,39,69,56,12,13,33,80,83,82,12,43,113,108,147,93,63,95,106,97,41,98,127,73,42,13,88,120,112,52,40,33,42,40,26,30,49,15,66,220,238,251,227,149,141,152,132,152,146,153,151,119,133,144,128,128,165,118,65,18,15,31,46,28,23,48,19,11,36,20,18,24,32,30,33,37,38,20,29,0,33,15,22,26,42,33,27,14,5,56,53,51,41,32,0,5,35,12,41,36,24,67,75,71,93,73,99,106,82,79,50,68,77,60,85,65,74,47,69,39,28,10,14,33,72,63,112,109,122,102,89,80,131,94,58,50,72,98,102,107,135,147,153,98,140,62,56,29,31,61,147,221,243,238,243,228,230,230,230,242,233,222,242,239,234,234,237,237,232,220,252,199,249,255,225,237,222,235,233,217,241,232,225,212,219,236,212,239,223,231,222,245,234,203,248,243,215,213,240,226,218,234,232,220,124,7,2,10,1,3,8,15,2,51,3,4,1,19,7,4,10,2,11,16,8,13,48,5,16,196,210,192,196,228,214,205,210,195,205,212,183,229,204,211,218,209,222,197,217,185,189,217,209,206,212,185,206,206,210,229,184,207,201,214,201,178,212,205,198,223,203,227,208,204,213,203,191,207,209,195,214,200,196,195,192,198,203,214,187,213,190,197,228,203,204,188,193,199,193,208,222,162,211,218,223,197,216,209,215,197,211,195,181,179,217,207,212,215,234,188,227,225,211,220,209,210,239,224,217,203,204,216,223,216,204,203,193,219,213,213,196,197,227,215,206,226,212,197,214,230,219,210,211,221,212,212,218,213,233,219,223,215,198,201,223,217,198,236,207,223,201,210,211,221,213,203,197,239,241,212,206,208,215,199,235,222,201,194,214,208,200,220,210,224,219,207,212,220,192,177,202,229,210,209,209,213,227,214,195,225,208,200,212,242,193,236,203,223,212,212,231,225,209,239,242,207,212,192,226,206,246,217,234,206,206,217,221,205,206,231,223,202,221,206,219,216,217,225,226,227,210,221,190,228,238,219,245,215,228,213,197,217,210,215,202,235,182,220,225,226,221,240,226,221,234,198,212,211,219,214,235,247,234,211,207,215,232,217,212,227,232,219,220,221,228,247,199,239,246,228,229,237,237,206,243,212,224,219,226,246,216,225,236,221,230,239,237,236,243,241,227,241,239,225,237,239,238,249,234,240,236,239,227,238,233,227,228,220,234,226,236,232,234,241,239,215,215,166,167,99,58,44,150,236,198,223,132,111,235,219,228,239,205,213,214,205,207,218,193,206,234,244,251,173,130,135,95,50,84,232,225,246,225,217,230,243,255,239,200,229,230,234,214,234,250,180,191,184,194,223,184,193,189,236,195,104,191,141,153,175,160,160,209,227,175,209,192,231,180,187,102,83,229,209,253,169,59,82,113,81,47,4,79,117,196,241,222,190,67,204,203,236,209,178,189,183,189,183,150,141,240,186,66,119,154,234,223,210,214,159,93,167,224,244,254,231,245,214,202,202,228,175,189,243,240,219,234,246,252,172,78,83,94,140,63,41,22,69,106,113,61,18,47,62,39,47,71,127,150,133,73,69,117,97,116,90,86,63,19,42,12,18,22,24,63,96,53,37,15,13,20,72,95,82,99,87,56,122,110,93,9,73,103,123,109,118,159,112,105,128,36,45,140,90,63,36,98,120,66,36,19,18,25,42,29,20,47,39,82,239,255,247,252,191,155,149,168,176,148,154,155,126,133,171,175,173,175,105,44,51,25,24,31,36,33,5,30,13,51,35,17,27,25,40,31,22,12,15,10,30,30,37,39,13,8,29,20,16,9,45,61,61,38,23,43,41,73,82,48,67,64,51,38,14,15,24,58,60,77,96,105,83,76,82,75,79,80,70,69,96,57,43,72,49,75,41,91,120,130,101,89,110,92,76,58,48,102,98,115,113,83,71,48,107,145,86,61,54,37,68,107,217,235,244,249,247,244,213,237,239,229,235,227,229,210,241,240,235,249,251,230,223,251,242,233,230,220,236,226,239,253,215,226,235,225,226,243,215,230,200,200,226,226,221,237,233,233,243,231,227,232,231,209,214,112,8,25,6,19,12,22,13,17,22,3,34,12,16,7,15,10,4,12,2,9,3,30,19,2,218,206,211,181,234,194,211,206,209,207,202,208,199,209,196,197,210,212,198,210,192,193,199,206,194,205,204,221,213,230,227,191,205,172,223,210,190,184,207,197,213,219,181,184,180,221,209,211,228,215,180,195,182,218,223,193,189,209,222,200,198,192,218,189,201,203,186,197,226,227,199,213,213,206,192,228,209,214,178,207,205,213,215,193,217,202,214,216,178,203,220,212,222,197,183,203,227,218,209,214,193,210,215,241,200,204,191,215,233,218,228,219,201,207,211,207,227,203,216,205,216,195,212,207,210,212,209,221,213,212,223,203,200,225,210,223,214,206,214,228,212,212,208,241,221,215,244,223,218,186,207,194,208,189,213,207,191,210,216,237,214,230,209,220,205,207,213,208,215,223,221,234,215,205,215,231,233,207,229,234,230,197,241,221,219,210,236,208,208,215,210,197,203,201,200,235,214,231,212,211,214,221,194,220,204,220,231,230,222,216,231,215,202,222,241,216,228,216,223,212,249,231,214,217,218,221,216,214,214,216,236,223,197,239,237,213,246,236,226,219,209,204,204,225,236,243,208,203,211,213,249,247,231,224,229,174,222,246,209,208,217,228,229,191,228,213,225,230,238,250,214,224,232,220,228,211,238,213,220,241,221,235,245,226,242,236,235,247,232,241,215,246,236,239,209,236,250,237,235,237,236,242,222,246,227,223,251,236,234,255,242,240,244,235,213,193,176,182,205,219,161,98,118,224,203,187,223,129,125,212,249,223,205,204,228,223,193,181,236,164,206,251,230,240,202,162,137,104,49,79,218,232,226,228,178,222,255,243,233,214,202,216,193,223,218,228,204,190,132,148,214,191,176,177,189,149,149,177,190,185,228,182,187,192,240,185,182,200,222,181,174,107,70,242,227,255,188,51,87,132,127,38,24,63,48,144,223,236,143,84,199,205,238,217,142,182,205,160,118,158,156,226,156,78,112,151,239,217,206,249,174,88,151,254,225,219,229,214,207,216,236,216,185,185,224,215,253,238,250,255,205,97,99,96,136,118,84,13,43,92,132,80,65,34,42,64,92,108,83,141,56,28,125,123,109,114,51,31,19,24,23,21,34,4,49,96,84,65,55,20,27,16,74,126,114,112,124,101,105,99,32,35,70,117,99,82,89,122,135,129,104,49,29,63,91,58,103,108,85,75,47,47,17,51,47,42,52,44,25,164,250,245,248,233,180,149,173,152,163,185,188,150,169,157,153,158,170,154,92,15,36,37,17,36,30,17,13,45,31,27,32,30,19,17,9,27,32,2,8,16,36,21,41,34,43,30,26,24,19,25,67,81,41,56,27,26,74,73,48,54,54,54,37,4,55,29,22,45,36,42,20,45,41,48,62,92,64,83,79,57,41,62,93,87,99,89,85,123,132,121,113,45,85,134,89,62,42,74,149,135,90,56,55,25,46,113,128,98,43,76,52,79,219,230,226,240,205,229,252,245,242,241,248,236,227,233,215,219,223,239,214,240,229,226,225,236,224,233,241,233,245,233,234,220,218,229,217,211,226,234,220,222,229,248,248,223,207,227,218,228,234,233,234,231,203,100,1,3,0,10,22,16,38,18,7,12,23,17,4,1,0,16,10,14,7,2,13,24,3,11,201,209,179,211,199,183,197,177,209,233,200,204,182,195,207,217,212,198,179,201,201,198,199,216,217,202,204,204,212,216,200,208,211,214,184,189,203,214,227,191,205,206,188,207,174,200,195,219,202,227,215,233,195,197,212,198,215,227,207,221,207,210,178,185,219,201,209,219,212,185,208,203,187,214,220,196,208,230,191,175,212,204,216,200,211,207,208,189,212,209,203,194,209,203,224,194,206,209,204,195,218,176,214,213,200,205,208,232,209,220,199,217,222,229,206,215,196,212,201,196,209,206,223,210,205,232,223,226,230,220,247,208,212,217,204,222,211,224,211,215,212,221,199,221,242,193,196,215,203,212,177,200,213,207,206,222,205,196,215,181,216,212,213,226,224,229,205,217,227,201,180,202,189,216,211,213,222,225,228,214,218,209,232,196,233,238,216,220,213,204,214,205,211,231,224,204,218,205,220,193,233,177,212,236,199,191,230,214,192,221,212,207,236,233,211,237,221,222,224,237,217,222,213,228,199,197,225,221,218,180,227,217,226,224,245,231,212,223,238,249,216,213,223,207,198,230,225,220,218,230,218,222,214,203,193,218,225,216,215,234,193,226,244,215,219,231,238,222,242,223,226,237,226,231,244,230,240,228,232,225,247,250,232,210,245,234,247,234,238,248,224,224,238,233,239,239,235,230,234,241,222,250,212,245,239,245,239,244,240,241,234,196,176,170,176,204,206,211,244,249,204,108,175,232,207,247,221,116,107,212,228,238,193,187,236,253,225,186,228,193,222,237,198,249,208,187,145,112,57,57,200,228,247,207,147,165,248,238,231,203,219,229,210,214,222,233,220,218,173,131,172,174,190,179,151,156,195,193,182,207,209,194,178,229,219,177,190,181,197,163,183,83,89,234,220,242,163,49,71,126,99,53,41,39,11,102,196,245,137,54,191,201,243,175,111,176,184,84,133,187,209,192,100,93,122,127,213,179,215,230,167,128,168,228,241,239,241,239,234,219,209,240,169,221,222,239,229,242,254,238,188,74,46,108,135,132,84,46,24,51,114,148,144,152,119,120,152,161,152,119,34,31,111,122,105,131,51,9,15,19,6,18,49,35,106,133,121,137,67,41,25,22,49,106,101,102,89,126,88,108,78,37,63,122,101,36,44,59,87,102,80,74,36,18,89,129,115,98,75,64,34,48,44,77,68,48,94,49,88,250,249,231,235,247,202,153,139,154,171,220,199,151,127,149,166,160,152,119,84,36,44,43,23,38,36,26,18,22,36,38,11,11,35,14,46,46,29,15,16,4,21,26,14,19,35,23,16,14,9,37,84,80,46,6,30,38,27,60,87,45,73,49,36,23,44,19,53,79,107,65,70,54,46,29,17,47,47,60,60,76,82,73,58,91,91,81,108,101,105,147,96,95,91,122,80,45,57,48,111,123,115,72,64,113,95,102,140,90,52,52,40,77,200,235,223,239,233,237,234,213,239,246,249,241,219,237,230,240,233,208,227,219,249,225,245,234,217,224,218,206,230,232,227,208,239,206,229,210,226,224,228,227,199,220,222,244,232,212,234,203,222,226,238,236,204,118,5,18,26,22,16,11,6,11,36,7,19,21,1,6,31,1,8,21,1,6,7,1,27,26,198,195,214,187,223,206,192,201,201,202,198,207,210,207,210,214,209,195,217,231,225,221,195,194,189,185,209,205,224,213,205,217,190,185,216,199,223,217,205,200,200,201,220,198,222,204,203,216,201,206,211,208,205,203,212,212,194,190,192,207,184,197,201,209,203,184,206,199,229,214,224,207,198,204,190,214,222,227,194,217,194,199,194,203,236,215,204,214,215,232,200,212,207,215,214,207,207,210,194,209,203,211,215,220,206,208,211,188,202,201,221,210,195,211,214,215,196,214,223,209,212,187,219,185,204,218,225,217,209,202,229,214,205,199,221,199,229,192,215,208,201,222,210,187,233,220,195,211,214,198,188,209,196,190,198,196,200,215,218,206,186,222,208,221,203,222,198,226,203,208,204,228,241,221,222,213,211,221,224,214,184,206,194,189,212,222,229,196,209,205,227,242,224,210,225,205,190,227,208,175,205,214,209,213,222,199,192,206,200,245,215,226,218,222,230,226,222,226,195,200,242,230,220,226,229,207,225,236,204,211,212,217,239,196,216,218,208,239,238,200,221,242,211,225,210,200,207,199,224,202,196,197,215,220,195,210,239,211,215,228,235,224,219,208,245,224,216,243,215,225,221,225,224,222,225,244,225,236,230,241,245,225,229,231,209,225,221,235,233,232,228,209,232,232,247,226,246,240,238,237,230,231,239,248,243,247,230,246,224,200,196,196,187,197,193,218,237,251,230,247,177,85,159,237,217,233,183,89,115,235,222,240,208,205,245,246,206,205,243,186,227,248,253,254,182,142,122,102,62,73,216,237,251,122,34,59,135,243,229,213,235,224,206,232,227,219,226,184,153,148,230,175,176,225,162,167,210,180,192,211,195,150,110,219,186,190,168,211,226,166,196,94,81,240,243,254,174,48,79,106,111,51,57,39,17,47,164,229,153,117,201,205,243,160,146,236,175,171,179,206,220,138,98,177,191,129,147,177,230,217,137,99,167,210,238,245,229,216,218,217,240,213,187,222,227,221,247,253,251,254,116,55,35,47,127,153,144,77,41,36,47,109,137,148,138,119,122,143,120,76,5,37,118,92,136,86,33,38,18,20,24,27,43,78,114,101,100,120,102,89,32,35,75,100,73,38,1,53,90,95,64,49,35,106,85,73,30,15,55,120,129,112,62,59,122,140,129,95,105,96,104,96,153,156,136,145,138,66,150,224,241,253,251,228,187,138,151,203,212,245,205,155,135,132,160,190,170,116,96,77,78,93,63,84,49,59,47,66,66,63,45,54,76,70,47,23,40,43,26,4,29,49,17,33,27,37,47,17,18,29,56,66,31,30,33,54,75,43,28,74,58,53,49,34,35,49,78,152,103,98,95,69,46,32,12,34,99,55,61,55,42,37,77,77,102,76,98,81,108,150,101,83,98,79,101,74,49,24,86,126,180,159,148,92,78,132,121,104,60,34,53,91,205,215,220,236,233,233,242,226,245,221,235,242,216,237,231,219,211,239,244,239,229,244,218,236,237,203,226,219,228,243,221,235,218,226,225,243,234,228,236,238,215,211,248,205,212,227,227,202,212,228,220,223,228,122,26,12,0,17,6,9,16,17,7,30,12,14,12,0,0,18,21,0,7,12,15,30,17,3,192,189,210,199,209,176,211,210,215,194,213,230,203,212,216,180,196,194,205,185,187,229,200,200,220,197,223,204,198,192,181,215,218,206,198,206,197,191,205,208,220,210,196,193,204,203,164,205,209,207,192,214,217,213,236,209,213,194,211,187,219,184,214,224,210,209,187,214,213,183,189,217,190,185,214,189,211,190,194,191,208,196,183,195,194,185,195,189,211,214,231,198,201,206,185,211,193,227,227,191,203,207,190,207,228,218,201,231,223,181,224,185,225,217,197,201,227,194,217,213,194,210,214,234,217,188,226,209,212,222,190,218,208,221,180,197,202,224,205,200,213,203,214,206,214,216,195,198,207,212,212,197,226,207,207,208,226,211,217,189,230,205,204,194,194,190,188,219,203,221,211,209,239,219,211,199,203,218,197,218,206,224,215,211,188,199,233,221,216,182,189,213,212,211,209,225,240,220,199,236,214,224,180,231,198,193,204,216,214,229,203,215,204,232,233,213,205,185,201,205,214,206,207,221,242,205,216,190,222,239,244,220,199,227,210,215,217,225,218,225,237,220,215,213,209,240,227,217,231,215,209,232,214,214,177,217,228,219,219,202,238,209,223,235,225,227,244,231,212,208,217,242,230,234,218,213,221,231,228,211,224,223,223,217,227,249,205,221,237,207,252,246,223,238,235,225,244,235,211,237,216,249,233,255,247,191,185,165,155,185,183,207,225,243,238,240,228,241,224,250,159,73,175,227,176,167,146,87,151,239,244,244,248,218,248,251,204,225,246,203,213,204,196,189,142,155,154,128,85,115,205,237,197,44,5,4,132,224,225,210,223,209,218,228,238,230,192,167,155,177,182,203,190,197,198,187,216,156,167,193,186,158,140,228,183,172,204,238,238,194,188,88,125,244,239,235,187,67,70,124,132,41,47,84,22,65,206,237,176,157,223,215,240,189,160,246,229,173,141,147,209,147,92,228,235,147,126,181,253,197,83,110,197,240,219,253,226,248,238,228,243,195,164,224,243,250,244,249,239,128,41,1,9,38,79,113,166,139,69,65,35,33,80,140,100,53,54,136,138,86,27,70,120,110,140,100,35,24,15,23,57,33,87,113,99,49,75,105,128,97,43,23,64,103,64,59,0,30,64,83,69,84,110,138,156,120,134,123,152,143,177,138,133,165,132,126,102,126,131,113,125,117,127,140,116,88,112,78,182,249,245,252,251,221,179,150,163,200,253,226,177,104,110,131,171,224,152,128,92,96,65,31,58,55,59,41,52,58,68,57,52,64,67,58,67,46,34,67,47,42,72,69,34,64,59,35,38,29,47,71,61,69,37,11,40,82,67,65,80,50,58,52,6,53,67,54,72,104,92,77,40,20,24,41,35,79,105,84,43,20,17,15,34,20,59,67,64,92,104,112,93,84,51,109,146,120,69,58,21,69,70,84,85,51,95,139,129,67,74,49,47,102,208,227,218,248,238,238,235,247,237,245,219,219,248,201,238,231,238,218,233,221,221,229,222,235,247,232,243,226,244,220,244,214,223,241,202,217,248,231,208,211,223,227,217,211,227,214,213,218,205,215,225,232,223,131,4,9,26,0,1,11,19,16,0,10,16,11,9,7,14,30,8,30,0,2,4,36,0,15,209,185,200,185,219,193,222,198,191,195,195,182,205,197,188,195,202,221,222,201,230,213,183,191,224,200,207,201,197,206,179,199,208,216,204,221,199,185,197,198,218,180,214,202,215,230,234,170,193,200,222,213,204,206,208,199,215,197,223,197,228,193,213,182,195,198,216,211,191,229,189,212,211,185,218,221,205,200,193,193,226,182,211,190,173,224,192,202,189,214,219,198,198,188,206,183,191,229,208,189,221,204,200,169,211,199,194,227,210,232,183,205,189,201,199,200,201,214,220,224,217,193,223,211,185,235,209,207,197,176,205,207,212,195,218,214,205,209,206,206,218,207,172,232,212,204,213,213,210,215,197,205,200,186,170,186,229,198,200,215,207,207,205,231,190,198,206,197,215,194,218,215,186,203,211,197,193,199,208,213,219,230,213,196,229,203,194,210,191,201,212,208,201,216,205,218,210,235,180,226,208,200,211,207,225,224,215,205,204,194,196,220,219,183,210,220,217,197,225,201,214,213,233,214,233,211,192,201,217,234,221,204,213,204,208,210,217,221,210,220,217,220,202,198,209,198,224,196,212,204,204,212,202,194,207,217,228,210,203,232,232,209,219,211,224,207,230,230,224,228,221,230,233,214,213,228,231,213,226,228,233,223,226,211,230,198,239,235,245,227,211,243,228,228,233,245,228,238,231,227,234,219,197,207,183,178,182,199,194,216,221,238,248,242,230,238,208,250,243,213,183,84,159,225,177,160,98,90,131,207,200,239,182,172,223,208,193,207,226,191,132,97,141,121,139,154,161,187,147,148,170,160,139,65,12,14,106,232,254,213,239,228,244,232,230,205,224,197,181,178,182,202,214,204,147,147,162,108,188,197,208,190,188,251,210,228,243,248,240,202,183,59,94,235,247,253,176,59,105,122,108,67,41,43,43,100,200,252,201,156,226,231,254,192,202,247,231,179,85,170,255,120,49,198,255,188,128,159,248,198,53,137,214,241,243,241,210,229,239,246,229,171,190,247,240,246,252,242,160,44,5,28,13,35,32,70,116,109,151,104,87,22,13,76,107,46,9,41,92,80,18,80,131,127,160,75,20,41,24,49,43,55,103,112,120,73,51,83,38,115,88,92,115,97,73,57,91,128,133,145,154,157,172,180,150,141,148,145,153,123,108,141,115,131,112,96,137,117,114,102,104,106,101,95,87,93,63,80,213,241,244,245,250,213,144,188,210,237,244,201,164,113,133,120,184,233,147,81,81,75,65,77,54,79,46,77,61,78,73,85,54,78,69,59,68,73,61,61,48,51,48,65,69,60,53,53,77,59,67,76,80,75,62,41,31,45,85,68,109,71,53,24,7,49,69,79,56,98,55,31,7,27,15,31,28,65,70,72,63,25,37,1,12,45,40,10,25,34,43,96,109,71,74,48,106,140,115,71,61,37,50,60,49,110,107,147,117,67,45,68,78,119,234,234,244,223,241,238,238,232,211,247,240,220,187,223,220,241,234,224,228,216,234,236,233,244,208,245,223,233,217,212,216,240,223,238,222,229,228,240,225,230,230,204,207,225,216,217,225,229,247,221,227,229,244,112,11,14,41,2,13,7,17,6,6,10,24,22,14,7,6,0,7,8,9,5,14,0,8,1,209,192,199,194,199,213,224,207,179,183,211,216,191,212,226,185,222,198,207,190,197,205,177,194,192,209,190,210,202,212,204,194,220,223,205,209,225,197,217,204,199,186,177,197,203,196,205,203,220,229,206,211,201,186,184,215,207,201,205,195,195,193,193,212,194,214,189,212,205,183,222,194,204,188,189,198,225,185,225,212,213,209,211,229,211,202,190,203,205,214,198,180,204,234,191,186,200,211,219,197,219,204,229,208,201,210,206,205,186,205,209,215,208,190,194,227,198,217,198,201,211,198,225,207,231,207,203,207,190,203,209,215,185,196,193,227,209,184,222,225,196,209,201,228,207,212,203,227,211,204,184,196,196,215,231,177,189,203,199,204,210,187,200,191,200,184,195,194,214,203,210,188,202,210,206,188,212,199,210,211,220,180,201,200,224,214,227,203,206,201,217,211,215,220,207,196,210,223,228,224,223,223,210,194,208,212,211,239,203,204,233,231,217,204,222,215,215,220,217,205,238,211,223,234,213,222,207,208,227,202,235,213,222,213,210,200,204,231,216,204,196,218,213,215,182,233,194,225,234,195,217,218,219,205,197,223,205,201,224,215,212,208,202,223,236,225,238,221,241,234,220,222,228,219,214,223,235,205,237,227,231,237,228,251,233,200,240,218,248,232,242,209,218,246,207,227,234,227,232,214,208,164,170,186,204,234,213,229,255,236,248,215,223,229,238,240,209,220,222,230,174,93,148,235,202,170,127,95,111,146,129,149,129,125,164,143,151,196,200,128,89,97,131,124,154,172,158,172,169,164,147,175,149,93,34,46,159,241,255,220,255,210,234,221,238,222,225,211,178,218,176,177,149,157,156,134,194,153,206,253,225,247,199,235,194,197,167,154,127,90,107,19,53,194,255,234,146,69,70,128,89,72,42,74,10,77,238,241,240,161,181,253,226,185,191,248,216,131,142,232,238,129,91,236,235,233,136,97,153,172,91,140,233,225,238,249,233,230,232,248,218,136,182,228,243,239,254,187,61,0,9,6,19,68,57,20,40,105,118,158,94,41,45,55,104,102,34,27,41,54,45,112,134,109,127,49,41,48,19,27,58,57,108,97,91,52,38,49,77,134,124,157,120,120,165,159,162,152,139,148,132,102,164,140,122,119,111,103,104,53,83,33,56,81,70,66,53,46,62,71,33,19,62,55,46,47,20,50,240,248,247,248,251,223,168,192,243,255,247,165,138,140,145,163,219,211,109,68,15,23,19,52,20,24,37,21,45,54,64,58,48,55,56,58,82,74,95,42,78,67,62,50,67,31,63,76,50,53,83,72,66,82,52,95,67,65,82,80,67,58,30,26,31,46,93,70,108,98,78,53,51,21,27,35,46,92,83,62,41,28,28,35,16,15,5,17,38,4,61,88,105,88,49,34,68,127,136,122,110,108,76,72,116,140,104,98,56,32,48,62,92,207,230,241,240,225,207,226,229,213,223,236,236,248,209,239,228,249,229,247,247,235,222,211,226,225,226,224,230,239,208,238,240,221,231,239,229,219,204,209,225,224,226,214,233,226,215,211,220,235,213,199,208,231,228,123,18,18,1,11,28,3,5,32,17,8,24,9,15,3,2,0,0,18,5,11,10,27,8,16,177,208,201,164,186,172,195,202,196,211,203,214,171,173,186,176,200,190,202,208,196,218,194,190,205,204,187,204,213,157,201,182,192,207,196,202,179,192,207,211,205,199,197,208,221,198,180,223,189,176,196,185,218,204,197,170,202,202,192,198,197,180,206,205,196,210,214,183,208,205,199,195,188,178,210,210,192,202,216,198,204,204,190,207,196,192,226,204,193,188,203,160,216,215,216,185,186,196,199,229,208,199,194,189,219,215,201,194,196,219,207,187,179,215,181,193,199,204,214,204,198,196,233,232,200,212,237,212,221,216,211,203,199,216,236,197,225,201,205,220,226,205,215,211,215,209,208,192,204,202,198,217,220,207,193,227,207,199,232,217,187,200,214,191,202,199,183,206,221,164,199,221,213,219,194,213,231,213,213,197,199,211,203,193,192,210,238,215,205,197,200,205,226,231,193,224,201,207,214,223,210,209,242,215,184,229,208,223,203,215,207,239,231,221,214,221,193,198,210,229,198,213,198,203,225,210,222,208,197,218,228,220,214,235,208,198,198,224,248,213,214,219,210,198,239,224,205,215,197,202,217,219,189,214,215,237,193,204,210,234,225,215,197,219,218,207,229,209,226,228,222,228,213,233,219,226,239,229,235,210,202,229,249,221,236,237,235,231,208,215,232,237,248,253,239,214,210,207,194,171,183,196,217,205,231,231,243,243,226,249,227,237,216,215,195,231,230,221,234,223,180,69,160,233,220,199,63,91,115,176,155,170,134,120,133,156,119,137,164,86,118,103,99,92,131,127,134,162,124,154,161,121,145,88,95,94,131,197,223,214,246,246,229,218,212,191,232,153,137,212,158,218,156,219,226,180,222,234,238,252,225,238,152,147,98,84,41,17,3,18,39,36,24,89,128,124,75,52,36,105,97,79,47,44,25,73,157,223,136,67,127,206,178,173,142,134,110,68,125,224,197,70,94,195,225,192,156,43,83,143,123,231,241,219,241,220,225,226,241,231,243,158,229,246,241,252,219,124,1,0,19,9,40,46,33,19,23,49,95,101,137,104,40,18,94,99,89,38,55,42,11,123,125,108,142,53,23,9,24,26,53,109,138,125,108,112,116,117,153,134,139,128,151,118,159,143,114,147,118,105,121,121,109,114,76,79,53,64,53,28,35,26,21,19,56,49,42,31,43,12,16,53,29,49,48,55,8,92,212,250,255,253,252,165,144,211,238,202,192,137,114,120,122,156,223,168,74,6,11,22,44,11,51,38,17,42,47,37,34,16,4,38,19,22,14,40,45,15,43,59,42,56,39,52,44,50,46,66,36,57,55,54,71,53,82,83,61,80,69,74,67,122,44,83,121,104,112,77,38,44,12,37,16,37,64,108,96,55,8,43,33,29,41,19,50,18,40,17,33,74,102,89,73,65,41,41,112,122,180,167,166,152,147,116,96,82,37,36,72,67,162,234,243,247,234,228,235,239,237,233,214,205,229,213,242,233,230,225,215,244,221,223,221,239,237,231,232,238,217,226,233,231,212,221,248,236,245,230,238,222,239,212,224,234,212,235,239,215,192,244,224,222,238,202,216,132,0,16,6,0,7,15,16,15,5,41,29,19,5,0,8,34,1,20,38,13,22,0,6,12,197,192,189,183,208,166,202,189,180,187,192,201,184,190,194,196,202,204,194,212,192,204,198,190,193,190,188,182,207,188,200,191,209,199,196,209,212,202,185,191,217,195,170,207,231,204,205,191,155,189,198,226,187,210,212,202,191,199,199,237,201,195,168,204,180,201,211,209,200,189,184,217,188,233,204,214,203,210,201,200,223,205,209,183,188,230,174,220,206,214,206,202,209,197,195,171,217,208,208,189,220,194,209,216,217,212,204,216,208,224,219,210,192,195,206,186,186,193,188,220,180,194,212,189,199,217,213,191,194,198,221,195,188,203,216,205,214,187,223,212,208,204,216,214,199,193,225,222,228,227,206,213,206,206,205,215,202,180,205,215,210,220,193,208,203,190,218,235,211,205,217,194,218,202,217,204,178,214,187,226,181,205,213,229,196,226,197,226,212,203,220,192,222,238,217,184,230,216,207,221,216,203,192,224,226,201,226,207,213,198,211,198,194,218,219,206,182,209,224,224,204,200,220,226,212,198,192,200,212,224,212,209,210,195,226,208,209,211,226,196,231,216,204,233,219,227,208,228,206,221,206,214,202,200,196,205,200,219,240,225,177,216,186,231,237,222,208,181,224,215,228,242,209,222,235,210,213,233,227,231,226,206,219,217,205,212,222,234,230,217,231,225,234,217,195,188,156,199,199,167,223,229,246,228,222,224,226,220,232,233,213,225,230,206,217,220,214,227,222,235,200,96,109,224,190,172,36,65,101,162,181,194,162,162,163,146,125,161,147,104,94,96,64,70,54,85,75,93,90,92,101,93,78,81,84,71,97,188,160,200,220,213,251,240,226,187,237,163,163,196,144,212,200,248,247,203,191,150,122,116,93,93,47,25,26,52,108,131,109,147,119,86,143,162,169,183,103,57,52,91,97,62,70,50,22,21,110,155,146,83,82,148,151,126,123,30,76,62,130,159,115,93,126,137,179,183,110,48,39,69,126,228,246,216,240,223,243,226,239,247,206,153,237,252,234,240,140,32,5,25,26,32,54,34,24,13,35,65,62,91,73,114,34,40,36,91,152,120,103,72,83,170,118,117,124,30,59,27,85,127,147,159,124,118,98,112,128,129,119,116,135,153,129,155,143,124,96,88,83,40,64,36,22,8,55,35,37,69,14,46,24,22,58,43,62,53,37,40,15,38,20,63,44,60,92,89,7,182,245,237,241,225,154,104,156,233,249,229,134,130,104,109,122,205,209,125,39,21,29,15,54,34,13,17,39,47,51,59,49,26,22,51,41,35,32,51,67,25,29,24,34,25,30,24,26,44,25,39,26,43,60,63,36,84,62,79,63,56,62,80,94,122,104,107,104,102,90,72,56,48,52,32,41,36,77,84,84,76,27,38,34,45,44,46,31,32,18,24,64,97,93,127,89,31,32,120,141,101,95,81,137,142,62,75,55,64,37,73,56,156,234,237,247,247,220,234,238,209,221,228,223,246,235,234,231,221,236,214,219,245,220,234,216,234,244,246,234,240,219,217,247,241,229,222,215,200,233,246,221,225,217,208,229,196,225,230,212,231,212,209,237,231,223,217,228,115,15,8,26,41,3,25,37,28,2,22,23,6,9,0,3,5,27,21,21,12,29,16,8,40,193,177,172,192,178,210,185,170,191,206,192,182,217,210,198,216,204,198,200,194,189,198,221,203,197,192,195,178,202,192,196,187,204,185,221,182,200,189,190,204,191,202,209,187,213,190,202,205,191,193,202,193,194,197,181,209,198,185,212,188,182,198,199,193,233,197,198,212,202,192,185,198,194,210,192,222,199,199,184,205,204,210,209,212,191,195,187,207,188,190,221,202,206,202,206,212,188,198,210,185,212,191,208,194,203,197,182,187,223,207,197,187,222,217,190,201,218,189,196,201,237,208,186,207,204,197,190,177,197,232,200,202,188,225,195,206,184,221,205,196,209,190,218,172,169,215,173,216,197,219,206,193,191,219,188,198,202,213,211,193,214,169,215,193,214,199,210,192,189,203,228,204,200,197,213,191,216,235,207,208,215,211,201,204,190,232,197,214,203,206,209,206,191,190,228,186,210,197,196,202,216,176,214,209,198,223,187,201,199,206,231,217,206,189,216,190,212,203,211,210,224,186,223,225,205,200,207,201,211,200,225,204,207,241,202,232,202,218,210,196,221,219,188,224,196,243,224,204,204,230,187,213,188,210,225,206,193,224,205,222,211,228,229,223,212,214,218,198,222,221,215,224,229,233,220,234,207,243,227,215,211,210,218,238,237,226,213,207,224,209,192,184,182,184,172,193,214,201,220,227,242,236,224,229,229,238,237,209,222,232,224,206,216,237,222,224,214,215,226,233,200,58,123,184,233,154,54,102,109,190,163,174,166,156,201,180,144,168,172,91,120,96,84,86,71,55,34,63,69,48,59,55,89,76,75,40,72,151,176,137,185,196,226,219,218,219,242,172,189,235,143,151,168,209,175,57,40,30,28,20,4,38,44,55,67,76,118,135,190,170,143,156,151,179,223,211,111,58,62,107,98,40,28,34,28,80,204,245,181,123,188,206,174,197,177,149,170,162,218,185,125,192,211,204,202,192,129,74,67,53,99,231,248,213,247,242,228,235,230,251,198,147,243,248,241,171,22,12,37,25,16,54,35,36,33,25,53,34,94,97,97,109,98,32,41,33,86,114,156,158,157,160,107,113,135,121,171,178,171,194,137,130,112,134,140,146,137,120,151,108,90,91,67,59,38,30,26,42,17,51,35,47,35,30,17,45,62,92,66,65,74,29,41,59,89,27,28,49,24,41,41,55,60,33,69,70,99,252,246,240,242,194,149,156,208,250,247,201,141,136,130,116,149,230,206,98,13,9,30,30,37,44,35,30,17,31,43,14,42,34,25,70,15,30,47,75,22,28,33,31,52,17,3,19,21,10,12,20,24,35,29,26,31,14,53,34,63,61,80,69,69,84,64,83,97,92,93,93,103,105,81,78,90,142,110,107,87,62,42,15,20,42,37,35,25,32,29,27,69,76,99,107,70,24,82,135,77,63,18,44,76,99,77,42,47,58,11,53,148,235,227,251,231,233,203,239,239,237,238,223,242,228,203,221,216,238,232,230,245,255,218,223,237,226,229,219,222,223,229,212,215,220,218,209,240,215,229,232,197,238,211,237,239,240,178,253,240,229,211,223,212,213,213,209,208,131,4,3,17,7,12,23,5,7,28,19,5,7,2,0,14,15,32,37,21,0,23,0,21,28,204,210,166,195,207,192,188,185,200,193,202,190,194,193,211,221,227,199,188,180,200,192,201,212,201,193,205,220,173,211,220,205,199,208,215,192,228,189,228,201,201,226,203,177,211,180,198,197,191,190,212,194,184,201,211,187,216,183,205,218,191,205,220,213,222,204,200,214,181,192,184,187,205,213,192,200,208,197,207,194,203,166,196,213,195,224,213,196,224,191,191,187,197,177,217,201,208,201,215,201,217,210,187,186,208,199,216,175,217,227,222,206,185,186,202,189,187,224,207,215,199,226,216,225,214,188,217,202,174,201,224,194,207,216,199,236,206,201,231,197,207,179,195,214,182,198,205,196,203,201,221,196,218,209,213,196,211,207,203,197,196,190,204,173,210,208,208,180,202,227,205,228,221,206,203,203,201,229,213,205,202,197,217,211,203,203,210,216,210,218,226,221,206,199,208,202,232,207,190,209,209,202,192,196,193,202,218,216,221,195,220,200,201,217,193,188,208,211,199,195,208,221,204,201,191,206,223,224,207,198,201,201,207,199,221,199,242,200,197,214,222,194,220,214,220,200,206,212,215,205,234,203,218,207,203,209,199,214,220,195,206,238,224,193,184,226,218,209,218,232,217,206,232,221,216,209,221,211,234,229,218,238,219,228,218,247,224,176,189,204,153,180,203,186,210,206,230,235,234,228,225,210,224,218,224,225,213,208,226,236,206,231,220,224,195,222,221,244,210,220,209,40,109,228,225,218,122,156,149,160,160,150,132,192,199,153,145,122,128,116,122,96,73,63,59,66,52,63,69,66,63,62,75,97,85,51,85,161,141,83,82,121,182,224,215,229,243,166,204,241,125,69,14,31,55,0,24,55,118,124,146,161,212,203,203,170,159,118,130,133,113,110,87,118,150,169,117,58,49,131,147,61,47,61,41,67,138,194,111,50,134,148,133,168,128,160,170,116,126,123,89,133,102,117,150,117,153,115,66,66,146,234,239,251,247,253,214,243,245,254,189,178,236,246,209,39,34,1,9,16,59,40,5,25,20,45,59,45,81,122,99,106,93,57,65,34,27,45,53,73,110,154,87,143,153,119,161,145,142,139,116,158,118,120,97,73,49,46,64,37,18,37,57,48,25,17,17,12,24,53,34,57,83,63,54,42,74,113,46,78,79,83,58,72,66,49,25,33,41,64,66,51,63,58,64,48,154,237,247,254,241,188,163,149,241,246,254,133,123,96,131,129,169,235,151,86,91,67,82,64,48,56,27,44,39,14,59,68,55,39,68,57,30,42,42,42,32,50,69,62,45,13,18,27,15,17,10,46,36,55,62,22,28,9,26,26,37,23,42,18,33,54,54,57,97,97,91,58,58,103,86,93,100,111,116,93,84,68,43,59,57,26,10,41,51,33,31,30,63,81,78,105,59,55,41,71,60,41,50,96,91,64,66,79,60,21,112,234,251,245,250,247,238,230,227,230,224,226,216,235,235,246,229,236,225,237,221,239,245,233,218,234,224,234,228,216,230,224,229,201,237,209,209,251,201,209,229,229,216,233,233,220,233,219,234,232,234,238,222,240,226,222,217,221,222,129,6,1,8,3,12,7,0,4,27,5,19,11,9,0,25,34,2,19,15,22,14,5,19,23,199,182,207,200,180,177,155,197,185,187,186,208,216,205,203,188,199,222,189,198,189,216,206,179,192,197,208,215,199,201,177,204,193,189,205,206,207,189,205,220,179,191,176,226,195,216,183,198,215,199,198,208,231,199,184,205,196,198,216,200,178,217,199,227,205,208,198,200,186,197,189,201,196,219,203,195,205,193,183,207,208,209,204,204,215,218,217,217,205,205,204,198,193,214,178,178,219,198,195,176,211,195,189,194,211,176,199,218,198,214,213,204,198,197,204,201,215,172,199,207,198,201,182,197,204,204,201,206,195,207,193,202,205,194,209,167,176,194,194,182,188,208,219,187,205,229,187,217,196,215,222,207,217,208,226,206,210,207,217,198,236,203,203,213,212,177,218,188,215,174,202,186,192,193,211,215,206,213,192,231,201,214,214,199,198,190,214,199,216,200,231,209,229,220,202,202,189,215,189,211,209,227,204,194,193,175,217,191,186,222,206,209,208,208,197,187,208,187,216,230,225,227,212,197,215,209,212,204,207,217,207,187,202,211,230,199,205,184,241,186,212,178,198,223,200,227,217,219,220,221,228,205,182,246,202,203,196,230,214,209,197,208,235,214,210,208,208,213,220,223,200,206,222,215,224,214,201,207,218,232,237,246,235,245,222,222,187,203,152,196,221,213,239,224,226,240,233,228,223,210,217,199,212,224,238,231,233,226,229,227,226,228,220,223,211,221,219,227,226,231,180,50,95,200,238,224,151,148,152,170,166,183,165,161,169,113,102,126,151,95,138,94,90,84,53,61,63,62,49,73,67,69,62,45,72,51,56,107,104,123,143,199,216,212,215,207,238,146,207,243,160,87,118,108,67,96,202,219,216,253,226,255,228,233,240,197,233,226,201,98,99,148,117,184,185,200,165,26,48,72,117,53,32,50,34,58,104,153,132,84,70,67,125,171,146,112,99,93,104,61,53,130,111,115,133,121,167,165,84,30,118,238,223,231,218,239,234,218,226,229,190,234,253,174,78,5,10,18,3,45,41,40,5,13,44,57,50,34,34,62,130,98,88,95,100,63,56,67,62,22,50,94,90,148,111,126,135,116,111,103,66,41,48,53,46,46,17,50,21,25,18,55,48,52,32,39,28,31,52,40,40,46,102,71,54,54,88,87,58,40,54,112,151,151,90,79,107,96,123,130,129,97,115,109,144,122,84,190,248,252,241,212,173,116,188,233,209,112,123,130,135,145,226,235,137,57,126,131,142,50,101,74,64,72,62,60,54,46,64,78,67,51,23,38,79,60,63,46,48,24,18,33,12,25,37,24,28,26,44,50,62,37,11,24,57,47,52,57,56,39,17,2,15,37,48,44,43,75,71,96,82,90,74,50,71,70,107,103,94,104,68,66,45,55,36,14,21,20,47,92,121,102,71,49,39,33,46,85,97,92,79,64,49,52,70,194,228,240,255,232,238,243,224,223,213,218,234,221,225,214,225,240,245,234,214,238,240,227,222,226,235,220,230,242,243,220,224,216,225,224,209,233,220,231,235,230,232,220,207,254,233,230,223,211,228,240,226,238,217,216,240,236,216,207,228,101,19,3,4,25,0,9,20,11,9,1,21,15,5,1,14,2,10,14,7,17,3,28,14,17,200,226,205,198,194,161,187,180,197,192,179,198,194,187,181,173,186,193,194,200,194,179,186,200,197,204,189,208,181,194,208,193,166,197,209,207,200,188,198,202,189,211,188,216,197,200,214,214,206,218,228,201,195,208,226,174,206,219,180,182,192,182,184,201,193,217,204,199,193,179,214,187,186,204,182,164,198,208,195,176,195,204,179,179,188,179,205,199,202,187,215,194,208,204,219,227,207,207,202,200,194,195,203,221,238,197,163,203,192,177,201,205,223,207,201,188,184,198,218,198,191,192,187,201,235,185,208,203,193,192,201,201,209,210,204,199,215,197,206,186,199,223,225,224,204,213,187,191,188,197,234,199,196,202,205,210,199,193,231,201,211,200,205,225,204,200,192,198,209,192,219,220,207,195,217,204,207,203,212,194,200,188,218,197,182,214,187,219,220,204,200,194,200,220,179,214,191,190,211,183,195,191,214,214,188,208,214,213,207,206,208,227,198,192,197,215,188,241,222,200,216,211,184,204,219,205,230,202,203,200,188,179,208,215,222,215,241,178,215,169,195,212,212,188,217,184,193,183,222,232,227,218,217,249,211,199,231,218,213,201,211,211,222,221,227,199,215,216,221,226,219,208,208,202,220,233,233,222,224,234,248,233,182,171,153,178,187,209,192,224,222,244,223,237,219,231,218,224,248,222,217,209,205,206,225,231,241,223,209,232,210,219,223,213,219,236,222,226,203,222,171,53,89,172,248,213,156,164,143,190,176,165,157,147,162,130,136,169,134,116,82,9,24,31,56,26,11,42,48,78,27,50,82,87,62,28,26,54,106,191,221,247,244,234,210,216,226,144,206,230,196,193,229,234,213,186,243,239,239,255,243,238,240,226,215,213,180,216,189,102,115,170,182,240,242,252,198,83,63,90,113,41,29,47,42,91,213,244,228,147,112,199,252,254,200,160,139,148,221,101,88,230,227,239,217,203,237,190,154,75,102,227,225,235,230,214,229,237,221,225,196,228,228,106,42,5,21,5,29,58,18,23,36,65,48,50,54,21,78,113,119,110,102,120,123,124,98,75,63,26,83,128,87,152,121,70,53,44,6,57,40,23,11,48,67,63,49,75,46,40,55,43,69,59,29,30,37,55,49,60,36,46,68,119,154,197,168,147,135,146,176,145,196,164,131,150,121,141,141,120,104,61,99,45,59,39,66,20,133,210,255,219,155,88,172,249,188,142,147,134,122,165,226,196,123,35,11,35,29,31,60,16,52,61,18,27,53,34,42,70,68,68,85,71,82,67,58,67,68,47,48,46,20,46,65,11,34,34,34,74,44,38,28,59,54,42,52,67,35,19,4,35,62,33,25,28,36,9,23,37,27,39,69,49,87,72,100,76,86,101,105,101,107,94,63,75,68,38,89,65,105,106,102,44,49,83,117,125,115,80,78,21,42,83,208,251,231,255,241,221,240,219,217,220,219,230,234,215,238,221,249,229,224,243,238,219,216,226,207,207,251,238,207,219,225,226,235,224,227,213,214,244,210,220,234,241,226,232,216,235,232,244,225,223,211,235,233,222,231,215,241,220,209,236,231,139,2,14,2,2,20,16,5,15,25,17,19,10,11,5,0,8,14,7,18,0,6,14,27,5,207,186,179,189,225,221,172,223,223,208,186,208,161,193,187,185,185,162,179,191,187,199,205,213,161,188,209,186,201,206,203,220,197,195,186,192,185,215,196,200,187,201,183,212,186,201,181,213,184,204,188,194,192,180,203,214,224,189,202,199,186,208,216,219,213,187,189,202,187,208,206,189,195,207,175,180,203,189,197,206,199,186,196,197,197,191,205,220,200,197,214,211,203,195,194,199,192,194,208,200,196,202,206,216,202,196,212,192,193,194,212,188,194,181,197,193,208,208,190,207,175,200,212,187,171,186,214,213,206,205,190,214,190,202,169,203,199,187,180,184,195,222,199,202,188,200,201,200,215,215,195,198,221,194,203,225,231,235,213,194,217,200,189,213,214,209,197,216,219,228,227,219,203,213,197,206,226,207,197,206,206,176,199,224,192,220,188,196,189,194,206,185,211,206,213,207,201,198,197,231,191,210,185,209,188,207,194,201,206,182,200,205,211,218,215,189,188,194,187,197,177,215,202,212,207,218,211,204,201,200,202,192,203,203,214,215,203,195,187,208,206,201,211,211,190,185,190,215,218,184,203,198,142,191,175,191,238,214,205,196,212,212,213,211,205,204,223,214,207,224,208,190,232,215,227,224,242,235,226,218,188,173,164,160,185,220,205,215,225,233,201,228,207,240,212,219,233,226,246,234,210,203,219,231,218,210,229,201,214,214,238,209,230,238,202,218,200,230,212,231,141,51,68,178,238,217,174,131,168,195,193,177,153,152,187,167,154,177,137,85,5,5,10,19,17,16,10,34,34,19,6,45,52,59,12,15,110,117,179,178,234,233,227,205,191,219,239,148,218,214,172,215,250,203,196,215,249,232,227,225,218,185,190,195,140,143,153,214,155,112,158,160,178,206,232,247,156,73,66,92,122,48,28,26,18,78,232,246,246,165,133,225,254,233,172,176,199,224,235,143,148,242,233,222,188,197,241,224,189,96,63,199,199,238,233,227,244,206,244,213,192,237,123,12,34,1,28,27,56,19,30,28,26,40,48,69,22,83,202,166,137,81,51,89,105,109,107,130,110,77,116,125,102,151,85,36,28,43,15,32,54,49,24,58,72,76,56,60,58,63,45,75,74,62,30,38,58,95,140,158,162,196,131,197,194,208,198,174,149,128,126,106,69,61,20,52,46,55,23,41,17,12,48,17,28,35,35,31,7,94,146,183,139,109,176,241,142,130,150,133,139,181,241,171,60,20,1,22,24,19,19,32,7,17,21,26,22,23,5,38,28,27,42,15,37,61,49,45,57,74,67,50,67,66,78,60,69,64,41,60,53,75,67,29,43,28,60,73,29,39,55,98,38,37,49,40,15,34,26,7,18,25,50,56,41,48,61,84,69,63,73,96,90,88,101,91,86,103,92,90,103,94,91,133,145,178,151,125,45,26,54,34,89,220,241,252,242,251,236,228,233,209,240,205,219,240,218,234,230,237,241,233,234,240,241,236,243,222,231,241,198,209,203,226,222,213,239,246,215,216,217,214,227,239,214,223,231,233,222,233,227,230,219,249,220,228,207,230,223,238,234,219,213,241,243,131,3,0,8,14,2,15,17,11,2,5,7,14,7,5,10,0,12,8,13,9,14,23,15,27,219,205,167,196,200,171,195,181,201,187,202,191,214,200,212,187,190,199,189,191,206,198,210,178,192,209,191,177,197,175,194,196,193,192,177,197,191,182,190,211,194,208,206,210,192,186,174,171,201,168,172,209,205,201,193,198,210,205,218,177,197,206,185,186,192,198,209,190,191,200,204,189,201,188,187,173,192,203,175,201,209,193,173,190,194,212,172,201,199,188,212,218,197,197,197,199,180,203,217,207,196,231,190,210,188,195,196,208,205,190,196,196,211,199,212,202,217,208,225,191,206,202,224,194,194,210,193,209,169,218,210,212,180,196,196,211,187,207,219,203,217,194,188,180,199,220,194,208,207,193,189,214,209,201,180,208,215,207,209,204,209,202,177,209,199,217,229,209,211,196,189,225,214,193,210,208,206,174,216,186,199,209,180,184,169,212,216,197,220,193,181,206,225,170,190,199,203,202,201,195,209,187,221,213,192,183,202,195,229,236,196,203,203,186,195,205,183,192,182,203,199,200,196,212,186,183,204,194,190,194,199,206,198,190,196,198,183,226,205,212,208,225,234,232,186,211,226,211,218,198,208,128,41,71,151,212,197,218,184,224,212,222,204,205,204,199,197,226,219,231,243,207,229,226,237,205,193,203,173,173,205,189,216,210,216,241,217,240,239,247,221,215,215,195,229,225,236,200,221,199,206,211,222,227,241,220,224,199,215,212,211,215,238,214,230,237,216,225,220,215,136,49,141,227,249,230,166,148,160,178,162,177,172,174,205,175,174,173,141,48,15,8,28,33,47,18,20,29,57,27,27,63,76,55,28,53,130,224,221,208,228,250,237,216,209,234,243,148,197,208,206,218,191,156,138,203,214,197,169,166,127,151,174,162,128,153,211,247,114,120,165,159,174,192,229,247,171,68,42,83,111,53,25,47,7,72,199,234,210,152,118,228,244,183,99,187,200,174,162,164,204,242,225,240,161,198,228,211,199,129,88,210,214,221,251,239,230,228,244,212,196,124,35,31,24,18,42,62,18,11,23,38,48,60,54,21,66,196,254,233,169,83,57,66,52,80,72,81,81,74,122,130,141,94,54,2,10,3,12,50,75,76,16,51,87,97,21,22,58,87,133,161,128,160,180,185,191,195,203,210,174,186,140,120,121,61,39,49,35,24,6,19,33,36,14,17,15,35,21,24,19,20,30,9,29,20,7,21,35,0,43,143,143,126,191,209,127,133,140,123,150,200,232,129,28,19,2,29,18,4,32,27,10,24,44,12,33,24,28,32,7,3,17,11,21,1,39,4,12,44,21,44,60,47,34,52,44,39,51,92,78,76,62,66,68,53,68,92,57,57,61,64,25,44,26,51,15,43,49,33,43,66,79,66,36,16,21,28,41,44,47,86,70,85,93,85,97,97,108,99,84,105,105,96,114,84,67,58,65,29,59,77,191,246,252,235,221,229,217,243,232,239,214,221,236,244,235,231,238,246,239,234,233,231,232,207,235,208,216,232,199,224,239,240,223,228,239,229,222,235,250,239,247,240,245,219,226,229,204,218,233,219,222,233,234,235,223,217,217,215,223,235,239,220,233,119,3,9,5,22,9,4,0,2,5,0,0,19,18,2,3,6,0,7,2,26,15,5,5,0,195,181,194,186,207,195,214,180,190,192,195,189,178,189,201,176,232,199,207,193,184,171,185,207,196,175,195,209,198,216,199,196,190,195,195,192,218,209,184,151,217,182,190,202,187,207,198,195,169,215,192,195,190,203,199,187,197,191,196,204,203,198,181,194,181,199,199,195,211,175,194,217,198,188,197,162,216,203,174,190,196,184,195,194,190,229,196,186,205,198,225,218,187,222,200,199,177,212,196,193,200,185,188,229,202,184,216,195,198,209,172,200,183,178,185,218,181,202,193,189,203,186,226,182,198,212,200,180,184,182,213,181,213,184,181,242,184,222,199,178,210,195,207,203,199,195,196,198,203,189,193,210,220,184,191,212,216,203,196,215,210,201,216,193,189,185,193,191,190,200,186,193,191,191,214,196,218,203,186,186,215,193,199,201,199,189,200,216,209,207,190,210,206,200,191,177,207,230,203,210,198,183,172,191,191,199,188,193,204,199,197,199,208,214,190,190,205,204,207,201,182,223,199,196,198,228,209,179,200,213,195,214,204,210,213,196,204,191,229,208,209,196,179,191,201,196,162,205,195,213,183,111,30,74,182,210,204,199,179,223,217,226,189,217,211,219,224,216,216,218,217,217,191,212,174,202,182,187,200,202,216,202,240,213,202,228,223,208,214,245,234,196,245,245,196,206,228,212,246,222,199,210,215,235,217,212,234,221,208,198,211,236,236,216,227,207,226,198,215,215,112,60,141,225,254,248,155,157,158,172,161,149,184,184,181,129,139,156,165,159,98,127,154,99,29,20,52,43,46,58,32,87,51,60,83,79,189,236,234,215,227,233,193,203,199,209,228,132,182,180,176,211,178,96,101,191,157,166,171,167,199,195,225,220,242,214,245,227,39,178,182,180,172,198,223,242,199,65,37,76,113,80,28,48,35,78,234,228,212,163,90,212,202,129,117,179,187,153,154,152,227,249,229,235,174,189,210,219,197,186,66,117,222,215,209,220,219,214,251,233,120,80,0,9,34,35,66,36,21,13,38,46,44,72,20,23,188,243,255,177,132,93,59,91,72,76,95,70,30,57,126,136,137,106,31,24,1,27,15,29,66,99,94,119,100,66,57,99,149,171,196,183,204,197,205,169,127,103,81,57,23,24,64,25,4,25,4,0,34,9,9,9,20,30,55,14,16,24,27,34,15,27,23,33,36,2,12,29,17,20,18,62,119,168,234,171,125,151,145,144,144,208,222,76,77,14,18,13,18,32,7,10,22,32,26,42,13,19,11,1,27,23,20,29,9,24,12,10,41,5,9,5,29,5,24,17,8,25,44,52,37,35,58,60,44,89,79,69,100,73,78,39,26,16,53,36,36,33,41,21,78,78,87,51,32,26,82,67,72,53,82,52,34,47,66,72,110,107,92,113,92,92,64,54,63,37,51,52,52,96,71,117,199,247,241,233,243,235,235,234,252,210,228,217,216,242,225,225,226,228,248,225,218,229,233,222,206,242,242,242,227,243,233,222,223,205,213,231,220,213,250,233,238,233,225,240,250,237,240,205,233,229,220,244,239,235,230,218,201,231,238,207,243,205,225,113,4,17,3,6,2,21,6,22,7,28,8,1,11,2,12,6,9,19,16,19,20,3,29,16,179,182,171,174,182,193,189,182,207,194,195,184,202,210,195,192,199,194,199,200,189,165,180,173,220,190,195,197,195,201,185,204,179,177,175,204,201,194,204,212,171,182,188,189,216,204,228,185,197,177,186,192,184,193,196,171,177,205,203,172,178,162,186,186,185,187,184,211,180,183,181,190,193,191,199,184,173,188,190,185,187,192,175,194,202,200,188,178,195,188,199,212,186,189,189,211,205,204,199,201,179,205,182,187,208,198,208,206,217,227,189,186,179,206,173,206,192,222,198,218,199,167,189,204,200,208,198,224,207,206,204,232,197,189,205,184,209,189,176,224,196,190,185,202,179,183,211,181,199,225,188,214,221,218,194,202,195,205,206,198,191,185,212,196,231,196,216,202,184,203,208,203,199,199,186,207,200,220,206,192,200,197,204,192,208,198,208,232,185,209,204,177,187,215,209,190,194,206,201,206,231,199,203,183,218,223,207,195,194,194,193,209,203,200,182,212,214,194,221,192,201,203,210,213,189,206,188,216,194,178,194,215,193,174,190,195,202,207,204,190,233,191,211,234,205,179,214,235,223,187,210,161,136,180,215,247,194,195,222,195,202,218,214,223,205,216,201,209,215,193,219,184,183,204,179,170,179,202,207,233,190,218,208,228,221,216,208,221,218,211,223,220,221,225,227,208,226,231,206,216,217,227,234,243,194,216,221,210,233,197,211,235,223,222,220,202,229,232,199,179,123,48,146,225,231,221,200,185,152,189,154,147,193,121,172,121,152,178,173,205,203,209,226,146,63,36,60,41,39,29,45,99,91,132,109,137,207,249,231,190,197,240,211,203,210,240,220,155,193,192,199,173,153,144,121,171,174,186,229,206,248,226,241,200,196,179,216,137,38,189,198,176,161,199,237,242,170,54,20,63,109,67,42,19,3,74,223,239,212,159,138,203,200,165,168,174,202,160,127,160,199,225,246,224,149,184,208,203,224,243,134,57,133,162,197,225,242,244,252,188,56,27,18,12,11,23,29,11,47,11,23,45,69,59,25,167,252,225,225,212,160,113,52,70,54,103,73,67,75,84,126,116,144,109,42,32,34,70,46,58,73,62,143,150,169,134,136,155,150,120,102,80,57,51,59,33,22,18,25,17,11,16,25,15,22,11,28,19,38,35,33,17,25,40,49,18,41,58,23,32,38,25,13,20,3,20,18,23,32,13,26,26,71,171,251,223,129,135,142,171,167,250,200,73,38,12,21,7,10,32,39,8,16,23,30,5,16,31,20,10,13,9,14,24,28,17,42,20,17,37,22,10,23,9,53,18,31,39,10,19,4,28,2,34,51,41,44,47,53,76,67,73,75,78,72,96,68,53,42,51,55,82,70,43,58,67,72,71,111,83,68,65,37,21,57,42,43,38,70,92,101,121,73,40,60,49,72,93,120,113,91,152,234,250,244,255,247,217,240,223,219,224,239,254,227,228,224,249,229,225,227,247,227,218,233,232,205,227,241,237,214,239,230,223,235,225,251,229,235,216,212,237,237,195,234,239,233,225,228,243,234,239,223,243,218,212,223,216,228,237,226,243,251,241,214,125,21,3,3,2,17,19,10,11,32,9,27,21,19,8,26,9,21,19,8,10,12,28,2,17,194,181,183,184,188,185,179,218,194,166,183,191,207,199,171,200,210,183,182,179,189,199,181,181,183,173,193,195,204,179,188,211,216,192,207,190,189,226,202,195,207,197,187,204,190,206,187,168,196,167,198,169,199,200,174,173,175,195,178,166,212,164,167,197,207,210,207,201,192,157,164,218,197,205,218,191,199,212,184,194,209,189,197,180,216,172,206,196,207,204,200,205,205,205,186,198,212,192,204,200,210,199,202,188,192,181,180,201,201,195,209,183,211,215,186,207,185,185,200,194,189,210,177,213,204,187,229,202,189,194,204,210,198,186,200,198,217,204,189,200,221,199,197,207,212,197,195,188,195,197,194,204,200,222,196,188,209,180,182,166,198,207,206,219,199,194,204,205,203,201,227,180,192,193,199,204,196,186,216,210,213,210,184,189,186,213,188,218,231,192,198,176,201,210,220,192,235,190,201,203,201,199,184,215,208,194,209,187,207,203,202,189,188,178,203,219,204,197,210,191,207,205,201,197,212,213,222,176,197,206,209,217,226,199,210,212,241,210,216,210,195,217,207,189,195,215,204,177,210,205,214,192,210,229,213,232,215,193,211,220,208,225,224,230,243,215,188,200,182,171,182,164,178,207,203,199,201,232,215,190,218,227,230,204,208,218,225,225,209,197,207,211,224,223,226,200,204,238,222,229,206,233,235,202,231,214,204,204,227,212,207,228,187,236,223,231,223,219,219,186,119,97,152,234,247,209,162,167,156,206,172,135,97,84,140,158,155,170,196,200,163,186,182,162,30,61,74,24,44,36,71,113,40,158,190,178,232,246,240,197,209,226,197,193,231,215,233,165,147,204,249,147,208,144,149,212,195,228,240,201,239,235,175,192,161,162,252,161,98,239,207,199,176,217,250,237,175,40,52,36,71,96,22,4,24,58,227,251,214,146,166,255,221,146,176,205,239,163,95,196,253,241,246,221,179,237,197,202,253,254,211,83,57,126,197,231,219,229,238,91,34,0,1,25,55,46,25,17,9,23,53,54,44,37,138,233,244,251,255,234,214,136,27,69,26,75,37,45,42,80,125,124,161,66,41,64,85,161,169,192,180,142,140,133,126,76,45,24,48,25,23,27,11,31,25,11,37,8,10,25,21,11,32,31,0,20,10,5,24,37,18,72,54,56,42,70,53,52,54,41,40,18,22,19,4,22,46,5,24,11,46,29,47,182,240,179,143,170,155,155,206,217,149,26,32,5,22,21,33,28,25,34,30,37,34,11,24,19,30,34,14,10,27,20,21,27,27,21,44,9,3,15,18,13,26,49,12,12,20,4,10,25,14,20,22,16,38,6,15,17,16,29,41,88,67,82,92,126,91,80,89,86,103,78,100,74,46,42,93,89,70,43,18,72,74,49,10,40,13,55,76,104,137,95,125,125,118,133,152,137,118,184,241,232,243,219,224,235,230,217,234,223,230,242,216,227,222,246,240,232,228,215,227,221,203,220,232,241,239,229,213,215,233,247,212,218,247,239,237,238,253,234,224,241,218,224,204,227,240,239,209,237,233,224,236,233,222,235,214,217,223,220,221,224,228,122,8,11,5,2,32,11,15,8,8,43,25,26,27,4,1,10,20,25,16,0,11,37,10,13,198,185,196,192,190,203,190,200,187,198,185,192,188,184,212,210,190,188,208,198,185,175,194,208,168,166,197,188,196,187,179,196,184,192,170,163,200,197,195,186,186,190,214,198,198,172,170,190,179,185,177,200,189,186,208,214,189,184,182,191,186,187,166,187,179,176,179,208,195,201,199,195,222,193,182,190,194,175,192,209,188,217,208,172,197,184,206,208,224,188,171,205,198,193,192,185,172,197,194,199,187,194,177,198,198,193,186,195,192,186,180,201,208,190,206,207,185,187,213,196,205,177,208,190,198,194,202,202,185,206,192,210,200,194,192,182,191,181,195,196,188,197,181,193,195,196,195,194,193,196,192,201,208,189,216,197,213,178,210,188,214,211,202,178,196,206,214,193,220,191,189,197,211,211,203,206,188,211,172,185,204,190,208,204,202,228,196,189,223,181,183,198,192,231,181,191,192,178,210,194,196,200,195,208,205,212,208,178,206,177,200,207,182,189,186,209,184,197,199,195,193,214,198,188,197,185,184,194,188,210,206,190,182,182,210,198,202,197,205,176,232,168,190,181,225,179,196,195,199,206,203,203,231,234,229,208,194,202,223,229,223,242,239,204,213,205,188,174,184,189,174,197,215,209,211,215,231,207,213,228,192,206,227,209,198,213,216,193,209,203,230,208,201,230,237,234,226,225,232,215,221,239,205,219,217,230,202,226,201,197,216,240,240,226,224,227,227,206,226,179,125,142,190,230,235,185,140,104,159,190,158,170,161,79,109,168,189,171,200,162,134,135,144,140,59,59,79,18,50,15,67,44,63,202,248,254,235,213,246,211,249,246,230,245,241,254,251,139,157,240,230,237,208,170,185,237,255,253,236,202,232,227,190,248,223,225,241,158,211,234,253,229,204,245,234,244,187,59,56,42,120,85,11,46,29,44,193,247,249,143,214,229,243,181,196,246,252,136,129,235,251,251,233,223,222,245,218,244,247,232,250,160,86,139,221,217,248,253,147,38,0,25,24,20,43,18,12,5,56,57,77,40,26,126,222,251,252,232,237,249,208,98,63,56,49,53,54,52,33,100,143,114,152,138,145,147,171,173,180,135,92,55,30,35,20,14,8,26,15,29,16,49,19,44,32,20,14,18,38,30,28,25,6,17,27,25,24,50,33,51,48,36,28,50,29,59,37,33,40,31,10,0,28,21,21,6,25,43,29,26,39,32,21,205,233,163,142,156,158,187,186,198,95,13,27,14,14,31,16,38,27,25,57,20,23,20,12,31,15,24,23,9,8,6,4,30,36,56,48,12,36,19,15,30,31,34,36,28,26,9,8,25,17,25,25,9,3,6,18,21,23,23,53,23,32,35,41,51,80,100,95,87,131,119,118,102,79,46,57,61,88,40,93,98,63,31,42,63,33,53,126,105,98,88,113,144,135,141,118,120,101,237,245,243,244,240,232,243,229,214,239,253,241,250,248,225,216,224,214,224,248,214,229,242,232,221,235,231,216,241,228,206,245,233,229,228,232,222,235,241,238,233,232,215,236,210,226,235,234,214,235,223,228,234,229,216,238,240,208,234,230,233,213,208,233,128,6,12,5,30,22,10,20,8,3,5,11,23,4,0,6,27,2,13,10,21,10,9,18,4,201,181,199,213,194,191,205,191,174,184,192,180,200,192,211,187,177,186,183,167,192,207,175,174,186,194,198,200,206,166,186,203,176,178,207,181,194,164,195,199,204,197,188,182,195,188,198,214,171,214,183,194,211,196,187,203,200,199,179,168,189,190,184,205,193,153,193,213,210,207,197,161,212,179,203,167,209,182,204,190,202,204,229,196,214,204,201,189,219,202,193,195,184,187,188,206,177,168,201,167,210,204,207,192,216,186,202,184,197,225,198,193,213,190,181,194,199,198,187,195,197,181,179,175,209,215,191,200,208,208,179,238,209,188,186,200,216,209,203,191,206,205,187,189,197,163,212,203,194,197,207,188,184,200,214,226,198,215,210,192,216,181,212,213,177,201,214,200,177,193,189,221,200,183,212,206,179,193,214,196,186,206,212,203,174,201,205,189,192,194,203,187,201,189,194,179,186,174,225,219,196,198,218,196,208,188,195,165,184,203,193,180,199,198,200,194,199,174,168,185,175,208,198,182,206,173,210,210,220,191,186,193,209,202,200,191,189,207,207,224,201,199,195,183,180,219,195,200,183,214,185,189,229,212,225,220,194,198,247,217,185,146,162,183,179,189,185,201,214,212,212,217,233,245,198,216,225,225,206,226,193,227,214,211,233,231,216,221,233,242,245,250,209,238,222,227,216,245,253,247,255,247,240,234,237,248,248,251,242,223,246,250,254,219,243,253,246,242,222,187,192,150,175,228,249,220,145,116,156,215,219,241,232,182,170,179,203,177,156,132,95,147,155,124,76,65,69,17,38,34,40,30,21,193,255,237,248,228,232,242,242,242,249,231,252,233,220,86,91,195,232,161,216,170,188,206,206,194,176,170,231,215,218,236,191,230,228,142,204,246,225,188,137,195,233,238,162,45,43,74,95,100,45,25,50,37,171,216,153,92,150,216,158,124,177,173,159,93,124,222,216,215,188,204,175,170,146,165,219,220,214,112,67,129,183,199,195,149,63,8,0,24,37,29,52,4,21,46,63,69,62,28,73,224,227,241,250,252,238,218,150,88,41,92,37,78,55,74,65,107,153,124,188,150,141,124,67,52,36,35,8,28,3,10,22,8,22,20,13,25,44,28,36,46,34,9,52,70,40,57,33,25,22,16,31,21,26,11,54,44,47,34,67,40,79,63,66,50,25,17,32,29,17,20,9,13,31,18,40,21,62,29,54,223,217,134,152,151,184,165,190,173,64,34,22,29,42,8,9,51,38,30,26,11,43,12,15,28,8,35,32,26,16,6,25,16,48,7,20,39,13,32,13,22,59,40,47,37,55,27,46,23,8,39,34,29,20,18,6,24,31,18,18,5,6,12,19,19,32,40,57,70,60,60,90,108,99,87,97,101,91,64,72,57,31,61,33,28,16,74,111,121,122,94,127,136,132,142,118,84,139,244,231,239,244,231,240,232,222,217,229,207,241,232,249,235,242,222,234,239,235,219,237,231,236,229,229,225,236,230,210,204,225,240,223,218,230,225,212,220,212,240,241,206,237,238,212,245,242,222,216,239,203,210,244,245,217,243,230,203,223,225,253,218,217,129,2,11,28,7,24,1,14,12,28,3,6,31,2,17,4,2,11,21,18,18,26,16,16,8,190,225,195,193,191,207,203,174,211,204,187,177,173,185,182,219,217,202,214,185,186,180,211,176,185,186,202,200,192,203,185,196,199,185,201,198,177,202,157,186,189,186,192,193,214,200,176,202,193,197,173,201,201,206,215,192,172,182,204,194,188,168,203,193,196,199,193,206,194,188,209,223,181,189,220,200,199,204,201,191,211,199,190,195,192,202,196,205,180,187,213,186,170,200,203,184,211,192,196,192,183,195,203,184,206,207,202,188,205,194,203,198,200,187,171,196,225,207,204,179,215,224,222,222,192,203,218,199,180,218,172,178,197,202,199,205,202,215,195,208,217,191,209,208,199,219,212,199,202,194,197,187,194,215,182,191,227,185,201,226,203,202,181,180,204,198,199,217,182,213,189,204,222,214,196,196,201,196,197,205,205,200,178,185,194,216,193,187,202,176,206,192,184,210,204,197,203,177,213,196,220,202,192,170,181,207,211,213,192,184,182,196,192,206,168,174,207,209,191,197,189,189,198,184,191,199,178,178,196,223,185,177,175,213,173,204,201,204,190,185,211,187,221,220,204,197,193,210,208,199,179,186,208,219,236,192,217,223,215,109,14,0,77,173,215,221,240,246,232,250,239,240,241,220,249,214,252,228,242,232,255,250,251,250,253,251,252,254,251,235,255,254,246,252,243,230,244,253,228,247,255,252,255,254,241,255,249,239,251,254,252,246,242,220,253,253,255,239,250,241,197,149,150,225,251,215,203,124,147,203,219,235,226,206,221,166,183,185,151,129,89,117,135,105,84,103,82,105,86,87,83,54,77,178,191,171,166,169,163,161,168,143,155,185,153,179,162,63,67,166,118,92,77,98,95,86,71,56,94,96,123,88,107,124,93,153,95,56,107,71,113,98,57,31,67,86,115,77,38,58,92,87,31,36,42,40,36,52,67,10,17,43,33,43,46,77,53,59,68,52,14,12,41,99,133,122,88,63,11,48,77,39,43,62,83,69,101,30,49,44,3,24,34,45,17,14,37,63,71,41,18,92,198,227,247,254,239,247,219,192,137,88,86,101,92,125,116,89,108,125,131,114,112,30,13,16,14,18,13,58,29,11,31,33,5,24,43,27,27,34,21,49,35,56,20,57,24,43,22,56,51,67,37,44,30,48,27,37,39,46,54,83,65,107,160,94,79,45,60,12,22,10,29,5,25,30,39,30,29,33,58,37,69,224,174,140,154,121,204,189,147,155,96,70,92,66,55,34,35,4,14,17,17,32,10,28,12,20,24,8,5,53,5,13,13,0,14,49,6,30,5,15,25,31,43,35,36,58,34,23,48,26,42,41,35,21,8,10,13,9,26,29,24,37,32,27,17,22,11,27,18,12,29,39,14,60,55,66,91,106,109,98,95,58,25,28,50,39,26,59,87,122,101,96,97,108,111,104,105,58,100,206,226,235,255,244,230,236,230,236,219,243,227,238,240,241,210,238,213,229,226,242,224,236,231,234,222,205,229,199,232,240,215,225,238,233,239,249,216,231,207,215,232,248,229,217,233,243,243,233,216,231,235,243,245,209,228,229,248,226,215,225,206,235,234,124,7,0,0,14,12,13,12,7,19,4,0,15,10,7,16,0,12,31,12,23,23,14,36,0,185,163,202,190,203,212,205,205,213,210,200,202,207,192,204,190,171,184,210,212,198,191,191,187,191,173,186,175,215,197,207,170,210,182,189,170,204,190,181,183,199,180,189,179,199,160,187,191,189,190,213,187,187,203,192,189,189,184,179,207,181,206,216,201,202,202,162,196,209,176,195,180,188,181,199,188,197,179,223,183,208,206,206,190,202,168,170,203,194,200,166,168,204,178,210,225,164,205,189,207,203,206,204,202,194,207,209,182,198,200,187,218,177,207,198,180,199,198,180,190,197,203,193,182,202,185,204,205,180,174,186,192,194,192,231,206,224,207,208,187,170,211,181,197,191,186,206,215,186,201,209,214,182,199,197,217,193,203,205,211,204,213,203,207,226,201,199,179,197,219,191,178,206,217,200,205,198,182,208,202,204,201,184,207,206,196,223,165,185,196,201,210,185,192,188,204,161,187,188,191,183,203,186,206,172,203,221,190,189,172,224,196,192,194,201,200,197,206,180,176,180,205,178,204,175,208,191,191,228,207,227,217,209,198,213,202,209,213,218,219,217,225,233,223,230,221,222,215,207,215,199,226,245,250,252,234,234,229,188,126,74,107,194,230,250,238,253,231,248,247,241,248,234,236,251,253,247,255,238,238,247,246,246,234,238,235,252,254,236,245,253,240,251,253,243,247,248,223,240,220,206,232,189,188,237,212,214,192,182,182,178,170,158,171,178,228,188,162,155,137,182,107,103,162,154,188,174,90,76,141,152,186,165,138,142,113,120,120,105,117,101,76,76,127,116,99,108,126,138,105,143,115,128,98,91,77,47,69,92,59,56,28,18,85,42,36,75,86,74,50,37,70,66,64,53,28,32,7,48,40,74,48,54,15,13,63,32,36,30,54,54,63,29,21,23,2,33,72,63,58,70,90,74,22,45,50,39,26,77,54,43,38,11,35,16,46,23,60,72,48,22,3,32,80,131,146,124,73,24,17,30,30,46,71,95,68,36,44,0,23,24,41,52,27,25,14,75,46,92,36,36,154,242,235,252,250,247,192,143,144,92,84,120,132,137,151,145,115,153,147,110,141,99,18,11,26,5,21,16,4,36,29,34,17,31,18,35,29,26,34,2,48,32,38,21,66,38,62,25,60,30,41,45,36,37,63,38,26,53,22,52,50,18,94,141,93,55,22,18,14,10,34,26,28,43,12,30,43,29,35,52,1,109,229,136,106,154,181,227,158,174,114,104,79,122,99,72,50,38,12,32,37,14,58,15,33,21,38,15,10,2,28,27,26,6,20,9,37,12,25,27,46,24,27,47,39,37,35,51,57,64,54,33,35,5,42,24,16,40,16,20,14,34,17,11,18,17,19,21,39,11,6,4,31,9,53,17,21,42,43,53,78,69,95,101,89,93,92,39,79,96,98,126,86,65,75,87,69,62,22,81,227,231,252,241,233,242,237,224,245,208,236,231,239,239,241,223,229,228,219,221,247,215,241,229,223,222,236,239,223,235,221,232,240,238,200,227,242,236,245,220,244,222,244,235,203,209,229,231,226,248,236,217,209,222,216,220,238,220,233,230,209,225,240,222,122,5,1,20,1,8,0,22,4,9,13,29,2,11,1,35,12,42,28,5,11,13,3,3,29,196,163,185,205,158,179,190,200,192,194,212,194,182,195,194,196,201,183,205,179,221,193,203,195,172,184,191,167,178,200,187,188,182,205,163,207,186,205,166,176,217,166,170,166,211,204,207,194,201,174,191,203,179,183,208,204,211,171,172,194,177,190,218,195,182,180,205,186,203,197,196,179,177,210,215,198,184,211,189,191,201,205,188,180,214,200,192,183,205,205,201,186,205,193,194,199,179,201,205,194,220,200,176,194,200,210,197,181,199,194,184,168,191,178,189,186,190,187,183,204,201,203,200,193,213,206,195,208,194,214,214,187,194,198,204,190,211,203,194,211,215,210,211,196,193,234,210,218,211,176,212,218,204,204,192,214,193,215,204,206,181,222,200,188,200,209,193,216,199,179,197,188,201,186,207,204,203,197,215,209,183,198,191,190,201,175,192,217,200,183,187,211,215,199,192,190,192,179,179,206,181,202,209,188,193,197,189,197,201,210,197,184,184,165,189,196,204,182,189,202,245,220,216,217,211,204,207,205,234,236,216,222,236,216,249,240,246,246,232,245,248,214,234,229,242,240,232,232,230,207,212,229,241,236,210,184,190,219,223,200,177,215,244,235,228,229,225,210,169,190,225,204,192,169,145,167,166,187,174,167,174,161,149,153,150,146,176,147,139,125,141,108,138,107,116,99,97,115,118,99,87,129,98,118,77,108,73,81,78,93,66,58,96,64,38,79,76,72,51,64,82,55,63,59,49,79,78,71,85,57,74,44,71,94,54,81,82,99,77,85,99,98,95,68,113,102,108,67,109,117,137,118,105,81,57,57,79,71,51,58,61,50,18,44,65,53,46,85,112,70,78,68,59,52,51,22,58,76,89,53,87,41,66,27,38,79,58,28,54,54,90,105,58,44,49,20,59,108,63,60,40,91,58,36,71,77,45,46,88,70,88,100,59,51,67,58,50,115,70,65,77,5,67,31,67,135,131,170,88,54,31,16,58,87,98,80,28,43,22,43,62,44,28,17,16,60,42,38,40,40,167,245,245,252,251,252,156,117,90,68,62,76,128,168,163,154,177,141,149,150,109,133,96,29,36,38,46,25,32,31,9,37,10,29,55,33,1,22,8,65,27,9,14,55,69,95,73,56,37,43,87,59,50,70,93,87,67,34,33,31,8,83,56,100,88,63,44,42,6,12,19,15,9,45,29,43,37,40,58,22,62,12,111,192,92,128,162,220,243,169,164,138,112,112,111,76,59,41,9,52,44,37,37,28,45,1,44,39,28,33,41,35,28,16,23,15,14,40,20,6,45,11,25,8,20,26,42,41,59,73,56,29,37,43,47,31,26,18,35,31,34,28,5,4,49,15,42,38,29,15,13,18,26,15,20,0,33,8,14,20,21,55,40,26,58,102,108,127,103,87,114,84,99,62,67,53,70,69,51,11,167,253,247,233,217,243,225,222,247,234,221,209,227,235,218,249,232,224,234,224,232,237,231,241,244,222,241,245,223,236,235,215,214,232,224,218,226,235,237,236,225,240,239,222,227,239,218,240,244,242,239,237,234,241,214,228,218,230,226,231,236,232,248,240,249,121,17,0,12,23,22,4,17,10,22,3,18,49,0,10,8,15,18,33,7,7,33,2,13,2,183,197,198,212,185,191,175,213,175,186,185,192,192,182,172,194,190,201,173,197,169,186,195,204,201,180,156,196,201,173,184,194,197,176,194,190,185,192,198,162,193,194,189,184,153,194,175,189,172,193,198,200,225,170,187,192,177,185,181,183,177,212,182,199,177,183,160,212,179,212,181,185,207,193,201,188,181,202,195,188,226,190,178,222,191,204,208,170,210,200,214,183,182,178,193,173,179,195,187,191,194,212,209,218,207,159,204,199,194,187,204,201,198,179,225,206,196,214,201,196,188,206,208,178,185,179,207,205,199,185,183,174,175,183,175,222,199,219,198,192,232,209,210,201,223,198,214,191,185,206,193,203,203,206,204,209,210,189,193,210,192,203,207,208,194,208,182,186,192,175,194,217,210,177,186,199,189,212,177,198,193,204,193,200,176,181,190,197,193,204,206,192,214,189,201,199,194,191,189,180,187,206,187,185,179,233,206,206,178,204,183,195,202,188,187,203,211,196,191,237,242,243,254,254,229,229,248,231,250,227,244,227,243,223,239,233,239,226,204,207,212,208,222,223,190,199,212,166,177,192,187,150,129,137,137,127,131,142,179,126,145,167,144,130,112,104,77,84,118,75,92,74,78,50,82,96,55,65,92,66,77,64,73,85,34,43,44,46,44,63,67,47,60,14,63,72,41,74,50,34,54,130,97,65,68,68,61,77,84,84,81,87,51,96,77,66,81,49,79,67,82,50,60,77,40,52,51,40,57,90,43,74,49,38,65,73,86,52,70,117,107,70,97,55,75,98,83,88,52,46,93,66,81,81,62,108,85,82,82,70,73,86,52,74,58,105,75,71,100,80,87,90,53,84,95,81,89,59,58,56,77,37,33,69,32,70,62,57,48,71,73,104,60,62,46,33,74,109,63,95,47,117,49,33,49,58,50,36,51,59,70,45,19,45,65,95,58,130,64,21,18,29,84,84,21,28,127,119,179,126,22,20,7,75,89,70,21,12,26,45,77,36,20,18,23,42,69,44,26,121,243,243,239,230,255,168,135,153,150,112,43,82,85,96,121,117,134,119,154,114,77,116,56,16,20,19,13,18,16,45,41,45,36,49,24,29,4,5,7,9,20,12,15,23,46,49,75,43,51,69,45,41,66,50,89,120,101,102,68,90,92,118,125,79,24,32,13,22,27,23,71,80,44,23,30,40,46,61,53,52,85,37,119,164,114,173,190,240,224,173,158,154,97,62,32,18,61,37,16,42,41,52,35,35,68,54,32,24,57,43,40,12,43,50,48,34,12,29,10,25,22,18,7,8,37,62,52,54,101,69,73,54,44,43,19,24,50,34,33,27,45,35,26,56,21,55,39,31,12,19,57,26,27,5,5,28,7,0,16,2,7,22,24,25,27,23,54,83,84,103,79,106,79,69,42,76,51,68,68,71,183,241,255,251,226,227,235,246,229,228,220,237,213,232,251,235,224,231,227,242,226,238,227,228,213,242,230,224,245,230,231,233,233,241,241,235,232,229,230,234,230,240,236,216,229,226,236,247,227,231,215,229,235,224,246,239,238,243,231,236,226,216,229,247,224,124,25,6,7,2,3,4,14,1,18,16,13,5,23,9,16,10,9,4,26,9,43,7,18,18,196,175,183,187,209,197,197,172,208,188,168,184,191,193,184,174,174,179,182,176,205,174,195,202,202,160,177,191,187,184,203,189,198,174,178,197,194,167,177,198,183,177,202,211,175,190,200,195,188,175,196,203,187,181,205,182,192,172,197,211,201,172,200,207,190,192,183,201,185,188,178,201,216,205,201,203,196,195,204,197,198,201,191,199,202,220,209,213,212,205,190,197,206,186,193,203,195,203,216,195,206,190,193,176,225,188,194,198,196,200,198,212,208,195,197,216,212,224,219,187,203,200,173,221,206,196,181,189,213,218,189,179,175,192,199,226,201,180,187,209,203,198,189,197,198,210,224,200,162,174,216,221,180,193,219,209,200,198,171,216,199,203,199,196,203,189,194,191,195,195,181,202,171,214,169,187,201,193,193,185,183,208,207,193,196,183,235,208,182,218,184,191,195,191,199,183,203,201,190,190,199,202,191,201,192,226,201,223,188,199,172,180,172,223,201,192,193,188,195,188,193,200,204,189,204,202,180,163,162,183,148,179,146,152,142,162,127,122,125,97,135,106,109,104,102,106,106,120,96,131,174,73,56,64,71,105,90,71,88,63,45,70,67,59,57,35,69,59,28,71,63,83,47,45,76,85,70,75,80,36,36,49,25,57,55,53,45,62,57,57,64,56,42,62,61,39,53,38,72,48,62,107,102,48,56,62,58,68,67,102,96,100,109,142,86,71,70,41,69,58,89,39,51,84,79,67,29,65,49,53,33,62,63,62,56,39,75,51,51,51,54,49,59,37,62,49,56,44,42,95,55,51,37,80,57,43,42,66,50,71,63,52,44,13,45,70,57,62,30,60,48,52,75,82,65,63,53,47,57,16,56,55,52,42,45,126,64,41,24,56,33,109,77,78,32,3,63,100,72,105,85,86,72,26,64,39,37,37,57,26,63,69,52,31,61,53,56,64,73,21,14,15,80,60,63,24,45,55,84,115,78,36,46,47,46,37,26,33,44,47,20,23,21,57,62,53,73,35,117,206,247,252,253,254,168,163,200,255,252,213,77,13,12,4,15,38,58,87,130,88,89,123,43,20,34,30,27,32,35,28,27,23,30,22,57,45,22,27,18,15,25,24,23,35,14,45,38,61,54,59,53,64,75,86,85,92,109,116,96,110,126,109,92,74,60,8,22,22,23,65,57,115,81,100,64,63,71,59,57,42,62,38,128,138,111,184,235,244,189,131,150,116,50,28,48,59,71,50,32,17,40,44,60,69,36,63,22,48,53,16,44,38,67,18,36,43,29,22,22,38,26,11,32,33,33,50,71,84,71,65,28,13,17,25,51,52,49,37,52,27,28,44,43,40,14,37,48,47,25,27,27,18,19,4,42,25,24,41,44,23,29,14,15,18,41,25,34,20,18,59,65,79,105,110,81,52,68,106,97,100,160,223,244,234,244,229,245,245,197,220,247,244,247,251,237,216,241,247,221,219,231,212,234,228,244,243,235,244,240,243,238,218,229,217,233,229,212,237,219,238,229,236,226,210,251,240,242,222,224,242,224,240,226,230,234,214,221,223,224,231,243,219,241,244,220,112,2,8,5,13,9,0,12,23,27,15,2,5,10,18,2,10,21,2,6,17,2,10,16,6,222,181,194,190,196,195,182,194,186,186,193,170,188,195,158,191,219,192,190,172,191,180,210,188,178,202,201,204,166,182,202,161,193,195,187,192,177,193,200,193,211,182,176,196,182,193,177,193,180,175,196,182,201,194,183,198,207,178,179,185,203,178,198,173,169,213,211,206,199,182,210,190,169,184,182,198,201,199,203,205,200,193,203,193,208,185,197,210,195,227,208,209,213,180,188,186,192,197,199,196,195,188,205,216,214,216,179,182,209,202,196,212,217,210,214,198,192,227,214,215,213,189,194,198,202,189,197,221,187,219,195,205,194,188,182,201,210,205,205,178,202,205,209,222,196,208,193,196,191,179,199,178,203,214,198,205,208,221,201,214,205,181,199,216,201,223,212,195,197,205,185,201,193,180,175,191,181,168,203,207,180,185,200,183,188,187,188,176,189,194,178,195,199,192,213,189,207,194,203,183,176,187,193,172,190,203,195,194,207,185,179,197,187,199,183,207,218,123,75,62,47,42,37,44,35,37,56,28,48,40,27,44,24,31,24,23,21,37,22,52,38,26,46,12,23,47,36,20,53,105,112,84,9,29,53,52,44,43,51,52,61,28,62,38,53,54,78,35,56,29,64,77,46,65,50,45,56,58,57,54,57,60,82,46,79,66,70,39,28,36,41,68,70,71,42,73,30,57,45,55,16,77,42,32,52,43,44,29,52,91,65,38,39,41,78,67,47,41,37,68,58,37,62,45,36,25,31,20,21,35,42,21,28,60,60,32,65,41,31,32,19,19,29,28,24,12,54,39,39,32,48,28,30,43,65,40,7,23,54,21,40,42,11,50,27,33,84,28,63,61,62,56,44,43,44,31,35,44,32,53,49,10,39,13,18,56,86,35,13,28,14,14,48,45,27,2,41,51,73,116,74,104,110,31,66,30,48,47,9,35,68,48,28,1,10,46,50,59,23,40,19,12,56,13,0,28,38,5,42,50,108,70,40,60,17,21,58,65,39,47,18,6,44,59,53,80,21,94,208,245,252,237,245,196,170,204,243,234,254,185,67,13,0,22,26,65,42,25,97,122,84,122,28,28,32,14,58,7,21,31,12,41,58,42,50,65,62,27,7,16,15,14,56,44,17,41,14,42,34,32,62,68,55,73,78,85,71,104,110,117,120,121,143,93,66,22,19,26,63,104,43,118,157,142,81,41,23,37,43,19,63,51,131,163,174,237,223,244,171,109,135,93,48,46,137,95,85,57,35,29,40,10,28,51,70,64,31,59,59,80,35,38,48,52,22,33,43,22,9,15,14,36,35,17,33,39,35,43,52,63,44,17,36,20,32,45,55,60,44,61,45,57,55,49,49,44,61,46,60,42,61,38,43,31,39,28,17,26,29,17,43,20,30,18,17,16,23,17,4,56,73,98,85,85,89,121,146,163,143,115,156,196,232,245,244,241,234,243,235,239,243,238,232,237,234,208,206,228,248,216,233,237,244,239,247,248,240,246,225,205,234,237,232,235,232,219,229,235,208,248,209,217,245,206,249,237,208,237,229,216,228,231,196,221,229,245,227,229,224,222,231,229,221,235,220,96,7,26,26,1,4,17,11,7,6,12,12,52,9,10,21,19,18,17,7,22,8,9,1,19,208,207,213,214,208,168,169,194,196,190,191,197,195,204,185,184,181,183,189,229,187,187,171,194,205,196,170,190,187,221,194,204,169,186,194,177,204,174,180,206,179,181,196,190,185,168,167,190,183,195,171,174,171,199,170,189,189,195,168,192,166,179,197,188,203,194,186,203,204,206,194,224,206,202,185,166,154,196,199,193,199,169,212,193,221,186,207,202,172,181,221,186,203,192,184,171,181,188,211,204,213,217,205,204,209,214,217,228,206,204,199,216,198,206,217,204,201,205,214,201,222,208,195,202,174,184,180,194,200,223,199,192,175,193,175,185,188,174,207,206,184,195,201,227,200,188,201,191,216,232,199,175,206,203,206,191,214,202,197,179,215,183,191,193,198,189,183,180,201,196,190,192,221,208,205,181,208,173,209,209,181,213,168,205,184,197,199,207,183,176,181,187,204,158,188,183,203,199,206,191,196,168,187,176,207,196,195,195,209,186,201,194,181,176,186,179,184,128,18,1,8,13,8,13,10,20,24,14,7,18,10,3,19,7,30,10,23,16,32,4,26,0,19,18,14,5,18,7,18,36,92,48,38,19,2,35,21,38,13,31,23,26,23,13,29,36,43,20,35,34,32,26,53,55,42,36,41,38,20,40,39,43,25,59,36,39,17,57,59,14,27,61,30,27,14,13,70,24,26,26,3,64,68,17,7,31,4,31,57,21,17,24,33,39,10,30,14,10,12,22,24,24,26,41,22,45,49,19,23,33,33,13,41,35,25,25,33,11,31,27,18,14,24,33,68,39,42,42,22,53,34,10,36,18,38,32,39,27,30,24,29,16,37,59,26,23,74,57,41,46,72,36,42,36,75,27,27,29,25,20,19,43,45,39,78,48,15,17,29,62,75,70,14,41,38,26,49,44,77,102,74,111,94,46,75,44,75,74,62,38,100,98,94,82,79,72,124,112,95,131,107,105,145,117,123,118,129,109,60,182,171,140,98,24,25,10,47,47,24,46,6,41,57,60,47,24,79,210,244,245,244,236,195,170,233,242,237,244,252,138,63,68,34,54,114,66,36,29,136,103,122,105,35,40,39,20,32,33,52,23,18,39,13,32,60,39,82,38,18,27,45,46,26,17,23,28,20,43,40,25,30,29,52,59,103,89,91,99,110,149,140,159,152,134,100,29,10,34,104,101,45,128,152,121,66,36,13,4,29,73,83,48,138,201,225,254,245,237,165,138,157,67,49,141,142,104,112,59,33,22,8,26,0,9,47,71,62,77,53,51,45,49,34,50,45,27,22,52,60,42,21,10,21,29,23,14,12,45,68,51,77,73,75,37,70,52,51,60,34,77,94,75,53,63,59,51,50,29,75,56,65,68,63,59,68,60,50,24,20,16,25,42,13,43,29,34,44,23,40,22,92,78,101,96,108,168,144,158,143,117,90,88,135,216,209,221,216,226,231,232,232,242,225,237,226,217,221,244,226,238,222,227,237,233,197,198,239,243,239,236,234,244,228,243,238,217,235,228,240,210,236,215,223,217,251,234,228,221,206,215,227,237,222,239,236,218,208,234,233,241,218,229,234,222,221,118,2,6,0,29,1,4,18,4,35,4,27,6,36,23,25,4,6,26,8,11,5,2,26,27,189,191,190,176,181,190,174,182,203,184,196,191,160,180,154,195,215,208,202,192,170,194,175,186,191,176,207,183,189,198,207,194,208,221,158,178,201,195,170,200,197,206,199,169,210,210,209,184,189,179,170,173,165,178,192,197,179,197,186,196,200,204,197,205,196,183,183,192,189,201,202,178,184,189,219,169,170,199,202,213,199,191,194,186,210,193,210,188,186,203,214,191,206,208,189,203,201,201,156,207,202,189,209,204,209,217,203,206,194,217,174,204,206,195,216,212,213,215,194,210,227,210,186,209,234,189,201,213,208,212,185,198,207,209,209,204,204,212,200,207,225,196,224,192,185,204,163,193,181,203,174,211,214,191,214,223,194,201,198,222,205,184,195,233,214,204,205,192,187,202,218,186,216,214,206,194,217,212,191,197,195,184,197,210,182,213,217,216,199,200,189,194,175,190,200,188,213,185,185,196,200,186,212,208,185,174,173,185,202,190,208,198,160,188,212,207,220,150,86,58,49,80,55,36,52,70,25,33,48,51,27,29,16,22,26,25,2,28,12,14,40,20,25,8,6,6,27,12,6,2,60,43,9,37,3,18,22,15,56,11,18,39,23,14,39,19,30,38,23,40,16,29,39,27,14,53,3,51,16,69,28,14,18,31,24,26,31,19,2,14,7,9,3,24,15,27,39,22,14,43,18,10,3,29,4,7,11,2,2,7,12,10,19,3,27,5,30,14,22,47,35,67,51,66,54,51,30,29,33,38,62,41,11,28,36,21,36,34,24,69,42,61,71,54,27,17,49,28,29,70,25,62,86,41,30,136,39,130,57,128,66,122,106,156,139,120,134,136,64,110,127,110,103,140,168,144,88,137,168,197,192,212,216,215,169,119,159,247,239,240,228,184,135,198,232,242,201,91,66,72,89,84,105,62,46,50,202,247,188,170,191,249,253,196,171,159,210,240,238,253,245,218,245,248,237,236,234,235,246,255,244,155,50,43,16,34,50,42,27,9,28,43,43,51,42,65,213,237,233,249,255,186,159,215,232,230,251,249,208,89,85,79,72,91,65,97,55,89,132,105,147,89,12,21,31,47,48,34,41,12,28,32,40,40,31,34,55,40,24,53,53,39,70,34,26,42,21,45,69,68,73,61,108,152,141,106,114,112,111,124,91,100,101,72,75,52,50,59,169,101,95,95,57,35,58,43,12,24,22,97,81,64,138,227,232,237,244,227,166,132,154,66,53,156,134,111,101,70,13,18,30,10,2,36,4,43,49,74,42,50,50,44,50,50,36,39,31,44,39,52,49,12,51,47,51,30,57,55,42,45,70,73,74,57,52,76,70,67,51,83,72,48,57,66,61,60,53,57,27,40,61,48,36,41,40,26,47,41,9,18,36,26,45,28,50,10,23,11,43,15,86,98,121,89,116,156,165,162,118,105,77,22,80,195,236,235,229,238,226,226,237,219,220,241,222,196,218,217,226,244,226,247,229,248,226,242,225,222,237,232,239,248,234,248,251,235,235,211,239,222,241,231,237,226,225,236,217,236,221,246,238,242,204,243,210,222,242,242,225,217,229,228,246,241,214,115,0,11,11,26,25,3,24,2,22,9,0,4,7,4,3,17,19,30,30,4,3,2,20,13,213,194,206,219,198,190,193,184,170,193,186,207,194,211,197,192,191,187,200,204,208,204,179,179,194,179,180,195,190,209,184,194,202,199,213,196,206,199,198,214,199,204,181,188,201,187,186,190,197,188,186,187,187,201,208,193,219,185,214,181,182,211,206,183,193,189,184,205,200,206,221,216,217,221,197,198,224,192,183,219,182,197,213,207,196,177,240,180,204,223,220,168,205,196,193,215,204,179,201,206,185,222,210,199,220,199,224,204,193,212,225,189,209,182,215,210,217,199,203,189,195,173,186,216,191,212,205,202,201,213,213,171,206,216,225,181,170,208,210,196,235,201,200,196,211,196,230,193,205,178,209,199,182,192,224,235,188,199,193,184,195,214,204,194,212,198,190,191,177,209,208,200,196,215,210,197,191,201,204,210,202,214,197,182,197,190,181,212,210,189,193,199,177,195,183,204,198,209,219,179,193,181,191,197,202,201,214,196,189,182,209,189,193,180,209,216,192,214,190,228,247,210,236,222,221,201,214,226,243,219,239,207,231,212,218,241,207,216,218,208,212,194,189,210,177,174,193,197,154,135,161,175,174,175,187,205,183,181,166,175,182,163,183,147,172,174,155,167,184,172,160,161,172,179,189,186,203,163,175,197,180,186,176,201,194,219,194,239,216,213,221,222,233,227,232,247,238,219,235,226,215,175,214,221,234,252,239,217,230,206,210,223,203,205,195,230,228,240,251,234,130,126,237,238,180,58,64,126,214,248,240,182,157,199,210,241,247,234,243,254,238,253,231,159,74,61,64,14,53,47,53,207,239,236,236,252,222,246,248,252,243,251,246,255,244,233,246,223,131,119,157,171,113,122,237,210,214,236,252,255,250,250,252,253,163,137,231,244,253,243,240,225,248,251,251,254,224,127,63,51,31,74,74,52,39,67,220,236,251,219,202,223,252,227,136,173,231,240,247,248,247,210,239,255,243,243,245,236,240,253,191,81,45,11,9,40,53,44,7,30,40,68,69,79,7,105,238,243,247,246,165,174,212,249,248,246,234,249,135,25,65,61,60,70,81,101,51,101,138,115,160,80,15,26,33,47,40,28,38,13,24,15,15,13,73,46,61,69,78,59,84,52,97,62,112,141,161,117,129,150,158,166,193,154,151,143,93,108,122,66,36,52,45,52,47,58,72,120,125,75,94,52,53,57,40,29,32,39,99,134,86,54,110,222,252,244,248,255,150,164,147,53,89,157,99,127,74,34,19,36,27,22,25,3,22,12,2,14,17,49,61,42,69,52,30,43,48,45,63,38,61,89,61,74,78,71,68,94,66,60,87,100,61,73,73,51,30,50,42,62,53,81,51,53,60,38,56,55,29,5,47,31,21,18,26,27,18,13,26,17,20,26,35,22,58,28,45,43,39,43,79,91,113,95,97,129,127,134,79,80,146,179,203,246,245,240,240,230,241,240,241,241,230,232,255,242,232,253,230,240,217,233,209,246,235,247,237,238,236,251,241,233,245,242,237,238,238,234,241,230,240,237,234,224,230,245,228,222,226,225,241,235,245,229,221,241,236,245,242,225,232,228,222,244,232,94,31,7,26,33,4,17,14,19,30,11,13,0,13,0,7,10,22,3,27,15,36,10,19,28,177,190,184,179,190,166,179,179,193,183,182,195,215,200,182,191,197,206,205,186,203,199,185,183,178,173,181,175,196,195,202,173,167,182,210,189,213,185,185,190,194,184,200,198,185,201,216,187,188,180,215,199,206,191,185,182,208,200,182,203,203,192,193,189,185,188,205,178,187,179,178,185,200,187,195,175,185,198,207,181,179,186,195,204,215,200,196,194,204,220,219,212,193,189,201,220,197,240,224,217,204,199,196,206,207,206,211,179,219,195,195,212,218,186,194,224,200,210,178,203,195,201,183,209,206,190,205,199,193,212,212,206,185,201,206,198,199,185,205,199,214,205,181,229,207,220,192,185,213,215,208,191,183,184,191,183,190,211,218,218,187,219,188,198,199,195,193,208,196,196,214,211,201,182,166,191,192,194,201,193,177,191,203,192,178,192,204,207,189,186,189,212,180,171,209,190,172,209,178,196,204,171,201,206,192,226,203,196,203,180,183,189,211,172,199,165,177,205,196,235,246,241,252,254,254,227,246,249,249,229,236,236,253,242,255,249,247,250,249,255,240,246,244,245,242,254,244,242,255,211,248,251,254,234,233,238,216,251,249,253,248,250,235,242,233,244,254,232,223,255,246,251,229,254,238,233,246,252,241,247,239,249,248,255,244,255,247,234,253,252,254,254,253,243,238,252,249,255,252,255,255,232,226,245,255,253,234,235,253,253,225,255,238,243,249,237,255,238,249,252,134,133,224,247,221,187,203,251,255,248,242,253,235,230,252,255,249,246,252,239,230,248,238,184,90,81,65,10,16,38,70,219,227,237,255,245,250,237,236,239,252,241,242,221,241,249,255,226,91,64,156,174,70,44,226,242,217,243,234,246,226,193,185,175,136,133,239,246,242,224,242,180,200,248,252,245,177,76,58,89,38,78,54,40,48,31,210,235,202,226,137,149,244,185,155,218,242,221,240,219,213,172,241,227,221,232,239,238,248,215,86,14,6,1,39,59,35,9,6,48,55,56,58,39,81,130,233,223,250,155,155,222,244,254,232,238,241,174,82,51,88,66,53,67,91,59,47,112,111,111,133,38,23,23,18,44,35,36,31,13,23,33,49,8,6,44,36,29,71,61,62,91,142,180,157,155,182,155,163,129,135,183,170,128,100,76,59,74,60,46,47,41,12,20,29,48,61,61,50,60,55,49,76,79,15,34,35,92,169,116,59,47,65,188,240,241,229,192,103,106,84,37,35,101,62,62,67,59,6,4,15,22,28,12,50,37,2,13,41,3,23,38,24,41,18,37,24,24,23,30,33,12,15,43,50,46,44,46,56,83,55,64,64,69,75,51,70,58,67,61,59,61,52,47,48,44,33,15,15,15,0,36,16,4,17,23,24,0,24,43,36,16,31,30,34,33,25,50,49,55,101,97,102,84,56,94,72,71,30,112,228,246,230,235,246,235,238,233,246,240,234,220,246,249,230,223,242,224,233,238,239,232,224,221,211,219,234,226,234,240,208,240,210,231,234,241,230,234,243,239,243,209,243,251,224,226,242,238,240,210,243,230,235,237,238,224,231,215,222,213,218,224,229,206,217,128,9,10,1,4,20,3,43,16,16,36,11,16,9,4,11,0,11,27,6,7,13,25,33,29,205,200,181,197,183,187,203,180,199,201,178,197,196,205,216,219,177,180,186,182,196,184,207,173,176,175,175,181,181,202,170,202,174,174,184,177,197,185,203,180,198,194,175,214,196,186,174,195,190,167,189,199,169,216,190,211,164,196,184,193,196,197,208,182,202,178,174,179,182,193,173,190,206,185,183,180,196,157,191,200,206,213,189,190,208,216,195,206,211,170,196,213,210,193,189,202,213,202,206,192,201,224,197,212,196,217,204,190,200,208,205,209,202,195,197,203,207,203,191,198,174,189,210,216,199,170,212,214,188,199,189,215,207,215,208,186,176,209,196,185,216,214,182,203,194,191,194,208,192,209,204,188,205,196,192,161,215,208,207,191,201,204,189,213,191,189,187,194,201,183,175,199,200,199,211,205,196,196,214,176,187,211,178,185,190,180,202,213,188,181,195,180,208,177,174,169,193,186,189,195,169,167,182,195,180,203,177,209,193,188,206,177,184,201,183,175,180,211,183,218,205,208,215,220,196,218,224,204,189,217,229,205,227,209,238,204,229,238,228,231,228,216,216,223,227,219,233,208,233,221,227,236,243,239,245,233,237,235,250,241,227,247,231,250,243,238,253,221,242,231,253,248,229,246,224,250,238,255,233,235,255,254,254,243,234,255,248,220,253,252,242,231,254,234,232,249,229,236,241,235,242,221,243,234,249,224,236,255,253,253,254,248,244,246,245,240,228,144,212,189,54,82,199,248,254,254,251,242,255,250,229,213,206,223,214,203,200,185,216,190,155,183,188,101,43,78,60,44,52,33,24,167,184,212,215,213,237,219,239,252,255,243,228,244,233,229,237,221,197,188,220,231,162,105,207,180,175,205,196,176,150,213,190,200,124,193,249,236,241,227,242,159,164,233,226,255,168,96,88,87,56,50,87,41,50,70,232,242,171,147,97,169,202,122,152,189,235,224,207,246,183,159,199,185,218,222,248,251,229,85,11,7,11,17,36,54,34,14,37,72,44,58,39,91,185,227,240,242,142,122,223,246,251,253,240,249,145,150,149,142,115,63,46,72,92,100,66,123,143,145,94,24,25,28,28,3,30,36,38,16,24,31,13,24,19,55,19,39,63,45,42,78,151,174,176,183,163,163,124,96,103,129,137,78,101,62,41,61,26,50,17,16,19,16,10,25,53,55,41,29,13,55,41,50,33,53,136,197,172,109,61,28,23,126,245,235,177,100,56,20,34,45,32,22,47,63,43,34,29,17,4,12,15,30,34,17,36,10,26,19,32,27,9,23,14,21,26,49,29,5,27,22,25,44,30,61,59,44,60,83,55,52,30,71,95,47,31,37,70,89,59,49,35,17,15,4,24,22,24,23,15,14,24,3,22,20,6,14,13,26,31,66,32,35,39,69,45,43,41,72,101,98,118,103,67,24,72,65,31,89,227,218,246,242,244,240,229,239,225,229,209,243,246,245,225,234,234,231,222,232,232,230,244,225,246,221,248,236,239,226,218,209,248,239,254,229,226,238,220,220,233,192,203,206,246,241,236,244,202,223,234,223,223,243,214,230,205,245,222,221,209,234,233,235,223,113,3,2,10,17,12,12,9,10,35,17,15,41,0,5,2,19,0,14,8,20,1,10,0,32,194,166,200,172,193,181,194,182,181,204,188,206,189,223,197,191,199,163,190,179,188,178,184,187,191,194,171,217,195,195,189,191,196,195,175,190,178,207,191,174,197,190,181,188,202,204,177,195,178,208,200,205,219,188,191,199,195,193,199,192,206,178,223,185,199,215,224,190,178,188,180,196,209,202,188,201,204,176,195,199,173,192,194,175,164,228,205,198,216,223,180,186,216,195,205,194,215,206,184,199,207,201,202,197,200,204,232,219,192,215,217,206,205,195,201,202,203,205,204,218,212,210,223,209,192,195,192,199,200,209,197,184,167,192,192,225,191,193,200,185,196,182,174,195,216,207,195,195,179,208,203,212,209,210,205,210,207,203,200,208,207,210,209,200,174,184,220,200,207,177,192,211,195,187,184,208,177,199,196,200,194,178,207,214,198,201,183,187,195,194,202,207,173,173,179,185,180,200,214,209,192,189,193,206,175,203,171,194,193,201,185,164,193,199,194,179,189,205,175,197,214,205,187,187,184,189,209,194,187,204,189,187,194,193,187,197,178,190,211,204,197,193,207,202,171,205,207,201,211,183,202,188,207,202,182,218,216,215,208,207,224,200,218,228,218,227,202,216,229,210,208,237,192,233,208,199,204,230,214,215,241,214,238,235,225,212,211,227,208,218,224,226,200,244,233,221,222,196,218,202,232,196,216,232,214,229,203,239,232,219,211,194,220,240,202,219,171,92,159,185,86,70,151,227,177,184,161,148,166,165,177,120,125,133,112,91,106,116,135,110,85,96,114,107,107,165,116,170,154,118,85,65,20,25,57,27,38,43,71,59,123,165,174,141,138,118,141,206,201,247,251,224,244,124,125,122,61,108,161,176,190,232,209,215,133,197,218,233,239,217,248,162,162,227,221,252,156,104,63,66,50,56,101,66,36,56,228,241,178,138,107,180,167,61,101,168,198,193,219,214,146,193,202,180,213,233,241,235,154,39,20,26,8,37,39,43,23,9,69,50,61,33,56,211,248,196,242,157,145,222,250,247,249,242,227,143,165,234,201,147,115,78,32,26,56,34,54,127,89,122,97,32,36,30,42,68,56,29,16,17,42,29,13,16,33,14,23,51,32,45,61,47,92,100,135,207,129,97,67,72,89,114,130,80,114,86,58,63,8,38,15,34,18,30,15,9,25,14,22,30,40,9,27,14,14,127,189,184,131,51,61,22,28,80,175,112,125,44,26,93,62,27,45,92,90,61,55,66,42,12,37,18,29,33,23,15,38,25,17,24,30,31,19,23,14,28,26,40,31,11,10,0,34,48,36,49,30,53,67,63,21,34,32,67,79,69,22,10,23,35,33,20,16,28,26,15,9,36,50,22,20,13,21,20,17,44,32,42,29,18,39,62,82,42,51,61,47,17,51,81,73,115,110,111,73,51,91,89,36,59,195,212,216,249,243,243,222,226,229,234,252,217,216,237,236,240,244,223,243,244,250,226,232,220,234,220,244,225,243,233,216,240,244,238,252,240,242,237,231,230,235,233,246,226,217,226,235,233,224,227,247,241,240,238,222,234,224,232,228,246,243,223,224,226,227,115,30,14,11,34,15,15,2,15,28,19,16,31,25,8,0,23,31,20,5,24,18,23,17,18,193,193,184,212,197,167,191,186,152,187,193,181,170,174,209,192,186,195,174,174,199,188,201,195,193,206,181,186,207,211,202,173,203,197,219,177,196,195,218,174,201,182,192,198,192,188,162,196,206,174,207,174,193,195,187,203,202,178,182,204,198,183,193,168,189,215,193,199,207,201,190,197,185,184,205,209,187,199,176,207,215,207,223,191,202,203,191,199,205,191,191,183,189,202,211,190,183,182,207,218,197,204,205,188,214,208,206,189,215,193,204,189,212,188,199,191,188,187,180,207,204,222,158,201,184,189,188,202,220,179,193,218,198,182,209,197,199,210,209,182,194,204,196,201,219,202,196,200,195,211,207,205,188,190,182,216,201,168,191,191,208,214,196,196,193,212,172,204,191,195,189,193,177,191,186,222,188,204,209,190,180,179,185,191,199,188,183,192,199,171,206,197,202,186,189,201,209,176,198,193,180,172,207,202,172,201,192,193,182,184,205,182,180,198,174,213,190,167,190,201,211,215,179,180,191,192,198,205,186,188,195,198,209,192,198,193,196,194,207,185,195,206,176,206,195,192,188,212,196,183,181,194,214,210,199,205,197,194,200,226,225,199,197,206,198,221,198,211,171,203,210,201,197,196,206,196,223,209,195,199,213,207,217,221,205,231,213,218,222,212,224,202,222,204,219,200,213,231,221,224,225,186,193,238,195,247,216,201,207,207,223,209,204,190,209,238,181,107,171,155,104,86,116,119,99,103,76,95,69,81,94,93,101,100,104,133,83,143,174,106,115,137,168,147,161,200,198,192,194,183,130,59,44,22,25,17,22,28,0,1,27,21,23,11,12,18,49,73,69,145,192,182,202,110,120,127,110,170,236,202,255,206,183,168,109,223,221,249,228,213,221,163,162,202,206,252,164,102,60,72,62,34,108,73,34,55,225,234,135,192,194,228,129,107,172,168,245,211,230,208,159,209,195,166,222,253,229,198,52,19,19,2,24,56,28,30,24,52,57,71,23,35,177,239,210,214,173,112,181,250,251,255,250,245,139,138,215,245,244,161,71,72,90,31,43,24,67,99,103,105,68,11,46,42,25,45,23,14,18,32,8,0,25,34,17,47,13,25,6,24,31,48,44,19,108,179,113,82,80,89,85,105,54,36,54,57,58,45,12,29,28,28,44,24,9,11,25,7,17,23,50,37,33,18,25,81,147,98,64,68,25,19,25,30,61,92,49,8,60,140,92,107,211,241,181,133,129,112,55,24,14,45,6,22,4,49,31,22,23,26,27,22,41,24,40,25,15,54,33,47,38,34,36,17,26,24,48,26,57,33,55,20,20,72,77,56,27,19,34,34,19,18,15,20,39,25,54,8,7,31,28,29,38,24,53,133,83,48,43,30,74,85,63,87,59,67,54,18,41,99,107,80,94,100,58,68,66,70,50,68,175,237,249,255,227,231,243,238,239,245,225,230,241,251,252,231,230,234,233,223,226,228,252,242,247,236,229,218,243,230,241,235,240,239,237,241,240,222,219,235,242,242,248,233,236,233,225,236,217,228,233,244,217,250,224,215,217,231,228,240,242,219,220,230,238,119,0,23,21,2,7,17,18,7,1,5,26,19,10,4,8,14,24,12,19,2,7,34,32,9,177,173,191,184,201,204,180,186,192,195,176,193,190,178,204,167,163,204,156,194,218,186,195,196,174,183,179,180,193,203,193,176,194,195,192,168,189,188,205,197,202,186,183,193,187,220,209,210,193,216,195,197,187,192,181,188,187,173,199,190,189,208,204,180,173,213,193,205,210,188,214,198,199,196,203,209,187,216,179,177,210,202,198,206,185,208,192,196,172,201,199,194,191,203,202,201,189,188,194,193,222,188,205,185,228,219,196,215,204,216,216,197,188,222,182,201,194,199,198,177,207,198,191,207,185,204,181,204,199,216,195,205,186,209,205,175,208,180,213,198,213,180,215,205,193,189,184,195,178,187,193,210,216,196,169,210,158,211,212,185,171,200,190,176,193,200,202,184,194,197,183,199,187,186,198,183,170,191,205,179,204,184,211,206,189,192,221,191,214,197,178,191,183,182,200,185,206,194,208,167,188,178,184,193,174,207,198,224,191,169,181,166,177,188,186,196,202,191,178,173,206,192,190,218,185,192,215,193,205,208,200,179,214,182,194,203,187,215,208,180,210,206,212,189,173,199,171,205,225,211,202,219,211,212,214,223,197,197,197,199,233,182,205,194,207,202,195,210,216,194,198,234,217,205,199,215,197,185,202,200,226,192,213,213,185,217,194,227,217,190,221,226,200,223,205,212,201,198,243,198,204,186,203,240,229,219,218,204,211,207,198,212,206,211,242,233,204,140,125,127,82,88,99,94,86,112,105,127,97,72,77,65,82,149,157,206,196,192,204,152,76,137,241,199,159,192,178,125,154,149,98,80,157,217,206,205,181,129,128,141,64,11,7,25,107,77,32,39,22,36,36,32,49,40,106,144,115,244,255,222,254,169,164,154,113,216,240,243,234,193,237,188,180,220,213,255,156,87,73,48,60,22,104,83,42,38,191,187,138,210,206,196,97,143,215,191,249,208,210,173,147,210,190,179,231,248,193,71,3,31,9,12,41,26,27,23,41,57,81,32,24,167,247,245,230,158,145,171,242,246,237,248,245,194,136,217,242,239,193,101,105,109,118,45,38,16,111,135,80,142,56,25,59,51,25,53,34,11,16,19,16,19,28,12,31,24,12,11,48,27,59,24,54,64,141,121,54,70,61,66,55,58,49,42,40,77,34,28,63,27,63,15,27,30,7,30,43,20,14,2,25,16,28,28,39,79,85,45,61,58,15,21,3,5,59,119,59,67,124,155,74,91,183,223,194,90,155,113,71,27,43,45,38,42,11,43,20,35,39,29,20,19,33,57,10,8,45,73,69,57,95,42,45,28,30,49,28,37,49,37,18,19,53,57,82,80,73,51,55,31,26,12,27,28,16,35,5,31,12,14,37,6,15,72,198,172,124,101,60,49,66,73,93,66,77,50,55,45,38,78,103,106,111,112,85,58,78,99,35,41,200,227,215,238,236,238,220,206,245,246,243,222,242,235,251,244,224,232,223,236,248,236,230,251,221,230,217,223,240,225,237,235,232,219,244,230,243,226,238,222,214,225,224,208,240,234,248,219,221,227,196,246,231,234,218,227,249,221,242,217,226,226,241,247,229,111,0,1,4,8,0,11,35,11,1,14,6,7,6,1,2,16,4,9,12,9,56,16,21,20,189,185,174,175,208,197,186,201,207,173,196,185,202,163,196,188,172,177,183,194,192,198,194,205,210,202,181,183,183,173,191,207,176,195,174,202,164,209,203,177,195,195,193,228,180,170,197,209,205,190,208,197,183,198,180,183,215,209,181,196,192,192,198,203,204,202,179,178,210,226,200,192,178,191,182,208,187,188,204,187,180,196,181,189,204,197,218,175,187,189,199,203,189,208,208,168,211,205,216,206,212,215,213,201,219,200,207,191,204,194,209,218,219,210,200,212,215,178,179,230,176,178,221,203,205,193,179,212,187,201,189,208,186,205,176,195,195,198,198,176,186,205,187,169,200,215,212,210,211,197,164,203,188,189,193,183,204,204,178,192,200,181,218,164,203,190,200,204,201,193,207,190,173,200,185,195,186,205,182,184,175,191,210,182,198,183,174,186,185,195,194,182,162,177,186,192,179,209,195,173,196,189,191,217,202,198,213,210,187,197,183,201,187,207,190,206,183,200,197,206,196,193,198,177,187,206,187,200,165,208,216,213,187,202,200,211,200,229,195,201,202,194,191,195,204,202,202,201,207,185,198,223,218,225,211,197,199,214,218,214,229,191,180,206,216,185,212,204,206,212,223,193,217,186,203,219,219,211,207,198,219,206,219,205,222,200,218,205,206,221,213,210,219,209,205,210,205,204,223,211,233,201,198,246,212,200,204,207,210,223,217,207,207,212,233,185,135,96,95,75,70,59,73,47,71,147,211,253,204,94,184,187,219,250,254,239,239,213,221,148,88,129,198,173,103,138,108,125,122,93,82,100,229,252,237,238,236,244,208,194,108,108,118,232,232,216,179,94,54,71,50,35,20,25,44,30,61,166,233,225,178,120,176,154,161,229,232,238,225,180,240,188,155,210,195,251,153,79,51,47,70,47,115,134,69,51,121,163,157,246,206,111,80,142,211,205,252,214,234,147,162,223,196,191,238,240,109,7,17,24,16,32,42,33,29,34,62,77,28,29,138,230,253,249,172,111,206,220,250,246,236,238,192,143,204,246,212,246,115,104,107,92,82,30,89,103,128,153,133,139,74,9,19,10,44,40,25,26,15,41,9,13,12,23,15,32,31,20,38,18,54,25,66,80,112,77,66,36,62,42,29,36,24,33,33,26,14,40,37,67,41,47,21,42,22,39,19,7,38,29,34,17,32,12,74,103,78,34,59,11,32,9,19,31,58,137,115,108,140,140,80,33,52,63,77,43,60,77,77,36,72,50,66,66,32,44,9,26,28,26,32,30,48,43,15,45,38,68,59,20,48,32,38,43,71,45,32,48,50,93,72,67,71,106,87,82,81,88,72,75,43,44,29,58,24,36,34,35,11,18,39,72,86,116,146,109,94,146,132,97,73,68,82,75,50,22,47,11,54,94,81,74,103,94,76,83,66,83,49,19,214,233,252,246,238,242,234,212,251,245,222,227,227,238,248,239,228,238,241,222,246,239,238,236,224,247,210,229,225,220,244,242,238,241,245,234,239,246,231,226,226,217,217,241,212,203,242,227,229,244,216,233,249,240,240,222,208,230,248,218,240,239,232,222,230,111,0,5,3,0,24,8,37,11,6,6,11,8,4,5,6,2,6,9,14,31,6,17,30,0,193,189,194,189,192,195,177,187,187,205,206,164,199,209,186,180,201,182,204,196,173,181,189,190,178,202,191,184,192,185,222,187,191,187,204,178,188,203,203,191,170,175,178,193,207,208,187,177,167,188,197,203,191,205,204,199,167,198,217,179,190,203,194,207,184,206,197,189,196,214,193,178,195,198,197,192,188,194,191,209,216,195,185,216,211,192,196,189,181,197,219,199,175,191,188,211,196,208,205,214,195,219,217,189,203,202,184,187,194,208,215,221,210,221,194,199,223,197,189,188,185,196,197,186,192,213,203,188,210,189,201,194,206,181,190,209,198,196,215,189,174,196,195,182,194,206,182,188,167,187,174,193,192,203,181,196,190,185,190,174,198,198,181,191,196,188,198,201,196,224,166,181,183,219,186,192,196,196,203,195,197,213,192,205,167,175,190,192,192,194,208,197,158,190,180,227,187,194,182,194,191,200,163,186,184,210,210,213,173,211,200,198,207,183,197,208,186,179,190,198,182,185,202,181,172,192,205,199,193,194,212,192,220,219,202,204,216,208,199,196,194,180,209,192,225,197,205,207,202,203,200,198,180,220,206,194,203,233,190,214,205,217,227,190,199,207,188,222,186,198,234,213,231,222,194,206,209,207,195,220,213,201,210,220,210,202,223,205,218,234,218,208,221,225,214,217,205,226,224,209,233,223,228,251,227,248,226,201,216,193,214,221,203,181,229,183,96,83,65,56,45,34,35,35,76,134,201,222,204,197,248,255,238,230,247,239,184,107,123,125,59,58,77,69,77,62,50,36,29,63,41,55,78,100,111,112,156,181,137,88,62,66,90,211,243,226,175,151,143,107,112,130,162,107,54,50,39,67,143,214,194,170,202,152,159,231,227,230,227,221,235,185,180,204,238,252,159,93,87,69,62,30,90,118,93,86,133,122,167,239,179,140,124,221,211,217,229,207,211,176,193,226,204,233,229,138,10,27,26,28,42,54,10,17,35,43,58,43,8,103,242,252,255,219,88,138,250,247,239,227,243,167,126,194,243,238,250,176,67,110,72,32,17,20,51,103,122,138,122,151,62,37,46,35,40,24,60,46,31,25,26,16,32,10,41,13,42,46,16,38,54,22,49,110,76,83,30,78,53,17,34,32,26,16,4,28,30,53,52,38,46,52,58,10,2,32,27,37,27,13,32,38,29,29,86,115,85,40,32,10,25,53,44,50,71,124,161,110,61,109,104,74,51,19,31,71,43,63,65,70,97,94,66,55,41,32,38,24,4,13,41,1,23,32,21,36,58,55,46,28,25,35,46,37,93,71,68,96,87,128,138,102,87,48,61,57,72,68,81,82,108,118,84,96,80,71,41,37,30,53,65,62,131,84,40,44,56,45,67,29,63,33,70,38,57,53,31,33,44,88,89,71,93,90,95,92,74,71,20,46,216,242,250,250,237,211,241,230,238,239,226,239,219,228,231,223,224,238,237,218,246,231,250,224,230,209,223,236,231,207,249,209,247,219,219,227,211,212,241,247,222,213,234,232,201,234,225,220,226,248,232,220,230,244,241,237,226,231,231,206,248,232,249,225,220,119,1,0,2,27,32,13,18,38,17,28,10,1,2,7,5,10,35,6,1,0,2,10,7,17,196,179,180,202,194,190,178,186,198,168,198,184,192,181,181,181,161,193,215,206,180,175,185,200,184,166,176,175,202,195,209,194,212,179,185,175,195,191,221,194,171,175,202,207,186,191,203,189,205,201,200,210,196,182,188,198,205,177,198,196,172,190,208,188,202,196,183,206,200,195,188,201,197,186,206,210,181,205,183,200,176,184,190,176,195,181,184,223,201,196,184,206,208,178,205,191,222,206,204,210,200,204,201,204,206,230,222,214,185,192,205,178,189,190,194,200,182,192,197,199,206,178,220,183,198,169,178,211,200,184,209,194,182,193,181,199,211,188,183,179,182,199,198,190,173,192,196,208,205,213,200,195,189,212,190,178,220,153,184,193,206,203,183,193,213,219,194,187,187,199,219,195,204,203,217,192,165,197,187,191,188,191,174,153,172,179,195,171,172,192,179,165,210,202,198,203,200,202,172,210,200,209,193,189,203,191,192,186,183,201,185,190,166,180,190,217,202,176,167,173,182,188,212,187,206,189,192,208,195,203,167,191,206,159,179,184,192,213,200,194,186,211,204,178,211,183,207,220,185,202,211,219,201,195,223,218,208,201,220,208,205,202,184,199,190,207,181,206,200,233,219,211,194,213,204,209,211,225,201,244,217,228,217,218,217,222,196,215,222,212,193,210,228,191,211,228,222,199,199,200,232,163,138,222,229,225,214,215,232,205,205,197,230,200,231,152,46,55,11,62,111,84,106,97,70,79,65,86,71,66,136,137,140,142,119,57,14,6,18,33,45,34,0,16,39,23,39,12,12,19,20,19,38,10,34,24,15,25,48,33,39,31,86,81,66,90,89,105,132,124,122,142,186,152,117,84,57,50,171,222,190,215,191,143,195,225,230,233,214,206,228,208,177,203,207,255,148,52,60,53,81,13,63,47,40,87,102,124,157,233,192,135,179,216,218,209,226,203,206,161,188,205,221,200,132,37,27,26,23,34,51,35,18,28,71,47,72,33,83,233,244,250,230,144,141,206,215,245,248,237,177,137,174,236,236,246,172,88,106,109,15,58,108,119,46,89,110,104,132,119,38,15,29,39,25,27,48,28,33,4,26,10,32,11,33,59,15,13,35,68,36,61,149,179,157,97,54,70,79,76,42,6,17,21,27,11,19,28,37,77,97,82,57,43,62,24,48,17,29,31,50,24,35,69,84,83,77,32,31,25,30,78,63,59,75,78,160,129,106,92,95,71,91,86,62,29,61,83,68,33,83,90,57,47,45,40,33,12,18,6,19,14,31,33,44,39,41,60,12,10,20,26,58,69,85,106,109,105,59,97,72,48,44,33,44,49,30,76,72,95,70,90,139,105,125,108,82,59,71,127,135,107,66,53,23,28,29,40,25,34,37,44,38,59,37,52,25,35,59,69,99,86,96,96,101,63,24,53,58,137,255,244,240,251,221,243,245,226,243,228,233,227,220,237,250,234,255,213,237,246,228,243,232,234,251,230,247,241,230,248,223,240,254,227,244,215,238,222,226,230,243,228,247,243,221,220,241,232,245,232,205,237,227,227,231,211,213,240,239,249,245,240,227,219,249,89,13,1,18,4,10,2,20,14,21,0,4,3,0,18,8,2,22,12,16,19,4,25,25,8,195,176,199,181,167,165,193,168,179,188,182,195,200,171,173,184,211,183,184,190,165,200,153,152,216,166,195,169,199,198,172,186,187,192,185,185,179,194,201,190,199,203,190,191,189,194,201,182,164,227,193,216,212,188,188,176,190,195,199,206,191,196,185,204,203,227,166,185,185,219,180,184,200,209,183,198,201,187,179,188,202,182,193,202,182,201,194,196,203,215,199,214,187,194,193,197,207,216,213,205,196,189,201,193,202,193,190,190,195,197,208,207,210,225,190,177,206,186,195,209,188,205,189,197,189,176,188,209,203,190,188,172,168,189,191,184,184,192,205,193,211,187,176,181,204,196,159,177,205,195,195,175,200,189,206,205,189,197,179,196,207,174,193,180,185,190,203,217,208,188,190,208,196,216,196,198,185,199,195,160,175,218,192,186,184,192,189,193,199,179,206,180,216,196,196,195,198,181,205,179,195,212,185,182,177,190,180,189,192,203,166,191,199,182,204,194,185,181,194,170,174,199,189,231,219,186,183,170,206,177,182,202,221,185,178,171,176,194,211,187,200,211,197,183,185,192,199,187,202,206,189,223,187,191,201,193,191,228,192,208,193,200,191,240,199,215,194,198,218,241,219,224,213,215,199,223,206,192,218,210,208,219,230,226,200,223,202,217,217,204,230,190,229,203,204,220,204,210,206,209,205,97,34,146,217,200,217,206,212,212,205,206,215,210,191,157,50,48,63,101,98,44,79,70,65,52,54,34,26,42,34,8,29,3,60,50,10,28,27,8,30,3,7,20,16,18,11,21,42,46,19,32,39,16,9,31,15,24,15,41,16,48,50,73,50,60,54,52,88,42,88,65,65,87,81,71,26,50,186,247,182,203,180,143,185,232,233,216,234,201,235,202,162,206,213,254,137,78,103,72,46,20,24,65,21,34,96,133,223,238,172,61,142,202,174,229,255,221,179,150,193,222,223,153,67,0,5,19,29,43,23,13,23,83,66,36,13,68,205,238,251,227,127,178,195,232,233,242,239,185,123,177,207,239,251,189,95,73,108,126,24,89,128,61,86,89,98,128,144,99,25,30,51,37,58,4,31,34,19,31,45,24,15,20,34,11,37,58,70,36,68,171,190,163,153,122,122,106,107,57,6,41,9,10,34,24,32,29,45,43,67,79,56,71,32,41,3,13,15,22,47,21,36,42,51,43,16,21,37,46,33,54,38,21,60,64,106,162,113,115,96,88,103,99,64,64,73,65,83,89,55,31,41,34,38,36,32,27,19,39,14,30,44,33,15,21,46,32,28,26,33,36,54,70,55,62,35,32,21,38,38,32,39,9,41,55,27,57,56,50,69,70,45,103,119,106,125,102,120,128,84,84,67,18,38,23,32,27,22,5,43,43,72,67,44,59,55,28,31,101,119,103,84,115,111,59,19,65,110,181,248,250,245,243,236,246,213,241,217,239,217,232,234,235,246,240,239,233,247,252,237,242,236,225,232,209,219,240,222,251,231,228,241,215,218,240,221,226,239,229,238,218,224,231,222,248,235,237,236,240,231,213,213,232,243,219,221,238,237,239,235,245,249,237,242,135,8,5,37,0,1,10,11,14,8,10,0,24,14,13,9,3,30,37,6,9,12,21,8,13,186,172,191,194,190,179,208,164,169,185,183,199,170,187,178,166,178,199,193,194,218,183,190,217,181,197,214,183,197,184,179,177,172,175,199,172,180,188,182,192,190,183,172,182,196,197,190,221,204,181,184,198,188,160,165,198,156,206,209,185,178,186,195,197,175,187,211,189,199,209,197,195,191,190,206,202,184,191,209,182,199,174,206,181,192,199,189,194,188,187,200,182,191,161,176,211,208,168,213,203,203,201,186,207,191,194,197,226,218,232,199,208,219,215,209,196,196,183,198,187,208,188,184,195,216,173,219,189,214,174,190,205,174,211,208,194,147,193,181,189,213,214,182,197,201,193,198,181,181,204,214,185,196,198,204,178,198,193,193,211,173,185,203,188,202,196,188,179,189,173,184,174,185,211,194,190,164,200,199,171,201,196,182,176,200,179,200,179,214,163,186,176,192,203,186,183,174,185,175,174,216,196,170,164,204,178,176,182,196,193,185,191,176,186,173,208,188,225,173,189,193,187,178,176,182,190,194,202,165,198,191,195,225,213,207,209,178,216,187,186,189,204,202,192,186,212,216,203,202,216,207,189,194,197,201,209,208,201,225,218,188,215,195,225,214,210,177,199,213,221,204,213,216,206,210,208,205,220,228,204,237,228,194,200,242,207,225,206,184,213,222,231,227,222,206,211,214,206,224,214,185,75,28,89,193,205,212,197,203,201,219,198,199,211,211,183,124,75,44,87,32,49,52,49,54,75,56,37,29,23,34,44,60,19,72,45,23,15,12,36,10,19,50,20,10,12,26,18,13,35,26,13,10,39,10,18,26,30,19,14,14,32,24,63,87,82,37,48,62,61,75,25,48,48,63,69,15,76,197,200,138,214,174,170,211,209,248,218,239,200,216,237,167,190,238,250,173,71,81,59,41,11,106,84,31,41,132,209,248,253,146,70,170,211,180,218,238,215,130,158,230,225,203,74,23,11,22,4,42,42,28,31,24,74,71,57,45,160,239,244,224,158,158,235,183,224,255,225,188,135,160,229,252,217,246,137,66,102,95,95,38,63,82,32,87,82,82,103,144,76,26,34,35,28,44,48,25,29,26,10,27,25,39,22,17,33,107,132,148,118,156,205,171,145,129,128,135,90,67,37,33,51,22,33,30,25,43,39,75,64,75,93,94,86,29,25,12,24,44,50,29,37,13,11,41,3,29,26,16,26,17,20,21,52,70,50,65,92,65,126,126,130,84,111,116,120,82,64,79,58,56,55,50,38,18,52,29,29,36,28,28,33,23,17,53,17,15,71,67,45,45,40,14,24,24,25,2,13,40,26,23,18,33,40,27,41,53,49,33,64,18,51,47,84,60,88,63,66,89,67,76,31,42,47,16,17,32,28,33,37,70,84,77,79,63,66,50,52,51,92,132,97,69,101,109,76,56,116,107,90,147,227,223,246,249,255,229,244,247,230,228,223,247,212,238,222,237,218,237,231,251,214,237,236,207,237,231,227,212,228,236,234,220,246,197,229,242,235,237,237,222,214,230,244,214,216,235,249,238,244,246,245,206,227,243,231,230,220,240,237,215,239,240,238,225,134,4,6,1,9,30,19,12,15,2,20,3,39,8,14,9,18,27,21,7,9,19,20,0,29,192,192,172,189,172,182,174,195,187,165,191,170,180,177,170,186,170,192,171,195,212,170,201,158,202,172,179,216,186,191,170,167,201,170,180,175,187,217,195,209,212,193,177,169,173,166,200,199,179,191,206,204,204,191,186,191,186,211,184,205,197,185,194,197,185,194,163,205,189,184,205,181,212,185,203,217,200,181,195,218,211,181,200,175,185,173,197,181,212,198,199,187,184,203,211,190,202,185,200,185,210,209,182,180,210,219,209,197,210,208,182,183,196,172,177,204,181,192,197,196,188,182,192,201,226,202,210,214,193,212,202,196,190,204,204,189,194,177,167,181,193,187,178,201,193,184,175,175,187,196,203,183,215,216,184,188,211,188,194,192,192,184,208,185,203,179,181,186,190,209,209,205,192,210,184,173,181,185,189,205,224,173,191,191,187,180,186,200,194,192,193,198,184,176,161,187,203,168,189,197,193,195,207,194,220,190,204,213,217,189,176,196,215,182,183,154,189,172,191,171,181,169,206,208,218,211,194,216,183,209,210,183,176,231,195,213,231,217,188,194,179,181,197,200,182,174,201,178,190,199,210,202,218,205,205,220,221,208,233,192,222,211,205,179,216,193,186,208,204,210,207,221,217,191,217,197,226,203,215,238,209,206,226,191,209,210,218,235,182,216,206,205,230,218,210,216,204,217,214,230,216,116,78,165,208,218,230,206,220,221,210,189,200,212,206,239,108,23,9,44,59,27,54,26,35,38,54,54,40,25,32,71,47,40,71,42,10,27,19,16,1,20,24,6,22,9,29,60,16,31,1,31,10,38,22,22,41,20,6,21,46,49,37,58,84,64,82,55,62,62,64,49,74,56,72,40,17,120,176,174,193,242,157,163,221,205,241,237,206,209,219,218,174,184,201,246,127,61,109,59,69,67,93,92,28,55,177,243,248,201,145,163,240,213,181,187,229,211,142,167,233,227,132,44,0,17,16,61,36,38,20,43,61,52,55,11,164,252,252,248,157,153,232,230,211,211,242,178,124,192,231,250,255,235,239,96,73,105,86,72,29,52,89,105,92,66,93,129,129,62,54,11,16,27,42,20,34,26,9,53,14,57,91,40,53,127,215,246,194,129,150,195,137,123,90,101,65,45,24,10,9,24,24,34,23,36,34,50,38,74,79,114,102,72,69,45,11,64,41,25,28,49,34,37,25,6,13,21,1,13,33,1,25,30,17,22,23,19,67,104,118,146,111,85,96,91,95,87,94,73,45,42,38,44,9,24,19,24,33,29,14,43,19,51,11,31,18,24,43,44,67,38,43,12,34,3,27,10,7,26,6,41,10,31,41,23,19,43,34,48,21,47,62,31,41,35,34,57,49,32,50,26,8,31,28,2,13,41,49,48,90,95,76,74,52,59,52,45,39,82,115,123,90,76,91,87,83,115,49,26,22,83,221,233,255,251,233,235,220,233,223,232,235,237,215,216,227,219,245,255,238,247,241,235,239,235,232,221,219,212,247,242,232,228,238,222,237,234,230,234,240,243,235,253,244,240,235,243,232,245,231,247,230,215,219,222,239,243,229,216,221,237,232,212,215,90,19,11,18,0,10,29,7,10,17,44,20,1,9,5,7,7,15,15,6,12,26,12,5,4,186,174,185,195,184,197,176,155,188,197,173,178,203,198,198,181,184,178,192,171,201,157,204,192,179,195,196,185,177,188,182,174,203,196,203,181,171,179,188,153,180,183,219,191,162,167,173,190,200,191,173,193,188,179,215,190,179,196,200,188,194,215,193,174,211,198,221,177,199,181,196,195,176,198,204,196,181,188,196,183,227,205,190,184,209,216,208,216,185,217,190,176,198,193,191,199,185,193,188,190,215,185,201,200,198,233,205,183,183,197,195,188,192,177,211,188,199,207,197,204,208,181,181,205,173,179,173,195,182,197,181,194,178,173,188,182,188,191,181,172,201,202,189,183,228,167,200,194,178,186,204,207,192,166,184,196,199,206,212,179,197,186,209,199,210,182,185,186,177,200,202,189,181,199,186,186,174,204,193,208,204,202,195,193,196,204,186,189,195,184,185,188,183,189,200,195,170,204,159,187,197,183,190,197,185,206,214,192,184,179,218,186,196,193,179,198,207,185,185,182,185,210,190,172,199,206,193,235,197,220,200,181,195,208,209,177,222,216,189,229,210,201,188,202,214,210,188,191,206,231,234,195,189,194,196,218,220,204,240,212,181,196,202,190,220,185,195,214,223,235,187,217,204,207,201,197,204,196,202,200,219,215,220,222,213,223,232,207,208,223,221,210,241,222,230,208,235,219,245,227,207,200,179,204,231,222,216,230,216,179,222,195,225,218,200,218,132,69,5,22,0,30,44,60,15,36,49,23,48,51,23,49,47,57,68,49,32,32,31,57,16,12,24,46,7,1,19,18,12,23,28,15,13,45,22,53,28,8,27,15,54,52,42,62,77,69,92,76,52,55,47,17,54,29,82,25,27,133,225,186,209,231,144,239,235,194,221,199,222,198,251,222,204,223,214,255,147,65,107,69,85,22,74,89,40,39,170,231,232,208,125,172,253,210,185,206,253,202,149,214,215,163,70,14,23,9,30,68,18,44,17,74,58,51,36,120,237,244,255,166,163,211,244,246,183,243,215,117,204,229,240,210,237,255,189,48,94,126,75,78,38,31,52,81,48,47,64,143,121,46,26,41,27,44,70,6,43,10,19,11,59,106,150,125,132,195,237,169,118,100,79,76,97,75,73,42,28,13,20,32,35,51,20,17,60,55,45,43,49,37,72,85,77,59,72,22,36,34,21,43,28,34,34,13,15,27,0,24,23,10,20,15,8,19,21,33,36,35,50,108,114,160,101,94,67,65,92,92,90,75,77,69,34,29,34,13,30,17,57,22,29,29,35,34,39,13,10,13,23,32,62,30,15,43,20,40,35,21,31,9,33,31,35,16,20,29,1,51,13,45,55,33,29,48,40,37,19,17,43,50,7,40,19,24,3,31,29,22,46,25,65,85,94,58,44,39,85,57,20,90,97,96,115,84,123,89,124,67,63,65,32,34,153,243,241,244,227,221,208,234,235,221,233,228,235,220,235,248,210,223,210,242,241,244,233,227,219,245,219,245,213,236,234,225,216,220,242,214,232,222,236,233,214,231,240,222,241,213,228,227,236,218,238,231,236,225,237,210,234,233,235,239,229,210,247,125,2,5,10,12,27,1,3,4,24,4,22,7,5,10,14,25,20,39,19,4,16,9,20,1,164,198,187,185,173,180,188,180,173,194,167,193,176,173,195,187,200,191,184,181,195,190,189,183,192,168,200,193,202,186,189,187,184,211,202,188,208,192,189,189,181,173,178,180,168,183,188,197,197,196,205,174,183,195,191,192,203,197,198,184,183,199,191,181,193,186,177,188,173,185,194,173,194,184,195,202,214,179,196,187,205,209,176,183,211,201,187,185,194,192,194,182,196,195,192,189,181,188,205,209,182,192,209,209,178,189,200,213,185,210,184,195,205,207,207,180,201,190,203,207,206,201,184,177,219,180,192,198,205,190,197,197,211,202,184,209,205,193,193,187,205,213,177,199,203,212,193,178,187,181,185,187,218,199,174,189,198,205,171,202,196,211,197,185,182,177,219,194,195,198,200,200,192,210,184,219,196,193,164,203,192,211,195,203,181,205,188,212,184,200,210,189,178,174,185,224,199,169,201,178,182,201,185,214,219,185,206,205,202,205,186,214,182,196,175,195,182,209,197,194,199,204,182,211,183,192,203,204,214,203,174,188,219,195,204,192,220,197,192,230,213,196,205,210,191,184,207,189,197,201,195,203,179,228,213,218,191,195,215,218,229,239,200,166,229,177,200,201,223,196,208,243,191,215,204,204,197,200,195,199,222,211,216,211,219,221,218,201,237,236,216,200,217,196,208,196,241,232,221,202,232,233,232,230,218,233,200,203,206,214,200,189,210,209,212,235,192,136,119,78,3,2,12,10,18,54,42,30,30,17,49,71,59,51,46,32,53,45,39,55,48,39,31,29,24,44,8,22,14,45,34,46,29,14,52,34,38,36,35,45,92,95,98,85,95,74,81,84,57,45,36,61,27,6,45,61,83,201,217,213,238,199,129,225,232,190,234,235,219,216,233,208,178,179,205,254,126,51,87,37,71,63,63,117,43,62,171,211,249,171,59,164,245,211,195,179,245,202,182,209,120,73,15,7,7,9,37,40,39,8,45,71,53,20,82,236,237,238,195,154,198,244,242,229,192,197,140,197,251,233,252,233,245,243,118,6,72,88,50,44,75,72,84,44,38,34,128,152,129,30,33,35,33,40,39,49,33,6,22,12,39,137,112,159,118,107,116,51,47,13,19,48,49,65,14,32,19,28,20,21,26,14,54,75,77,56,50,35,29,48,38,50,23,9,71,65,61,50,46,35,42,43,31,34,22,19,18,20,18,24,27,9,22,22,11,17,32,32,33,28,67,76,84,63,82,79,58,69,87,78,69,61,36,18,17,12,37,25,33,40,31,23,24,22,25,23,35,8,13,15,40,41,4,21,45,26,22,44,26,24,28,8,28,31,21,16,11,23,49,29,42,55,71,65,36,30,30,28,25,18,11,18,22,28,12,14,9,29,25,20,60,78,79,80,57,70,67,41,44,60,106,108,114,86,137,109,111,75,111,115,73,24,108,213,245,244,242,220,231,223,220,234,217,240,234,249,228,240,227,225,210,236,229,235,245,231,251,225,241,211,235,234,231,234,255,225,231,235,211,235,251,235,246,215,215,231,214,235,240,237,221,246,236,226,208,240,249,222,235,230,237,241,240,240,215,140,3,0,18,17,27,2,10,13,26,5,2,21,0,9,5,13,12,9,12,14,23,32,34,18,185,172,179,185,178,207,186,171,184,204,173,218,183,195,209,185,185,182,200,187,169,199,189,207,200,182,197,193,193,176,174,187,180,178,174,201,183,196,211,192,175,185,187,189,181,192,182,201,194,186,175,181,208,195,175,198,201,179,202,188,183,186,191,205,186,219,205,197,227,201,192,207,182,217,190,196,198,193,191,171,192,191,189,213,194,174,194,177,201,179,190,189,185,217,198,189,163,197,187,203,199,186,205,186,203,178,203,189,225,193,200,200,179,218,210,183,193,199,174,194,197,230,203,179,187,207,212,211,186,202,190,207,195,183,209,196,202,193,189,208,173,197,157,207,215,175,192,194,202,190,212,199,195,192,201,208,184,197,187,176,185,208,170,212,178,160,197,179,184,197,208,194,181,186,183,184,193,179,188,195,204,198,190,220,186,170,162,192,179,184,207,189,193,217,218,205,188,206,172,185,182,215,211,211,219,207,188,197,199,178,192,195,198,197,192,207,188,200,203,166,180,191,203,207,195,184,212,190,196,204,193,212,224,211,204,199,171,193,208,216,210,202,216,212,216,195,194,202,216,215,218,206,207,225,224,228,222,195,240,203,208,215,210,211,226,218,214,210,209,206,216,219,181,217,215,222,216,223,193,220,199,210,208,198,216,203,195,228,229,201,206,221,216,194,201,236,218,215,233,234,206,211,210,194,215,198,222,222,218,192,218,206,224,204,207,190,217,130,195,187,74,15,20,28,12,12,56,35,31,19,13,66,45,79,60,45,37,37,34,92,27,39,35,13,24,23,31,28,28,22,30,24,39,32,29,22,20,19,58,91,48,71,71,79,50,13,87,89,56,22,27,75,84,108,182,173,121,219,203,162,224,180,144,230,201,226,247,208,221,201,214,197,186,194,207,229,175,47,121,58,63,91,101,124,61,55,173,247,238,144,37,169,227,231,227,169,236,185,201,220,53,21,21,12,23,26,33,13,16,53,27,56,35,77,220,240,225,185,142,218,240,231,234,230,170,135,190,227,235,249,237,235,237,144,57,43,96,55,50,100,82,92,107,101,49,107,143,129,119,25,15,7,26,42,18,36,41,6,31,38,106,135,54,74,28,19,34,38,14,41,17,7,25,17,8,31,31,15,35,78,55,78,79,107,124,75,69,27,16,45,32,33,31,37,39,36,54,42,27,30,38,38,50,33,13,11,8,21,17,30,13,19,31,23,41,18,32,23,24,44,58,22,33,83,56,75,63,61,35,45,78,53,35,15,1,2,20,10,53,48,31,21,33,19,56,28,37,32,21,30,33,21,56,52,26,21,26,40,13,24,22,26,25,31,33,42,35,44,97,73,49,61,72,62,65,77,51,22,52,8,33,55,36,63,41,31,42,35,39,20,45,83,74,54,60,65,79,71,41,52,102,140,135,105,109,110,100,76,74,89,99,71,71,187,235,229,252,242,238,245,238,223,224,255,244,242,235,224,196,239,223,249,231,249,236,245,255,235,225,253,239,244,239,250,225,243,211,211,243,249,237,241,212,223,248,219,222,238,237,247,229,230,223,246,232,232,226,209,241,241,237,240,227,239,215,122,15,9,4,4,50,3,14,10,2,45,14,1,8,0,13,10,8,24,13,2,8,2,15,0,156,185,198,187,207,190,176,183,190,201,175,202,178,168,198,196,204,194,164,177,155,198,217,184,215,188,190,200,197,182,207,187,180,192,197,168,204,183,197,181,178,177,198,188,190,160,186,214,187,192,202,221,180,178,202,180,209,193,215,188,180,191,194,195,189,177,178,176,188,204,168,175,159,224,187,221,200,179,206,190,194,202,210,204,219,188,164,179,185,205,191,169,218,199,212,180,195,185,195,207,200,220,218,187,209,187,181,190,189,215,201,214,208,203,189,189,211,203,201,196,191,222,176,200,212,194,200,180,184,180,217,184,199,187,195,190,208,199,179,178,199,198,167,184,185,196,168,204,185,192,204,194,206,193,191,185,184,207,206,189,190,216,215,158,197,194,211,193,192,205,206,196,197,210,195,198,188,192,229,192,204,199,202,223,213,193,206,185,220,199,182,178,179,216,201,196,179,222,211,200,205,189,202,210,194,203,225,199,176,191,179,197,166,176,200,184,210,172,218,202,198,200,203,212,174,186,203,203,201,192,218,241,199,191,220,224,224,205,179,222,213,210,209,192,216,202,229,229,204,206,205,208,214,203,221,208,197,191,202,203,227,217,198,207,206,194,188,178,198,202,190,198,208,216,227,192,231,204,206,223,210,196,203,199,231,234,210,223,208,208,208,208,197,215,222,213,211,224,198,223,216,214,222,206,220,210,238,226,217,218,204,209,207,194,199,193,181,137,212,254,127,76,33,11,18,11,50,37,47,40,5,36,36,31,50,19,41,12,7,11,49,41,24,32,39,32,28,7,15,46,6,43,18,36,48,18,41,19,48,96,46,42,62,52,40,51,62,51,35,59,133,244,222,210,232,212,111,135,148,172,235,150,156,245,214,214,229,216,226,233,229,204,194,195,231,240,185,77,157,92,75,56,49,98,72,66,209,239,224,64,40,198,207,243,223,213,240,196,160,116,13,38,0,7,37,48,44,55,45,71,77,47,65,211,251,246,179,142,187,237,247,239,236,170,98,152,244,236,234,219,241,198,134,97,42,82,97,38,69,96,67,39,42,97,115,112,120,159,92,19,24,10,7,33,53,50,51,16,35,96,115,76,33,40,16,38,13,39,0,8,1,7,12,5,32,27,0,34,79,76,119,93,83,92,114,89,85,35,56,62,65,25,40,13,44,31,37,16,7,7,60,14,21,36,45,31,44,31,45,38,12,14,40,14,13,22,4,13,23,27,44,44,31,29,61,67,64,67,59,62,26,56,7,14,27,13,24,33,40,33,30,23,33,39,42,32,23,29,32,31,4,25,46,26,36,31,25,32,44,15,54,33,43,60,44,35,39,57,69,59,45,25,30,51,51,68,54,62,64,34,44,17,35,32,26,22,31,8,32,36,48,86,76,90,53,53,68,74,13,71,93,114,131,129,126,81,90,111,97,79,50,60,56,159,228,238,247,233,233,239,246,244,245,234,239,247,231,226,239,221,221,246,241,234,249,233,220,221,249,223,222,241,233,241,237,233,231,212,241,238,234,230,226,214,248,237,246,224,247,222,224,222,232,241,249,249,247,221,222,237,235,237,236,249,221,105,0,2,13,3,25,40,2,0,8,20,22,11,5,12,5,10,5,15,8,2,13,26,5,17,187,188,149,187,164,181,181,192,195,178,168,192,183,176,173,187,180,191,185,204,166,182,201,181,185,178,188,203,197,181,206,158,218,194,172,221,171,176,214,159,179,175,201,217,203,179,188,194,175,157,196,194,217,186,181,204,181,188,172,200,210,203,204,205,196,213,195,185,199,211,198,198,192,205,219,174,186,205,169,219,224,211,205,201,177,201,187,207,191,194,194,206,198,164,193,207,199,192,194,195,171,204,176,189,154,202,191,185,202,190,189,195,186,211,174,200,200,194,178,204,172,189,184,206,197,208,182,221,177,210,198,193,207,183,190,188,192,180,189,172,191,187,191,199,189,198,212,179,178,188,191,201,189,174,192,176,215,196,193,189,188,178,209,180,189,228,188,176,186,183,211,235,174,184,207,196,200,196,207,182,219,199,221,198,201,215,184,186,199,206,204,166,219,195,205,217,232,184,201,202,206,187,201,196,197,195,178,203,216,208,209,198,183,193,174,203,184,199,198,211,232,190,204,193,206,203,209,185,203,197,203,205,211,228,206,224,223,195,228,179,205,227,199,216,205,202,199,213,210,205,200,213,224,211,226,205,209,213,227,212,213,202,186,225,232,209,231,200,209,200,211,195,211,207,217,232,223,194,203,215,220,223,195,211,224,213,235,227,235,194,212,228,224,221,190,215,213,239,209,206,233,197,216,184,223,221,217,219,210,203,229,226,214,207,201,204,220,174,177,232,132,114,11,31,95,22,49,28,49,46,65,58,43,51,31,10,29,46,34,40,41,39,23,47,22,17,36,25,37,25,25,27,43,27,25,20,32,14,46,81,49,60,33,36,53,15,23,38,133,150,221,244,232,209,235,125,76,116,163,233,220,135,210,244,205,205,224,229,218,203,230,199,164,185,202,249,157,76,158,86,73,13,21,87,55,44,208,250,155,40,95,241,128,134,202,169,235,135,115,26,5,19,9,52,47,40,16,30,47,62,56,55,204,249,247,216,124,193,217,246,216,218,182,106,116,213,220,242,241,239,187,149,218,126,52,69,100,70,76,107,73,90,32,72,95,101,150,130,77,1,53,28,30,43,41,32,49,36,7,58,60,30,16,30,32,15,40,26,5,12,17,34,19,55,1,23,17,52,71,57,90,83,50,107,117,117,105,83,68,37,49,29,50,42,21,47,25,27,19,23,26,41,32,49,24,29,39,19,15,29,24,21,25,15,18,21,25,44,35,49,23,52,57,5,15,31,65,77,70,60,21,51,11,18,20,4,42,73,63,73,40,16,24,13,36,25,22,15,16,39,28,21,41,25,14,37,42,53,44,8,30,118,140,114,116,110,63,70,62,57,91,52,50,9,60,86,86,88,92,56,89,74,48,43,35,59,37,41,20,36,42,67,46,70,64,81,57,66,56,64,89,111,111,96,112,90,66,64,79,95,36,41,36,120,244,221,246,233,223,209,247,248,218,235,240,229,241,249,240,241,247,229,221,229,244,224,223,228,229,229,234,237,252,242,249,245,230,243,239,252,230,213,224,233,226,245,242,240,233,223,225,245,242,238,233,249,217,234,218,244,223,230,231,231,240,108,3,18,0,18,15,15,45,22,8,29,36,7,15,4,13,1,18,1,2,7,31,9,24,26,168,186,207,195,191,200,155,189,194,185,199,165,192,168,195,174,189,190,187,172,197,184,189,191,194,166,206,173,180,180,179,193,201,190,172,194,179,196,202,167,204,175,196,211,186,195,185,184,197,213,182,189,207,186,197,215,195,192,182,184,205,179,213,218,199,181,176,186,216,223,186,195,196,193,208,192,181,185,196,220,169,179,186,191,214,206,196,202,182,189,206,202,189,196,186,201,188,181,207,194,208,196,208,205,205,180,213,199,187,173,215,181,198,205,193,190,173,201,207,209,226,191,193,180,204,190,205,189,189,188,181,190,183,200,210,185,213,197,178,189,201,170,189,195,188,178,189,189,185,178,196,196,174,194,197,195,195,189,179,204,217,196,180,199,204,187,184,192,171,202,198,219,193,183,212,177,211,203,182,191,213,183,187,194,209,218,188,207,206,167,198,208,204,210,196,175,215,209,227,178,213,211,188,200,191,200,178,216,167,208,184,196,179,165,193,198,206,190,201,207,214,196,218,195,219,190,211,202,220,195,222,219,209,221,208,210,208,208,226,223,204,203,211,230,205,201,204,197,229,221,195,215,206,189,206,221,227,229,212,179,213,233,198,213,194,203,191,175,209,203,199,198,220,230,219,222,229,211,213,218,221,221,219,198,196,218,208,233,224,225,213,228,220,224,218,214,212,219,230,204,215,185,185,197,228,242,198,218,199,223,232,213,211,213,166,174,236,174,220,198,107,91,59,171,220,183,212,251,250,255,222,229,202,179,171,159,228,137,63,33,12,48,33,39,17,20,26,35,29,24,26,37,12,32,59,76,92,48,18,42,38,50,35,42,49,73,162,175,239,217,242,239,155,135,188,113,121,224,184,246,231,135,224,242,206,206,219,214,213,171,233,228,181,181,204,246,154,61,159,73,58,48,16,81,50,66,220,238,115,40,86,118,58,160,215,207,206,91,50,13,11,22,38,35,33,24,36,74,54,49,26,142,255,239,253,176,202,222,234,242,201,185,142,154,187,247,249,220,189,175,124,189,249,132,36,32,70,80,69,161,132,143,31,63,77,87,143,130,56,25,26,15,35,61,56,24,26,14,17,32,38,18,17,1,17,32,43,18,16,41,20,13,36,34,7,35,33,93,94,96,122,91,81,83,132,134,43,57,72,51,81,24,35,29,31,33,40,25,38,32,30,41,45,21,57,39,11,50,3,12,18,16,39,41,34,10,25,18,48,29,28,47,28,53,40,40,46,59,69,53,53,26,28,35,5,18,40,24,32,48,31,42,2,33,38,31,19,12,33,42,40,31,2,27,8,28,26,23,19,29,71,154,177,179,177,165,147,115,56,56,89,44,7,11,61,52,62,38,42,71,65,86,123,117,88,66,17,13,42,27,64,92,83,49,77,60,47,74,47,48,88,111,109,103,98,107,59,26,45,86,74,79,14,61,219,220,240,247,227,222,239,249,249,209,243,239,232,250,246,232,230,211,228,233,228,232,230,228,227,240,228,230,204,217,228,239,224,235,213,237,189,238,195,238,251,236,240,223,237,236,240,205,236,228,237,248,246,214,224,245,240,236,242,224,229,112,7,11,11,6,14,2,13,11,32,11,29,20,3,0,35,13,3,2,14,0,33,14,7,0,179,182,167,174,191,191,201,186,169,181,184,193,223,169,201,195,192,203,179,177,199,173,177,187,207,177,195,182,197,165,199,191,194,218,212,191,197,195,200,195,169,169,190,201,172,194,211,167,207,192,209,197,197,186,192,204,204,196,172,225,218,212,185,184,174,202,205,214,199,217,185,180,205,185,179,181,192,211,181,228,218,205,192,166,182,208,222,187,200,196,194,212,191,179,192,200,204,171,178,184,216,196,216,188,194,185,184,189,191,165,199,191,212,194,204,198,191,197,195,195,198,199,192,201,182,195,183,191,203,186,183,182,199,203,184,203,198,218,216,178,216,200,188,184,188,192,212,195,198,201,204,210,184,217,223,213,195,198,174,219,195,183,197,214,185,196,181,186,209,212,191,197,201,221,219,192,183,184,218,211,203,195,206,214,201,206,198,212,195,181,214,199,219,182,212,209,195,196,219,180,206,205,191,191,199,205,233,195,203,187,211,205,207,217,195,206,193,192,209,223,206,219,209,220,203,219,210,189,224,222,202,205,224,190,222,208,192,202,218,199,225,230,193,204,184,212,220,205,218,240,218,227,211,212,204,228,212,222,220,215,198,206,214,185,225,209,208,218,199,207,211,207,188,214,233,193,209,209,228,220,218,221,212,195,220,202,210,208,195,234,204,220,194,209,236,201,212,234,209,214,212,197,212,188,236,216,212,224,224,228,198,217,221,188,198,204,215,189,195,182,117,114,41,161,242,250,246,241,242,242,251,244,243,214,249,247,244,178,51,42,128,133,80,24,26,17,20,55,34,34,21,40,25,98,197,253,250,87,131,170,146,159,177,171,176,241,253,248,237,228,231,181,89,135,201,150,189,177,208,255,186,149,221,204,236,201,230,222,219,207,229,238,144,208,208,252,142,66,101,72,47,37,46,111,42,52,201,201,104,60,34,3,57,214,245,211,192,37,21,28,9,31,51,54,25,24,70,43,64,46,110,238,240,244,177,206,251,248,253,206,176,97,144,197,225,230,245,225,151,143,184,210,240,153,6,58,87,88,37,78,120,104,48,72,72,115,137,125,62,23,42,33,34,22,33,36,36,0,26,8,26,23,20,20,12,31,37,22,34,38,41,31,27,46,46,25,39,96,113,119,116,89,112,128,85,65,64,89,66,52,55,64,36,26,38,30,45,31,49,32,28,52,50,35,17,29,29,20,35,24,3,16,30,11,39,4,3,23,18,50,39,20,37,47,46,64,35,70,54,45,57,32,36,34,29,59,39,10,13,37,10,32,28,8,20,15,23,5,36,19,67,12,30,12,31,12,11,37,28,20,105,151,203,156,145,172,132,156,102,69,89,49,33,25,33,13,37,33,38,40,53,60,86,78,123,72,31,18,65,21,61,70,59,70,85,85,60,74,41,37,88,98,125,99,126,92,49,81,112,129,124,114,63,26,204,229,242,226,247,246,244,238,230,232,222,234,215,225,240,222,244,234,224,241,226,236,245,213,232,228,244,248,246,219,237,231,224,237,231,242,238,242,226,227,225,226,232,238,234,231,243,243,244,249,232,228,238,248,214,233,228,244,247,242,220,114,3,0,5,27,31,8,26,9,10,15,12,31,37,0,16,6,13,13,10,18,9,10,15,40,182,204,187,208,188,193,199,188,184,155,186,188,184,188,201,185,224,161,222,175,183,162,193,187,201,187,197,169,204,174,184,183,172,197,197,183,168,186,207,172,180,207,192,205,194,206,193,182,220,192,211,194,186,206,180,182,211,198,210,202,199,207,209,201,186,205,182,208,196,200,184,187,211,190,197,206,210,205,173,200,214,187,192,201,201,173,182,196,183,180,175,186,187,191,186,209,177,191,196,168,189,189,202,188,204,182,183,192,207,189,192,175,209,192,207,208,199,212,167,172,172,205,192,196,190,184,194,183,179,176,198,196,180,203,189,207,221,171,202,177,209,204,204,205,190,203,203,185,197,191,188,196,190,197,180,199,189,185,176,217,219,194,213,226,199,206,192,217,197,189,197,187,201,185,212,212,203,189,193,203,190,221,192,211,200,206,207,224,210,208,210,221,213,236,199,190,186,206,207,190,215,196,211,207,215,177,234,224,209,198,204,213,191,209,202,200,194,205,211,205,235,201,191,181,204,195,215,235,211,210,209,222,228,203,210,209,215,195,215,206,228,223,216,199,188,221,224,213,237,203,209,204,216,204,187,205,194,236,214,224,215,199,223,202,229,210,230,198,234,214,208,208,180,224,218,206,227,212,206,207,180,216,233,196,188,227,209,215,228,211,216,207,210,215,222,213,218,207,223,203,197,216,220,217,208,232,212,196,196,216,213,193,218,182,191,182,255,221,207,201,107,105,34,180,248,230,244,243,248,240,228,226,220,216,208,234,235,98,56,50,159,155,85,40,26,41,31,41,23,60,26,39,53,29,139,241,255,148,85,185,196,251,237,239,221,255,248,237,200,147,225,208,150,193,185,118,126,134,187,253,146,168,235,242,196,194,210,219,213,202,231,227,154,200,211,255,149,54,117,70,68,44,27,91,76,44,209,204,74,65,8,5,130,244,246,232,72,14,12,8,9,48,44,45,28,39,40,76,34,80,225,249,249,202,224,231,217,250,254,228,126,102,208,245,241,223,242,169,96,178,232,253,253,159,41,47,78,87,48,23,36,57,32,110,108,93,135,79,19,49,32,36,47,68,10,43,54,57,18,29,18,17,49,32,38,37,36,42,45,44,20,29,27,21,29,33,29,68,100,51,86,103,97,82,71,35,65,86,56,48,66,36,34,34,50,41,26,41,42,42,32,42,64,34,37,13,40,31,32,27,7,23,41,34,39,35,16,30,31,27,32,60,25,55,58,69,52,50,54,68,41,65,27,31,39,65,5,17,2,20,8,21,21,45,3,24,28,30,30,35,26,32,32,23,35,18,36,51,74,77,128,153,142,129,125,153,166,145,101,74,89,51,30,44,19,16,20,15,12,33,19,27,64,84,93,61,11,45,34,17,60,44,50,71,89,93,36,60,38,48,71,93,120,101,106,95,93,137,99,71,40,88,96,55,176,231,227,226,239,244,242,234,208,236,218,218,239,233,240,234,234,242,231,230,243,242,221,242,233,233,230,242,221,224,196,221,235,235,243,226,239,241,230,233,230,248,226,246,247,214,232,241,215,207,244,250,231,229,221,250,244,222,249,227,223,123,17,2,5,7,23,19,36,6,16,24,11,16,5,0,4,1,22,28,20,13,8,3,17,6,170,198,184,212,189,164,191,199,200,179,169,188,197,197,189,183,206,216,197,213,193,206,192,186,185,168,195,200,202,203,196,186,199,193,207,162,185,183,205,200,200,183,177,192,187,182,167,185,192,176,192,210,190,191,179,192,185,187,191,215,202,196,171,182,200,181,207,233,191,212,193,189,182,188,213,191,205,180,201,199,180,204,191,195,191,209,183,203,200,195,203,188,190,184,182,209,223,198,184,182,221,206,167,204,194,185,207,194,199,193,199,197,220,169,205,181,217,199,210,206,204,201,183,192,205,166,183,206,191,189,195,211,183,200,195,166,216,181,202,194,210,180,186,206,192,194,186,188,201,211,193,203,194,190,192,218,210,206,179,201,210,199,193,186,198,206,209,187,202,205,216,235,190,204,206,202,206,224,225,230,201,205,215,203,215,209,234,193,191,202,215,220,196,179,218,210,209,216,224,197,206,221,217,221,172,204,216,200,197,209,196,207,215,192,220,184,231,224,196,195,202,220,210,209,225,207,219,208,195,222,227,215,218,217,220,234,215,230,214,209,229,229,226,205,224,223,205,223,196,207,211,213,223,213,224,223,216,211,213,199,199,202,210,222,217,196,212,214,214,186,225,230,182,235,235,221,200,225,231,179,233,218,196,208,223,203,208,209,221,193,217,220,190,215,212,198,209,214,207,206,205,184,224,200,216,209,223,199,222,234,227,211,222,196,197,198,241,232,205,124,65,85,35,121,176,203,220,233,217,211,215,183,151,173,131,184,188,86,48,101,179,153,107,57,14,10,47,36,43,54,10,30,57,31,99,214,211,117,27,60,178,248,232,204,166,212,165,184,170,138,227,218,201,225,187,111,132,166,237,247,161,189,245,206,228,209,224,249,232,189,218,215,191,201,188,246,165,17,86,88,88,67,73,73,85,61,198,188,81,35,9,36,207,231,255,143,45,13,7,7,43,52,34,4,48,60,87,6,79,207,242,234,203,215,237,254,244,241,240,143,153,238,243,240,211,230,225,113,169,226,239,249,240,213,93,39,18,65,89,72,52,67,130,87,107,126,117,85,9,18,33,28,68,41,31,35,24,21,21,18,19,39,23,45,33,67,29,16,38,47,60,19,51,10,18,30,43,73,57,81,92,114,77,69,56,46,70,36,36,59,39,75,23,3,38,23,24,54,40,24,44,33,9,47,33,21,26,29,34,35,28,31,47,34,28,32,34,42,32,12,40,60,37,53,59,33,68,62,70,45,59,48,23,25,30,30,25,20,18,30,33,40,17,14,47,59,27,26,13,34,13,23,17,35,42,39,62,121,142,156,164,153,139,147,135,112,151,147,78,61,76,30,28,19,27,41,35,16,6,25,31,35,53,58,80,100,43,28,36,25,44,81,87,77,99,95,33,66,59,29,70,94,109,104,106,124,121,126,77,74,46,100,127,15,133,233,229,243,242,251,232,227,225,217,234,224,239,246,221,241,230,240,233,235,236,240,226,237,240,247,242,218,213,225,240,253,237,238,237,236,216,227,209,243,231,255,223,232,241,237,241,227,250,242,236,232,252,245,255,249,239,234,222,225,249,117,6,0,13,12,8,23,12,19,2,9,9,20,17,0,3,18,26,19,37,19,14,17,26,29,178,196,198,188,192,180,209,165,185,176,181,196,196,186,198,192,176,181,202,218,189,206,195,216,187,163,176,177,189,204,181,190,173,183,186,196,197,201,188,175,218,167,175,183,221,198,197,209,204,179,196,215,184,214,201,197,207,177,209,198,185,203,205,203,208,206,180,169,206,185,213,207,189,195,224,183,191,194,175,198,198,176,210,194,218,169,198,202,189,195,189,201,202,191,165,200,201,189,198,200,175,195,186,193,182,193,180,218,187,200,200,190,199,189,211,193,187,201,201,183,192,189,175,200,192,194,194,190,219,199,179,189,211,192,214,167,198,205,205,200,197,179,178,208,203,187,184,213,193,191,221,204,216,185,198,220,176,189,192,192,209,208,197,191,240,239,209,193,180,190,205,198,216,215,191,184,195,208,206,196,206,212,172,191,201,199,232,214,204,206,223,215,207,216,184,194,221,224,213,196,217,194,236,212,210,194,190,194,203,201,185,211,223,230,221,229,211,217,202,229,200,195,182,217,220,214,190,194,183,206,216,209,241,181,239,217,231,213,204,204,209,224,192,164,199,219,204,221,223,215,196,222,223,201,216,200,205,218,209,221,212,231,195,221,208,220,201,206,198,198,195,224,229,194,209,187,219,234,219,234,220,192,238,213,213,213,221,197,229,215,218,233,216,237,223,233,217,204,221,221,216,207,215,213,218,226,193,201,218,229,219,214,207,181,194,214,209,147,113,50,20,39,8,44,46,130,203,172,187,184,173,151,115,176,188,204,205,127,113,120,162,174,119,61,13,24,56,50,49,43,33,38,81,146,203,250,230,163,52,7,84,209,236,146,116,195,158,221,204,188,195,183,182,148,171,155,190,228,249,215,128,228,227,246,212,211,226,225,217,197,205,221,145,186,202,255,154,77,65,63,58,50,72,77,81,71,141,91,23,53,5,66,243,250,211,79,8,2,1,39,67,52,6,34,22,61,39,68,190,234,252,183,197,240,239,249,253,251,194,146,220,226,230,215,193,201,155,180,240,227,249,253,240,208,97,27,1,31,77,116,58,111,60,60,134,106,119,74,21,46,27,25,27,31,23,42,45,41,16,26,26,16,20,32,67,32,40,38,35,60,35,36,43,24,41,20,23,82,48,96,127,109,74,92,119,75,59,56,33,33,41,21,15,41,25,12,27,62,37,20,27,31,30,34,50,21,27,50,18,38,44,22,34,23,58,23,25,38,44,49,54,44,63,49,66,32,69,32,42,44,46,27,19,19,27,14,19,2,11,27,31,18,37,33,5,40,28,19,37,18,27,18,18,32,31,99,141,154,165,162,147,149,113,118,110,122,157,137,55,37,51,43,15,41,32,15,14,41,16,40,3,39,27,53,77,91,59,21,44,22,30,89,74,72,95,67,81,52,38,13,97,108,111,76,85,84,108,107,64,96,143,169,142,31,152,242,229,237,242,245,215,211,239,231,250,223,241,222,239,239,242,236,230,248,235,216,236,231,239,239,238,243,234,245,228,237,235,248,231,209,235,251,223,237,219,239,240,251,233,237,249,237,244,245,240,251,208,253,245,220,244,215,237,234,233,130,22,9,7,7,18,7,21,9,14,17,12,11,7,5,9,3,13,16,3,11,25,13,17,6,190,169,171,184,203,185,196,203,173,188,189,179,189,196,181,169,189,182,166,181,190,191,184,184,168,190,204,174,183,173,174,179,195,205,186,214,178,182,193,186,210,192,187,204,180,197,175,181,193,202,188,207,180,186,214,192,195,209,200,207,187,172,198,176,207,196,183,188,210,188,193,193,196,165,173,189,194,201,195,198,191,201,201,198,212,193,183,187,190,213,198,200,175,187,199,206,198,181,199,164,191,188,193,193,194,181,178,183,191,181,191,188,205,198,189,182,178,191,181,203,201,204,222,200,183,205,207,198,190,184,211,196,196,189,178,212,180,186,191,189,168,189,198,182,179,193,195,179,199,193,193,212,222,205,210,171,200,175,185,204,203,216,208,178,202,205,203,191,195,219,197,209,194,207,213,209,191,213,204,219,210,219,195,233,221,227,219,206,200,181,186,213,217,210,213,211,205,225,184,218,210,217,208,200,203,208,203,194,206,206,199,189,215,228,201,212,196,207,220,212,220,206,217,216,218,185,216,225,221,226,211,211,218,213,220,219,235,221,197,211,216,212,205,201,211,209,206,233,202,213,209,229,215,224,246,224,214,241,221,214,213,211,212,219,211,211,200,210,209,226,228,221,199,238,205,210,219,234,227,203,197,202,210,215,222,218,208,216,216,209,230,206,211,216,242,222,236,209,221,214,229,230,213,204,232,198,231,216,226,206,220,224,205,201,182,204,188,70,18,8,19,33,45,50,27,82,105,160,192,176,213,166,149,207,242,248,199,88,152,107,194,194,154,85,15,32,38,59,35,37,41,30,100,182,230,244,239,207,149,30,57,128,146,111,139,181,191,222,186,193,180,134,156,165,180,168,208,196,253,195,149,240,237,235,199,209,235,212,220,203,233,229,169,207,202,255,146,26,106,89,27,73,55,81,106,42,78,39,88,48,26,129,254,217,90,20,32,7,12,31,19,0,24,49,89,30,55,144,249,239,193,163,228,249,247,250,252,193,155,213,251,231,207,239,159,94,157,241,253,224,250,247,224,136,160,112,51,58,48,71,54,66,62,51,153,143,111,83,19,27,5,46,33,55,26,24,47,20,13,10,51,15,15,47,23,34,13,31,52,47,23,29,36,39,35,17,66,99,58,71,88,74,49,41,62,35,53,58,36,78,53,8,31,10,25,39,26,11,37,28,42,52,52,42,30,18,21,27,28,29,26,36,53,27,31,29,27,67,85,65,105,78,44,80,35,52,27,34,46,51,20,17,25,25,39,17,32,18,35,48,12,17,37,37,11,9,24,30,29,13,20,16,49,10,80,139,125,134,108,126,122,123,91,106,89,124,144,103,83,39,31,21,34,38,34,40,39,51,30,45,12,27,38,31,66,55,37,9,13,16,39,71,72,77,76,42,62,57,35,34,68,98,99,102,77,91,122,98,29,78,115,90,90,11,141,219,243,250,250,246,237,249,231,239,247,240,247,241,248,229,239,238,248,242,233,247,216,246,243,253,249,240,225,236,251,248,235,213,215,239,240,236,240,234,239,215,235,237,253,249,245,245,248,233,238,234,242,254,228,240,240,247,246,242,241,113,19,7,10,31,22,8,7,24,16,14,2,15,16,8,3,5,10,36,17,12,6,29,5,20,205,163,162,173,148,189,184,192,206,182,201,207,212,194,189,185,210,187,184,194,191,197,214,184,212,188,181,189,209,171,190,201,184,187,205,206,208,215,190,166,200,202,195,186,175,194,197,198,196,193,207,194,188,187,191,191,175,181,213,200,200,191,160,205,194,211,178,211,195,173,209,186,203,195,192,209,224,210,180,207,186,194,198,190,195,174,186,206,208,205,200,185,171,182,199,201,168,185,195,204,206,191,192,196,188,182,188,179,197,208,201,181,184,196,174,217,208,191,189,162,203,174,196,207,201,173,182,190,179,188,186,185,204,200,186,213,215,185,172,206,209,181,194,157,189,226,199,203,211,204,209,196,205,199,189,212,187,185,218,186,201,191,211,212,192,197,213,181,179,188,232,233,192,201,220,217,191,227,212,199,225,207,218,207,243,212,219,203,203,198,208,209,237,198,199,225,217,208,202,234,195,223,218,189,222,216,205,228,202,239,203,228,235,209,210,247,197,219,220,216,200,221,203,218,190,207,211,221,205,202,200,210,238,214,195,188,217,220,222,216,215,223,198,223,197,192,226,197,212,204,244,198,227,220,214,196,215,189,241,196,238,247,215,182,194,214,202,213,242,231,190,213,213,220,213,215,205,210,218,229,218,223,230,230,213,200,226,213,206,228,214,206,218,207,188,212,242,193,211,219,227,206,194,212,198,192,209,222,191,232,207,217,211,162,213,211,150,100,19,24,27,43,77,82,40,59,164,212,209,231,225,191,142,206,218,229,125,108,122,100,181,176,132,69,5,31,29,45,50,40,52,30,63,140,200,234,164,205,164,19,56,145,241,168,192,181,182,160,157,116,139,195,137,190,163,184,172,193,253,146,169,236,230,224,218,200,222,206,217,176,234,183,156,149,213,252,119,33,116,85,53,75,60,62,92,53,66,130,218,79,13,187,231,140,35,24,12,15,52,22,0,10,43,48,56,50,147,214,243,180,130,205,241,254,229,228,185,139,191,253,238,215,200,222,72,83,210,228,252,246,254,220,103,68,133,158,85,32,43,45,25,71,26,83,161,134,124,41,10,27,24,22,43,30,17,50,21,32,32,44,15,16,49,33,49,28,20,15,10,25,55,36,11,40,16,61,46,85,67,65,57,60,37,18,46,38,24,12,75,60,14,26,20,23,4,15,32,19,23,9,28,15,18,50,27,25,37,18,30,32,35,42,26,28,8,39,14,159,159,156,91,134,87,42,32,5,27,49,42,33,42,25,29,12,13,38,25,38,70,28,4,30,27,25,31,50,59,27,8,33,30,17,28,3,108,135,128,107,112,112,91,90,102,115,107,108,118,96,26,31,35,23,25,29,29,41,18,51,54,27,45,14,37,29,45,32,34,24,59,40,39,70,72,44,68,47,80,18,63,10,34,115,117,91,104,65,82,102,35,60,56,31,44,11,139,213,236,252,221,254,230,244,238,235,222,238,247,254,255,240,239,240,248,238,235,237,244,242,229,255,224,235,247,253,231,251,238,246,242,234,243,243,250,240,243,245,246,252,253,245,241,238,248,222,253,239,241,241,242,237,206,247,250,240,227,100,7,18,0,1,2,5,33,6,20,17,9,14,2,0,20,22,20,7,9,7,30,10,19,5,190,191,206,208,186,177,165,201,181,202,188,164,206,198,189,172,189,179,199,189,191,196,185,186,204,185,189,185,196,188,188,208,167,203,191,194,196,186,184,197,176,171,194,198,199,209,194,192,193,211,221,170,193,201,191,190,224,210,194,187,186,192,202,192,189,187,205,191,185,191,185,174,195,202,196,191,174,193,174,211,212,198,190,200,202,190,189,212,205,168,202,210,194,165,172,197,181,198,194,195,188,192,184,200,191,182,202,177,197,184,211,183,188,203,179,200,204,226,191,198,177,193,185,192,174,187,177,207,207,181,192,179,198,178,200,187,203,204,169,175,210,200,176,185,202,205,220,200,204,210,211,190,153,200,180,188,189,198,229,207,208,222,174,199,171,205,202,221,203,183,219,195,183,208,206,207,200,228,200,187,200,211,210,208,216,194,218,201,220,200,224,194,206,205,209,211,203,212,212,190,234,211,218,216,202,216,237,195,199,216,210,205,229,206,219,215,226,222,225,213,232,236,246,225,220,226,214,200,220,227,224,220,207,221,203,197,213,231,206,223,195,187,197,211,216,209,202,230,232,232,214,211,192,196,204,222,202,214,207,196,231,200,216,210,201,198,238,210,207,202,219,209,230,230,194,222,207,170,183,211,219,202,212,239,188,185,232,227,213,204,226,231,214,220,226,241,231,229,209,214,202,202,183,202,205,206,216,212,227,216,208,223,206,192,220,222,209,120,96,95,95,134,99,79,59,101,222,189,193,211,242,177,154,226,224,182,110,109,174,108,172,163,42,52,39,31,43,31,65,39,60,13,66,131,199,225,150,211,193,78,51,211,237,222,230,197,162,136,147,124,164,186,131,124,131,138,214,224,250,147,202,238,225,239,217,201,227,212,229,193,231,229,181,170,203,242,149,69,80,98,75,59,38,68,97,94,132,178,221,152,84,209,119,47,11,2,26,24,39,31,45,39,67,67,21,120,233,223,220,135,196,249,253,246,206,177,157,211,217,253,242,192,172,111,87,198,232,229,246,253,233,66,8,64,106,95,93,23,40,51,46,57,38,86,172,139,111,14,32,34,33,38,36,22,26,27,39,30,10,26,22,19,28,43,42,43,40,39,47,37,53,39,21,68,23,54,43,57,71,40,54,74,39,46,28,33,31,37,26,53,11,37,12,26,29,41,43,44,32,49,41,40,38,38,16,27,33,18,38,7,37,48,61,35,51,42,66,140,130,103,86,91,76,44,40,10,37,15,28,22,18,40,30,45,55,50,61,62,16,30,30,18,27,3,17,18,26,42,24,38,29,28,7,34,74,149,126,113,100,98,115,118,124,147,114,78,120,84,52,29,19,42,30,58,40,14,25,45,48,28,19,29,7,15,52,18,19,21,15,14,40,52,78,50,75,70,86,47,58,36,52,150,108,120,106,105,74,85,114,84,43,40,22,108,248,253,242,251,248,251,233,223,223,252,238,242,233,252,243,242,245,242,243,227,253,234,244,237,254,243,248,241,224,237,254,244,250,249,255,251,227,247,214,240,255,240,226,242,236,255,241,232,247,251,243,255,252,236,232,248,248,248,243,236,249,123,11,1,2,18,13,15,0,10,3,8,8,1,11,0,5,8,16,18,30,18,25,4,28,28,150,188,209,172,159,180,187,186,204,171,209,176,180,212,195,228,198,187,177,185,174,164,197,183,185,200,192,199,178,183,202,198,196,185,216,193,191,195,218,170,179,175,209,196,203,167,169,179,199,186,198,215,185,197,192,211,205,200,218,210,212,221,186,165,190,179,165,190,201,199,175,198,198,201,191,218,183,176,193,218,193,187,188,205,193,187,197,190,210,202,204,176,198,199,182,208,176,206,202,177,206,164,208,185,197,204,191,196,192,221,215,186,191,177,174,192,193,193,183,187,204,191,176,193,197,164,203,182,195,192,174,191,207,202,204,211,208,185,214,183,198,203,216,205,206,212,225,202,210,208,183,228,182,193,178,195,187,219,199,222,220,211,203,192,198,194,182,200,211,176,185,204,201,205,211,198,205,237,210,206,212,227,196,226,205,213,212,223,181,216,214,206,192,207,203,202,234,203,216,184,216,209,227,236,197,211,228,240,212,209,201,218,227,224,224,208,220,204,225,219,221,231,221,199,217,206,218,214,234,234,206,219,211,222,179,210,213,210,221,212,223,196,199,213,217,210,217,219,203,224,199,227,222,211,234,201,220,201,199,201,211,211,210,195,199,205,229,222,209,218,223,198,221,232,215,199,227,207,198,210,221,237,240,213,221,236,206,221,218,225,232,222,217,205,238,208,230,190,235,230,237,210,192,187,172,219,229,218,235,232,206,241,198,239,178,223,236,178,193,179,141,132,111,120,118,115,213,211,227,223,243,184,162,226,201,130,103,110,158,125,187,211,40,16,8,19,62,36,79,27,36,41,119,162,197,217,176,221,190,103,90,196,219,167,152,153,167,211,217,199,207,168,64,117,109,149,156,247,183,149,216,249,222,247,200,225,220,217,229,191,228,220,191,190,209,254,157,59,135,88,53,45,36,45,52,104,131,175,253,191,182,139,44,32,5,7,18,28,43,20,58,45,59,24,103,203,241,214,149,194,189,236,252,226,197,163,210,252,251,220,232,166,89,139,161,237,243,239,242,221,95,26,57,89,108,120,141,91,30,45,35,30,73,142,124,127,103,19,44,38,17,6,34,58,38,39,10,29,39,26,45,37,31,36,39,27,19,24,59,50,15,30,30,14,36,44,38,40,28,11,50,48,40,43,54,32,9,4,51,41,11,24,6,22,25,46,53,40,15,33,13,28,46,27,65,19,18,43,30,38,29,27,27,45,17,38,68,111,127,74,98,65,78,55,51,24,35,3,5,6,33,11,31,36,45,36,24,52,51,28,45,15,13,6,30,18,39,47,30,35,43,13,22,26,76,138,113,117,96,93,100,97,87,72,102,106,99,107,43,24,19,42,41,34,62,15,55,39,19,52,45,36,51,20,14,36,53,21,43,6,34,91,89,84,69,50,71,38,56,55,56,129,102,90,90,98,90,49,90,92,113,104,152,235,236,248,232,241,255,241,235,234,243,225,224,254,254,241,241,245,241,247,234,223,234,225,255,248,247,244,236,235,241,255,242,252,251,238,255,247,253,238,247,251,249,253,249,240,245,245,217,230,232,247,249,234,242,250,247,241,247,239,243,247,238,105,10,0,2,11,26,15,26,18,20,12,13,12,12,27,13,12,17,7,5,14,13,14,1,13,188,189,191,175,184,184,192,172,182,188,199,225,210,178,214,186,185,173,195,212,192,187,178,155,205,190,193,212,182,194,215,211,178,179,195,164,181,197,191,190,209,184,183,209,183,176,197,170,190,188,199,191,196,213,187,194,174,209,198,197,204,196,203,185,209,193,207,190,219,214,185,187,206,179,185,205,185,211,204,194,205,186,199,194,198,209,199,198,193,203,217,188,193,186,189,183,188,204,216,175,184,200,191,172,206,182,183,215,215,186,199,182,185,200,198,224,195,192,203,202,192,185,216,186,202,190,210,218,203,190,219,195,219,186,191,220,186,218,185,205,188,199,217,213,223,197,224,165,198,205,209,209,198,201,203,232,196,203,202,195,201,190,163,217,188,206,225,194,212,196,208,213,229,216,194,225,213,200,204,217,204,232,214,201,194,218,232,197,198,218,203,207,218,191,198,214,221,224,212,222,206,230,213,217,209,190,209,198,232,221,208,217,186,206,199,207,241,207,192,223,206,223,203,220,205,217,199,190,202,219,222,239,239,205,217,202,228,200,216,202,220,205,220,223,213,228,212,212,238,213,210,197,221,230,225,216,195,217,208,202,216,206,221,210,210,214,205,213,217,202,230,230,228,217,213,223,224,214,235,204,208,241,249,252,243,223,229,213,213,207,231,215,231,208,225,213,221,210,208,227,243,206,209,216,195,223,216,236,238,232,225,210,171,141,168,157,145,190,225,185,165,116,105,187,186,127,204,188,238,229,244,153,159,219,179,103,96,117,173,117,198,209,15,13,16,97,82,100,49,15,30,89,216,200,220,204,210,235,210,148,64,89,95,117,192,203,194,245,225,208,219,127,108,146,147,163,176,238,145,134,237,213,246,208,220,205,234,215,212,199,222,205,159,188,196,252,141,79,105,84,83,90,57,67,55,29,91,186,247,254,195,91,28,32,34,8,37,32,7,45,39,61,47,63,177,251,232,152,166,229,252,229,250,198,150,212,244,250,233,244,224,105,76,209,190,238,243,242,218,65,25,38,87,103,123,162,211,144,74,87,89,79,130,129,135,140,39,32,17,54,53,61,64,23,26,31,79,11,15,22,30,36,30,46,37,51,51,29,46,52,24,31,18,36,31,31,29,28,35,28,20,41,24,58,41,61,38,25,7,25,22,20,32,19,43,28,42,23,39,40,75,39,32,17,27,26,25,12,15,40,38,24,45,37,24,28,28,94,143,100,58,99,52,28,22,31,21,32,20,15,39,14,28,38,54,46,26,8,36,41,19,3,35,19,11,30,34,53,10,57,25,22,28,29,66,96,116,119,69,74,62,78,38,18,60,104,108,95,61,47,14,29,29,7,34,16,11,27,38,39,42,16,53,31,35,41,59,15,26,25,22,95,86,64,52,53,74,41,57,68,52,118,83,116,108,133,80,87,77,98,95,142,196,219,226,248,255,224,250,234,239,245,249,236,248,244,250,246,248,252,232,252,249,242,248,223,243,255,253,254,250,254,238,243,238,236,240,255,251,253,237,234,251,241,255,238,239,255,250,255,240,249,255,242,237,255,255,239,243,248,244,250,233,246,250,125,0,10,16,21,37,17,7,0,1,17,6,20,12,12,0,9,0,17,5,12,21,16,30,11,172,178,191,176,196,190,197,200,221,176,206,226,195,210,194,190,180,174,207,191,199,199,199,188,181,178,199,196,201,192,195,189,220,164,196,195,182,212,186,177,166,193,187,204,189,175,165,212,192,179,180,205,176,225,221,208,206,220,196,232,203,177,194,200,181,184,205,197,204,174,187,208,188,200,183,188,187,197,184,198,211,200,213,191,196,191,183,182,174,180,200,173,195,185,212,194,187,182,196,181,192,188,214,217,163,195,170,210,192,195,215,208,186,193,201,166,178,196,195,207,194,195,194,190,214,205,217,197,213,201,209,188,212,182,173,176,214,200,224,214,182,188,190,210,205,210,211,193,210,211,200,212,214,215,201,200,205,196,205,221,208,205,218,213,201,211,195,217,198,205,215,194,205,199,200,204,211,201,225,203,213,220,204,205,200,235,198,198,216,230,210,200,222,211,222,193,228,224,224,230,217,187,210,219,201,222,205,219,196,195,207,218,213,211,190,215,197,223,209,215,203,212,207,211,243,219,236,228,218,204,219,224,213,233,219,227,205,203,235,183,204,216,205,206,209,198,205,231,217,205,204,191,203,204,216,208,221,219,201,207,228,223,204,187,191,202,237,209,210,193,230,205,214,212,233,209,213,225,244,226,198,198,167,223,214,246,204,228,235,226,213,201,223,198,237,241,234,208,213,213,239,222,201,214,200,187,212,195,185,187,187,150,177,159,151,110,112,178,225,185,175,111,74,237,227,82,149,191,180,201,191,162,141,186,172,136,129,137,194,150,193,222,50,27,64,142,140,125,83,40,28,132,229,214,185,226,220,178,173,151,48,22,58,154,225,198,224,229,164,153,191,150,92,162,194,224,230,241,132,130,200,151,204,219,181,200,239,228,223,201,239,237,200,171,200,242,106,78,137,116,78,72,40,38,28,86,133,234,247,231,156,38,24,36,47,38,40,54,16,51,65,48,56,178,251,248,150,163,219,241,248,246,225,142,215,249,242,242,244,240,183,135,184,253,208,250,240,249,112,6,42,82,99,97,120,155,188,129,33,22,83,81,92,138,121,109,48,5,23,42,55,47,42,25,20,27,21,33,25,24,38,24,28,26,34,40,38,41,30,19,39,14,60,39,41,15,22,46,47,25,25,1,54,50,43,71,36,10,28,53,29,25,39,17,42,18,34,20,22,24,15,51,12,17,37,34,23,24,26,18,31,49,28,41,33,51,35,72,107,98,75,32,70,29,6,37,35,32,29,13,8,41,58,47,54,46,22,24,24,11,13,36,16,33,34,54,22,7,27,42,27,31,18,30,34,52,118,119,89,56,75,74,68,23,15,43,98,121,110,63,29,32,30,41,51,34,38,9,61,28,51,36,63,30,27,35,51,55,8,40,40,95,73,68,63,70,83,54,49,53,28,91,110,114,123,125,84,79,62,95,70,25,11,80,216,242,232,253,255,250,255,245,248,244,243,247,239,239,239,235,242,238,251,255,231,239,236,243,236,247,242,254,236,251,249,254,249,249,235,253,245,248,253,248,248,238,245,224,250,250,228,226,246,250,244,251,231,254,239,228,245,249,243,224,220,114,25,31,10,34,7,23,28,6,14,3,5,20,2,3,26,21,31,27,13,12,22,15,5,19,202,180,196,185,168,203,212,188,228,179,174,184,197,176,204,183,213,185,195,178,199,215,176,199,196,195,198,184,211,208,209,200,196,225,202,170,172,188,205,198,183,187,190,188,196,189,175,218,220,181,208,182,204,202,185,172,204,171,222,179,193,188,205,194,203,227,204,200,180,195,211,209,199,197,197,190,197,200,202,201,202,204,180,189,209,187,207,213,191,219,204,211,207,194,202,207,180,203,214,198,209,182,197,181,198,168,183,201,195,221,204,193,184,188,203,187,176,198,212,183,212,191,194,174,205,203,187,192,205,205,206,197,196,199,193,195,204,211,212,195,203,207,225,224,220,205,186,226,213,205,200,193,194,220,208,202,196,195,209,190,185,221,215,196,204,228,209,205,212,204,227,194,233,210,231,200,200,225,230,203,216,218,209,203,218,207,207,202,235,219,239,217,202,216,204,229,205,203,205,235,199,200,208,211,217,223,215,218,209,201,201,226,180,224,219,203,219,201,215,190,217,209,227,217,228,210,206,219,208,211,209,235,227,206,198,205,208,211,205,200,208,206,221,201,215,210,217,235,232,199,197,206,205,214,219,206,212,199,226,202,222,216,223,211,214,221,214,220,209,215,230,219,227,202,207,216,199,217,213,241,191,89,85,128,202,218,223,224,243,215,220,242,236,212,226,194,227,220,219,227,247,221,197,192,201,208,171,171,178,180,176,182,170,200,218,194,205,197,212,127,173,102,52,208,198,110,176,146,146,200,221,148,166,162,129,138,152,166,220,142,191,237,123,56,95,170,127,137,140,52,14,173,244,186,136,212,216,152,155,158,91,69,113,175,231,192,209,193,142,136,208,144,116,122,142,175,244,234,138,213,202,213,202,188,198,196,220,199,209,190,239,230,184,163,223,213,79,44,113,111,76,44,50,36,64,126,205,245,241,162,65,1,35,42,40,28,23,24,22,43,74,48,127,231,243,165,175,213,236,233,250,228,159,159,243,221,247,245,250,176,165,196,238,242,221,233,245,101,38,33,76,102,120,111,93,69,128,103,15,47,36,66,103,119,98,115,27,18,48,45,38,53,50,24,48,29,29,42,10,9,20,40,52,38,28,30,28,53,7,28,56,33,38,54,25,16,40,24,19,26,51,19,42,62,46,65,41,20,14,28,20,30,34,33,32,48,39,43,36,41,28,26,33,41,38,38,47,42,3,51,46,31,33,27,26,84,51,56,126,137,95,62,58,18,43,18,34,44,28,28,28,29,59,42,78,53,17,11,23,17,35,16,28,20,43,16,8,25,33,35,36,44,36,14,38,23,70,113,102,82,107,110,45,79,49,61,94,139,144,108,59,24,36,24,34,40,36,48,41,20,45,58,34,53,53,42,34,43,50,32,35,91,53,42,68,78,72,49,62,70,35,92,114,126,101,115,87,88,45,53,49,18,50,200,255,246,253,215,250,244,224,219,254,233,252,245,249,249,240,248,235,251,243,234,253,242,255,252,253,230,254,251,228,229,246,255,223,243,252,255,215,239,254,216,226,225,242,243,242,228,243,241,238,237,246,252,239,255,236,239,249,244,250,248,201,97,14,0,0,4,9,2,18,18,24,28,11,7,4,0,1,9,21,26,15,5,10,14,37,13,176,200,206,181,182,199,183,192,215,197,203,175,197,225,191,181,174,182,213,206,191,185,191,191,193,203,197,220,194,219,193,180,210,180,219,215,195,209,184,194,177,214,195,194,220,179,202,210,197,193,188,200,207,206,188,205,181,206,217,181,192,172,179,172,204,208,199,174,192,174,197,203,228,208,192,184,201,184,201,196,205,202,197,195,177,171,181,187,187,170,196,223,183,194,195,209,184,197,201,217,203,189,189,180,190,204,196,201,182,214,203,195,192,197,194,198,184,184,209,200,178,221,182,217,189,196,204,202,201,203,201,196,192,199,200,214,201,199,204,200,195,221,197,197,234,170,193,214,203,200,189,200,198,213,206,182,185,215,203,198,192,211,193,199,208,212,181,228,189,215,218,227,180,174,203,216,222,235,222,209,197,214,212,189,213,190,202,214,222,219,200,206,201,236,189,195,217,212,191,188,206,235,181,218,237,196,209,222,197,219,204,192,212,185,208,216,203,203,221,218,212,217,209,210,228,207,240,199,191,188,212,222,223,214,199,177,219,211,195,222,202,218,206,210,211,215,198,217,214,219,225,222,208,219,224,194,200,211,211,196,210,212,212,219,199,211,201,230,202,214,202,225,217,216,228,205,211,215,221,244,183,133,117,124,181,216,245,222,221,223,225,224,220,220,224,191,228,209,209,223,236,199,173,175,149,170,180,205,211,205,214,230,188,220,222,252,210,177,214,135,172,122,57,180,169,85,214,206,171,217,229,172,111,152,142,136,160,179,232,113,191,241,159,50,88,180,152,144,134,81,29,195,246,157,141,233,170,138,199,215,222,77,69,182,187,159,192,228,189,179,160,138,120,164,181,215,246,193,160,214,236,245,236,233,203,178,210,195,210,182,236,206,174,194,218,208,71,74,94,71,79,23,10,16,40,115,139,246,191,56,33,29,25,15,70,24,2,43,32,57,21,53,173,219,181,183,232,241,234,251,203,168,132,222,241,226,223,243,164,158,219,221,245,222,207,254,62,33,58,95,128,123,110,76,41,49,138,79,21,36,124,175,143,121,114,113,18,23,54,38,32,57,58,20,32,41,36,23,42,33,18,24,30,46,43,30,66,41,36,16,56,42,25,16,20,5,25,50,47,31,46,44,29,50,93,82,77,34,15,39,29,46,30,60,34,27,15,18,26,33,45,32,49,33,49,38,13,36,8,33,34,58,15,37,84,90,55,48,59,101,92,69,54,46,40,31,23,14,7,28,30,42,60,81,14,41,34,17,22,26,24,36,19,32,17,68,32,27,35,30,24,28,47,44,20,26,34,51,110,135,107,139,68,62,34,41,94,117,149,158,104,52,18,23,36,44,42,64,43,42,38,51,47,56,53,34,59,33,18,16,42,85,61,79,70,84,58,51,74,45,26,78,122,83,98,113,83,42,81,62,31,106,249,240,254,230,241,255,238,240,247,241,249,249,246,230,253,254,249,244,253,235,240,250,251,239,255,250,251,245,253,244,249,224,254,254,251,239,250,255,248,248,238,255,247,241,246,243,240,232,254,250,244,248,229,255,229,241,253,244,235,229,254,243,227,101,6,0,5,0,8,21,31,16,10,14,11,8,20,14,30,12,9,14,8,5,19,1,13,35,175,197,180,193,199,202,192,206,182,189,203,188,213,226,204,195,198,175,198,195,225,194,201,176,187,205,221,204,205,184,225,185,189,226,196,206,194,179,172,200,175,187,209,201,176,212,190,228,196,210,195,208,176,201,214,180,169,194,204,192,201,190,176,175,216,195,209,203,201,202,204,193,196,204,208,191,226,193,197,188,209,215,185,207,212,220,204,191,197,193,193,197,198,194,205,171,190,196,179,174,200,205,186,194,182,201,201,205,195,207,206,201,192,173,191,202,181,214,171,210,217,195,194,201,196,196,196,215,208,205,207,235,199,202,177,206,213,202,176,211,210,208,188,177,210,215,191,211,208,203,203,194,192,205,222,204,187,212,176,184,214,194,205,190,212,222,202,201,207,222,210,196,197,193,218,234,218,207,217,205,219,225,209,219,199,198,207,224,193,226,193,202,201,213,204,226,203,216,207,219,205,196,230,204,212,209,206,219,206,210,221,202,208,204,221,207,205,202,207,232,215,197,236,188,216,221,198,235,223,216,213,214,191,212,223,198,201,200,210,195,183,231,220,202,225,244,238,226,219,184,213,188,201,236,235,205,222,212,212,223,205,212,191,230,186,215,218,245,237,198,200,225,212,220,218,214,229,220,208,195,225,221,187,164,205,187,215,208,234,209,214,198,237,221,237,235,203,221,202,193,174,194,136,202,173,186,219,225,244,217,243,240,160,208,211,231,195,150,205,172,185,98,98,229,183,118,195,234,197,224,220,142,139,154,130,155,119,214,200,90,177,248,176,34,63,147,150,131,76,42,10,172,243,119,175,244,188,201,225,237,225,112,66,156,200,198,224,233,219,202,145,143,132,177,226,235,246,151,144,221,247,246,240,254,230,210,238,220,220,191,234,198,162,173,172,187,65,73,45,51,40,19,30,22,84,88,114,164,65,14,13,25,11,37,64,47,40,37,78,52,66,84,213,198,149,193,219,251,238,234,161,157,216,237,238,213,209,156,155,227,245,192,241,214,166,134,31,48,80,86,106,125,70,57,45,64,141,92,26,43,146,175,134,135,137,107,15,22,22,57,50,17,58,30,40,38,10,25,32,29,18,45,22,26,34,25,22,47,20,15,36,30,19,48,22,66,19,39,3,36,27,21,30,21,72,86,62,80,20,31,27,33,53,35,43,50,33,40,41,40,3,21,33,36,10,38,38,13,37,33,46,56,47,71,134,147,87,59,74,64,89,89,71,51,41,42,30,5,13,16,17,45,40,53,33,28,23,13,24,22,13,45,29,22,18,15,37,16,41,42,32,18,41,33,32,17,38,30,50,102,80,94,74,45,61,42,69,95,157,198,146,63,24,14,42,46,33,33,43,32,33,45,50,29,26,42,30,23,37,43,62,84,76,36,57,58,73,47,65,71,10,103,107,104,112,92,131,83,92,47,75,234,255,251,237,236,244,254,246,242,255,220,248,248,235,248,235,243,252,253,240,241,246,251,224,246,249,251,248,229,242,235,245,242,239,240,233,252,238,255,244,241,254,245,243,253,237,239,237,255,247,240,229,238,247,246,247,254,231,237,250,248,251,248,212,106,8,18,0,15,15,27,9,10,11,20,22,5,22,14,1,0,22,34,0,10,15,13,34,8,201,202,193,197,195,229,169,188,205,177,191,199,195,180,198,203,219,180,189,186,204,208,190,174,176,226,183,189,178,229,207,182,207,198,184,160,217,180,218,220,182,194,219,212,203,208,178,210,195,183,198,214,195,205,209,238,192,178,191,208,194,208,201,212,209,190,199,196,191,185,205,201,180,193,183,187,206,196,230,180,203,193,215,191,203,197,213,187,201,212,197,196,160,207,188,204,201,197,192,182,204,205,205,200,199,208,179,196,200,189,202,194,196,188,194,209,197,201,200,192,208,196,201,191,166,180,198,204,205,166,211,201,203,208,219,212,211,178,234,201,219,216,212,207,230,206,217,218,209,199,187,213,226,179,222,197,193,214,188,209,207,222,200,188,204,227,208,216,232,218,204,182,217,177,230,213,216,190,229,212,201,215,184,217,202,207,210,213,191,222,205,219,237,197,209,214,218,203,226,226,210,209,217,193,196,188,202,226,198,213,206,207,217,210,213,204,222,197,196,206,210,221,189,194,193,176,222,223,214,191,210,215,202,197,233,203,226,193,183,194,211,205,187,198,216,220,206,227,204,201,226,222,210,214,202,209,212,225,206,238,195,214,220,205,205,216,207,197,211,196,216,215,222,226,210,213,223,226,220,209,220,244,242,231,204,183,202,242,228,214,216,215,202,223,220,213,208,204,185,206,204,227,194,215,220,212,241,234,226,228,227,202,179,226,214,225,140,164,228,201,186,95,121,246,201,96,202,217,198,184,226,133,133,175,160,174,137,223,193,108,164,220,221,85,98,155,144,108,87,47,40,200,246,98,202,242,181,177,203,238,132,94,43,98,171,209,245,205,201,143,164,162,183,203,221,252,229,144,161,248,250,225,231,238,229,204,227,237,208,207,239,232,164,149,176,174,107,35,59,42,74,83,103,165,146,157,111,117,42,7,12,9,46,40,28,14,20,58,49,61,129,195,165,172,190,201,237,240,241,169,154,225,243,239,240,226,199,148,201,246,237,213,244,212,26,31,34,96,128,101,123,83,27,86,52,72,127,77,51,35,22,65,111,139,134,76,31,32,48,29,63,49,27,43,39,20,15,15,31,21,20,27,37,29,57,60,23,35,36,34,28,36,28,20,42,30,19,24,38,50,45,30,25,31,55,48,87,61,24,25,26,48,30,6,36,33,28,40,28,28,60,30,6,26,29,41,23,36,31,52,50,99,89,85,125,187,75,49,38,71,79,110,75,38,53,20,29,47,24,54,20,28,28,39,39,3,19,27,3,34,33,20,12,30,76,24,35,29,46,64,26,28,39,36,30,12,40,21,52,44,56,22,68,43,49,57,47,47,93,184,133,38,36,15,26,30,38,49,58,52,23,14,50,53,46,40,45,22,23,31,32,74,72,71,56,55,98,63,63,96,33,91,145,104,120,101,83,107,77,84,83,214,227,223,252,250,249,244,248,255,240,250,219,233,252,250,238,253,252,250,240,244,247,252,241,226,252,243,246,225,250,222,255,236,251,249,243,232,246,250,242,253,231,225,237,251,236,236,241,252,246,222,247,241,248,248,243,255,252,238,237,239,248,250,242,103,15,12,1,31,27,2,12,1,24,38,8,15,6,0,11,9,10,7,11,18,21,5,19,10,198,213,201,206,212,195,221,206,198,209,197,197,180,190,199,229,210,193,196,191,182,181,192,217,203,197,179,208,187,188,183,151,184,208,191,186,181,219,203,203,197,195,170,209,212,209,212,197,185,185,197,188,170,170,190,190,206,187,189,199,202,210,193,180,215,215,211,212,209,187,207,180,192,191,226,190,193,198,183,178,186,180,219,167,199,192,187,213,184,183,194,177,170,201,218,211,227,219,188,200,199,194,198,202,188,202,185,208,199,196,204,193,211,201,217,212,190,205,190,205,191,198,217,197,209,208,181,201,200,211,193,212,224,187,197,202,221,225,208,203,192,175,204,224,201,178,193,194,195,228,230,224,202,183,197,202,216,217,201,206,222,197,200,205,214,212,203,185,223,209,231,196,204,215,201,218,199,205,184,186,200,196,205,203,225,203,196,200,209,217,220,202,205,220,222,206,208,218,210,215,197,217,225,217,217,220,198,213,209,189,213,208,193,214,227,223,211,209,189,211,205,224,217,198,216,204,219,224,204,211,192,234,218,213,211,205,236,184,192,210,236,214,211,217,201,196,205,215,212,231,222,210,210,198,208,211,187,224,210,221,210,191,225,219,223,219,214,211,207,200,219,229,222,217,226,219,208,213,233,226,222,207,232,242,215,213,216,183,194,211,232,211,192,204,194,210,194,203,212,245,217,237,189,220,208,225,199,191,201,195,202,219,172,212,211,216,141,166,237,190,181,92,112,238,215,100,130,189,182,194,216,172,152,134,179,172,142,247,201,103,188,238,233,130,72,118,125,115,72,42,30,174,232,89,215,250,168,137,180,175,177,138,101,129,160,235,209,166,225,166,160,128,166,176,197,231,226,139,188,232,221,249,223,207,207,205,237,220,231,214,229,248,201,171,150,225,109,14,30,81,105,67,146,168,212,190,48,41,33,5,26,42,46,14,4,42,34,61,24,120,202,181,176,182,237,241,255,252,175,152,194,244,238,213,247,170,143,203,250,241,241,201,246,108,26,64,78,131,106,129,74,29,61,111,57,92,146,57,27,58,105,123,125,82,108,64,21,25,5,29,46,41,40,16,46,28,45,39,21,24,33,33,14,26,26,17,49,23,25,44,32,27,31,32,33,38,19,36,39,34,33,52,23,56,25,37,66,76,28,20,28,45,50,4,28,18,45,37,33,35,12,46,44,37,21,24,35,27,42,71,102,128,112,150,171,129,83,35,23,34,57,57,34,60,26,28,33,22,35,7,38,32,33,11,21,14,6,16,19,11,29,43,31,24,31,17,25,37,18,24,15,43,28,28,35,20,53,37,7,22,41,6,43,70,15,51,7,31,49,29,50,40,53,23,38,45,50,39,49,43,51,40,46,24,31,35,5,38,39,30,50,63,69,67,54,69,85,57,68,78,25,46,124,132,137,110,102,113,58,29,25,122,237,241,220,249,254,246,211,235,251,254,247,226,255,252,234,251,254,249,254,240,243,240,252,245,254,253,249,243,252,237,240,254,248,247,211,255,237,248,252,242,242,248,249,255,244,255,228,253,233,246,244,250,252,241,253,249,242,241,226,250,253,252,242,97,2,12,12,13,14,13,0,36,22,12,18,17,4,3,27,7,23,7,33,1,16,1,27,11,172,193,205,215,189,205,186,178,204,201,202,228,171,190,177,190,197,194,193,202,189,199,213,187,197,211,190,188,184,190,187,193,185,200,192,184,181,213,184,193,210,201,196,189,191,187,177,194,177,195,207,214,197,203,197,198,188,198,190,192,181,186,191,192,207,213,196,196,212,187,185,196,196,181,211,196,234,188,197,194,187,212,186,205,201,205,195,200,226,205,200,181,194,216,201,210,194,201,194,199,204,233,193,201,204,223,210,184,208,198,222,195,205,196,185,208,194,203,217,216,197,222,219,207,211,208,209,214,190,215,209,189,217,198,212,194,218,174,208,224,210,210,208,233,189,189,184,187,207,196,200,170,210,199,222,197,201,206,228,202,183,210,217,192,200,203,207,183,200,204,210,218,211,225,195,214,202,219,209,211,211,193,204,204,225,214,231,221,204,213,197,214,219,179,216,225,204,191,194,196,205,217,214,190,220,207,205,218,201,231,199,224,200,210,207,202,221,189,208,185,209,196,230,181,204,217,221,202,210,199,239,205,232,208,179,212,201,205,181,183,184,218,202,192,221,233,193,218,199,197,236,215,224,213,200,217,227,211,217,210,204,214,254,230,223,192,219,213,212,231,203,179,218,209,237,219,233,224,220,237,223,234,235,246,203,233,184,196,178,183,188,221,215,204,222,211,222,233,218,218,223,236,202,204,203,184,228,216,210,211,226,201,205,216,210,229,135,169,243,173,209,77,72,220,221,130,146,237,195,217,228,142,152,158,157,157,174,231,203,110,185,235,229,160,82,112,115,125,60,28,57,196,195,95,213,174,112,136,218,220,194,210,120,116,145,193,171,216,190,185,162,52,104,182,253,236,191,140,227,231,238,241,213,236,202,215,227,209,219,189,235,238,200,176,165,220,111,26,53,60,33,89,100,123,164,134,38,38,11,24,36,20,22,21,13,42,48,57,111,226,228,121,172,212,245,226,251,216,161,223,250,251,251,247,170,150,208,255,254,248,242,175,98,53,43,95,76,133,124,81,63,56,113,165,35,112,146,37,42,149,224,165,147,113,100,54,19,28,8,42,46,17,42,31,41,44,12,10,25,18,30,32,16,29,20,17,17,48,8,23,27,15,35,32,36,47,37,36,34,42,52,21,30,47,29,35,69,64,36,12,38,22,11,9,16,14,28,16,26,10,48,57,23,19,25,25,26,75,137,172,99,125,162,166,113,68,26,26,22,18,51,64,60,26,43,37,8,20,29,45,31,25,25,15,38,23,49,29,9,5,36,4,30,15,0,52,17,49,51,24,21,49,32,43,44,19,35,44,17,34,11,46,67,36,21,61,36,8,4,15,15,40,26,26,43,9,35,26,59,42,36,33,56,59,47,45,23,60,29,43,43,91,69,37,59,65,68,76,52,83,43,54,143,131,116,122,102,105,86,62,23,84,245,229,238,239,251,248,252,236,248,253,245,229,255,249,255,247,253,247,240,253,255,252,233,252,239,255,255,236,242,254,230,246,237,241,243,251,253,255,252,238,240,251,240,229,222,234,239,252,238,239,246,236,226,244,247,254,253,239,255,248,253,255,230,104,16,26,3,7,0,10,29,0,33,9,32,14,3,12,5,12,9,9,8,4,7,25,16,10,192,201,213,201,222,194,207,215,213,194,211,189,207,188,229,182,197,188,205,217,197,190,205,199,173,226,195,219,193,209,173,198,210,209,201,195,183,169,177,184,203,199,229,230,200,203,184,187,177,194,189,193,178,200,224,190,165,186,182,198,212,193,184,210,184,207,169,196,199,197,204,187,207,212,188,191,201,214,195,206,201,221,189,192,202,195,198,192,196,214,186,198,185,189,192,203,185,199,213,205,209,197,191,221,195,210,198,185,222,209,212,190,212,219,205,193,195,219,209,208,215,204,227,192,206,199,210,174,207,213,219,204,207,194,202,214,212,212,217,209,197,205,178,205,209,221,201,192,205,204,204,199,211,222,192,209,197,205,225,200,200,200,198,202,211,199,205,229,193,190,189,228,199,228,192,219,210,208,207,200,222,187,200,200,208,205,220,219,213,196,192,216,235,215,224,217,222,186,215,229,238,201,180,201,209,216,185,209,202,210,199,211,213,204,209,213,220,201,202,209,221,217,205,210,206,221,180,241,236,218,218,192,197,225,218,203,205,202,203,217,213,211,245,219,210,218,214,223,218,214,226,213,218,220,229,203,214,223,206,199,193,233,210,223,208,222,225,210,222,217,236,220,222,235,243,223,230,208,231,230,231,218,234,188,171,169,202,217,191,176,176,212,230,214,206,241,217,242,199,226,221,216,214,230,214,200,232,213,219,235,225,167,184,235,237,213,146,190,248,215,209,84,113,215,214,147,160,246,192,200,207,121,160,169,178,157,172,246,216,144,197,224,255,239,138,110,140,117,77,39,4,165,138,91,164,136,158,167,234,209,221,207,77,58,145,193,186,243,201,191,108,56,133,217,238,255,155,127,226,217,252,247,219,242,230,208,238,227,216,204,249,231,175,144,122,225,124,73,117,93,20,74,120,92,68,85,30,40,19,30,41,49,23,20,64,74,46,82,221,220,151,157,235,252,225,212,200,166,212,243,252,250,240,192,125,197,247,241,236,253,246,101,42,12,36,118,102,127,108,30,72,95,167,139,29,108,147,48,37,99,186,163,151,142,109,43,8,13,1,2,26,19,23,7,49,21,26,9,17,5,25,23,25,32,30,54,49,45,45,36,25,19,4,28,43,13,39,41,55,48,30,42,39,65,42,50,49,83,41,22,35,59,35,29,31,46,18,30,30,42,36,27,52,30,39,56,41,60,105,151,128,84,122,83,55,43,3,4,34,19,56,69,80,51,41,29,28,31,25,32,31,34,34,40,1,7,22,23,15,19,48,38,29,30,43,28,16,42,50,25,41,52,8,48,38,54,28,9,25,31,17,34,79,42,44,39,3,45,9,23,30,29,29,40,31,44,7,33,26,60,66,49,28,18,35,39,40,31,38,46,41,65,79,37,57,53,84,81,23,84,18,57,99,128,108,119,112,131,61,58,14,55,224,228,255,242,238,253,252,242,247,226,243,233,248,231,253,230,249,243,251,241,226,240,254,249,245,233,230,238,239,241,232,244,254,253,228,251,255,253,227,238,222,237,248,226,237,252,243,234,248,247,250,235,249,239,246,253,241,241,248,255,235,250,243,110,0,0,5,12,14,28,9,46,21,8,27,1,4,13,0,4,29,0,12,15,31,18,2,29,192,179,198,228,198,212,218,188,209,210,209,211,204,200,202,198,198,209,194,216,209,196,185,179,211,216,198,188,227,213,191,203,222,219,194,220,194,175,179,174,186,186,215,191,189,183,202,183,186,192,184,209,220,191,215,189,212,175,216,184,215,214,214,198,178,194,199,216,207,195,187,197,213,194,208,202,205,210,166,189,202,194,232,180,210,203,194,201,190,230,218,213,201,224,199,215,215,203,197,184,203,184,201,207,213,187,176,182,194,200,213,191,210,199,234,231,209,184,210,227,231,216,212,217,195,208,189,206,197,226,218,217,212,195,196,209,222,193,209,228,207,241,195,207,195,196,230,179,217,203,216,222,211,192,212,210,216,213,210,184,205,195,221,189,206,228,194,218,206,214,199,204,184,196,205,220,205,219,218,211,199,205,208,218,210,189,229,214,216,203,208,204,226,219,207,217,229,193,224,196,204,215,214,193,203,207,200,188,199,217,225,195,202,188,213,199,223,210,205,209,206,187,197,217,206,219,210,201,212,183,204,215,205,194,192,197,223,201,204,219,216,197,206,207,204,231,208,200,211,225,214,242,191,230,237,203,213,209,202,214,220,215,239,222,208,212,224,218,228,230,225,233,243,247,223,227,238,246,238,213,198,181,181,181,227,242,238,244,244,227,242,212,211,219,246,230,232,243,214,233,236,247,224,206,213,234,241,234,234,240,220,203,209,225,253,236,130,200,240,189,200,65,120,227,232,157,106,226,199,177,153,98,146,188,192,166,177,229,229,134,206,235,246,236,115,124,103,95,67,18,13,127,148,104,185,175,207,195,231,179,161,145,101,102,145,162,215,235,169,143,152,126,182,243,252,252,137,137,250,221,232,228,236,242,209,188,241,203,238,186,226,217,217,134,197,240,172,57,70,90,44,141,164,76,83,81,53,18,12,12,26,32,49,32,40,54,70,193,234,197,136,194,239,241,215,183,146,195,251,245,235,223,206,136,217,255,250,232,244,250,188,34,35,0,36,106,112,85,45,59,119,138,153,92,49,124,113,40,35,83,150,122,118,138,95,18,29,35,22,20,20,43,48,41,55,26,35,31,18,30,15,50,40,36,33,45,22,10,33,28,32,26,44,59,49,40,35,19,43,34,26,57,29,30,26,33,66,69,64,27,12,33,50,22,22,16,43,55,26,31,36,20,40,27,42,49,22,27,39,103,103,56,24,42,23,12,6,35,7,21,30,58,79,70,37,27,51,30,16,27,21,21,26,25,28,25,19,1,29,25,35,18,18,56,7,16,39,31,40,24,41,53,38,51,53,21,46,19,40,33,39,29,66,30,14,31,21,29,22,61,12,35,33,45,39,39,18,44,25,23,46,54,61,56,31,30,35,30,39,16,12,66,87,53,70,73,93,74,25,52,52,25,96,91,128,128,117,125,66,61,35,59,219,236,224,239,255,250,238,237,247,253,253,253,242,249,237,239,227,237,238,255,255,242,250,240,247,234,248,239,245,249,243,248,230,247,236,233,245,233,247,248,250,255,251,255,241,225,245,219,246,234,249,248,253,248,253,255,244,238,255,239,239,250,254,111,3,6,4,30,24,1,23,3,16,5,8,33,27,2,8,8,10,4,12,6,9,16,27,26,217,238,218,179,211,183,209,207,207,235,215,195,222,224,221,201,207,196,190,213,218,212,203,179,197,203,187,204,230,198,194,207,200,177,225,179,205,198,191,211,224,213,195,191,201,164,186,190,177,210,199,193,200,205,206,212,230,198,197,210,207,199,186,183,194,181,206,220,193,193,209,186,195,196,204,190,183,192,215,204,188,209,189,213,196,224,200,196,195,212,194,200,209,186,217,190,206,209,208,184,211,218,192,204,195,190,199,206,220,204,213,195,183,217,200,199,219,209,224,213,227,184,218,214,200,226,168,208,207,224,224,223,206,219,219,190,202,178,230,205,192,196,208,205,210,209,212,213,214,212,207,206,218,209,196,205,231,199,193,230,192,216,201,208,219,208,200,211,227,211,212,197,223,193,209,191,203,179,188,227,211,199,219,181,193,206,220,186,225,239,185,211,219,223,209,205,185,209,184,212,207,193,222,228,208,187,215,213,208,224,234,216,197,200,197,180,195,200,220,221,214,221,204,203,211,220,226,209,213,187,225,209,223,211,203,210,200,193,224,218,209,199,210,226,205,206,233,192,222,212,203,216,212,212,205,206,215,226,230,236,246,249,236,234,252,240,237,253,236,248,255,235,244,242,230,237,229,226,207,220,225,252,253,255,251,246,247,238,228,234,234,241,230,239,245,249,238,251,255,248,249,254,231,221,246,227,255,246,244,248,255,208,239,246,242,249,176,230,252,187,141,75,88,238,237,173,128,249,240,231,154,122,164,181,194,208,244,229,220,186,236,246,255,236,115,92,76,73,52,33,4,143,173,162,235,191,190,216,183,165,181,164,122,122,103,146,196,187,172,178,147,183,224,245,255,232,144,214,249,226,249,217,213,226,212,215,201,212,221,198,221,239,176,140,206,247,156,47,85,37,65,185,78,36,41,83,41,34,18,32,21,14,35,43,36,37,130,237,205,176,157,218,240,227,177,133,170,214,242,244,242,213,136,179,243,243,245,252,245,178,41,17,53,28,106,104,79,58,65,113,117,134,123,82,76,167,93,63,28,37,96,137,105,164,23,15,25,40,50,38,45,57,28,32,22,27,31,26,40,21,38,29,36,42,29,27,23,41,17,23,43,36,25,34,35,37,41,56,36,20,10,24,42,19,21,50,74,98,40,54,25,20,48,19,39,37,27,26,17,42,35,37,40,28,28,26,35,25,45,109,46,64,51,36,22,3,6,18,18,20,57,45,64,38,57,39,45,15,16,32,13,29,1,2,19,43,22,41,36,18,18,16,32,24,38,35,39,34,22,38,27,47,32,13,29,37,25,22,18,17,13,71,65,43,20,52,30,61,26,32,20,41,23,54,69,9,50,15,34,38,31,27,31,11,32,32,20,48,43,29,38,85,113,26,54,46,55,59,39,62,37,33,84,116,97,99,114,122,86,24,26,3,191,238,238,240,249,242,235,250,243,243,250,250,238,245,251,249,248,249,244,236,244,222,226,228,242,237,226,249,255,233,255,254,255,249,254,254,230,248,252,236,251,239,235,239,232,250,245,241,239,224,240,255,247,234,225,248,240,254,243,234,241,252,249,114,6,13,22,8,0,15,36,25,5,0,7,49,7,9,0,0,14,20,23,31,30,3,14,41,190,219,212,203,200,200,221,201,205,196,197,223,200,188,190,195,216,205,216,214,194,214,174,194,181,201,212,191,195,225,190,209,189,197,200,202,169,213,207,183,169,200,210,210,205,212,207,187,199,193,204,192,187,201,196,167,215,198,212,210,205,192,198,208,205,199,176,192,210,205,200,196,215,204,214,192,214,212,196,197,204,202,204,198,188,194,180,209,199,200,216,187,199,228,204,190,214,197,199,236,183,203,188,206,232,179,197,223,182,220,193,201,208,210,197,164,202,208,186,210,208,188,218,204,227,201,228,215,192,224,201,216,219,207,201,213,204,213,196,174,218,188,205,207,221,205,215,194,205,201,187,185,194,213,228,205,205,215,207,187,221,193,193,191,212,234,194,224,197,206,200,213,222,218,206,224,208,229,212,216,214,204,197,217,216,226,196,222,215,216,199,205,195,215,209,201,208,198,198,216,207,213,213,210,206,210,214,226,217,208,198,205,211,203,198,183,203,196,217,218,228,197,229,199,197,202,212,232,212,214,205,223,221,194,215,233,197,203,221,200,205,209,216,213,224,208,197,206,236,233,203,200,206,213,209,213,188,207,196,216,219,196,209,214,190,181,227,209,179,174,166,177,173,157,171,147,158,131,184,185,209,225,193,220,210,191,203,210,232,202,200,190,188,168,183,183,198,208,184,200,203,190,191,184,202,173,207,199,199,200,190,169,190,185,210,146,133,187,204,140,93,18,55,169,144,143,118,211,195,190,144,131,154,176,197,162,227,255,207,164,229,237,250,229,108,100,90,70,65,44,39,135,207,149,224,194,191,215,176,221,214,231,192,154,132,118,174,169,235,175,174,205,234,234,225,235,148,228,219,246,255,235,236,237,202,243,232,236,225,210,213,234,171,140,202,242,119,39,53,77,121,173,84,12,64,82,74,54,43,24,23,28,59,51,59,121,233,248,167,189,189,234,222,195,151,173,230,244,248,245,238,153,201,241,240,252,240,231,146,39,15,15,88,85,139,106,37,75,117,120,128,102,101,36,67,134,87,38,63,187,152,144,129,129,59,7,35,28,19,52,64,43,49,38,53,22,33,34,21,19,35,33,26,29,25,23,33,12,28,20,31,45,74,81,62,59,21,29,8,17,37,59,19,30,30,10,32,73,54,54,16,23,28,21,35,20,64,29,45,11,9,21,46,44,35,30,21,32,31,44,42,46,55,21,17,43,10,6,5,19,30,48,62,39,56,46,30,15,19,12,37,11,10,19,29,22,17,24,13,6,27,6,30,15,35,39,27,39,34,25,22,33,16,35,60,6,28,22,5,28,47,59,54,14,34,41,31,35,21,22,34,31,26,12,16,41,31,37,38,18,34,37,26,25,52,24,50,35,35,30,52,78,101,77,63,56,35,38,44,51,49,35,80,110,98,141,79,113,98,46,34,30,156,236,237,232,253,243,245,248,252,254,252,239,234,249,255,236,255,253,231,250,225,250,255,239,255,253,254,245,224,233,235,253,251,253,250,254,237,249,251,226,223,251,255,248,247,242,220,255,238,223,252,248,236,237,249,252,250,237,251,228,249,234,251,115,2,14,40,0,23,11,2,1,19,3,32,8,23,2,4,2,16,23,18,9,19,27,15,19,191,185,221,187,211,179,215,205,196,192,195,223,195,201,211,205,217,233,190,182,200,193,212,207,214,211,215,225,177,191,220,206,204,197,200,203,214,211,206,183,204,175,197,205,226,189,222,201,209,159,196,201,193,197,176,211,215,184,203,201,198,180,183,170,206,195,203,197,185,196,209,206,217,167,173,205,193,196,207,186,202,185,204,201,206,188,161,206,190,196,203,200,206,205,213,203,199,213,200,204,209,205,222,225,187,196,191,195,188,202,220,216,216,178,229,215,218,219,213,217,226,200,174,201,198,187,227,238,207,183,231,189,211,202,206,208,238,209,179,225,200,198,180,209,180,218,182,221,186,208,184,201,191,198,182,210,200,176,205,198,222,212,212,201,190,214,200,206,225,201,203,191,225,194,223,193,227,221,205,209,188,203,228,212,206,220,211,187,230,223,225,221,206,199,217,213,202,213,201,218,231,205,207,209,223,190,207,237,226,206,210,203,203,191,220,218,190,202,199,193,186,201,222,207,188,209,213,223,218,220,226,214,199,227,174,208,204,220,222,187,218,203,203,208,211,203,218,214,233,207,215,223,215,213,214,203,175,142,112,112,89,100,100,97,91,68,93,114,84,71,69,50,58,28,19,13,29,24,37,48,32,62,48,49,30,70,61,58,27,34,45,49,59,81,102,93,95,72,91,37,42,48,44,68,72,57,63,15,39,60,70,36,50,50,57,55,18,29,46,64,144,51,10,10,19,31,5,88,63,69,76,108,86,93,97,89,110,125,86,61,92,77,129,119,88,118,133,63,108,34,20,138,108,80,135,123,101,142,155,148,153,151,117,124,49,93,171,136,187,106,94,120,196,241,212,145,119,239,235,237,230,217,224,227,204,235,244,224,214,186,250,208,159,186,187,206,118,61,63,76,198,190,69,33,70,109,78,36,35,14,29,39,74,56,73,228,252,194,211,213,210,191,184,154,175,244,255,239,237,229,185,162,244,242,250,253,248,167,15,28,57,65,101,85,80,32,89,138,141,138,88,47,74,41,81,142,71,50,132,202,206,143,145,124,63,12,40,29,37,33,52,37,41,40,47,20,43,20,20,36,11,18,29,39,39,27,32,13,42,52,100,163,173,152,121,147,67,46,51,65,7,55,28,20,30,44,41,76,80,61,17,30,20,26,48,2,32,32,35,21,24,47,29,26,20,25,23,55,30,21,32,63,34,17,35,13,18,5,5,18,53,13,43,65,58,56,58,22,17,17,11,28,11,20,24,16,18,41,34,26,45,21,6,15,43,19,24,48,37,43,30,55,47,14,32,28,8,28,32,31,42,62,36,29,13,24,23,18,20,10,35,52,60,18,35,28,32,20,39,35,17,44,51,42,43,46,12,39,35,34,33,68,131,74,40,75,71,63,45,31,42,25,58,132,104,121,89,95,113,34,20,15,112,224,251,252,242,217,252,255,239,251,243,250,252,246,245,252,255,251,222,233,250,245,249,245,253,237,244,211,239,252,236,236,245,246,248,245,228,254,236,236,245,253,249,249,255,243,244,246,242,251,232,255,255,252,255,241,250,254,242,250,238,246,246,123,17,5,1,18,0,3,19,17,27,23,23,6,5,4,12,4,2,0,26,23,15,8,12,5,227,187,198,201,200,203,203,193,203,228,190,210,222,196,208,196,224,213,200,196,211,215,205,213,205,219,207,208,193,213,191,195,209,219,202,206,214,197,216,198,185,176,175,201,195,219,207,197,186,199,178,191,205,177,213,222,206,196,206,220,200,202,188,193,191,178,244,204,200,222,208,199,198,185,206,201,179,183,199,211,183,196,215,200,213,214,213,207,222,208,175,200,201,210,215,202,215,219,227,189,211,190,183,209,190,206,227,193,213,203,200,215,208,221,202,194,212,218,179,218,211,200,205,206,200,224,180,214,219,209,200,206,209,215,211,219,195,206,210,202,181,200,212,180,201,196,195,214,192,197,208,214,222,203,194,196,204,197,192,187,207,210,208,207,230,206,212,197,217,225,198,211,225,195,190,215,197,218,193,181,199,225,198,215,204,205,194,201,206,208,217,188,202,199,212,195,226,212,219,216,200,215,181,206,196,211,204,215,209,215,200,204,208,217,208,205,208,254,219,216,208,219,214,223,205,189,233,198,238,216,231,217,239,204,219,210,198,204,203,216,213,220,210,212,207,211,206,202,221,212,198,196,206,219,206,213,198,158,166,135,141,147,127,128,80,82,81,107,112,125,162,118,131,129,124,126,90,116,100,94,97,132,93,80,108,92,107,116,100,118,125,126,109,133,138,152,108,123,98,106,114,109,112,126,116,86,109,98,117,119,92,108,116,85,93,89,55,89,113,122,153,87,59,101,50,46,37,61,91,97,80,117,101,107,113,99,89,71,107,59,61,78,84,83,56,104,109,68,61,45,82,107,51,33,76,55,48,46,47,49,35,41,28,35,36,94,108,91,82,34,53,14,80,90,94,65,50,113,88,121,132,114,135,193,192,199,223,237,245,201,212,203,163,188,181,197,156,106,74,110,243,198,50,32,52,88,90,28,15,25,46,47,58,89,180,245,228,234,242,250,186,195,119,104,213,229,251,223,243,166,162,237,243,234,246,254,192,40,30,59,134,121,128,50,23,79,123,122,137,76,64,84,56,28,101,127,68,26,56,121,145,118,139,122,54,18,54,26,5,11,38,19,48,45,36,31,25,27,36,10,33,17,18,19,38,36,49,54,116,143,139,177,120,185,159,184,144,108,44,39,38,34,8,33,41,37,53,81,75,48,19,25,28,21,18,28,52,11,18,22,10,34,33,20,39,44,37,9,12,8,24,15,37,28,32,10,2,10,17,25,19,35,81,93,79,35,6,21,6,7,35,37,32,33,20,36,8,28,40,33,28,25,38,19,26,40,31,43,17,38,40,47,44,31,48,42,44,38,36,26,66,83,37,19,30,28,18,47,32,25,21,44,53,30,39,13,44,30,38,51,37,30,15,36,33,15,41,28,18,41,38,38,124,66,83,73,65,61,64,64,42,39,72,115,109,125,137,153,105,63,36,18,85,221,247,251,242,253,230,240,251,254,215,247,253,239,235,227,245,245,250,243,225,229,251,249,247,246,243,240,239,242,222,250,253,253,255,245,223,248,240,244,249,246,255,230,255,221,251,241,249,232,248,250,232,241,245,246,250,234,247,248,234,255,230,114,12,0,15,9,11,18,19,6,8,6,19,6,0,5,5,28,12,11,33,8,8,17,25,12,191,175,185,201,185,189,184,219,220,181,189,175,179,206,203,187,194,218,198,196,201,210,193,179,212,228,195,207,188,188,221,188,192,189,191,211,188,218,207,219,194,197,209,200,209,214,191,199,204,190,181,193,196,210,188,211,217,199,217,186,199,188,200,205,217,207,223,175,192,205,192,219,193,186,208,211,189,215,200,220,199,188,208,193,200,195,189,213,185,194,215,208,216,207,210,218,214,206,210,191,227,202,181,199,185,209,187,217,213,197,206,208,205,209,214,196,213,205,230,212,211,202,223,203,211,201,200,224,210,202,202,212,213,183,188,210,199,211,194,178,199,192,193,209,221,213,230,208,212,183,204,190,198,174,183,179,182,214,203,201,200,220,200,203,192,194,210,206,199,203,213,191,210,205,201,205,196,224,188,214,168,191,225,201,193,187,201,198,229,179,190,186,212,210,214,224,210,204,220,239,236,222,216,215,213,179,225,235,203,227,210,220,214,190,190,228,197,187,236,220,210,208,210,211,208,212,229,202,213,208,223,217,209,217,230,196,234,216,242,232,232,173,215,196,241,204,219,209,201,205,235,213,219,216,225,196,206,250,240,240,221,238,203,212,185,172,216,213,236,248,252,237,222,247,245,239,255,211,220,247,226,231,239,215,241,244,229,251,246,246,240,247,234,218,243,238,243,209,223,247,255,246,236,237,241,221,252,237,242,228,219,213,244,236,233,197,197,249,238,212,162,86,131,255,225,194,187,169,244,191,186,215,198,198,175,210,255,212,254,178,209,252,237,253,138,88,98,53,62,49,82,149,213,171,120,201,161,116,97,127,126,113,169,199,125,125,92,139,135,118,138,127,156,150,139,83,105,169,144,180,123,180,161,228,206,221,238,233,211,206,242,157,188,187,179,224,160,87,87,214,243,114,22,139,86,58,36,14,26,8,70,24,23,147,227,220,242,242,245,207,191,140,70,170,222,241,235,243,173,166,191,233,238,244,243,184,54,12,75,113,110,103,89,10,40,93,160,123,93,52,90,124,52,27,106,141,36,48,76,111,130,149,108,110,25,8,12,21,20,21,36,68,29,32,53,57,17,31,34,38,24,31,28,25,29,37,95,182,197,167,134,96,100,164,86,47,67,53,58,24,42,28,7,19,65,62,38,74,46,51,20,29,37,43,21,29,32,43,33,34,34,40,16,29,17,34,10,24,32,29,27,20,34,5,19,25,10,26,60,57,26,45,78,69,62,52,9,51,18,3,24,19,34,17,43,48,23,28,9,41,34,27,29,6,13,44,40,34,61,29,21,30,61,26,43,22,49,24,42,41,91,50,37,43,3,15,14,19,56,58,59,45,58,64,68,84,58,59,23,47,23,28,26,41,36,21,29,31,43,38,31,51,101,48,54,80,68,97,115,39,60,32,69,103,92,110,110,117,118,44,37,11,53,190,245,239,253,250,241,245,232,254,248,253,235,249,246,249,245,228,243,247,234,254,255,238,234,249,239,244,249,245,237,253,247,234,252,239,254,244,253,247,237,229,244,253,222,237,235,243,236,245,243,248,243,235,250,246,252,253,244,253,255,254,246,122,7,1,1,12,29,4,8,21,25,12,25,10,18,2,17,5,8,4,5,14,6,21,17,15,215,220,216,203,209,189,195,216,197,192,196,202,229,202,190,186,183,198,185,209,209,197,213,192,203,216,205,191,199,210,186,198,190,211,207,200,204,208,207,181,227,196,183,206,197,214,205,179,219,191,201,196,193,201,179,182,191,217,217,197,215,202,216,183,187,216,204,220,194,201,210,203,200,201,183,187,207,198,179,185,177,198,192,185,192,227,199,201,192,193,172,198,202,194,186,202,196,207,214,213,191,214,203,245,194,205,220,226,188,197,186,191,213,215,199,210,206,197,209,192,218,171,206,210,208,199,219,212,220,208,173,176,212,226,196,196,227,205,206,192,182,203,200,195,211,237,195,204,203,230,204,208,200,212,180,205,205,216,208,230,201,201,208,194,224,202,185,200,163,223,194,193,202,193,192,213,208,207,228,196,185,192,180,208,201,206,181,184,223,172,225,210,224,212,190,214,240,210,206,210,190,218,223,203,234,211,214,223,210,207,215,206,204,218,195,202,199,190,189,197,227,226,212,215,225,203,210,230,214,225,215,235,163,143,198,170,222,197,213,221,208,232,196,196,198,194,206,214,208,207,207,205,227,190,228,195,206,206,193,205,207,219,202,235,228,215,204,244,252,254,255,249,243,249,234,249,226,249,253,255,239,245,235,234,250,240,251,252,255,247,254,254,237,247,232,240,224,235,211,217,233,245,243,234,245,241,245,226,249,206,208,230,242,247,238,208,241,249,245,203,199,70,152,247,237,211,198,206,228,197,139,137,121,97,132,245,231,253,255,224,255,245,250,255,128,116,135,91,76,55,44,181,251,224,237,255,208,212,190,232,240,208,230,247,208,134,123,206,178,198,215,192,247,250,216,124,185,248,252,242,231,250,207,236,214,224,207,235,228,210,202,169,201,168,148,219,118,34,70,210,251,50,39,179,123,41,41,22,22,28,52,25,131,227,210,206,251,247,242,201,116,78,130,206,247,226,229,149,141,212,248,243,243,241,197,59,32,48,103,136,109,117,67,22,94,137,122,70,35,80,82,67,31,56,128,127,32,27,92,163,149,122,143,82,44,10,25,18,47,48,65,44,35,77,11,35,20,0,24,27,55,14,18,37,52,74,81,115,183,127,88,90,135,155,60,64,92,87,71,32,22,15,21,54,21,26,74,76,59,43,9,19,21,21,38,28,16,33,34,17,17,17,43,33,35,35,43,44,25,42,24,12,25,16,13,36,29,35,14,37,34,31,67,56,54,50,34,11,13,11,39,13,19,12,19,21,47,33,28,6,14,26,28,46,48,30,46,35,38,26,56,22,18,20,51,34,29,41,23,53,68,74,26,8,12,36,22,32,74,71,63,91,92,112,166,104,66,52,47,36,28,40,28,22,15,46,22,58,30,33,35,48,119,63,40,42,54,123,139,78,75,35,59,129,91,107,79,115,83,64,21,57,66,126,251,248,251,247,216,253,243,239,232,250,240,242,246,240,252,241,255,250,241,241,250,248,253,248,246,238,236,243,251,242,229,244,252,238,234,248,244,255,236,239,221,253,243,231,244,246,254,245,248,242,233,244,239,246,251,241,238,235,238,255,242,101,1,3,20,10,20,4,10,13,40,19,9,9,7,15,15,24,32,10,25,7,22,4,12,20,183,202,205,188,192,222,187,194,197,195,182,215,188,203,186,194,183,177,187,189,200,202,206,196,204,192,220,236,210,223,173,192,187,192,198,206,179,198,183,217,190,213,189,189,201,199,221,188,199,174,199,201,198,213,207,208,180,193,188,173,201,213,205,202,199,180,184,163,192,189,192,216,202,202,213,196,223,198,202,190,211,202,201,210,224,208,186,185,197,200,223,207,185,208,187,181,202,216,210,210,204,185,189,211,179,205,195,233,210,187,199,190,200,203,191,202,196,200,214,201,211,209,196,198,195,206,201,219,201,195,203,204,212,218,187,193,201,173,199,213,226,208,195,210,219,192,216,236,205,204,184,188,223,199,227,194,217,209,203,213,196,208,206,204,196,196,174,190,214,208,225,191,210,203,192,215,230,189,226,186,188,230,200,192,203,229,222,224,196,212,194,199,212,206,218,211,205,182,220,196,215,208,190,192,217,210,234,227,214,233,226,218,189,209,204,206,236,224,221,216,230,211,237,209,229,193,209,205,197,235,211,195,80,59,136,199,226,234,210,213,216,199,215,228,220,221,194,208,210,236,239,212,187,220,212,175,189,194,174,180,200,217,202,211,196,195,233,224,244,224,205,215,210,220,217,218,200,218,193,209,216,220,219,199,225,229,247,237,227,237,192,212,213,205,241,211,215,217,226,213,206,218,220,204,190,202,218,229,228,191,192,216,227,233,206,194,230,232,229,233,124,67,146,246,232,207,133,111,107,68,74,45,57,37,21,64,86,114,106,55,148,180,195,165,53,113,110,89,109,45,51,136,204,157,192,213,173,205,215,249,217,160,222,160,216,139,88,172,107,150,235,198,255,238,178,146,231,239,254,239,242,247,216,255,222,194,214,219,212,201,195,199,209,179,164,180,69,33,57,193,170,3,143,237,65,35,24,22,49,27,48,73,182,211,213,221,234,254,227,148,84,180,193,236,255,241,154,154,218,230,253,241,250,202,70,22,51,103,113,114,97,14,53,95,104,147,84,71,113,131,68,60,54,60,147,135,58,23,44,138,158,143,140,65,30,36,25,51,33,39,68,46,40,48,44,16,40,37,42,11,15,60,23,43,51,61,44,89,138,87,115,102,107,149,114,104,55,47,32,28,48,9,16,14,33,40,47,92,50,41,19,18,24,26,22,40,29,68,65,24,55,41,5,21,16,46,87,74,33,38,34,25,40,20,27,27,39,23,37,59,46,50,12,45,54,36,20,35,11,2,14,13,38,28,5,31,23,38,41,70,52,21,33,26,28,19,23,29,44,40,35,31,42,68,19,9,17,54,57,47,88,62,32,15,27,26,34,21,40,54,86,80,111,132,121,82,112,105,69,53,53,20,51,32,32,37,47,13,34,44,21,67,104,74,35,48,48,63,65,70,54,29,57,143,107,104,133,94,133,74,11,47,57,78,211,219,234,254,231,255,238,240,245,222,224,246,253,226,236,232,245,241,252,243,242,243,228,252,237,230,252,250,209,240,234,245,247,236,228,254,243,254,255,233,251,242,243,232,252,251,252,242,252,251,233,255,241,253,255,255,225,250,251,242,243,90,1,4,19,20,17,23,12,11,0,4,15,13,0,6,1,38,9,0,12,10,8,18,29,17,198,167,218,210,160,185,216,196,226,197,204,207,178,188,187,187,186,190,202,195,197,181,215,203,207,206,194,188,198,207,195,216,181,197,214,164,202,199,203,207,220,208,185,193,185,201,182,212,186,189,184,198,203,185,198,192,184,221,178,207,201,187,227,183,199,198,189,198,198,203,197,190,210,211,184,191,191,186,207,207,208,202,230,196,204,207,210,207,226,206,181,226,220,217,205,209,164,208,210,212,204,198,190,195,186,202,192,197,214,208,206,226,222,219,192,179,187,207,225,211,207,210,180,202,208,194,217,207,224,197,230,200,212,218,210,185,197,201,209,220,211,199,195,204,212,200,203,191,205,180,200,207,212,203,213,194,219,194,206,196,191,226,211,176,207,223,240,217,207,232,219,212,202,196,204,187,176,237,185,170,218,190,203,209,192,197,211,204,195,210,203,209,208,212,212,211,213,191,234,198,210,231,200,232,233,217,217,212,218,238,206,212,220,205,209,222,220,221,201,216,202,202,217,226,205,211,208,210,206,208,215,202,112,96,193,220,226,197,221,221,218,214,214,225,196,223,220,207,200,199,201,203,176,192,186,179,201,216,208,233,197,203,202,216,216,211,207,230,217,242,200,241,204,209,210,227,220,211,221,222,219,218,246,203,250,226,232,210,223,219,185,218,229,230,222,235,220,221,190,210,215,213,189,187,224,207,223,226,226,232,166,214,241,227,167,161,227,233,234,177,149,59,121,231,239,207,91,39,47,45,80,104,141,91,99,80,45,86,67,29,55,60,67,75,15,27,34,36,86,71,50,86,96,65,89,116,87,100,129,129,108,45,74,52,114,116,71,38,23,135,243,216,252,249,130,152,216,234,208,230,254,207,220,211,193,177,223,224,234,179,197,196,242,152,127,148,123,90,100,195,105,7,201,194,31,37,38,70,47,45,29,129,199,200,237,243,244,242,209,106,121,222,227,244,235,183,176,211,244,255,248,236,224,83,33,62,100,116,97,123,36,28,94,154,123,107,56,83,109,89,62,47,31,74,161,110,41,25,24,112,148,153,109,35,28,30,40,36,43,35,30,48,45,27,34,9,29,30,31,13,11,23,29,17,33,84,85,49,91,65,75,31,68,77,58,28,15,38,28,5,13,27,7,54,26,31,38,90,59,51,23,30,18,62,27,16,39,21,37,52,83,43,53,48,60,122,167,113,87,47,35,41,38,83,48,44,43,36,42,26,57,73,33,37,30,21,38,9,2,30,23,36,40,42,34,15,20,48,87,49,46,15,27,25,37,34,26,53,39,31,40,32,33,38,21,17,15,27,26,72,87,57,36,22,4,8,18,59,54,101,77,62,99,82,79,126,91,90,88,73,45,41,24,43,20,33,18,63,19,39,45,68,126,82,41,39,38,34,41,33,50,37,33,101,105,99,101,108,111,67,61,26,65,30,132,245,234,244,244,245,249,234,225,232,233,222,255,249,235,226,227,244,240,228,239,226,240,255,251,221,235,248,249,249,251,254,239,229,246,223,240,247,235,249,229,212,241,244,255,250,243,255,246,243,247,252,244,246,241,245,233,252,253,251,249,110,2,20,14,5,7,2,1,19,20,14,17,3,3,9,39,12,7,22,9,11,11,0,48,6,211,182,171,185,210,181,212,201,186,204,201,204,203,200,220,202,205,194,192,198,177,221,207,190,183,216,200,221,191,193,204,213,217,174,212,199,177,181,190,182,193,198,201,205,202,176,186,196,211,187,182,189,189,218,188,210,222,193,194,218,218,189,196,177,174,217,208,190,229,213,193,215,218,206,196,212,178,208,186,201,195,203,199,196,189,197,206,212,203,216,217,204,205,186,219,200,190,211,176,199,181,220,219,219,206,212,213,200,192,219,183,232,204,229,226,194,213,200,198,181,185,197,208,199,224,195,197,205,178,196,217,198,210,213,185,188,194,204,181,220,222,187,198,201,193,207,211,205,226,199,200,208,214,181,207,204,220,199,191,203,197,194,190,226,220,216,191,223,199,195,231,219,215,175,202,221,205,206,226,207,192,182,226,208,204,190,212,200,194,201,197,188,208,206,201,216,206,209,198,231,197,212,224,199,224,236,199,202,199,231,222,232,209,209,244,209,221,205,211,215,249,231,221,198,230,217,207,202,181,196,241,238,155,212,229,218,217,210,233,239,225,222,202,228,212,170,178,211,172,200,192,187,204,202,211,239,225,218,211,233,222,223,216,229,196,210,219,202,226,214,213,228,240,213,204,216,236,230,219,211,229,231,233,193,235,220,208,216,224,236,213,195,221,230,228,223,208,205,241,220,217,211,205,160,214,180,207,228,218,202,189,218,230,232,180,195,244,233,240,215,145,60,136,240,221,235,112,141,141,161,183,183,180,228,234,249,249,233,218,154,169,203,221,211,54,34,11,12,78,90,45,84,166,120,114,165,140,110,140,125,73,107,123,117,158,95,59,53,57,173,250,221,226,254,163,177,237,225,233,251,240,232,227,252,233,223,225,244,244,173,199,251,229,169,170,146,155,129,160,177,69,76,250,138,19,25,16,47,65,24,100,130,200,233,253,255,243,213,162,197,186,225,207,226,182,172,202,243,254,235,247,204,68,38,78,97,97,109,116,36,56,125,131,130,109,65,63,84,96,44,42,70,60,81,147,97,37,14,51,173,94,121,112,25,53,42,15,19,24,14,29,25,26,20,23,27,42,50,32,43,20,47,41,62,64,75,76,43,73,28,67,32,26,38,79,50,56,90,19,8,66,55,30,12,12,17,41,99,50,43,26,7,17,47,34,29,42,24,12,85,109,74,77,133,153,163,130,149,157,113,88,74,175,136,42,27,26,22,38,45,40,54,23,52,45,36,37,25,21,27,12,43,68,16,46,46,67,100,119,77,40,43,23,39,70,42,52,41,54,41,28,32,40,39,53,30,32,28,8,70,90,70,46,21,13,35,40,44,32,56,31,20,21,36,43,67,63,70,81,44,42,43,40,36,32,22,41,38,48,28,34,56,106,74,69,65,36,57,21,21,50,30,37,94,144,87,128,87,102,76,31,30,76,38,35,203,239,244,239,225,233,246,235,238,236,227,242,250,232,242,255,247,227,255,252,249,241,235,241,245,248,242,227,249,222,245,241,241,244,236,242,244,250,223,234,244,251,254,240,244,235,211,230,246,242,253,255,248,247,231,250,254,238,247,240,107,9,0,21,20,7,15,27,17,38,21,29,3,0,6,8,5,2,33,31,30,0,9,33,2,193,183,213,201,203,184,195,222,189,185,201,200,198,189,188,200,206,207,179,215,195,194,213,205,211,186,213,210,191,212,209,218,180,196,184,211,212,196,191,225,189,209,212,199,191,206,186,197,182,204,207,199,203,197,201,198,185,216,207,195,193,199,177,206,196,206,192,183,210,177,183,197,183,216,186,203,194,168,197,180,186,186,203,209,207,211,189,189,202,181,201,198,187,204,180,202,195,198,185,204,196,201,186,209,213,241,209,176,216,205,219,196,205,188,220,213,205,205,187,212,235,198,197,186,206,211,189,173,199,198,211,178,213,217,212,206,197,196,197,176,209,207,207,202,194,202,195,193,192,168,178,201,196,212,215,195,223,186,205,196,205,206,194,201,181,197,205,196,212,221,224,209,187,210,210,192,206,209,178,226,201,223,201,180,206,211,209,219,207,220,192,194,214,189,196,195,228,225,222,196,209,199,213,194,230,210,219,241,218,218,226,225,215,226,235,224,232,225,210,224,212,209,212,242,227,202,227,202,219,209,196,228,196,240,251,243,208,234,230,213,226,210,217,206,187,184,214,207,208,218,221,241,220,220,230,227,224,226,229,225,234,210,226,239,190,208,227,226,233,225,227,239,217,237,240,206,221,233,222,222,222,237,238,159,173,222,245,220,235,241,230,228,244,218,236,246,228,233,255,246,228,225,223,213,236,219,214,213,226,212,202,236,236,250,206,214,252,248,246,181,118,64,159,242,249,237,199,212,220,222,215,231,213,255,226,246,228,227,249,249,252,252,244,237,131,33,36,34,100,47,34,156,239,247,248,224,244,173,232,242,243,238,240,247,222,218,187,122,138,195,250,207,250,252,147,242,249,242,245,245,250,228,247,240,241,241,220,255,249,179,205,246,183,130,140,207,221,128,151,160,51,165,225,24,13,39,51,59,71,138,137,129,210,239,242,247,222,130,175,208,186,219,169,138,144,214,237,239,233,242,216,52,29,53,101,104,129,98,41,80,102,166,163,104,42,57,18,25,66,34,47,38,39,117,169,61,48,8,124,151,123,145,117,17,10,26,9,42,39,30,37,20,12,32,34,31,20,28,34,58,23,53,50,74,88,79,38,36,81,54,84,22,52,67,79,48,67,61,34,56,81,41,48,18,30,23,72,140,78,69,47,28,28,39,29,46,13,35,53,59,81,74,75,112,129,87,71,76,123,164,112,106,151,137,69,9,0,23,33,105,114,57,49,14,47,36,6,34,23,28,28,64,54,55,24,72,110,98,148,168,134,81,76,142,117,61,22,36,48,30,28,20,32,37,19,35,40,14,49,85,83,49,26,15,54,78,81,50,38,58,78,59,44,51,76,54,46,38,66,18,30,20,26,28,45,23,27,36,35,22,28,59,110,74,60,56,37,41,45,65,49,39,19,124,118,94,93,97,102,89,47,28,90,61,20,98,221,240,221,244,234,244,250,255,238,224,245,249,243,238,246,255,244,250,245,248,245,244,250,252,250,248,237,247,230,242,243,245,233,245,244,228,247,229,232,246,255,251,231,239,243,241,253,248,255,246,252,222,247,249,239,254,239,237,243,123,0,31,11,36,4,13,10,2,3,34,7,19,10,7,10,11,8,0,14,22,13,5,11,21,181,205,212,189,213,187,190,201,215,191,192,224,194,213,199,200,194,205,184,222,209,206,197,198,196,176,196,175,194,209,193,199,202,196,216,174,192,202,197,189,184,196,192,189,193,184,204,189,190,190,196,197,197,204,182,182,185,200,205,199,227,193,196,183,223,203,190,199,169,216,194,206,171,204,211,211,195,209,199,208,182,204,202,203,202,208,206,201,204,193,190,169,194,211,170,205,180,220,195,186,191,204,198,206,215,184,204,192,182,180,184,190,189,187,225,204,211,202,179,196,213,190,176,196,180,205,214,212,203,206,202,198,216,221,197,182,188,200,198,170,221,193,202,203,194,196,203,202,214,175,214,212,222,207,217,214,186,223,219,209,216,202,218,215,217,212,196,201,199,196,210,197,201,196,201,220,199,205,217,179,218,211,216,199,190,190,212,217,204,193,185,181,220,220,199,208,226,200,228,200,215,217,210,207,211,213,231,224,223,194,200,226,210,221,211,204,196,227,237,179,224,225,249,208,219,208,243,224,241,216,219,191,193,249,226,240,235,240,204,111,77,154,216,236,198,237,197,250,225,235,237,245,255,243,240,231,253,224,253,240,242,229,245,239,233,243,234,253,250,254,243,240,248,252,246,247,243,248,254,255,237,249,228,99,137,237,238,252,244,225,224,251,252,245,243,255,250,250,232,254,235,255,252,227,214,227,238,205,234,191,196,230,237,221,193,221,228,242,221,131,122,58,127,243,246,233,190,178,172,146,149,158,163,232,245,226,239,229,216,164,200,207,244,232,100,76,69,73,62,12,45,147,169,179,211,228,187,131,189,230,243,207,222,194,172,230,180,140,145,195,172,194,243,182,147,225,241,239,230,222,224,223,236,229,191,213,230,237,245,134,189,202,97,61,90,175,220,123,175,93,61,197,163,11,8,29,23,33,144,216,143,171,242,254,245,237,161,142,229,219,197,198,132,135,184,231,233,239,249,229,105,18,41,72,118,119,102,37,34,77,161,126,72,34,49,16,19,32,50,47,56,43,45,70,109,79,26,10,131,139,95,115,68,25,41,18,19,31,5,13,39,40,1,21,4,10,21,34,1,35,7,32,35,58,101,99,70,47,35,77,93,70,100,150,118,120,109,85,57,50,55,55,28,36,29,55,57,110,113,63,28,35,25,59,14,17,34,20,77,102,44,30,23,35,31,54,29,17,23,16,39,35,27,43,73,23,22,19,116,209,145,52,48,21,29,14,17,14,11,25,19,61,60,53,36,25,70,38,20,92,151,115,101,108,103,59,57,34,27,26,23,17,29,31,27,24,49,19,49,108,62,48,29,19,79,77,65,43,72,101,105,81,65,91,78,65,38,49,29,48,49,41,37,40,27,45,39,41,50,40,21,54,112,106,86,66,40,42,69,99,78,56,55,120,125,104,101,81,142,91,30,16,186,160,78,47,120,234,243,241,255,224,234,247,233,229,248,243,251,254,255,232,252,233,243,247,237,255,248,249,251,249,247,238,242,253,254,249,250,254,245,222,250,249,247,236,240,239,247,235,231,228,242,253,237,255,249,247,245,252,252,249,231,246,233,125,18,1,8,11,33,19,22,7,0,26,9,22,0,9,12,5,5,19,25,2,11,1,9,1,216,175,201,197,172,191,167,181,220,191,202,193,222,208,207,173,197,194,185,205,193,213,185,179,204,188,203,207,190,179,186,202,196,245,214,201,188,202,178,191,197,188,219,189,209,216,217,221,193,193,203,211,193,198,199,190,208,184,189,202,188,187,200,198,196,195,193,200,185,213,200,226,191,187,189,208,189,212,198,195,196,207,198,228,209,207,168,193,197,202,207,207,197,200,202,214,206,202,200,193,186,202,208,217,229,189,205,213,193,201,203,198,191,200,204,196,184,204,193,205,212,196,182,185,201,196,200,206,210,204,212,204,221,194,193,183,182,191,212,206,213,176,189,191,208,203,205,225,188,212,213,209,210,213,209,203,170,207,206,216,198,202,196,213,179,169,197,190,210,199,209,190,205,198,211,199,231,202,197,212,203,225,204,216,171,225,213,209,200,206,207,217,196,183,211,209,207,217,218,176,225,185,216,225,211,229,218,224,219,237,231,247,254,247,251,249,250,240,231,249,255,250,251,255,252,240,254,250,211,246,239,214,220,250,253,247,234,222,199,103,104,186,241,239,240,255,241,255,243,255,237,255,241,253,237,247,235,251,238,247,228,246,255,255,253,212,235,253,208,245,238,242,241,246,205,218,238,224,193,220,225,196,174,100,121,172,214,226,217,221,202,215,201,188,216,190,199,232,200,239,193,214,210,177,171,184,175,168,158,157,157,202,159,147,118,116,113,127,123,89,122,85,98,117,175,145,100,112,85,103,49,111,79,112,137,112,124,132,86,44,22,90,127,117,56,94,111,67,47,35,76,50,39,21,36,63,70,37,41,52,82,61,38,65,50,134,114,122,92,83,102,76,114,74,64,149,105,89,77,77,70,86,95,78,65,84,100,73,147,91,81,115,78,112,116,173,177,119,191,66,85,226,61,14,71,34,15,103,204,204,129,181,247,252,217,148,149,199,239,199,196,187,143,176,228,253,241,231,254,99,21,59,66,119,108,78,65,44,98,141,118,110,71,57,36,22,21,28,34,61,60,75,43,83,118,72,27,14,156,153,101,129,57,24,21,22,46,21,36,34,12,11,14,14,26,55,55,34,15,24,28,8,53,29,70,117,116,53,75,124,117,117,105,161,135,122,99,96,67,57,37,49,36,22,17,37,50,85,88,50,41,29,14,44,36,64,43,49,137,85,45,11,39,19,39,14,7,42,37,35,13,30,31,50,112,92,37,33,137,178,102,23,38,26,27,27,48,13,13,35,67,37,23,24,14,18,21,11,42,19,33,34,37,19,18,63,54,13,46,47,34,37,40,25,35,28,52,46,54,89,67,35,33,45,94,110,68,61,61,168,150,86,118,155,129,87,59,47,10,16,34,33,33,37,43,16,64,21,38,57,50,43,94,96,89,71,84,62,73,79,84,85,44,111,140,135,125,97,110,86,65,33,220,226,178,119,45,172,247,233,240,234,240,253,249,210,250,253,248,247,254,222,245,234,250,248,247,237,219,242,206,227,244,248,239,243,232,244,248,234,237,248,239,225,243,245,237,251,236,255,234,237,235,237,243,249,243,234,237,247,225,237,254,255,239,124,26,8,17,5,16,21,18,25,10,6,11,9,15,7,15,0,18,0,36,1,39,18,13,31,198,181,198,187,213,201,222,199,184,200,190,184,196,190,237,194,200,188,214,180,203,198,206,191,193,214,202,190,192,206,200,194,207,174,193,173,213,201,180,175,205,176,189,191,184,216,198,191,211,179,195,211,191,223,195,208,207,195,214,198,211,183,212,202,205,179,199,211,211,222,191,186,200,201,206,205,209,209,209,190,194,188,208,179,227,177,218,208,213,206,203,188,191,204,213,204,191,183,196,226,193,206,204,196,192,219,220,197,210,218,203,200,220,227,206,223,208,185,222,193,173,227,210,201,199,206,183,217,181,198,201,207,219,203,203,194,189,181,214,211,198,192,190,218,191,212,204,208,204,190,193,190,194,171,201,201,191,215,210,208,201,216,206,202,211,219,193,206,214,213,207,185,213,205,205,223,189,212,205,225,189,209,191,194,202,223,216,197,215,196,216,190,203,210,210,212,223,207,229,222,229,208,207,238,206,234,231,242,241,244,233,247,253,243,255,254,238,243,240,239,246,255,232,241,240,255,243,241,251,224,223,241,190,186,183,177,163,218,187,166,146,185,210,192,204,162,169,186,159,172,184,165,172,151,159,149,165,143,174,159,160,139,160,170,168,152,146,191,153,145,141,141,148,135,123,143,156,165,130,117,132,122,122,119,109,117,120,117,110,131,114,124,129,92,116,112,88,130,104,79,91,83,79,102,100,98,143,100,147,122,104,127,108,82,51,40,50,61,65,89,92,62,75,83,79,77,65,86,93,52,98,78,24,31,19,68,40,16,29,33,20,5,42,55,73,95,115,113,58,86,70,69,44,46,11,44,26,34,53,11,43,13,21,32,23,55,50,79,112,63,64,63,39,19,47,66,34,28,5,17,15,56,65,52,42,34,5,31,110,103,43,80,120,143,129,156,104,129,213,52,154,222,63,8,26,21,69,195,204,169,161,237,248,251,174,135,213,240,248,169,110,184,210,241,249,252,217,247,130,34,47,76,108,112,105,57,47,90,128,157,114,96,70,39,24,24,16,9,40,61,53,94,40,83,127,60,37,54,165,103,103,114,17,20,6,0,14,18,18,31,34,32,40,25,11,3,32,39,12,42,28,43,37,32,51,79,74,32,42,71,97,74,111,139,81,88,45,61,31,33,54,14,17,33,8,48,45,86,97,48,23,57,51,34,28,50,22,33,116,95,35,41,34,16,29,34,37,69,61,21,25,30,20,67,98,90,32,45,44,62,46,17,14,40,8,28,27,38,32,26,55,32,22,24,18,9,20,14,35,14,17,44,41,13,59,85,85,55,32,34,34,17,35,41,48,84,84,58,96,69,49,50,29,83,130,92,59,66,101,147,106,139,105,141,111,80,51,58,48,58,56,35,33,43,49,42,37,34,33,25,27,44,85,32,60,63,50,32,50,57,48,86,51,108,128,141,100,95,127,93,12,47,192,218,225,138,48,40,233,233,233,252,233,248,252,242,255,248,238,239,226,247,249,249,228,246,246,246,253,239,247,233,253,246,222,231,241,239,225,255,238,225,246,243,254,240,241,230,238,249,253,239,248,251,246,240,244,255,247,236,234,255,247,234,226,126,6,5,41,23,15,20,22,0,32,23,14,34,0,22,6,8,3,12,14,13,28,27,9,13,195,179,201,182,194,229,207,198,177,192,193,184,181,200,176,191,193,180,199,198,182,195,187,212,194,178,200,197,191,207,178,178,196,200,172,201,204,198,199,172,170,180,197,201,217,164,192,175,211,196,179,186,193,222,191,200,190,200,187,202,193,192,189,180,196,195,190,205,185,188,200,184,211,200,177,194,196,219,175,200,191,203,221,191,196,199,209,208,196,204,220,195,209,213,204,213,201,183,185,205,184,220,206,200,183,198,188,179,228,199,218,191,204,200,220,234,207,185,210,199,203,191,209,217,174,181,175,199,199,183,196,199,206,217,224,219,173,208,199,220,200,224,226,217,193,193,190,210,196,215,213,198,186,210,201,208,173,212,218,205,188,201,201,221,201,219,198,206,200,189,212,184,200,199,206,215,222,202,216,209,197,206,227,195,211,198,213,188,204,191,218,210,206,217,203,204,224,217,194,216,221,223,221,213,223,209,196,184,168,179,180,174,171,176,198,175,145,160,164,168,150,163,141,149,137,151,138,104,119,146,181,198,95,55,112,73,96,111,84,132,131,120,96,90,96,93,84,77,76,64,72,80,80,33,84,57,67,61,88,94,81,66,52,62,59,46,84,70,72,74,46,61,48,60,73,40,103,108,60,52,56,73,133,87,112,102,105,57,65,53,79,35,41,47,40,55,42,72,37,40,42,46,50,45,59,49,69,112,120,125,83,86,144,86,68,55,23,32,69,62,87,95,62,85,87,74,113,103,122,89,88,82,37,28,23,14,20,35,56,61,46,57,43,46,76,136,114,101,64,30,77,79,68,49,31,53,66,72,46,25,70,67,31,59,60,60,43,57,96,94,120,68,56,26,38,42,19,27,22,20,25,13,49,37,46,52,1,32,80,34,35,111,107,93,177,185,75,157,176,93,215,242,36,12,28,10,138,175,188,215,226,236,238,217,143,187,243,246,240,147,102,155,240,239,249,251,247,159,15,28,70,116,116,86,36,53,116,143,127,106,46,49,43,34,30,11,33,45,85,90,117,98,55,115,137,24,5,88,163,128,122,120,31,23,22,27,31,7,6,35,43,3,36,22,9,15,28,24,37,60,10,22,30,9,35,54,88,86,36,35,36,65,70,60,57,45,50,52,57,25,37,33,44,41,12,34,40,67,66,48,46,81,21,22,49,23,34,29,98,61,23,36,31,27,28,29,25,99,35,32,6,18,23,86,120,76,26,4,47,41,39,32,27,42,23,19,25,23,16,35,55,23,28,37,21,30,48,22,24,24,45,42,31,26,61,126,131,43,31,74,66,36,36,51,62,87,92,104,75,57,53,56,63,86,112,67,66,55,31,50,116,129,135,77,94,66,57,39,27,31,40,16,12,16,22,18,36,36,25,46,44,34,20,31,46,28,33,40,21,23,68,56,46,119,140,129,114,85,91,113,45,31,145,147,173,115,35,29,143,239,254,240,242,249,253,247,247,243,249,235,229,247,234,248,253,252,234,240,238,243,227,249,236,238,219,249,232,236,252,246,239,247,253,230,233,248,242,251,237,251,240,236,252,237,241,243,240,230,252,214,246,245,248,244,244,101,4,8,11,9,10,20,3,13,22,5,18,24,0,13,5,22,20,12,13,11,17,6,6,9,197,224,174,189,211,154,189,202,187,182,197,192,190,168,197,205,189,196,183,167,185,216,202,188,189,156,191,198,208,195,185,207,216,197,185,189,206,188,208,189,201,190,188,201,193,207,195,191,186,216,224,204,187,190,224,184,202,185,216,208,179,224,191,201,185,212,205,189,199,190,203,197,206,213,206,190,177,200,174,194,191,221,212,194,198,186,215,188,197,216,183,200,184,202,203,190,203,202,188,203,190,184,209,209,169,205,195,210,227,209,193,208,189,201,200,193,209,205,198,210,209,208,219,215,209,167,195,192,187,216,210,192,195,184,198,197,199,194,212,207,192,182,188,206,187,205,192,215,188,194,194,185,191,194,203,197,199,205,211,181,180,206,185,189,204,202,207,216,197,190,213,223,199,208,226,181,215,193,194,210,168,202,195,212,207,231,222,210,214,215,214,202,217,233,225,218,227,218,221,213,212,227,240,235,193,206,111,18,20,33,21,16,3,20,13,22,15,5,15,16,15,1,24,1,14,3,30,23,30,8,63,88,33,17,13,11,12,36,1,13,12,19,18,30,6,9,6,1,0,11,36,14,17,6,16,30,18,4,0,19,7,7,1,40,22,23,24,8,10,4,23,12,7,19,12,22,18,16,10,50,22,20,27,12,34,19,5,22,11,25,23,6,14,17,6,16,11,11,28,10,0,13,5,16,23,31,19,4,62,88,67,55,44,76,91,54,22,10,0,16,32,10,22,60,79,72,84,96,92,64,69,36,9,5,4,28,29,33,30,33,21,23,9,30,20,116,132,118,65,58,66,83,49,39,22,42,22,45,34,21,44,37,36,18,1,33,17,40,21,33,90,75,24,17,27,33,39,18,16,43,54,19,14,3,28,43,18,11,44,14,24,95,81,90,166,121,100,205,186,173,251,186,18,61,4,40,166,171,210,250,215,228,200,156,200,250,247,255,196,129,165,180,225,238,254,228,131,38,28,60,94,93,102,48,32,93,112,131,88,80,41,35,39,20,22,23,45,82,112,129,131,116,104,140,130,33,7,97,173,97,116,83,44,30,6,5,30,27,30,20,22,21,14,28,40,13,32,36,44,25,16,20,29,21,12,50,102,60,44,28,37,37,62,56,43,21,30,27,39,35,27,24,15,40,14,17,40,73,53,43,47,63,41,19,26,41,48,26,66,111,32,25,16,40,34,59,29,51,35,26,43,37,11,94,130,47,19,12,36,41,35,33,52,5,41,28,27,45,14,2,50,64,30,10,9,35,9,20,23,25,23,53,28,32,68,151,74,11,29,40,25,41,22,44,76,113,47,86,82,64,37,20,60,61,94,55,24,38,29,47,88,116,72,46,53,51,69,69,36,36,24,36,14,35,33,36,26,51,9,38,51,33,12,19,53,37,24,36,43,29,18,59,20,79,143,128,104,84,106,118,57,33,32,71,42,31,32,28,181,228,245,250,254,255,252,248,248,255,250,231,226,247,239,255,251,248,255,250,241,228,231,232,251,237,250,238,239,237,242,233,251,241,243,246,214,253,222,234,248,244,243,234,232,234,252,234,252,237,255,226,231,246,242,241,242,121,3,4,2,2,3,4,18,19,7,22,15,11,4,3,6,14,0,1,24,1,0,3,12,13,193,200,195,214,193,201,191,185,199,222,178,203,189,203,209,185,193,219,181,177,196,194,202,182,194,190,200,213,202,207,199,205,189,208,189,205,194,210,198,175,188,195,198,217,188,218,196,197,195,188,193,205,193,191,192,182,206,211,191,196,203,202,179,208,177,178,199,197,217,224,194,208,208,219,217,198,214,209,217,196,168,204,167,212,204,217,201,203,211,191,195,222,210,221,201,204,185,204,189,192,187,190,198,226,224,221,194,204,202,201,203,190,201,216,197,188,216,200,215,203,197,193,204,200,218,178,209,221,201,204,174,194,198,210,215,223,194,194,169,218,223,202,206,188,198,226,184,194,200,193,209,198,193,203,202,195,189,216,212,197,219,198,222,215,191,178,235,196,213,208,194,195,199,196,200,224,199,232,220,198,209,203,223,169,213,229,220,213,207,214,202,224,199,217,209,218,201,212,208,229,227,238,241,200,207,219,114,32,35,32,62,19,40,21,30,15,22,35,18,10,16,22,29,25,10,1,20,26,41,12,27,49,25,10,15,0,7,7,4,14,22,10,17,4,21,19,8,25,10,0,10,3,21,11,15,29,11,20,16,17,36,6,18,14,21,19,10,17,4,18,35,17,8,8,25,16,9,23,20,10,27,18,12,4,7,14,14,4,2,9,18,11,10,31,12,18,7,27,29,13,25,13,19,15,34,24,21,12,21,19,44,30,34,61,64,82,43,22,5,6,44,21,60,74,44,106,95,59,73,66,57,0,12,4,5,24,25,15,35,45,17,34,35,12,57,80,115,108,77,62,65,71,52,8,15,23,11,39,32,31,44,37,64,43,35,83,41,33,74,68,84,119,66,63,25,42,118,22,37,1,19,28,23,2,54,52,51,133,88,65,129,97,36,120,155,89,170,199,155,146,142,46,31,139,93,89,137,167,220,242,205,212,130,156,228,247,242,243,161,145,162,139,228,240,239,138,17,41,83,127,110,90,73,78,115,150,116,104,64,51,34,16,25,22,32,35,91,100,110,132,107,112,82,161,115,26,18,112,162,94,109,110,23,21,5,6,8,4,10,26,48,26,49,26,28,16,18,29,18,31,50,42,44,43,26,38,91,76,36,45,25,68,49,47,46,22,5,43,18,41,41,77,50,20,23,39,40,61,57,42,53,83,23,17,25,10,39,27,55,83,13,41,42,31,43,38,50,62,26,17,26,34,28,58,117,48,34,24,37,41,39,37,60,26,44,68,34,32,14,11,41,32,40,31,32,8,16,32,21,37,10,15,37,19,60,109,69,18,23,41,33,15,52,53,83,84,104,104,83,21,30,0,55,56,73,33,73,65,49,63,43,60,51,25,73,43,46,55,15,39,14,39,34,18,29,32,12,33,22,48,29,33,29,63,15,56,41,25,47,38,51,28,37,103,143,126,106,78,94,118,47,36,26,52,22,31,16,110,248,251,245,253,241,243,250,254,252,247,253,235,215,243,254,247,249,250,241,255,235,246,229,246,231,241,247,231,226,245,246,254,239,234,247,238,212,247,227,238,249,234,242,250,231,222,240,240,231,243,231,252,236,223,251,247,241,135,3,32,5,13,32,14,12,37,19,28,10,11,14,15,8,17,33,2,11,18,10,34,13,29,169,191,184,176,191,184,196,192,171,170,213,206,221,197,195,217,189,187,199,190,214,198,190,208,185,204,203,188,195,189,188,201,187,196,202,220,205,198,196,201,214,198,206,191,205,201,191,183,201,189,207,208,216,183,202,189,214,191,174,209,188,181,200,206,208,184,208,181,186,206,186,181,205,195,204,208,201,195,206,205,208,195,180,197,204,209,191,197,186,208,196,198,192,215,203,177,212,197,206,197,212,192,197,195,225,195,199,204,207,205,230,205,202,190,207,189,213,210,201,193,190,196,227,209,183,205,227,206,177,185,214,195,207,221,203,199,196,215,223,203,205,212,211,206,224,202,210,228,210,184,185,198,181,213,199,211,223,182,194,190,208,195,194,212,215,212,206,226,214,199,206,196,202,198,214,186,229,202,214,219,212,208,216,216,210,233,204,207,214,220,222,224,213,238,214,220,214,222,194,226,198,183,242,219,224,226,247,235,231,210,209,207,232,215,229,210,206,217,237,228,203,236,202,198,211,196,181,190,182,160,186,157,155,157,148,182,156,150,140,130,147,130,142,119,120,118,92,129,100,113,135,146,139,126,130,127,110,134,134,120,143,122,132,137,137,135,134,142,165,129,135,114,124,146,144,133,130,102,115,152,126,124,123,97,92,90,112,148,127,155,153,170,169,158,137,143,174,160,181,152,176,152,155,163,154,167,157,168,155,102,119,184,164,107,193,164,142,174,118,102,84,31,62,162,168,140,122,116,108,103,154,158,153,209,185,203,199,187,159,145,190,200,217,149,64,106,89,103,83,62,67,119,154,150,166,186,177,213,156,94,173,171,225,201,155,167,173,211,213,170,130,121,95,190,229,252,254,212,225,247,254,216,214,212,228,244,243,251,243,238,137,57,69,161,141,131,215,139,87,140,83,3,134,227,120,115,158,203,239,233,169,107,164,191,239,253,235,188,55,117,189,191,248,250,171,27,11,65,115,101,102,42,56,128,133,143,101,65,75,42,19,8,18,8,30,79,106,106,110,107,107,96,91,152,111,9,38,135,122,85,116,44,14,27,0,18,28,33,38,10,21,35,17,9,34,13,37,15,46,4,29,33,14,22,23,40,92,100,66,50,50,97,49,42,36,22,22,43,19,29,49,58,64,51,7,31,33,43,32,20,45,59,34,16,21,32,64,29,77,116,47,21,40,3,23,32,14,42,48,27,45,15,51,69,89,27,18,18,32,49,53,85,99,84,91,50,46,13,16,12,25,28,20,6,10,54,26,22,18,33,19,7,32,64,51,122,47,34,31,23,20,61,50,75,99,92,69,56,49,25,31,18,39,79,60,68,75,65,49,76,68,45,26,11,51,47,45,45,52,23,29,27,33,9,33,26,28,59,44,50,42,32,45,26,37,18,29,32,29,44,41,22,42,112,156,133,124,72,90,115,54,18,54,115,144,128,214,253,232,240,249,252,249,249,240,250,248,244,243,255,252,238,252,241,244,252,251,237,241,244,229,252,220,236,238,243,252,253,228,234,244,244,247,247,217,244,235,248,249,245,242,243,226,234,252,252,242,221,234,244,233,234,246,251,250,124,14,6,14,17,4,26,23,4,1,24,6,2,11,1,5,11,11,4,2,7,9,5,14,9,186,178,203,199,195,179,189,192,195,216,191,190,199,194,179,195,208,195,204,189,180,207,210,195,217,195,198,209,206,168,183,176,219,186,198,215,194,195,192,216,181,183,161,185,199,197,191,178,186,169,185,210,176,222,201,184,201,177,201,213,201,199,180,183,190,176,198,193,232,184,208,207,205,192,212,180,189,182,193,213,190,192,205,192,200,210,203,196,208,189,191,207,199,208,190,189,194,229,190,205,205,193,198,200,216,205,202,207,200,210,210,189,208,194,215,221,229,184,187,199,181,193,187,199,187,222,185,200,219,186,202,209,192,187,218,209,210,196,221,204,198,197,188,208,186,202,214,214,217,176,203,197,207,203,208,195,185,185,222,220,205,227,200,212,205,203,218,182,213,185,201,201,217,214,203,220,217,202,196,199,214,222,203,223,218,205,224,205,214,198,214,226,212,229,224,217,216,213,222,218,210,213,198,225,210,221,237,247,242,244,230,224,225,248,252,248,238,252,235,247,242,246,239,244,236,238,255,234,242,255,253,236,224,242,244,240,248,252,247,236,245,248,255,221,255,255,255,234,247,215,254,237,243,244,253,254,253,252,229,244,237,247,252,255,250,245,236,236,250,252,252,254,244,228,246,253,252,248,246,241,245,238,247,240,242,242,242,255,238,234,230,246,252,255,254,255,243,251,246,245,243,247,237,222,236,242,245,252,228,252,246,250,249,176,212,237,243,250,255,232,148,108,151,247,178,185,178,125,139,158,246,252,244,245,236,247,238,241,247,249,255,226,250,169,80,98,116,106,63,76,86,154,245,231,241,255,235,246,255,216,204,233,253,182,196,179,247,254,254,219,150,122,106,237,242,247,236,249,238,248,255,245,248,250,238,238,250,224,255,246,161,30,73,184,118,133,240,111,99,192,106,106,191,243,164,104,178,213,248,198,93,155,234,242,235,234,201,138,120,157,224,209,241,209,47,62,80,76,101,103,49,65,74,107,127,99,79,58,66,18,12,4,27,30,87,125,136,109,124,89,101,73,111,154,82,0,60,147,114,101,93,38,14,12,1,22,17,19,34,21,20,40,13,15,42,45,24,36,38,41,25,33,31,43,29,55,111,87,82,94,73,60,56,62,46,55,37,32,8,39,68,62,58,35,4,25,29,39,24,32,36,24,28,21,5,50,8,20,110,91,45,29,22,9,62,50,20,20,25,47,38,29,19,81,133,50,43,15,38,37,24,116,183,202,182,156,115,67,21,36,58,23,26,16,26,49,7,25,41,2,9,28,34,35,45,108,35,14,41,16,15,34,53,56,69,47,56,14,26,30,15,14,46,110,68,64,86,82,72,53,65,77,56,25,13,27,14,34,39,23,32,56,17,15,29,30,31,20,25,17,44,33,35,33,30,10,32,35,21,34,28,49,35,102,118,130,119,77,89,96,85,19,88,232,249,237,255,247,241,255,249,245,245,249,250,242,222,239,235,235,248,251,233,233,239,254,250,244,238,247,230,246,236,236,241,239,234,251,243,250,232,241,248,225,249,237,248,244,233,234,249,246,211,231,226,236,221,242,227,232,237,239,253,249,226,112,3,11,41,7,17,8,28,37,9,18,12,23,10,1,0,20,17,29,16,8,8,10,18,7,205,184,180,213,182,197,167,192,212,212,202,189,191,206,204,196,184,177,199,197,187,183,218,177,190,185,219,201,217,220,207,186,200,208,216,193,202,169,226,200,204,181,187,198,204,215,193,189,164,213,190,176,180,197,219,189,206,189,188,193,221,203,209,193,198,184,197,194,178,179,177,181,211,175,182,196,192,197,205,175,185,215,200,212,215,194,192,181,208,200,191,207,191,203,180,201,196,184,202,228,184,197,200,192,189,224,202,208,204,192,199,205,190,191,202,201,210,195,193,216,207,196,203,217,212,216,208,194,203,199,205,204,203,215,197,202,172,200,206,193,192,186,206,244,213,201,200,222,209,252,205,194,217,191,203,194,195,190,198,202,204,219,214,218,208,218,188,223,208,206,211,189,230,216,204,233,198,198,223,243,198,222,202,187,216,234,210,199,214,214,220,203,213,222,208,208,198,213,236,229,203,230,226,204,204,218,197,202,208,222,228,248,240,240,218,238,239,242,251,243,227,232,198,236,231,240,206,238,251,242,247,229,247,235,247,251,231,252,255,247,243,238,245,251,250,239,247,255,245,247,250,253,236,254,231,248,242,239,247,228,254,236,253,249,253,246,243,223,252,247,238,250,242,250,248,228,243,223,230,254,231,239,242,241,243,242,239,252,249,237,248,252,244,247,250,240,254,251,246,234,231,228,255,241,236,234,231,228,223,247,249,241,207,199,227,243,219,247,235,254,178,128,205,200,174,165,156,196,177,175,218,249,249,249,254,244,250,245,222,241,230,241,255,140,82,70,117,124,65,95,86,126,230,228,246,157,188,238,248,198,191,191,218,193,183,196,245,245,246,218,122,73,110,161,210,224,241,239,228,233,240,246,241,244,221,243,193,180,238,231,66,16,149,167,68,169,142,49,115,195,175,120,243,229,102,144,210,237,252,142,151,232,254,252,241,223,167,221,183,191,243,238,163,58,36,68,107,88,101,58,47,95,117,129,67,62,47,14,20,13,2,37,57,65,88,109,112,122,118,105,119,114,143,129,74,13,79,146,104,134,109,16,12,2,20,27,3,43,29,35,41,18,41,28,4,25,41,10,34,26,23,25,17,19,28,37,70,59,122,99,65,56,46,47,40,36,27,60,6,36,31,44,41,41,8,22,30,44,59,27,57,34,26,27,14,17,24,50,134,88,32,44,40,33,18,43,53,11,31,27,22,35,37,109,153,62,46,34,35,57,54,237,242,242,233,235,204,150,63,38,58,35,47,14,18,25,26,18,41,18,44,7,36,57,72,116,38,50,20,31,32,43,40,77,52,39,30,30,32,50,25,69,89,125,91,76,81,50,19,18,37,49,62,51,39,24,26,51,44,27,45,20,33,44,27,24,26,32,38,29,45,14,33,55,28,17,16,41,15,42,25,54,24,64,132,144,116,90,91,74,72,7,91,232,246,245,254,252,250,255,243,239,238,231,250,229,235,252,246,254,230,254,240,247,236,218,229,235,249,225,244,222,249,242,246,243,238,245,241,247,246,228,246,247,248,227,253,230,215,247,246,239,242,226,252,254,249,237,243,254,240,246,243,247,244,125,27,13,11,4,13,15,8,18,38,4,0,21,4,11,22,0,3,9,8,14,0,12,20,5,197,199,185,214,181,176,212,196,178,181,193,194,193,182,182,197,193,205,199,201,178,226,198,212,186,209,208,198,171,195,203,208,208,178,199,203,182,207,195,205,202,200,178,192,203,198,194,190,180,205,207,178,183,178,177,183,190,195,219,211,190,193,196,217,191,185,197,186,203,181,185,201,225,192,172,206,179,195,206,210,196,207,225,216,197,202,213,191,194,222,183,212,155,195,194,205,194,191,179,194,196,198,192,210,187,192,181,190,202,195,215,194,194,218,204,191,210,204,184,215,224,198,220,195,194,195,178,210,204,222,219,214,206,201,229,206,217,208,201,186,199,224,195,202,229,221,198,213,202,223,203,184,193,199,218,213,212,222,212,208,188,225,211,206,192,197,217,212,208,209,203,224,220,220,230,211,214,220,212,226,232,206,215,235,223,206,222,208,199,240,228,181,207,220,218,216,213,213,219,208,201,205,218,206,218,225,214,223,213,213,218,219,214,228,237,222,203,222,219,211,223,218,201,203,222,241,214,209,234,223,192,221,213,212,205,229,241,229,214,232,222,210,235,216,238,201,221,233,223,210,221,217,231,218,230,223,228,216,208,222,227,217,220,211,233,237,195,226,225,238,247,228,243,218,236,221,235,225,195,240,211,208,220,218,224,219,231,226,211,229,230,199,223,230,210,228,220,181,225,203,214,211,228,227,179,221,210,199,197,207,238,208,193,171,224,213,214,229,198,193,149,115,195,175,154,203,189,177,158,164,236,223,216,232,229,214,224,216,187,212,214,217,247,126,78,103,96,103,72,87,49,152,213,123,219,182,199,241,203,158,91,197,209,199,185,204,238,241,221,213,156,81,102,141,144,207,235,219,212,203,242,213,237,218,207,222,182,146,195,177,19,67,168,147,110,129,105,68,70,161,141,114,162,194,100,164,203,235,236,152,186,245,242,239,245,147,133,186,236,227,250,169,66,31,57,121,94,101,100,23,88,139,146,100,77,60,35,15,34,2,16,36,102,110,113,120,148,92,81,108,95,116,139,150,48,16,103,155,106,120,105,31,37,31,24,9,38,14,36,17,24,13,35,8,30,22,20,43,14,45,22,22,22,34,24,45,50,52,67,84,52,90,73,50,44,70,45,37,22,44,30,41,65,48,25,33,50,40,26,50,62,47,17,13,16,26,18,80,141,35,18,26,12,30,21,41,23,34,64,51,34,43,38,57,155,51,72,28,78,94,128,192,181,150,159,158,161,98,59,48,48,18,13,21,11,21,15,29,26,35,9,17,54,29,63,115,59,23,34,20,26,39,19,58,46,65,31,70,65,34,25,112,126,158,90,84,67,34,21,47,66,32,37,39,11,30,16,34,41,34,20,26,23,47,16,23,3,25,34,31,57,45,31,31,40,62,28,22,32,46,34,13,38,48,125,144,124,97,123,126,89,46,70,235,241,232,234,242,232,226,252,224,243,251,245,218,222,251,241,249,234,251,244,226,229,243,231,246,231,226,254,247,243,228,251,232,227,239,240,234,249,246,242,233,250,234,236,225,231,241,202,244,252,246,218,248,225,254,220,205,240,240,231,235,245,109,11,16,8,31,14,7,10,15,6,5,2,7,0,29,7,4,0,1,14,13,26,15,0,8,201,202,201,186,204,191,226,187,198,179,176,176,209,183,201,196,176,200,216,208,187,222,190,188,206,207,188,202,201,176,181,228,186,187,198,199,190,221,175,182,180,184,187,183,197,203,184,200,208,189,193,192,214,174,196,197,180,191,182,206,202,199,195,185,194,200,182,182,195,213,201,195,193,203,196,179,216,209,202,198,206,186,209,187,203,214,197,190,196,200,203,171,203,181,207,202,181,198,181,177,199,169,196,203,191,199,197,203,214,184,188,215,194,196,215,219,210,193,203,210,220,193,216,223,209,207,207,224,225,218,214,202,199,212,225,204,216,194,203,207,202,227,198,190,206,188,186,176,187,200,201,205,216,191,201,208,209,206,231,201,235,203,202,207,243,215,201,198,188,196,219,213,233,202,205,215,233,222,216,224,247,214,203,180,210,213,220,195,210,211,190,216,242,203,191,213,209,229,189,211,197,220,240,212,213,205,219,211,214,219,231,213,195,195,218,216,227,227,223,225,209,220,203,212,232,190,218,196,235,183,215,215,199,218,202,202,198,207,222,241,238,206,207,240,211,185,223,181,195,220,206,226,226,174,202,213,211,227,230,165,204,213,216,215,234,218,205,190,223,217,198,223,224,209,217,205,240,182,171,214,245,183,218,219,212,203,208,221,203,172,220,199,210,221,216,199,228,210,211,209,198,213,200,197,194,205,189,165,185,232,228,221,157,153,181,217,190,214,182,192,170,90,160,181,172,183,179,132,103,141,208,217,222,212,207,217,224,217,183,216,202,226,227,121,70,77,38,75,71,103,69,177,224,179,209,169,212,172,153,174,133,239,226,184,143,202,244,198,239,244,172,64,112,134,149,205,233,220,194,192,222,236,220,216,205,213,155,81,195,104,37,135,188,124,101,140,61,78,85,128,142,92,147,184,141,191,241,230,170,167,171,151,131,108,87,38,0,121,180,195,207,78,59,53,122,105,119,79,31,96,116,125,95,56,64,20,25,8,6,2,33,87,113,120,122,106,134,80,85,95,106,118,133,158,56,28,128,130,105,101,58,17,18,11,17,38,16,8,22,6,36,19,28,14,25,42,62,63,37,55,54,7,33,42,28,39,14,20,86,85,81,150,133,87,108,55,39,13,28,6,40,54,66,66,82,12,50,48,50,74,70,30,16,0,9,16,34,81,106,49,35,21,32,41,51,51,31,40,47,37,50,37,45,20,135,115,94,186,251,217,133,61,41,27,43,24,34,32,15,51,25,35,32,15,35,53,36,31,55,16,19,53,46,47,49,117,108,34,18,33,18,64,45,64,98,37,85,115,86,44,85,141,146,128,78,105,83,57,50,73,60,50,80,66,27,49,24,30,35,29,15,30,31,19,11,33,34,31,7,33,60,49,46,29,33,29,39,55,55,50,36,48,15,44,141,147,118,104,123,117,109,30,50,236,253,246,222,231,236,231,255,249,251,246,218,237,224,250,233,236,240,230,237,232,245,244,249,245,247,252,230,241,247,252,242,236,235,245,236,233,249,214,234,217,254,231,222,224,226,249,228,250,232,234,236,236,243,237,251,235,253,234,221,248,234,114,4,11,24,11,15,27,12,14,7,16,23,12,3,8,16,5,0,20,10,22,35,8,19,7,196,205,206,183,165,209,205,198,204,191,203,192,203,188,199,213,198,182,206,188,232,172,183,189,215,197,198,185,181,192,213,185,227,201,200,205,209,196,178,192,204,193,195,181,175,188,192,173,174,195,201,203,172,211,195,182,209,179,187,193,197,192,204,150,196,208,171,206,165,177,198,208,210,183,187,196,199,173,219,206,207,196,216,204,180,211,206,187,194,210,190,188,209,212,204,194,212,213,198,194,194,184,189,194,198,219,208,222,202,196,200,214,197,212,177,211,211,218,204,213,220,147,199,225,204,214,203,180,218,194,209,193,188,172,205,203,212,196,217,214,192,229,204,202,205,197,217,202,206,231,198,182,216,235,211,196,180,195,202,199,191,206,198,207,239,227,219,184,221,206,212,194,204,211,207,228,212,224,206,211,196,197,201,222,211,215,196,228,216,224,191,210,214,221,205,234,208,224,223,230,220,210,229,215,194,232,212,215,209,195,223,240,213,209,231,198,210,215,201,213,197,236,217,211,219,211,209,202,202,208,211,205,211,222,223,216,218,197,216,212,193,217,224,222,202,210,192,218,212,208,209,198,207,217,204,207,220,203,205,217,218,203,200,220,217,231,221,208,213,211,196,232,242,182,217,198,207,204,174,242,237,225,197,200,219,210,206,200,206,204,187,226,216,192,184,214,206,210,203,208,225,224,217,185,195,230,191,169,155,219,197,205,138,142,213,204,198,229,173,186,120,110,157,165,140,166,131,128,91,124,195,210,218,213,214,211,226,217,178,209,206,234,230,83,85,54,85,84,76,89,76,203,229,190,222,172,170,172,214,182,203,228,147,119,153,194,238,215,211,234,118,67,113,122,168,210,225,205,213,243,210,229,225,229,225,184,97,103,159,68,66,202,162,110,166,75,32,48,74,135,213,108,202,217,173,233,215,170,102,44,64,60,18,29,21,15,2,114,185,135,73,1,67,103,110,134,79,41,70,113,144,81,54,79,46,15,35,15,21,34,64,114,131,83,99,88,72,93,102,82,107,99,130,130,16,27,127,125,100,123,59,28,8,24,23,25,7,33,29,26,34,19,40,52,74,82,79,64,51,42,54,44,28,34,35,29,0,36,156,139,117,158,157,95,103,42,37,36,32,48,52,49,74,70,62,18,43,23,52,92,44,18,34,37,14,35,19,69,102,68,49,14,49,24,30,13,26,21,30,15,54,77,29,58,203,139,64,192,224,185,158,124,88,63,69,57,51,40,22,88,21,33,47,20,14,33,21,14,78,30,12,38,37,32,35,115,155,58,32,17,18,27,63,78,53,32,154,138,67,82,125,115,178,147,125,141,62,85,64,66,46,24,49,36,10,31,13,29,16,64,23,25,39,28,29,38,7,37,24,43,37,28,36,18,30,40,45,29,38,35,21,36,43,57,133,132,135,108,95,121,84,23,67,236,232,254,249,234,229,227,242,254,224,241,217,244,240,212,242,233,242,253,247,240,239,255,243,236,241,234,225,234,238,250,244,230,243,239,208,242,234,250,239,244,242,227,221,216,238,230,228,220,231,238,251,222,235,248,250,238,231,245,239,250,230,116,2,15,9,9,7,29,10,11,24,34,18,9,3,6,9,4,8,18,1,24,37,19,4,23,186,191,212,221,192,177,183,194,201,204,191,203,211,182,221,195,188,193,198,190,216,210,212,206,180,205,179,194,183,205,208,197,199,185,208,200,207,205,195,204,184,201,187,195,170,201,182,207,192,179,208,178,190,206,178,214,206,203,174,209,208,202,190,196,145,171,200,193,183,189,175,203,191,186,213,201,178,188,221,180,197,177,202,195,213,192,206,172,207,195,192,186,196,200,194,171,194,186,188,195,199,192,191,191,219,194,193,220,205,204,199,220,197,194,200,207,211,214,192,186,193,199,210,209,203,205,196,223,202,201,208,224,188,230,190,198,193,190,223,202,194,196,198,178,197,192,169,214,218,212,196,217,191,226,204,211,226,222,228,223,215,215,220,198,186,197,217,210,210,207,200,197,177,200,215,208,208,192,190,216,228,178,202,231,193,194,177,222,208,206,218,196,217,205,206,235,222,198,219,212,206,219,226,215,176,216,230,210,224,224,193,215,190,206,214,221,202,206,214,227,208,191,205,202,224,199,212,212,225,218,227,229,203,203,221,200,207,204,212,210,188,193,202,234,190,206,197,196,215,176,204,196,196,203,230,212,188,226,215,225,214,220,163,190,190,208,210,204,220,224,200,218,246,198,203,189,238,186,145,167,220,207,207,217,214,193,204,195,205,207,191,202,207,210,206,195,182,188,207,223,193,220,226,180,187,195,189,165,170,209,213,209,152,173,192,220,190,224,226,156,146,119,161,169,137,184,151,172,147,172,208,183,214,229,196,203,212,206,156,194,211,217,210,128,89,80,102,68,70,77,49,167,187,183,184,169,195,165,223,170,210,177,132,157,189,220,239,206,234,249,116,76,140,112,182,141,158,205,206,227,215,233,210,241,161,135,111,146,143,49,139,179,109,157,111,51,9,35,46,116,171,106,156,144,149,186,128,56,28,30,28,58,53,73,66,37,41,199,188,43,37,36,115,99,106,96,13,30,121,131,115,33,51,33,2,11,48,38,44,96,73,122,94,117,114,105,71,118,109,103,91,91,110,121,11,14,136,93,100,99,66,28,30,37,21,38,11,18,32,18,49,48,101,121,128,116,120,84,75,95,69,48,48,46,55,55,39,57,124,143,87,124,130,94,100,46,50,56,61,40,68,66,60,112,20,25,48,50,80,119,73,47,16,16,5,12,3,41,82,98,57,50,58,59,65,64,52,39,60,44,56,66,44,95,197,105,53,42,92,74,44,137,147,145,92,57,41,37,31,66,42,43,13,14,34,28,22,29,36,26,14,20,41,29,50,116,112,57,30,32,23,51,58,90,68,106,180,121,96,113,123,100,123,151,137,162,74,91,70,47,38,5,42,28,22,41,49,15,36,42,20,44,25,27,20,21,35,73,17,42,24,52,54,35,32,34,31,20,35,32,27,49,37,29,144,140,127,109,107,97,96,22,58,222,244,243,236,238,248,254,247,227,255,245,248,255,242,242,242,213,246,238,231,231,255,239,234,230,222,232,236,244,204,241,252,227,244,230,244,222,244,244,242,238,249,231,222,233,245,238,249,253,237,234,224,250,211,233,233,249,227,241,247,220,221,139,5,5,0,36,16,23,1,14,34,19,11,20,12,7,5,8,25,39,16,15,4,24,4,7,188,218,189,168,203,196,192,190,190,192,199,190,202,198,227,195,192,211,205,189,189,208,179,211,206,207,207,204,167,188,202,205,180,176,188,189,207,190,187,193,190,180,200,195,206,186,202,206,198,160,198,209,211,193,195,188,198,201,204,169,183,193,198,181,180,184,201,178,201,199,208,187,191,210,188,180,181,182,186,190,209,199,197,170,201,190,203,164,192,195,214,205,223,201,197,190,181,201,217,195,187,186,191,200,201,208,221,209,208,206,192,174,195,204,204,217,231,230,205,196,214,215,222,205,217,190,204,190,203,197,184,176,206,195,204,193,197,209,213,189,206,197,191,191,215,199,195,202,205,201,216,197,217,191,190,208,198,212,192,197,194,182,198,212,220,201,205,206,182,196,202,187,216,214,204,215,184,206,221,220,206,230,194,207,209,212,205,221,200,224,220,199,220,211,227,195,210,179,204,209,233,205,216,207,199,213,219,220,203,221,207,238,191,225,225,247,241,221,194,211,201,205,218,222,216,205,219,213,216,221,202,227,230,203,209,225,209,207,219,206,189,184,201,192,223,205,220,209,214,192,193,195,227,191,201,216,202,211,192,210,215,196,207,174,228,198,204,193,202,224,187,163,210,205,206,207,201,167,56,83,190,215,215,193,192,194,204,239,198,198,206,197,213,197,209,198,205,213,220,187,191,211,200,187,199,203,162,153,205,209,207,199,142,178,194,213,217,214,224,148,118,95,185,147,200,200,189,185,159,176,208,207,208,217,207,203,232,205,169,205,231,238,189,132,95,49,103,77,90,91,8,117,175,147,164,218,212,194,193,128,209,206,186,178,184,232,205,205,228,255,131,109,170,140,173,118,147,187,202,241,229,246,227,194,107,118,134,169,86,85,208,127,1,149,156,59,71,69,22,58,110,68,76,96,64,86,40,24,43,24,69,88,87,55,70,90,67,198,117,26,76,84,98,111,71,42,55,131,139,113,59,42,64,27,8,22,34,52,95,92,116,106,102,125,103,97,94,88,105,67,74,130,145,93,48,82,140,126,86,137,22,17,9,6,21,18,3,35,26,26,59,109,139,162,114,107,99,81,106,100,100,102,107,83,59,80,92,114,123,147,58,132,148,180,131,45,122,50,55,70,64,80,61,87,18,46,47,46,47,56,62,53,31,12,12,24,40,14,41,31,55,87,98,109,81,88,111,90,74,119,74,78,94,85,52,34,12,20,58,65,33,86,103,128,120,69,46,11,11,44,31,41,35,42,33,51,22,83,56,34,45,57,84,16,80,97,69,14,37,19,6,39,35,69,67,103,203,88,71,110,100,69,60,69,123,110,57,59,85,68,56,23,63,44,28,47,48,38,9,21,23,41,19,17,25,68,32,59,75,39,63,23,52,42,26,19,39,24,32,20,48,56,58,9,107,136,140,113,104,128,112,39,23,195,255,251,254,242,252,241,226,253,230,234,251,227,244,235,237,244,220,239,238,238,217,249,246,236,228,244,229,222,253,248,219,239,238,250,237,238,238,241,236,251,228,255,239,234,226,240,231,233,241,253,227,245,241,244,233,238,247,227,249,255,233,119,2,0,10,2,9,17,1,3,17,18,4,25,10,13,1,6,1,30,14,16,4,39,6,8,173,215,181,205,199,198,201,200,196,185,183,196,183,222,199,197,176,188,205,202,199,208,177,191,176,174,181,178,201,198,175,194,192,201,185,209,199,200,201,201,202,207,183,169,176,207,198,202,185,172,185,199,205,200,181,196,211,182,208,185,178,180,196,187,203,197,187,194,170,180,208,178,189,212,198,189,219,197,194,208,211,199,188,195,172,209,196,177,191,186,182,172,177,207,170,203,200,200,218,191,180,232,182,213,209,178,215,187,187,208,195,201,188,229,209,218,218,206,211,210,204,200,225,224,207,206,197,185,195,192,213,201,218,162,210,209,204,227,213,199,206,203,215,168,214,211,184,185,189,196,197,196,196,181,204,207,220,223,233,171,211,205,215,213,210,204,190,193,206,182,197,207,232,204,236,198,203,196,206,196,193,224,217,183,212,190,206,214,208,202,216,206,199,199,207,218,229,215,217,202,227,211,206,233,196,223,231,196,189,206,188,219,214,207,198,198,234,204,187,183,211,235,223,223,203,201,192,210,218,239,234,221,224,206,217,180,190,182,203,198,221,202,231,238,171,211,201,211,231,180,212,210,188,181,227,206,225,188,186,219,183,189,195,215,208,218,185,181,161,201,186,134,222,224,217,227,192,195,85,98,151,195,217,180,213,221,203,203,212,197,211,215,188,181,216,198,193,225,217,177,199,190,225,203,173,214,165,167,189,218,224,170,148,190,204,216,197,202,186,136,119,114,173,188,177,147,141,182,172,149,186,196,209,208,216,240,206,206,164,224,225,228,166,135,84,77,124,91,130,77,25,119,154,173,231,226,192,199,151,117,216,215,199,180,209,225,238,192,222,237,136,200,203,185,166,129,149,167,184,221,240,252,214,76,80,142,183,172,64,121,221,84,88,195,115,57,44,77,81,54,58,70,65,50,43,50,45,55,84,43,31,50,24,63,41,32,26,64,54,50,84,82,108,67,45,48,100,147,119,57,80,39,1,26,22,23,71,64,95,101,116,119,90,127,98,109,108,95,95,34,150,168,158,123,90,128,173,125,124,101,44,12,6,17,36,31,41,56,16,50,88,121,132,111,117,114,88,87,127,109,149,134,122,83,94,123,103,99,117,91,120,135,98,152,83,50,79,18,45,79,76,114,50,64,39,26,30,18,39,40,20,35,16,55,22,30,36,15,14,14,85,100,87,74,78,133,176,127,96,125,146,138,119,50,7,16,31,37,47,60,64,147,146,142,120,58,44,25,26,35,28,41,51,63,63,61,53,66,60,61,55,81,69,55,73,83,37,53,30,33,40,41,12,31,25,67,116,58,51,74,98,76,53,80,75,104,69,119,116,66,40,85,50,67,67,65,54,10,16,9,23,27,52,50,40,62,73,97,113,90,89,75,30,36,52,30,40,53,49,27,13,37,58,19,109,162,131,144,86,86,118,40,30,186,239,232,243,243,246,237,224,235,222,230,240,249,242,230,238,235,213,235,223,246,245,241,249,236,231,243,231,251,226,239,207,216,232,246,247,235,231,235,233,225,229,240,242,241,247,216,236,228,219,246,235,245,222,249,204,240,209,244,244,249,239,135,5,10,1,0,21,4,16,18,0,5,14,16,2,13,10,19,2,8,17,1,0,2,9,20,191,189,184,217,195,184,206,215,205,213,180,196,200,192,221,195,192,233,191,198,198,173,205,191,199,190,215,176,189,198,196,206,194,193,198,215,175,192,192,193,190,176,206,198,180,199,196,196,193,174,199,192,194,182,202,192,213,196,197,211,204,195,224,189,183,176,185,204,221,188,189,182,178,193,195,182,194,203,210,181,202,188,210,196,190,187,198,202,176,185,183,208,202,201,202,196,211,190,201,179,212,194,210,189,204,202,212,188,209,176,187,222,196,205,202,200,201,172,205,182,199,212,211,203,207,197,183,185,209,210,215,193,209,202,191,203,192,203,184,217,199,198,206,194,216,193,205,207,198,195,179,213,193,199,209,207,210,200,192,208,204,190,207,198,200,197,209,195,223,188,191,193,206,213,200,224,202,227,213,231,208,212,207,217,217,203,219,218,207,217,187,217,210,205,222,228,221,200,199,193,239,193,205,197,202,192,221,212,193,215,219,219,212,189,210,241,203,228,194,212,199,223,179,212,218,213,194,198,230,206,238,201,227,210,193,211,205,171,219,212,195,191,183,191,218,222,201,181,182,218,193,211,203,202,211,220,214,199,218,170,188,198,197,220,210,217,196,196,194,204,207,163,200,214,185,197,214,216,204,214,197,192,209,196,206,183,177,220,216,190,196,224,214,195,210,222,192,205,229,203,187,183,173,207,188,178,196,170,201,214,233,176,147,191,186,212,199,229,181,167,111,44,118,180,159,174,162,206,171,155,203,195,198,189,211,228,241,208,181,201,213,228,127,131,110,68,100,80,99,74,60,164,220,193,241,173,150,211,153,175,222,192,150,172,218,219,236,198,247,221,154,239,239,162,165,185,157,129,145,210,223,233,146,14,95,162,152,123,142,177,169,68,93,162,79,64,67,65,57,53,55,66,63,73,69,48,82,25,44,24,5,13,21,0,28,2,4,43,41,99,80,71,75,31,43,85,116,107,58,92,33,18,1,8,17,39,112,113,103,135,99,121,93,109,101,105,115,82,91,116,216,215,170,128,145,117,157,84,111,99,24,33,5,31,7,36,49,12,59,99,99,140,124,89,84,101,88,90,76,80,76,99,74,40,42,61,95,85,74,102,82,72,45,72,41,37,78,35,49,77,99,84,54,51,25,16,36,28,20,39,18,1,21,21,31,36,19,14,41,57,69,77,37,58,17,25,41,47,35,32,19,41,49,19,14,27,12,61,77,49,119,202,183,110,74,33,28,40,45,35,25,33,58,40,54,40,21,43,43,68,75,83,124,119,56,66,50,33,20,19,28,36,17,42,21,58,88,55,17,46,121,79,90,94,95,112,116,125,127,61,28,86,74,72,16,14,79,33,46,46,46,40,66,40,78,73,89,92,107,113,81,93,69,56,13,52,36,23,45,38,38,25,25,28,73,113,129,130,96,85,120,78,21,154,239,235,255,227,254,254,228,215,227,226,228,222,225,242,227,229,237,229,235,205,236,225,242,235,222,249,251,245,224,217,250,220,238,220,243,226,237,234,207,233,247,239,248,249,248,244,243,239,228,244,242,224,234,233,226,241,212,241,240,245,222,117,16,23,11,26,8,14,24,6,4,23,13,26,25,7,15,0,5,6,9,14,10,27,15,16,199,207,206,171,208,209,183,189,211,201,187,202,211,182,205,201,202,195,201,167,202,181,214,199,196,197,185,188,198,181,203,190,202,214,180,185,187,165,204,201,194,197,196,214,191,202,173,211,187,193,187,166,217,208,190,196,211,200,187,188,204,188,181,199,192,191,184,187,192,200,213,187,212,184,177,194,186,194,181,212,197,201,211,202,182,186,176,197,189,179,201,199,181,195,185,172,204,191,186,175,200,187,189,222,210,204,202,182,220,191,176,234,194,196,188,195,221,205,210,202,227,199,199,207,205,205,194,193,195,203,202,202,204,201,217,182,220,212,193,180,192,203,174,183,200,202,199,206,218,208,200,187,217,198,211,186,223,191,204,206,210,206,220,195,210,213,199,222,193,209,188,211,191,178,205,214,209,205,178,218,192,216,228,210,210,214,205,195,194,222,239,207,199,199,191,215,191,227,196,212,235,206,205,219,210,221,216,221,198,211,201,191,204,215,210,215,209,192,192,208,221,210,200,223,216,237,215,189,212,207,202,223,230,192,202,225,194,190,202,200,206,200,206,225,227,206,188,205,225,213,193,201,208,219,210,207,191,180,201,192,206,225,206,212,208,218,178,179,171,195,186,202,240,212,199,188,196,205,173,217,218,183,225,201,192,209,191,207,207,179,232,216,190,181,202,209,197,201,195,204,217,218,192,212,175,215,170,173,201,206,199,171,127,211,191,199,201,224,172,121,84,55,155,180,164,158,156,196,165,134,195,185,207,195,196,205,203,195,164,212,179,188,135,167,100,55,108,77,92,52,68,185,243,213,200,110,178,204,198,179,144,154,153,201,233,221,220,237,232,185,160,238,238,186,141,181,174,157,133,182,234,230,102,28,134,143,154,186,224,195,79,75,75,88,41,6,25,17,33,20,32,32,45,50,50,33,39,26,1,15,13,12,3,50,10,11,17,62,88,109,100,51,61,33,77,109,114,65,46,52,4,11,10,34,25,119,106,123,94,86,87,56,120,99,84,76,77,74,112,176,229,192,113,113,141,124,130,97,128,70,14,37,6,33,28,31,31,56,95,192,148,117,92,65,92,108,93,87,33,43,50,63,42,80,45,43,78,77,91,64,79,55,29,48,12,34,42,10,48,70,40,43,51,50,41,26,27,38,9,9,5,24,30,26,28,29,60,49,68,97,56,84,74,83,32,37,41,17,27,20,58,28,39,49,40,33,20,72,89,91,163,189,138,70,75,56,36,52,36,32,25,38,27,37,21,12,28,45,30,23,24,70,104,140,114,87,53,69,28,38,29,38,30,49,26,108,80,51,31,73,118,100,106,81,113,168,101,60,57,35,59,49,49,42,39,60,53,62,81,55,70,66,72,74,83,100,115,114,97,92,80,99,63,42,34,18,24,41,71,20,52,41,40,43,64,126,154,138,101,114,76,56,37,130,245,233,254,230,228,237,229,216,236,232,241,229,242,211,230,235,216,238,248,250,224,221,254,240,251,231,238,236,242,249,243,249,243,226,246,245,255,253,238,243,247,234,214,254,245,228,239,250,243,247,228,242,239,219,233,231,238,235,241,246,220,116,5,15,12,34,5,13,16,9,7,17,22,2,34,4,9,2,33,3,6,4,15,2,8,37,193,198,179,208,201,203,173,191,197,213,167,198,195,211,206,174,190,214,175,223,213,195,196,187,200,209,213,203,192,174,233,217,179,196,188,210,193,205,176,176,170,201,182,194,197,185,202,193,197,198,184,193,204,186,196,199,183,173,192,198,189,185,191,193,202,194,215,220,181,180,208,194,209,217,214,200,199,187,190,216,178,202,204,185,212,202,197,197,245,195,213,212,200,208,206,218,189,220,199,176,183,183,172,194,193,215,201,204,195,193,182,201,213,200,215,209,218,202,205,212,214,198,211,222,184,208,216,212,216,210,240,205,204,196,200,205,206,219,195,189,205,192,203,190,194,207,191,213,191,210,204,198,183,236,216,204,202,231,218,207,214,229,197,200,189,209,182,185,219,202,213,211,212,206,226,193,211,213,191,212,184,186,209,207,175,210,226,208,207,232,232,209,204,214,208,211,208,202,220,175,208,223,188,197,201,210,201,184,231,196,191,193,201,199,215,203,208,211,226,226,233,207,210,215,222,217,238,199,204,189,207,227,212,219,204,192,210,208,215,214,211,222,194,196,235,199,208,223,213,190,199,207,205,223,189,207,219,203,223,197,179,207,190,214,217,208,199,206,186,186,222,212,201,227,215,195,186,202,181,194,213,167,200,197,226,211,209,208,217,202,209,206,215,218,187,208,206,188,216,212,189,207,181,200,190,197,188,170,210,210,206,143,166,225,215,205,199,215,170,119,103,118,190,205,173,164,190,200,150,128,186,173,202,240,189,190,216,195,186,212,225,199,159,189,118,77,80,74,69,17,59,184,169,170,213,163,207,246,176,172,145,171,188,216,224,223,224,237,226,118,170,233,238,184,159,160,200,165,138,191,208,215,87,101,143,123,154,200,244,146,44,49,77,72,19,35,23,25,28,21,20,25,33,16,16,1,13,6,20,5,12,12,12,11,14,20,32,48,85,106,101,35,51,75,98,111,63,53,23,14,5,12,23,54,52,103,106,116,108,123,91,94,116,107,86,110,90,89,162,197,210,125,71,115,106,98,138,97,109,75,33,21,19,11,26,20,22,51,156,205,159,72,120,40,30,39,66,45,34,52,18,56,43,31,47,53,56,44,61,87,67,53,41,57,33,30,5,53,46,81,65,38,64,66,62,78,79,37,24,25,19,0,38,69,87,74,83,113,121,106,69,88,85,46,46,31,14,40,32,44,49,58,80,72,93,105,140,129,162,141,121,142,113,146,113,81,96,92,101,79,75,81,48,45,16,14,17,7,26,17,64,76,80,104,78,119,94,54,67,30,49,38,37,10,73,131,84,52,13,94,133,98,94,80,126,139,60,22,83,57,2,33,69,10,41,33,64,62,80,65,60,88,60,86,102,89,78,121,92,79,65,80,82,82,69,22,45,29,23,20,19,35,38,17,71,143,141,117,97,82,119,56,17,159,239,254,246,229,232,212,232,224,241,241,234,209,236,239,231,238,238,231,244,207,242,229,249,218,236,244,229,249,245,255,231,232,245,237,246,225,222,237,226,243,248,235,231,250,223,239,241,243,239,213,234,245,242,223,241,240,248,233,237,250,241,110,11,8,0,23,18,1,27,9,27,20,12,9,16,5,1,12,19,13,15,22,18,29,28,35,208,207,218,217,204,188,188,197,175,213,180,183,203,199,195,194,206,215,191,206,194,201,200,176,172,189,189,199,180,192,199,188,187,169,197,192,203,182,196,213,176,204,203,195,205,184,207,195,190,190,192,207,197,189,193,179,181,214,192,198,164,213,184,226,179,190,221,214,202,195,205,208,203,196,184,193,204,197,183,210,176,174,182,187,186,192,174,163,192,160,160,206,225,197,182,199,198,187,208,186,185,211,185,222,191,202,198,209,197,197,214,193,184,167,196,215,185,193,217,204,208,190,193,199,205,204,209,196,195,199,218,203,191,194,171,216,219,181,184,200,213,196,199,193,185,178,232,182,180,224,193,219,195,197,206,197,217,179,201,194,190,204,207,196,199,207,217,222,205,204,201,206,191,193,189,198,221,183,202,208,197,206,192,209,218,206,198,233,192,208,206,216,206,202,225,226,212,237,222,213,202,188,217,233,202,222,224,213,216,224,234,209,186,212,214,222,244,217,199,201,212,207,207,210,199,198,215,193,214,205,194,227,215,200,208,211,209,227,207,215,198,232,202,230,210,198,197,188,202,168,198,196,223,224,182,201,194,215,195,204,210,224,201,214,222,199,200,206,210,205,210,199,183,198,214,182,199,211,182,204,198,194,187,200,194,196,211,188,216,212,203,194,195,187,215,184,207,204,179,193,192,219,210,219,210,189,138,157,205,196,189,164,167,191,215,229,197,216,155,120,95,109,171,170,135,174,197,238,159,108,183,226,173,215,204,197,207,164,167,205,184,212,157,172,117,71,103,104,84,60,68,64,153,236,193,176,199,181,169,163,190,197,199,218,223,247,227,232,214,86,169,244,245,210,169,181,180,116,126,190,225,220,159,106,157,173,176,227,226,93,33,69,33,30,5,21,13,32,23,22,39,23,12,16,9,24,11,19,16,4,19,28,46,22,34,5,87,81,84,89,56,49,68,102,66,77,61,57,27,38,24,44,54,87,101,142,126,94,90,96,89,130,75,99,84,78,120,181,202,136,154,114,71,105,72,92,118,79,107,62,24,38,26,14,28,48,23,70,156,166,99,85,50,50,42,28,29,44,66,46,37,49,41,16,35,21,61,56,53,52,77,42,43,51,56,58,38,38,50,52,56,69,66,58,73,77,73,60,48,33,37,27,76,87,103,75,96,80,77,47,23,43,34,49,45,34,56,54,100,118,151,190,213,197,220,173,197,168,148,142,67,54,63,76,103,116,119,131,140,120,134,141,134,131,98,87,69,31,53,25,45,47,66,75,38,42,67,48,53,82,63,54,68,55,97,115,73,50,66,156,111,112,108,63,95,102,52,45,64,33,54,43,33,67,78,47,25,42,59,58,95,121,96,22,36,79,63,73,51,64,69,95,85,43,48,76,32,18,39,33,38,31,42,39,53,154,145,134,124,86,103,86,69,150,247,222,234,252,234,251,248,255,242,250,220,223,238,242,238,207,225,228,223,230,247,243,243,248,236,245,252,238,239,243,251,205,250,238,248,222,247,246,249,223,237,251,250,251,236,236,218,234,251,243,237,247,242,226,238,224,236,241,234,249,226,106,12,21,16,5,2,5,3,23,14,15,18,32,20,3,10,12,15,19,15,4,3,7,10,27,200,186,199,194,211,197,188,207,203,203,212,171,193,170,206,207,199,186,192,191,211,216,170,192,187,188,181,193,192,181,189,180,212,174,202,196,215,204,198,186,184,204,207,200,186,210,210,205,217,188,214,196,193,187,196,200,210,166,194,188,183,181,198,196,194,188,215,193,193,193,208,181,203,179,189,210,181,183,205,212,201,207,202,204,213,189,201,201,200,197,212,200,211,218,226,195,183,202,201,181,220,192,171,204,182,188,198,231,179,191,188,195,209,198,191,213,196,201,202,173,206,218,217,196,197,210,210,208,205,199,203,195,193,232,188,197,197,187,205,214,188,221,197,186,201,212,186,212,196,197,196,210,186,214,193,197,172,177,176,220,191,205,221,195,201,207,192,197,207,197,193,202,178,192,229,199,193,213,208,195,201,201,197,209,204,213,199,211,205,210,212,197,203,197,227,219,199,209,214,211,200,205,205,210,227,210,201,202,191,180,201,191,200,187,219,178,199,218,224,214,215,228,211,214,214,192,193,185,230,219,221,199,219,211,222,211,201,204,203,202,195,218,216,186,197,182,206,207,193,208,184,192,218,210,207,174,175,172,204,196,186,200,185,204,225,221,213,224,190,181,224,177,196,200,205,189,204,208,202,191,200,202,185,189,240,213,181,217,195,189,210,205,205,175,165,185,210,207,207,200,186,193,205,214,212,199,164,176,212,232,199,148,171,209,198,212,207,198,169,95,98,83,154,151,176,205,217,237,205,115,181,192,180,223,212,193,191,178,170,190,165,197,138,87,80,63,137,116,84,88,70,137,207,227,207,181,131,184,189,153,198,181,218,215,201,237,213,238,194,100,184,225,229,225,202,168,118,152,163,189,225,239,197,146,183,244,192,221,189,39,59,49,4,30,22,31,10,32,27,11,30,13,8,18,39,39,19,44,22,18,15,10,14,3,27,45,85,90,51,47,53,64,124,101,67,83,38,32,11,91,69,52,66,96,115,143,118,125,91,108,82,72,107,57,98,93,161,190,119,72,92,62,101,108,89,89,142,121,108,54,10,16,26,46,46,29,21,87,153,135,81,70,40,49,46,49,52,27,53,57,40,55,50,28,54,47,44,42,52,50,63,50,75,41,38,41,16,52,37,27,40,58,51,66,69,56,66,47,80,57,66,102,121,93,62,54,50,79,84,35,25,25,10,42,49,79,122,204,205,221,223,214,155,140,133,53,68,60,74,83,54,23,16,21,56,44,80,91,39,36,51,59,75,110,122,180,153,120,120,100,46,50,31,38,32,39,38,3,33,55,78,55,79,59,68,87,69,118,93,154,104,103,97,37,72,112,33,13,22,23,48,26,35,59,58,57,47,78,64,58,56,90,43,53,28,28,60,73,52,51,45,55,79,54,72,42,43,45,48,44,36,2,28,23,55,139,160,125,121,74,97,89,41,167,204,220,250,254,252,253,219,215,214,227,218,230,243,220,206,221,216,243,228,255,242,254,248,252,236,249,253,219,251,240,242,251,229,244,248,253,236,234,238,205,244,233,243,252,237,253,241,222,255,255,236,214,250,234,222,246,227,224,244,231,231,122,29,6,38,6,12,7,30,7,11,30,8,6,1,1,0,18,8,6,29,1,8,53,23,25,204,194,189,235,188,207,213,196,197,208,175,188,172,182,206,175,194,188,196,210,179,216,200,202,182,190,191,220,209,196,183,218,198,198,207,216,216,185,213,176,188,185,203,199,180,203,177,213,188,198,204,198,189,227,193,186,222,168,188,190,187,189,179,185,208,195,200,208,190,190,180,189,202,191,199,189,162,173,203,195,204,188,188,187,184,203,211,208,223,178,200,178,193,193,194,206,204,178,197,183,212,214,199,214,189,185,188,210,208,190,197,200,204,191,215,182,203,189,177,177,189,191,196,198,204,201,216,206,214,194,191,197,212,209,191,169,209,183,227,214,194,201,196,182,189,227,190,178,194,226,218,192,206,196,175,196,212,173,223,184,226,220,199,219,210,197,200,217,202,194,178,200,192,206,202,206,204,199,199,216,234,229,197,213,217,196,197,215,221,209,193,202,211,196,209,217,204,229,213,235,218,229,194,213,201,205,225,199,208,213,212,232,203,207,178,188,211,215,229,193,193,221,230,193,206,195,217,198,195,193,221,203,205,186,209,190,181,219,197,214,193,194,222,192,208,208,219,233,204,210,209,218,202,218,201,196,203,204,204,183,235,203,200,217,200,187,179,228,182,208,212,210,179,213,200,204,193,207,188,228,223,202,199,181,217,179,214,194,202,184,205,186,231,202,211,194,216,198,194,180,211,187,198,208,223,160,161,183,204,212,182,161,175,192,203,226,192,179,134,93,96,77,136,168,192,198,230,214,165,102,158,203,215,185,195,234,233,182,217,178,161,170,120,99,67,58,115,81,73,72,68,154,243,212,177,159,132,210,176,115,173,162,201,220,230,220,212,242,190,88,210,237,236,251,212,146,133,152,161,178,175,204,183,165,197,233,198,214,170,59,71,41,9,29,35,18,28,39,10,25,9,19,22,28,8,10,20,37,33,2,23,7,56,40,26,43,104,65,23,36,49,88,70,71,78,49,20,37,74,139,177,141,121,129,104,113,79,96,106,118,93,98,95,115,105,88,105,114,72,61,90,107,98,114,98,99,91,139,86,45,28,26,36,52,21,34,2,23,116,69,59,50,48,33,57,21,50,59,62,52,50,35,29,20,19,63,25,37,70,21,38,26,14,28,38,22,26,43,67,62,51,67,62,48,67,50,47,63,59,78,73,104,74,49,38,28,21,52,38,43,25,31,53,128,159,195,162,165,156,94,75,24,46,66,48,77,19,76,68,52,55,66,54,44,66,58,39,56,59,33,49,48,36,30,51,75,85,128,154,130,119,104,75,69,29,46,16,23,22,8,34,55,35,82,68,63,93,95,102,125,99,101,63,52,85,68,61,71,54,27,49,63,85,56,50,60,61,58,27,36,42,46,31,30,16,61,33,33,57,50,52,28,44,60,61,91,45,84,45,35,41,50,26,29,72,147,133,149,89,99,116,111,72,84,119,185,245,244,252,217,234,235,224,224,232,228,228,224,218,236,224,232,236,249,235,240,245,240,220,246,233,255,246,252,227,221,244,242,228,251,255,227,248,244,220,242,249,228,240,217,241,253,224,243,246,230,220,243,239,239,218,241,232,231,241,117,6,29,5,8,10,1,14,25,2,26,35,16,17,3,14,0,20,3,9,15,36,8,6,11,210,189,173,187,191,181,185,213,202,186,178,202,193,192,182,192,183,195,210,212,186,194,190,190,184,209,190,174,192,191,186,197,175,195,211,197,188,203,195,205,211,209,207,213,197,202,215,220,191,181,177,195,174,178,189,219,192,203,214,183,188,182,188,186,192,194,205,198,179,184,183,190,174,190,211,205,186,175,196,204,184,190,210,193,198,197,187,193,178,222,212,190,210,187,211,207,202,185,194,213,198,202,201,207,195,204,214,214,208,208,196,207,203,198,184,195,202,203,199,195,206,194,170,208,216,181,197,206,179,204,214,229,190,184,185,176,169,195,194,219,188,203,207,196,217,222,196,206,186,200,204,199,190,202,210,216,210,191,199,206,211,194,191,174,208,204,193,196,195,205,211,184,212,203,207,191,188,205,211,188,190,213,239,197,215,215,217,222,212,207,184,231,217,188,192,193,211,198,205,176,213,208,203,238,187,226,212,211,226,229,209,218,198,230,208,210,212,207,193,208,207,210,195,190,215,199,213,221,208,226,221,192,198,190,172,222,198,229,203,217,196,218,214,168,180,196,218,211,215,180,194,196,222,210,197,209,197,202,208,184,213,208,218,176,199,210,210,195,182,188,194,205,189,216,217,217,209,204,196,223,208,215,191,201,189,226,199,169,200,190,185,196,216,220,203,172,198,196,216,200,194,198,221,215,213,144,179,187,193,215,205,152,208,208,215,216,212,182,138,105,83,96,180,167,191,220,217,206,154,107,137,225,239,190,210,179,210,178,160,206,188,206,160,162,113,60,108,80,90,92,53,190,240,147,154,149,167,243,147,145,150,181,242,216,233,227,212,215,141,124,240,213,252,239,205,171,189,179,204,187,160,178,167,159,197,193,209,191,157,87,73,7,17,8,17,25,16,12,19,16,15,19,4,16,5,14,18,25,36,29,17,21,7,11,76,82,71,60,33,61,85,104,70,60,32,44,1,43,145,203,216,108,76,85,113,115,122,90,115,84,98,93,99,88,108,90,72,72,83,128,135,80,88,84,77,134,93,163,90,21,30,15,43,46,20,22,26,56,35,65,52,23,20,49,51,59,47,75,56,50,26,13,67,48,35,64,49,60,37,50,36,25,7,28,43,32,43,49,62,29,42,53,68,59,64,51,56,68,67,64,71,58,26,42,42,8,26,32,24,53,93,129,213,211,158,143,70,41,49,49,32,57,35,53,56,55,53,51,40,34,66,60,59,53,50,57,44,67,42,71,38,14,39,26,62,60,59,53,47,81,100,128,146,75,91,50,56,31,43,8,7,17,52,80,64,68,57,69,90,74,68,56,49,41,63,63,53,31,35,36,68,68,58,66,52,47,46,57,39,21,46,45,23,47,24,53,63,57,59,55,35,46,62,56,71,69,42,33,70,11,25,39,59,35,30,107,140,129,99,84,107,91,77,149,68,100,185,218,223,243,233,241,245,228,235,230,229,234,218,244,219,254,247,237,246,236,227,232,237,240,231,228,241,231,238,248,249,241,231,231,222,238,242,230,223,254,233,250,246,240,211,239,249,247,228,227,246,228,227,215,224,234,231,251,224,91,19,0,12,21,10,14,19,6,7,13,22,2,24,1,12,2,3,9,1,22,14,1,30,29,198,189,194,215,215,175,204,197,182,208,197,192,209,207,205,186,197,217,214,215,186,209,216,189,204,215,178,188,166,192,200,196,197,189,195,212,197,184,190,202,188,185,190,190,207,157,189,206,189,185,190,199,215,195,201,202,202,195,208,202,205,207,219,187,193,175,185,174,210,207,206,165,206,201,187,183,189,183,212,193,188,197,225,205,192,204,181,172,204,205,194,194,181,194,212,227,171,230,197,176,181,194,234,199,217,181,206,195,227,221,189,191,166,211,178,213,193,207,190,218,209,196,196,197,213,174,231,194,206,212,198,187,179,199,177,188,185,209,218,199,237,203,206,197,203,191,223,203,221,177,209,186,216,198,200,208,220,194,198,202,188,207,195,180,205,211,215,195,210,213,220,189,213,207,216,203,209,229,212,225,213,217,195,211,175,192,198,218,203,198,222,230,219,194,238,196,195,190,190,208,216,214,206,216,215,206,209,196,209,209,197,250,215,228,201,204,179,221,203,188,207,199,202,182,207,221,207,204,195,179,204,203,203,211,220,196,210,218,206,207,191,207,196,203,189,205,208,216,204,195,187,190,196,191,172,197,199,207,199,209,207,209,198,219,193,196,219,201,188,212,209,210,197,194,208,187,198,220,196,188,197,206,191,173,200,208,195,205,189,205,206,180,193,215,208,205,197,211,203,188,221,217,176,191,214,144,158,179,212,221,160,160,193,201,209,207,195,189,133,117,71,66,141,169,188,180,227,223,160,167,175,206,203,224,201,188,194,152,176,174,184,212,201,181,119,150,171,99,80,56,31,147,205,190,226,166,193,207,148,199,195,240,228,201,232,215,233,209,151,169,214,213,236,229,242,198,172,197,185,171,183,192,184,166,209,238,162,140,87,32,24,9,6,27,14,15,8,3,57,38,25,32,14,14,6,37,10,34,27,24,16,18,21,47,60,76,53,55,62,84,104,64,56,71,44,11,33,44,142,140,173,75,46,105,90,95,102,114,121,108,88,116,102,78,128,91,72,125,195,152,125,102,111,121,104,99,127,120,86,40,31,35,6,25,5,25,10,28,26,27,41,52,51,47,103,44,70,65,25,37,20,49,79,65,66,68,66,34,27,51,29,22,27,62,46,34,44,45,30,22,34,66,39,38,44,39,27,46,56,55,49,28,43,14,17,35,44,57,64,165,216,208,142,115,47,61,30,38,44,32,44,33,54,36,41,26,17,20,8,40,44,79,71,28,63,70,22,43,65,47,52,27,37,26,37,38,47,52,74,49,96,57,82,97,109,89,83,61,28,24,10,28,19,29,45,52,61,57,30,50,55,61,58,55,26,42,48,29,28,47,46,30,52,55,58,77,36,29,55,47,43,28,40,51,47,47,32,63,37,55,27,49,45,36,36,37,47,44,48,29,24,39,29,30,35,110,169,123,103,108,118,82,107,111,107,50,85,116,132,177,195,216,228,243,249,224,244,229,212,203,255,240,240,237,236,248,249,230,251,227,233,243,239,241,250,239,230,250,238,245,233,240,229,229,225,246,225,236,245,222,235,230,252,215,230,225,227,230,237,214,215,230,237,219,224,128,12,0,1,31,7,4,12,7,6,15,7,27,15,13,4,8,9,9,22,3,3,5,12,22,178,191,198,205,199,202,191,172,175,170,198,177,192,208,188,224,180,218,174,195,193,189,194,174,184,181,204,210,195,175,195,194,179,205,215,193,207,197,188,184,207,187,189,208,197,178,187,188,203,190,185,194,201,184,181,199,183,174,193,190,216,191,187,195,203,181,177,210,198,196,219,157,187,195,212,187,199,190,210,192,176,200,195,199,189,191,191,211,202,187,179,197,197,197,180,205,183,213,197,185,195,200,203,206,187,177,193,191,212,216,183,192,192,225,192,217,204,210,185,225,209,217,182,206,212,193,207,208,223,208,195,203,231,218,225,191,214,197,195,198,200,206,212,203,196,218,202,207,197,215,214,181,194,181,209,199,201,207,204,195,215,200,199,185,193,223,216,209,195,198,201,215,188,215,180,210,211,195,192,204,168,207,203,212,227,193,221,213,183,215,196,203,183,208,230,200,221,193,214,224,224,186,206,208,202,219,188,198,206,196,223,206,216,211,205,205,207,210,197,203,199,204,187,217,201,212,196,204,182,199,208,193,231,215,223,210,196,200,178,195,202,223,183,199,216,195,202,186,198,208,217,186,201,204,177,186,188,196,191,199,210,202,199,209,216,204,199,186,206,194,193,223,180,205,197,195,223,188,186,193,211,199,189,186,203,201,211,207,201,198,235,199,184,193,206,205,194,190,202,193,207,206,209,179,214,171,174,214,196,197,159,180,197,215,216,205,187,188,87,125,95,71,160,187,225,217,218,204,173,163,126,197,239,218,219,196,220,177,157,168,240,219,178,126,100,145,164,103,102,71,26,130,198,207,236,156,207,210,156,190,191,209,222,209,222,184,254,188,154,185,202,225,205,239,222,207,217,158,159,153,167,175,164,204,208,232,177,75,46,5,0,11,8,26,22,17,15,56,19,27,18,31,16,29,5,14,13,2,9,27,11,13,39,28,93,56,58,59,80,98,61,51,41,33,35,21,46,99,69,47,107,63,80,125,108,127,149,102,107,95,91,93,79,92,85,65,86,150,181,126,128,105,105,97,89,101,117,134,55,3,13,7,13,38,11,26,15,39,21,43,53,98,58,91,64,58,41,32,28,33,59,117,107,102,82,88,88,29,32,24,41,41,14,30,15,31,15,11,29,12,54,39,48,34,26,24,31,51,35,36,36,29,16,26,17,50,97,215,234,192,132,55,48,43,93,50,47,27,35,4,17,5,12,14,2,22,5,28,22,47,61,45,79,75,103,78,95,47,66,38,40,25,35,16,22,36,26,40,48,55,55,58,107,71,49,69,116,106,129,71,53,32,30,19,26,33,48,43,19,23,34,39,58,29,24,37,31,28,29,39,40,34,58,38,76,40,39,76,45,27,21,31,31,39,51,35,30,64,70,40,51,39,36,59,54,56,28,46,43,54,37,48,53,25,33,100,163,140,116,112,109,75,89,117,112,83,85,56,84,169,214,220,230,231,212,213,219,238,237,235,245,240,223,244,237,215,235,245,232,224,237,241,222,233,237,218,235,227,251,239,251,253,214,227,222,223,234,212,247,235,223,237,211,241,222,235,240,212,241,215,237,221,217,232,222,121,20,11,0,21,4,5,23,16,25,12,6,10,15,7,23,11,5,13,15,25,33,12,28,3,180,177,188,224,196,211,188,214,217,207,193,196,213,196,206,216,220,213,181,176,203,228,202,178,203,193,190,230,209,202,183,198,197,186,215,179,186,178,180,195,204,190,198,189,172,186,184,184,185,196,174,181,189,197,204,198,196,203,173,190,207,198,198,186,181,194,210,179,216,189,179,165,201,180,190,189,194,200,220,208,210,211,208,190,199,187,171,201,200,198,205,197,217,207,214,179,201,222,189,196,194,206,197,219,200,214,223,216,194,208,194,185,187,237,175,211,210,201,199,216,181,225,171,196,214,200,213,198,190,202,217,193,191,209,206,180,201,193,202,208,217,183,188,205,200,186,199,202,207,200,217,213,191,171,187,221,201,204,222,200,226,197,194,204,213,207,212,210,196,188,197,221,189,179,198,212,216,197,206,194,219,205,201,207,202,202,203,207,208,192,221,208,212,205,227,198,213,208,223,200,201,199,224,201,202,213,209,210,198,201,198,215,207,199,220,206,225,203,197,227,207,211,219,199,223,198,159,212,192,188,200,224,202,202,196,200,207,215,206,204,195,222,190,211,199,190,204,187,192,207,193,190,196,195,223,198,206,200,217,191,211,203,200,200,194,205,175,197,214,179,182,206,192,181,200,214,204,193,215,193,200,210,215,187,180,213,194,193,156,185,220,183,240,192,192,191,229,216,204,209,190,197,216,189,209,148,192,205,220,198,156,193,181,190,195,188,139,132,103,128,118,88,147,194,237,172,242,194,162,146,133,191,191,220,218,190,230,181,150,211,226,136,103,126,96,93,142,134,130,76,42,132,212,219,168,158,225,214,120,135,173,221,216,209,199,226,234,157,140,199,178,243,222,221,240,209,221,136,122,108,168,193,185,148,143,169,155,42,27,14,15,5,13,10,21,17,22,39,22,7,18,25,10,8,8,18,36,29,29,13,39,50,53,52,67,54,79,113,76,61,55,48,29,25,20,1,75,119,42,60,99,100,138,145,153,134,128,88,111,99,99,111,114,102,127,118,135,143,127,106,101,89,98,83,79,117,114,105,43,15,37,3,21,22,5,40,27,36,10,38,115,106,78,72,72,53,46,46,70,88,105,135,135,104,48,49,44,26,34,14,45,64,34,27,22,19,9,4,16,24,15,43,33,18,21,55,50,39,48,38,40,49,83,53,118,198,238,197,111,65,40,57,41,31,39,14,29,5,5,5,3,9,21,24,8,35,11,15,28,26,57,42,92,95,120,76,62,55,29,8,6,14,4,18,30,22,13,14,39,39,51,39,74,77,77,108,58,73,92,135,95,65,44,34,40,53,26,42,30,34,27,55,53,26,24,18,33,15,8,43,41,45,49,67,49,56,64,55,55,83,105,79,105,61,36,40,37,37,4,38,80,35,29,30,36,40,21,74,26,38,32,77,36,41,18,76,153,132,126,130,84,91,103,114,118,97,84,197,214,243,255,239,209,236,227,227,202,236,229,245,226,246,241,251,232,239,242,247,250,231,231,232,226,225,224,221,221,238,231,241,249,242,233,238,250,238,209,231,220,207,253,223,225,222,216,238,208,238,208,206,224,218,242,214,219,124,20,10,5,0,10,6,22,0,25,17,17,21,13,15,22,5,22,0,10,25,11,12,11,28,185,211,188,211,199,197,211,202,200,185,187,182,187,202,200,217,182,183,200,194,201,188,178,200,188,178,175,207,186,180,206,189,201,171,194,192,185,191,200,208,202,204,185,203,174,175,192,211,195,206,194,187,197,193,180,183,191,171,205,181,161,168,182,206,187,177,201,202,219,190,164,200,201,189,192,207,210,167,220,195,184,200,194,176,190,188,191,194,190,200,209,217,190,201,208,202,212,187,205,221,205,175,184,194,201,190,213,193,175,189,177,195,191,185,209,208,196,200,212,197,202,194,191,199,196,184,194,219,192,207,196,194,200,193,212,188,199,200,181,167,199,203,205,222,195,208,205,185,188,206,183,190,207,198,197,215,232,203,208,205,220,210,190,217,216,224,213,212,207,207,178,220,205,182,213,187,215,208,219,246,205,185,223,213,213,239,213,207,207,200,226,225,226,193,226,191,211,209,189,211,201,182,196,207,196,189,222,213,216,215,194,201,196,228,179,228,209,213,201,226,214,218,186,209,220,212,210,205,191,182,217,203,212,199,223,205,206,200,209,205,215,199,189,192,183,204,209,224,194,196,207,206,221,189,204,182,204,212,221,201,198,189,197,217,177,176,218,202,202,197,198,177,187,187,202,197,209,197,207,186,224,210,202,187,202,195,205,199,206,204,172,192,207,198,209,217,193,217,216,208,212,212,182,227,197,118,167,211,204,187,151,194,178,232,196,184,168,156,136,144,131,96,188,242,227,210,237,199,168,167,142,195,212,203,192,187,212,200,161,192,172,123,138,124,80,125,129,110,159,108,71,131,207,193,177,189,237,128,83,156,202,224,190,202,218,230,237,141,186,189,224,227,209,206,192,225,224,179,112,136,196,169,121,100,43,62,64,28,24,32,15,19,38,17,22,42,23,21,10,29,24,26,7,11,18,6,36,21,13,25,17,23,51,83,64,81,127,116,76,60,53,32,28,9,12,27,114,104,21,77,108,99,101,108,111,94,74,73,98,134,116,98,85,100,176,185,148,101,98,98,114,111,95,98,83,120,167,112,23,5,11,22,22,27,44,52,47,31,16,33,81,112,85,52,61,51,56,46,60,76,93,65,35,63,44,43,4,19,43,17,53,22,20,54,32,38,20,42,33,74,68,58,71,84,94,120,163,162,154,198,203,161,151,168,175,208,130,121,30,54,56,46,11,18,28,20,18,11,10,17,6,1,19,14,15,18,26,43,10,42,39,61,103,59,93,51,50,28,17,20,21,23,2,13,8,12,6,18,27,28,9,28,21,53,52,44,69,62,63,76,140,117,65,79,75,59,96,31,69,54,53,38,27,68,37,41,10,7,15,26,26,35,48,79,51,44,29,45,86,123,177,135,112,99,49,102,30,25,29,42,38,61,30,34,45,49,44,40,17,7,29,32,63,40,75,68,165,156,148,118,105,76,93,116,105,109,132,240,240,255,249,208,233,219,224,243,233,240,224,245,233,233,201,221,241,225,241,225,239,227,221,231,241,222,223,219,217,225,226,215,214,230,238,227,232,232,247,240,216,230,226,220,214,200,217,234,226,223,221,225,244,243,233,217,211,100,12,2,0,4,3,29,12,0,6,28,10,17,0,6,12,11,11,44,19,13,24,3,10,9,195,215,195,194,207,191,198,201,199,201,214,182,173,210,205,185,199,190,184,194,187,201,219,195,202,184,196,185,173,174,206,201,185,208,186,212,161,185,192,209,186,203,191,183,225,182,220,202,174,185,175,198,200,200,232,199,168,186,211,188,180,192,169,208,182,160,191,175,202,198,217,229,187,175,193,171,180,227,179,192,191,202,195,202,208,198,181,173,190,203,210,181,199,194,201,219,208,211,206,205,201,189,202,182,194,201,180,217,230,201,210,193,187,205,216,206,213,194,215,211,226,211,209,219,197,220,198,229,219,204,191,209,187,195,207,190,213,198,214,211,220,193,174,196,227,198,231,179,171,183,200,210,211,191,197,206,205,205,217,207,213,191,220,186,204,197,202,208,218,188,187,199,215,218,210,205,223,224,215,202,198,204,209,231,230,198,214,220,208,207,209,181,205,228,209,230,197,211,208,206,217,201,221,212,214,215,202,199,196,206,185,212,213,201,219,205,188,219,192,219,199,189,210,210,181,191,203,189,219,208,210,210,226,204,194,188,197,221,197,204,171,204,194,211,188,192,195,187,203,200,201,202,194,215,174,190,196,226,166,178,169,180,228,174,205,193,209,181,201,199,180,214,198,173,178,196,189,188,187,169,171,171,201,190,201,184,209,220,199,195,211,204,205,198,197,218,213,213,201,197,183,188,195,204,167,141,208,197,194,195,163,158,179,208,217,198,164,143,130,139,112,118,233,223,237,210,237,186,186,190,153,186,197,200,221,232,231,177,164,203,239,160,149,165,104,80,98,121,123,73,43,128,181,215,183,221,178,98,103,199,223,227,203,222,238,226,186,140,206,163,223,208,218,219,241,239,226,189,180,161,218,194,81,48,55,19,30,11,20,3,37,23,32,2,21,22,21,27,21,35,39,17,20,14,8,12,21,20,22,19,41,36,60,57,81,78,89,69,79,41,10,33,19,20,26,61,114,70,55,121,113,43,42,34,34,23,36,42,74,102,138,102,73,86,148,163,90,88,80,67,59,91,74,77,99,126,111,90,23,29,3,25,20,51,31,37,22,15,30,10,52,36,15,22,8,39,32,33,47,42,37,54,43,59,53,81,41,54,59,59,74,89,95,146,154,161,193,171,192,224,193,154,167,194,172,197,198,167,168,176,126,123,114,77,63,56,39,40,40,49,21,34,7,14,7,22,2,11,20,2,31,14,33,37,21,31,10,34,13,48,43,75,32,20,62,53,37,23,12,14,22,27,7,15,41,30,18,31,2,28,14,6,21,18,12,35,46,55,93,94,63,117,128,142,145,143,156,136,120,145,113,126,90,76,82,59,50,29,27,27,41,30,22,32,53,23,41,25,62,69,105,116,102,62,59,110,66,67,69,67,45,75,41,34,45,18,9,42,14,8,24,37,42,33,40,66,122,154,103,123,100,94,92,116,103,85,115,142,215,239,223,246,244,225,209,207,242,216,227,226,235,236,250,255,225,250,239,227,229,231,238,245,242,226,244,212,239,254,229,204,221,230,224,216,227,215,226,229,242,216,225,243,223,231,233,209,235,227,221,229,239,232,234,231,220,125,13,29,15,0,24,15,7,21,19,5,22,14,12,7,5,2,8,28,16,15,8,15,3,25,180,209,191,183,223,189,182,213,199,185,202,178,201,200,182,196,193,218,192,197,210,217,191,193,197,171,182,172,200,189,190,199,202,182,184,204,164,217,197,198,216,192,194,216,189,190,181,194,192,174,208,181,221,170,204,187,199,201,189,177,206,198,207,201,199,205,181,165,187,207,218,188,189,186,187,178,181,192,198,182,192,207,176,181,186,213,190,192,195,206,199,177,188,178,200,199,202,223,193,205,199,191,203,208,189,203,222,201,206,201,208,206,219,218,199,193,182,220,199,214,189,198,199,201,195,200,214,196,197,200,192,219,207,213,214,209,215,209,178,208,229,201,185,224,198,196,209,202,183,223,194,182,209,207,207,203,198,186,203,208,193,197,182,205,228,189,203,221,194,211,199,205,187,217,203,227,196,198,208,203,205,219,194,216,191,220,206,214,222,230,207,203,205,229,210,227,217,197,202,225,195,211,211,197,195,223,204,214,215,215,202,207,197,197,202,217,191,211,210,203,201,199,210,202,208,221,209,231,202,203,219,210,222,178,211,190,201,207,224,188,200,191,216,200,208,202,192,197,215,183,216,170,188,199,211,178,176,209,189,200,196,198,206,199,201,181,205,201,203,182,170,172,203,212,194,183,192,212,178,180,191,209,206,193,180,161,217,202,206,219,176,202,177,222,203,207,204,193,170,172,187,217,178,220,195,162,207,191,201,178,148,171,169,181,181,160,122,107,105,131,124,148,190,203,201,213,243,204,204,181,125,189,196,228,208,179,217,167,211,217,210,182,180,178,134,141,106,121,87,75,84,135,198,204,192,188,185,121,164,227,221,218,222,221,216,243,161,148,224,146,207,215,214,207,216,213,219,184,187,194,209,161,52,41,103,42,35,24,19,8,35,11,33,22,16,8,6,15,42,19,9,10,51,17,49,22,40,33,3,40,39,28,63,83,100,102,67,73,49,26,14,0,24,22,50,109,129,71,92,139,66,61,80,61,67,60,40,35,31,36,75,112,97,107,121,109,96,108,73,68,78,75,93,66,70,147,138,60,45,39,33,39,23,39,16,24,47,26,40,60,57,53,61,65,65,64,54,85,92,84,110,118,147,143,135,173,175,184,183,168,98,162,179,181,163,166,100,117,140,130,84,50,66,58,83,39,36,35,81,62,57,97,27,44,46,49,38,46,36,2,20,27,11,12,16,15,19,18,5,12,14,24,17,17,23,4,8,23,14,36,66,54,48,30,46,48,29,3,25,33,10,26,11,13,1,50,45,16,15,18,28,39,10,38,24,33,27,53,72,68,78,61,51,81,56,94,126,92,114,158,116,157,168,158,171,157,148,146,110,102,82,69,68,39,38,37,65,33,26,38,22,88,63,9,41,64,37,41,70,71,53,48,57,83,59,37,27,43,22,28,13,34,37,36,31,43,141,155,146,109,101,97,87,111,79,78,85,97,180,233,249,237,234,235,232,219,251,250,242,249,255,247,252,248,241,248,247,240,244,232,220,242,247,230,199,219,224,231,230,242,242,235,237,223,233,240,246,233,245,237,247,206,221,243,212,218,231,199,241,238,228,218,235,242,217,126,9,7,8,15,14,0,18,20,4,30,42,7,10,5,3,23,29,0,21,17,22,3,23,14,191,196,188,202,203,190,193,202,197,200,218,196,218,184,197,181,204,200,154,199,180,211,195,195,181,209,181,185,196,210,197,195,196,164,177,196,185,200,198,188,190,186,195,212,184,187,188,174,218,182,193,188,210,202,193,199,209,198,199,195,174,185,215,203,189,179,184,186,200,199,205,190,208,192,198,195,207,183,187,204,187,186,191,191,206,180,189,203,200,161,171,181,179,184,213,218,193,198,187,190,205,213,207,222,203,216,219,191,189,187,176,198,183,200,212,214,208,204,221,194,212,195,229,204,215,211,192,190,214,178,191,191,200,200,195,175,212,206,193,190,217,201,213,202,219,208,213,185,200,194,210,217,197,193,183,209,193,207,189,201,211,204,214,221,215,213,207,227,210,211,237,201,214,185,177,230,229,215,214,212,190,219,219,215,226,239,216,201,217,213,226,206,201,215,205,213,207,211,216,212,220,210,213,209,241,203,219,213,211,215,225,206,216,209,190,216,219,206,207,206,179,193,211,184,203,226,244,209,199,183,204,209,182,207,213,208,188,205,214,205,199,212,192,202,199,186,203,207,199,205,200,203,214,186,179,211,205,183,191,182,200,209,205,187,192,209,220,190,197,169,186,209,214,172,211,199,204,199,205,191,201,189,183,206,167,180,220,205,203,196,202,175,209,195,220,176,181,178,216,185,209,204,228,208,185,124,193,205,202,158,190,186,192,189,178,142,101,133,149,118,136,111,137,117,126,139,245,198,175,179,141,183,201,200,219,193,192,149,202,206,174,114,173,214,112,125,129,143,94,36,87,167,228,197,191,169,168,176,191,237,213,245,203,212,198,232,147,170,214,131,209,245,210,222,192,239,221,215,220,166,149,103,49,57,65,15,23,9,28,25,10,28,14,22,20,20,17,29,10,8,40,27,33,29,14,30,14,60,7,50,60,41,46,103,98,71,41,74,38,9,34,13,27,49,97,119,152,87,119,113,49,99,90,40,53,21,41,46,37,47,83,116,154,147,143,141,144,141,118,154,114,125,135,115,97,119,111,66,101,126,120,168,131,167,134,147,168,176,185,151,169,166,171,165,144,163,166,150,149,141,153,151,127,139,136,125,145,134,112,86,87,77,52,77,67,67,54,68,46,67,60,64,70,60,37,61,53,70,60,58,58,50,25,59,45,39,54,29,26,20,12,22,8,1,28,15,16,1,49,16,14,9,17,26,18,21,44,2,27,40,87,87,75,51,54,72,47,13,31,31,27,19,10,16,28,34,31,31,13,39,17,21,9,10,14,18,10,13,38,55,89,67,69,78,85,72,57,69,69,61,61,44,75,53,66,104,131,143,157,134,173,136,159,141,97,102,84,80,71,49,65,52,49,49,27,52,30,39,35,34,60,55,52,74,90,67,33,20,29,39,18,43,44,50,54,16,97,141,123,119,92,120,107,93,79,117,100,120,159,235,244,248,221,248,244,233,251,254,250,255,253,244,251,226,253,255,245,246,218,244,224,219,217,207,215,229,217,208,213,246,214,223,213,212,201,218,244,229,211,210,208,217,209,242,232,234,217,234,212,232,210,220,226,242,249,139,0,2,5,8,19,11,0,11,28,29,14,12,2,16,23,23,7,4,31,0,5,20,11,32,203,195,212,200,180,198,189,193,190,182,207,196,192,197,193,181,190,203,174,187,175,193,199,170,182,179,160,214,189,196,211,199,168,199,201,178,208,195,199,192,195,190,210,182,191,169,185,192,199,214,213,196,211,210,170,169,196,188,181,190,202,200,193,204,172,198,202,190,176,195,197,187,196,182,185,211,207,196,215,199,195,186,202,208,193,214,171,187,213,188,184,196,197,196,201,201,166,194,223,216,211,196,198,208,218,209,181,204,194,198,201,200,206,204,190,216,191,206,235,198,206,194,198,236,204,203,210,209,191,199,195,209,203,190,226,202,211,211,198,203,194,219,212,173,211,200,215,192,208,195,186,195,211,212,185,206,220,224,223,219,215,192,206,200,194,201,215,222,216,187,201,195,203,206,219,222,221,190,214,216,195,221,216,207,219,231,207,209,203,187,228,202,204,208,227,217,209,241,209,227,210,218,194,213,225,212,190,204,204,212,223,210,198,215,214,208,207,212,229,202,218,201,199,193,199,215,218,222,205,218,208,214,226,203,212,194,221,226,212,198,211,188,180,189,211,203,210,192,212,187,226,192,215,225,182,197,199,194,205,184,200,200,199,199,189,209,202,204,184,188,199,186,177,174,187,213,202,209,217,159,187,192,177,195,209,180,201,211,191,200,198,179,204,195,194,184,189,209,179,186,202,200,197,201,171,167,203,213,183,173,160,189,210,177,186,145,107,128,123,116,127,100,112,87,73,153,241,183,183,187,151,154,200,192,217,216,168,179,176,142,155,89,153,202,111,116,89,143,137,94,45,152,181,153,193,171,190,169,168,240,209,238,218,234,221,205,131,190,223,119,238,202,225,236,212,250,195,216,208,86,92,74,84,50,0,40,16,4,23,12,18,21,20,7,38,42,37,31,17,10,32,35,6,25,16,5,3,43,31,61,67,42,86,90,99,91,55,50,17,13,30,49,40,86,143,103,98,95,97,108,71,91,75,89,94,80,37,56,72,53,70,82,132,128,120,132,117,132,118,137,137,136,132,103,117,106,89,88,135,165,148,145,155,122,146,131,152,117,142,164,128,116,141,117,120,99,83,97,43,62,36,73,59,60,56,76,45,54,63,54,53,58,58,67,77,68,70,62,80,74,72,52,57,47,44,57,37,33,36,27,28,44,27,24,25,40,52,15,36,48,59,63,38,10,6,36,22,26,17,25,19,6,32,18,26,27,3,22,42,67,142,142,101,69,66,74,39,26,32,3,32,27,6,6,39,26,6,7,14,38,19,15,28,37,27,75,72,24,43,62,33,43,56,48,37,40,71,43,80,76,87,98,74,70,63,87,49,50,54,55,72,93,91,125,136,99,118,138,138,120,128,99,108,88,79,73,58,45,49,36,34,62,54,83,36,50,26,27,24,38,40,69,90,47,41,17,52,127,113,115,103,84,82,98,77,114,123,118,134,135,132,190,206,217,249,251,249,240,219,212,242,246,254,234,204,225,236,240,218,220,206,223,218,201,200,213,211,216,228,238,216,223,245,207,243,235,221,216,236,230,235,223,219,215,244,248,243,242,228,223,206,250,227,246,236,124,3,3,3,7,13,9,17,0,15,20,10,30,7,14,20,22,14,9,10,3,16,22,31,23,203,183,203,212,187,200,210,193,186,207,203,198,173,196,207,197,178,187,188,192,196,157,191,194,218,215,171,193,187,184,185,194,207,180,190,199,201,200,188,209,224,212,196,180,165,172,172,183,183,176,180,213,169,179,199,210,188,188,198,197,179,187,210,199,200,174,191,199,191,177,177,207,204,173,179,191,183,199,196,209,192,201,172,181,188,188,204,187,192,190,204,195,182,215,191,187,212,196,181,211,202,236,173,210,192,204,204,190,192,187,201,204,211,202,206,214,193,213,210,203,212,212,214,208,210,206,194,218,204,210,210,221,206,226,213,202,190,204,197,210,188,209,195,209,196,206,207,212,206,224,210,230,201,187,207,203,190,199,201,215,196,209,211,207,229,194,215,186,215,176,210,217,188,221,203,226,220,210,220,203,230,229,205,215,230,228,212,223,210,189,210,236,214,205,216,183,223,213,233,204,218,186,194,221,210,207,205,221,203,222,224,184,182,224,208,226,218,197,214,197,206,208,205,210,206,215,227,201,216,220,211,219,209,225,199,212,196,190,204,211,214,203,214,215,210,214,202,193,199,206,214,229,203,204,232,204,191,195,224,189,208,191,209,185,171,187,200,191,181,192,172,177,213,191,208,202,215,218,205,179,207,162,191,190,186,189,187,192,200,211,195,213,226,195,226,212,183,214,194,178,174,197,199,206,134,150,202,196,168,148,185,173,193,192,175,122,66,107,110,101,100,78,49,72,57,129,205,184,183,219,131,177,212,211,229,181,158,149,160,140,177,122,184,167,66,82,77,86,78,110,126,198,192,206,183,126,142,120,165,235,194,228,215,234,209,218,130,213,222,135,210,225,220,212,214,235,226,219,119,55,60,71,53,20,10,3,51,24,1,7,9,15,29,23,10,2,24,41,28,19,16,22,22,13,2,22,31,33,83,44,43,75,124,79,69,31,30,5,12,6,44,78,92,87,135,97,66,58,93,110,123,130,113,124,172,114,101,135,102,129,141,114,85,63,48,49,56,72,63,60,42,67,63,44,74,54,59,47,77,76,53,66,65,54,51,55,48,60,42,60,66,38,79,73,79,72,79,85,45,106,76,57,55,102,71,79,59,42,51,53,52,59,43,50,24,44,35,52,33,22,55,18,22,28,24,38,20,21,7,49,15,12,20,5,12,20,52,56,63,83,80,94,71,35,8,24,16,13,36,11,31,23,20,37,4,28,18,15,16,114,183,127,126,143,131,126,67,27,9,28,24,35,9,22,18,17,8,18,30,11,10,28,35,65,78,86,70,56,62,37,48,47,34,18,28,40,37,34,45,28,49,54,59,31,57,73,52,77,50,73,42,74,60,76,102,88,73,65,55,48,75,81,116,128,126,133,141,112,119,106,93,79,94,95,73,67,77,62,41,41,26,55,43,33,74,24,82,135,126,120,122,112,129,121,94,138,136,59,67,46,63,180,238,248,251,236,174,118,129,104,114,123,143,134,104,154,224,214,213,216,222,237,216,214,209,226,226,228,212,205,196,226,233,225,209,229,204,203,232,228,213,232,221,236,229,231,207,242,207,219,232,228,225,207,210,94,1,5,7,15,2,10,16,28,29,9,19,3,0,11,2,7,19,17,16,6,0,27,17,29,206,197,185,198,191,206,201,197,203,204,191,215,215,207,187,196,185,184,221,217,197,184,191,216,175,220,178,197,182,195,179,190,186,202,191,199,204,187,198,189,184,183,184,205,171,176,195,192,181,193,180,196,185,182,196,186,185,171,196,201,177,207,218,201,189,191,198,189,194,178,182,205,176,187,183,193,181,186,197,192,211,179,213,228,186,210,222,208,195,186,191,199,182,197,190,202,215,210,210,203,206,210,209,189,168,209,225,195,212,176,213,204,177,183,180,200,191,199,192,199,212,222,210,230,223,211,208,204,198,184,207,228,211,196,204,194,214,236,217,199,220,225,215,232,204,191,234,203,198,234,217,210,207,203,185,222,214,202,208,192,210,191,216,207,207,235,201,213,198,202,205,217,200,199,215,206,209,216,179,206,206,213,213,226,212,217,207,229,215,188,197,245,195,203,217,216,213,203,187,197,190,224,240,187,214,214,216,198,206,207,218,226,211,204,221,232,199,234,207,213,209,204,199,204,196,221,218,195,189,223,235,228,191,208,234,201,193,216,199,215,217,215,221,190,222,217,187,200,201,203,197,209,185,199,211,203,211,185,200,199,200,210,181,202,205,217,207,186,193,196,195,183,187,183,217,187,189,190,205,186,190,202,198,194,218,180,185,194,195,192,203,185,187,199,190,193,204,190,200,167,172,196,211,195,151,169,205,201,149,137,178,186,175,152,150,103,98,100,68,127,63,42,35,56,95,150,204,171,197,207,142,155,225,205,227,176,162,179,170,169,185,117,142,137,69,74,106,74,61,56,56,203,164,229,152,151,190,143,189,216,190,193,178,220,219,175,134,236,196,151,201,198,216,199,240,218,208,221,57,49,40,45,17,14,36,22,17,14,15,25,19,30,31,10,51,28,27,36,39,13,25,42,27,45,33,17,48,42,43,36,60,75,90,45,63,42,15,3,16,17,43,68,125,117,89,71,21,16,100,65,95,139,107,129,130,124,119,95,109,164,156,148,66,77,83,59,57,66,99,80,79,90,93,80,91,96,60,56,56,106,99,88,85,79,36,77,95,63,95,48,60,69,65,80,55,65,88,80,74,58,55,31,37,46,47,46,46,24,11,17,26,22,21,21,14,20,25,8,19,38,7,7,15,31,14,27,6,13,19,10,23,27,10,3,23,87,82,112,142,134,138,133,105,40,18,7,12,28,8,19,27,14,31,9,21,17,3,47,36,132,171,131,155,137,179,151,78,22,14,5,11,12,19,38,13,7,22,15,0,44,59,17,29,95,110,146,139,118,99,83,80,13,20,13,36,26,19,11,40,9,29,18,33,36,41,46,15,31,38,53,67,61,59,56,73,87,53,50,66,45,45,50,86,103,55,79,73,75,88,84,95,126,139,123,150,127,135,131,125,128,95,85,75,90,82,63,123,176,156,142,111,115,112,97,103,127,113,107,57,70,73,185,224,250,233,99,43,61,49,64,70,64,49,56,22,82,177,192,228,218,208,202,225,214,222,226,233,244,203,241,211,235,220,216,230,224,203,218,220,252,228,207,227,204,243,240,224,217,216,225,230,220,229,240,223,114,6,1,5,6,29,35,22,29,6,14,1,13,12,9,7,22,34,30,10,2,16,16,18,0,201,199,207,204,202,215,183,213,206,185,186,196,200,187,210,199,188,214,195,172,206,198,194,180,184,187,199,192,201,192,190,223,182,177,208,195,206,187,172,214,204,175,205,187,199,202,185,187,183,173,195,192,191,191,220,182,214,194,188,204,190,155,197,205,215,160,206,196,209,184,188,182,177,189,185,186,205,183,204,187,198,204,184,197,201,209,198,186,193,197,197,209,192,191,180,196,189,202,182,168,183,197,214,204,215,215,187,194,190,218,191,215,219,196,200,204,204,194,205,207,219,201,210,215,207,200,211,196,195,219,223,224,225,221,207,171,224,238,225,222,239,227,236,221,221,224,197,205,215,191,199,216,214,214,183,211,211,201,196,192,210,213,205,208,202,215,217,194,226,212,194,212,200,212,214,235,236,214,217,220,215,216,210,212,213,181,223,228,216,216,228,197,228,214,215,176,209,211,209,193,192,211,214,244,213,234,220,186,215,209,204,186,194,206,217,198,211,215,205,201,211,214,200,217,211,242,207,217,236,229,222,221,222,180,212,212,233,238,204,205,238,221,228,201,200,218,204,210,206,215,195,242,209,207,189,206,190,199,208,196,218,201,199,191,186,180,183,189,193,187,191,215,185,210,193,191,210,205,206,191,192,194,188,207,213,186,210,192,188,195,202,174,172,203,188,183,205,222,216,189,193,187,204,157,154,191,175,214,143,131,172,162,180,168,150,114,113,67,54,67,47,10,25,74,68,169,213,174,211,212,159,150,224,221,195,182,181,188,154,196,194,119,107,130,94,125,100,84,66,39,5,122,161,195,156,200,194,163,218,222,209,206,216,214,221,148,165,245,196,152,233,211,206,232,227,201,233,163,25,51,61,23,25,36,10,17,5,25,20,3,20,22,22,1,16,30,29,22,19,31,18,15,19,41,18,56,11,28,54,66,68,100,61,32,56,38,2,26,19,44,76,104,108,101,141,116,6,56,114,91,79,86,56,90,63,69,47,81,105,122,85,51,34,38,20,58,82,59,42,71,64,66,61,97,122,124,118,72,42,47,41,55,45,40,40,45,49,64,39,61,54,38,75,39,41,27,24,12,18,28,5,19,44,12,43,24,31,18,40,31,26,41,52,18,8,16,6,60,25,7,26,7,6,17,9,12,6,31,24,42,32,22,31,11,63,170,193,179,174,206,199,194,144,62,18,28,48,31,33,29,15,22,15,40,21,3,33,14,69,132,152,180,163,127,176,151,106,39,19,22,20,11,15,33,30,13,31,24,54,19,6,28,52,140,156,147,151,182,155,155,95,32,6,40,19,37,10,3,14,13,17,38,26,33,13,24,25,18,36,20,29,41,20,43,44,38,45,31,42,72,68,73,69,91,76,80,68,48,84,57,66,97,74,51,43,59,103,107,127,123,127,155,132,143,135,139,138,157,153,121,107,91,104,134,119,130,105,99,140,109,204,235,233,251,178,58,11,16,73,73,23,31,44,24,1,78,204,222,214,233,203,201,241,221,219,217,218,220,220,217,191,220,193,206,231,206,205,198,212,205,211,206,192,216,222,237,230,217,233,237,237,243,238,210,216,123,3,23,5,8,11,5,17,0,27,29,31,13,17,8,15,34,20,23,19,3,26,18,4,14,198,204,200,184,191,221,208,228,179,177,193,191,199,205,203,214,213,205,168,202,220,206,187,204,208,200,201,209,188,166,198,187,174,195,201,177,182,190,188,169,186,195,190,192,188,179,201,203,185,189,185,224,205,187,220,205,215,218,210,181,181,202,175,206,170,199,179,207,186,176,194,212,183,186,193,196,202,170,174,191,227,193,219,223,226,186,183,210,214,176,201,207,208,189,202,203,213,205,169,200,198,222,180,200,199,191,189,205,196,214,190,227,219,201,203,198,196,190,224,202,202,195,202,203,199,191,220,185,193,204,214,244,208,190,220,201,193,189,226,211,210,198,219,198,197,214,194,219,214,222,209,195,199,191,209,226,189,211,187,233,167,214,202,228,218,194,208,210,202,187,183,213,211,210,207,186,206,207,204,221,185,192,218,212,209,220,219,227,201,212,214,229,214,230,189,195,216,199,213,199,209,212,216,241,213,213,216,196,213,217,214,209,219,220,202,211,214,211,239,213,219,217,207,223,194,211,230,218,230,205,226,191,198,215,208,184,215,193,210,184,213,212,219,169,203,223,189,217,213,213,200,204,165,200,202,208,194,177,213,222,213,162,196,198,203,181,193,203,205,192,196,179,203,204,172,214,215,206,209,169,201,216,198,195,200,201,182,187,178,170,206,212,188,181,207,193,199,205,244,188,185,194,210,174,187,228,200,190,146,160,204,198,174,160,166,145,123,82,109,93,51,52,59,128,157,240,227,199,198,208,156,145,221,231,193,160,216,215,142,153,183,136,174,176,110,99,103,68,56,56,18,91,182,217,153,199,156,162,232,224,211,195,207,227,196,157,190,236,181,152,233,231,237,239,210,185,144,100,76,66,32,40,29,44,13,13,14,33,26,18,30,21,6,49,18,19,25,3,19,4,56,22,19,41,24,23,37,30,82,67,88,46,61,55,29,36,18,34,59,72,123,103,121,92,99,76,20,83,111,129,90,91,51,124,92,34,77,26,56,89,129,49,10,96,62,49,120,82,27,12,53,28,21,93,96,73,86,59,17,38,34,39,27,20,11,24,29,6,54,18,36,12,27,30,28,22,18,19,1,5,31,34,17,15,18,53,65,58,84,70,66,80,97,47,16,31,16,2,26,15,20,13,19,33,24,26,5,22,7,19,8,11,23,4,81,208,200,186,167,178,182,186,171,70,3,11,15,27,6,25,16,36,11,26,19,33,16,33,60,104,141,168,140,140,144,158,147,51,19,16,28,19,28,20,45,27,16,29,24,29,50,21,55,140,156,163,167,146,176,175,164,49,14,11,10,38,16,25,9,9,14,7,9,11,17,11,23,18,15,19,29,41,32,22,24,36,20,21,29,33,48,34,40,52,53,64,57,45,50,66,92,62,79,64,85,71,59,61,77,64,59,86,70,68,114,86,72,85,72,68,45,87,88,65,96,94,128,106,119,99,140,200,162,172,91,60,29,69,57,86,66,57,62,65,21,152,243,221,219,213,204,226,223,228,199,212,233,208,220,236,198,207,219,212,228,215,206,221,222,206,231,213,206,205,210,230,225,224,223,214,199,216,233,210,236,130,1,0,10,18,11,16,30,0,2,21,10,13,0,0,10,26,16,25,4,20,16,18,13,12,213,197,190,173,228,202,212,189,190,218,195,233,192,181,200,197,189,207,201,174,212,224,210,183,211,184,201,186,199,206,167,191,199,180,193,218,187,177,194,199,217,199,196,191,191,209,209,214,203,194,198,213,182,168,192,200,193,198,184,199,208,181,204,191,194,210,177,184,193,187,182,205,208,179,178,201,186,224,178,196,196,205,207,203,208,194,207,215,215,182,204,206,182,199,207,195,209,212,168,210,231,200,188,189,198,210,212,200,193,221,212,186,198,224,214,193,215,187,203,197,200,207,214,199,216,209,211,214,212,202,241,207,193,191,211,198,207,188,206,225,228,207,226,216,191,206,198,220,204,220,190,232,194,204,195,208,187,179,196,205,202,193,204,178,204,209,220,204,204,223,238,209,195,209,232,194,203,213,204,219,204,206,197,229,208,225,217,191,205,215,221,208,211,219,199,223,207,235,240,235,213,226,187,216,206,224,211,212,220,217,213,194,241,195,225,214,191,209,205,192,220,208,220,220,212,184,199,243,209,192,203,208,213,204,218,209,187,212,199,196,214,187,195,228,224,215,204,232,217,201,183,201,215,229,196,219,216,209,197,205,218,184,188,197,191,226,200,208,182,192,201,179,148,184,179,187,179,200,213,185,212,186,195,187,203,210,231,163,206,215,197,200,184,187,190,194,193,198,227,187,194,175,215,143,191,180,176,219,151,197,198,184,190,150,160,150,161,112,121,56,65,38,101,168,203,236,209,171,164,193,168,158,183,200,170,181,238,151,106,125,204,149,198,157,77,129,88,91,104,64,53,158,250,244,168,157,133,164,202,221,218,247,208,224,182,137,186,205,138,156,147,243,237,230,170,99,60,43,75,44,26,50,21,11,24,18,32,21,20,13,24,45,17,43,34,20,20,44,26,8,8,25,31,26,60,51,35,68,80,88,59,58,60,20,31,46,42,66,61,121,84,135,126,90,108,79,44,96,130,87,117,117,123,130,61,61,61,44,97,150,121,59,80,129,135,71,111,129,47,23,21,24,66,127,95,92,113,38,22,32,24,40,40,33,29,33,4,23,34,5,14,36,16,11,3,22,10,20,51,17,21,29,14,21,8,78,121,148,139,168,167,160,199,74,20,34,24,29,13,25,14,19,26,32,11,2,10,22,19,20,17,30,12,16,95,166,151,161,110,96,125,119,105,24,28,42,10,31,8,43,28,17,18,20,52,34,35,17,63,68,138,158,132,136,135,165,182,94,7,25,22,34,28,37,37,37,20,31,23,46,45,22,68,144,170,116,167,163,210,175,190,110,29,9,18,17,24,22,38,33,20,24,19,15,22,3,29,17,27,3,8,38,49,59,63,32,15,16,49,50,17,17,41,40,16,45,55,54,27,27,66,41,26,68,67,92,70,90,76,80,85,61,75,61,94,70,73,58,49,71,77,66,78,58,45,33,55,58,70,55,43,39,30,45,42,13,18,56,45,93,46,50,63,35,40,218,244,232,245,217,220,212,217,214,204,219,233,208,208,196,239,224,206,201,221,221,218,191,233,230,225,230,224,230,210,217,221,204,197,223,233,233,224,249,222,119,15,12,23,18,17,32,22,14,31,4,13,14,6,7,12,3,17,8,6,0,19,20,11,11,224,218,231,216,195,212,228,190,193,196,192,202,206,201,191,181,222,205,211,184,204,166,190,178,179,192,188,181,199,192,184,189,190,192,183,189,188,202,204,202,184,203,213,200,197,206,220,198,187,178,202,202,191,183,177,192,196,203,193,197,210,200,198,190,192,228,210,181,181,196,192,180,183,209,193,194,197,199,171,179,190,198,196,216,180,229,191,179,195,202,209,203,209,213,190,210,205,187,210,200,214,183,210,240,211,207,214,206,222,195,199,202,206,201,207,210,211,209,202,206,181,192,191,176,219,191,216,220,226,203,192,226,217,221,202,194,212,211,196,208,217,204,211,196,216,217,224,223,204,198,212,211,206,212,203,220,204,199,228,218,218,202,211,209,207,195,219,220,218,194,225,213,229,206,226,213,193,202,190,196,205,177,210,207,222,217,236,209,211,216,206,210,205,206,208,206,229,232,207,224,211,202,232,215,243,215,195,223,231,198,213,206,227,232,208,212,218,224,208,223,234,201,202,199,228,203,194,215,211,214,214,207,232,199,197,211,196,200,202,213,210,213,202,230,229,202,220,210,213,218,224,226,199,188,235,226,188,210,220,200,208,198,201,216,206,210,178,185,222,185,206,163,175,208,228,205,207,195,203,204,206,190,203,204,212,200,206,202,187,203,209,182,237,187,191,198,191,194,198,179,202,164,189,136,176,177,174,170,151,215,225,164,143,127,144,157,158,142,107,38,63,48,104,203,218,241,201,166,194,228,179,159,194,205,168,213,168,128,149,180,209,155,167,97,80,109,92,87,81,20,51,221,225,204,140,152,172,160,217,206,196,216,227,241,145,158,202,77,70,90,125,197,241,209,104,65,58,31,65,33,22,7,27,10,15,51,27,24,18,11,27,15,15,23,29,17,54,22,7,26,35,21,27,57,34,45,63,61,91,71,83,56,48,12,65,95,77,96,82,100,115,130,91,88,126,123,118,146,119,74,117,113,119,96,57,77,87,74,97,83,120,136,71,159,148,88,82,161,117,44,35,48,138,175,93,108,94,49,29,59,26,48,52,57,21,20,19,14,10,16,12,22,13,19,11,35,5,11,5,8,29,23,30,20,25,189,187,210,228,223,180,190,214,105,11,23,15,8,14,22,16,26,17,24,20,16,19,32,23,14,8,23,0,31,92,110,67,68,35,38,60,71,87,31,15,6,36,26,40,17,12,66,14,33,47,32,19,29,31,91,147,190,139,145,166,133,188,71,11,17,10,18,29,43,24,21,38,19,19,15,26,20,89,123,113,128,109,116,160,140,174,99,29,21,35,24,12,9,42,23,4,33,14,17,40,19,19,8,25,28,27,21,91,72,54,95,73,45,59,59,37,14,1,31,18,19,18,9,3,27,24,19,39,37,58,14,29,50,47,59,78,56,77,57,41,83,64,70,98,115,140,142,110,90,36,22,8,40,63,60,64,53,55,32,39,14,63,72,55,76,73,59,68,15,133,228,219,232,247,231,202,209,221,198,204,221,229,217,220,226,218,230,208,221,229,211,243,223,248,206,228,203,228,229,227,204,216,235,227,230,202,223,210,226,230,134,1,15,2,12,17,14,14,13,4,20,39,39,2,1,19,1,0,12,11,5,19,3,25,7,207,196,219,195,199,196,192,196,184,200,190,185,190,204,196,191,187,212,225,209,203,216,204,205,178,200,219,194,219,218,196,200,213,180,178,200,194,181,211,194,201,193,202,195,205,195,207,207,205,220,193,206,191,211,209,225,194,194,189,176,200,194,199,192,193,204,202,212,230,189,171,211,210,204,199,216,199,186,223,206,207,191,192,215,195,204,191,223,213,212,201,218,189,191,210,201,204,209,197,185,206,205,207,216,196,212,201,199,196,190,199,185,199,208,192,214,211,221,180,201,186,189,210,209,197,214,206,213,221,230,201,222,205,215,229,233,205,200,223,199,185,173,208,197,205,205,221,206,214,216,214,214,207,199,204,207,197,202,220,216,214,205,213,209,177,216,229,207,189,228,198,209,210,213,196,206,242,208,192,210,237,221,211,202,207,200,217,203,227,224,210,212,215,224,219,208,221,212,211,202,222,227,207,222,200,214,205,192,204,222,206,229,178,220,205,203,216,211,219,201,200,212,226,206,220,216,206,222,186,208,208,199,217,208,193,202,215,211,218,221,208,210,222,220,193,239,236,208,212,207,204,218,197,220,225,218,204,195,213,193,190,202,203,208,206,190,187,193,205,214,210,205,180,203,219,213,197,205,205,222,210,211,201,218,197,210,199,198,207,220,193,225,197,182,199,191,201,202,190,172,198,198,173,152,183,192,186,213,143,207,198,150,152,137,145,194,182,139,86,72,41,49,91,211,211,245,219,163,226,167,105,113,173,163,187,218,165,174,185,230,161,109,170,125,87,129,64,101,62,51,53,172,203,134,152,187,168,189,232,204,191,199,178,219,146,176,189,50,45,74,83,148,240,202,46,37,62,69,8,15,35,22,21,24,23,17,23,38,20,10,1,14,23,7,11,35,26,17,2,32,20,30,18,45,38,51,61,73,67,77,53,28,32,62,144,203,132,113,100,103,137,111,119,119,140,195,135,113,38,84,111,103,77,110,57,96,75,67,88,47,91,120,158,176,196,81,101,138,129,68,45,39,144,132,93,106,71,37,76,69,97,84,142,109,27,41,15,12,31,26,24,31,3,9,16,31,46,11,27,6,31,32,23,33,37,170,189,190,190,171,178,176,192,128,6,20,9,13,21,39,11,9,16,20,34,17,20,31,30,25,10,21,24,31,98,112,45,84,41,51,29,38,30,27,44,11,48,11,31,17,25,36,28,62,11,53,14,16,36,82,118,148,105,148,135,156,169,74,31,22,37,31,18,19,11,7,25,14,36,43,34,45,113,129,92,71,48,61,121,88,117,92,17,15,13,27,18,19,24,17,31,8,54,15,8,28,36,17,33,11,14,40,137,169,152,141,135,131,129,98,40,25,3,38,18,18,15,37,10,13,32,10,15,24,19,18,16,33,39,42,36,43,25,42,41,25,47,47,37,51,115,128,106,96,110,137,147,163,105,117,75,68,70,70,89,87,112,106,116,120,127,101,81,75,157,227,229,207,230,205,214,220,222,216,209,214,221,201,215,197,240,232,195,221,235,202,230,226,225,219,193,232,205,239,186,218,213,205,230,251,245,199,235,220,237,124,7,12,10,8,13,15,32,0,4,21,18,2,22,1,4,14,0,5,1,20,20,22,10,37,190,204,225,205,180,197,205,211,187,212,194,168,174,186,203,203,224,196,191,213,185,223,202,204,199,193,189,201,223,209,180,202,207,199,197,195,199,182,190,222,198,194,207,202,194,210,197,205,198,192,199,220,197,201,187,197,212,194,219,206,220,219,199,193,206,169,192,194,191,203,197,206,196,174,216,202,212,199,198,203,225,203,181,181,209,193,207,200,215,209,198,200,198,210,208,228,198,205,198,198,203,157,216,225,204,221,182,176,202,218,217,210,195,203,214,211,201,204,207,196,204,222,229,205,217,203,214,195,200,187,211,201,220,179,174,202,216,214,197,203,212,220,200,207,222,202,218,220,208,212,202,179,226,197,201,216,214,210,222,210,204,203,214,221,215,190,212,195,199,196,212,212,235,217,211,208,227,219,206,195,206,195,208,195,215,220,183,192,229,199,220,224,195,215,204,231,217,221,201,208,209,218,190,224,211,222,203,187,189,209,216,197,207,206,207,205,215,231,204,196,192,213,215,219,234,198,207,221,225,194,228,206,225,198,191,213,232,216,235,205,221,194,237,169,136,179,205,199,210,207,210,210,219,193,198,191,207,229,196,182,188,196,222,212,218,183,186,220,204,210,187,184,192,193,195,237,192,199,222,190,221,218,195,205,202,219,198,230,222,197,207,210,195,205,170,213,201,191,210,199,193,221,205,148,197,217,164,190,138,147,113,95,166,166,161,178,200,155,114,42,34,31,90,167,191,244,194,173,195,169,99,137,80,162,223,198,154,182,213,209,129,88,202,177,143,105,88,78,52,68,84,173,199,176,175,221,179,197,242,211,223,209,228,185,115,188,151,48,124,96,96,148,220,145,36,62,67,42,26,11,16,32,31,12,27,18,37,23,21,34,52,13,33,37,14,28,15,29,33,12,34,46,29,65,61,65,67,67,49,76,38,7,54,144,171,170,108,106,130,128,104,113,80,125,150,179,156,116,47,62,113,129,95,126,109,118,84,82,81,23,74,106,173,206,152,60,56,164,144,94,0,33,151,116,99,99,101,78,129,143,165,179,191,188,27,0,12,28,24,16,10,31,27,32,35,16,32,24,23,30,14,4,23,45,58,173,132,106,97,78,79,103,111,58,15,17,16,13,3,22,7,29,27,1,24,26,21,39,33,38,36,41,24,60,84,133,57,42,53,23,58,43,61,11,42,24,30,29,38,20,48,47,63,17,38,37,16,23,42,74,80,104,93,107,96,68,102,51,42,19,27,31,26,32,51,48,35,58,22,17,24,48,148,127,77,62,71,36,85,45,51,34,24,30,51,31,23,28,36,17,19,22,11,49,0,41,31,63,45,32,41,25,171,183,162,194,189,184,178,141,86,27,24,48,5,0,22,18,30,33,27,15,22,18,9,10,3,4,41,18,27,15,45,45,24,57,34,10,29,48,83,108,103,159,252,247,237,158,93,59,4,21,54,85,99,108,90,117,94,109,124,135,124,45,144,199,218,239,216,226,231,215,242,218,201,204,209,230,231,208,204,234,200,218,215,190,241,210,189,218,218,211,222,227,196,245,226,215,221,216,232,224,226,241,225,97,15,20,5,16,10,6,3,14,13,17,9,12,4,8,24,5,6,2,6,12,23,29,14,30,223,197,193,208,194,198,187,205,203,200,213,192,204,198,179,197,190,208,199,192,216,193,181,201,206,195,222,184,192,206,213,214,208,180,201,198,193,218,194,195,189,188,201,218,212,198,173,202,200,207,210,202,194,184,199,203,184,187,194,213,198,191,188,203,186,213,216,198,211,196,183,181,193,217,197,201,210,177,214,204,200,190,203,183,206,182,188,211,191,207,205,197,176,216,201,203,200,203,166,204,189,213,194,207,201,169,194,217,220,192,193,195,203,200,204,216,196,205,218,212,207,202,225,195,211,208,216,206,218,199,226,204,212,204,206,220,235,216,210,222,212,234,179,207,202,193,206,207,216,190,192,181,167,209,207,194,210,195,206,206,204,209,238,231,198,210,210,181,188,191,214,209,201,225,209,202,208,209,214,210,225,203,213,221,207,218,213,201,214,217,210,211,199,206,219,226,227,202,221,217,213,210,194,194,217,185,244,208,176,218,222,202,219,226,206,201,199,195,196,192,198,187,211,202,216,203,207,189,216,218,195,190,210,214,201,196,189,211,192,221,201,223,210,172,118,162,186,181,220,209,207,208,202,223,212,218,187,203,211,201,193,194,202,230,184,223,193,205,221,212,220,211,193,196,213,206,228,212,207,198,197,210,226,216,182,224,230,194,204,196,195,210,215,197,193,215,206,189,191,220,205,237,188,141,203,203,163,164,97,133,90,48,146,130,156,183,134,128,86,57,35,7,96,180,198,214,213,196,192,179,153,158,85,109,239,194,176,134,173,202,128,139,212,163,121,106,114,106,59,56,61,179,180,182,194,236,182,201,222,196,222,219,224,181,130,218,134,71,108,75,89,180,229,168,73,92,26,5,20,10,1,28,23,22,22,30,47,35,25,21,45,33,19,14,31,43,34,16,23,26,55,25,39,56,57,69,43,31,80,51,23,1,92,106,94,121,49,59,133,99,92,89,127,93,87,100,191,153,77,99,94,107,121,138,143,128,104,52,43,26,51,49,82,101,47,15,70,179,107,54,27,79,162,94,117,112,110,150,166,183,184,179,189,163,30,23,5,34,35,14,19,33,7,17,34,33,22,15,19,20,28,26,15,33,74,103,56,56,48,45,57,57,86,21,9,5,4,26,12,20,21,53,30,31,42,19,23,21,17,39,30,25,33,40,99,81,66,69,53,80,56,93,60,39,48,42,24,42,36,37,40,70,62,34,54,42,44,38,64,60,94,62,46,57,20,30,47,34,13,24,15,29,19,42,40,39,22,34,13,46,21,58,123,99,54,38,51,63,48,31,52,34,5,32,29,18,37,49,26,8,22,1,25,11,18,41,12,6,15,2,27,48,140,142,157,166,194,176,183,193,160,41,15,14,24,4,35,27,17,37,32,25,25,4,30,35,21,23,12,19,30,41,67,72,76,73,67,68,35,32,101,114,134,184,251,244,216,122,55,53,5,69,107,83,80,41,28,54,106,78,114,105,120,67,70,206,228,229,235,225,231,226,217,219,228,208,232,218,198,242,208,201,214,200,208,215,232,217,216,217,212,234,233,213,222,191,209,207,208,190,197,232,217,223,215,131,14,11,7,13,29,7,4,17,7,11,17,14,0,1,0,1,12,2,17,0,21,10,6,14,192,198,175,213,213,196,206,198,204,197,205,183,216,228,194,186,180,208,195,212,201,187,165,199,201,202,238,209,199,210,208,189,194,175,196,204,209,184,188,203,206,195,211,186,199,226,185,197,197,210,202,210,209,207,202,182,200,196,188,202,206,170,196,235,204,197,189,201,215,212,191,206,197,205,233,224,219,224,193,199,193,191,197,192,214,212,200,197,213,190,193,227,184,201,221,212,206,171,198,190,192,214,211,199,209,199,193,216,211,225,216,194,217,223,217,200,193,213,197,221,179,208,202,206,215,212,219,215,187,206,200,195,205,188,193,214,201,215,204,199,230,206,213,205,202,210,219,206,224,180,230,216,199,205,208,195,227,199,217,199,208,203,199,213,201,178,214,218,199,213,208,219,184,216,219,212,194,215,213,189,211,192,201,208,212,204,224,211,209,226,207,195,192,207,196,199,230,185,211,224,216,228,212,198,233,205,233,209,209,217,198,233,192,203,215,211,211,235,199,206,214,196,200,191,193,219,217,199,184,201,219,197,204,208,197,202,204,198,207,213,204,201,221,184,197,201,212,185,228,210,205,220,184,209,173,214,212,196,195,200,196,217,208,205,199,196,216,220,220,216,188,210,222,238,201,207,181,212,243,202,190,227,223,204,191,217,195,215,201,203,206,219,205,226,214,235,193,181,214,209,212,206,177,145,199,229,190,177,114,160,120,104,151,125,156,168,155,125,80,51,39,53,138,203,201,219,193,166,212,219,213,202,115,134,194,209,141,142,182,218,156,119,188,151,112,129,86,87,62,48,51,170,237,182,160,241,184,205,216,194,217,203,239,176,139,226,189,110,136,72,89,241,253,161,75,26,34,24,12,14,5,12,28,37,41,21,22,14,15,56,2,25,44,20,10,16,29,31,24,37,53,36,71,68,88,85,64,52,49,15,26,32,87,85,64,96,49,102,57,98,95,78,108,106,74,71,154,190,154,87,72,95,72,102,120,90,95,39,22,62,21,42,3,26,38,45,118,129,59,23,7,76,139,81,65,68,99,137,121,124,134,131,150,111,28,29,0,8,19,11,5,30,32,19,33,41,9,44,50,52,30,34,20,38,100,129,76,45,42,40,47,38,44,26,34,36,30,8,7,11,28,25,39,49,15,57,30,60,62,39,75,62,66,77,164,174,114,144,121,173,142,158,133,152,115,157,158,138,165,173,177,180,163,197,156,190,157,180,166,171,146,118,52,49,34,19,36,59,26,50,59,62,58,48,50,41,37,26,54,38,35,62,110,90,102,58,44,52,76,45,69,28,27,20,3,36,20,17,39,32,13,21,23,4,7,28,31,8,30,30,28,50,122,125,104,139,107,147,126,184,123,54,15,36,0,19,14,25,30,16,42,11,20,12,36,20,56,21,35,10,8,74,156,185,177,110,110,131,76,137,121,132,100,178,235,217,108,35,45,29,73,130,135,71,57,64,46,79,92,79,80,79,77,74,108,207,240,244,224,219,220,227,230,199,212,204,212,216,203,204,211,199,223,224,222,212,207,199,227,200,215,204,228,205,202,223,217,219,211,234,212,242,206,220,229,130,6,5,8,23,4,17,16,17,1,16,19,16,11,12,4,2,2,0,18,1,10,4,24,10,204,191,207,185,213,183,224,183,171,185,191,230,221,206,199,197,188,193,197,181,194,203,204,192,192,210,194,198,194,214,216,190,182,185,204,190,206,188,207,178,205,193,217,209,207,196,211,205,198,213,199,176,179,186,205,184,213,223,207,202,168,199,223,210,205,200,193,176,191,193,202,184,199,210,205,201,207,211,197,192,170,214,220,210,211,216,193,207,200,194,184,201,193,212,223,230,213,206,205,197,168,219,226,200,179,202,209,211,225,218,202,206,201,213,204,198,208,212,209,195,207,200,199,195,208,221,234,207,221,209,224,203,209,230,183,204,227,212,228,186,211,195,209,192,232,209,214,212,210,201,218,197,218,216,215,215,202,215,191,234,231,188,188,202,204,210,213,187,221,211,201,197,203,204,224,222,225,215,198,209,206,198,231,226,192,212,214,216,202,193,217,197,205,207,208,199,196,211,213,211,211,228,224,218,242,211,220,221,198,224,195,212,203,208,192,213,209,191,234,200,189,217,222,193,208,207,217,185,198,210,195,209,208,208,204,198,201,231,213,194,204,221,231,216,233,216,228,223,219,214,229,205,184,199,184,237,185,213,217,200,212,207,208,182,213,199,215,194,213,217,193,220,202,208,204,191,205,209,201,215,193,210,217,211,205,196,203,204,211,199,200,190,226,222,196,202,214,217,197,221,222,218,172,193,230,187,149,200,151,211,161,123,205,192,207,203,197,148,80,77,68,61,134,211,186,212,176,192,203,207,225,210,103,133,142,143,200,180,216,208,146,145,242,145,99,117,99,109,55,16,25,102,166,131,175,212,163,185,228,213,224,212,223,144,189,243,175,114,115,132,158,254,228,131,52,30,10,12,12,12,11,21,23,25,12,22,9,8,23,25,0,33,14,12,11,40,42,3,36,48,63,50,77,75,47,74,54,50,11,20,12,52,120,41,65,119,69,101,80,100,99,108,114,123,101,78,142,211,195,144,80,70,66,95,90,88,86,62,31,19,39,6,28,10,37,128,142,69,16,38,10,52,125,79,100,72,54,69,27,56,35,38,73,22,26,32,11,13,32,49,25,34,29,41,43,10,38,56,31,25,31,24,24,23,104,93,51,70,61,38,39,54,65,23,44,39,41,23,39,77,67,80,64,109,105,137,144,188,166,194,215,218,214,195,199,180,195,174,153,173,137,151,169,162,201,206,169,188,175,187,158,164,176,186,137,178,167,183,156,149,138,106,94,87,83,110,108,84,100,112,182,163,183,145,129,103,120,89,70,60,58,91,148,189,140,132,138,113,122,118,79,37,24,26,24,19,39,37,18,56,36,11,33,13,25,42,39,1,23,27,9,47,138,128,63,50,60,54,108,95,68,52,14,13,20,32,27,39,9,27,24,39,13,16,22,11,29,16,15,30,55,88,193,205,228,204,226,212,167,190,156,99,82,161,198,75,24,27,25,46,132,156,61,62,118,122,89,89,65,86,65,53,88,76,97,228,229,229,255,231,229,236,216,208,219,192,227,218,219,205,213,211,214,229,235,222,228,222,205,209,214,203,219,220,203,194,216,222,214,208,243,210,219,213,218,113,11,35,6,12,24,22,13,12,30,27,12,26,14,13,7,27,4,1,24,6,10,46,4,3,189,202,190,195,209,202,187,195,186,208,202,198,168,190,194,212,219,207,203,192,184,195,190,217,201,191,195,187,197,173,200,216,196,205,207,195,188,184,177,204,185,178,195,230,222,205,193,195,199,201,208,185,218,221,199,187,189,220,200,176,189,198,202,210,187,198,191,194,183,221,202,224,197,201,205,219,203,221,217,184,203,207,189,198,194,198,203,181,218,176,215,208,207,209,197,196,206,184,195,193,194,203,195,205,212,193,196,214,208,189,190,204,191,185,214,207,169,193,210,204,197,211,200,208,179,200,183,191,195,210,179,196,185,206,211,230,205,215,218,192,204,202,213,221,206,203,180,228,213,193,182,213,202,217,190,216,221,209,182,221,208,215,198,221,215,202,200,205,200,204,201,222,205,211,199,203,214,202,204,204,195,213,207,225,215,200,181,213,196,208,221,231,211,215,220,201,203,216,213,218,198,182,212,204,203,197,205,229,216,201,228,208,224,210,196,207,201,209,214,211,237,177,216,216,193,202,221,210,203,194,223,208,230,215,203,198,213,195,207,220,193,230,209,214,222,203,232,200,196,199,189,200,207,204,218,213,209,225,222,201,205,195,192,224,189,205,219,179,185,209,227,220,216,203,198,200,220,220,195,224,201,225,209,216,220,182,185,191,220,218,195,199,217,200,219,196,246,197,203,215,217,210,165,183,218,217,173,207,192,207,157,156,181,178,204,167,214,195,93,42,38,29,152,252,172,227,177,202,200,210,242,179,130,139,161,157,168,207,159,163,153,165,238,131,105,75,72,88,80,74,7,111,192,174,188,223,168,217,233,216,216,227,197,139,173,231,200,127,111,69,150,212,135,75,39,7,13,45,30,20,60,5,2,6,10,28,17,8,18,12,9,21,10,22,28,20,27,35,48,62,26,54,55,97,68,65,27,41,23,23,32,80,80,15,83,127,84,81,113,129,108,114,107,99,129,110,122,148,180,148,154,88,76,89,95,60,98,43,27,19,64,33,60,65,103,164,105,30,12,25,0,88,112,89,110,48,53,67,56,46,35,59,59,22,17,23,36,12,26,60,37,41,37,49,38,41,23,50,53,35,38,41,30,62,124,144,83,126,53,80,118,105,91,69,91,134,100,168,192,202,202,224,218,211,198,177,202,202,210,193,174,188,191,141,131,77,123,85,58,70,72,59,61,62,71,96,100,65,67,59,49,79,44,63,90,72,62,58,71,72,38,47,96,68,77,76,106,86,120,128,143,144,153,155,185,185,195,200,186,160,175,119,203,186,182,163,145,135,142,166,139,54,36,58,33,34,16,35,28,11,39,38,40,20,40,40,19,47,25,42,21,102,93,97,45,44,42,71,46,64,63,34,12,27,16,24,30,25,22,24,21,61,27,38,39,28,13,27,25,24,18,79,151,182,190,191,203,179,190,194,135,121,87,153,140,21,40,39,40,76,134,130,46,65,140,105,129,123,84,103,31,41,63,38,43,171,209,205,227,235,236,233,206,175,220,226,215,182,181,217,217,205,215,200,214,217,213,208,219,220,197,197,214,206,223,216,232,221,222,229,221,182,230,227,216,119,19,0,9,14,15,6,12,21,43,2,6,13,13,14,24,7,7,19,10,1,1,10,24,6,204,187,235,198,191,201,185,188,213,192,199,219,202,192,196,187,204,208,174,173,196,229,196,202,206,203,200,221,202,206,226,215,169,194,192,209,210,196,179,178,192,208,202,190,198,199,207,185,206,195,197,213,210,192,190,194,196,211,210,215,204,188,212,191,194,202,213,181,197,187,204,216,192,203,211,184,212,210,210,193,220,211,213,226,205,185,210,202,208,186,200,198,182,194,224,203,200,183,200,215,189,199,190,198,193,201,216,213,221,199,197,216,197,223,213,164,194,210,197,204,198,197,220,209,206,200,177,202,235,196,212,206,220,209,213,211,205,201,218,191,188,201,201,208,193,207,206,201,188,221,203,196,197,229,220,180,197,191,223,192,187,189,199,203,225,220,187,208,229,218,206,207,223,216,213,200,202,194,222,229,224,203,196,235,225,208,187,221,213,181,225,197,201,196,215,204,216,204,218,217,212,204,216,223,219,209,198,203,208,174,190,198,184,204,176,203,221,218,209,223,200,237,208,224,209,217,210,211,202,220,231,219,221,196,241,204,188,211,223,211,221,176,207,193,219,215,232,180,217,222,210,213,199,211,185,192,187,216,198,195,204,190,236,195,195,218,201,225,204,211,204,198,181,213,212,218,214,200,233,199,200,198,239,210,212,181,213,187,213,231,203,188,206,178,218,200,214,199,206,214,199,209,172,192,229,203,191,200,191,163,145,123,146,125,151,173,217,171,102,75,25,45,125,241,218,195,170,198,207,192,181,202,196,160,182,207,172,187,142,186,135,177,236,152,98,60,93,113,99,46,50,188,213,206,205,208,154,223,223,202,202,214,153,125,163,213,175,114,100,69,66,90,67,36,8,19,17,17,41,34,17,25,41,13,26,27,8,16,13,39,15,5,18,29,26,18,18,71,17,28,66,85,64,70,75,49,36,19,53,78,71,155,103,63,122,130,111,114,103,133,119,130,98,119,110,112,110,143,132,147,109,72,68,74,66,37,60,54,46,33,34,41,101,140,114,44,7,23,33,14,30,85,116,74,120,50,73,41,38,34,50,66,76,57,12,16,35,20,25,33,32,54,51,50,20,67,84,64,84,72,68,82,96,144,179,172,172,201,168,200,173,179,183,161,176,182,176,196,199,169,163,149,152,121,113,113,69,63,91,67,56,64,68,71,54,72,60,41,60,75,44,63,77,105,79,90,70,79,73,72,98,82,87,83,41,84,75,54,72,65,66,74,94,62,52,72,56,44,60,58,65,59,83,70,63,96,82,92,95,123,127,127,122,123,92,100,105,111,124,158,154,110,117,138,143,86,67,82,59,58,58,41,44,18,68,44,36,40,34,36,22,113,122,104,63,50,47,42,54,30,57,41,37,17,26,6,18,25,27,6,25,39,37,6,14,5,20,35,47,16,10,46,134,143,123,136,121,154,167,121,121,105,85,127,102,33,40,32,3,80,151,70,58,55,70,79,113,109,56,68,66,65,79,40,20,117,112,138,138,164,202,237,226,195,196,214,213,227,215,213,191,195,235,218,220,221,199,209,210,220,197,208,237,223,237,222,215,206,220,189,223,214,221,220,229,119,30,6,1,9,27,10,16,5,54,22,0,25,9,2,10,11,27,13,25,4,13,6,2,13,218,217,191,197,204,185,208,226,174,217,204,205,185,199,205,189,197,180,186,202,199,195,206,198,205,207,191,190,204,203,215,213,212,235,213,184,205,192,219,189,211,191,233,215,180,210,195,225,194,233,220,200,209,202,188,199,226,201,189,176,204,172,210,205,219,202,226,203,187,193,210,206,220,196,219,195,192,220,211,192,207,196,189,217,179,212,196,191,202,215,196,181,202,190,209,184,175,195,202,202,202,213,195,196,206,207,225,192,187,199,199,202,212,180,197,202,214,206,197,214,207,215,182,226,195,170,192,204,212,200,205,221,198,201,201,192,190,219,182,199,187,211,205,251,209,186,219,235,214,198,192,214,205,210,207,209,202,205,216,199,228,201,189,192,184,184,163,198,212,203,191,193,198,220,235,209,212,194,202,211,203,190,208,192,207,223,226,218,209,197,230,211,206,218,214,200,206,203,210,192,195,213,217,206,210,197,194,196,218,185,238,207,202,207,205,198,215,200,232,199,220,197,208,175,211,193,225,205,213,206,212,185,205,177,206,186,202,219,231,188,221,195,195,207,209,202,195,209,204,188,214,203,211,192,206,205,211,200,193,229,189,227,197,175,194,205,231,233,196,200,202,207,207,196,166,211,235,205,210,195,165,214,190,210,217,191,209,181,200,190,196,203,207,208,206,206,212,213,196,203,199,192,163,202,220,182,149,169,144,116,102,131,139,151,183,182,235,201,99,31,7,27,140,198,216,208,194,225,199,214,194,227,233,175,185,194,170,174,181,182,138,141,192,126,108,88,84,88,72,66,56,160,212,184,232,198,155,197,186,220,186,216,115,136,223,228,164,84,61,60,100,60,24,14,8,12,47,30,28,15,41,16,32,25,23,25,21,21,20,36,10,11,23,13,32,34,36,43,40,54,71,55,83,64,78,36,47,68,116,141,149,135,140,129,126,112,119,101,81,118,121,130,115,119,77,56,88,64,86,98,73,41,32,42,39,18,14,13,21,87,89,150,143,55,52,5,5,43,15,5,40,100,85,92,135,48,52,34,58,78,111,108,97,29,47,48,65,44,72,71,136,126,156,145,191,178,208,219,193,187,204,178,168,160,171,157,128,137,133,116,128,142,120,95,51,76,117,91,35,57,68,66,67,80,64,73,72,67,48,52,97,68,90,37,52,55,67,58,44,68,24,38,70,66,63,60,34,56,38,53,35,31,48,51,7,29,35,33,40,57,66,21,44,64,51,42,53,68,54,38,46,50,78,43,52,69,65,62,56,52,29,40,63,73,82,60,49,64,79,106,99,94,148,195,171,166,143,148,145,149,135,132,74,77,75,93,67,57,66,48,39,98,161,143,109,93,85,84,54,86,70,28,26,10,39,52,21,45,35,29,38,31,32,42,47,38,35,34,11,32,31,67,107,74,35,46,58,58,49,59,65,114,94,110,106,27,30,14,20,77,159,130,82,68,59,27,112,60,57,64,45,72,87,83,54,79,69,23,57,66,173,223,207,227,211,194,220,226,222,191,207,202,205,220,221,218,208,230,182,235,198,197,209,217,213,234,200,209,227,181,231,214,203,223,226,130,1,12,15,1,8,34,15,36,12,22,12,32,1,2,16,4,47,7,24,20,2,16,32,5,204,215,186,196,171,202,193,178,200,194,199,195,197,187,207,210,201,205,220,209,202,193,198,194,202,202,189,176,207,204,205,206,193,205,208,202,191,189,213,210,213,169,207,194,194,207,177,186,217,201,231,216,192,190,196,201,188,196,222,194,183,227,198,193,176,215,214,203,177,196,210,172,204,210,184,190,194,191,188,178,207,224,194,184,194,202,198,205,188,201,216,198,180,205,193,209,204,211,223,207,208,210,206,190,200,193,222,187,190,213,232,180,184,199,179,196,206,195,203,195,227,215,189,202,195,192,201,198,230,201,203,201,206,203,204,192,205,204,216,219,207,202,207,210,185,219,204,226,217,202,199,196,213,174,211,200,200,198,193,213,201,222,210,191,221,181,181,221,197,202,218,189,219,212,195,225,209,221,190,207,207,198,195,202,192,189,205,206,228,198,197,213,210,181,220,213,234,183,190,220,203,199,202,203,179,190,227,190,225,203,214,196,215,209,204,205,217,191,205,230,205,219,194,206,211,195,204,206,194,206,209,219,189,207,204,194,202,213,200,211,208,204,199,208,218,198,205,204,186,223,223,199,188,206,211,214,220,215,198,195,223,175,209,176,213,190,202,213,201,223,220,187,200,200,203,198,203,218,202,208,198,204,212,204,219,226,207,200,202,205,188,210,180,191,248,185,200,203,210,196,204,189,154,223,185,125,115,121,171,117,87,173,196,180,205,241,246,187,107,52,57,50,143,246,247,204,203,220,250,247,174,121,153,111,128,148,181,189,177,193,69,83,162,145,119,102,98,81,42,43,82,137,181,191,224,183,157,231,190,199,201,212,131,197,215,213,226,88,68,51,57,40,6,9,13,7,26,10,31,31,29,17,14,34,22,27,28,23,22,11,20,11,13,33,50,42,27,43,66,85,76,79,117,145,138,121,176,127,169,159,136,142,130,115,88,91,85,89,65,62,95,126,119,100,38,42,50,17,49,70,60,32,41,18,25,17,52,46,54,68,87,78,11,23,3,30,33,12,48,15,61,132,91,90,108,80,95,117,162,160,199,191,188,143,180,194,218,215,199,192,215,171,184,167,188,184,178,162,154,100,86,97,72,57,92,76,62,63,58,27,61,70,63,87,59,81,101,56,87,90,86,75,56,73,66,48,29,57,41,47,69,45,62,35,39,24,8,30,52,30,17,13,14,11,31,23,28,3,40,16,11,18,9,9,16,14,46,24,20,35,27,23,11,19,43,9,25,9,23,37,22,44,37,24,25,48,36,67,68,79,59,72,68,55,90,80,72,66,41,76,63,57,61,63,85,60,83,114,119,147,170,138,141,152,162,160,139,127,128,109,132,165,188,199,177,145,151,161,153,147,95,24,40,35,27,13,40,20,51,47,51,13,51,34,19,20,52,38,36,34,12,71,102,46,48,31,44,44,59,41,36,53,82,124,94,49,36,24,24,59,107,115,99,77,35,19,26,41,58,54,62,60,77,68,59,66,54,43,52,47,106,203,236,231,224,227,227,215,242,199,209,208,216,222,216,205,233,209,224,203,212,220,206,214,233,194,206,217,211,218,242,211,230,210,240,116,12,2,5,21,3,33,5,3,22,18,23,25,4,9,4,8,12,0,4,12,7,8,10,11,199,187,203,202,193,172,185,191,181,184,236,194,202,188,235,186,183,221,200,185,186,186,195,183,202,218,199,184,178,209,189,213,217,191,195,204,192,191,208,195,214,190,185,198,206,195,191,215,192,188,192,186,182,201,221,198,193,205,224,194,189,197,205,214,185,213,209,205,201,187,206,211,204,189,216,199,199,198,223,178,201,166,212,190,218,210,204,193,191,178,214,190,208,184,198,224,234,211,200,220,203,198,188,197,221,206,209,197,180,196,199,224,195,183,229,220,221,209,219,189,211,210,206,193,193,192,222,210,209,188,197,202,214,206,205,209,190,192,225,211,215,199,202,197,225,186,186,189,188,203,219,225,215,210,214,220,195,179,203,182,197,202,212,201,214,210,220,208,209,212,208,231,208,184,191,216,227,193,204,208,216,192,203,210,206,176,215,195,197,198,203,213,185,206,177,195,193,202,234,210,224,204,206,210,192,196,184,246,204,184,178,218,206,228,200,179,183,207,196,197,193,212,178,212,207,220,196,202,203,195,195,192,206,171,215,196,222,218,198,209,182,178,211,223,218,201,213,201,208,214,215,208,198,202,217,211,198,200,215,198,207,192,179,207,221,243,208,199,200,195,196,222,225,187,189,214,217,176,206,190,198,208,216,196,231,205,205,194,215,190,213,207,168,219,207,215,200,205,218,211,211,154,157,211,207,104,94,153,168,97,109,170,175,166,179,194,173,138,90,74,109,72,81,192,201,141,147,199,222,213,109,65,61,51,105,199,239,207,173,141,111,103,213,147,115,117,73,71,49,84,49,93,177,225,244,172,178,215,185,185,230,188,135,201,215,216,210,114,66,27,23,4,10,32,27,6,14,6,32,30,20,36,34,24,21,42,38,22,6,5,20,3,35,44,53,30,42,79,96,67,80,148,176,172,164,169,145,121,129,129,104,107,67,71,58,88,80,58,63,56,79,79,83,79,34,39,66,35,81,61,73,45,21,13,47,25,53,71,77,57,5,63,17,16,7,18,8,5,15,9,56,93,105,114,115,150,186,163,209,180,183,157,183,152,182,157,180,141,108,121,111,125,68,49,86,50,44,76,47,63,59,60,40,59,56,65,54,67,67,71,83,93,76,84,41,67,63,47,47,62,53,33,24,27,32,30,29,3,18,17,14,8,32,26,23,15,9,5,5,9,8,42,43,20,36,15,14,32,24,16,16,8,29,39,35,24,7,23,30,24,15,13,18,20,10,6,3,8,21,28,26,17,34,34,11,22,37,20,33,20,37,27,49,22,50,46,49,50,35,49,53,64,60,88,82,77,88,71,81,28,60,75,70,96,125,109,126,120,135,156,177,144,140,128,124,144,167,144,165,152,131,66,56,53,47,69,70,38,56,48,16,40,23,59,29,16,51,24,18,34,38,108,85,86,94,55,62,45,68,40,55,108,99,92,109,50,23,21,11,20,68,105,118,83,48,54,44,23,58,35,73,36,50,62,61,70,72,59,61,55,100,232,246,233,252,232,243,217,229,222,230,200,203,239,212,203,214,229,207,224,208,199,206,243,204,208,199,205,215,187,218,208,235,215,215,120,14,15,9,7,26,9,15,9,19,8,26,29,4,22,25,21,8,13,0,9,10,12,27,24,192,186,212,215,208,200,184,206,190,182,203,180,182,160,221,196,208,204,215,205,201,222,196,181,203,203,197,201,176,183,186,197,187,203,190,205,179,219,223,182,178,196,189,185,198,212,188,196,197,168,176,200,200,206,203,202,203,202,199,199,189,204,208,200,212,189,219,230,188,191,193,183,202,193,234,200,179,205,185,211,221,212,211,202,189,195,202,192,232,193,211,181,178,234,202,186,212,210,200,206,196,181,193,218,201,193,202,187,209,194,197,218,200,220,196,187,176,197,192,200,192,215,194,209,193,181,213,219,189,213,208,190,167,221,185,180,217,207,189,209,216,200,175,231,233,207,203,205,197,212,209,202,197,215,202,203,222,200,189,218,211,181,198,189,193,204,209,204,212,210,229,188,197,203,189,220,217,196,209,202,188,184,196,203,189,187,197,196,196,215,199,217,204,197,194,205,228,203,196,204,200,204,232,197,216,204,200,187,198,213,206,219,190,191,197,193,202,197,205,207,200,201,211,199,192,197,213,208,198,204,212,193,194,211,214,213,182,198,193,212,213,175,176,184,205,234,193,185,210,200,209,197,234,190,197,189,199,193,190,206,213,188,205,210,211,203,234,226,219,233,208,224,191,208,172,202,203,232,217,214,174,200,209,194,203,211,228,216,218,238,199,205,189,189,204,237,221,211,203,214,194,190,178,191,161,98,91,130,126,103,113,134,159,128,121,144,109,86,72,90,135,83,51,63,93,25,51,40,75,83,71,49,28,43,87,189,213,177,151,141,119,157,248,127,76,89,105,97,91,66,36,138,215,226,227,160,163,196,183,206,232,157,140,232,215,222,225,114,87,3,26,0,13,22,17,46,61,30,10,12,16,28,21,25,12,20,11,42,33,21,29,34,27,40,55,31,41,70,58,37,87,165,183,171,163,150,74,88,132,78,69,36,50,57,46,78,81,69,70,68,57,57,73,76,69,75,30,35,136,124,64,25,11,42,41,36,31,50,40,27,12,13,19,28,15,21,16,18,18,5,97,105,84,102,129,129,132,73,76,92,76,55,52,62,60,32,40,54,59,44,74,60,53,60,56,57,35,55,57,49,45,50,35,46,33,6,11,24,58,37,41,30,42,48,24,30,33,26,28,4,29,23,6,17,23,42,40,26,21,34,8,21,19,32,50,16,35,1,31,3,24,39,25,16,16,31,1,61,21,38,43,48,21,31,27,2,15,35,29,27,17,44,49,30,41,18,16,15,16,20,47,27,41,8,3,28,21,20,19,28,19,9,14,36,6,25,12,4,45,30,45,39,39,59,35,50,54,73,80,82,49,62,68,71,68,83,66,71,65,82,73,76,63,88,55,86,91,91,93,115,132,140,124,144,154,145,137,168,137,128,120,107,84,79,79,75,70,48,86,38,29,96,148,133,143,123,100,99,76,90,119,120,112,120,61,61,59,21,27,24,18,76,97,115,90,74,70,33,51,22,52,65,63,58,85,53,79,71,99,87,141,198,224,217,237,255,252,246,241,203,228,231,209,215,214,221,214,217,217,225,211,235,209,215,194,221,214,219,217,229,223,196,208,210,231,121,4,1,9,6,22,24,29,3,35,5,10,22,10,1,30,7,30,17,16,20,15,12,41,4,194,196,193,213,206,174,185,187,194,179,186,227,207,211,192,211,219,213,201,174,186,203,216,211,196,203,201,218,192,211,184,208,202,206,206,229,186,202,209,194,154,189,188,211,203,192,193,211,207,209,181,187,188,196,189,196,189,198,203,193,178,198,202,172,178,213,194,197,197,196,189,190,217,191,214,188,221,207,199,225,208,209,189,226,204,224,188,220,218,198,177,193,219,192,188,228,193,181,211,196,179,184,183,196,194,212,226,206,193,196,217,208,216,209,221,195,208,198,212,213,196,194,215,205,216,204,216,200,198,205,189,213,182,213,209,198,202,201,239,221,188,210,197,223,205,211,208,223,205,198,200,224,218,199,195,192,192,205,208,218,195,200,203,206,215,200,206,192,180,203,217,210,211,225,223,197,185,192,202,188,209,194,209,200,214,205,213,220,203,193,215,224,199,217,221,202,219,210,228,230,212,195,191,228,225,224,183,202,219,232,208,219,209,203,217,203,212,172,221,210,211,215,205,194,226,236,225,187,217,200,191,188,175,200,174,195,202,200,224,214,218,201,211,240,201,212,234,195,217,217,197,188,193,204,225,214,209,210,192,187,196,197,219,203,194,200,206,218,186,212,213,203,211,201,204,227,200,201,195,196,210,217,189,234,212,207,213,193,217,218,209,195,192,178,210,197,204,213,203,184,198,174,178,138,70,55,128,89,65,108,120,133,117,97,125,114,61,82,73,90,132,97,51,114,104,97,39,5,0,60,69,50,32,35,59,73,115,177,193,178,147,192,236,127,105,116,97,87,82,71,39,139,236,228,227,184,168,195,212,197,204,114,164,224,208,236,182,95,31,15,57,68,46,40,28,73,30,61,96,47,5,46,21,30,24,42,33,14,32,17,35,33,33,39,31,38,81,107,152,144,110,120,131,142,142,123,67,79,64,61,40,57,36,35,25,37,29,54,29,54,39,45,54,88,70,57,81,159,210,189,127,58,18,39,43,30,12,2,29,12,11,8,21,22,29,29,10,18,6,17,125,118,106,149,90,44,64,66,25,38,37,70,99,38,40,45,50,51,57,70,59,62,37,41,58,47,29,16,37,41,15,26,19,9,35,10,30,35,35,24,32,22,17,29,23,28,37,30,18,18,31,21,31,34,21,2,46,31,31,33,16,29,54,46,44,40,26,27,11,20,18,41,30,7,13,15,14,34,27,26,15,42,42,33,5,5,17,31,26,33,70,71,112,100,86,35,7,46,19,19,19,25,46,15,16,23,19,23,39,30,26,6,22,28,14,23,25,25,24,25,8,14,36,43,32,22,28,43,48,27,40,50,24,43,46,45,68,60,58,66,64,91,41,66,79,57,42,72,71,75,74,68,106,115,155,149,141,149,170,159,165,165,174,178,182,194,126,181,145,151,126,177,187,177,168,176,166,172,160,152,148,164,103,145,133,65,40,51,15,14,7,41,64,74,112,135,95,64,42,27,61,53,52,56,84,68,69,108,85,117,100,97,84,131,161,230,239,243,247,253,240,240,225,249,241,225,213,207,194,185,219,195,175,195,222,201,209,208,217,199,218,207,203,214,195,105,2,28,6,1,10,8,33,0,33,20,11,8,1,13,24,4,0,23,23,12,32,6,19,40,184,195,207,222,194,185,209,199,229,177,198,193,186,204,189,197,191,211,216,199,215,202,228,184,190,210,202,228,229,196,200,204,188,184,210,188,202,202,205,211,187,211,216,205,206,190,209,221,223,195,203,200,228,212,204,209,196,214,234,194,197,204,207,191,222,193,189,200,196,194,188,213,193,214,185,197,208,184,208,214,214,202,188,216,195,206,210,190,231,203,205,212,234,206,174,204,217,213,198,191,215,187,182,196,171,199,201,219,192,201,186,207,207,178,190,202,204,194,195,205,227,188,218,199,213,209,206,164,195,228,201,176,221,188,210,186,181,215,200,203,205,204,202,206,222,209,200,214,225,193,230,211,214,194,211,212,213,202,226,210,196,196,203,214,213,217,216,201,188,203,190,200,205,211,185,202,199,208,185,212,189,197,202,196,200,204,208,203,219,198,217,193,172,211,203,210,214,207,192,220,218,215,196,210,199,202,194,208,211,195,208,198,201,215,213,211,201,208,174,180,217,202,195,197,193,179,225,205,219,181,196,223,201,205,206,203,207,213,164,215,177,189,203,207,229,191,208,206,224,201,206,210,191,225,227,194,202,199,180,217,201,203,204,198,183,218,207,193,204,210,197,184,197,201,206,159,207,203,177,208,186,177,188,202,202,216,222,170,207,190,214,198,202,207,213,214,185,206,197,209,195,157,197,80,17,45,75,87,90,116,156,141,123,114,132,123,70,131,94,98,121,95,103,188,192,158,132,48,32,65,111,105,68,71,50,62,95,161,207,195,140,226,192,109,135,139,114,124,67,84,44,159,225,205,198,141,181,232,182,213,196,96,167,209,226,200,145,62,49,35,118,200,95,70,48,22,70,211,211,37,1,34,17,5,10,3,35,7,45,35,18,33,36,28,42,90,80,125,163,176,126,118,77,100,92,126,84,18,41,48,33,59,71,46,54,41,46,24,53,17,48,20,33,18,41,107,167,189,203,164,89,25,19,1,2,22,0,16,31,9,15,44,52,21,46,14,3,23,10,61,125,100,106,136,66,58,44,52,26,36,32,34,54,60,17,46,55,28,34,7,28,23,42,19,21,26,15,6,25,31,13,19,25,8,15,13,17,25,13,18,4,27,13,30,29,27,29,15,6,34,20,28,30,22,49,40,17,20,27,26,40,51,67,48,56,43,21,19,31,45,8,15,40,22,4,19,24,19,26,23,25,12,45,47,19,13,3,11,50,49,112,139,184,133,95,36,22,15,26,20,13,14,27,29,19,22,1,15,12,11,43,46,40,22,17,16,16,12,32,25,5,23,30,22,22,7,17,31,15,36,31,13,19,25,35,22,41,38,49,24,58,29,58,68,70,67,63,81,60,72,65,57,93,88,65,84,92,101,72,96,102,116,137,124,122,176,158,160,151,147,141,146,147,158,143,135,135,154,145,181,154,124,113,129,131,70,29,16,32,3,30,21,41,43,117,145,116,96,69,79,50,37,33,27,47,71,73,59,74,78,49,60,30,20,72,113,151,157,221,237,243,241,242,249,255,241,216,216,214,201,222,194,201,190,223,197,210,195,220,194,202,207,214,228,219,88,6,10,20,24,20,13,20,2,9,1,1,4,9,0,9,16,10,16,23,1,24,16,0,27,187,209,193,187,210,189,173,189,201,198,215,188,210,194,205,230,193,185,222,202,187,199,211,212,237,196,214,210,181,193,188,201,198,202,194,214,177,184,210,228,166,189,212,195,221,196,203,191,210,198,226,206,194,212,214,197,209,179,198,199,180,192,189,214,195,196,199,197,189,208,166,180,207,199,216,214,193,198,206,221,214,203,201,198,196,201,210,182,196,186,212,183,221,215,189,218,205,180,199,186,188,216,218,205,201,218,217,188,223,198,214,221,203,222,203,186,187,205,183,197,208,199,190,219,196,219,190,195,190,208,192,205,202,207,192,222,200,233,188,182,215,219,218,204,213,204,233,208,207,208,195,188,202,211,177,192,218,206,212,227,188,214,197,196,202,218,203,200,197,211,182,213,216,199,212,188,197,180,191,182,195,217,179,219,204,217,203,189,200,214,214,209,199,189,231,183,200,180,193,209,221,186,224,200,206,202,202,210,217,207,182,208,199,219,202,202,202,217,207,197,204,199,184,176,196,199,198,195,198,224,215,170,193,211,181,223,200,212,227,198,222,222,201,170,199,208,187,181,195,190,185,195,219,222,205,193,213,209,201,219,184,191,181,208,212,219,197,200,183,217,177,187,197,210,194,184,208,220,198,212,202,199,181,205,208,221,192,196,189,217,209,211,221,190,196,207,205,202,187,209,210,178,221,117,30,32,76,124,102,126,137,118,89,111,102,60,76,42,59,77,107,112,60,93,130,96,76,58,69,15,38,73,104,73,90,92,114,155,213,174,103,215,201,114,103,66,99,112,58,60,42,170,235,208,211,159,197,218,197,253,153,95,208,183,231,207,113,52,45,70,206,244,89,43,61,64,164,249,248,76,9,15,12,35,7,34,22,31,18,11,71,38,18,48,87,54,101,62,83,106,138,161,88,90,70,84,47,39,12,43,65,65,78,42,58,57,46,42,50,33,40,29,29,64,51,135,154,132,78,13,32,8,27,10,14,2,18,28,26,54,53,59,51,61,38,44,32,16,18,79,148,100,158,126,70,25,45,37,12,17,18,46,12,55,24,10,19,24,21,19,30,20,15,1,28,16,27,29,12,17,18,17,25,22,21,17,13,6,11,12,9,41,6,7,25,38,29,10,19,4,14,25,34,38,30,9,17,29,32,90,95,116,106,83,89,41,41,22,16,48,28,42,39,43,26,33,25,8,21,38,12,22,10,26,51,28,42,19,44,155,149,127,96,94,77,37,24,16,22,34,11,36,18,9,33,8,2,39,42,9,16,49,14,33,27,11,11,16,19,22,15,21,50,40,6,22,37,19,3,18,27,17,23,33,19,41,25,10,28,18,6,36,26,31,40,36,48,57,42,66,48,66,35,52,94,102,71,110,92,67,62,71,57,58,80,51,87,65,75,77,70,72,67,77,69,123,93,89,93,84,106,84,76,135,137,83,25,9,12,2,20,7,1,29,27,85,96,98,113,88,61,54,39,55,38,56,65,42,68,42,74,74,68,48,28,39,45,69,84,134,160,178,178,168,217,215,252,245,232,233,219,220,230,174,239,224,229,204,204,198,221,226,209,219,223,109,0,5,21,33,21,17,26,11,38,16,5,11,7,9,3,30,3,2,8,4,28,2,7,37,225,218,180,195,202,198,217,183,186,201,205,181,158,206,195,190,204,185,204,213,207,204,198,191,186,200,194,183,190,182,199,184,200,189,199,211,194,204,204,230,178,216,228,190,222,200,197,190,222,188,199,226,210,216,209,197,213,175,205,206,198,221,195,187,199,199,202,207,202,197,210,194,193,200,181,198,221,197,213,197,208,185,163,210,200,200,193,182,192,219,200,205,205,200,191,208,184,195,205,185,209,202,211,197,209,215,209,187,209,203,214,220,210,191,207,185,217,219,181,220,211,200,203,208,208,203,189,196,205,209,217,205,200,199,204,183,245,207,187,209,204,196,209,207,169,192,206,220,214,199,211,173,217,194,209,210,204,203,210,203,205,213,207,202,181,203,210,214,184,189,203,204,207,224,201,200,206,188,213,219,193,225,192,183,208,205,183,210,208,186,226,191,209,172,209,233,224,216,204,185,201,211,197,206,193,195,217,196,213,198,208,200,218,203,220,191,187,224,202,197,188,216,206,197,229,195,198,207,185,183,207,189,201,206,208,198,205,200,190,222,190,197,170,203,203,193,186,184,206,200,210,194,200,212,211,211,199,224,203,198,202,222,204,206,196,192,202,204,210,202,201,201,215,209,208,205,185,178,215,205,196,224,193,204,196,204,215,197,220,214,212,233,176,203,203,181,194,192,215,217,168,202,253,132,82,72,110,137,121,86,108,110,68,31,6,11,43,62,45,32,131,120,7,62,75,133,111,48,39,2,48,73,57,76,28,44,111,114,198,92,123,220,187,122,90,67,84,85,59,77,30,125,237,209,199,148,190,192,189,227,107,93,207,221,238,149,76,49,23,40,123,140,37,43,45,131,230,251,247,92,62,29,17,27,2,47,22,47,22,19,32,63,57,62,79,107,111,55,49,58,114,142,77,68,78,80,100,62,41,46,43,50,68,39,51,43,30,50,43,27,50,33,59,143,146,162,136,66,34,12,19,7,5,32,28,11,58,48,64,36,73,38,57,43,12,14,26,32,32,105,128,99,137,121,43,15,28,16,14,28,40,16,28,26,16,25,21,16,32,49,18,33,17,20,14,10,38,19,14,30,19,28,39,19,30,13,14,24,9,48,48,8,46,14,26,0,1,23,30,4,18,13,33,49,50,36,20,21,31,135,158,181,130,107,116,79,52,18,31,17,30,42,20,5,27,48,30,32,8,8,15,21,42,17,43,33,36,17,81,157,155,158,118,103,95,70,68,39,19,22,11,20,15,11,23,19,1,0,20,5,2,11,28,14,56,35,18,11,47,61,40,52,77,58,33,42,37,20,6,9,25,44,40,35,28,47,27,40,35,12,26,14,36,25,29,47,5,18,28,45,22,34,3,48,49,34,48,76,68,52,33,60,70,70,75,42,86,57,57,75,51,94,67,78,63,69,63,84,60,73,71,43,92,96,113,93,39,31,28,8,31,15,42,24,33,35,62,60,120,130,82,53,76,53,61,23,59,51,40,52,15,40,50,54,48,70,74,46,47,50,67,85,84,117,138,128,220,228,244,232,224,234,219,205,217,224,219,208,216,220,230,227,231,208,245,106,15,4,26,25,33,16,21,21,2,5,12,5,12,0,8,13,11,16,14,2,33,17,26,12,219,158,192,210,190,208,219,188,173,203,204,202,188,201,206,212,211,167,176,204,218,210,175,188,231,209,177,207,195,207,201,207,202,195,196,201,226,197,200,201,223,202,205,203,224,194,211,214,205,220,225,219,197,215,187,207,192,178,226,208,211,211,191,226,207,211,194,198,202,197,183,197,220,200,187,189,179,197,213,197,199,201,194,199,200,200,197,189,206,212,209,208,212,206,213,207,198,219,187,216,196,187,205,170,214,211,203,195,189,202,215,195,194,201,214,200,206,186,200,214,199,205,177,203,195,203,180,196,192,196,215,187,212,192,191,223,223,198,212,197,209,156,198,192,202,210,180,207,195,208,207,222,210,207,209,212,202,209,190,219,202,199,230,197,223,205,192,213,178,203,189,204,203,175,221,196,190,212,198,205,192,199,204,199,212,196,210,203,193,201,211,185,192,197,219,199,203,212,180,196,220,230,191,218,189,198,190,206,210,207,184,203,207,166,192,208,203,215,205,214,191,192,192,192,199,210,213,188,203,209,204,180,207,185,193,199,200,205,193,204,197,192,205,205,209,208,213,213,205,195,198,191,188,198,199,182,194,210,187,191,181,216,202,200,206,207,195,219,169,180,199,202,195,203,196,216,192,200,182,197,168,185,210,192,184,189,207,217,191,185,192,219,209,206,202,171,201,210,209,188,156,194,235,182,117,94,56,92,60,85,78,104,41,36,40,38,24,18,43,61,106,88,59,81,136,148,114,52,29,16,23,59,36,14,37,46,105,168,192,119,131,162,161,115,96,62,89,68,40,52,10,146,242,237,186,124,214,238,214,206,66,107,216,211,167,65,47,41,16,40,42,48,35,47,142,209,247,218,163,189,224,192,116,23,3,29,28,21,34,57,42,60,79,94,79,78,79,92,84,103,76,137,107,56,32,46,55,56,72,41,41,46,41,40,27,53,70,41,37,43,35,114,158,185,122,84,81,26,18,13,13,5,39,35,38,76,75,65,30,47,75,63,56,22,15,6,5,15,43,137,131,104,130,118,57,40,15,20,14,20,0,16,34,5,4,18,14,7,21,30,7,25,9,56,48,6,31,10,28,3,40,46,14,23,12,27,16,17,43,10,9,10,25,14,31,3,3,14,25,8,37,28,18,33,82,43,25,15,37,153,174,140,120,106,111,59,47,30,41,31,16,9,11,41,38,38,37,13,36,5,32,46,53,41,24,34,33,18,69,112,120,120,106,41,81,52,15,34,16,6,36,24,6,11,36,16,32,21,12,29,5,10,26,40,67,24,12,30,46,107,96,116,108,96,95,38,44,9,40,43,49,43,27,7,35,41,22,27,29,20,23,11,26,30,10,19,18,17,16,28,20,38,21,23,28,12,19,30,29,26,14,54,3,28,28,35,46,48,63,46,59,49,56,70,44,75,80,68,73,73,60,87,114,107,97,102,54,11,7,18,40,16,3,10,23,7,42,39,47,83,91,62,55,56,54,43,22,43,54,52,44,33,39,61,63,72,98,82,85,70,56,62,65,52,62,69,96,139,234,226,246,227,223,234,212,225,226,218,211,222,226,229,241,238,228,123,12,7,5,21,4,39,24,34,18,6,12,11,8,0,3,0,20,4,8,30,14,7,5,22,202,189,192,197,204,197,203,193,201,194,197,187,219,190,218,197,202,204,198,202,234,231,204,203,218,201,207,197,170,212,212,194,207,198,202,199,220,215,203,216,180,175,209,201,212,226,198,212,202,191,201,187,207,197,211,155,194,181,242,217,214,212,228,218,207,200,213,205,187,197,210,213,197,214,190,224,190,220,199,205,212,228,198,218,220,208,217,194,228,217,189,225,196,182,216,208,215,184,223,225,184,212,200,185,191,215,213,209,218,191,175,175,199,197,207,186,166,200,198,221,201,192,196,183,213,186,222,201,213,206,203,207,188,187,196,184,200,210,203,204,206,191,215,199,203,188,189,183,172,207,208,195,200,185,203,193,205,183,221,186,205,207,211,221,204,196,216,213,201,194,206,202,185,208,216,209,218,183,209,186,205,191,220,198,196,191,177,183,193,195,203,207,196,199,202,196,193,168,185,205,176,213,207,205,180,203,213,213,197,182,195,217,215,211,195,189,212,187,192,206,210,183,186,208,206,204,208,191,217,196,200,202,193,199,211,208,201,216,195,190,183,206,195,205,199,219,196,182,193,216,209,215,188,166,212,194,203,207,196,187,180,211,188,221,194,225,199,205,197,212,218,230,183,201,205,185,164,198,182,202,184,185,199,219,206,188,189,187,175,217,209,201,191,190,204,189,213,184,203,202,174,173,218,193,157,103,65,86,53,95,61,48,17,15,23,19,29,15,52,50,94,89,44,90,163,194,128,75,59,10,92,53,18,37,93,152,161,172,167,127,125,139,160,164,94,95,55,76,78,66,30,150,233,189,211,147,232,188,219,205,78,159,246,162,88,21,5,23,37,21,22,31,18,148,234,245,222,126,176,248,240,248,222,61,0,16,39,58,62,31,40,68,95,76,79,84,104,89,115,94,76,124,105,35,41,37,44,47,68,41,27,39,45,58,44,46,48,25,27,49,114,174,188,128,39,54,33,7,15,4,9,23,37,68,47,38,29,52,57,43,81,54,66,12,46,15,27,21,56,175,105,92,154,82,29,16,8,4,39,8,51,13,49,14,19,21,15,32,11,22,9,7,17,6,4,19,28,29,23,41,44,58,62,69,55,30,37,13,22,24,26,43,27,19,16,28,19,16,30,10,13,13,20,45,32,62,10,0,39,145,110,129,87,117,67,57,58,32,20,27,41,21,36,34,22,45,47,40,18,25,9,37,54,16,27,70,41,12,70,104,73,128,92,59,69,15,43,2,29,31,14,13,15,33,26,32,10,8,17,15,2,16,31,28,41,38,32,12,123,168,148,140,108,109,87,58,44,34,37,23,33,30,49,10,18,11,29,42,22,31,33,27,37,28,28,22,17,29,34,19,41,22,20,25,4,18,13,25,5,33,21,23,41,26,33,26,8,30,12,26,25,39,19,36,23,59,21,36,41,52,51,65,120,119,115,80,12,14,17,42,54,33,54,29,22,23,32,23,16,12,51,62,52,71,27,50,19,59,26,7,14,41,44,25,63,27,58,88,55,87,72,71,54,43,59,35,87,60,133,180,224,240,219,209,185,202,246,208,227,217,213,209,229,221,221,126,15,9,14,23,11,2,13,38,6,19,5,8,1,13,10,0,8,21,13,5,32,8,6,22,209,183,189,219,154,199,190,213,205,186,188,195,207,215,197,194,209,215,202,216,196,182,195,219,208,215,200,206,210,210,197,159,184,170,193,185,214,198,196,200,185,201,234,203,207,211,203,204,218,215,209,183,221,195,217,219,223,200,220,205,203,208,197,215,220,209,190,234,211,204,200,185,172,236,199,213,215,193,196,219,214,217,226,207,211,171,201,203,192,207,220,235,193,209,204,210,200,208,181,205,187,185,196,204,212,192,216,199,199,201,208,186,203,174,186,203,195,217,194,216,198,215,212,204,190,191,193,194,196,193,183,188,212,197,216,201,184,209,204,202,220,204,191,211,185,191,203,194,227,184,197,215,203,197,216,190,195,217,182,179,204,216,195,168,178,194,213,197,192,213,193,206,230,214,206,199,197,200,196,195,186,194,197,203,197,205,185,190,196,204,164,198,215,198,207,186,189,190,230,191,212,194,187,194,235,205,230,205,204,201,186,184,208,189,204,210,182,215,217,198,213,207,205,189,206,175,189,210,203,212,192,202,205,180,185,205,200,187,223,197,194,198,195,204,218,225,219,200,207,198,205,194,197,192,196,194,213,220,209,209,199,211,190,184,209,204,215,196,202,186,191,202,213,191,209,187,191,209,194,185,199,196,188,208,209,189,220,196,199,207,225,165,188,205,190,177,209,212,202,210,184,223,238,210,182,135,100,103,88,65,68,48,2,26,52,74,30,17,64,43,70,74,0,80,127,135,96,79,38,16,66,38,73,55,173,242,211,198,163,112,157,170,227,182,76,133,90,90,85,51,4,173,232,208,182,150,205,187,234,153,61,218,184,73,9,9,28,69,21,9,46,62,103,193,237,224,119,136,214,250,237,245,146,59,69,129,115,111,49,38,53,74,83,74,113,96,106,102,98,111,88,100,110,78,72,60,81,61,62,53,58,32,21,49,43,39,27,35,51,104,146,155,81,27,18,15,16,8,13,57,42,70,63,44,55,80,60,73,43,66,53,45,34,11,12,17,23,18,48,138,107,94,152,85,19,8,26,29,20,49,24,31,41,37,31,35,10,18,30,25,16,33,36,19,26,37,26,2,22,14,80,57,88,79,101,81,52,31,35,30,27,35,28,27,13,11,24,29,38,28,9,20,24,33,53,51,13,15,64,109,92,86,86,96,86,36,43,36,49,41,46,30,16,28,14,28,22,34,19,32,22,22,19,25,31,63,45,14,41,92,92,103,125,87,74,46,28,17,19,7,7,9,23,29,39,24,15,21,25,25,21,29,38,38,34,63,47,77,151,173,158,136,83,121,94,34,53,28,35,16,27,56,8,22,16,17,41,57,31,23,15,20,17,37,26,15,26,54,21,40,23,31,31,28,44,5,28,27,14,31,14,30,27,31,52,16,8,45,25,20,31,16,49,21,20,53,35,47,14,21,15,36,92,105,97,115,73,42,25,5,27,28,74,66,32,22,27,21,16,12,37,30,14,20,41,51,53,34,31,28,70,13,20,45,48,47,81,64,79,59,82,45,54,39,92,64,74,35,48,51,101,184,197,223,224,219,201,245,235,217,212,215,212,224,228,98,10,5,6,26,6,10,10,23,19,13,23,30,7,0,9,4,26,5,47,31,29,10,22,28,191,200,186,195,191,185,167,195,214,216,171,199,211,214,204,176,212,196,193,202,198,174,205,202,179,227,217,209,190,206,196,208,216,204,211,188,194,200,207,202,198,200,196,205,187,206,173,200,202,197,199,216,211,197,192,214,206,227,227,187,203,218,204,214,210,194,215,201,223,209,199,202,222,204,202,189,188,224,210,196,225,205,214,205,206,218,198,193,215,214,203,199,227,200,193,185,189,206,203,228,225,199,191,199,218,194,207,210,213,183,202,192,192,204,193,184,208,204,194,205,187,184,193,234,181,199,199,207,225,200,211,217,214,181,200,163,218,198,193,180,218,202,201,207,175,212,190,208,199,209,193,197,197,207,198,185,204,201,214,210,207,203,210,207,200,234,202,207,188,188,179,201,172,171,208,197,193,192,180,187,202,184,191,193,205,199,199,204,192,177,203,173,194,168,200,201,209,197,205,214,207,216,200,181,194,204,194,196,182,193,188,212,217,201,194,206,200,195,166,212,185,194,195,206,202,201,212,192,230,199,201,195,197,200,198,195,183,185,184,183,191,185,203,210,208,183,202,220,165,206,212,195,156,209,208,208,208,174,210,198,212,200,194,217,188,178,209,202,200,177,200,202,222,213,203,174,176,203,205,197,201,197,229,221,193,196,192,206,193,187,220,203,211,195,200,200,211,189,191,201,179,199,191,173,144,117,173,131,152,126,143,95,53,83,93,126,95,66,76,51,68,59,18,63,152,138,100,136,82,40,67,124,175,171,246,190,185,132,155,146,139,196,220,137,86,137,98,98,69,42,9,164,188,214,184,149,199,184,247,137,63,187,85,17,8,85,177,112,66,40,38,125,204,233,218,156,161,208,249,223,214,155,75,125,132,113,128,102,44,88,124,67,18,58,115,105,102,101,104,119,82,100,64,73,46,46,48,67,32,36,29,22,9,11,12,18,24,104,157,153,123,89,26,9,15,6,10,19,17,45,47,67,65,52,68,61,60,75,75,70,32,22,15,33,20,13,38,2,95,147,105,126,128,59,24,28,5,38,36,16,30,23,14,27,12,16,7,48,24,24,19,30,19,22,16,13,23,55,22,62,100,79,82,112,67,54,27,34,34,26,25,4,32,22,20,17,42,8,20,10,30,61,40,48,32,41,46,10,41,74,57,86,110,158,77,15,49,27,32,14,36,29,33,42,3,10,24,19,34,38,22,26,1,27,15,60,50,10,49,59,50,91,80,86,61,44,33,28,24,20,26,50,36,11,33,12,14,22,21,30,48,19,18,12,68,52,31,99,160,136,142,124,114,73,65,41,39,28,17,14,31,4,23,31,42,32,18,9,22,36,11,15,50,41,32,5,23,67,42,48,41,28,16,12,31,9,20,24,32,29,27,33,35,18,34,32,23,13,24,29,22,39,50,3,38,49,12,5,32,21,54,56,120,121,104,115,67,33,14,41,28,36,72,65,74,71,48,37,9,24,28,36,33,22,20,30,24,41,65,64,55,41,51,31,39,38,34,79,19,73,26,50,48,49,63,55,64,3,49,47,33,177,196,236,227,233,225,238,225,231,220,232,209,217,224,126,13,20,24,5,6,1,31,0,19,40,6,17,2,8,24,13,7,2,22,19,0,5,21,3,199,184,174,206,204,198,203,206,193,223,223,192,201,186,179,211,177,212,197,203,185,179,207,179,194,197,203,205,228,180,171,182,187,206,186,212,195,166,195,215,199,179,223,189,222,209,201,211,227,195,198,208,222,202,222,186,221,183,207,209,184,198,209,215,199,210,198,208,207,195,191,198,210,230,197,207,192,215,200,220,193,187,208,203,205,190,200,215,202,207,195,195,214,196,180,206,193,216,199,190,213,212,199,191,217,193,194,193,215,203,200,192,200,204,191,195,212,223,205,201,206,201,204,216,196,199,191,196,204,178,208,208,187,193,193,202,191,210,202,213,198,207,221,197,187,209,213,192,199,199,193,200,181,210,200,196,201,198,188,202,190,211,208,197,211,204,188,183,194,187,206,212,193,201,199,180,187,211,213,211,186,200,206,195,181,198,201,186,202,173,188,187,190,204,196,200,196,191,197,192,205,189,205,196,217,200,195,192,180,183,194,203,221,214,200,203,205,171,205,165,225,196,180,195,197,199,219,199,184,203,199,187,209,197,198,186,195,192,202,192,203,198,188,221,190,191,204,203,193,192,177,211,200,205,196,222,203,189,193,178,217,223,204,198,212,186,198,217,168,190,201,194,214,197,206,184,204,186,212,167,170,195,186,200,204,199,190,198,198,195,171,190,192,186,177,187,192,189,224,198,181,218,199,157,110,156,180,197,216,186,165,205,137,107,186,186,173,93,119,36,144,92,5,114,172,138,173,243,163,67,57,185,236,234,211,187,140,136,188,155,128,177,179,100,95,121,99,86,60,23,22,136,236,214,186,132,233,223,239,127,61,138,24,20,29,125,230,155,106,39,97,214,242,246,165,179,218,245,252,175,120,47,72,146,89,119,84,61,72,134,88,47,49,83,90,72,70,63,70,100,85,83,95,75,72,77,70,48,34,35,23,25,21,34,11,18,60,135,154,159,107,25,25,7,33,15,41,38,34,49,60,58,80,72,49,63,73,63,86,89,80,71,29,47,23,31,18,42,142,167,105,103,139,63,34,37,40,64,20,16,55,9,19,21,30,30,45,19,13,15,24,6,31,23,51,39,39,36,33,131,135,142,108,65,58,54,56,20,29,0,10,19,28,33,40,23,53,24,35,12,29,37,32,30,5,59,61,57,37,66,80,83,170,108,34,41,48,7,4,37,28,19,35,31,35,6,15,31,54,28,49,4,26,19,33,92,52,40,59,59,53,42,68,52,13,47,14,19,33,1,3,51,58,45,4,24,15,42,29,32,1,20,11,31,59,81,37,91,141,116,107,93,81,96,72,23,7,12,23,48,15,31,2,5,40,34,44,29,23,22,33,17,25,36,69,28,15,38,70,50,75,68,49,66,68,36,47,44,16,29,24,29,25,17,27,24,20,39,12,30,39,33,7,20,22,7,29,30,11,27,31,84,125,112,106,118,49,28,9,16,15,49,60,68,83,59,65,65,24,41,22,31,36,28,0,18,6,38,46,53,47,79,75,46,23,27,28,66,70,49,54,64,50,50,22,40,47,44,73,49,78,151,159,224,223,221,228,226,224,236,226,228,233,210,200,111,16,0,19,18,20,29,23,15,19,10,15,12,15,5,0,18,23,26,17,8,24,21,2,5,214,214,202,218,211,205,227,210,211,210,207,194,192,194,208,186,197,213,215,195,193,214,193,195,195,201,206,224,226,208,205,181,222,195,182,197,216,187,192,219,207,194,180,208,212,216,205,204,208,221,209,206,201,219,208,202,205,227,196,213,200,213,227,214,214,201,190,225,201,198,206,194,181,186,192,205,198,194,181,197,216,224,199,224,234,199,203,212,185,224,217,204,193,178,208,187,223,192,208,207,192,191,206,218,180,192,213,191,199,217,204,221,218,207,210,222,189,191,207,180,203,205,172,202,201,185,205,190,188,207,215,196,221,204,186,182,207,209,205,198,204,193,215,198,194,179,197,178,200,215,185,211,198,199,205,194,213,208,234,187,205,189,188,187,193,182,204,194,223,199,198,199,185,211,208,200,197,208,192,187,208,179,192,222,189,197,208,192,202,182,221,203,203,198,229,202,206,203,195,202,205,190,198,196,215,178,222,202,212,187,174,179,199,209,196,194,219,203,185,217,194,218,199,190,181,194,202,185,163,194,209,206,189,197,216,215,189,203,209,208,165,174,204,203,205,204,202,202,198,193,220,209,202,204,193,196,198,188,192,192,203,165,196,170,202,193,183,175,189,175,196,187,195,210,202,192,171,178,195,201,188,186,187,187,214,185,214,175,196,196,187,195,176,193,212,207,186,199,212,159,188,193,170,160,155,176,187,180,175,147,191,208,149,85,141,241,210,131,134,36,115,136,43,170,172,159,180,211,119,107,123,158,166,182,150,123,174,171,195,170,107,189,172,126,101,101,73,110,58,64,3,143,217,215,176,179,253,190,196,157,50,37,16,8,47,157,132,77,76,62,191,253,246,207,160,218,254,249,246,116,29,60,118,131,138,68,35,71,121,153,77,88,95,99,98,34,117,124,101,76,94,87,117,104,96,78,68,58,52,39,51,28,23,11,13,50,107,157,134,86,46,45,8,35,22,13,9,37,65,77,79,53,62,52,64,69,7,26,66,60,77,93,75,30,30,6,22,39,160,139,84,129,102,35,33,34,97,71,47,43,18,43,25,11,33,5,40,22,53,23,5,11,5,19,43,35,44,38,47,96,146,125,133,82,100,59,36,40,1,18,15,26,31,16,30,19,12,22,26,36,22,16,6,17,28,52,48,32,30,61,75,74,56,62,53,36,39,41,28,25,48,45,7,45,31,43,20,41,17,37,13,16,20,47,48,84,74,46,60,57,35,34,33,30,36,40,35,50,25,12,42,10,34,20,12,21,30,66,26,8,24,21,14,18,64,122,37,92,102,116,73,60,147,121,43,36,29,26,28,7,8,20,44,36,22,22,18,12,0,53,49,15,35,53,53,42,37,46,89,105,122,103,166,91,34,45,16,42,38,8,36,11,19,17,41,10,44,33,38,17,24,52,21,19,46,27,10,44,18,48,9,90,104,99,110,108,65,42,33,22,33,53,96,94,95,81,79,83,61,45,28,20,43,25,36,29,15,22,51,27,26,53,83,61,73,18,27,44,57,31,46,55,33,40,58,56,67,75,45,43,91,195,218,201,205,228,238,213,224,230,227,231,232,201,223,95,16,7,8,1,1,20,0,27,2,11,12,26,8,2,14,2,2,1,12,5,26,7,5,16,195,201,196,197,170,182,193,197,225,216,208,205,210,202,199,201,220,187,181,200,181,203,223,210,195,180,195,191,192,185,213,201,196,195,200,201,194,192,199,211,199,193,189,199,216,194,196,209,196,215,217,190,181,190,209,199,219,204,208,215,226,199,217,222,219,212,187,206,215,208,208,196,220,201,203,196,219,224,219,210,193,189,207,214,208,209,208,210,218,197,201,228,189,176,202,218,216,211,192,210,189,164,216,196,202,210,184,199,208,223,183,195,202,203,209,207,199,186,201,203,203,206,180,202,182,216,191,208,200,203,204,197,216,207,206,205,207,172,209,188,187,215,210,196,184,192,184,202,169,202,203,217,211,211,184,212,203,187,190,183,203,198,184,235,192,179,206,193,209,204,210,199,200,223,201,209,167,184,187,184,196,183,185,205,199,188,193,199,202,173,225,195,201,183,212,222,234,197,193,185,193,189,192,193,198,198,198,169,175,175,187,197,202,185,204,217,203,191,194,179,200,184,199,200,209,223,212,173,196,183,216,211,188,212,194,185,214,207,184,195,207,197,201,185,179,212,170,202,191,176,187,180,202,183,232,186,179,177,206,186,204,220,212,198,220,192,236,221,181,199,186,190,195,191,209,209,169,182,212,170,177,172,188,189,174,179,192,188,207,203,189,195,210,189,210,177,180,196,193,176,188,186,181,209,187,192,164,149,165,151,195,228,212,122,73,168,166,136,94,67,139,87,10,103,187,130,137,126,92,148,201,190,140,131,143,163,176,165,210,106,168,208,194,132,72,91,80,95,56,45,36,160,224,200,188,138,183,99,133,104,56,11,4,21,36,47,37,52,92,176,239,212,218,180,205,248,241,228,189,42,41,75,149,165,90,13,67,115,128,92,46,70,70,157,77,122,165,170,128,112,104,109,108,99,107,95,102,89,63,56,43,49,14,34,30,92,159,134,67,21,20,47,16,23,20,22,27,44,75,96,66,86,58,74,86,93,54,26,30,38,39,40,111,78,28,45,5,60,164,127,113,141,79,52,10,99,107,40,59,38,41,12,25,24,40,5,23,15,32,29,30,32,31,32,40,45,41,36,49,151,137,123,123,94,107,49,49,39,32,25,13,7,46,39,25,8,17,28,16,22,55,38,12,18,23,67,95,36,35,70,31,44,68,26,12,29,47,46,22,27,25,35,8,16,40,28,29,23,11,4,19,36,45,34,58,102,54,17,73,36,45,63,8,28,36,22,53,9,42,26,26,24,30,9,11,39,12,22,44,18,30,24,29,38,83,99,29,58,78,104,89,137,187,91,29,58,26,9,14,20,35,31,18,51,43,17,17,18,47,21,31,38,44,49,57,46,43,74,100,158,130,102,119,85,39,29,38,13,21,21,38,27,20,21,47,53,1,18,48,8,22,46,18,24,34,24,17,11,38,61,21,93,123,112,125,108,92,32,12,10,21,29,51,74,111,87,88,80,81,82,80,42,38,47,19,34,11,14,20,38,51,44,84,83,67,49,37,42,31,22,30,42,62,61,81,93,44,49,62,49,156,232,211,233,219,214,212,223,238,232,227,232,231,198,232,105,12,0,7,2,9,11,28,18,10,31,21,41,36,4,5,15,13,14,3,20,13,24,9,12,212,189,218,195,218,212,177,207,205,199,221,179,211,207,177,218,206,200,216,205,184,193,213,213,201,196,208,217,197,206,220,204,190,210,191,209,205,197,175,206,190,193,223,188,212,205,207,197,209,210,198,195,204,185,231,181,199,187,217,173,180,208,220,208,225,230,208,197,233,195,216,197,215,182,184,209,192,219,163,221,195,211,199,191,205,204,215,199,197,183,191,185,217,201,206,186,204,215,202,202,194,201,194,201,187,197,210,198,182,210,209,201,207,212,193,193,198,197,185,199,199,203,187,208,214,203,200,195,190,202,190,194,181,185,219,210,203,182,189,213,198,197,187,182,200,210,173,195,196,205,192,198,188,202,200,211,200,207,211,189,235,195,192,215,199,219,212,195,218,212,201,190,210,214,213,207,205,197,221,189,221,183,171,211,209,210,181,180,199,178,181,200,200,186,195,188,208,178,204,196,162,206,218,194,177,200,199,181,192,188,204,201,199,185,185,204,191,185,185,186,189,198,206,184,213,243,196,195,212,208,186,207,191,172,211,185,204,185,187,207,190,208,206,199,210,200,198,180,184,196,194,197,191,204,212,196,199,214,185,183,197,224,190,184,170,217,199,204,201,177,182,201,193,214,201,205,189,194,195,199,177,158,199,197,189,165,194,177,195,200,211,209,198,194,193,197,198,202,206,178,192,181,127,114,145,150,147,147,155,150,212,220,195,190,132,34,100,118,102,73,99,82,8,86,162,138,80,80,159,170,215,174,128,174,169,182,157,138,191,144,161,213,193,162,81,103,76,78,57,23,27,145,209,197,178,87,140,115,55,29,8,30,34,62,72,57,35,54,206,243,227,189,179,196,253,238,226,230,65,19,44,123,128,118,54,49,88,109,89,51,49,25,71,117,150,171,222,158,116,119,113,111,105,82,64,82,83,94,56,35,34,16,52,27,73,145,142,101,44,5,34,6,1,45,54,4,35,39,52,90,64,55,58,81,106,56,39,19,30,25,52,59,64,119,54,33,30,98,164,111,96,119,45,42,45,90,87,65,64,32,22,12,7,26,34,37,52,2,10,0,28,21,43,41,14,12,67,63,58,110,108,78,122,95,75,30,55,26,30,16,7,27,20,28,23,24,18,19,35,20,11,46,49,15,11,60,82,55,30,53,18,41,14,44,19,48,46,48,41,33,44,27,17,13,40,66,53,46,30,8,25,47,50,54,83,115,82,19,39,46,41,20,18,28,22,43,34,26,37,39,15,37,21,17,31,29,30,13,4,31,22,78,61,39,115,114,38,57,96,89,89,68,82,43,43,42,31,10,7,20,37,51,23,25,22,20,10,40,29,19,16,7,35,40,85,60,39,94,141,162,169,85,108,104,51,27,39,20,14,26,32,6,31,27,26,20,32,32,31,17,34,41,19,12,27,58,39,25,50,73,26,116,127,101,108,108,96,48,16,10,37,37,25,64,91,111,107,103,65,78,82,73,77,51,12,17,42,17,3,15,25,30,25,65,61,72,62,41,66,19,62,56,58,64,57,69,84,39,52,139,229,242,218,243,247,228,208,228,223,223,234,208,233,226,226,97,4,7,13,19,5,17,24,31,19,20,12,14,5,3,10,11,27,4,3,7,2,10,24,5,208,213,197,197,200,184,208,222,184,204,211,212,224,189,166,195,224,204,197,183,201,207,224,201,226,207,197,210,205,193,198,173,191,196,208,205,201,207,216,190,198,215,202,185,221,224,212,210,220,208,192,228,210,199,212,206,205,222,200,202,227,199,204,205,191,204,227,229,240,201,228,224,233,192,203,209,208,202,208,223,206,222,208,177,191,191,206,177,221,223,188,197,195,191,211,198,201,199,221,192,201,200,191,175,201,197,201,192,187,206,194,184,226,187,184,175,217,199,197,165,216,200,191,177,216,202,191,219,195,199,197,203,203,191,212,195,174,207,185,197,213,179,200,188,211,189,214,218,210,200,231,188,187,184,183,193,204,202,206,219,196,208,201,183,236,190,195,195,192,195,185,192,197,187,191,184,192,191,197,191,195,204,193,174,200,188,201,183,204,207,213,184,219,198,217,190,196,209,191,175,191,200,205,186,198,185,198,210,201,167,187,186,172,199,188,164,206,200,183,202,188,194,185,211,184,192,199,206,196,204,191,196,198,215,204,198,195,194,215,176,188,200,188,205,218,235,173,192,194,211,204,202,179,185,183,187,215,207,192,171,210,194,188,211,200,184,201,190,200,194,195,192,177,197,192,185,196,186,183,185,192,160,188,225,193,215,202,211,228,196,185,206,202,200,189,207,205,176,185,163,195,169,115,103,130,131,127,152,143,195,200,197,233,220,159,99,5,79,100,77,77,79,9,76,102,88,63,99,205,205,196,136,156,202,161,122,170,171,149,114,161,161,191,149,62,119,90,76,46,22,16,164,222,210,185,95,120,119,39,35,0,104,192,72,75,90,61,105,241,233,203,162,212,250,245,246,220,116,42,50,111,86,90,52,84,106,131,73,66,60,50,8,42,97,152,217,216,123,118,108,92,104,73,76,33,72,79,53,66,59,31,23,14,36,73,162,130,85,6,17,32,0,17,47,78,31,39,57,71,67,62,101,101,109,66,25,19,29,11,3,37,34,87,124,59,37,5,123,143,93,115,91,38,37,96,125,101,106,68,27,36,34,17,5,12,10,6,9,5,12,2,26,10,1,14,15,53,68,36,78,71,65,143,111,59,25,35,14,33,3,18,18,22,44,20,7,42,36,15,24,16,39,52,37,21,67,72,39,47,42,22,54,19,16,18,33,53,44,37,18,37,35,15,31,37,35,37,70,43,0,64,46,44,37,76,141,46,30,60,30,34,53,40,40,36,45,28,16,14,4,22,26,14,23,49,20,29,46,31,31,42,51,61,26,94,93,56,65,84,44,23,19,3,28,39,39,17,9,28,19,38,47,29,17,2,17,36,51,13,25,15,27,32,55,80,68,84,124,136,130,128,100,109,114,51,32,31,15,33,11,32,26,63,32,20,37,6,19,32,37,15,38,42,33,44,54,75,81,131,120,93,144,149,107,98,116,111,42,57,48,28,20,43,87,117,121,135,120,81,90,104,80,75,47,69,38,1,27,11,35,42,33,21,32,46,77,61,67,70,41,77,58,77,67,32,43,66,43,70,212,238,234,220,231,233,219,222,225,200,215,218,207,215,217,222,117,22,4,8,32,18,12,41,17,12,18,9,38,3,8,0,16,13,1,24,4,26,17,15,17,200,215,184,191,180,188,205,199,198,177,185,192,218,201,186,218,202,187,204,200,188,207,222,220,202,185,197,216,193,194,198,195,211,215,223,186,212,208,190,182,190,222,230,210,190,193,215,214,209,210,198,234,199,213,212,215,224,201,208,201,194,189,194,207,208,188,208,212,218,193,212,190,195,198,222,209,191,200,223,202,205,201,197,208,219,227,183,178,199,206,191,215,229,200,182,199,187,212,212,206,189,197,214,208,208,198,216,214,192,188,196,223,220,189,221,206,175,200,183,207,214,201,220,200,197,229,207,209,200,196,192,198,169,205,207,200,203,208,207,226,190,175,198,187,210,207,189,201,193,188,217,197,194,212,201,209,184,173,201,191,203,198,202,179,214,180,203,200,210,194,199,194,213,197,196,208,214,196,213,200,207,183,207,202,181,199,184,201,198,212,187,208,182,185,202,202,191,205,186,193,180,198,172,196,186,200,196,182,180,185,170,191,194,217,215,197,188,201,207,180,194,184,196,201,204,180,184,184,193,191,193,198,207,199,208,187,177,200,212,189,206,217,188,200,181,181,220,165,193,202,206,191,218,202,186,197,209,202,200,192,195,182,200,181,205,210,182,188,172,196,205,217,194,186,195,184,165,166,193,193,188,180,193,212,187,191,193,172,196,181,198,194,187,184,165,198,217,202,187,164,168,150,159,160,157,188,169,156,176,197,212,174,216,234,239,135,34,15,90,77,101,82,60,59,74,117,126,148,148,169,208,146,192,184,124,126,164,216,152,106,144,111,191,149,80,108,85,72,54,44,48,167,182,176,146,94,105,88,42,48,8,183,137,84,72,45,150,136,246,205,126,200,241,248,250,219,106,49,91,86,107,47,53,88,129,154,114,80,79,26,36,19,43,101,131,140,141,70,90,109,82,92,88,68,62,67,54,69,68,53,45,37,42,34,119,158,121,45,10,20,4,33,21,67,78,34,28,72,80,108,106,144,147,135,54,31,21,21,12,40,26,70,99,103,48,19,43,121,146,103,100,75,45,45,80,124,76,49,55,40,29,28,24,21,2,44,38,15,7,38,40,9,18,34,18,10,80,75,18,68,42,66,155,105,68,50,51,21,19,38,24,16,39,11,34,51,44,47,12,22,24,28,57,35,22,77,101,29,31,51,34,54,36,26,19,34,43,26,13,52,6,44,52,23,26,5,10,42,29,75,48,23,19,44,100,118,52,38,88,83,83,61,79,61,85,78,63,22,23,5,49,57,47,34,10,6,24,44,22,48,26,30,53,50,120,94,35,49,63,31,19,44,29,29,46,32,34,14,33,60,25,31,20,16,33,35,34,20,29,48,15,43,60,86,111,48,94,144,119,100,78,100,118,78,42,33,16,15,27,22,10,37,33,24,25,14,20,33,36,57,34,34,27,59,77,88,102,129,186,154,130,135,112,131,120,132,121,52,12,14,39,50,50,71,71,113,92,86,95,105,73,90,107,69,69,41,13,39,34,38,31,44,36,19,47,37,69,79,40,71,79,57,47,46,47,23,42,23,100,198,245,235,238,214,243,226,237,224,222,229,245,220,232,221,243,108,7,11,10,21,7,2,12,6,11,10,7,13,6,3,15,19,2,0,16,12,0,8,10,0,190,221,201,216,215,202,195,229,194,207,186,200,195,190,203,201,195,221,189,177,190,197,189,228,196,213,209,217,203,197,182,190,201,211,208,198,204,229,209,192,216,203,204,192,207,193,196,204,194,202,199,202,215,214,195,203,204,201,217,197,212,166,207,222,227,215,218,207,229,203,207,220,196,201,197,194,213,202,230,219,192,181,206,198,175,188,225,200,198,176,212,231,206,221,208,204,188,168,211,181,195,190,211,194,200,223,199,201,219,201,195,208,181,174,194,212,199,198,205,193,193,206,192,193,201,203,189,174,193,178,179,195,181,197,187,201,197,193,184,192,178,180,211,224,193,188,195,209,170,202,192,219,216,200,210,201,209,211,183,175,208,189,216,204,205,201,204,190,189,201,194,190,196,213,210,213,189,192,203,204,188,202,210,191,200,200,177,196,201,209,190,205,196,176,169,185,186,192,194,186,181,192,178,211,204,202,198,204,180,180,200,212,184,187,190,177,193,196,185,206,196,190,167,212,171,190,201,208,164,208,180,175,196,190,190,204,195,217,190,204,189,207,198,182,189,184,179,203,182,209,206,217,193,196,199,174,186,199,192,201,171,193,198,191,182,212,181,207,196,210,199,197,186,198,206,197,196,181,184,204,197,174,176,197,179,191,194,181,211,195,201,183,167,179,194,201,196,210,187,146,159,158,167,161,168,146,177,151,206,187,176,215,182,219,207,212,119,34,46,60,86,112,60,100,116,153,130,138,143,189,165,158,146,147,131,151,184,196,130,97,168,161,214,128,100,131,74,91,70,16,29,133,117,72,149,91,69,50,13,23,20,83,81,79,62,138,217,185,201,202,167,248,242,248,219,90,57,71,117,116,48,49,57,117,147,124,96,97,22,9,3,40,63,89,72,43,35,34,27,78,111,129,121,121,108,66,63,70,83,40,26,22,35,85,129,119,64,23,24,9,25,38,69,41,66,76,56,59,99,117,125,114,84,76,45,14,43,44,41,26,11,75,147,115,16,14,23,142,144,84,121,60,23,28,61,112,82,39,15,29,16,23,15,27,8,57,26,34,41,35,19,10,40,31,26,46,77,86,21,63,50,52,72,25,13,32,32,47,27,6,21,25,28,28,31,14,26,45,35,10,21,55,30,28,38,61,105,38,77,83,40,63,65,12,70,74,75,11,22,25,33,35,35,37,47,28,17,49,51,61,51,27,24,29,113,188,44,36,125,118,167,178,120,190,130,76,38,25,21,45,19,50,60,44,24,34,7,64,32,47,34,14,36,70,131,95,66,51,67,12,22,26,31,13,28,36,30,26,58,8,19,8,20,14,41,46,31,12,21,47,17,64,27,52,91,59,40,76,82,89,82,108,86,66,46,19,9,16,48,53,31,31,24,40,34,14,26,42,43,11,27,39,75,54,99,148,157,144,125,107,65,59,97,110,105,104,109,75,18,24,33,56,38,60,12,67,70,125,123,122,110,118,98,109,70,47,16,13,16,32,17,18,17,28,21,56,56,87,116,84,61,51,17,20,17,33,48,3,141,218,252,253,246,250,235,218,238,248,213,227,221,218,229,215,235,117,11,1,6,18,24,9,45,20,42,30,36,14,18,0,13,10,17,11,24,19,25,3,0,12,217,171,190,202,186,220,215,219,206,208,191,204,189,224,202,225,217,190,212,189,234,200,182,195,191,203,222,184,206,209,198,206,192,200,176,185,213,206,184,186,198,192,207,192,202,171,209,226,187,238,182,187,204,224,211,206,213,209,223,208,203,205,201,232,189,234,226,217,215,221,222,219,227,190,193,219,192,226,197,207,183,206,216,217,218,212,206,203,191,186,188,208,187,218,210,213,208,215,181,192,204,204,218,191,204,192,199,201,194,170,195,212,202,226,210,202,192,178,197,220,200,194,195,213,187,207,175,182,207,165,173,194,177,206,211,203,197,201,196,186,212,206,175,180,185,206,210,183,159,182,182,185,199,174,197,187,210,186,196,197,194,187,186,162,195,194,207,200,191,201,204,190,193,220,199,192,182,208,193,196,204,196,202,179,188,179,206,195,193,196,189,204,186,199,217,224,177,206,188,190,207,198,187,223,189,213,191,195,194,197,192,190,198,170,174,197,195,196,183,197,176,189,187,187,200,217,206,206,172,194,210,185,196,210,207,217,196,208,184,200,211,203,185,225,179,195,186,178,158,206,187,192,194,205,199,198,204,192,186,215,191,203,198,202,187,179,156,181,196,180,181,211,202,184,175,189,194,168,196,196,199,187,162,197,183,188,194,183,184,216,195,193,176,215,192,198,194,204,164,154,159,124,109,125,123,149,126,156,208,214,173,184,181,173,198,215,179,116,119,66,68,75,34,128,139,106,134,125,198,201,186,146,142,179,173,169,211,154,109,121,174,202,224,89,82,122,64,89,55,51,41,117,119,78,103,69,38,30,4,50,73,69,44,24,110,212,255,168,161,179,218,244,251,225,114,65,82,111,117,70,47,82,77,131,111,62,58,52,31,15,18,41,88,122,58,59,60,31,21,59,97,129,115,129,128,102,97,83,46,21,24,29,48,115,146,117,56,10,16,16,35,72,39,48,47,68,127,131,127,129,67,47,33,37,11,21,2,15,34,45,38,121,148,63,27,18,61,170,135,101,115,79,44,27,28,105,107,45,23,43,39,32,45,27,1,30,14,47,64,26,5,26,18,29,81,24,86,80,5,43,22,40,18,25,52,23,44,18,22,12,25,22,16,43,11,38,16,25,38,51,66,37,27,50,29,121,126,31,91,134,121,186,140,114,179,132,50,48,43,11,35,32,34,31,39,25,12,63,42,40,48,47,36,51,170,159,39,26,71,83,155,130,104,148,98,60,33,20,7,46,40,54,28,43,36,23,30,19,49,42,39,3,19,52,139,82,33,68,66,39,39,29,9,48,37,19,29,51,41,20,22,23,36,49,56,19,3,54,14,39,73,35,40,50,82,67,29,59,90,61,161,170,85,30,44,7,13,43,17,64,56,51,6,18,35,46,33,38,35,48,16,64,115,64,132,154,154,139,107,112,59,57,26,112,111,103,92,84,26,52,49,43,27,34,38,37,61,117,131,126,99,93,95,112,78,90,29,45,28,25,27,10,11,20,20,16,43,64,81,87,66,16,10,8,50,60,28,36,180,218,247,252,237,240,243,232,239,212,234,243,206,230,218,235,219,135,12,13,5,18,33,7,14,4,10,11,18,16,2,7,1,0,7,13,15,20,27,5,13,17,207,228,203,216,203,203,211,194,221,212,201,224,204,219,192,201,194,193,198,214,185,175,189,201,207,219,205,172,207,200,209,206,226,208,193,188,183,190,224,202,201,210,209,171,187,221,235,181,194,184,227,206,207,193,191,203,207,218,204,206,204,188,202,213,198,203,216,203,205,218,212,221,201,197,202,216,203,195,198,209,227,211,202,195,208,227,189,202,188,200,215,211,184,204,203,201,189,206,212,210,196,207,183,192,197,226,211,208,198,200,206,186,197,199,205,183,162,197,200,196,184,195,200,207,195,194,209,189,189,191,190,195,201,191,177,205,203,196,204,210,207,193,183,203,190,171,210,202,178,204,192,200,178,188,189,190,216,196,217,199,187,208,217,197,204,203,206,193,202,192,207,162,193,192,182,203,182,178,224,204,201,189,196,189,179,196,187,200,181,177,199,202,198,190,218,179,204,202,177,198,203,191,197,187,192,203,210,187,206,214,188,177,204,194,201,173,186,188,203,187,212,200,192,204,184,193,197,195,180,204,193,195,192,182,205,192,170,209,170,186,197,185,199,195,201,182,203,202,201,175,191,189,186,186,188,183,188,203,195,195,192,214,196,220,200,185,204,190,195,159,188,190,199,175,197,190,184,164,204,190,183,200,184,192,185,200,203,197,178,197,175,193,201,191,171,202,184,179,136,137,148,145,142,164,178,149,153,154,197,191,171,170,193,176,214,203,184,168,159,80,78,102,84,171,173,137,143,122,178,173,141,136,167,184,142,164,155,154,135,130,159,191,203,95,94,105,61,99,66,30,74,140,93,66,94,34,16,7,22,41,54,88,40,103,200,237,243,133,185,249,246,247,197,103,53,60,104,109,66,54,69,125,105,81,104,64,59,13,4,38,58,96,112,157,130,75,54,59,16,46,39,61,94,120,114,121,123,91,101,68,42,29,56,131,176,58,28,11,0,52,78,63,33,20,22,10,68,141,138,95,53,19,20,27,32,37,25,27,19,51,40,76,61,26,56,21,83,179,129,103,132,64,37,20,28,59,39,12,13,34,36,14,6,16,16,4,47,38,35,45,12,16,19,64,32,36,118,85,41,67,28,21,28,19,35,24,52,28,18,39,7,12,69,43,48,14,27,4,34,57,39,15,21,24,33,127,105,48,70,117,109,176,113,134,127,90,18,9,24,55,50,42,21,52,9,30,42,23,33,7,38,61,97,29,104,143,52,41,43,42,17,34,44,43,26,51,41,32,24,40,39,42,0,10,36,29,51,50,39,33,26,26,27,66,146,75,17,83,72,39,63,51,53,38,58,44,27,26,17,31,17,28,27,34,37,40,43,27,60,17,15,45,30,73,116,47,15,46,50,102,105,92,43,51,48,45,23,31,34,14,31,61,44,33,39,42,21,49,30,20,60,118,76,109,123,88,118,92,114,107,92,50,53,117,108,102,90,38,34,42,29,32,31,20,46,35,32,78,122,106,79,90,100,127,121,74,29,49,75,67,40,18,21,15,6,42,38,47,65,81,37,71,41,28,11,29,30,53,202,222,254,210,182,218,231,242,240,221,196,231,222,237,222,214,206,110,34,13,28,30,7,17,6,7,32,1,3,30,5,5,0,49,9,10,25,14,36,31,19,21,183,200,196,184,188,200,179,207,193,201,205,194,196,183,199,187,196,204,207,213,217,204,209,179,203,217,198,173,206,206,212,180,212,220,218,180,206,208,196,208,205,199,171,197,197,217,188,209,195,224,209,234,214,218,189,194,209,200,231,216,225,225,234,194,204,219,216,201,213,216,212,217,177,202,218,216,196,229,188,187,213,222,190,199,195,198,213,207,193,187,194,203,195,216,187,211,198,190,211,202,209,207,196,204,184,189,177,186,191,174,211,216,206,209,213,206,204,192,175,204,194,207,203,200,210,155,192,203,189,191,230,190,198,188,184,207,196,212,195,202,185,207,205,188,199,225,221,175,197,180,171,213,196,204,182,180,206,207,195,214,168,192,188,209,176,197,214,209,211,204,195,202,199,178,199,201,188,179,226,193,161,200,203,207,181,202,199,206,166,211,197,202,197,200,186,221,190,181,197,211,182,183,194,194,206,165,196,184,195,203,200,203,175,219,170,187,206,197,190,226,214,198,190,209,182,195,205,229,197,205,197,183,201,201,193,193,199,193,214,195,175,179,199,198,173,215,189,203,191,193,214,209,205,190,194,209,190,206,196,176,205,193,218,195,196,216,183,208,226,197,191,184,198,205,191,214,199,169,198,215,213,192,167,194,187,180,166,202,195,188,183,203,202,208,180,191,178,210,134,159,173,132,185,199,223,161,197,161,185,183,169,170,196,187,189,199,131,176,164,104,87,109,130,245,150,128,184,161,175,152,120,195,146,151,136,167,152,174,156,118,163,189,161,110,83,107,81,85,52,40,134,152,117,78,69,42,22,41,33,70,49,67,103,196,245,232,182,147,252,255,240,195,77,72,58,88,171,119,52,56,101,128,112,82,72,41,34,12,53,58,101,135,152,160,121,110,103,66,45,35,54,22,48,106,131,142,137,139,154,114,55,62,62,132,122,43,19,4,9,50,59,45,40,23,17,27,38,72,125,108,82,30,31,89,109,54,22,35,28,30,27,11,27,16,30,14,93,181,111,103,126,53,11,36,15,47,42,19,34,34,43,7,24,25,19,19,29,3,39,27,30,54,68,31,17,51,138,72,19,51,28,37,25,24,36,43,37,34,37,11,9,13,17,33,17,20,26,25,35,50,26,22,27,33,69,98,88,53,59,43,35,39,34,12,48,29,45,29,69,58,23,34,31,12,44,62,58,3,24,40,89,76,106,48,53,114,48,48,41,53,57,52,22,29,34,44,41,25,38,16,29,42,29,35,25,69,22,26,4,28,47,63,43,51,127,74,45,164,132,136,175,91,119,156,82,46,14,34,14,33,7,4,10,24,7,25,29,56,56,35,28,19,43,114,89,58,36,74,59,38,28,26,39,38,39,41,54,29,12,22,25,47,68,54,27,25,13,45,29,63,81,119,71,55,129,104,90,129,119,128,84,45,33,65,102,108,128,72,28,61,37,33,29,13,26,51,46,60,98,146,111,95,97,120,105,96,19,71,140,64,45,51,26,8,11,12,43,22,52,80,62,66,22,48,46,48,32,16,117,143,138,123,58,142,164,147,157,142,152,183,228,228,213,214,212,128,0,18,14,20,17,15,19,21,16,8,35,13,17,1,3,27,1,15,3,20,23,14,18,12,213,214,202,205,200,171,206,191,200,218,222,190,208,191,200,194,206,219,202,229,185,203,198,210,200,214,199,218,206,224,196,193,196,205,203,224,197,221,204,207,188,204,218,195,196,195,177,199,218,191,195,189,172,205,189,205,214,208,202,219,242,186,193,204,198,211,199,202,172,208,184,197,192,215,194,204,189,182,205,203,193,209,208,219,199,191,213,198,214,204,209,198,208,190,189,190,183,212,202,193,204,192,178,210,205,198,210,185,200,202,212,197,208,158,195,181,193,203,182,215,186,182,180,185,187,195,211,196,179,204,193,222,194,189,187,172,204,211,187,192,196,182,180,194,204,184,207,227,200,190,202,192,194,205,185,189,194,191,207,195,209,198,201,187,214,184,195,206,186,193,192,215,192,215,183,200,204,189,205,200,197,204,194,197,223,190,195,202,174,220,172,216,187,159,219,187,189,182,179,168,188,184,209,196,200,182,227,204,177,213,204,167,186,210,191,231,193,202,170,195,189,203,196,212,198,179,179,194,211,188,174,198,212,198,193,184,186,206,179,195,202,180,214,216,196,170,172,209,206,192,189,218,196,191,178,208,198,186,179,185,194,182,194,162,181,185,189,182,184,195,196,175,183,192,188,186,182,193,191,214,189,173,189,201,193,203,190,208,195,207,200,172,192,175,180,197,200,204,137,174,187,166,176,180,200,129,215,188,180,207,189,214,195,174,199,177,149,165,177,92,72,73,146,237,137,122,143,93,160,196,176,169,138,138,138,176,166,169,135,116,193,186,214,124,117,107,110,99,82,68,139,83,64,105,37,18,44,71,67,78,56,77,204,255,255,164,199,162,244,240,210,98,42,85,106,113,129,93,67,48,63,118,91,61,27,25,34,15,36,91,106,129,106,125,119,123,124,101,90,66,22,30,43,19,59,139,114,157,162,155,166,113,56,20,26,46,29,15,29,32,56,38,35,40,14,31,6,29,76,128,77,31,118,195,132,64,28,15,38,34,54,18,41,32,30,42,127,148,79,110,130,49,21,22,3,3,8,22,48,49,13,3,6,9,31,36,12,10,16,23,45,59,27,22,12,26,97,81,43,82,28,57,69,42,41,31,39,51,26,41,48,24,10,7,30,47,26,23,28,24,24,63,65,63,77,75,123,23,13,12,65,37,14,33,50,56,85,58,31,23,39,52,32,76,81,50,79,75,75,75,133,122,116,103,112,128,43,104,68,54,61,47,70,77,55,66,81,30,54,78,50,53,35,36,46,46,31,26,35,17,50,44,12,29,129,63,10,135,93,141,164,135,154,159,78,57,7,10,31,0,47,24,25,13,12,1,40,51,49,18,39,36,51,94,91,40,55,67,26,38,37,29,29,30,29,61,23,26,35,19,30,36,68,58,38,34,30,26,44,89,54,117,76,49,101,73,122,136,151,149,53,54,44,93,129,83,114,74,29,54,65,46,18,5,17,42,29,36,126,160,145,136,114,113,109,79,12,117,199,84,49,19,29,23,34,34,22,11,57,56,48,74,41,27,23,62,35,52,41,40,34,49,15,76,133,138,143,113,94,88,155,196,200,186,222,110,6,12,4,10,22,5,17,2,21,5,6,30,12,38,2,24,12,7,34,22,11,15,24,0,229,186,199,180,200,208,213,205,225,194,212,205,237,212,207,209,206,196,192,195,200,201,177,186,210,169,198,214,183,212,201,216,211,181,182,194,195,201,230,201,193,191,196,208,204,211,201,194,198,182,194,201,203,202,208,194,205,207,232,213,204,190,214,200,223,182,195,196,205,200,202,184,175,205,189,171,205,198,191,188,211,222,200,200,195,188,213,208,203,205,204,177,188,193,195,194,183,215,200,178,206,196,171,195,175,207,208,180,194,199,168,202,211,201,189,183,178,193,174,227,217,181,186,200,213,188,169,183,184,214,177,184,218,193,192,186,220,224,193,220,174,199,205,193,187,177,212,206,182,166,192,194,212,153,200,195,202,189,184,221,199,202,206,191,188,195,199,193,205,189,200,206,206,197,209,176,185,200,204,208,188,184,197,196,168,186,193,196,193,166,191,181,217,200,194,193,185,191,201,200,190,197,205,207,159,197,218,206,200,181,187,195,207,199,180,177,214,202,212,171,191,183,193,171,200,175,196,190,215,194,195,195,189,190,186,182,199,179,190,196,177,195,203,205,184,196,176,214,221,187,205,195,184,204,188,171,213,180,198,194,189,201,211,182,192,211,187,188,182,183,176,199,201,165,187,212,193,197,163,154,217,172,189,186,199,188,197,210,174,160,154,162,180,160,209,203,181,195,115,143,129,124,143,152,142,129,206,208,199,187,179,184,182,196,214,195,156,181,182,46,45,65,115,157,79,62,117,147,148,200,170,146,156,142,207,184,145,190,139,171,232,182,178,131,93,145,95,116,57,88,104,40,82,78,59,19,57,76,78,90,63,184,247,242,206,189,246,199,255,228,108,36,63,110,127,107,74,54,60,88,68,74,70,37,25,25,12,40,89,97,115,116,107,106,113,101,124,116,140,102,74,50,48,44,19,51,94,157,182,133,145,149,131,72,43,7,11,36,34,48,47,30,46,21,12,19,6,7,28,121,120,119,161,153,46,31,25,61,88,71,39,34,30,56,48,47,152,136,116,129,127,60,12,7,32,35,7,35,22,39,36,23,17,32,33,38,31,26,16,40,48,24,27,21,9,32,140,84,66,93,57,77,72,64,112,74,60,38,34,54,35,44,10,13,19,59,51,47,24,11,12,37,56,144,189,141,113,55,20,23,37,62,47,35,37,56,65,26,56,52,68,128,99,119,104,97,118,149,182,186,172,199,166,178,198,169,166,207,182,175,175,163,146,155,152,133,132,130,150,162,158,135,112,97,81,47,67,60,40,58,51,41,38,68,140,40,64,42,58,43,38,54,47,55,60,100,37,35,25,21,61,23,30,21,14,49,32,28,36,54,19,28,58,87,99,61,67,50,14,31,59,16,18,14,28,36,20,11,25,18,36,14,23,48,33,4,30,37,56,46,77,141,81,36,59,55,59,116,111,89,39,22,32,83,122,88,120,87,30,43,54,32,32,24,38,17,48,59,70,60,55,96,102,92,88,44,83,155,166,115,71,50,53,22,41,17,55,51,79,70,77,45,73,18,53,44,44,65,83,53,17,28,65,95,101,79,134,79,81,20,73,171,206,220,221,125,1,16,17,46,13,19,12,31,15,29,8,23,15,5,15,21,12,23,12,17,10,0,25,1,190,207,221,211,216,202,225,206,186,203,203,214,193,224,213,197,197,179,191,206,211,185,219,185,187,212,197,196,212,225,217,193,175,195,209,198,194,183,197,188,212,193,198,218,160,189,209,205,194,189,206,223,210,196,187,190,226,202,197,209,188,202,201,190,214,208,197,223,194,204,181,186,198,202,204,203,214,181,214,165,209,209,182,195,175,203,232,201,209,197,214,203,209,192,203,199,201,225,190,233,196,174,186,197,210,174,218,205,179,205,215,194,181,172,187,202,210,201,183,182,176,199,191,182,188,196,200,205,189,201,207,188,164,169,201,200,196,195,177,184,193,173,199,195,215,187,204,188,209,214,197,201,200,195,192,189,200,206,181,210,203,189,209,207,208,191,198,185,185,196,170,205,189,186,213,189,194,177,220,196,214,192,188,164,186,180,213,198,199,226,209,186,187,202,212,206,189,173,170,186,188,201,198,224,154,184,197,192,194,170,203,206,189,208,196,174,216,205,177,192,211,192,205,179,204,182,225,179,202,198,190,204,188,221,181,205,215,208,170,204,196,186,185,195,189,188,185,191,184,183,188,193,201,187,199,178,173,212,177,202,197,191,182,210,197,181,217,188,218,186,184,210,173,188,170,201,157,197,169,195,209,221,170,187,216,172,196,182,177,182,181,182,209,185,189,200,218,149,93,109,153,140,178,149,144,172,207,175,188,178,191,186,213,191,180,216,195,206,183,135,92,126,80,97,17,74,195,180,168,155,184,164,154,185,185,126,176,191,125,155,190,115,175,127,101,137,58,73,66,61,81,6,37,58,42,33,65,56,51,83,152,250,250,215,137,220,252,224,213,117,41,84,96,134,130,77,82,54,110,66,60,65,67,21,6,29,42,83,92,137,131,95,96,122,113,98,94,95,95,125,118,139,65,35,61,57,33,89,115,159,137,142,128,136,106,56,59,23,25,10,18,26,23,37,17,13,41,20,27,65,120,117,178,77,23,6,41,76,115,102,65,40,44,26,22,52,178,131,110,132,98,43,30,15,26,34,29,12,23,61,25,4,38,6,14,10,38,25,43,32,27,10,51,22,57,99,175,53,104,156,131,232,116,161,185,99,68,22,22,27,35,20,6,8,27,42,23,41,14,8,23,56,46,167,105,84,120,47,31,48,35,36,43,52,63,58,128,113,115,129,173,185,217,218,168,206,210,211,206,201,200,204,193,192,187,180,160,197,195,167,181,208,234,223,158,235,211,199,201,209,197,202,152,158,171,147,165,164,145,132,93,43,28,117,139,66,32,54,60,38,37,54,27,40,63,34,15,47,22,14,11,20,26,40,61,36,40,8,13,49,42,70,40,83,112,35,27,61,18,31,44,23,34,30,40,52,32,20,51,35,31,39,23,9,46,68,54,43,36,4,84,137,74,29,55,36,56,87,86,41,44,49,23,95,120,100,124,125,55,13,25,52,33,16,35,12,11,16,19,59,46,78,87,99,102,83,143,167,174,112,101,90,62,32,11,27,42,22,64,58,94,71,63,38,22,43,27,51,66,53,60,84,97,120,119,99,64,74,87,119,169,187,213,201,213,120,15,9,25,26,13,11,2,30,10,8,24,0,19,8,3,1,19,29,25,17,2,3,22,12,165,191,198,212,206,184,203,193,198,222,213,199,188,195,207,211,190,200,192,180,207,197,198,186,197,183,203,207,197,203,225,222,224,209,208,206,187,189,219,207,197,185,207,186,174,188,222,219,183,193,212,183,208,199,208,217,218,196,213,210,194,179,202,204,208,217,207,196,177,215,198,196,182,211,210,189,189,201,178,196,207,198,194,213,195,202,198,208,190,207,202,202,198,209,187,201,184,211,212,220,202,181,211,194,183,205,168,194,201,196,199,213,197,188,195,212,177,199,187,199,189,198,190,187,180,202,206,176,183,214,201,199,195,174,175,177,191,197,200,192,177,202,206,188,197,201,177,184,200,200,197,218,206,219,215,210,171,185,172,191,176,222,190,199,211,180,191,203,213,208,184,205,200,204,231,191,194,196,186,183,186,208,233,209,191,189,208,186,194,185,194,195,197,203,190,174,179,175,204,211,211,210,206,188,183,189,189,214,205,179,189,183,204,206,177,200,182,226,201,191,182,178,174,185,160,181,199,182,191,184,187,190,181,192,194,205,210,175,216,206,193,185,182,181,177,180,170,213,186,188,193,184,177,221,199,199,194,189,196,207,182,181,177,204,176,176,212,192,222,194,180,206,186,191,196,166,188,167,183,178,188,222,177,189,159,177,166,186,177,182,181,169,204,177,198,219,203,144,144,167,171,185,175,177,177,179,214,193,197,166,185,174,190,188,182,215,184,199,213,131,125,146,134,73,38,141,233,199,145,165,167,185,185,187,170,108,183,189,62,167,168,134,199,114,101,108,62,85,61,71,37,15,21,71,63,41,71,56,56,146,233,252,209,173,195,225,239,186,99,57,50,95,119,107,48,34,114,102,80,71,85,33,42,5,33,47,63,101,109,126,118,83,99,132,109,98,110,87,87,84,107,154,60,27,40,36,54,45,53,108,130,179,169,142,130,134,156,91,52,37,12,10,1,23,33,31,1,28,51,42,98,122,142,78,31,7,73,165,139,151,115,64,62,36,43,75,157,103,116,135,111,21,15,20,24,7,29,27,28,38,39,17,24,6,11,8,25,21,59,27,25,6,31,63,65,64,122,55,59,75,55,152,75,62,95,46,35,40,8,27,9,35,21,52,29,27,6,36,18,54,64,51,41,78,60,127,93,29,49,38,47,56,77,134,142,180,208,188,233,215,239,207,199,185,182,190,181,164,173,147,147,124,110,100,131,120,120,118,135,113,150,164,157,154,168,166,174,171,181,150,148,174,186,159,166,176,176,181,197,180,175,161,151,162,152,71,78,51,38,52,36,57,53,15,43,48,13,51,29,35,47,24,28,48,51,29,21,13,18,44,78,65,39,84,100,43,96,74,39,109,56,51,70,52,49,21,14,13,28,43,58,19,18,2,37,49,76,20,15,22,29,131,62,43,50,55,27,39,41,53,17,15,32,84,147,127,117,115,53,23,27,32,18,25,39,25,57,64,47,68,26,64,119,143,132,96,69,46,52,66,68,94,81,45,28,21,18,78,62,66,85,95,60,54,15,43,85,58,41,89,154,134,125,109,108,103,63,115,161,187,217,239,219,225,211,154,8,2,25,14,31,37,23,14,3,12,12,10,17,2,4,10,14,0,7,5,17,6,19,21,199,189,224,203,168,184,209,203,202,206,224,197,205,177,219,205,181,177,203,190,185,216,164,180,197,191,207,213,201,217,203,215,182,197,218,188,200,222,193,203,212,210,214,179,200,198,213,189,190,203,201,214,215,201,212,191,210,178,184,181,208,218,205,209,205,199,207,199,218,192,206,215,199,175,182,205,210,208,189,216,186,210,177,207,203,200,199,189,214,215,186,177,210,177,182,196,194,186,200,220,219,205,206,208,203,183,169,200,205,207,219,202,181,197,206,175,193,192,167,187,190,197,189,188,180,181,189,196,176,175,189,202,215,179,203,209,188,185,194,191,187,176,172,174,204,182,182,197,201,205,187,191,182,186,195,192,185,204,173,171,188,183,173,183,192,220,199,211,196,204,187,185,175,210,176,200,165,205,188,192,196,174,198,200,216,197,177,169,188,182,189,193,191,206,192,192,194,190,205,207,197,195,195,184,206,183,199,199,178,208,183,183,177,191,183,215,188,214,193,216,196,190,200,208,197,195,192,189,201,202,167,178,207,185,180,202,187,193,203,170,204,192,175,189,183,169,191,218,188,178,197,187,191,201,195,205,195,204,194,187,183,185,170,183,190,202,177,209,194,163,185,190,190,183,196,171,177,186,214,192,172,172,167,164,153,184,172,187,197,180,161,179,190,188,187,203,138,96,159,165,158,168,171,157,176,216,207,185,178,197,164,177,189,192,195,163,170,203,198,132,138,213,153,123,94,165,226,170,145,160,176,169,123,191,173,160,215,146,66,154,171,190,226,71,121,123,107,107,87,73,49,8,28,93,88,58,70,38,154,240,251,253,155,161,241,241,239,136,29,47,86,145,109,62,64,86,125,101,53,69,47,41,17,52,39,82,107,102,135,106,109,83,119,148,113,117,96,84,114,102,110,125,70,100,66,29,53,43,25,35,40,96,149,164,129,121,149,143,140,101,54,20,32,17,30,0,23,57,44,20,54,102,147,71,44,22,14,68,2,31,104,64,31,17,29,118,164,114,126,147,82,31,29,17,23,40,10,42,41,70,38,15,55,41,36,18,28,36,38,31,19,28,52,62,66,102,115,65,23,24,26,44,39,51,46,22,87,48,15,20,30,32,74,49,19,10,34,64,71,95,116,93,88,160,87,128,128,146,181,146,195,202,196,209,208,212,224,168,201,170,153,159,141,128,117,139,127,147,135,124,122,152,144,122,148,149,157,171,169,155,146,156,147,163,190,162,204,193,168,164,174,178,148,136,153,123,120,112,158,153,174,160,169,176,174,150,198,164,134,137,76,62,36,31,49,39,41,33,17,40,29,21,37,25,32,29,17,8,33,61,18,58,59,96,102,14,93,108,125,242,108,131,155,62,50,29,38,30,8,36,8,32,25,10,37,60,55,32,32,26,81,131,88,36,64,51,20,38,36,22,25,22,55,88,122,95,117,124,59,49,16,39,40,34,13,47,77,105,61,55,46,112,159,145,81,55,36,34,32,25,36,120,99,63,47,11,41,35,53,23,56,42,34,106,171,144,126,127,121,152,149,98,113,83,72,89,129,211,231,237,224,242,237,211,233,132,11,4,23,8,17,13,17,33,19,16,22,15,22,0,20,29,12,10,10,7,18,25,7,2,221,206,204,211,197,185,200,180,183,214,210,224,219,209,201,205,180,222,199,218,214,185,194,205,198,205,218,198,226,205,171,174,194,214,192,205,207,185,191,181,217,196,208,199,184,198,164,224,183,220,205,210,200,205,195,198,188,184,196,165,205,208,203,199,217,208,221,189,211,223,188,209,216,194,199,209,203,222,194,178,203,214,174,194,218,202,192,196,194,221,203,206,200,188,173,190,175,209,193,205,195,176,194,195,218,222,190,187,218,186,201,179,210,186,180,184,186,202,196,191,209,188,180,193,195,195,192,186,198,178,191,194,186,204,200,189,183,175,218,204,202,218,198,187,160,195,199,187,209,188,214,185,184,180,214,190,166,214,196,213,202,178,202,205,218,193,196,191,191,211,194,203,187,215,193,200,191,201,189,178,204,176,180,162,190,182,187,187,192,178,192,216,195,204,197,189,204,188,179,187,193,209,180,188,188,194,181,180,203,200,189,178,184,169,202,193,177,202,198,194,182,217,205,193,183,207,176,177,191,187,179,200,195,193,196,168,190,204,206,188,191,189,188,183,187,197,200,190,183,187,220,200,190,195,193,175,221,185,183,191,206,187,178,197,195,195,198,164,196,204,187,185,188,186,181,197,190,218,185,179,188,156,162,182,163,193,168,217,190,180,214,192,153,172,212,218,176,107,126,123,136,148,154,150,179,176,198,188,184,197,183,181,197,195,189,179,207,189,221,132,161,148,121,91,85,147,205,197,171,155,173,151,174,177,181,170,172,120,47,164,155,179,169,80,149,150,110,114,101,68,19,35,140,210,129,88,75,83,239,231,236,188,131,231,249,238,170,46,62,88,109,109,67,83,107,122,117,64,73,71,24,0,9,30,81,105,111,123,137,86,103,84,113,156,170,101,99,75,67,89,112,115,86,103,84,60,56,17,39,40,36,22,40,113,110,156,129,171,169,179,158,99,92,48,29,16,12,31,18,4,30,38,89,111,78,49,15,47,21,73,126,74,46,17,43,139,153,92,128,107,64,33,41,73,42,49,92,88,50,53,50,19,30,31,36,18,20,7,36,37,22,70,50,20,29,87,134,49,38,50,54,41,30,58,51,29,40,51,33,13,19,58,39,92,67,82,104,97,131,139,160,162,185,201,182,189,182,216,224,187,192,176,152,180,136,132,140,158,152,140,131,159,148,147,159,144,157,148,141,133,145,139,122,135,109,129,98,124,107,103,89,73,87,95,118,111,114,160,127,150,142,153,110,176,142,134,181,168,171,154,151,144,133,149,146,172,177,185,178,194,156,167,173,120,114,102,70,86,21,32,68,81,60,18,10,41,33,45,27,26,21,35,62,133,93,66,76,87,144,195,102,145,131,65,58,45,28,27,6,6,14,32,22,57,17,8,32,45,70,52,107,175,79,77,70,34,25,27,27,42,26,29,37,86,141,95,133,153,84,18,23,58,58,45,60,49,71,79,140,89,84,164,148,84,33,8,42,15,35,35,79,111,131,85,48,15,37,11,49,60,63,113,156,207,194,179,151,156,141,126,87,80,51,99,134,188,236,236,210,236,219,208,217,223,217,126,11,11,5,4,24,24,8,35,21,9,21,26,7,4,5,15,23,10,17,18,12,3,27,7,206,217,226,201,185,207,213,195,220,217,201,197,244,235,207,206,214,199,208,224,226,220,199,220,190,202,211,217,216,209,179,198,184,214,219,187,186,210,192,204,206,180,195,212,172,208,218,200,188,196,216,222,199,211,186,218,179,186,196,219,198,201,215,207,191,196,183,226,210,202,220,190,203,192,184,201,224,191,190,217,187,188,205,171,203,198,209,182,199,175,190,198,188,217,198,198,202,198,192,206,196,186,203,201,195,218,193,198,207,154,188,178,198,216,208,180,204,193,187,206,193,216,202,210,204,195,207,197,181,192,190,197,177,200,210,180,206,202,196,195,199,189,177,177,191,189,188,202,217,184,200,198,197,176,200,193,179,197,201,200,193,183,192,204,189,194,202,199,198,179,212,190,198,185,186,184,176,211,220,180,192,200,177,181,187,201,197,208,203,202,218,191,192,181,197,193,205,187,199,197,204,214,178,187,195,194,176,192,152,195,195,200,199,176,195,182,195,173,197,185,188,187,203,175,198,209,203,198,195,199,168,179,173,196,199,191,194,181,200,196,190,189,210,193,180,183,189,173,194,192,176,176,180,207,204,181,187,200,182,203,209,201,170,189,190,186,178,214,199,199,192,192,191,201,200,209,187,179,168,156,148,188,186,196,184,191,201,190,205,187,180,186,180,205,191,194,146,102,139,157,152,163,138,138,211,197,224,203,169,202,175,182,193,207,175,178,167,182,198,147,110,86,62,46,45,69,124,162,126,128,137,182,203,216,137,192,165,140,64,99,163,173,143,102,128,104,114,124,99,21,14,61,193,188,131,59,118,200,228,193,138,174,217,240,234,145,52,29,132,115,106,88,58,138,122,131,65,73,40,12,13,33,22,91,119,112,115,81,107,87,99,98,75,136,111,104,109,66,128,131,127,157,79,76,72,39,46,21,34,12,37,45,43,37,61,107,150,171,145,171,154,165,157,120,75,32,17,37,8,14,15,0,28,73,119,79,63,81,98,188,145,69,29,21,52,129,154,95,127,113,59,4,37,60,42,30,47,32,49,47,20,21,21,13,47,38,40,15,10,12,28,55,25,46,1,45,130,24,48,45,80,68,23,57,48,51,52,54,36,55,74,83,119,122,142,157,187,202,190,200,185,211,199,185,185,185,148,152,167,124,120,115,119,132,131,144,129,129,110,140,147,132,144,97,95,74,51,58,36,43,33,30,55,48,34,54,15,36,29,18,36,33,29,28,22,25,52,20,49,24,41,33,61,86,88,110,90,138,113,173,167,145,135,143,146,131,123,136,149,161,147,172,179,190,163,143,162,163,170,148,132,113,104,71,65,21,52,69,31,39,23,27,61,125,109,61,58,35,58,50,48,41,37,9,43,59,51,32,25,16,20,36,70,19,29,11,25,14,91,73,101,155,80,36,95,38,62,69,22,17,37,33,55,110,120,87,95,101,69,39,17,33,56,81,59,48,21,57,115,98,173,188,114,64,21,36,42,24,25,52,144,187,96,47,42,32,17,87,238,200,212,189,160,152,150,147,131,111,101,75,58,94,133,202,237,218,244,234,228,228,235,234,237,223,221,117,0,0,1,24,14,14,10,16,7,18,30,36,8,4,11,8,9,13,24,13,21,10,25,29,211,186,203,188,192,210,200,197,206,171,207,223,203,202,216,221,186,199,221,202,207,189,207,221,202,205,202,189,217,202,192,188,171,201,182,214,213,201,203,205,194,216,206,199,203,204,217,209,189,191,208,201,209,222,194,219,228,222,182,211,188,216,207,190,199,191,219,203,176,210,216,202,203,195,234,200,200,206,202,204,194,191,169,196,201,201,182,187,208,184,223,190,216,195,187,199,215,239,197,178,199,217,206,195,176,217,196,214,179,195,192,204,227,204,204,195,173,196,199,188,209,202,191,213,185,179,196,210,177,181,211,200,195,174,178,197,199,208,194,202,183,189,193,176,168,199,194,197,200,198,174,209,185,204,213,194,187,192,201,189,197,169,195,197,201,192,182,181,173,197,215,198,179,197,199,194,175,191,187,186,212,208,195,189,202,191,195,196,205,218,187,201,185,195,204,176,173,196,172,190,182,221,194,209,209,194,198,202,193,210,183,172,161,193,184,196,202,163,188,220,168,208,197,190,194,186,169,200,193,208,207,206,186,178,177,183,191,210,171,174,189,195,196,168,202,194,189,177,199,188,182,179,188,204,171,191,185,197,211,209,207,202,182,205,186,198,200,187,195,202,190,187,221,202,196,187,143,155,173,159,185,197,184,203,213,185,208,199,188,212,176,180,182,216,189,178,143,152,182,174,191,166,150,209,205,214,203,218,170,223,191,181,185,186,207,206,183,161,175,120,87,67,97,70,61,61,99,127,135,121,159,165,204,146,119,185,185,167,58,71,140,161,198,119,132,112,90,111,99,39,24,21,92,103,50,114,240,220,220,141,177,229,228,245,150,60,62,49,120,133,58,64,88,124,110,95,79,51,4,21,46,39,57,105,128,100,116,85,82,88,135,127,88,71,103,81,86,95,141,137,151,118,81,21,35,64,57,65,44,12,11,13,42,39,37,44,58,102,133,143,166,154,144,160,177,160,116,49,19,34,28,13,24,47,70,90,113,132,176,156,59,40,38,27,66,162,140,110,122,92,35,19,23,23,21,20,11,25,49,37,49,38,27,8,29,31,32,14,20,54,44,34,34,28,43,54,121,78,28,20,24,23,33,27,35,13,78,72,93,106,152,205,203,191,208,210,227,207,213,188,164,156,144,133,134,106,103,90,138,129,133,137,129,146,124,131,116,70,58,39,29,41,59,5,25,29,20,1,2,22,15,29,34,18,12,40,15,27,18,11,13,22,31,32,30,34,32,39,40,12,5,22,44,2,43,24,50,25,56,27,62,81,103,87,126,125,113,130,135,164,160,175,149,144,152,161,161,172,166,151,200,168,179,139,150,120,123,99,71,24,17,42,66,125,144,37,41,39,76,49,24,35,28,32,53,50,35,43,37,13,50,50,7,22,21,32,14,32,61,63,133,157,57,67,94,65,110,91,25,69,76,27,75,119,134,123,104,111,98,22,56,55,60,62,34,60,10,56,154,134,158,114,74,77,11,20,25,38,41,69,131,104,87,16,32,42,27,140,251,242,220,173,130,114,139,106,110,88,75,73,118,195,251,249,227,235,240,237,200,201,234,241,242,226,217,114,10,0,2,9,38,18,26,0,26,11,0,0,20,4,13,14,11,31,17,23,2,15,13,3,203,204,199,197,185,219,207,172,204,184,223,217,196,207,198,233,225,222,218,199,196,227,195,204,219,195,211,205,206,215,214,210,191,197,198,210,218,193,216,187,227,168,183,195,222,184,194,198,207,202,208,212,192,218,215,215,200,203,212,205,208,231,221,192,198,185,221,205,191,199,205,198,210,201,192,195,202,203,202,202,206,222,222,222,210,196,209,188,209,186,200,190,217,204,194,200,183,208,192,197,210,197,184,197,200,200,206,188,202,199,213,204,189,193,191,224,180,184,193,174,207,193,181,177,209,182,189,197,181,194,206,214,183,216,172,173,177,195,191,181,188,207,215,190,172,216,221,187,172,226,150,209,199,192,181,187,193,171,191,200,214,177,176,176,183,182,184,215,199,184,222,198,182,185,205,179,173,194,193,193,200,187,194,214,205,213,202,193,178,197,213,188,202,207,193,196,181,229,181,210,199,196,184,182,193,220,188,196,195,175,189,201,197,211,171,210,177,194,157,192,178,177,201,195,209,195,197,204,205,176,203,201,210,196,190,200,197,184,203,191,197,202,194,182,210,182,204,186,184,211,187,194,172,210,195,174,190,197,172,212,211,180,196,216,182,200,207,190,201,183,163,209,188,174,168,176,186,177,210,209,182,174,198,181,205,188,191,190,208,197,194,195,214,195,176,192,143,165,208,195,212,186,188,215,189,230,214,186,164,201,192,193,206,182,199,209,182,181,159,91,45,91,122,84,87,69,89,154,170,128,186,175,153,139,198,187,211,156,70,116,211,178,177,130,90,131,97,119,84,61,64,90,107,80,59,148,248,227,156,159,230,249,247,151,19,54,101,72,118,80,63,104,141,119,60,62,37,17,15,22,53,55,75,126,135,111,121,80,125,132,133,118,33,39,73,72,106,99,110,94,113,96,60,31,71,69,81,114,46,31,18,22,32,26,33,33,38,40,75,96,169,173,142,136,157,184,178,163,123,99,51,45,22,37,13,38,46,36,64,61,22,25,29,25,84,157,123,106,142,86,10,20,27,32,60,50,39,62,70,53,22,47,38,15,33,15,32,47,60,4,21,23,28,28,26,124,125,57,49,36,39,49,55,63,77,97,115,167,192,203,196,162,200,193,158,161,174,160,128,135,116,132,154,135,138,134,189,151,119,109,108,78,71,33,15,31,22,18,26,40,30,33,11,12,8,21,22,20,34,28,13,22,22,14,36,5,37,44,12,28,22,37,53,20,33,16,54,32,13,13,11,5,40,31,41,26,15,7,15,18,29,17,48,8,25,70,71,85,78,83,122,133,120,157,153,175,156,153,129,154,159,133,147,164,169,177,184,148,148,110,116,124,91,120,57,35,51,64,64,86,89,57,55,43,62,14,42,32,26,60,22,18,22,15,22,38,54,51,17,9,120,163,51,112,168,116,216,147,137,179,65,23,76,163,153,112,116,116,113,32,59,58,61,35,47,51,13,128,175,165,135,95,45,35,11,22,12,35,21,21,38,60,13,15,13,38,40,145,210,161,174,128,111,123,98,126,111,130,154,209,246,248,252,255,230,235,225,250,236,231,225,241,199,211,221,130,0,9,9,6,2,17,17,4,44,27,18,41,15,12,8,43,15,23,3,18,1,25,16,7,216,212,209,181,234,234,213,208,183,207,217,210,190,213,189,200,217,182,177,212,206,203,217,225,225,220,230,193,224,226,208,234,232,210,198,180,188,199,207,231,186,189,205,189,179,186,201,180,208,192,211,181,178,205,234,216,219,200,205,215,207,228,208,200,220,223,209,213,222,217,180,214,215,207,206,208,180,195,194,191,200,219,188,174,192,182,197,215,209,226,210,215,223,192,217,193,187,191,203,200,183,181,174,194,213,201,200,205,197,217,190,206,217,187,195,188,204,205,203,205,189,207,178,164,200,178,189,191,190,185,206,187,208,209,181,209,226,204,212,199,199,200,213,197,187,194,203,219,203,187,179,186,189,207,195,195,204,197,213,170,197,191,206,177,198,202,193,179,205,183,225,185,192,191,205,190,169,201,194,203,179,178,208,203,221,173,180,196,175,179,201,187,198,184,184,195,191,196,190,197,193,200,184,181,196,170,200,204,207,186,180,186,189,208,200,190,179,201,185,186,205,209,178,176,175,199,207,181,210,203,205,201,208,194,168,195,181,190,200,195,193,197,159,179,190,178,183,205,173,193,183,209,191,173,185,227,183,194,209,214,196,184,202,182,190,202,182,189,185,186,191,168,181,181,199,190,196,182,225,206,209,197,160,185,209,197,221,186,174,204,181,188,203,207,154,153,96,133,164,205,160,150,168,206,194,212,210,207,194,210,186,183,204,214,190,202,193,180,143,138,68,78,92,88,71,57,117,156,209,171,158,177,152,199,210,165,170,162,60,207,220,179,181,124,109,138,64,93,46,148,150,198,226,91,70,121,202,143,169,213,245,240,164,82,79,117,106,76,62,58,72,144,114,91,83,39,20,16,38,66,74,79,129,131,112,125,112,110,100,141,145,96,24,52,100,82,99,75,122,121,151,125,61,92,116,108,112,100,31,23,9,13,42,53,52,54,39,16,19,25,70,98,113,146,148,131,140,164,199,152,131,121,67,68,37,27,16,41,3,19,11,39,31,29,86,157,132,103,147,77,33,8,24,38,21,75,105,104,81,43,54,38,13,5,21,38,37,49,63,27,31,43,68,89,111,139,116,43,74,104,107,146,155,175,196,206,200,179,194,152,181,139,137,133,132,129,127,137,116,124,144,126,138,132,120,82,53,53,47,22,20,2,24,50,18,54,31,26,27,23,27,21,11,25,21,29,28,16,35,13,7,1,21,12,22,30,31,14,34,20,30,8,32,33,47,30,49,46,38,18,38,7,6,25,27,28,23,4,8,21,30,47,41,20,18,34,13,22,29,37,34,59,66,69,103,146,126,154,151,161,138,150,132,134,125,143,148,134,163,165,141,154,164,163,99,50,45,26,48,49,43,52,35,42,73,66,37,21,44,56,59,23,7,19,18,56,42,32,9,25,73,134,60,99,83,73,139,115,98,103,62,57,84,158,124,128,112,109,92,33,46,71,14,27,30,28,61,158,169,83,82,45,28,35,13,31,27,7,34,34,39,23,47,28,54,66,106,156,109,108,99,61,102,124,158,142,138,196,234,250,226,235,234,255,226,245,245,208,246,206,211,228,217,238,239,110,4,6,11,10,0,5,8,9,11,19,29,11,7,5,9,11,19,34,11,24,5,13,37,23,228,197,200,188,200,222,193,209,222,185,219,205,207,211,202,206,221,204,211,205,206,215,215,194,210,205,198,205,192,217,221,227,213,186,196,198,206,210,211,219,198,198,189,206,197,196,184,209,198,193,208,197,229,187,210,212,182,211,199,226,178,193,205,211,184,179,193,197,209,218,224,193,182,206,191,195,228,211,191,186,221,209,208,190,229,210,178,206,216,198,184,206,206,217,181,212,219,203,201,197,202,179,211,192,196,182,207,218,190,192,205,224,202,208,192,215,191,204,184,205,191,180,183,181,203,203,180,197,168,184,206,192,195,170,195,187,190,217,188,183,176,190,205,188,220,189,179,211,188,184,200,193,194,201,192,184,207,169,173,178,174,198,186,194,207,157,216,190,183,196,188,187,189,204,173,193,194,195,175,224,190,196,174,183,173,203,194,185,211,204,225,192,181,187,206,190,190,192,166,196,202,197,187,190,192,191,205,192,218,169,184,205,195,189,179,186,195,187,204,176,183,191,178,209,198,184,201,184,209,194,193,181,197,205,194,198,197,207,201,195,198,210,181,188,182,219,187,210,192,175,197,167,208,187,165,189,189,172,185,199,183,189,194,195,190,203,194,172,196,187,182,194,190,195,192,207,204,205,211,180,224,191,173,199,206,205,198,200,187,202,191,194,206,194,169,130,78,112,141,143,117,164,195,229,216,181,208,197,178,208,181,168,206,204,205,193,203,149,164,180,158,88,114,113,107,96,135,226,200,107,160,160,182,214,157,94,220,168,100,170,184,160,208,115,85,125,47,76,57,147,211,227,192,78,72,85,111,102,182,241,238,206,72,60,75,115,99,56,73,76,140,132,97,59,38,21,16,23,73,77,124,127,136,114,126,106,94,116,112,137,136,57,21,94,133,91,115,106,138,124,111,86,81,62,86,65,78,71,49,34,15,22,57,70,77,49,46,33,17,60,20,37,47,92,97,115,129,127,178,131,162,173,158,145,120,76,46,24,15,24,10,30,53,2,107,154,69,117,104,64,21,19,15,22,36,75,111,69,60,56,38,43,40,15,31,39,61,84,96,82,90,136,139,147,153,126,165,161,190,218,210,234,203,206,228,177,150,133,144,145,145,143,140,145,112,155,156,110,112,103,68,45,48,26,26,44,24,41,23,14,14,38,79,50,46,45,3,28,18,10,8,7,14,27,41,23,22,15,12,14,22,23,24,8,34,31,51,36,31,44,42,21,17,17,56,51,64,52,41,47,10,18,9,41,8,33,3,20,25,10,11,18,46,27,44,36,45,42,40,40,46,2,36,27,34,35,53,83,71,63,121,126,130,145,117,158,119,144,137,137,148,160,149,162,141,112,117,77,85,48,32,28,36,41,88,59,30,19,66,63,45,45,18,32,64,47,32,75,35,11,107,135,46,56,42,14,40,30,51,45,17,32,49,130,151,101,112,96,92,56,38,44,45,32,48,72,138,172,74,73,30,27,10,31,17,31,14,41,27,18,45,24,54,128,143,155,198,140,120,89,136,104,110,125,123,111,140,210,249,242,255,249,250,218,215,225,206,223,208,233,226,234,218,235,208,150,20,1,21,19,10,18,10,16,14,26,7,0,18,17,1,17,13,7,7,20,14,12,8,17,204,219,197,196,183,212,186,211,191,193,187,197,200,193,210,210,199,206,215,213,202,206,197,219,214,220,227,205,206,193,176,214,198,197,197,196,196,188,235,189,190,232,203,207,215,210,198,200,208,199,175,192,199,204,210,203,209,206,223,197,206,219,190,205,194,221,209,197,225,205,198,205,198,203,188,227,228,201,188,198,208,227,201,181,209,189,204,190,181,211,194,208,198,193,176,193,194,187,207,196,200,176,179,210,207,184,210,230,190,202,172,201,186,210,203,208,174,204,176,208,194,192,193,185,199,201,213,209,208,205,217,198,192,193,175,184,193,203,185,194,186,197,182,216,207,177,167,175,196,183,206,214,173,198,199,198,174,213,182,194,190,204,197,186,215,189,189,170,199,206,166,200,182,169,214,199,196,192,220,198,196,183,185,202,196,207,198,187,200,184,168,169,193,199,185,183,191,188,213,192,195,189,175,210,199,207,191,205,193,194,209,204,182,199,197,187,194,178,193,227,189,206,205,225,194,177,191,196,198,207,210,204,182,199,192,209,193,184,205,206,195,200,185,216,199,206,191,185,181,192,194,183,213,223,164,180,184,193,169,198,188,192,199,201,205,184,169,176,192,183,197,171,216,211,206,206,192,187,202,195,196,200,183,190,188,205,207,181,195,201,186,185,204,170,189,140,127,175,186,169,173,177,201,219,168,201,201,208,179,218,193,198,198,197,190,218,185,152,162,246,162,134,131,153,129,103,103,177,160,123,180,145,166,178,155,164,229,123,56,136,147,195,237,129,116,114,105,68,43,176,218,231,136,17,26,54,117,158,215,227,201,106,47,97,97,110,70,75,123,124,102,117,101,74,30,34,45,46,115,103,125,109,147,106,97,102,117,114,100,106,108,24,29,148,124,79,109,75,107,91,66,111,75,58,59,81,21,42,30,55,10,56,31,66,63,91,62,64,24,27,41,53,47,23,54,32,99,105,126,134,144,141,145,162,183,209,157,135,101,79,46,54,45,28,123,135,107,128,118,48,4,14,12,20,52,111,119,61,38,44,47,55,72,77,88,135,145,150,153,145,166,172,153,190,175,196,164,176,193,156,173,148,148,110,131,146,120,135,115,127,115,136,126,96,113,72,57,27,21,29,23,19,29,29,10,28,29,21,0,19,31,49,54,52,54,40,11,27,10,13,19,16,20,2,2,68,41,23,56,22,16,25,30,24,62,59,74,70,68,56,56,33,37,62,62,69,65,70,65,60,28,10,5,13,11,5,15,23,2,14,23,5,6,8,5,3,8,64,81,34,47,45,37,29,23,35,41,29,49,41,46,40,60,80,105,132,123,131,145,149,134,132,118,162,139,162,159,150,144,107,95,83,47,68,66,82,72,69,61,39,39,52,71,48,10,12,23,67,45,73,140,150,68,56,64,46,48,24,77,66,25,48,53,95,139,98,105,126,105,38,11,44,39,57,98,103,126,101,55,49,26,38,10,10,26,47,42,60,70,78,128,150,163,155,143,169,145,99,102,149,166,89,105,95,52,44,28,56,133,186,234,229,224,229,220,218,239,237,226,203,215,215,211,200,224,105,22,13,23,8,21,13,26,28,19,12,24,35,17,20,0,17,24,0,23,18,25,29,2,17,188,196,209,209,196,200,186,188,205,192,227,209,211,175,230,213,206,230,206,196,190,204,231,213,227,185,205,193,180,183,182,217,207,201,186,190,184,186,212,209,213,183,191,210,214,188,208,202,217,206,189,205,201,199,203,210,195,201,188,212,193,214,206,206,228,203,198,208,191,214,197,202,206,183,194,210,217,215,231,181,194,211,179,202,201,206,203,209,199,180,212,228,177,194,203,186,190,170,185,208,203,206,216,190,189,182,186,210,167,202,191,191,199,222,183,194,204,182,203,205,186,191,201,229,190,206,191,200,166,206,207,176,187,220,176,189,187,181,194,192,178,219,211,180,199,201,187,180,202,151,180,186,210,207,197,201,215,188,182,207,210,198,203,194,169,191,182,217,186,175,193,204,194,184,217,207,197,174,201,194,200,178,190,187,201,196,210,186,225,178,204,203,196,196,188,189,190,192,176,170,178,203,198,182,181,203,178,205,202,186,199,168,198,198,182,197,174,180,189,190,200,192,189,173,178,187,180,176,206,216,203,175,185,194,195,203,181,179,196,192,199,170,173,184,187,164,204,209,221,197,207,200,190,180,202,206,200,203,182,193,211,216,194,194,155,166,206,187,189,209,210,210,209,207,190,199,190,199,188,181,179,185,189,175,207,224,218,186,198,188,201,187,195,187,176,128,163,203,216,144,131,196,233,194,207,210,228,176,191,203,191,159,196,169,201,234,209,145,201,212,170,98,124,135,90,91,54,142,146,201,176,103,136,207,151,193,235,68,80,126,162,236,244,148,81,123,122,71,16,139,241,253,140,19,22,153,184,148,233,191,100,68,59,109,126,85,49,59,157,124,63,113,65,30,15,27,40,72,105,131,131,139,117,102,125,113,114,93,75,53,51,12,68,148,129,108,101,88,109,103,118,111,102,118,89,90,9,15,6,29,24,59,27,29,33,35,54,50,37,35,17,39,22,16,5,11,28,36,63,79,116,122,123,160,157,163,180,183,200,171,163,149,139,115,164,150,102,123,65,55,41,14,59,45,67,60,72,38,41,76,81,105,142,121,143,198,180,191,194,186,182,190,165,169,186,151,154,118,91,104,113,147,132,161,164,147,132,109,82,92,67,64,27,30,11,41,29,47,16,10,18,3,42,12,34,21,29,32,26,41,36,32,21,54,61,25,13,32,23,20,37,28,20,32,42,48,97,73,57,57,26,22,23,69,75,98,89,85,77,68,76,71,96,104,133,137,83,57,84,80,51,14,17,2,26,70,62,53,24,50,48,11,3,8,6,38,61,105,63,57,39,19,38,22,14,34,33,36,26,54,10,20,6,26,62,67,70,114,124,134,125,148,143,130,123,135,136,135,150,151,160,165,116,122,148,124,143,107,57,52,24,101,94,57,46,22,36,40,82,79,121,155,43,43,44,46,70,58,48,50,43,39,34,104,138,135,108,112,120,52,33,14,40,52,58,71,45,22,22,55,20,46,17,46,57,50,111,165,199,166,172,148,150,114,110,138,140,134,141,108,142,106,52,52,39,16,60,56,19,60,147,217,223,239,224,202,212,227,195,226,226,218,213,238,213,109,1,3,18,14,15,8,17,7,4,10,13,5,9,3,12,21,15,17,11,19,3,16,23,44,184,208,212,191,201,221,212,208,213,212,186,199,202,199,201,201,192,192,208,213,187,197,201,195,240,221,197,206,215,197,208,201,210,200,224,199,201,202,194,202,198,202,195,184,197,208,193,195,217,215,208,192,207,174,200,179,189,182,213,208,200,187,209,186,213,177,210,192,207,230,209,197,201,183,202,209,213,196,197,174,200,192,171,187,199,171,211,192,227,183,207,196,184,221,208,194,213,223,193,201,198,190,184,190,198,222,175,183,182,201,176,199,174,165,202,192,205,217,199,179,196,203,208,187,196,205,199,210,185,170,202,189,188,209,207,194,195,190,198,181,184,184,167,187,163,183,207,194,202,191,212,192,195,210,200,198,197,188,181,214,191,194,199,181,175,184,210,196,166,206,187,186,207,181,185,184,196,229,184,192,194,204,169,182,202,187,198,199,208,202,187,195,196,174,193,185,189,189,204,188,193,203,190,204,204,208,179,190,194,213,166,184,217,203,179,181,183,188,184,196,170,199,195,194,192,206,202,198,213,199,185,197,212,209,167,209,209,196,219,211,216,207,219,200,185,221,205,202,186,204,195,197,197,208,232,225,193,206,213,196,181,179,195,195,160,193,201,208,194,200,203,209,194,192,191,199,228,197,198,160,214,187,190,191,185,207,184,201,202,194,205,217,178,111,144,113,129,159,174,133,142,192,218,169,193,180,182,204,162,202,207,150,215,183,190,201,170,178,186,157,189,106,120,112,124,96,60,94,152,210,159,105,173,170,165,195,191,91,65,116,160,216,232,125,116,123,95,51,13,101,225,255,177,130,183,250,214,231,234,91,56,65,117,150,55,60,99,81,133,117,75,68,20,44,31,53,49,102,111,123,123,123,89,133,105,110,107,93,68,22,35,9,75,149,104,82,95,113,146,139,139,122,98,139,86,68,64,28,58,55,85,55,41,25,36,15,35,42,9,18,8,42,50,40,26,25,39,31,36,27,59,83,103,126,120,142,149,125,117,159,181,195,203,179,146,111,114,130,78,66,67,111,148,162,139,159,180,160,171,167,179,181,187,190,182,174,205,177,158,178,131,130,121,129,102,125,115,117,143,145,166,149,137,89,92,59,53,50,12,38,36,70,25,4,22,6,6,6,4,15,31,32,31,9,3,27,8,17,58,61,43,38,97,79,46,23,13,9,5,20,7,28,10,21,83,87,46,41,80,82,97,33,59,83,97,149,152,129,109,91,96,120,137,143,167,113,143,88,80,128,79,38,19,50,102,148,134,74,54,51,28,29,27,17,36,59,80,67,79,89,51,12,13,23,20,34,50,1,10,16,11,19,37,42,5,12,2,6,25,40,47,70,88,105,124,120,158,108,151,153,143,179,136,157,152,139,162,148,168,119,156,122,139,86,64,41,31,84,73,51,122,142,56,23,39,10,19,54,47,60,64,35,41,86,138,143,93,98,126,96,27,19,9,31,12,43,26,36,39,21,41,73,91,105,185,161,188,185,162,133,125,134,121,156,144,145,136,98,52,51,153,122,49,43,21,24,34,46,39,13,71,173,225,235,222,215,238,217,223,200,230,215,212,224,226,125,4,5,19,15,7,8,13,20,21,31,15,1,19,3,17,21,6,20,17,8,23,7,32,25,194,218,205,215,209,218,237,176,215,207,176,214,211,191,206,211,217,189,194,206,211,188,183,202,200,187,204,205,227,201,186,234,192,227,197,221,203,215,200,184,196,209,222,201,217,194,190,234,207,200,182,220,211,190,198,186,192,210,204,201,209,182,213,208,207,222,182,229,188,223,182,202,199,221,188,181,211,197,190,212,195,205,201,230,235,208,192,191,217,203,184,211,205,195,184,199,231,184,213,192,195,214,190,200,203,195,199,201,215,196,212,193,197,189,199,206,167,207,198,198,200,185,195,208,184,213,221,196,190,194,216,200,188,208,193,208,198,187,198,195,180,186,193,188,197,171,174,186,181,196,203,208,192,217,187,198,194,203,207,195,202,204,186,215,175,187,190,190,205,159,190,211,203,213,176,192,203,200,175,190,187,208,192,198,196,201,193,190,202,186,200,210,204,205,201,205,183,186,181,193,207,188,198,200,212,182,184,181,195,191,206,187,198,188,208,198,190,194,182,210,200,181,207,182,193,213,190,182,202,185,204,190,211,193,208,195,210,196,204,212,167,170,183,193,197,209,213,200,210,213,194,211,204,210,169,214,206,190,188,186,169,197,203,203,211,191,197,187,207,208,196,198,219,180,183,200,195,188,217,215,198,189,178,188,194,215,205,184,206,204,200,189,172,103,114,71,117,155,132,109,164,195,208,212,194,201,192,211,171,223,193,180,191,195,179,180,152,152,156,137,166,124,93,62,86,87,97,139,165,201,142,129,184,181,164,213,147,80,57,80,155,241,204,148,111,92,75,46,9,103,223,245,195,187,251,255,200,183,95,58,116,94,109,79,54,113,123,86,93,78,75,43,4,48,56,110,100,123,114,143,132,100,70,131,135,109,88,92,59,39,23,24,49,130,108,66,120,76,76,47,105,99,98,143,68,63,61,98,114,72,42,52,48,38,11,10,46,24,17,30,11,46,53,49,27,31,37,13,32,10,51,15,35,33,74,113,116,125,133,134,155,146,159,189,128,121,120,115,72,126,187,211,223,210,172,187,202,189,213,158,145,148,172,139,145,163,147,121,90,144,122,125,127,128,129,130,136,125,115,96,45,30,21,26,20,28,36,35,56,64,38,0,13,18,9,8,14,29,0,36,14,9,10,16,33,21,15,41,25,17,35,67,78,78,31,21,4,8,23,14,21,39,19,55,116,84,46,58,74,103,104,72,153,117,121,175,114,43,59,99,136,103,149,149,108,100,140,89,77,160,111,45,87,159,149,104,53,124,140,65,28,24,9,7,48,60,64,102,106,111,57,32,10,18,15,27,25,22,34,6,39,28,8,28,35,9,40,31,28,24,48,28,30,47,17,75,98,100,109,128,135,133,146,142,110,130,128,164,203,192,158,175,143,176,172,113,142,130,125,74,155,127,58,42,51,16,24,36,22,26,48,8,32,83,142,134,94,97,126,70,29,18,25,14,25,74,78,65,73,138,139,160,161,174,182,137,131,123,126,150,148,136,163,130,103,98,61,29,19,115,157,72,69,33,40,29,34,47,50,13,58,189,205,238,241,221,212,191,210,220,214,225,236,223,236,114,19,8,9,26,17,15,26,12,31,24,17,17,3,2,14,5,8,19,10,4,29,24,31,7,187,201,190,216,168,193,202,184,204,211,204,224,198,205,217,200,206,189,217,213,182,208,196,191,203,196,221,209,228,200,198,200,209,201,201,212,196,193,195,222,210,191,210,212,222,212,206,225,217,212,198,198,209,202,170,192,185,200,218,191,222,194,213,179,212,195,211,203,204,199,194,201,223,215,196,211,221,215,189,212,192,197,176,208,221,191,199,217,195,214,201,193,186,210,192,184,194,188,205,167,207,196,194,179,203,200,226,201,195,199,194,222,194,210,200,210,197,183,205,198,191,208,193,189,191,189,217,229,207,204,199,189,202,217,195,207,189,197,192,197,184,186,171,198,206,192,184,181,208,198,193,206,193,217,211,197,197,197,190,184,182,201,205,178,197,233,215,177,191,164,200,184,206,189,206,164,203,207,178,186,170,198,196,182,202,193,191,194,185,207,207,185,185,210,204,203,183,178,208,199,191,187,177,189,187,207,169,192,176,201,216,227,205,194,193,184,199,215,181,189,199,188,184,217,210,205,183,194,204,185,208,184,189,180,210,200,203,182,190,182,136,93,158,209,198,222,201,182,203,198,205,191,177,189,196,211,195,175,200,219,201,177,197,187,227,218,186,198,167,188,208,202,199,218,213,191,186,207,194,201,221,187,169,223,199,189,217,207,189,228,216,197,182,160,174,142,182,193,116,132,152,187,193,223,193,203,174,197,198,220,215,181,206,207,222,165,144,175,162,178,175,141,108,108,101,98,110,104,160,216,171,166,173,155,168,229,130,63,41,102,225,219,232,152,109,76,31,14,31,173,246,251,158,175,244,254,136,83,57,99,100,96,73,38,101,141,101,51,45,54,38,31,18,51,94,129,167,144,131,124,110,113,92,96,89,94,83,124,79,52,28,10,35,179,99,92,88,65,35,52,60,91,104,121,27,30,98,101,86,32,46,37,66,38,33,30,15,37,48,14,26,5,48,36,27,22,65,34,21,33,36,1,27,15,29,23,74,76,124,115,160,144,124,174,153,146,144,114,108,158,163,176,217,169,174,174,184,137,143,108,109,118,100,117,121,140,139,127,140,150,122,125,111,98,89,68,26,26,25,31,19,21,8,5,21,27,6,30,28,26,10,45,3,17,19,15,17,11,9,33,26,11,13,36,6,12,17,24,5,35,46,20,57,26,21,33,19,26,24,17,8,32,14,55,125,130,92,91,74,90,104,111,141,91,76,161,107,110,87,139,131,48,104,121,132,96,161,103,82,146,123,71,155,123,97,69,27,89,169,126,22,9,22,26,44,63,57,74,125,89,38,15,43,21,29,21,22,18,32,28,23,9,12,17,24,5,28,8,0,58,30,51,13,27,40,25,39,48,49,53,56,115,108,121,108,128,125,152,182,172,170,185,159,158,179,193,159,178,162,144,168,130,64,64,63,80,65,69,53,46,47,47,84,106,134,140,109,80,135,81,58,44,69,69,111,141,147,157,188,165,161,177,158,129,126,135,177,138,146,158,138,128,108,48,53,31,57,29,68,202,128,41,42,45,40,14,44,60,49,44,70,204,212,232,226,218,228,220,226,228,222,177,203,215,235,104,8,10,2,15,19,6,11,0,8,12,5,30,4,1,8,0,12,12,14,3,32,2,19,20,218,192,221,219,205,199,211,234,197,193,196,229,196,221,197,224,192,182,190,190,181,185,196,201,209,195,204,202,201,205,177,202,204,179,204,197,213,230,195,197,183,188,200,174,198,208,197,214,190,210,211,206,192,203,218,186,200,215,199,211,199,201,197,189,196,187,218,186,198,204,203,191,203,203,195,198,211,210,220,159,222,201,194,184,199,204,210,201,186,168,218,196,189,202,212,201,220,176,201,185,222,209,199,168,232,199,192,190,203,187,228,178,186,181,196,192,203,192,198,208,205,198,184,196,220,189,201,165,212,196,198,187,188,198,205,186,188,184,188,201,166,175,183,180,185,216,175,210,196,190,188,214,181,207,192,184,191,208,204,185,196,166,198,170,185,187,224,205,178,225,178,199,182,205,196,200,185,183,194,184,169,184,204,201,196,205,194,201,204,200,233,182,191,195,208,208,199,196,207,190,207,196,222,186,196,191,199,183,216,204,182,182,179,196,211,207,203,194,184,200,184,191,190,209,202,186,176,192,190,181,166,180,197,186,195,189,198,199,204,206,148,123,180,211,217,218,189,240,214,204,217,207,194,180,181,198,189,207,185,199,187,215,203,205,192,198,204,200,190,209,203,217,222,172,191,234,194,180,185,203,221,191,174,175,212,189,233,220,224,221,228,153,157,160,153,160,226,222,142,183,166,155,176,204,213,212,176,208,188,214,227,171,219,220,203,194,178,160,161,166,158,199,127,108,106,75,76,75,159,193,152,152,141,157,217,196,123,55,66,151,244,246,244,128,40,46,31,8,114,234,227,219,151,133,203,141,48,37,59,90,135,73,53,72,118,140,84,47,22,37,27,20,42,88,134,137,157,134,121,117,86,69,58,16,64,62,105,95,85,56,52,61,89,162,102,72,59,48,84,19,98,88,62,19,4,67,120,103,53,35,79,60,45,37,19,55,42,37,52,45,34,52,16,23,9,33,3,1,24,14,15,46,13,18,4,47,14,36,43,41,52,72,93,90,114,144,147,154,150,177,178,186,201,175,169,162,131,150,148,152,136,133,131,113,61,133,103,54,88,49,42,22,45,20,30,20,18,9,30,29,19,8,0,11,19,33,14,16,7,10,9,1,9,8,8,11,19,28,18,22,29,29,17,1,32,21,29,11,15,33,48,60,60,56,27,52,26,8,39,2,17,25,26,42,82,132,105,91,53,95,82,110,129,78,86,99,102,103,146,85,36,32,62,77,115,158,127,71,134,139,151,103,175,73,82,147,92,184,216,116,23,0,39,20,39,65,117,88,82,55,19,15,25,47,17,10,18,14,40,21,23,21,6,22,43,33,26,44,14,23,21,60,33,28,51,39,35,53,27,2,26,32,49,64,67,82,103,149,147,167,141,160,144,148,156,160,175,150,151,161,175,152,120,198,158,176,162,143,147,135,140,122,147,179,200,184,143,82,111,96,73,117,138,156,189,175,179,142,157,145,109,145,151,155,174,148,132,120,122,67,72,36,41,18,38,57,22,14,208,246,87,36,51,31,40,56,36,38,38,24,67,205,194,223,237,200,225,202,227,227,200,225,209,206,205,103,12,11,16,4,1,16,60,4,29,23,17,24,17,11,20,9,13,0,8,9,14,27,23,13,208,191,207,189,165,202,211,185,217,205,183,196,215,185,180,175,193,175,205,196,212,179,178,213,188,211,189,182,196,213,205,197,195,191,211,225,190,197,204,211,209,202,181,203,195,205,208,215,192,193,209,226,215,216,230,218,208,198,207,201,199,221,219,181,211,190,185,208,214,195,184,191,220,193,193,198,189,215,176,208,203,167,213,184,193,177,201,172,225,195,220,178,206,229,202,195,195,222,195,205,200,206,195,201,223,208,205,188,205,196,185,213,224,183,182,210,173,202,195,176,205,209,193,182,211,173,205,197,171,189,174,187,199,216,199,196,209,194,193,209,191,207,173,208,197,178,180,202,210,195,198,168,202,186,199,209,213,184,183,171,191,187,179,192,186,181,201,168,205,193,197,216,194,213,213,199,219,202,184,181,196,185,191,186,190,188,193,188,180,185,189,207,207,169,211,195,207,196,173,216,205,191,200,215,176,187,187,196,200,184,210,197,195,185,203,183,188,215,193,207,191,206,190,196,224,185,216,217,211,213,216,209,232,222,212,204,229,221,214,228,190,204,237,239,222,193,211,229,229,220,204,193,205,214,238,217,230,232,226,227,240,230,229,224,228,213,221,219,223,207,226,207,250,226,225,230,217,235,234,213,206,241,236,195,235,245,237,217,209,210,199,168,145,138,154,161,187,162,147,196,195,127,181,229,238,233,226,210,197,227,219,217,220,227,215,184,200,172,190,161,207,229,163,87,91,101,117,66,112,126,110,122,153,228,240,144,65,73,34,141,233,236,150,44,1,13,33,46,151,230,214,230,104,99,157,56,14,58,94,136,83,48,97,127,162,102,81,80,37,23,11,45,77,117,123,130,106,107,108,133,110,93,59,67,57,47,65,96,72,57,92,72,40,142,121,64,58,53,42,12,98,159,67,30,76,115,158,79,49,63,116,72,49,57,26,27,32,52,10,18,14,16,18,17,41,19,4,1,26,18,28,19,9,32,13,54,24,64,32,26,20,23,14,33,41,49,66,58,52,96,100,107,146,117,116,120,105,76,78,95,48,59,29,53,11,29,54,42,21,33,34,21,29,30,22,14,10,24,13,20,34,34,4,8,15,15,4,32,9,8,45,20,3,17,15,17,13,11,24,23,2,40,21,32,18,24,12,23,48,70,97,135,98,78,93,98,55,35,26,19,7,12,7,9,48,62,73,108,65,65,74,80,121,87,104,121,61,46,28,46,33,34,37,54,68,64,83,121,180,163,138,96,124,83,80,176,93,155,155,52,26,2,32,17,16,49,141,83,50,46,36,26,9,17,22,21,19,10,25,11,30,27,35,13,57,39,30,16,21,5,12,27,37,25,17,31,17,21,12,14,20,18,5,17,35,39,31,72,76,119,150,123,106,143,130,137,137,126,127,139,148,140,153,177,154,179,156,209,181,180,178,184,180,161,146,173,124,113,114,126,74,124,131,141,151,126,144,139,128,127,126,139,144,148,126,107,71,37,24,26,55,55,43,28,16,17,15,96,243,237,80,31,43,39,38,28,47,46,53,13,68,183,216,223,218,205,202,227,221,214,209,231,251,221,219,115,9,0,3,33,13,10,10,26,14,34,14,23,11,6,9,17,10,1,16,5,29,16,2,10,192,183,215,177,202,218,181,205,208,211,204,233,203,191,230,193,204,199,199,218,212,168,217,205,210,223,196,187,213,213,171,207,164,206,204,207,222,200,195,228,186,194,216,196,201,190,192,189,179,184,192,211,196,192,216,198,201,204,198,223,231,208,213,219,223,206,187,195,198,186,199,194,202,210,181,204,191,191,197,207,214,200,221,219,200,187,196,191,197,195,196,185,205,181,208,191,196,186,205,182,221,195,188,171,184,186,185,221,201,203,176,191,175,205,222,206,206,185,168,197,210,195,208,187,187,202,200,204,181,204,189,203,197,219,185,217,187,201,179,210,179,164,195,199,209,189,198,198,182,185,204,216,199,200,185,200,215,195,199,197,185,188,178,185,186,178,185,185,203,184,186,187,201,191,196,169,194,195,205,216,202,181,174,167,211,187,173,190,214,197,200,199,189,224,194,202,189,186,202,186,192,213,200,235,205,164,205,194,190,202,212,169,179,205,204,187,191,189,190,206,198,173,205,201,207,222,245,214,242,238,249,213,230,242,234,236,245,227,250,233,219,237,250,238,242,153,99,197,208,246,213,226,242,243,240,238,245,234,222,254,240,234,252,251,247,209,231,242,253,239,233,237,248,251,232,248,225,235,231,250,216,240,216,212,227,202,238,222,215,240,188,157,156,140,122,124,146,120,184,200,192,147,114,194,237,228,208,216,212,212,194,207,216,218,187,188,211,133,175,176,242,207,123,96,111,96,125,92,85,55,85,152,159,240,218,99,59,77,14,49,108,135,62,19,5,46,22,100,217,248,222,234,130,105,126,33,61,109,101,84,68,81,130,144,71,54,50,38,30,34,49,93,122,118,156,127,133,126,151,122,55,47,101,92,73,51,96,87,51,109,72,54,25,60,67,70,43,51,36,49,148,182,80,79,123,163,156,70,62,147,94,72,65,64,65,19,13,27,29,17,24,25,32,16,33,29,31,19,28,17,17,10,22,32,5,13,34,10,30,37,31,12,30,39,33,28,27,23,17,2,9,30,37,30,23,32,21,43,29,26,21,24,43,11,28,18,40,45,19,25,54,26,31,6,8,5,24,23,8,21,55,19,36,27,17,11,14,25,41,10,24,17,4,29,18,20,19,19,29,18,27,22,14,42,30,29,26,8,123,176,199,191,181,175,193,152,62,23,12,2,50,8,19,9,15,62,98,116,50,62,96,97,127,74,97,95,21,36,24,42,58,24,41,33,74,54,59,123,139,116,97,82,93,50,67,129,34,70,39,23,17,47,29,5,74,148,144,113,86,83,39,43,47,6,25,25,10,21,44,46,29,35,60,20,9,12,22,15,13,1,22,25,42,35,18,43,12,12,27,2,37,43,59,42,55,14,36,36,37,27,36,30,83,94,95,90,112,107,128,137,164,127,130,159,131,153,114,125,134,149,144,140,132,154,140,142,130,108,139,122,110,148,133,163,152,120,130,153,158,123,94,107,75,42,48,44,48,31,35,44,43,47,21,23,15,23,35,127,231,171,55,54,34,18,24,25,69,49,64,18,75,211,210,224,239,231,232,213,232,223,231,218,231,223,221,129,5,6,2,12,0,25,11,4,9,12,26,20,0,15,1,14,31,0,20,30,4,2,13,19,211,221,208,211,207,193,196,200,212,197,223,195,177,194,201,178,228,213,210,190,203,201,204,170,213,217,220,225,188,219,187,209,191,195,223,196,198,211,179,186,209,214,207,199,201,209,222,226,192,206,192,199,232,208,221,222,216,216,206,166,193,183,207,207,210,193,220,215,184,196,175,205,188,206,213,188,224,184,206,197,202,185,197,191,207,174,199,214,212,208,200,205,178,164,211,207,206,193,178,196,206,213,194,203,213,214,200,213,207,212,177,216,206,189,185,187,174,194,200,190,198,194,208,170,187,202,211,196,210,205,173,202,174,203,199,172,187,211,211,184,185,203,209,171,179,191,192,166,179,200,197,189,199,187,213,190,210,176,206,204,198,199,212,207,189,200,195,191,208,203,187,194,217,198,206,197,187,224,216,199,198,185,181,183,213,191,200,204,203,190,180,201,192,206,201,202,159,182,168,187,192,176,200,163,169,232,188,197,192,204,210,208,195,198,193,187,212,207,206,206,184,180,194,178,211,212,209,206,210,186,212,190,185,207,204,188,157,188,156,207,206,180,155,153,120,97,51,119,151,185,163,169,164,160,140,141,167,138,160,152,159,134,138,169,187,137,153,154,160,138,154,158,133,146,138,130,139,125,131,126,163,124,148,167,135,109,144,186,151,134,130,140,117,116,127,136,152,118,165,220,208,142,71,111,130,109,134,125,120,153,125,143,119,143,125,156,108,65,100,113,131,124,79,116,141,127,109,105,102,72,79,92,76,152,102,35,50,70,23,17,24,54,44,40,46,43,66,153,246,249,224,250,160,113,89,83,115,98,96,65,91,123,127,72,88,56,20,33,29,12,64,139,142,138,147,131,149,122,129,98,62,50,76,78,63,68,80,73,37,61,31,41,12,84,81,81,38,33,109,107,52,70,106,110,109,109,109,51,34,84,86,62,64,58,60,31,30,7,42,34,49,22,29,34,29,10,29,19,18,12,2,12,11,18,21,16,18,27,7,7,51,38,36,26,32,17,0,21,23,27,9,19,25,15,29,16,20,44,36,31,24,23,9,29,23,34,52,72,36,36,9,13,39,10,32,43,23,16,27,30,14,16,33,32,13,38,7,15,6,27,9,17,37,29,41,14,33,26,16,35,15,18,10,35,13,34,8,11,49,178,181,191,149,172,198,145,77,23,23,23,13,37,32,24,41,93,95,54,40,87,47,137,135,63,52,54,37,47,37,52,41,54,64,98,54,39,33,62,92,149,164,101,111,55,63,116,67,27,10,23,24,5,38,53,125,160,133,155,130,136,153,156,63,19,35,40,12,14,18,31,19,6,29,37,3,10,29,21,20,13,42,2,31,14,11,32,39,12,30,24,22,7,35,26,28,15,18,44,26,13,31,30,42,34,55,54,27,43,54,73,57,105,106,77,115,119,127,98,134,109,133,125,112,152,157,151,113,130,186,155,112,122,126,125,94,103,80,45,31,53,34,29,11,27,28,36,20,36,32,49,39,43,24,18,29,40,28,76,131,94,64,66,40,35,34,29,62,43,66,60,162,211,219,205,225,206,214,237,213,233,237,209,241,197,221,114,4,1,1,7,9,19,36,3,45,15,2,12,2,26,0,23,27,16,17,2,27,20,23,20,203,235,209,194,200,187,200,218,180,207,201,201,191,189,217,224,244,250,219,205,177,211,211,201,186,213,201,185,200,191,209,195,211,185,193,178,186,202,179,212,196,188,195,186,201,200,203,211,230,182,198,223,200,203,207,220,203,187,198,193,183,208,210,209,203,192,204,219,200,198,191,197,199,225,211,187,216,201,182,227,196,196,215,192,171,204,196,194,220,230,197,217,189,214,210,178,208,190,202,206,205,188,226,197,182,175,199,192,177,201,183,204,212,196,190,201,183,188,204,193,216,182,197,200,188,183,176,218,170,185,199,175,174,197,213,200,197,201,192,188,192,195,175,196,198,210,209,206,190,217,188,211,194,185,188,193,210,195,197,200,209,186,187,186,186,176,172,201,191,191,182,192,193,198,196,188,189,214,190,190,191,202,196,178,213,181,174,179,204,216,178,199,188,194,206,202,175,207,185,193,190,188,201,169,192,172,198,205,174,196,185,210,230,186,198,197,197,198,188,196,168,191,175,113,64,74,69,50,74,63,60,78,48,53,42,27,19,10,45,106,76,28,6,14,17,15,8,19,22,29,16,17,14,44,5,7,25,1,4,14,3,2,12,23,57,0,10,4,9,33,12,9,5,42,53,17,10,7,1,7,15,2,46,59,46,9,42,81,43,46,69,59,64,87,98,110,145,136,195,224,173,147,89,55,4,5,19,10,22,19,7,20,3,25,38,37,54,9,44,54,27,36,21,95,134,117,126,106,100,42,50,31,0,43,30,4,65,59,61,44,31,21,29,56,42,45,49,199,237,254,215,225,190,138,126,98,90,84,67,67,111,130,76,100,70,39,24,47,40,98,127,143,129,125,135,124,146,144,118,81,49,55,68,68,69,46,55,14,46,77,44,46,33,60,74,35,50,129,234,126,14,36,55,111,72,51,94,48,40,52,51,76,46,55,28,34,26,30,17,22,22,3,13,25,23,22,7,28,31,21,7,16,28,15,16,17,20,35,31,13,36,11,47,12,47,24,9,28,23,37,14,39,7,7,14,12,14,24,20,55,0,15,34,22,13,48,59,85,47,56,36,12,5,16,18,34,34,21,52,15,26,26,41,3,29,15,31,27,25,22,14,20,27,17,20,17,24,13,17,43,28,9,6,17,25,27,18,35,31,49,95,66,60,20,45,49,56,25,19,10,26,19,36,48,63,138,84,38,44,59,58,108,147,49,39,19,33,19,46,85,87,126,122,44,39,45,72,61,28,135,169,121,99,54,63,98,96,56,24,1,23,9,9,38,74,131,172,141,145,116,160,174,59,21,35,17,29,31,32,42,15,12,14,16,11,15,8,21,45,33,23,32,17,38,2,20,31,34,33,15,12,25,27,31,21,13,26,18,61,29,41,24,9,29,35,39,41,41,36,23,32,19,33,28,45,59,75,77,84,84,101,113,99,72,80,77,77,126,100,64,33,65,49,48,61,24,12,29,20,16,28,25,5,22,4,31,23,29,48,24,40,7,27,27,22,25,50,51,46,47,62,56,19,31,56,47,42,39,6,55,186,226,208,246,207,220,205,220,235,212,224,231,218,225,208,106,3,1,6,0,12,34,20,11,19,13,25,25,16,1,12,4,25,16,45,15,40,36,8,19,211,210,210,196,183,196,195,208,199,206,210,179,198,188,218,177,246,246,194,214,214,192,179,196,191,204,214,189,185,204,215,176,212,219,222,201,211,185,201,209,196,224,210,208,204,227,202,196,210,209,186,200,208,227,209,213,190,204,203,209,210,190,189,211,203,233,212,219,199,230,198,202,207,226,205,197,206,196,188,212,190,181,205,175,195,200,204,182,170,216,213,218,210,176,216,188,194,209,209,192,201,196,202,209,172,209,192,202,213,208,194,187,195,200,196,197,201,214,218,204,208,190,212,191,193,196,177,194,193,191,222,172,189,219,198,194,197,180,182,180,181,193,196,207,215,169,199,182,190,184,219,192,192,216,190,163,216,202,180,202,213,202,194,175,212,207,190,178,188,200,196,191,166,198,215,200,185,191,179,201,196,192,192,209,199,192,207,184,203,200,193,197,205,210,198,189,186,190,202,217,188,176,200,182,194,180,193,214,194,182,198,190,192,199,181,191,210,220,210,200,202,188,181,118,85,73,76,70,32,68,65,77,78,57,77,74,55,65,57,77,95,79,63,63,73,67,57,57,54,27,56,57,36,30,47,44,33,35,34,33,62,57,55,51,104,48,37,39,67,42,41,40,53,34,94,52,21,34,40,18,44,35,87,100,42,5,16,73,56,36,62,82,79,45,77,91,154,167,208,179,137,99,38,44,31,13,15,6,58,34,10,25,15,9,12,24,39,6,25,41,9,19,33,87,109,104,157,131,118,76,49,36,17,61,27,20,66,75,75,47,30,22,36,32,61,38,56,183,184,191,157,160,178,152,122,109,70,38,90,121,106,91,62,64,62,7,34,59,89,128,116,118,149,119,129,118,115,80,108,37,56,74,70,126,59,41,4,28,119,131,46,49,31,43,11,38,81,168,200,100,45,81,80,55,34,77,62,46,68,48,10,32,33,25,50,51,34,7,34,38,64,30,11,24,17,25,33,18,16,39,18,22,16,32,38,17,26,41,22,2,30,13,10,26,18,6,25,33,4,9,12,5,16,17,7,12,42,7,28,16,23,40,28,28,29,29,67,62,56,28,6,13,13,3,25,25,25,31,15,23,4,36,17,24,12,22,23,31,15,23,31,10,28,13,19,2,13,35,17,11,27,19,34,4,28,21,11,14,32,59,46,52,39,45,37,26,19,25,25,41,15,25,39,34,93,122,65,51,50,61,66,73,86,28,52,9,17,22,30,91,123,130,65,42,14,9,5,59,72,90,130,131,101,47,69,62,126,88,37,23,8,2,37,16,48,62,96,80,85,102,52,52,54,30,51,11,19,33,24,25,30,31,18,18,28,16,11,23,21,27,7,19,18,28,13,56,2,20,22,10,15,5,35,37,18,4,5,6,9,35,53,49,28,36,47,48,63,78,59,41,11,32,16,33,24,49,16,50,14,32,36,26,61,50,45,48,20,27,42,25,40,46,43,43,49,36,18,8,32,16,19,29,20,22,33,14,14,35,21,27,18,28,35,23,49,38,12,6,20,43,46,69,34,34,33,43,46,25,38,144,243,236,209,214,216,236,199,237,213,203,219,239,232,209,214,90,11,11,10,18,2,3,25,13,17,41,31,14,2,6,12,8,20,3,3,2,14,17,20,8,210,192,221,194,206,217,206,211,204,227,217,206,194,224,220,203,250,254,217,207,213,205,184,215,202,178,211,198,194,189,203,184,192,197,213,195,196,207,216,205,217,172,198,193,207,207,196,183,185,193,170,208,197,192,199,190,209,200,202,211,219,203,197,203,190,194,228,209,219,196,188,206,181,196,190,208,201,182,210,190,205,210,194,202,160,186,214,201,190,201,206,209,215,177,201,183,176,182,196,180,205,207,198,196,170,217,195,179,211,186,195,196,184,198,196,186,194,197,196,201,188,204,204,206,197,214,213,201,191,176,190,187,213,187,179,200,193,188,187,181,182,178,197,202,217,204,185,196,181,219,191,211,195,196,191,199,183,204,194,203,208,198,210,182,197,195,183,197,208,211,168,228,191,186,167,196,177,220,183,201,213,195,198,174,196,192,221,187,182,206,210,233,200,204,194,188,208,198,196,211,192,202,196,172,214,190,199,200,189,191,179,205,185,194,174,190,182,208,174,211,196,183,201,197,184,207,193,213,177,213,206,216,209,208,211,196,215,185,180,167,194,223,226,211,208,214,203,216,213,187,227,230,208,203,231,217,223,211,186,224,221,224,210,220,221,198,211,241,218,212,209,241,226,214,205,201,211,230,189,227,202,190,205,197,161,161,178,192,173,173,172,136,141,122,105,96,157,204,203,162,69,73,45,73,160,183,187,186,173,140,158,175,103,166,144,147,115,111,180,142,156,138,113,89,72,132,134,114,83,19,92,77,97,95,70,52,59,61,42,12,17,4,36,50,49,45,114,202,116,84,99,60,85,110,133,79,32,71,134,124,83,86,42,10,21,14,62,122,140,117,119,94,127,102,125,107,113,40,42,57,38,34,80,76,49,36,61,132,208,207,125,80,45,16,63,143,160,64,84,90,55,75,63,66,36,70,41,44,82,43,57,8,28,45,50,65,38,23,25,34,44,37,22,11,30,22,35,22,30,22,12,12,26,31,8,8,6,28,4,19,22,18,30,11,24,22,12,8,19,5,19,13,2,29,24,23,25,34,19,14,13,33,39,26,44,70,119,67,46,28,15,16,40,16,5,2,1,27,13,29,16,23,4,17,26,32,27,49,14,21,48,35,13,1,30,14,25,21,47,25,21,17,18,30,12,29,28,34,20,50,46,49,10,50,47,13,20,7,13,4,15,4,41,50,102,121,63,82,68,53,59,85,67,47,26,55,35,40,65,120,154,106,52,17,42,12,25,44,72,88,107,117,68,40,67,94,110,107,57,31,13,28,10,2,38,49,74,43,17,17,35,29,12,24,34,15,22,28,44,30,30,14,22,7,38,25,26,24,22,13,20,28,6,13,23,50,17,7,35,26,28,13,22,33,16,25,24,31,41,23,36,6,21,49,90,131,107,56,62,25,29,28,28,42,34,25,22,36,31,16,15,10,34,19,23,34,28,27,23,47,57,44,48,38,27,55,9,13,52,38,6,4,25,20,25,16,27,24,28,22,30,15,39,15,29,20,44,23,27,50,41,86,49,69,62,55,40,88,165,234,250,210,218,209,222,212,195,216,212,199,218,227,209,222,234,116,12,0,9,27,4,24,40,12,33,17,22,1,5,14,14,8,8,11,23,8,5,12,35,16,199,229,201,188,210,193,221,209,194,203,189,198,203,206,206,192,243,219,214,194,205,184,203,202,208,205,193,204,189,200,214,212,204,183,209,211,218,215,231,192,220,196,213,197,205,218,211,221,193,215,202,221,190,185,212,206,207,179,229,200,187,208,185,199,203,199,199,200,207,208,193,210,192,213,212,191,223,205,198,202,196,190,210,194,236,185,185,194,182,198,219,207,219,206,203,210,206,210,209,195,184,209,189,185,189,191,213,176,195,206,202,196,182,195,218,223,216,199,199,210,201,192,197,176,190,209,213,202,198,172,223,217,197,214,207,183,192,186,172,215,183,170,220,215,200,178,187,207,198,200,185,181,192,202,204,218,172,174,207,190,182,187,194,204,184,185,193,191,171,180,181,210,202,218,190,191,197,235,191,192,196,195,167,178,187,183,203,185,189,204,215,202,184,195,175,195,217,218,210,190,201,194,175,181,188,206,180,211,176,213,192,206,203,191,181,210,184,184,194,214,209,180,223,226,226,212,222,223,247,252,236,255,214,233,245,238,247,224,217,242,187,239,247,245,246,236,247,246,237,248,243,255,245,247,249,232,241,239,237,241,218,234,227,247,249,229,237,252,248,232,235,255,241,247,249,253,239,251,246,241,247,249,246,241,223,218,248,231,202,189,194,180,182,180,130,137,158,173,141,111,64,33,47,186,247,245,243,253,255,211,251,253,216,247,226,220,177,202,246,248,204,178,211,167,123,151,128,86,58,29,111,217,198,160,161,122,74,68,25,33,16,10,34,53,48,57,181,182,84,76,89,57,35,96,84,18,53,132,132,77,78,48,25,29,42,74,104,115,120,106,112,106,102,124,129,146,103,46,33,53,40,19,55,29,39,57,108,174,196,162,92,43,3,9,104,229,101,18,48,73,95,59,91,81,63,34,35,41,64,17,20,54,59,34,104,72,68,40,40,10,55,24,40,37,2,6,28,54,14,32,5,35,22,31,23,11,37,23,27,23,19,51,13,23,16,10,18,16,31,43,23,40,8,9,7,8,4,13,15,15,32,19,59,36,36,78,145,98,52,47,50,27,13,14,5,14,24,47,17,3,30,18,20,34,33,35,8,25,6,38,27,33,17,16,12,2,40,24,43,17,22,21,40,21,21,21,58,36,36,80,56,50,37,53,35,27,58,1,20,14,23,19,28,58,131,124,93,88,90,110,57,52,39,27,18,40,23,19,74,182,186,97,60,62,39,13,35,20,68,112,95,67,46,144,134,71,135,150,56,23,3,19,29,55,36,66,49,20,29,34,15,43,28,13,30,16,35,29,27,27,31,18,9,17,18,25,14,30,21,11,39,10,6,42,27,22,13,12,21,44,25,9,27,10,18,40,20,12,10,19,31,15,26,100,113,100,75,54,56,58,12,20,17,40,42,17,25,65,50,12,22,26,39,13,41,34,29,24,22,50,54,37,55,41,19,15,27,21,9,7,30,21,15,46,21,45,37,40,30,34,20,40,33,41,38,55,97,25,21,23,46,56,79,55,43,89,101,218,238,244,235,230,227,230,194,210,225,197,204,201,212,231,201,224,216,110,10,14,11,17,15,3,27,2,7,20,8,14,17,22,20,41,9,28,11,5,10,14,28,22,191,209,207,201,206,213,181,219,200,153,213,212,208,212,190,187,225,236,188,209,227,190,219,188,207,212,189,200,210,195,243,204,193,208,218,197,204,184,204,200,226,196,211,208,208,204,211,221,207,209,187,189,205,194,190,206,226,196,205,203,197,196,198,206,203,203,212,191,206,202,206,199,209,207,196,189,191,199,204,174,187,208,204,228,196,198,212,213,208,192,186,198,174,200,189,210,196,199,198,204,201,207,197,198,200,177,186,208,198,186,199,202,188,203,203,234,191,212,203,202,180,227,210,212,234,197,196,189,194,179,208,195,213,199,185,196,216,178,185,198,202,192,181,200,209,200,183,207,183,190,171,187,214,204,220,200,187,178,203,196,197,204,203,188,194,187,207,194,196,200,198,179,177,189,187,194,182,186,195,182,174,181,181,199,198,202,190,205,187,214,171,189,195,217,182,182,175,194,198,172,208,194,198,202,188,189,188,174,171,198,207,200,189,169,190,197,194,207,193,211,196,211,205,206,199,224,213,220,211,226,206,214,194,225,201,202,201,185,211,209,198,193,212,211,230,183,219,201,216,209,198,207,221,182,212,226,204,212,224,226,220,208,206,218,210,223,227,217,203,221,210,216,232,228,192,199,191,209,208,198,206,242,224,228,186,206,227,206,176,188,170,196,170,173,116,154,192,197,123,93,35,67,136,186,242,199,222,215,226,184,218,179,198,217,171,152,161,211,245,183,155,182,223,181,132,118,93,78,61,66,125,250,205,224,186,77,45,24,57,88,62,44,48,100,39,155,229,225,111,123,99,30,15,19,73,70,135,107,83,82,47,14,20,45,45,103,133,124,121,140,112,93,149,148,111,147,105,91,43,33,35,39,37,44,19,90,166,198,183,88,47,27,68,32,60,147,95,59,69,61,72,73,63,101,45,42,47,41,52,25,29,45,84,92,71,53,76,76,41,56,54,24,35,4,38,5,34,15,38,51,16,23,32,10,5,31,39,47,18,20,30,11,33,21,32,37,27,22,5,10,10,21,18,11,0,23,2,11,14,37,18,22,13,21,18,59,98,77,15,24,13,2,2,21,9,6,31,30,26,22,32,42,37,22,21,28,19,5,36,18,11,2,40,33,19,14,12,26,34,21,43,37,34,30,9,17,4,43,22,62,108,68,89,84,69,38,19,31,28,23,28,35,43,52,156,98,82,134,119,106,36,30,27,33,20,39,85,94,75,98,42,78,53,80,32,25,44,27,69,71,58,56,101,172,101,65,129,146,92,9,2,46,24,38,56,69,61,47,59,39,24,46,7,26,16,31,7,21,48,19,28,36,28,19,33,26,28,21,18,13,36,16,39,17,13,15,12,9,38,29,17,29,22,32,27,18,35,18,32,18,34,22,43,99,79,63,92,81,60,27,25,18,15,20,12,22,6,2,10,24,21,11,23,18,3,36,27,44,4,29,22,60,17,29,23,21,25,11,11,27,32,32,24,16,36,11,5,20,28,29,15,26,50,32,45,159,109,60,27,30,46,43,95,86,98,75,75,196,230,232,233,219,213,215,242,187,220,191,186,232,213,213,221,219,217,116,19,15,15,22,13,16,2,42,32,52,1,2,0,17,0,31,12,6,12,25,9,0,35,8,202,180,193,184,184,200,209,216,208,199,207,210,190,195,204,177,228,206,156,171,211,206,215,215,230,191,216,230,210,204,204,195,206,220,196,210,206,197,184,206,189,192,203,201,209,211,192,189,181,181,183,176,201,191,207,193,164,209,204,183,195,190,197,202,199,188,191,174,206,197,220,189,192,188,203,187,218,210,169,195,208,202,174,206,205,224,200,221,201,213,197,193,200,213,212,213,209,213,221,201,196,203,207,201,184,190,208,195,192,208,176,178,174,200,166,199,203,196,172,177,174,190,204,192,180,199,179,198,206,196,196,179,193,222,209,189,180,191,201,231,201,173,173,182,181,196,194,178,197,213,184,194,210,184,168,196,200,177,220,174,194,200,186,233,185,186,203,177,202,194,201,204,193,212,185,217,190,204,205,174,197,191,177,181,190,186,199,182,191,174,196,212,192,173,178,182,183,182,189,191,192,180,191,172,175,182,199,193,216,222,190,198,215,178,189,163,189,183,211,194,199,204,193,184,188,204,194,172,202,208,214,207,189,208,205,199,187,202,197,203,186,165,151,207,222,167,200,195,181,204,200,192,180,184,205,176,177,201,194,184,179,212,209,179,212,220,176,190,198,191,179,193,171,199,172,208,213,220,183,192,206,186,220,178,178,191,220,174,122,139,156,209,191,152,125,162,213,192,159,62,19,94,193,243,229,206,204,197,206,190,196,158,160,185,141,147,181,221,170,61,91,190,237,201,138,135,78,62,78,83,118,211,156,135,130,77,42,16,56,156,58,68,59,79,156,242,248,187,69,91,53,6,33,38,70,97,63,65,63,36,46,22,39,66,84,110,125,103,118,124,104,119,107,100,112,103,122,92,64,49,26,31,19,28,93,150,151,149,103,72,109,126,113,86,41,55,72,83,71,46,73,70,39,72,22,37,45,36,38,13,20,44,54,89,69,48,38,81,84,105,109,78,63,20,28,21,34,11,22,23,41,29,33,24,15,44,41,21,30,46,41,35,23,15,25,21,9,25,13,7,45,9,23,8,25,2,20,21,22,25,15,23,28,35,41,69,71,53,24,17,33,4,15,27,44,14,14,21,16,27,10,9,26,34,22,31,38,23,21,6,18,29,11,14,16,9,17,21,19,34,20,8,23,25,31,24,56,47,73,105,127,138,163,116,81,53,23,22,21,24,26,22,23,56,121,138,146,110,152,149,94,44,9,16,28,102,141,99,100,50,54,46,57,64,92,74,52,21,12,82,96,83,103,155,125,107,166,176,80,21,3,20,45,33,52,57,38,54,86,72,52,36,44,23,26,35,28,13,30,24,20,38,38,23,33,8,9,20,43,10,19,26,35,20,26,14,27,26,27,23,40,3,32,34,30,36,24,34,13,17,22,15,88,64,63,124,114,100,55,40,21,28,25,13,20,40,46,46,12,34,20,9,6,21,6,10,16,16,41,44,26,60,22,1,42,8,14,58,10,33,21,35,20,12,17,33,43,50,24,29,27,36,26,32,131,199,80,78,92,66,80,74,79,72,76,48,28,141,231,219,239,192,228,198,182,184,193,198,227,217,220,227,211,213,223,119,13,13,6,16,21,10,9,19,11,6,21,5,29,13,8,20,31,11,30,9,11,0,10,5,198,217,214,196,191,216,208,214,209,188,171,188,215,200,231,215,239,237,194,199,182,203,200,190,185,190,201,164,202,186,211,177,193,216,205,212,201,219,189,216,206,200,195,208,192,189,204,198,217,202,203,204,213,200,189,220,211,195,189,206,223,181,199,204,187,217,210,210,199,188,226,182,205,209,197,210,216,198,203,189,207,203,183,178,208,187,179,207,217,197,226,185,201,191,180,192,206,204,192,195,198,195,188,197,179,197,205,198,186,183,201,185,162,205,205,201,182,184,199,185,203,190,197,197,196,207,201,200,207,198,187,203,220,198,212,229,182,192,224,184,204,190,215,166,185,223,233,208,218,215,206,222,199,190,193,225,228,192,200,155,203,192,197,176,194,195,187,192,203,192,188,226,205,214,192,190,167,202,188,167,188,195,198,167,187,211,192,173,220,209,196,173,193,206,196,200,198,182,187,202,201,180,200,187,195,200,199,191,187,187,199,196,210,212,214,188,201,214,201,172,201,196,180,220,193,202,194,211,170,199,194,197,190,179,195,210,209,184,203,193,204,192,164,179,211,201,185,187,209,190,191,199,181,175,230,198,221,197,188,173,201,200,192,208,193,182,223,198,195,180,177,196,193,189,179,206,182,187,199,199,190,200,172,193,162,184,205,168,100,104,143,168,184,122,135,218,233,187,129,37,91,196,229,218,232,209,209,172,183,174,184,119,190,184,168,186,227,218,108,40,125,176,154,177,159,90,100,102,86,75,133,153,100,68,73,38,19,23,8,74,77,85,62,143,242,237,222,99,53,59,0,40,10,71,113,85,64,47,51,34,35,48,66,89,154,125,106,123,95,108,128,128,107,100,109,123,132,94,119,127,51,37,22,126,131,202,178,103,149,185,156,146,117,55,36,74,46,60,72,67,94,83,52,42,36,26,41,67,56,27,40,37,77,65,52,60,101,96,144,125,142,111,63,23,34,30,7,63,35,50,20,8,17,25,60,35,24,25,42,31,33,34,30,28,31,33,12,3,19,1,12,29,25,32,17,14,12,27,36,16,24,11,18,87,106,121,118,47,85,54,42,26,8,13,33,30,30,10,31,15,29,11,16,13,29,39,29,21,19,34,40,29,22,23,17,22,22,58,43,37,41,24,36,21,30,27,73,59,118,189,220,149,146,132,101,57,32,16,11,9,14,10,30,24,73,104,129,150,129,152,104,52,43,17,6,96,183,149,133,73,44,55,100,116,156,99,20,26,9,72,101,97,128,133,132,134,172,159,30,13,13,12,21,54,45,102,106,129,172,128,86,66,33,24,18,31,27,16,34,47,19,30,11,29,24,35,20,22,34,51,23,34,14,12,20,27,14,27,32,30,8,57,24,16,21,14,28,39,39,5,24,31,54,47,69,116,134,74,40,26,6,8,11,9,33,53,20,40,30,51,19,16,13,21,27,53,20,15,50,43,62,29,6,29,28,17,27,43,2,34,14,37,14,16,25,23,9,26,39,28,21,38,30,96,250,167,97,148,119,68,33,48,52,72,48,60,43,130,207,186,228,212,199,219,226,218,185,237,208,221,231,217,214,209,209,127,6,1,0,8,19,16,25,18,17,11,15,3,1,21,15,27,21,11,20,17,7,23,8,0,215,193,179,200,223,191,199,174,209,205,212,198,180,202,188,195,250,235,174,202,204,202,215,204,205,193,200,201,205,200,211,217,202,227,182,208,203,198,220,190,202,205,192,210,196,201,205,192,208,196,187,176,221,189,219,202,188,198,201,197,211,202,196,213,197,230,199,200,205,211,202,214,190,229,209,212,195,203,199,185,181,202,189,211,219,224,211,203,197,192,165,200,205,200,210,172,185,187,193,180,203,202,211,186,194,197,175,207,196,176,187,189,206,199,182,208,176,195,186,194,197,189,179,203,178,174,185,204,186,189,186,188,218,187,222,197,199,189,212,190,224,201,195,195,189,181,156,174,174,189,179,207,190,214,172,199,203,215,189,215,183,192,204,202,205,194,198,205,211,200,177,209,186,214,192,201,200,179,207,215,188,183,189,190,175,191,184,224,198,209,181,190,178,213,218,192,197,169,187,196,203,191,211,190,182,197,188,202,186,199,208,200,215,208,180,174,206,194,187,209,204,213,234,185,192,182,167,193,196,207,189,196,181,185,181,185,175,193,199,187,209,216,181,173,193,212,198,186,186,190,198,206,176,199,207,215,209,196,198,171,217,197,196,175,171,219,191,200,224,201,222,178,206,195,200,194,198,177,199,204,198,184,196,188,215,209,154,165,134,95,143,159,122,77,180,190,203,187,143,134,186,224,214,214,177,193,187,196,195,174,160,120,189,214,131,163,187,171,81,21,99,106,129,169,144,102,95,95,83,125,122,79,59,37,24,90,41,24,50,38,48,59,150,215,237,193,99,102,90,46,19,32,28,88,83,53,44,57,26,20,22,54,57,116,125,110,130,108,87,89,103,116,114,119,112,114,118,123,133,71,43,37,64,183,195,149,86,72,123,147,102,81,49,49,29,35,40,28,66,69,55,58,24,83,62,24,89,72,55,36,48,47,91,121,127,115,113,119,122,126,115,86,63,46,12,30,35,1,72,39,38,25,28,54,27,32,35,23,25,22,36,22,27,32,26,39,42,67,39,35,18,11,20,21,27,26,8,34,20,8,15,23,145,210,185,179,116,132,139,122,89,27,11,45,24,25,35,22,29,35,8,18,24,26,18,25,13,6,24,28,31,18,6,54,21,29,19,7,5,36,44,17,55,35,27,53,75,68,112,154,155,120,142,114,80,27,44,21,20,15,24,42,22,24,76,82,83,82,110,140,71,57,38,29,22,140,154,97,97,84,43,111,148,130,146,61,36,24,21,64,91,119,108,137,118,134,152,95,39,23,18,12,11,40,139,158,193,167,152,164,140,66,36,41,29,4,7,18,16,17,23,27,28,21,34,47,56,41,46,14,13,24,31,15,47,26,16,18,44,18,48,9,36,34,53,19,27,42,7,49,30,20,39,57,72,92,79,50,23,18,27,2,6,9,24,21,25,27,20,35,8,23,38,31,34,29,35,13,27,32,22,14,6,22,11,42,43,38,16,15,11,45,11,23,30,22,54,7,17,22,67,10,79,238,228,118,98,178,138,107,59,38,48,15,88,55,35,156,223,200,226,226,221,217,229,226,212,211,205,222,206,202,214,176,220,115,0,0,8,8,25,15,13,39,17,10,14,13,17,2,7,20,6,18,28,13,31,5,7,12,198,188,213,203,192,189,186,195,214,160,209,175,201,196,200,208,241,252,230,204,220,201,193,195,201,192,180,187,185,195,184,192,209,201,216,212,206,201,190,189,195,199,185,196,213,194,199,190,207,212,192,199,183,193,202,210,218,175,194,221,204,213,182,229,198,203,193,180,176,186,200,176,202,202,210,174,190,192,193,180,193,199,205,189,194,196,206,210,201,199,203,194,202,207,193,196,219,191,181,189,205,198,177,208,191,178,205,187,181,177,189,210,203,216,189,205,189,181,194,191,181,220,225,211,208,232,208,212,175,212,189,206,203,202,214,192,201,190,213,198,183,210,222,208,210,196,201,180,210,202,196,198,202,186,186,184,204,191,165,183,189,215,174,198,176,181,194,190,181,200,192,201,198,199,193,226,200,207,198,188,188,190,188,194,214,191,200,189,191,192,189,194,220,191,203,179,180,187,189,185,185,193,183,207,197,184,207,184,205,186,198,215,194,182,201,189,166,186,219,176,205,192,198,195,195,196,202,202,202,203,199,184,189,193,196,190,193,202,195,185,184,191,200,186,182,185,186,209,224,213,201,190,205,203,190,212,191,208,224,195,185,170,213,205,193,186,202,195,204,195,198,205,188,192,169,174,179,182,200,201,198,200,204,204,198,174,139,185,130,182,168,195,122,106,167,242,207,205,214,198,199,228,193,216,217,196,171,182,196,160,168,170,161,98,104,166,203,147,85,38,23,49,168,191,176,108,104,69,89,134,90,64,7,49,121,82,53,57,73,63,74,158,217,242,185,90,89,107,132,79,31,87,137,117,90,59,21,32,7,49,49,60,113,100,105,102,104,118,111,112,88,109,110,106,133,95,110,90,79,54,20,33,152,200,149,91,0,62,104,96,99,44,62,86,17,49,30,52,58,34,70,53,27,39,51,36,45,82,62,34,48,108,132,131,135,113,112,109,108,95,85,67,18,37,20,15,26,36,43,42,34,23,51,6,53,39,27,42,24,27,34,25,23,12,38,41,21,39,26,18,28,24,26,21,22,35,15,13,2,8,34,30,112,180,186,205,192,184,194,197,101,22,27,7,30,12,23,26,27,7,17,13,32,45,26,15,19,20,34,38,37,31,44,55,23,20,39,50,4,42,7,30,28,61,24,29,92,69,75,82,143,109,122,100,50,68,38,7,20,12,14,13,5,42,77,89,91,83,119,101,52,44,32,44,42,107,86,49,80,119,52,93,142,68,54,37,30,46,24,54,83,96,109,93,136,71,143,107,42,13,8,2,13,60,108,216,152,145,156,117,104,60,16,37,16,9,5,16,25,18,51,30,19,28,22,32,33,31,30,25,41,16,42,25,24,58,11,34,38,34,31,36,13,7,35,35,22,29,26,5,39,54,55,79,112,88,84,57,34,40,33,20,39,18,26,29,11,22,38,25,39,30,44,59,22,6,36,5,56,24,15,30,28,35,16,39,22,15,25,46,41,20,19,17,41,52,35,60,37,28,20,67,208,238,172,62,67,140,127,53,66,39,17,45,61,29,39,173,217,219,220,219,240,221,225,230,192,208,223,219,223,214,215,207,218,90,13,2,8,12,9,15,33,22,21,7,25,30,31,30,5,3,5,18,7,17,16,8,0,7,186,202,214,201,219,223,161,218,193,180,192,194,203,215,193,174,245,253,249,206,197,233,177,186,180,190,208,189,200,214,194,180,216,185,181,190,207,188,210,219,238,195,182,222,176,189,207,190,194,184,208,203,174,182,180,184,179,202,206,205,158,172,179,228,210,228,202,216,218,209,205,196,199,191,218,203,174,203,202,186,204,184,207,199,169,202,218,200,208,201,168,198,200,190,197,203,219,215,204,210,180,190,207,208,171,208,193,198,191,213,180,205,203,192,169,210,194,195,238,189,190,199,205,210,213,206,187,207,223,204,207,203,181,199,184,191,179,154,197,204,183,186,171,194,213,205,186,198,194,175,189,196,201,179,205,208,195,197,195,190,176,203,201,189,187,179,195,193,176,168,194,171,180,224,199,214,192,192,197,198,210,227,183,190,211,194,197,209,228,198,164,200,197,191,185,176,196,220,181,185,209,173,191,177,196,221,226,191,201,209,197,194,196,205,204,201,197,214,195,197,193,214,203,191,181,187,195,201,212,211,183,238,161,201,194,203,179,205,199,184,206,214,190,199,207,178,197,211,192,204,205,224,207,196,198,176,180,211,195,185,207,198,192,212,205,199,174,212,213,190,197,197,202,207,176,209,209,186,181,212,192,167,187,190,194,160,137,159,162,161,217,202,126,142,199,206,193,199,179,220,222,208,213,215,178,191,178,206,207,145,182,158,123,23,143,232,224,135,51,20,20,117,214,218,142,87,96,43,83,75,49,13,32,209,195,80,27,86,35,117,176,237,248,150,95,79,97,108,70,125,115,143,113,98,84,45,39,34,31,59,97,118,116,122,116,95,97,100,110,84,104,103,116,110,106,119,85,63,73,40,23,46,140,122,60,20,15,69,157,142,73,45,103,75,35,29,56,26,46,44,54,67,34,40,39,14,29,57,79,77,144,161,193,148,115,105,98,69,84,49,51,39,17,21,8,25,48,34,24,38,38,16,43,40,37,39,44,51,20,22,29,50,36,27,21,43,38,45,23,32,41,20,27,23,28,48,38,20,29,18,45,22,61,111,123,134,139,137,143,87,77,17,17,61,9,14,33,26,41,22,45,12,3,42,18,34,9,11,14,24,39,42,26,23,30,11,22,22,34,13,2,20,22,30,57,35,70,48,67,85,94,117,79,72,77,46,35,23,17,25,28,2,17,47,59,88,140,119,100,102,100,33,22,18,46,67,101,91,122,133,126,140,120,72,58,42,22,11,34,76,85,118,118,136,121,164,186,91,14,17,41,29,22,52,117,135,184,124,113,119,108,77,56,54,34,34,32,31,30,32,20,42,22,33,41,51,40,31,33,17,37,20,50,22,51,19,27,36,46,27,9,6,25,29,53,30,27,31,17,23,19,90,119,192,145,118,91,82,71,65,41,8,15,9,26,44,5,24,20,22,10,10,14,32,29,32,19,15,18,22,45,21,27,14,25,41,42,15,16,4,27,17,27,52,21,18,46,20,28,54,65,114,231,222,102,51,46,58,57,67,69,47,51,42,46,15,112,236,218,207,204,219,229,205,228,202,213,223,217,202,224,217,219,195,217,109,5,0,21,11,8,20,21,27,16,33,30,26,10,0,2,4,21,19,7,17,5,2,0,12,218,195,206,199,193,214,204,205,204,180,199,193,179,202,231,212,249,243,189,201,200,187,206,179,205,205,196,184,212,207,212,205,197,202,189,197,192,191,206,210,201,216,194,175,189,200,204,217,202,166,201,207,193,184,202,196,184,181,199,207,207,211,197,187,200,221,198,209,223,182,206,212,177,185,201,198,189,194,209,200,233,202,188,218,212,216,173,188,195,205,219,192,175,195,191,191,208,192,168,190,199,185,189,205,201,165,225,196,180,205,217,202,202,192,202,198,195,201,207,198,195,210,192,208,215,197,175,193,206,213,182,226,208,182,189,190,178,190,188,201,211,210,193,217,180,201,199,201,194,188,197,201,187,195,197,188,193,187,177,195,181,174,189,184,183,197,200,208,190,203,163,181,205,211,184,176,183,177,186,190,184,193,185,173,200,199,185,194,169,200,195,165,197,214,184,184,190,163,205,195,199,189,178,189,178,192,217,185,189,199,203,180,216,195,171,194,217,181,212,195,205,195,201,192,209,174,171,189,217,181,194,187,235,201,208,211,207,215,196,220,195,176,205,209,186,155,205,185,195,232,209,189,182,196,192,201,202,181,186,167,176,198,222,186,176,194,152,169,205,191,178,214,212,185,184,203,206,180,228,203,192,197,166,192,198,153,108,121,160,172,206,166,133,170,226,201,195,190,206,230,188,211,193,199,180,187,207,224,185,149,167,163,105,90,196,228,152,85,40,10,51,174,217,198,117,56,46,40,57,43,25,44,99,203,138,53,49,76,118,234,248,243,118,72,93,109,98,48,103,154,141,143,99,98,46,24,22,53,80,118,107,124,131,109,117,86,121,140,118,106,85,85,88,94,84,74,115,94,37,33,35,100,119,52,17,56,117,122,129,73,88,79,71,61,42,48,27,78,45,66,66,45,46,55,17,1,15,45,109,157,153,191,163,109,112,110,83,18,12,38,38,61,42,26,34,12,13,42,32,28,25,35,33,40,32,37,40,38,32,41,48,10,36,12,43,20,42,28,29,35,37,27,46,30,29,23,31,35,46,25,39,23,47,74,29,28,30,41,38,29,37,8,26,27,19,32,42,25,53,14,25,28,23,30,12,26,17,6,15,19,23,50,20,42,48,17,17,13,37,18,33,31,38,22,14,35,70,77,83,73,109,63,48,66,61,66,34,32,17,20,6,23,67,43,34,80,81,85,106,132,85,71,57,38,19,39,75,108,131,111,88,85,96,71,117,54,39,30,40,117,104,145,85,106,143,146,134,42,29,9,11,11,51,39,102,166,117,116,79,75,59,67,45,36,25,35,12,29,25,25,9,21,25,10,43,41,29,42,38,29,47,36,18,33,43,4,24,30,15,27,15,17,55,10,36,26,23,44,26,36,32,98,188,177,207,158,125,141,165,139,35,7,14,27,28,34,40,20,18,7,37,41,26,20,23,15,8,49,21,25,35,14,53,28,10,24,22,16,26,12,32,22,12,27,40,19,46,29,39,40,83,141,186,131,97,99,38,48,78,63,63,31,38,28,32,124,209,240,233,214,211,217,224,210,202,216,190,219,219,231,221,207,222,196,215,95,5,14,9,27,6,14,29,28,3,14,30,12,5,4,7,22,8,13,20,22,7,13,28,10,206,194,209,186,201,218,205,187,197,198,199,194,211,188,199,175,254,238,151,202,191,187,180,180,228,193,197,208,192,201,202,213,191,199,197,204,202,186,207,202,187,222,185,190,200,198,202,197,158,190,196,182,204,184,217,188,200,192,182,226,195,173,206,202,217,204,183,192,209,191,202,202,211,216,195,217,202,196,181,217,210,177,167,183,186,171,203,193,186,219,220,240,188,197,191,166,216,178,202,202,202,201,182,221,172,221,171,188,207,187,193,207,202,195,207,214,204,184,207,181,214,199,186,192,226,214,203,221,197,210,219,187,201,198,183,195,213,203,212,200,193,186,186,218,193,175,191,207,194,182,171,207,216,192,195,186,183,192,193,197,180,189,196,175,205,200,199,191,181,210,178,209,191,186,188,195,226,195,173,184,204,205,201,177,189,163,184,152,209,206,172,195,177,191,201,187,189,176,205,190,172,197,195,177,172,203,192,178,193,193,194,195,196,202,203,207,221,186,197,190,223,185,208,201,193,178,192,198,202,220,201,183,172,216,190,223,198,225,210,210,181,216,217,186,217,173,182,193,190,218,165,183,178,206,207,194,206,204,163,201,189,192,213,179,200,196,169,203,200,181,212,169,182,198,176,210,206,216,206,178,175,193,204,190,153,146,114,135,173,156,196,141,104,171,202,174,200,174,194,229,203,193,178,206,185,180,218,200,165,162,223,178,94,55,140,118,62,53,90,62,93,241,246,158,113,63,70,31,46,41,11,20,91,88,86,52,34,108,196,253,244,128,79,79,89,63,52,69,91,126,62,84,69,29,40,12,44,78,132,163,130,121,106,122,98,127,98,97,122,115,145,122,90,64,64,102,110,129,44,34,56,112,60,13,46,161,159,97,93,125,105,84,72,113,30,33,32,7,44,17,58,55,39,22,30,29,40,55,56,147,160,130,127,97,91,50,34,50,36,39,61,50,42,28,37,15,28,16,46,18,43,38,21,36,55,33,4,29,12,55,36,35,43,9,17,59,33,30,31,21,35,27,32,19,12,64,38,20,27,13,17,18,42,43,42,35,42,20,39,15,36,3,16,15,22,26,35,29,37,36,2,28,24,19,15,34,16,26,12,17,1,46,27,43,42,21,34,31,43,19,18,11,38,24,34,43,60,56,83,81,63,92,45,46,44,74,45,49,10,19,24,22,44,37,31,76,91,106,134,151,108,60,35,22,8,8,9,35,87,58,30,66,34,60,54,26,39,45,79,135,92,177,104,55,53,83,57,21,22,31,25,24,41,35,109,45,110,70,52,52,41,85,43,32,25,10,28,19,34,43,23,26,18,13,27,40,36,47,22,23,68,39,43,30,19,23,21,31,37,39,26,22,24,12,32,7,43,29,23,33,34,75,127,141,184,170,168,187,176,102,55,35,19,23,35,10,16,19,14,34,32,22,30,40,11,9,49,26,25,21,41,11,11,20,21,21,12,35,19,17,24,30,27,61,31,29,13,47,31,46,107,183,188,134,147,134,97,99,76,55,67,55,23,21,126,229,249,253,225,227,204,231,199,206,209,190,202,215,201,197,209,202,200,200,217,114,7,23,5,12,14,3,3,27,1,16,15,17,12,4,15,15,4,12,16,18,29,25,28,28,203,196,201,197,184,187,203,219,183,204,214,208,191,184,207,194,243,227,170,225,200,227,207,193,183,202,208,199,215,198,203,209,211,199,192,207,226,231,202,190,217,218,191,187,185,187,206,207,192,181,192,195,214,190,207,195,225,184,194,189,205,208,213,196,207,202,176,189,233,202,215,176,210,184,198,197,199,202,215,216,208,200,214,203,200,197,205,202,197,229,202,214,216,199,202,172,211,197,192,216,214,220,193,211,173,191,227,214,202,184,189,218,198,231,193,192,196,211,190,202,201,222,188,192,212,184,216,190,194,190,203,188,199,175,189,193,168,206,185,184,175,191,204,190,207,203,199,201,200,173,215,190,191,182,203,185,203,202,191,194,172,197,171,193,213,190,168,190,208,217,201,198,200,225,174,200,224,180,188,212,192,190,200,199,170,180,206,193,213,165,190,176,191,179,213,192,216,199,189,181,187,189,207,184,174,210,206,196,220,197,178,195,214,200,197,186,208,194,208,213,189,178,184,186,197,218,203,171,185,164,190,189,203,214,196,211,193,199,191,193,194,211,195,198,205,186,174,155,205,212,186,188,206,198,191,204,176,210,208,175,220,188,213,194,193,199,209,199,199,178,189,216,211,224,190,184,201,185,202,180,186,190,220,188,146,179,121,117,163,158,151,119,133,168,192,195,210,202,191,209,167,205,204,221,217,183,205,203,183,174,207,161,43,30,27,64,77,134,182,104,152,228,244,170,115,69,54,21,61,156,41,91,195,137,24,41,132,236,255,246,119,86,79,106,81,32,76,118,144,94,83,51,41,36,7,35,81,119,115,137,111,89,100,103,105,103,88,114,114,126,134,93,88,111,98,116,145,123,108,66,69,35,14,52,131,205,159,77,120,147,146,108,122,88,41,33,34,22,22,53,32,41,25,73,30,47,15,18,35,76,103,95,69,46,48,22,13,36,24,25,42,51,44,46,43,21,29,37,13,42,28,15,14,29,16,33,39,30,19,34,44,37,19,49,31,35,12,64,31,18,41,57,57,42,26,21,24,35,24,38,50,7,42,55,36,21,39,36,34,28,15,4,21,28,36,36,44,29,28,8,36,40,53,15,11,23,40,52,8,27,29,37,25,15,30,45,21,43,28,15,29,23,26,41,37,38,60,91,104,66,111,110,49,69,54,68,76,50,19,8,51,20,18,46,84,145,166,142,183,139,105,65,60,47,30,24,21,62,127,94,79,98,78,39,20,21,18,45,121,100,113,195,149,128,70,76,53,6,7,3,3,13,37,47,59,66,63,76,81,24,58,32,68,35,22,30,14,28,24,33,40,38,38,27,22,43,5,28,29,25,42,45,29,36,12,28,40,14,39,46,52,18,39,16,25,15,56,34,39,56,32,25,69,86,68,102,116,100,56,50,27,19,12,21,27,34,37,14,13,38,18,43,12,28,39,21,16,33,42,21,21,31,15,31,13,16,30,32,31,33,40,34,36,12,24,12,25,51,50,68,104,127,142,132,141,146,149,133,129,112,74,53,15,28,156,208,227,239,220,206,221,216,241,206,235,198,194,212,222,220,203,212,211,225,218,109,16,13,6,6,1,29,6,9,18,29,21,25,6,21,27,35,18,22,32,31,14,14,11,22,187,218,196,196,188,194,192,184,201,202,200,197,200,204,186,190,238,241,176,205,192,220,177,196,203,203,193,204,215,199,214,228,189,215,189,221,206,205,194,212,197,182,210,235,194,196,203,223,180,184,192,200,198,208,226,200,202,178,203,175,190,209,177,208,193,217,186,188,200,187,185,203,196,201,224,194,196,189,193,218,200,209,213,215,210,186,222,186,211,210,214,198,183,192,216,196,198,210,194,204,205,204,207,205,200,203,200,190,193,200,196,200,181,205,180,192,215,184,203,186,189,207,200,197,179,180,179,205,180,224,215,223,203,183,189,210,177,202,188,180,179,181,232,202,205,222,199,194,188,184,196,182,193,188,204,191,176,189,188,177,197,190,203,185,186,193,211,189,189,189,194,215,197,186,175,200,218,157,178,223,179,190,209,177,198,218,188,200,196,215,202,203,185,180,180,200,192,206,189,204,183,191,194,193,193,199,195,211,199,180,192,201,193,196,213,193,220,222,212,194,220,207,205,195,211,186,192,191,164,190,200,193,204,197,185,202,210,185,201,207,185,206,188,192,204,180,226,189,179,208,222,189,187,216,165,182,221,210,235,191,198,182,186,207,203,180,211,181,186,199,184,198,195,165,193,189,202,201,209,189,206,210,201,184,181,172,175,159,196,162,105,110,151,192,188,205,215,215,190,212,212,189,175,155,214,215,203,193,162,223,201,116,56,17,12,115,180,183,224,148,202,223,163,164,95,33,19,7,156,239,84,146,157,103,63,144,242,252,220,89,60,91,103,61,57,77,135,144,101,66,51,20,27,36,59,79,141,110,125,110,89,105,89,109,114,94,104,104,112,98,80,90,86,93,99,87,129,129,113,73,35,8,66,169,103,89,105,35,103,147,96,110,120,61,63,39,26,37,13,4,48,49,20,12,30,54,37,56,28,41,58,40,41,28,13,4,10,32,22,10,17,60,43,55,72,19,7,31,27,50,15,37,48,39,38,34,9,28,34,23,47,33,41,34,60,27,51,33,53,14,53,46,59,45,31,14,26,42,27,40,12,15,51,46,66,24,50,71,51,38,20,3,22,39,22,27,44,41,24,16,49,9,42,18,37,10,50,16,47,31,35,35,59,34,13,45,10,26,35,48,38,46,46,25,40,18,106,150,169,138,162,179,122,153,179,144,178,103,47,2,13,18,48,7,158,203,123,87,58,43,67,47,46,68,27,25,53,97,181,168,177,189,118,24,38,31,38,99,103,84,65,89,131,161,135,144,70,38,54,23,39,25,45,71,106,89,110,102,78,69,59,74,65,75,46,10,9,20,37,58,46,53,9,34,20,37,25,54,18,43,3,25,25,36,22,15,16,38,32,14,20,9,30,25,3,17,19,32,27,20,7,70,47,58,26,45,42,8,14,38,32,23,12,20,25,31,41,53,26,43,29,59,35,50,40,27,35,36,15,37,48,31,28,59,14,34,34,43,32,42,25,40,28,23,66,56,62,104,129,44,59,49,85,100,108,119,148,173,168,162,82,40,5,51,195,219,245,252,236,243,225,251,239,218,223,217,217,240,223,188,201,217,223,209,234,132,12,6,23,34,11,1,6,25,22,17,2,24,5,2,17,0,12,13,1,5,6,19,19,9,200,189,200,182,195,178,169,171,209,204,214,203,215,207,212,206,233,254,138,187,208,198,150,207,216,216,206,199,199,216,195,199,215,197,205,204,204,181,211,184,199,192,214,186,210,209,226,204,212,198,204,222,206,222,190,191,199,205,203,201,233,193,219,215,205,212,199,216,207,196,205,186,200,208,206,196,192,211,215,219,195,182,219,201,197,209,188,204,207,213,193,182,222,196,218,214,185,207,195,188,193,213,217,205,213,191,206,219,220,211,213,205,191,170,197,213,200,221,195,202,190,217,215,182,198,191,188,190,182,188,212,184,176,202,179,179,184,183,225,173,201,203,205,191,182,192,190,176,208,181,189,183,166,208,180,173,202,191,194,211,203,168,187,233,178,175,175,170,171,195,203,175,215,201,210,204,184,191,204,178,158,202,201,225,166,193,202,185,202,202,185,197,208,207,192,181,182,184,213,188,176,192,179,208,189,176,179,182,187,207,186,185,184,228,185,201,163,197,155,199,182,191,211,196,170,172,192,177,194,180,200,189,171,207,188,217,199,187,192,187,210,186,185,175,193,187,221,186,168,196,201,203,212,222,196,185,212,196,208,213,212,210,201,182,212,190,176,207,189,184,168,196,163,173,187,199,178,183,173,210,210,212,207,184,131,141,172,184,194,120,104,143,153,225,178,184,207,216,203,216,183,177,189,188,204,208,223,189,163,199,193,77,83,88,39,103,139,111,149,148,219,195,117,121,44,8,3,27,136,103,63,78,81,52,158,250,244,188,73,119,93,98,57,85,98,111,148,83,131,86,23,11,25,51,90,121,132,122,130,105,113,78,114,137,112,129,102,104,130,103,87,65,98,93,127,124,96,114,56,26,40,29,154,203,51,44,36,80,93,101,101,98,71,49,45,61,44,23,31,38,62,28,40,32,32,39,24,26,24,48,27,48,45,41,14,10,14,27,35,35,40,43,60,74,70,52,48,23,50,60,51,54,56,62,89,40,53,43,56,64,62,58,83,63,77,55,68,60,62,64,41,65,58,29,58,45,73,51,33,48,46,44,70,87,106,64,140,97,60,59,7,3,12,36,48,18,10,32,26,27,27,66,46,28,35,30,41,9,48,48,18,43,36,44,18,15,20,24,45,21,48,42,37,34,38,20,78,158,187,129,162,158,172,151,159,200,145,107,27,29,5,25,46,29,138,168,89,58,49,26,35,73,58,83,69,51,21,134,140,84,129,123,137,37,42,32,58,102,97,107,41,39,47,48,91,127,126,28,32,19,46,26,55,161,157,158,188,185,167,168,181,186,185,114,44,22,10,16,25,44,17,36,70,29,25,35,35,52,18,48,49,23,40,18,12,12,28,27,41,38,25,41,13,24,38,30,11,24,41,25,16,40,64,40,45,46,22,25,6,30,4,44,38,41,34,26,55,74,7,9,31,30,30,57,49,18,44,12,41,33,60,28,27,40,47,25,38,24,30,14,37,23,20,40,33,33,68,194,223,146,107,69,66,86,57,96,128,172,143,127,62,112,136,137,209,209,218,236,213,222,235,232,231,240,221,223,239,188,219,211,215,222,215,222,227,120,15,10,0,11,24,1,19,22,16,19,19,29,2,3,4,0,13,4,14,21,9,17,20,29,202,194,207,173,190,198,210,197,207,216,212,188,194,197,203,187,234,230,110,154,194,168,206,195,195,216,169,182,203,184,185,213,197,209,203,158,213,192,187,191,204,212,200,196,200,178,183,193,197,201,183,219,211,195,228,194,201,190,190,196,221,187,205,216,227,175,169,210,219,178,222,190,199,194,199,189,231,220,206,207,188,206,206,222,206,204,191,217,192,194,231,205,183,197,211,201,193,200,217,195,198,204,209,191,173,219,188,192,183,202,211,201,192,198,199,189,186,186,183,198,202,185,185,167,211,187,194,198,181,208,197,212,180,199,192,183,211,187,199,189,216,182,211,202,191,209,201,191,187,177,223,212,177,195,198,190,170,190,178,205,202,207,194,177,204,207,176,201,182,205,186,200,201,200,210,198,166,233,189,206,213,181,183,202,185,199,186,176,183,197,191,202,190,169,214,194,202,194,184,199,215,184,190,199,180,191,211,183,211,198,200,218,174,191,188,181,181,184,204,196,192,189,229,217,194,191,160,185,190,197,180,177,197,210,198,212,190,191,177,202,194,215,161,186,171,182,188,192,178,174,173,187,186,197,217,169,236,179,187,193,201,202,181,193,201,191,182,192,192,196,183,185,187,190,201,209,189,201,220,174,195,208,201,166,118,116,132,161,150,142,81,94,219,225,171,139,153,222,193,186,198,193,178,190,196,209,191,159,119,148,77,63,171,107,30,61,53,24,64,158,223,160,9,10,14,45,9,67,110,77,83,153,121,195,248,243,177,75,80,83,85,42,62,124,152,145,82,70,67,82,6,19,74,102,124,139,114,120,135,141,122,118,108,106,89,110,103,122,113,83,80,72,128,136,107,109,79,44,38,77,136,94,128,124,34,89,65,92,90,121,140,56,23,31,123,145,40,18,12,50,44,41,40,14,9,30,30,18,16,24,24,28,8,36,8,31,20,20,15,19,29,53,58,72,61,40,83,58,63,154,162,196,210,161,180,195,174,180,144,167,164,176,189,152,161,171,169,172,180,196,187,207,176,165,160,139,108,134,160,142,123,94,135,179,188,186,140,160,139,79,44,28,60,37,46,93,78,60,67,84,84,88,91,86,65,79,75,74,55,77,95,53,72,59,80,39,68,50,65,58,60,64,64,44,85,66,99,170,151,42,39,55,35,55,67,35,44,40,22,9,28,6,20,34,73,91,64,69,70,106,93,103,90,62,65,38,57,117,60,32,14,44,110,100,23,71,72,120,117,97,91,64,54,73,29,96,150,43,17,11,33,26,55,194,190,174,167,166,215,177,163,166,187,137,16,29,47,12,31,10,13,14,41,47,20,25,30,27,28,41,20,33,68,23,41,32,44,26,19,30,23,36,26,10,35,23,29,52,27,24,41,36,50,57,44,26,41,50,21,32,9,46,12,37,23,43,10,33,32,24,67,30,37,53,15,38,10,16,59,21,30,36,41,14,37,11,50,20,27,35,62,28,16,22,50,24,40,163,184,150,155,110,72,94,110,65,50,88,44,40,47,117,195,193,199,152,141,163,171,183,142,170,209,205,217,246,238,222,231,232,202,198,214,225,214,96,8,8,19,0,1,1,40,35,17,34,10,23,33,34,6,24,22,41,12,22,13,31,28,12,186,186,215,198,181,177,206,180,211,196,192,201,218,177,209,202,240,217,93,161,165,199,189,183,201,221,210,196,169,197,217,198,191,188,194,197,176,212,199,205,187,187,192,204,187,208,219,222,194,197,180,198,187,176,211,199,213,197,186,170,208,207,198,218,200,193,184,198,183,191,185,191,203,183,191,194,188,201,228,198,181,186,185,213,215,207,201,190,206,207,186,201,184,182,206,188,199,210,214,183,208,194,221,180,209,208,195,192,193,194,195,206,204,204,210,171,211,211,181,200,204,180,210,197,179,193,210,185,191,217,200,201,207,209,201,187,188,193,223,212,212,171,199,181,188,183,189,201,182,191,174,193,201,180,197,209,210,203,186,186,188,196,204,196,198,194,192,203,209,206,204,214,191,181,202,187,200,205,168,195,169,204,204,208,196,192,211,167,185,181,193,182,182,175,190,196,196,213,214,188,188,176,195,189,193,189,175,199,181,186,190,191,153,204,195,201,182,197,189,181,205,184,198,185,221,182,214,190,184,200,194,190,176,190,211,197,202,185,192,186,188,202,178,214,209,190,201,172,167,200,187,204,195,211,201,185,199,198,206,197,198,190,203,177,183,203,202,194,199,201,191,173,201,197,208,210,232,221,213,198,202,229,181,144,134,87,99,140,136,116,78,90,147,233,203,135,109,194,162,224,182,204,172,190,181,210,192,94,46,42,51,184,212,127,29,75,107,66,97,146,184,82,21,10,100,139,64,189,122,97,180,219,249,252,242,141,99,82,85,102,55,84,150,140,103,69,56,47,48,22,18,59,110,130,119,123,98,107,100,119,105,84,100,103,119,124,120,90,98,112,115,111,125,65,91,76,12,88,140,142,185,95,63,61,44,102,92,47,109,60,87,46,45,78,161,148,84,15,14,7,15,8,27,12,26,5,41,63,44,36,48,30,16,31,30,34,40,18,36,37,27,60,53,92,99,98,62,81,69,124,135,150,145,157,131,155,173,175,150,178,164,222,145,156,159,128,162,142,173,179,174,168,123,172,130,153,119,176,153,158,163,104,148,168,185,169,168,142,118,111,90,95,85,89,82,102,107,105,185,138,164,196,161,174,150,182,200,187,175,165,199,198,174,157,181,171,155,144,157,152,179,184,172,167,195,196,217,166,63,32,37,48,55,61,27,24,58,34,33,14,11,24,35,9,52,82,112,118,137,133,95,109,118,117,110,78,70,36,25,35,18,30,72,74,62,62,92,139,174,163,152,120,99,90,84,163,134,44,15,11,36,6,93,187,157,107,52,60,55,39,55,69,61,46,52,30,25,25,35,19,59,28,39,43,28,50,35,39,43,40,50,39,32,48,33,60,33,61,40,39,59,55,37,32,35,30,43,40,11,11,19,44,62,76,99,57,89,34,51,32,32,29,13,8,21,22,8,26,35,35,33,50,38,53,43,37,17,30,32,38,46,20,22,36,41,54,47,31,32,32,32,42,49,31,11,52,34,155,111,114,90,49,52,112,103,50,23,38,44,32,27,154,137,146,141,114,129,132,132,146,119,126,125,144,176,198,199,226,243,234,236,244,236,207,205,102,7,10,32,1,8,5,29,19,16,37,3,26,11,4,8,36,13,17,1,15,14,3,41,5,163,194,201,214,198,199,208,188,188,202,230,209,209,195,199,194,253,225,122,169,210,200,197,199,200,216,210,188,202,211,191,204,194,194,181,204,201,187,190,217,190,175,179,186,207,194,215,215,195,205,198,201,200,188,169,227,193,197,184,193,206,181,200,205,192,196,201,211,209,206,208,189,190,197,196,189,189,216,194,212,195,192,183,192,200,207,187,190,207,219,211,199,169,187,204,173,190,197,172,202,207,206,200,232,186,207,206,206,185,221,182,203,215,209,195,189,195,190,187,172,208,205,219,217,200,199,192,179,183,210,193,190,176,176,205,195,199,205,199,181,185,200,190,203,211,204,180,187,202,187,205,188,204,165,203,193,199,206,208,197,200,197,197,161,212,216,177,183,206,189,217,196,206,179,196,186,179,207,194,205,188,200,212,183,207,195,222,203,216,187,183,211,170,202,193,183,189,176,177,192,186,199,190,173,195,188,161,175,197,158,208,198,190,183,180,187,193,164,186,200,195,193,189,174,182,197,207,198,180,185,203,212,218,174,227,177,205,223,198,166,191,195,205,188,180,186,170,173,199,179,188,168,180,195,211,181,179,204,170,192,225,213,193,215,190,204,185,199,192,184,202,196,207,235,237,242,160,170,200,192,227,166,149,130,115,113,114,146,146,97,101,62,109,194,230,148,121,213,201,209,207,209,180,195,220,210,110,89,34,29,110,212,220,121,55,102,163,151,89,151,159,153,158,108,234,125,111,191,128,97,104,146,234,193,105,117,81,89,60,96,103,117,141,94,67,48,27,18,22,57,81,101,126,140,111,108,120,117,119,100,124,94,85,97,110,92,103,96,97,85,107,101,93,90,64,4,75,185,173,133,122,94,65,41,36,41,48,71,79,51,22,53,130,159,168,107,33,44,3,26,14,9,28,19,19,20,28,60,51,38,22,16,39,13,33,24,16,1,41,36,32,27,56,69,63,97,46,86,57,43,29,32,35,33,33,68,68,39,39,54,52,61,62,40,60,23,38,45,37,44,35,16,38,28,35,48,33,25,77,53,25,29,93,110,145,140,101,116,87,41,73,32,33,47,24,47,81,64,62,95,76,63,72,82,75,101,122,111,113,104,116,126,92,130,101,135,111,107,101,138,153,141,147,150,156,158,169,97,87,113,64,60,51,70,63,70,57,46,36,21,18,22,17,5,18,101,112,120,93,102,152,165,187,181,168,59,79,104,46,55,49,60,84,42,77,139,157,196,185,167,150,87,121,156,146,149,41,5,40,22,11,38,45,94,87,65,58,27,47,40,42,51,34,61,64,60,45,67,53,66,118,116,137,133,135,142,139,131,114,118,112,89,97,89,105,109,78,87,78,100,75,91,65,75,58,53,70,60,69,72,61,88,146,145,162,171,178,159,49,48,21,33,16,22,30,24,28,37,32,80,98,51,67,50,27,33,43,58,41,48,40,46,46,30,40,55,43,48,22,65,45,49,30,24,52,97,141,155,152,75,53,13,20,89,107,51,17,22,71,66,63,139,140,127,113,131,111,125,120,118,102,119,111,132,150,147,177,171,202,223,184,247,226,187,204,120,0,2,22,12,0,15,32,4,28,17,38,11,8,0,19,3,4,0,10,6,38,39,12,0,204,194,203,180,213,230,203,194,196,185,209,219,195,210,195,218,243,216,123,204,192,195,204,181,191,210,186,211,189,184,199,209,203,191,179,212,201,198,199,186,167,215,198,211,215,188,205,177,192,192,191,204,173,191,217,235,201,182,199,195,211,179,191,217,193,212,197,219,180,217,169,226,183,191,201,166,173,172,204,206,190,215,181,202,218,197,203,192,198,219,202,190,194,201,189,201,186,208,178,197,204,213,197,209,200,202,182,213,192,198,198,186,180,200,179,208,197,190,187,189,198,184,192,197,200,176,190,169,206,201,172,216,194,187,187,193,221,194,187,208,208,200,195,203,181,233,193,202,190,194,174,177,182,196,202,210,197,190,168,171,179,190,193,213,183,209,199,192,193,170,187,173,199,204,172,194,195,190,190,177,209,205,180,180,217,185,190,188,195,199,204,190,224,213,200,176,189,179,200,201,175,171,199,184,205,187,172,167,195,203,180,193,225,164,191,185,186,186,189,201,205,194,209,203,208,185,211,196,195,161,190,187,186,183,205,203,207,219,196,174,182,197,187,191,202,189,202,186,205,213,198,178,210,207,187,178,200,182,179,196,207,194,187,207,192,196,235,196,208,196,206,187,199,223,235,200,109,182,207,171,218,162,122,93,74,102,182,137,97,58,93,44,76,115,134,129,147,211,247,224,224,224,219,247,225,154,149,163,80,103,93,188,221,90,61,26,73,87,75,110,212,238,243,161,125,111,89,112,68,89,68,66,160,114,83,85,93,70,67,100,121,131,120,89,46,42,43,36,55,79,93,176,135,136,107,103,109,107,95,104,108,96,108,80,95,113,78,65,81,88,102,127,106,73,22,6,78,109,129,117,59,37,50,47,56,62,64,36,62,51,56,102,146,138,124,58,32,23,34,21,0,10,21,26,6,34,30,59,38,21,57,30,42,33,34,41,34,13,21,23,45,34,45,50,38,84,77,83,86,59,22,33,19,50,27,50,60,60,39,52,39,59,33,69,77,116,86,82,18,12,33,73,62,43,65,36,73,10,31,37,15,32,88,113,123,64,82,55,73,67,28,23,12,38,67,55,76,79,59,74,58,89,63,75,32,14,65,90,55,9,54,50,76,62,29,28,74,99,42,32,44,55,61,58,38,32,58,37,64,135,109,107,110,122,123,90,53,13,13,19,30,37,37,26,85,143,113,83,127,178,165,125,86,102,134,143,86,72,73,94,87,104,117,151,130,196,237,211,167,100,85,74,70,82,122,130,51,19,12,3,8,23,30,34,92,75,73,70,49,40,54,62,41,48,77,51,48,92,122,126,93,140,126,154,156,154,165,149,134,120,132,152,156,173,121,125,162,164,138,130,153,103,137,146,135,140,172,79,148,175,159,156,168,213,158,167,160,187,108,70,49,55,41,58,49,55,59,88,89,161,129,137,128,126,107,123,124,111,122,123,122,89,104,84,78,133,84,99,90,102,110,60,49,52,116,169,194,146,159,119,72,67,95,136,132,110,106,127,155,157,160,153,140,131,138,144,131,119,114,115,121,124,109,129,120,123,136,124,159,168,191,210,234,235,231,100,12,3,26,6,2,3,22,0,12,8,17,17,0,1,15,5,4,2,29,24,24,25,14,18,200,190,189,183,213,210,215,217,186,202,179,210,179,209,184,197,240,212,159,200,196,205,170,231,200,207,200,176,184,225,196,208,180,183,185,211,200,203,188,198,212,186,202,211,194,189,188,164,197,207,187,189,181,215,179,195,184,190,203,180,200,218,204,200,185,180,195,193,167,182,197,189,216,214,179,175,203,190,201,211,180,212,204,196,193,217,201,204,194,189,200,188,181,194,192,204,192,179,209,198,194,207,193,192,216,219,166,202,213,204,213,195,191,180,194,209,202,189,199,167,191,220,216,188,205,164,188,187,189,206,196,189,176,194,183,202,212,194,203,185,188,189,214,181,209,184,203,176,161,172,198,179,204,177,188,193,188,178,208,165,199,183,216,184,180,174,206,186,212,229,193,196,200,189,190,218,210,195,192,185,176,201,213,212,193,185,188,173,182,194,195,165,201,182,190,208,186,205,178,173,182,182,198,189,170,191,198,190,171,171,159,188,194,197,203,221,197,215,183,170,210,191,201,181,182,184,192,198,173,201,179,214,191,180,192,211,203,200,184,212,198,186,217,189,214,185,185,198,211,178,202,167,184,201,180,202,217,179,178,189,201,170,206,185,198,185,190,186,190,201,195,162,132,193,164,109,137,241,243,193,217,183,113,98,68,120,197,173,77,42,64,55,28,24,55,78,136,203,206,193,159,218,214,206,188,104,169,217,126,94,85,138,131,86,68,36,31,13,6,82,215,244,237,144,72,81,202,157,72,60,7,49,83,93,115,112,37,69,142,149,136,82,58,62,26,31,15,36,84,88,137,133,126,95,136,115,122,101,126,116,118,86,113,114,94,77,88,80,84,127,137,132,73,32,35,22,82,101,124,92,82,106,66,29,25,51,39,38,46,27,41,103,114,94,107,56,37,62,51,23,23,34,6,8,19,23,25,34,47,20,31,30,8,26,16,17,25,47,28,14,38,16,25,42,49,47,84,100,86,90,61,62,22,27,54,16,38,47,64,56,46,43,35,67,122,149,114,72,33,67,118,112,111,77,42,69,53,81,47,50,24,42,88,73,104,100,76,80,46,62,50,17,7,43,54,97,112,141,60,62,117,104,112,139,60,38,91,122,96,13,29,103,109,105,10,46,127,149,57,79,110,89,129,96,44,14,54,45,106,145,114,159,141,125,165,110,20,34,35,9,43,4,22,57,87,145,86,102,156,93,62,43,74,24,26,110,80,74,103,124,169,174,209,154,144,200,117,42,15,3,60,53,97,46,86,156,70,18,21,37,26,19,43,43,103,116,138,90,119,93,116,111,59,26,19,72,31,27,23,32,75,72,61,58,99,45,43,73,50,45,37,65,60,51,57,91,75,75,76,54,74,60,67,56,62,64,88,87,123,124,117,120,143,154,174,159,152,128,87,92,75,79,50,55,56,52,74,112,126,106,166,117,130,146,136,142,173,120,138,143,150,147,157,172,174,171,189,173,156,176,145,86,43,113,139,155,154,128,145,157,159,174,180,187,167,155,160,185,193,163,153,138,126,142,137,138,127,125,132,111,147,130,120,133,139,118,112,118,128,136,145,178,217,228,216,101,19,10,26,10,0,3,0,4,16,50,15,5,16,13,2,7,6,17,7,15,27,11,16,6,214,172,188,190,210,191,198,196,204,193,174,179,183,189,204,211,253,205,191,201,192,219,202,191,184,186,212,201,184,189,201,196,203,215,200,193,207,195,201,191,203,211,220,179,202,190,180,199,174,198,185,205,193,195,199,184,194,178,194,201,178,198,205,214,194,234,196,195,205,202,194,192,192,186,192,211,184,193,208,179,233,190,193,179,189,186,206,224,181,203,166,191,167,193,198,207,181,197,207,187,205,178,194,225,195,187,183,197,190,194,187,205,195,192,219,183,188,200,184,189,174,181,225,198,168,176,196,208,191,185,205,191,172,202,188,186,206,198,201,211,178,206,200,202,184,165,207,206,207,180,210,196,205,202,206,187,208,223,189,187,180,165,175,168,185,193,183,180,192,206,201,196,206,189,170,210,201,180,214,179,188,176,185,180,178,185,175,198,199,170,181,188,196,182,181,176,193,180,185,184,198,159,185,189,211,178,187,188,204,193,198,203,207,207,187,211,167,223,189,188,211,197,186,174,202,181,196,202,207,198,187,169,190,189,210,168,191,194,188,208,214,190,199,194,188,180,186,181,181,217,184,179,194,180,192,210,204,213,177,185,208,186,207,210,196,206,200,178,214,188,191,58,53,95,21,26,68,147,160,120,133,131,123,103,86,111,145,146,98,89,91,109,67,68,59,18,62,84,172,179,168,173,131,150,133,75,119,122,53,66,50,85,123,100,88,25,58,33,26,98,182,244,247,183,115,151,248,157,96,51,0,57,110,101,76,62,79,141,108,119,57,55,18,23,17,12,42,75,108,112,157,103,116,89,90,148,80,105,145,122,107,102,86,102,85,83,99,107,132,112,124,96,23,3,19,12,118,85,71,83,90,133,82,33,54,43,54,55,39,46,48,89,93,62,56,50,38,42,72,34,20,15,19,13,15,29,44,29,26,12,39,24,4,38,36,16,58,11,34,32,30,38,32,56,69,87,103,76,132,90,88,51,63,56,43,28,47,59,46,55,47,40,62,77,98,104,108,33,21,117,106,128,103,85,35,36,47,42,38,25,26,18,44,92,93,73,45,35,64,18,51,33,15,1,54,100,95,128,45,67,125,109,117,152,87,2,95,143,108,49,37,106,100,125,57,62,113,165,61,128,173,134,156,95,48,35,34,14,119,142,127,113,94,128,129,81,12,25,6,19,19,47,14,6,68,155,98,152,158,68,55,50,107,48,26,94,75,67,54,111,172,191,163,79,104,185,63,13,76,58,92,86,100,46,52,145,91,37,40,8,1,19,12,34,127,150,141,132,144,129,126,98,29,9,57,42,82,27,70,68,58,78,100,83,64,60,26,82,98,70,20,45,62,62,94,25,45,69,81,47,67,73,70,72,48,54,85,38,29,32,24,84,97,132,89,118,141,93,86,54,42,36,41,45,45,48,14,66,39,63,53,52,49,78,55,62,70,67,66,103,97,63,66,108,102,93,82,119,106,95,91,52,113,161,142,121,132,124,127,150,198,167,190,180,179,166,128,145,131,101,126,136,121,147,130,126,120,106,106,119,119,126,124,126,133,143,130,127,117,108,110,132,179,218,213,123,12,0,17,27,4,13,19,22,21,16,15,4,12,2,16,4,24,6,15,23,11,12,13,8,180,180,201,189,198,200,212,202,201,185,175,189,208,203,161,179,227,235,208,206,184,192,200,200,198,178,218,201,191,187,172,202,168,181,195,204,195,185,195,215,204,182,195,191,163,211,200,199,168,212,197,195,185,189,204,189,170,188,187,181,197,179,203,222,173,204,196,205,195,184,182,196,177,161,210,199,195,191,201,214,181,190,188,215,201,189,211,197,202,221,205,192,213,183,205,207,186,203,176,208,203,185,193,192,196,217,193,188,178,196,206,209,181,189,181,193,198,211,197,198,192,199,201,190,204,182,176,208,179,185,189,184,172,176,200,174,187,173,173,182,207,192,198,197,203,187,199,219,186,194,194,196,189,196,196,174,199,214,203,177,202,186,174,173,162,171,215,195,179,231,207,195,208,166,198,192,181,168,183,197,187,193,184,180,174,194,190,180,204,195,186,197,184,200,202,199,181,178,180,202,184,195,196,190,172,181,183,211,197,189,170,188,165,212,194,193,182,210,182,192,188,179,219,197,183,185,194,199,214,177,172,176,185,193,190,206,195,200,202,187,201,185,191,183,202,192,192,205,206,195,190,201,189,187,200,176,216,206,197,194,182,187,180,186,211,179,198,215,180,210,191,83,32,86,60,4,5,9,16,42,86,68,104,80,80,94,76,121,116,89,123,92,70,71,35,0,11,73,107,74,97,121,132,158,146,94,90,84,33,33,44,64,118,117,54,19,59,10,91,212,181,137,138,81,86,164,230,71,60,35,47,132,108,53,67,102,129,137,116,77,51,74,62,28,38,53,120,126,104,107,100,122,115,111,86,115,93,118,88,107,121,122,73,89,78,93,107,92,140,109,62,34,11,45,45,93,143,102,81,101,122,103,82,44,49,38,41,64,51,64,38,50,55,66,79,52,41,26,13,49,11,7,13,31,13,33,37,10,33,25,13,24,37,48,12,45,20,29,27,2,3,17,25,30,64,102,85,113,113,79,69,87,68,54,32,28,52,52,44,40,15,60,5,59,102,118,92,30,43,129,144,141,147,132,60,35,48,23,62,24,29,31,120,36,59,78,48,51,38,49,74,27,55,33,39,101,108,90,45,34,118,84,135,133,38,2,88,147,93,41,44,122,126,165,114,119,111,101,5,61,81,84,119,33,37,49,18,29,174,156,82,119,65,118,111,72,9,15,21,15,35,34,36,30,39,137,46,146,148,67,55,63,159,81,23,121,110,73,31,48,62,56,10,63,163,187,24,51,116,42,120,104,107,74,51,130,144,65,19,30,36,24,25,7,106,160,130,117,109,136,132,81,33,61,59,22,71,71,73,84,81,130,140,123,118,39,69,154,131,81,36,34,84,107,60,42,51,126,128,73,64,107,124,73,90,112,113,55,18,41,48,68,101,89,135,93,106,66,84,73,44,44,20,34,35,65,70,71,102,75,46,66,76,60,76,52,78,78,84,74,43,60,37,48,59,43,24,34,42,47,38,100,149,155,137,156,118,144,162,174,188,160,180,178,146,136,154,120,125,130,119,131,125,144,117,119,109,121,127,125,128,133,113,105,140,119,119,123,131,134,121,130,151,172,192,121,7,33,8,1,3,13,15,11,24,20,6,0,26,2,4,5,23,8,17,7,30,27,33,30,209,175,210,180,196,199,210,181,181,206,193,201,224,207,184,176,251,206,192,219,194,218,201,203,202,187,168,164,178,196,203,191,202,211,191,195,198,199,206,211,192,210,189,186,180,182,212,184,209,192,180,213,184,215,198,192,218,185,210,214,180,188,179,203,212,179,193,194,197,179,193,185,188,220,202,192,194,176,201,184,194,187,204,177,207,197,208,202,204,201,214,194,186,196,186,193,194,193,207,204,205,189,190,196,193,221,172,206,193,214,203,183,175,197,205,200,199,208,194,199,202,191,178,201,172,174,189,181,196,180,199,203,204,203,203,187,187,203,189,196,191,203,196,193,195,179,187,199,188,207,181,208,185,200,186,180,178,226,176,179,176,194,185,197,197,224,205,181,182,187,165,197,177,219,174,190,208,203,180,178,191,191,182,188,174,210,204,185,170,186,193,219,200,177,186,193,170,211,187,202,168,177,185,186,188,185,196,187,186,184,201,213,207,186,192,184,200,191,213,204,201,200,212,191,180,205,190,189,190,179,189,189,197,194,185,189,177,178,214,194,201,182,207,190,188,213,196,155,190,193,187,197,192,205,166,188,185,206,194,212,207,190,195,199,222,204,200,199,200,216,232,137,59,119,118,60,27,26,33,17,100,70,84,58,87,112,65,82,157,153,104,53,50,71,53,26,65,66,94,136,119,150,154,147,110,165,147,124,79,89,92,80,139,103,43,56,35,13,72,118,68,109,82,50,30,161,211,32,42,16,31,101,72,117,127,128,133,83,46,79,62,163,83,50,77,121,148,133,101,112,100,117,103,116,75,101,92,113,107,138,121,80,67,81,111,92,113,62,129,54,24,13,16,62,112,112,166,173,113,89,61,123,94,45,14,7,42,46,24,35,36,46,73,44,57,49,45,43,31,51,12,45,28,13,32,16,23,34,10,26,27,26,7,19,40,46,40,32,10,22,38,45,36,38,42,61,90,82,88,71,40,57,58,54,35,20,19,46,24,38,25,51,46,63,105,116,81,36,17,117,97,88,110,136,54,26,47,39,50,47,52,111,145,157,182,140,122,132,138,145,150,115,34,26,21,93,75,44,9,68,132,105,141,93,57,8,95,147,97,29,45,115,143,121,119,131,131,143,15,25,60,85,137,67,7,36,13,42,169,168,91,82,84,87,93,49,14,15,2,26,41,21,12,21,75,112,107,130,107,43,56,156,232,92,2,95,155,75,45,34,86,46,67,192,242,154,0,62,114,41,142,120,98,80,130,184,106,46,34,34,7,39,8,25,126,152,116,76,86,117,101,72,48,39,48,59,74,74,109,48,72,91,88,91,99,47,66,145,97,47,32,24,97,103,80,28,23,116,126,40,63,116,124,123,170,156,94,54,15,42,74,82,59,87,67,40,52,18,44,59,14,31,14,47,31,53,27,65,96,130,111,118,132,59,50,82,105,116,117,48,71,37,51,72,48,30,29,39,15,32,108,131,168,148,118,125,138,159,156,153,156,160,150,151,138,142,152,143,166,160,136,153,152,124,143,124,136,152,147,146,133,127,124,113,136,102,126,125,140,124,130,127,135,151,149,105,7,2,16,22,36,14,15,20,21,18,0,39,3,4,2,29,7,3,17,21,0,17,6,20,195,176,170,184,210,213,179,216,212,189,202,177,206,193,188,151,207,160,182,206,203,201,172,209,206,194,175,172,198,199,192,169,182,182,192,189,190,185,199,226,199,183,191,177,190,185,197,193,207,193,229,200,204,187,185,204,193,204,208,205,216,212,203,210,176,180,196,196,193,208,192,197,211,188,184,191,212,205,206,191,193,202,208,195,169,184,187,197,187,199,176,200,201,188,208,177,182,178,191,196,178,180,181,205,188,189,189,174,191,178,206,188,176,188,204,206,193,202,201,180,187,191,195,190,208,209,218,203,183,192,180,209,210,204,189,188,178,194,202,185,185,173,194,187,192,188,177,178,181,193,179,187,192,191,188,199,192,194,212,145,206,204,177,197,202,221,207,175,189,193,177,185,188,186,198,203,197,203,190,155,193,192,169,179,208,173,206,184,204,181,186,202,208,178,198,188,191,168,192,208,209,185,188,198,188,199,180,211,180,201,193,196,195,196,203,198,196,194,194,184,200,161,203,215,205,210,190,178,160,189,179,190,184,185,190,205,184,210,196,191,185,191,185,207,182,196,192,168,189,197,199,204,187,206,173,169,184,188,203,194,181,198,195,205,184,192,205,195,183,223,252,157,149,205,215,193,162,105,64,34,85,69,95,59,81,154,112,103,113,139,109,28,40,29,21,19,17,50,109,106,97,101,96,86,162,224,196,175,134,148,167,134,167,88,106,214,81,37,79,46,68,150,132,24,69,214,168,4,14,6,102,134,107,128,132,105,96,99,67,132,153,166,84,54,80,98,133,109,97,102,121,102,98,80,69,76,80,111,121,113,84,90,106,85,95,77,102,122,40,8,23,34,71,131,130,129,140,139,116,80,112,105,44,53,14,17,19,32,47,29,47,36,45,33,35,56,61,43,35,69,39,39,17,20,9,8,17,16,22,30,32,28,30,29,38,21,39,29,18,45,44,19,31,51,39,55,54,55,60,51,57,53,28,23,27,51,39,41,28,47,38,30,50,65,95,98,107,34,19,31,59,30,84,49,38,54,39,36,46,67,65,118,232,175,188,224,182,227,223,226,204,150,43,15,16,80,99,40,21,58,111,100,105,119,85,20,79,132,87,16,57,99,147,68,91,140,160,147,15,57,103,93,136,62,10,34,36,65,189,149,92,84,75,88,74,94,4,15,21,30,11,24,30,13,46,90,69,118,86,85,116,230,209,42,13,103,160,153,111,99,139,143,218,244,187,112,7,52,112,113,111,63,54,134,182,201,98,16,36,29,5,33,26,62,155,145,88,90,79,52,82,63,31,14,42,63,80,94,92,69,90,62,31,91,104,51,57,140,62,52,10,24,124,90,69,32,37,102,80,31,75,117,65,105,102,117,57,32,8,17,42,80,103,55,73,72,54,37,44,35,39,25,26,19,22,40,44,78,37,119,113,93,66,24,17,89,108,112,85,33,36,40,55,53,47,9,35,52,68,139,167,158,174,156,137,151,139,124,142,148,129,130,149,144,165,134,165,133,151,142,140,155,149,150,156,144,149,158,175,158,123,130,128,122,139,101,122,130,148,138,116,113,118,122,149,111,37,4,18,16,12,40,11,30,12,13,19,17,22,3,27,14,10,12,29,8,28,4,11,15,187,211,179,213,200,214,200,200,214,208,207,204,199,226,240,170,163,150,152,185,167,194,209,206,197,213,204,191,211,203,178,198,220,208,206,196,199,211,188,197,194,194,200,201,198,191,216,197,192,190,216,205,187,195,198,197,192,168,207,186,196,178,205,186,206,208,194,173,179,184,172,198,205,202,230,191,186,208,202,189,217,189,202,206,209,196,194,196,204,177,207,186,176,210,185,164,178,201,180,171,174,169,193,171,200,221,201,200,207,187,206,200,207,174,178,210,186,214,193,183,200,197,197,206,196,200,186,188,194,174,216,186,168,178,207,178,194,217,213,196,186,194,190,181,209,203,196,191,200,187,213,203,203,201,183,189,189,190,174,195,198,180,200,184,172,187,180,217,191,187,177,177,179,193,206,194,194,183,198,181,203,205,186,193,204,188,178,206,214,195,203,187,188,213,215,216,195,181,197,198,174,195,217,187,191,201,160,187,188,186,203,192,192,216,207,201,183,202,220,178,174,193,178,191,166,173,167,200,205,193,197,205,206,184,179,199,199,176,210,197,209,208,184,199,205,163,177,208,168,190,199,192,192,179,192,183,192,192,189,194,200,191,168,193,161,188,203,180,192,253,235,149,171,218,222,243,251,250,199,147,107,77,103,40,57,133,124,77,48,98,114,72,51,66,27,35,18,23,104,25,22,11,1,66,131,186,129,113,96,106,106,67,74,16,106,180,97,175,185,53,125,209,141,64,144,219,106,27,17,119,217,172,156,148,127,84,84,43,93,124,173,154,68,58,82,78,134,87,99,93,113,99,90,107,57,82,106,95,113,61,85,94,110,82,103,117,66,38,30,14,20,72,118,120,131,134,129,108,80,92,110,72,45,62,34,30,34,42,52,39,23,3,13,35,35,59,39,47,46,85,78,59,63,28,51,28,13,13,12,3,27,31,43,33,16,16,30,24,28,34,33,14,31,72,83,90,80,102,80,106,117,97,81,60,65,88,128,53,76,56,78,87,62,104,80,104,90,58,51,34,76,95,87,58,73,40,29,84,66,63,92,150,165,110,111,65,98,128,93,120,106,81,75,55,50,69,120,57,24,114,121,81,108,99,73,85,101,131,106,25,81,116,115,49,24,109,133,148,58,22,102,99,84,20,24,54,54,119,186,62,57,55,52,95,66,68,42,39,36,19,28,25,15,19,12,47,45,77,94,116,107,176,103,63,20,16,78,166,154,191,127,199,171,168,126,46,0,31,44,87,104,48,101,109,169,126,40,24,8,23,54,26,47,90,165,118,51,56,34,52,57,57,44,27,52,47,117,94,127,101,93,23,13,91,117,11,71,162,68,67,60,78,131,95,65,34,60,130,96,9,99,120,41,31,49,82,65,28,26,22,73,127,128,123,126,105,64,62,92,89,91,56,29,37,49,82,85,84,67,104,80,53,63,33,56,112,101,107,34,28,39,45,80,73,50,25,7,71,157,167,148,101,75,135,139,159,115,168,131,136,143,137,145,180,155,210,173,142,138,138,113,162,136,156,170,141,158,153,152,157,127,135,152,159,129,110,123,128,142,126,129,97,107,134,128,99,16,3,4,9,28,16,18,12,15,4,6,16,2,2,16,22,7,39,10,25,26,8,15,8,183,211,221,223,180,201,205,167,222,193,197,182,222,220,211,149,136,121,143,204,187,230,186,184,194,185,192,191,171,202,204,185,180,191,194,205,171,208,185,196,201,203,176,204,199,197,210,216,201,195,185,214,185,184,193,226,191,195,204,217,177,196,201,214,196,197,194,181,202,190,204,203,199,192,175,207,201,207,214,209,207,188,186,192,185,192,200,179,203,187,181,185,184,191,189,203,193,190,172,204,216,191,205,189,201,201,207,190,196,189,189,186,208,181,190,194,184,178,189,203,193,178,201,186,191,178,219,190,183,186,188,190,208,197,176,194,167,202,184,165,202,200,194,198,187,199,192,210,210,202,207,184,204,181,189,181,186,179,202,219,184,172,175,171,196,191,191,195,198,193,186,159,178,218,175,186,183,205,200,215,195,188,219,181,204,201,190,194,192,199,189,225,174,173,204,208,205,181,190,206,174,165,191,191,200,192,186,191,190,216,207,187,202,208,196,187,186,182,212,199,183,213,170,187,196,202,197,207,193,185,170,192,191,192,176,220,208,213,176,205,178,173,194,186,174,186,177,193,186,200,196,177,198,188,202,201,179,156,194,194,209,202,214,180,199,184,202,215,214,249,217,124,157,182,227,232,243,251,240,117,94,67,81,94,95,115,142,128,59,39,104,130,153,105,34,56,74,113,145,107,101,85,75,103,149,116,105,49,44,93,83,60,90,67,64,110,102,207,117,52,146,171,62,78,137,195,131,66,96,203,201,142,123,84,87,68,18,4,49,51,135,171,91,70,90,82,99,103,91,101,94,118,104,89,90,101,100,83,108,85,109,126,104,104,101,79,28,22,9,31,71,123,121,107,95,118,124,98,130,85,58,19,10,107,95,46,26,9,19,26,39,22,36,40,41,40,27,36,63,77,58,68,40,38,45,51,4,10,7,15,5,56,18,23,20,30,40,55,14,14,43,30,54,116,175,173,173,149,136,165,180,184,150,168,173,202,203,162,166,180,163,170,180,163,146,153,147,140,181,159,172,160,194,196,129,164,167,144,174,165,193,184,143,86,64,67,82,95,91,89,93,131,130,141,172,183,171,158,182,158,149,145,160,162,161,162,169,150,132,141,158,113,135,128,90,115,106,156,114,132,153,123,121,102,128,113,128,196,166,133,130,111,105,108,109,130,62,65,81,64,80,67,86,60,64,70,52,108,137,120,113,69,42,43,66,41,47,97,130,142,140,131,107,114,45,12,53,26,39,43,97,86,84,109,77,53,51,28,35,47,46,49,50,143,176,60,77,43,61,72,75,87,44,29,19,95,70,41,126,96,28,23,54,125,112,66,121,116,105,105,91,91,129,97,112,73,84,124,92,27,82,106,43,39,57,98,62,56,20,34,122,155,181,134,174,158,159,152,206,184,161,88,45,32,52,99,140,94,103,106,75,125,140,101,71,95,96,85,14,35,33,42,99,51,51,61,35,128,182,169,79,38,62,129,149,174,149,138,135,150,113,115,135,144,133,130,154,141,139,123,142,148,130,147,150,140,136,140,141,129,126,139,153,123,142,157,154,141,146,125,120,114,117,151,164,128,21,22,0,4,6,4,16,42,25,7,25,22,6,5,14,18,3,5,6,11,8,14,16,23,209,193,180,191,186,195,193,193,204,206,200,191,183,201,214,175,194,189,171,207,199,171,180,188,196,206,203,217,198,188,223,211,189,195,197,188,190,206,186,193,193,181,191,194,214,217,197,180,184,197,202,196,200,182,204,200,190,194,182,197,221,176,218,176,194,186,188,214,180,183,195,184,192,205,178,185,202,192,186,190,186,205,194,182,182,214,160,183,216,186,175,194,190,200,207,189,202,199,194,181,177,155,203,208,187,181,188,176,164,208,201,224,192,190,180,164,192,193,172,197,193,206,192,171,172,203,174,206,185,188,194,205,210,178,189,197,196,190,188,192,208,168,199,188,186,213,203,174,200,201,180,217,197,179,193,168,205,187,193,171,195,194,179,190,196,172,188,183,189,182,178,189,191,184,218,198,178,198,183,221,192,224,230,219,184,193,215,213,204,228,234,221,146,123,158,196,215,181,217,172,170,200,195,185,184,205,176,206,190,169,190,192,177,190,190,222,164,212,181,194,190,172,183,171,189,181,186,196,194,210,206,155,164,189,196,168,217,184,193,205,174,193,192,174,197,182,202,201,188,205,200,165,203,199,220,198,205,183,208,189,211,208,217,197,213,210,194,199,218,240,184,135,150,180,221,217,251,200,162,112,99,49,74,92,99,121,140,147,121,103,96,164,173,151,51,35,130,163,209,224,219,218,185,155,141,114,105,65,120,106,105,177,147,153,140,79,30,79,49,70,187,100,43,93,188,147,59,75,191,238,176,123,117,72,60,27,13,48,61,64,125,145,37,65,75,97,76,77,92,115,115,113,105,109,79,88,98,82,111,91,120,108,133,113,81,37,14,20,73,77,112,137,151,112,112,112,106,64,85,44,69,10,103,200,130,36,2,19,1,43,9,45,32,14,62,54,33,42,61,75,84,64,61,54,50,31,38,37,37,41,11,30,27,17,13,23,30,48,10,18,48,29,59,126,155,98,74,56,87,89,83,93,82,67,66,69,120,94,98,139,100,89,108,113,62,84,93,119,116,136,117,144,136,103,130,132,113,122,149,152,128,108,83,103,104,109,107,117,96,107,145,162,169,159,162,151,122,168,168,177,136,167,123,132,128,135,131,143,107,150,157,145,178,154,131,152,110,139,143,174,149,167,139,174,200,196,191,172,167,125,146,188,168,175,142,177,178,172,174,168,172,188,178,172,199,162,162,125,144,154,140,142,142,152,175,126,152,158,132,138,151,142,135,116,122,141,124,134,121,133,131,132,129,157,83,79,115,141,129,142,154,149,170,231,182,117,110,102,148,148,150,149,103,81,123,106,57,112,89,86,95,55,113,130,97,95,118,129,101,144,90,111,104,93,101,83,100,130,86,54,107,77,17,32,78,87,62,54,22,62,146,173,140,101,114,100,121,130,124,120,158,78,19,28,48,52,106,110,88,80,54,121,128,133,75,87,81,49,11,57,24,68,80,44,76,42,13,46,145,142,101,91,109,157,138,148,167,126,154,129,127,135,138,114,131,118,100,152,139,160,138,120,142,125,132,106,115,148,150,127,134,147,136,149,132,153,166,145,131,142,146,156,144,147,136,106,18,4,10,4,35,9,3,9,10,16,13,43,8,0,30,6,16,25,2,15,19,4,34,23,202,200,187,215,198,198,187,189,202,193,209,190,187,182,199,212,243,221,200,190,208,205,204,195,205,189,185,191,212,206,210,200,190,190,213,202,184,203,193,206,175,204,190,183,194,187,175,202,203,201,204,192,187,193,204,210,193,175,222,210,178,226,176,209,219,193,220,179,217,207,205,209,200,188,193,183,202,182,182,207,184,175,182,201,188,189,190,187,171,195,198,191,203,196,166,193,188,174,188,203,175,183,189,176,181,193,194,169,196,188,192,200,209,204,225,208,171,196,183,178,179,183,176,184,185,207,176,182,170,197,177,210,213,169,175,184,188,196,188,196,203,205,189,180,191,216,213,218,215,199,177,176,205,162,186,201,192,190,197,171,177,196,208,177,209,184,200,191,218,181,200,187,190,185,206,226,192,208,218,187,194,200,197,211,208,216,228,199,207,208,214,198,127,111,162,195,202,190,190,183,184,192,201,205,185,189,187,173,199,192,190,190,187,175,203,200,183,181,183,183,190,204,181,188,198,185,213,198,220,182,191,198,219,184,200,204,184,160,194,192,194,182,190,187,195,210,186,180,180,180,213,202,216,217,198,176,203,193,203,179,189,217,195,201,190,214,197,174,241,229,134,117,129,140,183,199,199,187,111,77,71,65,80,113,124,98,108,103,137,112,156,161,139,149,69,10,8,12,68,142,177,190,170,174,151,150,121,74,159,147,134,195,151,243,160,66,105,101,48,100,217,84,20,148,176,138,51,145,219,189,110,61,76,37,14,42,19,94,76,70,160,91,56,56,58,109,128,80,120,109,97,112,87,101,82,77,73,54,74,103,140,80,148,91,62,18,21,62,102,110,127,126,139,116,109,97,62,49,82,68,99,150,216,203,80,28,49,9,23,19,25,19,24,30,51,69,34,65,96,102,83,76,42,43,29,48,24,23,10,54,33,3,57,8,59,40,21,16,27,9,14,36,52,112,111,112,91,46,87,55,76,61,86,59,63,84,55,53,81,68,65,61,59,64,39,63,84,59,56,49,53,67,55,75,74,79,70,88,31,62,37,75,43,55,63,43,80,78,63,63,36,61,72,60,58,69,56,43,36,57,59,63,51,39,49,21,73,17,55,52,55,63,37,46,55,69,80,57,39,84,49,78,63,82,66,47,67,68,100,76,59,120,96,94,80,119,92,109,78,99,87,116,118,103,118,107,121,97,92,98,119,119,100,152,155,133,133,163,112,117,107,102,104,113,115,137,149,144,156,133,135,108,98,130,113,105,176,162,159,182,181,162,161,154,168,137,142,151,150,175,172,151,171,182,173,176,149,126,147,113,145,166,167,172,118,167,154,132,158,119,128,127,142,121,153,103,142,168,113,128,177,162,143,138,195,180,118,150,138,161,197,163,123,74,85,65,73,111,77,80,106,102,65,44,58,105,122,143,72,57,78,105,129,96,97,80,27,51,80,62,75,82,84,77,64,58,55,23,70,134,124,128,141,134,128,159,141,148,139,147,128,132,141,148,128,116,124,121,147,132,131,111,134,126,95,138,146,157,157,150,148,154,145,166,136,138,136,128,123,147,188,199,159,143,155,112,30,11,17,6,8,7,35,11,6,8,4,7,3,5,14,11,8,5,5,20,19,28,7,7,195,184,198,203,218,182,191,186,189,212,174,181,190,188,213,207,245,231,206,203,197,212,197,205,202,191,206,205,185,216,209,211,203,214,215,210,200,212,221,210,206,195,208,194,183,191,180,187,203,187,201,167,200,183,197,204,208,187,209,171,217,194,169,208,202,208,202,196,161,189,192,188,204,171,197,202,199,196,184,172,194,207,195,202,207,199,198,201,210,200,194,203,182,179,206,196,195,191,218,210,201,159,218,155,211,186,217,203,200,184,199,209,195,201,185,217,198,181,191,198,200,197,191,180,185,185,181,189,203,180,178,178,194,197,181,214,174,194,198,213,203,184,235,224,214,193,171,203,189,172,193,183,181,204,194,180,188,186,166,186,233,212,202,188,208,209,199,196,221,199,193,222,231,214,196,184,226,216,213,215,184,127,116,161,175,190,195,167,129,105,142,144,112,94,143,183,228,211,204,174,209,217,197,208,182,186,180,201,196,195,188,174,198,200,187,181,204,181,200,189,194,193,199,205,192,187,209,206,182,200,181,182,221,191,187,191,180,182,204,219,203,177,202,190,202,203,210,220,209,217,189,167,188,201,167,183,153,140,156,152,165,152,140,127,139,130,136,197,237,162,131,166,99,107,90,142,141,165,137,59,87,55,74,113,131,131,130,142,84,106,182,132,143,157,106,21,20,48,43,4,2,59,100,107,109,117,103,107,223,155,92,93,98,158,74,114,229,155,90,152,186,94,94,159,190,184,152,153,146,90,85,61,50,15,18,23,73,119,87,87,120,56,54,85,64,111,140,112,101,82,85,94,94,65,95,60,59,113,100,119,135,94,41,24,3,46,30,84,126,134,141,143,121,103,109,60,100,78,126,128,123,155,172,131,53,45,44,14,30,14,18,38,27,24,20,75,69,113,97,98,92,44,21,27,23,18,21,26,25,17,23,22,43,29,0,34,38,32,31,40,40,33,25,117,89,190,168,176,160,159,141,127,124,154,149,150,123,128,146,100,135,116,126,88,92,121,109,111,121,132,128,116,137,135,76,155,136,155,96,150,150,123,135,129,144,149,150,170,131,107,139,118,133,90,92,125,90,95,94,107,91,118,106,98,69,127,83,98,106,77,103,76,98,81,72,80,92,104,75,78,77,74,74,51,113,85,65,82,94,55,43,36,57,55,63,52,73,43,57,63,74,54,72,78,86,70,73,60,54,57,42,42,89,47,76,47,60,48,47,52,42,61,47,44,63,68,95,69,81,54,62,33,50,59,65,56,57,43,27,81,64,53,34,53,23,40,58,64,42,69,75,65,78,111,97,115,113,118,78,96,98,102,77,102,118,103,114,117,80,109,104,103,110,113,110,114,125,126,92,105,137,139,138,172,160,131,134,161,162,167,137,132,118,77,88,77,92,89,113,98,102,98,147,137,106,131,127,123,128,99,130,138,115,113,106,116,108,139,127,131,114,153,103,136,169,113,141,107,115,136,154,124,124,148,145,157,176,189,168,157,126,124,129,109,137,116,117,106,113,119,132,140,117,127,125,117,129,126,142,137,150,149,151,146,145,145,135,156,144,159,188,195,175,157,168,125,0,23,7,42,4,32,29,3,13,10,26,13,8,0,3,25,44,23,2,30,19,14,8,4,189,195,206,184,193,208,198,223,179,188,193,196,181,193,185,231,252,221,193,219,203,224,209,229,219,231,233,233,221,236,211,212,227,193,186,212,206,179,189,185,186,195,200,189,220,201,204,209,216,186,194,216,215,221,183,188,176,182,197,176,199,198,209,195,197,209,216,211,204,199,191,223,183,176,194,200,180,179,198,196,192,210,190,194,192,210,185,203,212,208,195,193,203,212,175,193,187,196,219,173,198,195,176,198,155,205,190,195,200,185,179,182,184,162,166,143,199,195,193,204,214,201,205,208,205,221,195,191,192,195,209,214,212,182,231,192,182,228,214,195,202,195,171,145,147,168,159,172,189,187,203,219,190,174,213,183,217,229,217,213,223,192,220,198,226,232,227,223,227,224,225,197,231,222,196,156,163,182,206,211,158,122,84,81,134,124,113,93,81,66,61,90,94,133,123,175,192,208,239,202,250,216,215,215,198,201,186,187,211,197,182,187,192,211,207,191,203,208,181,219,202,212,182,201,198,211,207,190,180,194,204,193,170,185,200,177,199,187,177,198,192,203,217,181,207,180,184,201,198,200,130,102,79,161,152,139,129,109,123,113,104,108,63,85,54,88,88,176,209,89,127,139,93,108,105,125,131,116,165,104,100,50,74,111,146,158,121,157,99,46,116,142,126,130,118,59,12,31,37,25,34,14,32,4,36,52,125,129,218,169,80,55,62,43,25,183,244,101,133,164,125,153,169,201,151,194,202,140,71,57,56,38,8,15,65,96,140,137,66,83,140,39,54,41,102,128,55,77,128,70,100,78,58,61,73,86,75,103,104,135,89,39,43,18,23,55,89,103,98,127,104,107,119,97,54,119,106,119,118,133,113,96,96,79,42,30,63,40,55,14,21,18,28,26,33,47,67,89,58,54,55,31,31,38,33,27,21,36,41,25,4,51,35,23,17,20,26,22,52,37,33,85,35,57,74,85,53,48,60,68,83,87,66,77,78,45,49,82,88,76,64,80,84,72,77,65,79,84,130,91,96,107,102,133,109,93,103,141,117,117,134,137,108,101,122,135,141,99,102,86,114,112,120,134,131,97,121,128,114,121,93,122,135,156,120,109,114,141,148,126,136,131,90,124,130,127,119,121,126,130,129,177,140,137,109,116,140,110,133,122,111,122,108,104,98,109,122,130,122,125,105,138,137,135,115,127,112,143,147,126,111,101,110,91,103,115,100,72,115,108,110,115,106,106,90,126,99,133,117,87,102,114,115,94,92,114,76,75,59,92,66,66,83,91,47,92,83,56,58,66,65,64,70,66,53,53,81,71,71,64,55,74,78,84,68,49,67,73,52,70,47,57,58,52,56,69,70,56,43,52,59,61,69,80,38,49,54,72,58,54,69,63,69,83,78,50,86,36,52,76,83,83,70,84,65,87,76,84,68,92,85,92,74,92,90,84,99,121,128,117,103,119,124,109,142,133,132,140,134,108,99,107,103,97,113,104,118,141,136,129,102,109,98,100,113,107,102,108,124,104,162,123,127,142,123,139,121,128,137,134,130,138,145,142,164,165,170,168,158,139,163,177,173,151,142,106,14,4,27,25,3,22,10,1,14,24,17,20,0,2,16,20,26,8,16,5,6,12,11,3,186,192,181,210,208,174,204,183,212,189,189,204,213,183,175,215,255,223,153,189,183,181,237,219,228,237,225,231,237,229,227,221,231,199,174,180,183,223,191,197,201,195,213,218,193,218,202,220,162,186,191,203,191,199,193,195,210,180,216,199,192,182,201,206,197,189,195,183,178,198,212,208,201,203,212,208,187,169,190,200,190,174,204,208,207,195,211,219,194,201,198,214,182,201,178,198,162,193,201,209,186,191,159,209,211,189,205,188,182,205,183,137,91,104,87,128,183,208,217,218,213,241,239,213,198,182,208,242,206,206,208,205,190,212,200,203,230,220,205,185,220,203,127,152,112,127,98,149,210,214,211,179,193,191,234,190,170,199,149,166,173,184,172,185,208,194,176,155,173,179,166,169,134,171,144,76,97,114,128,104,124,122,104,91,101,86,92,114,98,97,95,111,144,101,98,141,92,180,184,193,183,186,193,180,193,223,191,204,195,207,191,179,193,174,218,199,200,193,198,191,217,227,203,204,216,183,190,218,213,209,178,201,194,187,206,228,199,193,218,179,189,194,180,197,198,143,137,149,126,133,129,96,85,129,146,132,142,120,106,97,116,89,76,60,102,62,76,194,201,90,89,100,113,112,77,163,153,119,168,152,106,55,85,114,122,146,117,91,95,57,106,113,74,105,142,111,112,63,111,48,67,30,35,19,37,75,66,103,161,194,125,102,164,73,50,161,166,60,110,130,136,160,187,187,164,170,202,138,97,57,49,35,63,83,70,97,129,128,45,76,100,25,64,91,100,104,57,60,86,66,25,68,51,33,57,65,79,103,99,122,57,4,27,41,80,109,123,122,114,116,114,96,97,103,102,132,119,94,114,98,116,88,53,52,69,56,31,49,14,20,14,20,0,36,44,24,21,53,38,41,29,33,30,20,38,20,65,31,14,13,12,49,33,46,43,33,32,34,14,52,52,29,19,51,19,50,53,47,34,61,55,45,24,29,41,23,22,40,40,31,41,25,62,48,37,40,51,45,67,44,44,34,60,43,59,27,15,33,63,67,29,35,35,18,16,29,64,41,55,63,45,58,69,44,29,40,41,27,29,58,72,28,66,56,53,46,33,51,81,37,46,33,47,55,33,42,39,43,58,55,40,37,52,42,60,43,77,54,49,57,36,71,59,65,53,73,54,62,103,67,56,81,98,76,83,100,83,88,72,96,106,89,90,80,96,62,102,80,119,108,108,111,108,129,117,117,111,118,117,127,128,135,151,114,78,137,136,114,133,111,119,132,138,139,133,113,117,103,119,86,136,127,111,90,114,115,135,119,129,130,123,127,117,110,125,103,111,112,67,123,122,122,119,131,90,108,104,116,55,77,113,113,98,114,95,128,118,90,75,114,80,113,88,92,94,102,78,112,102,88,90,67,74,53,110,57,69,56,66,75,60,76,74,96,73,100,107,88,72,88,80,84,78,68,121,82,75,74,42,34,75,85,52,53,47,48,58,59,71,64,68,114,121,105,97,88,76,84,85,98,92,119,140,149,155,143,139,135,119,111,148,136,120,135,132,150,177,171,155,158,171,143,173,153,113,117,26,17,13,2,27,9,7,14,13,5,9,7,0,0,11,7,13,21,10,29,0,25,4,5,172,192,197,193,204,161,207,186,218,191,214,196,219,204,197,244,251,223,160,155,139,95,112,131,119,127,144,124,129,131,153,192,182,211,202,206,201,178,183,211,206,184,205,176,210,207,184,178,195,191,176,183,201,203,204,192,171,210,212,182,185,184,204,189,201,206,184,191,188,211,195,191,186,186,193,180,186,184,194,177,195,184,211,182,177,206,196,198,200,178,207,190,204,190,189,192,198,179,212,197,199,197,209,185,198,196,209,186,206,232,203,121,96,100,93,109,149,197,200,201,221,192,160,166,190,195,193,199,153,151,232,218,169,131,135,140,152,218,199,227,212,211,138,111,130,136,133,149,198,226,205,201,190,216,215,120,82,85,61,123,169,146,112,114,122,103,120,80,78,75,103,95,66,92,99,60,53,68,51,73,103,122,108,99,97,100,105,104,141,134,128,120,118,70,77,84,68,84,101,81,100,114,134,159,170,191,191,154,175,183,178,180,183,191,177,142,170,138,125,151,211,183,158,191,198,165,139,154,179,180,204,195,231,192,214,202,197,237,175,187,139,158,146,146,126,121,95,109,99,117,98,82,109,113,124,144,125,137,100,140,127,104,117,95,78,67,111,236,122,80,93,92,108,140,108,212,175,103,190,141,65,52,62,110,49,76,128,121,108,94,89,89,77,89,119,185,156,130,127,115,85,92,102,97,223,148,135,145,123,123,68,149,195,93,80,164,142,69,137,90,91,172,148,84,111,186,198,193,87,84,69,64,86,54,78,67,65,60,67,87,44,61,76,90,103,87,96,54,72,46,46,46,37,45,71,64,51,61,54,40,27,15,50,102,113,116,126,128,103,95,78,102,84,100,95,111,107,84,104,58,72,56,66,62,73,35,1,17,25,33,24,47,17,36,20,36,36,36,28,33,4,24,46,8,49,26,32,45,29,21,27,29,18,49,48,29,47,21,45,2,37,26,25,29,38,44,71,78,71,53,16,23,6,26,35,40,31,30,48,48,65,45,43,28,36,32,20,47,32,34,42,52,35,36,29,69,49,39,28,47,31,25,46,40,72,29,38,48,19,41,36,36,59,52,60,31,41,37,33,29,47,48,37,58,44,48,38,40,37,53,48,53,59,71,36,45,20,35,32,60,26,24,43,26,31,33,47,28,52,72,46,36,44,41,46,26,64,59,42,35,50,50,43,60,36,18,61,44,22,33,48,65,55,20,52,61,48,41,52,28,38,33,52,59,43,20,26,64,38,35,31,42,29,46,71,52,28,48,37,30,34,23,49,47,70,38,39,50,65,33,57,39,46,57,41,79,76,90,82,82,83,74,92,93,86,93,96,106,98,118,99,106,111,107,91,106,110,111,96,104,98,122,141,106,134,122,139,126,140,112,118,155,113,116,106,104,133,114,133,135,143,102,133,94,101,85,94,98,107,104,124,122,124,130,128,138,121,118,123,114,104,103,115,100,123,128,102,120,87,110,95,70,78,68,70,98,47,57,67,82,97,160,163,165,166,101,95,86,107,70,78,105,143,137,158,129,165,128,121,111,117,100,90,108,124,111,124,144,158,116,149,166,164,94,117,97,16,7,6,18,16,37,27,33,10,16,34,6,0,10,1,0,15,10,25,25,18,32,26,29,183,200,182,182,222,198,198,205,202,190,198,211,196,202,209,226,249,204,168,202,140,1,15,6,4,14,43,36,22,11,43,146,202,176,220,223,206,187,208,200,207,215,166,201,193,203,203,195,189,196,180,171,212,197,206,181,175,202,175,218,185,181,193,193,206,198,210,214,208,213,198,197,184,171,210,168,224,196,203,204,205,187,197,185,184,217,193,199,221,197,204,212,188,194,176,182,183,182,208,199,189,190,191,193,185,221,207,238,205,188,217,140,118,187,137,143,147,173,146,154,155,115,108,133,120,99,117,158,84,110,179,212,126,59,68,38,97,192,212,172,191,166,120,122,94,126,127,172,195,202,195,199,222,208,196,95,59,59,88,163,170,148,105,94,105,101,64,85,78,45,92,111,93,98,121,89,101,104,94,84,102,103,118,113,71,109,88,139,123,114,117,79,74,64,75,68,85,84,63,47,82,74,115,139,157,155,127,121,149,162,174,176,145,163,147,119,155,134,128,142,133,124,154,152,127,136,134,141,164,195,191,184,175,177,170,175,182,211,170,147,149,129,140,92,115,119,109,89,124,144,110,91,84,100,98,97,111,100,114,151,185,165,192,154,126,102,158,254,121,66,108,107,119,172,190,231,186,101,147,176,107,50,59,83,44,56,164,233,174,73,94,120,94,93,79,154,204,174,138,145,136,170,173,155,198,151,146,128,68,40,60,159,142,71,103,194,135,100,147,85,99,166,96,57,25,132,160,163,85,68,49,35,52,59,56,69,60,79,55,78,54,44,54,55,80,82,38,37,98,63,60,76,45,78,71,71,32,45,25,18,47,89,111,101,142,133,137,121,98,111,86,79,83,125,84,102,116,84,32,17,26,56,43,63,38,52,11,31,45,51,42,16,20,11,24,25,10,40,15,25,24,37,22,19,52,43,28,13,6,16,17,20,14,33,40,38,38,28,15,42,30,29,32,34,36,67,66,73,47,38,25,33,25,17,58,66,50,48,59,38,42,84,64,44,52,39,48,43,28,42,48,30,35,49,49,45,51,44,39,12,27,27,36,34,28,32,43,30,40,48,41,35,44,33,49,41,13,41,39,54,63,51,63,63,50,52,40,68,39,40,41,42,52,45,31,19,37,48,36,46,36,52,39,42,24,39,53,41,42,33,39,69,21,55,45,38,37,51,57,30,50,45,21,39,17,52,61,57,60,57,51,55,42,56,48,42,40,26,45,44,45,77,42,53,35,44,37,37,48,45,35,37,32,25,31,44,67,52,15,14,37,47,29,59,7,50,31,7,45,36,21,36,50,40,17,43,48,37,34,51,77,43,41,30,18,59,43,54,46,25,38,43,15,43,58,30,48,57,68,58,25,53,46,49,85,45,47,50,44,38,47,49,57,41,51,49,78,45,72,88,47,60,59,56,75,64,48,108,78,68,88,89,86,90,73,73,83,100,117,101,115,110,79,118,68,113,107,122,111,74,111,108,109,101,104,122,104,94,106,133,115,150,158,151,117,113,116,122,107,90,119,139,154,140,156,144,148,155,121,124,119,109,88,106,100,112,115,123,117,113,124,124,127,86,91,99,27,26,9,10,15,19,24,20,15,19,39,11,4,18,16,29,17,24,6,10,5,33,21,28,206,211,202,210,192,188,203,205,204,189,198,181,182,207,204,254,252,232,176,191,126,22,11,5,12,43,9,15,40,43,40,173,220,238,230,219,215,209,215,184,226,201,216,209,215,223,176,213,213,192,210,195,211,185,211,222,190,218,201,209,183,185,191,219,211,213,206,196,240,208,210,229,202,193,193,213,199,181,171,196,215,220,199,199,196,198,205,189,208,202,243,230,197,228,205,235,207,188,155,185,196,196,218,202,207,209,209,203,162,127,127,120,132,152,95,100,109,109,86,76,72,84,87,78,90,52,85,100,61,78,172,178,53,44,34,22,84,119,146,134,156,121,89,89,79,79,102,163,171,156,147,136,137,183,158,115,77,94,169,196,156,107,95,124,120,104,114,99,105,107,124,116,117,132,101,116,119,122,122,125,166,131,125,123,147,147,118,120,101,114,90,84,120,103,110,121,106,86,94,133,162,130,133,156,155,139,151,180,154,144,176,153,124,158,141,149,171,147,154,167,175,186,162,190,186,168,184,148,165,163,117,98,114,78,79,98,134,146,156,153,162,149,115,102,117,143,89,126,143,214,180,177,109,78,64,80,63,74,166,189,198,191,210,175,115,101,237,224,100,111,87,116,188,228,248,254,199,84,109,149,122,67,91,136,113,111,157,208,161,88,111,103,88,79,32,80,210,227,238,221,166,192,228,103,130,129,97,145,115,43,82,155,82,68,170,149,103,158,189,216,181,131,56,18,0,69,80,69,52,29,26,7,19,63,57,19,58,63,34,91,51,71,82,76,107,79,96,57,74,80,57,58,60,51,64,56,40,16,15,42,70,105,133,139,110,140,111,81,106,73,96,65,81,114,98,67,72,31,19,9,26,32,40,51,59,48,33,35,60,41,31,30,31,1,25,18,20,16,21,35,24,34,28,45,10,26,40,50,36,48,46,32,40,12,57,33,28,43,26,17,33,33,34,66,59,73,77,12,39,28,41,39,21,35,29,43,72,39,87,59,61,65,42,73,55,43,46,56,62,64,59,34,45,63,58,69,49,49,8,37,38,1,4,9,31,19,18,13,30,23,35,58,48,31,61,67,37,69,54,48,62,49,53,66,63,77,66,50,70,62,55,41,44,40,43,42,38,50,49,38,45,30,34,19,25,24,56,25,50,15,2,49,22,34,45,18,44,32,56,28,37,41,47,28,39,51,50,59,53,49,68,34,48,62,53,28,47,52,46,54,49,48,42,58,37,44,46,59,26,36,46,30,43,49,37,39,32,69,43,19,60,29,58,31,32,47,45,32,40,36,42,39,47,49,35,44,47,27,29,45,36,15,53,30,51,29,53,38,52,50,32,44,27,50,23,31,30,53,43,42,27,38,59,52,51,20,39,59,45,49,45,24,10,20,30,52,42,35,48,38,49,48,56,50,35,55,66,37,21,62,52,65,58,61,41,57,74,51,49,52,28,31,20,33,33,26,38,47,74,27,73,99,111,104,67,76,119,111,102,97,101,110,124,133,99,107,134,148,117,125,159,174,155,158,142,174,148,132,142,154,136,102,136,122,102,76,91,90,111,136,99,91,109,74,117,96,15,28,41,2,20,24,16,28,15,26,22,30,2,4,22,14,9,32,18,28,15,25,5,24,166,192,186,191,203,189,175,191,182,174,183,187,187,198,208,253,247,206,166,199,114,36,27,25,43,40,40,35,51,38,73,184,223,232,240,232,200,208,198,224,201,220,231,200,224,205,200,205,210,212,217,195,214,195,209,237,212,208,211,177,217,194,240,244,197,207,213,203,222,230,191,216,211,186,198,211,215,205,206,236,214,216,214,240,240,205,172,212,210,200,170,226,207,202,180,223,202,175,207,182,192,177,204,161,136,126,134,141,75,55,70,68,114,104,76,73,97,107,81,71,66,58,106,77,115,123,120,103,91,101,120,96,65,54,95,84,95,118,98,109,128,111,86,118,155,138,143,115,119,116,125,80,103,103,126,99,141,151,178,189,176,124,151,120,144,109,157,135,134,117,98,137,131,134,108,138,124,126,121,124,136,156,147,121,170,153,127,74,79,106,122,125,153,158,154,138,116,139,126,155,180,113,128,149,116,138,138,184,181,183,176,175,142,168,170,162,174,189,186,187,189,186,187,205,157,158,144,163,160,132,99,47,82,89,78,120,178,192,191,194,183,156,152,144,144,119,129,125,150,190,227,237,238,203,159,163,161,161,206,207,169,202,210,203,84,117,195,166,110,147,112,135,200,208,236,200,192,97,107,137,163,112,72,87,160,180,116,135,122,105,104,97,90,34,12,53,104,168,208,177,148,162,181,113,127,100,71,173,152,86,138,154,90,93,128,115,168,178,175,229,185,104,51,21,12,30,23,57,52,33,40,30,45,41,29,31,25,30,71,71,65,65,36,63,66,65,63,53,46,9,52,55,52,46,44,44,21,39,37,59,110,91,91,99,115,92,89,76,84,97,101,103,118,131,94,85,33,15,21,46,50,88,19,64,66,30,25,57,84,49,72,41,6,3,5,17,5,26,21,25,9,44,8,35,25,56,52,55,80,50,54,39,3,15,33,27,18,17,27,21,66,51,59,78,66,73,58,37,23,52,23,20,34,84,58,61,55,57,48,73,67,75,68,29,80,62,61,66,38,48,75,60,45,73,39,43,53,52,20,5,21,21,6,33,16,59,35,35,53,70,47,56,29,61,39,74,39,53,53,69,44,36,68,47,44,61,37,34,62,83,57,38,53,68,47,48,54,34,31,45,43,52,17,23,21,10,9,29,6,36,37,25,25,36,38,34,38,58,41,26,36,62,75,75,61,57,40,68,58,64,47,68,68,44,35,41,59,75,90,60,52,45,30,53,50,57,54,23,18,45,26,27,38,50,25,60,56,43,26,37,18,18,32,5,18,4,37,54,24,27,39,52,42,38,53,56,40,49,42,33,51,22,61,69,38,27,29,32,37,18,36,53,42,45,47,61,20,32,55,59,26,12,52,34,51,27,42,46,29,61,47,62,54,52,70,65,37,52,59,25,37,40,31,31,71,71,55,40,59,62,62,51,71,61,45,71,57,76,40,25,10,32,26,33,38,39,20,51,60,38,77,51,107,75,109,110,131,116,107,88,57,48,59,81,91,74,124,136,121,125,128,122,146,156,147,147,130,134,168,117,152,155,145,137,136,97,77,113,126,104,108,108,105,109,120,97,3,0,5,15,10,12,49,15,21,17,30,20,27,17,18,5,8,41,2,18,11,11,19,14,177,180,188,167,159,205,199,195,178,193,192,196,204,206,169,229,249,153,166,228,139,46,26,38,26,37,38,37,32,34,94,170,181,127,158,164,148,170,172,172,148,135,128,133,160,180,192,198,199,200,210,220,176,206,209,211,189,212,198,213,192,165,200,219,171,183,177,190,204,197,204,195,202,220,213,216,176,196,191,205,209,191,222,212,211,205,167,154,128,108,159,147,165,145,180,225,220,217,242,255,231,196,166,117,58,61,74,114,113,67,83,121,127,132,128,128,128,90,130,105,85,92,96,147,131,127,137,128,124,83,81,91,73,101,127,124,119,146,114,148,164,89,119,154,201,228,164,194,159,163,133,102,108,123,140,149,135,229,196,191,181,139,131,113,118,102,157,117,104,88,114,110,128,104,109,113,127,128,96,91,104,107,149,157,149,132,111,85,97,110,114,123,132,106,137,132,124,134,136,157,141,137,103,112,92,89,138,190,154,160,146,141,135,165,137,127,149,173,190,148,158,128,118,156,118,87,135,102,131,127,92,97,127,150,184,184,181,205,160,142,170,142,139,130,116,133,106,128,124,145,208,220,254,251,250,251,236,255,228,191,188,157,144,115,95,126,175,130,91,133,111,110,162,193,229,170,161,109,116,133,166,117,106,55,163,180,115,106,115,141,162,107,91,44,11,62,12,25,104,115,126,121,186,159,184,147,115,203,116,104,216,197,46,125,97,97,188,107,73,140,148,56,14,2,31,124,104,77,67,41,79,52,47,69,21,42,58,67,102,69,43,45,27,42,50,37,25,50,49,42,43,32,11,54,29,35,63,82,91,95,126,131,78,99,69,97,87,65,53,83,103,121,136,138,80,24,5,30,58,64,116,103,92,51,59,17,25,75,51,62,51,64,58,41,12,13,31,49,46,37,18,35,14,49,34,48,28,44,47,69,79,50,23,21,6,39,16,31,37,31,57,49,75,61,58,31,24,44,20,27,21,40,39,63,67,55,71,56,48,40,45,55,80,65,55,34,78,60,49,78,58,48,62,61,36,52,27,20,3,18,18,23,31,45,14,13,25,18,43,41,62,39,63,51,63,55,40,47,68,70,52,45,65,55,44,51,79,28,37,68,25,57,56,41,38,50,41,52,72,41,37,26,7,16,26,12,5,49,20,39,5,26,24,48,35,42,40,55,49,43,26,80,79,56,66,74,58,65,42,46,44,57,68,35,73,75,58,26,36,52,61,61,31,27,49,21,44,48,34,31,70,28,37,31,28,53,39,58,20,36,15,21,31,21,31,21,19,10,29,40,27,55,50,29,47,59,51,57,79,51,63,56,63,28,48,29,21,46,63,36,59,21,32,50,70,30,60,27,53,38,14,65,69,36,24,41,15,30,50,44,7,51,29,18,64,65,58,45,60,60,52,53,35,64,36,76,43,57,46,83,67,60,56,61,67,72,51,47,40,30,7,31,27,35,46,37,58,81,48,52,47,30,49,67,44,82,98,56,46,91,19,88,75,83,69,77,112,115,109,137,105,98,132,141,162,94,135,109,77,130,117,122,152,129,111,110,100,145,139,132,113,122,143,113,131,104,28,19,21,24,21,2,2,6,18,23,10,14,25,6,10,11,17,26,9,21,16,36,6,40,124,189,200,186,209,200,212,222,208,220,201,201,209,220,197,237,214,125,143,219,103,59,48,24,3,21,43,63,43,44,76,130,97,31,81,77,91,68,140,124,66,63,77,99,102,145,152,171,124,132,120,148,117,143,160,157,140,120,161,135,112,104,135,148,105,124,122,106,109,130,127,129,163,174,146,101,94,119,152,138,125,143,156,143,148,138,114,113,86,65,89,97,79,100,128,210,244,231,239,250,245,232,162,99,85,117,102,145,101,130,139,152,143,164,146,127,137,114,144,103,143,168,104,115,85,128,99,110,128,90,127,126,151,204,168,197,197,167,148,136,144,80,88,136,180,180,140,172,146,147,138,129,140,127,151,147,193,214,164,138,137,129,92,92,104,65,111,120,101,99,59,104,83,112,71,105,90,101,100,90,92,111,99,120,111,125,111,123,119,110,115,110,106,123,89,114,90,78,114,132,132,83,104,87,85,88,150,167,145,112,95,109,107,107,109,70,72,139,140,85,58,86,124,113,113,109,125,161,150,123,158,121,141,156,151,160,135,107,127,95,108,136,107,94,126,111,140,103,98,126,135,147,149,159,148,160,188,181,206,220,211,194,205,172,94,147,224,132,109,100,117,110,182,214,215,174,149,152,146,98,133,132,104,17,124,212,132,121,124,161,200,255,240,209,174,132,104,110,140,155,189,135,161,144,192,167,157,223,80,126,212,102,75,144,128,136,148,76,22,38,77,67,22,18,89,131,137,101,90,119,154,134,107,70,96,94,71,47,69,76,52,24,27,52,56,18,25,28,56,46,54,55,31,16,12,61,60,123,95,113,132,113,91,75,96,94,68,105,79,102,117,118,109,89,21,35,10,41,74,102,123,113,120,92,82,26,31,54,102,85,110,64,46,52,56,19,14,21,32,17,51,47,48,35,23,22,13,31,42,53,56,46,35,24,34,47,24,18,45,23,45,91,76,41,15,22,12,34,17,21,44,70,51,75,62,74,63,49,35,51,32,71,73,72,49,58,51,41,53,53,57,73,51,56,44,48,42,17,42,24,19,12,13,16,42,19,10,4,38,52,59,65,59,23,23,68,45,66,60,51,38,27,41,52,60,35,61,59,44,65,81,42,45,58,47,30,57,57,60,51,29,16,19,4,19,28,6,14,35,19,26,24,18,52,42,48,25,80,43,45,28,73,52,95,39,64,77,65,47,67,79,64,48,53,46,59,64,58,44,29,48,51,40,57,47,35,42,47,46,32,45,36,35,56,44,61,29,63,19,4,34,31,8,32,5,33,28,8,40,34,36,66,49,46,33,43,50,36,21,44,48,58,33,58,29,36,45,44,29,41,56,62,50,41,63,55,37,54,45,44,56,35,57,30,17,29,15,56,13,52,25,42,12,34,47,37,30,76,49,35,51,35,53,45,53,68,53,63,72,79,77,63,55,69,58,73,51,64,19,25,21,19,44,34,77,91,131,106,63,39,72,75,89,64,37,83,54,35,47,43,33,83,127,110,125,103,133,139,134,122,93,115,121,116,104,111,103,87,104,94,83,129,111,78,75,105,121,124,102,111,113,135,143,100,145,105,1,30,20,14,18,14,33,3,24,9,27,24,48,6,4,8,36,6,51,8,13,5,18,22,179,174,210,194,217,208,196,216,198,194,203,205,218,223,222,255,218,158,106,153,37,22,33,43,27,21,51,36,34,51,77,128,113,54,64,93,72,99,142,119,128,89,105,99,129,135,123,133,94,51,51,75,72,85,110,111,67,60,85,92,97,52,85,94,67,60,64,60,83,78,69,57,67,108,90,56,87,76,103,101,60,77,72,75,119,94,79,64,74,60,80,79,103,99,82,136,181,181,169,182,156,156,118,115,102,115,116,118,140,131,143,133,144,131,103,143,132,127,152,120,111,115,135,102,101,140,143,111,141,132,170,147,196,212,236,217,179,170,160,140,140,77,118,136,138,118,136,144,120,139,114,134,105,99,113,166,208,176,131,115,91,108,50,56,91,87,114,135,105,82,64,56,88,83,100,116,102,128,82,67,83,123,96,116,148,143,142,106,117,95,96,99,109,92,130,136,111,85,49,107,134,90,109,113,118,99,120,124,108,100,84,77,108,125,111,110,131,123,105,90,103,100,91,101,90,132,166,161,160,160,159,160,121,101,94,91,82,84,85,72,80,66,86,114,120,121,96,123,84,79,38,54,56,61,46,32,63,115,148,195,234,224,208,219,112,105,187,155,128,122,122,157,239,235,180,152,174,164,186,91,117,185,160,70,146,244,138,81,90,124,185,248,232,255,237,247,206,238,191,162,217,109,101,120,175,119,181,175,98,169,139,79,124,202,246,193,103,63,23,16,40,52,17,55,48,77,85,61,18,86,96,93,85,83,77,95,63,61,69,39,46,35,31,55,42,43,57,7,60,86,49,61,15,26,46,54,114,126,105,133,118,104,92,87,87,123,100,98,105,103,109,90,65,39,20,22,32,84,103,125,106,136,126,113,75,38,44,94,104,117,106,55,36,24,32,44,13,17,18,32,15,0,34,40,11,18,35,44,45,41,73,45,47,57,44,26,45,34,56,75,59,65,69,26,24,7,21,13,31,58,63,67,66,67,75,56,50,58,20,44,64,69,64,54,67,46,55,36,61,40,50,27,35,59,50,50,71,5,36,44,14,24,19,7,14,17,28,56,52,36,36,40,70,53,68,59,63,32,74,52,64,58,37,43,71,58,60,64,50,73,41,49,47,49,67,66,44,24,63,47,45,38,38,38,2,28,14,34,20,24,22,33,46,22,64,73,34,24,37,20,57,68,61,46,43,56,49,49,64,49,75,59,51,59,53,68,53,30,50,57,40,40,60,46,45,50,24,40,27,38,41,59,41,43,28,36,29,25,43,26,3,29,6,21,32,31,29,39,31,44,52,53,62,45,34,64,58,54,65,43,24,45,15,39,25,32,49,37,30,52,35,59,49,44,75,43,31,74,59,61,44,3,27,28,7,41,18,37,26,34,9,12,65,12,27,40,42,57,35,72,49,58,66,36,31,60,45,58,53,37,58,50,60,69,57,60,32,17,14,43,30,13,14,8,85,129,157,91,99,104,128,121,131,133,90,103,102,75,103,93,108,101,138,141,128,137,119,139,123,110,114,126,134,146,119,126,99,119,89,118,92,106,62,75,83,121,89,94,136,108,95,122,127,105,133,120,24,0,34,22,11,37,0,44,22,35,5,9,15,6,1,17,9,18,29,17,29,22,24,23,177,170,185,165,169,142,118,135,116,149,138,143,134,134,173,253,228,134,59,66,5,35,18,22,27,47,25,29,42,48,101,145,118,83,120,172,132,150,190,164,148,148,148,142,138,118,130,134,118,92,86,86,73,94,92,102,95,61,69,84,67,101,87,103,64,104,98,108,95,94,93,75,84,97,109,98,101,90,94,114,94,100,95,75,95,133,122,109,102,107,107,133,122,118,74,86,82,88,61,79,80,75,85,120,101,99,95,114,123,91,96,109,119,98,95,93,126,119,119,101,102,111,128,122,128,123,109,113,123,137,161,148,185,243,236,233,236,208,209,201,178,117,124,118,116,120,115,96,94,87,109,110,93,98,146,178,191,146,115,140,131,103,89,81,110,89,125,147,115,96,77,101,120,122,135,118,91,100,120,83,144,148,143,136,139,159,115,102,139,135,114,126,100,119,121,140,128,127,114,86,80,102,79,115,122,112,130,84,100,89,117,105,133,143,130,118,134,127,84,118,84,90,94,113,111,151,170,164,152,144,145,163,131,92,74,111,88,82,107,103,89,102,112,97,122,87,115,91,84,63,57,47,65,71,57,72,69,94,110,130,157,136,162,166,116,83,93,94,138,148,153,132,152,126,85,78,63,90,72,72,104,170,171,87,83,133,120,122,59,24,89,223,235,236,232,246,232,177,150,117,186,164,106,157,120,118,185,89,72,213,61,101,188,221,246,145,103,33,20,65,37,53,43,45,42,44,64,18,63,48,46,38,46,46,49,31,36,37,42,53,37,27,13,56,27,28,37,50,38,34,44,19,36,37,104,72,97,99,98,102,100,106,89,117,76,84,76,131,105,127,95,73,15,3,38,74,70,110,98,83,98,134,101,119,106,68,110,103,96,75,41,40,47,25,22,26,11,39,31,41,8,41,50,29,28,24,32,42,11,53,51,64,43,45,26,41,39,40,55,65,40,38,13,15,15,13,12,37,67,53,66,47,83,56,68,68,44,71,55,69,52,45,57,51,61,77,65,75,33,61,45,42,36,48,36,52,45,18,2,28,25,16,9,14,13,29,37,40,69,60,27,62,30,48,57,54,45,57,59,19,37,69,64,59,52,47,88,18,28,65,27,32,62,42,49,56,75,30,70,53,47,9,18,10,21,16,32,50,31,36,12,29,26,39,42,52,11,16,13,39,45,58,53,49,37,65,31,55,67,41,60,60,61,63,42,69,48,38,57,77,75,54,49,36,49,74,30,38,36,28,37,38,39,51,64,27,26,27,28,4,1,22,39,15,5,28,22,12,33,31,47,65,34,58,45,38,68,54,46,46,55,38,71,39,40,42,48,29,58,39,59,48,39,48,30,56,74,43,58,64,44,38,24,22,28,12,5,26,12,46,3,29,8,37,49,57,37,52,52,73,56,49,41,48,45,59,59,39,65,75,50,67,71,34,59,60,53,13,44,55,45,29,29,68,103,130,116,88,117,130,118,130,153,123,91,116,149,148,152,143,154,151,151,156,131,109,107,136,115,99,137,122,146,150,158,114,123,121,135,122,137,148,120,124,110,103,98,88,87,58,65,95,91,109,127,89,6,1,17,12,43,9,19,28,7,17,23,33,14,2,12,17,15,27,18,14,9,19,16,14,143,111,115,117,129,117,96,59,46,34,30,39,73,70,122,241,225,124,66,59,2,3,39,53,29,49,43,27,42,68,115,147,153,167,162,143,156,141,194,205,165,113,128,120,137,118,136,110,128,149,104,137,147,139,143,129,114,110,93,87,110,112,113,124,95,110,95,81,119,109,121,120,88,92,117,121,137,118,129,126,126,143,116,109,129,146,130,92,127,116,135,119,114,114,94,111,98,69,101,83,93,78,96,93,105,91,100,119,96,124,103,102,104,103,87,96,91,104,132,122,114,137,104,104,128,118,127,131,119,154,131,170,230,208,221,239,240,251,255,221,205,143,127,125,127,126,106,85,105,117,122,127,150,187,180,205,187,118,107,152,126,132,133,158,165,169,137,202,164,158,168,162,177,143,145,138,150,157,159,143,153,155,156,146,108,162,127,118,147,114,147,142,129,109,110,122,157,119,125,118,113,102,124,110,99,111,95,94,88,117,92,130,138,143,139,114,101,102,119,109,104,127,152,129,127,158,161,152,155,152,165,167,134,53,80,77,93,83,93,103,96,111,121,100,115,98,109,106,111,148,127,112,110,81,73,104,96,87,107,112,74,58,81,140,145,123,35,55,99,57,53,54,87,64,34,54,42,44,9,8,40,69,162,108,73,19,71,141,103,22,9,10,143,202,236,247,184,126,151,115,207,149,144,148,107,139,140,34,118,169,143,161,158,58,117,115,51,25,14,64,49,38,62,24,35,23,50,13,53,30,11,40,31,27,44,23,1,42,34,43,42,17,20,12,7,57,25,25,27,53,32,49,33,23,79,116,113,97,115,101,108,100,99,114,80,109,122,107,130,87,45,25,37,11,63,109,116,106,129,115,85,109,109,98,89,94,102,81,44,34,46,44,21,12,33,11,7,33,38,14,28,19,21,14,34,16,18,20,36,27,51,84,74,90,44,34,31,81,69,58,24,13,26,25,25,36,35,44,65,55,86,42,69,75,46,46,80,47,27,62,60,52,64,82,37,59,70,61,62,39,60,60,47,30,61,45,27,43,45,25,5,14,12,32,43,10,45,37,41,47,29,42,67,64,56,66,56,14,16,29,48,58,64,59,73,53,60,81,59,62,44,51,51,78,42,69,34,46,51,40,26,25,29,29,12,26,37,6,10,38,21,38,37,45,35,9,34,5,5,50,51,56,72,59,65,90,52,77,54,49,70,62,71,61,52,53,53,82,49,32,28,58,38,43,40,16,59,56,72,70,58,47,54,44,72,50,52,42,35,8,28,19,11,20,33,23,21,25,50,17,32,53,49,44,57,58,69,47,41,62,54,32,59,51,55,24,27,67,63,69,54,69,29,64,78,59,44,43,42,39,52,16,22,40,31,9,29,32,22,41,16,28,33,43,33,29,54,46,51,51,76,39,76,57,53,37,81,46,50,53,70,79,30,42,83,58,41,37,31,30,57,25,56,107,131,115,106,83,89,107,121,127,77,113,94,110,117,115,158,120,140,141,121,108,152,94,115,114,118,137,133,145,150,127,157,133,147,151,127,95,139,177,99,121,112,118,115,130,116,94,87,90,60,79,116,105,31,11,11,11,14,10,9,16,33,11,11,19,9,4,43,12,4,9,13,8,0,42,7,4,96,103,95,117,155,183,182,153,130,105,98,101,80,74,133,244,238,148,83,137,60,33,41,38,44,25,45,17,25,43,83,164,163,182,168,175,188,192,170,142,146,111,140,157,125,123,105,108,129,134,130,189,161,168,158,173,158,131,116,124,126,152,115,119,137,119,120,111,97,139,126,114,113,107,82,120,128,115,135,131,125,117,153,126,97,127,131,82,128,123,118,131,92,96,107,94,112,78,84,105,99,111,123,100,109,108,130,117,131,123,121,125,113,122,105,95,114,111,111,117,128,116,127,130,133,106,140,130,132,117,117,120,143,143,149,168,209,196,210,231,218,208,180,156,146,107,113,110,115,96,122,151,175,211,237,245,173,160,172,173,188,188,233,202,186,206,152,174,177,177,200,202,185,136,142,126,188,184,178,138,112,124,107,91,146,125,100,137,129,110,129,162,128,130,127,112,98,115,128,122,108,123,122,155,137,131,106,130,131,119,137,118,139,132,107,103,117,83,93,118,119,163,217,198,123,165,172,171,147,133,153,123,154,100,85,119,123,138,116,108,126,108,131,108,127,126,150,146,172,242,230,122,96,106,109,142,144,101,88,115,105,100,184,205,193,177,42,7,8,9,21,10,99,165,132,139,163,170,97,28,12,36,134,152,172,128,129,200,125,84,54,32,10,62,77,150,155,158,209,195,211,147,162,130,117,192,104,90,172,196,212,186,89,28,26,49,42,41,61,75,50,30,36,17,34,34,25,15,17,26,10,34,11,16,41,37,12,20,42,39,25,45,11,22,12,26,16,34,10,49,59,77,60,49,75,98,100,108,108,104,105,101,93,101,102,90,116,130,100,41,17,20,35,74,94,100,88,101,85,102,62,105,115,114,96,64,85,71,32,31,37,40,7,21,47,47,29,16,29,3,18,22,30,55,24,32,20,36,22,49,30,45,61,58,57,28,53,48,25,16,18,11,40,39,31,52,50,81,74,59,60,61,38,52,37,75,63,45,61,48,60,64,48,68,61,68,85,70,81,59,65,60,43,41,41,28,21,31,27,49,37,10,23,24,16,27,37,41,18,38,50,40,69,54,49,46,41,45,41,31,53,54,53,48,83,61,41,37,55,38,63,49,45,44,47,68,61,58,52,35,34,12,25,15,5,10,16,8,23,33,30,81,45,46,41,15,21,11,17,39,78,56,77,60,34,65,81,85,73,73,51,56,84,65,51,52,92,84,65,66,58,52,55,44,55,25,52,32,57,62,40,42,46,65,32,47,15,2,27,24,11,19,8,24,36,16,42,58,26,61,44,57,26,40,71,44,55,69,71,68,59,70,80,81,64,40,38,64,70,56,43,36,50,48,35,58,52,45,49,39,47,37,27,12,26,17,24,30,15,29,18,25,21,23,65,37,43,14,67,51,33,49,46,66,60,58,54,55,82,81,82,81,90,72,80,56,37,45,53,28,24,32,62,150,107,110,120,134,106,54,73,76,68,103,62,60,126,129,122,116,133,138,115,124,113,113,159,152,128,121,151,149,144,147,121,129,154,108,134,131,155,149,136,116,116,142,110,118,128,120,99,87,106,111,87,86,5,29,14,16,29,9,16,31,20,46,20,13,3,16,36,6,20,23,18,25,6,43,1,29,87,97,89,152,192,213,212,190,204,174,150,132,127,118,203,253,245,158,148,183,97,29,27,9,10,13,41,23,50,37,63,148,135,179,151,181,166,148,140,98,108,137,138,148,107,134,109,130,143,145,127,141,145,156,127,147,167,134,104,113,110,71,89,114,95,97,115,98,113,128,124,116,115,104,80,96,136,128,121,131,116,121,119,133,123,136,120,130,121,129,110,107,131,129,103,93,146,117,106,111,127,143,115,110,137,144,131,149,135,117,131,93,105,90,121,86,136,98,120,122,116,106,103,116,95,118,122,125,156,136,99,84,92,71,107,71,125,148,185,171,213,221,237,248,208,139,119,116,127,125,118,114,150,249,223,167,167,163,171,178,184,197,189,189,190,193,138,149,117,163,202,191,137,98,133,150,188,170,137,124,90,93,70,95,125,126,87,101,109,69,112,108,116,117,94,98,111,99,112,117,128,157,148,137,124,109,97,139,112,123,106,113,138,97,89,67,70,125,155,176,144,182,245,212,152,157,147,153,150,151,155,172,147,125,49,84,111,138,111,120,145,209,167,131,119,131,136,129,178,216,219,123,102,109,141,164,160,133,66,83,92,113,188,232,220,145,122,104,76,71,22,56,145,201,198,185,191,194,186,110,91,32,99,163,167,153,221,212,122,118,109,71,95,76,55,129,172,155,157,171,201,158,170,103,145,179,123,184,208,217,189,105,99,10,14,32,70,76,56,39,30,36,22,50,22,15,18,16,49,28,29,24,22,37,27,26,16,5,27,34,32,18,34,23,23,22,24,48,35,51,76,89,42,53,90,107,107,105,96,70,83,93,102,118,102,87,117,82,43,34,16,47,68,114,123,112,113,123,112,104,69,76,109,94,124,107,96,95,94,129,107,74,28,44,50,50,14,40,30,17,26,12,35,30,38,36,21,36,12,13,33,58,54,77,98,43,45,28,7,19,5,34,40,24,66,50,78,56,63,63,52,40,40,39,51,53,50,32,66,64,67,51,37,72,65,47,47,58,48,58,64,31,49,38,46,25,32,38,29,8,19,11,26,21,24,43,43,52,35,38,39,56,47,25,56,30,21,51,24,41,30,52,63,37,51,73,75,53,60,59,62,50,64,33,63,50,66,52,60,25,28,34,8,19,24,33,3,27,45,25,52,30,47,27,12,33,32,37,51,92,78,84,60,57,48,52,57,59,49,69,70,59,79,67,64,63,46,67,57,43,58,27,42,27,44,43,62,15,60,42,41,61,30,40,43,31,19,13,35,18,37,47,14,18,35,24,0,37,53,17,33,56,38,47,71,56,60,70,58,66,71,90,28,16,47,40,59,22,47,66,44,49,22,51,46,77,65,58,61,36,45,20,16,38,26,10,36,27,5,7,6,3,28,68,35,81,54,34,54,45,53,73,61,62,68,54,60,64,59,61,47,53,60,76,49,37,56,39,34,55,41,44,128,159,161,149,138,136,109,62,44,95,97,100,67,107,116,121,124,156,133,126,128,120,157,121,139,149,160,118,129,95,142,129,105,129,114,94,126,152,186,150,139,155,132,110,123,135,176,133,122,129,119,108,84,70,12,21,49,13,6,5,5,25,16,29,20,11,6,22,7,15,27,26,26,5,17,23,23,11,81,101,80,86,154,133,121,153,139,181,154,136,144,185,226,254,243,136,179,233,150,81,12,12,21,19,48,38,51,33,70,89,78,109,127,95,110,133,67,82,85,97,95,91,101,98,110,81,92,69,82,103,105,76,104,97,137,111,78,99,72,64,96,91,113,135,103,103,121,130,131,128,102,101,97,145,138,128,125,92,96,118,120,110,139,114,129,130,132,117,112,123,143,129,129,149,128,122,115,123,102,132,116,136,120,168,152,138,167,117,101,111,75,134,94,98,92,82,110,115,108,107,124,133,123,85,103,134,130,125,99,92,95,64,66,77,77,75,118,140,147,176,162,215,219,203,182,150,139,108,86,64,162,175,157,126,112,124,156,159,129,142,147,134,141,152,113,103,91,84,113,111,120,97,105,111,117,156,119,116,102,115,120,149,89,107,111,112,98,59,118,104,93,90,71,79,70,96,89,83,119,146,130,132,84,126,123,126,114,98,124,107,102,110,84,91,163,156,178,188,143,195,239,200,154,160,168,171,170,135,145,140,171,147,91,78,88,111,120,139,197,194,162,171,129,113,120,104,97,184,131,120,124,99,161,178,201,143,92,80,95,102,139,142,172,180,227,151,158,163,131,111,85,172,207,154,127,146,179,131,83,7,45,127,159,136,200,179,93,80,78,81,87,86,85,110,146,137,102,115,179,194,135,82,151,146,161,234,199,238,198,61,34,1,59,64,55,60,40,42,39,7,19,29,33,19,53,14,34,15,61,25,29,29,20,29,0,14,17,11,40,15,40,22,20,29,3,25,40,63,65,86,78,81,110,125,89,75,77,69,74,109,91,116,94,109,92,25,17,19,40,88,107,147,91,90,81,103,90,177,93,82,111,102,114,101,115,125,123,150,159,77,29,57,22,24,16,74,19,2,19,17,25,48,18,19,5,19,22,31,29,60,71,81,96,90,50,34,30,4,16,13,54,49,46,76,52,76,50,52,78,45,50,57,64,64,55,80,59,58,91,55,65,41,59,71,74,25,22,60,34,58,29,38,53,13,7,32,19,15,15,21,46,30,15,12,49,32,44,39,67,34,66,48,55,53,48,41,19,33,27,51,49,71,69,57,31,64,40,60,63,64,69,58,55,29,51,74,31,13,14,34,18,17,5,40,25,28,16,23,68,33,30,30,42,57,38,43,58,77,43,64,64,50,24,71,50,58,59,48,61,38,31,47,67,46,40,61,45,58,76,48,46,61,77,42,74,61,64,73,39,51,45,54,59,46,23,21,8,34,13,9,14,24,27,11,13,19,59,36,44,56,48,45,96,34,46,66,43,41,68,37,53,62,49,59,57,57,35,44,78,49,47,71,47,63,35,57,62,26,28,51,18,15,16,18,16,33,25,33,23,50,43,29,75,66,55,67,48,78,67,44,63,57,47,64,59,91,65,63,85,66,69,60,34,44,50,40,35,32,55,103,130,147,109,122,128,136,118,101,129,121,104,142,141,87,114,126,114,108,129,145,137,133,141,130,117,145,157,110,109,88,117,107,110,112,108,153,132,142,128,127,146,152,147,149,143,120,137,108,117,132,102,121,108,95,7,1,42,20,14,10,15,3,18,13,22,9,6,0,23,8,21,18,32,13,7,14,21,20,101,99,86,74,85,99,56,86,92,108,90,96,149,195,244,247,240,115,99,238,133,54,14,34,7,42,36,76,38,28,85,79,83,90,90,74,77,81,73,68,71,69,93,108,85,98,80,108,78,75,91,83,90,76,63,78,113,68,98,81,91,97,87,83,90,109,98,127,95,89,117,122,126,103,109,118,129,133,74,122,121,117,91,112,119,113,102,130,140,116,114,135,142,91,129,119,148,143,123,143,152,126,120,105,114,112,131,149,142,134,116,138,131,135,138,145,146,97,113,104,94,112,110,120,112,105,67,115,151,165,137,145,137,86,111,90,84,91,85,112,108,64,119,189,204,217,240,232,187,133,86,32,120,143,122,64,95,107,131,90,134,123,100,82,104,103,108,95,86,95,85,132,106,93,121,88,103,144,127,119,138,137,142,137,101,80,62,140,108,84,110,91,86,87,53,76,71,66,90,72,84,94,111,136,128,131,143,108,116,125,132,105,107,145,151,143,173,191,191,182,132,175,147,150,141,159,164,164,156,147,132,137,177,172,118,57,85,85,140,114,160,148,149,134,141,109,119,104,118,136,94,122,152,157,185,150,178,194,130,78,89,144,152,127,90,185,242,192,250,185,167,107,124,181,214,191,159,127,146,67,60,4,57,172,175,136,168,104,51,30,49,72,66,43,73,118,171,86,122,161,182,158,77,101,152,129,177,161,90,159,109,20,18,17,64,33,25,35,42,25,28,31,37,23,30,23,54,34,30,9,28,34,58,15,43,20,11,33,32,35,17,22,27,34,23,31,22,46,76,91,90,52,66,80,99,75,85,69,83,67,84,123,96,88,87,67,24,18,11,78,105,128,126,126,108,77,121,89,100,136,87,104,108,95,142,103,100,111,113,127,141,152,89,50,31,48,37,47,42,27,19,34,24,40,44,30,5,22,17,16,53,44,97,72,91,74,68,63,44,35,56,33,53,44,79,66,65,79,61,65,64,65,46,64,41,54,29,46,42,58,56,57,29,45,36,38,29,53,24,65,45,29,20,41,25,6,13,50,35,12,15,17,9,23,41,44,53,35,43,62,31,67,47,56,52,37,18,27,41,19,53,64,54,57,46,60,49,49,43,46,71,61,56,37,63,39,53,58,43,4,43,23,42,32,21,24,20,14,12,55,58,20,53,44,29,26,43,32,39,75,64,74,69,75,52,52,58,40,38,23,53,69,51,52,51,53,90,53,52,61,85,77,55,48,45,60,69,45,47,46,45,33,63,56,39,11,41,17,21,13,20,38,16,19,14,44,36,40,30,52,59,58,66,60,61,51,50,74,76,71,70,38,42,42,66,87,62,44,45,53,50,57,69,60,47,62,80,65,22,9,31,7,24,45,11,31,31,20,30,14,45,47,56,54,57,65,59,69,31,47,73,44,41,76,76,66,57,57,72,64,67,46,52,40,41,40,35,76,62,84,67,96,134,116,107,122,110,116,124,139,145,146,139,147,133,120,132,109,122,112,142,153,110,120,118,105,124,148,123,122,103,151,114,133,106,111,101,95,99,102,88,110,127,128,155,131,127,82,83,91,115,94,82,89,99,93,28,26,17,1,8,5,46,16,0,9,0,29,9,1,11,0,10,20,35,29,1,33,26,3,128,150,140,164,158,148,109,110,120,127,80,106,103,133,191,247,234,65,88,201,82,25,34,17,26,26,70,76,53,50,72,84,64,63,87,67,72,58,83,72,105,90,64,92,99,90,96,105,77,74,108,72,76,121,82,116,58,100,97,110,127,96,103,119,86,79,89,84,96,101,113,145,127,106,100,119,111,124,103,100,97,101,95,111,109,126,109,126,144,112,130,129,117,101,114,104,140,116,140,117,117,83,113,95,127,139,144,143,136,118,143,114,116,117,142,154,173,135,135,128,118,112,92,123,91,106,120,163,190,175,166,116,105,120,137,137,114,117,120,137,108,152,82,151,205,193,231,240,243,214,126,119,129,128,125,60,55,76,84,116,146,146,123,132,96,107,100,104,92,101,113,98,101,122,114,90,109,109,120,96,105,128,99,86,76,82,113,148,134,103,129,111,91,77,88,53,85,79,72,41,70,86,116,142,114,125,135,109,89,117,135,181,119,129,154,160,176,185,186,156,161,154,178,160,134,186,206,184,152,169,179,132,135,130,113,104,79,100,134,102,117,112,117,120,104,123,134,121,134,116,116,91,130,163,162,166,163,167,132,104,131,125,126,136,141,216,209,182,247,213,159,78,122,220,223,147,129,118,97,86,83,0,70,173,163,138,181,105,35,87,80,111,150,117,119,166,172,74,135,183,137,133,75,168,186,154,142,83,8,32,19,37,65,40,43,23,41,55,11,75,35,45,46,45,39,31,26,17,46,32,36,5,17,10,21,53,26,7,25,29,33,35,41,22,16,21,53,59,81,84,80,75,45,67,81,96,90,89,74,78,103,124,108,83,48,23,8,30,66,88,130,120,100,99,102,77,88,84,94,83,21,62,83,63,81,97,95,112,120,98,126,128,110,50,43,60,66,67,47,55,52,14,35,22,25,38,41,12,34,38,53,50,38,79,75,55,38,66,81,55,47,59,75,54,63,60,68,52,49,71,50,30,63,32,49,84,24,46,57,54,38,49,37,56,70,57,63,82,44,59,57,26,33,34,52,10,37,26,34,31,29,23,26,30,13,43,61,62,59,28,33,87,54,64,47,39,48,34,35,32,40,36,52,60,55,55,54,79,48,73,52,81,65,45,44,33,64,27,11,26,7,13,10,43,21,10,44,32,36,45,59,37,61,41,16,37,44,20,63,93,48,73,45,55,71,61,35,66,40,41,53,56,80,75,48,34,47,47,61,43,60,45,62,44,81,53,45,55,48,76,62,43,38,79,59,29,27,18,33,42,11,20,17,12,23,11,15,68,39,53,57,57,41,58,50,62,67,77,40,61,57,70,63,49,61,45,52,68,25,61,51,68,45,67,56,65,56,55,61,27,36,20,7,22,36,11,37,46,29,25,15,58,54,51,55,75,71,52,48,36,64,43,63,79,75,60,64,80,86,58,41,61,47,52,66,70,89,180,148,131,147,96,96,76,110,93,94,73,87,134,126,125,141,147,97,84,83,104,122,101,111,84,88,120,131,132,145,167,139,151,142,149,128,121,145,117,79,66,111,88,67,98,118,146,113,112,97,75,92,108,83,94,114,76,125,98,29,12,43,24,24,15,6,11,19,17,26,19,0,2,11,17,8,18,24,21,9,12,24,4,167,146,165,215,213,181,155,146,128,133,122,107,117,109,177,238,238,99,54,85,8,26,40,9,21,40,27,33,49,61,70,103,103,114,109,89,114,98,84,80,96,104,112,102,107,79,78,64,94,86,93,103,87,110,101,118,90,89,111,139,151,114,120,111,100,88,121,122,94,122,115,97,82,81,103,76,112,109,99,118,101,115,115,118,137,103,126,97,138,112,141,103,102,84,93,97,114,104,103,131,122,90,117,98,129,140,116,127,98,102,98,104,105,120,122,115,120,133,113,100,105,122,94,102,92,104,97,163,128,123,134,111,118,144,179,131,113,126,129,149,94,100,115,150,164,161,149,159,197,246,223,213,180,160,182,139,146,82,47,102,153,167,150,143,133,125,138,115,161,133,151,115,113,131,123,74,88,116,89,91,113,106,114,54,53,84,125,132,103,110,114,93,119,84,96,100,82,72,73,81,44,58,93,104,119,109,110,116,97,109,123,101,105,154,160,184,195,188,168,167,162,163,171,185,174,177,169,178,157,167,167,81,81,126,132,151,114,143,138,102,114,90,118,87,72,99,109,129,113,97,124,87,101,123,165,133,121,126,130,139,158,125,130,120,166,225,216,203,244,209,186,118,169,221,140,81,129,169,157,24,28,19,75,205,136,157,198,92,38,91,136,183,160,164,143,176,149,95,182,154,131,160,188,228,240,148,85,16,0,11,47,76,86,65,62,15,26,21,33,52,32,29,23,16,38,63,27,28,26,36,60,21,7,26,30,38,42,23,23,22,27,48,10,34,20,30,34,35,99,108,97,95,41,70,74,74,64,89,87,93,125,151,83,53,16,23,24,59,138,126,120,98,90,99,78,102,94,68,148,107,12,41,47,71,91,89,58,54,84,112,105,142,119,101,56,55,72,61,65,53,38,60,35,31,34,36,27,60,56,50,45,48,33,66,54,50,45,62,94,70,23,41,66,85,80,67,62,57,58,64,18,43,36,69,50,55,41,75,48,61,64,38,63,55,65,82,70,40,34,40,62,52,58,49,33,9,24,23,22,32,27,12,15,17,30,36,80,43,61,59,42,38,68,47,61,27,45,34,30,55,41,70,75,46,66,45,56,26,57,60,22,26,49,80,65,17,62,44,17,37,11,30,1,15,16,32,12,14,35,47,71,53,33,58,16,23,39,19,37,44,55,37,56,55,62,41,47,30,57,56,39,21,22,53,30,35,48,39,54,31,63,54,43,42,87,58,63,51,44,74,51,46,66,56,52,34,6,20,9,14,28,13,19,7,30,45,61,33,68,46,52,57,58,60,37,54,70,78,66,73,70,59,58,58,63,37,31,30,35,58,67,61,46,70,56,79,49,44,73,1,24,12,16,3,42,30,24,24,28,36,32,50,54,42,62,72,76,54,64,75,38,52,46,58,48,32,52,70,65,63,43,59,74,42,51,109,177,182,188,162,143,131,69,45,84,72,96,108,95,112,141,99,104,101,88,61,42,75,84,116,110,111,89,95,102,118,141,153,154,135,111,146,118,113,137,157,116,104,131,119,110,116,131,97,123,107,96,127,89,106,89,81,80,107,99,73,7,1,17,28,23,17,14,8,16,41,32,10,23,19,3,29,5,8,31,18,14,5,26,3,120,125,115,152,176,163,140,98,124,145,102,130,142,147,201,251,234,83,57,58,23,54,27,17,42,28,33,45,49,47,89,114,114,116,106,103,99,122,123,126,103,97,82,138,130,123,124,114,112,108,136,113,100,98,108,129,89,125,131,102,135,108,99,106,105,93,109,101,103,99,106,84,94,82,114,146,102,113,121,144,140,142,121,123,99,122,79,88,100,74,87,110,101,91,123,104,120,84,91,81,123,92,123,98,101,104,117,116,97,106,86,113,112,75,90,104,105,96,99,88,88,100,92,93,75,94,98,116,109,106,100,108,115,123,148,131,104,91,83,105,92,69,91,95,130,230,183,149,168,222,208,155,106,98,201,245,216,174,148,169,167,128,142,144,139,146,152,136,127,124,116,137,94,118,89,88,83,100,62,81,120,120,78,78,82,91,134,119,81,95,102,72,75,87,129,122,103,122,87,73,73,86,115,99,86,139,125,119,124,120,101,121,162,151,165,170,172,183,169,177,181,171,160,160,171,169,161,159,172,182,166,134,74,121,115,82,113,125,145,99,122,122,113,107,39,70,92,118,112,76,81,93,86,71,105,105,97,104,126,118,125,114,127,125,196,242,214,246,251,240,166,160,234,205,81,51,185,217,175,70,37,5,127,189,157,196,215,123,66,123,146,125,119,150,164,175,131,141,181,159,174,186,200,149,216,137,59,16,9,59,38,77,39,47,37,32,16,36,22,24,33,33,45,19,54,50,61,24,44,37,24,21,20,9,12,6,24,33,25,11,35,26,49,24,17,36,70,67,84,96,110,88,92,81,60,92,101,91,88,84,142,90,51,31,12,54,85,88,112,90,92,108,106,101,76,96,127,119,134,149,32,25,37,71,86,65,115,73,84,109,116,104,52,86,103,103,52,40,56,45,52,30,39,23,31,23,24,40,59,59,37,15,6,38,87,37,64,87,100,49,82,64,45,49,56,62,52,30,43,63,79,50,49,45,72,68,51,39,61,51,49,72,48,64,74,36,62,34,29,46,39,51,63,34,31,21,14,4,6,22,25,16,35,44,20,51,45,43,76,74,69,64,45,56,50,47,41,19,55,27,40,38,70,44,37,29,41,55,65,47,31,75,54,74,39,50,50,30,11,2,0,24,13,13,31,29,24,19,11,53,40,40,56,32,38,44,15,48,63,55,62,72,61,48,48,55,21,52,49,27,12,46,37,24,10,55,24,52,45,75,57,28,62,70,43,41,75,69,63,41,46,59,69,29,39,9,16,9,17,28,41,23,17,19,30,18,80,88,59,65,63,50,68,49,67,81,66,63,53,76,51,76,33,74,44,47,38,47,76,45,47,49,59,40,75,52,62,69,29,32,19,19,13,26,11,34,3,8,20,46,50,63,59,42,69,56,47,47,21,41,54,71,56,41,65,34,51,47,76,62,77,60,64,42,77,111,154,146,136,108,119,68,63,50,92,114,54,97,127,136,97,123,79,97,131,84,59,79,81,108,94,105,115,132,116,150,135,163,138,118,95,101,132,132,150,187,142,121,76,136,91,102,83,123,116,120,120,148,113,87,64,81,38,69,60,73,24,34,16,34,8,0,13,16,7,0,17,18,23,4,27,14,16,14,25,5,33,4,42,32,139,139,121,110,121,133,104,123,140,105,103,129,167,160,220,227,219,74,62,57,2,60,4,5,38,11,29,30,61,54,80,118,110,78,116,109,141,110,110,99,124,102,104,105,118,133,127,123,121,134,152,117,91,111,132,123,130,149,107,126,101,104,103,126,93,94,129,101,104,107,104,91,115,120,114,125,122,109,120,126,110,128,154,118,128,128,87,85,96,79,104,117,102,113,107,125,86,80,76,99,98,97,99,57,63,93,104,135,104,109,129,103,106,87,112,127,108,139,136,117,124,114,129,96,84,105,114,117,105,132,101,102,110,99,116,101,123,95,51,91,77,75,45,36,95,160,158,137,155,142,103,105,11,59,125,211,230,244,211,199,142,127,111,85,91,119,129,98,125,89,87,83,99,109,119,110,104,158,94,104,86,114,96,108,67,66,108,110,77,112,92,92,86,108,127,130,147,109,96,91,70,68,115,109,139,152,148,146,102,146,121,147,173,171,172,124,157,147,166,148,182,124,158,156,174,137,145,155,160,155,158,148,135,107,112,107,139,159,123,95,103,119,65,66,86,80,107,114,86,100,79,68,92,83,50,101,80,64,86,108,80,109,66,152,237,244,233,230,248,226,134,182,206,148,58,47,100,198,171,50,26,4,125,254,192,162,176,139,119,124,172,140,130,154,184,143,101,170,171,168,169,152,111,44,81,77,31,34,10,56,78,52,40,11,11,31,58,42,32,24,63,31,44,47,32,35,46,43,39,30,16,6,20,36,19,15,22,30,40,28,36,29,36,30,56,69,74,86,93,92,82,40,68,69,98,92,87,104,119,96,76,23,47,25,17,63,118,115,93,94,107,102,117,92,90,114,123,89,167,177,70,60,48,61,104,69,94,106,99,116,121,101,70,90,98,131,113,55,50,82,86,45,24,19,18,39,26,45,51,24,17,14,8,41,38,52,74,82,82,69,60,59,71,65,49,65,65,45,61,39,54,60,23,49,41,55,51,50,45,47,62,69,75,66,30,85,53,40,74,61,53,47,64,33,9,11,33,14,14,32,30,22,37,42,54,61,44,57,28,35,71,38,47,30,53,52,47,33,45,44,58,31,58,45,61,77,77,35,51,40,45,38,50,64,58,32,42,39,29,20,34,7,19,4,35,3,23,35,62,43,55,52,73,27,29,9,25,51,65,32,66,60,48,19,9,17,17,10,20,26,34,18,15,12,22,9,20,41,49,62,62,38,36,81,40,69,53,70,79,67,62,39,52,55,29,22,36,2,6,21,31,33,6,28,18,52,60,49,85,42,60,55,67,69,81,72,82,51,60,43,48,50,48,64,56,41,19,44,41,65,61,64,28,56,64,43,36,39,14,29,12,7,8,7,21,41,30,15,11,55,69,76,54,52,82,49,66,51,48,50,71,60,49,78,57,37,68,60,79,55,93,47,52,63,81,154,137,128,103,77,81,49,52,46,129,117,64,48,95,115,111,106,121,109,109,77,91,99,93,78,111,102,118,135,114,115,112,150,142,88,104,116,104,112,137,164,123,124,83,68,76,86,76,108,119,101,97,101,120,82,105,98,41,33,39,44,18,5,27,32,18,16,42,22,9,11,13,10,29,3,3,35,23,10,14,10,24,44,29,21,147,140,112,98,103,113,125,158,106,114,147,148,117,149,207,253,229,77,105,19,16,65,36,36,41,26,57,30,28,38,94,131,78,108,116,104,115,126,110,83,94,98,116,106,114,104,108,110,83,117,105,124,86,91,106,96,113,112,94,103,98,111,105,122,119,104,115,146,131,100,108,123,102,138,125,133,117,144,120,122,122,122,124,108,122,116,99,111,80,82,102,107,92,69,100,99,80,98,61,75,90,132,102,101,110,122,106,130,150,144,158,146,161,167,142,148,141,116,137,135,99,119,97,104,111,133,107,112,130,128,140,129,106,114,87,111,117,122,80,145,104,68,54,41,48,78,84,72,123,130,124,161,110,59,27,103,149,148,203,201,196,174,146,98,91,88,76,76,89,92,110,109,89,88,154,120,136,138,108,108,71,92,95,105,96,105,102,115,113,152,145,105,102,72,79,89,123,109,135,129,95,111,141,180,164,100,128,136,145,142,148,189,160,152,142,151,126,132,150,143,157,134,178,137,158,158,147,152,157,165,170,169,136,124,108,105,102,126,102,123,97,107,65,66,95,112,127,63,43,59,54,57,53,28,41,71,88,83,88,103,52,91,127,164,230,250,222,215,244,218,169,205,230,133,60,26,3,52,92,38,48,45,167,235,124,79,122,140,121,125,210,178,162,168,174,107,126,215,171,187,163,136,77,19,7,34,28,38,55,47,38,19,20,35,37,23,34,37,41,32,53,49,27,25,1,37,66,39,19,32,19,49,16,57,25,18,36,18,21,25,34,29,34,19,39,43,83,90,104,83,65,56,81,95,86,118,106,131,73,59,18,18,36,96,93,126,118,105,112,95,133,81,83,78,100,91,102,107,135,171,89,103,94,83,71,95,101,82,105,99,109,97,86,101,112,126,89,51,69,60,81,57,59,23,29,60,62,46,16,24,39,7,10,22,45,55,72,80,60,52,89,68,78,57,52,56,71,82,76,30,49,35,71,37,41,65,49,38,64,63,57,57,53,57,67,72,45,37,63,54,41,39,66,34,14,17,12,20,13,17,29,4,35,61,50,33,23,41,66,29,69,19,13,17,8,14,35,35,40,27,50,54,65,77,50,70,46,54,90,58,38,52,36,37,47,41,83,34,22,28,27,12,43,29,25,39,68,26,60,35,52,44,41,49,20,12,43,42,37,55,57,34,31,13,12,31,3,20,20,14,7,15,7,16,10,3,50,73,38,87,32,66,40,80,44,65,49,41,63,52,50,51,22,45,29,17,30,23,14,8,15,20,25,51,36,39,45,53,55,53,54,70,40,69,61,44,61,56,64,37,61,52,58,56,28,17,32,63,35,55,57,41,40,72,45,46,42,46,10,43,17,15,15,33,35,27,22,16,31,77,66,70,59,81,53,45,60,26,36,69,46,60,64,61,70,85,61,58,74,71,61,41,26,57,147,119,100,122,107,61,74,87,111,118,153,136,50,35,59,53,51,98,97,36,52,40,72,98,81,75,57,62,82,91,74,96,99,135,107,118,92,93,62,51,81,136,115,46,56,16,73,55,37,72,100,93,85,104,99,71,87,74,48,41,17,24,20,10,16,10,14,40,11,25,40,13,13,8,27,9,19,4,4,31,25,3,36,19,2,30,133,146,103,119,117,114,123,116,105,113,130,122,125,132,207,249,216,58,74,58,19,60,25,51,28,24,56,52,72,42,93,153,78,90,90,97,100,121,121,91,133,117,102,76,106,99,115,70,105,120,113,118,92,98,74,88,103,118,127,98,125,134,138,109,103,143,140,119,104,89,120,104,101,132,144,147,112,146,109,123,120,113,139,120,96,74,112,127,86,102,96,114,118,97,101,128,100,113,99,108,122,100,113,97,122,105,105,103,129,141,119,138,133,143,117,110,136,107,115,113,92,95,53,76,112,109,104,80,79,100,114,141,138,101,96,80,125,109,99,127,98,97,93,74,93,66,55,102,70,112,160,180,163,81,45,86,110,125,147,143,207,245,230,161,111,85,63,61,82,81,120,118,114,98,90,140,114,146,138,126,115,100,112,104,116,107,129,134,96,139,115,112,120,78,83,82,102,169,149,148,95,144,165,145,109,76,92,93,143,187,176,201,189,177,174,193,170,178,163,170,177,163,148,129,167,159,168,199,190,182,186,157,141,158,129,95,110,94,120,112,109,135,83,81,100,109,118,106,71,73,45,77,36,50,35,46,62,69,96,73,90,97,112,205,242,255,219,204,239,228,194,171,240,193,50,22,6,20,25,44,39,61,132,145,95,49,49,110,144,211,204,175,185,168,162,142,218,238,149,139,158,83,81,14,36,56,61,68,54,49,34,14,46,49,12,44,55,35,40,31,44,57,23,32,40,44,30,30,34,54,25,48,45,33,36,22,19,19,14,31,30,25,29,42,47,69,97,119,76,80,94,93,82,79,103,121,85,111,44,5,39,23,68,98,93,121,103,110,82,104,96,107,95,104,100,79,125,73,118,162,69,77,91,126,100,78,90,82,69,111,104,123,116,106,100,97,84,44,39,54,69,67,64,44,25,47,46,32,31,34,45,27,36,57,75,75,86,58,26,49,97,120,68,100,61,60,75,69,59,60,64,55,55,69,59,56,60,66,72,97,64,59,57,59,77,45,54,49,63,86,51,39,41,16,26,10,36,23,34,13,29,26,25,60,39,56,40,21,8,26,30,25,21,22,22,18,18,27,41,20,50,49,54,54,59,80,53,49,47,39,46,72,54,43,40,51,68,16,11,19,15,7,6,13,20,6,29,14,34,30,39,55,36,36,30,13,36,30,32,42,53,35,28,2,8,28,27,25,33,38,9,28,22,30,40,39,42,45,44,75,47,47,42,83,47,52,61,60,38,26,78,21,45,31,14,42,22,33,13,23,29,29,35,36,53,54,66,32,63,69,40,98,80,54,53,35,44,39,42,58,55,20,39,67,31,39,53,66,53,66,48,68,73,85,52,35,36,34,35,24,5,21,11,19,31,22,32,15,59,53,76,55,63,48,47,32,42,25,68,73,73,66,56,72,110,63,54,59,42,46,37,42,35,112,131,108,127,129,98,66,89,133,150,158,141,115,86,76,72,43,35,72,35,29,41,40,100,165,91,56,90,90,75,78,36,76,109,121,103,108,116,63,58,32,84,94,69,77,91,85,82,65,58,59,52,78,80,69,72,61,83,41,46,79,84,64,12,8,3,0,22,27,30,18,15,35,13,5,27,0,6,17,33,33,17,6,6,3,6,31,130,147,131,100,106,117,130,120,120,125,108,110,97,129,203,251,231,68,102,33,22,37,10,33,30,16,39,48,52,74,107,125,104,84,111,99,128,122,135,129,125,122,102,92,111,114,111,104,112,114,105,120,139,130,115,116,116,121,101,105,104,116,108,98,94,95,123,100,103,111,128,110,119,148,126,111,123,101,131,116,106,135,115,103,96,105,117,136,121,97,98,77,102,109,126,128,115,100,129,109,128,110,125,123,117,135,90,99,111,79,80,107,100,77,74,102,118,132,111,90,77,71,92,117,101,92,75,100,107,145,104,87,98,116,102,85,109,109,75,86,94,100,116,129,118,108,87,101,83,104,156,132,112,81,71,133,130,97,130,115,143,168,172,172,157,167,138,86,103,87,127,136,124,109,128,151,130,107,124,124,115,158,151,110,114,138,111,102,122,122,127,91,84,77,89,116,110,143,145,132,82,106,92,91,71,53,52,106,155,189,192,233,212,230,224,244,193,208,198,219,214,207,180,182,194,188,211,207,200,206,205,171,134,160,111,101,103,90,140,120,127,106,86,109,81,110,125,105,115,92,96,70,67,67,49,49,70,83,94,109,111,85,138,223,255,252,255,218,246,208,176,171,187,179,120,28,32,90,156,54,61,117,106,62,59,27,15,111,154,223,190,185,184,175,164,184,224,184,116,112,95,40,9,2,63,105,57,73,38,36,23,12,25,30,48,23,42,47,19,21,34,29,9,12,52,46,14,11,23,38,47,30,28,23,36,15,28,39,20,36,27,21,36,55,48,83,86,80,79,50,109,119,100,111,106,112,71,36,14,5,76,44,85,83,90,93,99,97,70,88,120,115,122,81,80,71,48,30,117,134,80,101,67,84,102,95,78,101,113,127,103,103,74,109,72,90,115,88,51,56,57,112,64,53,58,30,13,29,14,30,29,24,51,58,64,68,94,62,65,103,105,88,61,70,57,62,84,84,87,79,33,53,62,107,81,89,52,74,79,74,70,79,52,71,65,56,81,63,51,31,52,57,35,50,24,29,14,16,27,19,19,24,45,46,43,51,17,34,20,43,48,55,28,21,35,8,9,48,30,17,37,45,53,28,48,45,66,70,64,73,60,69,64,64,79,67,18,31,7,1,27,27,31,29,34,26,28,35,10,32,39,56,48,28,18,27,21,13,4,15,49,33,23,11,28,13,6,11,33,15,10,13,35,24,16,16,21,38,34,27,44,34,39,38,41,52,37,74,79,37,44,52,24,29,8,15,9,17,21,14,13,38,39,38,65,15,52,67,51,51,73,63,61,27,36,51,23,28,42,25,39,55,47,39,67,38,24,19,18,63,23,24,64,39,32,53,44,4,21,24,16,38,34,27,24,21,46,59,53,49,36,55,50,43,59,66,61,51,79,81,69,99,69,93,94,77,67,47,45,25,33,56,24,86,121,95,147,136,90,136,162,147,135,168,111,142,129,98,123,115,131,167,131,125,105,137,185,183,139,145,128,186,144,136,108,124,117,154,170,133,115,82,102,12,68,133,109,103,80,92,67,56,56,56,46,55,86,95,72,80,59,60,58,73,160,103,8,1,36,4,25,7,26,20,31,21,35,17,26,26,15,15,17,36,2,18,19,13,14,16,157,183,153,147,169,165,164,122,152,152,155,143,133,151,209,254,219,78,104,57,9,44,27,43,29,33,16,48,55,43,131,150,118,118,94,125,88,125,126,97,127,104,121,118,114,150,109,79,114,106,148,118,137,143,105,128,110,123,116,113,104,93,124,93,106,117,101,93,123,105,78,103,95,133,134,142,146,136,141,128,116,115,114,138,114,113,131,114,75,98,81,89,72,95,91,109,86,84,101,93,120,121,119,95,141,123,94,120,116,100,107,100,65,86,74,82,93,95,97,105,77,97,115,95,96,85,63,105,119,97,83,89,75,98,105,80,97,74,92,76,43,100,102,103,146,130,89,104,100,77,83,99,95,58,66,87,88,103,124,90,77,110,148,172,192,245,205,163,156,133,106,109,117,104,108,115,95,108,127,119,108,133,132,118,139,132,106,91,74,86,143,89,113,80,66,68,82,96,112,136,92,73,95,77,60,93,44,75,178,176,172,207,230,226,229,234,163,189,219,212,199,186,193,166,208,199,242,218,173,182,204,135,99,117,107,88,118,118,117,116,130,71,47,62,71,111,105,155,111,67,88,79,51,46,43,53,82,81,103,125,129,122,154,249,252,247,212,228,243,200,172,116,172,202,156,136,136,244,200,74,45,89,32,9,52,34,50,96,184,204,185,178,224,202,193,202,163,130,63,31,47,20,38,66,93,85,23,45,43,10,31,50,44,37,43,43,51,59,28,46,37,37,36,20,50,9,29,5,18,63,42,20,20,14,16,52,14,27,8,33,46,15,66,86,61,89,83,94,132,73,103,73,108,120,108,56,19,22,37,51,100,107,103,85,96,97,85,96,99,93,68,113,104,94,76,49,51,48,101,118,103,78,95,115,93,88,102,80,112,92,98,94,96,90,87,108,110,95,89,56,80,84,92,79,50,14,15,37,5,16,51,86,69,55,98,92,118,102,84,109,91,86,83,42,76,63,81,64,43,14,51,59,55,74,67,62,67,82,74,64,62,64,88,62,68,77,62,56,44,60,58,76,57,35,8,28,33,32,31,8,29,19,29,33,28,26,17,32,58,30,17,43,41,28,41,26,26,34,12,21,21,40,44,27,35,45,64,37,61,84,49,14,68,48,41,12,5,0,13,17,33,11,19,24,13,13,31,21,2,42,7,32,45,37,59,39,10,14,47,37,51,47,19,16,21,2,13,3,25,16,49,12,8,16,27,45,34,41,20,30,33,19,0,16,28,66,61,90,59,40,59,48,62,44,14,18,22,26,22,59,20,40,28,75,29,58,52,64,51,54,81,64,75,45,41,38,38,56,55,77,37,31,29,45,34,36,33,27,40,53,52,50,58,40,18,36,37,26,49,12,25,15,39,30,6,43,66,45,55,59,57,60,61,44,46,39,71,68,78,103,62,80,98,68,62,36,37,36,28,42,40,33,52,134,132,115,121,88,101,125,160,132,124,109,73,92,88,113,140,196,207,197,192,172,181,194,197,184,155,144,168,207,158,157,116,131,117,106,132,157,148,120,114,76,111,157,118,103,100,76,92,116,107,73,83,87,112,128,84,100,115,82,121,159,221,112,65,5,2,9,25,13,30,3,16,14,21,11,37,16,23,9,33,15,14,21,26,14,24,13,147,151,170,158,131,154,163,144,133,169,157,178,135,154,222,230,217,70,135,46,7,55,4,29,15,27,51,44,53,80,124,129,132,122,108,113,79,101,83,108,124,138,139,105,112,132,131,98,122,108,110,111,99,98,115,105,115,129,102,117,139,112,118,79,125,105,130,104,107,76,86,119,108,123,154,158,136,130,135,144,153,152,136,144,143,147,124,135,123,132,109,127,113,141,100,88,89,59,61,82,78,97,94,95,144,106,73,124,98,114,129,89,108,82,111,95,106,86,104,91,113,94,87,83,90,81,66,87,78,78,89,32,65,86,113,81,82,86,84,64,83,93,81,101,103,124,143,123,92,99,114,97,108,95,85,84,95,84,106,112,101,137,93,135,143,194,184,180,227,190,127,112,123,125,73,86,64,78,129,108,92,123,145,111,112,120,86,106,93,69,122,86,105,103,88,54,59,73,117,144,89,86,83,80,62,69,37,45,116,196,156,196,240,217,230,211,166,149,204,183,174,181,176,191,205,202,181,183,155,162,163,110,80,87,82,84,116,105,130,111,121,68,65,54,75,70,103,113,91,91,45,67,54,25,19,62,140,152,117,86,124,126,172,219,246,206,155,186,173,179,120,158,144,99,113,77,114,145,139,45,16,46,56,31,89,81,62,130,165,185,179,211,225,219,134,112,143,65,40,6,27,93,82,94,51,34,20,50,13,21,25,36,77,36,35,24,23,37,31,40,21,43,12,29,13,24,31,38,11,41,31,41,36,22,7,37,24,22,31,27,29,56,63,61,64,70,88,80,100,72,97,104,105,98,28,31,14,43,85,67,114,115,116,89,90,106,96,88,109,102,95,97,125,111,106,97,95,77,149,159,85,92,84,103,93,73,100,99,103,67,76,88,83,65,98,96,137,117,125,89,72,87,95,84,48,34,10,46,58,58,43,62,50,65,64,107,98,110,126,124,114,118,54,30,53,68,52,50,59,41,41,53,54,50,51,52,60,64,55,55,63,55,83,44,56,67,44,36,50,55,36,49,28,22,18,9,11,13,9,6,36,33,24,32,38,24,29,55,63,38,11,11,32,20,21,16,26,50,36,48,37,41,22,37,41,55,53,16,55,57,13,26,31,7,35,42,13,34,32,18,42,27,34,24,33,40,28,3,23,15,37,30,21,53,18,36,8,24,47,16,9,25,21,9,20,30,26,18,24,52,12,20,29,22,13,30,42,19,40,12,8,22,29,20,60,80,48,66,48,70,46,39,16,5,4,24,10,27,4,21,32,27,21,43,45,81,51,71,49,56,38,58,46,42,41,34,29,80,47,27,74,12,17,47,34,25,71,45,51,49,38,53,53,68,20,48,39,19,13,55,26,8,9,31,15,50,46,76,73,62,67,81,62,64,30,51,67,65,42,47,71,75,51,40,39,14,16,25,33,33,21,47,120,128,103,62,44,56,81,90,105,102,73,64,63,82,55,101,141,172,186,176,132,193,166,179,159,132,155,130,148,165,145,140,139,132,122,127,150,158,120,129,144,104,158,187,120,94,72,127,143,132,146,150,158,161,134,152,128,121,153,132,172,186,175,108,15,4,11,20,2,26,4,15,28,30,11,31,14,17,19,6,37,33,23,16,18,26,36,6,143,133,151,148,127,121,151,142,163,146,144,173,167,150,211,237,194,81,97,46,4,57,30,51,16,50,55,47,64,58,127,137,122,103,89,110,95,98,117,114,115,110,98,99,99,111,93,104,131,101,102,111,113,106,102,102,107,119,102,106,137,131,113,109,119,115,120,119,99,121,109,122,153,128,159,171,137,165,164,141,139,169,138,171,152,180,181,165,159,190,166,153,159,161,154,162,135,130,104,147,101,115,145,127,142,141,102,147,157,110,116,136,106,106,96,107,108,74,100,99,83,88,53,75,91,69,88,88,74,78,86,61,34,93,99,133,125,91,113,72,93,98,107,109,92,113,112,135,125,140,118,92,91,88,98,95,58,60,111,95,109,155,132,76,87,123,124,146,223,192,117,126,110,111,80,69,66,80,133,115,122,97,120,119,115,119,119,119,101,125,75,87,120,126,101,100,103,100,81,113,71,63,68,75,88,94,62,80,135,186,143,153,236,247,246,218,147,177,202,215,208,207,185,173,174,193,197,184,150,123,155,67,88,90,87,108,157,122,121,106,111,96,66,63,62,94,104,112,80,69,81,116,128,139,137,151,220,165,171,157,136,166,230,236,195,135,117,133,151,130,147,162,96,99,115,69,29,62,92,16,3,59,141,120,102,109,102,172,186,213,232,201,200,178,113,85,116,64,33,10,60,105,69,34,56,17,21,44,25,64,30,34,67,33,40,26,36,16,45,53,44,47,37,50,48,31,40,30,24,28,49,35,40,31,18,43,27,39,23,29,31,53,48,61,80,70,56,116,93,107,109,128,79,22,30,12,38,101,128,107,119,87,105,78,120,98,91,88,92,91,108,112,124,86,104,116,111,81,173,165,78,90,87,115,98,78,102,87,91,97,127,80,94,106,103,138,110,119,121,85,80,70,77,92,87,60,57,50,51,47,73,74,49,88,77,108,86,110,113,113,140,89,54,45,25,42,67,26,30,39,36,43,23,36,41,41,37,50,27,22,43,35,45,56,25,23,26,40,38,41,38,52,30,21,32,24,27,47,29,19,24,33,30,7,13,28,23,18,8,21,38,35,28,29,4,40,45,16,26,35,49,36,44,42,58,60,33,50,33,42,40,33,29,64,29,16,32,23,28,18,16,8,0,24,5,42,4,37,22,30,44,34,34,45,6,29,20,36,41,32,3,18,20,10,26,25,30,8,36,15,33,14,12,20,32,23,25,37,46,29,61,8,35,70,25,67,36,60,54,42,50,70,27,23,20,15,32,28,15,11,22,6,23,46,32,64,53,70,57,55,57,63,49,49,42,21,42,47,30,32,33,44,38,56,43,35,44,18,27,37,47,63,45,62,26,20,37,32,24,50,31,48,5,12,65,48,62,68,59,49,77,64,43,42,36,60,17,65,66,73,53,84,71,63,15,38,35,28,44,18,10,19,95,129,126,90,63,91,54,53,56,47,40,93,53,84,78,102,117,110,138,120,148,138,134,132,106,104,126,125,87,86,106,137,106,92,75,99,126,116,110,110,138,132,176,195,127,104,111,124,129,132,137,153,183,140,136,116,137,160,146,179,173,179,152,98,17,0,10,7,10,21,9,18,21,20,21,9,12,17,31,4,18,4,6,6,40,41,5,2,127,91,140,129,131,125,117,148,165,141,146,147,116,194,241,243,179,58,81,24,13,38,7,35,17,29,45,54,38,40,138,104,143,127,103,94,131,113,101,98,106,95,105,67,96,127,89,115,106,117,137,107,100,105,90,107,117,109,100,125,95,104,122,89,104,96,89,96,100,107,110,114,104,144,110,148,125,141,127,130,141,137,131,128,105,119,111,151,166,167,160,128,124,146,181,168,168,158,165,156,194,168,166,180,132,125,104,129,106,117,110,121,102,108,77,87,88,62,71,109,70,67,60,71,85,121,76,66,59,66,67,63,64,75,99,129,89,104,69,82,102,111,127,122,117,103,94,88,106,120,87,125,83,80,62,73,92,79,67,101,83,121,125,109,109,102,109,125,160,140,115,115,93,101,61,98,104,116,118,108,109,103,142,182,117,98,89,113,114,127,105,120,154,98,98,104,125,90,99,54,78,94,53,91,123,107,81,89,95,164,135,110,110,222,201,89,106,162,223,211,191,172,178,163,151,145,168,155,151,129,136,78,130,101,88,102,103,95,90,93,134,109,104,104,93,124,102,120,116,56,99,163,219,255,248,248,246,251,255,207,186,221,235,222,152,147,128,173,165,122,159,144,136,182,182,143,115,123,137,57,22,70,180,128,156,80,158,226,196,241,234,145,138,156,54,37,21,23,20,68,81,47,35,30,51,51,54,41,26,50,30,40,31,35,52,29,41,48,23,58,34,30,34,38,29,20,51,39,43,56,28,6,63,39,25,18,14,42,49,43,57,64,79,108,105,89,80,147,104,118,100,36,45,36,5,46,132,122,102,123,85,81,78,94,88,109,77,71,55,107,92,108,119,90,106,106,122,95,205,205,92,98,93,124,93,78,99,61,77,88,104,87,112,91,87,99,147,138,78,34,28,77,91,96,94,59,47,80,73,45,81,74,91,84,102,81,84,61,83,51,60,64,51,58,50,64,46,22,47,18,60,63,30,13,59,36,53,45,44,21,74,41,23,54,40,28,41,22,25,20,66,18,30,35,25,30,10,51,25,10,36,22,27,43,37,51,40,35,51,9,40,43,47,42,20,13,46,12,22,30,34,50,52,32,12,43,36,46,30,34,47,48,29,34,63,26,48,39,13,8,16,53,13,22,51,20,9,45,15,31,25,28,34,35,15,51,14,57,25,30,5,37,21,27,20,32,21,24,30,31,30,29,26,24,21,41,51,38,41,1,45,31,50,40,11,46,40,30,44,38,28,23,28,28,31,29,53,42,25,31,18,25,35,21,17,29,27,40,51,60,60,43,47,50,18,36,48,36,55,50,51,24,54,24,35,17,38,36,25,89,64,37,50,51,39,23,12,22,19,12,14,16,7,30,23,47,64,62,67,18,72,69,46,82,56,61,32,79,56,73,35,65,48,55,21,6,36,9,38,29,13,31,56,58,104,111,99,80,70,71,94,60,44,53,88,105,96,104,64,87,86,105,143,169,161,157,120,107,95,86,73,115,118,120,126,88,65,109,105,94,86,80,92,110,132,155,121,125,113,111,121,88,108,127,121,139,110,115,159,141,156,119,160,137,139,92,30,15,26,14,15,18,8,9,0,24,12,8,25,6,11,8,30,32,23,27,8,12,14,13,116,143,131,146,141,141,133,145,162,149,140,131,138,137,252,253,200,75,104,23,45,52,19,13,11,46,9,61,43,78,109,115,124,136,88,105,111,100,102,71,64,99,125,106,107,133,121,116,115,135,108,117,110,114,106,97,117,114,107,104,105,85,61,110,94,101,99,85,92,80,115,109,101,96,113,76,124,100,85,99,118,99,87,54,39,79,97,84,112,101,123,120,104,103,143,139,158,161,145,163,153,152,154,112,112,52,76,91,88,92,97,106,75,96,63,70,50,45,44,46,62,73,67,80,101,109,117,93,67,99,107,94,148,127,126,96,73,69,108,113,124,127,107,125,105,105,138,108,91,112,94,108,94,85,89,82,52,64,68,94,69,104,131,134,117,94,105,111,123,103,75,101,107,79,90,138,130,96,113,107,77,122,132,175,110,96,127,131,131,154,123,141,151,98,79,98,105,103,94,72,89,57,78,89,100,105,112,116,80,87,101,57,59,67,110,54,63,134,181,170,161,164,157,119,135,75,96,100,94,158,125,122,99,77,95,93,103,87,66,62,94,99,82,69,93,92,103,110,113,125,96,181,213,246,249,251,236,227,228,180,144,223,242,213,187,195,171,169,147,128,136,211,182,171,136,96,105,155,120,37,6,30,147,166,148,153,203,243,246,242,130,90,93,71,19,0,19,8,82,55,59,51,53,33,51,22,34,16,23,43,49,30,37,13,52,26,22,49,31,30,40,28,28,49,56,52,24,2,19,35,37,35,12,36,54,58,12,38,57,67,71,92,97,104,65,101,120,134,137,53,62,34,14,41,70,104,123,123,103,99,81,67,121,99,87,93,92,85,66,84,105,90,103,109,108,56,84,86,189,182,78,89,81,103,85,79,75,57,92,120,91,79,82,106,89,126,117,61,14,12,33,62,94,86,112,67,67,88,57,47,68,74,98,74,88,112,77,24,7,12,46,62,12,26,52,50,45,56,38,64,64,44,57,47,36,58,51,54,55,53,61,53,22,32,41,50,47,31,58,49,31,43,14,14,32,6,37,34,47,14,16,13,38,39,22,39,32,51,25,29,40,60,45,45,34,27,31,60,10,17,28,36,19,50,38,25,28,41,41,48,43,13,24,32,59,26,41,35,24,7,42,44,31,11,26,29,33,27,51,22,27,35,39,35,22,45,41,61,38,42,24,15,48,31,36,21,32,19,37,44,23,35,29,34,30,64,51,29,38,65,25,13,36,60,38,35,19,18,23,29,30,39,48,13,48,0,49,4,23,35,36,27,43,14,42,31,34,66,46,38,51,49,57,13,49,12,28,51,51,56,56,20,23,6,34,48,27,7,20,29,34,71,48,18,39,9,20,27,28,20,20,20,38,25,21,53,23,49,73,70,50,77,55,66,62,57,73,72,69,58,36,52,61,65,46,32,30,38,20,32,44,43,41,56,45,81,64,83,37,39,87,39,47,75,63,63,63,43,24,39,42,29,101,123,126,103,62,83,87,108,93,94,92,82,101,80,90,108,90,81,82,100,113,92,78,124,113,114,128,101,91,103,92,100,107,116,91,106,119,87,84,107,141,157,140,110,13,14,8,24,10,13,18,23,28,12,24,16,8,4,26,7,34,17,19,19,12,10,8,17,147,143,139,143,153,134,161,149,132,169,175,143,130,166,214,255,186,92,148,18,22,36,15,39,16,57,13,43,64,44,111,86,103,117,106,87,109,116,109,63,67,129,106,90,107,118,111,118,134,102,96,92,120,88,97,89,98,81,72,106,115,128,113,93,84,73,121,96,91,100,108,102,81,75,110,98,103,95,100,112,109,94,63,65,52,67,76,67,77,79,110,128,79,121,98,109,98,114,141,122,138,116,79,59,54,42,52,63,41,96,88,83,81,67,64,75,40,64,32,29,75,46,67,97,112,90,100,102,74,99,119,70,145,90,52,67,61,74,94,129,134,102,103,149,122,101,152,80,131,126,76,123,81,91,115,108,117,75,98,115,95,117,143,152,114,124,128,130,92,71,45,89,98,95,111,98,87,33,77,104,89,68,104,86,91,96,94,114,136,146,142,112,138,85,89,113,107,124,114,114,122,93,116,95,118,168,128,154,83,66,54,57,28,73,91,78,85,132,151,161,138,167,155,148,147,113,105,103,83,103,144,100,117,107,89,82,84,74,64,84,100,81,55,74,79,114,74,76,73,48,92,141,138,174,154,131,112,64,118,56,92,163,164,198,251,210,167,144,139,142,208,216,220,168,95,73,75,135,115,35,4,64,168,153,146,204,255,162,176,164,92,51,26,33,8,19,63,66,76,58,26,46,49,39,36,51,28,12,39,35,43,69,49,28,22,53,49,34,32,56,64,8,34,38,37,47,45,45,23,54,12,53,40,34,57,57,8,43,65,107,85,106,99,91,102,119,115,117,71,34,38,13,51,88,107,115,107,107,74,69,79,92,82,103,99,101,104,75,87,102,75,136,95,104,114,105,100,124,210,214,87,79,75,83,94,65,82,63,77,84,104,134,107,89,102,47,22,18,22,20,13,61,94,86,68,51,60,74,56,47,82,62,68,87,104,93,64,44,39,28,38,27,39,76,47,50,67,39,78,50,55,42,42,32,34,48,24,67,59,45,40,59,59,53,64,24,33,46,65,46,45,65,10,15,32,36,20,6,34,18,34,18,14,36,56,32,44,25,24,21,67,57,58,41,32,41,41,52,58,36,30,46,21,71,39,55,65,36,57,28,53,54,36,39,22,46,32,28,13,12,0,34,28,36,50,39,15,26,33,6,52,42,34,19,11,62,32,54,60,15,22,30,39,23,39,22,58,37,60,69,64,29,5,38,15,29,40,7,47,27,17,64,45,43,43,38,21,35,12,45,41,22,41,24,35,43,7,16,38,33,19,18,28,28,33,50,35,23,29,42,48,44,45,35,31,24,33,28,10,55,50,34,38,18,46,30,29,39,31,53,24,35,53,16,26,8,25,16,42,25,27,4,29,59,43,42,45,37,73,65,44,41,45,54,38,54,33,29,64,68,73,49,49,57,29,31,11,29,38,27,63,50,49,35,52,28,56,37,54,46,74,62,51,84,42,43,5,54,46,57,16,51,106,124,123,118,94,102,101,113,115,111,101,110,98,91,96,103,90,97,81,94,121,93,81,107,115,138,148,138,74,98,134,86,107,100,123,91,79,92,92,112,141,102,126,81,31,29,12,28,8,15,30,19,31,10,8,14,23,19,15,3,20,19,11,18,12,21,19,8,126,121,130,126,126,149,157,180,134,154,144,131,126,154,220,238,149,108,135,10,42,36,25,62,35,36,47,27,54,63,84,94,93,103,78,40,72,89,83,72,88,76,72,79,116,95,112,135,107,87,101,117,102,115,113,71,119,112,98,117,145,105,115,97,89,81,69,84,87,118,104,109,106,107,117,117,79,136,126,95,84,62,92,105,88,86,81,98,124,89,97,111,124,116,117,92,89,102,120,156,137,76,63,56,45,33,28,58,63,98,77,97,92,84,43,55,29,80,53,69,64,57,68,62,72,95,107,84,102,102,113,98,105,48,35,68,67,82,59,88,100,110,117,111,104,110,109,77,80,110,94,104,101,81,85,112,142,121,112,111,94,121,133,149,128,133,114,115,87,69,71,104,115,112,88,111,104,75,65,87,127,57,70,62,43,63,63,65,79,102,68,115,108,123,128,186,135,160,154,126,149,171,154,157,190,189,169,145,91,117,81,80,88,77,87,98,114,118,134,164,141,130,157,138,135,107,118,107,94,98,84,104,106,90,102,81,98,100,127,102,56,73,71,94,116,81,101,95,90,68,36,100,50,55,20,67,71,26,83,47,97,214,143,209,220,192,237,218,180,232,185,251,182,132,111,108,118,163,131,105,76,114,154,174,163,237,231,123,142,154,50,45,7,36,53,50,73,38,47,55,31,42,50,13,25,48,60,27,30,30,29,29,33,33,41,36,47,49,55,37,34,5,46,47,36,48,34,39,32,29,44,63,49,34,57,81,51,67,102,117,121,103,102,84,121,114,72,38,14,33,40,69,104,119,99,123,60,96,95,120,96,94,116,97,82,146,107,89,62,77,119,112,56,104,106,89,107,97,166,205,135,94,57,88,64,81,99,99,110,101,113,125,126,91,29,51,47,29,36,15,34,60,82,50,78,43,70,54,48,59,75,74,101,81,113,114,66,21,11,15,26,59,44,43,56,53,51,49,74,44,66,60,44,36,44,45,22,62,57,59,59,50,70,49,68,38,58,35,36,46,53,32,20,23,28,19,21,21,35,16,27,30,29,29,34,49,37,23,44,14,53,65,44,23,45,26,58,58,48,27,49,43,45,45,47,35,70,47,36,42,18,33,26,50,76,38,42,39,31,16,20,12,16,34,25,65,9,27,29,32,39,47,38,38,29,54,49,51,79,48,28,33,48,25,32,41,49,65,58,50,81,35,23,12,13,32,42,17,35,33,37,24,47,44,13,47,45,40,44,22,28,52,21,3,20,29,13,14,1,25,9,40,42,44,25,41,16,24,25,53,22,27,47,20,31,19,9,38,30,39,32,3,15,23,63,25,16,37,27,27,21,36,21,47,15,7,30,16,31,14,23,17,18,25,44,39,43,48,58,43,48,65,38,44,31,49,75,62,46,50,55,38,51,45,33,24,33,38,48,19,40,35,60,36,33,20,45,46,59,88,121,85,90,68,42,45,34,93,99,72,92,98,105,113,116,124,121,111,85,111,99,86,95,110,127,81,127,121,106,88,77,90,104,69,48,77,88,114,136,129,128,105,123,130,111,123,115,100,76,96,82,91,104,111,63,64,17,35,7,11,28,17,10,9,13,10,18,12,36,19,4,43,29,21,10,11,8,27,40,5,118,57,111,77,114,95,110,114,120,149,151,145,143,164,251,237,165,62,73,18,51,51,27,40,12,25,30,75,55,71,88,106,87,61,104,61,74,47,55,59,72,74,52,46,64,90,92,130,114,99,75,102,115,53,105,104,92,116,90,116,118,119,82,101,102,109,111,73,83,79,110,100,121,92,94,106,80,85,89,86,71,64,106,115,138,102,103,86,77,70,54,100,120,130,106,105,122,97,129,148,100,85,76,83,48,81,64,94,61,100,89,103,120,77,96,74,111,101,122,85,63,78,75,97,56,44,54,68,67,98,86,64,74,72,62,68,85,67,35,66,86,79,102,85,129,113,77,60,91,125,127,138,84,84,87,122,143,142,121,90,80,114,131,137,147,143,123,102,114,87,77,96,81,75,88,81,51,50,90,59,66,50,76,76,61,109,68,62,49,69,111,147,138,135,156,163,187,180,151,176,166,133,153,157,153,153,148,106,77,63,82,78,89,67,66,82,70,117,118,93,103,112,129,85,106,96,89,91,92,87,89,76,94,104,106,94,82,101,93,119,98,95,86,83,87,65,94,88,101,37,66,91,67,55,33,114,146,54,138,88,141,224,108,165,191,216,228,231,213,185,160,180,158,139,138,159,158,169,150,139,116,121,151,180,178,186,207,90,105,69,12,17,27,57,60,58,47,39,35,57,21,21,35,11,18,32,48,26,27,40,15,22,25,17,40,13,41,39,24,33,46,42,54,35,21,57,33,19,60,63,58,60,39,55,51,73,62,45,74,115,80,71,68,109,88,54,21,19,18,40,88,120,136,107,103,80,110,96,98,79,85,88,109,107,107,85,115,109,110,101,104,99,116,98,86,90,71,89,86,174,162,56,61,78,82,120,116,120,114,89,99,124,75,37,32,37,36,15,20,53,73,71,64,50,66,42,81,53,68,75,84,103,89,83,84,85,51,33,16,24,21,63,28,39,69,51,36,38,48,28,40,68,43,35,42,23,48,36,20,20,66,43,73,64,63,6,55,60,68,50,20,36,26,10,37,5,27,31,26,23,37,54,16,33,46,53,32,60,31,48,60,51,42,36,29,41,58,40,57,54,47,72,27,54,29,52,45,35,46,7,28,46,38,39,41,23,35,11,45,6,19,2,20,32,34,15,30,50,37,26,34,50,5,49,59,65,48,35,47,31,49,33,31,47,29,39,58,30,21,49,100,87,50,46,28,52,42,32,50,42,28,36,41,45,43,29,39,44,36,34,22,41,27,28,0,44,26,6,33,27,12,28,23,21,28,24,16,35,19,47,46,13,14,13,36,15,38,14,30,43,24,29,53,41,17,43,0,35,22,30,42,27,33,37,36,44,14,14,35,23,27,25,21,29,31,36,50,21,34,49,55,58,33,46,45,36,39,45,33,70,42,46,47,54,48,33,43,69,25,31,37,26,21,58,38,36,39,49,75,144,129,128,97,64,22,90,104,120,88,97,104,103,125,127,121,114,106,114,97,105,70,73,85,121,125,87,116,96,105,47,53,66,96,81,75,102,92,53,106,114,131,122,92,101,117,105,115,105,100,106,92,102,79,100,77,87,29,5,8,23,34,22,24,16,30,15,17,14,17,32,42,21,41,29,22,8,23,1,6,3,82,99,88,77,84,95,70,85,54,135,110,135,150,208,242,240,162,59,55,30,32,49,44,37,20,44,67,55,73,74,120,95,114,105,102,112,86,65,84,93,75,70,45,58,75,83,90,109,94,93,99,124,107,110,75,113,112,102,97,101,135,80,123,110,108,134,106,120,111,145,116,117,119,98,81,107,81,88,60,69,65,84,112,123,120,101,80,79,42,54,62,51,78,75,91,101,122,111,106,84,102,82,74,107,85,67,104,76,98,123,104,105,104,84,72,75,100,104,107,75,101,107,83,105,76,74,51,62,63,93,98,56,82,87,95,77,59,67,36,69,60,40,73,88,130,125,85,50,105,132,119,98,129,96,82,110,151,142,113,79,94,117,167,156,141,142,125,100,121,111,105,52,71,75,107,70,76,58,66,57,66,53,67,56,70,108,84,46,84,64,100,133,170,150,139,157,140,129,179,180,130,88,73,35,44,99,53,59,46,76,54,106,45,98,126,58,86,102,127,130,100,117,107,84,86,92,66,96,78,97,81,90,80,66,89,104,87,67,88,90,80,85,64,55,71,102,79,41,89,81,81,127,88,60,65,155,204,86,120,163,196,169,109,185,205,163,185,187,164,120,71,88,98,114,153,140,152,175,181,167,177,179,191,235,130,101,110,64,22,41,8,55,42,56,65,43,37,39,19,38,59,42,48,27,30,27,61,32,43,45,55,48,12,32,22,36,52,48,46,32,29,24,68,18,25,29,41,57,83,92,43,33,70,74,101,111,77,52,36,75,83,70,73,50,38,15,15,39,66,96,113,119,104,91,133,105,93,51,64,89,86,89,84,89,119,63,109,107,110,89,110,123,110,84,112,97,115,66,99,155,207,108,51,70,83,64,106,92,100,127,104,55,30,29,7,23,12,26,69,82,124,113,95,84,81,63,94,83,58,83,74,104,96,78,88,55,41,32,3,11,46,31,48,18,37,31,35,18,21,26,34,37,51,47,45,51,64,59,42,85,55,52,56,49,38,42,19,44,48,47,48,31,34,43,39,53,27,17,39,34,48,44,36,42,6,55,44,32,38,45,36,50,77,58,18,35,52,38,29,42,58,21,45,45,45,50,39,34,43,13,17,26,19,43,61,7,17,24,41,5,34,43,46,28,45,37,33,37,33,24,38,35,26,33,27,60,51,56,44,56,7,11,51,35,47,39,29,38,43,40,64,66,54,41,44,60,40,22,32,29,48,24,26,25,77,13,16,31,17,31,34,29,18,9,14,6,18,20,15,37,21,17,7,44,6,22,42,31,46,31,39,41,24,20,21,14,43,59,62,45,10,24,31,28,43,35,30,23,27,51,50,51,45,63,31,17,7,26,22,5,18,19,33,12,36,19,32,34,58,59,48,20,67,36,47,47,29,25,42,26,44,36,16,56,52,21,51,53,48,44,46,15,26,45,25,61,64,82,151,155,117,113,142,120,125,105,82,93,108,129,154,131,135,123,118,96,87,110,91,86,82,96,132,113,81,73,78,86,98,88,71,98,105,85,61,91,60,47,94,104,106,121,60,89,103,137,129,101,82,88,73,136,169,165,119,62,9,15,16,19,26,7,43,2,33,14,31,18,22,22,19,12,27,51,28,9,21,18,9,24,86,75,76,50,73,88,74,57,75,113,112,136,120,182,245,239,157,65,76,41,41,27,37,13,6,24,33,52,85,88,105,105,113,110,98,96,105,83,109,95,73,66,65,66,45,76,93,93,90,98,89,91,107,105,80,118,108,77,115,95,90,99,113,113,123,130,130,135,129,82,87,105,63,90,74,66,91,62,80,103,112,85,107,92,97,79,84,48,72,64,71,76,66,87,73,86,102,105,117,78,68,81,91,82,89,100,88,138,99,102,55,50,86,84,82,113,102,85,76,87,62,73,79,109,84,82,69,74,67,90,82,84,101,106,103,90,83,66,61,50,72,101,90,113,68,96,90,85,117,126,137,105,81,91,115,106,122,137,134,123,120,121,152,149,172,115,116,88,91,118,117,85,84,93,90,59,80,62,65,51,77,76,37,54,73,66,65,55,94,113,77,80,106,67,95,65,87,108,147,131,93,36,40,15,44,46,4,15,46,77,84,161,162,53,66,122,124,136,158,135,121,103,57,94,84,100,126,109,81,83,102,81,74,79,50,78,87,86,76,79,98,50,81,70,58,91,51,65,65,92,119,116,57,56,74,148,179,102,144,222,207,135,132,209,196,218,133,81,156,75,17,29,29,101,140,114,138,154,141,168,167,155,178,187,82,64,29,24,26,24,52,76,30,36,52,32,46,41,41,36,38,49,38,28,39,37,41,34,43,50,38,28,24,32,50,13,34,37,34,39,31,32,49,28,39,40,40,91,112,78,70,53,9,55,124,132,124,105,87,80,110,53,22,60,33,42,56,94,99,100,91,99,107,127,134,109,115,87,104,99,88,114,93,82,105,98,110,102,84,107,108,113,103,111,70,100,89,78,79,120,215,144,72,90,87,90,108,116,126,77,59,42,27,12,10,24,43,76,103,119,86,105,123,129,127,71,78,92,134,96,94,77,80,82,115,57,45,10,1,29,34,52,16,47,27,76,34,36,48,36,30,46,39,50,51,79,40,68,55,47,50,62,46,42,48,52,53,48,39,29,54,31,41,29,9,25,25,8,18,33,58,48,36,59,41,59,54,90,54,47,50,52,53,40,56,45,49,60,29,34,45,29,40,42,39,22,41,44,33,20,19,42,30,32,25,15,11,23,44,44,19,33,45,23,5,24,48,47,45,62,40,60,13,38,58,50,51,49,35,46,45,18,30,37,32,28,25,18,47,42,26,60,69,46,20,10,21,53,33,54,27,40,51,36,58,46,10,15,5,25,18,32,4,7,31,17,28,11,33,38,35,30,43,39,45,47,39,26,5,35,36,25,51,17,13,48,44,61,31,14,32,44,40,29,47,40,34,26,28,52,59,30,20,51,64,40,19,20,1,10,20,21,29,38,29,43,30,18,31,75,38,41,63,57,53,44,40,42,44,27,52,30,32,36,16,62,24,57,44,38,34,34,51,19,12,37,76,134,122,123,127,123,147,115,129,122,107,106,114,139,155,119,107,81,141,112,87,95,125,63,91,90,117,108,103,89,99,113,116,126,136,100,56,49,70,79,46,44,52,74,63,71,44,66,107,120,122,87,76,96,74,154,165,166,161,110,25,1,9,18,24,24,12,14,2,11,13,34,45,16,19,21,20,13,26,42,11,6,16,9,86,84,35,40,70,55,88,80,81,94,101,93,73,179,239,247,119,56,100,37,36,24,19,39,35,38,32,41,65,83,92,101,78,61,66,81,105,83,85,92,90,89,84,63,48,59,48,47,73,81,89,88,94,90,70,113,97,113,84,107,100,104,80,99,70,100,69,91,93,103,83,109,75,92,107,78,79,82,74,94,111,91,108,85,51,88,56,111,73,64,115,100,97,103,106,117,80,89,60,68,70,77,98,100,99,97,113,132,119,129,102,88,98,79,87,109,97,103,91,87,100,66,74,91,98,111,75,41,58,94,91,72,72,97,76,115,66,86,81,79,81,107,123,62,67,102,102,134,138,125,173,137,106,93,107,94,82,104,142,135,145,166,159,116,159,157,144,106,76,79,127,94,79,97,63,62,56,76,59,80,73,63,89,59,45,70,81,82,98,93,69,81,53,31,49,55,60,88,113,95,77,81,44,20,35,28,45,31,71,97,90,187,119,66,93,91,152,121,102,125,83,80,109,102,127,93,120,99,93,83,90,63,78,72,66,71,113,55,46,60,99,84,53,39,42,47,54,25,35,70,105,96,52,88,62,88,122,142,214,238,158,94,167,246,226,169,16,78,130,61,24,23,23,83,110,29,75,59,93,91,81,103,111,34,39,35,23,27,38,72,63,66,51,56,34,56,67,43,60,54,80,43,28,17,57,57,37,20,32,44,36,27,15,26,40,48,43,31,26,35,20,31,34,21,49,36,34,69,114,78,69,36,42,31,86,128,140,121,146,140,72,29,21,34,55,50,97,103,102,134,98,86,108,98,108,110,99,97,87,109,86,60,97,101,98,88,77,86,89,94,108,87,94,121,99,88,81,83,67,89,187,179,92,86,92,107,150,123,75,15,37,2,17,12,53,44,91,108,106,91,115,120,124,146,84,74,99,74,81,75,101,104,88,79,83,27,22,9,16,17,40,55,46,43,57,65,56,38,30,47,31,44,53,40,35,30,45,43,54,36,38,51,30,44,41,36,48,9,68,49,45,40,30,30,33,25,36,13,37,54,47,43,62,19,29,27,55,11,34,37,48,22,25,23,28,40,37,60,52,67,30,36,65,32,40,39,20,12,20,21,41,53,53,40,28,9,25,21,13,42,22,31,22,38,24,26,34,47,50,45,48,31,36,51,40,14,57,39,28,22,26,65,49,36,42,41,53,44,22,21,30,26,81,105,37,17,30,28,38,23,47,31,47,31,52,30,20,20,28,23,25,27,10,23,15,31,30,9,7,8,36,17,33,43,25,29,40,28,22,12,60,43,26,34,38,26,42,44,40,38,35,26,9,27,35,23,23,23,24,59,50,46,8,17,21,18,36,13,39,34,24,24,34,65,25,20,34,26,40,74,43,70,69,73,30,46,42,24,49,58,33,53,51,28,17,63,21,12,27,59,15,10,21,12,31,20,33,83,88,98,106,110,88,81,89,99,109,120,95,105,110,95,101,88,82,105,70,68,114,100,65,119,108,104,94,72,115,102,108,118,113,62,71,45,73,73,55,44,27,64,55,75,86,85,103,123,128,118,122,106,98,134,187,161,139,71,19,4,15,2,45,30,23,7,30,27,0,14,13,1,23,0,54,16,7,12,10,28,2,27,78,59,84,70,94,93,96,94,102,116,77,112,98,189,241,251,117,67,71,13,34,33,50,28,48,44,26,75,51,81,100,107,101,60,55,82,91,90,55,71,64,81,113,73,95,67,57,52,69,65,68,90,65,87,107,106,116,98,93,114,121,92,103,79,57,69,67,70,118,96,131,155,85,69,94,74,102,106,86,90,117,104,75,77,93,118,105,85,108,104,102,101,85,99,100,99,95,75,77,74,86,81,41,86,107,112,135,150,131,135,132,140,143,93,90,102,75,82,71,84,117,81,52,70,95,111,59,71,53,72,81,115,90,97,128,103,67,59,68,101,109,102,102,75,99,102,122,112,90,101,111,124,91,74,91,63,54,65,93,136,139,129,136,117,156,166,144,107,77,76,102,125,78,89,75,63,44,75,76,70,76,65,51,47,104,113,70,56,85,75,51,45,100,75,68,34,50,94,112,109,138,92,114,63,82,91,68,113,113,112,73,135,118,71,58,112,124,102,107,78,72,85,92,97,103,96,87,77,66,80,95,57,63,69,44,91,53,92,73,60,94,72,53,49,68,72,66,44,41,19,64,54,45,62,71,90,158,229,245,130,80,102,171,226,190,76,20,25,136,91,96,101,125,121,54,14,6,23,4,34,22,17,12,29,34,29,35,47,74,39,69,45,27,15,31,47,49,81,46,17,83,32,41,30,54,33,26,55,32,6,40,58,11,41,45,51,36,57,42,17,17,40,60,40,58,46,49,69,96,90,70,41,36,44,51,102,172,149,96,62,15,23,50,57,78,96,110,94,93,82,89,78,103,125,103,101,80,93,70,118,98,105,108,92,95,112,90,105,95,92,104,75,105,139,94,91,113,119,95,107,133,207,128,86,114,97,91,54,22,19,23,21,43,36,83,97,88,99,93,86,126,91,112,98,115,92,84,79,76,79,90,66,52,69,50,31,21,8,28,40,29,36,43,61,68,38,30,57,56,63,45,48,42,23,82,29,47,51,26,59,59,20,63,48,22,38,26,50,55,60,52,37,18,39,24,31,13,10,19,40,40,55,45,56,22,36,20,60,18,25,38,33,29,45,13,51,54,57,22,34,37,39,2,62,32,15,10,30,28,16,36,28,20,56,16,9,25,25,13,8,23,6,0,19,25,38,20,35,7,14,28,50,41,52,12,55,58,32,53,28,22,27,32,28,13,29,19,26,47,14,27,11,68,78,69,62,41,40,6,32,26,40,55,42,35,35,23,24,26,46,14,6,15,8,21,26,39,22,33,60,35,48,20,34,38,14,46,11,23,29,31,24,13,12,60,54,54,38,40,26,17,23,15,3,25,6,37,67,45,51,36,37,50,29,0,32,29,20,30,29,21,30,15,37,65,34,54,14,38,33,18,35,57,68,69,50,27,43,57,41,29,44,38,24,16,22,31,44,24,40,16,20,27,10,50,30,70,76,72,93,58,92,74,67,80,82,79,104,90,111,131,68,90,64,95,83,83,91,120,126,98,100,116,77,113,85,58,74,57,104,71,85,74,26,71,35,38,30,9,96,82,98,74,128,98,121,134,106,124,119,108,113,151,157,129,64,29,0,3,21,21,10,19,10,7,28,6,4,6,6,18,1,1,3,11,2,31,15,11,22,71,54,85,71,97,98,87,127,117,125,121,115,107,187,230,243,123,45,67,5,40,14,45,34,23,35,28,81,70,106,82,102,94,44,71,61,90,88,79,42,59,62,61,69,69,71,65,81,62,76,93,92,112,97,93,110,115,125,112,129,94,75,81,72,79,79,78,98,86,121,158,133,110,98,122,100,118,141,108,125,129,67,74,59,124,120,110,100,110,94,137,120,98,76,81,88,89,66,108,105,72,114,71,80,89,121,147,142,124,128,155,138,146,150,132,123,152,117,135,112,87,149,94,78,110,99,96,107,102,85,124,95,90,114,93,163,74,67,87,84,104,75,81,78,65,103,84,100,113,86,113,102,81,88,96,78,100,82,94,93,121,153,133,107,120,123,109,88,79,81,129,140,136,93,66,74,60,52,43,61,88,77,61,80,116,113,122,79,92,109,80,117,129,127,99,83,65,107,127,113,126,135,145,131,93,134,127,130,134,123,85,102,89,105,133,117,132,138,105,89,49,87,74,53,60,54,88,71,84,85,98,79,90,71,78,127,95,92,82,70,53,67,82,123,99,90,54,82,58,54,62,27,77,49,58,131,249,229,144,34,31,43,89,143,124,45,1,38,78,115,120,107,100,117,85,45,78,89,48,55,27,65,94,48,58,63,78,77,48,39,67,44,36,51,42,36,36,43,41,47,58,65,47,47,54,45,49,34,44,27,46,24,43,36,43,45,42,51,43,20,72,55,55,69,39,52,70,84,93,88,78,63,65,31,38,38,97,74,49,29,48,88,74,105,97,83,122,97,101,110,94,88,109,114,97,105,121,76,73,70,98,101,93,74,111,108,106,88,102,86,106,104,124,148,97,90,105,137,142,48,58,176,159,113,62,16,8,19,24,21,18,36,70,81,106,90,125,106,129,85,105,119,107,103,108,49,67,74,78,60,79,111,107,77,68,15,3,12,10,30,43,41,43,37,27,55,28,19,37,21,60,53,2,48,38,95,49,57,35,22,34,18,16,15,48,47,35,35,47,30,15,44,58,66,2,18,14,37,16,46,21,29,27,25,34,32,38,41,51,32,29,41,45,32,53,62,36,68,31,49,29,39,27,13,53,19,28,24,36,37,35,27,42,41,23,1,31,20,15,14,39,16,27,17,27,52,26,33,32,21,32,13,41,60,12,18,14,37,12,38,28,47,18,34,28,32,44,43,25,49,45,49,25,86,80,66,26,31,43,14,6,22,23,48,26,45,19,48,32,36,21,26,30,25,36,33,22,10,26,19,19,17,42,46,13,15,21,36,44,38,51,41,36,49,56,66,48,52,24,30,5,18,46,27,18,13,14,54,33,46,37,63,43,24,24,28,5,9,11,15,23,13,21,46,43,41,33,42,53,43,25,34,44,28,42,59,15,55,50,45,43,63,45,29,52,40,37,57,36,38,31,5,29,21,51,63,52,52,64,58,58,41,56,89,83,49,81,112,129,101,93,58,62,96,92,89,91,125,118,144,110,98,111,99,99,68,39,45,59,89,62,43,38,53,48,46,33,38,101,122,99,108,92,117,110,102,72,106,113,95,82,90,87,85,75,61,23,10,14,18,12,10,17,24,15,15,37,17,21,7,7,16,2,22,8,20,18,26,5,10,59,35,78,84,83,98,96,108,136,126,133,137,159,209,216,225,122,42,81,33,46,36,31,22,35,41,52,68,66,85,89,77,77,59,66,72,82,85,85,82,25,39,53,50,79,56,75,82,77,78,64,94,162,104,87,83,128,100,112,102,94,90,96,82,118,148,118,149,115,135,144,96,96,115,110,107,110,159,123,91,120,94,72,40,108,107,79,98,101,110,144,197,67,54,86,130,118,89,109,114,113,119,77,107,140,153,135,107,125,135,92,109,136,147,137,132,145,124,147,96,152,179,139,114,116,91,87,121,105,121,102,104,106,97,150,181,71,53,92,89,126,93,101,96,63,84,88,133,175,160,114,129,99,165,153,137,138,152,137,150,165,153,157,148,145,146,139,97,94,74,125,162,114,130,98,72,47,56,52,68,54,66,65,118,113,114,81,87,64,107,119,129,136,119,142,139,105,88,116,128,147,107,147,124,114,157,127,121,151,110,77,100,140,102,151,118,91,120,100,113,101,84,114,90,97,96,84,80,64,112,109,79,56,71,92,92,81,66,62,58,75,49,41,110,149,84,53,83,55,102,128,97,77,82,5,100,192,206,170,35,0,70,44,70,43,20,15,45,88,88,105,93,98,85,119,153,96,103,97,88,69,161,142,105,97,81,83,35,27,34,44,43,31,45,45,48,60,48,66,34,31,38,32,41,44,26,27,27,62,34,39,53,43,36,42,26,26,42,12,37,25,43,60,47,36,62,70,86,105,83,58,26,39,35,68,51,52,50,33,53,53,84,64,104,124,80,119,75,102,77,96,83,117,77,96,91,100,87,101,57,87,101,88,109,97,116,107,95,122,105,112,134,117,122,55,39,92,122,65,27,28,111,184,104,30,10,18,16,22,10,27,45,95,101,140,116,106,93,105,116,114,89,95,106,54,83,64,67,75,61,69,67,78,83,73,38,25,2,21,24,41,38,33,52,24,43,29,45,33,29,53,32,53,19,16,36,21,62,30,31,28,54,20,30,53,47,30,32,24,43,8,39,51,40,32,12,13,25,22,13,38,39,21,49,25,46,29,87,17,20,33,35,29,29,32,77,52,41,46,37,44,69,32,40,41,56,40,47,33,25,31,29,54,21,24,46,21,22,37,43,18,29,23,29,61,30,50,42,22,30,32,19,44,29,24,45,11,46,13,9,22,40,17,19,22,31,19,30,19,15,20,43,7,19,59,65,62,20,55,32,34,28,31,56,12,13,25,41,33,27,45,6,7,0,20,10,34,19,26,26,15,38,52,27,33,16,30,44,45,49,46,56,75,41,38,54,44,54,37,3,42,30,22,34,22,47,26,41,55,48,44,63,26,38,16,22,23,14,12,4,36,19,38,52,43,42,47,40,8,64,17,34,31,10,48,38,33,57,44,45,85,57,50,45,53,42,43,46,30,49,51,15,7,25,27,22,38,52,63,58,85,44,55,78,90,87,52,108,118,111,110,59,70,72,108,134,96,98,108,131,118,96,115,83,99,108,125,109,84,126,119,82,89,67,105,87,85,82,108,152,121,146,102,133,99,119,103,81,91,106,91,105,76,66,93,86,29,3,5,27,9,18,24,7,0,24,13,27,24,25,37,3,12,4,20,34,16,5,9,0,65,27,65,45,95,79,93,114,137,124,124,137,129,203,227,243,89,51,59,21,40,26,27,26,12,36,27,53,83,119,85,59,30,48,51,38,81,91,111,121,70,36,37,57,82,81,84,51,39,71,53,79,185,99,66,98,130,111,94,114,94,120,86,99,110,135,133,128,103,103,152,89,85,77,88,100,102,174,105,78,86,84,76,55,83,91,80,67,94,80,180,213,66,63,82,142,129,88,62,72,92,110,104,115,136,110,115,86,69,127,53,76,124,147,146,125,111,112,106,110,95,212,147,94,118,96,93,83,83,84,106,77,69,49,155,182,69,47,100,110,118,88,134,180,160,92,107,171,232,170,145,140,156,207,181,155,158,164,173,185,183,174,199,202,221,153,178,129,119,121,122,115,95,88,81,74,80,74,80,80,39,56,81,99,111,82,56,56,108,86,103,132,106,126,145,149,141,116,107,120,92,130,119,122,112,140,106,125,123,119,92,124,132,100,100,92,104,101,115,121,131,166,143,132,115,125,95,66,48,76,104,107,79,107,79,95,91,113,59,75,95,90,62,67,123,96,70,26,16,53,101,109,110,91,33,15,35,141,187,28,9,68,92,123,47,22,93,93,114,125,85,68,101,73,97,98,110,116,91,109,87,120,92,116,97,57,65,54,68,27,55,50,48,47,44,47,57,73,51,33,23,46,30,44,37,57,37,29,46,44,56,41,31,29,50,42,37,19,48,32,53,55,57,82,59,77,86,98,116,87,67,49,45,56,35,54,51,46,89,98,99,112,110,107,128,92,107,123,100,91,92,87,112,100,93,87,88,73,101,99,99,99,89,105,97,126,78,61,101,115,131,120,79,61,27,58,53,83,41,11,6,55,140,105,58,44,18,24,35,35,66,82,108,111,74,98,131,114,88,81,99,99,73,47,64,54,51,73,73,86,64,72,83,69,53,37,27,15,24,35,59,56,30,36,48,29,35,46,46,25,35,21,8,34,29,43,20,63,27,39,19,49,18,52,62,21,53,12,56,34,34,42,59,47,13,40,4,24,33,39,49,30,44,58,46,29,42,33,17,37,44,23,67,51,36,24,19,47,65,59,61,46,41,49,48,54,43,46,32,45,53,37,31,32,16,13,57,26,30,27,31,24,43,21,22,49,11,10,26,22,36,34,39,7,10,40,44,8,43,23,23,38,8,28,40,8,38,14,33,7,12,45,46,17,54,84,67,49,29,39,28,37,13,28,30,30,25,17,22,11,8,34,25,31,6,43,21,10,18,27,16,18,21,23,17,25,55,52,36,24,42,25,33,38,36,20,60,30,26,25,17,28,57,35,38,34,18,79,40,13,51,45,3,15,28,12,6,22,14,20,10,30,44,55,46,31,38,53,38,31,27,3,3,16,38,35,32,39,14,60,43,44,54,54,44,49,45,23,29,39,0,40,29,32,37,45,43,87,32,40,61,67,76,103,104,82,78,94,94,80,90,56,63,53,91,97,86,71,62,87,97,116,127,160,148,165,183,176,158,141,132,145,164,163,138,149,142,142,146,163,131,129,145,169,124,153,137,149,144,113,131,127,114,128,146,130,5,5,39,18,33,11,8,0,7,15,32,3,28,0,11,1,9,6,42,18,1,32,26,17,94,72,33,34,58,80,81,139,140,120,97,122,139,226,245,238,83,43,44,4,47,16,29,39,27,32,27,63,84,127,130,93,56,41,64,53,70,95,148,142,92,68,35,69,75,88,74,47,34,33,89,99,182,133,84,125,129,140,86,83,75,106,92,91,125,82,74,76,70,118,100,62,57,60,64,63,117,162,113,59,111,102,91,115,111,108,89,82,96,92,157,198,63,50,89,161,127,72,85,71,84,106,92,97,119,100,117,92,102,174,58,64,99,107,99,95,109,98,98,102,115,170,81,98,90,92,98,102,71,107,105,83,114,93,176,193,72,78,89,105,109,73,181,226,215,112,95,174,165,141,146,135,184,156,102,140,130,157,148,166,137,168,169,141,107,88,103,111,81,101,75,82,68,51,34,58,59,68,54,54,52,43,33,54,90,75,66,81,73,64,45,68,90,94,119,91,125,119,116,101,106,116,108,112,125,132,135,101,130,94,98,112,140,147,149,150,163,140,140,136,144,135,129,124,92,125,121,105,97,79,77,84,62,91,92,69,81,73,80,61,71,83,52,122,144,118,116,79,56,81,134,144,95,75,78,88,47,43,122,47,21,99,155,152,93,115,129,118,114,117,104,114,119,120,113,130,125,126,132,105,123,113,90,74,35,44,30,59,73,48,66,48,52,59,45,42,70,46,44,57,65,68,43,32,32,35,58,47,44,19,38,41,37,23,49,37,56,49,54,51,47,56,92,57,64,69,74,77,83,121,114,73,33,33,58,50,41,49,68,124,139,131,119,94,61,69,84,113,67,78,100,123,89,110,99,89,96,117,102,93,99,91,82,95,115,93,83,106,109,92,81,58,33,20,18,68,25,41,51,30,25,78,153,121,109,36,28,44,27,73,78,107,119,88,85,94,69,79,110,109,92,73,87,68,66,69,60,63,71,45,94,93,83,85,37,36,15,31,40,52,38,47,37,25,29,38,25,16,51,48,44,22,23,44,48,43,32,30,31,26,35,36,26,42,19,33,21,5,13,40,35,44,41,23,12,18,21,33,37,55,43,28,70,49,44,14,29,46,50,37,31,53,30,46,27,41,39,46,47,37,59,50,45,43,60,37,52,45,23,31,43,50,39,10,24,20,15,21,8,11,9,27,43,43,5,33,24,41,14,18,41,31,62,8,53,41,27,51,43,52,19,34,19,51,31,15,39,12,30,29,18,25,31,26,6,44,107,60,39,31,33,11,26,30,48,37,12,10,47,23,27,26,4,22,38,21,20,33,31,31,43,16,37,30,28,15,38,32,65,37,32,33,41,44,59,47,31,30,35,18,31,28,17,38,32,37,41,32,47,23,33,40,21,27,23,44,2,12,10,22,14,34,29,36,47,27,34,29,58,56,41,38,37,10,17,40,15,25,41,29,65,46,49,11,71,53,36,48,52,21,46,17,28,24,51,59,52,50,50,44,48,61,62,73,53,70,69,76,55,80,84,60,51,33,52,34,98,13,36,36,53,116,151,162,168,160,199,176,178,208,201,222,173,199,199,180,186,188,180,174,161,183,168,171,168,174,185,177,156,147,168,145,180,156,127,98,14,22,20,33,2,8,24,18,24,33,13,33,22,20,6,14,39,6,21,26,22,31,46,18,172,147,112,62,39,67,91,102,145,139,108,94,108,198,243,224,96,46,41,0,51,47,20,21,22,29,33,63,93,144,229,219,160,115,88,104,146,173,224,231,152,147,116,98,79,103,114,103,62,64,92,105,206,110,101,87,111,100,72,97,94,93,86,95,77,71,77,95,96,129,157,103,73,67,99,78,105,178,154,138,144,192,163,171,160,181,185,173,149,160,212,214,123,84,101,166,149,136,138,161,158,162,166,134,154,146,142,139,212,250,142,68,70,81,91,68,102,74,101,74,126,166,126,169,165,132,183,149,161,168,168,162,206,183,247,251,148,121,112,103,137,100,190,237,182,131,118,124,113,111,92,115,123,87,70,52,90,88,74,61,63,47,49,29,5,1,6,14,13,11,40,13,17,16,27,13,12,29,20,32,18,15,34,19,35,9,28,24,26,34,17,36,22,54,69,111,117,77,114,106,83,93,127,131,127,120,70,97,120,106,141,118,104,171,154,151,169,140,146,118,120,131,154,103,118,110,142,106,111,69,67,66,71,64,78,85,52,68,9,44,74,83,58,123,125,98,103,92,125,139,143,110,78,101,128,122,60,82,154,98,39,102,141,109,120,124,126,110,147,115,104,129,122,113,132,120,104,124,96,129,102,118,49,37,111,72,73,75,90,45,69,33,50,52,33,59,52,59,51,72,54,70,37,35,63,38,30,59,36,44,39,47,32,24,48,40,42,33,67,54,68,100,101,88,94,88,67,86,123,167,148,62,49,58,56,64,48,31,20,77,132,115,95,93,104,81,88,98,104,82,100,120,92,90,78,75,109,77,85,100,84,87,124,95,102,103,104,104,79,29,33,35,32,41,34,17,11,13,45,46,15,142,242,130,111,54,15,74,75,101,119,91,83,67,68,39,65,75,69,62,68,79,76,73,71,70,67,74,91,70,97,93,73,55,22,14,13,26,43,38,66,51,28,52,59,57,41,24,74,43,31,39,22,59,39,47,14,51,20,57,22,40,24,28,48,55,17,39,36,35,60,40,25,25,36,12,11,15,31,46,18,81,39,30,28,69,43,43,59,25,18,45,39,59,47,26,14,30,36,46,60,72,45,42,25,94,38,49,37,52,33,66,54,14,52,24,13,45,11,6,32,16,26,22,29,29,51,51,30,40,55,9,50,26,48,36,21,22,40,6,36,47,37,11,16,16,19,30,16,6,4,26,34,24,21,22,69,89,66,27,18,27,45,23,27,47,34,59,41,26,25,46,15,21,19,24,22,39,33,22,56,14,40,35,7,14,30,43,41,38,38,14,50,33,49,37,41,26,57,39,32,31,18,45,23,21,40,27,51,33,37,9,31,41,45,30,9,21,37,21,23,35,35,33,45,50,47,50,66,51,33,62,48,30,31,19,24,38,36,38,34,37,42,34,41,40,38,51,32,35,19,20,39,36,58,83,88,64,53,32,70,30,68,71,56,9,7,43,65,55,60,56,46,55,53,106,113,107,35,10,34,145,205,169,215,199,213,217,239,226,240,207,219,215,203,214,216,179,179,193,206,203,230,203,194,185,193,196,201,178,202,196,191,195,220,119,9,3,14,31,13,24,35,16,11,21,18,2,18,0,15,35,26,30,1,24,0,21,23,25,232,228,223,110,95,95,109,92,144,134,112,110,105,202,244,236,94,108,84,24,40,36,61,55,15,51,27,45,75,165,229,237,213,127,125,135,206,242,252,254,183,169,145,150,149,138,176,155,133,146,130,179,245,183,123,99,137,137,136,129,145,125,145,155,155,155,148,155,157,203,222,159,104,173,201,158,157,208,174,209,195,193,195,186,199,179,212,204,208,200,204,193,159,157,139,179,190,211,210,210,185,203,213,194,217,175,211,190,183,195,153,129,81,80,70,73,79,45,89,81,119,164,204,206,213,182,186,200,180,211,189,185,217,204,192,199,173,150,107,135,100,62,111,131,155,127,79,83,78,8,17,7,58,4,0,14,15,22,48,11,61,145,106,64,35,24,25,7,29,46,20,14,17,10,35,2,9,16,0,18,7,26,26,2,5,3,61,18,15,32,26,2,0,25,44,41,83,95,94,106,137,135,141,124,134,98,95,101,127,119,128,156,113,147,146,146,139,123,100,76,125,96,108,137,148,142,124,107,89,119,90,71,62,113,69,91,72,42,38,31,80,70,39,84,120,112,100,98,98,161,168,116,53,75,98,89,80,47,143,149,69,98,103,67,58,66,94,121,84,94,79,71,80,132,89,82,87,63,104,104,104,75,71,41,101,100,131,83,101,77,28,41,44,51,53,26,64,48,33,59,54,45,42,59,54,43,44,30,60,55,39,39,43,22,33,41,27,36,61,91,138,166,119,123,81,127,116,119,135,96,77,13,30,46,46,54,83,40,52,70,44,107,110,90,69,75,85,79,108,75,91,113,95,107,100,93,97,81,101,92,101,117,89,90,70,109,116,65,98,19,31,24,15,34,39,19,25,36,33,61,44,150,185,122,158,52,60,75,92,132,99,53,76,80,70,69,65,77,79,56,65,84,72,89,71,50,110,107,94,89,120,65,55,23,6,20,11,5,51,16,52,31,36,49,35,52,41,37,42,31,19,28,30,57,14,24,57,31,26,12,16,29,23,31,26,19,32,30,34,27,35,39,24,3,3,10,9,18,36,30,34,20,40,27,28,31,42,28,35,29,47,54,32,26,59,28,38,30,51,50,48,36,59,48,33,46,46,67,24,60,56,4,26,27,9,27,8,23,27,27,25,44,52,54,38,23,40,25,55,50,61,17,37,33,34,50,51,32,32,19,31,23,37,41,30,37,20,10,29,44,13,41,7,8,14,21,54,105,68,56,15,14,7,39,32,45,34,29,29,2,34,41,31,20,31,14,43,34,33,50,30,20,8,48,27,28,29,20,50,43,41,54,40,34,31,46,53,26,50,16,20,33,35,60,29,49,16,41,48,38,42,37,20,20,41,24,32,39,30,21,37,27,44,32,37,48,30,54,23,50,45,12,22,32,49,17,3,37,52,34,41,30,51,73,29,45,60,67,55,44,9,24,31,47,81,91,74,80,36,74,35,61,47,30,22,39,45,21,45,52,50,62,104,91,107,80,143,122,47,60,46,186,213,193,210,197,215,225,205,240,213,173,215,200,238,228,219,192,201,207,205,201,201,202,213,225,193,197,252,219,212,208,205,217,218,118,32,9,12,16,3,12,10,25,26,29,26,16,14,0,13,26,26,6,5,9,27,25,22,11,234,239,237,156,113,150,103,120,146,156,163,166,136,188,250,218,89,155,152,47,32,22,22,42,52,30,47,30,89,122,141,249,219,142,169,156,229,236,225,223,174,204,179,190,187,198,190,193,192,186,181,211,217,160,160,140,170,200,186,196,196,194,180,214,202,193,197,187,208,224,240,195,219,232,243,231,220,213,189,186,203,189,200,239,219,201,204,210,177,129,84,104,117,199,184,224,179,210,223,207,180,181,204,184,182,189,151,158,116,77,133,176,107,79,76,93,71,50,89,95,165,181,209,212,203,224,194,178,189,179,209,202,204,154,72,97,138,172,111,107,71,71,106,122,132,104,82,83,32,24,40,30,34,98,98,146,172,248,243,229,236,249,244,240,232,238,212,247,215,226,224,199,238,212,192,213,235,192,224,206,195,193,187,175,169,148,151,142,174,176,171,176,120,134,104,51,86,71,109,140,126,117,128,137,99,115,77,101,76,81,133,147,145,122,132,113,127,95,105,86,103,67,122,151,109,115,133,126,116,115,106,112,93,85,70,73,54,70,81,80,90,76,68,52,70,122,95,46,72,101,110,78,104,81,66,52,56,61,133,160,73,61,64,61,42,39,49,57,70,81,91,78,65,75,91,61,36,71,50,60,35,58,17,58,33,67,100,74,89,126,103,97,103,93,90,109,78,72,70,69,52,60,49,36,29,55,45,16,56,24,45,21,53,52,49,56,55,67,55,97,140,144,103,104,104,129,131,102,44,21,22,23,65,73,66,66,55,78,45,40,54,60,73,73,76,102,91,82,98,88,74,90,68,111,101,83,96,110,85,105,133,88,105,91,97,87,68,93,116,87,42,39,27,46,36,18,33,34,27,30,34,79,80,57,133,91,45,66,61,89,62,53,50,24,61,68,90,67,82,51,86,86,76,81,78,75,94,87,94,97,39,14,41,24,1,32,25,20,42,41,22,44,22,50,27,39,33,10,29,46,44,22,52,36,25,31,28,16,40,58,78,53,31,12,44,45,39,46,21,49,25,24,13,44,31,4,8,20,38,24,40,46,31,24,19,22,32,23,36,29,32,37,40,63,39,34,32,41,54,35,53,40,64,53,53,16,23,31,59,31,43,63,26,43,1,7,1,28,24,24,43,27,35,60,40,39,41,39,59,34,22,41,45,26,32,47,55,29,43,50,20,23,42,54,17,27,28,24,44,23,26,39,11,5,22,46,40,44,65,36,44,20,45,38,37,18,49,46,8,4,21,13,44,26,6,26,33,24,47,33,25,33,9,19,10,26,33,49,32,35,34,30,40,72,27,32,29,25,44,56,46,40,34,34,42,41,20,58,43,30,35,43,16,11,21,40,38,20,30,34,19,49,35,47,42,30,36,41,23,35,35,43,45,37,52,41,4,12,13,34,26,7,10,30,9,49,43,51,65,35,41,17,21,60,123,93,95,99,70,113,96,92,73,76,89,108,88,60,36,50,26,49,64,66,103,119,132,104,99,65,131,239,204,215,229,206,224,227,191,206,198,193,219,205,192,205,215,192,200,181,215,213,225,208,211,229,188,227,229,205,223,176,216,202,226,97,23,21,11,0,29,5,14,6,0,31,17,12,29,18,12,19,3,2,8,14,35,34,40,12,234,245,246,150,96,156,150,161,172,191,250,249,209,231,241,233,106,180,119,24,63,5,34,10,13,39,23,55,93,144,136,156,149,129,149,138,195,224,193,162,145,159,193,189,197,225,205,195,193,198,168,115,108,139,172,180,192,196,205,213,198,200,183,203,195,196,193,190,184,73,98,138,227,247,255,235,178,180,186,192,173,183,227,250,188,174,176,181,130,39,9,41,92,170,218,201,194,187,201,223,176,180,176,205,172,177,182,82,57,30,63,147,162,134,27,85,77,118,133,172,180,195,190,193,187,188,183,186,169,196,195,183,177,78,44,69,103,174,150,135,69,81,111,129,143,115,122,162,229,229,240,228,249,245,254,250,255,230,247,254,231,236,252,254,255,255,249,232,254,247,252,239,255,248,255,252,233,243,234,237,242,253,246,251,253,249,246,234,234,242,250,229,255,249,233,172,135,88,98,117,99,59,93,95,106,86,108,102,72,67,148,100,124,121,118,97,126,130,94,140,134,107,98,134,136,131,147,139,101,82,117,82,92,74,45,44,51,75,85,53,69,46,25,77,64,75,82,54,79,107,88,107,77,85,118,81,70,52,101,147,65,27,46,9,29,26,39,76,76,62,61,58,54,67,81,77,74,51,47,81,46,69,57,19,54,24,44,74,74,105,127,124,113,124,156,146,136,126,71,25,44,43,68,11,67,45,33,47,50,17,44,28,40,40,60,61,78,94,72,35,118,141,113,139,122,116,69,27,38,27,49,65,131,119,72,44,47,31,57,28,28,51,50,58,76,83,88,108,108,95,116,99,99,82,69,85,119,115,94,115,102,107,122,69,63,72,78,112,117,103,72,60,35,45,19,52,27,37,25,40,29,48,46,14,97,51,58,34,27,49,77,51,63,70,76,71,78,52,77,73,82,49,71,77,97,69,76,77,82,29,26,41,10,29,23,33,51,62,36,43,50,28,28,19,61,26,28,16,29,38,39,37,55,34,30,23,29,18,40,40,32,31,57,51,27,34,26,44,30,42,39,24,6,2,2,54,9,37,22,44,25,51,29,45,29,61,50,32,44,22,37,34,49,40,14,46,38,43,35,43,44,36,18,55,48,20,54,46,57,40,41,31,37,5,35,12,20,24,17,35,25,38,34,46,30,55,25,39,54,38,38,52,35,48,31,48,46,36,28,21,20,36,56,71,20,34,54,29,42,44,34,27,39,66,21,38,32,27,54,69,86,38,39,44,24,44,27,24,32,7,19,25,2,17,24,10,17,19,7,44,16,12,14,17,39,43,48,54,21,40,46,61,43,31,41,60,38,43,42,28,65,9,46,45,26,45,44,50,55,38,28,19,17,34,23,3,7,28,3,22,27,34,54,24,30,18,35,23,38,44,49,34,27,23,29,41,16,39,25,23,32,35,24,58,48,42,35,43,44,56,29,77,150,172,152,135,114,114,149,161,136,149,129,149,151,159,128,166,105,93,85,36,58,64,53,84,104,110,127,103,192,238,219,223,211,207,227,202,179,187,183,221,211,172,180,214,205,193,205,178,201,215,193,219,199,181,207,209,197,207,185,213,214,209,183,129,10,4,16,5,9,18,0,17,5,3,1,10,19,15,10,12,22,16,22,14,16,28,37,1,249,233,233,130,113,140,164,180,205,224,249,241,242,240,253,225,100,161,86,20,37,14,34,21,25,44,34,54,64,110,101,72,73,93,102,115,126,130,150,152,201,181,144,214,177,203,168,169,194,158,132,17,3,78,146,203,219,196,168,185,192,178,163,157,178,179,157,178,69,4,28,60,196,226,227,232,157,145,154,163,162,193,212,211,186,169,156,150,61,1,12,23,22,134,179,202,219,159,176,175,180,183,217,164,180,172,117,52,38,38,45,118,171,148,77,68,81,119,171,203,199,170,193,181,168,179,186,147,174,200,168,168,103,27,54,19,44,86,137,129,83,31,47,81,101,107,171,247,244,255,236,254,244,248,252,232,255,254,250,230,253,247,245,244,243,240,240,247,255,251,252,250,228,230,242,243,243,255,254,239,239,249,248,255,254,255,240,246,249,255,224,254,243,238,229,233,200,121,93,107,120,122,108,149,134,85,115,126,104,114,119,115,110,129,121,128,124,106,109,130,149,88,114,142,139,145,90,73,53,94,116,123,96,87,44,61,77,84,53,61,62,35,27,56,57,82,74,49,39,45,95,62,68,74,101,78,80,74,65,150,79,21,63,66,95,46,28,53,76,72,100,89,65,33,44,103,90,69,80,55,46,76,48,55,56,56,53,63,102,111,131,135,136,134,128,148,118,87,37,55,24,78,95,79,68,50,55,43,42,66,75,64,23,57,86,116,114,108,121,51,91,149,121,143,81,15,30,28,38,64,110,94,108,129,137,47,27,75,35,22,29,62,119,67,109,89,111,96,97,100,119,116,100,99,97,107,77,106,108,113,72,89,87,61,82,97,82,104,120,112,127,82,47,20,47,35,40,27,57,32,35,55,44,35,99,84,30,15,12,66,67,55,53,81,67,85,63,89,78,72,76,45,64,79,87,96,71,72,45,16,3,21,24,28,24,31,63,62,25,33,36,22,46,38,54,49,43,51,54,44,22,53,11,34,25,46,50,53,57,19,25,50,40,39,32,45,43,51,39,64,43,9,34,45,35,10,17,24,2,29,22,34,27,51,39,42,31,37,35,37,49,37,43,31,18,52,38,26,45,61,51,45,61,43,60,35,46,31,21,39,63,39,53,13,30,23,33,37,24,27,32,1,14,28,39,31,24,68,38,34,39,45,59,48,80,33,30,16,14,8,57,38,23,36,37,42,38,36,29,47,34,37,49,33,47,9,3,40,64,61,77,58,24,29,44,24,38,25,9,9,11,23,8,16,24,28,47,22,38,22,39,19,14,25,38,28,35,28,54,37,28,29,34,36,44,54,26,38,35,18,21,34,29,43,20,43,36,52,29,53,29,56,23,27,23,4,11,19,10,41,32,56,25,23,39,15,16,24,51,22,39,3,13,31,16,36,29,23,33,22,36,2,33,41,21,23,57,45,56,27,35,199,252,241,222,177,141,144,163,155,157,161,159,151,177,175,170,159,170,149,119,80,88,57,67,102,114,145,71,140,223,219,196,222,191,209,187,174,179,189,206,199,212,167,199,184,206,210,180,176,177,191,198,186,194,191,211,194,184,186,200,212,202,210,190,124,22,0,10,9,27,15,21,14,18,24,8,25,8,13,12,45,21,8,14,10,14,8,29,14,246,238,208,137,122,146,116,145,187,249,247,240,253,253,232,243,157,186,66,21,56,12,50,18,18,46,48,57,75,125,85,32,57,73,117,122,149,148,179,193,153,161,188,178,172,180,175,160,141,137,55,9,30,19,88,191,220,197,174,157,160,167,169,150,176,179,171,116,77,30,46,42,68,164,208,210,151,149,152,197,190,195,167,174,165,150,162,83,29,39,40,29,39,55,125,214,204,202,169,188,165,198,193,184,164,131,82,47,69,77,91,84,126,193,152,107,113,157,145,214,179,177,194,177,186,168,156,164,181,172,185,96,28,12,25,37,40,35,74,96,73,59,11,18,24,11,72,124,231,243,237,230,215,206,184,186,174,168,129,117,119,228,245,245,250,229,254,252,247,251,253,255,247,246,255,238,251,246,255,253,241,237,231,246,250,231,255,253,250,244,253,255,249,249,239,243,235,179,75,82,67,94,86,130,108,126,98,113,145,150,148,136,128,135,97,132,124,73,110,111,94,76,127,135,130,117,80,68,85,92,104,103,104,78,67,80,77,108,84,49,57,51,39,56,66,57,60,63,58,29,76,75,97,78,69,96,105,106,88,139,125,21,70,148,141,89,74,60,108,162,161,126,60,33,100,104,91,89,66,85,71,84,90,77,85,59,79,79,87,90,143,115,91,85,78,45,63,64,68,76,86,98,101,81,95,83,78,66,69,57,40,55,27,43,123,133,134,109,128,112,133,140,78,70,15,6,9,72,115,131,130,118,127,111,123,127,112,85,29,9,17,87,131,115,93,100,120,113,109,138,86,102,89,91,140,119,106,79,111,112,98,94,71,56,86,79,90,122,99,107,115,109,49,23,22,34,28,35,39,44,56,57,52,96,185,108,19,30,12,65,54,78,89,71,94,72,87,57,61,102,71,85,69,88,104,87,52,41,14,4,9,43,32,44,41,65,57,81,47,33,27,42,45,56,26,46,23,48,53,50,41,26,51,32,29,36,11,52,29,43,40,36,43,43,57,54,64,35,39,48,55,60,54,55,29,32,50,33,39,14,30,45,34,17,38,43,25,45,35,6,46,28,57,51,18,30,29,54,45,67,54,9,19,13,60,58,12,47,45,45,59,22,31,2,32,38,53,26,27,22,35,45,34,42,27,30,38,35,47,50,39,64,19,54,24,33,16,22,16,7,34,29,22,43,47,18,16,9,4,51,30,39,14,25,21,33,36,49,71,41,78,82,45,25,33,12,36,21,14,30,16,38,18,36,21,34,38,12,40,6,30,19,9,32,20,46,21,52,17,20,31,31,45,62,62,22,45,41,41,15,37,44,19,33,33,20,47,32,33,26,22,22,36,19,33,23,27,15,16,33,33,17,38,22,33,37,8,22,19,25,20,25,52,60,57,31,31,20,34,18,29,30,33,10,9,35,6,39,36,8,66,199,248,251,227,220,187,147,165,135,146,148,140,150,153,185,161,164,191,177,140,139,121,99,103,127,90,81,104,187,243,231,224,213,203,214,189,181,182,192,188,207,212,202,204,209,217,218,192,219,191,218,178,183,189,212,199,194,201,221,205,202,216,217,197,124,7,0,5,23,33,1,23,7,2,23,1,27,28,2,14,26,22,18,9,23,6,20,23,9,248,231,234,212,140,152,103,127,160,166,194,244,244,238,216,219,136,184,71,7,31,3,54,15,54,49,60,66,88,145,134,101,103,105,141,158,176,192,166,187,160,205,167,168,155,157,180,177,133,32,71,60,58,65,49,113,205,199,180,184,197,178,157,160,183,183,145,84,113,135,132,57,31,119,198,177,173,184,209,208,153,160,125,169,174,174,63,38,60,79,125,88,44,18,79,139,191,201,179,192,211,187,174,163,150,81,86,103,134,116,102,91,68,128,168,135,157,157,160,189,182,178,186,202,191,180,171,183,184,171,109,128,119,106,109,129,107,107,165,237,248,243,217,136,72,38,16,6,96,151,138,161,181,241,242,246,241,154,126,102,178,254,232,239,222,252,250,242,236,246,255,242,236,254,249,237,251,226,252,233,255,252,243,254,242,254,252,241,247,237,202,123,164,238,240,236,229,169,84,72,91,89,82,138,122,95,67,104,124,148,155,118,112,115,102,134,137,122,94,82,97,91,135,160,139,95,100,111,105,90,78,90,124,120,101,117,134,97,113,103,93,91,51,56,68,53,54,53,39,16,58,87,106,82,83,112,106,123,105,176,139,62,109,148,126,122,87,111,168,170,151,107,47,44,70,87,68,95,104,106,71,144,128,144,93,126,76,82,104,95,71,52,56,68,72,84,85,131,134,160,122,134,82,65,86,111,114,91,89,87,118,108,73,71,108,111,106,125,117,141,109,90,11,21,12,45,68,109,132,143,136,124,127,131,137,115,132,92,11,17,42,147,95,91,146,112,79,100,97,118,98,100,99,120,89,76,100,110,118,107,83,73,55,74,87,84,108,116,112,114,84,24,36,36,10,21,30,26,34,53,22,43,74,96,230,148,34,25,47,72,75,90,56,80,63,65,71,54,77,68,67,101,72,93,51,41,21,4,31,25,8,29,61,60,75,69,72,46,48,11,22,48,68,29,48,59,25,51,41,34,33,51,27,38,50,50,39,48,21,80,36,59,65,33,45,42,38,32,33,86,66,72,48,58,74,59,18,14,28,36,13,23,25,22,43,52,46,56,32,15,73,53,43,30,49,34,24,51,27,55,55,45,49,32,56,40,43,55,28,74,39,15,29,33,19,44,36,51,26,25,34,35,31,43,19,38,43,37,47,36,39,35,72,46,44,31,32,4,4,50,10,19,21,14,23,13,46,34,5,30,23,27,19,32,3,0,40,16,19,49,66,85,83,58,29,7,36,21,45,30,41,22,33,36,31,40,26,34,5,27,16,25,34,23,56,22,27,31,52,22,47,14,54,34,39,18,37,21,40,43,15,31,23,33,42,38,43,12,18,33,54,33,20,29,15,25,19,43,39,47,36,53,40,28,19,35,43,11,53,31,34,70,22,44,46,39,36,36,34,15,15,29,24,26,29,14,29,18,26,131,190,228,188,165,205,220,218,207,204,161,140,133,103,108,103,127,145,140,156,139,145,159,150,140,132,147,103,113,158,229,235,240,245,240,230,199,233,212,218,245,218,212,232,217,228,242,200,228,219,237,237,218,235,195,229,247,185,231,205,215,225,218,202,223,195,113,14,4,1,21,31,10,1,7,16,20,35,15,15,2,0,8,15,1,7,25,29,3,18,4,252,242,222,215,93,83,80,102,70,48,47,99,139,175,227,181,156,162,62,49,27,6,35,22,32,66,55,74,130,210,149,132,143,113,155,185,158,207,193,187,192,197,172,185,177,142,171,141,49,54,122,120,125,108,68,70,102,204,225,182,170,164,168,186,171,112,51,110,140,161,181,141,74,116,181,155,170,212,178,181,135,137,143,123,146,90,27,30,85,187,168,172,118,32,53,84,165,198,201,170,185,189,180,135,114,61,73,106,71,119,145,91,53,101,124,138,160,198,204,165,195,170,182,158,190,200,193,192,179,116,95,138,154,140,183,218,246,254,243,233,235,239,227,238,243,220,175,118,172,208,252,248,248,229,253,234,250,242,230,241,230,224,250,245,255,244,243,230,247,247,255,238,253,252,226,251,235,235,255,254,243,250,251,244,221,244,238,244,231,103,40,25,93,145,169,161,166,92,82,67,100,105,117,144,145,128,91,112,114,97,116,100,102,67,83,83,128,93,80,99,130,121,142,101,107,108,140,130,95,100,112,99,103,105,122,124,127,126,102,120,49,87,79,111,92,60,85,63,46,16,71,100,93,88,96,101,104,119,110,155,177,70,66,81,76,85,91,170,193,138,157,95,33,20,67,90,59,94,64,73,104,144,163,156,157,113,117,77,77,85,115,66,76,100,118,119,118,190,180,123,124,122,93,71,86,93,132,136,100,131,137,124,91,83,58,73,126,148,117,111,65,58,80,79,110,123,142,144,161,138,144,133,130,118,136,101,111,100,60,27,76,115,147,89,114,113,102,129,68,103,79,117,117,93,63,92,92,79,97,75,88,87,87,86,95,91,108,107,97,42,70,19,23,17,20,65,27,28,35,41,37,44,42,66,131,166,77,32,64,109,86,66,96,86,78,73,73,71,90,82,73,93,78,35,40,25,4,29,13,0,32,37,52,68,64,63,52,49,13,25,49,14,48,25,56,36,42,21,34,15,5,36,7,49,26,12,34,57,25,40,75,51,33,41,48,40,46,45,71,78,97,88,73,72,78,66,54,22,22,32,13,17,35,32,25,26,31,42,32,30,38,42,36,36,13,47,56,47,73,48,30,47,54,20,54,43,48,21,41,36,34,21,60,50,39,32,2,6,21,30,25,51,38,48,55,27,59,42,33,35,37,54,30,47,21,46,21,6,40,30,16,16,35,15,23,38,17,26,46,25,22,26,46,12,25,28,20,44,43,25,26,53,70,77,56,22,14,14,36,51,29,50,41,38,25,26,33,20,18,30,14,24,26,16,23,37,22,28,31,47,39,38,21,38,38,24,54,49,40,24,43,32,17,30,38,42,26,25,62,15,18,11,29,41,42,62,44,17,38,14,29,35,30,56,33,63,28,47,28,35,42,46,21,41,40,46,26,25,40,22,8,14,23,31,14,30,34,40,175,248,247,251,204,207,181,182,178,199,216,202,188,167,134,115,110,115,120,134,148,124,130,161,159,156,169,135,115,148,202,210,203,214,232,231,228,231,230,223,251,222,233,247,239,238,234,252,247,216,226,235,229,223,228,232,223,221,216,220,206,191,223,217,212,211,217,107,6,2,4,18,7,15,15,9,32,48,6,0,26,6,10,2,18,12,9,5,31,12,13,22,173,201,211,136,23,47,65,51,79,60,51,44,52,135,208,134,118,150,63,36,20,32,19,36,53,28,29,51,106,181,181,149,147,165,176,208,195,202,184,182,185,192,164,151,169,167,155,51,31,47,138,167,146,118,59,61,55,173,187,152,164,154,163,129,145,75,15,97,168,180,177,202,178,157,161,135,147,173,166,145,104,147,166,117,98,34,13,28,118,177,153,183,119,61,60,68,75,187,180,124,122,155,145,123,82,32,65,121,103,82,110,77,78,85,85,106,123,172,220,177,211,181,205,199,182,228,175,176,117,66,48,89,179,238,241,246,249,255,245,232,243,246,242,255,243,239,254,247,250,235,254,235,250,251,249,239,255,253,234,237,247,234,234,244,253,249,247,255,234,243,249,245,247,234,255,252,255,247,240,235,243,246,249,242,255,251,249,248,90,39,32,19,93,85,87,127,151,65,93,115,129,177,120,120,126,115,105,104,85,69,84,84,68,37,61,76,96,103,111,136,124,98,146,130,94,136,140,134,91,82,66,117,97,88,133,137,89,94,101,86,82,39,67,85,73,61,63,87,137,127,126,95,98,102,135,138,144,146,143,148,183,124,68,107,144,123,145,173,147,105,138,84,19,44,66,108,64,71,76,78,116,147,155,158,146,132,164,147,104,109,103,67,86,108,106,116,131,154,138,95,118,119,93,43,79,139,131,137,80,79,84,99,70,101,63,83,129,104,60,8,12,67,139,128,117,144,154,151,134,136,120,111,133,95,89,76,91,78,106,95,106,124,90,109,87,114,91,97,114,106,100,81,105,85,59,97,104,96,99,111,94,105,105,106,87,94,103,70,50,41,29,26,13,34,52,82,41,47,14,14,22,49,42,18,68,172,150,75,47,77,87,83,70,87,60,60,57,107,84,82,65,57,16,22,4,10,27,12,25,77,62,76,68,66,53,81,50,57,34,15,37,16,34,11,26,19,28,24,41,52,27,26,23,56,36,24,49,46,43,37,21,54,27,54,24,39,27,52,30,67,71,86,61,71,94,72,67,55,35,9,25,19,7,31,21,36,20,39,30,7,57,43,37,39,27,44,40,45,40,45,27,49,37,50,46,28,50,32,38,44,27,42,14,36,28,50,50,33,47,42,44,41,15,48,36,36,50,48,60,35,30,52,17,27,62,18,34,10,18,12,4,15,7,11,13,7,25,27,31,47,48,46,27,23,12,36,26,18,32,23,41,50,54,88,55,28,18,21,16,33,50,64,36,41,44,21,46,13,20,31,17,5,28,22,20,50,42,32,45,28,13,26,59,45,28,8,25,33,21,28,34,38,29,12,20,29,42,31,39,17,18,18,38,36,30,43,13,67,42,36,25,32,28,32,24,11,25,56,43,63,39,40,28,44,29,40,48,29,27,37,11,43,37,49,38,9,42,66,249,236,246,245,239,255,221,200,176,173,182,187,188,210,207,152,124,144,121,158,159,182,127,169,158,157,168,155,138,160,175,170,138,160,141,150,126,165,158,139,159,166,172,175,187,188,157,178,197,190,167,172,192,194,210,207,203,223,201,198,194,180,215,208,231,226,232,134,11,1,6,11,11,27,12,9,6,20,19,10,15,13,13,6,15,37,26,8,8,5,30,28,103,102,64,46,28,72,60,86,97,74,78,109,90,124,170,73,74,117,21,38,37,36,21,27,29,7,45,74,87,123,133,125,173,169,187,188,185,177,174,164,169,161,170,162,149,128,102,29,37,67,126,161,119,149,138,136,71,120,149,157,103,86,155,131,65,35,26,80,135,177,177,223,223,185,188,123,102,177,173,128,116,180,186,142,122,39,31,58,96,182,177,206,132,23,62,28,56,125,126,105,77,134,107,61,62,70,76,127,60,71,99,66,83,119,179,215,183,188,215,181,163,174,196,166,172,175,167,147,125,77,166,249,246,244,242,234,236,239,249,252,224,245,255,255,237,247,249,243,255,250,245,254,255,231,241,253,237,254,255,245,250,231,243,245,222,238,236,249,245,255,249,255,240,248,242,239,252,250,251,222,252,251,252,243,244,236,230,114,86,63,74,100,70,74,38,98,114,61,124,51,132,116,96,118,107,65,88,70,69,73,100,114,90,77,79,102,117,125,172,155,102,83,138,130,128,98,105,97,73,106,99,93,80,83,137,135,132,102,103,72,70,80,23,29,67,62,105,110,114,133,156,148,115,140,132,144,123,116,135,127,135,121,49,53,103,127,66,92,69,46,63,60,60,16,77,90,22,29,88,113,129,144,128,119,145,158,211,170,144,115,63,59,36,68,72,106,123,112,133,97,124,90,89,26,46,145,147,129,102,49,77,111,107,128,86,80,54,8,27,9,68,112,117,98,117,71,79,91,95,105,104,85,64,61,95,90,65,77,89,91,102,114,79,88,113,88,98,96,103,73,103,135,125,123,70,80,127,83,62,84,103,92,96,77,101,77,53,8,17,28,32,17,62,56,88,108,98,59,36,18,11,35,12,15,53,144,179,91,57,73,69,65,78,69,64,54,66,77,71,47,28,40,16,42,10,25,24,55,64,62,75,92,73,55,79,72,66,47,21,47,27,25,32,32,23,23,21,37,45,32,38,56,50,38,30,42,33,44,45,34,48,32,28,37,29,45,27,47,48,110,63,57,52,67,74,81,79,29,2,26,1,14,38,39,42,17,32,18,8,27,12,35,27,30,22,29,34,33,22,24,51,41,44,71,35,53,32,41,27,35,36,30,20,25,26,58,43,59,35,7,19,39,24,42,30,12,48,52,23,75,50,27,36,32,27,32,36,7,36,14,14,4,18,42,24,16,26,17,52,38,40,22,26,24,37,27,17,35,11,62,25,21,39,72,96,46,0,14,5,6,36,33,27,70,49,26,40,24,16,29,41,18,31,18,41,17,4,28,32,41,36,51,39,30,27,27,21,36,44,45,31,14,45,29,27,39,35,37,18,26,47,6,61,49,27,11,74,51,44,49,14,40,47,24,46,32,8,31,8,43,33,35,38,36,38,37,16,61,8,31,16,13,38,34,8,33,19,100,247,228,251,248,246,244,223,245,227,178,181,169,182,175,226,221,238,221,198,188,192,173,189,195,164,175,173,162,162,185,166,141,107,37,18,5,27,32,60,39,49,35,27,53,45,50,66,63,79,112,79,67,96,114,97,113,117,134,141,157,127,128,147,166,166,169,190,106,8,0,25,27,26,19,14,15,11,12,13,16,10,4,7,35,37,17,22,14,2,16,27,8,112,76,44,33,61,110,148,160,133,125,124,134,92,182,183,82,68,62,30,45,43,35,35,23,28,20,60,78,113,113,154,134,156,163,192,193,161,156,155,180,183,165,159,159,99,101,16,25,30,78,76,82,110,147,228,172,55,75,108,131,133,121,151,58,30,30,41,87,161,156,176,231,182,188,182,108,92,162,218,135,121,217,254,180,164,125,62,53,100,197,178,167,134,32,41,39,35,99,164,115,164,166,79,38,79,88,87,102,80,90,106,96,87,159,240,239,210,148,183,171,156,136,109,125,85,112,133,115,218,250,248,249,223,252,255,255,244,249,236,251,232,248,255,253,250,244,230,252,249,241,255,246,251,255,239,254,246,224,255,242,238,248,237,246,223,244,251,242,220,255,254,240,249,252,225,252,252,252,249,255,255,243,243,228,160,158,84,59,71,76,71,70,78,69,56,81,106,119,120,110,110,103,86,65,91,67,80,94,87,85,129,142,132,95,83,102,129,100,128,147,133,131,130,141,115,66,84,67,77,107,110,85,82,103,92,108,124,111,107,77,88,74,75,41,37,105,104,88,97,98,88,64,41,81,81,29,56,36,31,58,90,146,60,10,33,34,36,48,19,46,57,64,51,36,62,56,39,42,106,137,151,145,133,103,133,136,186,194,156,150,139,115,105,87,62,70,88,101,86,116,159,105,95,19,38,54,92,123,107,61,49,94,144,115,58,36,32,8,69,95,115,82,103,76,63,42,45,56,69,78,59,65,49,54,83,50,75,58,63,74,86,97,101,108,93,117,107,87,68,124,129,150,133,97,53,46,61,67,21,39,49,77,116,75,39,38,31,21,25,16,18,47,71,107,118,121,146,117,51,23,30,27,51,82,82,111,143,138,50,30,53,56,69,91,78,45,91,76,70,39,39,25,10,21,9,39,34,64,52,64,60,47,96,56,79,69,69,38,31,78,25,41,57,25,38,16,50,37,65,46,32,32,23,27,31,31,20,30,53,49,42,46,66,31,16,44,45,23,65,64,52,49,76,52,15,23,48,21,6,33,30,39,31,42,36,6,31,25,51,34,61,19,26,15,8,28,22,19,9,57,26,11,36,27,41,30,29,23,33,40,31,34,18,57,40,41,62,43,28,58,37,40,15,47,11,33,28,25,30,21,24,18,20,22,23,33,8,39,55,23,27,35,4,21,23,20,2,30,13,31,16,25,36,52,6,26,17,25,17,36,28,42,28,65,87,97,31,21,26,23,32,35,30,37,38,43,22,47,27,19,35,20,18,20,15,32,28,40,33,38,7,26,26,17,36,4,40,21,42,40,49,18,38,38,18,7,17,51,20,13,20,23,26,54,26,39,48,57,11,37,25,8,54,39,33,28,3,19,23,41,35,37,43,23,21,33,50,46,23,19,16,29,26,26,31,49,4,134,234,246,252,246,234,253,239,239,214,209,225,203,190,168,186,220,253,248,174,149,182,175,191,161,148,152,162,153,166,163,130,122,79,27,7,10,6,34,30,0,9,22,31,16,18,31,10,12,36,16,21,41,25,10,28,7,11,3,33,42,41,51,57,76,89,90,119,91,30,4,31,8,9,17,25,17,11,22,21,36,38,15,27,11,7,14,32,23,23,11,16,14,139,99,53,89,95,101,151,160,155,137,155,170,124,193,218,76,50,59,27,55,21,53,34,26,37,43,31,80,125,146,134,139,202,186,190,165,172,162,163,158,166,162,147,151,96,57,21,31,67,56,53,50,55,88,205,126,42,81,96,138,156,106,106,31,15,28,88,149,189,193,197,217,159,161,178,129,94,174,219,160,112,218,247,202,172,180,106,67,115,193,123,142,60,43,76,41,86,63,143,174,167,133,57,54,91,96,80,132,109,116,111,122,124,142,202,193,140,61,74,88,87,75,58,64,81,104,142,171,244,244,254,248,254,254,247,236,240,254,249,246,244,253,237,239,255,246,253,245,240,255,240,246,250,245,252,243,252,252,245,249,245,249,254,226,238,243,241,251,242,245,254,250,244,247,248,247,252,245,230,243,252,244,253,241,155,85,34,48,54,34,41,71,74,65,73,99,109,135,169,141,115,102,103,101,106,120,116,99,100,117,159,103,94,93,76,79,127,97,113,122,115,119,129,125,112,60,23,49,81,98,120,78,107,61,101,112,107,110,82,73,106,117,89,61,34,57,74,56,40,35,28,35,19,52,49,19,35,15,25,7,42,153,79,27,25,40,51,57,57,55,54,73,46,63,76,64,40,60,112,158,178,148,158,168,163,161,165,155,181,134,138,124,104,113,80,84,123,123,104,122,91,114,90,37,15,45,19,51,83,79,85,130,97,44,4,6,22,88,125,134,142,129,88,27,22,35,57,47,42,12,44,35,45,14,28,41,50,42,34,43,68,108,86,88,81,122,108,105,104,140,139,128,70,44,62,43,46,41,63,48,39,42,47,63,7,26,18,18,19,51,65,99,135,120,123,114,135,115,107,93,114,76,31,68,31,116,100,154,116,60,57,61,61,70,61,56,55,15,42,28,18,16,11,26,26,73,88,65,61,73,44,76,93,59,68,46,56,37,22,61,42,36,31,49,28,21,42,30,32,47,44,39,46,41,52,49,41,20,42,52,24,47,34,47,14,66,26,42,48,21,19,14,46,48,15,33,34,11,19,20,9,31,45,9,18,29,26,50,28,40,26,26,20,46,48,17,8,34,33,33,36,31,37,29,30,24,37,35,44,41,2,9,24,10,37,44,31,10,38,5,19,16,24,2,32,34,29,0,29,26,39,32,28,41,25,22,7,34,40,37,7,31,37,23,22,23,25,20,28,20,18,18,40,38,13,35,22,50,25,14,26,24,31,39,50,102,84,47,6,18,31,9,10,43,34,35,40,2,11,38,23,20,21,33,14,24,19,16,27,10,38,25,24,20,41,45,22,31,32,21,35,29,50,10,23,12,29,23,38,38,31,9,38,10,64,49,59,45,35,37,8,35,41,25,60,56,31,29,42,33,41,31,40,52,23,23,32,34,24,28,40,36,36,23,9,50,34,171,234,251,238,252,236,249,246,246,246,223,248,209,250,227,219,163,220,188,79,57,84,86,74,98,83,74,83,51,85,69,88,116,99,144,143,137,142,124,79,105,131,90,69,56,47,75,61,66,56,42,36,18,17,49,62,15,24,25,10,25,16,28,20,25,33,32,23,55,11,15,7,20,13,17,21,12,3,23,2,27,14,29,2,13,26,5,13,27,18,8,26,23,82,100,92,157,115,115,85,89,106,75,117,175,130,215,199,101,97,53,23,25,38,18,30,23,26,54,69,68,126,208,222,215,220,221,225,216,220,203,208,205,205,216,231,145,78,118,125,95,102,97,121,97,67,70,109,99,74,126,151,103,89,82,89,45,54,58,118,196,210,185,225,236,156,154,204,152,133,174,228,171,98,187,244,211,160,173,159,114,142,176,63,53,44,74,94,78,60,63,63,103,85,77,53,54,126,117,73,107,104,117,90,119,115,99,105,110,51,26,26,58,52,75,104,145,231,237,245,255,237,254,232,249,255,255,243,240,255,249,233,251,243,255,250,254,248,245,253,248,229,238,236,255,243,246,235,225,248,255,250,250,252,231,255,252,254,254,234,230,246,254,234,236,254,246,251,252,242,253,231,252,254,243,243,245,128,93,56,44,110,103,83,81,86,46,38,105,119,134,184,148,133,128,119,120,101,70,70,104,101,109,102,88,97,86,90,62,80,105,95,109,93,106,104,149,81,72,33,30,44,39,76,59,44,47,101,143,127,102,99,78,118,92,111,54,39,54,45,44,46,59,29,32,43,56,79,68,45,33,82,44,71,163,114,44,95,89,91,59,44,58,70,109,69,51,64,118,161,164,171,175,116,109,162,153,166,126,150,96,57,64,4,11,20,66,102,58,81,65,36,38,39,57,80,43,12,15,11,50,116,82,86,54,10,4,15,78,113,135,132,138,161,113,55,23,22,19,27,34,27,34,37,45,32,24,13,43,40,43,13,46,43,75,74,94,81,110,93,107,116,94,55,10,43,61,42,22,43,38,26,38,24,28,12,25,25,38,12,20,64,77,104,110,110,156,99,110,122,107,159,182,171,72,27,61,74,73,79,129,159,70,48,39,77,53,95,53,17,31,16,17,29,19,41,70,67,84,86,85,71,72,92,29,62,47,43,70,60,35,39,34,46,73,15,56,23,25,47,62,35,33,68,39,35,49,52,71,15,40,32,30,58,33,21,52,45,25,34,38,53,67,40,23,27,9,36,35,9,39,18,23,20,5,26,42,2,11,38,30,23,16,41,12,34,34,20,20,16,21,39,50,21,15,22,33,34,16,15,21,28,28,30,33,17,19,9,37,28,13,21,16,21,32,18,36,24,54,19,42,17,16,27,12,7,5,33,4,22,41,29,19,37,38,6,30,22,23,13,14,23,29,24,35,11,17,16,24,31,27,50,33,20,25,12,28,23,59,94,79,35,16,17,30,19,41,21,27,24,55,13,27,10,26,42,44,7,22,19,37,41,47,14,38,33,18,34,17,16,31,38,36,20,39,30,18,51,18,45,28,18,33,15,32,23,39,39,31,9,40,44,21,26,17,44,32,59,23,12,30,11,20,5,36,32,17,38,39,42,34,26,35,21,44,49,13,17,31,46,201,251,255,243,247,243,233,233,232,246,230,240,230,246,218,216,118,70,54,29,0,15,3,12,18,25,25,32,18,22,23,71,154,192,228,235,233,236,241,224,238,223,214,232,207,175,194,189,205,170,169,174,195,162,168,198,166,151,115,134,154,120,117,100,88,71,52,39,54,32,10,6,4,8,6,18,3,26,17,8,25,0,7,13,5,9,13,19,5,18,26,11,0,154,133,161,173,164,134,100,111,96,88,93,121,132,149,183,67,67,38,50,41,23,31,48,35,42,29,26,60,159,220,253,238,243,251,243,242,231,188,244,222,227,233,234,129,111,168,130,134,148,135,131,109,157,122,136,125,133,167,249,130,49,64,105,122,117,126,187,205,240,211,218,220,164,137,131,117,129,186,127,85,72,73,165,107,108,155,156,148,147,176,94,73,68,88,125,81,87,77,76,53,44,63,83,93,93,128,104,130,97,116,114,81,82,108,140,109,129,65,50,72,98,117,165,200,224,238,252,246,250,253,229,235,247,238,255,249,250,246,226,255,246,254,248,240,236,243,238,253,226,254,251,219,254,250,247,237,242,245,255,255,255,240,245,240,233,152,144,175,151,172,154,154,137,137,155,135,157,153,183,145,145,130,139,118,50,58,60,110,125,100,125,104,77,69,75,103,134,139,131,110,112,94,99,94,69,57,71,64,81,97,63,103,96,85,60,94,98,103,116,104,54,84,97,75,100,59,14,21,20,55,54,42,47,36,121,134,119,106,62,103,91,105,56,34,13,23,32,26,45,70,59,49,53,105,155,141,126,134,141,146,110,162,167,96,172,135,102,95,113,114,141,82,40,13,75,127,108,171,127,136,116,62,88,75,91,69,24,22,32,16,25,23,6,1,30,57,83,73,87,89,118,167,232,233,234,251,249,178,242,146,38,10,9,41,100,133,152,135,144,124,142,92,34,52,67,96,61,85,111,58,78,94,56,43,74,73,22,34,38,41,62,76,94,81,63,72,83,57,49,41,39,29,28,50,37,41,18,30,21,38,37,14,17,41,21,21,53,64,103,126,106,102,139,108,104,101,105,87,119,105,101,63,29,42,76,86,82,103,134,179,96,20,33,45,19,5,21,26,28,18,36,34,58,74,87,82,81,87,78,79,63,53,99,117,109,123,112,69,73,92,96,61,80,68,52,69,69,76,106,81,70,53,53,56,79,80,70,49,97,51,71,121,77,79,91,77,47,60,53,41,24,24,8,24,28,27,12,17,24,49,3,29,39,13,12,25,13,19,53,32,38,30,27,50,28,21,26,52,28,33,33,27,23,20,30,54,32,23,33,16,34,51,18,22,15,32,11,44,41,19,12,18,8,2,33,48,47,39,19,16,37,45,15,20,22,15,26,38,36,26,33,29,33,26,6,27,21,18,21,19,11,21,36,11,25,15,12,24,26,20,32,1,18,34,7,30,37,112,56,21,36,9,13,38,20,28,15,18,14,20,36,25,16,32,14,27,39,14,6,27,48,29,17,29,17,37,2,35,13,28,37,19,24,17,37,7,12,38,20,8,7,23,6,22,37,21,22,17,30,17,31,32,20,41,18,27,16,37,28,19,28,39,52,47,36,57,13,56,32,48,14,22,36,42,39,14,62,238,245,252,240,224,243,234,248,242,247,246,225,242,245,228,210,129,18,2,3,12,18,30,36,50,51,77,48,52,57,24,96,165,232,232,249,250,243,195,234,232,201,198,215,220,230,198,229,202,235,227,235,215,250,219,230,225,221,218,224,221,235,215,186,183,178,142,169,92,12,0,23,10,26,8,42,6,11,1,26,14,24,9,22,10,9,19,22,15,27,21,19,20,176,129,125,144,166,143,140,95,86,78,53,88,107,198,180,50,38,19,13,53,58,33,18,4,14,23,66,53,97,179,178,167,165,167,175,165,98,114,157,194,136,116,107,74,79,139,97,120,83,100,99,69,101,96,84,79,115,168,236,83,41,99,124,182,205,239,255,254,238,186,154,150,168,131,101,80,84,145,107,72,57,66,61,48,90,101,68,68,133,152,97,100,78,84,92,94,100,99,102,72,90,86,58,80,114,78,97,110,107,98,81,85,64,45,96,141,136,106,61,75,37,102,149,196,159,115,169,207,197,202,243,235,249,236,239,245,254,249,239,248,246,250,255,236,254,246,241,240,252,254,250,247,252,253,241,253,244,255,248,239,235,252,189,192,239,24,24,13,41,54,38,112,25,28,91,27,60,47,6,43,81,52,55,44,49,84,111,117,91,59,80,62,76,91,84,111,102,131,94,113,122,127,116,96,86,90,83,57,94,119,94,92,92,62,78,86,104,83,94,105,54,59,50,80,87,54,40,56,32,51,88,47,56,53,120,111,100,124,61,71,78,84,81,44,59,50,52,50,0,60,62,59,40,124,135,110,114,109,141,120,90,111,130,98,134,97,89,95,107,116,115,76,70,31,59,63,41,67,26,13,34,15,25,16,18,17,10,8,16,31,81,124,139,186,206,230,252,251,234,253,247,244,229,245,232,241,250,230,252,124,54,14,105,114,140,177,128,101,98,100,113,107,117,117,138,142,173,154,163,146,159,153,141,122,136,79,46,35,94,70,71,77,60,104,89,72,52,57,77,34,18,29,26,43,46,33,34,47,12,53,21,32,34,14,69,37,80,76,95,91,73,103,72,59,66,75,81,26,41,33,27,38,47,63,85,82,73,76,131,167,158,56,28,4,28,32,6,35,22,50,74,70,87,64,50,88,63,62,57,62,55,80,120,175,160,206,174,147,131,140,153,151,143,144,148,167,156,153,132,141,164,159,165,169,165,167,164,137,157,150,165,148,129,172,157,157,146,130,76,50,22,9,2,16,12,20,40,26,41,15,23,44,27,50,35,35,59,27,74,37,38,40,64,74,70,82,29,45,50,14,38,31,30,38,30,39,26,22,41,25,15,13,16,2,10,5,18,17,36,12,10,25,16,26,14,25,11,18,39,24,32,44,24,25,40,33,37,53,25,32,40,30,29,20,31,33,23,25,10,25,29,13,21,40,15,16,16,55,14,21,11,7,28,16,31,51,37,92,109,68,38,37,27,27,34,12,35,23,11,25,23,38,31,30,47,15,4,20,12,27,17,14,5,18,20,36,17,21,26,29,27,29,13,42,19,32,41,12,19,38,15,10,30,27,20,22,8,43,3,28,32,27,27,14,38,22,10,26,41,22,26,40,32,30,20,18,21,29,47,24,47,48,27,13,20,30,97,234,249,238,255,247,249,245,230,255,238,250,240,236,228,212,208,164,119,82,28,13,27,30,45,48,44,100,82,74,100,73,96,131,129,205,182,194,198,177,175,153,170,167,163,173,186,178,191,195,189,222,207,228,179,215,217,194,171,187,212,234,192,213,208,197,209,197,218,130,6,0,8,12,11,3,11,24,12,22,1,1,8,3,18,7,1,28,9,39,22,37,0,24,154,82,66,96,137,142,126,103,125,109,98,96,129,172,184,39,46,61,17,13,36,43,30,33,37,56,50,53,70,72,54,70,88,79,94,79,40,50,97,85,38,33,42,20,62,59,63,81,71,61,88,55,48,46,50,70,28,139,227,79,41,73,163,206,235,233,228,175,122,45,69,149,198,212,214,169,148,189,161,183,118,86,92,128,86,94,70,55,44,61,54,85,78,74,62,68,90,84,117,103,87,95,88,80,57,85,94,102,89,98,63,77,59,43,81,72,90,63,61,47,62,71,106,136,79,5,19,9,27,16,43,34,54,96,157,123,76,102,107,102,107,95,124,90,67,85,62,61,84,89,37,49,75,50,53,59,104,157,83,116,45,45,2,139,189,28,29,37,39,7,111,214,53,10,28,18,16,32,21,25,63,46,86,73,67,116,106,118,69,37,100,44,26,61,81,81,100,141,125,132,91,92,112,127,115,104,107,92,87,122,110,105,64,81,59,30,58,75,55,80,42,55,50,53,64,45,48,49,16,56,82,44,10,65,83,112,120,111,52,82,87,74,91,65,110,126,130,115,86,120,89,76,78,136,132,56,43,22,100,67,41,32,58,74,77,108,64,70,44,70,66,68,66,31,41,22,17,40,31,25,39,18,39,143,119,163,154,243,253,246,237,255,252,255,244,254,249,255,249,240,245,246,225,211,142,172,103,68,94,41,87,140,124,150,148,109,106,107,115,113,120,92,81,99,122,142,138,138,118,129,136,156,130,137,151,71,20,12,52,88,91,103,56,63,53,98,105,83,99,106,75,49,53,54,10,32,36,41,31,43,38,44,46,60,35,37,50,92,66,46,61,70,69,101,69,88,54,52,31,14,39,40,35,54,96,118,72,85,71,138,191,116,46,15,8,23,10,28,24,67,72,67,97,98,91,58,71,73,60,86,82,54,72,101,96,159,113,126,102,112,114,114,144,126,126,110,136,134,102,123,124,133,121,143,122,140,119,106,127,93,138,94,121,110,104,96,94,104,51,47,10,8,18,6,9,15,13,41,9,21,27,42,63,48,57,73,59,91,69,56,80,98,109,132,164,131,78,68,53,44,73,42,54,30,57,43,20,54,28,28,42,31,46,16,28,21,14,14,41,25,37,30,52,33,27,17,9,22,39,29,22,12,30,34,23,26,29,32,13,36,20,20,30,14,15,41,4,9,38,34,37,28,32,26,14,37,41,3,34,31,27,5,35,20,26,23,26,63,101,89,43,27,16,26,40,26,21,21,46,33,36,37,6,4,32,27,26,42,21,24,42,33,43,25,24,23,9,17,25,25,29,28,32,33,5,57,23,20,29,8,22,44,28,48,39,19,27,55,37,6,29,32,17,3,22,49,7,56,32,17,36,21,28,27,37,25,21,9,35,13,24,45,29,30,42,4,115,230,169,213,226,239,255,249,245,226,253,215,241,248,237,212,233,239,244,224,196,162,117,29,66,38,54,54,72,49,43,30,27,47,74,103,136,150,161,156,138,176,161,168,176,152,177,167,170,177,178,175,195,166,172,194,177,158,176,180,177,181,170,153,172,173,183,197,153,138,17,4,17,3,7,27,17,37,2,35,11,7,13,7,24,11,19,7,11,2,14,15,38,8,123,107,38,64,84,71,103,150,177,164,176,147,179,185,192,138,188,131,108,134,96,144,84,100,64,49,72,81,95,88,77,81,98,90,108,118,74,36,54,15,20,10,51,51,49,63,34,60,66,73,87,69,84,71,67,78,87,114,199,107,77,143,113,159,178,131,89,52,34,46,92,142,207,247,239,249,248,237,227,250,219,100,83,130,98,92,83,69,65,59,39,58,77,89,69,77,90,80,65,88,53,85,92,106,102,86,106,74,87,94,130,128,91,37,73,60,98,80,99,85,70,43,54,62,64,41,76,9,18,24,28,18,22,19,89,94,13,14,25,32,26,35,47,36,35,32,42,6,64,79,44,39,24,14,25,26,65,153,75,26,24,22,6,150,245,28,35,39,43,39,149,246,92,44,99,45,64,52,43,41,97,70,112,101,113,101,71,75,47,61,47,49,39,5,48,64,90,93,113,106,115,102,121,102,100,130,77,88,67,73,139,114,71,79,77,63,23,85,73,29,52,50,85,47,31,17,52,57,74,49,85,43,73,78,143,182,155,104,93,113,102,119,139,146,162,168,203,178,191,211,181,161,113,125,122,14,60,10,14,48,14,23,19,16,23,32,38,6,9,11,35,39,70,68,116,138,149,195,236,247,240,242,230,253,234,243,221,247,250,255,239,246,236,234,226,221,161,153,129,98,102,84,31,17,16,23,21,7,54,66,143,156,146,133,101,104,97,127,121,143,74,118,95,123,97,97,129,93,121,109,108,103,123,127,78,22,17,11,73,95,108,103,65,94,89,111,94,102,101,132,105,49,36,32,42,20,36,32,15,29,29,36,24,23,25,36,23,63,40,63,40,74,83,82,74,64,64,43,53,35,33,42,27,68,84,89,80,69,71,43,140,165,89,10,14,40,45,48,76,68,65,77,99,89,73,64,92,67,48,83,98,59,76,57,32,52,20,33,20,47,16,33,21,26,34,7,53,49,36,39,26,21,13,27,6,29,30,44,20,49,32,10,39,31,8,24,39,53,30,7,40,30,25,16,21,23,32,15,34,26,4,13,3,10,13,57,22,13,6,61,36,35,42,85,143,112,89,20,40,62,42,57,36,29,23,41,23,24,14,36,16,4,9,36,24,19,24,13,41,29,15,16,9,28,33,7,23,26,18,46,46,39,26,12,20,30,22,12,29,35,40,23,16,14,30,29,9,21,37,17,46,11,34,3,38,20,16,14,39,21,26,8,34,32,26,16,27,17,60,90,93,36,40,26,31,6,29,32,38,35,35,22,28,31,51,24,27,41,26,19,51,32,41,33,9,25,28,13,39,31,29,43,32,41,19,29,18,47,35,35,15,28,17,13,13,9,15,19,31,25,23,60,39,50,37,41,41,25,40,41,28,52,41,57,10,46,31,38,36,21,39,31,42,41,36,23,71,95,96,106,164,203,234,232,213,198,197,213,203,220,210,172,206,241,255,240,249,211,209,156,97,88,63,45,36,44,49,33,27,20,19,35,46,79,105,129,174,177,201,172,179,189,195,199,192,205,203,197,171,183,149,180,175,125,177,182,151,156,154,165,134,153,159,169,177,116,15,1,7,18,19,8,7,3,12,17,33,4,11,4,0,27,12,14,11,3,28,9,20,21,153,132,73,78,90,61,108,171,239,229,221,220,235,230,246,230,216,213,194,200,222,207,219,166,105,102,115,115,139,113,147,153,168,82,128,133,111,114,80,80,59,59,69,96,134,87,77,111,97,107,101,105,123,130,167,156,156,173,233,192,194,203,167,197,165,151,107,145,144,110,111,151,210,224,255,239,222,194,244,243,128,117,104,125,72,36,73,81,96,69,42,64,60,92,103,88,46,72,53,95,84,78,100,77,97,104,75,56,85,159,155,206,176,82,57,52,103,113,173,128,106,70,70,130,156,183,177,112,178,203,210,164,154,110,250,250,155,143,182,197,185,200,205,166,191,168,176,181,234,255,185,171,161,152,166,164,200,248,168,143,142,154,192,243,236,42,84,101,134,116,196,241,87,116,123,98,115,102,90,142,132,71,77,135,95,61,38,50,79,43,53,11,13,59,90,117,120,98,79,101,125,122,94,87,80,69,101,116,84,154,136,83,115,158,101,49,60,52,48,70,30,24,71,67,48,27,36,40,77,116,122,145,160,175,179,179,119,90,54,130,144,177,165,163,181,158,190,182,212,198,184,148,123,72,14,12,7,5,16,29,25,7,9,47,23,94,122,122,164,210,226,238,255,248,255,253,227,252,255,250,235,241,251,249,246,247,224,191,190,180,150,115,118,13,29,4,13,29,2,14,33,29,11,10,37,49,18,5,91,119,154,149,124,92,93,100,109,122,103,124,95,100,106,134,127,111,128,127,100,114,120,102,115,126,73,0,20,47,104,97,101,88,88,94,91,96,93,123,89,119,130,93,49,28,12,31,51,7,19,30,33,39,34,38,60,37,58,63,28,73,83,69,61,69,52,73,67,64,29,32,40,49,39,73,71,85,61,44,44,5,37,147,151,49,48,29,63,55,71,74,74,83,97,79,56,72,63,77,77,84,69,63,65,47,31,11,41,16,22,1,17,12,39,38,12,35,33,4,7,22,19,13,9,26,12,18,42,13,17,30,24,41,42,8,40,14,18,29,23,20,8,32,18,32,16,28,63,1,10,27,24,34,35,27,34,21,16,16,30,13,27,39,18,16,72,109,70,53,4,19,8,17,41,33,14,18,28,12,6,17,33,12,10,22,23,16,14,35,21,17,19,8,4,9,33,43,40,15,14,26,32,11,0,16,36,11,14,23,13,9,34,26,28,17,23,25,20,15,16,30,18,34,13,30,12,25,2,24,28,34,28,23,10,23,50,20,10,35,39,60,101,48,33,19,7,20,28,39,19,13,30,15,48,40,49,25,18,27,17,31,31,39,57,33,19,34,43,17,53,37,57,17,49,28,34,18,28,16,31,6,21,17,17,14,19,12,42,22,11,38,51,32,53,47,38,29,36,67,49,26,33,38,22,48,53,51,43,45,34,49,56,39,47,60,45,65,42,66,46,50,62,115,128,138,120,168,153,148,169,153,168,139,169,161,167,232,210,234,226,170,146,157,135,130,107,114,146,125,106,108,88,102,98,85,109,127,153,166,189,167,170,165,153,200,165,193,192,199,188,173,162,164,173,179,172,146,175,145,143,163,178,153,155,175,172,123,23,18,0,2,16,11,20,17,6,14,0,1,2,26,12,4,6,14,13,3,21,30,24,23,232,211,119,165,114,119,132,149,216,219,186,213,224,219,173,156,201,182,132,141,159,196,232,155,110,111,103,128,114,115,162,160,178,164,152,158,146,131,124,137,90,76,121,144,164,191,165,201,152,161,178,183,231,245,238,238,245,248,244,253,245,240,255,247,229,235,253,237,244,255,243,247,241,207,209,202,231,198,216,188,77,91,144,158,85,60,59,56,112,95,69,66,70,55,59,64,38,71,63,97,68,80,90,88,81,79,68,59,99,119,162,160,120,60,71,81,89,95,92,104,94,94,130,157,132,227,183,150,215,227,241,233,188,200,255,241,218,199,223,206,194,239,228,206,227,234,234,223,251,244,207,241,242,241,237,233,176,235,228,191,244,238,194,251,195,56,163,177,171,117,148,251,112,116,132,96,120,82,102,91,137,106,104,142,92,79,83,122,122,105,66,37,104,119,112,86,94,97,140,139,111,95,76,74,26,76,66,120,106,102,133,75,100,146,121,69,29,56,93,85,45,50,47,48,31,46,64,91,147,170,147,138,168,147,166,123,78,38,90,105,108,132,112,141,144,176,164,144,139,123,104,102,128,99,55,43,109,139,170,159,194,224,253,239,252,222,250,238,238,240,253,233,241,253,253,236,233,232,198,181,161,128,84,75,65,61,33,22,6,14,44,29,16,26,25,18,28,33,23,13,44,25,41,28,60,23,34,27,65,87,160,110,73,71,79,97,117,121,148,155,61,77,86,85,81,112,128,99,115,123,137,99,120,103,45,106,123,112,112,92,104,116,70,111,110,76,70,116,99,105,110,56,51,35,34,36,26,44,48,17,42,57,61,63,38,35,67,70,76,58,58,61,77,56,73,65,63,72,19,55,40,20,22,82,72,39,6,21,25,16,47,56,145,152,70,34,67,83,82,67,55,31,79,84,71,65,111,90,66,89,48,51,56,23,8,10,51,12,12,3,56,0,41,4,27,8,23,31,35,16,18,36,25,17,11,36,12,36,46,6,16,6,14,14,26,6,19,16,14,19,25,0,33,9,21,9,25,17,16,1,9,34,14,22,23,18,26,35,23,26,15,35,21,13,80,98,74,48,16,34,8,10,8,8,1,24,38,12,10,3,6,27,30,3,35,39,6,17,2,22,11,26,25,21,16,19,6,23,29,32,26,14,42,5,10,18,11,35,11,26,34,25,27,0,16,19,18,25,2,38,12,1,32,47,11,16,25,1,5,19,12,9,25,21,30,19,27,38,41,38,85,98,79,29,33,19,32,18,9,13,34,18,14,9,35,4,20,24,3,39,65,39,35,35,19,29,18,20,26,13,13,27,21,22,41,23,23,16,35,70,24,22,26,10,30,7,31,24,37,27,10,37,29,40,38,38,24,35,16,42,41,48,43,48,75,35,15,10,21,44,45,45,69,40,48,58,50,27,47,56,21,26,107,146,176,157,149,159,145,143,167,164,123,130,177,179,179,200,173,176,166,216,206,193,208,226,190,217,203,204,212,190,172,182,200,184,173,155,192,136,158,144,127,155,166,178,195,197,209,187,161,174,169,174,169,165,175,158,144,168,177,173,179,165,206,118,15,0,28,2,5,24,14,22,3,38,19,16,0,2,9,14,12,13,32,7,5,14,34,13,253,229,208,220,238,194,169,137,217,198,199,237,243,196,188,165,219,168,139,114,95,201,226,164,110,110,142,141,113,144,127,150,204,200,152,162,161,187,155,155,134,112,155,158,227,205,182,229,228,211,241,248,247,216,243,250,250,255,245,254,241,253,245,248,245,235,246,244,255,253,241,241,228,221,247,230,236,171,238,216,34,108,130,141,119,85,68,76,111,92,80,87,110,59,48,81,77,69,74,101,104,120,102,52,89,67,94,76,42,93,56,69,67,67,52,67,108,53,74,86,90,138,134,104,61,170,135,61,77,78,113,116,158,170,222,241,149,202,163,95,82,146,131,74,128,162,164,224,237,183,131,134,163,244,206,155,120,179,220,201,199,136,100,202,126,50,121,80,116,56,108,150,79,102,71,74,72,70,58,48,106,111,156,139,107,114,116,121,94,100,81,84,124,127,94,65,138,159,136,122,65,58,63,50,28,13,41,81,97,71,77,40,79,105,62,68,58,20,57,67,74,37,44,60,34,59,120,127,141,192,143,173,155,131,139,106,71,74,96,98,83,99,108,129,130,150,170,156,168,146,190,196,244,239,249,246,249,249,255,249,244,255,249,253,240,227,232,229,248,234,212,166,130,89,109,63,44,22,1,19,13,12,4,8,38,32,8,18,14,39,43,49,56,39,31,48,54,36,50,50,20,102,132,48,61,74,22,22,25,54,105,86,78,64,87,107,140,118,156,146,86,78,107,110,97,131,153,113,111,133,125,119,107,91,128,110,123,93,98,99,128,103,101,104,124,129,94,131,114,42,57,30,7,31,39,45,31,30,26,38,27,55,53,54,34,41,62,60,64,64,70,66,97,74,85,91,84,23,49,41,28,25,50,49,69,8,32,19,34,9,26,37,107,116,140,85,47,79,65,72,76,76,66,63,98,75,101,65,84,65,39,47,28,18,21,42,14,18,29,11,17,45,29,30,18,17,15,26,16,23,20,24,28,13,38,10,18,8,21,14,21,27,18,14,25,21,18,11,3,22,23,14,53,39,18,30,4,24,44,31,15,38,28,28,29,22,15,26,8,6,27,22,26,23,46,95,89,22,8,16,11,14,3,3,26,39,4,12,25,35,17,15,24,32,29,18,34,17,15,23,24,23,3,23,23,37,19,8,11,10,23,18,31,19,12,11,10,15,9,30,13,7,22,14,20,9,34,31,22,31,38,18,13,4,43,41,41,8,24,23,7,25,22,8,38,8,21,12,14,13,49,79,79,67,36,20,40,15,22,22,4,50,31,11,14,39,12,16,20,27,44,33,34,6,23,24,22,34,17,29,16,27,6,23,43,20,10,17,15,25,9,27,12,21,5,4,34,37,34,26,28,22,14,25,20,11,11,12,20,20,13,13,18,10,30,27,19,14,29,30,43,16,42,25,32,39,23,42,38,21,27,30,104,203,170,205,206,211,181,176,182,178,183,155,167,167,171,157,165,161,183,177,171,211,230,202,197,204,209,216,206,218,215,214,229,216,193,207,190,181,188,182,170,174,183,164,172,190,191,185,199,175,199,176,150,163,186,159,196,182,196,190,161,205,206,97,22,21,10,37,21,10,13,22,8,32,37,12,0,5,31,23,4,20,15,8,22,24,16,9,245,231,227,250,249,236,220,187,215,242,251,236,248,241,249,246,231,247,247,252,181,235,241,185,183,206,174,182,140,114,117,135,193,149,157,182,179,148,145,138,166,187,198,160,162,138,136,218,167,176,238,236,228,213,217,182,228,251,247,239,251,255,253,254,233,242,252,236,250,244,219,184,154,179,203,235,219,179,232,189,61,83,96,84,100,100,148,104,148,83,80,58,80,61,81,115,88,98,68,88,86,123,99,71,68,82,92,74,52,85,77,64,70,82,43,58,115,78,82,103,116,145,164,100,70,145,101,102,114,84,64,72,120,113,200,252,213,210,193,119,46,131,164,105,142,153,152,202,249,183,178,143,206,230,209,197,174,223,245,222,217,192,124,199,122,88,87,84,86,72,100,98,69,93,69,98,109,99,105,88,146,107,81,107,92,113,124,110,80,39,86,61,63,102,83,161,145,127,110,104,48,101,103,73,58,24,22,58,58,44,71,24,42,50,32,29,50,66,42,67,81,90,71,40,29,38,99,146,154,124,103,145,113,114,123,135,138,118,151,146,182,159,214,253,239,243,243,249,254,249,243,255,231,245,243,252,254,231,245,251,217,207,167,148,152,101,61,46,17,102,130,38,1,2,2,11,19,18,25,39,37,17,33,62,41,61,68,54,74,40,55,76,123,84,30,33,42,56,60,89,127,143,172,88,21,88,49,56,29,28,61,46,116,106,140,156,131,135,177,122,79,82,101,131,92,132,126,111,103,121,128,107,111,100,105,89,61,90,123,96,106,89,107,112,115,107,124,77,43,19,30,48,41,48,39,18,41,31,41,15,38,24,26,54,61,72,62,64,60,71,45,54,68,72,42,68,64,46,32,51,14,34,32,52,50,33,34,73,49,81,64,76,105,96,154,144,49,30,82,83,66,64,75,96,65,115,58,39,69,55,33,62,22,21,35,20,46,31,36,15,37,13,15,20,20,39,29,13,21,24,4,18,15,27,14,26,15,30,22,28,33,23,14,15,7,25,8,13,18,14,21,11,13,1,15,19,1,22,27,4,21,25,31,26,30,10,26,33,25,17,11,5,35,16,47,88,79,49,22,29,4,5,12,17,21,37,33,0,13,41,11,22,10,22,4,32,40,19,20,15,12,27,25,19,12,18,20,30,27,15,18,30,20,9,25,5,22,19,13,18,22,9,23,42,16,34,26,42,24,38,30,37,20,35,34,43,16,1,25,19,32,15,6,2,30,8,6,9,20,2,20,49,46,85,63,12,14,17,7,30,8,43,29,39,36,26,37,6,26,35,25,28,19,12,18,29,16,11,21,8,0,22,9,35,16,12,4,5,12,39,13,22,27,45,23,6,25,32,6,25,10,35,12,18,10,6,26,9,16,16,5,30,24,30,29,50,25,9,29,34,21,13,30,15,21,12,30,12,18,28,20,69,184,195,193,177,168,198,183,179,162,166,164,182,178,138,161,134,148,171,219,175,181,164,148,166,154,156,186,197,194,198,172,192,179,198,205,215,194,190,205,213,202,197,191,172,158,192,203,197,217,216,191,199,213,221,213,192,219,230,220,222,199,201,197,127,20,12,5,17,1,3,8,10,11,6,18,15,19,7,7,22,5,17,11,24,34,2,13,4,208,162,150,199,206,211,113,99,127,179,204,244,234,238,243,243,230,251,239,241,129,217,229,122,140,169,120,197,90,108,118,135,169,130,143,182,188,117,52,131,140,192,213,118,134,81,100,170,84,61,112,104,148,95,98,104,146,199,198,182,192,230,255,240,249,255,253,254,243,234,222,136,82,134,139,134,182,191,252,177,45,95,67,82,86,86,143,106,101,108,84,73,81,55,85,90,87,75,60,78,82,121,97,63,55,60,76,68,49,121,96,67,61,78,61,61,53,124,111,100,65,105,93,113,45,134,79,102,120,54,93,75,121,121,171,211,121,160,158,50,47,109,186,116,114,107,103,162,162,137,125,132,161,199,184,212,139,183,241,192,206,191,137,158,139,84,103,82,125,76,122,104,71,92,58,85,94,113,80,122,139,104,135,143,97,88,116,65,42,46,34,26,54,57,89,123,111,81,53,76,65,102,129,97,96,52,49,17,17,65,53,44,69,45,62,61,23,58,33,39,67,74,71,49,46,78,121,141,130,151,154,168,174,184,221,255,249,244,248,239,254,250,252,255,228,248,253,218,226,244,254,235,239,219,201,190,171,136,110,92,43,8,3,11,23,4,7,16,12,65,105,18,12,14,30,33,21,28,26,58,57,45,60,142,77,131,98,57,49,75,38,64,142,136,71,32,56,117,89,82,84,94,97,64,37,48,26,30,16,41,87,78,135,116,121,133,117,136,133,92,62,74,109,100,99,134,81,125,122,124,126,84,85,79,101,133,77,106,102,110,125,101,84,116,119,79,38,30,21,18,72,70,63,72,8,28,6,56,52,30,31,34,50,86,81,91,70,65,76,70,86,95,81,45,94,81,67,68,41,28,30,39,58,55,60,43,73,76,104,104,72,69,71,61,128,171,133,63,45,42,80,96,90,72,54,68,78,40,82,50,43,44,16,22,34,17,30,14,15,15,22,6,46,11,10,49,27,13,10,15,12,28,14,44,26,18,4,12,26,31,20,15,17,29,44,4,16,32,18,22,13,8,19,48,25,13,42,30,13,14,40,9,28,10,25,22,30,20,16,21,7,32,32,54,28,83,112,56,7,25,23,23,14,30,21,32,2,10,11,36,11,47,14,2,14,5,10,3,2,39,28,33,4,8,21,32,17,25,13,5,15,20,5,49,9,30,3,14,37,30,29,17,10,40,15,26,56,54,24,21,31,24,24,24,36,24,30,15,15,60,12,26,21,11,7,22,31,3,3,10,5,26,70,114,88,65,26,17,28,37,6,35,51,27,28,27,5,29,31,30,65,51,50,7,21,47,21,35,4,0,13,43,24,15,22,33,58,14,29,18,20,19,5,21,16,4,11,11,27,41,19,13,49,20,19,12,15,25,5,21,10,51,30,28,17,35,10,10,20,42,32,27,24,23,3,43,8,16,9,15,36,145,188,176,179,134,160,154,145,130,131,152,204,217,200,175,141,162,128,184,213,222,213,194,166,148,145,117,154,132,121,118,142,142,132,145,134,169,142,142,175,164,199,156,137,124,127,144,192,216,215,196,196,192,207,222,209,228,225,206,223,198,198,184,212,126,11,4,5,9,0,24,21,38,7,20,25,20,7,12,9,23,21,6,25,10,13,33,17,23,178,97,46,54,56,86,61,49,82,114,150,227,191,125,184,186,220,210,166,159,61,159,225,90,37,67,105,143,78,58,85,132,129,112,113,142,155,116,91,113,110,119,146,142,98,89,143,181,117,80,53,89,111,64,50,65,119,110,108,155,155,178,254,249,249,222,249,247,243,231,248,142,77,87,64,85,133,155,240,147,38,95,39,82,27,65,82,97,128,106,93,97,53,59,91,110,87,73,96,64,68,78,78,107,34,49,56,69,68,72,95,79,75,59,66,46,82,55,63,61,47,36,61,76,51,84,51,25,63,53,85,80,82,86,65,77,61,27,12,12,16,36,79,40,53,19,45,51,50,24,31,70,70,90,95,136,109,109,156,110,145,144,108,97,55,47,63,62,85,92,47,38,44,61,37,47,52,45,99,122,127,93,104,95,52,66,88,115,95,65,56,31,38,50,64,66,94,89,108,80,39,89,79,96,115,103,97,48,33,7,46,17,17,61,63,76,85,63,72,93,66,100,150,132,191,224,237,251,247,250,255,243,251,247,251,246,243,251,232,247,254,251,230,233,202,222,187,76,40,117,201,177,135,142,170,166,141,77,72,31,25,31,15,28,12,20,6,0,19,69,93,117,57,47,35,58,53,52,47,95,129,83,77,103,84,133,134,60,41,63,40,32,62,71,66,64,38,52,77,53,56,60,93,59,29,74,61,55,16,117,124,150,168,130,134,131,131,140,126,131,103,71,128,120,118,97,95,111,113,113,78,89,96,78,55,112,106,96,89,95,117,94,115,110,72,22,26,39,15,46,65,119,120,24,1,41,12,26,60,6,48,54,73,68,82,70,64,60,70,81,85,66,80,65,90,99,77,88,35,31,41,29,19,33,49,53,61,74,76,95,86,51,88,58,111,149,165,87,44,67,65,111,78,61,76,97,73,70,76,57,76,47,37,20,21,14,28,8,8,26,22,4,21,22,35,29,3,23,37,18,8,25,21,14,5,27,10,37,19,31,33,41,11,9,16,19,28,33,15,7,29,26,13,2,17,11,20,9,28,44,11,21,34,16,26,19,25,18,40,24,10,19,14,16,9,79,115,66,20,31,39,12,8,18,19,25,18,11,34,36,12,3,29,35,19,21,18,14,37,5,42,20,25,23,8,36,26,8,13,21,36,30,36,9,20,11,26,33,28,18,25,21,33,17,15,7,23,23,40,41,13,46,45,10,35,16,21,12,8,9,30,16,16,33,23,8,7,44,5,18,33,13,54,48,77,75,37,36,24,12,17,26,17,15,32,19,10,24,30,45,20,28,16,23,10,14,37,10,30,25,7,35,8,36,14,32,18,6,20,13,21,18,17,13,26,41,15,46,11,21,13,34,28,25,15,22,32,17,8,16,2,9,14,14,3,8,20,16,35,12,5,20,17,32,17,10,27,20,24,44,86,155,124,176,129,122,122,135,124,143,169,210,254,247,243,229,248,196,180,224,250,243,250,249,220,190,126,79,76,74,128,128,90,110,103,100,125,133,91,95,114,98,93,77,74,89,60,65,110,129,157,153,143,147,151,132,164,155,165,168,165,172,165,139,166,95,22,10,10,0,19,15,11,22,27,20,13,11,15,19,18,11,13,18,24,11,30,4,4,42,230,147,92,104,118,82,135,130,171,192,197,225,207,150,216,180,210,195,157,158,84,179,213,50,59,55,105,144,76,73,80,85,95,45,88,106,141,137,124,106,76,106,194,165,144,106,167,237,157,84,80,115,139,87,142,93,59,44,64,157,177,234,244,248,235,255,235,252,250,250,254,127,72,124,121,98,48,101,159,29,28,62,84,82,44,57,53,55,116,114,119,113,96,82,77,100,99,86,90,103,81,39,37,54,57,43,74,74,57,68,102,87,73,71,81,64,83,93,53,68,90,71,94,151,129,188,163,42,59,102,110,88,75,75,57,79,89,131,172,139,201,176,214,161,133,111,142,171,128,112,71,47,73,64,44,78,61,57,74,96,75,95,85,71,20,60,45,37,52,41,31,62,42,52,26,53,17,40,128,125,129,91,73,66,45,87,90,131,94,57,50,33,61,37,37,50,112,104,78,49,14,20,56,66,49,55,74,31,13,11,17,22,77,108,182,178,209,223,255,223,249,255,243,249,245,239,253,247,240,254,243,239,242,243,240,231,213,213,208,200,187,178,164,172,174,168,107,8,0,37,151,154,82,50,61,66,58,30,35,35,24,57,96,102,102,147,110,39,64,120,122,154,114,38,93,78,35,65,35,68,115,69,35,50,50,95,85,68,42,51,43,65,40,68,70,67,11,34,78,53,113,99,135,100,24,88,84,47,84,167,186,156,150,139,131,141,106,84,129,151,117,115,137,94,91,97,146,121,94,86,66,73,53,72,76,79,77,118,101,123,122,105,69,44,12,11,53,27,41,94,102,84,84,47,13,15,38,68,47,55,35,73,92,78,69,88,89,69,86,72,80,89,87,67,103,45,40,38,50,35,28,15,27,62,77,50,67,69,80,81,75,68,50,64,52,74,145,185,103,40,75,61,90,61,72,52,80,68,70,43,23,29,7,20,18,11,24,3,30,27,25,23,22,13,12,15,12,34,12,6,27,19,28,10,28,31,30,20,6,25,42,17,23,15,10,9,10,12,17,24,8,30,20,13,14,11,23,50,21,33,4,33,26,34,20,18,23,37,26,7,27,39,16,20,0,57,93,65,23,19,17,11,31,4,20,19,37,25,18,31,19,32,15,21,21,26,29,36,11,11,25,21,35,16,22,12,14,23,10,24,24,9,27,20,31,21,8,22,16,22,38,15,38,26,34,26,32,24,23,38,38,23,14,12,40,26,26,24,10,10,20,13,4,12,15,45,22,5,38,32,7,27,11,37,64,96,74,49,24,25,13,13,11,24,9,41,24,42,16,18,46,43,24,31,17,25,36,20,5,17,46,25,31,41,1,33,21,13,18,35,13,33,41,29,11,31,5,10,10,19,32,20,5,3,41,8,27,25,10,47,22,28,23,4,16,13,22,18,21,27,46,15,14,52,4,44,26,25,24,25,33,93,118,96,105,81,110,113,121,150,161,210,194,222,241,226,221,192,164,218,239,235,230,224,208,178,96,66,57,84,130,153,126,118,124,144,172,139,121,88,38,36,23,18,63,50,30,41,40,43,52,49,42,27,39,27,34,57,85,55,144,152,196,167,134,90,26,0,16,0,25,26,23,28,0,46,43,20,19,5,34,23,23,9,6,28,5,17,15,24,219,188,100,162,153,149,163,180,182,230,199,249,188,144,192,188,237,208,166,194,103,194,221,76,54,58,93,127,83,47,40,40,40,33,53,73,91,157,116,88,106,167,216,206,167,114,150,246,162,104,74,124,133,150,151,84,27,8,40,135,242,237,241,227,245,223,203,175,168,154,190,102,117,167,138,106,79,102,138,77,65,67,55,95,55,67,65,67,77,75,100,95,98,67,78,68,106,67,137,125,87,58,31,39,25,67,62,72,98,68,89,108,79,74,59,63,121,112,54,89,138,65,158,164,211,253,229,171,133,147,143,68,73,69,144,237,237,247,247,238,241,250,228,248,250,250,255,246,252,238,249,207,166,71,41,45,4,47,34,27,41,25,27,37,35,49,32,57,42,25,27,31,58,37,27,46,29,29,118,129,91,74,108,35,58,86,58,59,35,41,23,19,29,9,65,34,36,41,37,40,39,86,83,91,116,100,148,169,203,222,235,255,246,243,254,252,242,226,242,243,242,238,216,248,250,230,237,222,208,180,164,173,153,134,126,172,184,147,140,160,176,140,128,116,88,108,46,2,28,10,74,62,63,52,77,92,68,97,128,145,136,165,152,201,238,225,222,95,57,83,133,124,43,45,49,91,55,57,40,51,66,55,86,32,34,41,75,105,30,60,94,105,107,97,97,109,45,63,30,74,100,94,126,98,40,90,56,18,85,154,178,146,145,131,150,150,78,46,83,128,89,115,115,120,106,87,74,69,35,85,89,79,81,100,55,82,88,108,102,71,60,22,26,25,34,10,57,90,96,103,42,47,40,32,12,0,30,25,60,54,63,64,74,93,62,95,76,98,87,82,84,75,66,44,26,33,32,14,32,11,15,44,56,77,64,71,68,80,85,88,93,81,54,90,68,48,101,157,173,99,25,49,44,67,71,78,59,79,100,74,39,47,13,29,30,7,28,26,17,25,30,36,25,13,14,22,24,21,44,9,20,10,28,20,4,33,0,9,14,14,33,19,13,16,31,24,40,23,27,19,11,23,46,9,41,30,29,25,26,28,20,15,34,13,23,34,30,7,27,26,21,34,25,45,21,37,86,94,66,7,20,6,11,41,26,25,17,22,5,19,17,7,15,23,21,18,52,26,18,16,48,34,16,19,28,30,42,25,17,9,41,38,16,30,26,30,15,25,24,9,13,39,22,40,26,28,31,33,37,21,34,24,35,20,55,13,9,31,21,15,25,26,27,7,26,41,32,40,36,16,18,17,21,37,19,75,91,51,42,23,20,25,36,25,7,23,31,38,4,26,43,46,13,24,34,13,9,20,43,41,25,35,33,12,25,21,9,39,30,5,9,10,30,40,36,19,7,28,12,28,19,14,16,11,59,6,25,18,11,19,13,20,37,8,14,34,31,37,14,47,18,31,38,11,42,13,17,46,12,9,17,60,56,40,77,68,47,47,29,89,82,69,77,74,69,94,97,90,71,99,146,106,117,121,131,97,45,45,66,103,152,160,127,129,109,112,117,117,137,106,60,15,39,38,50,52,61,51,22,57,11,11,19,25,29,29,10,30,33,20,119,228,217,220,149,68,11,22,30,10,9,8,39,17,8,29,15,7,16,17,32,11,8,21,32,3,0,13,24,7,237,131,108,95,76,114,140,189,194,231,243,250,199,174,204,213,244,246,228,191,95,236,211,80,85,48,78,139,52,46,25,53,14,9,22,37,102,148,142,88,88,127,185,177,77,81,125,195,110,33,55,88,128,146,157,129,54,53,39,101,185,199,206,228,196,224,165,88,36,43,110,88,142,151,107,83,56,172,225,109,60,66,86,95,58,76,60,51,64,92,134,102,73,90,92,128,138,90,108,145,89,94,69,31,42,37,53,71,107,70,84,89,48,75,67,48,106,105,130,124,122,73,130,124,173,234,244,224,72,104,124,83,77,103,135,178,246,239,242,219,231,241,236,245,247,243,225,219,189,249,246,206,133,54,10,24,8,29,44,54,40,17,39,55,35,25,27,40,36,33,43,33,43,57,45,49,25,11,48,50,58,73,98,114,35,18,22,11,23,12,21,7,20,24,24,36,152,121,157,175,210,241,233,228,240,237,255,248,255,242,236,241,251,253,243,236,226,218,194,154,149,122,115,81,49,89,147,141,150,138,116,117,114,84,56,126,91,95,86,37,56,40,70,54,39,94,52,10,12,8,120,118,203,187,207,173,168,187,229,192,174,205,183,168,136,175,154,43,17,25,46,53,50,21,36,53,53,33,23,37,75,49,71,41,39,9,86,158,77,54,77,105,152,101,103,67,82,66,48,27,44,27,45,61,32,42,53,16,100,144,167,145,152,135,150,142,87,40,117,138,101,137,129,100,75,74,65,82,58,53,32,70,53,102,105,96,95,118,68,56,21,7,10,32,54,24,40,60,76,69,21,45,5,53,34,7,50,51,44,79,62,65,78,103,80,71,90,88,71,73,68,91,64,18,27,30,2,13,34,36,25,71,62,74,80,93,94,101,55,86,68,76,49,83,91,73,70,113,165,131,94,60,39,42,56,94,82,113,90,59,49,7,12,26,13,10,12,27,28,16,30,27,11,37,22,1,32,15,10,20,44,15,2,19,9,31,21,13,19,8,6,22,41,26,14,24,13,23,28,22,34,12,11,34,28,29,8,23,19,9,9,29,15,17,22,8,10,35,10,14,10,23,43,20,23,26,87,84,39,37,12,7,21,37,43,0,20,30,9,15,25,41,25,23,28,2,32,16,19,26,9,23,2,19,31,22,34,36,18,18,3,33,42,15,23,29,11,25,16,15,21,30,28,35,17,32,35,13,15,36,43,37,46,44,28,37,23,18,26,17,18,33,29,25,28,15,11,18,23,22,51,30,18,14,18,39,74,92,58,25,3,14,51,11,24,39,25,28,13,50,81,53,17,48,8,32,19,35,25,6,42,44,25,13,12,12,18,23,22,11,4,34,30,13,5,7,22,5,30,25,24,44,25,36,29,30,15,21,40,28,12,5,19,24,16,35,44,14,32,25,25,27,35,10,29,34,32,30,34,25,32,55,34,79,51,52,59,58,33,31,8,15,33,33,6,24,63,39,10,26,54,21,28,33,69,50,71,67,63,85,112,99,79,72,42,68,70,65,78,72,50,48,20,26,69,72,34,52,45,35,45,36,56,103,138,156,126,92,53,15,189,229,228,222,153,66,4,27,18,40,24,6,33,4,25,0,19,36,1,22,18,16,17,9,10,6,23,24,23,18,225,165,91,91,48,69,121,141,202,192,197,246,199,186,225,210,240,240,193,109,95,224,203,87,62,64,70,138,81,83,67,72,81,29,56,60,77,119,121,82,60,51,63,58,17,29,32,25,14,54,23,41,63,86,113,120,131,115,117,155,189,158,147,173,138,126,163,118,50,50,42,70,124,83,70,71,95,146,217,87,35,70,78,87,96,79,88,76,79,88,106,99,75,55,95,153,158,114,132,140,128,146,116,98,64,72,78,93,111,110,68,106,85,58,88,93,125,105,94,114,112,65,86,74,117,192,227,146,2,90,95,142,163,155,147,101,42,142,181,184,130,168,253,250,255,240,215,218,196,148,149,130,87,31,32,16,13,25,37,63,43,35,60,54,41,32,40,51,48,23,49,30,84,126,94,33,11,19,6,22,59,74,102,80,44,39,36,36,63,128,159,187,205,231,245,252,248,236,253,254,236,243,231,255,243,249,243,227,233,197,186,208,157,134,154,97,128,108,29,1,7,26,84,68,43,53,92,101,85,91,42,33,44,33,16,15,25,34,22,63,77,122,176,117,122,193,121,61,52,34,148,232,226,239,200,169,141,102,128,86,94,90,37,67,40,74,96,81,118,106,123,126,135,129,99,125,45,24,55,58,96,65,66,70,50,31,48,124,79,29,26,80,83,80,54,67,52,83,36,70,41,69,90,102,17,32,85,51,131,129,152,160,142,148,126,137,81,65,124,106,86,114,97,109,63,54,41,56,94,59,89,89,97,71,103,100,58,32,25,26,16,25,31,49,62,76,55,28,80,111,68,8,24,22,68,58,45,46,19,39,49,64,66,64,81,68,65,59,93,80,66,28,20,9,19,5,7,46,53,85,104,89,107,100,85,82,107,71,92,60,91,57,85,78,86,80,47,72,103,171,187,102,52,5,78,51,88,63,74,50,44,40,36,17,3,16,11,24,8,36,32,22,34,37,47,14,22,32,5,33,13,37,20,21,30,32,17,18,43,16,4,17,8,32,54,29,19,23,12,12,30,26,6,35,25,24,1,9,7,25,33,29,4,32,50,15,26,18,34,5,31,16,22,32,5,32,57,96,59,25,7,13,18,8,20,10,26,16,23,26,45,39,10,25,24,39,10,16,27,14,16,33,15,36,14,36,27,25,42,29,16,23,25,7,8,35,24,20,23,23,31,35,5,23,33,39,14,37,4,24,33,44,43,16,28,39,19,24,18,7,3,48,21,3,8,33,20,5,19,31,33,15,41,18,20,12,47,74,90,58,12,8,35,18,36,30,9,46,56,28,36,18,8,55,36,3,18,34,50,12,19,29,25,26,30,42,41,18,18,25,7,13,56,7,51,25,9,30,24,22,21,5,4,24,11,26,33,27,21,21,39,12,27,11,14,41,8,19,18,34,25,31,8,10,33,23,7,22,12,24,49,58,60,78,39,60,25,14,19,13,34,17,38,37,20,6,82,67,29,50,38,25,24,31,51,26,65,76,49,88,64,28,50,57,11,38,77,35,56,63,50,65,68,111,89,91,94,72,42,34,34,89,135,201,230,222,230,216,129,96,231,230,245,236,177,82,4,3,16,21,10,17,22,20,5,4,33,12,0,0,0,24,32,15,17,24,21,5,9,11,251,221,190,140,68,92,131,161,159,139,160,216,159,113,150,194,227,202,113,98,82,194,179,117,106,77,106,129,113,148,150,152,118,111,112,131,123,119,95,72,77,65,48,79,74,59,64,74,69,86,75,40,71,79,76,88,139,169,199,167,145,112,87,127,89,86,98,126,101,97,55,43,84,72,72,63,65,85,106,35,66,104,99,134,153,114,48,62,73,83,88,72,76,58,68,134,135,99,119,169,123,130,113,131,111,82,79,104,110,106,98,128,64,45,79,112,160,95,63,26,25,63,66,59,40,50,46,8,19,6,24,55,156,103,80,7,24,32,26,22,20,25,71,120,86,106,140,178,145,96,86,124,94,17,34,17,10,27,37,39,33,38,31,25,30,55,46,66,47,39,19,20,88,155,122,114,94,90,95,115,145,154,189,228,224,229,252,250,247,254,254,239,248,255,249,244,239,250,245,237,219,182,157,157,142,109,98,65,41,6,21,3,18,51,82,42,71,89,14,9,53,65,79,14,38,39,49,61,58,65,58,53,64,74,27,40,7,63,109,103,138,163,166,151,131,149,150,61,52,17,94,142,124,109,66,70,66,43,81,77,69,115,101,85,73,100,148,180,172,193,197,174,130,130,154,114,66,74,92,33,75,62,44,74,41,70,21,37,56,75,39,75,77,52,80,60,89,105,118,106,95,105,125,113,61,44,93,46,53,100,140,106,130,113,125,155,95,86,137,115,83,84,76,72,55,53,58,58,101,80,72,68,86,83,54,45,38,50,34,61,40,27,65,78,139,156,118,137,139,122,149,57,69,62,65,63,31,31,52,54,57,71,64,68,64,89,103,101,78,44,28,14,45,19,31,50,49,83,85,102,110,103,98,84,55,81,79,68,70,89,61,73,65,82,88,52,65,59,65,105,175,166,117,55,35,61,83,42,45,44,17,33,16,14,43,17,36,25,27,18,26,23,11,7,17,3,12,21,18,15,22,42,24,41,35,20,30,2,14,44,33,25,9,44,9,31,21,27,21,9,20,30,14,18,17,15,25,20,19,19,9,24,39,12,23,23,25,18,10,38,33,37,3,33,17,17,46,77,92,16,12,4,7,16,49,30,16,19,23,45,53,33,40,25,15,14,39,7,35,17,22,7,49,24,15,18,13,22,31,38,17,31,13,27,36,11,14,13,11,17,9,49,25,34,26,23,39,11,23,33,31,44,58,37,32,41,23,10,41,22,18,26,29,18,44,31,10,31,25,18,22,35,31,12,10,28,32,44,84,105,52,14,17,12,23,1,14,23,25,37,53,22,18,27,34,52,19,18,18,14,43,8,25,23,33,3,17,26,11,14,45,1,21,11,17,20,10,32,8,4,27,35,22,21,23,35,35,14,13,37,6,47,2,23,19,19,47,32,29,4,20,36,29,21,40,16,25,14,7,7,32,37,63,64,42,31,21,11,21,30,59,20,15,19,11,15,66,76,55,75,27,25,32,39,31,61,31,84,73,69,50,66,51,61,29,56,53,49,85,93,73,96,148,216,212,238,209,208,189,168,152,173,187,240,207,225,202,183,172,149,239,240,247,222,179,132,22,11,34,5,27,15,0,32,9,8,8,38,26,9,2,29,9,5,5,14,19,42,10,38,254,240,246,234,147,130,145,170,171,112,125,165,152,105,146,160,151,132,127,131,146,151,152,123,133,133,145,138,122,171,166,161,191,211,235,235,212,216,190,227,196,205,185,185,198,193,229,230,224,214,201,212,199,194,193,197,207,206,204,191,161,162,176,189,129,73,51,82,80,87,39,50,88,58,79,91,82,112,145,95,86,121,141,146,135,120,148,100,40,54,58,63,78,64,59,121,86,103,123,131,100,102,130,153,133,111,110,89,96,79,43,72,42,46,35,49,115,26,52,44,57,90,38,102,63,53,19,23,22,40,32,21,43,25,41,28,52,14,18,37,15,19,31,23,30,53,74,67,47,62,56,126,73,12,22,9,29,17,9,38,16,12,20,28,40,44,57,78,28,26,31,105,165,227,207,213,241,234,251,240,237,246,226,240,241,242,231,242,236,199,211,219,159,174,125,128,84,108,110,72,36,15,8,30,23,32,11,22,33,37,7,8,31,8,31,9,7,19,7,9,24,12,29,67,56,86,86,106,93,101,84,69,70,54,20,13,4,0,20,27,26,53,40,13,30,19,28,32,36,10,31,62,63,45,39,90,144,137,179,148,137,133,99,71,67,58,66,65,90,72,77,77,68,83,57,54,40,70,49,27,55,66,92,30,106,70,11,66,157,64,58,105,130,63,48,41,66,32,64,61,47,37,23,48,78,57,39,47,30,70,113,112,105,121,147,178,93,87,78,66,62,68,94,72,57,66,86,70,103,99,102,79,58,40,24,32,36,26,38,38,64,66,100,143,131,140,156,139,171,132,135,128,84,99,80,74,49,31,35,40,42,66,68,88,67,89,53,47,38,32,37,29,24,29,33,60,64,98,90,101,83,103,114,79,49,74,86,64,91,60,73,53,69,38,72,80,82,70,42,40,104,167,188,144,97,56,28,60,24,6,27,12,23,39,18,44,24,14,25,27,22,37,26,33,36,19,18,31,12,8,50,28,38,29,3,11,26,26,17,34,19,33,32,9,17,24,15,35,35,42,27,34,25,15,14,43,24,26,10,31,23,30,18,13,22,22,15,14,18,15,40,1,12,9,32,28,25,79,99,32,6,23,3,23,10,25,16,13,23,13,34,16,17,24,39,21,25,14,25,4,16,15,41,24,24,19,11,27,0,40,4,28,11,17,16,40,28,17,20,4,12,29,54,21,27,18,39,24,46,32,41,35,33,24,40,18,36,14,12,27,18,14,4,18,32,10,25,29,24,22,36,27,26,19,25,41,40,34,63,88,64,41,7,15,24,3,18,31,42,48,36,35,12,16,6,26,21,26,36,28,21,41,18,31,28,5,5,31,21,25,14,17,5,9,18,23,26,32,28,44,16,14,23,22,13,26,13,16,9,17,0,9,29,12,39,25,38,47,33,44,20,29,14,25,26,16,50,31,29,24,65,65,101,96,97,121,132,167,167,180,169,200,169,170,139,163,195,183,161,165,112,92,125,131,136,69,88,91,78,93,80,67,63,42,35,45,57,61,47,68,48,131,165,218,241,246,243,248,243,225,225,214,234,240,224,185,148,144,139,133,215,238,242,231,219,95,17,9,8,14,36,11,16,20,19,11,14,26,16,0,8,26,3,31,17,11,9,14,10,23,250,252,240,247,165,132,130,153,141,133,137,157,125,169,173,138,130,134,104,160,142,173,191,165,193,192,214,181,180,224,225,233,232,241,254,239,232,251,239,255,235,250,230,251,251,253,245,255,249,234,244,249,246,254,255,249,246,246,243,252,246,253,233,246,254,108,100,59,86,113,74,122,114,141,157,188,134,205,216,111,121,208,201,207,188,180,126,104,60,63,44,65,80,52,64,88,87,125,135,163,113,93,122,151,183,126,111,80,43,45,67,137,87,72,59,53,73,63,131,116,164,196,171,226,251,245,243,220,235,213,235,226,232,215,214,247,240,240,239,227,230,207,230,145,177,165,180,208,180,203,181,219,190,227,229,216,240,230,229,222,232,223,137,234,218,142,248,250,240,247,244,225,247,246,253,241,243,248,252,246,238,231,244,193,180,184,182,183,151,38,79,126,144,125,108,72,63,24,23,34,3,12,6,15,21,42,50,66,55,64,77,81,91,129,72,98,78,72,31,1,28,52,92,125,174,101,109,85,71,21,53,18,40,20,39,19,37,41,24,27,49,33,38,33,40,99,98,50,25,22,124,149,129,114,27,69,71,103,110,68,63,53,2,19,32,3,18,8,16,29,8,16,100,42,43,92,41,39,47,35,46,78,161,152,169,88,29,114,140,103,93,84,77,50,47,45,37,37,49,60,32,33,43,45,49,38,75,23,51,80,70,79,89,92,107,141,72,63,98,82,89,94,116,82,57,80,86,107,101,103,72,52,52,25,34,50,28,41,66,75,123,111,116,148,128,150,129,116,105,122,86,75,61,68,71,76,41,23,15,56,41,67,80,90,64,48,19,21,17,20,18,31,50,77,91,92,86,85,92,82,95,86,90,82,94,77,85,124,74,72,57,53,73,74,80,71,65,76,41,58,46,94,187,208,146,46,31,37,16,17,19,52,21,13,10,23,34,30,26,34,26,21,13,29,14,22,23,35,16,26,21,28,13,29,39,6,26,30,18,36,35,7,27,12,29,40,31,17,14,30,16,28,30,28,60,30,37,3,44,29,12,21,28,14,14,10,18,31,35,33,6,38,4,28,34,32,14,87,77,8,15,8,23,11,5,9,40,22,21,22,14,42,32,33,30,29,13,25,18,31,22,11,34,15,5,39,9,15,19,17,19,7,20,3,30,29,12,14,11,14,27,30,24,45,38,34,42,29,23,36,12,40,21,17,22,43,22,21,24,28,12,32,17,20,43,35,30,19,23,32,43,27,15,17,8,31,26,42,38,45,113,86,48,23,23,30,18,64,13,13,48,34,39,18,26,17,29,49,25,22,28,4,12,40,23,13,4,0,31,16,32,0,41,32,18,46,11,9,35,41,18,12,22,10,38,17,39,9,29,10,12,31,32,12,18,14,47,10,32,37,25,36,18,22,8,28,31,12,29,19,43,64,69,100,219,236,242,232,247,247,249,243,229,252,246,243,250,253,254,243,230,220,239,239,229,162,97,125,116,84,86,76,46,56,41,29,73,56,81,57,81,136,185,171,163,237,233,241,240,233,239,249,243,250,205,175,176,168,151,141,227,224,212,246,245,111,0,2,13,34,13,26,16,32,12,25,35,11,8,8,48,6,14,6,18,18,18,14,12,20,203,244,236,235,145,111,159,120,155,115,156,167,152,160,123,165,157,147,159,174,220,246,237,234,249,242,242,243,255,239,252,255,240,255,254,250,252,249,232,252,254,249,255,245,251,245,236,244,241,254,245,255,242,252,255,241,255,252,237,235,254,228,242,253,241,187,126,133,135,150,141,154,183,160,195,227,201,164,158,102,144,226,225,234,216,183,124,78,80,78,56,74,93,83,92,150,128,117,120,165,115,123,90,92,160,124,88,75,83,57,99,188,182,128,150,103,150,92,149,183,195,227,203,240,252,247,211,250,244,252,226,244,248,232,251,239,246,245,237,242,246,234,248,246,236,239,255,246,252,248,243,216,246,243,243,251,254,254,255,242,253,255,255,255,246,252,244,240,242,243,252,251,247,250,240,244,252,239,255,250,253,242,222,253,251,221,234,251,255,67,83,224,238,235,162,136,67,52,99,94,144,186,194,250,238,229,252,254,237,251,253,235,250,238,251,245,236,237,207,78,90,236,225,167,115,50,88,75,53,55,88,134,175,217,242,231,226,250,247,252,240,240,250,218,247,245,250,221,96,22,102,160,108,58,15,4,13,39,42,76,86,114,173,148,178,167,164,159,157,175,133,96,113,117,128,124,50,39,50,51,38,77,131,135,126,60,49,62,80,22,22,47,26,55,53,79,43,84,103,96,103,122,114,108,76,18,75,62,43,73,62,71,79,77,94,97,77,51,60,72,93,81,108,74,71,78,90,128,83,60,13,64,40,52,29,65,53,102,81,97,116,135,120,107,115,120,126,111,78,59,75,59,67,94,76,52,71,61,54,46,37,77,77,23,39,4,49,21,13,19,51,86,93,77,82,81,90,74,76,73,55,93,68,71,78,99,69,72,62,69,61,64,75,79,89,57,70,66,81,51,65,47,87,170,166,58,32,37,11,24,21,5,13,13,30,19,37,29,15,14,13,27,34,46,40,23,35,16,36,19,36,30,19,24,35,21,12,33,8,29,47,37,9,21,22,30,31,22,17,20,38,15,24,23,29,29,16,23,3,28,13,37,27,26,13,38,16,31,29,10,16,11,9,19,5,14,12,28,96,28,21,39,21,22,21,15,43,37,29,24,50,23,44,15,14,19,24,14,15,18,9,30,19,26,7,24,16,20,5,24,26,16,9,23,28,22,26,29,9,25,22,23,34,23,38,22,46,25,29,35,41,20,29,18,45,55,51,35,22,35,17,34,14,2,8,49,35,44,33,16,29,31,12,21,2,28,5,26,42,17,62,85,90,46,22,20,18,11,27,52,45,0,29,9,11,25,11,9,20,0,37,24,14,14,12,21,20,14,45,28,24,23,30,22,20,30,26,21,41,1,2,27,24,22,20,13,18,33,20,10,15,22,19,24,25,8,21,23,28,9,33,3,37,26,24,21,35,11,41,25,22,30,31,109,245,246,248,236,255,252,244,255,247,233,246,247,247,248,230,250,245,250,245,250,224,183,141,134,78,70,20,18,43,65,68,39,66,57,89,75,108,136,97,62,91,135,190,198,191,210,240,233,235,240,228,230,231,223,206,234,248,234,243,233,237,105,7,2,33,16,6,22,21,15,32,9,25,23,26,1,5,11,11,33,16,15,16,19,13,4,142,159,185,168,126,137,136,137,145,148,149,155,175,169,138,152,190,205,229,252,243,236,215,208,210,246,240,240,233,221,206,196,202,205,207,220,206,206,219,205,214,223,160,210,211,221,226,199,211,201,175,179,188,171,190,198,193,211,204,203,191,205,214,204,165,143,141,112,163,164,150,143,146,127,157,151,140,108,80,54,122,132,121,150,127,82,67,9,110,104,121,46,80,82,122,114,119,73,80,74,128,98,26,54,93,81,87,55,46,81,50,173,135,91,118,83,130,127,109,127,142,122,143,219,242,226,219,150,233,179,158,208,222,185,242,236,233,249,231,238,252,236,254,243,252,248,245,253,252,242,255,254,252,253,242,251,253,249,224,249,246,255,255,238,249,253,231,234,253,240,249,237,245,255,243,251,244,254,244,249,249,225,239,246,241,254,240,219,191,34,45,177,190,212,193,217,235,251,239,252,243,245,246,229,237,238,237,238,238,252,233,223,249,234,252,247,224,220,156,27,78,189,156,186,165,196,238,255,244,255,250,239,254,255,251,248,243,247,239,255,255,253,249,239,236,242,252,124,16,13,89,135,125,140,172,203,249,251,244,242,237,250,243,247,247,250,238,226,248,255,246,186,175,157,115,81,65,37,56,4,28,42,74,45,71,34,50,77,73,107,79,84,76,127,129,108,104,138,137,147,137,152,82,93,66,30,83,59,35,66,67,82,103,109,103,62,90,79,75,94,98,74,71,87,82,67,62,49,34,18,16,28,23,53,70,68,107,105,123,96,106,115,116,122,110,83,76,67,35,18,83,62,58,86,60,60,41,39,41,41,52,55,30,57,7,39,24,19,28,58,78,90,87,101,76,88,70,97,71,36,76,76,69,62,53,62,36,67,65,69,71,41,50,85,64,60,62,78,79,101,64,44,44,42,60,52,40,34,19,18,17,27,19,29,14,26,28,5,44,38,33,12,37,8,24,17,14,45,16,16,17,19,3,28,37,23,24,35,19,19,37,0,34,27,4,14,34,38,15,31,20,31,6,32,31,18,18,21,49,27,39,26,13,28,14,30,20,27,20,21,38,1,6,31,20,21,17,70,81,53,23,26,29,24,14,53,14,43,9,43,32,7,16,36,52,10,41,31,25,30,25,26,21,21,13,18,18,9,25,21,46,14,35,24,50,6,33,26,29,36,30,23,20,19,35,27,46,21,38,15,35,28,35,24,31,11,48,19,26,26,14,29,19,23,25,29,14,30,14,8,43,18,31,26,29,57,36,29,21,18,13,87,97,84,30,18,28,28,18,46,25,27,33,4,23,12,22,35,32,8,11,27,8,30,13,24,9,9,52,14,13,37,26,14,22,25,20,9,35,17,53,34,32,26,11,16,2,25,22,32,36,20,32,4,9,31,42,12,28,34,9,47,29,28,35,40,30,20,17,46,11,14,29,106,215,234,252,233,217,217,235,223,229,203,239,220,232,227,237,202,224,235,253,246,220,191,135,100,28,53,73,21,35,61,79,56,49,74,97,112,112,128,85,65,40,79,147,166,220,220,241,246,243,246,254,253,247,238,229,225,249,228,220,244,237,109,16,17,9,12,25,6,27,0,17,25,30,3,15,0,15,8,13,46,23,12,6,9,21,18,236,231,214,173,151,131,165,153,185,164,145,145,175,157,184,210,228,250,246,250,195,135,113,16,61,148,109,104,55,53,38,2,0,0,5,16,22,23,25,39,20,15,45,24,31,30,25,41,24,25,56,52,41,1,22,11,53,102,99,54,9,19,81,64,76,92,76,96,79,62,54,52,83,70,81,87,43,42,57,49,52,26,27,58,23,23,53,47,81,56,97,82,77,87,127,127,103,100,96,109,76,68,71,72,62,64,96,62,74,40,71,92,32,63,44,44,76,66,77,70,51,55,42,82,91,24,10,38,41,30,7,81,107,104,151,146,168,159,189,182,215,234,244,245,246,248,228,235,232,242,223,209,192,183,161,181,190,192,128,83,119,154,183,172,170,131,152,199,212,207,193,203,201,200,173,172,126,110,170,108,108,79,107,109,64,75,60,72,94,26,29,63,131,211,227,241,238,243,251,245,240,250,224,236,225,237,209,184,163,178,148,114,113,91,93,71,58,61,24,12,70,216,245,247,247,249,236,251,250,249,254,237,239,240,227,240,247,224,213,205,153,153,138,117,44,37,66,51,35,2,92,237,249,237,241,249,248,245,248,232,245,248,246,246,235,246,246,230,217,212,193,89,41,65,73,86,46,44,35,63,88,140,69,60,53,60,71,129,78,84,96,91,85,74,37,64,62,33,35,52,56,60,35,45,70,38,76,70,52,93,132,119,124,141,104,74,81,75,119,118,143,124,96,95,43,47,32,13,8,30,56,54,60,90,95,120,90,123,115,98,91,101,91,92,52,69,54,61,61,51,60,67,63,83,59,79,51,45,59,52,29,54,38,30,56,49,73,92,93,128,100,106,109,105,111,95,78,79,50,93,76,54,76,68,23,40,67,61,48,67,71,72,55,104,98,85,85,94,68,29,43,10,7,3,20,21,29,38,18,24,24,4,34,25,19,48,36,14,19,47,23,50,43,36,37,13,32,29,23,29,16,50,11,13,29,27,11,21,40,12,12,34,20,11,26,11,37,15,36,23,15,29,6,22,18,34,16,21,31,28,35,27,21,14,32,11,11,31,13,29,19,12,33,33,49,44,18,64,88,68,51,39,28,55,19,3,38,12,24,25,30,41,29,24,40,29,29,30,17,29,23,42,27,34,41,18,18,20,27,15,13,10,4,3,32,9,7,9,7,33,14,44,31,52,17,33,7,16,14,26,36,25,39,32,22,20,23,3,36,34,23,4,9,38,17,25,2,28,11,13,47,23,36,18,31,20,43,28,24,34,3,60,90,106,86,49,7,9,36,52,42,31,9,19,21,21,25,30,6,30,19,6,21,14,11,27,15,30,18,32,20,36,26,41,9,20,9,32,8,32,20,21,39,18,11,33,18,30,19,57,8,26,29,9,23,16,25,20,29,24,19,31,14,41,23,26,29,26,30,30,26,37,8,146,194,205,202,190,185,206,193,203,185,224,224,222,209,199,202,209,200,188,217,177,169,155,143,124,138,152,143,138,73,78,68,46,80,80,88,92,97,100,106,89,71,106,227,224,239,246,248,246,247,243,250,224,246,255,250,251,255,246,203,243,245,136,0,10,7,5,32,3,20,30,1,26,31,26,5,1,4,17,19,8,15,7,16,12,4,10,194,241,250,251,242,185,203,211,235,194,123,133,171,144,198,254,232,226,221,237,134,96,82,38,18,56,41,23,26,9,22,36,19,11,14,21,16,22,10,30,35,14,21,4,20,25,5,22,23,65,61,87,39,2,17,14,56,60,58,34,37,21,62,58,64,79,130,102,80,54,31,43,88,76,54,21,38,27,58,36,55,47,72,83,65,57,31,64,61,71,51,75,60,63,90,112,100,81,64,60,67,79,74,71,90,54,102,73,41,40,51,65,23,18,34,7,93,37,65,38,43,17,25,47,46,10,54,30,73,38,21,122,135,190,229,225,254,245,252,246,234,239,202,214,211,182,169,152,121,109,120,91,102,108,104,143,115,105,49,15,19,91,95,101,32,4,52,54,27,22,47,42,23,34,6,25,4,32,11,31,12,19,19,54,54,61,79,113,110,25,22,11,34,105,105,90,80,110,112,76,89,50,43,47,49,32,25,6,19,3,11,17,60,43,54,9,31,105,39,6,39,130,158,177,158,178,134,125,136,136,97,95,49,63,15,34,20,10,9,20,7,20,41,50,9,38,105,61,34,46,77,210,204,165,168,170,199,147,161,157,87,151,97,119,117,52,52,30,27,17,39,6,9,0,95,136,80,50,17,43,99,150,85,61,38,52,42,40,54,19,46,67,39,41,35,66,30,59,79,78,83,131,105,152,117,73,151,89,52,63,115,126,106,81,72,38,51,66,77,114,79,73,51,24,20,44,24,12,40,47,57,90,74,84,122,126,103,110,103,104,90,80,92,72,76,50,74,62,87,77,110,76,61,89,77,74,52,41,60,44,15,41,52,33,70,120,123,93,110,112,114,90,102,101,82,69,101,75,64,83,70,84,67,47,63,64,52,34,69,62,66,62,59,83,74,76,76,49,35,2,12,31,23,36,2,18,32,66,7,34,21,27,22,10,14,41,17,36,21,7,18,24,26,26,15,35,33,24,22,30,28,5,10,29,18,51,36,20,20,28,24,10,51,38,55,18,33,31,16,21,2,16,19,56,48,9,27,17,34,9,33,27,27,7,31,33,10,27,26,27,25,42,27,24,16,19,11,36,91,88,34,54,32,7,16,29,27,27,47,18,30,32,11,4,18,0,1,16,24,20,46,15,5,20,0,34,34,22,20,6,19,4,7,27,21,24,23,11,41,10,42,38,36,43,36,16,67,26,12,41,16,37,56,26,37,14,20,25,43,22,23,36,34,25,6,12,17,30,15,31,32,8,31,34,27,5,14,8,33,48,29,33,43,86,112,68,25,14,35,32,48,25,25,14,20,30,33,38,19,28,19,16,21,42,38,9,38,0,29,32,39,18,18,15,19,14,40,25,9,39,47,28,25,2,6,14,16,0,35,5,26,26,5,30,11,25,44,8,41,15,38,17,23,26,19,26,30,20,23,16,12,14,41,131,186,165,161,169,159,168,152,177,175,172,176,174,203,197,173,148,154,125,149,141,137,139,126,96,153,176,212,133,84,60,37,21,42,94,74,50,71,93,118,77,97,201,247,235,249,221,222,243,250,252,236,246,247,233,234,252,232,192,209,240,221,120,3,1,0,21,2,5,19,6,34,31,26,17,0,6,12,24,20,10,6,1,17,22,25,15,237,222,255,252,255,237,252,228,225,161,113,151,129,189,216,255,226,186,163,190,181,207,191,134,146,153,89,108,127,151,94,93,81,80,90,109,106,81,85,106,85,82,98,115,125,116,119,84,139,153,162,184,107,69,95,72,83,103,104,67,34,60,105,81,105,103,128,114,89,89,73,68,63,78,84,84,69,70,68,87,69,36,71,95,91,57,63,61,73,48,58,60,75,56,68,82,93,60,67,25,18,40,50,53,34,47,42,50,14,13,33,52,42,38,28,52,122,91,130,133,135,161,138,154,153,124,119,122,193,124,133,194,233,227,236,232,225,181,169,164,116,123,143,128,106,118,122,97,82,75,86,71,68,60,75,60,65,51,30,13,35,58,47,38,12,22,16,26,27,14,13,24,57,45,72,86,97,84,93,101,81,91,109,126,111,89,88,108,136,48,17,17,45,39,26,30,16,17,10,17,6,10,46,22,43,68,96,61,70,100,98,97,88,140,101,82,73,128,87,38,5,54,24,16,19,11,3,7,12,28,21,31,28,44,35,38,52,48,56,48,9,50,131,138,75,29,105,112,55,45,11,53,48,48,53,5,13,15,34,23,28,7,2,14,29,3,23,22,36,16,25,41,58,47,62,129,50,22,63,60,38,65,64,64,63,42,55,54,73,47,69,82,94,98,123,136,158,170,162,139,129,135,143,125,120,100,81,36,37,52,57,72,27,49,57,47,51,64,59,33,45,4,31,10,51,14,12,59,67,65,88,82,114,123,88,112,114,120,120,119,83,62,56,57,58,67,59,72,45,75,103,85,82,80,78,60,25,41,41,28,35,59,45,38,81,114,131,109,117,127,76,101,68,80,57,80,75,74,110,68,77,60,54,29,72,37,45,76,93,93,82,57,87,83,68,31,41,18,9,9,53,18,32,2,5,54,34,29,19,16,23,21,0,33,18,15,31,6,33,10,16,53,27,54,39,42,15,13,22,23,19,23,17,19,4,16,15,27,3,16,23,26,16,40,19,14,47,31,35,17,28,41,24,3,35,42,41,15,7,12,4,39,9,13,16,37,46,10,48,14,22,5,16,21,13,16,39,23,31,75,47,42,7,28,13,15,29,12,52,14,17,16,32,20,39,64,37,32,39,39,32,9,48,7,40,27,10,8,20,18,22,11,6,42,24,12,30,7,29,27,43,19,27,40,24,9,0,36,12,16,24,9,41,47,29,42,22,25,29,21,32,28,16,26,28,7,6,12,23,11,6,23,1,2,7,27,47,8,63,23,20,21,29,36,84,81,46,28,17,41,8,15,28,12,15,24,23,30,21,10,24,33,21,33,19,34,25,13,12,10,6,12,54,35,25,19,8,19,31,25,26,27,11,7,20,16,15,23,11,38,28,4,18,14,7,46,24,28,30,14,13,12,36,31,42,21,20,18,13,15,16,4,50,109,101,148,115,98,133,142,122,119,133,129,142,142,126,136,133,146,103,104,98,133,87,98,69,25,86,112,116,88,82,88,62,43,37,12,8,6,27,61,82,71,104,205,216,217,216,222,220,232,252,251,226,251,236,233,253,249,205,182,187,212,192,103,18,4,16,34,23,4,23,11,17,12,8,5,5,3,32,0,12,9,14,29,30,5,24,26,255,252,254,253,255,251,238,243,238,157,115,152,135,194,242,244,235,179,128,221,251,236,241,231,192,242,190,184,236,220,189,133,173,169,176,236,248,228,223,216,163,247,247,248,239,239,252,252,252,233,233,245,181,140,178,169,121,132,115,88,47,96,108,70,94,123,141,139,135,103,62,76,61,72,60,69,80,76,67,68,49,61,50,113,90,39,38,62,76,71,38,35,16,25,61,90,77,61,57,25,24,30,23,38,43,70,117,121,137,97,98,151,141,151,91,127,237,189,200,220,207,190,155,220,190,135,125,92,123,94,124,122,176,171,148,143,135,53,42,56,16,96,78,88,86,88,62,91,84,87,78,102,62,50,18,18,24,22,23,30,25,86,74,100,64,20,104,135,129,131,131,150,143,143,150,151,157,168,155,147,134,88,95,58,24,38,31,36,46,33,48,35,29,105,116,138,132,134,118,121,128,142,137,172,164,171,189,158,133,119,99,81,73,76,48,46,57,62,62,53,14,57,64,65,90,77,114,91,127,144,105,120,142,139,149,162,117,124,107,84,30,30,69,65,48,24,105,59,48,38,20,45,52,70,64,76,47,59,9,41,4,20,5,17,53,23,72,42,80,50,40,23,76,35,54,39,58,36,31,47,35,42,49,85,126,140,156,163,144,153,150,153,147,136,127,106,95,115,59,75,35,24,29,30,18,15,28,30,25,37,59,56,53,40,38,23,58,43,38,37,37,16,16,19,60,42,53,91,112,117,113,100,119,121,104,97,105,122,88,68,59,37,66,59,61,63,49,79,85,72,94,98,77,59,50,19,24,26,13,48,37,78,64,76,116,130,89,69,73,95,78,83,81,91,61,67,92,74,60,48,45,64,56,67,56,58,65,64,72,60,66,83,45,31,34,37,11,47,28,11,8,33,16,36,61,48,64,35,17,20,45,33,46,16,9,29,26,22,13,40,34,31,27,13,21,0,48,19,30,32,21,28,16,21,20,8,15,29,37,35,33,21,6,38,18,26,14,38,11,26,37,29,8,12,30,24,14,55,25,12,37,32,10,14,5,25,38,25,13,15,31,20,48,16,1,43,30,28,43,88,81,42,16,23,50,24,43,14,16,51,9,10,9,23,20,15,15,51,18,23,37,28,15,51,21,32,18,14,7,10,8,47,28,21,9,20,19,20,16,19,11,11,31,40,19,46,52,26,25,40,27,23,26,38,26,22,19,16,26,16,29,45,4,7,16,4,10,17,29,6,25,34,21,25,10,32,28,10,29,33,24,23,13,6,67,119,84,65,80,37,16,22,6,18,23,21,12,28,28,13,24,35,24,36,44,25,16,18,32,33,37,7,27,20,33,22,70,35,30,31,14,22,12,5,26,23,18,10,28,28,16,30,10,28,34,7,20,2,39,40,41,22,20,0,32,27,35,22,18,22,24,36,87,124,111,148,119,112,122,142,101,122,117,119,140,126,103,125,127,121,134,105,135,128,113,121,95,116,90,100,118,125,106,138,111,72,46,76,105,84,78,92,73,87,155,232,237,217,235,244,236,249,243,245,239,240,233,245,220,249,215,211,198,216,205,110,2,1,12,25,8,14,6,24,22,14,10,16,20,7,21,8,0,25,7,0,15,15,25,18,200,151,156,190,184,229,244,241,219,131,115,123,122,144,173,207,202,142,96,111,187,213,213,106,92,168,109,105,141,159,99,102,155,144,141,212,194,190,191,179,176,193,203,237,197,154,225,228,241,247,243,238,96,122,158,135,116,141,120,50,12,87,81,73,38,76,124,121,89,99,89,44,51,57,62,69,79,59,33,37,18,57,46,5,7,49,42,33,47,62,50,29,24,28,102,104,122,152,133,180,161,133,133,104,137,205,211,230,212,171,143,162,124,169,112,113,205,151,119,134,141,124,87,102,52,74,57,17,38,22,48,132,42,92,99,115,103,27,29,18,25,50,64,4,15,30,55,41,65,71,80,124,99,105,115,125,147,132,88,47,54,151,171,191,166,57,136,179,169,150,125,108,90,95,89,69,73,72,92,98,97,103,109,91,121,63,100,98,117,100,49,24,83,189,205,214,184,188,167,141,154,127,110,132,105,105,96,91,71,77,75,45,55,56,80,49,48,98,38,57,1,93,169,192,175,149,140,152,130,138,142,149,114,112,103,96,87,53,60,46,20,41,77,105,55,62,163,136,53,5,33,144,208,191,116,119,135,96,87,72,67,64,50,50,55,52,43,73,40,57,49,37,60,81,108,114,109,126,139,49,90,111,138,152,129,167,146,98,100,82,70,46,60,33,41,37,27,29,18,30,42,21,31,2,20,17,14,14,39,38,53,74,79,62,11,23,10,29,40,12,0,35,38,70,93,73,101,121,77,107,106,110,114,127,87,105,109,69,72,70,53,62,49,60,58,83,70,80,81,87,142,84,37,11,9,22,10,25,40,57,76,80,134,96,103,96,98,114,64,80,86,85,64,72,87,77,80,64,68,38,55,69,47,53,67,69,59,75,77,64,62,48,41,31,36,15,32,16,32,17,28,33,20,28,26,56,37,34,38,66,97,69,36,43,12,27,36,37,34,28,21,36,8,26,21,13,31,23,26,33,12,21,43,44,1,17,13,9,18,27,23,22,4,28,23,36,19,38,29,32,22,25,37,26,29,31,25,12,24,10,49,29,45,33,12,19,12,43,18,4,15,25,24,23,35,18,49,17,0,83,70,20,20,38,15,10,7,39,28,24,25,12,51,10,44,48,14,28,41,16,3,42,29,24,34,10,27,35,16,23,11,13,29,11,11,16,14,11,17,25,29,32,51,23,13,25,36,21,52,45,22,48,27,41,24,22,29,28,22,36,29,25,11,12,40,27,20,9,28,14,20,5,12,42,14,16,31,2,26,27,44,15,5,20,18,72,93,108,77,47,24,26,11,17,21,6,24,10,26,35,20,17,20,6,40,14,33,9,3,32,10,23,19,5,37,17,14,19,29,23,16,18,31,35,8,19,37,22,9,16,26,12,33,3,6,22,40,22,18,2,20,24,33,31,19,14,24,22,17,14,41,16,61,114,102,117,134,134,183,149,132,142,164,208,185,172,180,166,169,211,199,172,189,193,188,201,229,209,210,227,189,179,208,195,202,158,185,193,213,196,189,193,175,168,205,229,213,245,246,247,243,236,249,250,250,249,252,233,242,239,228,218,215,222,208,90,18,0,0,13,15,11,5,16,13,30,3,16,13,11,16,14,30,9,2,40,12,37,3,16,69,94,96,132,201,200,179,190,215,139,99,139,111,93,20,15,31,53,25,19,35,20,8,23,45,19,2,50,59,45,41,36,40,9,45,51,32,30,47,35,58,15,47,40,74,25,30,55,53,105,121,116,28,49,49,41,117,132,194,95,56,135,124,84,72,55,88,67,68,86,96,119,57,68,71,77,94,67,52,56,59,77,75,40,43,70,92,55,68,69,126,145,126,111,171,198,187,254,237,236,193,188,145,154,201,235,240,217,232,205,186,166,63,111,49,68,140,108,68,61,78,72,87,99,83,65,22,27,23,35,63,60,49,43,64,55,75,1,30,40,14,68,67,73,69,41,106,77,126,126,128,154,179,158,124,147,195,179,118,36,23,148,146,166,77,51,126,84,93,67,37,40,17,23,36,20,49,71,119,128,118,161,140,156,163,159,166,130,143,105,28,36,67,150,134,122,85,79,46,43,42,35,49,49,3,35,30,70,72,80,122,130,149,135,155,105,106,152,68,51,34,98,99,149,121,83,87,48,24,31,30,12,9,29,11,36,64,96,97,74,8,124,164,169,81,61,175,161,93,25,18,103,129,124,65,26,39,10,30,58,27,54,64,57,68,86,142,191,152,151,162,176,165,153,173,148,151,192,171,68,52,68,53,54,41,42,28,36,19,20,54,15,18,21,44,36,29,28,24,30,3,25,29,7,42,36,31,42,36,35,37,99,70,39,33,20,16,24,35,30,22,50,34,59,66,74,69,92,127,94,109,111,118,96,110,72,65,47,56,72,70,70,76,45,72,75,77,76,67,62,48,50,29,8,1,12,24,56,73,57,79,116,71,126,119,100,102,79,68,98,61,99,104,51,44,75,61,68,48,51,80,91,87,49,79,41,71,79,64,68,44,24,15,48,19,2,19,40,7,28,33,22,63,80,43,26,41,67,55,65,141,73,52,4,25,4,29,12,31,36,20,27,29,8,42,50,42,27,19,26,46,44,3,26,35,17,14,37,35,31,39,9,9,13,30,32,32,20,28,18,26,9,39,21,25,45,44,12,19,34,22,8,39,30,35,20,11,54,14,5,19,24,44,35,29,34,39,30,35,75,83,54,44,20,7,24,25,19,23,36,49,29,44,5,40,42,23,37,11,35,18,50,39,14,13,16,15,16,13,25,13,29,36,17,16,24,7,21,24,20,14,42,50,57,18,5,23,21,26,39,17,45,46,20,25,30,16,36,20,25,14,35,14,12,29,35,22,0,55,12,10,44,34,27,35,29,27,52,27,17,30,15,23,19,15,36,37,109,91,40,37,15,25,41,29,22,29,30,13,24,45,15,4,14,2,30,18,15,38,39,29,17,15,27,34,4,0,9,13,15,29,28,3,34,16,19,51,4,40,40,25,51,33,25,8,23,33,30,20,31,12,16,23,19,22,23,36,23,29,35,24,29,43,92,32,69,81,84,135,85,98,149,159,158,144,139,119,159,163,188,208,202,222,223,220,249,251,237,245,248,235,211,214,207,214,188,217,226,201,201,201,207,178,165,169,193,236,214,234,226,197,187,201,218,215,214,214,210,226,242,241,241,197,202,189,108,32,5,14,12,15,2,20,12,21,31,0,2,13,22,8,23,25,37,33,15,14,59,13,17,180,187,186,171,148,140,114,156,224,159,122,133,123,91,32,14,58,90,51,30,62,35,19,19,63,67,49,76,91,79,38,24,44,40,31,44,47,32,22,31,14,69,21,49,33,28,19,28,11,39,59,88,61,91,121,94,157,188,247,175,122,164,222,199,141,75,62,57,64,106,131,197,116,89,86,70,108,44,73,68,107,168,214,170,131,185,184,146,113,88,137,224,241,175,187,182,126,192,166,156,75,79,92,86,160,195,157,147,197,244,241,180,83,88,102,141,222,214,112,84,91,56,95,123,73,80,89,60,53,53,54,58,49,55,59,76,47,35,72,62,50,117,130,169,133,127,147,153,121,110,132,119,93,107,131,116,97,92,39,24,38,49,24,34,31,13,92,115,104,94,133,118,123,137,135,137,121,129,140,137,156,138,142,133,130,112,98,80,50,33,29,62,39,48,50,29,45,56,72,106,126,114,96,110,141,133,137,126,154,173,168,179,156,148,124,81,49,76,38,89,28,29,72,32,42,27,50,63,94,99,82,110,103,127,106,133,165,179,175,129,77,95,130,133,68,19,55,72,33,87,6,33,48,96,71,60,89,129,117,109,119,128,141,149,172,167,191,199,149,130,137,146,131,80,85,52,46,78,61,30,30,33,16,10,37,7,21,2,31,35,42,7,29,10,34,8,11,27,38,34,35,47,19,28,30,34,43,31,41,9,60,111,55,46,27,16,31,6,39,36,64,71,50,49,72,51,78,73,95,74,88,73,68,76,46,76,76,52,46,72,66,78,61,86,53,81,66,74,52,20,22,5,26,15,21,37,51,76,84,68,81,128,79,98,74,90,78,75,77,84,98,77,80,62,55,42,50,79,63,39,86,77,73,60,92,83,60,62,38,13,31,13,15,15,16,9,46,41,39,44,39,27,30,55,31,17,37,29,23,40,82,130,58,34,3,17,33,14,10,38,9,46,23,42,46,24,22,53,51,32,21,40,30,36,9,49,35,46,16,9,8,41,34,51,20,4,9,27,17,13,22,28,2,30,27,24,23,34,18,33,29,25,20,26,5,26,38,35,18,42,11,26,6,19,18,54,29,12,30,61,94,71,16,0,21,49,30,19,36,37,18,42,14,40,48,41,38,18,11,18,30,37,23,43,27,13,32,3,31,19,3,12,18,16,35,25,14,28,26,25,28,35,54,28,34,21,36,20,37,14,27,16,18,49,35,27,15,35,21,15,28,29,30,30,18,13,18,18,28,21,10,24,3,18,33,11,3,25,22,50,23,33,15,27,31,19,38,50,121,85,49,25,24,50,34,29,52,18,11,33,25,38,40,24,8,3,28,22,5,19,24,30,16,8,27,36,23,21,17,27,18,28,32,13,27,27,25,50,33,29,40,23,36,51,31,19,26,11,8,17,17,22,37,36,31,18,19,7,7,41,43,19,55,112,52,26,25,47,53,27,40,56,68,79,63,38,87,83,110,113,131,124,167,178,149,224,206,184,181,188,169,121,138,167,194,175,175,154,145,150,128,164,140,98,117,118,127,122,133,106,107,90,104,83,120,133,149,128,152,153,177,162,168,155,140,97,31,2,8,5,6,8,12,2,31,12,48,2,28,13,17,13,21,17,22,0,5,5,22,4,252,234,232,180,140,130,151,186,234,166,143,165,151,121,12,18,80,135,86,36,74,41,30,59,110,39,75,84,120,94,70,72,82,53,79,68,60,34,53,55,66,80,66,95,115,94,77,48,74,87,140,147,99,160,120,129,201,233,247,145,85,187,229,229,129,98,99,122,114,109,142,156,94,119,134,126,124,69,65,92,142,186,255,175,179,248,232,214,115,42,103,162,188,139,123,60,45,105,42,39,32,27,69,80,60,58,68,81,165,166,201,152,88,115,81,120,198,195,99,73,84,126,120,126,132,110,107,117,67,7,62,158,137,145,135,137,123,64,107,75,121,164,129,128,138,119,87,70,37,29,31,12,30,22,84,73,93,96,108,74,20,105,134,147,94,46,127,175,163,180,185,80,139,168,128,126,112,98,46,60,17,54,49,75,60,60,82,92,110,99,56,4,43,92,151,146,146,143,184,201,174,196,177,176,146,134,107,60,91,111,105,80,88,64,64,44,44,48,60,47,38,52,101,106,130,141,147,157,180,204,174,187,159,131,123,102,110,99,125,75,36,74,54,24,32,44,51,76,105,67,52,41,108,182,164,146,192,182,170,152,159,155,117,73,105,85,78,49,34,46,2,25,31,23,49,26,24,28,28,25,44,24,25,24,25,3,37,22,29,8,36,35,17,27,21,13,52,27,51,39,21,25,50,11,23,37,64,27,16,25,26,24,31,23,42,14,3,42,40,97,66,62,78,80,88,71,70,76,73,73,69,81,75,43,47,58,37,48,65,84,44,83,74,75,81,68,43,50,38,25,38,19,21,25,82,58,87,98,81,93,86,85,102,84,84,75,96,66,64,78,71,73,46,34,53,55,48,56,56,83,92,54,52,79,61,48,65,32,11,21,2,16,14,21,40,36,28,49,49,19,32,34,51,27,67,36,35,39,24,18,34,112,95,60,26,14,13,20,29,18,7,27,29,36,25,24,14,28,28,35,16,11,13,44,13,11,8,16,9,17,40,32,48,16,13,39,33,43,1,33,36,32,28,40,30,36,39,11,10,57,11,45,19,25,26,12,40,29,28,19,39,26,11,36,54,25,37,23,23,50,81,62,34,20,36,16,41,36,23,25,26,15,34,16,22,30,15,28,28,17,56,25,23,3,13,39,44,24,27,32,48,22,33,47,16,28,26,39,30,53,38,18,15,41,33,25,47,38,26,44,14,18,5,25,65,30,26,24,22,15,26,9,30,24,19,43,26,14,26,17,2,1,27,21,11,19,2,38,26,7,23,20,25,15,29,26,25,49,71,93,78,37,27,32,15,2,21,24,22,5,7,23,22,24,18,28,10,9,36,20,11,23,32,19,13,22,22,3,15,3,13,45,42,41,10,8,41,18,21,49,16,16,47,35,25,28,22,16,32,33,39,24,20,16,20,14,12,41,33,21,50,23,71,115,54,31,30,11,57,58,32,50,41,66,61,72,49,72,72,57,71,56,106,99,71,92,121,108,112,109,95,66,109,142,145,151,113,131,70,90,103,59,61,96,76,59,56,66,45,74,57,50,31,40,74,97,66,69,71,95,90,95,101,70,127,98,7,12,29,4,28,20,23,18,23,19,5,1,1,13,11,17,14,27,15,20,23,21,26,19,252,252,255,239,222,225,245,236,231,167,130,133,169,106,18,16,96,141,66,63,92,75,66,56,78,81,95,117,100,95,57,38,60,81,98,73,65,49,43,56,42,43,81,70,84,75,65,67,101,83,83,62,73,86,82,84,148,216,208,130,83,141,147,120,139,118,157,177,171,172,139,83,111,145,162,150,151,86,47,41,76,132,149,128,129,181,139,176,126,43,69,122,153,90,68,1,22,56,27,46,28,48,76,73,65,28,26,30,44,34,13,43,36,28,31,41,34,56,21,51,110,114,185,175,189,197,179,180,55,17,25,72,119,88,99,79,73,32,41,33,72,85,58,50,57,45,61,63,41,48,58,80,90,114,120,143,122,186,129,63,29,136,187,161,79,26,106,89,110,112,82,80,48,95,59,53,49,46,40,18,3,54,62,99,107,144,148,157,187,164,66,44,84,150,142,130,128,129,133,122,130,67,101,68,49,45,31,29,32,19,21,46,67,105,85,55,122,126,38,75,38,65,142,158,193,187,167,165,159,106,94,96,69,67,38,27,5,12,25,70,74,135,160,169,129,164,174,167,161,129,44,73,139,135,139,94,72,94,54,32,26,45,13,12,20,35,31,37,2,19,29,37,32,18,14,1,43,16,19,27,33,46,2,19,0,23,6,24,33,31,61,31,16,29,37,45,50,23,30,32,20,26,57,26,42,39,47,29,25,34,31,17,28,24,34,55,60,92,99,82,83,62,62,41,66,96,61,86,58,89,88,91,49,67,46,65,64,73,72,67,74,83,63,69,23,26,37,42,8,25,21,29,68,59,76,92,78,88,90,92,91,84,81,78,77,80,84,102,50,38,94,62,62,32,71,58,58,66,66,68,71,76,68,57,46,38,18,11,13,28,26,34,20,25,34,53,76,48,22,31,51,30,65,37,35,7,31,44,25,23,25,39,132,99,31,18,12,14,45,33,33,12,34,31,16,34,28,33,38,13,65,10,31,12,28,43,20,13,21,10,27,26,25,13,23,11,17,38,25,1,52,13,39,5,40,21,34,37,27,32,31,37,43,30,42,30,57,19,29,45,11,22,20,22,24,22,59,30,46,37,102,81,36,36,0,38,28,27,20,25,32,33,35,34,5,25,20,32,31,29,34,40,42,14,8,44,40,28,37,25,11,32,27,7,34,12,21,22,29,35,20,19,49,14,34,42,32,39,31,37,41,31,12,35,40,48,12,20,15,16,27,21,9,48,16,24,13,15,20,7,22,17,22,36,11,9,39,9,25,10,45,16,33,19,15,31,28,40,34,68,124,67,37,26,13,32,11,16,24,25,36,33,46,11,23,36,24,11,24,39,46,35,40,21,26,22,20,32,40,17,18,14,18,10,31,23,33,21,28,20,19,16,10,29,16,24,15,19,24,44,45,31,38,2,7,32,30,4,40,51,58,54,137,161,129,108,68,40,45,33,42,44,52,54,41,76,63,58,68,78,55,79,66,79,75,60,39,70,104,96,58,60,83,142,129,83,83,103,91,106,63,50,71,65,56,63,68,16,47,56,63,41,51,55,45,66,40,34,39,50,43,70,37,54,56,62,31,21,5,19,17,1,15,19,24,12,16,13,1,2,17,27,11,0,4,30,25,16,6,2,250,249,246,255,246,245,223,243,236,168,135,138,151,114,48,61,128,130,98,130,128,105,74,117,127,111,120,115,83,119,55,35,46,57,88,122,41,51,43,73,71,73,98,106,100,110,103,85,136,81,24,48,93,122,74,81,170,226,236,112,81,186,124,80,108,141,138,135,170,197,177,103,73,77,102,112,94,67,51,85,50,44,60,44,60,102,98,122,133,124,67,70,78,78,54,35,52,39,40,46,66,52,72,101,79,38,25,44,47,62,25,47,66,59,61,82,88,61,93,75,38,53,74,103,111,106,141,86,30,25,58,101,90,67,65,70,76,21,55,39,75,110,109,140,146,144,161,154,162,187,170,169,137,161,139,130,107,95,96,48,38,56,77,67,6,38,39,41,65,29,59,47,64,95,86,107,102,134,131,133,132,98,113,134,145,125,113,139,123,91,37,43,47,69,28,44,44,41,19,26,18,13,40,66,93,83,90,121,119,87,99,119,112,130,103,82,112,102,49,50,70,55,42,59,61,40,54,53,40,48,54,68,92,131,138,142,144,159,150,144,178,182,173,178,153,156,121,112,121,51,27,39,65,28,10,24,37,16,18,15,6,37,16,27,33,7,16,19,9,22,2,11,25,19,19,41,18,11,9,51,41,53,29,36,31,37,51,66,67,68,51,37,37,28,40,42,45,52,52,74,83,114,99,97,44,6,43,33,46,54,39,51,63,61,45,58,52,98,104,67,75,68,28,25,65,77,76,74,59,94,35,80,65,53,57,63,62,56,43,63,104,68,43,46,22,1,25,16,27,44,68,84,97,86,122,106,104,80,78,80,68,73,72,85,82,77,76,81,48,73,63,49,62,61,59,46,62,70,54,95,65,82,56,23,26,0,19,19,6,7,18,57,13,57,60,41,27,57,58,31,44,54,62,47,48,26,38,25,41,14,28,29,77,94,81,38,39,29,32,38,4,26,50,31,24,55,32,24,41,36,24,44,19,40,24,28,23,10,16,35,40,28,41,13,44,16,14,17,33,36,24,35,20,15,27,46,28,19,22,25,22,43,19,17,28,27,20,23,35,26,27,20,37,10,37,24,26,55,2,32,70,88,51,63,26,19,29,15,28,23,34,39,23,31,28,42,42,16,41,44,24,9,5,41,23,27,15,29,33,48,19,30,21,36,31,0,37,1,22,40,42,34,42,34,17,43,39,26,29,29,28,44,34,28,30,14,17,48,17,2,27,6,28,15,23,20,27,26,16,30,8,25,13,8,47,28,23,36,34,7,34,22,40,10,17,33,5,36,36,46,100,124,92,49,22,17,12,21,10,22,20,36,8,48,26,29,27,14,23,5,22,38,17,11,50,28,11,22,24,19,16,27,17,35,8,36,11,41,31,24,10,19,19,18,23,22,33,42,13,23,20,15,32,16,32,26,39,30,69,61,64,151,212,208,208,184,154,93,60,24,28,45,19,35,63,48,46,48,71,83,59,40,64,80,59,38,33,86,132,99,93,54,87,91,85,97,94,90,69,82,76,57,59,85,79,72,76,33,76,65,62,49,36,58,56,82,56,41,29,44,41,74,84,44,45,58,41,3,21,6,31,15,29,46,10,23,26,3,6,7,1,24,3,5,17,19,28,9,11,33,235,255,253,237,246,253,244,219,213,139,132,135,134,183,176,119,151,189,120,101,91,47,62,85,133,84,76,60,75,95,68,44,25,42,97,109,46,64,68,81,74,65,99,89,47,90,73,97,99,71,45,22,71,104,53,82,156,202,174,86,55,171,106,63,104,134,73,66,123,191,142,57,57,33,68,80,45,66,103,88,68,77,37,30,26,29,26,104,118,63,67,69,54,64,88,55,55,73,51,67,56,53,92,61,74,82,119,122,104,101,92,125,94,62,81,100,76,88,111,68,24,36,23,32,21,32,24,9,64,213,245,253,215,158,173,184,192,130,101,46,117,191,193,179,177,172,166,134,180,157,107,94,86,37,32,12,14,15,48,35,23,43,87,98,33,65,152,159,152,179,186,173,178,178,187,157,178,189,167,170,150,89,116,73,66,29,32,31,53,62,43,63,34,66,109,146,134,166,139,181,139,143,192,196,198,178,189,165,182,150,121,89,62,43,43,7,63,59,18,78,28,44,40,81,114,116,154,120,120,122,143,178,160,183,208,196,185,136,146,124,117,92,66,51,44,12,45,21,37,14,50,26,37,16,20,4,37,8,19,14,13,9,6,38,29,8,19,38,15,4,40,8,38,28,85,76,24,41,32,70,60,68,87,105,158,139,141,147,99,91,59,61,62,87,108,115,98,117,112,126,145,142,146,148,78,5,23,36,52,54,50,57,39,32,38,43,45,13,38,66,64,64,36,45,72,51,68,55,66,35,71,25,55,62,56,27,76,83,64,61,66,28,21,26,4,2,30,62,72,71,70,101,98,96,88,80,85,87,93,50,71,64,97,77,76,76,51,62,38,52,48,53,58,77,65,54,59,63,49,54,64,8,7,7,7,9,51,23,13,19,37,54,28,25,48,41,57,61,39,54,41,45,60,37,42,66,44,33,49,56,45,37,35,76,109,46,27,18,39,31,57,40,43,23,40,29,34,42,29,41,32,30,16,15,18,10,38,40,47,12,21,22,17,11,29,23,54,10,19,30,21,20,26,38,20,15,22,50,1,32,26,40,38,30,13,21,14,24,33,20,38,30,28,25,36,29,40,15,14,16,57,93,58,22,2,24,21,30,43,28,23,32,37,19,30,49,25,53,31,19,17,26,25,33,13,15,15,21,16,42,41,49,49,32,28,30,19,40,41,53,22,37,47,15,17,34,21,49,6,6,45,12,20,31,33,35,16,33,31,15,20,31,43,25,12,21,15,30,26,19,13,24,14,54,24,37,43,45,26,35,19,28,16,34,25,19,42,62,34,26,51,94,125,87,28,17,36,27,37,24,18,20,29,34,20,14,48,16,38,25,3,44,21,42,37,21,30,20,35,31,20,15,28,35,16,40,29,12,28,19,23,11,5,4,12,24,26,34,13,24,23,32,17,35,24,37,15,25,34,67,138,223,229,175,185,201,213,204,102,44,59,31,43,43,37,28,51,39,39,52,45,74,54,41,73,82,30,42,96,116,142,80,30,38,35,86,42,36,41,32,63,51,53,53,76,65,48,61,82,27,69,74,54,47,66,60,102,75,52,59,51,73,50,70,48,20,19,9,31,32,18,11,4,18,11,15,14,11,8,9,42,3,27,2,9,10,21,16,12,3,228,254,246,236,224,223,221,209,193,118,115,141,162,192,233,161,156,149,78,102,73,33,13,45,55,79,95,79,106,109,94,66,46,45,78,71,56,65,74,54,91,79,65,75,52,69,52,86,97,78,24,8,62,86,73,69,69,84,81,31,36,92,50,56,51,81,45,64,79,103,74,51,54,76,35,45,37,62,69,58,89,110,71,80,72,47,40,95,75,109,127,155,130,88,85,80,40,36,48,74,69,79,71,82,88,87,105,107,55,76,80,82,67,50,36,29,16,33,57,27,25,39,42,111,111,71,98,118,192,222,227,228,206,145,141,187,238,129,62,18,41,98,87,80,83,74,55,22,22,17,23,23,23,12,33,31,20,50,116,52,16,72,132,171,83,58,137,118,152,156,116,127,92,108,94,91,120,68,76,53,71,28,40,43,28,26,32,57,98,104,58,25,44,182,163,174,170,178,172,175,111,93,128,147,112,131,114,86,90,96,51,62,42,42,46,65,92,137,137,121,104,90,72,210,198,209,170,142,146,94,106,109,96,86,42,63,26,17,16,11,14,19,17,22,60,16,40,19,21,22,27,52,39,14,9,15,21,16,50,30,16,25,36,39,41,35,15,53,42,30,33,43,79,84,107,136,96,45,83,28,142,142,109,125,114,94,73,79,62,74,81,105,93,111,97,131,107,87,143,122,112,105,60,47,45,13,13,56,16,36,54,40,22,29,56,32,31,22,39,64,82,63,55,52,54,77,53,64,63,66,80,46,55,56,71,70,64,80,37,55,15,29,35,34,13,43,59,65,83,108,73,87,110,84,89,93,80,84,90,81,77,72,62,69,49,43,67,53,25,43,52,71,30,71,55,58,74,53,35,44,18,33,29,19,14,28,28,21,38,23,33,42,44,58,72,39,37,46,38,38,38,50,49,17,38,27,50,59,45,45,56,44,52,35,107,102,49,29,41,57,65,18,32,34,22,26,45,40,27,14,40,55,47,30,36,45,26,28,18,34,36,8,20,22,36,13,32,37,40,28,16,24,30,26,37,23,38,43,18,13,27,21,21,6,37,45,27,38,28,13,31,17,40,41,49,43,22,28,46,35,11,82,74,45,14,22,57,35,15,35,20,36,32,36,30,23,14,38,31,19,21,13,11,20,34,26,25,26,14,18,14,23,52,23,28,28,46,12,17,27,20,20,27,47,35,28,29,43,18,14,16,5,19,38,25,31,31,13,17,14,34,37,30,8,7,13,31,24,14,3,34,33,33,14,41,4,25,18,30,3,28,46,15,23,24,19,52,59,31,14,22,53,125,87,63,22,7,36,26,19,19,14,12,33,6,18,34,34,31,28,21,37,40,46,17,28,27,13,4,8,52,8,54,6,37,28,25,33,32,27,22,24,38,30,21,18,31,10,47,31,24,37,52,41,52,57,53,91,138,146,162,160,95,152,127,115,147,201,162,137,113,89,67,39,44,25,18,46,51,43,38,54,67,58,40,51,66,44,59,44,68,62,61,53,57,48,46,57,41,33,50,69,44,39,50,37,52,59,42,62,82,54,60,42,60,52,68,82,48,51,70,62,40,42,29,34,22,29,7,21,12,22,26,36,5,31,7,15,2,5,25,33,1,9,5,9,23,32,13,12,247,240,224,235,244,228,216,208,153,125,132,123,127,167,218,156,116,118,57,101,104,38,66,70,84,134,111,152,158,166,131,156,152,121,140,157,112,116,94,140,137,138,113,139,118,130,101,128,118,123,128,35,89,141,126,103,86,114,100,97,71,101,111,128,144,110,111,105,96,110,88,55,60,34,74,64,45,57,55,69,63,72,95,134,110,127,93,150,147,185,246,245,202,120,82,43,39,35,28,44,61,80,58,54,53,80,84,56,53,58,40,34,42,27,20,52,25,51,100,106,153,151,191,222,241,238,220,198,225,197,179,101,61,26,35,76,111,74,53,5,47,40,75,105,80,121,88,113,114,154,146,137,180,167,182,138,121,146,150,86,3,33,102,69,42,49,75,57,24,26,29,48,40,30,38,57,62,85,91,75,85,122,118,134,130,134,120,143,125,130,87,17,31,90,105,86,80,35,27,11,11,36,30,57,87,49,71,59,89,78,149,162,172,148,137,154,148,140,136,136,105,42,38,102,113,83,59,23,55,44,43,65,21,29,23,2,18,26,38,23,42,36,13,9,26,25,32,33,47,31,49,72,41,32,47,29,49,72,62,59,70,96,114,84,47,59,91,115,107,76,50,10,103,169,160,114,91,67,63,77,64,83,63,52,40,59,76,70,88,81,93,101,106,105,110,101,107,112,79,82,52,49,21,18,28,43,70,116,54,32,46,33,34,61,59,50,16,35,49,65,51,82,70,62,68,57,84,100,77,102,61,83,47,82,45,48,36,16,40,20,38,14,47,60,82,84,93,85,94,94,115,85,83,87,67,66,70,83,75,103,72,61,38,59,75,81,48,37,57,45,58,51,48,77,65,60,42,63,23,20,6,16,22,25,34,30,50,63,36,57,61,39,29,53,51,62,19,53,37,38,67,56,46,59,30,69,23,42,45,27,36,58,19,49,31,78,99,53,31,22,37,20,25,2,22,29,12,18,18,25,29,21,39,30,25,32,43,29,22,16,17,28,32,25,10,53,3,33,6,23,51,27,54,35,32,30,25,18,25,48,20,32,21,19,19,20,37,15,30,31,9,18,45,33,33,19,30,37,15,24,24,55,74,35,19,26,30,39,8,20,30,37,20,42,15,40,19,5,12,14,20,27,53,38,17,10,27,28,10,40,28,21,34,29,39,42,24,13,43,42,17,31,18,54,30,29,16,40,33,24,41,51,35,28,40,34,34,40,23,4,33,35,24,4,29,16,16,27,16,5,27,14,16,3,14,4,29,31,41,27,13,46,5,15,24,19,71,70,23,11,42,28,65,83,114,67,28,30,0,25,26,20,17,5,29,25,14,37,23,5,29,44,32,3,38,14,29,17,33,18,14,10,4,5,33,33,31,19,26,30,14,39,14,12,26,35,20,36,28,17,31,60,89,105,126,119,114,156,168,135,186,112,45,85,37,55,94,140,167,168,164,120,111,42,28,55,28,39,52,62,62,38,66,70,68,52,53,52,43,57,57,56,41,62,36,45,64,68,50,39,44,33,34,24,37,47,55,52,27,27,50,34,54,49,54,46,72,43,44,25,57,38,54,51,45,36,16,32,9,25,6,13,42,31,22,12,14,21,6,6,0,10,5,14,17,9,18,3,13,28,249,242,244,242,250,251,233,197,205,129,119,112,145,110,94,76,126,133,73,143,106,100,79,108,128,153,174,175,185,179,176,168,190,174,176,165,184,166,191,184,164,165,182,147,180,185,173,159,132,136,127,95,116,160,169,133,145,129,169,123,154,160,151,169,142,173,165,143,151,106,94,53,86,60,108,78,68,80,56,72,81,42,53,82,89,83,74,83,86,137,157,148,112,81,66,71,78,2,35,17,47,40,60,93,54,36,58,14,34,65,31,57,78,117,97,121,171,202,252,247,236,229,228,218,225,208,176,111,78,52,28,3,6,34,28,29,62,93,98,96,133,156,172,199,208,226,183,222,195,188,236,219,134,174,175,145,119,99,109,51,32,13,47,38,31,34,76,108,112,118,148,140,181,159,179,115,145,208,223,230,139,220,182,187,152,138,112,118,83,81,38,38,59,48,46,74,90,93,111,98,132,162,150,184,163,146,114,152,144,141,156,142,156,90,77,86,46,38,47,33,24,15,13,19,42,21,6,22,18,35,41,39,30,10,39,19,21,14,12,8,33,19,0,29,20,20,37,55,52,73,117,136,150,180,165,150,178,185,217,167,154,194,198,183,92,84,169,209,185,158,94,75,204,203,134,117,81,42,39,52,34,42,34,91,69,73,98,115,84,118,83,120,104,119,105,105,72,70,67,15,41,20,65,48,97,132,155,175,192,117,50,25,42,63,30,38,41,57,49,82,78,53,76,52,61,84,75,85,69,81,70,53,84,82,42,68,25,25,17,3,24,30,44,43,66,81,96,104,68,86,98,93,90,83,78,64,96,98,75,48,60,56,52,54,47,49,77,78,48,59,84,47,77,57,50,36,29,20,23,13,17,38,33,43,48,60,53,74,64,52,36,18,56,45,28,47,53,56,39,48,58,28,52,77,42,41,30,26,50,63,53,17,18,42,35,32,106,106,53,19,15,11,39,36,8,27,30,47,11,33,26,25,25,40,26,14,10,42,47,28,8,58,24,8,28,39,34,35,9,7,11,10,22,37,0,17,32,22,33,18,15,15,45,20,10,18,32,24,38,22,53,30,10,30,31,21,47,22,35,30,37,44,140,36,22,14,13,42,31,16,40,12,27,37,28,22,54,21,17,20,29,7,15,47,27,33,22,17,17,21,44,36,15,20,24,31,21,29,42,6,55,15,30,5,30,24,24,7,35,61,21,43,28,31,32,10,32,24,26,20,24,15,2,1,14,36,29,20,5,28,9,6,22,24,23,50,13,20,22,38,14,19,29,33,13,39,65,65,45,35,46,17,25,48,95,99,93,20,18,28,30,12,23,32,31,6,15,17,15,16,18,23,50,5,30,20,5,12,36,45,25,17,24,12,17,18,48,29,28,33,20,31,8,20,21,29,27,21,28,37,46,102,130,115,97,102,120,139,129,107,119,99,106,92,77,56,81,95,146,133,103,126,84,51,41,21,29,32,41,45,71,51,52,34,33,79,45,64,55,56,65,50,44,36,38,47,60,73,60,41,59,50,44,32,46,59,47,68,51,33,53,67,29,47,44,40,41,25,84,41,42,70,26,56,57,48,8,6,31,19,33,31,22,10,53,6,4,19,2,35,22,11,5,18,6,21,5,22,14,45,255,224,242,254,251,245,209,230,189,123,103,107,94,86,55,77,143,180,133,162,175,131,90,130,160,163,169,174,182,183,181,176,180,183,189,173,199,188,193,210,208,174,182,210,203,154,184,162,124,174,119,41,86,123,204,179,126,178,171,157,171,188,153,154,139,153,148,166,171,133,122,141,100,86,110,73,92,46,42,58,54,57,32,6,27,38,41,56,18,14,41,50,91,84,83,115,44,32,2,30,53,39,94,97,77,89,119,81,128,111,134,186,178,211,213,230,242,214,233,201,176,136,111,98,68,52,65,23,18,33,11,32,86,112,71,59,67,91,158,155,184,200,193,171,167,116,126,127,123,134,156,106,105,117,122,87,131,140,127,104,59,19,79,127,77,116,177,210,190,192,200,190,158,182,171,148,149,121,114,122,125,88,101,102,94,71,102,110,110,64,81,25,36,117,148,193,203,185,190,151,177,150,147,140,110,120,112,73,60,34,34,53,31,31,21,15,17,33,18,26,27,46,42,43,18,13,43,16,31,22,26,39,20,51,38,38,57,66,57,49,69,60,61,72,65,72,141,163,168,191,209,191,207,220,184,199,214,214,234,164,162,217,212,175,108,126,165,188,202,170,94,75,184,146,70,73,52,44,41,37,115,118,110,125,137,133,153,123,139,79,116,122,106,74,75,64,59,10,38,20,35,86,105,131,148,129,132,172,173,120,33,42,87,115,69,50,13,64,71,77,40,72,84,55,72,88,83,107,102,119,92,61,59,55,14,0,8,29,36,22,38,79,65,87,62,92,77,83,62,76,86,55,43,44,92,73,55,66,51,68,50,69,83,35,86,79,60,71,47,88,94,67,39,33,42,26,14,46,21,10,27,7,23,53,25,41,36,39,45,23,51,59,68,70,42,49,22,53,65,55,58,62,52,39,46,41,36,40,41,35,48,25,66,18,13,32,53,82,112,43,12,30,16,4,43,27,45,43,22,33,13,19,44,31,13,45,43,42,24,35,21,40,1,23,49,25,34,19,39,38,29,34,22,14,49,41,34,54,38,21,24,22,31,26,38,28,23,5,39,44,34,44,37,18,32,30,43,33,31,30,24,65,95,79,9,18,5,27,24,30,20,26,36,18,19,6,23,36,5,42,18,29,26,13,8,20,11,23,76,45,29,11,39,20,49,26,17,49,6,44,30,20,36,22,32,35,29,21,28,41,29,11,10,61,57,20,33,38,6,33,32,21,27,29,19,2,14,51,29,22,29,37,26,36,21,10,27,29,6,20,31,8,13,21,22,25,63,90,22,42,2,25,8,46,88,104,87,78,44,22,1,14,19,23,34,16,15,26,21,36,32,33,43,50,55,7,18,2,15,7,19,20,24,51,7,28,76,11,46,8,65,35,17,21,14,22,30,28,36,24,27,88,92,107,56,83,90,99,86,50,74,104,120,95,77,81,87,83,91,57,77,94,88,98,60,70,81,70,123,97,110,56,110,113,105,82,88,59,82,105,98,58,81,71,83,74,104,88,61,62,73,74,52,21,59,79,94,90,96,105,96,73,64,65,84,89,84,119,89,83,86,62,47,74,66,65,48,16,14,2,47,5,18,30,8,6,8,18,14,24,7,4,6,10,14,30,11,20,15,43,241,252,250,244,244,244,221,212,170,108,126,132,145,104,86,102,138,128,110,114,132,70,73,71,115,127,137,120,123,97,135,113,127,115,145,153,139,140,134,131,125,101,148,122,157,132,160,138,43,72,28,0,3,74,96,101,65,88,106,123,125,114,148,116,92,121,120,131,102,112,105,118,97,87,81,89,61,59,28,37,47,41,54,51,46,82,104,105,75,80,94,60,136,102,110,144,92,19,39,54,132,129,170,161,160,174,221,195,189,207,205,210,220,213,141,212,129,109,65,41,42,32,37,34,7,8,49,65,55,41,36,59,162,187,95,41,19,54,85,155,147,126,128,81,25,32,52,24,43,77,66,75,118,122,127,121,181,159,199,171,67,63,167,171,123,140,190,169,148,107,119,85,63,56,22,2,0,7,13,28,125,72,90,135,145,175,200,217,192,163,103,55,70,114,111,140,84,97,49,67,47,27,25,25,13,14,57,10,31,23,12,14,28,34,13,3,48,1,23,31,11,43,45,46,32,19,14,26,25,57,28,38,35,56,112,152,162,198,245,228,227,248,205,217,123,150,231,232,240,222,209,179,207,220,197,192,215,198,206,133,121,188,164,187,176,183,186,205,153,136,71,23,90,117,98,91,97,90,95,108,111,128,134,143,120,135,134,125,111,95,100,53,25,35,36,8,52,49,62,78,130,130,140,119,126,134,127,127,83,32,5,9,94,94,71,72,53,54,78,52,81,78,64,89,87,84,58,90,122,126,58,36,34,32,26,24,26,30,33,61,59,69,69,43,76,78,54,54,79,42,74,78,79,72,45,45,58,52,47,48,67,43,50,69,60,54,46,45,56,55,59,23,15,13,32,21,2,47,5,30,47,36,51,33,58,24,43,32,51,66,51,34,52,58,58,49,57,43,18,59,32,76,54,50,22,46,27,47,50,48,57,54,31,27,45,43,38,45,91,95,31,43,46,11,5,43,34,33,28,26,21,33,27,39,10,30,25,26,10,37,33,46,10,26,27,12,18,56,20,30,37,27,19,28,12,44,45,40,39,23,44,21,32,38,14,29,12,31,55,16,31,6,31,42,19,26,23,18,38,36,62,32,75,76,35,49,39,16,31,18,54,44,58,28,30,8,19,17,18,17,35,20,23,41,18,18,30,29,46,35,17,35,7,21,33,32,5,38,28,50,40,20,40,38,18,19,35,39,26,38,38,29,28,8,28,7,26,36,0,34,25,39,31,27,36,36,24,27,34,26,15,25,27,45,17,20,26,39,8,53,35,16,21,45,25,47,97,82,13,17,4,20,17,28,25,60,112,122,72,41,0,13,5,14,29,12,10,27,44,15,17,8,30,11,27,13,20,40,12,15,22,30,58,35,44,42,24,10,37,22,16,42,19,24,24,8,13,34,21,27,38,55,139,132,110,104,123,141,73,91,105,102,118,142,101,99,79,101,90,73,84,83,83,109,127,122,130,138,132,141,151,148,150,149,129,169,134,103,117,129,115,104,100,95,117,108,120,105,95,56,94,66,81,103,84,112,127,139,113,169,134,133,146,137,140,161,144,159,153,155,163,120,110,125,137,100,12,3,10,2,19,19,19,20,5,32,12,9,7,17,27,7,13,32,20,3,9,20,22,1,250,249,247,230,238,238,223,221,170,120,144,118,162,146,162,206,132,50,15,4,22,51,17,20,31,20,25,37,58,36,23,23,55,51,21,18,58,37,52,55,41,40,28,57,26,76,123,106,48,41,41,42,45,33,23,23,37,35,21,31,55,33,44,42,54,52,32,44,67,47,51,44,55,53,68,44,25,24,13,34,118,158,175,168,160,195,195,191,175,160,198,171,169,155,151,157,174,168,207,233,220,239,230,220,209,236,210,188,149,120,106,114,82,66,103,67,36,48,25,7,10,43,74,57,29,25,54,62,53,48,42,110,229,251,212,120,25,10,28,51,32,25,40,36,27,34,42,46,60,40,14,64,74,90,75,80,69,63,80,74,18,31,85,83,49,53,49,52,48,31,30,21,38,46,85,82,119,129,107,152,134,151,159,185,139,184,153,126,119,64,66,60,29,34,12,28,8,30,40,11,22,24,28,55,18,43,28,29,29,15,45,10,37,32,11,24,13,62,28,23,53,43,28,50,9,7,17,32,36,65,69,67,109,132,150,174,165,199,195,196,191,175,203,146,106,123,165,156,197,143,159,158,169,149,121,164,168,153,154,101,92,136,140,154,160,156,160,139,96,62,54,38,108,122,150,65,65,68,67,75,115,87,84,98,70,61,99,82,62,40,46,30,30,54,54,48,68,86,115,133,149,141,139,132,144,134,132,79,19,22,62,92,63,64,74,89,81,77,50,54,68,44,40,69,106,108,86,121,69,60,36,30,18,39,28,36,67,80,79,66,67,62,57,71,57,82,67,83,58,62,81,66,72,74,50,43,74,35,56,37,51,42,56,94,79,63,67,25,66,20,11,43,15,11,15,9,47,31,65,34,58,32,41,53,64,15,57,50,73,57,46,51,41,40,61,43,30,47,44,32,46,59,55,65,65,36,30,45,44,27,82,42,55,42,50,37,57,38,113,110,66,31,21,35,36,38,40,22,18,14,25,34,14,23,23,35,37,37,22,20,29,13,22,24,26,47,18,36,26,13,22,12,47,25,20,50,17,12,23,11,37,16,57,43,10,8,12,18,16,37,52,11,3,39,51,31,18,51,47,23,21,31,56,82,88,34,2,33,34,25,26,44,39,51,7,12,42,51,27,6,21,37,33,32,19,48,32,6,29,23,30,17,16,33,20,15,26,61,38,33,48,20,24,41,17,22,23,25,23,28,48,23,31,22,23,23,31,14,36,12,12,23,38,29,24,32,13,31,25,20,24,36,13,6,30,11,51,2,22,18,28,41,11,10,44,32,101,24,27,23,12,20,40,15,21,14,40,112,105,90,40,32,14,15,42,25,22,11,33,23,5,9,36,15,20,0,13,49,24,27,42,38,17,14,41,31,17,18,14,28,50,15,20,16,40,34,30,14,18,24,48,59,85,126,110,142,151,162,170,142,162,130,146,120,141,131,129,139,110,124,148,118,154,155,128,115,137,150,177,150,136,120,146,167,183,152,141,124,111,98,109,116,109,124,98,134,112,120,113,114,104,138,134,122,109,140,156,174,176,162,192,164,150,177,191,160,166,208,193,190,165,150,148,172,191,93,28,3,22,12,14,3,0,5,9,3,23,30,5,0,6,18,23,22,12,8,20,30,7,3,253,248,248,225,230,249,226,215,159,98,168,122,147,112,156,167,91,27,15,41,34,61,32,23,29,13,21,32,43,20,22,22,27,44,21,29,28,17,19,27,42,35,19,32,80,80,77,45,35,59,33,45,34,29,41,46,20,16,8,25,25,41,51,20,32,68,22,33,45,44,24,45,52,69,88,58,69,70,105,109,175,253,223,242,224,224,203,195,177,187,210,207,203,185,191,229,219,218,228,201,211,175,180,168,92,111,78,92,122,117,85,41,12,25,32,20,7,88,64,45,74,52,55,44,46,43,23,45,44,24,63,148,242,252,233,197,40,4,32,2,47,17,34,19,19,36,35,50,47,42,32,28,51,34,39,19,32,51,47,53,47,48,27,57,54,101,63,88,89,102,128,101,144,123,144,135,68,141,155,129,95,72,43,26,18,45,45,25,25,13,27,44,53,26,28,59,32,38,40,23,16,39,30,17,23,33,25,27,48,21,23,26,18,40,19,27,9,50,34,29,19,18,31,38,27,16,21,28,39,25,28,38,23,19,40,27,26,30,52,24,20,43,27,50,27,57,10,41,46,43,17,55,55,33,36,64,32,50,34,41,54,63,52,84,46,30,19,41,23,38,47,57,21,47,44,46,41,49,35,47,24,56,26,43,17,71,24,49,33,60,66,35,61,77,103,131,133,157,140,110,108,124,111,141,136,138,119,108,81,79,131,92,67,78,59,69,61,82,59,69,73,71,89,93,86,112,97,23,64,36,27,14,24,35,76,101,73,86,83,70,96,49,64,44,39,51,81,79,56,49,52,72,59,65,59,47,50,69,43,63,82,66,52,77,55,88,55,32,17,22,7,24,36,19,30,31,36,31,33,42,61,65,33,52,58,33,47,51,38,40,47,51,27,65,35,71,43,27,46,36,41,29,27,68,43,77,51,31,58,45,33,17,63,36,46,32,36,10,23,72,86,89,60,5,19,26,31,21,37,32,18,32,26,15,26,10,10,47,53,19,46,26,14,24,24,42,11,34,32,39,23,36,5,32,6,33,6,4,25,13,52,21,32,19,37,38,44,43,40,8,30,44,10,21,37,28,62,35,34,17,41,55,46,102,93,25,5,43,37,21,29,31,28,2,32,43,38,17,21,28,20,17,26,46,46,43,23,20,29,53,30,35,10,18,35,26,37,22,46,43,26,35,17,55,20,33,35,35,57,25,28,36,31,35,24,49,28,28,24,36,16,11,27,9,21,44,29,19,29,20,7,48,20,13,30,25,14,30,28,10,28,41,34,33,22,56,70,20,31,16,29,34,13,27,20,9,39,52,104,101,59,54,18,10,10,6,27,33,53,27,27,26,3,13,25,24,18,25,15,18,27,16,22,27,25,31,35,7,18,41,30,28,8,16,37,18,9,25,45,34,27,85,82,70,62,94,162,179,178,200,197,189,150,198,170,155,175,150,161,158,178,198,172,162,194,157,167,172,154,166,153,142,171,160,140,132,132,134,107,124,124,119,106,129,129,127,128,156,142,123,130,136,138,130,153,128,152,167,158,172,158,174,180,158,170,191,187,207,156,177,201,166,169,169,190,125,7,10,0,10,20,3,12,2,20,0,16,10,20,12,8,8,5,10,4,0,37,8,11,34,250,249,248,249,241,235,225,213,146,115,175,140,151,76,56,56,24,21,22,22,48,39,46,31,33,40,56,45,23,14,33,12,31,18,25,38,32,43,23,48,41,9,41,39,69,85,40,45,23,27,54,43,46,53,41,66,59,60,38,39,46,57,69,57,49,46,32,58,103,110,86,102,165,131,147,157,162,175,222,218,229,237,230,217,177,156,150,131,147,160,167,142,138,153,156,145,129,129,106,77,64,47,46,25,25,12,40,74,144,124,77,79,35,30,24,41,34,56,41,46,30,30,48,54,36,40,32,66,68,25,83,153,243,233,236,225,92,16,2,24,40,31,44,46,67,61,48,64,56,49,65,60,63,53,64,75,110,85,116,136,92,64,99,123,123,142,140,151,166,147,142,106,89,63,74,19,58,19,31,26,27,20,11,27,29,23,29,5,40,28,42,5,48,43,52,24,46,55,36,30,29,29,23,53,59,50,38,29,31,20,42,31,27,21,51,13,18,23,53,29,23,18,21,26,18,29,23,30,18,17,29,31,45,4,14,24,36,56,31,28,23,24,19,24,50,60,22,28,14,3,19,12,21,27,24,37,24,32,32,28,55,45,58,34,29,27,7,31,43,41,62,46,29,33,14,27,29,47,40,31,29,45,32,54,56,68,68,68,71,89,114,106,106,132,113,146,111,122,137,126,109,98,117,114,119,131,136,146,121,92,78,52,58,95,84,91,82,62,85,70,112,112,93,107,62,46,31,9,17,10,12,27,60,75,99,86,108,118,102,96,93,78,63,85,50,55,80,67,63,83,73,51,56,58,47,70,61,58,48,44,69,70,58,55,37,25,37,22,30,42,27,19,54,15,51,33,43,50,61,51,65,52,69,54,57,54,65,50,47,50,29,36,32,58,40,28,31,55,49,53,42,37,35,66,28,33,30,54,36,33,48,66,63,14,31,47,67,58,45,49,83,140,75,25,23,5,21,25,8,27,19,4,18,27,27,13,15,41,67,15,36,29,11,34,27,26,43,31,26,25,30,45,47,24,2,29,39,19,42,34,29,31,26,25,52,39,27,24,20,9,9,19,45,14,14,15,25,16,23,26,27,44,32,73,63,54,34,29,19,20,63,18,21,44,35,37,33,6,14,17,41,24,14,29,23,10,2,43,26,36,48,25,19,26,9,36,14,38,21,15,31,13,33,31,55,19,36,29,47,41,49,28,52,14,56,15,33,32,8,30,24,13,22,33,19,26,36,45,18,11,14,12,40,38,30,9,6,35,43,17,12,37,15,7,11,71,61,7,36,19,10,16,38,46,25,7,32,27,69,82,93,74,39,17,34,40,30,23,18,17,23,22,8,21,13,32,39,47,17,29,33,41,16,13,42,11,35,31,13,14,37,22,37,12,42,14,29,26,13,44,71,74,92,124,96,69,128,202,178,209,191,196,203,181,177,197,170,173,149,176,198,197,199,195,180,179,173,180,179,170,168,176,164,175,160,180,169,169,171,146,146,136,168,157,152,155,163,170,168,152,176,170,163,160,177,141,152,170,166,184,170,202,182,183,169,161,164,167,189,170,183,154,186,185,188,105,12,1,13,3,21,6,7,13,5,2,15,15,2,17,27,13,44,32,22,7,18,10,11,40,250,255,250,229,224,238,224,214,141,147,154,194,205,84,21,24,33,32,44,31,54,32,50,37,21,41,23,28,50,30,24,41,26,25,24,44,46,64,51,49,36,50,27,57,60,72,85,51,51,41,38,37,38,48,34,82,85,112,105,166,135,142,162,147,196,182,209,196,219,191,226,181,205,227,204,221,222,229,203,198,163,169,168,164,145,148,171,138,99,137,118,120,116,84,13,85,11,30,8,33,26,24,32,41,34,19,61,63,75,52,60,47,42,86,141,129,91,65,30,18,35,39,63,61,56,30,55,80,28,62,132,152,178,162,182,159,99,64,31,35,52,52,55,47,50,112,87,120,97,120,164,170,163,144,143,124,146,149,139,119,65,32,48,71,89,50,37,59,39,32,34,44,15,11,38,17,27,22,15,53,3,33,17,24,38,20,32,37,45,28,41,29,7,33,10,30,7,50,45,30,15,23,4,23,14,28,12,17,16,19,17,36,36,19,14,36,31,19,59,36,24,28,37,40,18,19,14,22,40,6,24,29,31,24,6,27,0,30,7,37,27,24,35,27,45,51,14,14,0,17,5,56,38,26,30,52,32,47,46,37,24,13,37,47,51,12,8,13,31,7,58,35,15,31,44,36,40,56,33,58,60,43,97,98,108,115,77,115,137,126,82,110,123,148,118,95,98,102,120,127,102,121,100,133,123,119,123,99,59,67,45,48,72,55,62,71,70,107,89,116,103,97,57,50,29,32,17,31,19,58,94,104,97,75,109,131,82,97,86,78,79,70,92,89,79,81,77,71,64,70,89,61,46,40,67,58,31,94,35,69,83,44,66,26,18,18,12,30,11,23,30,22,46,60,48,34,63,69,56,41,42,75,63,41,59,70,49,38,30,35,43,45,31,29,51,63,35,40,29,49,55,42,41,22,57,42,58,43,37,30,62,39,35,42,44,35,39,31,54,37,36,72,99,73,28,18,28,25,26,30,40,9,38,26,19,32,21,15,37,54,37,31,34,21,23,40,36,32,33,15,58,8,19,26,23,26,18,62,36,20,39,16,47,44,34,18,39,31,36,26,34,10,57,37,23,47,20,40,31,22,28,36,18,61,98,42,32,21,25,36,27,31,18,38,26,45,24,12,36,22,40,27,25,21,30,13,26,36,40,12,20,32,23,42,35,38,44,34,14,45,44,36,35,23,28,23,23,41,9,31,41,27,26,28,35,46,12,9,31,21,54,53,5,39,33,20,25,11,20,31,15,15,36,27,33,21,12,7,37,15,23,23,23,15,48,83,35,11,43,28,18,19,25,17,18,38,28,20,33,51,97,84,76,27,44,31,6,22,10,15,29,33,31,6,31,11,24,38,8,25,15,47,30,46,17,26,26,24,29,22,18,34,18,25,23,21,24,28,36,95,83,105,135,186,154,87,64,108,163,176,207,186,195,190,179,167,205,210,205,183,187,172,183,168,182,184,198,183,186,172,202,169,178,209,187,182,176,157,175,199,194,188,185,185,197,204,146,170,169,194,188,190,186,186,181,190,176,195,165,170,178,179,173,175,180,210,181,187,163,160,166,145,166,180,166,114,17,7,6,31,13,13,25,2,18,0,22,4,8,7,16,9,24,22,7,41,18,35,16,37,244,254,248,244,237,229,215,191,98,130,156,212,210,61,24,33,29,55,29,46,31,32,52,51,10,46,33,48,29,59,53,42,34,25,44,33,59,40,75,58,70,56,66,39,51,128,109,85,82,100,140,131,156,156,180,215,235,206,200,216,234,244,235,203,231,234,229,221,229,221,200,170,167,154,128,135,103,109,71,38,79,33,41,74,144,169,196,169,106,95,93,124,80,45,0,25,31,34,58,38,90,39,45,37,36,62,60,59,57,39,37,71,84,188,255,246,204,129,26,34,63,99,34,37,39,34,53,58,79,168,191,141,86,61,71,91,57,92,90,120,162,112,145,135,140,171,163,130,153,138,112,111,126,100,72,45,26,53,22,48,18,34,48,6,69,19,19,50,29,34,44,40,47,43,41,34,49,19,39,35,25,40,62,51,46,38,45,84,36,51,50,45,31,43,51,50,43,57,48,36,45,66,52,38,42,19,46,61,53,52,61,68,50,51,50,53,22,37,58,42,32,49,43,58,47,33,31,47,37,27,62,44,41,34,66,45,54,32,55,42,58,52,38,66,61,55,8,35,19,56,35,39,40,70,50,38,36,42,33,42,47,25,40,16,14,33,20,45,16,53,75,36,36,25,50,47,77,50,33,53,42,68,98,96,109,89,86,99,83,106,102,106,111,111,108,108,108,90,73,113,97,98,136,115,110,103,63,69,46,50,37,52,76,84,57,58,78,91,70,55,58,26,34,24,26,27,7,73,74,88,118,103,111,115,112,84,91,67,75,101,94,62,77,95,71,68,78,63,53,68,69,83,79,67,58,66,73,49,63,54,57,35,21,15,26,24,26,22,51,47,41,34,51,37,56,62,60,41,57,55,45,44,73,39,62,72,43,36,56,53,59,38,35,35,76,25,51,41,19,37,18,48,39,50,42,23,23,47,32,70,34,45,33,60,25,48,58,24,39,44,31,30,87,100,66,33,8,34,39,53,68,31,19,5,39,21,29,35,7,0,26,21,43,44,28,29,38,42,31,54,46,16,35,21,19,46,18,26,8,46,38,30,21,35,31,47,20,5,28,60,49,22,26,20,8,53,18,41,51,52,7,35,11,42,91,63,57,7,20,27,12,33,37,38,25,54,11,35,29,34,38,42,26,34,16,27,38,27,36,30,20,10,37,47,42,16,37,9,31,44,23,18,55,30,23,33,14,46,20,42,32,30,44,20,63,21,33,29,17,14,41,25,18,31,32,33,49,24,13,19,6,17,46,38,14,8,32,2,40,33,35,4,34,12,57,102,37,26,52,17,35,31,22,34,16,1,34,22,15,12,88,98,116,34,9,15,26,25,23,17,30,49,9,53,25,48,30,20,7,0,36,10,6,5,34,32,20,29,31,20,11,56,27,19,22,31,25,27,142,159,98,72,59,123,138,62,20,44,82,146,178,197,200,197,155,148,220,249,229,203,177,179,179,190,168,174,169,178,167,170,170,173,173,194,193,177,188,211,207,188,204,195,200,189,202,200,197,175,186,190,199,181,167,194,213,171,184,179,174,187,188,175,183,173,211,204,188,177,207,197,212,171,175,189,184,96,10,3,14,13,9,0,7,4,1,11,9,21,27,15,28,19,23,23,13,15,9,13,12,10,252,251,229,244,230,221,210,166,41,49,133,197,196,63,6,11,25,44,36,54,30,56,31,50,48,30,45,51,61,52,60,75,61,106,69,93,83,98,113,123,147,166,165,203,175,205,222,227,221,233,215,235,233,244,225,235,225,235,219,221,212,211,209,177,162,175,127,98,119,107,117,108,100,80,52,71,59,46,20,22,9,7,8,62,101,147,137,124,109,77,98,92,97,77,8,11,54,34,16,41,58,45,37,42,22,73,101,115,134,91,86,86,148,250,252,246,241,148,30,30,94,100,93,58,33,46,70,79,112,157,169,88,55,49,42,41,47,130,135,84,145,93,130,82,89,66,49,46,32,38,69,23,42,16,34,5,13,38,29,38,4,48,37,46,15,27,22,17,19,31,39,63,19,22,48,47,62,31,30,57,54,92,86,137,146,175,198,181,224,184,191,192,171,176,193,192,193,191,174,163,200,199,194,188,206,194,184,159,190,188,202,217,201,208,212,200,193,138,180,210,209,190,204,120,78,73,88,128,176,175,190,184,176,185,199,190,158,177,178,214,212,213,195,187,176,86,36,14,44,88,139,160,134,160,156,157,141,149,152,159,153,155,163,146,130,97,108,111,121,133,132,100,81,92,89,126,131,63,51,37,32,53,92,101,93,78,61,72,76,121,58,73,110,95,81,72,101,96,117,114,107,56,76,47,55,49,35,37,31,43,45,49,74,63,66,45,65,56,55,52,38,11,48,21,33,32,60,93,92,84,77,108,89,120,91,102,82,97,87,66,91,87,91,78,61,63,67,90,103,57,86,78,61,74,63,66,62,52,49,39,22,11,44,5,14,18,37,73,59,31,32,42,61,55,48,59,44,64,12,58,67,70,25,66,31,39,45,50,37,47,58,17,40,30,41,18,39,38,54,34,63,50,45,49,29,37,55,47,29,53,60,19,46,27,17,48,38,82,22,7,38,26,12,86,73,74,9,13,45,45,61,13,16,23,7,22,19,12,36,42,19,7,48,23,48,25,29,39,27,18,19,61,10,15,22,34,9,29,29,32,1,18,36,23,83,37,11,31,23,52,43,28,20,38,41,28,31,28,25,24,14,41,23,15,97,82,45,30,15,30,20,47,22,25,22,10,23,7,32,36,30,19,27,9,25,6,22,19,37,40,21,13,23,48,19,33,10,13,24,34,42,8,19,40,34,55,37,39,53,40,52,63,35,34,42,21,31,40,22,11,20,28,50,26,24,50,5,24,33,37,28,10,6,18,23,0,21,38,31,22,16,28,23,31,82,82,36,24,14,19,20,30,12,4,26,15,14,10,22,29,30,59,90,94,56,47,19,28,8,31,26,14,30,16,28,37,39,5,14,31,41,31,13,13,53,41,26,12,34,33,4,19,10,12,8,36,24,69,169,172,112,106,47,38,38,8,42,4,37,117,124,148,156,208,192,209,244,255,204,186,208,171,207,186,181,173,182,179,162,186,186,157,162,188,183,174,159,179,191,193,190,188,167,146,172,165,175,186,155,190,174,171,195,181,200,177,189,203,191,183,174,196,165,180,180,176,193,189,184,183,193,157,196,192,168,108,32,5,19,32,7,20,21,10,2,19,15,0,21,8,13,8,19,29,20,0,8,9,9,19,251,255,243,221,223,236,220,186,43,81,138,210,212,38,20,17,21,39,57,73,52,35,49,45,45,60,61,91,111,129,132,149,160,162,182,164,179,222,218,226,217,231,219,217,233,233,218,226,207,211,211,184,201,182,139,150,97,89,71,73,50,63,43,39,26,33,12,32,64,66,118,159,163,87,63,84,52,80,50,70,44,11,31,28,87,155,131,116,82,116,112,144,106,44,22,47,73,68,24,45,59,67,60,43,31,81,110,103,110,82,85,135,191,238,238,238,231,160,43,14,53,148,139,123,48,64,149,145,121,63,48,81,68,66,43,23,37,54,30,22,25,28,41,37,37,14,14,15,21,7,16,12,4,52,35,30,38,33,46,28,35,34,46,52,17,34,68,45,41,38,71,44,56,101,108,117,167,178,197,187,203,222,209,223,245,240,239,249,242,218,221,230,202,237,255,237,215,214,217,236,247,250,229,247,239,231,237,225,223,243,250,244,246,230,237,231,255,249,242,221,207,204,167,78,119,139,219,227,238,247,209,238,240,237,242,242,249,248,238,227,228,199,173,122,78,94,131,196,206,219,233,240,225,239,226,245,233,242,231,216,237,202,212,229,227,178,173,177,194,223,233,194,143,141,140,99,119,145,60,75,55,77,101,74,79,72,73,50,65,61,67,56,76,98,88,81,86,100,117,87,50,49,53,39,64,19,36,39,13,40,59,52,79,43,67,57,58,49,19,26,16,18,27,54,74,91,90,107,98,107,75,84,102,74,95,72,98,72,75,88,70,67,60,45,45,68,94,80,76,69,46,66,61,72,77,49,102,46,32,31,38,8,9,44,39,40,47,54,67,55,57,47,57,54,55,42,54,61,50,56,64,48,71,55,45,42,48,53,30,36,52,59,32,58,41,28,17,49,50,46,55,40,55,40,45,43,34,58,44,38,58,50,52,48,29,37,52,33,34,54,75,13,46,15,82,122,63,53,25,25,63,22,13,9,11,4,13,2,13,20,19,9,26,15,0,22,37,13,25,23,8,17,22,30,45,9,45,26,6,45,18,23,12,26,59,26,27,18,48,30,20,16,32,35,12,15,43,47,36,42,18,46,20,12,69,95,24,25,34,29,17,19,33,26,20,33,27,26,39,44,27,22,25,41,22,14,19,47,34,5,15,50,19,32,32,38,32,42,54,45,32,37,18,37,55,36,33,30,30,23,35,40,12,46,32,25,53,11,26,33,39,14,32,28,18,38,39,16,26,49,31,16,31,18,2,22,23,28,15,23,9,22,9,26,56,83,15,37,28,19,40,9,31,25,31,64,24,20,17,8,31,15,77,102,68,78,23,20,25,39,31,33,9,17,19,30,34,24,33,23,28,13,14,10,49,7,23,22,20,22,23,32,21,11,28,28,15,91,184,146,157,176,144,120,79,63,41,43,82,147,125,119,161,208,156,177,207,180,113,145,146,165,164,137,165,151,167,160,182,181,152,146,138,169,160,139,173,169,164,167,148,163,131,142,149,171,143,153,189,160,180,183,179,188,171,185,174,189,162,171,175,182,172,181,180,178,166,194,160,198,162,153,194,183,167,113,13,19,2,2,33,13,3,42,12,9,4,6,21,3,21,19,17,16,15,14,14,7,34,14,235,255,237,248,233,248,223,169,77,86,136,197,247,76,82,77,82,130,121,161,151,147,184,171,175,212,217,202,230,244,240,209,215,162,226,216,210,194,203,180,165,139,141,144,158,93,38,108,110,103,66,38,26,11,23,6,23,31,9,60,18,33,43,22,34,50,33,35,25,58,104,137,102,57,62,83,63,95,108,133,158,127,113,63,106,157,145,122,97,122,107,124,114,32,0,61,133,157,146,137,173,151,96,36,9,23,48,45,25,43,117,135,153,181,219,196,193,126,15,5,70,144,119,108,35,70,121,113,53,37,25,44,80,18,38,20,4,41,4,38,40,33,16,19,25,19,26,40,20,44,11,55,47,56,30,49,74,64,50,44,67,68,64,53,48,90,108,134,162,171,181,208,221,212,225,221,231,235,233,228,198,209,204,175,150,158,163,155,186,193,179,192,184,185,180,164,165,158,185,205,195,169,165,183,198,201,205,197,203,171,190,187,201,213,215,214,202,203,197,75,68,98,120,157,179,224,212,193,195,216,209,215,237,250,227,199,181,157,114,74,58,26,90,110,174,168,208,226,216,246,213,211,193,211,180,193,205,197,171,190,196,217,182,205,175,166,120,119,147,181,169,185,190,142,123,84,93,106,82,78,97,121,119,78,81,74,59,74,72,71,81,91,104,78,98,91,115,89,81,84,54,26,45,53,37,69,54,67,68,113,52,42,47,84,47,48,46,17,30,10,31,70,68,74,110,102,109,133,108,74,101,76,77,60,69,88,84,63,91,59,101,49,61,59,86,81,84,94,55,61,86,43,76,69,53,39,48,21,20,24,57,10,31,53,57,29,61,51,42,60,50,47,58,37,45,38,66,50,55,40,56,53,58,61,51,65,52,75,47,56,36,43,64,29,37,40,35,48,32,32,40,21,44,36,55,44,31,37,56,26,28,38,48,43,44,33,46,58,40,49,13,33,32,10,48,85,120,91,36,9,16,29,9,15,27,26,9,32,27,22,25,31,23,35,27,33,23,40,7,35,31,37,27,36,26,28,4,9,30,16,35,41,35,13,27,28,14,30,14,16,29,13,40,35,30,31,32,23,10,24,32,42,31,29,75,72,55,32,25,14,26,33,17,3,20,32,52,49,30,23,25,28,24,14,34,24,30,9,16,28,27,23,38,25,13,7,47,8,58,31,30,90,17,22,55,19,52,47,41,37,38,45,45,26,23,38,30,41,44,43,36,31,13,10,8,11,11,31,48,18,19,29,27,7,19,28,36,27,18,22,37,15,1,10,95,60,23,27,25,27,14,30,21,24,20,24,19,35,38,20,22,20,42,39,109,98,26,41,26,16,21,8,18,14,39,27,21,27,13,38,30,22,36,36,14,20,19,34,36,14,22,29,31,21,45,1,43,179,188,192,201,214,203,225,204,161,131,138,96,100,82,53,93,142,150,142,177,161,118,157,136,156,148,157,169,159,146,145,143,136,128,115,121,154,132,131,127,122,137,119,166,131,160,127,116,143,146,143,157,142,125,154,137,134,143,152,150,163,172,193,169,163,200,189,178,158,160,171,168,161,176,187,206,175,174,117,2,1,4,17,23,13,22,17,13,15,28,28,33,9,22,8,24,15,36,18,8,33,9,26,244,240,252,251,241,246,217,206,118,129,182,247,243,150,181,188,184,224,195,214,235,242,233,212,225,237,197,226,194,217,199,192,170,133,109,120,113,92,95,64,79,70,99,65,58,43,2,31,10,7,39,24,58,25,47,60,31,45,33,50,81,55,55,34,24,32,33,32,56,74,30,29,26,53,21,68,42,61,97,143,198,240,219,130,187,175,200,220,187,169,204,226,230,145,18,86,178,223,240,216,203,205,152,83,31,68,74,85,53,87,133,142,93,81,122,136,109,63,29,19,24,60,61,54,33,41,75,47,70,37,61,75,33,16,5,14,20,26,31,28,25,37,41,49,59,48,61,54,76,80,49,62,131,136,92,90,75,114,147,166,180,180,204,228,203,222,213,240,245,236,251,239,233,212,212,207,213,192,199,183,184,175,175,175,170,150,146,163,181,144,155,156,148,136,167,151,168,177,147,146,150,131,137,146,177,162,168,171,164,153,161,165,194,198,171,107,111,104,57,38,68,145,186,198,190,184,181,173,203,199,181,190,172,136,100,64,23,38,76,99,131,199,167,197,182,209,217,201,178,191,161,153,170,131,170,173,150,157,180,180,179,158,156,201,169,141,104,103,82,107,99,115,102,103,80,92,110,105,79,99,101,173,115,109,97,102,116,103,89,72,77,70,76,89,79,96,64,85,44,42,52,53,76,53,40,26,32,64,133,93,55,52,44,46,3,18,10,26,48,47,68,94,108,80,103,108,97,98,78,91,80,74,86,70,50,70,69,65,58,85,73,58,59,106,69,104,55,52,93,92,59,98,81,57,21,12,19,23,35,36,19,38,35,53,36,58,59,54,53,24,69,38,42,62,26,43,43,71,64,46,58,41,45,35,45,42,44,40,51,67,25,58,66,50,23,57,74,47,36,28,25,48,27,41,37,32,39,37,42,38,43,38,51,34,16,36,34,51,46,35,53,38,48,38,13,42,83,102,74,65,19,12,15,28,21,20,34,40,19,26,42,34,6,31,51,11,31,11,45,29,23,25,25,29,23,37,2,11,36,32,18,20,30,38,34,29,21,32,48,61,36,35,25,37,41,39,13,41,21,5,18,38,7,12,55,83,81,33,27,27,21,11,25,29,30,37,35,32,22,39,5,20,36,15,29,18,32,62,35,8,29,21,20,49,39,18,32,32,35,35,54,73,58,28,25,41,44,19,21,28,28,19,36,26,23,17,17,5,16,10,21,32,22,31,5,54,15,12,31,30,15,18,9,12,11,19,16,20,42,27,37,7,34,30,87,42,25,41,15,17,26,5,23,16,49,35,13,7,30,30,14,32,28,40,90,117,86,39,18,12,22,20,49,10,18,48,26,10,27,26,41,17,23,20,22,46,33,45,14,33,45,30,28,31,61,27,139,192,241,250,212,187,174,202,190,185,197,164,122,98,65,26,12,45,69,94,170,192,213,228,226,175,159,179,162,182,149,162,170,170,143,178,148,148,165,156,159,155,145,151,145,169,144,135,159,134,102,117,123,129,154,134,122,114,114,129,152,121,130,135,133,150,156,142,155,153,175,159,149,166,192,167,175,159,145,98,23,4,0,13,7,8,25,1,10,13,8,1,21,12,37,6,33,9,60,31,5,12,22,27,233,230,247,235,238,242,242,205,161,196,180,198,208,148,180,205,187,198,184,160,151,122,163,125,131,131,97,90,69,97,77,85,124,112,111,105,109,120,117,105,144,128,127,139,159,122,62,25,1,31,24,83,91,101,90,97,102,78,96,75,65,59,70,55,39,31,28,43,97,73,94,77,45,77,26,35,19,36,50,152,217,224,242,250,233,244,243,228,238,249,248,244,241,185,20,25,149,177,161,119,103,94,69,34,29,50,156,182,168,153,119,84,50,20,13,10,3,13,27,18,34,48,32,56,24,38,45,53,53,37,80,37,32,49,36,46,62,47,79,68,89,112,139,127,163,176,202,218,245,208,95,107,229,209,216,234,240,219,242,225,238,225,245,225,221,203,227,198,199,194,175,171,173,192,193,174,172,179,187,178,202,197,204,172,152,154,169,174,156,152,186,189,168,164,164,151,170,200,166,178,153,165,150,170,157,161,180,143,193,175,196,187,181,152,78,31,50,92,165,141,180,202,234,226,197,190,178,156,101,124,112,64,46,36,70,90,135,165,160,178,205,208,226,190,175,183,175,177,167,169,163,177,180,188,156,151,144,160,166,172,170,154,163,179,161,145,103,121,92,79,62,33,5,56,68,36,55,57,47,106,124,141,162,130,126,135,121,122,101,105,100,101,66,101,97,101,103,88,112,78,74,76,70,84,64,78,49,54,64,59,37,30,47,38,26,19,42,47,71,80,105,119,101,67,95,91,110,79,74,85,80,56,86,94,77,91,79,72,59,61,65,66,94,66,63,60,60,80,60,105,62,42,18,34,19,6,5,25,26,60,53,49,55,37,50,41,84,57,37,50,69,47,33,74,53,51,38,44,50,63,49,29,68,54,50,25,26,49,60,25,33,37,45,20,51,30,36,71,31,53,36,34,38,43,26,33,43,61,70,37,34,29,44,62,56,55,66,32,25,43,46,29,44,24,30,34,37,95,99,71,14,46,18,16,34,34,19,24,57,40,23,25,28,5,35,36,16,27,22,57,35,20,31,16,33,18,23,26,26,13,38,38,31,37,29,22,18,46,52,20,24,31,27,48,28,31,38,44,29,30,3,20,20,8,2,85,94,44,28,17,40,20,24,24,33,58,24,26,30,11,12,34,57,52,27,37,29,19,30,28,27,25,21,42,35,46,16,13,38,56,21,41,68,48,15,15,37,23,14,45,40,35,26,39,18,6,35,8,10,38,20,22,24,6,22,39,35,9,13,16,28,21,18,20,33,13,45,39,24,28,30,27,44,72,79,51,57,2,29,30,7,12,45,31,21,29,25,37,13,22,51,22,30,32,49,92,104,88,58,43,21,28,26,26,2,20,14,39,15,27,35,24,27,3,24,33,20,32,10,39,32,22,15,17,22,62,184,222,208,161,145,88,104,152,191,175,202,200,146,149,87,7,20,14,10,44,97,207,253,233,245,227,212,250,244,217,225,209,216,213,224,233,250,220,220,232,233,212,204,234,195,217,234,208,204,206,142,201,185,154,184,174,169,155,172,168,139,162,155,136,147,141,170,142,148,160,160,151,147,161,150,149,169,142,111,103,11,3,4,13,24,38,20,8,21,6,23,27,11,0,25,1,16,17,26,30,21,20,20,10,197,183,201,188,195,177,161,144,137,113,118,120,114,103,138,123,120,133,129,119,129,91,111,95,113,83,120,38,3,22,64,102,153,128,165,151,136,173,197,187,190,192,203,192,202,190,118,129,60,19,44,115,142,160,151,151,114,145,133,139,112,111,124,129,108,56,44,89,110,202,187,186,158,109,81,68,58,78,100,171,241,247,224,229,215,235,255,255,246,232,212,224,171,100,3,13,68,70,43,35,52,9,38,55,20,102,169,236,184,117,54,61,30,23,19,13,5,21,28,30,92,101,74,44,47,61,69,67,75,66,78,69,117,120,163,142,178,192,204,215,216,230,225,223,217,220,238,235,227,156,86,180,218,240,214,209,226,253,234,212,202,183,181,190,182,169,167,180,180,165,172,184,189,170,166,153,162,176,159,167,203,193,157,190,178,170,145,159,158,169,177,167,173,171,157,166,159,163,167,152,174,149,187,170,166,156,175,168,182,177,123,79,102,57,101,113,137,189,210,231,221,203,205,177,163,108,62,53,39,9,78,79,100,136,137,156,165,198,197,197,181,188,212,149,171,200,187,182,172,143,158,190,185,164,166,181,150,176,141,157,164,171,164,170,170,131,112,117,88,84,72,8,7,22,48,18,37,29,46,81,149,168,151,110,142,156,141,131,119,97,93,93,101,106,107,78,112,108,101,111,109,95,53,82,96,73,60,60,33,6,32,35,6,34,52,75,61,95,93,81,92,59,112,92,97,91,96,82,68,88,78,71,100,67,98,75,88,26,36,58,67,56,81,93,63,59,94,102,78,98,45,28,31,24,8,21,39,31,53,59,77,69,28,66,52,58,60,53,65,39,70,51,49,41,79,71,51,19,65,23,45,39,26,50,37,52,50,48,46,56,57,39,39,27,42,32,41,35,17,21,34,28,54,35,41,37,37,33,65,36,39,67,43,42,28,50,57,46,43,53,27,42,19,30,12,37,27,38,94,111,82,27,22,28,19,17,26,29,11,23,25,25,41,25,28,39,50,44,20,41,53,41,12,11,17,39,42,36,19,29,21,20,24,21,10,8,29,23,47,26,22,52,32,39,15,15,26,26,36,27,11,41,28,24,37,34,118,64,41,42,3,29,52,28,31,50,23,27,8,49,18,9,41,45,34,22,23,50,30,9,23,37,36,40,16,44,24,14,44,40,29,33,42,41,29,46,12,47,16,13,40,39,41,39,29,26,14,19,20,16,44,40,28,7,22,32,25,33,5,34,18,44,25,22,23,19,22,12,24,17,34,10,22,66,94,22,19,19,7,8,25,22,17,42,22,41,20,49,16,17,4,31,28,17,30,29,49,116,93,56,43,23,2,16,26,30,21,23,18,12,17,17,7,14,24,27,38,20,13,19,26,26,21,35,33,67,186,213,218,180,154,124,130,167,169,161,173,195,177,200,146,119,111,115,56,42,109,195,252,244,244,252,252,226,249,249,247,255,250,255,250,246,235,251,254,226,222,254,252,255,252,252,239,253,247,252,253,248,224,254,219,235,237,226,252,234,222,255,216,211,214,190,188,187,171,185,181,164,175,138,156,154,161,140,135,114,15,8,22,0,12,21,12,6,3,9,16,17,4,20,21,19,38,5,16,8,3,32,1,23,80,84,44,59,58,55,72,92,107,138,138,155,154,130,135,134,138,146,171,130,157,156,166,148,161,142,152,67,13,34,102,140,193,187,199,166,166,168,167,173,130,144,151,161,127,106,122,117,25,41,46,75,131,147,132,131,155,133,166,134,151,165,161,204,198,70,23,60,157,205,229,211,193,140,103,89,112,131,151,171,215,208,195,144,139,150,180,166,142,106,68,94,49,21,29,60,113,138,103,109,111,127,75,20,15,64,150,131,74,75,33,88,99,92,79,76,105,134,49,19,130,186,124,89,62,97,101,127,56,21,38,110,151,246,227,229,255,230,228,220,203,215,177,181,192,192,186,199,184,74,73,154,187,208,181,176,160,159,174,138,144,163,161,159,138,178,162,138,160,192,186,183,155,188,148,155,175,160,166,160,158,155,177,150,176,164,170,158,178,174,159,139,135,141,140,141,142,129,156,165,148,189,167,159,198,159,155,108,109,60,38,75,55,157,188,184,211,204,203,189,161,119,87,48,9,53,32,100,113,145,122,160,149,136,161,151,160,164,173,161,191,193,158,148,153,171,155,128,137,129,151,157,139,170,170,186,156,153,160,158,147,162,164,166,166,159,129,104,64,60,112,51,23,39,44,60,59,46,81,94,113,129,115,132,107,118,117,100,66,83,87,104,82,105,102,93,127,89,110,115,102,93,68,83,80,85,51,23,9,42,39,47,51,51,73,108,99,75,76,85,88,63,94,81,102,75,91,48,79,76,90,91,51,86,89,67,65,51,32,88,87,80,88,87,79,73,64,77,41,32,32,17,16,21,21,37,42,50,76,80,59,48,37,22,44,66,34,44,34,52,16,46,45,41,52,28,30,32,53,74,29,55,41,52,53,64,47,24,43,58,37,35,41,26,52,28,67,20,43,52,51,55,45,54,62,29,37,43,53,47,23,20,38,47,48,48,38,30,33,21,18,47,17,30,26,34,6,15,51,49,96,77,34,28,22,32,23,24,6,32,42,9,24,14,17,18,25,52,52,0,36,31,19,44,37,15,40,16,43,33,19,13,31,8,47,26,45,35,38,37,44,31,48,17,49,16,44,38,37,27,33,28,34,18,20,36,74,100,27,42,19,21,34,37,19,31,36,30,27,16,21,49,17,39,14,22,20,5,37,38,20,36,25,19,31,14,26,11,29,38,29,17,21,42,31,33,7,42,17,47,37,31,32,33,36,39,39,12,3,9,10,33,38,28,16,38,58,18,23,28,21,19,14,32,10,6,30,13,13,30,8,31,39,87,67,30,23,11,0,29,29,26,30,17,11,52,22,34,27,7,40,16,5,24,38,20,49,85,149,115,61,30,0,36,13,25,37,30,16,20,32,10,34,23,23,27,44,33,26,25,26,19,20,54,27,130,202,230,174,207,232,175,174,171,175,148,199,182,164,200,196,175,189,150,126,143,169,176,155,147,166,189,225,252,250,247,246,255,250,250,239,243,231,252,248,252,242,242,251,244,253,252,253,243,248,255,247,251,238,254,253,237,249,247,255,255,253,255,255,253,255,252,231,229,228,228,232,246,228,200,201,187,199,138,135,77,6,0,0,9,29,21,8,30,3,22,12,12,11,6,11,5,20,1,29,36,11,12,15,4,74,44,49,28,21,16,80,112,143,157,215,245,200,182,163,169,160,184,171,176,171,185,165,161,179,160,163,65,24,18,51,116,126,137,99,103,62,90,45,80,87,66,85,94,45,78,83,61,17,19,79,120,180,150,173,181,193,214,205,186,201,222,223,210,236,132,20,82,143,237,234,237,220,114,81,84,92,161,140,114,108,122,100,85,21,63,82,104,135,137,165,161,177,49,28,108,193,201,200,172,164,151,115,45,30,63,93,81,48,66,47,107,83,116,179,238,229,244,111,36,114,165,109,42,73,161,135,136,108,22,25,117,215,188,244,211,208,215,190,170,168,168,155,162,154,177,162,157,143,32,80,165,142,173,140,113,112,121,122,95,172,142,133,167,174,188,146,150,142,141,160,151,134,157,150,162,151,133,152,159,133,172,136,130,156,167,175,212,197,187,189,157,164,155,133,144,166,162,119,188,187,172,203,174,190,128,27,14,59,103,139,181,207,233,224,155,131,61,53,11,22,25,44,89,102,148,150,183,169,200,165,207,170,146,188,207,185,193,179,191,133,155,161,145,165,156,159,152,159,160,176,168,166,160,148,156,156,172,173,149,150,141,173,160,167,142,152,98,79,107,102,100,51,65,72,69,80,124,94,95,103,65,77,63,91,59,92,96,74,91,104,103,122,120,100,108,114,122,116,110,87,89,59,42,28,7,47,40,37,50,45,40,75,89,98,97,66,73,63,67,83,87,51,89,90,36,54,74,92,97,55,94,56,60,72,59,70,73,91,90,73,54,81,86,80,51,60,35,14,25,3,31,16,54,55,36,66,69,30,54,60,40,54,48,66,41,49,56,28,48,28,45,36,40,44,50,44,44,37,61,44,38,32,48,63,43,36,51,53,57,16,48,46,49,45,55,36,42,76,55,52,53,41,61,45,9,51,47,22,48,31,13,50,46,28,41,41,34,38,23,52,55,57,36,35,34,42,45,47,32,91,117,74,19,34,5,43,15,19,46,28,12,29,18,35,18,16,54,36,13,39,27,25,25,43,23,24,31,21,12,30,29,25,21,30,37,7,13,44,26,20,30,29,35,10,28,29,16,22,21,11,20,26,45,27,34,94,105,50,27,15,27,54,20,29,20,11,20,22,21,46,39,27,29,13,17,9,20,30,24,32,40,24,15,28,34,38,26,36,18,46,37,29,41,45,43,31,26,20,22,60,24,35,36,44,29,35,14,49,13,28,8,23,29,42,8,10,19,24,5,24,11,32,29,9,14,21,16,32,21,21,4,62,67,42,47,39,8,32,26,32,19,23,27,8,24,14,36,26,24,41,26,38,10,40,33,38,22,88,120,107,73,35,30,28,34,23,28,35,15,22,30,16,12,34,11,42,26,10,42,31,37,37,33,101,124,139,132,99,189,187,176,164,143,173,136,171,186,184,201,183,174,197,208,213,242,243,168,107,0,51,83,134,172,200,205,182,172,227,247,254,253,236,255,248,251,255,249,236,255,249,250,255,237,246,255,250,255,255,249,245,248,244,244,250,255,251,247,241,254,254,247,250,245,240,242,253,227,236,242,232,240,219,202,194,105,3,6,5,17,3,15,10,17,14,8,12,12,10,0,23,12,22,27,18,8,12,5,15,8,142,144,70,29,40,33,80,176,185,202,241,234,234,159,167,166,144,181,146,149,117,176,137,107,99,112,74,27,13,31,62,119,112,89,101,81,67,70,92,96,87,120,113,112,112,133,153,135,21,19,84,174,207,197,243,215,217,230,227,224,227,209,189,187,203,67,1,46,95,153,133,114,75,50,58,43,77,114,80,50,31,19,34,26,14,56,132,212,255,251,247,240,229,144,24,101,187,185,145,120,115,104,51,25,20,77,147,160,137,122,150,147,73,125,223,252,248,217,75,28,108,80,68,33,116,207,179,181,129,50,12,122,200,205,218,187,194,185,171,175,189,179,164,171,196,179,185,155,113,45,124,149,156,163,174,163,154,145,181,170,175,160,138,163,171,172,142,168,161,156,143,141,179,182,160,158,162,164,178,151,144,176,183,177,172,189,196,246,230,186,156,155,182,245,197,218,189,237,236,203,185,206,146,105,93,124,160,148,179,201,215,247,174,123,101,65,49,33,61,121,138,142,173,217,249,232,197,215,211,197,177,197,247,208,192,183,231,218,178,155,138,187,221,214,194,174,214,218,201,167,204,206,170,189,178,215,199,188,189,218,216,201,170,159,161,166,122,130,92,100,96,85,54,98,97,97,100,112,95,95,88,91,93,79,52,91,117,71,82,77,92,82,116,106,117,113,103,129,114,85,52,33,25,13,44,34,36,37,37,85,57,122,83,66,97,83,71,83,88,91,68,61,89,113,82,87,96,110,103,86,72,44,57,83,51,80,46,67,102,56,88,80,95,81,35,29,31,23,47,2,30,34,41,50,40,69,33,32,69,40,36,45,43,33,70,81,40,50,34,56,38,58,58,76,56,43,66,49,90,39,52,26,40,46,40,47,51,35,29,72,27,35,45,53,37,38,31,51,32,34,34,41,48,42,37,48,49,36,44,66,47,79,34,19,41,23,47,43,24,20,24,38,37,37,18,9,34,11,10,41,59,64,116,120,48,11,21,16,19,27,0,21,18,24,25,24,27,67,21,27,29,2,24,26,34,5,14,20,2,37,7,3,48,30,47,17,44,20,15,31,33,25,33,12,50,40,26,41,0,18,48,38,33,29,22,51,63,71,46,49,16,17,11,10,5,17,44,34,39,7,57,34,20,14,33,23,31,46,29,15,32,49,36,28,38,50,6,19,33,31,25,15,45,41,32,36,51,47,27,36,16,27,39,34,31,16,50,27,37,43,25,13,13,20,40,51,46,23,28,16,10,26,2,22,37,25,25,31,9,21,8,22,53,99,71,34,14,42,30,7,20,34,26,21,19,25,28,22,7,18,10,22,3,28,28,13,14,14,47,50,121,107,83,22,3,31,7,24,42,8,55,21,34,23,36,12,15,27,21,13,41,28,39,91,101,32,61,74,55,131,125,109,124,104,127,127,163,174,202,197,200,177,204,231,239,250,253,202,146,8,18,48,45,97,140,161,133,139,169,236,237,230,198,198,235,237,227,228,235,246,255,252,228,248,252,239,255,249,239,244,242,237,251,250,245,253,247,226,236,251,246,250,241,255,255,239,225,254,211,249,236,219,227,241,211,101,28,7,14,4,8,11,5,28,17,12,7,7,13,3,28,29,5,21,26,10,28,8,30,14,168,192,128,57,37,60,101,149,151,145,193,217,158,87,100,93,100,61,75,80,43,61,66,68,69,66,56,31,23,69,116,125,142,169,156,178,187,198,204,202,212,199,208,209,203,221,214,161,81,36,97,207,220,224,217,231,218,213,206,206,126,152,103,99,57,22,33,29,21,23,13,37,18,25,17,90,77,85,86,73,54,38,36,72,105,142,189,236,238,245,236,244,219,83,18,33,97,87,76,55,50,30,38,31,15,45,142,205,184,199,212,168,90,61,148,164,159,101,2,24,84,73,63,26,131,236,165,170,118,16,6,104,164,179,185,164,123,109,144,189,181,233,253,198,175,186,222,223,111,95,227,245,225,180,181,205,222,186,165,188,228,237,184,188,211,232,187,165,194,251,244,154,176,242,247,198,187,213,242,233,162,208,242,247,175,145,158,197,124,104,128,133,251,245,195,163,246,244,234,147,137,91,41,50,112,243,236,175,133,133,85,32,16,72,187,217,150,128,240,220,223,190,235,244,254,192,179,227,248,171,168,235,234,201,147,173,217,179,84,118,173,245,239,222,166,205,219,221,145,170,248,237,150,161,228,251,233,152,201,248,252,201,152,161,162,133,128,98,87,113,87,47,43,108,102,119,112,109,130,117,106,98,127,114,108,81,131,98,97,112,77,111,102,114,136,123,107,70,13,23,40,8,19,59,61,52,85,92,84,79,88,70,57,86,105,63,72,72,70,84,66,58,88,91,86,73,114,57,83,52,42,74,55,70,80,69,116,78,127,124,102,75,54,39,29,22,23,8,30,17,52,80,42,44,61,81,65,53,52,63,47,47,50,27,47,69,52,42,23,46,45,41,36,63,75,57,40,49,24,40,48,60,39,42,57,30,19,21,29,42,30,30,50,53,41,43,42,45,23,45,34,40,52,63,47,46,39,30,25,30,43,33,52,54,31,46,63,35,42,30,35,54,53,30,10,25,22,39,21,35,23,0,85,126,85,64,35,6,38,10,21,18,29,24,50,15,15,19,31,10,18,43,38,35,24,32,39,25,26,38,42,41,29,22,14,37,31,19,33,24,36,10,30,33,42,23,33,25,20,12,27,46,20,55,19,8,30,91,92,33,19,20,20,24,29,18,15,39,37,30,28,14,14,26,33,26,11,29,27,12,39,24,34,38,22,29,19,24,32,29,34,55,31,38,29,41,42,56,33,51,25,45,24,45,18,26,14,28,8,26,7,18,22,27,35,8,18,26,38,26,0,5,7,16,35,20,21,20,15,20,39,14,54,85,44,27,9,12,25,21,29,29,17,18,17,30,26,36,29,24,33,25,32,11,27,20,17,42,27,24,88,103,97,52,40,11,19,11,36,28,27,16,17,13,23,27,42,24,16,23,48,47,91,138,87,38,87,62,52,86,121,136,133,102,137,172,153,181,207,208,194,175,183,202,208,203,243,243,206,121,100,68,46,21,47,70,127,167,154,147,144,147,133,148,139,144,172,219,242,217,151,201,191,195,199,206,228,234,232,244,243,252,229,255,255,245,253,243,248,226,255,243,235,251,241,211,222,233,246,255,241,241,254,232,255,115,2,16,15,9,29,7,19,22,16,28,14,20,12,0,0,2,11,7,16,8,8,26,19,18,146,134,124,26,47,45,73,113,118,115,112,140,75,49,66,58,91,105,87,109,110,119,135,133,152,162,170,39,15,78,151,215,249,249,245,248,243,245,248,247,239,229,244,243,228,217,236,155,57,20,66,109,201,179,159,140,121,83,73,59,50,65,57,61,63,32,42,28,48,40,51,25,69,79,108,101,51,38,50,100,83,57,92,140,202,237,197,190,228,179,178,153,128,19,11,84,59,75,93,91,97,77,36,61,31,73,124,156,131,123,177,171,28,25,83,89,78,63,20,29,124,150,115,63,121,202,214,211,143,28,12,105,154,201,158,82,69,75,95,128,142,226,245,176,161,200,241,210,86,149,236,250,202,167,220,234,181,150,159,212,252,206,147,174,191,205,183,135,183,200,212,137,181,245,241,181,151,223,246,228,160,167,236,240,133,116,107,101,85,116,146,165,202,228,149,153,165,188,77,44,84,83,22,57,93,126,98,45,36,90,118,99,103,146,230,242,184,182,241,251,194,148,179,230,218,176,130,219,215,180,182,197,186,157,144,155,199,99,111,136,149,211,236,187,125,172,200,167,136,140,184,176,141,168,207,217,158,144,184,216,204,160,182,132,148,164,141,132,126,131,127,68,61,46,70,62,111,91,94,118,117,86,114,115,100,105,107,112,92,124,128,93,123,107,92,64,42,34,31,26,51,40,57,93,89,105,88,91,72,76,70,92,87,88,89,114,82,89,67,88,85,85,83,81,74,86,79,79,46,80,56,40,70,70,60,73,94,112,108,72,56,27,29,35,40,50,19,37,72,46,59,63,48,46,37,43,56,18,34,39,54,40,44,55,70,45,43,41,31,43,45,32,52,53,50,53,55,60,60,50,53,51,53,38,18,42,41,30,63,38,57,34,59,51,43,57,44,54,54,37,29,49,31,39,21,18,61,20,63,38,14,20,33,33,39,40,40,39,67,36,13,34,7,37,15,43,40,23,97,20,39,22,29,94,103,95,80,19,14,12,17,38,44,30,36,30,18,33,31,40,33,24,19,13,16,33,28,10,22,41,47,26,32,45,21,51,32,28,15,0,38,26,37,32,5,42,31,26,21,10,35,52,25,41,11,16,46,90,78,42,35,33,30,15,46,48,21,24,33,57,36,29,33,12,21,19,18,15,14,27,16,39,38,40,35,41,23,7,40,35,44,46,24,37,41,37,18,35,20,39,37,34,26,21,36,24,34,24,24,14,11,30,30,18,25,29,20,24,26,25,20,18,34,20,7,8,10,35,5,17,13,22,54,69,35,9,11,7,8,45,34,47,7,24,47,8,39,27,19,34,40,13,27,24,24,5,23,17,20,58,39,79,70,94,51,37,3,20,13,35,39,12,32,38,20,12,46,13,0,19,20,84,164,169,116,66,159,124,103,125,139,181,203,161,213,206,195,203,208,196,180,167,165,203,209,242,223,242,220,147,217,180,92,34,1,26,101,138,170,136,143,172,149,128,139,105,115,180,224,126,57,56,101,108,135,121,157,215,245,214,189,167,172,230,208,221,188,209,253,243,255,227,254,247,235,213,224,240,242,255,248,253,244,248,224,108,1,11,14,14,20,0,23,0,13,14,29,42,15,9,6,4,5,11,21,21,23,10,10,11,113,89,28,6,63,60,91,130,125,132,120,138,128,127,168,157,167,183,194,213,215,208,205,194,228,237,203,101,22,88,155,207,214,233,227,216,233,213,215,206,198,160,158,164,153,131,127,52,16,15,31,31,11,20,26,10,12,21,16,43,44,101,139,158,166,36,33,118,170,212,223,230,196,174,94,46,90,67,87,88,27,38,56,103,127,100,79,88,70,108,113,117,120,32,36,126,185,174,148,162,154,111,112,99,127,119,94,85,55,81,85,77,28,56,150,178,210,201,44,38,120,105,88,46,43,165,129,202,218,44,1,78,156,212,178,154,126,148,135,130,159,157,166,157,145,181,221,120,68,81,189,165,159,153,158,157,152,133,148,177,206,170,141,153,126,153,102,151,155,142,94,124,125,130,175,135,163,147,163,134,162,161,183,176,125,167,173,168,174,189,223,193,227,209,127,103,76,61,20,38,76,69,42,32,30,50,82,96,167,162,199,176,199,171,213,188,174,160,187,161,138,138,152,162,153,157,144,179,174,152,167,156,140,130,159,159,174,160,168,199,136,155,160,136,150,168,163,172,172,156,172,157,152,157,168,180,161,163,152,162,128,156,169,129,159,149,153,151,160,147,123,119,93,71,62,84,94,102,97,107,114,115,94,102,124,99,106,127,97,103,85,80,53,4,12,7,23,35,45,81,102,124,106,89,89,100,91,83,75,90,96,78,58,84,110,73,81,76,72,100,102,75,81,62,66,80,50,68,49,101,68,54,70,77,77,94,124,80,76,37,20,36,22,18,24,39,26,75,58,54,47,52,34,76,45,55,34,45,82,48,57,61,55,14,50,52,24,48,61,67,22,51,45,43,50,24,35,54,45,49,57,28,17,26,41,27,39,45,45,32,31,22,30,27,55,48,49,38,27,30,29,47,16,36,38,47,19,28,35,44,2,39,41,30,50,22,23,60,37,18,9,43,26,42,23,32,20,24,45,26,9,10,17,12,85,97,85,58,15,10,24,32,40,16,6,27,23,26,5,41,29,9,14,12,32,11,17,15,38,6,6,22,12,2,31,22,24,23,42,33,26,10,35,19,14,40,49,25,24,8,15,17,10,32,23,45,53,31,102,75,34,39,21,19,30,6,40,22,19,30,23,51,41,29,24,26,14,30,40,8,48,19,21,37,32,25,45,13,59,36,46,48,28,58,34,35,23,56,39,49,15,16,27,32,22,32,7,22,3,13,6,40,26,30,7,11,22,25,45,32,31,32,27,18,37,24,50,14,25,25,27,28,79,25,10,14,18,10,36,35,31,39,9,5,22,16,8,11,44,46,17,32,10,46,11,11,8,9,17,26,9,37,77,100,102,52,24,38,10,41,20,52,11,37,29,4,17,28,35,38,68,121,140,125,111,111,126,129,112,119,164,186,174,156,190,179,175,193,201,202,184,195,200,201,179,178,161,185,168,161,195,145,131,122,58,18,48,51,91,123,159,154,170,174,169,168,149,179,252,148,26,96,139,134,130,135,145,178,209,174,124,82,86,142,150,157,98,159,245,232,247,240,235,252,231,226,193,215,238,231,240,236,235,191,182,108,0,27,1,0,10,8,12,23,3,21,1,12,4,11,22,6,0,22,19,14,15,9,42,11,74,96,38,23,70,76,160,201,193,203,221,202,219,205,205,198,215,242,226,224,222,236,233,208,214,220,188,99,20,42,82,164,174,187,140,110,131,98,88,77,92,69,70,74,24,22,17,29,27,36,59,40,42,48,52,27,16,11,44,67,73,71,67,111,79,49,61,103,220,239,236,245,231,127,36,31,83,91,96,41,20,9,36,75,48,33,11,53,88,132,183,181,165,32,25,83,125,132,101,89,84,68,24,60,159,142,144,162,114,123,217,152,21,131,229,253,243,232,72,29,91,123,33,39,117,172,151,168,169,48,18,29,103,146,232,224,231,190,209,178,162,161,148,145,178,174,146,58,37,131,168,175,169,176,166,155,168,178,165,169,161,159,175,160,157,132,162,195,138,167,150,131,155,146,137,181,148,145,167,149,144,190,161,169,150,182,209,222,228,214,174,178,126,56,24,26,22,38,13,59,70,62,115,131,162,177,171,196,207,225,200,199,174,180,176,156,139,151,179,169,159,165,176,169,175,155,132,144,131,137,120,145,162,139,162,176,192,183,179,167,148,172,147,141,162,146,176,156,181,136,189,149,147,143,183,163,172,169,164,143,153,157,163,152,142,155,155,135,128,140,133,117,162,115,97,102,113,92,100,54,80,90,79,70,78,66,65,55,41,51,17,25,23,23,56,77,54,109,127,149,146,112,92,99,99,78,84,61,91,108,116,91,101,97,78,73,79,75,87,89,81,66,62,40,64,56,46,66,71,68,66,87,109,96,96,92,78,24,40,26,38,13,42,43,62,62,56,60,67,80,67,55,45,37,34,69,54,51,33,49,32,39,72,42,45,48,37,47,41,50,50,17,18,38,51,41,38,43,42,48,26,36,52,45,40,49,59,57,55,43,47,52,44,16,29,40,48,35,57,40,33,49,47,28,8,27,16,65,16,53,38,19,25,60,42,26,18,65,20,50,33,19,30,40,37,35,18,13,7,19,10,9,28,32,15,76,103,123,37,33,27,33,60,17,51,22,2,5,36,40,21,28,17,23,30,20,29,16,16,19,65,50,10,35,35,10,37,36,42,28,30,19,27,30,22,29,34,27,18,34,24,37,16,30,17,43,35,51,100,89,54,11,22,6,20,36,20,30,33,22,23,46,9,44,16,23,14,36,15,1,15,29,42,17,36,19,30,12,11,12,50,29,59,11,33,42,54,22,43,38,24,27,29,26,25,21,39,24,8,13,29,34,36,24,51,12,25,24,15,22,40,11,11,38,26,26,34,32,1,17,13,76,81,28,25,24,35,41,33,9,11,10,29,33,34,27,3,18,42,12,24,50,17,33,14,29,12,23,21,22,24,18,8,73,98,92,82,25,28,47,21,7,16,23,11,32,40,36,7,38,92,78,61,42,44,77,63,53,65,78,89,90,70,76,111,129,141,121,135,145,110,133,120,89,126,144,139,156,146,147,171,153,149,181,120,118,111,33,25,58,102,138,148,169,181,179,168,207,235,173,54,99,148,176,160,173,164,194,230,181,103,37,126,162,136,151,90,148,247,223,253,232,216,246,242,205,212,211,225,207,199,173,167,142,112,96,11,1,19,19,16,4,19,40,8,24,11,21,30,24,21,1,7,6,12,10,17,5,1,6,172,176,87,25,58,77,163,223,218,247,234,235,201,195,184,188,171,185,181,182,132,156,143,157,146,128,120,44,13,24,51,105,56,90,52,32,31,30,54,79,56,79,76,54,76,61,40,13,35,32,87,114,124,92,95,115,115,92,105,100,80,38,67,25,18,5,22,72,115,136,110,111,95,135,91,60,56,95,155,103,19,29,92,141,138,121,115,106,120,147,128,113,52,22,24,27,54,45,22,48,29,28,13,41,132,152,161,220,193,232,240,246,89,100,192,238,225,148,37,28,98,99,72,62,151,233,203,196,137,10,16,53,16,58,120,209,211,194,183,180,173,176,178,170,174,173,139,18,74,184,173,164,166,152,154,174,166,172,156,181,169,128,164,147,158,158,154,207,182,165,165,185,168,182,151,165,156,197,167,172,183,158,173,194,200,196,199,221,145,95,47,3,15,26,33,6,40,89,134,141,182,189,217,200,214,194,183,187,183,181,193,175,150,162,158,149,189,187,170,162,180,157,168,161,165,171,159,142,162,136,131,159,133,152,152,179,153,173,171,171,162,183,163,151,157,138,153,149,154,173,131,120,130,134,124,131,135,168,146,157,159,169,144,135,124,123,136,126,106,134,102,127,119,147,135,147,123,111,92,105,65,74,81,50,108,48,46,26,30,45,59,75,58,94,109,120,136,135,139,111,128,87,89,96,86,70,98,82,98,80,47,89,89,105,77,94,78,101,83,60,63,69,60,74,73,91,65,74,65,96,74,90,108,93,46,35,6,31,19,7,18,42,38,59,58,52,59,71,59,52,48,67,38,70,62,50,52,26,28,51,39,34,35,41,44,43,41,60,63,43,54,60,40,47,20,71,79,52,53,58,50,37,25,43,61,49,33,67,30,30,20,28,43,51,33,23,35,26,29,53,29,39,16,36,32,26,27,36,59,8,46,30,45,18,35,37,19,35,43,39,39,34,26,60,43,17,21,10,18,14,14,22,20,13,28,43,52,78,116,107,68,15,27,12,21,27,34,41,42,20,20,18,30,42,20,11,25,10,34,34,29,12,47,53,13,7,27,42,18,22,36,24,5,6,18,24,29,23,5,54,24,18,28,19,33,37,33,38,60,86,75,15,57,20,20,35,25,38,14,34,33,29,26,33,46,44,14,21,52,32,28,14,37,24,43,43,22,23,27,19,66,48,44,24,19,45,44,36,53,46,29,24,19,38,14,9,24,22,19,10,23,31,4,19,10,27,17,24,40,20,15,23,39,39,17,10,43,23,39,23,11,82,60,7,30,12,15,16,38,21,25,27,31,22,14,25,29,10,34,20,13,38,31,45,26,47,38,36,11,8,20,25,28,35,39,104,92,66,45,20,32,30,7,50,50,10,13,17,63,106,69,67,56,45,57,55,79,52,56,64,75,47,50,50,40,72,42,46,38,64,43,44,79,131,165,191,210,222,221,201,237,189,220,220,124,200,188,93,77,64,91,115,125,170,217,210,211,243,249,179,82,123,159,164,156,161,169,197,219,184,121,60,145,177,181,172,108,154,248,232,236,220,247,243,230,229,184,181,178,192,160,141,154,132,144,101,11,24,29,1,23,3,25,6,1,9,38,28,22,10,8,10,23,7,19,7,15,5,19,20,203,194,118,36,61,80,155,168,194,244,233,220,189,158,123,131,121,111,75,63,69,83,51,44,66,42,18,17,39,44,84,113,105,113,130,135,127,133,132,148,156,152,177,157,160,157,153,111,42,56,128,197,229,191,200,184,161,146,125,100,96,103,74,39,9,29,24,91,129,138,118,139,156,174,193,112,132,172,182,178,40,38,132,182,159,144,124,89,122,119,90,38,21,7,31,76,60,96,87,100,116,159,118,65,181,164,133,157,165,159,223,150,40,31,105,72,44,25,0,32,71,89,62,27,122,231,247,219,160,32,8,122,137,34,37,70,136,191,184,195,194,175,213,190,168,140,31,60,162,198,198,175,169,161,198,203,162,184,197,172,181,183,194,168,164,187,170,162,154,151,192,172,140,173,164,174,172,165,190,174,174,208,225,231,182,126,83,69,40,3,12,27,29,81,122,187,210,207,191,212,199,218,179,192,167,187,186,145,154,155,189,193,184,169,171,175,164,161,182,164,165,191,164,164,164,202,150,194,188,168,185,160,177,179,169,161,148,147,162,157,177,157,144,167,169,151,146,163,187,152,165,158,181,160,158,150,135,136,167,143,144,182,181,142,123,89,128,154,141,122,110,119,90,93,85,83,117,129,140,119,145,111,101,105,124,98,107,98,102,114,110,116,127,150,111,148,145,112,115,104,102,117,106,60,78,76,77,79,89,63,63,89,100,77,71,62,61,54,73,77,73,76,80,67,83,97,67,71,60,81,85,82,87,36,6,13,17,8,45,33,41,59,47,51,72,55,54,62,56,42,40,24,61,53,56,57,55,44,37,54,50,37,57,22,50,55,41,39,50,42,67,49,51,38,51,41,33,40,38,24,49,41,35,64,52,67,60,50,38,28,42,30,16,34,18,46,37,31,5,38,19,44,50,35,48,41,31,46,61,57,37,35,33,35,36,30,26,20,36,51,17,34,32,10,42,31,55,22,45,30,12,45,23,34,39,38,34,32,68,135,68,53,17,42,11,9,63,28,27,24,27,18,13,12,41,31,27,8,19,30,25,49,36,28,32,33,36,29,42,30,42,43,26,43,43,40,30,45,24,35,40,31,22,37,7,15,36,37,31,106,77,67,11,19,22,16,35,35,30,43,48,27,14,34,22,48,42,27,10,7,13,24,31,54,24,28,39,31,13,57,50,13,30,33,30,22,22,41,27,37,28,30,10,45,41,41,36,5,29,13,13,28,22,33,22,14,30,25,18,13,36,40,25,32,26,45,42,45,10,2,28,89,71,33,10,10,17,19,33,33,27,22,31,28,29,32,23,19,17,23,18,33,12,30,34,24,25,14,23,27,31,21,39,25,29,56,155,98,80,52,49,13,29,1,37,32,8,73,94,95,62,16,56,59,43,64,48,22,37,42,71,73,46,79,58,64,39,35,39,10,28,69,193,225,234,238,254,251,252,251,252,248,230,189,96,145,188,124,82,79,54,51,56,109,185,205,175,176,247,134,47,89,99,124,134,147,157,183,212,141,85,86,162,152,183,147,106,155,248,242,243,249,218,237,254,236,202,173,198,164,158,130,136,131,134,130,7,1,17,6,18,5,16,12,14,7,14,2,8,4,12,13,34,34,6,14,4,25,4,25,169,186,74,13,33,100,126,147,145,167,167,153,77,66,66,43,76,50,58,70,61,62,73,87,100,112,73,16,26,70,118,194,197,203,212,209,208,201,190,218,190,185,188,184,207,193,220,121,61,21,74,167,177,140,125,122,138,139,116,110,95,138,144,184,107,24,56,134,185,224,235,233,234,220,174,123,127,188,228,147,48,23,91,100,122,104,75,65,78,111,56,51,37,12,54,137,180,213,201,212,220,249,157,90,206,194,171,149,65,25,38,28,12,18,28,48,25,26,4,50,17,86,30,38,107,148,181,230,198,58,25,116,212,161,47,37,46,125,131,199,188,197,163,162,70,16,56,137,194,183,185,167,175,168,185,169,157,167,148,192,180,163,157,135,196,169,139,174,164,187,137,164,166,166,191,184,197,215,222,198,209,163,148,108,44,4,19,21,83,105,134,188,199,213,225,214,209,212,190,176,200,192,171,173,164,190,157,133,172,175,166,186,187,158,160,184,178,160,173,189,166,180,158,166,164,166,176,159,186,177,165,196,167,165,176,181,191,165,192,152,158,150,151,135,163,124,143,135,143,161,199,193,191,166,163,191,181,187,152,156,173,176,190,122,109,111,120,145,135,133,98,110,121,103,96,106,118,134,124,138,127,127,117,125,129,119,113,124,133,122,108,112,140,125,116,109,113,97,119,65,68,104,63,88,69,87,78,67,55,72,74,76,56,76,67,45,49,75,61,75,75,78,86,63,93,93,73,70,80,82,56,36,27,29,25,18,41,40,54,61,72,63,57,52,64,71,69,68,50,57,39,59,27,81,52,36,35,48,48,56,51,45,36,32,55,41,72,45,53,36,12,38,48,41,18,53,39,44,34,40,43,49,27,43,39,59,32,37,35,34,40,50,25,6,43,33,31,39,58,39,44,50,45,33,14,32,44,37,57,32,60,27,53,69,25,23,60,34,44,38,42,64,38,36,57,38,37,39,10,15,23,8,2,19,7,29,13,23,41,80,124,77,51,34,8,33,25,5,23,21,11,46,13,15,49,16,15,40,53,17,14,26,13,16,45,12,26,51,23,60,25,28,19,21,35,31,30,21,38,43,7,14,32,30,38,32,25,20,20,78,94,57,29,41,24,36,14,26,25,13,5,20,26,45,51,18,32,29,13,13,31,25,19,32,40,13,17,4,44,31,25,14,44,32,24,29,35,27,15,46,52,42,23,35,29,19,25,25,16,30,40,34,32,10,1,30,6,17,32,29,37,25,35,14,34,33,28,10,44,32,33,93,41,4,32,13,17,32,6,11,4,19,34,7,31,24,23,26,27,28,14,17,26,27,2,5,15,6,27,25,38,26,18,16,41,42,82,103,125,47,51,20,22,17,24,35,56,107,58,76,39,34,61,58,42,64,75,45,51,53,38,59,55,39,82,66,71,17,37,40,131,216,222,235,213,226,233,241,251,242,251,247,244,192,92,99,104,113,109,118,12,19,0,22,46,68,62,116,197,96,33,80,62,100,95,104,113,156,215,142,61,96,149,150,192,169,89,172,244,251,232,212,226,245,249,238,239,184,169,181,160,156,154,160,163,114,1,0,20,22,36,21,18,19,23,2,11,11,10,19,6,20,15,5,0,11,23,24,29,10,116,105,26,28,27,61,87,83,114,77,91,62,93,89,91,96,114,134,124,151,160,189,184,175,197,193,145,55,29,94,160,229,225,220,218,183,223,190,209,186,148,135,142,89,137,103,101,33,17,41,57,114,105,98,112,110,131,133,166,166,167,211,200,227,129,33,41,149,204,243,243,213,139,69,77,44,92,122,138,84,6,19,50,49,45,41,48,52,82,134,129,178,90,2,102,177,226,235,238,189,213,210,134,84,198,194,210,213,132,82,82,33,1,92,143,167,193,122,18,86,71,60,48,49,123,163,141,151,169,50,26,122,197,217,183,102,17,13,20,74,78,79,61,33,37,90,155,173,205,152,164,173,175,141,174,168,160,173,153,170,179,172,167,171,194,176,173,174,183,190,194,187,199,210,230,233,194,196,134,96,63,91,2,48,51,98,143,190,186,228,223,255,197,200,193,184,163,175,163,144,158,185,176,175,182,161,194,166,138,163,165,148,151,184,175,169,186,171,180,161,156,135,168,177,158,143,177,139,147,156,179,138,159,149,175,136,164,149,152,197,188,155,159,162,132,144,163,144,170,183,199,178,171,162,195,181,208,184,168,176,136,155,159,154,138,89,91,105,128,113,110,120,112,119,99,117,112,115,123,109,105,107,123,134,134,117,101,127,108,113,108,116,117,118,92,114,116,83,106,87,86,91,68,72,52,88,87,92,80,92,63,95,73,53,47,59,69,78,49,68,69,78,77,80,68,87,109,99,37,30,43,21,16,21,31,45,44,64,65,37,61,57,55,48,57,54,49,48,48,54,51,48,47,64,49,46,64,54,51,66,26,41,53,18,59,22,32,33,52,31,48,58,40,75,43,40,32,48,28,35,83,44,36,20,46,11,30,26,45,10,51,72,40,40,44,46,16,50,29,28,20,13,40,45,64,57,48,74,48,46,31,15,32,25,33,48,30,30,23,22,28,24,15,43,47,45,25,24,33,32,22,40,19,12,18,19,37,50,55,51,98,153,118,47,43,13,16,17,37,11,45,42,44,37,45,33,66,53,6,31,36,47,35,28,52,23,21,46,34,6,13,14,5,32,28,25,28,25,35,8,26,43,40,35,61,6,34,40,20,47,87,87,56,23,23,23,22,20,29,13,14,11,39,30,9,27,15,12,35,44,15,34,42,21,9,34,36,42,14,40,37,21,29,32,71,37,45,21,55,25,20,40,34,55,36,15,22,7,39,24,26,8,28,23,15,28,7,17,16,3,18,40,40,21,17,24,7,38,50,12,65,74,21,41,26,0,31,18,29,41,13,48,28,19,31,33,1,43,13,57,38,14,27,57,15,17,12,26,30,26,28,32,24,61,25,33,33,55,119,89,75,50,18,28,39,77,103,82,45,47,39,52,54,24,55,68,43,39,40,45,60,60,67,44,62,57,17,45,32,45,136,180,189,215,221,202,188,196,196,210,247,239,240,223,136,105,88,121,160,147,99,12,9,26,7,33,2,53,170,84,45,84,69,96,88,86,61,146,168,134,56,84,117,165,151,141,88,174,226,245,251,236,252,245,241,248,252,200,173,183,177,186,178,156,191,113,0,10,2,51,8,13,11,33,13,2,22,23,19,4,29,11,19,48,22,9,8,31,13,17,55,15,20,31,47,107,107,150,141,133,181,166,163,176,176,190,226,226,223,242,231,225,224,220,216,226,182,62,22,75,133,160,169,159,150,134,120,108,89,100,84,42,66,63,69,54,61,20,8,64,120,173,155,176,192,206,195,205,198,209,201,211,219,190,155,28,48,100,187,197,169,64,27,62,39,54,75,100,52,16,17,41,71,106,84,91,116,128,146,189,195,242,116,21,74,147,172,170,147,127,84,59,3,62,153,164,204,207,172,157,173,86,64,148,219,213,232,110,42,48,102,99,55,46,178,224,187,183,118,3,10,108,168,201,173,175,152,122,46,37,65,48,99,107,137,159,192,179,171,167,157,168,149,170,131,169,165,129,148,154,183,174,172,168,187,175,172,175,200,197,203,218,191,187,127,105,82,9,10,24,44,58,78,170,204,188,226,213,203,191,160,188,188,192,183,157,171,146,154,181,150,156,169,165,192,166,145,151,142,183,178,149,166,178,175,162,186,165,184,149,135,138,141,147,148,167,183,145,151,155,162,158,164,186,148,120,116,144,161,161,155,186,152,167,164,192,176,190,168,137,142,167,190,171,169,161,187,175,191,156,158,185,192,170,116,111,86,93,106,89,80,59,111,96,98,96,98,125,119,121,126,100,128,112,122,127,119,126,111,149,103,107,121,108,102,116,107,88,103,111,66,44,82,69,76,84,77,95,74,69,52,62,62,52,51,62,77,51,66,97,86,75,76,91,98,73,36,52,54,35,27,23,32,26,20,60,72,66,49,46,66,47,61,49,47,48,50,67,39,68,55,54,61,41,30,52,46,44,55,44,47,41,32,31,42,37,43,56,36,35,29,50,34,52,31,35,28,55,78,21,37,37,25,51,27,25,53,36,32,46,18,36,10,34,32,31,16,59,34,52,29,30,59,49,29,36,54,26,24,52,42,20,27,20,81,53,17,23,26,19,32,47,36,16,22,25,18,35,24,4,22,14,46,9,38,32,24,16,53,39,26,46,126,95,82,51,26,14,20,29,35,10,31,42,25,25,40,48,32,42,32,10,42,50,48,48,39,23,17,52,21,25,16,46,11,21,36,22,42,49,53,30,23,41,30,35,37,26,35,16,91,97,46,35,15,20,29,19,13,37,20,11,64,16,19,28,35,23,56,30,44,21,7,24,43,38,15,18,31,47,48,15,47,32,30,34,8,36,60,38,18,29,47,27,33,31,17,24,32,31,28,18,36,6,43,19,20,21,7,28,31,32,27,28,27,44,37,9,22,26,77,60,22,13,32,2,33,20,6,27,19,43,18,21,18,12,35,34,39,42,3,8,28,15,45,22,30,19,48,30,29,20,22,34,14,10,21,26,45,107,115,54,59,29,69,99,82,33,45,63,45,31,55,62,57,43,45,9,27,38,38,64,84,60,61,65,57,28,37,50,102,137,175,219,195,213,193,200,175,216,201,212,202,172,148,123,104,94,195,220,214,204,193,144,110,67,74,139,179,66,36,85,94,126,88,68,66,142,206,147,45,41,78,103,105,111,67,165,225,247,254,246,245,237,230,239,236,234,194,183,185,160,194,184,197,106,10,9,38,19,15,10,29,6,31,1,30,7,3,11,15,11,9,17,31,31,4,9,13,4,143,103,8,64,74,114,188,196,192,199,226,206,215,203,208,193,218,224,205,180,169,192,177,164,127,146,84,13,27,48,105,90,99,60,81,39,82,94,65,75,74,95,88,144,120,180,137,45,20,61,141,198,184,217,207,209,195,204,195,194,130,138,125,115,53,20,64,64,115,83,117,77,66,120,131,124,120,150,141,87,0,54,118,159,175,104,120,125,149,194,215,212,81,6,48,112,120,92,60,73,68,72,15,77,147,139,166,187,164,156,228,85,42,101,171,114,90,56,16,28,13,49,5,37,174,191,251,238,135,30,31,120,185,207,183,181,182,183,175,156,123,168,178,164,211,204,184,185,147,149,188,137,142,157,158,178,154,153,167,174,156,196,220,192,198,195,166,161,153,110,97,65,23,17,5,10,8,6,26,95,167,178,206,206,207,201,201,184,189,161,169,161,149,157,156,166,152,151,160,154,169,176,161,163,156,138,147,138,154,165,166,174,161,187,150,152,166,157,173,189,155,153,154,152,156,166,170,181,167,179,170,166,165,170,174,152,155,182,173,175,174,190,185,197,173,166,186,187,165,164,149,150,162,181,169,211,154,156,138,177,188,167,174,172,181,92,76,89,73,103,104,73,90,74,87,124,143,121,103,146,97,126,101,125,129,107,87,102,123,97,92,136,100,96,99,111,97,119,80,90,96,76,75,68,79,72,82,91,89,63,55,65,79,83,62,58,69,71,67,75,101,74,95,65,45,59,5,18,29,30,42,46,33,60,60,57,45,48,42,45,31,63,42,52,63,65,42,60,61,82,44,56,73,8,69,40,48,64,58,58,56,57,20,50,44,42,54,30,71,59,54,54,40,36,49,39,48,31,14,18,51,55,42,46,47,47,44,38,23,58,42,27,28,46,43,44,25,42,37,27,34,29,16,39,27,39,25,11,29,31,26,41,75,33,59,41,47,24,53,29,45,60,9,45,19,53,15,40,50,16,29,27,35,27,19,34,42,12,21,29,25,7,19,69,96,81,63,43,26,31,35,17,54,45,22,36,30,34,44,16,31,18,12,37,20,35,5,30,33,13,46,42,13,14,11,33,41,35,17,11,25,47,31,8,12,24,39,12,44,22,31,82,77,18,9,16,42,45,9,46,42,24,34,22,24,19,22,29,29,35,16,31,26,26,49,53,31,20,34,42,37,37,20,49,62,1,28,43,25,45,40,25,5,31,40,23,15,5,43,28,50,21,6,33,8,28,22,54,14,15,12,16,4,22,50,41,30,19,17,49,91,71,18,34,14,10,32,9,32,32,35,40,3,20,25,12,24,17,19,3,25,21,13,22,23,17,6,15,19,42,17,35,30,10,11,26,16,16,35,71,95,115,71,98,128,84,19,63,47,42,45,44,46,55,43,83,28,33,39,37,43,68,43,48,60,67,40,59,4,31,51,73,95,158,186,204,211,188,202,216,200,189,194,127,121,146,92,133,203,253,239,232,248,248,240,252,233,227,220,107,107,108,129,112,122,95,84,173,239,171,84,86,34,60,64,65,80,128,222,237,252,243,233,255,212,249,240,237,228,175,173,202,208,181,171,122,4,8,0,28,1,9,0,28,21,39,0,24,20,4,11,8,18,10,3,7,15,15,31,25,201,162,47,51,100,123,196,209,217,192,193,210,181,181,171,159,152,139,142,63,107,80,77,89,79,39,19,40,36,60,104,119,109,106,137,149,158,162,178,169,181,171,184,202,194,212,188,105,26,73,152,181,202,158,166,146,127,146,100,92,94,60,48,23,0,13,43,102,155,160,189,118,118,156,130,128,175,235,234,145,11,64,146,150,160,128,110,87,96,130,93,79,25,13,70,108,145,115,136,155,169,196,93,121,204,218,172,161,96,110,98,47,28,30,57,73,34,25,8,15,44,55,37,34,63,176,170,240,180,28,14,118,187,206,190,158,190,196,174,188,191,199,193,206,183,178,164,157,210,132,154,169,167,167,188,177,202,233,185,184,177,186,169,131,99,117,85,55,29,25,30,23,34,46,15,43,46,82,128,185,199,193,176,181,173,210,151,178,183,145,178,175,193,184,147,164,176,176,188,161,176,173,149,156,184,161,159,154,181,140,174,144,161,189,167,155,151,168,157,195,186,170,166,160,169,172,163,156,171,166,171,167,161,192,151,187,201,187,190,167,158,165,158,145,157,163,171,166,173,197,193,165,181,183,159,162,169,173,150,157,197,172,146,169,144,123,82,98,89,96,70,105,85,68,101,94,112,105,127,102,108,110,100,122,114,126,117,79,112,138,100,111,117,66,94,98,103,117,110,139,91,77,63,72,91,98,96,49,72,86,78,78,76,81,91,83,71,68,110,71,91,69,39,28,39,25,32,40,54,24,49,65,60,72,52,44,51,42,68,40,52,43,46,55,58,66,65,51,58,19,36,65,44,42,51,46,50,49,83,44,25,63,31,20,41,29,31,39,25,48,53,73,49,43,73,57,47,37,33,46,19,31,44,40,37,40,32,62,37,29,49,41,13,50,25,38,43,51,72,40,34,24,25,31,47,52,23,23,20,47,44,8,15,25,32,18,49,58,23,57,42,35,49,11,15,49,33,16,44,26,32,14,26,39,52,8,30,14,19,50,11,35,29,29,74,103,109,83,71,30,15,13,35,19,18,24,5,4,46,29,21,32,26,6,30,32,25,24,42,43,22,42,41,25,22,5,19,28,42,41,64,36,44,27,11,41,22,54,17,17,37,56,103,53,30,13,25,35,27,35,26,42,12,23,43,14,48,33,14,68,12,50,35,63,31,17,24,35,27,52,4,37,45,50,44,34,47,32,33,26,30,43,36,38,46,39,24,7,25,33,38,16,35,21,25,22,19,26,27,13,21,33,18,16,5,8,19,33,17,76,84,30,25,34,24,3,11,6,27,17,35,28,18,25,44,22,20,21,42,26,28,11,42,42,39,49,34,46,29,59,21,9,35,9,22,19,8,33,27,35,68,113,132,130,79,61,34,36,37,49,42,57,60,51,54,52,64,45,43,56,39,58,60,25,41,47,37,28,48,41,32,49,55,40,72,131,152,183,184,198,218,220,169,119,124,76,93,111,143,200,210,238,231,247,251,253,237,244,234,186,196,200,153,140,125,127,205,209,254,218,197,141,154,118,101,118,109,187,246,250,248,233,253,208,172,210,252,236,213,185,191,179,199,183,155,99,6,8,0,2,40,17,39,14,10,6,12,30,2,7,8,2,16,0,14,8,22,6,14,12,158,140,44,43,80,98,133,157,148,120,141,84,96,87,85,90,49,75,59,45,48,49,78,98,92,97,24,13,48,81,157,172,178,210,194,213,198,213,229,188,214,202,200,212,184,166,161,72,22,57,98,154,135,91,76,73,57,65,61,79,82,101,110,140,75,24,109,160,237,234,237,186,126,129,123,144,176,191,216,129,6,27,85,110,96,70,30,50,51,82,74,76,25,23,95,175,186,188,207,214,233,183,100,124,207,217,216,174,84,57,65,23,39,15,45,41,53,29,29,18,33,25,49,22,104,125,147,182,175,4,14,107,159,185,173,153,170,199,176,154,166,166,151,151,164,152,166,166,161,154,165,166,169,188,223,184,203,178,158,136,112,67,48,39,19,72,47,102,111,86,141,157,198,185,192,182,94,152,134,131,128,133,157,164,171,162,149,178,156,127,162,160,156,160,172,150,165,151,173,185,169,164,158,135,165,157,180,150,160,153,155,155,157,177,175,190,175,163,167,178,186,187,174,178,167,163,189,206,160,183,142,150,177,186,162,164,160,173,158,170,145,161,141,173,164,173,157,187,186,186,186,181,178,158,167,162,177,165,182,162,177,171,169,167,152,120,112,113,80,84,104,68,63,30,80,69,75,116,129,121,119,124,125,106,117,135,99,75,110,109,114,128,75,88,129,112,117,107,98,89,79,46,97,84,70,110,65,64,74,122,68,83,97,75,93,84,77,84,48,66,40,21,46,35,0,51,39,40,46,58,51,59,29,49,45,47,78,62,59,51,35,40,51,65,80,45,55,67,54,34,54,56,45,44,31,71,43,64,74,74,45,49,71,44,48,57,56,37,42,45,37,35,66,39,47,34,29,29,46,46,37,32,58,48,36,52,41,24,19,62,64,44,43,42,31,62,23,35,46,41,52,53,28,25,36,28,35,22,48,22,12,39,23,35,13,36,60,31,34,37,43,23,25,26,7,38,26,20,38,47,18,11,39,13,25,30,29,15,22,14,22,18,28,45,10,59,97,112,89,49,41,40,32,18,37,54,22,20,35,11,10,32,34,35,11,35,41,10,26,14,25,42,7,7,23,22,21,50,42,9,39,38,33,45,9,42,57,40,42,29,28,32,91,81,17,20,35,29,58,47,31,13,40,46,29,32,35,46,21,18,32,26,32,35,39,18,55,33,27,35,34,47,40,52,45,29,17,35,33,17,36,27,34,25,32,26,28,15,20,26,21,22,20,20,44,45,34,26,38,16,9,34,8,22,35,16,39,24,39,105,53,24,12,28,18,24,21,20,8,43,43,45,17,26,20,31,28,46,12,21,37,0,38,35,17,19,27,27,38,51,6,16,39,2,21,46,39,27,17,37,51,93,113,107,51,26,35,71,11,33,64,61,40,42,80,65,61,61,54,57,34,49,62,76,52,72,38,55,35,56,37,52,35,60,41,18,89,80,93,115,144,169,154,136,117,101,89,87,126,186,197,203,169,169,171,209,209,193,191,203,230,188,110,75,30,98,176,240,253,248,248,252,231,247,231,234,220,223,251,255,253,247,239,227,174,212,239,246,238,214,196,186,187,188,175,104,23,6,7,19,23,8,0,24,21,4,16,30,5,17,18,19,24,10,21,20,19,18,27,10,144,106,24,34,38,76,103,99,63,67,62,95,49,62,76,73,65,122,124,143,140,154,175,170,179,184,90,27,77,117,197,209,223,199,221,193,227,188,165,166,168,143,147,88,101,102,57,13,18,27,49,103,88,96,88,120,104,160,171,169,153,230,212,204,129,55,73,172,248,243,254,215,143,134,149,105,94,116,118,60,14,25,52,51,47,62,49,70,123,178,205,181,70,55,100,184,230,217,209,185,148,113,42,85,165,159,222,213,105,48,23,14,19,30,45,3,45,21,40,48,82,72,79,108,160,209,240,186,118,11,19,143,187,178,168,183,174,162,184,171,184,171,168,160,173,192,176,133,183,189,201,192,176,154,151,111,88,61,22,49,15,39,104,133,155,159,170,189,159,165,210,194,200,186,171,199,171,177,184,121,171,164,138,141,136,145,146,139,160,166,159,138,139,127,147,160,143,151,138,152,164,142,165,148,154,163,159,154,169,171,167,131,131,169,164,152,164,166,157,169,150,153,155,169,173,177,153,161,165,160,156,182,165,166,156,165,154,167,165,185,172,164,167,197,179,160,173,160,176,165,187,165,167,167,148,176,164,184,184,162,192,162,175,169,205,171,110,97,93,102,105,87,77,68,53,71,86,102,133,105,99,108,97,94,126,136,112,103,136,100,128,119,130,129,129,79,83,51,66,72,75,80,68,87,81,87,121,75,89,81,80,76,96,93,118,98,51,78,33,32,30,19,37,31,30,46,70,80,81,81,73,51,46,69,66,70,56,47,31,27,51,64,48,73,46,82,54,48,65,57,19,52,55,13,56,70,48,49,60,60,54,40,68,39,25,44,36,51,67,66,40,51,53,44,40,31,36,42,44,41,37,40,31,48,52,51,57,27,54,14,55,55,45,29,64,54,46,26,30,42,45,34,22,35,21,34,15,22,39,23,24,27,64,44,54,47,36,30,28,32,6,5,41,47,32,51,34,33,27,23,40,8,48,29,34,28,33,12,29,30,54,34,29,27,39,49,23,59,87,112,70,30,26,23,30,36,16,36,16,45,38,33,48,18,37,33,28,12,21,38,20,16,21,25,51,31,34,37,17,40,35,28,45,16,41,25,37,53,34,10,24,33,73,91,42,32,23,8,23,36,16,40,34,32,25,17,45,39,5,9,55,45,35,37,48,14,20,19,48,29,58,56,18,24,34,33,35,19,28,31,49,16,39,22,15,29,33,44,11,3,4,59,25,26,16,47,9,19,24,39,29,24,34,13,6,23,5,19,62,110,22,29,22,16,13,37,19,38,23,27,7,13,25,21,18,37,17,6,31,19,29,24,21,32,20,11,30,46,10,11,35,39,19,24,19,38,36,38,26,42,99,102,66,83,69,84,49,65,36,35,69,20,31,59,41,62,46,62,54,67,79,54,49,52,49,71,63,53,52,48,55,58,59,25,35,30,55,27,19,32,59,101,116,106,112,119,105,94,131,176,177,155,171,162,158,155,156,149,168,154,161,136,43,21,24,24,104,202,216,254,255,245,243,245,249,249,224,242,234,252,238,249,249,233,220,246,241,246,253,206,202,196,182,179,174,100,15,9,8,15,8,11,0,10,17,20,41,13,14,9,8,17,23,0,9,48,12,9,19,29,61,32,11,50,55,81,106,108,126,119,144,136,141,190,190,167,196,209,197,209,194,213,211,209,215,221,84,50,32,75,159,188,177,171,146,142,160,123,106,88,88,87,59,86,57,63,55,15,27,68,146,181,164,170,181,216,219,229,223,189,228,220,223,205,105,38,77,113,201,221,195,161,106,150,113,87,47,0,19,25,38,47,60,54,34,65,62,114,182,219,189,195,56,17,92,134,164,115,130,80,60,21,20,104,133,133,155,209,136,33,40,15,10,36,55,45,41,20,17,61,114,149,177,163,168,195,217,224,134,0,26,121,169,167,166,164,160,180,145,161,176,192,163,170,188,195,210,196,159,150,116,132,59,53,22,15,49,52,108,134,150,169,194,186,174,218,206,176,201,174,147,153,167,155,158,165,181,183,170,161,171,156,138,186,156,174,144,130,158,162,167,152,146,162,164,161,147,167,146,154,145,139,148,139,122,136,150,144,173,149,144,147,166,151,160,163,175,148,149,141,149,180,164,178,162,165,164,184,180,170,197,189,176,153,157,167,167,170,159,183,200,155,169,164,182,145,159,155,146,173,173,165,168,142,164,190,158,147,139,167,152,177,153,156,161,167,145,122,98,82,71,73,116,97,80,93,112,122,125,166,132,101,100,131,124,103,123,138,110,92,116,103,102,90,76,86,82,25,80,59,79,75,74,90,84,82,53,82,73,99,79,113,96,68,60,33,46,26,15,39,45,74,69,74,55,53,49,61,68,70,40,38,67,40,48,36,55,28,37,57,46,59,61,49,51,45,61,68,42,60,45,31,31,64,48,62,50,66,65,37,41,45,47,20,34,27,22,48,65,58,35,43,54,40,33,30,43,33,38,44,35,37,39,9,73,37,46,55,44,38,37,22,29,33,46,46,13,42,25,53,19,19,45,46,12,37,27,17,27,40,31,17,32,58,34,11,20,22,39,41,33,14,31,18,11,25,51,14,38,20,31,20,33,16,24,17,31,5,39,22,16,34,26,26,32,10,6,17,51,114,114,95,67,15,6,15,8,24,41,15,28,18,26,38,4,43,43,46,22,21,29,17,10,43,52,36,34,14,31,24,23,14,24,27,38,37,30,44,43,45,13,11,42,91,70,16,23,19,7,15,27,25,21,18,36,19,14,21,37,27,37,54,34,42,41,25,22,55,9,23,33,33,44,40,21,34,43,42,24,37,19,35,23,47,20,50,28,10,16,29,11,21,30,29,23,30,22,7,12,32,9,25,24,23,33,45,8,43,85,78,24,46,30,32,2,25,25,24,21,26,10,23,19,0,14,15,14,31,24,20,13,45,18,30,44,20,21,38,5,25,19,45,42,11,28,45,25,12,76,128,105,28,16,47,123,146,92,81,95,84,114,77,55,68,10,59,76,48,101,41,65,55,46,59,49,55,40,57,31,37,39,47,34,21,62,42,67,65,49,39,12,50,89,137,148,152,130,134,150,157,216,236,208,214,181,174,177,181,174,155,159,155,97,82,35,37,68,74,110,182,242,232,244,241,249,247,230,238,242,242,248,235,251,249,238,254,243,250,241,200,244,196,183,220,183,119,18,3,3,10,32,19,11,10,29,7,11,17,7,2,3,9,26,23,7,29,27,12,24,22,81,40,21,31,86,127,156,203,182,200,210,217,218,194,193,216,199,211,205,221,206,192,179,175,163,168,42,43,30,63,133,112,95,79,94,108,76,65,71,103,109,124,146,148,155,163,130,20,35,92,159,212,232,214,226,196,226,193,192,169,142,151,136,124,48,2,33,50,62,93,103,108,96,127,110,109,87,19,23,22,21,53,66,93,80,88,98,120,137,119,126,64,31,40,82,120,87,58,56,43,44,8,46,102,194,196,135,167,107,16,14,19,36,28,20,33,16,22,23,50,90,95,86,97,98,124,149,214,148,3,19,113,174,164,189,176,185,204,181,171,190,215,173,168,121,126,107,66,50,22,12,64,67,104,93,146,151,164,178,203,206,190,213,180,189,217,191,187,146,170,151,173,161,176,171,180,158,166,162,169,170,170,162,161,178,174,157,146,165,181,159,174,169,142,169,152,151,145,174,177,167,168,148,144,162,166,146,160,139,160,143,162,150,157,155,132,153,158,168,165,162,199,158,157,167,152,166,183,158,171,160,183,158,173,165,154,164,181,186,165,146,158,170,176,166,177,166,159,166,165,182,169,190,171,170,170,156,193,189,166,166,167,147,135,162,169,194,223,172,142,51,37,122,83,116,112,101,153,138,139,137,144,136,97,123,109,105,103,98,114,94,90,74,59,77,66,81,60,101,95,68,86,97,111,102,103,86,79,97,123,73,80,35,38,23,18,20,42,48,69,51,58,63,44,71,47,85,45,57,67,59,74,58,54,74,50,38,49,50,62,46,77,58,51,62,37,69,73,60,66,49,24,47,56,72,32,17,61,42,61,23,39,45,57,65,49,38,55,20,54,40,60,50,37,29,28,33,55,32,30,38,39,46,44,59,56,40,27,17,22,49,23,48,32,29,41,35,38,39,18,42,13,41,34,47,47,18,56,3,30,43,61,37,20,28,12,41,14,26,47,33,37,33,17,50,14,36,41,31,24,41,9,57,39,5,8,41,41,12,38,34,19,22,41,14,45,57,21,29,48,92,125,91,89,67,17,20,27,30,9,29,33,40,14,42,58,5,54,34,34,44,52,6,43,35,22,24,9,45,20,25,42,36,32,30,11,29,5,30,30,40,34,34,86,80,63,47,13,19,26,18,6,13,11,27,15,50,32,28,4,37,30,57,37,32,20,11,41,22,38,35,27,45,25,49,44,38,22,36,29,46,47,21,39,37,38,29,12,30,15,36,6,29,44,30,19,42,10,28,31,24,33,30,47,21,27,36,53,84,39,14,40,14,21,21,34,18,16,34,62,13,17,36,15,24,21,35,22,15,12,11,18,3,25,24,47,23,40,21,18,25,27,18,44,21,12,27,99,96,73,44,26,40,181,203,163,151,103,134,125,155,111,117,89,57,104,98,102,63,59,69,41,39,34,34,46,47,72,48,58,50,21,52,39,39,48,62,71,71,65,49,57,85,131,183,183,150,160,149,175,252,227,249,255,227,233,236,211,247,221,225,213,234,231,170,163,121,81,71,97,124,139,190,228,225,243,245,225,247,249,248,234,250,255,233,221,233,237,242,204,219,194,205,225,183,93,0,0,9,0,27,35,25,0,8,21,32,6,10,10,19,5,3,19,22,8,16,11,1,28,175,85,40,72,112,170,181,228,210,214,213,173,198,177,185,201,165,167,158,118,154,115,104,93,74,64,14,16,18,67,108,112,74,63,110,138,133,156,170,183,175,213,195,212,189,225,165,62,28,78,170,205,198,160,176,156,110,107,118,96,107,58,47,47,15,40,44,89,98,112,140,119,158,156,118,144,134,120,125,20,46,89,133,163,135,158,126,104,97,74,79,48,21,17,46,68,69,53,43,30,21,35,49,168,244,245,212,159,67,1,37,0,24,46,44,15,36,25,14,56,56,71,74,90,107,128,145,176,147,31,76,123,169,198,211,200,212,184,178,162,150,99,102,83,10,9,22,57,65,106,127,157,166,197,165,218,211,192,183,199,161,164,158,192,165,153,150,170,143,148,166,146,124,155,164,167,167,155,181,144,180,178,133,147,157,162,138,170,149,150,148,150,141,159,163,173,145,162,165,169,140,139,169,167,142,147,144,137,132,145,143,165,166,158,149,134,169,141,164,137,146,150,176,172,162,161,159,121,147,158,140,168,158,167,156,153,150,160,138,150,150,164,136,147,165,167,176,172,163,171,179,186,184,160,166,173,173,157,165,180,143,166,158,144,153,149,193,222,255,209,62,69,99,119,135,126,88,85,95,93,99,94,105,53,87,71,66,84,94,74,79,72,84,98,106,115,96,78,68,92,69,85,71,106,103,102,107,81,56,61,34,37,33,38,26,59,50,67,65,53,35,40,42,45,62,66,42,62,57,59,58,58,47,74,65,57,72,54,47,47,38,68,28,46,44,47,35,47,39,85,68,57,67,48,49,33,54,60,45,54,46,24,35,39,48,28,12,35,20,47,41,27,52,62,27,33,19,34,38,19,39,52,23,47,36,49,43,36,53,39,49,18,25,33,58,29,61,43,31,33,45,33,30,32,26,51,56,43,43,31,17,30,2,21,53,18,9,39,11,30,33,37,18,26,25,26,21,28,37,28,19,41,26,37,22,25,33,40,28,17,30,19,26,29,34,56,71,45,30,59,29,36,79,119,98,87,40,45,45,42,44,8,22,38,20,17,17,7,29,32,32,18,20,28,20,33,45,54,6,27,12,49,13,16,21,36,10,26,33,37,56,36,34,31,86,58,48,33,8,28,28,8,46,28,23,41,24,47,36,32,34,46,33,47,46,27,22,21,16,52,49,14,30,43,21,14,33,49,11,46,27,27,40,22,35,52,8,14,16,20,11,11,17,23,21,28,23,8,31,32,10,44,13,29,24,13,24,67,114,23,40,36,27,23,21,35,37,19,24,20,50,1,28,39,35,4,21,52,19,12,28,39,8,29,20,17,39,20,23,41,38,28,22,23,34,34,91,128,85,35,29,11,133,199,193,174,164,109,153,122,140,109,112,100,100,115,121,99,118,110,85,99,114,96,91,127,101,111,103,84,51,34,48,45,28,41,45,31,28,19,51,12,37,54,108,126,162,178,167,195,255,252,249,245,247,235,246,238,246,237,225,244,230,246,252,252,194,163,166,104,39,37,65,59,86,173,171,175,196,211,228,210,240,246,238,213,255,238,230,192,185,195,160,172,172,101,9,0,14,11,3,8,6,11,6,14,20,23,30,16,14,32,18,5,25,11,2,20,4,21,208,112,33,71,91,163,188,194,172,170,142,139,146,114,127,97,95,92,101,73,76,37,72,29,58,33,27,14,46,128,167,191,174,181,175,183,165,209,185,203,189,214,188,184,200,196,133,11,12,56,97,128,102,95,79,58,64,91,72,121,112,125,137,129,11,18,102,167,197,187,218,171,157,161,142,149,151,206,127,84,47,65,131,139,127,103,98,78,101,88,58,31,37,23,23,38,17,11,26,16,11,29,33,79,175,226,203,197,76,18,31,20,10,20,36,22,30,27,33,59,144,152,160,158,167,153,142,142,99,68,137,213,195,188,173,159,120,98,55,37,28,24,38,68,104,112,156,174,179,186,199,177,210,209,181,196,178,173,160,167,163,165,160,154,172,159,161,141,146,149,155,175,175,145,147,154,150,122,150,172,168,155,185,154,157,161,170,147,155,154,138,144,170,135,153,157,167,158,174,137,154,160,138,149,142,132,137,135,146,144,145,144,154,158,162,150,161,165,127,115,154,148,146,153,142,163,150,124,141,145,124,138,159,147,116,125,120,149,130,126,142,138,145,147,120,129,111,112,121,123,123,122,152,155,140,121,132,132,148,146,142,132,163,121,172,118,163,243,220,239,132,66,38,117,102,103,85,100,92,70,87,76,72,86,70,75,60,56,76,87,90,106,89,91,107,104,90,78,114,97,84,90,77,90,61,86,67,40,29,21,58,50,48,53,61,70,70,73,50,34,71,44,83,60,57,42,65,73,71,52,67,63,53,69,70,25,64,82,55,65,66,51,53,44,62,53,58,57,58,55,50,48,44,29,36,47,60,71,50,41,34,58,36,40,33,51,36,66,58,37,26,63,63,32,43,28,33,36,39,44,50,48,40,28,61,49,43,55,43,41,36,52,39,37,28,29,39,40,51,41,25,28,43,45,9,27,29,28,12,23,20,17,23,35,34,52,29,20,30,33,17,48,43,29,31,33,27,27,32,21,36,4,26,34,35,37,8,25,35,12,44,32,32,25,25,33,9,22,55,23,31,33,27,84,135,99,94,73,33,41,22,23,22,14,12,32,22,16,29,13,6,33,35,29,38,9,33,33,51,19,34,13,38,36,30,48,16,26,10,9,27,16,11,21,58,58,61,32,20,35,44,27,31,2,47,13,22,30,21,26,10,38,49,29,38,58,30,46,31,29,56,41,43,18,22,37,34,31,56,34,27,37,21,52,21,24,14,13,7,46,17,49,29,24,2,2,42,26,15,36,22,17,32,19,29,9,13,102,45,20,22,25,42,17,34,21,23,2,2,30,39,26,14,29,16,36,38,25,23,13,21,24,31,17,29,19,41,27,51,7,33,37,18,27,80,120,131,37,54,32,38,115,180,203,176,184,186,158,134,122,103,108,104,146,118,126,124,139,140,107,141,109,137,143,160,166,188,163,160,151,136,145,144,77,68,46,49,41,44,14,29,44,40,20,38,77,109,125,134,175,247,252,237,244,246,236,244,250,252,255,252,251,252,255,244,251,232,248,251,219,133,66,27,26,17,31,101,150,174,168,179,158,166,201,187,181,191,185,188,114,161,145,152,138,148,87,3,36,4,2,6,10,5,30,7,20,32,9,4,26,0,8,28,7,3,11,3,3,10,21,168,55,19,78,64,118,110,102,105,89,82,83,78,51,59,50,71,92,69,95,114,117,135,133,149,142,45,20,111,156,199,214,235,207,189,208,215,189,156,175,170,128,138,139,106,100,59,10,24,38,92,67,120,75,98,136,143,160,173,183,198,218,207,187,64,39,92,156,211,188,192,167,129,140,137,110,111,118,84,55,48,47,81,86,89,74,56,53,44,33,41,32,29,20,61,28,22,41,22,38,41,43,40,83,98,147,181,234,83,13,8,17,29,34,24,16,29,5,23,40,69,76,60,63,63,59,35,48,15,42,129,172,138,84,64,43,21,31,41,60,118,130,152,162,159,198,191,197,202,182,191,171,154,143,146,151,153,151,158,189,160,134,148,141,141,170,154,163,151,146,161,158,168,149,154,156,155,175,153,154,143,153,139,166,147,157,156,158,163,142,156,137,159,155,138,145,146,130,155,173,146,142,158,130,116,147,182,152,148,130,143,127,161,145,151,162,131,163,159,146,158,155,140,163,121,143,155,169,132,157,127,143,124,148,135,134,156,140,129,160,146,140,134,118,112,120,120,111,92,106,105,113,154,116,135,87,101,154,140,129,128,143,190,133,121,118,134,185,229,255,168,82,39,73,114,131,96,112,79,105,106,92,98,99,104,104,105,71,104,90,121,115,124,83,127,109,95,123,107,107,87,70,65,52,35,35,43,24,51,31,39,61,70,79,69,68,49,55,81,49,46,58,40,46,76,72,36,44,52,58,71,52,32,15,62,67,41,40,40,51,70,52,23,55,37,54,45,43,44,41,46,58,48,34,40,41,61,64,44,51,55,65,33,58,33,34,22,26,30,33,75,58,54,12,39,15,50,52,30,36,35,39,15,44,29,23,44,28,36,43,22,51,75,29,31,6,43,36,30,28,47,46,56,31,51,35,42,33,45,28,49,51,46,48,33,21,28,33,39,24,39,28,30,29,20,38,18,17,37,36,20,35,27,38,22,23,11,18,15,29,61,26,35,8,18,20,29,36,35,42,51,22,32,18,52,92,128,120,104,39,5,16,11,36,24,24,30,45,40,18,37,20,38,27,27,33,45,29,22,24,18,31,20,54,57,19,19,38,16,34,29,25,25,29,54,63,68,14,8,11,12,22,20,43,33,19,7,49,3,18,36,12,33,24,20,34,18,28,36,40,42,37,48,6,61,25,42,41,39,48,49,28,41,19,23,45,4,17,3,22,45,22,30,14,25,36,20,37,41,31,43,39,40,29,27,7,91,92,58,2,44,4,16,25,21,23,15,39,29,24,17,27,29,31,6,54,36,16,6,25,21,19,33,9,22,5,21,24,54,37,26,29,42,87,111,72,76,44,18,29,116,205,206,176,185,178,167,157,156,137,119,122,144,108,146,128,157,137,158,156,142,142,135,173,162,157,166,154,161,161,177,149,159,141,122,109,143,132,106,92,57,84,50,65,21,40,58,50,68,104,180,204,229,237,244,250,244,252,255,226,236,246,251,245,241,252,250,228,236,244,218,192,145,107,23,55,113,173,182,198,225,196,172,167,154,181,154,144,146,127,114,129,123,125,111,84,15,1,29,10,42,16,4,5,10,22,8,9,23,0,33,15,8,20,13,7,6,5,35,32,58,19,44,50,56,74,97,62,87,94,97,129,87,124,140,162,158,178,169,184,203,201,191,206,227,147,73,32,84,132,179,202,198,188,174,157,147,110,118,79,96,86,68,50,32,51,33,1,64,105,140,179,188,184,186,207,214,191,227,193,193,190,205,178,63,19,57,135,121,104,136,140,128,116,124,124,73,62,49,13,5,61,46,81,16,37,7,16,26,17,17,21,25,33,26,15,38,41,48,60,78,70,109,140,182,159,168,188,56,31,14,7,17,29,27,22,41,36,11,3,14,27,15,20,29,71,56,56,42,42,56,60,49,85,75,140,132,148,163,203,185,212,215,196,164,159,156,167,162,170,170,172,143,152,141,134,138,136,140,143,140,139,161,142,136,167,154,141,132,138,162,150,138,158,184,174,119,159,166,170,132,143,156,147,169,157,148,130,164,134,156,160,149,156,136,144,157,146,140,154,162,157,161,160,168,184,160,130,131,153,149,122,130,154,144,140,142,137,141,166,147,158,146,169,142,136,147,142,149,141,151,143,153,146,176,169,183,155,155,150,157,169,157,119,138,147,147,157,171,138,154,131,141,147,115,138,141,138,129,127,143,151,136,119,102,109,144,213,211,206,156,160,76,82,106,78,96,93,110,87,104,124,127,99,118,128,77,79,93,88,81,102,116,116,120,93,88,95,99,47,30,41,48,23,18,36,51,41,54,46,78,49,73,63,74,53,75,51,64,48,43,50,67,36,68,53,66,45,65,56,45,55,45,48,58,29,44,65,52,53,59,45,55,44,44,59,37,45,49,46,52,42,47,49,53,38,52,50,42,38,50,60,32,54,43,45,22,37,55,35,43,44,57,37,49,38,70,65,43,43,44,30,41,40,38,35,21,45,38,44,27,42,34,58,29,36,17,32,22,17,43,31,41,53,47,37,34,22,30,34,37,48,56,28,31,54,23,33,15,45,13,41,28,18,11,17,44,48,35,10,48,38,32,35,37,18,9,25,45,24,24,32,53,19,6,23,13,21,33,47,41,32,17,16,9,20,45,113,113,124,78,63,30,24,12,22,28,40,39,27,29,24,50,43,41,47,41,54,35,32,37,14,54,20,21,24,40,11,43,32,18,44,46,32,32,53,93,65,45,11,29,10,29,34,31,22,37,49,33,27,22,27,28,12,29,35,24,16,16,28,29,43,33,30,32,39,37,36,36,39,36,36,60,33,18,26,5,34,26,19,19,25,31,16,25,17,19,29,16,5,34,12,22,21,0,27,96,75,15,21,17,33,53,12,18,48,6,29,13,23,49,10,9,33,18,40,54,34,42,36,36,19,27,17,27,36,23,55,23,35,0,50,121,110,91,36,25,29,29,103,163,186,193,154,188,191,167,196,175,149,142,134,125,153,166,140,178,174,158,156,151,166,173,175,185,159,173,145,131,167,157,170,161,144,149,145,147,136,135,136,122,128,89,84,63,11,39,7,14,11,77,103,125,128,159,180,234,232,247,246,239,255,250,254,253,250,253,242,250,230,251,247,242,211,150,122,123,155,212,237,242,224,194,191,164,169,181,149,154,164,187,173,161,146,108,69,13,17,12,1,24,5,13,0,9,7,11,26,9,9,13,21,12,22,5,32,6,12,4,9,43,40,26,78,105,127,147,162,163,192,172,205,205,199,212,185,215,209,213,229,186,204,188,175,166,139,14,11,69,125,142,148,152,105,78,78,79,69,76,65,69,103,90,137,129,167,78,30,90,110,179,191,196,195,219,197,211,212,201,167,136,135,135,86,1,29,68,88,134,101,132,143,130,144,124,97,64,41,34,1,39,19,21,21,24,24,9,36,14,17,16,34,30,26,35,36,17,94,181,116,191,164,185,187,224,222,145,122,32,29,17,2,40,25,34,19,33,19,36,38,40,11,20,42,52,43,50,62,34,16,83,139,130,165,172,175,191,172,187,185,165,166,158,174,153,167,165,156,148,157,161,126,158,138,144,136,135,161,141,148,153,163,141,152,151,149,146,163,154,148,142,152,150,177,135,146,157,149,127,154,151,141,140,162,128,148,140,142,148,150,153,151,165,164,153,163,145,139,155,150,141,156,149,132,161,158,176,135,175,126,134,149,136,129,159,165,147,165,115,137,151,147,163,175,181,172,138,142,172,173,155,145,165,152,125,136,152,151,160,148,141,152,143,143,110,167,143,180,173,187,164,152,142,151,155,130,166,153,168,166,136,165,134,132,94,106,112,169,215,159,106,152,145,110,103,83,108,75,60,91,104,77,108,107,98,112,90,102,114,86,134,104,122,81,91,81,54,45,41,29,40,24,49,31,38,73,51,62,73,58,50,55,51,56,50,81,57,45,59,60,47,61,23,50,64,62,47,70,49,32,58,24,65,60,36,27,38,56,44,64,77,49,28,37,66,36,34,66,50,52,41,44,29,39,70,46,72,38,40,18,50,32,38,29,54,40,54,29,43,47,46,36,12,30,41,45,34,48,45,32,47,21,43,55,34,32,53,38,68,37,27,39,39,42,43,40,36,48,53,26,40,53,27,34,39,27,52,30,43,26,16,38,35,83,27,31,60,10,29,12,38,19,20,34,16,39,47,33,54,25,18,28,18,29,27,35,38,19,28,33,14,25,44,18,48,28,48,17,18,35,12,23,39,32,24,20,22,33,79,133,142,83,74,50,50,10,14,38,49,38,26,45,23,36,17,35,23,24,59,34,30,33,11,27,18,37,39,16,17,37,17,15,12,23,34,44,76,87,57,19,20,16,19,29,4,32,37,24,18,21,59,58,43,32,37,46,42,35,20,48,26,32,42,49,35,40,18,25,16,40,24,36,32,19,45,29,16,27,16,19,30,25,16,23,38,16,36,47,27,27,15,18,15,24,9,28,96,22,12,17,28,17,19,26,36,2,15,24,10,50,29,39,29,34,37,23,53,23,39,32,60,37,4,28,31,6,8,25,26,4,93,120,86,52,41,41,36,63,94,132,189,198,156,165,160,175,167,165,175,159,159,142,84,106,144,154,189,169,203,160,185,168,145,162,167,177,155,156,179,159,149,153,161,139,151,133,179,165,139,167,130,106,95,84,58,43,69,38,24,20,41,82,90,95,72,84,107,105,123,144,179,205,211,203,252,229,242,248,255,245,255,242,255,223,226,219,196,213,239,230,229,215,175,202,215,217,209,196,168,171,206,192,200,181,141,93,9,17,7,19,1,28,9,0,42,28,32,0,20,3,1,15,8,4,27,7,11,22,19,25,111,62,27,96,145,178,195,215,196,218,194,193,205,198,188,195,151,166,179,147,137,133,115,87,86,34,10,34,30,55,66,72,86,59,93,93,103,114,173,173,175,187,202,197,193,219,126,42,64,113,214,207,200,206,173,142,150,117,108,128,108,94,96,52,18,44,43,100,110,157,180,162,146,117,135,116,18,5,6,24,20,50,47,7,6,31,26,36,23,19,41,42,51,24,29,18,55,79,122,126,133,112,135,130,181,179,195,129,14,28,41,8,38,21,40,44,35,20,57,50,58,36,49,65,79,61,56,44,61,105,161,180,189,193,184,168,153,173,159,149,135,135,157,148,131,121,140,131,102,157,124,164,132,157,154,131,151,148,127,140,138,139,135,123,162,152,133,140,146,144,130,149,145,144,120,140,150,149,149,145,145,150,161,116,160,166,141,167,154,159,144,159,132,160,148,141,148,165,137,164,163,162,146,148,128,157,174,133,170,159,158,132,149,143,152,166,156,184,154,144,170,156,158,144,150,154,172,171,115,124,140,140,132,148,138,154,147,159,115,122,131,149,121,108,109,121,140,115,114,142,143,170,155,132,151,143,132,114,163,120,113,146,141,113,99,49,42,85,143,66,66,72,115,129,95,115,104,70,43,85,61,73,89,104,90,109,79,99,80,89,90,84,79,34,35,34,43,37,43,49,49,66,32,59,59,69,60,54,101,50,80,88,60,64,34,64,50,50,35,65,70,41,60,36,60,34,51,41,64,51,56,52,75,52,65,57,62,41,40,62,45,30,60,66,11,56,44,63,25,36,43,38,64,47,58,17,56,38,36,68,50,75,49,32,22,43,38,46,16,50,51,26,29,53,26,33,25,63,53,40,31,13,48,20,35,26,34,42,37,17,15,32,48,38,50,49,34,29,48,43,40,38,31,43,13,16,16,22,56,29,17,40,13,42,50,24,14,26,14,45,45,23,50,27,14,43,14,35,60,39,40,17,33,6,25,15,30,10,35,33,30,56,17,26,25,35,16,31,36,45,33,40,37,27,37,39,15,12,42,57,91,143,116,109,54,42,35,24,35,29,55,27,65,56,27,20,6,50,49,28,9,31,26,27,33,25,45,40,39,42,22,19,26,27,39,21,97,101,63,43,16,26,15,9,26,9,44,21,27,15,52,27,34,39,22,27,25,33,30,45,20,39,25,18,27,41,19,2,32,13,23,37,41,39,41,30,18,34,27,31,40,17,27,17,17,10,17,13,2,38,16,28,9,8,6,60,69,16,16,4,37,44,29,26,14,46,8,37,24,29,21,19,7,11,4,10,10,40,10,26,26,24,37,31,29,27,37,17,48,93,110,76,39,28,25,17,69,95,127,180,197,194,186,180,165,190,158,216,169,132,154,171,125,96,100,101,128,155,171,153,128,140,153,161,147,159,143,170,177,158,149,145,142,142,145,167,159,166,154,145,138,135,132,111,100,79,88,82,72,88,125,145,132,130,97,63,82,102,77,104,140,135,122,147,124,130,141,179,186,194,207,234,235,216,221,206,241,241,249,180,138,159,168,177,196,232,236,215,211,228,224,243,230,203,193,110,4,11,1,9,11,15,26,23,18,29,29,21,18,5,15,9,13,22,8,13,29,23,11,31,158,49,55,109,143,182,175,185,167,169,155,184,135,141,119,108,91,109,100,58,57,61,54,46,49,44,38,24,54,76,88,117,129,152,173,193,191,212,214,241,208,232,204,212,228,203,111,37,25,78,137,129,140,87,95,65,81,72,127,111,106,103,125,76,28,17,56,44,87,123,179,161,150,120,118,66,25,21,20,22,21,40,41,33,6,14,25,14,35,22,23,12,34,51,22,26,21,58,64,145,57,44,51,108,111,176,213,195,100,21,38,34,44,58,17,55,33,29,27,39,41,71,105,146,100,118,150,170,187,181,172,162,144,149,128,136,142,137,145,149,133,145,134,133,144,139,152,113,143,138,139,154,138,138,146,135,170,151,145,150,142,146,108,142,138,137,142,140,134,135,153,133,142,113,138,120,128,160,113,157,144,151,152,165,146,116,142,153,153,135,109,162,149,124,154,144,128,165,166,151,177,163,135,169,163,148,126,153,136,137,152,143,141,126,154,118,153,163,154,157,176,151,128,141,150,160,143,138,145,153,143,129,162,131,126,147,162,142,138,149,153,150,156,167,140,160,139,129,138,149,143,132,180,144,129,127,135,112,142,148,114,149,177,140,143,86,62,52,61,36,47,75,58,118,79,96,135,177,128,40,0,15,28,50,76,65,51,56,70,47,47,61,34,62,30,49,60,45,46,50,63,55,63,46,60,69,68,45,72,91,65,27,44,42,41,65,54,50,56,60,48,102,70,53,67,71,71,66,51,70,72,68,43,59,60,85,53,28,61,36,68,61,71,63,58,36,55,46,57,38,41,56,38,43,43,60,64,9,48,45,56,28,29,40,22,46,19,48,39,58,59,35,35,50,55,49,20,40,46,30,36,25,51,28,33,36,16,46,59,25,19,25,58,25,64,38,56,47,25,45,10,36,42,51,20,14,27,23,27,38,64,42,16,42,27,31,42,35,37,4,46,29,32,23,40,45,28,28,15,25,32,43,30,1,32,34,11,5,34,32,42,13,21,23,11,22,26,23,7,24,40,22,37,35,40,15,15,32,24,29,44,25,83,139,143,106,61,76,34,9,8,18,23,19,15,22,22,34,27,36,37,27,47,42,25,19,21,14,38,19,35,29,26,48,48,35,53,75,90,70,20,26,4,25,22,23,13,6,20,31,35,42,61,25,40,15,24,25,42,28,42,46,35,54,42,51,16,46,35,25,41,27,41,46,56,31,29,25,8,6,26,16,22,27,14,20,39,38,28,39,33,29,19,16,42,70,58,2,17,27,2,28,6,2,51,13,41,31,19,28,51,11,7,19,35,9,21,15,34,26,45,33,39,23,16,40,58,91,119,89,58,21,30,60,41,66,81,106,154,207,182,185,172,157,139,160,168,181,178,157,192,181,119,113,112,69,104,154,159,151,158,170,161,163,164,170,136,171,174,155,167,170,182,174,179,181,139,175,156,188,201,169,156,145,120,92,110,117,107,103,145,143,158,173,138,109,103,111,123,145,124,131,123,156,139,101,126,130,153,148,117,195,173,170,170,193,216,209,173,104,64,137,115,131,158,230,244,247,252,232,237,248,251,242,218,113,6,0,11,43,15,27,20,18,15,6,8,11,2,0,14,10,60,11,26,26,10,18,12,24,141,27,50,46,82,119,144,116,97,109,106,89,70,51,53,48,39,65,78,79,93,122,119,99,149,68,12,59,68,105,173,170,199,199,222,217,224,188,201,183,203,171,165,134,108,121,53,16,22,42,79,113,111,97,82,62,99,75,63,82,46,53,36,38,17,33,8,39,16,80,135,163,134,135,156,90,23,19,16,25,4,38,44,10,10,25,13,22,4,21,22,17,15,20,30,7,77,92,133,120,121,133,108,126,154,144,206,189,87,34,16,40,22,24,54,19,10,24,27,48,46,64,142,150,169,170,175,185,175,169,164,131,161,170,159,146,140,141,149,143,139,139,135,165,169,142,134,139,144,164,122,141,145,147,137,120,135,148,129,149,161,145,138,154,170,136,127,129,134,144,144,139,123,156,125,134,128,168,157,157,133,161,171,158,152,167,131,151,147,138,111,154,121,142,151,136,150,124,126,142,160,141,143,158,155,161,145,143,162,165,148,135,137,150,121,159,154,158,137,140,135,133,154,148,144,154,158,150,140,165,145,177,149,143,150,121,137,166,154,157,182,155,149,159,143,177,154,143,146,160,122,155,141,128,156,141,136,151,157,138,135,170,153,150,124,85,69,47,22,56,81,76,74,67,57,125,223,251,242,205,116,55,24,16,35,10,16,14,61,46,36,47,52,73,61,77,69,55,68,49,83,36,28,46,54,46,65,28,69,44,56,66,43,75,52,37,61,55,57,49,46,66,52,58,61,48,66,53,63,55,45,80,62,57,50,44,57,70,37,59,46,44,76,57,75,28,62,58,84,64,53,65,39,27,40,74,42,49,26,60,47,56,55,42,22,39,30,39,16,39,58,57,47,44,43,51,42,39,43,40,61,21,52,31,44,37,21,35,26,48,32,29,53,53,13,25,38,41,29,52,21,30,58,34,40,40,24,16,23,39,18,30,40,33,20,36,25,17,12,40,39,39,29,36,35,34,40,44,17,35,40,42,14,24,19,26,42,32,23,15,21,27,15,31,24,16,33,41,26,38,47,42,43,20,15,43,27,20,15,18,31,15,33,50,66,145,134,129,108,72,19,30,17,8,1,32,19,45,24,34,19,15,38,45,38,12,43,41,52,33,27,36,28,24,30,23,36,36,76,65,61,43,5,34,42,18,35,9,21,34,41,23,32,37,41,34,27,3,29,41,17,14,34,35,15,34,47,51,39,30,34,11,28,28,32,22,43,39,25,0,11,45,23,20,22,16,8,24,38,34,32,17,39,30,51,53,33,19,19,19,27,20,4,23,10,15,39,15,19,14,39,51,24,14,0,6,12,17,24,40,35,15,42,27,41,65,119,109,68,57,39,32,18,24,55,73,131,153,175,209,185,170,158,142,164,152,155,154,163,155,170,161,149,147,120,126,75,126,164,195,182,177,190,188,153,181,179,150,185,199,181,153,189,160,168,178,139,165,181,177,191,146,164,153,149,151,123,106,158,136,133,151,150,151,140,167,128,159,173,168,164,154,159,155,149,165,151,146,129,136,141,143,156,141,166,142,146,152,150,67,24,96,75,98,117,207,236,235,248,238,250,244,255,255,223,111,7,0,2,35,10,15,18,23,9,10,6,25,24,2,7,0,22,0,7,7,1,11,18,21,80,8,40,39,92,98,65,61,77,60,63,73,78,93,106,120,145,149,177,157,185,193,194,195,182,97,58,48,105,152,166,227,197,149,153,145,142,136,105,115,100,103,106,63,74,20,40,29,12,66,64,69,75,34,22,32,39,14,19,24,15,13,34,38,41,26,28,24,49,59,132,131,112,126,119,93,46,24,15,7,26,27,9,33,33,2,31,61,45,50,16,35,2,58,36,43,23,99,135,146,142,160,145,142,116,72,56,44,45,27,10,40,28,36,26,27,48,30,45,15,43,61,144,161,171,189,165,136,162,158,145,136,145,153,163,142,162,167,146,129,167,161,143,174,151,164,146,142,139,136,116,137,134,156,148,137,140,164,167,149,152,128,132,141,131,142,132,124,152,160,153,126,150,120,169,144,157,130,138,159,146,178,150,143,176,141,149,153,172,152,153,151,133,149,166,128,130,169,146,130,116,119,118,114,112,142,145,132,165,120,160,147,112,117,139,112,124,114,125,116,142,145,131,148,127,163,156,138,131,147,147,141,144,149,148,143,140,144,130,118,142,120,132,97,86,109,146,117,127,143,105,121,101,109,107,122,141,122,114,94,106,97,111,98,41,36,58,37,53,32,28,22,50,39,48,77,175,224,240,254,245,229,163,99,24,18,8,17,32,36,57,58,82,66,64,76,79,65,55,42,73,77,79,65,51,53,52,51,56,82,62,47,66,54,42,49,50,70,68,19,50,59,27,64,74,49,63,43,59,59,60,43,41,69,78,59,54,41,65,52,64,35,63,44,54,20,43,62,52,80,48,60,60,49,18,54,47,37,36,51,36,47,63,17,40,37,57,53,36,22,46,34,56,53,16,42,40,38,43,45,24,30,6,38,58,22,43,52,53,32,27,45,45,43,46,51,37,45,47,68,42,16,25,42,22,34,6,54,28,48,39,27,20,42,28,45,37,31,25,17,16,34,62,33,13,42,26,18,33,32,44,28,18,44,6,8,34,29,22,52,13,33,28,32,17,28,2,29,9,21,18,21,47,22,36,31,29,15,20,13,29,6,29,37,46,67,73,156,138,146,109,77,39,32,21,40,10,20,47,30,26,21,19,20,32,68,22,5,46,30,36,51,71,35,36,15,45,28,38,90,76,46,13,13,38,1,34,34,30,23,58,52,59,41,60,21,12,28,14,30,61,16,41,58,11,43,36,38,51,43,21,43,39,32,17,23,28,14,25,9,48,41,20,9,13,6,35,10,18,41,6,13,8,32,81,60,8,28,11,8,23,29,19,16,24,6,28,14,10,32,25,34,34,16,30,35,37,23,36,26,45,34,31,75,130,120,83,28,51,14,35,26,62,82,78,108,108,162,199,187,161,170,159,148,170,161,152,183,122,141,180,158,178,174,178,158,110,113,107,149,178,185,162,153,165,169,156,175,163,185,142,165,173,163,185,153,164,187,182,172,170,168,190,167,154,131,134,102,120,142,140,155,162,162,164,155,164,150,163,176,179,159,143,149,163,133,126,144,130,110,115,138,148,144,141,126,180,148,151,104,90,79,78,48,65,133,180,186,205,218,230,247,242,251,228,116,0,14,4,0,18,0,22,15,45,14,38,12,9,0,13,11,8,6,9,4,26,14,33,12,32,37,88,58,79,100,113,109,114,157,158,160,167,188,175,176,183,200,184,198,160,183,199,168,153,46,30,41,104,131,141,130,130,100,81,67,58,76,82,51,54,49,60,80,54,51,21,2,13,12,30,57,27,35,24,18,8,28,6,36,8,17,39,42,40,34,62,46,26,69,132,130,102,151,117,84,22,17,19,28,48,24,33,47,14,55,33,20,17,4,39,25,34,45,20,28,45,47,44,86,56,60,48,45,36,29,31,11,15,16,42,21,56,57,95,82,82,92,100,109,120,108,139,166,174,190,167,145,137,151,131,148,124,139,136,129,121,129,128,156,126,135,133,154,129,161,135,175,152,139,140,167,142,121,148,140,133,144,125,124,130,129,139,138,133,154,137,139,160,179,162,179,158,147,139,137,129,154,117,160,155,135,150,156,135,181,140,163,106,139,143,145,130,134,131,110,140,146,134,133,152,149,116,136,127,133,131,142,156,124,155,153,166,132,138,135,133,126,134,118,159,154,156,160,144,138,142,136,136,121,162,147,152,113,138,99,131,122,126,94,96,89,134,97,113,115,102,104,120,113,116,109,135,89,98,113,131,110,90,88,84,104,47,79,85,82,65,84,75,69,62,11,50,60,48,18,99,182,219,237,243,234,225,224,162,89,46,41,21,15,48,78,79,82,105,60,88,76,79,56,33,47,47,45,57,50,60,50,54,53,41,68,47,31,69,27,81,62,52,63,42,60,38,26,58,47,51,77,62,46,38,49,58,49,64,40,55,39,53,41,43,58,40,36,42,45,43,40,40,57,64,59,12,37,36,43,70,53,69,56,45,48,51,30,51,40,46,38,70,36,46,40,49,59,28,16,56,47,26,41,43,46,4,32,39,43,50,30,29,43,52,32,36,16,21,33,27,22,36,18,23,28,31,35,23,16,33,44,33,24,33,58,60,18,38,31,31,57,29,34,32,34,26,35,47,17,38,43,31,30,28,28,42,17,25,39,15,40,8,19,20,37,28,26,37,21,28,21,12,39,3,27,22,21,29,23,24,44,34,22,43,27,29,31,35,51,18,40,69,140,155,153,132,81,32,47,34,29,11,8,55,41,53,22,36,10,52,30,23,25,33,16,22,3,21,24,33,26,29,82,137,78,23,17,4,14,38,29,18,5,51,36,18,42,31,21,26,18,17,40,36,24,33,24,30,43,49,30,25,28,27,12,45,30,43,20,28,19,34,29,18,10,27,49,2,9,13,14,16,12,4,24,50,34,68,50,25,29,27,31,23,35,7,21,4,20,49,24,13,23,13,24,27,40,41,26,23,3,14,15,33,83,98,111,92,39,35,54,37,24,30,31,69,101,91,122,152,179,148,162,176,183,158,177,171,159,157,129,159,150,188,190,173,186,168,163,113,101,102,99,139,174,178,169,146,183,182,170,170,178,176,172,162,183,177,181,191,182,169,167,183,181,175,176,172,163,129,146,157,153,158,136,190,175,161,154,148,179,156,154,181,176,154,137,147,133,155,145,144,154,124,132,123,120,105,160,170,174,166,141,176,141,82,39,64,86,98,111,129,138,170,204,205,202,239,147,2,6,14,19,26,8,0,27,10,22,17,20,21,4,18,19,9,20,14,12,3,0,18,7,41,67,51,72,170,195,192,187,174,184,202,176,189,172,184,183,182,183,161,174,156,165,153,120,83,17,19,33,72,99,93,106,68,108,91,111,118,79,72,66,73,61,41,26,22,36,28,35,29,26,30,8,13,15,13,35,37,31,25,12,26,13,45,19,36,48,105,98,111,145,194,145,136,152,152,80,0,9,33,4,35,52,23,32,32,27,19,41,10,13,31,12,26,51,24,35,56,39,40,44,18,35,15,21,19,29,14,18,42,42,62,76,133,172,179,212,188,198,185,205,225,211,170,166,177,122,137,142,155,145,150,141,117,147,136,153,141,153,129,137,133,118,123,140,126,128,134,127,126,130,124,165,128,150,137,144,138,144,102,154,140,159,145,134,157,144,131,153,100,143,132,121,141,149,135,150,139,124,121,124,123,145,114,142,142,119,138,133,120,112,111,153,111,124,133,134,138,157,115,144,155,117,134,136,105,123,146,136,140,134,144,131,129,150,143,130,114,130,122,114,124,153,115,139,148,126,132,129,141,140,128,129,100,118,91,124,130,130,146,137,120,133,121,157,117,166,160,150,132,168,159,173,147,130,114,106,94,81,81,118,97,81,92,76,51,63,79,90,94,93,67,91,70,17,64,17,83,121,125,189,251,241,253,255,250,233,159,63,18,10,10,48,39,67,94,43,74,54,53,64,39,53,81,55,38,61,48,71,64,60,67,59,28,56,76,41,87,68,54,44,41,62,44,54,67,52,68,30,86,70,60,43,56,47,40,62,56,40,55,81,30,56,38,45,34,65,45,64,30,36,52,53,54,50,41,55,45,39,35,78,51,33,28,51,59,25,27,50,11,21,52,45,48,31,47,50,25,34,27,36,25,42,19,43,34,22,40,23,29,29,29,33,26,39,45,47,38,12,48,47,49,36,21,33,25,11,13,9,46,24,61,15,19,23,35,47,57,34,13,13,40,40,18,0,33,15,30,22,15,13,31,24,14,32,26,30,18,35,16,18,37,37,28,63,27,46,10,39,20,45,28,13,20,21,28,17,18,21,16,41,50,30,51,42,8,20,18,50,47,44,58,113,182,174,146,120,100,77,68,49,19,33,28,34,30,33,9,11,16,42,22,45,16,17,39,23,33,31,31,18,72,96,51,49,16,29,36,25,19,36,20,61,30,52,41,30,15,17,25,43,22,31,44,43,28,34,13,49,38,34,9,16,33,37,21,19,18,32,12,11,13,45,23,45,12,32,22,32,30,20,68,16,52,54,21,28,32,15,17,47,48,29,23,28,24,33,37,6,9,11,30,24,9,4,30,22,28,24,47,81,113,127,82,70,25,36,28,34,6,12,57,87,103,101,98,134,185,205,176,180,174,176,162,174,177,189,164,151,210,158,203,158,164,149,136,152,158,153,99,83,108,137,155,198,197,197,173,187,138,181,148,154,164,155,185,164,162,178,180,156,146,178,179,193,165,168,152,124,139,131,150,155,153,168,154,164,144,145,160,174,189,157,150,175,169,162,165,138,160,130,127,118,128,134,155,148,163,175,182,173,191,179,131,130,113,116,102,73,26,80,91,124,173,160,192,100,10,3,17,26,6,26,19,8,10,11,29,10,16,2,17,4,17,6,8,4,11,18,24,24,65,79,92,114,179,171,205,188,171,178,188,192,179,171,141,165,168,129,128,107,97,108,80,55,39,29,42,21,76,123,129,94,111,131,110,58,35,32,58,16,19,48,44,31,29,9,42,44,16,35,13,30,45,2,19,25,9,28,9,26,8,24,22,37,42,55,132,156,184,189,205,155,137,134,142,68,36,5,28,24,20,38,19,13,25,20,26,67,47,48,46,40,49,48,51,6,26,29,25,56,27,16,32,29,53,19,59,77,82,125,149,184,196,212,217,217,195,177,173,185,206,157,177,165,142,142,149,150,149,140,153,139,118,130,125,122,163,145,121,138,137,127,115,104,119,106,126,125,140,116,116,120,137,130,140,140,147,174,150,141,155,134,127,139,143,130,153,133,111,132,134,124,122,129,120,145,114,128,105,143,160,125,152,136,121,121,126,132,121,135,117,153,104,132,134,138,127,115,81,118,136,149,140,143,128,121,121,137,136,132,130,128,139,138,153,132,140,142,138,142,137,129,124,125,106,123,136,118,143,120,131,108,115,129,101,117,76,110,116,156,126,141,112,126,132,130,105,150,147,140,153,126,122,120,88,81,84,68,54,76,76,101,80,93,76,72,82,68,93,99,67,70,54,75,67,19,101,115,90,97,114,175,254,250,246,252,220,244,177,86,41,0,10,17,56,44,83,66,49,43,54,39,51,51,52,78,42,67,42,73,60,41,46,61,69,62,71,62,32,53,42,49,73,55,60,45,36,52,58,51,40,47,24,61,58,77,51,26,46,46,29,62,48,47,55,34,34,50,26,48,65,37,43,51,46,43,42,44,49,26,23,17,46,68,41,30,49,35,36,44,29,31,23,40,47,27,19,40,34,47,54,30,49,43,16,21,43,49,38,35,32,45,45,45,31,28,36,30,25,31,23,21,22,39,30,24,20,11,26,44,50,45,13,40,35,25,55,16,23,34,43,30,26,32,6,31,15,28,32,22,6,47,36,33,17,21,36,40,31,31,60,33,17,29,12,18,31,25,58,27,15,13,23,26,28,31,37,29,26,54,45,50,44,20,29,24,35,43,5,38,27,41,34,64,127,136,158,163,133,91,68,45,17,14,38,18,41,1,25,44,41,47,54,3,27,23,11,8,40,7,31,84,78,74,39,16,22,13,17,18,43,49,38,40,24,26,30,11,33,28,20,40,20,29,36,27,32,25,15,7,19,32,39,14,41,16,17,7,9,14,18,32,20,23,13,43,36,17,32,33,28,32,94,50,9,6,22,25,15,11,20,42,7,25,22,21,14,20,8,17,32,12,18,17,36,18,48,99,129,129,109,61,25,37,40,24,14,25,48,40,79,101,107,125,118,182,189,173,169,155,177,198,162,202,172,144,173,167,174,172,172,153,159,181,167,161,164,161,161,96,92,108,140,141,175,174,190,195,156,179,181,185,162,151,149,141,150,141,145,150,165,164,170,197,162,158,137,138,136,131,146,144,147,177,183,172,174,155,152,165,166,172,163,140,160,140,165,163,171,155,169,156,166,148,143,173,158,160,185,154,202,195,179,188,174,165,155,109,75,50,57,61,94,123,138,108,18,8,19,5,18,29,33,11,9,13,5,31,4,21,6,7,16,17,19,4,35,22,9,12,51,31,73,94,156,176,168,168,135,148,118,116,104,95,108,86,52,63,82,58,52,66,63,82,94,42,27,38,36,64,75,44,42,20,15,47,21,12,14,24,18,37,17,34,29,30,21,5,39,18,17,45,21,29,16,33,50,34,18,42,35,15,24,33,29,44,61,126,137,122,137,121,115,137,123,77,44,19,20,31,36,28,41,32,34,38,54,29,30,40,11,32,18,11,43,25,29,27,15,24,36,16,68,61,57,137,137,125,200,217,189,199,170,161,159,152,168,181,168,168,167,123,149,165,129,154,137,160,146,154,136,115,138,159,107,153,147,122,139,130,117,142,132,121,127,114,138,137,124,132,112,122,132,138,108,132,161,150,146,128,111,99,81,138,103,133,117,113,140,132,140,138,104,131,142,154,143,148,164,134,167,141,138,124,116,146,142,127,141,131,120,124,112,147,131,139,130,106,105,123,122,145,134,95,122,97,128,130,156,126,120,129,136,103,129,133,120,112,126,121,132,120,115,123,141,126,143,139,122,135,104,111,129,118,110,117,100,95,109,94,83,57,108,88,56,94,90,113,102,84,109,125,132,120,102,107,109,109,108,98,89,86,114,67,84,92,78,75,56,68,69,59,86,79,61,51,68,109,102,99,124,123,151,206,255,212,254,252,254,247,147,70,15,0,1,28,28,56,34,52,56,68,49,51,76,53,42,31,78,67,46,65,55,39,65,37,52,70,25,34,41,31,63,39,43,48,62,44,73,61,67,45,65,56,47,41,73,57,33,66,35,66,47,60,50,60,35,51,43,57,50,37,53,58,57,63,31,41,55,65,44,12,35,50,43,29,27,33,11,45,18,30,31,53,25,29,49,41,31,43,47,48,49,42,47,31,26,30,28,32,60,34,46,16,35,41,26,21,22,25,36,62,22,43,37,46,27,34,60,35,49,28,10,42,8,25,45,50,27,15,39,21,38,32,18,14,46,36,17,35,39,29,20,6,39,15,34,24,23,36,30,52,26,21,18,23,14,23,10,16,15,32,22,6,44,46,31,44,35,47,31,26,38,19,34,38,19,31,59,17,34,34,51,53,48,55,66,134,112,168,168,150,100,75,44,43,29,26,25,21,31,22,39,58,27,13,27,22,20,27,35,32,105,82,68,21,25,6,30,25,44,47,56,27,27,28,61,26,41,71,43,22,37,16,31,33,27,39,22,24,33,39,28,29,28,11,11,23,23,13,29,25,31,24,21,15,21,9,29,32,8,40,29,49,26,33,18,7,8,24,21,30,25,6,28,37,5,23,11,16,21,27,25,34,64,79,129,113,63,58,34,38,45,45,29,32,23,34,74,118,105,113,97,107,179,178,175,138,129,188,175,160,180,169,124,134,160,181,172,129,176,166,168,167,162,165,171,171,150,158,115,77,96,119,173,197,215,156,167,177,185,167,141,169,159,158,180,148,161,155,142,163,164,170,165,153,144,154,147,142,169,160,160,177,141,171,155,167,194,167,180,173,165,162,167,180,174,143,163,149,188,188,151,166,145,157,191,161,187,182,176,213,206,201,189,199,188,154,118,51,72,44,50,57,112,111,29,2,20,16,27,23,27,26,31,5,12,8,35,4,27,5,19,32,11,18,57,22,21,14,46,41,66,63,116,111,109,110,82,88,60,71,75,73,71,91,87,94,92,85,80,44,42,62,28,49,23,14,20,35,19,30,21,13,17,27,17,9,17,24,5,25,29,26,29,20,29,28,25,11,18,18,35,6,21,11,22,40,20,26,20,28,43,19,38,38,57,85,74,102,115,163,144,135,122,96,20,22,23,31,43,38,61,23,41,29,0,26,8,31,26,7,38,33,40,12,20,47,30,66,41,70,63,137,166,168,208,209,208,184,167,160,163,185,152,166,126,158,188,176,174,161,147,169,140,129,145,124,155,144,146,139,144,130,124,125,153,107,130,121,118,146,168,135,133,97,113,147,114,119,118,135,136,121,112,116,108,97,74,67,123,109,102,131,97,101,107,105,122,98,89,96,97,106,81,108,109,118,89,97,112,123,106,96,121,114,138,113,113,121,128,149,133,130,139,116,81,130,108,136,122,143,136,104,128,89,115,99,98,119,103,104,104,122,93,93,132,97,94,102,135,128,110,116,127,118,149,136,137,101,90,134,139,110,96,129,118,89,68,72,82,133,66,74,105,109,91,93,94,124,118,133,145,105,148,128,108,105,144,122,121,120,99,106,93,92,73,86,49,93,74,61,72,81,78,38,68,91,123,155,159,151,137,137,184,227,254,247,252,250,246,246,182,111,38,4,12,28,30,47,32,48,38,35,55,43,61,64,60,71,81,89,61,55,71,69,37,44,45,43,67,54,67,42,64,49,20,45,61,72,37,60,60,69,48,48,57,60,52,52,5,48,34,51,24,39,64,36,48,55,32,36,58,58,75,54,31,52,24,55,16,21,48,51,30,25,14,40,11,44,42,27,31,48,29,43,41,46,20,52,37,30,20,20,23,26,20,47,28,34,46,32,31,32,51,40,21,33,32,28,12,31,29,41,21,34,27,34,38,31,67,32,40,18,64,16,16,38,16,59,52,23,26,28,35,31,51,33,10,16,8,26,32,2,12,24,1,15,30,53,27,13,22,14,34,36,28,31,29,39,23,51,22,47,23,33,40,28,24,24,46,37,28,54,5,22,25,19,20,27,19,46,57,47,25,28,32,48,42,67,116,186,174,153,148,143,109,68,33,36,45,41,32,41,19,24,35,23,48,19,28,25,75,58,68,31,41,20,15,8,31,29,37,40,19,33,14,35,54,53,55,41,49,46,19,30,28,47,17,19,24,24,33,48,24,53,30,17,28,12,29,29,21,17,21,9,15,40,12,20,39,54,19,3,34,15,21,21,48,8,19,45,40,31,44,31,25,30,24,53,36,84,96,126,153,110,62,46,48,28,3,48,26,16,35,50,36,67,93,123,130,109,92,150,199,182,165,159,149,155,171,182,170,180,164,158,190,186,136,155,183,162,158,160,173,159,168,200,180,192,159,135,128,88,103,134,182,163,161,170,153,130,159,173,185,156,161,178,160,153,163,168,177,172,199,160,151,152,145,129,125,134,162,160,184,145,145,177,151,150,166,171,140,165,158,150,133,141,157,166,159,156,135,167,137,162,175,163,149,173,169,194,188,213,195,191,183,195,170,161,106,52,39,61,74,79,3,11,10,9,18,18,19,27,21,4,5,38,27,11,3,7,23,23,11,4,34,18,13,23,39,28,39,69,89,102,91,92,97,99,104,112,100,106,105,63,62,44,47,21,39,2,26,17,38,32,12,35,53,31,17,22,30,51,3,21,26,38,31,32,27,18,19,47,42,41,45,19,16,37,20,34,45,22,11,27,5,22,56,13,16,7,21,11,26,60,85,117,127,143,132,159,136,113,110,77,46,32,30,11,28,19,19,51,52,48,13,20,29,18,33,18,26,19,30,16,34,94,106,143,166,178,177,217,196,204,181,195,174,184,173,173,160,176,177,163,157,139,166,161,151,143,142,126,127,138,148,171,139,140,116,115,113,144,110,103,139,120,152,127,151,138,148,149,139,104,151,111,120,146,93,93,114,125,138,98,131,95,107,135,107,114,147,111,128,113,124,115,115,100,122,103,112,91,92,119,81,73,65,62,119,70,78,111,96,137,97,122,118,134,119,139,126,86,117,73,98,93,122,120,110,105,124,107,146,97,90,85,62,90,92,97,103,88,86,66,91,101,93,121,129,118,101,116,111,90,77,120,112,119,98,93,121,97,64,100,111,70,82,99,93,113,96,108,146,125,130,147,154,151,126,124,129,110,89,91,108,92,102,118,101,86,102,114,101,106,71,103,116,79,79,56,78,72,54,45,53,86,61,116,162,139,129,110,106,131,165,186,249,252,255,250,234,230,198,132,69,3,15,53,23,35,49,63,66,56,56,66,69,62,74,53,90,46,59,62,89,75,30,51,70,77,34,57,90,60,57,47,40,47,67,41,37,38,86,48,66,44,33,71,57,70,46,55,60,47,51,30,55,16,28,76,49,13,55,48,53,27,35,41,68,37,50,58,24,38,18,41,39,35,33,40,39,18,51,39,17,33,31,33,14,55,43,30,15,58,28,41,11,28,11,47,15,56,39,13,23,58,29,42,33,25,59,43,55,18,26,28,46,19,46,41,14,41,37,33,24,51,31,27,15,0,12,43,30,45,6,4,34,24,29,27,19,2,29,17,16,32,48,34,20,41,5,36,33,6,7,21,20,26,28,37,35,5,63,52,49,43,44,7,18,8,27,26,39,48,42,31,5,26,21,32,50,36,27,20,43,45,35,21,44,69,60,102,103,151,171,162,165,118,131,113,109,58,35,47,26,29,24,28,24,17,26,41,74,61,58,32,15,33,32,52,50,14,40,71,113,120,86,48,47,50,63,25,22,34,60,29,45,48,42,33,27,38,18,59,34,21,25,6,9,5,39,50,22,17,8,12,31,34,46,44,20,14,20,40,17,15,7,8,17,31,27,28,11,37,40,30,50,108,148,191,129,104,56,60,33,15,29,14,39,27,19,49,18,60,62,106,110,110,100,126,106,176,177,187,182,158,137,170,154,147,176,159,146,165,147,144,166,157,160,163,156,182,171,166,138,172,146,187,181,159,143,87,76,126,118,175,177,176,169,173,159,161,181,153,170,154,201,168,176,158,174,174,162,166,150,126,123,152,146,162,164,144,178,155,144,177,168,159,186,179,180,184,148,152,135,152,168,175,192,154,150,158,170,147,187,180,147,161,163,184,233,224,216,213,172,177,222,145,149,115,120,90,72,106,11,10,18,29,4,7,22,19,14,9,14,16,3,3,17,17,1,28,17,5,3,9,26,3,41,39,41,50,97,135,100,93,103,76,37,63,27,57,25,5,25,28,19,31,44,27,2,4,18,28,16,33,31,18,13,19,30,14,40,29,36,22,13,41,38,21,9,23,33,30,36,36,21,8,40,38,12,11,44,15,11,17,25,21,30,17,33,38,42,43,59,99,112,97,82,57,40,54,18,34,43,11,7,15,56,43,25,29,52,41,7,42,17,12,6,17,26,5,41,50,87,146,199,232,199,197,206,165,159,157,136,162,146,161,138,150,136,127,129,141,133,146,141,148,129,132,113,80,107,99,130,129,139,144,151,114,127,111,109,108,97,143,151,144,137,136,121,127,117,112,93,127,136,140,121,144,140,149,155,152,132,136,117,134,136,147,170,162,162,123,142,151,144,141,154,152,132,119,134,130,120,141,121,128,119,135,174,150,120,131,149,136,175,126,121,130,119,122,113,117,137,127,110,130,104,87,94,111,108,105,92,103,131,130,111,98,109,130,110,118,144,103,152,134,140,159,143,151,163,131,115,148,116,108,100,120,108,105,97,114,121,112,127,137,120,122,133,112,75,84,106,109,88,114,101,108,62,76,84,77,92,98,94,80,86,61,117,91,90,110,63,81,71,69,63,50,76,47,54,66,64,53,30,27,65,52,76,109,160,116,72,106,142,181,231,242,255,253,246,255,235,170,87,42,20,4,21,43,61,58,57,61,71,54,50,64,75,51,59,54,73,77,66,57,46,60,73,24,86,65,31,59,36,39,61,61,48,54,38,45,63,54,45,68,61,50,55,26,57,58,66,51,37,27,44,65,59,60,35,44,51,51,63,69,6,27,72,23,72,26,46,43,18,45,12,19,36,43,25,23,27,40,33,12,40,28,28,35,39,54,29,64,37,30,15,47,45,3,56,5,35,22,27,36,21,32,7,47,21,24,23,38,65,43,35,37,20,14,51,37,28,29,11,14,34,33,40,37,12,21,31,30,5,7,39,30,41,10,47,21,41,24,32,16,44,48,45,7,41,18,24,24,36,1,27,24,12,11,26,35,15,30,19,26,17,39,21,41,30,45,19,29,10,2,50,29,51,39,23,19,24,30,17,38,38,31,16,46,28,24,63,68,131,151,155,161,176,144,153,127,163,131,121,105,50,68,61,58,105,106,109,84,55,76,114,134,147,169,186,215,243,196,127,59,33,47,73,23,25,37,22,3,11,42,21,21,15,53,26,27,61,38,50,20,20,19,24,43,17,29,38,0,20,71,44,18,3,15,19,8,33,43,8,22,16,41,47,45,63,79,145,116,172,125,100,72,28,56,64,11,34,9,32,12,42,32,32,62,59,84,113,116,89,83,117,99,143,181,166,143,166,161,159,161,133,184,169,190,160,170,180,161,184,177,169,141,152,145,156,161,157,150,186,158,172,196,160,147,130,110,135,128,145,172,200,177,186,175,196,170,185,158,173,184,160,166,173,177,160,177,156,143,145,181,156,141,165,178,166,184,184,169,177,169,187,192,153,160,167,172,159,159,176,160,175,152,173,169,172,147,168,151,145,175,180,208,193,219,208,206,173,206,206,165,156,156,160,154,134,115,16,0,29,20,6,7,9,2,13,12,2,15,7,12,17,11,24,15,17,2,31,3,1,14,11,18,47,46,29,34,57,42,21,41,6,24,15,30,7,21,23,10,30,22,33,29,0,16,21,32,15,22,35,24,32,12,28,30,42,11,19,31,44,14,35,25,25,9,11,24,25,10,19,18,10,11,30,25,25,32,29,29,61,33,29,53,29,33,66,37,63,48,57,29,28,13,35,36,20,25,47,23,11,22,13,35,33,30,40,26,8,9,47,29,7,40,44,30,50,22,30,137,177,203,150,137,138,113,107,87,102,126,131,131,124,116,111,106,101,122,105,90,139,124,107,134,125,129,131,130,147,127,164,136,125,121,126,125,141,114,98,134,133,114,127,105,110,135,96,86,114,113,125,129,91,130,121,101,80,76,106,112,89,120,114,109,99,99,54,86,97,106,102,106,97,92,91,99,102,103,123,104,116,123,124,123,107,112,116,79,144,116,99,82,100,69,74,71,129,117,112,135,141,121,107,96,89,108,71,71,139,145,148,115,98,115,119,86,118,115,140,124,148,154,136,150,124,127,133,141,141,134,118,111,103,116,119,96,151,143,134,133,139,134,136,128,142,93,99,111,94,88,72,74,89,87,66,91,96,72,120,108,88,94,103,110,67,81,88,86,66,88,71,36,54,63,56,42,59,66,50,64,25,44,41,36,76,120,154,187,125,127,104,141,151,195,241,234,227,237,248,251,229,174,114,39,1,15,13,32,45,62,39,58,76,46,66,44,28,48,72,55,45,56,59,60,64,44,43,69,52,57,62,55,47,45,56,42,44,73,69,42,34,49,60,56,55,52,53,53,38,71,20,33,46,60,52,60,26,25,46,30,38,57,43,62,28,57,56,51,19,38,42,53,49,8,42,40,9,22,33,12,60,27,48,57,24,52,29,35,57,38,34,26,33,16,32,18,28,28,42,2,8,32,28,37,41,33,27,16,28,36,26,20,31,32,33,34,39,41,36,23,22,11,28,24,36,25,23,6,14,19,15,31,23,25,23,18,34,18,40,31,19,41,15,52,8,43,44,16,26,41,18,26,26,16,25,17,17,31,12,1,44,19,19,17,5,41,37,22,28,37,46,39,24,36,38,17,28,26,34,29,32,24,17,14,17,17,3,25,57,30,29,40,47,57,86,96,134,169,172,181,195,165,185,174,174,152,151,177,222,169,179,221,196,193,193,193,196,139,156,112,69,14,32,40,45,54,60,25,14,51,30,31,33,16,20,32,33,25,51,29,61,57,34,48,36,29,41,17,33,55,55,27,47,59,66,31,31,23,40,65,84,75,95,69,144,113,167,119,94,97,46,109,29,22,33,14,19,7,31,21,7,25,25,53,61,85,85,84,102,95,106,120,102,159,169,171,158,170,174,164,172,172,144,178,171,170,153,176,184,147,169,182,160,155,154,164,157,150,168,166,145,167,146,157,171,180,165,134,85,92,117,161,194,191,166,195,178,155,171,158,138,173,164,159,189,167,179,167,181,182,165,151,165,195,176,158,177,178,169,195,173,159,188,165,170,134,155,172,178,184,196,162,146,157,158,147,155,174,162,133,150,162,185,208,221,212,201,189,179,182,199,172,153,167,165,161,151,103,3,10,9,30,11,17,25,7,11,31,41,14,15,11,29,10,11,23,57,23,17,11,22,36,42,15,26,15,45,36,44,38,38,34,19,17,20,38,25,34,33,33,21,11,27,25,24,29,43,25,9,20,22,3,20,24,18,13,18,44,25,24,18,20,21,24,20,16,37,37,22,31,43,36,21,33,19,27,30,21,68,39,46,42,37,35,7,53,56,32,32,34,43,20,27,13,41,15,28,26,38,28,25,18,40,42,30,35,57,28,36,45,27,42,21,27,49,22,25,27,38,63,90,118,145,118,118,94,71,97,99,116,115,125,96,89,108,88,110,107,132,84,103,120,137,135,161,131,134,149,155,165,179,136,154,129,127,140,116,137,97,105,85,66,65,64,67,97,105,86,95,101,113,123,107,69,91,86,77,82,85,69,78,83,67,63,68,39,44,64,75,35,47,73,63,59,65,81,86,68,68,79,87,70,83,101,75,69,97,39,33,27,50,57,60,47,81,97,88,92,81,72,113,95,80,63,85,88,81,107,83,113,121,91,90,95,48,100,87,124,135,88,113,75,86,70,104,82,69,36,79,112,89,55,95,120,109,114,66,102,116,101,101,112,104,118,108,114,130,114,106,90,75,65,58,60,30,67,74,70,60,57,93,81,75,75,67,106,68,53,76,88,62,51,65,64,76,47,66,41,61,62,66,67,58,20,66,69,142,172,161,194,178,137,102,113,133,140,203,245,252,250,250,254,207,134,74,68,33,32,26,26,38,27,62,39,41,60,69,51,40,38,78,56,44,52,33,56,37,53,51,34,62,53,46,58,37,50,42,67,62,19,55,60,41,50,71,44,32,54,49,43,25,54,27,40,36,48,48,24,58,30,50,43,43,23,56,31,59,35,40,33,35,33,15,24,26,36,32,38,38,44,47,38,19,38,45,29,35,32,35,28,29,23,17,46,59,45,39,45,31,37,28,33,32,30,27,25,22,29,16,28,37,19,37,37,38,16,38,51,41,16,39,45,31,30,8,33,8,20,40,36,52,39,20,6,16,4,18,10,30,2,9,14,15,12,28,19,14,31,16,25,35,13,43,22,26,35,8,27,22,32,39,11,7,18,12,56,22,15,0,47,27,22,44,11,15,39,40,26,59,34,10,30,6,32,19,40,41,22,40,13,19,19,29,44,30,29,35,49,60,57,56,90,41,83,92,113,116,135,129,139,161,143,160,91,64,51,19,42,35,47,60,39,49,10,28,53,8,43,32,45,28,22,20,37,11,16,40,37,28,18,47,91,38,61,55,84,80,72,90,135,120,64,88,76,93,111,128,155,129,113,183,145,165,114,63,55,47,39,63,22,32,46,37,14,30,29,7,13,25,34,15,71,45,80,77,87,94,66,70,96,115,106,133,167,193,162,159,191,166,165,194,155,186,132,169,173,167,181,135,155,141,145,159,178,166,161,170,143,177,193,137,146,160,173,188,188,167,151,119,91,117,125,150,182,183,199,175,193,147,159,162,173,174,179,154,154,164,172,174,169,177,192,173,174,147,185,189,196,172,180,165,187,189,145,157,139,151,187,169,168,173,180,162,182,171,178,160,164,174,169,159,172,171,202,199,204,200,191,176,169,173,191,157,170,158,172,156,100,12,9,43,15,16,22,12,7,8,2,30,13,10,3,5,34,10,17,16,35,14,13,7,21,20,18,10,15,8,36,42,17,23,43,21,33,19,26,51,17,33,12,27,15,12,21,18,51,8,23,28,27,13,30,26,44,44,47,6,43,14,23,37,33,26,18,33,8,41,16,45,41,44,43,22,65,41,25,23,56,9,27,33,44,20,12,41,11,18,18,32,14,45,34,32,27,26,23,33,20,53,20,9,23,64,54,66,51,127,79,66,71,54,73,54,64,55,122,84,97,103,97,130,145,147,102,133,73,99,77,106,93,101,89,62,69,106,93,95,96,84,90,74,97,104,121,95,101,117,124,110,117,145,139,139,151,102,96,137,107,91,111,131,101,112,96,87,97,111,112,104,99,80,107,108,139,131,144,136,113,136,121,124,126,75,102,132,130,153,133,102,57,71,62,67,83,92,100,97,95,102,89,87,92,111,81,134,56,75,75,49,88,96,100,100,102,116,108,81,113,84,75,76,94,81,108,110,108,127,109,97,81,118,84,84,77,90,118,83,121,111,96,110,90,84,91,80,87,81,75,87,80,86,69,93,123,102,95,75,76,102,107,95,111,77,89,101,91,83,105,98,92,74,72,70,46,74,50,71,78,69,101,97,72,79,64,60,103,88,53,40,76,78,64,60,80,58,70,66,81,86,68,81,38,63,71,62,38,84,90,133,173,211,164,172,103,97,104,121,169,213,244,254,250,234,204,180,148,83,76,45,24,6,15,27,7,37,48,42,32,53,69,63,26,41,66,43,40,50,57,42,60,51,42,53,58,37,51,53,36,58,48,52,40,59,27,50,66,40,61,61,44,46,61,48,51,53,43,35,27,26,48,31,35,47,44,37,20,29,52,49,11,31,38,64,21,19,55,51,33,24,58,45,46,58,24,53,17,6,48,50,24,46,36,32,36,48,37,22,36,25,35,55,17,48,41,21,38,26,36,23,30,31,15,20,25,15,37,41,51,27,17,9,27,24,17,26,25,36,22,22,55,29,13,10,24,42,17,22,15,35,18,33,12,28,18,21,15,15,24,59,21,41,26,33,30,12,0,28,20,32,28,24,21,23,22,12,27,11,9,36,16,35,19,34,19,22,41,31,64,58,60,43,18,42,19,14,12,50,46,15,27,30,70,37,24,21,37,16,38,16,55,22,22,21,19,23,32,37,35,33,50,43,73,86,71,53,50,52,3,42,151,138,61,28,27,30,20,28,36,34,52,34,38,27,64,41,19,43,23,16,27,31,15,43,37,52,71,58,70,72,78,95,92,95,79,89,85,106,63,79,78,61,45,25,70,39,61,44,28,3,15,38,16,4,24,36,48,24,30,25,18,48,81,67,69,73,89,105,95,109,89,128,143,181,206,175,151,150,171,159,173,150,145,155,174,151,131,130,160,150,156,146,147,150,188,169,159,127,157,174,176,150,172,150,155,175,160,182,169,126,105,96,78,132,158,144,175,182,154,145,180,190,173,168,133,164,163,170,197,175,174,159,170,154,158,144,166,169,165,139,151,172,174,153,173,178,172,152,189,184,152,179,183,178,166,182,166,171,150,177,163,158,163,173,182,186,193,205,180,184,174,191,166,164,163,144,159,156,116,21,1,24,4,17,28,12,16,8,34,11,25,0,0,4,14,15,7,20,9,11,14,8,11,33,45,38,17,36,23,31,31,24,29,17,29,34,27,50,43,27,43,26,14,39,53,25,30,20,25,23,12,28,47,20,26,9,30,35,18,23,35,38,10,13,14,37,42,36,49,42,40,49,13,32,24,45,63,23,43,31,1,28,3,2,12,25,25,33,41,32,56,40,23,6,21,11,39,23,34,54,24,42,48,78,121,156,215,193,216,214,206,215,171,202,199,194,196,187,153,134,149,106,136,105,94,107,121,124,108,138,130,160,127,129,105,98,92,95,79,80,103,92,105,99,90,56,102,113,123,80,47,75,85,82,73,73,71,75,111,101,92,127,119,125,129,123,118,149,138,134,109,119,121,110,124,166,139,183,134,143,156,138,136,124,106,147,127,179,152,93,108,88,103,114,125,107,170,137,110,115,144,164,150,129,136,119,94,94,110,141,156,154,144,163,147,128,149,157,114,108,106,96,84,108,111,117,84,105,103,110,72,103,78,75,84,85,94,97,84,104,135,130,117,94,100,91,107,111,97,99,99,131,121,107,107,114,104,87,60,93,62,81,102,110,103,99,67,92,94,59,109,115,79,114,81,81,90,107,95,98,94,118,111,91,97,66,89,59,68,95,76,67,61,52,78,64,73,40,64,77,89,47,65,71,60,42,60,40,62,67,78,111,142,159,146,182,156,129,113,130,121,192,191,172,178,215,193,188,162,141,152,151,100,59,39,21,9,11,19,31,30,52,70,53,63,75,53,70,46,42,43,48,58,37,43,71,65,44,74,69,33,64,51,35,65,59,61,46,39,71,37,38,22,57,42,40,26,40,51,61,26,38,52,26,17,30,61,55,38,49,39,18,39,29,18,36,27,33,58,55,22,35,55,33,47,44,51,11,27,27,34,33,33,45,31,41,61,38,41,45,51,30,52,41,31,41,14,68,37,30,11,42,28,31,38,27,39,33,6,46,37,26,33,25,13,33,32,38,33,37,36,35,36,3,15,13,30,13,21,14,28,18,24,33,21,25,0,0,33,46,27,41,16,48,17,14,20,11,10,17,20,28,38,9,51,37,20,36,28,11,57,4,42,32,46,38,10,15,11,33,21,19,5,16,44,34,38,36,13,48,31,0,35,20,34,29,32,16,40,33,31,27,41,23,27,23,34,11,7,42,22,21,46,77,67,102,86,112,118,164,243,154,71,11,54,38,31,47,46,58,44,39,51,52,41,41,50,58,40,32,3,16,36,18,18,32,37,32,35,14,36,38,56,20,30,27,8,46,41,56,32,44,17,16,11,46,1,32,18,2,25,16,24,36,34,15,37,25,53,71,57,55,72,83,94,74,79,77,68,96,96,121,161,184,168,175,142,140,150,154,125,149,147,137,153,140,138,163,169,169,171,155,159,187,152,154,137,171,178,158,162,156,167,158,192,171,153,182,138,178,140,127,96,115,107,137,148,192,179,164,155,158,145,141,144,157,196,146,158,179,193,176,145,138,133,131,144,139,158,147,153,153,177,177,148,160,162,166,158,161,129,177,161,169,178,144,142,168,147,158,150,144,159,176,187,195,190,204,196,195,182,184,183,180,171,160,150,183,112,31,1,31,5,0,22,0,35,24,28,19,13,5,15,14,20,11,28,24,10,15,10,4,10,40,24,20,27,20,28,35,21,32,35,34,51,35,62,72,69,62,21,50,28,6,4,20,35,25,16,8,23,35,27,30,18,22,26,31,23,24,39,37,27,30,28,64,48,37,55,38,47,22,19,38,21,2,33,32,27,40,30,21,23,38,14,35,16,31,45,24,32,29,25,14,18,14,24,28,39,30,57,61,142,102,158,108,157,148,165,154,168,217,141,176,153,153,147,121,111,111,104,91,75,105,94,126,151,145,145,90,112,126,101,125,128,110,90,122,127,104,92,86,93,114,99,77,99,103,115,94,91,66,88,106,92,97,119,68,110,118,141,113,90,149,129,143,116,138,127,141,119,119,135,120,129,132,120,113,93,90,85,79,89,109,79,67,101,111,125,112,121,128,143,132,141,116,92,129,120,109,130,142,116,121,134,122,115,105,115,121,118,116,111,101,115,115,111,95,95,108,86,87,98,84,65,119,67,68,93,97,69,91,99,94,144,93,80,106,94,104,113,123,83,103,82,112,89,123,124,108,102,121,108,102,101,99,105,97,66,102,93,96,107,103,76,85,80,95,108,77,96,98,72,99,81,72,98,122,78,96,77,89,78,87,59,90,78,74,78,82,84,64,79,81,66,51,61,55,37,58,77,78,43,82,62,51,63,71,63,36,63,52,88,144,176,190,168,193,139,102,94,135,107,104,133,152,179,202,182,187,249,250,243,227,175,140,74,41,29,6,16,14,15,43,55,50,48,40,70,59,52,53,56,42,67,44,70,30,55,46,42,51,56,34,40,61,21,28,64,28,51,61,49,64,49,42,48,44,44,41,30,64,41,32,39,29,33,33,40,43,19,49,42,15,52,25,34,36,59,47,26,33,22,26,16,34,29,28,23,39,32,22,28,52,32,40,13,17,20,33,46,34,44,28,26,32,37,32,19,27,37,26,10,38,27,9,28,38,34,27,9,9,6,30,39,23,7,17,20,20,48,27,30,18,25,35,47,33,20,19,7,31,13,20,20,27,44,4,44,30,34,20,29,24,24,18,26,32,28,24,26,32,12,22,17,8,31,9,33,2,20,39,24,24,46,31,20,52,36,16,17,42,25,31,43,16,19,38,17,18,19,30,31,18,14,40,23,43,25,31,46,47,37,16,37,34,26,30,18,21,31,56,39,28,62,58,74,67,73,109,126,71,39,43,42,32,90,104,88,86,115,117,83,67,95,100,86,61,30,20,37,48,29,67,55,51,23,34,26,7,13,29,27,31,20,23,13,12,3,22,28,20,28,9,15,28,56,31,38,26,18,22,22,25,44,23,27,68,68,75,71,82,79,97,83,72,75,101,65,99,97,179,168,183,161,176,179,138,162,137,168,170,132,131,150,166,148,160,159,164,149,190,175,147,130,149,150,160,139,162,118,158,160,148,149,162,166,152,158,185,164,153,156,100,104,102,152,168,159,178,144,153,154,161,160,166,148,169,166,154,139,127,143,141,138,131,117,132,146,123,158,159,150,146,157,116,147,166,152,183,142,159,154,166,179,150,125,149,162,165,189,154,180,163,185,159,199,194,208,213,194,214,190,154,149,196,157,144,123,11,0,15,44,6,8,8,31,1,16,18,13,3,0,11,10,1,3,14,16,43,12,20,11,40,21,27,14,27,6,42,12,25,35,33,60,65,40,62,79,62,31,28,19,7,11,33,38,7,52,28,58,25,7,40,45,32,19,78,11,34,51,44,50,18,34,48,15,47,25,0,40,28,37,25,19,40,32,31,22,19,31,26,20,11,31,26,30,21,24,7,34,10,14,25,23,44,39,38,34,56,95,47,67,70,62,51,81,37,39,72,76,54,71,62,29,70,72,97,101,102,108,88,108,92,94,94,84,94,81,81,76,62,96,109,104,92,112,118,120,105,105,64,83,139,112,125,77,111,116,140,113,109,123,125,95,119,93,86,105,97,77,56,60,91,111,91,60,81,91,96,101,98,88,52,80,78,82,76,72,71,83,92,75,81,59,81,86,115,105,92,96,118,107,105,129,87,61,89,76,74,69,68,102,111,104,78,74,80,58,69,70,63,86,54,58,84,67,81,80,90,76,100,73,87,106,74,69,85,97,67,112,87,109,109,130,116,129,114,119,90,85,100,77,100,112,87,94,113,123,106,88,114,118,108,97,118,97,131,125,128,89,86,98,119,79,87,80,89,112,82,75,92,86,112,92,74,122,107,91,96,109,88,101,109,72,93,73,83,82,74,95,69,67,77,82,65,56,85,45,75,67,56,58,82,62,48,84,60,65,53,54,54,67,71,118,128,135,128,98,122,154,157,145,97,49,89,116,163,149,163,227,249,255,254,254,243,247,210,160,122,51,16,1,19,24,10,31,43,56,53,43,54,62,86,68,48,53,53,41,38,57,49,69,18,57,38,39,48,42,32,50,54,52,50,60,27,42,34,20,26,41,49,38,27,22,38,41,27,38,54,27,21,29,45,30,35,44,35,54,33,38,32,23,37,11,27,20,24,51,44,19,9,38,31,21,24,39,18,18,33,51,28,37,45,42,37,38,33,10,21,51,25,4,34,31,23,37,5,8,19,53,43,33,38,30,27,48,47,22,47,2,21,21,17,40,25,21,24,19,21,19,11,39,21,43,34,46,9,14,28,14,32,10,24,21,35,18,37,33,33,21,20,19,30,29,15,19,10,36,25,33,4,39,5,18,42,25,5,0,27,28,26,14,2,1,26,53,39,57,39,51,22,31,40,30,51,31,26,26,37,22,20,42,13,33,3,32,1,25,39,15,47,25,44,51,25,54,10,48,41,57,42,12,27,26,74,139,132,146,146,166,156,141,108,126,167,144,138,87,47,15,40,54,39,35,14,21,18,23,32,46,13,33,32,19,30,16,6,12,33,13,8,15,15,19,10,18,19,15,19,13,6,69,27,61,30,41,57,24,77,52,74,99,63,77,113,112,70,97,110,184,199,191,160,158,148,157,148,171,183,165,167,172,172,177,158,160,171,165,166,151,164,154,170,133,153,165,169,158,145,166,146,147,168,156,189,156,161,154,169,148,148,144,122,124,68,88,147,182,177,180,152,155,166,158,148,182,164,152,159,161,133,153,153,149,147,147,129,158,169,151,156,147,150,164,156,156,164,152,170,157,177,160,153,151,151,138,149,156,167,178,162,178,196,168,168,195,186,180,209,200,191,181,193,151,172,183,192,105,16,7,5,13,16,2,32,20,2,2,10,21,25,16,18,2,25,17,15,7,6,14,18,22,18,28,20,33,28,23,4,45,18,30,31,41,52,87,59,58,59,30,57,49,25,13,12,15,19,31,45,44,38,42,25,58,54,29,32,33,14,20,28,28,35,10,13,44,21,19,32,28,20,27,25,30,35,20,24,10,32,12,27,10,17,23,17,15,55,12,33,40,25,24,35,22,49,51,37,40,41,34,44,52,68,62,72,37,41,46,27,68,85,68,74,106,98,124,105,128,111,91,138,115,93,101,94,61,87,61,70,67,110,87,122,128,152,165,148,151,152,139,125,84,97,116,154,111,112,140,110,98,134,99,82,62,75,79,85,54,66,80,80,59,63,63,51,52,75,57,75,112,76,54,42,78,66,92,81,86,74,105,92,85,57,81,87,80,88,109,85,68,81,98,75,97,127,97,85,67,68,57,91,86,65,76,85,93,64,82,88,88,71,106,100,82,77,73,98,102,117,112,105,95,87,99,95,116,116,127,102,79,108,97,119,130,109,98,116,113,91,77,90,126,94,74,105,101,95,130,138,151,135,99,90,98,94,104,90,90,87,97,120,110,131,96,117,114,113,116,104,106,104,100,97,88,88,102,106,123,97,88,106,100,88,81,76,85,77,74,101,75,87,99,57,49,53,82,81,45,65,68,87,76,87,77,89,53,54,66,57,61,42,52,24,39,39,28,34,83,99,155,199,115,75,62,93,84,84,95,95,142,236,252,254,250,243,226,253,251,245,214,168,134,116,43,3,18,27,11,11,36,59,53,48,44,55,44,71,38,56,50,51,58,54,54,46,56,26,57,32,61,44,60,24,24,45,20,50,30,53,36,32,55,29,33,45,43,32,45,10,52,41,32,69,5,33,48,20,36,31,56,10,34,53,37,42,26,48,11,15,24,56,30,38,50,52,33,22,49,22,17,49,11,41,20,39,48,26,27,53,43,49,20,15,7,7,47,37,58,27,19,43,19,33,11,2,34,13,40,41,48,23,22,43,24,32,33,16,15,6,24,26,34,5,22,31,18,51,17,14,49,11,2,43,14,23,7,39,6,24,17,8,37,31,15,37,29,16,34,28,31,28,16,11,24,25,22,45,32,42,24,29,14,26,26,21,27,12,47,36,30,32,42,23,41,25,28,42,17,22,39,40,41,47,8,23,40,14,6,34,28,17,14,53,26,32,40,37,15,38,9,46,22,24,56,61,88,159,135,133,163,129,146,137,125,147,151,148,109,17,16,33,7,39,11,53,24,1,13,15,3,6,15,25,18,12,36,33,26,30,15,6,64,28,9,27,41,46,26,39,27,42,50,41,34,47,39,52,60,67,95,41,70,81,86,70,77,79,120,177,151,181,173,171,168,161,138,173,171,161,176,161,164,156,163,158,171,178,151,141,165,161,161,159,159,166,162,165,161,169,196,166,177,172,170,165,159,171,170,183,138,154,154,144,117,94,75,116,125,180,184,190,175,143,161,158,166,133,143,184,135,134,176,157,170,172,162,179,159,158,172,159,132,141,162,161,159,163,170,146,189,168,155,180,181,182,163,131,184,151,170,182,152,180,180,188,182,162,199,202,177,184,182,174,154,189,157,177,107,2,1,18,13,13,3,31,11,35,28,5,11,11,14,1,12,10,38,9,40,0,28,3,22,32,2,11,27,29,23,31,10,11,32,56,34,37,50,45,65,31,35,29,16,26,27,44,11,31,51,32,34,34,22,39,43,34,6,34,39,16,22,23,36,30,15,34,24,41,30,26,47,36,36,39,33,54,32,17,8,24,29,21,21,20,9,22,9,17,35,18,8,32,26,22,30,16,45,52,38,42,46,37,41,78,35,53,49,52,34,77,96,72,79,93,111,122,123,80,98,101,98,98,103,102,69,75,66,74,90,102,92,90,99,96,101,110,97,101,68,63,83,86,53,70,104,98,119,93,120,112,113,82,71,81,79,95,75,64,78,77,96,109,79,82,102,81,77,84,96,67,81,84,95,113,117,107,100,112,104,112,106,119,81,88,82,104,100,94,117,125,78,115,108,92,92,105,117,107,92,118,106,106,103,84,113,82,104,106,99,117,84,90,105,132,87,102,116,118,103,142,104,94,95,109,100,110,111,108,110,118,111,132,86,121,116,121,108,94,122,126,115,118,97,97,131,106,127,141,125,117,135,123,142,132,95,127,111,80,106,127,108,112,135,116,116,122,122,99,136,95,120,102,112,91,105,104,119,96,99,95,95,102,86,116,115,100,112,100,92,96,115,86,79,84,86,77,51,54,60,95,77,66,69,80,71,68,79,50,38,35,29,59,64,50,43,40,35,41,18,52,68,93,107,85,108,87,70,46,51,38,39,114,150,176,220,239,246,250,251,236,237,218,249,244,210,167,127,76,79,37,23,3,8,42,59,55,36,63,29,50,46,73,55,67,39,33,51,55,50,39,45,9,44,60,49,15,33,59,57,31,35,40,52,27,44,47,39,42,48,47,37,38,48,44,30,31,47,46,31,11,52,37,39,21,35,1,48,43,51,53,20,49,41,14,45,36,42,18,14,44,36,43,34,27,32,25,40,13,37,7,35,18,20,28,54,27,20,16,26,15,8,25,27,37,33,25,30,33,22,21,24,25,19,19,41,13,12,31,10,40,11,32,18,18,16,9,37,30,21,13,17,29,35,17,27,32,17,9,33,31,25,34,18,7,17,22,28,13,60,8,22,49,30,35,39,1,49,55,62,28,26,20,42,42,48,40,36,39,34,28,27,9,19,36,25,40,21,28,31,27,59,16,27,23,24,13,23,13,28,30,32,37,23,30,26,36,48,45,26,11,67,51,35,23,33,51,68,127,108,134,131,127,129,117,101,117,149,167,120,30,9,20,28,20,40,37,30,21,38,19,13,1,17,42,8,26,16,35,9,7,15,7,18,3,7,21,14,27,12,18,22,26,58,35,24,52,50,61,71,72,43,73,94,70,91,85,73,116,142,183,179,162,142,162,143,136,140,139,168,177,165,216,179,162,179,164,162,176,155,173,134,138,153,150,140,176,178,166,198,167,147,157,146,174,171,153,168,163,141,151,172,151,175,194,154,140,97,88,85,131,152,183,180,202,178,163,171,170,144,169,164,148,159,143,141,151,155,145,131,159,171,186,156,172,163,139,158,163,160,152,155,178,154,153,157,157,163,163,143,166,125,162,163,165,195,147,199,160,209,169,169,165,152,156,180,157,150,167,122,20,12,25,20,13,8,40,23,11,16,18,15,29,35,0,32,43,13,7,23,9,5,26,5,39,14,25,39,14,18,19,39,17,25,44,41,27,62,55,46,45,75,43,23,16,26,29,17,34,25,4,10,23,25,37,25,31,52,34,4,10,20,26,21,45,38,31,22,11,47,38,26,43,31,9,42,25,21,26,35,10,21,6,14,24,10,15,9,22,9,19,24,19,50,11,41,36,28,41,35,45,41,19,49,23,37,39,35,45,46,29,30,55,44,45,36,51,41,48,37,26,32,34,56,52,25,26,15,44,27,43,67,62,59,37,45,21,27,31,34,54,29,70,39,68,62,54,81,93,95,78,80,95,86,78,102,105,78,102,110,99,121,140,137,114,117,122,72,118,94,108,112,131,101,118,117,118,129,103,108,123,101,131,91,92,127,119,112,85,113,104,116,98,87,87,105,119,119,113,102,124,123,120,134,117,122,111,112,119,126,103,104,122,125,97,107,97,124,95,124,120,92,103,93,101,101,83,113,124,132,98,143,111,126,120,104,153,126,101,111,127,107,130,123,111,111,118,140,104,107,107,132,123,117,126,117,111,114,118,105,127,104,109,113,117,102,122,110,111,109,115,96,120,97,91,115,103,104,117,95,109,112,96,119,87,110,132,116,109,94,102,82,75,99,66,65,89,67,54,65,65,65,58,89,87,64,81,61,59,65,62,52,59,51,34,45,63,49,70,40,52,54,76,80,87,107,105,73,63,80,44,62,77,110,115,121,147,190,207,233,244,250,249,247,255,243,255,255,238,190,145,135,83,45,11,4,57,3,18,26,24,39,33,29,55,21,40,39,28,29,53,64,43,60,48,47,34,37,28,25,39,40,51,58,30,47,55,37,46,37,47,39,37,31,51,42,36,30,38,28,30,36,22,17,53,23,19,17,22,64,52,20,18,35,25,22,14,36,21,33,23,25,25,15,14,19,25,29,44,16,23,35,20,17,30,33,32,10,15,33,33,24,31,9,15,27,39,40,19,18,36,40,33,19,6,18,0,19,31,23,48,18,35,30,6,5,14,30,5,59,26,25,35,11,32,17,26,18,25,25,33,11,30,31,14,16,4,12,40,32,12,33,9,24,21,28,5,29,69,34,25,21,22,8,18,46,26,27,11,10,29,27,52,22,46,32,14,23,28,13,26,30,18,32,10,43,27,29,38,36,10,32,24,40,56,54,20,42,10,25,26,47,49,25,45,30,47,78,77,82,106,104,122,127,116,101,117,135,154,119,24,11,31,18,33,37,17,24,14,13,9,15,19,39,24,11,28,13,13,35,34,33,7,24,26,51,28,39,15,32,30,50,61,33,35,58,54,66,66,52,84,49,75,83,101,99,103,121,151,168,172,177,157,137,146,136,134,168,154,162,177,150,192,197,157,175,167,167,134,152,139,157,171,159,169,158,156,168,168,153,155,150,157,178,137,179,176,162,188,157,165,145,172,162,176,161,150,138,110,64,75,117,178,190,164,188,164,157,164,163,160,161,135,156,134,144,153,184,162,162,173,133,164,114,145,159,168,140,140,152,169,151,159,133,151,150,187,187,153,196,155,171,123,169,140,164,167,149,170,173,143,165,164,157,169,162,167,149,195,138,7,19,4,11,39,20,10,3,0,5,10,22,41,0,11,22,18,27,0,35,19,8,37,19,24,32,13,28,33,33,30,50,44,21,39,30,41,27,30,40,31,35,24,20,22,19,24,26,22,15,23,24,11,12,5,18,31,21,26,22,36,23,45,15,24,14,15,16,30,21,22,14,15,42,13,18,8,27,10,7,11,26,6,9,16,18,15,17,26,3,16,3,20,37,42,58,49,44,54,74,58,45,50,81,72,39,58,29,60,51,29,22,45,54,33,20,44,54,50,20,43,37,30,62,43,43,32,40,34,55,78,51,67,61,117,73,80,99,81,79,73,80,92,64,81,104,87,90,94,101,98,110,81,121,101,94,76,96,119,91,119,112,116,131,114,122,125,129,102,132,135,104,107,144,131,111,115,90,84,96,132,136,126,126,116,109,115,122,86,148,130,110,82,115,114,111,110,106,138,124,110,107,114,124,120,147,94,131,103,139,126,101,115,126,131,105,116,115,124,121,123,117,114,142,135,105,109,114,100,112,130,98,126,110,115,122,132,138,122,130,99,80,104,106,93,113,132,110,120,109,117,110,96,144,141,122,131,144,106,126,107,104,109,103,112,142,125,115,115,114,140,108,132,116,78,100,88,103,99,106,104,102,125,71,101,107,90,89,78,88,118,82,70,55,90,94,94,104,100,57,97,87,92,58,68,57,41,81,57,63,60,60,67,58,58,50,83,96,89,58,68,77,76,66,47,30,91,86,117,105,114,102,142,99,112,102,96,81,117,110,160,162,214,234,254,248,243,252,254,252,254,255,251,214,156,146,115,83,51,35,14,20,35,10,42,32,53,44,48,64,27,60,38,33,62,27,53,43,19,14,15,37,22,45,18,53,82,42,29,15,25,41,36,14,31,26,37,30,34,22,40,53,34,43,32,30,25,56,48,19,27,57,21,11,25,37,33,22,53,44,18,17,29,34,36,42,4,10,8,5,27,7,43,29,12,29,43,11,24,24,7,49,4,11,20,32,22,28,33,55,27,17,17,39,52,29,7,12,30,42,39,16,28,11,32,11,34,11,23,18,11,15,18,23,29,13,30,29,13,10,7,23,25,27,30,32,22,6,9,20,10,16,8,24,29,16,19,23,15,31,37,35,32,20,34,49,31,25,9,22,18,38,26,12,47,32,31,13,31,39,38,34,20,31,50,10,14,27,63,8,33,14,56,30,62,44,29,28,37,25,26,35,46,40,23,41,40,61,78,82,98,67,103,87,92,99,110,101,107,95,30,27,13,10,51,23,19,19,28,19,43,27,21,16,22,25,26,35,23,1,17,10,34,10,0,17,30,9,29,45,33,34,21,53,48,45,39,47,82,73,45,53,93,88,82,119,99,165,161,161,161,162,166,177,159,152,149,160,146,169,149,170,176,167,149,163,170,154,131,156,154,148,156,183,154,141,169,183,171,147,163,139,150,162,154,156,142,153,160,151,143,155,149,157,173,192,191,188,137,129,82,100,118,158,161,172,175,196,160,166,175,179,136,153,165,152,171,182,174,162,153,162,163,178,185,175,158,169,146,144,145,141,159,176,153,146,153,169,161,151,140,154,141,178,149,145,159,163,137,167,150,158,167,172,161,142,170,178,176,109,29,0,37,2,13,27,9,9,4,6,12,8,14,9,14,46,25,9,9,25,10,28,19,4,35,25,32,32,37,45,14,69,25,41,29,51,49,46,21,47,20,58,31,39,42,40,32,29,29,28,19,19,11,42,25,13,38,33,48,25,41,15,31,40,32,18,33,28,25,14,27,12,31,15,13,39,28,25,10,0,14,15,12,8,27,11,15,15,25,9,23,14,9,21,36,44,69,72,59,104,46,62,72,84,60,51,70,60,67,64,58,64,44,60,56,47,32,16,39,39,38,32,64,40,76,58,69,47,56,42,45,25,29,88,82,132,96,103,123,96,131,127,151,121,132,115,129,95,107,112,128,123,104,100,108,94,137,117,104,108,78,109,109,108,106,124,115,109,105,109,97,119,109,113,115,155,123,127,125,125,134,125,105,103,112,121,114,117,125,112,125,93,85,121,119,96,110,115,124,146,119,117,107,111,138,136,126,142,143,135,104,127,108,103,127,128,141,98,137,124,111,122,103,116,150,136,121,108,110,138,121,125,95,132,99,119,149,144,144,115,121,127,108,100,94,125,132,131,129,123,111,116,109,121,98,131,102,114,104,113,126,133,107,112,125,105,127,128,121,131,107,86,71,112,95,125,96,96,96,122,113,83,71,101,86,86,97,73,71,77,83,111,97,107,97,87,119,65,60,41,50,99,57,67,85,93,90,78,71,58,46,55,51,45,72,43,66,18,73,61,81,78,96,43,30,77,105,100,81,97,100,118,116,106,138,106,114,103,82,79,75,82,131,138,163,210,211,234,251,255,248,240,249,254,254,239,205,222,143,128,104,56,38,16,1,26,13,28,18,32,34,51,53,49,47,34,55,46,53,28,50,33,26,59,15,49,54,38,47,48,3,47,47,15,30,20,34,32,16,48,29,26,38,13,42,15,13,33,7,40,40,61,33,15,4,35,26,44,42,47,19,37,31,11,48,18,28,32,49,8,20,12,35,16,22,18,40,28,42,21,40,41,27,15,4,12,30,14,9,15,15,35,35,46,29,46,2,26,29,8,20,15,39,34,30,14,14,16,20,6,19,34,17,14,9,18,24,29,1,20,37,24,44,28,15,4,41,39,28,38,31,15,27,26,11,34,37,49,6,30,16,16,56,40,24,10,22,13,24,35,50,27,45,27,22,25,17,16,45,63,52,43,21,44,11,36,23,31,16,25,13,20,22,62,48,26,40,21,30,32,42,63,51,38,45,12,43,47,66,118,105,96,105,115,101,98,121,84,138,139,39,36,30,31,36,27,21,1,25,52,37,29,29,32,20,14,21,18,31,31,30,23,10,35,31,6,21,40,44,37,23,34,49,55,64,57,42,97,81,86,76,82,100,81,95,103,155,170,163,174,153,142,168,169,192,160,181,178,135,156,154,177,145,150,144,165,143,186,176,159,160,179,162,161,166,154,180,156,158,162,173,154,168,164,131,164,168,162,155,148,151,146,153,150,163,165,188,200,167,157,138,99,113,109,138,154,184,185,175,164,175,160,141,186,146,180,168,167,168,178,168,143,188,183,189,175,197,168,163,175,129,160,132,158,175,168,151,157,144,154,148,157,149,139,160,148,164,164,160,147,169,165,149,168,162,163,175,155,164,102,4,23,26,21,13,11,27,24,15,8,28,25,26,0,2,11,9,2,4,26,9,10,22,7,70,39,26,34,14,19,11,19,31,28,13,13,5,14,6,21,24,40,15,36,8,28,6,14,13,41,31,39,38,25,53,19,27,27,31,16,25,13,37,36,18,22,14,3,18,5,38,27,20,30,20,21,11,23,12,14,23,10,11,26,19,25,7,22,25,17,13,18,4,38,46,48,44,72,45,54,43,49,42,59,48,40,56,57,70,51,64,58,46,67,62,53,56,36,40,54,35,56,61,85,89,81,75,60,69,78,47,60,43,57,46,95,103,113,81,78,87,116,116,118,128,131,135,117,116,111,126,106,103,114,111,106,98,136,103,107,108,107,118,120,94,115,103,98,102,103,124,128,111,133,150,121,139,136,101,99,132,117,145,137,118,108,126,121,84,118,116,125,146,145,122,128,125,115,120,97,99,124,92,113,101,132,142,105,108,102,110,96,122,93,112,112,124,105,122,107,112,125,128,123,142,148,132,100,133,139,121,116,122,100,133,125,156,134,125,121,139,104,129,143,122,139,135,148,123,104,119,104,144,94,85,106,125,142,101,129,133,127,111,115,140,106,116,132,101,145,132,138,119,116,134,128,124,121,118,105,106,80,76,61,81,101,85,76,82,77,73,100,91,121,100,85,81,72,68,60,62,55,62,68,74,55,57,59,56,87,97,67,57,62,71,54,44,59,86,49,75,83,75,72,57,41,76,61,65,82,62,84,96,73,74,129,161,113,132,113,105,37,55,42,64,81,132,138,172,162,194,234,243,245,253,249,248,243,215,239,252,225,188,150,173,112,51,31,9,8,7,42,22,45,35,46,49,45,46,59,42,23,32,36,39,36,37,40,50,52,41,23,24,47,30,39,38,41,45,21,33,56,48,41,14,28,24,37,28,27,43,31,39,29,28,29,18,17,24,34,44,34,14,10,19,6,26,36,20,13,60,34,20,29,31,17,39,22,19,30,47,19,21,14,51,8,19,26,11,35,26,13,12,15,32,34,37,40,22,9,9,17,31,7,7,18,27,7,30,21,29,18,11,22,37,22,15,35,29,10,1,9,11,22,27,17,21,2,17,9,44,22,25,5,20,8,13,45,12,5,9,16,22,25,49,25,41,33,55,21,25,35,33,22,36,43,26,30,66,76,59,33,18,28,26,40,41,28,34,54,48,41,27,29,38,35,53,40,49,25,43,33,49,28,31,32,39,38,78,111,157,129,158,138,100,102,140,144,154,143,70,41,6,35,20,23,15,10,8,40,21,8,37,44,12,27,19,20,38,34,31,10,9,32,30,26,20,16,36,25,38,47,49,54,59,75,60,62,102,86,93,74,95,95,80,149,150,176,154,143,156,155,182,164,153,153,155,174,185,167,161,158,182,132,160,155,167,179,155,170,152,200,155,151,177,150,196,162,123,161,175,185,171,146,152,155,152,132,142,146,162,160,154,150,173,147,175,179,181,181,192,140,112,78,109,108,160,190,184,185,178,142,186,174,178,146,157,167,170,166,161,191,132,168,155,145,176,175,161,154,159,145,166,140,152,156,163,157,159,150,164,158,152,178,160,155,158,161,152,179,158,170,169,171,182,170,141,159,142,111,8,6,10,10,31,17,31,4,24,4,29,30,14,1,22,28,17,15,2,9,10,22,10,34,31,47,17,24,51,21,7,32,18,21,33,45,22,9,18,17,6,29,22,27,8,3,33,21,0,12,9,28,44,20,18,6,16,35,28,12,35,28,12,32,30,8,4,29,11,10,23,12,6,12,36,31,13,30,20,23,28,34,48,21,14,16,20,16,13,38,28,19,27,45,6,65,62,57,66,76,49,59,61,55,78,66,83,70,55,53,85,95,104,84,77,65,82,61,58,44,69,58,53,99,93,74,121,81,106,106,89,75,51,89,71,70,90,70,87,65,73,110,69,99,103,87,129,109,128,140,140,114,125,111,126,140,123,115,116,116,119,84,128,130,119,124,101,151,111,130,120,129,145,116,150,110,113,127,119,107,121,164,120,105,117,108,124,126,118,132,104,146,112,110,108,136,117,103,134,118,135,104,119,118,123,124,64,95,105,127,136,135,122,106,122,124,102,102,131,136,123,148,130,122,103,131,137,123,117,148,128,112,117,136,141,109,92,114,123,107,139,119,133,111,117,135,119,103,116,113,111,114,86,94,105,119,123,112,122,94,117,116,116,110,105,121,115,119,127,149,128,118,131,121,134,148,124,159,145,139,133,85,100,82,84,112,87,84,82,74,76,58,79,120,93,101,78,64,94,69,111,85,62,68,89,96,106,88,74,99,74,74,62,68,39,48,69,55,80,68,62,52,74,56,50,54,46,49,58,53,64,79,60,65,100,125,150,150,179,168,154,150,124,87,97,111,82,115,99,89,125,124,177,166,195,196,215,201,228,248,242,251,247,238,252,241,243,194,166,102,67,114,5,19,24,25,30,33,35,29,15,41,18,31,11,48,35,49,13,39,50,23,31,33,39,36,30,35,31,24,13,24,42,34,9,17,50,49,24,50,30,30,33,30,33,25,16,16,12,28,33,33,42,33,10,51,9,27,8,47,32,23,43,45,12,25,22,23,20,49,19,14,41,44,23,25,14,12,23,23,23,22,14,11,19,12,14,33,23,29,38,28,8,5,26,31,24,10,22,15,23,3,18,20,5,22,28,17,11,25,15,28,10,13,23,17,14,42,33,0,43,31,30,9,33,14,26,7,29,8,22,33,31,14,21,23,33,43,14,14,28,20,23,48,61,31,43,35,23,47,29,17,41,14,22,30,10,51,35,22,29,33,28,42,39,61,45,44,42,52,24,36,49,44,44,35,34,42,80,118,140,134,122,95,85,112,115,122,146,139,63,36,3,12,26,27,8,17,29,31,40,11,45,41,15,31,26,25,28,12,11,11,15,23,39,20,39,31,60,49,29,50,56,42,81,60,51,52,67,78,76,109,104,107,144,183,152,167,166,156,154,180,174,179,163,164,183,167,159,170,147,172,148,166,147,153,159,145,149,154,155,163,157,160,164,155,167,151,148,135,153,151,176,161,146,168,150,165,162,174,194,164,151,149,167,143,152,146,181,162,160,146,138,102,87,91,127,164,185,206,147,167,155,168,150,156,145,175,147,157,156,166,146,150,138,150,150,153,148,155,179,161,161,174,180,171,167,160,185,135,167,180,140,173,174,167,187,200,199,146,178,145,156,141,178,171,185,174,170,124,1,8,6,3,13,15,13,21,25,28,12,16,9,8,3,18,5,4,10,13,7,6,3,7,27,14,15,18,25,32,17,9,9,30,16,24,26,45,10,33,1,7,18,27,15,33,32,31,25,20,15,16,30,8,46,21,11,0,25,27,38,40,7,11,31,31,4,35,19,21,24,23,3,26,15,26,24,22,29,9,15,1,27,29,18,10,36,12,46,26,35,10,2,37,35,49,23,55,72,71,68,87,63,102,71,66,80,102,109,150,100,79,110,102,107,70,74,38,67,39,48,64,65,117,113,105,97,106,117,121,104,97,106,84,101,95,85,131,133,94,91,95,87,88,130,113,100,111,134,137,137,126,135,143,132,116,129,120,132,136,153,121,128,114,117,149,132,140,156,131,122,139,128,135,130,144,146,140,144,134,128,97,141,126,132,128,121,109,91,102,117,118,134,121,132,128,117,135,133,128,95,97,129,133,126,118,124,139,138,111,128,104,130,121,147,157,104,130,132,127,112,125,118,102,112,129,149,129,137,114,104,132,120,119,145,111,132,121,131,129,126,114,140,144,133,127,107,108,99,118,144,133,130,132,154,145,131,132,128,135,171,130,148,141,119,112,140,118,104,104,105,123,116,140,144,153,126,140,150,109,119,121,110,133,122,122,58,82,89,86,95,92,102,116,98,100,126,96,89,110,107,100,92,107,84,98,101,111,102,70,65,63,73,78,46,39,68,66,74,60,47,34,65,48,34,40,60,26,37,53,55,102,64,81,97,122,137,154,172,162,173,194,195,184,164,135,125,129,92,101,73,73,92,63,105,132,154,157,179,226,225,244,235,243,252,255,246,237,233,234,241,233,210,144,116,70,66,19,5,5,41,34,45,35,34,33,33,30,47,28,28,33,27,35,38,31,36,57,32,38,52,26,22,30,15,40,35,31,11,7,42,36,19,25,22,27,7,44,35,37,16,27,20,32,12,47,29,34,32,38,39,22,28,7,27,33,39,13,21,23,10,15,15,18,33,26,13,23,18,26,39,29,12,41,32,34,11,4,18,37,14,20,13,17,12,29,30,52,8,6,29,15,27,45,44,12,31,34,7,36,26,15,41,37,2,24,6,11,29,45,41,9,21,31,24,25,18,17,3,11,30,42,32,4,24,24,25,41,22,22,23,30,13,40,37,27,13,23,37,39,23,26,33,17,20,50,18,21,43,51,10,31,6,50,24,17,57,47,40,33,36,44,32,17,50,16,10,56,57,71,61,59,55,37,36,41,55,66,55,76,28,40,9,33,21,15,12,8,26,34,21,10,41,29,20,7,17,45,6,47,24,9,20,25,49,21,36,26,42,17,50,37,63,40,51,70,62,72,80,96,94,122,108,141,173,149,162,151,174,171,165,155,163,176,163,141,157,153,148,165,147,140,149,126,112,165,175,166,182,161,154,148,157,168,173,169,158,145,160,138,164,154,160,168,162,175,179,167,198,173,169,155,136,117,117,151,150,158,158,174,154,179,163,134,132,92,85,102,169,178,174,162,172,160,159,154,159,168,118,163,153,152,157,154,139,165,157,175,176,167,162,173,169,145,147,173,183,154,153,165,139,152,181,184,140,158,164,166,167,141,148,171,163,157,149,171,170,168,159,102,22,10,3,20,3,11,31,10,7,3,13,7,20,11,14,10,10,12,4,5,19,5,1,3,10,43,14,15,12,4,38,24,19,16,42,5,24,22,24,2,22,49,8,18,26,10,17,10,24,22,20,33,8,40,11,15,15,9,13,11,22,34,16,13,42,14,24,16,9,10,27,12,8,9,17,19,26,12,18,10,18,46,36,11,20,22,25,11,28,19,10,20,32,41,24,25,37,31,50,36,33,36,31,45,53,65,55,76,57,82,85,68,81,99,58,40,70,12,43,45,35,66,52,47,82,60,47,75,42,63,61,80,53,65,72,51,57,42,76,63,56,32,27,45,82,85,90,50,64,78,73,113,93,97,98,115,83,112,125,118,100,123,116,128,125,138,125,136,113,125,152,125,121,112,118,121,161,123,125,119,122,98,98,135,97,111,137,139,124,123,101,137,137,134,138,138,128,134,136,113,126,133,135,118,122,116,129,144,140,147,127,135,139,128,123,136,140,131,144,128,119,150,128,128,128,141,137,157,128,117,120,128,145,131,127,114,126,96,117,132,128,126,141,115,121,146,129,148,145,146,147,125,128,146,103,132,131,135,135,121,136,126,127,124,124,136,112,101,115,125,123,127,108,129,121,121,115,128,113,73,108,87,132,117,91,96,104,120,109,127,125,117,99,116,140,88,114,128,91,85,96,74,61,98,88,76,61,77,73,49,35,57,78,101,77,75,79,66,92,45,67,58,26,51,30,45,62,72,60,36,29,60,113,88,95,109,112,70,102,116,69,115,91,80,71,68,132,111,92,103,92,91,116,43,51,69,89,58,123,132,131,153,149,180,194,228,237,238,247,239,252,249,249,244,240,216,179,190,131,98,113,48,13,20,10,20,24,29,20,24,16,40,49,33,18,27,16,38,40,40,21,51,16,20,43,9,37,15,29,9,11,7,21,35,33,29,18,6,43,16,47,38,38,15,31,27,53,39,18,25,35,19,11,23,29,17,22,20,32,31,8,44,22,11,18,24,29,26,44,32,17,20,6,30,20,23,15,40,30,23,13,25,27,31,23,38,19,19,16,30,14,16,40,18,12,26,29,22,15,16,37,55,17,13,65,17,41,52,35,9,30,25,19,29,3,27,46,16,27,33,18,42,31,22,22,7,20,23,2,2,26,25,25,30,32,44,36,17,49,47,51,19,46,34,23,37,42,33,35,36,34,31,24,20,22,20,48,46,39,24,21,41,30,32,59,36,21,45,31,54,41,38,18,47,34,32,28,38,72,69,30,41,32,30,17,12,16,29,28,16,40,21,22,11,44,31,26,34,10,23,7,12,34,22,37,24,14,26,54,25,25,57,31,41,71,76,50,79,79,69,112,93,155,194,169,173,151,163,180,163,148,144,162,161,168,138,158,156,149,141,178,150,172,163,173,144,180,166,153,158,175,166,149,147,156,152,173,153,157,137,178,173,151,169,149,163,142,186,168,178,158,166,162,146,151,152,162,165,197,144,167,166,142,171,150,106,66,66,131,145,152,152,178,159,152,138,172,158,164,144,152,172,165,180,168,165,160,157,158,183,154,169,148,167,133,162,167,164,166,149,174,154,187,170,166,172,160,166,173,138,155,164,170,165,183,152,153,184,190,116,3,7,11,3,18,6,18,18,2,26,19,2,27,1,17,4,28,22,14,24,27,23,4,4,30,31,16,43,14,27,43,15,19,14,20,20,10,29,9,16,45,14,25,12,23,13,20,12,11,16,8,45,45,36,19,17,13,45,10,10,31,28,35,13,31,20,2,32,32,36,11,12,2,37,4,4,43,23,17,21,7,38,30,19,14,27,35,29,20,19,31,8,33,28,22,16,52,3,4,22,20,44,15,30,22,17,47,53,33,36,21,33,35,22,35,32,32,47,40,69,36,35,42,48,67,53,57,66,27,36,61,48,47,63,31,60,61,65,34,23,36,46,45,58,56,75,68,42,75,45,67,78,46,76,68,112,103,125,130,129,112,111,114,103,107,119,127,138,114,129,124,128,128,119,134,118,116,108,105,126,100,92,109,118,139,108,147,132,117,136,144,124,151,127,151,129,128,119,132,129,123,130,121,122,138,166,154,116,129,135,132,102,126,133,124,129,145,145,136,129,139,138,132,128,123,133,148,116,144,125,121,122,141,152,118,134,129,134,125,132,119,136,144,130,135,146,126,159,149,130,145,130,147,112,134,133,127,118,128,110,137,111,129,130,117,94,136,108,133,139,140,118,124,123,109,102,115,103,118,100,114,113,116,94,107,125,115,126,115,102,128,118,99,109,66,107,86,88,102,82,68,75,67,90,113,68,77,91,74,64,56,59,43,87,40,93,60,89,62,64,54,67,83,84,63,52,56,42,20,24,53,70,77,73,61,36,52,58,56,48,40,49,62,53,55,61,86,89,108,87,128,158,129,112,88,66,46,22,48,14,30,72,81,85,85,129,122,169,200,185,239,253,254,244,251,234,255,242,250,252,243,195,175,148,110,88,65,44,25,19,28,66,30,39,26,57,23,28,47,26,34,11,21,34,33,42,44,44,32,53,32,32,27,33,29,47,13,34,28,27,31,54,22,2,35,20,31,24,19,50,13,9,7,30,30,24,14,29,41,17,5,15,7,38,4,38,16,1,24,19,14,28,11,1,8,6,27,19,27,23,37,7,43,12,21,31,5,45,51,24,17,32,28,5,11,24,29,6,5,2,7,5,9,35,39,31,38,8,21,27,9,10,9,8,24,13,13,3,26,22,26,9,24,1,11,8,16,30,22,10,24,9,30,20,18,25,29,45,42,67,67,18,39,53,20,7,41,25,49,21,22,46,45,42,27,49,17,57,30,24,49,43,62,25,45,43,39,56,44,59,53,68,21,19,22,60,17,44,28,26,42,37,46,7,29,31,14,52,20,41,8,16,14,21,12,30,33,3,14,35,3,23,34,12,44,46,21,18,34,30,66,55,48,62,72,82,95,85,87,90,115,171,183,186,163,170,150,182,162,152,161,143,174,154,163,159,174,176,158,168,144,146,177,177,174,165,147,159,159,178,148,186,158,163,168,157,177,173,163,178,163,162,158,164,152,163,141,152,142,177,159,165,137,155,153,137,153,187,157,180,172,162,181,210,173,163,106,90,77,106,130,168,162,171,168,161,173,148,165,187,163,174,151,174,164,167,162,183,167,159,172,165,160,177,155,165,166,158,155,158,163,151,161,152,163,170,146,159,176,180,162,153,161,152,156,147,189,143,180,106,9,6,3,0,24,1,11,13,29,26,29,29,12,17,20,5,7,11,18,21,3,20,16,23,60,14,25,23,41,15,37,11,39,15,26,31,10,4,24,20,20,11,27,13,0,48,7,24,42,29,21,29,8,34,14,46,23,9,28,15,7,48,29,10,13,40,10,11,17,44,21,41,33,18,24,20,52,51,34,4,33,5,23,15,41,27,21,38,34,10,19,29,28,27,15,33,19,17,9,4,33,11,19,37,40,51,36,36,38,31,30,34,56,32,54,67,53,24,46,49,68,49,45,64,48,21,58,58,64,31,59,61,34,67,72,62,64,69,74,53,44,54,54,44,105,77,94,82,84,102,89,89,88,136,134,147,129,114,133,142,106,129,152,136,108,112,115,110,108,120,102,105,148,103,139,135,137,116,144,134,138,114,126,154,153,116,141,138,115,135,115,122,119,117,116,120,130,115,101,118,122,125,121,134,104,134,144,133,132,130,132,133,111,120,124,139,124,144,138,128,150,130,150,114,141,148,136,137,140,135,119,136,140,121,138,130,152,130,130,129,123,166,121,157,130,135,120,143,173,136,130,138,119,150,126,119,138,143,132,152,137,168,122,118,146,146,134,127,130,148,143,140,123,126,131,116,139,109,141,120,137,124,140,106,115,125,123,121,92,100,115,104,111,116,86,82,85,79,84,109,79,88,85,83,93,89,75,95,81,101,85,59,75,68,64,52,67,61,79,61,88,67,76,79,68,41,58,71,66,74,60,60,30,48,66,90,55,59,50,64,40,51,72,35,60,57,45,77,95,113,129,121,146,141,141,132,80,59,84,85,91,75,57,57,53,70,72,98,112,104,146,159,219,213,223,230,247,213,242,239,226,243,235,220,229,211,196,190,145,121,105,94,57,29,21,25,11,61,37,45,39,43,32,13,36,44,19,30,11,30,28,17,15,47,13,38,33,23,21,9,42,33,20,15,14,25,42,25,31,19,17,14,56,43,20,37,25,9,2,22,22,18,32,24,3,29,2,46,20,2,54,20,51,43,26,14,17,13,11,6,33,38,21,37,12,0,29,11,18,33,28,34,29,29,38,20,29,16,20,39,35,22,39,21,36,9,34,18,12,8,19,35,31,27,36,14,19,16,3,18,20,42,44,22,17,13,8,15,7,24,22,3,6,30,17,46,37,52,42,32,36,54,39,40,52,55,53,19,32,23,27,42,9,26,48,40,57,30,10,18,49,37,40,28,36,29,39,50,38,35,49,34,44,29,25,15,17,33,31,29,72,25,40,51,29,12,15,8,39,20,23,20,13,6,50,33,16,44,24,13,30,22,36,5,53,19,44,33,40,40,55,52,59,63,94,91,91,86,75,108,157,179,178,147,169,169,166,134,161,156,170,147,152,153,186,140,173,191,178,180,172,155,157,183,137,151,154,169,132,164,143,168,169,169,186,184,163,160,160,154,164,170,162,166,162,159,151,144,161,157,160,162,163,176,150,137,127,154,164,167,171,161,162,153,155,176,148,142,98,84,92,134,147,183,196,174,163,170,172,132,167,153,176,188,175,155,165,193,166,137,164,133,185,158,168,157,162,159,162,159,150,176,195,161,151,204,190,172,178,191,174,168,154,171,155,149,166,172,166,92,12,5,4,16,15,2,9,4,11,8,20,5,28,8,15,30,5,4,9,18,24,40,23,35,22,30,23,27,31,19,23,13,38,18,10,14,16,19,12,14,9,18,13,21,23,50,22,22,23,20,13,10,9,15,6,33,4,18,36,13,12,13,10,15,37,10,33,21,30,12,47,27,44,2,8,31,36,8,18,36,17,12,39,19,29,18,34,16,18,13,8,19,19,16,30,27,23,26,25,36,21,37,38,28,33,58,24,39,45,63,54,59,40,35,34,46,56,61,60,83,85,72,45,68,61,79,65,50,49,37,72,46,35,62,59,88,52,66,66,82,73,92,112,95,80,100,98,92,59,90,79,105,126,108,124,122,130,124,122,94,115,127,145,130,136,122,113,112,136,148,134,127,160,149,168,136,138,110,140,120,144,167,115,104,149,154,137,128,116,124,121,107,143,126,141,117,111,125,116,117,141,140,106,102,133,138,154,128,102,107,123,121,131,125,118,150,122,91,127,154,97,128,118,131,95,135,129,157,175,148,137,156,122,126,151,173,153,138,143,147,129,143,142,148,156,141,136,146,136,152,115,145,138,140,154,173,157,136,153,151,126,159,148,140,171,134,146,154,140,148,130,167,151,133,153,156,126,154,163,146,127,135,144,147,142,151,128,115,131,114,97,126,95,121,83,94,124,122,92,78,76,62,70,62,81,64,61,60,88,93,68,76,84,74,107,89,89,96,100,77,76,64,63,41,78,56,69,70,44,58,38,49,62,60,56,15,58,54,65,50,64,7,78,60,45,49,53,34,62,75,81,94,101,122,147,152,129,124,150,161,160,153,132,90,87,87,63,53,60,38,50,56,95,98,132,158,168,206,190,212,238,233,230,240,209,253,244,230,239,247,246,223,211,200,181,182,141,99,62,60,44,24,14,29,22,36,10,42,29,15,28,8,23,43,33,27,27,36,37,9,30,12,28,5,41,18,52,22,33,8,16,40,10,11,26,21,18,15,27,16,32,26,19,40,25,19,9,20,35,17,38,10,15,4,23,10,9,11,27,27,11,21,16,17,7,21,38,8,17,24,44,31,10,29,2,18,44,45,20,15,26,8,38,12,5,7,12,40,31,3,29,5,30,44,23,18,9,29,7,11,18,12,39,34,11,44,16,16,22,3,32,13,7,14,14,38,38,22,37,44,22,29,19,34,51,20,6,26,37,50,48,18,13,60,56,54,39,50,55,63,49,68,20,29,35,32,44,43,43,42,41,23,55,26,30,19,0,36,29,49,28,16,32,15,47,5,43,21,15,14,16,17,11,10,26,32,51,12,36,39,29,23,20,23,31,44,39,44,51,24,41,70,66,64,61,85,93,74,100,166,149,173,160,167,168,146,169,173,151,171,156,158,149,163,166,145,161,166,143,153,146,151,156,161,169,152,122,164,173,147,146,151,152,159,153,163,152,179,165,160,150,167,152,153,157,184,162,193,160,155,155,128,155,168,147,185,136,125,141,157,157,157,135,157,178,187,156,142,128,108,88,95,100,144,150,169,180,168,161,138,158,156,168,164,150,160,154,157,170,177,165,148,151,153,168,180,156,162,148,160,152,163,168,168,151,174,167,181,170,149,174,161,178,169,161,177,177,150,161,86,4,29,2,3,22,16,56,16,13,31,11,26,1,0,11,4,5,17,49,17,6,10,2,3,27,35,18,21,21,39,17,13,30,18,11,12,6,23,12,10,9,17,25,24,6,26,30,18,20,23,33,4,21,28,29,46,23,8,37,19,32,31,39,22,31,52,16,27,22,14,12,37,25,22,14,37,15,18,10,21,31,6,24,14,8,11,12,27,31,25,25,19,34,11,9,41,37,27,24,25,47,38,41,31,34,32,50,73,44,38,66,56,47,55,59,57,75,50,62,67,85,70,48,55,94,42,62,47,81,61,48,49,24,59,72,44,46,39,59,10,40,46,95,92,82,62,81,75,57,64,94,86,96,96,126,106,106,108,101,87,94,131,108,126,127,148,115,114,122,141,130,88,110,111,121,110,152,147,113,125,119,144,141,128,145,110,120,152,129,133,132,139,142,139,110,127,118,130,123,134,144,120,123,109,150,156,137,148,123,134,136,147,143,161,154,112,132,123,135,150,134,147,145,128,127,165,136,140,124,121,130,159,155,173,138,132,141,132,130,164,140,157,127,150,156,141,135,162,134,120,165,145,152,136,103,143,148,116,147,134,123,146,141,144,175,183,172,156,176,167,145,144,145,127,132,144,133,143,144,142,120,117,123,127,110,117,111,116,108,116,141,116,106,90,74,105,98,101,96,81,91,71,61,59,46,75,62,74,50,70,37,65,105,82,80,79,81,92,74,69,65,95,78,76,29,66,50,70,54,31,38,53,54,62,59,56,68,64,58,35,50,59,45,63,52,41,77,63,71,73,84,85,82,132,83,133,67,111,151,150,143,157,137,129,101,139,98,98,92,37,36,52,71,46,38,59,56,87,99,130,167,130,154,179,209,204,216,216,216,228,238,227,230,241,235,223,229,225,204,177,186,164,149,144,63,69,17,22,18,39,29,22,29,0,21,3,44,10,48,20,12,8,40,28,22,23,2,30,41,26,12,61,12,34,22,21,34,23,23,37,51,11,21,28,38,12,22,26,11,11,32,29,13,13,8,37,33,37,28,20,30,22,1,28,21,19,26,30,25,24,28,55,10,5,5,20,24,13,6,21,9,12,27,32,5,4,20,32,37,53,16,35,20,22,25,39,8,25,14,19,40,8,17,33,5,3,36,16,6,13,26,4,34,15,49,27,35,23,37,52,21,56,22,55,19,24,21,46,15,36,42,36,30,62,67,69,51,42,35,41,27,56,54,45,48,29,44,38,59,16,54,39,45,31,53,56,29,22,34,27,15,24,39,14,13,6,27,20,26,34,22,28,32,43,31,30,23,28,3,8,37,36,22,13,15,41,25,11,40,30,38,62,62,60,98,102,97,129,150,129,150,160,142,135,163,154,163,135,173,168,164,156,157,131,139,132,177,144,136,144,150,117,165,126,149,149,146,140,166,145,164,183,141,131,146,113,145,152,145,139,172,154,165,154,158,156,152,167,159,171,165,168,144,165,169,159,141,159,140,134,163,133,175,156,167,177,157,152,160,166,125,86,82,136,148,155,161,188,147,143,132,152,143,137,173,173,157,161,160,181,132,174,175,135,176,169,160,141,146,166,148,152,161,201,161,158,176,148,162,154,171,150,166,164,154,155,182,164,147,127,19,16,6,15,13,22,11,19,22,25,27,45,6,8,12,6,22,14,7,10,22,0,0,33,14,40,7,9,12,23,22,9,26,32,17,8,48,45,2,24,34,24,17,27,23,11,32,6,2,20,38,12,13,4,14,20,24,27,4,8,5,5,34,14,6,4,27,27,24,26,3,20,9,22,10,5,21,20,18,31,6,7,8,13,6,48,21,11,3,4,36,13,38,48,40,14,25,16,36,33,39,32,17,14,26,30,34,32,32,22,27,39,35,41,58,8,19,35,33,34,8,21,42,37,45,56,43,28,83,68,59,56,67,28,34,38,34,25,21,25,25,14,52,56,71,86,93,63,77,66,86,108,138,111,87,97,75,101,102,122,71,96,105,118,129,139,141,150,118,136,136,128,136,88,82,114,153,126,108,132,121,127,120,147,133,143,140,147,147,115,121,107,131,136,133,144,152,145,172,166,135,137,140,169,178,139,136,153,168,162,171,155,156,157,142,149,142,151,166,138,141,123,139,95,116,126,120,118,123,145,123,121,102,89,110,140,137,121,131,134,120,121,122,98,121,132,123,147,123,156,106,116,106,109,126,103,114,108,95,95,114,117,91,113,139,139,136,119,130,147,123,124,139,114,140,131,134,105,124,104,90,116,115,112,103,122,114,113,110,118,122,78,100,73,71,120,118,105,83,75,78,79,34,60,63,104,85,53,89,63,94,101,95,80,71,30,60,84,55,82,93,62,63,71,52,75,45,64,58,69,57,59,51,33,62,64,69,69,82,76,54,59,74,77,105,59,78,79,80,74,78,55,110,87,90,96,70,82,79,82,67,94,86,101,125,150,151,121,126,120,134,108,84,77,57,28,55,27,38,28,28,43,52,78,95,108,140,153,166,161,179,191,212,198,170,200,213,182,214,203,218,241,240,244,213,174,172,141,111,106,94,83,110,41,3,18,39,22,19,10,35,12,19,24,11,14,26,22,38,49,50,36,22,38,10,30,23,39,23,24,46,12,43,30,26,31,14,1,25,17,31,40,40,29,28,30,14,29,31,8,18,18,27,23,15,7,10,18,31,1,48,32,49,24,36,23,32,14,26,8,20,4,50,41,31,18,20,26,19,14,9,24,29,7,22,46,32,42,37,14,20,9,21,20,9,42,25,12,8,25,31,21,10,40,27,43,34,20,35,48,23,24,28,25,45,32,31,20,47,29,55,32,33,78,60,37,39,49,17,28,51,24,18,74,46,62,37,58,57,51,45,49,40,29,38,43,34,46,28,22,32,33,46,36,13,31,13,24,17,9,39,55,5,18,25,5,10,17,3,29,35,32,34,7,47,39,40,25,26,41,43,25,69,83,91,104,158,186,160,142,152,165,171,150,167,155,144,137,109,157,160,166,156,176,154,169,159,187,177,159,172,139,150,147,161,163,151,155,161,166,158,134,150,150,172,143,151,152,147,174,142,154,130,151,157,179,139,154,156,143,163,149,168,168,139,163,159,172,162,142,161,147,152,163,170,160,186,146,189,166,168,97,103,77,122,124,187,153,177,153,145,175,158,141,172,145,167,163,126,161,149,176,164,152,172,141,152,132,154,167,161,170,133,149,162,140,157,168,160,151,175,160,130,152,166,156,165,182,157,103,23,13,28,8,16,11,0,5,22,20,34,26,11,14,7,22,2,7,17,37,31,22,0,6,34,7,15,34,27,39,20,2,11,28,21,12,7,21,31,33,21,19,18,11,28,37,31,6,16,30,29,17,14,25,13,37,12,26,24,1,6,24,4,20,28,14,36,39,10,10,25,23,3,0,44,23,3,31,45,22,18,24,16,27,28,10,13,0,33,23,22,19,2,19,39,26,31,35,33,32,39,7,15,39,16,22,25,48,31,9,16,33,37,46,6,26,16,32,27,33,39,37,33,50,32,43,51,84,71,61,45,51,59,37,67,58,56,41,52,56,37,51,69,50,67,53,96,87,78,111,106,77,81,67,55,61,88,121,119,102,107,112,116,119,127,87,112,98,146,154,167,117,150,141,92,142,126,118,105,114,116,124,78,93,129,121,124,127,112,141,146,133,120,121,147,103,127,129,130,127,129,130,111,95,104,105,113,129,102,103,106,99,130,100,111,139,139,147,123,113,136,121,132,125,121,135,136,114,128,138,106,66,89,53,63,134,138,121,156,146,108,109,96,123,124,116,140,121,126,130,135,109,115,143,115,125,103,82,90,90,101,105,106,128,111,72,56,89,95,69,96,105,100,95,126,128,122,118,107,106,91,119,118,122,127,109,109,96,99,105,105,101,104,114,99,131,123,81,99,78,115,80,101,70,87,102,75,117,112,105,101,124,95,58,72,34,64,69,88,80,90,64,69,59,101,54,79,63,54,50,36,49,39,28,30,53,59,56,38,62,53,67,53,53,68,57,60,46,51,55,49,63,50,64,43,48,42,47,52,51,33,22,57,87,115,142,126,84,112,147,108,129,115,90,126,115,109,89,41,86,52,59,62,71,30,75,58,57,72,85,78,110,124,123,129,134,166,180,189,192,190,212,214,201,230,216,213,198,195,205,232,193,151,116,116,109,103,47,34,19,52,15,29,32,10,39,27,10,26,5,31,33,32,16,50,2,26,41,11,32,18,21,21,16,15,15,22,23,17,16,14,37,10,11,33,25,17,10,19,12,19,36,5,18,15,21,31,44,30,7,26,25,19,13,24,22,19,15,15,6,26,17,50,5,23,7,18,25,41,16,29,15,36,10,27,8,33,38,18,18,35,34,37,14,2,55,27,50,7,9,16,12,28,22,25,8,31,23,20,12,36,28,55,20,48,22,38,38,35,31,35,26,30,47,51,53,52,32,22,14,22,42,35,13,39,43,36,23,36,33,41,11,60,22,55,32,37,40,39,53,48,20,9,30,51,27,14,28,46,24,39,31,33,6,7,14,12,38,17,22,24,22,20,46,22,26,50,26,15,45,65,27,76,103,108,154,170,167,210,157,178,172,171,179,181,163,161,170,172,176,144,165,165,143,173,150,163,160,179,161,147,154,167,182,159,142,143,149,146,140,151,146,152,143,187,171,144,165,190,171,162,191,162,166,161,167,170,146,148,149,164,171,157,139,151,129,161,178,172,140,160,155,153,154,141,180,173,172,155,188,170,137,147,86,62,81,129,164,154,199,185,147,154,158,180,147,169,164,153,143,147,144,145,125,160,153,162,149,165,169,154,146,156,172,170,191,173,151,162,164,173,145,158,154,154,149,136,160,186,110,28,0,12,7,7,38,42,19,11,16,49,14,9,4,0,0,10,13,19,12,45,11,24,1,29,23,2,14,28,13,4,11,14,36,4,22,16,13,14,22,5,12,22,37,12,6,13,20,6,1,19,17,21,19,35,20,4,33,21,3,25,33,48,30,41,19,16,10,12,14,7,19,8,16,40,24,26,16,19,9,1,5,11,19,21,12,29,24,3,29,19,16,28,20,10,29,45,29,39,18,40,42,14,17,7,18,31,36,15,27,40,39,30,30,22,9,43,43,33,30,41,32,26,43,45,32,37,71,66,105,88,42,71,42,38,53,43,69,56,19,41,17,29,43,50,32,29,36,57,46,55,48,44,56,75,89,115,122,168,109,143,120,133,128,117,137,129,112,142,124,133,146,162,151,145,137,135,133,121,133,146,110,105,120,117,131,134,166,128,146,151,127,120,116,93,102,108,133,134,107,111,113,92,92,86,105,95,66,73,91,101,57,74,94,113,119,112,128,139,113,121,120,105,119,145,149,144,114,163,139,100,98,121,127,157,156,146,150,154,102,142,119,148,98,108,128,99,117,117,123,142,153,157,143,149,158,139,142,133,137,119,119,142,124,132,134,125,110,99,116,132,127,102,150,153,162,135,109,117,138,99,139,131,146,120,110,94,106,121,108,79,110,105,129,131,106,82,77,74,72,100,118,95,95,112,96,113,105,138,146,107,72,75,55,86,59,60,50,73,89,80,75,86,73,62,77,62,36,70,42,49,52,41,82,47,40,56,37,85,65,55,65,54,64,39,49,54,64,57,67,50,58,60,40,73,40,63,41,39,39,26,22,48,65,58,61,80,64,54,110,104,71,112,126,110,114,105,138,96,95,87,131,94,71,60,71,53,47,59,25,27,34,24,83,41,76,101,91,104,121,146,132,124,161,169,169,184,177,205,216,218,207,169,201,185,189,174,158,188,149,112,100,120,96,72,44,49,21,40,30,16,42,1,40,5,15,31,15,17,19,19,18,22,17,27,15,15,12,17,28,31,25,5,24,11,1,47,12,7,1,20,37,27,29,43,35,35,27,8,34,33,38,6,17,25,16,21,28,39,36,15,7,9,34,9,11,33,15,15,43,31,19,32,32,18,37,22,21,23,26,43,30,8,26,51,11,23,34,67,16,10,13,20,2,46,36,4,29,30,44,6,10,37,31,36,56,10,24,35,23,36,19,44,59,51,58,32,40,19,36,17,45,26,34,57,54,36,50,64,35,49,21,29,28,47,33,43,45,26,18,11,9,30,15,25,26,2,20,8,18,35,24,18,33,14,8,30,27,32,24,14,19,17,29,28,16,17,47,35,43,52,36,59,67,128,152,163,156,178,193,143,165,157,157,152,155,155,160,129,177,129,154,148,136,160,148,141,145,160,147,179,166,159,168,167,167,167,145,154,165,175,163,156,176,162,175,181,158,167,176,148,153,129,150,145,132,167,172,157,166,150,138,145,175,172,168,171,127,136,161,163,131,163,150,148,182,181,163,179,176,185,155,162,127,97,77,111,126,144,175,160,174,172,147,181,154,170,169,160,165,152,139,168,155,149,159,165,166,157,159,179,161,158,133,158,134,170,152,157,192,151,170,170,145,159,129,175,177,156,112,0,0,31,15,15,0,22,9,2,8,3,12,26,1,20,9,25,12,30,21,18,1,35,26,10,9,15,27,12,14,9,29,12,46,22,26,20,12,21,10,4,7,38,0,40,7,8,24,13,21,38,27,15,31,14,23,29,14,0,22,35,12,22,6,15,35,17,16,33,4,37,27,8,13,14,21,17,29,5,8,14,26,16,16,32,21,10,20,6,12,33,17,53,17,26,18,26,31,30,18,26,21,41,32,38,39,13,22,12,17,27,19,22,28,19,22,33,19,35,35,28,33,39,49,29,41,30,38,13,55,49,61,56,72,58,71,37,33,66,27,33,21,38,43,55,39,52,58,26,72,55,39,42,71,76,78,124,144,111,124,130,137,158,152,133,144,126,115,108,117,124,149,128,148,154,169,157,157,173,165,130,133,113,153,114,125,152,135,140,135,131,117,120,96,108,112,129,102,123,123,120,100,119,145,135,146,122,108,118,100,114,110,114,128,118,128,103,102,95,123,104,133,136,108,151,134,128,144,155,101,155,154,138,182,171,135,148,139,133,120,118,129,146,111,118,136,151,120,124,117,116,142,149,174,172,124,152,144,120,142,135,128,151,149,147,135,162,161,142,142,123,157,169,118,137,112,131,132,129,136,119,145,142,111,109,123,107,133,101,86,97,116,111,91,101,80,66,94,81,121,74,91,108,109,98,105,88,99,93,94,100,68,73,87,70,76,46,64,33,43,50,52,44,70,71,60,67,51,59,57,65,46,62,45,66,67,56,68,65,59,49,98,97,68,75,18,45,81,59,55,37,71,68,31,31,21,27,58,47,42,55,71,61,67,56,45,52,52,75,73,78,76,81,103,56,72,102,100,102,100,117,126,113,103,107,91,102,80,122,87,78,47,65,54,60,47,47,51,72,36,72,61,37,70,131,126,112,161,152,153,210,189,172,181,172,153,187,205,191,175,176,163,192,172,134,170,162,179,159,78,80,89,113,52,47,29,44,51,27,35,29,13,37,30,10,53,25,43,36,36,24,4,19,15,22,11,36,27,25,49,16,15,21,14,26,47,17,31,25,28,11,17,14,29,14,0,26,15,8,5,12,27,4,41,25,46,12,6,39,7,3,22,10,3,33,22,26,23,13,17,9,10,29,33,38,23,36,40,4,16,42,13,9,21,30,36,29,40,24,21,26,18,17,39,28,52,40,23,37,37,28,35,62,29,66,44,55,60,22,44,36,40,57,49,62,51,56,44,55,39,30,33,38,43,48,37,31,51,36,45,25,42,21,1,12,23,16,14,24,11,11,44,14,11,17,36,14,5,33,17,10,34,27,24,39,30,50,20,22,50,33,39,49,99,83,109,125,170,191,169,155,160,157,164,156,169,168,133,145,148,152,140,151,151,145,167,154,144,149,135,168,177,161,172,180,184,178,190,149,148,194,170,159,165,193,177,151,171,135,165,164,163,158,155,148,193,153,182,149,159,165,180,168,150,156,158,152,156,145,160,168,162,151,172,156,161,166,136,158,147,157,178,148,136,143,116,102,118,128,172,167,173,161,164,148,160,174,173,143,152,133,133,156,163,153,142,154,136,157,146,142,128,158,136,150,174,155,167,185,158,155,140,156,186,145,176,179,147,148,107,18,1,3,5,22,25,27,8,3,27,17,14,8,12,11,7,4,2,6,10,9,2,2,11,9,24,29,5,13,41,14,30,14,3,22,9,12,0,8,17,37,11,27,2,23,9,22,20,7,0,17,25,8,43,19,27,12,33,7,14,1,0,14,3,6,33,26,19,32,3,14,11,10,24,18,9,44,32,18,22,18,20,15,11,21,11,19,33,18,9,27,17,10,43,14,13,35,48,32,35,43,15,68,15,29,28,28,21,12,24,27,19,33,35,18,20,26,24,27,38,32,9,22,25,54,37,30,61,54,50,36,70,58,46,65,44,71,49,62,45,35,55,62,58,44,51,43,69,60,61,48,49,30,41,102,93,121,120,110,94,98,68,122,111,142,112,125,118,118,121,112,99,124,119,129,122,110,146,117,138,136,150,118,160,132,130,134,147,127,146,127,132,117,147,115,144,110,101,110,134,110,136,120,159,128,152,147,152,162,164,168,185,178,170,146,101,113,139,97,121,121,125,135,135,133,139,145,128,156,113,142,128,156,164,122,134,130,136,133,126,128,139,137,136,165,132,128,140,141,104,153,145,125,142,151,159,177,132,124,132,116,138,119,153,143,164,137,135,153,145,178,154,129,150,127,118,139,106,140,147,120,158,88,143,109,131,109,114,126,142,131,113,84,101,111,98,117,100,119,105,83,96,108,131,89,96,109,114,82,78,83,98,87,79,69,92,78,73,56,53,56,62,64,62,98,69,38,72,39,84,42,61,44,66,68,49,54,63,57,65,68,79,64,51,49,64,38,57,70,51,41,30,62,50,50,51,38,58,68,49,47,46,28,43,46,53,62,74,88,75,75,63,55,74,71,73,92,103,83,106,93,116,94,73,104,116,121,116,122,122,141,135,115,111,93,100,87,76,57,58,38,24,40,20,35,39,37,36,71,79,66,111,148,138,166,165,139,165,152,162,185,205,183,180,181,205,238,214,185,175,188,155,146,155,170,183,155,127,121,95,63,78,31,47,55,68,69,21,46,38,36,38,17,12,30,24,19,32,26,15,23,34,5,3,12,20,16,13,19,8,21,11,35,25,31,15,16,33,10,25,20,38,16,10,18,31,23,53,38,42,35,11,11,14,2,20,23,18,20,8,43,11,46,15,31,35,27,21,20,8,32,28,18,44,18,29,36,16,5,2,8,25,19,34,27,38,28,34,28,32,28,28,34,57,45,45,49,43,63,63,65,58,45,54,44,52,37,58,42,44,32,48,28,18,21,17,18,58,49,34,9,29,31,3,13,7,22,38,29,28,4,29,19,11,26,12,10,11,26,12,31,24,4,19,26,24,28,67,39,61,59,53,60,75,52,92,117,136,158,167,169,161,182,170,192,175,167,140,139,149,177,167,142,175,124,178,167,171,156,168,170,175,152,173,133,169,166,159,176,172,178,128,159,150,167,133,166,166,159,175,171,151,172,161,160,162,178,174,142,146,153,156,180,143,150,170,162,155,177,192,134,156,157,154,167,146,151,147,157,145,148,144,165,142,151,116,133,104,92,111,136,159,166,151,145,167,149,170,146,150,146,164,144,150,161,151,167,168,157,147,162,146,146,176,171,148,174,151,147,173,147,167,154,172,163,177,185,165,187,135,0,4,2,9,20,11,29,18,13,25,26,5,23,19,6,1,1,4,27,30,16,16,19,29,7,18,7,16,6,6,17,13,21,24,26,20,18,7,28,18,13,26,15,12,12,10,3,17,23,13,14,35,15,41,14,18,19,24,53,25,12,9,35,18,3,2,25,25,18,3,23,10,17,20,15,8,27,44,17,4,32,40,2,7,7,37,11,13,19,16,53,32,33,29,8,22,31,36,48,20,31,31,27,29,11,22,44,35,27,13,41,33,54,37,44,13,26,36,23,41,28,30,11,62,50,60,28,30,38,60,50,33,24,44,73,48,67,86,76,82,93,65,38,74,83,56,59,73,80,69,66,47,64,102,99,127,129,113,123,90,109,82,90,93,99,119,117,100,100,127,114,85,113,76,85,94,111,87,124,127,128,120,137,144,119,139,102,145,137,126,119,137,150,147,147,141,141,129,126,111,165,143,115,116,129,147,116,138,156,150,142,156,130,140,131,118,139,149,149,163,144,161,173,169,144,154,143,135,135,148,145,131,134,157,127,125,146,140,141,140,128,123,145,155,162,105,136,110,109,122,143,127,101,140,95,124,147,135,132,133,127,144,159,142,127,138,128,140,132,126,136,139,147,122,101,120,131,107,120,116,141,140,123,134,141,132,126,128,110,127,93,122,106,98,86,80,108,119,99,118,109,124,117,136,95,115,72,96,73,85,87,70,77,97,96,45,64,48,45,51,54,84,39,62,63,43,68,43,55,72,71,59,68,52,55,61,61,58,44,54,74,44,40,41,56,54,50,41,60,54,57,47,47,62,43,82,49,61,84,59,73,43,50,69,45,37,55,54,62,67,76,79,105,93,77,113,121,108,113,90,86,62,82,71,73,113,88,93,125,122,112,147,92,108,115,130,98,92,106,118,75,69,60,52,42,44,58,42,24,30,53,25,31,46,86,92,84,80,107,113,112,149,121,145,167,177,153,208,186,189,178,175,162,210,198,202,173,156,127,140,177,151,141,129,168,167,108,54,85,115,104,69,49,79,27,35,26,41,10,35,12,18,35,5,35,16,5,14,15,10,11,28,22,12,20,11,25,8,17,8,6,8,12,11,29,22,19,27,10,20,28,22,34,15,45,31,4,18,11,39,25,17,22,31,10,19,25,25,1,23,25,35,50,22,21,41,12,16,31,28,36,6,63,15,21,40,27,48,29,7,26,20,23,66,30,25,57,46,49,55,77,60,76,40,50,31,46,51,30,20,33,33,14,35,33,48,32,33,19,31,13,42,19,29,17,7,17,27,16,7,27,25,12,37,23,28,38,13,22,13,2,31,27,25,33,25,37,34,41,65,68,71,79,80,84,95,90,129,125,146,132,148,170,149,145,168,161,154,158,172,177,169,152,155,145,151,157,162,139,136,136,145,145,155,121,151,171,150,164,161,139,159,146,163,150,168,145,169,150,172,149,166,182,134,147,157,146,164,166,142,156,143,141,175,166,155,182,157,171,158,144,144,162,158,184,154,154,160,161,166,184,171,143,172,146,155,158,127,90,97,98,140,177,174,178,169,156,181,145,181,168,150,158,167,150,137,147,158,164,174,155,141,142,177,163,156,177,163,135,152,156,141,157,171,176,173,140,154,163,104,21,15,11,6,35,21,12,45,11,29,26,28,45,19,20,7,12,20,28,5,17,14,23,15,6,30,49,13,14,16,23,34,23,12,6,16,6,16,11,25,7,36,36,14,5,54,35,20,18,26,30,16,25,9,45,11,32,32,21,20,24,10,31,12,27,24,20,4,16,16,27,15,39,18,18,8,24,33,3,8,27,37,48,32,20,22,35,9,19,8,23,20,23,28,40,58,49,46,20,20,37,14,23,42,38,39,23,58,39,43,41,52,54,53,47,35,65,51,61,30,75,58,63,33,52,74,49,42,64,72,60,89,49,91,50,70,83,87,82,81,81,59,55,73,91,113,99,116,110,123,110,92,109,140,138,145,156,133,141,114,138,110,116,98,111,124,118,134,114,86,156,101,93,106,114,144,125,128,113,142,100,94,89,110,111,132,126,124,110,127,135,96,137,112,119,106,103,118,111,135,143,120,128,119,100,117,118,118,111,117,117,87,110,110,70,101,159,120,140,157,111,130,137,151,140,132,142,137,108,146,95,126,128,121,133,151,156,131,123,141,144,149,124,114,123,130,109,116,134,130,113,145,129,114,110,124,120,144,108,133,113,129,107,149,141,138,123,131,109,127,137,114,127,100,125,145,117,107,113,110,106,112,126,142,133,124,86,114,79,92,124,144,144,88,119,91,105,110,92,73,107,139,128,116,75,102,68,85,95,97,95,68,57,90,63,74,71,32,74,63,77,73,69,95,65,46,79,60,53,56,65,52,75,82,59,85,85,57,50,58,90,53,47,69,39,62,59,66,68,54,60,43,38,45,54,44,66,58,46,51,67,60,36,43,48,47,42,42,54,64,56,44,64,59,49,47,32,31,36,51,62,41,20,62,67,68,54,72,53,58,90,79,79,66,95,99,85,98,85,110,109,121,104,83,54,58,87,61,48,43,42,16,36,52,48,35,25,55,42,16,37,30,57,78,91,121,105,117,135,130,112,136,107,155,136,144,103,130,166,157,142,165,147,140,132,125,110,142,123,155,154,138,157,128,121,100,95,110,104,74,74,65,42,48,55,30,40,24,31,36,18,31,33,34,10,5,22,21,11,27,34,4,30,29,10,30,20,27,4,10,5,15,36,37,30,42,10,20,32,20,14,19,12,26,46,23,36,22,31,26,33,9,14,68,46,30,10,2,34,25,11,27,6,31,37,13,33,44,31,56,23,47,53,34,66,38,60,65,13,37,72,75,70,46,44,41,61,48,49,45,40,53,25,40,36,31,30,27,36,6,16,11,12,14,10,25,4,7,39,29,27,21,29,5,30,40,15,13,19,40,2,40,25,42,35,51,47,42,45,70,82,80,76,89,111,79,74,111,104,118,145,141,152,136,160,124,156,162,184,147,155,146,158,161,149,164,153,169,158,150,145,157,174,164,121,173,134,150,120,149,148,151,164,138,146,143,171,177,163,133,151,154,154,158,164,178,131,170,157,162,178,155,165,186,174,155,177,161,158,143,141,142,166,172,158,163,177,181,171,170,152,180,173,157,187,160,149,149,148,93,117,98,130,152,175,172,166,169,156,162,168,145,162,157,143,144,168,137,169,165,126,131,164,161,160,137,169,139,177,154,149,148,157,163,175,149,173,166,160,110,10,8,23,15,30,10,0,28,34,17,16,14,13,4,34,6,19,15,11,10,9,7,13,24,4,32,10,25,19,22,30,19,38,15,28,17,34,19,27,33,20,15,56,28,23,17,10,37,20,20,35,12,22,20,40,24,41,8,30,0,2,9,37,4,39,11,11,23,5,19,20,14,11,25,13,22,55,43,37,11,20,26,30,19,37,33,33,27,18,23,11,15,47,42,47,46,23,39,19,58,37,43,70,49,56,36,57,80,48,68,52,62,46,50,53,63,83,58,40,67,49,25,57,56,31,52,30,29,32,46,60,49,60,62,38,48,67,33,48,63,68,52,29,57,62,49,43,74,81,115,111,142,85,121,100,88,80,118,121,120,129,122,110,115,122,97,115,122,119,147,109,122,114,115,127,120,108,114,115,116,128,113,95,106,116,110,118,98,80,96,118,106,116,120,107,86,106,110,127,123,137,144,121,99,113,103,104,130,85,109,106,123,100,121,97,119,126,105,118,95,81,101,119,120,91,116,109,121,138,129,107,106,120,130,148,132,131,110,148,126,118,117,114,123,141,141,155,112,115,144,128,164,155,136,108,147,140,129,136,119,130,106,143,137,123,127,136,130,158,130,138,121,106,125,101,109,114,101,109,104,112,133,104,135,107,109,124,100,116,105,116,106,103,87,123,107,100,89,92,77,107,90,106,134,75,98,86,77,103,90,90,84,68,65,55,69,90,101,64,58,65,71,67,58,46,50,58,46,49,48,35,46,71,41,61,31,79,44,47,94,71,28,48,28,51,56,56,49,47,57,60,42,52,55,47,66,44,66,67,59,26,58,54,48,43,60,45,66,61,62,39,52,57,45,56,45,67,34,38,59,57,43,27,33,47,50,45,56,47,72,41,64,56,72,56,71,64,76,93,100,93,77,72,86,86,77,113,71,89,111,76,74,68,61,48,51,48,59,17,33,27,44,66,36,33,33,40,63,29,13,50,69,71,89,71,67,86,117,123,89,100,139,139,87,109,100,149,130,128,149,160,120,144,139,136,119,151,128,142,114,143,144,143,137,136,145,130,63,83,72,59,79,68,37,54,25,44,62,31,55,32,38,43,51,51,29,42,20,40,22,13,3,27,24,3,0,13,31,16,40,17,12,31,18,21,9,2,30,9,12,7,33,34,30,7,20,12,5,20,28,38,35,34,52,13,31,41,50,57,34,29,37,32,57,56,33,36,57,39,45,58,44,75,70,54,42,22,71,68,61,42,34,45,24,36,22,57,28,18,44,45,36,18,5,5,51,15,17,13,22,13,19,21,41,37,25,35,20,3,27,23,30,60,19,56,61,62,88,45,35,86,79,81,89,93,72,70,89,112,91,132,122,140,90,139,138,138,153,161,142,163,159,138,149,156,160,149,159,156,154,148,142,179,172,170,164,168,158,157,147,164,166,178,176,147,112,176,124,140,152,157,163,174,146,156,159,151,140,160,166,164,150,155,119,132,152,150,155,139,141,150,165,146,171,161,169,181,174,151,160,160,143,156,169,181,160,132,163,159,133,129,96,96,126,153,171,193,172,170,160,166,167,175,174,150,133,160,154,143,158,149,146,153,139,171,161,164,158,159,158,172,168,153,146,178,144,138,147,154,108,0,17,26,2,11,6,9,4,8,11,27,14,11,8,19,10,19,10,14,11,20,8,15,21,26,32,27,42,23,6,15,1,15,9,25,6,27,8,14,3,10,13,25,32,21,22,15,12,24,12,40,18,37,12,13,18,13,1,7,22,26,9,29,22,39,27,36,20,20,24,40,20,27,36,3,6,13,12,13,38,20,8,12,36,8,25,11,10,9,33,27,21,32,38,18,33,48,49,14,20,58,64,55,71,56,31,42,27,44,31,20,25,57,54,35,38,52,38,44,35,34,33,20,16,35,21,45,27,31,48,39,36,32,23,42,61,41,39,50,43,30,32,50,45,33,11,32,56,35,65,85,96,95,90,78,73,87,93,102,125,115,114,102,81,79,75,97,103,109,147,142,96,127,115,137,104,92,119,121,106,124,109,118,120,128,122,115,127,129,125,120,140,126,128,139,134,122,144,134,116,104,136,134,130,101,122,101,120,136,132,128,105,127,138,126,102,135,123,132,114,118,103,104,123,108,109,105,122,112,131,110,130,128,161,104,156,123,116,121,114,125,112,96,148,130,144,113,105,133,143,165,131,117,140,140,164,140,155,128,119,128,117,147,115,123,134,100,127,127,121,121,99,127,155,101,158,124,118,110,114,70,118,75,85,122,112,108,121,133,84,117,105,74,93,104,100,94,110,112,90,79,78,105,107,118,126,108,85,105,125,99,72,67,60,39,103,75,58,54,58,75,61,72,50,76,76,33,78,30,36,51,76,42,45,71,54,39,62,52,61,47,30,43,43,58,62,67,75,45,52,53,71,30,62,35,55,34,75,28,55,35,37,75,37,40,35,63,61,58,48,73,52,57,41,47,74,66,56,67,70,67,72,28,42,54,45,77,61,74,63,55,66,49,62,53,42,53,85,34,59,85,52,68,94,69,53,86,85,86,66,29,60,73,89,128,139,134,84,88,88,72,90,39,51,55,53,33,29,30,18,63,46,28,46,56,64,54,51,64,54,33,66,84,69,90,75,127,90,105,124,89,102,134,120,144,141,131,137,123,138,129,125,108,129,112,128,124,157,135,117,141,140,130,125,129,114,118,91,105,118,91,98,75,95,73,51,60,69,40,37,39,65,42,36,35,14,31,22,48,33,17,21,25,21,22,18,22,43,9,3,18,3,31,5,44,58,28,10,19,22,28,32,31,17,28,39,32,32,38,48,50,43,51,54,35,44,43,50,33,16,47,36,20,65,61,41,32,54,54,48,62,10,30,31,34,23,58,18,23,19,21,22,16,0,10,25,31,45,1,28,26,24,27,34,40,44,15,55,48,58,50,44,33,75,61,42,57,83,76,72,57,47,53,76,56,49,85,60,81,78,86,108,132,149,169,155,154,160,140,138,177,147,147,158,184,127,94,121,160,153,150,169,151,174,158,152,161,180,177,159,170,147,165,118,131,143,144,156,155,140,141,141,151,141,143,140,159,162,151,157,167,160,148,156,171,174,153,155,142,130,149,140,141,139,162,133,143,171,147,149,172,152,155,188,171,154,146,158,175,149,158,120,117,96,111,149,145,185,183,171,170,154,129,156,149,161,154,179,171,139,164,193,156,159,137,184,176,156,160,168,169,169,164,144,172,161,169,163,177,99,24,0,14,3,20,24,40,20,35,11,32,14,23,7,14,4,16,19,5,14,16,12,19,19,22,6,31,6,12,38,16,16,8,28,7,35,42,37,28,23,51,30,18,34,22,15,50,19,20,26,0,6,28,22,24,3,15,32,1,19,13,19,19,9,15,25,25,2,8,24,20,5,7,43,18,7,24,12,12,20,35,30,9,12,30,31,6,8,18,28,9,48,24,31,46,37,63,46,40,61,65,63,66,58,65,55,55,21,20,27,51,46,40,46,35,44,32,22,37,34,45,19,27,25,41,27,59,68,33,39,14,40,48,64,37,53,36,29,78,54,22,33,53,24,44,31,43,46,60,25,78,60,91,111,92,95,92,106,100,128,95,94,102,95,116,120,107,144,117,109,122,118,107,144,142,132,121,124,127,131,122,121,124,120,119,102,124,122,127,127,130,136,137,118,118,137,117,112,126,107,111,112,103,100,114,94,86,127,121,128,108,118,139,138,115,105,117,102,124,119,134,145,142,113,133,131,114,148,115,134,130,123,126,140,129,123,147,151,136,124,150,119,123,134,129,125,135,119,121,117,143,160,155,172,177,160,144,150,130,161,147,116,127,134,141,106,94,113,120,142,130,137,113,126,147,133,104,131,134,139,124,123,150,96,111,120,111,93,88,107,73,112,94,93,117,97,83,71,73,73,102,79,87,106,110,86,107,106,104,104,91,108,78,72,85,55,49,62,77,74,60,59,51,73,75,95,48,56,34,59,47,45,70,48,79,53,72,71,37,55,81,42,51,55,26,58,54,67,66,58,76,65,63,38,72,48,50,29,55,65,80,53,76,29,37,48,57,51,58,47,62,74,44,33,66,92,57,57,61,67,79,68,69,50,50,50,62,71,64,50,59,63,68,40,62,62,44,59,68,76,61,38,52,39,44,27,51,45,45,60,25,55,62,103,106,86,94,115,95,135,82,98,97,72,72,82,73,53,38,66,56,23,45,49,57,50,19,42,25,49,28,35,57,31,67,58,68,66,50,50,54,40,99,89,101,100,63,90,101,97,127,86,77,122,109,110,124,123,112,122,132,108,144,112,144,96,159,169,150,153,95,103,146,86,91,132,97,161,110,157,112,125,151,141,100,88,112,91,79,83,45,66,58,55,45,50,41,36,60,21,9,39,23,21,24,24,11,6,31,50,22,24,5,42,12,51,32,10,34,43,25,39,50,42,42,51,51,71,18,69,80,52,50,50,62,61,85,68,58,64,32,25,29,18,42,8,26,14,23,19,46,9,15,33,26,12,39,48,23,45,44,30,28,28,34,41,38,48,69,62,61,25,47,53,73,52,61,66,56,63,59,78,82,86,77,75,61,78,53,82,122,97,116,154,191,197,167,127,149,121,113,143,189,144,156,146,146,155,147,157,154,158,156,143,132,153,159,157,137,151,122,152,146,136,135,156,150,167,169,169,151,174,151,142,150,172,147,139,172,158,159,140,124,143,149,144,148,154,157,142,168,198,176,155,155,140,149,166,147,156,149,146,152,117,172,150,163,172,154,152,159,141,107,101,95,91,108,157,171,170,149,133,130,147,135,171,160,123,158,155,153,173,180,173,168,172,147,179,145,131,171,164,162,149,156,169,168,140,167,122,6,3,11,3,30,20,32,9,3,13,14,12,14,0,5,12,5,9,4,0,23,3,9,27,15,26,24,31,19,31,1,27,17,5,33,36,7,40,26,11,0,28,6,20,38,9,23,28,15,15,14,25,5,21,27,29,24,14,47,22,33,7,24,12,29,21,26,14,5,5,6,16,23,26,15,2,8,40,19,15,25,25,27,45,1,35,13,18,35,6,34,10,35,24,16,49,26,55,33,37,41,17,41,43,42,29,28,48,18,44,51,44,14,16,26,39,21,29,44,28,9,48,35,5,34,31,26,24,29,23,8,39,15,29,43,17,30,43,17,31,39,22,40,24,1,29,53,31,18,42,65,56,72,83,88,94,116,120,122,124,102,133,89,114,127,113,123,87,95,94,121,102,121,110,82,108,91,131,102,98,129,104,119,107,120,120,115,105,135,92,110,121,119,107,116,119,112,113,123,97,133,114,129,133,127,108,114,97,105,96,106,121,92,101,115,107,93,99,121,114,108,123,107,122,114,118,138,126,124,119,117,122,101,73,87,121,108,98,112,113,99,152,144,142,131,130,109,146,118,102,94,132,143,152,148,125,108,141,127,137,118,98,110,121,135,112,143,163,137,160,136,124,137,94,134,116,120,129,136,150,123,136,132,126,121,92,122,102,99,87,94,90,95,111,98,109,80,87,68,52,90,84,75,71,64,103,109,102,87,96,83,96,103,104,97,59,87,112,63,96,72,72,29,44,62,89,72,26,60,73,68,72,82,48,64,66,58,39,81,45,48,54,58,50,76,68,61,58,31,47,60,53,57,55,41,31,49,69,55,45,56,47,42,32,57,75,51,76,42,43,12,56,44,53,46,32,64,56,55,83,33,56,64,59,56,39,37,33,52,73,34,60,55,71,48,47,48,29,61,46,43,51,62,50,40,57,17,40,56,57,57,61,66,67,51,45,72,43,35,85,68,84,64,65,79,86,94,95,94,75,86,65,89,93,87,71,77,73,82,54,43,45,46,27,44,36,34,50,21,47,40,33,37,32,44,32,46,50,50,47,68,64,61,71,58,59,80,64,91,97,109,109,116,90,99,125,130,139,117,121,145,123,109,102,139,123,105,135,146,155,125,122,153,145,146,144,144,132,167,152,109,154,135,124,112,104,123,48,93,99,73,83,44,37,66,10,15,32,30,53,54,46,24,7,34,11,4,24,22,51,28,1,24,38,64,44,51,41,22,37,57,81,37,47,45,41,76,55,47,35,11,44,33,9,32,31,23,41,27,30,38,50,55,25,22,36,54,67,42,68,62,65,73,66,44,59,51,51,48,31,63,70,42,44,55,20,46,50,69,61,70,75,104,67,78,80,74,74,80,84,142,129,150,149,171,177,160,162,116,165,134,145,157,138,174,160,143,185,171,170,157,157,179,165,143,125,169,157,128,126,145,158,168,169,152,138,162,164,138,152,153,161,161,152,145,157,188,161,157,163,187,158,182,153,139,148,185,150,170,164,174,194,156,161,160,173,147,139,164,165,165,162,152,141,162,175,165,182,154,136,149,143,171,120,123,99,81,143,163,170,170,151,152,185,174,178,166,176,158,162,157,155,147,144,163,138,177,130,133,134,159,140,176,155,150,155,160,143,160,94,8,5,24,6,15,2,11,8,25,6,28,25,24,3,40,33,28,25,19,8,15,1,14,36,18,5,47,34,9,30,11,34,23,22,4,5,13,20,5,15,17,17,17,41,23,0,34,39,16,22,25,31,7,12,41,10,12,16,38,23,18,43,31,22,22,25,24,7,12,15,5,18,31,14,28,3,22,13,25,16,18,32,45,40,27,4,18,30,25,11,36,19,30,6,8,22,52,26,21,15,14,21,32,33,17,36,47,3,15,46,22,6,48,38,25,31,14,5,31,30,21,53,30,32,27,16,24,33,39,22,42,9,35,55,33,31,45,36,71,55,60,50,29,26,30,23,37,22,44,36,51,75,75,96,97,82,83,120,92,118,118,125,109,119,107,91,107,99,115,114,123,118,97,133,101,96,74,73,71,139,97,104,111,84,101,109,120,128,103,127,111,105,101,129,97,117,103,119,130,105,132,128,131,132,124,109,102,105,106,116,129,146,138,79,111,127,106,102,123,101,79,115,107,131,135,109,146,103,115,100,109,101,90,69,106,79,94,94,114,120,116,123,85,134,93,125,109,121,106,115,123,103,101,100,117,119,104,133,113,127,147,117,142,113,134,151,131,137,139,137,125,86,105,90,114,119,115,125,95,134,103,110,120,109,95,122,105,121,114,94,112,100,94,103,104,104,107,98,110,62,91,64,92,80,72,52,95,82,81,52,85,73,99,98,107,109,115,102,96,108,84,92,103,88,96,95,110,118,88,65,50,52,46,60,63,62,57,73,34,92,25,31,39,49,63,67,57,64,69,42,83,61,80,58,32,54,77,46,62,56,44,45,34,56,58,59,57,39,58,67,58,53,56,36,30,42,43,29,92,60,25,35,21,40,36,52,46,29,42,17,58,49,54,30,34,47,43,48,26,13,40,54,61,61,24,59,61,48,43,67,41,35,38,56,44,61,58,66,38,67,34,47,54,59,70,59,68,62,63,60,74,51,103,107,123,87,97,82,59,75,63,52,65,55,45,43,60,56,53,13,64,47,37,36,31,21,34,26,45,39,48,48,42,41,45,32,51,42,42,73,44,55,56,68,61,75,89,75,96,82,86,86,98,98,120,105,116,111,117,136,112,110,101,109,147,114,107,124,140,139,113,114,144,147,154,155,147,150,124,146,160,157,140,145,166,177,171,190,210,211,238,183,176,176,159,198,95,138,67,50,33,58,94,41,7,33,20,41,25,28,52,42,56,47,46,41,38,70,47,46,26,36,15,20,50,34,30,27,40,30,45,51,60,43,41,54,55,74,31,49,59,23,15,40,49,21,32,41,41,18,20,36,41,44,62,56,31,50,82,68,59,94,83,75,70,77,48,62,59,58,85,89,108,149,144,167,164,149,145,150,165,146,136,149,147,168,154,152,151,186,184,157,189,179,150,142,170,136,131,129,179,171,157,152,157,160,165,171,183,158,159,177,167,160,175,146,182,140,152,166,172,157,173,177,145,143,142,185,152,184,186,165,178,162,164,166,175,155,160,135,162,183,158,192,149,179,163,157,156,153,178,177,187,161,172,117,103,90,124,143,161,172,164,153,157,172,155,148,158,161,144,176,193,181,162,148,183,161,148,144,180,160,158,162,163,144,180,162,156,125,1,14,1,28,5,12,9,26,6,16,4,24,26,6,21,24,1,0,42,8,29,10,22,11,36,26,61,29,48,49,40,33,54,31,59,43,49,36,24,27,21,15,13,10,26,11,11,40,14,28,28,28,32,19,28,29,39,25,10,27,8,37,9,10,19,22,52,1,19,19,19,0,23,17,20,33,11,20,24,16,17,19,3,28,7,26,5,42,37,21,43,14,27,35,39,34,46,15,37,25,33,42,24,40,74,9,21,13,6,48,20,29,29,19,34,10,16,29,31,26,14,36,2,30,23,34,21,19,36,30,35,44,50,29,24,3,24,46,44,25,69,28,71,80,86,53,42,54,48,64,77,62,102,114,77,88,59,79,76,73,78,118,116,94,105,109,122,94,111,119,92,98,108,109,118,92,120,103,105,99,107,95,111,89,107,101,94,129,103,116,120,115,112,107,112,131,138,122,128,96,104,107,108,108,108,117,123,118,94,112,108,131,123,128,108,123,140,125,110,96,102,132,95,114,97,133,132,118,108,125,118,113,91,103,92,92,102,90,78,70,92,103,78,97,118,97,119,112,116,102,117,81,75,73,112,117,86,121,123,126,120,121,134,110,163,128,94,126,102,96,99,132,125,110,104,124,133,97,121,121,95,80,95,85,101,98,106,107,114,123,86,112,97,99,106,106,120,110,105,128,103,83,76,84,73,87,37,72,58,59,77,60,88,94,78,81,107,79,98,95,105,121,95,115,101,107,89,96,80,61,87,101,61,55,68,47,83,46,63,51,58,29,83,60,72,67,52,44,49,44,45,62,65,29,41,66,56,67,45,56,64,57,61,40,46,67,65,75,65,55,61,49,21,15,53,68,52,43,38,57,29,49,51,61,35,44,53,59,58,66,21,64,59,80,60,50,38,39,66,26,37,54,68,50,62,59,63,73,58,74,33,29,50,37,22,57,21,23,36,56,35,67,51,21,44,47,49,28,60,41,74,69,66,47,65,65,71,63,82,53,52,86,73,70,58,66,77,83,69,67,74,52,43,36,51,71,70,72,46,33,57,23,11,70,22,34,41,24,53,42,53,30,27,36,33,39,30,44,49,39,45,41,64,80,73,77,93,57,70,101,97,64,102,102,106,113,79,129,117,141,129,124,140,134,148,119,163,184,167,154,138,150,190,209,228,237,238,245,250,247,235,240,241,238,255,255,251,233,244,231,234,247,251,227,177,156,105,15,20,10,9,41,33,50,32,64,35,29,61,34,18,34,39,24,34,48,55,24,25,21,10,36,52,56,75,58,78,49,30,48,39,35,50,27,67,46,35,36,48,42,37,29,46,58,27,39,42,60,38,54,61,60,42,46,44,52,68,37,66,70,50,74,106,127,132,135,149,145,188,164,160,170,151,147,171,175,160,157,166,156,170,165,177,169,128,128,150,135,172,147,165,190,160,144,159,169,162,148,165,164,165,143,147,171,165,149,133,166,142,172,151,160,156,163,184,163,164,165,156,149,168,155,163,169,173,146,179,168,164,159,141,160,174,150,158,129,174,165,164,174,170,161,153,163,164,178,113,86,96,103,137,161,179,163,138,150,156,131,118,132,149,143,170,166,155,172,193,156,137,142,167,176,157,181,166,155,141,152,159,110,1,0,12,7,7,19,9,29,12,18,14,10,15,7,28,6,7,11,28,11,3,17,43,19,57,78,79,89,61,124,84,113,122,111,124,128,90,48,50,52,26,34,23,21,24,9,48,21,19,16,2,28,24,14,25,9,18,21,16,23,19,11,18,0,18,26,18,25,17,23,6,7,18,15,42,36,10,6,41,9,31,14,15,21,9,17,17,30,27,30,27,12,5,23,40,33,20,27,50,12,48,46,34,47,53,47,47,7,19,38,41,20,55,45,19,12,4,11,21,6,11,25,20,17,27,47,11,34,17,41,12,50,28,44,55,20,30,43,45,32,41,51,72,51,29,37,70,50,62,52,65,62,78,68,60,63,67,77,77,83,90,110,89,57,77,56,98,112,115,103,99,101,110,94,129,113,107,132,108,140,125,105,100,105,132,123,117,133,117,121,125,129,123,117,138,114,106,96,114,90,112,112,103,136,100,119,102,128,92,143,104,131,119,127,123,131,117,156,114,135,116,141,106,116,135,119,115,121,129,133,104,109,153,130,104,107,54,86,92,136,111,117,141,112,112,94,114,123,134,121,113,110,120,107,138,128,106,112,119,135,146,137,151,138,126,121,80,118,101,103,116,104,108,107,145,145,107,103,115,112,113,88,134,101,113,108,105,87,115,110,80,86,114,106,102,95,86,93,95,93,84,78,87,89,72,94,81,83,92,84,64,78,68,45,44,66,58,58,77,48,57,58,84,66,67,62,71,98,63,71,36,56,68,53,61,69,35,73,68,54,55,51,49,67,55,69,77,69,53,68,53,50,35,39,58,57,48,73,76,70,50,52,52,52,34,44,52,45,50,35,44,37,47,41,31,32,38,27,57,67,39,53,58,48,66,51,49,57,57,40,37,35,54,49,44,64,52,44,32,22,60,49,46,53,30,57,62,45,54,46,29,50,45,35,32,50,22,56,28,55,54,63,37,21,28,49,70,56,57,53,52,58,22,56,39,75,63,27,47,60,48,48,56,45,76,62,41,66,65,70,62,81,64,70,70,69,79,69,72,53,63,71,54,66,45,30,94,75,48,34,69,28,30,41,43,51,55,52,45,38,20,30,40,34,54,36,55,44,37,45,55,64,45,53,79,95,68,78,84,102,59,115,135,112,128,135,124,131,148,170,180,187,238,250,251,239,242,249,248,213,255,249,253,246,250,248,241,246,252,252,255,251,250,241,243,247,230,187,77,38,3,9,22,8,26,67,43,57,42,48,43,41,48,18,45,35,51,61,36,41,27,39,35,36,44,22,37,18,37,31,47,11,39,31,32,27,37,20,45,16,42,22,38,33,32,48,60,33,37,69,42,44,83,46,69,51,57,51,62,40,59,59,76,86,80,107,139,184,143,154,183,159,148,156,160,179,171,156,150,154,169,178,178,168,133,136,167,154,140,154,160,161,142,140,185,171,164,183,174,186,149,170,152,166,171,164,174,151,145,181,156,126,158,169,162,184,155,152,156,137,141,138,158,150,154,157,174,157,174,149,150,147,168,146,150,146,165,172,147,165,153,166,157,158,128,163,121,144,104,62,113,91,140,132,174,170,154,146,140,112,153,153,146,145,168,166,156,159,151,146,151,161,156,153,172,163,168,155,136,129,26,2,17,20,2,21,25,7,1,33,29,10,7,13,28,9,7,9,32,17,30,10,24,2,153,154,183,182,175,169,182,153,152,146,147,136,129,102,64,51,23,38,47,12,7,17,19,37,8,38,20,10,1,25,16,29,20,4,1,12,34,16,26,17,16,25,36,23,8,32,40,18,21,34,17,22,13,8,10,10,17,7,2,16,3,20,19,0,2,31,13,33,29,22,25,32,21,16,23,8,73,21,59,44,34,32,50,0,26,47,44,23,52,36,11,34,22,24,37,20,2,29,21,28,39,16,16,50,13,20,21,40,49,23,50,37,54,36,58,64,48,33,52,53,52,30,18,45,33,38,49,57,65,59,65,48,62,60,80,58,95,73,90,57,84,85,110,104,99,86,112,118,133,117,96,116,121,130,113,126,134,110,135,135,128,116,86,102,106,117,143,123,139,100,128,120,117,136,121,122,135,103,133,132,103,106,110,98,85,106,119,136,125,112,82,152,123,133,102,125,123,111,124,123,126,111,110,118,94,127,105,122,135,148,143,135,108,134,143,135,145,138,118,130,117,124,113,124,114,118,108,112,142,140,101,94,109,132,83,95,95,110,116,112,109,129,132,95,102,113,97,103,114,98,116,119,114,98,122,113,126,97,92,98,112,116,87,71,82,107,83,84,96,83,82,91,83,100,104,94,88,108,83,86,60,94,85,98,100,103,94,78,94,80,67,99,79,107,76,67,61,27,58,29,53,54,66,82,84,62,67,60,55,59,45,55,90,66,51,64,38,63,43,56,90,40,60,46,55,55,71,48,63,44,36,59,40,57,43,63,47,28,36,55,67,50,56,71,47,42,49,37,49,47,72,46,42,50,42,51,51,34,60,53,6,44,39,38,36,56,55,55,38,63,53,34,50,67,34,62,39,51,56,29,42,33,24,41,66,46,45,69,49,65,51,51,39,31,60,56,46,53,32,37,51,59,49,64,57,44,77,63,48,41,32,58,43,58,49,68,48,60,8,48,46,59,38,58,61,45,55,79,48,25,51,47,33,40,65,75,77,45,84,56,20,46,61,69,50,62,41,65,38,65,63,43,45,44,49,37,52,33,28,39,47,29,44,37,48,61,44,37,34,34,57,52,32,70,45,69,44,37,60,65,69,88,57,98,111,161,136,181,206,210,212,220,212,229,243,244,247,242,252,250,253,231,244,255,253,246,252,250,253,252,244,253,255,243,203,168,152,121,31,4,8,20,14,17,49,52,53,57,15,48,33,35,30,35,45,39,14,53,42,26,38,27,24,23,18,33,37,53,41,46,43,47,39,51,35,31,33,31,26,22,58,38,39,27,27,50,69,60,58,59,60,57,49,52,76,62,64,74,64,100,93,90,126,154,119,117,131,142,131,140,158,157,175,164,151,126,147,160,143,139,161,171,146,165,144,163,151,148,142,164,176,169,169,184,161,145,129,129,153,158,167,161,150,166,144,165,161,162,136,160,173,169,186,172,185,164,178,135,139,156,165,145,152,155,138,160,146,127,144,150,178,183,118,139,158,161,147,166,164,171,188,138,167,185,135,87,73,109,150,153,178,177,188,166,153,164,144,123,149,142,155,164,156,135,159,143,131,165,185,159,147,181,130,139,168,110,23,6,10,9,11,3,0,1,18,15,21,15,8,5,19,46,24,15,15,11,6,18,31,17,175,151,184,146,131,132,121,133,109,75,64,35,51,27,47,33,32,26,18,14,16,30,2,33,8,16,26,26,22,7,5,20,25,14,25,20,13,6,24,38,8,25,26,45,5,23,14,14,8,2,3,21,11,27,9,10,43,12,36,29,18,20,27,53,27,54,36,11,18,50,47,31,21,54,40,17,35,34,39,49,18,14,17,30,13,31,77,17,39,43,31,29,18,29,27,26,20,29,19,42,62,23,41,22,18,25,59,45,56,71,14,29,51,43,51,45,68,63,60,96,66,48,43,40,64,36,86,69,101,106,107,101,61,74,90,94,85,133,120,101,95,132,110,126,81,120,137,99,113,126,102,121,99,107,110,113,107,126,111,116,104,96,124,101,109,112,109,115,126,112,133,116,115,117,125,120,132,118,107,108,110,111,116,108,100,109,104,115,105,97,125,111,122,115,108,104,104,100,101,98,105,97,115,112,115,119,108,141,131,114,156,120,114,114,122,104,121,132,114,116,124,113,100,99,151,149,96,106,103,114,117,123,115,120,108,106,77,109,76,112,111,94,96,97,111,130,101,143,112,120,135,127,105,101,130,110,109,120,108,111,102,87,110,85,95,100,107,75,101,86,108,85,68,122,102,92,105,92,92,82,102,91,98,131,133,128,105,119,119,105,96,98,73,74,72,74,93,47,65,57,65,86,87,75,84,55,51,68,76,50,49,63,52,62,69,59,67,34,45,66,66,57,59,50,58,93,29,69,47,41,79,55,70,68,42,62,70,42,56,44,41,44,41,53,44,49,24,83,49,36,47,53,55,50,52,35,42,57,34,24,39,9,32,45,41,29,35,38,63,28,38,26,42,49,27,40,42,39,36,36,23,62,37,38,34,60,47,59,32,28,49,59,28,23,51,26,35,36,35,35,30,46,40,52,43,47,51,39,66,50,8,59,39,38,35,64,52,48,42,76,44,36,44,46,40,43,25,35,37,67,37,51,52,39,59,81,46,55,67,67,55,40,70,64,42,69,79,51,55,75,41,71,87,71,87,58,46,56,68,39,70,61,59,50,60,60,41,50,33,65,47,48,25,44,47,27,45,34,56,60,72,60,27,32,71,68,77,75,82,94,110,122,88,155,157,148,184,178,213,227,255,255,252,255,248,247,255,252,224,254,238,255,236,255,245,233,232,246,228,111,115,26,0,15,7,19,45,33,42,24,26,23,31,51,68,33,38,32,27,25,19,47,44,38,48,38,41,25,44,39,17,22,40,39,20,23,49,38,12,21,13,26,48,19,41,73,60,69,52,44,58,68,57,74,46,56,64,39,64,53,91,106,100,109,145,117,140,154,133,134,133,142,126,142,119,137,133,121,121,133,163,107,146,143,155,150,117,149,169,158,165,145,125,135,146,141,147,135,151,152,170,168,171,143,146,137,160,153,138,160,146,182,161,168,165,161,146,138,157,127,150,175,160,172,170,142,186,146,166,151,148,156,174,135,157,147,151,138,135,165,170,195,174,175,150,124,127,107,77,134,142,162,191,177,191,179,158,142,157,156,159,145,160,165,176,179,160,173,126,169,174,181,163,149,152,132,14,0,28,16,12,7,36,34,11,0,12,12,8,18,14,32,6,10,16,30,20,32,1,5,107,108,79,49,88,62,15,5,35,39,10,37,29,17,24,19,42,7,42,20,39,22,29,25,33,46,14,22,28,44,12,5,5,4,29,29,7,31,22,8,22,21,27,25,9,35,24,29,28,17,6,14,9,16,12,4,28,21,16,7,24,15,22,29,14,27,65,46,30,31,36,40,19,58,34,17,48,60,59,50,32,47,20,40,34,43,16,59,33,30,57,14,11,37,36,24,25,27,38,38,51,29,15,39,32,23,31,48,51,35,55,50,43,40,31,53,33,47,62,39,35,58,62,59,66,79,89,90,110,126,124,96,100,146,115,110,136,117,152,138,116,106,130,132,143,106,111,114,117,119,131,123,119,115,123,112,115,102,128,120,114,131,113,132,90,115,121,110,121,106,128,115,124,121,127,149,119,120,120,127,108,124,102,108,118,134,126,97,128,109,113,133,117,138,137,140,116,113,112,128,126,118,113,124,135,125,111,106,130,99,119,97,140,86,142,139,129,135,100,120,132,118,157,123,122,149,115,124,117,118,145,150,135,141,133,135,154,111,121,124,121,115,100,122,128,95,120,125,129,121,82,94,106,84,124,148,124,120,123,116,157,142,124,109,116,121,118,107,116,116,107,100,91,116,89,92,117,86,93,92,77,76,80,89,78,79,97,99,105,108,74,85,82,70,108,93,58,59,64,65,55,61,46,74,95,76,51,71,51,45,59,49,76,65,43,48,49,41,26,47,63,74,71,38,62,49,64,44,64,59,36,51,70,47,59,42,63,55,43,44,75,41,66,36,47,62,51,32,48,42,47,67,48,42,53,39,37,12,18,36,5,53,34,40,62,41,36,40,48,54,24,39,40,36,29,55,58,46,29,74,58,42,37,56,25,22,53,45,43,31,31,44,17,65,51,57,42,50,59,28,33,46,50,60,35,60,37,26,50,35,54,51,46,33,71,44,47,38,47,38,33,77,45,36,17,65,45,50,41,59,31,62,61,79,40,41,61,54,50,80,15,42,58,70,33,86,39,47,93,62,53,61,61,72,91,67,60,66,53,66,58,84,72,51,72,64,23,59,79,76,84,73,59,55,54,56,31,75,18,56,54,58,51,43,74,34,44,39,47,68,44,56,48,54,49,50,63,73,103,104,135,156,151,203,182,160,186,209,203,247,255,255,254,249,245,241,252,242,217,228,234,232,173,94,11,1,12,18,33,2,18,12,21,29,34,49,53,27,54,35,25,40,56,38,44,54,47,34,15,40,21,42,44,13,28,35,34,31,39,31,46,23,37,37,50,41,30,43,47,35,54,41,46,51,42,68,50,55,42,66,67,58,92,68,114,130,173,173,138,142,146,150,132,125,130,129,139,148,162,147,145,151,160,136,156,157,154,145,155,132,165,134,152,133,148,156,156,157,137,155,147,140,121,138,148,155,167,150,148,157,142,149,151,157,155,130,148,188,150,146,164,161,146,155,140,154,183,168,175,160,165,175,139,150,170,138,159,157,150,181,145,158,157,166,172,155,142,111,99,66,113,143,142,162,174,143,155,165,132,149,156,144,156,160,133,156,151,138,153,145,160,140,127,139,163,111,26,3,9,5,9,10,12,22,21,18,14,5,32,12,24,0,0,11,29,11,15,19,24,18,64,34,32,51,39,12,26,29,19,60,37,16,48,8,16,24,25,34,38,32,17,29,18,19,30,3,23,2,11,25,15,20,10,31,5,33,11,4,12,27,29,36,25,19,19,28,2,43,40,36,35,27,3,26,38,12,15,16,31,8,22,16,11,17,19,45,24,26,10,48,35,32,52,43,49,18,21,31,13,34,9,43,61,18,45,45,43,46,39,52,55,38,33,28,58,51,41,49,28,33,38,26,31,38,34,44,48,17,36,26,16,42,20,15,23,17,41,55,53,48,48,47,43,69,67,39,85,74,110,110,115,119,121,98,120,132,126,105,124,106,107,104,130,108,113,112,124,139,95,115,123,114,124,109,109,101,116,124,119,123,138,134,110,125,148,122,91,139,117,115,121,124,131,141,124,143,123,97,117,152,126,105,139,107,121,118,117,122,122,118,126,137,96,137,123,114,110,128,129,136,120,132,119,145,106,121,117,92,120,114,128,103,121,121,129,121,115,125,127,108,102,112,137,133,122,122,132,128,113,143,150,123,154,145,101,140,119,138,137,121,116,118,148,153,127,118,119,147,102,125,124,138,115,95,115,101,103,106,111,94,98,127,130,131,120,106,113,94,111,89,93,84,110,99,74,78,100,112,79,90,64,68,61,68,78,104,66,105,81,95,95,67,61,102,90,67,83,62,75,59,43,85,42,34,59,60,44,86,59,79,52,60,44,56,66,53,50,68,83,42,59,62,49,71,66,61,59,56,78,50,56,56,53,56,34,59,67,65,41,60,52,71,61,54,21,48,37,56,54,54,83,26,38,30,30,34,51,26,47,41,14,48,51,33,30,43,45,25,53,40,13,33,48,25,17,50,56,55,43,48,46,50,34,32,37,56,60,30,51,73,25,72,55,20,58,34,44,87,75,66,48,24,29,47,35,55,25,44,45,29,56,37,59,52,59,9,28,34,69,45,37,29,40,37,47,60,48,33,48,35,39,35,23,37,62,18,34,24,30,43,40,49,36,37,61,33,53,41,35,42,39,52,54,50,28,78,33,59,52,46,37,64,58,42,44,75,83,71,68,80,34,71,71,71,66,64,71,77,73,71,87,84,86,81,58,79,45,51,69,97,73,59,84,82,56,51,81,23,64,44,39,43,65,88,93,35,58,104,149,175,227,249,226,240,222,249,251,255,226,245,252,246,242,247,190,130,59,11,12,11,17,28,16,34,7,35,24,17,39,37,36,43,39,36,63,20,46,50,45,23,59,30,39,55,26,50,22,27,45,25,52,40,29,42,31,23,50,47,60,38,30,54,61,37,49,43,47,41,54,82,68,51,76,77,76,78,131,124,130,137,132,149,126,118,159,141,163,157,179,180,173,156,173,165,165,168,178,144,150,136,169,169,153,170,146,163,154,163,147,114,142,170,129,159,145,153,185,158,174,148,133,177,178,161,148,169,160,161,168,153,138,161,153,169,153,152,143,186,164,162,171,157,145,166,180,167,154,144,157,145,175,162,149,166,164,173,158,139,139,78,78,108,144,159,174,193,161,171,152,152,169,154,169,170,157,167,164,178,140,156,168,169,172,176,160,108,34,0,26,19,8,3,10,5,27,13,33,41,18,9,9,29,30,20,25,13,16,13,14,54,44,40,31,34,35,28,35,26,17,29,37,29,43,2,40,27,9,13,33,26,20,9,30,25,46,25,21,20,8,15,25,7,9,10,22,5,17,20,6,19,8,30,17,12,21,26,16,12,9,26,13,14,7,32,23,14,18,1,45,13,22,11,33,40,19,24,36,49,26,24,18,48,36,17,36,13,2,27,43,29,29,4,24,32,23,9,42,30,19,17,53,19,39,20,26,43,29,25,37,33,27,62,30,45,13,42,44,38,27,24,32,39,26,18,36,34,72,35,24,65,30,39,33,63,47,72,62,50,68,78,116,112,92,103,94,116,110,96,128,117,109,119,113,111,107,115,143,126,127,104,97,111,115,124,108,125,142,134,114,106,126,126,112,120,127,124,133,107,132,122,123,125,138,101,128,126,138,116,134,119,107,105,118,104,128,112,133,90,115,107,113,82,84,115,77,110,121,134,138,131,118,124,131,166,122,108,126,115,117,106,100,106,124,92,135,131,110,112,93,122,124,123,121,110,127,132,100,126,115,113,131,122,126,117,117,141,107,103,96,110,135,144,135,131,108,104,126,135,110,122,98,141,118,90,125,112,98,102,86,115,126,120,127,111,107,86,134,103,96,87,54,93,91,89,97,81,86,100,83,92,102,77,91,66,97,91,106,91,106,101,78,60,49,39,46,63,82,51,43,30,56,58,24,43,52,46,17,45,44,71,42,66,77,60,71,52,39,69,47,76,49,58,71,56,47,73,52,43,57,47,53,43,72,45,64,55,48,54,59,61,67,71,41,42,73,70,59,58,59,58,42,71,29,63,56,53,41,56,34,51,35,63,41,79,30,80,54,46,59,60,54,70,30,18,54,50,27,31,44,68,51,49,14,36,36,30,26,39,38,38,62,33,36,30,52,46,46,60,40,38,53,17,32,42,30,11,45,44,50,45,47,31,24,8,64,30,78,42,30,30,74,44,34,47,41,32,23,53,44,55,38,26,41,37,39,20,39,49,61,46,65,25,34,41,21,40,40,49,39,56,38,31,51,45,66,55,61,50,51,18,17,46,39,46,40,40,56,35,56,67,72,51,74,73,68,60,69,31,91,75,96,72,60,77,77,81,95,95,105,106,143,113,135,114,151,153,141,145,137,97,103,107,89,118,82,9,20,64,92,130,130,163,190,175,181,253,253,249,246,244,244,249,249,249,248,246,220,228,199,185,196,220,192,190,163,205,165,48,23,36,36,44,25,37,30,30,14,64,25,47,35,38,42,13,37,52,17,14,35,30,22,44,23,19,49,25,18,29,41,54,55,38,54,54,39,62,66,79,67,80,97,59,94,100,72,107,96,113,122,119,122,123,118,116,146,152,175,166,165,172,186,159,153,186,166,153,149,156,158,162,146,180,158,147,148,154,156,174,160,139,147,155,150,157,156,167,161,209,181,164,165,155,152,148,163,159,151,173,154,151,155,174,167,153,168,155,159,153,180,163,138,155,154,164,150,170,155,151,144,172,152,175,152,167,163,173,160,173,175,134,105,88,106,128,155,157,170,160,140,136,166,181,179,163,163,159,161,186,149,157,168,166,176,151,168,111,3,36,5,10,19,22,18,6,14,12,9,11,24,20,28,3,9,16,10,17,16,12,16,32,29,19,3,53,50,21,25,30,10,25,33,36,10,35,17,28,29,14,21,19,33,11,13,17,33,12,42,33,23,30,51,35,12,15,6,14,50,19,25,6,34,19,41,44,19,4,21,59,10,12,27,32,1,2,13,25,20,5,34,19,3,51,26,10,26,30,30,25,27,24,26,27,19,32,39,22,37,42,30,33,57,37,36,49,17,35,25,56,19,38,16,24,22,33,42,34,53,24,33,56,28,40,15,35,47,54,42,39,41,30,42,39,17,42,24,45,63,57,74,49,75,66,71,75,60,72,99,93,87,93,135,99,109,95,127,112,121,114,84,88,97,92,121,111,116,135,127,103,110,110,108,140,109,117,125,117,119,117,132,121,112,139,111,111,109,88,101,78,116,118,91,95,99,91,105,136,119,110,144,115,101,117,112,120,126,115,113,106,93,90,96,118,101,109,109,94,108,146,119,123,115,124,122,122,117,123,114,126,131,131,114,127,137,99,89,116,110,105,130,116,117,109,129,114,123,133,142,103,111,120,128,112,128,133,133,119,81,122,102,117,129,127,115,115,99,110,114,135,130,112,112,108,103,102,124,124,124,135,134,107,149,123,153,102,92,118,94,76,76,126,144,121,136,111,113,114,112,112,96,97,144,78,86,67,53,108,82,107,85,91,100,75,57,36,56,90,78,91,66,29,48,66,64,40,52,42,77,62,63,30,73,44,76,49,60,52,77,35,57,79,65,53,29,61,43,58,53,47,45,40,76,50,55,53,84,86,72,54,52,77,43,62,66,38,78,38,69,54,77,34,37,42,51,48,26,62,32,63,47,44,33,77,60,31,44,24,35,63,43,44,29,31,37,21,38,45,40,66,43,46,38,21,60,46,56,41,26,43,35,56,45,52,53,75,64,54,47,44,26,49,41,31,50,44,19,52,44,12,59,36,23,40,27,34,53,16,39,32,32,40,26,42,56,22,70,36,35,68,56,48,38,28,22,61,46,22,40,52,46,36,36,56,34,32,44,37,19,40,37,55,34,39,34,59,39,42,50,32,37,27,10,21,45,65,16,53,52,23,22,49,40,54,56,82,64,52,63,64,62,75,44,42,64,78,96,76,82,85,101,132,116,113,135,140,157,148,134,157,117,160,191,173,180,136,139,114,128,121,132,101,93,105,145,82,113,213,241,251,246,245,242,241,246,252,236,248,252,243,245,246,254,247,249,234,248,243,217,61,33,35,22,42,32,24,7,29,32,21,37,36,35,10,32,15,16,27,13,19,37,18,34,42,25,29,13,53,23,22,18,40,50,69,46,70,66,68,45,55,46,71,92,66,119,109,122,109,133,121,95,127,109,112,122,129,122,169,119,143,118,144,154,153,165,125,161,178,172,169,166,160,169,136,154,157,158,141,153,148,188,154,181,141,147,118,156,154,158,191,203,189,173,146,182,162,147,170,161,163,175,167,154,165,169,160,153,186,152,151,163,160,159,168,153,131,163,184,165,143,160,147,182,138,155,157,136,172,138,164,151,185,128,123,70,88,138,151,170,170,161,129,140,159,152,157,162,159,151,180,162,163,154,164,161,147,148,107,17,6,3,21,23,10,17,0,2,7,29,22,42,20,10,15,9,26,22,31,8,0,15,8,15,28,21,31,32,41,10,21,17,39,12,29,21,13,35,50,32,32,12,24,9,11,30,10,9,17,14,13,26,6,29,21,18,14,11,24,17,12,14,30,2,24,25,40,26,1,20,18,7,5,17,29,27,27,19,33,32,24,13,12,45,40,13,27,3,12,4,33,27,24,34,19,34,36,49,30,32,32,56,49,21,18,54,60,24,40,36,32,69,43,48,15,26,40,26,38,51,56,39,32,39,14,24,71,48,49,52,65,39,47,44,53,55,64,42,43,57,52,48,74,47,85,113,88,98,102,99,98,86,85,95,105,130,112,128,115,106,106,123,99,116,129,114,117,117,124,119,131,94,111,119,107,117,116,103,118,121,151,113,111,127,95,126,121,84,111,109,114,132,104,81,112,106,145,132,134,129,114,106,114,116,93,120,116,142,122,97,101,142,124,134,127,120,138,107,94,108,101,120,129,131,104,121,119,99,125,118,148,144,112,122,139,150,131,125,128,112,114,113,146,123,117,110,136,136,112,124,116,116,146,147,137,145,124,117,119,108,125,117,130,126,138,124,108,117,114,106,109,131,123,83,80,112,110,121,109,127,110,101,96,125,116,108,105,102,120,99,108,130,119,116,138,136,111,106,123,115,108,109,132,120,117,115,74,77,85,90,72,62,59,85,82,110,108,90,109,115,90,81,73,50,57,75,65,95,77,69,65,56,42,85,72,67,48,80,76,56,68,37,60,67,62,53,75,76,55,47,75,51,55,69,66,69,61,57,61,39,23,64,64,56,57,62,55,60,48,44,40,65,68,51,62,67,37,36,49,41,52,44,70,44,37,45,85,32,31,77,31,20,25,37,50,32,72,32,27,56,55,48,28,41,57,40,39,37,16,40,44,54,50,49,27,57,52,29,22,42,38,27,25,47,41,55,54,63,38,42,32,36,34,27,49,59,36,50,40,57,68,76,28,16,55,41,19,36,35,25,50,55,33,46,4,22,22,12,54,57,43,11,6,62,45,27,22,54,41,49,29,63,27,46,34,33,34,28,34,50,45,54,8,47,49,32,43,37,45,66,26,60,43,62,65,60,73,58,55,48,36,44,50,57,30,71,67,65,89,74,92,100,97,115,120,120,122,98,111,127,128,131,140,183,125,175,177,147,140,135,224,197,163,128,108,117,66,70,149,136,181,225,250,254,255,255,254,250,255,229,255,248,231,250,244,242,253,242,227,212,43,15,27,5,12,19,20,27,34,34,21,19,28,9,9,23,24,27,25,42,32,22,15,7,33,15,22,12,44,26,50,25,29,33,20,32,67,54,31,44,62,55,65,91,65,43,79,113,138,102,127,104,120,153,135,142,147,131,131,161,134,149,140,125,134,169,147,155,157,178,170,166,180,173,180,134,149,151,151,151,156,187,152,157,174,155,140,152,124,145,159,170,154,145,158,152,112,168,131,163,153,138,157,163,161,135,165,160,130,149,163,154,143,139,178,149,155,165,161,161,161,168,169,153,159,149,144,127,172,167,151,177,177,148,132,105,74,83,80,161,168,180,153,175,165,177,138,166,168,129,141,147,171,151,152,164,162,163,112,20,1,7,12,26,18,20,13,21,18,24,3,1,2,20,14,7,6,6,7,15,39,39,9,50,0,18,17,20,29,5,29,33,44,5,19,27,31,27,21,36,38,31,10,20,37,45,16,16,25,17,16,6,37,11,20,11,16,38,25,25,2,9,13,6,12,30,9,18,28,13,40,36,0,16,5,12,18,22,35,24,24,34,29,24,29,16,25,11,29,12,14,38,24,52,11,29,40,21,38,9,15,33,39,52,26,11,40,9,24,46,46,20,57,51,21,23,13,15,48,40,66,40,68,36,31,38,52,66,14,31,41,42,41,46,47,69,43,56,39,43,42,44,48,63,60,78,109,103,104,88,83,103,99,112,125,96,129,124,110,115,124,110,148,129,126,119,120,129,113,85,141,126,114,113,136,119,120,118,146,140,97,124,120,118,122,126,115,153,135,115,96,128,144,103,134,127,114,132,123,131,141,129,95,114,149,114,98,101,110,109,109,113,116,134,126,113,123,136,129,124,105,105,118,103,112,109,116,146,130,130,92,126,125,120,125,107,128,126,124,107,138,121,139,135,98,110,140,119,144,135,132,141,87,130,125,126,140,145,93,126,148,123,124,104,142,98,126,121,122,120,98,118,130,99,119,90,103,101,94,132,114,104,118,113,95,94,92,103,84,127,108,121,63,90,96,109,134,87,110,70,78,109,92,110,90,104,116,116,112,60,72,100,81,90,105,104,106,85,103,80,117,109,96,109,89,90,93,101,74,98,91,73,70,60,57,75,62,75,57,56,40,58,29,79,46,35,68,51,65,62,59,66,58,52,60,47,65,83,36,35,40,60,52,59,58,25,51,74,64,74,66,66,54,60,36,53,40,37,54,39,41,42,54,36,59,46,43,46,51,40,21,68,68,49,38,40,84,47,51,45,60,49,42,61,44,68,52,61,62,34,50,49,98,48,52,80,30,39,48,32,18,50,49,55,54,22,67,27,69,41,36,68,60,61,61,47,49,41,41,42,40,46,50,38,52,49,44,45,33,39,56,43,13,38,43,45,27,39,44,73,64,13,46,60,66,42,44,47,53,24,59,59,20,19,60,35,30,41,38,53,60,30,43,29,46,58,27,11,41,36,55,18,47,42,41,58,33,30,74,60,38,68,60,53,51,65,54,45,66,45,51,65,76,85,73,59,55,74,69,105,95,92,107,114,123,162,147,104,120,144,172,164,156,157,205,137,87,111,116,115,89,115,153,190,195,237,251,255,252,243,250,253,237,253,221,250,255,252,249,221,37,1,17,26,17,45,53,35,12,57,15,42,38,27,42,28,28,30,35,3,64,32,34,27,28,19,32,28,20,21,30,44,35,15,11,39,26,31,64,62,34,45,57,52,53,48,62,75,68,117,114,147,148,152,149,91,107,132,181,162,145,122,145,137,168,131,152,136,140,175,141,176,124,148,161,158,161,167,156,161,157,151,144,142,150,166,161,161,146,155,166,202,141,141,159,176,139,143,147,144,136,124,164,144,152,150,142,153,147,144,153,172,125,150,166,168,156,162,135,147,154,160,124,164,162,170,145,142,143,148,158,157,156,129,148,142,125,76,75,103,129,143,174,144,158,135,113,145,155,154,171,167,159,166,167,164,171,147,140,27,8,14,8,12,37,21,17,16,12,33,20,1,20,13,28,29,17,15,33,46,19,6,16,13,26,23,22,25,15,21,41,26,36,31,38,22,14,33,18,21,16,18,4,20,36,8,14,9,39,57,32,30,7,25,34,31,7,8,10,8,20,13,23,6,26,20,16,21,31,25,40,11,20,35,9,37,29,16,5,21,24,25,25,23,12,3,3,38,8,9,17,41,3,21,23,45,20,28,36,29,15,39,3,22,13,32,44,20,17,47,51,21,43,38,23,22,22,43,21,16,35,43,37,18,41,27,38,65,18,26,41,23,46,9,31,47,57,38,38,22,25,53,44,46,53,74,68,91,117,118,87,100,124,124,129,103,112,97,123,106,135,148,112,124,137,129,132,117,127,123,126,136,133,120,140,131,114,138,113,143,114,126,94,131,138,129,114,146,129,121,94,116,130,141,138,125,126,139,123,90,119,108,103,140,120,154,108,137,126,149,110,113,157,136,100,141,137,145,129,137,144,144,116,120,149,118,111,128,126,153,138,152,134,115,110,116,125,146,109,131,134,138,131,120,132,131,129,147,102,157,121,120,134,118,148,142,121,111,133,127,146,154,115,139,131,122,104,134,135,108,127,118,110,118,142,96,116,112,105,131,116,113,116,117,95,100,129,111,128,100,105,66,115,123,76,130,81,85,76,80,107,68,97,103,97,124,110,148,89,85,89,110,94,95,126,105,79,95,105,96,92,117,120,121,126,149,112,96,90,103,122,110,89,109,82,79,55,46,52,51,57,45,75,66,64,61,88,35,44,61,60,65,52,70,31,68,53,53,26,68,50,53,76,54,44,47,48,21,49,22,78,45,38,68,47,52,71,48,58,65,34,38,68,51,42,59,38,52,81,70,70,72,41,73,61,38,36,49,64,44,31,65,57,51,44,54,44,35,54,48,20,38,58,19,35,55,56,40,42,69,30,14,41,26,59,55,54,58,32,42,30,39,66,40,16,37,41,27,32,60,54,58,21,45,38,22,43,31,49,50,47,48,31,29,30,29,65,40,36,38,35,34,50,56,41,45,50,44,46,54,23,7,33,34,49,19,38,25,46,34,37,16,49,47,45,40,53,58,2,40,58,30,8,39,34,47,40,58,70,49,53,44,29,53,64,65,71,30,70,45,58,70,53,58,40,52,62,55,84,90,109,77,74,85,86,101,99,100,103,110,136,123,155,183,180,179,124,131,144,155,154,72,78,83,114,107,166,189,210,178,197,213,215,206,212,215,196,227,235,175,12,21,12,32,15,34,29,49,21,20,46,8,43,34,21,30,27,36,29,23,12,25,24,24,14,43,39,32,42,25,37,20,41,40,6,39,39,39,54,42,47,61,73,59,58,73,48,69,64,95,126,140,117,132,109,108,122,131,177,186,175,149,163,150,155,163,135,119,126,156,161,150,156,139,176,158,163,190,158,156,160,141,146,140,176,153,147,169,144,171,134,174,164,151,160,151,116,117,151,136,172,165,120,156,155,164,114,130,153,133,155,158,159,146,152,131,141,154,139,143,180,170,160,167,158,161,156,150,134,134,185,186,165,145,168,171,137,136,115,98,102,147,143,182,160,166,167,147,158,166,159,174,130,192,140,165,169,170,112,1,16,11,3,4,14,13,18,13,10,7,11,31,4,15,11,28,1,5,1,22,4,20,30,0,31,10,11,5,38,32,24,46,35,38,24,21,33,43,47,7,10,16,19,12,8,44,24,18,15,16,3,23,14,21,6,44,6,29,22,0,20,26,23,2,31,14,13,19,24,4,3,5,18,12,11,11,15,27,34,23,12,25,17,14,12,14,25,22,51,27,3,2,29,27,18,39,13,28,24,24,50,31,17,28,18,35,39,34,51,23,19,35,16,34,33,23,49,24,37,54,42,34,64,28,40,31,24,7,45,23,36,47,41,39,42,24,52,42,46,54,38,35,43,41,69,60,24,53,80,58,60,102,97,100,106,125,93,130,134,111,132,139,128,100,130,128,93,139,120,120,152,142,144,121,112,122,138,149,123,125,139,134,132,128,136,138,125,144,115,135,138,118,138,119,131,125,117,123,116,131,163,136,128,132,92,136,151,123,162,110,129,133,116,110,98,109,124,120,133,155,151,152,135,111,139,147,144,159,124,114,165,123,134,133,151,130,144,118,140,131,113,105,117,141,131,124,123,123,118,123,126,135,131,143,136,155,129,117,158,122,122,138,127,109,146,165,116,135,141,142,111,127,143,113,133,139,138,142,133,99,105,131,130,121,123,111,122,118,120,115,84,121,117,132,142,120,110,114,109,117,92,109,88,102,102,116,100,93,115,77,124,118,95,115,121,123,110,121,110,86,83,82,72,59,73,86,88,89,96,95,121,86,119,81,65,80,68,68,76,56,69,107,79,36,81,24,56,57,44,50,33,66,31,78,55,51,44,75,44,71,64,52,54,44,72,70,47,54,49,59,59,52,42,36,54,70,37,56,54,50,59,50,18,70,63,62,54,29,43,43,54,30,36,64,45,25,37,37,71,47,39,47,59,62,28,32,61,28,63,28,64,26,40,34,45,21,41,45,44,56,36,44,27,50,9,57,33,20,29,58,32,43,43,61,43,47,41,23,29,27,71,24,31,51,35,50,50,26,15,16,50,29,36,53,42,40,50,40,25,34,49,48,34,15,53,48,37,44,10,36,61,41,32,22,41,35,62,19,38,52,41,52,43,29,17,32,53,73,22,39,37,62,51,56,35,29,27,12,48,37,46,16,54,45,39,38,48,26,26,42,31,50,36,53,48,84,42,54,55,95,44,71,51,52,70,59,55,66,80,96,100,116,84,144,170,142,110,143,190,195,166,128,143,94,137,157,98,140,146,145,157,101,99,94,117,85,107,120,183,99,25,34,16,29,19,26,39,20,13,21,31,23,31,20,27,39,26,17,30,6,30,2,18,10,24,4,44,32,16,31,47,33,24,27,25,45,41,48,76,30,58,51,58,45,46,77,75,67,63,104,107,90,77,130,90,102,131,136,137,147,130,175,180,160,151,160,143,147,180,163,160,156,137,133,165,159,154,143,153,157,141,136,175,146,167,155,167,170,160,161,137,170,172,151,138,171,142,148,145,170,191,162,145,150,144,135,115,131,178,155,149,179,169,180,151,137,139,166,147,176,165,152,148,145,182,160,169,162,195,129,162,160,161,152,165,143,166,160,108,99,81,125,120,142,166,177,186,161,176,147,142,149,128,158,177,146,150,187,108,17,1,0,6,29,23,20,11,38,19,8,2,3,0,19,24,4,19,14,31,17,2,3,17,28,8,26,32,28,49,27,35,17,10,14,20,25,30,24,20,17,21,20,32,48,15,12,29,30,13,21,9,5,9,19,12,37,25,11,20,23,26,27,9,51,37,29,25,17,23,15,33,24,12,31,32,21,18,33,41,27,25,39,24,36,48,29,36,22,13,6,21,42,25,23,19,30,24,24,11,15,28,39,8,44,16,21,34,27,31,10,57,25,7,42,31,43,20,21,48,15,19,31,15,36,33,31,34,27,32,25,25,6,31,32,44,18,36,45,44,78,51,35,39,61,63,54,44,45,70,52,71,85,100,100,111,109,134,130,142,119,131,136,126,131,123,113,123,113,123,115,144,153,115,126,129,120,108,137,129,114,121,147,150,131,149,139,112,144,136,129,120,128,128,137,140,125,151,113,141,144,137,118,99,117,121,122,113,117,140,149,107,107,114,93,95,122,124,142,122,94,139,142,123,128,129,107,95,149,149,142,146,152,118,124,119,135,136,136,127,131,131,127,124,111,110,137,153,139,107,150,147,149,158,120,139,108,87,120,124,138,149,124,126,147,141,128,129,167,155,136,132,132,128,112,101,130,116,130,118,110,119,111,117,115,112,109,119,125,111,121,130,109,138,115,138,143,138,113,120,114,115,115,110,124,126,118,107,102,96,71,88,100,63,89,84,96,107,88,89,85,58,43,35,52,62,60,62,72,61,66,59,55,79,75,33,57,60,85,54,106,69,84,77,60,66,55,82,85,63,62,62,53,30,63,57,59,38,52,74,77,74,54,52,47,72,55,61,51,51,38,62,46,68,46,73,56,14,61,78,49,40,52,49,51,52,47,41,58,40,34,67,27,32,50,52,37,33,28,51,43,47,54,37,53,34,69,47,26,45,71,40,47,50,58,46,31,40,22,58,35,41,44,26,58,35,38,22,34,45,39,58,26,38,38,58,37,58,43,56,46,29,22,54,20,20,42,33,49,46,50,66,49,48,39,10,38,56,31,45,17,47,76,28,18,57,7,57,51,49,19,24,61,18,42,34,71,22,51,48,38,43,29,31,24,54,38,23,32,57,44,25,39,43,30,55,26,36,34,48,33,52,33,33,25,49,51,42,40,24,37,56,66,45,53,47,52,62,44,87,58,24,64,58,37,53,52,50,56,58,35,91,97,100,82,135,118,111,105,144,191,223,196,209,189,188,213,214,190,147,128,76,84,71,85,70,74,26,39,79,40,26,30,15,13,32,33,41,8,7,3,22,24,36,41,14,42,10,38,50,25,38,25,4,16,30,35,30,23,35,34,34,48,51,56,33,46,56,38,67,40,35,44,51,70,77,46,55,74,80,51,94,100,79,85,121,98,103,95,108,101,149,170,187,178,173,149,158,142,157,179,166,179,161,154,156,193,150,141,144,142,141,131,155,158,144,144,136,161,165,161,151,157,147,141,163,177,153,148,181,161,145,169,141,170,171,148,168,143,140,173,177,165,138,157,131,146,148,180,183,163,156,144,156,129,176,165,173,166,171,161,155,160,152,154,134,149,176,151,153,111,118,86,65,108,154,158,170,192,182,163,160,138,133,144,141,151,124,148,111,12,0,15,55,30,13,37,16,13,27,11,3,3,1,1,12,39,2,18,7,10,26,18,28,30,13,22,16,28,27,12,12,61,8,26,9,24,22,44,22,19,28,30,24,23,26,19,2,17,16,28,20,30,28,27,23,16,8,37,3,11,9,5,34,5,25,23,28,32,12,31,20,27,23,19,28,20,21,32,23,35,32,14,25,15,25,10,41,37,21,39,14,42,21,50,55,37,25,31,31,35,20,35,7,15,20,17,23,26,31,4,42,17,43,34,43,35,25,14,30,22,34,23,14,41,18,24,31,5,39,44,42,16,28,26,45,34,57,46,44,43,41,59,56,63,57,76,87,70,57,13,38,72,58,95,92,122,120,106,121,101,100,130,101,85,102,144,140,141,126,132,129,127,105,149,125,149,133,163,133,104,152,147,120,101,119,135,94,118,128,109,124,134,136,139,117,122,114,129,108,134,126,110,121,133,113,139,116,126,118,117,146,133,119,115,124,116,124,85,151,124,127,121,109,136,117,115,147,113,127,133,128,131,137,137,163,152,138,139,134,103,101,94,152,125,122,136,134,123,150,121,129,99,108,139,105,123,121,104,84,136,132,122,120,114,139,160,118,100,132,115,107,99,108,124,95,117,127,96,125,131,113,100,126,124,112,107,129,105,109,113,131,126,124,126,142,123,93,138,105,106,121,136,110,124,104,83,119,124,121,93,103,79,83,98,121,80,101,91,47,63,76,90,78,34,77,82,64,69,25,57,43,38,39,78,37,16,42,66,73,65,72,14,59,67,26,68,42,43,62,58,49,57,60,67,81,66,60,68,60,52,72,60,71,64,55,45,61,55,18,45,71,60,57,49,63,61,44,23,83,81,57,56,56,58,47,46,60,54,52,50,47,65,65,56,55,57,24,37,46,56,50,40,53,52,73,37,31,47,70,31,62,58,69,24,40,38,54,36,48,61,29,38,35,25,40,63,50,34,55,60,49,37,38,57,25,57,64,64,47,42,44,36,49,15,50,44,34,39,55,71,23,55,49,69,48,26,35,23,46,11,26,61,51,29,37,51,37,31,36,43,41,42,7,22,52,45,32,33,8,38,67,27,24,35,48,32,54,43,51,28,32,34,15,56,29,11,33,29,37,35,42,44,29,37,22,40,50,28,35,23,14,46,42,40,57,47,51,58,53,49,73,32,50,72,42,65,66,57,59,49,68,89,101,85,126,115,110,107,120,195,190,200,170,176,164,188,171,162,123,107,114,140,140,164,140,138,126,130,101,54,4,32,3,17,15,30,41,23,14,18,38,22,37,37,7,8,15,12,35,2,17,30,18,20,11,18,35,56,29,52,53,61,29,33,42,54,45,33,49,27,76,55,79,83,63,71,63,78,50,102,78,100,104,158,119,133,148,135,123,141,133,161,141,158,137,160,151,128,164,159,154,137,160,157,167,133,129,156,142,197,110,145,180,168,169,166,137,155,160,172,168,142,165,158,178,147,170,162,127,161,180,159,139,166,160,156,173,139,156,170,189,146,166,163,171,142,141,164,139,144,143,151,172,168,148,156,146,143,157,139,159,154,144,150,159,125,159,169,159,149,119,118,112,97,92,133,169,190,166,144,186,176,140,124,142,149,160,166,113,25,4,1,19,5,2,16,5,5,35,7,18,4,7,25,20,14,37,20,3,6,2,15,16,13,29,13,15,15,16,20,18,31,33,17,20,14,23,40,19,11,25,15,32,16,12,31,10,1,14,34,42,6,8,14,24,26,23,31,14,39,15,10,30,7,18,24,15,29,37,10,16,30,21,17,31,19,29,8,16,26,2,32,3,36,18,20,36,33,36,1,5,48,21,51,17,18,33,20,40,18,41,43,56,42,29,37,21,24,22,19,44,4,42,32,29,29,33,7,32,28,27,20,42,10,17,55,34,32,38,48,37,28,30,43,39,47,37,29,37,53,46,53,38,68,66,48,75,45,65,60,60,25,31,62,106,57,91,51,59,87,104,116,110,105,141,127,139,135,133,119,130,149,125,144,142,123,102,101,119,114,105,138,127,133,107,120,123,108,131,128,150,135,136,130,119,132,114,102,125,133,102,152,119,151,139,128,114,123,119,132,147,113,155,127,132,120,135,131,121,109,119,138,134,134,142,118,135,131,149,127,135,117,137,133,139,151,140,137,113,111,146,115,128,128,140,150,105,129,117,129,119,120,140,131,154,157,153,162,129,113,118,129,128,120,146,126,143,154,136,128,111,115,137,140,116,115,132,115,133,122,149,143,105,111,117,101,108,106,115,99,111,112,83,110,99,97,118,115,115,148,144,137,133,130,97,90,119,137,121,128,106,77,100,114,128,101,121,103,111,125,115,118,102,115,89,83,72,92,64,57,77,87,92,111,82,76,88,98,71,80,49,73,50,57,61,60,60,70,48,44,65,45,42,57,52,58,52,97,83,70,37,49,27,47,46,36,19,78,47,43,47,48,67,82,49,35,45,64,32,33,66,40,57,47,41,57,44,43,67,11,52,51,41,48,46,65,41,44,60,45,42,42,59,26,37,54,34,66,31,42,22,73,49,61,59,31,22,42,43,48,45,59,55,56,33,46,62,41,48,49,59,29,49,34,44,34,45,60,24,47,55,40,43,48,41,33,34,51,51,72,42,30,20,41,43,36,23,36,26,44,40,59,46,61,17,30,41,27,25,56,69,21,54,45,14,34,49,33,51,27,25,33,39,63,34,43,40,26,26,35,42,29,30,44,41,39,27,32,63,44,58,46,29,60,64,45,36,30,47,39,78,70,26,47,40,46,81,63,46,66,58,68,40,54,73,67,64,74,63,61,81,108,107,111,68,63,79,88,92,129,162,132,155,127,141,113,87,112,114,129,178,165,182,166,198,203,210,193,145,74,39,24,8,23,3,27,13,38,34,29,33,1,26,23,14,32,12,25,32,42,33,41,59,31,30,22,22,32,43,17,39,45,33,55,32,59,46,67,61,60,83,58,57,53,80,74,63,50,71,98,125,127,121,137,140,151,135,168,152,166,149,151,144,114,121,124,127,111,121,131,148,119,143,107,137,147,148,174,156,164,159,141,159,172,166,132,167,160,167,165,186,158,171,167,147,139,153,156,136,176,152,169,135,166,154,145,144,160,170,150,132,159,158,167,162,158,174,176,158,171,165,183,159,157,147,147,150,147,125,145,152,134,177,134,144,144,142,161,129,183,162,133,122,97,85,102,119,152,180,167,150,173,133,151,135,156,153,147,102,15,3,18,14,13,4,10,25,31,26,12,7,11,22,11,4,9,8,7,5,14,3,16,33,34,7,19,24,36,24,27,31,9,12,32,23,45,12,0,30,21,32,9,12,18,38,30,28,7,22,24,9,15,43,12,15,16,18,9,25,31,9,13,16,11,12,29,24,22,44,13,5,14,28,20,2,19,18,14,13,39,4,10,18,32,34,4,27,28,20,5,34,12,13,43,11,49,54,34,55,38,48,23,44,38,18,48,20,49,29,27,44,30,48,23,49,20,35,25,41,55,8,42,38,41,26,38,45,18,40,51,51,38,25,29,28,69,74,72,52,32,57,60,65,87,65,119,121,72,111,69,70,72,85,104,106,108,110,99,98,106,124,125,107,115,129,117,124,111,102,94,132,146,144,129,126,102,119,136,120,135,129,125,128,121,133,112,122,149,141,137,134,106,140,112,139,152,122,151,131,132,106,142,127,113,141,141,124,139,115,104,116,168,137,145,147,137,165,132,130,158,143,129,141,143,141,171,113,141,110,118,129,114,126,139,134,110,109,143,145,117,121,140,124,131,133,131,125,143,119,136,134,146,147,141,135,150,122,132,115,144,120,120,141,141,152,142,149,122,141,120,145,145,127,173,146,141,150,148,128,171,126,132,127,131,111,129,122,127,123,127,107,84,102,113,85,74,89,92,92,99,109,137,97,105,86,80,85,95,101,102,128,111,93,128,126,81,82,91,132,115,110,127,92,86,98,106,106,85,79,101,81,99,66,95,104,109,78,82,55,107,66,105,72,68,54,83,65,53,37,29,60,55,61,75,80,68,39,44,44,62,70,57,47,37,29,61,45,50,50,61,51,54,39,60,35,66,49,67,57,59,54,29,59,59,23,44,50,76,53,50,49,44,43,46,58,49,42,49,27,40,49,77,47,44,62,40,74,68,30,60,40,54,47,43,35,59,50,71,50,31,57,45,48,50,55,52,43,41,38,32,52,47,78,42,40,52,60,28,46,58,40,56,73,49,58,36,21,44,46,33,39,34,43,68,31,33,27,50,28,36,46,30,43,48,38,33,51,43,36,30,40,16,67,27,48,20,47,58,58,35,56,25,33,30,49,46,50,20,39,62,45,48,60,18,55,37,53,24,34,39,23,39,32,32,36,56,33,47,27,37,28,18,41,42,48,66,34,40,70,65,44,37,63,42,63,43,55,50,47,73,56,49,63,63,80,64,51,66,61,95,78,103,92,84,65,98,102,121,93,117,109,139,149,124,132,148,183,178,164,110,50,40,31,27,42,38,38,23,31,10,46,14,38,34,45,51,25,12,35,26,33,47,18,29,43,55,41,45,17,53,37,32,42,41,62,42,50,57,45,69,61,73,46,60,64,55,67,54,70,120,104,117,126,125,112,119,145,140,105,143,127,152,121,166,142,153,144,168,159,138,155,153,113,141,135,176,148,165,161,135,175,174,172,152,179,164,127,149,171,160,160,155,157,157,193,140,126,161,143,145,180,140,132,161,159,136,138,150,145,168,153,116,131,151,178,169,170,189,137,149,164,154,148,153,150,143,154,157,148,145,125,154,105,141,139,146,128,121,141,156,140,153,128,119,83,103,73,97,139,146,149,156,169,158,148,163,144,147,116,26,4,17,18,23,15,19,5,21,17,8,21,0,16,28,0,19,6,3,7,42,18,12,9,21,12,32,10,39,27,15,31,11,36,27,21,37,28,39,17,30,34,28,38,19,11,43,22,34,22,8,1,21,6,50,6,18,25,20,22,14,24,32,5,20,14,18,22,34,25,17,16,28,40,6,1,33,5,37,44,24,16,23,32,26,18,19,28,14,6,30,53,48,35,27,31,32,48,28,49,49,52,29,40,45,62,29,49,18,25,33,34,36,37,36,44,16,55,44,52,58,34,37,50,35,29,33,15,42,28,25,48,48,67,48,45,46,61,61,28,59,58,42,68,75,80,91,98,86,82,89,105,131,110,115,136,143,152,126,130,116,118,118,115,113,136,108,95,92,93,106,131,128,101,121,107,95,106,104,113,115,130,130,121,139,117,157,146,137,142,155,183,162,116,125,123,125,125,129,107,134,116,135,158,114,112,146,135,123,146,155,133,131,118,126,120,132,149,130,131,137,146,133,136,138,135,121,133,129,144,152,134,125,139,130,143,129,145,153,122,142,127,117,143,151,140,127,152,139,127,153,146,179,127,151,134,126,127,127,115,170,150,151,141,144,136,120,135,134,128,129,124,117,133,114,136,150,159,162,116,161,173,149,120,147,146,127,122,116,141,123,92,93,100,91,115,108,114,83,111,96,75,90,99,83,68,89,86,92,86,93,124,118,129,120,101,82,55,95,22,56,78,83,85,81,99,100,117,84,103,101,89,95,51,63,84,74,54,75,58,55,25,27,61,32,57,22,64,32,52,69,34,85,80,56,63,52,57,66,55,81,83,70,40,71,97,73,48,64,52,61,54,69,63,63,59,52,59,39,51,56,46,49,54,50,52,37,37,69,47,34,50,40,59,50,45,44,35,49,45,66,46,22,49,73,51,70,55,59,62,36,58,55,48,56,40,22,50,50,55,41,50,46,20,34,55,57,37,28,26,53,34,47,50,29,54,49,48,50,50,45,45,39,48,68,36,16,52,26,54,23,25,40,48,41,52,57,45,48,59,44,56,28,57,25,44,33,47,47,29,44,61,53,34,44,57,32,53,54,53,39,55,36,48,61,32,22,40,46,39,46,39,40,60,40,48,29,30,36,24,33,40,28,63,27,49,74,32,50,51,44,46,64,33,62,56,58,34,62,53,31,45,49,43,68,62,70,56,64,54,57,57,56,57,57,61,61,64,61,29,35,78,77,48,49,80,94,115,95,72,70,74,106,130,71,78,65,113,142,152,116,39,13,4,2,25,37,32,26,26,16,24,29,51,9,38,56,49,41,3,9,37,14,25,47,26,48,48,31,64,33,45,31,48,28,59,55,37,64,53,38,56,89,51,58,63,40,45,64,66,82,104,106,105,119,83,92,123,110,128,124,132,124,139,156,192,144,199,173,118,172,162,155,157,148,157,203,166,151,183,173,158,147,145,161,166,156,133,157,156,150,163,143,143,135,154,133,169,147,170,146,164,167,165,136,155,154,138,149,133,137,134,123,141,141,146,152,148,140,156,162,151,152,159,145,134,164,146,146,150,145,138,155,170,155,156,155,138,116,146,146,143,139,146,143,166,107,93,119,119,104,125,152,162,161,145,164,132,156,94,7,11,30,0,5,18,14,9,15,23,8,0,20,28,28,15,23,13,42,19,6,14,21,21,38,28,17,35,28,13,34,19,52,22,38,14,4,22,21,18,23,3,16,11,18,53,33,27,38,22,5,13,36,18,34,23,34,32,25,9,24,22,12,20,35,27,30,13,0,13,40,6,8,29,39,20,3,2,24,36,19,38,23,39,10,22,16,11,21,31,13,14,25,36,62,24,35,35,6,20,18,34,3,29,22,30,34,16,22,28,51,17,39,24,42,8,39,32,65,44,31,47,45,62,31,18,14,32,44,44,27,53,30,61,15,32,51,41,32,48,50,37,51,54,73,78,74,90,65,85,58,69,123,115,124,98,109,118,135,129,159,114,107,136,135,157,129,121,111,127,128,150,135,133,132,117,111,126,138,122,115,124,100,97,131,111,115,133,129,102,119,136,135,119,126,124,118,137,144,130,112,141,126,100,124,125,124,138,137,135,119,119,114,114,112,137,137,116,137,122,113,138,151,125,120,144,136,140,120,126,122,123,130,144,142,148,136,142,127,127,112,140,114,115,142,130,125,134,120,127,141,139,167,152,154,159,141,149,124,158,138,140,142,141,153,118,136,141,127,132,134,139,133,164,146,134,148,158,139,138,155,121,133,95,121,124,137,130,143,107,121,91,92,103,118,123,112,88,86,91,113,99,131,143,103,81,108,112,92,110,106,101,106,127,108,98,119,114,94,94,106,62,105,88,69,91,110,108,77,101,67,86,40,66,82,81,41,31,58,84,71,30,53,56,89,64,71,93,54,48,85,87,76,87,65,90,69,53,71,96,91,66,94,86,68,75,80,83,102,80,59,59,51,47,53,55,70,50,65,78,69,39,41,61,32,47,99,58,62,62,31,48,68,72,41,57,54,50,37,75,57,53,52,43,49,67,69,46,68,54,52,55,32,35,40,68,66,35,29,49,44,55,53,44,83,51,49,47,55,49,8,28,82,33,48,42,47,34,32,52,58,49,50,41,38,35,31,62,22,54,35,40,20,41,42,30,24,40,59,47,8,59,54,41,49,24,12,36,37,36,28,36,42,15,27,42,52,54,41,32,54,25,44,31,58,24,22,36,39,46,16,66,38,46,54,54,22,32,32,11,42,17,20,50,11,34,18,40,36,37,29,30,28,33,49,30,57,68,69,57,54,50,61,76,61,53,54,69,55,39,58,25,54,57,74,45,72,61,74,73,63,69,84,75,61,60,101,98,104,103,105,102,103,87,92,71,58,77,115,116,68,45,30,30,35,33,51,30,13,23,49,29,29,41,16,19,37,41,24,23,22,39,66,22,34,46,24,28,17,15,19,53,47,47,67,41,38,58,29,35,59,45,31,67,35,67,36,57,67,71,82,90,113,124,133,121,126,147,121,129,96,107,130,114,164,158,168,172,162,168,149,130,138,138,142,168,149,144,169,173,170,150,162,159,147,139,160,151,157,160,163,180,185,154,147,150,152,145,155,145,146,183,161,157,152,152,136,159,126,136,158,154,159,147,148,148,156,127,147,139,145,159,146,131,139,141,156,160,154,158,166,144,139,137,147,136,169,128,140,143,151,157,132,114,157,151,148,124,122,104,98,136,127,162,150,148,164,148,152,115,0,3,17,10,35,20,35,1,29,23,3,6,16,1,27,11,19,13,37,28,0,4,36,22,33,31,30,33,23,9,18,36,27,14,33,25,23,25,54,48,7,26,43,23,31,28,12,18,13,13,12,29,15,17,13,25,18,27,22,41,22,17,24,41,4,32,35,19,32,18,10,4,15,26,46,29,18,6,49,25,36,12,11,23,28,33,42,18,19,33,36,19,29,30,9,29,21,11,33,30,32,9,11,32,21,34,19,32,40,52,52,51,33,50,32,52,53,33,23,17,29,63,26,37,46,64,56,35,64,52,46,22,35,30,48,70,30,43,55,65,54,48,41,79,62,54,58,69,73,102,91,82,95,83,94,84,85,87,99,102,153,159,148,128,102,120,152,148,121,159,136,139,114,142,127,116,145,132,138,142,153,129,141,147,137,123,122,137,129,118,127,121,124,130,141,114,168,131,133,140,162,122,137,147,148,133,129,117,134,104,141,115,130,117,133,144,131,116,122,111,125,132,120,125,110,150,146,146,148,98,130,142,131,144,134,121,142,140,144,148,142,137,143,131,130,153,144,137,130,148,149,143,161,141,133,149,148,158,143,160,151,127,113,114,118,132,155,130,114,135,144,124,137,147,152,122,124,117,124,136,136,127,129,137,116,140,107,137,106,143,171,147,159,136,122,150,114,159,123,130,138,139,143,150,129,144,131,113,133,127,104,116,105,103,74,91,116,83,100,108,117,106,99,111,85,119,82,65,109,97,95,108,96,106,79,86,83,101,80,65,52,61,62,55,94,96,116,89,90,111,95,67,81,86,88,49,69,109,78,80,75,72,78,86,94,67,65,104,98,83,101,76,48,71,68,67,64,56,80,37,63,28,56,42,83,48,69,49,62,46,46,32,65,59,58,48,45,48,34,58,75,42,60,48,72,38,63,46,60,56,30,26,37,15,52,44,44,23,40,36,52,29,54,38,58,53,61,46,48,43,52,44,31,52,64,26,39,62,31,25,49,53,39,55,50,63,51,46,23,59,15,39,52,37,51,42,45,25,50,44,47,32,35,41,53,47,66,50,32,47,36,24,28,50,42,48,45,26,40,26,47,42,38,57,29,33,23,33,38,28,43,44,61,50,45,31,66,35,29,41,24,43,47,48,40,55,60,37,24,42,45,67,20,70,57,41,36,48,44,39,64,51,54,62,55,73,48,54,60,58,65,49,58,44,37,104,50,94,99,94,86,52,105,127,105,85,88,89,97,99,100,68,87,79,88,83,66,65,52,72,70,55,19,2,51,21,20,27,36,4,15,31,27,47,51,40,38,30,27,20,31,30,25,41,42,55,15,38,22,61,17,20,36,31,48,43,29,50,36,35,57,62,65,70,39,56,52,37,60,80,85,73,91,120,125,121,139,147,123,137,150,143,105,135,135,173,148,144,140,171,139,158,175,166,148,164,154,151,140,171,155,152,174,163,173,160,179,147,141,167,165,167,167,143,168,140,160,183,168,153,164,166,157,179,164,170,161,164,178,165,162,165,163,136,140,156,136,158,138,185,188,164,159,143,129,155,143,126,170,128,137,148,149,154,165,168,160,174,138,147,123,155,159,150,129,153,140,148,153,73,68,91,116,120,158,163,189,193,157,114,12,10,11,13,0,14,7,19,31,11,11,5,4,0,15,5,9,0,33,10,12,22,14,24,30,23,15,14,31,33,27,16,22,24,12,20,8,25,9,22,30,39,22,16,19,22,4,24,3,7,30,28,24,50,31,14,36,22,37,17,15,14,36,15,13,30,22,13,30,26,25,35,23,18,30,35,14,14,37,34,9,5,35,15,43,10,12,28,26,48,26,23,4,20,8,45,7,18,46,37,21,20,47,29,10,42,25,51,42,23,23,30,27,10,43,53,47,45,61,31,23,36,30,26,32,43,47,63,58,55,53,41,29,63,59,67,64,37,36,64,30,56,70,49,84,71,84,83,69,66,99,139,102,92,100,77,80,81,81,107,90,121,117,137,126,146,125,107,158,95,124,128,129,115,130,140,125,141,152,175,123,143,138,125,122,95,112,156,96,134,117,140,131,116,107,123,137,138,141,128,157,148,142,158,124,147,134,150,134,127,130,95,136,133,168,169,142,140,143,165,130,126,111,111,143,143,134,148,119,136,139,132,145,145,140,155,139,129,132,160,160,113,141,146,156,137,115,135,134,118,125,135,131,109,119,139,150,137,130,126,115,90,92,82,124,115,122,134,125,114,121,125,116,126,116,116,100,111,165,123,129,114,126,126,145,126,98,105,129,113,140,152,141,151,117,108,137,111,125,116,116,124,155,110,120,131,110,150,93,77,90,114,81,72,80,73,48,87,94,93,72,115,73,100,75,76,115,74,123,90,103,115,135,89,50,73,90,58,106,74,72,57,48,77,61,102,90,80,56,87,94,28,69,44,57,62,42,61,63,50,61,56,68,66,84,69,70,80,75,82,39,66,73,61,76,72,81,58,45,65,93,75,48,55,31,47,33,50,43,45,73,68,46,30,74,62,49,48,33,45,53,45,42,67,22,60,46,31,49,56,34,55,51,35,50,58,80,39,42,58,62,45,40,46,13,29,41,36,37,14,54,24,68,49,55,50,39,53,32,45,46,40,36,42,66,41,59,20,31,37,50,59,31,51,32,34,53,36,40,33,38,45,19,37,23,45,21,25,33,22,36,40,53,16,34,48,27,44,29,46,43,47,26,61,22,45,40,40,60,50,26,58,65,62,15,34,31,31,36,47,32,57,29,32,63,43,32,30,40,58,32,42,52,37,58,33,48,31,62,51,30,34,64,53,55,34,46,85,73,48,62,30,58,81,71,61,80,69,87,76,59,55,80,67,77,69,50,78,56,82,71,69,57,66,62,71,51,47,54,69,68,64,51,30,35,30,12,23,8,16,31,52,32,30,40,18,20,41,20,59,29,37,22,44,41,24,59,24,55,32,45,56,46,33,38,57,48,47,52,46,45,54,64,63,82,36,75,57,47,91,70,62,88,84,113,113,84,95,121,143,144,124,133,139,145,123,146,165,135,117,134,138,166,175,150,136,150,144,156,159,130,164,150,151,178,167,136,156,149,116,154,160,139,154,165,136,145,159,147,158,144,154,134,178,153,156,150,170,165,144,128,147,121,134,160,140,171,149,172,143,155,143,169,165,153,195,171,157,132,145,158,148,139,162,135,151,159,158,137,170,153,160,130,148,152,171,165,132,123,105,93,67,77,111,141,170,154,143,160,110,11,15,34,7,21,11,26,5,19,0,21,24,12,5,19,5,13,4,10,23,3,19,9,8,9,39,50,38,23,30,15,16,21,26,27,33,24,28,24,27,14,9,26,43,4,11,22,28,23,17,5,9,23,38,24,33,23,15,16,22,36,0,11,31,11,31,48,10,12,13,13,18,17,42,26,16,14,47,26,4,28,4,34,39,14,31,19,13,19,19,31,22,26,39,48,3,20,20,43,46,46,48,11,9,39,35,27,12,28,38,14,12,22,40,49,58,35,18,62,45,27,42,80,44,60,55,72,73,24,61,46,67,64,38,41,43,37,57,97,57,75,90,95,100,106,100,99,124,64,82,74,120,79,89,98,72,83,71,87,61,121,111,136,120,142,141,143,120,133,124,127,124,140,113,127,135,128,113,140,131,123,100,126,115,124,113,106,128,124,148,122,154,123,114,136,141,122,125,118,100,140,119,131,152,134,129,152,134,136,156,132,117,146,134,146,124,139,133,121,131,121,123,117,150,132,119,114,120,146,113,168,132,139,132,157,142,155,142,144,144,122,124,134,135,117,125,131,134,122,130,112,122,121,137,114,102,133,125,138,118,134,105,137,108,123,128,109,109,121,110,132,140,152,147,137,135,129,98,112,103,111,102,114,89,136,109,105,112,125,124,147,125,123,85,120,103,125,134,105,127,147,136,125,129,132,96,85,95,121,106,83,99,116,80,79,82,97,90,104,72,78,89,86,81,74,77,74,36,65,32,54,78,75,104,65,95,62,60,53,46,52,61,62,63,56,63,69,71,90,55,51,87,70,43,81,65,59,54,52,71,65,49,80,39,51,50,62,45,72,68,63,50,69,49,53,43,48,41,64,59,82,61,50,69,37,66,46,58,71,32,51,43,59,34,67,55,68,65,59,20,35,46,50,48,47,34,29,57,57,55,64,57,53,49,48,61,57,66,32,49,40,62,46,60,47,63,42,49,51,76,56,54,51,41,44,75,37,42,57,64,34,50,32,43,59,35,54,51,59,38,40,60,44,32,34,57,35,48,51,41,64,60,51,54,52,1,58,44,66,38,30,43,36,74,73,48,56,30,38,25,49,37,47,57,38,57,50,58,52,74,44,47,14,10,29,29,33,64,36,37,47,44,42,53,48,30,34,41,34,35,47,32,54,68,34,36,34,32,45,51,65,45,72,71,64,70,68,60,70,54,59,48,40,48,72,74,70,44,64,43,72,69,63,71,89,75,81,55,66,63,56,53,62,42,69,74,62,66,53,62,32,27,37,38,44,28,33,51,44,29,40,26,54,29,24,5,31,34,26,56,52,34,29,22,28,39,7,69,31,32,47,52,60,54,48,54,68,30,58,58,57,38,52,70,66,68,59,52,77,72,95,101,65,51,71,84,90,89,95,116,137,106,125,149,132,149,134,144,153,144,199,155,133,181,151,144,143,150,128,127,129,121,153,132,145,144,126,166,152,153,139,160,161,146,161,167,156,162,170,154,158,145,147,178,150,179,158,153,143,159,157,133,145,138,173,180,141,140,143,155,147,168,164,137,160,170,170,148,153,137,151,153,142,165,149,180,141,145,135,132,144,145,137,140,127,141,121,155,175,137,136,103,89,76,95,129,145,162,163,106,26,0,9,37,16,10,2,12,16,2,14,32,19,5,7,15,13,12,42,12,20,0,3,9,17,30,48,1,28,26,18,7,11,52,36,22,31,9,29,27,7,32,5,11,10,28,13,36,23,23,11,34,30,18,23,11,39,26,2,11,12,17,38,5,15,17,11,11,4,10,9,8,15,27,24,35,35,37,5,37,18,26,2,19,23,19,40,32,12,26,33,39,46,30,24,45,13,49,26,18,25,42,35,27,36,11,33,36,36,35,27,28,5,35,19,57,53,35,28,52,46,39,29,35,65,59,58,72,56,35,54,33,77,49,53,49,35,72,68,74,79,94,66,77,88,96,71,79,80,56,99,80,67,88,64,88,94,110,117,105,108,131,123,118,152,134,126,148,128,131,132,107,126,138,140,101,120,128,119,117,132,125,155,136,104,153,133,130,119,136,164,126,160,144,143,124,101,125,144,113,120,144,143,143,101,111,105,129,124,162,127,133,133,127,134,126,125,87,132,127,131,126,97,134,132,133,133,162,127,134,142,142,135,143,119,131,135,124,144,139,126,130,131,143,129,118,112,152,153,139,112,132,165,135,155,139,115,135,151,150,167,134,134,130,155,121,132,120,127,128,117,125,133,129,156,115,123,134,120,116,121,107,147,134,121,119,130,137,130,130,156,117,128,115,104,129,141,141,122,99,137,115,139,138,144,107,89,125,129,118,123,105,130,153,115,123,154,126,114,84,101,80,97,103,87,59,79,89,63,75,63,95,86,86,83,64,73,83,74,100,100,102,118,97,81,86,96,67,56,102,85,96,54,31,73,61,67,65,81,73,84,56,51,76,52,79,40,53,46,54,56,59,41,78,57,63,29,59,47,66,60,59,51,61,46,58,69,55,45,66,46,49,56,56,77,43,42,74,48,24,24,55,49,46,54,27,55,59,56,32,62,41,52,58,58,40,52,61,42,35,48,61,39,49,26,44,36,45,32,25,69,47,57,16,52,42,44,41,66,46,46,44,34,28,59,52,63,39,42,48,58,51,36,53,49,58,55,66,50,57,26,26,43,58,25,24,52,30,73,21,54,30,52,48,46,57,31,16,48,66,18,48,40,32,41,29,49,56,48,30,26,59,29,44,36,33,39,47,38,58,23,47,54,37,40,24,38,41,78,43,61,15,49,26,43,37,52,40,37,39,33,53,57,62,50,45,47,81,70,48,37,56,52,39,49,51,69,86,46,43,64,79,88,45,86,88,55,95,97,107,108,93,79,58,45,75,59,54,24,75,28,23,45,47,9,24,12,39,31,26,48,20,21,61,46,52,31,35,60,53,52,43,29,19,54,41,36,40,32,42,21,34,33,60,40,52,45,63,38,37,68,59,61,49,62,22,46,53,77,69,88,77,52,56,51,92,82,92,97,125,136,144,132,162,121,132,162,171,151,157,148,171,146,181,173,177,133,156,166,170,186,140,151,149,157,148,150,126,157,115,167,183,162,116,125,148,171,162,157,151,165,148,158,163,131,154,159,134,109,147,169,168,150,166,166,137,144,142,149,174,145,149,139,142,145,138,158,160,158,156,159,139,173,165,161,154,142,146,131,155,144,130,137,160,146,133,136,142,142,148,144,120,78,84,78,106,123,127,164,102,16,18,15,11,12,11,11,18,12,35,20,21,13,4,20,33,15,9,10,20,3,25,11,25,38,32,34,5,48,16,40,18,11,36,11,30,7,41,18,41,30,11,23,15,31,32,25,33,9,29,36,6,10,28,32,38,35,14,6,27,10,19,7,11,6,17,20,14,11,9,14,27,10,18,38,36,12,9,29,17,16,17,44,23,34,44,38,14,41,22,19,36,30,22,64,33,17,33,20,49,34,35,25,26,28,28,12,55,15,9,39,61,3,39,44,29,16,33,51,40,58,24,24,51,45,46,77,34,76,84,71,71,82,84,73,91,73,87,90,76,90,79,95,103,66,90,57,70,55,95,71,82,92,107,135,104,134,126,111,113,132,137,132,132,122,129,118,98,125,132,134,127,110,135,122,117,148,153,167,152,144,170,152,139,152,153,147,147,125,107,156,129,125,133,127,136,141,129,145,134,143,136,162,142,151,134,118,123,147,142,126,141,149,115,124,144,104,137,124,166,149,128,158,159,145,149,153,170,127,120,154,131,127,114,103,142,101,129,134,160,124,146,120,109,147,118,126,87,110,124,137,134,145,108,118,123,137,128,150,149,164,163,133,130,137,146,123,143,146,146,133,128,138,122,144,138,121,104,128,134,124,120,138,125,123,136,143,181,118,116,137,138,123,149,138,130,160,101,110,107,105,113,140,143,138,140,144,170,148,165,147,142,151,129,125,143,151,128,134,112,117,83,132,111,133,105,119,110,98,64,70,104,86,113,86,69,76,70,96,95,121,103,70,93,76,67,53,88,47,86,37,61,75,69,55,85,83,64,35,60,74,80,69,78,44,59,95,51,50,58,65,39,53,42,55,62,56,31,62,38,63,34,61,55,56,64,43,34,64,46,26,60,53,43,59,49,48,23,40,30,36,38,53,43,29,74,48,61,67,35,35,44,44,48,49,29,53,42,52,55,59,53,73,57,42,71,59,45,53,36,43,46,42,67,51,55,47,36,13,54,26,28,46,53,30,30,43,35,37,37,37,43,70,49,42,56,38,31,50,47,28,29,33,36,37,13,35,37,58,46,25,54,56,53,44,36,79,45,36,56,35,39,66,46,75,46,62,40,33,45,34,33,37,40,49,30,59,51,25,31,40,60,55,50,29,41,14,17,50,62,46,65,66,35,37,33,49,43,82,67,38,45,50,29,42,33,46,38,41,38,54,44,43,60,38,46,42,69,52,65,75,72,55,72,87,76,86,93,72,106,113,89,63,58,30,62,41,49,46,74,60,53,52,25,32,39,44,44,25,38,43,38,37,49,30,37,13,29,32,23,35,4,35,26,36,56,40,52,38,32,44,30,40,59,50,47,42,57,47,51,70,35,62,51,44,66,59,86,67,50,52,60,50,55,55,107,105,104,118,126,151,141,155,184,168,121,181,139,181,168,165,144,170,171,168,159,163,169,160,180,152,191,163,178,148,138,166,147,164,191,157,176,168,131,132,155,170,169,182,156,150,156,178,173,160,189,153,176,162,153,148,172,152,159,148,142,145,165,171,150,156,113,123,141,139,157,173,163,149,148,139,181,119,176,140,168,138,181,161,155,166,170,138,140,139,134,120,177,150,162,166,172,159,121,75,81,114,82,126,119,38,19,14,16,7,23,23,2,25,44,13,20,27,12,4,31,13,14,33,7,16,15,41,25,4,9,46,29,33,14,14,18,49,34,24,34,19,22,32,18,5,16,21,14,28,20,9,30,5,11,31,14,22,35,17,31,11,16,17,4,8,26,18,22,47,24,16,15,20,9,42,25,30,46,13,7,18,19,34,33,17,10,33,29,31,11,39,43,25,34,25,29,17,30,20,5,22,36,30,38,45,64,45,33,33,28,33,33,48,30,51,66,27,35,40,29,44,54,55,48,50,29,50,24,56,45,73,67,94,103,93,99,107,122,88,112,71,101,76,81,71,57,115,68,133,94,96,84,104,123,115,118,137,138,109,116,121,132,138,131,109,138,127,102,130,107,118,128,93,134,128,137,121,114,126,117,157,167,126,154,137,143,123,137,116,117,129,125,136,140,132,132,119,146,131,164,128,133,141,137,137,125,161,161,159,162,167,148,155,139,141,138,144,140,140,141,142,158,157,123,162,152,155,157,169,151,137,132,145,137,129,157,122,146,114,113,109,96,123,115,122,131,140,157,129,113,137,103,158,110,138,150,149,118,142,150,142,147,137,155,140,155,128,141,153,148,129,148,141,126,152,165,147,159,133,114,148,131,148,159,131,112,118,127,99,156,134,126,131,112,105,101,140,130,131,116,148,127,125,114,154,155,137,115,106,139,153,159,114,118,132,113,107,140,135,85,88,118,125,79,88,98,66,62,79,114,93,69,112,99,59,56,92,59,74,94,82,89,79,76,49,72,61,28,50,43,46,60,51,65,49,63,44,51,84,68,60,66,58,57,60,71,64,71,65,72,73,44,65,74,80,71,57,55,66,61,19,64,70,87,50,51,54,65,22,50,28,64,65,44,49,56,32,39,57,43,20,55,33,45,50,47,46,91,50,28,62,67,68,67,39,32,49,47,56,34,38,52,87,22,50,57,47,29,50,33,38,51,46,38,63,43,55,42,41,48,42,58,32,43,52,57,36,57,52,67,50,36,34,38,24,49,41,56,42,49,45,35,46,34,46,46,31,26,46,55,53,47,43,20,33,52,60,55,29,51,21,41,74,52,59,39,33,56,63,54,59,56,13,36,44,19,37,31,22,39,43,12,62,12,16,51,46,28,29,29,37,40,47,48,52,41,52,46,43,40,44,44,39,38,57,34,46,34,33,33,49,50,68,46,37,69,39,62,58,67,57,71,60,60,52,67,70,69,75,76,59,100,32,76,42,78,58,67,81,48,52,63,35,54,39,57,34,51,49,18,25,42,55,45,31,45,33,24,14,7,60,50,28,32,51,31,39,45,17,46,32,24,23,82,40,19,25,41,61,8,29,32,62,32,53,68,51,48,67,60,43,63,40,41,77,32,51,44,53,69,83,70,88,124,149,135,154,173,150,145,140,144,173,168,162,140,165,185,187,164,159,167,170,190,185,176,166,155,153,153,160,148,143,177,165,156,168,144,149,140,157,158,157,152,161,154,135,145,186,141,176,145,140,153,130,172,164,156,160,160,164,163,143,153,166,122,151,152,130,137,147,156,148,140,143,159,141,129,137,157,152,163,158,163,164,154,153,159,126,158,122,124,160,111,149,168,168,132,117,79,99,102,119,103,29,14,17,13,35,12,1,35,18,15,13,2,20,20,19,0,1,17,9,7,19,13,3,22,26,36,33,22,35,15,28,19,24,26,32,29,51,24,23,37,12,28,6,13,15,6,31,32,35,15,9,15,23,8,21,20,26,45,20,18,56,48,19,18,13,24,20,36,25,2,12,20,46,46,34,20,23,37,7,27,21,33,33,39,32,39,5,28,45,26,16,21,12,19,36,44,41,38,30,33,7,42,25,51,36,38,31,13,58,19,11,23,23,44,43,53,50,52,50,31,39,75,39,52,50,58,55,80,71,72,71,79,86,80,65,97,73,74,84,48,62,34,62,98,91,94,98,143,105,95,120,157,138,141,115,143,128,125,124,124,138,128,116,141,148,123,134,145,151,136,108,154,126,149,156,164,130,112,135,130,127,105,104,142,109,113,122,128,141,126,130,135,119,141,114,111,132,141,140,139,127,133,162,134,138,122,152,132,157,147,150,138,122,136,109,156,137,138,122,154,154,148,152,155,168,153,125,130,142,94,109,126,134,135,133,133,114,147,120,150,130,160,136,110,163,161,139,159,159,132,135,131,155,166,158,150,125,107,137,134,137,154,165,110,123,140,131,119,144,147,137,140,159,117,142,137,168,190,161,121,131,114,137,140,136,137,156,157,160,168,130,160,133,101,107,102,91,98,140,125,115,108,118,74,94,132,120,104,67,94,122,96,111,99,89,89,74,81,86,93,83,91,70,44,78,91,120,100,114,76,80,89,68,61,85,56,74,80,94,92,74,63,81,60,61,40,53,31,60,59,45,53,47,38,64,90,54,50,45,86,26,72,70,58,43,41,37,71,58,38,85,58,49,79,56,71,51,75,64,56,48,58,54,47,56,49,58,63,66,60,65,65,40,66,43,74,54,46,56,59,47,53,50,33,59,56,47,74,46,56,59,49,64,18,65,55,52,28,59,42,56,54,64,68,48,71,47,24,47,67,44,62,26,57,60,23,69,28,32,43,46,51,31,26,48,16,42,49,34,69,51,47,48,22,26,42,64,29,40,41,47,53,42,47,30,15,38,19,27,54,48,28,26,37,29,45,54,27,41,27,36,36,40,35,13,32,48,24,40,49,39,40,25,68,41,51,27,46,22,51,53,28,55,34,46,43,62,36,54,40,44,45,55,52,37,43,55,46,53,58,61,39,56,31,37,47,39,61,73,62,58,60,43,54,46,54,59,70,73,51,92,70,76,102,106,74,58,42,48,56,55,64,38,68,68,75,40,61,42,37,56,52,65,46,49,29,30,50,56,37,27,50,29,44,44,21,11,40,51,50,26,38,25,50,40,14,53,53,28,52,48,41,42,65,70,47,38,45,54,22,63,70,60,47,27,62,52,46,61,50,89,52,83,77,64,63,62,49,64,91,112,82,108,122,145,137,136,119,161,160,129,128,145,148,175,147,123,160,134,188,166,161,167,169,164,191,151,148,158,141,157,172,145,159,142,124,150,157,160,159,148,145,166,168,136,140,143,114,139,130,168,160,149,181,175,156,168,160,145,163,171,155,164,163,140,160,141,178,160,165,154,170,156,163,138,130,147,153,144,126,163,148,155,147,136,137,143,143,155,156,153,143,173,144,130,122,116,78,93,81,16,21,32,0,0,9,7,26,6,12,17,18,22,6,18,18,7,8,19,6,14,17,23,14,27,31,11,39,48,25,20,15,38,29,23,31,11,51,31,32,13,30,20,18,11,21,13,12,6,24,34,9,43,13,27,18,43,3,29,36,35,20,29,16,26,34,25,29,30,12,28,29,21,25,40,31,20,26,25,39,23,25,11,34,30,22,20,40,49,49,32,11,38,40,17,40,24,30,16,38,52,24,29,40,45,35,35,48,40,48,32,40,22,25,29,34,47,57,47,67,41,32,63,24,40,52,57,47,46,54,48,28,36,40,79,53,85,47,28,55,15,48,54,71,58,90,104,86,109,137,130,118,138,126,139,144,167,164,148,162,141,169,154,149,129,124,138,141,126,124,152,145,158,154,141,138,149,126,134,131,122,98,113,112,141,142,121,135,131,160,161,150,164,167,140,149,140,144,114,141,128,108,124,125,128,109,159,142,123,131,150,131,143,125,151,126,113,130,101,140,141,108,141,141,113,144,141,134,145,171,134,142,143,140,157,134,114,158,147,154,141,141,122,134,132,143,141,167,158,143,138,130,102,124,119,132,139,136,146,151,145,161,134,134,107,115,110,135,135,129,178,120,142,125,114,134,143,163,148,151,162,164,151,144,146,112,156,132,138,118,149,158,130,129,126,101,117,110,113,112,83,112,126,115,92,92,84,84,60,73,104,69,118,129,99,103,89,92,95,59,107,99,121,97,92,90,90,86,111,95,101,97,93,13,56,49,68,53,86,80,69,65,73,82,120,45,92,78,94,77,73,65,73,61,46,69,39,58,68,54,68,57,53,41,43,31,66,51,76,37,60,57,41,46,57,55,47,70,59,60,55,56,52,56,32,39,39,56,46,54,70,52,39,62,46,40,65,54,25,57,48,65,44,62,69,42,28,49,67,44,66,61,49,47,38,75,66,57,62,68,64,54,40,47,38,56,36,30,43,19,50,39,41,36,46,43,60,52,51,31,40,53,45,55,51,17,53,18,35,47,53,43,54,54,45,27,29,18,19,49,50,13,36,29,55,46,34,59,47,49,45,47,45,47,41,58,28,58,44,23,55,33,45,64,53,37,23,45,28,54,56,20,58,52,54,25,42,51,66,31,62,53,32,34,29,38,67,33,52,23,44,37,50,43,48,44,50,45,57,52,58,42,52,44,50,49,58,58,58,67,52,21,37,46,60,46,43,44,49,51,38,69,53,59,68,60,59,47,73,41,73,70,88,69,71,53,55,44,44,39,33,53,47,29,29,25,17,56,46,20,34,31,30,61,51,56,25,62,39,31,45,44,42,31,25,31,31,55,29,41,37,42,50,46,47,51,53,57,47,55,48,28,58,39,71,52,39,61,60,54,84,60,90,62,75,74,52,73,92,107,140,106,125,105,126,130,121,130,159,178,150,138,127,138,169,216,132,150,177,167,145,151,164,161,155,156,138,151,168,161,161,144,147,133,143,156,167,140,129,156,132,140,156,157,122,121,134,156,149,172,193,179,158,150,153,132,173,161,154,178,170,173,130,136,138,163,121,165,132,147,152,186,164,182,126,156,144,154,172,157,156,166,158,127,161,131,135,141,153,157,156,133,163,145,146,143,118,100,76,65,25,11,40,0,11,37,46,12,2,24,7,27,22,31,20,12,24,5,17,8,27,26,11,9,17,16,15,20,43,8,17,11,30,31,28,43,33,37,15,21,28,21,29,48,19,7,9,14,29,30,10,22,25,21,18,31,43,19,31,11,38,38,32,43,22,32,17,43,22,23,37,27,32,8,18,25,23,32,28,10,21,20,36,23,22,33,7,50,24,45,30,47,42,31,34,45,38,30,27,34,22,36,51,24,48,50,35,33,49,69,16,18,31,25,50,42,54,55,58,65,35,34,75,41,50,47,60,44,62,58,44,27,42,40,59,76,70,55,57,41,75,65,41,80,45,85,94,130,136,108,102,99,135,95,120,137,156,147,191,155,148,113,144,117,98,133,142,143,124,143,143,134,125,143,156,117,121,123,139,150,127,155,159,121,145,152,134,136,103,132,131,127,133,154,156,145,138,143,150,139,142,120,131,130,135,146,127,123,128,131,131,135,138,132,111,134,153,111,118,126,130,121,133,131,129,158,151,128,171,152,135,135,148,157,149,153,151,157,139,133,128,140,134,126,145,122,158,165,144,133,113,132,142,143,151,180,140,111,127,131,137,137,123,117,135,120,126,118,115,117,126,168,126,137,138,146,103,81,129,105,115,120,100,115,102,92,100,94,94,103,80,101,100,142,131,129,117,129,137,124,131,149,141,143,122,139,113,106,106,92,120,121,137,99,101,94,122,146,111,100,110,136,129,130,114,80,74,75,49,44,76,91,71,57,93,60,65,74,62,54,69,62,67,57,98,104,88,89,93,58,72,75,63,76,72,84,77,78,76,44,28,68,76,65,57,72,68,72,52,55,74,40,37,71,60,56,45,44,51,21,38,42,36,41,72,35,44,55,30,42,43,65,29,42,53,38,54,81,56,65,61,48,36,67,56,45,62,37,70,49,52,65,54,58,48,44,57,34,22,47,45,54,44,63,33,34,59,56,59,51,25,56,29,55,53,62,57,42,50,18,51,40,23,35,31,48,48,26,53,47,45,35,30,39,22,44,36,40,40,64,40,73,48,62,36,43,27,33,39,56,50,66,40,41,47,44,38,50,35,49,47,48,36,45,28,27,12,46,38,38,29,35,38,62,55,43,5,45,44,47,74,41,42,40,47,47,42,21,42,66,35,72,28,32,54,60,65,51,66,58,38,41,52,67,72,41,63,50,41,32,34,35,43,56,23,56,48,51,57,54,40,49,66,44,43,43,59,58,54,36,87,57,49,77,78,64,67,59,30,55,66,21,28,37,26,53,32,37,30,30,25,34,37,30,27,36,40,30,52,36,64,26,47,38,44,32,50,46,11,21,57,43,43,40,31,43,64,53,37,33,54,19,58,69,50,55,66,51,57,77,87,86,70,94,95,89,102,104,109,142,133,119,132,128,164,135,158,156,160,172,182,167,153,163,161,195,151,171,155,150,155,162,138,144,150,163,150,130,167,155,164,129,165,127,171,138,173,142,164,133,180,165,162,164,161,167,164,173,168,155,166,162,176,169,163,163,138,166,166,167,144,153,160,167,141,134,164,150,145,153,164,154,121,136,141,129,139,153,140,155,149,137,136,120,153,134,147,134,143,134,149,151,123,134,152,136,146,116,82,80,30,5,27,6,26,17,10,1,11,33,14,9,33,0,22,13,1,14,39,5,33,32,22,21,34,19,22,21,45,37,8,18,31,19,8,34,32,6,31,28,22,21,17,40,41,15,16,14,32,14,22,14,13,19,29,26,22,9,17,26,33,26,40,18,43,24,3,15,33,40,29,15,48,21,32,30,50,31,41,23,43,31,23,21,29,29,9,20,29,9,31,11,22,42,51,36,47,41,47,57,26,26,18,54,58,15,32,78,57,54,65,55,87,57,52,54,67,91,99,83,74,85,102,118,94,111,157,133,138,126,135,140,113,107,113,107,82,63,91,63,66,97,110,95,98,87,88,97,74,86,79,90,99,108,93,83,75,97,110,97,108,113,127,143,123,119,127,146,131,125,138,151,159,155,156,161,122,113,145,150,137,139,130,137,141,173,156,132,146,145,141,153,120,155,142,160,159,158,154,161,121,126,138,126,125,142,143,138,136,169,166,134,152,126,146,163,170,158,146,164,154,140,155,154,143,152,192,152,142,156,170,132,130,128,119,120,89,123,111,125,141,137,122,144,130,132,162,150,136,116,111,145,165,150,142,163,158,163,147,141,117,96,107,156,138,191,156,155,175,165,115,108,122,129,147,163,165,129,161,179,154,170,131,151,145,176,149,145,139,149,148,148,135,107,132,122,133,128,132,149,127,120,120,112,130,136,143,98,93,127,158,123,117,145,151,114,101,151,144,143,122,98,97,126,70,97,118,115,170,130,94,58,57,91,105,68,98,112,113,90,85,104,100,88,82,61,78,50,44,61,46,65,78,80,72,76,73,64,71,47,92,93,85,90,82,52,96,75,85,51,98,64,58,63,55,79,56,84,42,27,73,51,44,46,56,39,54,62,58,26,65,62,22,42,38,30,45,70,18,32,17,37,78,32,61,58,48,60,45,25,54,37,41,55,46,75,57,27,54,45,42,64,43,43,59,69,46,28,60,77,30,40,33,59,32,36,32,54,50,50,41,32,49,34,32,65,50,53,29,41,39,37,64,49,21,39,47,49,55,53,58,25,64,44,51,46,50,53,42,38,37,41,45,14,64,70,43,40,27,30,46,52,66,29,46,37,40,59,44,36,28,46,45,32,36,25,10,51,70,31,36,55,46,36,20,36,40,29,52,41,65,29,44,59,57,57,37,35,76,32,25,54,62,52,59,62,39,42,45,58,54,44,31,52,56,30,37,29,29,49,42,32,50,52,44,32,75,45,48,44,46,68,47,53,66,58,48,41,78,43,85,50,32,67,47,40,66,42,43,36,27,39,57,25,51,31,20,23,49,50,53,48,35,39,40,29,76,41,66,18,33,28,58,47,56,11,29,42,48,42,52,40,16,55,57,46,53,72,67,75,70,56,49,60,92,75,97,124,116,109,100,132,135,134,135,147,141,166,176,172,175,156,157,149,134,152,175,173,177,170,158,166,156,163,181,161,162,151,164,178,166,156,178,155,163,153,161,163,142,153,134,170,150,138,151,144,153,148,160,129,158,141,166,163,139,182,145,157,173,151,124,154,151,142,156,143,134,161,144,182,143,161,153,144,158,146,149,144,150,155,148,125,157,142,148,149,129,148,121,129,113,135,141,176,159,160,159,161,130,132,29,2,28,21,8,33,7,21,25,31,12,11,19,8,10,9,3,9,31,15,23,13,46,13,7,23,31,26,14,15,33,33,23,13,32,20,33,20,23,33,25,21,19,28,5,14,24,31,28,36,22,14,20,32,28,42,16,7,20,24,16,32,53,36,11,29,15,10,11,42,16,26,40,11,26,4,12,24,38,6,26,44,54,12,20,22,24,24,31,52,45,36,47,24,48,48,41,41,27,24,61,38,14,45,57,61,51,46,31,43,72,62,58,82,29,64,61,60,75,73,81,57,91,104,99,121,123,129,134,114,122,115,120,116,102,115,85,80,63,78,75,109,96,118,94,90,96,83,106,89,101,105,106,100,107,70,101,90,91,113,119,108,117,162,154,135,149,136,140,130,159,121,141,157,126,150,142,117,115,148,138,139,156,142,134,136,164,121,142,102,118,130,165,132,149,137,143,149,143,134,126,117,135,114,144,144,150,119,128,152,167,136,146,156,155,158,156,141,139,155,151,142,150,141,146,155,178,161,171,157,152,139,146,122,138,128,113,137,126,144,130,151,125,148,128,146,145,149,104,104,146,140,137,182,147,140,170,174,140,152,122,117,133,142,145,151,141,159,123,174,126,122,139,147,144,166,135,130,137,177,163,133,148,121,146,158,136,139,159,137,158,153,128,115,123,123,138,145,148,113,105,100,92,118,121,121,124,119,111,131,112,142,138,135,94,129,110,104,120,134,142,127,112,94,95,99,127,124,136,163,111,77,84,80,96,87,132,106,103,94,102,113,93,77,88,84,79,36,54,65,74,72,65,55,51,65,48,47,59,72,77,86,86,62,93,55,82,83,95,79,64,89,73,48,70,78,20,47,37,37,55,54,38,72,46,42,48,45,48,44,59,47,62,53,42,34,58,50,62,58,40,42,78,67,54,39,35,55,47,35,42,36,37,43,45,57,45,67,67,60,30,40,61,47,65,48,55,46,51,77,49,58,48,70,28,49,52,34,48,54,45,44,46,31,46,56,28,35,56,54,42,39,57,66,38,45,32,32,60,69,23,45,50,47,36,57,47,40,67,30,39,38,41,53,52,49,40,46,17,26,41,49,50,42,84,47,26,48,44,34,46,44,70,38,39,56,44,54,61,62,40,72,44,35,42,36,53,32,19,26,13,34,65,79,37,45,37,20,40,38,49,55,46,19,50,41,36,30,46,43,49,57,41,54,24,62,48,27,52,32,65,49,53,46,81,46,40,39,46,53,53,56,69,31,66,51,44,27,52,53,67,49,30,42,46,42,36,20,39,29,50,38,50,21,29,44,20,46,35,24,38,54,34,51,43,38,27,15,37,19,51,57,52,48,57,30,48,81,42,35,70,41,43,62,25,42,58,76,52,77,79,58,84,82,73,84,88,128,82,123,105,130,164,131,149,161,161,158,170,153,166,156,190,149,162,158,168,148,164,163,140,160,151,156,168,158,133,152,171,180,169,169,154,159,157,149,143,175,141,149,134,182,156,155,154,148,146,173,172,160,141,125,129,147,139,160,150,160,174,161,153,151,137,125,151,169,158,130,160,142,127,136,136,145,130,154,137,144,154,154,143,125,111,121,136,156,145,145,115,137,138,174,137,138,132,144,138,146,165,100,25,5,1,19,8,1,5,16,17,17,39,18,25,31,19,27,13,19,21,31,17,25,19,10,8,32,27,1,26,29,29,21,31,24,16,31,17,41,27,15,22,37,23,43,23,13,26,33,16,18,14,30,13,10,4,30,16,42,21,42,21,4,4,24,14,11,31,18,43,27,21,50,38,27,58,23,43,39,67,48,39,35,25,48,22,34,27,22,40,35,19,18,21,16,14,50,36,46,34,42,22,35,43,34,73,56,49,57,57,65,57,71,70,72,57,56,76,100,89,89,91,92,118,128,98,109,121,92,135,115,109,107,123,99,114,94,158,104,124,102,150,106,110,121,124,135,131,143,149,132,139,151,139,108,126,114,125,133,120,163,169,139,125,151,152,148,158,151,162,149,165,165,151,139,132,137,139,132,158,136,123,138,153,151,145,137,143,144,126,142,138,151,128,144,130,132,154,113,141,139,147,148,130,143,160,157,118,143,142,144,140,131,127,127,134,152,142,101,148,125,136,139,137,153,153,130,144,127,134,152,135,126,151,161,158,121,139,140,149,168,173,159,144,150,172,176,132,149,131,146,157,146,148,150,150,128,139,151,152,155,146,159,143,119,143,158,141,113,139,135,134,133,126,108,85,116,119,124,121,112,122,131,124,132,126,112,124,130,127,135,124,27,4,20,12,23,20,7,5,17,4,28,8,19,4,0,31,20,16,5,5,25,28,18,1,15,35,40,25,31,8,33,4,1,22,10,16,33,11,3,3,9,7,28,14,1,11,14,15,12,16,28,23,6,11,21,7,22,24,20,5,14,5,9,6,11,10,24,15,37,21,21,26,35,18,33,12,0,25,21,3,26,26,34,11,22,4,29,27,13,11,17,29,7,8,15,20,11,19,36,21,26,15,41,38,27,46,5,14,23,18,14,11,7,24,12,13,26,18,40,34,11,24,22,20,4,31,10,23,15,18,9,9,25,18,14,31,26,11,14,16,11,17,17,9,14,10,10,1,16,11,2,16,4,29,3,3,16,29,45,14,15,36,13,27,26,29,11,3,15,13,22,11,39,1,14,3,16,6,17,7,43,18,25,0,20,24,17,7,18,5,25,2,4,11,14,30,15,8,38,28,23,7,16,42,42,7,10,23,25,6,11,16,30,14,47,36,17,28,18,15,41,21,26,16,24,34,23,23,14,15,4,15,37,13,10,23,10,0,9,25,7,17,5,7,27,15,5,15,6,4,27,6,13,36,8,12,18,2,1,14,15,13,46,8,31,35,21,23,19,10,1,32,23,17,3,18,42,28,11,3,23,18,10,45,0,15,12,37,11,3,5,31,34,26,12,30,3,4,13,4,11,10,27,1,15,10,10,8,13,4,10,10,4,24,16,5,22,16,10,45,46,45,26,11,25,49,19,19,3,10,12,13,16,24,25,6,4,17,19,3,14,15,45,40,10,16,28,12,11,10,19,14,6,51,16,29,42,13,29,1,25,26,13,10,31,5,19,6,22,30,20,18,37,11,18,25,12,20,14,12,2,15,26,11,1,24,24,21,15,9,38,38,46,8,7,23,12,15,19,18,24,2,28,5,2,16,25,30,3,16,58,19,15,31,15,26,20,11,43,17,31,26,21,3,12,8,29,8,2,24,38,24,18,10,1,20,16,32,15,7,19,1,0,7,0,26,4,2,34,8,9,32,32,26,42,26,39,37,14,51,23,25,8,43,14,14,33,33,18,6,21,11,20,29,23,13,21,18,21,26,11,35,17,20,21,48,25,16,16,33,21,28,19,32,33,37,26,48,39,27,19,12,20,45,19,21,35,49,25,53,56,20,40,6,10,21,28,56,24,31,48,36,28,21,22,70,25,24,34,36,47,29,82,58,49,63,58,64,71,40,68,53,42,46,59,74,94,99,79,97,103,128,109,78,100,112,117,100,129,104,115,92,106,91,82,144,140,131,126,127,131,128,148,141,115,138,138,137,143,124,139,114,151,124,150,147,126,159,145,155,170,139,158,136,158,126,146,157,134,164,174,137,143,98,149,144,132,129,157,149,123,110,134,126,112,145,139,161,139,137,138,145,146,131,109,127,108,125,138,148,121,130,112,131,154,123,170,155,150,137,130,126,153,142,122,131,129,117,134,148,126,162,117,136,157,143,151,103,143,156,120,150,154,157,159,122,159,130,140,144,145,152,117,164,162,143,151,160,129,147,142,151,116,144,140,142,148,130,159,152,156,124,156,120,160,118,118,99,148,186,132,125,111,113,122,122,125,123,132,124,129,134,149,132,130,118,123,128,145,125,41,0,24,35,37,7,18,31,15,20,13,18,12,23,8,39,16,23,16,30,2,23,21,17,16,21,8,12,21,7,22,17,28,27,4,3,35,4,20,30,8,3,15,19,42,29,12,31,18,18,13,11,19,24,14,25,51,11,41,8,11,10,1,19,14,2,11,16,25,19,11,11,16,12,52,19,8,18,12,18,42,23,8,12,24,19,12,17,27,28,13,42,5,24,19,12,35,7,15,15,17,12,19,21,12,35,13,35,11,7,0,22,21,28,18,13,31,21,1,5,15,14,41,8,21,41,30,0,26,16,6,17,22,13,28,8,20,30,9,26,30,6,12,34,45,42,58,23,4,4,14,3,41,7,25,1,7,10,2,20,37,24,22,31,4,29,6,5,29,23,11,13,22,31,30,33,13,13,24,1,4,6,10,21,3,13,4,30,22,17,26,19,13,30,47,32,17,18,0,18,12,18,12,10,9,5,8,18,3,35,12,41,17,13,7,10,24,28,34,24,6,39,9,25,30,13,27,10,4,18,10,31,32,8,23,39,26,14,13,35,28,18,10,25,23,4,20,6,25,40,18,38,15,11,25,22,30,12,32,20,25,2,20,16,23,9,31,20,5,22,13,15,14,23,23,21,18,12,11,16,5,1,15,4,40,18,20,18,7,21,8,22,1,15,28,30,17,38,20,8,33,17,23,14,10,1,22,45,20,19,19,12,10,25,3,3,13,12,29,7,0,23,13,1,10,18,29,54,5,10,22,12,13,20,16,21,6,12,3,5,23,19,17,10,13,16,12,24,31,20,36,27,23,1,32,30,18,8,24,27,12,24,50,28,5,6,5,1,24,30,13,33,27,18,23,5,2,31,15,1,8,32,17,21,13,8,15,34,30,7,20,22,15,4,7,10,35,14,14,41,14,42,13,34,16,20,14,22,29,26,26,8,12,16,30,24,22,10,4,0,9,21,13,8,11,20,10,17,29,12,15,14,17,20,6,18,11,19,6,11,24,22,3,26,31,0,3,12,32,8,21,5,18,20,26,9,5,33,19,25,31,38,20,16,14,5,17,10,34,12,26,8,12,19,38,28,30,17,33,32,6,21,38,19,15,3,31,22,35,7,21,3,30,43,17,14,10,40,28,34,16,30,26,40,18,6,29,9,18,2,36,25,34,16,30,3,30,14,13,28,36,38,11,38,38,51,25,8,36,21,22,17,37,17,33,38,24,50,31,28,25,20,18,30,38,40,9,31,22,14,42,33,35,40,36,53,10,47,44,34,60,57,35,49,45,70,56,39,33,31,48,53,25,40,53,35,52,49,32,60,55,38,50,65,65,56,71,101,91,91,77,98,116,112,110,84,118,110,104,102,117,128,141,112,114,152,125,142,130,128,147,142,144,134,112,156,130,139,119,147,130,131,140,131,130,119,145,106,112,103,128,112,129,123,107,135,133,110,131,154,148,130,149,148,138,129,162,120,112,148,138,126,141,124,122,139,134,126,137,121,140,103,134,147,154,115,117,147,104,110,127,153,157,147,163,172,152,137,159,152,144,128,123,144,155,136,134,131,142,115,136,126,128,123,101,120,107,113,136,138,120,113,97,85,111,111,133,111,105,143,102,89,141,106,118,149,135,122,115,106,96,149,119,123,153,90,136,138,115,123,130,148,150,122,124,144,135,124,127,116,126,118,151,138,138,144,96,136,121,138,99,98,84,79,103,94,62,71,85,66,78,81,97,101,84,88,85,121,59,102,107,100,100,132,89,64,81,82,74,94,59,63,43,62,53,50,71,93,56,98,73,68,54,53,46,36,61,70,70,50,51,54,86,42,63,62,46,89,67,67,45,77,54,68,74,72,69,71,47,67,71,51,63,58,56,70,63,52,83,57,39,40,21,23,61,69,49,46,35,39,23,47,44,62,43,36,40,49,52,46,39,37,54,62,25,14,39,45,26,67,43,25,52,65,40,35,54,51,39,49,38,37,43,34,56,43,35,30,53,51,35,47,32,28,40,30,48,40,32,23,18,44,48,48,30,30,37,34,29,36,46,44,45,37,52,42,58,45,29,30,34,33,51,42,49,35,50,46,22,44,41,50,66,57,36,15,31,40,53,52,27,43,62,33,40,37,36,33,36,22,54,46,22,42,52,40,32,58,44,22,42,36,32,55,31,42,60,43,59,73,54,41,60,24,51,51,35,64,65,46,54,68,60,55,62,69,81,68,80,90,62,48,78,71,82,68,74,42,82,95,84,82,28,48,61,86,73,42,70,60,56,67,31,27,30,33,64,29,57,43,20,48,13,28,29,10,40,32,51,31,46,29,32,31,28,64,28,11,39,56,27,39,32,42,20,22,54,47,45,74,79,46,63,43,59,52,34,51,44,85,82,77,66,68,84,70,119,126,94,111,131,114,145,148,146,141,140,128,134,156,128,147,184,156,139,158,142,122,146,153,152,150,156,149,107,166,136,172,149,171,146,164,162,150,146,166,163,163,142,141,158,181,149,143,121,162,149,147,133,168,147,150,157,127,159,161,169,160,166,149,168,141,169,146,164,168,147,152,177,174,156,144,148,133,171,138,154,153,146,152,153,118,162,146,127,137,142,174,137,160,102,85,85,86,117,152,141,174,135,168,102,9,17,25,0,15,1,9,20,13,12,23,0,23,10,30,24,18,18,14,35,6,43,28,16,11,8,22,3,30,41,21,12,9,10,20,33,35,17,33,8,34,24,46,23,49,38,30,7,27,11,26,13,12,34,11,13,49,24,9,44,10,10,30,35,27,14,20,37,37,7,20,14,31,29,26,37,16,19,21,6,43,45,30,33,28,37,35,11,31,41,8,16,32,30,24,38,13,61,40,27,50,40,11,38,16,51,33,22,12,30,28,28,12,8,36,56,63,64,47,49,35,24,40,48,56,50,71,61,61,68,58,31,64,51,48,76,82,57,59,47,62,89,111,89,89,89,97,75,81,61,57,70,91,97,101,71,100,72,84,89,110,110,115,151,132,123,121,133,137,125,161,157,99,119,117,126,134,108,121,112,120,126,146,121,134,94,144,128,122,136,134,142,149,107,141,134,151,131,130,142,124,146,134,153,136,113,107,117,123,142,165,138,128,129,156,135,143,117,116,127,123,118,129,130,86,138,95,122,129,145,123,121,147,123,140,145,176,136,114,140,110,129,115,117,108,159,118,122,130,127,126,123,116,114,139,122,152,123,136,135,94,120,133,115,138,131,113,124,106,117,97,125,153,147,130,116,112,122,113,79,130,131,99,124,97,93,124,116,104,125,115,114,106,79,99,118,104,129,117,116,123,133,147,127,102,72,90,108,77,98,105,109,94,65,41,79,92,99,98,49,83,78,72,96,60,63,77,58,58,48,81,67,111,80,23,51,48,87,65,56,51,68,85,52,49,102,55,50,69,50,38,69,64,57,33,68,52,71,49,57,50,50,54,63,46,62,52,77,77,52,57,76,39,37,71,48,63,60,64,67,46,62,59,68,40,82,32,64,72,50,58,70,40,58,39,63,51,51,38,53,66,50,59,42,42,38,43,28,35,14,28,49,60,63,50,45,32,27,65,47,60,39,52,40,46,46,24,74,53,57,37,60,50,37,49,43,43,45,49,50,48,37,43,52,29,57,52,49,39,23,67,43,49,55,36,33,25,55,45,35,59,34,36,43,40,48,39,58,26,31,40,50,40,32,26,32,28,51,60,45,36,62,70,56,26,71,50,54,49,35,54,31,50,19,54,41,37,23,35,54,29,11,40,34,37,34,47,56,29,40,35,33,54,65,34,61,65,37,63,42,75,48,52,64,52,41,23,55,53,46,68,60,68,51,23,58,45,49,49,47,90,73,69,67,75,91,56,62,29,66,77,48,44,32,64,63,42,68,70,63,53,54,40,49,23,40,63,44,40,38,39,50,39,7,40,38,31,27,32,37,22,36,4,31,42,33,16,32,30,22,49,50,20,54,30,30,38,44,47,43,46,57,60,46,76,84,40,100,62,98,97,56,49,72,77,94,65,90,74,154,139,122,137,124,124,114,153,134,152,152,152,158,179,181,138,169,119,148,162,124,145,142,156,161,138,139,156,146,153,140,168,174,160,152,178,147,161,170,166,162,152,156,154,160,130,157,120,138,166,149,149,136,145,122,160,161,132,156,155,144,161,163,173,157,169,166,150,170,143,151,127,154,166,146,153,181,161,134,138,128,182,153,143,146,141,123,170,139,128,126,113,88,77,68,78,104,154,170,171,114,14,5,7,6,23,19,18,10,13,38,33,15,28,1,15,25,44,13,19,29,44,10,21,13,24,13,28,51,16,31,28,22,15,17,44,9,14,28,9,37,9,38,24,5,10,20,4,28,18,32,13,19,15,14,28,32,25,28,21,17,5,26,15,41,27,16,12,23,19,27,14,10,28,49,3,42,60,14,4,41,26,29,24,11,28,40,38,21,17,12,32,42,20,20,33,45,30,23,29,30,39,48,26,36,12,18,23,39,24,41,10,28,11,32,30,52,25,11,82,41,48,40,51,34,79,31,54,28,37,31,36,20,69,47,39,67,49,66,67,93,77,89,83,89,72,90,84,70,68,76,79,100,112,106,80,107,95,108,111,91,131,123,131,123,132,137,146,126,135,112,108,155,119,106,146,126,138,127,127,103,96,145,138,134,121,109,126,150,126,149,136,124,147,159,128,128,113,123,100,102,113,135,104,129,144,93,81,96,127,126,124,124,123,114,126,128,148,132,146,138,143,111,141,151,145,153,145,133,142,146,139,130,122,111,110,136,131,99,134,111,121,137,121,132,122,134,112,133,128,143,100,125,142,137,122,135,136,130,117,153,133,137,131,127,99,115,101,125,133,106,119,143,147,135,112,143,129,114,105,122,132,121,134,117,90,114,148,129,140,151,133,139,99,112,134,113,130,132,144,110,116,130,134,146,124,98,120,105,120,121,135,92,135,118,131,142,114,144,121,83,79,106,112,121,86,73,70,86,74,85,76,102,123,76,118,92,58,70,71,81,71,111,117,109,100,77,67,75,78,86,59,96,47,38,97,65,62,100,67,71,40,34,66,42,59,26,68,64,27,32,31,52,45,50,47,60,66,73,62,65,42,77,47,56,37,21,70,67,70,47,55,38,56,47,55,73,44,55,41,65,48,44,40,39,46,54,62,43,14,68,53,78,70,53,63,46,50,51,79,62,31,42,47,68,60,46,73,25,78,38,53,34,42,40,24,48,23,47,21,48,52,55,44,48,66,13,41,46,53,30,61,36,30,47,37,36,79,68,59,49,41,42,47,46,55,44,46,18,8,57,52,28,26,33,39,76,64,26,30,48,35,41,56,33,37,29,51,42,30,54,38,22,44,49,47,25,40,38,23,56,37,43,42,18,46,32,33,37,37,59,20,25,49,18,21,47,40,47,65,46,41,43,50,64,55,66,57,55,63,50,34,37,34,67,63,60,31,65,58,75,71,88,61,77,92,88,84,90,75,84,54,87,106,48,58,58,57,71,41,30,52,36,31,36,43,19,40,13,50,35,26,35,25,41,18,58,19,20,56,36,41,22,21,24,55,40,28,51,25,23,27,22,21,44,47,33,42,41,25,52,68,51,64,70,53,62,37,77,59,51,75,61,51,48,72,99,78,78,127,134,141,127,141,142,124,146,154,158,134,166,156,170,171,175,158,173,158,149,160,164,159,159,175,164,126,161,145,146,158,133,169,174,135,152,138,158,167,172,186,156,165,162,160,160,172,165,149,143,152,156,136,149,163,148,154,158,138,145,161,151,153,154,138,134,147,144,133,150,152,165,189,158,156,152,167,150,159,122,143,166,137,136,131,141,143,142,165,134,147,146,157,143,94,86,93,87,114,122,167,123,20,3,20,23,12,27,1,22,15,20,9,16,1,26,6,17,10,34,32,12,23,19,53,33,27,37,12,19,38,3,41,8,14,9,14,26,6,32,6,25,45,26,7,6,14,15,13,40,31,8,21,7,27,51,20,29,4,35,3,15,16,38,13,18,10,8,41,29,32,9,2,19,16,13,46,14,18,16,19,14,44,7,16,8,20,27,4,10,2,17,28,30,62,25,10,18,35,14,33,17,31,50,39,11,30,7,9,14,33,44,34,54,34,41,13,26,21,36,39,28,52,48,45,54,70,53,65,61,69,42,52,64,83,75,84,71,103,83,91,79,66,82,84,75,68,78,87,71,75,84,69,109,108,116,133,139,109,120,126,129,141,131,123,121,137,112,96,137,120,117,132,139,137,136,103,142,151,138,162,142,166,128,165,137,154,145,141,156,149,133,125,139,119,106,131,133,138,151,133,138,135,107,144,145,142,125,126,113,121,110,106,125,128,115,130,140,106,125,143,146,150,166,149,151,148,140,136,145,137,147,143,153,145,106,122,132,103,132,132,138,128,153,121,120,119,128,113,116,95,119,147,126,121,141,133,129,122,142,162,161,158,159,114,142,131,162,146,150,126,119,117,148,124,133,110,127,131,115,122,140,171,139,156,103,117,124,148,155,126,128,105,118,137,145,137,125,132,116,129,128,123,133,138,110,140,123,147,148,168,146,139,132,134,158,152,144,156,134,138,113,87,100,113,106,117,80,91,95,96,108,97,97,84,80,94,52,95,79,101,112,98,110,88,80,59,88,46,68,102,77,69,71,53,47,44,77,70,33,56,86,45,85,66,55,48,54,65,74,69,43,54,61,43,59,80,59,70,38,62,61,64,67,72,66,43,76,53,43,64,51,48,46,71,63,40,57,67,54,67,61,55,27,28,34,60,60,54,36,53,53,74,53,23,51,54,47,59,43,22,44,38,49,58,70,47,37,47,65,61,15,30,26,52,47,55,62,58,65,45,26,53,30,55,64,34,56,38,59,39,34,28,27,52,36,51,28,22,36,59,51,42,49,45,45,51,45,40,32,27,53,42,31,47,46,3,46,39,44,40,42,55,58,42,42,20,29,42,42,35,66,31,59,53,52,47,39,28,38,22,55,22,48,38,20,41,35,31,32,20,39,37,44,54,34,24,47,40,36,62,32,35,55,57,23,72,30,67,42,58,42,23,21,28,58,49,77,44,73,83,58,92,62,63,91,72,79,80,112,92,86,104,68,65,38,43,66,55,47,50,43,59,33,27,33,14,6,66,52,46,31,37,31,44,26,31,66,28,36,44,14,38,19,45,33,48,24,44,51,31,40,38,30,35,16,54,42,37,29,44,77,53,67,64,58,46,61,63,46,69,35,62,33,94,69,38,107,69,76,94,120,137,141,151,162,148,128,121,148,167,195,150,163,158,180,171,156,159,150,173,154,182,171,163,164,197,165,154,179,182,156,182,153,147,135,118,154,134,187,171,164,153,153,172,171,143,159,165,151,149,158,145,148,167,160,160,150,140,160,156,145,154,151,141,160,135,129,131,161,157,143,184,150,159,149,159,156,158,163,147,171,158,171,135,147,131,146,112,156,146,135,174,150,132,112,103,81,98,113,139,128,5,5,0,15,1,21,7,22,17,11,15,45,17,14,53,19,15,30,18,6,39,14,16,39,34,29,5,19,47,33,19,5,14,29,27,8,25,22,34,27,29,25,12,14,8,15,31,20,29,7,18,15,2,33,36,19,21,24,9,20,8,13,18,11,8,11,30,14,20,36,44,42,11,11,12,36,28,3,29,4,36,39,36,22,42,25,30,15,17,8,28,36,27,40,31,41,18,44,28,28,26,35,41,20,23,64,40,36,10,36,40,43,26,19,33,40,29,40,45,61,48,33,41,37,76,57,75,83,122,102,70,102,113,91,100,120,56,91,78,96,59,54,104,67,131,67,92,108,96,112,91,123,128,115,149,129,124,127,130,129,106,121,117,119,98,130,134,105,117,117,132,140,143,131,130,146,151,149,139,147,156,138,97,109,133,132,141,129,133,119,131,127,130,97,121,121,116,133,134,123,136,150,159,156,116,178,166,159,130,150,118,148,157,161,130,144,151,152,154,169,153,161,130,137,124,154,132,146,137,163,166,142,155,145,165,144,108,122,126,132,120,109,134,143,162,96,134,122,125,102,151,147,120,162,131,137,142,160,165,122,153,147,119,136,117,148,163,139,126,146,140,156,141,148,118,134,126,121,126,159,120,102,123,147,101,108,150,140,139,138,107,109,142,125,118,121,112,107,122,122,136,118,108,122,124,142,128,125,111,137,132,93,116,119,108,122,108,90,114,89,112,86,89,106,92,86,97,93,92,87,79,80,62,78,60,65,69,82,72,72,79,75,67,49,53,39,54,29,46,66,49,57,41,63,34,22,66,34,54,51,50,64,66,47,64,61,62,54,65,90,52,76,67,50,39,57,57,37,53,57,50,69,67,42,67,53,40,45,63,64,55,40,45,34,25,55,50,35,46,50,27,47,50,43,54,37,42,50,69,60,46,49,48,44,39,28,47,42,53,32,29,31,23,56,47,15,71,28,42,44,46,46,30,49,36,45,39,62,29,48,34,55,58,20,41,37,51,52,46,61,40,20,47,49,39,38,37,32,53,45,39,27,51,41,37,47,49,31,42,31,39,20,65,45,47,46,51,49,52,46,21,39,44,38,54,38,34,44,26,35,46,27,49,36,32,25,27,37,35,25,57,56,35,42,33,48,44,21,49,19,24,33,59,47,51,62,70,57,45,23,37,45,67,36,27,46,20,36,44,57,43,43,43,61,47,79,49,64,49,65,56,55,78,72,88,98,78,74,57,59,79,53,60,53,52,64,81,84,29,43,44,28,48,32,18,46,50,40,22,43,48,44,9,38,43,33,24,50,21,60,35,54,34,56,30,31,40,56,37,29,35,46,49,58,48,50,51,43,29,46,55,72,65,49,56,70,58,46,73,39,56,38,78,56,72,112,97,65,66,101,128,112,132,157,153,113,135,141,175,149,137,137,132,161,177,198,188,184,175,191,158,171,166,166,212,156,139,150,141,168,161,150,162,147,157,159,169,166,158,121,156,174,151,171,162,166,150,152,133,163,146,142,142,154,125,152,145,159,157,154,137,161,148,150,162,143,142,148,141,140,134,138,142,143,152,132,148,153,138,146,156,149,153,148,141,131,142,138,124,177,158,165,145,129,119,97,80,77,111,100,24,0,14,9,26,6,23,16,0,21,28,17,9,14,54,41,22,3,18,21,32,30,18,30,11,42,20,43,16,15,8,24,14,25,41,9,5,27,25,45,28,32,16,0,35,12,12,22,10,19,41,10,37,0,9,18,21,29,37,23,16,13,32,44,17,6,24,25,34,19,37,7,38,33,11,6,5,30,17,19,7,37,21,13,54,12,4,25,26,0,18,30,31,24,38,25,0,27,38,20,21,51,30,40,40,34,34,7,41,17,20,12,28,46,45,29,52,55,40,42,55,70,24,42,49,82,72,61,70,51,112,50,62,64,71,67,82,66,62,53,33,59,70,111,95,81,99,102,111,146,157,143,130,133,145,144,148,132,138,123,126,154,129,127,110,110,123,147,158,132,125,128,147,132,124,163,129,104,113,138,120,88,134,117,108,123,140,117,130,142,120,121,141,136,136,88,154,131,126,127,140,120,111,120,110,151,137,117,153,166,134,143,140,111,106,131,130,150,147,141,142,160,169,151,142,155,136,127,137,130,123,136,126,150,98,148,148,137,127,136,125,135,154,117,148,124,136,138,163,129,125,139,137,137,147,139,140,141,115,143,117,148,151,146,136,147,143,134,156,156,167,155,161,131,169,134,157,169,145,131,136,125,152,125,156,140,138,138,147,148,160,131,121,87,92,85,115,94,117,126,112,93,75,92,115,101,100,96,81,68,114,142,75,94,105,91,105,77,78,70,89,70,88,70,73,79,85,94,95,104,75,80,42,40,78,82,93,71,78,78,63,73,66,60,64,59,32,64,62,58,53,46,69,53,66,52,44,70,36,41,47,80,64,71,64,62,58,57,66,68,67,56,38,61,63,55,51,63,69,42,63,53,58,67,72,42,56,32,46,61,50,40,55,92,41,55,48,54,43,42,50,53,73,45,63,61,26,45,48,70,46,66,48,34,53,59,66,44,50,55,69,26,40,45,36,43,51,61,59,23,36,52,67,28,53,42,51,46,59,40,31,37,60,49,24,54,49,41,63,37,46,39,58,27,58,30,55,44,57,48,40,21,36,67,33,40,45,43,68,50,32,59,42,41,40,45,53,28,16,25,61,54,19,37,41,28,32,40,39,58,31,32,60,68,59,42,29,45,42,40,59,75,42,65,29,36,35,43,51,57,31,36,61,46,44,51,79,52,29,37,79,68,56,65,39,72,56,77,67,73,40,54,64,45,69,67,60,55,43,24,54,80,96,78,95,72,45,63,41,60,57,40,41,76,55,65,69,57,61,39,76,57,29,46,56,19,43,28,42,37,28,43,30,56,23,33,13,56,26,41,59,39,37,46,54,16,47,41,25,36,36,49,28,53,60,29,51,43,44,52,60,44,49,50,32,56,67,72,68,42,61,42,67,44,71,52,60,48,72,113,121,104,109,141,131,150,135,137,170,129,143,141,120,154,167,164,162,165,127,153,138,151,166,141,151,146,158,156,188,155,169,170,178,166,142,169,164,163,129,180,152,165,150,136,154,141,139,153,170,175,176,156,166,174,162,157,178,138,158,172,135,167,170,174,169,149,171,158,163,170,139,165,143,140,162,160,136,122,157,154,162,135,150,142,163,151,153,120,113,116,135,137,159,146,140,126,91,59,88,80,8,7,41,9,31,13,5,4,15,31,10,8,18,2,23,10,45,12,19,26,4,7,34,52,12,14,59,30,22,8,22,13,19,37,25,32,11,18,12,28,19,23,33,24,26,18,24,16,28,14,13,2,19,22,52,24,28,19,8,40,25,11,40,17,24,21,16,44,19,27,6,22,35,43,16,3,18,11,20,32,47,20,10,21,4,40,7,28,4,52,44,22,19,19,23,15,33,52,35,62,44,25,18,18,39,31,9,14,39,30,27,39,48,34,24,45,28,56,41,61,56,43,54,63,72,68,61,54,74,73,29,39,57,46,52,31,74,73,45,28,24,64,28,49,48,89,79,95,125,128,146,135,136,136,140,152,181,165,142,151,153,165,150,159,149,126,148,152,132,120,151,131,128,143,120,134,125,114,140,153,119,117,126,133,138,143,143,119,130,132,151,152,130,149,128,144,156,147,133,124,110,118,121,140,140,122,122,134,123,140,137,154,133,100,125,119,121,98,95,139,136,131,150,148,143,147,152,173,148,136,144,138,137,140,145,151,152,155,143,122,150,124,156,139,151,128,121,141,139,142,123,148,115,107,126,114,123,150,139,150,135,169,146,138,129,120,117,149,135,122,151,145,139,111,132,132,114,153,142,139,146,139,140,151,127,112,157,164,143,136,112,127,121,119,142,118,115,100,121,137,105,106,119,113,122,97,120,107,94,75,92,97,89,94,107,110,86,104,97,83,110,107,108,118,63,85,89,72,101,75,117,112,80,63,50,56,65,63,70,67,82,66,70,90,89,72,37,83,42,82,70,86,70,79,70,48,64,48,65,85,53,54,38,43,80,54,68,58,34,40,53,48,55,53,55,49,69,42,61,49,49,52,53,48,61,39,57,71,69,52,74,56,23,51,68,41,61,72,69,50,30,40,33,65,38,42,51,56,40,39,53,58,46,36,51,23,63,50,39,52,60,48,47,44,34,36,54,31,22,37,55,60,56,44,63,46,56,30,50,36,34,11,59,40,68,32,45,58,23,26,41,36,51,30,27,46,44,47,43,37,34,53,63,11,42,34,43,61,34,34,43,36,55,43,39,63,38,57,47,72,39,36,53,43,28,45,47,43,22,33,15,45,48,41,41,32,32,57,36,34,62,42,48,42,24,61,58,31,42,45,57,32,25,54,36,49,63,63,66,41,29,39,38,40,36,63,47,67,57,38,57,27,61,52,62,33,12,50,53,69,59,41,57,79,86,69,66,29,52,37,83,74,79,48,47,45,35,43,73,48,38,43,47,47,53,39,20,14,26,29,46,41,20,49,40,20,21,12,55,62,53,47,38,21,26,55,27,44,53,52,36,53,44,33,61,52,51,48,48,44,37,74,39,41,86,36,47,63,43,57,92,47,94,64,90,98,77,66,94,119,139,111,126,139,128,120,140,144,162,182,159,139,120,137,169,149,141,129,146,137,136,139,146,176,161,129,129,148,164,157,127,171,140,152,152,146,123,148,148,137,152,131,161,161,134,155,138,131,174,172,144,155,159,152,163,141,154,162,159,157,155,147,122,143,167,120,135,160,158,162,150,143,128,172,156,130,139,155,167,141,153,159,162,137,118,164,146,170,137,157,161,181,134,126,162,136,131,76,70,74,33,18,20,8,9,29,2,17,12,5,15,26,6,32,25,8,18,18,16,25,31,43,26,5,24,15,39,8,8,43,21,40,28,16,30,26,39,46,26,2,24,7,9,16,8,47,23,22,22,32,17,53,20,9,5,6,39,20,30,30,13,46,28,23,12,20,21,15,3,34,17,32,26,27,21,19,31,12,34,22,33,27,16,4,6,36,43,14,40,21,4,30,38,35,12,49,56,42,48,40,22,35,10,46,49,23,32,21,61,24,41,41,45,35,42,52,54,33,38,47,56,47,42,53,63,40,27,32,29,64,26,31,43,31,52,53,71,68,52,74,45,65,45,54,79,83,104,110,116,77,123,119,107,122,149,137,157,149,144,145,120,137,119,120,138,122,124,148,125,134,142,141,124,120,123,102,114,141,123,125,115,124,163,160,122,131,99,134,140,120,152,140,144,132,131,152,141,148,133,130,157,152,129,121,109,131,137,133,130,126,123,124,120,128,103,130,124,109,120,109,121,115,148,150,159,131,143,142,163,160,163,127,140,154,142,148,120,151,133,149,156,131,144,127,139,122,152,138,136,136,119,135,124,140,150,137,144,127,135,152,127,127,149,125,122,134,112,114,107,124,145,145,139,118,112,113,119,88,117,136,105,120,99,80,102,91,84,80,103,94,55,76,107,118,140,134,151,94,120,125,124,150,166,147,134,117,100,101,100,90,104,119,103,98,83,97,108,120,106,110,121,133,130,109,121,108,88,44,46,60,89,93,94,89,76,52,62,69,69,66,88,63,80,64,104,95,84,71,64,76,67,28,52,75,58,63,84,110,80,65,44,63,46,72,53,55,65,81,54,47,60,50,45,54,64,67,62,74,36,54,60,49,43,37,52,47,81,58,43,51,73,56,41,76,48,51,55,67,44,65,58,56,46,59,71,43,72,61,77,67,79,64,39,34,40,69,57,63,59,48,27,47,65,28,41,23,83,44,54,44,71,63,51,47,58,14,60,38,41,43,33,36,45,39,48,22,47,16,28,40,40,43,41,31,37,60,50,11,23,35,55,52,52,57,51,39,51,16,49,56,32,40,52,49,43,48,72,36,56,63,29,25,48,64,52,44,43,42,63,42,31,63,50,59,41,55,49,18,33,35,29,55,57,66,77,40,44,23,62,52,51,52,66,59,60,44,55,64,42,63,31,53,30,44,29,46,62,24,69,68,60,40,45,17,29,57,61,33,42,30,57,59,41,61,37,43,68,43,53,74,53,61,40,74,63,54,57,63,68,47,26,29,56,29,41,59,57,35,29,59,46,41,42,57,36,23,20,50,40,29,27,13,37,19,35,47,54,52,42,37,30,29,51,51,15,63,63,18,37,43,33,60,67,22,54,80,36,52,49,70,87,75,81,46,92,78,108,111,130,137,129,143,135,125,157,141,154,134,167,168,191,157,153,158,161,172,184,157,155,133,139,149,141,142,146,162,147,125,162,172,175,163,161,156,142,154,141,145,165,144,147,135,191,160,182,191,161,152,168,160,163,199,177,163,142,195,153,153,144,167,146,150,166,184,150,170,157,170,155,147,177,163,145,164,151,138,158,145,159,140,167,166,127,145,162,133,146,134,154,146,122,154,139,158,143,145,143,130,117,69,23,16,12,21,26,12,15,14,8,25,12,29,36,26,32,26,35,18,27,25,8,28,3,14,38,50,9,9,29,37,31,34,19,8,22,17,46,40,5,37,17,55,31,21,40,27,20,16,30,35,4,16,37,18,14,27,16,22,40,35,20,36,8,20,20,13,31,20,16,17,44,40,47,12,16,22,11,33,21,34,25,34,19,35,33,11,23,26,38,29,24,23,23,59,29,27,24,62,22,55,42,38,58,55,31,41,54,68,66,37,56,63,29,46,38,64,80,55,82,77,80,70,109,118,119,130,122,124,139,122,99,123,104,118,103,98,85,62,86,91,85,105,114,114,100,109,103,87,56,67,101,106,117,99,92,123,114,101,87,109,77,108,132,128,154,120,157,163,123,141,146,133,164,147,156,116,136,135,140,164,151,145,131,154,145,150,135,128,119,140,136,112,113,151,137,151,155,158,176,135,126,136,135,136,150,157,122,127,144,153,143,155,140,151,175,177,167,151,162,165,166,153,138,141,147,161,164,157,145,155,141,116,131,103,128,131,113,128,133,117,128,134,138,133,159,122,121,123,140,148,143,154,149,136,140,156,143,162,152,133,128,104,113,159,144,165,128,143,142,141,139,121,136,131,156,138,153,150,155,175,163,136,125,133,149,174,130,118,152,145,123,131,132,129,119,130,125,138,127,137,127,92,116,129,106,140,126,112,118,151,124,123,130,142,103,140,131,120,142,125,134,116,110,96,90,116,106,151,152,113,105,92,57,96,99,69,93,102,97,108,98,120,116,93,84,67,77,62,80,71,72,72,85,62,35,81,62,58,69,74,99,99,58,71,62,59,65,56,102,76,72,67,73,42,76,78,45,43,56,51,42,60,70,63,38,51,53,60,56,56,41,35,66,49,49,77,47,31,61,61,31,59,43,75,57,38,58,72,50,50,51,83,44,56,64,47,56,49,64,68,45,72,47,58,56,19,34,59,79,72,25,18,34,40,42,38,52,51,52,56,37,56,55,27,53,51,29,56,15,54,20,30,49,45,37,51,41,51,34,49,50,45,51,61,45,48,22,64,15,49,27,27,56,62,42,59,42,55,52,58,40,36,23,52,36,50,71,43,52,69,55,44,68,41,46,44,53,73,55,29,54,35,26,69,37,45,39,38,50,58,34,61,39,48,30,44,40,30,50,54,52,53,45,39,22,50,41,54,49,61,60,62,33,49,25,33,52,46,44,48,51,71,61,51,53,40,33,35,49,49,38,45,59,67,54,58,72,53,63,39,62,52,30,64,63,50,48,44,54,45,47,41,61,49,45,51,41,43,68,21,26,16,39,37,34,53,39,61,48,34,56,61,70,44,66,55,56,50,49,50,61,31,43,66,52,57,72,65,48,74,49,40,74,80,89,97,100,122,113,105,81,134,126,142,144,151,163,174,187,169,150,179,166,160,133,154,168,152,173,172,183,146,153,161,163,141,157,160,175,165,178,156,160,150,147,130,132,152,168,138,140,146,155,142,158,143,172,172,135,148,158,133,171,146,169,138,136,161,152,132,146,153,140,140,133,154,157,147,138,151,132,135,149,160,147,165,143,142,138,171,128,118,119,175,133,127,125,105,132,136,130,123,163,145,162,151,132,125,133,101,21,9,19,3,16,17,26,1,24,6,34,17,32,14,41,21,30,14,51,13,28,4,12,18,24,25,34,22,16,19,22,28,41,27,39,42,30,24,4,24,14,15,23,10,6,47,21,19,38,37,38,6,19,35,31,35,11,6,37,23,27,38,13,36,10,14,21,38,38,9,9,11,28,22,30,49,15,52,53,28,22,9,66,27,4,27,21,25,16,32,22,9,40,34,47,38,27,31,46,37,36,39,34,68,41,35,60,49,55,58,25,57,47,61,46,62,99,98,115,73,83,61,84,116,116,113,127,129,113,139,133,128,90,128,86,72,93,66,101,93,98,99,111,113,105,91,100,98,98,72,94,92,100,114,100,103,97,90,99,109,141,115,155,144,146,144,142,117,103,118,151,157,145,125,146,187,117,143,135,145,137,118,137,146,154,161,141,146,142,120,127,130,138,126,134,138,121,134,161,125,128,131,143,123,120,110,146,142,136,153,170,134,142,166,165,157,133,130,160,169,154,136,148,136,148,160,165,148,142,160,160,143,130,143,110,121,110,136,157,109,116,115,142,137,144,137,115,121,140,135,121,123,141,131,142,152,152,163,149,130,131,140,137,147,143,175,169,155,141,144,145,106,113,131,141,153,150,147,153,147,137,148,122,122,147,169,147,163,131,151,158,126,126,138,113,120,124,130,121,129,137,112,133,127,121,113,132,102,126,120,121,138,125,120,127,117,115,122,123,133,130,113,128,99,106,117,115,111,147,131,113,73,62,80,91,100,102,92,112,110,67,95,105,81,104,55,61,65,67,75,50,89,72,79,64,58,87,56,59,76,52,92,102,104,95,61,79,72,83,74,94,80,79,74,92,84,35,69,47,54,42,66,53,39,57,57,38,51,60,27,41,51,51,52,65,38,42,35,29,51,40,48,51,21,64,54,43,33,38,48,52,31,59,67,30,47,49,69,58,57,35,49,62,29,77,44,64,72,42,32,44,51,56,53,46,67,37,48,48,55,56,57,60,36,32,55,48,22,39,39,57,40,28,11,32,38,29,57,64,30,30,30,51,60,62,57,43,67,45,63,40,23,26,49,40,55,31,27,44,50,51,54,47,33,54,47,58,42,37,25,30,45,52,53,39,52,53,60,53,31,40,72,34,52,68,53,24,49,34,47,45,52,55,40,35,32,51,54,57,21,48,53,69,64,26,48,53,64,17,41,28,42,32,50,54,47,55,47,31,33,38,19,58,64,44,71,55,68,56,41,66,50,39,65,56,61,49,32,55,44,68,52,43,40,53,54,24,37,72,51,23,28,74,50,34,64,39,39,42,27,56,47,48,40,38,45,73,14,53,23,61,76,58,37,42,43,45,45,40,42,67,35,47,87,53,44,52,78,36,71,67,82,55,67,104,86,85,122,118,87,75,103,124,142,131,145,153,168,160,171,168,179,193,167,166,163,163,169,170,150,163,172,182,157,161,168,163,164,174,183,160,172,143,155,142,140,149,165,162,160,174,156,180,147,169,143,164,145,159,138,131,147,158,166,147,155,147,131,164,152,136,142,125,119,126,160,146,160,167,125,139,133,145,146,155,166,143,130,142,155,165,123,127,130,130,139,149,130,122,121,126,139,147,114,169,114,125,137,138,109,15,4,21,15,0,15,13,30,7,35,19,0,47,27,16,12,17,42,33,19,4,37,20,26,16,26,39,30,22,30,19,27,25,23,28,32,23,21,30,21,27,54,8,29,12,27,7,41,17,37,31,37,18,14,38,23,32,42,1,28,48,20,20,39,54,24,23,29,41,23,25,12,45,41,51,28,27,27,18,37,24,14,18,23,38,37,21,11,36,40,18,28,33,24,17,17,46,42,25,26,37,29,21,54,53,48,67,42,57,67,55,60,62,83,62,83,56,86,111,70,108,108,110,135,77,122,118,87,120,100,121,136,108,106,109,103,118,103,132,116,115,130,114,143,112,121,123,138,149,142,124,128,136,119,137,123,152,124,148,169,156,135,139,153,158,150,149,139,180,137,144,152,154,130,146,131,137,143,133,141,124,140,157,129,132,138,163,136,159,109,132,163,137,143,171,136,116,115,134,155,140,152,115,122,138,154,157,164,144,151,143,123,144,125,131,148,114,129,113,141,135,102,149,154,159,162,152,86,135,134,149,135,162,139,136,156,141,124,163,141,150,108,157,152,162,162,134,144,144,131,151,149,170,151,144,149,142,162,149,145,155,140,139,152,145,117,126,131,131,141,139,151,147,105,145,122,125,114,119,113,125,143,155,150,146,142,111,105,137,152,97,13,13,5,23,10,25,16,2,0,7,24,49,31,16,54,45,0,30,12,13,10,14,7,30,24,19,24,38,22,12,2,16,39,20,22,24,7,27,7,32,28,20,29,13,16,22,28,5,2,43,17,8,28,17,13,7,5,12,15,30,15,32,30,5,23,24,40,5,40,0,7,5,5,21,34,7,18,25,20,28,41,53,18,14,30,13,12,14,2,11,9,31,15,1,26,21,11,24,20,23,21,20,5,10,8,12,21,18,20,33,50,23,7,15,28,26,18,32,16,33,8,21,25,13,5,25,33,27,5,3,10,34,8,37,13,26,14,19,23,12,4,14,20,10,21,4,19,1,29,8,26,30,26,28,36,29,26,9,9,15,21,17,18,25,24,44,2,27,17,26,9,36,23,33,4,7,11,6,8,21,28,27,11,27,15,17,31,41,9,38,20,24,31,25,14,16,12,9,16,16,16,23,21,30,22,8,28,29,10,1,17,11,20,16,6,21,18,11,35,3,11,5,9,20,19,16,25,7,34,24,9,32,22,17,13,16,27,12,19,24,34,18,0,13,30,5,8,10,26,10,26,19,17,12,12,38,20,2,13,12,35,16,29,3,42,35,15,40,15,11,5,19,17,8,45,39,20,10,40,12,17,27,6,13,42,9,17,7,18,22,14,14,20,18,22,1,5,15,24,18,33,40,33,12,11,11,11,36,8,45,19,29,40,2,20,9,6,28,9,15,14,25,29,13,25,30,32,19,16,8,24,21,45,30,27,45,15,28,29,5,29,18,11,20,9,32,14,18,47,2,10,17,15,19,29,5,13,14,17,35,21,18,5,16,12,11,5,6,29,30,21,28,40,10,31,3,13,38,14,2,21,22,15,29,4,9,6,3,16,23,13,33,13,28,22,17,22,19,20,29,43,8,3,20,17,15,21,21,21,13,33,6,2,12,2,21,16,19,31,21,14,19,21,31,26,25,37,3,15,17,14,20,27,29,25,2,16,8,14,22,12,36,50,33,38,11,26,28,20,23,23,15,34,21,26,39,29,50,34,24,18,34,25,30,15,16,39,14,17,3,24,21,41,19,55,41,9,13,28,22,19,28,24,5,29,51,19,14,35,16,27,28,0,39,35,36,34,39,35,35,31,41,35,40,46,47,13,25,26,13,50,32,23,48,37,34,34,34,25,11,38,28,27,41,27,36,47,25,43,16,9,30,49,41,54,74,47,58,64,52,66,41,57,52,39,72,106,88,87,97,118,119,129,82,102,112,89,103,129,97,132,118,108,126,103,111,91,100,128,123,135,115,136,112,130,99,139,157,120,144,125,131,117,153,138,101,155,129,147,162,160,136,139,149,160,134,132,169,142,160,112,164,133,120,121,139,137,146,160,136,110,157,147,160,143,119,140,157,157,132,151,155,146,134,120,132,114,134,144,166,166,174,129,139,144,165,125,119,159,134,120,116,132,140,144,116,123,116,127,128,105,144,143,153,155,144,149,127,139,129,150,123,169,138,151,137,128,126,169,136,152,136,158,146,164,149,148,147,140,139,165,128,131,132,154,125,115,166,137,143,141,120,145,147,145,136,118,108,130,171,132,126,135,93,107,115,157,147,132,112,121,124,123,128,118,118,108,110,147,103,17,0,3,9,15,36,5,37,5,26,35,17,37,15,1,27,21,33,1,16,7,1,22,21,10,7,12,6,0,22,9,12,13,18,6,19,27,17,19,24,16,22,9,32,18,7,29,27,18,18,1,17,47,9,25,13,22,21,13,10,13,15,23,21,23,10,24,18,34,8,14,24,33,6,10,0,33,1,13,37,2,12,37,9,35,34,5,21,37,10,28,13,12,43,15,23,5,31,10,18,13,18,25,26,45,4,20,10,20,11,16,7,14,10,25,16,17,3,9,9,10,9,12,0,8,6,11,20,20,17,17,3,23,12,22,11,7,17,10,7,16,22,14,34,25,16,14,18,6,23,3,16,31,16,11,21,37,12,12,2,19,28,30,19,12,25,18,35,14,29,26,23,8,39,16,20,2,31,14,42,16,8,29,22,18,5,5,15,26,16,1,18,20,27,23,5,16,17,21,17,24,28,33,10,25,16,9,19,23,27,19,28,33,18,30,21,12,16,12,19,7,29,20,12,10,4,32,19,21,43,18,32,28,22,31,29,13,12,16,36,19,13,30,32,28,22,24,14,22,38,26,2,31,16,13,16,11,24,15,12,34,8,26,10,33,13,5,8,8,6,27,19,12,7,27,17,48,24,10,1,5,17,25,11,6,38,13,15,20,14,21,14,23,26,22,0,23,36,20,32,16,8,12,19,8,11,24,1,13,12,26,29,23,2,21,8,31,20,25,3,19,35,6,13,5,16,26,19,3,14,20,16,3,20,10,42,15,18,13,27,19,3,48,4,8,19,14,22,26,11,27,18,12,9,13,28,37,1,14,23,16,23,21,17,30,13,26,20,15,23,21,9,29,37,16,17,24,21,25,4,8,6,20,34,12,17,10,19,0,23,26,0,14,24,4,15,31,4,3,8,35,30,22,1,13,29,21,15,8,42,6,14,13,41,2,17,43,17,7,7,30,4,17,38,20,8,8,15,35,19,11,13,24,31,16,23,36,26,8,29,27, \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/estimation_16x16.txt b/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/estimation_16x16.txt deleted file mode 100644 index 7216dbcb..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/estimation_16x16.txt +++ /dev/null @@ -1,2 +0,0 @@ -30,45 -12,8;12,8;12,8;12,8;12,8;12,9;12,9;12,9;12,9;12,9;12,9;11,10;11,10;11,10;11,10;11,11;11,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,11;9,4;10,12;11,12;11,12;11,12;11,5;10,11;10,-1;12,8;12,8;12,8;12,8;12,8;12,9;12,9;12,9;12,9;12,9;12,10;11,10;11,10;11,10;11,10;11,11;11,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,11;11,13;11,11;11,12;11,12;11,12;10,9;10,11;10,-1;11,8;12,8;12,8;12,8;12,8;12,9;12,9;12,9;12,9;11,9;11,10;11,10;11,10;11,10;11,11;11,11;11,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;12,12;11,12;11,12;11,12;11,12;11,11;10,11;10,11;10,-1;12,8;12,8;12,8;12,8;12,9;11,9;11,9;11,9;11,9;11,9;11,10;11,10;11,10;11,11;11,11;11,11;11,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,13;11,14;10,13;10,8;10,11;10,0;12,8;12,8;12,8;12,8;11,9;11,9;11,9;11,9;11,9;11,10;11,10;11,10;12,11;11,11;11,11;11,11;12,11;12,12;12,12;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;10,13;9,13;10,24;10,12;10,11;10,0;11,8;11,8;12,8;12,9;11,9;10,9;11,9;11,9;11,10;11,10;11,10;11,10;11,11;11,11;9,10;11,11;12,12;13,12;12,12;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;10,12;10,13;10,9;10,7;9,11;9,0;11,8;11,9;10,9;11,9;11,9;10,9;10,9;10,9;11,10;11,10;11,10;11,11;11,11;11,11;11,11;11,12;11,12;11,12;11,12;11,12;11,12;12,11;12,11;12,11;12,11;12,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;10,12;10,10;9,11;9,11;9,0;11,9;11,9;10,9;10,9;10,9;10,9;9,9;10,10;10,10;11,10;11,11;11,11;11,11;11,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;12,11;12,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;10,12;10,11;9,9;9,10;9,11;9,0;11,9;11,9;11,9;10,9;10,9;9,9;7,9;9,10;10,10;11,10;11,11;11,11;12,12;12,12;11,12;11,12;12,12;19,14;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;10,12;10,12;10,12;8,-2;8,12;8,12;8,0;11,9;11,9;11,9;11,9;10,9;10,9;10,10;10,10;10,10;11,11;11,11;11,13;12,12;13,12;10,12;3,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;10,12;10,12;9,11;9,25;8,12;7,11;7,0;11,9;11,9;11,9;11,9;11,9;10,9;10,10;10,10;11,10;11,11;11,11;11,11;12,11;11,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;10,12;10,12;9,12;8,15;7,13;6,11;5,0;11,9;11,9;11,9;11,9;11,9;11,10;11,10;11,10;11,10;11,11;11,11;12,11;12,10;12,11;12,11;12,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;10,12;9,13;9,14;8,14;6,11;4,11;3,0;12,9;12,9;12,9;12,9;12,10;11,10;11,10;11,10;11,10;11,10;12,11;12,11;12,11;12,11;12,11;12,11;12,12;12,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;10,12;10,12;9,12;9,14;9,15;8,16;5,15;1,12;0,0;12,9;12,9;12,9;12,9;12,10;12,10;12,10;11,10;11,10;12,10;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;10,12;10,13;9,13;9,14;8,16;7,17;3,16;-2,12;-5,7;12,10;12,10;13,9;14,10;13,10;12,10;12,10;12,10;12,10;12,10;12,11;13,11;13,11;13,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;10,13;10,13;9,14;9,15;7,16;6,18;0,18;-8,12;-19,3;12,10;12,10;13,10;13,10;13,10;12,10;12,10;12,10;12,10;12,10;13,11;13,11;14,11;13,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;10,13;10,13;9,14;9,15;7,16;4,17;-1,17;-13,12;-30,-2;12,11;12,10;11,10;16,10;14,10;12,10;12,10;12,10;12,10;12,10;13,10;14,10;18,10;13,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,13;11,14;10,14;10,16;9,17;5,18;0,19;-12,14;-39,-11;12,11;12,11;12,10;12,10;12,10;12,10;12,11;12,11;12,11;12,11;12,10;12,10;12,10;12,10;12,11;12,11;12,11;12,11;12,11;12,11;12,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,13;11,13;11,13;10,14;9,15;8,16;7,18;3,19;-4,17;-13,6;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,13;11,13;11,13;10,13;9,14;8,15;7,17;5,17;1,15;-3,2;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,13;11,13;10,13;10,13;11,14;9,14;9,16;8,16;5,13;0,-2;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;10,12;10,12;10,13;9,13;9,14;9,14;8,13;3,-5;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;12,11;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;10,12;10,12;10,13;10,13;9,13;9,13;9,12;4,-7;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,13;10,12;10,12;10,13;10,13;10,13;10,13;10,13;10,12;6,3;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;10,13;10,13;10,13;10,12;10,12;10,13;10,13;11,14;10,14;8,12;2,-1;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,13;11,13;10,13;10,13;11,13;10,13;10,13;10,13;10,13;10,13;9,13;8,13;6,12;0,-6;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;10,13;10,13;10,13;10,13;10,13;10,13;10,13;10,14;11,14;10,14;10,14;8,14;5,13;-1,-10;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,13;11,12;11,12;11,12;11,12;11,12;11,12;11,13;11,13;10,13;11,13;11,13;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,12;11,13;11,13;11,13;11,14;10,14;9,13;9,13;9,13;9,14;9,14;9,14;9,14;9,14;9,14;7,13;5,12;2,0;10,13;10,12;9,12;9,12;10,12;11,12;11,13;10,13;10,12;10,12;10,12;11,12;11,12;11,13;10,13;10,13;10,13;10,13;10,13;11,13;11,12;11,13;11,13;11,13;11,12;11,12;11,12;11,13;11,13;10,14;10,14;9,15;9,15;10,15;8,13;8,13;8,15;7,14;6,13;7,13;8,14;8,14;5,13;4,12;2,-1;10,13;7,12;7,12;7,12;8,12;8,11;8,12;8,13;8,13;9,12;9,11;9,12;9,12;9,12;9,12;9,12;7,13;7,13;8,13;8,12;8,12;8,13;9,13;10,13;11,13;11,13;10,13;10,13;10,14;10,15;10,16;9,17;7,18;6,16;5,12;8,15;8,15;1,13;1,10;4,10;6,12;7,15;4,14;3,12;2,1;-1,13;5,12;6,12;4,12;6,11;5,9;2,5;3,6;0,1;6,9;6,10;3,10;6,11;4,11;3,10;3,10;1,8;-7,3;-6,-1;3,8;4,10;2,12;-11,13;1,13;-4,13;-6,13;-6,13;0,13;-3,14;0,15;0,15;1,16;-11,13;1,14;3,13;-2,5;-8,2;-17,-8;-3,0;0,6;1,10;2,11;-1,10;2,11;1,0; \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/exhaust_16x16.txt b/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/exhaust_16x16.txt deleted file mode 100644 index 719c3f04..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/exhaust_16x16.txt +++ /dev/null @@ -1,2 +0,0 @@ -30,45 -6,4;12,14;6,16;24,9;30,2;7,11;11,12;13,10;12,12;30,11;9,13;10,11;4,11;1,-7;7,-13;9,-32;1,-12;22,9;29,5;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;28,-9;12,12;12,12;12,12;12,12;10,5;12,12;0,-1;9,29;14,3;4,31;11,24;-10,7;5,23;-15,-32;13,6;13,6;0,6;27,3;10,9;12,11;14,3;2,-19;-4,14;16,-13;12,12;17,10;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;6,18;10,17;9,12;12,12;12,12;12,12;3,9;26,12;-16,-1;8,31;11,-10;17,-17;16,-22;13,14;10,18;12,12;12,11;20,-23;3,9;7,4;12,13;10,13;12,12;15,24;11,-6;12,12;12,12;11,11;12,11;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;14,9;12,12;12,12;12,12;12,12;24,17;4,11;17,12;-32,-1;12,8;13,11;13,-4;13,25;14,-26;12,12;20,-8;12,12;12,12;13,12;13,12;12,12;12,12;14,11;11,13;3,8;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;14,16;5,6;5,12;-32,-1;12,11;13,14;12,13;12,12;8,-2;12,20;11,13;12,14;12,12;12,12;10,7;11,-10;13,14;11,13;12,12;-16,-10;12,12;12,13;9,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;16,25;12,12;18,12;-32,-1;12,13;12,12;16,14;16,30;11,7;10,-4;11,15;12,12;9,22;13,15;11,-12;12,12;12,12;12,6;4,-22;12,12;12,12;15,24;12,9;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;15,9;19,6;27,12;-32,-1;11,5;13,26;6,-20;13,8;13,-2;8,-14;12,22;10,1;11,-14;13,24;15,10;14,17;12,-8;12,12;11,-9;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;5,12;-32,-1;12,12;9,-8;12,12;30,1;25,-3;12,12;12,17;8,14;8,24;8,-2;7,20;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;8,16;8,10;12,12;-32,-1;9,11;5,6;14,1;-4,27;12,12;19,7;-18,-32;22,-20;11,20;11,16;10,20;12,12;12,12;12,12;12,12;12,12;12,12;31,-22;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;7,-4;12,12;13,12;-32,-1;12,12;12,12;11,4;12,12;12,20;12,7;12,12;10,20;13,8;19,-1;12,11;24,19;13,8;14,6;11,9;2,16;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;11,11;14,26;17,12;12,12;-32,-1;20,18;10,10;15,-17;14,-2;12,12;11,26;13,27;10,12;13,14;23,9;8,20;17,0;12,12;12,11;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;10,13;12,1;13,12;-32,-1;16,11;12,12;9,13;22,0;-32,-5;9,8;15,6;-8,-2;12,12;10,-21;12,3;12,12;8,3;12,12;12,12;12,23;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;11,11;7,12;31,-1;8,16;11,7;11,18;11,9;12,3;13,-4;5,24;8,17;12,12;12,14;12,12;-9,14;7,-2;12,16;15,6;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,14;11,12;21,-1;13,20;27,-9;11,6;14,8;7,22;19,7;4,1;-24,21;12,19;11,18;9,-24;14,-20;12,7;13,-28;10,15;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;13,12;24,-32;14,5;9,18;25,-26;24,-27;12,11;10,16;7,26;12,12;17,17;13,4;6,18;12,20;30,3;16,17;12,16;12,12;12,-21;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;6,-32;12,12;12,12;-16,11;12,12;10,11;25,-9;27,5;22,28;8,13;13,3;12,30;-5,-8;18,-31;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;-9,-32;13,12;12,12;12,3;18,29;15,-9;1,19;-9,14;-3,-3;-21,8;13,6;-12,12;-2,-13;20,-32;-19,-31;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;-24,-30;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;27,-1;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;11,-1;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;-5,-1;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;-21,-1;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,15;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;-29,-1;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;17,-1;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;1,-1;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;-15,-1;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;-31,-1;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,9;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;3,-1;12,12;12,12;17,20;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;-13,-1;12,12;12,12;-8,25;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;21,-1;-2,5;-3,25;-18,27;1,-31;0,17;-9,26;-23,27;-23,20;-27,18;1,30;3,15;0,0;3,22;3,5;0,0;0,0;0,0;-17,-18;-15,-16;-1,15;-4,9;2,11;-13,-2;2,13;-5,16;-7,-2;-7,7;0,18;-5,-11;0,-10;0,0;2,-5;-5,-32;4,-27;2,21;-8,7;-8,1;-17,-10;-4,-1;-13,0;-8,5;1,10;0,-1;4,12;5,-1; \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/ground_truth_16x16.txt b/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/ground_truth_16x16.txt deleted file mode 100644 index 850b7eda..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/ground_truth_16x16.txt +++ /dev/null @@ -1,2 +0,0 @@ -30,45 -12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12;12,12; \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/localVar_16x16.txt b/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/localVar_16x16.txt deleted file mode 100644 index 5e4ea8ee..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/localVar_16x16.txt +++ /dev/null @@ -1,2 +0,0 @@ -30,45 -0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;1,0,0,0;0,0,0,0;0,0,0,1;0,0,0,0;0,0,0,0;0,0,0,1;0,0,0,0;1,0,0,0;1,0,0,0;0,0,0,0;0,0,0,0;1,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;1,2,2,4;25,115,115,529;196,644,644,2116;225,420,420,784;576,696,696,841;4900,3920,3920,3136;9604,6664,6664,4624;9,120,120,1600;1024,2208,2208,4761;3249,5016,5016,7744;484,1870,1870,7225;9,288,288,9216;64,384,384,2304;324,882,882,2401;10404,8058,8058,6241;1936,2332,2332,2809;196,322,322,529;1,10,10,100;4,16,16,64;4,100,100,2500;1156,2482,2482,5329;3600,5160,5160,7396;81,594,594,4356;0,0,0,1521;0,0,0,10000;1,134,134,17956;0,0,0,0;0,0,0,0;0,0,0,0;1,0,0,0;0,0,0,0;1,0,0,0;0,0,0,0;1,0,0,0;1,0,0,0;0,0,0,0;1,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,4;25,110,110,484;196,560,560,1600;529,713,713,961;1296,2196,2196,3721;4096,6784,6784,11236;6889,9960,9960,14400;441,1659,1659,6241;1764,2520,2520,3600;4225,4875,4875,5625;529,2208,2208,9216;36,558,558,8649;36,276,276,2116;529,1564,1564,4624;9801,11088,11088,12544;3600,4620,4620,5929;225,360,360,576;4,2,2,1;1,9,9,81;1,44,44,1936;2025,3060,3060,4624;4624,4760,4760,4900;16,168,168,1764;0,0,0,1681;0,0,0,10609;1,133,133,17689;9,0,0,0;1,0,0,0;4,0,0,0;9,0,0,0;9,0,0,0;1,0,0,0;1,0,0,0;1,0,0,0;1,0,0,0;1,1,1,1;0,0,0,0;0,0,0,0;0,0,0,0;1,-1,-1,1;0,0,0,0;1,0,0,0;1,0,0,0;1,0,0,0;0,0,0,0;0,0,0,9;81,198,198,484;225,540,540,1296;2209,2162,2162,2116;6400,5760,5760,5184;6241,7347,7347,8649;7396,7998,7998,8649;8464,7084,7084,5929;2916,4104,4104,5776;3249,6498,6498,12996;784,3724,3724,17689;400,1820,1820,8281;784,1288,1288,2116;1849,1935,1935,2025;8649,4650,4650,2500;4624,3060,3060,2025;1089,891,891,729;625,175,175,49;81,0,0,0;441,693,693,1089;3969,4347,4347,4761;2809,2862,2862,2916;0,0,0,0;0,0,0,2116;0,0,0,10816;1,134,134,17956;1,1,1,1;16,0,0,0;25,0,0,0;9,0,0,0;25,0,0,0;1,0,0,0;1,0,0,0;4,0,0,0;9,0,0,0;9,0,0,0;9,3,3,1;9,3,3,1;1,0,0,0;4,2,2,1;1,0,0,0;0,0,0,0;4,2,2,1;4,4,4,4;1,0,0,0;1,4,4,16;196,378,378,729;256,784,784,2401;4624,4692,4692,4761;16384,8960,8960,4900;6889,4067,4067,2401;8649,3534,3534,1444;17689,8246,8246,3844;6889,8798,8798,11236;4761,8832,8832,16384;1024,4032,4032,15876;3136,5656,5656,10201;6400,5920,5920,5476;5776,5700,5700,5625;6724,7626,7626,8649;2916,5130,5130,9025;7744,6688,6688,5776;5184,3528,3528,2401;4225,2665,2665,1681;4356,3564,3564,2916;7056,3528,3528,1764;2500,600,600,144;1,0,0,0;0,0,0,225;0,0,0,10404;1,-135,-135,18225;16,0,0,0;25,5,5,1;25,0,0,0;36,0,0,0;16,0,0,0;9,0,0,0;9,0,0,0;9,0,0,0;9,3,3,1;16,0,0,0;25,0,0,0;25,0,0,0;25,10,10,4;4,4,4,4;4,6,6,9;1,0,0,0;4,2,2,1;1,0,0,0;0,0,0,0;1,9,9,81;576,720,720,900;100,450,450,2025;1849,1763,1763,1681;8464,5796,5796,3969;3969,5733,5733,8281;5041,6177,6177,7569;7921,7476,7476,7056;8100,7740,7740,7396;6561,6075,6075,5625;1296,2088,2088,3364;4489,3618,3618,2916;7056,4368,4368,2704;5041,4331,4331,3721;4900,5530,5530,6241;1849,3311,3311,5929;7225,4930,4930,3364;6084,3744,3744,2304;7396,5934,5934,4761;6241,7110,7110,8100;8100,8730,8730,9409;5184,5688,5688,6241;1,35,35,1225;1,54,54,2916;0,0,0,11881;1,-137,-137,18769;64,0,0,0;49,0,0,0;16,-4,-4,1;25,0,0,0;25,0,0,0;36,0,0,0;25,0,0,0;36,0,0,0;16,0,0,0;9,0,0,0;16,0,0,0;9,0,0,0;25,0,0,0;25,0,0,0;16,4,4,1;100,10,10,1;49,14,14,4;25,10,10,4;36,0,0,0;36,96,96,256;1764,1680,1680,1600;1600,1880,1880,2209;1024,1184,1184,1369;1681,1517,1517,1369;2704,3484,3484,4489;2025,3330,3330,5476;2809,2915,2915,3025;4489,5293,5293,6241;5329,6132,6132,7056;1764,2100,2100,2500;3025,2090,2090,1444;3249,1596,1596,784;1764,2310,2310,3025;4489,6164,6164,8464;1521,2808,2808,5184;729,810,810,900;900,330,330,121;1764,882,882,441;2025,1530,1530,1156;5041,5467,5467,5929;3136,4144,4144,5476;0,0,0,676;0,0,0,289;0,0,0,12321;1,-139,-139,19321;9,0,0,0;9,0,0,0;36,0,0,0;9,0,0,0;4,0,0,0;9,0,0,0;9,0,0,0;9,0,0,0;9,0,0,0;9,0,0,0;4,0,0,0;9,0,0,0;9,0,0,0;121,0,0,0;36,0,0,0;1089,231,231,49;1225,210,210,36;1369,185,185,25;1225,245,245,49;1764,1218,1218,841;3364,3654,3654,3969;3969,5292,5292,7056;4761,5313,5313,5929;2704,2964,2964,3249;2209,3290,3290,4900;1681,2952,2952,5184;3721,4453,4453,5329;12321,12432,12432,12544;9025,9405,9405,9801;2116,2392,2392,2704;2704,2704,2704,2704;2304,2256,2256,2209;1089,2244,2244,4624;4761,7176,7176,10816;900,1890,1890,3969;100,150,150,225;324,342,342,361;576,600,600,625;441,945,945,2025;3600,4860,4860,6561;441,1092,1092,2704;1,2,2,4;0,0,0,3025;0,0,0,12100;0,0,0,19881;0,0,0,0;0,0,0,0;1,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;1,0,0,0;1,0,0,0;1,0,0,0;1,0,0,0;4,0,0,0;9,0,0,0;9,18,18,36;256,320,320,400;1600,720,720,324;2209,611,611,169;3249,798,798,196;3364,522,522,81;3600,600,600,100;4761,1725,1725,625;2916,2376,2376,1936;2809,2703,2703,2601;6084,3900,3900,2500;3844,2914,2914,2209;3249,2850,2850,2500;3600,3480,3480,3364;9025,7505,7505,6241;19321,15846,15846,12996;6889,9545,9545,13225;1225,2485,2485,5041;1600,1640,1640,1681;961,1147,1147,1369;729,1431,1431,2809;4489,5025,5025,5625;400,920,920,2116;81,108,108,144;576,336,336,196;576,552,552,529;289,1139,1139,4489;2304,3984,3984,6889;4,58,58,841;0,0,0,0;0,0,0,1849;0,0,0,12544;1,-144,-144,20736;1,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;9,0,0,0;0,0,0,0;4,0,0,0;4,0,0,0;4,0,0,0;16,0,0,0;9,0,0,0;121,11,11,1;484,22,22,1;576,24,24,1;1024,32,32,1;529,138,138,36;1681,451,451,121;2304,2928,2928,3721;3969,5355,5355,7225;4096,3776,3776,3481;6889,4980,4980,3600;3249,4161,4161,5329;1296,3276,3276,8281;4900,7280,7280,10816;17424,15972,15972,14641;8100,11070,11070,15129;3600,5100,5100,7225;576,1272,1272,2809;841,1102,1102,1444;400,620,620,961;144,228,228,361;1936,924,924,441;225,315,315,441;25,125,125,625;1444,1292,1292,1156;256,480,480,900;169,728,728,3136;1156,2754,2754,6561;9,117,117,1521;4,68,68,1156;9,174,174,3364;1,114,114,12996;1,-149,-149,22201;4,0,0,0;1,0,0,0;1,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;1,0,0,0;4,0,0,0;4,0,0,0;1,0,0,0;1,0,0,0;0,0,0,25;4,0,0,0;196,0,0,0;400,0,0,0;400,0,0,0;1225,315,315,81;2116,414,414,81;1936,616,616,196;2601,1530,1530,900;5929,4774,4774,3844;4624,4964,4964,5329;7225,4760,4760,3136;3969,3276,3276,2704;1024,2560,2560,6400;9216,9600,9600,10000;12321,10989,10989,9801;5476,7104,7104,9216;3364,4292,4292,5476;289,578,578,1156;676,286,286,121;256,96,96,36;49,105,105,225;784,672,672,576;144,180,180,225;64,136,136,289;1444,988,988,676;144,252,252,441;144,696,696,3364;1296,3132,3132,7569;1,46,46,2116;4,94,94,2209;1,61,61,3721;0,0,0,14400;1,-150,-150,22500;0,0,0,0;1,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;1,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;9,48,48,256;900,600,600,400;1521,507,507,169;1936,440,440,100;3364,580,580,100;4225,585,585,81;3969,693,693,121;4225,1755,1755,729;4356,3234,3234,2401;3136,2912,2912,2704;5776,3192,3192,1764;5041,3550,3550,2500;4624,5236,5236,5929;13456,10672,10672,8464;7744,8096,8096,8464;4225,4290,4290,4356;2601,2499,2499,2401;324,720,720,1600;676,728,728,784;169,286,286,484;256,288,288,324;1369,851,851,529;289,374,374,484;225,300,300,400;961,651,651,441;196,280,280,400;256,768,768,2304;1681,3772,3772,8464;1,53,53,2809;1,0,0,0;0,0,0,0;0,0,0,14161;0,0,0,22801;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;1,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,9;256,0,0,0;441,0,0,0;625,50,50,4;784,56,56,4;1089,132,132,16;841,232,232,64;2025,945,945,441;2116,2162,2162,2209;1296,2268,2268,3969;3025,2585,2585,2209;6084,4992,4992,4096;5476,5550,5550,5625;6084,3900,3900,2500;5041,2911,2911,1681;1225,1365,1365,1521;2025,1980,1980,1936;784,980,980,1225;961,682,682,484;529,552,552,576;1156,1258,1258,1369;2209,2021,2021,1849;576,744,744,961;625,650,650,676;961,930,930,900;576,432,432,324;289,884,884,2704;3025,4895,4895,7921;2209,1974,1974,1764;16,0,0,0;16,204,204,2601;1,118,118,13924;1,141,141,19881;0,0,0,0;0,0,0,0;1,0,0,0;0,0,0,0;1,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;1,0,0,0;1,0,0,0;1,0,0,0;0,0,0,9;0,0,0,0;1,0,0,0;1,0,0,0;9,3,3,1;9,6,6,4;16,8,8,4;16,68,68,289;1681,1681,1681,1681;2401,2842,2842,3364;576,1560,1560,4225;1296,2556,2556,5041;8836,8272,8272,7744;2116,2668,2668,3364;1600,1120,1120,784;2025,1530,1530,1156;1444,1330,1330,1225;1849,1677,1677,1521;400,740,740,1369;1444,1596,1596,1764;676,1222,1222,2209;1849,2107,2107,2401;1521,1677,1677,1849;676,1066,1066,1681;1521,1716,1716,1936;441,882,882,1764;900,1230,1230,1681;256,784,784,2401;3136,3472,3472,3844;7396,6450,6450,5625;3136,2352,2352,1764;256,1056,1056,4356;1,107,107,11449;4,278,278,19321;0,0,0,0;0,0,0,0;0,0,0,0;1,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;1,0,0,0;1,0,0,0;1,0,0,0;1,0,0,0;1,0,0,0;4,0,0,0;4,0,0,0;4,0,0,0;4,0,0,0;4,0,0,0;9,6,6,4;100,390,390,1521;3136,3304,3304,3481;3844,3100,3100,2500;484,1254,1254,3249;4624,5916,5916,7569;10201,8585,8585,7225;1024,1536,1536,2304;1369,1591,1591,1849;2025,1710,1710,1444;1600,1400,1400,1225;1369,1369,1369,1369;400,680,680,1156;1369,1147,1147,961;1521,1131,1131,841;2025,1080,1080,576;1521,897,897,529;1521,1014,1014,676;2209,1598,1598,1156;441,609,609,841;1024,832,832,676;361,627,627,1089;1521,1326,1326,1156;3136,2632,2632,2209;8100,5940,5940,4356;3136,5488,5488,9604;9,393,393,17161;7056,5376,5376,4096;0,0,0,0;0,0,0,0;0,0,0,1;9,0,0,0;0,0,0,0;0,0,0,0;0,0,0,1;0,0,0,0;0,0,0,0;0,0,0,0;1,0,0,0;1,0,0,0;0,0,0,0;9,0,0,0;144,0,0,0;256,0,0,0;100,0,0,0;256,112,112,49;576,408,408,289;3025,1925,1925,1225;2704,2808,2808,2916;1764,2814,2814,4489;7744,6864,6864,6084;5329,5256,5256,5184;1369,1850,1850,2500;961,1302,1302,1764;1521,1560,1560,1600;1936,1628,1628,1369;1600,1400,1400,1225;1600,1280,1280,1024;1681,1517,1517,1369;3249,2451,2451,1849;2401,1960,1960,1600;2209,1504,1504,1024;2209,1598,1598,1156;2209,2021,2021,1849;1089,1221,1221,1369;1369,1258,1258,1156;1156,1190,1190,1225;1521,1287,1287,1089;1156,1088,1088,1024;3969,3528,3528,3136;4096,6720,6720,11025;25,670,670,17956;8836,6298,6298,4489;0,0,0,1;9,3,3,1;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;1,0,0,0;0,0,0,0;0,0,0,81;400,280,280,196;900,210,210,49;784,140,140,25;961,589,589,361;1369,1221,1221,1089;2401,2107,2107,1849;2704,3068,3068,3481;4624,4556,4556,4489;4489,3819,3819,3249;2025,1845,1845,1681;1521,1287,1287,1089;961,1116,1116,1296;1225,1365,1365,1521;3136,2072,2072,1369;2704,1976,1976,1444;2401,1960,1960,1600;2704,1820,1820,1225;2601,1530,1530,900;1225,1015,1015,841;1764,1218,1218,841;2209,1645,1645,1225;1444,1406,1406,1369;1444,1406,1406,1369;1681,1722,1722,1764;2025,1980,1980,1936;2809,1802,1802,1156;1849,1849,1849,1849;2601,3672,3672,5184;2916,6912,6912,16384;16,660,660,27225;7921,5785,5785,4225;1,6,6,36;400,120,120,36;144,36,36,9;225,0,0,0;64,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;64,0,0,0;0,0,0,0;0,0,0,0;361,0,0,0;1,0,0,0;256,16,16,1;576,24,24,1;961,217,217,49;2304,1248,1248,676;3136,2856,2856,2601;2916,3402,3402,3969;4225,3835,3835,3481;3025,2970,2970,2916;1681,1804,1804,1936;1156,1088,1088,1024;1600,1320,1320,1089;625,825,825,1089;1024,768,768,576;2401,686,686,196;3025,935,935,289;2209,1081,1081,529;3136,1344,1344,576;2401,1519,1519,961;729,999,999,1369;1600,1600,1600,1600;2025,1845,1845,1681;1225,1400,1400,1600;1849,946,946,484;2209,658,658,196;2025,1170,1170,676;2601,765,765,225;2601,1224,1224,576;3136,3360,3360,3600;3025,5500,5500,10000;225,1905,1905,16129;7569,6438,6438,5476;676,910,910,1225;4225,2210,2210,1156;1444,684,684,324;1521,39,39,1;1444,38,38,1;1444,152,152,16;1296,468,468,169;1296,576,576,256;1024,480,480,225;961,496,496,256;1156,544,544,256;1369,666,666,324;1600,680,680,289;625,275,275,121;841,348,348,144;1600,920,920,529;2209,2021,2021,1849;3481,3304,3304,3136;5041,3550,3550,2500;3844,3162,3162,2601;4225,3120,3120,2304;1369,1295,1295,1225;625,800,800,1024;841,1218,1218,1764;1521,1092,1092,784;225,255,255,289;784,588,588,441;961,558,558,324;1849,817,817,361;1521,741,741,361;1764,756,756,324;2116,828,828,324;900,660,660,484;1444,950,950,625;1444,874,874,529;1296,792,792,484;1369,703,703,361;1936,968,968,484;1089,660,660,400;1156,714,714,441;2209,1504,1504,1024;1444,1064,1064,784;1444,1558,1558,1681;529,1426,1426,3844;144,756,756,3969;1521,3315,3315,7225;3600,4320,4320,5184;2401,1666,1666,1156;2116,460,460,100;2025,405,405,81;2401,490,490,100;2025,540,540,144;1296,612,612,289;1936,1364,1364,961;1936,1672,1672,1444;1444,1064,1064,784;1089,528,528,256;1681,1066,1066,676;1936,1496,1496,1156;1849,1419,1419,1089;2116,2070,2070,2025;4096,4096,4096,4096;2809,3445,3445,4225;5776,5624,5624,5476;2916,3348,3348,3844;1521,1053,1053,729;1156,1020,1020,900;289,578,578,1156;676,702,702,729;1089,1089,1089,1089;400,500,500,625;400,220,220,121;169,156,156,144;400,240,240,144;361,133,133,49;289,187,187,121;529,322,322,196;324,180,180,100;576,216,216,81;441,252,252,144;400,240,240,144;256,144,144,81;529,276,276,144;400,320,320,256;484,594,594,729;1156,1088,1088,1024;625,525,525,441;729,945,945,1225;225,750,750,2500;144,732,732,3721;1225,2450,2450,4900;576,1296,1296,2916;2209,1175,1175,625;676,364,364,196;1296,576,576,256;1296,756,756,441;900,630,630,441;1600,840,840,441;5041,1562,1562,484;5041,1917,1917,729;5041,2059,2059,841;3721,1952,1952,1024;676,962,962,1369;1444,1292,1292,1156;784,840,840,900;1024,1440,1440,2025;4624,3876,3876,3249;3136,2912,2912,2704;5476,2738,2738,1369;1849,731,731,289;961,620,620,400;676,572,572,484;441,399,399,361;1369,999,999,729;1024,960,960,900;729,810,810,900;324,324,324,324;144,72,72,36;36,30,30,25;25,15,15,9;36,24,24,16;9,12,12,16;36,24,24,16;81,54,54,36;49,42,42,36;25,20,20,16;25,15,15,9;49,42,42,36;81,81,81,81;3969,1512,1512,576;2025,1530,1530,1156;2209,1269,1269,729;2401,2107,2107,1849;400,1220,1220,3721;144,720,720,3600;2025,3330,3330,5476;3249,4788,4788,7056;3844,4402,4402,5041;2500,2350,2350,2209;3721,3477,3477,3249;2601,2703,2703,2809;1369,1554,1554,1764;3136,3472,3472,3844;8100,5490,5490,3721;9604,4410,4410,2025;14884,5002,5002,1681;10609,5768,5768,3136;2401,2450,2450,2500;2401,1176,1176,576;2025,1125,1125,625;2601,1683,1683,1089;5776,3192,3192,1764;3249,2964,2964,2704;3481,3186,3186,2916;1849,1935,1935,2025;1296,1224,1224,1156;676,702,702,729;729,837,837,961;1296,1260,1260,1225;900,900,900,900;729,702,702,676;441,252,252,144;289,170,170,100;64,128,128,256;81,72,72,64;25,20,20,16;16,12,12,9;9,9,9,9;49,49,49,49;81,72,72,64;25,20,20,16;9,3,3,1;9,3,3,1;25,295,295,3481;8281,9737,9737,11449;5329,6935,6935,9025;4225,4355,4355,4489;3969,4032,4032,4096;729,2430,2430,8100;144,744,744,3844;2916,3618,3618,4489;5476,4366,4366,3481;2809,2385,2385,2025;4624,3400,3400,2500;4489,4489,4489,4489;2401,2352,2352,2304;2209,1410,1410,900;2500,2100,2100,1764;6889,4399,4399,2809;8464,5060,5060,3025;11881,5886,5886,2916;7569,5220,5220,3600;5184,5040,5040,4900;5184,5112,5112,5041;5625,5625,5625,5625;6400,6800,6800,7225;8281,8190,8190,8100;2916,3564,3564,4356;2209,1974,1974,1764;1936,1584,1584,1296;625,675,675,729;841,870,870,900;484,660,660,900;625,550,550,484;729,702,702,676;676,728,728,784;169,169,169,169;100,0,0,0;25,20,20,16;144,96,96,64;9,9,9,9;4,0,0,0;1,1,1,1;9,15,15,25;81,81,81,81;81,63,63,49;4,4,4,4;1,0,0,0;16,104,104,676;4356,4356,4356,4356;5476,5328,5328,5184;2401,3332,3332,4624;3844,5332,5332,7396;900,3060,3060,10404;121,638,638,3364;3721,5063,5063,6889;4225,3575,3575,3025;4096,2176,2176,1156;5041,2982,2982,1764;4096,2688,2688,1764;4096,2816,2816,1936;3249,3477,3477,3721;3136,4032,4032,5184;5041,4899,4899,4761;5184,4680,4680,4225;5184,4464,4464,3844;3969,4032,4032,4096;4900,4410,4410,3969;5625,4500,4500,3600;6400,5120,5120,4096;5776,4560,4560,3600;5476,3774,3774,2601;1681,1722,1722,1764;1156,1088,1088,1024;1156,986,986,841;289,374,374,484;576,480,480,400;400,420,420,441;289,289,289,289;289,204,204,144;225,150,150,100;49,42,42,36;1,1,1,1;1,1,1,1;25,20,20,16;81,45,45,25;1,3,3,9;1,1,1,1;0,0,0,1;9,21,21,49;225,195,195,169;64,64,64,64;1,3,3,9;784,784,784,784;4624,3468,3468,2601;4761,2691,2691,1521;3969,2205,2205,1225;6084,4056,4056,2704;1296,2412,2412,4489;529,1426,1426,3844;4225,5980,5980,8464;4225,4875,4875,5625;5041,4544,4544,4096;4356,4422,4422,4489;3364,4292,4292,5476;5776,5700,5700,5625;4761,4278,4278,3844;3844,3534,3534,3249;4225,3770,3770,3364;4225,3315,3315,2601;4356,2838,2838,1849;3136,1904,1904,1156;3136,1792,1792,1024;4489,2345,2345,1225;4900,2170,2170,961;3364,1682,1682,841;2209,1739,1739,1369;784,1064,1064,1444;529,667,667,841;441,462,462,484;361,323,323,289;256,256,256,256;196,182,182,169;49,28,28,16;9,3,3,1;9,15,15,25;100,90,90,81;49,56,56,64;9,6,6,4;4,6,6,9;144,84,84,49;1,4,4,16;1,2,2,4;0,0,0,1;4,6,6,9;121,99,99,81;121,132,132,144;361,646,646,1156;2304,3504,3504,5329;5184,5112,5112,5041;4489,2613,2613,1521;5776,1672,1672,484;5041,4402,4402,3844;576,2496,2496,10816;529,1403,1403,3721;2916,4320,4320,6400;3136,4480,4480,6400;5184,5544,5544,5929;5929,5467,5467,5041;3481,3717,3717,3969;4489,4355,4355,4225;5929,5313,5313,4761;3969,4725,4725,5625;3136,3584,3584,4096;2401,2156,2156,1936;2601,1836,1836,1296;1936,1452,1452,1089;1681,861,861,441;1936,308,308,49;1936,176,176,16;1600,560,560,196;1849,1290,1290,900;1156,918,918,729;1369,777,777,441;324,306,306,289;225,150,150,100;64,40,40,25;9,3,3,1;1,0,0,0;1,0,0,0;1,0,0,0;16,16,16,16;81,99,99,121;100,110,110,121;49,42,42,36;196,84,84,36;169,52,52,16;36,12,12,4;1,3,3,9;49,35,35,25;121,44,44,16;361,361,361,361;3364,1914,1914,1089;3481,2301,2301,1521;4356,4686,4686,5041;2704,4524,4524,7569;3364,4698,4698,6561;2304,4992,4992,10816;324,2376,2376,17424;529,1449,1449,3969;2401,2450,2450,2500;2209,2115,2115,2025;3249,1881,1881,1089;3136,1848,1848,1089;2304,2016,2016,1764;1936,2332,2332,2809;3969,3843,3843,3721;2916,2700,2700,2500;1156,816,816,576;676,234,234,81;841,174,174,36;961,248,248,64;784,168,168,36;484,132,132,36;529,184,184,64;841,464,464,256;961,1054,1054,1156;1764,2772,2772,4356;3025,3795,3795,4761;1024,896,896,784;1024,64,64,4;625,0,0,0;400,20,20,1;121,11,11,1;1,0,0,0;0,0,0,0;1,0,0,0;16,8,8,4;64,80,80,100;225,330,330,484;225,405,405,729;529,598,598,676;324,324,324,324;169,156,156,144;121,143,143,169;289,391,391,529;2500,2750,2750,3025;2304,2448,2448,2601;1444,608,608,256;1681,615,615,225;1296,612,612,289;961,589,589,361;1444,2166,2166,3249;324,1674,1674,8649;484,1386,1386,3969;1521,78,78,4;441,21,21,1;324,18,18,1;121,55,55,25;400,300,300,225;841,464,464,256;1369,481,481,169;1369,777,777,441;361,285,285,225;225,75,75,25;225,45,45,9;256,48,48,9;256,48,48,9;225,30,30,4;196,42,42,9;324,162,162,81;225,210,210,196;841,435,435,225;1156,1020,1020,900;2704,3172,3172,3721;3136,4256,4256,5776;2704,3692,3692,5041;2209,2538,2538,2916;1156,1020,1020,900;484,242,242,121;361,19,19,1;256,0,0,0;196,-14,-14,1;196,0,0,0;484,22,22,1;900,90,90,9;1600,280,280,49;841,725,725,625;576,744,744,961;64,184,184,529;441,1029,1029,2401;2500,2500,2500,2500;81,99,99,121;25,20,20,16;121,132,132,144;196,168,168,144;81,54,54,36;121,440,440,1600;64,608,608,5776;49,784,784,12544;324,306,306,289;1,8,8,64;0,0,0,0;0,0,0,4;9,12,12,16;169,52,52,16;196,84,84,36;400,480,480,576;196,364,364,676;81,72,72,64;49,28,28,16;100,60,60,36;81,45,45,25;64,40,40,25;81,45,45,25;81,54,54,36;100,90,90,81;169,182,182,196;196,168,168,144;841,145,145,25;784,84,84,9;1089,297,297,81;1156,544,544,256;1225,910,910,676;1369,1295,1295,1225;1156,1122,1122,1089;676,572,572,484;529,368,368,256;625,375,375,225;841,638,638,484;2401,1617,1617,1089;5929,3619,3619,2209;4489,2881,2881,1849;1600,680,680,289;16,56,56,196;441,966,966,2116;1600,1560,1560,1521;36,48,48,64;1,2,2,4;16,12,12,9;64,64,64,64;81,99,99,121;64,328,328,1681;1,71,71,5041;49,777,777,12321;289,17,17,1;0,0,0,0;0,0,0,1;0,0,0,1;4,4,4,4;9,3,3,1;25,45,45,81;121,297,297,729;144,288,288,576;36,36,36,36;25,10,10,4;64,16,16,4;49,21,21,9;64,16,16,4;49,14,14,4;81,36,36,16;64,64,64,64;121,132,132,144;196,210,210,225;64,80,80,100;9,12,12,16;64,16,16,4;144,12,12,1;441,21,21,1;961,0,0,0;729,0,0,0;441,0,0,0;361,0,0,0;400,0,0,0;900,150,150,25;3249,969,969,289;8281,3458,3458,1444;10000,6700,6700,4489;3025,3795,3795,4761;16,120,120,900;400,340,340,289;2500,2100,2100,1764;64,248,248,961;4,12,12,36;4,4,4,4;36,12,12,4;121,99,99,81;144,480,480,1600;4,138,138,4761;64,592,592,5476;576,0,0,0;0,0,0,0;0,0,0,1;49,0,0,0;1,2,2,4;9,6,6,4;169,182,182,196;64,120,120,225;81,108,108,144;16,4,4,1;25,10,10,4;49,14,14,4;49,14,14,4;64,8,8,1;25,10,10,4;16,8,8,4;16,12,12,9;36,18,18,9;25,30,30,36;64,40,40,25;9,9,9,9;4,4,4,4;729,0,0,0;9,0,0,0;961,0,0,0;961,0,0,0;676,0,0,0;289,0,0,0;529,0,0,0;289,0,0,0;784,56,56,4;1936,88,88,4;784,140,140,25;3721,244,244,16;16,12,12,9;100,100,100,100;1849,1247,1247,841;1024,992,992,961;1,20,20,400;4,6,6,9;16,4,4,1;25,15,15,9;81,36,36,16;1,15,15,225;9,213,213,5041; \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/raw_1.png b/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/raw_1.png deleted file mode 100644 index ebf23e3c..00000000 Binary files a/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/raw_1.png and /dev/null differ diff --git a/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/raw_1_12_12.png b/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/raw_1_12_12.png deleted file mode 100644 index 92941218..00000000 Binary files a/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/raw_1_12_12.png and /dev/null differ diff --git a/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/ref_frame_16x16.txt b/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/ref_frame_16x16.txt deleted file mode 100644 index b1a877a2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/build_debug/non_greedy_mv_test_files/ref_frame_16x16.txt +++ /dev/null @@ -1,2 +0,0 @@ -486,720 -214,214,214,213,214,212,213,215,214,214,215,214,214,214,215,214,214,214,214,216,214,214,214,214,216,215,215,214,214,216,217,216,215,214,217,217,218,217,217,215,216,217,215,218,216,216,218,217,218,219,218,216,219,218,218,220,219,219,219,220,222,219,222,222,222,223,222,223,224,223,222,225,223,224,224,223,225,224,224,224,224,224,225,224,226,226,223,224,226,226,226,226,224,224,227,225,226,227,227,226,225,225,224,224,227,227,227,228,227,229,230,228,230,230,228,229,230,230,230,230,229,229,230,230,230,232,232,233,230,230,231,232,233,232,233,233,232,233,233,231,233,233,233,235,234,235,237,238,236,235,236,236,237,237,236,237,236,236,238,239,239,241,241,240,241,240,240,239,240,240,239,241,240,241,242,241,242,242,242,242,242,243,244,244,245,244,244,244,243,243,244,244,244,243,243,244,245,245,243,244,245,246,246,244,244,245,247,247,245,245,244,247,245,245,246,244,245,245,245,245,245,245,245,245,244,245,246,246,247,247,247,246,247,247,247,247,247,247,247,247,245,245,247,247,247,247,246,247,247,247,247,246,246,247,247,247,246,246,247,247,247,247,247,246,246,246,246,246,247,247,247,247,248,247,247,247,247,247,247,247,247,248,248,247,248,246,247,246,247,247,247,247,247,247,249,241,234,247,247,247,250,249,249,252,252,252,251,251,252,252,252,252,252,252,253,253,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,252,252,253,253,252,252,253,253,250,250,244,251,252,252,253,253,251,251,230,211,171,147,80,131,251,251,252,252,249,242,206,236,252,252,251,251,252,252,252,252,249,243,215,212,212,184,169,186,193,186,179,152,136,129,129,132,141,118,71,35,27,44,76,82,53,44,33,36,68,94,117,144,123,107,77,36,45,21,18,34,48,55,47,57,66,66,62,61,68,68,74,73,71,65,120,214,249,252,249,248,223,184,205,244,251,251,250,250,251,249,249,250,251,252,250,250,238,240,252,251,248,230,195,218,217,183,229,249,245,229,136,177,243,234,143,105,108,67,101,177,193,223,171,92,55,21,48,55,45,91,71,36,36,57,76,63,17,159,250,250,250,250,253,253,251,251,252,252,252,252,252,252,252,252,194,110,29,128,248,226,206,165,176,235,252,252,250,242,247,247,249,249,247,248,247,247,246,247,247,246,247,246,247,247,246,247,246,250,243,226,233,252,240,127,96,63,7,118,238,246,250,250,250,248,219,210,225,212,198,213,226,237,251,246,242,236,182,170,229,246,250,250,248,247,246,244,244,242,243,243,242,244,244,244,244,243,242,241,242,241,241,241,241,241,241,241,239,240,239,239,238,238,239,238,238,237,236,237,238,235,234,235,233,234,233,231,231,230,227,228,229,229,227,228,227,227,227,229,229,227,225,226,223,223,224,222,224,222,223,222,222,230,233,239,237,217,212,225,230,224,223,222,218,217,218,216,214,219,217,216,217,217,215,214,215,217,217,213,214,214,213,214,214,212,210,211,210,208,210,208,208,210,206,209,207,202,205,204,201,201,200,199,200,197,199,195,199,114,5,1,4,7,9,8,10,10,11,11,11,11,214,214,214,213,214,212,213,215,214,214,215,214,214,214,215,214,214,214,214,216,214,214,214,214,216,215,215,214,214,216,217,216,215,214,217,217,218,217,217,215,216,217,215,218,216,216,218,217,218,219,218,216,219,218,218,220,219,219,219,220,222,219,222,222,222,223,222,223,224,223,222,225,223,224,224,223,225,224,224,224,224,224,225,224,226,226,223,224,226,226,226,226,224,224,227,225,226,227,227,226,225,225,224,224,227,227,227,228,227,229,230,228,230,230,228,229,230,230,230,230,229,229,230,230,230,232,232,233,230,230,231,232,233,232,233,233,232,233,233,231,233,233,233,235,234,235,237,238,236,235,236,236,237,237,236,237,236,236,238,239,239,241,241,240,241,240,240,239,240,240,239,241,240,241,242,241,242,242,242,242,242,243,244,244,245,244,244,244,243,243,244,244,244,243,243,244,245,245,243,244,245,246,246,244,244,245,247,247,245,245,244,247,245,245,246,244,245,245,245,245,245,245,245,245,244,245,246,246,247,247,247,246,247,247,247,247,247,247,247,247,245,245,247,247,247,247,246,247,247,247,247,246,246,247,247,247,246,246,247,247,247,247,247,246,246,246,246,246,247,247,247,247,248,247,247,247,247,247,247,247,247,248,248,247,248,246,247,246,247,247,247,247,247,247,249,241,234,247,247,247,250,249,249,252,252,252,251,251,252,252,252,252,252,252,253,253,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,252,252,253,253,252,252,253,253,250,250,244,251,252,252,253,253,251,251,230,211,171,147,80,131,251,251,252,252,249,242,206,236,252,252,251,251,252,252,252,252,249,243,215,212,212,184,169,186,193,186,179,152,136,129,129,132,141,118,71,35,27,44,76,82,53,44,33,36,68,94,117,144,123,107,77,36,45,21,18,34,48,55,47,57,66,66,62,61,68,68,74,73,71,65,120,214,249,252,249,248,223,184,205,244,251,251,250,250,251,249,249,250,251,252,250,250,238,240,252,251,248,230,195,218,217,183,229,249,245,229,136,177,243,234,143,105,108,67,101,177,193,223,171,92,55,21,48,55,45,91,71,36,36,57,76,63,17,159,250,250,250,250,253,253,251,251,252,252,252,252,252,252,252,252,194,110,29,128,248,226,206,165,176,235,252,252,250,242,247,247,249,249,247,248,247,247,246,247,247,246,247,246,247,247,246,247,246,250,243,226,233,252,240,127,96,63,7,118,238,246,250,250,250,248,219,210,225,212,198,213,226,237,251,246,242,236,182,170,229,246,250,250,248,247,246,244,244,242,243,243,242,244,244,244,244,243,242,241,242,241,241,241,241,241,241,241,239,240,239,239,238,238,239,238,238,237,236,237,238,235,234,235,233,234,233,231,231,230,227,228,229,229,227,228,227,227,227,229,229,227,225,226,223,223,224,222,224,222,223,222,222,230,233,239,237,217,212,225,230,224,223,222,218,217,218,216,214,219,217,216,217,217,215,214,215,217,217,213,214,214,213,214,214,212,210,211,210,208,210,208,208,210,206,209,207,202,205,204,201,201,200,199,200,197,199,195,199,114,5,1,4,7,9,8,10,10,11,11,11,11,214,218,218,215,218,217,215,215,216,218,217,217,219,218,216,215,219,217,216,217,218,221,221,221,220,218,219,220,220,218,217,219,218,220,220,217,218,217,220,223,220,221,219,220,219,217,219,217,218,219,221,222,220,220,220,221,221,221,221,221,223,224,223,225,224,223,224,223,224,226,226,228,227,227,227,225,228,229,229,227,226,228,229,229,229,229,229,230,229,226,226,228,227,227,230,229,229,227,228,229,227,230,230,230,230,231,230,230,232,228,230,230,229,231,230,232,231,230,231,232,233,230,233,233,231,234,235,236,235,236,234,232,234,233,236,237,236,237,237,236,239,237,236,238,238,237,237,238,240,238,239,241,240,240,240,241,241,240,240,240,241,240,241,242,243,240,242,243,244,244,242,244,244,244,245,244,244,244,244,246,245,246,246,245,245,245,247,247,247,247,246,245,246,245,246,246,246,247,248,248,249,248,248,247,248,249,248,249,248,249,248,249,247,249,250,248,249,248,248,248,248,249,249,248,248,249,249,249,249,249,250,251,250,249,250,249,249,249,249,249,248,249,249,248,249,250,248,249,250,250,251,251,250,250,250,249,249,250,250,250,250,250,249,250,249,249,250,250,249,250,250,251,251,251,251,249,251,251,251,252,251,250,250,249,251,250,250,251,247,249,250,250,250,252,248,233,242,250,249,250,249,249,250,251,251,251,251,251,250,252,250,245,248,251,252,247,249,252,252,251,250,249,250,250,250,248,250,251,249,248,242,243,249,252,251,251,251,251,251,250,251,251,251,252,250,251,245,237,252,240,207,180,212,229,246,251,247,228,171,179,151,123,49,149,250,250,252,252,250,238,178,234,251,251,250,250,253,253,252,252,252,252,252,252,252,252,252,252,252,249,253,253,252,252,253,253,249,249,209,216,252,252,252,252,252,252,253,253,245,190,135,134,118,107,49,100,248,248,250,250,253,253,252,252,253,253,252,252,252,252,252,252,252,252,252,252,252,252,249,242,205,167,207,246,251,251,251,251,252,252,251,250,252,252,250,250,235,252,252,252,252,245,252,252,218,167,225,251,172,125,116,104,100,85,87,96,91,76,69,62,55,77,95,93,65,34,41,49,68,90,52,32,41,65,69,59,17,150,247,247,249,249,252,252,250,248,245,247,249,249,237,245,250,252,223,173,118,103,162,210,240,188,165,207,234,248,251,247,245,249,249,249,249,249,249,250,249,250,248,248,250,248,248,249,249,247,249,250,251,239,225,252,222,119,104,47,8,136,242,246,250,250,252,251,223,209,223,229,214,202,218,235,252,242,192,113,42,15,89,181,225,246,248,248,248,247,247,245,244,244,244,244,244,244,245,242,242,242,242,244,241,240,241,241,240,240,239,239,239,239,238,237,238,238,238,237,236,234,234,236,236,232,232,233,232,234,231,230,230,228,229,229,227,226,226,228,227,226,225,226,224,225,227,222,223,224,222,222,220,224,231,229,203,153,120,83,73,129,183,212,225,227,226,222,222,221,216,216,214,213,215,218,217,217,215,214,214,212,213,214,214,211,212,212,212,212,211,213,213,210,210,209,207,208,208,207,206,205,202,203,205,201,200,198,201,196,200,115,3,1,6,8,9,7,10,10,10,11,10,10,214,218,218,215,218,217,215,215,216,218,217,217,219,218,216,215,219,217,216,217,218,221,221,221,220,218,219,220,220,218,217,219,218,220,220,217,218,217,220,223,220,221,219,220,219,217,219,217,218,219,221,222,220,220,220,221,221,221,221,221,223,224,223,225,224,223,224,223,224,226,226,228,227,227,227,225,228,229,229,227,226,228,229,229,229,229,229,230,229,226,226,228,227,227,230,229,229,227,228,229,227,230,230,230,230,231,230,230,232,228,230,230,229,231,230,232,231,230,231,232,233,230,233,233,231,234,235,236,235,236,234,232,234,233,236,237,236,237,237,236,239,237,236,238,238,237,237,238,240,238,239,241,240,240,240,241,241,240,240,240,241,240,241,242,243,240,242,243,244,244,242,244,244,244,245,244,244,244,244,246,245,246,246,245,245,245,247,247,247,247,246,245,246,245,246,246,246,247,248,248,249,248,248,247,248,249,248,249,248,249,248,249,247,249,250,248,249,248,248,248,248,249,249,248,248,249,249,249,249,249,250,251,250,249,250,249,249,249,249,249,248,249,249,248,249,250,248,249,250,250,251,251,250,250,250,249,249,250,250,250,250,250,249,250,249,249,250,250,249,250,250,251,251,251,251,249,251,251,251,252,251,250,250,249,251,250,250,251,247,249,250,250,250,252,248,233,242,250,249,250,249,249,250,251,251,251,251,251,250,252,250,245,248,251,252,247,249,252,252,251,250,249,250,250,250,248,250,251,249,248,242,243,249,252,251,251,251,251,251,250,251,251,251,252,250,251,245,237,252,240,207,180,212,229,246,251,247,228,171,179,151,123,49,149,250,250,252,252,250,238,178,234,251,251,250,250,253,253,252,252,252,252,252,252,252,252,252,252,252,249,253,253,252,252,253,253,249,249,209,216,252,252,252,252,252,252,253,253,245,190,135,134,118,107,49,100,248,248,250,250,253,253,252,252,253,253,252,252,252,252,252,252,252,252,252,252,252,252,249,242,205,167,207,246,251,251,251,251,252,252,251,250,252,252,250,250,235,252,252,252,252,245,252,252,218,167,225,251,172,125,116,104,100,85,87,96,91,76,69,62,55,77,95,93,65,34,41,49,68,90,52,32,41,65,69,59,17,150,247,247,249,249,252,252,250,248,245,247,249,249,237,245,250,252,223,173,118,103,162,210,240,188,165,207,234,248,251,247,245,249,249,249,249,249,249,250,249,250,248,248,250,248,248,249,249,247,249,250,251,239,225,252,222,119,104,47,8,136,242,246,250,250,252,251,223,209,223,229,214,202,218,235,252,242,192,113,42,15,89,181,225,246,248,248,248,247,247,245,244,244,244,244,244,244,245,242,242,242,242,244,241,240,241,241,240,240,239,239,239,239,238,237,238,238,238,237,236,234,234,236,236,232,232,233,232,234,231,230,230,228,229,229,227,226,226,228,227,226,225,226,224,225,227,222,223,224,222,222,220,224,231,229,203,153,120,83,73,129,183,212,225,227,226,222,222,221,216,216,214,213,215,218,217,217,215,214,214,212,213,214,214,211,212,212,212,212,211,213,213,210,210,209,207,208,208,207,206,205,202,203,205,201,200,198,201,196,200,115,3,1,6,8,9,7,10,10,10,11,10,10,215,216,216,214,217,215,216,216,218,216,216,219,217,218,215,216,217,216,218,217,218,215,215,215,217,218,217,219,217,219,217,218,218,218,219,217,217,215,215,217,217,218,218,217,219,217,220,219,220,221,218,220,220,218,220,218,220,222,218,222,221,222,222,222,224,224,224,227,224,223,223,225,226,226,226,224,226,229,228,226,226,224,227,225,226,226,226,227,227,229,227,227,227,227,226,229,227,225,226,225,227,229,228,227,229,229,230,229,230,232,230,229,229,231,229,231,231,230,231,232,230,230,232,230,232,233,233,233,234,233,234,232,234,235,233,234,233,234,234,233,233,235,237,236,235,236,236,239,238,238,238,239,237,237,239,239,237,239,240,239,239,239,240,241,241,240,241,243,240,242,242,241,242,243,242,244,244,244,244,244,245,245,245,245,246,246,245,244,246,246,245,246,245,245,245,246,247,245,246,248,248,248,247,247,246,247,248,249,249,248,247,248,249,249,248,247,247,247,249,248,249,249,249,249,248,248,247,248,248,247,249,248,249,250,249,248,248,248,248,249,248,249,249,249,249,249,249,249,248,248,248,249,249,249,250,249,248,250,249,248,249,250,249,247,249,249,249,249,249,250,249,249,250,250,248,249,249,249,249,248,248,248,249,250,249,249,248,248,247,248,248,248,248,252,244,232,244,249,248,249,247,247,248,249,250,249,249,249,248,250,248,243,249,251,252,250,252,252,252,251,247,248,249,247,247,247,248,248,248,249,246,242,242,247,250,249,250,249,248,247,248,248,247,250,247,250,237,230,245,188,181,208,243,244,252,252,248,216,170,179,157,134,49,149,250,250,252,244,250,229,141,191,247,247,248,243,248,252,250,251,251,252,241,252,252,208,240,251,241,249,252,252,252,252,252,252,252,252,252,252,252,252,252,252,253,253,252,252,239,165,127,125,110,104,36,85,248,248,249,249,252,252,251,251,252,252,252,252,252,252,251,248,252,252,251,251,251,252,250,240,230,202,204,249,251,251,251,251,252,250,250,249,251,250,250,248,235,252,251,251,242,242,252,241,149,112,205,242,193,130,101,104,102,115,109,96,97,81,81,64,66,68,72,117,110,65,50,47,82,90,52,29,37,70,65,57,12,141,246,246,249,249,252,252,250,250,244,244,247,252,240,244,250,252,245,219,178,95,113,186,242,204,186,220,225,248,251,250,246,247,248,248,248,246,249,249,248,249,247,248,247,247,248,247,247,247,247,248,248,242,222,252,210,116,104,35,11,142,243,247,251,248,252,243,224,207,219,229,222,203,209,230,234,234,196,146,60,66,145,208,231,243,245,245,244,244,244,243,242,244,244,241,243,241,242,243,240,239,240,239,239,239,239,239,238,239,238,236,237,237,234,237,235,236,237,235,233,234,232,231,230,229,230,228,229,229,229,228,226,227,224,225,226,226,225,224,224,224,222,224,224,222,222,222,221,222,222,224,230,231,241,225,173,131,103,77,48,94,171,217,233,230,227,222,219,219,217,215,215,214,215,217,215,214,212,212,213,214,213,214,215,214,212,212,208,212,210,208,212,210,212,210,207,208,206,204,204,205,205,202,200,199,200,196,200,197,200,114,4,0,4,7,9,8,10,10,11,11,12,10,217,217,217,215,215,213,214,216,215,214,215,215,213,215,215,214,215,214,216,217,214,217,217,216,217,214,215,214,214,217,215,214,214,215,217,217,216,214,214,216,213,215,216,214,215,218,217,217,217,217,217,217,217,218,220,215,217,218,219,220,217,218,217,221,222,218,222,221,221,221,221,222,222,222,222,225,224,224,223,223,224,224,225,227,225,225,225,224,223,225,226,226,226,225,227,227,228,230,226,226,226,226,229,226,225,228,228,227,228,228,231,231,231,231,230,232,229,229,229,230,232,229,230,231,232,233,231,231,230,231,232,232,232,232,232,232,230,233,232,232,233,232,233,236,236,235,237,236,236,235,234,237,234,235,236,236,238,238,239,240,239,239,239,237,239,241,241,240,239,241,239,241,242,241,241,241,242,244,243,244,244,244,245,245,244,244,244,244,244,244,244,244,244,244,244,244,245,246,245,245,247,246,246,245,246,247,247,248,247,248,248,247,248,248,247,247,248,248,249,248,248,247,247,247,247,248,247,247,247,248,248,247,246,247,247,247,247,248,248,247,250,248,248,249,248,249,248,247,248,248,249,249,248,248,248,247,247,247,247,249,248,248,247,248,247,247,248,247,248,248,249,249,248,248,249,248,248,248,249,248,247,248,247,247,248,248,246,247,247,248,249,247,248,251,236,228,245,249,250,250,249,248,247,248,249,249,248,248,249,252,246,243,251,250,251,236,215,238,242,248,250,247,249,248,248,247,247,247,248,248,247,244,241,243,248,248,249,249,248,248,248,249,248,248,248,251,230,222,248,215,214,237,251,240,239,252,247,206,159,167,146,125,43,152,250,249,251,243,252,239,171,208,249,249,248,244,246,251,249,251,250,248,233,252,218,174,238,252,250,251,252,229,225,239,252,252,251,251,252,252,250,246,235,252,248,252,252,252,234,156,132,135,119,116,32,77,248,248,247,247,249,252,250,250,244,247,252,250,252,252,245,247,252,251,251,251,252,252,251,245,241,214,202,248,252,252,250,250,252,251,251,250,252,252,250,245,239,252,250,250,233,243,238,143,95,145,249,249,200,137,106,101,118,126,115,98,87,83,74,69,65,62,67,92,123,102,60,56,99,85,40,27,41,73,57,57,12,122,246,246,249,249,252,252,249,250,243,241,246,251,241,242,247,252,247,226,212,129,108,152,222,219,195,227,224,248,252,252,247,244,249,249,249,247,248,248,247,249,247,247,247,246,247,247,247,247,247,247,248,248,229,252,199,110,97,29,14,152,243,248,250,249,249,250,225,206,217,229,228,206,204,226,249,232,207,200,188,190,220,240,244,245,244,245,244,242,242,241,243,242,242,242,243,241,240,240,240,239,239,239,239,239,239,239,238,237,240,237,235,236,233,234,236,235,234,234,232,231,232,231,229,229,230,229,226,229,229,227,228,226,225,225,225,227,225,224,224,223,222,223,221,219,218,218,220,220,226,231,240,246,241,198,150,122,106,87,69,110,166,209,238,239,236,227,223,222,217,219,217,215,217,217,213,214,215,215,213,211,214,214,211,210,213,211,210,212,211,208,210,208,210,208,207,210,206,206,206,207,204,202,198,199,201,198,201,198,200,113,4,1,4,7,9,8,10,9,10,10,10,10,217,220,218,217,218,215,215,215,215,214,214,216,214,214,213,214,216,213,215,215,216,218,219,218,215,214,216,217,214,216,216,214,214,213,215,217,216,214,215,215,216,217,218,215,216,213,215,216,215,215,215,218,218,218,219,218,218,218,218,218,217,217,219,219,221,220,218,222,220,222,223,222,222,222,224,222,223,224,222,224,226,225,225,224,224,224,224,224,224,226,227,226,224,228,226,228,226,225,229,227,229,226,227,227,228,229,227,230,229,229,231,231,229,230,230,230,229,231,233,231,230,230,232,232,231,232,230,232,230,230,233,231,231,232,234,234,232,236,237,235,235,236,235,236,237,237,236,235,235,236,236,236,237,237,236,236,237,238,237,239,241,238,238,241,239,239,240,240,240,239,241,241,241,242,241,241,243,244,243,244,244,243,244,244,244,244,244,244,242,244,244,244,245,246,244,243,244,244,247,247,246,247,247,247,247,247,247,246,248,249,247,248,248,247,248,247,249,247,247,248,246,248,248,248,248,247,247,247,247,247,247,247,247,247,247,247,248,248,247,248,248,248,248,248,249,249,247,247,247,248,248,247,248,247,248,248,248,249,248,248,248,247,249,249,248,247,247,247,248,248,248,249,249,249,250,249,247,249,249,249,249,248,247,247,247,249,249,247,247,247,247,247,249,248,228,230,246,248,249,248,249,250,248,247,248,249,250,249,249,248,242,245,252,249,243,171,119,187,232,249,249,246,248,248,249,249,247,247,247,247,247,247,240,240,244,247,250,247,248,247,247,248,248,247,247,250,231,245,252,227,221,214,201,201,237,249,247,200,156,162,139,118,37,157,249,248,252,242,252,249,184,202,247,248,248,245,243,250,249,251,252,251,225,241,225,222,252,252,246,250,227,172,211,241,252,252,248,246,252,251,250,241,230,252,244,251,252,252,233,150,134,140,120,123,33,77,248,248,247,247,249,252,250,247,234,246,252,249,250,250,241,251,252,249,252,252,252,252,252,241,250,221,189,239,252,252,250,250,252,250,250,250,252,251,250,238,245,252,251,247,228,232,183,161,148,212,253,253,169,107,93,89,98,101,87,76,74,59,62,53,50,49,46,54,79,100,63,65,100,76,39,30,48,71,59,60,12,134,246,246,249,249,252,252,249,250,244,240,244,251,244,240,249,252,246,223,236,174,105,130,200,209,179,216,208,227,251,251,248,245,250,248,248,247,247,247,247,248,247,247,247,246,247,246,246,247,246,247,248,251,236,245,182,105,91,19,18,163,243,248,251,247,252,242,226,204,217,229,223,216,205,223,234,217,206,227,252,252,251,251,247,247,245,244,243,241,241,240,240,241,240,239,239,239,239,239,239,238,240,238,236,237,236,236,236,234,236,233,235,236,233,234,232,232,231,231,231,229,228,227,229,227,229,229,228,225,225,225,224,224,225,223,222,224,221,222,224,220,220,219,220,218,219,220,219,228,231,242,238,200,171,146,126,114,107,95,80,78,102,127,181,221,238,231,223,220,221,216,215,214,212,212,214,213,212,214,214,212,210,211,212,211,209,210,208,209,210,210,211,207,207,208,205,207,205,206,204,201,203,202,201,199,202,198,200,196,201,114,3,1,4,7,8,7,10,10,10,11,10,10,218,220,220,220,220,216,216,217,215,214,217,217,216,217,213,213,217,216,215,217,216,217,217,217,216,215,217,217,217,216,215,217,217,215,215,215,215,216,215,216,214,213,216,216,216,217,216,217,216,216,216,218,217,216,218,217,217,218,218,219,218,220,218,220,220,218,220,220,223,226,225,222,223,224,223,225,224,225,224,223,225,222,224,224,221,225,222,224,224,223,225,224,227,225,226,224,226,226,223,226,226,227,228,226,225,228,230,229,227,229,229,229,231,228,230,229,231,232,229,230,229,231,233,232,232,232,231,232,232,232,236,235,233,232,232,232,234,234,233,234,234,236,236,236,236,237,237,234,238,237,235,239,236,238,236,235,237,237,237,238,237,237,239,240,241,239,241,241,239,241,239,240,240,240,242,243,242,242,242,244,243,243,244,243,242,244,244,244,242,243,243,244,244,245,248,246,245,246,246,246,247,247,247,247,248,249,249,249,248,247,249,249,248,248,247,247,247,245,248,248,248,249,247,247,246,246,247,247,248,249,248,246,248,249,247,247,248,248,248,247,247,247,247,248,248,249,248,247,249,248,248,247,247,248,247,248,249,248,247,249,249,247,247,247,247,249,248,248,248,248,248,248,249,247,249,249,247,249,247,248,248,249,249,249,249,248,249,249,249,248,248,247,250,247,228,239,251,248,249,248,249,248,248,248,246,248,248,250,250,247,243,246,252,249,240,182,169,231,248,252,249,246,247,247,247,247,247,247,247,247,247,248,247,241,240,243,248,249,248,248,247,247,246,247,249,250,230,245,250,186,171,199,220,229,250,252,247,201,169,177,155,125,42,168,249,249,252,242,252,252,175,174,239,246,249,247,243,247,252,250,252,249,242,250,229,237,252,251,212,229,243,232,252,248,252,252,248,246,252,247,250,241,234,252,247,252,252,252,226,146,125,128,118,111,29,83,247,247,247,247,249,252,249,246,231,243,252,250,250,250,241,252,252,250,250,250,252,251,248,246,243,212,173,226,252,252,250,250,252,251,250,251,250,252,250,237,249,252,252,237,218,210,220,219,222,252,250,229,129,99,92,92,96,86,85,81,81,78,71,73,69,60,57,52,63,83,67,81,107,63,40,32,53,74,59,62,12,141,246,246,249,249,252,252,250,250,245,241,247,251,248,241,248,252,249,217,237,207,129,139,195,229,208,207,182,200,244,251,251,243,248,247,247,249,248,247,247,247,247,247,247,247,245,246,247,247,247,247,245,249,245,234,161,92,83,17,25,174,246,248,251,250,250,250,227,204,217,228,230,227,209,224,245,201,201,237,252,252,246,252,247,244,245,242,241,239,241,240,239,239,239,239,239,239,238,238,237,239,237,237,236,237,236,234,232,233,233,233,235,234,232,232,231,229,229,230,230,227,224,226,225,225,226,224,225,224,222,222,223,223,220,223,223,222,223,221,221,220,220,220,219,219,218,221,228,231,240,209,159,130,110,96,96,95,88,84,80,75,49,34,67,135,200,225,224,222,219,218,218,216,212,210,214,215,213,214,213,211,210,212,212,210,213,210,211,213,212,211,209,207,210,208,209,209,206,206,203,204,202,203,201,198,200,196,198,194,201,114,3,1,4,7,9,8,10,9,10,11,10,10,219,222,221,219,219,214,217,218,215,215,215,217,217,215,214,214,215,212,216,217,213,215,216,217,218,215,217,215,213,216,217,215,214,214,215,214,213,213,217,216,214,215,215,215,217,216,217,215,216,215,217,215,215,216,214,219,219,220,220,219,219,219,221,219,221,223,223,224,223,223,224,223,223,222,223,224,225,224,221,224,220,222,225,221,223,224,225,224,223,221,223,225,223,225,222,226,227,225,226,226,228,225,227,226,226,227,225,227,228,229,230,228,226,230,229,229,230,231,232,227,231,232,231,233,231,234,234,234,233,232,232,232,234,233,235,233,231,232,232,234,233,233,235,235,234,235,237,237,236,237,236,236,236,237,239,236,237,237,235,237,238,236,236,237,237,238,237,237,239,239,240,241,242,243,244,242,243,243,242,243,243,244,242,243,242,244,244,243,243,245,245,243,243,244,245,246,245,245,246,245,246,246,247,248,246,248,249,249,249,249,247,247,249,248,248,248,248,247,247,247,247,248,247,248,247,244,247,247,248,247,246,247,248,248,249,249,247,248,247,247,246,248,247,247,248,247,247,247,247,247,248,247,247,248,246,247,248,248,248,247,248,247,248,248,247,247,247,247,247,246,247,247,247,247,247,248,248,249,249,247,247,248,249,248,248,247,248,247,248,249,249,249,250,242,234,247,248,248,249,248,248,247,248,246,247,246,247,248,248,245,244,250,249,249,252,247,252,252,251,249,248,248,248,246,246,246,246,246,245,247,248,248,247,247,240,239,244,245,250,248,247,248,247,247,248,248,224,237,215,182,215,230,243,250,252,252,248,204,174,169,157,127,39,173,249,245,251,241,251,251,198,187,240,248,249,248,242,245,250,249,252,251,245,251,224,229,244,243,242,251,252,236,252,252,252,252,250,244,252,249,249,241,235,252,229,245,253,253,226,128,107,116,103,118,33,83,248,248,247,247,249,252,250,247,235,246,252,248,250,248,245,252,252,250,252,252,251,248,247,247,241,220,181,229,252,252,249,247,250,252,249,250,250,252,249,236,252,252,250,226,229,252,253,253,250,252,247,186,119,114,110,121,117,114,113,116,124,110,112,109,108,75,96,86,91,105,80,118,124,61,35,27,62,77,62,62,9,136,247,247,249,249,252,252,248,250,245,239,247,251,250,240,244,249,252,219,230,234,148,141,179,217,214,187,165,187,227,248,252,242,245,246,247,247,247,247,247,248,247,247,247,247,247,246,246,246,245,245,246,247,252,225,139,94,74,10,29,176,243,248,252,245,249,243,220,201,216,228,230,225,215,236,234,180,189,223,241,239,230,245,243,242,241,240,240,239,239,241,239,239,239,239,238,237,238,239,238,236,237,237,236,235,235,232,233,233,233,232,233,231,228,229,229,228,226,227,226,224,227,226,226,223,225,224,222,224,224,224,223,221,223,220,221,223,219,217,218,217,219,220,219,218,219,226,231,231,188,139,110,98,95,92,97,95,95,91,87,73,63,52,35,57,129,200,219,218,219,216,216,216,215,214,212,211,212,212,212,212,212,213,210,212,212,211,212,210,212,209,210,210,209,210,207,211,208,206,208,204,204,203,200,199,198,197,200,195,202,113,4,1,4,7,9,8,10,10,10,11,11,10,222,223,221,220,220,218,219,218,218,217,217,217,217,218,217,215,217,214,215,219,217,217,218,218,216,217,217,215,215,213,215,216,212,216,215,215,217,214,213,214,214,214,218,216,216,218,215,217,217,217,216,218,218,218,219,218,220,220,218,218,219,221,219,221,225,224,223,222,222,223,222,222,224,224,224,224,223,223,224,225,225,221,223,224,223,226,224,224,224,226,225,223,223,224,226,224,224,225,224,227,225,227,229,226,227,227,228,227,227,229,228,226,230,229,228,229,231,232,232,234,231,233,232,231,234,233,233,233,233,231,233,232,235,234,234,235,234,235,235,237,235,235,237,236,234,236,237,236,238,235,237,238,236,237,239,239,237,239,239,239,239,238,239,240,238,239,240,240,239,242,241,241,242,241,241,241,242,242,242,243,244,243,242,243,243,244,244,243,245,245,243,244,243,244,245,246,246,245,246,246,247,246,247,248,248,249,247,247,248,248,249,249,247,248,249,249,249,247,246,247,249,249,248,247,249,249,247,248,247,247,247,245,248,247,248,249,248,247,248,247,249,249,246,248,248,247,248,247,247,248,248,249,248,248,247,247,249,249,249,248,248,247,247,248,247,248,247,247,247,247,248,248,248,247,249,249,247,248,248,248,248,248,250,251,249,248,248,248,249,249,248,249,251,240,240,250,250,249,248,249,250,249,249,249,248,248,247,249,247,243,248,251,250,249,252,252,252,252,249,247,246,247,247,247,247,245,247,247,247,247,245,247,247,248,244,240,242,246,249,248,247,247,247,249,249,246,226,248,242,211,232,244,234,218,241,250,249,201,162,160,139,113,41,176,249,243,251,239,250,252,212,200,246,248,249,248,246,245,251,250,252,247,242,247,178,202,252,252,249,250,246,227,246,242,251,251,250,245,251,251,249,243,235,250,163,158,234,249,225,137,119,113,107,110,29,90,247,247,247,247,250,252,250,249,240,246,252,249,251,245,248,252,251,250,252,252,251,246,248,252,238,245,198,208,252,250,250,250,251,252,249,251,250,252,244,240,252,252,248,241,252,252,252,252,222,224,169,122,113,118,128,122,126,119,93,91,95,101,104,94,86,79,85,83,84,95,99,136,115,51,34,25,61,72,60,60,12,140,247,247,249,249,252,252,249,251,248,238,244,249,252,244,241,248,252,226,218,244,163,100,132,167,184,171,168,198,215,243,252,243,247,247,247,247,248,247,246,246,247,246,245,246,246,247,248,245,247,244,248,247,252,217,118,87,68,11,30,179,243,249,251,247,246,240,214,198,216,229,231,234,220,233,237,160,178,225,233,232,229,244,240,240,243,239,239,237,238,238,237,237,237,237,239,237,237,236,237,237,236,235,235,234,233,232,231,231,232,230,229,229,227,229,227,227,228,225,224,227,225,226,224,222,225,224,224,225,223,222,222,224,223,222,220,220,221,216,216,217,218,216,219,220,222,229,227,184,136,105,92,101,125,132,120,109,106,98,91,85,74,60,50,36,57,150,201,211,219,217,219,216,213,213,212,210,212,213,213,214,214,212,212,212,210,210,211,211,210,209,207,210,210,209,208,207,208,205,205,202,201,203,199,200,199,196,202,196,200,113,4,1,4,8,9,7,10,10,10,11,10,10,220,222,221,220,223,220,220,222,220,218,217,218,217,219,219,215,219,218,217,218,217,218,215,216,216,214,217,216,217,215,213,214,216,216,215,214,214,212,214,215,213,215,214,212,212,214,217,216,216,215,219,217,218,221,219,220,218,220,219,218,221,220,221,219,220,221,222,224,221,222,220,220,223,223,221,220,220,221,223,225,222,222,222,220,222,224,222,221,224,222,222,222,222,226,223,221,224,222,222,226,227,224,227,226,227,226,226,228,227,228,227,229,227,229,231,230,231,231,233,233,233,232,233,232,229,232,232,233,231,230,232,232,232,234,235,231,235,236,234,237,237,236,234,237,236,235,236,233,235,237,236,237,238,236,236,236,237,238,236,237,237,237,238,239,238,238,239,240,240,240,241,241,241,241,241,241,240,240,242,242,241,243,242,242,243,242,244,243,244,244,243,244,244,246,246,246,246,246,247,247,247,247,245,247,247,247,247,248,248,248,247,247,248,246,247,247,249,249,249,249,248,249,246,247,248,247,249,247,247,247,247,246,247,247,246,246,247,248,249,249,249,247,248,249,247,247,247,248,247,247,248,249,248,247,247,247,248,248,247,248,249,247,247,247,247,248,247,248,247,248,248,249,248,248,248,249,249,247,247,248,248,249,250,248,248,249,249,248,248,248,248,251,247,238,245,251,248,250,249,248,249,249,250,247,248,247,247,248,245,245,248,250,247,245,248,252,247,246,247,247,248,246,247,247,247,247,246,247,246,247,247,245,247,248,248,244,240,240,247,248,247,247,247,246,250,242,236,252,240,224,234,203,189,214,244,250,248,201,167,153,141,109,37,187,250,245,250,236,251,252,228,178,208,247,250,250,247,242,251,249,252,245,242,205,172,241,252,252,249,250,237,190,225,241,252,252,249,240,252,252,250,239,237,249,192,212,251,251,227,142,130,137,113,110,28,95,247,247,247,246,248,252,249,247,237,240,250,252,251,243,252,252,251,250,250,252,250,245,251,252,245,248,204,215,252,252,250,250,251,252,249,250,250,252,241,244,252,252,244,252,252,252,252,174,95,78,64,58,84,77,73,81,83,92,64,45,48,43,49,46,49,52,44,46,51,57,57,80,80,59,47,50,72,69,58,53,11,139,247,247,249,249,252,252,250,251,248,238,242,246,251,245,239,245,252,232,206,229,188,144,144,162,220,194,172,221,219,239,252,248,248,247,247,247,245,246,246,245,246,245,244,244,245,245,245,244,245,243,247,245,250,223,115,89,63,7,42,194,245,249,252,247,247,229,215,197,215,230,230,234,223,236,234,146,179,228,236,231,225,241,237,241,240,238,239,236,236,237,237,236,235,236,236,236,235,235,236,234,235,233,232,231,231,229,229,229,228,228,227,226,229,225,225,225,222,224,227,224,226,224,222,221,224,223,220,222,220,222,220,219,222,219,220,219,219,219,218,216,216,217,217,220,228,225,188,139,106,92,83,110,134,135,122,105,94,80,72,61,61,53,48,36,22,101,177,204,223,221,218,214,216,214,209,212,211,211,212,212,211,211,212,211,208,206,211,210,208,208,208,208,207,209,206,206,205,206,204,200,203,203,200,198,199,198,198,192,201,114,3,1,4,8,8,8,10,10,11,11,10,10,216,220,220,219,221,216,219,218,221,219,218,219,219,219,216,215,217,215,215,217,214,216,215,214,218,216,214,218,218,214,216,216,213,214,214,215,214,212,214,214,214,210,214,214,213,214,214,217,215,215,217,218,217,215,218,217,218,221,220,223,223,221,221,221,220,221,222,224,218,222,222,219,219,221,221,217,219,221,222,219,221,222,222,221,221,221,221,221,221,222,219,224,222,220,222,223,225,224,224,225,222,223,225,226,225,224,225,224,227,226,228,229,227,228,226,227,229,229,230,230,229,232,232,230,231,232,231,231,233,233,234,230,232,232,232,234,233,234,234,234,236,234,234,235,233,234,233,234,237,235,236,235,235,236,237,236,235,238,236,235,237,235,236,238,236,236,237,238,238,240,237,240,240,240,242,241,242,241,241,241,242,242,241,241,241,242,244,244,243,243,243,245,244,243,244,244,245,247,247,246,247,247,246,247,246,247,248,248,248,247,246,248,247,246,247,248,249,248,248,248,248,247,249,247,247,247,246,248,248,248,249,247,247,248,247,248,247,247,249,248,248,248,247,248,248,248,248,247,249,249,247,247,248,248,249,249,249,248,248,248,247,248,247,249,248,247,247,247,249,249,248,248,250,249,249,249,249,248,249,249,249,249,248,249,249,248,248,249,249,249,247,250,246,237,247,250,249,248,249,249,248,249,249,249,249,248,247,247,242,246,251,249,246,244,247,249,247,245,246,247,247,247,248,247,247,247,246,247,247,247,247,246,247,247,247,247,242,240,242,246,247,247,247,247,250,241,234,252,230,201,184,187,222,238,252,252,249,206,175,173,153,111,44,190,249,247,249,236,249,252,223,167,205,246,250,251,249,245,247,250,251,239,244,227,218,251,252,250,238,249,215,211,242,244,252,252,250,243,252,252,248,238,237,252,251,252,253,253,224,145,134,132,117,111,27,95,247,247,247,247,248,252,250,247,242,242,249,252,249,246,252,252,252,252,250,252,250,243,252,252,243,250,222,227,252,252,250,250,251,249,248,250,251,252,240,248,252,249,246,252,253,196,123,75,50,28,2,9,28,33,45,39,44,98,84,46,35,32,32,30,36,33,29,37,62,76,60,48,46,53,55,68,76,62,46,49,12,106,240,242,248,248,252,252,249,251,248,239,241,245,250,247,238,244,252,246,200,227,238,187,204,215,250,232,193,244,231,240,252,249,247,247,247,248,247,246,247,246,245,245,244,245,244,244,244,244,247,244,247,244,251,241,141,95,62,6,53,210,245,250,252,247,246,240,217,199,216,230,231,233,225,250,230,133,180,232,231,227,224,242,237,239,241,237,237,236,236,235,235,236,237,236,235,234,232,232,232,230,230,231,232,232,229,227,228,226,227,228,224,224,224,224,223,224,224,224,225,224,223,223,223,223,223,221,222,221,220,222,218,217,218,221,218,219,215,215,218,217,218,214,218,223,229,210,155,112,89,77,75,90,105,105,102,95,85,73,65,60,62,60,57,47,24,95,186,221,239,228,221,217,218,217,214,215,210,209,213,213,213,212,212,212,209,211,210,208,210,209,208,210,206,208,207,205,206,204,205,200,200,201,198,197,197,197,198,192,202,114,3,1,5,8,8,8,10,10,10,11,11,10,218,222,219,217,220,218,217,220,221,221,222,222,217,216,218,216,216,214,215,215,217,216,217,216,215,217,215,216,216,214,217,217,216,217,214,216,214,213,215,214,214,214,215,213,215,215,214,214,215,217,217,216,216,216,218,218,215,219,220,219,222,220,221,221,221,221,221,223,221,221,219,221,222,219,222,220,221,219,219,221,219,220,220,223,219,222,223,221,223,219,221,224,221,221,223,221,224,222,222,224,222,223,224,222,223,224,223,225,226,227,225,226,225,226,229,226,228,229,229,231,230,229,232,232,231,232,231,232,232,232,232,232,232,235,235,234,236,234,234,235,236,235,234,236,233,235,235,235,237,236,236,236,236,237,239,237,237,237,238,237,237,239,239,236,236,239,240,239,238,237,237,239,241,241,241,241,242,242,241,240,241,242,240,240,240,241,242,241,244,242,243,244,243,244,244,244,244,245,245,245,247,246,247,248,248,247,246,247,247,247,246,245,248,248,249,248,249,249,248,249,248,248,246,247,249,249,250,247,247,247,247,247,247,248,249,249,249,247,247,247,249,249,248,248,249,249,249,248,249,249,249,250,249,249,249,249,249,249,248,247,248,247,248,249,247,247,247,247,249,248,247,248,248,248,249,248,248,248,248,250,249,249,250,249,249,247,248,248,247,249,250,250,240,241,250,249,249,248,249,249,247,248,247,247,249,249,250,243,241,245,248,249,245,246,249,248,247,244,244,247,247,247,247,244,247,247,247,247,246,247,245,245,247,247,247,247,247,241,240,243,247,247,248,247,249,236,231,243,191,196,228,225,239,237,249,251,249,207,170,164,153,115,43,192,249,248,249,236,251,252,239,193,211,247,250,250,250,245,246,250,252,244,252,235,225,251,249,226,211,249,240,240,250,247,252,252,250,241,252,252,247,236,232,252,252,252,252,252,222,140,125,130,113,109,29,99,247,247,247,247,249,252,250,248,244,246,248,249,245,248,252,252,252,250,250,252,246,248,252,252,241,243,201,190,252,252,250,250,248,251,250,251,251,247,237,250,252,247,241,253,195,91,28,20,57,26,12,27,33,42,54,51,56,81,68,51,39,31,34,36,37,34,36,55,89,84,58,44,28,35,40,66,78,61,50,59,10,93,227,240,250,250,252,252,249,252,248,242,241,244,250,249,236,241,253,253,207,206,247,210,202,224,251,249,201,237,231,214,247,246,244,244,247,246,246,247,246,246,245,244,245,246,248,245,244,242,246,244,244,243,253,251,148,102,69,6,59,212,242,250,252,242,243,231,219,201,213,227,227,225,222,253,217,114,173,231,232,226,226,243,236,241,240,239,237,236,236,235,233,235,236,235,234,233,233,232,233,230,231,229,230,229,231,232,227,227,224,225,225,222,226,222,222,225,223,224,222,223,223,224,223,219,221,219,221,222,219,222,222,220,218,215,217,219,217,216,215,217,217,222,229,236,240,198,134,101,91,85,78,91,87,93,97,92,99,94,93,89,91,86,81,86,65,117,194,219,243,243,245,233,227,224,214,213,213,213,213,211,210,209,210,211,212,212,211,208,206,208,209,206,207,207,204,203,202,204,203,203,203,200,198,198,198,198,200,193,202,113,4,1,4,8,9,8,10,10,11,11,10,11,218,223,222,220,222,220,220,219,222,220,219,219,218,216,216,218,214,215,217,216,216,216,218,217,217,217,218,217,215,217,215,216,217,218,217,215,214,215,214,212,215,213,215,215,213,215,212,214,213,215,214,215,220,215,216,215,220,219,218,222,220,222,222,222,223,223,221,223,221,222,222,222,221,220,219,220,222,218,220,221,220,218,220,221,219,219,221,220,220,222,221,223,222,222,223,221,221,222,223,223,222,224,225,224,225,221,223,224,226,224,224,227,227,228,229,230,230,232,230,229,232,232,232,231,231,234,232,233,234,231,234,235,234,234,233,237,236,235,236,237,238,235,237,237,235,236,234,235,237,237,238,237,237,236,236,238,237,237,237,237,240,238,239,239,236,238,239,238,239,240,237,239,239,240,241,239,240,241,241,240,242,242,240,241,243,243,243,243,244,245,244,244,244,244,244,244,245,246,246,247,247,247,247,248,248,247,247,247,248,247,247,248,247,246,247,247,247,247,247,248,249,249,250,248,248,249,248,249,249,249,248,247,247,248,248,249,249,249,249,248,248,247,249,249,249,249,249,249,247,249,248,248,248,248,249,247,248,247,248,248,249,249,248,248,248,248,248,248,247,248,247,248,248,247,248,248,249,249,249,249,247,250,249,249,249,247,249,249,248,249,249,249,240,244,251,248,250,249,248,248,248,248,248,249,249,250,249,244,242,248,247,247,245,247,249,247,248,244,246,247,245,248,247,247,248,246,245,247,245,245,247,245,247,245,247,248,247,246,241,240,244,248,249,247,251,237,242,247,221,236,252,236,208,225,249,250,248,200,160,152,138,97,44,198,249,247,250,239,252,252,244,190,208,246,251,251,250,249,246,249,252,243,250,212,190,243,241,242,251,252,243,252,252,245,252,252,250,242,252,252,247,232,226,250,251,251,252,252,215,127,105,109,103,101,29,107,247,247,247,246,250,252,249,247,244,243,245,248,242,252,252,252,251,249,250,252,244,249,252,252,238,235,189,168,244,249,249,249,249,251,250,251,251,246,241,252,252,234,230,219,156,98,33,11,44,39,34,49,46,44,51,44,55,87,73,55,44,30,32,37,32,28,46,77,89,71,57,44,32,34,45,77,80,61,59,55,19,145,242,242,250,250,252,252,248,252,247,244,242,244,247,251,239,237,250,252,220,192,240,220,201,217,231,240,194,214,193,171,221,240,244,244,249,250,247,248,249,245,246,247,246,246,245,244,244,243,247,243,246,241,253,245,139,101,67,5,67,218,240,250,252,245,239,232,222,203,210,224,225,229,224,251,202,95,168,231,227,227,227,241,236,239,239,236,234,233,234,233,232,235,234,232,232,231,232,230,231,230,232,230,226,227,227,229,227,224,225,225,224,226,226,222,221,222,223,223,222,222,222,220,222,223,221,220,220,222,220,221,219,218,220,218,217,217,217,217,218,223,228,235,245,245,221,167,129,117,108,111,113,118,114,107,93,85,92,93,92,87,82,77,79,75,70,72,73,119,197,225,246,246,249,226,212,214,214,215,212,210,210,211,210,208,208,210,210,206,209,208,207,207,204,204,202,205,206,201,202,203,202,202,201,200,200,198,205,199,201,113,3,1,4,7,9,8,10,10,11,11,10,12,218,223,222,221,221,219,222,222,220,219,216,219,218,220,219,217,215,217,217,217,220,214,215,214,214,218,213,214,214,214,214,215,216,214,214,216,214,214,216,214,214,214,216,213,214,214,213,215,213,214,216,214,217,216,216,218,217,218,221,219,222,220,220,220,222,224,221,221,221,220,220,220,222,220,221,218,220,221,220,220,220,220,217,218,218,220,219,218,222,219,218,220,221,221,218,220,222,218,221,223,222,221,223,224,224,224,221,223,221,223,224,226,225,226,228,227,228,229,230,231,231,230,232,232,230,232,234,232,231,233,233,232,232,233,231,233,235,232,234,234,235,234,234,233,234,237,233,236,235,234,235,234,233,234,234,236,237,235,236,236,235,235,235,236,237,236,235,237,237,238,237,237,239,237,239,239,237,238,239,239,240,240,240,242,242,242,242,242,243,240,243,244,243,244,244,245,246,246,246,245,246,247,246,248,247,247,247,247,248,247,248,248,246,247,248,247,248,246,248,249,247,247,248,249,248,248,248,248,247,247,248,247,249,249,247,247,249,249,248,249,249,249,247,249,249,249,249,247,247,248,248,247,247,248,247,248,249,249,248,248,248,247,248,248,247,248,249,249,248,248,248,249,249,248,249,248,249,248,248,249,248,248,249,249,248,248,249,248,249,249,251,246,237,247,250,247,249,248,248,248,248,248,248,249,248,249,246,241,246,247,247,245,244,249,248,248,249,244,244,247,247,247,247,247,247,247,246,245,245,246,246,247,245,246,246,246,247,249,245,242,241,246,248,248,248,237,251,252,236,250,231,190,209,236,252,252,249,209,166,152,131,91,47,199,250,250,249,235,252,252,247,191,174,238,251,251,250,247,242,249,252,243,250,191,191,247,252,249,251,251,237,246,232,232,252,252,250,240,252,252,249,231,225,252,252,252,252,252,207,120,102,112,94,98,24,101,248,248,247,246,249,252,250,246,245,246,246,242,244,252,252,252,252,249,250,251,241,251,252,252,241,245,227,178,237,249,250,250,248,251,250,249,251,241,243,252,247,217,220,239,227,190,121,91,93,83,79,84,62,46,49,47,53,89,80,54,49,35,36,35,30,36,52,89,92,61,44,34,39,44,57,83,79,60,63,50,37,191,246,242,251,250,252,251,249,252,244,245,242,241,246,250,242,236,244,252,236,193,230,237,202,219,221,222,201,197,180,168,208,238,246,243,246,246,246,247,246,247,246,246,245,244,245,242,244,242,244,242,245,242,253,240,128,94,57,4,80,224,243,250,252,241,237,228,222,204,211,223,226,227,235,250,186,80,159,228,232,223,229,240,234,236,234,233,233,233,233,234,232,230,230,230,230,229,229,229,227,228,226,226,228,224,223,226,225,226,225,225,224,222,225,223,223,224,222,222,221,222,221,220,221,218,220,222,218,217,216,219,217,216,218,216,217,216,214,219,226,233,246,246,221,185,159,143,135,126,118,122,126,127,113,110,77,59,69,49,49,50,46,51,47,45,47,42,43,20,25,106,163,199,224,209,208,214,215,212,210,212,212,210,210,209,206,208,208,206,206,205,205,205,205,206,205,204,202,203,202,201,203,200,200,201,202,203,203,197,205,113,4,1,5,9,9,9,10,10,10,11,12,12,220,222,219,220,223,221,221,219,222,221,219,219,220,219,219,219,217,217,216,217,216,216,216,214,215,214,214,213,213,214,214,216,217,214,214,214,216,215,217,216,216,215,215,215,214,216,214,217,215,217,216,215,217,216,218,218,218,216,217,221,221,221,221,220,220,220,222,223,221,221,222,219,222,222,219,219,222,222,217,221,219,217,220,221,219,217,218,219,221,219,218,220,219,218,221,221,221,220,219,221,222,221,221,222,224,222,224,225,222,222,225,227,227,226,229,228,227,230,229,232,230,229,232,230,232,232,230,233,232,234,235,234,235,235,234,234,234,235,235,235,233,233,234,234,237,237,236,236,237,237,236,236,236,237,236,239,236,236,237,237,237,235,237,237,236,238,238,238,238,238,239,239,239,239,240,240,239,239,239,239,240,240,241,239,241,241,242,244,242,244,244,244,245,245,245,245,245,246,246,245,246,246,246,246,247,247,247,248,247,247,246,247,248,245,247,247,246,247,245,247,249,248,249,248,247,249,249,249,249,249,247,247,249,248,248,249,249,249,249,249,248,248,249,249,249,249,249,249,248,249,248,249,248,247,249,248,249,248,249,248,249,249,248,250,248,248,249,249,249,248,247,249,249,248,249,248,248,248,249,249,248,248,248,248,248,249,249,249,249,249,250,242,239,249,248,249,249,247,248,248,248,248,248,247,249,250,244,243,249,249,245,243,247,249,247,247,248,247,245,247,246,247,247,246,245,245,247,245,247,246,247,247,247,246,246,247,247,248,247,243,240,242,247,249,247,235,248,239,205,199,198,212,232,249,252,246,249,208,174,169,153,96,53,209,249,249,249,234,252,250,247,190,151,222,250,252,249,247,241,247,249,231,223,201,227,251,252,252,250,250,203,198,222,239,252,252,251,241,252,252,250,229,234,252,251,251,252,252,210,131,122,126,111,99,21,113,248,248,247,245,249,252,250,246,244,248,246,235,238,252,252,252,252,250,250,247,245,251,249,252,248,249,240,181,228,249,250,250,249,252,249,251,250,238,247,252,243,238,252,252,252,252,193,151,132,81,71,102,91,66,71,69,74,65,46,54,46,41,36,33,38,46,66,82,71,53,35,38,47,46,68,81,79,61,62,39,41,207,247,239,252,250,252,250,249,251,244,247,244,239,246,249,246,231,241,252,251,210,218,247,213,195,174,180,223,205,188,214,217,234,246,242,249,247,246,247,247,246,245,246,245,246,245,244,245,243,246,241,246,241,253,232,122,97,48,3,90,226,241,250,252,242,237,230,223,205,207,224,230,230,244,253,169,68,151,226,221,221,232,238,237,237,234,232,231,232,233,232,229,230,231,229,229,225,229,226,225,227,225,226,225,226,226,225,225,224,226,225,223,223,222,222,223,223,221,221,221,220,220,220,221,218,218,221,217,219,218,218,216,214,217,216,217,215,218,226,229,241,226,177,146,116,102,94,91,85,69,74,71,63,66,94,89,65,52,39,36,31,34,33,31,31,32,41,56,62,48,39,10,21,113,174,202,214,211,214,210,211,209,209,210,208,207,210,210,205,206,207,207,208,207,208,207,204,205,206,204,202,203,205,201,202,205,203,205,199,204,113,3,1,5,8,9,9,12,10,10,11,12,12,219,222,220,221,222,219,218,220,220,219,219,221,218,217,218,218,216,217,218,214,217,214,215,216,216,222,216,213,214,215,217,215,216,217,216,216,215,215,214,216,214,213,214,212,215,214,214,217,217,217,217,217,217,217,216,218,219,220,219,217,219,219,222,222,220,221,220,221,222,220,220,222,220,216,219,219,218,219,218,217,221,222,222,218,217,219,220,221,219,217,218,219,219,220,219,220,222,224,223,223,222,222,224,220,221,223,223,225,225,225,225,227,229,229,228,228,227,227,230,229,229,229,229,231,231,229,234,232,229,234,232,234,234,233,234,234,234,233,235,233,236,235,235,233,233,236,234,235,233,234,237,235,234,236,236,237,236,236,238,235,237,238,237,239,237,237,237,238,238,237,238,237,239,238,238,239,238,240,240,239,240,240,240,241,241,241,240,243,244,243,243,244,245,246,246,245,245,245,246,245,247,247,246,248,245,246,245,245,247,245,248,247,245,247,248,249,247,246,248,247,248,247,249,249,247,247,248,248,248,247,248,248,248,248,247,249,249,247,249,249,248,249,248,249,248,248,248,247,248,247,249,248,248,249,247,248,248,247,248,248,247,248,248,249,248,248,247,248,247,247,247,247,247,248,247,248,249,247,248,248,248,248,247,247,249,248,248,249,247,250,249,240,243,249,248,248,248,248,249,249,248,247,247,248,248,247,242,245,251,249,245,242,245,248,247,245,247,246,242,246,247,247,247,246,247,245,247,247,247,247,247,247,245,247,247,247,247,248,248,250,244,239,243,249,247,229,242,213,200,236,236,240,234,236,251,244,249,209,170,169,154,100,57,206,249,249,249,236,252,248,248,205,179,239,252,252,249,250,243,248,245,245,246,223,251,252,250,226,235,239,213,240,240,246,251,250,251,240,252,252,250,224,225,252,250,251,252,252,217,139,123,137,116,110,28,109,249,249,248,247,250,252,248,244,244,248,245,232,246,252,251,251,252,250,248,245,246,251,249,252,248,245,242,187,229,250,250,250,248,250,250,251,249,238,250,252,238,245,252,252,252,252,162,100,87,43,50,92,105,72,97,163,139,90,44,70,84,44,37,50,66,82,94,79,59,45,42,39,44,45,62,81,75,60,63,33,40,208,248,240,252,249,252,251,250,250,243,247,244,239,244,248,249,233,237,252,252,223,204,247,194,144,135,153,232,221,186,229,230,228,245,240,247,248,247,248,245,247,247,246,245,244,246,245,244,242,245,242,245,241,252,225,117,97,47,3,104,230,239,250,250,239,235,224,221,205,205,219,228,230,247,234,148,62,145,226,225,225,230,237,234,236,235,232,234,232,229,231,231,229,229,229,228,229,226,224,226,227,225,227,227,223,224,227,225,224,225,225,224,224,224,223,222,221,223,222,220,223,220,220,222,219,220,218,217,220,217,218,218,217,218,215,215,215,217,225,210,168,137,102,83,73,46,24,22,36,45,41,46,42,46,73,73,63,57,34,34,34,33,35,32,33,43,68,71,67,54,42,24,11,83,159,197,214,207,210,211,209,209,210,207,208,212,209,209,208,209,207,207,208,205,204,205,207,206,206,206,205,205,205,205,204,201,202,206,202,206,112,4,1,4,8,10,9,10,10,11,11,12,12,222,222,222,219,218,218,217,220,220,219,221,219,219,219,217,215,218,217,215,215,214,215,217,216,216,214,215,217,215,216,217,215,214,217,215,214,217,214,217,216,217,216,214,215,217,215,216,217,218,220,216,219,220,219,220,219,221,222,219,219,220,217,218,222,221,222,222,220,221,217,219,218,218,218,218,219,219,221,219,220,218,218,219,218,217,218,219,218,220,219,219,219,223,221,220,220,220,223,221,222,219,220,222,222,224,221,221,221,223,225,224,224,224,226,227,225,227,229,225,229,229,228,229,229,231,229,231,231,230,230,230,229,231,231,231,234,233,234,232,233,234,235,234,233,233,234,235,235,235,233,234,235,234,234,232,236,237,236,236,235,236,234,237,237,237,238,235,237,238,237,237,236,239,237,236,237,238,239,237,239,239,239,241,240,242,243,241,242,242,243,243,243,243,244,244,244,246,245,244,245,246,246,246,246,246,246,244,244,246,247,247,247,247,245,246,249,248,249,247,247,248,249,248,247,247,248,248,248,247,248,249,250,250,248,247,247,247,247,249,249,248,248,249,248,248,248,248,249,247,248,248,248,248,248,247,249,248,248,248,248,248,248,248,247,248,248,248,248,247,250,248,249,247,247,247,247,248,247,248,248,249,249,247,250,249,249,249,248,248,250,248,239,246,252,248,249,248,248,248,247,248,247,247,248,249,246,242,247,249,248,246,245,247,246,247,248,249,247,242,246,247,247,247,246,247,247,247,247,249,247,246,247,245,246,246,247,245,246,248,248,247,243,241,247,246,240,252,243,237,252,252,220,217,242,251,248,249,208,165,156,140,83,50,202,249,249,249,236,251,246,249,228,193,243,252,250,250,249,246,247,247,252,245,236,249,249,225,219,250,251,239,252,252,244,252,251,250,239,250,252,250,221,225,251,250,252,252,252,214,131,115,119,105,103,26,124,249,249,247,245,252,252,248,246,242,252,247,244,252,252,251,251,251,252,245,246,251,252,249,252,248,242,240,181,225,249,250,250,248,252,250,250,245,237,252,249,240,252,251,253,247,153,79,68,95,61,51,84,100,79,123,196,181,131,92,159,139,67,45,69,111,118,137,104,69,51,38,45,45,35,60,79,74,56,65,35,41,213,249,243,252,249,252,250,250,249,243,248,247,238,244,247,251,238,234,247,252,235,198,239,222,142,128,166,239,221,172,227,241,226,245,244,246,250,246,248,244,244,246,245,245,244,246,245,244,244,245,241,246,241,253,214,111,93,34,1,118,234,240,250,252,243,237,229,221,205,204,215,230,231,251,236,131,60,141,228,215,222,235,236,237,234,235,234,230,231,230,229,229,229,229,227,229,225,226,228,225,229,224,224,224,222,223,225,226,224,228,224,221,225,224,223,223,221,223,221,221,222,218,219,220,217,219,217,216,217,217,218,214,215,214,214,215,212,216,213,155,101,66,23,40,48,32,36,36,44,46,46,46,43,45,64,66,63,56,37,40,36,33,37,35,43,63,74,71,65,46,48,18,49,155,193,210,212,207,212,208,210,208,209,210,208,210,210,208,208,208,208,207,207,206,205,207,207,207,207,207,206,205,207,203,206,205,202,207,200,206,113,4,1,4,9,10,8,10,10,11,12,12,12,217,221,220,220,220,218,219,220,217,218,220,218,221,219,218,218,216,216,218,215,218,217,214,217,214,215,215,214,218,214,216,217,215,217,214,214,214,213,213,217,217,216,218,217,218,218,218,217,214,218,218,218,220,220,218,216,220,220,220,221,221,220,222,218,220,222,219,220,220,220,220,220,220,221,219,219,220,218,218,217,218,217,217,218,220,218,218,219,219,220,220,220,221,222,220,221,220,219,219,220,220,221,221,220,219,222,222,222,223,224,226,224,225,225,226,226,227,227,227,227,228,229,229,229,230,228,230,229,230,232,231,232,234,233,234,232,232,232,234,233,234,234,233,234,235,236,233,235,235,233,233,233,235,237,234,235,236,235,235,234,236,234,235,237,236,236,237,236,237,237,238,239,237,237,237,240,238,237,238,238,239,240,241,241,241,241,241,242,244,243,245,244,243,244,243,244,245,244,246,244,245,246,245,247,247,247,247,247,247,245,247,247,248,249,246,247,248,248,249,248,248,247,247,247,247,247,248,247,248,249,248,248,248,248,247,247,248,248,248,248,248,247,248,249,247,249,249,247,249,248,248,248,248,247,247,248,248,248,248,248,248,247,247,247,247,248,247,247,247,247,248,248,248,248,247,247,248,248,249,247,247,248,248,248,249,248,247,249,247,251,244,237,249,249,249,249,249,249,248,248,248,249,247,249,249,241,244,248,248,247,243,248,247,246,247,245,249,249,244,244,247,247,247,246,245,245,247,246,247,246,247,247,246,247,247,247,248,247,247,247,249,249,243,244,242,245,252,240,241,241,201,212,245,251,252,242,249,202,152,155,134,84,51,198,249,249,248,238,252,247,249,219,174,214,248,251,249,249,246,250,240,252,222,176,216,239,249,249,252,250,242,252,242,237,252,251,250,241,249,252,250,227,234,252,250,251,252,252,210,120,99,108,99,103,24,117,248,248,247,245,249,252,249,244,244,252,242,235,252,252,250,250,251,250,242,247,252,252,250,252,250,235,239,164,172,246,250,251,249,249,250,250,240,241,252,243,243,252,223,234,174,92,81,81,136,121,71,54,68,45,79,170,151,116,87,157,128,48,40,39,72,100,137,118,72,50,42,48,44,47,68,78,71,57,66,32,51,219,249,248,252,248,252,249,250,249,241,247,247,239,240,244,251,240,234,245,251,246,199,230,250,192,164,176,225,244,205,223,248,224,237,244,239,248,245,246,246,244,245,245,244,245,245,246,247,245,247,242,247,242,252,207,107,89,31,0,125,236,239,250,249,240,234,222,220,207,204,212,226,235,247,229,128,58,137,230,217,222,231,237,236,235,232,229,232,229,228,230,229,228,229,226,224,226,225,225,226,224,222,224,224,224,225,226,226,224,224,224,224,223,220,222,220,220,220,218,218,220,220,217,220,217,217,218,214,216,214,217,215,212,215,214,213,215,215,214,153,92,65,21,15,25,47,66,57,55,49,47,47,41,58,79,73,63,55,41,36,32,33,35,30,50,82,80,75,56,49,27,61,180,221,216,214,214,216,212,209,210,206,207,208,209,208,208,208,207,211,208,208,209,206,208,209,211,208,208,207,206,206,206,203,202,203,204,205,198,205,113,3,1,5,8,9,9,12,10,10,12,11,11,220,221,218,217,219,218,215,217,217,217,220,216,216,219,220,217,218,217,216,217,218,218,217,218,218,217,216,216,217,215,217,216,217,215,217,218,215,217,216,216,217,217,217,218,218,217,219,218,219,219,217,218,220,218,217,217,217,219,220,220,218,221,219,218,221,219,219,220,221,222,222,222,222,222,220,220,219,219,219,218,220,220,218,219,218,220,219,216,219,216,220,220,221,219,218,222,220,221,220,221,222,221,222,224,222,222,225,224,223,222,226,227,226,227,227,226,228,229,227,229,227,229,230,230,229,230,232,229,229,233,231,230,232,232,231,232,233,233,232,231,233,233,234,235,234,232,233,232,233,234,232,235,236,235,235,233,235,236,234,235,237,236,237,236,237,238,236,239,239,236,237,238,238,237,239,237,238,239,239,239,239,240,241,241,241,241,242,243,242,244,244,244,244,244,244,245,244,244,246,246,246,246,245,246,247,247,247,247,246,248,247,245,249,248,248,249,247,247,247,248,248,249,248,248,249,249,249,247,249,249,248,249,248,248,249,249,249,248,249,250,249,249,249,248,248,248,248,249,249,248,248,248,248,247,247,248,247,248,248,248,247,247,248,247,248,248,247,247,248,248,247,247,247,248,249,249,247,248,249,249,248,248,248,248,249,247,247,247,249,251,241,241,251,249,249,247,249,249,248,249,247,247,248,248,246,241,246,248,248,244,245,248,247,246,245,245,248,249,247,245,247,248,247,246,246,246,245,245,248,246,247,248,248,248,247,249,247,248,247,248,248,249,248,244,235,233,253,214,185,199,218,236,249,250,251,243,249,209,166,169,144,85,60,202,249,249,248,240,252,249,247,217,163,210,251,250,250,249,251,246,237,235,181,194,246,252,252,252,250,241,211,232,236,239,252,251,251,240,247,252,250,229,236,252,250,251,252,252,207,129,117,113,103,99,21,122,249,249,247,245,252,252,249,246,245,251,215,190,237,249,251,251,252,250,237,249,252,250,250,251,251,240,243,152,163,245,250,252,249,248,251,249,239,243,252,227,235,217,156,218,180,170,150,60,120,109,73,46,54,51,67,127,131,119,63,133,109,47,52,27,65,81,106,113,80,51,44,41,39,57,81,77,73,59,64,32,49,222,249,249,251,248,252,249,249,248,243,247,247,240,240,244,251,245,233,243,251,251,204,213,252,213,162,172,211,241,214,215,249,205,202,232,233,249,249,248,246,243,247,245,244,244,244,244,245,243,244,243,246,245,252,200,104,87,24,1,143,236,242,250,250,241,231,224,219,211,206,212,226,229,249,224,127,56,135,234,211,224,232,231,238,232,233,230,227,229,229,227,228,227,225,226,227,226,223,225,223,225,224,223,226,224,226,226,223,222,223,224,223,224,219,220,221,219,222,218,218,217,218,221,216,214,217,214,217,217,214,216,214,215,213,214,214,211,218,216,170,132,115,77,72,77,66,77,79,67,55,49,50,49,59,72,67,62,58,44,39,34,31,34,41,73,86,86,70,60,44,40,148,217,226,217,214,217,212,212,206,207,207,206,210,209,211,210,208,209,208,210,208,208,208,208,210,210,208,211,206,203,206,206,202,202,203,200,204,201,208,113,2,1,5,8,9,8,12,10,10,11,12,12,219,222,218,217,217,218,217,217,217,219,218,217,220,216,217,217,215,217,218,215,216,218,217,218,217,217,217,217,217,214,216,216,216,218,216,217,218,217,217,217,218,216,220,219,217,218,218,219,221,220,218,220,220,220,219,220,221,220,220,218,219,218,219,218,218,220,221,222,221,221,221,220,219,221,220,221,219,217,221,219,219,220,218,217,218,221,220,218,219,217,217,218,218,219,220,218,218,220,220,221,220,221,222,220,222,223,222,222,224,224,223,222,223,224,223,226,225,225,227,224,226,225,226,226,230,230,229,231,230,231,231,232,232,229,232,232,232,232,232,232,233,232,235,234,232,233,232,232,232,230,231,232,230,232,234,232,235,237,237,237,236,236,237,236,236,237,236,237,239,239,237,239,240,240,238,239,239,238,239,239,240,241,241,241,242,242,243,243,242,243,245,243,244,245,244,245,245,243,244,245,245,247,245,246,245,245,246,247,247,245,247,247,247,248,247,246,249,249,248,248,247,247,248,248,248,247,248,248,249,248,249,250,250,249,248,248,248,249,249,249,249,247,248,250,248,248,248,248,248,248,247,248,248,247,249,249,248,249,249,249,249,248,248,248,248,249,248,248,247,248,248,248,248,247,248,247,248,247,247,248,248,248,249,249,250,250,249,248,249,249,239,244,252,247,248,249,249,249,250,250,248,249,249,250,245,242,249,249,247,244,245,249,246,248,245,245,252,252,252,252,251,248,245,246,246,245,247,246,247,248,247,247,245,247,247,247,247,247,247,247,249,249,248,248,226,229,239,190,209,240,249,220,218,241,249,244,249,211,173,177,150,101,57,195,249,249,248,242,252,249,249,235,181,208,252,252,249,249,250,250,218,209,214,243,251,251,246,244,249,208,199,241,237,243,252,252,252,240,248,252,250,230,235,252,253,253,252,252,231,160,137,134,105,95,15,113,248,248,249,249,252,252,251,250,251,251,206,203,243,248,251,251,251,246,240,252,250,251,250,251,252,239,250,191,176,248,252,252,250,248,252,246,235,248,248,207,218,207,207,252,193,186,167,86,134,117,85,53,51,47,77,163,134,98,62,147,114,51,64,56,106,96,94,101,71,51,39,42,36,56,91,73,73,59,59,32,45,214,249,249,251,246,252,249,250,248,242,247,249,244,239,241,249,246,233,240,250,252,222,205,252,241,169,165,195,225,215,199,238,199,179,215,224,245,249,249,247,244,245,245,244,244,243,244,245,245,249,250,252,252,251,208,125,101,33,7,151,238,248,251,252,234,234,226,218,211,206,214,220,232,248,223,126,53,132,231,214,226,232,236,233,232,234,230,230,229,227,229,226,226,228,225,226,225,224,223,225,223,222,226,224,223,222,223,223,222,224,219,221,222,220,220,219,221,219,220,217,217,218,214,214,214,215,214,214,217,215,213,214,212,212,213,212,212,218,232,202,168,151,116,107,88,71,71,89,87,72,65,50,57,66,69,57,54,53,39,38,43,49,58,69,85,80,65,66,50,44,11,74,190,208,221,220,210,210,208,212,207,207,211,208,210,210,208,210,209,210,209,208,211,210,208,206,209,206,206,206,205,205,204,205,205,204,202,205,200,206,112,4,1,4,8,10,8,10,10,11,11,11,11,217,219,218,217,220,215,216,219,219,218,217,216,216,217,217,214,217,215,217,216,216,218,215,217,216,215,217,215,217,217,218,217,215,216,214,215,215,218,217,215,219,219,220,219,218,220,219,221,222,221,221,222,223,220,220,222,221,221,217,221,220,220,220,220,221,219,221,221,221,219,217,219,221,221,220,222,220,218,223,218,218,219,218,221,219,219,217,218,220,217,220,219,218,221,218,221,220,219,221,220,220,221,219,222,220,221,222,222,223,222,223,223,224,224,226,225,226,226,224,227,226,225,224,228,228,227,227,228,230,230,229,228,231,231,230,232,230,230,234,233,232,231,231,231,231,232,232,233,233,233,232,234,233,232,233,232,234,234,237,236,235,237,236,236,237,237,237,237,238,239,240,239,237,239,241,239,237,237,238,239,239,240,241,241,242,243,242,242,242,243,243,244,245,243,244,244,244,244,245,244,245,245,246,246,246,247,246,247,246,247,249,249,249,247,247,248,249,249,249,248,248,248,248,248,248,248,248,248,250,250,248,248,247,247,249,248,249,248,248,248,248,247,248,248,249,249,249,249,248,249,248,247,248,248,249,249,249,248,248,249,247,249,249,247,247,247,247,248,249,248,247,247,247,249,248,248,247,248,249,249,249,248,249,249,249,248,249,249,250,245,236,245,249,248,249,249,247,249,247,248,248,248,249,248,242,246,249,248,245,244,248,248,247,248,247,248,249,245,252,245,240,247,247,246,246,245,246,246,248,245,247,247,247,249,247,247,247,247,247,247,249,249,249,250,237,239,252,212,230,250,220,203,227,247,252,243,249,210,168,167,138,88,51,189,249,249,247,242,250,246,249,243,180,192,246,250,249,247,252,249,245,245,229,250,249,249,198,187,242,237,241,252,247,247,251,250,251,240,246,252,250,239,244,253,253,253,253,253,230,153,127,122,108,92,16,115,248,248,250,250,252,252,252,252,252,252,239,244,252,252,250,250,252,244,244,252,248,250,251,250,253,244,250,188,161,245,252,252,250,246,252,243,236,252,242,229,251,232,250,253,191,250,186,91,127,79,67,43,57,60,81,178,148,70,31,152,122,57,61,46,113,101,69,56,44,48,46,39,36,61,93,81,71,55,64,30,41,211,249,249,250,244,252,248,250,248,243,247,249,247,239,243,247,249,236,237,249,252,234,202,244,252,206,172,199,205,214,220,229,202,186,211,217,239,250,247,247,245,245,246,245,246,244,246,252,252,253,253,252,252,251,227,139,103,31,10,172,241,250,250,253,253,240,229,218,212,205,206,223,227,249,222,127,52,131,229,206,229,236,231,236,230,235,229,229,230,229,227,229,228,226,226,225,225,222,226,222,221,223,222,224,221,225,224,222,224,222,220,219,220,219,219,219,218,218,216,219,215,215,217,216,215,216,214,215,215,212,214,214,214,212,213,213,212,218,229,210,163,129,107,99,80,53,61,80,83,81,107,118,113,102,71,62,60,48,42,75,112,111,104,106,107,76,64,60,48,29,24,120,179,197,218,214,214,208,210,210,208,212,210,209,210,213,212,210,212,212,211,209,210,212,207,207,210,206,208,207,206,205,206,204,204,205,202,206,200,204,113,4,1,4,8,10,8,10,9,11,11,11,11,220,220,218,220,218,217,217,217,218,216,218,217,215,218,219,218,217,217,217,217,217,218,218,216,217,215,214,217,216,216,217,217,217,215,215,215,215,215,215,214,218,217,218,220,218,219,219,219,220,220,219,219,220,220,219,219,218,216,219,218,217,218,219,217,219,218,220,219,220,219,219,222,221,221,219,223,220,220,221,217,220,220,218,219,217,218,217,217,220,219,220,220,218,220,220,220,221,221,217,220,220,220,222,219,222,221,220,221,221,222,222,221,223,224,223,226,223,226,229,225,228,228,228,227,228,229,226,230,230,227,230,230,230,231,232,230,232,232,230,232,230,229,231,228,231,235,232,231,233,232,232,234,233,234,236,231,235,235,233,236,234,235,237,235,234,237,236,237,238,238,237,239,240,239,238,238,237,236,236,238,239,239,241,241,242,242,243,243,244,243,244,244,244,245,244,244,242,243,245,245,244,245,245,245,245,245,247,247,247,245,248,249,248,249,248,247,248,247,247,248,247,248,247,247,247,248,249,249,248,248,249,248,247,249,249,249,248,248,249,247,248,249,248,249,248,249,247,248,249,248,248,248,249,248,248,247,248,248,248,249,248,248,247,248,248,248,248,249,247,247,247,247,247,248,249,248,248,247,248,249,248,247,248,249,250,248,249,249,249,243,239,249,249,248,248,248,249,247,248,247,248,249,247,244,242,247,249,247,244,246,248,248,247,248,248,246,239,186,172,205,234,249,247,248,245,245,249,248,247,247,246,247,249,249,248,247,247,247,247,247,247,248,250,251,238,252,245,195,207,204,226,231,249,252,249,242,249,203,153,152,124,83,42,186,249,249,247,240,247,246,249,242,190,184,239,250,250,250,252,252,241,230,208,217,239,239,224,239,252,242,252,252,245,248,248,249,251,240,249,252,250,246,237,251,245,243,251,232,151,103,109,122,126,123,57,144,247,247,250,250,253,253,252,252,252,252,244,253,252,252,250,250,250,240,247,252,248,249,249,248,252,237,248,194,144,238,252,252,250,246,252,237,241,252,236,243,252,249,252,247,211,253,202,103,78,32,32,27,60,48,69,194,154,68,39,148,105,47,64,38,109,101,69,54,39,48,45,39,32,44,75,72,73,57,64,36,42,211,249,249,249,243,252,248,250,246,244,249,248,250,241,242,245,249,241,234,245,252,248,200,221,250,235,184,166,158,201,230,222,211,211,213,214,236,248,248,248,247,244,243,244,244,247,252,252,252,253,253,252,252,248,181,99,69,13,34,186,235,212,214,234,234,232,226,215,210,208,208,219,229,247,212,126,51,134,227,208,230,232,234,234,233,231,227,227,225,227,227,224,225,226,224,223,222,224,222,222,224,224,220,220,222,223,225,222,222,222,218,221,220,218,217,217,217,216,216,214,215,214,213,214,214,215,212,212,213,209,211,211,212,214,212,210,210,213,212,166,122,105,92,105,97,88,70,78,71,96,148,141,145,123,109,95,71,49,54,125,150,139,124,123,122,108,83,60,39,31,135,220,221,210,210,213,211,210,208,209,210,211,211,212,211,209,211,212,210,210,208,208,207,208,208,207,209,207,208,208,206,207,205,206,203,204,204,204,199,205,113,2,1,5,8,8,8,12,10,10,11,10,10,217,222,217,219,219,215,219,219,219,218,216,219,220,215,216,214,217,215,215,217,215,217,217,217,218,217,218,218,220,216,215,219,217,218,218,218,217,217,216,216,218,215,219,218,217,221,220,221,219,220,219,217,218,218,220,217,218,218,216,219,218,218,217,217,219,218,220,218,218,220,219,221,221,220,218,220,218,217,221,215,220,220,216,219,216,219,218,220,221,218,220,219,221,219,219,221,220,217,221,220,217,220,220,221,219,221,221,222,220,222,222,223,222,222,224,222,224,223,224,226,226,229,227,228,227,227,228,227,229,230,230,229,231,228,229,230,229,230,229,230,231,232,232,229,230,232,229,229,230,230,232,233,232,232,233,232,232,231,232,234,233,233,234,236,237,237,237,239,239,238,238,239,238,237,237,236,237,237,238,237,239,239,241,240,240,242,241,243,243,243,244,243,243,242,245,244,242,244,244,244,246,245,246,245,246,246,245,247,247,247,246,247,246,245,246,247,249,249,248,247,249,248,248,248,248,248,248,250,249,249,249,249,248,249,249,249,249,249,249,248,248,249,248,248,248,248,249,248,250,248,247,248,249,249,249,249,248,248,248,248,248,248,247,247,248,248,248,248,247,249,248,248,247,248,247,249,248,249,248,247,247,247,250,248,247,248,248,248,249,239,242,250,247,248,248,248,249,248,247,248,249,249,249,243,243,248,248,247,244,248,249,248,247,247,248,249,232,169,185,229,240,249,246,246,246,247,248,247,247,246,247,247,248,249,247,248,248,247,247,247,249,249,248,249,234,252,225,154,209,247,253,241,237,249,247,243,249,204,164,162,136,82,48,202,250,250,247,238,248,247,249,242,188,196,244,250,250,247,252,250,238,184,147,210,252,252,245,252,252,237,217,234,241,250,250,245,252,242,246,252,250,250,205,134,82,80,91,99,107,118,135,143,155,165,128,150,198,190,189,188,196,192,177,170,183,157,201,250,251,251,251,251,249,240,249,251,249,251,251,248,252,237,239,222,165,227,252,251,250,248,252,233,245,251,231,249,252,249,254,206,200,253,127,39,59,27,30,29,61,47,63,188,164,81,35,130,107,61,64,39,112,101,71,55,41,48,50,37,34,34,49,71,75,60,66,32,46,215,249,249,249,242,252,247,250,248,244,249,247,250,245,245,248,251,244,233,244,252,251,203,196,249,239,146,117,139,190,240,201,182,232,228,216,244,248,250,248,246,247,244,245,243,251,251,252,195,126,104,87,92,99,79,66,63,38,39,85,132,142,144,197,222,220,222,211,213,212,207,220,225,249,229,129,50,139,226,202,231,234,233,237,229,233,228,228,227,226,226,228,226,226,225,225,225,221,223,221,222,223,222,225,222,222,221,222,223,221,219,222,220,217,219,217,215,215,215,215,214,215,216,214,213,216,214,213,214,211,211,212,211,210,214,209,213,211,215,182,127,94,84,110,112,96,74,63,47,83,137,132,128,128,117,94,64,49,55,113,131,116,102,105,118,102,82,68,34,40,159,223,222,223,215,213,212,212,210,208,209,212,211,212,213,212,213,211,212,213,212,212,210,212,210,206,209,208,208,209,207,206,206,205,206,205,204,206,201,206,113,2,1,5,8,9,8,12,9,11,12,10,10,215,220,218,218,220,215,217,217,219,217,216,218,214,215,214,214,214,213,214,217,215,215,219,218,217,215,218,218,217,217,216,215,215,217,217,217,216,217,217,217,218,217,217,218,218,220,220,221,217,219,222,217,220,219,215,217,219,218,217,218,219,219,218,219,218,215,220,218,220,218,219,220,218,220,219,221,217,220,220,217,220,218,216,216,217,219,220,220,218,219,221,219,218,220,218,216,217,219,218,220,218,219,222,218,221,221,220,221,219,221,222,221,222,221,222,223,223,225,224,222,227,226,225,228,229,227,224,229,227,226,229,228,229,229,229,229,230,229,228,229,229,230,232,230,230,229,229,232,230,233,233,232,231,231,233,232,232,233,233,234,234,235,236,235,236,237,237,237,238,238,237,239,239,238,239,237,237,237,239,239,239,239,238,239,240,240,241,241,242,241,242,242,243,243,243,242,242,244,244,244,244,244,244,245,245,245,245,246,246,245,246,247,246,247,246,245,247,247,247,247,247,247,248,247,248,249,248,248,249,249,249,249,248,247,247,248,247,248,248,248,247,247,248,249,248,248,248,248,249,248,248,249,248,248,248,248,249,248,248,247,247,249,247,247,248,248,249,247,247,248,247,248,247,249,247,248,249,249,248,247,248,248,248,247,247,247,247,249,246,237,244,249,248,249,247,247,247,247,248,248,248,248,246,241,247,248,248,244,245,249,247,247,245,246,247,248,250,243,252,251,247,247,245,247,247,247,247,246,245,246,248,248,247,247,247,247,247,248,247,247,246,249,249,246,230,252,238,205,230,251,246,191,224,249,247,245,249,209,171,173,145,95,65,219,251,251,248,238,246,246,249,249,207,190,240,250,249,250,252,252,227,179,206,248,251,251,238,252,247,174,182,232,235,252,248,243,252,242,244,252,249,251,178,95,66,57,83,84,105,131,135,141,139,150,129,132,113,88,88,94,100,87,86,77,63,53,173,242,250,250,251,251,248,244,252,250,250,249,250,248,252,244,247,225,156,218,252,252,250,250,252,230,249,246,243,252,251,251,199,113,183,186,99,69,61,65,36,24,79,47,62,197,162,65,36,131,98,66,70,39,108,93,58,48,42,49,49,36,34,33,45,72,79,57,67,34,45,214,249,249,249,240,252,247,250,248,243,249,248,251,246,241,248,251,249,232,240,248,250,216,184,238,238,162,125,170,217,244,202,180,244,243,218,231,244,251,249,247,247,245,244,248,251,251,165,84,55,23,6,6,9,11,36,56,49,59,46,22,69,56,140,200,206,215,201,207,210,211,220,229,248,234,136,53,145,224,206,234,232,235,232,229,232,226,229,227,224,227,227,227,227,225,225,222,222,221,219,221,222,226,225,224,225,222,220,222,222,219,222,220,217,218,215,217,217,216,215,218,218,217,216,215,214,212,213,214,213,214,211,214,212,210,211,211,214,229,217,167,123,86,105,118,103,69,56,42,70,118,119,131,125,112,81,61,41,47,112,111,104,90,99,107,94,78,59,33,29,139,198,208,224,213,214,210,210,213,213,211,213,211,211,215,213,212,212,211,214,211,211,210,212,212,211,212,210,211,209,208,208,205,205,205,203,205,207,202,207,113,3,1,4,8,10,9,10,9,11,11,11,11,219,221,219,219,221,217,218,218,217,220,215,217,216,214,217,217,217,214,217,217,216,218,214,215,219,218,219,215,218,217,218,218,217,217,217,217,217,218,218,217,217,218,220,217,219,221,219,220,219,220,218,220,219,217,217,216,220,220,218,220,219,219,220,220,220,220,220,220,222,220,222,222,223,223,221,221,219,221,220,217,220,217,219,222,218,222,219,219,219,219,222,219,222,222,221,221,222,218,220,220,219,222,221,222,221,222,223,223,220,222,221,221,223,223,224,221,224,224,224,226,227,228,227,229,229,227,229,229,229,229,227,229,231,229,231,231,231,230,230,230,229,230,232,232,232,233,233,232,234,232,232,234,232,234,234,234,235,233,234,235,232,234,235,234,237,236,235,235,237,237,237,240,237,239,241,239,240,239,240,240,240,241,242,241,241,243,241,243,241,242,242,241,243,241,242,242,241,243,244,244,245,245,245,245,245,246,246,247,247,247,245,246,245,246,249,249,248,248,247,247,248,247,248,248,249,248,248,247,248,249,249,249,248,249,248,249,248,248,249,249,247,249,249,249,248,249,249,248,249,248,249,249,249,248,248,248,247,249,249,248,248,249,248,248,248,247,249,249,247,248,248,248,249,249,250,249,247,249,248,248,249,249,249,248,248,248,248,250,245,237,248,250,248,249,247,247,249,248,247,247,248,249,244,242,248,249,248,245,246,248,247,248,246,246,247,250,252,252,252,252,241,244,245,249,247,247,247,244,245,245,247,246,247,248,247,247,247,247,247,246,247,248,250,245,237,252,243,211,224,202,213,219,241,252,246,244,249,207,172,162,138,80,61,218,251,251,248,238,248,244,250,247,205,188,220,249,250,250,252,246,243,204,225,249,248,243,181,208,239,220,224,242,244,252,251,242,251,244,243,251,251,251,180,102,93,84,85,84,80,84,80,81,78,77,67,79,80,71,64,84,94,71,81,75,66,47,149,241,251,251,250,250,246,247,251,249,252,249,250,247,252,250,247,238,157,196,250,250,249,249,248,231,252,237,248,252,235,227,145,115,210,237,160,81,66,84,64,57,95,65,59,168,151,75,48,131,99,56,66,71,127,86,55,45,42,51,48,35,36,26,43,75,70,56,67,34,47,211,249,249,249,242,249,249,250,248,245,250,249,250,248,241,245,249,252,236,239,248,249,233,184,220,251,221,166,203,222,246,245,211,252,243,179,202,233,248,252,246,248,244,245,252,253,197,106,65,52,59,48,28,24,39,54,61,63,63,55,53,33,2,115,196,200,211,192,202,206,204,219,225,251,249,143,58,152,222,203,233,232,235,234,228,234,224,226,229,224,226,227,224,225,224,223,223,223,224,222,223,223,225,225,223,225,223,221,221,222,220,220,219,218,221,217,216,217,215,216,216,215,215,214,215,214,213,212,214,212,210,213,209,208,210,210,216,213,229,206,161,129,101,116,109,92,69,53,35,80,121,107,115,96,86,78,62,45,52,108,105,104,107,91,82,69,60,63,23,58,174,193,207,218,211,213,209,211,213,212,212,216,213,213,214,213,214,211,212,213,210,213,212,213,211,208,214,210,209,210,207,208,206,205,203,204,205,208,205,206,112,4,1,4,7,10,8,10,10,10,11,11,11,216,220,219,217,221,218,216,217,217,216,214,217,216,217,217,215,217,217,216,217,214,215,217,214,215,217,218,215,216,215,214,217,217,214,214,213,215,217,214,218,217,215,218,217,217,218,219,219,219,217,220,217,218,218,218,221,217,221,219,217,220,221,220,219,219,217,221,219,218,220,222,222,219,220,219,220,219,222,220,218,222,222,220,221,220,220,220,220,219,218,220,222,222,222,224,222,220,220,220,221,219,220,222,222,223,220,220,223,219,222,221,222,222,221,224,221,223,225,225,225,225,225,226,227,227,227,227,230,226,228,230,226,228,227,227,227,229,229,230,229,231,230,229,228,229,232,230,233,230,231,231,230,231,232,230,232,233,235,235,232,233,234,232,234,234,232,235,235,236,235,235,236,239,237,236,238,237,237,239,238,239,240,241,241,240,241,243,242,241,243,242,243,242,241,243,242,242,244,243,244,245,244,244,245,245,245,245,246,245,243,246,247,246,247,248,246,248,249,248,247,247,248,248,249,248,248,248,248,248,248,248,249,250,248,250,248,248,248,248,248,247,248,248,247,248,247,248,248,247,248,247,249,248,248,248,247,248,247,248,248,248,248,247,248,249,248,248,247,248,249,248,249,247,247,247,247,247,247,247,247,248,248,248,249,249,250,249,249,240,240,250,249,248,248,249,249,247,248,247,246,249,249,242,245,250,247,245,242,247,247,245,247,246,245,246,247,247,247,249,242,239,242,243,246,246,246,245,245,245,246,245,245,245,248,247,246,247,248,247,247,247,247,249,243,237,252,219,179,199,214,232,223,252,252,246,243,249,201,152,145,122,75,56,215,251,251,248,236,245,242,249,246,204,177,218,249,250,250,252,248,248,198,198,235,239,243,208,230,253,223,244,252,241,252,251,243,251,245,243,249,251,251,176,114,102,73,57,47,56,51,45,47,41,48,42,45,41,48,37,60,77,45,55,50,52,45,38,135,227,246,248,246,244,248,248,250,251,248,249,249,252,252,238,230,162,191,251,251,250,250,240,233,247,209,228,171,141,193,184,212,253,253,181,109,73,94,62,55,98,60,72,168,148,60,39,113,77,57,66,77,125,78,48,42,47,57,44,42,42,24,42,72,72,56,61,27,53,213,249,249,248,242,249,248,251,248,244,250,248,250,250,242,244,247,251,239,236,245,250,242,186,209,252,242,174,198,224,233,247,215,244,234,167,180,214,243,250,246,244,243,243,252,250,152,85,67,68,79,79,62,57,61,59,63,61,60,61,68,40,20,151,215,210,218,190,197,195,203,221,226,252,244,151,63,150,213,207,234,228,233,231,230,230,225,228,226,225,226,222,223,225,220,221,221,222,221,222,224,222,223,223,221,222,219,219,220,219,218,218,217,218,218,215,216,215,213,214,213,211,213,213,213,213,211,212,209,210,212,211,213,208,211,209,210,212,225,202,147,116,77,73,61,53,55,55,42,81,131,122,110,77,62,50,53,39,51,101,103,113,107,85,66,55,50,49,17,73,184,200,214,217,210,213,210,210,212,212,211,211,211,215,214,212,212,213,211,212,212,212,211,211,211,210,208,208,210,206,206,207,205,205,204,204,202,205,201,208,113,2,1,5,8,8,8,12,10,11,12,12,10,215,218,218,215,219,216,215,216,215,216,217,215,214,215,213,213,215,212,214,215,215,220,216,217,216,215,217,214,219,217,216,215,214,217,217,216,214,214,215,217,217,217,219,217,217,217,218,218,217,219,217,220,219,219,222,220,220,219,219,221,220,217,220,220,220,220,219,220,219,219,220,219,222,220,221,221,220,221,218,219,221,220,221,221,221,223,221,222,225,225,223,222,221,221,221,222,224,219,222,222,222,221,220,222,220,220,218,221,221,220,222,222,218,220,222,222,225,224,224,225,225,224,226,227,225,226,226,225,226,229,229,229,228,226,227,229,230,229,230,228,231,231,229,229,229,229,230,230,231,231,231,234,234,233,233,231,232,233,232,234,234,232,233,236,235,232,232,233,235,234,235,237,236,237,239,237,237,237,237,239,240,240,241,240,240,241,240,241,241,242,243,242,242,243,244,244,244,243,244,244,246,246,244,245,245,246,245,245,246,245,246,247,248,248,246,247,248,249,247,247,248,247,249,249,248,247,248,248,248,248,247,249,248,248,249,249,250,251,249,248,248,249,248,248,248,247,247,247,249,248,249,248,248,248,248,249,248,249,247,247,249,249,248,248,248,247,248,247,247,247,247,248,248,247,248,247,247,249,249,247,247,247,248,247,248,247,248,248,238,242,249,248,249,249,249,250,248,248,247,247,249,244,242,247,249,248,245,245,247,247,247,247,245,246,248,246,247,245,247,247,242,242,242,245,245,244,247,245,247,247,245,247,246,248,248,247,247,247,248,247,248,248,249,238,230,247,189,201,244,243,240,207,235,251,244,244,249,194,160,154,131,72,72,232,252,252,248,236,246,242,250,249,213,191,221,249,250,249,252,245,238,164,177,242,251,250,222,248,252,231,245,252,242,252,251,241,250,246,241,248,251,251,174,120,105,71,55,56,60,62,60,61,53,57,53,53,49,55,36,61,85,43,48,52,68,22,31,155,240,248,249,244,245,249,249,250,249,247,250,249,252,251,223,203,149,188,250,250,249,249,235,240,237,190,208,187,206,245,214,246,252,179,160,157,118,113,73,45,94,79,65,151,161,89,42,105,96,78,64,61,105,62,51,50,48,57,44,57,53,26,49,74,70,57,61,26,51,217,249,249,248,246,246,247,252,247,246,249,248,248,250,243,243,247,251,245,234,242,250,250,196,194,246,245,171,186,226,227,237,204,225,228,188,189,201,238,252,248,246,244,245,252,229,123,92,85,88,91,87,71,46,44,49,53,50,55,46,55,39,35,187,234,225,231,195,200,202,208,212,201,240,251,156,68,151,205,202,235,226,231,229,225,233,227,226,226,223,225,225,224,225,223,222,220,222,221,221,223,223,223,222,222,221,217,218,220,217,216,216,217,216,214,215,217,217,214,215,214,212,213,209,214,212,210,212,210,212,211,213,211,210,214,210,212,209,224,199,137,103,69,71,57,44,49,45,41,101,143,131,120,87,68,46,44,39,67,108,101,112,99,78,73,55,46,39,13,103,193,200,217,215,211,212,211,213,213,212,212,212,214,214,213,212,213,212,211,214,210,212,210,212,212,209,211,207,208,208,206,207,206,204,204,207,206,207,203,207,112,3,1,5,8,9,8,10,10,10,11,12,12,216,216,216,214,214,214,213,217,215,213,214,215,214,214,216,214,214,214,215,214,214,216,217,215,216,219,216,217,220,217,219,218,218,215,218,216,215,217,216,220,218,217,219,216,219,218,219,220,219,217,217,219,220,220,220,221,218,222,222,219,221,221,221,221,221,221,220,222,221,220,222,222,219,220,221,219,220,221,222,222,218,220,220,223,222,221,224,222,222,223,223,222,222,221,223,221,221,224,221,222,220,221,219,217,221,219,220,222,219,224,222,221,223,222,223,223,227,224,225,227,227,224,224,227,225,226,229,229,228,228,227,229,229,229,229,229,229,228,229,228,229,229,229,230,231,231,231,232,231,231,232,233,231,233,233,230,233,233,232,232,235,234,232,232,232,233,235,236,236,236,236,237,236,237,237,237,237,237,237,239,242,241,241,241,241,241,241,242,242,243,241,242,242,242,245,243,242,243,245,244,244,245,245,245,245,246,245,245,245,245,245,247,246,247,247,246,249,249,249,248,247,246,247,248,248,248,248,248,248,248,249,248,247,248,248,248,249,248,248,247,249,248,248,247,247,248,248,248,247,247,249,249,249,248,248,249,248,249,248,248,248,247,248,247,248,247,247,247,247,247,247,247,247,247,248,247,249,249,248,248,249,248,248,249,248,247,249,247,237,246,249,247,249,249,249,247,247,247,248,249,249,241,243,248,248,246,244,248,249,247,247,247,246,247,247,247,246,245,247,247,244,242,243,242,243,245,246,247,247,246,246,246,247,247,247,247,247,247,247,245,249,249,251,235,236,252,218,231,253,253,221,188,226,245,245,239,250,198,169,169,144,84,84,240,252,252,249,236,245,242,250,251,228,184,197,246,251,251,251,236,214,189,215,249,250,248,234,252,253,225,232,244,240,252,251,245,249,246,241,246,251,251,165,125,107,72,50,57,66,70,76,64,64,68,61,61,57,63,53,87,92,70,95,79,75,25,114,241,252,252,248,241,248,249,247,248,247,247,248,249,250,252,214,218,155,141,244,249,249,249,231,246,236,241,252,241,252,252,242,220,141,106,178,242,180,136,107,89,108,66,61,164,181,101,80,129,115,115,72,70,107,63,65,61,51,55,41,57,57,39,59,72,70,55,62,28,47,208,249,249,248,247,246,244,250,247,247,249,249,249,250,245,242,246,252,247,232,241,252,252,206,188,232,248,191,171,229,214,195,207,218,223,226,212,193,230,246,249,246,252,252,252,230,116,94,83,87,108,94,59,39,35,37,41,41,49,35,52,31,35,192,234,234,234,217,222,222,212,228,222,250,231,126,73,167,204,211,232,225,234,227,227,227,224,227,224,223,225,224,223,224,222,224,221,221,221,222,224,223,222,220,221,221,220,219,218,219,218,217,216,218,216,216,216,214,215,214,215,212,211,212,213,214,212,211,212,212,209,208,212,206,211,210,212,211,220,192,132,94,66,80,73,56,52,56,50,102,152,131,122,95,66,51,47,38,93,115,100,111,93,76,69,53,50,18,42,161,209,209,215,210,211,211,210,208,211,211,213,215,212,213,214,214,213,211,211,211,210,210,211,210,212,211,211,210,209,208,208,207,205,204,206,206,205,208,203,207,112,3,1,4,8,9,8,10,10,11,11,10,11,218,220,218,217,218,216,214,215,216,214,216,215,214,214,214,215,217,215,217,218,215,216,214,217,215,216,219,217,216,217,219,216,218,216,217,217,216,219,217,217,218,217,220,220,220,221,218,220,220,221,217,218,219,219,221,219,219,219,218,222,222,220,223,220,219,221,220,221,222,223,223,220,222,220,220,222,220,223,222,221,224,222,221,222,221,221,222,221,220,219,222,223,221,222,223,222,222,222,223,221,222,222,220,222,221,220,220,221,222,219,220,221,224,226,223,224,226,226,225,226,227,225,229,228,227,228,227,229,227,228,229,228,228,227,227,227,225,226,229,229,229,228,229,229,231,231,231,230,229,231,232,233,232,232,234,232,233,234,232,234,234,234,234,234,237,237,237,237,237,237,235,236,236,236,235,234,236,236,238,239,239,239,240,240,241,240,240,241,240,241,242,242,242,242,242,243,243,242,244,243,245,245,244,246,246,245,245,246,246,246,247,247,248,247,247,248,247,247,247,247,248,247,248,247,247,248,248,248,248,248,248,249,248,248,248,248,247,248,247,248,248,247,248,249,248,248,249,248,248,249,249,247,248,248,249,248,247,248,248,248,248,248,247,247,248,248,249,248,247,248,248,248,248,248,247,247,247,249,247,247,248,247,249,247,247,247,249,243,238,247,249,248,249,247,247,250,247,248,247,249,247,240,247,248,247,245,244,248,247,247,247,247,246,246,246,247,247,247,247,247,245,244,245,244,244,243,244,244,246,247,247,247,246,246,245,245,247,247,245,247,248,250,252,236,246,252,210,233,227,206,233,213,233,241,232,237,250,197,167,154,130,77,83,233,251,251,249,238,244,240,250,252,222,190,196,243,250,252,250,228,221,195,217,250,251,246,245,252,231,181,189,235,238,252,251,243,246,246,236,243,250,240,165,136,116,88,57,60,66,50,53,59,54,57,58,53,50,60,55,80,80,57,73,78,69,26,161,241,249,249,244,241,251,248,249,249,248,250,248,249,250,252,232,241,165,125,227,246,249,249,226,241,235,252,252,252,252,252,229,196,113,81,195,246,231,177,121,94,110,85,64,153,173,112,81,96,114,122,81,91,131,113,100,67,53,54,34,52,54,33,57,74,74,55,61,32,39,200,249,249,248,248,247,242,251,245,247,249,248,248,249,248,241,245,250,251,232,236,249,252,222,184,222,251,207,157,181,150,158,227,225,196,234,240,197,226,248,247,252,252,253,253,191,101,81,73,91,104,96,57,37,39,34,37,40,46,39,46,26,37,197,237,239,248,234,245,239,243,248,246,247,210,96,80,184,204,205,234,226,234,228,227,229,223,226,224,224,225,223,224,224,222,224,223,221,222,222,221,222,222,221,218,221,218,220,219,214,218,216,216,217,214,213,214,214,212,215,214,214,214,209,214,212,210,213,212,212,208,211,209,207,209,207,211,208,218,198,139,93,59,78,79,61,57,69,62,123,152,128,122,88,66,50,42,69,117,121,110,116,101,81,56,47,30,27,118,214,223,218,216,214,213,212,210,207,210,212,213,214,214,213,213,214,215,213,210,210,210,211,212,211,208,211,212,212,211,209,208,207,206,208,207,206,205,208,207,207,111,3,1,4,8,9,8,10,10,11,11,10,12,216,221,218,216,217,216,217,216,215,217,214,214,217,214,215,213,215,217,214,215,214,216,218,214,216,217,215,215,217,215,215,214,215,216,216,218,216,216,217,217,217,218,220,218,221,218,218,219,219,222,219,219,220,219,220,218,217,220,220,219,222,221,221,220,220,221,220,221,219,220,222,220,220,222,221,220,222,220,222,221,219,221,218,219,218,218,219,220,220,218,220,219,220,219,219,220,220,221,221,220,222,220,222,220,220,220,218,221,220,222,222,222,224,222,224,223,224,225,226,227,226,225,226,228,227,228,228,225,228,229,228,228,226,227,225,226,229,225,226,224,226,228,229,229,229,228,230,230,229,229,230,232,231,234,233,231,232,233,232,234,236,234,235,235,235,235,235,235,235,235,236,237,236,237,237,237,237,237,238,238,239,239,239,239,242,241,240,241,241,242,241,243,243,242,243,242,244,242,243,244,243,245,244,245,245,246,246,245,247,246,248,249,246,247,247,246,247,247,247,247,247,247,247,247,246,247,247,247,247,247,247,247,247,248,248,247,248,248,249,248,248,247,247,248,247,249,248,248,249,248,247,247,247,247,248,248,248,247,246,248,248,247,247,248,248,247,248,247,247,247,247,248,248,248,248,247,247,247,247,248,247,249,248,247,247,248,249,239,240,249,248,248,247,249,248,247,249,247,248,249,243,241,248,249,247,244,246,248,246,247,246,245,247,247,246,246,246,246,247,247,247,244,246,246,246,245,244,246,247,247,247,247,247,247,246,245,247,247,247,247,247,247,250,227,245,241,167,196,213,237,253,236,229,218,222,233,249,186,147,142,124,69,83,234,251,251,249,237,243,239,248,251,225,196,205,247,251,252,250,221,211,201,229,251,252,231,209,219,186,177,218,242,241,251,252,247,246,243,237,248,250,237,152,129,124,97,69,69,67,57,51,44,51,51,47,49,46,52,44,68,80,51,54,62,51,35,162,239,250,250,243,244,252,248,247,247,248,249,249,250,249,252,236,252,198,132,233,247,249,247,225,237,239,252,253,253,232,184,164,182,163,142,213,249,218,124,83,66,85,77,67,151,149,74,78,84,100,116,79,113,158,133,98,51,54,61,46,63,50,34,57,70,73,56,64,27,49,217,250,250,248,248,249,239,248,243,247,249,247,246,248,249,240,244,248,251,235,234,245,252,231,181,212,244,223,121,117,181,195,244,222,165,211,244,213,223,245,246,252,252,224,165,113,77,88,76,85,101,87,56,39,36,34,40,45,42,36,46,24,46,208,234,234,234,222,231,234,234,252,252,245,205,92,97,194,203,216,229,227,233,228,225,227,225,227,227,226,225,224,225,225,224,222,225,225,222,222,222,221,219,221,222,220,216,218,218,216,217,214,216,216,215,214,212,213,214,213,212,210,213,211,208,211,213,209,207,210,208,209,210,206,211,207,207,208,217,210,160,107,72,89,85,69,66,82,70,120,168,136,120,88,55,57,45,83,150,122,119,117,90,77,58,39,22,98,203,229,221,215,215,214,212,210,210,211,211,213,214,212,214,214,214,212,213,213,212,211,213,212,209,211,213,212,211,212,212,209,209,208,208,205,205,208,205,208,203,208,113,2,1,5,8,8,8,10,10,10,12,10,10,214,218,216,216,216,214,216,218,217,214,217,216,216,216,216,214,214,214,213,213,214,216,214,217,215,215,214,214,216,214,216,214,217,217,217,218,214,216,216,218,218,218,220,217,217,220,219,218,218,220,220,219,219,217,221,219,217,219,220,220,218,220,222,219,223,223,222,221,218,222,219,218,220,220,219,219,219,219,219,217,219,219,217,218,220,218,220,219,220,220,218,220,221,221,220,221,220,218,220,221,222,221,218,220,220,220,220,222,222,220,222,222,222,224,221,223,223,223,225,226,227,226,227,226,225,226,227,228,226,226,228,229,230,229,229,227,227,229,227,228,227,229,229,228,229,229,230,230,232,232,231,231,232,232,234,234,235,234,234,233,233,235,235,236,236,234,235,235,237,236,237,238,236,240,238,238,240,239,239,239,240,240,238,239,241,240,242,243,240,241,242,242,241,243,243,244,242,242,244,244,245,245,245,246,246,247,245,247,246,246,246,245,247,246,248,248,248,248,246,247,247,247,247,246,247,247,248,247,247,247,248,248,247,248,248,248,249,249,248,248,247,248,249,249,249,249,249,248,248,249,249,249,249,248,248,248,247,248,248,248,248,247,248,248,250,249,247,247,248,248,248,247,246,247,247,248,248,248,247,247,248,247,248,248,247,250,249,238,245,250,247,248,247,247,248,248,249,249,249,248,240,244,249,248,246,244,247,248,247,247,246,246,247,248,247,247,245,246,247,248,247,243,246,248,247,245,244,244,247,245,248,248,246,247,247,247,247,247,247,247,247,247,249,218,232,232,184,229,238,252,234,205,231,224,212,224,250,190,163,150,124,71,89,236,251,251,249,237,245,241,246,252,226,199,203,247,252,252,248,211,207,206,232,233,233,186,197,244,223,214,238,252,243,252,252,249,247,245,243,252,249,181,113,117,108,87,43,46,51,37,45,40,43,44,39,43,43,49,45,71,78,60,67,69,42,42,169,235,250,250,241,245,252,249,249,250,247,249,248,250,248,252,238,252,212,141,227,247,250,245,223,236,250,250,227,179,123,152,195,198,168,176,246,245,139,106,73,61,87,74,60,142,160,97,82,85,116,110,85,129,150,122,80,45,52,63,71,81,56,42,61,70,71,52,61,29,57,229,250,250,249,249,252,237,244,241,246,249,247,249,248,251,241,241,245,251,241,229,242,252,245,183,200,240,229,164,161,223,229,248,242,174,207,250,211,196,235,239,251,236,123,87,46,62,78,71,87,94,89,55,45,35,34,44,33,41,30,46,21,57,221,236,240,240,212,213,214,231,243,251,246,202,92,117,204,199,215,234,230,236,229,229,229,225,227,226,226,227,226,225,224,223,225,224,224,224,222,222,223,222,222,220,218,217,219,218,216,217,217,215,214,214,213,214,214,213,214,210,210,211,210,211,210,210,210,208,208,208,212,207,210,210,205,210,208,214,221,193,143,100,96,90,62,58,76,60,125,158,141,129,80,56,48,39,93,136,123,120,107,84,53,51,25,50,170,223,231,218,217,215,212,212,210,212,214,213,217,215,214,215,213,214,212,213,215,212,213,215,214,214,213,214,215,211,210,212,210,210,209,206,208,208,208,206,208,205,208,113,2,1,5,7,8,8,10,10,10,12,10,10,217,218,218,218,217,215,214,216,213,215,215,216,215,212,216,215,214,215,214,216,214,214,216,215,214,214,216,215,213,214,214,213,214,217,217,217,218,216,215,217,218,219,219,218,219,217,216,217,219,219,217,218,220,219,219,218,218,217,217,217,219,218,219,221,218,217,219,219,219,219,220,219,218,220,219,220,221,218,220,218,217,217,220,221,219,219,218,220,219,220,221,220,222,220,218,220,221,219,222,221,217,220,219,217,219,220,219,220,221,221,220,221,220,222,221,222,223,222,222,221,225,225,224,225,224,224,225,225,227,227,226,227,226,227,228,227,226,228,229,229,229,228,229,229,230,227,228,229,231,232,234,232,229,232,232,233,233,234,235,234,234,233,235,234,233,236,237,236,235,235,237,236,236,237,237,237,237,237,239,238,238,239,237,239,239,239,238,240,240,239,239,241,241,239,242,242,243,242,242,242,243,245,244,245,245,245,245,245,246,245,244,244,245,245,248,248,246,247,247,247,247,246,247,247,248,248,247,247,247,247,248,248,246,248,248,248,248,247,248,248,247,248,249,248,248,248,247,247,247,247,247,248,248,247,248,247,247,248,247,247,247,247,247,249,248,247,248,248,249,247,248,249,247,249,247,247,248,247,248,247,247,249,248,248,248,250,245,237,248,250,247,249,247,248,247,247,249,247,249,245,242,248,249,248,244,243,247,247,247,246,245,247,247,246,246,246,248,249,247,245,247,243,244,247,247,248,246,246,244,245,246,249,249,248,247,246,247,247,246,245,246,249,245,222,252,245,213,245,211,206,213,219,248,239,209,224,251,193,171,163,139,80,90,238,251,251,249,236,244,236,244,251,239,210,187,235,249,252,245,210,186,162,206,219,244,223,230,252,239,227,246,247,240,252,250,250,247,242,235,253,207,128,106,114,85,34,27,36,37,26,24,25,29,23,26,28,21,32,36,68,79,57,73,69,47,128,236,246,250,250,239,245,249,250,246,249,249,248,247,250,248,252,237,240,206,127,196,248,250,237,219,225,248,191,152,188,196,222,215,183,176,194,247,235,161,147,120,76,77,89,66,127,184,141,87,72,120,115,94,138,154,112,89,59,56,59,76,83,55,47,59,66,67,47,61,25,51,221,250,250,249,249,252,239,241,240,245,248,247,247,248,251,244,239,244,250,245,230,239,251,250,188,190,235,246,207,173,224,233,233,252,222,223,252,198,165,217,234,251,239,115,73,56,61,87,78,93,103,91,60,38,37,39,44,31,37,32,47,18,67,230,234,234,234,217,212,216,231,237,250,246,185,80,128,208,200,224,231,231,233,230,230,229,226,226,227,224,226,225,223,223,225,223,222,221,222,222,219,220,218,218,218,220,217,215,216,214,218,212,214,215,213,216,213,213,211,211,213,211,214,211,208,212,208,209,212,208,207,207,208,208,208,207,207,208,212,223,215,160,110,109,99,71,57,75,63,114,153,135,125,90,61,58,50,99,130,106,110,94,59,59,39,24,116,211,225,224,220,222,214,213,214,212,211,214,213,214,214,214,216,214,214,214,214,214,214,213,212,214,214,214,211,212,212,213,211,209,212,209,211,208,207,208,205,210,206,208,111,3,1,3,8,9,8,10,10,11,10,10,11,219,221,220,215,216,213,214,216,214,214,214,214,218,213,214,215,213,217,215,216,215,215,214,216,216,215,215,217,219,216,218,217,217,217,217,218,216,220,217,217,218,217,220,218,220,219,218,220,218,218,219,217,219,220,219,220,222,220,219,218,218,221,219,218,221,220,219,221,221,220,218,222,223,221,221,221,222,222,220,220,220,222,220,219,220,218,221,220,219,222,220,220,220,220,218,220,221,219,221,219,218,220,221,220,219,219,217,221,220,219,221,222,223,223,223,225,226,225,224,224,224,225,225,224,225,225,226,227,226,227,227,227,226,226,229,226,228,227,228,230,228,231,228,229,229,230,232,230,231,229,232,231,229,231,230,231,232,234,236,234,233,236,231,235,236,235,237,234,236,236,235,236,237,239,238,237,237,237,238,238,238,239,239,240,241,240,240,240,240,240,240,240,241,242,240,243,242,242,245,243,246,245,245,245,244,246,245,246,245,245,245,245,245,245,246,246,246,247,247,248,248,246,246,247,248,248,247,247,247,247,247,247,247,247,247,247,247,248,248,248,247,248,249,249,248,249,248,248,248,248,247,248,248,248,249,247,247,249,249,249,250,249,248,247,248,247,248,248,248,248,247,247,247,248,249,247,248,247,247,247,248,247,248,249,250,252,241,239,251,249,249,249,248,249,247,248,247,247,248,242,244,249,249,247,244,246,249,249,247,247,247,246,247,246,245,245,246,247,246,245,246,244,244,247,246,248,247,246,246,244,246,246,247,248,247,247,246,247,245,245,245,250,244,217,253,236,195,199,197,241,236,243,252,245,221,219,250,181,158,145,125,79,94,234,251,251,250,239,244,237,244,251,231,209,179,210,245,252,241,193,151,173,242,249,252,224,240,252,224,208,237,240,235,251,250,250,249,237,224,248,193,119,119,111,60,20,24,43,36,23,24,23,26,22,21,26,22,21,31,71,79,60,77,53,84,218,251,251,250,249,245,248,249,250,244,248,247,248,247,252,245,252,235,214,190,116,179,246,249,231,192,200,219,177,207,237,248,252,214,200,195,218,253,253,188,135,111,73,86,78,66,120,167,137,100,105,151,131,98,135,134,105,89,62,56,62,66,74,68,54,63,75,69,50,59,24,54,218,251,251,249,249,252,243,236,236,244,249,248,248,247,250,247,239,243,249,249,228,234,248,250,200,178,230,243,226,167,182,232,224,247,214,208,248,204,176,206,229,251,235,121,97,69,83,92,98,116,113,91,53,48,37,36,45,39,44,34,51,18,78,238,238,245,245,225,227,224,236,236,242,246,167,69,143,213,202,224,232,233,235,229,231,227,227,225,224,224,225,224,224,226,223,223,220,218,220,219,219,217,217,215,215,216,215,216,215,215,214,214,212,211,212,213,213,214,211,212,210,211,212,208,212,210,209,210,208,208,206,208,206,207,205,207,209,206,211,220,218,170,122,113,110,88,81,79,65,126,140,129,132,95,74,73,81,118,115,107,106,92,84,77,35,62,206,234,222,221,216,222,214,213,212,210,214,214,213,215,215,214,214,215,216,216,213,215,214,212,212,209,212,213,211,212,214,213,211,209,212,209,208,211,210,208,207,211,207,210,112,3,1,3,8,9,8,10,10,11,10,10,10,215,217,217,217,216,214,214,215,215,217,216,214,214,215,215,214,216,214,213,215,216,214,214,213,214,214,216,216,215,217,217,217,217,217,215,215,218,218,218,218,217,216,218,219,219,218,219,218,216,217,216,215,217,218,219,216,219,219,216,218,218,220,222,222,222,221,223,221,218,220,219,219,220,221,220,219,220,219,221,221,221,218,218,219,217,218,217,219,218,217,220,220,218,220,220,218,219,217,221,223,219,221,222,221,222,221,219,221,222,222,222,224,223,222,222,223,222,221,224,222,226,224,222,224,224,224,225,224,224,226,225,229,227,226,228,226,227,228,226,229,227,228,228,226,230,229,229,230,229,229,229,229,231,231,230,231,231,232,234,234,235,236,237,237,237,234,235,235,237,235,236,236,237,240,238,240,238,237,238,238,241,241,239,239,240,239,239,241,240,241,241,242,242,240,243,242,242,243,244,244,245,246,247,245,246,246,246,245,244,245,247,248,248,248,247,247,247,246,247,247,246,246,246,247,247,246,247,247,247,248,246,248,247,248,247,247,248,247,249,248,247,248,247,247,249,249,248,247,247,248,248,247,247,247,248,248,248,249,248,249,248,248,248,247,247,248,247,247,247,247,248,247,248,248,248,247,247,247,248,247,247,247,248,247,249,250,237,241,249,248,249,250,248,247,247,247,248,248,247,242,246,250,247,245,245,248,248,247,247,246,245,246,246,247,246,245,245,245,245,244,247,245,241,247,244,245,247,247,246,245,244,244,247,247,247,247,246,246,245,245,244,250,236,212,238,188,185,233,232,252,236,220,238,237,224,220,239,156,133,136,118,71,87,234,251,251,250,237,242,239,242,249,233,201,173,218,250,252,225,176,180,214,252,252,252,210,236,252,211,190,228,238,236,252,248,250,249,237,232,254,185,132,114,79,46,9,30,41,31,27,27,29,27,27,22,24,22,29,40,76,74,61,59,34,128,243,252,249,252,246,245,247,247,248,244,249,246,248,248,248,246,252,244,224,199,110,172,245,251,226,199,206,220,214,250,250,253,230,177,196,206,219,253,251,193,176,135,95,73,83,71,121,194,165,104,87,123,107,84,108,137,121,96,59,50,54,59,76,77,68,66,80,77,49,63,22,58,222,251,251,249,249,252,247,232,229,244,248,249,249,247,248,247,237,239,245,249,229,229,245,251,214,171,222,242,232,175,155,219,223,214,205,204,229,223,199,195,217,252,227,119,99,76,89,110,110,113,89,70,60,47,37,34,27,38,34,26,45,17,82,234,234,234,234,227,229,235,243,234,242,232,157,79,166,216,207,225,228,231,231,230,228,226,223,224,225,222,224,223,223,219,219,221,220,218,217,216,215,216,216,217,214,212,212,214,214,212,214,211,211,208,210,210,208,209,208,210,208,207,208,208,208,209,206,207,207,205,206,206,205,204,206,205,204,205,208,217,226,189,143,121,106,93,84,92,70,111,133,116,120,85,76,84,90,122,112,107,125,124,105,86,33,102,226,232,217,216,214,214,212,214,211,212,213,215,214,214,214,212,214,214,215,212,214,214,213,212,213,213,209,209,212,213,210,211,210,209,210,209,211,206,206,209,207,208,204,208,113,2,1,4,7,8,7,10,9,10,11,12,10,219,218,217,216,221,214,216,216,213,217,216,214,215,215,216,214,214,215,212,215,214,215,216,216,216,214,216,215,216,213,218,218,216,217,217,219,218,218,217,220,221,219,218,216,217,215,219,220,217,217,217,218,219,220,219,218,218,217,218,217,217,219,218,218,218,220,218,219,221,219,220,218,218,219,219,219,218,220,220,220,219,221,219,218,219,219,219,220,219,220,220,221,219,219,217,220,221,219,222,220,220,222,220,221,219,223,222,223,222,218,222,221,222,224,222,224,222,223,226,222,223,222,222,224,223,224,225,224,227,226,225,227,226,226,227,227,228,229,228,228,228,229,228,229,229,228,228,227,229,227,230,231,231,234,230,232,233,232,233,234,236,236,232,234,236,236,237,237,237,236,237,237,237,237,238,238,239,238,238,239,238,240,240,239,240,241,243,242,242,241,241,242,241,242,242,243,243,244,245,242,245,245,244,245,245,246,246,246,247,247,247,247,248,248,248,248,247,246,248,248,248,248,247,246,246,248,247,247,247,247,247,247,247,248,247,248,248,247,249,248,247,247,248,248,247,248,248,248,247,248,247,248,249,248,248,248,248,247,247,247,248,248,248,248,249,248,248,248,248,248,248,249,248,247,248,247,247,247,249,248,247,248,249,249,250,247,235,246,251,248,250,248,247,247,247,247,247,247,244,241,247,249,245,243,246,248,247,247,245,246,247,247,247,247,245,245,247,246,246,245,247,246,241,246,247,247,247,248,249,246,246,245,245,247,247,249,249,247,245,246,245,251,232,212,244,220,232,249,239,238,178,206,240,242,226,235,246,169,161,150,122,75,94,235,252,252,250,236,241,240,244,252,243,222,194,225,252,252,222,188,188,232,250,250,239,196,240,252,215,201,241,249,242,252,247,250,250,239,230,251,181,101,61,36,20,2,6,29,29,19,28,32,34,38,39,35,32,38,45,73,58,54,39,33,174,243,251,242,248,245,249,250,245,247,244,249,248,248,248,250,247,251,249,245,247,149,166,247,249,212,212,251,252,240,252,251,248,166,82,148,175,226,252,252,201,134,126,75,65,94,128,141,151,122,74,46,47,60,56,90,128,129,99,59,49,66,61,76,95,66,66,88,80,55,61,19,61,223,251,251,249,249,252,249,232,223,243,246,247,248,248,249,249,239,237,244,252,235,226,241,251,229,167,208,243,235,202,153,207,208,179,218,223,214,216,224,198,205,252,218,113,85,57,74,67,50,44,30,37,47,47,36,27,26,21,24,18,39,12,88,240,239,248,244,229,235,240,247,245,249,246,154,95,190,218,211,227,229,231,229,230,227,225,225,224,224,224,224,220,221,219,218,219,218,217,219,218,220,219,218,216,214,214,214,215,213,212,213,213,213,210,213,212,210,211,208,210,208,207,211,207,208,207,207,208,205,206,208,205,205,206,205,207,207,206,213,217,228,201,146,116,86,83,91,83,78,125,130,105,95,65,69,96,112,134,116,110,128,123,98,79,24,45,160,185,211,223,214,215,210,215,213,213,215,212,212,217,216,214,215,216,214,213,214,215,213,214,215,213,212,210,210,212,211,212,213,210,213,209,209,210,206,209,205,206,207,209,113,2,1,5,8,8,8,12,9,10,11,10,10,220,222,220,219,219,214,214,214,214,217,217,217,215,214,215,214,214,213,214,214,213,214,214,215,216,213,214,217,216,216,216,215,217,218,217,217,217,218,217,215,219,218,219,218,219,220,219,220,219,218,219,220,220,217,220,218,219,220,217,222,218,219,219,216,218,217,219,220,220,220,219,221,219,218,219,218,220,218,216,219,219,220,220,220,218,220,220,218,216,217,219,218,217,217,217,218,218,216,218,219,218,219,220,218,221,222,220,219,220,222,219,222,221,219,223,222,222,222,225,222,223,222,222,225,224,225,224,225,227,225,226,227,225,223,227,228,226,227,225,227,226,226,229,225,226,228,227,227,227,226,229,231,232,231,231,230,232,233,232,234,234,237,235,234,234,233,238,234,236,235,237,237,235,238,237,237,239,239,239,239,239,238,238,239,240,239,240,242,241,241,240,241,241,240,241,242,243,242,244,244,244,244,242,242,244,244,245,245,245,246,246,246,246,246,244,245,247,247,248,246,246,246,246,245,247,248,247,247,247,247,247,248,247,247,248,247,248,247,248,247,247,247,247,248,248,248,249,248,249,247,247,248,248,248,247,247,247,247,247,247,247,248,248,247,248,248,247,247,248,248,249,248,248,248,248,247,247,247,248,248,248,247,248,249,250,243,238,248,247,248,248,247,247,247,247,248,248,246,240,241,247,247,245,242,248,247,246,247,246,246,247,247,247,246,246,246,246,247,247,245,247,247,242,247,247,247,247,246,247,247,247,244,244,244,245,246,247,247,244,244,246,251,232,232,252,233,243,219,182,225,210,229,252,239,225,239,250,193,171,162,137,79,92,238,252,252,250,237,243,238,244,252,247,232,199,209,249,252,218,196,198,235,250,250,229,182,242,252,232,230,252,252,245,252,248,251,248,239,223,240,164,94,70,49,39,7,7,14,30,27,27,48,51,55,53,55,49,47,33,44,18,64,110,112,231,246,250,244,243,246,249,249,244,247,244,249,247,248,247,247,248,250,252,240,250,166,155,243,217,195,221,252,251,245,252,252,247,140,84,131,173,236,250,250,171,101,65,43,35,93,142,154,141,70,31,36,47,48,60,92,107,77,65,59,60,68,70,70,81,58,70,105,85,49,61,21,55,214,251,251,250,250,252,252,238,228,244,246,248,247,247,247,249,240,234,242,250,240,225,236,252,242,171,198,242,237,223,171,188,216,180,216,239,189,201,242,212,204,252,190,80,44,6,4,6,7,10,7,13,29,41,33,33,29,30,25,33,36,18,102,233,233,234,234,229,237,246,250,249,234,234,150,114,204,215,213,225,230,230,227,229,227,223,223,223,222,222,222,221,220,218,219,219,217,219,218,218,217,216,215,214,214,215,213,213,213,212,213,209,212,212,214,211,209,211,209,210,210,209,208,208,207,208,206,206,208,208,207,207,208,206,206,206,206,207,209,210,196,160,142,118,93,83,83,87,75,124,134,111,116,75,75,95,112,134,113,118,126,113,94,73,29,20,105,171,212,226,217,216,212,214,215,214,215,217,217,217,214,215,216,215,217,216,217,215,214,212,212,214,214,213,208,210,212,212,211,211,212,210,211,210,210,209,206,210,208,210,111,3,1,3,7,9,7,10,10,11,11,10,11,221,220,220,217,222,215,216,219,217,217,217,216,214,216,217,215,217,216,214,215,213,215,216,218,217,218,219,218,218,217,219,218,217,220,219,219,216,219,219,217,219,218,218,222,221,221,219,221,220,222,222,220,222,221,221,219,222,221,222,222,220,220,220,220,219,220,216,218,220,218,220,218,218,220,220,219,221,220,221,220,219,220,218,220,220,220,217,218,218,218,219,218,217,219,220,218,219,218,220,219,220,222,220,221,219,220,219,221,222,220,224,222,222,223,221,223,223,223,223,223,225,223,222,225,224,226,224,225,226,227,228,225,225,224,225,225,225,227,226,225,224,225,226,226,225,225,229,229,229,229,229,231,229,231,231,233,231,232,232,231,232,232,234,236,236,235,235,236,235,236,236,237,237,239,240,237,238,239,240,239,239,240,239,240,241,241,241,241,242,240,241,240,239,241,240,243,244,241,244,244,244,244,245,244,245,245,244,246,244,244,246,246,245,244,245,245,246,247,247,246,246,246,247,246,246,247,246,247,247,247,247,246,247,247,247,247,248,247,248,248,247,248,248,249,248,247,247,247,247,248,248,248,248,247,247,248,248,247,247,248,247,247,248,248,248,249,247,247,249,248,248,247,248,247,249,247,247,248,247,247,247,248,249,248,249,238,240,251,247,247,247,248,249,247,247,247,249,245,241,246,249,248,244,246,249,247,247,247,246,247,247,246,247,247,247,247,247,246,248,248,247,249,242,244,248,247,249,247,247,247,247,246,246,244,242,246,246,246,246,245,247,250,227,235,252,196,202,214,232,252,236,250,247,234,219,243,250,191,163,140,123,69,91,238,252,252,250,238,243,240,244,252,238,214,183,184,240,251,217,199,194,239,250,250,232,196,252,252,253,218,232,251,246,251,248,251,249,242,228,241,228,194,176,178,199,226,221,155,82,18,36,63,61,61,60,54,46,71,101,116,73,183,210,170,250,250,251,241,237,244,245,248,245,246,244,247,247,247,247,247,248,250,252,238,250,184,146,206,185,185,237,252,241,242,240,252,192,116,175,198,202,249,250,250,183,125,117,86,89,145,195,205,198,135,75,80,102,113,118,127,118,84,62,55,49,51,50,62,74,55,62,110,89,50,66,18,56,214,250,250,250,249,252,252,246,227,241,247,247,249,248,247,248,242,235,239,250,247,227,232,252,252,183,181,238,236,229,179,159,169,168,221,243,184,178,241,223,181,222,167,94,84,55,58,53,54,59,45,49,53,33,27,42,47,40,36,25,35,10,117,241,235,249,237,230,242,245,250,249,249,245,139,134,217,214,216,225,225,228,227,227,226,223,224,224,221,221,221,221,221,220,219,218,219,217,217,216,215,215,216,214,213,214,213,213,213,213,211,212,213,212,214,208,211,210,206,208,207,208,210,208,208,208,208,209,207,207,208,207,206,205,206,207,207,205,210,203,171,141,127,134,115,91,79,77,82,117,135,128,131,98,85,100,113,132,111,114,131,117,103,72,21,98,191,201,218,217,216,218,214,214,214,214,213,215,218,217,215,217,217,213,216,217,215,216,217,216,213,212,214,212,212,212,213,211,208,207,213,208,205,210,207,210,207,208,207,207,112,3,1,3,7,9,7,10,10,10,11,10,10,217,219,217,217,219,216,216,216,217,217,215,213,215,217,217,214,218,216,214,216,215,215,215,217,220,219,215,218,218,218,217,217,217,217,220,221,217,217,218,220,220,218,220,219,218,219,218,219,221,221,220,221,220,218,218,220,218,219,220,220,217,220,220,217,219,218,221,219,218,219,217,218,218,220,223,219,220,220,221,221,219,218,217,220,220,220,220,219,219,221,222,221,221,219,221,220,220,219,219,219,218,218,219,217,217,220,221,218,220,220,220,221,220,220,224,220,221,222,221,220,222,223,221,222,221,221,223,222,225,223,223,225,225,224,226,225,226,229,225,226,225,225,226,226,229,229,228,228,229,230,230,228,232,232,230,231,231,232,232,232,231,234,235,236,237,235,237,236,236,236,236,236,237,238,237,237,237,237,237,239,239,242,240,240,241,242,242,244,242,242,241,241,240,240,241,241,243,242,243,243,242,243,243,245,246,244,245,246,246,245,245,246,245,245,244,244,245,246,247,246,245,245,247,246,245,247,246,245,247,246,247,246,246,248,247,246,246,246,246,247,247,247,248,247,248,248,247,247,247,248,248,248,248,247,247,247,247,247,247,247,246,247,247,246,248,247,247,249,248,248,247,247,248,247,248,248,247,247,247,247,247,248,247,250,247,236,244,249,247,248,247,247,247,248,247,247,247,240,242,248,247,245,242,246,248,246,247,246,247,246,247,246,246,247,247,247,246,247,247,246,247,249,244,244,247,247,248,247,247,247,247,247,248,246,244,241,243,245,246,247,248,249,218,226,233,212,240,240,252,252,208,214,235,227,214,241,249,178,134,125,124,70,85,239,252,252,250,237,244,240,244,251,239,209,186,191,252,252,203,192,200,247,251,251,242,224,253,253,225,144,173,226,241,250,249,251,246,247,241,252,253,253,250,252,252,252,248,193,113,26,81,118,61,55,57,43,63,204,250,236,158,226,160,141,250,246,252,226,223,245,245,251,246,243,242,245,245,246,247,246,247,247,252,229,243,187,160,195,161,196,252,252,252,204,168,206,148,127,213,212,222,252,252,252,247,190,154,158,164,211,218,210,203,137,99,115,132,154,145,144,133,100,87,65,60,55,37,56,71,59,57,102,88,55,63,17,62,217,250,250,249,248,251,249,244,219,233,247,248,248,244,245,248,245,234,238,247,248,229,227,250,252,190,169,225,241,226,176,103,142,198,214,249,198,179,250,214,150,192,214,229,243,242,250,248,243,247,241,245,235,147,91,93,81,56,25,31,31,19,127,233,230,234,234,240,244,246,252,234,215,217,122,152,223,214,217,218,227,223,223,222,223,222,221,222,221,221,218,218,218,218,219,220,216,215,215,215,215,215,214,214,213,212,211,211,212,213,211,209,209,208,210,210,209,209,208,207,208,207,207,207,206,208,206,207,206,207,207,206,207,206,205,205,206,207,211,218,194,139,117,116,109,90,81,83,78,121,134,133,139,99,110,119,137,133,108,113,117,117,101,69,22,122,225,223,225,221,215,215,213,217,214,213,216,214,215,217,214,214,216,214,214,214,216,216,214,214,214,212,211,212,211,211,211,208,207,207,207,207,207,206,205,208,208,208,205,208,113,2,1,4,7,7,8,10,9,10,10,10,10,218,219,217,216,220,217,217,217,216,216,217,215,217,215,215,216,214,216,216,218,217,217,215,217,217,215,215,216,216,216,217,217,219,217,217,220,218,218,218,217,218,219,221,221,219,220,218,219,220,220,219,220,220,217,221,218,218,219,221,221,218,220,220,220,220,219,217,220,220,220,221,220,219,220,220,219,220,220,219,218,222,220,218,220,220,219,218,221,219,219,219,221,221,218,221,218,219,218,217,218,217,218,219,218,219,219,219,221,220,219,222,221,218,222,220,221,223,220,222,222,222,224,222,223,222,222,221,223,224,222,225,223,224,226,226,227,225,226,228,226,228,227,226,227,226,226,227,226,227,227,227,229,231,230,228,231,231,234,232,232,234,233,234,234,235,235,235,237,237,235,235,236,237,237,238,238,237,238,239,240,240,241,240,241,242,242,242,241,241,241,241,242,241,242,242,243,242,243,244,243,243,243,244,244,246,245,245,245,245,246,246,245,244,245,245,245,245,246,244,245,246,246,246,246,247,246,246,245,246,247,248,247,247,247,247,247,248,247,248,248,248,248,247,247,247,247,247,247,247,249,247,247,248,248,248,247,248,248,248,249,247,247,247,247,248,248,247,248,248,248,248,248,248,246,247,247,247,247,247,248,248,248,247,249,247,236,246,249,246,248,248,247,247,248,248,249,246,240,245,249,250,245,244,248,247,247,246,247,245,246,248,246,248,247,246,247,247,246,247,247,246,249,245,243,247,246,247,247,246,247,246,247,249,248,247,246,244,242,246,246,250,247,221,245,252,237,252,231,211,201,184,223,234,225,211,241,249,176,152,146,144,85,92,242,252,252,249,237,245,239,244,252,247,236,206,203,252,243,199,198,214,247,250,250,228,177,253,237,194,90,65,191,244,252,250,246,246,251,243,251,253,237,224,224,249,251,246,183,101,5,72,105,68,58,52,37,50,223,253,253,152,97,40,88,234,240,248,214,214,247,248,252,245,242,240,244,248,247,247,244,247,245,252,193,222,203,163,195,154,216,253,240,225,146,181,246,124,147,231,201,239,252,253,253,247,184,101,103,104,108,97,74,93,99,71,53,44,49,57,61,66,60,63,66,78,71,41,60,78,63,58,102,89,52,61,16,70,218,249,249,249,249,252,250,249,224,226,243,246,248,246,247,247,246,237,237,245,251,232,224,244,252,212,160,213,243,227,205,172,178,226,224,244,234,198,249,225,162,199,236,252,252,252,252,252,252,253,253,252,252,203,134,121,99,60,35,27,29,13,143,234,227,247,238,245,252,251,253,218,185,191,125,176,229,212,216,222,227,226,224,224,221,220,220,220,219,219,218,217,217,217,217,217,217,214,214,214,213,215,212,213,214,214,212,211,210,208,210,210,207,206,211,207,208,208,208,210,206,208,208,206,207,207,205,206,206,207,207,205,206,207,206,207,207,206,216,215,181,154,141,136,123,98,82,74,82,120,155,159,147,109,110,113,107,116,103,122,150,132,112,44,54,197,220,212,222,220,222,215,214,216,216,217,219,213,216,218,215,217,216,215,215,215,215,215,213,214,214,211,211,209,210,212,211,210,207,205,208,208,207,207,208,210,209,212,207,208,112,2,1,4,7,7,7,10,9,10,10,10,10,217,222,219,217,221,216,218,217,216,215,215,217,218,216,215,214,216,217,216,217,215,214,219,216,217,219,217,216,217,217,217,219,217,219,218,218,217,219,222,221,219,217,220,221,220,221,219,220,221,223,220,220,222,220,220,223,220,220,219,219,219,219,218,218,220,220,221,220,219,218,217,221,219,217,219,219,222,218,220,220,217,220,218,218,219,217,220,221,217,219,220,218,220,217,218,220,219,221,219,218,220,218,221,221,218,220,220,219,219,220,222,221,219,219,221,222,220,220,220,223,223,223,223,225,224,225,226,223,223,224,225,226,227,224,224,226,226,225,225,227,229,227,227,227,227,226,227,227,227,229,230,230,230,229,230,230,230,233,235,232,232,233,232,232,234,236,237,235,235,235,236,237,240,239,237,238,239,240,239,239,240,240,239,242,243,243,242,241,241,241,242,241,240,241,241,242,242,243,243,243,243,242,244,244,242,242,244,244,244,244,244,244,244,245,244,244,245,245,246,246,245,246,245,244,245,245,246,248,246,245,246,246,246,249,246,245,247,247,248,247,246,247,246,248,247,247,247,247,248,246,247,247,247,247,247,247,247,247,247,247,247,248,247,247,247,248,247,247,246,246,248,248,247,247,247,247,247,247,247,247,247,247,248,250,240,235,247,249,248,248,247,247,247,247,246,247,244,241,247,248,246,244,247,250,247,247,246,245,245,244,246,246,247,247,246,245,245,245,245,246,246,247,246,242,245,247,247,246,246,247,247,247,247,247,248,247,244,242,242,244,250,247,226,252,252,241,230,175,207,225,211,235,240,223,212,246,250,184,159,151,146,109,124,246,252,252,250,243,246,240,242,250,249,234,215,195,242,239,211,216,232,248,248,248,172,100,212,216,171,80,35,142,232,250,250,246,242,252,236,234,251,219,202,186,222,250,222,150,92,2,60,92,62,56,51,29,36,212,251,213,71,21,11,71,215,239,250,207,224,250,248,252,245,241,239,242,247,246,247,246,247,248,251,215,208,220,204,178,143,219,214,147,164,175,253,253,141,198,234,199,248,252,252,252,248,170,108,84,17,6,9,2,57,110,68,36,20,27,27,46,74,50,37,30,57,56,38,69,78,68,57,100,93,52,61,19,61,206,249,249,249,249,252,251,249,231,226,240,248,247,246,247,246,249,242,237,241,250,237,222,239,252,229,162,195,240,234,233,214,194,234,224,237,224,174,231,234,199,210,215,250,252,252,252,252,252,253,253,252,252,174,124,118,88,55,27,30,25,22,173,234,230,234,234,252,252,253,252,204,188,189,135,195,228,213,212,218,227,223,224,223,221,218,218,219,220,219,218,217,215,215,216,216,216,214,211,213,214,214,211,211,212,211,212,211,210,209,209,210,208,208,210,207,207,209,207,205,209,206,206,207,207,207,205,207,206,205,205,206,205,206,206,206,209,205,210,222,199,152,123,118,115,93,79,96,119,141,137,128,120,88,82,69,66,71,87,123,129,113,91,39,36,163,215,216,227,217,217,219,217,217,215,215,217,217,217,214,215,217,217,214,215,216,214,214,216,214,214,210,213,212,210,212,211,208,207,207,207,208,206,208,208,211,208,210,209,208,112,2,1,3,7,9,7,10,10,10,11,10,10,217,218,217,218,217,214,214,216,217,218,217,215,218,216,217,217,217,217,216,217,215,217,218,219,218,219,219,216,214,217,217,216,216,216,218,217,217,220,218,217,220,218,217,220,218,221,217,218,220,220,222,219,222,220,225,222,219,220,219,220,220,220,219,219,218,219,218,221,221,220,218,218,218,217,221,221,219,220,218,217,220,218,217,221,221,221,221,221,218,218,220,220,219,216,221,220,221,222,219,222,221,220,219,218,219,219,219,218,220,220,219,221,220,220,222,221,222,221,223,222,222,224,224,223,223,224,223,226,224,222,225,224,226,225,224,227,228,228,227,226,226,227,226,227,228,227,229,230,230,229,229,230,229,229,230,231,230,231,232,234,231,231,233,234,234,235,234,234,236,237,237,237,238,239,239,240,240,239,239,239,241,242,240,241,243,242,243,243,244,242,241,243,242,243,243,242,243,243,243,244,244,243,244,245,245,243,244,244,244,244,245,245,245,246,244,245,245,246,245,245,245,244,245,247,245,244,248,246,246,246,245,245,247,247,246,247,247,247,247,246,247,247,247,248,248,247,247,247,247,248,247,248,248,247,247,248,247,247,247,246,247,247,247,246,247,247,247,247,247,248,247,248,248,247,248,247,248,248,248,247,247,246,248,249,237,236,248,247,249,249,247,247,248,249,249,249,241,242,249,248,245,243,247,247,247,247,246,247,246,246,246,246,247,245,246,247,245,244,245,244,246,247,247,242,244,247,246,247,246,246,246,246,247,248,247,247,247,244,244,241,249,238,215,247,224,191,215,217,246,247,232,241,235,221,210,245,250,179,150,137,132,117,147,247,252,252,250,249,251,243,245,251,247,225,206,197,234,236,228,204,219,249,248,248,144,38,156,202,188,113,9,106,226,248,249,244,243,252,232,221,243,213,201,177,213,251,186,137,88,1,74,86,62,61,50,36,30,204,248,132,22,6,26,147,237,245,251,214,241,252,247,250,245,245,239,242,247,245,248,244,250,244,249,197,149,166,188,194,137,201,190,174,226,229,248,219,84,187,217,198,251,248,251,250,249,218,103,78,23,8,14,11,37,72,62,41,36,36,33,60,87,55,37,34,63,51,29,74,80,66,58,104,97,51,62,18,62,206,246,249,249,249,252,249,250,240,226,234,247,247,247,248,247,249,245,237,239,249,244,223,231,252,248,171,179,235,240,235,222,174,214,235,223,221,177,202,218,203,218,205,230,247,248,248,244,241,242,239,253,252,146,108,112,79,50,24,36,19,33,208,243,234,250,246,253,253,235,223,195,200,186,148,211,228,213,211,217,224,219,222,222,220,218,218,218,218,215,216,215,214,218,215,213,214,215,215,214,214,212,211,210,212,211,210,210,210,211,209,210,207,206,211,206,206,207,205,208,207,209,206,204,207,205,205,206,206,206,206,207,208,206,204,206,206,206,210,214,182,139,118,100,73,60,64,101,136,149,141,106,78,49,49,48,47,62,83,105,102,78,60,22,21,133,196,220,231,218,219,219,217,220,219,217,217,219,217,217,216,218,216,215,215,215,215,214,215,214,215,214,214,215,212,212,211,209,209,209,211,208,211,211,210,209,206,211,208,210,112,3,1,3,8,9,8,10,10,11,11,10,11,215,216,218,216,216,215,217,217,216,218,218,218,214,217,216,216,218,217,214,217,218,216,218,217,217,217,217,217,216,217,217,219,218,218,216,218,217,217,217,217,218,219,220,219,219,220,219,216,215,218,217,220,220,218,218,219,220,219,220,220,216,221,220,220,220,218,219,219,219,219,220,220,218,220,222,219,222,217,219,221,219,220,218,219,219,219,221,220,218,221,220,219,219,216,220,218,218,220,217,220,218,217,218,217,219,219,221,220,219,220,220,221,221,222,220,219,221,223,223,223,222,221,222,221,221,222,223,224,224,227,223,224,225,224,226,225,224,226,227,226,224,224,226,227,227,229,227,225,228,229,229,231,231,229,231,231,231,231,229,232,232,234,235,234,235,234,235,235,237,237,237,239,239,238,239,240,239,239,238,239,239,239,241,243,240,242,243,242,243,244,245,244,244,242,242,242,243,243,244,243,242,242,242,244,245,244,244,245,244,244,245,245,244,245,244,245,245,244,244,244,244,244,244,244,247,246,245,246,246,247,248,246,246,246,246,247,247,247,247,246,247,247,247,246,246,246,246,247,247,247,248,246,246,246,246,247,247,247,247,248,247,247,247,247,246,247,247,247,247,246,247,247,247,247,247,247,247,247,247,246,245,245,249,247,234,241,248,247,248,247,248,247,247,248,249,244,241,247,248,247,242,244,247,246,247,247,247,247,246,247,245,244,245,245,246,245,244,244,244,244,246,246,247,243,243,246,246,246,246,246,245,247,246,247,247,245,247,246,246,241,248,226,202,234,213,224,244,232,252,237,205,221,229,213,207,246,249,172,141,136,120,98,97,152,201,245,249,249,250,243,244,249,250,226,211,207,228,203,160,122,181,244,246,233,125,54,135,190,197,138,73,159,243,250,249,241,245,251,237,222,237,211,198,178,218,252,175,138,77,1,75,85,67,61,56,38,34,206,242,147,39,71,192,241,251,250,242,196,236,252,244,250,245,246,236,240,245,244,244,245,246,249,246,184,69,68,130,147,206,250,241,240,232,227,247,158,87,193,193,212,252,249,252,251,249,225,141,87,55,57,38,25,74,71,51,54,37,35,50,74,70,46,45,42,58,46,35,74,83,67,56,106,97,53,61,24,61,196,247,249,249,249,252,247,246,246,228,229,245,245,247,248,247,248,245,236,237,247,247,222,227,251,250,183,167,222,244,242,237,178,191,245,222,208,211,196,188,211,229,207,224,247,244,244,243,236,239,234,252,244,131,106,100,76,49,22,38,15,56,226,234,234,244,252,253,237,213,222,202,205,176,163,220,225,217,211,220,221,219,222,219,217,219,217,217,218,215,216,216,217,215,214,214,214,214,213,213,213,213,211,210,209,208,210,210,211,209,208,210,209,206,207,206,206,207,207,207,205,205,207,206,206,205,205,206,207,205,207,208,208,208,205,208,209,207,210,213,170,128,112,99,98,75,71,124,152,162,163,143,104,71,63,71,73,87,110,120,105,83,36,44,154,217,216,215,219,219,219,218,217,218,217,218,219,216,216,217,217,214,215,215,215,215,218,218,216,213,214,214,215,215,213,212,209,211,212,210,208,208,208,208,206,208,208,209,208,209,112,2,1,5,7,8,8,10,9,10,10,10,10,218,218,218,217,218,217,217,216,214,217,216,217,217,215,217,217,217,217,216,217,218,218,217,217,217,219,218,217,219,217,217,217,217,218,219,218,216,217,218,217,217,216,219,219,217,219,219,219,218,218,219,219,218,217,221,218,219,219,218,218,218,219,219,219,221,219,219,219,216,217,217,217,220,220,221,220,220,223,221,220,222,220,220,219,217,220,218,218,222,219,219,220,219,220,218,217,218,221,220,220,219,219,219,218,221,220,218,220,222,221,218,221,223,221,221,220,223,220,222,224,221,221,223,222,223,224,222,223,223,223,225,224,225,225,225,227,225,225,227,225,227,228,226,229,229,230,229,227,228,227,228,230,229,227,228,226,229,230,230,233,231,232,234,233,236,237,235,235,236,234,236,238,239,239,239,240,239,239,240,239,240,241,242,241,243,242,242,244,242,244,244,244,243,243,242,242,242,242,242,242,244,244,244,244,244,244,244,245,244,242,245,243,245,245,242,245,245,247,246,244,245,244,245,246,245,245,247,247,246,247,247,247,247,247,247,247,246,247,247,247,247,247,247,246,246,246,247,246,246,247,247,247,248,247,246,247,247,246,247,247,247,247,246,246,248,247,247,247,247,247,247,247,247,247,247,247,248,247,247,247,249,249,249,243,234,245,249,247,248,248,247,247,246,246,246,242,241,248,249,246,242,245,248,247,248,247,247,247,246,246,245,244,245,246,246,244,245,245,246,245,246,247,247,246,242,247,245,245,246,245,245,244,247,247,246,246,247,246,248,246,249,231,226,252,232,242,252,228,219,183,193,229,232,212,207,249,248,182,153,140,127,92,60,53,59,175,249,247,249,240,242,249,251,240,224,214,154,117,126,38,99,232,249,244,155,52,88,175,232,202,141,204,251,251,249,242,247,251,238,226,231,206,196,179,223,252,169,141,75,0,75,84,73,62,54,33,41,221,247,197,116,195,249,249,249,249,230,200,240,249,247,250,246,247,235,237,244,244,245,243,246,245,248,189,41,7,32,115,237,249,247,229,151,198,223,139,183,242,202,231,252,249,252,247,251,251,212,162,89,76,57,86,142,105,66,50,46,45,54,69,49,43,56,51,42,24,41,81,81,69,51,107,106,50,64,22,56,195,244,249,249,249,252,248,245,248,234,226,242,246,247,246,247,246,247,236,232,245,250,229,220,244,250,198,163,208,242,246,238,188,168,239,222,188,217,179,161,208,236,210,205,230,238,239,240,237,240,232,253,237,130,100,97,71,48,28,37,0,84,239,235,246,253,251,245,203,203,229,212,206,165,180,226,225,214,206,220,221,219,220,217,217,216,217,216,217,215,214,217,214,217,214,214,214,212,213,211,214,212,211,213,212,210,209,210,208,210,206,209,210,206,208,206,208,207,207,208,203,206,206,205,209,206,206,207,205,207,207,205,206,207,209,208,206,209,215,228,211,161,136,117,115,132,135,154,169,162,165,151,116,94,96,93,99,100,107,111,101,77,54,136,217,239,233,216,219,218,220,218,217,217,214,219,219,219,216,217,218,214,218,216,215,217,217,217,214,214,215,214,214,215,212,211,210,209,209,208,209,207,209,209,208,210,210,212,208,212,113,2,1,4,7,7,8,10,9,10,11,10,10,217,217,218,216,218,217,214,215,216,214,215,214,217,218,217,217,216,214,216,219,219,218,218,217,218,217,216,215,214,217,217,216,214,216,217,218,218,220,219,218,218,217,218,220,221,220,220,220,221,222,218,219,219,217,218,219,220,220,220,220,219,219,219,219,220,217,219,221,219,220,219,219,218,218,220,219,220,219,218,220,221,220,220,221,219,218,220,219,217,219,219,218,221,222,221,219,221,221,218,220,219,220,220,219,222,219,220,220,222,221,219,222,220,220,222,221,222,220,222,226,222,223,225,224,225,224,224,223,223,223,221,224,226,225,228,226,227,228,225,228,228,227,229,227,225,228,228,227,229,226,225,228,229,228,228,229,230,230,232,232,230,233,232,234,233,236,235,230,235,234,235,234,236,235,235,237,238,240,238,240,240,240,240,240,240,241,241,241,241,242,243,241,241,242,242,243,242,242,242,241,241,243,243,244,242,243,244,243,243,243,244,245,244,245,245,245,246,245,246,245,248,247,247,248,246,245,245,245,247,247,247,246,247,246,246,247,245,246,246,246,247,245,246,246,246,247,246,246,246,246,247,247,248,247,246,248,246,247,247,246,247,247,247,247,246,247,247,247,246,246,246,246,247,246,246,245,247,247,247,247,247,247,248,241,236,245,247,247,247,247,247,247,247,248,246,238,243,248,246,244,242,247,247,248,247,246,245,245,245,245,245,244,244,244,245,245,244,244,244,246,245,244,247,244,241,245,246,245,246,245,244,245,246,246,246,246,246,246,247,247,252,229,230,252,222,240,213,178,221,220,225,237,236,211,208,251,250,181,161,155,131,86,55,53,6,59,185,227,249,243,242,249,252,242,231,186,87,99,120,18,62,203,252,252,186,124,125,182,243,222,179,210,252,252,249,245,247,250,244,229,230,204,196,182,226,252,166,142,71,1,75,87,71,55,56,32,41,224,249,191,143,236,252,230,237,243,230,202,240,251,244,248,245,248,236,237,244,244,244,244,244,249,249,173,54,61,55,71,220,246,247,192,166,249,226,163,232,248,207,247,252,250,250,245,252,252,249,204,108,57,7,49,118,92,55,44,53,47,61,79,43,50,75,50,32,13,46,84,83,68,48,106,108,53,62,22,50,182,244,248,249,249,252,247,244,249,239,224,239,245,244,245,246,245,247,237,228,239,250,232,222,240,251,220,163,191,236,238,235,184,119,188,183,148,225,196,132,190,226,183,162,205,231,236,242,235,237,231,253,231,127,108,92,76,43,34,34,15,112,233,234,234,253,253,226,187,223,234,218,185,152,193,224,226,213,203,218,219,221,220,218,215,217,216,217,216,214,215,214,215,213,216,216,211,213,213,212,211,211,212,212,212,211,211,211,210,209,208,208,206,206,206,205,206,205,205,207,205,205,205,206,207,206,205,206,208,205,204,206,208,207,207,208,208,209,217,232,206,167,144,119,111,111,113,115,105,100,89,91,91,72,60,50,52,51,55,62,60,58,45,108,215,226,227,226,218,216,215,220,218,218,221,219,219,220,220,218,217,218,217,218,217,216,215,214,215,214,217,214,215,215,212,211,211,211,210,210,208,210,210,210,208,210,211,212,210,210,112,2,1,2,7,9,7,10,9,10,10,10,10,217,218,218,216,218,216,217,219,215,217,217,218,215,215,218,216,217,219,217,220,219,218,218,216,219,218,220,219,218,217,219,219,218,218,218,220,217,220,220,217,222,218,219,218,219,219,219,221,219,220,217,219,219,221,221,219,221,218,222,222,220,220,218,219,223,219,219,222,218,219,221,220,219,217,219,218,218,221,219,221,221,220,221,220,222,224,222,219,220,221,222,222,221,222,222,221,221,221,219,217,222,223,221,222,223,222,223,224,222,222,220,222,221,222,223,222,225,222,224,225,223,225,225,225,225,224,224,225,226,227,227,225,226,226,226,226,226,227,229,227,228,229,227,227,227,227,227,229,229,231,230,229,231,231,234,233,234,234,231,233,232,232,233,232,232,233,235,236,236,235,235,234,234,237,237,238,240,239,240,238,239,241,241,239,241,241,239,242,242,242,242,243,244,243,244,244,244,244,244,243,244,243,241,242,241,241,244,242,244,242,244,244,244,244,244,246,245,245,245,246,246,245,247,245,246,246,246,247,247,247,247,247,247,246,246,247,247,246,245,245,246,248,247,247,248,248,246,247,247,245,246,246,246,245,246,246,247,247,247,247,246,247,247,247,247,247,247,247,246,247,246,246,245,245,246,247,247,246,247,247,247,247,249,237,238,248,247,246,246,247,245,246,246,248,244,239,246,247,246,242,244,247,246,246,246,245,246,245,245,245,246,246,245,245,244,244,245,244,244,245,245,245,247,246,241,243,245,245,247,245,244,244,244,245,245,247,246,244,249,248,250,224,229,230,187,204,213,222,250,233,226,231,231,205,212,250,247,178,150,150,132,81,56,98,78,111,203,235,250,237,244,249,252,229,218,183,50,115,175,25,60,205,248,253,224,191,186,201,241,221,189,204,245,251,246,244,247,250,244,234,224,197,194,184,232,250,154,149,71,1,80,84,70,51,56,33,47,234,248,170,158,250,251,215,232,235,210,199,238,246,245,248,245,249,240,236,244,243,244,244,244,247,251,198,181,205,125,67,137,191,190,195,226,252,218,168,251,228,210,252,252,249,249,249,252,252,249,201,134,89,28,6,14,9,29,39,42,44,55,63,49,59,83,52,23,19,48,92,86,69,46,105,112,56,63,19,46,180,239,248,250,249,252,247,245,249,246,225,231,244,245,245,245,243,248,242,229,236,248,240,221,231,252,236,169,181,228,244,221,196,96,92,166,183,237,236,159,186,225,171,161,190,224,240,238,236,238,230,252,225,119,105,94,73,45,33,29,4,148,245,250,250,253,241,199,206,251,241,213,156,146,207,222,230,209,207,223,217,221,220,218,216,213,213,214,217,218,216,216,213,214,212,210,212,212,215,213,212,212,208,210,210,209,211,210,211,212,210,209,207,208,207,206,209,205,204,207,207,207,206,205,207,207,207,208,207,206,205,206,207,208,210,209,210,211,216,212,163,113,97,68,59,69,50,41,44,36,35,71,84,69,42,28,33,20,37,50,62,30,42,167,212,217,222,221,222,216,218,218,218,222,222,221,220,222,219,218,220,217,220,219,217,219,217,219,218,219,219,216,217,216,213,212,212,212,212,213,214,212,213,214,211,210,211,213,211,210,112,3,1,3,7,9,7,10,10,10,10,10,10,214,217,218,215,216,215,214,216,218,217,218,215,217,217,215,218,217,217,218,218,217,217,217,215,219,218,217,219,218,220,218,219,217,219,219,218,218,217,217,218,218,220,220,218,217,216,219,218,216,219,220,220,220,218,220,220,219,220,217,217,218,218,221,219,220,219,220,219,218,218,218,218,219,218,220,219,222,222,221,222,221,222,221,222,222,221,221,221,221,219,221,222,221,222,222,221,222,221,221,222,219,220,220,222,223,221,221,221,221,219,222,222,222,222,223,221,222,225,225,223,222,224,224,222,225,224,224,226,224,226,225,225,226,222,224,225,225,224,222,224,226,225,226,227,226,226,226,228,226,226,227,229,231,231,231,232,232,231,232,231,231,230,231,232,231,232,233,232,235,233,233,234,235,236,235,237,237,237,237,237,238,240,240,240,240,240,240,242,240,241,242,241,243,243,243,244,243,242,242,241,244,242,241,243,241,242,243,242,244,243,245,244,245,245,245,246,245,246,248,246,248,247,245,246,246,246,248,248,248,248,247,247,247,247,246,248,246,248,245,245,246,245,244,244,247,246,244,245,244,244,245,245,245,244,244,245,245,246,246,246,246,245,246,246,245,246,246,246,246,247,246,245,246,245,246,248,247,246,245,246,245,249,244,234,240,247,247,247,246,246,245,245,247,245,240,242,247,247,244,241,245,246,245,245,244,245,245,244,244,243,245,246,245,245,245,245,245,245,244,244,244,244,245,246,241,241,245,245,245,243,244,244,244,246,246,246,245,244,247,249,249,212,229,233,201,236,226,227,230,184,209,231,231,205,214,250,244,164,138,139,128,67,110,238,224,227,232,223,242,230,234,242,253,237,223,168,86,174,168,66,127,232,253,253,228,206,203,214,244,214,197,198,231,251,239,242,244,247,244,233,225,198,195,186,232,233,144,143,61,3,82,86,68,47,51,29,46,235,248,134,165,250,245,218,226,220,206,200,233,246,243,245,242,246,239,231,240,244,243,243,241,249,240,238,252,252,169,100,58,69,202,222,250,250,153,177,252,207,222,252,247,250,245,250,249,252,243,221,223,212,147,127,115,71,42,12,18,54,62,63,50,93,90,37,29,19,54,92,86,68,44,108,107,55,61,24,50,179,243,248,250,249,252,245,243,247,247,231,225,240,246,247,246,243,246,242,226,230,247,242,218,224,253,246,176,168,215,241,226,206,140,140,203,212,234,251,198,212,224,185,199,198,217,236,237,235,235,228,253,212,116,103,88,77,34,34,16,31,194,233,251,251,244,208,202,229,252,201,159,111,163,218,223,229,201,207,221,217,218,216,215,214,215,212,215,213,213,215,212,211,210,211,210,210,213,211,210,211,210,208,208,210,209,208,209,208,208,210,210,207,207,207,207,206,205,205,205,205,206,207,206,208,206,205,206,206,206,208,207,206,206,210,206,208,209,214,195,127,91,69,36,53,57,43,49,37,35,39,53,72,66,55,41,30,28,44,59,63,18,73,198,221,225,220,216,218,218,218,218,220,218,221,220,219,220,218,220,217,217,217,217,215,215,216,215,215,215,216,215,214,213,214,212,210,212,214,213,210,211,213,212,210,212,214,212,207,211,112,1,1,5,7,8,7,10,10,9,11,10,10,217,220,217,217,217,214,216,218,218,217,216,217,217,217,216,215,218,217,219,218,217,218,218,218,221,217,219,217,216,219,220,219,221,220,219,220,218,219,218,218,222,217,218,220,219,219,219,219,218,220,219,219,218,220,221,219,218,217,218,219,221,220,218,218,221,220,221,220,218,218,220,221,222,222,222,223,222,225,222,221,224,224,224,223,223,223,222,221,221,223,221,222,221,222,224,221,223,225,223,222,224,222,222,223,222,224,223,221,222,222,223,224,222,224,223,227,226,226,229,225,226,225,225,225,224,226,226,225,226,225,227,226,225,225,225,226,226,227,226,225,226,227,229,226,226,226,225,228,229,229,229,228,231,230,228,230,232,230,232,231,230,233,233,234,233,232,232,232,234,234,234,234,236,236,236,237,237,239,239,239,241,241,241,240,239,242,241,241,242,241,244,242,242,244,244,244,242,244,244,244,244,243,243,244,244,244,246,244,245,245,245,246,247,247,248,249,248,249,248,248,247,247,249,248,249,247,247,247,247,247,247,247,246,247,246,246,245,244,245,245,246,244,244,244,245,246,245,245,248,246,245,244,244,245,247,246,245,245,246,248,246,246,246,247,247,246,246,247,246,247,249,248,247,246,246,247,245,246,246,245,247,249,241,230,242,247,247,248,246,247,246,246,247,244,238,245,248,247,242,241,246,247,247,247,246,245,246,246,245,244,246,245,245,245,244,245,245,245,244,244,245,245,244,244,242,241,243,245,246,245,246,246,244,245,245,247,245,246,245,249,246,222,251,244,226,245,200,193,217,206,222,238,233,201,217,249,243,172,146,142,123,59,127,244,250,249,209,202,240,229,229,235,246,240,247,202,93,165,204,153,217,251,253,253,208,208,202,211,236,210,218,211,237,252,239,247,242,248,243,236,230,207,191,181,237,218,136,145,57,2,83,91,71,46,49,36,36,235,242,121,183,244,245,217,223,212,206,213,236,246,242,245,243,245,239,227,236,244,243,244,243,248,246,241,252,252,167,129,69,60,209,238,245,232,101,184,245,196,238,252,248,251,247,250,249,252,229,236,252,252,253,253,249,186,84,14,57,150,71,41,31,76,94,31,31,24,55,100,85,67,42,98,113,57,61,20,56,189,243,248,250,249,252,245,244,247,249,239,222,238,245,244,245,244,244,244,232,232,245,247,224,219,248,252,193,165,203,239,233,222,168,152,222,236,225,245,199,192,212,199,231,208,211,235,237,237,235,230,252,204,110,105,81,75,41,23,8,73,242,249,251,251,211,199,215,252,243,156,80,70,181,223,225,233,199,211,218,215,219,214,214,216,216,213,214,214,212,212,213,212,211,213,212,214,211,209,210,212,212,209,210,210,208,209,210,209,208,208,210,209,207,208,208,208,207,205,207,205,205,207,207,206,207,206,205,205,206,206,205,205,207,208,208,210,212,220,195,146,113,78,60,65,63,56,60,54,39,57,69,55,48,43,39,30,38,55,58,42,19,123,224,224,229,221,220,219,217,219,218,222,222,217,220,220,219,219,219,218,217,218,218,219,217,215,217,215,215,214,214,215,213,214,213,213,214,214,212,211,212,212,212,210,212,210,210,208,212,113,1,1,4,7,8,8,10,9,10,11,10,10,217,219,217,220,220,216,216,218,217,217,217,217,218,215,216,217,216,219,220,219,218,220,218,216,219,219,218,217,217,219,220,221,218,218,220,220,220,219,218,218,219,219,220,218,220,220,219,220,219,221,220,218,222,222,222,218,219,221,217,220,220,218,222,219,219,220,220,219,221,222,221,221,221,221,222,224,224,224,223,224,226,226,224,225,226,224,224,224,224,224,224,225,221,222,226,226,225,224,223,224,224,225,225,223,223,223,226,225,224,224,227,224,224,224,224,226,226,225,227,226,228,227,224,224,228,226,225,227,227,227,224,226,226,225,224,227,227,229,228,228,230,227,228,227,230,229,229,232,227,232,232,229,232,232,233,232,231,232,232,233,233,234,236,235,236,235,236,235,234,234,235,235,234,235,236,237,238,238,238,239,239,239,239,240,241,240,241,242,241,241,243,243,243,243,243,243,243,243,243,245,244,243,245,244,243,245,244,244,245,243,244,245,245,246,249,248,247,247,247,246,247,247,247,247,247,247,247,247,247,246,247,247,246,246,246,246,245,244,244,244,244,244,245,244,245,244,244,245,245,244,244,245,246,246,244,245,246,245,244,244,246,245,246,246,245,247,246,247,246,246,246,246,247,246,246,246,246,246,245,244,246,247,236,235,245,247,247,247,247,248,246,247,249,241,240,246,247,246,242,244,246,246,247,246,244,245,245,245,247,245,245,245,244,244,244,244,244,245,244,244,245,244,243,244,242,237,240,245,244,243,245,245,244,246,244,245,245,246,245,249,241,220,252,231,192,211,205,231,238,226,242,240,229,198,220,250,246,178,153,151,131,53,112,243,251,251,218,176,225,240,237,228,240,229,228,208,150,184,189,205,252,252,251,251,202,212,202,212,242,229,245,229,242,251,239,249,244,247,241,234,232,198,177,184,239,198,134,141,53,3,78,81,64,49,50,41,51,239,249,111,160,237,243,221,215,217,226,215,234,249,241,244,242,245,241,228,231,241,242,243,244,248,246,234,253,221,134,156,90,62,195,234,245,177,85,216,232,203,248,249,249,247,247,249,250,250,215,238,252,252,252,252,249,208,124,33,84,180,71,30,15,69,84,32,34,19,67,104,81,65,36,98,109,57,60,28,54,196,249,249,249,249,252,247,243,248,248,244,224,232,245,244,246,244,244,246,231,226,239,249,231,218,241,252,208,163,193,234,235,221,185,145,186,236,224,234,204,167,173,199,246,221,203,236,239,235,237,230,252,198,113,107,88,70,29,8,27,156,234,251,252,230,204,213,234,234,202,125,52,60,188,219,227,228,198,211,216,217,218,213,218,216,215,214,215,214,212,215,215,213,213,212,211,212,212,210,212,213,212,210,208,208,210,210,208,209,208,208,209,209,210,209,208,209,211,208,207,208,208,207,205,210,207,206,208,205,206,206,205,207,208,207,206,210,214,219,204,172,173,155,118,108,81,69,73,58,94,113,84,67,51,45,39,37,46,58,27,40,147,224,243,221,221,225,221,222,217,216,218,218,218,219,217,218,218,218,217,217,217,216,216,216,216,216,215,215,218,215,216,215,213,215,214,215,214,213,215,212,212,212,211,211,210,210,212,210,210,110,3,1,3,7,9,7,9,9,10,10,10,10,219,221,218,219,222,218,218,219,219,219,220,221,218,218,221,218,221,219,219,221,218,222,218,219,220,216,221,219,217,218,219,218,219,220,219,218,219,220,219,219,222,221,222,220,220,222,221,223,223,221,222,220,219,219,219,222,222,222,220,221,221,220,222,223,223,221,223,222,223,223,222,221,221,224,225,225,224,225,226,227,228,229,228,229,227,226,227,226,226,228,226,228,227,226,227,225,226,229,226,225,229,227,227,227,226,228,228,228,227,227,229,226,226,228,223,226,224,227,227,224,229,225,226,227,226,229,228,227,226,223,226,225,225,226,226,229,228,225,227,229,228,229,229,229,229,230,230,231,231,232,234,231,232,233,234,236,233,234,234,235,236,236,236,235,235,236,236,234,233,236,235,235,236,235,237,237,237,239,238,239,237,238,238,238,240,241,241,239,242,242,243,243,242,242,242,242,243,243,244,244,245,245,245,244,242,243,245,245,247,246,246,245,246,246,247,247,246,247,246,247,247,247,247,247,249,247,247,247,247,247,247,247,246,246,246,246,245,246,245,244,244,245,247,247,245,244,245,246,247,246,244,244,244,245,246,246,245,244,245,244,245,246,246,247,247,246,246,247,247,247,245,245,246,246,248,246,247,247,246,246,249,247,235,237,248,245,246,247,246,247,247,247,245,237,242,247,247,244,241,246,246,244,247,245,245,246,245,245,245,244,245,244,244,244,244,244,244,244,244,244,245,245,245,244,242,235,239,243,244,244,241,244,243,246,244,246,246,246,245,249,233,212,239,191,194,238,229,252,252,226,220,228,219,193,221,250,247,174,144,143,130,54,108,244,252,252,249,202,194,203,235,246,237,220,214,187,180,203,202,221,252,252,250,247,185,219,206,215,232,187,230,229,239,242,236,250,241,249,241,235,229,200,181,187,245,181,118,136,49,8,66,73,62,49,57,41,46,212,168,87,156,206,238,212,213,226,232,213,230,248,242,247,242,244,241,232,234,239,241,242,244,247,247,217,220,182,150,212,118,41,150,206,227,156,158,249,222,210,251,248,250,247,248,246,251,243,210,241,252,252,249,248,249,177,117,39,84,168,57,31,19,75,73,29,32,20,65,93,83,69,42,79,111,62,51,27,45,192,249,249,249,247,252,246,242,248,246,248,224,224,244,245,245,244,244,247,237,226,236,247,236,215,232,252,225,169,181,223,239,223,199,160,165,228,231,204,198,166,134,175,240,235,201,218,231,229,233,237,252,191,120,111,88,50,16,4,83,243,252,252,248,210,208,231,252,252,158,104,36,66,199,212,231,223,193,214,213,218,217,212,214,214,214,213,214,213,211,211,213,211,209,212,211,210,211,212,213,212,211,210,211,210,210,210,209,206,210,209,209,208,207,211,208,209,209,208,210,211,210,209,209,208,208,208,208,209,208,206,208,208,207,205,207,211,213,213,189,193,226,225,194,146,103,72,47,34,80,126,107,81,60,45,43,34,51,29,36,154,230,235,245,222,225,221,220,218,214,216,216,220,220,218,220,218,220,219,216,217,218,217,215,217,215,216,215,214,216,214,217,214,212,213,213,213,214,214,211,214,211,213,213,212,211,208,214,212,211,111,2,1,3,7,9,7,10,10,10,10,10,10,220,224,219,221,222,218,219,220,220,219,220,220,220,219,219,222,218,220,222,220,221,219,222,222,221,221,218,219,221,219,221,221,219,220,219,219,220,220,222,221,224,220,223,220,220,222,222,225,220,224,222,220,222,219,223,220,220,222,222,224,221,224,224,221,221,222,224,220,222,222,220,224,222,223,225,225,225,227,227,226,228,227,228,230,229,229,228,228,229,229,227,228,229,227,226,229,229,229,229,230,230,228,230,230,230,230,228,229,228,226,231,227,226,229,229,229,227,226,227,224,227,226,225,226,226,228,229,226,226,228,228,229,230,228,227,229,226,228,229,227,229,230,229,227,229,230,232,233,230,232,232,232,234,234,235,232,235,236,236,235,234,235,234,236,235,232,234,234,236,236,235,236,233,237,238,237,239,238,239,239,239,240,238,240,239,240,240,240,240,241,243,242,242,242,244,243,244,244,244,243,244,245,243,243,244,244,245,245,245,245,245,245,245,244,246,246,247,246,246,247,247,247,247,248,246,247,247,246,247,247,247,247,246,246,246,246,246,246,245,246,244,244,245,244,244,245,245,246,245,245,244,244,244,244,243,244,244,244,245,244,245,245,245,245,246,246,246,246,245,246,247,247,246,245,246,246,246,245,246,246,249,244,233,241,246,246,249,245,245,244,245,249,244,238,244,248,247,242,242,246,245,245,246,246,245,246,245,245,245,244,244,244,244,244,246,244,244,245,244,243,244,244,242,242,242,237,237,241,241,242,243,243,242,243,243,244,246,247,244,251,227,211,239,207,226,250,240,252,224,199,226,230,216,196,225,251,243,158,127,136,115,44,111,244,252,252,249,214,187,181,214,246,251,240,204,174,198,205,203,221,247,252,249,237,152,203,203,190,153,94,173,204,230,228,231,248,241,249,243,233,231,214,179,190,242,163,119,132,41,20,65,56,55,57,50,57,31,49,96,138,177,208,227,201,197,218,234,209,230,247,241,245,243,245,240,233,229,237,242,243,243,248,245,228,231,171,175,224,125,45,108,222,250,160,208,251,207,224,251,248,250,245,248,244,251,233,209,248,249,250,243,242,248,156,101,26,87,155,37,28,25,83,66,26,30,22,61,84,82,78,50,92,116,62,51,39,25,128,244,244,247,247,251,246,242,248,246,250,232,220,238,248,247,247,245,246,243,227,234,248,240,216,226,251,237,174,175,217,236,231,210,171,163,217,223,161,197,198,114,150,223,227,162,173,220,226,235,241,252,181,110,104,66,41,34,115,183,248,250,250,231,215,229,234,254,220,135,98,30,103,211,215,234,216,195,208,212,219,215,210,214,211,213,212,213,212,211,211,210,210,210,210,209,210,210,208,210,212,210,212,212,211,211,208,212,209,207,207,209,210,206,208,208,207,208,208,208,208,207,208,209,209,207,208,208,206,208,207,206,205,207,206,206,208,213,198,179,197,223,235,213,157,103,57,25,13,23,43,65,65,51,46,33,34,22,8,110,223,244,241,228,223,226,220,215,217,215,217,219,219,218,217,219,219,218,219,218,217,217,217,217,214,214,217,215,215,214,213,213,212,212,215,214,213,212,212,213,210,212,211,208,210,212,212,212,211,212,113,1,1,5,8,8,7,10,9,10,11,10,10,220,223,221,221,219,217,218,219,221,220,217,218,221,222,219,219,221,219,220,219,220,223,219,219,220,217,219,218,218,220,220,221,219,220,221,221,222,220,219,217,221,221,219,220,220,220,220,221,218,218,223,223,222,222,220,221,223,222,222,222,223,222,221,221,220,222,222,221,222,225,224,223,225,225,226,226,226,227,229,229,229,230,229,229,231,230,231,230,231,230,228,227,230,229,229,230,230,230,230,232,231,230,231,230,232,232,228,230,228,229,231,229,230,231,228,229,228,229,227,226,229,226,226,226,224,226,227,227,229,229,229,227,228,228,228,229,231,229,229,230,229,229,229,231,229,230,230,232,230,230,232,228,230,232,232,232,232,236,234,234,234,231,232,235,235,235,236,236,236,237,237,238,239,236,237,237,237,237,237,239,240,239,237,237,239,240,241,241,240,240,240,240,241,241,244,242,243,245,245,243,244,243,243,242,242,242,244,245,245,245,244,244,245,244,245,245,244,247,246,247,245,245,247,248,247,246,244,245,246,248,247,246,246,246,247,247,245,244,245,244,244,245,245,244,246,246,245,246,244,244,244,244,245,245,245,244,244,244,245,244,245,245,244,244,246,245,244,246,244,245,245,245,244,244,246,245,246,246,245,246,248,240,230,241,246,245,246,246,246,245,246,247,239,239,247,247,245,241,245,247,246,245,245,244,245,245,244,245,245,244,244,244,244,244,244,245,246,245,244,243,243,243,242,240,243,239,237,241,242,242,244,245,243,244,242,244,245,247,244,251,225,232,252,214,236,245,204,208,220,229,245,248,224,203,224,246,237,161,135,128,113,41,104,245,247,251,251,228,218,179,188,231,245,252,224,184,228,199,204,224,240,252,239,169,92,206,196,152,103,17,83,174,233,222,232,247,240,251,245,232,226,210,165,182,245,179,149,141,60,49,63,65,59,43,52,51,40,35,103,206,208,229,243,193,192,217,233,212,231,246,242,244,242,244,240,233,229,234,240,244,241,248,244,224,184,119,160,210,125,97,214,249,244,181,240,251,196,232,252,247,249,245,248,247,251,222,217,251,247,250,242,244,247,155,99,24,94,155,38,27,33,90,55,23,32,25,64,76,82,77,53,89,116,74,45,46,10,72,226,243,249,249,251,247,241,248,244,248,237,217,235,246,247,247,245,247,245,230,234,244,246,221,220,249,247,189,169,207,238,230,213,182,119,162,194,151,204,231,162,158,218,217,151,160,203,223,235,251,236,146,100,81,66,25,84,237,252,252,250,229,221,226,249,252,252,183,124,91,32,150,223,214,236,209,199,214,212,217,214,212,213,213,214,213,214,211,212,210,210,211,210,211,211,212,210,211,211,212,210,210,211,211,210,210,211,209,208,208,209,207,208,208,208,210,208,208,207,208,206,207,210,209,208,207,207,206,207,207,205,206,205,208,210,212,213,188,174,198,216,222,220,189,155,140,110,71,58,49,31,33,24,6,49,93,153,209,237,241,235,230,228,221,219,216,216,218,217,217,220,219,217,218,218,216,218,217,218,218,218,218,217,217,214,217,213,214,215,213,214,212,213,214,214,212,212,213,212,212,211,214,213,210,213,211,213,211,211,113,1,1,4,7,8,7,10,9,9,10,10,10,221,224,220,221,222,217,219,220,219,220,221,220,220,224,221,221,221,220,224,218,221,220,219,218,217,217,217,219,220,219,219,220,220,223,221,220,222,221,220,218,222,218,219,220,219,222,220,221,221,221,221,223,223,221,224,221,221,223,221,223,220,222,223,220,224,223,224,224,223,225,224,225,225,224,227,226,225,227,229,229,230,230,230,230,231,232,232,233,231,231,231,231,231,229,231,232,229,230,230,229,232,229,229,231,229,231,228,227,230,229,230,228,229,229,229,228,227,229,231,227,229,228,228,228,227,227,227,226,229,228,229,227,226,229,229,231,228,227,229,227,227,229,229,230,230,231,230,231,232,231,232,231,231,231,231,233,233,232,234,233,234,235,234,236,233,233,237,236,237,237,235,239,237,236,236,236,238,237,236,235,237,237,237,240,238,239,239,240,240,239,241,241,240,241,241,242,242,241,244,244,241,241,241,243,244,243,244,245,243,245,245,245,245,245,246,244,245,244,245,245,244,244,244,245,245,245,244,244,245,246,247,246,246,245,246,245,245,246,244,244,245,245,245,245,245,245,244,244,244,244,245,245,245,245,242,245,244,243,243,243,243,245,244,244,244,243,244,244,244,245,244,244,245,245,246,246,244,244,246,247,248,234,232,245,245,247,245,243,246,245,247,244,235,240,246,246,241,241,245,245,245,245,246,246,244,244,245,244,245,243,244,244,241,245,243,243,244,243,243,243,242,242,242,242,243,238,235,238,241,243,243,244,243,244,244,244,243,245,245,252,220,229,243,191,208,196,190,240,242,248,249,243,223,205,225,241,234,164,151,146,115,40,99,240,248,251,248,232,243,208,170,207,238,252,227,203,248,200,221,224,232,253,182,109,62,154,157,87,37,3,95,201,246,229,241,251,252,253,252,249,246,234,176,199,252,223,199,162,71,52,71,72,63,49,47,54,42,49,200,248,231,252,252,211,207,243,252,227,247,252,252,252,250,249,244,239,233,234,241,243,243,248,243,205,118,66,131,136,101,174,251,252,202,174,251,236,200,244,248,249,247,247,249,249,252,212,223,251,245,250,243,244,248,150,101,29,98,161,42,22,41,91,49,24,29,27,63,84,81,71,50,76,107,74,48,48,11,92,242,245,248,248,250,244,238,247,242,246,245,222,227,244,246,246,245,245,248,232,229,240,246,229,217,244,251,200,165,194,229,234,219,174,106,80,144,185,219,248,191,182,221,217,185,184,197,219,242,252,205,117,89,90,64,92,180,234,253,253,234,232,233,234,252,234,216,142,136,74,60,182,220,224,230,205,202,212,215,218,213,213,215,212,213,211,214,210,212,213,211,211,210,211,210,211,213,212,211,210,210,212,211,208,210,210,209,208,212,211,208,211,209,209,208,209,210,206,209,210,209,210,208,208,211,210,206,207,210,206,208,210,207,211,211,215,211,187,189,207,211,221,229,233,238,234,221,226,201,137,77,16,92,211,239,242,251,251,249,249,232,225,222,217,217,217,218,217,217,220,218,217,218,218,219,216,216,217,218,217,218,215,215,216,218,218,215,216,214,215,215,215,215,214,212,216,214,212,213,212,211,212,213,210,211,210,214,212,210,112,2,1,2,6,8,6,9,9,9,9,9,9,221,224,222,223,225,222,222,220,222,222,222,223,223,220,220,223,222,220,224,224,221,222,220,223,221,220,223,220,221,222,220,220,221,221,219,218,221,221,221,222,221,221,223,223,221,221,223,224,223,228,221,221,224,222,226,225,222,222,223,224,226,226,226,227,228,226,226,224,223,226,225,226,224,228,226,225,227,228,229,227,229,231,230,231,231,231,232,230,231,231,232,232,232,232,232,232,231,232,231,232,231,230,232,228,231,230,229,229,227,230,228,227,229,229,230,229,231,232,229,229,231,227,229,229,229,229,230,232,230,230,232,230,230,230,228,231,229,230,230,229,229,230,231,230,231,230,232,234,232,232,233,231,232,232,232,234,233,235,233,234,237,237,236,235,234,235,237,236,237,235,236,237,237,239,238,239,240,239,239,237,237,237,239,238,241,240,239,241,241,242,240,241,242,242,243,242,243,242,242,243,243,243,242,242,243,243,243,244,243,244,244,244,246,244,245,246,245,246,245,246,245,244,246,244,244,245,245,245,244,244,244,245,245,244,245,246,247,245,245,244,245,246,245,245,245,243,244,244,245,245,244,244,244,244,243,244,244,244,245,244,244,245,244,243,245,245,245,246,244,245,245,246,245,244,246,246,245,245,244,245,245,232,235,244,245,246,245,244,245,245,245,240,236,244,245,244,240,241,246,245,244,244,245,245,245,245,245,245,245,244,243,245,243,244,242,243,244,242,242,241,241,240,243,243,244,241,234,240,243,243,244,241,243,245,245,246,242,244,246,248,209,224,212,170,215,227,233,252,237,214,227,237,221,212,231,245,239,182,175,155,126,41,93,238,242,251,243,230,249,230,197,207,222,252,225,171,236,156,179,214,217,227,118,32,10,131,127,64,33,89,227,249,252,252,252,252,252,252,252,252,252,252,220,226,252,250,202,146,63,51,69,76,58,54,56,53,49,85,233,248,252,252,252,239,248,252,253,253,253,253,253,253,253,253,252,252,252,248,249,251,248,251,247,214,132,66,71,43,69,181,250,227,105,173,251,214,207,245,247,248,246,249,245,252,245,202,232,251,244,250,243,249,248,146,73,11,84,132,40,20,66,92,41,28,23,35,64,81,83,70,55,71,107,77,44,49,12,83,243,244,249,249,249,245,238,246,243,246,247,225,220,239,246,246,246,244,247,236,225,235,249,232,214,236,252,216,166,184,225,231,223,203,150,127,169,216,219,235,193,162,207,208,208,212,194,218,247,242,164,126,117,65,86,193,252,252,251,250,235,240,244,248,252,252,168,106,132,73,93,203,220,223,231,204,200,214,213,219,213,213,214,212,211,209,213,211,211,213,212,210,211,210,211,211,211,212,210,211,212,212,209,211,211,210,209,208,209,208,211,212,212,210,208,210,209,208,211,212,209,209,210,210,211,211,209,210,209,209,210,212,210,211,215,217,201,184,199,214,213,218,226,231,244,249,251,251,233,178,114,80,184,234,252,252,251,251,238,231,225,220,219,217,217,218,217,216,217,217,219,219,217,219,218,219,218,215,216,217,216,215,218,217,216,217,214,216,216,214,217,216,216,215,213,215,213,213,213,213,212,212,214,213,212,211,213,212,212,112,2,1,2,6,8,7,9,9,9,10,10,10,221,224,223,223,223,220,222,223,222,220,220,220,222,222,218,223,222,223,225,221,225,222,222,222,222,225,222,222,221,220,219,219,220,220,222,222,223,223,222,222,223,223,223,225,225,224,224,224,224,225,226,224,224,224,226,223,222,225,226,226,225,228,227,227,227,227,227,223,226,227,226,228,225,227,226,226,229,227,230,228,228,230,230,234,232,231,232,230,229,229,229,231,232,232,234,234,234,233,232,231,232,234,230,232,231,232,231,230,230,229,230,229,231,229,230,231,231,230,230,229,230,230,231,229,230,231,230,231,234,232,233,236,233,232,231,231,231,232,230,230,231,231,231,230,229,231,230,230,232,230,232,230,232,234,233,235,234,233,234,234,234,235,233,236,236,235,236,236,235,237,237,237,238,237,240,241,240,240,240,239,239,238,239,239,238,240,241,241,240,240,241,242,241,241,242,242,243,242,242,242,241,241,241,241,242,242,241,243,244,244,244,244,244,245,245,245,246,245,246,244,244,244,241,243,244,244,245,246,246,246,245,244,245,245,247,245,244,245,246,245,244,245,245,245,244,244,243,244,243,244,244,244,244,243,242,244,244,243,245,245,244,245,244,244,244,244,243,244,245,244,245,244,245,245,243,244,243,244,243,246,242,225,237,245,244,245,243,244,245,244,245,235,236,245,245,242,239,243,246,245,244,242,242,244,244,244,243,241,243,243,243,241,244,243,241,242,241,241,241,241,240,241,241,241,242,240,237,239,241,242,242,242,244,243,244,243,243,242,246,246,208,234,224,208,247,240,243,230,194,214,226,236,217,212,236,248,242,177,171,162,141,66,103,233,243,250,241,226,248,237,214,210,203,251,192,117,179,82,129,206,208,204,85,21,106,220,225,214,205,243,253,253,253,253,253,253,253,253,231,208,193,193,141,148,192,150,122,78,32,45,44,48,49,47,44,51,34,54,178,163,157,213,181,163,204,240,247,229,252,252,252,252,253,253,253,253,252,252,252,252,253,253,250,244,162,91,64,4,43,198,247,177,67,177,250,200,220,246,244,248,244,247,242,252,234,200,238,249,244,248,245,249,241,144,77,9,18,67,45,30,74,92,35,27,24,36,62,76,81,71,54,70,114,81,42,55,12,82,241,243,247,247,248,242,237,245,243,245,249,233,217,236,245,244,244,243,246,238,224,231,246,237,211,227,252,226,173,173,215,232,227,218,206,167,188,236,221,208,194,174,174,187,212,224,200,216,249,212,145,117,97,80,146,245,252,252,251,241,234,239,242,247,253,218,111,85,115,74,119,204,211,226,225,205,200,211,212,215,213,214,212,210,212,209,211,211,210,210,209,210,211,208,209,211,212,209,209,209,210,210,211,212,212,209,210,208,209,210,209,210,210,210,208,208,210,209,209,208,208,210,210,208,208,208,210,210,211,211,209,211,209,212,216,208,185,184,203,214,218,219,217,220,226,234,240,246,210,154,106,71,198,233,228,245,235,234,225,221,220,218,216,216,219,215,218,218,215,217,218,218,217,217,218,215,216,216,217,217,216,217,216,217,215,214,215,214,214,217,214,212,215,214,212,212,212,214,213,213,212,213,210,208,213,212,212,210,212,113,1,1,3,6,7,7,10,8,9,10,9,9,220,224,225,224,225,221,223,222,222,224,221,221,224,221,222,223,223,223,223,222,222,223,220,223,224,221,224,221,222,222,221,222,224,223,225,224,223,225,223,227,225,225,225,226,225,225,226,226,227,227,226,226,227,225,226,227,229,228,227,229,226,226,227,227,227,226,226,226,228,227,226,227,228,229,228,229,228,229,229,229,232,232,231,231,234,234,232,233,232,231,233,233,233,233,233,234,234,234,232,233,234,231,233,230,232,230,230,232,228,231,231,231,231,230,232,231,228,231,230,231,234,229,231,233,232,232,232,234,233,234,235,234,235,237,235,234,233,233,231,230,232,231,232,232,233,232,230,231,231,232,231,231,232,232,233,232,233,235,234,234,235,236,235,236,236,235,237,236,237,235,236,239,237,237,239,238,240,238,239,238,239,242,240,241,240,241,242,241,240,240,240,242,242,241,242,241,242,242,243,243,241,241,242,241,243,242,243,242,245,246,244,244,245,245,245,245,245,244,244,243,242,241,241,242,244,245,245,247,244,245,245,245,244,244,244,244,246,245,245,244,245,245,244,244,245,245,244,243,244,243,244,243,242,244,244,244,244,244,244,242,244,245,245,245,245,245,245,244,244,244,244,245,245,244,244,244,243,245,245,246,235,225,240,244,244,246,243,243,244,245,243,234,240,244,244,240,239,244,245,244,245,244,243,242,245,244,243,242,242,245,243,243,242,242,242,241,243,241,240,241,241,241,241,241,241,242,236,235,240,242,242,240,243,242,244,242,241,241,248,240,211,250,229,217,252,213,183,223,224,237,242,235,214,214,237,250,236,151,143,165,176,117,145,247,249,251,244,224,242,233,222,226,198,229,144,53,122,33,88,198,206,245,190,204,252,252,252,252,252,252,243,229,206,155,155,137,124,115,99,88,65,42,24,15,13,54,56,21,31,44,42,46,47,43,42,42,38,42,45,27,12,9,8,10,10,17,34,34,69,105,131,163,186,220,231,247,253,253,252,252,252,252,252,252,226,144,94,25,43,207,229,157,131,231,248,199,235,250,248,249,244,248,245,252,222,202,246,246,247,249,248,252,231,208,134,18,1,14,45,63,98,78,29,30,20,44,63,73,84,65,53,62,107,88,46,54,11,82,242,244,249,249,246,243,240,245,243,245,246,241,217,227,244,244,244,243,246,245,228,229,244,241,216,222,249,238,184,166,203,229,224,224,220,187,169,223,220,174,190,198,155,166,226,238,220,220,241,180,102,89,61,108,226,252,250,250,246,245,242,244,239,248,249,181,68,87,118,81,142,204,214,229,233,214,218,227,221,221,213,213,214,211,213,211,212,212,212,210,210,210,211,214,211,211,210,210,210,211,213,208,209,210,209,210,209,212,211,210,213,212,210,211,211,212,212,209,209,211,212,211,210,210,208,209,213,213,213,214,215,213,213,216,218,198,177,191,212,217,222,221,219,219,220,225,231,243,195,149,90,65,189,223,218,231,224,225,218,219,220,218,217,218,220,220,222,218,217,218,219,218,217,218,220,217,215,217,220,218,216,214,216,217,214,215,216,217,216,216,215,214,214,214,214,214,214,215,215,211,212,213,212,211,211,214,212,209,213,112,1,1,4,6,7,7,10,8,9,10,9,9,223,224,224,222,225,225,224,224,224,222,226,224,225,222,221,225,221,223,222,222,222,220,225,222,223,225,221,224,224,222,224,223,225,222,223,224,222,223,223,223,225,225,224,227,227,226,226,225,226,227,228,227,227,230,230,229,229,228,227,229,229,230,227,226,228,227,228,227,228,229,228,229,227,230,231,230,232,230,231,231,231,232,232,233,232,231,235,235,233,236,235,236,235,237,235,234,236,235,232,231,231,231,231,231,231,230,229,231,233,230,232,229,231,234,231,230,229,229,230,231,230,231,232,233,235,234,237,238,237,237,236,235,235,234,234,234,234,232,231,234,232,232,232,233,234,232,234,234,234,233,233,232,232,232,233,235,234,235,236,235,236,236,236,236,237,236,237,235,235,237,238,238,238,237,239,240,238,240,238,238,241,240,240,240,241,242,241,242,242,241,241,240,239,240,242,243,242,240,241,242,242,242,243,243,243,242,243,243,243,244,244,244,244,244,245,245,244,242,244,242,241,241,242,242,242,243,243,243,244,245,246,246,245,245,245,244,245,246,246,246,245,245,243,244,245,244,244,245,244,244,243,243,244,243,242,243,243,244,244,243,242,242,242,242,243,243,242,242,242,243,243,242,241,244,244,243,244,244,243,247,232,226,244,243,244,244,242,244,245,245,237,232,243,246,242,237,241,243,242,243,243,244,243,244,243,242,244,243,244,242,243,243,243,242,240,242,242,242,242,239,240,241,241,241,242,242,236,234,239,242,242,241,242,240,243,240,242,239,248,232,203,234,203,205,214,187,220,247,240,241,231,236,212,217,240,246,239,156,134,145,160,143,187,250,248,252,243,223,241,230,221,240,224,224,128,62,94,3,83,220,252,252,253,253,253,252,210,173,138,137,104,96,99,73,77,68,69,74,59,50,29,12,6,14,10,48,76,29,43,53,50,54,53,51,49,45,42,39,42,36,38,30,8,8,9,10,10,10,10,10,10,11,11,11,27,53,101,130,171,213,243,249,252,245,248,210,132,69,44,115,142,142,181,250,240,200,243,249,249,248,245,246,247,252,209,208,249,245,250,247,252,252,219,221,163,42,11,7,22,83,114,73,29,31,21,41,67,78,80,63,50,50,89,85,45,54,14,71,238,244,249,249,247,242,236,246,241,243,246,247,223,220,241,244,244,243,243,246,229,224,240,244,218,215,243,243,193,163,190,225,222,220,224,199,163,210,222,146,196,231,156,172,231,249,240,211,185,118,82,56,85,176,252,252,250,249,244,244,242,243,239,252,234,155,63,84,111,95,153,209,233,242,251,248,236,249,234,220,216,217,214,212,213,209,212,212,212,213,212,210,210,212,212,211,212,210,213,211,210,214,210,210,211,210,211,213,211,211,214,212,213,211,210,212,212,212,213,211,212,212,211,211,213,213,214,215,213,214,214,216,217,218,220,195,181,203,216,220,221,222,222,221,222,230,240,246,193,144,79,65,194,216,219,230,217,224,217,219,218,217,216,215,219,220,219,217,218,220,220,220,218,220,217,214,219,217,219,217,217,217,214,217,217,217,216,216,216,215,215,214,216,213,214,215,214,213,211,214,213,214,213,212,212,209,213,212,210,112,2,1,3,7,8,6,9,9,10,10,9,9,223,226,225,224,226,223,225,226,225,224,225,223,225,225,226,225,222,223,223,226,225,226,226,226,225,223,227,225,225,224,224,224,225,224,225,225,225,227,224,225,226,226,226,228,227,226,229,229,229,229,227,229,231,229,230,229,231,229,230,230,228,230,230,231,231,231,229,230,231,230,230,231,230,231,234,233,233,233,232,234,233,232,231,232,234,232,234,236,235,234,236,236,235,236,235,236,234,232,232,232,233,230,232,232,233,233,231,232,231,230,230,229,232,232,232,231,229,232,229,229,232,231,234,235,236,238,239,237,237,237,238,236,236,237,236,235,235,236,238,236,236,235,234,233,235,235,235,237,239,237,236,238,236,236,236,236,235,237,236,236,234,235,237,234,235,237,236,237,240,238,238,239,237,239,239,239,239,239,239,240,241,240,239,239,241,242,240,240,241,243,243,241,241,239,240,243,242,240,241,242,241,242,242,241,243,241,243,243,242,242,242,244,242,244,243,243,243,243,244,242,242,242,243,243,243,243,242,243,243,245,245,243,244,244,245,245,242,243,246,245,246,245,244,246,244,244,242,242,243,243,242,244,244,243,243,243,243,243,241,243,243,242,243,243,243,242,244,243,243,244,244,244,244,244,243,244,243,243,246,244,225,231,245,244,244,242,243,244,244,243,232,236,246,245,240,237,242,245,245,245,242,242,243,242,242,241,240,242,242,242,242,241,242,241,240,239,240,241,242,243,241,242,241,241,242,243,240,232,237,240,241,241,241,241,242,240,241,236,247,219,192,222,174,182,229,226,248,252,202,212,230,235,210,217,238,247,241,162,141,128,108,81,155,243,232,242,233,220,238,227,222,237,238,252,182,106,103,35,151,245,253,253,159,121,150,127,98,78,51,55,60,78,93,100,105,100,120,122,110,101,87,94,112,105,61,79,95,73,61,51,56,56,54,43,50,82,69,54,94,92,40,56,83,68,70,63,54,28,12,12,9,10,11,10,9,11,10,12,10,12,16,57,110,119,204,167,147,125,65,71,31,122,224,248,231,203,247,247,250,248,247,243,250,252,198,220,251,244,251,246,253,253,199,207,129,33,37,16,18,51,85,63,33,27,19,48,69,74,76,55,42,38,80,90,47,50,14,62,228,243,249,249,246,239,239,245,242,245,245,251,229,213,236,244,244,244,242,245,231,220,236,245,222,208,236,244,208,169,180,219,222,219,222,207,164,178,234,199,219,252,188,163,231,246,246,156,105,89,70,71,131,241,252,252,250,249,247,242,234,237,238,251,229,137,54,64,109,108,162,216,238,247,226,198,200,234,245,225,214,215,214,214,211,211,213,210,214,211,212,212,209,213,210,210,212,213,214,210,214,211,214,213,212,217,212,213,214,212,214,214,215,213,212,213,214,214,212,212,211,210,212,214,213,214,216,216,217,217,219,220,219,223,217,186,189,213,218,223,222,218,221,224,231,244,250,240,167,123,63,65,174,207,222,230,217,222,218,219,221,218,219,219,217,219,219,218,220,221,219,219,220,218,217,217,218,219,217,215,219,219,216,218,217,218,216,214,216,215,214,215,216,214,214,215,213,214,214,213,214,211,212,214,213,213,213,212,212,112,2,1,3,7,8,6,9,9,10,10,10,10,222,225,225,224,225,222,223,225,227,224,227,226,223,224,225,227,224,224,225,225,229,227,224,225,227,229,226,226,225,224,227,227,228,227,226,227,225,227,227,226,228,228,228,227,229,227,229,229,229,231,230,231,232,232,233,231,231,231,232,232,229,231,232,231,232,231,232,231,231,232,231,231,229,231,231,229,231,231,232,232,233,233,229,231,234,234,234,234,234,235,233,232,233,233,234,232,232,230,229,230,234,234,232,232,232,232,231,231,232,229,232,232,230,231,230,232,234,231,231,232,232,233,234,235,235,236,237,237,237,236,237,235,237,237,238,235,235,238,237,237,236,236,236,238,239,239,240,239,237,240,240,237,237,237,238,237,236,237,236,237,235,235,235,235,237,236,238,236,236,236,238,238,237,238,237,239,239,239,240,240,239,238,240,239,238,239,241,241,240,240,240,242,241,241,241,241,242,240,241,241,242,241,241,242,241,241,241,242,242,243,242,241,243,243,244,242,241,241,240,240,242,240,240,240,241,241,240,239,240,241,241,242,241,240,244,243,244,244,242,243,242,243,243,244,243,242,242,242,241,241,241,242,241,243,243,243,244,244,242,242,242,241,241,242,242,241,242,242,243,241,242,241,241,243,242,242,244,243,246,238,221,234,244,243,244,243,243,242,245,238,231,240,245,241,237,238,242,241,243,242,241,242,242,243,241,241,241,242,241,241,241,240,240,240,240,240,239,241,241,240,240,240,239,239,240,242,240,233,235,240,239,240,240,240,240,237,239,236,248,211,214,236,191,226,243,212,208,213,210,229,232,237,201,212,240,248,242,148,122,124,103,34,98,228,229,237,223,208,236,225,215,235,248,252,225,214,167,73,147,159,127,106,55,47,46,57,80,73,66,60,49,57,77,112,185,204,232,244,251,251,249,252,247,195,78,68,129,126,83,45,64,62,52,49,150,206,139,152,200,154,95,193,251,247,250,250,252,249,238,238,223,174,102,54,21,7,6,8,9,8,10,9,13,11,81,77,83,96,73,88,22,112,246,247,221,211,248,244,249,247,245,242,252,239,191,232,252,244,250,243,252,252,196,193,104,17,91,69,23,31,49,64,42,28,26,45,69,66,68,52,39,38,82,89,42,55,14,67,228,243,249,249,244,239,239,247,241,244,240,246,237,212,228,240,241,244,238,244,233,218,230,243,229,207,229,247,218,174,171,210,220,215,218,202,139,143,197,185,246,252,173,141,177,241,246,155,93,83,65,91,198,252,252,252,250,248,242,237,235,240,234,251,206,138,73,79,119,123,167,218,251,178,110,75,45,160,221,213,220,210,214,214,215,214,210,212,211,210,211,211,214,212,210,212,213,212,214,212,210,213,213,215,214,213,214,214,212,212,213,210,213,212,215,216,212,213,213,211,211,211,212,214,214,215,215,215,216,217,217,218,223,224,201,182,201,218,217,218,220,223,225,234,248,248,232,179,117,89,25,34,169,208,225,229,217,224,217,220,218,218,218,218,217,215,218,221,219,218,216,218,215,216,217,215,219,215,217,217,216,217,215,218,217,217,216,215,214,214,216,214,213,214,216,214,214,216,214,215,214,215,214,212,215,213,214,212,214,113,1,1,4,6,7,7,10,9,9,10,9,9,223,227,227,225,227,225,226,226,224,226,227,225,226,225,224,225,226,226,224,224,227,227,227,225,227,225,226,226,227,229,227,230,229,227,228,230,227,229,230,227,227,229,229,231,229,229,229,230,231,230,232,233,234,232,235,235,235,235,234,234,234,232,230,233,232,231,231,232,232,232,231,231,230,230,233,231,232,233,233,234,231,234,231,231,234,234,234,233,234,233,234,233,232,234,233,235,232,231,233,232,232,232,232,232,230,230,231,231,232,232,232,232,233,232,233,232,232,233,234,233,234,236,237,237,237,238,238,236,237,238,238,239,237,237,237,236,235,235,238,238,237,239,238,241,242,239,242,241,240,242,240,241,241,240,239,239,240,240,239,239,240,240,239,239,239,239,239,240,240,236,237,240,240,239,239,239,241,240,239,238,237,237,239,240,240,240,239,240,241,240,241,240,241,240,241,242,240,240,241,241,241,243,241,241,241,239,240,239,242,244,245,242,242,244,243,241,240,241,239,240,239,237,237,238,238,239,239,240,238,238,240,240,241,241,241,244,243,243,243,243,245,242,244,244,242,244,243,243,243,242,242,242,243,242,241,243,241,243,244,243,242,241,242,242,241,241,242,242,240,243,242,240,241,242,241,241,243,242,245,230,220,238,242,242,243,240,242,243,245,233,229,241,245,241,235,241,244,242,242,242,241,243,243,242,242,241,242,241,242,242,242,242,240,239,240,239,240,240,239,239,238,241,241,240,241,241,241,234,235,240,239,239,238,239,239,238,240,240,249,211,221,242,203,219,206,186,221,240,235,247,236,237,197,212,240,247,238,148,130,124,102,41,114,240,240,246,224,208,230,218,214,246,253,253,234,176,167,98,76,59,54,68,64,89,81,61,110,165,180,136,90,47,30,126,239,249,251,251,252,252,253,253,249,204,95,79,140,129,95,75,82,79,68,91,174,194,153,126,147,139,94,198,247,236,251,252,252,252,253,253,246,160,79,69,33,139,225,220,195,148,113,69,47,53,91,46,48,39,39,81,22,150,251,251,217,221,249,245,247,245,244,240,252,226,194,240,247,242,245,242,250,252,217,197,90,16,132,101,32,23,21,57,57,38,29,57,79,54,60,46,33,39,71,92,46,51,20,106,245,245,250,250,244,237,237,244,240,241,241,244,243,215,221,240,240,244,239,242,238,218,225,240,233,208,221,243,226,182,166,199,220,211,218,191,151,106,126,152,150,144,94,73,84,189,240,177,139,83,69,170,252,252,250,249,247,242,244,240,231,227,237,245,185,148,98,104,131,125,167,209,247,175,57,20,8,33,147,201,218,217,212,215,213,213,212,210,211,212,212,212,213,214,213,211,212,212,213,214,214,212,215,214,214,217,212,214,214,213,214,214,213,213,214,214,214,214,213,214,213,213,214,213,216,216,216,214,216,216,217,217,224,222,192,186,208,220,220,222,227,232,245,247,250,201,145,107,63,18,24,138,221,223,227,225,221,222,219,217,218,215,217,219,220,218,220,219,217,220,220,220,217,216,218,217,217,217,220,217,217,217,217,218,217,219,218,216,217,216,216,214,215,216,214,215,214,216,217,214,215,216,213,212,213,214,214,211,213,112,1,1,4,6,7,6,10,8,9,10,10,10,227,231,226,227,229,229,229,226,230,226,228,228,227,228,227,227,226,227,227,226,227,227,228,227,226,229,228,226,228,227,230,230,229,229,229,229,231,230,230,231,230,229,230,230,233,231,231,233,231,233,233,234,235,235,234,236,236,232,235,234,232,232,232,234,235,234,235,232,232,232,233,234,232,234,235,235,235,234,234,233,234,235,234,235,234,232,232,234,233,232,235,232,232,234,234,235,231,232,234,234,236,232,231,232,232,232,232,232,233,233,235,233,234,235,234,234,234,234,234,235,236,237,238,236,238,241,239,238,236,238,241,237,237,237,237,237,236,238,236,238,238,240,241,240,240,239,242,240,243,243,242,242,241,241,241,242,240,242,242,242,242,241,241,240,239,239,240,240,239,240,240,241,241,240,239,239,240,239,238,238,238,237,237,238,237,240,239,239,240,241,241,241,239,239,242,242,241,239,241,242,241,240,239,237,237,238,239,240,240,243,244,243,242,241,242,241,239,239,239,237,238,238,239,238,239,240,239,239,237,240,239,239,242,240,244,242,242,242,242,243,241,241,242,243,244,243,243,244,244,243,244,242,243,243,244,242,241,244,243,244,243,242,241,241,240,241,241,240,241,240,241,242,241,242,240,241,242,243,242,224,225,241,241,242,241,241,243,243,239,227,235,244,243,238,236,241,241,241,244,242,241,243,242,241,240,241,241,241,240,240,241,240,240,240,240,239,239,239,240,240,240,238,239,239,240,239,241,236,230,237,239,239,240,238,239,239,241,242,246,203,225,210,153,205,218,223,252,249,231,232,232,242,191,214,241,249,242,152,136,141,122,46,123,244,246,251,236,213,225,216,223,241,251,238,108,74,118,134,108,51,50,65,73,161,240,243,252,252,252,252,183,114,67,77,193,240,249,247,212,199,171,145,143,128,76,74,111,69,52,55,44,49,46,46,51,55,51,53,45,45,45,50,86,89,105,143,147,165,203,155,146,75,52,40,73,230,252,252,252,252,251,236,158,133,110,39,52,47,44,60,37,179,252,252,214,230,250,244,247,242,243,240,252,214,198,246,244,244,247,243,252,252,224,195,75,6,131,83,23,39,17,34,55,55,43,58,63,36,55,49,29,26,61,87,47,43,26,141,246,246,250,249,245,234,237,244,240,242,240,243,247,220,214,237,241,244,239,241,239,221,223,235,238,211,214,238,232,190,163,185,217,211,217,212,198,169,115,61,39,16,27,81,82,183,230,162,128,79,126,219,252,252,251,247,243,242,246,239,229,229,234,234,175,152,125,129,135,137,147,128,196,117,46,29,5,54,164,207,227,220,214,214,212,215,211,213,212,211,212,212,211,213,212,212,214,212,213,213,216,217,214,217,216,214,216,214,215,215,214,216,218,218,217,217,217,217,214,213,215,214,213,216,217,214,217,221,219,219,220,222,227,211,183,193,215,217,226,232,239,246,252,232,171,124,78,28,4,83,190,231,247,225,224,225,222,222,217,217,217,219,221,219,220,220,220,220,216,219,220,219,218,220,217,217,220,218,217,217,217,217,218,219,216,218,215,218,217,214,217,219,217,216,215,214,214,216,215,214,212,213,214,214,214,212,215,212,212,112,2,1,3,8,9,7,9,9,10,10,9,10,227,229,229,229,230,229,227,229,230,230,230,230,230,229,229,229,229,229,229,230,229,229,228,227,228,229,231,230,230,232,229,231,232,232,232,231,230,232,234,230,232,233,231,232,232,232,233,235,235,234,235,237,237,237,238,236,236,237,236,235,234,235,234,235,236,235,238,237,235,234,232,235,233,233,236,232,234,234,231,232,232,233,235,233,234,234,233,235,234,235,234,233,234,231,233,233,232,234,233,234,232,235,234,231,232,234,235,234,235,237,235,236,236,234,237,235,235,236,237,237,237,237,237,239,238,239,237,239,240,236,238,238,237,238,237,237,238,237,238,238,239,239,241,241,242,241,243,243,242,243,242,243,243,242,242,243,242,241,242,243,243,242,240,241,241,241,242,240,243,242,241,244,242,241,241,239,240,239,237,238,238,239,237,237,238,238,240,240,239,241,241,241,243,241,242,241,240,240,240,235,234,235,234,237,237,237,240,240,241,241,240,241,241,242,240,239,238,237,236,238,237,239,242,241,242,243,240,240,238,237,237,237,241,241,240,242,241,241,240,240,241,239,241,242,241,243,242,242,242,242,243,243,243,243,242,244,243,244,245,242,241,241,242,240,240,240,239,241,239,240,240,240,241,240,240,240,240,244,239,220,229,242,241,244,241,241,242,243,235,227,240,244,242,234,237,243,241,241,241,242,241,241,241,239,240,241,239,239,240,239,238,240,240,240,239,239,240,240,238,238,238,240,239,238,240,237,241,237,231,237,239,241,238,240,240,239,241,244,244,198,217,208,198,240,237,224,234,208,194,230,234,243,186,213,245,251,245,156,141,148,128,51,134,244,247,251,240,224,234,229,225,234,160,83,47,37,85,131,122,64,27,0,46,208,251,251,250,250,244,216,203,172,143,142,76,57,67,42,14,33,53,17,16,37,29,24,74,53,25,21,15,21,21,29,31,28,27,26,22,19,19,30,22,31,33,21,37,36,37,42,47,43,41,41,31,157,236,237,252,252,250,196,149,154,129,62,66,74,70,86,61,148,243,226,214,237,247,248,245,244,245,245,252,200,208,248,243,247,245,243,252,252,205,156,55,7,134,70,21,64,39,33,32,62,60,46,42,25,51,47,30,30,56,93,51,46,16,84,243,245,250,250,241,235,238,243,242,241,243,243,246,229,208,228,238,239,239,239,240,222,218,233,237,214,208,232,236,198,166,178,215,214,216,219,217,201,145,94,78,41,7,42,71,200,227,127,87,81,189,251,251,251,249,246,249,249,244,226,231,236,253,236,167,162,148,149,143,143,131,47,90,79,36,33,16,177,248,228,231,216,217,215,212,213,213,214,212,213,214,213,212,212,214,212,214,213,213,217,217,215,216,217,218,218,216,216,215,217,215,214,216,216,218,217,218,218,215,214,215,216,215,216,219,217,217,219,221,220,222,224,223,198,179,207,218,225,238,244,249,248,196,139,99,56,5,26,151,227,246,246,237,228,225,223,221,217,216,217,220,220,220,218,217,217,220,219,219,218,217,219,220,218,217,217,218,218,217,217,217,217,217,218,220,218,215,217,217,216,216,216,215,215,215,215,214,212,213,215,213,211,212,211,213,212,215,212,212,112,2,1,2,6,8,7,8,8,9,10,10,10,227,229,228,229,228,228,229,226,229,230,232,231,229,230,229,230,231,230,229,229,230,229,229,229,231,230,231,233,234,232,232,234,234,236,233,234,233,232,232,232,234,234,236,235,236,235,234,236,235,237,236,236,236,235,237,239,237,237,236,237,238,237,237,235,236,236,236,236,237,237,236,236,237,235,234,235,233,232,233,233,233,233,234,235,234,236,236,236,233,230,235,234,232,234,232,232,232,234,234,234,234,232,232,232,234,232,232,233,234,232,234,234,232,234,233,235,235,236,236,237,237,236,237,237,236,237,236,238,236,237,237,236,237,237,237,237,237,237,238,240,240,241,241,240,242,243,242,241,242,242,243,244,243,245,243,244,243,243,244,244,244,244,244,243,242,243,245,244,245,245,244,245,243,242,243,241,239,239,236,237,239,237,240,237,236,238,237,238,239,239,239,239,240,240,239,241,240,239,236,231,229,231,234,235,239,240,241,240,239,240,238,239,240,238,239,237,239,238,238,239,240,241,241,242,243,240,239,239,237,237,236,236,238,237,239,240,241,240,239,240,240,239,240,240,241,240,240,241,241,242,242,243,244,243,245,244,244,245,244,241,242,242,241,240,240,241,240,240,240,240,241,240,238,240,240,239,240,244,231,216,232,241,240,241,241,241,241,241,229,232,243,244,239,232,240,242,240,242,240,239,239,239,238,240,241,239,239,240,237,238,239,239,239,239,239,237,237,237,237,237,237,239,239,240,240,237,240,238,228,234,240,238,239,240,237,239,237,244,237,207,241,220,219,250,209,178,214,221,221,239,237,240,175,216,246,252,246,165,145,139,124,57,144,243,248,251,239,223,242,245,220,133,69,51,51,63,91,174,192,143,72,26,12,92,192,174,139,114,78,53,55,101,134,130,80,12,8,27,15,19,73,45,16,20,13,30,73,57,22,13,10,20,14,20,29,19,16,17,18,19,18,17,20,23,22,19,24,34,30,28,34,33,31,25,31,39,38,34,48,134,61,66,86,137,117,81,185,200,150,115,89,83,130,182,204,245,247,245,246,244,244,250,249,190,220,247,244,247,244,242,253,253,172,146,50,2,141,61,35,110,56,39,27,36,65,53,41,20,47,55,33,26,51,90,50,50,18,65,228,243,250,250,239,233,239,243,243,242,239,241,247,238,209,221,237,237,240,236,238,225,214,229,241,220,206,228,237,207,174,171,205,214,214,216,186,122,89,142,189,123,28,15,32,160,213,143,84,129,227,249,249,249,245,245,247,247,238,226,232,234,253,216,160,161,149,152,143,155,126,44,132,130,88,51,54,219,249,247,227,212,220,214,214,212,210,212,213,215,211,212,213,212,212,212,212,212,214,215,214,215,216,217,214,214,216,215,214,214,214,216,214,217,217,217,218,217,218,219,217,217,217,216,218,218,220,221,218,218,221,224,215,185,189,214,228,241,249,249,222,173,122,79,37,7,91,205,241,243,248,233,229,223,223,219,216,215,218,220,220,218,218,219,217,217,218,220,218,217,217,218,217,217,218,219,217,218,220,218,217,217,217,217,216,219,217,215,217,217,217,215,214,214,216,216,215,215,212,212,213,213,215,212,214,214,214,213,214,113,1,1,4,6,7,7,9,7,9,10,9,10,226,229,226,228,227,226,226,227,230,229,232,230,229,231,231,231,230,232,232,230,229,229,229,230,230,231,229,230,233,233,234,235,236,236,236,237,237,234,233,235,234,234,235,236,238,238,237,237,234,237,238,237,237,235,237,237,236,235,237,237,236,240,238,238,239,235,238,237,236,239,238,239,238,239,238,235,235,235,235,236,236,237,236,235,236,235,236,236,235,236,236,234,234,234,235,234,232,233,235,235,231,232,232,234,235,234,235,233,233,235,231,232,234,232,236,237,235,236,238,239,237,235,236,236,236,237,236,238,237,237,239,237,237,239,238,237,240,239,240,241,241,243,243,244,243,242,244,244,244,243,244,244,244,243,243,245,245,244,245,245,244,245,243,246,244,244,244,245,245,244,244,244,244,243,244,241,239,239,238,239,239,239,239,240,241,239,239,238,237,240,239,239,239,239,239,236,236,232,232,231,230,235,234,236,239,238,238,239,238,239,238,237,239,238,240,240,239,239,239,243,243,244,244,241,241,240,237,235,235,235,237,236,237,238,237,240,239,240,239,238,240,238,240,240,241,240,239,240,242,242,243,244,243,244,244,245,244,244,245,244,242,244,242,240,241,239,241,240,239,240,239,240,239,240,238,239,243,241,223,219,239,241,239,239,238,240,243,236,226,237,244,242,236,233,241,241,240,240,239,241,240,241,240,240,240,240,240,240,238,237,237,237,237,239,239,237,237,238,239,239,239,237,238,239,236,238,240,236,229,232,237,238,238,238,237,239,238,247,233,207,244,206,184,206,202,214,250,245,245,248,238,237,178,223,247,252,243,145,119,110,96,46,148,243,250,250,237,227,245,252,190,99,61,55,37,63,141,240,235,187,166,92,58,44,27,47,17,11,42,18,38,39,20,93,128,98,59,25,15,25,72,47,26,19,17,31,68,65,22,14,8,16,17,17,24,17,13,21,11,17,18,18,18,21,19,16,22,20,22,17,18,27,17,24,22,25,32,24,40,34,30,39,56,98,76,91,187,234,170,97,81,63,87,163,219,248,250,248,242,243,243,252,236,184,230,245,243,245,243,243,253,253,166,132,37,6,136,48,44,109,47,44,27,24,44,57,51,24,46,55,36,28,55,94,53,50,19,51,219,242,249,249,236,235,239,241,243,242,241,242,243,245,213,212,236,237,242,238,239,232,214,226,237,226,205,222,239,217,179,164,199,216,207,215,179,113,43,19,116,161,117,98,69,114,187,139,101,188,251,251,249,247,246,249,248,239,229,233,241,248,253,195,156,154,141,148,137,159,120,54,186,188,120,89,6,93,195,208,226,214,214,214,211,216,215,214,215,214,214,215,215,213,212,212,213,214,214,217,217,217,217,219,217,215,214,217,217,217,217,217,217,216,218,219,219,218,218,220,218,219,219,218,221,220,219,217,218,218,223,224,203,186,204,230,246,247,247,190,143,103,51,12,36,156,229,240,251,240,232,225,223,222,218,219,219,217,216,220,219,218,219,218,220,218,217,217,218,220,220,220,219,218,220,220,218,218,218,218,218,217,219,216,218,218,216,217,215,215,217,215,214,214,216,214,215,215,213,214,214,215,212,210,214,214,213,213,215,113,1,1,3,7,7,7,10,8,10,10,10,10,227,230,229,229,229,226,228,227,229,231,230,230,231,230,230,231,230,232,232,231,234,232,230,232,232,231,232,231,232,232,234,232,234,237,234,237,237,237,238,237,237,236,237,237,238,239,237,237,234,236,237,236,238,238,239,239,237,238,238,238,237,237,237,237,238,239,238,240,240,238,239,239,240,239,237,236,238,237,238,237,236,237,236,238,236,235,235,236,236,236,237,238,237,235,237,237,234,236,236,236,237,235,237,235,235,235,234,235,235,236,236,234,235,235,234,234,235,238,235,237,238,236,237,237,236,237,236,236,237,237,239,239,238,237,239,239,239,241,241,241,241,241,241,242,243,242,242,242,243,242,242,242,243,243,245,245,244,245,245,246,246,246,245,245,245,244,245,244,245,246,244,244,244,241,240,237,237,237,238,241,240,238,238,237,239,240,239,239,238,239,236,237,236,235,232,231,232,232,231,230,232,232,234,235,235,236,237,238,237,237,237,238,239,240,240,239,240,240,242,243,243,242,241,241,240,237,234,235,234,236,236,236,237,238,239,240,240,239,240,239,240,239,239,240,241,241,242,241,240,241,241,242,242,243,245,245,245,244,244,244,243,243,240,240,238,239,238,239,240,239,240,239,238,239,239,238,242,240,220,222,239,241,240,240,239,240,241,231,224,241,243,238,233,235,241,241,240,240,240,240,240,239,241,239,239,239,240,239,238,239,237,237,237,237,237,237,238,238,238,237,239,239,237,239,238,238,238,240,230,226,237,238,238,239,235,240,238,248,226,206,223,168,192,232,228,246,252,240,227,237,239,240,185,229,247,252,231,119,95,89,71,17,126,242,248,250,235,228,245,253,194,101,57,6,2,12,90,188,161,154,177,132,54,14,11,43,36,29,49,24,37,39,17,15,46,134,127,80,48,29,78,49,17,15,14,21,55,73,24,14,14,13,21,22,26,19,16,15,16,15,19,17,15,17,15,20,24,23,18,19,24,20,19,20,23,25,26,21,18,24,19,48,67,95,80,45,53,63,84,81,87,22,66,193,230,250,247,245,244,243,243,252,223,185,238,239,244,244,242,244,253,249,116,117,44,15,144,39,49,98,37,40,25,29,35,35,66,45,46,59,67,104,134,121,57,55,20,44,214,243,250,250,235,236,238,241,240,240,242,241,241,248,221,207,230,234,241,236,238,235,218,224,234,231,206,216,237,223,191,166,188,212,209,217,221,198,155,50,37,120,149,155,136,94,99,96,149,228,252,252,250,246,251,248,244,232,228,240,245,234,233,171,152,130,111,134,133,155,106,73,184,158,113,75,11,3,71,184,222,224,217,213,217,215,215,214,214,214,213,215,216,215,217,214,216,216,214,217,217,220,219,217,219,219,219,217,222,220,217,219,218,221,218,220,220,218,219,220,220,219,220,222,221,218,218,220,219,220,227,222,198,199,229,246,252,227,160,118,72,24,4,36,162,229,249,249,232,232,225,224,220,216,220,222,220,220,221,220,220,220,220,220,222,221,220,220,220,220,220,219,220,220,219,220,219,219,218,218,220,218,217,220,219,218,219,217,217,217,215,215,217,216,215,215,214,215,215,216,216,214,216,214,214,212,213,212,214,113,2,1,2,6,8,7,8,8,10,10,10,9,229,231,227,229,230,227,228,229,228,229,232,229,231,231,231,233,231,231,231,232,232,233,233,232,230,233,231,233,232,230,231,231,236,235,235,237,237,237,236,237,237,237,237,238,239,240,239,238,240,238,240,239,236,237,239,240,239,238,242,240,240,239,237,240,240,239,241,241,239,240,239,239,239,237,238,239,237,236,239,239,239,241,239,240,240,239,237,237,238,237,237,236,237,237,238,237,236,237,237,235,235,236,237,237,234,235,236,233,234,235,234,236,236,236,236,235,236,236,237,235,236,237,239,238,238,237,235,234,237,236,235,237,237,239,240,239,240,238,240,240,241,241,241,242,241,243,243,242,242,242,242,243,243,244,244,244,245,245,245,245,245,245,245,245,247,246,245,246,245,245,244,243,245,242,239,236,237,239,240,241,239,238,238,239,241,240,240,241,237,236,236,233,234,233,233,232,234,233,234,234,232,230,229,232,232,232,235,239,239,238,239,238,241,240,238,240,239,240,241,241,239,239,239,237,239,237,235,237,236,237,236,236,239,236,239,239,239,240,237,239,240,240,241,239,241,240,242,243,243,243,241,243,245,244,244,245,245,244,244,244,242,242,241,240,241,239,239,238,241,239,239,240,237,237,237,240,242,234,216,226,241,240,241,241,241,244,237,224,232,241,242,234,231,239,241,241,241,240,239,239,239,239,240,239,240,240,237,239,238,237,237,236,236,237,238,237,237,237,236,237,237,237,236,237,237,237,237,240,232,227,235,238,238,239,237,240,237,249,218,206,225,206,245,250,232,217,226,200,213,241,241,241,191,234,245,252,222,111,101,94,77,8,100,239,249,250,238,227,245,252,207,84,28,19,41,87,75,48,28,51,136,163,119,38,23,71,38,41,54,22,51,35,16,26,11,22,77,131,110,104,111,47,18,10,16,11,46,76,24,11,15,14,20,17,21,16,16,16,14,16,14,13,17,18,16,20,24,20,17,16,19,21,15,18,20,20,28,15,22,18,31,63,69,97,65,51,47,22,42,74,93,21,56,198,240,250,251,244,241,240,245,252,204,193,244,236,245,243,241,240,253,232,95,110,36,27,145,34,63,91,32,38,17,32,29,25,51,59,71,98,153,174,169,154,77,52,17,34,204,243,250,250,234,235,239,242,241,240,238,240,238,244,232,204,226,237,239,240,236,241,227,228,240,237,211,211,235,227,199,171,178,214,210,222,231,238,221,114,93,147,150,152,127,75,19,57,196,247,249,249,247,247,250,245,232,226,238,244,246,253,210,153,151,117,95,123,131,151,97,104,213,141,88,65,4,49,163,204,222,222,217,217,212,217,215,212,212,214,216,215,214,216,215,216,217,217,218,219,220,222,220,220,219,219,221,221,221,219,219,221,219,220,220,220,221,218,219,220,222,222,222,223,223,220,221,221,221,222,229,219,199,224,249,245,184,132,87,32,5,23,98,176,240,242,236,233,228,225,223,218,217,217,220,220,220,222,222,221,217,220,220,220,221,218,219,220,220,221,219,220,220,219,220,220,220,219,218,219,219,217,218,220,220,217,217,220,219,217,215,218,217,216,215,215,218,216,216,217,217,214,214,214,214,216,216,214,212,111,2,1,2,6,8,7,9,9,9,10,9,10,228,231,230,229,229,227,228,229,228,229,229,227,232,232,232,232,231,234,231,232,230,231,230,229,232,231,230,231,233,231,233,235,236,237,237,239,236,237,237,238,237,236,237,237,239,239,240,240,240,241,239,239,240,239,239,240,239,239,240,239,239,241,239,240,241,241,240,240,240,239,241,239,237,239,239,238,239,239,237,236,238,237,238,240,240,239,239,239,237,240,238,238,239,237,237,239,237,237,236,235,237,233,237,235,234,235,232,234,235,234,235,235,236,234,238,237,236,238,236,238,237,237,237,237,238,237,235,234,236,236,237,237,237,238,241,240,239,241,239,239,240,242,241,240,242,243,240,243,243,242,244,242,243,243,242,242,242,244,244,245,246,245,246,246,246,247,243,244,244,243,242,243,244,241,240,240,241,241,242,241,240,239,238,240,241,241,240,239,237,237,234,235,234,235,234,235,233,235,235,233,232,229,229,229,232,234,235,236,238,240,239,238,239,239,238,239,239,238,236,237,237,239,237,236,236,235,236,236,236,235,237,237,237,237,237,239,238,238,239,239,239,239,239,240,239,240,242,243,244,243,244,243,244,244,244,245,246,246,245,244,244,243,241,241,240,240,239,239,239,237,239,237,237,237,239,240,242,226,213,232,241,239,238,237,240,241,231,224,235,242,240,231,234,240,240,241,240,239,239,238,239,239,238,237,239,237,238,238,236,237,237,238,237,236,236,235,237,237,237,237,237,237,237,237,237,237,237,240,236,229,235,237,237,239,239,240,240,248,220,227,244,213,232,220,184,195,235,226,235,247,242,242,200,236,248,252,220,106,88,85,73,11,108,240,249,250,235,228,245,253,199,69,57,78,107,93,54,35,26,29,71,155,181,113,64,75,46,55,65,48,60,36,26,32,16,22,13,39,107,164,156,66,30,12,11,11,40,71,31,16,13,14,22,17,17,15,15,14,15,13,18,19,12,13,17,26,22,18,17,16,18,14,16,13,18,18,19,17,13,19,49,83,75,70,54,53,39,22,51,68,78,33,72,193,238,250,247,241,240,236,245,251,190,201,245,234,247,239,242,243,251,218,77,116,44,33,143,28,70,84,21,36,21,27,30,25,32,54,76,100,133,134,124,104,71,54,13,33,207,242,249,250,229,234,239,241,241,238,238,236,237,242,236,212,223,244,252,252,252,252,251,249,246,244,218,205,231,227,202,171,171,202,215,223,236,243,217,144,144,171,156,148,130,78,54,133,228,247,249,249,248,246,248,240,229,231,245,244,243,234,181,147,151,134,124,128,132,151,133,156,207,107,78,49,9,116,238,237,228,218,217,218,212,215,212,211,214,214,214,218,217,216,219,220,222,222,224,222,220,223,222,220,222,218,222,222,222,222,220,222,217,218,219,220,220,220,223,227,230,236,239,233,228,222,221,220,219,227,231,214,217,237,209,151,114,61,9,14,117,175,196,243,248,237,232,227,221,221,217,217,218,219,223,220,220,221,217,217,219,219,217,217,219,217,219,219,217,217,218,219,219,218,218,220,216,218,220,217,217,216,218,219,217,218,220,218,218,219,218,215,217,220,218,215,214,214,215,215,214,214,212,213,213,213,215,212,217,114,1,1,3,7,7,7,10,9,10,10,9,9,225,227,229,229,229,227,226,229,227,229,232,230,233,231,230,233,232,232,234,232,234,232,232,234,234,234,231,232,234,232,233,235,235,235,235,236,238,236,237,240,238,239,237,240,239,240,242,237,240,239,240,240,239,240,240,240,241,241,241,240,240,241,241,241,241,239,240,240,241,240,239,240,241,240,240,241,240,239,239,237,239,238,238,239,239,239,238,239,239,239,239,237,239,238,236,235,235,236,236,237,237,235,236,234,234,234,234,235,235,234,235,236,236,237,237,236,235,235,236,236,238,236,236,237,237,236,234,234,235,236,237,237,236,237,239,239,239,240,240,240,242,241,241,242,241,241,241,243,242,241,242,242,241,239,237,236,241,241,244,246,244,243,241,243,242,241,240,240,240,241,242,241,242,242,243,244,244,242,243,242,242,240,239,238,239,240,239,238,235,235,236,237,236,237,238,234,236,235,232,232,230,229,229,229,232,235,237,239,239,239,239,239,239,242,239,240,239,239,237,237,236,235,237,233,234,233,231,235,235,234,236,234,237,235,238,238,238,239,240,239,239,240,241,242,242,240,241,241,242,243,245,245,243,243,245,245,245,246,246,245,242,242,242,242,241,241,241,239,241,239,238,239,238,237,238,242,240,218,216,237,240,238,238,238,240,238,222,226,241,241,237,232,239,241,240,241,239,240,240,241,242,239,240,239,237,239,238,239,238,240,240,237,237,235,237,236,237,237,238,237,236,238,236,238,239,240,238,240,237,228,234,239,237,237,239,241,243,250,215,232,229,169,202,213,215,236,252,241,252,244,239,238,201,242,244,252,210,87,63,53,59,6,107,239,247,250,234,229,245,253,200,73,62,66,64,59,61,55,44,50,39,99,188,178,122,71,27,55,68,54,61,43,32,34,24,35,22,31,20,63,154,97,68,42,23,13,34,76,30,12,12,14,16,17,18,14,17,17,15,19,16,16,15,17,32,33,27,20,12,17,19,14,17,16,15,20,21,15,22,21,68,101,77,62,43,54,33,39,69,66,61,21,77,207,246,248,248,239,240,235,247,241,180,212,244,236,247,237,240,243,251,206,62,105,50,46,137,22,76,73,21,36,8,22,22,28,35,30,53,101,110,77,59,53,48,57,30,79,222,244,250,250,228,234,239,239,244,239,236,236,236,239,248,229,238,249,252,252,252,252,252,240,251,249,223,205,225,229,208,180,164,196,214,224,207,178,193,183,183,183,156,137,109,99,128,227,252,252,250,247,251,247,243,231,232,244,249,247,253,226,159,148,154,151,150,141,141,155,173,188,129,61,59,35,12,150,241,231,234,217,218,216,214,214,211,212,210,216,214,221,228,230,243,249,248,240,234,232,230,227,225,223,220,220,222,221,222,221,223,223,218,219,219,221,222,225,234,239,248,248,251,249,228,226,224,223,230,236,240,214,197,167,124,83,28,6,80,198,217,215,235,240,238,230,227,223,218,219,218,220,219,218,218,219,220,219,220,220,218,217,217,219,218,217,220,221,218,217,218,218,217,217,218,218,220,219,217,218,218,218,221,221,218,218,219,215,216,219,217,217,217,215,215,214,216,215,214,214,213,215,214,214,214,214,216,214,216,113,1,1,4,7,7,7,10,8,9,10,9,9,225,229,226,225,229,226,226,227,228,227,229,230,230,229,231,230,230,233,232,231,232,235,233,234,235,235,236,234,233,236,237,235,236,236,238,240,237,237,237,238,238,237,239,239,240,240,240,240,238,239,240,239,239,238,237,239,239,240,241,239,241,241,239,240,239,238,238,238,240,239,239,239,238,240,238,239,241,239,239,239,240,240,239,238,237,238,239,237,234,237,237,237,239,236,236,236,235,236,236,235,237,236,237,235,235,235,234,234,234,236,234,235,236,234,236,233,234,235,232,235,233,235,237,236,237,235,234,237,237,237,237,237,237,239,237,237,239,238,240,241,242,242,242,241,242,242,241,242,240,239,238,235,234,234,235,234,236,239,241,242,238,235,234,232,230,231,233,235,239,240,241,242,243,244,244,245,244,243,244,242,241,241,239,239,236,237,238,238,237,236,236,235,235,237,235,235,235,236,236,235,231,231,230,231,232,233,238,239,241,241,242,241,242,242,241,241,239,240,239,235,234,233,232,232,233,229,231,231,232,233,234,233,232,235,235,236,236,235,237,236,236,237,238,238,239,238,238,239,242,242,243,244,245,245,244,243,244,244,244,241,242,241,241,244,242,243,241,241,241,242,239,237,237,237,238,242,235,216,222,240,240,239,239,237,241,234,220,230,240,239,232,229,238,240,241,240,239,239,239,239,238,239,238,237,239,238,239,239,240,241,239,239,239,237,236,236,238,237,237,237,239,239,238,239,238,239,239,239,239,227,229,236,237,240,240,239,245,243,209,216,199,190,233,236,239,246,252,223,221,239,238,233,200,239,243,252,212,100,81,81,72,9,106,238,245,250,232,229,244,252,231,114,46,5,17,53,66,54,40,48,44,54,115,171,180,108,32,30,57,53,62,41,33,33,33,39,30,35,30,19,63,119,157,112,72,33,29,74,35,14,14,13,20,18,17,17,17,16,13,18,15,12,19,26,39,37,28,19,21,22,21,27,16,22,27,27,27,29,30,40,63,83,86,67,52,57,42,58,92,87,54,12,107,232,250,248,242,236,239,233,249,231,174,222,240,232,244,236,238,244,251,193,54,90,51,57,125,22,84,65,10,32,10,25,19,24,30,31,26,62,85,56,45,33,48,43,41,117,230,246,249,249,237,239,247,252,251,247,247,242,239,241,253,237,212,206,234,240,176,164,144,157,236,250,232,205,227,238,218,191,168,187,216,195,123,75,98,136,137,127,107,81,68,126,198,234,250,250,252,249,250,246,237,228,237,247,248,234,234,191,151,148,157,150,148,139,150,181,155,125,69,33,51,15,34,208,247,233,238,220,220,216,214,214,216,215,217,215,218,231,236,247,246,246,251,251,252,251,249,243,231,228,225,223,223,219,219,221,220,222,221,222,222,222,223,232,241,243,235,222,227,246,244,226,227,232,243,246,232,175,136,98,53,11,26,126,229,242,222,203,229,237,232,226,221,219,214,220,221,221,220,218,221,217,219,221,218,220,219,220,219,218,220,219,220,219,220,220,218,218,220,219,218,219,217,218,217,218,220,217,218,219,218,217,215,217,217,215,214,215,217,214,215,215,214,215,215,216,215,214,214,214,216,214,215,213,213,113,2,1,2,6,8,7,10,9,9,10,9,10,230,229,229,229,229,229,227,229,227,226,230,227,229,229,229,234,231,232,231,227,232,231,232,233,230,234,236,234,237,236,236,239,238,238,240,239,240,239,239,239,238,239,237,239,240,240,240,238,239,237,237,237,237,239,240,239,239,240,239,240,242,241,238,239,240,240,239,240,240,238,240,240,239,239,239,241,239,239,237,239,241,240,240,239,239,238,238,238,237,239,238,237,237,238,237,238,239,238,237,237,236,234,235,234,236,236,236,237,236,235,234,235,236,236,234,235,234,234,234,233,235,234,237,237,238,237,237,238,239,239,240,240,241,239,239,240,239,241,240,240,240,240,241,240,242,241,240,242,240,237,237,236,237,238,238,238,237,235,235,234,230,230,228,230,232,234,236,239,241,244,245,244,245,244,245,245,244,245,242,241,240,240,241,237,236,235,235,239,239,239,237,236,235,237,236,236,237,236,234,234,233,232,232,233,234,236,239,241,242,244,245,246,243,242,243,242,242,241,238,237,233,233,234,231,232,230,232,235,234,236,236,234,234,235,236,235,235,235,236,235,236,236,236,236,237,238,237,240,241,242,243,243,244,245,245,246,246,245,245,242,241,241,243,245,246,245,243,243,241,241,240,239,239,239,239,242,229,214,231,242,240,240,236,240,239,224,223,237,240,236,228,234,240,239,241,239,238,239,239,239,239,239,240,238,237,239,237,240,241,242,242,240,242,240,239,239,239,238,240,239,241,241,238,240,239,237,239,240,242,229,229,238,240,241,240,241,245,240,203,223,215,216,252,245,237,248,236,193,226,238,241,225,192,241,241,252,227,146,142,134,119,42,139,243,248,251,234,229,245,251,241,128,27,2,12,57,62,45,48,45,28,35,39,91,184,152,53,24,41,50,55,36,17,23,23,33,17,35,15,60,189,225,242,214,193,126,110,118,31,8,11,12,14,14,17,19,17,14,16,22,20,16,34,37,33,33,37,37,32,35,35,39,39,34,39,40,41,39,44,53,75,79,69,65,67,64,56,78,92,88,45,59,174,245,251,244,243,236,239,235,252,213,177,234,234,237,241,235,237,248,251,175,40,59,65,69,108,29,87,56,12,32,10,24,20,16,24,34,28,38,73,87,70,48,76,51,36,138,230,246,250,251,246,250,252,252,253,253,251,244,240,244,253,208,121,43,30,79,28,53,89,74,196,241,249,248,249,250,231,204,173,185,216,208,112,17,17,40,49,37,44,27,29,122,229,245,247,247,252,249,249,240,233,239,247,252,252,252,235,161,149,156,159,162,142,139,150,156,126,61,25,24,33,2,91,239,252,252,238,225,229,221,218,213,216,218,216,220,225,238,228,179,150,152,198,237,250,250,252,252,241,226,226,225,222,220,222,222,221,221,223,222,221,222,225,235,228,168,123,86,112,204,228,232,240,248,250,238,166,114,77,24,5,83,205,237,250,217,183,218,231,231,223,218,220,220,220,220,219,220,221,221,222,220,220,221,220,219,219,221,221,220,220,219,220,220,220,221,220,221,218,220,221,218,220,220,218,220,220,220,219,220,220,219,218,218,218,214,217,220,218,217,217,218,216,216,215,216,215,215,214,214,214,216,217,213,214,112,2,1,3,7,8,6,9,9,9,10,9,10,229,230,228,227,231,229,230,229,230,229,229,230,229,232,233,232,232,235,234,232,233,232,231,232,232,231,231,232,232,235,236,234,235,236,237,239,240,238,239,240,239,239,239,239,240,236,236,237,234,233,234,237,236,235,237,237,238,238,238,238,239,239,238,237,239,238,239,240,237,239,238,239,239,240,237,236,237,237,238,236,239,237,237,239,240,239,236,237,237,239,236,236,239,238,238,237,238,236,236,236,234,233,232,233,236,236,236,234,235,235,235,235,234,232,234,234,232,234,232,234,234,235,236,235,236,237,236,239,238,238,239,237,239,240,239,239,241,239,240,241,241,241,241,240,241,240,242,242,241,240,239,240,240,238,237,236,235,232,229,230,229,226,228,232,234,237,240,241,243,245,247,247,247,246,245,245,244,241,240,239,237,237,238,236,235,235,236,238,236,235,237,236,234,235,233,233,234,230,232,232,232,233,233,234,235,238,240,240,242,244,243,244,245,245,242,243,242,242,238,238,237,234,233,232,231,230,232,232,234,235,232,234,231,231,232,232,234,233,232,234,233,231,233,236,235,232,235,237,239,242,243,244,244,244,245,244,245,244,243,242,242,242,244,244,244,244,243,242,240,241,239,238,240,239,238,241,222,214,233,239,239,238,238,240,234,217,223,238,239,231,225,235,238,237,239,237,237,238,237,238,238,239,239,239,240,239,239,240,241,241,242,243,242,240,241,239,241,241,239,240,238,237,237,238,238,239,239,239,241,235,232,239,242,241,243,242,249,237,215,241,223,232,242,222,211,203,230,215,241,245,237,214,189,240,239,252,231,160,147,140,122,53,171,244,247,250,227,229,245,249,236,129,40,1,11,49,66,57,41,30,22,30,42,35,121,180,121,53,44,44,53,28,19,20,18,19,24,30,35,190,252,252,250,179,130,162,178,176,63,16,7,5,14,13,17,14,17,14,17,22,21,33,43,37,24,45,70,60,71,72,71,65,45,46,42,49,50,47,54,65,77,79,72,70,70,60,61,74,84,64,33,57,182,246,250,246,238,234,236,234,250,197,182,236,232,240,239,239,239,250,249,173,74,46,73,74,69,38,93,45,15,32,8,21,16,21,18,29,28,86,171,185,145,78,89,84,50,124,217,242,251,251,250,239,217,235,247,248,242,229,244,249,250,195,82,23,3,11,10,72,96,24,137,246,251,251,253,253,249,216,186,179,214,227,151,59,41,54,46,54,34,17,24,52,158,240,250,250,250,247,245,238,238,239,245,250,234,229,187,149,153,153,160,158,138,141,146,139,85,27,29,15,31,8,92,226,246,246,249,229,228,216,221,215,214,214,216,218,230,237,166,89,81,48,18,109,119,152,199,229,230,225,226,226,225,224,223,222,220,224,221,220,220,222,223,231,186,93,36,17,11,69,184,232,251,251,208,148,101,56,4,27,153,232,250,250,220,183,202,225,229,220,219,220,217,220,221,220,218,219,221,220,217,217,219,217,219,221,219,218,217,217,221,220,222,221,218,220,217,218,220,218,218,220,218,218,219,217,217,217,220,219,216,220,219,216,217,219,219,218,218,214,218,215,214,218,216,214,214,216,213,213,217,214,214,212,215,114,1,1,4,7,7,7,10,9,10,11,10,10,226,230,228,230,232,229,227,230,230,231,233,232,232,231,232,232,233,234,232,233,232,231,233,233,234,232,232,232,235,234,234,235,233,235,236,237,238,238,239,237,238,239,239,239,237,237,237,236,237,236,235,235,237,238,237,238,237,239,238,240,240,239,241,239,237,238,238,239,240,238,239,239,238,237,237,238,237,239,237,239,239,237,239,237,239,237,237,237,237,236,235,237,235,237,236,236,237,236,237,237,236,236,235,235,236,232,235,234,234,234,234,234,232,234,234,234,236,235,234,235,234,235,235,235,235,237,240,236,237,237,237,237,237,239,240,241,240,241,240,240,239,241,242,241,243,241,241,241,243,243,242,240,241,237,235,235,231,229,231,230,229,231,231,234,236,237,239,240,243,246,247,247,245,246,246,243,240,238,239,236,235,236,234,234,235,235,237,237,236,235,236,235,233,235,232,232,233,232,235,236,233,234,236,235,237,240,242,244,243,245,244,244,245,244,244,243,244,244,244,243,239,236,234,231,230,229,230,233,233,232,232,230,230,230,231,231,231,232,231,232,231,230,233,231,233,232,235,239,240,244,245,245,244,244,244,244,243,244,243,241,244,244,245,246,244,244,243,243,241,241,242,241,241,239,240,240,220,223,240,240,239,238,237,240,226,215,231,237,235,226,228,236,237,238,239,237,236,237,239,239,240,240,241,240,239,240,241,242,241,244,243,243,243,242,242,242,241,240,240,238,239,240,239,240,239,237,239,239,244,237,233,241,243,240,242,242,249,237,217,244,207,190,220,203,188,221,243,229,251,236,237,204,185,241,236,252,223,147,133,124,105,49,169,244,248,251,228,228,244,249,238,188,119,35,15,31,47,44,26,18,20,21,36,45,68,130,179,137,64,49,49,27,20,17,14,24,31,150,250,250,250,250,224,105,19,2,110,203,128,70,29,9,13,10,14,15,11,20,15,20,24,57,125,84,26,30,59,79,85,89,80,59,39,33,31,35,42,42,55,62,75,86,69,62,62,46,61,77,72,50,9,66,211,246,250,240,234,234,233,235,246,184,191,241,238,251,252,252,252,252,250,200,117,41,86,80,34,47,93,36,17,24,15,44,33,27,17,23,38,115,184,160,118,49,60,100,96,133,203,240,252,252,211,135,74,33,55,176,229,238,252,252,250,146,73,29,2,30,16,8,12,12,132,187,155,133,175,234,250,247,188,172,207,238,191,94,78,66,57,63,39,28,29,1,95,235,250,250,249,245,247,242,246,246,247,252,253,202,150,142,155,153,162,158,136,141,145,123,48,9,16,22,20,27,28,14,128,222,250,250,224,222,221,221,223,218,227,234,247,250,171,93,104,57,7,7,8,10,27,147,219,225,235,223,228,228,233,237,239,235,228,225,224,224,222,227,183,89,45,29,8,91,211,238,250,177,123,76,27,5,97,212,245,246,250,226,181,187,222,227,220,220,223,222,221,221,221,220,219,219,220,219,219,218,217,219,220,220,220,220,218,221,219,217,219,218,219,220,218,221,218,219,223,218,221,219,217,218,217,217,219,219,217,219,218,218,218,219,220,217,218,217,217,215,215,217,215,215,214,216,214,213,216,217,216,212,216,113,2,1,4,7,7,8,10,8,9,11,10,10,229,228,229,229,229,226,227,229,229,230,232,232,232,233,231,231,231,230,230,229,231,231,233,235,232,232,233,235,235,234,236,235,234,237,237,238,238,237,239,237,236,237,235,238,237,234,237,236,236,237,234,237,237,237,238,237,239,237,238,237,237,238,239,238,238,237,236,238,237,237,237,239,238,238,237,236,236,236,237,236,239,237,236,237,237,236,236,237,235,234,236,237,235,235,236,234,236,237,237,236,237,235,233,235,233,232,232,233,231,232,234,232,233,233,235,233,232,234,232,234,235,234,235,235,236,234,235,234,234,234,236,234,236,238,237,240,241,239,241,240,239,239,239,239,242,241,242,244,242,240,238,237,234,232,232,232,233,233,233,232,233,234,235,236,233,234,237,240,241,244,244,241,240,239,237,235,236,235,233,233,232,234,234,233,234,235,237,237,235,236,234,233,233,232,233,233,234,233,236,235,234,234,235,237,238,239,241,242,243,243,244,244,244,246,244,244,245,245,243,243,239,235,232,232,230,230,233,232,234,231,231,231,231,232,232,230,231,231,230,229,229,231,229,231,234,235,237,238,241,244,245,246,245,244,244,244,244,244,244,244,243,244,245,244,246,244,244,242,241,241,241,240,239,241,244,237,222,231,243,240,240,236,240,238,220,223,237,239,232,224,234,239,236,239,240,238,239,242,240,238,241,242,243,243,244,241,241,243,241,243,243,242,244,244,243,242,243,242,242,241,242,240,240,242,242,240,240,240,241,239,235,240,244,242,244,242,248,226,214,214,179,211,231,222,225,244,252,201,225,237,235,202,185,238,235,252,212,151,139,128,102,39,170,243,246,251,227,232,243,244,244,253,227,118,35,1,3,25,22,16,20,17,32,48,60,50,121,184,130,87,39,23,23,10,19,18,91,235,248,232,198,121,103,45,13,21,8,94,150,85,104,49,32,11,13,15,14,14,13,23,22,157,249,137,29,11,67,111,83,61,48,36,22,21,19,24,29,37,55,63,85,88,71,53,35,34,50,55,46,29,103,173,209,238,232,237,236,236,233,243,244,186,218,250,252,252,252,252,252,252,248,199,133,32,84,77,12,52,86,29,25,10,97,157,62,25,12,23,65,135,168,113,77,39,45,131,130,137,211,239,251,249,164,87,26,5,18,122,222,249,253,253,165,87,31,7,9,7,18,128,145,89,60,12,6,14,17,81,193,235,207,165,193,241,214,129,101,64,34,39,37,30,107,68,119,234,250,251,250,247,249,243,246,245,248,234,234,176,147,147,153,155,167,155,139,138,134,137,99,96,41,40,33,28,27,27,18,95,212,234,246,219,223,222,225,230,239,249,249,249,170,84,12,60,198,176,62,18,21,136,242,237,232,230,237,245,250,250,249,249,234,228,229,228,236,249,226,167,127,66,69,194,246,208,164,109,64,16,28,160,236,243,252,249,231,186,174,212,224,224,223,223,222,220,224,221,219,221,219,220,221,221,220,219,221,222,221,219,220,221,223,222,220,220,217,218,221,222,222,220,221,219,218,220,220,221,218,218,220,218,217,218,219,219,218,217,218,219,218,220,219,215,219,219,217,217,217,216,216,217,215,215,217,216,216,216,217,112,2,1,3,8,8,6,10,9,10,10,10,10,228,232,229,229,229,227,231,231,231,231,231,233,233,233,234,232,232,233,232,233,232,232,233,231,232,231,234,233,233,234,235,238,237,239,239,239,238,237,237,234,235,234,234,235,236,235,236,234,235,236,237,238,237,236,237,240,239,235,235,237,237,235,235,235,237,238,237,238,237,236,236,236,236,236,236,235,237,238,236,237,235,235,237,236,236,234,237,236,237,236,235,235,233,235,237,236,235,234,236,235,233,236,232,234,234,233,231,231,232,231,232,231,231,233,233,229,232,232,230,232,231,232,234,234,233,233,234,232,232,232,235,236,237,240,239,240,240,238,239,237,239,243,241,242,241,239,240,239,239,236,235,233,231,232,231,233,233,236,240,236,236,235,235,234,234,236,237,240,237,239,236,235,232,229,231,230,231,232,232,231,231,233,230,233,233,232,235,234,236,234,234,234,232,233,233,236,235,234,235,236,236,237,236,238,240,239,238,239,239,239,242,243,245,245,245,245,244,244,241,237,232,229,229,231,231,230,232,233,232,233,232,230,230,229,232,232,230,230,229,232,232,230,233,232,237,237,236,241,243,244,244,244,245,245,244,245,244,244,245,245,245,242,242,244,243,243,242,242,242,242,244,242,244,244,246,236,224,236,241,239,240,239,240,231,217,229,241,237,227,226,237,239,239,239,240,241,244,245,245,245,245,245,246,245,245,245,241,242,243,244,242,242,241,242,242,243,242,242,243,242,244,244,243,241,240,240,239,240,240,240,237,241,245,241,243,245,247,221,207,222,211,244,252,235,235,252,215,182,230,233,237,196,191,243,236,253,206,157,150,139,109,43,177,243,247,251,228,236,245,244,235,252,251,174,136,54,1,7,15,14,16,15,27,48,67,38,30,132,187,139,50,12,10,12,24,51,40,65,64,39,90,51,37,45,15,21,12,63,62,71,160,148,92,54,25,19,19,17,7,23,20,125,210,89,33,15,56,102,66,48,34,15,20,17,17,29,18,30,63,81,96,73,49,53,29,31,27,51,92,130,172,134,174,226,232,243,238,246,252,252,252,229,251,251,252,224,161,143,171,241,244,194,127,15,82,91,12,60,67,27,29,5,161,193,53,26,12,35,97,174,195,150,117,91,75,97,107,141,236,248,251,251,179,77,29,5,23,194,251,251,248,168,78,21,1,15,2,58,211,249,235,97,7,5,8,13,21,1,54,188,204,178,188,237,233,169,144,81,30,35,11,66,214,165,151,240,243,251,250,248,249,240,243,248,251,251,214,158,150,153,153,165,167,148,138,135,140,169,181,216,185,76,14,13,35,29,30,7,74,211,248,243,223,219,234,237,249,240,182,134,87,43,42,155,241,241,191,59,32,154,241,241,240,238,242,240,245,235,229,244,249,237,240,239,249,249,250,223,142,74,15,110,167,131,109,48,14,74,190,241,250,250,242,235,196,171,196,222,226,221,223,223,222,221,219,220,220,219,219,218,219,220,222,221,220,219,218,218,219,221,220,221,221,219,221,218,220,220,220,220,222,222,220,218,219,218,218,220,221,219,218,219,219,220,218,220,219,219,219,218,220,217,218,219,218,217,217,221,214,214,214,215,217,215,216,213,215,113,2,1,2,7,8,7,10,9,10,10,10,10,227,229,230,229,229,228,230,232,230,230,232,230,234,234,230,232,232,231,234,233,234,232,231,232,229,230,232,230,233,235,234,235,233,237,236,237,237,232,234,233,233,235,234,236,235,232,235,234,234,235,233,235,236,235,239,237,236,237,236,236,237,234,235,236,236,237,235,236,235,236,235,234,235,235,235,236,234,236,237,235,235,235,234,232,236,235,233,235,234,232,234,234,234,234,234,235,234,234,233,232,234,233,232,235,235,233,233,231,232,231,230,230,230,232,232,232,232,231,230,231,231,232,233,231,230,230,232,231,233,234,232,235,237,240,237,237,236,237,238,236,239,237,239,239,236,234,234,234,234,235,232,232,234,232,231,234,234,235,236,237,239,237,237,238,237,237,239,239,237,235,233,232,231,231,231,231,233,231,233,234,231,232,232,230,230,232,233,232,230,232,233,232,232,230,232,233,233,234,235,236,238,240,241,240,239,238,238,240,240,240,241,242,243,243,245,242,243,242,236,232,229,227,227,227,228,228,229,229,231,233,232,231,228,230,232,233,234,231,233,235,234,233,232,235,238,238,240,242,245,245,245,244,244,244,245,246,245,246,246,245,244,244,244,242,244,241,243,243,243,243,241,244,244,245,246,231,227,241,241,241,240,239,240,224,220,235,240,234,225,231,238,239,241,241,245,247,246,246,245,245,245,244,244,244,245,245,243,243,243,244,242,241,240,242,244,242,243,242,242,244,245,244,244,241,241,241,241,242,241,243,238,241,244,242,242,245,246,220,230,233,222,249,239,212,188,212,222,211,251,238,231,196,197,242,239,252,200,155,123,125,105,44,185,243,249,251,226,236,243,241,223,248,233,194,232,164,145,69,3,3,12,14,22,53,72,42,23,73,162,195,93,24,8,20,46,46,35,29,27,38,96,82,44,30,12,25,19,65,72,32,36,113,185,135,84,51,30,19,14,27,29,31,47,50,38,15,17,55,56,39,19,10,17,15,21,24,15,35,50,71,100,66,41,19,17,44,88,191,196,169,123,133,222,235,243,251,251,251,251,251,252,227,252,252,248,138,101,99,45,141,159,133,99,10,94,98,19,65,60,24,35,8,49,110,60,29,14,48,165,204,179,123,112,96,40,44,57,106,248,248,250,234,123,49,16,1,104,240,252,252,175,68,24,2,33,70,101,220,253,253,135,23,28,78,102,56,11,8,19,129,198,184,198,231,228,169,145,63,24,13,33,189,234,223,148,217,248,247,248,244,244,242,245,234,234,227,186,156,156,152,156,164,164,146,135,133,156,212,201,250,232,107,88,136,97,44,24,23,18,97,233,237,236,224,235,242,196,123,54,10,1,18,11,25,162,226,220,125,17,58,191,232,249,247,211,145,124,83,110,199,241,238,237,214,214,242,229,185,156,107,61,46,39,39,42,10,82,194,248,248,246,239,238,210,171,180,216,227,225,223,221,223,223,221,220,217,218,218,221,225,228,231,231,231,224,221,220,219,218,219,220,220,218,217,219,221,216,217,221,220,221,217,219,221,219,220,220,220,217,220,218,218,217,218,220,217,217,220,218,218,219,220,217,217,216,217,216,213,214,214,213,215,216,218,216,214,214,114,2,1,4,6,7,8,10,8,9,11,10,10,225,229,228,229,229,226,228,229,232,231,233,233,230,232,232,231,233,232,232,235,235,235,230,229,229,227,229,230,232,234,235,234,234,236,233,235,234,232,235,233,233,235,236,238,232,231,234,232,235,234,235,234,234,233,234,236,235,237,239,239,236,235,239,236,236,237,234,234,235,233,235,235,234,234,234,231,232,232,232,232,233,234,234,234,232,233,235,231,232,236,232,233,234,234,233,232,233,231,231,231,232,231,231,236,233,236,234,232,231,227,230,230,228,230,233,231,232,232,232,233,232,231,233,234,232,232,233,234,233,234,236,236,236,236,235,235,239,234,233,233,233,235,231,232,233,231,233,231,233,235,237,236,236,235,232,235,236,236,236,237,239,238,238,238,238,239,237,238,236,236,231,230,233,232,235,233,235,235,236,235,231,235,232,233,232,233,235,232,232,231,232,232,231,231,233,231,232,237,239,239,241,242,241,240,241,241,240,241,241,241,242,241,242,242,241,241,240,237,232,228,227,227,225,228,229,227,228,231,231,233,234,229,232,231,233,236,231,234,233,234,234,230,236,236,237,241,240,243,245,244,245,244,244,242,242,245,246,246,246,245,245,246,245,244,242,245,244,245,245,244,244,243,246,247,241,230,233,244,242,241,242,242,239,225,232,244,242,236,230,239,243,241,245,245,248,249,248,247,247,246,246,247,244,245,244,244,245,243,244,242,241,241,240,242,242,244,245,244,244,245,245,244,245,244,243,243,242,244,245,245,242,237,242,243,240,246,241,215,225,224,186,204,209,181,192,240,240,230,248,235,232,193,201,241,241,252,191,145,112,116,96,39,185,244,248,250,226,236,244,242,225,237,225,209,252,252,245,174,71,12,1,5,4,21,53,36,21,9,16,109,123,56,21,26,36,34,25,28,32,45,94,83,42,29,19,29,34,67,79,40,30,27,64,136,165,128,76,41,28,32,33,30,29,30,36,20,17,39,41,33,15,15,18,11,20,27,21,42,40,35,63,69,112,146,174,179,171,230,191,130,120,169,249,249,252,252,250,250,210,160,105,68,130,194,146,53,122,104,25,21,11,23,49,13,74,103,42,74,50,22,32,3,75,116,57,32,17,78,184,193,123,63,43,129,141,74,24,55,216,236,183,99,38,8,13,5,42,191,194,148,80,12,11,98,239,251,252,252,240,125,34,111,246,248,244,188,95,15,15,125,188,203,203,235,191,104,63,18,8,24,97,205,251,243,125,185,250,245,249,245,249,249,250,253,236,201,160,152,158,151,160,167,161,143,136,133,170,235,177,148,110,103,232,248,208,109,35,23,12,25,159,233,249,236,247,201,120,59,2,3,9,17,39,17,37,154,205,144,53,14,94,219,249,249,205,100,49,19,9,75,179,210,220,137,102,130,111,109,137,138,113,92,39,22,27,35,154,238,249,248,239,238,223,179,167,209,226,225,224,222,223,221,220,221,220,224,228,233,243,247,249,249,249,246,233,226,223,224,219,221,221,222,221,217,222,219,221,221,223,223,219,221,222,219,219,221,221,220,218,220,220,220,220,221,220,219,218,218,219,218,219,216,216,215,217,216,215,216,214,217,216,214,214,217,216,213,218,113,2,1,4,7,7,8,10,8,10,10,9,10,229,230,229,229,230,227,229,230,230,229,233,232,231,232,230,234,232,233,232,231,233,231,232,229,226,225,227,227,230,230,231,235,236,237,234,235,233,232,234,234,234,235,235,236,232,231,232,232,232,232,232,231,232,233,235,234,236,239,237,236,240,235,237,237,236,238,235,237,236,235,234,232,232,230,232,232,230,231,231,231,231,231,234,232,232,231,232,234,233,232,234,232,233,235,234,234,233,231,232,233,232,232,231,233,236,235,233,230,231,229,230,233,230,231,231,228,229,231,232,234,235,235,235,234,234,232,232,232,234,235,235,235,235,235,232,232,233,230,232,232,233,230,231,232,228,229,231,228,231,232,232,235,235,231,234,235,233,237,236,237,239,237,239,240,237,234,234,234,234,233,232,232,231,231,232,232,233,234,235,235,236,236,235,234,234,234,233,231,230,231,229,231,232,231,233,235,236,236,238,236,239,239,239,241,240,240,241,242,240,240,240,240,240,240,240,237,235,230,229,226,226,225,226,227,227,231,231,230,231,232,231,230,230,232,232,235,235,232,232,232,232,232,231,234,236,235,239,241,242,244,245,244,244,243,243,243,244,245,245,246,245,246,245,244,246,245,245,244,245,245,245,245,245,247,240,227,237,244,240,241,241,245,236,229,242,245,244,237,238,244,246,247,247,247,247,247,247,246,245,245,246,246,247,247,245,245,244,244,244,243,242,240,241,242,244,245,244,244,245,247,244,243,245,244,244,244,242,243,242,244,241,235,239,241,239,246,233,206,212,187,177,220,221,222,231,252,226,189,237,237,233,196,202,241,242,252,187,159,122,118,94,38,186,243,249,250,225,236,244,240,230,228,221,230,247,252,251,218,147,142,109,32,4,19,20,5,6,10,9,29,93,108,33,8,21,17,23,17,27,35,65,82,39,31,20,42,51,68,83,48,38,26,49,37,61,153,164,113,66,47,38,34,30,23,22,30,33,31,30,29,24,15,18,15,21,30,27,49,19,45,123,118,188,249,252,222,200,226,176,122,107,193,250,250,251,251,158,97,34,2,5,9,24,13,34,21,31,65,17,29,31,19,61,33,78,125,63,84,47,15,35,5,170,200,56,29,39,88,122,112,94,36,29,160,136,55,35,9,26,55,56,27,32,119,127,60,27,4,23,46,12,44,175,250,253,253,252,252,136,37,112,241,252,252,251,185,96,18,14,162,223,225,237,192,118,56,26,17,6,114,185,194,233,162,58,121,234,245,248,248,250,252,234,234,211,171,142,141,145,151,162,169,157,141,136,141,181,225,168,46,9,62,214,239,240,162,73,22,17,8,75,213,247,247,248,183,90,43,4,19,145,210,145,76,11,21,98,118,68,19,27,149,241,242,222,123,78,21,2,20,122,203,231,173,64,26,4,19,45,54,78,105,111,115,117,135,194,238,246,242,237,233,195,165,196,226,227,223,222,220,222,223,219,222,230,238,249,249,251,251,249,249,233,239,241,224,221,221,223,222,220,219,222,220,220,220,218,220,222,221,221,220,220,220,222,221,218,219,220,221,219,218,219,219,220,218,219,218,216,220,219,218,217,216,217,217,216,216,217,215,217,217,215,215,217,215,214,113,3,1,2,7,9,7,10,9,10,10,10,10,226,227,228,227,227,228,230,228,229,228,229,229,227,229,229,229,232,231,232,231,227,231,228,230,229,229,226,225,228,230,234,231,232,234,234,233,233,231,234,233,236,235,232,231,229,229,229,229,229,229,230,229,233,232,231,233,231,235,235,235,235,235,235,233,232,232,232,234,234,231,232,230,231,230,229,232,230,231,232,230,232,230,231,232,232,234,230,232,232,233,233,233,234,235,235,234,234,231,232,233,235,232,231,233,233,236,232,230,231,231,231,231,231,230,229,230,228,230,230,232,233,234,236,234,234,232,232,234,233,236,235,236,235,233,234,231,232,231,234,235,234,233,231,234,235,230,233,232,234,235,234,232,231,234,234,233,234,233,234,236,237,237,238,235,232,232,229,229,230,230,229,229,230,228,230,232,233,233,235,236,235,236,233,234,232,231,230,229,229,229,229,231,229,229,229,229,232,233,234,234,235,236,237,239,239,238,239,240,238,237,240,238,239,240,238,238,235,231,232,228,225,228,227,230,231,232,232,230,230,231,231,229,231,229,230,230,229,232,230,230,231,230,233,230,232,235,237,242,243,245,245,245,246,246,245,246,246,246,247,247,247,247,244,245,246,246,245,246,246,245,246,246,248,246,235,230,241,244,242,241,242,244,232,235,247,246,241,239,244,248,247,247,248,247,247,247,246,245,246,246,246,246,246,247,244,244,245,245,245,243,244,244,243,244,244,245,245,245,246,246,245,244,245,245,245,245,244,242,241,241,241,236,237,241,239,244,231,201,208,207,221,252,242,224,218,223,198,203,241,237,227,192,207,241,245,250,188,162,127,129,95,39,194,243,250,250,225,236,246,242,234,216,222,237,217,226,237,228,233,252,215,220,245,207,199,210,205,186,169,145,154,184,154,95,64,40,11,9,27,20,55,77,39,33,34,67,57,70,90,44,39,35,46,40,34,40,93,167,159,122,78,47,23,19,33,28,36,31,24,31,23,13,17,16,19,26,14,92,148,204,207,163,245,252,198,168,234,223,139,86,116,216,251,251,253,150,50,7,1,17,21,26,26,28,35,16,135,198,121,56,10,10,66,49,72,152,109,93,32,18,17,51,252,229,83,32,38,96,110,98,66,52,36,62,75,46,31,16,27,22,8,88,213,249,243,179,81,22,3,41,33,137,252,252,252,252,223,130,19,59,232,244,245,201,84,37,17,2,93,247,251,251,185,108,59,26,42,12,48,225,243,177,147,76,8,51,217,244,248,248,245,247,235,225,189,149,131,136,139,150,166,165,152,141,140,141,190,219,186,134,21,7,151,230,243,191,83,28,11,16,27,125,231,236,242,185,90,40,15,137,236,238,237,180,83,24,15,93,117,57,6,42,187,228,236,145,44,18,7,43,168,217,245,202,101,51,27,30,25,19,54,129,175,196,191,150,99,149,234,236,242,214,170,187,222,231,223,224,224,220,221,222,220,231,239,246,247,247,244,193,151,133,135,190,228,227,231,230,228,225,223,222,221,221,221,219,221,223,223,222,222,222,223,220,221,222,220,221,223,221,221,220,219,217,218,220,221,220,219,220,219,220,220,219,219,218,218,218,217,216,217,216,216,218,219,217,217,113,2,1,3,7,9,8,10,9,10,10,10,10,228,229,229,228,229,223,227,229,230,227,229,228,229,230,230,232,231,232,230,231,231,231,232,232,235,232,230,230,230,230,231,230,230,230,231,232,231,231,229,227,227,229,229,227,225,226,226,227,226,227,227,229,229,227,231,232,229,232,233,233,231,229,233,231,230,230,226,229,229,229,229,229,229,231,230,230,226,230,230,229,230,229,229,229,231,230,230,230,231,232,233,235,234,233,232,236,234,231,233,230,230,230,229,230,231,229,231,231,230,229,229,231,228,229,230,228,229,229,230,230,233,233,233,235,235,233,235,235,234,235,234,233,234,235,234,234,235,235,237,237,235,235,235,236,235,236,236,234,237,239,236,235,232,232,233,231,229,229,230,232,235,234,231,232,230,227,228,227,226,226,226,225,228,227,229,231,233,234,234,232,230,229,231,229,226,226,226,229,229,229,227,229,229,232,232,232,232,232,232,231,234,231,234,235,235,239,237,237,235,236,237,237,237,237,240,237,237,235,235,235,233,232,229,228,230,231,231,229,229,229,231,229,226,227,227,230,231,228,231,233,233,232,234,234,232,232,237,241,242,245,248,245,245,245,244,245,246,247,246,245,245,246,245,245,246,246,245,246,246,245,244,245,246,243,232,231,243,245,245,244,245,237,227,240,247,243,239,240,246,245,247,247,246,247,245,246,245,244,246,246,246,245,246,246,246,246,245,244,242,242,243,245,244,244,245,246,246,246,246,244,245,245,244,244,244,244,244,244,242,241,244,234,234,238,238,246,224,215,228,217,230,244,212,175,195,238,227,230,250,235,221,189,208,241,243,245,187,164,120,114,96,52,198,243,249,249,225,237,245,245,234,208,221,245,225,232,240,233,243,252,249,252,252,252,252,252,253,253,252,230,252,252,252,252,251,251,205,128,81,46,71,76,32,51,66,89,67,83,100,44,38,43,48,44,34,38,34,44,114,155,152,112,29,7,31,41,39,31,39,33,26,34,31,16,15,76,202,246,250,235,173,198,250,230,103,104,219,243,164,73,128,231,252,252,170,62,11,0,22,27,29,29,34,35,50,15,92,241,241,141,41,35,78,57,84,144,119,101,27,39,36,101,251,204,72,32,27,57,59,61,56,59,55,64,61,46,38,21,35,19,33,135,250,250,248,248,187,97,68,53,61,204,245,245,236,142,74,33,9,132,248,248,244,194,91,38,59,154,240,246,244,168,95,36,23,37,36,8,112,243,246,174,91,31,15,15,165,235,245,248,237,239,225,206,170,147,134,142,150,156,164,166,148,139,138,131,140,119,136,78,4,64,182,222,249,210,107,37,11,20,21,8,114,214,249,243,124,32,5,7,66,181,247,247,160,64,20,83,183,144,74,20,45,162,155,103,50,14,6,90,227,235,249,219,146,106,65,60,55,33,62,123,141,127,125,64,17,34,191,233,239,189,171,215,227,227,223,223,223,222,221,221,223,232,233,192,160,150,135,110,73,100,71,110,222,234,250,250,242,238,230,228,224,220,221,222,223,222,222,221,218,221,220,220,221,220,221,220,220,220,220,220,221,221,220,218,220,220,217,217,218,218,220,218,218,218,217,219,218,217,217,214,217,218,218,217,216,115,2,1,4,7,8,7,10,9,10,11,10,10,228,230,231,230,226,228,231,227,230,230,229,232,231,232,232,232,235,232,232,233,234,236,232,235,234,237,234,234,233,230,231,229,232,232,232,231,229,227,228,225,226,226,226,227,224,225,224,225,226,227,229,227,228,229,229,230,230,232,233,232,232,231,229,229,229,230,231,230,229,229,230,230,231,230,227,229,229,229,230,228,230,229,230,229,228,230,229,232,234,234,236,235,235,235,234,237,235,234,234,230,232,228,229,231,229,229,230,231,230,232,230,231,231,228,230,229,229,231,232,234,232,233,237,236,236,235,235,238,237,238,237,236,234,235,237,238,237,236,239,239,239,241,236,236,235,234,239,236,236,234,235,235,234,235,230,231,232,228,230,230,230,231,230,228,229,228,227,227,227,227,227,226,227,227,226,226,226,229,230,229,227,227,227,227,226,227,227,228,228,227,228,228,228,228,230,228,230,232,232,232,230,232,233,234,236,237,237,237,237,237,238,237,240,239,239,239,240,239,241,239,236,234,230,230,229,230,231,230,229,229,228,228,229,229,231,233,232,234,232,235,236,235,238,237,235,235,238,243,244,247,246,246,247,246,247,246,246,247,245,244,246,246,245,245,247,246,246,247,246,245,244,245,245,240,229,235,244,243,244,244,244,235,232,244,244,241,237,243,247,247,247,247,247,247,247,247,246,246,246,246,246,246,246,247,246,246,247,244,243,244,244,244,244,245,244,244,246,246,246,246,246,245,244,245,245,244,244,244,245,243,243,236,232,237,240,242,221,210,222,194,185,212,204,205,231,251,233,220,241,235,218,196,213,240,242,244,187,147,107,109,83,47,200,243,249,250,224,239,245,246,228,197,227,251,234,237,228,223,229,240,227,247,253,239,240,250,249,251,248,212,251,251,252,252,253,253,249,205,108,27,38,107,152,159,141,101,50,74,107,53,34,39,52,45,34,41,36,39,32,27,145,244,203,202,229,190,99,4,69,173,190,199,181,205,251,251,253,253,200,145,163,215,248,200,56,77,185,217,169,84,153,240,251,214,90,14,2,14,28,32,32,35,34,33,39,32,22,166,251,237,128,66,80,71,81,140,136,84,24,103,88,77,182,102,53,45,14,31,29,49,47,78,99,67,54,48,55,55,48,23,23,168,251,251,252,252,241,122,41,34,28,92,104,63,36,15,29,32,14,134,247,247,247,247,228,251,253,253,252,211,108,61,7,23,33,38,16,45,200,245,249,196,133,99,44,2,122,231,245,248,234,232,217,189,155,138,137,145,158,156,166,163,142,141,135,129,99,27,7,18,80,210,246,228,250,228,149,69,11,13,19,29,16,50,202,217,198,108,16,13,35,169,241,244,228,113,55,13,95,151,85,60,42,33,36,50,14,52,185,245,249,239,249,249,222,173,113,70,36,37,31,34,53,43,100,110,21,26,141,216,206,171,196,227,232,231,235,237,233,232,228,226,227,238,202,139,92,44,39,31,39,86,70,121,233,238,252,252,252,252,246,236,229,226,223,223,222,221,223,222,220,220,222,222,222,223,221,219,222,223,223,220,220,221,222,220,220,221,222,220,219,222,219,220,219,220,219,216,217,217,217,217,218,217,218,216,218,114,2,1,4,7,8,8,10,9,10,11,10,10,228,230,228,227,230,228,229,229,227,227,231,227,230,231,230,231,229,232,234,232,230,231,233,235,232,234,233,231,232,230,230,229,229,230,231,230,228,228,226,224,225,224,223,222,222,224,221,224,225,225,227,229,227,225,229,229,229,229,227,228,229,228,226,227,230,227,227,229,229,228,229,230,228,227,225,227,229,229,228,229,227,227,228,228,228,229,232,231,232,232,232,235,232,235,233,230,231,230,230,229,229,230,229,230,230,230,230,229,231,231,230,230,228,230,230,229,230,231,233,235,235,236,235,234,234,233,237,238,238,236,236,236,233,232,233,236,234,234,236,236,236,235,232,229,228,230,231,230,229,229,229,230,230,229,229,228,226,223,227,228,229,231,229,229,226,227,227,225,226,225,224,224,223,224,224,223,224,223,224,225,226,229,225,224,224,227,228,225,227,226,226,226,224,224,225,229,229,228,229,228,230,229,232,233,232,233,234,233,234,236,235,237,236,236,239,238,239,238,236,236,232,232,228,227,229,229,232,230,229,227,227,226,227,229,229,230,231,231,234,234,234,236,237,236,235,236,240,242,244,246,245,245,247,248,246,246,246,246,245,245,244,244,245,245,245,246,245,246,246,244,245,245,244,235,229,240,244,244,244,244,242,231,239,246,243,238,239,245,247,247,247,247,246,248,246,246,246,245,245,244,245,247,246,246,245,245,245,244,244,244,245,246,244,244,243,242,244,245,246,245,244,244,244,244,245,245,246,244,243,242,243,237,231,235,240,242,215,205,200,185,211,232,226,226,242,240,188,205,242,234,218,197,214,242,241,240,191,161,120,102,81,44,194,243,250,250,223,242,241,248,225,192,231,251,240,230,232,237,206,212,200,224,245,142,165,230,221,252,246,191,247,250,251,250,250,251,236,186,75,2,13,120,203,169,148,100,46,59,101,61,30,41,51,47,42,44,39,30,44,10,90,241,252,252,248,245,165,37,130,242,252,252,252,252,252,242,249,222,133,157,161,239,246,146,106,87,169,220,149,96,181,244,251,174,46,6,8,17,29,37,38,39,44,46,37,36,15,116,249,249,174,83,65,41,72,148,135,49,36,148,92,65,68,36,70,38,19,28,41,54,38,89,117,69,61,53,50,60,64,15,43,209,250,250,252,202,133,80,34,17,21,32,29,38,41,45,33,37,18,92,238,239,248,248,253,253,252,249,139,43,4,1,24,32,42,25,38,197,248,248,247,245,178,153,165,86,141,234,248,252,234,225,202,174,153,139,134,142,155,155,159,155,136,137,138,157,176,141,208,228,229,249,251,247,251,251,209,123,53,21,17,20,27,27,22,116,215,232,237,229,241,249,250,250,240,173,90,27,7,17,36,37,25,35,27,37,199,242,250,250,251,251,248,248,224,163,108,63,34,29,24,24,11,46,137,226,148,43,57,125,146,188,224,237,240,245,249,249,248,246,229,226,237,243,210,131,76,36,15,24,7,25,34,95,168,166,198,227,243,243,251,251,230,226,227,222,223,222,220,220,220,223,220,220,221,220,218,220,222,220,219,221,221,221,220,221,220,217,219,221,220,219,218,220,218,218,221,220,217,216,216,215,215,216,218,217,216,114,3,1,3,7,9,8,10,10,10,11,10,10,227,230,230,229,227,227,227,227,229,229,229,229,227,229,229,226,229,229,232,230,230,232,229,230,231,232,231,230,229,227,228,227,226,229,230,230,231,228,228,226,225,222,222,222,223,225,225,227,226,226,227,226,224,224,226,229,229,229,229,227,227,228,227,228,228,226,226,227,226,227,226,225,226,226,225,225,227,226,226,227,227,227,226,226,227,229,230,231,233,232,232,231,229,231,230,230,229,227,228,229,233,229,230,232,229,229,230,231,229,227,227,228,228,227,229,229,230,232,234,236,234,236,237,234,236,237,237,238,236,235,233,234,233,233,234,232,233,235,236,233,230,229,226,227,227,225,230,227,229,230,231,232,229,232,231,226,225,221,225,228,229,229,226,224,228,226,224,224,224,224,224,222,222,224,223,224,224,224,225,224,229,228,226,225,225,224,225,225,226,225,224,225,226,225,227,225,225,227,226,227,225,229,232,230,231,231,231,233,234,233,237,236,237,238,239,240,238,235,235,233,231,230,228,229,228,233,232,229,229,228,225,226,226,226,228,226,229,230,231,232,232,235,237,240,241,242,242,242,244,246,246,246,249,246,247,247,247,247,246,248,246,246,247,245,247,248,246,247,245,245,245,247,245,233,232,244,246,246,247,245,237,234,244,248,243,238,242,244,246,248,247,247,247,247,247,246,246,246,246,245,244,245,246,245,245,246,247,244,245,245,244,246,245,243,245,245,245,246,246,245,245,244,245,245,245,245,244,243,241,241,242,238,231,233,243,240,214,206,215,214,243,252,221,193,207,231,211,224,247,237,213,204,221,244,239,242,201,166,138,121,85,48,198,243,249,249,220,241,241,252,219,184,236,248,244,230,198,228,200,148,130,188,240,168,199,243,242,252,248,205,248,249,237,222,192,190,168,148,123,73,78,160,207,141,137,108,53,53,92,65,31,42,55,44,42,45,43,35,42,16,80,221,179,199,253,232,182,51,96,240,252,252,252,252,251,190,208,191,165,183,194,247,193,151,158,175,204,206,160,139,215,247,248,147,30,9,6,24,29,22,129,207,202,179,105,53,7,97,247,247,182,95,20,15,57,105,95,32,24,79,63,72,79,42,55,34,16,47,49,37,34,33,48,57,61,66,34,41,28,29,195,249,251,190,88,33,5,24,29,23,24,33,38,39,42,36,39,35,38,14,93,201,239,241,238,212,136,66,22,3,19,43,41,49,46,74,207,246,251,251,251,251,196,199,252,155,151,242,252,252,242,216,187,160,145,141,137,143,157,149,158,153,135,141,141,185,245,246,251,251,252,252,252,252,253,253,246,210,117,50,15,12,23,23,30,8,68,215,245,245,248,248,251,251,246,174,110,37,10,18,17,34,27,27,25,118,232,234,247,247,250,250,250,207,138,98,47,27,18,14,21,25,24,14,146,226,240,202,96,89,153,214,248,245,245,245,246,246,238,241,225,229,244,242,192,129,74,27,18,12,75,107,59,42,26,8,15,18,89,183,231,238,249,231,228,226,228,223,223,222,221,223,222,221,222,223,223,220,221,220,221,222,221,222,222,219,221,221,220,220,220,221,219,220,220,218,219,219,220,217,217,220,218,218,219,218,218,113,3,1,3,7,9,8,10,9,10,11,10,11,224,226,227,225,226,227,227,229,229,228,230,227,230,229,225,227,226,227,230,231,230,230,230,229,228,230,229,228,226,222,220,222,224,227,227,226,225,223,224,223,225,222,223,224,222,225,224,224,224,223,224,224,224,223,226,224,224,225,226,225,224,225,223,225,226,221,225,223,222,224,223,222,223,225,225,226,226,224,225,225,226,226,226,227,225,229,228,230,231,229,230,230,230,229,229,227,227,227,226,227,229,230,230,230,227,227,227,229,227,225,227,224,225,227,227,227,227,231,231,230,232,234,234,235,235,234,236,232,234,234,233,234,233,234,234,233,231,232,234,232,231,231,229,231,230,229,229,229,230,230,231,232,232,230,229,227,226,225,225,224,226,226,224,224,220,220,222,221,223,221,222,222,222,222,222,221,221,220,224,224,222,224,222,224,225,226,225,223,224,223,224,225,222,224,223,223,225,225,227,226,227,226,227,226,227,230,231,229,230,232,233,234,234,236,237,236,236,236,232,232,230,229,229,230,230,229,232,229,228,226,224,225,225,227,226,226,226,227,230,228,230,232,235,239,241,242,243,244,243,245,245,246,246,247,247,245,245,244,245,245,244,245,246,246,245,246,245,245,244,244,247,247,242,233,239,245,244,244,245,245,235,238,246,246,240,238,245,246,247,246,246,247,245,247,246,247,247,245,246,245,245,245,244,244,244,245,245,244,245,244,246,245,246,246,244,242,245,245,245,246,245,245,244,244,244,245,243,241,243,242,241,238,229,230,244,235,214,219,223,218,237,215,182,191,230,249,229,243,250,235,212,207,219,244,237,239,202,167,138,115,86,57,203,244,247,248,220,239,241,252,208,184,241,244,246,213,178,202,177,158,148,203,252,199,220,246,252,252,249,203,224,198,186,194,146,171,166,200,213,143,154,177,203,140,162,117,63,68,89,73,30,46,54,41,38,46,42,36,41,14,76,190,139,154,208,170,183,122,95,190,243,247,249,245,205,196,251,210,189,199,194,224,183,176,203,190,213,200,156,167,230,248,240,120,24,6,11,26,39,150,251,251,251,251,147,53,8,86,247,232,162,98,21,10,42,61,74,49,55,87,57,71,66,40,35,18,43,49,33,35,37,29,28,43,57,51,43,16,72,225,253,253,133,44,6,7,32,25,27,25,34,35,36,44,37,43,42,45,45,48,37,15,68,101,91,60,38,33,48,68,74,83,81,101,103,131,190,213,169,154,163,146,113,95,128,93,76,172,234,234,234,196,165,151,146,140,135,142,151,151,162,148,136,142,144,163,166,141,226,234,200,188,225,237,246,246,250,240,149,60,18,25,30,25,27,35,16,26,166,222,251,251,252,252,212,130,68,22,14,15,22,30,29,31,33,28,139,198,228,235,251,251,246,159,93,51,25,24,20,46,77,59,44,19,81,163,235,215,179,178,206,235,248,247,217,150,145,134,145,223,226,235,248,212,149,97,64,28,5,45,93,89,67,51,39,35,39,35,35,9,82,208,243,243,225,220,226,226,223,222,220,222,223,222,221,223,222,221,222,221,223,222,219,221,222,222,221,221,219,218,218,219,219,217,216,218,217,217,220,219,218,216,219,220,220,216,217,115,2,1,5,8,8,8,10,10,11,11,12,10,224,228,225,224,226,226,227,225,228,227,228,229,228,227,229,229,229,230,231,231,230,231,231,231,231,229,228,230,229,229,225,223,224,225,224,221,222,222,222,223,224,221,224,223,222,221,222,222,220,222,224,224,220,222,224,222,220,221,222,223,223,224,223,222,222,224,223,224,226,224,224,224,225,225,223,225,228,225,225,224,225,227,227,226,228,229,229,229,229,230,230,230,230,231,229,228,228,228,229,230,230,229,229,231,229,229,229,226,229,227,227,228,225,226,227,228,228,227,230,231,231,233,233,233,235,234,233,232,230,232,234,236,235,236,234,232,234,234,235,233,233,235,235,237,234,232,232,227,229,232,230,232,230,230,229,227,226,226,227,224,224,223,224,223,222,222,222,222,223,223,222,222,224,221,220,221,218,220,219,218,222,222,223,224,226,224,224,225,222,224,223,222,224,221,222,224,223,227,229,229,228,229,229,226,227,230,229,229,232,230,233,232,232,235,234,237,239,236,234,232,233,233,232,230,229,232,231,232,230,230,230,231,231,227,229,227,227,226,229,229,227,230,231,236,236,240,243,243,246,246,245,245,245,247,248,246,245,244,244,245,244,246,247,245,247,246,245,246,246,247,248,249,241,235,244,246,244,245,248,240,236,243,247,244,239,240,246,246,246,246,244,247,247,247,246,247,246,246,247,245,245,245,244,244,245,244,245,244,245,247,247,246,246,246,245,244,245,245,245,245,244,244,244,243,242,241,243,242,241,240,240,241,230,227,243,231,211,214,211,181,200,210,198,224,252,252,219,218,245,233,208,212,223,245,231,244,204,163,139,113,84,50,200,244,248,250,222,244,242,252,206,194,249,244,249,238,194,211,211,195,178,218,252,220,234,247,252,252,208,149,145,150,180,198,211,248,229,218,188,155,158,162,189,128,174,124,81,86,86,79,30,49,54,43,37,39,44,36,42,12,121,244,170,164,201,170,171,127,104,150,225,248,250,240,194,218,252,210,205,160,175,244,143,170,212,176,217,168,139,184,229,250,237,120,21,5,10,22,124,242,253,253,237,153,67,21,5,84,246,226,154,86,15,14,70,91,66,59,81,91,76,59,44,39,32,33,44,38,32,33,34,32,35,41,44,55,35,117,243,247,242,103,15,1,19,31,29,34,37,44,45,53,57,62,69,72,78,81,85,75,80,53,26,32,41,50,42,56,64,60,67,69,69,66,63,60,48,27,12,14,15,27,36,48,48,39,13,100,237,243,224,174,145,145,138,141,137,137,145,148,155,143,134,141,144,140,69,10,6,8,12,14,11,19,53,92,133,147,128,81,47,51,51,53,50,46,41,43,16,41,146,198,201,160,96,46,27,28,20,16,24,30,27,32,33,35,33,29,18,73,199,217,243,179,83,38,21,12,89,214,211,132,57,37,39,15,24,45,95,218,244,235,249,222,141,83,55,14,38,153,217,239,243,171,95,70,31,49,105,89,84,57,47,54,39,38,34,30,35,38,21,77,211,225,231,221,223,226,225,225,223,223,221,224,223,222,224,222,223,223,224,222,220,221,225,224,221,222,221,222,220,221,221,220,221,220,220,217,220,222,217,217,220,220,220,217,220,116,3,1,5,9,9,9,12,10,11,12,13,12,224,225,227,224,226,222,222,226,226,223,227,227,225,226,227,229,227,228,231,229,229,232,229,229,229,230,231,229,231,230,228,227,223,223,222,221,222,220,220,221,223,222,222,221,221,222,222,222,222,222,220,218,221,219,220,221,220,220,222,225,221,220,220,219,222,218,222,223,219,223,223,223,225,224,223,224,225,223,223,225,226,225,226,228,226,228,229,229,229,231,230,229,229,229,232,230,229,229,229,227,229,230,228,227,229,231,227,226,226,226,227,224,227,227,226,229,226,229,229,227,231,230,234,235,233,235,232,230,231,230,234,235,233,233,232,234,231,232,235,234,235,235,237,239,235,232,230,229,230,229,227,226,227,227,229,227,226,225,224,226,226,225,223,223,221,220,221,220,222,224,223,221,222,222,220,222,222,220,220,219,223,223,223,225,224,224,225,222,225,224,222,223,221,221,222,223,222,224,222,223,225,224,226,227,227,227,227,229,231,230,232,233,230,234,235,234,236,235,234,236,234,232,230,231,232,230,232,232,232,234,234,232,230,230,227,225,228,229,228,226,226,226,227,229,232,237,239,241,241,242,242,241,242,243,245,245,244,244,245,246,246,245,246,245,244,245,246,246,245,247,248,246,238,236,246,245,245,247,245,237,236,246,247,242,237,242,245,245,247,245,244,244,245,246,246,247,246,246,246,246,245,244,244,244,245,245,244,244,244,245,246,246,247,245,246,245,245,245,245,244,244,244,243,243,240,241,240,242,240,238,237,240,232,224,241,224,204,197,192,197,239,226,208,229,244,223,185,220,246,230,207,213,226,245,231,245,199,151,124,99,73,55,205,244,249,247,222,244,243,252,203,208,251,241,250,244,208,237,232,212,187,227,252,227,224,193,200,209,162,128,148,184,236,251,251,252,241,198,163,160,133,135,180,111,192,132,88,81,78,84,25,53,56,46,33,43,44,38,34,23,158,243,206,222,247,192,199,160,61,94,184,233,242,203,175,244,249,211,162,130,222,203,91,174,188,160,205,139,127,186,233,249,237,127,26,2,10,19,152,244,250,214,64,3,1,10,6,133,251,224,168,86,22,26,32,66,64,52,61,61,55,51,39,33,43,38,36,37,40,39,35,33,34,28,39,55,47,126,196,198,77,9,6,38,42,50,63,73,94,105,121,133,132,130,128,109,95,78,69,69,59,55,56,43,47,60,58,58,58,63,65,69,69,70,69,76,75,66,59,61,66,66,71,81,87,69,44,102,229,226,187,152,137,141,138,142,142,141,149,146,153,141,134,145,149,141,71,17,15,30,40,42,39,34,40,39,39,43,42,42,38,35,39,52,57,55,60,54,55,42,36,27,15,39,47,55,43,44,27,24,34,29,32,30,26,31,33,29,30,33,27,125,222,195,155,47,32,26,42,126,231,194,128,49,34,29,27,12,43,169,230,236,242,184,120,72,49,16,28,170,241,241,215,115,79,29,44,145,162,139,77,35,45,38,31,32,33,43,37,35,27,12,127,217,226,232,224,225,225,224,224,225,222,221,224,223,223,222,223,223,223,224,223,222,223,223,224,222,221,223,223,223,223,224,222,223,221,223,224,219,220,220,219,221,221,219,218,115,4,1,4,8,10,9,10,10,11,12,11,11,222,227,225,224,227,223,225,223,225,226,225,226,226,226,226,227,226,225,227,226,228,230,231,227,228,229,229,231,229,229,228,227,228,226,225,223,222,221,221,218,220,220,220,222,220,222,224,223,223,219,218,219,218,220,222,219,220,220,220,223,220,221,222,220,221,221,221,218,219,219,220,222,221,223,221,224,224,222,225,224,225,227,227,227,229,228,226,230,229,230,230,229,229,229,229,229,230,228,227,227,229,227,227,229,229,229,229,227,227,228,227,227,226,225,224,224,224,227,227,227,228,228,229,230,231,230,231,231,229,230,231,232,231,230,233,232,232,233,232,234,235,234,232,234,233,231,232,229,227,227,224,225,223,222,225,226,227,226,228,226,226,226,226,224,221,222,221,220,224,224,224,222,223,222,220,223,221,222,221,219,221,221,221,221,222,222,222,223,222,220,219,221,223,220,220,222,221,221,221,224,222,223,226,225,227,228,226,226,227,227,229,229,230,232,232,236,235,236,237,235,234,237,237,236,235,237,237,236,236,236,234,235,234,230,230,230,231,229,229,225,227,229,226,228,230,234,236,236,238,237,238,240,241,241,242,241,242,245,244,245,245,246,244,244,244,244,246,245,244,245,246,243,234,238,247,248,246,247,243,234,241,247,246,241,241,245,244,244,246,247,246,246,246,246,246,248,247,247,246,247,246,246,244,244,245,244,244,244,245,245,246,246,246,247,244,244,245,245,246,245,246,243,243,244,241,242,242,242,240,238,235,239,232,224,237,222,205,206,212,228,252,221,187,189,219,229,214,235,250,227,204,217,229,246,227,247,200,150,124,94,66,48,204,245,250,249,223,244,244,252,203,215,250,238,247,249,211,223,252,248,190,195,220,181,139,113,160,206,196,214,201,217,252,252,252,252,240,163,137,169,139,160,190,130,190,106,78,73,83,105,22,45,57,41,41,45,38,43,33,26,163,243,195,223,249,232,237,225,112,38,125,196,202,171,174,233,208,172,135,162,252,203,75,171,187,151,199,119,116,198,231,248,247,151,45,3,8,10,99,240,247,202,66,4,8,1,111,250,253,251,173,82,30,19,50,109,84,49,57,57,48,44,39,40,35,36,36,38,39,38,39,34,33,33,53,56,53,113,108,83,74,72,93,97,112,116,108,109,104,92,86,86,72,60,62,59,56,57,66,69,72,76,77,82,98,114,121,127,131,136,142,133,146,149,139,147,146,149,136,123,122,120,113,111,97,94,78,92,200,199,155,139,134,144,139,145,147,150,153,154,152,138,135,144,159,144,83,51,43,46,54,53,64,60,59,59,58,59,50,54,50,43,41,44,39,39,40,40,42,47,45,42,50,53,60,62,58,64,67,56,53,50,42,43,37,35,37,28,33,30,37,9,67,171,179,139,57,35,19,26,178,223,151,86,42,29,39,13,47,205,239,240,249,224,143,83,49,14,98,226,247,218,150,83,49,122,201,186,148,79,49,40,25,29,28,36,39,35,38,33,49,16,78,196,218,235,228,222,224,221,224,223,222,222,225,224,222,224,225,223,223,222,222,222,225,225,222,222,222,225,223,222,222,224,225,223,222,221,222,223,220,220,221,220,222,221,220,114,4,1,5,9,10,9,10,10,12,12,11,11,223,225,226,221,226,223,222,224,224,223,225,227,224,226,226,226,226,224,226,227,228,230,227,229,231,229,231,230,231,230,231,232,229,229,229,227,226,222,218,222,217,220,219,218,220,219,220,217,217,219,219,218,220,220,221,219,218,220,217,221,220,219,220,221,222,220,222,221,217,222,220,219,222,220,221,222,222,222,224,223,225,228,225,226,226,225,226,228,229,231,229,231,231,230,232,230,232,230,230,230,227,228,229,229,230,231,229,230,233,231,232,228,227,225,223,224,223,226,225,225,227,226,229,226,224,227,227,227,228,227,229,229,228,232,229,232,232,233,231,230,233,233,234,231,230,232,230,228,227,224,221,222,224,223,225,224,226,226,225,227,226,225,226,226,222,222,222,224,224,224,222,220,221,220,219,222,220,219,220,218,220,219,220,221,218,219,220,217,221,220,219,222,219,221,221,221,219,223,222,223,225,224,225,223,226,226,227,223,227,227,227,230,227,232,232,231,234,232,234,235,237,239,240,238,240,240,239,239,237,237,237,238,237,236,233,230,231,229,230,229,229,227,229,231,233,234,232,235,236,237,237,239,240,241,242,241,242,242,242,242,242,242,242,243,245,246,246,246,245,247,247,240,233,242,246,245,246,246,237,236,245,246,243,237,242,245,245,246,246,245,245,246,245,245,245,246,246,246,246,246,245,246,246,245,244,244,244,244,243,244,245,246,247,246,245,244,245,245,244,245,244,244,244,244,242,242,239,240,237,237,235,238,235,226,232,220,213,216,215,200,220,196,187,221,247,247,229,240,247,222,203,219,230,243,220,249,203,164,142,108,71,49,208,244,249,246,220,241,245,251,190,214,247,236,248,251,211,195,227,232,139,101,134,152,168,168,229,250,230,238,222,238,251,249,251,252,197,109,129,174,171,186,200,139,165,69,48,55,69,97,19,46,57,46,42,40,45,44,21,31,168,234,189,215,243,222,240,248,131,49,110,188,226,161,144,160,108,130,148,220,252,150,122,213,189,194,183,106,162,218,240,244,249,188,70,3,4,2,43,210,252,252,201,133,182,244,253,253,252,179,91,36,12,33,27,74,76,42,41,45,42,39,39,33,35,37,36,38,35,36,42,44,51,63,80,95,99,85,67,82,100,92,73,74,65,59,57,56,113,60,62,73,85,99,112,123,135,139,141,145,138,138,133,130,133,119,107,95,77,67,65,58,56,55,49,46,49,43,42,45,39,36,35,24,24,24,31,40,103,140,145,142,139,139,142,147,156,154,154,155,152,136,136,152,162,134,69,27,38,15,24,27,35,36,38,44,50,46,54,57,50,56,58,64,59,56,57,53,52,51,49,48,46,42,41,49,57,63,63,72,73,73,75,73,66,62,59,57,44,50,36,36,26,30,153,134,77,34,32,178,236,212,160,98,62,27,33,19,119,227,250,250,249,227,152,99,56,18,35,152,157,128,105,43,99,204,234,185,107,69,33,24,101,146,124,82,51,39,36,34,44,9,77,193,205,231,231,225,226,222,225,223,223,224,222,223,225,225,223,220,225,224,221,224,224,222,222,223,225,226,224,226,224,225,223,226,224,221,224,220,221,220,219,223,221,220,221,116,3,1,5,8,9,9,12,10,11,12,12,12,221,222,221,223,225,221,223,221,220,222,222,223,225,223,224,226,228,226,226,228,226,226,229,229,229,229,229,229,230,231,231,234,228,231,232,229,227,221,221,219,220,218,218,218,215,218,217,215,218,215,218,219,217,219,218,217,217,217,221,219,218,219,217,216,218,219,221,219,217,217,217,218,220,220,218,220,219,220,222,222,225,224,223,224,225,224,226,229,229,228,229,230,229,226,227,229,231,229,229,226,229,229,228,232,230,231,231,231,230,232,229,230,230,227,227,225,222,223,224,223,225,224,224,224,223,223,225,225,224,227,227,227,230,230,232,232,231,232,231,231,232,232,230,231,231,229,229,228,225,222,223,223,223,226,226,224,224,224,226,226,227,226,223,226,225,225,222,221,223,220,223,218,217,218,217,220,219,218,219,220,221,219,218,218,217,218,218,218,221,221,220,220,220,218,220,220,221,223,221,222,220,222,224,223,224,225,225,227,225,225,228,227,230,229,229,231,231,234,233,235,236,239,239,238,240,240,237,238,237,236,237,239,237,234,235,232,230,229,229,229,228,228,227,231,231,232,234,234,237,235,237,237,240,243,242,244,242,241,239,238,240,242,243,242,244,245,246,246,244,244,246,235,229,241,244,245,248,244,234,238,247,244,240,239,245,246,246,247,246,247,246,246,246,246,246,246,245,246,246,245,245,244,246,246,244,242,244,244,244,244,246,245,246,246,245,244,243,244,244,244,244,244,244,245,243,243,240,239,237,237,237,239,239,232,229,217,210,207,180,195,238,214,241,250,252,236,192,225,249,217,203,219,229,240,215,252,202,160,149,117,74,55,214,244,250,246,221,240,247,243,177,214,248,245,252,252,218,147,159,161,122,114,156,211,227,223,252,252,234,240,212,234,251,239,252,247,177,120,142,169,175,188,203,150,148,72,63,24,32,90,27,69,57,36,34,35,46,44,23,93,220,234,191,212,237,213,234,242,128,24,90,198,225,148,139,136,140,159,165,217,174,112,155,243,209,240,192,85,187,238,239,241,247,224,127,28,2,9,12,88,223,240,249,249,253,253,253,210,112,45,1,12,24,27,34,30,39,51,41,39,45,43,45,42,44,51,57,62,69,74,87,103,111,110,98,77,63,60,45,50,57,50,53,61,76,86,100,118,129,128,125,139,146,138,128,117,93,70,61,55,46,39,35,34,33,30,31,29,31,27,24,25,17,23,19,17,24,30,35,33,34,36,30,23,21,13,22,11,32,96,141,152,143,146,148,154,155,155,157,160,151,136,138,153,166,121,53,32,33,28,23,18,16,14,13,16,18,22,23,23,26,26,33,32,35,42,48,56,58,61,62,64,69,63,63,61,59,62,55,53,47,48,54,58,66,71,77,78,72,73,66,57,55,48,34,72,70,27,157,239,248,232,150,111,63,31,34,18,70,210,241,241,229,144,104,83,69,33,21,15,14,10,19,9,92,234,227,143,101,45,58,196,235,235,241,184,118,75,51,31,39,8,72,203,209,229,234,225,228,222,226,223,224,224,222,225,225,224,221,222,227,225,226,225,224,224,225,227,224,224,222,228,225,222,226,223,224,222,222,223,219,221,221,221,223,220,221,116,3,1,5,8,9,9,11,9,11,12,11,11,219,220,222,218,223,220,221,221,223,222,220,222,222,221,221,222,222,223,224,227,226,229,229,226,229,227,230,229,229,231,229,229,226,228,229,225,226,224,221,221,218,216,216,216,213,214,216,214,217,218,217,216,218,217,215,214,217,219,217,219,217,216,216,215,216,214,216,218,215,218,219,216,220,216,216,217,218,219,219,220,219,221,220,223,225,222,224,225,225,226,228,226,226,225,224,224,225,227,226,229,228,229,230,227,229,229,228,227,229,229,230,230,231,229,226,224,225,223,221,221,222,222,222,220,220,221,222,223,224,226,227,226,227,231,230,232,229,230,231,229,230,229,230,232,231,229,226,224,224,223,223,223,221,221,222,222,222,221,222,225,222,222,223,221,222,224,225,222,221,219,219,221,219,218,218,220,217,219,221,222,222,221,221,217,217,216,218,217,220,218,215,219,220,221,220,220,219,218,219,219,221,221,220,220,225,224,224,223,223,225,227,227,226,229,228,229,230,229,232,235,236,236,235,236,237,236,237,236,235,236,235,235,232,232,231,229,229,229,227,227,228,226,229,228,230,232,232,235,234,234,235,239,241,240,240,241,240,240,238,239,240,241,243,243,244,243,243,244,244,244,241,227,225,238,241,241,246,239,229,240,246,243,238,241,245,245,244,244,245,246,247,247,245,245,247,247,247,246,245,246,245,244,244,244,244,243,244,244,244,243,244,245,245,245,244,244,245,245,245,245,245,244,245,243,242,242,240,239,236,236,235,235,237,235,224,214,199,196,211,240,252,203,218,230,222,206,196,229,248,214,201,218,223,237,214,252,194,149,134,108,70,53,210,244,250,242,219,238,246,238,181,224,250,250,248,232,187,144,167,182,187,160,181,237,247,225,246,252,220,228,187,197,239,238,252,239,179,146,141,163,192,171,206,146,151,136,101,37,37,111,58,75,61,36,36,35,38,46,140,221,236,224,186,210,240,211,233,234,122,22,41,139,196,187,217,188,167,201,188,195,159,99,182,232,194,252,163,83,198,235,242,236,243,250,203,127,53,3,3,25,57,145,198,216,203,163,110,60,37,15,41,60,53,64,61,66,65,69,75,76,80,84,86,91,99,91,91,93,86,76,63,63,57,50,48,53,55,64,73,85,103,117,137,141,139,134,127,107,80,67,53,44,39,28,29,28,31,27,20,23,25,25,19,14,19,26,25,30,28,31,35,19,17,21,23,36,34,35,25,18,25,33,39,38,19,21,14,47,111,139,155,158,143,150,148,150,145,148,160,155,141,132,141,157,158,101,40,23,29,46,49,29,21,13,15,16,16,24,24,20,20,24,22,21,20,16,19,19,22,27,31,43,44,46,60,69,80,91,94,89,83,76,67,60,57,53,48,49,54,60,68,75,69,74,67,54,59,56,180,237,248,211,130,75,39,34,32,38,23,22,142,198,148,99,79,70,67,66,55,37,11,15,12,125,234,241,227,135,95,55,19,100,198,228,248,234,165,104,64,30,46,10,77,206,208,232,235,224,228,222,227,224,224,224,225,226,225,226,225,224,226,225,224,227,227,225,226,225,225,224,226,226,225,225,224,223,222,223,221,218,220,222,219,220,222,217,218,115,4,1,4,8,10,9,10,10,11,11,11,12,220,224,220,220,221,216,218,220,220,220,221,220,219,218,222,222,222,224,224,228,227,226,229,227,228,229,228,227,227,226,227,226,222,224,223,220,221,221,222,222,219,219,215,216,219,217,214,214,217,215,217,217,215,216,213,217,217,215,218,216,215,214,215,215,214,215,216,215,217,216,217,219,217,218,221,220,218,218,218,219,222,221,221,223,222,224,224,227,227,224,223,225,225,225,226,224,229,228,229,227,228,230,228,229,229,227,229,230,229,231,227,230,230,228,228,227,224,221,222,220,223,224,223,222,220,219,221,220,220,224,223,223,227,227,228,231,229,233,232,233,230,230,231,230,230,230,226,224,222,220,223,219,218,222,219,220,222,224,224,223,224,223,223,222,222,224,222,220,223,222,223,221,222,221,221,220,220,223,222,221,224,222,219,220,218,218,217,218,219,217,220,218,219,218,219,220,217,219,218,221,223,223,222,222,225,224,224,224,225,225,226,225,224,226,227,228,229,230,231,232,234,232,234,234,234,236,236,235,235,234,234,232,230,229,229,227,227,229,227,227,227,227,230,230,230,234,234,236,237,235,237,237,240,239,240,240,237,239,237,238,241,240,243,243,243,242,243,245,245,244,240,225,229,242,241,244,245,233,232,242,245,241,238,244,245,244,246,245,246,247,246,246,246,246,247,245,245,247,246,246,246,245,244,244,245,242,244,244,243,245,245,245,246,246,245,245,245,245,245,245,244,244,244,245,243,242,240,237,237,235,235,237,239,240,218,208,208,217,228,253,194,78,131,198,236,232,223,243,247,209,203,219,222,232,215,252,188,146,128,101,63,52,214,244,250,242,220,246,252,239,194,229,230,205,189,189,200,185,238,248,241,173,159,232,247,226,238,251,223,196,145,187,241,247,252,226,176,165,160,181,206,154,193,133,165,185,156,76,55,125,66,89,65,45,39,41,30,61,216,246,219,198,177,210,239,208,234,237,130,66,54,103,165,219,252,210,177,130,173,237,167,165,200,184,153,210,122,69,200,228,244,240,239,249,252,243,210,134,73,113,54,7,14,5,10,8,10,17,45,67,74,92,105,113,120,113,115,110,97,103,100,82,67,61,59,55,51,53,52,53,62,65,80,90,108,129,136,144,137,131,110,94,75,52,43,35,32,27,23,29,28,19,15,12,15,25,25,23,18,25,29,29,26,14,24,40,35,37,37,33,35,26,19,30,41,44,35,19,19,15,16,22,31,53,33,38,51,97,196,181,161,161,155,158,151,150,148,158,158,149,135,133,143,164,155,82,29,12,16,40,60,54,36,27,14,19,31,27,25,18,13,19,23,23,28,22,16,13,17,24,19,22,23,22,24,27,28,35,47,55,69,78,81,87,90,83,80,76,66,64,57,55,51,57,61,69,59,50,171,208,176,159,99,70,43,31,34,33,36,39,16,31,76,126,137,71,74,100,96,153,196,214,245,246,253,253,236,173,104,36,5,12,15,55,198,228,199,128,71,45,46,8,82,206,211,233,234,225,226,226,226,225,226,223,227,227,226,227,227,228,229,226,229,228,228,227,227,228,226,229,225,225,223,226,227,221,225,222,222,219,219,223,221,222,225,220,218,115,4,1,4,9,10,9,10,10,12,12,11,11,214,220,218,218,219,217,216,217,220,219,218,217,218,221,220,221,220,222,225,224,224,225,226,226,227,224,226,223,223,227,223,224,222,221,222,219,220,216,218,219,218,214,215,218,214,215,215,213,215,212,215,214,213,215,212,213,213,213,213,215,210,212,215,212,213,213,213,214,213,212,215,213,215,215,218,216,217,217,218,220,219,223,222,223,224,222,224,224,225,223,223,223,223,224,225,228,226,227,227,228,227,227,228,226,226,226,226,229,228,227,227,227,227,224,225,224,222,219,220,221,222,224,223,221,218,221,222,219,220,222,223,224,224,224,225,226,226,228,228,227,228,228,227,227,228,229,227,222,222,219,216,218,220,220,221,222,220,223,224,223,223,222,223,221,225,222,220,219,219,221,222,224,221,220,222,221,220,216,218,220,218,220,219,217,217,217,219,217,217,218,217,217,215,215,215,214,217,217,220,218,220,222,221,221,222,222,222,220,221,222,222,222,223,225,223,223,226,226,226,226,228,227,228,231,232,233,234,231,232,235,234,232,229,229,228,226,227,226,227,226,226,226,226,229,233,233,234,234,233,235,236,234,236,236,236,238,236,237,235,236,238,239,241,240,243,242,243,245,244,244,235,221,231,243,241,245,240,226,236,244,244,237,237,245,244,246,245,246,246,246,246,246,246,245,246,244,244,244,244,244,244,244,244,244,245,243,243,242,242,242,244,246,246,246,244,245,245,246,245,245,243,243,244,242,241,241,238,236,235,234,232,235,237,240,214,208,213,222,217,202,125,13,103,220,251,244,220,235,244,203,206,218,219,229,215,252,193,160,141,110,61,46,214,244,251,248,228,250,252,219,165,179,181,187,210,227,247,214,229,241,250,182,140,228,249,230,230,239,167,179,197,205,245,250,236,197,165,178,160,192,210,155,201,134,182,187,148,83,42,138,81,87,81,50,42,49,24,70,231,246,197,176,177,212,240,208,232,246,169,160,111,88,149,228,250,178,112,103,212,198,110,152,207,177,154,190,71,76,201,214,226,217,229,242,252,252,251,227,177,183,110,54,29,18,19,29,45,46,46,46,50,46,49,53,53,53,52,53,49,49,93,47,53,58,63,67,77,88,103,120,122,129,139,131,110,90,69,55,42,35,28,19,22,14,14,12,14,22,26,29,26,24,17,12,22,27,23,19,25,37,30,32,29,27,39,43,42,45,43,33,25,22,39,46,46,48,34,26,21,16,24,24,41,52,60,87,105,170,210,171,165,158,159,163,158,158,154,163,165,149,134,135,146,164,140,65,24,24,23,44,64,62,60,37,15,28,33,29,18,14,15,13,16,19,30,27,22,18,17,29,27,28,27,29,24,24,22,15,16,21,21,24,34,35,46,59,65,78,83,90,98,93,90,79,69,59,57,51,50,36,50,79,77,76,65,60,54,50,48,41,33,37,22,54,101,75,53,42,136,225,243,244,249,249,247,247,244,222,130,47,6,11,14,76,220,235,202,143,91,47,37,6,102,211,219,238,229,225,227,222,226,223,225,226,226,227,227,228,226,228,229,229,226,227,228,225,229,225,226,226,224,225,224,224,222,223,222,222,222,223,219,220,222,222,224,220,220,116,3,1,5,8,9,9,12,10,11,12,12,12,214,217,214,216,219,215,215,216,218,218,219,218,218,221,221,219,221,220,221,223,224,224,224,224,225,227,225,224,225,224,225,227,224,225,224,221,223,218,217,214,213,217,215,212,213,213,213,214,215,214,212,215,214,213,213,214,212,211,214,212,214,212,212,212,212,214,214,213,214,211,213,213,213,214,216,216,217,218,219,217,221,220,221,224,222,224,224,223,225,223,223,224,223,224,226,226,230,228,229,229,227,227,224,227,226,226,224,227,226,224,223,225,222,221,221,221,223,219,222,222,223,223,222,220,219,222,222,220,220,222,220,222,226,223,225,224,222,227,228,227,227,228,227,229,230,227,224,222,223,220,221,224,224,223,221,221,223,225,222,223,226,222,224,222,221,224,223,224,225,225,226,224,224,221,221,221,220,220,219,218,219,218,217,217,217,218,218,219,217,217,219,215,216,217,216,215,215,219,218,216,218,220,220,221,222,221,221,222,220,221,222,221,223,224,224,224,225,226,226,227,229,227,228,229,232,233,232,231,231,232,233,235,232,230,227,224,226,224,226,228,227,225,225,227,228,231,232,233,234,235,238,238,239,237,237,237,240,240,237,237,238,240,240,240,241,243,244,244,245,243,230,221,236,241,240,244,231,225,239,244,241,235,240,244,244,245,245,245,244,245,244,245,245,245,247,245,245,244,244,244,245,245,245,244,244,243,243,245,244,244,245,244,244,244,245,245,245,245,244,245,244,244,242,243,242,239,239,236,236,234,236,236,237,242,214,210,210,198,176,223,142,16,149,237,248,208,190,232,242,203,206,217,220,225,217,252,191,163,145,124,71,45,215,243,250,250,223,228,193,154,151,189,221,234,245,248,252,210,189,201,232,178,149,228,252,210,163,202,182,208,233,223,251,252,201,163,159,162,153,184,197,182,226,142,186,172,133,72,35,132,83,95,68,53,49,47,24,74,243,243,207,180,184,220,244,212,226,249,179,222,179,79,147,230,217,156,111,142,245,168,59,159,236,202,184,172,92,139,212,188,196,196,208,219,228,245,253,229,187,184,92,58,59,57,62,66,84,84,86,83,88,85,79,77,74,74,76,85,86,91,93,118,135,127,134,122,113,108,90,78,68,47,40,37,27,27,24,22,22,23,23,21,19,12,12,10,14,23,27,30,33,32,18,12,16,19,15,15,37,42,27,27,38,46,50,52,51,45,43,34,23,38,51,52,54,54,45,29,33,48,53,48,51,55,97,131,155,239,216,160,165,159,162,162,160,160,158,170,164,147,140,138,152,169,123,51,38,39,26,36,54,64,71,55,36,33,31,24,24,22,13,17,11,21,32,30,30,19,20,28,24,33,33,30,30,27,24,19,23,24,22,21,20,20,23,18,20,21,27,39,53,70,83,98,114,118,105,86,74,53,49,55,51,57,68,76,75,73,72,68,63,55,48,40,43,44,39,39,27,69,101,100,94,78,113,167,214,227,198,172,160,180,238,242,248,240,177,141,99,40,17,9,139,222,229,237,227,229,226,226,227,224,227,229,227,227,231,230,227,229,230,229,229,230,231,229,227,228,226,227,226,227,225,225,224,225,224,225,229,224,223,223,224,225,226,223,222,116,3,1,5,8,9,9,12,10,11,12,12,12,212,217,213,214,215,213,217,214,217,214,216,217,218,218,217,221,220,220,220,221,222,223,224,222,223,222,225,223,222,225,224,226,224,225,224,223,224,219,219,216,216,216,213,215,212,214,215,213,216,212,214,214,213,218,214,216,214,213,214,215,213,211,213,212,213,214,212,214,214,212,215,213,214,213,215,215,215,218,218,218,216,217,219,220,222,220,223,222,223,222,226,226,224,227,224,226,225,226,228,225,225,227,225,225,226,226,227,227,224,223,224,222,221,222,224,222,224,222,226,224,222,222,220,220,217,217,217,217,218,219,219,222,222,222,224,224,225,226,229,229,228,227,226,228,227,224,223,217,221,222,222,226,222,224,223,222,223,224,223,224,224,224,224,222,224,224,225,224,223,225,224,223,222,220,220,220,221,221,218,220,217,218,220,219,222,218,218,218,217,219,216,215,216,217,218,217,217,215,217,217,218,216,217,219,218,220,220,221,222,223,223,223,223,223,223,222,224,225,227,227,227,225,225,227,226,229,229,230,230,228,231,232,231,231,226,223,226,225,225,227,227,227,227,227,230,230,231,233,234,235,236,236,237,237,235,237,239,237,238,237,237,237,237,238,240,241,240,242,245,236,223,224,237,241,241,243,224,227,243,242,238,234,244,244,243,244,244,245,244,244,244,244,245,244,244,244,244,244,244,243,243,244,243,243,243,244,244,246,245,244,244,244,244,244,244,245,243,243,243,244,242,243,245,243,242,240,238,237,237,237,237,237,239,244,218,199,192,204,219,252,143,49,169,221,232,215,207,237,244,198,209,218,216,222,219,252,183,151,125,105,71,46,211,243,250,208,152,188,187,183,202,225,249,249,252,241,252,204,177,188,207,164,136,221,223,184,189,231,199,229,248,217,252,240,173,160,170,158,154,186,188,216,245,132,180,163,148,84,19,118,76,90,71,44,44,48,22,76,235,245,221,177,188,221,239,213,221,245,171,230,216,101,146,218,186,130,132,195,252,185,118,199,244,189,218,217,131,188,209,199,211,192,184,185,199,219,232,183,128,78,10,2,6,8,8,10,21,36,48,65,79,78,79,77,77,83,83,78,80,78,61,69,61,59,54,48,46,45,57,77,71,26,15,25,18,20,14,12,15,18,20,32,32,18,15,12,12,16,23,45,44,40,34,22,24,15,15,20,36,46,29,19,39,47,46,52,48,40,28,27,44,54,57,58,51,50,46,33,34,49,58,57,57,56,119,132,181,234,198,160,159,147,165,161,162,165,166,178,165,148,142,145,160,164,103,48,53,49,37,23,25,56,70,68,54,36,34,30,38,33,24,19,17,27,35,33,32,29,16,17,25,32,37,36,29,32,32,27,29,27,34,30,19,17,25,22,15,16,15,24,24,23,30,34,43,60,68,83,91,97,93,82,71,63,59,53,53,58,66,74,78,79,77,76,69,61,62,54,45,38,39,42,42,36,38,27,19,96,199,230,250,250,252,252,243,195,142,107,41,26,14,64,223,232,236,236,227,230,228,226,228,226,227,227,231,232,229,229,230,232,229,229,226,230,230,226,227,226,228,230,228,227,226,226,228,228,228,227,225,226,225,226,226,224,225,223,224,115,3,0,4,9,10,9,10,10,12,11,12,12,212,214,213,212,213,214,213,212,215,214,214,215,214,214,217,214,216,218,220,222,220,221,223,222,220,221,220,221,222,224,225,223,222,225,222,222,225,220,220,219,219,222,219,220,220,218,216,213,214,212,215,214,214,213,214,214,213,215,215,215,214,214,214,212,214,212,213,213,214,211,211,216,213,214,216,214,217,216,215,217,219,217,221,222,217,221,222,222,222,221,222,222,225,226,224,225,224,224,224,221,224,223,224,226,224,224,224,225,224,224,222,222,222,223,223,222,225,223,225,224,223,221,219,219,219,216,215,217,217,220,219,222,225,222,222,225,227,227,225,224,226,226,224,225,224,223,221,219,221,223,225,224,224,224,222,222,222,224,225,225,224,222,225,224,225,226,224,226,225,223,221,218,218,220,220,221,220,220,219,217,218,218,221,221,222,221,221,219,219,219,219,219,218,220,217,218,215,216,219,218,221,217,217,218,218,217,222,223,222,221,223,222,222,223,221,223,222,224,224,221,224,225,225,225,226,226,227,228,229,229,231,230,231,230,227,223,225,225,224,226,224,225,228,228,230,229,232,231,232,233,234,233,235,236,236,237,237,237,237,236,236,237,236,239,239,239,238,240,241,231,215,223,239,237,243,236,222,236,245,241,238,238,244,245,244,244,245,245,244,245,244,245,245,244,245,244,244,244,245,244,244,243,244,244,243,244,243,245,245,245,244,244,244,244,243,241,243,244,243,243,243,242,242,242,241,239,239,237,239,238,238,238,239,243,211,197,205,224,237,252,114,55,195,234,251,232,229,249,243,199,211,217,212,223,223,252,188,154,125,108,71,55,203,204,181,184,183,239,226,214,230,227,246,242,240,235,252,212,174,200,226,177,133,212,244,237,226,248,193,207,238,182,218,213,159,174,189,178,196,208,200,229,231,116,164,188,163,105,33,91,72,89,68,47,47,52,20,74,233,241,217,152,171,218,236,214,216,243,173,214,230,113,134,178,131,162,167,221,241,132,162,240,236,175,221,212,147,205,216,214,214,196,201,199,190,193,194,132,95,87,70,81,69,57,46,30,20,16,32,39,32,29,27,23,29,28,22,25,17,25,24,18,36,36,38,32,36,71,119,142,81,24,24,18,15,14,11,14,19,28,24,24,35,34,33,18,13,16,27,45,41,49,50,44,41,31,20,15,24,27,25,24,34,46,45,39,41,35,19,39,55,54,56,58,47,33,30,26,25,46,59,68,54,68,136,134,211,252,177,156,150,150,163,163,165,165,174,186,165,145,146,150,170,164,84,56,76,66,60,36,40,62,67,73,63,42,37,35,34,34,24,19,23,36,30,30,34,33,30,17,24,31,30,36,35,37,36,32,29,29,41,37,22,16,16,22,18,16,27,36,31,29,27,19,18,14,18,25,33,45,61,69,79,95,93,90,82,72,65,59,61,59,61,72,76,81,77,72,71,69,59,56,61,51,57,47,46,37,20,104,206,227,239,212,172,132,110,67,35,9,74,221,245,245,235,236,232,231,231,230,229,230,231,231,233,233,228,229,232,230,229,229,229,227,229,231,228,226,229,227,229,228,228,229,229,231,229,230,228,226,228,226,228,226,225,225,222,116,5,1,4,9,10,9,10,10,12,12,13,12,210,213,211,211,214,212,213,209,213,213,214,212,213,215,213,214,213,216,218,219,221,219,220,219,221,220,220,221,220,223,222,221,221,224,222,220,222,220,220,220,222,221,219,221,219,219,216,213,214,214,214,214,212,214,214,214,214,213,214,214,212,211,214,211,209,211,211,208,210,210,213,212,211,213,214,212,214,217,216,216,217,217,219,217,220,218,217,219,221,222,224,222,221,221,221,225,223,222,220,219,218,221,220,219,222,221,223,223,220,221,222,220,221,219,220,221,221,220,222,219,217,218,217,218,217,218,217,220,217,219,221,221,222,221,221,220,222,222,223,222,222,224,220,221,221,222,222,219,224,223,222,224,222,222,221,220,221,223,222,221,221,223,224,224,222,223,222,225,224,220,220,217,220,220,223,223,222,221,219,221,218,221,221,220,223,222,223,222,217,221,221,221,219,216,216,214,216,215,215,216,217,217,217,217,216,218,218,219,220,222,222,220,223,222,222,222,224,223,223,225,223,222,223,226,225,225,228,229,230,228,228,228,229,229,228,227,224,222,224,226,223,224,225,225,227,226,228,229,232,234,234,233,233,235,234,235,236,236,235,234,233,235,236,236,237,237,236,236,236,222,211,224,234,237,240,226,222,240,244,238,234,241,245,244,245,243,244,243,243,243,244,242,244,242,242,243,242,243,242,243,244,242,243,243,244,242,242,243,244,243,244,242,242,242,241,242,242,242,242,243,242,243,241,240,241,238,237,238,237,235,237,235,241,239,215,193,209,223,199,228,96,97,239,246,252,233,219,242,238,196,212,215,209,219,231,252,198,178,146,120,95,66,176,209,224,227,216,250,226,212,225,219,240,231,238,228,250,205,169,203,243,218,152,235,251,251,221,178,150,192,209,177,206,187,156,187,204,181,208,218,183,200,204,113,182,174,159,147,74,95,68,95,70,48,53,50,18,71,230,245,207,124,171,223,236,215,211,244,165,184,205,127,112,78,98,165,200,217,146,135,199,248,219,150,198,167,126,198,206,214,221,214,216,206,200,214,178,152,183,198,228,241,241,247,245,244,239,217,149,73,55,51,46,50,42,37,35,27,31,36,34,40,60,53,39,16,53,127,161,162,70,23,26,14,11,11,9,21,43,46,39,26,21,37,44,41,28,15,19,19,40,51,47,53,46,44,39,29,23,21,13,24,49,54,46,32,23,22,44,53,55,47,45,56,44,30,12,24,44,56,56,60,51,47,108,147,234,234,159,152,145,150,167,160,161,161,179,185,156,140,149,159,170,142,61,39,56,76,69,38,42,74,71,76,66,37,34,30,36,27,22,16,17,24,23,36,37,35,32,22,21,17,25,40,27,33,35,22,19,29,35,31,25,17,16,12,19,30,41,44,39,32,23,18,14,15,16,17,19,20,25,26,36,42,53,69,81,95,104,103,93,85,83,77,68,66,60,62,63,66,69,69,68,71,77,74,63,63,42,16,24,24,38,53,50,53,64,27,56,189,243,243,250,236,235,235,231,229,228,231,231,231,235,233,232,232,229,231,228,231,231,228,228,228,230,229,230,230,230,229,228,230,229,229,230,228,229,229,227,229,227,224,227,228,226,225,224,116,3,1,5,9,9,9,11,9,12,12,12,12,210,212,210,212,211,210,212,208,212,211,211,211,213,213,214,212,215,216,217,218,220,219,218,219,218,219,218,221,219,218,223,220,220,221,219,219,221,220,218,220,219,218,218,220,216,215,216,214,215,213,215,215,215,215,217,215,214,217,214,215,213,213,214,211,212,208,208,211,211,211,211,212,207,211,213,211,212,213,214,214,215,214,213,216,216,217,218,218,221,220,223,220,219,222,219,222,222,220,218,218,220,218,219,221,220,220,222,220,221,219,220,220,218,218,216,218,217,216,216,216,217,214,218,218,217,219,220,220,218,220,220,220,221,219,220,221,220,222,223,222,224,226,222,222,220,219,219,220,222,221,222,222,223,224,223,223,223,221,219,219,219,219,221,222,222,221,221,222,222,219,218,219,221,223,223,227,223,221,222,223,222,221,223,222,223,224,223,221,220,220,221,219,215,217,214,214,216,217,218,215,219,218,217,219,220,218,219,218,219,217,220,221,220,222,221,223,222,223,223,220,224,223,219,224,225,226,228,226,227,224,227,227,226,227,227,228,227,224,225,224,224,225,224,225,230,228,228,229,230,233,233,233,232,233,234,232,232,234,233,232,234,234,235,235,234,235,235,237,231,215,210,227,234,236,235,218,227,242,241,234,236,243,242,242,241,242,242,242,244,243,244,242,242,243,242,244,243,242,243,243,244,242,243,242,242,242,241,242,241,243,244,242,241,243,242,241,242,241,243,241,242,243,242,241,242,240,239,238,237,235,237,234,241,235,217,194,193,195,210,249,95,118,247,247,251,189,198,238,233,197,214,218,208,225,237,252,186,146,118,108,75,68,220,245,251,244,223,251,207,212,226,213,239,229,235,231,246,225,181,185,220,200,143,217,251,214,170,160,178,224,244,213,191,183,166,200,199,151,203,203,160,176,193,120,171,182,126,174,157,131,94,90,69,47,47,56,18,67,233,247,210,131,177,229,239,216,209,245,175,162,181,158,117,58,88,181,194,192,151,145,224,246,209,149,174,115,117,218,214,225,225,210,213,215,220,230,179,158,225,241,242,243,251,252,253,253,250,210,162,132,131,129,125,118,111,95,82,80,93,90,85,96,89,53,31,21,94,136,147,144,55,27,24,12,15,12,10,33,54,45,54,42,18,23,40,50,47,36,27,28,32,49,52,49,48,46,46,45,41,36,27,46,62,46,51,45,39,49,51,57,50,38,23,30,38,19,15,35,58,60,55,49,38,19,55,164,251,217,145,148,141,157,160,159,162,167,191,177,146,146,157,165,174,124,40,21,31,58,67,35,36,62,79,77,48,23,25,31,33,34,34,19,14,15,22,32,32,34,37,31,21,18,20,23,27,30,30,22,12,23,27,19,20,23,30,40,43,51,55,49,46,32,20,14,17,12,23,33,29,33,26,29,23,23,27,22,28,39,57,73,78,96,123,146,152,152,134,126,109,93,82,66,63,59,61,59,60,57,55,61,47,42,44,46,47,52,41,11,116,223,250,250,243,235,238,234,233,229,230,231,235,234,235,236,233,231,232,232,231,232,231,230,230,231,230,229,229,229,230,227,231,232,230,228,229,229,227,228,223,228,227,224,226,226,226,224,224,116,4,1,6,9,9,9,12,10,11,12,12,12,206,214,212,210,210,208,209,209,211,210,210,210,212,211,212,214,213,216,218,215,217,218,218,215,217,220,219,220,218,220,220,219,220,220,218,219,221,219,221,220,220,220,218,218,218,216,213,216,214,215,216,214,216,216,213,213,214,215,213,216,216,215,216,214,213,214,214,212,212,211,212,214,212,210,212,212,213,213,212,214,214,214,215,214,215,216,220,221,219,218,218,217,216,216,217,217,216,218,219,220,218,218,219,218,219,220,219,218,217,218,219,217,216,217,215,218,216,212,215,215,215,216,215,217,217,217,218,218,220,220,219,220,217,217,219,222,222,218,221,221,221,223,221,223,221,217,219,220,221,222,220,219,221,223,222,223,224,223,221,222,220,218,221,221,220,221,219,222,221,220,222,221,221,221,223,222,222,222,224,225,222,222,220,219,221,221,222,224,222,223,221,218,218,217,214,215,219,217,218,219,220,220,220,220,221,220,218,218,217,219,218,218,220,218,221,222,222,225,222,222,223,222,223,223,221,224,225,222,224,224,225,224,226,224,224,226,225,226,225,222,221,222,224,226,228,229,230,229,231,233,232,230,231,233,232,232,232,232,232,234,234,232,234,231,233,233,235,237,229,214,215,232,235,237,226,216,235,242,237,232,236,244,243,241,242,241,241,242,241,241,242,241,243,242,241,242,241,242,242,243,242,241,241,242,242,240,241,242,241,243,241,240,240,240,240,241,241,241,241,242,242,241,240,241,242,240,240,239,239,235,237,235,244,231,214,183,194,227,240,249,104,115,233,221,227,196,209,243,235,203,226,222,211,217,216,209,131,126,104,93,68,57,216,245,252,236,216,249,199,215,228,210,238,230,236,229,243,234,198,184,183,164,111,155,201,220,222,178,198,246,252,230,193,191,172,208,185,146,210,208,179,174,196,136,187,138,71,207,198,161,125,97,61,36,44,57,19,64,226,248,193,101,160,216,235,213,210,243,190,156,181,218,159,78,121,145,185,213,98,159,237,239,201,185,190,97,170,246,222,223,225,228,224,207,213,224,169,200,239,224,224,222,232,227,211,154,106,89,90,108,133,128,113,113,110,133,146,139,128,105,114,150,125,68,29,24,114,139,145,130,42,25,29,25,17,12,13,19,49,55,58,39,22,13,23,46,50,54,48,39,42,42,48,52,47,50,48,47,53,45,46,50,49,48,54,50,54,53,50,52,40,34,27,43,47,35,45,55,71,77,76,81,77,50,94,206,234,202,145,141,145,156,165,159,166,180,191,162,137,147,160,174,169,110,47,41,41,48,57,44,33,49,72,60,39,15,16,22,30,39,34,26,17,14,21,27,20,26,35,36,29,22,17,21,32,36,32,25,17,12,19,33,43,44,49,53,53,56,54,47,41,28,21,16,22,35,42,44,40,31,27,21,15,19,18,25,24,22,26,51,77,67,61,76,98,134,145,145,156,159,157,148,141,136,129,118,103,100,97,90,89,74,60,46,27,16,22,7,99,222,247,248,238,232,235,231,233,231,233,235,235,234,236,235,233,235,233,233,231,232,232,231,232,232,230,231,231,229,229,230,230,231,229,230,230,227,229,227,225,226,226,225,225,226,226,226,223,115,3,0,5,9,10,9,10,10,12,12,11,11,205,210,208,209,210,208,210,207,212,212,213,210,211,210,210,212,213,212,212,216,216,217,217,217,217,217,220,219,219,217,221,219,218,220,220,219,219,220,218,217,217,218,216,215,215,215,217,216,215,214,215,216,215,213,212,212,211,213,214,212,213,214,215,212,216,215,215,216,212,212,212,212,211,212,211,213,213,210,212,213,214,214,215,216,214,215,214,216,218,215,215,215,214,215,214,214,216,216,216,220,217,220,219,220,221,217,220,218,220,217,220,217,216,219,215,215,213,214,214,214,216,214,216,215,216,219,217,217,217,218,218,217,219,217,215,218,218,218,218,219,220,221,221,220,220,218,222,223,221,222,218,221,221,221,223,219,220,220,222,222,220,221,219,219,220,221,222,219,219,221,222,223,223,223,222,221,223,222,220,222,222,219,219,219,218,219,223,223,222,222,223,222,217,218,218,218,218,220,222,223,222,221,221,221,220,218,219,219,218,216,218,217,217,222,220,221,221,222,223,220,224,224,222,223,223,222,222,222,223,223,227,225,227,232,227,227,225,226,226,222,224,224,222,223,228,230,230,231,229,230,231,232,231,231,234,231,233,234,231,232,234,233,232,232,232,232,235,234,224,211,220,234,236,238,219,224,240,241,234,228,242,243,242,243,240,241,242,242,240,240,242,242,243,244,242,242,241,241,242,241,241,242,242,242,242,242,241,241,243,245,243,242,240,241,241,242,243,241,243,241,242,240,240,241,240,241,240,241,240,238,239,237,244,227,220,194,215,235,235,250,89,96,203,220,247,219,237,249,239,213,227,209,174,177,188,215,161,149,125,101,63,60,216,243,249,231,218,243,191,222,226,212,236,227,234,230,239,235,196,180,199,178,113,147,220,243,250,177,188,246,252,229,182,179,171,214,189,184,226,208,202,159,184,151,184,106,21,221,199,160,167,113,69,21,33,56,17,66,227,248,182,83,132,194,233,218,210,244,191,151,185,247,199,94,76,132,210,156,72,171,240,233,199,196,194,142,199,239,221,219,221,223,229,226,229,213,163,200,231,227,239,237,232,197,127,79,49,62,77,93,87,48,39,35,45,66,98,114,85,39,32,103,116,89,39,41,135,127,148,120,29,18,28,42,34,18,16,30,54,61,61,32,13,13,20,48,56,43,32,32,34,42,50,47,52,48,50,49,50,54,48,56,61,68,70,69,77,77,83,92,97,94,101,111,110,111,121,122,119,124,127,135,117,84,152,248,249,190,147,149,144,160,160,159,171,186,188,150,143,153,166,179,159,96,59,65,57,65,66,66,70,61,61,60,55,51,47,48,48,47,45,34,27,27,31,20,15,19,28,38,36,35,31,33,36,36,37,32,24,27,37,50,54,53,54,57,55,52,49,36,25,22,25,40,42,43,39,35,37,38,34,19,16,15,17,16,29,28,38,93,114,98,68,43,27,25,33,43,47,53,61,66,75,88,104,107,113,112,110,95,80,69,39,27,22,16,36,111,221,241,242,243,238,235,231,231,233,233,231,233,235,236,235,234,235,236,233,233,234,234,232,233,232,231,234,233,232,230,232,229,230,229,227,232,231,229,228,230,227,226,226,227,228,227,227,225,223,116,4,1,5,10,10,9,10,10,11,12,11,12,205,208,205,207,206,207,207,206,209,210,207,207,210,209,210,210,210,211,212,214,216,214,217,214,215,216,212,216,217,214,214,215,215,216,214,215,215,214,216,215,214,212,212,212,215,215,215,218,214,212,214,214,216,214,212,213,210,210,210,208,209,209,211,212,211,213,212,211,214,212,211,209,210,212,211,211,210,212,211,211,212,210,212,211,214,214,214,213,211,214,214,215,214,211,214,214,214,216,213,215,215,217,220,217,219,218,217,219,217,218,216,215,218,215,214,216,215,213,214,214,211,215,215,216,216,215,215,214,218,216,215,214,215,217,213,216,217,217,223,220,222,222,219,221,220,220,221,220,218,217,215,218,220,222,220,219,219,220,218,219,218,215,217,214,217,219,218,218,217,220,219,222,220,218,219,218,218,218,219,217,216,217,218,219,217,219,219,219,219,218,219,221,218,218,217,215,217,216,218,219,220,221,219,220,220,216,217,218,216,219,218,217,220,219,223,222,219,222,222,223,222,220,221,222,223,224,223,222,220,223,224,224,227,226,230,229,224,225,223,222,223,220,222,225,226,227,226,225,226,229,231,231,230,231,232,230,230,231,232,232,229,232,233,232,230,229,233,229,217,208,224,235,239,232,217,232,244,239,229,232,240,240,240,240,241,240,239,239,241,241,241,240,241,241,241,242,240,241,241,241,242,241,243,242,242,242,242,243,242,242,243,242,240,242,240,240,241,240,240,240,240,241,240,240,240,237,239,238,239,239,239,238,241,225,217,200,209,187,207,234,89,123,232,243,252,221,223,241,224,190,198,179,170,202,230,251,187,172,142,125,81,62,220,243,244,227,218,232,185,226,225,213,235,224,231,229,234,232,186,184,198,187,165,174,229,248,250,164,185,243,235,190,131,156,187,217,184,194,220,204,193,128,171,149,164,88,24,225,191,136,174,144,92,20,19,51,17,72,230,247,177,93,157,200,239,220,206,244,189,139,195,246,207,102,81,170,219,141,74,178,234,220,193,190,163,129,203,228,219,214,215,222,225,222,240,211,158,206,209,212,222,236,239,148,105,72,56,77,79,50,29,33,42,56,55,39,54,96,92,58,16,57,109,109,52,64,138,119,147,102,23,14,27,58,54,50,49,51,60,57,48,23,11,9,20,46,46,30,22,25,30,46,55,60,68,76,84,93,112,117,125,136,134,137,129,117,118,107,113,116,109,109,100,101,100,104,118,113,117,109,117,128,99,93,195,250,234,176,144,150,150,156,161,166,181,186,169,136,141,156,165,180,140,78,55,47,43,46,51,54,56,59,57,56,51,57,63,57,64,62,63,63,60,59,50,48,42,46,42,51,49,41,39,36,35,37,38,42,37,37,41,50,52,55,54,53,54,48,41,33,37,41,43,52,43,35,27,36,47,42,44,37,21,15,15,16,33,35,52,112,131,110,89,49,27,27,42,38,29,19,26,28,22,26,28,37,40,44,50,55,51,60,83,104,150,208,244,244,252,252,241,244,237,236,232,230,233,232,233,234,233,233,232,231,232,232,233,233,234,233,232,232,233,233,233,233,229,230,231,229,230,231,230,229,228,228,227,225,227,227,222,222,225,228,226,223,223,116,4,1,5,8,9,9,11,9,11,12,11,11,204,209,205,206,207,206,206,204,204,204,208,207,208,208,208,210,211,212,210,213,212,213,213,213,214,214,215,214,214,214,214,213,214,213,214,216,214,216,214,217,214,213,214,215,217,213,214,214,214,213,212,210,212,213,210,212,210,210,211,207,207,208,207,207,212,210,209,209,210,212,212,212,211,212,213,213,210,211,212,208,210,210,213,212,214,213,211,213,212,212,211,211,212,213,214,214,215,214,214,217,214,217,215,215,220,214,217,217,215,215,214,215,214,216,216,214,214,214,214,214,214,213,216,215,214,215,215,214,213,216,217,216,215,214,217,217,217,218,219,218,221,221,217,218,219,219,217,217,218,217,217,220,221,218,222,222,220,218,217,217,214,217,215,217,217,217,218,217,219,218,216,219,218,216,217,218,216,215,216,216,217,218,217,217,217,215,215,214,214,218,219,216,220,220,217,216,214,217,215,216,217,217,220,220,220,219,220,218,218,219,218,218,218,220,220,218,221,221,222,221,222,221,220,221,222,221,222,224,223,223,224,224,226,225,224,224,223,224,222,219,221,221,224,226,225,226,228,229,230,230,231,232,230,231,232,231,232,232,232,231,229,230,230,230,228,230,231,224,214,214,231,239,236,221,218,239,244,238,231,236,242,240,241,241,240,241,241,240,240,238,239,239,240,240,240,240,240,242,241,241,241,241,242,241,241,243,243,242,242,243,242,242,240,241,241,241,241,240,240,240,240,240,241,239,240,240,239,240,237,239,236,238,243,217,210,177,186,201,235,242,97,152,246,245,232,180,201,208,201,192,216,204,197,229,245,252,187,170,149,129,84,69,222,243,245,223,220,225,189,235,222,215,234,225,231,228,231,234,205,196,165,162,188,182,230,250,248,154,165,218,187,165,143,177,207,210,171,189,203,205,203,145,184,150,140,65,70,250,165,84,137,160,143,58,12,29,11,70,231,248,174,115,201,208,236,219,207,249,185,155,208,205,143,77,107,183,185,134,123,199,230,210,190,158,123,150,213,229,227,212,213,220,224,222,237,194,168,230,225,214,206,231,183,107,107,69,73,87,44,33,36,61,95,108,115,84,56,103,103,71,30,39,109,125,70,95,129,112,145,78,16,19,8,41,59,57,61,56,58,47,36,28,24,28,44,67,70,76,88,99,111,122,122,131,141,138,135,127,129,122,116,118,111,117,106,107,105,96,106,109,111,110,112,107,116,113,110,116,101,103,93,92,54,99,231,250,247,162,140,151,151,159,162,174,185,178,150,135,150,163,181,175,112,63,46,39,41,50,55,56,58,58,60,59,59,62,53,51,50,50,49,50,53,47,50,54,55,63,61,63,63,61,59,53,53,47,47,42,41,44,44,48,49,53,52,57,60,54,46,41,46,49,50,55,36,21,24,33,49,48,49,35,24,16,14,21,38,38,57,106,114,115,87,59,29,27,65,73,66,62,66,58,48,46,48,53,56,66,58,72,169,238,251,251,252,252,252,252,252,252,241,240,238,234,234,234,233,234,236,236,235,234,235,234,231,233,233,233,232,232,234,232,233,233,233,232,231,233,232,230,231,232,229,229,229,229,227,227,227,226,228,227,226,225,226,226,223,116,4,1,5,8,9,9,10,9,11,12,11,11,200,206,206,206,205,202,204,205,205,206,207,207,207,206,207,206,206,208,209,210,209,208,211,209,211,212,210,211,212,212,213,214,214,214,212,211,213,212,213,215,213,214,214,212,214,213,209,209,210,211,212,208,208,207,206,206,207,208,208,206,208,208,208,210,210,208,208,209,209,208,210,210,210,209,207,210,208,210,209,211,210,208,210,212,212,210,211,212,212,211,211,212,212,212,212,210,212,213,212,213,214,214,214,214,214,215,214,214,214,214,214,214,215,215,215,215,213,211,211,213,213,212,212,212,212,214,214,214,215,213,215,214,217,217,215,217,215,216,217,217,217,218,218,218,219,218,217,216,216,217,218,220,217,219,219,216,214,214,215,215,216,216,215,215,216,214,216,214,215,219,214,214,216,215,214,215,215,214,214,213,215,218,216,218,216,217,213,213,215,214,214,215,215,214,217,215,214,214,213,214,214,217,218,217,217,217,218,217,217,217,219,220,218,219,218,218,216,220,222,220,220,221,222,220,219,220,221,221,219,221,220,220,222,223,222,220,222,223,222,221,222,221,223,226,225,225,227,229,229,230,230,232,230,229,232,229,230,231,230,230,229,230,230,229,228,229,229,222,211,218,233,237,234,216,225,240,240,231,229,241,240,241,241,239,241,239,239,238,239,238,238,238,239,239,239,240,240,240,240,240,241,241,241,241,241,241,240,240,241,239,239,241,240,240,239,240,242,240,240,239,238,240,239,238,238,237,237,237,236,236,234,239,237,219,201,191,214,223,250,238,96,136,214,212,203,169,200,226,218,211,240,214,200,229,240,251,177,164,136,110,72,66,218,242,242,221,224,218,194,241,221,217,231,225,230,226,231,235,211,229,174,143,185,161,201,246,222,128,170,219,189,210,181,184,209,197,179,189,196,207,214,179,212,158,102,78,148,249,146,48,97,134,168,128,55,36,8,37,194,246,174,128,202,193,227,218,210,252,166,149,194,123,118,113,97,148,170,132,151,227,222,207,196,147,107,169,238,230,229,216,210,219,222,223,236,178,179,235,225,236,229,240,159,96,115,73,89,76,39,24,80,130,128,117,91,117,113,109,118,84,37,41,97,125,85,106,124,108,130,61,11,14,5,15,33,55,57,62,66,70,80,77,125,89,157,143,134,138,119,135,133,132,128,129,128,118,109,112,113,109,106,90,84,87,93,95,78,67,79,66,61,59,51,46,43,39,44,40,58,60,24,36,6,119,238,250,234,148,138,152,148,162,168,178,183,166,137,139,155,169,179,166,82,33,27,17,22,17,27,25,30,36,28,34,37,38,38,44,43,44,53,49,56,55,56,56,48,56,53,53,54,53,57,63,61,65,67,61,61,69,66,65,58,60,58,57,59,37,34,33,24,35,56,51,30,22,18,31,49,54,49,31,24,19,17,32,50,41,54,109,114,125,99,56,30,46,109,130,141,147,149,131,117,119,133,144,147,149,138,123,181,243,251,251,252,252,249,249,246,240,237,241,236,238,237,233,235,235,237,238,237,236,236,235,235,234,233,234,233,232,233,233,233,233,232,232,232,232,232,230,232,233,231,231,229,229,228,227,227,227,226,226,227,226,228,226,223,116,2,0,4,8,9,8,10,10,11,11,12,12,201,205,201,205,205,203,204,204,204,206,208,203,206,205,206,207,207,207,206,210,206,209,206,205,210,211,210,210,208,210,210,209,212,210,212,210,210,213,211,212,212,213,211,210,213,208,209,210,210,210,208,208,207,207,206,208,210,207,209,208,206,207,209,208,210,208,208,211,211,209,210,211,209,208,207,209,208,208,210,210,210,213,208,209,210,211,210,212,214,213,213,213,213,211,212,213,212,213,212,214,214,215,215,214,214,213,214,214,211,215,213,215,214,213,216,211,215,214,211,212,211,211,214,212,214,212,214,215,213,214,214,215,215,216,218,217,216,216,217,216,215,216,216,219,218,215,217,216,217,216,219,218,217,217,217,216,214,214,217,216,216,218,216,214,214,215,214,215,215,215,215,215,216,213,212,215,214,215,216,215,216,214,214,217,216,216,217,216,214,214,214,214,212,213,215,215,215,215,215,216,218,216,216,218,217,218,220,218,219,218,222,221,221,221,218,217,220,219,218,218,219,218,219,220,219,219,219,220,217,218,222,219,221,220,221,222,218,221,221,221,223,222,222,225,226,226,227,226,228,230,230,230,229,226,229,229,228,227,228,230,229,228,229,226,228,234,229,220,212,221,234,239,226,214,233,239,235,225,232,240,239,242,240,240,238,239,239,238,240,239,239,236,237,239,238,239,238,239,240,239,241,240,241,240,240,241,240,241,241,239,239,240,238,240,240,240,242,239,240,240,237,239,238,238,239,237,237,236,234,237,231,242,239,224,226,220,233,217,245,194,96,161,200,213,222,207,234,240,233,219,242,209,192,229,236,249,172,155,127,101,63,61,215,240,242,220,224,212,199,242,218,214,229,227,229,225,229,232,207,214,155,151,196,133,150,188,200,175,203,227,206,223,173,177,212,192,186,186,193,207,212,196,219,163,80,103,203,250,141,37,67,91,132,171,139,63,6,24,167,245,168,120,215,185,220,218,210,248,162,159,198,160,190,147,81,119,156,155,198,244,214,201,213,150,98,187,238,229,234,218,208,217,222,228,229,166,193,236,225,233,233,252,141,87,112,74,100,63,19,47,118,133,90,59,19,33,88,126,123,81,43,40,99,115,89,120,114,120,120,44,34,46,49,71,86,114,120,122,133,128,124,122,131,131,121,110,109,117,127,136,134,133,122,112,101,78,63,56,56,52,53,52,41,39,28,36,53,54,62,60,50,39,31,29,30,30,35,29,24,27,23,23,12,159,252,252,227,136,148,143,154,167,175,190,172,147,133,147,161,173,181,139,63,33,28,15,27,33,19,28,24,30,28,17,18,19,17,17,16,18,22,17,25,35,30,35,38,45,55,56,57,58,56,58,57,57,56,57,58,59,72,80,85,84,73,75,65,56,42,27,29,29,48,46,25,16,14,25,42,54,46,39,31,22,39,48,48,41,56,113,118,127,108,60,42,106,152,139,110,83,109,128,140,136,127,116,104,123,123,124,107,108,198,237,248,245,237,238,238,238,236,239,237,238,238,236,235,235,236,236,236,238,238,236,234,235,235,234,233,232,234,235,233,235,233,233,233,231,231,230,230,232,231,231,228,225,226,227,226,225,226,226,226,226,228,226,222,117,4,1,4,8,10,9,10,10,11,11,11,11,200,204,202,202,205,199,201,204,203,204,204,204,206,206,205,205,207,207,207,206,208,205,205,206,207,208,209,208,209,209,207,210,208,209,209,208,211,210,210,211,210,210,209,210,208,209,210,209,209,207,208,206,206,208,210,211,207,208,208,205,207,206,206,206,208,207,207,205,206,208,208,206,208,209,206,209,208,209,208,208,208,209,209,208,210,210,210,210,212,210,212,213,209,209,211,210,212,212,213,214,213,213,212,213,212,212,214,212,214,212,212,212,211,212,213,212,211,212,214,212,211,211,213,212,210,212,214,211,210,211,213,215,214,216,217,215,218,216,216,219,217,217,214,213,217,216,216,216,217,218,218,217,216,215,216,216,215,215,217,212,214,217,212,214,212,213,215,213,214,214,214,214,214,215,214,214,216,214,215,216,214,214,214,215,214,217,216,214,215,214,214,214,213,215,217,215,214,215,214,215,218,217,218,217,216,219,217,217,220,219,221,220,220,221,217,218,214,215,217,214,216,215,217,217,218,216,215,219,217,220,220,219,220,217,217,217,218,218,218,220,222,220,225,225,224,224,224,227,227,229,228,229,225,224,228,226,227,224,226,228,226,228,226,227,227,230,224,212,211,225,236,231,215,217,233,235,227,223,235,238,238,239,236,236,237,235,234,237,237,237,237,237,237,235,237,236,236,237,236,239,237,238,240,239,241,239,239,238,237,238,239,240,239,238,239,239,239,238,239,239,237,238,238,236,236,236,235,236,233,234,236,249,245,252,237,231,211,169,203,149,103,196,234,243,237,197,225,243,222,210,236,200,200,234,237,249,173,164,137,105,61,66,223,243,241,226,221,194,199,240,214,215,227,224,227,224,226,229,190,198,142,141,210,149,150,199,220,190,189,209,209,219,172,188,217,184,198,184,197,202,212,196,193,141,56,152,234,250,155,47,81,66,89,136,168,134,28,21,177,245,171,124,222,197,212,216,215,226,139,194,236,184,174,127,132,145,136,173,225,249,207,202,207,145,110,182,229,226,230,223,211,215,219,231,218,157,207,233,223,234,229,252,123,78,97,73,103,49,22,50,130,123,65,74,48,29,71,125,119,70,35,47,105,107,92,121,112,117,120,104,136,138,142,146,138,125,125,125,120,125,117,134,130,96,111,95,79,83,82,79,67,57,53,38,40,53,47,37,26,28,53,66,59,29,19,55,78,76,87,90,81,56,32,32,33,31,33,30,29,26,30,11,71,213,251,251,208,137,150,146,156,173,178,178,159,136,138,152,163,174,168,113,47,34,29,28,40,34,37,36,32,30,18,21,19,15,24,16,13,18,19,14,19,17,13,19,17,16,20,23,25,24,40,46,51,58,61,63,62,63,71,74,70,71,70,75,83,80,76,67,61,59,61,55,36,24,21,24,37,52,49,48,53,47,51,49,46,29,54,113,123,127,105,49,73,146,157,99,55,41,70,106,107,81,57,49,46,49,51,60,87,78,113,216,243,242,241,234,237,238,236,236,237,237,236,237,238,236,236,239,238,237,237,236,236,233,232,234,231,232,234,235,232,233,233,232,233,231,232,232,229,229,229,227,225,227,225,226,225,227,226,224,227,226,226,225,223,117,3,1,5,8,9,8,10,10,11,12,12,12,200,204,201,202,200,200,201,203,200,200,203,200,203,203,202,203,205,202,205,207,205,207,205,207,208,208,206,206,210,208,207,207,205,207,207,206,207,206,207,208,207,208,208,210,208,207,209,208,207,207,207,207,207,209,206,206,207,205,207,206,204,205,206,204,203,204,205,207,204,204,205,205,206,205,206,206,207,210,207,208,207,208,207,210,211,211,211,209,211,209,210,210,210,211,213,212,210,212,211,210,211,211,211,213,214,211,214,214,213,214,212,212,212,210,210,209,213,210,210,212,212,212,212,210,212,213,213,211,211,214,214,216,217,217,215,214,216,218,219,216,216,216,215,216,218,216,217,219,217,215,217,216,215,214,216,216,216,214,216,216,214,212,212,213,214,212,212,213,213,213,215,214,212,214,213,216,214,212,214,213,214,213,214,216,213,212,213,214,215,214,213,214,214,216,216,212,214,215,214,214,217,218,215,218,217,217,217,218,218,218,220,219,218,216,215,214,215,216,214,217,218,215,217,217,217,218,216,219,218,216,219,216,219,217,215,217,217,220,221,218,219,222,221,224,221,220,227,226,225,225,227,226,226,227,227,227,225,228,227,226,227,226,228,224,228,231,220,212,213,225,232,224,211,224,236,231,224,227,237,235,237,238,236,237,235,235,234,233,235,235,236,235,235,235,234,237,237,237,238,239,239,238,239,239,239,237,237,240,239,237,238,239,238,239,239,238,238,235,237,237,234,236,237,236,236,235,236,235,236,239,242,252,233,200,181,183,169,155,211,160,113,195,227,236,213,193,226,238,219,201,235,199,204,237,234,249,173,168,144,120,71,66,221,244,242,227,213,181,200,238,216,215,227,226,225,226,226,233,208,217,150,160,227,188,210,206,231,199,146,204,218,200,172,174,193,181,204,177,193,197,216,188,160,103,58,203,250,251,177,63,94,93,57,74,130,191,112,77,201,247,176,107,193,190,211,209,212,207,147,198,222,154,112,154,192,115,93,175,238,248,203,206,185,124,120,185,226,226,229,229,213,216,223,239,206,159,223,232,227,234,234,252,124,69,85,78,117,52,18,48,129,113,69,107,106,120,124,125,92,45,29,66,120,107,99,124,101,125,118,108,151,137,142,137,138,146,128,119,99,90,93,84,67,53,53,49,38,29,19,33,57,65,50,19,29,72,82,71,44,27,71,95,82,37,49,95,90,57,75,118,108,77,40,29,33,34,30,29,30,27,36,14,148,247,249,249,190,135,156,143,170,179,178,165,131,126,146,154,165,175,152,79,36,33,27,28,32,38,29,29,23,22,21,22,22,21,21,21,24,16,22,20,19,19,20,21,21,24,13,18,18,17,47,53,46,32,23,30,36,39,51,64,81,87,79,81,72,71,72,74,80,85,85,80,69,62,59,51,46,42,53,51,52,47,43,39,34,31,48,111,118,120,108,47,80,151,121,75,40,52,97,96,82,70,76,81,66,57,45,29,36,60,80,165,236,240,244,237,238,239,237,239,237,238,238,236,238,236,236,238,238,237,238,236,236,235,235,236,234,235,233,233,231,232,232,231,231,232,232,229,228,229,228,224,227,229,227,226,227,227,225,226,226,226,228,225,223,117,2,0,5,9,9,9,10,9,11,12,12,12,197,201,199,202,202,200,200,201,201,202,199,199,199,198,202,201,201,201,202,204,204,204,206,207,205,206,206,205,208,207,207,207,205,207,207,205,207,206,206,208,205,207,203,206,206,204,208,206,206,205,206,206,207,206,205,206,204,206,204,204,204,202,204,203,202,201,204,206,205,204,205,205,205,206,207,208,207,208,208,207,207,207,208,209,207,208,208,208,208,208,211,208,208,208,210,211,210,209,210,211,208,211,210,211,212,212,214,213,212,210,210,213,211,211,211,212,213,211,211,211,211,210,212,212,210,212,211,212,212,213,214,214,214,213,215,214,216,217,215,213,211,214,214,217,218,217,217,214,215,214,216,213,213,213,213,217,213,212,217,213,214,214,212,214,211,212,210,210,211,211,212,212,212,213,214,212,213,211,212,213,212,212,214,212,211,212,212,211,211,213,212,214,214,212,212,212,214,214,214,214,215,215,214,217,217,217,219,217,218,219,221,218,219,215,214,217,214,215,216,216,217,216,216,215,218,216,216,217,214,217,217,215,217,217,218,219,217,217,220,221,222,220,222,220,221,222,223,225,224,223,224,227,227,226,226,226,227,226,227,225,225,225,225,226,227,225,218,210,216,229,230,216,215,232,234,227,220,227,235,232,236,237,236,237,235,232,233,234,233,233,234,233,234,234,235,234,234,237,237,237,237,239,237,236,237,237,238,238,237,237,236,237,238,239,237,235,236,235,235,236,235,235,236,237,237,239,242,242,247,244,244,220,121,78,79,123,169,209,250,153,97,187,224,242,229,209,235,240,209,202,235,194,204,234,234,247,170,155,125,107,66,70,219,244,242,234,207,184,216,240,217,215,226,225,225,226,227,236,210,226,183,180,229,184,204,200,232,205,136,211,195,158,149,150,178,181,207,172,193,193,220,184,146,90,71,231,246,251,184,64,100,105,81,30,62,141,155,144,217,250,171,87,182,201,212,204,204,191,179,202,201,179,150,206,204,79,44,171,247,236,197,195,174,111,120,210,231,229,235,230,221,217,225,244,196,174,236,232,231,238,237,252,143,74,82,84,117,56,26,38,112,130,69,66,87,108,89,75,51,29,49,117,135,108,101,115,107,128,118,135,163,129,117,104,92,81,57,44,40,32,25,25,19,21,45,73,61,38,23,39,82,92,64,17,44,113,127,125,79,61,108,108,88,42,78,108,75,39,25,89,114,88,48,34,33,32,36,33,29,39,19,46,207,249,248,248,180,141,151,153,181,165,156,149,132,132,147,153,167,177,127,59,27,29,25,29,27,22,27,25,22,23,27,19,23,22,23,24,23,22,22,26,22,25,21,21,18,20,18,17,22,16,48,68,50,31,17,15,18,20,33,51,52,53,60,60,70,83,88,96,96,83,76,69,75,75,75,80,73,68,61,64,54,44,36,23,30,35,49,112,113,122,101,53,96,120,96,64,39,78,106,98,111,126,135,146,97,120,69,54,34,39,58,132,225,233,243,242,239,241,235,238,237,236,237,237,237,240,238,236,238,238,234,235,233,233,233,233,234,231,232,234,233,232,232,232,233,230,229,231,230,229,229,227,229,229,227,229,227,226,225,225,230,225,228,228,222,117,4,0,4,8,10,9,10,10,11,11,12,11,200,201,200,199,200,201,200,199,199,201,204,202,201,201,200,200,203,202,204,204,200,203,205,203,203,204,206,205,207,206,207,210,205,205,207,206,208,206,208,207,205,206,204,205,203,204,207,206,204,204,204,203,205,207,206,205,207,207,208,206,205,206,205,205,205,205,207,207,205,203,205,203,204,203,206,208,206,207,206,208,206,206,206,206,206,208,208,210,209,208,211,208,210,208,208,209,208,211,210,209,211,212,209,210,212,212,213,211,211,211,212,213,212,211,212,210,211,212,210,210,210,211,213,212,212,213,212,212,214,215,213,214,214,212,214,214,213,213,214,214,214,214,214,214,214,216,214,214,214,213,214,214,214,215,213,214,213,214,215,213,212,214,214,211,212,211,212,211,211,212,212,213,213,216,211,212,212,211,213,211,213,211,212,214,214,211,211,212,214,214,212,215,214,212,213,211,212,214,215,213,214,214,213,216,215,217,217,217,218,217,217,216,216,214,214,214,214,214,215,216,217,213,214,214,214,217,214,216,215,215,217,216,218,218,217,218,219,220,222,220,222,224,218,222,222,224,224,223,225,223,224,224,225,224,224,226,224,226,223,224,226,224,223,223,227,224,212,206,221,231,228,212,220,234,231,221,218,229,233,232,234,234,233,235,232,232,231,231,233,232,234,233,234,235,234,235,236,236,236,234,236,236,237,237,237,236,236,236,236,237,236,236,234,237,236,235,236,234,235,235,235,236,238,243,246,247,247,241,234,206,180,165,102,49,42,145,211,210,228,139,125,221,244,251,233,215,232,239,202,195,236,187,205,235,234,249,162,150,122,99,61,64,219,244,246,238,213,205,238,247,222,214,228,229,224,227,224,237,200,198,170,174,232,188,196,187,234,188,107,179,164,165,182,167,172,197,217,183,205,196,228,178,171,98,74,236,237,251,181,62,98,115,92,49,7,77,124,177,237,251,166,91,202,212,222,200,180,197,209,199,196,151,159,249,192,86,95,174,244,224,194,216,169,106,165,238,238,236,233,233,227,214,229,247,183,188,241,231,234,235,238,252,181,96,98,94,127,72,37,27,66,128,113,65,28,43,44,36,40,53,106,139,136,70,83,113,105,139,95,69,68,42,33,24,19,22,26,55,68,38,24,19,13,24,63,96,94,87,57,60,107,105,72,25,63,123,122,122,129,127,113,108,96,38,72,110,84,43,39,95,100,83,44,29,35,33,29,37,29,39,15,88,250,250,249,249,172,152,157,160,174,152,143,143,137,145,158,160,171,168,102,35,26,29,27,27,31,23,17,26,25,26,24,24,27,20,25,24,23,22,27,26,22,24,21,25,23,23,26,23,21,24,58,71,51,33,18,21,29,54,63,57,64,63,50,30,20,24,32,45,65,77,81,87,81,74,69,63,64,75,80,76,78,66,64,55,51,45,54,120,122,117,102,60,96,118,84,57,35,93,124,113,120,85,66,67,105,155,122,79,56,47,51,107,214,231,237,244,235,237,236,237,236,236,236,236,238,238,240,238,233,234,233,233,233,233,232,233,232,231,230,231,233,233,230,231,229,230,231,232,230,227,230,227,228,226,225,229,225,227,226,226,227,228,229,225,224,116,3,0,4,8,10,9,10,10,12,11,10,12,199,203,197,200,201,198,199,198,201,202,201,203,203,202,204,199,201,203,203,204,203,205,205,204,204,205,204,203,206,202,205,205,205,207,204,206,204,205,206,206,205,205,202,206,202,202,204,203,203,202,205,203,205,203,205,204,203,205,202,204,202,201,204,202,204,207,206,204,204,202,202,203,202,204,204,203,202,203,203,203,208,206,207,205,205,207,205,208,206,207,208,207,210,209,208,210,209,205,208,211,208,208,208,209,209,208,211,211,209,209,211,211,211,210,211,210,208,210,211,209,208,209,212,211,210,211,212,212,211,212,213,212,213,213,213,213,215,214,214,214,213,216,212,211,213,214,214,214,214,213,213,212,215,216,211,214,214,212,215,212,212,212,210,214,211,210,211,210,210,208,211,212,211,211,212,214,212,214,214,211,213,214,213,212,211,212,212,211,213,214,212,212,212,211,212,213,212,214,214,214,212,211,213,212,213,215,214,215,215,214,214,213,214,214,214,214,213,215,214,214,214,215,213,214,217,212,215,217,216,216,216,217,217,217,216,215,218,219,221,220,220,219,221,222,222,222,221,223,222,223,223,222,221,222,222,223,223,223,223,222,223,222,222,223,222,218,208,205,224,231,217,210,225,232,226,217,225,231,231,231,232,233,230,232,232,230,230,232,230,230,231,230,233,232,233,233,232,236,236,236,235,236,234,234,235,235,234,235,235,233,234,233,232,234,235,236,234,235,235,237,238,244,249,249,246,234,211,180,166,170,194,226,174,89,127,212,191,212,224,132,129,221,237,238,202,184,222,235,196,196,229,184,213,236,235,248,175,169,141,113,60,65,219,244,251,238,198,214,251,251,222,211,226,227,223,226,221,236,203,191,158,147,207,185,190,166,178,163,141,189,162,185,212,190,189,215,214,192,211,196,230,174,186,104,73,235,227,247,176,56,89,118,106,56,27,49,56,146,230,251,144,83,198,212,227,191,144,170,208,157,129,141,168,243,158,88,98,147,237,213,205,241,181,101,171,246,237,235,232,230,229,216,229,239,175,203,239,231,237,231,245,252,219,127,87,103,131,101,62,23,35,93,128,114,67,49,49,49,76,108,131,136,78,28,93,107,116,121,53,21,15,17,20,20,11,19,59,92,96,77,43,21,21,23,68,114,122,131,122,103,108,100,74,27,64,116,94,88,88,116,132,104,89,42,34,70,100,81,79,103,93,64,33,34,32,34,34,29,37,41,39,161,234,249,250,234,166,149,155,149,163,174,191,163,139,153,152,155,170,150,82,19,26,27,29,27,26,22,23,26,23,24,26,22,23,24,26,23,23,24,23,26,25,25,24,22,25,22,24,30,19,33,58,66,48,34,20,31,62,67,71,60,46,42,39,34,22,16,17,35,56,44,33,38,48,61,71,77,69,67,67,63,61,67,83,89,91,79,96,134,124,117,107,70,97,110,88,56,34,89,133,131,93,56,39,29,57,113,122,90,54,55,54,89,207,231,234,240,233,238,231,233,236,236,237,235,236,236,238,235,235,235,234,236,233,232,232,232,233,231,230,232,231,231,230,231,227,228,227,227,230,228,228,226,226,226,224,223,224,225,223,224,225,222,226,225,222,118,3,1,6,9,9,8,10,10,11,12,12,12,195,199,199,198,200,197,198,199,200,199,200,200,199,200,201,201,205,200,200,202,204,205,203,203,205,203,203,202,203,204,201,205,202,205,205,203,205,201,202,202,203,206,203,204,204,201,202,203,201,203,206,203,204,204,204,202,202,203,201,201,203,202,204,204,203,205,205,204,204,205,205,202,205,206,203,203,203,202,203,205,205,206,206,205,205,204,204,206,206,205,206,205,206,206,206,207,207,206,207,208,208,207,208,208,210,209,209,210,209,207,209,208,208,210,211,209,208,210,210,209,211,210,211,209,211,212,209,207,210,211,211,212,214,212,211,212,213,212,211,213,212,212,214,214,214,212,210,209,210,211,209,210,211,211,211,213,213,211,210,212,211,213,211,210,211,210,208,208,212,209,210,210,208,210,211,214,212,210,212,211,211,212,211,210,209,211,213,211,211,210,211,212,208,210,214,211,212,212,212,212,211,214,211,211,213,213,213,213,214,214,212,212,215,214,214,213,213,211,213,214,211,213,216,215,216,217,216,217,215,215,215,219,217,215,217,217,217,217,220,219,220,221,219,221,219,221,221,218,220,218,220,221,221,221,221,221,219,221,220,219,220,220,221,223,221,216,206,209,226,224,211,211,226,231,222,216,227,229,229,229,231,230,229,231,229,231,231,229,230,227,230,228,228,230,230,232,232,232,233,233,234,231,234,235,231,235,234,234,233,232,233,232,234,234,232,234,237,237,243,247,248,246,239,215,184,166,170,184,200,218,236,252,205,115,167,238,227,242,226,116,110,201,219,222,196,191,222,236,193,196,230,186,220,245,251,252,191,181,144,117,63,60,217,244,249,192,142,171,231,249,221,210,224,228,226,228,219,236,209,214,178,137,189,180,174,154,162,164,191,188,171,204,213,187,164,217,207,188,207,194,226,165,187,90,75,231,226,247,167,54,81,110,98,59,33,40,12,89,199,246,148,81,190,206,238,192,103,174,177,95,143,168,213,195,80,100,123,119,205,209,219,235,172,108,169,235,232,238,230,230,233,215,230,228,170,219,239,233,236,241,251,251,212,81,57,87,136,135,95,45,22,50,100,133,147,138,112,122,139,153,140,82,27,17,105,109,113,116,37,21,21,20,19,17,26,42,93,125,132,128,80,39,31,25,66,101,91,93,101,125,117,93,80,24,54,104,92,45,10,39,75,101,95,60,26,33,91,122,118,118,83,50,44,47,59,57,65,64,72,50,87,239,251,245,250,246,162,153,148,144,164,206,231,170,138,146,147,166,171,134,73,43,43,41,41,38,35,32,36,37,33,34,29,25,27,27,29,27,24,24,22,26,25,24,22,23,23,22,24,25,22,36,66,64,43,24,27,56,65,55,54,68,63,37,22,23,21,21,53,85,90,66,45,51,42,21,23,36,48,57,68,73,70,66,71,72,79,95,104,106,101,118,112,74,87,116,94,67,36,63,122,141,121,65,64,81,70,105,118,99,60,48,54,85,206,232,233,242,234,239,230,232,236,236,236,236,237,235,236,236,236,236,235,236,233,233,233,233,233,231,232,231,231,230,231,231,228,229,227,228,229,227,227,225,226,226,225,226,224,224,224,222,224,225,224,224,224,118,3,1,5,8,9,9,10,10,11,12,12,12,193,200,194,198,198,196,196,198,197,194,198,199,197,199,199,198,202,198,199,202,199,201,200,201,201,202,203,202,203,201,205,203,204,205,203,203,200,204,203,203,205,202,203,207,203,204,202,205,206,202,203,203,203,205,206,206,203,204,204,206,204,201,205,203,204,206,204,206,205,203,204,205,204,203,204,204,202,201,204,204,205,202,204,205,202,204,204,207,205,203,205,205,204,203,204,205,202,203,206,206,208,208,208,208,207,206,207,207,206,205,205,207,210,208,208,208,207,208,209,208,208,208,208,210,210,210,212,210,209,210,209,210,210,208,207,210,212,210,210,210,211,211,211,214,212,212,212,207,208,210,212,207,206,211,207,210,211,209,211,210,210,210,209,208,209,208,207,207,209,208,211,209,209,208,208,210,206,207,208,208,210,211,210,211,210,212,209,210,213,210,209,211,211,211,210,212,213,210,213,212,209,210,211,211,211,212,212,211,213,213,212,213,212,210,213,213,210,210,211,212,212,213,212,212,215,213,213,213,215,216,214,215,216,216,218,216,217,217,217,217,217,218,217,215,217,218,216,218,218,218,218,219,220,218,218,218,220,218,218,216,218,217,217,222,216,210,202,212,228,216,203,218,228,225,217,220,229,229,229,228,228,226,226,227,226,229,227,227,226,226,227,225,229,227,230,231,230,229,227,229,229,232,231,231,232,234,231,232,231,229,230,229,232,234,237,240,243,247,245,237,216,191,170,168,181,197,217,230,239,242,248,252,188,83,166,247,219,247,186,95,129,217,242,247,226,216,240,241,194,205,235,192,227,249,253,253,187,160,125,97,55,58,210,243,246,127,36,65,164,238,224,210,226,225,226,227,222,232,206,191,170,167,207,194,181,205,167,173,213,179,184,203,205,141,114,213,190,183,199,195,224,162,188,83,89,235,228,247,168,56,74,110,97,56,33,42,18,48,181,243,161,126,196,214,244,189,152,217,196,141,173,196,200,158,86,177,196,116,163,178,218,221,143,113,181,230,232,236,233,230,235,224,235,211,173,229,237,232,240,250,250,248,122,34,29,65,118,137,138,80,47,32,44,98,141,160,142,131,129,146,135,66,13,41,128,96,125,99,34,28,12,23,30,27,38,80,114,105,100,120,114,77,36,25,70,86,68,38,36,66,89,92,74,25,43,97,94,67,35,16,61,113,135,104,71,72,108,128,123,131,119,107,113,127,133,139,125,131,128,68,148,234,250,249,252,234,159,150,152,177,212,232,202,140,131,139,158,191,177,125,84,79,72,69,74,69,66,57,57,64,59,56,57,53,47,50,45,41,39,39,35,31,31,32,26,25,27,25,24,18,22,50,69,60,39,26,36,60,67,49,56,76,69,46,24,26,33,50,86,124,129,95,76,58,32,26,21,38,69,61,42,36,38,52,67,84,94,86,83,90,108,117,104,72,79,123,122,81,46,38,74,136,149,150,141,103,88,119,122,92,61,47,50,98,211,233,234,245,236,235,233,235,235,234,236,235,235,235,234,234,235,235,235,233,232,232,231,230,232,231,231,232,231,228,227,229,228,228,227,226,227,225,227,229,226,224,225,226,225,225,224,222,223,224,228,225,222,117,5,1,4,8,10,9,10,10,11,11,11,11,197,198,197,195,199,197,197,199,198,195,197,201,198,199,200,197,200,198,200,200,198,201,201,200,200,201,204,202,205,203,201,203,199,201,201,202,203,202,206,201,203,203,201,200,205,206,202,205,203,203,203,203,205,205,206,204,206,205,203,203,207,203,202,203,204,205,204,205,204,201,203,204,206,203,202,205,203,201,202,203,202,201,204,203,202,205,206,202,203,203,203,203,203,205,204,204,205,202,204,204,204,205,207,207,206,206,206,206,208,204,206,206,204,205,205,205,206,207,206,207,207,205,208,207,207,208,207,208,209,208,207,209,209,207,208,210,209,207,208,209,208,208,209,209,208,210,210,212,208,208,208,208,210,208,209,208,209,208,206,211,206,206,208,206,207,210,210,207,209,208,209,210,208,208,207,208,209,206,208,207,208,210,208,211,211,210,210,209,211,210,210,212,209,211,211,212,212,211,211,212,211,211,210,211,213,210,212,211,211,213,214,214,213,210,210,212,212,212,211,212,211,213,213,214,215,213,214,215,213,213,215,215,216,216,218,217,218,216,216,214,217,219,215,217,216,216,216,218,220,217,215,216,216,218,221,217,217,217,218,216,216,217,217,217,214,207,201,218,226,208,208,220,226,220,213,223,230,227,228,227,226,227,227,227,226,228,225,227,227,227,229,226,228,227,229,229,228,229,230,231,230,229,232,231,231,232,229,228,230,231,232,233,235,239,243,243,236,220,195,173,167,178,199,214,230,239,242,244,239,236,238,245,181,79,164,239,168,163,142,102,155,243,251,251,238,230,248,246,202,217,245,199,197,194,194,193,142,137,122,123,92,101,207,240,190,43,2,5,109,237,226,211,223,223,227,223,224,230,201,171,164,173,205,216,202,222,175,178,217,141,156,187,181,156,150,231,187,192,205,223,242,188,205,82,114,243,237,251,167,67,82,120,105,57,37,49,15,73,200,247,190,137,205,221,249,200,167,249,222,173,165,142,224,150,98,226,235,145,113,166,251,192,94,100,202,243,236,239,231,231,235,229,236,192,179,236,232,237,250,250,251,144,33,2,19,30,76,118,142,139,89,54,41,27,88,143,112,58,46,122,129,73,20,72,135,103,137,97,27,27,19,24,38,34,67,101,113,77,54,103,113,103,63,28,63,92,76,48,13,27,68,101,103,68,113,146,150,139,134,140,139,147,162,162,146,145,131,123,117,117,123,123,118,125,127,130,130,125,100,79,200,251,251,251,252,235,159,152,165,214,252,242,165,117,129,139,174,217,177,113,89,84,66,58,58,57,57,54,59,55,57,62,62,63,66,65,72,70,64,66,59,63,62,54,53,50,49,39,35,35,43,66,72,63,44,19,33,68,79,74,72,71,60,43,24,48,71,58,57,79,88,71,46,30,25,22,24,62,87,74,44,19,21,15,23,33,43,59,81,90,107,113,100,80,66,104,146,116,67,52,39,56,84,82,72,64,89,133,113,83,51,42,60,111,218,235,236,244,234,235,233,236,235,234,233,232,234,236,232,232,233,232,231,231,232,232,232,232,233,232,232,231,232,231,230,229,227,229,228,230,230,225,226,227,225,224,224,226,225,224,225,224,224,227,225,226,226,116,5,1,4,8,10,9,10,10,11,11,11,11,193,196,194,196,197,195,195,198,198,198,197,197,198,199,196,195,199,198,200,200,199,199,199,201,201,199,199,201,201,202,201,200,201,200,203,203,200,203,200,201,203,201,204,201,199,205,202,203,202,201,203,201,203,206,204,204,203,203,204,203,205,205,204,204,204,205,205,202,204,204,203,207,203,202,202,201,203,202,203,202,203,201,201,204,201,201,203,204,205,203,204,205,206,205,204,206,202,206,205,203,205,202,205,204,206,205,204,206,208,206,204,206,203,204,205,207,204,203,205,206,205,204,205,208,208,206,208,207,206,208,206,207,208,207,207,207,207,206,208,209,207,208,207,208,207,208,210,208,208,208,209,207,210,211,207,207,208,207,207,207,207,207,206,208,208,208,207,209,208,207,210,206,208,208,208,209,209,210,208,208,207,208,208,210,208,211,211,208,211,211,210,208,211,210,210,211,212,210,212,210,210,214,213,212,211,209,211,211,213,212,211,211,212,212,212,210,208,212,212,211,212,212,213,214,214,213,213,215,214,212,212,216,215,213,216,216,214,212,215,215,215,215,215,215,217,217,214,215,214,214,215,216,217,217,217,214,217,217,217,216,217,216,218,217,208,203,201,219,221,203,212,223,223,214,216,226,225,225,224,225,226,225,224,224,227,226,225,226,227,225,227,226,225,226,227,225,227,228,230,229,227,230,227,229,229,226,229,228,231,233,239,241,239,235,219,199,179,167,177,192,210,227,238,244,241,239,238,232,230,228,235,236,182,81,159,222,162,153,113,100,139,207,214,220,183,186,227,225,190,214,241,174,113,97,107,131,142,156,152,163,154,141,162,167,144,48,1,3,113,237,236,217,231,229,230,224,227,220,213,191,187,186,183,199,184,200,148,151,163,110,164,196,201,199,199,250,212,227,235,242,253,206,188,62,103,242,252,252,185,81,81,121,105,57,36,48,23,75,229,246,212,159,212,236,247,186,184,247,235,163,103,187,248,113,68,208,249,181,129,163,252,190,69,130,227,243,243,236,228,230,233,234,236,171,186,239,229,250,250,250,170,41,1,8,12,38,48,70,118,129,153,105,66,41,31,107,104,55,17,33,83,78,33,96,125,102,141,75,26,31,17,30,29,42,91,100,97,80,72,76,78,101,95,76,100,111,112,86,83,100,120,157,156,160,173,163,162,155,139,150,143,121,113,118,108,106,105,99,108,117,116,105,109,121,117,116,103,98,59,83,220,252,250,251,253,230,160,168,199,234,234,199,136,121,130,143,195,216,141,75,65,51,65,59,65,61,59,64,64,69,61,59,63,59,57,53,54,56,57,56,57,60,64,66,70,71,71,65,68,67,69,81,81,71,52,39,35,63,91,91,84,63,43,31,21,60,90,74,55,70,87,62,32,24,23,21,39,81,91,65,41,24,19,14,15,19,23,19,29,35,61,97,101,86,55,60,109,146,113,70,58,49,50,48,50,78,111,130,90,64,43,43,69,141,238,241,240,235,231,239,232,232,232,231,231,232,234,231,230,233,232,230,232,231,230,231,229,231,231,230,230,229,229,229,227,227,227,226,226,225,224,227,225,223,224,224,225,224,223,225,224,225,226,224,227,224,224,118,3,0,5,9,9,9,12,10,11,12,12,12,194,196,195,193,194,194,194,193,197,196,196,198,194,198,199,196,200,195,195,199,195,200,198,199,200,198,200,200,201,199,201,201,201,200,200,202,202,202,202,202,203,202,204,203,204,206,202,206,204,203,204,205,206,202,203,203,206,205,203,204,206,203,205,206,203,204,204,202,205,207,206,202,203,204,203,204,201,202,201,200,204,203,202,202,203,202,201,202,204,204,202,203,205,205,202,204,204,204,205,205,203,201,206,203,203,203,203,205,206,204,206,206,206,204,204,204,205,204,203,206,205,206,210,206,207,208,208,208,206,208,206,207,207,206,207,206,208,208,207,206,206,208,207,209,210,208,208,208,209,208,210,208,208,207,207,206,206,208,206,208,207,206,209,207,207,209,208,209,210,206,208,207,208,209,207,208,208,206,208,208,206,213,211,210,213,209,211,211,209,211,212,211,209,210,210,210,208,211,212,208,212,214,211,212,211,213,213,210,212,210,210,210,212,212,211,211,212,212,211,213,212,213,210,211,212,212,210,210,212,213,213,212,212,211,214,214,214,217,214,214,214,214,214,213,214,215,215,214,213,215,214,214,213,214,216,214,214,215,216,214,214,214,217,214,209,202,206,223,208,203,219,224,220,212,218,225,224,223,226,224,224,223,224,225,223,227,223,224,224,224,225,224,227,226,226,229,226,224,227,226,229,228,228,227,228,229,232,237,239,239,234,221,202,182,174,181,193,210,223,236,241,244,243,239,236,230,229,228,225,225,232,230,188,84,149,234,197,179,124,102,118,141,141,146,127,125,157,160,135,174,188,122,99,98,114,133,148,162,164,176,166,153,154,154,145,93,51,61,147,239,241,225,241,234,230,223,228,217,219,175,179,208,171,182,154,167,147,127,185,153,210,249,241,236,214,249,219,220,181,153,129,90,98,12,59,196,238,249,150,60,73,125,114,66,39,50,28,81,237,246,246,160,193,240,239,189,201,246,198,139,127,230,246,112,78,217,252,226,123,97,184,174,109,165,237,242,239,236,231,230,227,237,228,153,201,237,237,250,251,203,62,2,9,6,31,43,39,36,54,94,125,142,113,62,38,62,111,97,42,23,28,48,38,110,119,99,128,56,27,29,17,26,32,74,107,96,99,65,51,59,74,122,130,142,145,144,153,166,168,160,142,137,139,128,139,128,123,116,116,110,100,88,69,67,64,69,59,56,58,59,56,49,44,49,49,41,34,46,11,69,237,250,251,251,252,221,162,188,232,252,246,155,119,130,131,152,217,206,103,37,14,16,24,29,29,25,33,32,38,44,46,50,46,51,48,50,59,57,54,61,60,58,61,56,60,57,55,59,57,60,64,67,66,76,76,68,63,70,88,82,69,54,39,38,28,57,99,112,113,100,79,51,33,28,26,24,51,90,86,59,36,29,24,19,22,24,24,21,19,18,55,92,103,93,64,32,52,109,136,131,109,96,82,81,101,127,139,112,72,44,35,60,95,201,246,243,239,231,234,235,232,231,230,233,233,233,232,232,230,230,232,230,230,231,230,228,230,229,227,227,227,227,229,229,228,225,225,226,227,225,224,224,225,225,223,224,223,224,224,226,225,224,226,228,225,224,225,118,3,0,5,8,8,9,12,10,11,11,12,12,194,194,194,193,193,189,193,193,192,194,195,194,194,196,196,196,194,195,196,194,197,197,196,199,197,197,199,199,196,198,198,197,201,198,198,199,196,201,200,199,200,198,201,200,201,200,200,200,201,202,200,201,199,201,202,200,202,200,200,201,201,203,201,201,201,201,203,201,202,200,201,203,203,200,199,202,201,198,200,202,201,200,203,201,199,200,200,200,200,200,201,201,200,201,201,201,201,205,203,203,203,201,203,202,200,201,204,203,203,202,202,203,203,206,202,203,204,203,204,205,205,205,205,205,204,204,204,206,203,204,207,206,207,204,206,206,207,203,203,206,205,206,207,205,205,205,206,205,202,207,208,205,206,203,206,206,205,206,206,204,205,208,206,206,207,206,207,208,207,208,206,205,208,206,207,205,204,208,206,206,209,207,210,212,209,211,210,206,210,212,208,207,210,207,208,210,209,210,208,210,208,206,209,208,209,211,211,210,210,208,212,211,210,211,213,211,207,210,210,208,210,209,210,210,210,210,212,210,210,212,210,214,214,213,212,212,215,212,214,214,213,214,212,210,213,216,213,212,214,214,212,212,214,213,212,212,212,211,212,213,214,213,214,211,203,201,210,220,202,207,222,222,216,208,220,222,222,223,222,222,224,222,223,223,225,223,220,224,223,223,225,222,223,226,224,225,226,224,224,224,223,227,228,229,234,234,235,229,219,203,186,175,179,191,205,219,232,240,242,241,237,233,229,227,225,227,223,225,224,226,230,223,190,80,149,233,220,178,91,78,107,147,153,149,137,122,152,134,111,143,153,116,106,103,95,103,112,125,139,152,139,141,148,144,133,103,100,108,141,211,219,204,234,242,237,228,227,211,222,151,162,206,170,208,162,199,226,178,234,210,238,249,228,217,145,126,103,89,60,20,14,18,54,32,29,94,129,134,71,42,52,99,104,63,54,62,27,59,184,226,155,66,130,178,167,174,164,128,88,61,125,228,208,76,86,185,206,188,137,38,76,139,112,208,238,231,243,232,232,231,223,241,223,159,211,243,249,250,225,114,11,5,8,18,42,44,27,19,37,51,89,102,112,96,46,36,90,127,96,56,46,38,33,122,124,105,110,45,26,22,19,37,67,116,129,115,114,94,99,113,117,133,130,134,135,126,133,131,137,141,126,122,112,113,107,85,89,76,59,51,49,44,37,34,30,41,48,35,24,29,28,24,32,39,36,42,53,55,15,121,251,251,252,252,244,166,162,209,244,234,199,131,122,130,133,173,226,172,74,24,15,25,27,30,22,12,22,27,42,49,45,30,17,20,30,29,27,39,39,33,36,41,43,45,50,53,56,59,57,57,55,55,57,59,59,65,66,70,69,72,76,79,85,85,72,81,107,117,124,94,50,38,31,29,24,36,72,96,81,53,31,26,27,27,31,27,30,27,25,21,57,95,104,99,66,41,32,83,130,141,144,154,159,143,144,139,96,66,42,38,48,66,174,241,249,241,235,236,233,230,230,231,233,233,233,232,233,233,233,233,233,231,231,230,228,229,230,229,229,229,228,229,228,227,225,226,226,226,229,229,228,228,227,226,226,226,226,226,226,228,226,225,227,225,228,226,222,117,4,1,4,8,10,8,10,10,11,12,11,11,191,194,194,195,194,192,194,194,195,191,192,195,193,194,196,193,194,193,195,197,195,197,194,197,196,196,198,198,198,200,199,195,201,200,199,200,197,198,198,198,199,198,200,198,197,199,198,200,200,199,199,198,199,200,201,200,199,200,201,200,202,200,199,202,200,200,202,202,202,200,201,200,200,202,201,201,200,202,199,200,201,197,199,200,200,198,200,200,199,200,202,200,201,201,201,200,200,204,199,202,202,200,204,202,202,206,203,203,204,205,203,201,203,202,203,202,203,202,203,203,203,203,203,203,204,205,205,204,202,204,204,204,205,204,206,206,203,203,205,203,203,205,204,204,204,204,204,204,205,206,206,204,203,204,206,207,203,203,205,203,203,203,205,205,203,206,206,204,205,203,206,207,206,208,206,206,207,206,207,207,208,208,203,206,205,206,209,207,210,208,207,209,210,206,207,211,208,208,211,210,208,207,211,210,210,210,209,211,209,207,208,208,211,208,208,208,207,208,209,210,210,210,210,209,210,210,211,211,210,213,210,212,212,212,213,212,211,212,208,211,212,212,211,209,212,211,212,211,212,211,210,212,211,212,212,214,212,210,212,214,213,212,215,210,202,198,215,214,199,212,220,217,207,211,220,222,221,218,222,220,222,221,220,222,220,224,221,221,225,220,224,223,222,222,221,225,223,222,227,225,229,232,232,233,232,217,203,188,174,177,188,202,217,229,235,237,236,235,234,229,227,225,225,225,223,225,223,224,223,225,227,223,198,78,133,212,209,156,51,47,106,166,179,182,160,157,179,159,132,165,170,117,112,85,63,62,72,90,91,94,90,95,106,109,93,87,84,76,84,173,184,173,222,232,237,229,222,205,227,149,157,217,165,204,190,236,252,198,203,142,122,117,77,71,26,2,14,23,81,129,131,167,127,98,133,143,165,177,105,42,35,87,95,49,40,44,36,25,107,160,139,66,83,144,151,145,118,65,61,84,121,173,130,84,112,158,186,181,129,49,39,76,117,225,245,227,238,235,234,233,226,246,213,158,229,248,251,246,119,36,2,3,18,34,47,29,19,18,31,56,75,87,95,94,73,40,42,89,133,122,93,68,76,154,124,122,106,29,47,62,105,142,141,153,134,123,125,112,124,125,129,135,134,146,145,136,133,123,101,90,69,56,51,45,42,30,29,36,46,53,30,36,41,17,32,59,66,52,34,41,37,28,32,42,51,50,87,69,20,186,251,251,252,241,164,113,165,229,252,241,152,112,129,128,134,198,229,134,47,18,14,27,30,33,21,18,30,34,51,63,51,34,19,40,42,35,48,49,39,26,13,27,31,21,25,23,30,25,28,31,36,40,48,52,61,67,63,59,59,53,56,61,91,120,118,117,98,105,100,73,63,57,44,40,36,70,100,96,78,47,32,29,27,30,34,33,30,31,31,28,56,87,111,105,75,41,53,123,134,118,100,101,122,128,100,69,57,39,42,33,45,160,245,245,249,230,234,231,230,228,230,232,231,233,234,232,232,232,231,231,232,231,230,230,231,231,231,230,228,228,229,229,229,228,226,228,229,229,227,228,228,226,226,225,226,228,227,227,227,228,226,228,227,225,228,228,224,117,3,0,4,8,10,9,10,10,11,12,12,12,193,196,193,192,192,192,193,193,193,196,192,191,194,192,194,193,194,195,194,193,195,197,194,198,197,196,199,196,198,198,198,197,198,198,199,200,197,199,198,198,198,196,198,199,199,197,200,199,198,200,200,200,200,199,198,197,198,199,201,200,200,202,201,200,201,200,201,202,200,200,200,200,201,200,200,200,200,200,201,201,199,198,200,198,200,199,198,202,202,198,199,200,201,201,200,203,200,201,201,202,202,200,203,202,203,200,203,201,201,206,205,205,202,201,202,201,202,203,201,203,204,202,201,203,204,204,203,205,203,201,206,202,203,204,202,204,204,203,204,202,203,203,203,203,205,205,203,206,202,205,205,203,205,205,206,204,205,204,204,203,203,203,201,205,204,204,205,206,204,205,206,208,208,205,209,206,205,207,205,207,208,205,206,206,204,206,210,206,208,210,207,207,207,206,207,208,206,208,209,210,210,210,210,211,211,208,207,210,210,209,206,207,208,207,210,209,208,210,209,208,208,208,208,208,208,208,210,208,208,210,208,211,208,207,208,210,210,209,210,209,206,209,211,210,211,212,211,209,211,211,211,211,213,212,211,211,211,211,211,210,210,214,207,204,200,202,216,203,200,218,218,211,207,216,220,216,220,218,220,217,220,220,218,218,222,221,220,222,221,224,222,222,224,223,223,224,225,225,230,232,229,230,218,203,190,179,181,186,200,213,225,232,233,235,234,232,229,227,226,223,223,225,225,225,222,226,223,227,220,226,223,223,200,83,120,199,239,172,64,87,129,171,172,171,156,163,189,164,152,180,158,113,119,88,60,69,59,59,51,59,61,55,57,61,69,82,81,53,60,157,155,125,159,186,219,225,219,207,237,155,187,242,146,133,127,184,172,67,56,19,0,12,9,59,66,58,74,77,117,143,183,159,136,151,142,189,234,238,126,52,57,120,111,48,41,47,29,75,207,247,199,114,172,210,173,196,163,149,182,168,217,189,130,164,199,206,203,181,138,66,59,54,112,243,242,233,233,232,234,231,229,245,195,157,240,249,252,156,26,3,2,11,29,44,32,18,21,26,46,53,88,106,89,100,89,57,38,35,76,122,153,149,148,165,110,119,128,128,161,163,165,147,133,125,113,131,145,139,144,130,121,108,97,90,70,56,47,35,32,24,25,30,26,29,45,32,22,47,77,81,60,67,66,29,36,63,76,63,34,40,43,33,39,42,53,29,62,69,84,230,251,251,250,191,138,130,190,245,251,192,127,118,131,129,152,218,199,103,22,10,15,23,32,40,29,24,28,21,47,55,43,32,29,57,49,39,58,56,33,21,33,50,41,23,22,29,24,19,20,22,24,39,43,35,25,33,35,39,52,52,59,62,69,80,83,83,87,89,97,98,89,90,83,74,103,127,129,114,77,46,30,25,29,32,34,30,27,32,33,30,61,91,106,106,77,44,83,133,94,66,35,49,103,93,67,47,39,50,25,55,185,242,249,249,233,233,229,229,229,229,230,229,231,231,232,233,231,229,230,231,230,230,231,230,230,229,230,227,226,229,228,227,227,227,228,228,227,227,227,225,225,226,227,226,227,228,227,226,226,228,226,225,229,227,227,224,222,118,4,1,5,8,9,9,12,10,11,12,11,12,193,194,190,193,189,191,191,190,193,193,193,193,193,191,193,191,195,194,194,196,193,195,194,196,196,196,196,197,197,195,198,195,199,196,195,199,196,199,198,198,198,195,198,198,195,198,196,196,198,197,199,199,199,198,198,198,195,198,200,196,200,198,198,201,196,200,200,199,199,197,201,198,199,200,199,198,198,202,197,199,199,198,198,197,200,199,199,199,199,198,200,201,199,198,200,202,202,201,200,202,202,200,200,200,200,200,200,201,199,200,200,200,201,201,202,200,201,200,203,201,200,203,201,202,202,203,203,201,203,203,204,203,201,203,204,203,202,202,203,205,203,203,203,201,204,204,203,205,203,205,205,201,205,203,200,204,204,203,202,203,204,204,206,205,205,202,204,206,206,206,205,206,205,206,206,203,206,205,206,205,205,207,205,209,206,207,207,206,208,207,208,207,208,207,206,206,206,206,208,207,205,206,209,207,208,208,208,208,207,208,208,207,210,206,205,206,207,208,204,204,206,207,208,207,206,206,208,210,205,207,208,208,207,208,208,208,208,208,207,210,207,210,211,210,210,211,212,210,212,211,211,212,208,210,209,208,212,212,210,210,209,210,207,204,197,208,216,198,208,219,215,206,208,218,216,217,217,217,218,214,220,216,217,220,218,221,218,219,222,218,221,219,223,225,224,232,230,230,230,217,202,190,178,177,188,199,213,223,228,234,233,232,229,226,224,223,223,222,224,223,221,223,225,226,222,226,223,222,219,227,217,223,196,65,121,212,252,217,136,139,151,171,159,152,146,168,191,158,130,149,141,116,132,107,87,84,57,53,48,63,65,55,49,53,66,90,73,47,73,150,131,76,90,132,197,229,214,211,239,170,194,252,134,45,20,23,27,9,40,66,78,117,137,178,180,189,191,143,134,130,144,141,99,95,84,102,146,172,107,37,41,109,117,57,57,57,33,47,146,181,131,71,121,144,120,146,141,145,156,122,127,117,83,136,123,118,149,129,150,136,79,51,134,243,246,232,230,231,234,232,230,245,182,188,248,248,188,49,2,12,5,28,42,36,24,21,27,45,56,54,83,114,102,88,99,87,59,46,39,43,64,75,109,141,95,137,157,133,157,139,149,141,129,137,130,127,111,76,55,43,39,31,28,37,44,32,21,27,19,18,27,38,41,49,78,55,30,42,81,96,56,64,82,63,57,75,77,49,25,29,46,55,56,49,51,48,53,50,140,243,251,251,241,186,161,153,214,250,224,147,113,123,139,131,175,237,164,83,70,57,55,55,50,49,45,35,34,29,29,60,56,52,56,47,33,30,51,51,38,33,48,54,29,22,27,27,26,19,24,31,46,65,64,45,26,16,29,32,31,41,35,36,40,51,62,76,84,87,81,76,79,83,94,103,110,114,105,104,92,66,54,50,41,39,34,31,33,29,35,30,60,96,103,105,83,47,41,58,57,46,55,91,95,75,49,44,50,28,116,239,249,249,250,236,232,233,233,227,227,228,229,229,230,231,230,230,231,231,230,232,230,230,231,230,231,229,229,231,229,229,229,227,227,227,228,227,227,227,227,226,226,228,227,228,227,228,229,226,227,229,222,225,228,226,228,226,224,118,4,1,5,8,9,9,12,10,11,12,11,11,189,192,193,192,194,191,188,190,190,191,189,189,194,189,191,191,192,193,191,193,193,194,193,193,195,197,197,194,194,195,197,195,196,196,198,196,194,199,195,196,198,198,196,195,195,193,196,195,195,197,195,195,198,196,197,198,199,200,199,199,197,197,199,198,198,198,198,199,196,196,198,199,199,200,199,196,198,196,200,199,196,198,201,198,198,198,196,198,196,197,198,198,197,198,199,199,198,200,200,199,200,199,200,199,201,200,201,200,198,203,200,199,200,201,199,201,201,202,200,199,201,201,200,201,201,199,200,202,200,201,203,202,205,203,202,202,204,202,204,203,199,206,203,201,203,200,204,204,201,201,200,201,203,202,201,202,205,204,203,203,205,204,205,207,205,203,203,206,205,206,206,205,207,204,206,205,205,205,204,203,203,205,207,206,207,208,206,205,205,205,202,205,207,205,207,207,205,205,206,206,204,207,207,205,206,206,206,207,204,207,207,207,205,205,205,204,206,204,207,206,204,206,205,206,205,207,209,204,206,206,205,206,206,208,206,205,206,206,207,206,208,209,207,208,208,207,208,206,209,208,210,209,209,208,207,210,209,209,209,207,211,212,205,207,202,220,218,202,214,217,208,205,211,214,215,215,213,213,215,215,217,217,217,218,217,217,219,217,218,219,221,224,226,230,230,228,218,204,194,181,177,185,195,209,220,226,229,230,231,229,225,222,222,222,219,222,223,220,226,223,223,223,221,223,220,223,219,222,218,227,216,222,178,51,93,194,251,208,143,152,167,176,164,161,142,146,173,138,105,132,139,121,128,95,83,71,50,60,49,47,54,56,61,66,70,85,75,48,57,113,111,107,148,180,217,233,207,218,241,159,191,239,141,95,115,105,76,97,198,216,223,247,237,247,225,252,232,215,229,225,227,99,96,160,139,173,184,213,134,45,39,89,113,54,43,48,28,45,114,153,141,81,72,99,124,158,133,134,115,86,120,51,43,131,132,122,138,131,160,160,111,45,119,234,237,240,229,228,235,224,239,237,183,220,250,181,79,7,5,7,16,43,42,25,25,26,46,50,59,53,29,76,106,94,92,102,103,75,57,48,41,21,57,112,101,132,139,133,139,127,120,87,77,53,34,39,49,36,33,34,30,17,29,58,62,50,31,35,33,18,30,46,40,45,72,81,62,72,93,79,48,37,77,110,143,131,91,81,83,100,103,113,123,114,120,118,131,116,100,206,243,243,244,207,154,125,197,251,193,133,120,131,133,139,201,226,127,72,124,136,156,64,91,69,63,67,61,57,58,57,71,73,57,50,43,42,55,67,63,57,46,36,22,22,27,25,29,32,27,24,43,65,62,42,25,32,57,48,49,59,56,36,18,19,30,32,31,45,48,61,78,81,85,80,79,74,77,87,93,91,91,84,73,68,63,51,46,39,34,29,59,93,101,110,80,51,35,30,46,66,101,101,83,54,44,54,66,186,248,248,251,251,238,234,234,230,226,229,228,230,230,228,232,233,233,231,229,229,231,231,228,229,230,228,231,231,231,230,229,228,225,228,228,227,228,228,228,229,229,229,229,227,229,227,228,227,229,229,226,229,229,228,228,226,228,227,225,117,4,0,5,10,10,8,10,10,11,12,12,12,189,191,193,193,192,191,190,190,192,191,191,192,192,193,195,191,193,189,189,193,192,194,193,192,191,193,192,192,193,193,195,194,195,195,196,196,193,194,195,198,196,195,196,195,196,198,194,194,195,194,196,195,195,196,198,197,197,199,197,196,198,195,196,200,197,199,198,198,198,196,200,198,196,194,196,199,198,200,198,198,198,198,200,196,197,198,196,197,196,196,198,198,198,197,198,199,200,199,198,200,201,200,201,198,199,201,200,201,201,203,200,200,201,199,201,200,203,199,199,202,199,200,197,199,200,199,200,200,202,200,200,201,200,202,201,204,205,203,204,205,204,201,203,202,203,199,202,203,200,205,203,203,204,202,204,203,202,204,204,204,203,203,203,203,205,202,203,204,203,204,205,205,204,206,206,204,205,203,205,205,205,207,204,205,205,205,205,205,207,203,204,205,205,204,203,206,205,205,203,205,205,203,206,204,205,205,204,208,206,206,205,203,206,203,204,204,204,205,204,203,203,203,203,203,204,206,204,205,205,205,205,205,205,206,207,205,207,207,207,208,205,206,207,207,208,209,207,208,208,208,208,205,207,208,208,207,209,208,207,208,210,206,214,212,217,244,219,206,216,214,208,205,213,213,213,216,213,214,216,213,218,215,217,219,217,220,217,221,224,225,228,225,227,217,200,194,180,177,184,191,205,218,225,227,230,229,228,225,223,225,223,224,223,221,218,222,224,222,222,223,224,223,222,224,223,221,221,222,222,227,213,217,168,42,78,173,241,210,147,166,170,183,178,176,162,159,165,132,135,163,141,117,77,20,26,34,29,33,29,33,31,36,32,46,65,66,63,37,33,77,105,166,238,250,244,226,205,224,240,168,191,234,171,203,238,203,185,186,249,247,247,251,236,244,236,247,213,200,192,227,181,105,131,177,188,227,244,252,193,80,79,108,115,52,33,44,25,81,214,247,227,146,131,196,251,251,201,160,151,181,221,103,71,222,237,242,224,186,223,191,163,69,94,216,224,238,229,225,236,225,242,231,185,249,220,97,27,1,11,11,39,47,22,23,26,39,51,61,54,12,79,111,108,94,83,111,107,122,99,70,66,32,83,119,103,139,121,66,50,34,29,33,34,24,16,44,68,60,49,60,53,30,21,55,84,53,24,34,43,46,49,52,48,50,68,111,156,171,170,142,137,153,155,153,162,164,145,143,137,139,125,110,93,77,71,62,63,56,52,22,115,217,250,234,144,87,174,245,167,128,128,133,136,149,229,207,89,51,35,29,43,42,41,38,39,42,43,44,48,50,49,59,63,65,69,69,69,69,73,65,58,56,51,48,42,40,47,36,31,27,32,56,54,44,46,59,60,47,55,61,51,36,25,44,50,30,34,33,30,29,26,32,42,52,66,74,84,85,81,79,80,86,100,111,101,93,79,63,61,50,71,96,99,115,85,57,58,81,116,133,118,81,54,38,45,93,221,245,250,250,248,239,233,234,231,226,227,226,230,230,230,230,229,231,232,231,231,229,228,231,229,228,228,228,228,229,227,227,230,229,228,229,229,230,228,229,229,228,230,231,229,229,231,232,230,229,229,230,229,229,227,230,230,227,230,230,226,117,3,0,4,8,9,9,10,9,11,11,11,11,190,193,194,192,195,191,190,191,191,193,192,190,192,191,192,191,193,192,190,193,194,191,191,193,193,192,193,194,194,194,196,195,193,194,197,195,192,194,194,194,195,194,194,195,195,194,193,196,194,195,199,194,198,197,196,195,195,196,194,198,194,196,198,193,199,196,193,194,196,195,196,195,194,195,196,198,197,198,196,198,196,198,197,195,200,196,196,196,196,197,195,198,198,196,195,198,197,198,199,198,200,198,199,198,197,197,198,197,198,199,200,199,198,201,198,200,199,198,198,199,199,200,200,201,201,201,202,199,199,200,200,199,201,201,203,202,201,200,202,202,201,204,200,200,203,201,200,200,202,202,202,203,201,201,203,200,201,202,201,203,202,203,201,203,205,204,204,203,202,205,205,203,204,202,206,203,204,203,206,206,205,207,205,204,202,202,203,205,205,205,203,204,204,204,205,205,202,203,205,203,205,203,203,202,204,204,202,202,202,206,203,203,203,202,204,202,203,203,203,201,202,201,202,203,202,206,205,203,206,204,203,203,202,204,204,206,203,203,205,205,203,206,205,203,206,204,207,206,206,206,205,206,205,205,208,208,204,206,207,205,207,204,212,201,137,184,190,202,215,212,202,206,211,212,213,214,213,213,214,214,215,215,213,217,220,220,223,224,226,226,218,205,195,182,175,180,190,201,214,222,223,228,227,223,224,220,220,220,221,221,222,222,220,223,223,222,223,220,222,223,224,221,222,223,222,221,222,222,222,226,214,218,149,51,103,196,252,227,156,161,175,184,172,168,158,162,187,160,165,184,149,64,4,1,17,32,21,22,25,26,22,22,27,53,58,63,41,44,73,128,167,196,234,234,234,217,200,227,233,159,208,239,152,210,243,201,194,217,249,230,234,221,213,175,189,186,140,145,148,231,160,88,150,171,171,215,224,251,189,72,68,94,121,54,32,35,14,84,227,246,242,164,128,234,252,252,178,174,187,213,222,118,163,249,250,251,212,204,240,228,214,85,91,206,212,230,232,222,236,224,249,229,195,245,119,20,15,1,22,32,46,29,22,26,36,53,52,61,19,85,219,178,122,89,67,89,94,103,109,107,108,99,134,128,123,124,52,23,19,17,14,29,69,45,18,46,78,85,59,61,74,55,44,74,83,48,42,46,66,103,140,157,165,190,121,180,200,198,187,169,147,131,117,88,65,53,43,45,39,37,36,29,29,29,25,23,19,24,21,27,15,109,158,203,143,91,185,234,150,130,126,140,140,174,234,169,61,21,10,10,20,14,18,17,15,21,19,24,18,22,27,29,27,34,36,36,44,42,46,51,57,60,64,63,63,69,69,61,54,54,47,56,73,61,59,57,38,30,48,55,39,33,53,62,54,36,42,39,34,31,19,22,33,46,53,50,42,46,61,68,75,74,71,74,83,97,101,100,97,89,94,103,100,116,96,108,155,165,164,116,71,48,37,41,100,216,249,249,250,239,237,233,233,228,225,226,228,231,230,228,229,231,228,228,228,229,230,229,230,231,228,228,229,228,228,228,230,228,229,230,229,229,229,228,230,229,230,233,231,229,231,231,230,229,230,233,229,228,227,231,228,226,227,229,231,229,227,118,4,1,5,8,9,9,10,10,11,12,11,11,193,190,191,190,192,190,190,194,192,192,192,191,192,192,192,192,194,191,190,192,190,190,192,194,195,196,195,196,195,194,194,193,196,193,193,194,191,193,192,191,195,192,193,197,193,194,194,196,194,195,198,193,193,193,195,197,195,197,196,196,196,194,196,196,193,194,196,197,196,194,195,194,194,197,197,197,197,197,195,196,197,198,198,196,196,196,195,194,196,197,198,198,198,199,198,198,196,198,198,197,196,196,198,199,200,198,197,198,198,198,199,198,198,198,197,199,198,197,201,199,199,203,200,201,201,200,200,198,198,200,202,203,200,202,200,197,199,198,201,203,200,201,200,200,202,199,201,199,199,201,199,202,201,200,200,202,202,200,203,201,201,201,200,204,204,203,203,205,205,203,204,205,204,204,203,204,205,203,208,207,204,204,202,203,202,201,203,202,204,202,203,203,200,202,203,205,201,203,200,203,204,202,202,200,203,205,201,201,200,200,204,201,201,200,200,203,202,201,201,201,202,202,202,201,202,202,202,203,201,204,203,202,204,203,205,203,202,204,203,205,204,204,205,204,205,204,205,206,207,206,206,204,205,203,206,207,205,208,207,206,208,197,209,129,45,86,156,210,215,204,202,206,213,212,211,210,207,210,212,211,214,215,217,220,223,223,222,214,201,192,184,174,181,189,200,215,220,225,226,224,225,223,221,220,217,215,219,218,221,221,219,222,221,222,222,222,221,221,222,220,220,222,222,222,223,221,224,220,223,222,215,207,146,55,119,217,252,230,158,159,155,170,165,162,154,175,200,164,171,183,130,62,11,2,24,38,30,28,33,25,29,35,33,54,59,53,30,64,124,199,239,214,229,235,230,214,204,229,227,158,196,211,166,206,199,158,152,212,230,197,185,171,155,141,184,170,167,174,198,252,116,112,181,164,167,206,224,240,182,66,49,71,116,73,32,40,13,61,222,239,216,154,107,213,251,163,117,173,206,189,164,149,213,249,238,242,171,184,228,200,221,127,76,180,211,216,241,231,237,228,252,228,187,162,28,2,16,14,42,45,36,17,24,39,52,54,63,23,67,208,252,203,145,110,57,69,65,82,71,80,89,91,142,132,136,120,33,15,19,19,17,35,86,78,42,41,85,83,41,29,51,92,126,146,144,151,171,190,200,202,200,191,179,168,142,123,102,72,59,40,31,25,16,22,22,16,18,22,15,21,20,22,18,17,23,15,21,20,23,14,27,10,48,144,136,112,205,207,135,139,133,142,147,201,237,128,40,23,8,9,14,13,17,14,15,15,14,17,18,14,17,19,14,16,15,21,20,14,19,21,24,28,28,35,37,46,46,49,59,56,57,65,67,70,71,61,52,49,57,69,64,67,62,46,29,26,39,35,31,28,39,38,53,78,76,66,41,24,24,34,36,46,61,70,77,89,88,83,86,95,106,96,94,108,97,95,109,95,66,55,42,45,61,73,179,242,249,249,237,236,229,231,231,226,226,231,231,229,230,229,230,233,230,229,229,228,229,226,228,231,229,230,228,228,229,228,231,228,230,231,229,231,231,231,232,232,231,231,231,231,230,231,230,230,229,231,230,229,229,229,229,229,229,228,230,229,226,118,3,1,6,9,9,9,10,10,11,12,11,11,191,193,193,192,194,193,188,192,190,190,191,191,192,188,190,188,188,191,193,189,192,193,193,193,191,196,193,191,193,193,194,191,188,192,194,192,191,192,193,191,193,193,193,193,192,196,192,193,193,191,194,193,194,192,191,193,193,193,193,196,193,195,195,192,195,193,194,196,195,193,194,194,194,194,195,196,193,198,198,196,196,197,196,196,198,195,198,196,195,198,198,195,196,194,196,198,193,197,196,195,195,194,198,196,196,198,198,198,198,197,197,196,196,199,196,200,200,199,199,198,200,198,198,199,198,200,199,198,198,200,200,200,203,199,200,201,200,199,202,200,199,199,200,200,202,202,199,203,199,196,201,198,200,201,200,201,200,202,202,200,200,202,203,201,202,200,200,200,202,203,202,201,201,200,202,204,202,203,205,203,202,201,201,202,203,200,201,200,200,201,200,203,203,200,200,201,199,200,200,199,202,200,202,202,200,200,200,200,200,199,200,199,200,201,200,199,199,200,200,199,199,201,203,201,201,200,200,200,201,202,202,203,199,202,201,200,201,202,205,205,205,205,205,204,206,204,205,205,204,204,202,204,203,203,204,206,204,206,206,208,207,203,191,100,23,77,181,214,214,203,201,211,210,214,210,207,211,212,213,216,220,221,219,222,212,199,192,181,177,180,186,196,210,216,223,227,223,225,220,220,219,219,220,217,219,219,218,218,220,222,222,221,220,220,221,219,220,221,221,222,223,222,221,222,223,221,224,220,224,218,212,207,126,61,135,217,252,229,155,157,160,173,163,166,184,179,179,136,156,162,163,156,110,123,130,100,29,21,47,33,33,29,43,80,67,67,74,99,173,231,234,208,219,230,220,206,209,234,223,148,179,186,163,203,180,106,107,187,160,160,153,162,186,189,231,212,217,197,232,217,58,136,191,161,165,199,232,240,183,68,43,68,125,79,32,50,18,66,233,241,214,156,103,210,200,122,129,196,198,150,146,164,236,245,236,240,168,198,207,187,224,189,90,116,196,206,229,227,229,240,253,220,127,66,1,15,21,22,53,33,20,22,27,50,51,66,29,42,186,245,249,198,143,115,56,84,84,80,71,66,50,67,138,137,151,100,25,22,14,22,22,19,53,82,93,103,96,79,77,110,141,160,182,195,191,190,189,164,137,107,71,47,33,32,69,20,22,22,15,19,16,13,17,15,19,22,24,30,29,23,24,23,16,23,23,23,22,21,22,20,18,22,23,71,94,148,228,197,135,141,139,151,159,224,216,96,34,18,7,16,16,17,17,16,16,16,17,20,20,15,18,21,15,16,19,19,19,16,15,15,16,16,13,15,18,17,21,18,27,31,28,42,42,50,55,60,66,65,71,81,81,74,65,49,40,39,42,41,41,44,43,33,59,83,77,65,36,36,61,57,54,64,66,49,37,44,54,75,92,93,87,97,98,102,88,59,41,39,41,45,63,87,84,107,213,244,248,246,235,235,235,229,230,231,230,229,230,231,231,230,230,229,231,229,228,228,228,230,228,228,231,230,229,229,232,232,231,231,231,232,231,233,236,234,234,234,233,234,232,232,234,231,232,233,234,235,229,233,231,229,232,231,232,232,230,230,227,117,4,0,4,8,10,9,10,10,11,11,11,11,193,193,194,190,192,192,188,193,190,190,190,192,191,189,190,190,190,191,193,192,193,192,191,191,191,193,191,192,193,193,193,192,192,189,191,192,191,192,193,190,191,191,193,193,191,192,191,193,191,192,193,195,195,192,192,192,193,193,193,194,192,193,194,195,193,192,194,193,194,194,193,193,191,192,191,195,193,193,196,195,196,194,195,194,195,197,197,195,196,195,194,193,195,195,195,195,196,196,193,195,196,196,195,196,198,196,194,196,198,195,198,196,198,199,197,200,198,198,199,198,196,199,198,198,198,198,201,200,199,199,198,199,199,200,203,202,201,200,201,200,199,200,201,202,201,199,201,199,201,201,198,201,197,200,200,199,200,199,201,200,200,201,201,201,199,199,199,200,200,200,201,201,200,202,202,202,206,202,200,202,200,202,201,202,200,199,204,200,202,200,201,202,202,200,200,203,199,202,199,199,200,200,203,199,200,201,199,201,198,198,200,196,198,198,198,201,200,199,199,199,201,201,200,199,199,199,201,201,199,202,200,198,201,201,201,202,200,203,201,201,204,202,204,202,202,205,204,202,205,201,201,203,202,201,200,204,205,205,204,208,206,202,212,143,115,186,217,223,211,199,208,208,213,211,212,214,214,220,219,220,219,213,201,190,184,176,179,186,194,208,217,220,224,223,222,220,217,217,216,215,214,215,215,216,219,219,221,220,220,222,220,221,222,219,220,222,221,222,221,222,223,223,219,221,223,218,222,217,225,218,215,192,119,66,143,223,250,225,172,178,172,188,170,169,152,124,156,133,145,166,183,203,196,223,213,148,51,40,57,29,33,29,53,109,83,120,127,132,217,250,240,198,212,229,212,206,212,236,224,163,191,185,193,170,152,145,122,183,182,196,193,211,215,232,230,213,205,166,201,132,49,178,198,159,158,197,241,234,174,60,39,50,104,75,29,46,19,66,236,246,201,162,144,220,206,167,171,179,191,160,117,175,220,221,231,224,174,198,207,195,235,240,130,68,142,158,198,223,235,250,253,202,63,10,3,22,28,39,46,21,22,21,49,55,61,34,31,160,247,247,248,206,155,107,41,61,53,76,72,76,55,70,132,122,141,81,20,22,18,44,50,61,70,94,139,165,167,141,141,141,139,121,104,93,63,51,37,29,24,15,16,16,15,17,17,14,21,20,13,17,22,19,22,29,34,40,43,46,48,43,37,27,22,29,18,17,27,19,24,17,23,27,23,23,50,177,250,196,142,146,143,156,185,243,188,67,31,14,15,20,15,24,20,15,19,22,18,15,20,18,17,15,17,18,19,19,17,17,16,17,16,16,15,14,13,15,15,14,16,15,17,18,16,21,22,25,36,33,39,49,58,61,60,69,78,84,78,72,69,54,57,41,45,72,64,53,50,76,83,66,79,83,75,55,26,27,44,38,32,40,55,78,98,105,90,63,48,55,68,93,121,128,95,130,240,244,248,241,234,237,231,231,232,232,231,232,231,230,231,231,230,231,231,229,228,228,231,231,230,229,229,232,231,232,232,231,231,232,233,233,233,235,236,234,234,236,234,236,236,235,234,235,234,236,235,234,232,233,232,229,230,229,230,232,231,231,226,117,4,1,4,8,9,9,10,10,11,11,11,11,190,193,194,189,189,190,188,193,190,189,191,190,191,188,191,191,189,191,193,190,193,191,191,191,189,194,192,193,192,192,191,191,193,191,192,192,190,191,193,190,191,191,190,191,190,194,191,192,193,191,193,191,190,193,193,194,193,194,193,193,193,192,193,191,193,194,191,191,192,194,193,193,194,191,191,193,191,191,191,189,193,194,191,194,194,193,195,193,194,193,194,194,194,195,195,195,194,195,193,192,194,193,194,195,193,196,195,194,195,193,197,195,195,198,196,198,196,196,200,196,197,198,198,200,199,200,198,199,200,198,199,196,199,198,197,198,197,200,200,200,202,202,200,201,201,202,202,200,200,199,201,199,203,200,199,200,199,199,199,199,200,199,199,199,200,200,198,199,198,196,200,199,197,200,201,202,200,200,201,201,201,200,201,199,200,198,201,200,199,200,199,202,200,199,200,200,199,201,200,199,200,200,199,198,198,199,198,197,198,199,199,198,200,196,196,198,198,198,196,198,199,200,199,199,200,198,199,201,198,199,199,198,200,201,201,202,199,199,201,199,199,200,203,200,199,201,204,203,203,202,201,202,201,204,203,202,202,205,204,207,202,207,222,194,204,233,231,217,204,202,210,217,218,228,230,225,223,213,208,200,190,185,176,174,182,193,206,212,216,219,220,220,218,214,217,213,212,216,211,214,215,215,216,217,217,217,219,220,220,220,221,221,220,221,220,220,219,222,221,220,221,220,220,221,221,219,219,218,224,213,210,189,117,79,157,229,247,203,166,168,169,201,179,146,113,79,138,145,158,167,173,184,163,177,175,136,48,46,68,31,40,28,69,97,56,158,193,185,234,234,234,198,224,236,214,213,221,242,229,170,170,213,235,179,199,166,151,215,221,239,233,222,213,225,179,183,158,166,234,133,112,236,220,191,178,212,251,239,162,66,39,38,87,78,24,31,25,46,218,246,210,160,174,248,239,174,157,200,240,163,106,194,246,230,248,221,170,209,208,212,246,252,199,94,76,132,213,239,252,252,250,121,19,8,4,25,42,42,24,16,22,45,56,59,44,22,140,241,251,251,251,241,196,122,30,38,34,54,54,59,40,83,135,112,136,66,32,67,100,155,169,173,171,150,143,136,107,71,39,34,33,24,23,19,12,18,19,14,19,12,12,18,15,17,26,22,20,22,22,21,22,24,31,40,47,43,40,51,53,47,41,28,28,20,18,25,18,22,22,15,31,24,26,24,32,177,234,180,146,144,147,161,196,222,134,34,22,15,21,22,27,20,23,23,19,26,21,16,14,19,19,15,15,17,18,24,22,19,19,18,22,19,16,18,14,19,20,17,17,16,24,21,16,19,16,17,17,16,22,19,23,27,34,39,48,68,79,88,101,102,89,80,75,92,99,89,80,76,61,48,68,77,61,38,45,73,65,40,23,24,19,45,83,97,101,83,110,127,129,142,146,123,91,181,247,247,243,239,235,235,231,231,233,233,231,231,232,232,231,231,231,231,231,230,229,230,230,232,229,228,230,228,230,231,231,231,231,233,232,233,236,234,233,234,234,234,233,235,232,232,233,232,233,231,233,235,229,233,231,230,231,228,230,230,231,231,229,118,2,1,5,9,9,9,10,10,11,12,12,12,190,193,193,190,191,186,190,191,189,190,190,191,188,192,188,190,191,189,191,188,193,192,191,193,192,191,192,193,191,192,191,191,195,189,190,191,191,189,190,191,191,192,190,192,191,189,192,190,191,194,191,193,191,189,195,190,191,191,191,192,191,194,191,191,194,193,194,191,193,193,190,194,192,193,193,193,192,191,193,192,195,194,194,192,194,194,193,194,195,196,197,193,196,194,193,195,193,193,193,194,192,193,192,194,195,193,193,194,194,192,195,195,195,195,194,196,195,197,196,196,197,196,197,196,195,198,196,195,196,196,199,199,198,198,200,199,200,198,201,201,200,203,200,203,202,200,202,199,200,198,198,200,199,202,200,200,199,199,198,198,200,199,201,201,199,199,199,200,200,199,199,199,199,201,200,199,200,199,198,199,200,199,199,199,199,199,199,200,199,200,198,198,203,199,198,199,198,201,202,200,199,199,198,198,198,199,198,198,198,198,197,195,199,196,194,195,196,196,198,195,196,198,194,199,198,196,198,198,198,199,197,198,200,199,200,199,198,199,200,200,200,198,200,201,200,202,201,201,203,200,202,201,201,200,202,203,203,204,205,208,198,209,209,191,216,230,218,209,197,207,224,228,248,249,244,224,198,193,185,179,178,183,190,200,212,216,220,218,219,218,215,215,214,213,213,212,212,214,213,214,214,214,217,217,216,220,223,222,222,222,223,222,222,223,222,224,222,224,225,223,226,226,228,229,227,229,229,226,229,219,213,185,145,128,182,239,238,184,143,121,157,205,174,166,149,92,130,162,175,176,178,162,120,128,142,133,55,53,71,41,43,32,52,46,31,192,251,243,253,253,251,230,249,252,236,241,249,252,238,119,125,224,252,210,214,184,167,229,250,250,236,193,215,230,188,245,207,222,252,174,208,250,252,229,196,235,252,252,190,65,46,53,100,85,18,35,26,51,200,245,237,147,198,248,252,186,185,250,245,131,120,246,252,252,252,227,211,225,215,234,251,251,245,149,83,137,230,246,253,253,146,31,6,9,12,38,44,25,18,13,39,55,61,47,23,121,240,247,251,251,252,252,207,112,46,50,45,55,55,44,44,111,136,120,146,141,154,167,162,175,156,128,93,55,36,25,33,18,15,16,19,22,14,18,14,18,21,19,27,24,28,27,24,23,24,28,22,22,30,26,30,37,45,50,42,47,48,39,46,42,36,24,14,17,23,20,22,17,23,22,32,27,29,27,25,184,235,160,148,143,154,171,200,190,82,11,15,17,22,27,25,27,21,28,31,29,30,20,19,18,17,16,19,19,16,18,22,27,23,22,21,17,20,22,21,27,31,31,27,31,32,29,32,25,21,18,16,16,15,15,16,18,18,20,19,25,34,35,42,57,69,82,102,119,125,123,101,77,57,45,68,72,61,56,78,89,62,34,28,31,18,56,96,106,102,90,121,132,142,132,133,104,103,237,248,243,245,234,238,234,230,236,234,232,231,232,232,233,233,232,233,233,233,232,231,231,229,229,229,228,228,228,230,230,231,231,232,231,230,232,235,233,233,232,235,233,232,234,233,234,233,234,232,231,229,232,231,229,231,229,230,230,231,233,231,231,229,118,3,1,5,9,9,9,10,10,11,12,12,12,190,193,192,190,193,192,190,193,191,190,193,191,189,188,193,190,188,192,193,190,191,190,191,191,190,192,189,187,189,191,191,190,188,190,189,190,190,191,191,189,189,189,188,190,191,191,188,187,193,190,191,190,191,190,187,192,189,191,191,191,191,191,193,191,192,190,189,193,190,194,191,190,193,189,191,194,189,190,194,194,195,193,193,195,193,194,198,194,196,194,195,194,191,196,195,193,193,196,195,196,194,194,195,193,194,196,195,193,196,197,195,195,197,194,194,195,196,195,198,195,194,196,195,198,197,197,196,197,199,198,198,200,200,199,200,199,200,202,201,200,199,200,199,200,199,199,199,198,197,200,201,199,200,198,201,198,197,198,199,200,198,198,199,199,199,199,198,199,200,199,201,201,199,200,200,199,198,199,201,200,201,200,199,199,201,200,200,198,198,198,196,199,198,198,199,198,198,199,199,199,198,196,199,198,198,198,196,197,196,196,195,196,198,196,198,198,195,197,197,196,198,198,196,196,198,198,198,196,196,199,197,198,196,196,200,200,199,198,199,198,200,199,200,200,200,200,199,200,203,200,200,202,201,201,202,204,203,205,206,204,197,207,193,180,208,211,213,204,199,217,224,214,177,164,170,174,179,178,184,196,204,214,221,223,222,222,221,219,218,220,217,218,218,218,223,219,221,224,223,226,225,229,229,230,232,236,237,237,240,239,241,241,241,243,239,242,244,243,245,244,249,250,251,252,250,252,252,252,252,243,231,211,191,151,189,248,250,199,165,105,139,213,202,236,215,155,177,172,196,193,170,139,101,124,139,137,64,52,69,38,52,39,46,24,20,188,247,247,252,252,250,237,250,250,245,251,252,252,230,99,92,207,237,186,192,177,162,195,214,181,202,179,224,230,206,249,201,233,214,150,208,243,227,182,139,200,246,235,160,76,48,57,96,91,28,29,39,39,172,230,140,83,152,211,151,131,169,201,160,81,112,202,222,205,198,193,186,181,155,163,200,235,218,117,66,108,186,198,200,147,47,14,10,10,32,45,33,18,14,34,53,54,56,18,93,222,252,252,252,252,250,217,171,101,50,70,60,78,72,57,69,125,137,127,167,143,134,100,52,42,29,27,22,18,19,16,15,19,20,13,18,26,29,33,31,33,34,33,41,45,41,44,31,32,24,24,34,28,30,26,38,46,43,48,62,53,67,79,49,30,29,18,21,24,19,22,25,21,22,28,35,30,40,23,51,217,212,144,146,141,165,180,185,163,80,33,22,28,32,22,28,29,26,22,33,34,28,28,18,18,15,17,15,15,22,17,16,18,27,26,30,27,22,26,24,32,36,39,50,37,37,37,35,33,24,21,17,19,18,21,16,14,15,14,17,15,17,17,15,24,30,33,44,54,63,75,89,103,97,90,102,111,103,83,77,60,41,34,27,32,29,74,106,108,112,86,105,125,135,126,119,87,131,240,246,241,243,233,233,233,236,229,232,234,233,236,236,235,235,235,234,234,232,231,232,232,231,231,232,232,233,233,233,233,236,235,231,233,234,232,234,235,233,234,234,235,236,236,233,235,234,232,232,231,232,230,228,230,230,230,230,230,231,230,235,232,226,118,4,1,3,8,10,9,10,10,11,12,11,11,192,195,194,193,194,191,193,193,193,193,191,196,192,191,191,191,192,192,194,191,193,189,190,191,189,190,192,192,189,193,188,188,193,190,192,190,192,191,193,190,190,195,189,191,193,190,192,192,191,191,189,192,191,191,194,191,192,190,189,192,190,193,191,192,194,189,192,190,189,194,190,193,192,188,190,193,192,193,193,191,193,190,194,195,193,194,194,193,193,194,193,192,196,193,194,196,194,196,195,194,193,196,193,195,196,195,195,195,196,196,196,197,196,195,195,195,196,196,196,198,198,199,200,199,200,200,199,203,202,200,202,200,203,202,204,202,200,201,199,200,198,200,199,198,199,196,200,197,200,202,201,203,199,200,199,199,200,202,198,199,200,198,202,200,200,199,199,200,200,198,199,200,198,199,198,198,201,200,200,201,201,199,199,200,199,199,196,198,200,200,197,198,199,198,199,199,197,199,198,198,198,198,198,196,198,198,197,198,197,196,198,197,198,197,199,195,197,199,198,197,198,198,195,197,198,197,199,196,195,199,195,197,197,196,198,198,200,198,198,198,198,201,199,200,199,199,200,202,203,200,202,201,205,205,205,205,205,206,208,204,201,206,188,200,217,220,222,216,217,225,208,103,23,11,85,179,208,223,229,236,242,246,245,243,241,240,241,240,240,240,244,245,244,247,246,248,251,251,252,252,251,251,252,252,252,252,252,252,252,252,252,252,252,252,252,252,253,253,253,253,252,252,252,252,250,250,252,252,252,252,245,218,210,147,159,244,253,225,205,114,141,211,225,245,242,204,190,170,176,168,158,120,101,124,133,139,91,93,89,81,97,83,95,80,84,181,187,171,185,169,160,141,153,154,158,183,174,180,149,74,78,127,127,111,104,106,93,75,84,70,105,97,129,110,95,120,95,124,99,66,96,100,116,105,32,42,73,78,102,66,46,51,78,88,37,31,33,46,50,47,48,9,35,43,29,24,49,71,50,53,61,32,12,6,56,107,122,128,80,48,21,40,61,47,68,72,76,88,69,51,30,19,12,23,45,35,28,21,23,47,60,63,24,72,208,245,252,252,254,254,211,170,138,85,89,100,93,98,99,84,99,137,123,135,125,55,29,20,15,16,16,16,18,17,20,21,17,19,25,23,18,24,37,44,38,38,36,36,37,41,45,49,50,44,41,33,33,31,30,29,37,54,55,71,60,91,154,117,66,41,17,19,21,20,25,22,24,24,33,35,41,34,53,18,82,245,186,132,144,140,182,189,169,144,90,70,77,57,45,33,24,29,27,27,28,34,31,31,24,19,21,16,18,19,19,21,18,15,16,18,29,25,29,30,28,33,32,39,43,46,39,38,41,34,31,22,21,23,18,21,22,19,22,22,19,18,18,21,18,16,17,20,17,20,29,32,36,49,61,73,86,94,101,101,83,63,50,45,42,40,33,70,101,108,108,99,103,107,115,106,112,59,93,222,234,243,247,230,233,232,235,233,234,234,233,234,235,235,231,231,234,234,234,233,231,233,235,236,235,234,234,234,233,233,233,235,233,233,234,233,233,233,234,234,237,236,233,232,232,233,233,232,232,231,230,233,231,232,233,231,232,230,231,232,231,232,229,117,4,1,4,8,10,9,10,10,12,12,10,12,192,195,193,193,195,191,189,191,192,192,190,191,192,192,192,191,192,191,191,189,190,192,191,192,190,190,194,193,191,193,190,190,192,191,191,190,190,189,190,193,192,192,189,193,191,190,192,189,192,189,191,194,190,190,190,193,191,191,190,191,189,191,191,189,193,191,190,193,189,191,189,190,195,191,193,190,192,194,193,194,195,193,194,194,191,194,194,193,196,193,195,193,191,195,192,193,192,194,194,191,193,195,194,193,194,191,194,194,194,196,192,194,197,194,197,197,195,194,197,196,196,199,197,198,199,200,203,200,200,200,200,201,200,200,200,199,201,201,199,199,197,199,200,201,198,197,198,199,200,200,201,199,201,201,202,202,202,201,201,201,198,200,202,202,201,200,199,201,201,200,201,200,200,201,201,200,201,200,200,199,199,199,198,199,200,197,200,198,198,200,199,198,198,196,199,197,198,198,198,198,197,197,197,195,197,197,197,197,197,198,197,196,197,197,195,194,193,195,195,196,195,196,196,198,197,193,196,196,198,197,195,201,200,198,200,201,200,200,202,202,203,202,207,207,207,210,210,212,214,214,217,217,219,218,220,223,223,226,228,218,223,224,210,224,236,245,242,229,226,223,201,123,59,95,191,246,252,252,251,251,251,251,251,251,251,251,251,251,250,250,251,251,251,251,251,251,250,250,251,251,249,250,246,248,249,242,244,242,241,238,239,225,214,228,209,214,222,214,214,199,184,170,166,167,159,163,171,187,192,179,153,157,172,104,104,172,170,171,163,95,122,147,150,189,160,141,142,116,117,107,120,107,98,114,107,117,114,120,125,115,130,129,144,134,121,116,79,74,68,60,59,48,55,41,31,60,50,62,69,69,88,58,40,53,50,57,48,24,29,42,60,38,56,36,37,27,19,68,41,43,57,28,53,85,36,19,18,4,46,63,52,53,59,88,54,35,40,42,47,36,65,49,57,44,20,26,41,57,32,49,74,49,12,10,26,78,110,126,137,71,20,9,16,37,64,67,84,72,47,45,23,16,23,42,43,27,25,30,51,53,63,32,50,185,248,248,252,252,252,181,142,128,94,95,122,142,142,142,137,120,130,141,118,130,92,21,14,17,14,19,13,14,20,19,26,28,27,23,27,28,31,30,26,36,43,41,41,50,56,48,45,52,46,50,53,50,46,30,37,35,36,47,50,50,44,99,159,116,69,43,16,21,21,24,23,24,29,21,33,44,46,45,51,17,97,226,144,129,147,175,217,178,154,141,103,92,112,106,64,36,36,26,27,33,32,30,27,24,27,24,18,24,24,23,24,19,23,20,18,16,16,23,26,27,25,30,27,33,49,56,46,37,44,41,35,28,24,29,24,20,22,20,22,24,22,27,24,21,22,16,17,19,18,19,21,16,17,23,24,29,33,45,63,76,89,96,93,87,77,67,53,81,103,108,119,94,76,72,73,66,61,18,96,233,238,247,242,232,238,231,236,233,232,234,233,233,233,234,235,234,233,233,235,234,232,235,233,234,236,234,234,233,233,232,232,233,233,233,232,233,233,232,232,233,232,234,232,232,231,231,234,230,231,232,230,232,229,229,230,230,231,231,231,230,231,230,227,118,3,0,6,10,9,9,11,9,11,12,12,11,192,193,191,192,191,190,191,191,193,192,191,192,191,188,191,193,187,188,189,191,195,190,192,191,191,191,189,189,190,189,189,191,190,188,191,191,188,188,190,189,191,189,187,190,189,191,190,188,190,188,189,192,189,188,187,186,191,191,190,191,190,190,189,189,193,190,191,192,189,191,189,191,192,191,192,191,190,191,192,192,195,193,194,194,194,196,192,192,193,193,195,193,195,193,194,194,193,194,192,195,195,194,194,194,195,193,194,196,194,195,195,196,195,195,196,195,196,194,196,198,196,197,198,196,198,201,200,201,202,203,202,199,199,198,200,200,199,200,196,196,197,197,198,196,196,196,199,198,200,201,199,200,200,201,200,201,200,201,200,205,201,199,204,199,199,198,200,200,199,201,201,203,202,201,200,202,199,196,199,199,199,198,199,199,199,200,198,196,198,197,198,198,196,197,198,198,197,197,198,198,197,199,198,197,198,199,195,195,198,198,198,196,195,194,196,195,196,196,193,196,196,196,195,194,196,194,195,194,196,202,201,210,217,217,220,220,222,224,228,227,226,231,230,235,236,235,237,237,241,242,245,245,243,244,245,246,247,248,246,233,236,225,222,228,219,229,203,193,203,219,234,203,200,227,246,242,227,218,210,207,194,190,184,184,183,178,177,177,173,169,167,166,168,168,159,157,152,150,146,145,146,136,137,134,130,125,121,117,113,111,107,93,100,137,101,85,100,95,96,89,81,71,66,64,64,73,66,61,67,65,67,68,81,70,73,70,62,80,79,69,87,71,64,69,59,79,77,69,74,69,83,84,87,93,89,98,104,119,107,112,119,109,116,113,104,96,71,63,65,63,61,57,56,50,45,55,52,61,79,99,103,78,59,68,58,66,61,47,64,69,83,65,69,49,71,45,31,67,53,51,53,54,80,105,60,65,60,24,61,83,72,59,62,97,63,40,46,42,39,49,83,74,87,71,55,54,70,62,61,103,78,56,50,16,69,63,63,133,142,160,85,31,20,20,53,81,96,75,42,34,17,23,45,42,31,21,29,51,50,62,39,39,165,243,252,252,252,252,160,90,81,65,44,87,139,148,162,166,173,155,156,139,110,126,67,16,18,17,19,20,23,29,29,29,34,34,23,17,18,21,29,29,26,25,37,55,61,64,60,49,49,54,57,54,49,55,70,67,60,48,34,32,37,63,79,97,92,61,45,27,21,22,24,26,26,26,23,27,38,44,50,33,49,19,110,184,100,132,156,223,250,162,144,141,110,100,95,74,64,39,23,29,36,35,35,34,29,33,31,31,36,34,41,41,34,29,21,21,21,19,19,17,19,22,16,25,23,39,56,49,56,46,45,42,39,35,24,27,28,27,24,26,29,21,28,29,22,26,25,24,27,18,18,25,17,19,21,17,19,22,20,19,23,27,40,50,62,84,103,109,104,124,112,102,112,85,59,56,57,57,50,24,159,239,249,249,238,233,236,231,233,232,232,233,234,233,232,235,235,233,235,234,235,236,235,235,233,233,235,234,233,233,235,236,235,234,234,232,233,233,234,233,232,233,231,230,229,232,233,231,232,229,232,231,229,230,228,229,228,229,230,226,229,232,231,228,227,119,4,1,5,8,9,9,12,10,11,12,12,11,191,194,194,195,194,189,191,193,192,191,192,193,190,187,192,192,190,189,190,190,188,188,189,190,188,187,189,188,188,190,188,187,191,190,187,187,188,188,188,189,189,188,186,188,188,188,190,188,191,189,189,189,190,190,189,189,189,190,190,189,187,187,189,189,191,190,188,190,188,189,189,190,190,190,190,190,192,189,189,191,192,193,193,194,192,192,193,193,195,192,193,191,193,194,189,195,193,194,196,193,196,196,196,194,196,196,196,195,196,196,192,194,196,194,194,196,199,198,197,199,198,197,199,201,200,199,199,202,203,201,200,202,200,200,199,199,198,197,195,199,196,196,195,196,196,196,200,200,199,200,202,200,201,200,199,200,201,202,201,200,200,201,201,200,201,200,201,201,201,200,200,200,200,200,200,200,200,199,198,199,199,199,198,198,199,198,197,195,198,198,193,195,197,196,198,198,198,194,194,196,196,194,197,195,198,196,195,196,196,198,197,199,194,198,197,195,196,195,197,195,194,196,194,193,194,193,195,192,200,207,214,239,240,241,242,244,247,243,245,242,244,243,241,237,237,235,232,231,226,223,222,217,217,210,204,204,201,200,197,185,188,196,199,164,127,139,127,132,141,146,158,150,157,155,144,129,116,107,102,97,87,81,84,76,77,79,71,78,73,70,66,61,64,62,61,93,51,49,51,50,54,55,48,48,51,41,49,48,46,46,46,38,49,118,82,51,60,58,70,63,86,84,90,93,91,99,85,60,55,63,57,66,66,53,71,66,56,60,63,57,72,61,47,62,47,61,63,55,74,63,68,81,68,83,78,88,85,83,91,90,84,74,84,83,87,88,77,75,69,74,77,70,78,75,57,64,51,77,81,62,86,87,79,81,53,88,74,72,71,65,65,57,75,45,64,54,49,82,66,45,42,50,72,107,72,56,41,15,73,102,75,81,71,99,68,45,53,42,39,44,50,27,64,72,63,45,65,77,73,112,63,44,32,20,69,72,30,70,127,127,162,94,36,23,12,56,76,55,34,31,22,41,53,33,21,27,47,49,61,45,27,137,244,246,252,252,253,170,131,124,135,115,59,65,80,108,105,134,130,131,150,124,109,122,60,14,22,24,19,20,29,35,31,34,37,42,35,24,19,16,19,18,22,24,16,32,48,53,57,60,61,60,48,57,54,55,91,118,113,92,70,66,86,103,104,73,43,33,27,25,16,32,48,46,37,31,35,38,46,47,50,49,47,30,109,146,96,161,193,234,234,138,144,130,79,60,33,43,49,33,23,30,43,37,43,39,49,53,38,42,41,39,30,31,44,39,35,29,26,23,18,22,15,18,17,19,36,55,61,62,78,63,48,47,43,36,31,34,35,33,34,30,32,33,31,31,32,40,40,35,27,27,26,21,20,23,23,23,20,18,15,16,18,17,21,24,25,31,52,63,72,88,91,96,102,85,61,56,59,70,60,59,193,240,249,249,239,236,236,234,236,231,234,235,233,234,236,236,235,235,233,234,236,234,233,236,234,236,236,234,237,237,235,234,236,234,234,236,233,235,235,235,234,233,231,231,232,233,231,231,233,229,230,231,230,231,231,232,230,231,230,227,229,230,231,231,227,117,4,1,4,9,10,9,11,10,12,12,11,11,193,196,193,194,193,192,190,194,191,191,192,193,192,189,191,190,189,190,189,190,190,189,193,190,191,190,188,190,188,189,190,189,190,190,189,189,189,188,191,187,189,188,186,190,189,189,189,188,191,190,189,191,190,193,190,189,191,189,190,191,187,188,189,189,193,189,189,190,190,191,188,193,189,191,191,190,193,189,191,193,193,192,194,194,191,193,193,194,194,194,194,193,194,192,193,193,194,195,196,196,194,197,197,197,198,196,196,198,198,196,198,196,196,197,196,198,198,197,199,198,198,202,201,200,202,201,200,199,200,202,201,204,204,200,200,200,198,198,199,199,197,198,202,199,200,198,200,200,199,199,200,201,200,201,199,201,203,202,201,200,198,199,201,199,203,203,201,202,198,201,199,196,197,199,199,199,198,200,200,197,199,196,196,198,197,198,196,197,199,195,198,198,195,196,195,196,194,192,196,194,196,195,194,194,194,196,194,195,193,193,196,194,196,196,195,197,196,196,195,194,194,193,197,193,192,193,193,192,206,205,190,198,198,193,191,188,186,182,179,173,171,168,157,154,153,147,141,132,124,121,118,115,114,111,103,100,98,101,107,94,101,141,172,107,40,58,67,81,71,65,72,65,70,69,65,62,64,61,61,63,56,63,55,60,67,62,68,68,69,62,60,57,52,55,50,55,51,49,49,50,57,50,56,56,50,55,54,54,53,53,53,46,61,119,91,52,55,55,62,69,89,102,107,107,106,113,99,70,61,57,67,59,66,65,57,66,61,59,56,56,61,58,52,57,53,54,59,53,59,55,59,55,53,54,54,51,52,54,51,53,51,50,53,53,52,58,58,55,55,59,51,59,57,52,46,45,46,51,73,53,39,62,69,68,59,73,76,61,54,54,48,37,57,44,59,36,61,103,61,33,24,44,49,87,70,48,41,8,54,92,82,96,77,98,73,42,52,42,41,49,32,19,56,75,55,22,66,57,62,98,46,41,23,14,81,45,36,25,18,72,78,127,93,31,19,42,60,41,31,35,45,55,37,24,25,39,56,55,50,25,113,235,250,250,252,252,174,155,211,246,251,216,69,9,8,15,41,49,51,68,113,111,110,114,46,19,25,15,27,26,19,24,26,29,31,43,52,38,24,22,22,17,23,21,19,18,20,38,42,50,54,49,56,59,69,80,93,93,117,123,103,111,113,115,98,61,37,18,22,18,27,69,71,66,77,90,74,54,63,66,59,46,48,46,116,123,108,200,235,253,207,117,147,117,51,31,48,70,53,35,24,22,36,48,57,51,47,58,54,51,48,43,38,36,42,41,35,44,37,25,26,23,24,22,21,23,36,56,63,69,71,51,33,32,29,29,42,48,42,41,41,42,42,42,44,46,43,40,44,44,42,36,31,34,30,26,27,20,21,22,18,24,22,22,18,18,22,18,23,25,33,47,59,84,101,89,65,69,87,103,102,84,181,239,249,249,242,234,236,236,234,234,234,236,235,235,234,234,234,234,234,233,234,236,233,235,236,236,238,236,234,235,234,235,234,234,236,235,236,236,232,233,233,234,232,233,234,230,232,233,233,232,232,231,230,231,230,231,228,229,232,229,230,232,231,230,227,118,4,1,4,8,10,9,10,10,12,12,12,12,191,194,194,193,192,190,189,191,191,192,189,192,193,189,191,191,191,190,188,189,191,191,190,191,193,192,191,191,192,190,188,189,190,189,188,190,189,188,189,189,187,187,190,191,190,186,189,189,186,189,188,189,188,187,190,189,189,188,188,191,191,191,193,191,189,191,190,190,191,191,191,191,191,192,190,190,190,190,191,193,193,191,192,193,191,193,195,194,195,194,195,196,195,196,195,198,194,195,195,196,196,197,201,197,198,199,198,198,197,199,199,199,198,198,200,196,200,199,199,202,199,200,199,200,202,202,201,201,201,203,203,202,200,200,199,199,199,198,200,200,199,200,198,199,200,200,200,199,199,199,199,199,199,200,200,201,200,201,199,201,200,199,201,200,201,199,200,199,200,198,198,198,198,198,199,200,198,198,199,199,196,196,200,197,195,196,196,196,194,194,195,196,193,194,195,193,195,193,194,196,194,194,197,195,195,194,194,194,194,196,194,194,190,194,191,194,195,193,195,193,196,193,191,192,196,195,194,191,198,153,71,62,57,51,49,42,44,35,39,37,36,35,31,31,31,26,24,25,24,25,26,27,24,20,25,28,33,35,37,34,37,108,154,84,16,30,43,49,49,43,44,43,48,48,52,48,52,48,50,52,51,55,53,49,50,54,51,57,50,57,53,44,54,48,51,52,53,49,50,52,49,53,48,50,53,48,49,50,50,45,48,43,34,77,65,44,43,36,48,41,42,68,53,50,47,55,53,47,40,39,45,46,39,45,48,40,48,39,42,44,36,40,38,37,37,43,39,34,43,37,36,42,36,38,30,36,36,36,37,33,36,35,36,33,32,37,43,38,39,39,40,35,33,36,32,33,24,45,81,43,37,57,57,48,36,51,55,51,42,51,30,39,42,31,53,14,36,70,54,21,17,27,22,47,36,55,42,3,27,60,78,105,70,97,81,44,57,39,54,46,19,24,60,73,37,10,36,35,56,71,16,35,19,18,53,21,9,23,19,14,40,49,108,75,36,59,33,33,34,42,53,43,28,17,37,55,53,54,23,89,222,244,252,252,252,185,164,207,249,249,250,204,68,19,6,16,33,62,43,22,95,106,118,110,34,23,23,23,34,19,20,20,19,22,30,39,46,53,47,32,24,20,23,26,21,24,19,21,19,29,35,38,55,56,59,72,88,76,66,80,93,117,125,125,141,104,55,23,17,18,68,93,42,95,155,141,92,48,45,49,36,41,72,61,130,159,168,230,234,252,176,115,153,100,48,79,138,100,86,41,37,22,18,24,36,50,53,56,59,59,57,59,49,40,46,43,34,36,42,38,25,27,21,22,21,17,31,35,44,49,50,44,39,30,30,33,31,38,37,38,38,46,57,60,60,55,47,47,49,49,49,50,46,41,44,40,37,38,28,27,31,27,18,25,21,21,24,17,16,19,30,33,68,94,98,98,83,110,139,149,141,117,139,191,241,245,236,232,237,233,235,233,233,233,233,233,233,233,233,234,233,233,235,231,233,235,234,236,235,236,236,236,236,235,237,235,235,236,234,236,233,234,234,233,235,231,232,233,231,233,231,230,230,229,229,230,229,229,229,229,228,228,231,232,231,228,227,119,3,0,5,9,9,9,11,9,11,12,11,11,187,192,188,193,191,190,192,192,191,190,191,190,193,191,193,191,192,190,191,193,192,192,191,191,191,192,190,191,189,188,190,188,189,190,186,188,189,186,190,189,187,190,188,191,191,189,188,189,191,188,188,189,188,191,190,190,188,189,191,191,189,192,192,190,191,190,191,189,190,192,188,193,191,190,193,192,193,192,193,195,195,195,194,195,197,194,194,194,193,194,193,194,196,195,197,196,199,196,195,198,197,200,199,199,201,201,202,200,199,199,200,201,200,200,202,201,200,200,201,200,200,200,200,201,203,203,205,203,205,205,204,201,200,200,200,201,200,203,203,201,200,200,200,199,200,198,201,201,200,200,203,200,199,201,199,201,200,200,202,201,200,201,200,198,199,198,198,199,200,200,196,199,198,198,198,198,198,198,199,195,199,196,198,197,194,195,195,196,196,192,196,195,194,196,194,197,194,195,197,192,194,194,194,193,193,196,190,193,196,192,196,190,195,197,193,196,194,194,193,194,193,192,194,194,195,194,195,193,198,117,6,3,5,6,10,9,10,8,10,11,10,11,10,10,10,10,10,10,10,10,11,11,11,11,10,11,12,12,10,12,10,32,77,46,6,11,9,21,25,29,32,29,34,32,35,32,36,35,35,36,32,37,35,32,38,33,34,35,35,34,31,37,33,32,33,35,36,33,33,34,35,35,30,30,34,36,33,32,32,32,35,31,24,45,53,34,25,27,29,28,32,36,33,31,33,28,32,35,26,26,27,27,33,33,31,34,30,29,35,29,29,31,30,26,26,29,31,31,28,28,30,25,30,32,27,28,25,26,27,30,29,31,31,34,31,25,29,29,29,29,27,29,30,30,28,35,19,35,75,36,41,46,56,36,27,42,53,32,16,24,10,29,23,26,29,24,65,43,21,14,27,54,58,73,31,31,28,30,35,37,73,104,72,91,85,45,55,47,64,78,43,35,84,96,87,74,78,86,120,128,95,123,114,118,132,103,131,120,127,108,84,174,159,155,101,27,31,28,41,50,44,24,21,33,49,54,64,30,73,207,247,247,252,252,186,164,216,251,250,250,245,143,73,61,47,53,75,90,32,41,119,105,131,99,27,31,20,25,36,26,24,17,20,24,21,29,46,50,56,49,31,33,39,36,29,27,23,24,21,21,26,22,29,26,46,71,88,91,87,91,112,146,138,157,160,131,78,37,21,26,120,88,45,113,120,105,69,36,25,15,19,57,97,71,138,203,237,252,236,234,150,121,163,83,53,131,122,119,95,47,30,22,20,17,22,39,47,59,63,57,58,47,56,45,39,43,39,40,34,46,45,38,27,21,22,19,22,20,29,35,51,62,60,67,67,57,49,48,46,46,41,57,71,64,60,53,55,54,47,45,51,53,50,55,55,52,51,52,46,32,22,21,19,27,23,29,25,17,22,18,30,39,77,99,106,103,107,159,164,163,155,124,101,82,144,206,228,239,236,234,233,236,236,234,235,233,232,231,233,235,234,236,235,235,234,235,235,235,237,236,233,236,236,234,235,236,236,235,234,233,235,234,232,233,232,231,232,232,232,230,231,230,228,231,229,230,231,228,229,229,229,228,230,230,230,229,226,119,3,1,5,8,9,9,11,10,11,12,12,11,188,191,191,189,191,190,189,190,191,191,190,192,191,190,190,190,190,190,190,192,192,188,192,192,191,191,190,189,191,190,189,189,188,189,188,187,188,189,189,191,188,190,189,187,190,188,191,191,191,190,188,191,189,189,192,188,193,191,189,191,191,191,188,193,189,190,193,190,194,192,192,193,192,192,190,194,194,194,194,193,193,196,194,193,196,195,197,196,196,193,192,193,195,197,198,197,198,198,199,199,200,200,200,201,201,201,202,202,201,203,200,202,203,198,200,200,202,201,200,203,203,203,204,203,204,205,203,202,205,205,202,205,203,203,202,202,205,202,201,201,202,200,201,203,199,198,200,202,201,200,202,200,202,200,200,199,197,200,198,199,197,199,200,196,198,198,198,196,198,198,196,196,198,196,198,198,197,198,198,197,196,196,196,195,196,195,195,195,198,196,192,194,192,192,194,194,196,193,194,194,193,193,193,192,193,195,193,192,194,192,193,197,193,195,194,195,194,192,196,193,193,192,192,193,193,194,193,196,202,145,75,63,46,54,53,48,49,39,43,38,36,33,31,29,23,21,21,21,17,14,16,16,12,12,12,12,10,11,11,12,10,15,51,42,10,11,10,12,12,17,24,24,30,29,29,29,31,31,28,33,29,31,30,34,31,31,29,29,26,24,27,99,19,14,16,13,12,13,13,13,13,14,13,14,13,13,14,15,15,14,13,14,15,15,14,15,13,15,17,15,14,13,14,14,15,14,14,15,19,22,32,56,50,36,45,55,56,46,32,30,35,39,57,50,22,29,28,30,36,39,51,47,39,44,58,60,41,35,39,33,33,44,34,62,83,53,36,122,41,130,57,129,54,134,123,145,144,134,144,122,81,104,124,122,108,126,160,132,102,140,168,191,191,206,224,210,185,110,177,236,246,238,236,188,146,213,232,249,189,89,57,78,59,92,86,46,43,57,212,251,214,171,177,243,243,201,151,143,223,247,245,251,252,226,246,243,250,252,252,252,252,252,250,153,49,38,15,31,43,47,25,12,23,48,48,66,36,47,194,245,249,249,252,188,155,203,246,249,253,253,208,99,82,81,82,91,86,121,53,87,140,106,136,84,20,22,24,28,31,27,25,18,22,26,23,29,34,46,58,54,51,54,59,59,55,51,43,49,62,55,56,60,56,54,113,153,134,123,98,105,130,118,91,92,86,71,63,61,43,69,157,108,83,106,55,42,42,32,18,14,38,94,95,72,128,234,234,234,236,234,164,146,168,71,67,153,107,114,105,52,25,9,21,15,15,20,18,30,43,45,46,54,52,51,44,34,37,39,39,44,51,51,39,29,35,45,45,30,40,55,56,66,76,84,75,59,59,61,58,56,55,59,61,54,50,49,56,62,63,45,33,45,60,62,51,39,36,38,30,26,20,15,28,29,23,29,31,24,17,18,24,44,83,94,104,103,108,146,152,150,127,103,75,20,73,191,235,246,235,231,237,234,235,236,233,233,235,233,234,234,233,234,233,234,236,234,236,236,234,236,235,236,234,234,235,233,233,236,235,235,235,234,234,232,233,233,232,231,231,234,231,229,230,230,229,230,228,230,229,229,230,228,229,227,230,231,226,118,4,1,4,9,10,9,10,10,12,12,12,12,189,193,190,192,191,189,190,191,193,191,191,191,191,188,191,190,190,191,193,192,190,191,194,195,193,193,191,191,192,191,191,191,191,193,188,187,191,189,190,188,189,192,188,191,190,191,191,191,194,191,194,191,190,192,189,191,190,192,191,193,193,190,191,193,194,194,193,193,191,193,193,193,194,191,194,194,194,198,193,196,194,194,198,197,195,194,195,195,197,196,196,198,199,199,200,199,200,201,201,201,201,205,203,199,201,202,201,204,203,201,203,203,206,204,205,203,203,203,205,206,204,204,205,204,203,202,207,206,205,203,206,205,205,202,202,205,201,203,203,203,205,202,202,204,201,200,203,201,201,200,202,201,200,202,201,199,198,199,200,200,199,199,198,195,198,198,198,198,199,198,198,198,198,198,196,197,198,198,197,197,198,196,196,194,197,198,195,195,196,196,195,193,193,195,193,195,195,194,194,194,193,193,195,192,192,193,193,196,195,193,195,190,194,195,191,194,192,193,193,194,193,194,199,194,193,196,193,198,214,208,209,228,228,231,231,229,230,229,229,227,227,224,223,221,222,221,217,217,219,216,213,214,210,208,206,206,202,194,195,194,183,151,159,174,174,183,181,184,177,177,175,173,170,167,165,160,163,162,160,158,159,166,166,166,174,173,181,180,185,184,188,196,194,199,200,204,206,207,209,211,215,217,216,224,225,225,225,232,232,231,234,234,223,170,192,231,236,244,243,235,214,213,213,209,212,208,219,235,243,241,246,235,122,106,211,250,175,83,61,139,222,248,239,173,165,206,217,238,247,250,250,250,240,242,241,163,78,75,64,33,44,50,59,208,248,235,249,241,252,252,249,248,249,252,252,252,252,238,246,217,125,112,164,173,122,128,225,232,217,252,253,253,253,253,252,237,176,153,251,251,252,252,252,238,227,252,252,252,220,117,69,65,35,72,89,48,35,70,230,245,246,226,218,228,251,226,140,186,249,250,252,252,253,224,242,250,246,252,252,252,252,252,210,92,28,2,22,37,48,27,15,22,35,52,55,54,19,84,239,243,249,236,168,167,210,239,251,251,250,252,143,27,69,71,71,78,80,101,53,115,147,107,138,70,15,27,24,33,29,24,27,21,19,27,18,20,31,36,40,44,54,64,71,67,83,86,109,139,127,122,128,142,146,163,184,162,145,121,100,113,99,72,45,36,36,42,39,56,73,100,131,87,74,60,28,55,45,20,22,26,93,115,93,49,108,240,250,248,252,246,180,170,160,52,72,150,108,106,80,42,23,12,19,17,17,21,24,18,18,18,19,43,56,50,47,43,46,47,40,43,46,43,44,38,46,68,70,61,59,62,64,66,73,68,72,76,63,54,47,51,53,51,63,65,66,62,57,57,53,38,21,16,22,32,32,22,15,18,19,17,19,18,24,27,28,27,29,32,24,23,22,46,89,89,97,95,84,120,127,118,86,88,137,164,222,247,242,243,236,239,235,235,236,235,232,234,237,234,233,235,235,234,234,234,233,234,235,236,236,236,237,238,236,233,234,235,234,236,235,233,235,234,233,231,232,233,235,232,230,231,231,229,229,231,228,230,228,229,230,228,230,230,230,230,231,231,225,117,4,0,4,8,10,9,10,10,11,12,12,12,188,192,190,186,189,188,188,189,191,190,189,191,190,192,191,187,192,193,192,193,193,191,190,189,190,192,190,190,192,190,190,191,191,191,192,193,191,190,189,191,190,191,192,191,192,191,192,192,189,191,193,191,191,190,197,190,190,190,191,192,188,193,188,191,192,192,195,191,192,191,190,191,191,192,193,193,195,193,193,194,194,196,195,195,196,192,194,193,196,198,196,197,198,198,199,201,202,203,202,203,205,203,202,203,201,199,203,202,203,204,202,205,203,203,206,204,205,206,204,205,203,205,205,204,204,205,205,203,206,205,201,203,201,204,205,203,205,203,204,203,202,200,201,201,199,200,202,200,199,201,199,200,202,198,200,200,200,201,196,201,199,198,200,199,200,195,196,198,198,196,198,199,195,198,198,198,195,196,197,195,196,194,196,195,195,195,195,195,193,195,193,193,193,193,195,193,192,193,193,192,193,193,195,193,194,194,192,194,194,193,193,191,195,194,192,195,194,195,195,192,193,194,193,194,193,193,193,196,205,208,223,241,243,248,249,251,251,251,251,251,252,252,252,252,252,252,252,252,252,252,253,253,252,252,252,252,252,252,252,252,252,252,252,248,253,253,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,252,252,252,252,252,242,252,252,253,253,253,253,253,253,252,252,252,252,252,252,252,252,249,243,113,118,243,246,237,203,203,247,253,253,252,252,252,252,253,253,252,252,252,252,252,252,249,182,85,81,64,29,37,41,61,217,252,252,252,252,253,253,252,252,252,252,250,250,250,241,248,230,103,92,168,173,60,47,232,247,224,252,252,252,220,229,186,176,141,155,251,251,251,239,252,198,195,250,246,252,184,99,75,75,43,61,87,46,41,53,207,247,198,212,122,162,241,177,165,207,234,234,223,251,216,163,208,213,214,227,252,252,243,206,97,13,4,5,25,50,32,19,16,40,50,57,52,38,63,145,244,244,239,160,152,219,247,252,250,243,248,181,83,60,89,75,53,77,90,74,55,133,127,113,132,53,20,25,29,34,33,29,21,18,21,21,19,26,21,28,29,39,54,61,76,83,138,173,157,169,170,157,155,147,141,160,158,118,87,73,68,68,53,45,39,28,19,21,33,46,53,63,64,62,67,62,73,74,32,23,32,89,161,113,71,41,48,186,234,252,232,187,122,101,86,26,38,91,68,77,67,39,21,10,21,14,19,21,21,25,22,24,20,16,26,34,39,29,26,28,22,23,28,34,35,29,31,46,56,51,46,48,58,72,72,53,56,81,75,59,59,62,63,57,63,69,69,64,55,41,28,23,20,17,16,17,20,18,17,20,15,16,23,19,27,32,27,34,40,36,30,23,27,61,89,97,103,97,69,74,81,76,33,103,244,244,247,247,241,241,239,238,234,234,235,233,236,238,235,236,237,234,236,236,235,235,234,235,233,232,235,234,232,234,231,233,233,231,233,233,232,231,231,232,230,232,233,233,231,231,231,230,228,230,229,229,230,230,228,228,229,230,227,227,230,229,231,231,227,118,3,1,5,8,9,9,11,9,11,12,11,11,185,190,188,188,190,188,189,188,190,188,189,189,189,190,189,190,189,191,189,188,192,192,191,190,190,191,191,190,190,188,190,192,191,190,191,191,191,188,191,194,191,192,190,192,191,190,194,191,192,193,192,191,196,193,194,196,192,195,193,192,192,192,194,193,192,192,191,192,191,192,194,190,191,191,194,195,193,195,195,194,191,193,194,193,195,194,195,195,198,194,198,198,198,199,197,200,200,200,203,204,201,201,205,202,203,203,200,205,203,201,202,201,205,203,204,204,202,205,203,203,205,205,207,206,206,205,205,205,203,202,203,201,200,200,199,201,200,200,203,199,202,200,199,200,199,200,200,199,200,198,199,199,198,198,198,197,199,198,198,200,199,198,197,198,198,198,197,197,198,196,197,195,196,194,194,196,195,193,196,196,194,193,194,194,194,193,194,195,191,191,196,192,192,194,194,193,192,195,193,195,193,192,193,193,194,193,193,193,192,193,195,189,192,191,193,193,193,194,190,194,192,192,195,191,193,193,191,192,195,196,200,202,207,208,206,209,209,210,213,213,210,212,213,215,216,215,217,219,222,220,221,220,223,226,227,230,221,222,230,231,236,234,234,229,229,235,237,239,241,244,241,243,245,246,246,246,250,250,249,251,251,250,251,251,251,251,251,250,251,251,251,251,251,251,252,252,252,252,250,249,249,249,249,248,248,248,247,246,246,245,245,251,246,215,239,251,244,246,244,246,244,247,248,248,248,247,249,249,226,148,214,174,51,83,201,245,244,251,247,251,253,253,252,219,212,219,196,191,189,196,200,183,164,179,175,94,51,68,60,50,61,38,34,160,204,209,222,211,244,245,252,245,252,252,251,251,232,208,223,212,187,200,245,229,146,95,209,193,149,203,198,170,152,209,196,189,144,188,251,239,239,212,243,171,169,227,220,251,163,91,77,75,65,59,99,46,39,66,224,248,174,124,82,175,204,122,138,198,227,226,217,230,181,163,186,193,206,223,251,251,215,106,19,2,6,17,44,34,24,17,28,54,56,59,20,107,184,210,246,239,163,145,212,250,252,252,243,239,147,152,134,121,117,49,57,59,91,83,57,128,119,118,121,39,19,31,22,28,31,28,24,18,23,24,25,20,19,22,24,40,46,54,67,80,167,170,160,198,168,152,119,98,105,130,125,89,77,59,56,51,33,29,25,16,14,22,21,29,33,39,47,29,35,49,46,39,18,48,142,190,175,97,43,35,16,112,239,239,183,99,45,22,19,15,14,38,50,66,56,28,21,16,12,19,23,23,21,20,31,28,23,22,21,17,19,18,17,17,16,14,19,19,14,21,22,21,34,33,33,40,50,67,55,43,57,71,73,55,36,33,54,68,59,44,34,30,24,17,19,20,16,19,18,21,23,22,21,17,17,24,22,19,32,38,43,56,49,45,36,23,36,71,103,103,107,107,63,49,73,76,26,98,235,239,247,247,239,241,236,237,235,236,234,233,236,237,236,235,238,236,234,236,234,234,236,234,233,234,234,235,233,233,233,232,234,231,232,232,231,231,230,233,230,232,233,230,231,230,230,231,229,231,230,229,229,231,228,229,231,230,231,229,231,233,231,231,228,118,3,0,6,9,9,9,12,10,11,12,11,11,186,190,188,188,188,185,186,186,185,186,188,191,188,185,188,186,189,189,187,189,188,190,192,191,192,192,193,192,191,191,192,190,190,192,193,192,190,191,191,193,193,191,192,191,192,193,191,192,192,192,194,194,196,193,194,193,194,194,192,194,193,197,195,195,194,194,193,192,195,193,195,196,195,193,193,196,195,196,198,195,195,195,195,195,195,192,194,196,197,195,196,199,197,199,199,198,199,200,201,200,201,201,202,201,203,204,203,201,202,203,201,203,203,202,203,203,203,202,205,204,204,204,203,205,203,204,204,204,204,203,202,201,202,201,200,199,199,198,199,200,199,197,201,201,198,199,200,199,200,200,198,198,197,196,198,198,199,200,199,198,194,196,198,194,196,194,196,196,196,196,195,196,195,195,194,197,195,195,194,193,193,193,194,193,193,193,192,193,193,194,194,194,194,191,194,193,194,193,193,194,194,193,192,192,191,191,190,191,190,191,194,192,192,192,191,193,191,191,193,190,191,193,194,193,190,190,192,193,194,194,191,195,194,195,195,194,193,193,196,194,197,196,194,198,196,197,197,198,199,198,198,198,200,199,201,203,194,198,203,206,207,206,200,200,207,206,205,206,207,208,209,212,211,210,214,216,213,214,216,215,216,217,218,218,220,220,218,220,219,218,221,221,222,221,221,221,220,222,222,221,219,220,220,220,221,221,221,219,220,222,218,221,224,203,217,227,220,222,217,219,218,219,221,220,216,218,223,222,178,74,152,174,92,83,165,229,186,186,177,165,156,157,153,124,130,128,115,100,89,108,116,92,84,102,108,90,110,140,129,139,145,127,75,57,55,39,42,36,48,54,56,65,99,150,168,149,128,137,156,186,207,244,252,252,247,127,132,122,65,122,180,174,200,228,207,215,134,198,251,234,241,205,244,171,168,219,220,251,160,88,70,73,62,53,97,52,33,67,232,247,170,142,120,201,156,59,117,174,229,225,221,218,161,190,189,179,208,238,251,251,145,44,6,1,11,29,42,30,21,32,48,56,62,29,70,217,230,219,249,167,138,207,252,252,252,248,241,146,132,245,211,141,112,62,36,34,64,36,59,131,95,124,107,29,28,24,29,36,34,27,22,22,19,26,24,21,20,21,21,32,41,46,59,45,108,113,138,203,148,114,92,78,95,123,111,74,83,76,66,50,32,31,21,18,24,21,19,18,21,23,23,26,22,20,21,21,26,131,211,199,145,63,36,27,9,56,152,106,100,38,35,72,63,33,45,83,75,60,52,50,40,21,21,20,22,24,26,29,22,31,31,25,27,26,24,24,21,22,22,16,17,21,22,19,17,17,19,31,50,38,47,58,41,35,48,69,74,56,33,15,23,35,34,29,22,19,20,19,18,23,22,20,23,24,25,19,25,42,45,33,21,23,43,58,58,57,54,48,39,25,46,88,101,105,106,105,69,60,86,98,53,62,205,232,243,249,238,239,231,237,236,235,238,235,234,237,236,234,236,235,236,236,234,235,234,234,234,234,235,233,235,234,232,233,236,235,233,233,231,231,234,233,233,233,231,231,231,230,230,230,230,231,231,230,231,228,232,229,229,231,227,231,232,230,231,230,228,118,4,0,4,8,10,9,10,10,12,11,12,11,185,188,187,188,187,185,188,187,188,186,186,186,185,188,188,188,187,187,189,189,189,189,189,191,191,191,191,189,192,191,191,191,191,191,191,190,192,191,191,191,191,191,192,193,193,194,196,191,191,194,191,192,196,191,193,194,191,195,193,193,194,194,195,194,194,193,193,194,197,194,196,195,194,194,195,197,194,197,199,197,196,198,197,195,197,196,197,198,198,195,196,198,198,199,198,201,200,200,201,199,200,200,201,199,202,202,201,202,202,202,201,202,200,202,201,202,204,203,204,203,204,203,205,203,201,203,203,203,202,202,201,203,203,200,199,199,200,199,200,198,198,196,198,199,198,198,196,197,197,198,198,198,196,198,200,198,199,198,195,197,196,196,195,194,193,196,196,194,196,196,193,194,194,194,195,195,193,194,196,193,195,194,193,194,195,193,192,193,193,191,194,194,192,192,193,192,191,191,191,191,191,192,193,193,193,191,192,193,190,189,192,191,193,190,192,193,193,192,193,191,189,192,190,190,192,192,191,191,191,193,194,192,193,194,193,192,193,196,195,194,194,197,195,194,195,196,198,195,196,195,196,198,198,199,200,197,188,198,202,200,205,198,193,200,203,204,202,200,204,203,200,206,208,206,205,205,207,206,206,207,208,209,210,210,211,212,211,212,212,212,211,211,214,215,216,215,216,216,215,215,216,215,217,214,215,215,211,214,216,217,217,216,222,191,198,222,214,217,212,214,214,213,214,214,211,213,223,223,179,102,179,174,113,93,106,141,106,98,71,67,57,64,96,95,112,102,105,119,111,141,160,113,98,149,167,162,182,198,197,200,195,162,118,74,43,25,17,12,10,10,9,10,11,10,10,11,10,24,39,53,78,129,155,199,198,104,126,139,97,174,231,218,245,232,208,175,107,196,239,231,236,203,244,171,166,221,216,251,157,85,75,65,60,44,101,63,40,57,222,246,139,183,196,223,152,100,166,182,233,220,222,196,150,212,184,163,217,249,251,181,49,4,3,7,33,38,34,24,26,48,53,65,27,49,184,246,232,216,184,120,191,250,252,252,250,250,149,131,218,252,237,134,91,81,85,25,37,23,64,123,87,120,84,25,35,22,33,38,33,30,19,24,21,20,21,23,26,20,24,23,25,35,33,32,46,38,114,165,108,92,76,76,94,98,69,55,62,51,47,35,29,35,27,24,23,19,19,24,24,15,21,23,24,24,15,28,21,82,131,106,81,53,33,15,10,19,69,85,46,15,59,147,110,106,203,246,191,118,135,125,68,29,16,21,25,23,18,26,29,27,30,34,37,32,33,31,28,28,24,28,33,39,39,33,28,23,27,46,55,50,50,42,39,36,41,52,65,66,48,27,17,19,18,17,20,18,22,20,22,22,22,26,21,24,24,24,73,111,81,54,35,25,60,71,55,59,54,55,46,24,57,90,99,95,95,108,81,64,79,77,52,61,176,230,238,249,238,237,233,236,235,235,236,234,233,232,234,233,234,235,235,236,233,233,234,234,233,234,233,233,234,235,234,232,234,234,234,234,232,233,233,232,232,232,233,231,234,232,230,231,230,231,231,230,229,230,230,231,231,230,230,230,232,233,232,231,227,117,4,0,4,8,10,9,10,9,11,12,11,11,184,187,186,188,188,187,187,186,188,190,185,187,185,185,191,186,187,187,186,190,190,187,186,188,188,188,189,190,188,188,190,188,190,192,189,193,191,191,192,191,191,189,192,190,192,191,189,192,192,190,192,194,192,191,192,193,193,192,193,192,192,194,192,194,194,192,193,196,194,193,198,193,191,196,196,195,194,196,198,194,199,199,198,199,199,198,199,196,195,198,197,198,199,196,198,199,198,198,199,200,199,198,200,198,199,200,198,200,202,200,199,202,201,203,201,202,203,202,205,201,202,204,205,203,200,204,200,202,200,200,203,202,203,201,200,199,199,199,197,197,197,199,200,199,198,198,198,196,196,196,194,194,197,196,196,197,193,194,195,195,195,193,193,193,198,195,194,193,195,193,191,192,194,195,191,193,191,194,193,193,193,191,193,191,193,193,190,192,190,191,193,188,192,192,192,191,189,191,191,192,192,190,191,192,191,190,191,190,188,190,190,190,193,191,190,192,192,192,191,190,192,188,188,187,190,191,191,192,191,190,192,193,190,193,191,193,193,193,194,193,197,195,197,196,194,197,196,197,193,195,198,198,198,196,198,190,190,200,199,201,202,195,194,200,205,204,203,206,200,205,204,201,206,202,207,205,204,205,207,208,207,210,208,210,210,208,207,207,210,210,212,214,214,213,214,214,214,212,213,213,214,214,214,215,213,212,215,212,212,214,215,214,220,185,187,217,212,215,212,212,214,212,212,212,209,210,225,219,190,126,135,121,95,97,98,98,92,104,103,120,89,64,63,39,93,153,181,212,214,214,229,147,73,159,230,188,160,185,177,145,138,132,102,83,159,214,209,202,206,145,139,129,46,6,18,37,115,62,28,11,9,23,19,30,58,34,106,137,116,239,251,233,249,176,162,148,107,212,232,232,234,200,246,176,169,217,217,251,152,87,75,71,63,34,96,76,30,45,201,189,146,222,216,200,110,132,204,198,244,213,226,177,149,224,171,172,235,248,212,75,5,9,8,22,46,32,24,23,42,54,66,45,32,155,248,248,227,159,139,174,237,252,251,251,251,170,131,207,251,251,198,84,104,112,120,45,55,24,81,135,101,134,77,24,35,26,37,37,31,32,17,19,24,24,18,24,29,21,23,24,28,24,24,21,41,69,130,120,79,74,61,63,61,49,46,34,36,36,30,33,39,44,45,35,23,21,23,29,24,19,21,27,26,21,29,22,33,86,88,51,49,33,22,15,14,20,64,105,64,69,124,143,86,84,184,231,201,92,155,118,69,45,33,33,39,38,23,25,24,28,29,34,31,31,37,24,24,29,31,53,68,63,65,53,38,27,31,38,36,47,50,35,36,38,45,52,65,80,67,53,46,34,27,26,19,22,21,26,19,21,27,21,24,28,22,80,177,163,101,97,72,59,71,71,60,61,55,54,43,32,57,84,90,90,95,112,89,65,78,80,42,45,191,235,239,249,235,238,234,235,236,233,235,232,233,235,233,236,235,234,235,233,233,233,234,233,232,231,233,233,233,233,232,233,232,233,233,235,233,233,232,231,231,233,234,232,232,232,231,231,231,231,230,231,232,229,232,230,231,234,229,232,232,232,233,233,229,118,3,0,5,9,9,9,12,10,11,12,12,12,186,187,184,184,185,186,190,186,187,189,186,188,186,186,189,186,188,188,186,187,185,186,186,188,186,186,189,188,190,189,189,188,191,191,188,191,190,190,191,193,190,189,190,188,193,190,192,192,190,193,189,191,194,191,193,193,193,193,194,192,192,194,191,191,190,191,193,193,194,191,194,198,195,196,196,196,196,196,194,195,198,199,198,196,200,197,195,197,198,198,198,196,196,195,196,196,197,196,198,201,199,199,199,197,199,196,198,199,200,202,202,202,201,203,203,200,201,200,201,200,202,204,205,203,202,203,201,201,200,201,202,201,199,202,202,198,198,197,198,198,200,198,198,194,196,199,196,198,196,196,195,195,196,196,196,194,197,196,192,194,195,193,194,194,194,195,193,193,193,190,191,193,191,194,196,195,193,192,193,193,194,192,194,190,190,193,190,190,191,191,192,191,190,191,191,191,193,194,193,193,191,193,191,190,191,190,190,193,190,192,190,190,193,191,191,191,191,189,193,191,191,193,189,191,192,191,193,193,193,193,192,193,191,190,193,193,190,192,194,192,192,196,196,196,195,195,196,194,196,199,197,196,194,198,199,192,192,201,200,200,201,191,196,203,201,205,203,204,205,202,203,206,206,205,206,204,205,204,206,207,209,211,210,209,210,209,208,211,210,210,211,210,211,214,212,212,212,212,214,213,214,212,215,213,213,215,212,214,212,212,213,211,226,196,199,230,221,218,213,213,212,211,212,210,211,207,226,194,131,108,96,83,84,71,60,62,84,153,211,251,193,99,161,205,252,252,252,252,250,214,228,143,73,149,198,156,109,126,121,104,90,84,95,100,211,241,245,248,248,248,246,188,118,93,119,215,243,200,174,101,62,67,23,28,27,14,38,22,68,190,212,225,177,126,185,141,139,225,226,236,229,201,244,179,168,214,214,251,151,70,77,65,67,36,101,106,66,60,117,151,180,248,199,123,65,153,227,211,249,211,224,163,170,225,191,200,250,235,99,16,6,18,17,36,40,26,19,38,56,62,50,27,128,243,250,250,170,113,188,229,253,253,244,245,170,142,209,251,252,242,124,108,108,82,74,51,84,72,120,144,119,151,69,21,37,27,38,34,33,32,19,23,19,26,24,21,24,24,35,30,30,33,27,32,51,88,110,74,54,60,51,51,34,34,34,33,32,19,17,39,49,44,51,46,24,24,25,27,29,24,26,25,27,25,23,28,53,107,91,47,43,22,17,16,24,31,72,135,124,106,145,121,67,48,18,67,80,47,76,62,61,61,60,67,59,57,42,26,21,23,21,27,28,27,33,27,29,29,53,61,50,34,34,47,50,50,50,36,26,39,51,68,75,73,65,64,80,86,82,79,77,69,63,50,40,34,33,29,29,27,24,28,32,45,77,136,137,94,99,152,135,89,79,63,63,61,51,48,49,30,55,86,92,89,84,107,92,75,70,83,40,44,200,236,242,249,234,238,234,235,234,235,233,233,234,233,236,236,236,234,233,234,233,235,233,233,232,233,233,233,231,230,233,233,233,231,233,233,232,232,234,231,232,232,233,233,231,231,231,231,231,231,231,230,233,233,229,230,230,232,233,232,234,234,233,233,230,118,3,0,4,9,9,9,12,10,11,12,12,12,186,188,184,185,188,185,184,186,185,186,186,187,188,187,188,188,186,185,188,185,186,187,189,189,187,188,187,189,188,188,189,188,189,191,188,189,188,189,187,190,190,188,192,190,192,192,190,191,191,190,191,192,190,193,191,192,192,190,194,191,193,193,191,193,193,194,195,194,193,194,195,195,196,195,196,194,194,196,198,193,194,196,196,198,196,195,198,196,196,199,196,198,198,198,198,198,196,198,198,195,197,198,200,200,199,200,199,199,202,199,201,204,199,201,200,200,200,200,201,199,202,201,200,201,199,201,198,203,200,198,201,199,201,197,196,199,198,197,197,200,197,196,199,196,199,196,195,198,196,195,195,196,195,194,195,196,193,197,196,194,195,194,195,193,194,194,192,192,196,192,192,192,193,193,192,193,193,194,193,194,192,191,193,190,194,193,194,193,190,193,191,190,191,191,190,191,191,192,189,190,190,188,190,192,192,189,193,192,190,192,191,190,192,191,191,191,192,191,192,191,191,194,194,189,191,193,192,192,194,194,195,194,193,194,194,194,192,196,195,193,197,195,198,196,196,196,195,196,198,200,198,199,196,199,196,188,200,200,200,203,198,192,199,203,203,205,204,207,205,205,202,203,201,203,210,205,205,206,205,207,208,209,212,212,210,211,212,209,210,211,210,211,211,212,213,213,212,214,213,213,215,214,213,215,214,213,211,213,214,214,213,217,235,206,216,249,232,220,214,212,214,210,211,212,208,209,233,172,90,77,55,55,67,43,39,44,75,147,208,244,200,198,252,252,252,252,253,253,191,116,111,90,73,66,63,76,65,53,55,48,50,57,57,56,76,93,110,117,141,152,140,97,53,67,113,209,230,215,196,149,158,127,108,120,165,122,47,41,33,66,137,206,189,169,206,154,166,232,228,237,225,202,241,187,170,212,217,251,153,79,80,58,62,25,98,115,96,85,120,146,178,226,169,141,123,198,224,216,247,218,224,163,187,229,201,217,237,142,33,9,12,19,41,42,27,20,33,50,62,55,22,98,235,245,251,218,111,152,232,246,252,252,249,169,137,202,250,250,252,158,87,106,87,27,29,24,59,93,123,134,125,131,46,21,37,25,38,36,34,24,23,21,23,27,21,26,25,25,34,29,33,35,34,33,60,92,87,71,52,49,41,38,34,16,20,23,16,21,18,29,54,60,63,58,45,24,23,29,24,24,23,29,29,30,31,37,79,105,87,66,42,23,30,42,57,75,92,123,151,111,81,113,88,68,49,22,29,51,65,53,69,68,82,84,64,70,59,40,26,15,19,21,24,24,23,27,24,30,55,55,26,16,19,24,50,77,83,75,76,97,109,122,124,97,80,71,61,59,59,77,93,97,103,89,78,71,63,63,53,34,31,50,73,99,115,97,59,42,52,62,63,57,63,57,53,59,53,53,52,37,45,84,91,97,88,100,92,66,69,65,27,63,228,241,244,248,234,239,233,236,234,233,235,233,233,234,233,234,234,236,236,235,235,234,235,236,236,234,231,231,233,233,234,233,233,233,231,232,232,231,232,234,233,233,232,231,231,231,232,232,231,231,230,231,231,230,234,231,230,233,230,233,233,231,233,233,229,118,4,0,4,7,10,9,10,10,11,12,11,11,187,191,188,188,188,188,186,185,185,186,188,188,187,184,187,185,184,187,186,188,189,187,186,188,186,186,185,185,188,187,188,186,188,187,186,190,187,190,188,188,190,189,191,187,191,192,187,190,190,189,190,189,191,190,190,193,194,192,192,192,193,194,193,193,193,194,194,194,196,193,197,195,191,193,197,196,194,194,193,197,196,195,197,196,197,196,197,196,199,194,198,198,197,195,195,197,196,196,196,199,198,198,197,198,199,196,198,199,199,199,200,199,200,201,202,200,201,201,201,203,202,201,201,199,198,200,199,199,201,198,198,199,198,200,199,197,199,198,198,198,198,196,196,197,197,196,195,197,195,196,196,194,194,194,194,193,193,193,195,194,193,194,193,195,193,195,195,191,196,193,195,192,193,195,192,193,192,194,191,190,193,193,194,194,193,192,191,193,191,192,193,190,191,191,190,190,191,190,192,190,191,190,188,190,189,189,191,192,190,191,189,191,193,189,192,192,190,192,191,193,191,191,193,192,191,191,194,193,190,193,192,193,193,193,196,195,194,198,198,198,198,198,196,196,198,196,196,196,198,199,197,198,200,203,196,192,198,201,203,203,196,198,205,206,206,205,205,207,208,205,204,202,202,206,208,208,207,208,209,209,210,210,211,211,213,212,210,210,211,211,213,213,212,215,213,214,214,210,212,210,213,214,213,214,213,217,214,214,215,212,212,218,232,178,150,214,230,217,212,211,213,212,212,212,211,207,230,155,61,36,11,61,108,103,98,90,84,80,60,78,48,63,153,157,152,122,108,74,16,6,29,21,24,24,12,33,29,26,27,29,25,21,29,19,29,28,33,34,24,33,28,31,31,45,74,82,79,83,96,119,135,128,119,145,181,145,112,89,66,59,152,245,204,221,212,141,195,230,233,239,223,203,238,197,173,208,214,251,156,82,93,52,64,14,69,73,36,76,116,125,160,234,186,145,156,216,199,200,242,223,205,160,206,229,217,203,147,50,3,18,16,36,42,27,22,27,51,61,56,28,81,222,247,247,221,139,137,205,249,249,250,251,173,124,186,238,250,250,169,90,96,108,34,46,109,87,64,73,101,128,126,111,33,23,39,27,38,34,35,27,23,26,26,24,25,23,25,30,33,38,36,42,35,60,144,177,141,87,66,61,64,60,29,16,18,17,16,24,24,21,57,72,72,79,64,44,27,26,28,27,29,30,40,37,31,49,86,95,61,37,29,25,52,60,63,66,64,89,149,145,96,76,83,97,87,87,55,48,69,64,64,65,75,67,55,55,53,44,27,16,16,22,20,27,29,27,29,32,55,44,23,22,19,24,57,84,91,101,98,92,77,71,65,53,50,47,44,34,39,61,69,78,92,104,110,116,129,120,89,57,81,126,128,113,78,53,35,24,27,23,20,30,37,40,49,55,57,51,52,40,45,80,95,98,97,103,92,64,39,42,45,139,246,246,249,249,240,240,233,236,236,236,234,236,238,238,238,236,236,236,236,234,234,234,234,236,237,238,234,233,233,233,236,236,238,235,233,234,236,234,236,236,236,236,236,236,233,232,234,233,234,233,231,233,234,232,231,235,233,234,234,234,234,232,235,236,228,117,4,0,4,8,10,9,10,10,11,12,12,12,184,189,184,187,189,182,185,185,187,188,187,186,186,184,184,186,184,186,184,184,188,184,186,185,186,186,184,188,184,184,185,186,186,186,188,186,188,187,187,189,186,185,184,190,189,187,190,188,188,190,192,189,187,192,188,189,189,187,193,190,191,191,190,192,188,189,193,191,191,192,194,192,193,193,193,194,195,196,195,194,196,196,194,194,195,195,195,193,194,194,191,194,196,195,194,193,197,194,194,197,196,194,196,195,194,197,196,196,200,199,199,201,198,200,200,200,198,198,203,199,199,198,198,200,196,200,200,198,195,196,199,196,196,197,195,196,196,195,194,195,195,193,193,192,192,195,194,193,194,191,194,193,196,194,192,195,191,193,190,192,196,190,190,192,192,192,191,191,192,192,194,191,192,193,192,194,190,191,194,193,193,193,191,192,190,191,191,190,190,192,191,189,191,192,190,190,189,191,190,190,191,193,190,190,191,187,191,189,188,191,190,189,190,190,189,190,190,192,191,191,191,190,191,192,193,189,190,191,191,191,190,191,193,192,194,196,194,197,197,197,197,196,197,196,197,196,198,198,197,199,197,200,200,203,197,193,202,200,204,199,194,200,207,206,206,210,205,205,206,206,206,206,202,204,204,205,208,208,207,205,207,207,210,211,212,212,208,211,211,211,211,214,214,214,214,214,212,213,212,211,212,210,214,214,211,212,212,216,211,211,211,216,208,92,39,129,198,215,215,212,211,211,212,210,208,212,221,144,52,56,79,97,86,75,83,56,54,69,41,28,23,26,15,27,44,14,46,54,19,15,15,14,14,21,21,18,23,20,26,29,17,19,22,18,24,19,24,26,27,26,19,28,25,44,48,59,59,52,27,39,95,55,71,63,72,92,75,87,47,68,189,243,192,200,183,147,213,223,230,236,218,204,234,198,173,206,213,251,147,77,95,59,66,19,61,83,23,46,118,155,219,250,163,78,138,200,173,202,236,223,182,156,210,232,221,141,64,5,10,22,31,48,34,25,24,41,60,63,32,61,201,244,250,230,139,159,187,231,250,233,251,178,114,177,220,249,254,193,94,83,107,84,26,68,118,83,67,76,92,118,131,96,27,28,35,33,43,33,31,24,22,26,31,24,23,25,24,32,38,48,70,53,69,167,201,180,143,122,129,130,92,49,24,15,21,19,18,23,25,27,63,73,74,91,76,61,41,29,29,27,27,32,39,38,34,42,55,43,24,26,23,26,42,48,50,44,50,59,121,155,125,118,87,98,106,96,90,69,60,63,70,67,66,49,40,36,30,36,34,20,18,17,20,27,23,30,23,28,57,51,31,21,23,33,46,51,53,50,39,30,29,31,33,33,33,28,26,32,45,55,58,57,62,69,76,87,105,118,107,103,123,123,98,71,47,27,21,26,21,15,21,21,34,53,60,60,55,54,56,38,44,95,105,99,76,97,103,66,29,61,101,179,247,247,250,250,240,243,237,236,235,234,233,234,236,239,235,235,236,235,234,233,235,235,234,233,235,234,236,235,235,234,235,236,233,236,235,234,235,233,234,233,233,234,233,235,233,233,235,234,234,234,234,233,233,233,233,230,231,235,229,231,233,232,236,231,229,118,2,0,5,8,9,9,10,10,11,12,12,10,184,190,184,187,186,186,186,187,189,187,187,186,188,185,188,188,185,187,185,186,185,186,185,186,189,188,187,187,188,188,188,187,190,187,188,188,188,190,187,190,189,189,189,188,188,190,189,189,190,188,193,190,191,191,190,191,188,190,191,190,191,189,191,191,191,193,190,193,194,192,193,191,193,194,194,194,193,195,191,197,195,195,196,194,194,196,196,195,196,192,196,194,194,195,198,197,197,198,197,199,196,198,196,198,198,195,199,200,201,201,203,200,199,198,199,199,196,199,198,197,199,200,199,196,197,198,199,197,199,197,197,198,197,200,196,194,198,196,196,194,192,196,194,195,194,193,192,194,192,192,192,191,194,193,193,193,192,192,193,192,193,192,190,193,189,192,193,192,194,191,194,191,191,192,193,191,193,194,194,194,192,192,191,194,194,191,191,191,189,191,193,192,192,194,192,190,190,189,194,192,192,193,191,191,191,193,189,190,191,191,191,190,190,190,191,192,191,191,190,193,192,189,193,193,193,189,190,193,192,194,192,194,194,193,195,195,196,196,197,198,198,200,201,200,202,199,199,200,200,201,200,200,200,200,193,199,203,203,206,196,198,206,209,205,207,207,207,209,207,209,210,208,208,203,203,205,209,210,207,207,210,210,211,209,212,211,210,213,212,211,214,212,210,214,212,212,214,212,213,211,213,213,212,210,212,214,210,212,212,214,213,222,195,78,7,88,191,216,216,210,210,209,210,211,207,211,219,177,107,54,44,63,34,33,46,38,39,63,53,36,24,22,24,45,63,29,59,44,17,21,14,24,19,19,18,20,19,22,24,24,20,15,25,14,18,23,17,27,25,22,22,21,25,51,44,44,76,78,39,49,66,51,60,43,52,44,50,53,27,76,191,191,133,200,156,159,229,208,233,229,222,208,232,206,173,203,216,251,152,73,96,62,73,30,93,104,30,51,139,215,251,251,136,79,159,207,181,207,237,223,152,154,214,242,198,68,15,7,7,30,43,38,23,18,42,55,64,42,47,177,246,246,239,150,162,220,210,246,250,235,182,124,171,227,251,251,251,134,77,103,95,73,35,84,84,39,88,95,81,114,124,85,23,30,37,31,41,33,33,26,25,24,28,29,29,28,27,42,98,147,163,137,146,199,169,137,122,119,130,88,53,33,17,22,19,23,24,23,28,31,66,72,66,90,85,69,55,31,24,34,33,35,38,33,28,22,19,17,22,21,18,19,23,34,38,36,45,35,52,74,74,122,129,101,94,102,110,104,93,83,70,66,62,46,33,23,21,26,33,27,22,20,23,26,25,27,33,21,36,59,48,41,34,41,39,28,25,23,17,17,21,17,15,19,25,25,32,38,46,46,50,49,35,43,53,62,64,67,65,70,79,69,58,50,32,24,21,23,25,23,32,27,51,76,69,67,64,54,55,44,45,107,122,101,78,84,100,63,67,110,95,98,165,221,249,249,242,242,238,238,236,235,234,236,236,233,235,234,234,236,235,236,234,232,233,233,233,234,233,234,234,233,234,233,234,235,233,235,238,236,237,236,233,235,235,233,233,235,235,234,234,236,235,233,231,231,233,232,232,234,233,232,232,233,234,232,229,120,3,0,5,8,9,9,12,10,11,12,13,12,185,191,186,185,188,185,187,186,187,186,188,189,187,189,191,188,185,188,189,185,187,186,189,186,185,188,186,187,187,187,188,188,184,186,186,186,189,189,186,187,189,190,187,188,187,186,190,188,189,189,189,188,189,190,189,188,190,191,190,190,189,189,191,192,190,189,192,191,193,192,192,191,191,194,194,196,193,193,195,196,196,196,197,193,196,196,193,195,196,196,195,196,195,194,197,197,196,197,194,194,195,197,198,196,197,199,198,198,200,200,198,197,198,199,198,197,198,198,197,196,200,198,196,198,196,196,196,196,197,196,193,196,196,197,197,195,195,195,196,197,196,194,195,195,192,194,195,193,193,192,193,191,192,193,192,191,191,191,189,192,194,191,193,192,191,191,189,192,189,192,193,190,192,192,193,194,194,192,192,192,194,196,194,193,191,190,190,193,193,191,193,192,193,191,191,192,192,190,191,192,189,193,190,190,192,189,191,192,191,189,191,192,188,192,192,193,190,193,193,192,192,192,193,191,191,191,196,193,191,192,190,192,192,194,194,196,196,198,198,198,199,201,202,200,201,200,201,202,200,201,199,200,203,198,192,202,206,205,204,194,201,207,209,208,206,207,207,210,209,208,208,208,208,208,205,204,205,209,212,210,210,209,210,210,210,213,212,211,211,210,210,210,212,212,214,213,212,213,212,211,210,212,212,211,209,214,211,213,211,210,214,223,218,127,90,165,212,220,215,210,211,209,208,210,208,215,211,212,122,5,2,21,29,33,35,31,37,64,56,45,36,29,25,66,66,42,74,41,21,28,13,23,23,15,23,15,24,27,27,26,17,22,18,21,19,18,19,25,31,22,17,19,42,53,36,57,77,80,55,67,72,56,63,38,57,63,53,39,33,128,178,151,170,220,151,179,230,206,235,227,222,203,228,211,174,201,214,252,151,71,104,63,72,41,74,98,39,62,157,223,249,218,127,151,234,226,184,207,242,212,147,177,212,235,131,26,9,4,19,45,40,26,12,37,54,61,47,29,155,244,249,249,160,156,219,242,222,236,252,171,135,182,226,249,252,252,244,96,84,108,77,76,29,57,93,96,111,83,86,126,126,71,21,29,29,34,39,29,33,24,27,29,26,51,80,49,49,135,226,231,198,151,142,177,143,122,112,83,59,38,32,18,17,20,23,21,25,29,36,32,46,72,68,93,90,68,57,36,31,32,31,36,34,33,26,22,19,17,16,15,17,16,18,21,23,21,28,27,29,27,53,122,132,131,103,83,97,100,109,96,87,75,55,50,30,22,19,22,27,32,29,17,21,21,28,32,24,25,22,39,61,60,61,57,35,20,15,16,22,18,19,22,18,17,19,25,21,33,41,39,37,35,33,46,41,39,43,43,45,55,62,52,43,33,21,21,23,19,25,30,36,31,61,89,71,73,68,51,61,43,38,104,116,111,94,87,101,88,102,109,62,27,18,89,228,236,248,237,235,240,238,238,237,236,232,236,235,235,236,237,236,235,235,235,235,235,235,234,234,232,234,234,234,236,233,235,234,236,238,236,238,236,236,236,233,235,235,235,233,233,235,232,233,236,234,233,231,232,233,233,230,231,231,231,236,233,229,118,4,0,4,8,10,9,10,9,11,12,11,11,184,189,187,186,185,187,187,187,188,186,188,188,188,186,186,186,187,187,188,188,186,189,187,185,187,188,188,186,187,187,188,186,187,187,187,185,184,187,185,188,188,186,187,186,189,188,186,188,190,186,187,187,191,189,189,192,190,192,188,190,190,191,191,189,193,191,190,191,190,192,192,193,192,193,195,195,196,195,193,196,195,192,194,194,191,192,195,194,194,192,196,195,196,197,196,194,196,197,194,196,195,199,199,196,197,197,197,199,198,196,198,196,198,196,198,196,196,201,199,198,198,199,195,198,198,196,199,194,197,197,196,197,195,194,194,194,196,194,195,193,193,195,193,195,191,192,194,194,194,192,193,193,193,191,191,193,194,191,191,193,193,191,192,192,190,194,193,189,190,192,191,190,191,192,193,191,195,193,192,193,191,193,192,193,192,191,191,191,192,194,194,193,193,194,191,193,194,193,192,190,191,188,190,192,190,191,192,193,191,192,193,193,191,194,196,191,193,194,194,195,196,195,193,191,192,193,193,195,193,194,194,193,194,194,194,196,195,198,198,200,204,204,203,203,203,201,202,202,204,204,204,202,205,198,198,206,205,210,198,196,207,207,208,208,208,207,208,209,207,208,206,208,208,208,209,203,203,203,205,210,210,210,210,209,211,209,210,211,210,210,212,212,210,213,210,211,212,210,213,212,212,212,213,212,213,214,212,215,212,214,211,224,228,202,201,217,231,222,214,212,212,212,212,212,213,212,207,212,144,43,11,21,11,27,30,27,30,42,55,33,32,36,28,54,58,47,72,39,30,54,39,44,42,24,29,24,19,25,21,29,21,15,21,18,24,21,25,37,31,24,26,29,64,59,46,71,87,78,72,92,51,51,55,48,61,42,59,31,25,135,221,194,212,231,137,207,231,204,237,221,223,198,227,212,173,198,215,251,152,62,92,65,64,38,57,89,52,38,149,237,233,208,126,178,251,218,186,197,244,207,167,208,193,155,61,3,12,6,41,42,25,20,29,54,60,54,29,126,245,245,251,169,154,214,243,247,200,245,201,129,198,238,250,250,253,253,202,45,89,101,66,64,26,31,50,76,61,48,98,136,128,55,21,36,33,35,40,32,34,23,22,29,42,106,139,133,147,189,224,180,120,89,76,108,102,83,62,34,29,19,23,19,20,26,25,28,34,39,38,37,31,47,62,66,62,57,75,57,37,36,27,37,38,31,25,24,23,17,16,15,14,15,15,18,18,19,18,18,19,23,55,100,129,131,116,103,87,64,75,93,90,79,65,57,34,12,17,15,32,38,27,24,20,20,31,32,25,20,25,18,21,39,39,31,19,22,22,24,28,23,23,27,26,32,27,19,27,21,23,31,32,31,43,57,45,44,35,23,24,26,35,30,28,23,20,22,20,24,35,30,29,29,66,85,64,72,66,55,57,51,35,84,106,114,99,89,105,103,122,80,72,82,34,23,153,231,249,247,235,236,237,233,236,234,232,233,236,236,235,236,234,232,233,234,236,234,233,234,233,234,234,235,235,235,236,236,233,235,239,235,235,235,235,236,234,236,234,234,233,234,233,233,234,233,233,231,232,232,231,233,232,234,235,234,235,234,229,117,4,0,3,8,10,9,10,10,12,12,11,11,184,190,187,185,188,185,190,189,187,188,188,188,188,188,186,185,186,189,186,188,187,185,190,188,186,186,186,189,188,186,187,184,188,189,188,190,186,186,187,187,188,187,185,186,187,187,189,188,188,187,188,188,190,188,191,188,188,191,186,191,188,189,194,190,191,191,190,193,195,194,192,195,194,193,193,192,196,197,195,195,192,194,194,192,194,192,192,197,195,193,194,195,195,196,195,193,194,194,197,198,198,197,199,200,196,198,198,198,201,197,199,199,196,197,198,196,198,198,198,198,197,196,198,197,195,198,200,197,197,198,196,196,195,193,193,194,196,198,194,193,196,196,192,193,193,191,193,191,194,192,192,191,191,192,190,190,194,191,191,193,191,191,191,191,193,191,191,193,192,193,192,191,194,192,192,193,191,192,194,192,191,191,192,193,193,193,194,192,192,192,194,192,195,194,196,197,196,198,194,193,192,194,190,189,192,192,192,194,195,193,195,193,194,197,196,194,194,195,194,198,198,193,194,194,194,195,193,192,193,193,195,196,196,196,198,199,198,198,200,203,205,201,204,205,205,206,206,207,205,207,206,207,205,195,202,207,208,207,199,201,208,208,207,208,209,209,208,208,207,210,211,209,209,212,210,206,207,204,204,208,211,212,210,210,212,210,210,210,211,212,209,211,214,210,213,212,210,210,212,214,213,213,212,214,212,214,212,214,214,214,213,219,221,205,223,224,220,222,214,214,212,210,211,210,212,212,198,219,182,129,126,79,12,8,21,23,24,37,50,33,21,28,24,45,41,54,73,37,53,73,49,69,60,31,41,23,18,23,15,22,20,25,20,25,28,30,30,28,33,34,49,64,90,87,77,87,83,59,75,79,50,51,37,38,20,19,51,36,90,210,234,197,228,200,134,228,223,203,232,218,224,198,224,216,176,200,212,251,147,59,94,48,72,63,74,116,49,46,171,217,247,185,71,180,244,213,196,191,247,197,190,229,129,68,14,9,15,20,49,33,23,24,46,63,57,27,107,237,250,250,171,145,212,239,247,233,201,199,150,186,249,249,251,249,251,243,95,24,89,84,44,48,59,93,75,57,27,57,126,144,117,38,21,33,28,35,36,34,28,23,24,29,60,135,112,124,119,115,115,71,44,41,37,47,49,43,31,19,16,19,16,22,36,33,51,75,65,55,49,35,31,30,34,45,46,41,62,74,64,43,33,36,30,33,32,27,27,18,17,20,15,19,16,17,17,15,16,14,18,27,36,55,63,81,86,82,78,67,71,68,71,78,67,51,33,19,14,20,27,30,29,29,21,17,28,26,26,28,23,26,20,16,29,22,21,23,24,24,25,29,26,27,27,33,33,29,29,26,19,34,48,46,58,60,73,68,54,36,21,19,19,18,21,23,24,21,28,31,31,37,33,29,62,78,64,66,62,55,60,54,38,76,97,118,105,92,104,109,109,78,98,115,83,39,106,223,245,245,241,231,235,237,234,233,233,234,234,232,234,233,234,235,231,232,233,234,234,234,236,236,233,233,234,235,235,234,236,237,235,234,236,234,234,234,233,234,233,235,234,234,235,235,233,232,231,235,234,232,233,232,230,231,233,233,234,232,229,119,3,0,6,10,9,9,11,10,11,12,11,11,187,191,188,188,187,189,186,187,188,185,189,188,191,189,187,188,188,187,189,188,189,189,185,189,188,187,189,187,188,186,187,188,186,188,188,188,188,188,187,188,186,183,188,188,187,186,187,187,186,187,189,188,188,185,190,191,186,189,187,188,188,188,190,189,191,191,190,192,193,192,193,190,194,195,195,196,193,196,195,195,196,196,197,195,193,195,197,195,195,196,196,196,195,195,195,195,195,196,194,194,196,194,194,195,198,200,197,196,197,196,196,197,198,196,197,197,197,194,196,196,196,197,198,196,193,195,196,194,197,193,194,195,194,197,196,195,192,194,196,192,193,193,193,194,193,193,192,190,196,194,192,194,193,194,192,191,192,191,190,191,191,190,193,193,190,191,193,192,192,191,191,193,191,192,192,193,191,191,194,193,193,194,196,196,193,198,198,194,194,194,196,194,195,196,195,199,198,197,196,192,193,191,195,194,195,199,197,196,196,198,195,194,195,198,199,198,198,196,197,195,194,193,193,193,194,192,193,194,193,194,195,195,196,197,198,200,199,198,202,203,203,206,205,205,205,204,208,208,206,206,208,209,204,198,208,210,209,205,197,207,208,208,210,210,210,209,210,211,210,211,212,211,211,210,208,207,212,208,204,205,207,211,210,210,213,208,209,212,209,210,209,210,210,211,211,214,212,211,212,212,212,210,213,213,212,212,211,214,212,214,212,218,215,198,211,204,214,218,210,210,211,212,212,209,216,210,201,200,184,163,200,203,63,12,12,14,22,27,47,29,19,22,18,42,44,57,72,35,35,39,32,53,51,38,36,22,20,19,17,22,18,21,22,23,27,24,30,30,20,36,53,68,70,58,68,63,61,42,74,56,35,47,21,61,67,89,189,179,151,210,197,154,223,175,143,239,210,210,226,217,223,193,226,217,176,192,211,251,150,75,120,63,74,92,107,129,73,50,178,246,250,149,42,175,233,238,227,188,251,185,213,225,55,17,8,6,24,37,45,22,29,51,53,61,26,82,222,243,251,178,140,198,241,246,240,229,151,132,191,239,252,249,236,247,230,120,45,38,111,63,39,96,88,95,100,103,57,96,139,139,109,28,25,32,31,42,33,37,32,19,26,41,98,101,61,47,29,34,38,33,35,30,21,19,27,21,16,25,21,19,42,70,72,68,96,118,108,76,52,43,40,35,30,27,27,30,28,39,55,48,31,24,31,35,32,24,22,21,19,22,18,18,18,19,16,16,16,15,14,22,34,34,38,47,43,59,73,64,71,66,56,62,54,48,31,15,14,14,24,30,42,32,26,23,18,29,33,26,26,28,29,27,25,25,26,24,24,27,24,27,26,25,33,32,31,34,33,32,27,54,71,53,53,56,62,74,71,53,36,24,27,26,21,28,32,27,26,30,31,30,34,32,58,75,55,57,69,64,56,56,37,69,99,120,114,101,114,106,110,76,66,84,84,54,80,189,241,243,245,235,235,236,236,235,236,236,232,234,234,232,233,234,234,232,234,235,234,236,234,235,234,235,236,236,234,233,235,234,233,233,234,235,234,235,234,235,234,234,234,232,233,234,234,233,233,235,233,233,234,235,232,231,234,234,234,234,229,118,3,0,5,9,9,9,11,10,11,12,12,12,184,188,186,188,189,185,186,187,186,186,186,188,186,184,187,188,185,186,184,187,186,186,189,187,188,188,189,186,185,188,186,186,189,186,186,186,185,188,188,186,186,189,188,188,186,186,187,188,187,187,186,188,188,188,192,188,187,190,189,192,191,190,193,191,194,192,191,194,193,194,192,192,192,192,195,197,197,194,196,197,194,195,196,194,196,193,194,196,194,195,195,194,196,196,196,194,195,197,194,191,192,194,195,196,195,199,197,194,194,196,196,195,196,196,195,194,195,196,195,195,196,196,194,197,195,196,196,193,196,195,192,193,194,195,193,193,195,193,193,194,193,193,191,194,194,192,191,192,193,192,194,191,193,192,193,194,191,191,191,192,191,193,193,192,193,193,194,193,191,191,191,190,192,194,191,192,193,193,194,196,196,194,195,198,200,198,197,196,198,198,199,198,198,196,198,200,199,198,197,197,197,198,197,198,198,199,199,200,197,197,196,195,195,197,197,196,197,197,195,195,197,193,193,194,192,196,195,194,196,196,198,198,198,200,199,200,199,202,204,203,207,207,208,206,206,206,207,208,208,209,208,209,203,203,213,213,212,200,204,212,213,214,211,213,211,210,212,213,211,210,212,208,207,210,211,209,210,209,206,206,204,209,210,208,212,211,211,211,212,212,211,211,214,211,210,211,211,212,212,213,211,212,212,212,211,212,213,213,212,214,213,217,216,199,207,197,208,220,211,214,207,208,212,208,218,206,199,195,180,134,193,249,141,67,15,10,17,19,43,29,18,23,15,44,40,59,61,23,34,26,27,36,32,34,32,23,23,23,25,30,27,27,27,19,21,25,35,33,27,26,42,71,42,41,58,59,57,37,61,23,22,49,119,234,214,200,252,211,113,129,133,174,232,149,163,243,205,210,225,223,222,196,225,219,172,190,208,251,152,83,152,84,78,38,49,127,62,58,207,244,224,65,47,214,226,228,218,199,251,185,172,127,13,26,4,18,46,39,29,27,44,57,64,32,63,201,248,248,190,133,190,237,247,239,228,185,97,166,245,249,252,217,241,198,149,112,39,71,106,58,66,105,57,36,27,90,101,114,134,133,98,24,35,32,26,42,33,35,32,25,24,90,111,61,37,23,24,16,17,23,19,22,18,18,22,23,19,21,25,38,68,83,103,88,86,104,106,103,78,66,59,47,39,32,26,29,32,28,26,29,24,28,35,39,34,29,29,24,29,24,17,21,16,20,21,16,19,16,12,19,30,35,37,31,30,38,53,63,66,65,64,55,40,40,29,13,14,15,23,38,49,48,31,24,24,27,29,25,25,24,26,27,28,28,28,29,24,31,32,24,31,28,36,39,38,48,44,37,36,57,73,62,46,39,44,46,57,70,65,61,52,47,43,28,29,28,32,30,28,27,33,28,49,76,55,59,73,60,57,62,37,67,98,114,112,110,113,100,98,92,94,83,67,50,64,170,241,240,241,238,238,237,234,237,234,233,235,231,234,234,235,237,235,236,235,233,235,234,233,232,236,236,233,233,233,234,233,235,236,235,234,233,235,235,234,234,234,234,234,233,233,234,233,234,233,234,234,234,235,233,234,232,233,233,235,235,227,117,4,0,4,8,10,9,10,10,12,12,12,12,186,191,186,188,187,185,187,187,188,185,187,187,187,188,186,188,185,185,189,187,187,188,187,188,188,185,189,186,186,190,184,190,187,188,188,184,189,187,189,190,190,189,187,188,188,187,187,187,190,189,190,189,187,188,190,191,188,191,191,188,192,193,194,194,192,193,193,194,195,194,194,192,196,194,194,195,196,196,194,194,196,198,198,197,195,196,198,196,195,195,194,194,197,197,196,195,195,194,192,195,195,194,197,196,196,196,195,194,195,195,194,195,193,195,196,193,196,196,198,195,195,197,194,198,196,196,196,194,197,193,194,195,196,195,193,196,194,194,194,192,195,194,195,193,190,193,192,193,196,194,193,192,194,194,195,193,193,194,194,195,193,193,193,195,193,194,194,193,194,192,195,193,196,194,191,196,196,195,194,194,196,197,197,198,196,198,200,198,200,201,200,198,199,201,200,200,205,202,202,203,201,201,200,201,200,199,201,200,200,200,199,199,200,199,200,197,195,194,196,196,193,195,196,194,198,195,196,198,198,201,201,202,203,202,203,200,203,206,206,206,207,207,208,208,211,210,210,210,212,211,212,212,202,205,213,211,208,204,208,213,213,217,213,212,214,211,213,212,212,212,210,211,210,210,212,211,212,211,214,209,205,206,210,212,212,211,211,213,210,210,213,214,212,213,212,213,211,212,213,213,214,213,216,212,214,214,214,216,212,214,211,217,216,198,209,198,209,220,212,217,212,211,211,211,220,203,198,192,217,163,187,226,132,125,31,38,80,37,40,31,47,47,55,65,35,53,29,7,39,33,31,34,31,29,33,30,27,31,36,36,28,34,30,31,20,27,40,29,27,21,44,70,29,51,36,36,45,18,24,24,117,162,208,252,240,208,240,136,72,118,155,220,232,136,192,241,207,214,215,224,221,197,227,219,174,186,204,251,148,79,148,87,80,31,12,80,49,59,220,248,136,18,94,236,128,153,208,196,249,151,114,44,1,27,6,38,47,31,22,37,51,66,48,46,182,246,251,218,147,189,236,247,234,223,191,115,126,228,251,250,222,224,181,134,217,128,50,48,92,61,79,124,78,87,32,65,84,103,133,131,81,13,34,40,29,42,32,33,36,19,27,83,80,30,24,15,14,19,18,19,22,23,24,24,28,25,19,28,27,44,61,61,79,71,80,89,105,129,106,77,67,56,54,48,31,30,27,31,33,24,28,32,34,35,35,33,26,27,33,27,21,23,18,19,20,18,15,16,17,23,31,36,37,39,35,35,33,43,72,69,60,55,39,33,28,15,16,12,30,55,59,53,39,26,22,26,30,27,21,21,22,29,27,25,29,25,27,23,30,32,27,32,40,88,114,108,98,83,55,48,62,57,62,48,30,35,49,73,87,85,81,76,66,61,51,47,49,41,30,22,30,26,49,72,62,63,75,66,55,63,39,65,101,110,113,97,121,89,49,66,77,82,49,37,39,125,240,238,241,241,237,238,233,238,236,234,235,236,238,236,237,237,238,235,236,235,233,237,236,234,236,236,231,235,235,236,237,233,234,235,234,237,235,233,234,235,235,233,235,233,234,233,233,234,232,233,230,232,232,231,234,235,236,234,234,233,229,118,4,0,4,9,10,9,10,10,12,12,12,11,184,189,189,188,189,185,186,188,187,189,187,187,188,186,188,187,188,186,185,188,185,188,186,187,189,186,188,186,187,189,189,190,191,185,189,191,188,189,188,189,188,188,187,189,190,187,190,188,186,188,189,190,188,190,190,189,190,190,191,190,193,194,194,193,191,193,195,194,194,196,193,196,197,196,196,196,194,195,195,193,194,195,195,196,199,198,196,198,196,194,196,195,198,195,195,194,195,195,194,193,193,192,194,194,191,195,193,195,195,194,195,194,194,191,192,196,196,193,195,194,194,195,196,195,193,197,196,194,197,195,194,196,192,194,193,192,195,196,193,192,192,193,193,192,193,194,192,193,197,191,192,191,194,195,191,196,194,194,194,194,196,197,196,196,196,194,194,193,193,193,194,194,191,192,193,194,192,192,195,194,195,194,196,195,195,198,198,199,200,200,200,201,202,201,201,203,202,203,200,200,203,202,203,203,203,204,202,201,201,203,202,202,203,201,201,200,199,198,196,193,194,195,196,200,198,197,198,198,201,203,205,205,204,204,203,205,207,206,208,208,207,210,210,212,212,211,213,213,214,214,217,210,200,212,214,214,205,204,214,213,214,213,213,212,211,212,214,212,209,214,211,209,213,213,212,211,211,212,210,210,208,208,206,207,214,214,211,211,212,212,212,211,214,214,212,214,213,213,213,213,214,214,216,217,215,216,213,211,211,214,214,214,215,198,208,200,207,220,212,217,212,214,215,212,220,199,195,192,231,196,199,189,99,104,51,156,220,185,214,226,246,247,241,235,198,186,168,164,206,156,57,16,43,50,48,35,27,32,33,45,32,33,33,24,31,37,66,77,87,35,42,65,22,51,22,46,46,66,160,186,247,214,224,251,139,129,166,109,138,197,194,248,207,133,218,236,209,210,217,224,216,198,224,220,174,187,205,251,150,63,130,84,72,29,30,79,53,53,213,236,106,34,97,124,53,162,218,208,220,108,61,12,7,26,22,48,35,21,31,48,63,50,34,148,249,249,248,184,203,235,250,236,202,182,122,147,189,245,251,218,223,170,125,194,253,144,29,47,89,68,75,143,148,148,63,63,81,99,144,126,62,13,33,39,35,44,30,34,31,18,19,33,37,23,20,16,21,20,24,27,27,29,25,32,34,25,31,36,44,92,81,92,99,76,79,90,115,99,49,55,58,75,71,41,29,32,27,28,27,27,34,33,38,37,39,31,25,32,33,27,21,25,25,29,26,19,23,17,20,24,31,32,37,38,34,42,39,42,46,65,68,49,45,35,26,18,20,27,28,31,25,29,37,26,19,28,28,24,21,26,26,29,29,26,28,28,21,25,33,27,34,26,71,158,192,191,184,153,134,100,49,51,67,55,27,21,44,55,65,68,66,68,77,98,112,107,89,55,30,25,24,24,50,79,63,62,72,71,59,63,41,50,90,106,118,101,112,102,56,33,50,85,81,64,23,65,222,235,244,241,233,239,236,236,236,236,236,235,236,235,235,238,234,234,234,233,237,234,235,234,235,236,235,236,234,236,235,236,234,233,235,234,233,234,235,235,235,236,234,235,232,233,232,233,231,231,232,230,233,235,231,232,233,234,235,233,229,118,3,0,4,9,9,9,11,9,11,12,11,12,182,189,185,187,188,184,187,185,187,186,188,186,182,185,185,185,188,186,188,185,186,188,185,188,189,186,189,186,188,190,188,189,189,189,190,190,192,190,189,189,192,188,188,190,189,190,192,191,192,189,190,191,187,189,193,190,192,193,194,193,191,194,194,190,193,195,192,194,194,195,196,195,197,195,195,193,195,197,194,196,196,195,194,196,198,198,197,197,197,195,196,195,196,196,195,195,198,196,194,195,194,193,194,195,193,193,194,194,191,193,195,194,194,192,196,194,193,193,194,192,193,193,195,198,195,195,195,195,196,197,197,195,194,195,195,196,194,196,194,191,195,192,193,194,193,195,194,194,195,195,194,194,194,194,194,194,196,195,195,195,196,196,195,198,196,196,196,198,197,194,198,195,196,193,191,196,193,194,195,196,196,196,198,197,196,200,202,201,202,204,204,204,204,203,204,202,205,203,202,206,205,206,204,204,205,204,204,203,202,206,206,202,204,203,204,201,199,202,199,198,196,198,199,198,203,199,199,202,201,204,204,208,207,204,207,205,206,205,206,211,209,207,211,209,212,213,214,214,214,213,217,207,207,216,217,211,202,212,215,213,214,214,212,211,212,211,213,214,212,214,214,215,213,213,216,213,214,211,212,212,212,211,208,209,210,214,214,213,214,211,212,215,214,215,214,215,214,216,216,214,216,215,215,215,215,214,215,216,211,216,214,216,217,198,208,199,207,220,212,217,214,214,216,216,216,199,190,190,234,195,191,172,104,107,50,178,250,250,253,253,252,252,252,252,251,249,252,249,248,194,49,53,128,113,67,39,24,31,33,42,33,33,33,35,32,90,208,251,243,105,115,188,132,165,168,170,169,217,252,252,252,214,226,179,83,139,178,147,182,189,181,250,173,146,231,225,214,206,218,227,214,195,222,218,178,187,205,251,150,53,107,79,67,24,31,97,61,41,190,209,110,61,9,7,69,226,251,212,176,42,24,17,5,33,39,39,21,24,50,59,56,35,122,239,252,252,200,213,247,251,252,222,173,119,155,215,221,249,236,228,174,117,184,235,249,138,19,25,85,69,26,77,119,102,40,78,90,110,139,119,50,16,45,34,35,39,28,35,29,15,24,19,16,29,24,22,24,24,29,29,35,37,32,30,37,36,39,36,47,97,91,110,117,97,128,117,89,63,48,55,64,63,61,41,24,28,27,29,27,27,34,31,33,42,33,29,26,31,30,26,23,27,28,27,30,27,22,23,18,24,33,34,39,37,38,42,46,50,51,57,59,57,48,38,34,41,47,35,29,22,17,24,20,21,23,23,26,27,23,24,30,31,31,24,27,27,29,27,30,31,34,33,75,155,173,176,171,165,165,158,95,60,98,59,30,21,23,31,33,40,39,45,49,59,93,112,95,58,31,22,24,22,50,83,69,63,80,76,51,63,45,45,90,108,118,99,117,99,61,94,103,120,113,109,60,34,193,236,243,246,232,240,233,234,236,233,235,234,234,234,234,237,235,231,234,236,234,235,236,235,235,236,236,236,234,234,236,234,235,235,233,235,234,234,237,235,234,235,235,233,232,234,238,238,235,236,233,235,236,235,234,232,234,235,235,234,230,119,3,0,5,8,9,9,11,10,11,12,11,11,184,188,184,185,187,185,182,187,185,188,186,185,188,184,186,184,187,186,187,186,185,187,188,186,188,187,189,188,188,189,188,190,189,188,190,189,187,190,189,190,191,190,190,190,192,191,189,189,190,189,190,192,192,192,193,193,193,193,193,194,197,193,191,196,195,193,195,194,195,194,193,195,194,193,196,192,193,196,196,197,195,196,196,197,196,195,196,196,198,198,193,196,196,196,198,194,194,195,195,194,196,195,194,194,193,195,193,196,193,194,195,190,192,193,193,194,193,193,192,193,193,193,196,194,195,196,195,194,197,197,195,198,195,196,196,196,196,196,196,193,194,194,193,194,194,195,195,196,198,194,196,193,194,194,196,198,192,196,197,192,196,194,195,195,196,198,196,198,199,198,198,198,196,196,197,197,198,198,199,199,198,200,199,198,200,203,203,204,206,203,204,205,206,205,204,204,203,204,205,206,208,205,203,205,203,204,205,204,205,205,206,206,206,205,205,205,203,203,202,203,202,201,202,201,202,203,204,204,203,206,206,207,209,208,208,205,208,208,208,210,208,212,212,213,214,214,214,213,214,213,214,203,208,215,214,208,201,214,215,213,215,212,214,212,214,213,213,214,212,214,213,214,214,213,212,214,214,214,215,213,214,216,215,209,207,211,215,217,217,216,216,216,215,217,218,215,216,219,216,217,218,216,217,216,216,217,216,216,215,216,216,215,220,200,206,201,204,221,213,220,213,213,212,212,217,196,189,193,239,207,204,177,113,113,57,176,248,235,249,241,250,250,240,225,195,210,205,214,227,99,42,75,145,152,81,39,24,30,37,44,42,35,34,38,33,29,158,238,243,145,87,186,207,250,250,240,226,251,252,230,198,145,221,205,143,191,188,122,136,147,186,250,146,168,236,222,216,201,223,224,214,193,219,222,180,190,205,251,154,53,95,79,79,33,36,75,63,40,192,209,89,54,6,4,134,245,252,214,96,11,19,6,18,38,37,29,16,44,55,59,30,97,226,245,250,201,201,240,252,252,253,216,131,144,217,241,237,246,247,178,123,173,231,247,250,153,41,43,71,81,45,29,39,42,53,107,97,108,141,104,38,21,43,33,41,39,26,43,28,19,21,20,22,18,30,26,23,29,34,37,39,41,33,30,29,33,41,34,48,62,69,55,67,90,102,81,65,42,50,80,61,57,56,45,37,22,23,30,27,28,34,34,31,36,36,34,26,33,30,31,29,24,28,28,36,28,28,29,18,24,32,35,37,41,44,48,55,54,62,56,54,66,55,40,32,43,49,32,19,18,15,18,17,21,20,22,25,30,21,25,27,34,27,24,30,27,26,33,33,45,65,81,127,156,151,141,139,139,152,147,98,75,97,63,27,29,21,19,20,20,19,24,18,29,51,82,90,63,40,19,24,24,51,80,66,73,79,74,54,63,48,38,88,98,113,102,112,113,92,127,110,79,48,86,90,39,173,237,234,246,236,237,233,233,235,232,233,233,233,233,236,234,234,234,232,233,235,235,235,233,234,233,233,234,235,236,232,233,233,235,235,234,235,234,232,235,235,233,232,234,233,236,239,241,241,240,240,240,239,238,236,236,238,237,238,234,229,117,4,0,4,9,10,9,10,10,11,12,12,11,184,188,185,186,187,184,186,186,185,186,187,189,190,186,188,185,185,188,191,189,187,191,187,188,189,187,189,187,189,191,191,191,190,188,189,188,187,189,188,190,192,191,192,190,190,192,189,191,192,190,192,194,193,195,196,188,193,195,192,195,194,195,196,196,197,196,195,197,195,195,196,196,194,194,198,192,195,196,194,198,198,198,196,197,196,195,199,198,199,196,195,198,195,198,195,194,194,193,193,194,196,195,195,194,193,193,193,193,194,195,192,193,193,191,195,191,193,194,193,196,196,196,193,193,196,194,196,195,197,196,196,197,195,198,198,198,196,197,195,192,196,193,196,196,196,194,194,196,195,194,194,195,193,197,198,195,194,196,198,195,194,197,196,196,195,198,198,195,198,198,200,197,199,199,199,201,198,200,200,200,200,200,202,201,202,204,202,200,202,204,206,206,205,207,207,206,206,206,208,208,207,207,207,207,208,205,208,208,208,209,209,206,209,208,209,207,206,208,205,206,204,204,206,203,206,202,202,206,205,207,206,210,210,208,210,211,214,212,212,211,212,213,214,214,214,215,214,214,215,217,211,204,211,215,212,203,206,216,215,215,214,214,214,214,214,211,212,214,212,214,213,214,214,212,217,213,217,218,214,218,215,216,219,214,208,207,213,217,218,219,217,217,218,217,218,217,218,218,216,218,218,218,219,218,220,217,218,215,214,216,216,215,219,201,206,201,201,220,212,214,214,213,212,215,212,196,184,205,243,220,213,130,62,67,29,115,183,206,218,201,214,207,204,179,143,157,150,179,196,92,65,94,158,160,109,50,16,22,38,48,38,40,36,34,39,35,113,208,231,122,11,59,179,243,249,219,184,220,174,183,158,141,217,210,197,205,162,108,151,169,229,243,134,198,234,226,220,199,224,222,215,195,220,219,179,185,205,251,155,47,73,84,87,57,55,84,69,61,207,171,63,48,4,42,206,248,253,145,33,10,10,11,35,46,25,15,34,52,64,26,77,213,249,249,204,200,235,250,251,248,252,170,157,216,236,245,215,246,193,119,182,223,249,249,252,202,100,30,16,62,71,66,56,72,101,89,103,123,121,84,29,24,34,32,44,36,28,38,29,22,25,21,27,29,27,33,28,33,36,35,42,36,35,33,27,35,39,39,49,77,57,70,101,93,78,64,54,44,64,56,46,59,51,50,37,19,22,28,31,30,28,34,39,34,38,36,30,33,29,29,32,26,23,35,34,35,30,27,29,21,34,37,41,52,41,49,56,56,60,63,53,50,57,44,32,30,33,22,13,16,18,15,19,24,18,29,25,27,26,23,29,29,31,30,28,24,31,43,88,131,149,156,165,151,130,126,127,127,137,134,80,55,74,49,33,28,24,24,24,20,21,19,18,27,33,64,87,75,43,23,24,16,43,78,66,75,76,72,52,59,52,26,83,107,105,97,102,105,107,119,53,64,76,85,107,36,159,236,226,248,238,239,234,235,237,231,236,233,233,233,233,233,233,234,236,233,234,233,231,234,235,236,233,233,235,234,234,233,235,235,233,234,233,232,233,233,234,232,233,236,238,241,243,244,243,245,244,243,243,242,244,244,245,241,238,234,227,117,4,0,4,8,10,9,10,10,11,12,11,11,183,190,186,185,186,185,184,190,186,186,186,184,187,183,184,184,185,185,185,184,187,185,187,189,189,188,187,189,190,187,190,191,191,187,188,189,188,191,188,190,187,189,192,189,189,189,192,190,192,191,193,193,191,192,191,190,191,193,194,194,195,194,193,196,193,196,193,194,196,194,196,193,194,196,196,192,196,197,194,196,195,195,196,195,195,195,198,194,195,196,196,196,194,193,191,193,195,193,191,193,193,193,195,194,193,191,191,194,190,192,192,191,196,192,192,194,192,194,196,196,192,192,196,194,194,194,194,195,193,196,194,196,195,195,193,193,194,194,196,192,196,196,196,197,195,196,195,191,196,194,194,195,195,193,192,196,193,196,197,193,197,195,197,199,198,198,198,200,196,197,199,198,200,199,201,202,200,200,198,200,199,200,204,201,201,201,201,200,201,202,205,206,205,206,205,205,208,208,206,206,207,208,206,206,206,208,208,207,210,208,205,207,208,208,206,206,208,207,206,208,208,206,207,207,206,203,205,206,204,209,209,208,211,209,211,211,212,212,214,214,213,215,216,214,214,212,212,213,212,214,205,203,213,215,208,202,211,217,214,212,213,214,214,212,212,212,214,215,213,214,213,213,214,214,215,216,215,214,214,213,217,216,214,217,214,208,206,212,217,218,217,218,217,218,219,218,220,218,217,218,220,219,219,217,218,219,217,217,216,214,216,212,219,202,202,202,199,220,212,215,212,211,214,217,210,191,192,209,232,159,111,76,25,38,19,47,69,135,187,178,190,183,188,170,141,175,185,234,210,106,120,108,173,186,126,66,11,24,39,39,43,34,41,33,62,140,200,241,219,150,57,9,129,213,213,146,129,183,164,215,197,176,214,198,158,148,162,173,205,203,251,216,130,224,232,231,215,198,223,217,217,195,222,219,174,183,203,251,158,48,71,65,63,54,56,78,89,62,131,94,34,47,5,93,249,249,198,68,12,7,6,27,47,32,12,30,47,66,37,56,189,243,251,190,196,238,251,252,249,251,191,159,228,235,237,228,215,195,135,171,235,245,249,249,253,219,84,35,7,34,79,111,71,107,61,59,112,125,122,64,19,25,31,33,45,38,29,36,32,25,24,27,27,30,31,29,32,32,35,37,40,34,37,37,31,30,45,29,41,94,72,107,125,105,70,66,86,74,84,54,30,49,51,40,27,18,27,27,23,34,29,29,34,34,33,27,33,32,28,32,25,26,30,27,33,32,33,34,22,30,44,48,62,61,45,50,57,51,53,54,49,35,33,39,29,23,24,19,19,16,15,27,23,27,24,23,28,25,25,25,29,31,27,27,26,29,36,104,152,157,160,152,145,132,124,113,116,121,133,122,61,36,44,30,21,29,27,25,27,27,27,19,19,22,21,42,74,71,44,22,27,19,37,81,66,66,68,68,54,56,54,25,77,105,107,92,95,103,100,105,54,110,149,159,125,21,144,232,235,249,240,242,236,233,238,236,238,237,236,235,235,234,236,238,237,238,233,231,236,237,240,237,236,236,235,236,238,238,234,233,233,231,233,234,233,234,233,233,235,239,241,244,245,244,244,247,245,244,244,246,243,244,243,240,236,232,229,118,3,0,4,8,9,9,10,9,11,12,11,11,184,188,187,186,186,184,185,186,186,190,188,184,185,183,186,186,187,185,185,187,188,190,189,188,193,189,190,191,190,193,189,190,191,188,191,188,189,190,189,194,190,190,193,190,190,191,192,192,190,193,193,194,194,191,197,195,195,195,194,195,196,195,194,196,193,196,194,192,195,194,196,195,193,196,196,193,197,195,195,195,196,196,192,197,196,195,196,196,199,194,195,196,194,196,194,193,196,194,194,195,194,194,194,195,192,192,193,191,194,192,192,193,193,195,196,193,193,194,193,194,191,191,191,195,198,196,195,195,197,195,195,196,193,198,193,192,193,194,196,192,196,196,196,196,195,194,194,193,195,196,194,194,194,195,197,196,195,195,194,196,198,196,198,197,196,200,199,199,201,199,200,200,201,201,200,202,200,201,202,201,200,201,204,203,202,201,203,206,206,204,206,207,205,210,207,207,205,205,211,206,207,207,206,208,208,208,208,207,208,208,208,207,209,207,208,211,210,210,210,210,212,211,211,210,213,212,207,210,210,214,212,215,214,211,214,214,213,216,217,216,217,214,214,215,216,213,211,213,214,213,202,206,216,214,206,206,213,214,216,215,212,214,212,214,215,211,214,212,214,216,213,214,212,215,216,212,215,214,212,212,214,214,215,214,216,218,210,209,213,217,217,220,219,218,217,217,221,219,219,218,219,219,220,220,219,218,220,218,216,214,213,212,222,205,203,201,199,218,214,214,214,211,215,218,207,192,185,211,186,77,26,9,13,27,32,63,29,58,129,161,200,196,216,178,150,216,229,251,178,102,132,106,188,189,145,84,7,26,35,39,44,33,44,26,78,173,219,249,232,207,137,26,93,138,164,123,137,186,182,223,203,202,164,160,142,164,188,190,214,208,251,182,150,241,223,235,208,200,227,219,221,197,225,218,175,181,201,251,155,51,95,73,47,60,58,70,91,48,48,36,78,59,9,146,250,234,95,19,14,4,23,44,36,18,23,47,63,47,45,165,246,246,178,167,232,251,252,243,252,191,155,211,242,239,216,236,160,100,158,229,249,249,247,247,239,159,156,116,58,59,55,70,64,57,38,62,131,130,112,56,16,29,33,35,39,35,34,37,23,25,27,24,27,28,32,39,34,28,36,33,37,37,34,27,30,36,33,36,75,97,92,91,67,69,50,56,66,37,54,43,39,59,36,27,22,17,23,23,33,34,28,33,30,36,35,31,33,29,29,28,25,24,31,33,32,37,34,31,35,64,90,84,88,71,51,53,48,43,40,39,33,30,21,28,32,22,19,16,17,23,39,34,25,20,21,25,24,24,19,28,29,29,33,28,28,24,75,143,153,128,118,115,116,115,112,104,111,122,133,115,57,27,20,16,24,29,30,31,26,31,22,26,28,21,24,36,61,52,35,23,20,26,39,77,71,62,61,60,57,46,55,29,65,107,104,100,95,98,101,104,49,80,125,125,91,13,124,227,240,250,242,243,240,240,243,240,241,242,243,243,242,242,243,243,243,244,243,243,245,245,244,241,239,237,238,241,242,241,239,236,237,239,238,238,239,238,235,237,240,241,243,244,246,245,245,247,247,245,246,247,244,242,241,241,242,244,234,116,3,1,6,9,9,9,10,10,11,12,11,11,182,186,185,183,186,184,184,186,184,184,186,186,188,186,186,187,186,188,188,188,190,189,192,190,188,193,191,190,193,190,189,190,190,191,191,191,189,191,191,190,193,192,191,190,191,193,194,192,192,193,194,193,193,194,196,195,195,193,193,194,191,193,195,197,192,193,195,193,196,193,194,195,191,194,194,193,195,197,193,194,194,194,196,194,193,193,195,197,198,196,194,195,195,195,196,196,195,191,194,195,192,191,193,190,192,194,194,195,193,195,192,193,196,194,192,194,196,191,193,192,191,193,191,193,191,190,194,198,195,194,195,194,194,193,194,192,191,192,193,193,194,193,193,193,193,195,198,194,196,195,193,196,195,193,196,194,192,196,197,196,198,199,199,198,199,201,200,200,198,202,199,197,204,201,203,202,200,203,200,201,203,201,201,200,202,203,203,206,207,209,208,205,208,208,208,208,208,206,205,208,210,211,209,208,210,208,208,207,209,207,207,208,207,209,212,212,214,213,213,213,211,214,214,217,216,212,214,214,214,217,218,217,216,215,217,217,215,217,219,218,215,215,214,212,215,213,210,212,214,212,203,212,218,207,203,208,215,214,213,214,214,214,210,211,211,211,213,215,214,213,215,214,214,212,214,213,212,214,215,214,214,215,213,214,217,216,219,212,209,213,217,222,218,220,217,218,219,221,220,217,218,218,222,220,220,220,217,217,219,214,216,213,221,206,199,206,198,217,214,214,216,214,216,218,208,189,193,192,150,77,16,10,33,60,71,87,42,70,163,190,221,217,224,166,157,222,240,225,124,100,139,98,178,182,113,81,14,24,34,40,39,31,48,19,79,153,194,249,191,215,170,37,64,162,221,169,192,188,168,162,160,128,142,192,160,190,179,176,175,214,251,151,169,241,220,240,207,204,224,218,222,193,222,221,174,179,204,251,159,48,108,96,69,75,61,63,96,60,60,114,195,103,26,180,248,133,36,17,6,16,40,42,22,23,43,57,57,38,135,240,249,199,147,214,252,252,236,232,188,149,205,234,249,214,219,217,71,84,201,244,247,246,246,229,93,85,135,147,85,36,37,46,47,51,36,100,143,137,122,45,15,28,29,32,47,35,31,39,24,27,29,21,26,29,31,35,37,31,35,33,29,34,34,32,29,35,31,38,56,74,84,67,48,59,41,27,41,35,31,26,42,43,23,22,20,19,19,24,29,28,29,29,32,29,33,32,32,32,30,28,27,29,24,37,35,35,42,37,50,126,163,133,98,111,75,52,45,35,36,36,34,27,27,26,33,29,25,32,31,51,57,38,23,19,24,21,21,28,27,24,26,31,29,23,28,29,95,150,126,119,114,110,107,102,109,109,116,117,130,106,54,26,21,24,22,29,26,30,32,29,37,34,25,21,24,24,32,31,24,26,24,24,36,80,68,60,60,66,61,48,59,30,70,118,114,101,97,101,92,102,72,51,47,51,42,7,141,241,247,249,244,242,243,244,244,242,244,246,246,247,247,247,248,249,248,248,248,249,251,248,249,247,245,246,246,247,245,246,244,244,244,246,247,243,243,243,240,242,245,246,245,245,247,245,247,247,246,247,247,247,244,244,243,245,249,250,237,116,4,1,4,8,10,9,9,10,11,12,12,12,181,186,186,184,189,185,183,183,185,187,184,184,185,185,184,185,187,186,188,188,188,190,190,191,192,189,193,193,191,192,190,191,191,191,192,189,191,190,190,191,189,192,192,191,191,189,193,194,193,195,191,195,194,190,195,191,193,195,192,193,196,193,193,196,195,195,191,195,196,194,194,195,195,193,197,198,198,196,195,195,194,194,191,194,194,192,195,194,195,195,196,198,195,193,196,192,192,195,191,192,191,191,191,193,192,191,191,193,193,192,193,190,193,193,189,190,193,194,192,192,192,192,194,194,194,191,191,194,191,193,191,191,194,194,191,192,193,193,192,193,191,192,195,194,195,194,194,194,194,196,195,198,197,194,196,195,193,200,200,198,198,196,200,199,201,203,201,202,201,200,202,200,201,201,201,202,203,203,201,201,202,203,201,200,205,204,205,208,207,204,208,210,206,208,206,208,208,205,209,207,211,211,211,211,207,208,209,210,208,208,208,207,212,209,211,215,211,214,216,216,216,215,216,215,215,215,215,215,216,217,215,217,216,216,217,216,216,215,215,215,215,214,214,213,213,214,210,210,216,208,205,214,214,207,203,211,214,212,213,213,213,214,211,212,212,212,214,214,214,213,213,212,212,213,213,212,214,215,214,214,213,212,217,216,214,216,217,219,212,209,211,217,222,223,220,219,219,217,221,219,220,218,218,221,219,219,220,216,217,215,220,215,221,207,200,204,196,217,217,214,219,215,218,224,211,199,211,232,204,128,97,89,96,100,79,87,56,120,216,188,207,215,232,185,168,223,230,171,97,103,151,106,174,174,52,60,31,21,38,39,45,32,46,15,72,145,190,232,165,210,199,58,60,206,249,211,220,194,146,129,164,136,150,189,155,139,106,145,189,247,249,143,200,241,221,243,206,205,221,218,221,194,227,222,174,182,206,251,158,53,100,93,74,56,46,50,96,87,128,185,237,135,89,201,143,54,21,15,13,33,42,28,26,37,54,62,35,105,226,246,215,149,194,245,252,250,225,175,146,201,239,252,239,203,183,121,87,179,237,247,246,245,227,78,14,49,112,132,78,24,27,45,50,51,41,115,144,136,113,34,19,36,30,33,45,31,29,39,27,28,25,25,28,26,30,40,35,33,32,29,38,36,34,31,26,29,34,33,44,59,65,42,53,77,32,42,60,30,34,28,30,32,14,27,24,18,22,27,34,25,28,30,29,37,33,35,39,32,33,30,27,25,26,34,37,37,42,39,63,129,156,125,98,92,76,61,45,29,33,33,29,24,28,25,25,32,44,47,53,53,40,25,21,26,19,22,23,19,27,22,27,28,27,27,30,22,96,144,122,117,109,106,110,113,111,113,113,108,116,94,53,28,22,24,28,32,33,31,26,30,36,33,32,29,26,28,29,26,26,21,24,25,33,77,71,61,66,72,69,47,62,34,63,125,115,111,96,98,86,85,92,84,57,39,20,89,249,249,249,249,244,248,242,244,244,243,247,249,247,248,249,249,250,248,250,249,249,249,247,248,250,250,249,247,248,248,247,247,247,246,247,247,247,245,244,244,244,244,245,245,248,248,247,247,248,246,247,247,245,245,244,245,248,250,251,250,236,116,4,1,4,8,9,9,10,9,11,12,11,11,183,187,185,184,185,184,185,184,184,187,186,184,186,183,185,188,188,188,188,187,191,194,191,194,196,194,194,191,193,192,191,194,192,191,190,189,190,192,192,192,193,191,193,194,191,191,193,192,190,190,192,191,190,190,194,195,192,194,192,194,193,193,193,196,193,193,195,194,199,196,194,195,196,198,197,199,196,197,194,195,196,197,198,194,195,196,194,195,196,194,195,196,198,196,193,197,194,188,193,193,191,194,192,190,193,191,193,191,191,192,193,192,192,192,192,190,192,191,196,195,191,194,193,192,193,193,192,192,193,193,192,190,191,192,193,192,195,195,192,194,193,194,193,193,194,194,196,190,195,197,195,200,198,198,201,197,199,203,200,199,200,200,200,200,200,200,200,200,200,201,201,200,203,200,201,204,200,202,202,203,202,202,204,204,206,204,207,208,206,208,209,209,209,209,209,207,208,209,208,210,210,208,209,211,210,210,210,209,211,210,211,211,212,214,213,214,214,214,212,216,215,214,215,215,214,214,217,215,215,214,214,214,216,214,212,215,215,214,214,213,214,214,214,213,212,213,210,213,213,205,205,215,211,203,210,211,212,213,210,212,213,214,213,212,213,214,214,214,213,212,214,213,213,212,213,214,212,214,212,210,213,215,213,215,217,215,217,215,220,216,211,212,220,230,233,234,225,221,221,219,219,218,220,217,220,218,219,220,217,216,216,214,222,208,198,208,196,214,220,219,222,224,229,231,210,197,209,223,225,186,187,169,132,119,78,134,129,120,221,208,213,234,244,194,179,220,208,128,96,115,153,113,181,191,24,29,20,37,71,62,55,31,40,11,110,176,198,223,186,227,205,108,77,190,207,170,169,170,179,194,230,178,205,166,95,109,98,147,182,244,210,134,227,245,234,244,205,211,223,224,222,192,226,222,173,178,205,251,153,48,97,71,50,61,40,49,63,86,135,163,243,193,183,163,37,18,22,11,27,42,29,22,36,50,66,34,84,207,249,229,148,181,232,249,252,239,186,149,205,242,252,247,234,170,74,125,152,230,249,249,244,220,87,21,37,89,100,117,136,71,43,44,52,49,70,141,122,129,95,23,23,30,33,36,48,35,31,36,24,25,22,26,34,26,29,37,35,35,32,33,35,34,29,31,28,27,32,29,45,43,35,24,44,56,42,68,57,37,32,28,38,23,17,31,23,27,24,24,31,29,34,33,29,38,33,31,38,32,33,26,27,28,31,39,33,34,32,37,59,121,120,87,96,82,69,59,34,28,32,29,23,22,25,25,25,34,45,34,39,43,29,24,27,23,19,23,24,22,23,30,27,30,31,22,33,26,91,139,121,122,101,99,89,71,76,86,101,105,111,81,53,29,19,30,26,29,33,26,32,30,33,38,32,32,29,28,30,29,33,29,26,29,35,81,72,65,69,66,70,49,63,40,50,117,115,107,105,107,78,49,75,105,112,99,173,246,252,252,251,248,250,249,247,242,244,247,248,248,248,249,248,248,249,248,248,251,251,250,249,247,249,249,249,249,249,248,246,250,248,248,248,247,247,246,248,246,244,244,245,247,247,246,248,248,247,245,246,245,244,244,245,247,249,251,250,249,236,116,3,1,4,8,10,10,10,10,11,12,11,11,183,189,187,184,187,185,185,188,187,188,185,185,188,190,187,187,190,190,192,191,191,194,193,195,194,194,195,193,193,189,190,192,192,193,191,191,193,191,196,194,192,193,194,196,194,194,195,191,190,193,191,193,191,192,193,191,193,193,195,194,195,194,195,195,191,194,194,194,194,196,198,198,199,198,198,198,195,195,196,196,198,199,195,196,198,194,195,196,195,197,196,195,195,196,198,196,195,194,193,196,193,191,190,191,195,190,192,193,192,192,193,191,191,192,192,194,194,193,194,196,197,196,196,194,193,194,195,193,192,193,194,194,193,193,193,195,196,195,195,195,195,196,197,195,194,196,194,197,198,198,200,203,205,203,201,202,203,203,202,202,202,203,205,201,201,202,200,205,202,200,203,202,202,200,204,203,199,200,204,205,204,206,205,208,208,205,208,208,210,211,211,212,209,211,212,212,212,210,212,209,211,211,210,214,212,214,212,212,213,213,213,211,215,212,214,215,212,216,214,214,215,213,213,214,214,215,217,213,215,216,213,214,215,216,213,212,215,214,214,215,214,212,215,214,212,214,213,217,212,201,212,215,207,206,212,214,213,211,213,216,212,214,214,214,215,214,214,213,213,212,212,214,213,211,213,214,214,212,212,214,214,214,217,216,215,217,217,219,218,223,215,211,215,229,248,248,239,226,222,221,219,219,219,221,219,218,219,217,220,217,220,213,220,211,200,211,200,222,229,226,231,225,218,205,169,158,167,142,142,182,240,202,159,126,95,205,189,129,218,214,225,242,237,170,155,219,184,111,115,123,170,121,184,211,27,5,29,92,105,91,68,36,20,83,221,209,200,217,211,221,216,168,77,92,107,135,173,198,199,240,241,208,208,125,98,139,170,177,185,221,143,122,210,216,224,237,212,215,229,230,226,195,228,222,173,177,205,251,145,71,100,79,88,68,48,45,48,56,95,184,252,252,211,81,1,24,21,27,42,32,18,29,48,62,39,59,184,244,242,159,173,224,250,250,252,205,150,203,247,252,251,243,234,95,97,194,183,245,247,247,234,83,25,43,93,116,116,166,199,129,77,73,93,97,123,142,122,127,78,20,25,36,32,36,47,28,33,39,24,27,18,25,29,25,30,36,36,37,31,29,38,31,32,30,27,29,34,35,27,19,19,24,24,24,34,65,56,38,33,21,24,22,24,25,22,30,26,30,33,29,32,31,31,37,36,33,34,35,29,25,25,32,32,31,40,36,31,39,51,91,130,99,74,83,55,38,38,30,26,20,25,21,24,28,28,42,46,48,40,30,24,23,24,21,23,22,27,29,29,32,31,34,31,26,27,26,53,106,125,118,99,76,60,54,35,38,66,88,101,88,62,37,27,27,31,30,28,30,29,30,28,29,32,39,36,33,35,33,41,34,33,35,38,84,72,66,68,64,68,51,69,41,45,111,105,110,107,112,95,61,68,105,102,113,187,206,242,252,251,251,248,251,247,247,249,247,247,248,248,249,248,249,249,248,251,250,248,250,250,249,251,249,249,251,251,251,248,249,249,249,251,249,248,247,247,245,244,245,247,247,247,247,246,245,246,247,247,246,246,246,248,249,251,250,248,249,236,117,3,1,4,8,9,9,10,9,11,12,12,12,185,190,187,188,186,186,187,187,188,189,189,188,190,189,190,189,188,190,191,191,193,194,192,195,191,193,195,190,193,193,193,194,193,193,192,193,193,197,196,192,196,193,193,196,193,193,193,192,194,194,194,193,194,192,192,195,192,197,196,198,196,196,197,196,196,194,196,198,198,196,198,201,200,200,200,199,198,194,197,199,196,198,200,197,198,197,196,196,195,196,195,195,198,198,195,193,192,193,194,192,192,193,193,191,194,193,193,194,193,191,194,192,194,193,193,191,194,196,193,196,195,198,198,195,196,195,196,196,194,193,194,197,197,195,196,197,200,198,198,199,196,200,197,197,197,198,199,198,201,200,202,203,203,203,205,205,202,204,204,203,203,204,203,203,203,205,205,203,205,205,205,204,204,202,202,206,203,204,204,203,205,206,208,206,206,207,208,210,210,211,210,211,209,210,211,212,212,211,211,212,214,213,214,213,211,214,214,213,214,212,213,211,214,213,211,212,210,214,214,216,214,210,214,216,214,214,214,214,215,214,216,214,212,215,213,214,213,214,215,211,215,212,211,213,211,214,211,216,208,203,212,211,204,209,216,212,214,214,213,214,214,213,211,211,213,213,211,214,213,211,214,214,215,213,213,214,212,214,213,215,214,215,215,216,216,216,219,217,221,223,219,215,196,178,192,217,231,229,222,222,220,221,221,217,222,218,219,218,217,217,218,216,224,218,207,219,208,222,222,207,195,181,177,172,155,165,158,99,118,172,231,181,169,124,79,229,218,90,146,182,192,215,201,154,155,195,154,120,134,142,198,130,192,238,62,15,62,128,119,104,84,38,24,145,250,217,185,219,226,187,185,151,50,40,61,154,215,223,210,231,167,144,198,142,108,153,190,202,234,239,127,126,192,179,194,203,190,203,227,234,228,199,235,229,178,177,212,252,128,67,125,109,96,79,43,36,34,82,159,234,252,252,144,22,4,26,30,38,34,18,23,43,61,54,45,153,248,248,171,171,222,248,252,252,234,152,197,244,252,252,250,245,177,126,186,235,198,244,244,244,104,11,48,87,118,113,125,153,177,114,51,33,70,77,99,134,117,132,63,15,29,33,29,41,51,32,35,37,23,27,23,27,29,25,33,39,36,36,39,31,29,36,36,32,30,36,33,32,29,26,26,23,18,18,38,59,47,37,47,23,17,26,21,23,26,29,28,31,37,30,31,32,32,39,34,34,32,34,31,27,27,23,34,39,30,33,37,38,50,78,110,127,96,56,52,35,23,27,23,19,22,20,23,32,33,44,59,54,32,21,19,19,22,25,23,22,25,30,31,26,31,36,31,25,29,27,33,63,106,126,93,74,77,74,62,42,34,68,108,114,95,58,33,29,27,33,28,30,30,32,30,33,38,34,36,35,36,38,39,39,34,35,42,85,74,60,61,64,77,53,71,52,33,110,116,110,115,116,104,88,66,89,53,27,5,79,218,247,250,250,248,250,249,251,249,247,247,248,249,249,249,250,249,249,251,251,249,249,251,252,252,251,250,251,251,251,250,252,250,251,251,251,251,247,248,245,244,245,246,246,247,247,245,245,247,246,245,245,245,246,248,249,249,249,250,249,236,116,4,1,4,8,9,9,10,9,11,12,12,12,187,193,190,186,191,191,187,191,189,189,191,190,191,190,191,191,192,191,193,195,194,194,194,191,193,194,194,195,194,195,194,193,193,196,196,193,196,196,197,195,198,198,196,195,193,197,199,195,196,195,195,196,194,197,196,194,196,195,195,196,196,191,194,196,196,197,196,198,198,196,196,199,198,201,200,200,199,196,198,199,198,198,195,198,198,196,198,198,197,198,197,195,197,197,194,197,195,195,194,194,193,193,193,191,193,192,193,192,192,194,195,194,192,195,195,193,197,196,196,197,196,197,199,199,198,198,195,197,198,196,199,199,198,198,198,200,198,199,200,200,199,200,200,199,200,199,199,200,201,203,205,202,201,202,203,204,205,203,204,204,202,202,203,204,204,206,202,206,203,202,207,203,205,206,206,206,204,205,206,205,207,208,206,208,208,209,212,210,210,210,210,212,211,211,210,208,210,210,212,212,215,214,210,214,213,212,211,212,212,214,214,211,213,212,214,213,211,215,213,213,214,212,214,212,214,213,214,211,211,217,217,214,214,214,213,214,214,212,212,213,215,212,212,213,212,211,212,214,204,204,216,207,204,212,213,214,214,212,212,212,211,214,212,212,212,211,212,212,214,214,210,214,212,212,214,214,214,212,215,216,214,215,216,216,216,217,217,219,218,222,218,224,184,85,71,125,199,230,225,225,220,222,221,220,223,219,220,218,221,220,224,222,230,225,207,213,188,189,178,163,175,178,192,200,182,201,207,188,178,185,198,127,174,117,56,201,196,94,146,152,156,198,199,162,144,170,134,137,145,165,220,125,192,252,126,56,89,157,143,124,120,57,34,181,251,191,157,219,199,130,150,158,108,63,83,160,229,207,192,197,127,159,190,168,133,125,159,196,252,244,142,196,233,202,198,190,178,183,205,211,213,194,235,232,187,183,217,238,89,49,101,96,91,50,28,28,59,129,198,249,252,164,50,13,11,27,37,36,24,20,34,55,55,43,141,243,249,182,169,222,247,249,249,235,154,177,243,251,249,244,245,159,179,192,226,248,202,248,236,107,34,44,90,115,114,120,114,81,120,91,34,19,45,52,103,127,120,117,42,23,29,31,34,44,53,27,39,40,22,27,24,23,29,26,33,37,34,38,31,34,33,35,39,30,31,32,32,30,29,28,27,28,23,23,31,47,43,55,51,21,24,19,26,37,24,31,37,34,34,30,29,28,34,37,31,33,32,31,33,26,27,29,30,34,32,31,31,60,59,56,119,135,96,64,47,40,38,26,21,18,16,22,26,27,36,47,54,49,23,23,23,18,22,18,29,25,27,26,24,33,32,30,32,29,24,29,22,38,71,98,109,91,100,105,71,64,42,55,99,124,145,100,53,33,25,29,30,29,32,39,31,34,38,36,39,35,38,41,38,37,40,35,37,89,76,61,62,64,81,55,70,56,28,99,116,116,117,112,112,71,58,47,48,11,59,214,251,251,250,248,251,250,249,249,249,249,250,249,249,250,249,251,251,249,249,249,251,251,251,251,252,251,250,251,251,252,250,251,251,249,250,249,248,248,248,247,245,246,247,245,245,245,245,247,246,245,244,244,246,247,249,249,249,250,250,250,237,115,4,1,4,8,9,9,10,9,11,11,12,12,187,194,191,193,191,191,193,191,192,191,192,193,192,189,194,194,195,197,194,196,196,195,194,198,193,194,197,191,196,195,192,194,192,194,197,195,194,197,196,196,198,196,199,198,194,196,197,196,196,195,198,198,198,198,198,196,195,198,195,198,197,196,197,196,198,197,197,199,196,198,199,198,198,199,197,196,199,195,196,196,199,199,198,199,198,198,199,198,198,198,195,198,196,198,198,195,196,194,195,196,196,194,195,193,194,194,195,195,194,195,198,196,196,195,195,197,196,197,196,198,196,198,201,200,199,198,198,198,198,200,201,201,200,200,200,198,200,199,201,201,200,203,201,202,203,201,200,200,204,205,203,203,202,200,201,200,202,204,203,204,203,204,203,203,203,203,204,202,204,206,202,205,206,205,207,207,204,206,208,208,208,209,208,206,207,210,210,211,210,208,212,213,210,210,210,210,209,208,211,211,213,213,211,212,211,213,211,211,213,210,213,209,213,213,210,212,213,213,212,213,213,212,213,214,212,213,213,212,213,211,212,212,212,213,210,212,211,213,214,213,214,209,212,215,212,211,211,210,202,212,212,201,205,211,214,212,212,212,214,209,211,211,211,213,210,214,211,210,211,211,212,211,212,212,211,214,214,214,213,214,216,217,215,215,214,216,217,215,216,217,221,226,203,133,94,116,177,217,226,227,219,219,220,218,222,220,222,225,226,224,224,221,217,205,177,175,164,178,190,195,210,219,229,223,198,214,232,245,211,182,202,129,172,111,62,191,173,118,197,205,191,224,222,167,134,157,130,143,141,179,222,92,174,249,175,67,77,151,149,137,120,61,32,185,251,151,134,209,183,149,185,224,196,108,85,169,200,157,198,218,187,190,188,141,107,145,182,214,252,208,144,227,242,235,238,230,207,188,202,200,199,179,217,214,178,186,214,201,69,50,80,67,64,25,25,19,54,116,147,246,201,57,19,10,17,38,41,31,15,27,53,60,39,56,193,243,189,162,210,246,249,249,234,162,160,217,251,245,236,236,164,152,240,214,245,240,212,246,92,35,44,86,123,110,119,101,59,59,121,85,35,21,130,186,157,132,110,105,37,18,36,34,35,42,47,33,39,34,29,28,22,29,27,28,33,32,34,35,33,33,31,33,33,36,33,29,30,29,31,33,33,34,31,27,24,34,77,84,64,33,19,30,31,36,31,28,37,37,32,29,32,28,30,36,33,29,36,30,32,34,22,28,32,28,34,37,76,96,66,53,63,100,98,68,49,40,44,41,29,19,21,19,17,27,38,44,39,33,24,16,26,26,22,24,20,27,25,27,35,30,35,30,31,29,23,24,26,29,36,68,101,118,122,118,86,71,50,47,84,108,158,168,96,45,28,23,31,34,34,35,34,37,38,41,39,33,39,35,34,38,36,40,39,87,81,62,64,63,74,54,63,63,25,84,116,110,120,107,105,72,53,56,18,112,248,248,248,248,252,252,249,251,249,247,248,249,251,250,251,250,250,248,248,248,249,250,248,250,251,251,250,250,250,251,251,251,249,250,249,248,247,248,248,247,247,245,246,245,245,245,247,247,245,245,246,245,245,245,244,246,248,249,250,251,250,250,237,116,3,1,4,8,9,8,10,9,11,12,11,11,189,194,195,191,193,192,191,193,192,193,195,195,195,194,194,196,199,198,195,196,194,196,197,194,197,196,193,193,194,193,195,195,194,194,193,194,193,196,194,194,195,195,196,195,194,196,197,196,197,196,198,198,195,196,198,198,200,199,197,199,198,198,199,197,200,198,198,199,198,199,197,198,197,198,197,194,198,196,196,197,193,198,196,198,200,198,198,200,199,195,197,197,198,195,196,198,196,196,198,197,197,197,196,197,197,196,197,194,196,196,195,197,196,200,199,197,199,198,198,197,199,200,200,199,198,201,200,200,200,200,203,201,204,202,200,203,200,201,203,201,201,202,204,200,203,201,200,204,200,204,203,201,203,203,202,202,201,202,201,201,203,202,202,204,204,203,203,205,205,205,207,205,206,204,207,207,207,208,208,208,207,207,210,210,208,209,207,207,210,209,209,211,209,210,212,210,212,210,210,210,210,212,208,211,212,212,213,211,212,212,210,211,213,211,212,211,211,212,210,212,212,212,213,211,213,212,214,212,212,213,212,214,212,213,211,211,212,210,212,211,213,211,212,213,212,212,213,208,201,212,208,200,209,213,211,212,211,212,213,212,212,210,211,212,212,214,212,211,213,212,210,212,212,212,214,213,214,214,214,217,215,214,217,218,216,215,214,217,216,218,217,228,232,217,208,188,183,194,211,225,223,224,222,221,225,222,224,222,218,209,201,191,191,188,173,192,190,211,229,227,235,231,235,219,188,211,227,242,185,160,215,155,178,109,96,236,193,114,210,239,215,230,219,155,138,160,133,156,136,195,206,75,174,249,183,57,75,144,137,120,101,54,27,190,242,122,160,244,190,181,216,249,224,108,66,139,194,197,237,227,226,198,145,119,141,193,215,237,251,170,149,238,234,236,235,239,222,214,237,229,214,181,205,199,166,167,179,177,71,56,79,50,62,31,27,45,86,107,134,184,84,21,22,9,29,45,28,19,31,45,57,51,42,96,223,190,157,207,238,249,247,240,164,166,218,245,252,229,231,162,153,224,250,221,243,237,171,108,25,53,83,116,118,119,80,58,46,56,141,78,32,31,130,164,150,132,117,94,22,26,32,38,39,44,45,29,39,34,22,25,23,28,27,33,33,32,35,34,32,36,33,29,40,39,33,32,29,34,34,31,33,35,30,28,28,32,65,81,69,47,24,30,34,37,32,31,29,27,33,27,29,27,27,37,33,27,35,39,29,29,29,28,33,27,49,84,118,149,90,44,51,59,92,89,66,57,41,39,26,16,17,24,24,21,41,44,29,22,19,24,29,26,29,24,27,27,29,33,32,33,32,34,29,31,30,27,27,21,30,36,56,79,91,86,65,59,43,47,58,92,157,190,158,66,25,23,22,28,30,34,34,39,38,36,40,37,33,37,37,36,37,36,36,83,78,57,62,55,75,54,60,71,25,81,122,110,116,109,120,87,80,59,66,223,252,252,249,249,252,252,251,250,247,249,250,252,250,250,252,250,249,248,248,248,249,248,249,248,248,249,250,251,250,251,250,249,248,249,249,249,248,247,248,247,246,247,245,245,245,244,245,246,245,246,246,247,247,247,247,248,248,250,251,252,251,251,237,116,3,1,4,8,9,9,10,9,10,12,12,12,191,196,194,195,195,192,193,191,193,194,195,194,196,194,196,195,194,194,195,195,195,194,193,195,193,195,194,191,195,195,193,196,196,193,193,192,195,194,193,193,192,196,194,193,194,194,197,196,197,197,195,194,197,198,195,194,198,199,196,197,197,195,195,196,199,197,196,197,197,198,198,199,198,199,196,196,198,195,199,196,196,197,195,198,196,198,201,198,199,198,195,197,194,197,197,194,197,196,198,196,194,198,199,198,196,197,196,194,198,198,197,197,198,198,197,200,198,198,199,197,199,198,198,200,200,200,198,201,199,201,200,200,202,201,203,203,204,201,205,207,203,203,203,206,203,202,203,202,204,203,200,201,203,203,203,200,205,202,201,203,200,202,203,201,202,205,205,200,204,206,204,206,205,204,205,206,209,208,207,207,207,208,206,208,208,209,207,209,210,209,208,208,211,209,209,207,210,210,211,208,208,211,207,210,212,209,212,214,212,211,211,210,212,211,211,211,212,210,210,211,209,211,210,210,212,211,211,210,210,211,212,210,211,214,210,212,210,211,212,210,212,211,211,211,209,211,212,202,205,214,199,205,212,210,212,211,212,210,210,209,214,212,211,214,210,212,213,211,212,212,214,213,212,214,213,214,214,212,214,214,214,215,213,216,215,216,216,216,217,217,220,221,227,234,241,234,204,189,198,215,225,229,228,224,223,214,207,198,193,193,194,199,207,214,201,214,211,219,233,227,227,223,224,204,182,206,224,239,155,150,227,172,191,97,102,249,217,119,175,220,177,194,212,158,148,160,150,165,143,214,215,94,178,237,204,102,91,138,129,115,70,43,27,189,223,105,200,249,190,186,210,217,160,94,66,131,184,234,250,215,198,141,171,142,169,222,215,249,245,148,169,241,225,237,227,235,217,214,238,235,227,202,234,224,177,162,151,171,98,57,65,54,85,60,101,150,169,178,98,99,36,15,21,11,44,37,22,27,36,63,47,58,133,181,186,157,199,233,250,250,244,179,152,215,246,251,244,235,171,137,214,252,249,208,249,213,41,36,35,92,114,115,127,87,40,82,62,74,146,67,26,33,28,59,118,127,122,75,21,26,33,38,48,56,45,28,44,31,23,28,24,28,27,34,34,28,34,39,28,31,33,35,33,33,34,33,30,32,38,34,36,33,37,32,29,31,40,61,71,54,27,29,36,36,28,29,29,30,27,29,32,29,34,33,30,32,33,36,28,28,30,35,44,74,113,98,141,190,112,50,40,40,79,96,75,59,46,39,29,18,27,26,27,28,34,34,24,17,17,24,25,30,31,27,29,33,32,35,35,34,41,33,34,30,31,37,28,25,30,30,23,28,40,44,49,49,35,32,42,46,95,162,133,60,28,21,23,30,38,37,36,38,34,34,40,36,35,35,38,41,33,38,30,78,84,53,65,65,81,56,57,81,27,70,124,113,122,109,119,97,78,62,47,200,250,250,248,248,253,253,250,250,249,249,249,252,251,251,250,250,250,247,248,247,248,248,247,249,248,250,251,251,251,250,249,249,248,250,249,249,249,249,248,247,248,246,247,246,245,244,246,247,246,246,248,248,247,248,248,251,250,252,251,250,250,251,238,115,4,1,4,8,9,9,10,9,11,12,11,11,197,199,198,196,196,196,196,196,194,192,194,197,196,195,196,196,196,195,198,198,196,198,198,198,196,196,196,199,199,196,197,194,193,194,196,195,194,194,195,196,196,195,194,192,192,194,195,192,194,196,193,195,196,196,194,195,196,196,195,197,198,196,195,194,195,194,196,196,193,197,196,197,198,196,198,198,198,198,197,199,198,201,199,197,200,199,201,200,199,196,196,195,195,196,195,196,197,196,198,196,196,199,196,198,196,198,198,197,203,200,197,200,199,200,200,199,200,202,201,199,198,199,198,200,200,199,201,201,207,203,202,203,202,205,206,207,204,203,206,206,205,206,205,206,207,203,205,203,199,204,203,202,203,204,205,204,202,204,201,201,203,203,204,203,203,205,204,205,205,205,205,205,206,204,206,207,207,207,208,209,210,207,207,210,207,207,207,208,209,207,208,209,209,207,208,210,208,206,209,210,211,211,210,210,208,210,211,210,210,211,210,209,210,209,209,210,208,209,210,211,211,210,211,210,211,212,211,208,210,211,210,212,209,211,210,210,214,211,210,210,214,212,211,211,210,212,209,203,210,210,199,207,212,213,211,212,212,210,212,211,211,211,210,212,210,211,211,211,209,212,212,214,212,211,214,214,216,214,213,215,216,214,214,214,215,216,215,215,214,216,218,220,225,226,233,241,234,216,205,202,206,214,214,207,204,200,203,200,207,211,215,223,224,230,207,214,209,212,227,217,222,221,219,196,181,210,227,229,141,161,240,190,190,88,96,246,218,108,150,205,167,199,220,160,161,157,157,167,154,242,214,96,187,234,232,151,93,122,130,114,68,39,21,191,210,108,219,241,171,141,170,184,164,154,101,113,169,243,192,170,198,177,155,114,170,189,216,250,225,137,191,241,225,238,225,236,211,208,232,229,225,201,237,237,206,185,162,215,109,19,36,57,99,70,124,167,211,180,60,38,16,19,21,29,41,21,21,35,50,54,42,137,216,169,162,196,237,245,248,252,188,161,199,237,250,233,241,178,139,207,251,252,247,199,240,125,18,49,70,121,112,123,91,34,64,127,63,89,146,50,29,41,96,118,120,127,116,65,12,26,39,42,47,53,42,30,48,33,29,30,20,32,24,34,32,23,33,31,31,33,32,36,36,31,34,32,30,37,37,39,41,39,42,32,30,34,32,49,70,59,34,26,34,38,35,21,27,28,27,32,26,33,29,30,31,33,36,36,31,33,57,84,109,119,121,137,153,147,87,37,29,31,59,65,55,50,49,46,26,27,24,19,19,27,31,18,22,16,23,24,21,30,26,30,24,26,31,29,37,36,34,36,34,36,31,32,33,31,25,30,28,26,24,28,54,54,30,20,20,23,27,46,51,39,32,19,27,29,33,38,37,42,40,33,40,39,36,36,33,37,34,37,30,78,83,57,66,57,76,65,56,73,30,57,127,120,117,106,117,101,60,41,22,130,244,244,246,246,253,253,250,250,251,252,250,250,251,252,251,249,249,249,250,250,248,249,248,249,249,249,249,249,249,249,249,249,249,251,251,252,251,251,250,248,247,247,247,245,245,244,245,245,246,249,249,249,251,250,249,251,250,252,252,252,250,250,237,115,4,1,4,8,9,8,10,9,11,12,12,12,198,202,198,200,201,199,200,200,200,198,198,198,198,198,196,199,199,197,198,195,198,198,199,200,202,199,198,200,204,202,198,198,198,198,198,196,196,193,195,197,195,198,195,194,198,195,194,195,191,192,194,194,197,194,194,194,193,195,193,193,196,198,198,194,196,198,198,198,195,198,196,198,196,196,198,195,199,195,198,198,200,202,198,199,199,199,199,198,199,198,198,197,195,194,195,198,198,198,196,198,198,200,198,199,200,200,200,200,201,201,200,201,202,201,201,201,200,201,201,201,202,202,203,199,200,203,204,205,203,205,207,204,205,206,208,211,207,208,207,207,207,207,207,205,206,208,206,204,204,205,204,205,205,205,205,202,205,203,205,207,205,206,207,205,203,205,206,206,206,206,204,207,204,206,208,205,207,204,206,208,206,208,207,206,209,208,206,208,208,207,208,208,210,206,207,208,206,207,210,208,213,212,207,209,210,209,208,210,207,209,209,208,209,208,208,208,211,210,208,210,212,212,211,211,211,209,211,213,212,211,209,207,209,210,208,210,210,210,210,212,212,210,210,212,209,213,206,202,212,202,201,214,211,212,210,210,211,210,211,210,211,209,211,212,210,211,212,209,212,212,212,212,212,214,213,214,215,214,214,213,215,216,214,215,213,215,216,216,219,221,223,223,227,230,230,233,228,220,196,181,178,181,191,200,212,214,218,221,222,226,225,223,222,225,204,211,204,204,223,217,220,221,218,188,184,213,230,220,126,172,246,191,192,74,80,214,211,135,148,229,192,216,226,142,153,159,168,167,168,247,205,99,192,236,247,190,88,112,124,120,66,30,28,185,193,108,212,189,124,130,197,208,205,205,109,98,162,202,163,201,210,188,148,59,117,192,225,250,198,131,217,234,227,237,222,236,206,211,230,227,223,197,233,232,202,160,158,222,99,27,47,59,53,62,89,131,155,121,43,23,12,19,35,31,29,21,32,51,56,42,97,229,217,143,194,229,246,230,250,217,162,222,235,252,237,230,191,143,200,248,252,252,246,174,118,50,27,84,98,123,118,90,47,55,115,144,46,104,137,39,33,135,208,164,136,120,108,53,15,13,19,40,44,46,36,28,41,29,28,27,19,24,31,32,30,31,30,29,29,35,30,27,36,27,36,33,26,34,35,34,41,45,44,34,31,36,26,45,68,62,37,24,35,36,29,31,23,25,31,28,29,30,30,34,31,33,32,37,30,51,137,170,118,112,148,153,119,59,27,27,24,27,49,64,64,60,53,38,23,16,19,20,21,25,22,21,15,25,25,21,22,24,26,24,20,27,28,31,32,34,38,31,34,35,33,33,28,33,33,25,27,31,22,35,61,53,31,24,22,21,16,23,27,29,33,28,25,30,35,39,35,36,41,37,39,36,35,35,37,39,31,39,34,74,88,55,67,61,79,66,46,82,39,43,120,114,116,107,113,106,57,48,15,81,237,240,246,246,253,253,250,250,252,251,252,251,251,249,249,250,248,248,249,250,250,248,249,247,248,249,248,248,247,248,249,249,249,251,250,251,251,250,248,248,247,246,246,246,245,245,246,247,247,246,248,250,249,249,249,252,249,252,252,250,251,250,237,116,3,1,4,8,9,9,10,9,11,12,12,12,200,202,202,201,204,200,200,203,205,203,202,204,202,201,202,203,202,199,202,200,199,201,200,204,204,203,201,204,205,202,204,202,201,200,199,199,200,198,198,199,198,196,196,198,198,197,199,196,195,197,198,198,196,195,195,196,196,198,195,194,195,196,196,198,197,198,199,198,200,198,198,198,200,200,200,200,198,200,199,199,198,199,199,199,201,200,200,200,198,198,198,198,198,198,198,198,200,198,198,198,198,199,198,202,200,200,202,199,201,198,198,204,200,200,203,204,201,201,202,202,204,208,206,206,208,205,208,205,208,208,208,209,208,209,208,207,206,209,210,208,208,211,207,208,207,207,209,206,206,206,206,207,206,205,206,205,206,206,204,207,207,205,203,204,204,204,206,205,205,205,204,205,208,205,208,208,206,207,205,206,206,206,207,208,206,209,210,206,207,206,207,209,209,207,206,207,207,208,208,209,209,208,208,208,208,208,208,209,208,208,208,207,208,209,209,210,210,211,211,209,208,210,209,207,210,210,210,210,211,210,210,210,210,210,208,210,211,208,210,210,211,208,210,211,211,214,201,205,210,200,211,214,214,214,212,212,211,213,212,211,212,212,215,214,212,214,212,212,212,214,213,212,212,214,215,214,216,214,214,215,215,218,217,218,219,222,221,223,228,226,225,226,223,215,205,192,182,183,188,192,191,186,193,209,221,227,229,225,225,223,224,223,219,223,202,208,208,204,222,218,222,224,217,186,189,217,231,213,134,190,245,194,191,81,88,210,230,149,138,233,201,209,193,127,152,161,174,157,180,250,205,125,201,234,249,229,130,112,125,117,76,43,20,169,167,103,167,139,150,193,234,215,214,199,94,63,136,196,200,239,213,188,118,69,147,208,241,251,168,147,233,229,230,232,223,234,204,214,229,227,222,198,231,230,198,137,133,232,134,65,92,86,38,73,127,94,96,66,37,31,14,36,39,28,25,22,43,61,46,83,201,243,160,171,232,244,234,214,193,162,208,252,251,245,234,184,152,206,249,252,252,252,237,84,39,14,27,101,105,127,87,35,66,100,153,122,33,132,125,35,35,115,201,155,125,127,98,45,10,19,16,22,27,30,32,35,44,26,24,26,22,25,29,33,29,33,30,28,33,34,32,29,27,34,31,28,34,27,29,40,43,43,39,36,38,34,33,41,60,72,45,25,27,38,33,26,31,24,31,30,29,31,29,32,32,25,28,29,33,44,104,169,133,109,114,84,45,23,14,13,21,26,47,72,71,50,40,38,25,23,17,19,23,20,21,20,21,21,23,19,27,27,24,23,25,30,25,30,29,31,38,32,36,39,32,31,31,31,31,27,31,30,22,41,59,47,34,27,23,27,29,29,33,24,29,36,29,29,34,38,36,37,38,35,40,32,33,37,34,41,37,39,32,78,91,55,69,57,74,71,50,78,51,34,110,120,115,107,109,116,67,52,16,62,229,237,246,246,253,253,251,251,252,252,252,251,249,248,249,250,249,249,250,249,249,251,250,249,248,249,249,249,248,247,249,249,249,250,249,250,250,251,251,248,247,247,247,246,245,245,247,246,248,249,248,248,249,249,250,252,251,250,250,251,250,249,236,116,4,1,4,8,9,9,10,9,12,11,12,12,200,204,201,201,205,202,203,201,202,202,202,204,203,203,200,202,201,199,205,202,203,206,203,207,205,204,205,204,206,206,204,205,202,202,201,198,200,200,198,198,199,199,197,196,199,197,197,199,198,198,195,195,196,196,197,196,197,195,195,197,198,195,196,198,199,198,196,198,200,200,199,201,199,198,200,198,200,199,203,200,198,198,198,199,199,199,201,201,196,198,196,195,198,198,197,197,198,199,198,198,199,200,201,200,200,201,200,202,204,201,201,200,202,203,204,202,201,202,205,202,204,209,208,208,208,208,208,207,208,209,210,210,212,210,208,210,208,210,208,208,209,208,209,208,208,208,210,210,207,206,207,208,207,207,207,203,206,206,206,207,205,205,205,203,206,203,205,206,203,207,206,206,206,203,205,205,207,205,206,207,206,208,205,205,205,204,207,205,206,207,204,205,208,207,207,210,208,207,208,206,208,207,207,208,206,207,206,208,208,208,209,208,209,209,210,209,209,208,209,207,209,210,209,209,209,208,210,208,210,210,209,208,209,208,208,207,211,211,207,211,209,208,210,210,210,210,200,210,207,200,213,214,214,214,213,212,212,212,214,213,214,212,211,213,213,212,214,213,215,214,217,221,221,224,225,224,226,225,227,230,229,233,236,234,233,235,237,236,234,232,226,212,198,187,190,197,204,215,224,235,232,224,218,217,225,229,233,233,234,232,231,233,232,239,217,221,220,216,238,231,234,237,226,195,206,231,247,214,141,214,252,205,201,86,122,238,241,161,120,214,187,191,165,110,154,172,179,165,202,250,214,152,217,234,251,247,126,111,97,105,80,33,29,129,157,117,175,171,174,218,228,187,167,145,107,78,124,170,215,235,175,149,136,136,188,238,246,248,149,169,241,221,236,227,225,235,204,212,227,227,220,195,230,236,187,125,181,252,154,68,85,89,60,151,151,72,58,65,57,25,33,40,33,23,30,39,60,43,55,178,248,192,148,194,244,234,223,192,149,192,233,252,244,231,199,136,202,248,252,252,250,250,154,36,34,3,41,99,118,87,31,56,104,130,151,87,37,137,112,31,22,82,130,120,126,127,88,26,23,26,25,28,24,45,39,35,48,26,27,24,22,32,27,31,36,30,33,35,30,36,34,35,32,27,31,29,30,33,34,31,34,35,36,41,38,38,34,29,63,70,52,29,21,31,26,30,32,32,30,34,35,31,32,27,31,27,31,37,32,33,46,115,105,46,49,38,24,21,13,14,14,31,41,59,66,47,42,35,27,25,21,21,19,14,18,25,21,21,23,25,25,24,25,24,27,27,24,33,28,35,40,32,36,30,31,35,29,33,30,32,26,25,27,43,63,42,28,29,23,29,32,26,32,31,33,33,32,33,27,33,42,38,36,39,36,39,35,34,34,35,36,37,32,80,96,57,72,55,71,78,50,74,53,33,95,115,116,109,110,115,69,51,19,54,218,237,247,247,251,252,252,252,251,251,249,248,247,248,249,249,249,249,250,249,249,247,251,250,248,250,249,248,249,248,249,248,248,249,248,251,249,250,249,248,248,246,248,248,247,247,248,248,249,249,249,251,249,250,249,252,252,251,249,249,250,250,237,116,4,1,4,8,9,9,10,10,11,12,11,11,200,204,204,202,206,200,203,204,202,201,200,200,200,202,202,199,200,200,203,203,205,204,203,204,204,205,205,206,206,203,202,203,203,202,200,198,200,199,199,198,198,198,199,200,199,198,197,197,199,197,198,198,196,198,196,196,197,194,195,198,197,195,195,197,194,196,200,200,200,200,201,200,199,198,199,198,198,201,201,201,200,200,200,198,198,197,198,200,198,198,198,195,199,199,197,197,197,198,200,201,200,201,198,201,201,199,202,199,200,204,204,204,204,203,204,204,200,203,204,204,206,207,205,206,208,207,209,208,210,209,211,211,209,210,209,209,205,207,208,209,210,206,205,208,207,206,207,206,208,206,208,207,205,203,205,205,206,206,205,206,205,206,204,205,204,205,206,203,204,205,205,202,204,203,202,204,205,206,205,205,204,205,205,206,203,204,206,205,206,206,206,206,206,205,205,206,207,208,205,207,206,206,208,207,211,208,208,208,207,206,207,207,207,206,209,208,208,209,208,208,208,210,209,208,211,210,207,210,208,209,208,206,208,209,209,208,210,209,210,209,210,208,208,209,213,207,199,211,203,205,216,210,212,211,212,213,213,214,212,212,212,212,211,212,210,212,211,217,220,225,241,244,244,244,247,248,250,251,252,250,248,251,248,246,244,247,246,237,233,226,219,221,228,236,249,252,252,252,252,252,252,252,252,245,239,235,239,243,249,251,252,252,252,252,248,245,248,243,252,252,252,252,249,217,235,251,252,234,167,232,253,196,162,66,110,244,251,172,141,224,223,214,161,123,165,192,200,189,239,252,234,170,231,249,250,250,123,83,72,65,63,34,12,120,185,156,202,205,198,216,179,163,165,174,147,105,111,142,195,177,184,167,163,201,234,251,252,237,146,205,246,231,240,230,233,237,207,212,225,227,219,195,229,237,184,145,202,252,150,51,63,70,92,175,110,53,53,57,57,38,43,35,24,29,44,53,53,44,135,243,205,165,171,213,237,224,196,152,193,233,252,252,246,206,145,178,243,250,251,251,248,172,35,14,50,42,86,122,86,49,59,107,134,130,131,64,44,141,92,29,33,45,107,125,121,137,71,16,29,28,33,40,47,56,35,33,46,26,20,27,24,27,29,27,32,31,32,33,33,27,29,33,29,29,31,30,35,31,29,32,25,29,33,31,32,29,36,34,59,74,51,37,21,22,28,34,33,31,33,26,32,35,29,31,36,34,33,37,34,32,40,88,66,45,49,26,23,14,14,17,15,21,39,59,58,49,42,36,27,18,14,21,19,19,21,19,24,26,27,24,25,24,25,24,26,26,29,36,29,33,36,34,34,30,36,33,26,33,32,28,31,29,33,51,55,42,31,28,33,32,33,29,31,35,28,29,32,31,30,31,35,39,38,31,34,37,31,35,29,34,32,33,31,71,98,59,72,65,54,62,52,62,57,28,89,119,107,107,102,115,75,49,28,30,183,236,247,247,252,252,252,249,251,249,249,248,248,248,249,249,249,248,248,251,250,249,250,248,248,248,249,250,249,249,249,248,246,247,248,249,248,249,249,248,248,247,247,248,247,249,249,249,249,248,249,250,250,251,251,252,251,251,250,250,249,250,237,115,3,1,4,8,9,9,10,10,11,12,11,11,201,204,203,202,202,201,202,202,202,201,202,200,201,200,202,204,201,204,203,204,206,200,203,203,203,205,203,201,202,204,205,203,202,201,201,198,200,201,200,200,201,199,198,200,201,202,199,199,199,196,201,200,199,197,196,197,196,196,197,195,198,198,197,197,198,200,197,200,202,199,201,201,198,199,199,198,199,200,201,200,200,200,202,200,200,199,198,201,198,201,198,198,199,198,200,199,199,200,198,201,203,201,201,200,202,200,200,202,200,201,202,203,201,202,204,203,204,204,206,205,208,206,203,208,208,209,209,207,207,208,210,211,212,208,208,208,207,208,207,208,208,205,206,208,207,207,207,206,206,206,208,206,207,206,205,205,204,206,206,206,207,203,204,203,204,202,205,207,203,205,207,205,205,205,203,203,205,205,205,207,204,204,204,204,206,203,206,203,203,207,204,207,206,205,208,207,205,206,205,205,210,208,207,207,207,210,207,207,208,207,209,208,209,210,209,208,207,210,210,208,210,209,208,210,210,210,210,209,210,208,210,209,209,208,209,210,209,211,210,212,211,208,211,211,214,204,205,210,201,211,214,213,212,209,212,213,213,214,214,212,213,212,212,212,211,209,211,212,212,206,203,205,202,201,204,204,207,207,216,211,182,173,170,171,176,165,151,137,138,147,164,188,199,206,207,206,208,210,203,201,201,199,191,183,187,186,183,189,197,202,196,198,197,200,187,185,189,181,199,199,201,201,183,164,186,205,214,173,124,186,197,133,112,19,57,176,171,128,124,190,200,189,145,117,153,179,180,182,235,250,207,160,220,247,252,241,103,95,82,70,57,15,34,149,212,151,213,194,184,200,179,213,224,229,183,165,103,108,178,190,232,173,190,208,244,252,250,240,164,246,252,252,252,247,250,248,212,212,227,226,220,194,236,231,162,158,212,230,113,39,53,72,139,189,84,42,59,87,60,37,49,17,20,34,52,53,43,111,229,220,172,185,187,216,229,195,141,182,235,253,250,250,241,149,171,233,250,250,249,249,171,39,8,12,74,81,121,95,30,74,105,137,126,93,101,41,57,136,77,24,73,173,160,132,131,118,68,16,32,36,34,53,69,62,33,39,42,27,29,26,21,29,29,32,29,29,33,27,32,30,31,34,30,55,73,67,63,58,44,34,30,27,32,29,30,30,35,35,54,76,59,36,23,26,29,33,33,33,31,27,33,31,28,30,36,30,30,36,33,32,33,53,47,47,55,34,17,14,15,15,14,23,37,55,56,46,44,39,31,20,19,20,18,22,16,24,27,21,25,24,24,29,28,24,26,25,29,32,30,33,37,37,33,33,33,32,29,34,32,33,31,31,40,57,59,35,29,37,27,32,34,31,31,31,38,29,30,30,26,32,37,32,35,38,29,37,34,32,34,35,33,32,31,71,95,59,72,69,41,37,38,48,44,29,71,113,113,102,99,118,94,55,27,28,157,233,249,249,252,252,252,250,249,248,249,249,247,249,249,249,249,248,249,249,248,249,249,248,249,249,248,247,248,247,247,245,246,246,245,248,247,249,249,248,248,246,247,246,248,248,248,248,248,248,249,250,249,250,249,252,250,250,250,249,250,250,236,117,4,1,4,8,9,9,10,9,11,11,12,12,201,204,201,200,205,199,202,202,201,203,201,200,202,203,202,200,203,203,203,204,203,203,204,202,203,203,203,202,201,200,199,204,203,202,203,200,200,201,200,201,199,199,200,198,198,199,201,200,200,200,201,200,199,201,200,200,198,198,198,198,200,201,200,201,202,200,200,200,201,200,201,201,201,200,200,198,200,201,200,198,201,200,198,201,201,203,200,199,197,200,203,202,200,199,200,199,202,200,200,202,201,203,202,204,203,202,205,203,202,204,202,204,205,203,205,205,203,207,205,205,206,207,207,208,209,210,208,207,208,209,211,209,209,208,207,208,207,209,207,210,210,207,208,208,207,208,208,207,207,207,209,207,206,205,207,207,207,205,205,205,205,205,203,203,203,202,204,206,203,204,206,204,205,202,203,206,205,204,203,203,204,204,206,206,205,204,203,205,205,205,204,206,206,207,210,208,206,207,207,208,209,208,207,204,210,210,208,207,208,212,210,208,210,209,210,209,210,210,210,210,208,208,208,210,213,212,210,210,208,207,207,210,211,209,213,213,213,212,211,214,212,212,213,213,215,205,210,208,203,213,214,214,212,209,212,211,212,213,212,214,210,212,211,211,211,213,211,212,188,130,108,99,98,96,92,90,78,74,102,88,56,60,57,54,44,34,26,19,19,21,38,56,63,57,62,63,54,53,49,51,50,48,43,45,59,79,89,89,93,84,69,55,50,51,51,52,57,54,51,50,50,53,54,50,48,53,57,53,24,29,46,89,132,48,5,19,13,14,35,71,78,70,72,77,83,86,89,92,103,106,98,73,103,108,119,128,64,119,122,84,79,36,37,129,127,77,128,94,100,139,137,159,165,145,125,114,53,98,138,158,175,101,99,111,185,227,243,157,127,226,218,227,226,220,224,232,210,210,229,231,220,193,243,223,163,177,198,200,114,57,49,83,203,208,68,36,75,107,69,40,35,15,29,49,56,36,89,215,239,196,207,219,198,210,200,140,172,225,252,252,249,249,173,165,227,246,250,250,249,177,35,33,51,82,99,88,92,44,64,118,136,129,77,73,89,33,77,133,71,21,100,201,182,136,126,122,41,18,40,33,40,51,57,43,27,39,48,24,30,28,20,29,33,31,33,30,32,27,31,35,46,57,73,153,164,150,158,153,95,40,42,36,23,28,33,27,39,35,57,77,61,41,23,27,27,36,34,27,31,30,35,33,27,32,34,35,30,32,32,31,28,26,36,45,34,21,15,13,15,15,14,28,33,40,52,49,46,42,39,23,18,16,19,26,21,25,20,22,26,27,23,22,27,21,24,28,29,32,28,36,35,31,32,36,34,27,35,32,29,36,31,29,42,62,52,33,25,22,27,33,29,27,34,33,29,29,27,31,29,29,33,35,33,36,35,32,33,40,32,36,33,36,32,65,106,57,68,84,51,43,39,38,45,26,59,113,106,107,103,116,103,55,32,27,120,232,251,251,250,249,250,249,249,246,247,247,248,248,249,249,248,249,249,247,247,247,248,249,249,248,247,248,249,247,246,246,245,246,245,246,248,248,247,247,247,246,245,247,245,245,247,249,248,248,249,247,249,249,250,252,249,249,248,251,250,249,237,115,4,1,4,8,9,9,10,9,11,11,12,12,200,205,204,203,204,203,202,200,201,202,201,201,202,201,203,201,200,201,200,200,204,203,204,200,201,204,202,202,200,201,203,201,201,202,202,200,200,201,200,201,200,200,199,200,199,199,198,198,202,198,200,198,200,200,200,201,199,201,199,200,202,200,200,198,200,201,198,203,201,199,201,200,200,199,200,201,199,200,201,199,196,199,202,199,201,199,201,201,198,201,199,200,203,200,202,198,199,202,201,202,203,203,203,201,202,203,204,204,203,204,202,201,205,204,206,205,203,205,205,206,211,207,205,208,205,207,205,208,207,207,208,205,207,207,209,210,207,207,206,206,208,208,205,207,208,206,207,206,206,204,205,206,206,205,205,203,206,204,203,204,203,205,205,203,204,205,204,205,203,202,203,201,202,205,203,203,204,204,201,202,203,205,205,203,205,204,205,206,206,208,205,206,206,207,210,207,208,207,205,208,208,208,208,208,208,208,208,210,211,208,210,208,210,209,210,212,209,209,210,210,211,208,210,212,210,211,211,211,211,210,211,211,213,213,212,213,214,214,212,214,213,212,212,222,220,214,224,213,211,215,212,214,213,214,210,209,212,211,212,212,212,212,210,210,212,213,211,216,199,163,153,153,148,145,145,134,104,89,103,117,115,129,136,128,125,118,118,113,110,106,105,108,102,106,100,87,97,103,103,107,105,105,105,107,110,128,131,128,125,122,113,101,103,110,109,104,111,103,108,108,104,105,96,97,104,109,106,77,53,78,97,132,171,77,61,95,67,56,44,63,89,87,84,107,114,106,99,92,86,85,94,65,66,66,68,89,59,119,123,89,78,50,72,100,83,42,66,58,50,64,59,66,52,46,38,44,39,77,105,83,68,38,47,25,59,98,95,46,44,108,98,109,116,111,137,199,205,213,230,230,224,195,245,203,160,195,178,195,162,114,66,120,253,189,43,28,40,78,62,33,21,17,45,51,44,60,189,249,217,226,248,242,188,193,129,122,204,239,251,251,239,171,165,219,249,249,248,248,198,53,26,72,116,123,119,59,36,72,117,139,122,75,66,97,76,34,90,131,63,27,50,126,144,131,134,98,37,18,25,24,27,29,31,22,23,49,46,31,28,23,29,27,30,31,31,33,34,33,69,68,130,146,155,170,140,169,179,160,132,89,64,38,29,25,27,29,35,33,51,78,66,46,20,22,29,30,30,33,33,30,35,29,30,33,34,30,29,31,34,33,27,25,18,21,19,15,21,20,16,17,16,24,30,41,63,65,61,51,33,20,17,22,21,23,23,23,23,24,24,25,29,24,21,24,27,28,29,27,26,37,37,39,32,32,39,27,33,37,27,34,33,27,53,64,47,32,27,27,22,31,34,34,39,46,42,33,35,34,34,34,35,30,31,35,36,35,30,33,36,33,29,40,27,62,103,60,75,83,56,64,67,50,53,29,56,119,115,113,106,121,99,57,36,35,83,209,253,253,249,247,250,248,246,248,248,246,246,247,248,249,249,249,249,248,246,247,248,249,249,248,248,248,249,248,246,245,244,245,247,247,244,247,247,248,248,247,245,244,247,247,249,249,248,249,251,249,249,248,251,252,250,251,250,251,250,250,237,116,3,1,4,8,9,9,10,10,12,12,12,10,199,205,202,201,206,197,202,202,199,203,201,202,202,201,202,201,199,200,201,200,200,202,201,200,200,202,200,199,201,200,200,203,200,199,201,199,202,201,200,201,199,201,200,200,200,199,199,197,199,198,199,198,198,199,197,198,200,200,198,199,200,201,198,199,200,198,198,202,198,196,201,199,198,199,199,201,200,202,202,197,200,200,200,201,199,200,198,201,200,199,200,201,199,199,198,198,201,201,202,201,200,200,202,202,201,201,201,201,201,204,201,203,205,202,204,203,202,203,205,204,204,206,203,204,206,206,205,206,206,207,206,204,208,205,207,208,207,206,203,208,206,205,207,207,205,204,204,205,203,202,205,203,206,206,205,203,203,205,205,202,202,202,201,203,204,205,204,202,201,204,204,203,203,200,203,203,201,203,204,203,202,202,204,205,204,204,206,206,205,205,204,206,206,207,209,208,207,207,208,210,208,207,209,209,211,208,210,211,208,212,212,210,211,210,210,210,211,211,209,212,211,208,210,210,210,210,208,212,212,212,213,213,212,213,216,215,215,214,213,215,213,212,217,231,216,222,230,210,214,214,213,212,211,208,212,211,214,213,210,212,210,212,212,211,212,214,217,222,223,229,236,236,233,225,225,219,190,183,211,218,235,247,248,249,247,251,252,252,251,251,248,245,244,244,236,219,236,244,243,246,242,246,246,249,247,244,239,227,223,222,225,225,231,244,240,231,240,227,244,249,248,242,208,222,239,251,233,187,208,241,237,204,177,89,150,249,234,205,173,165,226,191,168,191,200,205,173,232,250,250,238,185,220,240,240,233,107,110,113,74,76,46,76,173,191,152,142,174,171,134,103,122,160,125,174,178,118,100,90,151,117,123,156,130,153,139,139,68,101,166,152,163,151,151,161,208,206,210,228,229,217,197,240,177,168,198,159,216,171,92,101,198,252,112,2,94,105,49,39,26,15,24,49,43,39,145,240,220,230,249,252,228,177,131,69,145,233,244,248,247,168,158,223,242,248,248,246,196,54,27,62,108,110,111,87,33,48,99,139,121,71,48,97,96,61,38,109,136,53,26,42,108,138,132,139,97,26,9,15,16,30,27,31,40,34,44,51,25,28,23,20,31,26,33,32,27,37,39,116,183,190,180,124,99,100,149,104,62,74,75,59,28,32,24,27,32,36,27,46,83,67,41,24,21,28,29,30,30,30,34,33,30,30,29,30,34,32,33,29,26,30,26,19,19,18,19,21,16,17,18,26,36,29,35,64,73,69,44,27,29,13,17,24,23,24,17,23,29,24,24,21,22,24,26,29,24,30,32,27,35,33,34,36,34,40,38,34,34,33,32,30,33,63,65,39,26,22,24,33,38,52,65,64,60,59,62,71,75,61,40,28,33,33,34,38,29,31,34,30,34,31,38,27,57,104,59,64,83,63,103,109,65,61,33,55,125,105,116,104,112,107,57,30,48,64,159,249,249,249,249,249,249,245,247,247,247,246,248,247,249,249,249,250,250,247,247,248,248,249,248,246,245,245,246,246,247,245,245,247,246,246,246,247,247,245,245,247,247,246,246,249,249,248,250,249,249,248,249,251,252,250,251,251,251,250,251,237,115,3,1,4,8,9,9,10,9,11,12,12,12,198,200,200,202,203,200,199,199,199,201,202,201,202,202,200,202,200,201,203,200,201,201,201,199,200,201,198,200,200,198,198,199,201,199,198,199,200,198,200,201,199,200,198,200,198,198,198,197,199,197,199,198,200,199,199,199,198,200,196,200,198,197,202,199,200,199,195,198,199,199,198,199,201,200,200,198,198,198,200,200,199,200,199,198,200,200,200,200,200,199,199,200,199,198,200,200,200,200,199,201,199,201,201,199,200,200,202,203,201,201,202,201,202,200,203,203,202,205,204,202,203,201,203,207,204,204,204,206,203,206,208,205,206,205,205,206,208,207,208,204,206,206,205,206,204,204,203,206,205,204,202,202,205,203,202,202,205,205,205,204,202,202,199,201,202,202,202,203,201,200,204,205,201,202,201,201,203,203,202,200,201,204,202,203,203,205,205,204,206,204,206,207,206,208,208,208,210,209,209,207,210,208,207,208,207,210,210,210,212,211,211,210,212,210,212,214,212,212,210,211,212,210,212,212,210,212,211,211,213,213,213,214,214,213,215,216,216,215,213,214,213,212,214,224,171,146,185,201,214,215,213,212,210,212,212,210,212,214,211,211,214,214,215,216,217,217,216,214,212,209,210,212,208,211,217,225,202,197,235,241,242,246,242,240,243,245,248,247,249,251,251,252,250,252,248,236,249,251,251,251,251,252,250,249,249,248,245,241,231,230,227,231,233,244,245,231,246,232,244,251,252,245,212,229,245,252,236,211,248,249,248,214,167,77,150,246,249,249,202,190,242,192,142,140,122,103,139,230,252,252,253,227,249,252,251,251,155,124,129,85,81,53,57,184,248,218,233,252,210,203,209,247,252,212,252,252,221,129,128,204,164,201,221,211,252,252,209,139,195,249,251,251,245,245,236,242,210,212,225,226,214,194,220,167,197,192,164,227,111,30,71,198,226,34,47,205,131,41,29,17,27,33,39,24,116,219,208,218,246,253,250,206,114,91,130,202,248,229,235,180,152,218,247,249,245,246,200,56,28,57,107,110,113,84,33,35,87,129,124,79,47,97,105,64,50,61,135,128,45,30,100,159,142,130,142,82,23,16,15,31,31,42,48,49,45,50,42,25,25,21,28,27,35,28,29,29,39,74,88,157,171,127,97,108,122,128,81,66,83,77,57,45,33,20,24,32,34,25,56,81,66,47,23,21,26,31,34,32,33,33,31,29,27,31,31,29,31,31,43,50,38,30,27,26,29,22,18,23,20,23,38,39,33,38,48,56,56,41,30,17,15,21,21,27,27,22,24,26,27,27,24,27,29,29,28,29,32,31,25,36,32,36,39,34,33,34,37,34,28,35,29,39,66,61,37,23,19,27,35,33,49,61,79,77,92,131,128,102,74,58,44,35,36,29,33,34,31,32,32,35,29,38,28,57,106,65,57,74,68,118,128,70,66,36,57,128,108,108,97,115,101,64,29,57,62,100,243,244,249,249,245,250,244,246,247,248,247,247,248,248,249,249,250,247,247,248,246,245,246,248,245,245,246,246,246,246,245,245,244,245,246,248,247,247,247,245,245,246,246,247,246,248,248,249,249,248,248,248,250,250,249,251,250,252,250,250,237,116,4,1,4,8,9,9,10,9,11,12,11,11,197,202,200,200,200,196,201,200,198,203,198,199,201,200,199,201,200,200,200,199,202,202,200,198,198,199,200,199,199,199,198,199,196,200,198,196,203,197,199,201,199,200,197,199,197,196,198,197,199,200,197,200,201,203,203,200,201,200,200,200,198,200,199,199,200,199,200,199,198,199,200,200,199,198,199,200,197,198,198,196,199,199,199,199,200,200,198,201,200,198,200,201,200,199,199,201,203,200,200,201,202,200,200,204,200,201,200,200,202,200,201,201,200,200,201,204,201,203,204,203,205,203,203,203,204,207,202,204,205,206,207,203,204,203,206,205,203,205,205,207,205,206,206,204,201,203,205,203,204,204,207,205,203,203,202,204,203,204,202,202,203,201,203,203,205,204,203,201,203,203,201,203,202,199,202,202,203,202,202,203,203,203,204,202,204,205,204,206,207,207,206,206,205,207,209,207,206,207,207,207,207,207,209,207,210,208,210,211,209,211,211,210,212,214,213,214,215,213,212,213,215,211,212,212,213,215,213,213,213,215,215,215,216,216,217,214,217,213,215,214,211,214,214,207,92,52,150,201,218,217,213,214,214,214,216,210,213,214,214,216,217,219,216,214,208,203,199,194,189,192,194,197,203,208,217,225,205,199,224,219,223,223,216,219,217,218,218,219,221,221,223,224,225,225,222,212,226,230,221,226,225,224,222,223,220,222,222,222,222,213,210,208,208,213,207,202,218,207,221,228,229,214,180,212,222,236,199,186,232,234,234,193,153,66,142,244,241,232,138,102,117,66,42,41,28,27,20,50,87,110,106,74,133,162,179,157,59,105,108,94,111,59,55,148,194,159,185,219,174,188,199,249,225,176,208,168,212,135,104,159,95,150,208,212,252,252,189,158,224,241,251,247,241,244,237,243,206,210,224,225,218,197,204,181,220,169,134,184,87,53,63,176,159,1,144,240,85,39,22,23,39,45,30,52,194,202,203,244,252,252,230,143,66,150,192,242,244,223,177,150,214,249,249,247,246,209,63,32,59,101,116,113,89,31,35,96,130,132,96,63,102,113,69,51,44,61,141,111,41,32,53,148,151,134,141,60,26,28,28,37,40,58,57,60,50,48,36,18,28,22,24,28,36,32,27,33,41,48,50,81,114,112,105,102,117,137,104,81,66,47,42,44,37,19,20,29,34,26,57,84,68,51,25,19,23,27,36,28,31,33,30,33,39,37,33,35,33,39,89,82,39,33,28,37,35,33,30,22,25,26,33,43,39,42,41,44,42,33,21,16,19,19,24,23,25,25,23,26,24,33,50,43,35,28,31,27,27,32,27,35,37,36,34,36,37,35,33,36,33,35,30,46,83,60,36,22,16,29,33,35,37,63,90,87,117,123,102,98,97,91,61,42,37,34,33,33,34,34,34,31,31,40,26,59,111,71,54,51,45,70,76,50,51,33,44,122,109,110,93,107,117,72,30,51,65,51,201,240,249,249,247,252,247,246,247,245,245,245,248,248,249,250,249,249,249,248,248,247,246,246,246,245,244,244,244,244,244,245,244,244,244,244,245,246,245,244,248,248,247,247,246,246,247,246,248,249,248,249,250,252,248,248,250,251,250,250,237,116,3,1,4,8,9,9,10,9,11,12,10,12,198,202,200,198,202,199,200,199,199,200,200,199,198,199,200,200,197,199,200,199,200,198,199,198,198,199,198,199,198,198,198,197,198,199,199,196,199,197,199,198,198,198,196,195,198,200,197,198,199,198,200,200,200,200,199,201,200,200,199,200,201,199,198,199,199,201,200,199,200,199,198,199,199,196,199,199,200,200,199,201,199,198,198,196,199,200,199,199,200,198,199,199,199,199,200,200,200,202,199,201,199,200,200,199,202,201,199,199,200,200,200,199,200,200,199,200,202,204,202,202,205,204,203,205,205,206,206,205,204,205,205,201,203,203,203,205,205,203,202,206,205,204,204,204,201,204,204,205,201,204,206,203,204,203,204,204,202,202,201,202,202,204,203,203,201,200,202,201,203,203,204,203,201,203,203,202,202,205,204,202,203,205,203,203,204,204,205,204,207,205,206,208,205,208,205,207,208,204,207,206,208,207,209,209,209,210,208,209,212,209,212,212,212,212,210,214,213,214,213,212,214,214,214,214,213,214,216,214,217,216,214,214,213,213,214,214,213,213,212,211,212,211,218,206,115,118,191,211,220,212,216,215,217,224,221,218,216,217,214,214,210,203,198,194,192,188,194,195,199,208,210,216,217,220,221,228,213,202,222,214,216,219,213,215,214,215,216,216,218,219,218,220,216,226,225,210,232,231,219,217,216,219,218,217,219,218,218,220,219,222,214,208,203,206,205,188,207,197,212,228,225,203,175,209,220,232,171,176,224,222,233,185,151,67,145,241,236,216,83,31,44,49,79,105,110,84,88,79,68,74,58,27,27,45,66,64,12,32,42,41,81,63,43,94,93,48,71,110,83,98,107,122,105,66,70,49,107,92,53,54,29,144,217,203,250,248,154,175,229,228,235,227,228,229,226,234,203,213,226,229,226,191,193,207,236,151,122,162,115,89,96,192,90,17,212,203,38,26,24,34,54,41,30,116,188,186,232,253,251,241,197,114,121,208,222,229,240,187,145,206,252,252,248,248,217,71,34,60,101,112,113,91,35,36,107,147,134,96,55,90,117,78,52,40,36,72,146,105,45,22,31,130,139,134,123,47,31,29,33,40,39,45,45,47,42,28,21,24,23,25,29,29,34,31,28,29,29,61,87,77,77,69,59,42,66,87,63,45,22,29,33,23,31,29,25,27,36,29,63,91,73,50,24,21,21,30,32,33,33,28,29,57,85,58,33,50,60,112,135,98,62,52,43,39,56,76,49,26,23,23,37,43,52,43,39,43,32,25,29,19,20,24,24,29,25,28,24,26,23,69,98,50,42,34,25,33,34,31,32,36,37,38,34,36,36,33,33,32,33,31,29,66,88,57,30,21,18,30,42,46,60,77,73,61,77,87,88,103,112,106,81,66,52,36,36,33,33,35,32,36,31,38,26,65,122,79,45,36,28,32,39,32,33,24,38,107,111,107,94,100,106,72,39,46,69,28,136,237,252,252,250,248,249,249,247,246,247,247,249,248,248,248,249,249,249,248,245,244,245,245,245,246,244,244,244,244,244,244,246,245,246,245,244,244,244,245,247,247,246,246,248,247,245,247,248,249,248,249,250,250,250,250,250,251,250,250,237,116,4,1,4,8,9,9,10,9,12,12,13,13,200,203,200,201,200,196,199,200,200,200,198,199,198,196,199,200,198,199,199,198,198,198,198,197,196,197,198,197,198,199,199,198,198,199,199,198,200,194,197,199,195,199,194,197,198,196,198,196,198,198,196,200,196,198,197,196,200,198,197,199,201,199,198,198,200,198,199,198,199,199,196,200,200,200,198,197,199,199,200,199,200,198,199,199,198,198,198,199,199,198,198,198,198,197,199,199,199,198,199,200,200,200,198,201,199,199,203,198,198,199,199,199,198,200,199,199,200,201,202,200,201,201,200,203,203,202,202,203,203,202,201,202,203,202,204,203,201,203,203,204,201,201,205,203,201,202,203,202,203,201,203,200,202,205,202,203,200,202,204,203,203,200,203,200,202,202,202,201,202,204,200,202,205,200,203,203,203,203,202,204,203,206,205,203,206,205,203,203,204,207,206,207,208,206,207,205,208,206,206,207,206,208,206,205,207,206,208,210,209,208,210,210,212,212,212,213,214,212,212,214,213,214,213,212,212,214,213,214,214,215,215,212,214,214,214,213,213,211,214,213,210,213,221,223,189,215,237,222,220,222,228,231,242,241,227,215,211,207,199,195,192,191,189,193,198,206,211,214,215,216,217,218,216,217,217,224,206,198,220,210,213,216,213,218,215,217,217,217,217,219,218,219,215,227,231,204,231,236,219,223,219,219,217,216,216,220,220,221,221,220,225,220,211,212,204,194,201,194,210,225,229,198,182,218,226,232,172,193,229,232,240,191,158,65,152,245,244,222,136,130,149,167,190,212,211,220,244,248,243,235,210,153,190,211,221,200,59,31,11,17,77,66,41,100,153,125,141,152,129,118,113,110,99,110,130,138,158,108,58,47,67,183,234,213,252,244,153,211,239,232,251,240,248,245,244,249,222,232,240,244,241,184,196,244,237,170,149,164,160,108,128,195,68,76,246,123,6,37,22,49,50,39,96,128,184,226,253,253,250,203,161,168,184,230,199,214,192,155,199,238,252,252,247,213,72,29,57,105,114,108,99,37,47,117,143,144,86,66,59,63,83,55,48,52,52,89,153,94,44,19,63,157,115,122,101,33,35,36,24,22,23,19,19,25,27,16,24,24,22,24,27,36,31,34,34,50,64,72,82,61,49,40,47,36,25,53,53,27,48,59,27,26,46,46,31,22,29,24,63,94,75,55,26,23,22,27,35,29,33,31,33,85,114,80,74,139,165,174,150,131,159,132,79,80,155,141,60,31,23,21,25,44,61,48,42,41,29,29,33,19,23,22,24,53,49,32,26,36,64,108,108,76,64,52,35,38,71,60,34,37,36,40,35,31,33,35,33,28,32,30,34,79,96,52,30,19,22,61,65,43,51,57,57,47,38,41,62,71,72,78,71,61,43,33,29,33,33,37,35,30,31,41,28,61,121,81,52,51,49,36,32,38,31,39,44,104,114,107,98,98,105,73,43,35,77,29,41,188,247,247,246,246,249,251,249,247,248,246,246,246,247,248,248,247,247,246,247,247,246,245,247,247,244,244,244,244,245,244,244,245,244,244,246,244,245,245,245,247,245,246,245,246,246,245,246,246,246,249,249,250,249,249,251,251,250,250,237,115,4,1,4,9,9,9,10,9,11,11,11,11,198,201,198,198,198,198,198,196,199,199,199,197,198,197,198,198,199,197,196,199,196,196,198,198,199,196,196,199,195,197,195,195,197,194,198,197,198,197,196,197,198,196,196,196,195,195,193,198,197,198,198,196,198,196,196,198,196,198,197,197,199,199,200,199,196,196,197,195,198,198,196,199,198,198,198,196,201,197,196,198,196,200,198,198,199,198,197,200,200,199,199,201,200,197,200,199,198,197,196,198,199,199,198,199,198,199,200,199,199,198,201,202,200,200,198,200,200,202,202,201,204,201,200,201,201,202,201,200,201,203,203,199,204,201,201,203,203,204,201,205,203,201,202,201,203,203,201,203,201,201,200,200,202,202,203,201,199,200,202,203,201,199,200,201,201,203,203,202,203,201,201,205,203,201,201,203,201,203,204,202,203,205,203,203,205,204,206,205,205,203,202,204,204,207,205,206,204,203,207,205,207,206,207,205,207,208,206,208,209,209,210,212,210,210,211,212,212,212,212,213,216,212,211,212,214,213,214,212,212,213,212,213,212,215,215,212,214,213,213,213,212,213,222,211,207,236,237,229,225,230,236,217,217,222,211,204,200,201,199,201,205,212,217,221,226,225,230,226,225,227,226,225,223,224,223,225,209,199,223,224,223,227,224,227,229,230,231,232,230,230,230,234,234,241,228,159,189,238,238,240,234,235,235,235,239,238,238,239,240,243,241,244,244,240,236,213,225,214,216,237,235,208,203,239,246,247,191,219,249,249,250,186,134,63,150,245,252,238,208,207,217,223,226,216,215,252,252,252,252,252,252,246,252,252,250,250,126,38,28,39,88,57,39,162,249,251,252,252,229,173,234,247,251,231,242,251,215,230,180,120,146,210,241,225,252,246,167,242,252,252,252,252,253,253,252,252,251,251,252,252,252,185,210,251,191,129,124,199,207,116,158,155,61,170,220,50,8,33,33,52,49,132,134,127,217,253,252,244,218,141,180,212,206,208,179,159,141,199,224,252,248,248,222,67,24,49,94,112,114,97,43,52,108,141,140,94,55,56,29,41,64,55,57,61,51,98,150,78,38,14,96,158,102,117,85,33,35,31,13,17,19,19,23,20,25,28,23,22,23,21,28,34,31,33,36,80,104,69,40,43,46,44,57,48,55,84,75,53,65,63,40,41,60,54,39,23,28,27,62,114,95,67,30,16,24,24,35,30,34,31,38,66,81,86,88,113,122,93,57,58,121,134,115,120,141,112,57,31,17,24,43,98,113,60,34,33,31,30,26,22,25,22,29,57,61,46,59,73,95,113,129,158,146,91,73,133,137,73,31,27,38,35,35,30,36,36,31,36,32,31,44,97,92,47,27,16,46,86,69,41,39,65,74,53,37,55,68,61,50,46,47,36,27,24,27,33,33,34,33,34,33,35,29,56,114,89,58,62,61,48,58,53,47,50,51,123,121,104,98,93,111,82,41,32,76,49,30,89,224,236,245,245,250,251,250,251,248,246,247,245,246,248,248,248,246,245,246,248,246,245,245,245,244,244,244,244,243,244,244,244,241,243,244,244,246,244,244,244,245,244,246,246,244,246,246,248,247,249,248,248,250,248,249,249,248,249,236,116,4,1,4,8,9,9,10,10,12,13,12,12,195,201,199,199,200,196,198,198,198,198,197,198,198,196,198,197,197,198,194,196,199,196,197,199,195,195,196,196,195,193,195,195,196,200,197,194,197,193,195,196,196,198,193,197,197,194,198,197,195,197,198,201,196,200,199,197,198,198,200,198,199,196,198,199,199,199,199,196,197,199,198,199,198,199,198,199,200,198,198,196,198,198,199,202,202,201,200,200,199,198,199,199,198,200,199,200,200,198,201,200,201,201,198,202,199,199,200,198,199,201,201,199,198,200,199,199,200,199,201,198,199,202,199,200,203,201,203,200,200,203,202,202,201,201,203,203,203,203,200,202,200,201,202,201,203,201,203,201,201,203,203,202,200,200,201,204,201,202,204,200,199,200,201,200,202,199,200,200,199,203,200,200,203,199,203,203,200,202,202,205,201,202,203,202,203,202,203,204,203,205,205,205,203,200,206,205,205,205,205,204,205,207,206,207,207,207,210,209,209,213,211,211,215,213,214,212,213,212,214,215,215,218,216,217,217,220,217,219,221,219,222,222,225,224,224,225,224,225,229,230,230,230,230,214,216,244,245,244,240,240,203,110,97,165,216,227,227,235,241,245,248,250,251,249,251,252,251,251,248,248,247,248,247,248,249,247,235,233,248,249,250,251,251,251,252,252,251,251,252,252,251,251,252,252,217,106,150,233,250,250,252,252,251,251,252,252,251,251,252,252,252,252,252,252,252,236,235,233,229,225,229,200,208,236,242,234,179,224,234,232,219,140,113,59,143,240,240,217,187,182,165,150,139,147,175,234,246,246,247,246,222,167,217,240,252,228,89,69,69,82,64,18,37,133,199,199,194,202,170,129,190,215,236,190,212,199,171,245,186,139,145,183,194,185,246,188,149,227,227,233,232,217,218,216,214,212,205,226,239,240,234,135,184,215,99,74,103,195,191,123,173,92,54,209,150,2,28,35,26,43,122,204,133,153,246,252,241,215,152,142,236,227,181,186,136,122,189,229,243,252,244,236,91,22,48,90,113,111,103,46,51,102,129,139,84,63,56,33,14,19,55,53,54,55,49,76,120,78,33,26,128,153,96,118,69,21,23,14,18,21,16,17,21,24,23,29,23,26,27,22,27,25,30,31,32,58,106,97,65,53,40,67,83,78,108,134,118,105,112,94,67,53,50,46,33,19,26,26,67,113,107,74,36,22,17,22,33,34,31,36,83,95,45,33,24,27,24,27,29,19,27,29,33,31,26,43,77,53,31,33,112,201,145,64,35,31,29,27,27,24,21,19,27,34,47,45,47,48,51,41,33,83,113,102,104,116,94,60,34,29,33,31,35,34,34,31,34,37,41,31,60,108,75,44,29,22,69,76,71,56,54,107,101,74,74,97,99,64,39,35,31,24,33,29,23,29,27,34,31,36,37,37,26,52,115,90,75,70,67,63,76,71,57,62,50,121,131,107,95,88,111,90,45,22,163,177,63,46,135,227,250,250,251,247,251,252,251,246,248,247,247,245,247,247,246,244,244,245,244,244,247,245,244,244,243,242,244,242,242,244,243,242,243,244,244,244,244,243,244,244,245,245,246,247,246,248,246,248,248,247,247,247,247,248,247,247,236,116,3,1,4,8,9,9,10,9,12,12,12,12,200,203,200,200,199,199,196,196,200,199,198,200,202,198,199,199,196,196,195,196,196,196,196,195,198,196,197,198,196,195,196,195,196,196,196,196,197,195,196,197,197,195,194,197,198,198,196,198,197,198,196,195,198,198,198,200,196,198,197,197,199,194,198,200,197,199,198,199,199,198,198,197,198,202,199,197,200,197,201,200,200,200,199,200,200,199,201,199,198,200,200,202,200,199,200,200,202,202,201,202,202,200,199,198,196,199,200,198,201,200,201,199,201,203,199,202,199,201,200,198,201,200,199,200,200,200,200,200,200,200,201,201,205,203,202,202,200,200,200,202,200,203,203,202,200,200,202,204,203,202,201,203,202,200,201,202,202,200,202,202,200,200,201,200,200,200,199,201,200,202,201,200,201,201,202,200,202,200,201,203,203,202,201,203,203,201,204,206,205,205,205,206,206,203,204,208,208,206,206,206,208,206,208,208,209,208,208,213,213,213,212,212,211,212,214,212,212,215,219,226,234,237,240,239,242,243,246,246,246,247,247,249,249,251,251,251,252,252,252,252,251,251,246,223,236,249,251,248,235,240,194,95,101,192,244,248,252,252,249,249,251,251,250,249,249,246,249,248,245,245,244,243,242,244,248,248,240,232,241,246,243,244,244,240,242,239,241,235,237,232,221,228,226,218,173,104,133,184,205,222,221,218,218,219,217,213,214,211,205,210,205,198,198,198,199,174,181,184,178,186,169,155,158,166,167,146,116,138,127,125,126,106,106,77,96,139,150,135,112,93,94,83,77,89,85,114,137,126,138,108,100,57,51,90,118,114,58,86,107,86,51,28,53,62,57,59,51,59,76,35,42,38,83,61,47,74,53,107,112,104,107,104,103,80,133,71,68,130,98,95,79,68,77,72,73,58,76,90,86,98,141,101,71,125,98,117,112,161,149,120,191,61,79,217,74,5,45,23,25,92,204,203,140,193,251,251,226,148,141,200,249,202,157,175,149,192,234,251,250,250,247,103,29,47,93,112,113,105,51,44,104,137,134,91,62,67,34,18,12,17,39,53,56,57,46,71,110,73,33,41,152,137,101,118,49,19,19,11,16,19,23,22,21,25,26,24,27,23,24,25,28,30,31,34,31,28,67,106,93,54,54,122,139,105,116,139,142,120,111,97,60,44,37,40,32,20,19,26,52,78,84,64,33,30,23,22,30,34,27,58,130,96,34,21,17,26,26,25,30,28,28,24,24,28,24,47,103,80,36,42,134,172,90,49,42,32,31,27,29,32,18,29,53,34,23,21,20,17,22,25,21,25,30,30,30,29,32,74,63,33,38,32,34,33,33,31,34,40,46,53,83,100,61,39,21,42,88,94,85,67,75,170,144,103,117,133,128,78,53,51,29,34,46,34,21,24,29,33,33,34,37,37,31,43,91,82,79,86,70,69,83,71,68,69,48,123,132,110,102,92,112,94,38,34,207,236,177,121,38,168,245,245,246,244,252,252,249,249,250,248,248,247,245,246,246,245,246,247,244,244,245,245,244,244,244,244,242,242,243,243,244,244,244,243,244,244,244,242,244,244,245,246,245,246,246,246,247,248,248,248,248,248,249,250,249,248,236,116,4,1,4,8,9,9,10,10,11,12,11,11,198,198,196,198,199,195,196,198,197,197,198,195,196,197,197,196,198,195,195,196,196,196,194,195,194,195,196,195,195,193,196,194,193,197,194,193,198,196,196,194,196,199,197,197,197,195,197,196,196,197,196,196,196,198,195,197,197,196,197,196,198,196,198,195,195,195,196,195,197,198,197,200,196,198,198,196,198,196,199,200,199,200,200,199,198,198,200,199,199,200,200,199,199,200,200,199,200,200,199,198,200,202,199,200,200,199,200,198,200,200,198,201,200,203,200,200,201,201,203,199,201,201,199,202,203,199,199,203,201,202,199,201,202,200,201,203,201,202,202,203,199,203,203,201,205,199,200,202,200,202,203,200,201,201,200,202,200,201,201,200,200,199,200,200,201,199,202,200,198,202,200,201,201,201,202,203,201,203,202,203,204,202,201,203,203,203,203,204,205,203,204,204,205,205,208,207,208,207,208,209,206,206,209,207,208,212,211,212,212,213,212,211,214,211,214,210,212,227,228,246,250,250,252,252,251,251,251,251,251,251,251,251,250,250,250,250,248,248,242,236,230,220,221,219,188,184,190,182,186,199,190,155,170,192,191,194,191,181,174,173,174,171,176,167,166,159,155,160,157,163,162,162,159,157,163,159,158,153,156,159,158,155,151,151,151,152,151,144,160,148,119,125,121,137,128,112,130,118,116,122,127,127,119,116,113,111,106,100,99,97,93,87,80,87,80,96,85,100,126,110,134,116,112,118,92,72,51,57,46,60,71,83,96,74,77,75,81,79,61,76,90,81,90,73,38,39,41,46,34,21,34,37,19,16,41,52,53,110,125,101,52,46,67,63,33,22,23,41,44,25,47,16,37,21,24,41,33,59,31,80,97,69,78,57,33,8,35,55,25,27,17,23,29,42,46,18,46,35,11,27,128,100,42,97,134,147,141,174,104,136,198,63,151,231,41,15,40,3,55,178,206,191,170,223,250,244,179,134,191,242,250,158,127,174,210,246,252,252,249,249,129,27,42,85,121,117,104,49,49,98,133,143,89,70,68,39,19,13,15,23,46,68,64,68,51,95,127,67,23,55,160,130,118,118,42,18,18,15,17,16,24,26,26,25,20,24,27,23,26,25,30,29,31,30,34,30,38,78,77,53,48,80,88,76,114,134,103,82,59,54,47,29,32,39,39,24,18,31,54,68,72,51,38,53,35,24,30,30,28,50,115,89,33,27,15,27,35,37,41,34,37,33,22,29,31,51,114,90,40,31,46,62,44,40,44,33,25,32,33,24,19,39,56,35,24,20,17,24,26,24,24,23,25,23,28,27,38,93,88,42,35,35,34,27,32,36,43,71,77,81,94,81,54,27,38,69,107,100,73,51,81,130,113,120,128,134,120,78,62,49,39,51,49,32,23,22,26,31,37,31,32,43,32,34,54,41,54,65,46,42,50,53,65,77,48,113,139,122,111,90,118,108,37,32,190,227,229,167,25,46,213,238,247,247,249,251,248,251,251,248,247,245,245,246,245,245,245,247,245,244,245,242,243,243,244,244,244,243,244,244,244,244,244,245,242,242,244,244,244,244,244,245,245,248,247,247,246,245,247,247,245,247,247,248,247,247,236,115,4,1,4,8,9,9,10,10,11,11,12,12,195,199,195,196,196,196,196,195,198,196,198,198,195,194,194,197,194,198,197,198,196,195,196,194,195,193,193,195,196,195,195,194,195,195,195,194,195,195,194,196,193,195,198,194,196,196,192,195,196,195,197,198,197,195,195,198,197,196,198,196,198,195,196,196,196,198,195,197,198,198,198,196,198,196,194,198,198,198,195,196,199,196,199,198,200,198,198,200,201,200,199,200,199,199,201,202,201,200,200,200,199,198,201,203,201,200,200,203,203,200,200,198,200,200,200,200,197,201,201,200,199,202,201,201,202,199,202,201,200,201,201,198,200,200,200,200,200,201,200,200,201,202,199,199,201,203,202,200,198,200,201,200,200,200,201,201,201,200,200,200,198,199,199,200,200,199,199,202,201,200,201,201,201,200,202,201,203,201,203,205,200,203,203,204,205,202,204,204,203,205,205,205,206,208,211,208,209,209,210,210,209,208,210,211,211,212,212,212,213,213,214,213,213,212,212,210,212,223,190,177,183,180,181,175,176,171,170,167,166,163,158,155,151,150,143,140,141,134,129,125,116,119,169,179,98,73,87,91,97,103,101,108,113,104,98,89,93,82,72,83,71,73,76,79,73,66,66,61,67,80,84,81,73,62,62,64,68,65,64,67,66,63,65,59,59,60,69,64,101,105,48,53,52,89,112,108,119,106,88,63,62,64,56,56,50,49,47,47,45,51,48,47,45,40,43,63,61,51,79,102,115,121,107,94,111,92,60,53,25,44,61,71,88,68,63,77,72,83,94,89,109,90,90,87,36,24,24,29,28,32,45,56,47,44,41,39,69,118,135,110,65,57,68,80,56,41,36,53,62,50,55,22,57,34,37,63,36,51,27,61,90,71,86,72,46,16,16,37,24,32,23,37,43,35,46,27,53,39,7,25,70,60,41,84,114,114,163,161,84,155,179,93,210,236,49,18,23,6,121,191,190,207,201,229,242,201,148,181,242,249,230,128,97,163,232,246,253,253,249,160,36,41,87,111,118,84,57,46,95,127,137,94,57,59,39,19,14,12,25,47,81,101,103,117,88,141,141,44,12,76,161,112,129,112,33,21,11,16,22,19,23,23,30,27,21,23,25,21,24,26,28,31,27,29,37,28,35,54,77,69,35,33,25,68,98,76,56,49,37,53,46,24,37,51,43,28,21,24,53,68,60,49,55,61,33,31,33,27,33,34,96,95,41,29,24,29,35,45,40,38,37,36,24,29,32,73,122,74,23,22,28,31,37,37,36,37,33,37,30,29,19,34,53,30,25,19,20,27,27,27,26,23,24,24,25,33,41,109,101,46,36,25,36,34,32,31,68,87,82,99,85,63,39,26,57,77,89,77,53,42,29,55,113,142,127,82,71,57,58,55,42,46,36,27,31,29,25,27,32,36,33,32,33,35,30,29,29,32,31,28,27,29,59,69,43,108,141,134,113,89,115,100,52,14,129,154,147,129,25,29,168,237,250,250,252,252,248,249,249,248,245,245,245,245,245,244,244,245,245,244,243,242,243,244,244,242,242,244,244,242,244,242,244,244,244,244,244,245,244,244,244,243,245,244,244,245,244,245,246,246,244,244,246,247,247,246,236,116,4,1,5,9,9,9,10,9,12,12,12,12,196,199,198,195,199,196,195,198,197,199,196,195,197,198,196,192,196,197,195,193,197,194,194,196,193,193,194,198,195,193,197,196,194,196,195,195,195,191,195,196,196,195,195,196,196,196,196,194,193,196,196,196,196,195,196,195,194,195,195,196,195,194,199,196,196,198,198,198,197,197,197,200,199,198,198,199,199,198,198,196,196,195,200,199,198,199,198,197,198,200,200,201,200,199,202,198,199,199,199,200,199,200,199,200,202,200,201,201,202,201,200,202,196,200,200,200,200,199,200,200,201,200,200,198,200,198,200,202,200,201,201,202,200,201,202,201,200,201,200,200,200,202,204,200,203,201,199,202,200,201,200,200,202,201,200,201,202,202,200,200,201,198,199,202,200,201,201,200,199,198,200,201,201,198,199,201,200,204,203,205,203,203,205,203,205,202,205,206,206,207,208,210,210,210,211,212,213,212,212,214,212,213,214,212,214,214,213,214,213,214,214,211,212,211,212,212,210,207,104,19,17,13,12,12,11,11,9,10,11,10,10,10,10,10,10,10,10,10,12,10,12,9,61,91,27,5,10,9,12,10,13,12,10,12,12,12,13,12,13,13,12,12,12,12,12,12,12,12,13,13,12,12,13,13,13,14,13,13,14,13,14,14,13,14,13,12,14,12,21,23,12,13,12,14,15,17,23,18,14,14,13,14,14,15,14,13,14,14,14,14,15,15,13,15,13,18,17,15,18,15,60,76,60,66,53,72,89,58,21,10,11,17,30,22,35,67,67,85,90,84,84,66,66,26,8,26,26,27,30,31,33,41,40,31,32,22,43,93,133,114,74,65,68,86,46,32,24,25,25,44,34,12,58,28,33,28,12,30,11,27,38,39,77,95,48,27,21,20,27,32,33,29,36,27,29,11,33,39,12,13,24,12,39,83,66,86,174,105,95,194,189,171,248,190,21,38,15,46,150,174,210,238,212,233,201,144,184,240,249,249,199,141,133,174,227,248,249,249,156,44,38,81,109,109,112,46,53,102,130,138,89,66,55,35,19,10,18,27,46,86,117,124,123,129,101,156,134,30,18,105,156,102,122,87,29,20,9,20,19,22,24,24,25,24,27,24,24,25,23,24,29,27,27,36,34,32,33,55,93,59,27,22,21,60,77,67,39,30,27,35,36,24,46,57,42,32,21,19,40,55,61,45,49,53,32,29,27,29,37,21,66,96,45,30,28,30,38,39,37,38,37,38,31,28,28,74,113,48,19,24,29,41,30,40,41,39,38,36,31,24,16,25,57,36,24,21,19,29,23,28,28,22,32,24,29,28,65,122,81,39,31,29,30,33,36,44,73,85,81,93,81,50,35,23,54,74,67,59,41,37,33,45,88,98,71,56,49,36,47,54,45,39,34,32,33,27,28,29,34,35,27,37,33,33,33,27,39,33,37,36,27,29,37,48,27,96,139,131,119,83,106,101,58,30,45,57,24,42,26,28,182,244,250,250,246,252,249,250,249,249,246,244,245,245,244,245,245,245,245,244,244,244,244,244,244,242,244,243,244,244,243,244,242,244,244,244,244,243,245,243,244,244,243,244,243,244,244,244,244,244,243,243,244,246,243,245,237,116,4,1,5,9,9,9,11,9,12,12,13,12,196,201,197,199,198,195,197,196,198,194,195,196,193,197,198,194,194,193,194,196,195,197,194,196,196,196,198,195,196,194,195,195,196,198,196,195,196,194,197,196,194,196,197,193,195,198,196,197,194,194,197,193,195,196,195,196,194,194,195,196,196,195,198,196,198,198,196,197,196,195,195,198,197,197,196,198,198,197,196,198,200,199,199,195,200,200,199,200,198,199,200,200,199,199,199,198,198,199,200,198,198,199,201,198,198,199,198,200,199,198,200,199,200,200,199,202,200,202,199,199,200,200,199,198,202,200,199,200,199,200,199,200,201,200,202,201,200,203,200,201,201,199,200,203,201,200,201,198,200,201,201,200,200,203,201,202,201,201,203,200,201,200,200,199,201,203,201,200,199,199,201,201,200,200,199,200,203,200,204,205,203,207,204,204,205,203,204,207,209,208,212,213,214,214,214,212,214,214,215,214,216,217,213,215,216,214,214,213,214,213,213,212,214,213,212,213,216,211,115,48,41,28,32,28,25,22,19,19,19,18,16,17,16,14,12,12,13,10,11,10,13,8,24,37,12,9,12,10,11,10,12,11,11,12,12,13,12,12,12,12,12,12,13,13,13,13,13,14,12,12,12,12,13,12,13,13,14,14,13,13,13,13,13,13,14,14,14,14,13,14,14,15,13,14,14,14,15,14,14,14,17,15,14,14,15,16,15,17,15,15,15,14,16,15,14,14,14,15,14,15,13,34,46,28,37,41,59,79,49,21,13,12,27,14,48,76,62,91,81,62,82,64,48,14,10,14,13,15,20,24,33,32,24,42,38,10,44,95,120,105,80,61,72,81,49,23,15,30,19,36,23,26,61,39,57,32,36,54,30,39,66,63,71,92,63,64,49,42,129,32,21,17,18,15,21,17,36,42,48,117,93,75,134,95,34,125,168,82,165,210,160,171,161,49,29,139,104,103,148,174,241,244,207,199,141,166,229,250,250,231,160,139,176,166,234,247,249,165,41,36,72,116,108,103,57,58,101,134,139,104,63,64,39,14,13,15,29,48,84,111,125,116,111,113,92,154,117,22,24,121,141,95,125,74,22,19,11,18,16,24,23,21,24,23,24,24,22,23,22,26,28,29,28,33,35,29,27,38,79,71,39,33,21,39,48,41,36,19,15,27,33,33,49,61,50,33,22,23,44,66,63,46,60,55,31,23,21,24,34,26,65,97,42,31,24,24,38,37,37,33,35,35,28,33,32,77,103,40,21,19,30,42,36,43,44,46,38,38,29,22,19,19,49,37,24,22,18,27,25,22,28,22,29,27,29,31,61,112,61,27,29,29,35,24,33,53,83,84,81,92,69,44,27,17,48,60,65,59,57,55,48,57,53,52,52,39,42,42,47,44,37,38,29,26,28,33,27,29,33,36,36,28,33,36,33,35,36,36,36,42,36,33,35,31,26,93,142,130,116,78,98,100,67,33,38,57,38,43,20,91,250,250,250,247,245,252,247,252,249,246,248,247,245,245,244,243,245,245,245,244,243,245,246,244,244,243,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,243,244,244,244,244,243,244,244,244,242,243,244,245,246,244,235,116,5,1,4,9,10,9,11,10,12,12,11,12,198,200,200,197,198,196,194,196,194,194,193,194,194,196,197,193,194,195,195,193,194,194,196,195,195,196,195,195,196,194,195,195,193,196,194,193,196,197,199,194,195,196,195,196,195,194,192,194,196,195,195,194,196,195,194,196,196,198,195,196,196,195,195,194,196,195,195,197,196,196,196,196,196,195,197,198,198,199,200,196,198,198,199,194,194,199,200,200,197,198,197,195,200,198,200,199,198,198,198,199,200,200,198,198,198,198,198,199,199,200,198,201,201,201,201,198,199,198,200,200,199,201,199,200,199,199,202,199,201,200,200,203,200,200,204,204,201,203,201,204,200,201,203,199,201,200,200,202,201,201,202,199,200,201,202,203,200,202,203,202,202,202,204,204,201,202,203,203,204,205,206,202,203,202,202,205,203,203,202,205,206,205,206,204,206,206,206,211,212,212,212,212,212,212,213,212,213,213,213,215,214,215,214,214,217,213,211,212,212,211,212,213,215,212,214,215,219,231,212,215,223,219,226,223,224,222,222,221,216,217,214,212,212,208,205,201,198,195,190,183,174,164,165,158,147,158,160,159,155,151,152,144,139,136,131,129,122,117,117,118,119,120,125,125,123,127,127,125,129,131,129,130,129,134,134,136,139,138,129,130,145,141,139,142,141,145,144,139,135,95,117,146,136,132,109,107,109,108,127,136,143,157,156,153,158,155,158,164,159,160,159,158,161,158,157,162,147,157,149,139,142,126,145,181,146,115,157,156,139,168,135,91,66,15,87,160,144,156,130,112,104,101,157,168,179,193,191,199,199,198,165,151,175,191,203,123,75,104,117,108,75,57,81,124,141,142,168,198,183,200,169,132,168,172,219,198,155,161,172,219,215,151,118,107,109,192,234,249,247,226,214,232,233,229,229,220,222,232,240,239,234,232,163,63,55,158,149,118,226,170,87,136,70,4,133,239,133,102,150,201,252,222,159,134,153,206,249,249,233,184,85,132,178,194,240,246,186,40,27,67,102,107,98,58,51,90,135,133,92,71,59,41,16,10,13,22,46,80,111,110,113,103,101,109,108,158,96,9,34,137,128,101,122,52,21,20,11,16,12,24,25,21,24,25,24,17,23,24,24,27,29,26,29,31,27,30,25,33,91,83,55,52,61,81,65,43,34,22,20,33,29,38,53,55,61,46,14,25,47,33,29,31,60,58,29,31,20,24,30,31,85,104,39,27,27,22,34,33,35,31,30,37,27,33,28,78,110,44,30,19,28,44,39,55,75,81,74,62,49,32,19,21,48,30,26,21,16,30,22,27,30,24,29,22,31,32,63,100,47,26,32,28,34,36,38,67,89,82,71,61,44,28,22,19,48,66,75,78,76,70,60,77,69,47,33,28,46,42,35,36,36,33,31,28,29,29,33,29,32,34,33,33,32,36,35,34,36,32,34,41,41,37,33,39,28,101,143,130,120,75,100,101,69,29,40,104,117,143,216,253,252,252,251,247,252,250,249,247,247,248,245,246,247,244,245,244,246,246,245,244,243,244,244,244,245,244,244,243,244,244,241,242,244,244,244,243,243,242,244,243,244,244,242,243,243,242,241,243,244,244,244,244,245,245,244,244,234,116,3,1,4,9,9,9,11,10,12,12,13,12,197,200,199,200,200,195,195,195,197,196,195,196,194,194,194,196,197,196,195,195,194,196,195,197,196,192,195,194,198,197,194,194,193,194,193,195,198,193,197,197,194,197,196,194,195,196,195,195,194,194,197,194,194,195,194,195,196,194,195,195,195,193,196,194,194,195,196,197,194,194,196,194,198,198,195,200,198,199,198,199,196,194,199,197,198,197,195,198,198,195,198,199,196,199,199,196,197,197,200,196,198,198,198,198,198,199,198,200,198,198,199,199,198,197,199,200,199,200,200,200,201,200,202,200,200,201,202,201,200,201,200,202,203,202,205,203,203,203,201,204,205,207,206,203,203,202,202,200,203,205,205,205,205,204,203,205,205,203,205,204,206,204,207,205,205,205,203,206,208,206,202,205,203,205,206,205,207,205,206,208,204,205,206,205,208,208,209,211,212,212,214,212,210,213,213,212,214,213,214,210,211,214,212,212,214,214,213,211,213,214,212,212,214,214,213,215,218,229,232,250,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,252,252,252,252,253,253,253,253,253,253,253,253,253,253,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,252,252,253,253,252,252,251,234,249,252,252,252,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,252,252,252,252,251,250,232,244,252,252,246,194,219,251,232,251,241,214,168,103,162,236,192,187,159,151,125,145,238,250,252,252,253,253,253,253,252,252,252,252,248,184,93,101,109,107,83,68,89,153,234,244,252,252,216,252,248,218,220,233,252,211,193,219,244,252,248,208,132,117,122,219,252,252,252,252,252,252,252,252,252,252,252,252,250,231,251,251,138,19,92,184,110,145,223,98,104,181,113,100,230,252,128,111,173,225,246,184,98,149,209,244,248,248,204,145,129,139,215,227,248,202,57,34,64,99,101,99,58,44,88,127,139,95,61,57,45,16,11,16,23,46,81,108,117,113,108,99,100,97,112,154,80,7,52,147,121,105,111,44,21,17,11,18,15,24,24,19,24,21,19,26,22,27,27,26,30,28,24,27,26,36,26,43,99,80,92,89,71,72,68,58,43,42,34,28,29,36,44,54,69,45,18,23,46,46,25,15,33,39,31,28,16,27,27,36,115,105,38,31,22,23,33,32,33,29,29,33,34,38,31,90,128,58,26,23,34,39,33,125,188,189,186,166,122,74,25,26,48,31,24,18,20,26,29,24,27,27,27,21,29,28,63,103,47,31,33,26,37,33,41,78,83,57,42,30,24,22,19,22,57,92,77,75,92,71,53,74,81,58,37,31,33,24,25,33,42,29,22,33,32,31,29,29,26,27,38,35,34,33,38,34,30,35,33,42,35,37,35,37,31,90,146,127,123,80,93,103,79,18,89,239,252,252,252,252,252,252,251,249,249,249,245,245,247,247,246,245,244,244,243,243,244,244,244,244,244,242,242,242,244,244,244,242,241,242,243,244,243,241,241,241,241,241,241,241,242,242,244,242,241,241,241,241,242,244,241,243,244,243,244,242,234,118,3,1,4,9,9,9,10,9,11,12,13,12,197,198,199,197,199,197,196,196,195,198,195,195,197,195,194,193,196,196,193,195,197,195,198,197,196,196,196,194,196,196,198,199,195,198,196,197,196,193,196,193,195,195,193,196,195,199,198,196,196,195,199,195,195,196,193,194,194,194,196,193,193,196,197,197,194,194,196,195,196,197,196,197,198,197,198,196,194,198,198,196,196,198,196,197,198,199,198,195,196,199,201,198,196,198,198,199,199,198,198,198,198,196,196,198,200,199,198,199,199,196,198,199,199,198,199,201,201,201,200,200,198,200,200,203,201,201,204,200,202,202,202,204,202,202,203,203,203,206,204,203,205,207,206,205,204,204,204,203,206,205,207,205,206,207,205,206,205,205,203,205,207,206,206,206,205,206,206,208,207,206,207,205,208,206,206,208,207,207,208,208,206,207,207,207,211,211,211,213,211,210,214,212,212,212,213,213,212,212,214,214,210,214,213,208,214,216,214,215,214,214,213,214,213,214,214,213,214,215,218,225,227,231,234,232,236,235,237,238,239,241,240,242,242,242,242,244,247,245,245,245,247,246,249,247,244,249,249,250,252,250,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,251,252,252,252,251,244,252,252,252,252,252,252,252,252,252,231,239,251,252,252,252,252,252,252,252,252,244,247,251,251,251,249,250,249,248,251,250,250,249,246,252,245,232,246,237,230,212,232,250,251,221,185,227,236,235,251,232,214,184,141,217,208,154,170,181,182,153,170,237,249,252,252,249,247,251,249,219,244,252,252,250,149,83,97,91,103,70,78,75,133,237,231,230,174,184,249,231,217,171,181,222,193,199,207,235,249,247,226,128,71,115,163,188,227,248,235,227,245,247,244,244,246,228,239,185,179,243,214,87,14,151,164,93,154,134,57,109,191,156,128,228,226,115,137,208,229,238,144,125,230,252,252,251,227,155,227,215,195,230,241,200,71,43,63,98,103,101,62,36,88,124,128,97,52,59,42,17,14,12,26,48,84,108,114,120,113,114,103,97,99,118,145,63,6,77,151,110,110,100,31,20,16,14,18,18,24,16,22,24,21,27,24,23,28,28,32,30,27,29,30,25,31,22,35,67,63,116,99,69,59,36,37,39,37,45,33,24,30,29,51,59,45,20,17,40,49,28,24,43,37,26,27,14,25,22,62,133,95,36,27,22,24,31,33,35,32,31,39,30,42,33,98,158,73,37,16,38,36,54,216,251,250,241,223,205,157,62,39,50,27,27,16,18,27,22,27,26,29,23,18,31,28,75,109,62,29,29,24,34,32,41,64,56,40,25,29,36,30,26,53,116,110,79,84,70,52,28,34,55,50,47,44,39,29,26,48,45,26,24,21,29,33,32,31,27,32,37,33,33,38,31,37,32,31,33,34,30,41,37,39,29,76,141,132,125,87,94,105,86,20,95,238,252,252,252,252,252,248,250,247,247,247,245,245,245,247,247,244,243,242,241,242,244,242,244,244,242,242,242,244,242,241,241,243,243,242,242,244,244,242,242,240,241,241,241,240,241,241,241,239,240,241,241,241,242,244,243,242,244,245,244,244,233,117,3,1,4,8,9,9,11,9,11,12,12,11,196,200,197,199,200,196,197,197,198,198,198,199,196,194,195,199,195,196,194,194,196,194,196,194,197,197,195,198,194,194,195,197,198,197,199,197,196,194,196,196,194,192,193,195,196,193,196,196,194,196,198,194,194,194,194,194,194,195,196,195,194,195,194,196,198,195,195,198,195,196,197,195,198,195,193,198,195,194,198,199,196,196,198,195,197,198,197,196,196,196,199,198,195,196,199,196,199,196,198,197,197,199,197,196,195,199,196,198,198,197,199,199,199,199,197,197,198,200,200,199,202,200,202,203,203,201,205,205,204,204,203,205,205,201,204,203,205,206,205,208,203,206,206,207,205,202,206,205,205,206,208,207,206,205,205,206,206,206,207,205,206,208,207,204,203,205,205,205,206,208,208,208,207,207,207,207,206,208,208,208,205,205,207,208,210,210,208,211,210,212,214,211,212,212,213,212,211,212,212,212,213,215,211,212,213,214,214,211,212,212,214,213,214,214,213,215,214,214,215,216,215,215,215,214,215,216,218,217,217,218,217,217,217,218,217,218,218,217,220,216,217,219,217,217,212,212,217,219,218,219,216,218,219,219,222,221,224,222,223,223,222,221,223,222,221,222,221,223,223,220,223,222,222,220,214,224,221,225,218,210,225,220,223,227,224,224,221,223,226,203,197,216,220,225,223,222,224,220,221,219,210,212,214,217,218,214,220,215,216,217,217,217,218,215,220,213,202,214,207,189,180,212,224,231,193,166,215,218,208,227,207,188,153,133,190,169,154,186,194,187,151,171,221,231,230,221,222,218,226,217,186,220,223,230,250,123,81,87,78,84,69,88,61,151,208,155,203,168,190,239,210,172,105,179,220,193,197,187,222,228,233,235,153,73,113,136,141,200,223,221,209,217,223,219,220,226,210,214,186,153,184,176,47,61,193,125,112,135,96,72,87,141,135,84,160,185,113,171,216,234,212,155,203,249,246,246,229,142,125,198,229,214,247,175,72,49,56,106,104,110,71,42,89,122,134,98,58,60,39,17,14,13,29,48,87,112,116,117,113,111,106,94,101,101,125,148,49,5,100,143,104,117,82,25,19,8,19,19,17,22,21,27,24,21,26,24,27,26,29,29,30,32,27,27,28,38,33,32,34,39,93,77,47,85,75,48,57,66,69,43,21,20,26,40,55,45,19,22,43,41,32,56,67,39,26,22,16,30,23,79,128,66,27,26,24,27,33,30,27,32,32,36,31,41,36,64,137,101,60,46,83,82,126,194,185,144,159,155,152,104,55,49,53,22,21,18,16,30,25,28,25,22,26,21,30,27,69,118,74,39,27,26,37,31,41,60,60,44,34,65,74,27,53,117,144,134,83,62,59,34,30,48,71,43,34,37,29,31,36,45,35,23,30,19,25,34,29,32,24,26,36,30,32,37,32,34,35,37,29,33,34,41,36,39,31,63,138,137,122,93,95,115,98,18,69,237,252,252,250,248,251,244,249,248,244,245,245,245,244,245,244,244,244,242,244,242,243,242,239,241,239,239,242,241,241,242,242,242,243,241,241,242,242,242,240,241,239,240,240,241,241,239,239,239,239,241,242,244,243,244,242,244,244,244,246,244,233,116,4,1,4,8,9,9,10,10,12,12,12,12,199,199,199,198,199,198,199,199,198,199,198,196,198,196,196,198,195,198,196,197,196,192,198,194,196,196,195,196,196,195,195,195,194,197,195,196,197,197,199,194,195,196,196,196,195,195,194,194,193,194,194,192,196,196,194,194,196,195,196,195,198,195,194,195,193,193,195,193,194,195,196,195,193,195,198,197,194,196,196,196,196,195,195,196,193,193,197,197,197,197,197,193,194,198,194,196,196,196,200,197,197,198,196,196,198,198,198,197,200,198,198,198,198,199,198,199,199,200,200,203,203,202,202,202,201,203,206,206,206,204,204,207,206,205,206,205,203,204,206,204,206,205,207,208,206,208,205,206,207,205,207,205,206,206,204,205,204,203,205,206,203,203,206,204,205,205,205,207,204,207,208,204,208,209,208,207,208,209,207,209,206,209,210,208,212,210,211,214,213,212,211,213,213,212,211,212,212,211,212,212,212,213,213,212,212,212,212,212,211,212,211,212,212,214,213,213,215,213,217,215,214,215,215,215,214,214,213,215,217,215,215,214,215,216,214,217,215,214,214,214,214,213,214,214,207,208,211,211,212,212,214,211,213,213,212,212,212,214,211,211,214,212,212,211,212,214,213,213,213,210,211,212,213,207,208,215,212,215,212,196,212,212,209,216,214,214,213,213,220,202,188,217,224,214,208,209,209,208,210,209,204,196,202,209,209,207,208,208,208,208,206,205,210,207,211,205,191,207,199,173,178,210,216,217,165,160,207,218,212,212,195,169,141,110,164,173,166,187,160,132,103,143,213,222,221,214,217,215,218,210,178,214,214,225,235,107,64,60,60,77,71,92,68,172,202,169,215,175,220,186,167,166,138,227,217,181,158,181,226,221,229,250,155,67,123,124,150,200,215,227,210,215,219,219,219,234,208,212,158,105,173,113,45,140,191,108,122,116,65,80,76,129,143,83,169,185,150,205,229,214,173,163,168,175,134,110,88,45,5,105,179,204,197,60,40,61,98,112,110,72,41,86,125,134,102,61,56,41,16,11,17,25,47,87,111,117,114,104,117,104,92,97,103,102,131,139,34,14,117,134,103,109,67,22,17,15,21,21,21,19,22,26,24,22,25,29,39,46,47,46,40,36,33,27,32,39,30,28,25,35,76,95,103,146,136,90,67,40,35,33,30,27,39,55,46,57,41,26,42,34,43,83,63,33,21,18,22,24,27,90,110,43,29,26,28,36,30,35,30,34,32,32,33,36,40,31,124,109,94,200,235,214,127,86,52,33,31,24,43,37,35,57,36,16,27,18,24,29,24,27,29,28,26,24,29,24,54,108,95,49,30,26,34,35,49,79,67,37,76,116,75,44,103,137,165,150,90,96,61,47,41,70,79,34,56,47,26,39,42,36,23,24,25,23,22,29,38,26,26,29,29,30,33,33,36,32,31,36,31,33,39,38,37,49,31,57,133,135,130,103,101,115,99,18,55,232,252,252,250,242,249,242,247,245,245,245,244,245,243,244,244,243,241,243,241,241,241,240,241,241,239,239,240,241,242,241,240,241,242,242,241,240,240,241,240,240,239,239,239,239,240,238,238,239,240,242,242,245,244,244,242,242,244,242,241,242,233,116,3,1,4,9,10,9,10,9,12,12,12,12,195,199,198,198,199,194,194,196,197,197,193,196,196,195,193,195,195,196,195,193,196,195,196,196,197,193,191,195,194,194,194,195,195,193,197,195,195,194,194,194,194,196,196,198,196,195,195,193,194,195,195,195,193,196,198,195,194,196,197,193,194,196,196,196,196,194,194,194,193,194,193,194,195,196,194,193,194,195,194,193,194,196,194,195,195,194,193,195,197,193,194,194,195,195,195,194,196,194,196,197,196,194,192,198,196,195,198,197,198,195,198,198,196,199,198,200,202,200,200,201,204,203,203,202,204,203,203,205,203,206,205,204,205,204,206,204,202,201,201,204,203,206,206,203,204,206,205,206,204,202,204,200,205,206,204,203,202,202,202,203,203,205,204,205,206,205,206,207,207,205,206,207,206,206,206,208,208,209,208,211,209,210,212,210,211,211,211,212,211,209,212,210,210,212,212,212,211,212,210,211,213,212,210,211,210,211,211,211,212,212,213,212,213,213,212,212,212,212,213,212,212,213,212,213,214,212,213,212,214,215,214,215,214,215,214,214,214,211,213,210,211,212,212,214,210,211,212,211,209,212,213,210,209,210,212,211,208,210,212,208,209,207,210,209,210,212,207,208,209,207,207,209,210,203,205,210,209,211,210,195,208,215,203,215,219,212,212,206,222,215,192,230,234,213,208,204,210,204,203,208,203,199,199,205,209,204,206,205,203,205,205,206,207,205,208,205,189,207,195,159,184,211,214,214,149,160,208,210,215,220,198,167,125,107,164,161,149,168,148,133,98,125,203,221,221,213,212,212,222,206,172,213,211,229,223,102,77,72,89,69,73,95,61,193,216,199,224,184,184,143,190,180,192,235,147,142,158,198,229,218,222,247,137,61,112,134,174,185,201,212,208,224,217,216,226,234,213,175,108,100,160,65,69,192,156,114,139,71,27,50,62,139,178,128,187,213,183,228,221,146,101,72,55,42,25,27,17,10,10,110,184,150,81,21,57,95,108,121,77,35,64,118,131,94,62,59,45,21,14,14,27,45,81,106,111,114,107,103,97,96,103,102,93,98,125,118,22,19,123,123,103,108,57,21,20,15,22,21,16,23,21,27,25,29,50,68,83,80,78,66,57,51,39,32,32,35,34,31,22,50,139,159,122,155,135,97,86,38,27,33,36,45,54,59,59,72,44,27,43,33,62,89,64,37,23,19,18,26,27,82,108,64,37,27,30,36,32,30,28,35,34,35,35,37,34,66,178,139,74,209,232,186,128,108,94,78,44,41,43,32,41,61,30,19,22,29,24,27,31,24,29,27,29,27,30,30,34,95,107,57,33,23,30,37,63,91,66,49,137,141,74,87,120,119,179,165,118,138,74,79,68,51,56,28,52,38,23,40,33,31,29,26,25,21,28,30,26,28,29,29,31,28,31,35,33,34,29,32,35,34,33,41,41,38,35,49,131,136,128,116,101,111,101,27,52,229,252,252,250,239,246,243,244,241,241,242,239,241,244,243,241,244,241,240,239,239,240,239,237,238,238,240,241,240,241,243,242,242,243,240,241,244,241,241,240,239,240,239,239,237,238,239,239,238,238,241,242,241,241,242,239,240,241,241,242,241,233,117,3,1,4,8,9,9,10,10,11,12,12,12,195,196,198,197,198,194,195,194,195,198,196,195,195,195,194,196,195,195,194,196,198,196,198,193,195,197,194,196,195,195,196,195,197,197,195,198,195,194,195,195,197,196,196,196,195,196,198,198,197,198,196,194,196,196,196,195,197,196,197,195,195,194,196,198,196,198,194,194,196,194,198,196,194,196,194,196,195,195,195,195,196,195,194,194,193,195,196,192,194,194,195,193,194,196,194,196,194,194,196,193,195,195,196,196,198,195,197,196,196,197,198,198,197,196,199,199,200,200,200,201,202,202,202,206,203,202,202,201,203,203,205,204,202,203,205,204,203,203,204,202,203,202,200,201,203,203,200,202,201,202,205,203,203,202,204,203,202,203,205,205,206,205,204,207,205,204,206,205,206,206,206,205,206,206,205,207,208,208,209,207,206,208,210,211,209,211,210,210,212,209,210,211,210,211,210,211,209,210,213,212,212,209,208,212,212,211,212,211,212,214,211,212,212,212,214,212,212,212,214,212,214,212,213,214,213,214,213,213,213,211,214,213,213,214,213,214,214,213,212,213,213,210,214,212,210,211,211,212,210,209,211,208,212,210,212,210,208,210,210,209,207,206,208,209,206,208,207,207,207,206,208,208,208,203,205,209,210,210,211,196,203,216,197,207,223,208,208,204,215,198,131,166,214,210,208,203,205,203,203,206,205,201,196,202,205,204,206,204,201,203,208,203,206,205,206,208,189,209,191,150,188,210,215,208,151,176,207,210,212,222,205,162,133,120,155,152,162,185,178,184,144,153,210,217,224,212,212,210,218,201,169,212,212,235,216,134,105,80,110,78,78,77,50,164,200,199,181,169,185,178,222,186,202,186,136,165,177,221,223,217,225,241,120,80,125,128,186,160,162,193,207,232,213,223,233,240,178,127,110,125,130,43,148,183,97,148,133,34,10,42,36,107,174,111,141,167,167,195,127,64,27,27,41,56,66,60,53,47,47,196,197,62,43,43,103,107,111,85,26,50,105,129,94,61,60,43,19,12,15,25,48,79,101,111,112,114,103,90,101,99,105,101,93,105,122,100,15,30,136,114,110,116,50,25,17,11,22,22,21,24,24,26,37,64,93,117,118,109,101,85,78,71,65,54,44,50,43,48,39,55,130,149,87,116,118,110,117,45,62,63,38,49,57,66,72,77,38,29,44,33,67,98,71,34,15,15,19,27,24,32,76,73,45,43,46,47,45,48,46,47,45,50,48,48,46,104,177,95,31,50,76,71,55,117,143,127,102,66,45,37,46,57,43,35,27,26,29,28,32,30,30,31,35,29,42,31,63,144,113,53,33,23,27,24,52,93,67,105,185,114,87,110,117,95,133,150,141,162,77,73,77,44,37,26,38,29,26,34,33,28,27,22,23,27,24,30,30,29,39,38,29,34,39,33,31,36,33,37,32,34,38,37,36,39,36,43,119,136,125,116,98,104,111,35,36,217,250,250,250,238,246,242,245,239,240,240,239,241,241,242,241,241,239,237,239,238,236,237,237,237,237,236,238,238,239,243,243,242,242,240,240,244,241,243,240,239,240,239,241,240,242,241,240,239,239,241,241,241,240,241,240,240,241,241,242,243,233,116,3,1,4,8,9,9,11,9,11,12,11,11,193,200,198,196,199,194,196,198,196,197,195,198,195,197,197,195,197,196,195,196,195,195,196,196,194,195,197,197,197,198,199,195,195,196,196,195,196,198,197,196,196,196,196,197,195,195,197,196,195,194,196,196,196,196,197,196,196,195,196,195,194,197,194,194,197,194,196,198,196,196,197,196,197,194,193,196,194,195,197,194,195,194,193,195,193,196,194,193,194,193,195,194,193,193,194,194,196,193,195,195,195,199,195,195,196,197,196,196,198,198,198,198,198,198,198,196,198,200,200,201,200,202,202,203,204,203,202,203,201,203,203,200,203,200,203,204,200,203,200,203,201,201,205,202,203,203,201,204,201,199,205,202,201,200,200,203,203,202,202,201,202,205,203,204,203,202,204,204,204,204,205,205,205,205,205,206,207,207,206,207,207,208,208,207,208,209,211,209,208,208,209,209,208,210,210,209,210,210,209,211,212,212,210,211,210,212,213,211,211,208,212,211,209,212,214,214,214,214,214,212,214,214,214,212,211,212,213,212,213,214,213,213,209,212,211,212,213,212,214,212,212,211,212,214,212,211,209,210,208,211,211,210,210,209,210,210,210,208,210,208,210,207,207,206,208,207,205,208,206,208,208,209,205,200,210,209,208,208,212,197,196,214,169,166,207,205,210,206,208,175,61,73,171,203,209,202,202,203,203,207,203,201,196,193,205,206,204,203,203,202,205,202,201,204,202,208,188,206,190,149,196,207,216,203,153,182,203,209,210,220,202,154,115,113,171,178,185,195,171,198,176,167,206,211,223,216,214,211,221,198,168,211,212,234,199,141,116,64,104,87,97,79,24,120,167,151,168,198,177,208,198,121,198,196,178,197,200,225,215,217,229,233,117,130,164,136,183,141,141,178,194,230,222,227,240,176,105,132,139,148,84,74,214,139,19,148,147,35,54,66,33,62,108,71,62,78,84,82,53,27,43,53,81,93,92,56,73,71,83,190,123,52,62,74,113,105,85,34,54,106,136,108,63,61,46,23,12,12,29,54,88,102,108,115,110,115,96,94,111,110,102,90,84,124,143,102,44,90,162,112,116,116,44,19,12,17,25,19,17,24,28,42,67,104,116,141,131,111,101,91,94,101,103,100,93,78,79,83,85,93,96,118,84,135,105,157,122,50,113,57,52,61,63,77,71,70,36,33,37,28,61,78,57,29,17,15,22,27,23,20,27,39,77,90,84,91,82,87,97,98,89,94,95,92,98,83,56,30,29,24,52,50,41,93,122,125,105,70,38,27,22,37,45,39,41,32,37,39,40,43,39,40,45,46,53,43,85,122,72,35,27,25,22,27,38,67,70,113,175,87,70,120,113,87,83,87,110,127,50,59,83,52,48,43,46,39,39,47,45,31,19,21,23,24,31,37,36,48,53,61,69,63,56,42,32,35,35,28,37,31,33,39,33,38,40,36,110,136,132,125,95,104,113,48,26,199,249,246,250,235,245,240,242,240,237,240,239,239,241,239,238,237,235,237,236,236,234,234,232,232,232,233,236,239,241,244,242,241,242,239,238,240,242,241,242,242,243,242,242,244,243,243,241,242,243,242,242,242,240,239,236,237,237,239,241,241,234,116,3,1,4,9,9,9,10,9,11,12,12,12,196,198,198,195,196,196,197,196,198,197,196,197,196,196,195,198,195,195,198,197,195,193,197,198,195,197,195,197,196,194,197,195,196,198,197,196,194,196,198,196,198,196,195,200,196,198,198,195,196,196,196,198,198,198,198,195,196,196,195,195,195,198,196,196,196,194,196,198,197,195,199,194,195,197,194,196,195,194,196,195,194,194,196,195,195,194,194,196,197,195,195,196,194,198,195,194,195,198,198,195,197,198,198,196,197,194,196,195,194,198,195,196,199,196,199,199,200,201,200,200,204,203,202,203,200,202,202,203,203,199,202,201,199,204,201,200,203,200,202,202,202,200,201,202,203,202,200,202,201,201,203,200,201,200,203,202,200,201,204,202,200,203,201,202,200,203,205,202,206,204,203,203,203,206,205,205,204,203,206,205,208,207,210,210,208,211,205,207,208,207,208,208,210,209,209,208,211,210,210,211,210,208,210,212,210,210,212,213,211,212,213,212,214,212,213,212,212,213,213,210,211,212,213,210,211,212,210,213,214,212,212,212,211,212,212,213,211,212,212,210,211,210,212,210,209,210,210,210,209,209,210,207,209,208,210,210,208,208,207,207,210,210,206,209,208,207,208,208,208,207,206,210,201,201,208,207,208,206,208,199,193,212,160,141,198,204,210,205,206,196,105,100,170,202,213,205,201,203,203,205,205,203,198,194,199,204,203,204,204,201,202,201,203,203,205,207,186,209,188,158,205,207,218,192,145,190,205,208,208,221,196,146,114,99,160,181,178,157,143,196,166,153,204,201,215,211,218,213,221,195,169,214,217,228,156,131,106,75,118,88,115,72,26,103,170,179,205,211,169,193,135,123,215,201,188,179,208,224,213,214,234,222,134,201,201,160,161,128,145,144,163,226,231,239,198,74,84,142,180,152,60,141,235,96,57,196,127,55,77,66,62,48,59,56,63,66,42,51,44,53,50,39,44,40,44,39,29,38,30,56,46,59,90,85,112,78,43,48,94,137,112,70,62,50,23,11,15,26,49,91,110,112,115,111,112,110,97,103,115,102,93,79,112,179,163,125,108,130,164,101,104,105,35,25,12,14,24,18,22,27,41,61,103,139,125,117,109,106,98,92,111,126,139,137,119,93,97,120,120,103,93,95,105,118,98,151,78,24,73,45,62,78,92,102,66,50,37,27,33,20,30,38,29,23,18,19,19,23,22,26,24,26,77,95,90,95,69,111,149,124,101,136,139,121,100,46,21,21,29,34,67,56,71,142,141,141,116,56,31,27,25,17,26,51,56,56,63,59,51,61,69,73,78,78,84,69,69,58,28,27,23,21,29,28,27,40,32,75,118,59,56,79,100,85,70,74,87,98,73,86,117,81,55,71,68,55,56,62,42,30,25,27,29,30,44,48,59,63,71,93,102,93,76,60,46,31,28,33,35,32,34,40,34,33,39,25,100,143,134,127,93,97,106,48,23,189,249,244,250,236,243,235,239,239,237,238,237,238,237,236,237,236,234,235,235,232,232,234,233,234,236,236,238,240,244,244,242,241,239,239,243,244,243,244,243,243,244,244,244,243,243,242,242,244,244,243,242,241,240,239,237,236,237,239,241,241,232,116,3,1,4,8,10,9,10,9,11,12,12,12,194,199,196,196,200,195,195,197,195,197,194,194,194,194,196,197,197,196,196,196,196,194,195,196,194,196,196,196,194,196,198,195,197,196,194,195,195,198,197,195,199,196,198,196,194,196,195,196,198,197,196,195,198,198,197,196,196,198,198,197,193,196,197,197,197,198,197,196,197,196,198,197,196,197,197,197,196,195,197,194,195,196,193,193,194,196,192,193,196,195,197,195,194,196,195,196,199,194,197,197,196,199,197,196,196,198,196,197,195,196,196,196,198,199,201,197,199,200,200,202,200,200,198,201,202,202,200,200,200,200,203,199,202,203,202,203,200,203,200,202,203,200,200,199,200,199,199,200,201,204,202,202,203,202,203,203,203,200,200,202,202,203,202,202,203,202,202,204,202,202,203,204,205,204,205,205,203,205,206,205,205,205,207,207,206,207,206,206,206,207,206,207,208,208,209,207,211,210,209,211,207,209,211,210,210,209,210,209,212,209,211,211,209,210,210,209,209,211,210,210,213,210,210,213,212,213,210,210,212,210,212,213,210,211,209,211,212,209,210,211,212,209,211,207,208,210,207,211,209,209,209,208,206,206,208,209,208,207,208,206,205,206,206,204,206,205,203,207,205,205,206,205,200,202,207,205,206,204,207,200,189,211,188,165,201,205,208,202,205,213,181,189,197,199,212,203,205,201,199,203,199,201,200,193,193,199,202,201,203,202,202,204,200,200,198,210,189,203,182,151,208,207,217,177,147,195,200,211,207,223,192,149,116,72,122,148,160,159,150,201,172,156,197,191,205,204,207,210,224,194,169,212,219,210,130,134,103,75,119,94,116,73,44,158,216,205,243,171,131,207,150,156,214,178,160,172,217,224,215,211,241,203,153,242,221,173,146,148,158,125,162,219,235,245,137,31,107,153,164,150,145,191,167,72,88,160,86,58,54,38,56,44,48,59,69,79,73,61,53,44,29,21,17,23,21,18,15,16,15,35,54,85,97,83,82,47,43,84,125,108,72,63,47,27,12,13,21,46,89,104,109,111,107,110,99,100,100,103,105,89,85,115,185,221,170,145,132,146,160,95,110,92,23,19,12,17,19,21,32,26,56,107,125,132,115,92,94,96,90,76,87,92,91,95,76,55,61,79,88,77,68,82,92,83,44,76,43,35,67,37,59,82,83,78,53,48,37,23,30,26,18,16,18,20,16,17,24,27,26,29,39,62,74,64,47,39,28,21,34,32,24,25,36,31,33,32,21,30,24,48,76,46,121,195,169,131,86,43,27,40,35,26,14,33,40,34,51,33,38,55,49,52,78,87,116,124,81,60,31,30,30,21,33,27,27,26,22,73,91,54,37,48,94,83,80,95,79,104,101,114,137,55,42,78,74,55,47,49,46,43,43,42,44,53,54,63,70,71,88,106,107,98,90,71,63,45,32,34,28,38,36,29,35,36,39,29,87,137,134,128,94,93,108,59,19,171,246,242,249,232,238,237,236,237,234,237,233,233,235,233,233,232,231,231,233,235,233,235,238,240,240,240,243,244,242,243,241,241,240,241,241,242,242,241,241,244,243,243,243,241,241,241,243,241,240,241,239,241,236,235,234,234,235,237,236,237,231,117,3,1,5,8,9,9,10,10,11,12,12,12,198,198,198,196,197,199,196,196,196,196,197,197,195,195,197,196,195,194,195,194,196,196,198,194,195,196,194,198,198,197,196,195,196,194,198,198,195,198,195,195,196,196,195,198,197,196,198,197,197,196,196,196,194,196,198,198,196,197,198,196,196,198,194,195,196,194,198,194,194,197,198,194,197,199,196,196,196,197,197,198,195,195,196,195,198,195,194,196,194,194,195,195,195,196,197,198,196,197,198,198,199,198,199,198,198,197,197,197,196,198,198,198,200,197,199,200,201,200,200,201,201,200,199,199,202,201,201,201,200,200,201,201,200,202,201,203,203,200,201,200,200,200,202,201,199,201,201,202,203,199,201,202,203,204,202,202,203,202,200,202,199,201,202,203,202,201,202,203,204,200,203,204,201,202,203,201,202,205,206,205,205,203,206,204,202,204,204,207,206,208,208,207,207,207,210,209,209,209,208,210,209,211,211,211,210,207,209,208,209,210,212,209,208,209,208,210,208,211,211,208,210,210,208,208,210,211,211,212,211,210,211,212,212,212,210,208,210,210,209,211,211,208,212,210,207,207,208,207,208,208,209,208,209,208,207,206,206,207,207,205,206,205,205,207,205,205,206,206,206,205,208,204,197,204,206,206,206,205,208,203,191,211,203,190,210,207,206,198,205,214,201,221,209,197,208,201,203,200,198,200,199,203,202,197,192,197,203,203,203,202,205,202,201,201,199,206,188,202,167,156,211,205,217,168,147,194,202,212,206,221,188,143,101,74,140,178,183,168,169,211,169,137,186,200,205,195,201,200,214,192,173,215,217,198,134,162,109,79,108,82,99,44,66,198,231,218,211,138,177,218,171,172,145,141,167,200,232,220,217,212,245,177,167,250,228,188,132,163,184,152,157,189,225,236,107,34,138,135,155,182,225,187,84,65,67,89,42,29,27,14,35,23,27,36,40,45,43,37,27,21,22,15,19,17,16,18,16,19,18,54,74,97,106,80,50,42,83,106,105,67,62,56,21,13,11,29,46,81,113,112,112,107,107,98,96,107,101,100,87,75,119,184,235,197,120,128,131,142,145,97,115,83,15,20,17,16,22,24,34,41,110,182,152,115,105,88,78,86,94,70,48,45,48,51,48,49,46,55,69,70,72,71,76,62,41,44,35,39,48,35,46,70,58,56,52,47,49,41,38,27,17,15,17,20,26,26,24,36,45,63,87,85,77,64,67,66,35,28,26,23,29,27,26,25,35,27,30,42,40,57,66,71,148,189,146,103,62,52,46,37,35,34,29,25,22,23,24,17,17,24,21,19,31,68,103,116,112,74,56,54,43,37,36,31,27,21,48,105,87,53,29,63,116,85,89,81,108,157,92,54,61,44,41,51,51,36,37,47,50,56,56,56,60,60,76,87,99,107,108,112,99,97,95,88,76,61,43,37,31,31,34,26,35,32,40,28,79,140,135,131,98,94,102,59,15,156,245,241,249,230,233,234,232,234,231,235,232,232,231,230,232,231,231,230,231,232,230,238,244,246,245,243,244,244,244,242,241,241,241,242,240,242,239,240,241,241,242,241,242,240,242,242,238,239,240,240,241,239,237,235,232,233,234,234,237,237,229,117,3,1,5,9,9,9,11,10,11,12,11,11,196,198,196,198,199,197,197,198,196,196,197,201,199,196,195,195,197,195,195,195,196,197,195,194,196,197,196,195,192,195,198,195,196,195,195,198,198,198,196,193,198,194,198,198,198,199,194,195,194,192,194,195,196,196,197,195,194,196,195,195,196,195,192,193,194,195,195,196,196,193,196,197,195,196,198,197,196,196,196,195,195,198,198,196,196,195,195,195,196,195,196,195,195,198,196,197,200,198,199,198,200,199,199,200,199,200,195,198,196,200,201,198,198,196,198,198,200,199,199,199,199,200,200,201,199,199,200,200,201,202,201,199,202,200,198,201,200,199,199,199,200,200,203,200,200,200,200,202,200,202,199,201,201,201,202,199,200,201,201,201,199,200,200,201,202,204,204,203,200,201,202,203,202,203,203,203,204,204,205,202,207,206,205,207,205,205,205,208,206,207,208,205,207,206,208,207,208,207,206,211,206,208,211,210,210,208,210,210,211,207,211,212,208,209,208,210,210,210,212,211,211,209,209,208,210,211,208,210,211,210,210,209,209,211,210,209,211,210,208,209,209,208,209,208,210,210,206,207,205,206,207,206,207,207,204,207,207,205,206,205,206,203,205,207,204,206,205,206,206,203,206,202,199,204,207,206,205,202,206,207,191,201,213,189,198,209,206,199,200,208,195,207,203,194,205,201,205,204,202,204,201,201,203,203,198,195,203,203,205,205,203,204,203,205,201,208,194,199,169,170,216,206,210,158,156,200,201,212,209,217,174,137,100,104,187,207,178,159,179,214,165,128,186,197,206,205,193,195,210,186,175,219,208,196,155,176,131,81,95,97,81,30,70,169,182,194,207,158,203,225,174,149,153,167,181,221,229,223,220,224,243,136,168,249,233,198,141,169,193,150,124,181,216,216,98,76,146,138,162,202,249,151,49,59,72,57,20,23,14,11,19,20,21,19,24,20,21,18,20,17,15,18,17,17,18,18,18,20,37,73,86,101,94,50,60,77,105,99,63,57,55,29,12,11,23,44,76,106,120,107,106,111,96,98,106,102,96,89,83,110,167,206,197,133,89,106,99,116,127,98,114,61,19,24,12,24,24,31,29,61,163,187,131,107,75,54,50,42,51,43,32,35,34,38,47,40,31,44,63,76,77,72,64,46,41,40,34,36,41,43,55,74,59,61,57,46,60,62,60,39,23,18,16,19,36,64,69,70,76,122,128,98,74,75,78,58,40,30,28,32,36,41,46,57,69,75,88,106,124,139,161,149,133,141,125,122,118,92,93,97,85,78,67,64,51,43,37,29,27,19,23,19,44,76,88,104,92,99,92,73,71,59,57,44,41,25,71,119,87,63,25,78,127,84,103,89,129,136,61,44,53,45,31,30,35,44,43,50,53,55,60,57,77,90,84,90,86,87,100,96,85,79,84,84,78,71,55,43,33,30,35,31,33,33,39,29,69,143,139,130,104,89,104,71,16,152,245,244,249,234,235,229,231,236,229,233,232,230,232,232,232,232,230,229,229,229,229,238,244,245,245,245,244,242,243,242,239,240,239,241,240,240,241,239,240,241,243,241,239,240,240,240,241,239,242,241,240,242,236,235,233,234,233,234,236,234,229,118,3,1,4,8,10,9,10,10,11,12,11,11,197,199,198,199,199,197,198,198,199,198,200,200,197,197,197,198,196,195,197,194,194,194,197,193,194,196,193,197,195,195,196,195,195,194,196,194,194,195,195,196,194,196,196,195,193,194,195,193,195,196,196,191,193,194,193,193,195,194,193,193,193,193,193,194,195,192,195,195,193,196,195,195,196,195,197,195,196,197,194,196,196,195,196,197,197,197,194,195,195,196,197,195,196,196,198,198,196,198,199,197,198,196,196,198,197,198,199,199,196,199,200,199,200,198,198,199,199,199,198,196,198,199,199,200,200,201,200,203,201,201,200,199,200,198,199,201,200,199,201,201,199,199,202,204,202,199,199,200,203,201,204,201,200,199,200,200,200,201,200,203,202,203,200,202,202,203,202,199,204,201,203,203,203,204,202,201,202,203,201,202,202,202,204,203,206,205,206,206,204,204,204,208,207,207,208,207,207,205,207,208,207,208,208,208,205,206,211,210,209,208,210,209,208,209,207,210,208,210,210,208,209,211,212,210,209,210,210,208,210,211,208,208,209,211,210,209,210,208,208,207,209,207,210,208,208,208,207,207,205,205,207,205,206,208,204,205,206,205,204,205,207,203,206,204,202,201,201,206,204,203,206,199,199,206,204,205,204,202,205,206,190,195,208,194,194,205,203,196,204,205,193,201,200,192,201,203,203,204,202,206,202,203,203,202,202,196,203,206,205,205,202,203,204,204,203,210,198,195,160,176,218,212,208,156,174,206,203,215,209,210,165,133,105,116,177,167,144,164,196,223,172,125,184,202,207,205,202,201,204,181,177,215,196,199,165,157,103,83,118,107,84,57,71,99,152,222,202,174,196,175,162,157,187,194,201,230,220,226,221,237,227,98,165,244,235,215,160,173,166,131,130,188,219,213,165,134,147,165,182,213,235,95,35,66,47,35,16,21,17,15,22,20,20,18,17,18,17,17,22,20,14,13,20,17,14,15,18,25,59,87,81,82,55,47,81,101,102,66,59,53,24,14,19,29,46,81,100,113,116,108,107,100,94,103,105,103,94,89,128,183,184,143,133,99,81,88,67,98,115,109,122,57,17,22,10,24,33,35,30,71,157,159,119,83,57,44,37,33,40,37,43,45,39,51,45,30,24,34,51,60,61,54,53,44,46,41,35,38,33,45,50,64,61,57,62,55,59,69,67,63,51,35,27,34,72,91,78,77,94,98,86,57,36,35,34,30,29,35,42,68,89,127,158,185,212,203,205,196,185,184,175,151,93,55,74,79,89,113,119,139,133,117,127,131,132,127,97,82,67,53,45,28,34,44,47,70,63,71,71,48,63,76,81,78,62,35,86,117,81,52,51,119,111,90,108,64,102,109,53,52,56,46,39,39,46,56,51,52,57,64,65,66,101,98,63,53,50,61,62,62,61,59,61,69,70,66,62,48,34,30,35,32,36,29,38,24,60,144,145,136,108,89,110,90,45,165,241,241,250,240,239,234,233,234,231,233,230,231,232,232,232,229,231,231,232,233,235,244,245,244,245,244,244,241,241,240,240,240,241,241,239,241,240,241,241,241,241,240,240,240,239,240,239,240,240,240,240,240,239,236,234,234,235,234,236,233,225,117,3,1,4,8,10,9,10,10,11,12,12,12,199,201,201,196,196,198,199,200,198,199,196,196,196,196,198,198,198,196,194,198,198,196,195,194,196,196,195,196,195,196,196,195,194,195,197,194,195,194,193,194,196,194,193,193,193,193,193,191,194,194,193,191,193,194,194,193,193,194,194,193,191,192,193,195,191,194,194,193,194,193,196,194,196,196,194,194,195,196,195,195,196,196,196,194,196,196,194,193,196,195,197,198,199,196,196,199,198,195,194,196,193,194,199,197,196,196,198,198,195,198,196,197,200,200,199,198,200,198,198,199,198,199,200,200,201,199,200,200,200,200,200,200,202,202,200,200,199,201,203,201,201,201,201,201,202,203,201,201,202,202,201,201,200,201,200,199,201,203,201,201,202,202,202,199,201,200,202,203,202,201,203,203,199,202,203,201,203,204,202,203,204,202,203,202,203,204,206,206,202,205,208,206,209,208,205,206,207,208,208,208,208,210,206,207,208,207,208,205,208,206,208,207,206,210,208,207,207,208,208,208,208,207,208,207,209,210,208,210,209,208,208,209,209,210,209,208,208,208,208,206,208,207,208,206,206,206,206,207,204,206,206,208,207,205,204,204,203,205,204,203,204,200,203,204,202,204,202,201,203,202,202,198,200,205,202,206,205,204,203,206,195,188,208,199,193,203,198,199,205,205,193,202,205,192,198,206,207,201,201,204,205,203,202,206,203,194,197,201,203,204,203,203,204,202,201,210,202,184,153,174,211,214,199,165,183,203,205,212,208,197,148,114,93,82,143,161,157,185,207,224,180,130,171,196,203,212,203,200,211,180,174,201,176,207,137,83,81,86,133,112,73,65,61,130,214,234,208,170,129,164,165,146,181,163,203,230,214,229,221,247,198,81,183,236,235,225,185,164,124,151,158,188,212,216,204,160,184,213,196,231,191,66,62,55,24,18,22,22,15,22,18,19,21,20,17,16,19,15,17,18,18,18,15,19,19,19,16,41,85,84,66,52,46,71,97,98,68,60,53,27,16,77,83,68,87,115,114,120,117,111,99,98,98,100,109,93,93,107,160,202,127,72,83,89,94,98,72,91,113,122,122,41,14,19,14,38,35,35,33,93,171,133,89,67,48,42,42,42,49,50,42,48,49,37,31,22,23,33,39,57,51,48,44,44,46,33,34,35,34,39,45,53,48,46,55,60,55,63,68,73,72,59,64,86,103,81,63,52,52,63,59,45,24,18,17,27,48,72,129,191,217,214,200,191,165,142,135,87,73,58,87,107,54,38,34,33,62,39,77,88,46,50,53,56,84,128,150,164,160,147,115,75,63,44,32,42,29,30,27,26,41,44,59,69,71,68,103,93,77,91,97,136,112,93,88,45,102,101,41,46,42,44,46,45,55,55,55,61,67,69,59,50,73,75,46,47,45,46,51,51,54,53,51,52,54,62,58,51,44,33,32,30,35,29,36,28,51,144,147,133,106,89,113,98,58,143,210,229,250,250,244,239,236,232,227,233,231,229,231,229,230,229,229,236,239,242,244,245,245,244,242,241,240,240,242,239,239,239,237,239,238,239,241,240,240,238,240,240,238,239,239,239,239,236,239,239,237,235,230,230,228,230,233,233,234,233,229,118,3,1,5,9,9,9,12,10,11,12,12,12,200,204,201,199,199,200,200,198,198,199,197,199,196,198,198,196,198,197,198,199,199,199,198,195,195,198,198,197,196,195,199,198,195,194,196,197,198,194,194,198,195,193,193,195,194,196,196,194,196,194,195,192,193,194,194,195,193,193,194,193,193,194,195,193,194,193,190,194,193,193,196,194,195,194,196,196,197,198,197,196,197,198,195,196,195,195,197,197,197,195,198,198,197,197,194,196,197,196,197,196,198,197,196,199,198,195,198,198,197,199,200,198,198,198,198,199,197,199,199,201,203,199,199,201,198,201,201,199,200,202,201,200,201,201,202,201,202,201,200,202,202,202,202,200,203,201,201,201,201,201,202,200,202,202,203,203,202,202,202,201,200,203,200,202,202,201,201,203,205,202,204,202,202,202,203,203,203,206,204,203,204,207,208,207,203,206,207,206,208,205,208,209,208,209,208,209,208,208,209,209,207,209,208,208,208,209,208,204,208,207,208,208,208,209,206,208,210,208,208,208,209,209,210,208,208,208,208,207,209,209,209,210,206,207,206,207,207,205,208,210,207,205,208,206,207,207,205,205,205,205,206,205,204,205,205,204,203,204,203,202,203,200,200,198,203,206,202,204,203,205,202,194,203,203,203,203,205,206,203,207,200,190,206,203,194,199,199,201,207,206,193,200,209,197,195,202,207,206,204,205,202,206,204,202,208,199,195,201,207,208,204,203,201,203,202,207,204,173,152,178,208,214,188,155,183,200,205,214,196,190,128,93,88,89,169,175,182,200,207,218,170,123,163,201,203,200,203,205,211,184,183,182,165,196,132,110,75,71,114,86,77,71,71,169,250,220,164,158,146,203,170,127,150,156,214,222,214,225,223,248,170,102,207,234,238,235,200,165,139,169,169,182,178,186,181,167,213,221,212,225,180,87,67,35,8,19,17,22,22,19,20,19,19,19,19,20,16,14,16,17,16,15,16,15,15,23,31,61,88,71,47,50,69,88,88,65,61,55,27,15,74,154,173,138,106,108,110,120,110,96,95,103,98,101,98,98,103,100,117,118,68,54,88,87,103,107,81,98,107,127,109,29,19,19,25,41,29,28,26,56,92,68,54,47,39,38,43,46,47,54,55,48,39,30,21,22,27,36,37,44,48,39,39,38,32,35,35,27,31,37,45,53,52,53,53,53,51,54,59,61,66,72,80,90,80,52,42,34,31,30,31,20,17,37,59,103,160,190,187,169,148,111,77,54,50,49,57,61,56,57,68,74,62,56,58,46,49,58,48,49,52,45,44,46,46,49,55,63,86,122,141,155,142,99,71,53,35,26,14,19,27,23,32,44,56,76,82,83,93,105,118,122,95,80,59,48,81,57,43,49,40,37,43,53,56,56,57,69,66,61,53,43,45,39,44,51,47,48,47,40,46,46,46,50,53,59,63,61,56,47,36,29,39,30,36,34,49,136,151,128,107,87,110,100,70,97,133,190,240,244,250,250,242,233,231,231,230,229,229,229,229,227,233,239,245,245,245,247,247,245,243,243,242,241,243,242,240,239,237,239,239,239,239,240,240,240,239,237,237,239,237,238,236,237,238,236,236,234,231,228,229,230,232,232,236,236,229,118,3,1,5,9,9,9,10,10,11,12,13,12,198,199,198,199,197,200,198,198,200,196,198,200,197,198,198,196,196,196,195,200,199,196,196,194,197,195,193,198,196,199,201,196,195,194,196,196,194,194,195,194,193,193,194,193,193,196,197,195,194,194,194,192,194,194,192,193,193,191,190,193,194,193,193,194,191,194,194,193,193,192,196,193,194,198,194,196,196,195,196,196,197,194,197,196,196,198,198,197,196,197,198,196,195,196,195,196,196,194,195,193,196,199,197,196,196,197,196,197,197,197,198,197,198,200,198,198,199,199,198,200,199,200,201,199,202,200,200,203,200,200,200,199,202,201,200,203,204,202,202,202,200,200,201,202,200,198,200,202,200,199,202,201,201,204,204,203,202,204,201,204,203,201,203,200,203,203,202,202,203,203,204,203,203,207,205,202,205,206,203,206,205,205,206,206,208,204,205,206,207,206,206,205,206,208,208,211,208,207,209,210,208,208,207,209,209,208,210,208,209,207,208,208,207,208,209,209,208,209,209,207,207,209,208,206,209,209,207,207,208,207,208,205,207,207,207,207,208,207,206,205,206,208,206,205,207,207,207,205,204,206,203,205,202,203,205,201,203,203,200,201,204,202,201,203,203,202,203,202,203,203,198,199,204,203,202,202,201,200,201,206,201,187,203,207,194,195,200,206,205,208,197,197,208,202,193,195,205,205,204,203,202,202,203,205,205,203,198,195,203,205,202,203,204,204,200,207,208,160,153,184,207,216,176,154,188,201,208,210,196,189,130,107,93,79,153,167,195,206,208,211,160,130,167,212,213,207,198,198,213,185,176,175,184,209,155,172,123,81,96,70,87,83,58,177,244,153,173,169,179,245,148,144,173,185,235,214,216,218,227,242,147,129,212,227,238,233,218,190,173,178,172,182,157,178,159,162,203,204,202,199,153,92,55,7,9,16,11,22,24,19,18,19,20,18,18,17,16,18,18,21,14,16,18,17,16,23,53,72,83,56,41,77,96,92,64,62,51,33,7,44,145,194,215,139,74,97,106,116,105,92,101,104,97,92,95,103,107,98,85,81,91,130,127,90,101,101,83,112,113,131,100,26,22,19,24,27,15,19,21,33,53,50,46,38,31,36,41,50,56,62,57,36,33,23,36,55,43,48,46,46,48,46,31,35,35,29,33,29,27,37,35,43,50,54,57,49,51,50,50,54,55,63,67,59,43,33,34,23,16,17,24,46,78,149,203,205,170,126,80,55,49,51,52,51,56,53,52,53,50,42,36,49,76,79,69,65,61,67,63,62,65,55,47,39,37,44,53,61,61,69,66,78,113,127,134,104,70,59,37,26,23,14,23,27,35,53,65,66,71,83,78,73,64,57,55,48,51,44,43,50,27,29,42,55,57,59,69,64,52,55,48,48,39,31,40,40,45,50,49,51,48,46,44,52,55,57,63,64,62,49,37,37,34,35,35,36,36,116,156,129,103,84,107,93,86,114,90,98,173,224,243,244,233,229,230,230,231,228,227,227,227,228,234,243,245,244,245,245,244,244,244,244,244,241,239,239,239,238,237,240,238,238,240,238,237,238,238,237,237,237,237,238,236,234,233,232,233,233,232,231,229,231,232,234,236,237,230,117,3,1,4,8,10,9,12,10,11,12,13,13,194,199,198,200,200,198,200,196,197,197,198,200,196,198,198,198,199,196,198,196,195,196,196,198,195,196,198,196,198,197,198,195,195,194,192,193,195,195,196,193,191,193,193,193,194,193,191,196,194,192,195,194,195,195,191,193,194,192,193,192,191,193,193,194,195,194,193,195,194,196,198,197,196,195,196,196,195,196,196,196,198,198,198,198,194,196,198,198,196,193,195,194,196,198,197,196,195,196,194,196,198,196,198,196,197,198,195,198,196,195,198,198,196,198,198,198,198,200,198,202,204,200,203,203,202,203,200,201,204,204,201,202,203,200,201,201,205,203,202,205,201,201,201,201,203,202,203,203,203,202,203,201,203,204,202,203,203,203,205,205,203,204,202,201,203,203,201,205,203,203,203,203,207,204,205,205,207,206,205,205,205,206,206,206,205,206,207,205,208,208,207,207,208,207,207,209,207,208,207,208,208,208,210,208,207,208,211,210,211,208,212,208,206,207,207,209,208,208,208,208,207,207,209,208,208,208,208,208,206,207,207,206,207,207,208,205,207,207,206,206,205,205,206,206,205,206,204,204,206,205,207,203,201,201,204,204,201,203,200,201,204,200,202,202,200,199,198,202,200,201,198,198,203,200,202,200,202,202,201,202,202,187,198,208,192,192,203,203,205,206,194,196,205,203,195,191,202,205,204,202,200,205,201,201,206,202,200,196,199,207,202,202,202,201,202,204,208,155,160,191,206,213,172,166,191,198,213,212,192,199,142,115,81,74,143,160,206,198,212,206,164,154,165,212,212,214,213,199,204,182,172,167,213,215,180,187,124,133,131,95,93,76,51,142,215,178,210,188,200,217,155,191,198,214,235,212,219,212,233,214,139,159,211,225,232,230,225,200,194,182,166,175,169,189,171,178,213,209,180,135,93,46,23,8,9,14,12,21,25,23,17,19,19,16,19,17,18,16,13,17,18,17,19,21,25,46,60,75,59,46,74,103,101,69,60,55,25,15,15,74,134,141,162,87,50,99,98,107,101,100,111,104,93,99,101,101,109,91,84,136,171,154,122,96,107,100,86,110,125,137,83,17,23,19,14,20,17,22,12,19,38,40,44,40,44,65,73,70,58,45,35,30,26,42,79,81,65,63,57,53,45,39,32,31,30,28,33,31,25,27,27,36,36,46,54,41,45,42,41,41,47,53,46,40,32,18,18,17,29,55,98,172,218,204,157,104,57,49,58,51,53,42,40,34,27,29,21,24,21,17,20,46,70,55,57,56,57,59,50,54,51,50,33,20,27,25,35,43,49,67,70,77,74,74,83,102,114,101,84,67,47,32,18,16,19,32,48,53,57,58,55,51,54,50,45,49,46,36,33,27,23,35,54,55,54,58,54,54,44,49,48,37,36,28,36,45,39,48,51,57,55,48,46,48,46,47,51,51,56,49,44,45,39,36,36,38,28,99,155,130,107,92,97,89,102,108,92,72,78,117,134,182,217,226,230,224,229,227,225,229,228,232,240,244,243,239,238,242,244,244,244,244,243,241,239,238,237,236,237,239,238,238,240,239,237,238,238,235,236,236,235,235,233,233,231,228,229,230,230,232,233,232,233,234,236,235,229,117,4,1,4,9,10,9,11,10,12,12,13,13,196,200,199,198,199,200,197,196,199,197,198,198,194,198,198,196,198,197,196,196,195,196,197,196,197,197,198,196,194,194,194,194,193,193,194,193,192,193,195,193,194,193,193,194,194,192,193,193,193,195,195,193,194,193,194,193,194,195,191,192,193,194,192,194,192,195,196,195,195,194,198,194,197,198,195,195,196,197,194,199,196,195,197,196,196,194,197,195,194,195,193,193,194,196,196,194,194,195,196,194,198,195,195,199,198,198,198,200,198,198,198,195,196,197,199,198,200,198,200,202,201,203,203,202,200,203,203,203,201,202,203,203,203,203,205,201,200,201,201,202,202,204,202,203,205,204,203,203,203,203,205,201,201,202,202,200,201,203,202,202,204,203,201,201,203,201,203,203,203,206,204,205,203,204,206,204,203,206,206,207,204,206,205,207,209,205,206,205,206,207,207,208,206,208,206,207,208,208,207,208,208,209,211,208,208,208,208,209,209,210,210,208,209,208,209,210,207,208,208,208,208,209,208,206,206,206,205,208,207,206,207,204,207,208,203,205,207,206,206,204,203,206,204,205,205,205,206,201,204,203,204,206,200,203,204,200,201,200,201,200,198,201,199,201,200,201,201,197,201,200,192,198,201,199,200,200,201,199,199,203,203,188,192,206,193,191,200,204,199,203,193,192,208,204,198,190,197,203,201,203,201,201,202,203,202,202,203,199,196,200,201,203,200,203,200,206,210,153,174,190,201,208,170,168,185,202,213,194,185,175,119,119,83,91,159,181,216,190,217,196,165,157,139,201,209,212,212,207,218,185,163,179,229,198,143,149,106,139,149,127,121,83,29,135,208,201,230,151,205,206,152,193,188,221,226,212,218,208,239,188,139,181,208,226,225,226,228,205,200,175,145,154,165,196,191,208,207,229,188,79,44,16,8,12,12,12,13,18,25,27,25,17,19,17,15,20,15,18,13,14,17,15,14,24,36,49,80,60,51,71,91,98,68,60,54,29,14,14,46,110,63,45,113,69,63,119,113,115,119,116,117,99,97,105,100,101,90,71,101,174,179,131,106,94,110,98,79,118,124,127,70,10,24,15,19,25,19,19,20,19,30,37,56,85,83,79,68,52,35,29,33,48,71,95,126,110,75,82,66,37,31,27,32,29,30,29,27,30,25,25,21,23,31,35,42,35,29,28,29,29,31,29,31,27,23,20,27,54,113,194,227,200,142,77,44,49,57,50,42,36,24,21,16,17,17,13,16,17,15,14,17,40,59,50,67,84,84,78,59,46,42,32,18,13,17,16,17,25,30,34,43,55,68,80,83,73,68,83,102,111,92,68,47,27,17,18,30,37,41,41,35,44,41,40,51,41,32,29,24,24,24,48,47,42,57,42,54,44,40,66,43,31,45,56,56,50,48,43,39,47,54,54,46,43,43,43,48,46,49,47,44,47,43,47,39,40,28,86,153,135,120,99,92,79,101,122,106,90,69,56,87,178,227,230,228,223,226,224,229,230,232,238,243,243,234,234,238,239,239,242,238,237,237,236,236,235,236,236,237,239,238,237,236,235,235,234,234,234,235,233,232,234,232,232,230,228,226,227,231,230,231,232,232,233,233,232,227,118,4,1,5,9,9,9,12,10,12,12,12,11,195,203,198,197,198,196,201,198,198,195,195,198,196,199,196,193,196,195,198,196,194,196,195,195,196,197,198,198,198,196,196,197,193,195,195,193,193,191,193,192,192,191,193,193,194,192,193,195,192,193,194,193,194,193,192,192,190,191,193,194,193,195,195,192,192,191,194,195,193,196,191,193,194,193,196,194,196,195,193,193,193,195,195,197,194,193,193,194,195,194,195,194,194,195,194,194,193,195,194,198,199,196,198,198,200,199,199,199,198,201,199,199,199,197,200,201,200,202,200,201,203,200,203,203,202,204,203,203,202,199,202,204,204,202,201,202,202,204,202,202,201,202,202,203,202,203,202,200,205,202,202,200,203,203,199,202,203,200,201,203,203,203,202,203,203,202,203,205,204,203,203,206,205,204,206,203,206,206,208,210,205,208,207,207,207,208,208,205,207,206,205,206,207,208,207,210,209,211,209,209,209,208,209,209,210,209,210,209,210,207,208,212,208,209,208,207,209,208,206,208,206,208,208,204,207,206,206,207,206,208,206,207,208,204,206,204,204,205,205,204,203,205,202,204,202,203,203,201,202,199,204,201,201,203,200,203,201,201,200,198,201,198,200,200,199,202,201,200,200,199,196,199,201,199,200,201,200,201,201,199,206,191,191,203,191,190,199,202,204,203,192,193,201,201,201,191,191,201,202,203,201,200,200,198,202,201,204,199,191,200,202,204,199,201,202,208,206,155,185,194,198,202,157,171,194,203,208,181,149,137,128,141,101,87,155,207,225,191,221,188,162,155,122,195,206,207,212,203,223,188,165,189,214,135,107,129,96,123,132,140,140,107,51,131,201,208,167,139,230,195,127,145,182,224,222,217,214,214,237,160,159,188,210,237,217,225,230,213,204,172,134,128,164,197,191,141,131,173,128,59,22,7,8,12,20,17,17,19,22,24,24,27,17,19,15,14,18,15,16,18,15,19,19,29,46,69,63,51,85,99,90,68,60,56,30,17,16,20,96,110,39,59,109,104,126,151,149,145,117,112,117,108,110,107,101,93,101,125,137,152,137,108,107,101,109,89,81,115,128,120,50,14,17,15,22,22,23,33,39,34,25,37,94,95,76,69,53,51,43,52,73,96,110,125,132,94,52,44,39,24,26,29,26,31,27,26,24,18,17,16,17,17,18,27,32,30,29,34,38,44,49,48,56,61,61,65,124,203,224,200,135,71,46,53,53,45,31,19,21,12,19,18,17,17,14,18,13,16,14,20,15,37,53,61,93,102,112,75,58,45,31,22,10,16,13,16,17,15,18,17,23,32,35,45,59,69,77,78,67,73,103,110,88,67,41,27,30,39,34,30,31,29,35,38,41,33,28,21,17,22,24,30,31,43,46,53,49,40,73,62,38,72,96,94,87,69,57,50,37,36,35,49,51,44,45,37,39,36,41,38,26,31,37,50,45,47,33,73,162,148,123,109,90,79,98,116,118,101,112,190,217,243,243,227,232,227,229,227,230,237,235,240,242,236,236,237,240,243,241,239,236,235,235,234,234,236,237,237,236,235,236,235,234,234,233,232,232,232,231,230,233,233,233,231,226,224,223,224,225,228,228,230,230,229,229,229,228,117,3,1,6,9,9,10,12,10,11,12,11,12,196,199,198,198,197,196,198,198,198,195,198,198,197,195,196,198,198,195,195,197,196,197,198,196,198,196,196,196,197,196,194,195,192,192,193,191,193,191,193,190,190,195,190,191,192,191,191,192,193,189,192,191,191,194,189,190,191,189,192,193,191,192,193,197,193,191,191,193,193,194,191,190,193,190,191,192,193,193,192,192,191,193,195,193,194,193,194,196,194,197,195,197,194,194,195,193,194,196,198,195,198,199,199,199,198,198,198,199,197,199,199,198,199,199,200,199,200,200,201,200,202,201,200,203,200,202,202,201,203,202,202,204,202,202,202,204,203,202,204,203,201,202,203,203,201,203,203,200,203,201,202,203,202,202,202,204,202,203,201,201,206,203,203,204,202,204,206,202,202,204,202,205,205,204,205,205,207,207,205,204,205,206,206,208,208,207,208,207,210,209,207,207,208,208,210,212,210,210,210,211,208,208,210,210,211,212,212,211,212,211,209,209,210,209,210,211,208,208,208,205,207,205,207,207,207,207,206,208,204,208,209,205,205,205,204,203,203,202,203,202,203,206,203,204,202,200,203,201,203,202,201,200,200,204,201,199,202,200,199,200,198,199,200,200,198,197,199,200,200,196,196,201,200,199,200,199,200,200,201,201,203,194,187,197,194,192,196,201,201,203,196,188,201,203,203,197,189,199,202,199,200,200,200,201,201,202,200,200,196,194,198,203,199,202,197,208,199,147,198,195,200,198,162,180,192,207,204,183,160,146,149,159,111,98,179,226,226,202,227,188,176,174,135,199,203,206,211,201,220,171,160,194,180,126,119,123,88,121,119,112,134,115,77,136,176,197,174,163,234,139,93,155,196,231,220,222,214,224,228,145,184,193,210,239,213,223,226,224,210,181,142,150,186,186,137,74,33,67,66,31,22,9,14,14,20,16,17,20,20,24,27,26,19,17,15,17,16,14,20,12,15,17,27,43,57,62,49,77,100,99,71,57,55,33,16,10,22,40,107,90,30,88,119,98,107,113,112,90,71,77,98,124,121,107,92,92,162,206,145,106,100,97,114,104,102,87,80,124,141,110,34,12,16,21,36,35,45,49,38,29,14,38,84,78,67,59,62,63,60,63,60,77,74,49,45,47,37,31,20,20,25,24,28,28,32,30,34,38,43,46,55,67,66,72,79,84,104,136,160,169,176,182,187,176,170,168,187,198,139,119,46,48,53,41,28,17,13,15,15,17,15,19,15,16,17,15,15,17,19,16,15,31,48,61,67,61,65,53,40,40,23,16,15,14,16,15,17,17,16,18,16,19,19,27,35,46,54,69,77,74,64,80,119,117,93,83,74,69,95,54,51,51,41,37,40,36,29,20,15,21,16,22,30,31,44,48,39,50,56,40,69,112,139,131,104,92,75,61,51,41,34,34,44,46,39,39,34,27,32,27,24,21,18,30,39,53,34,62,159,155,127,107,92,84,92,117,114,100,141,236,250,250,242,227,229,225,229,229,234,239,242,240,241,241,235,239,243,243,240,239,239,237,235,237,237,237,238,235,235,235,233,233,234,230,229,230,230,230,229,230,232,230,231,227,224,226,221,222,223,224,225,229,230,229,232,233,229,117,4,1,4,9,10,9,11,10,12,12,12,12,196,202,198,196,200,196,197,196,198,196,199,198,195,196,194,196,196,197,198,197,198,198,199,198,198,196,196,196,196,194,193,194,192,193,193,194,191,193,191,189,193,192,191,190,194,191,191,192,190,192,192,191,191,194,192,193,193,191,192,191,193,192,191,192,193,192,193,193,192,195,193,193,193,190,193,193,192,193,193,194,194,192,193,194,193,194,194,193,194,195,196,195,194,193,193,196,195,197,197,196,199,200,200,198,202,199,198,200,202,201,195,198,198,200,202,200,199,198,200,202,204,201,200,200,202,203,200,202,202,202,202,202,202,200,202,205,202,200,202,203,204,202,203,203,201,203,202,200,204,202,203,203,203,205,200,203,202,199,203,203,203,201,200,202,202,203,205,205,203,204,204,205,205,205,206,206,206,204,204,207,204,208,207,207,207,207,206,207,210,209,207,210,210,210,212,210,209,210,211,212,211,213,213,211,211,208,211,210,213,211,211,213,209,211,211,211,212,209,211,210,208,210,209,208,210,209,211,210,207,208,209,207,206,202,204,204,202,205,203,202,202,203,203,202,203,202,200,202,202,200,200,200,201,200,198,199,198,198,200,199,198,199,199,200,198,199,201,200,199,194,197,200,199,196,198,200,199,198,199,198,202,196,184,191,196,195,196,202,200,201,196,192,200,201,202,200,189,195,201,199,199,200,203,200,201,200,201,201,198,193,194,202,198,204,198,211,188,150,204,195,193,194,169,174,193,210,203,196,172,157,147,139,103,122,218,248,239,212,235,193,189,192,141,200,206,204,211,206,218,155,162,205,199,151,161,182,106,96,105,119,122,81,74,118,181,213,184,207,180,95,113,188,228,230,219,225,210,236,203,139,210,171,211,240,211,222,219,229,222,193,160,178,209,181,77,39,53,38,33,24,21,23,17,19,21,16,22,18,19,21,24,27,17,21,15,15,17,12,15,20,19,21,28,48,55,51,66,94,90,73,63,55,33,14,13,19,37,64,108,56,47,117,90,60,48,41,54,48,45,45,51,95,117,100,82,91,155,162,108,78,76,80,86,83,94,78,80,123,137,95,25,9,13,23,34,36,33,28,18,21,16,18,47,41,41,33,28,38,36,34,39,45,43,39,44,48,47,46,49,60,66,70,76,81,98,124,146,169,170,175,187,191,191,181,177,178,174,185,185,175,160,149,134,121,113,85,68,55,51,53,46,39,29,16,13,16,15,15,17,13,22,17,15,21,18,19,12,17,17,16,17,26,50,52,48,40,55,42,34,32,13,13,14,15,16,17,19,17,15,16,22,21,14,21,19,27,35,41,55,71,79,78,75,111,131,139,156,145,157,146,139,144,125,105,93,77,65,57,43,39,40,31,32,36,26,35,30,36,36,32,59,79,99,106,96,70,72,84,74,65,53,47,47,47,50,51,40,30,26,27,23,20,21,23,27,50,49,49,148,153,122,117,94,90,95,108,109,99,102,157,221,242,242,234,230,223,226,230,235,241,241,240,241,238,240,244,244,245,241,239,241,239,238,238,238,239,237,235,234,230,231,231,230,231,231,230,228,228,227,229,229,227,227,227,227,224,224,225,221,223,223,227,229,231,235,237,231,116,3,1,5,10,10,9,12,10,12,12,12,13,199,201,200,198,198,196,198,199,198,199,198,198,197,198,196,195,197,192,195,195,194,196,199,196,199,198,198,198,195,196,193,195,192,194,194,194,193,191,191,192,192,192,193,191,190,192,193,194,191,192,193,192,192,193,192,191,193,191,192,191,191,192,191,191,192,192,191,194,191,191,190,192,194,191,191,192,193,192,194,191,193,192,192,192,190,193,192,193,193,194,194,197,195,194,195,194,195,196,198,195,197,197,197,199,198,199,199,200,198,199,200,198,199,200,200,199,199,201,204,202,200,199,201,202,199,202,202,200,202,201,201,201,201,201,200,201,199,202,204,203,203,203,202,203,203,204,202,201,205,202,201,203,203,204,202,202,202,202,202,203,205,203,202,203,203,201,203,204,203,204,203,204,204,205,205,205,206,204,207,210,208,207,206,208,207,208,208,208,210,208,210,211,211,210,211,212,212,210,212,212,212,214,211,208,208,209,209,211,211,209,211,210,209,211,211,210,210,210,210,210,209,207,208,207,210,211,210,210,207,211,207,208,207,203,204,202,204,201,205,204,201,202,201,203,202,200,201,199,201,202,201,200,200,200,202,200,200,203,198,198,199,200,200,195,198,198,198,200,196,193,197,198,198,198,199,198,198,199,198,196,199,200,179,188,205,196,193,199,199,201,195,188,199,200,199,198,190,190,200,202,201,200,199,200,200,197,199,200,197,195,191,200,196,200,199,213,178,141,204,191,189,182,158,182,196,200,192,164,121,117,119,124,112,132,210,216,194,199,228,190,189,191,132,190,204,203,208,203,206,158,193,217,209,168,185,191,118,137,112,105,112,90,83,148,223,211,194,186,172,133,148,220,229,227,218,220,211,237,172,141,219,145,203,235,212,221,211,229,224,194,181,186,212,172,59,47,57,41,19,13,24,19,19,23,18,17,22,19,16,19,22,23,18,20,14,12,16,17,19,17,19,27,46,48,42,66,92,92,68,60,56,31,16,14,19,33,61,93,108,70,94,124,71,68,71,57,57,45,33,39,29,45,88,99,98,86,108,113,81,84,81,77,90,75,83,68,70,118,118,77,27,28,28,30,42,40,36,36,49,47,46,50,53,57,61,56,64,64,69,81,81,80,90,121,135,147,150,166,173,175,178,167,92,157,164,174,169,164,123,126,137,127,98,81,67,56,57,57,59,64,60,56,62,60,53,49,48,48,43,42,37,17,14,15,13,16,14,15,19,17,16,17,14,20,19,15,21,19,17,19,14,30,61,57,41,41,39,41,36,17,16,18,15,16,16,16,18,19,16,16,14,18,18,15,15,20,19,23,34,55,63,77,86,74,71,64,66,73,113,101,124,137,138,146,155,151,153,150,150,139,110,87,69,66,57,51,49,37,52,36,41,45,48,71,63,39,44,51,59,66,69,65,56,55,55,67,62,43,38,27,28,30,24,20,25,51,42,43,131,150,128,113,99,93,92,110,103,101,95,89,164,235,249,248,231,223,226,233,244,250,250,250,251,251,251,251,250,250,247,239,236,234,232,236,235,234,231,230,229,229,228,227,229,228,229,229,229,226,225,226,228,227,227,225,224,225,222,222,222,224,225,227,229,233,235,235,231,118,3,1,5,9,10,9,12,10,12,13,13,12,198,203,200,199,199,198,198,198,201,196,198,197,195,198,198,199,199,197,197,196,198,197,196,197,197,195,195,195,195,195,192,194,193,191,193,192,191,193,192,192,192,191,193,190,193,193,193,193,192,195,192,193,192,190,192,190,190,191,193,191,191,191,191,192,190,191,190,188,193,193,191,194,193,190,192,190,192,195,191,193,191,192,193,190,194,193,196,196,192,193,194,195,196,195,194,196,196,197,194,196,199,198,198,197,199,198,200,199,198,199,197,201,201,201,200,200,200,198,201,199,200,201,201,201,201,200,201,203,200,202,200,202,203,203,204,203,203,202,203,203,202,202,202,202,203,201,201,201,203,203,202,202,202,204,202,205,204,203,205,202,205,205,202,206,205,203,204,205,203,205,205,201,205,205,204,207,205,206,207,207,205,207,211,208,208,210,208,212,210,210,211,211,212,212,214,213,213,213,214,212,211,211,208,210,209,208,209,209,212,210,211,210,210,211,208,211,211,208,208,206,207,207,207,208,210,210,209,208,208,210,211,210,208,207,208,206,206,207,207,206,204,204,203,204,204,202,204,205,203,206,204,205,204,203,204,201,203,200,202,203,199,198,200,200,197,200,200,200,194,193,197,198,199,197,198,198,196,197,199,196,202,199,178,190,203,198,193,199,199,200,198,188,197,198,199,201,193,188,196,203,201,199,199,198,198,196,200,198,199,196,191,199,198,202,198,211,165,141,205,196,186,177,170,185,200,197,176,136,90,105,115,126,128,123,138,125,124,165,226,182,181,189,127,186,206,202,209,204,188,160,204,195,170,114,176,196,107,138,139,146,99,47,78,171,233,190,176,176,185,171,188,236,229,229,221,219,215,236,142,167,225,129,215,230,217,223,209,226,226,203,195,171,158,133,51,61,45,15,19,13,19,22,25,24,22,18,19,22,19,16,17,17,23,29,18,16,17,15,17,19,21,36,46,42,63,98,99,78,63,57,35,18,13,16,34,61,92,117,133,97,106,107,77,99,78,55,63,43,42,47,33,32,66,106,147,150,160,150,139,147,134,139,136,135,139,118,118,127,118,89,104,135,141,156,152,148,150,163,178,186,179,182,178,175,181,172,176,168,170,166,160,139,143,158,150,149,143,138,136,124,107,99,77,66,66,69,65,64,56,53,58,61,63,57,57,59,57,57,57,61,63,59,60,54,47,46,43,40,35,26,16,23,22,18,21,15,15,17,18,17,16,19,17,16,16,23,17,18,19,18,16,41,92,81,64,54,49,51,32,15,13,16,15,16,18,17,19,21,17,18,16,17,17,18,18,19,22,25,19,25,46,59,68,74,76,66,71,63,66,68,59,66,57,62,68,67,86,100,125,152,148,143,153,151,150,140,120,102,83,73,67,56,53,57,50,39,36,32,37,36,42,51,55,52,57,69,67,60,38,30,31,33,31,30,55,53,41,30,107,149,116,113,103,93,97,104,104,116,110,92,162,224,234,246,235,229,242,248,251,251,252,252,252,252,253,253,252,252,251,237,231,229,230,231,227,226,225,226,227,225,229,229,226,228,229,225,226,227,226,225,227,227,225,225,224,224,223,225,226,227,228,229,232,234,236,234,228,117,3,1,5,9,9,9,11,10,11,12,12,13,201,205,200,198,199,194,196,198,198,198,195,198,196,197,198,199,199,195,197,198,198,199,199,195,194,194,195,194,191,194,193,195,195,193,192,191,192,190,190,191,191,191,191,191,191,191,189,191,191,188,189,190,193,191,190,192,192,190,190,189,191,191,188,191,189,189,191,191,191,192,192,190,193,191,191,192,193,191,194,191,193,192,192,194,193,193,196,195,195,194,194,196,196,199,196,195,198,197,196,194,194,197,195,197,199,199,200,200,198,199,201,200,201,200,199,200,202,200,199,200,200,200,202,200,199,200,200,200,201,201,201,201,201,200,200,203,202,201,201,199,201,202,202,201,200,202,204,202,203,203,203,204,200,203,203,202,204,203,204,202,204,203,200,202,203,202,203,202,202,206,205,204,206,205,206,204,206,203,207,207,205,210,208,208,208,210,211,211,212,208,211,212,212,212,213,213,213,213,212,212,212,210,210,209,208,208,208,208,208,207,209,211,207,208,210,210,210,209,210,210,210,208,208,207,207,208,208,209,209,212,210,208,207,205,206,207,209,207,208,207,206,208,207,207,206,205,208,207,207,207,208,207,208,207,206,205,205,206,205,207,202,203,203,201,201,202,199,200,195,194,200,199,199,199,199,198,198,198,196,199,201,196,182,188,201,199,196,198,198,200,196,189,196,199,198,200,201,188,193,198,198,200,196,198,198,199,200,198,198,199,192,192,198,199,200,206,162,150,199,196,182,181,171,177,198,193,190,143,101,111,101,121,116,97,94,79,81,145,219,180,183,199,135,177,204,200,212,202,172,172,182,141,148,89,179,200,103,109,99,136,129,90,77,168,186,164,193,178,188,151,185,232,221,230,222,220,226,225,128,193,225,131,224,226,218,226,210,224,217,210,181,93,82,84,54,59,13,16,25,13,18,19,21,24,22,21,24,19,19,16,15,21,19,25,18,17,19,17,16,24,34,44,41,49,90,101,84,66,56,40,16,14,17,37,63,84,113,122,101,83,103,110,83,90,88,73,89,75,61,64,52,49,71,100,132,133,134,120,116,122,113,119,119,117,126,111,110,107,92,91,119,147,148,162,158,147,141,151,151,146,147,141,128,128,125,110,98,86,87,75,66,63,57,61,62,65,63,63,62,62,68,65,61,70,63,69,67,63,56,56,61,55,54,49,46,44,44,42,39,39,32,37,36,24,26,27,29,35,35,39,41,45,46,47,36,16,16,13,20,19,14,18,16,22,20,17,18,21,19,21,20,72,132,119,97,84,78,77,47,15,14,13,16,21,21,17,21,17,19,18,18,19,18,18,23,42,57,55,48,32,31,39,37,41,47,50,54,55,60,63,66,66,72,71,66,66,63,59,63,57,63,65,62,83,94,115,125,89,135,130,127,121,121,106,89,86,71,62,56,53,54,48,48,53,59,61,53,50,34,18,26,29,39,52,54,47,33,21,84,127,118,107,102,95,89,110,106,120,119,99,130,134,146,211,229,238,248,248,246,246,231,226,233,240,247,247,230,235,247,224,226,227,225,224,221,222,220,222,222,224,224,224,229,227,229,228,226,229,226,225,223,223,223,224,226,226,227,228,228,230,230,229,230,233,232,230,228,117,4,1,5,9,10,10,10,10,12,12,13,12,202,206,203,202,201,198,197,199,200,200,199,199,200,199,198,195,197,198,198,199,196,194,198,195,194,195,198,194,194,194,193,195,196,194,193,193,193,193,193,190,191,190,190,191,189,191,192,190,190,192,189,193,192,192,193,191,190,189,191,188,189,191,192,189,191,191,191,192,191,192,190,193,191,190,194,190,191,193,190,193,191,192,195,192,196,196,196,196,195,197,196,198,199,198,198,198,196,199,198,196,197,199,198,197,199,198,199,199,202,200,200,199,200,200,198,200,199,200,201,198,202,202,202,201,201,200,200,202,202,202,201,203,202,200,202,202,202,203,202,205,203,206,206,202,207,207,206,208,206,208,207,206,206,206,204,203,203,203,205,203,205,206,203,201,204,206,206,205,203,205,204,202,204,205,206,207,207,206,206,208,209,208,208,210,210,211,212,213,212,212,212,210,211,212,212,214,213,213,213,212,213,210,207,208,209,208,211,208,207,210,208,208,210,209,208,209,207,208,210,210,210,208,210,208,206,208,209,209,209,212,208,208,209,209,210,206,206,208,211,210,208,210,207,208,208,208,209,208,207,210,208,209,208,207,208,207,208,203,206,210,206,205,209,208,205,206,204,203,196,199,200,198,199,196,199,200,198,198,199,196,196,196,187,185,198,200,194,195,195,198,198,188,197,198,197,201,199,197,190,197,200,199,200,198,201,199,199,198,199,200,194,190,194,199,205,199,156,164,203,197,163,159,171,185,192,182,182,133,105,106,91,105,93,77,66,62,71,139,215,178,190,204,148,175,203,207,212,185,153,165,159,154,173,111,194,171,76,91,88,95,73,108,120,184,199,199,204,147,160,134,186,221,205,218,214,219,235,207,121,223,211,131,226,218,224,224,218,214,220,205,105,56,46,60,53,36,12,15,18,15,23,19,16,21,19,18,25,13,19,20,14,19,18,19,23,19,16,20,20,31,46,41,44,74,99,94,65,56,42,18,12,19,35,65,92,100,110,84,41,43,98,107,111,148,113,131,177,120,103,125,102,124,142,119,100,71,61,52,52,52,55,63,55,57,53,55,65,63,60,58,61,62,67,68,59,63,60,58,63,63,66,60,59,62,65,63,70,66,69,65,69,71,67,65,63,75,67,67,65,55,56,54,54,53,47,47,41,41,31,29,36,27,27,27,21,20,23,19,18,21,17,21,20,16,17,19,22,43,57,65,66,75,82,80,61,23,12,18,19,19,26,19,20,23,23,24,19,23,19,24,32,112,177,146,133,128,139,135,64,18,12,16,17,18,20,17,19,19,17,19,20,21,22,19,33,70,94,89,77,69,56,41,36,21,18,19,24,27,27,32,36,42,42,51,54,50,57,55,55,64,63,64,65,65,66,63,62,59,62,65,60,69,87,106,112,127,133,128,128,109,107,94,88,95,83,83,81,69,58,53,42,39,42,45,46,30,36,27,69,127,127,118,104,102,100,103,103,118,114,88,82,47,59,164,232,245,249,223,165,139,115,109,118,138,157,141,98,154,215,217,227,220,220,218,217,221,219,221,222,218,219,221,221,223,225,226,229,227,225,226,226,222,222,225,225,226,226,228,228,229,230,228,229,229,229,228,225,117,4,1,5,9,11,10,12,10,12,13,13,13,200,203,202,203,204,200,200,201,201,200,201,201,200,198,199,200,198,198,198,199,197,196,198,193,197,197,194,196,193,196,193,195,196,196,194,193,195,192,195,191,189,192,192,193,191,191,192,193,190,190,191,190,192,191,190,190,189,191,193,191,190,191,189,192,191,191,193,188,190,190,191,190,191,192,190,191,192,192,194,189,193,193,194,195,195,196,194,197,196,198,198,199,195,196,198,197,199,198,199,199,199,199,199,200,199,200,200,198,198,200,198,197,200,200,200,202,200,198,199,200,200,200,201,201,202,201,199,202,203,203,203,203,204,204,205,203,204,204,203,205,206,207,209,209,208,210,208,206,209,208,210,209,208,211,208,207,204,205,205,205,206,205,205,204,205,204,204,205,205,201,202,204,202,204,205,204,208,207,210,208,207,211,209,211,208,210,212,212,211,212,213,213,211,211,212,212,212,210,211,208,210,210,209,210,210,208,207,209,210,208,207,209,207,210,209,208,210,208,209,208,209,210,208,207,210,208,209,213,211,210,209,207,210,210,208,210,209,210,210,209,208,209,209,209,209,208,208,208,208,209,210,208,208,207,207,208,210,208,207,208,206,208,208,207,207,206,208,203,198,202,201,200,199,199,199,197,198,199,198,197,193,193,193,184,195,201,193,194,196,199,197,188,194,199,195,199,200,192,188,191,197,197,196,196,196,197,196,195,196,197,198,190,190,193,208,188,153,176,197,200,154,150,184,189,185,165,143,105,107,100,74,91,66,56,49,47,71,140,214,177,190,212,155,170,213,211,207,168,157,183,163,171,199,127,149,122,77,93,98,90,53,48,71,184,202,231,171,136,176,131,207,220,201,206,200,211,230,179,129,247,203,139,232,220,224,220,227,218,228,187,59,44,58,52,31,22,17,19,21,15,22,19,19,24,18,20,23,16,19,14,18,18,12,27,21,23,20,23,31,39,38,48,64,84,95,62,59,47,17,14,13,32,61,89,104,103,114,76,20,35,85,80,105,144,101,130,141,113,114,94,116,162,155,113,93,88,79,63,73,71,75,94,93,93,83,87,96,85,84,66,75,99,90,84,77,75,74,83,85,76,75,69,71,72,72,75,74,66,63,61,58,50,46,44,37,45,38,36,37,23,32,30,26,31,25,22,19,19,18,16,19,17,14,17,18,17,18,14,15,15,16,19,14,16,21,18,33,85,102,116,126,139,143,148,111,36,12,14,17,23,23,17,27,22,23,23,23,22,19,24,39,122,169,146,142,139,152,151,78,20,15,14,18,15,19,24,18,18,21,26,18,20,22,20,40,109,135,131,131,112,102,84,59,23,10,14,14,15,18,15,18,19,21,25,21,30,29,29,30,37,41,51,51,50,57,57,61,66,63,62,65,62,61,56,57,95,59,65,65,70,89,101,113,116,120,123,131,141,137,142,124,105,98,84,76,72,95,60,118,153,157,143,116,116,105,111,103,106,105,87,83,65,80,203,244,244,237,113,49,62,66,66,53,43,53,49,11,78,187,211,228,221,218,217,217,219,216,217,217,218,220,220,218,219,222,224,225,225,224,224,225,226,226,225,225,224,225,223,223,225,224,223,227,226,225,225,224,119,4,1,6,9,10,10,13,10,12,13,13,13,202,203,202,203,204,204,200,204,202,201,203,202,202,202,202,201,200,199,200,198,198,198,198,197,196,198,197,193,195,196,196,193,193,194,194,194,194,193,192,193,196,194,193,193,192,192,191,193,189,188,189,190,191,191,190,191,190,190,193,190,190,191,191,189,190,192,192,192,190,191,193,193,192,190,192,189,193,194,192,196,194,196,197,196,196,195,194,197,196,197,196,198,199,198,199,200,202,200,201,200,198,200,200,201,203,200,202,201,200,199,201,201,202,199,200,203,200,203,202,200,199,200,201,200,201,203,202,203,203,205,205,204,205,207,208,206,205,205,208,207,208,210,208,210,212,211,211,211,212,211,212,212,211,212,210,211,210,209,209,208,208,206,203,204,204,205,202,204,205,203,205,206,206,206,207,209,208,210,211,210,210,207,208,208,210,212,212,212,210,210,210,212,211,210,212,210,210,210,212,210,211,211,211,213,210,210,210,209,210,211,208,210,210,210,210,211,211,211,211,210,212,213,211,212,211,211,212,210,210,212,210,211,212,210,210,212,211,210,211,210,210,210,212,211,208,208,210,209,207,209,207,208,208,207,208,206,209,209,207,210,205,204,210,206,203,206,208,200,200,207,203,203,204,201,200,201,199,199,200,194,191,198,199,183,191,202,198,198,198,198,195,182,194,199,195,200,194,196,188,187,198,197,196,194,195,195,197,195,193,194,197,193,191,187,209,179,155,185,193,199,146,158,187,179,180,155,153,129,117,86,74,87,48,35,27,44,85,173,223,178,189,207,156,159,205,215,197,170,199,201,169,185,203,107,110,129,95,121,107,81,67,44,22,117,183,204,170,183,185,144,212,217,212,214,195,210,217,148,164,252,199,160,235,231,226,228,234,217,233,164,39,55,51,31,23,16,17,17,14,23,24,19,18,19,26,21,25,19,19,16,13,16,12,23,27,23,28,29,37,42,46,65,80,87,69,59,46,23,11,15,30,51,83,106,110,103,119,86,23,61,107,83,99,89,62,80,76,68,63,64,84,122,101,61,40,31,41,53,80,66,46,55,57,66,59,104,120,103,112,76,49,45,53,42,45,39,36,46,37,37,38,44,37,33,38,32,33,31,25,24,23,18,22,23,16,22,19,27,32,30,38,33,33,36,40,24,13,16,14,17,19,15,15,15,16,20,16,17,16,20,20,14,22,14,24,21,55,177,178,179,179,179,186,184,169,56,7,16,21,23,25,26,22,20,24,27,23,22,21,21,54,121,163,153,142,144,148,162,108,37,11,11,15,16,18,19,19,18,25,26,36,19,23,22,55,152,163,147,160,159,157,157,108,34,13,12,13,15,16,16,14,18,16,17,17,20,17,18,22,18,23,24,25,27,31,35,40,40,49,50,48,59,59,60,61,66,66,64,64,61,66,65,62,70,65,62,70,85,105,125,129,134,139,146,141,141,152,132,146,155,146,125,97,96,106,118,122,125,120,112,116,120,181,241,244,244,185,46,4,49,74,80,52,36,37,27,12,86,199,216,229,222,217,218,218,220,215,217,217,215,216,217,214,218,219,220,222,221,220,220,222,221,222,223,221,221,221,224,223,223,221,217,222,223,225,223,222,118,4,1,6,9,10,10,13,10,12,13,13,13,204,205,203,202,203,199,202,203,204,202,202,202,203,200,199,201,200,201,202,199,198,198,200,196,198,199,196,198,198,198,197,196,194,194,194,194,194,193,196,195,193,193,193,194,191,193,192,192,194,193,194,190,194,193,192,194,192,193,193,193,194,193,191,194,192,192,193,192,195,191,193,194,192,192,195,194,195,194,196,198,198,198,200,199,196,199,200,200,197,196,199,200,198,201,201,199,200,199,199,201,201,200,203,203,199,201,200,201,202,201,201,199,199,202,201,201,199,201,203,203,205,203,204,203,202,205,203,204,207,204,206,208,207,207,208,208,210,210,207,210,208,209,210,210,212,211,211,211,212,212,213,214,212,211,212,211,213,213,208,208,208,207,208,204,201,201,203,202,206,206,207,205,207,210,208,211,211,209,210,209,208,208,208,208,208,211,211,210,210,211,209,208,211,210,212,213,212,213,214,212,213,212,212,211,210,208,209,211,210,210,212,212,212,211,210,211,211,210,211,213,212,214,213,212,213,210,211,212,211,211,212,211,211,212,212,212,210,210,211,209,210,210,210,209,208,209,211,210,209,208,208,208,208,210,206,208,212,208,207,207,208,207,206,206,206,207,208,201,202,207,205,206,203,203,200,199,202,199,200,195,194,198,202,185,190,203,198,198,197,200,198,186,194,200,196,198,196,198,192,185,193,198,198,197,196,193,194,195,196,196,196,191,192,188,208,169,161,195,186,203,146,160,198,174,182,178,169,152,136,106,105,81,51,55,57,110,154,218,226,176,185,210,158,130,198,214,188,186,213,191,157,156,177,116,165,177,113,108,90,84,76,52,23,93,184,223,171,187,171,150,227,219,206,209,202,219,206,144,184,248,181,144,217,238,236,236,223,174,153,100,45,66,29,18,18,16,19,18,20,19,22,19,21,21,20,22,15,21,19,15,16,14,18,17,22,30,29,40,42,42,60,77,90,66,63,47,24,18,12,30,47,78,109,114,115,107,109,76,39,83,112,107,121,84,56,119,79,42,68,45,59,110,116,57,19,81,72,63,100,75,28,21,21,32,36,95,98,92,101,53,24,22,23,28,24,24,19,15,19,18,19,15,19,17,17,19,21,21,14,19,14,16,21,16,21,17,17,46,57,61,69,73,76,77,85,47,15,16,13,14,14,18,20,18,20,17,19,16,16,20,20,22,20,14,24,16,74,195,184,185,173,174,173,181,175,59,15,13,13,25,27,25,25,25,27,25,25,26,26,23,53,101,142,163,141,139,144,162,148,56,16,10,13,26,22,17,23,24,19,28,24,21,26,22,67,144,155,157,164,169,170,180,162,70,16,9,14,14,13,18,16,19,16,21,21,16,16,14,19,19,17,16,20,24,31,28,29,29,31,31,29,39,36,39,43,44,53,53,60,66,66,72,74,76,73,69,72,68,64,69,71,71,72,70,74,78,114,77,91,84,71,69,57,64,74,91,98,101,110,107,113,130,151,175,153,153,119,36,27,46,70,83,70,54,50,37,17,148,242,226,234,218,223,220,219,223,219,220,217,215,216,217,217,219,217,219,219,217,220,219,221,220,219,220,220,219,220,221,221,220,219,219,222,223,224,222,222,119,5,1,7,10,12,10,12,12,13,13,13,13,205,205,203,205,203,202,201,201,203,204,205,202,200,201,202,200,199,199,200,200,201,202,201,203,201,199,199,199,199,198,198,196,198,196,196,195,195,196,192,193,193,193,194,193,193,193,193,194,191,195,195,193,195,195,193,192,196,194,193,193,195,193,193,194,195,193,192,196,197,194,196,196,193,198,195,194,196,195,198,198,199,199,198,199,199,199,198,198,200,201,199,200,201,200,200,198,201,199,200,201,201,202,199,203,200,200,202,199,201,200,202,202,202,200,202,202,201,202,201,202,205,205,205,205,206,205,204,205,204,205,204,207,207,205,207,205,210,208,208,208,209,212,209,210,212,211,211,208,212,211,211,213,211,212,212,212,212,211,213,208,210,208,204,203,202,204,201,202,203,204,205,204,206,209,209,210,207,208,208,208,210,209,211,210,211,210,211,210,209,210,208,212,210,208,213,211,213,214,213,212,212,211,212,211,210,211,210,211,213,210,210,214,212,212,212,212,212,210,212,212,211,212,211,213,213,214,214,211,212,212,212,212,211,212,210,210,212,211,209,211,212,207,209,208,206,208,208,208,209,210,210,207,208,208,210,208,211,212,206,209,205,204,207,206,205,209,207,200,205,208,206,205,205,203,202,201,199,199,196,193,195,200,203,186,187,201,199,197,198,198,200,190,194,199,193,198,196,198,197,186,188,196,196,194,195,193,194,196,194,195,197,194,193,188,203,160,171,195,186,200,151,192,207,177,184,154,141,139,141,129,113,62,46,55,105,188,207,237,218,171,186,208,177,144,194,208,181,208,214,161,118,149,199,142,196,161,90,117,87,94,89,61,51,164,242,233,177,156,154,160,214,216,216,213,199,225,191,134,206,182,130,139,174,232,244,237,169,88,56,41,54,46,12,20,18,16,22,19,18,18,21,24,19,19,21,21,21,18,19,15,14,15,17,18,23,29,46,41,38,65,71,79,72,61,54,26,19,41,48,59,69,95,117,117,120,93,98,89,55,95,118,103,125,120,124,134,65,58,56,51,87,134,132,76,88,143,146,71,111,132,53,22,24,39,76,120,92,89,92,46,32,27,25,28,28,32,22,16,15,18,19,14,17,21,15,16,14,15,18,19,16,16,16,22,14,22,20,89,136,139,156,160,165,174,190,80,10,15,8,15,13,15,18,15,17,16,18,18,19,21,20,17,18,15,25,19,74,171,130,135,124,107,117,116,114,42,18,15,15,24,24,26,29,29,28,29,28,32,29,22,52,78,141,174,141,148,139,155,168,75,17,13,11,24,20,16,22,28,29,24,22,25,28,29,72,143,151,150,165,158,163,176,194,108,24,14,11,14,17,18,16,17,18,21,17,16,16,15,16,17,19,19,20,31,50,47,44,43,34,33,35,29,19,19,19,22,22,29,28,34,37,36,49,47,55,57,58,65,63,74,77,79,79,80,73,71,73,66,70,62,65,73,84,80,73,50,38,39,40,53,58,63,56,43,24,40,43,29,37,47,66,71,63,50,59,22,52,231,250,232,232,219,224,218,219,222,218,220,219,218,218,221,220,220,220,218,220,220,220,220,220,222,221,220,219,220,219,220,220,219,220,221,222,222,221,221,223,118,5,0,6,10,11,11,13,12,13,13,14,14,203,210,204,204,205,202,205,202,204,203,205,202,204,205,201,203,202,201,202,202,203,204,201,200,203,200,201,200,199,201,197,198,198,199,198,198,198,194,196,198,197,196,194,194,196,195,194,196,194,191,193,196,196,193,195,196,195,196,195,195,196,197,195,198,194,196,199,194,197,197,198,198,197,199,198,194,198,196,198,200,199,199,200,200,200,200,199,199,199,200,199,201,200,200,200,200,201,199,198,200,200,200,203,203,201,203,203,203,200,201,205,203,202,202,204,204,205,206,203,204,204,205,205,207,206,203,205,203,207,206,205,203,204,206,206,204,206,206,208,208,208,211,208,207,209,212,210,211,211,211,210,211,210,209,214,208,211,212,209,212,209,208,206,202,202,203,205,206,206,203,204,204,207,209,209,212,209,207,209,208,207,208,210,210,210,210,211,210,209,208,210,212,211,209,210,210,210,211,211,210,211,211,213,211,211,212,212,212,210,212,211,212,212,210,212,212,210,211,208,211,212,211,210,212,213,211,211,212,211,210,211,211,212,210,210,211,210,208,208,209,209,207,211,211,207,209,208,208,208,207,210,211,209,210,213,210,214,222,215,208,208,208,209,207,203,207,202,199,206,207,207,206,204,206,203,205,204,204,198,193,201,199,202,191,183,198,196,200,201,200,202,190,197,201,198,200,196,199,198,194,187,194,200,194,196,195,194,195,192,193,194,193,196,189,193,148,175,199,182,204,163,210,220,170,153,123,129,155,161,135,110,43,41,46,103,213,214,232,209,168,190,210,189,145,201,205,175,222,177,137,143,187,222,141,165,109,81,113,89,99,75,46,61,199,251,203,141,160,173,174,217,205,202,212,209,230,166,150,188,87,75,84,117,205,243,217,92,56,57,41,49,27,12,25,21,19,19,15,22,16,22,22,19,21,15,20,21,18,16,18,14,15,23,23,21,39,45,36,61,70,74,66,60,54,31,12,63,111,103,98,97,103,112,120,103,90,118,135,123,118,93,81,110,123,121,119,69,73,93,88,87,90,124,117,88,147,167,87,94,149,103,45,42,63,132,147,93,92,87,43,44,42,43,49,57,57,21,12,15,13,17,16,18,15,19,17,17,19,17,16,17,19,19,16,21,23,29,160,208,192,208,197,199,194,227,120,7,11,11,15,18,19,16,18,17,17,19,20,23,16,27,26,19,22,27,19,81,134,81,62,54,51,53,52,60,36,24,14,21,24,23,27,28,28,28,31,34,28,28,31,59,87,142,173,131,149,140,147,174,86,22,15,12,22,23,23,29,27,29,30,17,28,26,29,87,134,132,122,123,130,130,148,173,112,32,13,10,16,24,17,19,18,15,18,15,20,21,19,18,17,19,17,20,40,84,92,81,73,67,63,59,43,21,16,15,15,18,18,18,19,21,23,22,24,27,29,32,33,39,38,44,53,49,57,63,64,66,69,74,89,99,108,128,128,104,72,42,24,32,42,61,77,60,46,40,46,44,44,57,75,75,65,69,71,54,22,143,238,248,231,227,221,223,216,217,217,217,220,217,217,221,220,218,220,216,218,217,217,218,215,217,219,219,217,220,221,220,219,219,220,220,217,220,218,223,217,218,120,5,1,6,10,11,10,12,11,12,14,13,13,206,205,205,205,203,202,203,203,205,206,203,204,202,203,204,200,203,203,200,200,200,200,200,201,199,198,199,201,202,200,200,198,200,199,198,200,199,199,198,199,198,196,197,199,198,198,198,198,194,198,197,197,199,198,198,197,197,199,200,199,199,199,201,199,196,197,196,198,197,198,201,199,198,201,198,199,200,199,200,200,199,200,198,200,201,201,202,201,200,201,201,202,203,200,201,201,204,203,200,202,204,200,201,203,202,203,204,204,204,200,203,202,201,203,203,203,203,203,205,204,203,204,205,205,204,208,206,205,206,207,208,207,204,203,207,204,206,207,205,207,206,207,208,206,209,208,209,210,208,212,208,208,205,207,210,210,211,208,212,211,208,209,208,208,205,203,204,204,205,205,206,205,206,207,208,209,208,209,208,208,208,209,210,210,209,208,211,209,207,210,210,211,210,211,212,209,209,207,211,210,211,211,210,211,212,213,213,212,214,214,212,212,212,214,212,211,213,212,210,212,212,213,212,212,208,211,213,213,213,210,211,210,211,211,210,209,211,209,208,208,208,207,210,210,210,210,209,205,209,208,207,209,205,208,216,204,203,222,218,208,206,206,207,206,205,206,201,201,207,205,208,204,205,209,209,208,210,206,200,203,206,205,206,198,186,202,204,201,205,203,207,196,199,208,205,206,203,202,203,201,189,191,200,198,200,198,196,197,195,193,194,198,195,199,185,138,188,198,189,204,162,208,173,142,168,149,164,190,195,159,101,49,44,35,105,189,195,225,200,171,198,188,125,112,165,176,185,201,155,160,176,224,173,85,175,131,93,101,71,92,55,41,56,190,207,150,154,179,197,184,228,212,201,198,200,227,144,164,178,75,73,61,79,165,235,190,49,42,64,46,33,14,19,27,21,17,22,20,17,22,22,21,20,20,19,21,19,21,17,15,17,16,24,24,37,46,39,48,63,77,66,60,63,26,26,62,144,208,142,115,110,109,121,100,105,104,153,201,171,109,37,73,117,103,115,109,90,107,74,66,72,51,95,130,146,164,176,94,76,148,130,81,27,63,157,132,87,99,71,42,62,66,85,106,132,106,31,13,15,12,23,19,15,17,17,19,16,18,21,15,22,15,23,25,20,27,39,177,194,172,186,161,166,166,200,95,9,16,7,16,21,16,19,19,23,23,21,26,25,23,28,30,23,27,22,34,96,113,60,46,43,36,39,45,46,25,22,18,20,24,24,28,26,24,30,34,35,36,32,27,51,70,124,141,113,134,128,137,159,79,24,16,10,22,23,29,26,29,30,24,29,31,27,36,98,139,97,63,64,66,86,85,112,83,29,17,12,20,17,21,17,17,22,16,21,19,16,21,23,22,21,19,18,48,147,181,156,153,141,133,126,88,41,19,14,15,16,18,19,17,18,20,19,19,22,19,19,23,18,23,21,23,32,29,35,39,37,40,44,52,45,67,116,129,117,93,120,138,147,148,116,92,75,74,61,57,60,87,111,112,100,95,118,107,90,78,165,238,231,225,230,217,223,219,222,218,214,219,218,218,216,219,217,217,220,215,215,216,217,216,216,218,217,218,217,217,216,217,220,220,218,218,218,219,220,218,220,118,5,1,6,10,10,10,13,12,12,13,13,13,202,206,203,204,206,202,202,203,204,203,205,201,205,203,199,202,200,200,199,200,199,198,201,200,199,197,201,201,200,201,198,197,199,201,202,201,200,200,198,196,198,196,198,198,198,198,196,198,198,196,197,198,198,198,198,197,198,198,198,198,199,199,199,199,199,201,198,197,199,198,199,198,198,199,198,196,200,199,200,200,198,199,200,201,198,199,200,201,201,200,201,203,202,204,201,201,202,200,201,201,203,201,201,203,200,203,204,203,201,202,200,201,202,200,202,203,205,203,201,204,203,204,203,204,207,203,207,204,205,208,203,206,206,206,207,205,206,204,206,205,205,210,206,208,208,207,208,207,210,211,208,207,204,203,208,208,209,208,209,212,208,206,208,205,203,206,203,204,206,208,209,207,207,208,212,209,207,206,205,207,207,210,208,210,210,210,209,208,209,210,208,210,212,208,208,210,207,208,207,207,211,208,210,211,209,209,212,211,212,212,211,212,212,211,214,210,209,213,210,211,210,209,208,209,211,209,210,209,212,211,210,210,209,209,208,208,210,208,210,211,208,208,208,210,208,209,205,206,208,206,207,206,207,205,207,173,133,170,202,206,207,203,206,205,208,208,198,205,206,204,207,204,205,206,205,207,207,205,202,207,211,210,210,205,191,201,210,207,209,206,210,199,199,210,208,210,206,209,207,207,197,192,204,203,202,200,199,202,200,198,197,200,198,208,184,141,198,208,184,181,131,150,102,98,170,168,176,184,185,146,101,51,53,37,90,177,180,222,203,173,205,163,89,121,99,147,202,201,156,178,190,202,129,89,198,167,115,98,82,91,60,49,57,165,194,174,179,210,195,178,230,215,219,205,201,206,132,192,149,46,116,83,83,165,229,162,39,59,47,24,23,14,19,16,23,23,22,23,20,23,18,21,23,17,18,19,19,17,19,19,18,21,28,33,42,41,53,63,64,63,64,59,36,12,48,125,178,188,101,90,117,113,111,92,99,115,147,183,181,114,42,63,114,131,113,120,123,108,101,74,64,42,50,118,165,198,152,62,57,149,151,71,6,44,153,121,91,98,79,76,126,144,171,173,196,174,44,9,9,14,23,16,19,18,19,21,17,20,19,16,23,22,22,21,24,19,55,171,135,102,102,80,87,79,122,57,19,20,9,21,24,24,18,21,27,26,28,27,20,27,34,27,25,30,29,37,96,97,53,50,42,41,45,46,42,27,19,22,24,28,29,24,31,39,39,41,42,38,27,26,48,52,93,107,69,85,80,83,101,60,29,19,15,28,29,31,34,31,33,31,24,30,24,47,115,120,78,47,48,45,51,56,62,55,29,17,16,19,23,22,22,17,21,21,21,25,22,22,15,21,18,22,19,46,154,190,179,182,184,189,189,170,94,27,14,17,21,17,21,19,17,19,19,24,22,20,22,21,21,19,21,16,24,36,39,39,33,38,29,34,29,46,97,113,105,172,251,251,245,177,85,42,29,32,66,79,90,101,97,106,96,101,122,135,128,81,130,211,216,233,226,216,222,217,221,221,219,217,216,218,217,215,217,218,216,218,215,214,217,217,217,216,217,218,214,214,217,217,216,216,217,217,218,216,223,217,218,120,4,0,5,10,12,10,13,12,13,13,13,13,202,204,202,203,206,203,203,207,203,203,203,203,204,203,203,200,201,202,200,201,200,200,200,200,199,200,201,199,199,201,199,199,198,199,198,196,199,198,198,197,199,199,198,199,194,199,200,198,198,198,197,198,199,200,201,200,200,200,200,199,199,196,199,200,199,199,199,200,198,200,200,200,200,202,202,200,200,199,199,200,200,200,199,200,201,201,199,202,199,201,202,199,201,201,203,200,202,201,199,202,201,201,203,202,200,204,204,203,201,200,201,201,205,202,202,203,204,204,202,204,203,204,205,205,201,203,204,205,206,206,204,209,209,205,208,205,205,206,205,205,206,205,210,208,208,208,208,212,210,212,207,206,207,206,207,204,207,208,208,210,207,208,206,205,204,205,204,205,208,207,208,207,209,208,207,206,204,205,206,206,207,208,207,208,208,208,210,208,209,213,210,211,211,208,207,209,208,208,211,209,209,211,210,211,211,208,211,211,211,208,210,212,210,211,211,211,211,211,212,213,210,209,210,210,208,211,210,209,210,209,212,210,210,211,208,210,211,210,208,210,210,207,208,207,208,208,207,207,208,208,203,205,208,207,207,162,105,141,195,206,210,205,205,205,205,205,200,203,203,205,206,204,205,204,204,206,206,199,204,207,207,211,210,210,194,199,211,205,210,208,208,200,199,210,206,210,207,208,210,207,205,195,203,207,207,207,202,206,205,203,202,203,201,212,184,151,206,214,187,160,87,120,78,78,141,127,146,155,149,121,91,50,44,33,98,182,182,223,201,185,212,174,148,152,86,124,224,196,167,146,160,203,150,126,214,156,100,110,98,94,63,60,62,178,213,202,193,217,187,179,232,208,221,213,229,193,122,207,143,49,88,71,91,181,230,165,73,68,32,11,22,14,19,14,20,24,21,21,22,21,22,22,22,18,16,19,16,20,22,19,21,27,33,39,43,52,71,72,63,59,62,34,26,7,63,106,103,118,47,83,110,96,108,93,104,100,93,119,168,154,83,76,97,120,119,123,132,124,106,68,44,30,41,49,95,108,69,26,62,171,118,49,4,54,159,110,103,104,105,141,167,179,193,175,196,170,41,7,8,13,24,15,21,23,24,19,21,24,22,20,31,29,28,25,29,23,71,140,74,47,57,41,50,47,56,36,24,22,16,22,23,25,28,26,24,27,26,27,24,25,37,34,22,33,27,44,105,93,66,66,60,62,68,71,62,35,35,41,40,49,53,52,50,66,66,61,59,56,54,55,64,63,108,76,38,49,39,46,52,41,24,20,22,31,26,33,37,36,29,34,32,27,33,53,117,113,63,47,44,37,45,41,52,38,20,25,18,23,24,26,27,27,23,18,26,26,27,19,18,24,24,22,21,54,133,174,154,166,174,181,185,196,146,39,14,16,15,20,18,24,21,20,26,21,22,24,23,23,23,17,22,23,24,44,71,77,62,63,59,60,40,50,102,110,111,208,249,249,224,114,49,28,11,74,123,97,71,48,53,72,82,86,116,119,117,59,73,218,232,232,226,215,225,217,219,218,218,217,219,217,215,218,217,217,215,214,216,214,217,214,214,217,213,216,217,217,218,217,215,214,215,218,219,219,222,217,218,117,5,0,6,10,11,10,13,12,12,13,14,13,202,205,203,202,205,200,201,203,200,202,202,200,202,200,200,201,201,201,200,202,200,198,199,199,202,201,199,198,198,196,198,200,198,196,194,195,198,198,194,198,199,197,198,198,198,194,196,198,198,198,198,199,200,199,200,198,200,201,201,201,198,200,198,197,200,201,200,200,200,199,199,199,201,200,201,199,201,203,200,200,203,203,200,203,200,200,202,199,200,200,198,199,199,198,199,199,202,199,200,201,202,201,199,202,200,200,202,201,203,203,200,203,203,202,204,203,204,201,205,209,203,206,205,202,204,205,206,202,205,206,202,206,204,204,205,205,205,202,205,204,203,206,205,207,208,207,204,205,208,207,208,206,207,207,206,207,208,206,209,208,206,207,206,204,205,206,207,207,206,205,205,207,206,204,203,202,203,204,204,206,206,208,207,209,209,208,208,208,209,210,210,210,210,208,208,209,207,208,208,206,209,208,207,210,210,210,212,208,209,209,209,211,210,210,210,208,211,211,211,214,212,211,210,210,210,207,209,210,210,209,211,211,210,211,207,208,211,208,209,209,208,208,205,207,205,205,206,207,207,205,206,205,205,206,212,202,177,185,205,205,206,206,204,203,204,200,197,203,204,204,205,204,203,205,206,207,201,200,206,211,208,209,210,211,198,197,211,207,211,208,212,202,199,211,207,211,207,207,207,209,207,198,200,208,211,208,208,207,208,206,206,206,205,220,178,156,208,213,183,154,117,158,118,101,144,143,165,167,161,130,93,49,52,43,122,210,186,224,200,184,217,198,219,198,101,128,200,183,145,141,181,206,164,128,197,153,103,120,96,86,79,42,42,152,210,176,163,221,174,189,229,206,225,210,231,172,138,232,170,111,125,54,103,226,250,174,65,46,10,15,22,16,21,16,23,28,20,21,22,16,19,23,19,16,19,16,15,19,21,27,27,32,48,37,43,69,76,76,60,61,42,18,15,30,100,74,53,82,62,87,86,95,103,93,112,104,80,87,153,182,153,101,76,93,85,104,115,107,95,58,39,33,37,29,27,45,39,45,123,128,57,29,4,70,150,89,101,97,95,118,118,127,132,117,138,106,27,22,13,13,25,24,30,22,26,31,23,20,29,29,29,36,31,24,31,27,87,123,54,49,53,40,50,42,53,28,21,29,16,23,22,23,26,27,28,34,35,34,34,50,56,52,57,67,65,79,150,157,137,138,133,144,149,161,127,126,144,152,173,132,164,169,174,183,178,179,173,174,168,172,168,156,153,72,45,47,38,46,45,49,40,42,42,46,49,45,47,42,45,33,29,35,33,59,112,120,89,63,57,57,50,53,59,36,20,20,17,27,23,27,29,30,27,24,33,22,21,24,24,21,22,25,25,63,131,144,111,110,122,130,137,160,123,52,16,11,13,19,21,23,21,21,26,23,24,22,23,26,22,18,21,24,22,64,152,164,149,134,125,122,93,116,121,101,95,184,249,177,95,37,32,23,75,142,120,76,66,55,42,75,86,72,79,85,90,56,122,237,247,243,242,231,232,221,219,215,217,217,214,214,217,217,217,216,215,216,214,214,216,214,213,214,212,215,214,215,216,214,217,216,217,218,219,217,219,216,220,120,4,0,6,9,10,10,13,12,12,13,12,12,202,205,203,204,203,199,201,202,200,200,203,200,201,200,202,201,202,200,198,198,199,201,200,199,199,197,198,198,197,199,199,198,197,198,197,198,195,198,201,195,200,195,196,200,196,198,196,196,198,199,201,200,197,198,198,199,199,197,200,199,201,199,199,200,199,198,200,202,199,199,198,199,199,200,199,199,200,199,201,199,199,198,200,202,200,199,201,200,200,203,201,200,200,198,201,199,201,200,200,202,200,199,200,203,201,202,202,203,201,201,202,200,203,202,204,204,203,202,203,205,202,203,204,205,203,204,203,203,204,206,204,203,203,202,205,203,203,203,202,204,205,204,206,204,205,206,206,205,206,208,207,210,207,207,206,204,207,207,205,206,207,208,205,206,207,206,208,209,208,207,206,207,207,205,205,204,203,204,204,206,208,208,208,208,208,208,208,209,209,210,208,208,211,208,208,209,206,208,208,208,208,209,208,208,211,208,209,208,210,208,212,211,210,213,208,209,211,209,212,211,209,211,208,210,208,207,210,209,211,208,208,210,208,208,208,207,208,207,207,209,209,209,210,208,206,208,205,203,203,204,206,205,205,210,213,215,213,213,212,208,208,206,208,204,203,198,201,206,202,204,206,206,205,209,206,202,199,202,210,207,208,210,207,210,200,194,209,205,207,207,211,206,198,210,210,210,207,206,209,209,211,201,196,205,211,208,210,210,210,208,210,208,210,217,174,174,215,198,170,185,159,204,163,145,198,189,208,189,194,163,99,51,52,51,134,226,191,219,197,193,212,198,237,216,114,137,157,137,166,181,203,205,141,138,225,144,103,118,93,97,70,40,21,106,176,154,174,217,163,197,223,206,214,213,222,141,159,250,194,120,113,98,178,250,226,120,51,19,8,22,22,12,23,15,24,28,23,26,19,21,20,20,19,17,17,16,16,21,21,21,30,45,42,47,66,76,72,62,61,43,23,17,15,69,113,41,63,109,78,85,71,95,109,103,111,113,105,83,133,191,188,153,90,79,86,113,108,71,75,58,34,24,27,24,27,29,40,135,151,71,18,24,9,69,119,73,106,80,53,53,45,52,46,48,61,51,25,19,15,23,29,28,27,31,31,30,31,27,30,39,37,30,31,29,31,35,107,110,49,63,54,49,59,60,56,29,30,35,37,49,50,59,66,73,82,92,118,131,149,178,182,188,199,216,203,198,204,184,185,181,171,170,160,162,171,177,183,193,193,184,177,170,173,177,175,177,173,176,176,164,155,151,142,103,95,81,77,95,98,98,116,131,151,168,152,157,145,132,122,98,77,73,61,79,157,173,148,133,124,122,120,112,92,39,13,22,17,24,30,23,30,35,29,33,27,26,35,24,25,25,26,27,22,74,124,122,67,45,47,57,69,85,86,45,26,12,17,22,18,23,22,23,21,22,20,24,21,25,24,24,22,19,25,93,203,221,211,206,211,205,186,184,147,105,81,164,199,71,17,29,20,54,132,142,67,66,118,89,89,97,83,70,54,56,79,55,104,225,244,244,250,246,241,226,223,216,217,214,214,214,215,216,213,214,213,215,215,212,214,212,214,214,211,214,212,215,214,214,216,216,215,213,216,217,216,214,218,118,4,1,6,9,10,10,13,12,11,13,13,13,200,200,200,199,203,199,200,201,199,202,201,200,200,200,200,200,199,198,199,200,198,199,200,197,198,198,198,197,199,199,200,199,197,197,198,198,196,200,194,196,198,195,197,195,197,195,198,199,198,199,199,199,201,201,198,199,201,200,200,200,199,199,200,201,202,198,198,199,199,198,200,200,199,198,199,199,199,201,200,200,201,201,201,200,198,199,200,200,200,202,201,202,201,199,203,200,202,200,199,201,199,201,200,202,202,200,203,201,202,203,199,203,203,201,203,203,206,201,200,202,200,204,203,203,203,203,205,204,205,203,201,205,201,203,205,205,205,203,204,204,203,202,205,202,203,205,203,206,207,206,208,207,208,208,204,205,205,203,206,208,205,208,207,207,208,207,207,207,208,208,208,207,205,206,205,205,205,205,205,205,208,209,207,207,210,208,208,208,206,208,208,208,208,206,207,208,209,207,208,208,208,209,207,210,210,208,209,210,209,209,208,211,208,210,211,212,212,209,210,211,209,209,208,206,206,207,210,208,209,209,208,208,209,211,207,206,207,207,207,207,208,208,206,207,208,207,207,205,205,206,204,205,206,204,206,211,209,203,207,208,204,205,205,206,203,198,203,205,207,206,206,206,206,208,206,203,200,206,209,207,205,208,207,212,204,190,205,205,207,206,208,203,196,211,207,209,209,206,209,209,211,206,197,200,211,210,208,209,210,208,212,208,213,214,166,188,224,199,184,194,190,208,175,173,195,179,184,172,206,175,100,54,41,38,141,231,193,214,190,191,207,196,232,204,144,136,141,164,179,201,183,169,140,171,234,137,105,98,77,90,72,38,27,111,191,170,202,221,157,206,213,204,211,214,200,124,178,244,188,121,91,67,162,206,136,70,18,12,13,22,21,17,27,22,18,24,23,22,18,19,22,20,20,15,17,18,21,22,21,31,44,40,48,62,77,78,57,61,39,24,15,21,29,92,108,27,85,118,91,92,87,122,120,104,108,117,119,105,133,165,185,167,129,101,85,99,76,67,80,53,30,19,26,30,42,50,119,164,82,38,15,20,7,75,104,74,106,74,41,43,40,43,45,42,50,35,16,25,17,22,29,28,33,31,33,28,31,32,30,37,38,38,32,36,35,42,136,136,95,126,76,91,105,106,91,73,106,129,128,182,191,201,206,206,214,214,208,203,200,202,198,196,193,183,162,149,125,98,122,87,78,73,61,71,61,71,70,130,126,63,64,61,60,63,56,62,59,60,65,55,59,67,62,67,77,67,71,81,89,85,112,128,146,125,173,179,184,179,175,178,187,177,169,112,184,184,167,159,160,161,155,166,134,73,33,35,30,37,32,31,29,31,32,35,35,31,39,29,29,37,37,33,29,93,124,97,49,37,47,41,48,54,56,37,23,17,17,23,29,22,23,25,20,27,22,26,24,21,20,27,23,21,24,71,169,188,190,196,194,199,188,194,146,107,89,136,141,27,27,34,12,71,137,117,46,67,128,111,125,111,77,69,57,47,51,39,32,152,221,220,227,220,239,232,222,217,217,214,215,214,213,216,214,215,213,213,213,214,213,213,214,212,213,214,215,214,214,214,214,214,214,214,215,215,219,213,217,119,5,0,5,9,11,10,12,12,12,12,13,13,203,203,201,201,200,198,202,201,200,202,203,200,200,200,199,198,200,198,199,200,197,199,197,198,198,197,201,196,195,199,196,198,195,198,198,199,195,195,202,197,201,199,197,200,197,199,199,198,201,197,199,201,199,202,201,199,201,200,200,200,200,198,199,200,199,200,200,201,201,199,199,201,202,201,198,199,201,200,200,200,202,201,200,201,199,200,199,201,200,200,199,198,203,199,202,199,199,200,200,201,200,201,200,199,201,201,200,202,203,204,203,205,206,203,203,203,204,202,202,204,201,201,202,204,202,203,205,202,203,202,203,204,204,202,202,205,204,204,205,204,204,202,204,203,206,203,205,206,204,206,206,208,204,204,204,204,205,204,203,205,203,206,207,206,208,208,206,204,206,206,206,206,203,203,202,201,205,205,205,204,207,210,209,208,208,209,206,206,206,208,207,207,210,208,207,208,208,208,206,206,207,207,207,210,209,206,209,208,208,207,207,207,206,208,208,211,209,208,212,208,208,208,205,209,208,208,207,206,207,207,207,209,208,206,205,206,210,209,206,206,207,206,205,207,203,206,207,205,206,205,206,206,204,205,203,205,207,202,204,203,202,202,207,207,200,199,206,205,206,209,206,206,204,208,205,201,205,209,210,210,207,206,208,210,208,191,204,208,204,206,208,205,196,205,208,209,209,207,205,205,208,211,202,196,209,212,209,208,208,206,210,206,215,210,162,201,229,198,193,205,181,177,147,136,143,134,143,162,219,174,92,51,39,43,134,233,195,201,184,194,202,203,214,201,200,174,181,196,190,171,147,174,121,171,230,141,107,77,75,98,73,48,53,169,222,187,220,208,155,206,208,207,205,218,172,124,199,234,186,127,115,51,64,97,48,37,16,9,14,16,27,21,22,17,20,24,23,25,16,17,21,14,19,17,15,21,18,20,24,47,44,40,67,75,72,65,60,42,28,31,48,66,78,139,109,71,127,122,129,119,93,123,126,121,107,115,118,109,126,136,150,145,112,81,59,55,53,38,52,37,24,31,39,59,101,139,112,60,24,21,20,15,16,91,92,81,117,72,51,44,46,55,59,58,51,28,16,24,19,28,33,29,40,46,44,48,50,55,64,69,74,81,84,84,96,128,185,183,177,190,168,178,182,184,184,169,176,179,189,196,182,181,159,141,141,121,103,88,77,75,66,61,60,57,57,66,59,59,65,61,59,59,66,69,73,80,78,77,69,64,74,75,75,70,69,71,66,65,65,60,65,71,68,74,79,68,64,66,64,62,60,60,58,56,56,63,66,67,77,96,113,125,120,117,125,118,113,113,115,122,123,143,145,113,125,131,111,93,71,60,51,47,52,49,47,45,40,42,34,34,36,33,35,90,117,92,63,49,48,46,49,53,54,35,23,22,26,25,24,29,24,22,24,26,27,27,26,24,25,25,19,22,27,66,125,134,130,126,132,130,128,137,118,104,83,121,101,33,33,26,11,82,137,103,54,54,84,98,121,99,78,65,46,49,61,44,37,103,108,99,128,165,214,234,224,215,216,217,219,217,215,214,213,214,212,215,214,214,214,214,214,213,215,215,214,214,213,216,214,213,213,213,217,216,218,214,217,117,5,1,6,10,11,10,13,12,13,13,13,13,202,205,203,201,203,201,200,200,199,198,198,199,200,200,198,200,200,199,200,199,196,199,198,198,200,196,196,196,198,197,198,197,197,199,199,198,196,197,199,198,199,197,201,201,200,197,201,200,196,200,200,200,199,201,200,200,200,196,199,199,198,199,200,198,199,201,201,202,200,199,201,201,199,198,198,200,198,200,199,198,199,200,201,200,202,199,200,200,198,198,199,200,199,199,200,200,199,200,201,201,199,200,202,197,199,201,203,201,204,203,202,205,201,202,205,203,204,201,203,203,203,205,204,205,204,202,202,203,202,202,204,204,203,205,201,203,203,200,204,203,205,201,206,203,201,206,203,205,202,203,206,205,205,205,203,203,206,203,203,206,206,206,205,207,205,205,205,203,205,204,206,205,205,204,203,204,202,205,207,205,206,204,207,207,207,206,206,207,204,207,207,206,207,207,208,207,206,205,207,207,205,208,208,206,205,206,208,207,208,208,205,208,207,209,206,208,210,207,210,210,208,209,208,206,209,208,207,207,207,205,205,207,205,206,205,203,206,207,206,206,206,206,204,206,204,202,206,204,205,205,202,204,203,202,203,202,205,205,206,206,203,202,205,203,199,200,203,205,205,204,203,206,209,207,200,201,206,206,208,208,206,207,204,206,207,190,198,205,206,206,207,205,195,208,208,207,208,207,208,204,207,209,204,195,202,211,208,209,210,205,209,207,217,201,162,213,227,181,163,154,150,118,95,127,147,163,164,198,240,179,97,44,22,36,142,240,208,207,189,210,218,220,193,189,225,179,199,184,170,175,170,183,107,146,196,139,108,84,91,98,67,46,63,177,218,193,223,190,159,210,202,205,206,214,145,140,211,221,179,90,81,65,83,54,22,33,10,17,16,22,28,21,23,24,18,22,26,17,22,21,15,14,19,16,16,22,20,30,42,42,42,52,69,68,57,71,63,45,68,110,133,146,141,158,139,117,130,106,108,95,81,103,119,130,108,110,92,67,81,75,100,102,81,53,38,43,37,35,27,25,40,55,83,134,124,73,39,18,20,15,16,11,31,110,90,92,121,66,56,54,61,89,91,100,76,35,42,54,63,72,77,87,125,133,156,162,180,190,200,208,198,194,188,186,162,168,181,152,156,132,138,128,116,115,103,83,74,71,127,72,65,65,62,57,67,64,69,70,70,76,65,70,71,70,70,71,77,72,63,56,62,60,55,61,61,59,57,51,45,43,47,49,48,49,41,50,38,44,49,45,48,50,53,53,58,55,61,58,53,59,58,57,51,53,57,59,57,56,57,54,63,61,59,57,55,63,65,57,59,67,72,85,99,96,156,167,168,172,155,142,139,139,137,133,113,95,83,67,62,53,53,45,40,96,141,146,109,93,80,66,74,74,65,37,23,19,25,29,31,32,29,29,23,30,28,24,27,27,24,24,24,25,29,70,107,87,62,53,54,53,53,55,66,96,95,111,92,41,27,19,20,71,139,113,76,45,41,51,68,68,61,53,46,61,71,69,59,73,55,34,61,87,154,213,219,220,218,217,217,213,216,214,214,214,213,212,210,211,212,213,214,212,215,212,212,213,212,214,213,213,213,214,216,214,217,215,217,120,6,1,7,10,11,10,13,12,12,14,13,13,200,200,201,200,200,199,200,198,198,200,199,200,199,199,199,198,201,198,195,196,197,198,196,198,197,194,197,195,198,198,196,200,197,198,198,195,197,196,198,195,198,200,198,200,198,199,200,199,199,199,197,197,196,199,201,198,200,196,198,201,200,200,199,199,200,200,200,200,200,199,199,200,198,199,198,197,199,200,200,200,199,199,199,199,199,200,199,199,199,199,200,198,200,200,201,200,202,200,199,204,200,200,201,202,202,200,200,201,201,201,202,200,202,203,202,202,202,203,203,203,203,205,202,203,201,202,206,204,204,202,206,204,204,205,202,203,204,203,204,205,205,203,203,204,204,201,204,202,203,204,203,203,205,204,203,206,203,203,205,205,206,205,207,205,205,205,202,204,207,206,205,207,204,205,205,203,205,206,205,205,205,205,208,206,206,207,206,206,205,205,207,203,205,205,203,205,205,207,207,205,205,208,205,207,208,205,209,207,206,208,204,207,208,208,208,207,206,207,208,204,207,208,205,208,207,207,207,206,207,206,206,205,206,205,206,207,208,206,205,205,204,204,203,204,203,203,203,202,206,203,202,206,203,201,203,203,205,205,203,203,201,203,207,203,195,203,206,205,207,205,205,203,205,204,198,203,207,204,204,206,205,206,207,205,208,191,194,205,205,206,204,203,195,204,206,206,207,206,207,207,206,206,207,194,198,206,206,206,206,205,208,207,216,193,166,227,217,141,116,129,153,111,102,157,190,206,204,237,252,192,103,57,40,48,135,246,241,222,216,241,246,243,163,139,158,126,141,160,202,185,191,195,87,100,177,153,108,89,86,80,59,41,57,129,177,192,221,182,163,208,200,202,212,203,124,162,213,217,193,96,75,51,44,39,16,29,18,17,25,16,27,22,21,24,23,23,21,26,25,19,20,15,18,18,23,23,23,41,39,42,61,66,59,63,115,145,131,133,145,150,156,149,137,137,128,113,100,72,71,71,72,79,87,107,110,108,63,52,50,24,55,67,76,59,32,32,22,25,27,40,63,71,79,67,42,27,18,19,19,10,16,12,53,116,87,105,116,77,101,119,155,179,181,193,167,160,189,202,210,213,203,203,197,190,186,185,184,179,169,151,136,117,103,88,66,70,68,58,53,57,59,54,56,59,63,61,65,72,77,74,76,87,87,86,81,78,67,64,60,57,55,48,47,40,40,36,31,36,31,26,28,21,27,25,25,22,20,28,21,19,24,20,18,19,19,24,16,16,21,18,23,24,23,23,19,24,28,26,29,31,29,34,33,35,37,38,42,44,49,55,58,61,56,62,67,66,71,67,63,63,62,60,64,65,64,72,80,92,105,120,128,142,151,149,159,157,163,158,148,143,136,120,122,159,170,178,163,151,155,154,150,140,97,36,27,24,29,34,27,37,38,36,32,24,30,23,31,27,24,28,23,28,33,80,99,68,56,43,51,45,47,41,35,76,92,112,92,52,29,15,20,55,98,113,93,58,31,24,33,42,59,49,53,63,67,65,66,67,55,38,48,48,85,200,235,236,232,219,216,214,216,215,214,212,212,210,212,214,212,211,212,211,213,212,209,212,211,212,213,212,210,211,215,215,217,211,216,119,4,1,6,10,11,10,13,12,13,13,14,14,196,201,199,198,202,198,198,200,200,198,201,199,199,198,197,200,199,197,197,197,196,198,198,196,198,196,198,198,197,197,196,196,196,196,196,196,197,198,198,196,198,198,199,197,198,197,199,200,199,200,198,199,198,199,198,198,201,198,199,200,200,199,200,200,198,199,198,200,200,199,199,198,200,198,199,200,199,200,199,201,198,199,199,198,199,199,201,199,199,203,201,201,199,200,201,199,199,201,200,200,201,199,201,200,201,200,200,199,201,200,201,205,202,201,203,204,205,203,204,202,202,203,202,201,202,205,204,204,202,201,204,202,204,204,202,205,204,202,204,202,203,201,206,202,201,205,201,205,203,204,204,203,203,204,204,203,204,203,204,203,202,205,205,205,202,205,206,206,206,205,206,204,203,203,204,203,205,207,206,207,205,205,205,205,206,205,205,204,205,204,204,206,205,206,205,204,204,204,205,206,205,204,205,206,209,208,207,208,207,206,206,205,204,207,206,208,208,205,208,205,205,203,205,204,205,209,205,207,205,205,205,205,205,205,207,203,205,204,203,205,205,205,203,203,203,202,203,201,201,205,203,202,201,202,205,203,203,204,202,202,200,201,206,199,199,205,201,206,206,204,204,204,205,199,199,205,204,205,204,205,203,204,206,206,210,195,191,204,206,206,206,206,196,203,207,205,208,204,206,204,205,206,208,199,194,205,209,205,205,208,206,206,216,185,181,236,211,110,89,145,173,123,124,162,178,183,177,203,191,148,93,89,105,65,98,192,192,160,162,193,202,211,117,69,71,45,103,193,232,193,178,156,86,107,206,164,103,97,87,87,65,68,56,96,182,204,221,172,161,209,200,201,220,187,122,186,213,220,214,122,83,39,17,17,15,30,17,28,29,23,23,23,25,23,23,23,22,25,22,19,19,19,21,17,28,24,36,42,45,65,78,71,63,127,174,180,175,160,134,122,128,122,98,94,91,86,79,72,86,74,66,63,62,72,84,84,54,47,56,41,79,58,69,46,23,23,23,27,50,64,57,42,29,26,19,16,17,15,15,15,23,11,74,116,87,107,112,137,180,185,195,194,187,141,152,156,186,174,167,140,126,112,93,119,61,53,57,53,47,55,53,51,53,51,45,48,47,47,59,48,54,63,56,61,59,56,58,52,54,50,47,45,39,41,32,31,30,24,26,21,22,22,18,21,21,18,15,19,19,16,15,14,16,16,17,21,19,21,23,24,21,21,23,20,19,21,17,15,16,16,21,21,20,18,20,19,18,16,19,19,15,19,19,20,19,21,25,26,31,29,30,33,31,39,39,39,48,50,53,53,54,62,63,64,63,69,68,69,71,68,68,68,71,71,77,88,106,120,124,134,142,145,145,146,132,127,127,150,160,154,162,164,136,84,69,62,54,57,53,50,52,52,46,44,37,36,37,34,36,31,30,29,36,83,101,78,66,57,57,55,61,44,40,101,100,113,111,50,28,18,15,30,64,98,104,77,53,33,27,41,49,52,63,57,60,61,57,64,67,50,64,68,111,227,244,244,250,236,232,228,223,217,214,212,212,212,213,212,211,213,214,211,212,212,211,213,212,214,215,212,213,214,215,217,218,214,215,118,6,1,6,10,12,10,13,13,13,13,14,14,200,200,200,199,200,196,200,199,198,199,196,199,198,195,196,197,198,197,195,198,196,194,198,198,197,195,198,198,197,197,196,195,196,198,196,196,198,195,198,198,199,198,196,198,198,199,199,198,196,200,199,199,201,200,200,198,199,199,198,199,198,198,200,199,200,197,198,200,199,199,196,201,199,200,202,198,200,198,200,200,197,199,201,201,199,199,200,200,198,198,201,201,200,200,200,200,199,198,201,202,200,201,198,198,198,201,198,199,200,199,201,199,201,200,201,204,201,201,201,204,205,204,202,203,205,201,200,201,203,203,201,201,202,203,204,200,201,203,201,203,203,202,202,203,203,203,203,202,202,201,202,202,203,203,203,203,202,203,204,203,205,205,205,203,201,204,204,204,205,206,206,205,205,206,204,202,205,207,205,206,206,203,206,203,204,205,203,203,203,203,204,204,206,205,203,207,203,204,204,203,206,205,204,204,206,203,204,206,206,206,204,206,207,205,205,206,206,205,206,206,205,206,204,205,205,204,203,203,202,203,203,202,206,204,203,204,203,204,203,205,203,205,205,202,202,203,203,203,206,202,200,203,202,201,203,202,204,205,203,204,201,202,203,197,197,203,201,202,201,202,205,204,200,196,202,205,204,204,204,207,204,204,206,202,209,200,189,200,204,205,203,205,193,202,208,206,207,205,204,204,203,206,208,202,194,198,208,206,205,205,200,205,213,181,193,217,162,92,101,132,130,106,120,131,133,129,125,124,95,101,66,92,139,84,41,87,87,39,36,33,60,98,64,37,22,17,77,171,203,177,146,148,105,155,244,146,88,90,94,97,76,67,36,123,226,216,222,166,166,210,198,209,222,158,131,210,208,230,213,108,60,30,29,18,12,24,34,49,50,37,28,22,28,28,19,22,23,19,18,22,22,18,20,23,25,36,42,44,61,76,93,69,87,141,162,175,160,143,102,92,115,89,54,32,39,45,50,66,63,62,56,55,52,55,59,71,61,56,47,45,134,132,69,43,21,29,35,45,44,38,31,18,19,17,18,17,20,16,15,20,17,22,98,111,90,113,102,113,118,95,93,85,67,66,59,55,56,51,50,50,51,53,53,55,52,48,51,54,49,48,55,48,44,43,41,38,34,34,34,36,31,39,35,29,28,27,29,23,19,21,21,19,16,18,17,15,16,16,19,15,17,17,19,23,21,21,19,18,19,15,18,17,19,25,27,17,23,24,19,26,22,27,29,28,24,19,19,15,18,18,24,23,30,41,46,45,33,26,17,17,17,17,17,21,27,23,25,22,26,23,20,29,21,22,23,20,24,20,27,26,28,32,33,39,43,48,48,49,60,65,69,70,67,67,66,62,65,69,68,68,67,70,71,72,70,68,68,76,92,93,99,118,120,118,139,145,153,151,131,139,139,129,122,102,92,87,82,73,71,68,59,49,50,96,141,149,132,110,110,102,101,96,111,130,110,121,112,63,26,20,15,21,33,66,101,98,80,61,48,46,43,47,54,60,66,68,62,64,76,64,103,103,129,217,217,231,246,246,249,245,241,234,229,227,223,220,218,213,212,212,214,210,212,215,211,213,214,214,214,214,212,213,215,214,216,214,217,117,5,0,6,10,12,10,13,12,13,13,14,13,198,203,200,200,199,199,200,200,201,198,199,198,199,199,197,198,198,197,197,198,199,197,197,198,199,197,194,196,198,196,194,196,196,197,199,200,198,197,196,197,198,198,200,199,198,197,196,199,198,199,200,201,199,199,202,200,200,199,200,199,199,198,197,198,196,200,199,197,199,198,200,200,200,199,201,200,200,200,199,199,199,200,200,201,200,199,199,199,200,200,199,201,200,201,202,200,201,203,202,203,202,202,200,199,203,200,201,201,201,201,199,202,200,201,201,199,200,200,203,202,202,202,203,204,200,202,204,202,203,201,202,203,202,202,200,201,201,202,203,201,202,202,203,203,204,203,202,204,203,203,202,203,203,202,202,204,204,203,205,204,204,204,203,203,204,204,202,204,206,207,208,205,206,206,205,203,204,206,206,208,204,204,204,205,205,204,205,203,205,203,204,204,201,205,206,205,204,202,203,206,204,204,204,204,205,202,203,204,204,207,207,205,206,205,204,207,207,206,205,205,206,205,204,205,203,202,200,203,203,203,203,203,204,203,204,201,203,203,204,203,200,201,201,203,202,202,204,203,201,202,203,202,203,201,203,203,201,205,205,205,203,204,203,194,198,205,202,202,203,205,204,204,200,197,203,204,203,204,203,203,202,204,203,202,207,202,190,198,205,203,200,204,195,199,206,203,205,204,206,204,206,205,206,207,194,194,204,206,206,206,203,208,204,171,194,148,84,84,103,103,82,91,127,127,111,98,116,113,72,90,78,87,117,88,64,120,125,79,53,13,6,57,69,61,42,31,38,61,118,165,183,189,145,193,239,117,103,113,94,103,73,62,41,145,243,218,217,164,174,214,199,214,217,128,143,213,208,234,190,100,49,36,40,62,56,36,47,64,45,64,99,44,19,22,19,23,22,22,24,21,17,21,19,27,38,42,39,56,79,105,147,135,116,117,127,138,130,121,87,56,73,71,54,40,33,31,31,42,43,42,44,45,44,47,50,62,66,57,97,159,214,203,134,66,35,24,21,21,19,19,19,17,16,17,19,19,16,19,14,23,16,39,118,108,109,127,77,62,62,52,52,51,51,59,54,54,49,47,50,44,48,48,48,44,39,44,41,36,33,31,33,33,25,30,24,19,21,18,22,19,17,17,22,19,15,19,19,22,21,23,21,25,22,18,20,17,17,15,22,17,21,23,27,31,33,34,29,26,18,15,20,28,29,29,23,19,19,18,19,24,22,21,24,32,33,27,19,19,20,16,21,35,69,88,100,97,75,36,15,16,19,23,25,30,20,18,21,15,24,17,19,22,24,30,22,19,19,17,20,18,18,20,21,25,21,24,25,27,28,28,37,36,44,46,43,50,51,49,57,66,63,65,68,70,67,67,67,67,63,62,67,67,69,79,103,116,130,143,146,152,153,167,162,163,170,182,188,178,133,172,165,142,136,149,168,184,173,166,162,169,172,157,153,153,120,122,128,71,30,16,11,16,20,40,66,96,112,95,78,69,51,45,48,57,72,64,66,63,74,89,112,102,84,108,99,129,185,219,239,243,247,248,249,248,243,241,231,227,222,217,214,211,212,209,208,210,212,213,211,211,212,210,214,211,212,213,216,120,5,1,7,10,11,10,13,12,12,14,14,13,200,200,200,200,200,196,199,199,199,201,198,200,198,198,199,197,198,198,195,199,199,196,196,195,199,198,197,198,196,197,197,198,200,199,199,199,200,199,199,200,200,201,201,200,201,199,199,201,200,202,199,199,200,200,200,201,200,199,199,201,202,202,202,199,201,200,199,201,199,198,198,200,200,199,200,198,200,200,200,202,202,204,201,200,201,202,201,201,203,203,203,203,204,201,202,203,201,203,203,203,203,203,201,203,202,201,199,199,199,200,201,201,202,199,200,201,202,204,203,202,202,201,203,203,201,204,203,204,204,201,201,202,203,201,202,201,201,203,202,200,203,203,203,200,201,202,200,201,203,205,205,203,204,203,205,204,203,203,202,203,205,202,202,203,203,203,203,203,206,204,206,206,206,204,205,207,205,207,206,202,205,203,203,201,200,204,203,204,204,203,205,203,203,205,204,205,203,203,206,204,204,205,203,203,206,201,204,206,203,205,203,205,205,204,205,204,205,204,205,203,205,204,201,204,203,202,202,202,203,204,204,201,204,202,201,204,203,202,200,203,201,200,203,202,203,203,202,200,201,201,202,204,201,200,203,200,201,202,203,207,204,203,199,196,201,203,202,203,202,202,203,201,196,202,205,202,203,203,204,203,201,201,202,200,205,204,190,196,207,202,202,205,193,199,205,202,204,203,204,205,204,203,204,207,202,191,200,206,205,206,203,209,201,170,198,102,16,35,68,98,80,107,147,130,116,103,136,119,73,115,88,78,124,99,96,193,190,137,110,44,36,71,93,97,76,62,64,49,84,155,207,210,157,202,210,117,126,124,116,108,81,73,42,153,238,210,214,157,179,214,193,226,195,101,157,214,213,231,157,78,53,31,127,213,116,49,53,37,69,214,210,35,8,24,16,26,22,19,15,21,23,27,28,38,46,44,53,75,89,114,159,165,155,114,95,97,101,107,66,23,31,51,54,54,42,40,39,34,31,27,35,36,38,34,29,46,38,89,162,178,190,146,95,42,12,15,8,13,14,13,21,21,29,36,39,44,24,20,18,22,18,56,135,107,122,125,58,49,51,47,47,44,37,42,40,35,35,32,31,28,30,27,26,23,24,22,18,17,17,17,16,17,19,18,14,19,17,18,17,17,16,16,16,20,26,21,22,21,24,24,21,28,29,33,27,16,22,17,15,21,19,29,46,64,76,67,58,41,21,14,26,34,17,20,33,27,14,18,19,17,29,35,22,17,29,41,37,19,22,14,31,89,105,120,146,128,83,41,20,17,24,32,27,18,21,21,15,19,17,20,22,20,24,34,38,27,22,16,16,16,20,21,22,22,23,21,16,22,17,24,18,19,23,22,26,23,30,29,27,32,41,42,47,50,53,61,66,66,69,70,69,66,70,74,69,69,77,73,71,81,77,84,97,99,113,129,136,147,162,167,161,150,145,135,129,129,132,141,151,153,155,158,159,132,116,129,130,84,28,20,14,15,17,27,41,59,106,139,132,99,69,59,48,36,46,52,53,65,69,63,78,71,65,53,20,25,67,114,144,172,200,225,234,237,245,246,247,244,240,231,222,217,215,212,209,212,211,211,209,209,212,210,212,213,215,212,215,118,5,0,7,10,11,11,14,12,12,14,14,14,199,200,199,198,196,194,196,196,198,197,197,197,195,197,196,196,197,198,195,194,195,196,199,197,196,198,196,197,199,195,200,199,195,200,199,201,201,203,201,198,198,199,200,199,199,199,202,203,200,202,201,202,200,200,202,200,201,200,202,202,202,202,203,203,201,200,199,200,199,198,198,198,199,196,199,198,199,202,199,200,200,203,200,200,202,202,203,204,203,204,205,204,201,203,204,202,203,201,202,201,202,202,201,202,203,200,201,200,200,200,197,200,200,202,200,199,200,200,201,201,203,200,201,203,201,201,204,202,202,201,202,203,200,203,201,201,201,199,201,202,201,200,200,202,203,202,202,202,201,203,203,202,201,200,202,201,201,202,201,202,205,203,202,202,201,202,202,201,203,200,204,205,204,204,203,205,203,203,203,201,203,204,201,201,202,201,205,201,200,203,202,202,202,203,200,201,203,201,202,203,203,200,199,201,202,202,206,203,201,203,203,202,202,203,204,205,202,202,203,203,203,202,204,201,202,203,204,202,201,203,199,200,203,201,202,200,201,202,200,202,201,203,204,202,202,200,201,201,200,200,201,201,201,200,198,199,200,200,200,200,202,203,193,194,201,201,201,200,200,200,200,196,195,200,203,202,200,202,200,201,200,202,199,201,203,204,191,191,201,200,200,203,193,198,206,203,206,203,203,202,201,203,203,204,203,193,193,203,205,205,200,210,195,175,214,108,23,43,77,110,96,116,136,132,110,90,92,76,64,64,57,61,119,95,39,108,135,105,94,66,57,45,45,74,76,80,84,81,112,150,194,151,118,212,202,116,118,90,99,118,71,62,36,138,225,205,207,151,182,212,193,231,160,77,183,221,226,217,113,70,42,50,174,244,101,63,42,33,163,249,243,57,2,12,12,17,17,24,17,16,25,30,35,51,46,49,74,79,93,56,61,105,142,128,79,81,86,92,63,41,31,43,53,50,50,50,51,43,34,28,29,31,29,26,34,49,85,136,154,134,77,43,21,15,9,13,14,13,16,29,33,44,58,53,59,46,24,24,16,23,16,81,136,98,126,122,56,27,21,19,22,20,23,21,18,25,21,18,22,19,19,21,22,18,16,15,17,17,15,14,18,18,18,23,17,19,17,21,18,16,20,19,29,28,20,24,22,22,21,20,22,16,26,37,37,28,25,20,20,19,24,56,99,118,109,99,87,58,25,23,33,22,15,26,30,23,20,17,18,20,29,30,21,19,19,32,47,29,19,14,55,131,158,132,108,95,78,61,28,20,33,25,15,24,24,17,17,16,16,18,23,23,16,19,33,36,31,18,17,15,17,28,27,26,32,29,21,24,19,19,16,16,20,22,23,25,26,26,26,20,25,29,25,27,30,30,31,36,40,39,46,48,53,55,62,69,79,84,87,92,82,81,79,77,71,65,66,59,107,64,67,69,70,66,69,72,68,101,105,91,91,99,101,74,86,120,130,85,38,17,14,17,17,20,18,31,56,89,104,104,102,87,64,43,36,42,48,54,56,54,57,57,61,59,47,46,41,44,60,76,105,132,143,156,177,203,213,233,245,246,241,227,220,217,216,213,213,214,212,211,212,214,215,212,216,217,219,119,6,1,7,11,12,11,14,13,15,15,15,15,198,201,198,200,201,196,198,197,197,196,195,197,196,197,198,195,193,196,198,197,198,196,198,197,198,196,194,199,194,196,198,196,199,199,203,203,202,203,200,200,200,201,200,198,200,200,200,200,200,204,202,201,202,203,203,205,204,203,204,204,205,204,203,203,201,202,200,201,199,199,200,199,198,198,200,200,203,202,203,201,201,201,202,201,199,200,203,205,202,203,202,205,205,202,202,201,200,204,202,200,200,202,203,201,201,202,202,203,202,201,199,200,200,198,201,199,200,199,200,202,201,200,200,202,201,202,199,202,202,201,200,200,203,201,202,202,203,202,199,200,200,200,200,200,202,202,201,201,204,203,203,202,201,203,202,203,201,202,203,202,203,200,202,203,201,200,202,200,203,203,203,202,204,203,204,205,200,203,204,203,204,203,201,202,201,203,200,203,202,200,203,202,202,201,199,202,203,200,202,202,202,202,201,200,201,199,200,203,201,201,202,203,201,203,202,202,201,200,200,199,202,202,200,201,200,202,201,200,200,200,202,197,200,201,200,201,200,200,202,201,199,199,200,200,199,201,200,201,202,199,200,200,201,200,201,202,201,199,198,200,203,201,193,196,202,200,201,200,200,201,198,194,197,202,201,201,202,202,199,201,200,200,199,200,201,203,195,185,198,202,200,200,191,196,203,202,203,204,204,202,202,202,201,201,203,194,190,199,203,202,199,207,189,179,231,153,76,69,91,122,96,101,109,110,69,20,28,28,30,41,36,30,105,88,13,48,78,127,87,35,55,14,36,67,63,48,29,59,107,137,166,104,121,221,193,118,81,66,83,91,74,66,34,149,227,206,204,150,191,208,193,231,109,81,211,221,230,148,69,69,46,35,127,138,69,62,34,128,217,246,231,91,49,15,11,25,17,17,21,25,34,35,49,49,51,72,80,94,95,59,46,63,115,135,93,59,62,77,82,73,47,39,51,53,44,46,51,43,45,40,34,32,28,33,71,135,159,173,125,50,33,13,12,14,11,14,15,31,40,51,53,53,55,59,53,34,21,18,16,22,19,103,133,98,138,116,45,14,11,14,14,14,17,15,15,17,21,22,21,20,24,24,19,20,24,22,18,15,16,17,15,21,21,24,23,22,24,24,20,19,16,33,36,18,19,24,26,17,16,21,21,19,26,22,29,41,35,23,18,19,31,110,155,156,136,116,111,69,46,30,27,22,22,26,14,17,25,17,22,29,19,17,25,23,17,31,48,40,29,14,68,160,157,140,109,104,112,66,37,29,23,14,18,26,19,21,18,16,18,18,24,23,18,18,21,40,44,25,20,18,24,42,49,59,63,51,46,33,17,18,16,23,27,29,26,19,22,30,23,24,28,25,25,20,21,19,23,21,18,22,23,26,27,23,30,37,43,44,44,55,56,59,58,57,64,61,61,63,64,64,71,66,68,75,72,75,69,73,71,66,60,61,63,49,90,109,119,95,37,25,15,15,16,19,22,17,23,39,60,89,119,115,87,59,45,37,36,35,43,40,50,48,49,52,43,57,66,67,65,61,59,63,64,73,81,102,122,155,197,223,246,246,235,227,220,216,216,218,216,217,215,217,219,218,222,223,222,117,6,1,7,11,13,12,14,13,15,15,15,15,194,198,199,199,199,196,196,196,196,196,197,198,198,196,194,195,195,197,196,195,198,199,198,196,197,198,197,196,198,195,196,199,200,201,201,205,207,205,204,203,202,204,203,202,201,201,200,201,203,202,204,204,201,203,205,202,205,207,205,204,205,204,205,203,203,205,200,200,203,202,200,198,199,201,205,205,206,207,202,204,203,204,205,203,205,203,203,202,200,202,202,203,200,201,200,202,204,202,204,203,203,203,203,205,205,201,204,203,203,203,200,201,200,199,199,199,199,202,200,199,201,199,200,200,200,203,203,203,202,200,202,200,202,204,199,199,202,202,201,200,200,200,201,200,200,202,200,202,200,201,202,203,202,201,201,202,203,201,201,202,202,201,201,201,202,199,202,202,201,202,200,202,203,203,203,202,201,200,200,202,201,201,200,201,200,200,202,201,201,201,199,201,201,203,202,200,203,203,199,201,203,202,201,202,202,201,201,203,201,201,202,200,203,204,204,202,199,200,200,200,200,200,201,198,200,198,200,200,199,201,198,199,200,199,199,200,200,200,199,201,198,197,199,200,199,198,199,198,199,198,199,200,200,199,201,200,199,200,201,199,203,200,193,200,201,199,198,199,201,202,196,196,201,202,199,199,202,200,199,201,200,200,199,199,199,204,195,186,195,200,198,199,194,195,203,201,202,201,203,201,199,200,199,199,201,198,189,194,200,201,200,208,181,184,233,180,125,69,70,103,76,89,81,76,46,19,26,18,21,27,46,32,112,104,49,89,125,176,110,55,38,12,55,60,57,27,11,42,83,154,189,112,140,188,159,134,87,76,77,81,74,68,38,163,235,211,201,147,199,205,206,220,76,106,224,227,170,69,49,35,14,27,32,36,31,55,143,220,237,205,169,197,224,198,115,21,14,14,23,31,36,45,43,56,74,81,80,76,85,78,91,94,96,140,97,62,46,51,74,74,60,32,35,41,54,51,41,46,45,42,35,37,48,103,159,182,160,89,48,33,19,13,13,12,18,27,45,55,54,57,54,60,60,54,52,28,17,17,15,20,35,129,133,103,141,103,36,10,10,14,16,14,16,16,20,24,21,18,24,21,17,23,23,17,23,35,31,23,19,15,19,20,33,36,29,30,27,27,22,18,29,36,23,19,27,24,22,18,20,19,24,27,24,22,16,31,55,36,19,18,50,144,170,174,120,101,117,72,56,35,25,31,22,19,14,19,21,30,35,19,16,14,19,26,33,31,33,52,32,24,65,113,105,111,108,73,73,48,39,32,19,19,21,16,14,19,24,20,24,19,18,19,21,23,16,33,50,35,22,17,49,92,106,108,97,84,71,46,24,15,26,32,28,19,22,23,18,20,25,21,19,24,30,29,28,25,17,19,17,19,24,20,20,22,22,19,22,20,23,27,31,30,27,34,32,37,38,38,44,42,46,48,54,57,58,69,61,65,70,72,68,67,70,77,113,106,105,96,49,21,16,18,17,18,20,20,22,20,24,40,51,69,73,66,59,50,43,31,31,35,42,45,41,41,37,45,60,72,88,84,81,66,60,60,63,63,54,64,97,150,212,233,245,241,230,218,217,218,220,222,220,220,222,224,225,224,225,119,6,1,8,11,12,12,14,12,14,15,14,14,193,199,195,198,197,194,196,195,196,196,196,197,195,194,195,194,196,194,193,195,195,194,198,195,196,198,197,200,195,195,198,200,201,199,204,203,205,205,203,204,203,203,205,203,201,203,204,203,205,206,205,205,204,203,204,203,204,205,207,208,206,208,206,206,206,206,205,206,204,204,205,203,203,203,204,205,206,203,205,205,203,205,203,202,206,206,206,204,203,205,202,203,201,202,201,203,202,203,202,202,204,204,204,202,203,203,202,200,201,200,198,199,200,199,198,199,201,200,199,201,199,198,201,201,200,201,198,201,200,201,202,200,201,200,203,201,199,201,201,200,199,202,200,199,201,199,201,201,202,201,202,201,199,200,198,200,201,199,202,202,202,203,200,201,200,201,202,200,201,200,201,202,204,201,199,201,200,200,201,199,199,201,200,202,201,201,200,203,201,201,201,197,202,200,200,202,198,199,200,201,199,201,201,202,201,200,201,199,201,202,202,200,200,203,199,201,204,200,200,200,203,201,200,201,200,201,200,201,200,199,201,202,200,196,198,201,199,197,199,199,199,200,198,199,198,199,199,200,199,195,200,199,196,198,199,198,197,199,199,198,201,200,198,199,198,200,200,199,200,197,191,197,200,200,199,201,199,202,199,199,200,197,199,198,199,200,198,185,193,201,200,198,191,193,200,203,200,199,198,198,199,199,198,200,202,198,193,189,200,200,203,205,173,190,225,200,169,84,59,73,61,70,70,54,13,26,27,24,35,29,54,32,97,89,30,79,145,184,102,84,50,25,63,50,29,18,93,159,157,186,193,130,139,142,167,156,102,104,75,72,78,60,29,159,230,208,191,143,205,200,219,203,63,156,241,169,77,9,7,9,27,27,39,23,23,135,221,248,212,125,171,252,252,252,215,51,4,30,43,54,57,43,45,65,93,84,82,88,83,86,100,99,92,122,100,66,51,40,55,62,55,30,21,24,39,60,51,40,27,27,32,55,127,158,183,136,47,24,15,17,16,11,17,24,44,53,54,58,59,59,62,61,60,62,51,21,20,16,25,16,47,146,121,115,137,83,33,13,12,16,22,20,17,20,30,22,22,31,21,16,19,18,18,24,27,25,32,32,23,18,15,37,45,50,57,52,53,51,31,27,40,24,17,26,21,17,21,21,17,20,23,19,25,25,23,20,39,49,32,16,73,139,129,117,104,99,88,61,53,35,29,31,24,19,19,16,23,34,32,20,19,19,17,27,35,29,22,49,40,28,63,82,81,127,100,77,62,31,49,24,23,25,13,19,17,19,23,32,24,15,19,15,21,32,24,23,40,44,27,30,111,168,166,157,117,104,91,53,26,24,27,20,22,26,24,19,18,18,17,27,32,21,23,27,37,27,21,20,16,21,26,29,27,22,24,22,17,17,20,22,15,21,20,24,27,26,25,24,29,24,26,24,23,29,29,34,29,35,36,39,39,44,41,52,107,97,106,106,46,28,19,19,22,22,31,25,21,19,21,20,22,29,42,48,52,55,44,41,36,31,41,39,33,33,39,42,48,64,72,76,74,76,64,63,57,54,56,51,51,66,127,170,205,236,227,219,221,223,225,225,222,221,224,227,227,224,224,118,6,2,8,11,12,12,15,14,15,16,15,15,196,199,196,197,197,194,198,197,196,196,195,195,197,194,193,196,192,197,196,195,196,196,199,197,198,199,200,198,199,198,198,198,200,203,201,201,203,203,203,204,203,204,204,205,203,203,203,205,205,202,204,205,203,205,207,206,203,202,203,204,208,208,208,206,208,209,205,205,208,207,208,211,205,203,203,204,202,205,204,204,205,201,204,203,203,204,206,205,205,201,204,205,200,203,200,201,203,200,202,202,201,203,203,200,202,202,203,201,201,203,200,201,200,199,199,198,199,199,198,199,200,200,201,201,201,199,196,200,199,199,200,202,202,201,200,199,200,197,198,199,200,199,199,200,200,200,198,201,199,198,202,203,199,200,199,200,199,200,201,200,201,200,200,201,201,198,200,200,198,201,200,199,204,199,200,201,200,202,199,199,200,201,201,203,201,201,200,200,202,200,199,199,200,199,200,199,200,201,198,200,200,200,199,200,199,199,202,199,199,200,202,200,198,199,200,199,198,199,197,200,198,198,201,196,198,199,199,201,199,201,199,197,200,200,199,200,199,197,197,196,199,198,198,202,198,198,198,199,200,198,198,198,198,197,196,199,197,198,199,200,201,194,200,200,199,200,200,200,199,194,192,200,198,200,199,198,200,195,199,198,196,196,196,196,196,200,198,185,186,200,201,198,190,189,200,199,197,198,196,196,198,199,199,198,199,200,195,187,196,201,202,199,173,199,217,198,194,132,99,81,66,77,72,41,4,23,36,62,40,35,60,38,67,69,12,45,137,146,73,57,19,33,66,55,52,69,180,220,201,212,184,129,143,165,207,171,103,122,90,77,78,50,25,158,224,205,187,147,208,196,224,159,63,213,202,74,24,24,24,44,33,36,43,29,117,211,242,242,145,130,210,249,249,249,163,71,75,105,124,108,62,41,49,87,93,66,109,101,96,95,97,97,88,116,95,66,49,68,79,62,63,35,34,24,27,38,44,39,29,39,66,118,154,154,87,32,21,17,15,13,14,23,43,55,63,59,56,61,62,63,63,56,52,41,27,15,18,19,24,12,70,149,107,114,132,71,25,16,15,17,21,16,21,27,26,22,29,25,18,15,14,17,21,22,28,26,17,35,33,23,15,36,64,71,92,102,106,79,34,33,36,18,29,27,17,17,20,22,27,28,19,18,17,20,30,28,27,47,46,20,61,111,81,78,85,104,89,41,44,39,22,18,24,34,21,24,34,17,21,24,23,23,22,22,19,29,35,55,47,31,55,81,89,111,133,98,52,33,36,26,16,26,24,16,20,22,26,25,19,22,17,16,26,24,24,16,37,57,25,64,156,165,173,156,98,112,92,63,46,27,23,14,24,27,21,18,17,20,18,34,28,16,21,22,38,35,26,22,17,21,24,27,28,27,27,23,21,18,21,20,19,25,26,30,26,28,31,24,25,25,23,24,23,17,25,21,20,23,21,24,21,26,24,43,98,96,108,106,58,31,19,14,32,46,50,55,41,27,28,19,15,19,22,20,26,30,39,37,34,39,37,50,45,33,37,39,45,49,59,59,54,56,59,55,55,59,61,67,51,30,50,69,118,199,217,219,224,221,225,223,224,225,225,224,225,225,224,118,6,2,8,12,13,12,15,14,15,15,16,15,198,198,197,198,196,196,196,196,196,198,195,196,195,193,195,194,197,194,195,198,195,195,200,199,199,200,198,199,196,197,198,196,199,200,203,201,202,203,203,204,204,203,204,200,200,204,202,200,201,203,204,203,203,204,203,205,203,203,202,205,205,207,207,208,208,207,208,207,207,208,211,207,206,205,203,206,205,205,205,203,204,205,206,203,205,205,204,205,203,204,204,203,203,203,204,205,201,204,206,203,201,201,202,203,203,202,202,199,202,203,201,204,200,198,199,198,199,199,198,200,198,198,202,199,201,200,199,200,199,198,201,200,200,200,199,201,200,201,200,198,201,199,198,201,200,199,200,200,201,200,200,201,200,200,199,202,201,198,200,200,199,201,199,199,200,200,199,196,199,199,200,201,202,200,199,200,200,201,202,202,202,201,202,201,201,201,199,200,197,200,202,198,200,198,199,200,199,200,201,200,198,198,198,200,200,198,201,199,200,199,200,199,198,198,196,199,198,198,198,198,199,197,198,198,199,200,197,196,196,197,197,196,198,197,198,196,198,196,199,198,196,198,195,199,197,198,196,197,198,194,200,200,199,199,198,199,197,198,200,199,193,194,198,199,198,198,198,196,195,193,196,199,198,198,198,198,198,196,196,199,196,195,200,195,196,195,198,186,181,198,199,197,189,190,199,199,196,198,196,197,198,196,196,196,200,197,199,187,190,198,206,191,170,204,198,174,158,134,134,135,146,133,145,112,61,83,88,124,83,60,91,38,78,66,4,53,147,130,112,150,77,49,57,116,185,184,223,206,181,163,154,141,133,188,215,121,94,123,95,99,74,38,24,158,226,209,178,150,218,200,232,131,67,204,98,29,6,73,187,117,82,53,36,125,227,251,213,157,159,196,246,225,214,155,76,97,119,130,142,104,62,80,102,83,65,69,110,101,90,98,92,102,100,108,89,75,70,65,65,56,53,37,32,28,19,25,22,33,36,96,148,146,143,71,27,21,12,16,11,14,27,48,60,57,61,59,59,61,68,71,66,62,44,29,22,19,17,21,29,12,95,154,99,122,122,57,25,15,16,21,21,22,30,31,27,26,21,16,17,22,16,19,27,21,21,27,22,23,39,35,19,69,102,99,104,101,81,51,46,38,28,24,23,21,17,24,19,27,36,22,18,18,16,22,30,32,22,40,49,22,48,81,80,80,117,149,81,36,42,26,15,15,17,28,41,36,20,22,16,19,33,34,23,15,16,23,34,71,57,24,48,68,53,87,102,66,35,33,37,17,15,15,24,26,22,27,19,14,22,24,21,27,26,14,22,24,40,66,35,104,158,143,139,114,105,89,76,59,37,26,15,20,21,17,20,20,23,26,23,21,27,23,26,22,29,44,31,23,17,26,34,39,41,37,32,31,31,26,19,25,30,32,25,22,25,21,27,25,20,26,29,36,27,19,23,18,21,23,18,21,17,21,24,55,112,103,118,112,61,37,15,13,30,56,78,78,69,57,43,33,23,19,19,19,21,19,19,30,29,35,43,61,61,46,38,36,41,45,46,50,50,47,51,51,57,60,56,50,51,37,50,36,57,163,202,219,227,221,224,225,227,226,226,225,226,225,224,117,6,2,7,12,13,12,15,13,15,15,16,15,197,199,195,198,197,196,196,197,197,196,198,194,196,194,195,198,197,198,197,197,196,198,200,200,200,200,197,198,201,197,196,197,198,202,201,202,204,201,203,200,202,205,202,203,198,202,204,203,203,198,201,204,204,204,203,204,204,205,205,206,207,207,209,208,209,203,203,205,205,205,204,206,203,207,207,206,207,207,205,208,203,205,207,204,206,203,205,203,202,203,202,204,202,205,203,201,204,201,203,203,204,205,204,201,201,200,200,201,199,201,201,202,200,200,199,198,198,199,201,200,198,199,199,196,199,198,196,200,200,200,199,198,200,199,202,201,199,201,199,198,199,198,198,198,200,203,200,199,200,200,200,200,199,200,199,198,199,200,198,198,199,199,198,200,200,199,200,200,200,199,200,198,200,197,199,199,199,201,199,200,200,199,198,200,200,200,198,197,198,199,200,200,197,198,200,198,199,199,198,198,198,198,198,199,199,197,198,198,199,199,197,198,197,199,198,195,199,198,196,199,198,198,198,197,199,199,194,198,195,196,199,196,197,197,198,198,198,197,199,199,200,198,195,199,197,199,198,195,196,192,197,196,197,199,195,198,196,196,197,198,196,192,201,198,196,198,195,196,191,192,196,199,196,196,196,195,194,193,198,193,194,194,195,196,195,197,198,190,179,194,198,198,187,184,197,197,196,194,196,196,193,194,194,195,198,196,196,189,185,191,205,184,173,203,181,150,132,138,174,179,199,193,208,199,126,105,178,207,177,115,125,59,132,94,5,84,166,137,177,247,153,56,57,170,232,221,228,168,140,124,169,146,116,178,174,92,83,123,96,101,73,32,24,156,226,208,175,160,226,217,248,141,70,115,30,5,43,129,237,160,110,34,99,225,251,242,149,172,217,252,250,189,117,66,77,114,107,117,88,53,89,136,100,65,57,77,90,86,97,85,79,107,101,89,89,83,59,64,50,36,42,32,30,26,14,21,26,20,52,146,157,145,112,49,17,12,15,13,15,19,51,66,59,59,59,62,63,62,64,71,74,83,74,56,38,23,22,22,26,27,128,145,100,127,107,56,30,31,41,42,33,29,37,33,29,18,15,17,22,24,23,29,24,13,20,26,29,33,37,41,28,104,149,134,113,74,85,66,49,44,18,14,17,26,25,21,31,26,19,27,23,20,27,27,19,29,25,45,53,32,21,60,87,94,152,125,53,38,40,27,22,19,16,35,37,32,24,17,18,22,39,39,24,16,17,18,40,92,72,28,47,62,32,43,55,41,27,35,35,15,16,16,16,33,36,17,18,18,19,29,35,27,19,14,19,20,50,78,43,107,157,111,96,101,93,103,67,36,37,19,29,23,12,19,23,20,33,30,21,20,15,27,33,31,28,39,44,28,16,39,54,64,77,71,66,70,51,24,29,35,29,28,28,22,23,22,22,27,33,33,28,35,33,26,23,19,23,18,21,22,18,22,23,75,128,110,111,107,71,31,19,17,23,50,79,92,85,79,71,53,43,36,21,17,18,17,17,26,19,27,41,49,64,69,58,44,40,37,37,51,56,54,54,53,50,51,48,49,54,45,67,53,65,165,203,221,231,223,224,225,225,223,222,228,228,223,225,118,6,2,8,12,12,12,15,14,15,16,15,16,196,197,196,197,196,198,197,195,197,194,196,199,196,198,199,198,201,198,198,200,198,200,203,203,203,200,202,202,199,201,201,201,197,199,201,200,201,202,202,202,203,200,201,202,202,203,202,200,205,204,201,202,201,202,204,205,203,203,204,203,206,208,206,206,205,206,205,205,206,204,207,206,205,207,205,205,207,207,206,205,206,205,205,203,204,205,204,203,203,203,201,203,207,204,200,201,201,204,203,204,204,203,203,201,204,201,201,202,200,201,200,200,200,199,201,201,198,199,199,199,198,200,202,197,199,196,199,203,200,200,201,199,199,200,199,200,199,199,200,198,200,201,200,199,199,196,199,198,199,200,197,200,198,201,199,201,202,196,199,198,199,198,197,199,199,198,199,200,200,198,198,196,199,199,197,200,198,198,198,198,198,198,199,198,199,199,198,199,196,198,199,196,199,199,198,198,198,199,199,198,199,198,198,198,198,197,197,196,199,199,198,198,198,199,198,200,198,199,198,198,200,198,200,199,199,196,198,198,196,200,198,199,199,198,200,198,200,198,196,198,198,197,198,199,198,199,197,199,195,195,198,195,197,198,196,198,196,199,201,198,190,195,199,200,198,199,198,193,192,195,196,197,197,198,195,193,195,194,194,195,193,193,195,192,196,194,196,191,179,192,197,200,186,181,194,194,195,194,194,194,194,195,193,195,194,192,196,193,185,188,204,174,179,202,177,175,159,177,186,183,198,172,189,204,159,82,139,243,208,134,117,67,141,121,50,129,181,128,174,207,113,101,122,171,189,177,155,129,152,149,198,136,98,182,171,111,99,92,84,102,70,42,24,155,225,212,178,166,234,198,201,152,69,44,4,7,26,143,143,87,72,69,189,250,252,189,159,223,252,252,249,129,43,63,108,130,118,76,41,77,133,134,83,61,69,112,92,60,105,117,99,104,90,80,105,105,93,88,71,59,53,33,29,25,16,21,24,37,97,144,126,84,54,28,15,15,10,15,15,32,60,63,63,61,63,59,69,66,46,41,39,60,78,89,81,46,18,22,17,46,147,134,98,128,92,41,29,66,100,78,41,32,37,31,29,19,13,18,19,27,31,27,18,15,16,23,41,34,37,41,39,134,150,134,128,99,106,67,53,41,16,13,15,19,29,38,27,23,13,19,26,27,37,22,16,21,25,49,71,36,23,60,73,73,61,44,37,36,46,28,23,24,34,33,20,31,30,26,30,35,27,22,31,23,17,37,45,94,77,25,60,54,26,33,33,27,27,37,39,20,15,16,24,24,23,27,18,14,21,32,32,21,18,16,24,23,68,93,40,78,116,101,87,83,153,126,46,39,29,26,24,21,16,16,22,27,28,25,19,21,18,19,33,31,23,30,47,34,19,55,84,117,127,124,135,98,45,28,36,24,26,30,28,22,21,21,23,27,34,32,24,27,33,41,28,18,29,26,26,27,27,28,22,83,127,102,103,103,77,42,20,16,26,54,76,93,89,80,83,76,67,57,41,27,20,21,22,21,21,22,25,33,56,76,74,65,48,33,43,54,55,50,46,39,42,47,61,71,65,54,61,43,89,204,223,226,228,222,223,223,225,222,224,226,228,223,223,118,5,2,9,13,12,12,15,14,14,15,15,15,198,198,197,199,195,197,195,198,199,195,198,198,199,197,198,197,198,199,199,200,200,202,203,203,203,204,205,202,201,200,203,200,200,203,203,202,203,201,202,202,202,203,200,200,199,200,198,197,201,199,200,202,199,200,203,204,203,203,201,205,207,205,207,206,207,206,208,208,207,206,205,207,207,207,205,203,208,206,204,208,203,205,206,203,206,201,203,206,203,203,204,203,203,205,204,204,205,204,205,204,202,203,203,203,203,203,202,202,203,201,203,202,198,203,200,199,200,201,200,199,201,199,198,198,200,200,198,198,199,200,198,201,200,198,200,199,198,199,198,198,199,195,198,200,198,199,199,198,197,198,196,197,198,196,198,196,198,199,198,198,197,200,198,197,198,197,199,199,198,197,198,195,198,195,196,195,193,197,194,197,197,197,196,198,201,198,199,197,196,197,197,199,196,194,196,196,198,198,198,196,198,197,193,198,198,196,199,198,199,198,198,198,198,199,197,198,198,196,196,199,197,196,199,198,197,198,198,200,199,199,199,198,199,199,198,198,199,197,199,198,198,199,197,199,197,198,199,195,198,197,198,199,197,199,196,197,199,198,199,197,194,193,197,198,199,197,197,194,194,200,198,197,196,198,195,194,196,193,199,195,194,195,195,191,191,194,197,196,180,187,195,198,187,179,195,191,191,195,194,194,193,194,192,193,193,193,196,196,184,189,200,171,186,194,175,175,168,178,178,159,160,149,172,212,200,121,78,157,167,139,110,61,122,81,17,113,182,131,130,104,99,156,184,192,145,136,133,147,166,170,195,119,155,210,184,149,100,81,75,92,68,44,25,151,227,209,181,151,181,128,130,118,39,17,6,17,26,49,53,40,83,173,233,250,218,169,207,250,251,251,190,45,44,90,132,132,91,42,45,113,142,93,71,46,85,140,77,93,170,162,109,103,92,101,110,117,118,97,84,73,65,46,43,30,26,26,38,88,144,135,67,36,18,15,16,17,23,20,20,41,69,71,62,63,66,72,86,78,42,25,27,31,39,65,99,80,30,21,15,58,157,126,107,123,73,39,22,84,119,73,47,42,37,18,22,27,21,17,28,27,18,23,24,14,21,26,31,34,43,50,49,130,131,110,121,94,98,57,46,41,12,14,14,21,33,36,31,16,16,23,26,37,24,20,19,17,18,60,89,43,30,59,45,47,38,31,30,36,46,28,24,37,26,22,16,22,32,45,47,23,20,18,24,42,57,34,39,109,71,28,62,44,32,36,26,26,31,39,33,21,21,32,30,17,20,28,25,29,37,22,17,26,27,23,34,36,79,93,37,41,81,98,101,137,170,96,31,35,29,16,19,19,22,24,22,27,21,21,23,19,19,34,29,27,34,30,54,40,37,82,102,149,122,100,99,72,48,37,33,22,33,25,23,25,24,18,31,37,19,29,27,22,28,45,38,20,24,28,30,29,26,31,26,80,125,102,103,107,87,46,21,16,21,46,63,81,86,92,87,87,87,76,67,50,36,27,21,21,23,20,22,24,34,51,69,73,72,51,39,42,32,39,43,46,51,48,74,87,73,57,57,57,148,231,231,228,225,222,224,223,224,224,224,225,229,224,225,118,6,2,7,12,14,13,14,14,15,15,15,15,199,203,201,203,200,198,200,199,200,199,201,203,198,201,200,198,201,201,201,201,201,202,202,203,201,203,203,200,200,200,200,200,200,203,203,202,204,199,200,200,200,203,199,201,203,202,203,200,200,202,198,202,203,203,203,203,204,203,205,205,205,205,205,208,206,208,208,205,210,208,207,206,207,208,208,207,206,207,208,207,207,207,206,204,203,203,204,203,203,206,205,203,206,202,205,205,202,205,205,205,200,200,204,201,204,202,202,203,201,200,201,202,200,200,200,203,202,201,200,198,201,199,199,198,200,199,198,202,198,196,199,196,200,200,198,199,199,198,198,200,199,198,199,199,199,196,197,197,197,198,196,198,196,198,198,198,197,198,198,196,199,197,195,196,195,198,198,196,196,198,197,194,196,196,195,195,195,198,197,195,197,198,195,193,198,198,196,196,195,195,199,197,196,196,195,198,195,195,196,195,196,194,198,198,197,196,195,198,197,196,197,197,197,196,198,196,195,198,196,198,196,197,198,195,199,198,198,198,198,198,197,198,198,198,198,195,198,199,198,198,200,198,198,198,197,197,197,201,196,198,199,199,200,198,194,196,198,196,200,193,191,195,196,199,200,197,194,193,196,199,196,196,194,196,197,196,195,193,195,195,195,195,195,195,195,195,197,195,182,183,193,199,187,177,193,196,194,195,193,194,192,192,193,191,194,195,192,196,189,188,192,170,184,176,140,133,123,137,133,120,145,166,191,220,220,185,115,66,94,124,104,66,98,73,4,76,161,125,77,73,151,194,208,170,143,168,160,170,159,164,184,132,198,210,193,162,86,101,85,78,61,35,23,153,230,224,174,83,132,124,69,39,7,29,43,47,50,55,39,53,183,250,252,214,179,203,245,250,247,226,81,26,63,105,133,99,45,55,76,105,92,71,63,23,71,140,137,186,219,153,111,105,101,121,100,85,79,77,77,66,61,46,42,33,34,30,54,125,149,98,34,19,14,10,17,35,46,25,14,48,69,66,66,69,81,92,90,60,35,27,23,20,32,44,82,109,42,25,13,79,165,107,117,116,57,43,61,99,103,76,62,44,26,14,12,24,29,32,26,14,17,18,27,31,27,22,15,20,50,60,46,95,92,85,105,101,83,40,46,33,17,17,15,29,19,22,29,26,18,29,30,17,26,24,20,23,28,66,92,40,34,55,29,27,26,27,27,31,49,33,31,34,30,24,17,19,36,53,49,30,23,18,27,60,57,29,54,120,68,24,61,38,26,39,23,28,26,39,38,23,38,31,21,19,22,25,36,39,27,19,15,19,27,52,48,25,90,96,35,35,71,87,88,75,61,43,35,35,17,16,18,19,29,39,27,16,16,18,27,29,33,25,16,19,28,39,69,49,56,117,127,152,126,92,110,85,51,38,35,33,22,18,23,22,29,36,32,21,16,27,28,30,33,45,42,27,35,38,43,43,51,57,40,108,134,111,101,104,94,44,24,16,18,20,36,74,96,112,112,98,93,86,81,76,57,45,27,17,19,22,19,18,26,24,37,62,73,71,56,50,53,48,49,52,55,65,72,66,69,62,57,137,230,239,234,224,225,222,224,225,221,223,224,226,229,224,224,117,5,2,7,11,13,12,13,12,15,16,15,15,203,205,205,204,203,206,201,203,202,200,204,200,201,203,203,202,203,203,201,201,203,203,203,201,202,203,200,205,203,201,202,201,202,200,201,200,202,203,199,200,201,199,202,202,200,203,202,200,203,203,205,204,202,204,202,201,205,204,203,204,205,207,207,208,207,207,207,208,209,210,208,208,209,209,207,205,212,208,208,213,207,208,210,208,208,205,205,204,205,205,205,206,205,203,203,207,203,203,203,201,203,202,203,203,201,200,201,201,202,201,201,201,200,203,200,199,199,200,200,200,200,197,200,200,198,200,200,199,199,198,199,198,196,198,200,198,199,199,200,198,200,199,196,199,198,198,199,198,198,198,197,198,198,198,198,197,198,199,197,198,197,196,199,196,197,198,196,196,196,195,200,198,197,196,199,197,195,199,195,198,197,197,197,196,199,195,195,196,196,196,198,198,195,199,198,195,196,196,197,191,196,198,193,198,198,194,196,198,196,194,194,198,197,196,195,197,198,197,198,197,196,198,198,198,197,198,197,196,196,196,198,199,197,199,198,198,199,194,199,198,197,197,195,197,197,198,197,195,197,196,198,200,198,198,197,194,198,199,197,191,192,196,198,199,200,197,188,193,198,200,195,190,194,196,194,195,195,192,196,193,193,198,195,195,193,193,194,196,186,182,192,199,194,180,192,197,193,198,193,194,195,194,193,195,193,191,193,198,190,192,183,168,188,160,128,124,124,138,145,136,168,191,188,212,216,210,185,85,26,70,100,81,101,69,5,55,116,109,60,104,191,189,185,151,166,195,162,134,138,189,169,118,188,156,178,146,77,119,91,83,61,30,19,155,236,217,171,72,122,120,57,34,4,117,171,87,69,60,46,98,231,249,203,171,205,229,247,247,215,99,45,51,81,92,98,53,81,122,117,71,57,64,41,13,34,102,166,215,195,133,109,109,100,114,91,53,51,65,75,57,59,50,39,37,29,34,85,141,131,74,22,17,12,12,18,47,67,32,19,51,73,74,78,96,111,105,68,31,31,20,11,15,22,35,85,116,53,27,21,113,157,94,121,103,50,41,92,120,102,91,61,45,24,14,17,19,36,27,19,15,15,14,24,41,27,15,21,12,46,81,41,62,69,68,131,132,72,32,37,29,15,26,29,21,20,17,26,32,41,33,17,15,16,29,34,46,25,63,100,39,41,51,27,29,32,22,27,34,46,46,27,22,22,28,26,36,37,30,46,48,35,29,57,42,33,40,78,131,60,32,67,40,37,49,33,33,36,47,36,26,28,23,30,28,18,34,39,29,27,20,17,24,43,49,34,29,101,96,37,41,66,50,39,44,31,22,37,39,21,17,17,18,35,34,22,21,19,24,31,36,29,26,22,17,24,49,89,51,84,129,134,144,105,116,113,80,56,45,36,27,23,23,19,24,36,39,24,21,16,17,28,47,35,41,48,33,48,60,70,81,116,121,98,142,149,118,102,111,102,46,26,19,18,31,46,84,117,131,125,114,85,84,90,86,76,63,49,29,19,21,23,21,18,24,24,35,54,73,78,79,64,51,44,53,68,55,56,47,65,40,75,207,243,241,225,220,225,221,220,221,220,221,220,224,228,223,225,118,5,2,7,12,12,12,15,13,15,15,15,15,205,206,205,206,201,201,202,201,202,203,205,204,201,203,201,200,199,200,200,200,201,199,200,202,200,201,202,204,202,203,203,202,202,203,204,203,201,199,199,200,201,202,201,201,201,200,201,200,203,204,200,203,203,202,202,203,203,203,206,202,205,208,206,207,207,208,209,207,207,206,208,205,208,210,208,208,208,208,209,208,210,209,208,207,207,207,204,205,207,210,207,204,205,202,206,205,204,204,201,204,205,204,204,203,203,203,202,202,201,202,202,203,201,200,200,200,200,198,201,198,200,200,200,200,200,199,199,200,195,198,199,199,200,197,198,197,199,200,198,199,196,197,197,197,198,198,199,200,199,198,199,200,199,198,198,199,197,198,196,196,199,199,199,198,198,198,195,198,196,197,196,196,196,195,199,198,196,196,197,196,195,198,196,196,201,197,194,195,194,196,195,194,194,196,197,198,195,196,196,194,195,194,196,193,194,197,193,196,195,193,196,196,194,194,195,195,195,196,196,198,195,195,196,195,196,196,195,196,194,195,196,195,195,196,198,195,195,195,195,195,196,196,195,197,196,195,194,195,194,197,196,194,198,198,196,195,194,195,198,191,194,197,197,196,196,195,190,196,197,196,194,193,193,194,193,194,194,194,195,192,195,194,191,191,190,194,193,197,190,177,193,199,196,187,192,200,194,194,193,193,193,192,195,195,192,194,193,195,194,198,178,165,189,173,153,156,170,179,176,168,198,200,185,202,203,212,213,158,59,26,76,76,106,102,38,74,105,114,113,141,156,168,181,161,177,167,138,122,160,208,152,102,130,118,188,141,86,129,91,88,72,31,38,158,191,163,155,87,103,78,32,25,16,164,162,80,68,39,132,156,244,227,146,199,233,237,244,218,93,56,65,87,92,72,54,96,134,159,114,77,66,29,20,10,29,97,123,133,101,81,105,105,106,106,93,81,59,53,67,67,66,46,36,36,30,59,125,149,110,49,14,11,14,25,39,63,73,47,18,48,84,98,112,122,141,117,53,27,37,27,19,21,21,31,100,121,49,28,28,131,153,88,125,92,41,30,73,99,68,63,51,47,31,16,22,28,24,24,26,17,16,30,26,23,27,20,19,20,75,89,30,59,55,85,141,97,57,29,34,31,14,33,27,20,16,16,18,46,54,34,20,19,17,31,57,46,17,73,103,36,46,59,31,38,40,25,30,44,50,33,19,21,20,30,44,39,25,22,23,39,65,66,35,15,24,31,99,145,54,39,83,66,78,82,51,76,74,58,47,20,19,18,26,31,38,38,25,23,30,33,23,42,32,27,38,56,123,92,30,43,63,33,25,38,29,21,33,40,26,21,24,23,24,22,28,31,19,36,38,26,29,32,23,28,41,65,98,49,83,130,119,113,98,95,100,69,42,37,22,25,29,24,27,31,28,29,24,19,17,28,29,33,36,42,58,36,71,101,106,120,155,157,107,118,126,118,103,116,113,55,26,24,40,58,66,78,87,99,108,103,102,88,95,104,97,90,69,43,25,22,22,21,18,23,23,24,36,51,74,81,71,62,57,52,53,41,35,37,54,30,96,220,241,235,228,225,229,220,223,222,221,224,224,227,228,224,225,117,5,1,8,12,12,12,14,12,14,15,15,15,203,204,202,204,202,203,199,202,203,204,203,202,205,203,202,200,198,199,200,198,199,202,201,199,199,200,200,200,199,201,202,200,200,199,200,199,199,200,200,201,200,199,200,199,201,203,201,200,201,201,201,203,202,203,204,201,202,202,202,205,206,205,204,208,210,207,207,206,206,206,206,207,208,207,208,208,209,208,208,208,206,209,208,207,208,206,206,207,207,205,204,206,204,204,206,202,200,201,203,202,202,201,200,201,203,201,201,201,200,201,200,199,201,200,199,201,199,200,199,197,200,199,200,198,196,198,198,197,196,196,198,200,197,196,199,195,196,198,198,196,198,197,195,199,196,195,198,196,195,197,196,199,197,198,199,197,198,197,198,197,196,194,197,196,196,198,197,197,197,196,196,194,196,197,194,193,193,196,197,198,195,197,196,194,197,195,194,195,194,194,194,195,196,195,195,198,196,195,196,194,196,194,194,195,195,194,193,196,194,195,196,195,195,195,194,196,194,195,196,195,194,193,194,194,195,194,194,193,195,192,193,194,193,195,196,194,195,194,194,195,194,195,193,195,194,193,194,193,196,194,193,194,193,196,194,192,196,195,191,191,193,194,195,193,194,193,192,196,194,193,195,194,191,193,192,193,193,191,195,195,193,194,194,194,191,192,194,196,191,176,186,195,196,179,188,195,191,196,192,194,195,191,191,191,192,194,193,196,195,207,174,158,174,157,154,161,171,165,155,156,196,200,179,200,194,204,214,205,130,33,56,71,94,96,42,100,119,138,144,124,156,186,188,157,135,144,153,158,191,195,120,102,148,156,222,132,87,116,76,103,72,36,52,132,137,93,132,100,76,42,23,25,17,89,84,56,47,127,214,174,195,172,174,248,246,244,210,97,53,71,102,93,54,46,73,127,160,116,83,78,39,12,12,27,51,84,75,39,25,26,55,89,108,118,113,113,107,81,72,69,52,33,31,31,33,89,143,141,81,23,16,14,31,67,66,70,71,74,48,65,111,112,120,116,112,74,34,21,24,31,27,24,23,67,148,105,33,22,39,148,136,96,124,81,36,24,64,96,84,54,34,45,34,27,32,21,14,16,27,31,35,29,21,12,19,27,33,46,91,86,37,60,52,47,63,41,39,35,35,39,26,16,23,23,25,17,41,41,38,44,32,21,21,53,33,35,34,81,105,36,60,86,43,73,64,37,69,67,56,36,19,25,19,35,42,36,24,21,20,41,73,57,34,23,25,19,125,163,49,54,124,123,191,183,133,185,141,74,37,12,16,14,21,37,43,24,23,25,21,38,55,41,14,24,33,61,133,90,32,55,52,27,24,31,26,24,36,41,25,27,35,24,17,14,23,30,44,40,23,16,22,38,39,53,33,58,103,48,64,88,88,91,90,133,107,57,40,29,22,19,33,35,39,33,17,17,26,27,31,37,21,19,24,53,68,54,121,146,148,143,119,96,69,68,90,118,98,107,115,60,34,37,57,63,44,45,44,45,59,108,117,109,101,96,106,104,88,58,34,23,20,18,23,20,17,25,26,33,56,76,81,78,66,37,26,27,35,45,48,18,132,231,243,247,246,243,239,230,234,235,235,236,232,226,229,226,223,117,5,1,6,10,13,12,13,12,14,14,15,15,202,201,204,201,201,202,202,204,203,203,205,201,199,204,200,205,200,200,204,198,202,200,200,202,199,200,199,199,200,199,201,198,199,200,198,201,200,201,202,198,201,199,198,200,200,199,200,201,200,200,201,203,203,201,201,202,201,201,203,203,205,205,206,209,209,208,208,208,208,207,208,206,208,206,207,208,205,206,206,204,208,210,206,208,207,208,207,203,203,204,205,204,204,202,205,204,203,203,201,203,200,200,200,200,200,200,200,200,199,199,199,200,198,198,198,197,200,198,200,198,199,197,195,198,196,197,197,198,198,197,196,197,198,195,196,193,195,198,194,198,196,197,198,197,198,196,198,197,198,197,197,197,198,197,196,199,197,199,198,198,198,195,198,197,198,199,196,198,197,195,195,197,198,197,196,196,197,195,196,196,196,198,199,197,198,196,197,198,195,198,194,197,197,193,191,194,196,196,194,195,195,194,197,193,195,196,196,197,196,194,195,196,194,195,197,196,193,193,193,196,194,195,196,193,198,194,191,195,194,196,197,196,194,196,194,193,196,194,195,194,191,195,195,194,194,196,193,192,194,194,194,193,195,195,193,192,196,195,189,190,195,193,196,196,190,193,192,193,194,195,192,196,197,194,194,193,191,192,196,192,194,195,192,195,193,193,193,194,197,180,184,194,195,179,178,195,192,194,193,193,193,192,191,191,192,196,195,196,199,199,155,135,142,114,116,133,150,132,132,156,194,196,179,196,192,194,206,216,172,118,113,69,71,79,44,122,134,123,132,114,182,214,169,143,139,161,165,184,189,142,112,124,169,203,219,100,86,105,68,87,60,39,39,121,108,64,111,77,51,29,18,24,34,73,41,34,117,211,252,162,152,193,229,250,246,215,101,49,73,102,96,74,50,65,85,125,106,78,71,44,26,11,29,46,79,117,69,43,36,37,36,40,89,121,130,125,121,120,110,74,50,27,24,35,34,101,151,110,47,22,17,25,55,63,46,42,54,77,110,138,126,116,77,41,38,24,17,11,17,20,30,33,46,132,139,47,27,20,47,155,127,97,123,75,34,24,55,117,93,44,35,40,42,33,31,17,12,14,19,43,39,24,14,19,15,35,62,42,97,88,37,63,37,29,32,27,37,28,43,37,18,19,14,24,29,36,36,21,16,38,47,49,51,26,16,24,40,97,107,29,92,137,129,200,144,134,178,124,71,36,27,27,35,32,20,27,35,24,39,50,36,50,57,33,37,69,142,168,52,39,81,87,147,125,95,141,99,62,46,17,21,19,29,36,33,31,26,20,26,48,44,38,19,25,22,66,141,86,32,57,55,25,43,38,21,32,39,39,26,37,32,19,15,17,22,30,40,32,18,26,19,35,61,44,26,65,101,50,37,62,61,84,148,165,92,33,37,29,18,21,26,45,45,27,22,19,26,44,41,29,16,19,19,61,85,63,138,154,145,139,101,92,86,56,66,116,97,103,112,66,36,37,57,42,28,32,30,31,51,100,122,104,94,100,108,108,102,73,36,25,30,26,23,19,16,22,24,30,42,60,76,81,63,35,19,22,31,42,33,39,188,233,250,250,248,248,249,249,249,247,246,246,240,232,227,225,223,116,5,2,7,11,12,12,14,13,15,15,15,15,204,205,205,206,203,201,204,205,207,205,202,204,202,204,201,203,200,200,202,201,201,200,200,200,201,200,202,200,200,200,198,200,199,200,199,201,200,198,201,201,200,200,200,200,200,200,200,201,202,201,205,205,201,202,204,204,204,202,203,205,205,202,204,206,205,206,206,207,206,206,206,206,206,203,206,205,203,207,206,208,207,205,206,203,204,205,206,204,204,202,203,206,204,203,204,203,203,203,201,202,201,201,200,200,202,198,198,199,198,198,198,196,200,196,195,199,195,198,197,197,198,194,197,198,196,198,198,196,194,196,196,196,195,196,200,194,197,196,194,198,196,199,195,195,196,196,197,195,195,195,196,198,196,194,195,196,196,195,193,196,197,196,198,197,194,197,197,197,196,197,197,198,197,195,197,197,198,198,198,197,196,197,198,198,201,199,196,199,199,195,196,198,193,195,196,197,195,195,197,196,197,193,195,194,196,197,196,198,197,196,196,194,195,194,193,194,194,196,193,196,196,194,195,194,195,194,192,193,193,193,198,194,195,192,193,193,195,196,195,195,193,193,195,196,193,192,197,194,194,194,194,193,192,192,194,192,193,195,188,192,193,192,193,189,189,193,193,190,191,195,194,193,196,195,193,193,193,193,193,192,193,192,190,191,194,194,193,192,195,182,182,196,196,178,176,194,194,195,190,190,193,192,193,193,196,197,195,189,181,185,142,131,134,122,142,154,166,152,152,171,195,196,177,192,193,191,200,208,171,169,163,73,70,94,90,190,151,130,157,122,197,174,136,156,167,185,162,166,168,154,141,115,160,200,177,88,87,103,71,82,48,33,82,129,95,74,89,44,35,29,14,40,61,75,37,92,191,245,247,146,197,252,244,245,208,105,52,62,107,105,79,55,72,107,95,77,72,69,45,22,15,33,60,83,115,155,118,71,53,38,42,39,32,70,116,129,131,119,121,106,74,45,26,23,43,134,155,85,31,10,16,38,61,43,22,19,15,34,77,136,145,101,60,24,22,17,31,32,15,16,26,27,41,68,51,25,31,13,66,162,115,108,132,67,32,16,41,85,61,35,28,42,33,22,26,23,19,16,33,32,32,36,20,16,37,52,39,55,119,81,32,56,26,27,31,22,35,26,40,40,18,18,15,19,39,39,28,17,23,18,46,71,40,18,14,22,34,110,110,31,83,102,116,181,122,132,120,85,52,29,40,48,32,21,16,24,31,48,48,23,21,22,48,67,85,36,92,148,57,32,43,39,42,44,38,39,36,53,50,23,24,28,30,24,22,35,33,31,40,33,25,43,39,30,39,80,137,79,29,78,69,48,71,53,38,55,49,46,39,19,21,27,18,19,32,27,26,33,30,22,38,49,31,35,35,83,104,47,29,57,61,96,115,81,50,40,39,29,26,32,33,33,42,39,30,28,55,44,28,35,21,24,41,104,83,77,139,119,107,102,108,89,76,52,49,113,103,105,113,73,35,47,45,32,29,23,27,26,46,83,105,114,98,103,106,113,125,82,33,39,76,56,30,24,17,23,19,24,39,51,65,81,66,41,26,24,25,43,31,55,208,226,249,236,205,229,246,243,228,222,219,230,240,235,227,221,221,118,5,1,8,11,13,13,14,13,14,15,15,15,204,205,203,203,204,205,202,205,203,202,205,203,205,204,202,203,198,202,203,200,200,199,199,200,200,198,200,199,200,199,201,201,199,199,200,200,198,198,201,199,199,200,201,201,200,200,202,206,204,201,206,205,204,203,205,204,204,204,205,203,205,205,203,204,203,203,204,204,204,206,205,204,205,204,206,203,203,207,206,203,203,205,204,205,206,206,203,203,206,204,205,205,204,204,204,204,202,203,201,204,203,203,200,202,200,198,200,200,200,198,196,199,198,197,198,197,197,194,195,197,198,196,197,198,195,198,197,196,196,198,198,196,200,198,199,198,198,199,195,198,198,197,195,194,198,196,195,195,194,196,196,197,196,196,195,194,194,196,193,197,198,194,195,196,197,196,195,197,198,196,198,198,196,197,197,197,196,195,199,198,198,198,196,197,196,197,196,196,196,198,198,198,198,196,199,198,195,198,197,195,195,195,199,196,195,198,197,196,199,196,197,196,196,196,194,196,193,198,198,195,196,196,195,195,199,195,194,197,195,194,194,193,196,195,194,194,196,194,194,197,191,196,194,194,196,191,193,192,193,194,194,193,193,195,197,193,194,193,188,193,194,194,194,187,189,196,193,191,192,193,193,194,196,193,191,193,191,194,194,191,193,191,189,193,194,191,192,192,196,186,176,194,202,183,180,191,191,193,193,193,194,194,195,195,193,186,179,174,188,190,146,162,168,161,187,193,193,160,185,192,192,198,173,191,194,194,196,200,142,158,173,73,84,103,134,248,155,140,192,136,167,155,154,172,171,153,136,173,170,181,167,99,154,186,173,113,89,98,85,87,50,50,115,139,97,86,72,22,27,42,46,55,72,55,94,214,244,228,172,139,243,251,243,198,89,51,64,101,128,115,73,57,81,129,105,78,71,39,25,13,26,60,88,113,130,157,131,116,112,73,50,38,37,29,47,92,122,133,126,118,124,103,62,37,53,113,117,56,19,10,15,49,64,33,19,15,13,16,25,74,117,107,68,25,33,85,100,73,35,21,22,28,31,22,26,21,28,10,91,160,103,122,128,63,22,14,18,34,30,25,29,36,30,15,17,23,31,33,25,18,16,36,39,48,51,29,18,57,126,76,38,57,23,29,34,21,30,29,47,46,23,16,21,33,26,27,29,27,15,34,50,41,47,38,20,31,54,97,100,40,40,55,34,49,46,40,41,39,51,33,44,48,30,25,21,18,44,53,42,28,27,31,56,95,90,28,69,118,46,36,40,42,51,45,45,46,26,47,43,25,45,32,19,22,20,26,39,42,29,24,23,29,44,65,43,54,129,71,40,127,113,128,159,95,120,123,78,51,17,17,13,21,29,35,29,21,17,23,33,46,50,26,16,21,47,100,102,46,39,67,50,44,45,33,37,29,47,35,30,41,25,23,25,42,49,63,51,21,18,32,34,59,86,122,84,68,132,101,87,129,104,105,83,34,36,99,107,103,121,75,41,53,47,30,21,21,16,28,48,63,120,132,112,113,101,118,126,79,26,85,137,84,44,26,23,19,20,24,34,49,65,81,76,60,33,36,45,37,37,29,115,145,130,118,84,141,180,175,174,156,152,171,209,229,222,216,219,117,6,2,8,12,13,12,14,13,14,15,16,15,202,201,200,202,203,203,201,200,205,205,203,205,201,203,201,203,200,201,200,201,201,200,200,199,199,198,201,200,200,202,201,201,200,202,202,201,201,199,198,198,200,199,200,201,201,200,201,201,202,203,205,201,203,203,202,206,204,202,203,204,205,205,205,207,207,204,203,204,205,206,206,203,203,204,205,202,201,202,204,205,201,202,205,204,202,203,205,205,204,203,203,205,203,201,204,200,200,201,200,201,200,202,201,201,201,197,199,201,200,200,199,197,198,198,197,200,197,198,198,196,198,198,198,198,196,196,197,197,197,197,196,198,198,196,197,193,196,197,194,196,194,195,193,197,194,192,195,195,196,194,196,196,196,196,194,198,194,196,195,196,195,195,197,196,196,196,196,198,198,197,193,196,195,196,195,193,196,194,196,198,196,196,196,195,196,196,195,195,196,194,195,196,196,198,195,195,198,196,196,197,196,195,196,198,198,195,196,194,196,195,195,196,194,198,197,195,194,198,196,196,195,193,195,194,194,197,194,196,195,195,195,191,195,195,194,193,193,193,194,195,193,194,192,193,193,193,192,192,194,193,191,191,192,193,194,193,193,191,190,194,194,192,191,188,193,192,193,194,193,192,192,193,194,194,193,191,190,191,192,194,192,190,192,193,194,191,193,191,192,189,176,190,198,188,182,187,192,194,191,193,196,193,192,185,178,176,181,186,202,191,158,172,163,165,181,181,171,157,194,192,190,198,174,190,194,191,195,194,143,166,166,61,61,89,134,220,121,116,153,115,160,169,183,171,134,122,151,184,175,187,141,121,198,195,188,134,91,117,95,93,61,66,120,90,81,101,57,17,42,81,63,76,47,76,210,253,252,178,171,178,246,248,210,100,36,65,101,121,121,83,69,60,92,113,89,79,41,24,18,22,49,87,112,118,119,137,130,116,121,111,98,59,34,40,31,37,73,118,141,147,147,141,142,116,68,37,40,31,20,14,13,46,65,41,28,21,12,19,15,26,80,122,88,33,122,188,139,72,29,24,36,46,35,27,25,22,27,27,115,157,101,128,121,52,20,12,15,18,22,25,33,36,22,15,14,23,41,29,19,15,11,24,56,62,26,16,15,29,111,77,43,67,23,45,50,28,48,39,47,39,26,33,30,25,16,11,29,33,34,38,30,17,33,60,41,79,56,90,105,34,39,36,38,42,29,45,37,33,58,49,26,29,52,49,35,61,74,50,63,73,66,68,117,113,127,92,131,130,33,101,51,61,69,62,62,74,55,59,63,57,58,51,48,46,53,39,42,42,31,23,21,28,50,59,34,50,124,73,36,108,96,139,173,121,158,155,80,42,21,13,16,19,36,37,23,18,17,17,34,50,43,21,26,21,43,113,101,48,43,63,36,24,34,24,31,35,33,46,42,28,23,19,20,34,64,59,33,21,18,22,58,66,74,124,71,56,100,83,108,130,139,136,68,37,28,95,114,93,114,87,44,47,52,34,24,25,26,39,44,59,113,140,126,126,112,110,107,56,24,122,164,90,55,33,21,19,22,27,35,49,62,76,77,68,48,42,41,49,50,43,47,25,36,54,34,50,105,131,134,113,89,101,149,189,206,214,220,118,6,2,9,12,13,13,15,14,15,15,16,16,203,204,202,202,202,202,202,203,200,203,205,201,204,201,201,201,200,201,201,199,202,201,200,200,201,202,201,201,201,202,202,203,201,201,202,199,203,200,200,200,200,201,202,203,201,199,200,200,200,204,203,202,202,200,203,203,203,205,203,205,204,202,202,203,204,203,204,204,202,203,204,203,202,202,202,204,205,202,202,202,203,201,202,201,200,200,201,204,203,201,202,200,200,200,200,200,200,200,201,202,199,203,200,200,199,198,201,199,201,200,198,199,200,198,196,198,197,198,199,196,199,198,198,198,198,198,193,196,196,197,193,195,198,193,196,195,196,194,194,195,193,193,193,194,195,196,194,194,194,195,195,194,193,195,194,194,199,196,193,196,195,195,196,193,194,196,197,195,196,196,195,196,195,194,194,195,198,195,196,194,195,196,194,196,195,194,196,195,197,197,196,193,193,195,196,198,196,194,196,195,195,196,197,195,193,197,195,196,198,194,198,195,194,196,195,195,196,196,196,193,194,195,194,194,195,195,196,194,192,193,196,193,194,195,193,193,194,193,193,194,190,194,191,193,196,191,193,193,192,192,191,192,194,191,191,191,190,189,190,194,193,191,188,189,193,192,193,191,190,193,193,195,192,193,195,192,192,193,193,191,191,194,193,190,193,190,193,191,190,193,180,184,198,187,183,189,190,195,197,193,190,181,173,177,182,184,191,191,208,179,128,136,114,120,148,133,136,152,199,187,181,198,170,188,194,189,195,193,159,194,174,55,53,69,122,174,74,70,134,139,146,173,162,140,139,145,190,173,142,179,136,160,227,167,171,119,91,130,90,90,64,68,97,49,60,89,52,15,50,76,78,64,61,177,250,250,199,175,234,208,246,234,99,49,57,99,118,114,73,57,62,71,85,84,77,53,24,12,24,47,83,113,117,116,107,117,119,107,106,105,121,107,75,56,47,49,36,47,98,135,159,165,152,151,127,79,47,27,19,16,12,27,51,49,46,33,14,21,18,20,42,103,113,101,183,148,48,22,23,51,68,61,55,41,28,30,31,45,142,141,106,141,110,46,17,15,16,16,20,23,30,42,31,16,23,30,29,25,24,22,12,37,45,45,38,22,14,42,127,71,62,92,62,107,83,61,100,70,55,35,21,43,29,20,17,14,16,42,44,27,17,19,18,55,73,164,193,135,106,33,32,43,46,51,39,48,44,35,56,48,53,52,74,101,105,119,119,118,143,161,177,182,188,191,180,183,212,187,161,184,171,160,157,149,162,160,150,150,127,132,137,127,139,124,103,95,70,64,69,53,53,69,45,45,26,59,135,63,28,60,49,43,51,42,50,52,56,51,28,21,20,28,29,25,28,24,16,33,30,28,43,41,32,37,66,102,96,43,50,56,25,29,34,23,28,31,43,37,28,33,24,23,29,37,39,52,41,26,25,50,63,41,79,138,79,39,57,61,66,117,127,87,52,31,27,97,120,93,120,91,41,42,51,41,29,24,23,31,41,42,59,83,93,110,105,97,92,38,93,180,162,118,84,59,33,23,23,26,37,48,61,69,76,75,52,35,39,57,69,67,64,37,33,40,40,81,111,107,101,84,73,62,95,166,198,212,220,118,6,3,9,12,13,12,14,13,14,15,15,16,202,206,201,200,202,203,204,204,204,200,202,202,200,201,202,204,203,201,200,200,201,204,203,200,202,201,202,201,200,201,200,202,200,201,201,200,199,201,203,199,202,200,201,205,199,200,204,200,200,202,202,201,201,201,202,200,201,201,202,202,200,203,201,202,201,200,204,201,202,200,203,201,200,202,204,201,202,201,199,201,199,200,200,199,201,198,198,198,200,200,198,200,199,197,198,198,201,199,200,200,199,200,199,200,202,199,200,199,199,202,200,201,198,198,201,199,198,198,198,196,198,199,198,198,193,198,198,196,198,195,198,197,196,198,196,194,194,196,193,196,194,194,195,195,196,195,195,195,196,194,196,196,196,192,191,196,195,195,193,194,195,193,194,196,195,193,192,194,194,192,194,195,192,194,194,194,197,193,196,195,193,194,195,194,192,195,195,195,195,195,197,196,195,193,194,193,196,193,194,194,192,196,196,195,193,196,196,195,198,193,193,195,196,195,195,193,193,193,191,195,196,194,195,193,193,195,194,194,193,193,193,193,195,192,192,193,193,192,193,193,193,193,195,193,193,194,193,194,193,193,192,191,192,193,191,194,191,187,191,191,193,190,190,190,194,191,192,191,187,191,193,193,193,194,194,191,190,190,191,191,191,190,191,191,190,189,189,193,191,190,181,181,195,190,186,191,194,194,188,179,175,174,179,190,191,190,192,195,203,150,115,121,118,141,154,144,136,167,206,187,182,194,173,187,194,189,194,196,171,201,184,101,94,102,96,99,35,77,190,171,148,142,132,151,156,191,190,122,150,193,120,178,203,116,177,122,95,118,66,83,61,65,67,33,37,65,45,29,53,62,49,61,159,249,252,200,163,215,249,211,213,122,35,66,92,122,111,69,63,71,81,83,79,69,47,35,15,33,51,78,114,118,122,110,103,111,106,104,100,95,108,120,120,133,70,37,49,42,33,63,125,152,162,157,150,144,105,68,51,33,18,13,22,34,37,28,22,25,17,18,27,67,112,143,178,99,27,19,33,95,117,97,75,57,33,34,39,69,148,133,108,144,101,29,17,15,14,21,19,23,29,49,40,29,34,16,14,21,29,30,36,36,19,21,48,41,43,101,145,50,99,145,136,231,153,153,202,112,60,29,23,23,22,33,19,15,37,33,32,31,25,16,44,50,39,194,113,85,112,19,39,36,42,45,42,51,54,57,122,93,122,151,181,200,206,213,164,209,218,210,203,197,203,182,186,188,201,193,185,201,186,181,184,195,204,205,201,205,191,189,194,198,200,192,148,179,175,165,162,149,136,120,89,65,41,109,149,51,23,37,33,34,31,38,35,24,41,40,24,34,37,25,14,17,27,24,41,35,22,23,35,48,53,61,42,81,97,40,55,59,27,43,41,24,43,37,38,36,17,26,27,33,40,27,18,27,41,44,60,54,31,14,69,130,76,39,55,48,39,62,63,45,38,29,24,96,125,92,115,104,47,25,35,38,30,23,27,26,26,26,24,42,51,72,89,103,97,99,149,168,137,124,124,84,55,32,26,28,33,53,60,71,81,78,59,37,35,39,48,58,61,41,59,89,105,120,108,87,80,76,79,106,156,199,216,217,220,118,7,2,8,12,14,12,14,13,14,15,14,14,203,206,206,206,203,202,202,201,203,205,201,201,202,201,202,201,203,202,203,203,205,203,202,203,200,202,202,202,202,202,200,200,203,202,204,203,203,202,202,204,205,202,204,202,201,201,201,202,200,200,198,199,201,200,202,200,199,201,198,203,201,203,200,200,201,201,203,201,201,200,202,200,200,203,202,202,200,199,201,202,201,199,200,198,199,199,198,199,198,199,200,199,199,200,196,200,200,198,196,197,198,199,199,200,199,197,199,199,200,201,199,200,201,198,199,199,198,200,200,196,200,198,196,197,196,197,196,198,196,198,198,196,197,195,198,197,197,196,196,197,198,197,194,196,193,194,197,195,195,197,195,194,195,196,194,192,195,193,191,196,197,194,194,195,195,193,192,192,192,194,195,196,194,193,194,195,194,194,195,192,197,198,194,196,193,195,197,193,194,194,195,196,195,194,195,195,193,195,194,192,192,193,194,196,194,196,194,193,195,193,193,193,193,195,195,191,194,195,193,194,193,193,193,192,195,193,193,195,193,194,193,192,193,193,193,193,194,189,192,194,192,194,194,194,192,191,193,191,190,191,193,192,190,189,194,192,187,190,193,192,191,189,190,191,193,195,191,190,190,189,191,191,191,192,191,193,193,191,191,189,192,190,189,193,193,191,191,190,191,194,184,179,196,194,189,192,181,178,173,175,182,187,192,196,191,191,195,200,195,131,136,168,165,185,188,165,171,194,208,189,181,200,175,184,197,191,198,191,179,202,195,123,125,158,125,73,46,139,232,188,131,144,163,168,176,184,168,138,190,200,95,161,163,139,210,121,110,119,68,76,57,61,56,19,29,57,43,45,66,54,45,145,241,250,231,156,191,232,250,194,95,55,53,104,110,115,68,68,106,98,87,83,75,46,30,16,29,57,83,112,122,118,116,101,101,118,106,101,105,87,104,109,117,141,78,39,49,40,43,34,34,78,128,160,163,154,137,141,151,100,53,36,18,12,19,22,20,22,17,37,59,55,84,131,160,91,32,13,69,163,134,141,120,59,36,33,38,94,159,112,112,141,79,30,21,12,19,25,20,25,36,43,40,43,27,13,17,14,23,47,39,18,14,17,25,72,73,77,128,51,57,60,77,141,76,77,99,60,60,39,15,17,15,32,31,36,32,17,13,30,36,45,56,51,36,52,62,110,94,28,55,55,57,70,86,123,148,177,200,202,224,222,225,212,194,187,183,181,184,170,142,144,139,125,119,122,131,122,125,133,127,131,141,155,158,162,179,179,170,172,165,164,162,162,172,184,188,170,177,174,185,188,170,169,147,170,159,67,57,61,46,49,39,36,44,31,40,38,21,45,34,22,26,13,21,42,45,36,19,20,22,45,70,53,32,80,97,45,73,78,43,82,69,49,77,51,46,34,17,24,29,47,36,15,14,15,24,54,63,31,18,11,41,119,85,42,56,45,27,39,41,31,27,26,24,98,132,94,121,107,54,24,19,27,25,30,23,27,45,57,46,34,37,66,116,125,131,116,90,60,53,59,74,97,82,56,27,24,35,43,61,65,77,78,61,42,29,44,60,55,55,90,133,141,124,108,92,76,76,112,171,206,230,243,229,225,224,116,6,1,8,11,12,12,14,13,15,16,15,16,203,206,205,205,203,202,202,200,201,201,204,204,202,200,201,204,201,199,202,201,202,205,203,200,203,200,203,206,202,204,202,202,205,204,205,205,203,206,204,201,203,202,200,200,199,201,204,202,200,199,199,200,200,202,199,200,201,200,201,198,199,201,199,200,200,201,201,199,201,200,199,200,202,199,200,200,201,201,200,204,201,200,202,201,201,198,199,201,201,199,199,199,199,200,200,197,200,198,199,198,198,198,198,199,199,199,198,199,198,200,197,197,200,200,199,198,198,199,199,198,199,196,196,197,197,198,195,195,197,196,196,197,196,195,196,196,195,195,194,198,196,193,195,194,196,195,195,195,192,193,193,193,194,195,194,196,194,193,193,193,192,193,194,194,193,194,193,193,194,192,193,195,194,193,193,193,194,193,195,194,193,195,194,193,193,191,194,195,194,194,191,194,193,191,194,192,194,193,191,199,196,191,191,196,194,193,191,193,196,194,194,193,191,191,193,194,192,194,196,195,193,191,192,192,193,189,191,194,193,193,193,194,193,195,192,192,191,192,193,195,194,192,194,192,194,195,193,191,191,193,192,193,193,194,192,192,188,187,194,194,189,189,192,190,193,191,192,194,190,188,189,191,190,191,193,195,193,191,194,190,190,190,190,191,191,191,189,193,192,193,194,182,194,188,174,174,170,179,184,188,193,195,192,195,191,192,193,203,177,122,145,163,173,181,165,158,183,204,207,190,179,196,178,183,196,188,194,193,182,193,192,125,130,194,153,118,94,171,236,160,137,155,187,159,152,190,167,162,211,151,64,152,162,182,208,96,121,130,97,98,80,77,41,9,32,92,65,71,59,37,135,224,249,249,157,173,224,235,249,124,48,61,90,124,108,74,62,111,129,94,74,77,50,26,14,24,46,80,104,116,124,112,107,103,113,144,118,98,99,92,105,96,104,124,81,78,70,41,39,32,35,31,48,95,131,153,146,151,161,163,145,105,64,34,23,12,21,17,22,53,50,40,48,91,139,105,57,19,26,55,24,50,108,80,37,33,43,118,154,110,116,131,68,26,30,23,37,37,38,42,42,52,34,24,29,22,17,19,33,33,25,24,21,15,42,69,59,100,124,54,36,38,29,48,30,37,41,28,60,39,12,17,17,21,48,44,27,25,32,46,70,88,93,86,89,137,98,156,149,120,177,163,191,198,201,227,218,213,204,169,173,162,155,143,128,109,119,135,136,134,134,129,132,129,138,138,141,146,146,154,156,151,139,148,142,165,181,178,184,186,178,170,169,170,161,156,154,128,136,143,153,162,158,168,167,180,174,152,174,158,139,117,85,63,57,57,49,58,42,33,32,32,31,26,41,31,24,28,26,24,34,44,40,45,49,109,103,36,118,105,125,221,119,141,166,75,53,29,23,30,30,31,30,24,18,23,35,42,38,39,38,12,80,141,78,51,60,33,29,35,29,30,27,26,28,100,136,103,115,113,60,27,18,24,28,29,27,40,80,85,80,60,36,117,150,133,108,56,44,24,24,26,42,95,102,62,40,28,29,32,46,53,56,53,44,104,151,148,140,131,137,150,148,118,95,82,73,99,155,210,239,246,246,238,229,224,223,115,4,2,7,11,12,12,13,12,15,15,15,15,201,206,205,200,204,201,202,202,203,200,200,203,201,199,200,201,201,202,201,203,203,202,203,203,201,204,206,206,206,205,205,203,204,206,203,202,204,202,202,199,198,198,199,199,202,202,199,201,200,199,201,200,200,200,202,201,199,200,198,200,199,200,200,201,202,200,200,198,199,200,201,201,201,202,200,201,202,203,200,200,199,200,204,200,202,201,201,202,201,200,199,199,201,204,200,200,200,199,200,198,198,199,199,198,196,199,198,196,198,198,196,198,198,198,199,198,198,198,198,197,196,198,197,196,198,196,194,196,195,198,198,198,197,196,195,196,196,193,195,196,194,191,193,198,195,193,196,195,197,196,194,194,194,196,195,193,194,193,193,195,193,193,195,193,195,193,192,194,194,193,193,194,193,195,193,191,193,191,193,190,193,195,190,194,193,194,194,191,193,192,193,194,191,190,194,194,191,193,196,194,195,192,193,193,189,193,192,194,193,191,193,193,192,193,193,192,191,192,193,193,192,192,194,193,192,192,192,191,193,194,194,193,192,194,193,191,194,192,193,193,190,191,192,192,193,193,192,192,192,191,192,191,193,193,194,190,188,193,191,191,188,189,193,192,193,193,189,192,193,189,190,195,193,193,192,193,198,193,193,192,193,190,189,190,190,195,193,192,196,199,194,173,172,169,163,179,184,192,193,193,196,194,195,194,190,193,195,196,155,105,122,123,143,153,122,139,189,201,205,191,177,199,177,185,199,191,198,193,188,189,189,137,134,150,119,97,81,146,196,187,163,158,155,128,174,198,177,173,171,112,60,159,180,198,166,73,130,135,111,124,115,73,23,21,129,204,118,78,56,106,216,246,239,177,161,224,236,232,179,60,75,98,105,116,64,73,107,134,118,67,71,54,25,12,18,43,77,105,118,128,119,105,102,98,112,156,141,101,94,84,96,100,116,122,83,98,89,52,44,31,37,36,32,35,49,89,126,140,150,153,159,171,160,110,64,40,27,23,17,22,24,22,25,34,86,115,87,49,21,24,26,77,114,79,42,20,46,138,153,104,122,118,53,25,47,51,60,64,60,59,54,43,24,12,23,34,31,35,23,15,23,29,26,48,51,26,30,97,130,52,37,50,54,55,44,61,45,35,52,44,26,21,32,55,61,69,71,65,88,123,132,151,168,176,193,200,186,205,189,202,226,196,200,184,174,169,149,138,125,123,118,123,139,144,150,140,145,146,141,147,150,144,132,130,131,129,127,120,110,104,98,99,90,89,89,99,105,108,124,136,143,145,156,152,142,155,159,162,165,162,166,155,153,147,137,143,140,151,185,186,185,184,169,168,146,123,125,102,84,67,47,56,77,71,43,27,21,26,33,40,44,31,17,28,65,126,105,33,89,93,132,190,104,140,149,65,60,36,36,37,20,21,23,29,28,42,34,21,23,45,59,63,122,157,74,46,61,29,24,37,25,30,30,26,29,93,126,99,121,115,75,33,22,34,35,34,35,43,60,95,123,74,93,174,150,92,51,32,32,21,21,25,67,135,113,71,42,26,22,29,50,50,76,114,177,214,204,196,174,160,141,124,99,74,64,84,147,206,239,248,249,239,236,231,225,222,219,115,4,1,7,11,13,12,13,13,14,14,15,14,204,206,206,206,203,200,203,205,202,203,202,200,201,202,202,202,203,201,203,203,206,205,204,205,208,208,205,206,206,207,209,205,206,205,205,205,202,204,203,203,200,200,203,200,201,200,200,200,198,201,201,201,200,202,205,203,202,203,206,204,205,204,203,204,201,205,201,203,202,200,202,202,203,203,203,204,202,202,201,203,202,200,203,201,203,201,201,202,199,200,201,201,203,201,201,200,200,200,199,199,200,198,200,199,198,197,199,199,194,196,197,196,196,196,194,197,198,196,193,194,196,197,196,194,195,197,197,195,195,195,195,195,195,195,197,194,194,195,194,195,194,193,196,193,194,193,193,195,195,194,194,194,193,193,193,195,192,193,194,194,195,195,195,195,194,194,193,194,196,194,194,198,192,192,195,193,192,193,193,193,193,193,193,193,193,193,192,194,191,192,193,193,196,194,196,193,196,195,191,195,193,193,191,191,194,192,193,192,192,193,191,193,193,194,194,191,193,191,189,193,191,194,195,193,195,194,195,194,194,192,193,194,193,194,192,193,194,191,192,194,193,191,193,193,191,192,193,192,192,193,193,192,191,192,192,188,189,192,193,189,189,193,195,193,191,193,192,191,194,192,188,193,193,191,192,194,196,195,192,189,193,193,194,193,193,195,198,196,192,184,174,162,169,178,181,192,193,194,195,194,191,191,191,193,190,196,197,193,145,107,135,146,163,156,124,150,199,203,203,193,176,200,184,184,203,193,200,198,191,186,192,146,99,96,71,68,46,65,123,185,160,123,153,146,194,191,154,164,174,137,63,121,163,173,149,95,125,124,109,127,99,48,7,58,177,190,115,72,128,200,238,206,155,179,210,247,234,140,73,38,104,115,105,71,57,109,127,120,77,66,50,25,20,19,39,79,105,121,125,117,107,104,97,100,95,136,140,103,101,84,112,131,139,123,87,87,59,53,49,44,45,27,36,36,31,40,54,100,133,151,154,165,169,163,149,119,86,45,31,22,14,14,21,18,31,75,102,84,76,71,108,168,130,60,33,18,54,151,139,103,127,107,46,19,30,38,45,42,41,46,46,43,20,15,13,30,48,29,19,16,18,26,45,50,24,21,12,53,110,61,38,57,58,56,47,49,42,34,53,51,50,62,80,105,125,117,130,154,187,205,199,200,196,201,195,184,170,169,147,155,148,115,121,107,114,128,133,146,136,136,140,145,147,145,137,108,101,81,63,53,45,41,33,29,33,39,33,34,22,24,30,29,29,27,24,28,33,27,29,37,39,37,39,47,53,84,88,103,100,128,141,147,152,156,150,147,141,137,139,142,154,154,169,177,177,172,168,178,160,159,143,141,147,116,87,60,52,41,61,60,42,27,22,16,60,137,103,37,49,41,34,56,38,44,48,36,55,48,43,29,17,24,19,29,46,33,19,19,15,37,79,77,118,152,66,52,64,27,41,50,31,35,35,24,32,103,127,102,110,112,78,37,29,41,54,56,37,37,20,52,121,104,155,177,94,58,35,27,23,20,41,61,141,175,103,61,33,32,20,97,207,214,215,189,172,173,159,148,132,105,84,77,67,78,133,197,239,247,250,244,234,229,226,226,226,219,219,117,5,1,7,11,12,11,14,12,14,15,15,14,203,208,206,203,207,203,203,203,205,206,204,203,203,202,204,203,205,205,204,206,206,206,206,208,207,210,209,209,208,206,207,207,206,206,205,205,205,204,203,204,204,205,205,200,202,201,201,206,201,202,203,203,205,205,206,204,204,206,207,207,207,205,209,208,207,206,207,207,206,208,208,206,206,206,206,207,204,205,204,204,205,203,205,202,205,204,202,203,202,202,205,201,200,202,198,200,200,200,200,198,201,201,200,200,198,200,199,199,200,197,198,199,198,198,198,196,197,198,198,198,195,198,195,194,197,194,197,194,194,195,193,194,194,195,194,194,193,194,194,195,193,195,194,194,194,193,195,193,194,193,193,193,192,193,193,192,196,193,191,194,194,194,191,194,194,191,193,193,193,193,194,195,193,193,194,193,194,191,193,191,191,194,193,194,192,192,193,194,194,194,193,193,194,194,196,194,193,192,194,193,195,193,195,196,193,198,194,194,194,194,195,191,194,194,192,195,194,194,194,194,194,193,193,194,195,194,194,196,193,191,195,196,193,196,196,194,196,195,193,192,197,196,196,196,191,194,193,194,193,193,193,192,193,194,193,183,191,193,189,190,191,194,192,191,192,191,192,194,193,194,190,190,193,191,193,192,194,193,193,193,192,194,196,198,198,195,187,177,173,173,177,177,181,193,193,199,198,193,196,195,191,190,192,192,192,201,198,193,145,134,181,187,203,174,152,185,208,207,205,196,179,207,189,187,203,196,202,201,194,179,176,110,73,92,88,74,56,61,84,136,136,139,162,174,193,135,148,182,186,180,52,72,160,179,182,123,121,123,103,121,89,26,8,45,114,123,66,127,232,240,214,146,166,229,234,246,139,59,58,54,116,108,67,67,102,136,111,84,76,44,21,15,23,38,66,106,122,116,113,109,101,110,118,118,69,72,108,99,100,104,137,142,141,127,71,47,47,57,55,57,46,23,19,26,35,35,38,38,60,110,134,151,167,154,156,163,168,148,93,56,37,31,21,12,24,32,57,85,112,146,166,139,70,33,26,16,73,160,124,108,131,91,38,10,16,16,25,25,21,31,38,45,27,15,27,29,30,36,27,16,19,38,37,35,24,23,15,56,118,63,35,33,21,27,23,29,22,40,73,80,95,121,160,182,184,193,200,212,222,213,198,187,177,162,142,136,126,122,109,122,125,117,125,121,127,133,137,125,95,83,61,41,46,39,37,24,18,21,22,19,23,24,15,17,19,21,21,29,25,32,30,24,17,19,27,26,31,25,30,32,27,21,16,24,20,24,23,20,28,29,36,49,59,76,93,104,117,118,125,133,142,151,159,162,148,151,159,159,167,172,174,168,178,174,156,159,134,139,118,85,81,60,38,45,57,108,110,43,38,41,48,45,33,49,38,30,53,41,33,37,28,23,30,43,33,24,24,19,19,40,61,60,126,170,65,63,84,50,94,89,53,72,65,27,46,126,132,112,110,108,90,40,40,66,69,57,50,47,19,70,145,128,158,126,50,41,27,22,18,29,45,71,115,102,63,47,28,28,28,149,245,242,220,160,127,116,117,115,104,93,67,83,140,200,242,249,250,249,236,233,231,225,224,222,223,223,222,117,4,1,7,11,11,11,14,12,15,15,14,14,207,207,206,205,206,205,205,204,200,204,206,204,205,202,203,203,202,204,202,204,205,204,208,205,205,209,208,206,207,203,206,203,202,203,207,206,206,209,205,204,207,205,204,203,200,205,204,203,201,202,202,201,204,204,204,205,204,200,202,204,207,207,205,208,207,206,205,207,205,207,209,206,208,206,205,206,205,205,203,205,203,205,207,204,205,203,205,202,201,202,200,199,201,200,200,200,199,202,199,196,198,198,199,198,200,199,198,198,197,198,198,197,199,198,198,197,197,198,198,197,197,196,199,198,196,196,195,194,194,194,193,195,195,196,194,192,195,195,194,193,194,193,193,193,195,194,192,194,190,191,194,191,194,194,194,195,190,192,193,192,193,192,193,192,191,189,191,194,194,191,191,195,193,192,195,193,193,193,193,193,194,192,192,193,193,196,193,192,192,195,196,194,195,193,192,190,194,196,192,194,194,194,193,191,195,193,195,193,193,195,194,195,193,192,194,191,194,194,193,198,191,194,194,195,194,191,197,191,192,192,191,194,191,194,194,193,196,193,196,197,195,193,191,196,194,193,194,192,194,194,194,194,193,196,189,188,196,191,189,190,191,192,192,194,191,192,195,191,193,193,193,190,191,194,190,194,193,193,198,194,194,195,194,192,184,175,174,177,181,189,199,196,190,194,193,200,200,196,197,194,196,198,196,196,196,204,193,178,135,139,188,198,201,173,174,200,210,210,208,199,179,204,194,186,207,199,204,203,197,174,159,102,57,80,95,95,73,78,92,149,173,135,169,184,164,144,181,184,200,188,55,131,204,180,203,133,122,134,90,107,68,62,71,88,127,91,60,148,248,219,147,160,220,250,246,159,52,63,88,83,110,74,57,99,134,131,84,78,44,19,14,23,49,63,95,115,115,117,103,101,107,125,125,110,38,41,88,85,106,97,116,110,105,103,44,45,76,81,95,86,48,31,19,19,45,44,37,34,30,37,59,102,144,157,150,152,159,171,176,149,119,76,49,39,27,23,23,36,53,56,56,51,31,25,27,13,79,159,113,113,137,86,29,11,22,30,32,39,54,60,62,53,35,32,31,18,21,27,39,34,33,31,19,23,38,38,47,122,128,53,38,33,34,43,52,68,66,89,134,165,184,198,208,193,181,184,172,174,170,160,141,139,137,134,133,139,146,112,142,143,124,110,98,70,56,38,29,36,26,27,21,23,31,26,24,16,17,15,18,20,20,23,18,18,15,18,18,23,26,28,23,15,21,16,18,24,24,32,32,21,19,22,19,15,20,21,21,23,23,19,20,27,28,31,26,24,32,53,60,72,93,107,126,130,144,147,146,157,155,155,142,141,162,165,161,168,169,172,173,153,156,130,101,110,98,123,89,32,46,50,60,61,61,63,55,39,49,34,22,34,40,51,40,29,21,22,29,29,42,39,26,29,105,157,53,99,136,110,208,150,140,166,80,36,65,146,140,120,107,107,98,39,52,63,45,35,45,43,23,128,169,135,132,62,38,39,21,22,19,21,32,43,52,50,39,36,24,28,20,125,193,159,160,118,99,99,111,122,121,128,165,219,250,250,251,251,241,231,231,229,222,223,225,223,225,225,222,116,4,1,6,11,12,11,13,13,13,14,14,14,203,207,208,205,205,204,204,205,203,204,203,202,204,206,204,202,203,200,202,202,202,205,207,205,205,205,204,205,205,204,205,207,206,206,207,208,210,208,206,206,207,206,206,206,206,204,203,203,200,204,203,204,202,201,202,202,204,203,202,204,205,203,205,204,204,204,206,205,204,205,204,205,207,205,205,206,202,206,205,205,207,202,205,204,204,205,202,204,203,202,203,201,202,200,201,202,199,199,202,199,198,199,198,198,196,201,197,197,199,198,199,196,198,199,198,197,197,196,196,195,195,197,196,197,198,196,196,196,196,198,195,196,195,193,197,198,196,196,197,195,191,193,194,195,193,192,195,194,195,194,194,195,192,193,196,193,196,193,191,191,193,193,190,194,193,192,194,193,192,194,194,193,193,192,191,191,194,194,193,192,195,195,195,193,194,193,193,194,192,196,192,194,191,193,194,193,195,191,194,191,193,191,193,193,191,194,192,193,193,195,195,193,194,193,193,194,193,193,192,193,194,193,193,193,193,194,191,194,193,193,196,192,191,195,195,194,191,191,194,189,194,194,192,194,191,194,193,193,193,191,191,192,194,192,187,186,193,188,186,191,192,193,193,194,191,189,191,193,192,191,190,188,190,191,193,193,195,195,197,198,191,190,180,172,173,180,187,192,198,200,202,200,196,197,194,198,200,197,195,198,198,198,202,200,203,203,173,141,106,118,160,170,167,154,186,204,200,208,204,201,182,206,195,184,207,200,202,206,200,162,160,139,64,78,109,100,76,71,105,184,204,146,166,168,159,177,202,152,184,167,67,209,216,162,212,125,116,129,81,84,53,109,155,185,181,102,59,122,205,128,136,214,246,248,174,68,57,90,113,80,63,53,88,133,128,96,70,44,21,11,27,56,78,100,117,122,116,110,105,111,117,135,139,95,24,54,92,89,104,87,103,121,131,107,66,89,108,97,106,89,60,44,19,21,51,62,56,32,21,28,32,33,59,98,129,142,143,146,153,168,173,161,140,110,75,49,34,24,24,18,19,23,19,23,23,22,92,150,107,122,128,72,25,14,26,34,32,50,98,97,68,52,43,41,27,16,17,18,43,59,49,36,38,59,68,106,118,139,115,50,77,97,125,146,158,185,193,205,205,192,186,178,165,151,137,127,137,128,133,137,137,136,139,141,132,124,107,92,60,51,41,25,21,23,37,33,33,31,16,20,27,25,27,18,16,19,16,21,15,21,21,16,22,19,18,19,17,19,19,25,30,20,19,17,14,22,24,23,27,21,21,18,20,19,16,22,19,21,21,20,19,21,25,34,35,24,27,32,32,27,28,30,35,45,59,89,111,124,131,141,147,142,150,145,134,139,132,142,147,154,160,159,155,163,146,152,99,36,46,35,43,48,41,45,39,36,51,35,21,26,51,61,48,29,21,21,27,49,46,26,23,11,64,130,63,80,86,84,147,103,112,123,70,35,81,155,139,126,107,108,102,45,51,59,39,24,28,26,68,165,155,107,73,37,31,34,29,29,24,21,27,27,29,30,31,35,51,75,106,160,137,107,114,95,98,115,141,137,153,226,249,249,251,251,249,241,233,229,227,225,223,222,224,227,228,227,224,115,4,1,6,11,12,11,12,11,14,14,15,14,204,206,204,203,206,203,201,202,202,204,206,201,203,203,201,201,202,204,202,202,204,204,207,206,204,205,205,204,205,205,206,205,206,204,207,205,206,207,206,206,205,204,203,207,202,205,204,205,206,203,205,204,201,201,204,205,205,205,206,202,203,205,202,204,202,202,207,204,202,205,205,203,203,204,203,202,203,203,203,203,203,205,202,201,201,199,202,202,202,202,200,201,201,199,198,198,198,200,199,199,199,197,200,197,197,197,196,199,197,198,198,196,198,193,198,196,194,197,196,197,198,198,197,197,195,194,197,197,196,194,196,196,194,197,195,194,197,193,196,195,194,194,192,194,195,194,193,198,196,194,196,192,193,193,192,193,193,192,191,193,191,193,193,191,194,193,193,194,191,191,194,195,193,191,194,193,191,191,194,192,192,193,193,193,192,193,193,191,191,192,192,190,191,192,193,190,189,192,192,193,191,191,192,192,192,190,193,192,192,193,191,192,190,192,194,191,194,191,189,195,191,192,192,191,194,189,192,193,191,193,192,193,191,191,192,193,193,191,192,191,190,190,191,191,190,193,193,190,191,191,193,190,190,191,183,189,193,187,190,192,190,189,190,189,190,190,192,188,190,190,189,189,188,194,194,194,195,194,191,188,182,174,177,181,189,195,200,200,201,202,203,201,199,199,193,200,199,196,199,199,199,199,200,199,204,196,171,130,101,122,152,155,131,150,203,205,195,201,203,202,180,204,196,181,205,199,202,205,189,143,163,194,141,106,110,116,98,89,110,200,204,119,141,160,160,205,178,120,202,162,84,190,168,166,226,122,109,127,83,84,48,151,206,220,186,83,50,79,115,93,175,239,246,203,73,58,79,117,112,57,59,89,130,133,93,80,50,26,15,27,59,87,111,118,125,121,106,106,109,124,118,139,133,53,17,93,110,81,100,80,120,130,116,121,83,87,77,70,85,66,49,36,15,24,62,84,76,50,39,32,36,32,25,32,47,86,103,103,130,131,150,148,163,167,157,152,113,77,53,37,28,23,25,23,26,24,110,145,97,128,115,59,22,8,19,19,35,92,115,82,63,53,31,34,36,32,45,54,76,85,84,88,95,119,131,135,146,151,148,152,184,190,206,212,205,199,191,181,154,139,139,135,125,125,136,137,121,147,145,125,100,93,71,50,40,35,34,53,29,32,21,15,18,32,51,48,39,38,15,19,24,19,16,17,19,18,22,16,17,17,15,18,16,19,20,20,23,34,50,49,46,36,25,22,18,26,41,46,45,36,29,22,15,16,18,18,16,20,18,19,19,17,21,26,32,31,33,25,19,39,41,31,28,20,24,31,36,39,46,63,84,90,123,129,134,137,131,136,130,122,129,128,148,153,148,163,123,108,106,67,56,48,35,35,33,39,60,40,22,39,42,49,52,42,28,28,39,38,40,29,25,20,103,143,60,51,51,31,47,37,43,48,39,29,52,127,137,122,99,106,100,47,54,60,52,43,35,61,129,155,91,57,45,22,23,29,29,32,28,34,38,34,43,54,67,105,145,170,167,160,113,93,125,109,107,127,122,92,128,207,241,242,251,251,236,228,229,223,223,223,217,219,223,226,226,223,224,116,4,1,7,11,11,11,14,13,14,15,15,14,204,207,204,203,206,205,206,203,203,205,204,205,204,203,201,203,204,201,203,206,208,206,206,206,206,206,204,207,207,204,204,206,206,207,205,205,206,205,208,206,205,204,205,208,205,203,204,205,205,206,205,203,204,205,204,204,204,203,204,203,206,205,204,204,205,206,203,204,203,206,205,204,204,205,203,202,201,202,203,203,206,202,201,203,204,202,199,200,200,198,198,199,201,198,198,200,200,199,200,199,201,201,199,201,198,202,199,200,200,195,201,198,198,198,198,198,198,197,198,197,196,197,195,196,194,195,198,197,198,198,195,196,195,195,196,195,194,194,196,194,197,196,195,196,194,195,195,193,195,195,193,196,193,194,193,192,196,193,192,195,194,193,196,194,191,193,193,194,195,196,192,194,196,193,192,192,194,194,194,194,193,194,193,191,192,193,195,193,191,193,191,191,191,193,193,191,193,189,193,190,190,193,191,190,191,191,191,193,194,192,191,193,192,192,191,193,193,194,190,193,194,189,191,190,191,192,191,194,194,190,191,192,189,192,190,192,193,191,193,194,193,192,193,191,190,191,189,190,190,191,192,193,193,189,191,193,193,196,196,196,193,194,195,194,192,192,191,193,193,195,196,191,193,193,197,195,190,183,177,184,185,188,193,198,201,202,202,199,201,200,198,200,200,193,192,199,201,200,199,199,198,197,200,201,207,189,181,153,132,177,198,172,134,174,216,205,197,196,205,205,181,200,193,178,203,201,199,208,182,139,182,222,176,117,110,136,121,104,107,175,175,137,163,144,169,202,147,153,239,152,59,135,152,200,242,131,111,127,98,90,43,161,220,226,143,13,10,66,117,126,208,245,203,87,43,77,101,117,90,62,104,125,127,100,81,62,23,17,31,61,93,107,122,122,122,113,99,108,115,113,98,111,90,14,40,141,103,79,97,79,105,76,58,105,87,66,67,55,44,36,36,24,14,34,51,65,74,75,68,46,36,32,30,30,27,29,44,57,87,108,123,131,139,137,144,173,188,187,166,133,114,85,54,50,35,39,125,135,96,122,99,42,14,14,11,23,52,89,90,51,42,48,48,55,61,71,86,110,138,134,141,160,179,181,175,181,179,182,174,178,179,160,157,152,149,145,144,141,129,134,134,133,131,122,122,103,94,72,46,33,24,25,18,17,20,25,22,29,30,24,14,16,36,39,41,48,47,38,21,16,16,14,20,17,19,17,19,30,29,34,30,22,19,16,21,30,53,69,63,60,64,56,50,35,36,68,69,64,66,60,57,43,24,15,19,21,15,16,23,25,18,21,20,18,20,21,24,18,33,75,74,53,49,29,17,21,27,29,26,30,34,36,49,46,71,97,112,123,130,147,146,143,137,133,128,147,139,156,170,136,134,107,74,76,60,59,79,57,67,63,37,32,45,57,62,56,30,19,30,41,46,72,152,152,59,42,45,44,49,37,47,42,29,26,31,96,133,124,102,98,106,61,38,48,63,71,76,95,96,75,47,35,29,24,18,23,28,35,44,55,72,91,129,155,160,165,163,154,134,133,123,137,158,112,92,83,51,31,24,64,135,180,230,242,224,224,224,222,222,220,223,221,221,223,223,221,222,116,4,1,8,11,12,12,14,13,14,14,15,14,200,204,203,203,205,203,203,203,203,202,203,201,203,204,203,204,201,202,203,205,206,203,206,203,204,205,204,207,205,205,206,206,205,205,208,205,205,206,205,204,205,204,205,205,204,205,202,206,206,206,206,203,205,207,204,203,205,202,205,204,206,205,203,206,204,202,203,202,205,204,205,204,200,204,205,205,207,203,204,203,200,201,201,205,201,201,201,200,201,199,203,201,201,200,198,200,199,203,200,200,202,198,203,201,200,203,199,199,200,201,200,198,200,199,200,199,199,198,198,198,198,195,195,196,198,199,195,197,196,196,198,196,197,197,194,196,197,195,198,195,194,196,194,195,194,193,196,196,195,194,195,195,194,195,192,192,195,194,194,194,193,194,192,191,194,192,192,194,192,193,193,194,193,192,194,195,193,191,193,192,194,195,193,195,194,195,194,193,192,191,196,193,193,192,192,194,193,193,191,193,193,190,191,190,192,190,193,194,190,190,191,191,190,191,191,193,193,190,192,194,191,191,192,190,192,191,190,190,189,191,193,192,190,193,191,191,192,192,193,194,193,192,190,190,192,193,192,192,194,193,192,194,197,193,199,199,193,196,200,200,200,200,198,201,200,198,198,199,199,198,199,196,193,188,187,184,184,187,188,193,196,200,204,199,199,200,200,199,199,198,199,198,199,189,184,200,200,198,199,195,196,196,198,203,199,174,173,148,159,202,208,181,152,200,219,206,198,189,201,204,179,200,196,175,198,198,203,212,179,156,196,207,165,115,118,136,110,84,66,125,163,175,174,125,153,186,146,194,230,93,61,141,168,224,235,134,110,121,112,79,22,144,239,239,127,5,36,149,173,167,241,209,95,56,67,107,107,83,53,66,131,123,88,87,59,32,18,23,53,78,113,124,121,122,111,106,106,109,109,94,66,62,59,15,56,155,101,82,98,78,115,126,118,113,83,105,95,57,37,22,23,21,30,49,43,33,33,49,55,36,29,21,24,32,29,27,21,26,33,49,74,101,127,123,123,139,152,169,176,177,184,177,162,147,118,120,155,128,95,115,83,37,27,20,42,59,89,78,71,41,44,59,77,123,127,146,143,181,189,192,189,195,190,181,178,171,156,144,140,122,112,112,124,138,145,148,149,142,133,113,93,82,66,51,33,24,16,18,22,21,16,17,17,16,16,16,23,19,19,21,17,31,38,34,44,62,54,29,21,18,15,15,16,18,21,21,40,59,69,65,56,45,23,21,29,69,77,78,96,98,91,78,78,58,85,100,107,112,92,74,83,81,44,19,14,19,34,79,53,49,35,24,19,20,16,15,17,33,76,87,69,71,54,26,20,16,27,34,30,38,29,24,22,18,21,25,37,41,69,106,124,129,129,133,139,137,127,141,139,133,150,148,160,160,133,127,131,122,133,105,69,58,31,90,100,60,37,24,26,39,85,70,125,146,57,48,51,53,59,50,55,46,42,29,26,96,145,133,98,105,115,65,29,22,45,60,55,57,47,35,34,34,26,19,33,40,56,69,107,154,165,177,174,164,150,135,129,133,142,146,126,123,152,116,61,38,33,24,35,31,19,47,145,216,224,223,223,221,225,225,222,224,225,223,223,223,222,116,4,1,6,11,13,12,12,11,15,15,14,14,200,203,201,203,204,201,201,199,202,201,199,203,202,203,201,203,201,201,204,203,204,200,206,203,203,204,203,205,204,205,203,206,206,205,205,207,206,205,206,204,207,205,203,204,203,206,206,204,205,204,202,203,203,205,203,202,203,203,203,201,205,205,205,205,203,203,202,204,203,202,200,202,202,202,203,202,204,204,204,201,202,202,201,206,203,200,203,202,202,202,203,200,200,202,203,203,203,202,202,199,202,202,200,201,200,203,200,200,203,198,204,201,200,200,198,199,200,198,198,198,199,201,199,199,198,198,199,198,200,197,196,198,199,198,197,197,196,196,196,195,197,194,194,197,195,197,196,195,197,196,198,196,192,196,194,194,196,195,195,195,194,193,192,193,193,196,192,191,193,193,194,194,195,194,193,191,195,193,189,193,194,191,193,193,194,195,193,191,193,192,192,194,193,194,191,192,193,192,195,193,194,194,194,194,192,191,193,194,196,192,192,191,191,194,191,193,192,190,191,192,193,192,191,193,196,193,195,191,192,195,194,193,189,193,194,195,194,195,193,194,194,193,193,193,196,195,193,194,194,196,195,206,202,201,221,201,196,203,199,204,199,199,203,200,206,204,201,205,200,199,199,195,191,185,188,190,192,195,199,202,199,201,203,198,195,198,198,196,196,197,198,195,200,185,177,196,197,199,198,196,196,197,199,199,182,139,127,106,133,184,176,153,152,205,218,208,203,184,194,203,182,199,193,177,201,198,202,208,162,169,188,152,159,128,115,119,92,84,67,91,154,213,147,90,176,193,164,206,181,68,53,98,158,218,231,141,115,123,93,61,12,113,234,252,169,118,185,252,212,206,225,101,60,73,100,114,76,67,76,87,117,87,83,63,25,21,22,47,77,109,131,127,125,116,105,116,116,113,113,95,48,21,43,15,60,154,92,84,96,84,141,143,147,122,98,145,100,66,49,29,53,55,57,51,44,39,23,24,31,20,16,17,19,32,40,33,19,25,30,28,30,39,55,81,110,125,129,137,140,134,145,159,175,192,189,179,165,117,104,120,86,65,84,118,149,156,144,154,164,161,174,170,179,185,182,179,179,181,186,174,160,149,139,134,130,115,113,116,114,127,134,138,151,151,130,110,86,59,45,34,26,30,34,24,19,12,14,17,13,19,16,16,17,15,17,13,17,20,20,17,27,36,24,39,81,93,51,25,22,16,15,17,15,19,19,35,79,82,51,52,77,83,59,30,82,109,91,165,145,107,100,102,102,108,134,146,147,104,139,87,98,136,62,30,22,55,120,148,124,86,71,39,14,24,17,16,23,51,67,66,88,77,44,24,17,16,19,28,33,23,22,19,19,16,19,23,22,25,19,26,35,46,61,76,89,103,111,122,135,123,131,138,146,161,146,154,150,150,165,156,162,146,141,135,131,89,60,49,49,90,71,41,118,143,57,38,25,26,38,36,45,45,34,32,30,98,152,130,99,92,117,80,33,17,16,27,28,33,25,29,38,39,48,63,85,118,148,169,182,177,160,148,136,136,135,141,147,141,125,94,50,64,135,106,50,33,24,29,35,34,48,12,64,195,214,227,226,220,227,221,221,222,223,223,225,223,223,115,4,1,6,11,12,11,14,13,14,14,14,15,200,202,198,199,202,199,199,200,202,200,200,201,202,198,198,199,200,200,201,203,202,202,204,202,201,202,201,204,202,201,203,204,204,204,204,203,204,203,206,204,204,204,204,200,202,203,202,206,202,203,203,202,202,201,201,203,205,202,203,203,203,203,203,202,201,204,201,200,202,202,201,202,202,203,204,203,202,201,201,203,205,205,200,202,202,205,205,200,202,201,201,200,203,201,204,204,200,202,199,201,202,201,202,202,200,200,200,199,201,200,198,199,200,200,200,201,199,199,200,199,200,198,199,198,198,198,197,200,198,199,199,195,197,198,196,198,198,198,198,197,197,199,196,196,195,195,197,193,196,196,196,195,194,194,195,195,194,193,192,194,194,194,194,195,195,192,194,195,195,193,193,193,193,195,195,196,191,193,194,192,194,193,192,193,192,194,192,193,193,190,194,189,192,192,193,193,191,194,192,192,194,194,192,192,194,193,193,192,195,196,194,192,193,196,195,194,195,193,193,196,195,194,195,195,195,196,195,198,198,196,195,197,196,195,195,194,195,196,195,196,196,197,196,195,199,196,195,198,196,198,195,205,183,162,189,193,200,202,199,200,198,201,200,203,204,203,200,199,196,191,191,188,191,194,199,196,197,200,197,200,198,198,200,194,196,196,196,198,197,196,196,195,199,186,171,195,200,195,199,197,197,198,201,198,170,124,116,103,131,164,131,125,143,194,220,209,202,186,187,203,180,195,199,176,198,196,203,189,139,158,154,148,169,130,98,87,94,99,97,115,174,206,140,131,194,183,158,202,162,73,41,55,153,221,231,155,110,96,73,41,10,125,233,252,202,206,252,252,205,185,123,57,81,100,105,76,56,101,110,89,86,76,55,30,12,23,47,87,118,126,134,130,118,119,99,130,130,112,114,98,60,27,38,17,50,141,98,88,95,93,81,49,101,93,110,152,80,49,57,87,110,82,61,46,45,32,23,22,23,23,19,17,20,34,50,46,37,35,33,31,23,19,22,26,37,56,84,108,124,132,141,136,148,159,165,162,138,113,111,112,85,117,175,202,222,214,167,204,192,198,189,173,165,153,149,132,147,128,126,122,111,113,117,113,124,127,123,125,126,122,105,88,61,42,33,28,24,27,26,30,36,32,25,15,15,14,13,13,13,18,19,17,16,15,16,18,19,20,16,21,30,29,26,49,89,80,37,22,18,14,14,21,16,20,19,54,108,73,47,49,63,108,84,75,137,122,107,174,124,46,53,105,147,119,141,136,89,92,128,98,74,125,98,43,85,160,164,109,72,105,125,71,27,14,17,16,39,47,52,99,112,90,41,19,22,10,23,21,20,17,17,25,18,17,21,24,20,20,23,19,19,31,34,36,33,36,45,66,81,95,116,116,136,144,147,142,135,145,148,163,180,184,167,168,153,155,164,122,153,136,94,84,146,125,59,39,29,23,27,23,32,30,29,31,32,90,139,133,91,84,114,84,34,22,16,22,39,48,57,73,84,110,134,152,178,175,173,157,143,132,131,148,150,152,150,133,111,96,58,23,17,108,153,75,50,36,24,25,31,39,55,19,57,193,214,225,231,219,223,220,220,219,220,222,225,223,222,115,4,1,7,10,12,12,13,13,14,15,14,14,200,204,199,199,200,199,198,201,202,199,201,201,199,200,198,199,200,199,201,198,203,201,201,200,200,204,200,204,202,201,202,203,203,200,204,206,203,202,203,203,204,201,201,203,200,202,201,203,204,201,200,201,201,201,203,202,206,202,202,203,200,201,200,200,201,201,201,200,199,204,203,201,202,201,203,201,203,201,203,201,200,202,201,203,200,201,202,200,201,199,202,201,198,201,201,199,199,201,202,201,200,199,200,200,199,198,200,200,204,199,200,198,197,200,196,200,199,197,199,199,196,197,199,198,198,200,199,196,198,196,200,198,196,199,196,197,198,199,197,196,196,195,196,194,196,195,195,195,194,193,193,195,195,197,194,193,196,192,195,196,195,195,192,196,193,197,194,193,196,194,194,195,193,194,194,193,194,192,193,195,194,191,195,196,194,195,190,191,195,195,192,192,194,194,192,195,194,194,197,193,191,193,193,194,195,194,193,194,194,193,195,193,195,197,193,194,196,196,196,196,197,199,198,201,200,197,201,198,200,200,195,198,196,199,197,196,195,197,196,196,198,195,196,198,197,196,196,196,194,199,197,203,136,79,153,191,199,203,198,208,203,204,203,196,200,194,190,191,189,191,193,198,198,197,199,198,199,198,198,194,195,194,196,199,196,196,196,197,197,196,198,197,202,190,170,194,200,198,200,196,196,200,207,196,178,162,155,148,184,179,122,129,143,169,212,215,201,191,185,200,182,192,198,173,196,199,202,171,145,159,155,168,182,143,93,96,109,105,92,107,177,226,166,168,175,130,177,214,142,76,50,98,218,243,243,160,74,66,55,20,45,178,235,232,160,179,248,248,142,76,60,64,110,110,72,53,94,132,108,55,42,47,34,16,18,50,98,130,137,133,128,120,115,103,82,91,97,98,107,106,83,41,39,12,45,154,111,99,112,52,59,38,58,96,90,103,29,29,95,108,87,44,38,36,35,32,25,27,24,24,21,26,19,28,39,36,43,37,26,22,18,16,17,17,21,21,24,35,51,77,97,110,130,142,146,156,147,141,149,122,107,152,184,197,194,175,167,156,150,137,133,127,120,111,115,120,119,134,141,128,133,140,125,114,101,92,73,50,33,30,25,24,16,17,18,18,21,13,24,27,24,24,19,19,16,12,20,17,15,18,17,17,16,15,17,16,14,16,19,17,22,24,30,44,62,55,27,16,15,15,15,20,16,19,16,56,118,108,93,79,49,104,110,105,156,102,90,144,105,103,90,148,125,63,106,117,124,101,155,87,71,147,122,97,148,150,86,66,27,82,161,97,33,14,10,24,43,42,43,101,126,78,32,21,17,13,18,21,21,17,19,20,16,18,21,19,20,18,24,21,16,24,30,36,34,23,31,35,39,41,44,55,76,100,111,122,123,137,141,154,168,162,163,160,165,170,182,179,168,171,143,135,162,125,78,80,63,60,60,52,54,51,55,57,47,103,156,143,107,86,117,87,42,43,46,73,102,136,153,172,174,169,171,163,156,136,129,141,152,148,153,166,145,121,93,63,56,44,41,11,79,212,148,53,43,33,30,26,42,45,57,22,72,214,210,222,230,217,223,220,223,222,220,222,222,217,220,116,3,0,7,11,12,12,13,11,14,15,14,14,206,207,205,203,205,201,200,202,201,202,199,200,202,200,201,199,199,198,201,202,198,199,203,200,199,201,200,203,199,200,201,199,202,203,202,202,202,202,202,203,202,201,207,202,202,202,200,200,200,201,200,200,202,202,199,201,201,200,201,201,199,201,202,202,202,201,202,201,203,202,201,200,200,201,199,203,200,201,203,199,201,199,200,204,201,201,203,200,200,200,203,200,203,199,201,201,200,202,200,200,199,200,201,200,199,203,200,199,200,199,200,198,199,198,196,199,199,200,198,198,198,199,197,195,198,196,198,198,196,196,195,196,198,198,196,196,194,195,197,194,195,193,194,196,191,195,194,194,195,193,196,195,193,195,194,195,196,194,195,194,194,194,192,196,194,193,193,191,193,192,194,196,193,193,191,193,193,190,195,194,194,196,193,192,195,193,196,196,194,195,195,194,195,192,192,193,195,195,191,196,194,193,195,195,196,194,195,195,198,196,195,195,193,196,198,196,197,196,195,198,198,198,198,198,198,199,198,200,200,198,198,198,196,198,196,196,196,197,196,195,196,193,195,196,198,198,198,198,195,198,198,200,142,120,180,200,217,214,216,226,209,204,196,191,192,191,193,196,199,201,203,204,205,205,206,203,200,201,201,202,200,200,201,201,204,200,200,202,202,203,202,203,206,204,179,194,209,207,210,207,206,210,209,185,170,165,158,165,208,192,143,172,169,142,189,221,216,209,195,205,191,201,210,185,204,210,199,175,181,173,159,153,171,192,128,119,123,84,77,82,163,214,162,160,134,160,220,191,108,63,50,147,249,249,239,112,39,43,35,20,97,231,227,206,126,109,205,167,51,38,61,95,117,73,59,95,124,134,81,47,46,24,19,25,35,88,129,141,138,129,121,118,108,86,42,33,53,62,93,103,93,57,46,39,66,161,127,96,66,48,67,15,77,109,72,30,8,66,131,98,49,39,60,53,37,39,29,24,28,26,25,27,24,26,24,19,24,19,16,16,16,15,18,21,19,19,24,20,22,28,41,40,50,57,79,97,110,148,156,151,153,171,188,192,201,184,166,165,153,151,143,141,150,128,127,118,81,119,96,78,69,53,45,33,32,31,20,22,15,15,21,18,19,17,15,14,16,16,17,21,16,21,17,14,22,18,16,22,17,14,19,19,19,18,17,16,17,16,21,15,27,36,43,60,59,56,40,35,24,14,18,17,19,22,16,31,89,123,110,91,48,83,92,98,126,75,89,100,103,123,118,88,49,22,53,77,113,149,131,81,134,159,142,106,155,98,79,143,95,162,199,101,21,9,13,14,33,48,86,94,78,48,27,15,14,16,16,17,17,23,21,15,21,22,19,20,21,19,18,21,18,19,21,36,38,32,44,36,33,24,21,23,34,34,47,56,65,91,111,130,136,153,162,162,151,154,157,150,156,147,151,152,159,154,130,181,166,166,156,141,143,137,141,141,143,169,179,171,127,91,113,92,61,108,135,160,192,182,166,155,140,138,130,129,142,139,159,170,155,128,113,98,69,55,38,39,32,39,36,30,194,241,115,41,41,26,29,33,42,37,60,29,71,214,210,220,230,216,222,215,218,218,219,222,223,220,219,115,4,0,6,10,13,12,13,12,13,14,15,14,205,210,207,206,206,203,204,205,205,200,201,203,201,203,199,201,200,198,201,197,202,200,200,202,200,205,201,200,200,200,194,198,202,200,199,199,201,200,201,201,200,200,201,202,201,202,201,200,201,202,203,204,203,202,201,200,201,199,200,201,200,198,200,201,202,199,200,200,200,202,199,201,201,198,199,200,199,198,201,200,200,202,199,199,199,200,201,200,199,199,200,200,197,199,202,200,200,199,198,198,198,199,199,199,196,198,199,196,199,196,197,198,197,199,198,198,198,196,198,196,196,198,196,198,195,197,193,195,199,193,195,195,195,198,194,196,195,193,195,194,194,193,194,194,193,194,194,194,193,195,195,194,193,192,193,193,195,190,191,190,191,193,190,191,191,192,192,192,193,193,193,191,192,192,194,193,193,194,193,195,194,193,196,193,193,195,196,198,195,194,192,195,195,195,194,194,196,194,195,194,193,198,198,194,195,195,195,195,196,194,196,193,194,196,194,196,194,195,197,199,197,198,197,199,198,198,201,196,199,198,196,198,198,198,197,198,199,201,201,203,203,205,205,206,207,208,210,208,212,211,213,221,193,207,235,231,233,218,211,218,214,210,210,211,217,217,224,226,228,227,225,228,227,227,227,226,223,222,227,225,226,226,226,225,226,226,223,226,227,227,227,228,229,227,207,211,226,226,229,225,221,231,210,166,137,128,127,151,197,167,160,217,199,138,159,225,239,236,225,225,212,223,232,208,229,235,205,198,212,177,158,158,214,239,139,96,103,93,86,73,119,142,112,142,154,219,248,133,65,61,39,107,235,239,151,46,6,32,31,43,166,246,213,205,115,92,163,74,27,71,93,124,79,54,97,123,133,87,79,63,28,16,17,48,87,124,128,122,127,124,122,121,113,81,69,77,60,44,89,104,66,76,96,63,48,130,102,46,60,48,45,17,105,165,72,36,63,139,162,84,44,89,104,69,54,53,37,22,24,24,23,27,19,25,21,23,23,19,20,13,17,17,16,16,18,18,19,16,19,26,30,34,27,22,26,33,37,44,59,51,66,81,92,114,121,121,122,116,101,93,83,73,63,50,43,40,33,25,24,30,23,21,26,27,26,19,17,21,17,14,17,17,17,17,22,20,16,18,17,21,22,16,18,15,17,19,19,18,15,21,16,19,21,18,19,18,24,21,25,19,34,85,101,108,105,85,86,75,49,24,17,15,17,22,16,17,34,40,71,103,48,67,74,90,104,64,110,101,65,56,41,44,40,38,44,38,64,63,89,139,165,144,122,89,131,68,81,182,111,169,157,38,23,13,18,23,33,71,141,114,63,55,30,26,19,15,19,22,21,18,21,21,17,23,20,20,20,20,21,20,23,21,20,28,29,31,38,25,21,22,15,19,22,24,21,27,27,32,44,58,76,97,118,127,134,141,146,142,139,147,141,142,146,148,167,180,183,182,185,181,184,193,189,188,181,169,175,165,123,103,125,101,101,138,145,161,150,142,126,131,141,133,139,134,141,137,127,114,79,48,34,38,41,38,33,27,22,33,23,94,248,233,78,45,44,19,29,29,36,39,56,27,69,202,210,225,229,214,224,220,219,220,217,221,224,222,223,113,4,1,6,11,13,12,13,13,14,14,14,14,206,205,206,205,205,205,206,205,202,203,199,201,200,198,201,199,202,201,200,200,200,203,201,202,203,203,203,200,204,203,195,201,202,200,204,200,202,204,202,204,201,200,203,202,201,204,201,200,202,203,206,206,205,203,204,202,201,202,200,201,200,202,200,203,200,199,202,200,202,200,203,198,198,202,198,202,199,201,201,200,203,201,198,199,198,197,198,200,200,199,198,198,200,196,197,198,200,199,197,198,198,198,199,196,195,200,198,198,196,195,197,196,198,197,196,198,196,197,196,196,195,198,198,195,196,194,195,198,195,195,196,194,194,194,193,194,195,193,195,195,195,194,193,195,192,195,194,193,194,196,193,190,191,193,190,192,193,190,191,192,191,193,191,194,194,191,193,194,195,190,192,194,193,196,194,193,196,196,195,196,194,194,194,195,195,193,196,192,193,194,194,197,197,195,195,193,192,196,193,195,196,194,197,194,195,195,197,195,193,196,194,196,196,194,194,194,196,194,194,196,193,193,196,199,198,199,198,199,195,195,196,198,197,199,203,208,220,229,230,229,233,234,233,237,237,234,240,237,242,239,234,244,222,243,249,241,230,160,134,193,229,246,245,244,248,248,249,249,248,249,249,249,248,248,243,250,237,229,242,243,246,242,242,240,239,245,229,229,238,240,241,240,238,232,224,209,209,215,222,226,212,225,200,160,133,127,129,136,159,131,170,229,198,139,123,188,226,235,226,218,212,215,226,212,214,225,188,197,201,136,159,176,229,226,108,96,110,101,113,95,85,61,80,139,141,234,208,70,65,72,31,30,122,139,66,11,14,38,29,92,214,246,217,235,139,103,121,59,67,88,112,88,59,92,128,128,91,80,57,30,17,21,45,89,127,132,128,121,120,128,132,124,88,79,102,84,69,43,93,72,48,67,74,48,27,63,77,69,62,25,29,62,144,177,85,100,133,165,157,73,50,121,108,78,74,63,47,21,23,21,24,27,22,27,22,24,24,19,21,20,15,17,21,15,15,19,16,13,15,16,25,36,37,23,27,31,25,31,19,19,24,20,19,23,25,25,28,29,34,33,32,22,26,29,31,19,18,24,29,39,29,30,24,18,27,19,16,18,14,17,17,17,19,17,15,19,19,19,19,18,17,16,20,19,17,18,19,17,19,19,17,19,17,20,21,19,25,17,29,16,94,196,201,187,170,169,171,160,90,25,11,15,21,15,19,25,15,33,84,96,38,57,71,90,118,75,101,72,40,44,36,45,37,35,44,47,53,52,69,111,147,124,120,84,106,55,55,131,53,52,42,17,27,14,16,27,74,129,162,129,91,90,57,63,35,19,23,16,22,22,22,22,22,21,21,23,19,20,15,19,19,22,22,15,18,23,20,17,22,20,16,16,27,29,24,24,26,22,26,34,37,41,39,46,61,84,95,106,113,120,132,141,150,147,145,149,148,147,142,139,147,141,141,145,136,128,135,145,131,117,144,134,112,140,139,143,141,126,132,133,134,124,109,94,76,52,49,47,41,37,28,36,39,36,25,25,23,23,28,115,248,181,66,55,35,25,27,31,48,46,62,26,73,206,211,224,226,214,220,218,222,218,218,222,222,221,222,116,4,1,8,12,12,11,14,13,14,14,15,15,204,204,203,205,205,205,203,201,202,200,200,200,199,202,198,199,200,200,201,199,203,200,201,204,202,202,204,204,220,234,206,200,202,200,204,203,207,203,202,205,203,202,205,203,201,202,205,203,201,205,206,206,205,206,206,205,206,204,205,204,203,205,207,202,205,206,207,206,204,205,201,203,203,201,203,204,203,204,202,200,200,199,201,200,200,200,199,198,200,200,201,200,198,200,200,202,201,198,199,200,199,198,199,197,196,199,199,196,198,197,196,196,196,200,198,195,195,194,198,196,197,196,197,196,192,197,195,197,195,193,195,193,192,194,194,194,193,191,195,194,193,193,193,192,194,195,193,193,192,193,192,192,193,193,190,190,194,192,196,194,194,195,193,195,194,192,193,193,192,194,196,195,196,192,195,196,195,194,196,198,194,196,198,196,198,194,195,193,195,196,196,197,195,197,195,195,197,196,194,196,193,195,197,195,197,197,196,194,194,195,195,196,197,196,194,196,195,196,195,196,196,197,195,199,198,198,197,197,202,198,195,199,195,200,203,195,200,205,205,205,204,203,200,200,198,193,194,192,187,174,162,203,187,165,158,151,139,83,73,119,158,167,164,162,163,161,160,155,155,153,151,156,151,149,146,168,167,132,144,148,147,149,141,144,149,161,149,127,133,137,139,141,140,139,161,145,129,133,153,170,128,134,125,125,125,120,122,130,149,120,177,231,199,139,88,106,125,135,135,130,137,131,131,128,136,137,123,139,113,71,105,124,141,128,83,114,133,116,126,113,99,49,54,90,81,145,113,36,51,60,36,27,41,41,43,29,43,46,53,165,245,246,232,242,168,116,103,84,99,100,68,62,87,122,127,93,87,54,33,17,23,49,92,138,128,129,130,126,133,125,130,105,66,48,70,76,71,80,57,42,31,45,49,38,31,70,91,62,36,30,128,116,67,80,86,125,128,130,113,56,39,78,76,64,67,65,46,17,19,23,27,28,23,27,27,21,25,23,21,22,17,19,16,19,17,13,17,16,14,17,17,28,37,29,35,31,22,15,16,19,17,21,16,20,18,19,16,21,19,21,31,28,31,29,20,16,19,37,61,59,46,43,19,14,23,15,18,14,16,19,19,23,15,17,19,16,17,17,18,18,21,18,16,19,17,18,16,17,21,20,19,22,17,21,20,16,25,15,26,18,63,160,164,170,166,166,178,149,78,20,12,16,15,19,26,22,34,80,104,61,29,71,66,107,145,83,55,40,39,37,42,58,56,60,66,71,59,55,55,58,75,131,158,98,102,54,46,107,72,43,14,14,27,17,21,29,106,161,162,141,137,136,139,135,71,24,13,18,17,18,23,19,20,21,19,22,21,19,17,16,22,18,19,21,19,21,17,17,19,19,17,19,19,19,22,18,19,20,22,29,36,37,30,27,41,39,37,40,39,45,51,71,91,103,111,106,112,120,122,122,126,132,134,133,133,125,136,145,126,139,163,139,123,128,124,127,107,95,76,66,55,41,43,33,30,27,27,30,30,38,39,41,36,26,23,29,17,27,24,79,144,80,58,60,33,31,33,37,46,55,53,36,140,226,220,228,224,216,222,217,219,217,219,221,221,220,221,116,4,1,8,13,12,12,15,13,14,15,15,15,202,202,201,202,202,200,201,200,200,204,201,203,200,198,201,199,201,200,202,200,198,201,200,202,202,200,206,203,240,252,205,201,202,198,206,200,203,205,203,200,204,203,203,200,201,205,200,203,204,205,206,206,205,205,206,204,205,205,201,206,205,203,206,206,205,206,206,204,206,204,204,205,202,203,205,205,203,203,202,204,202,200,201,203,201,202,202,200,202,200,200,200,201,199,200,199,200,198,198,202,199,198,200,199,200,201,197,198,197,197,198,198,197,195,197,196,198,198,196,196,195,196,196,194,195,196,193,196,195,193,195,191,194,195,197,194,194,195,194,194,192,194,194,194,192,191,192,193,193,193,192,193,193,192,193,196,194,196,196,196,194,194,193,193,195,196,193,193,194,194,195,193,195,196,194,194,195,196,196,194,197,196,196,196,195,193,193,196,194,195,193,196,195,194,195,193,194,195,193,195,193,193,195,195,196,193,194,195,194,193,194,196,193,193,193,194,196,193,195,195,196,196,195,196,195,197,198,196,198,198,198,198,193,199,190,120,79,80,71,69,66,62,56,55,53,46,46,36,33,29,29,105,81,14,12,10,18,12,10,16,10,15,14,14,14,11,12,11,12,12,11,12,10,14,8,34,52,15,9,12,10,14,11,15,9,37,40,10,13,12,13,11,15,10,49,62,25,19,34,76,33,35,57,60,65,71,78,111,153,149,199,212,180,143,85,51,15,6,12,12,28,23,10,15,12,32,34,32,36,16,44,36,29,21,30,110,132,121,129,119,107,70,52,49,15,42,35,18,65,64,59,57,43,25,31,44,66,48,78,184,241,249,221,234,180,134,122,94,108,68,61,80,110,127,93,89,57,29,21,26,46,96,139,131,125,128,126,133,129,109,100,71,41,35,63,83,91,55,45,25,32,73,54,35,38,74,69,33,50,127,224,137,22,35,75,105,75,76,81,58,40,30,39,56,56,48,34,23,24,24,33,31,23,28,26,27,27,22,26,23,25,29,19,19,21,19,16,16,18,17,21,19,18,22,26,20,17,19,19,18,18,18,16,20,19,15,17,18,17,19,23,27,20,20,20,16,30,53,69,59,53,45,25,16,15,18,18,18,19,18,16,19,21,16,16,21,22,17,22,19,21,21,16,20,19,18,24,16,19,24,17,19,19,22,19,20,24,16,21,28,35,63,66,63,62,56,53,44,38,21,15,16,19,22,27,34,69,117,86,40,46,63,65,114,141,65,43,34,24,24,42,77,95,127,123,65,36,40,57,54,47,113,165,106,92,53,41,87,97,57,20,13,20,20,17,27,81,142,162,150,160,124,173,158,72,23,12,14,20,18,21,22,19,22,21,21,19,20,22,22,19,17,20,19,19,23,16,21,23,19,22,18,16,15,20,21,19,19,16,19,34,41,40,41,34,33,33,27,28,30,24,27,37,36,41,42,51,61,65,79,85,88,98,102,107,99,101,89,88,104,100,86,59,76,50,49,52,39,33,29,29,25,21,24,25,23,22,22,26,30,30,33,25,27,29,27,21,24,29,27,40,45,55,50,28,34,42,41,41,44,21,71,210,235,226,223,221,220,220,220,218,217,220,221,223,220,221,116,6,2,8,12,13,12,15,14,16,16,16,15,204,205,201,202,204,203,205,200,202,202,201,200,200,202,201,201,203,201,201,201,201,199,201,201,202,201,207,198,241,252,200,204,203,197,205,199,205,202,201,205,201,201,202,200,202,201,202,203,203,205,204,204,205,206,206,206,204,203,205,205,204,204,204,203,206,203,205,205,202,204,205,205,202,202,206,205,203,205,201,204,204,202,202,201,203,202,202,201,203,199,203,201,202,202,198,200,199,201,199,200,199,200,200,199,201,198,200,201,199,199,201,201,197,200,196,198,199,197,198,196,199,195,197,197,196,198,196,196,194,197,198,198,196,195,196,196,198,195,195,197,196,194,196,198,195,196,196,197,196,196,196,193,195,197,194,198,198,194,198,195,196,198,198,196,195,195,194,194,194,197,196,194,196,194,194,196,198,195,194,195,195,196,196,194,195,195,192,193,193,194,194,194,193,194,192,196,195,191,193,194,193,194,195,194,194,193,195,194,194,195,194,195,194,194,193,194,192,192,193,196,195,195,196,195,196,199,197,196,198,198,195,196,196,199,185,115,79,76,72,70,68,68,63,68,65,61,62,62,59,63,61,77,87,71,56,57,59,61,68,60,54,45,46,45,42,47,46,46,46,46,46,46,45,45,37,59,103,69,43,40,38,44,35,38,35,49,85,61,35,29,29,32,31,23,69,78,23,12,17,67,59,58,67,66,56,46,65,95,153,184,207,179,130,94,62,51,22,11,15,9,27,27,12,16,13,14,15,20,25,17,30,35,24,12,27,71,85,110,130,123,103,67,51,34,3,35,43,26,74,88,75,55,28,19,32,50,70,35,65,181,205,177,168,170,149,146,128,96,59,46,88,120,121,92,84,54,29,18,28,54,94,135,132,128,120,119,121,131,117,68,76,51,48,62,72,102,67,41,15,33,118,148,69,39,61,55,22,48,104,141,198,78,36,69,65,79,60,67,55,59,51,25,18,33,38,33,42,41,33,24,28,31,24,31,31,28,28,23,25,29,23,30,27,22,24,21,22,15,20,19,15,20,19,18,17,15,21,17,16,18,15,21,20,17,17,17,19,17,17,17,16,19,18,18,20,27,40,42,61,70,55,37,20,15,15,17,19,16,20,21,19,19,19,17,17,21,17,17,19,21,19,17,20,24,21,17,19,18,16,24,23,18,20,22,23,18,18,24,27,30,35,51,51,41,29,29,30,22,27,21,12,21,23,21,33,53,104,121,65,52,61,57,66,90,84,45,39,23,21,25,28,61,118,131,72,32,19,26,32,61,68,95,128,112,93,41,40,66,103,88,28,18,17,19,22,23,45,70,83,81,91,84,58,49,37,19,17,16,23,25,18,26,27,19,20,19,21,22,17,21,20,17,21,24,24,17,20,22,17,19,20,18,21,19,19,21,19,19,16,19,21,31,34,34,27,23,34,65,76,57,45,32,22,26,29,29,33,37,39,30,27,32,34,34,33,33,37,37,33,36,44,36,30,33,31,38,38,26,22,21,25,25,25,22,26,25,28,27,23,26,21,23,24,25,24,25,24,28,27,25,31,30,39,43,46,47,49,49,46,32,25,134,240,237,222,219,218,219,220,218,217,219,219,220,222,220,220,115,6,2,8,12,13,12,15,15,15,15,16,16,199,203,203,203,203,200,204,203,200,204,199,200,203,203,202,201,203,202,201,202,201,202,201,200,201,201,209,195,243,252,196,205,203,197,205,200,207,202,202,203,202,203,203,203,203,203,203,205,204,203,203,204,202,203,207,203,204,206,202,206,204,205,205,204,204,206,206,205,206,202,204,205,203,204,203,201,202,202,203,203,203,205,200,201,202,201,200,200,202,202,202,197,200,200,200,200,199,200,198,200,202,201,200,198,199,199,200,202,201,201,199,199,201,199,200,198,197,199,198,199,200,198,200,198,197,199,196,200,197,198,200,197,199,198,199,196,198,199,197,198,197,199,196,196,200,196,196,198,195,196,196,198,198,197,196,195,195,195,195,196,196,196,195,194,197,198,195,196,196,195,196,193,196,196,193,194,193,194,195,193,194,194,194,196,195,193,198,198,193,194,194,196,193,193,195,192,193,193,194,193,193,195,194,193,193,195,194,194,194,192,193,194,194,193,193,193,194,192,192,196,196,196,197,196,196,196,195,196,197,197,195,196,196,199,205,191,193,200,199,205,206,203,205,210,208,209,210,211,211,211,191,171,189,218,225,216,218,217,217,221,219,220,215,218,216,217,219,219,222,218,221,222,220,218,210,220,219,214,215,214,216,214,216,212,207,210,209,212,210,207,208,205,200,198,205,176,156,169,172,191,170,161,148,130,139,120,105,117,160,190,186,157,90,44,36,98,169,183,176,176,174,153,171,171,129,154,160,138,110,102,163,153,145,127,113,104,81,124,134,115,91,46,53,98,91,101,87,59,74,67,55,33,17,12,36,57,61,29,100,198,117,79,92,79,98,130,125,63,29,64,125,126,94,86,49,29,17,21,61,103,125,131,128,123,114,116,120,126,101,38,30,33,44,60,95,90,44,24,48,116,194,208,127,82,52,13,63,162,142,49,71,65,68,78,60,71,47,56,52,49,61,34,23,23,34,46,55,56,44,28,27,32,32,29,17,28,32,22,28,28,27,25,20,24,27,23,24,18,18,19,17,19,18,19,17,18,17,16,17,20,19,19,19,22,15,19,19,14,21,18,18,21,18,15,22,33,34,59,97,90,61,31,21,21,17,17,15,19,18,19,20,21,17,17,19,20,17,19,18,20,21,17,19,22,21,21,20,20,19,19,22,21,21,20,22,24,24,19,28,31,36,50,45,37,34,29,29,19,19,20,19,22,23,24,29,59,128,113,68,83,81,59,62,74,46,33,32,21,34,28,54,126,145,97,41,26,30,25,29,43,71,88,97,111,62,51,71,69,116,111,51,19,12,19,18,25,48,52,49,41,33,27,29,27,17,24,19,16,21,21,24,26,25,25,21,22,24,24,27,24,27,21,23,21,20,25,20,19,19,17,19,23,21,19,23,21,21,17,18,24,24,21,19,22,21,35,80,122,107,79,57,29,19,29,33,31,38,31,24,22,20,22,23,24,23,22,23,22,20,25,28,40,38,37,42,34,27,21,25,20,16,25,25,24,24,22,22,24,28,28,21,28,25,22,24,30,28,25,47,36,28,36,35,48,68,68,59,61,54,123,167,231,248,225,222,221,217,215,214,215,215,215,217,220,218,215,219,117,6,2,8,12,13,12,14,12,14,15,16,15,199,203,201,201,201,200,203,202,205,203,201,203,202,201,201,200,204,200,203,204,200,203,202,202,204,200,206,193,244,252,191,203,200,197,206,200,206,203,199,202,200,202,205,202,204,203,203,205,203,201,203,203,201,204,201,203,204,203,205,205,203,206,204,204,206,202,205,204,204,204,205,204,202,202,203,203,202,202,203,202,200,201,203,202,200,201,200,200,201,199,200,197,201,198,200,200,198,200,198,199,199,199,199,199,200,198,199,199,199,197,198,199,198,201,199,199,198,194,198,196,200,198,197,197,196,199,196,199,198,198,198,196,195,196,196,197,198,195,196,197,196,196,198,196,196,196,196,195,198,196,194,196,198,200,195,198,196,195,194,195,196,194,195,196,195,194,196,196,195,196,194,193,196,194,196,195,192,194,193,194,193,193,194,193,191,194,194,196,193,194,196,193,194,196,193,192,194,194,195,193,191,195,195,192,193,193,194,193,195,194,189,193,193,195,193,192,195,192,192,195,191,195,197,196,196,195,194,195,196,195,193,193,194,199,206,209,224,230,235,235,235,239,238,241,239,240,242,242,240,242,239,214,205,239,252,252,246,244,249,246,251,252,248,246,248,251,251,250,249,252,250,248,250,251,246,246,249,240,247,249,250,251,248,252,245,249,247,241,251,248,249,247,248,244,251,232,218,242,252,252,213,200,188,187,205,168,132,128,165,189,160,112,67,32,55,174,241,250,252,252,250,221,252,242,205,248,238,196,174,203,252,230,210,179,201,179,112,132,123,93,56,31,102,219,199,183,163,91,77,40,27,35,22,27,41,63,59,54,181,200,88,83,89,49,40,78,75,34,58,116,125,92,81,52,25,16,29,53,107,134,122,118,118,118,119,123,125,130,94,39,33,35,35,45,61,61,31,48,111,177,202,178,100,40,15,10,104,212,128,21,44,62,92,72,64,71,44,49,43,50,49,41,31,40,58,69,68,59,61,39,27,25,29,31,26,29,33,28,27,35,31,25,26,25,27,27,27,25,24,19,19,21,20,18,21,23,14,20,18,18,21,18,19,17,20,19,18,18,15,15,20,18,18,20,29,37,30,81,129,98,55,31,20,17,14,19,20,15,23,19,16,20,21,19,17,22,21,21,18,21,23,16,20,19,23,20,20,19,18,22,22,20,20,23,22,21,20,21,39,33,28,47,50,48,44,46,30,25,23,15,20,21,21,24,30,67,132,117,67,75,101,79,56,56,41,27,26,22,34,27,89,160,150,102,67,71,44,24,31,23,59,82,94,67,58,113,118,68,117,138,63,21,12,17,17,29,43,51,51,30,29,30,24,30,23,21,23,20,21,23,30,27,26,27,23,21,22,30,25,27,24,24,31,20,23,27,23,19,19,19,17,21,17,18,21,24,17,17,18,23,24,18,18,17,34,78,115,104,77,71,61,33,16,22,24,24,33,27,17,18,22,21,18,24,23,21,21,20,20,20,24,33,41,33,35,29,22,23,21,23,23,22,28,24,22,23,27,27,25,27,25,24,22,27,23,32,25,65,104,53,27,34,48,57,76,77,68,69,99,217,246,246,243,216,225,217,214,214,212,210,213,214,214,217,217,214,218,116,5,1,8,12,12,13,16,13,14,15,15,15,200,204,201,203,205,201,202,202,200,200,200,200,199,199,198,201,200,200,202,202,202,201,204,202,206,203,205,193,244,245,180,199,200,202,204,199,207,203,204,203,199,201,200,200,203,203,203,201,203,203,201,204,204,202,200,203,203,203,201,202,203,203,203,203,201,201,200,200,204,202,204,203,202,203,203,203,205,202,202,201,200,202,199,201,201,199,199,198,199,199,200,199,200,199,200,198,198,200,198,199,198,198,198,198,199,198,195,198,195,196,199,196,199,198,198,195,196,199,197,199,197,195,198,198,195,196,194,197,194,195,198,195,196,195,196,197,197,196,196,197,195,195,194,193,195,194,198,195,193,196,196,196,196,193,194,195,198,195,195,196,192,197,194,193,195,193,192,192,193,192,197,195,193,195,191,194,196,194,192,191,194,193,193,194,193,192,194,194,194,192,192,194,194,193,192,193,193,194,194,192,193,192,193,194,193,191,190,191,192,193,192,193,194,192,193,194,193,193,192,191,193,193,193,194,194,196,195,194,195,194,196,196,195,194,196,199,200,205,204,206,206,205,207,208,208,208,207,208,209,211,213,203,184,189,214,224,217,210,211,212,212,212,212,212,212,213,213,214,214,212,213,212,213,214,212,214,211,213,214,213,211,212,214,211,212,211,213,213,211,212,214,214,212,215,217,204,199,210,228,213,178,177,175,190,213,167,124,148,182,185,141,82,39,39,122,212,234,229,221,225,222,197,221,197,186,227,173,160,181,221,249,174,151,177,226,192,122,133,96,60,72,52,135,244,208,212,165,83,55,10,63,98,55,39,60,66,63,154,249,219,107,115,105,41,17,27,49,67,109,97,78,73,51,27,17,29,49,103,131,122,118,122,120,116,125,128,127,117,111,73,40,29,34,37,39,34,31,97,162,178,161,92,33,38,56,18,66,141,82,52,76,65,77,76,66,66,40,39,36,39,54,33,30,44,70,84,73,60,58,56,29,32,53,49,33,25,30,25,30,34,27,27,21,29,29,25,25,27,24,21,22,23,25,21,21,19,18,22,18,22,19,20,20,24,23,17,18,23,19,16,21,20,21,19,26,35,27,53,83,66,39,18,14,17,15,18,19,22,22,22,21,17,21,21,22,21,21,21,21,23,19,20,24,17,23,24,22,20,19,22,22,19,22,25,22,22,23,24,41,45,39,59,75,73,81,84,57,31,21,18,17,20,23,23,23,56,146,123,87,109,127,110,63,51,31,22,31,43,67,55,71,83,59,71,79,72,42,30,44,33,39,74,85,66,96,157,98,54,126,149,76,20,12,14,23,28,37,51,55,38,41,44,29,27,18,25,23,24,25,21,27,26,27,27,23,24,29,29,24,25,25,26,27,23,26,27,23,23,22,19,24,20,18,21,25,24,17,22,21,21,19,17,24,28,59,88,77,76,80,80,50,27,21,15,17,18,25,21,22,23,19,20,22,19,24,23,19,22,21,24,23,24,27,26,21,21,25,25,27,23,24,24,23,27,27,24,24,27,27,26,27,26,33,25,27,26,41,150,125,46,39,38,55,66,85,78,71,76,78,200,245,237,230,213,218,216,212,211,211,214,213,214,214,216,217,215,216,115,6,2,8,12,13,12,15,14,15,15,15,16,205,207,205,202,203,201,199,202,203,202,201,202,201,200,203,202,201,202,201,201,202,203,203,203,206,205,206,193,234,219,167,195,195,199,205,200,203,202,205,206,203,201,203,200,204,203,200,203,203,201,203,203,202,203,203,200,201,201,200,200,202,202,203,201,201,201,201,203,201,202,203,203,203,202,202,201,202,202,202,201,198,200,202,199,200,200,200,202,200,198,198,198,200,197,199,199,199,200,198,198,198,201,199,196,198,198,198,198,199,199,198,196,195,197,197,197,198,196,197,193,194,193,193,195,196,195,191,195,195,195,196,195,196,195,195,195,196,194,193,194,196,195,196,195,196,194,193,193,195,197,196,196,192,193,194,193,194,194,196,193,194,194,193,193,191,191,192,192,191,194,193,192,195,193,193,193,195,195,191,193,193,194,193,195,192,192,192,193,192,192,193,191,193,194,192,193,195,194,192,193,193,190,194,193,194,194,192,193,194,194,191,194,194,195,193,193,194,193,194,194,193,193,194,192,194,196,196,195,194,195,195,195,194,194,194,195,196,195,197,195,198,198,198,200,198,199,196,199,199,199,204,199,188,166,178,207,208,204,199,198,200,200,198,199,200,199,200,199,197,199,200,198,199,199,200,198,199,199,200,200,198,198,198,196,197,198,198,198,199,198,197,199,195,198,200,186,182,187,204,170,128,143,158,191,207,152,124,173,207,180,130,63,30,102,198,231,217,204,196,203,197,184,194,147,162,187,147,159,179,225,177,72,108,193,230,186,141,109,89,81,74,66,127,196,156,126,100,65,30,2,72,130,82,79,71,63,167,237,246,182,74,84,39,16,19,28,84,105,90,57,49,49,27,19,30,57,102,125,128,113,117,121,110,118,129,119,108,119,124,98,63,57,53,38,31,38,92,156,179,162,103,100,110,127,130,64,44,69,71,86,79,62,77,65,57,50,42,37,33,39,39,31,30,49,64,74,69,54,57,73,87,106,105,73,36,30,28,27,34,33,29,24,27,26,23,29,27,29,30,23,25,27,27,31,25,19,21,21,24,27,22,20,24,24,22,22,20,19,18,17,19,19,18,18,24,39,44,66,77,57,37,23,14,15,15,20,19,21,28,19,22,23,18,19,20,22,21,21,23,21,19,25,25,21,22,22,22,19,20,23,23,20,27,24,25,28,27,30,48,53,61,120,135,141,155,134,92,53,25,13,17,20,19,29,19,49,128,136,145,139,152,143,95,53,22,23,34,81,115,98,82,61,34,25,52,63,71,83,60,35,32,64,98,75,117,159,101,94,148,165,75,18,15,9,21,31,39,57,71,66,81,79,51,29,24,23,22,22,22,23,26,27,24,30,22,26,29,27,30,27,24,25,25,25,28,29,26,29,24,22,27,24,21,27,23,21,23,21,19,19,21,23,24,41,72,53,67,131,137,95,39,24,21,17,23,16,18,22,19,23,17,23,23,19,21,18,27,20,17,27,19,22,18,21,29,21,23,24,26,24,26,26,27,24,26,26,25,25,29,30,30,28,29,29,29,17,116,200,96,69,88,66,73,74,93,71,76,76,43,161,219,214,226,211,215,211,212,216,213,213,216,214,214,216,216,216,216,115,6,2,7,11,14,12,15,14,14,15,15,15,201,203,202,202,201,203,202,204,203,200,204,203,205,204,203,204,200,201,201,203,205,201,201,202,206,204,203,195,235,233,184,194,193,203,201,201,203,201,203,202,203,204,205,201,201,203,204,201,201,201,200,203,202,202,201,201,202,201,200,200,201,200,199,201,200,200,202,203,201,201,205,202,204,203,201,202,200,200,201,200,201,200,201,199,200,200,199,200,199,200,199,199,200,199,199,198,197,199,198,199,199,199,200,197,198,197,197,199,196,196,198,199,197,196,197,197,198,196,195,196,195,196,195,196,195,196,194,197,196,194,195,192,194,194,193,193,193,195,196,194,196,196,196,200,195,197,198,196,199,197,196,195,195,194,196,192,193,194,192,195,193,193,194,193,196,193,193,194,194,193,195,193,191,193,193,193,192,192,196,196,195,193,193,194,192,192,195,193,193,193,192,192,191,193,191,193,194,193,193,192,192,192,192,193,192,195,196,193,195,196,193,193,194,194,193,194,194,194,193,193,195,192,194,194,193,193,190,193,196,193,193,194,194,193,195,198,191,194,194,195,197,196,199,198,196,197,198,198,199,196,200,202,198,174,163,189,203,207,202,194,197,198,198,198,195,195,198,198,195,196,198,196,198,196,196,195,196,196,199,198,193,194,197,195,194,196,191,195,196,194,196,193,194,196,196,186,184,182,186,160,115,111,128,178,182,130,146,195,215,184,119,55,90,191,230,225,206,197,193,199,194,182,176,138,176,187,162,176,194,199,103,44,133,186,178,177,139,112,106,81,81,77,127,152,78,62,49,42,41,3,34,72,76,81,57,149,240,246,206,91,66,37,5,16,11,45,108,86,55,43,39,31,17,31,56,95,127,120,118,118,107,100,105,128,124,103,108,111,128,118,113,100,53,24,42,108,166,199,161,116,128,150,160,154,131,66,50,57,53,74,72,70,73,55,43,45,42,45,46,55,56,37,43,53,67,64,53,67,102,122,130,145,144,107,59,32,26,29,30,35,28,27,24,28,25,28,34,32,28,26,24,28,31,33,34,27,23,22,29,27,24,21,24,23,24,25,15,19,21,18,21,20,21,19,47,80,95,117,95,62,63,60,34,21,21,19,19,26,22,19,24,23,21,19,17,19,21,26,21,19,23,21,19,22,27,23,24,19,18,26,24,21,30,31,27,28,22,32,53,79,124,169,199,162,145,141,105,72,30,12,16,19,15,20,25,28,89,113,124,145,133,152,110,42,21,27,16,96,166,145,122,87,36,53,97,105,139,105,39,23,24,71,95,94,124,148,145,141,174,149,49,15,18,12,15,34,54,107,123,139,169,137,85,46,22,28,25,24,24,16,22,27,24,27,24,27,25,31,33,26,27,27,30,27,29,26,24,25,26,21,27,26,26,30,24,23,24,26,18,23,21,19,24,48,60,38,66,130,125,67,35,25,17,16,18,19,22,21,20,20,19,26,22,19,22,22,24,23,20,22,21,21,23,27,22,24,26,20,27,27,24,25,24,29,28,24,24,27,30,29,27,29,32,33,19,83,223,168,89,160,129,83,57,49,52,47,71,63,27,143,205,206,227,211,214,208,210,213,210,215,212,215,217,216,217,214,219,116,5,1,8,12,12,12,14,12,14,15,14,14,200,200,201,201,203,202,199,204,201,202,203,203,204,200,203,202,203,203,200,200,201,203,200,203,205,204,207,203,252,252,208,201,200,204,200,199,203,200,202,201,202,202,203,201,201,202,201,203,200,200,200,201,201,200,203,202,201,202,202,201,200,199,200,201,200,200,199,200,198,199,201,199,200,200,201,201,199,199,200,202,200,201,200,199,199,200,201,198,199,200,201,200,196,199,199,199,200,198,198,194,196,198,199,198,196,199,196,196,196,196,196,197,198,196,197,196,196,198,198,195,198,194,197,196,195,198,195,197,193,192,193,195,195,194,195,196,198,197,197,198,198,197,196,196,200,198,196,198,196,196,194,195,197,195,198,194,195,196,194,194,196,196,197,197,196,195,198,198,194,198,193,196,197,193,196,193,194,193,193,196,191,193,195,194,194,195,195,193,192,191,193,194,192,195,191,192,191,192,194,192,195,190,192,193,191,196,191,191,194,194,193,193,194,194,191,191,193,191,192,192,193,193,193,194,196,193,194,193,193,191,194,195,192,196,196,194,194,194,196,197,196,198,198,196,198,198,196,196,196,196,199,198,203,194,177,179,194,204,205,202,195,196,196,198,196,195,197,196,196,195,195,194,193,196,195,193,196,195,196,201,197,196,196,192,196,194,193,193,193,194,193,195,191,191,196,185,193,183,170,159,135,119,132,167,132,100,155,208,217,201,134,126,189,224,227,207,193,198,193,197,192,174,166,157,192,177,151,159,184,187,93,54,97,100,124,177,164,123,109,71,79,114,127,92,37,27,35,78,49,23,38,50,54,66,160,227,244,195,96,92,97,65,14,12,33,92,95,49,50,37,22,22,26,53,79,106,117,118,125,102,96,96,105,115,107,108,108,113,122,117,111,79,36,20,79,169,188,156,81,81,118,130,120,78,56,51,44,44,45,57,72,61,56,41,41,45,46,46,61,81,63,30,41,56,75,112,103,111,122,123,122,122,129,103,70,35,22,31,26,31,34,26,29,25,27,33,29,36,25,25,30,25,37,29,33,29,19,31,34,30,29,25,29,27,24,25,19,19,18,23,23,17,29,18,110,193,171,171,146,134,145,124,83,30,10,17,18,22,24,23,22,22,21,21,21,19,18,29,21,20,27,20,22,22,24,26,26,22,21,30,29,27,29,23,29,29,31,33,66,71,112,174,137,134,131,114,89,55,40,18,14,18,18,19,19,27,73,85,94,84,110,148,74,34,26,21,31,129,148,93,113,105,53,107,148,145,146,77,26,26,15,61,97,107,122,130,128,136,139,93,36,21,17,17,24,50,117,176,212,172,173,167,116,72,33,31,21,17,24,18,21,23,29,22,21,25,27,34,30,33,25,27,34,28,26,27,27,26,21,24,28,28,28,29,22,24,30,24,28,18,25,25,22,45,56,54,76,88,65,47,27,17,21,15,19,21,21,19,19,27,19,23,20,20,25,20,21,24,26,21,20,25,26,21,27,26,24,24,31,24,21,27,27,28,30,27,25,29,28,31,29,27,38,18,84,236,239,119,97,177,149,88,68,40,41,38,66,50,25,150,212,211,227,211,211,210,214,214,211,215,215,213,215,218,217,216,218,115,5,2,8,11,12,12,15,13,14,15,15,15,200,200,202,200,201,200,201,202,200,201,203,202,202,201,201,202,199,200,201,200,203,200,200,203,203,203,203,206,252,252,230,209,203,202,201,201,202,200,200,201,200,200,200,198,201,199,199,200,199,199,200,200,200,200,200,200,201,201,200,200,202,200,199,202,199,198,200,200,200,198,198,197,199,199,200,200,199,197,198,200,199,199,199,198,200,199,198,198,197,199,199,197,200,196,198,200,196,198,196,196,199,198,196,196,198,198,198,196,195,196,196,197,195,196,195,195,198,195,196,196,196,195,195,197,195,196,194,194,195,194,196,194,195,197,196,198,199,196,198,197,199,197,199,202,196,197,196,196,196,194,198,195,194,197,197,195,195,198,196,196,199,196,197,195,196,198,196,197,195,194,195,195,195,197,195,195,198,195,193,193,193,191,194,194,196,193,193,194,193,195,193,193,193,195,193,193,196,190,193,194,193,194,192,194,192,193,193,193,194,191,192,193,193,195,192,191,192,192,192,191,193,191,193,193,193,194,192,196,194,193,193,193,196,195,195,195,193,199,197,196,199,197,196,197,197,195,196,195,196,198,194,198,201,199,197,184,185,199,204,205,203,198,199,202,199,196,194,196,198,195,196,195,195,194,196,194,193,192,195,199,195,194,195,193,192,196,193,193,195,194,195,197,195,192,195,186,201,184,160,164,151,164,184,180,116,105,181,210,215,194,179,197,219,226,206,197,192,194,196,197,198,170,162,182,180,114,105,162,213,184,72,43,35,63,160,207,170,119,99,69,78,100,95,48,4,67,114,93,68,48,78,62,61,174,228,245,191,96,88,107,132,84,37,66,121,132,84,49,40,23,13,37,47,79,114,108,110,113,119,106,96,101,101,108,105,109,115,110,108,92,71,52,24,28,131,188,134,76,8,42,104,103,87,46,80,76,41,42,46,57,61,51,47,43,38,47,42,33,45,64,46,34,57,103,155,155,133,117,110,113,107,110,94,59,36,23,22,34,27,30,35,31,31,27,29,29,31,28,29,28,28,32,34,36,33,29,23,32,44,36,36,35,33,33,32,29,19,21,22,23,22,16,25,24,95,191,191,205,180,180,189,191,122,25,8,12,15,20,22,22,19,21,25,22,26,22,21,24,20,29,24,26,26,24,25,29,25,20,24,24,29,26,24,27,27,35,26,32,70,75,89,103,139,118,110,110,71,64,43,21,16,12,19,20,25,24,74,107,104,109,119,104,55,45,29,22,33,101,98,47,101,129,60,95,146,83,53,40,22,29,16,61,83,114,114,107,127,92,121,109,35,19,19,14,32,50,118,206,160,150,146,122,108,61,40,43,23,15,23,21,27,22,25,28,24,26,34,39,28,30,27,27,31,29,34,27,29,27,25,28,24,33,29,25,29,28,27,26,29,29,23,21,25,57,72,93,118,77,57,47,33,24,19,18,21,24,20,19,22,23,23,24,21,24,24,22,23,21,25,18,27,25,22,28,23,26,25,28,31,24,25,29,25,28,29,31,29,29,28,30,31,32,28,58,212,242,182,67,72,134,104,74,76,49,39,45,62,25,38,190,226,219,224,209,216,213,217,216,213,213,213,215,213,214,218,214,218,116,5,1,7,12,13,12,15,13,14,15,15,15,202,202,201,200,201,199,199,204,203,200,202,200,200,199,202,201,199,202,201,202,200,201,202,200,201,201,201,200,253,253,243,213,198,202,200,201,201,198,203,201,200,200,200,201,201,200,200,202,200,200,198,199,200,201,200,199,201,200,201,199,198,203,200,200,200,200,200,200,200,200,200,200,200,200,200,200,199,199,201,198,197,198,199,200,197,198,199,199,199,197,197,197,198,200,196,196,198,199,199,197,198,198,197,196,196,201,199,198,198,198,198,196,198,195,196,199,196,198,196,196,198,196,200,196,196,199,197,198,198,199,198,199,198,196,196,195,194,194,196,195,196,196,197,198,195,195,196,196,196,196,194,197,198,194,197,196,196,198,195,196,196,197,198,196,196,194,193,195,193,196,193,193,194,193,197,195,198,195,193,196,194,196,193,193,195,193,195,194,193,191,192,196,193,193,191,194,194,192,195,191,193,193,191,193,193,194,191,193,191,192,193,189,192,191,193,193,193,193,194,193,193,191,192,193,193,192,194,196,195,195,195,195,196,197,197,196,196,195,195,198,195,198,196,198,201,197,198,197,198,197,197,196,200,200,201,192,181,191,200,208,205,204,201,207,206,198,199,196,197,195,196,198,196,199,196,194,197,193,193,197,196,193,194,193,194,195,193,192,195,195,192,195,194,192,196,187,200,177,148,159,166,181,204,191,129,151,205,208,202,184,188,211,217,207,199,197,192,193,192,202,198,155,172,200,125,60,131,215,230,139,47,23,9,112,210,213,141,67,70,54,73,74,59,21,34,203,192,87,57,74,66,84,196,244,243,157,90,84,103,116,74,116,132,144,134,102,89,39,20,20,40,65,75,117,118,107,113,108,108,104,113,99,103,112,110,111,104,100,90,81,50,36,18,60,152,139,69,14,15,83,141,129,72,76,114,78,42,38,47,51,42,46,48,39,41,40,33,34,29,44,66,83,138,150,164,157,114,103,99,102,82,53,43,25,19,17,17,27,32,29,30,31,30,28,29,31,27,31,31,26,29,27,35,38,33,32,29,31,39,44,31,36,41,32,41,30,24,29,24,26,24,23,23,24,60,111,129,148,135,139,144,102,53,22,11,15,23,17,26,21,28,27,24,27,24,27,19,28,29,26,27,30,31,27,26,27,20,18,27,29,29,26,27,30,31,25,33,29,71,58,80,114,95,118,92,81,62,63,49,17,19,16,21,22,25,25,53,110,133,116,96,108,81,46,26,20,31,73,95,97,155,144,117,152,135,78,61,42,25,25,29,70,88,112,93,126,151,150,188,101,17,20,9,20,24,46,101,133,171,115,108,118,84,67,42,41,22,14,23,20,27,18,24,26,26,31,32,34,24,31,35,24,28,32,28,30,34,29,30,29,30,29,22,32,26,26,30,27,30,29,20,33,29,85,150,150,160,117,86,87,71,56,32,19,18,17,20,26,24,24,19,26,22,19,30,26,23,23,24,24,24,27,26,23,27,22,25,30,22,29,27,28,24,29,29,24,31,29,29,33,32,44,41,104,231,211,103,66,64,72,59,61,66,45,41,44,39,12,123,233,232,221,217,213,214,213,214,214,211,214,211,213,216,215,218,214,218,115,5,1,7,12,13,12,14,13,14,15,16,15,198,199,201,200,201,199,200,198,198,201,198,198,199,199,201,199,201,197,200,201,200,203,200,202,200,203,200,198,241,250,206,197,197,195,198,200,199,199,199,198,200,200,199,199,199,199,199,200,197,198,201,200,199,200,200,200,199,200,201,200,201,197,198,201,200,201,200,200,199,199,200,200,199,200,198,197,200,199,199,198,197,199,199,198,198,199,198,198,198,200,196,199,200,196,198,199,198,196,198,198,199,198,195,196,196,196,197,195,198,197,196,199,198,200,198,195,198,196,199,196,197,198,200,198,194,198,200,198,197,198,198,197,198,199,194,198,198,197,198,195,199,196,196,198,195,195,195,196,196,194,197,193,194,197,194,195,194,196,195,194,197,195,197,196,194,194,194,192,192,194,194,195,194,193,192,193,192,195,194,194,194,191,195,191,194,195,195,194,192,195,192,193,193,194,192,192,193,190,194,193,193,191,190,193,189,191,191,191,191,193,193,189,190,193,192,190,192,192,195,193,191,192,192,195,194,193,192,196,195,193,196,198,196,195,196,196,196,198,197,195,197,196,199,200,200,199,199,198,197,200,199,197,198,199,200,199,188,181,193,205,206,199,188,197,204,200,200,199,198,198,197,195,197,198,198,197,196,197,196,195,196,194,196,197,194,195,193,193,193,192,194,196,196,192,193,189,191,153,117,139,169,191,207,171,126,172,216,198,189,189,197,203,200,199,194,196,193,191,197,200,190,151,184,184,101,65,181,236,157,81,48,9,37,174,239,179,107,46,40,45,56,50,25,19,89,193,136,68,73,41,97,204,245,245,141,80,82,105,107,44,84,144,143,122,98,83,46,25,25,35,79,125,117,117,113,114,114,95,102,111,112,101,105,117,110,106,94,81,101,83,41,26,16,85,119,64,8,37,97,119,110,65,76,73,87,74,44,44,36,43,40,39,45,38,35,34,29,32,33,43,108,154,159,162,139,118,116,103,71,50,36,35,42,45,32,15,16,22,28,38,33,29,29,28,33,24,30,29,31,29,28,34,32,37,33,29,29,33,42,39,41,35,38,39,35,34,29,25,25,24,30,29,24,33,49,59,57,51,36,37,35,31,27,17,17,15,19,24,17,25,30,25,31,25,23,31,29,31,29,27,27,27,28,25,33,30,25,22,30,26,30,31,22,29,29,33,27,36,58,69,77,66,105,64,62,65,48,65,41,26,19,14,19,24,29,30,29,58,83,69,102,147,92,53,36,27,24,39,65,107,120,96,90,98,82,94,102,50,22,25,44,97,102,139,94,90,144,151,141,42,14,17,16,19,36,39,79,151,106,112,101,84,87,49,50,45,22,22,20,23,24,28,29,22,28,27,33,31,29,34,25,31,35,31,27,31,33,29,27,24,32,29,26,28,27,29,30,29,28,27,22,33,31,96,166,183,189,173,144,168,167,135,50,15,15,20,21,26,27,21,26,24,24,22,29,22,27,24,21,27,22,28,22,25,28,19,26,31,24,27,29,28,29,24,22,32,24,28,34,32,41,47,74,141,177,134,96,98,75,49,51,46,54,49,41,40,29,114,235,242,228,215,217,214,214,211,212,211,214,212,214,214,216,216,219,213,215,117,4,2,8,12,12,12,15,13,15,16,15,15,196,199,196,199,199,198,198,198,199,195,199,199,198,200,199,198,199,198,196,197,198,198,198,198,200,198,200,193,249,240,173,187,192,194,197,198,200,193,199,199,200,200,198,199,198,198,196,199,198,200,198,198,200,200,200,198,198,197,198,198,198,201,199,199,199,197,199,197,198,200,200,200,199,197,197,195,199,199,196,198,197,197,198,199,198,198,198,198,197,198,198,196,199,196,194,197,198,198,198,197,198,198,197,198,196,196,196,196,197,195,198,196,199,199,197,200,195,196,198,198,197,193,199,197,197,199,197,198,198,200,198,199,198,198,199,200,199,199,200,198,199,198,196,196,195,198,198,196,194,196,197,195,196,194,192,194,195,194,193,195,194,196,193,192,193,191,193,193,191,193,193,193,193,190,194,190,191,192,191,194,193,191,193,193,193,189,191,191,192,192,191,193,191,193,191,191,192,189,193,190,191,192,188,190,191,192,193,193,191,189,194,190,194,191,191,191,189,193,191,193,195,193,194,196,195,196,199,198,199,195,193,196,197,195,196,199,196,196,197,194,197,198,196,198,197,198,199,199,199,200,200,195,197,198,199,198,197,184,181,196,201,196,162,170,197,199,201,197,199,199,197,200,195,198,198,194,198,196,195,196,196,196,195,194,194,194,196,193,195,195,193,194,192,192,197,191,181,146,110,113,150,186,191,149,116,179,203,189,197,193,201,198,196,197,191,194,191,195,194,203,174,144,194,185,87,64,128,126,60,47,90,55,98,237,235,166,121,55,52,34,34,40,12,39,92,101,59,53,45,113,214,249,246,146,82,86,107,93,57,79,108,122,84,90,79,33,29,15,38,78,130,143,117,120,113,109,104,105,111,106,105,103,116,114,103,94,83,92,113,103,56,24,30,73,61,21,43,157,170,84,97,100,94,81,84,99,53,25,31,34,43,45,35,33,35,30,26,30,33,31,103,155,152,128,126,112,78,53,27,31,35,39,53,54,47,34,21,19,21,32,39,32,32,30,26,32,32,27,32,29,30,35,30,33,33,30,31,36,42,45,37,36,44,42,35,35,25,27,27,25,28,27,26,31,45,49,50,40,26,31,25,23,29,19,16,18,20,22,21,22,33,34,27,32,25,26,31,29,29,27,32,27,27,27,27,32,24,28,30,26,32,27,24,32,33,29,30,33,58,59,74,83,45,79,55,35,47,54,57,23,19,21,18,24,29,25,31,71,89,115,149,163,130,66,39,27,22,27,27,33,66,59,55,56,47,51,44,21,24,22,73,120,118,171,110,65,56,56,57,26,16,21,15,27,22,34,79,66,100,58,61,63,35,59,48,40,22,25,23,17,30,26,29,26,26,30,29,33,32,30,26,31,32,33,33,30,32,25,25,24,31,34,23,30,29,28,30,29,29,29,27,29,29,69,123,144,167,162,176,174,168,129,42,21,12,16,18,21,26,23,26,23,28,33,29,24,28,24,24,27,24,25,28,24,24,26,23,30,27,27,25,29,29,29,29,27,29,30,36,36,39,48,117,170,161,130,128,140,111,93,81,63,55,42,37,27,125,229,251,249,219,220,219,214,212,211,212,213,213,216,214,214,217,216,218,215,220,115,4,2,8,11,12,12,14,12,15,16,15,15,195,197,198,198,196,195,199,199,198,199,198,199,201,197,198,197,199,198,199,200,196,198,195,195,198,200,202,195,250,237,171,201,199,198,199,197,199,198,200,201,201,200,199,200,199,200,200,200,199,199,200,200,199,199,199,199,201,198,199,200,201,198,198,200,196,198,199,200,199,197,199,198,200,199,200,200,198,198,198,198,198,196,199,197,194,199,197,198,196,198,198,199,199,198,197,197,198,199,199,198,199,199,199,198,199,198,200,197,198,200,198,199,196,198,197,195,200,196,198,198,198,197,196,198,196,198,199,197,198,198,198,197,198,200,198,201,198,198,199,198,198,198,199,199,196,197,197,196,195,193,195,194,196,195,195,196,193,193,193,194,196,192,193,191,191,193,192,190,191,194,194,192,193,192,191,193,192,192,186,190,191,191,191,188,193,190,190,189,190,192,189,192,193,193,191,193,191,190,193,190,191,191,190,193,190,190,193,190,191,193,195,191,191,194,193,194,192,192,193,194,192,197,195,192,198,196,198,199,196,198,198,196,196,194,195,196,197,198,196,195,193,195,194,192,197,196,197,196,198,198,197,198,199,198,199,199,200,195,179,184,199,200,174,171,196,200,201,198,194,198,199,198,198,195,196,199,196,196,197,195,196,195,196,192,195,197,196,196,196,193,191,191,193,196,201,191,169,158,143,120,159,169,154,126,122,183,190,195,203,201,200,193,196,197,192,196,193,192,201,198,165,160,214,164,70,36,16,57,63,126,179,95,159,231,222,180,117,55,39,9,55,149,64,98,196,116,34,37,141,227,243,242,139,84,87,114,84,56,97,113,146,108,61,60,39,24,19,39,79,124,139,123,120,112,103,100,104,115,108,104,104,106,116,104,89,83,88,104,118,124,103,73,54,48,16,63,117,201,160,69,142,147,134,110,120,108,48,30,25,31,35,40,39,31,27,33,30,29,24,25,56,84,94,93,69,43,36,31,28,28,36,34,33,37,50,56,33,17,23,24,35,35,32,32,27,30,23,29,33,28,31,35,34,33,36,33,29,36,47,45,36,41,43,45,41,35,30,25,29,28,24,31,26,27,38,50,49,39,36,35,29,25,24,20,17,16,24,25,22,27,33,30,35,37,33,33,29,32,35,33,31,34,29,27,35,29,32,33,27,35,34,28,30,31,27,31,31,37,57,87,108,69,112,100,53,64,52,74,69,49,26,14,24,24,27,28,73,156,166,152,159,160,118,66,45,36,21,30,27,45,107,89,77,107,84,36,19,22,29,29,110,107,125,182,150,143,84,60,58,16,19,16,15,22,29,48,66,88,45,67,66,33,52,45,49,45,22,21,21,22,27,26,29,30,28,25,32,29,27,30,25,32,29,30,32,31,27,31,33,26,35,29,29,29,25,33,28,26,33,29,26,31,37,50,66,66,75,93,100,97,60,48,34,17,16,18,22,27,22,31,27,29,34,37,36,31,27,25,28,27,32,34,27,25,29,26,27,27,28,32,28,29,28,28,31,28,31,34,33,33,36,48,93,131,144,149,150,154,147,146,139,108,69,44,24,18,159,233,249,238,224,227,224,219,219,217,215,215,216,214,218,216,215,216,218,216,215,115,5,2,7,11,13,12,14,13,14,14,15,15,196,200,198,198,198,196,197,199,200,198,199,199,198,198,199,195,198,198,196,199,198,198,198,199,199,197,202,194,249,238,175,214,203,198,200,197,201,196,201,199,199,201,199,200,199,199,200,199,198,198,198,200,199,199,198,199,201,200,201,200,198,199,200,198,198,198,197,198,200,199,200,198,198,198,200,199,201,198,198,200,198,198,197,198,198,197,199,198,197,198,197,197,198,197,199,200,197,198,196,196,199,198,198,198,198,200,199,198,198,197,199,196,199,197,196,198,198,198,196,194,195,195,198,197,197,198,198,198,197,196,195,197,197,198,197,195,198,198,198,196,196,197,198,198,196,197,196,195,196,194,195,195,194,196,198,193,192,195,195,194,192,193,193,193,192,192,196,191,191,194,192,194,193,191,195,192,192,192,192,191,192,191,191,192,191,191,193,193,191,192,191,194,194,192,192,191,194,192,193,191,192,191,193,193,192,192,189,191,191,191,193,191,194,192,191,194,193,196,195,194,195,194,196,197,194,194,196,195,195,198,196,197,194,193,194,194,193,193,195,193,194,196,193,193,195,197,195,198,197,195,196,196,198,198,196,199,199,198,192,177,186,203,200,200,200,200,203,201,201,197,195,198,197,198,196,196,195,194,196,194,195,194,193,195,196,194,193,193,192,192,195,193,192,197,203,189,159,151,160,156,176,156,128,134,148,195,200,204,220,207,199,194,195,196,194,195,194,196,204,192,171,207,208,122,58,33,18,116,188,207,215,148,219,223,174,168,96,36,21,9,169,225,81,139,179,85,64,157,235,245,214,112,89,85,109,71,53,99,132,141,109,94,57,30,24,21,38,84,132,134,125,116,116,110,95,110,112,109,104,104,110,98,106,92,75,92,102,121,126,124,112,74,39,13,73,155,100,97,71,60,117,113,112,113,110,76,48,31,19,34,36,33,31,34,29,24,31,29,28,31,28,39,43,37,34,22,29,25,17,27,33,32,31,43,54,59,55,38,27,20,31,43,37,31,29,29,29,33,30,32,32,27,30,33,33,35,31,37,46,42,37,38,38,43,46,34,29,27,25,28,31,26,29,27,40,55,59,58,58,61,44,31,18,16,18,17,21,25,24,27,31,31,36,33,31,29,32,35,33,33,33,31,35,30,34,37,31,34,35,35,28,29,31,27,31,31,36,31,78,154,163,148,161,168,146,165,165,166,171,103,31,10,15,21,24,39,154,199,128,99,63,52,51,47,60,52,36,34,24,101,171,158,181,182,111,36,14,29,29,88,117,81,81,97,126,152,149,134,72,26,24,12,24,24,36,71,108,76,115,104,66,71,49,77,76,69,34,18,20,19,33,26,28,31,26,33,31,31,33,30,32,32,27,31,30,32,29,26,33,32,33,27,25,31,30,27,26,29,29,28,29,27,41,53,54,57,48,34,31,29,26,31,24,17,18,17,24,24,25,27,29,32,35,42,35,35,33,26,29,28,33,36,35,29,24,32,29,27,32,27,34,34,32,33,31,34,32,40,33,85,124,66,66,67,84,110,122,141,141,160,165,144,78,45,24,37,203,234,249,246,235,244,238,235,235,229,228,224,219,218,213,214,215,214,218,213,214,114,5,2,7,11,12,12,13,12,14,14,15,15,194,201,200,200,199,199,198,200,198,198,199,198,200,197,197,199,199,196,198,200,196,200,198,199,202,198,200,196,247,232,153,202,202,197,201,197,203,199,199,198,196,197,196,200,198,198,199,199,199,196,199,198,199,200,198,200,200,200,201,199,200,200,198,202,201,200,200,199,200,200,201,198,198,198,200,202,197,200,200,198,198,196,201,199,197,202,196,198,198,198,199,197,198,198,198,199,198,198,197,198,198,196,198,198,199,197,198,198,196,199,198,199,198,200,199,196,199,195,198,196,196,198,198,198,198,199,198,195,197,198,199,196,198,197,196,198,194,195,194,196,196,194,194,193,194,195,196,196,196,195,194,193,196,194,194,194,192,194,192,193,195,191,193,191,192,192,192,194,193,193,191,192,193,190,193,194,192,192,192,194,194,190,191,189,192,193,194,193,191,193,195,194,193,192,193,193,193,191,192,192,193,194,191,191,190,191,193,190,191,191,194,190,189,191,192,195,193,193,193,194,193,194,193,192,196,194,193,193,193,195,195,197,195,193,195,194,192,192,195,194,194,194,194,195,192,193,195,194,195,192,193,194,193,195,193,192,197,198,198,186,177,191,199,204,204,196,198,202,202,200,198,194,194,195,193,193,193,194,194,195,194,194,196,191,193,194,192,193,191,192,193,193,193,201,201,184,148,118,149,168,175,151,106,124,170,221,195,193,222,224,198,194,193,194,194,194,194,198,210,188,158,217,169,73,91,73,34,126,128,140,148,164,243,200,113,107,50,19,5,27,142,129,54,95,71,63,175,245,244,190,90,86,89,99,59,63,109,137,141,90,97,75,31,21,23,43,84,131,134,120,116,119,119,96,105,118,105,103,105,111,106,97,95,79,84,106,121,120,110,103,57,27,13,29,148,196,63,21,51,70,79,95,114,113,87,40,35,67,45,29,26,33,31,36,38,25,24,28,27,26,26,29,19,27,31,23,24,18,26,24,27,35,41,52,57,63,60,60,50,32,39,57,66,59,57,57,59,57,53,54,57,54,57,61,56,58,56,57,60,66,66,57,63,68,61,55,52,46,71,41,42,44,44,42,54,89,97,88,112,100,66,49,24,14,21,21,22,20,21,24,31,34,31,36,31,31,29,26,36,29,31,37,30,28,27,29,27,25,30,28,30,29,27,27,35,30,36,29,67,164,186,141,149,147,159,171,161,181,127,103,24,15,12,15,30,40,137,149,73,45,46,54,56,72,76,64,60,51,29,136,153,99,115,128,117,34,26,31,74,107,96,100,59,41,42,64,78,118,116,46,21,13,30,24,66,151,166,170,180,193,171,170,178,171,190,136,40,15,14,15,27,27,29,33,36,33,33,33,37,34,39,44,34,34,33,28,34,33,36,31,38,31,27,28,27,29,28,34,31,32,34,29,36,44,53,57,41,27,26,28,24,29,20,20,23,24,25,24,28,29,29,36,41,40,45,38,29,32,30,28,29,42,38,25,29,29,32,30,35,29,34,39,33,33,35,35,41,36,64,197,215,137,105,64,57,78,78,85,115,146,151,120,67,96,127,160,237,222,220,239,235,238,236,237,233,235,233,232,227,219,220,212,215,217,216,214,216,116,4,1,7,11,12,11,15,12,14,14,14,15,197,200,198,196,199,199,198,196,196,198,198,199,198,198,198,197,200,197,196,196,196,199,199,199,200,198,200,196,246,214,105,170,188,191,203,195,200,196,198,201,197,198,198,200,198,198,200,199,200,199,199,200,198,201,200,200,199,199,201,200,201,200,199,200,198,200,200,198,198,198,200,199,200,200,198,198,198,197,197,197,199,199,198,200,198,197,199,198,197,198,198,197,198,198,196,195,197,197,198,198,198,198,198,199,197,196,200,199,198,199,199,198,200,198,198,198,196,196,199,197,199,198,198,199,195,196,196,195,196,198,198,197,195,195,196,197,196,196,197,195,194,195,196,195,192,193,195,194,196,194,194,194,193,194,192,192,193,193,193,191,191,195,194,195,195,191,196,193,191,192,193,192,192,191,194,194,191,193,193,192,193,191,193,191,191,193,193,191,192,194,193,193,191,193,194,191,193,192,193,192,191,193,192,192,190,190,189,191,196,194,192,192,193,191,189,193,191,191,191,191,193,191,191,192,191,191,194,193,194,191,193,193,192,194,193,195,191,192,195,195,193,192,193,194,193,193,193,193,193,192,193,191,194,192,194,195,191,194,196,195,181,177,189,198,199,199,194,195,200,201,200,197,197,195,193,191,192,191,195,193,194,196,191,193,196,192,194,200,194,202,205,198,198,207,200,174,138,98,134,156,163,141,85,108,188,235,189,119,146,202,200,195,196,191,194,192,196,203,202,157,121,132,77,89,166,117,37,37,55,34,74,158,237,151,24,7,14,29,7,54,110,61,111,165,129,182,240,242,167,86,83,96,89,51,72,111,145,140,90,76,81,61,26,19,47,91,127,136,122,116,117,114,106,101,105,104,96,105,114,105,97,88,86,97,97,116,121,112,76,36,50,65,89,92,136,130,42,76,68,78,86,94,116,68,21,23,111,125,60,24,19,31,29,30,29,25,23,25,33,26,25,31,21,27,24,24,24,24,29,22,22,33,34,42,60,70,71,64,76,57,65,139,167,175,173,171,171,178,178,178,173,165,171,164,168,168,163,157,161,180,191,186,180,185,169,155,155,147,127,131,137,140,142,91,146,188,171,173,151,151,134,87,46,41,47,53,50,50,58,57,67,82,78,78,82,74,74,71,77,80,76,80,76,75,72,68,65,61,66,63,61,61,62,63,62,61,63,57,101,166,128,47,27,41,41,48,49,49,57,41,27,14,12,17,29,25,68,104,67,71,69,89,107,109,95,64,81,57,74,122,66,33,14,53,109,61,34,76,83,100,133,108,101,81,57,57,28,88,143,65,20,11,27,19,92,189,201,170,167,170,177,185,179,186,188,133,33,13,16,12,22,24,28,34,31,33,29,31,34,28,42,38,31,31,33,31,30,33,32,33,34,27,24,31,29,29,25,33,23,26,31,21,29,37,48,52,45,37,43,39,23,27,18,24,25,20,27,25,29,30,32,34,47,45,42,44,28,33,29,30,35,34,39,31,32,32,32,31,32,31,33,36,36,33,36,41,39,41,51,156,189,141,141,101,87,101,81,60,49,80,83,53,37,121,179,182,190,144,160,179,181,186,178,180,185,200,214,224,229,231,227,221,219,217,217,212,214,115,4,1,7,11,12,11,15,13,14,14,15,14,194,196,196,196,199,194,193,198,197,197,197,198,196,193,199,198,198,195,196,199,194,200,197,197,199,197,201,199,249,217,91,160,183,187,203,192,196,193,199,200,198,199,195,198,198,199,199,198,199,198,200,202,200,199,198,200,200,198,201,199,199,199,196,199,200,196,198,199,199,197,198,197,198,198,195,199,196,196,194,196,198,195,198,199,196,197,193,195,195,195,196,197,198,198,199,198,196,196,198,198,194,199,196,196,198,195,198,196,199,198,194,199,195,195,195,194,196,196,196,194,194,195,196,196,196,195,195,193,194,194,195,195,196,193,195,195,194,196,194,195,195,196,195,193,194,193,193,195,193,192,193,193,193,191,194,191,190,193,193,193,192,192,191,192,191,192,195,192,194,195,193,193,193,193,194,193,194,192,191,192,193,191,192,193,192,192,192,193,195,193,193,195,194,193,191,194,195,193,194,195,194,193,193,192,191,192,195,192,191,191,193,191,191,193,190,193,191,192,192,191,191,191,191,191,190,189,194,193,193,193,193,193,193,193,194,194,195,193,193,191,191,193,191,193,194,196,194,193,194,190,195,191,192,194,190,193,194,192,194,195,194,177,177,193,196,196,194,191,194,198,201,198,198,198,197,198,193,195,191,191,193,191,196,193,198,196,207,213,204,220,211,197,206,212,181,164,139,105,118,130,132,123,95,90,165,234,212,115,112,193,198,207,197,193,194,193,208,204,183,113,54,20,55,158,230,130,56,70,102,87,85,144,193,104,15,8,122,145,59,199,132,102,185,220,246,249,229,163,92,84,104,87,55,86,114,146,118,82,62,38,53,46,29,54,94,130,132,120,113,119,110,108,112,95,98,97,101,116,112,99,83,83,96,105,108,97,109,70,38,95,145,165,157,116,76,50,51,86,81,72,87,76,77,25,20,87,180,160,56,28,18,21,27,27,24,26,25,24,26,27,25,25,23,27,24,21,24,27,30,26,26,26,29,33,44,71,82,75,71,71,67,118,146,150,160,160,165,168,175,178,170,161,170,169,159,165,156,145,152,163,184,185,177,162,120,154,150,150,101,153,156,172,154,109,131,184,188,145,154,141,123,107,83,88,89,91,95,94,107,115,143,169,170,167,159,173,166,172,190,179,183,185,192,193,179,178,167,174,165,164,172,175,182,181,183,184,193,188,193,159,81,40,32,27,33,38,35,36,39,27,21,14,15,16,19,21,43,57,97,149,137,122,103,117,128,112,99,79,76,80,46,37,29,38,82,60,66,60,91,128,148,165,146,139,120,101,81,140,133,39,25,10,21,22,89,188,152,83,43,46,60,62,65,61,61,57,30,27,26,27,32,31,42,45,46,45,51,46,44,43,41,47,41,38,41,40,40,41,38,38,41,38,39,40,33,37,41,32,36,35,33,33,34,47,60,79,70,71,84,66,40,27,21,22,19,21,29,22,30,33,35,44,50,41,43,44,29,30,29,30,29,34,37,32,34,31,31,32,34,33,33,33,36,39,39,41,49,49,55,133,137,104,97,42,47,108,108,51,25,30,43,25,25,116,150,144,141,110,118,124,125,127,124,126,130,148,163,193,217,227,236,230,230,227,222,218,215,114,5,2,7,11,13,12,13,12,14,15,15,15,195,200,196,196,196,197,196,196,197,198,194,196,196,195,197,193,195,195,193,195,198,194,197,195,196,199,201,211,251,217,123,185,189,193,200,193,199,195,196,200,198,198,199,199,199,197,198,196,198,197,198,201,197,198,199,200,199,201,201,198,199,196,197,199,199,198,198,198,197,198,199,197,199,198,199,199,196,197,198,198,198,198,197,197,195,197,197,195,198,196,197,197,196,198,196,198,199,196,197,194,195,196,195,197,195,198,198,195,196,198,196,195,197,196,196,198,198,195,197,195,195,194,193,198,195,196,194,194,195,195,195,196,199,195,195,196,195,195,195,197,195,194,193,193,195,196,193,193,195,194,194,194,192,194,193,195,196,192,194,194,194,193,191,193,191,190,193,193,191,192,192,190,193,194,191,193,192,193,192,189,193,192,193,191,191,193,191,191,193,193,190,192,193,194,193,194,194,193,196,194,195,193,191,194,191,193,194,189,193,194,192,192,192,193,194,193,192,192,191,191,190,192,191,192,193,192,194,188,191,191,192,193,193,193,191,194,192,195,193,195,192,191,196,194,195,195,193,193,194,194,194,192,195,193,193,193,192,195,193,196,194,190,177,179,193,197,193,192,193,193,195,198,201,199,198,199,196,195,195,193,192,193,201,198,211,219,224,229,170,178,200,194,209,179,144,129,113,116,121,132,115,100,108,75,123,214,226,132,115,203,216,213,212,203,205,202,217,198,136,94,26,22,95,216,247,131,64,84,151,150,105,133,152,163,157,121,227,160,109,210,136,107,110,161,241,204,106,84,87,99,63,70,107,125,148,111,73,56,41,25,38,44,63,108,131,133,112,113,118,115,108,108,116,96,98,103,101,106,102,92,86,98,101,113,105,88,62,13,69,148,169,161,123,74,37,31,40,60,60,79,75,52,39,55,100,142,184,118,44,32,17,17,20,23,23,23,21,27,29,32,31,27,21,23,28,22,25,26,23,25,27,21,27,36,35,52,74,81,78,74,66,60,43,37,34,34,36,49,55,51,46,48,50,53,50,42,62,58,60,57,48,50,39,45,54,60,46,47,48,42,47,46,51,31,98,119,127,139,103,112,75,68,64,34,36,37,48,58,60,64,69,89,90,88,81,91,87,90,118,114,111,105,134,130,117,116,103,124,120,130,122,130,150,131,143,147,159,172,153,104,94,92,62,55,57,60,57,64,51,19,17,16,20,22,18,19,43,86,120,136,99,106,160,175,177,180,154,84,76,86,57,60,57,57,66,46,68,132,170,209,203,159,136,118,137,137,148,141,51,9,25,12,16,26,46,85,79,62,46,36,36,38,40,40,40,50,55,55,54,56,63,82,105,118,122,131,136,134,129,119,123,111,104,108,103,99,96,101,94,87,90,88,80,81,77,81,76,71,70,68,76,76,67,90,145,148,152,164,155,131,67,36,28,26,34,30,32,33,37,48,57,66,73,63,57,59,49,45,44,49,49,51,51,44,41,38,38,44,41,39,36,36,45,47,41,50,57,87,132,165,137,77,46,20,22,95,96,44,21,21,43,56,100,150,138,133,133,118,128,116,112,117,114,120,121,122,123,150,170,182,212,224,228,231,229,220,214,113,5,2,7,11,14,12,13,12,15,15,14,15,198,198,198,197,198,197,199,198,195,197,195,198,198,194,198,196,197,198,194,196,195,199,198,195,200,198,199,210,252,211,142,210,198,200,200,194,200,195,200,198,199,199,198,198,196,198,198,198,198,198,200,200,200,199,198,201,197,196,200,198,200,198,197,198,196,199,199,198,198,198,198,196,197,198,199,200,198,199,196,196,198,198,196,199,199,198,198,197,199,197,196,199,196,196,197,196,199,196,196,197,194,198,198,197,198,195,198,196,196,196,195,197,195,198,195,194,194,196,196,196,194,195,198,193,193,193,196,196,193,196,198,194,196,192,195,195,192,197,192,192,195,196,194,196,194,193,194,194,193,192,194,194,192,192,195,193,194,194,192,195,194,193,193,192,195,191,191,192,192,192,191,191,189,192,194,190,194,191,190,192,192,193,193,193,193,191,191,190,192,192,191,192,192,194,193,191,194,193,193,193,192,196,191,191,194,192,194,192,193,193,194,192,193,193,193,196,196,195,195,195,191,193,194,193,195,190,196,195,193,191,190,193,193,193,192,193,192,191,194,193,192,194,193,193,191,191,193,193,191,193,192,193,194,192,193,193,194,192,194,195,194,196,187,178,184,197,200,194,192,192,194,194,200,201,198,196,194,198,197,197,200,199,214,195,220,234,232,201,110,174,215,198,226,178,124,102,71,103,177,154,97,83,83,65,69,110,148,136,134,220,235,221,216,220,214,207,218,159,150,163,94,96,113,197,209,91,59,36,79,97,65,113,188,252,253,163,131,88,89,125,67,65,26,79,155,101,94,93,88,58,71,117,136,135,103,79,53,35,27,24,55,70,114,141,129,124,107,114,110,107,109,109,109,94,102,101,95,97,83,75,79,94,112,122,120,71,23,5,74,132,129,111,56,51,52,32,37,48,62,69,54,40,50,99,132,132,125,71,30,39,32,16,23,22,26,26,24,29,26,38,32,25,25,21,24,25,28,26,23,25,25,24,30,27,34,41,61,78,77,79,76,71,53,30,32,27,30,44,45,41,42,46,42,44,37,49,76,84,98,59,34,32,42,78,78,72,60,37,39,36,33,45,34,48,85,109,135,90,93,71,67,68,44,26,18,23,55,80,77,83,53,62,84,72,71,77,42,27,66,78,71,41,60,69,53,72,30,34,72,84,57,31,51,55,63,55,37,35,36,27,94,138,119,118,122,113,116,104,46,16,13,16,19,18,29,23,77,141,114,81,117,174,139,115,103,105,141,128,67,69,79,91,91,101,119,153,150,200,245,198,158,101,76,76,79,91,112,122,59,19,19,12,16,18,24,43,72,89,78,62,54,55,61,60,55,53,56,63,61,69,92,128,95,143,149,142,145,141,147,146,141,132,142,156,151,151,145,144,151,149,144,132,139,143,133,141,142,144,148,87,155,160,150,152,174,212,176,165,170,140,105,67,51,52,57,60,59,56,64,99,128,143,136,125,132,123,113,112,122,125,123,131,118,102,101,98,109,107,94,87,81,94,94,74,41,60,126,153,155,164,147,111,77,54,101,148,125,93,92,136,153,145,157,160,141,140,137,132,136,127,125,122,124,131,129,132,119,120,127,138,168,178,189,211,225,221,219,115,4,1,7,11,11,11,14,12,13,14,14,14,194,200,197,197,197,196,195,197,196,198,197,198,196,194,197,193,197,200,197,197,198,197,198,198,198,199,195,203,251,209,162,214,194,202,196,197,200,193,198,200,197,198,199,198,198,198,198,198,198,197,198,199,198,197,199,201,197,199,199,198,197,197,200,199,197,195,196,197,198,198,199,197,196,199,198,198,198,196,196,196,197,195,197,198,198,195,194,198,196,195,195,198,198,199,198,194,195,193,196,196,196,197,193,198,194,196,196,197,197,194,196,196,196,195,196,194,194,194,195,196,194,194,197,195,194,193,192,195,194,192,192,192,194,192,193,195,194,191,191,194,193,194,193,193,194,195,194,193,193,193,194,194,192,193,193,191,192,191,194,192,194,194,193,194,191,191,192,193,193,191,191,190,190,192,189,191,190,191,195,190,194,189,189,192,194,194,192,194,192,193,193,193,193,192,193,192,193,191,193,191,193,196,195,192,191,194,194,190,193,190,189,193,191,190,193,193,194,193,194,195,194,193,189,192,193,191,195,193,193,194,191,193,192,191,193,193,192,191,193,192,192,191,193,191,191,193,191,192,193,189,191,191,191,192,193,194,191,193,191,193,196,193,196,185,177,189,194,197,193,191,195,192,195,198,198,198,195,193,189,191,196,199,211,147,139,191,150,122,138,232,244,188,220,171,117,94,71,107,180,182,92,51,60,46,37,21,51,74,118,207,221,204,200,209,207,199,178,121,165,209,138,107,100,131,139,93,66,35,35,27,17,84,205,247,242,154,76,81,199,150,53,61,4,31,85,88,116,83,53,86,115,146,129,83,60,40,37,23,23,44,76,115,133,134,121,110,110,112,106,110,113,108,110,102,104,101,90,83,73,71,87,110,120,129,76,26,21,6,66,114,122,89,77,101,60,31,39,51,54,47,44,41,54,110,103,84,91,47,29,43,43,29,17,17,21,23,23,30,32,38,33,25,26,24,24,29,24,25,27,27,24,26,25,27,32,36,47,69,80,84,88,81,69,51,39,35,30,37,43,48,45,42,41,39,38,76,130,121,113,63,28,73,118,121,89,77,54,36,40,48,44,39,41,29,81,74,109,99,62,76,46,63,53,16,20,14,55,110,113,116,71,81,125,125,124,128,66,25,94,133,102,19,49,94,95,87,18,37,111,160,57,57,132,98,115,81,29,22,30,18,97,152,109,129,136,130,145,101,29,10,15,14,22,21,23,24,78,152,81,94,173,95,60,57,53,23,36,104,77,65,100,139,168,171,218,182,148,213,139,38,20,16,64,71,73,48,85,169,90,25,17,11,26,18,24,35,87,133,123,111,104,106,111,89,42,31,39,41,49,44,38,55,65,66,74,61,68,56,50,71,69,59,53,59,66,65,64,58,59,72,74,64,62,76,66,60,58,74,86,80,102,111,88,116,160,143,150,136,129,118,81,77,58,53,59,60,70,70,92,122,133,133,128,128,131,141,134,141,160,145,145,153,150,159,159,163,168,160,170,174,168,159,152,76,50,129,153,158,140,137,135,140,175,171,182,186,153,151,159,170,171,157,149,137,128,142,139,133,137,127,128,130,126,131,136,130,120,120,115,113,125,128,134,170,212,223,223,115,4,1,7,11,10,11,12,11,13,14,14,13,197,198,197,198,199,195,195,197,196,198,195,196,197,195,198,196,195,196,196,198,198,200,196,197,197,199,198,206,252,217,185,215,187,200,195,194,200,197,197,196,197,198,198,196,198,198,198,198,198,196,196,197,199,199,198,200,198,199,199,197,199,197,197,200,198,198,197,195,198,195,198,198,200,198,196,196,193,198,197,196,197,196,196,196,193,196,197,198,197,197,196,196,195,196,196,194,196,194,196,198,196,195,198,196,195,197,194,196,195,194,196,194,197,195,193,196,196,196,193,194,194,193,196,194,194,194,194,196,194,196,196,193,196,195,197,195,192,193,194,195,192,193,194,193,189,191,192,193,193,194,195,195,193,192,192,191,191,192,192,191,191,192,194,191,190,190,190,191,192,192,192,190,188,192,189,189,193,191,190,191,190,189,191,191,194,192,191,192,192,193,192,194,192,191,191,191,192,191,191,194,191,192,191,191,193,189,192,191,189,189,190,192,193,190,190,192,191,191,191,193,189,191,192,192,193,191,192,191,193,191,190,191,190,191,192,195,192,190,190,189,191,191,191,190,193,191,193,191,191,195,189,190,191,190,192,192,193,192,194,195,192,196,193,193,181,174,188,196,197,194,191,192,192,190,196,200,199,200,191,190,186,187,192,61,60,100,42,19,61,130,161,103,148,122,110,99,78,108,150,148,98,49,76,86,66,73,27,29,64,88,162,151,150,165,165,169,146,103,121,129,62,84,66,79,120,104,69,9,45,25,28,126,184,245,235,173,107,174,253,158,86,48,2,65,105,105,89,57,97,119,137,116,72,55,37,30,16,26,59,87,112,121,132,116,107,113,101,103,107,117,116,107,115,110,107,90,87,81,87,99,109,128,118,78,34,18,20,29,100,102,87,100,102,122,72,37,43,41,46,40,45,43,48,84,87,73,69,56,27,26,37,35,26,12,18,19,22,33,32,32,27,27,26,27,26,24,25,27,29,26,25,25,27,27,31,37,54,79,84,91,114,106,86,72,54,41,37,39,44,47,44,41,39,43,42,85,115,114,104,40,39,109,125,132,104,73,49,27,41,41,40,37,36,46,47,87,74,41,63,32,46,59,40,24,20,12,44,110,113,125,68,68,122,107,128,150,71,18,103,137,93,20,38,106,114,118,63,50,124,160,57,103,164,108,141,96,29,32,45,25,119,164,117,116,110,119,124,74,19,14,14,13,20,23,24,23,67,138,66,122,157,64,77,71,97,51,11,87,91,61,73,124,174,182,144,72,110,169,54,8,66,72,92,75,89,71,64,140,107,41,20,12,18,21,28,36,106,152,144,133,134,139,150,97,37,43,46,53,61,52,58,66,72,93,97,89,92,43,36,105,102,63,30,30,64,79,72,43,39,74,83,64,60,71,75,54,39,63,78,51,33,29,56,87,99,136,121,110,117,88,81,59,36,34,28,36,43,41,46,55,66,74,63,53,57,70,68,65,61,72,76,108,74,69,79,83,92,96,96,109,94,96,74,49,103,150,152,138,129,129,134,158,192,194,185,171,156,160,150,151,145,129,127,124,122,131,128,125,132,127,131,128,122,125,122,128,127,126,122,115,127,122,110,136,184,212,224,116,5,2,6,11,12,12,14,13,15,15,15,15,196,200,198,198,198,199,199,199,199,199,198,200,196,194,196,197,198,198,198,196,197,198,196,197,196,198,191,204,251,224,194,210,188,203,193,198,196,193,198,197,196,196,197,195,195,195,196,198,197,198,198,195,199,196,195,198,196,198,197,197,196,196,198,194,196,197,198,198,197,195,196,199,196,197,197,198,194,194,198,197,196,196,196,197,196,195,199,196,195,196,195,196,193,195,195,194,195,195,198,195,194,197,193,193,195,194,197,196,194,196,192,195,197,196,193,194,194,193,194,192,193,194,193,193,194,193,191,193,193,194,193,191,194,192,191,194,193,191,193,195,193,194,194,193,190,191,192,191,190,193,191,193,193,194,191,192,195,190,194,189,191,191,188,192,191,190,189,192,192,190,191,190,191,193,192,192,190,191,190,188,191,191,190,190,191,190,189,193,189,190,193,190,193,191,191,191,190,192,191,190,192,192,189,190,190,190,191,188,191,190,191,193,190,188,192,193,189,190,189,191,190,189,188,189,189,190,190,190,190,191,193,193,192,190,191,191,191,193,193,189,190,191,190,189,191,191,190,194,192,189,191,189,192,192,191,194,190,194,192,191,195,191,193,194,188,179,174,187,197,193,193,192,191,193,190,191,198,201,200,200,189,193,197,82,14,87,56,5,5,10,7,43,89,72,96,89,71,99,84,108,111,98,128,93,73,75,53,40,31,50,109,111,103,113,125,146,140,99,84,64,29,61,53,56,117,101,53,21,43,14,74,203,178,142,123,97,87,160,234,106,54,23,24,146,117,67,82,97,140,137,90,66,57,81,65,24,36,64,123,128,106,121,110,110,109,98,90,102,117,111,106,114,114,105,95,81,84,83,99,116,125,116,67,31,14,23,46,98,135,88,76,92,93,102,77,43,30,34,40,42,40,39,37,59,71,72,63,50,38,18,25,29,18,17,16,22,24,24,27,32,28,26,23,24,25,24,28,33,28,28,27,26,34,27,31,41,74,91,84,100,109,81,64,75,73,44,33,39,41,45,45,42,43,39,35,55,96,104,92,38,40,121,142,130,126,117,56,31,30,39,43,36,51,49,105,63,54,81,36,54,39,61,68,33,27,14,35,100,99,81,35,51,113,107,138,120,34,4,84,130,90,19,51,112,115,131,115,99,126,133,24,57,92,79,116,58,21,36,40,36,151,172,108,108,85,98,106,63,24,12,15,12,24,25,27,20,63,137,72,120,149,59,43,55,137,93,21,104,104,65,36,39,69,48,24,60,176,176,19,49,129,42,105,134,105,92,41,130,126,42,24,13,16,20,27,37,122,163,134,123,119,133,140,80,22,44,62,58,74,73,83,74,83,121,131,129,132,41,47,159,131,55,19,31,97,110,77,33,42,114,125,67,78,121,117,97,88,136,104,45,26,35,50,77,107,95,112,93,92,78,69,65,36,32,24,34,43,44,50,61,94,95,65,57,74,84,52,35,66,79,81,68,39,41,41,44,46,34,36,37,39,38,42,88,142,158,130,130,131,142,146,151,174,167,167,162,152,150,145,143,137,130,132,134,129,129,122,121,126,121,128,127,117,117,118,124,128,124,122,128,141,139,120,117,149,168,196,118,6,3,8,11,13,12,14,13,14,14,15,15,198,200,198,199,199,198,199,199,200,200,199,199,200,197,199,199,198,199,197,196,196,199,195,200,192,193,179,169,248,212,186,208,184,202,194,196,196,192,199,198,195,195,196,195,196,195,196,198,196,198,199,196,197,196,198,195,194,196,198,196,197,197,196,197,193,196,196,196,198,194,199,196,196,195,195,199,197,198,196,195,196,194,195,197,196,198,194,196,194,195,197,193,198,196,194,194,196,196,194,193,193,193,195,193,192,196,193,196,195,194,198,194,196,196,195,195,193,193,193,196,193,193,196,194,195,198,194,193,191,193,191,190,192,193,194,192,191,191,191,192,192,192,192,194,193,193,193,191,193,195,192,192,194,192,191,193,193,194,192,192,193,192,193,193,192,191,193,193,193,190,191,193,190,191,191,190,190,191,193,191,190,191,192,190,188,191,193,190,191,190,190,189,189,192,190,191,191,192,190,191,191,190,191,191,193,191,192,190,190,190,190,190,190,191,191,191,191,190,190,189,190,190,190,190,188,190,190,192,189,189,191,192,193,190,192,191,190,191,190,192,191,190,191,191,194,190,191,190,191,193,192,193,192,191,192,192,191,191,192,190,188,190,190,193,194,189,176,174,190,196,195,195,192,191,194,192,191,198,199,204,198,212,250,137,80,149,133,62,3,9,5,25,92,70,80,73,77,113,84,92,141,147,107,59,53,72,35,46,44,57,112,141,135,128,141,156,152,155,154,113,97,97,81,105,137,94,51,93,63,8,69,126,93,107,74,44,29,141,191,49,24,4,39,122,77,86,114,131,141,82,67,72,103,147,84,48,72,108,143,114,105,109,102,106,103,90,77,94,109,106,109,114,106,84,83,84,88,89,110,131,108,64,20,19,27,61,108,127,155,157,132,87,84,114,75,33,23,28,29,38,36,28,29,39,59,60,61,55,42,22,26,39,36,31,19,16,24,25,23,27,26,24,22,26,29,23,27,29,31,31,26,25,26,33,30,37,64,77,76,74,66,50,48,63,70,46,35,36,39,46,40,42,37,39,37,59,99,105,89,36,39,101,103,92,127,110,54,28,32,39,45,39,42,110,144,155,168,150,145,129,131,147,157,117,30,9,30,87,75,43,11,53,125,116,134,103,34,11,84,129,86,18,53,116,130,128,122,143,147,133,21,24,65,85,133,71,19,31,33,53,174,163,102,92,75,82,87,69,29,14,15,19,29,24,25,24,57,144,100,107,112,51,69,141,226,96,15,111,130,89,59,44,78,39,60,204,241,155,11,60,117,62,120,115,113,90,134,179,114,51,15,14,16,27,24,41,141,152,110,95,88,102,105,61,22,34,50,67,77,77,76,56,65,92,71,99,121,34,54,153,100,42,22,28,98,95,69,24,28,102,114,46,63,123,128,129,142,152,85,33,28,29,57,71,63,86,59,63,65,34,60,55,40,30,27,39,39,47,46,68,105,114,113,112,120,64,39,92,105,124,101,52,42,39,51,51,39,37,32,45,35,45,113,148,173,152,127,133,144,153,152,150,151,149,157,154,145,155,147,142,151,147,147,150,146,146,141,136,139,136,139,132,128,123,121,135,130,117,117,130,146,146,130,121,128,130,157,111,12,2,9,11,14,12,15,13,13,15,15,14,193,200,199,199,199,197,198,195,199,203,198,199,200,199,198,198,199,198,197,198,196,198,195,200,197,204,183,157,214,172,178,203,188,203,191,198,197,195,201,196,195,199,197,196,196,196,196,195,196,196,198,198,199,194,195,198,197,197,196,194,196,196,198,198,197,197,197,196,193,198,198,198,196,196,198,198,195,195,198,195,197,197,193,196,197,195,195,195,197,196,195,195,193,193,195,195,194,192,194,195,193,194,196,195,194,193,195,193,192,194,193,193,193,194,192,193,193,193,196,192,193,196,194,193,193,193,195,195,192,194,192,192,194,193,195,192,191,193,193,195,191,191,192,191,193,192,193,193,192,191,190,194,192,191,191,192,193,189,192,191,191,192,190,192,193,191,190,192,189,187,192,190,189,191,190,192,188,190,193,190,191,190,191,187,189,191,191,190,189,189,188,189,190,190,188,189,187,193,190,189,191,188,190,191,190,191,194,192,190,189,190,191,191,189,189,190,190,191,188,193,191,190,191,189,191,191,189,188,189,188,192,191,189,191,193,193,192,192,192,189,189,191,190,191,194,191,190,191,190,191,193,190,191,191,192,193,189,191,192,189,189,193,191,194,190,193,187,172,179,190,198,194,191,191,191,193,192,193,192,196,196,232,253,177,148,216,204,190,155,117,62,47,83,74,92,56,78,159,120,98,109,143,116,29,24,39,30,43,35,39,106,113,110,98,93,95,162,205,170,159,125,153,150,128,141,59,88,207,100,33,77,39,66,163,123,41,57,185,152,15,6,15,114,131,97,130,134,120,95,70,76,132,153,164,90,55,84,98,127,99,92,97,98,103,93,82,71,80,94,103,107,97,77,83,96,92,97,98,124,110,53,23,14,28,68,114,125,129,147,144,120,89,112,109,61,45,21,17,29,34,35,33,27,30,37,42,51,56,44,27,37,59,63,46,24,16,21,17,26,26,23,26,23,26,30,24,26,29,23,29,28,27,27,29,32,34,47,55,57,63,61,56,58,60,39,22,32,41,45,40,37,43,39,40,33,71,104,98,88,42,16,41,61,63,71,54,42,34,33,41,41,44,35,113,204,190,201,199,196,212,205,212,209,147,37,7,22,74,78,46,14,44,116,98,103,119,58,24,96,132,83,14,38,117,123,80,83,127,158,144,20,57,99,98,134,66,15,33,32,81,186,132,78,79,60,74,81,71,37,14,14,19,24,26,27,19,40,101,111,98,74,76,122,230,215,57,8,90,164,153,113,98,119,136,203,248,202,119,10,54,111,93,125,85,66,150,173,183,108,10,22,14,13,33,27,59,148,133,85,69,56,67,72,57,27,17,43,78,83,83,90,79,87,54,30,83,113,34,57,139,84,44,22,28,90,92,61,25,37,105,102,31,79,113,75,96,113,131,69,30,24,30,54,69,88,45,62,68,40,43,57,59,47,36,24,28,35,46,58,49,57,98,110,85,61,31,35,88,116,114,75,36,33,42,57,53,46,35,42,48,63,135,170,160,156,148,130,145,148,144,145,136,137,139,150,149,149,165,155,146,150,148,150,153,152,158,155,157,162,156,160,153,141,142,137,141,131,116,118,128,135,139,134,121,120,113,139,107,14,2,10,10,14,12,13,12,13,15,15,14,195,198,194,198,199,198,196,196,198,198,199,197,198,197,199,199,198,200,198,199,197,198,196,200,200,225,228,167,153,135,169,197,191,200,193,198,200,198,198,197,196,198,199,198,197,198,196,196,195,196,198,196,198,196,195,195,197,199,198,196,197,194,195,197,195,196,197,196,196,196,199,196,196,197,197,198,197,197,196,196,195,194,195,197,196,195,195,196,194,194,194,191,196,196,193,193,194,194,192,194,194,194,195,193,190,194,193,193,195,193,193,193,195,193,192,193,195,193,194,194,190,194,194,192,192,192,191,194,193,190,194,193,192,193,194,193,192,193,194,194,193,191,191,192,190,190,193,190,190,193,190,189,191,190,192,191,189,193,191,191,189,191,190,188,190,188,191,191,191,192,192,190,190,192,190,190,192,189,191,189,189,191,190,190,190,190,189,188,189,190,190,190,191,192,189,191,190,188,188,187,191,188,191,196,189,200,205,194,193,189,191,191,188,190,190,190,190,191,191,192,192,190,191,191,190,192,191,193,191,190,190,191,190,189,192,190,192,192,190,191,193,193,192,191,193,191,191,190,189,190,191,190,192,189,189,191,193,191,194,193,188,191,190,190,192,193,195,186,177,180,193,199,195,195,193,192,194,194,194,187,191,234,234,162,163,218,229,236,244,249,200,126,95,69,91,56,73,155,120,75,55,91,119,81,52,60,33,43,43,27,99,33,39,21,18,50,149,173,125,113,90,128,127,80,102,31,103,194,99,170,177,35,131,211,118,60,125,214,122,23,18,109,212,165,127,139,113,93,81,54,87,122,150,165,81,59,76,90,113,89,85,104,110,108,93,85,78,89,94,95,97,83,83,99,107,102,103,113,94,50,22,20,27,77,116,123,131,133,129,87,77,98,95,84,39,49,39,31,30,31,36,33,31,26,29,35,48,51,35,27,48,72,66,57,37,14,15,22,24,22,21,23,25,28,32,27,28,26,27,29,31,30,30,24,34,67,81,86,92,91,91,95,95,75,62,56,71,83,112,77,73,73,74,73,68,97,104,97,91,56,46,51,70,76,66,55,51,53,55,56,63,53,72,150,157,117,97,89,107,111,108,103,113,78,33,33,41,71,114,67,29,76,108,87,97,117,95,79,121,129,92,19,70,116,101,50,25,92,137,144,41,35,98,116,93,29,25,37,44,139,178,84,66,61,64,70,71,81,44,25,24,17,29,32,27,23,19,44,66,96,101,95,131,165,95,15,14,18,84,147,156,170,137,178,171,167,119,50,6,13,32,77,116,74,84,121,161,108,24,27,15,21,16,27,35,83,160,103,54,55,49,57,70,66,32,15,33,74,83,101,126,113,77,21,23,96,112,29,70,146,75,57,43,54,121,93,66,45,64,128,99,28,95,117,45,30,57,104,63,31,26,35,86,121,119,129,120,98,81,69,97,103,88,55,26,26,35,73,92,57,72,98,104,63,56,40,39,107,108,93,48,29,40,42,65,66,45,39,36,81,147,173,142,87,103,129,130,153,154,144,132,126,130,135,146,150,155,162,151,146,142,139,144,155,155,155,156,155,159,155,155,151,147,147,142,141,131,122,129,136,137,132,120,107,112,118,144,105,15,3,10,10,14,12,15,13,14,15,14,15,191,196,195,195,195,194,196,195,198,195,198,198,196,195,197,198,196,199,198,197,197,199,196,196,193,223,230,149,132,133,170,198,193,200,193,199,197,196,199,197,196,196,196,196,198,197,196,197,198,195,197,198,198,198,197,198,199,197,199,197,198,197,196,197,196,196,197,198,198,198,196,198,197,198,199,198,197,197,196,194,195,196,196,194,194,195,196,194,193,194,195,195,194,192,195,195,195,196,193,194,192,192,193,194,192,193,196,193,193,195,195,193,195,195,192,193,191,191,193,191,192,189,190,193,194,192,192,193,193,193,193,193,192,191,193,194,192,194,191,193,193,191,193,190,190,189,193,192,192,191,192,191,189,191,189,191,192,190,190,191,189,191,191,189,191,190,189,190,189,190,190,188,189,191,190,189,189,189,191,189,188,191,191,188,191,190,188,187,188,191,189,191,191,193,196,196,195,193,191,192,195,197,198,204,195,190,208,202,192,191,189,192,193,189,191,190,191,190,188,191,187,190,191,190,189,192,190,190,193,189,190,191,189,190,188,186,190,190,191,190,188,191,191,191,190,190,191,189,192,193,192,191,190,191,191,191,191,190,192,193,191,193,191,191,192,195,194,197,187,178,189,199,206,199,199,200,201,203,199,188,204,252,212,142,159,206,217,229,241,251,217,145,97,68,93,91,81,112,136,110,57,49,97,141,151,95,31,49,93,116,126,118,107,93,80,92,139,132,108,69,63,95,77,69,81,75,71,86,104,197,129,46,165,165,57,68,175,204,125,55,91,211,219,152,137,102,84,76,31,33,46,70,136,154,69,58,69,86,112,73,95,106,114,120,100,96,89,101,102,98,92,91,101,113,118,104,110,78,37,19,22,38,77,120,131,117,121,122,117,101,98,95,62,13,25,105,98,49,22,22,29,27,28,29,23,28,47,55,37,30,61,77,66,60,51,46,42,29,18,19,22,22,24,30,26,27,29,26,30,30,27,27,32,28,50,139,179,178,168,161,166,162,179,169,155,161,164,174,173,175,182,180,179,170,163,160,139,136,148,151,170,174,162,162,180,161,139,143,153,166,165,162,175,184,147,93,83,78,83,93,88,100,112,122,137,145,160,174,159,173,167,165,158,138,150,157,150,145,164,159,150,136,144,141,134,122,104,122,141,151,108,126,133,128,125,94,111,127,152,199,164,108,116,110,115,118,115,123,92,75,70,64,76,75,75,67,68,53,57,98,116,129,121,81,29,38,56,27,48,86,121,137,135,125,118,109,43,28,39,31,26,54,100,89,91,117,74,35,39,31,38,33,39,48,54,141,169,70,52,55,60,70,71,76,49,24,28,71,52,54,110,87,41,14,57,121,89,30,103,134,92,111,89,97,129,96,95,78,75,134,85,23,99,107,47,12,34,98,61,40,17,44,132,160,181,158,169,159,152,162,165,171,159,86,32,18,35,114,123,103,99,104,100,111,135,86,76,100,87,71,33,26,41,63,81,63,47,38,41,106,183,174,110,40,64,122,138,166,158,142,135,132,135,137,146,139,134,139,139,143,136,136,141,148,147,146,145,144,143,139,144,143,141,145,144,145,145,144,146,148,139,129,118,111,119,129,149,104,14,2,10,10,14,12,13,13,13,13,15,14,192,198,194,195,196,194,194,194,195,197,195,193,199,195,195,195,193,196,195,196,196,196,195,198,189,200,198,170,193,176,181,196,192,200,195,198,197,195,196,199,197,197,198,196,195,198,196,196,196,195,199,196,198,197,198,198,195,196,196,196,197,198,200,199,197,197,198,196,196,197,195,197,198,197,198,196,197,194,194,196,196,198,196,196,194,194,193,195,196,195,196,193,195,196,193,194,194,193,191,193,195,193,192,193,193,193,194,193,192,193,192,193,193,192,192,193,192,190,192,192,190,191,192,192,193,194,194,196,193,194,192,191,192,190,190,189,191,193,190,188,189,190,192,191,189,191,192,190,189,191,190,190,192,191,192,193,194,193,191,196,192,192,190,190,192,188,190,193,189,187,188,187,186,190,186,184,190,189,190,188,187,187,188,189,190,191,192,189,191,193,190,195,196,206,212,212,211,204,205,205,209,212,214,210,157,148,182,202,201,191,191,190,190,190,189,187,189,191,187,192,190,188,190,190,193,189,190,191,190,190,188,191,190,189,192,190,192,189,189,193,188,189,190,188,189,190,190,191,189,191,191,191,191,191,192,187,191,191,193,192,190,193,196,198,203,206,201,202,207,197,190,198,211,211,207,208,213,212,211,193,229,234,169,130,143,181,208,217,234,221,168,118,87,59,77,86,101,111,119,147,127,93,93,149,168,126,59,35,104,165,201,214,216,212,183,164,137,130,116,75,114,97,107,171,124,157,136,59,38,81,53,71,179,107,8,87,178,136,60,76,179,245,171,121,101,79,59,36,14,39,55,71,140,126,48,55,71,86,99,69,95,102,97,111,102,89,89,100,85,87,105,102,108,116,117,93,76,39,13,24,48,79,108,129,129,111,112,112,105,73,93,63,56,16,103,196,127,46,28,11,21,24,24,18,24,32,62,75,37,36,63,76,77,71,62,56,49,35,22,19,20,24,26,28,29,28,29,28,29,33,31,28,30,31,53,126,151,103,81,81,83,88,90,113,91,76,78,81,113,105,109,119,106,102,106,97,78,84,101,113,129,130,130,133,135,128,128,125,128,130,130,127,134,119,90,92,95,93,100,101,107,120,137,144,149,160,162,167,109,151,154,153,139,134,139,136,127,128,132,134,100,139,160,154,159,147,147,155,132,146,141,174,159,148,160,161,190,183,177,181,156,145,163,161,169,165,167,181,174,184,179,175,178,178,183,179,169,162,153,139,144,153,142,141,130,145,159,140,144,141,150,149,146,147,139,121,117,121,100,124,120,114,134,133,133,113,103,91,113,131,118,147,154,160,172,209,179,112,115,121,127,129,137,132,96,73,91,106,63,81,106,81,92,68,124,132,101,83,127,128,105,130,105,97,111,96,111,74,84,123,79,59,100,91,39,33,79,104,64,51,36,66,143,159,143,113,108,116,121,124,126,134,137,71,29,27,29,73,99,92,95,57,54,113,139,98,56,75,63,41,34,27,46,70,65,56,49,36,27,61,131,149,114,74,113,137,137,158,146,137,136,141,136,139,141,131,126,124,128,139,145,142,131,130,127,125,125,130,136,136,141,141,145,151,148,152,152,148,147,142,136,136,146,153,151,132,142,105,13,1,10,10,13,11,14,13,14,15,14,14,193,196,194,195,196,194,195,194,195,195,195,195,194,195,195,196,194,195,196,193,196,197,193,196,193,203,203,212,249,213,191,202,192,203,194,198,196,195,200,197,197,199,199,200,198,195,196,196,196,195,197,196,195,197,196,195,199,195,197,198,194,196,196,197,196,194,195,195,197,195,195,194,193,197,196,194,197,194,194,194,193,195,193,194,194,197,195,193,192,193,193,193,194,192,194,193,193,191,192,193,194,196,193,193,192,192,192,193,193,191,191,192,191,191,191,190,190,190,192,193,193,191,194,196,198,203,208,204,203,199,192,193,190,191,194,192,190,191,190,193,190,190,192,191,191,188,192,190,191,191,190,189,190,194,193,205,206,204,205,205,200,191,188,191,189,189,191,189,190,191,192,191,189,194,186,188,191,188,192,191,190,194,193,191,191,194,200,200,207,210,204,207,198,196,195,196,218,216,214,211,201,209,201,181,133,101,155,204,205,204,195,190,193,189,192,190,190,191,189,191,190,191,191,192,190,192,191,190,190,187,190,190,191,190,187,190,190,190,189,187,191,191,191,191,188,190,191,189,190,190,192,192,191,191,189,188,191,195,196,196,198,205,202,200,210,214,204,205,200,200,188,174,196,202,206,194,195,211,204,194,252,224,130,126,116,141,155,169,199,183,122,93,68,49,67,105,120,118,124,108,131,141,144,145,152,151,80,18,12,22,84,141,167,197,180,171,144,143,110,86,168,133,148,171,139,232,170,58,118,107,57,120,194,72,9,131,161,110,67,125,213,185,111,87,81,53,28,18,17,95,81,72,145,94,42,62,70,99,121,92,105,85,92,102,87,91,81,73,62,81,107,118,122,105,105,70,29,22,18,64,106,113,123,119,128,114,107,98,73,66,88,93,80,118,188,201,96,42,31,9,16,18,27,20,18,27,54,60,35,62,91,103,84,62,53,42,32,25,19,18,18,27,27,22,24,25,31,28,31,29,29,30,34,28,44,117,120,112,97,79,85,71,71,66,69,63,59,67,60,55,65,62,57,61,61,60,56,59,63,60,63,54,57,55,51,57,54,62,56,49,50,57,55,48,49,54,58,57,66,66,54,57,60,56,49,53,55,52,46,51,44,46,48,49,46,40,47,41,46,39,41,48,60,63,57,52,51,55,50,53,50,70,61,67,69,66,81,67,75,77,61,76,83,87,93,86,92,105,98,105,96,97,102,98,117,110,109,113,112,109,92,102,112,120,124,148,145,134,153,128,118,105,106,108,102,118,120,141,139,144,149,136,125,112,121,123,123,143,158,161,173,185,196,176,159,170,148,133,150,146,158,162,165,170,165,168,179,173,144,142,154,148,149,156,158,158,143,147,157,136,133,142,132,136,138,129,145,127,125,147,133,136,152,153,146,150,166,166,136,153,151,165,180,155,127,76,77,77,83,92,87,95,105,80,63,58,59,87,103,118,94,62,67,110,134,92,84,81,52,57,54,59,67,76,73,61,63,51,42,35,66,114,138,129,132,124,131,156,141,138,138,145,134,131,137,127,124,121,122,137,127,123,125,123,122,121,122,132,144,139,142,145,149,151,147,145,144,137,130,130,136,151,179,189,174,153,153,104,12,1,9,9,12,11,14,13,13,14,14,14,193,198,197,194,194,194,195,196,191,194,195,195,197,194,194,196,191,195,198,193,196,196,193,198,196,202,201,225,248,214,193,202,192,203,201,204,205,203,204,204,205,205,205,203,200,199,196,197,198,198,198,197,198,197,194,196,195,196,196,196,196,195,194,194,197,196,195,194,193,194,196,196,196,193,195,196,198,195,195,197,196,195,193,194,197,195,196,197,195,193,193,194,196,193,193,192,192,193,193,194,193,195,192,194,195,191,191,192,191,191,193,192,191,191,190,191,191,190,191,193,193,194,198,203,207,216,211,213,212,203,198,194,195,195,193,194,197,193,192,196,193,194,196,193,195,193,199,203,196,197,195,190,193,192,196,203,202,209,199,202,200,190,193,189,191,189,190,194,196,206,203,203,209,220,205,199,204,200,203,203,208,211,208,208,208,217,213,205,220,223,218,219,177,139,122,131,176,185,181,166,145,140,133,139,114,101,141,196,218,220,213,203,206,201,201,196,190,193,190,194,192,193,194,190,193,191,190,190,190,193,190,195,192,190,191,190,194,191,192,193,189,193,192,192,194,190,188,190,190,190,189,193,193,195,197,196,202,204,208,210,211,213,193,164,169,192,185,173,163,151,149,134,155,164,144,137,139,159,153,174,246,167,119,137,97,112,100,121,147,150,127,84,69,58,84,118,136,143,128,130,96,100,174,159,136,156,93,25,15,18,26,16,17,57,80,96,110,124,95,108,221,146,73,87,105,161,89,115,243,155,92,159,175,85,85,173,189,170,152,167,151,92,66,63,46,22,19,33,65,134,77,74,129,64,45,65,76,114,132,95,110,93,98,110,84,86,78,71,62,90,112,125,129,98,59,37,22,26,45,111,127,121,115,123,118,108,100,83,88,77,114,125,135,165,174,139,59,34,39,24,14,17,27,21,21,22,27,47,68,94,101,93,67,37,30,23,19,18,17,16,15,24,22,24,25,29,27,27,29,29,30,30,35,26,49,124,105,166,155,147,146,142,141,142,157,157,155,148,130,127,126,127,115,117,117,105,115,116,121,118,123,129,129,124,130,134,86,140,141,141,90,139,142,132,125,123,135,136,138,131,120,114,113,115,103,102,105,110,108,103,104,99,103,110,107,97,101,101,101,107,102,96,93,92,105,95,84,87,79,83,83,94,81,93,83,63,77,94,85,73,59,60,51,56,57,65,57,61,63,61,55,58,67,59,64,59,59,60,56,64,59,57,51,54,60,55,59,54,59,50,50,49,47,52,50,50,57,61,114,66,62,57,61,50,51,49,59,59,56,56,51,63,53,51,47,43,45,57,66,61,72,73,84,82,85,113,99,100,84,97,96,91,105,104,98,103,111,110,101,96,96,102,96,106,114,105,119,105,118,123,92,101,131,141,151,151,148,139,142,158,158,153,141,128,103,88,87,78,79,98,96,97,109,104,125,121,121,130,128,139,130,119,127,134,128,117,116,113,112,119,124,127,134,137,102,127,145,123,115,105,107,129,143,145,141,131,147,161,160,162,159,157,131,124,122,112,118,115,115,118,104,116,132,141,140,132,127,138,141,139,145,146,150,153,149,150,146,144,145,142,149,161,185,191,185,169,172,110,9,1,9,10,13,12,13,12,13,14,14,14,191,198,196,196,193,191,195,194,196,196,194,195,194,198,197,193,193,190,195,193,195,198,193,197,196,199,194,223,247,207,182,198,191,203,215,224,222,224,229,227,228,227,221,217,211,202,196,199,198,198,196,194,197,194,194,194,196,197,194,196,197,196,196,194,195,194,194,196,195,193,194,194,196,199,192,195,198,194,197,196,195,198,197,195,196,192,193,195,193,196,195,193,195,194,194,191,190,193,195,191,193,192,189,193,193,193,190,194,194,192,193,192,192,193,193,193,192,193,191,192,193,196,193,191,177,166,174,168,194,206,198,202,203,202,203,211,207,205,202,206,200,205,208,201,204,200,223,216,210,209,198,194,193,192,163,160,162,155,147,173,196,192,193,193,191,190,199,198,214,225,211,207,214,243,218,205,218,213,219,216,217,220,220,219,217,220,205,155,150,177,184,189,150,114,92,78,108,117,119,111,86,80,81,90,118,114,129,177,184,214,229,223,225,218,217,208,207,204,197,199,207,203,199,198,197,202,198,195,204,202,200,203,201,200,201,206,203,201,203,204,205,198,192,192,190,192,193,191,193,191,193,196,200,204,205,209,208,198,186,183,188,191,153,110,118,148,146,137,127,115,122,116,115,105,84,73,80,97,84,163,224,111,115,125,97,117,102,127,116,133,163,113,70,63,81,112,145,158,118,127,115,59,135,149,93,144,122,47,28,24,34,31,25,42,16,9,36,58,88,150,205,155,95,57,80,69,33,166,236,101,103,156,162,155,164,208,179,191,192,139,71,56,55,37,26,31,54,90,136,152,63,78,110,33,51,76,83,106,88,79,104,77,86,91,61,58,64,81,87,102,113,130,112,46,27,17,29,62,93,123,117,112,123,110,112,101,81,103,101,92,113,122,118,108,110,83,45,31,43,48,24,14,21,24,22,25,31,47,76,84,67,51,39,27,23,17,15,15,23,22,19,21,19,28,27,24,27,30,32,28,31,29,33,34,36,63,70,65,60,48,65,66,65,74,78,77,72,66,65,64,72,75,72,80,75,76,73,75,84,88,95,94,107,97,108,113,106,120,118,125,116,128,122,114,112,108,120,120,127,115,114,119,119,122,111,124,118,117,127,118,122,118,116,130,131,134,128,124,144,142,141,134,130,139,133,132,132,120,125,128,139,143,129,146,129,126,125,132,136,117,114,109,106,108,114,113,116,117,118,121,106,118,118,123,137,134,134,125,132,141,135,127,121,123,120,116,114,101,95,95,107,113,115,111,107,109,103,106,105,112,112,108,113,106,103,100,102,96,93,83,80,76,79,84,72,74,68,74,73,57,59,61,63,63,62,60,66,62,70,69,65,69,65,71,61,69,63,57,60,55,65,59,52,60,58,56,57,56,63,61,48,57,46,54,59,63,62,57,62,61,61,55,60,57,58,59,61,56,60,64,62,69,71,74,83,85,89,91,83,88,80,79,86,81,80,81,95,101,104,119,110,108,115,120,118,123,137,132,129,122,118,106,104,106,108,103,115,120,116,132,130,122,99,104,106,101,107,107,103,102,97,112,135,141,141,137,135,129,136,135,137,141,138,142,146,158,165,160,163,158,152,157,173,181,179,163,167,110,10,2,9,10,14,12,13,12,14,15,14,14,196,198,194,195,198,196,198,197,196,198,198,193,198,197,196,198,196,195,196,196,198,197,192,196,196,203,192,227,248,195,175,194,185,191,217,229,231,234,234,237,243,241,239,233,217,201,198,199,196,193,195,196,197,196,195,198,195,197,198,197,196,196,196,195,197,194,194,195,195,198,195,193,194,194,193,195,196,196,196,194,198,195,194,196,196,194,191,193,194,193,192,193,196,191,195,195,194,195,192,194,195,193,192,194,193,191,196,194,192,191,193,194,191,192,190,191,191,191,193,193,193,192,183,139,99,106,98,110,171,206,208,214,216,213,218,216,215,211,220,222,207,217,215,209,201,195,211,210,204,210,207,198,208,188,148,134,114,125,111,158,200,196,205,196,200,200,203,185,177,181,153,157,188,204,171,175,196,190,179,167,160,167,173,164,151,168,142,81,83,96,112,130,116,122,117,96,87,84,96,98,97,89,87,111,135,116,106,108,110,168,188,182,188,193,206,207,211,216,205,196,201,204,203,199,193,204,205,199,211,202,189,201,208,203,198,201,206,197,191,195,199,205,199,201,202,202,204,205,201,200,200,198,193,186,192,193,179,155,133,130,136,142,125,106,109,131,131,126,121,116,119,109,100,91,76,55,59,71,78,195,193,85,113,99,100,112,83,166,152,126,180,124,79,57,75,106,120,133,95,101,92,78,104,105,89,107,129,112,97,76,95,74,48,22,11,15,61,81,95,108,142,199,113,105,173,75,36,158,166,55,116,132,127,181,200,190,156,181,189,149,82,61,51,42,59,72,81,107,136,116,69,96,80,25,56,83,86,101,77,59,89,51,36,71,46,41,49,70,83,97,90,84,49,19,21,39,75,110,127,127,116,114,105,106,97,93,100,106,113,91,118,117,99,82,57,63,53,31,27,45,31,14,17,22,25,25,32,34,50,51,32,33,33,21,22,19,21,35,44,39,22,19,23,23,25,29,28,27,30,33,29,32,35,28,30,28,32,37,39,52,59,55,50,37,22,21,20,23,33,43,44,43,45,44,43,38,45,41,45,43,44,47,42,43,40,42,65,41,38,35,70,37,39,36,39,35,34,38,40,44,42,44,44,41,42,43,40,42,47,47,45,41,45,46,44,48,47,40,46,52,53,51,44,47,48,46,44,50,50,45,48,51,47,51,51,51,53,49,55,50,54,54,54,58,59,62,60,65,57,59,73,68,69,79,92,91,98,85,97,98,97,100,103,101,87,100,99,88,94,98,104,110,114,116,114,119,115,116,110,121,119,122,130,123,137,125,84,139,136,123,127,132,128,137,125,130,135,122,113,102,107,98,100,106,96,99,108,120,116,132,130,125,133,125,128,125,124,131,127,122,88,121,124,117,117,119,84,120,115,108,78,89,95,98,107,110,97,113,122,104,95,101,107,110,94,91,98,96,101,103,97,98,94,86,86,79,86,76,55,68,65,66,70,71,74,79,88,83,90,88,78,82,80,83,107,67,119,66,69,65,61,53,52,55,50,49,53,47,46,56,59,59,73,106,124,121,120,103,91,91,83,92,98,109,132,143,133,133,136,130,127,126,129,130,127,139,147,153,160,152,149,142,158,165,163,139,138,107,13,2,11,10,14,11,14,12,14,15,15,15,196,200,195,198,199,197,200,197,197,200,199,198,196,198,198,195,199,197,197,196,197,201,195,199,199,202,195,234,248,206,177,188,151,105,122,128,125,133,132,141,145,149,166,197,208,198,197,200,197,195,198,198,195,195,197,198,196,194,197,196,194,193,196,196,196,197,195,197,194,196,195,193,198,195,193,196,196,195,195,195,194,196,194,194,196,195,195,196,196,194,194,194,196,191,193,193,191,196,195,193,197,198,196,195,195,194,195,196,192,191,193,194,194,195,193,196,194,196,199,204,198,208,189,129,112,113,108,105,163,205,201,200,205,185,162,177,179,178,199,207,162,166,211,213,179,121,131,141,156,205,217,211,223,200,144,127,124,139,130,170,209,210,216,210,210,213,206,133,91,86,69,117,167,158,119,114,133,122,105,83,80,81,92,87,77,96,92,78,69,68,71,83,88,117,122,96,89,89,107,114,122,126,122,122,121,92,75,81,62,81,85,85,100,108,132,148,175,202,182,145,156,171,179,169,169,191,181,155,176,166,141,162,179,174,154,172,178,154,143,149,176,203,205,212,220,217,210,205,211,207,201,179,156,152,150,149,134,122,106,101,110,106,91,93,109,119,124,128,123,114,120,113,112,111,127,91,76,72,105,232,157,70,98,88,101,110,112,197,165,110,175,147,77,56,63,74,47,65,108,118,104,75,101,101,79,86,105,177,171,130,122,114,78,100,97,92,208,147,111,132,117,126,81,171,189,87,85,171,140,65,141,83,89,186,153,97,104,184,208,189,91,57,51,63,90,74,63,67,88,74,55,81,59,29,60,79,89,99,79,59,72,48,42,63,46,42,57,64,70,80,60,39,22,29,52,76,119,132,132,135,120,101,102,96,89,107,101,111,107,99,99,63,68,59,56,65,62,42,15,20,22,19,15,15,23,22,29,31,31,26,27,29,24,25,24,25,24,40,44,30,24,23,16,24,27,29,30,29,32,29,31,31,31,32,33,29,31,40,63,72,75,56,32,25,15,22,24,33,48,49,46,52,48,44,47,43,46,44,41,47,42,41,49,43,39,41,38,40,37,42,39,38,39,38,41,34,39,33,36,40,35,47,39,44,42,37,44,39,46,42,40,48,46,46,46,48,53,46,45,46,46,48,45,44,44,42,46,37,38,36,41,44,34,42,37,37,36,40,41,34,40,36,37,40,39,41,41,43,40,44,41,41,37,42,43,40,42,39,38,39,39,39,41,39,43,41,37,45,41,44,43,37,45,44,41,44,40,48,42,42,46,39,44,41,41,48,44,42,43,41,47,45,47,49,49,55,50,51,49,47,46,47,51,53,50,49,59,60,67,71,72,82,81,81,83,95,92,100,99,90,96,95,104,103,101,99,105,112,113,113,103,116,111,112,119,119,129,130,128,126,128,123,134,131,117,124,116,120,134,137,126,128,122,115,120,114,111,105,99,107,109,110,122,119,122,125,123,122,117,118,117,117,120,121,107,104,118,113,118,113,101,84,84,72,74,73,68,70,55,63,63,73,105,149,160,154,139,112,98,94,84,76,87,110,141,149,150,142,144,135,128,130,120,109,98,104,111,118,138,142,136,126,136,147,147,120,122,100,16,2,11,11,14,11,14,13,15,15,15,14,190,194,193,198,200,198,200,200,203,203,205,204,203,202,196,198,197,196,199,194,196,196,196,198,196,202,198,243,250,207,180,194,117,18,5,11,9,14,15,19,16,17,57,150,199,200,201,202,200,197,202,198,195,198,199,201,200,198,198,196,198,196,195,197,199,198,197,195,196,196,195,198,198,196,198,199,194,195,199,198,197,196,195,196,196,195,196,196,197,197,196,196,195,194,194,195,195,197,195,196,200,196,200,204,200,200,199,198,197,195,196,194,195,193,198,203,203,213,215,215,210,202,196,156,139,159,141,133,162,171,146,150,158,105,95,115,120,114,136,141,79,108,189,211,130,62,66,67,106,174,210,194,192,161,121,112,100,123,130,175,193,193,203,194,200,203,191,103,49,57,101,159,165,131,102,87,100,92,76,69,69,69,77,85,87,104,101,91,98,92,94,100,98,115,113,91,93,109,116,120,130,125,110,87,84,71,66,77,67,71,54,64,80,75,97,120,142,165,155,123,132,149,152,152,149,161,147,119,146,145,129,145,146,141,141,154,153,138,142,145,159,181,190,188,186,184,164,167,184,184,171,156,150,130,124,115,118,124,102,103,111,143,123,109,101,90,104,102,107,104,141,163,161,164,182,159,104,88,166,241,118,81,102,94,145,173,174,229,188,94,146,158,107,55,61,77,35,53,134,211,169,83,89,113,97,89,82,149,196,187,159,149,125,174,178,148,213,151,164,158,54,28,56,168,137,68,121,178,134,114,166,92,118,163,95,29,26,133,167,156,89,44,41,38,61,59,51,55,67,57,52,78,51,39,66,80,96,83,57,46,71,54,47,73,46,52,63,65,69,48,33,23,32,70,100,124,135,132,135,118,108,101,87,87,98,110,101,93,99,75,41,18,33,51,43,59,66,45,21,28,36,38,28,12,18,21,22,26,30,25,19,26,26,29,28,29,29,37,32,21,24,29,24,19,29,24,31,33,24,31,30,30,33,30,36,33,45,69,85,79,56,35,22,19,18,21,42,54,55,61,56,50,54,53,53,50,47,46,44,40,44,47,42,39,41,43,40,49,44,45,46,36,39,33,31,33,34,29,31,39,37,41,41,39,43,43,49,51,46,51,52,49,52,54,53,55,53,55,55,52,51,54,54,55,50,49,49,40,38,44,43,42,41,42,41,37,39,39,36,35,39,39,35,41,41,43,38,38,43,43,40,45,45,38,43,39,41,46,44,43,47,44,45,46,45,44,44,44,43,45,43,46,45,39,42,41,39,44,38,39,45,41,44,37,41,39,34,38,35,36,35,33,36,40,38,41,36,34,41,37,41,39,37,41,43,41,37,41,41,41,41,43,40,35,44,37,36,40,39,43,41,39,44,42,43,36,41,43,43,41,68,73,41,42,46,45,81,44,48,48,48,48,48,48,51,49,53,54,85,60,58,57,59,79,60,57,59,59,61,67,68,73,80,86,85,90,84,78,90,99,99,96,106,110,96,106,84,110,111,126,110,101,104,103,115,101,103,102,97,101,108,113,125,152,157,153,147,126,115,109,106,114,125,149,156,160,159,153,146,142,141,125,112,107,98,96,90,97,117,124,131,120,121,123,129,115,113,100,17,3,12,10,16,13,14,13,14,15,15,15,184,190,186,199,201,201,205,202,203,205,208,210,208,205,198,194,193,193,194,193,197,195,196,197,198,198,201,249,250,205,181,199,120,15,4,10,17,27,25,29,40,32,50,158,214,214,222,218,210,213,212,206,203,208,217,215,214,209,204,204,203,202,201,204,202,202,203,202,200,200,201,203,205,204,208,210,205,207,213,206,206,205,200,202,201,200,203,198,203,207,203,202,201,200,204,201,199,203,199,211,214,214,221,214,211,214,209,205,200,193,189,183,184,188,199,206,206,212,209,212,164,121,137,118,123,131,105,106,119,103,86,87,90,71,69,92,100,77,86,107,69,86,167,166,91,67,56,45,74,118,150,123,129,120,99,93,85,93,96,142,155,145,151,141,144,150,155,101,75,95,158,207,165,113,101,117,116,107,108,104,109,107,119,121,123,131,122,123,120,128,130,133,139,135,127,123,132,140,132,112,103,100,86,97,106,100,110,116,105,102,93,116,133,131,138,151,149,138,149,158,157,168,171,161,162,160,155,149,160,162,163,168,155,160,168,184,178,165,170,169,162,163,131,103,98,91,81,98,138,151,165,162,163,151,129,112,119,126,112,120,164,205,185,151,119,88,75,73,75,88,159,198,198,196,225,184,119,117,223,227,88,120,108,110,182,224,242,244,191,84,119,163,131,69,64,125,108,101,163,212,162,87,105,105,109,86,32,100,188,229,221,230,177,212,217,106,140,120,103,127,114,46,72,165,98,81,141,137,130,162,184,196,175,124,82,22,4,53,51,69,49,30,32,17,39,45,44,35,42,38,61,94,55,56,81,92,94,75,63,55,74,61,55,75,54,47,58,55,45,27,23,34,74,118,121,122,123,128,116,99,95,92,96,95,104,117,93,83,72,37,19,15,42,46,38,57,65,47,22,39,53,54,49,21,17,18,22,26,26,28,23,25,24,28,26,27,29,37,38,34,38,37,43,23,19,29,28,31,28,34,28,29,25,33,39,54,76,86,82,48,25,18,18,18,22,41,56,55,51,59,57,55,57,51,52,56,54,51,48,47,46,49,50,44,44,46,48,48,47,45,25,24,21,15,23,21,18,16,25,33,33,35,36,42,46,48,52,56,51,46,54,55,55,53,53,55,55,58,53,54,54,55,54,54,55,53,53,45,46,42,43,44,39,46,36,32,26,22,28,26,26,26,26,35,36,37,38,40,40,39,43,43,37,43,46,50,51,53,55,53,57,50,55,57,53,56,52,52,49,54,57,53,56,50,50,45,44,45,40,43,38,39,41,39,43,37,37,35,36,39,39,37,38,36,36,34,32,34,32,36,42,41,42,41,42,46,40,43,41,42,42,41,39,39,38,37,42,41,40,36,43,43,38,41,44,41,38,41,41,40,42,40,39,39,42,42,41,35,39,42,37,41,45,42,44,49,52,54,44,48,49,48,53,49,50,44,43,45,46,49,48,46,53,52,57,56,54,55,59,61,57,51,38,38,39,35,37,39,38,49,56,57,87,102,113,98,83,98,103,112,108,108,99,105,110,116,127,119,120,125,132,141,149,153,154,154,160,155,145,143,143,136,122,119,132,118,105,95,93,108,112,111,106,105,110,97,114,99,18,4,12,11,15,13,15,13,15,15,15,15,191,188,181,188,187,188,190,183,187,177,180,192,196,200,195,188,189,189,188,187,192,191,190,192,192,193,195,253,249,188,168,213,128,22,33,30,27,31,33,36,46,46,88,195,227,220,222,225,219,207,214,208,203,205,210,212,212,214,214,212,210,217,222,217,211,213,214,215,208,211,215,216,214,214,222,220,208,216,218,217,221,220,215,215,217,214,213,212,221,220,218,222,214,219,218,217,215,215,203,211,214,192,208,214,215,220,214,213,196,184,184,187,194,187,191,179,137,132,144,147,97,66,83,78,90,95,80,88,92,88,76,72,77,82,95,99,100,101,108,105,89,97,119,96,67,75,79,72,88,96,107,117,132,107,97,118,147,152,134,151,145,133,114,100,101,109,126,115,125,148,188,200,173,134,136,134,128,122,138,141,126,117,118,124,130,122,120,131,133,130,133,133,131,144,148,152,153,148,125,98,94,99,97,119,159,149,152,149,120,128,130,151,164,135,128,143,131,115,147,171,168,171,172,170,170,177,178,168,181,184,188,199,178,169,181,194,178,150,141,151,162,132,94,65,69,81,83,137,168,182,189,179,184,162,148,131,127,134,123,138,163,207,219,220,206,189,175,166,160,157,187,194,181,202,220,184,95,121,226,171,98,155,115,122,184,235,236,197,177,108,115,146,149,94,69,118,161,180,130,120,129,111,106,85,81,24,4,58,90,160,200,196,151,166,190,125,132,102,69,178,160,78,154,178,78,108,142,108,174,172,163,224,178,108,65,12,12,35,32,63,44,28,29,17,31,27,32,27,31,40,74,87,57,66,65,71,66,55,64,59,50,38,39,55,46,39,42,35,28,31,54,66,98,116,105,97,101,105,103,88,85,89,95,101,110,117,105,75,35,16,24,41,59,70,51,54,60,35,26,49,63,61,57,32,13,17,18,21,21,24,24,20,24,28,24,21,32,37,39,51,48,42,47,34,24,24,24,29,34,31,29,30,35,44,58,74,77,70,44,24,21,17,16,15,35,54,54,57,57,54,57,56,55,53,53,60,50,51,56,53,54,57,51,48,48,50,48,50,48,35,21,16,21,17,16,15,18,19,17,25,36,39,38,45,49,51,54,55,51,50,51,55,56,56,54,58,57,54,54,56,57,54,53,55,54,55,53,47,44,40,44,44,40,38,23,21,17,19,17,17,19,18,23,22,32,33,39,36,39,43,40,37,30,46,56,57,59,59,61,60,61,62,56,55,63,55,55,56,51,57,55,54,60,49,45,49,44,41,35,42,44,39,41,44,39,39,38,34,46,38,37,34,20,23,21,23,25,21,25,27,35,41,42,44,45,44,49,47,46,49,47,42,39,39,40,39,42,41,38,41,39,42,50,42,38,42,44,45,43,41,43,47,37,44,46,39,42,36,40,35,35,39,36,41,49,55,55,53,48,54,54,53,58,54,53,55,51,55,54,53,58,54,55,61,60,63,59,64,69,61,53,36,23,23,27,28,37,36,27,47,51,54,71,82,87,74,77,100,115,106,98,85,64,67,68,88,98,83,113,127,131,131,126,130,133,150,154,144,136,139,139,129,132,149,152,138,123,117,104,109,117,109,105,98,108,101,111,97,19,4,12,11,16,13,15,16,14,15,15,15,194,180,158,155,145,141,151,151,141,129,128,143,162,184,192,191,192,190,187,188,192,192,195,196,194,196,177,234,242,143,165,215,131,28,33,29,25,30,28,41,42,51,82,176,178,136,150,166,157,153,176,177,152,120,134,146,165,188,194,210,200,202,210,210,200,199,213,216,199,199,215,216,194,171,187,207,185,179,193,187,202,214,209,208,216,220,214,196,192,205,207,213,214,208,210,212,209,208,166,158,139,113,141,152,146,154,176,210,216,219,244,251,245,202,168,108,67,77,84,99,87,82,98,101,118,129,121,129,117,108,117,100,103,107,113,117,110,119,123,125,110,91,94,78,85,118,120,141,139,132,143,151,146,93,94,146,207,213,176,177,162,143,126,108,118,127,151,150,151,195,201,187,177,154,135,126,112,110,136,134,113,95,98,113,116,114,104,109,111,117,110,100,109,121,131,146,140,125,113,100,105,105,97,131,145,127,136,135,120,126,132,152,136,108,102,100,93,93,147,180,159,150,134,138,157,151,144,128,145,170,173,169,145,127,141,150,119,108,107,120,144,127,101,95,127,160,174,196,195,184,179,162,161,146,132,129,136,135,132,133,140,170,209,232,249,249,251,251,249,243,230,200,168,142,146,118,79,120,182,126,94,144,116,118,143,193,236,175,162,120,108,120,149,129,72,67,149,197,116,102,122,131,147,113,84,42,14,55,19,62,96,113,120,114,204,162,181,158,127,205,124,99,198,151,65,128,110,104,191,124,78,162,131,57,36,6,39,122,121,91,62,61,74,63,59,49,41,48,57,61,77,69,46,44,42,48,47,34,46,47,37,32,31,33,26,31,28,22,37,65,91,94,118,108,81,88,85,105,94,77,75,80,106,111,120,122,73,32,21,22,52,68,97,112,74,59,55,31,37,66,69,62,66,51,43,39,24,17,19,23,21,27,22,24,28,21,26,29,30,44,55,50,46,40,27,21,25,33,28,33,31,29,44,63,77,74,54,32,24,19,17,16,17,40,53,54,57,60,61,57,55,55,57,53,54,53,57,55,57,56,50,54,55,55,51,50,46,47,44,29,22,18,17,21,17,20,20,17,19,23,39,42,43,44,50,55,52,56,50,48,57,55,53,54,57,59,53,54,53,59,58,52,53,51,56,53,51,51,50,46,44,46,44,32,18,20,18,21,18,17,19,16,18,25,29,32,34,33,44,46,39,30,39,58,54,57,61,63,61,60,61,60,60,57,60,61,59,54,56,49,52,53,51,52,41,50,45,37,42,41,43,44,38,42,40,38,44,41,45,45,26,23,19,16,21,17,22,18,20,26,31,36,39,46,41,46,50,52,51,53,50,46,41,42,43,41,44,41,43,46,42,43,44,39,43,46,44,43,45,43,41,45,41,42,46,38,30,27,21,24,29,24,27,34,35,42,48,49,52,50,53,56,56,55,55,58,56,59,56,55,59,60,63,63,62,61,61,66,63,50,38,26,29,28,27,35,51,56,65,79,55,53,51,39,57,60,59,83,87,68,53,47,36,62,74,68,77,77,107,119,121,118,106,112,125,132,136,124,121,116,102,107,117,129,142,120,118,129,122,134,134,126,115,124,133,111,130,103,16,4,11,12,15,13,15,15,15,16,16,15,183,160,138,123,108,112,127,143,145,127,118,116,139,181,203,209,206,201,203,204,211,210,212,215,214,214,196,238,224,133,155,205,109,27,46,22,29,33,29,36,42,51,72,130,95,50,60,81,78,91,144,128,89,63,70,89,114,139,156,168,136,116,125,137,129,147,158,162,139,130,149,148,116,87,123,154,113,112,121,114,132,141,134,131,156,178,157,104,111,129,141,158,128,126,134,141,153,160,105,83,87,64,90,78,74,98,133,208,246,249,250,250,250,207,135,96,93,108,107,119,116,122,143,145,159,157,143,150,135,130,139,120,119,128,115,113,112,122,128,128,128,104,115,127,148,182,183,182,163,143,149,160,139,88,90,137,184,178,162,170,151,149,141,131,132,129,145,153,187,192,170,157,143,130,109,102,93,79,107,114,107,99,92,97,101,95,95,103,98,103,99,86,94,112,115,117,120,128,115,104,120,114,99,107,110,99,109,114,96,94,108,131,125,101,97,94,88,97,150,170,143,119,99,100,111,108,103,80,112,141,128,118,95,92,102,105,101,110,125,137,147,136,142,133,141,160,151,165,137,118,118,111,113,107,105,108,112,117,115,107,109,117,128,141,144,146,154,167,178,195,211,216,212,200,202,166,92,151,234,152,92,106,101,127,186,228,229,175,155,141,144,109,133,152,97,31,132,219,128,97,122,147,186,246,241,214,180,159,99,112,141,159,182,137,148,130,192,170,150,203,80,125,207,104,86,151,136,139,153,80,22,63,73,44,29,9,62,142,152,122,90,124,138,125,107,83,77,73,76,83,90,67,41,34,30,42,44,39,41,39,53,53,43,33,29,25,21,39,74,109,111,109,129,112,88,89,97,100,88,91,88,97,114,113,111,74,29,20,19,45,85,97,112,121,114,111,73,23,30,64,80,93,89,69,63,55,33,19,14,22,17,19,27,21,27,24,25,23,25,40,45,53,52,42,36,27,24,26,29,33,30,47,66,77,69,48,28,24,18,17,15,22,53,55,56,57,56,57,55,57,54,59,56,54,60,57,52,56,59,57,57,51,50,50,48,50,49,44,40,24,20,17,18,18,18,21,21,22,17,31,40,44,45,45,49,51,54,50,52,55,51,49,49,49,55,51,52,55,58,57,53,56,55,59,54,53,55,53,56,56,51,50,42,25,21,21,16,21,21,19,19,22,19,22,31,36,44,49,51,45,25,28,48,61,60,61,63,59,57,56,59,59,60,61,57,58,55,51,55,50,48,52,46,48,48,44,41,38,44,42,40,42,42,46,43,48,46,46,48,39,22,19,17,19,16,21,22,17,21,16,37,37,40,44,42,46,49,53,54,50,46,51,48,45,42,43,48,42,46,43,44,44,41,45,42,48,44,45,47,45,47,45,45,42,33,26,20,16,20,22,18,22,25,24,27,36,42,41,44,49,52,55,51,51,50,53,57,55,55,55,56,61,63,60,60,62,63,61,56,42,28,29,29,29,27,37,58,99,142,118,69,67,84,75,74,70,63,69,60,38,38,29,33,84,96,103,111,104,128,129,126,118,112,116,123,118,106,108,106,105,97,92,87,108,106,83,83,109,130,128,125,123,124,134,137,121,141,102,15,4,11,12,15,14,16,15,15,16,16,15,166,149,125,112,114,115,132,162,173,171,159,155,164,193,211,210,208,205,203,202,205,206,206,207,214,219,229,247,237,139,119,138,57,25,39,24,29,32,31,35,38,56,75,122,100,64,68,78,85,104,142,132,113,99,122,106,111,126,120,120,76,57,53,62,71,78,88,100,83,62,67,80,78,61,71,94,77,76,80,69,71,78,72,65,89,101,88,66,63,74,89,86,65,59,59,84,103,109,93,83,77,81,95,92,95,99,103,151,178,178,173,174,181,144,113,108,117,115,119,132,122,124,131,134,140,122,114,131,124,114,123,116,117,122,117,114,111,121,120,122,126,124,147,166,186,223,237,218,190,160,145,149,138,106,112,129,136,130,118,127,119,125,128,123,109,92,109,157,195,177,141,124,119,106,81,77,75,67,93,116,107,85,78,75,79,84,100,105,89,95,86,79,108,130,110,102,126,132,118,103,125,124,103,113,101,96,105,114,112,84,83,107,105,103,101,102,104,103,128,124,100,100,82,81,103,107,107,96,118,131,112,98,92,89,95,110,113,132,149,152,156,150,158,151,107,91,98,95,87,88,82,80,89,91,96,89,96,102,99,97,88,84,69,57,55,53,54,61,69,105,154,200,230,233,245,217,116,134,203,152,121,122,100,161,241,237,193,160,160,158,174,111,119,173,157,73,153,238,123,98,101,99,186,247,250,250,251,251,187,232,204,177,212,107,100,121,148,123,172,160,61,172,163,71,129,201,252,184,95,59,16,28,43,49,38,33,55,59,62,65,56,85,102,88,88,76,72,77,73,69,72,63,52,34,27,42,41,43,40,36,57,69,53,29,20,28,34,69,106,113,114,101,128,112,95,109,88,106,107,105,113,111,125,108,61,28,12,26,49,82,110,102,110,112,118,121,72,30,51,94,111,102,80,61,46,30,26,24,16,15,18,25,24,24,29,27,30,25,27,29,35,51,56,49,48,34,22,27,29,34,50,74,79,57,38,24,20,16,15,19,31,50,59,57,54,57,57,54,54,61,57,59,56,56,56,53,61,57,55,51,58,55,52,54,46,50,47,45,40,24,18,19,17,27,21,19,24,18,19,30,42,40,46,49,52,54,53,56,54,47,51,45,41,49,49,51,54,55,53,57,55,57,59,51,54,58,57,57,57,55,57,51,44,30,21,17,19,25,19,19,18,22,19,30,48,45,52,53,43,35,20,32,55,57,61,61,59,60,50,57,56,55,60,55,58,59,53,53,48,47,54,47,55,53,47,47,39,42,41,43,44,44,47,56,49,49,47,48,40,27,21,18,22,17,21,20,26,21,18,23,29,41,41,42,45,46,48,53,51,54,52,44,45,45,45,46,43,45,48,44,44,43,46,50,48,50,51,51,47,50,52,49,50,42,26,22,21,21,22,21,21,24,23,22,25,33,37,38,47,47,48,50,49,54,54,50,57,56,54,49,53,62,57,60,56,59,57,54,48,31,29,33,33,33,26,38,87,125,149,137,104,126,129,123,134,123,98,98,84,86,100,90,101,120,139,148,152,135,128,131,132,128,121,125,137,134,122,117,119,118,111,101,102,111,100,87,89,116,110,101,107,93,87,105,116,109,128,96,17,5,11,12,14,14,16,14,15,16,15,16,144,122,116,117,120,109,110,130,143,155,171,175,180,174,166,167,164,155,141,126,127,120,116,117,142,154,183,245,236,136,67,62,9,18,36,21,31,29,30,40,41,52,99,149,128,110,116,137,133,141,173,167,165,141,148,141,127,131,122,115,101,102,93,83,77,92,102,103,86,70,69,76,81,85,92,89,80,88,84,87,94,89,89,81,84,95,91,92,96,96,103,107,92,83,81,95,113,120,112,110,110,101,125,122,115,112,89,84,86,85,76,75,86,84,100,109,105,104,109,118,112,109,111,107,111,97,101,113,107,109,115,116,116,121,118,123,118,116,111,102,127,145,151,159,199,226,234,234,233,213,197,190,165,122,111,117,129,122,100,95,95,100,110,113,108,94,141,184,191,152,105,119,119,105,87,88,102,108,127,140,122,98,83,92,107,108,117,122,99,100,101,98,133,153,124,118,142,146,122,108,127,128,126,124,112,114,127,142,136,113,99,103,108,99,103,112,109,104,104,96,82,84,100,110,123,135,126,119,127,119,111,110,100,96,110,116,123,152,156,154,153,152,157,155,108,67,81,101,92,93,95,93,97,97,95,95,101,101,103,94,94,85,67,71,81,84,73,67,57,86,108,131,147,133,165,172,125,81,91,126,139,131,113,115,160,143,88,76,74,73,86,63,93,151,172,88,98,119,103,119,79,38,82,222,252,252,251,251,232,186,148,110,166,137,124,145,108,126,188,91,83,188,81,87,173,200,249,160,84,38,2,40,54,51,45,44,44,36,39,43,41,41,53,59,57,61,55,46,42,41,47,45,38,32,28,36,35,29,33,40,55,46,33,28,27,31,55,95,100,105,110,100,101,87,100,98,98,112,106,118,116,124,112,56,24,14,29,60,87,115,111,100,101,113,111,115,100,77,109,116,99,71,44,30,26,24,22,18,15,17,24,24,22,27,33,24,28,30,26,28,29,42,51,51,56,46,27,22,32,55,76,73,54,33,21,19,20,17,21,41,56,60,60,53,57,55,56,55,55,56,56,57,54,52,52,54,57,56,57,55,53,53,55,55,49,51,45,43,37,20,22,18,17,24,20,17,19,24,21,31,39,41,46,47,47,57,59,53,55,53,38,31,37,47,52,50,60,55,53,56,54,56,51,56,56,59,56,53,58,54,53,53,39,19,21,18,19,19,22,22,18,19,24,38,42,50,49,46,31,22,20,29,57,60,61,58,56,57,54,57,60,51,59,59,53,54,51,53,53,50,52,53,50,47,40,38,44,44,41,41,45,50,48,50,51,50,52,45,41,28,21,22,19,19,21,20,20,19,21,20,34,43,42,46,49,49,49,54,57,49,46,53,46,46,45,44,45,41,47,46,47,52,51,48,50,51,51,58,55,59,57,55,51,36,27,20,25,21,20,21,21,22,21,23,22,35,39,39,47,48,43,47,48,50,52,49,52,48,50,54,57,55,55,59,56,56,59,53,40,30,29,36,33,27,26,66,112,127,131,119,120,126,128,136,144,139,116,119,130,138,148,144,149,153,146,145,138,124,124,120,123,125,125,136,153,155,138,129,125,125,125,123,127,137,122,121,117,116,114,96,97,75,64,86,84,85,110,88,20,5,12,12,15,13,15,15,15,16,15,15,117,109,117,117,117,106,93,87,79,90,107,129,133,114,102,110,119,110,85,64,53,44,46,46,69,75,131,239,239,128,55,58,12,13,33,34,31,25,36,44,43,52,93,154,153,149,149,165,165,164,174,168,163,115,137,143,128,128,121,126,129,140,139,145,141,146,149,146,127,92,91,104,114,113,112,116,102,105,106,108,117,109,107,111,116,105,114,126,122,125,135,132,125,130,120,126,129,127,119,116,118,128,141,123,108,102,102,98,90,77,69,84,94,95,105,105,108,110,110,112,106,110,114,109,110,110,107,111,109,112,119,113,115,116,116,122,125,126,124,114,122,140,137,165,203,214,214,227,252,252,246,236,200,149,120,113,128,129,106,97,94,98,118,139,147,153,195,215,180,136,132,144,142,143,150,156,170,170,163,178,168,163,166,168,169,141,136,152,141,151,155,137,139,144,129,134,152,147,134,127,139,141,139,136,125,127,125,137,142,127,127,112,99,103,111,121,120,109,110,103,98,119,125,123,145,146,126,112,109,107,106,112,104,117,146,133,125,156,159,154,151,149,153,161,130,74,87,107,114,112,106,106,105,103,101,98,109,110,104,108,118,151,134,93,106,107,100,109,99,98,92,91,84,45,93,141,151,107,45,51,66,72,48,37,66,69,53,46,35,33,21,11,26,71,146,101,41,11,84,158,83,35,9,28,127,205,219,244,177,131,139,126,203,156,148,154,95,167,143,46,133,166,133,183,129,73,139,103,45,22,20,61,53,41,32,29,30,30,32,29,27,29,34,33,37,34,33,30,23,29,27,27,25,20,27,27,21,27,27,31,37,41,30,40,42,47,69,90,104,108,112,94,95,93,87,99,100,110,115,116,125,99,50,21,15,32,67,99,98,106,109,93,95,107,116,112,101,94,111,76,40,36,26,26,17,19,15,21,23,21,22,21,24,27,26,29,28,25,33,28,31,31,46,57,55,62,40,29,52,75,71,44,29,21,21,15,18,29,42,55,64,61,57,55,53,58,58,56,55,55,55,60,51,55,57,55,54,57,59,55,59,55,56,51,51,50,47,37,24,26,23,17,21,22,16,21,19,19,21,34,42,39,43,48,52,55,54,54,55,44,35,34,37,53,57,59,61,57,57,55,56,57,57,57,55,57,57,55,55,59,57,47,25,19,25,21,18,21,19,19,19,18,24,35,44,49,51,34,22,24,17,44,58,59,63,55,59,59,57,60,52,56,56,51,61,53,58,60,54,59,53,52,51,47,46,43,42,41,43,42,48,53,50,49,47,48,50,49,36,21,22,23,20,19,24,25,18,24,22,24,36,45,45,45,51,51,52,50,53,55,50,54,47,48,44,45,49,46,51,50,53,57,53,45,49,49,56,57,57,57,52,55,46,34,20,24,28,17,20,27,22,23,26,24,34,36,38,44,48,47,50,50,49,50,54,51,46,49,54,53,55,60,57,62,60,58,61,52,33,34,38,39,36,21,39,104,129,113,117,110,107,99,94,107,99,107,92,101,124,134,141,131,146,149,128,111,119,119,122,124,119,122,133,141,148,142,125,131,134,127,122,121,143,150,128,121,114,122,119,108,111,87,84,83,78,81,106,94,19,5,13,12,16,13,15,15,15,16,15,15,95,110,121,122,122,110,103,80,67,63,72,83,92,97,96,127,164,165,144,130,110,95,96,92,88,80,141,245,246,142,102,126,50,19,29,31,33,26,32,34,39,50,93,157,170,180,180,178,178,175,162,145,139,110,134,150,129,122,118,127,136,141,150,160,166,172,170,174,159,128,111,116,121,118,114,112,118,113,107,114,111,107,116,117,113,101,105,126,123,130,135,136,137,143,134,126,122,114,113,112,119,132,141,121,98,95,105,102,103,95,86,105,111,107,107,101,103,112,115,117,112,115,114,111,116,117,110,111,119,111,118,121,110,110,116,128,126,126,136,139,131,129,129,136,151,150,144,152,179,199,216,221,213,197,182,146,149,125,109,112,114,114,124,136,171,226,226,215,179,161,171,176,183,186,192,209,205,194,171,173,164,198,228,222,179,138,140,168,184,182,169,132,111,111,103,105,128,139,135,130,134,125,122,127,131,124,113,113,110,112,127,115,100,104,117,128,124,117,112,118,125,125,131,130,143,148,112,100,98,102,122,118,120,159,215,190,139,155,152,157,153,146,158,161,147,96,73,98,118,125,109,106,108,131,137,111,126,127,125,126,173,251,234,123,97,105,110,140,135,108,101,113,91,108,186,200,207,173,65,18,10,20,10,21,120,169,139,133,132,140,110,45,21,27,122,151,154,115,156,188,117,96,63,23,20,78,95,152,172,153,198,190,212,146,160,139,108,180,97,102,184,192,198,171,92,18,25,46,45,44,49,57,38,26,23,23,27,29,25,24,27,27,27,27,30,29,26,31,24,22,22,21,26,19,22,21,20,25,28,26,29,44,51,61,53,53,68,95,108,106,105,91,98,90,98,112,105,119,117,118,96,45,21,12,39,71,108,109,87,101,92,90,71,80,101,107,103,90,96,55,33,38,51,35,17,24,36,48,34,19,18,18,27,29,29,29,28,29,28,31,24,27,38,51,60,66,59,50,59,61,39,24,19,17,18,22,30,51,58,67,64,57,59,58,55,55,57,55,59,53,57,56,55,60,60,57,55,57,53,54,53,52,56,51,52,46,42,33,19,28,26,21,18,23,24,23,25,18,29,43,39,46,50,49,55,54,54,52,44,38,30,32,42,56,63,59,57,59,63,59,57,59,59,55,53,56,56,61,59,57,53,33,22,27,21,22,23,23,21,19,26,20,32,42,47,48,43,27,21,21,22,49,63,60,64,61,60,61,59,59,57,60,57,53,59,60,60,61,57,59,55,57,57,49,48,44,45,42,48,47,48,56,51,51,54,53,48,38,28,19,19,23,16,18,20,22,18,19,20,25,41,43,43,49,50,52,50,51,51,50,55,54,50,50,51,51,52,48,56,58,55,54,48,49,51,53,53,54,55,55,55,53,38,25,21,25,23,18,25,23,18,27,27,24,30,40,41,43,49,45,52,54,48,54,53,55,55,55,56,59,59,60,63,65,60,63,61,43,39,38,44,39,38,22,69,142,131,120,128,117,98,68,66,71,71,90,67,78,115,128,128,122,132,136,123,121,117,115,134,140,130,130,146,143,140,133,116,129,122,114,118,122,149,151,123,121,120,122,130,126,133,114,110,109,95,106,117,91,19,4,13,12,15,14,15,14,15,15,15,15,92,106,112,116,122,114,108,96,78,75,73,79,89,86,94,144,206,218,204,196,181,162,150,132,129,124,181,248,249,159,156,211,104,37,33,30,34,29,36,28,37,45,79,133,139,167,169,165,164,153,139,116,120,118,139,139,120,115,120,129,141,132,125,134,137,148,139,155,159,128,117,110,103,93,99,111,102,105,106,106,109,108,108,111,111,89,93,113,125,131,128,124,129,132,118,114,116,115,118,120,127,129,113,107,111,108,105,107,123,112,104,112,108,107,111,111,121,126,131,142,131,121,115,108,104,113,112,111,115,104,120,114,107,112,117,131,121,107,119,143,149,136,101,91,96,84,84,89,108,136,164,183,198,224,237,222,182,148,125,113,111,111,104,100,163,241,230,181,159,160,174,180,186,191,184,191,199,178,139,140,125,160,202,195,142,103,118,156,181,161,135,108,98,93,86,110,120,117,118,120,120,94,101,121,121,119,90,82,84,84,112,114,125,133,131,135,129,112,116,122,113,112,113,110,129,118,89,90,106,135,152,150,152,190,247,226,150,154,152,155,159,145,153,157,159,116,71,83,105,120,118,113,145,181,177,137,135,134,122,126,162,239,226,126,94,101,132,167,170,117,78,96,92,118,176,233,231,161,131,88,77,63,55,57,127,208,177,182,158,196,192,96,81,24,94,172,179,172,206,201,126,116,105,89,83,57,57,156,157,158,165,150,199,153,169,114,139,182,125,196,222,221,189,118,68,10,12,30,63,71,51,34,23,24,23,27,29,25,29,30,27,28,27,29,28,28,25,24,24,18,23,22,26,20,23,25,24,24,25,29,29,47,67,78,56,53,83,109,105,91,97,77,81,98,103,115,108,117,120,77,42,16,15,39,72,114,125,110,98,96,99,104,71,71,96,103,113,102,107,88,86,107,103,68,26,25,49,51,29,22,24,22,25,24,31,28,28,29,24,26,27,29,31,46,61,66,76,61,46,27,15,19,18,19,26,39,55,57,63,68,61,59,62,57,56,60,57,59,59,60,66,61,59,61,57,63,63,57,56,53,53,55,57,51,45,41,45,30,23,21,22,25,19,21,24,27,23,27,39,43,42,50,54,53,50,51,54,39,39,36,25,35,40,51,58,60,60,60,61,57,61,62,57,55,56,55,55,55,56,57,45,27,23,24,25,27,18,19,23,21,20,30,39,42,46,46,42,28,31,24,37,63,63,64,65,61,57,57,57,61,55,56,57,58,65,63,58,54,58,57,56,60,57,54,50,45,51,51,55,53,50,54,51,52,48,51,51,37,26,19,23,22,19,23,19,17,25,24,20,35,43,43,48,49,50,53,57,55,57,55,51,53,60,62,54,56,58,57,54,48,53,46,49,55,52,53,52,55,56,57,51,42,31,22,25,30,21,22,24,19,24,22,21,23,31,46,47,51,52,56,54,53,60,60,60,56,64,68,68,66,64,65,66,65,60,59,53,44,41,45,38,46,44,44,125,160,141,140,148,133,115,76,68,85,84,105,77,96,128,127,136,127,137,136,131,135,131,132,145,148,141,135,132,113,125,130,108,123,118,125,134,137,151,148,143,147,141,134,132,137,142,127,125,124,121,110,109,84,19,6,12,12,14,13,15,15,15,16,15,15,91,97,103,118,122,119,119,104,93,82,84,77,78,85,71,83,128,143,140,145,152,147,137,134,148,176,229,251,248,142,170,244,158,62,25,17,33,34,44,49,39,46,67,91,88,118,123,104,108,101,86,89,95,94,108,110,99,97,100,107,101,100,98,88,93,83,91,109,117,104,95,93,81,92,98,96,99,108,110,108,110,112,109,114,115,100,103,122,134,127,111,113,112,110,107,112,122,123,121,122,140,124,105,120,127,128,127,124,131,127,119,126,129,120,125,133,134,141,148,149,137,129,118,110,99,105,109,100,110,94,110,111,103,115,117,136,117,103,103,120,131,131,104,83,84,75,77,78,84,102,124,137,139,151,178,210,207,208,181,162,116,98,77,63,136,192,169,122,124,129,137,145,134,132,122,132,132,130,117,121,93,98,127,130,107,95,106,122,136,130,113,105,101,118,125,129,121,101,102,104,109,86,105,113,101,88,72,73,62,72,85,98,126,137,135,130,118,117,125,122,110,109,116,104,99,97,89,117,141,165,178,170,168,184,220,188,147,165,156,160,160,142,149,150,168,147,83,71,79,105,113,137,171,181,184,156,135,112,104,98,95,165,149,122,107,121,152,171,183,145,78,76,81,107,127,139,160,169,221,156,153,166,118,95,95,162,199,165,132,152,174,130,71,10,50,139,145,123,189,165,74,83,75,79,90,78,97,120,139,136,88,141,185,162,137,83,151,159,168,235,193,229,170,59,38,2,31,60,57,54,32,25,32,35,29,27,29,28,30,33,29,25,32,24,27,26,24,24,19,24,22,19,25,24,25,24,26,25,27,32,42,66,74,80,60,79,106,98,92,85,84,64,82,102,103,105,101,110,75,30,18,21,49,84,116,124,127,100,95,107,103,156,114,88,100,107,117,112,119,105,124,139,145,101,39,33,34,33,26,30,29,21,24,29,29,35,34,31,24,23,28,27,26,43,61,68,81,79,46,21,19,17,17,27,50,55,61,67,62,66,63,61,60,61,63,61,65,61,62,64,62,62,62,60,53,55,55,51,57,54,54,55,55,53,45,46,39,23,17,20,23,21,19,23,26,24,22,30,43,45,51,53,52,51,53,54,49,44,36,33,29,34,43,52,57,60,56,55,60,58,57,60,60,57,58,53,49,52,54,50,41,28,19,23,21,19,17,19,22,21,23,31,42,45,48,44,39,37,34,27,46,66,62,61,65,59,55,56,53,55,54,54,54,60,56,59,60,61,56,55,61,57,60,61,50,52,60,55,53,55,60,54,50,53,53,47,49,35,19,23,17,19,25,19,19,25,24,21,30,37,46,46,47,57,57,52,54,57,55,52,58,64,57,56,55,58,59,55,49,45,44,44,48,54,53,57,61,57,55,51,50,35,25,26,21,25,22,24,21,17,22,23,27,25,43,57,54,58,61,61,63,60,55,61,60,61,69,66,63,63,61,61,60,62,59,55,49,41,42,33,37,48,57,91,145,142,127,139,141,141,127,111,121,122,114,143,127,116,122,130,135,112,132,145,131,139,132,132,151,149,136,113,101,84,105,125,111,118,120,137,143,130,129,132,144,162,153,141,130,121,128,113,116,111,105,104,102,86,19,4,12,11,15,13,15,14,15,15,15,15,110,113,112,122,124,126,129,118,110,108,107,103,104,100,95,94,92,87,67,76,101,98,98,103,142,195,232,252,246,105,128,237,157,39,27,18,28,37,63,78,48,45,67,83,72,91,81,66,77,67,74,77,83,82,87,92,90,92,89,89,93,86,86,87,83,87,78,85,97,92,96,97,102,101,96,96,96,104,104,98,101,111,111,124,127,109,119,124,133,119,100,106,107,107,101,105,124,120,117,120,136,136,129,136,121,125,129,120,131,135,141,144,135,117,117,117,128,136,138,147,131,134,131,124,113,114,129,125,131,110,121,116,107,116,113,122,116,110,99,118,151,171,147,123,110,96,98,94,97,92,103,115,103,85,110,178,212,229,233,218,182,146,78,47,86,142,107,67,93,99,104,106,108,110,96,87,91,100,96,96,88,87,89,105,107,109,112,97,110,117,113,109,124,136,127,131,100,82,88,98,113,97,108,102,84,78,63,78,69,61,74,66,86,112,122,127,120,124,134,120,113,123,120,116,112,116,133,152,175,184,186,184,171,164,168,160,155,173,165,166,168,153,150,139,167,176,106,68,68,93,113,129,150,150,147,139,130,118,105,91,96,107,109,119,145,160,173,174,186,174,114,86,94,121,125,131,107,189,240,185,245,216,152,104,109,185,199,172,148,161,135,81,66,9,45,159,165,135,181,131,42,42,38,60,66,69,89,122,144,106,113,171,171,139,76,105,148,127,189,157,85,147,113,27,7,28,67,57,38,34,33,31,27,39,42,35,32,30,27,28,28,29,23,27,25,24,30,21,22,23,20,22,23,21,29,26,24,26,27,43,59,84,79,63,57,87,98,98,91,73,78,63,89,110,98,97,97,62,29,17,27,59,98,122,122,116,110,92,97,89,104,129,88,97,105,106,117,105,110,108,117,120,129,133,86,42,33,37,42,45,43,36,22,25,33,31,32,30,26,28,27,30,34,51,67,73,97,103,66,42,51,39,41,51,56,61,63,66,65,62,61,60,60,57,57,60,58,63,59,56,60,53,55,54,50,54,47,49,55,51,46,53,53,52,48,45,37,19,19,23,22,23,19,19,18,19,30,40,50,49,47,57,50,53,57,55,50,42,39,34,38,37,44,54,54,57,57,61,58,57,64,53,56,61,59,55,52,51,50,48,32,20,23,19,17,22,19,21,22,20,27,42,46,49,48,38,29,30,29,33,53,63,59,61,61,53,55,54,50,49,54,56,57,57,58,57,55,60,62,59,53,59,63,59,61,59,57,59,61,58,56,55,53,53,49,49,46,40,20,18,25,19,21,15,17,24,27,27,33,43,44,53,57,57,57,57,57,55,55,58,62,58,59,58,55,50,53,50,41,39,40,47,49,52,60,60,60,61,59,51,49,33,18,22,24,25,24,22,16,21,27,27,27,39,51,55,59,61,59,62,61,57,60,57,62,63,60,64,59,66,62,58,62,59,60,57,45,47,44,43,77,77,74,107,122,105,106,120,114,114,124,127,152,142,143,165,127,127,122,117,117,102,132,139,118,120,116,122,139,143,137,124,117,107,118,131,121,113,99,107,113,105,100,105,125,145,145,131,119,98,93,90,98,112,103,95,108,86,21,6,11,12,15,13,15,14,15,15,15,15,116,123,117,119,112,117,134,136,138,139,142,141,145,150,151,167,160,137,113,100,107,104,103,101,111,139,196,250,237,79,88,180,74,31,33,17,25,26,65,82,46,45,75,89,89,93,79,78,85,86,89,84,84,87,89,92,93,88,87,94,88,93,98,91,96,90,90,90,93,96,107,131,126,111,98,94,94,91,92,87,96,105,108,123,122,106,109,112,115,112,97,104,106,101,101,107,118,117,117,115,125,128,134,136,103,103,106,104,117,135,136,123,125,108,105,110,122,133,140,139,131,136,126,135,131,139,150,155,160,134,137,119,106,112,105,109,107,107,113,159,189,189,166,139,113,116,141,129,111,108,126,134,113,116,112,156,181,197,232,234,238,215,127,101,132,133,113,69,66,63,71,117,140,128,121,125,104,90,99,108,96,103,118,117,116,121,108,93,105,105,104,107,112,123,108,102,81,81,111,127,123,103,118,112,93,79,74,74,71,73,64,57,58,71,107,128,122,133,128,107,102,112,125,129,127,133,156,172,179,182,178,171,170,164,167,160,159,171,170,169,165,166,163,121,126,156,124,102,96,110,111,112,118,111,112,103,107,120,129,117,107,111,102,109,143,170,181,162,169,169,130,117,125,129,129,137,128,225,222,191,251,213,163,103,128,214,201,136,126,137,103,68,50,5,66,205,173,143,189,100,26,66,78,122,129,125,142,142,140,89,146,178,146,126,102,179,196,154,148,78,5,37,34,32,57,55,56,35,29,28,23,37,28,31,43,43,39,33,29,26,33,25,30,27,23,29,20,24,24,24,24,22,26,29,31,23,24,27,35,53,70,100,88,60,41,75,97,87,78,70,86,82,104,120,109,89,50,27,25,29,62,98,111,120,116,104,106,84,90,90,83,85,35,56,68,85,97,94,100,84,110,103,123,141,116,75,38,48,57,57,56,51,33,20,31,38,26,27,29,25,26,44,61,58,55,74,103,94,54,62,79,60,59,59,62,67,68,69,62,56,55,59,55,59,56,53,56,53,53,50,57,56,51,55,54,55,53,47,59,54,51,57,55,50,54,53,30,19,22,24,20,19,23,20,22,22,25,48,54,53,54,53,54,56,56,55,48,42,42,33,38,47,46,50,58,57,55,56,57,59,59,54,53,58,58,53,52,53,50,41,22,22,19,21,21,24,21,20,22,21,31,44,50,53,42,36,31,29,32,29,52,59,58,59,60,55,55,55,53,49,50,52,54,59,54,56,46,48,55,59,59,54,54,56,59,55,59,55,56,57,57,57,53,53,52,55,51,28,19,21,20,19,21,24,19,18,21,24,39,48,50,58,57,53,59,61,57,55,60,59,58,58,57,60,57,60,57,44,46,43,47,54,47,60,57,60,57,57,57,52,47,25,20,21,22,27,21,15,23,19,21,26,24,43,59,59,56,61,61,58,50,49,57,61,60,61,61,58,59,63,63,60,57,57,60,54,42,58,101,140,162,140,124,116,102,83,96,100,78,84,95,120,132,131,134,132,105,97,92,92,113,111,127,111,97,113,112,122,139,152,150,145,146,135,127,119,129,122,82,78,97,103,99,101,108,125,117,111,108,92,83,81,92,102,101,95,107,95,19,5,13,11,14,13,14,14,14,15,15,15,116,118,105,112,104,110,130,130,136,141,144,137,143,146,168,205,204,191,153,129,123,118,119,113,120,116,171,250,233,78,69,84,11,37,35,16,29,26,39,45,46,57,89,113,103,111,98,92,100,101,101,89,93,94,98,105,95,92,89,92,96,88,96,94,91,92,93,100,96,91,107,133,125,115,110,100,89,88,101,105,98,106,115,116,101,90,111,111,113,108,101,116,113,115,111,111,117,111,110,102,106,106,110,120,97,100,108,107,110,111,111,111,113,105,116,121,128,137,126,127,113,103,101,110,116,113,118,124,127,115,116,103,100,103,100,104,98,104,112,141,157,150,128,110,106,128,163,137,110,115,132,134,112,106,122,143,159,169,176,178,191,242,218,208,167,159,189,139,131,81,57,112,151,157,155,159,137,125,128,137,133,122,129,132,117,120,114,85,89,94,80,81,90,92,83,78,77,97,124,130,108,108,119,100,98,91,98,99,84,81,75,62,51,60,95,99,106,120,126,107,101,121,113,112,120,142,165,171,177,172,168,170,169,168,167,168,167,166,169,167,164,166,178,114,75,123,131,130,125,138,116,103,102,91,94,77,78,101,123,106,108,107,98,106,113,132,143,139,133,125,120,129,133,120,127,118,158,252,201,215,251,221,166,123,201,221,136,79,110,184,137,49,42,1,78,184,131,152,198,101,42,95,132,166,159,155,146,177,141,104,170,145,154,170,172,230,245,158,92,42,1,19,36,65,71,46,35,24,24,29,26,31,34,33,34,40,44,37,30,29,26,26,26,24,24,23,23,23,23,26,24,29,29,25,28,27,25,27,43,54,82,108,100,77,54,76,77,78,77,81,94,89,119,128,102,51,17,17,37,66,105,116,114,108,106,108,95,85,92,78,118,103,17,14,30,69,87,90,69,53,88,98,119,131,102,80,59,53,54,62,67,63,47,27,22,32,33,33,33,26,46,57,54,41,31,55,61,55,39,59,81,68,63,59,62,71,70,61,56,56,55,56,57,53,58,55,49,54,53,55,53,50,56,60,57,59,59,57,55,54,59,54,55,57,51,42,28,20,17,21,23,21,21,16,24,19,32,51,52,52,50,54,53,50,54,53,49,39,32,29,35,54,54,55,50,53,57,55,56,52,54,51,56,57,47,52,55,53,48,36,21,18,24,26,21,21,24,23,23,24,34,50,52,51,39,35,34,37,29,36,52,55,52,59,59,53,53,50,52,45,48,49,51,48,50,45,30,38,47,53,58,53,53,51,54,57,50,54,54,58,55,53,57,52,50,52,42,25,17,22,20,21,24,22,20,15,24,32,46,52,55,63,53,57,57,59,56,55,62,59,61,65,65,65,59,61,55,45,46,45,50,49,54,59,59,62,62,60,58,53,37,19,19,22,23,19,17,22,25,19,20,26,37,56,60,59,57,65,62,50,48,51,58,58,59,59,56,59,60,60,60,63,63,55,61,49,43,116,162,184,187,160,148,113,85,79,81,87,73,77,90,102,121,109,106,100,88,77,53,71,99,113,117,100,89,107,125,134,141,153,148,131,136,133,114,108,147,148,106,101,108,114,114,113,105,112,113,108,113,108,106,96,89,80,81,84,101,89,19,5,13,12,16,13,15,15,15,16,15,16,155,141,112,120,116,110,111,107,111,113,118,109,108,112,120,158,169,166,135,122,122,118,116,122,139,133,196,250,228,71,72,64,4,49,28,26,31,23,36,41,44,55,103,122,113,119,112,111,110,116,116,112,108,110,116,123,124,117,115,110,113,115,115,107,107,110,119,125,113,113,107,117,117,116,111,95,96,103,113,103,107,112,109,110,89,95,117,120,114,114,118,126,125,121,126,125,122,112,90,91,94,80,92,110,99,106,117,113,101,107,104,109,116,107,117,114,108,107,115,111,92,90,92,95,82,83,84,91,105,104,108,98,102,98,97,99,92,86,88,111,110,111,108,111,97,114,147,124,108,99,92,89,69,69,86,99,149,193,190,139,149,234,201,157,88,98,202,230,225,179,149,150,145,117,131,139,141,146,148,137,128,118,122,124,105,110,106,90,102,98,95,91,95,102,82,77,80,84,111,116,91,93,97,84,79,99,135,131,120,108,88,79,68,81,98,95,95,124,137,120,125,118,99,116,143,158,171,171,163,170,171,170,169,164,168,168,168,170,168,166,163,166,173,141,94,112,127,122,128,136,131,117,109,111,103,78,67,78,96,93,95,97,102,105,96,84,94,107,97,99,102,117,128,112,129,123,202,252,212,242,251,243,174,160,225,192,85,64,169,211,177,62,32,7,93,204,143,181,210,125,80,101,153,155,136,162,163,179,120,144,171,150,181,196,185,165,188,136,71,19,5,49,61,64,43,31,33,29,29,27,32,33,31,33,32,33,43,44,43,26,28,33,24,24,23,24,23,26,23,29,27,27,30,21,26,26,29,39,51,61,82,105,103,86,66,71,75,87,91,99,98,97,129,93,41,19,16,42,78,106,119,114,101,107,104,105,99,83,96,99,140,146,40,14,31,69,95,84,78,74,93,98,124,114,67,70,96,97,57,57,67,68,61,39,26,23,33,33,35,51,60,48,30,22,20,35,59,55,50,81,83,65,59,62,63,69,69,61,53,50,53,56,55,52,55,49,55,57,55,51,50,54,54,58,53,61,59,55,60,56,53,53,53,54,53,44,26,19,21,18,19,17,17,20,22,28,39,50,50,49,49,47,53,51,57,57,47,38,29,35,45,50,50,56,53,56,55,51,56,59,55,53,53,56,53,54,53,50,44,30,18,19,19,16,21,19,18,21,18,29,48,51,50,50,40,35,39,36,31,41,55,49,51,53,51,45,35,36,39,39,37,36,32,33,28,26,25,25,34,43,56,53,50,56,53,53,51,53,57,49,56,57,50,52,54,46,37,24,15,19,16,24,24,19,19,22,20,31,54,57,54,59,57,57,56,57,59,60,58,56,62,61,61,63,57,61,50,43,46,42,53,56,54,59,57,61,62,59,57,45,23,21,17,19,21,19,25,21,20,21,23,34,50,60,59,60,64,63,60,47,41,54,57,57,57,58,59,54,60,62,57,59,66,60,63,43,58,126,159,156,146,131,105,81,56,44,84,107,78,77,99,129,122,115,110,105,113,91,83,79,93,107,105,95,98,122,130,141,145,150,136,118,110,106,110,118,165,172,138,124,109,104,105,105,108,122,121,119,125,128,116,99,93,74,71,59,69,75,21,7,12,12,15,13,14,14,14,14,15,15,198,162,136,132,130,120,119,111,101,120,135,117,121,119,100,114,117,120,115,122,118,115,116,127,151,150,214,249,229,71,69,49,13,52,21,35,31,26,43,40,45,54,104,120,105,113,115,117,115,125,126,115,118,110,115,128,132,137,123,118,120,123,128,115,110,109,119,128,127,125,115,109,105,105,115,112,104,109,115,112,110,117,116,109,100,104,125,129,130,123,121,132,130,129,130,121,125,113,100,95,81,80,93,104,97,98,103,103,90,85,89,95,104,98,113,97,88,92,103,122,105,113,116,115,110,105,112,119,128,128,120,118,113,108,114,102,103,101,104,112,109,122,122,111,100,104,115,111,110,85,62,77,78,63,55,51,97,157,177,151,143,151,127,97,24,28,121,181,237,237,221,201,156,109,84,78,84,113,121,107,102,90,102,106,91,98,112,112,119,127,105,99,101,95,111,101,77,85,101,107,84,98,103,77,81,84,121,134,127,117,96,88,77,91,126,121,145,159,146,131,123,129,126,147,163,161,158,156,148,152,160,160,159,160,160,159,163,163,162,157,153,157,173,158,126,114,103,118,127,135,128,113,106,102,89,72,84,92,106,91,77,84,86,87,68,60,62,80,91,87,92,107,105,112,118,139,242,252,228,227,244,240,156,157,220,155,47,32,97,191,175,69,36,21,145,253,185,159,180,143,107,115,182,158,151,179,182,139,96,172,174,168,180,164,110,42,86,83,34,19,36,66,56,38,29,27,32,36,35,35,34,33,33,32,32,31,28,46,46,35,32,21,31,25,23,32,25,25,26,31,23,24,28,24,23,27,38,50,57,80,101,95,81,63,69,91,94,94,93,117,112,88,70,30,18,24,50,87,111,117,109,100,105,98,105,104,88,97,106,94,160,177,90,66,52,74,87,88,93,97,107,106,115,96,78,92,113,136,94,49,63,67,71,54,31,21,24,43,52,51,39,23,21,22,16,24,41,60,67,91,84,63,67,61,69,70,61,54,55,49,55,55,56,53,48,55,55,52,53,55,55,55,55,58,63,55,56,59,53,55,53,53,53,54,49,39,24,17,20,17,18,18,19,19,32,36,39,49,44,48,41,39,42,42,46,43,38,29,35,31,36,48,44,49,55,58,57,56,57,55,54,50,53,56,53,51,49,47,44,27,19,19,16,19,19,21,19,16,27,41,46,53,50,45,43,34,37,32,32,54,59,57,54,55,37,19,18,16,17,15,20,21,17,19,17,20,20,15,32,50,55,53,50,52,48,52,53,50,51,51,53,54,55,47,51,46,26,21,21,17,16,19,22,18,19,23,29,43,60,51,52,57,54,59,53,57,55,59,59,50,57,57,57,61,61,50,42,38,38,40,46,56,49,56,59,57,61,58,54,38,26,17,17,22,19,21,21,27,21,19,26,44,63,65,61,66,60,57,56,41,46,55,60,64,59,63,61,62,66,63,69,70,64,65,55,38,92,146,139,126,114,86,73,68,51,62,113,125,69,63,96,105,112,115,118,105,100,90,93,93,86,84,83,101,112,118,120,127,136,145,126,101,101,101,102,99,137,156,133,110,76,64,65,77,92,104,111,116,126,122,114,95,91,83,53,39,34,43,24,8,14,13,14,13,14,15,15,15,15,15,171,155,144,131,126,128,131,126,115,122,141,130,137,139,115,109,101,117,121,131,128,120,126,135,147,147,216,250,228,74,70,43,12,50,19,29,30,29,44,43,47,56,101,117,92,96,108,111,108,119,115,108,108,101,100,103,113,117,113,98,96,110,115,111,101,89,93,108,112,109,102,109,105,110,121,117,119,114,117,118,122,118,112,118,107,122,136,133,130,115,121,126,124,126,126,120,109,113,103,98,92,84,111,117,97,90,87,87,77,80,71,73,93,94,104,101,95,93,110,115,131,145,145,151,145,147,147,150,134,133,130,126,125,115,103,107,121,122,117,115,118,122,126,122,112,107,102,102,109,102,101,121,111,79,56,51,56,78,93,104,126,121,117,147,127,51,35,112,153,164,220,195,194,181,138,104,83,88,89,74,83,73,86,110,103,115,122,118,123,130,113,94,72,79,115,104,92,84,104,121,108,125,127,118,96,79,82,99,120,113,123,123,96,120,139,158,163,131,120,117,131,149,149,162,165,149,148,146,135,143,152,155,157,152,151,152,148,147,148,148,145,152,170,162,140,122,108,105,111,111,115,100,95,105,74,69,99,122,110,68,56,51,53,61,53,44,55,79,88,92,88,94,84,89,107,179,234,252,229,213,240,226,163,188,221,148,40,6,12,46,84,40,31,40,159,245,140,104,122,132,111,144,203,163,161,176,174,100,137,210,193,182,154,118,70,14,8,27,39,53,68,48,26,29,27,27,29,24,40,39,35,36,29,33,29,29,29,25,44,47,34,24,22,26,24,27,27,28,27,24,24,26,27,27,28,31,49,54,70,93,99,73,62,72,82,101,103,107,106,118,84,49,27,15,33,65,95,121,116,105,101,104,101,99,102,92,94,104,113,95,150,176,94,92,75,76,80,86,104,102,103,105,113,98,98,111,113,122,88,59,54,63,75,64,48,21,31,49,44,38,21,17,24,17,21,30,53,57,68,90,74,63,66,71,78,68,55,56,55,55,56,61,54,53,57,59,60,59,53,57,61,55,57,59,56,59,58,60,53,53,55,53,55,50,50,32,16,24,13,19,20,16,21,24,40,44,43,45,42,40,37,39,33,25,27,27,24,27,25,24,22,33,36,43,56,54,54,53,54,54,54,55,51,50,49,54,50,44,39,26,15,20,21,16,18,18,18,29,32,32,39,47,48,41,34,39,36,27,39,50,44,50,53,48,30,11,17,19,14,16,16,15,15,19,21,17,19,22,47,57,57,58,52,51,48,55,49,48,50,50,53,49,51,51,45,41,25,16,18,18,16,19,22,15,22,33,39,50,53,54,55,56,58,51,53,57,53,58,53,47,54,52,51,53,54,47,35,31,42,43,46,53,49,56,55,53,53,53,47,31,23,21,16,17,18,19,21,18,20,25,39,56,61,63,68,65,62,56,45,36,48,63,60,64,66,63,75,71,68,71,68,65,52,44,34,72,143,134,119,118,100,72,74,92,108,124,143,127,66,43,55,58,55,75,74,47,42,38,72,89,75,70,60,69,78,84,81,87,108,125,113,100,110,95,67,47,83,113,94,71,48,34,44,53,57,72,81,97,98,102,88,77,83,64,55,34,21,29,17,12,15,14,15,15,15,15,16,15,16,15,132,155,167,126,115,124,141,140,108,113,117,98,123,132,117,117,109,122,116,120,122,119,130,134,122,124,210,251,226,71,74,43,13,48,24,37,26,30,43,46,53,58,112,122,97,101,101,108,109,118,114,100,115,107,105,101,96,102,101,101,103,110,113,113,107,94,92,106,103,107,107,102,116,121,122,117,113,122,120,118,120,117,117,116,115,130,149,138,118,118,113,111,111,117,119,113,107,95,108,117,100,101,121,115,108,108,102,112,100,97,94,96,113,103,107,109,122,105,94,106,114,128,123,135,139,127,130,129,130,122,121,127,96,85,82,80,119,111,97,96,96,109,120,127,124,117,109,106,114,116,128,128,102,94,88,91,79,57,69,80,88,116,163,190,169,80,46,99,128,128,144,162,212,232,207,162,115,87,65,63,75,81,98,116,126,128,130,124,121,125,116,121,106,96,117,107,106,114,123,134,128,139,149,128,102,80,75,81,123,150,153,137,120,133,145,141,119,82,76,114,146,172,176,185,185,177,178,180,165,178,190,180,184,181,172,160,159,163,176,185,177,190,193,165,156,148,115,93,95,107,115,113,121,129,99,90,110,118,112,75,56,63,60,68,65,56,49,60,78,77,83,84,77,84,106,219,251,251,234,218,250,236,187,200,225,168,61,9,2,12,46,41,39,75,129,141,89,43,64,104,128,195,193,171,171,177,157,142,221,245,169,158,157,97,57,9,11,49,72,69,42,35,31,26,27,29,33,35,27,37,44,39,33,29,31,28,31,29,25,39,42,35,29,23,32,27,30,29,22,28,24,27,30,28,36,48,55,65,88,103,78,64,83,88,98,103,110,121,120,97,48,28,23,28,69,101,120,111,96,103,95,94,105,97,108,100,89,99,97,74,124,149,93,95,83,87,88,96,106,101,105,104,109,110,109,105,93,111,90,49,47,54,79,77,64,42,35,39,25,23,19,18,18,23,38,56,66,73,78,62,41,58,84,89,80,67,70,67,67,67,69,69,57,47,69,72,70,63,61,67,65,66,63,59,60,58,62,63,57,57,55,55,57,54,47,29,21,17,16,20,23,19,16,31,45,41,46,42,37,40,30,41,41,28,31,24,26,27,19,22,26,25,31,41,48,42,54,62,59,60,57,58,57,57,58,57,55,53,39,20,18,17,19,19,19,22,20,20,19,20,25,28,33,40,39,34,33,27,24,28,29,25,37,39,22,15,17,17,15,17,15,17,17,18,19,19,16,29,51,47,51,50,46,44,41,53,50,54,59,54,51,47,49,48,46,30,20,19,17,20,19,18,22,19,32,42,41,51,52,54,56,55,55,58,57,51,48,47,47,49,45,41,49,41,48,42,39,39,39,44,37,44,43,52,54,50,49,45,37,21,22,21,15,22,16,21,23,19,28,42,55,61,65,62,60,63,57,48,42,43,55,69,64,73,78,75,79,74,71,55,51,47,34,34,31,96,122,108,136,132,99,85,106,130,149,153,145,131,96,77,59,30,48,67,52,30,28,42,110,140,102,87,86,92,87,75,72,87,99,122,115,112,111,74,53,33,53,84,70,77,83,66,63,63,53,50,63,71,76,78,68,62,68,53,47,66,79,76,23,6,14,12,16,15,16,15,15,16,16,16,142,174,188,127,110,134,170,168,120,122,121,101,122,130,128,126,120,139,124,122,125,124,120,126,118,125,211,253,224,66,86,48,14,49,22,32,27,27,44,50,55,63,120,135,108,101,103,117,111,126,126,109,118,110,105,102,104,114,120,116,105,109,117,120,113,109,105,111,119,116,113,109,110,117,116,107,104,103,110,112,116,114,107,111,104,131,141,128,118,110,124,111,105,109,113,119,105,93,111,124,113,103,105,94,99,112,112,114,105,113,113,117,130,116,114,118,131,114,92,89,96,96,88,102,108,92,84,94,109,105,111,108,77,78,83,97,104,89,81,97,101,105,106,91,108,112,110,100,93,103,97,86,77,102,121,118,122,115,99,102,85,106,134,139,121,69,59,114,127,98,96,120,132,176,185,181,180,172,137,107,109,101,99,121,126,127,123,125,122,116,128,137,131,128,128,111,123,136,114,117,117,129,135,111,98,89,73,83,113,134,142,107,92,117,108,104,89,59,56,91,163,200,192,207,220,219,224,219,198,201,220,214,209,207,182,170,182,205,221,228,205,213,220,163,134,135,105,92,95,92,115,124,131,127,100,96,89,106,129,116,107,99,89,95,74,54,53,41,66,60,70,114,114,98,126,234,252,252,250,232,251,232,180,185,185,172,112,36,19,100,164,61,53,110,104,62,39,12,18,101,167,214,188,179,188,187,174,201,250,174,94,123,114,52,18,6,59,96,72,48,30,32,36,31,28,32,33,30,34,33,39,43,36,34,28,27,31,29,25,29,40,41,39,27,28,30,33,26,23,33,22,24,31,30,42,57,60,83,95,78,77,83,96,96,101,117,112,114,83,35,19,25,51,65,99,108,99,99,97,98,77,92,103,100,108,84,79,65,51,39,108,141,84,97,76,93,100,88,102,103,98,103,111,104,98,93,92,102,101,83,59,52,74,84,76,59,41,17,17,23,17,18,27,44,55,60,65,76,84,64,61,92,93,94,79,78,84,75,83,77,70,63,53,55,76,89,83,78,70,73,76,73,71,65,66,66,64,60,63,61,57,63,57,55,46,34,24,19,16,18,19,17,23,28,44,41,37,34,32,30,29,39,29,35,32,19,20,26,27,24,23,24,26,37,35,32,54,59,62,63,64,61,55,62,62,56,55,50,37,20,19,16,16,21,18,22,20,21,20,27,22,20,36,41,37,39,33,23,21,20,20,30,41,31,21,16,16,17,14,19,19,19,15,17,19,19,23,23,31,34,31,37,32,28,29,38,54,55,54,56,54,52,48,52,46,31,18,16,19,21,21,17,21,24,34,42,45,55,59,53,56,53,53,55,53,53,49,47,41,41,43,44,44,38,43,40,40,34,32,38,41,47,43,44,50,49,46,44,35,19,18,18,19,22,14,22,24,30,47,49,58,61,60,57,62,60,51,45,39,49,66,74,72,81,78,77,84,65,44,36,37,33,32,28,36,89,109,112,145,132,91,104,146,146,147,133,116,129,124,110,109,116,133,143,121,107,112,133,186,184,139,141,152,164,156,129,123,125,137,148,139,136,123,95,76,46,83,125,98,99,107,90,88,83,77,57,49,67,77,89,71,65,66,45,72,108,157,113,12,5,10,13,14,12,15,15,15,15,16,16,122,169,180,132,126,149,188,184,147,160,150,128,148,148,153,149,146,165,149,148,151,147,141,146,130,145,224,253,218,69,105,56,15,51,21,36,24,29,44,51,54,59,122,131,117,113,105,118,113,119,120,112,115,103,106,115,120,128,120,110,103,107,113,115,109,109,110,121,119,119,121,112,120,118,117,103,89,101,103,113,112,104,103,91,98,111,130,134,129,141,135,124,112,121,123,123,124,112,122,123,110,96,85,78,90,99,89,88,75,83,88,94,112,102,107,105,118,116,97,100,107,111,103,104,90,79,80,88,94,90,96,95,81,93,100,105,104,85,85,101,102,97,84,70,77,95,103,89,77,71,77,69,65,92,97,107,123,126,120,114,94,78,76,93,101,74,74,91,91,102,114,94,92,113,139,167,219,245,216,174,166,132,105,124,121,111,109,107,103,113,125,118,116,129,136,130,136,127,91,84,88,110,135,103,92,97,74,60,77,98,122,118,85,91,96,87,66,70,57,67,143,183,178,208,231,230,232,218,170,174,210,211,200,193,184,171,193,213,214,214,172,201,217,131,90,103,101,104,105,98,97,110,124,97,66,66,61,83,125,139,136,105,79,85,70,57,40,44,85,80,99,128,139,108,149,253,253,253,235,214,240,203,171,147,178,183,150,132,134,227,201,71,54,79,54,7,26,28,28,110,192,200,189,194,211,201,179,199,187,119,57,38,45,18,26,67,85,63,41,36,30,31,35,39,37,28,27,33,36,35,32,39,44,43,28,23,27,24,31,26,27,40,46,41,29,29,24,24,25,28,26,29,39,41,56,59,83,90,73,88,96,92,93,94,107,116,108,66,28,19,28,57,83,97,112,106,100,99,100,104,92,92,98,100,105,90,84,67,61,51,112,141,84,92,80,99,88,85,100,91,97,92,94,93,89,94,93,105,107,112,100,64,64,75,83,73,45,20,14,18,13,33,50,57,61,63,77,89,101,97,96,103,110,101,74,63,69,64,66,67,55,46,43,48,62,69,83,81,74,67,72,66,67,73,64,69,66,68,66,65,63,59,59,58,42,29,22,14,18,17,21,23,16,22,33,34,28,24,29,33,34,29,24,22,30,27,19,26,23,29,25,22,27,29,38,37,42,48,53,59,57,54,44,41,52,42,37,39,28,20,19,16,21,20,21,21,18,20,24,29,26,29,33,39,39,34,31,27,22,24,31,33,31,25,18,14,19,21,19,21,21,22,20,23,19,16,21,25,27,29,23,25,24,21,25,30,48,64,56,55,58,54,51,46,46,27,19,21,17,22,18,22,22,21,45,51,51,56,56,58,57,56,58,59,56,50,51,45,43,48,50,51,47,43,44,35,38,39,40,40,43,53,48,50,51,45,48,41,27,25,23,17,22,25,19,19,26,40,50,54,57,60,62,64,66,63,48,45,46,54,69,79,72,76,78,61,60,45,35,26,24,31,31,29,48,120,112,92,111,95,92,120,139,127,115,103,89,103,99,101,153,182,194,193,181,171,170,193,201,179,145,141,173,184,179,156,136,141,141,156,153,155,154,129,112,77,121,171,117,89,92,88,113,124,106,90,91,98,114,122,103,99,103,94,112,152,187,115,10,3,10,12,14,12,15,14,14,14,15,15,92,124,141,118,128,151,166,162,149,162,150,145,155,150,160,152,150,163,149,151,163,161,152,157,142,161,235,253,206,64,117,54,13,46,17,37,16,30,42,46,58,64,113,122,115,111,101,113,95,96,107,108,123,118,116,115,119,125,116,110,102,106,113,111,108,107,110,113,113,117,116,121,128,124,118,108,112,115,120,113,103,101,104,111,108,127,143,148,147,148,148,135,140,152,142,149,147,141,149,137,133,128,119,108,110,109,104,98,81,71,69,83,92,101,105,102,125,116,117,136,136,140,116,99,97,92,92,95,94,81,91,92,95,88,76,97,96,83,80,92,83,81,74,43,64,90,106,98,74,71,78,72,72,85,88,89,104,113,118,120,107,104,95,103,118,104,94,78,75,92,121,121,109,125,110,125,153,185,188,185,207,174,121,120,123,118,92,79,69,83,114,105,107,123,133,124,123,115,101,105,87,83,116,110,92,87,81,58,54,67,118,140,107,90,80,80,74,65,55,59,121,167,159,192,239,240,237,206,160,159,193,212,193,186,184,181,189,195,192,189,155,168,161,98,84,106,95,109,116,113,117,109,119,77,39,42,55,94,98,103,97,69,63,69,57,45,32,56,162,157,95,77,126,129,188,234,240,212,165,175,195,172,129,160,160,113,114,73,120,160,127,37,27,66,56,22,87,94,63,133,171,184,205,207,230,223,142,127,146,74,33,14,12,50,85,74,48,32,34,34,27,35,34,37,40,38,34,33,34,30,33,36,37,45,36,30,25,27,32,27,27,29,45,44,37,28,23,29,24,30,35,36,36,48,57,64,68,68,73,90,100,99,99,95,112,103,50,23,18,41,70,86,108,99,103,105,101,108,102,100,97,105,104,102,108,100,104,99,104,77,139,152,86,103,82,104,95,77,93,96,100,88,85,93,94,93,94,105,117,118,123,96,70,71,80,76,57,29,16,20,41,49,55,58,62,74,80,100,104,96,110,125,119,98,52,40,48,48,50,46,48,46,42,42,44,55,62,57,57,53,48,51,56,51,47,48,57,53,53,51,45,53,46,37,32,23,20,18,15,19,17,19,20,22,25,24,25,31,34,29,35,34,25,27,32,24,25,25,24,30,26,30,32,37,40,34,39,46,42,34,41,40,30,26,30,30,31,29,19,21,20,18,22,21,20,17,22,26,22,27,25,23,31,35,35,35,31,28,28,29,38,31,24,19,17,18,18,18,25,23,20,24,19,22,18,19,21,25,29,24,25,22,23,26,28,29,45,56,57,57,53,54,55,53,37,22,24,19,17,21,19,20,19,33,38,47,51,53,61,55,57,55,60,60,51,51,47,43,49,47,51,51,48,46,38,36,41,37,45,46,49,57,51,52,55,48,45,39,29,21,22,17,19,18,22,24,22,44,53,60,66,60,66,66,62,63,49,46,50,56,60,66,61,73,69,50,43,30,29,27,27,27,33,31,93,128,93,66,60,69,86,93,101,78,75,84,71,73,73,104,152,165,171,174,178,160,155,171,158,148,132,131,146,135,139,130,119,114,104,128,145,143,141,137,134,104,152,190,122,86,85,107,143,146,141,135,141,151,140,136,124,134,150,147,164,171,181,111,9,3,9,11,13,12,15,13,15,16,15,15,83,94,93,93,104,123,140,139,136,142,131,139,145,132,144,135,129,137,125,136,143,150,147,148,142,164,237,252,196,63,96,37,18,46,24,39,19,30,40,46,56,67,117,126,114,110,100,98,94,98,105,109,121,123,105,100,105,111,107,103,113,108,112,121,108,109,105,110,110,106,106,119,129,118,118,114,110,120,117,110,104,110,117,122,133,142,159,155,144,154,151,150,151,154,156,157,158,156,166,171,177,174,159,149,149,159,160,158,142,126,125,125,135,139,135,137,143,124,127,152,151,134,110,108,103,101,98,103,103,84,92,99,94,81,57,83,89,85,80,82,78,67,65,50,58,90,111,118,114,92,95,83,86,104,99,112,110,113,117,119,129,128,117,118,117,93,88,86,70,79,102,114,128,146,136,93,89,112,131,163,218,198,133,123,112,112,84,62,55,70,112,115,113,113,121,119,113,116,121,117,103,98,97,94,102,109,95,100,95,80,85,108,83,64,71,80,90,77,55,66,137,176,152,157,214,251,249,201,155,166,198,217,207,191,183,171,179,182,190,186,151,138,118,89,98,114,87,101,120,123,108,101,121,92,74,72,69,94,93,85,83,53,61,111,115,145,131,154,232,191,171,141,131,172,227,236,181,138,104,129,173,128,136,157,84,99,127,81,34,64,67,28,19,69,152,119,122,101,94,170,179,206,231,212,197,194,101,61,78,46,13,10,70,88,63,48,36,29,30,37,27,34,34,31,44,39,33,34,40,31,34,35,31,35,34,39,27,28,30,25,31,31,34,41,41,35,27,25,33,35,34,38,50,55,62,64,81,78,74,106,104,105,113,106,74,31,20,28,50,86,101,107,101,90,101,99,102,101,97,98,98,105,109,105,101,103,110,105,111,86,161,172,92,104,84,112,100,94,97,86,100,91,101,94,96,100,96,109,111,124,133,97,75,73,80,83,68,49,29,42,57,59,59,69,73,80,97,99,95,103,119,127,129,81,46,45,42,47,46,43,46,48,43,40,41,42,46,47,46,48,39,34,42,43,39,45,43,43,40,35,44,39,34,34,30,21,22,18,24,17,22,24,21,29,18,24,29,29,26,27,30,26,27,35,37,23,26,21,25,32,27,33,40,37,36,43,41,44,43,32,32,37,29,30,27,35,42,28,19,18,23,21,19,19,18,22,19,23,27,24,26,30,29,26,27,30,25,27,28,38,41,28,28,17,15,18,17,17,17,26,21,19,17,18,22,19,21,28,31,32,31,25,29,29,36,34,37,47,41,43,40,44,49,46,34,21,22,17,17,24,16,20,21,23,34,35,44,54,59,57,56,57,56,55,53,50,41,38,46,46,51,53,44,39,37,39,44,40,42,42,43,51,51,51,53,55,50,36,23,23,21,16,21,22,16,22,29,40,57,66,67,69,63,63,64,57,54,50,51,54,50,53,52,68,68,45,37,28,29,27,25,28,30,40,89,124,103,83,67,72,70,61,66,48,39,50,63,90,111,113,122,125,130,141,154,146,136,142,123,123,114,107,98,83,115,122,111,93,76,101,121,115,108,117,136,133,166,188,130,100,112,122,138,140,135,146,156,153,141,128,138,150,160,164,169,163,157,106,13,2,11,10,15,13,15,14,15,16,16,15,92,93,87,81,80,89,106,120,133,136,133,139,135,127,133,134,124,124,124,126,139,148,143,148,140,167,239,253,190,54,77,20,22,44,19,40,22,32,36,48,58,71,126,130,124,112,99,102,104,117,106,100,101,101,102,89,92,101,98,111,108,108,116,107,105,102,106,102,105,102,95,115,110,103,106,105,101,101,106,102,105,109,115,120,122,122,128,138,130,135,130,127,134,140,130,123,116,120,137,147,170,167,152,140,138,156,169,177,169,167,168,173,180,181,174,158,135,100,112,130,132,131,100,101,106,89,90,94,86,73,81,78,84,73,63,87,99,106,91,77,65,87,77,61,87,101,123,126,113,107,96,93,101,108,114,120,112,107,115,105,117,119,100,111,98,84,76,81,81,69,87,97,96,111,119,113,97,101,107,127,160,146,127,107,93,90,75,85,82,105,123,94,87,109,153,163,127,114,109,127,129,119,118,120,119,118,93,117,110,103,82,63,57,70,76,89,111,112,81,74,117,160,147,100,131,193,179,115,106,147,198,214,191,182,169,154,141,141,152,157,147,140,116,98,103,106,93,105,113,101,83,82,120,111,98,92,83,110,103,113,105,73,109,163,208,252,251,251,253,253,253,213,182,211,234,213,160,143,132,158,156,122,152,139,107,170,184,122,103,115,119,63,16,84,164,139,142,113,161,208,209,245,227,145,125,150,69,34,21,10,33,67,81,59,43,33,33,32,36,30,28,37,29,30,31,37,42,35,37,33,29,27,30,33,38,44,35,34,31,31,38,29,24,28,41,42,35,34,36,39,36,44,61,65,76,90,96,99,98,116,118,118,92,46,31,18,27,65,98,112,107,94,93,93,99,99,100,100,94,85,77,97,95,102,101,97,106,99,109,78,177,174,78,102,81,105,100,92,91,76,94,96,103,97,96,95,85,105,123,119,83,40,41,67,89,91,86,66,61,74,62,63,60,68,76,87,94,89,103,77,61,56,47,50,51,49,46,48,50,51,52,48,46,46,41,39,43,49,48,41,38,33,42,40,43,41,40,37,40,43,41,38,40,35,30,23,19,24,17,24,21,22,25,22,24,23,26,35,34,24,22,27,34,40,39,31,24,17,31,42,40,36,38,42,39,39,37,43,49,42,33,29,24,29,32,35,46,35,24,22,19,21,22,27,26,27,24,23,30,28,27,27,30,32,33,33,22,27,38,41,42,27,19,18,22,23,20,21,21,29,29,20,18,21,22,21,23,29,36,35,29,28,30,32,42,37,23,36,32,30,34,28,32,32,26,25,17,17,18,19,19,19,23,23,27,28,31,38,37,51,50,48,55,53,56,44,36,34,38,46,48,48,42,44,38,35,36,33,34,33,40,46,45,43,49,50,48,34,17,21,18,18,19,20,22,22,30,46,49,57,64,60,59,60,61,59,54,53,51,57,56,56,52,61,61,43,36,29,32,29,27,29,28,39,60,91,101,104,88,73,69,62,85,61,26,51,82,104,105,90,76,76,88,94,131,141,141,139,99,100,102,83,78,83,114,111,106,96,73,94,106,96,85,93,122,118,144,156,118,119,120,110,109,104,111,117,125,123,115,116,124,136,136,143,156,148,141,99,16,3,11,11,15,13,15,15,15,16,15,15,95,97,93,93,84,77,76,107,122,136,146,146,137,132,143,137,132,132,129,142,147,155,145,143,136,166,239,253,192,84,102,21,29,46,17,33,24,36,34,47,62,64,110,124,118,116,103,106,112,116,103,88,89,101,105,99,105,110,112,108,112,99,103,115,99,103,101,96,99,101,91,102,111,96,91,98,94,100,104,92,95,98,101,110,100,92,97,108,106,98,101,97,109,111,92,66,51,71,93,107,117,117,125,118,106,115,133,149,151,154,157,165,176,168,143,118,87,61,83,95,94,108,99,91,88,78,67,66,64,54,50,48,61,61,64,97,113,120,100,95,87,89,93,93,117,115,103,84,70,80,105,116,127,130,121,117,103,114,125,103,95,117,94,93,98,83,91,88,79,77,79,87,81,87,118,122,111,107,104,106,109,95,90,96,87,88,94,119,109,93,105,90,89,99,143,152,116,110,119,131,154,153,134,139,131,101,84,98,99,95,85,88,82,84,85,70,104,124,116,96,87,110,99,56,34,70,75,52,70,120,181,183,155,156,162,145,127,99,103,111,118,134,122,112,93,98,98,105,103,83,64,75,100,91,84,70,84,106,103,105,110,93,112,184,216,250,251,251,244,215,244,168,128,220,239,193,199,165,168,173,122,128,161,201,187,191,154,116,118,149,141,41,2,51,146,161,132,160,226,220,232,228,133,84,63,85,38,5,29,41,71,66,54,39,38,33,33,36,26,38,36,34,32,31,35,27,36,42,33,32,33,29,33,29,36,38,41,39,36,33,29,29,23,30,31,45,50,39,39,40,49,57,69,90,104,98,99,102,114,135,123,77,38,16,23,40,78,107,112,110,92,96,94,95,102,96,92,101,97,79,75,83,99,101,99,98,104,99,103,84,187,184,75,87,74,102,87,78,71,60,90,90,105,96,98,90,77,117,100,49,26,18,26,51,76,102,101,66,72,82,54,63,70,72,83,81,90,104,83,48,22,12,23,36,48,46,48,50,50,51,48,50,50,52,48,44,50,49,52,53,46,45,44,44,41,37,39,44,47,41,39,42,39,33,30,22,19,16,19,24,17,21,23,19,28,26,29,38,34,25,19,29,43,43,47,34,32,28,40,66,47,39,37,39,39,38,39,45,50,46,35,25,26,30,34,38,47,36,28,20,19,19,21,29,24,26,30,28,29,28,26,35,33,33,34,22,23,32,45,44,43,35,22,27,29,33,33,33,30,30,39,44,42,32,21,24,28,33,30,31,35,29,36,39,42,38,31,28,22,32,26,27,29,29,23,19,23,17,23,20,20,24,24,27,30,28,32,32,34,41,37,46,49,46,39,30,25,31,37,43,46,41,39,35,33,26,29,31,22,27,34,44,39,42,43,40,35,26,23,22,22,19,21,22,21,28,37,40,48,54,56,59,56,61,62,55,57,54,54,58,56,55,52,56,57,45,39,34,28,33,35,28,33,42,47,61,68,69,64,67,54,63,83,52,50,80,57,57,61,40,38,42,35,42,106,139,130,111,79,98,100,92,92,96,111,100,107,92,83,104,105,93,80,84,98,96,94,116,116,116,125,108,93,94,100,96,105,103,101,97,104,105,96,115,137,138,139,100,18,3,12,12,16,13,16,15,15,16,16,16,89,101,103,108,117,108,103,108,110,128,145,148,140,140,142,137,136,139,147,150,153,157,141,135,126,160,237,251,189,107,127,34,30,36,25,35,22,35,34,45,59,69,94,95,101,107,102,96,98,109,98,87,86,104,108,92,116,127,119,119,100,100,105,103,107,97,97,89,99,98,86,107,120,112,97,97,89,93,98,86,94,97,100,108,107,95,96,101,86,83,87,97,105,96,78,66,53,62,69,69,87,89,113,117,110,115,113,120,114,121,122,132,141,109,80,63,43,36,56,50,59,94,85,81,85,66,66,58,57,53,53,42,53,68,61,84,101,99,89,100,83,89,101,109,132,87,68,65,42,72,86,125,137,114,120,119,118,117,129,110,101,108,87,93,80,89,98,102,101,75,92,104,104,110,137,143,114,112,125,123,108,78,66,87,114,107,104,114,90,64,78,92,89,78,99,89,84,89,101,118,132,134,117,121,116,93,93,106,122,117,113,128,122,108,103,92,123,153,158,145,93,75,57,45,42,55,65,62,90,122,157,160,146,152,165,157,128,104,97,92,97,105,106,103,93,93,93,95,94,83,77,89,89,68,49,60,92,113,104,84,79,69,90,145,145,174,148,134,109,79,137,79,78,160,176,196,235,199,190,159,145,151,206,242,218,160,87,89,106,125,108,41,12,68,161,162,147,208,246,187,188,172,96,57,10,16,24,29,56,69,60,42,31,43,41,34,38,33,30,35,40,33,33,39,35,29,30,37,38,34,29,29,27,27,36,34,43,48,37,35,27,24,31,30,39,37,45,56,45,49,59,83,97,103,108,97,98,111,122,107,58,29,24,26,56,89,110,112,110,105,90,92,91,92,98,95,101,103,94,87,84,97,97,108,105,95,105,95,107,89,191,200,91,84,68,89,76,68,74,73,94,98,106,104,96,110,97,67,35,21,22,14,19,37,66,84,66,40,62,71,57,60,66,77,74,95,103,101,71,34,18,17,18,32,41,46,51,50,44,45,46,47,48,47,47,49,43,50,49,49,49,44,50,51,48,42,41,44,42,43,42,42,42,35,24,23,17,16,20,22,18,23,24,26,25,31,33,35,38,31,30,36,39,46,47,40,30,27,50,57,48,40,42,42,43,43,35,50,50,41,36,25,29,30,33,43,48,34,21,19,22,16,18,23,22,29,33,28,27,25,32,29,28,35,33,26,30,41,41,46,49,36,24,31,39,34,38,39,34,38,53,66,53,31,17,27,29,31,40,28,33,38,36,37,41,39,34,28,24,29,25,25,32,37,21,20,22,21,21,19,23,24,25,29,30,35,33,32,38,32,36,47,43,37,29,26,28,26,29,38,39,39,34,24,27,29,31,28,24,33,28,33,35,28,39,30,28,23,19,27,22,24,21,23,26,33,45,46,47,48,59,59,55,57,55,57,55,55,53,51,59,53,50,47,49,46,39,34,29,35,39,39,44,43,49,51,45,48,55,55,41,34,76,70,63,71,44,39,30,55,63,46,37,43,105,128,115,98,93,106,100,99,106,104,98,99,111,97,98,110,106,95,84,93,102,87,77,101,110,126,137,126,115,106,104,103,111,103,107,93,86,94,81,103,118,118,124,92,20,4,13,12,16,14,16,15,15,16,16,16,105,121,130,153,189,186,170,172,137,117,132,143,136,129,131,126,128,135,145,150,148,158,139,134,120,161,239,248,169,96,128,22,38,38,22,38,16,32,35,43,60,68,83,78,89,100,79,81,75,77,84,79,84,93,89,84,98,114,123,112,114,98,98,109,100,95,93,97,101,105,95,121,138,123,109,91,85,95,98,84,87,97,101,116,121,114,113,102,92,101,110,93,76,78,91,98,97,87,73,85,85,77,101,110,120,128,114,105,88,100,118,131,121,81,60,55,44,35,43,53,70,91,88,73,81,80,62,63,65,70,72,57,63,65,60,65,71,74,73,77,77,99,108,103,103,61,43,62,63,73,74,85,104,100,107,104,111,117,102,89,88,115,101,89,107,108,101,111,132,120,109,113,94,113,152,148,125,128,134,119,107,89,68,92,107,103,98,99,83,66,81,75,78,63,61,65,54,66,76,71,87,93,81,105,114,125,134,152,152,153,151,141,160,154,161,163,182,195,178,142,96,86,67,63,74,85,77,76,103,122,135,134,136,145,146,131,119,103,108,104,92,93,91,105,86,95,92,83,93,90,116,119,78,61,72,93,116,96,88,87,84,61,39,90,63,56,27,58,68,25,94,34,100,196,148,196,240,205,224,210,195,207,202,241,198,139,119,116,132,150,141,99,100,100,137,163,166,228,229,127,146,139,49,28,3,29,49,61,69,48,47,34,36,41,38,37,29,34,39,32,39,43,35,37,33,32,30,30,39,35,33,33,33,33,39,35,36,36,39,38,31,37,44,51,42,39,45,53,50,55,96,115,110,97,95,105,107,98,65,35,22,24,46,71,94,111,119,101,102,101,87,93,83,87,103,101,106,100,88,96,100,98,104,100,102,103,108,106,99,88,160,209,136,72,51,78,84,89,88,96,103,103,115,107,119,97,46,26,21,23,18,15,30,53,63,64,63,46,69,67,50,62,63,80,103,86,92,98,55,27,19,14,22,34,41,42,47,48,43,47,45,45,45,43,47,39,44,44,43,47,42,45,48,51,50,51,49,43,42,46,41,40,43,37,27,20,24,16,22,22,21,27,36,33,29,30,33,37,37,34,36,43,46,47,47,42,34,30,46,55,42,41,44,39,41,45,41,50,53,44,36,27,27,24,35,51,47,23,24,22,21,19,15,16,21,31,28,27,24,22,33,29,31,36,29,32,40,45,44,46,47,44,32,35,40,36,38,35,35,42,44,61,75,47,24,27,32,33,36,34,32,39,44,38,36,38,33,28,33,29,26,26,36,39,20,20,19,17,21,21,24,22,23,25,30,34,28,36,33,35,39,42,40,31,25,26,19,23,30,27,30,29,30,23,29,33,29,27,29,26,25,29,28,31,29,28,24,20,22,22,22,24,22,24,23,34,43,43,46,44,50,49,54,53,48,53,53,50,52,53,51,50,55,48,43,42,33,36,29,41,43,33,44,43,44,45,35,43,44,46,34,69,112,89,79,55,23,41,63,101,114,98,93,82,121,133,119,122,112,113,103,106,101,85,90,104,124,103,110,114,95,86,75,93,101,85,74,91,105,115,137,131,126,120,110,105,109,109,111,95,91,103,91,102,103,92,93,77,23,5,15,13,15,15,15,16,15,16,16,16,152,156,160,188,235,224,189,186,142,115,108,114,111,107,112,104,114,110,109,118,128,145,141,142,135,179,246,247,150,62,87,21,50,41,24,34,22,33,31,51,62,72,104,94,89,85,73,74,66,62,66,74,74,73,64,55,78,95,102,113,108,102,98,108,103,92,97,93,106,103,99,121,128,125,103,96,89,104,104,88,95,98,103,114,112,112,107,101,99,99,97,71,65,70,87,124,124,113,88,71,74,57,71,84,98,110,108,108,91,107,129,130,102,87,78,69,64,58,76,75,76,100,92,92,91,79,78,69,83,97,108,83,65,69,59,80,73,53,57,69,78,103,104,77,71,59,77,74,65,66,58,77,86,87,86,88,122,118,78,55,80,113,133,122,98,99,91,123,156,146,118,89,83,104,156,156,137,133,127,106,101,98,73,82,85,88,91,81,71,61,71,62,67,61,52,57,60,90,79,66,64,68,83,127,150,155,169,170,179,159,148,166,165,158,160,139,139,146,134,100,73,72,74,77,64,74,81,62,78,105,112,112,109,122,122,102,95,89,94,91,83,85,84,100,99,101,91,86,86,85,105,117,83,77,91,100,103,75,84,98,92,66,60,92,74,69,26,99,135,45,129,76,136,203,114,162,195,206,228,218,227,179,146,169,155,148,153,147,156,157,148,145,142,129,149,187,177,184,181,98,98,77,29,15,17,67,70,59,48,37,50,50,39,38,40,37,32,39,36,37,38,36,31,37,32,24,34,29,34,38,39,41,37,38,36,33,29,31,37,39,48,67,69,53,42,49,59,69,62,54,77,105,87,73,91,103,81,42,24,19,30,56,86,98,99,107,99,97,101,92,83,90,83,88,101,103,104,89,100,105,98,103,95,102,108,103,101,99,96,77,118,195,173,77,45,84,89,94,91,95,107,108,115,113,72,39,21,20,20,16,25,46,71,81,75,62,51,49,84,74,59,68,81,98,81,83,89,82,42,14,15,19,23,35,36,38,44,45,46,43,38,44,45,40,42,39,36,37,40,44,44,49,47,48,53,49,48,44,45,44,44,46,46,34,25,30,33,33,25,34,33,27,42,33,33,35,36,44,43,39,37,46,47,45,43,37,33,35,53,53,40,47,46,44,41,39,45,44,44,44,31,31,22,30,42,40,41,24,22,19,23,21,21,26,24,32,27,28,29,27,38,26,32,38,27,36,42,43,45,49,50,45,39,37,39,40,39,38,38,39,29,46,79,67,40,32,27,31,36,33,37,37,42,46,40,36,37,37,38,31,28,27,25,31,21,17,17,19,19,22,23,24,31,33,27,31,28,33,36,40,45,36,31,28,21,22,22,26,37,37,38,37,29,24,35,31,33,35,28,33,31,33,41,39,33,28,26,24,18,20,21,16,20,23,21,31,34,34,41,39,44,44,42,40,41,45,33,45,45,42,45,42,44,36,39,46,41,37,34,39,36,35,42,32,32,27,28,39,57,53,88,138,134,109,105,72,38,87,90,112,122,119,125,121,142,130,124,117,101,110,112,103,76,72,99,110,112,98,105,98,77,62,49,76,91,88,76,91,89,83,110,120,127,112,94,101,110,113,125,99,84,105,97,111,104,97,91,68,24,6,14,14,14,13,15,16,16,16,16,16,188,178,139,143,198,167,113,120,103,88,86,85,88,86,89,84,87,74,78,84,91,123,130,147,136,187,246,246,139,47,79,14,47,39,29,40,20,34,34,51,63,78,117,104,104,97,76,100,94,78,84,87,76,55,49,49,63,74,86,91,106,101,97,103,107,95,95,106,107,104,92,107,109,108,112,107,110,118,117,110,115,113,105,100,93,92,98,83,80,81,73,71,77,79,99,116,117,110,78,57,39,50,63,49,59,81,92,98,101,108,122,112,95,89,95,95,77,83,93,92,93,98,97,98,88,76,89,95,99,105,101,88,89,83,87,98,82,67,69,68,68,92,96,69,82,97,89,83,63,55,50,59,71,72,89,98,109,121,81,53,85,125,123,87,97,95,94,124,139,142,113,89,89,127,165,159,146,132,112,94,94,100,98,78,67,86,81,74,63,53,60,59,71,57,48,44,67,101,87,64,73,82,90,141,155,155,141,141,150,147,163,161,145,95,68,58,55,71,63,45,43,57,69,107,65,64,81,57,92,109,126,120,96,101,100,88,90,84,84,86,75,83,80,87,77,85,91,84,87,74,78,94,79,73,78,79,87,81,82,72,80,92,107,125,81,65,65,154,217,90,119,160,203,169,108,193,220,188,191,184,150,107,73,81,70,121,169,146,163,170,162,172,180,176,187,222,151,106,122,53,41,22,21,48,50,69,57,47,33,41,51,47,43,41,40,40,38,35,41,35,39,36,36,37,30,32,28,29,37,43,46,42,36,35,36,26,32,33,32,59,82,91,64,45,53,68,103,114,85,71,56,59,83,90,81,55,37,22,26,46,69,97,113,110,103,103,104,99,95,83,79,91,86,83,96,100,101,90,95,107,100,97,97,101,108,103,94,99,84,80,97,158,201,111,61,76,85,96,84,103,107,110,103,49,25,21,20,19,15,35,61,87,105,116,105,103,71,59,104,82,87,105,93,87,78,79,85,66,33,19,13,18,34,36,35,35,39,41,34,39,33,36,42,39,36,42,48,46,52,53,51,53,48,48,47,49,45,47,44,46,44,41,46,31,29,34,34,34,32,31,33,34,37,37,36,39,41,44,44,40,42,43,49,47,50,40,29,37,56,55,37,42,42,42,39,40,46,41,37,32,33,27,27,34,39,44,34,26,27,19,23,23,24,32,33,29,28,29,24,28,39,25,34,41,32,41,42,45,44,47,47,48,37,35,38,33,39,38,34,35,32,33,61,76,64,40,29,33,34,38,37,40,45,37,38,36,36,36,39,36,31,32,33,24,18,23,21,21,25,24,20,30,33,28,31,31,30,42,39,39,34,27,35,29,22,19,19,27,44,50,49,39,21,30,35,35,39,32,38,38,36,48,45,44,41,39,28,19,19,20,20,19,23,19,33,32,30,36,34,40,43,49,45,38,39,41,38,30,37,36,37,36,35,35,35,40,38,37,33,36,37,35,40,30,23,26,25,53,72,90,137,149,122,127,145,113,119,118,84,98,105,125,143,137,128,113,117,109,93,105,107,83,64,94,125,116,103,80,89,98,83,81,77,93,95,83,67,75,66,59,87,96,113,96,75,85,103,119,125,101,81,87,90,121,137,133,121,80,22,4,13,14,15,13,15,15,16,16,16,16,133,132,87,65,91,73,74,84,74,88,78,77,83,79,82,64,72,72,71,75,86,98,110,129,119,182,245,246,138,60,84,21,46,30,25,36,18,34,34,47,67,84,117,109,105,92,73,107,109,103,93,92,87,75,56,52,59,66,73,79,83,86,89,104,103,90,98,102,111,103,94,93,95,103,105,119,117,122,115,112,118,108,97,92,78,87,84,78,78,64,72,90,103,94,107,99,85,100,72,64,67,71,79,63,64,77,81,93,97,102,104,91,83,88,100,103,100,93,109,115,101,101,90,76,63,63,85,95,99,82,78,73,87,91,81,99,89,78,71,67,65,91,96,89,94,96,97,85,77,59,56,65,66,98,95,88,87,92,97,87,112,120,120,121,107,99,102,117,118,127,131,109,118,141,157,157,153,133,123,99,95,101,96,106,68,87,83,69,71,66,75,61,66,71,49,53,60,63,68,75,101,105,83,91,108,98,70,66,92,110,125,120,92,54,37,20,28,32,27,33,26,67,77,149,144,71,74,107,130,139,134,136,111,89,94,87,92,97,100,97,84,78,90,75,61,79,76,85,76,77,70,79,88,62,55,52,62,77,66,44,51,91,125,110,71,70,88,159,190,118,148,213,226,129,131,240,232,199,133,97,129,76,10,11,8,90,151,124,145,150,159,169,168,164,168,184,103,52,57,19,18,35,61,68,47,47,47,46,42,44,46,43,46,44,43,38,36,39,36,33,34,39,39,31,30,35,34,38,45,36,39,40,38,30,26,34,30,31,36,76,105,89,69,52,41,72,118,132,113,115,87,88,110,91,49,28,26,36,58,87,108,107,110,105,98,105,105,110,101,86,93,96,88,97,97,89,101,97,90,95,98,103,97,88,97,99,93,91,83,81,74,114,200,160,77,74,94,103,97,114,116,75,59,21,19,20,17,28,48,73,99,110,108,110,122,127,118,83,79,97,112,100,84,83,77,92,92,54,26,16,15,16,32,35,31,35,32,36,36,36,42,39,32,41,49,44,53,49,52,54,49,53,46,50,45,46,50,43,47,43,45,42,41,32,27,32,27,24,24,26,22,33,44,35,34,37,35,42,46,46,47,45,45,48,45,37,29,40,57,50,39,32,29,35,33,39,37,27,27,24,27,29,36,45,43,38,30,22,23,23,27,26,24,30,27,27,24,27,38,42,39,43,50,41,41,43,38,44,42,39,41,40,35,41,36,31,32,30,25,30,30,29,34,66,84,51,31,30,31,34,40,38,37,39,31,38,39,30,32,34,24,28,33,25,18,27,27,24,27,28,33,29,30,32,35,33,39,43,39,33,23,29,33,24,29,23,18,31,46,49,44,31,21,21,34,34,33,33,31,31,36,49,48,44,41,36,27,18,26,25,24,26,25,27,33,41,35,32,36,32,38,50,52,48,44,46,41,36,34,39,36,30,35,32,34,34,32,37,31,33,39,32,34,27,23,23,26,49,74,101,125,118,115,124,134,132,122,129,108,105,109,128,139,124,107,106,121,107,86,100,96,76,80,106,123,115,104,86,106,123,116,124,103,103,76,54,61,68,55,45,57,69,76,74,70,81,99,111,122,105,90,89,91,133,159,161,147,91,17,3,12,12,15,14,15,14,15,16,16,16,58,59,41,36,43,54,72,89,87,86,89,89,77,71,70,66,78,70,81,87,88,100,98,107,102,179,244,245,135,66,97,13,46,27,19,35,18,38,36,45,65,85,114,99,90,75,65,88,105,96,80,86,98,96,90,69,60,59,53,61,67,76,83,94,100,87,95,106,109,101,93,96,97,102,101,92,90,92,79,83,101,105,107,107,88,81,83,74,81,77,75,96,112,99,107,81,66,87,83,95,97,95,102,89,92,97,102,98,97,87,81,77,68,74,79,78,91,115,121,124,114,109,105,96,81,66,77,85,79,69,83,87,84,78,64,86,104,93,89,63,65,87,97,84,76,96,109,110,82,72,72,81,107,122,111,77,70,92,108,121,125,128,140,134,105,92,104,107,96,108,136,142,146,152,152,150,152,155,144,109,83,77,111,99,71,89,75,61,66,69,76,74,68,72,68,63,60,63,72,69,83,95,67,63,53,49,46,37,47,72,108,104,89,71,45,37,38,49,47,49,71,89,90,173,134,57,81,102,141,119,107,117,96,101,103,112,113,115,116,100,93,92,84,78,71,84,75,74,77,62,60,65,89,74,60,46,41,59,56,39,40,69,91,83,69,84,82,80,127,171,237,243,156,92,179,252,229,146,35,69,149,83,25,26,24,95,125,64,53,55,66,84,74,75,68,71,50,23,40,25,45,69,62,56,39,41,44,50,48,46,49,50,49,49,45,37,42,37,36,35,37,38,33,35,36,38,41,42,44,37,34,38,39,36,32,36,33,33,45,83,100,89,69,57,42,41,87,120,137,140,134,132,82,38,24,28,46,73,101,111,113,108,102,97,101,101,100,101,99,97,99,106,103,105,103,91,104,100,98,99,97,104,93,89,94,93,89,96,90,83,80,87,180,190,103,73,91,108,111,107,53,23,23,12,23,21,38,62,89,110,108,109,107,115,113,123,99,89,106,98,94,86,81,82,79,83,85,49,22,15,15,23,33,39,43,46,42,44,43,44,46,36,33,39,45,43,47,49,49,49,47,45,43,51,46,42,45,44,42,39,39,40,36,26,31,34,26,18,19,17,19,38,39,37,36,29,29,41,43,44,42,40,40,43,42,31,28,43,57,51,42,32,23,40,45,41,30,23,27,24,24,31,39,36,43,41,24,22,24,20,23,20,19,23,20,27,18,27,38,44,45,33,44,39,42,39,39,44,46,41,34,42,35,43,35,27,31,25,27,33,31,36,33,41,80,81,46,27,27,29,32,34,38,35,34,36,36,30,29,34,30,33,28,18,21,24,26,22,27,23,25,24,27,38,37,34,37,34,26,29,29,38,38,24,24,28,31,40,51,45,39,27,20,23,21,21,26,22,24,26,38,48,45,42,39,34,23,19,22,28,27,27,25,31,33,39,45,39,38,31,28,39,44,51,54,50,51,47,46,46,38,34,39,33,33,33,32,33,31,32,31,36,34,25,19,18,36,51,65,83,87,91,94,105,104,92,111,105,109,111,97,117,118,100,91,92,102,87,70,86,106,101,91,100,111,108,103,93,105,121,120,127,100,85,54,45,77,83,56,27,40,45,61,77,83,93,103,121,122,117,122,105,104,146,171,167,147,94,17,3,12,12,15,14,15,14,15,17,16,16,56,54,47,43,47,48,74,85,75,89,93,88,71,69,78,72,81,85,94,93,105,110,111,116,104,185,242,242,124,58,72,10,46,31,24,33,23,32,36,44,66,83,101,95,80,70,62,77,92,95,65,71,76,78,92,79,71,57,57,60,54,66,80,87,89,87,96,104,107,95,99,113,105,97,84,69,63,74,74,79,94,114,125,122,94,87,96,87,99,97,82,108,118,102,101,74,76,105,96,98,99,98,106,99,84,100,103,102,89,71,77,63,63,68,46,55,89,109,128,133,124,134,133,141,129,105,99,93,83,81,103,100,98,86,63,92,111,102,81,63,60,87,98,91,91,97,113,112,78,63,71,94,111,117,94,70,89,109,121,106,109,111,119,121,82,87,97,79,74,83,112,136,141,144,139,129,137,144,141,99,71,75,115,129,71,82,60,49,53,58,64,73,76,75,64,74,101,106,94,64,69,95,66,56,73,80,65,49,59,99,132,120,116,98,99,87,77,86,75,104,116,117,90,113,113,68,92,118,111,100,92,91,91,93,97,99,110,96,88,87,89,86,87,61,77,84,69,83,74,71,60,61,78,63,73,60,42,56,59,57,48,42,61,56,44,69,54,86,186,239,241,150,65,92,172,243,189,80,8,29,114,107,102,103,99,124,72,11,10,12,13,17,17,20,14,31,43,34,50,62,69,54,52,51,44,34,45,51,47,53,48,51,50,45,41,38,43,34,33,39,33,33,39,39,41,43,46,45,37,36,33,32,36,36,43,41,35,42,46,71,89,83,68,55,49,42,47,81,141,147,108,65,26,20,34,60,89,101,105,110,102,97,100,94,98,98,93,98,92,88,83,97,100,104,103,96,103,104,102,103,96,100,97,91,99,111,101,98,108,105,96,89,152,210,141,84,92,107,78,38,21,19,16,16,26,51,72,96,109,104,108,111,111,107,105,98,97,100,94,81,84,78,78,80,74,88,75,39,19,15,14,32,40,46,48,43,49,46,45,45,40,38,38,45,45,39,46,43,44,46,39,41,44,40,39,38,32,36,40,33,36,36,32,29,32,32,15,19,19,17,21,34,36,27,31,26,37,31,28,35,33,32,25,27,31,28,30,45,51,43,40,34,32,36,29,32,33,27,26,25,32,28,29,41,42,39,26,21,25,19,21,18,18,21,21,21,21,32,34,39,32,29,39,38,45,40,43,49,43,38,34,37,34,30,32,31,31,37,36,32,35,39,35,33,63,97,73,34,31,29,29,34,32,34,31,31,33,31,36,34,31,29,22,20,21,18,23,20,22,21,24,33,29,34,35,34,31,24,25,26,40,44,32,25,27,34,43,49,48,42,38,27,16,23,25,19,23,21,24,29,37,42,43,48,42,29,18,22,24,24,25,21,21,29,29,37,39,39,42,39,30,27,29,42,50,53,53,54,51,49,40,39,44,40,40,37,35,36,35,38,37,33,31,24,21,17,37,50,52,60,62,77,77,77,82,83,79,74,87,104,103,112,99,71,66,79,89,69,73,114,131,120,103,102,118,101,91,72,61,67,72,97,81,65,49,39,65,52,41,32,40,88,94,94,94,99,108,110,113,115,126,115,111,136,148,137,115,78,21,5,13,13,16,15,14,15,16,16,16,16,79,90,77,64,54,69,79,81,85,87,100,87,65,61,67,82,97,104,110,106,125,130,120,130,125,196,243,243,117,48,68,8,51,29,26,36,22,31,35,50,66,86,92,96,84,67,65,71,94,87,77,56,39,51,65,73,78,74,66,72,64,70,82,95,110,84,89,104,106,105,105,111,99,90,84,75,84,97,87,99,113,128,140,116,108,112,109,107,122,139,106,112,127,94,95,79,102,117,90,87,100,102,128,131,83,72,89,103,94,79,87,84,87,96,77,67,100,128,136,137,132,142,130,147,150,134,133,128,127,114,120,106,109,137,103,106,123,98,94,87,96,113,126,114,109,95,130,164,86,73,69,84,109,90,83,70,67,93,96,86,93,91,112,107,84,103,99,88,98,96,103,114,126,134,131,127,123,122,112,94,85,78,126,153,111,84,77,61,52,53,55,51,59,80,59,74,114,116,110,85,79,100,87,119,128,106,104,78,78,97,120,124,129,140,135,132,109,107,119,120,122,113,84,97,104,114,139,124,119,116,108,101,91,93,76,66,57,78,92,79,76,77,92,79,74,79,74,99,89,81,83,58,61,58,82,86,74,81,73,73,59,53,69,54,53,60,41,142,251,241,144,45,30,45,80,163,125,29,2,25,76,98,120,117,106,114,88,53,79,73,41,41,36,75,77,61,57,57,92,76,53,44,42,48,44,44,44,49,51,53,47,50,52,39,43,39,36,36,32,37,36,40,42,42,48,45,45,42,31,36,37,36,37,42,47,47,42,47,61,77,87,78,64,57,54,53,39,51,100,88,45,28,23,45,72,95,101,98,100,97,97,93,97,98,91,96,97,104,98,74,69,78,94,99,96,97,99,100,101,101,103,98,93,105,127,137,89,77,105,152,128,57,91,177,184,108,61,42,24,22,13,19,20,31,64,86,107,102,112,117,109,108,102,100,99,108,94,86,83,74,79,74,73,81,86,81,66,36,16,20,16,33,41,39,40,37,36,39,38,37,42,36,37,42,36,39,42,46,41,39,42,41,37,30,28,34,35,34,35,33,36,35,29,33,46,38,18,16,18,18,27,32,29,33,32,33,31,27,32,27,29,29,29,31,33,39,45,43,45,44,42,43,43,39,33,39,37,33,30,36,39,27,32,37,43,36,19,21,23,19,20,18,21,21,26,29,27,35,36,33,29,30,39,37,42,39,34,39,33,27,29,30,24,23,31,29,31,32,36,33,27,29,27,29,39,68,85,61,32,29,29,32,38,32,31,29,31,35,34,32,33,28,18,22,22,17,19,22,20,23,26,25,32,29,30,29,23,24,21,35,47,40,38,34,34,45,47,53,47,40,34,22,19,21,25,19,24,23,22,36,39,42,46,45,37,26,24,22,16,21,24,20,23,23,35,39,38,45,42,39,34,30,23,29,35,41,46,50,49,51,47,42,44,46,50,44,44,39,43,37,35,36,29,26,24,21,33,44,42,51,62,66,59,59,67,74,72,49,70,108,115,112,92,60,68,84,86,96,101,110,130,135,121,112,110,96,87,67,47,42,50,72,64,52,49,41,37,42,39,31,75,121,118,93,98,113,106,98,84,87,101,100,97,102,97,87,83,66,23,7,13,13,16,15,15,15,16,16,16,16,87,103,105,88,86,96,97,92,90,96,101,83,49,53,69,74,92,97,101,108,134,135,127,137,133,200,243,243,103,53,68,10,50,24,29,27,27,34,37,50,72,86,87,75,66,62,66,72,91,100,91,81,34,30,43,59,72,67,70,77,76,71,81,103,139,109,81,98,116,110,110,113,97,101,97,94,110,119,118,122,121,134,136,113,114,111,108,100,129,157,104,107,112,93,78,62,102,106,88,85,91,100,161,184,75,48,78,125,122,81,99,91,112,127,104,104,127,134,139,117,109,139,87,120,154,142,147,143,146,128,123,96,128,187,130,111,125,108,109,111,119,129,113,104,100,80,151,194,76,61,80,97,115,92,89,77,61,63,87,117,177,159,113,112,120,154,152,132,140,151,139,141,151,160,160,158,154,134,138,111,90,89,110,141,122,113,92,68,57,54,55,57,46,63,77,92,110,96,83,78,82,94,95,147,130,128,140,124,108,103,117,130,131,131,130,126,127,122,123,131,127,111,84,99,125,112,123,122,105,115,118,103,98,107,104,87,84,100,91,80,69,81,101,86,71,71,79,92,88,80,70,56,66,68,60,98,120,89,63,59,51,77,113,78,75,76,18,97,187,200,178,32,2,43,39,82,54,7,13,51,89,87,99,95,89,102,93,102,109,103,99,84,67,153,125,112,105,88,89,50,38,37,39,45,43,42,42,45,50,56,53,52,46,39,39,32,39,39,34,37,39,37,46,50,45,39,39,40,40,39,31,40,43,42,49,48,49,63,86,92,92,80,57,49,55,53,51,49,53,49,35,40,54,88,93,108,101,97,96,91,98,98,93,91,95,96,102,101,101,94,75,85,93,97,96,98,101,100,99,101,98,104,121,139,121,113,53,37,95,138,81,21,17,113,177,93,41,18,12,18,16,17,39,71,90,104,109,111,113,112,105,103,99,104,106,91,74,66,70,73,75,69,76,79,84,89,59,27,18,15,18,34,37,38,42,39,38,39,39,37,33,34,41,37,37,36,39,39,42,46,35,28,32,30,27,34,34,34,38,33,34,30,23,46,57,46,34,29,22,25,31,31,35,39,37,37,38,33,37,32,25,33,35,38,44,41,40,42,40,42,45,46,46,46,44,45,42,39,46,44,44,35,32,39,45,31,19,23,19,24,25,22,23,30,30,23,34,31,37,35,25,31,29,29,28,34,26,25,27,21,24,24,22,29,29,27,24,24,26,27,32,24,22,20,24,36,65,83,52,24,33,32,32,33,29,36,30,33,34,29,32,31,17,19,19,18,21,16,21,17,27,32,23,32,26,20,19,19,25,46,48,44,43,39,42,46,43,51,41,39,32,23,24,22,24,23,27,25,24,31,36,42,47,45,34,25,18,23,23,21,20,22,21,27,38,37,39,41,44,40,39,36,27,21,27,31,37,46,45,47,50,49,47,44,45,47,46,46,44,43,46,39,32,19,20,29,33,41,43,54,59,53,58,48,60,83,93,77,62,105,110,106,94,58,70,77,94,112,92,90,99,124,111,95,105,111,124,118,114,107,102,103,89,92,87,84,95,86,92,81,109,152,121,107,118,131,117,101,97,96,107,104,103,90,84,90,100,83,22,7,14,12,15,15,16,15,15,16,16,16,89,117,112,103,110,122,114,105,104,104,111,90,57,44,48,49,66,74,87,104,139,134,121,139,132,197,240,240,103,57,54,9,49,24,32,27,22,35,35,54,80,104,75,55,44,42,57,64,87,84,124,123,46,30,39,53,65,67,66,55,54,61,60,96,179,120,77,108,131,129,105,115,105,112,110,101,120,127,116,124,102,108,129,82,87,84,69,74,110,153,101,83,85,71,69,61,88,91,79,69,81,81,158,192,69,49,86,145,125,67,66,63,85,100,106,110,118,116,120,89,94,127,53,78,142,143,134,116,114,104,112,84,117,200,121,83,104,98,101,85,92,95,89,66,73,63,135,182,54,61,84,107,118,83,124,188,148,100,110,159,237,171,130,135,149,197,181,146,146,165,184,179,178,201,205,205,190,160,152,126,100,93,115,122,97,95,83,53,62,73,70,61,45,57,67,99,113,84,75,71,83,96,90,116,127,133,146,132,128,122,124,127,120,119,116,119,125,119,123,128,123,109,101,111,122,111,105,111,104,103,105,103,123,137,140,128,106,110,92,80,72,81,103,87,81,77,86,89,83,90,83,65,84,76,53,89,116,106,89,52,32,59,107,105,111,76,22,34,49,142,156,24,12,80,105,98,37,16,69,103,113,108,98,98,95,93,102,95,108,103,108,95,90,134,102,98,89,39,39,45,42,38,47,45,43,46,51,52,52,60,55,46,46,39,44,37,36,39,35,38,44,46,47,45,41,41,42,36,37,41,40,40,44,44,46,58,62,74,93,96,99,83,65,54,49,53,55,51,49,45,60,88,112,117,102,106,101,90,93,101,100,93,91,98,94,98,102,99,103,98,106,103,98,98,102,105,101,101,100,101,108,125,134,128,96,52,34,44,42,57,50,35,17,40,125,116,65,24,6,17,23,49,73,92,108,106,109,97,110,108,90,96,98,98,83,72,63,63,66,71,74,69,80,83,88,80,49,23,16,16,21,37,36,39,41,36,35,35,38,37,37,37,36,39,32,35,39,39,43,38,34,30,33,35,28,30,35,31,34,31,32,27,29,46,50,39,29,33,19,24,33,30,38,37,39,47,44,36,34,31,36,34,35,45,44,45,34,32,33,38,44,45,49,45,47,44,44,46,47,42,42,42,39,38,36,27,21,26,29,28,32,30,28,29,28,21,24,30,23,29,28,23,24,22,28,30,22,27,28,26,26,22,24,29,29,22,19,24,26,20,23,24,21,26,24,23,42,83,77,42,27,24,31,31,34,36,33,33,31,37,30,24,21,23,22,21,23,19,21,23,30,28,22,27,30,21,18,23,33,46,48,44,46,45,44,45,40,42,39,35,34,23,20,28,30,30,33,31,31,40,40,40,47,42,29,25,21,24,20,18,20,21,27,31,38,38,34,41,43,45,45,42,31,25,26,23,26,31,40,43,46,50,44,48,43,46,49,44,47,45,43,45,30,21,23,25,37,42,46,53,52,52,51,52,67,92,112,92,72,88,85,85,81,55,50,67,90,87,89,61,52,84,90,98,127,147,159,169,170,167,159,156,152,154,158,153,153,156,157,144,157,162,141,140,154,149,135,139,137,136,137,136,132,120,131,127,143,107,13,4,11,12,15,13,15,13,15,16,16,15,89,105,102,98,118,133,134,131,126,127,135,129,87,65,51,27,42,67,89,105,141,136,114,128,132,200,241,241,81,45,45,4,44,22,31,29,29,40,37,55,94,137,124,96,59,39,68,67,85,94,150,155,83,77,58,56,64,74,85,47,32,47,59,99,179,120,78,107,134,115,94,107,95,103,99,96,106,95,84,82,65,103,125,60,61,63,58,60,107,160,111,96,89,84,93,97,115,103,96,89,98,97,168,192,73,61,90,147,125,63,74,74,96,99,104,106,106,108,102,89,120,173,71,52,99,108,106,95,95,88,100,86,122,169,97,83,92,92,102,87,89,102,90,78,101,95,182,210,84,85,90,107,116,104,188,252,221,116,113,155,165,144,142,141,158,153,123,120,125,146,160,159,153,170,172,152,128,90,93,92,79,88,81,76,59,51,47,56,61,66,55,56,50,55,41,69,81,76,81,72,71,70,53,78,83,101,122,114,113,116,120,118,95,99,113,117,120,121,116,104,98,100,110,113,125,138,130,136,136,122,132,132,134,143,141,119,109,122,116,104,84,77,80,79,79,79,89,78,81,80,73,62,75,86,61,122,143,122,116,82,51,83,127,122,113,78,72,78,43,66,133,59,24,115,147,139,101,96,117,126,125,108,114,106,108,114,107,128,124,132,126,106,103,100,69,49,45,34,38,47,53,48,46,53,52,57,57,50,55,57,53,59,50,42,41,34,41,38,45,47,43,42,34,39,40,35,36,37,38,44,43,39,42,50,67,85,77,62,72,85,102,130,119,71,48,51,53,51,55,49,66,118,128,116,101,93,88,87,92,87,94,90,92,97,98,98,92,100,102,105,104,101,94,101,99,104,104,96,96,108,111,94,69,53,60,30,36,43,34,37,40,46,17,69,152,117,92,39,12,30,45,78,98,110,109,91,93,92,83,86,83,84,81,75,66,64,65,61,66,67,79,76,81,86,87,75,42,21,20,16,34,38,36,36,39,41,32,36,38,41,38,37,37,33,41,41,43,36,34,37,29,30,30,27,33,38,31,27,32,28,27,31,36,50,35,22,24,22,19,23,32,37,37,44,38,39,45,39,43,36,44,47,39,44,44,41,29,27,27,30,43,44,44,47,42,41,46,42,45,47,42,44,40,39,39,29,26,24,20,21,22,21,26,24,33,28,27,33,29,32,31,31,36,33,34,34,34,31,26,30,33,25,24,31,23,22,20,21,27,19,25,22,22,24,20,22,27,58,84,67,40,27,26,36,29,30,36,30,30,34,33,20,21,23,22,27,27,24,28,26,29,33,26,31,29,20,19,25,42,44,35,42,45,40,44,42,41,42,42,34,30,29,29,32,32,33,36,34,36,38,38,40,39,33,26,29,23,24,22,21,27,24,35,33,31,39,38,40,39,39,42,37,38,40,24,22,28,21,31,36,36,46,44,49,48,42,50,48,46,48,48,37,29,21,19,27,42,48,54,59,57,49,47,48,57,63,69,71,51,67,64,66,69,55,48,40,46,57,71,50,25,38,52,103,170,174,178,188,188,190,197,208,199,192,192,190,194,190,191,176,177,182,171,180,170,162,160,168,172,162,169,160,157,158,163,158,163,110,12,2,10,11,15,12,15,15,15,16,16,15,80,91,90,92,109,140,148,150,139,130,153,163,155,139,115,49,42,80,93,108,147,131,105,114,120,199,241,241,73,54,46,8,48,17,36,29,23,33,37,54,97,169,199,209,150,90,101,102,141,183,233,231,167,134,106,83,74,91,122,104,68,72,81,128,207,135,89,100,115,110,76,96,94,102,107,100,103,91,80,84,83,137,171,93,69,74,90,84,116,175,149,147,152,151,159,162,162,157,165,158,174,161,214,216,111,97,102,152,145,134,154,151,162,158,159,156,159,152,152,155,188,229,136,70,56,75,85,83,92,73,87,75,112,160,135,147,153,156,158,154,161,158,157,148,180,181,232,249,154,134,106,125,127,100,173,240,172,107,114,120,123,93,105,95,101,102,60,61,69,79,71,53,46,48,44,31,17,10,12,12,14,14,13,14,13,13,14,15,14,14,14,14,15,15,14,13,14,14,17,20,21,31,20,14,17,40,77,88,103,101,102,98,94,110,121,125,121,118,105,105,107,100,126,117,125,159,155,153,142,141,145,134,127,131,135,120,128,140,131,118,93,81,72,66,67,82,89,77,65,48,40,42,75,76,59,139,151,111,104,91,110,133,151,117,97,98,112,122,81,87,155,103,44,111,134,118,112,117,126,109,116,116,108,115,114,110,120,121,128,134,125,114,116,110,62,65,92,79,68,56,62,57,48,53,54,51,55,57,53,57,53,61,51,41,44,45,53,50,49,41,37,45,39,38,32,31,37,41,46,41,46,47,69,105,109,111,97,84,63,87,139,157,145,67,41,45,48,59,56,50,54,87,121,117,94,84,79,78,84,84,88,87,84,98,91,93,92,96,104,98,93,92,99,100,107,103,96,100,97,92,59,32,31,32,37,34,31,36,32,39,41,39,33,152,216,132,104,51,26,54,74,106,111,98,89,79,73,60,61,71,80,72,66,67,66,66,63,72,73,75,90,81,87,92,77,52,19,21,19,21,31,38,42,34,41,40,46,46,38,37,40,38,33,39,41,41,36,35,32,28,31,30,31,27,31,35,29,32,33,28,29,29,46,47,24,22,22,16,22,26,31,37,39,40,41,41,41,44,45,43,45,40,39,43,46,43,34,37,32,32,34,38,47,44,43,41,45,47,39,43,42,39,42,41,38,24,22,20,21,26,17,21,28,28,35,31,37,38,37,39,33,36,41,39,39,36,38,41,33,32,31,28,35,32,32,28,21,24,21,22,27,23,23,20,24,23,22,36,65,84,61,30,26,33,34,28,33,35,35,35,30,21,20,26,24,19,20,24,26,26,29,28,33,27,19,21,21,30,39,41,40,42,39,39,42,43,39,41,43,32,33,29,24,26,26,30,32,28,36,41,38,38,38,32,23,24,23,22,23,29,24,29,31,31,34,36,38,40,41,41,41,37,34,33,30,24,21,26,23,27,29,34,40,44,51,50,50,51,48,50,56,42,23,22,21,31,50,60,62,67,55,51,51,44,51,48,45,46,44,47,50,58,57,57,53,53,63,65,96,79,39,22,23,120,196,194,205,205,206,217,229,238,220,206,213,212,214,217,212,199,200,202,199,198,190,187,186,199,199,194,203,198,188,180,188,184,193,115,7,2,8,11,14,13,15,13,15,15,15,15,82,90,83,97,102,130,139,138,130,130,160,194,241,250,223,112,79,105,100,102,141,130,105,110,116,193,244,243,87,110,81,12,51,22,32,29,25,36,34,47,79,155,218,250,217,125,140,136,213,247,252,252,185,167,147,139,137,142,178,157,138,152,155,188,246,184,120,110,133,132,117,134,135,147,149,145,152,150,141,155,160,206,235,154,127,162,205,162,157,179,176,194,203,196,195,194,193,203,207,212,213,188,199,186,152,148,136,170,185,195,209,203,206,203,204,201,196,197,204,194,191,194,164,131,74,66,71,74,68,58,71,86,136,179,186,206,202,206,208,199,199,206,193,197,214,195,200,185,174,168,106,120,107,65,92,129,136,110,93,93,64,21,11,7,22,28,13,23,31,38,44,45,49,133,79,60,33,16,15,15,14,14,13,14,14,13,15,14,14,14,13,13,14,14,13,14,13,13,14,14,15,18,20,18,15,16,38,67,81,85,92,118,123,129,133,125,125,107,89,103,108,117,146,137,132,154,150,137,124,117,117,111,112,105,121,134,129,126,118,113,107,115,101,78,79,95,94,75,71,60,42,48,78,79,47,89,111,110,107,88,109,131,136,111,89,89,105,89,76,68,154,153,51,88,96,66,64,72,98,98,92,92,102,99,92,92,87,93,80,92,95,90,87,84,59,66,113,120,116,101,105,86,57,47,43,50,49,53,46,44,51,55,47,47,50,48,51,50,41,39,44,41,35,33,34,38,37,41,45,47,57,80,137,150,114,99,96,119,108,117,138,107,60,27,35,47,48,54,57,55,44,57,81,97,91,81,75,72,84,83,89,83,88,90,91,93,88,97,95,96,93,95,106,107,101,97,100,96,88,77,64,41,31,32,32,35,33,31,35,35,35,37,34,162,183,118,136,51,42,83,101,114,78,67,73,64,62,63,64,73,71,63,62,67,70,76,71,70,90,104,96,102,95,65,38,23,17,15,17,22,36,41,45,35,36,41,45,48,41,38,37,39,36,36,40,34,32,31,32,29,33,29,27,31,28,35,32,30,28,32,31,27,49,36,17,25,17,18,19,25,36,36,43,39,41,43,42,40,44,41,41,46,40,42,40,37,39,41,39,36,35,44,46,43,43,47,46,38,45,43,39,44,41,38,39,24,20,24,14,21,21,21,23,31,41,36,36,39,37,36,37,37,41,35,40,37,35,38,38,36,36,34,33,31,30,25,23,28,22,19,27,24,22,23,24,22,21,27,41,73,81,54,26,24,33,33,33,33,39,35,27,19,19,22,19,21,22,21,24,24,29,33,24,26,19,29,31,33,44,36,39,38,44,41,41,42,37,41,39,39,41,31,29,30,24,29,29,28,34,42,40,39,37,29,23,24,23,24,23,18,22,25,31,33,36,41,40,37,39,43,34,40,41,39,38,25,29,23,24,27,25,25,34,34,46,50,49,50,50,50,53,44,24,19,20,38,65,76,73,57,53,52,55,54,48,40,35,44,39,46,45,42,45,57,76,95,108,113,147,105,63,36,53,176,213,208,217,206,216,226,228,225,208,207,214,208,210,218,217,205,202,202,204,206,203,203,204,216,220,215,226,217,208,205,207,213,216,113,5,2,8,11,12,12,15,13,15,15,15,15,73,89,78,90,94,117,125,127,124,130,189,237,249,249,250,160,116,128,117,124,146,151,159,160,141,198,247,242,104,169,126,31,53,14,32,27,25,32,35,53,69,105,155,238,209,141,159,152,229,252,247,221,173,177,179,194,192,194,201,195,194,201,191,201,228,188,156,147,160,184,183,190,190,192,200,196,196,194,195,200,193,210,212,183,201,243,252,235,199,208,197,203,202,194,206,225,218,198,208,195,190,128,92,97,129,183,175,189,192,199,209,200,201,195,196,196,191,191,188,170,105,81,130,172,124,78,59,59,63,54,85,124,168,194,203,206,205,207,196,189,193,189,200,196,199,148,87,85,137,176,113,94,83,65,83,122,137,102,95,81,36,15,24,24,57,84,110,155,179,213,242,249,253,253,249,237,227,227,224,224,217,214,212,210,210,204,200,205,211,202,196,199,194,191,180,173,170,166,166,156,160,165,174,171,128,112,97,67,80,86,102,123,127,109,107,122,113,105,88,81,87,95,139,141,134,144,121,119,111,96,103,95,102,103,121,131,111,108,126,133,125,131,122,104,90,96,84,68,71,71,73,77,93,74,47,63,83,100,88,64,86,117,121,89,73,73,63,57,53,50,126,163,61,45,69,34,22,32,59,65,69,81,84,81,73,73,76,65,56,55,56,58,53,56,42,36,43,70,102,98,113,116,104,92,76,84,96,87,70,64,56,50,42,50,49,41,43,38,46,39,39,41,34,39,39,44,43,42,50,54,72,83,141,145,96,103,105,137,135,108,60,20,24,27,66,64,54,55,51,60,54,46,46,55,65,67,71,83,91,90,95,92,93,95,93,99,97,97,99,97,90,101,106,95,106,95,83,82,79,95,97,80,47,30,31,35,34,32,32,32,31,42,29,78,91,76,136,65,33,62,60,66,51,57,60,57,72,73,74,75,66,50,61,71,71,76,71,81,93,92,95,84,53,30,19,21,14,17,23,31,42,39,39,38,39,37,38,39,45,38,36,42,39,39,35,33,36,29,26,33,35,30,34,34,31,31,31,32,29,33,31,36,32,20,21,24,19,16,18,24,35,36,38,39,39,39,39,38,44,42,39,42,41,39,39,39,42,45,40,43,42,42,45,42,45,44,43,43,44,41,36,41,44,38,34,24,17,19,22,17,16,18,26,37,39,37,42,41,37,38,36,39,39,39,37,38,37,36,38,37,32,29,29,29,25,28,24,29,22,28,33,22,27,27,22,25,26,29,29,46,78,69,40,22,29,33,33,35,33,33,21,15,22,19,19,24,19,21,20,24,35,27,24,25,22,21,27,37,39,39,36,39,39,39,48,44,40,40,39,45,38,35,36,29,33,28,29,35,39,43,36,38,37,28,25,20,20,22,20,21,22,23,29,37,34,38,36,39,42,37,41,39,43,40,38,33,30,25,22,25,19,25,33,29,33,39,44,42,44,53,50,40,21,25,24,44,90,97,95,85,87,99,99,83,79,78,84,89,95,79,37,32,36,50,62,83,98,103,128,105,90,66,136,229,213,211,213,208,221,221,201,198,199,208,214,193,193,208,204,199,192,198,211,206,207,206,205,218,218,218,225,219,208,205,219,225,222,113,5,2,8,12,13,13,14,13,15,16,15,15,66,79,75,106,104,121,127,129,131,137,204,240,249,249,250,139,105,148,152,160,174,201,245,245,196,214,250,226,105,193,126,22,45,14,35,26,24,36,29,52,72,116,132,147,148,130,160,144,179,217,183,156,154,181,180,190,199,198,200,194,194,192,168,118,106,138,178,185,194,202,201,208,198,197,194,191,192,193,192,188,164,85,103,144,223,251,252,234,189,201,177,182,185,188,226,250,209,190,187,174,129,41,24,22,80,169,200,213,192,191,188,187,188,182,187,178,184,176,165,110,40,36,73,158,168,108,58,60,74,92,128,157,189,197,197,196,190,191,184,179,177,192,194,184,161,77,50,50,92,165,148,117,89,89,100,132,148,118,112,169,231,243,252,252,252,252,252,252,253,253,252,252,252,252,252,252,252,252,252,252,253,253,252,252,253,253,253,253,252,252,253,253,253,253,253,253,253,253,252,252,253,253,253,253,252,252,229,168,112,98,101,117,110,89,96,112,110,106,109,92,64,78,111,125,131,127,110,109,119,117,98,119,134,110,127,131,112,131,143,134,110,110,123,105,92,81,59,59,57,79,90,81,77,54,46,69,76,71,68,48,75,103,105,94,76,77,86,67,58,44,96,168,78,23,33,26,41,19,32,56,66,81,63,62,61,49,62,71,71,55,47,50,40,53,44,35,36,37,62,77,89,110,134,130,113,131,158,159,148,134,78,30,34,45,68,47,48,42,45,43,40,41,44,42,41,43,50,64,81,95,74,48,119,137,108,128,120,112,65,28,20,20,36,70,117,105,73,53,50,55,48,39,29,38,58,78,91,93,93,92,97,98,101,104,106,96,96,104,98,101,96,103,103,105,92,75,70,79,87,100,113,113,91,51,34,34,32,35,31,34,33,33,33,53,45,39,85,54,31,29,32,52,51,56,53,70,80,81,77,71,71,68,67,72,76,74,74,84,83,77,62,42,23,17,21,15,19,24,43,49,41,43,37,41,42,35,34,36,35,37,43,38,39,34,34,33,28,29,29,32,30,35,34,31,33,33,32,26,34,33,29,37,25,20,24,17,21,21,19,29,35,36,34,38,37,38,36,36,47,39,41,43,43,42,41,41,37,42,41,39,43,43,42,39,43,48,39,43,42,41,47,43,39,35,27,21,22,17,22,21,15,26,30,35,38,39,39,37,37,34,41,38,35,39,36,38,35,40,35,32,34,23,23,29,30,29,33,34,40,36,33,33,37,35,30,37,33,29,29,28,57,81,66,38,24,25,29,30,35,27,18,21,19,17,17,19,21,19,23,28,24,26,25,22,18,18,37,41,39,38,39,35,38,36,39,36,41,40,35,41,38,40,38,30,28,31,35,38,37,39,40,36,33,25,19,20,18,21,21,19,20,21,30,34,27,33,34,28,32,31,36,39,34,35,33,33,33,29,25,22,24,23,22,27,29,34,37,42,43,47,45,40,26,61,153,171,147,129,118,122,141,146,139,141,137,143,157,156,160,148,107,86,58,51,55,68,74,80,113,113,98,113,197,230,207,211,205,208,218,200,185,191,200,211,203,183,186,199,200,199,196,202,204,202,207,204,200,210,208,205,216,201,193,202,214,214,208,114,5,0,8,11,13,12,13,12,15,15,14,15,62,82,72,118,123,124,141,137,148,151,195,239,245,245,236,114,110,145,161,182,201,243,252,252,247,240,252,220,108,165,74,13,39,14,32,23,26,33,35,53,70,112,105,77,66,82,134,128,117,137,141,146,177,179,171,181,184,190,182,179,171,166,100,22,11,59,155,199,209,199,180,178,177,169,164,164,167,178,171,160,73,1,10,55,178,246,248,214,166,152,142,169,174,185,210,212,186,181,179,139,53,9,17,20,36,104,182,217,201,184,181,184,182,181,180,183,185,174,124,68,40,45,61,103,167,155,89,64,81,122,159,182,197,188,189,187,183,179,171,170,180,190,179,155,86,32,34,37,46,95,139,111,63,35,41,83,105,96,173,250,252,252,253,253,252,252,253,253,252,252,253,253,253,253,252,252,253,253,252,252,252,252,253,253,252,252,252,252,252,252,252,252,253,253,253,253,252,252,252,252,252,252,252,252,252,252,251,251,210,130,96,105,109,90,108,137,115,118,120,109,100,103,117,121,129,126,114,115,118,117,125,139,137,97,117,137,129,151,114,79,68,84,117,105,98,79,42,59,81,80,62,53,56,51,42,62,74,74,71,53,44,57,95,95,82,93,92,79,72,74,73,152,99,10,45,59,67,55,33,42,83,86,103,102,48,33,57,93,88,73,71,51,51,67,42,46,39,35,57,78,94,101,132,137,119,121,139,143,121,87,54,36,38,75,95,92,63,45,53,42,46,49,48,48,44,61,90,110,110,111,108,63,111,134,125,130,64,35,20,15,34,71,105,115,129,130,122,59,53,73,34,16,21,60,90,95,100,99,97,97,105,104,103,100,96,97,98,106,96,96,98,106,103,83,77,79,83,86,92,98,112,124,125,98,50,31,30,36,36,34,35,31,27,54,58,41,99,68,27,21,19,45,53,62,67,75,83,78,69,73,83,73,76,75,71,82,81,91,76,49,34,17,17,17,19,23,29,48,59,53,39,38,37,42,40,36,40,39,36,41,39,36,32,35,37,32,35,36,33,33,35,34,37,33,30,32,31,34,36,32,33,43,37,28,27,27,24,23,22,22,29,26,28,32,29,38,41,43,42,41,41,43,40,42,44,43,37,42,47,44,45,41,44,42,40,44,42,43,42,42,42,41,42,34,22,25,19,18,21,21,22,25,30,30,29,34,38,35,36,37,38,39,36,41,39,36,43,37,33,25,20,21,26,29,33,29,24,38,36,30,26,27,31,27,37,32,33,31,26,34,39,62,81,64,34,24,30,29,29,22,17,18,18,23,18,19,19,22,26,27,22,21,22,18,24,29,32,32,31,31,37,39,37,36,34,36,35,35,39,38,36,37,36,32,34,34,33,41,34,39,39,36,28,21,24,16,16,19,16,25,19,29,36,37,31,27,29,18,23,24,23,27,24,26,24,33,33,27,27,27,24,23,27,25,26,29,32,27,42,45,50,27,51,212,250,250,223,171,154,141,150,149,152,160,163,170,170,171,178,169,160,143,107,89,77,81,84,100,123,116,111,158,219,216,203,206,197,194,193,183,177,193,199,201,194,182,190,201,201,204,196,189,197,197,203,196,195,206,198,198,200,190,182,196,210,200,200,114,6,1,8,11,13,12,13,12,15,14,13,13,83,96,92,134,123,124,139,142,149,147,196,237,248,248,235,130,122,144,144,169,200,250,252,252,252,252,252,221,134,175,68,17,40,8,35,27,29,36,36,57,76,108,73,48,59,71,115,125,141,163,166,177,179,185,177,168,178,176,179,164,163,123,49,16,17,33,90,170,206,193,164,155,157,155,157,150,165,168,165,119,51,34,37,31,77,170,215,195,164,149,160,184,171,180,176,169,174,173,163,82,27,34,32,33,29,43,130,200,205,194,179,176,185,181,184,180,175,146,79,61,76,89,84,68,125,176,136,94,102,146,171,195,189,173,179,172,178,177,172,173,184,175,159,102,33,21,34,31,24,22,62,99,74,58,26,23,33,37,54,120,235,248,252,237,223,209,205,188,179,156,138,112,135,231,252,252,251,251,252,252,252,252,252,252,252,252,251,251,252,252,252,252,252,252,252,252,252,252,253,253,252,252,253,253,253,253,252,252,252,173,92,74,87,93,104,130,119,116,104,111,127,140,140,127,132,132,120,125,123,108,105,118,105,70,114,137,137,127,84,59,73,94,100,100,107,102,75,80,84,87,72,56,62,75,60,50,60,69,77,52,45,27,55,87,94,106,98,91,91,105,84,150,124,30,85,140,144,115,83,76,108,157,169,122,46,24,71,93,88,77,84,87,83,105,91,82,68,65,78,92,110,109,111,115,98,73,64,56,54,63,83,89,93,101,88,91,78,89,88,66,63,53,53,50,53,81,119,129,113,110,119,104,131,131,84,51,7,17,21,55,95,117,125,112,113,122,132,107,117,86,28,9,34,99,114,105,105,101,101,106,105,108,99,92,102,104,107,104,89,97,110,97,87,81,77,81,93,98,94,106,110,119,114,107,50,23,30,32,33,39,33,36,28,63,68,76,196,114,17,19,14,47,59,76,78,78,77,69,71,70,78,82,79,73,82,89,88,71,42,23,16,17,19,18,25,40,57,65,59,48,38,37,41,42,42,41,39,39,42,33,36,37,33,36,33,37,36,33,31,36,37,40,39,33,36,33,33,37,42,37,39,57,51,52,49,37,39,38,30,27,30,19,29,34,27,33,37,41,38,41,40,36,41,41,41,37,43,45,42,41,39,45,43,36,42,44,44,42,43,39,39,42,42,29,19,25,26,29,32,29,28,30,27,35,30,32,41,33,33,38,39,41,38,35,39,35,37,37,29,17,17,34,32,21,28,24,27,28,27,29,22,25,21,26,29,27,25,32,31,29,36,41,73,78,54,30,24,29,29,24,18,19,20,23,18,18,21,27,25,27,21,21,25,18,23,24,30,30,31,32,36,34,34,36,34,40,31,38,39,33,37,34,37,36,34,40,36,35,36,32,38,31,27,26,22,16,20,21,21,23,20,35,30,33,32,24,27,27,25,21,24,23,24,24,25,31,35,37,29,27,26,25,31,26,25,27,24,31,37,35,45,18,79,211,247,238,229,217,196,167,147,129,128,141,143,149,154,158,163,162,170,171,152,141,122,103,113,130,116,96,122,201,230,215,217,215,201,187,181,183,192,200,198,203,204,199,202,208,210,209,194,197,201,199,198,188,196,203,194,195,198,190,191,199,203,198,205,113,5,1,7,11,13,12,12,12,14,15,14,14,98,130,113,144,126,115,128,113,125,122,189,244,252,252,238,200,149,125,118,124,161,167,199,244,251,251,252,217,144,186,76,21,37,16,38,24,28,39,39,63,98,153,130,91,101,104,134,150,170,190,186,188,183,184,178,169,167,175,172,165,132,70,59,67,71,60,47,108,184,199,180,165,163,174,171,170,166,160,122,86,112,130,131,79,41,109,200,189,170,172,205,198,160,165,163,165,168,155,89,43,56,89,105,101,60,34,75,152,200,205,188,180,191,189,189,177,150,90,62,93,100,111,114,74,88,152,174,141,139,165,186,194,181,175,175,176,179,183,181,186,186,171,129,102,107,105,113,104,96,120,160,230,251,251,209,144,70,25,16,10,90,141,145,146,177,237,252,239,229,189,135,115,199,253,252,252,251,251,252,252,252,252,252,252,252,252,248,249,252,252,251,251,252,252,251,251,253,253,251,251,249,249,212,137,186,246,245,245,252,169,79,60,60,83,96,127,126,120,100,101,125,131,136,125,108,115,126,124,128,111,81,95,101,74,118,142,120,127,97,89,95,97,96,97,117,113,99,101,123,121,104,100,93,83,66,66,54,63,77,49,42,27,46,80,96,94,89,105,105,131,110,150,153,53,101,144,146,133,89,114,174,194,169,111,46,33,61,79,68,73,92,79,95,147,146,133,122,111,94,74,85,96,89,66,63,70,66,71,97,131,150,139,129,109,75,71,83,95,107,103,98,88,89,97,73,73,98,110,120,119,134,131,145,109,28,12,12,53,84,110,126,119,122,118,119,120,123,105,131,82,20,12,47,120,116,111,110,104,106,105,105,96,96,100,108,108,101,94,99,106,97,78,67,78,84,90,93,98,103,109,113,113,85,38,20,26,24,29,35,35,32,37,29,55,69,92,212,146,39,22,27,66,75,81,75,80,73,68,74,72,76,74,84,85,89,89,57,33,19,18,21,17,19,32,51,63,70,69,61,48,38,36,34,39,44,36,40,40,36,36,29,35,34,31,34,35,33,33,34,36,39,42,38,37,38,33,39,36,40,40,42,69,70,70,66,64,66,54,49,28,23,26,22,27,23,30,33,39,41,38,39,37,41,38,39,43,38,41,40,37,46,41,38,40,42,46,43,44,39,39,41,40,39,27,26,37,39,38,36,40,38,32,34,34,31,36,34,36,37,35,37,37,37,37,36,31,37,36,25,17,27,36,24,21,23,26,27,25,24,19,21,19,23,23,18,25,24,24,31,27,35,33,44,81,75,51,25,21,29,19,21,30,28,29,31,25,30,29,23,21,17,23,17,22,22,27,29,29,33,30,35,35,33,30,33,35,29,32,34,36,34,30,35,32,35,38,33,34,33,34,29,31,29,17,22,22,22,19,23,26,27,40,32,33,29,24,31,27,28,29,30,29,30,34,24,33,37,36,32,27,24,27,27,25,29,23,29,29,34,26,44,124,196,229,194,185,191,198,208,203,200,162,132,121,114,123,128,137,143,144,157,165,165,165,150,136,147,146,102,95,166,231,235,234,242,236,225,213,216,221,229,230,222,232,235,230,227,232,229,224,221,220,220,213,213,211,214,210,206,208,205,201,204,208,211,210,211,113,4,0,7,10,12,12,14,12,14,14,14,14,92,120,117,150,125,108,107,103,88,53,111,215,249,249,242,215,104,89,79,87,83,50,56,107,139,192,245,187,144,175,61,41,34,19,36,21,34,34,39,69,123,199,184,150,137,136,162,177,193,197,188,184,183,183,180,166,168,166,167,141,74,52,101,130,120,88,47,56,118,191,207,188,183,181,193,178,163,124,49,86,155,187,175,124,86,117,198,169,161,188,201,186,137,141,149,144,153,86,24,24,91,171,162,168,108,37,57,96,171,206,189,176,182,189,180,151,100,52,61,108,90,103,130,77,66,96,146,138,128,171,192,194,181,177,186,185,190,193,196,186,173,116,92,149,152,162,185,225,252,252,252,252,252,252,253,253,243,215,160,122,170,210,241,252,252,252,252,252,252,252,252,252,253,253,251,251,252,252,252,252,250,249,252,251,252,252,250,252,252,252,252,252,252,252,253,253,251,251,252,252,229,121,48,38,86,168,141,158,173,110,88,70,103,117,116,137,141,138,104,108,113,93,98,99,86,77,84,98,112,97,92,125,116,114,148,123,114,118,120,112,102,95,89,99,110,99,110,122,115,114,108,94,79,76,66,109,97,58,71,61,58,50,83,92,87,89,97,103,106,129,122,156,177,66,63,112,99,92,102,174,194,153,147,110,48,28,54,75,69,72,73,78,113,158,151,154,150,126,119,80,80,98,99,87,93,120,122,122,136,165,172,137,118,113,89,93,89,92,116,112,98,107,124,113,91,63,55,92,129,145,133,103,76,59,75,92,103,120,130,146,138,139,139,130,127,121,125,113,117,84,53,29,74,122,109,113,111,108,110,99,101,99,101,105,105,99,86,97,104,89,95,84,80,84,87,95,99,101,87,113,93,47,45,16,16,16,22,37,38,29,37,34,34,39,52,66,143,167,97,42,59,96,86,79,71,76,76,73,74,75,71,73,88,83,67,43,27,17,16,18,17,26,42,58,66,64,69,70,61,48,28,34,39,34,41,39,36,33,32,34,37,37,31,35,35,34,33,31,35,37,36,42,35,36,40,38,40,36,36,41,45,73,84,77,80,81,87,74,58,35,17,21,24,23,25,24,29,35,34,34,39,40,38,36,38,39,40,38,39,41,45,44,44,41,41,43,42,41,36,40,39,38,39,23,27,36,36,39,34,31,31,30,33,37,28,35,38,30,37,38,38,36,37,38,36,30,35,33,25,18,28,24,17,18,22,25,23,23,25,19,21,27,27,27,23,23,20,24,27,33,28,28,32,59,86,72,41,24,22,19,26,35,33,38,36,37,36,31,27,19,19,22,22,21,23,27,32,32,29,28,35,35,32,32,32,33,33,36,30,31,35,37,34,32,34,36,31,32,30,28,36,29,22,26,33,31,31,27,34,31,31,32,32,35,31,29,29,36,34,35,34,32,36,35,39,36,37,35,30,30,24,27,25,27,25,29,24,26,32,33,184,246,250,250,216,198,183,171,180,198,215,205,179,155,131,113,108,113,122,129,142,149,152,159,155,152,162,148,120,147,188,210,210,213,226,226,221,222,225,229,238,234,231,237,239,238,233,236,237,235,229,230,233,230,236,230,230,224,223,225,208,207,217,222,226,218,217,113,2,0,6,10,12,10,13,12,14,14,14,13,90,110,105,152,130,118,113,107,111,75,60,100,162,211,229,143,50,51,55,69,68,42,39,56,57,135,219,128,115,151,52,37,32,20,34,19,34,36,39,60,98,171,174,147,154,156,179,191,196,194,184,182,176,181,177,171,162,156,146,77,36,58,133,152,143,115,66,39,54,154,194,184,156,150,162,152,142,65,19,84,162,183,190,184,165,152,160,142,149,174,178,150,125,149,146,127,112,41,9,45,108,177,177,191,127,46,55,50,114,181,175,123,120,136,146,116,58,44,71,111,87,94,120,72,65,69,98,111,109,169,208,197,188,188,195,200,200,210,193,173,122,37,45,113,171,242,252,252,252,252,253,253,253,253,252,252,253,253,252,252,252,252,252,252,252,252,250,250,252,252,252,252,253,253,252,252,250,252,251,250,245,249,252,252,251,251,252,252,252,252,252,252,251,251,253,253,251,251,249,237,94,36,41,45,77,89,83,127,153,68,81,108,131,154,131,139,123,125,107,91,79,70,88,87,61,49,67,81,95,110,113,140,118,104,135,122,110,122,139,123,88,83,91,96,99,100,118,118,108,108,95,74,73,47,51,109,77,55,62,97,133,121,126,116,104,125,148,142,137,143,139,157,188,102,52,94,130,137,136,192,150,115,135,87,46,35,77,92,62,66,71,89,125,149,152,148,143,145,151,132,108,105,105,85,89,120,131,130,131,151,150,112,116,123,100,52,87,148,146,131,87,79,104,118,89,83,77,82,127,111,63,17,7,84,146,128,123,134,139,140,144,142,129,119,117,112,106,100,112,92,97,99,102,121,98,105,111,103,101,101,107,108,105,96,106,83,79,103,106,105,103,105,107,109,100,102,107,108,96,68,35,20,19,12,20,35,53,71,56,37,33,33,33,33,36,25,83,174,170,85,59,78,81,83,67,77,77,71,74,73,79,83,69,49,33,17,16,24,15,18,36,49,66,69,67,72,71,69,64,43,31,36,36,30,35,36,34,34,33,41,38,36,33,34,34,38,34,30,36,38,39,39,36,35,39,41,40,39,45,39,40,74,77,76,77,79,85,72,65,39,19,19,21,21,28,29,25,29,26,32,34,31,35,37,36,40,35,38,39,36,48,44,39,44,38,44,42,38,39,36,37,42,34,28,25,29,36,37,33,31,33,35,29,33,33,35,35,31,39,34,37,38,34,39,32,35,36,33,30,18,28,24,18,18,18,22,21,17,21,24,29,40,42,39,29,26,20,24,29,29,30,27,29,36,69,89,63,35,16,14,18,30,34,37,37,36,37,29,26,18,19,22,19,21,24,27,27,26,32,30,33,31,30,32,30,35,28,32,32,32,33,31,34,32,37,36,32,35,34,31,29,25,21,21,39,39,38,33,34,42,37,35,27,32,31,31,33,31,39,33,34,36,35,38,33,34,32,35,36,31,31,27,26,34,24,32,27,34,20,70,245,246,250,250,247,245,218,196,178,170,184,185,197,203,194,168,143,127,122,145,153,145,149,157,162,158,165,165,156,170,169,163,143,130,136,133,143,154,152,158,167,166,170,173,182,183,178,187,184,189,184,188,199,201,207,199,203,204,208,210,191,193,202,212,221,219,219,113,3,0,7,11,12,12,13,12,15,15,14,14,90,108,95,139,123,113,122,157,192,190,163,110,113,108,87,39,37,76,79,98,93,74,84,93,83,138,184,85,78,97,24,36,29,28,36,16,34,34,41,62,86,124,127,134,150,171,193,190,191,187,182,176,175,174,174,168,147,142,84,25,34,64,128,144,145,135,132,113,60,103,152,150,115,97,125,139,74,29,29,92,151,165,189,222,223,190,190,125,116,167,164,125,122,179,184,132,123,74,33,43,101,181,176,203,124,44,61,37,73,136,148,98,77,112,128,71,49,60,76,107,59,84,113,71,74,106,185,222,194,181,206,201,190,185,185,180,168,181,177,145,89,91,181,250,253,253,252,252,253,253,250,248,252,252,252,252,252,252,253,253,253,253,252,252,250,247,250,252,252,252,252,252,252,252,251,240,229,252,252,249,248,250,252,252,251,251,252,252,252,252,252,252,252,251,253,254,250,250,222,122,71,64,83,91,73,70,61,113,128,78,90,83,125,134,116,107,90,84,70,71,68,76,101,110,88,81,96,111,119,120,148,140,89,78,130,137,123,100,100,104,95,97,97,98,91,95,116,129,120,106,98,83,84,69,31,43,46,77,102,134,129,161,156,123,120,137,146,137,131,134,121,117,163,126,45,66,103,113,84,88,84,53,67,66,49,32,60,87,51,57,84,112,126,145,138,126,139,145,189,168,138,98,64,60,55,78,77,92,105,117,117,120,130,113,73,16,53,144,159,132,96,57,64,89,115,117,97,83,57,30,12,13,45,98,127,100,81,83,99,110,96,103,96,84,81,74,86,81,85,81,83,89,98,105,98,112,104,100,105,99,99,97,102,113,123,117,75,88,122,103,69,63,100,116,115,98,110,87,43,25,15,19,19,20,46,69,91,110,97,63,39,27,34,31,30,34,65,155,187,97,38,53,69,76,70,74,74,71,77,79,76,57,35,23,21,17,22,21,27,46,57,64,66,69,77,69,69,70,61,40,33,35,34,34,35,36,35,36,36,41,39,35,37,38,38,37,34,36,37,37,40,36,39,42,43,43,45,44,38,35,46,71,66,63,64,60,69,61,55,39,17,23,15,23,31,28,29,24,28,30,31,27,27,34,29,30,34,32,32,33,37,36,39,39,41,45,38,44,44,33,34,35,34,24,21,34,39,39,38,35,39,33,31,32,25,31,27,33,34,33,38,36,36,37,41,29,30,36,27,23,33,22,20,21,15,23,19,22,22,17,27,30,34,39,31,27,23,24,26,32,27,27,31,28,41,74,86,58,22,13,16,24,37,36,33,36,36,35,27,18,20,23,18,21,25,25,27,25,24,24,28,27,28,29,30,33,29,29,31,32,30,32,31,32,33,33,33,30,32,31,24,25,23,21,35,39,36,41,43,40,37,37,27,29,36,26,33,33,26,33,29,34,36,29,34,32,34,37,35,33,31,31,26,30,30,33,21,40,15,92,246,246,249,249,248,249,243,232,216,196,180,172,185,205,220,229,237,212,174,177,177,173,176,178,180,177,183,181,174,171,162,141,97,51,21,12,20,28,27,36,39,39,42,46,55,58,61,63,71,75,79,83,93,101,108,109,117,129,140,142,130,136,152,164,182,178,191,114,7,3,9,12,14,13,14,12,15,16,16,16,102,119,93,123,101,101,137,211,243,243,240,180,140,87,42,46,71,106,131,154,146,109,123,131,118,172,191,85,66,63,23,41,32,30,31,25,30,35,46,64,95,132,129,130,162,182,188,181,178,173,173,173,168,162,165,155,127,76,24,12,33,53,78,87,105,129,205,189,63,76,111,136,126,117,141,75,28,23,44,117,162,173,185,227,204,165,181,109,96,173,194,125,118,230,250,165,158,134,69,40,90,177,171,198,118,40,61,39,53,80,151,151,141,148,83,54,70,81,87,110,83,98,113,87,93,174,251,251,227,147,168,173,159,133,107,92,82,103,113,139,211,249,253,253,252,252,252,252,250,250,250,251,252,252,252,252,252,252,252,252,252,252,251,249,250,251,252,252,252,252,252,252,252,252,251,244,230,252,252,252,251,251,252,252,252,252,252,252,252,252,253,253,251,251,249,237,190,165,95,57,57,54,55,71,81,68,57,77,96,97,112,94,98,103,85,83,83,79,74,95,80,88,130,130,103,102,99,104,115,109,126,134,111,121,140,135,99,57,76,81,93,107,103,102,103,103,110,121,106,110,89,77,112,93,78,43,45,109,105,101,98,92,89,73,63,72,72,52,57,48,48,36,95,142,59,10,19,35,36,37,35,44,48,49,56,38,59,76,54,56,89,141,149,131,120,125,132,150,185,168,167,150,131,115,104,97,67,74,92,105,104,128,131,108,95,24,20,73,100,113,103,81,63,92,134,117,61,31,17,9,48,97,108,104,97,66,54,41,51,62,65,66,65,67,59,57,62,65,69,62,66,68,79,96,92,98,99,103,108,94,101,112,132,148,152,97,42,67,86,61,32,27,42,86,105,83,49,31,23,16,15,20,37,57,76,99,122,131,142,118,66,34,38,40,36,59,72,103,146,133,74,40,62,74,75,78,73,78,77,73,49,23,20,17,18,21,19,37,52,65,66,66,73,67,71,72,68,67,61,41,39,39,32,37,35,38,36,38,45,44,45,42,35,37,38,35,42,41,41,35,38,40,39,42,45,47,37,43,44,42,47,60,54,42,42,40,43,42,41,24,23,24,20,29,24,25,24,28,27,32,32,24,32,27,28,32,34,26,27,33,29,31,34,35,33,36,38,40,38,31,32,34,27,20,27,34,36,40,34,33,34,34,31,26,27,27,31,32,29,29,39,35,29,35,33,33,31,27,21,19,35,24,18,21,17,22,23,22,19,22,26,24,32,31,29,25,14,22,25,29,33,27,27,30,24,49,83,79,45,18,14,25,37,40,39,37,43,34,29,23,18,19,22,20,22,29,24,27,27,24,31,28,26,27,26,32,31,25,29,29,29,31,27,29,32,31,30,24,29,27,28,24,18,23,35,38,46,47,43,42,41,39,26,26,29,30,33,28,29,32,29,33,32,32,35,34,35,33,35,36,32,28,33,27,26,35,22,41,15,122,247,247,249,246,241,247,245,247,241,233,220,206,196,186,213,234,252,252,176,166,171,169,175,169,163,158,163,166,155,151,144,127,87,39,15,9,11,12,14,13,14,15,14,14,14,15,14,15,15,15,15,15,15,15,15,16,23,29,38,44,38,51,61,76,92,91,110,94,19,5,13,12,15,12,16,15,15,16,16,16,113,134,105,126,97,84,113,188,222,222,192,115,124,88,59,96,108,104,129,154,153,123,139,155,145,193,197,85,74,63,31,50,29,27,32,28,34,32,50,74,115,155,147,156,178,183,182,174,169,170,174,169,160,160,164,152,98,50,21,32,56,49,49,44,61,91,181,155,41,83,109,113,134,109,98,32,13,30,69,140,182,181,201,226,168,152,182,120,111,183,229,155,132,236,252,208,169,174,122,63,102,170,126,126,69,39,66,43,59,58,115,169,163,110,64,57,83,102,84,110,101,118,113,110,131,147,204,202,132,72,91,99,90,76,60,65,79,98,123,187,251,252,252,252,252,252,252,252,250,251,252,252,252,252,252,252,252,252,252,252,252,252,250,251,252,252,252,252,252,252,252,252,252,252,252,252,252,252,253,253,252,252,253,253,252,252,253,253,253,253,253,253,252,252,252,252,160,88,43,41,59,31,47,65,86,68,61,102,105,127,156,136,119,107,86,92,120,109,103,92,89,132,139,117,91,87,77,83,96,93,117,119,126,124,133,132,99,58,59,69,66,87,88,96,97,88,109,113,104,109,79,78,114,112,97,66,41,66,63,48,41,38,40,39,38,41,36,25,36,25,31,13,36,139,78,15,16,35,42,37,44,41,48,53,63,48,56,92,66,79,112,149,162,135,147,160,163,164,168,168,178,151,131,115,112,134,111,101,104,118,97,95,112,107,90,29,6,12,11,66,78,83,92,118,91,45,20,14,24,78,120,140,153,125,76,42,24,21,30,35,37,42,39,38,43,41,42,38,42,45,43,54,71,84,81,87,94,103,105,101,115,139,143,113,76,48,39,44,42,37,32,32,29,39,57,55,26,21,16,15,22,49,64,89,110,128,128,129,136,133,108,91,104,64,39,66,61,75,105,150,125,56,50,63,79,86,81,73,48,35,27,21,19,17,21,29,50,63,68,70,69,77,75,72,68,59,61,57,51,44,40,39,39,38,30,39,38,38,43,43,41,40,39,37,34,38,43,37,42,42,37,40,39,43,42,42,46,46,39,41,50,52,39,34,33,26,28,29,31,24,20,27,19,26,25,19,21,28,25,24,29,34,31,24,29,33,28,27,27,29,27,28,29,29,25,29,30,30,29,28,34,26,21,19,22,25,24,31,29,29,27,24,23,20,29,21,21,27,25,25,26,28,25,25,28,26,27,23,17,31,35,21,20,17,16,20,22,23,22,18,26,27,22,24,33,26,20,24,27,29,26,26,22,26,28,28,55,85,76,34,15,22,35,35,35,40,27,35,33,19,19,21,21,20,29,26,24,29,27,27,24,24,29,26,26,24,30,28,26,31,25,28,24,27,32,27,29,25,27,27,23,24,19,19,31,40,41,44,47,42,40,38,31,27,27,28,31,29,29,33,32,33,35,33,29,33,35,28,33,33,37,35,29,27,29,32,29,38,23,168,248,246,249,243,243,245,240,245,245,245,245,238,230,211,211,185,210,182,86,83,90,90,90,87,84,79,81,83,82,75,93,101,101,133,139,131,121,102,88,89,111,96,87,73,75,63,60,61,53,44,39,38,48,49,43,37,26,16,19,25,24,22,20,26,29,31,34,43,24,10,15,14,16,15,15,16,16,16,16,16,152,166,148,162,133,108,89,101,103,96,74,50,82,83,103,155,144,103,81,93,110,100,134,157,148,194,196,89,77,65,30,46,30,31,33,24,35,34,46,83,141,205,215,216,224,218,220,217,213,208,209,209,211,208,226,174,91,116,109,102,101,92,104,90,94,98,122,114,83,135,159,110,94,85,64,37,45,65,96,167,190,183,234,237,164,164,196,142,137,195,213,158,118,188,246,191,155,172,159,117,138,166,66,62,58,69,97,74,79,57,73,92,87,81,71,76,98,123,97,87,84,96,100,125,119,84,107,95,54,26,36,53,76,92,103,153,205,242,250,250,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,253,253,250,250,247,244,144,76,46,79,111,93,86,92,81,51,59,106,134,155,159,150,139,114,108,107,103,89,83,98,103,114,117,92,81,91,76,78,79,96,125,119,103,92,124,136,101,61,39,37,38,51,86,60,42,56,105,122,110,114,74,93,114,105,94,38,35,50,39,46,43,51,45,42,37,64,84,49,51,52,69,53,53,143,126,67,86,98,78,66,50,54,72,78,63,40,73,112,132,164,156,162,146,134,158,160,160,147,141,87,53,31,11,10,17,57,69,71,79,81,44,38,47,56,76,41,14,17,14,57,104,92,95,57,15,10,18,66,107,131,132,132,141,110,48,16,24,24,29,32,31,33,32,33,27,28,31,29,28,25,31,50,63,74,73,84,89,88,94,102,111,84,52,38,31,36,38,36,34,32,36,35,34,34,35,36,27,19,14,33,63,79,105,122,126,131,124,118,113,119,146,162,152,73,29,58,57,60,74,125,162,106,49,37,66,86,64,42,22,17,21,15,25,24,45,64,65,74,74,75,73,75,74,62,64,61,52,59,55,36,38,35,39,41,39,45,46,44,42,46,46,41,40,39,40,40,43,39,43,46,43,43,40,42,43,42,44,42,37,43,53,56,35,20,25,21,26,24,27,21,20,22,21,18,17,27,20,21,25,21,24,27,28,23,32,24,26,27,24,24,29,27,26,24,23,25,24,23,26,28,27,23,20,20,20,23,21,24,22,20,22,23,26,18,19,19,20,22,24,28,24,19,19,25,21,23,21,21,18,28,38,17,15,21,19,23,20,20,21,20,23,19,23,23,22,24,21,23,23,27,24,27,25,24,24,22,29,62,86,66,36,17,22,28,29,27,29,26,23,24,22,24,21,22,27,28,24,22,22,21,26,30,21,26,27,25,29,27,27,25,27,28,23,26,27,23,28,27,26,21,22,26,19,18,26,34,34,36,35,34,34,31,27,31,24,30,37,32,30,34,33,26,35,31,31,33,32,32,31,36,32,30,36,26,28,30,32,30,35,208,251,251,248,246,247,242,238,240,239,244,246,249,248,233,223,128,61,39,6,11,12,16,24,29,35,28,23,29,21,19,65,141,191,230,244,239,235,225,217,216,216,224,216,202,207,195,193,196,182,179,171,178,181,181,177,156,139,131,138,140,122,110,94,81,69,56,50,45,21,7,11,12,15,14,14,15,14,15,15,15,198,206,190,209,203,185,137,120,108,92,80,103,151,135,148,182,160,128,103,96,99,82,93,118,127,184,185,84,71,44,25,46,27,33,32,28,33,33,50,71,145,234,247,247,248,245,240,243,223,208,242,249,235,233,232,133,109,187,120,135,128,111,130,122,131,121,129,125,118,181,229,120,51,69,101,125,131,151,173,214,234,229,234,208,177,141,142,120,123,177,134,87,75,84,152,118,103,141,146,136,160,186,113,88,77,97,115,89,106,80,73,59,63,73,92,85,105,133,104,98,83,99,96,88,88,105,141,112,79,59,58,68,104,131,155,205,232,242,250,250,252,252,252,252,252,252,253,253,252,252,252,252,252,252,252,252,252,252,253,253,253,253,252,252,253,253,252,252,252,252,252,252,253,253,251,251,244,159,165,175,170,163,160,158,123,152,164,156,146,160,157,150,152,145,148,132,55,65,79,104,124,92,94,89,78,67,69,116,139,146,131,120,120,120,101,82,66,57,91,92,92,98,89,98,94,92,73,69,88,95,120,108,78,71,101,102,96,61,34,34,31,55,68,48,42,49,107,119,112,110,73,93,101,82,71,34,33,39,39,39,33,73,74,54,49,112,153,125,134,138,145,130,108,171,172,117,141,136,105,117,92,110,140,67,37,23,77,131,122,168,148,123,111,74,81,69,68,64,19,7,12,11,16,16,14,14,27,51,69,89,93,97,110,155,203,229,243,247,248,178,253,155,51,10,5,47,101,132,140,130,117,113,124,92,57,49,61,84,84,89,89,77,70,71,69,52,63,58,32,27,43,64,57,65,71,80,79,85,93,79,56,25,30,38,29,32,37,33,33,31,31,36,36,41,35,35,36,30,44,65,91,120,121,118,108,103,90,85,92,101,110,114,110,51,29,57,66,70,66,92,150,155,95,42,47,49,31,23,16,18,20,21,40,54,66,72,72,73,78,81,72,70,71,71,101,122,123,113,91,63,90,63,75,76,72,73,69,78,82,79,98,71,66,66,70,66,69,76,74,76,81,69,71,98,63,66,67,63,62,62,60,52,25,19,17,18,21,21,23,21,22,23,21,24,24,21,25,25,24,28,23,28,27,21,30,38,38,41,27,19,26,22,24,26,25,25,25,31,23,22,26,22,19,17,22,22,22,21,20,25,19,24,24,19,21,20,24,23,21,23,19,20,19,24,23,21,27,21,17,29,34,22,20,17,15,25,18,19,24,17,17,22,21,20,18,19,21,24,25,19,20,22,27,23,24,23,22,30,66,93,66,28,15,17,23,27,24,22,22,21,18,18,20,24,27,23,20,24,22,21,24,27,22,23,26,24,26,24,27,24,28,24,21,25,23,27,26,22,26,26,20,19,18,18,24,21,28,29,25,26,27,29,27,24,26,29,25,26,33,29,26,28,27,30,31,27,30,31,29,31,32,29,30,27,31,23,42,16,55,237,253,253,251,251,249,248,246,243,245,246,248,249,246,238,214,109,8,6,10,11,22,26,25,40,53,51,49,47,45,42,98,180,213,240,241,231,227,218,217,211,209,217,216,219,227,218,219,224,225,231,229,230,231,229,236,224,212,215,225,223,215,202,191,173,164,147,143,102,12,2,10,10,13,12,15,13,13,14,13,13,172,178,158,169,186,182,160,170,174,159,137,160,181,146,134,151,170,164,136,119,108,82,78,91,111,172,164,61,37,22,11,37,30,31,29,24,32,39,52,58,92,157,182,185,171,145,162,158,114,126,175,193,161,123,109,66,83,137,103,113,104,92,98,78,94,88,84,94,90,160,236,96,22,88,147,196,218,241,251,251,242,182,157,161,174,122,106,98,101,155,96,59,53,50,73,45,69,96,86,79,136,153,98,99,80,89,101,95,111,105,91,89,81,71,83,81,87,105,97,98,101,97,87,75,60,75,121,114,110,85,63,72,79,128,173,194,155,119,168,214,194,208,236,237,253,253,250,250,253,253,252,252,252,252,252,252,253,253,252,252,253,253,253,253,253,253,252,252,253,253,253,253,252,252,190,212,232,33,24,38,32,34,41,95,31,27,49,26,37,39,34,34,53,46,58,60,55,75,89,101,84,81,70,73,80,81,98,113,122,120,118,105,110,117,105,89,88,92,86,89,93,106,107,93,72,79,80,83,89,89,97,93,69,45,54,76,75,60,58,48,31,56,80,40,35,46,107,118,110,110,62,77,74,68,69,44,58,55,47,35,21,66,80,50,54,127,143,99,116,112,132,122,83,129,148,122,124,95,70,101,108,122,123,81,45,26,70,68,37,72,40,18,21,9,15,12,13,14,13,14,20,27,73,108,138,182,210,237,251,251,252,252,252,252,252,252,252,252,246,246,245,101,21,46,93,143,153,152,115,108,109,119,120,98,93,102,135,149,158,161,157,157,150,150,149,136,146,101,35,24,62,84,62,67,64,77,86,77,74,74,63,44,36,27,26,34,38,34,33,33,35,43,36,41,38,35,35,41,62,81,90,89,82,82,73,62,61,71,66,42,40,34,42,34,37,63,69,82,68,71,110,170,156,62,24,15,18,20,14,19,25,46,65,70,72,73,76,78,72,73,69,66,66,75,117,157,171,187,179,160,147,143,150,151,152,148,151,151,160,159,151,165,159,158,160,166,161,156,169,158,164,160,155,156,145,152,160,154,148,119,76,40,16,12,12,12,16,16,21,27,22,27,29,31,35,29,34,46,48,46,46,41,37,41,53,82,87,77,48,31,36,33,35,29,33,32,31,29,28,29,26,22,23,22,19,22,17,16,23,19,17,18,18,21,19,21,23,21,19,24,24,20,22,28,24,18,18,24,18,30,39,24,20,17,15,24,23,22,20,19,21,18,19,23,19,23,23,19,22,24,23,22,22,25,23,21,25,21,33,84,92,57,23,15,19,21,19,18,26,19,23,24,24,24,22,19,26,24,21,24,21,22,27,27,24,24,23,21,21,28,27,22,27,26,21,24,24,23,24,19,19,22,20,19,23,19,19,24,21,25,24,25,21,21,25,23,27,22,24,29,29,28,27,25,27,29,29,29,24,31,32,29,31,27,38,26,33,15,88,240,252,252,252,252,252,252,249,249,249,249,249,249,249,216,206,163,116,73,16,10,11,11,18,45,68,77,87,87,83,74,98,130,154,193,203,198,186,173,175,171,172,171,168,180,191,188,188,193,200,207,203,208,201,203,209,200,202,202,208,214,211,208,204,201,203,198,199,112,5,2,8,10,12,11,13,12,14,15,14,14,130,134,97,95,119,110,104,141,171,150,113,143,141,89,73,98,125,131,126,120,123,107,92,99,119,170,155,57,50,35,16,31,30,48,42,37,42,45,57,56,71,73,61,63,66,80,86,82,43,53,81,73,37,21,35,27,49,61,65,87,78,76,78,53,59,39,51,61,44,123,215,87,24,92,153,205,226,243,235,184,106,65,81,137,219,214,213,179,175,207,167,155,134,101,103,97,86,85,76,57,49,56,62,74,74,77,79,79,97,98,94,86,78,66,86,81,79,84,89,98,81,86,70,62,45,46,76,74,73,67,67,52,53,81,115,139,62,7,11,12,17,27,44,43,63,87,116,118,92,93,98,89,85,109,113,76,69,84,82,53,77,79,40,47,53,48,60,61,93,178,90,110,52,27,6,128,210,27,13,15,16,10,96,207,48,19,43,19,27,15,20,30,62,50,57,86,80,110,104,104,88,57,95,77,54,65,64,76,98,124,130,130,116,105,103,117,125,115,119,94,97,105,93,83,55,73,80,55,68,69,73,76,61,45,48,50,61,63,57,61,35,64,88,43,19,51,100,117,127,104,65,91,72,68,79,81,105,113,128,111,104,121,117,73,76,134,116,60,54,47,79,85,47,47,66,75,88,84,63,62,39,61,59,51,56,35,43,30,12,35,28,27,29,25,57,125,130,167,145,240,252,252,252,252,253,253,253,253,252,252,248,248,243,243,228,200,139,172,116,93,79,43,71,118,139,162,151,117,100,107,104,120,116,100,96,106,130,136,135,140,132,132,129,132,132,139,139,69,24,15,57,94,86,92,70,77,85,91,94,91,101,84,60,32,31,37,29,33,36,37,36,41,38,34,40,37,35,45,51,63,60,62,63,60,56,68,71,64,65,37,28,27,35,40,37,63,75,83,74,74,84,130,175,106,23,9,15,18,19,37,58,61,72,74,75,75,73,73,67,73,60,65,75,64,77,97,108,129,112,126,96,108,117,118,118,122,125,121,127,126,100,125,115,124,128,124,110,115,102,111,119,108,126,104,117,99,122,109,96,75,50,34,21,14,12,16,18,21,23,24,32,28,34,37,34,37,54,69,72,75,65,65,66,74,120,158,171,148,85,53,57,72,67,55,58,50,37,30,35,34,26,33,26,21,24,18,15,19,19,15,17,23,21,27,23,23,27,23,27,22,25,27,25,25,24,21,26,21,24,26,24,21,21,17,19,24,19,20,21,21,21,24,20,19,23,24,22,19,23,28,24,23,26,23,23,21,23,21,17,44,84,82,45,18,17,15,20,20,19,23,24,25,26,29,26,28,28,24,26,27,24,26,35,38,30,28,23,27,26,24,25,21,23,21,24,23,23,27,24,22,19,16,21,21,23,22,22,19,24,24,18,24,28,26,31,26,29,31,22,29,27,30,24,25,34,30,33,26,29,31,32,31,30,28,30,31,39,14,97,226,172,206,229,245,251,251,249,249,249,249,249,249,241,200,223,237,242,229,191,151,109,49,56,33,52,34,44,50,45,42,38,48,68,109,143,151,153,154,165,171,176,171,160,172,183,178,173,179,182,181,176,181,174,176,171,162,171,168,174,176,178,178,177,181,184,184,192,113,7,1,8,11,13,11,14,13,15,15,15,14,120,118,88,83,108,75,62,97,132,102,71,123,119,71,37,57,67,68,106,143,181,177,162,165,170,207,196,139,149,134,121,131,122,122,107,84,60,62,74,78,92,87,89,98,101,97,117,109,63,59,53,33,27,44,53,47,61,56,49,75,59,80,89,75,77,55,81,87,61,124,208,117,80,123,137,163,164,148,92,60,41,32,63,143,253,253,253,253,242,240,248,249,180,107,118,134,113,84,86,80,72,57,39,57,66,78,86,81,84,77,78,81,69,74,97,92,82,84,88,89,87,103,110,119,92,62,47,54,87,87,90,91,63,65,56,53,42,66,59,13,22,19,19,17,20,24,72,83,24,18,25,23,20,36,50,24,16,24,32,19,53,86,34,13,22,18,28,28,59,165,76,8,16,26,13,141,243,34,24,29,21,31,131,253,83,33,76,42,53,32,30,46,87,70,81,112,120,110,81,69,35,44,60,46,43,32,45,78,105,112,115,103,99,92,97,112,115,122,101,94,76,100,116,97,82,86,79,47,52,59,52,50,59,51,53,63,44,48,57,63,45,59,80,58,69,74,146,165,149,118,87,116,109,124,130,133,165,171,194,195,190,198,175,132,93,121,108,46,39,16,22,32,14,15,12,13,15,15,14,14,14,15,23,40,65,78,116,135,162,210,220,247,253,253,252,252,253,253,252,252,252,252,248,248,238,234,232,208,169,150,118,111,99,79,43,6,12,15,13,15,47,79,141,158,142,132,110,102,101,101,104,120,100,103,106,105,120,120,122,119,112,113,109,111,117,118,86,28,10,10,70,105,108,98,77,90,98,101,103,103,103,120,108,66,36,32,37,36,39,33,32,34,36,37,32,37,40,30,34,50,61,59,59,66,74,70,69,67,60,40,34,29,36,37,39,69,79,87,74,64,45,35,125,165,77,18,12,28,50,58,66,67,67,79,79,73,73,74,69,65,62,79,93,67,65,63,39,30,29,29,27,23,29,34,32,32,35,29,31,33,32,32,27,25,29,29,26,21,31,27,28,28,25,36,32,28,28,28,24,27,23,21,19,18,17,19,25,22,22,24,21,26,22,24,25,23,35,34,35,44,36,42,36,39,39,74,131,121,69,37,47,45,42,45,38,35,31,29,28,23,25,27,22,21,21,24,18,20,19,17,23,24,25,23,21,25,29,24,21,25,22,23,27,23,23,24,22,21,23,21,17,16,19,19,17,20,21,25,19,20,24,23,24,17,21,25,18,22,23,24,27,22,27,24,23,28,23,25,26,25,56,88,77,39,17,15,19,22,27,25,26,33,33,34,28,31,35,25,29,32,27,32,40,42,42,31,31,32,31,35,30,28,30,29,31,31,24,28,28,23,26,23,19,17,22,21,18,19,19,21,23,27,31,35,35,32,34,34,35,32,36,38,35,37,38,39,35,40,34,35,38,35,41,41,43,39,46,33,61,106,74,92,142,200,238,217,202,204,212,212,214,212,195,182,203,234,251,251,249,239,211,157,111,85,56,37,29,29,32,25,24,21,24,43,63,91,108,131,157,171,187,178,171,184,188,187,181,187,191,186,183,178,165,166,155,155,169,164,165,157,150,155,161,164,166,163,182,113,8,2,9,11,14,12,15,13,14,15,15,15,122,113,81,65,98,80,74,85,119,84,61,127,152,132,76,71,54,56,110,168,232,240,220,222,231,244,238,207,230,211,193,214,206,224,215,164,127,123,121,109,121,129,149,163,148,116,125,132,97,99,89,65,53,65,88,95,118,113,94,109,77,101,124,102,126,132,164,159,139,181,237,198,181,201,184,172,156,141,118,139,127,106,130,158,224,243,251,222,217,208,246,236,123,106,108,122,83,55,69,79,96,74,53,51,57,78,87,78,64,55,66,84,70,74,94,86,91,83,91,89,92,148,178,212,169,90,59,65,95,122,155,134,92,81,88,110,144,208,179,117,183,217,205,179,154,125,250,246,150,152,174,180,172,209,205,156,179,174,169,160,228,250,171,166,159,136,166,173,207,253,178,141,135,139,184,253,243,57,97,132,151,119,190,253,110,115,128,104,120,94,99,103,129,103,103,133,103,75,48,42,59,48,48,33,26,64,90,97,99,95,100,118,119,111,107,92,84,90,100,92,98,121,117,101,105,134,110,53,46,63,66,61,54,46,59,57,47,43,43,49,77,109,107,130,145,149,186,165,142,93,81,128,142,167,164,171,180,181,198,198,196,192,174,144,109,79,27,3,12,11,13,13,16,17,20,23,33,56,126,132,160,199,222,241,252,252,253,253,252,252,253,253,252,252,246,246,245,245,220,193,184,168,148,109,119,21,27,18,18,22,12,16,23,27,20,8,20,39,20,14,91,141,160,153,125,105,86,90,108,113,118,129,96,89,107,106,115,112,121,114,107,113,108,114,115,118,77,9,27,66,111,103,91,98,91,107,96,98,95,100,109,115,115,99,49,30,32,44,36,28,37,33,37,43,44,50,47,28,34,57,56,63,72,76,74,64,64,67,63,41,31,31,31,40,39,62,76,73,62,33,26,17,29,129,143,60,31,51,62,74,76,70,75,70,73,77,70,67,66,78,86,88,85,61,62,58,33,16,19,20,21,20,20,22,22,23,21,19,22,19,18,21,24,21,20,22,19,21,20,20,22,17,22,22,18,20,19,22,22,17,23,18,21,21,17,20,18,22,25,17,17,16,22,23,18,20,20,26,21,22,23,21,18,22,20,26,80,100,71,27,12,14,21,21,24,24,19,21,20,19,20,23,19,18,20,23,19,17,18,19,21,19,16,19,19,16,23,18,16,20,18,21,19,18,20,19,17,21,16,21,19,16,22,18,18,23,18,24,24,24,25,21,27,27,20,23,22,19,24,19,21,21,21,23,23,20,21,21,21,21,24,64,91,76,42,14,17,22,27,29,22,26,25,24,29,29,27,27,24,33,24,32,38,42,40,32,30,26,34,29,29,34,31,28,30,30,29,28,25,23,26,25,20,24,24,15,21,21,21,21,29,35,33,34,34,33,35,33,35,40,39,41,42,38,41,42,43,42,40,44,41,47,44,44,51,50,52,51,57,57,44,52,57,98,148,154,143,148,151,154,156,152,152,141,148,162,197,232,222,229,225,185,171,172,141,127,117,123,120,116,110,115,101,89,92,98,115,131,153,170,172,156,152,162,171,177,187,202,201,198,195,175,154,160,158,165,175,165,163,151,145,152,162,159,159,161,181,113,9,4,10,10,13,11,15,13,14,15,15,14,151,116,78,49,81,74,102,117,152,122,85,163,230,218,135,146,124,104,116,142,217,214,179,205,223,217,199,175,193,177,138,143,155,207,232,153,95,101,112,122,130,136,155,160,167,160,159,145,140,142,128,128,100,89,119,143,189,182,164,194,156,165,184,184,225,238,247,247,250,250,252,252,251,251,251,251,239,240,252,252,250,250,253,250,223,194,210,216,227,197,245,224,84,95,131,139,96,52,57,66,90,78,60,69,74,75,71,60,55,58,79,89,75,75,85,82,83,82,83,74,82,134,149,179,127,80,69,70,88,106,122,101,83,94,123,159,160,222,191,129,210,233,245,226,200,214,253,253,218,214,225,214,218,237,234,196,219,240,222,229,249,249,206,206,236,248,236,223,204,248,214,208,242,233,210,247,198,65,141,186,188,121,173,248,118,118,122,103,119,98,101,92,127,121,110,121,96,85,97,116,126,106,66,44,83,122,126,91,77,115,135,140,118,95,89,64,40,57,79,126,121,104,98,76,109,148,122,66,36,46,76,76,57,41,51,56,46,55,66,84,126,150,155,170,171,157,166,130,82,72,85,107,110,127,147,146,149,169,165,140,149,141,116,127,125,104,57,47,102,115,136,167,200,235,250,250,252,252,253,253,252,252,252,252,250,250,243,241,230,224,196,187,171,112,94,72,58,66,25,3,14,27,42,44,17,8,13,15,21,30,19,21,19,24,51,46,42,65,44,31,73,104,146,116,93,81,74,100,116,126,150,154,84,72,83,103,112,112,116,105,112,114,115,113,116,112,85,90,116,117,113,95,104,101,97,107,96,98,99,108,111,118,104,53,30,28,44,42,34,36,34,34,34,38,43,53,51,37,45,59,69,84,73,71,69,65,75,66,64,47,29,29,35,38,36,60,61,44,27,22,15,18,14,41,153,146,74,57,63,83,80,75,64,62,64,72,70,72,92,88,90,80,69,54,41,37,25,19,13,17,19,15,27,20,21,21,18,22,16,21,18,18,24,21,19,19,16,22,22,17,21,17,20,20,17,20,16,18,21,19,21,19,19,18,21,17,16,21,17,20,20,21,20,21,19,20,19,17,23,18,23,20,15,23,19,21,63,96,80,30,11,17,16,20,18,18,21,21,21,19,20,23,19,22,20,19,19,20,19,16,23,20,19,18,21,23,17,19,19,19,15,18,21,19,16,17,20,17,23,19,16,18,18,19,20,22,18,27,24,24,25,20,24,19,22,25,18,21,19,19,21,19,18,18,21,21,21,20,21,18,18,30,68,96,69,29,15,18,22,18,17,24,21,21,20,20,21,23,17,23,18,23,45,45,40,21,21,23,19,22,22,24,24,21,22,24,26,27,25,18,21,27,21,22,18,18,21,18,20,23,24,27,27,23,24,27,33,27,28,30,27,33,31,33,24,34,33,30,33,32,35,36,34,35,39,39,39,47,40,41,46,51,30,20,109,151,148,159,156,160,156,149,152,147,142,142,155,172,177,183,183,181,193,212,213,206,211,212,206,197,205,206,196,188,181,179,170,174,183,176,165,146,141,140,146,163,179,195,196,201,199,175,157,165,165,173,176,165,167,164,153,161,172,167,169,176,191,113,8,3,10,12,12,12,14,13,14,15,15,14,192,149,135,124,128,98,132,162,236,189,118,205,251,250,200,239,238,220,179,159,209,211,200,238,244,206,195,174,208,190,137,132,115,191,235,139,107,120,134,151,138,144,141,142,191,200,178,173,170,171,163,157,145,141,160,167,218,206,186,251,221,226,252,252,253,253,252,252,252,252,252,252,253,253,252,252,252,252,252,252,252,252,253,251,221,232,250,244,253,184,250,193,32,100,117,144,118,87,89,86,116,92,69,71,83,77,67,72,74,80,84,93,90,101,101,73,73,78,86,74,59,79,63,60,63,56,51,71,76,66,74,72,85,116,119,98,74,181,130,49,74,91,110,105,137,172,225,247,153,180,152,92,66,130,154,66,131,158,173,226,246,174,121,148,201,246,194,163,131,180,230,206,199,172,126,204,123,69,120,95,113,59,124,167,67,97,63,70,90,66,64,61,110,112,112,126,105,122,142,139,119,83,93,102,105,127,117,93,110,130,140,118,81,78,57,47,42,21,37,92,99,83,61,40,76,98,74,55,33,40,46,57,58,43,45,55,33,52,129,141,160,174,150,161,147,130,138,100,73,72,95,92,76,92,116,133,151,167,146,134,152,152,178,216,237,248,250,250,252,252,253,253,253,253,252,252,251,251,239,239,240,245,210,158,128,112,104,60,33,19,3,16,31,14,10,12,12,27,18,9,18,25,29,45,55,43,31,39,46,44,42,45,42,100,134,52,41,81,56,40,39,71,95,75,78,77,96,123,138,141,152,147,80,68,86,102,110,112,111,107,109,113,112,109,109,110,108,116,105,97,113,103,111,107,100,107,93,111,112,117,103,59,59,23,32,38,32,38,33,31,35,36,36,37,42,48,46,43,64,79,73,75,71,68,75,70,78,77,64,45,32,33,34,35,37,52,46,33,35,30,23,24,42,56,104,154,134,80,51,66,79,73,66,61,65,70,85,92,89,76,78,72,60,46,26,14,18,21,15,16,20,17,18,18,19,20,16,19,19,20,23,18,22,22,21,21,17,20,17,17,19,19,19,19,21,24,17,21,18,18,20,19,21,17,17,21,16,17,15,22,22,16,20,17,21,21,17,21,19,18,18,17,21,20,21,14,48,101,87,39,13,12,18,21,17,16,19,18,18,21,19,19,15,18,18,15,18,17,20,22,17,20,18,18,17,20,18,17,21,19,20,19,19,20,18,17,17,18,20,19,17,17,21,18,19,24,19,26,23,27,27,24,28,24,22,21,24,24,19,19,17,21,23,15,19,19,20,16,17,19,23,22,38,77,87,63,23,14,19,16,21,22,18,17,24,19,22,19,20,23,16,29,40,46,29,17,19,20,19,21,22,18,23,21,23,20,20,22,19,24,18,18,20,19,22,19,19,22,20,19,23,18,21,20,19,29,19,19,21,18,24,22,23,24,21,21,23,25,21,23,22,27,22,24,27,23,29,26,23,31,28,32,23,27,131,190,190,199,190,197,191,183,183,179,178,164,162,167,156,164,176,179,191,185,192,206,214,220,203,199,212,222,220,213,215,218,211,204,201,191,186,182,171,165,165,171,178,175,177,193,202,188,184,192,184,184,183,183,183,179,180,189,195,186,194,196,200,114,7,2,7,11,13,12,15,13,14,15,15,15,226,212,231,233,227,165,181,199,248,220,119,203,244,242,220,252,243,243,218,178,222,244,253,253,252,252,251,251,252,252,243,237,181,223,241,190,174,183,174,186,146,134,138,145,193,174,170,175,179,160,119,146,163,184,187,153,171,143,143,217,159,175,238,225,230,206,220,201,226,250,250,251,252,252,252,252,252,252,252,252,252,244,240,178,157,192,208,230,218,171,247,184,45,78,72,103,104,107,141,122,128,103,64,65,70,64,83,96,94,84,77,92,107,121,109,77,70,74,84,79,68,83,71,77,61,61,48,63,88,75,92,77,110,131,146,127,74,155,125,91,101,72,75,90,123,132,217,250,207,219,214,113,63,132,174,115,144,158,155,218,240,203,172,148,199,248,214,215,169,205,247,227,221,208,137,169,133,90,98,93,104,69,101,93,72,96,70,101,103,87,88,86,127,106,104,131,106,117,132,92,68,51,75,71,73,99,107,131,129,122,113,89,64,73,95,91,57,24,13,44,58,55,57,38,48,48,41,42,39,46,37,61,77,76,71,33,17,39,118,152,149,141,117,125,113,117,135,123,119,126,141,154,157,174,213,232,242,250,250,242,252,252,252,252,252,252,252,252,250,250,241,237,216,194,161,137,145,115,65,38,19,105,129,30,4,8,10,14,13,25,10,19,42,17,16,39,40,56,59,47,41,54,47,71,118,91,46,37,42,61,67,89,128,153,168,86,48,83,51,40,40,31,52,59,101,113,128,147,144,145,135,108,66,80,98,114,107,109,119,107,110,107,118,114,106,106,101,98,74,89,110,105,108,99,100,111,113,117,116,84,38,21,30,42,45,45,33,22,37,34,36,39,33,37,34,45,57,69,74,73,66,62,67,67,69,75,77,81,73,41,31,33,31,38,33,45,54,45,55,56,56,63,70,77,80,107,162,136,66,56,60,70,68,65,73,85,89,80,75,63,69,72,61,38,21,16,16,19,17,24,21,19,23,17,20,22,19,21,18,15,21,20,17,18,16,24,18,17,21,15,23,21,21,15,22,26,15,22,21,19,18,20,20,17,20,15,17,20,17,21,18,19,20,19,21,21,17,16,23,18,20,19,19,19,20,19,35,88,91,46,18,15,19,18,17,19,18,13,21,19,21,24,19,22,17,23,18,21,23,19,21,16,18,17,17,20,20,20,19,19,18,16,16,17,17,18,20,17,17,19,17,17,19,20,22,26,23,28,31,27,29,30,26,23,26,25,25,26,22,19,18,20,20,15,18,19,17,20,19,18,17,21,19,41,80,88,59,20,14,17,17,20,15,22,20,17,21,20,24,20,18,26,42,45,25,17,22,18,22,19,21,21,20,20,21,21,18,21,18,18,18,18,19,19,20,20,21,19,17,23,22,19,20,19,21,21,19,23,21,23,18,19,23,20,22,22,19,21,22,24,22,21,22,25,22,23,21,26,24,22,22,31,21,65,183,200,190,190,181,191,182,178,166,165,179,181,171,150,141,149,150,163,181,178,179,174,174,175,158,154,187,204,194,186,187,198,199,192,190,187,194,197,199,200,199,193,181,173,157,177,203,204,217,223,208,201,205,212,209,206,205,212,218,208,208,201,208,114,5,2,6,11,13,12,14,13,14,15,15,14,204,223,234,233,224,158,165,165,244,181,83,169,222,159,134,197,202,194,121,92,121,178,221,250,244,210,250,239,251,251,240,227,131,197,236,134,119,127,136,171,93,101,120,130,170,131,131,172,176,113,76,112,151,177,188,122,97,92,96,160,81,70,100,101,139,84,98,92,150,203,197,198,164,243,254,254,252,252,252,252,252,231,236,141,75,120,116,148,191,178,251,181,40,81,60,85,76,96,133,112,124,101,83,75,66,60,77,104,88,78,73,85,83,89,92,72,57,61,73,67,56,98,111,91,84,78,62,55,71,99,111,83,79,84,93,96,61,145,90,92,117,65,85,88,125,108,162,217,148,176,160,65,58,105,155,103,110,98,94,156,160,144,131,118,176,208,184,204,159,201,244,184,194,183,147,179,114,90,99,91,112,74,102,86,74,96,68,101,97,95,103,110,128,96,104,126,100,102,101,74,62,54,57,44,42,71,106,118,114,77,70,79,75,99,114,111,105,86,49,31,26,44,47,38,58,41,47,56,42,46,20,54,84,67,69,53,30,71,132,134,142,145,145,168,173,198,230,237,250,250,252,252,252,252,252,252,252,252,245,244,239,242,252,240,229,212,204,203,177,128,105,85,39,13,8,9,14,18,9,16,12,67,98,20,8,10,26,41,38,43,34,46,67,51,71,112,87,119,95,53,55,63,49,76,139,131,66,32,48,89,86,87,95,95,93,53,40,49,43,39,23,41,69,96,137,132,128,144,143,136,131,105,68,85,106,115,112,116,113,114,110,111,113,95,93,84,92,103,87,98,107,101,105,94,97,117,119,99,45,26,21,23,60,56,69,54,23,21,24,40,35,37,39,37,49,66,74,74,71,73,60,64,76,71,69,67,77,74,66,50,31,34,36,37,35,48,57,45,63,79,88,93,86,78,72,81,131,172,117,53,46,57,78,87,88,83,75,72,69,60,71,68,54,41,21,17,16,21,18,19,24,17,22,18,16,21,19,19,19,21,19,19,21,22,18,19,17,21,22,17,20,16,19,21,21,19,19,19,22,19,19,19,18,21,19,20,18,18,17,16,21,19,21,18,22,20,17,19,21,21,16,19,24,19,19,21,25,75,104,49,19,16,15,17,19,22,17,16,17,19,19,20,24,20,17,19,19,18,18,20,18,20,21,18,21,19,17,22,18,17,19,18,17,17,24,17,19,21,17,18,19,18,19,23,23,30,28,29,30,33,33,26,31,29,27,27,27,28,21,15,19,19,18,19,23,19,17,19,21,19,21,20,20,22,48,91,90,46,17,17,17,21,20,19,21,19,22,21,18,17,21,27,48,46,26,21,17,17,25,21,16,18,17,18,21,21,19,20,18,18,21,19,20,20,19,19,19,21,19,18,19,17,22,20,24,19,16,19,17,22,21,19,23,22,18,22,19,22,20,18,23,23,24,19,21,23,21,24,19,23,31,23,40,131,190,168,157,146,140,155,145,131,127,159,205,205,188,174,164,155,141,170,219,229,227,198,165,151,128,113,133,148,151,131,128,139,136,141,143,144,152,163,170,181,178,162,150,128,131,148,181,198,216,224,205,203,212,226,224,215,216,212,215,196,185,184,193,114,6,1,9,12,12,12,14,12,15,15,15,15,97,124,137,147,119,72,91,97,199,162,94,169,189,108,42,60,57,58,46,55,78,117,156,219,193,145,193,172,218,211,167,166,70,151,221,64,39,61,88,137,65,66,87,106,134,88,111,155,152,110,81,107,113,127,150,111,103,92,118,204,124,59,49,77,111,60,75,63,123,147,112,148,134,182,253,253,252,252,252,252,249,249,244,128,50,80,63,98,132,163,240,141,28,78,67,87,59,60,96,92,109,118,112,95,79,68,76,87,79,76,77,69,61,56,73,67,61,61,56,64,58,81,93,84,64,73,76,53,48,58,86,64,53,41,67,69,59,85,39,39,55,61,71,78,97,72,69,78,51,36,34,27,31,46,57,33,43,40,38,71,50,33,41,47,71,93,98,128,107,122,146,110,134,142,105,101,66,57,56,57,70,56,63,51,62,59,42,64,46,58,100,119,126,96,96,96,64,68,87,103,103,65,48,42,45,50,59,87,104,95,81,76,76,73,81,111,118,97,81,48,13,9,15,15,25,42,61,72,72,63,57,74,87,109,134,148,184,230,249,249,252,252,252,252,252,252,253,253,253,253,253,253,250,244,240,229,201,222,165,88,54,116,188,180,154,131,147,155,131,79,61,44,23,27,12,10,12,16,18,12,16,57,95,94,58,24,45,57,34,50,35,90,132,84,73,83,115,136,137,84,37,46,53,46,71,86,58,44,41,56,59,53,53,53,76,57,36,65,62,41,33,107,146,143,159,134,128,134,129,137,141,125,111,105,109,120,113,112,115,111,114,98,89,73,75,74,73,98,97,105,101,104,111,95,105,98,59,36,17,22,16,49,85,95,102,39,15,23,30,39,44,36,41,64,73,77,71,73,77,75,69,72,75,69,79,82,83,79,69,47,32,32,37,37,29,51,54,47,66,81,96,88,79,80,72,66,90,137,163,114,48,57,80,93,81,71,76,70,68,63,66,64,56,36,22,18,18,22,20,24,19,19,21,18,21,21,21,18,18,19,20,18,17,18,18,19,21,19,18,23,19,18,22,19,21,19,20,21,19,20,21,22,19,17,22,24,16,20,20,20,23,19,18,20,20,19,20,17,21,19,17,21,19,23,17,21,19,57,114,66,21,15,14,18,15,20,24,21,20,18,18,21,21,19,20,22,15,17,21,17,21,21,21,24,18,19,17,20,23,17,19,17,18,17,19,19,22,24,18,18,18,19,22,23,23,29,23,28,32,25,28,29,29,28,26,24,29,30,23,20,18,16,21,18,19,20,18,21,21,18,15,17,21,20,28,55,91,82,41,17,15,17,18,20,22,16,19,22,18,18,20,25,48,41,19,22,17,19,24,18,18,22,20,20,20,24,21,21,20,16,20,19,21,21,19,18,22,22,16,21,20,23,21,19,19,21,21,19,21,17,20,19,21,23,20,20,21,23,24,20,19,19,19,18,26,23,21,19,22,18,26,21,61,150,164,155,145,125,125,132,124,147,169,217,252,241,244,244,235,220,185,222,252,252,250,241,203,186,119,72,72,83,119,118,93,101,101,108,125,117,106,92,94,111,100,82,73,77,65,84,114,127,152,153,141,141,152,159,164,167,172,167,168,151,151,149,162,113,10,4,10,11,15,13,15,14,15,16,16,15,54,55,60,72,69,66,111,130,229,190,125,212,239,160,91,102,96,104,118,143,151,180,183,228,181,135,196,163,217,200,163,166,75,179,222,55,59,59,82,134,65,70,76,93,98,66,88,118,141,127,103,99,92,110,162,163,141,118,153,250,160,85,69,105,144,100,125,83,54,39,67,146,186,210,242,251,250,250,251,251,251,251,246,125,78,124,100,96,71,92,160,42,36,73,65,86,49,64,63,72,101,105,115,96,97,79,66,89,69,77,92,101,66,48,44,56,62,55,64,74,74,85,85,81,78,66,69,57,67,78,69,83,91,64,108,159,130,168,154,77,69,110,102,71,84,69,79,90,97,138,170,143,181,176,208,168,144,113,141,184,116,107,71,42,72,53,56,83,68,80,77,61,85,88,72,52,16,36,41,35,46,42,46,46,41,46,42,43,31,61,121,135,115,92,77,60,45,76,107,106,89,54,51,49,49,52,30,60,110,109,93,64,36,23,43,63,49,51,63,49,15,15,16,36,87,113,155,178,195,231,249,249,252,252,253,253,253,253,252,252,252,252,252,252,246,240,237,230,214,203,200,208,195,156,160,181,150,172,108,8,4,52,157,133,80,65,67,72,55,40,41,37,41,77,89,101,130,147,115,44,65,129,147,152,84,24,71,72,42,60,41,86,132,76,39,42,71,83,80,64,45,39,49,53,47,56,77,71,39,45,52,67,97,97,123,89,39,87,88,41,90,170,174,156,151,134,131,137,112,91,124,145,113,112,110,112,113,115,115,96,78,74,78,74,72,69,81,77,84,98,96,109,122,103,59,31,19,19,19,27,40,90,94,70,77,35,20,19,29,54,52,49,58,71,79,80,73,70,77,76,77,76,74,80,83,77,84,64,42,25,19,27,29,35,33,49,57,48,67,79,86,82,76,78,74,65,51,83,152,166,108,62,57,74,75,70,69,66,66,66,66,63,52,35,19,19,18,19,22,22,24,22,23,19,21,21,16,19,17,21,17,17,20,16,21,21,19,22,20,21,21,21,18,24,20,18,19,17,21,18,21,19,18,21,18,23,18,16,19,18,21,19,21,21,24,21,21,21,16,21,17,20,22,22,22,18,17,54,112,72,29,17,12,18,17,19,16,23,18,21,19,20,19,22,23,23,23,16,23,19,19,23,17,19,21,20,19,17,22,18,17,20,20,15,19,16,26,23,17,24,23,24,25,24,33,33,29,27,26,28,29,33,33,27,27,33,28,27,26,17,17,19,19,22,16,19,22,18,21,16,21,19,20,22,19,31,62,91,76,33,16,18,18,19,19,21,23,19,17,23,19,22,53,38,21,22,18,24,19,19,22,17,16,18,19,21,17,23,21,20,19,21,25,17,18,21,21,21,18,21,23,21,21,22,24,16,25,25,17,22,18,22,20,21,19,19,24,19,19,23,23,21,21,18,22,23,20,20,26,22,27,22,48,110,122,111,116,91,105,109,117,159,182,204,216,212,225,226,227,207,166,217,245,245,249,208,206,171,88,51,47,73,140,140,127,129,118,139,149,139,114,88,49,37,31,23,37,55,39,34,41,47,52,54,33,32,33,36,44,58,75,66,121,165,184,173,135,97,17,3,12,11,15,12,14,14,16,16,16,16,106,113,118,141,141,136,166,166,250,206,131,217,235,191,125,154,148,152,170,185,198,221,221,250,177,134,200,186,237,214,189,193,95,197,221,57,66,60,85,132,71,53,39,36,51,34,48,78,115,144,120,95,98,150,225,217,167,117,155,247,168,81,71,123,150,141,152,105,39,1,26,131,250,237,229,253,245,245,197,181,172,168,204,123,134,180,130,105,69,87,136,70,58,54,43,78,66,69,62,57,74,82,103,98,90,86,83,103,87,67,112,118,77,51,31,35,50,53,65,81,87,86,89,89,75,72,61,50,92,120,86,113,139,84,144,174,202,252,253,192,107,145,137,86,72,72,125,234,252,252,252,252,253,253,252,252,252,250,249,252,250,250,225,193,151,45,24,39,29,40,42,29,39,42,43,43,39,37,41,41,38,41,39,37,40,34,32,43,25,59,116,130,109,75,81,68,54,76,71,57,42,22,22,26,28,20,12,12,19,44,50,51,53,55,69,86,95,106,153,177,190,221,246,249,253,253,252,252,253,253,253,253,252,252,247,247,243,241,223,206,196,182,162,171,164,134,145,174,179,154,147,149,145,110,118,122,80,112,65,5,6,18,67,66,57,60,59,83,77,94,151,147,145,159,182,212,217,231,214,95,39,93,127,129,74,32,63,69,46,55,37,41,61,51,49,44,46,36,71,102,46,57,90,97,114,104,108,83,50,46,42,68,100,98,103,82,42,63,62,31,91,169,160,145,134,129,136,141,89,38,99,125,99,106,105,105,108,100,87,65,59,62,69,71,78,81,83,91,89,92,100,97,68,39,27,17,17,23,33,78,118,99,53,33,36,27,23,17,32,55,60,63,60,72,80,80,75,74,77,79,69,80,88,85,89,63,49,29,19,19,16,22,34,41,40,59,66,77,87,85,87,78,78,76,66,67,60,53,98,157,163,99,39,48,61,69,71,65,64,76,92,72,51,26,18,22,14,22,24,21,23,23,22,20,23,21,16,19,20,21,19,19,22,20,19,19,20,19,18,20,21,18,21,20,22,21,21,25,19,21,22,21,18,19,22,18,22,21,19,20,19,24,19,21,21,21,24,18,23,17,17,19,17,23,21,22,18,29,98,87,34,19,14,16,21,18,22,19,19,21,20,20,18,21,20,17,20,23,23,21,22,17,23,22,19,24,17,21,20,18,20,18,19,18,19,21,22,22,18,18,23,20,19,26,38,36,25,26,26,32,29,29,34,28,29,29,27,24,23,22,16,18,18,22,24,19,17,22,25,21,22,17,19,21,21,22,32,77,99,68,29,15,20,16,17,21,21,19,19,23,18,23,49,36,19,20,16,24,20,19,23,20,19,23,21,20,24,18,21,22,19,20,23,21,24,16,19,21,21,25,21,19,20,20,21,18,21,20,21,21,19,19,22,22,19,19,23,20,19,23,21,23,26,20,24,23,20,21,17,23,27,21,41,56,64,66,63,57,57,56,56,86,79,88,89,88,98,88,103,91,62,107,131,124,123,104,128,96,52,53,54,85,139,156,129,128,113,121,137,131,135,105,44,29,35,33,41,46,41,39,40,43,34,19,13,17,21,21,24,18,17,13,122,227,237,225,147,71,16,3,14,12,16,14,13,16,17,16,16,16,122,124,132,154,156,149,163,168,250,188,107,195,232,162,92,111,88,108,150,169,200,231,233,252,195,163,218,200,245,244,227,199,96,206,218,66,75,51,85,130,63,48,29,24,25,25,39,35,89,163,132,94,91,117,197,175,103,69,95,173,101,51,47,91,130,133,158,121,77,29,51,118,205,213,210,244,214,212,170,79,21,44,104,97,139,149,104,91,95,162,234,124,79,66,65,79,66,72,56,61,71,81,120,97,76,77,86,132,137,85,106,145,93,93,72,51,49,55,77,69,84,79,80,88,61,68,62,54,108,90,105,118,122,75,97,141,177,246,252,213,70,114,128,96,95,94,129,198,247,247,250,250,249,249,252,252,252,244,235,231,203,241,249,222,128,31,6,10,21,35,39,39,38,31,41,43,37,39,36,43,42,38,37,41,53,59,55,41,34,23,30,59,61,75,107,87,31,8,11,12,13,14,15,19,20,24,24,35,123,105,148,196,219,236,252,252,253,253,252,252,253,253,252,252,252,252,246,246,236,222,184,155,144,133,112,95,86,102,121,125,145,138,116,120,120,94,85,118,124,104,71,52,60,53,71,62,37,76,56,22,23,11,67,137,179,191,191,194,167,178,214,200,173,188,181,169,156,168,151,56,14,21,49,63,43,42,44,51,50,46,41,43,69,59,57,61,43,20,91,151,76,64,90,126,149,112,96,75,54,52,44,43,53,51,54,56,42,53,50,32,94,158,153,139,132,131,133,141,83,50,110,125,97,108,112,109,89,69,63,54,63,73,78,80,80,82,96,97,100,93,63,37,24,23,19,20,33,46,54,69,77,67,43,28,22,16,25,32,39,51,57,61,64,72,79,84,75,76,77,75,83,88,88,75,48,32,22,22,19,17,27,45,58,66,68,84,90,93,99,79,75,74,69,71,65,69,73,64,61,92,152,148,96,53,37,53,69,73,72,102,95,68,56,27,19,16,22,24,19,24,20,24,21,22,20,25,24,18,24,17,19,21,21,21,18,18,19,21,20,21,24,15,20,23,19,21,23,17,21,21,20,24,21,21,19,25,19,20,23,17,24,20,17,20,21,21,23,20,22,21,19,19,17,21,19,18,25,25,77,101,51,20,12,16,22,18,21,22,19,23,20,22,25,20,18,21,21,18,22,23,25,22,19,23,20,18,21,19,21,21,19,17,17,22,17,23,24,19,19,23,20,22,21,19,30,35,31,31,30,26,31,31,30,29,29,32,28,29,21,17,20,18,20,19,20,24,23,21,19,20,19,20,24,23,18,19,20,35,79,88,61,29,15,19,17,19,18,25,18,21,23,29,47,31,22,23,17,21,23,19,21,21,21,19,22,23,21,22,21,23,21,21,21,24,21,21,23,22,23,21,21,24,24,18,25,22,19,23,17,24,20,21,19,21,19,21,24,21,21,21,21,25,24,21,25,23,23,23,23,22,24,25,31,50,53,59,57,53,56,48,36,35,26,16,18,15,18,15,50,45,16,46,43,34,39,38,63,47,46,66,65,77,105,96,77,69,46,57,69,71,91,84,50,45,44,43,46,50,48,44,39,37,20,23,66,115,141,145,129,93,47,29,171,232,241,240,158,69,12,5,14,13,14,14,15,15,16,17,16,15,131,117,80,76,111,125,158,169,238,164,105,208,241,172,100,84,29,74,130,164,197,192,205,248,206,174,202,213,237,236,194,130,86,202,205,86,85,52,90,128,81,87,84,64,63,54,56,62,92,130,117,88,49,49,72,43,27,17,19,33,18,21,17,42,57,90,118,116,110,122,146,148,173,151,155,169,120,146,166,114,48,27,48,73,120,87,57,76,87,160,197,96,68,83,85,104,110,95,59,60,81,96,106,87,72,60,76,146,148,110,142,167,133,141,115,92,74,65,84,75,105,102,87,102,76,71,69,88,134,107,80,106,83,52,95,106,127,183,236,131,19,71,101,139,163,154,144,99,61,131,169,159,153,177,253,253,252,240,235,228,174,141,142,162,90,15,9,12,30,38,39,44,38,39,40,35,39,37,42,49,40,37,38,33,83,120,93,47,12,13,11,24,67,89,114,91,41,36,37,42,74,115,151,194,219,239,251,251,253,253,252,252,252,252,252,252,250,250,246,246,227,197,180,190,174,147,139,107,98,86,27,4,10,30,56,41,28,53,76,90,93,78,60,42,51,42,23,17,28,44,48,66,87,114,153,131,125,170,118,60,43,36,136,215,240,237,203,175,111,98,121,88,83,85,67,60,58,68,87,91,109,110,115,129,136,123,106,110,44,50,49,54,110,74,72,66,62,42,60,124,73,37,35,66,81,59,60,55,63,64,63,73,64,66,76,71,44,50,67,46,99,149,149,145,133,141,139,137,61,60,128,111,101,108,98,80,69,55,67,61,74,84,83,89,83,88,97,92,67,39,23,21,18,28,35,38,51,63,74,56,79,106,72,28,15,26,56,62,43,39,38,51,49,63,69,70,79,79,84,90,91,78,59,35,25,18,16,17,23,39,65,81,92,96,102,105,84,91,84,72,75,66,76,77,75,74,68,67,59,52,93,163,173,113,43,34,67,78,83,79,71,56,46,29,16,23,22,24,24,22,26,19,23,27,21,20,23,18,18,23,21,22,18,19,20,19,24,20,19,21,24,19,20,24,21,21,21,20,22,23,19,22,23,17,21,19,18,20,18,21,24,21,21,19,19,24,20,19,23,20,25,19,21,19,19,19,24,24,60,106,66,24,12,15,19,22,21,19,18,19,24,19,22,23,19,21,21,22,17,22,21,19,26,19,21,21,19,20,22,21,19,20,19,19,19,19,22,21,18,17,19,19,22,22,32,29,28,32,27,28,32,27,30,30,30,30,24,24,22,20,22,19,18,23,21,19,26,21,20,21,21,17,20,20,22,20,20,23,41,83,91,60,26,15,18,23,21,23,19,22,26,32,49,30,20,26,16,21,23,21,26,21,22,23,17,26,21,23,26,19,23,18,23,25,21,21,19,24,21,21,23,23,22,16,22,24,21,23,25,23,23,24,21,21,23,23,24,23,24,21,21,23,26,25,24,22,24,26,22,23,21,21,36,53,63,62,61,51,38,31,17,15,15,16,16,16,16,19,65,51,32,57,31,17,25,28,57,43,58,81,72,77,56,50,49,54,37,39,56,48,56,69,55,51,73,84,91,103,98,71,50,39,36,81,139,206,227,226,218,191,132,109,228,238,241,234,178,99,9,4,13,11,14,13,16,14,16,17,15,15,214,175,89,50,101,142,191,214,249,191,156,241,251,233,188,155,76,90,141,171,165,127,159,221,162,120,160,185,229,188,111,97,92,194,174,101,119,81,116,126,104,138,133,123,123,120,130,125,134,141,100,89,71,57,68,54,54,56,62,72,54,66,70,64,69,77,86,97,129,159,181,163,155,132,111,120,83,84,107,108,93,69,53,53,69,57,53,61,61,98,114,46,63,90,98,129,153,122,59,62,71,77,94,68,67,73,86,132,134,103,131,178,122,137,136,123,113,85,86,87,129,124,92,111,63,51,55,110,161,98,72,29,39,65,55,56,45,54,27,8,13,18,31,77,106,96,77,31,4,23,34,28,25,26,77,105,110,112,159,177,131,91,90,148,95,10,6,10,14,21,36,39,32,34,32,32,38,36,50,59,41,36,29,12,83,139,134,109,81,87,92,122,158,174,192,205,220,245,250,250,252,252,253,253,252,252,253,253,249,249,243,237,212,177,151,150,141,105,89,91,42,7,8,17,19,29,68,60,74,73,20,5,31,77,72,38,21,27,42,47,49,50,54,51,46,57,28,17,12,63,106,119,140,160,182,141,130,167,128,71,46,26,93,139,119,97,75,67,57,59,69,61,66,108,105,81,88,117,141,164,179,184,188,183,120,156,125,125,69,73,65,42,73,55,65,56,55,59,39,50,61,63,36,55,75,61,59,62,79,98,97,98,99,95,101,92,57,48,69,45,67,112,125,129,126,131,143,144,84,87,113,79,82,78,72,72,57,60,64,71,81,78,89,85,87,87,64,43,31,26,29,37,33,38,56,80,108,124,130,136,134,145,124,57,50,75,81,60,38,33,40,48,47,59,62,70,74,78,85,80,59,37,24,16,20,16,22,41,54,77,90,99,108,101,96,86,84,81,76,73,69,75,77,77,70,64,69,66,63,63,55,95,170,179,119,58,48,74,68,39,29,32,31,22,22,23,22,24,23,30,19,23,30,23,23,17,25,19,17,25,18,21,23,23,24,20,21,22,26,22,17,23,23,19,19,20,23,19,18,23,20,24,22,21,20,22,19,20,20,22,21,19,21,21,24,18,23,18,22,21,17,21,22,21,22,23,18,25,38,83,69,26,22,14,19,19,20,17,19,27,19,23,19,19,22,20,24,18,20,23,22,22,20,20,22,20,23,24,21,18,19,18,18,20,18,17,24,20,19,20,18,22,17,24,31,29,29,26,29,27,28,28,32,29,29,35,30,27,17,19,22,16,22,18,18,24,21,24,24,21,22,21,23,20,22,22,20,22,22,52,90,89,53,22,18,17,21,23,18,22,21,39,53,25,21,25,19,19,21,21,24,21,24,22,20,24,18,22,22,25,21,19,24,18,24,21,21,22,22,28,22,22,22,21,25,20,18,26,23,24,22,21,26,22,24,19,22,24,24,28,23,21,24,26,24,21,23,22,21,26,24,23,37,61,69,71,57,31,22,22,26,32,27,25,25,19,18,27,84,70,57,66,32,30,36,36,50,39,58,83,80,72,60,56,57,52,34,42,55,49,62,64,49,98,165,200,222,236,230,208,182,167,154,172,201,234,229,227,205,187,154,147,241,245,238,229,205,111,6,3,9,12,14,12,14,14,15,15,15,16,246,245,174,122,167,205,252,252,251,244,232,249,253,253,246,244,159,139,152,165,160,127,143,173,127,116,135,139,160,133,109,117,126,166,150,130,147,122,146,139,114,154,165,172,203,216,235,235,223,212,195,195,198,208,216,204,213,214,219,225,220,223,219,224,212,201,196,192,202,212,216,203,181,169,184,186,135,81,54,55,79,80,47,44,72,63,88,92,78,127,143,89,103,132,141,155,146,146,131,90,54,41,61,66,72,71,73,116,98,87,129,137,111,116,123,154,133,105,112,92,97,82,55,79,49,32,34,62,101,48,42,44,57,75,52,60,58,42,33,22,22,31,30,36,30,24,30,28,27,26,28,27,26,24,27,24,29,41,61,74,57,55,81,121,67,14,20,14,16,17,20,22,17,20,25,24,29,19,73,83,32,37,41,92,187,213,219,232,245,247,250,250,252,248,252,252,248,248,246,245,233,199,223,215,174,160,134,122,118,107,92,71,53,29,10,18,24,15,13,16,15,13,13,13,14,14,15,14,14,14,14,12,18,25,29,55,78,88,92,102,97,93,94,71,73,57,35,15,11,27,21,25,37,44,36,14,17,27,24,15,20,14,49,73,61,55,53,101,130,151,159,134,135,145,106,52,50,61,80,85,78,78,77,71,66,64,52,59,42,47,45,39,48,55,67,69,103,80,19,76,143,89,45,104,104,53,47,46,53,51,56,61,48,53,52,47,45,44,42,41,42,62,95,98,108,125,140,148,110,91,83,76,94,89,82,71,65,72,80,73,85,89,89,91,66,48,30,31,42,41,42,50,65,88,104,127,143,148,149,140,143,139,124,105,85,88,77,59,46,29,36,41,46,73,76,74,77,69,60,42,25,18,21,16,24,33,53,69,76,96,101,99,98,89,87,84,66,77,77,78,85,75,73,64,64,64,67,70,66,65,60,49,95,170,182,144,81,41,40,34,23,22,24,21,24,21,24,30,24,24,22,24,28,25,23,23,25,22,21,22,20,22,21,21,26,19,19,22,21,26,20,24,22,17,19,21,19,20,24,23,18,22,24,19,21,18,20,22,23,20,17,23,24,19,23,24,20,21,23,19,23,20,22,26,19,24,18,21,26,71,77,33,22,15,19,21,19,23,22,19,18,18,19,19,21,27,20,19,21,19,24,19,22,19,18,25,21,17,21,19,19,18,18,21,16,19,24,16,23,23,17,21,19,24,33,27,27,26,27,29,30,29,31,34,26,29,32,23,19,17,19,20,20,21,20,21,24,21,21,19,19,22,25,22,17,22,19,24,24,21,56,95,87,52,23,19,21,16,23,21,22,38,36,21,24,17,18,22,22,26,24,19,19,19,20,23,19,26,23,23,22,18,24,26,18,22,21,21,23,22,20,21,23,23,22,23,21,20,21,21,26,20,23,18,20,25,23,25,21,22,20,24,29,20,21,24,20,21,27,29,21,23,44,69,84,89,96,116,150,171,181,189,184,184,176,154,136,161,192,157,157,161,126,107,121,141,126,72,66,89,84,94,78,67,61,55,41,41,56,51,65,61,55,120,184,216,246,246,247,247,241,230,218,222,241,245,215,198,172,155,129,135,220,238,228,233,224,111,4,1,7,11,14,11,13,14,15,15,15,15,247,247,246,197,236,245,249,249,252,240,218,250,252,252,248,248,188,138,159,151,148,136,147,152,131,142,149,137,143,129,120,142,150,169,168,184,198,192,209,184,177,206,230,248,252,252,252,252,253,253,253,253,252,252,252,252,252,252,252,252,253,253,252,252,252,252,253,253,252,252,252,252,246,251,253,253,224,124,81,69,76,100,94,90,118,120,153,165,152,176,186,124,146,200,209,217,193,190,140,115,59,37,43,57,74,70,63,92,99,132,152,166,127,107,118,140,156,124,104,83,70,66,72,122,92,76,68,66,77,60,122,127,162,194,159,214,247,247,247,230,225,228,239,239,224,216,236,237,239,243,230,229,228,220,217,142,181,181,193,188,184,185,193,210,196,208,227,230,232,228,235,235,229,230,151,223,217,147,247,247,245,247,252,252,253,253,252,252,253,253,253,253,252,241,223,213,194,191,181,184,156,49,65,128,139,135,101,72,48,27,14,10,14,13,14,19,26,36,51,68,71,66,63,68,68,125,73,76,71,84,47,13,29,53,93,132,134,113,97,82,66,42,35,37,30,33,27,23,28,29,26,25,24,34,33,26,36,67,87,41,20,18,101,153,130,103,65,66,75,85,89,73,67,54,15,8,13,11,14,12,13,13,13,14,75,26,55,81,46,34,41,38,54,92,141,144,152,102,36,116,160,78,61,93,65,42,46,39,45,49,47,52,42,44,46,37,43,34,34,38,49,70,80,87,95,103,120,129,94,76,66,67,98,98,90,78,71,77,84,91,98,98,71,47,42,38,40,36,37,51,71,88,110,122,129,137,137,134,126,124,117,99,90,76,73,72,72,66,42,38,41,42,48,66,79,79,65,41,27,22,21,22,19,29,56,67,80,80,80,94,90,97,95,81,75,72,78,78,87,92,68,74,67,63,71,73,81,66,71,77,60,66,60,96,180,210,163,62,26,33,24,20,19,24,22,24,27,23,31,29,27,29,27,23,28,23,21,26,21,20,21,24,27,19,21,24,21,18,21,27,29,29,24,21,22,19,23,27,22,22,22,19,17,22,24,21,24,21,21,19,24,24,22,25,23,19,23,18,22,21,19,23,20,24,19,18,20,22,16,66,81,33,25,16,17,23,17,23,21,16,22,21,21,23,21,21,22,17,21,21,21,26,19,19,23,16,22,22,19,20,20,22,16,18,19,19,26,19,23,20,16,17,23,23,32,34,22,26,30,32,30,29,29,33,28,27,29,25,22,18,19,18,20,24,18,19,21,21,18,18,22,19,21,19,19,21,20,24,19,21,31,62,99,84,45,24,18,18,24,21,19,35,34,24,19,21,22,18,22,23,25,22,24,22,20,25,22,23,19,19,21,21,29,21,20,21,22,26,23,22,23,27,21,22,23,22,23,23,22,19,17,17,24,27,23,24,24,24,24,17,25,25,22,28,19,24,23,22,25,21,27,31,44,64,70,113,188,245,252,252,252,252,253,253,252,252,252,252,251,251,250,250,236,228,248,248,239,155,94,108,89,88,76,50,56,58,47,38,53,56,71,65,77,134,149,152,189,242,245,243,234,235,237,241,245,241,204,196,183,170,137,155,226,228,227,243,237,108,1,1,8,11,10,12,13,12,14,14,15,14,246,246,249,218,244,246,240,240,240,129,118,197,207,237,237,236,144,108,143,134,139,132,144,155,147,159,159,155,160,161,165,184,212,243,250,250,252,252,252,252,253,253,252,252,253,253,253,253,253,253,253,253,253,253,252,252,253,253,253,253,253,253,253,253,252,252,253,253,252,252,252,252,252,252,253,253,247,192,144,119,125,157,162,155,165,167,210,229,183,171,136,100,156,202,223,237,210,185,118,76,80,79,74,54,79,86,93,124,105,106,133,147,134,134,94,111,137,110,82,71,70,77,101,192,174,134,136,123,142,111,155,164,207,242,215,252,252,252,253,253,252,252,253,253,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,252,252,253,253,253,253,252,252,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,252,252,253,253,252,252,253,253,252,252,253,253,251,76,100,237,233,218,158,121,69,48,78,99,141,173,204,237,251,251,252,252,253,253,252,252,252,252,252,252,252,250,196,61,96,223,216,177,97,63,67,57,61,74,101,141,181,213,249,249,252,252,253,253,252,252,253,253,252,252,251,209,76,23,110,165,110,62,11,17,24,22,46,59,83,113,140,162,177,167,168,164,148,165,138,121,125,136,120,106,64,30,49,37,39,97,124,103,103,79,46,69,78,49,50,56,51,60,65,71,80,85,105,112,117,120,101,92,71,30,63,66,36,69,75,71,77,85,98,90,81,61,55,66,80,82,81,74,69,81,95,97,76,51,41,36,33,29,33,50,73,83,97,112,116,122,127,125,121,120,119,102,85,66,69,66,59,73,75,63,48,36,45,45,42,66,63,49,34,17,21,19,18,31,51,66,80,83,90,95,81,91,81,78,77,67,71,73,78,84,79,76,72,64,63,68,76,70,74,75,74,77,73,74,78,68,74,162,177,63,27,27,20,26,18,21,20,20,25,24,24,26,25,25,29,26,25,24,24,24,25,22,19,24,22,23,20,23,23,18,28,34,19,32,36,21,21,24,29,24,20,24,21,21,26,26,28,19,21,24,19,24,23,21,24,21,25,21,21,26,21,23,19,18,21,21,21,22,19,21,24,46,85,47,18,21,17,20,20,24,19,21,27,21,18,20,22,21,18,23,25,20,24,23,21,20,19,21,22,21,19,17,20,19,21,21,19,21,22,18,23,19,21,23,21,31,30,30,28,25,30,26,31,35,31,27,23,30,29,27,25,18,19,19,20,19,20,19,20,22,24,21,18,21,20,21,21,21,21,22,19,25,25,23,67,100,80,43,20,19,18,17,27,45,33,19,22,21,19,23,23,25,23,21,28,23,23,24,21,22,22,24,26,20,18,25,20,24,24,23,23,21,22,23,22,18,21,23,21,24,21,21,24,22,23,23,24,24,25,22,17,22,22,25,23,23,23,19,27,23,25,20,23,25,29,45,33,112,234,246,250,250,253,253,253,253,253,253,253,253,253,253,253,253,251,251,253,253,247,190,128,116,60,41,21,14,39,57,52,48,51,67,85,87,112,141,120,83,91,140,181,191,213,237,249,249,248,248,238,242,238,230,217,231,248,244,241,244,236,105,1,1,7,11,10,12,13,12,14,14,13,13,247,247,242,191,207,244,227,193,111,37,68,150,159,163,173,174,109,105,140,136,153,144,150,165,165,169,163,165,183,218,242,251,238,236,230,210,236,244,241,241,231,230,217,213,213,209,215,213,209,208,206,207,210,216,151,217,211,211,210,200,200,198,181,179,156,173,201,199,202,211,215,200,189,208,208,194,160,148,131,112,126,158,144,128,146,124,167,156,124,104,74,67,101,114,122,134,118,88,68,37,78,106,103,64,74,98,109,137,90,71,87,90,108,97,51,82,94,67,74,71,71,70,81,149,136,113,113,85,130,109,116,121,136,144,129,229,237,236,207,174,232,196,138,211,227,184,234,217,235,239,234,241,242,250,252,252,252,252,253,253,252,252,253,253,252,252,253,253,252,252,250,250,253,253,252,252,253,253,252,252,252,252,253,253,252,252,252,252,252,252,252,252,252,252,252,252,246,246,231,229,204,42,71,176,195,214,199,216,239,252,253,253,252,252,252,252,253,253,253,253,252,252,252,252,252,252,249,249,231,226,146,17,86,193,204,189,174,200,237,249,253,253,252,252,253,253,253,253,253,253,252,252,253,253,252,252,246,245,251,150,35,12,81,132,110,146,178,213,239,247,252,252,253,253,253,253,253,253,252,252,252,252,249,194,158,147,98,85,46,41,52,33,41,49,55,54,53,57,60,78,77,81,95,88,86,104,102,99,110,118,133,144,151,141,79,104,68,32,71,53,32,59,68,87,99,100,90,79,83,78,83,95,97,92,81,86,86,85,75,55,40,29,23,23,34,51,68,84,95,105,113,108,115,114,114,112,107,99,78,63,44,49,66,61,66,72,77,67,45,42,43,37,41,44,46,34,24,30,22,32,48,64,81,89,90,92,93,87,80,88,78,66,69,73,77,75,66,66,57,59,53,63,73,64,69,69,70,69,76,80,78,81,61,44,23,23,58,50,33,29,23,22,24,26,20,21,21,25,33,22,26,30,24,22,25,27,28,26,23,23,21,19,19,25,22,22,22,29,33,23,23,26,20,20,26,24,23,24,22,20,19,24,26,28,20,21,26,18,23,23,31,19,25,25,20,25,19,26,23,21,22,17,20,23,21,23,20,24,27,37,84,62,26,21,21,24,21,22,24,20,21,26,21,24,23,24,22,21,27,22,21,26,27,24,23,21,19,17,19,24,16,16,22,21,17,20,22,19,19,20,17,17,22,24,34,32,29,31,27,30,30,32,32,27,29,31,29,28,24,22,19,21,19,20,20,20,18,19,21,23,22,20,20,19,23,21,19,24,25,22,22,19,36,76,100,76,34,20,19,17,29,45,27,19,24,20,21,19,25,19,23,24,19,24,21,24,24,23,21,24,20,22,23,22,27,25,25,17,23,25,17,23,21,22,21,20,21,18,22,23,21,22,19,24,26,21,23,24,21,21,27,23,23,27,24,21,23,25,23,24,23,29,25,30,19,111,217,230,242,229,218,217,223,225,219,226,237,235,222,240,246,224,227,249,252,252,226,179,156,112,59,53,34,16,39,57,63,55,69,91,102,104,112,125,98,66,50,79,152,174,221,243,251,251,251,251,253,253,252,252,253,253,250,250,244,244,236,105,2,1,7,11,12,11,12,12,14,14,15,14,244,244,243,147,100,125,113,133,87,17,79,170,224,237,215,200,152,134,151,160,191,172,153,165,163,168,178,199,223,252,246,246,219,150,101,35,65,151,122,99,71,35,21,7,14,12,14,21,16,12,15,15,15,23,31,29,36,39,39,26,23,29,36,50,23,12,14,19,45,79,81,29,6,33,71,64,65,78,85,87,83,77,54,53,74,74,71,55,30,51,52,45,53,41,43,45,31,45,38,49,68,78,93,81,76,81,102,108,89,88,98,94,80,76,53,66,71,79,86,76,70,56,50,65,46,45,37,37,78,61,69,60,48,51,37,83,81,30,12,19,40,23,24,68,89,112,140,147,169,165,172,203,208,235,250,250,249,249,248,248,242,238,222,208,199,192,184,183,179,173,118,67,107,162,178,193,174,136,169,208,215,209,203,202,189,176,165,151,137,131,128,117,110,103,85,75,64,66,66,81,82,15,30,74,117,196,228,243,245,245,246,246,245,245,241,238,228,216,200,189,182,169,152,131,116,105,100,70,46,58,48,4,44,177,236,250,251,251,252,252,251,251,250,250,248,248,244,244,234,227,214,191,167,160,136,105,69,38,90,63,15,1,91,238,253,253,252,252,252,252,252,252,252,252,253,253,251,251,244,242,229,227,173,81,48,46,61,71,49,32,40,37,90,125,88,51,47,63,71,85,84,82,89,76,77,77,56,53,48,46,51,47,52,53,50,63,61,46,71,59,44,86,129,143,131,122,104,84,84,80,110,128,130,116,94,79,54,42,32,23,27,24,35,51,66,84,94,108,120,112,108,112,111,104,100,96,77,69,57,45,55,51,74,77,63,74,74,68,49,44,46,39,33,39,51,33,44,64,66,82,95,104,108,101,97,99,84,87,79,79,74,77,81,84,81,61,57,52,57,53,52,58,63,66,66,70,75,73,81,81,64,47,29,18,18,16,18,33,42,30,16,26,25,27,26,20,23,24,26,23,26,23,24,22,21,36,39,24,24,27,21,25,22,24,25,19,31,31,19,20,24,22,21,24,29,28,21,19,26,19,24,23,22,23,24,20,20,29,24,23,23,28,23,17,25,23,21,24,21,25,20,21,28,19,22,22,37,42,20,27,85,76,32,19,28,41,23,25,31,29,24,21,31,28,23,19,23,27,22,22,24,29,24,27,24,17,21,24,20,17,19,18,18,18,19,20,21,16,22,21,21,18,19,32,31,31,31,27,27,31,30,28,27,33,31,25,28,25,23,18,17,23,19,20,22,18,22,21,21,23,19,20,21,21,25,17,22,26,21,23,21,26,21,34,84,100,76,35,19,19,27,45,24,19,22,20,22,22,24,27,19,21,24,21,22,23,24,24,25,18,22,26,22,26,22,23,27,24,19,26,22,19,23,25,26,20,23,24,19,22,20,22,24,21,23,24,23,21,24,19,24,23,28,21,23,27,24,21,20,25,24,19,24,29,22,134,204,190,195,180,178,188,196,199,202,212,221,214,203,212,204,189,195,189,203,193,160,172,158,129,135,158,153,118,82,81,73,63,76,94,93,95,100,103,114,101,67,126,218,210,235,247,250,250,251,251,252,252,252,252,253,253,248,230,221,244,237,107,4,1,6,10,12,12,12,13,14,14,15,15,183,200,197,130,113,121,127,142,97,63,117,173,214,250,250,250,237,184,188,201,235,191,133,148,146,163,197,225,232,216,224,221,144,103,89,22,23,59,32,15,16,14,15,13,14,14,14,15,14,14,15,15,25,14,15,16,16,17,23,22,24,34,52,96,42,9,19,11,39,74,66,25,7,34,68,56,61,88,104,92,63,54,29,39,67,70,63,39,42,47,51,54,50,46,54,59,50,53,53,62,66,73,79,73,77,71,89,114,93,79,80,77,81,71,63,79,72,73,83,60,45,30,39,61,26,19,18,27,74,45,41,42,31,33,33,61,34,17,22,38,89,54,48,104,141,199,227,238,249,247,245,245,239,238,226,213,204,188,175,157,139,116,103,92,91,93,105,115,122,110,39,1,24,85,102,94,46,2,32,44,45,45,38,35,27,21,16,22,19,15,15,14,15,16,21,44,59,79,88,109,122,34,23,15,36,113,111,103,87,84,86,78,70,59,46,33,34,27,27,24,12,15,15,24,43,46,54,21,46,105,61,8,46,134,173,158,153,154,139,128,117,122,86,71,62,44,37,32,24,14,12,15,15,16,29,48,21,18,96,65,34,11,74,203,217,154,176,134,187,176,171,149,129,131,119,113,126,70,51,38,19,11,12,25,36,10,81,132,63,35,48,43,110,150,100,49,29,37,47,47,47,47,43,46,43,48,45,50,47,51,72,76,92,101,97,137,129,84,140,83,49,62,116,111,86,67,58,40,46,59,80,104,90,65,40,31,24,19,22,22,34,48,66,82,93,105,114,120,114,115,113,107,105,95,85,69,60,61,56,60,60,60,82,78,74,79,81,75,45,43,50,40,33,44,52,29,69,107,114,114,108,116,105,93,94,94,80,74,78,78,76,84,77,66,64,53,55,57,54,59,58,60,67,69,71,67,75,87,75,53,34,19,18,20,17,16,16,25,39,37,30,21,23,25,26,19,21,29,22,25,28,19,24,26,22,24,22,24,22,21,27,23,23,24,25,33,27,24,20,22,25,21,29,24,32,45,32,21,22,25,27,21,22,24,24,29,22,22,29,24,23,24,27,22,24,24,21,25,24,21,25,31,33,23,19,22,27,25,24,21,68,87,38,23,30,29,19,25,37,21,19,26,29,25,16,23,24,16,21,24,23,34,28,22,25,24,22,23,24,20,17,19,22,17,19,24,18,21,23,16,17,21,29,30,29,29,24,30,29,31,31,25,30,32,24,31,27,26,21,19,24,19,18,21,26,22,17,22,22,23,18,21,24,22,25,22,27,24,19,21,30,23,19,25,43,88,98,70,33,14,33,40,29,23,17,21,22,21,26,23,24,24,22,21,22,24,23,22,22,23,21,19,24,23,22,27,25,21,26,22,22,25,22,24,21,19,23,21,25,20,23,19,24,30,21,24,18,28,29,21,25,19,26,25,21,29,21,24,21,22,27,22,30,22,32,151,176,153,160,154,162,165,173,177,174,181,193,189,184,189,187,173,157,135,132,141,130,144,122,89,126,185,205,151,87,64,42,38,57,64,56,52,61,89,111,104,103,200,249,232,231,246,249,249,250,250,249,249,251,251,253,253,237,183,191,241,238,107,3,2,7,11,12,12,14,12,13,14,14,14,230,243,250,250,250,250,249,249,237,201,227,243,252,252,252,252,251,251,246,245,240,180,125,143,144,169,222,250,223,181,166,198,196,196,193,132,125,139,105,112,129,148,122,80,96,77,94,116,102,93,92,101,88,93,96,109,114,107,121,112,128,141,149,175,97,78,99,84,95,109,108,58,45,85,98,68,88,110,120,117,90,78,57,60,72,84,77,62,67,71,67,64,51,59,76,98,87,74,55,57,77,69,65,60,56,51,69,87,81,57,41,35,24,33,31,47,48,46,57,39,35,24,46,77,54,64,35,59,129,103,127,141,149,153,130,170,165,125,118,134,183,141,134,198,229,245,242,234,220,178,169,155,118,129,131,126,116,106,104,94,85,82,79,78,76,65,58,56,59,61,28,4,24,60,49,33,19,9,15,14,16,14,14,22,38,57,71,83,87,90,87,88,88,92,94,99,97,98,95,103,112,47,15,14,17,42,23,14,14,12,15,14,15,15,17,34,53,72,87,81,76,84,101,109,103,102,110,67,73,131,97,41,16,39,32,10,17,14,15,15,15,15,14,16,18,31,36,43,48,55,67,48,8,46,100,117,72,33,107,102,57,33,14,54,41,34,22,11,21,12,16,16,14,14,14,15,14,16,13,28,30,20,19,53,59,23,81,108,62,48,49,35,53,61,51,49,39,43,50,56,58,66,80,84,99,109,120,141,144,155,155,148,146,136,132,122,116,96,75,46,37,31,33,52,49,48,31,30,46,46,43,41,38,27,26,23,20,25,38,55,69,79,97,99,105,116,108,114,114,112,104,98,88,68,69,59,50,65,68,65,65,72,93,86,79,101,86,51,38,34,38,41,34,43,50,30,78,106,106,113,98,96,96,91,87,84,68,83,82,87,81,69,73,59,57,46,53,57,62,64,66,69,67,71,70,82,74,50,37,21,17,22,16,18,21,17,16,33,39,38,33,22,24,21,23,22,22,21,27,24,21,22,28,24,24,23,22,29,24,24,19,24,27,23,28,28,24,28,25,27,24,23,29,22,36,41,24,22,21,29,24,21,24,25,24,24,22,23,26,24,27,24,22,24,26,23,25,23,28,28,30,33,30,33,23,22,25,20,27,20,46,92,50,28,22,15,24,27,22,23,19,24,24,21,24,23,21,21,22,31,32,26,30,29,25,24,24,32,27,17,20,19,19,19,17,24,19,19,22,24,17,24,26,27,32,30,31,31,25,31,33,32,28,27,35,28,23,26,21,23,20,19,24,19,19,21,23,20,22,23,18,19,17,19,21,20,16,23,22,19,21,23,22,19,24,44,89,97,66,27,33,39,21,20,20,18,23,24,23,25,24,24,25,22,23,23,23,23,22,23,20,22,20,23,24,26,24,23,24,17,23,22,22,25,17,21,25,25,20,24,22,21,24,20,24,22,22,27,21,22,26,21,23,30,26,23,26,22,22,23,24,23,29,22,41,116,118,120,129,122,130,133,133,128,120,121,128,137,138,142,145,134,128,106,113,117,99,102,61,27,61,107,131,89,46,73,66,25,21,24,16,16,26,49,66,71,113,226,248,210,228,245,248,248,250,250,249,249,251,251,251,251,214,173,184,217,231,110,3,2,8,12,12,13,14,13,14,15,15,15,252,252,252,252,252,252,250,250,249,241,251,251,252,252,254,254,251,251,248,248,240,163,115,141,146,185,248,250,246,179,137,219,252,252,248,215,202,243,196,190,235,239,173,139,174,165,185,234,242,225,217,225,160,226,246,253,246,234,249,249,252,252,251,251,167,137,179,156,134,128,119,59,39,91,107,83,96,125,142,137,126,107,66,57,63,70,74,78,75,62,55,59,65,54,71,90,76,55,51,51,65,66,53,42,41,38,61,70,63,61,51,38,25,35,32,35,55,85,108,113,130,99,114,156,135,138,109,145,227,196,207,206,214,200,156,205,178,122,97,102,105,85,126,162,170,177,155,131,122,39,25,48,32,84,83,82,92,82,90,89,97,91,83,78,63,42,21,12,14,15,22,17,19,66,81,105,56,16,97,123,126,125,128,142,144,157,158,158,156,149,144,141,120,105,90,72,47,35,33,25,52,35,39,26,37,112,119,125,115,120,124,125,127,128,145,151,171,171,171,155,139,125,111,95,70,61,67,39,64,81,45,47,29,58,66,77,91,86,85,95,95,111,122,127,145,151,151,136,133,117,110,86,36,66,78,78,35,41,100,60,42,37,17,57,66,78,59,46,50,38,14,19,23,21,19,26,39,35,34,43,44,41,45,51,49,36,54,50,44,49,45,41,44,50,67,88,103,128,134,147,153,155,154,150,150,147,141,133,91,100,81,56,45,36,29,28,27,27,23,21,41,33,44,76,61,47,36,30,41,36,36,35,21,21,20,29,38,58,76,89,101,103,114,105,107,107,107,109,104,98,80,73,60,55,58,56,62,63,66,67,78,94,105,105,88,65,42,24,21,21,23,40,38,65,63,66,100,106,104,102,88,92,84,75,71,74,79,84,84,77,65,55,55,56,53,57,57,55,64,65,67,75,70,68,65,52,40,22,18,19,17,17,19,21,19,26,29,39,38,34,33,28,39,25,21,27,24,24,25,24,21,25,22,24,23,22,31,24,22,28,24,24,27,27,26,24,21,26,21,24,27,20,24,20,24,24,17,24,24,23,25,23,22,23,25,24,24,24,23,23,28,24,23,29,22,23,24,25,23,29,27,24,38,33,23,25,22,23,24,25,41,91,66,28,18,20,26,21,27,20,23,25,25,26,23,29,19,22,29,27,29,25,31,28,21,24,32,28,19,22,18,16,19,19,18,21,21,19,18,20,16,21,24,32,29,30,30,31,33,29,30,34,30,29,32,28,24,26,19,21,24,18,23,19,21,21,19,19,19,20,22,22,18,24,21,16,23,24,22,19,21,19,23,25,18,23,50,94,100,60,45,33,20,21,19,23,19,21,23,21,19,22,21,24,22,21,24,19,22,26,24,24,25,19,25,24,22,24,22,29,22,20,22,19,21,19,22,21,25,21,24,24,22,24,22,27,20,21,26,21,23,22,21,26,24,20,23,23,25,19,25,25,24,21,48,119,122,135,130,122,137,134,124,122,125,125,125,122,124,130,136,131,132,128,125,123,112,105,96,89,88,105,114,91,108,138,116,79,63,80,94,94,92,88,91,98,146,235,243,218,248,248,251,251,251,251,251,251,251,251,249,244,216,202,202,199,200,112,6,1,7,11,14,12,15,13,15,15,15,15,148,157,179,189,200,175,163,186,135,94,138,173,184,159,150,192,217,229,245,240,233,153,115,133,118,133,160,210,199,131,95,127,195,210,218,117,112,162,110,104,145,150,95,94,151,118,152,214,217,188,169,199,180,194,210,225,206,170,227,234,245,245,246,246,120,108,157,113,118,126,122,51,21,92,108,73,67,90,118,128,119,100,66,55,44,53,67,82,87,58,51,57,50,51,44,40,23,39,37,39,50,47,54,48,45,36,89,103,117,151,151,174,143,128,123,104,139,192,217,229,245,175,158,169,127,170,120,124,219,161,113,107,130,120,102,113,63,51,47,14,29,14,61,111,71,90,97,105,100,27,26,26,31,51,29,29,25,27,32,51,68,75,88,96,106,110,113,114,117,129,103,38,47,142,182,199,127,56,130,178,171,144,126,109,94,92,84,83,80,79,81,91,87,93,98,94,96,90,100,100,125,96,53,39,79,180,201,200,190,179,171,151,132,125,123,125,119,101,98,85,71,63,54,53,56,62,75,47,61,96,63,44,25,96,175,179,183,164,155,156,141,135,130,128,130,118,105,88,64,53,57,45,22,51,79,92,56,54,143,136,66,26,27,155,186,173,131,101,125,83,80,63,68,66,45,46,38,39,49,55,44,50,52,53,55,86,122,112,110,123,116,61,78,128,153,159,150,154,131,119,111,86,62,47,44,42,29,29,21,24,22,17,22,16,17,17,14,16,24,24,44,44,53,69,57,57,29,30,36,24,28,24,21,28,35,52,69,83,111,115,111,107,108,108,107,107,99,103,90,70,60,61,58,64,66,57,69,72,70,78,87,95,109,78,44,28,17,24,21,18,40,55,66,94,104,101,112,106,103,103,79,79,75,70,78,78,75,74,69,63,57,50,56,58,60,53,57,60,65,66,68,74,67,57,37,20,20,21,15,17,17,19,23,27,27,29,40,47,37,37,39,76,94,37,23,23,20,26,22,21,26,24,24,24,27,27,21,22,24,22,21,31,28,24,25,21,21,31,24,22,26,20,24,20,22,23,24,26,22,29,29,26,24,25,25,21,26,26,21,27,24,28,27,25,22,23,22,23,33,24,23,24,24,21,19,22,27,24,28,29,27,79,80,33,23,18,24,22,25,23,21,24,21,26,31,20,22,21,24,25,24,25,26,23,24,27,24,22,21,22,19,21,19,20,21,23,22,20,21,15,21,23,27,32,30,35,27,24,28,23,31,33,34,32,30,32,31,29,19,20,21,17,22,26,23,23,21,19,22,22,21,20,21,18,20,24,22,19,20,21,22,24,23,19,22,21,24,61,109,103,77,37,18,27,17,21,20,21,21,19,23,19,24,22,22,25,24,21,22,23,24,24,27,23,19,23,23,27,23,23,24,24,24,24,23,22,22,18,25,22,24,27,21,20,24,23,19,24,22,21,22,23,27,22,25,26,22,24,23,23,25,19,27,22,69,125,111,134,130,137,160,147,140,157,173,181,166,160,169,171,184,182,195,182,181,189,179,205,219,202,202,211,207,196,198,204,189,176,186,204,201,201,200,193,171,170,198,230,246,246,251,251,251,251,250,250,249,249,251,251,247,240,242,242,224,196,188,109,7,1,7,10,12,11,12,12,14,14,14,14,17,17,27,45,46,21,18,33,26,33,76,88,83,75,92,146,181,193,197,200,218,150,118,129,115,93,26,14,43,64,38,9,18,20,16,13,19,29,18,32,46,45,25,32,38,24,41,52,48,36,28,33,36,32,33,54,50,25,32,47,86,96,115,118,41,49,52,56,101,122,166,89,55,123,118,85,55,57,59,60,73,79,89,105,54,57,62,82,94,67,48,50,59,70,83,49,42,71,96,53,61,76,105,134,132,98,158,189,191,244,246,242,195,165,147,153,195,237,240,217,226,188,188,148,73,103,66,80,155,118,73,60,76,72,77,91,55,53,51,37,25,17,48,54,27,34,49,64,66,14,31,38,22,66,53,80,44,51,81,95,110,128,143,158,166,171,129,173,169,168,127,31,36,128,147,148,69,39,107,103,86,71,61,54,39,37,33,36,53,74,97,114,131,143,139,148,155,157,157,146,146,92,36,25,73,141,131,119,87,76,61,43,38,26,36,26,20,19,31,54,78,93,113,126,134,151,148,78,98,137,73,52,19,91,124,139,118,85,66,47,27,24,19,15,16,16,24,34,66,83,107,82,44,127,165,172,86,77,174,164,96,38,23,102,130,118,63,32,44,46,51,44,41,46,58,69,73,107,134,167,147,142,145,160,164,169,177,161,158,187,167,77,44,63,62,51,42,39,27,29,26,19,22,16,18,21,23,16,21,21,21,23,18,22,19,19,29,29,39,38,39,38,59,98,85,57,27,18,25,20,21,23,33,50,54,61,64,73,91,99,100,100,108,97,103,99,92,77,59,54,57,67,67,66,71,69,72,79,79,86,88,75,54,38,25,21,20,16,30,55,73,86,100,101,101,104,105,93,98,75,66,80,79,90,83,74,61,59,61,55,54,50,55,60,63,59,56,62,67,66,66,56,38,27,19,17,18,18,19,20,21,25,27,34,44,44,47,39,41,41,38,64,132,71,29,18,21,20,25,23,20,25,20,21,31,25,39,37,24,24,24,29,23,22,24,22,27,26,23,24,22,17,25,24,22,24,28,24,29,29,24,24,24,27,25,26,21,22,28,24,22,25,27,19,24,23,22,28,24,25,24,18,23,22,26,29,21,22,22,27,23,67,85,40,22,16,23,23,23,23,27,21,25,27,22,21,22,22,24,27,20,20,24,26,26,24,23,18,19,23,21,19,19,19,21,20,21,22,22,21,17,22,23,29,36,33,30,24,31,32,31,29,30,30,29,28,33,31,20,19,23,21,18,21,20,21,20,23,21,18,25,21,19,22,21,18,21,19,20,23,19,17,19,24,27,22,18,30,62,110,99,53,26,18,22,22,23,21,19,24,22,19,26,24,18,24,19,24,21,22,23,22,23,24,25,21,24,21,22,20,24,25,22,23,21,23,17,20,27,18,21,22,21,26,23,25,19,24,22,23,26,21,27,29,26,24,26,24,23,18,20,24,24,22,52,76,56,66,82,105,118,105,100,128,148,154,145,141,143,162,181,190,201,192,200,205,212,244,250,248,245,250,239,217,204,209,213,208,218,229,210,198,210,204,187,178,186,208,217,215,226,221,207,206,204,203,202,203,212,210,217,220,242,238,208,190,187,112,5,2,9,10,13,12,14,12,14,15,14,14,25,42,77,82,88,47,46,81,47,93,155,165,177,179,183,174,148,118,126,169,213,154,130,139,129,101,25,16,43,74,45,32,36,21,19,16,62,63,43,63,70,66,46,47,39,24,50,48,29,17,28,38,29,44,35,57,56,33,34,16,27,42,77,96,58,107,112,89,155,208,246,198,110,177,211,198,134,68,60,54,63,99,149,163,110,93,83,91,94,57,61,75,113,158,195,169,132,174,174,164,112,89,145,217,232,155,189,177,143,185,179,168,101,71,86,110,155,182,162,146,198,240,252,178,53,105,105,138,229,202,119,93,85,66,80,86,73,74,76,57,45,39,44,70,60,71,60,78,78,29,74,60,81,141,135,149,143,147,146,141,131,124,122,122,117,116,111,98,91,79,47,18,23,37,35,45,27,25,73,87,100,108,120,124,125,128,126,132,129,135,139,145,137,143,139,124,121,97,93,75,64,41,24,32,32,37,26,32,42,57,73,89,104,107,111,116,116,116,127,127,146,166,171,171,158,152,131,61,63,72,47,60,29,35,54,28,32,35,46,62,79,92,97,100,101,109,120,136,158,171,181,142,73,106,134,117,51,19,63,71,50,46,17,40,60,66,71,73,109,120,132,118,127,130,142,166,163,166,182,191,168,150,146,152,125,93,71,47,53,71,53,34,35,22,19,27,16,19,21,17,21,21,23,20,17,24,20,21,22,19,24,26,29,35,35,36,34,32,28,25,29,22,57,91,66,37,17,15,15,22,33,44,57,59,59,63,62,64,68,76,86,87,88,93,85,75,58,58,57,55,57,61,66,72,71,77,80,83,88,77,53,30,24,19,24,21,24,42,62,84,96,93,98,97,91,93,86,79,76,65,65,85,80,69,71,54,55,53,58,56,53,59,65,62,61,61,62,67,63,55,39,26,16,16,22,18,15,19,30,28,27,38,40,42,48,44,40,44,37,34,28,36,100,112,64,23,14,21,22,22,22,24,24,22,25,29,35,32,19,32,29,20,24,22,24,27,22,20,26,24,23,22,22,23,27,25,23,24,22,30,23,23,31,29,22,23,27,27,26,27,24,25,25,20,26,24,24,27,23,23,22,23,24,25,25,26,23,24,21,20,19,53,93,53,23,16,22,26,24,22,24,26,21,27,20,19,25,24,23,21,22,22,29,29,22,21,21,22,19,24,25,18,17,21,21,21,21,20,20,20,19,21,28,30,27,34,28,32,31,27,32,25,30,30,27,34,29,28,23,18,22,18,17,22,19,24,19,21,23,20,23,20,20,19,20,20,21,25,19,23,20,17,20,22,23,21,20,25,28,65,106,83,50,22,15,23,22,21,26,20,19,24,24,24,21,22,21,21,22,26,23,23,22,20,24,26,21,23,24,21,22,29,21,24,24,21,23,23,25,21,23,21,23,24,21,23,25,23,21,27,24,21,24,23,23,25,28,22,22,17,23,28,27,29,53,89,58,42,36,38,55,47,42,45,61,68,59,69,72,88,112,113,129,119,137,150,149,189,203,186,189,182,155,138,141,165,179,173,169,162,132,130,133,134,122,109,113,118,130,118,116,112,99,104,103,107,115,125,135,143,152,158,178,172,155,145,157,110,12,3,11,11,15,13,16,14,15,16,16,15,94,118,155,145,141,87,95,131,94,162,231,245,252,252,216,164,128,119,141,184,219,160,145,155,146,118,31,29,92,136,71,47,65,45,46,68,97,82,78,95,97,90,66,73,66,61,87,80,58,48,61,66,70,81,81,100,99,91,76,48,71,77,127,139,95,144,117,114,200,242,249,174,83,200,241,228,120,90,106,120,134,134,167,155,112,137,134,130,127,64,48,94,147,202,249,193,177,240,233,211,111,49,107,171,204,138,104,71,38,94,45,55,31,38,59,69,68,69,71,94,155,161,186,131,71,110,93,109,186,163,86,67,75,92,121,124,119,123,129,125,65,13,54,136,153,146,145,147,139,72,93,89,103,173,152,115,130,105,94,66,44,27,18,21,27,36,104,73,85,108,107,39,17,87,134,142,77,51,132,175,188,184,182,121,170,166,151,130,109,82,67,55,49,55,54,63,67,64,80,95,128,118,58,20,56,112,138,150,151,168,182,190,199,189,186,168,154,136,110,91,87,88,88,88,80,82,68,33,47,65,47,51,36,45,87,114,140,146,160,172,180,190,183,178,165,141,125,109,111,106,110,69,29,59,54,62,29,35,69,73,101,62,39,53,98,164,170,176,192,182,178,162,156,148,133,104,103,83,97,47,36,33,27,32,28,21,24,20,22,17,16,37,35,23,16,20,21,18,22,23,22,21,24,24,24,27,23,23,27,26,31,40,33,32,30,20,23,24,26,31,24,22,33,42,31,27,21,16,23,45,64,73,71,66,66,64,62,66,68,75,78,80,90,80,66,48,48,66,61,60,61,57,69,71,79,83,87,78,49,35,27,22,18,20,22,43,62,67,82,90,96,94,95,87,88,85,77,71,79,71,75,75,64,60,54,57,55,51,54,54,62,67,58,61,69,66,65,53,40,31,19,19,17,17,21,21,22,24,32,41,40,38,42,44,39,45,44,44,41,30,28,19,34,96,102,48,19,15,24,19,24,27,20,26,21,22,28,21,26,29,23,21,25,22,22,27,24,19,19,26,22,21,28,25,22,29,22,22,31,29,23,23,28,27,22,26,28,22,27,25,26,25,20,22,23,29,23,22,21,25,27,22,33,22,20,29,23,25,21,22,21,35,85,65,27,19,16,22,23,24,24,24,24,23,21,21,24,25,22,21,24,31,30,20,26,22,20,23,21,25,18,24,23,17,21,21,26,24,19,18,22,23,30,27,31,36,31,28,27,32,31,34,29,29,30,29,32,25,20,21,19,20,23,20,22,23,17,21,24,21,17,19,24,21,20,23,24,25,21,20,22,21,19,22,24,23,19,25,19,43,86,98,79,46,23,17,20,21,23,20,24,24,21,21,21,24,19,22,24,21,24,19,22,20,24,24,22,20,19,26,18,21,24,23,26,21,18,22,24,20,22,22,26,28,24,26,22,22,22,22,25,23,26,24,22,27,21,24,26,22,26,32,34,29,87,114,61,33,27,24,47,49,42,39,47,55,44,59,52,50,67,69,79,55,82,86,73,100,101,98,105,91,84,81,98,143,155,137,119,112,90,83,86,66,66,68,61,60,61,53,52,53,47,46,36,44,63,71,72,65,79,86,100,98,90,94,110,97,21,5,14,12,17,15,17,16,16,17,17,16,98,132,165,145,139,88,87,109,81,162,241,248,252,252,247,239,234,230,232,236,235,158,145,153,151,123,33,22,88,141,78,72,85,64,57,66,92,89,108,122,111,94,63,49,53,69,92,79,60,58,56,60,67,68,77,87,75,81,71,68,79,74,79,77,78,96,79,86,153,204,224,130,72,145,149,126,113,120,153,181,176,169,123,95,105,146,149,139,128,73,54,62,95,125,159,132,134,186,175,171,114,64,76,113,136,88,61,19,17,31,20,55,47,46,69,69,47,21,14,37,34,13,16,33,55,36,24,61,57,48,51,47,79,131,174,181,186,198,200,183,61,8,22,83,99,86,87,82,72,31,64,48,64,92,58,65,61,69,62,55,48,45,50,59,84,106,122,139,145,165,159,80,28,102,177,160,66,33,99,115,113,103,94,88,72,66,57,53,48,41,33,29,27,35,61,87,110,128,153,163,186,161,77,32,81,156,152,142,130,134,132,127,120,92,78,65,56,43,31,19,14,15,15,36,63,105,105,48,101,112,57,57,21,74,169,185,174,153,157,151,134,124,106,89,62,52,40,23,21,11,34,46,68,121,152,171,135,164,193,178,156,118,61,73,132,132,133,100,80,69,49,38,31,34,27,25,21,26,18,17,22,21,19,18,21,17,20,19,18,21,22,42,42,34,23,21,24,21,21,23,27,22,22,25,21,25,34,31,38,39,33,31,32,37,39,46,35,21,27,35,34,33,34,23,24,33,33,49,71,89,94,84,76,70,65,65,63,66,70,71,75,78,78,76,60,63,61,61,66,61,65,64,71,76,81,73,49,35,28,20,24,22,25,41,59,76,80,89,92,92,91,87,92,84,79,80,75,76,84,82,71,64,60,57,61,55,51,54,58,61,64,66,60,68,64,53,42,27,22,15,18,21,19,22,21,27,36,39,43,45,44,43,40,47,46,40,41,42,43,37,29,26,24,40,97,95,36,18,16,25,23,24,27,18,25,24,25,26,29,27,21,21,25,23,23,22,21,24,24,24,24,21,30,28,23,24,24,29,24,27,25,22,39,30,26,27,25,30,23,24,19,23,26,22,26,24,30,21,24,25,21,25,25,24,23,23,21,23,24,26,26,27,78,75,33,22,18,19,25,29,23,17,26,28,25,30,22,29,22,18,32,21,22,28,21,23,22,27,22,18,27,31,27,19,24,28,23,20,22,17,20,28,24,30,32,31,31,29,30,28,29,30,27,27,33,31,25,30,21,23,22,21,24,19,19,22,21,21,23,19,24,23,21,20,21,23,21,19,21,21,22,21,19,21,23,18,23,22,22,47,51,79,105,81,44,19,18,27,19,19,24,21,23,25,29,20,25,29,22,23,21,24,24,23,24,22,21,26,22,23,24,22,24,24,21,19,22,24,21,21,26,23,24,21,23,25,24,28,21,25,24,21,29,25,26,23,23,24,22,24,29,55,40,53,150,171,132,107,61,31,35,40,45,39,35,46,48,67,54,53,70,65,69,56,66,62,50,60,48,59,100,91,68,62,93,136,129,113,103,107,91,88,81,61,63,61,62,54,53,50,60,64,46,41,35,50,55,53,46,35,45,42,49,48,53,57,60,63,25,9,16,15,17,15,16,17,16,17,16,17,83,107,139,137,145,105,92,108,80,154,233,248,253,253,253,253,252,252,243,243,230,148,139,150,151,130,71,45,90,133,91,113,119,84,78,95,124,114,124,125,109,101,59,41,39,65,101,99,67,50,61,59,57,62,83,103,89,95,82,87,120,81,50,36,75,113,72,95,166,221,247,119,71,169,131,93,119,166,138,131,164,206,192,98,61,86,93,101,86,62,74,70,51,48,62,52,70,84,91,141,129,100,90,87,91,67,55,36,46,53,42,68,59,59,66,71,71,53,39,39,63,57,45,53,78,74,52,77,96,68,83,85,66,56,89,120,113,113,136,92,31,36,70,108,87,64,69,71,71,24,42,42,61,105,102,130,136,146,153,149,162,161,160,160,152,143,129,113,106,107,104,44,6,56,89,61,35,36,38,46,48,48,45,49,53,115,93,104,120,123,135,134,130,134,129,136,134,131,138,127,133,105,51,32,51,47,31,30,35,33,36,33,21,22,39,57,77,88,95,103,110,87,102,110,120,139,122,84,102,103,59,47,38,31,59,66,53,47,51,50,37,36,45,66,107,135,140,141,137,129,141,152,165,184,188,192,157,147,132,112,103,55,47,38,74,34,28,29,26,17,23,20,19,19,15,25,21,21,22,17,22,21,19,23,26,25,23,23,23,26,27,40,39,33,35,29,40,51,57,62,66,67,46,38,37,42,47,49,48,50,61,71,85,98,116,105,67,20,23,39,42,49,44,37,29,40,59,66,76,83,82,79,69,64,67,60,64,67,71,65,59,63,51,56,65,57,61,60,62,67,62,69,73,69,54,37,30,25,19,19,22,40,62,73,79,94,98,94,98,88,86,84,84,82,81,79,76,75,80,68,56,57,57,57,56,57,56,63,66,59,64,66,64,53,39,26,21,22,20,17,19,22,24,32,35,45,42,46,49,45,42,40,43,43,41,45,38,42,47,44,41,33,35,32,63,106,81,33,17,23,23,29,24,20,24,24,30,32,23,21,25,26,21,30,22,20,22,21,24,24,27,26,24,27,24,24,28,22,27,27,23,26,23,27,24,24,27,24,24,20,21,27,25,19,21,24,19,23,23,24,24,30,30,27,23,21,25,19,30,28,23,25,61,89,45,23,19,21,26,21,21,22,21,31,35,23,22,28,27,26,21,27,34,29,22,20,22,21,22,18,27,29,18,24,25,29,25,19,22,17,21,25,31,28,27,28,27,34,30,29,30,31,30,33,32,31,29,23,21,22,21,19,22,20,25,19,23,24,15,21,22,20,24,22,19,21,17,24,19,20,23,18,23,18,18,19,27,24,24,49,41,37,89,108,79,43,20,16,20,22,19,26,22,23,24,21,29,24,22,21,24,24,21,22,22,21,23,25,22,23,26,22,23,21,20,23,23,23,22,29,22,19,21,22,23,22,24,20,20,27,25,25,26,24,24,22,23,21,26,24,48,53,72,175,218,218,215,193,167,117,62,22,30,35,33,36,43,44,50,56,59,59,65,49,62,62,65,71,37,75,125,101,97,75,85,100,85,92,86,82,68,81,85,56,70,71,74,67,55,61,65,66,56,55,58,60,53,59,71,57,49,46,43,46,51,48,50,54,23,10,15,14,15,15,16,16,16,17,16,16,147,137,148,149,181,171,166,172,137,181,234,246,253,253,252,252,252,252,237,232,208,127,133,148,157,171,156,108,127,156,101,113,97,71,61,74,101,80,81,77,86,96,64,45,38,56,91,96,54,33,45,52,51,48,76,84,75,95,67,101,115,60,41,18,73,98,64,84,154,206,177,69,66,160,105,61,109,120,80,71,100,188,154,60,48,38,53,63,54,59,87,82,74,52,46,43,27,26,26,86,98,59,66,61,64,79,74,39,50,56,39,64,57,72,90,72,76,85,101,104,103,103,103,112,95,89,73,86,90,88,109,63,34,18,21,46,24,12,15,16,61,176,245,251,222,158,161,190,202,113,95,69,120,194,180,190,169,172,164,152,151,139,118,92,75,53,27,11,9,16,33,47,30,34,100,119,63,63,148,177,177,177,174,174,171,179,179,180,184,174,169,154,142,125,105,77,56,41,35,32,48,50,38,35,31,84,112,136,145,152,163,168,166,155,169,184,194,197,191,183,174,152,129,106,77,66,63,34,63,55,41,58,39,42,45,81,118,120,122,119,121,127,144,170,183,189,189,179,177,146,135,117,91,80,60,62,34,31,22,19,29,14,33,39,29,17,24,24,23,22,21,21,18,21,23,26,22,24,24,24,24,24,25,24,29,48,63,69,55,36,41,44,46,69,78,106,133,138,134,119,103,76,59,54,62,84,101,107,108,103,113,128,136,146,154,131,65,28,20,32,56,69,62,44,37,39,45,49,44,41,57,66,63,63,53,57,63,65,63,55,49,57,59,50,56,61,59,62,63,60,66,59,50,36,27,27,20,20,28,41,58,74,77,86,95,95,95,90,86,88,79,71,79,77,87,80,66,58,62,55,50,57,49,53,59,59,64,66,66,64,61,54,41,28,21,21,16,15,21,25,23,33,37,39,45,45,48,46,45,44,42,44,43,40,44,43,44,49,41,43,46,42,40,40,41,78,107,81,35,21,27,24,41,35,23,27,27,34,39,28,23,21,22,27,27,20,24,24,22,27,25,27,27,25,27,29,24,30,29,26,25,19,24,25,30,31,27,26,27,22,22,29,22,25,23,23,28,23,24,25,23,36,33,21,22,19,36,39,28,18,31,29,44,93,58,24,22,21,30,29,23,27,28,25,24,25,26,26,27,28,23,22,30,21,20,26,23,26,20,18,25,22,25,24,31,27,24,25,17,20,24,27,28,27,33,30,33,29,31,34,28,32,33,27,30,34,29,30,21,23,23,19,22,21,29,23,20,19,22,25,19,22,20,20,25,25,23,23,24,18,21,22,19,21,25,24,24,22,30,62,42,24,40,93,114,78,38,15,19,22,23,20,24,22,21,23,28,20,23,25,27,26,17,26,23,20,22,27,22,22,25,21,21,22,18,22,26,24,24,21,22,23,24,23,24,26,26,24,22,30,26,22,25,28,24,22,27,26,25,41,59,73,152,204,201,204,200,204,211,198,114,56,46,34,35,33,34,37,41,46,49,49,54,56,59,61,60,61,45,61,94,82,101,78,50,50,48,70,63,56,48,53,60,59,66,62,68,66,59,61,61,63,61,58,59,60,50,69,90,80,65,45,51,50,48,50,47,48,24,12,16,15,17,16,16,16,16,16,17,17,230,224,197,186,241,251,248,248,198,207,247,248,253,252,248,246,237,239,227,220,190,117,128,141,163,204,224,162,150,139,70,90,74,47,42,52,64,56,68,84,104,109,91,70,57,64,73,77,60,52,62,68,71,69,74,67,65,79,71,95,105,69,45,15,54,77,59,61,76,90,81,33,42,80,55,66,74,76,62,56,67,89,81,50,39,43,47,53,41,57,78,77,79,84,88,76,72,59,43,74,83,101,136,160,139,114,92,57,55,50,36,59,78,86,94,82,82,84,104,98,82,72,74,82,65,47,29,42,15,36,41,26,26,33,62,99,92,73,100,130,190,248,234,233,201,131,142,185,238,132,49,32,54,97,84,80,71,64,54,45,38,27,22,29,25,29,27,25,31,58,90,59,22,68,143,154,84,69,131,124,155,131,122,118,108,111,109,96,119,69,61,47,42,49,46,43,33,32,37,38,91,93,53,34,44,158,182,182,176,171,167,158,148,98,140,145,143,124,111,96,82,67,61,63,54,47,44,57,93,116,130,142,102,71,68,191,206,206,179,149,138,91,129,102,91,77,49,46,41,29,23,24,24,26,23,22,22,21,23,16,24,18,33,46,25,22,21,18,21,24,20,23,27,31,34,33,30,30,33,36,33,39,36,33,71,102,129,137,85,61,71,64,95,135,129,123,123,101,74,54,64,74,81,105,101,117,116,122,123,115,132,124,121,103,63,41,33,27,35,35,35,40,43,39,29,39,38,41,44,37,58,61,60,63,63,60,60,60,60,59,57,78,74,57,55,54,63,61,61,59,47,38,27,24,22,22,30,38,61,77,79,89,92,97,91,85,92,81,79,78,78,83,84,73,62,62,54,54,55,49,50,57,55,56,61,61,57,59,62,51,37,29,19,21,19,20,20,21,31,30,41,43,44,46,44,49,45,42,44,44,43,46,41,41,47,45,37,46,43,41,45,46,41,38,49,46,85,115,64,33,17,41,70,30,22,22,24,39,35,26,23,23,26,26,25,20,23,23,19,29,27,26,27,24,24,26,26,26,27,24,22,27,25,25,30,34,36,31,27,30,26,20,29,28,23,25,25,29,24,22,23,26,24,24,21,33,54,37,23,23,32,31,32,90,75,33,17,33,40,20,27,31,33,25,25,36,28,25,28,21,20,24,18,19,27,27,22,22,20,24,23,25,23,23,27,29,26,23,23,19,22,24,28,29,31,29,29,28,31,31,27,31,29,29,31,26,29,31,23,19,20,19,24,23,23,26,20,20,28,21,19,22,21,24,20,22,26,21,22,24,25,20,23,26,21,21,24,18,41,74,36,18,28,42,101,106,76,37,15,21,18,22,24,20,21,23,21,24,22,21,27,23,21,22,26,21,26,26,21,19,22,22,22,24,22,19,20,21,22,27,26,25,24,21,26,24,21,23,18,25,27,21,25,33,45,47,53,60,53,78,123,139,149,143,113,117,117,115,157,181,152,140,116,77,51,33,35,37,35,40,45,40,51,57,60,57,49,57,57,59,50,41,70,61,49,53,41,53,57,61,54,45,47,49,55,53,58,57,57,55,53,59,61,65,55,57,63,65,73,67,65,56,48,49,46,44,48,48,24,12,16,15,16,16,16,17,16,16,16,17,224,242,204,181,240,245,241,224,150,186,243,249,253,249,244,243,237,241,227,222,186,110,125,129,145,185,216,151,128,116,59,101,94,66,50,68,104,95,115,143,157,160,152,131,118,120,134,136,114,111,121,131,139,132,134,126,120,137,120,135,122,128,118,51,93,120,118,95,84,110,112,83,84,113,94,113,141,127,113,114,103,101,72,57,51,45,83,69,53,47,61,69,65,68,97,129,132,129,104,139,157,180,246,244,203,136,71,61,59,46,39,65,68,62,69,63,66,63,77,53,43,49,36,49,41,31,20,24,22,39,89,109,147,163,194,235,238,239,229,224,218,209,160,97,63,33,29,84,113,63,41,17,32,60,71,100,96,109,111,110,113,124,143,153,158,159,159,150,152,151,148,100,24,28,99,81,37,41,57,49,28,24,26,33,47,50,49,64,74,81,83,79,105,122,133,138,134,139,138,141,142,125,84,31,46,104,98,78,63,43,29,21,23,33,40,56,61,61,58,61,80,103,142,158,153,143,145,151,155,159,166,148,104,60,70,117,119,102,59,32,34,30,26,25,23,21,19,21,23,17,20,25,15,23,23,21,23,20,26,28,26,27,48,48,41,43,40,39,50,51,54,51,52,86,103,83,53,48,79,109,107,83,46,36,118,162,141,118,85,59,56,55,71,81,53,47,47,57,71,78,85,81,91,101,108,103,105,112,117,117,111,84,50,36,29,28,34,48,85,94,65,42,27,31,25,33,46,42,41,42,59,63,65,68,65,64,67,68,74,73,69,85,83,59,63,66,57,57,48,39,27,19,26,24,24,39,60,76,78,84,92,91,95,84,86,87,79,77,69,83,84,78,79,56,48,55,58,51,55,54,57,60,59,62,57,60,62,53,40,28,22,19,18,19,23,20,28,36,38,47,47,38,46,49,47,46,46,40,39,46,44,49,48,48,48,46,45,46,42,41,45,41,46,46,44,40,38,86,106,66,30,22,34,22,24,24,21,27,21,22,24,29,24,24,29,24,24,25,24,25,21,26,27,26,29,24,23,26,22,28,23,26,34,25,28,30,29,24,22,30,23,26,25,24,25,22,25,24,23,24,25,22,22,29,26,25,27,24,22,27,27,24,27,72,82,37,24,21,25,24,28,29,24,23,21,27,24,24,24,23,20,19,26,26,26,23,21,25,24,24,26,26,24,25,27,24,30,27,22,18,18,29,28,31,27,26,30,26,30,30,27,31,27,27,33,33,31,28,23,19,20,22,19,19,19,19,22,21,26,20,23,21,17,25,23,23,26,20,22,22,26,20,22,29,24,17,29,21,55,81,28,27,25,24,47,90,111,70,36,17,15,23,20,22,18,21,27,22,22,25,24,21,22,24,24,20,23,24,21,24,24,22,23,22,21,21,21,26,23,19,24,20,22,29,27,20,24,24,24,24,22,27,28,61,90,101,128,117,100,146,169,143,145,105,74,73,50,57,94,142,153,165,160,122,107,53,32,35,35,39,41,49,47,53,58,53,42,52,60,53,47,37,56,48,51,61,47,45,53,67,59,43,43,46,44,45,46,49,55,53,51,49,54,55,54,57,48,49,43,48,56,50,54,45,47,46,45,48,23,12,16,16,16,16,16,17,16,17,16,17,184,227,168,125,169,192,181,118,65,141,213,241,252,249,249,248,243,243,227,222,181,107,123,125,125,133,113,71,132,134,90,127,129,114,77,99,128,134,160,173,182,176,179,176,168,174,177,182,174,177,177,177,180,174,182,173,174,175,164,158,133,161,134,71,124,166,163,146,139,152,155,145,148,159,154,158,155,164,160,152,144,127,99,99,78,74,100,87,64,51,57,63,60,39,52,71,92,102,82,109,100,121,165,130,115,91,52,63,66,33,42,39,47,44,59,57,45,43,52,41,28,45,56,65,65,89,105,137,174,205,233,247,240,238,230,222,198,177,164,111,78,57,19,9,19,27,22,28,59,76,112,100,128,168,174,201,208,210,213,214,214,219,228,223,144,184,163,146,131,114,108,61,9,24,34,36,20,42,75,107,103,120,144,155,164,175,175,116,120,208,210,206,137,205,187,175,152,136,123,110,96,77,37,27,42,29,46,71,88,99,109,126,142,158,157,164,159,148,94,159,152,143,154,152,139,115,90,88,56,36,40,37,27,43,44,24,25,27,29,22,19,15,22,21,21,19,20,23,19,23,22,21,29,25,19,26,23,33,43,55,68,76,116,130,141,171,149,153,189,191,192,163,149,189,208,175,98,89,153,189,181,149,81,91,209,219,127,100,76,50,47,27,44,49,59,81,84,94,104,103,96,98,100,103,98,110,105,104,77,66,41,27,32,34,34,48,84,131,154,155,164,115,34,22,55,63,42,39,44,46,67,71,73,68,63,67,74,79,77,90,86,93,72,73,76,61,53,36,27,20,21,24,23,39,53,61,69,81,84,83,81,83,81,82,80,78,75,69,76,79,72,61,55,50,51,54,54,59,60,62,59,60,57,63,64,53,42,24,21,19,19,17,19,19,27,36,39,42,49,49,45,46,44,43,46,45,43,46,46,45,49,49,46,48,46,48,45,45,44,41,44,44,48,46,42,41,31,37,98,109,54,21,17,24,29,24,21,24,25,27,25,22,24,27,29,27,24,25,26,26,24,25,21,29,32,27,28,28,27,25,23,29,28,23,29,31,22,28,29,27,24,27,22,24,27,22,32,22,21,23,23,24,21,29,27,27,26,25,31,22,22,28,21,56,91,51,23,15,23,25,20,29,24,19,27,27,23,27,26,18,20,21,23,21,20,24,21,27,22,24,29,18,21,24,25,29,30,27,24,24,19,24,29,27,28,30,27,29,32,26,32,31,27,29,29,32,32,35,27,18,21,19,21,21,22,23,19,21,21,21,20,21,21,22,22,19,27,22,20,25,22,22,22,22,23,26,23,22,71,71,25,29,22,16,23,45,97,102,67,37,22,22,21,21,19,24,25,25,25,22,24,24,19,22,28,24,21,24,21,23,24,26,24,17,26,25,20,18,24,22,20,25,23,28,24,20,26,23,24,24,24,24,39,99,123,113,113,93,101,132,126,116,118,111,96,91,76,65,80,108,122,131,123,117,108,55,32,30,36,43,51,50,48,47,41,41,41,57,59,53,56,59,63,48,55,66,51,57,60,69,56,48,50,48,50,43,52,48,51,50,41,43,61,64,39,38,41,39,44,36,43,33,36,45,36,47,50,43,23,12,17,16,16,16,16,17,17,17,17,16,200,228,166,135,167,185,210,142,87,160,214,244,252,251,252,248,245,248,227,226,181,109,129,124,121,93,48,51,137,169,144,166,171,134,92,128,163,174,179,184,187,181,185,181,186,187,195,191,199,203,198,199,199,193,194,198,191,182,174,153,113,143,110,56,98,134,171,164,146,159,160,170,181,179,175,163,140,143,157,157,148,139,137,145,104,82,105,84,80,70,54,59,52,37,24,14,24,33,34,49,28,18,31,36,66,90,84,110,78,16,12,14,42,74,83,85,63,72,98,96,117,125,150,174,185,223,233,240,236,233,222,196,178,143,121,98,60,40,51,43,21,21,21,20,88,127,65,50,62,86,135,160,194,188,174,170,141,130,122,124,125,127,134,121,97,88,98,104,129,127,129,116,51,26,84,114,75,98,162,183,191,201,206,194,188,174,147,134,128,131,120,122,130,108,98,89,84,90,93,104,106,83,70,49,51,103,150,181,185,178,187,184,184,176,156,144,112,112,110,91,69,42,37,32,34,30,21,20,18,18,24,19,23,41,33,25,19,22,24,22,28,19,27,29,27,32,27,37,41,49,60,61,61,68,65,67,55,76,136,161,183,189,193,190,200,208,188,203,217,209,219,165,162,201,197,159,116,135,165,189,186,167,78,76,181,135,73,50,37,54,49,47,89,113,109,116,121,121,123,127,116,108,114,109,103,87,72,48,34,30,33,39,38,72,107,129,145,146,155,153,169,130,37,35,90,101,63,42,47,56,74,70,68,63,65,74,69,81,81,94,104,103,93,76,63,40,25,25,22,27,25,33,51,62,68,72,76,82,82,78,76,69,72,66,67,72,76,78,68,61,55,49,52,53,57,55,59,57,57,65,65,68,63,60,46,29,23,17,21,22,17,23,25,35,41,43,50,48,45,47,46,47,43,48,49,41,51,48,48,49,45,49,48,46,46,43,43,42,45,48,41,41,43,43,40,43,42,31,54,105,98,48,19,21,22,19,19,27,29,29,31,24,24,24,21,22,25,25,25,26,24,24,31,27,24,30,29,20,18,26,28,32,30,26,22,27,25,28,24,31,39,24,26,23,26,27,25,24,22,21,25,30,25,32,28,28,29,25,36,35,29,32,28,41,92,67,27,20,18,24,22,23,29,30,27,30,29,27,22,24,25,22,18,24,22,22,24,20,26,25,31,31,22,25,24,28,28,27,33,20,16,30,27,25,29,30,33,26,29,29,32,33,30,29,28,37,32,25,24,19,18,21,18,20,20,19,24,17,25,24,20,20,23,23,19,24,21,22,22,23,22,19,21,22,16,25,29,20,81,66,19,28,18,18,18,23,53,99,103,67,34,17,21,22,22,20,24,23,18,21,23,23,20,21,24,22,27,22,19,25,22,22,21,25,24,21,21,24,22,25,27,21,26,23,23,23,25,21,23,25,31,26,39,98,113,94,84,74,88,97,78,65,93,104,113,117,98,88,74,89,85,81,78,75,83,65,65,66,61,77,94,92,90,87,92,105,106,104,97,81,88,90,91,77,69,79,81,73,75,81,60,50,58,54,49,50,57,56,74,87,87,87,86,90,85,84,77,84,95,97,94,87,89,72,56,64,67,55,22,9,16,14,16,16,16,16,16,17,16,16,196,221,178,171,200,227,243,168,132,200,244,250,252,252,252,249,243,243,224,226,171,112,132,125,139,114,93,111,150,126,104,125,116,94,48,92,124,123,137,129,132,125,131,132,126,132,129,140,138,142,142,142,144,134,143,141,148,153,163,125,63,76,50,13,44,71,79,85,77,92,96,110,134,131,129,110,109,113,115,124,122,112,98,122,102,87,90,80,79,65,46,41,53,46,54,53,60,81,80,118,84,65,90,84,128,125,99,141,92,24,40,57,141,158,169,170,162,185,201,199,205,201,201,211,206,208,164,177,138,112,73,45,39,29,46,39,18,10,61,74,40,36,19,55,156,187,132,50,15,42,81,134,145,124,98,60,46,34,27,36,55,65,69,76,102,119,125,152,179,171,178,166,47,63,160,188,111,121,165,162,146,127,118,82,57,39,18,12,17,17,22,38,129,89,115,140,158,179,193,193,178,159,112,66,84,121,132,122,94,78,68,53,37,39,35,31,30,28,61,24,24,18,25,19,19,26,20,21,26,21,24,30,28,42,43,37,27,27,33,26,28,30,39,44,55,66,107,155,181,210,219,214,218,218,217,206,132,152,216,224,227,222,214,208,201,202,200,198,201,193,200,155,129,168,174,179,178,185,196,198,148,136,65,33,78,97,92,93,85,83,94,109,136,135,125,134,129,128,134,141,125,105,87,69,38,30,34,31,37,35,61,87,122,138,142,142,135,136,129,128,89,25,16,21,75,97,76,77,64,67,75,66,71,65,64,66,75,81,78,92,110,105,73,45,28,23,22,23,27,29,50,57,62,68,68,69,73,77,71,66,71,66,71,66,64,69,74,63,53,48,47,48,51,55,56,59,63,66,64,61,71,61,46,35,20,15,21,21,21,17,26,37,42,43,44,49,48,46,46,45,45,46,49,48,49,53,51,53,45,46,41,44,49,45,48,39,44,47,40,42,41,38,41,39,42,44,39,43,45,69,112,96,41,16,19,21,25,33,24,37,38,27,28,24,25,24,24,26,20,26,27,31,29,28,28,23,24,24,27,27,30,33,35,24,21,27,27,27,27,45,37,22,26,27,24,23,21,25,29,23,30,33,26,27,24,30,27,29,36,32,29,27,28,32,82,80,39,29,19,23,23,21,31,31,24,27,29,27,22,28,26,22,23,17,22,23,19,30,26,28,42,27,19,23,22,28,30,26,29,26,24,32,30,28,31,31,26,30,33,33,30,30,31,29,30,35,34,29,23,24,20,19,22,22,22,24,24,23,23,27,24,23,22,27,24,20,26,23,27,23,22,28,23,22,21,29,21,35,85,49,21,27,16,22,22,23,27,50,100,103,69,32,15,21,24,23,24,25,23,23,21,27,24,26,25,22,22,18,25,27,24,22,20,23,23,22,25,27,22,21,23,27,21,24,26,21,26,19,23,31,30,22,34,85,124,125,105,108,113,113,92,82,103,108,114,114,106,101,93,100,93,79,90,79,98,108,125,125,124,133,141,139,137,139,147,159,154,146,130,113,120,111,109,108,101,102,94,100,108,101,85,78,82,83,87,87,91,95,120,140,135,138,134,141,150,138,150,148,155,164,167,151,141,133,119,122,128,99,17,3,13,12,16,13,15,15,16,15,15,15,142,190,191,216,243,243,246,163,128,205,248,252,252,252,253,248,244,245,224,226,162,108,131,128,149,151,174,199,144,36,2,21,35,47,36,30,27,33,37,36,37,34,36,30,36,37,36,35,39,40,39,39,39,36,40,38,40,69,111,87,37,41,32,39,35,25,30,29,30,29,26,25,36,35,35,40,46,50,42,56,60,46,43,52,65,67,67,49,36,29,24,45,93,150,178,173,171,188,191,193,155,162,191,181,183,168,154,184,175,184,210,226,243,240,236,231,220,217,200,168,160,128,113,104,74,66,62,48,42,54,29,8,19,36,52,50,39,32,50,61,42,37,37,105,229,250,225,114,14,10,27,30,36,32,27,29,31,36,34,40,50,42,45,57,73,73,77,78,88,78,76,75,33,26,71,81,46,41,50,48,38,24,22,21,25,50,74,94,118,131,134,144,150,158,160,154,150,169,160,135,116,78,64,45,35,35,28,30,28,27,28,23,23,25,24,28,20,21,29,24,27,27,27,23,26,27,26,28,27,30,29,27,37,41,35,34,27,22,22,32,44,52,56,66,104,139,169,175,175,178,179,190,188,186,191,166,92,113,161,163,165,154,160,149,147,157,145,155,151,146,157,100,98,129,141,159,160,170,155,136,92,65,31,46,108,117,125,92,70,66,61,83,104,104,99,93,84,75,73,73,50,31,33,34,39,37,47,61,82,107,119,134,133,139,132,132,134,130,125,89,32,5,65,90,56,80,79,83,81,67,67,61,71,64,71,77,83,96,85,100,83,51,39,21,23,19,26,36,50,64,64,65,66,70,70,73,73,69,68,68,63,68,73,68,75,66,50,51,49,49,52,50,56,58,63,66,66,74,71,62,55,28,23,22,19,24,14,21,31,36,44,45,44,49,50,47,51,48,48,53,47,52,47,47,54,50,52,45,46,47,44,40,46,48,42,45,47,46,46,45,41,39,45,39,41,45,45,47,46,41,79,118,86,39,19,20,25,22,24,36,30,21,25,27,27,29,25,23,30,27,25,25,31,24,27,25,24,34,22,30,33,27,31,26,32,31,24,30,27,28,24,25,27,23,26,28,25,24,23,30,32,36,39,27,25,24,31,29,44,53,31,25,24,29,71,92,75,47,17,18,26,27,21,27,36,25,23,22,24,31,25,35,28,24,25,21,29,25,27,23,24,22,21,27,27,30,28,24,29,28,25,27,31,31,34,32,26,31,30,31,31,33,29,29,29,35,34,26,29,22,19,21,23,22,22,19,23,22,22,29,24,23,26,22,20,24,25,22,24,20,20,23,24,27,19,28,20,46,89,38,27,27,13,23,20,23,21,25,55,101,104,67,35,21,19,22,24,23,20,24,23,24,21,22,25,22,23,19,20,25,24,21,24,21,22,25,25,24,23,21,19,24,25,27,17,26,26,23,28,24,26,21,31,59,94,108,116,137,153,166,151,141,147,139,142,135,137,138,128,134,122,117,117,130,144,144,154,148,146,155,155,146,141,144,148,159,157,148,142,125,124,117,113,117,111,111,112,121,128,125,117,113,111,110,114,119,122,127,150,161,162,166,172,181,180,181,177,177,180,183,186,181,179,161,160,166,173,111,10,2,9,11,14,11,14,14,15,15,15,15,110,184,236,249,246,246,252,147,117,207,241,251,252,252,252,248,246,243,225,225,155,117,138,134,147,118,155,177,101,20,6,27,36,49,38,27,23,21,34,25,29,27,21,27,25,30,24,27,26,27,29,27,29,25,30,46,53,71,70,45,53,52,37,50,52,41,45,51,42,35,30,21,29,27,30,33,39,44,27,23,26,26,28,47,50,56,58,47,51,64,109,106,171,245,251,228,231,235,211,198,177,205,226,209,206,197,205,232,229,227,226,217,211,192,173,152,128,117,94,92,122,101,69,36,8,11,22,13,23,69,59,22,44,54,63,48,33,38,40,40,39,36,54,160,249,249,252,202,46,5,13,14,21,18,26,23,23,32,32,28,36,37,42,44,46,46,39,35,27,31,42,47,45,46,44,48,61,79,78,84,99,116,122,114,126,139,150,157,97,160,150,122,93,75,55,39,29,36,42,36,30,22,27,39,44,25,20,27,25,29,29,27,25,31,29,30,33,32,34,31,28,26,30,34,27,27,31,27,29,32,40,38,21,24,25,23,23,20,23,21,24,30,30,34,29,33,39,39,38,35,31,34,33,31,36,40,46,44,22,26,35,35,36,39,38,30,35,38,38,34,39,42,46,45,41,63,52,43,35,26,29,30,47,47,37,37,39,44,46,47,40,32,35,36,39,45,41,42,42,45,43,50,50,54,72,88,101,118,132,133,129,122,125,123,125,125,125,118,113,108,88,101,130,108,60,68,61,73,65,63,66,64,73,73,87,90,94,105,77,45,35,28,21,24,25,36,60,76,80,77,80,76,76,71,74,71,65,62,65,68,71,67,69,68,65,58,50,52,50,47,50,56,65,66,66,62,75,72,51,34,27,22,19,19,18,23,29,36,47,44,46,50,46,53,51,53,50,57,53,51,53,52,53,50,51,48,50,48,46,45,46,46,48,44,46,41,39,49,39,43,46,39,42,43,49,46,44,42,39,39,43,80,109,81,38,17,23,26,25,21,18,23,25,28,27,28,24,24,28,31,28,28,30,29,29,19,30,34,27,27,33,33,29,33,33,29,23,32,29,22,30,27,29,29,31,29,24,29,30,34,27,35,38,21,27,29,31,34,49,45,22,23,31,32,52,93,80,36,14,19,25,23,22,33,30,19,26,28,27,22,23,30,22,20,24,26,22,26,23,24,28,23,29,25,26,29,29,30,31,23,26,32,27,32,29,34,27,32,33,28,28,29,33,32,31,31,33,31,19,23,21,21,24,22,23,25,22,19,20,23,24,21,17,24,21,19,24,23,24,22,23,20,18,28,21,25,19,57,84,29,23,20,17,24,20,26,22,21,28,56,101,99,68,34,15,23,21,22,21,23,22,26,25,23,23,19,25,22,22,22,22,23,26,23,16,22,24,23,23,23,24,26,29,25,22,22,24,20,27,27,24,23,31,59,59,55,77,113,162,197,194,183,178,175,173,168,172,183,178,166,154,155,159,177,173,171,169,162,167,175,172,160,153,152,152,159,155,153,142,126,130,125,126,133,117,122,126,139,130,136,139,137,139,139,132,134,139,148,156,169,165,170,177,179,182,176,173,174,177,178,177,175,179,166,167,173,183,114,8,2,9,10,13,12,14,12,15,15,15,15,92,163,203,244,233,230,239,100,114,202,237,251,252,251,252,246,247,240,223,224,143,125,154,159,167,76,52,55,17,24,27,22,37,42,41,33,29,31,27,34,33,29,32,28,34,30,28,36,29,29,33,33,32,29,35,44,66,98,66,36,38,34,34,44,60,55,52,66,72,62,44,48,55,47,55,52,43,39,41,71,87,94,105,120,139,139,156,170,175,196,205,217,235,247,242,212,193,177,155,137,139,159,167,153,152,142,133,148,128,114,89,78,63,45,38,19,13,26,50,78,137,122,67,46,27,23,22,24,25,50,41,32,49,44,46,54,38,32,49,51,43,38,91,166,225,239,243,228,101,24,21,18,30,35,41,43,45,46,53,50,47,50,55,57,57,57,63,61,84,100,110,113,65,62,96,126,157,156,148,149,157,156,131,111,95,78,57,42,43,36,34,33,24,27,21,24,24,24,22,23,26,23,32,40,45,33,27,33,32,37,31,29,30,32,27,35,34,29,26,29,32,20,29,26,19,25,29,22,23,33,51,41,22,22,22,18,23,24,20,23,22,22,23,24,24,22,24,23,24,25,18,22,23,21,19,29,48,38,20,20,25,24,22,24,25,21,25,29,31,36,44,39,38,37,26,31,28,23,19,22,22,28,50,39,24,19,29,25,29,47,42,39,39,39,54,66,66,61,58,63,75,93,100,115,123,117,126,122,119,120,115,121,113,120,115,113,117,113,132,141,125,103,92,69,61,70,59,62,65,67,72,67,84,85,95,94,70,49,34,25,24,23,27,44,61,77,98,101,94,102,97,89,81,79,81,78,68,59,71,76,67,66,66,66,63,56,51,48,47,53,56,63,73,69,73,67,52,37,25,19,17,17,20,20,31,38,41,48,44,50,46,50,55,54,56,57,57,56,55,49,52,53,49,49,44,48,46,47,48,42,49,50,45,39,43,47,39,39,43,45,41,45,46,44,39,41,41,39,44,40,40,34,73,110,78,35,23,23,20,22,23,30,26,27,31,26,29,25,29,30,28,27,30,30,27,29,31,32,26,30,32,31,37,28,28,29,22,29,29,30,34,24,31,38,30,27,27,32,28,29,30,29,27,23,31,28,28,27,29,24,25,33,28,29,36,84,79,31,21,24,27,19,27,24,23,26,29,29,23,23,22,27,25,26,29,21,25,28,24,27,24,28,24,28,29,25,25,27,33,27,25,28,29,28,34,31,31,35,31,33,31,32,27,30,30,34,36,22,21,20,21,23,22,22,23,22,23,23,22,27,21,20,24,22,24,26,25,27,25,23,22,23,24,21,23,24,17,74,74,20,30,27,19,23,21,25,21,23,26,26,56,97,96,62,29,21,18,24,24,19,23,21,26,22,24,24,20,27,22,26,25,23,27,23,26,23,22,23,24,24,21,22,30,23,21,26,24,24,22,24,28,24,52,81,98,122,112,77,117,186,201,206,200,187,185,184,193,194,188,187,172,181,193,195,195,186,189,186,185,188,188,181,178,180,177,179,177,171,162,151,162,160,155,155,155,162,164,167,160,162,170,171,175,168,165,160,160,158,161,171,173,174,174,179,175,170,169,169,173,171,171,171,174,168,173,176,184,114,8,1,9,10,14,12,15,13,15,15,14,15,105,142,147,173,150,146,165,81,126,201,236,251,253,253,251,245,245,238,223,214,124,133,169,193,203,64,5,9,19,37,28,24,35,36,33,36,33,28,33,30,36,40,41,44,36,42,42,39,42,40,41,39,43,48,44,49,43,68,92,45,35,42,45,49,50,56,40,66,85,88,96,143,133,139,155,166,182,195,191,199,207,213,211,213,210,208,214,222,216,215,212,203,152,180,164,146,139,141,147,130,109,111,117,128,123,71,23,65,25,17,12,19,30,32,36,36,25,35,49,53,69,51,53,47,28,71,146,154,93,51,19,25,50,34,45,57,39,33,50,63,51,81,141,158,159,157,182,169,104,60,29,38,54,51,57,58,67,76,83,100,101,124,143,155,165,162,152,146,142,140,136,123,72,47,56,76,84,60,49,48,45,38,34,34,28,21,23,25,25,23,29,27,18,24,28,27,27,29,33,26,34,33,37,46,40,32,28,27,28,32,26,25,28,26,24,28,25,24,27,24,25,26,23,24,25,22,22,22,24,34,51,44,23,22,22,24,24,23,23,24,22,22,24,23,27,22,21,23,25,22,17,23,25,23,21,29,46,42,24,19,20,24,25,30,32,37,40,41,38,33,27,24,24,24,24,22,19,27,25,18,21,33,53,40,21,23,27,22,52,60,39,47,52,48,83,106,103,101,94,108,120,122,116,122,123,112,108,113,110,105,105,105,110,111,115,117,125,120,114,90,65,53,54,56,59,64,58,63,62,77,85,83,89,90,75,53,33,23,24,23,31,46,64,91,100,108,105,100,97,97,98,87,89,78,80,73,74,77,70,70,68,64,75,75,66,61,53,57,50,60,61,59,63,59,53,35,27,20,18,24,17,24,32,36,44,51,53,47,52,55,57,54,53,57,55,55,57,58,55,46,42,48,48,46,44,43,50,47,49,45,45,44,44,44,43,45,41,41,44,42,41,43,40,34,43,40,42,39,41,41,42,39,31,78,111,75,33,13,23,27,29,26,27,31,25,27,25,24,27,28,27,33,26,30,36,26,26,29,33,31,30,34,31,26,24,27,24,29,30,30,27,22,28,29,23,29,27,23,29,29,29,33,32,25,31,29,27,29,24,29,28,30,23,31,31,70,94,46,23,21,17,28,25,22,27,33,28,32,41,31,25,24,26,25,29,28,24,26,26,26,27,21,24,24,30,31,29,33,27,24,24,32,29,28,34,32,32,35,31,30,28,31,34,27,29,31,32,32,24,18,23,22,22,24,20,22,25,19,19,21,25,23,17,24,21,19,23,24,21,21,25,19,26,23,23,27,27,85,66,19,29,19,22,21,21,23,19,28,26,29,29,55,101,92,60,32,17,19,22,24,21,23,22,24,23,25,24,19,22,23,23,24,24,25,19,21,25,20,24,23,28,24,22,24,24,30,21,24,25,19,44,84,89,99,142,181,170,82,55,123,171,193,193,197,196,184,169,165,200,212,190,189,187,184,185,189,186,184,187,186,183,184,187,186,185,190,185,184,180,181,189,184,188,188,194,188,184,189,177,187,189,188,189,186,186,181,178,175,176,182,177,177,181,178,178,178,177,177,177,177,174,171,174,170,176,174,184,115,9,2,8,10,14,12,12,12,13,15,15,14,145,171,168,189,158,158,158,76,135,203,243,250,253,253,252,245,244,232,218,198,89,105,155,199,222,69,6,11,21,45,38,36,32,32,36,34,36,34,32,32,39,44,47,54,54,53,57,59,57,57,63,56,53,57,56,51,59,105,111,87,86,93,116,133,141,151,169,192,204,208,224,239,242,241,240,235,235,233,226,227,224,208,191,170,159,138,137,134,112,101,87,66,46,36,39,84,137,190,213,160,120,99,108,118,106,55,3,11,24,38,40,41,47,51,52,38,37,49,59,56,53,47,42,39,77,174,251,251,201,116,24,11,59,75,68,51,36,36,55,48,67,152,192,128,82,76,77,93,62,75,98,117,141,134,147,152,153,159,143,140,135,126,125,121,120,110,79,51,39,36,33,33,30,35,34,19,28,27,21,29,23,25,21,27,29,24,29,19,27,26,26,31,31,40,33,40,48,51,57,56,54,49,46,45,42,37,37,46,45,45,49,47,44,48,47,44,50,43,50,50,46,47,51,49,50,51,49,51,29,44,58,45,46,46,48,41,40,40,37,43,42,48,56,53,50,48,47,47,46,42,48,43,48,50,46,61,63,54,34,27,28,41,45,47,49,48,46,43,39,34,40,39,36,38,35,34,29,31,30,32,30,44,56,39,29,21,42,57,54,52,31,41,50,55,91,103,96,84,87,98,104,104,97,111,111,103,104,102,104,101,101,104,103,114,121,120,102,73,57,36,33,47,55,53,58,61,61,65,68,81,84,73,65,44,33,26,23,24,23,51,66,87,113,107,102,101,100,100,96,93,84,86,83,83,83,89,82,62,65,65,71,78,79,76,69,64,59,54,61,62,62,60,49,37,29,22,22,20,18,23,26,38,44,46,54,54,56,56,53,57,54,58,56,51,55,48,53,51,46,44,44,47,47,49,43,44,49,45,41,47,44,43,41,39,42,42,44,45,48,43,41,41,43,39,41,45,38,42,41,44,47,35,33,32,82,109,70,34,21,24,28,63,50,23,22,27,26,26,29,28,28,23,30,27,29,27,25,37,30,34,30,27,25,20,29,26,28,30,29,33,25,27,24,19,25,33,34,31,27,29,25,29,33,31,32,26,27,29,28,34,29,29,29,27,23,50,93,63,30,22,19,27,27,27,31,25,23,42,37,19,22,29,29,30,26,25,28,22,28,29,20,27,29,24,32,36,31,29,27,28,29,32,32,24,33,33,34,31,33,33,30,27,29,33,30,31,35,26,25,25,19,20,23,19,21,27,22,23,21,21,21,21,19,24,22,20,24,16,23,19,24,24,21,20,24,18,44,93,48,20,27,17,24,21,23,23,19,21,28,29,22,32,64,100,101,63,29,17,22,22,25,24,21,21,23,28,17,23,27,22,23,21,28,25,21,21,24,24,22,25,19,27,23,22,23,23,26,26,25,34,141,182,111,66,63,121,130,41,7,23,77,139,167,190,195,191,160,166,239,250,221,187,178,176,179,177,177,175,178,179,179,181,178,167,171,186,185,184,186,185,192,191,194,196,189,171,181,188,177,184,186,186,189,189,192,193,191,187,186,186,184,185,183,185,185,184,186,184,185,183,184,180,181,180,184,183,188,116,7,1,9,10,13,12,14,11,14,15,15,14,177,194,198,213,184,181,145,75,136,202,245,251,253,252,251,246,243,233,217,181,52,64,139,192,214,65,9,14,26,55,49,53,47,38,38,37,40,43,43,46,54,53,64,61,55,99,64,77,91,107,122,137,148,162,179,178,182,212,223,214,234,243,242,242,237,236,234,232,227,225,220,219,214,206,199,182,169,150,128,122,118,114,116,116,112,84,74,72,46,39,24,12,10,14,11,31,103,145,155,125,107,99,97,105,106,65,5,16,50,49,38,40,46,56,50,35,38,63,103,110,111,98,87,94,149,242,250,250,247,145,36,16,75,107,93,60,31,38,75,87,118,171,151,90,63,35,32,26,45,101,129,91,125,112,118,97,83,53,39,39,33,33,67,27,23,24,27,26,19,26,24,26,29,35,33,22,25,27,23,27,31,29,33,37,36,39,43,45,49,51,56,53,49,75,104,131,152,172,182,190,203,190,186,184,179,179,187,197,192,187,182,148,194,200,198,198,193,192,188,153,184,182,186,194,194,199,200,198,190,158,191,183,193,193,187,116,75,82,85,135,154,174,187,184,183,174,181,182,175,169,178,196,206,202,188,178,152,91,27,9,33,76,141,159,155,164,160,163,153,149,153,149,154,147,145,139,118,106,95,108,123,137,129,97,72,85,96,113,103,68,42,46,38,48,80,79,81,70,70,86,87,82,80,87,94,94,101,98,95,98,105,108,109,85,85,63,45,37,34,34,36,48,50,58,61,61,68,69,62,65,59,46,30,24,19,22,28,47,63,86,101,112,102,94,91,93,98,97,91,84,80,77,81,83,87,77,63,69,66,78,74,73,81,72,65,61,63,69,70,63,52,37,27,20,22,18,19,21,27,41,47,51,50,50,52,56,59,53,58,49,47,54,53,51,48,50,46,45,44,47,47,46,44,43,49,48,44,43,44,43,44,43,42,41,43,46,45,45,42,40,39,41,43,42,42,36,45,42,42,45,40,36,36,27,32,81,109,69,27,17,33,56,35,20,26,24,25,31,26,27,29,27,28,29,25,28,33,29,29,35,29,26,29,26,24,28,33,32,27,29,27,21,23,29,32,31,50,48,27,26,26,33,30,27,29,28,32,27,29,37,27,26,30,30,26,39,89,75,34,23,17,25,24,29,32,24,24,26,25,21,29,29,31,28,29,24,20,32,23,29,39,31,25,24,35,34,34,31,32,24,28,33,29,31,31,35,29,33,34,30,33,32,33,29,32,34,31,29,22,23,19,19,22,22,27,22,20,20,23,24,22,24,22,22,19,24,26,19,21,27,24,20,30,22,27,21,54,92,34,24,26,16,24,22,26,21,21,22,24,24,21,26,29,63,105,93,59,29,19,21,22,24,17,24,24,22,25,21,23,17,19,22,23,28,26,21,23,24,24,23,25,19,21,29,22,24,27,30,25,53,180,178,101,92,57,46,40,14,17,12,37,102,126,154,192,206,178,185,248,247,190,179,177,173,176,176,171,172,173,178,177,179,173,157,165,182,179,177,178,179,186,186,186,181,170,152,168,184,178,180,180,179,183,188,187,189,193,188,182,185,184,185,188,186,185,186,183,185,184,184,186,185,189,185,190,187,193,115,7,1,8,10,13,12,14,13,14,15,14,14,185,195,189,191,167,171,146,81,139,201,249,251,253,253,252,246,244,237,222,172,43,66,141,201,207,49,8,15,20,53,57,59,53,45,53,43,48,62,66,82,95,113,127,142,152,163,181,188,200,214,224,231,236,236,235,230,228,230,222,224,223,218,215,201,184,168,149,131,111,92,81,76,65,48,38,29,32,21,17,14,28,65,115,152,153,94,69,93,71,57,59,59,33,17,14,18,74,127,130,113,110,119,133,121,95,33,3,44,74,66,35,32,51,56,55,35,25,59,103,100,96,87,95,128,189,250,248,246,229,145,33,9,66,133,157,125,36,55,155,151,125,78,55,82,78,55,27,28,31,28,35,41,31,27,30,33,22,22,26,20,26,18,27,24,21,27,25,28,23,27,28,29,36,39,38,34,32,39,45,50,50,57,58,51,69,92,107,130,159,176,194,204,206,214,219,225,225,229,236,235,240,235,234,241,237,236,237,234,224,221,223,230,242,246,238,237,238,238,240,234,235,238,242,241,244,243,249,250,249,249,245,236,211,203,162,110,116,151,213,236,240,245,236,237,236,241,244,244,248,245,246,241,228,191,152,127,96,101,136,172,200,222,239,241,231,230,231,235,229,232,238,237,234,220,222,231,202,171,162,175,198,217,216,186,167,151,140,122,119,109,83,81,53,61,85,71,72,61,66,81,77,71,66,76,83,90,95,93,94,94,103,101,71,52,40,34,39,36,36,36,43,52,51,58,59,61,67,63,53,42,27,26,25,19,34,45,69,80,96,116,96,93,95,91,89,87,87,84,80,81,84,84,80,74,68,65,66,71,81,74,71,66,67,67,65,69,70,66,59,44,21,20,25,22,19,19,26,40,53,53,52,57,49,52,55,51,55,46,53,51,46,52,55,53,42,47,49,43,46,42,46,49,49,47,46,44,41,41,43,43,37,44,45,44,47,40,46,41,37,41,39,39,39,38,43,45,43,43,43,38,38,41,34,26,22,32,87,106,72,35,18,26,23,27,25,23,27,26,26,27,28,29,26,26,25,24,26,29,30,31,29,24,27,24,24,30,29,27,27,27,22,29,28,29,30,29,43,30,25,28,30,27,27,27,21,29,32,26,30,28,30,29,24,24,29,29,69,87,45,27,24,24,25,25,22,24,23,22,24,29,33,34,27,30,30,27,22,21,22,34,38,20,20,29,29,32,29,34,39,30,43,46,34,33,32,31,33,30,35,35,28,28,33,33,30,29,31,31,22,22,23,19,22,22,19,24,20,24,24,22,24,22,22,19,23,23,23,18,23,27,19,21,23,20,29,17,66,81,25,30,24,19,24,19,28,26,21,27,24,22,20,25,26,32,66,99,89,60,32,21,17,23,25,19,20,23,21,23,30,23,21,23,24,23,22,24,28,22,24,29,27,23,22,25,23,27,18,30,22,88,174,139,163,175,145,125,94,59,30,37,87,122,117,115,159,204,178,182,215,173,145,149,157,159,164,167,163,164,168,170,169,172,167,151,157,169,164,164,166,165,166,162,162,162,154,141,159,174,167,176,174,171,173,175,171,167,175,177,174,177,176,174,177,183,183,180,178,179,181,179,183,184,185,186,188,185,191,115,7,1,8,11,13,11,14,13,15,15,14,15,175,177,171,170,154,165,123,69,124,191,242,251,253,253,251,250,244,241,230,178,59,93,165,218,222,75,56,73,84,125,127,151,149,152,166,171,184,203,212,223,232,234,234,227,222,168,215,212,209,202,195,189,178,160,153,127,127,112,77,109,112,68,65,42,19,9,13,13,19,16,18,34,33,32,26,19,26,28,26,29,36,43,96,127,113,81,61,79,81,92,109,128,141,145,104,66,105,139,133,110,99,100,110,112,110,53,1,57,130,135,129,139,147,147,113,54,23,38,56,49,36,48,92,134,169,201,216,208,190,109,22,4,76,128,135,102,35,59,137,116,59,29,21,59,61,33,23,15,24,27,21,27,27,26,25,17,33,27,26,30,27,33,26,37,46,43,43,31,39,46,47,48,56,59,54,53,66,90,112,146,167,189,203,207,213,214,214,220,232,234,236,230,220,211,199,189,173,172,179,183,188,188,190,194,193,190,185,180,176,180,184,187,184,171,168,179,188,192,190,188,193,186,186,185,191,206,205,214,211,206,166,91,68,77,131,154,179,212,211,219,212,209,211,216,224,220,210,191,174,145,117,87,60,59,78,118,152,184,208,223,224,220,221,202,193,196,186,182,183,185,193,195,193,186,192,201,175,141,128,133,142,161,181,171,162,139,122,103,97,103,90,88,91,107,119,84,85,88,77,89,77,68,72,67,80,79,80,89,87,86,78,69,49,45,43,43,38,38,44,43,72,89,63,58,59,59,52,36,33,24,23,26,30,50,63,83,105,106,100,104,92,89,84,81,78,83,78,78,79,87,84,74,77,61,72,69,77,87,71,77,61,65,66,75,79,65,62,45,27,26,21,19,21,19,27,43,51,55,60,49,49,51,50,50,44,47,53,47,48,53,51,48,50,46,44,48,44,46,48,46,50,46,45,44,43,39,45,45,38,43,43,44,43,43,42,42,44,40,39,38,38,39,43,41,43,39,39,39,40,39,41,37,35,33,24,26,32,82,108,69,31,16,21,27,26,27,26,24,27,28,27,32,24,26,28,24,29,27,29,31,26,25,23,25,32,29,26,26,22,30,25,27,28,26,27,26,29,23,27,33,23,26,27,27,29,28,35,25,24,29,27,27,29,31,27,29,54,89,61,27,25,24,27,24,23,23,26,25,33,29,35,41,27,24,24,27,21,22,30,26,17,17,24,27,29,36,33,30,39,39,44,46,41,41,38,27,29,27,33,31,32,36,33,28,30,29,31,29,21,23,27,25,21,24,19,21,24,18,22,22,24,23,20,24,22,17,21,23,20,22,21,24,24,20,21,26,83,67,21,30,20,16,23,24,26,21,24,24,24,22,22,23,21,28,33,61,102,93,61,33,15,21,23,21,20,19,25,23,23,25,24,24,22,26,22,22,23,25,24,26,26,22,25,23,25,26,31,19,57,175,207,213,230,217,215,214,200,166,155,140,112,113,92,51,89,141,134,145,171,157,147,154,152,141,146,156,150,149,146,145,143,146,139,120,128,141,139,139,139,137,133,133,133,139,139,127,144,146,143,153,152,152,148,153,141,139,155,157,158,162,162,163,166,169,170,169,167,171,173,177,176,174,180,182,188,178,186,116,8,2,9,11,13,11,14,12,13,14,14,13,143,150,142,148,141,144,104,48,98,165,227,252,250,250,250,250,246,246,242,212,119,151,195,246,243,155,177,192,207,217,205,218,221,223,222,220,220,218,216,216,215,221,206,184,162,141,132,122,110,98,91,88,83,76,70,62,79,69,14,8,11,18,33,39,45,39,40,48,48,46,43,50,51,44,41,38,33,35,39,41,52,47,45,39,33,24,32,43,36,54,87,138,198,249,228,156,148,168,197,193,188,190,200,204,229,147,19,79,182,223,220,212,208,187,168,69,28,61,85,77,60,78,122,138,95,101,116,129,113,70,36,14,30,49,60,61,39,39,54,51,57,38,49,62,27,25,24,21,29,29,32,37,38,43,45,47,55,60,59,60,74,78,56,66,132,137,86,74,88,118,143,160,173,184,197,204,208,217,225,232,238,241,240,232,230,216,209,203,198,194,186,186,175,171,174,170,164,158,155,156,164,159,154,155,150,150,151,156,165,169,164,150,141,134,141,155,162,168,170,173,175,169,166,180,193,186,160,120,102,97,63,55,82,138,179,199,203,196,193,185,188,197,201,192,171,140,106,68,41,39,67,97,124,152,169,183,190,201,198,191,183,174,171,165,168,165,160,154,155,165,166,174,174,170,182,189,165,125,112,114,97,99,111,109,100,93,86,77,94,92,77,91,114,141,136,102,103,107,108,100,84,81,81,74,76,78,78,81,72,71,67,61,57,50,56,49,51,48,42,54,101,89,60,59,46,41,29,26,21,24,37,58,76,84,98,98,100,95,87,90,81,83,81,77,75,76,82,72,75,77,71,61,59,55,64,81,80,80,75,67,72,73,81,81,73,51,33,22,19,21,16,21,27,38,53,53,54,54,51,51,47,49,46,51,45,47,53,46,50,50,49,47,48,45,47,50,45,48,51,44,50,48,42,45,43,43,40,42,44,43,46,42,42,42,39,37,40,38,37,37,41,49,42,41,36,41,43,37,43,38,35,42,39,35,27,24,26,35,86,108,69,29,16,25,30,26,26,27,30,24,24,29,31,29,25,32,30,27,26,31,23,25,28,28,32,22,29,28,25,29,30,27,28,27,24,26,32,27,25,31,48,33,28,30,27,30,26,29,25,27,21,23,32,28,25,26,38,87,76,35,23,20,26,20,24,24,24,31,27,31,35,31,23,25,27,26,23,19,22,28,22,24,24,26,28,34,29,36,31,25,35,32,45,44,41,34,25,33,32,28,34,29,34,29,33,32,26,23,25,26,21,24,26,23,19,21,19,27,21,19,24,24,24,20,22,21,19,20,22,25,23,25,17,26,24,34,90,53,18,31,18,17,27,24,17,23,23,22,22,21,24,23,23,27,23,29,70,105,92,64,31,14,19,20,24,24,19,24,23,20,24,23,24,23,20,20,25,22,19,25,20,24,24,23,28,28,29,24,139,230,238,240,202,170,165,195,204,192,199,177,119,96,63,13,9,30,53,97,163,194,222,233,212,177,177,189,178,169,160,156,153,153,155,142,141,150,153,154,152,148,142,145,146,149,154,146,146,132,113,124,129,135,136,135,122,117,133,139,139,145,143,146,149,147,148,151,151,157,161,160,166,165,169,171,177,165,168,113,10,2,10,10,13,12,15,13,14,15,15,15,148,152,150,154,155,162,132,109,146,190,243,247,248,248,247,247,243,243,242,216,166,180,184,207,193,156,192,190,192,193,179,174,163,159,152,144,133,122,102,77,68,84,95,98,106,104,106,105,104,112,111,116,125,127,134,129,150,134,75,39,6,19,32,59,91,96,94,100,98,93,101,82,71,69,71,58,50,42,37,55,83,97,89,76,66,53,33,36,26,33,70,142,228,251,251,231,229,248,252,252,253,253,252,252,245,198,28,45,144,166,143,111,93,85,54,32,35,60,142,183,176,145,110,90,55,35,22,17,17,17,34,30,50,59,53,51,27,42,46,49,54,53,62,52,52,42,47,49,59,53,54,75,89,120,140,150,173,181,206,205,232,189,92,126,214,226,224,213,224,231,241,235,237,229,226,221,215,221,212,208,199,194,186,185,184,179,182,179,181,177,172,173,173,177,178,179,174,163,161,158,161,163,159,162,157,160,170,166,173,175,165,163,156,153,156,163,171,172,176,177,191,187,187,180,163,152,73,35,35,86,151,160,185,202,210,208,199,193,170,152,132,105,111,66,41,43,66,99,130,156,175,185,199,208,204,193,181,179,175,172,169,164,165,165,169,174,166,162,167,163,160,165,160,159,170,179,170,130,108,112,101,74,75,41,19,49,69,61,52,62,57,84,127,147,147,117,124,135,132,131,110,105,98,90,92,88,90,87,88,83,89,84,76,74,72,66,66,64,53,57,63,53,41,38,27,27,27,25,43,60,75,92,105,98,89,88,90,91,89,83,85,84,83,74,72,77,81,75,71,64,57,53,54,55,75,73,75,76,73,83,77,84,74,49,39,22,20,19,14,19,27,42,51,53,54,57,53,49,53,46,45,46,49,46,50,53,48,49,49,49,48,48,49,44,48,51,49,47,40,47,45,42,46,44,44,43,45,43,42,45,40,43,45,36,37,40,38,39,42,44,45,39,37,41,40,41,37,37,37,38,44,41,41,37,30,24,28,24,31,81,103,71,29,33,36,22,28,27,24,25,26,28,27,25,32,28,29,32,24,27,24,27,30,25,33,24,26,26,26,33,28,25,26,26,27,33,28,31,28,48,56,24,26,27,34,29,28,31,22,29,24,28,22,26,28,23,31,71,93,46,19,18,21,25,22,21,30,33,27,29,26,24,28,30,26,21,24,26,21,21,27,29,24,26,29,29,29,37,31,20,30,34,30,41,44,33,25,29,36,27,33,32,27,33,31,30,29,27,24,17,22,24,22,27,22,24,21,21,25,23,22,20,24,25,24,20,23,19,26,25,18,28,19,26,21,45,92,39,24,30,17,27,24,22,25,23,24,24,19,23,24,21,23,25,23,21,32,71,110,97,61,26,17,26,27,20,20,21,22,26,26,23,22,25,22,22,18,27,23,22,23,25,25,27,23,29,22,57,180,227,211,170,131,100,114,168,175,170,196,195,153,149,104,18,7,13,13,42,114,213,253,253,251,230,232,248,238,233,223,220,219,227,229,226,231,232,233,234,230,227,224,224,225,228,229,215,212,190,165,177,181,182,181,177,159,151,160,158,158,159,154,151,149,146,150,147,146,148,149,150,153,151,154,155,165,146,145,108,13,2,9,10,13,10,14,13,13,13,14,14,191,194,192,193,194,205,196,193,202,206,221,222,206,194,182,176,181,174,170,153,131,133,123,127,108,90,124,121,122,121,119,122,114,119,120,122,121,115,99,35,5,13,46,105,142,155,158,159,166,175,183,191,196,195,206,196,205,192,153,139,50,20,58,105,155,151,144,137,131,129,125,122,113,110,123,122,114,64,29,77,133,179,186,162,151,98,85,77,59,81,104,171,238,248,241,227,227,233,253,253,248,247,226,196,194,93,6,20,71,75,47,38,36,35,37,26,25,71,171,206,168,102,59,69,63,49,17,12,9,26,33,37,89,107,88,62,31,38,64,62,59,62,57,59,101,139,153,174,194,200,211,216,220,221,227,231,232,232,232,229,240,156,100,174,210,214,210,223,226,224,217,207,193,185,185,174,168,171,169,169,169,170,171,164,169,170,174,167,166,171,168,175,169,174,173,171,170,168,167,165,163,160,169,170,167,167,166,169,170,165,167,174,170,159,171,171,175,187,180,189,190,187,131,76,68,78,95,102,145,194,212,230,232,222,203,176,156,123,80,51,24,18,47,77,101,115,131,153,174,191,198,196,194,188,180,177,173,176,165,169,173,161,168,171,174,169,167,167,168,168,155,158,155,155,167,174,166,144,125,108,96,86,70,24,4,27,47,39,33,36,31,81,133,154,147,127,132,139,137,123,111,106,97,90,93,90,93,100,98,100,105,107,96,87,75,78,92,74,58,46,36,29,28,27,25,31,46,64,71,82,89,92,90,89,82,76,81,80,79,86,78,81,78,81,79,76,83,75,65,51,50,57,66,69,76,78,74,75,76,85,79,60,40,21,19,19,21,18,25,38,48,51,56,54,50,49,51,49,46,49,42,48,53,48,49,46,48,49,45,45,46,43,45,46,46,46,45,40,43,44,42,43,40,44,46,46,45,39,38,41,41,39,37,38,44,43,46,39,39,38,36,40,37,39,39,38,38,42,42,40,42,39,36,35,33,26,23,28,26,30,80,108,75,46,25,19,24,24,30,31,27,28,26,24,32,32,24,26,27,25,29,29,23,26,27,25,28,27,39,28,22,29,25,26,29,32,28,23,29,29,29,23,29,33,29,31,27,26,28,24,26,24,24,31,26,24,24,54,97,60,26,17,25,26,31,32,27,29,28,33,25,27,31,27,35,29,23,23,20,27,26,27,25,21,31,32,31,34,27,21,29,41,39,30,35,34,29,33,30,29,29,32,29,23,29,29,28,30,21,21,24,19,21,23,23,24,22,24,20,20,21,24,27,21,19,22,24,23,24,23,24,23,19,25,18,65,86,25,26,25,18,25,25,22,23,23,19,23,20,27,24,23,26,20,23,21,25,30,69,113,96,60,31,18,21,19,24,24,19,23,24,22,21,22,24,22,28,23,24,23,23,29,22,23,21,31,23,75,210,229,184,186,173,137,145,178,171,166,182,184,181,194,162,112,122,91,39,21,96,194,248,248,250,232,249,252,252,252,252,252,252,252,253,253,253,253,253,253,253,253,253,253,252,252,253,253,251,251,249,249,249,249,246,246,239,237,238,233,231,229,223,214,206,195,195,189,184,182,174,171,171,161,158,155,157,136,130,103,14,1,9,9,12,10,12,11,12,12,13,13,178,178,171,167,158,165,154,158,163,140,123,97,83,71,53,40,48,63,76,90,112,134,143,166,150,124,139,137,143,145,146,155,153,159,165,169,170,169,160,81,9,22,73,142,184,186,182,167,162,164,159,159,154,149,147,136,137,127,121,97,21,23,60,98,128,122,122,128,132,138,149,150,167,171,183,192,198,94,21,77,155,210,222,210,175,134,112,95,105,132,132,165,208,223,201,162,136,134,178,168,133,107,84,69,59,23,7,53,99,118,110,111,124,124,74,24,17,65,148,118,73,61,57,103,104,87,80,83,105,139,41,30,139,154,122,86,67,102,107,112,83,34,36,110,168,239,240,244,245,242,231,219,207,201,197,188,189,188,184,186,188,90,78,177,184,181,174,168,163,158,167,162,165,163,162,159,153,156,150,151,156,160,163,159,158,161,160,154,154,160,162,160,158,158,157,150,151,160,164,169,164,159,157,145,139,137,135,138,148,152,152,160,173,182,179,186,185,182,167,106,103,81,45,54,78,151,186,211,222,220,203,171,150,119,87,51,28,22,44,89,117,134,124,165,161,151,145,152,162,166,169,179,176,165,168,166,158,164,164,155,157,159,163,162,156,165,170,170,160,147,151,159,156,150,160,162,163,154,137,106,72,95,112,57,8,32,59,59,72,78,68,96,122,121,116,98,112,105,95,93,83,92,89,94,89,87,101,107,111,107,114,103,105,95,85,89,72,55,33,24,24,25,29,39,50,63,76,79,92,85,81,80,79,77,73,76,74,76,77,71,78,82,86,81,74,77,65,63,53,50,64,71,77,76,84,81,76,79,68,61,44,25,16,19,26,20,25,38,48,55,50,51,52,51,49,46,47,50,42,50,49,47,49,49,46,46,45,45,47,48,50,48,44,45,46,45,40,46,48,40,44,45,47,43,44,44,40,41,41,43,38,42,43,44,45,43,45,39,41,39,36,43,37,40,39,39,45,40,38,41,35,37,37,35,33,24,26,21,24,28,30,82,104,78,35,21,27,21,26,29,25,24,32,30,24,30,31,22,24,29,29,26,25,27,27,24,28,34,26,24,27,28,33,26,29,27,24,25,21,28,28,27,34,32,32,33,27,27,27,29,23,26,25,25,22,24,30,39,86,74,33,23,20,29,31,36,31,24,33,29,26,24,18,37,49,29,18,25,28,24,27,27,27,29,28,29,32,29,24,24,28,34,37,34,35,33,31,35,27,30,29,30,32,27,28,31,31,28,24,19,21,23,23,24,26,23,20,21,21,23,29,21,19,23,23,20,23,23,22,22,23,22,22,24,26,78,71,18,27,22,17,22,23,26,24,16,23,28,20,23,21,22,23,23,25,26,28,22,33,80,114,97,66,29,15,23,18,23,23,24,25,23,24,23,25,21,30,29,20,24,19,24,23,24,27,24,40,126,218,213,185,215,225,184,166,184,182,171,178,182,177,196,189,166,191,172,130,147,171,178,162,159,179,170,215,250,251,251,249,249,253,253,252,252,253,253,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,252,252,250,247,243,239,234,226,219,217,213,199,194,186,183,157,148,107,10,1,8,8,11,10,12,10,11,13,13,12,105,109,101,98,87,90,71,65,93,103,106,96,82,86,56,18,13,24,69,117,152,181,208,249,227,173,178,170,176,176,179,181,173,177,173,176,171,169,163,83,16,28,73,127,145,134,118,102,90,81,74,69,64,62,62,53,61,60,69,59,12,27,73,130,168,168,171,179,188,193,198,204,207,213,217,228,220,113,28,69,159,236,244,239,211,123,93,89,110,155,127,103,112,127,120,77,36,38,86,118,127,126,133,150,182,74,9,112,190,205,183,168,161,152,104,41,19,58,127,87,52,66,64,108,106,129,186,237,249,249,111,38,129,144,125,72,97,158,145,152,120,36,21,113,212,220,212,209,205,208,200,181,170,169,164,156,163,167,159,165,136,40,92,162,152,163,145,137,122,127,135,126,132,126,142,154,160,164,144,149,152,151,143,144,152,151,154,141,150,151,144,136,131,149,150,134,137,162,175,193,185,177,176,153,155,147,131,147,162,159,147,165,196,184,193,185,165,134,51,12,46,119,155,179,207,212,206,174,140,111,61,31,14,28,62,92,105,120,156,191,185,184,199,193,184,154,161,179,199,203,184,178,157,160,162,140,156,168,158,145,156,164,167,160,159,170,174,167,140,152,163,167,152,157,176,162,162,156,143,108,78,92,117,81,48,76,96,86,106,118,93,90,82,80,79,78,80,84,92,86,83,97,97,102,102,97,108,108,107,116,121,120,105,90,62,39,34,22,26,31,30,42,55,67,77,87,89,92,79,80,82,78,79,71,78,81,75,74,75,86,87,88,78,76,66,60,61,56,60,66,81,81,79,80,77,87,85,66,42,27,20,21,24,24,27,42,49,50,51,50,49,49,51,51,49,49,46,48,49,50,48,45,48,49,41,48,48,49,50,47,52,47,42,41,44,46,44,46,44,43,47,50,43,42,42,45,39,41,41,42,41,44,46,43,39,37,38,39,40,36,37,40,37,38,45,42,36,39,36,41,36,33,38,37,38,31,26,22,26,28,25,29,79,108,75,42,21,22,24,24,26,29,26,26,23,27,31,25,25,29,28,23,27,28,22,27,30,28,24,27,27,24,27,31,29,22,32,26,23,26,33,32,29,46,43,25,25,30,24,24,23,22,25,24,27,27,29,25,68,91,48,26,21,30,33,32,29,27,28,27,28,24,26,28,32,24,21,24,20,39,39,23,27,36,29,27,35,29,25,21,27,32,33,31,37,35,23,31,32,30,34,30,33,29,29,24,26,27,19,21,20,22,21,24,24,20,27,23,23,20,27,28,22,23,21,22,23,22,23,23,27,22,25,17,34,87,54,23,26,15,24,21,22,23,18,21,23,25,18,25,23,25,24,20,27,21,23,21,24,32,71,113,99,62,32,21,22,24,23,23,21,19,27,25,18,25,23,22,24,23,21,24,24,24,27,35,92,119,153,142,109,179,208,169,154,152,162,163,167,183,188,203,197,182,206,216,219,240,237,170,76,24,43,77,133,175,207,202,174,175,219,244,252,252,252,252,252,252,253,253,252,252,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,252,252,252,252,252,249,244,242,241,234,233,226,226,207,198,114,4,1,6,9,10,9,12,10,13,13,13,13,106,113,113,118,109,118,63,39,91,132,152,147,141,141,91,22,16,34,91,148,173,191,227,245,231,170,163,152,154,152,145,144,129,122,119,113,108,94,79,29,13,39,61,95,96,84,79,71,78,79,87,94,96,105,116,117,124,126,149,128,27,30,94,168,215,216,221,225,227,230,228,224,226,216,203,195,188,65,1,35,89,145,142,126,89,59,58,50,82,122,98,59,42,35,38,24,14,43,126,210,253,253,250,250,246,141,23,110,181,191,150,118,108,97,56,31,26,51,136,150,128,132,146,123,66,137,219,253,242,237,86,16,102,93,56,42,116,199,167,170,129,18,16,113,192,200,191,194,191,189,188,179,171,178,166,152,167,167,167,160,100,50,127,168,155,167,163,163,145,155,165,160,165,152,158,166,180,182,161,165,174,176,162,158,165,177,169,155,164,169,170,153,157,170,181,186,171,183,199,229,229,177,168,165,199,223,199,185,200,227,222,206,200,190,143,106,96,127,174,156,175,211,214,207,168,137,108,66,40,40,78,127,143,160,183,218,241,222,207,218,228,201,190,199,229,207,179,199,234,234,178,159,157,196,229,210,177,181,212,212,190,179,202,216,193,178,188,217,212,186,184,217,224,191,183,163,165,160,139,128,98,99,112,82,73,95,96,109,120,115,103,93,86,84,93,76,95,100,101,106,97,105,99,104,102,103,113,106,110,125,117,82,50,33,30,24,27,29,35,51,54,65,76,86,91,88,88,80,80,78,81,78,78,79,70,82,80,79,84,86,87,78,74,64,57,59,57,67,74,76,96,89,89,89,85,78,42,29,21,17,17,21,29,38,51,51,54,58,51,50,53,51,50,51,48,45,50,52,49,49,44,47,44,41,46,44,49,49,47,47,47,44,44,42,43,46,46,44,43,46,47,44,41,41,40,40,41,39,45,47,45,43,37,40,39,39,42,35,41,37,41,44,39,42,34,33,38,36,38,36,30,35,37,35,39,32,29,25,27,24,21,27,31,84,114,84,52,24,19,26,26,27,25,26,26,24,28,33,32,25,26,29,30,22,26,29,25,23,25,27,25,28,25,26,26,30,29,24,28,31,32,25,29,35,33,22,28,28,19,27,22,25,29,28,39,29,26,25,50,93,66,37,26,24,29,28,29,29,32,22,28,24,22,33,22,21,26,22,29,36,29,22,29,35,35,32,29,33,24,22,25,29,32,31,37,32,31,28,32,28,35,31,28,28,31,27,29,26,22,22,17,21,26,23,22,21,27,27,19,21,22,26,21,23,22,20,26,18,25,24,23,21,27,19,50,94,43,23,28,16,25,19,21,26,18,24,22,19,22,25,23,24,25,25,22,23,23,24,21,21,33,75,111,95,63,29,16,22,19,23,23,21,24,23,24,21,24,24,19,26,24,24,27,25,30,89,92,44,80,72,55,122,149,130,116,99,116,141,161,185,200,220,211,184,211,229,229,246,231,200,122,14,9,27,48,83,130,142,114,122,179,233,238,236,224,217,236,241,248,248,252,252,252,252,252,252,253,253,252,252,252,252,252,252,253,253,252,252,252,252,251,251,250,250,252,252,248,240,236,243,245,250,253,248,250,247,227,112,3,1,5,9,10,10,12,12,13,13,13,13,150,160,160,165,154,155,87,56,116,151,172,168,162,166,122,45,33,53,100,151,161,170,188,226,169,97,102,93,95,89,88,79,71,71,66,66,66,65,58,23,18,62,97,141,157,159,168,174,187,192,200,206,208,214,219,215,218,210,218,175,60,39,99,188,238,245,239,235,227,216,194,180,159,134,110,90,72,17,18,35,25,23,15,16,11,16,39,69,74,73,71,79,55,21,35,64,107,146,188,249,252,252,246,246,240,98,2,56,98,96,61,47,40,30,28,34,25,53,152,209,187,197,206,208,84,46,157,179,159,107,8,19,81,83,73,44,132,237,194,165,120,16,13,106,183,188,184,164,119,115,145,164,184,233,249,200,176,188,228,228,103,87,214,248,215,190,185,224,210,178,179,207,249,225,181,181,227,251,193,170,204,249,236,176,181,240,251,205,179,210,251,244,177,197,250,250,189,157,165,203,135,85,125,149,243,250,205,186,242,248,222,141,148,93,45,56,133,248,250,190,141,126,92,50,21,65,184,220,147,152,234,250,247,203,235,253,252,199,185,252,251,193,168,224,250,204,149,165,210,170,92,122,160,245,250,213,162,208,250,225,153,175,249,248,164,161,230,251,216,166,211,251,248,181,162,140,158,155,138,131,122,118,103,66,55,91,103,107,118,118,117,114,111,109,105,106,106,106,112,110,100,108,99,100,109,118,129,114,105,82,33,23,30,24,33,42,51,62,70,76,74,83,88,81,82,82,82,82,77,81,82,79,78,74,83,88,84,86,80,69,71,62,50,64,58,67,69,72,82,89,105,103,98,79,46,33,19,19,19,18,29,37,51,59,51,59,53,55,53,46,51,49,46,49,53,46,44,49,47,46,43,45,48,45,46,52,46,44,44,49,40,41,46,40,43,44,53,45,41,42,42,41,40,45,39,41,40,47,45,41,43,41,39,39,42,38,39,41,38,39,39,38,41,34,40,38,35,40,32,34,36,39,38,37,38,32,33,27,23,28,29,27,29,27,73,117,86,51,21,23,31,27,23,24,23,29,33,32,27,26,30,26,28,28,26,24,29,28,24,33,28,21,29,28,27,24,25,30,31,34,28,25,24,26,22,23,27,24,27,24,27,25,39,49,28,29,24,24,35,81,93,42,24,19,27,32,28,25,22,29,25,27,29,23,22,26,26,25,26,30,20,24,30,30,31,29,32,27,27,22,23,29,35,34,32,33,33,27,27,35,33,29,31,29,33,28,30,29,23,19,20,21,19,24,20,21,26,26,23,17,24,19,22,28,19,27,21,22,23,18,27,20,27,23,67,86,28,24,24,19,22,16,25,23,20,24,22,21,24,23,17,26,21,21,23,23,26,21,24,25,21,33,71,114,98,60,36,18,19,21,23,24,19,24,26,23,24,22,21,28,26,25,26,31,95,138,82,27,78,85,48,91,111,125,136,105,141,168,165,189,203,214,191,165,192,208,208,227,232,240,201,104,116,94,43,28,48,82,118,155,178,174,150,156,140,127,149,155,166,216,249,229,160,186,207,195,198,208,218,242,251,251,249,249,252,252,252,252,252,252,250,250,250,250,251,250,237,221,222,236,250,252,252,252,252,252,237,109,2,0,6,9,12,12,11,11,13,14,14,13,182,181,178,175,169,165,91,74,129,162,171,160,149,153,109,36,42,54,92,120,112,108,123,136,75,46,70,71,83,87,89,103,110,118,130,139,155,160,167,78,28,84,135,205,229,237,244,240,248,245,248,248,248,247,247,242,238,227,219,162,44,25,65,108,191,178,159,135,120,97,74,62,56,56,59,69,67,23,28,43,44,50,33,29,48,78,90,99,73,51,64,89,92,59,84,156,206,227,184,188,221,202,168,138,107,20,14,53,76,89,83,94,98,95,49,61,57,87,128,140,114,134,183,191,35,14,87,92,90,67,9,34,115,128,99,60,118,196,190,204,163,33,7,93,169,177,153,100,43,54,103,131,166,245,251,165,158,199,250,210,72,137,249,250,201,165,188,235,191,149,157,204,250,204,155,165,197,213,165,152,188,208,190,156,171,237,253,175,159,200,251,217,163,184,236,231,147,120,123,102,74,100,138,158,217,227,163,146,162,169,95,60,63,72,34,60,76,115,117,61,36,54,125,84,107,160,247,250,200,193,237,249,208,165,177,214,215,163,154,198,205,172,163,187,207,166,141,144,192,110,88,144,148,206,226,170,139,165,197,170,148,158,188,177,150,156,198,218,173,152,174,216,196,157,151,133,146,147,132,135,135,136,109,70,61,54,57,97,106,103,110,107,108,111,109,108,115,108,110,118,114,117,102,115,118,103,86,56,30,25,25,35,39,47,67,81,93,93,88,83,81,79,85,83,79,80,83,83,88,84,86,83,84,90,81,84,76,77,66,63,63,51,56,56,64,73,71,92,96,100,108,85,55,32,19,21,21,19,24,35,51,60,59,58,55,53,53,53,53,49,46,49,50,51,47,45,45,44,45,44,44,47,45,47,44,43,51,46,44,45,43,46,43,45,46,44,39,44,46,40,45,45,45,43,43,45,42,42,43,42,39,42,37,41,35,36,38,44,41,37,38,34,39,36,35,36,33,36,40,39,41,38,31,36,33,35,33,29,23,35,58,31,21,27,23,70,109,86,57,27,20,24,20,26,24,37,35,24,30,24,20,24,24,28,34,21,28,24,26,27,23,26,31,23,24,27,25,36,31,28,26,24,30,23,27,28,26,47,35,24,22,29,44,30,27,23,22,24,34,73,92,61,27,23,24,29,27,26,28,22,27,29,27,26,30,30,26,24,27,29,19,24,26,28,29,29,33,29,27,21,34,31,34,33,33,33,30,26,29,33,30,31,29,31,29,30,33,29,26,19,16,22,24,22,27,19,22,23,21,27,23,18,19,19,24,24,21,23,23,21,18,25,22,23,84,69,19,26,20,19,23,18,24,21,16,25,23,22,24,19,23,24,21,22,24,27,22,24,22,24,21,23,37,72,106,98,62,32,19,19,23,26,22,19,27,21,25,22,22,28,20,24,25,87,162,171,109,89,149,134,97,121,141,177,193,170,199,191,179,205,205,200,181,172,194,194,199,222,226,242,217,175,211,173,84,29,9,36,104,141,154,137,133,167,143,128,137,131,127,176,234,151,52,74,115,117,120,140,150,204,243,216,183,154,182,206,213,224,202,234,253,253,249,249,251,250,237,213,220,245,252,252,251,251,252,252,231,111,4,1,6,10,11,11,13,12,14,13,14,14,160,159,148,137,128,127,66,59,108,117,121,100,92,89,37,10,41,57,88,112,107,114,120,134,110,110,142,150,171,184,195,200,208,218,222,224,225,227,222,104,21,71,137,208,229,232,233,223,221,214,205,198,193,181,171,157,148,128,108,62,16,21,17,23,23,15,14,12,13,15,14,31,64,91,123,150,147,55,38,110,192,238,235,229,222,185,95,59,70,64,71,71,37,39,68,110,126,103,70,62,85,101,107,117,112,27,24,118,178,186,155,151,148,127,95,95,127,122,104,81,41,57,97,77,9,55,146,180,208,190,46,29,118,125,100,38,83,146,142,208,206,49,3,83,166,188,176,153,126,130,146,141,144,155,146,135,142,165,192,134,50,120,190,178,162,152,152,168,153,147,155,171,194,154,147,150,160,162,139,148,150,152,139,143,148,155,155,141,144,142,159,147,143,154,174,165,139,153,158,178,163,182,212,194,213,181,109,98,73,52,47,55,92,74,38,25,15,51,78,102,154,174,188,188,189,198,206,188,159,160,173,177,147,145,152,160,151,142,151,165,159,152,163,167,167,145,153,165,180,159,155,173,146,159,162,137,148,161,171,157,160,169,169,162,159,171,177,171,153,161,157,160,142,150,161,124,145,145,139,138,139,141,131,111,83,66,66,94,99,97,100,93,95,95,89,104,110,103,105,111,108,101,88,66,45,22,19,27,30,36,39,73,104,107,111,99,91,88,84,82,82,89,88,83,82,82,83,83,85,84,81,86,86,78,70,61,66,66,57,62,66,64,64,63,64,83,83,93,111,96,63,34,30,21,18,18,24,39,45,56,60,61,59,55,51,52,53,54,50,47,53,50,47,46,47,47,49,44,42,47,48,49,48,47,39,41,45,45,41,43,45,46,47,43,41,41,41,41,42,43,44,45,42,46,44,37,39,37,41,39,42,37,35,44,40,38,41,42,39,36,39,38,37,37,33,39,43,36,35,39,34,33,34,32,35,34,33,27,23,29,39,25,21,24,24,23,60,108,93,57,26,16,30,26,32,34,22,23,27,24,24,31,27,24,24,29,29,24,24,23,26,27,27,26,24,29,39,30,23,26,21,26,28,22,32,25,36,38,24,26,25,29,22,26,26,25,25,32,34,45,95,75,33,27,24,24,26,23,27,29,25,25,30,28,27,25,24,28,25,29,25,16,26,30,31,31,32,32,27,22,30,34,30,32,36,36,34,24,35,34,26,33,29,26,33,36,34,25,24,19,21,19,17,22,22,23,22,24,22,24,24,23,26,23,20,22,24,25,21,20,20,27,27,42,91,53,20,26,17,19,21,26,21,26,22,19,23,22,23,18,25,23,16,26,21,22,24,21,27,24,21,23,24,33,69,105,99,57,32,19,20,22,18,29,29,23,26,23,27,23,24,25,62,120,137,120,101,129,150,125,106,130,150,171,181,170,181,178,179,195,198,200,194,185,194,184,172,183,178,188,172,152,195,155,119,123,54,20,38,57,89,97,133,171,163,160,163,154,140,174,241,152,29,77,134,132,134,143,143,184,199,154,113,61,100,141,149,162,117,167,245,246,247,247,252,252,242,221,221,242,249,249,249,234,231,206,182,107,9,1,9,10,12,11,13,12,13,14,14,13,88,89,84,70,68,63,26,39,78,92,95,87,82,89,41,17,53,83,146,176,190,205,229,245,201,185,199,201,220,225,226,227,225,226,222,218,213,212,196,80,23,54,92,162,173,164,146,127,118,100,94,83,73,70,59,46,31,16,11,15,28,39,33,42,49,42,37,22,18,13,25,44,69,83,93,105,87,44,47,116,204,251,245,243,232,146,39,32,75,98,96,40,12,22,45,73,57,49,38,44,79,139,174,194,172,32,20,103,158,150,103,93,80,63,30,70,137,147,157,144,117,127,198,167,45,107,228,252,242,228,76,30,95,88,56,33,108,169,146,165,165,49,1,41,110,162,203,218,205,196,190,175,162,163,150,144,170,166,157,67,50,150,174,168,154,156,163,162,150,163,163,160,161,139,152,155,160,158,150,165,167,165,150,155,158,159,150,145,158,154,155,144,151,159,159,159,159,186,208,218,217,207,178,158,127,54,25,15,41,45,19,33,55,88,116,136,155,174,184,191,205,213,205,193,180,177,175,157,152,165,167,162,151,160,164,166,166,158,158,155,138,130,134,143,146,147,157,165,182,182,178,168,156,162,155,150,154,161,161,156,160,162,170,165,159,144,163,162,159,164,158,158,156,162,163,134,139,151,143,131,133,142,130,128,129,110,105,111,100,93,96,89,84,78,77,77,78,76,71,49,41,35,19,24,19,27,33,68,71,104,121,134,124,112,101,93,91,87,86,80,85,89,88,81,78,84,85,78,80,77,83,80,73,65,57,59,60,66,63,66,70,66,76,75,89,95,91,102,66,35,31,18,20,25,23,31,43,58,57,58,62,57,57,52,53,49,47,55,50,52,51,42,43,47,49,44,44,45,47,47,46,44,43,45,40,43,41,46,45,47,46,39,43,39,42,44,39,38,46,43,46,42,41,45,38,39,40,38,37,40,41,42,41,44,42,39,37,37,34,35,41,36,39,34,33,43,40,37,33,34,37,39,28,29,33,29,39,32,25,21,23,22,24,26,19,33,25,52,108,95,62,35,20,31,25,23,28,22,24,23,29,31,24,31,25,28,21,19,32,26,31,27,24,27,30,39,25,19,25,29,27,23,27,27,27,24,21,28,24,29,34,21,26,24,24,29,24,34,36,36,80,90,46,23,20,25,29,27,26,26,30,26,27,30,24,23,27,24,29,27,25,25,21,30,33,27,31,34,23,23,26,30,32,36,34,31,34,33,29,32,33,27,28,35,29,30,38,29,18,21,25,19,19,20,19,20,23,23,21,24,21,24,24,23,21,21,26,24,19,24,17,28,19,57,89,31,21,25,18,24,21,23,21,19,22,22,25,24,22,23,24,24,22,25,24,24,19,24,23,18,26,25,27,22,33,63,104,98,67,37,21,23,20,21,23,24,21,20,26,25,27,61,92,83,62,48,64,87,63,56,63,74,95,83,95,89,110,120,117,137,142,147,143,133,130,118,124,137,148,162,149,141,163,142,168,191,116,96,101,46,46,74,97,135,154,173,187,185,175,208,248,168,52,113,163,163,160,166,155,193,213,162,110,66,120,153,156,158,91,146,242,243,247,247,252,252,245,228,213,214,225,220,201,185,179,160,144,97,15,2,10,10,14,12,14,14,14,15,14,15,88,94,101,107,107,111,57,72,135,162,177,170,169,177,99,36,63,100,163,212,219,236,245,245,226,190,188,186,193,186,184,177,166,162,151,145,131,127,111,29,13,30,63,103,91,76,59,49,39,35,39,46,53,63,73,79,76,66,49,20,17,39,72,98,96,101,98,103,110,101,99,84,74,68,54,40,22,13,34,67,125,146,125,119,109,105,88,80,90,110,150,106,16,24,89,132,131,120,110,100,110,138,132,102,59,15,14,29,46,47,33,34,27,24,15,46,138,153,170,212,191,228,245,245,102,96,208,232,218,130,14,37,98,109,85,44,142,230,212,190,131,19,12,25,26,57,121,190,212,197,193,184,179,182,171,185,181,183,122,34,98,176,181,170,164,165,163,170,166,166,166,163,167,157,164,161,163,162,168,172,166,165,165,170,166,168,165,167,166,165,170,163,162,160,178,188,184,201,202,198,151,83,39,7,6,10,12,16,42,94,130,152,178,188,198,208,211,212,202,191,179,176,173,163,163,162,167,168,167,162,165,172,171,171,173,170,166,166,157,155,151,143,138,143,155,155,159,163,167,165,164,162,162,168,171,170,171,165,155,155,157,149,141,139,128,118,129,135,139,151,149,154,153,163,166,133,132,140,139,130,125,128,130,127,126,124,117,123,110,109,107,95,86,75,69,66,63,53,46,39,37,46,55,61,83,93,99,121,125,132,129,121,107,91,94,86,83,77,80,77,81,81,77,80,80,89,88,79,86,80,73,74,61,62,66,61,76,72,66,75,72,71,84,95,109,103,72,39,23,27,24,26,26,30,44,50,59,59,55,59,57,57,56,55,46,50,53,53,51,48,53,43,42,47,44,50,47,45,45,43,45,42,46,45,42,45,46,46,42,43,40,46,43,43,41,37,42,44,44,42,44,43,43,38,42,40,33,39,38,38,46,37,39,39,34,42,35,40,40,36,37,36,41,38,34,37,35,36,37,33,36,30,33,34,33,36,37,32,28,28,23,25,26,22,27,27,30,31,48,96,107,81,44,22,23,25,23,27,22,27,30,26,24,23,28,27,25,30,30,24,25,26,26,31,36,28,21,23,23,27,22,25,29,26,28,23,25,30,27,33,24,30,33,24,27,29,30,28,36,36,54,92,67,34,21,21,30,22,26,34,32,27,26,26,27,28,24,29,32,29,28,24,23,28,34,33,29,29,27,22,29,36,33,30,33,29,31,30,34,29,33,33,26,33,31,29,36,27,16,23,23,19,22,18,21,21,19,21,20,29,23,22,20,24,23,19,24,24,25,21,26,23,23,77,77,27,23,22,17,22,21,24,23,20,21,21,23,22,24,24,22,28,22,24,27,22,26,26,22,24,23,21,25,21,25,32,60,104,102,68,40,24,17,22,23,21,27,19,23,29,66,101,77,59,50,49,53,60,48,35,48,50,49,46,48,39,41,51,45,43,49,53,52,41,78,146,168,194,214,222,224,221,238,197,198,203,132,188,191,105,78,55,81,93,118,177,208,216,200,225,247,169,60,116,147,153,159,168,164,202,226,170,112,86,148,173,167,170,96,148,244,244,247,247,252,252,245,237,202,179,182,176,159,145,144,139,144,100,16,2,10,10,14,12,15,13,14,15,15,15,170,178,183,184,190,174,98,110,167,197,210,204,198,195,103,42,55,93,162,193,206,221,236,239,185,141,135,121,115,105,93,84,78,73,66,58,49,42,24,9,29,48,78,116,112,113,119,122,123,128,137,140,146,149,155,156,164,169,167,108,29,51,124,194,215,203,198,180,172,155,134,113,99,86,73,55,28,10,30,83,117,131,130,139,162,184,205,108,107,147,195,173,30,27,111,165,165,150,127,104,107,111,82,27,7,11,33,63,81,76,90,115,130,151,89,88,172,158,139,166,144,160,228,168,19,37,88,75,35,10,8,33,78,83,61,50,137,221,233,234,175,31,9,104,131,52,31,90,155,196,207,202,198,195,200,196,190,133,41,70,156,188,178,168,168,162,169,173,168,170,164,166,171,168,172,167,166,168,166,166,161,160,163,167,166,169,170,171,176,175,184,184,185,200,208,210,177,116,79,57,16,6,11,14,39,88,137,163,188,198,203,216,212,208,201,190,186,181,171,160,158,159,171,173,167,166,164,168,166,165,166,168,170,168,163,160,163,168,173,177,180,179,174,176,175,174,170,163,167,164,165,169,168,169,167,169,167,162,162,160,159,150,161,160,153,145,152,155,139,149,149,147,156,168,170,135,109,123,134,137,138,125,119,120,117,108,103,112,118,123,125,120,117,103,98,107,99,92,96,95,107,109,114,130,124,134,126,121,120,105,109,102,95,93,87,76,68,71,71,76,77,76,77,85,84,81,79,69,73,66,63,68,61,63,62,65,67,78,70,73,73,79,102,91,71,47,25,27,23,24,29,34,47,53,53,60,63,59,53,52,55,55,51,48,50,53,53,55,47,48,46,45,47,44,50,45,46,43,37,47,46,45,47,46,45,48,44,39,45,43,40,44,47,40,44,44,46,46,36,45,38,35,41,36,42,41,38,43,39,41,36,38,34,37,39,35,36,41,36,36,43,38,33,37,36,38,33,33,34,33,38,35,35,35,37,35,33,30,35,30,24,24,24,24,21,26,24,24,24,31,83,106,75,50,24,22,19,21,30,25,26,27,24,27,29,22,27,28,24,27,27,24,28,34,27,27,24,28,22,27,28,21,28,23,25,27,27,34,29,22,35,30,24,27,27,26,29,27,29,31,37,81,84,45,17,18,27,23,27,32,33,26,28,26,25,31,30,23,31,45,24,21,20,27,34,31,30,28,24,26,26,33,36,32,33,29,30,32,31,31,29,32,32,29,33,41,34,22,22,24,18,22,24,21,21,24,21,20,25,21,21,21,22,19,22,24,26,23,23,24,22,16,34,89,56,19,27,16,19,21,22,21,25,24,21,21,22,24,21,24,24,23,24,18,25,25,24,24,20,21,23,23,23,24,21,21,33,65,115,113,71,46,18,24,26,19,25,25,24,66,108,82,55,50,53,54,53,59,42,36,46,48,53,51,54,47,51,63,48,38,41,29,22,87,185,227,244,251,253,253,252,252,253,244,244,199,106,168,181,118,84,65,56,33,61,131,172,191,172,203,247,144,53,98,104,114,128,150,150,193,220,152,93,90,158,172,169,168,100,160,244,244,247,247,252,252,247,245,217,178,176,171,154,141,141,138,154,109,14,2,10,10,14,12,14,14,14,15,14,14,198,197,196,193,194,174,97,107,156,183,194,178,174,170,83,27,45,71,124,148,148,154,170,156,89,74,72,61,63,56,57,61,67,76,80,92,98,108,79,16,37,87,143,193,197,205,206,208,209,211,212,214,200,189,192,184,190,189,202,126,22,37,103,152,164,150,131,125,117,110,105,113,116,129,141,155,114,31,59,128,196,237,246,247,227,212,156,109,135,183,218,155,35,22,78,115,111,86,72,65,77,91,75,64,26,9,69,143,193,203,208,227,233,245,162,121,202,202,174,156,74,45,48,12,8,19,21,26,29,39,31,34,46,59,54,33,103,158,166,224,211,53,15,125,203,174,66,16,53,107,155,184,189,186,174,154,80,24,66,144,192,184,171,170,170,170,169,168,170,171,167,164,168,167,171,165,171,169,163,171,170,168,167,166,171,178,182,188,199,212,215,212,202,166,134,110,39,1,11,23,65,105,143,171,192,214,221,226,216,207,194,184,184,178,174,174,174,174,166,160,155,159,162,166,174,169,169,171,167,171,171,175,174,166,166,160,165,171,169,173,177,177,174,170,169,166,165,167,170,173,177,180,172,154,144,137,135,137,137,150,168,179,184,185,181,176,181,181,174,171,166,170,170,168,169,133,104,108,131,149,138,121,118,116,118,114,105,110,109,124,125,130,133,116,127,129,130,126,123,124,126,121,122,118,113,113,108,107,100,102,101,92,87,86,80,74,69,64,78,72,78,81,82,85,71,69,65,60,67,63,66,66,66,68,73,64,78,86,81,82,87,82,59,39,28,26,25,21,32,44,44,55,59,61,59,56,64,54,54,52,52,59,53,49,47,53,47,50,50,45,45,44,50,47,42,47,47,49,46,43,45,46,43,49,42,40,43,44,43,41,40,42,46,49,45,40,38,40,41,38,38,39,39,36,42,39,43,38,41,39,39,38,34,39,38,39,33,39,36,35,34,34,37,33,36,34,32,34,39,33,32,36,34,33,32,34,30,35,36,28,21,25,25,23,25,21,26,28,23,39,41,78,114,90,61,31,25,29,25,24,28,23,26,31,25,27,23,25,27,29,29,29,30,23,27,21,25,24,27,34,26,28,23,21,29,29,29,27,23,23,24,29,21,25,29,32,31,31,32,28,30,63,88,61,32,21,21,31,31,28,33,27,30,31,27,32,28,21,29,29,21,23,26,27,29,31,34,24,29,24,21,36,34,31,33,35,33,28,29,29,33,35,34,30,29,35,37,27,21,20,19,22,17,21,17,22,21,22,23,19,24,21,23,22,21,21,23,21,22,23,23,16,54,87,39,24,25,19,17,22,27,18,16,24,27,22,24,21,22,20,23,25,20,25,24,25,24,23,24,23,23,22,24,22,24,21,21,34,60,111,110,72,44,24,22,21,25,23,69,105,77,55,44,50,53,49,53,60,52,38,46,55,52,55,57,47,56,60,49,37,42,37,103,205,227,237,230,249,249,249,250,250,253,253,249,215,91,101,109,97,115,94,34,6,12,20,51,78,66,125,200,89,46,85,64,86,96,106,107,157,211,136,68,94,151,169,164,164,105,160,245,245,247,247,252,252,249,249,239,195,182,181,173,160,152,148,163,110,12,2,10,12,14,13,15,13,14,15,15,14,181,180,178,168,165,121,81,85,125,136,136,114,105,93,30,29,39,55,90,90,86,80,87,78,70,86,102,117,129,143,153,162,171,178,183,191,194,207,152,45,42,85,154,209,216,215,208,206,206,200,192,184,162,149,141,123,115,104,97,44,13,41,65,97,103,97,107,112,131,146,155,170,185,203,206,218,142,50,55,139,203,251,236,220,139,68,63,46,103,134,131,82,5,19,44,65,51,46,48,57,91,131,152,170,99,18,84,177,224,232,226,222,211,207,112,89,179,211,222,211,114,65,81,23,7,76,139,162,172,137,40,49,88,74,60,42,117,163,142,165,170,42,15,121,190,197,173,98,22,12,38,64,74,73,55,15,27,86,145,194,191,171,167,164,162,160,159,165,162,166,167,164,164,165,165,164,171,172,171,173,177,181,186,198,205,211,218,217,211,191,159,117,61,83,8,25,63,100,141,173,190,208,217,217,217,205,195,186,181,177,172,174,170,170,175,172,172,171,168,168,166,160,166,167,167,171,166,169,171,171,171,171,170,166,162,165,168,166,161,154,150,155,156,158,160,162,157,152,164,169,171,178,173,165,154,151,148,146,148,160,170,175,184,181,177,173,180,184,182,181,178,175,165,154,159,141,116,105,109,121,118,108,109,112,114,113,114,112,116,124,125,123,122,122,124,125,120,118,120,116,114,110,108,109,100,106,105,107,103,97,104,87,86,80,75,74,65,71,73,79,84,81,74,71,65,67,65,59,67,67,71,68,66,73,76,78,78,85,92,80,60,39,23,22,24,24,29,40,47,57,62,57,57,56,55,57,57,53,50,51,54,54,50,49,49,50,47,49,49,47,54,50,48,43,44,46,47,45,41,46,46,52,43,44,44,44,43,41,42,40,45,48,49,41,37,39,40,42,40,41,38,36,43,41,43,40,35,41,37,36,40,33,36,38,40,39,35,34,32,35,33,39,32,28,39,35,33,35,37,33,33,35,33,28,33,31,31,32,33,34,24,24,25,24,26,26,26,24,29,34,32,47,82,134,111,68,41,21,21,20,22,24,26,22,27,25,23,27,27,31,24,31,24,23,27,26,25,31,37,29,22,27,28,22,24,27,27,27,23,23,25,28,33,29,35,39,28,28,30,28,24,45,87,84,39,20,28,34,29,29,29,26,29,26,31,27,19,20,24,19,25,36,27,24,30,32,24,33,25,24,33,28,33,33,32,34,29,32,32,26,36,36,31,30,35,33,37,29,22,20,19,24,24,17,24,21,22,21,22,24,23,24,28,19,24,24,21,27,21,20,21,23,71,78,28,25,20,16,24,18,22,29,19,24,24,19,24,22,23,24,20,24,23,22,26,22,21,22,22,22,22,24,25,25,21,25,27,22,32,61,108,112,68,40,24,19,23,66,107,78,49,48,50,51,46,46,59,61,49,40,41,48,53,55,52,50,53,62,46,35,43,47,139,189,195,216,206,208,200,194,210,234,250,250,249,214,123,107,88,100,149,156,86,32,11,12,12,17,11,54,147,70,42,77,75,93,77,63,63,141,203,121,56,74,125,143,142,147,96,160,247,247,248,248,253,253,252,252,247,210,189,189,184,177,170,160,173,111,11,3,10,12,14,13,15,13,15,15,15,15,124,114,96,90,89,61,26,59,78,79,77,56,53,36,10,36,61,86,122,139,141,144,151,156,159,182,195,200,212,211,216,219,216,215,212,213,211,215,164,47,32,72,125,170,166,155,135,124,118,105,95,88,79,71,70,61,60,59,57,20,16,60,108,158,169,172,182,189,198,202,204,213,208,213,208,208,142,34,39,97,160,196,170,79,44,57,51,59,66,64,57,25,8,35,77,98,103,102,103,119,155,206,215,232,132,27,82,145,187,170,142,125,95,68,12,49,139,164,200,236,181,164,190,89,42,132,205,225,205,135,49,68,107,84,47,52,150,225,199,177,122,10,21,121,187,191,186,185,157,105,44,36,44,50,71,102,135,170,199,193,179,171,166,160,153,152,150,150,154,159,162,163,167,166,170,171,180,184,186,198,197,201,202,191,178,156,131,101,64,19,5,11,24,47,98,153,178,201,214,210,205,196,187,183,176,172,167,165,162,165,167,164,169,167,169,168,163,163,157,162,165,163,170,171,171,166,166,172,170,173,170,163,152,146,158,162,169,173,163,155,154,157,160,160,163,165,157,148,145,149,153,164,168,169,168,171,177,175,179,176,165,155,155,162,163,164,166,173,174,172,171,174,175,173,177,163,134,105,83,86,96,96,96,103,106,99,105,116,118,127,124,120,122,118,122,122,120,118,118,112,114,109,111,114,106,106,105,103,99,99,97,88,83,84,81,77,76,67,82,81,78,72,60,66,61,69,66,65,66,69,69,77,84,73,81,87,92,73,56,38,27,19,21,29,34,38,50,55,59,61,56,60,59,59,54,53,58,44,51,54,49,55,53,49,45,48,49,48,52,53,49,46,46,44,43,43,48,47,45,47,43,46,44,43,47,43,43,40,43,46,46,41,41,44,43,39,39,35,42,42,44,44,35,43,37,36,37,38,39,34,39,41,34,41,37,32,38,33,34,35,31,36,32,29,39,33,41,37,25,34,31,32,31,31,34,34,33,35,33,31,29,25,22,25,24,22,29,26,27,27,25,37,26,42,99,107,80,51,26,19,29,28,26,20,27,32,21,25,27,29,27,23,27,24,27,28,28,33,28,24,22,26,29,25,28,28,27,27,23,24,25,27,32,33,48,39,20,28,22,24,26,30,70,92,57,28,28,24,30,27,29,29,23,31,27,21,22,24,22,25,37,34,26,29,27,30,31,28,26,22,31,31,33,31,33,36,34,36,27,28,37,30,28,29,34,35,33,31,16,20,19,22,20,20,23,19,23,18,21,21,20,21,19,26,24,27,22,24,24,21,19,32,92,63,16,27,23,16,21,24,19,24,23,25,23,24,26,18,24,24,29,26,20,22,22,26,23,19,23,25,27,24,27,23,23,26,26,27,24,29,59,108,107,71,47,21,75,111,76,47,33,50,48,45,50,49,53,61,47,33,45,44,50,55,55,50,54,63,53,40,39,41,82,122,163,215,212,208,200,185,186,202,209,211,219,171,144,136,104,111,191,235,207,197,188,167,125,80,59,124,172,51,33,92,105,122,84,53,62,143,203,121,50,52,68,84,87,100,73,149,247,247,249,249,252,252,250,253,248,224,195,190,193,182,179,176,176,110,10,1,10,12,14,12,15,13,15,15,15,15,60,63,53,52,42,19,22,53,94,114,128,128,132,100,25,43,81,115,187,200,208,204,212,210,208,210,209,210,206,204,199,191,188,184,174,163,153,151,87,16,26,47,90,108,89,76,66,60,64,64,66,82,89,105,117,128,145,155,150,54,16,73,138,201,208,206,210,205,202,193,189,181,160,146,129,113,50,4,32,74,110,115,100,75,71,108,122,107,136,146,144,85,2,55,126,169,158,143,132,130,165,200,203,198,93,2,50,103,115,88,67,61,67,75,29,71,154,160,152,191,170,171,201,89,33,90,150,137,95,55,22,35,35,39,27,37,138,220,231,226,159,21,21,121,183,190,187,191,196,199,182,169,165,174,184,190,202,198,182,176,168,167,168,157,156,160,159,160,160,163,170,174,178,186,192,195,198,191,177,157,136,114,85,56,24,5,11,10,14,11,30,111,166,190,205,211,207,196,188,179,172,172,171,164,163,165,169,162,159,162,162,165,163,161,162,159,160,158,156,159,159,161,167,171,171,171,167,170,170,165,165,162,161,160,162,169,170,167,163,164,168,170,168,168,166,168,171,165,165,165,166,171,169,170,168,169,172,174,174,174,165,160,155,159,169,173,180,175,162,151,159,173,179,176,180,174,145,104,80,81,87,94,93,88,94,87,96,111,118,126,123,125,119,115,122,122,121,119,115,111,119,112,110,111,108,107,101,102,96,103,104,93,96,88,93,77,79,83,77,76,69,64,66,63,61,72,71,65,75,69,73,80,87,92,71,78,49,38,24,22,26,27,34,39,52,57,55,60,60,61,60,51,54,55,48,51,57,57,52,50,49,49,50,51,49,47,51,55,50,47,43,45,45,47,42,42,46,47,43,45,46,43,42,42,44,38,44,45,42,41,38,36,43,41,39,40,41,41,49,39,36,45,37,36,39,38,37,39,35,37,38,40,39,31,36,36,34,36,31,38,33,29,39,36,36,30,34,33,32,33,34,36,33,33,34,35,35,38,29,35,33,27,28,21,26,22,26,27,23,24,24,26,27,30,36,81,110,84,58,37,21,21,24,20,30,25,25,29,26,31,29,23,24,28,27,33,31,23,25,28,24,29,27,31,28,19,27,28,25,31,27,29,30,28,33,26,24,23,25,32,25,26,49,88,77,37,19,26,31,25,24,27,30,27,24,24,23,22,25,31,31,32,28,32,24,27,34,27,27,26,29,29,30,36,33,33,32,28,31,31,34,36,31,27,27,31,35,33,19,19,23,19,23,22,21,24,21,20,21,20,17,22,24,23,28,24,21,28,22,20,17,59,92,40,19,27,16,23,26,22,22,21,24,26,21,22,24,21,18,26,26,21,24,24,25,21,23,22,21,26,17,23,26,21,27,25,23,28,25,23,31,57,97,108,79,77,118,67,39,37,42,49,46,44,49,48,50,57,42,35,43,48,51,53,54,51,52,61,50,34,37,37,57,61,100,156,172,201,212,212,212,216,210,196,182,133,121,115,97,118,199,246,251,251,253,253,248,247,230,246,223,88,83,123,124,141,112,91,110,188,232,157,83,52,50,51,42,63,60,149,247,247,249,249,251,251,216,237,248,227,205,191,193,180,179,179,179,111,10,1,10,12,14,12,14,13,14,15,15,14,124,135,133,139,128,60,47,101,146,187,200,188,197,146,46,42,78,134,183,201,203,194,192,185,177,171,161,149,145,136,121,111,103,97,90,81,63,46,17,12,39,57,90,110,104,114,121,136,147,157,168,178,187,193,201,204,209,215,195,78,19,67,133,186,189,172,163,147,131,117,102,91,68,61,49,35,17,15,50,100,152,167,168,127,116,142,147,147,187,226,236,134,23,59,135,164,152,123,103,89,104,121,101,84,22,10,58,99,127,117,137,157,176,179,103,128,206,203,169,143,100,112,122,46,23,44,59,69,48,32,27,21,29,30,31,28,78,150,169,227,193,33,17,118,184,184,174,175,182,188,196,203,201,199,193,190,183,177,169,163,165,163,162,164,164,170,172,177,185,190,198,198,191,181,169,146,127,97,64,42,17,23,29,36,47,46,41,31,39,82,146,191,214,199,194,189,176,178,169,167,171,173,174,176,172,174,173,169,168,170,169,167,168,165,167,165,163,166,166,169,170,169,170,168,167,168,167,166,165,163,165,169,169,168,170,169,167,168,167,170,171,167,168,169,165,172,173,177,179,177,175,171,165,165,159,159,158,155,164,167,169,170,172,174,174,179,174,168,159,157,162,165,165,165,169,174,148,110,92,81,84,95,96,81,77,69,79,99,115,126,120,117,119,116,115,118,114,116,116,110,109,106,108,105,101,101,101,102,103,111,111,100,89,79,67,73,80,76,81,73,74,79,73,74,71,72,67,76,79,78,79,92,93,66,52,34,22,22,29,33,34,43,52,56,60,60,59,57,56,57,54,58,59,54,50,53,55,55,54,47,53,49,45,51,54,52,45,48,49,49,48,45,49,46,47,44,48,46,45,46,42,42,40,43,47,43,43,41,39,39,43,43,36,43,43,41,42,41,40,37,34,40,36,41,38,35,45,34,43,39,37,38,35,41,33,38,39,31,36,33,33,39,33,33,33,33,35,33,36,31,28,33,34,35,36,38,29,33,33,29,35,29,27,22,25,22,30,23,20,27,24,28,29,29,27,34,69,113,104,73,48,24,22,25,28,22,23,31,24,28,23,28,28,27,29,21,27,29,29,24,27,32,29,26,28,21,20,24,26,33,30,26,31,32,23,24,30,29,28,30,28,29,33,76,92,47,27,25,25,27,27,26,22,27,25,25,27,23,30,24,28,32,26,34,31,34,29,26,23,25,34,33,31,33,37,34,30,33,34,31,33,35,28,29,28,29,30,25,24,21,22,24,23,22,25,23,22,22,24,18,20,24,19,22,22,23,22,21,23,20,28,81,80,27,22,23,15,18,23,23,25,23,19,24,22,20,23,22,22,22,24,21,26,22,19,24,24,24,25,24,18,27,27,21,29,25,28,29,19,26,32,31,53,99,133,130,83,33,39,42,38,43,46,54,55,60,60,52,49,51,48,48,53,49,49,51,52,54,42,35,38,43,46,47,39,58,79,114,149,162,183,202,209,213,185,125,100,88,83,89,141,193,219,244,246,250,253,253,253,253,244,181,198,188,136,134,126,134,181,242,246,226,171,140,130,127,112,120,110,179,250,250,250,250,246,229,168,208,246,235,216,188,196,180,175,183,172,108,11,0,9,10,13,12,14,13,15,15,15,14,190,199,186,190,172,82,64,108,161,194,198,189,185,136,41,33,59,105,144,157,146,127,121,109,96,87,81,72,64,60,60,57,55,61,66,70,78,84,33,14,55,97,159,186,187,195,201,203,210,208,207,210,209,210,206,201,193,191,170,56,12,43,85,131,117,101,84,75,66,56,62,70,79,94,113,132,63,18,89,162,235,253,249,191,137,147,141,137,177,215,227,130,16,33,88,113,94,71,57,50,71,81,85,87,26,17,101,167,200,199,207,210,213,196,108,129,205,232,207,178,87,45,61,18,25,29,33,34,30,36,22,33,36,38,48,34,78,139,132,169,158,23,19,109,173,181,167,165,163,169,171,172,171,170,166,165,166,164,166,169,168,171,174,173,179,191,193,192,190,176,160,135,103,77,49,27,23,46,70,92,115,136,156,169,183,190,190,178,122,158,158,153,148,146,148,152,155,155,155,157,153,156,160,160,163,163,169,169,170,168,170,171,165,163,165,163,161,160,163,168,167,165,165,164,160,163,163,162,165,165,167,166,166,170,170,169,171,172,170,174,173,168,162,162,164,164,165,159,159,161,158,158,155,148,153,160,165,163,165,171,169,171,171,174,173,169,167,162,168,168,165,165,159,162,164,168,165,132,104,94,74,92,102,82,77,55,61,73,97,114,115,119,112,116,117,114,113,114,107,107,104,102,107,103,106,114,110,108,105,103,97,77,66,55,73,72,69,83,77,77,77,79,75,74,77,78,83,76,87,89,61,58,56,29,37,24,25,37,38,51,55,53,62,60,60,58,58,56,54,57,54,55,55,57,53,51,55,52,51,50,47,52,53,51,50,48,50,48,46,47,48,47,50,49,47,42,45,46,42,49,44,44,45,43,48,43,44,46,40,39,34,39,40,37,45,42,36,39,40,38,36,39,39,39,39,37,37,37,39,32,37,38,32,36,32,33,34,29,35,36,34,34,33,31,33,35,35,32,34,34,35,39,31,29,33,30,29,30,29,33,27,29,29,25,23,19,24,26,22,21,29,26,31,27,47,52,24,44,101,115,84,55,33,26,23,20,27,30,23,21,29,25,29,28,28,29,24,27,27,26,23,27,29,23,23,26,27,28,29,33,30,27,29,27,29,27,24,31,38,33,22,31,33,50,89,67,32,21,21,26,24,27,25,24,27,24,26,24,29,35,29,28,27,34,36,33,33,29,26,24,31,32,36,32,30,38,35,29,29,33,29,35,28,29,34,28,27,25,21,19,21,21,19,22,20,17,22,18,21,21,21,20,22,23,23,22,23,23,27,19,40,96,57,21,24,21,18,20,24,24,22,24,20,22,24,24,21,19,27,26,22,22,22,21,23,21,26,27,21,26,22,25,20,23,34,16,24,23,26,24,24,26,50,118,124,108,79,29,54,39,36,34,44,49,54,64,57,62,64,61,50,53,54,55,53,48,53,51,41,42,42,40,43,46,44,48,35,32,86,62,89,127,147,165,158,122,115,101,83,73,118,171,188,187,164,162,174,190,201,211,203,193,220,185,102,63,57,94,182,242,251,251,248,243,242,240,230,229,207,241,252,252,252,252,246,235,186,229,252,250,230,195,201,184,175,185,172,105,12,0,10,10,13,12,14,13,14,15,15,14,186,188,179,181,146,63,62,94,136,173,163,152,142,84,31,31,46,78,98,95,77,65,63,59,61,68,73,81,98,109,121,136,145,151,162,172,175,182,93,25,63,116,182,212,212,213,205,205,195,188,178,164,156,146,132,117,96,90,63,14,18,32,71,98,89,92,103,116,130,142,156,174,182,200,206,214,127,39,94,168,250,251,248,208,137,139,130,113,113,122,119,45,13,29,47,64,52,53,69,88,139,177,193,190,68,31,112,182,218,196,186,167,147,112,49,90,157,183,213,222,130,47,27,13,26,26,19,23,23,22,34,43,65,75,69,99,164,213,197,175,108,7,25,119,178,176,162,165,165,164,164,162,164,166,167,167,167,176,177,180,190,191,198,196,177,161,139,116,90,55,36,25,33,56,83,111,138,160,172,185,193,199,195,192,193,188,189,183,184,176,159,148,144,138,144,143,139,143,143,143,145,141,142,149,145,145,151,153,152,154,155,158,151,150,155,154,158,159,159,160,158,161,165,159,158,159,160,160,163,165,160,162,167,169,169,170,171,173,168,170,168,164,166,169,166,167,162,160,161,163,166,167,163,167,171,178,177,172,174,171,169,164,162,165,165,165,168,165,162,169,174,174,174,169,171,180,183,168,122,88,78,87,87,83,90,77,65,59,78,108,111,113,117,115,116,116,116,114,112,108,107,113,114,111,113,117,107,97,82,67,63,65,69,73,78,78,81,81,85,75,73,81,70,76,86,83,94,97,69,54,35,27,26,27,36,36,48,53,59,61,60,61,60,62,64,61,53,53,55,56,52,55,55,49,49,52,52,53,55,49,51,53,50,46,48,53,44,47,49,53,51,46,47,46,46,41,38,46,46,47,40,45,47,41,44,42,40,39,36,41,39,41,44,42,42,39,38,40,33,39,40,34,37,39,39,37,38,37,33,31,32,36,35,36,32,37,34,33,39,32,34,34,33,35,32,32,35,36,34,35,33,33,29,30,31,27,33,33,29,32,30,30,34,26,25,25,28,27,22,27,23,24,31,27,30,28,21,27,28,65,110,100,72,45,24,24,27,25,24,23,25,26,27,25,24,29,27,19,23,31,32,29,26,25,27,31,25,32,29,29,26,29,29,25,33,24,25,33,29,27,26,26,28,33,76,87,52,26,16,25,24,24,23,29,23,26,31,25,37,33,27,24,30,39,32,31,35,35,24,25,31,33,34,26,38,33,31,33,28,33,31,33,29,33,29,29,31,29,17,21,22,19,19,21,21,22,23,20,21,24,23,25,19,19,23,17,24,21,23,18,61,94,36,24,30,17,15,19,26,21,22,28,23,19,25,23,20,21,24,21,23,21,20,27,22,27,22,23,26,21,22,21,28,33,34,25,25,27,22,27,25,52,110,98,61,74,78,78,69,42,39,38,53,48,45,56,52,57,57,54,55,50,54,55,56,54,51,55,52,50,49,44,46,49,50,52,50,46,45,33,28,35,53,89,110,124,141,126,101,103,141,180,199,188,164,150,139,146,150,151,148,150,161,130,52,15,9,27,118,193,240,250,252,252,252,252,252,252,253,253,252,252,252,252,248,246,232,251,250,250,242,199,210,192,180,190,167,102,13,1,10,10,13,11,13,13,14,15,15,14,152,149,136,113,83,46,53,73,99,125,98,81,63,27,18,41,62,92,106,111,116,122,132,143,153,165,172,179,190,197,208,208,211,212,211,214,213,203,102,29,53,99,162,188,184,169,157,143,128,113,99,92,83,73,66,59,49,61,45,10,29,73,133,168,167,178,187,204,208,213,219,219,222,221,219,213,108,19,55,114,183,210,191,137,118,132,124,89,27,5,10,18,32,38,49,51,41,41,71,121,174,196,200,185,71,28,89,143,165,136,113,84,57,33,24,91,135,142,159,213,132,10,12,15,28,33,30,24,21,28,29,60,118,162,165,152,175,212,215,211,127,4,34,125,176,175,166,168,166,166,164,165,168,167,177,186,192,198,192,182,167,147,130,105,74,51,27,28,48,66,97,125,147,168,184,198,200,199,196,188,181,174,167,161,160,159,162,165,169,173,166,159,156,156,155,153,155,154,155,154,154,157,153,153,154,151,152,149,149,149,149,148,151,151,150,151,155,158,155,157,159,158,156,156,155,156,156,157,158,160,162,167,169,166,168,166,168,169,169,171,167,168,167,167,167,168,168,171,177,174,174,176,173,174,177,173,172,170,168,166,162,162,161,160,160,163,165,165,162,152,157,171,172,173,169,168,169,169,146,122,89,78,64,63,106,96,96,98,118,134,128,133,127,120,120,118,122,122,117,121,112,117,121,108,100,90,83,74,72,61,68,79,85,86,90,81,85,90,83,75,79,85,86,93,86,76,55,40,29,29,29,35,38,43,52,54,64,63,61,66,60,59,57,53,59,55,55,53,55,56,51,51,51,53,51,50,53,55,54,53,48,50,52,50,45,49,49,49,51,49,53,44,46,46,42,42,39,40,49,49,42,40,43,45,45,43,43,41,37,40,42,39,43,38,39,40,39,33,37,41,42,41,38,33,34,36,33,37,41,34,32,37,39,37,39,39,37,33,38,32,29,37,33,34,36,33,38,35,33,31,29,37,29,34,30,21,35,30,30,37,28,25,27,31,32,21,22,26,22,27,29,24,27,29,28,28,27,27,24,28,53,101,111,88,62,31,20,17,27,26,29,32,24,26,27,30,21,27,32,27,31,23,22,28,26,30,33,33,35,26,22,32,30,24,26,32,24,24,28,24,34,27,26,29,48,89,71,33,24,23,24,28,25,28,21,28,29,22,27,25,25,25,28,34,30,33,35,29,25,29,32,31,35,36,35,37,31,29,30,34,35,34,31,31,29,32,31,24,23,24,18,21,22,20,23,18,20,21,22,19,16,25,19,23,22,18,23,23,26,27,85,74,22,30,19,19,21,19,23,18,22,24,24,24,22,21,19,22,22,21,26,26,23,22,23,24,25,20,27,25,19,26,24,34,29,21,31,25,27,28,67,110,86,54,12,61,128,125,100,76,100,100,107,86,66,57,37,74,72,41,64,45,44,52,51,49,43,55,51,54,46,46,48,51,56,54,55,51,55,47,46,42,27,53,87,131,168,165,130,120,134,181,223,232,219,204,195,189,188,182,171,167,160,144,108,74,48,49,79,86,130,185,224,248,252,252,252,252,252,252,253,253,252,252,251,251,252,252,252,252,247,208,216,203,187,198,168,96,15,1,10,10,12,12,13,13,14,15,15,14,78,69,58,43,23,21,44,55,72,94,91,89,93,43,13,53,97,148,181,196,201,203,210,214,212,213,212,212,213,211,213,207,201,198,191,182,181,163,63,20,39,73,118,118,108,91,79,77,70,72,81,95,105,120,134,148,155,169,139,33,38,103,170,216,218,222,220,215,213,201,192,179,163,143,129,112,30,1,33,49,76,75,93,101,109,132,123,105,59,20,14,21,34,46,60,76,71,79,91,100,136,131,122,91,27,33,61,92,94,81,71,56,48,29,32,123,188,178,145,156,90,9,15,15,27,34,34,27,28,26,28,51,86,105,100,99,104,128,160,208,149,16,21,105,167,179,174,176,174,181,189,192,193,187,181,170,150,128,105,79,54,27,21,41,63,92,116,141,159,178,194,200,200,199,194,185,179,175,168,167,166,163,162,160,162,166,170,166,168,169,168,164,162,160,158,160,167,165,161,158,158,160,160,160,155,157,160,156,155,154,155,157,158,158,159,157,159,159,154,157,157,157,158,154,157,159,156,155,158,160,163,165,166,165,162,163,164,160,162,168,165,166,169,167,165,168,166,167,170,165,162,162,158,161,161,165,167,170,169,164,163,167,171,171,167,167,171,174,167,159,159,159,158,152,153,152,155,166,194,219,192,122,54,65,96,95,118,124,126,134,128,132,132,125,123,119,116,115,110,106,104,98,89,74,69,75,84,92,83,75,83,94,92,96,93,86,93,91,87,75,95,105,84,63,43,28,26,29,30,41,45,54,55,56,61,61,62,60,65,60,56,60,59,55,57,55,54,57,54,54,53,50,51,53,53,51,55,54,53,50,50,50,50,47,46,50,51,49,47,48,46,46,48,44,46,45,46,46,43,46,42,40,44,44,46,43,43,46,38,40,38,35,41,35,39,39,34,42,42,39,40,42,36,33,36,35,35,34,33,34,37,37,38,39,35,32,34,38,33,36,34,33,33,34,38,30,31,31,30,33,28,33,32,24,34,34,34,35,32,29,24,31,30,31,30,26,25,24,26,22,22,24,24,27,30,32,23,40,69,36,21,30,78,123,100,76,46,28,24,29,33,29,29,27,24,27,24,36,29,24,26,22,27,30,32,31,27,33,27,27,27,31,33,22,27,32,25,27,31,30,27,36,40,27,31,72,87,55,27,17,22,25,23,27,27,27,26,26,31,25,26,25,29,32,29,33,34,27,23,29,31,33,36,33,36,33,29,29,29,33,34,36,36,32,29,34,33,29,19,19,16,21,27,19,23,21,22,22,23,23,20,22,22,23,22,22,17,25,23,51,99,53,23,27,15,19,26,19,25,23,23,29,19,28,23,17,26,23,21,21,26,24,23,20,22,24,22,21,26,24,23,24,23,26,25,27,25,24,33,80,113,77,55,16,42,164,185,160,127,107,126,149,155,119,91,69,82,106,106,101,83,54,48,50,46,35,43,42,44,45,39,42,37,44,52,47,49,53,58,55,51,47,43,54,71,128,180,171,152,147,146,189,250,251,250,250,246,243,242,242,238,226,222,219,208,204,186,162,117,60,77,96,115,144,184,229,242,246,246,248,246,246,251,251,253,253,252,252,253,253,249,209,214,208,197,207,178,100,12,1,9,9,13,12,13,13,14,14,14,14,57,59,61,67,23,27,50,70,116,138,171,178,169,99,41,65,106,161,198,208,211,206,210,203,198,194,188,186,177,168,158,148,139,126,116,102,85,53,11,18,42,68,93,93,98,104,107,122,141,154,168,180,189,196,205,211,208,228,169,57,41,87,161,198,194,178,156,145,126,113,103,89,79,59,56,44,12,16,53,93,116,110,125,134,136,138,139,135,128,146,121,51,34,77,137,157,146,133,121,109,95,78,62,49,27,31,47,57,60,50,45,35,33,30,49,145,217,232,190,155,61,6,25,9,26,34,26,27,29,32,24,46,69,75,83,92,103,136,146,186,160,32,56,136,178,195,191,197,194,191,182,162,141,112,89,64,35,21,31,51,72,101,129,147,165,183,195,200,202,196,190,181,175,171,165,165,164,163,162,159,156,158,159,157,157,160,160,160,162,163,159,159,156,152,155,152,159,160,158,155,151,150,153,158,155,153,160,158,156,159,157,155,158,157,155,156,154,151,147,151,151,156,157,157,160,159,159,155,155,156,153,154,156,158,156,157,159,155,158,161,157,159,160,159,159,156,150,150,147,142,148,149,148,151,155,160,166,165,170,165,165,163,165,173,166,168,168,170,174,165,165,160,151,145,153,155,152,152,195,252,252,209,89,59,94,105,123,113,99,97,92,101,108,106,102,91,84,83,81,83,86,77,78,69,76,91,98,92,96,88,92,97,87,93,93,90,101,101,103,89,69,50,33,33,24,29,40,46,54,55,58,61,63,60,61,64,60,58,57,61,56,57,55,55,57,55,53,53,56,51,49,53,53,48,54,54,52,53,51,49,46,49,50,47,50,47,45,49,46,44,49,46,46,44,47,46,39,42,40,42,45,41,44,44,45,45,35,45,37,34,40,36,42,39,35,37,41,41,35,38,37,36,36,37,35,34,38,33,35,43,36,33,34,29,35,37,34,34,34,36,34,35,35,36,31,30,36,31,29,29,31,26,31,36,33,35,27,29,31,26,27,28,28,33,33,28,23,24,26,26,24,22,26,31,24,26,25,53,60,25,21,30,25,50,71,115,96,65,44,29,20,24,20,23,28,24,31,27,24,27,24,22,29,33,32,27,34,32,28,33,26,27,29,29,27,24,28,32,36,25,29,36,29,27,23,50,88,71,39,22,20,26,26,27,23,24,24,30,31,26,28,21,25,31,34,35,32,29,22,27,33,35,33,33,36,33,32,29,27,31,32,35,33,28,34,30,35,31,17,20,20,24,22,21,23,16,25,26,24,20,19,20,19,26,19,21,22,23,18,72,94,29,25,27,15,22,18,27,22,19,21,20,25,22,26,24,22,23,19,24,22,18,24,28,22,23,23,27,24,22,24,26,26,24,26,23,30,45,94,111,71,48,21,28,137,219,201,168,151,139,116,116,133,125,115,100,115,117,119,123,113,103,99,99,101,89,94,100,111,114,102,86,60,44,55,49,35,33,36,50,47,42,41,47,41,68,113,132,147,161,160,206,252,252,252,252,253,253,253,253,252,252,250,250,250,250,246,239,204,165,159,116,59,33,55,89,113,132,158,185,198,206,212,220,231,239,244,246,250,250,232,171,188,191,183,200,180,103,12,1,10,10,13,12,12,12,13,14,14,14,145,151,154,108,57,53,46,78,132,178,198,199,195,105,38,61,98,147,179,184,171,161,153,147,134,123,115,107,99,86,78,69,62,59,58,49,58,47,10,29,66,112,162,175,177,181,186,189,196,197,194,196,193,196,194,191,187,190,129,23,22,57,101,127,102,84,72,65,67,73,84,95,107,120,141,136,37,25,102,159,208,200,207,191,149,145,138,137,157,184,163,73,39,79,135,153,125,109,99,98,92,77,62,38,23,25,23,30,34,28,22,19,21,29,37,100,173,207,221,210,80,7,22,11,26,27,27,26,24,31,26,69,131,149,151,150,150,148,138,146,100,57,135,200,204,185,164,143,121,97,68,42,24,27,44,69,96,117,148,164,179,187,198,199,190,187,178,181,175,170,163,160,165,163,161,159,163,166,158,152,152,155,160,159,159,159,157,156,157,150,152,157,158,154,149,153,159,159,160,154,150,149,157,159,159,158,156,157,156,159,157,158,158,152,147,152,150,144,144,145,150,151,155,152,153,153,151,147,150,150,145,144,142,151,149,151,152,143,148,150,144,143,139,139,138,131,131,132,139,141,141,147,146,144,144,137,133,132,131,132,127,123,128,134,139,143,146,147,145,148,148,145,143,139,151,155,147,136,163,232,253,253,135,66,67,93,121,104,99,95,89,86,91,97,88,74,77,85,76,69,75,88,96,93,98,103,103,103,96,98,100,101,84,86,101,93,94,80,54,36,32,30,33,39,45,51,55,64,67,65,60,62,64,59,57,58,60,54,50,54,60,54,54,57,55,53,56,51,47,56,50,57,55,49,51,51,49,52,53,49,50,49,49,48,49,45,47,46,46,53,47,46,45,48,43,37,46,44,39,44,42,44,41,46,44,39,42,36,35,41,35,36,39,40,39,42,41,36,33,36,40,36,34,31,37,41,39,37,37,33,34,38,34,34,33,30,32,35,33,36,37,26,34,33,31,31,29,34,31,32,31,33,35,30,29,24,29,31,31,25,27,32,32,33,33,30,29,27,26,23,25,25,39,40,22,28,27,27,27,26,28,28,28,24,31,73,113,118,93,56,36,27,21,22,27,25,24,26,26,27,27,25,31,32,32,33,27,29,27,34,36,28,26,26,31,25,26,34,29,21,31,29,23,21,28,31,69,91,57,27,15,28,28,27,27,24,30,26,27,23,25,21,25,36,30,29,33,31,25,29,34,32,38,35,37,31,29,33,26,34,30,30,29,32,30,33,33,29,22,20,20,22,23,19,22,20,25,19,20,24,21,22,24,21,20,25,20,22,40,97,62,20,30,14,20,22,21,23,22,23,22,27,24,22,23,23,28,20,23,26,21,22,22,25,21,24,21,20,28,24,24,24,24,25,26,31,68,115,104,62,41,20,35,118,197,210,183,176,170,150,117,100,109,124,129,117,121,118,120,135,139,139,134,132,137,139,149,159,165,160,158,147,133,139,119,95,73,51,48,36,46,40,35,44,26,28,47,65,96,120,132,182,248,249,251,251,253,253,253,253,253,253,252,252,253,253,252,252,251,251,246,210,141,68,25,26,19,46,108,158,175,174,171,165,171,180,177,185,195,191,157,116,142,147,141,158,152,99,15,1,11,10,14,12,13,12,13,14,15,15,185,186,175,102,60,49,42,71,109,152,173,174,160,71,24,43,69,112,128,116,104,87,82,72,66,63,59,61,70,81,85,98,110,118,137,143,159,128,42,35,86,144,197,210,208,200,198,201,193,184,176,165,160,147,132,118,92,91,45,6,22,42,86,98,97,105,114,134,147,161,173,182,193,198,210,186,78,39,98,162,208,195,199,168,130,132,133,120,101,103,75,35,32,45,78,89,83,78,61,54,50,37,29,27,21,23,32,29,27,26,24,28,27,38,33,73,124,146,192,227,101,7,17,10,25,29,24,25,16,19,27,40,69,74,72,71,63,63,45,47,30,44,138,155,127,92,50,30,28,34,57,81,107,130,155,179,186,193,201,200,191,185,178,171,167,155,154,151,157,155,158,160,164,158,151,162,160,163,162,157,154,156,159,159,158,159,162,160,154,153,148,151,158,160,161,153,157,155,154,152,151,149,150,153,150,151,153,152,154,156,157,153,158,156,152,154,150,156,154,150,150,148,146,142,149,150,152,153,147,149,152,150,150,149,149,148,146,146,146,147,143,139,142,136,138,139,136,145,145,137,139,137,138,136,135,125,106,109,111,107,109,109,115,122,122,124,118,112,113,121,124,129,135,135,147,139,126,122,152,199,249,250,158,77,52,79,107,99,104,98,100,104,105,108,98,96,101,95,87,89,86,98,100,101,106,108,107,98,104,106,107,107,87,78,60,38,38,30,27,36,43,45,52,53,57,60,63,68,63,64,57,62,60,53,58,56,56,57,55,52,59,57,50,57,50,55,53,51,53,49,54,50,50,53,50,53,47,53,51,48,57,47,49,46,48,49,41,47,48,48,53,50,49,39,43,44,43,42,43,44,43,45,43,44,45,34,37,42,36,38,40,40,39,39,35,38,38,34,41,37,38,37,35,39,39,35,33,33,38,36,31,35,33,34,37,35,34,32,29,34,37,33,31,34,29,33,33,27,29,31,35,27,29,34,29,28,29,30,26,29,30,33,28,31,27,27,26,25,21,23,25,29,46,33,23,22,25,27,27,33,25,41,53,27,24,26,46,102,134,113,75,50,27,24,30,25,25,22,25,24,25,31,30,34,30,30,26,25,36,31,27,28,26,27,26,29,32,21,24,25,31,29,27,26,29,53,61,88,77,33,27,23,23,26,19,22,27,23,26,32,24,24,32,30,38,30,34,28,25,29,31,39,27,37,35,31,35,29,28,35,33,31,33,28,36,34,33,27,22,18,17,21,21,24,18,19,22,20,19,24,21,24,21,21,28,17,24,19,61,92,35,25,28,16,23,23,19,22,20,24,24,21,22,24,23,29,23,18,27,23,23,22,23,22,22,23,24,27,21,23,29,26,21,25,33,80,124,83,54,38,19,33,107,183,200,179,172,181,177,160,139,131,116,115,126,131,142,130,145,146,152,155,145,142,148,156,161,160,163,158,161,161,169,165,155,136,130,120,108,108,98,92,82,79,67,53,36,35,45,53,67,108,170,214,235,245,250,250,252,252,252,252,253,253,253,253,252,252,253,253,252,252,238,178,143,93,53,61,96,153,189,202,203,190,175,165,157,156,157,149,130,118,139,134,120,122,117,87,20,2,10,9,14,13,14,13,13,15,14,14,176,169,146,72,37,46,46,66,86,114,110,101,72,17,27,47,64,90,86,81,80,84,93,104,113,125,141,151,164,174,183,191,200,200,209,203,213,163,57,45,84,145,188,198,192,183,174,160,145,126,109,96,85,73,63,55,45,49,28,8,52,100,153,181,183,191,196,202,207,206,206,204,199,195,195,162,59,22,67,116,140,129,131,122,113,125,127,109,71,56,47,26,27,32,42,45,39,36,23,24,21,19,18,23,30,26,33,32,29,46,55,62,71,78,97,144,177,152,153,178,76,7,14,8,24,32,25,19,17,17,21,30,27,29,30,25,32,50,48,40,39,36,44,43,49,66,83,103,126,146,164,184,195,200,202,196,183,173,176,169,167,162,160,154,148,148,139,146,149,145,150,153,153,156,154,152,153,157,158,156,160,154,152,155,150,153,162,157,156,151,150,150,153,154,155,155,150,148,148,150,153,150,151,150,150,152,146,147,151,152,145,147,153,155,153,154,156,157,158,150,149,145,147,141,143,149,150,153,150,149,148,151,155,151,153,154,151,145,152,152,149,153,152,155,164,161,157,160,155,153,149,147,148,149,154,144,137,141,145,157,155,152,148,144,143,141,135,130,137,141,139,139,141,143,137,116,106,108,160,191,204,204,158,136,99,102,98,87,108,98,99,106,111,115,108,107,105,103,97,95,97,93,95,101,105,115,110,90,100,96,79,66,36,29,30,33,41,39,48,53,55,53,60,65,56,58,60,65,60,54,58,55,57,57,59,53,56,60,55,56,53,54,53,49,54,57,52,51,55,58,51,55,54,46,53,49,49,57,52,48,49,48,49,49,51,46,47,46,49,48,47,49,46,49,43,41,44,37,42,44,43,42,39,38,42,41,36,42,37,42,39,36,36,38,40,39,39,36,38,39,36,42,42,36,37,34,35,30,32,36,36,32,33,36,36,34,31,38,33,30,31,36,31,26,33,35,34,33,29,30,34,35,31,31,31,26,31,29,29,33,31,26,29,31,25,28,32,29,21,23,27,25,24,25,24,26,22,29,32,26,25,48,46,21,23,35,30,29,54,103,135,118,79,48,29,20,17,22,21,24,33,31,32,28,29,29,27,36,35,27,24,29,31,24,33,31,28,27,27,25,29,28,29,24,30,53,39,61,86,61,29,21,26,24,24,30,29,23,33,31,22,27,33,35,33,36,34,27,24,26,34,35,32,33,34,35,30,28,32,34,31,37,33,27,35,29,35,28,20,22,18,21,21,28,21,18,23,20,17,23,20,19,21,19,21,21,20,29,90,69,19,27,22,17,22,22,24,26,22,23,19,23,22,20,22,24,28,26,25,22,21,22,26,21,21,23,23,27,24,25,19,24,27,53,113,116,79,46,32,27,41,92,160,195,181,168,174,182,173,168,171,155,131,111,112,139,166,170,173,174,170,164,154,154,158,162,165,162,162,158,156,160,163,160,150,149,158,158,148,148,144,118,112,110,91,81,58,41,36,27,17,25,58,89,117,132,149,181,217,241,246,248,251,251,253,253,253,253,252,252,252,252,252,252,248,201,156,124,113,164,211,237,246,226,198,186,177,174,177,163,156,161,180,171,148,134,112,83,20,1,10,9,14,12,13,14,13,14,14,13,107,112,86,46,40,45,51,79,89,94,78,65,45,15,39,66,99,137,143,162,167,173,187,192,197,201,204,211,211,210,207,206,208,199,192,177,183,126,30,29,57,102,144,144,134,113,101,86,69,63,63,64,76,93,103,126,133,157,89,17,66,120,189,213,210,209,203,202,193,185,170,154,140,122,119,80,15,27,56,89,107,103,136,128,122,128,129,102,48,32,31,24,22,22,25,26,21,24,18,23,22,17,25,24,30,39,30,31,42,83,152,114,177,181,186,212,225,191,156,129,39,14,17,10,24,29,28,21,20,24,30,35,42,35,35,42,43,44,45,38,30,24,76,123,142,160,168,183,192,188,187,185,179,173,166,162,151,150,152,147,148,149,147,146,147,148,153,147,152,148,145,145,150,149,143,150,145,152,150,150,158,151,152,152,153,152,149,151,153,158,153,152,147,144,151,151,149,142,146,152,154,152,158,155,153,155,152,157,153,145,148,149,153,158,153,147,146,154,152,149,148,149,151,149,151,145,149,156,150,148,145,143,153,156,157,156,148,155,154,152,157,146,151,157,159,153,148,145,150,158,155,144,147,153,155,153,142,158,167,168,168,160,155,155,163,160,158,138,159,160,158,151,146,150,145,122,98,84,118,171,192,164,129,141,128,127,109,94,94,75,73,84,101,105,102,115,106,104,102,94,103,91,98,108,112,87,101,73,52,41,34,35,32,40,45,45,53,51,55,59,63,63,63,57,59,61,57,60,52,53,56,57,59,55,57,59,59,59,54,55,52,49,54,50,56,55,54,54,49,53,51,53,52,54,53,51,55,52,49,51,48,44,51,49,45,51,49,47,46,49,47,42,47,45,47,40,41,47,40,40,42,39,39,41,38,39,41,42,42,39,40,36,37,40,32,38,39,39,42,38,43,34,34,36,32,35,35,36,34,33,37,30,32,33,39,31,29,31,31,35,34,35,32,32,31,33,29,29,36,28,28,30,34,31,25,31,33,29,26,26,30,28,25,28,26,26,27,29,29,27,24,22,26,25,23,27,25,25,27,27,24,24,24,29,34,31,23,23,27,33,72,125,134,105,74,47,29,19,29,29,27,28,31,34,27,28,34,33,28,28,31,23,28,28,26,33,26,28,29,27,32,30,28,24,24,30,21,37,81,84,49,19,21,27,25,25,23,25,30,29,24,29,36,35,35,32,37,25,23,31,36,35,34,34,36,38,32,35,32,32,31,32,33,32,31,33,38,23,22,21,18,18,20,26,20,21,22,20,19,26,21,19,20,24,19,19,21,52,89,39,20,28,18,19,21,21,27,20,21,23,18,24,18,23,23,23,24,22,24,24,24,21,24,24,25,26,24,25,22,21,25,30,78,114,92,64,43,32,31,50,89,134,181,193,181,175,176,179,177,179,174,165,149,131,102,109,145,164,178,180,178,173,162,156,155,158,162,162,163,162,156,157,155,151,152,150,153,149,148,150,141,132,130,114,100,78,62,53,53,44,28,28,51,80,86,82,77,84,109,124,138,157,182,200,206,218,226,231,247,248,253,253,253,253,253,248,222,193,189,218,237,238,229,211,191,194,194,200,208,191,186,197,217,212,194,172,147,96,14,1,10,9,13,12,13,13,13,15,14,14,47,39,27,27,42,47,59,100,125,152,147,154,115,35,44,79,136,183,200,210,208,210,210,205,204,199,194,190,179,169,159,154,139,125,110,87,81,40,8,26,26,59,80,78,79,71,81,92,109,128,142,160,178,189,200,210,208,214,127,33,59,112,182,204,188,175,159,144,133,120,113,105,91,91,79,50,25,29,56,101,118,130,168,163,140,137,132,91,25,8,18,21,25,21,24,21,22,29,19,21,22,19,26,19,24,33,31,29,39,83,131,134,120,121,127,142,179,189,180,137,40,14,16,10,24,31,30,35,39,34,42,51,51,48,54,59,62,61,57,50,53,105,160,182,185,173,164,158,162,156,148,148,140,131,134,139,139,131,135,133,132,138,145,150,152,152,149,153,152,143,144,147,143,145,141,147,145,142,143,136,141,144,147,148,146,141,140,139,150,154,150,150,147,139,146,151,150,150,148,153,155,154,158,161,160,156,150,156,159,154,154,160,159,152,146,141,144,147,155,150,154,152,150,153,155,153,148,155,155,160,155,149,160,160,163,159,150,148,154,155,155,155,143,141,142,139,128,131,141,141,136,133,140,142,136,129,137,141,132,130,132,138,139,150,158,151,146,138,132,127,137,133,123,137,148,137,104,60,50,73,105,92,61,87,109,123,108,94,92,65,42,43,49,61,82,99,103,100,99,93,91,90,84,86,71,50,40,33,36,39,41,47,48,56,55,56,55,54,59,59,66,66,66,62,52,59,56,52,58,54,54,57,57,57,51,54,57,54,53,52,53,55,54,57,56,49,54,56,49,55,54,50,51,51,56,51,48,51,54,45,48,44,45,51,51,53,45,43,44,44,44,49,49,44,51,45,34,41,44,36,42,42,39,39,41,46,38,43,36,41,40,35,42,39,38,37,38,37,36,39,35,36,34,37,37,33,37,34,35,41,34,28,37,33,35,38,30,27,33,34,34,29,34,35,27,34,32,27,34,35,27,30,32,31,34,31,24,27,25,28,32,24,28,25,30,29,27,29,32,27,27,31,26,24,23,23,30,26,22,24,29,27,26,37,35,24,30,29,26,22,28,40,84,137,139,116,75,48,33,25,32,23,31,29,28,34,30,27,24,27,30,29,28,27,23,29,28,29,29,28,28,22,25,22,21,31,26,29,60,91,78,37,18,31,24,19,27,22,26,25,26,24,34,37,29,35,29,27,31,28,36,41,32,36,34,35,33,34,33,33,37,32,30,34,35,30,34,31,21,22,20,23,19,20,23,21,21,16,27,23,15,21,21,23,21,22,24,77,70,22,27,18,18,22,27,21,19,27,22,24,20,24,24,24,21,18,22,21,27,27,21,21,26,23,27,24,22,26,24,27,58,108,108,76,50,27,32,32,63,95,124,173,193,190,181,172,170,174,172,171,162,153,164,155,120,98,92,118,145,163,178,166,151,146,149,161,161,155,159,163,162,159,155,157,156,153,152,152,151,152,154,148,151,144,129,110,87,87,75,73,73,84,122,139,140,121,97,80,76,81,82,102,122,125,128,132,136,139,155,182,201,204,204,222,237,227,228,231,245,250,243,186,147,156,159,174,189,220,236,222,219,223,241,243,233,216,194,111,7,1,8,10,13,12,14,12,14,15,14,14,98,95,66,48,40,45,55,92,127,169,185,199,141,47,51,77,134,178,193,196,186,179,173,163,147,136,123,110,103,89,76,71,63,54,46,42,47,22,19,41,41,66,97,118,141,159,178,189,202,213,219,222,222,230,218,219,213,205,110,27,39,79,139,146,129,111,94,84,84,93,98,102,114,115,111,63,19,24,31,47,69,120,184,172,145,135,132,90,21,16,16,19,24,29,25,22,23,23,24,21,21,25,25,19,24,36,35,29,37,48,66,117,51,44,56,98,134,168,211,196,84,21,14,24,44,40,46,50,41,36,37,39,38,67,110,126,114,116,153,170,174,176,173,156,147,146,142,142,139,134,133,131,128,126,122,134,139,138,135,134,140,139,141,150,151,148,145,142,148,138,139,144,142,142,141,145,139,135,137,137,139,142,141,138,143,145,140,136,137,141,134,139,143,144,146,145,147,147,150,151,148,139,141,148,146,141,135,143,154,155,153,146,155,156,149,153,158,161,152,149,150,146,146,147,148,143,145,147,155,161,157,152,155,152,153,146,141,146,141,142,150,149,146,144,142,139,145,146,142,142,146,145,151,152,148,150,150,145,136,137,146,145,150,158,160,147,132,141,126,129,134,131,124,145,160,145,128,92,59,31,61,36,63,76,82,98,94,105,145,175,122,34,6,10,24,46,55,62,65,60,63,50,43,60,42,45,45,49,46,51,51,55,61,60,57,56,56,53,61,63,61,61,62,57,54,60,60,60,60,55,57,53,51,59,52,57,56,55,60,55,57,55,54,48,54,57,50,53,53,53,50,49,59,56,53,52,52,50,50,51,49,48,46,46,46,50,46,42,45,44,47,49,48,44,43,43,38,42,43,40,42,43,45,41,39,41,39,37,39,38,35,38,37,36,42,39,33,35,37,36,35,37,32,36,34,32,38,37,36,35,30,32,31,38,35,29,32,35,35,32,34,31,34,31,25,36,27,30,31,28,33,32,33,28,30,31,24,28,30,30,26,24,27,28,29,28,27,30,25,25,30,23,24,26,24,27,23,25,24,27,25,32,35,29,33,35,31,24,24,23,27,29,27,40,86,138,138,110,81,52,29,26,23,21,29,28,24,29,29,28,27,30,32,24,24,32,26,27,30,27,29,21,20,27,27,28,31,29,40,76,88,67,31,21,23,21,22,21,23,22,24,24,32,38,34,34,32,29,27,26,39,34,35,39,36,39,27,29,35,34,35,28,33,29,29,35,35,25,26,32,16,21,23,23,18,20,20,18,23,20,19,22,25,19,27,19,41,78,42,21,29,19,15,27,19,22,25,18,24,24,23,20,22,21,21,25,26,22,25,24,20,23,26,22,25,25,21,26,44,92,113,88,58,35,28,34,32,60,102,119,156,194,191,184,168,157,155,167,162,160,153,149,168,166,143,112,94,90,106,137,170,169,160,159,166,169,168,160,158,168,166,169,165,160,161,159,160,155,156,157,157,163,169,165,164,145,129,116,99,100,100,116,139,150,153,153,132,113,115,116,125,136,134,129,122,129,128,115,123,129,141,141,133,175,171,170,177,188,210,206,177,107,74,122,139,148,174,224,251,249,245,244,248,248,249,249,230,112,4,1,6,11,13,12,12,12,14,15,14,14,173,145,92,64,43,37,48,62,86,138,165,180,124,45,37,56,108,139,142,131,116,106,96,81,74,66,55,54,57,61,66,83,90,108,122,128,147,76,17,47,72,119,146,177,204,211,218,208,210,208,203,192,182,167,157,154,136,117,54,19,35,47,87,89,85,84,78,80,86,76,72,60,47,48,39,32,25,29,29,33,43,87,150,144,127,127,129,90,35,13,14,21,26,28,22,26,17,24,26,22,24,24,25,23,27,34,31,31,52,81,124,128,127,134,131,139,155,159,184,184,94,46,34,31,42,33,32,29,24,25,22,29,30,76,153,166,170,173,187,191,181,173,152,144,147,153,157,153,145,141,141,147,152,147,146,150,153,149,147,146,143,144,143,141,143,141,141,141,146,143,137,139,146,144,139,145,141,138,139,141,142,142,144,141,143,147,143,137,137,134,133,139,148,152,153,151,148,146,147,149,147,142,134,134,142,142,141,141,139,142,141,142,144,140,143,150,156,155,154,148,144,145,145,143,147,147,145,149,145,146,139,136,136,127,136,135,140,142,141,137,140,153,153,160,149,146,153,151,153,152,150,149,153,159,160,162,166,159,156,152,152,148,141,141,145,145,141,149,156,152,156,143,139,150,151,143,109,81,59,49,45,44,56,71,77,70,68,113,221,252,245,188,131,75,25,4,11,15,24,27,39,43,44,48,50,53,56,59,63,61,64,63,65,59,50,59,53,51,57,62,59,56,65,61,59,56,56,55,56,56,55,55,52,53,51,56,54,57,57,57,55,50,54,53,48,54,53,50,53,51,55,48,51,54,49,53,52,50,47,50,51,47,46,43,44,49,49,49,40,44,47,45,46,44,44,43,41,42,44,43,42,41,40,43,42,37,39,41,37,35,40,40,37,41,37,35,33,38,36,34,39,36,36,37,38,37,33,32,36,33,33,36,33,29,38,30,33,35,27,33,30,27,35,35,29,31,27,33,37,27,31,29,28,27,29,30,30,26,29,29,28,31,32,27,21,29,25,26,29,29,26,27,24,24,26,27,25,22,24,29,24,28,30,26,31,23,27,27,23,29,27,25,22,27,26,44,86,134,143,129,101,59,42,29,21,24,24,25,23,31,31,29,27,23,28,24,29,33,27,28,26,26,24,22,29,33,27,26,29,38,79,83,49,29,19,20,27,22,26,21,18,27,33,39,36,32,32,27,27,28,32,37,37,31,34,42,31,29,37,37,29,31,30,31,33,33,34,24,22,22,21,20,19,24,21,23,20,20,23,22,24,25,21,19,26,24,59,64,26,23,24,16,22,24,21,23,25,24,20,27,26,24,19,24,24,22,23,19,21,23,24,27,24,21,25,23,32,83,115,95,66,41,28,27,26,38,72,91,112,141,184,193,178,171,160,154,153,158,160,161,159,149,162,174,165,155,129,115,95,113,160,179,189,185,178,177,169,164,170,173,175,176,174,172,166,167,161,162,165,164,167,165,173,169,171,162,146,132,113,109,114,125,139,146,153,155,150,145,148,155,162,173,165,150,148,159,160,148,139,137,141,133,127,139,146,139,132,133,143,139,125,72,51,92,96,104,137,202,245,248,252,239,248,248,252,252,239,110,3,0,6,11,13,12,12,12,14,15,14,14,157,122,71,54,42,46,47,63,73,102,129,142,76,26,45,45,80,85,83,69,56,62,65,71,84,100,106,121,137,147,160,170,176,180,188,193,187,98,46,59,94,147,171,191,184,168,158,142,132,126,132,107,88,107,73,63,56,39,28,33,30,51,72,69,69,46,42,42,33,28,25,21,24,22,24,29,30,36,28,39,41,65,120,114,114,123,125,89,25,15,14,17,28,28,23,25,27,28,25,22,19,21,24,25,25,35,37,36,43,98,150,160,155,151,152,137,110,79,62,46,42,31,17,21,33,36,33,37,34,32,29,31,32,55,132,170,170,170,166,156,156,159,155,155,145,150,155,151,153,154,153,152,155,152,150,154,154,157,154,147,149,146,143,145,138,140,144,141,146,146,147,145,139,134,141,143,143,141,143,143,139,148,146,149,150,144,151,145,145,148,150,152,152,156,151,154,157,155,158,158,155,150,143,147,147,148,149,133,132,135,140,128,121,129,125,122,122,134,138,134,136,131,134,136,134,137,141,125,120,129,133,130,129,134,146,146,143,151,152,146,145,146,145,149,147,146,145,146,142,136,136,134,139,141,136,132,124,123,124,118,115,107,100,97,105,110,119,127,126,129,124,122,111,105,106,93,74,45,47,50,52,32,30,51,49,53,45,63,173,250,252,252,251,248,175,95,24,4,10,17,28,44,55,61,59,66,75,74,72,76,67,57,60,57,53,54,50,50,53,57,63,59,55,61,57,54,53,53,55,56,57,53,59,54,52,59,57,52,57,50,53,52,53,51,47,54,57,56,49,49,53,55,52,49,50,50,53,50,48,51,48,44,47,46,45,44,47,51,47,41,44,45,46,49,44,44,43,44,38,42,39,36,40,38,41,35,35,37,36,38,38,39,34,34,33,39,36,34,42,37,42,36,39,41,29,33,35,34,37,33,31,35,33,30,33,34,30,30,29,33,31,29,31,31,30,31,35,35,27,29,29,28,27,27,33,28,24,30,29,29,29,23,25,25,28,29,22,26,26,27,31,27,29,27,22,22,28,29,21,24,28,22,28,27,27,24,30,24,24,33,35,27,24,27,29,37,36,80,85,142,152,147,111,90,47,27,25,29,18,24,27,24,30,26,29,25,26,31,29,24,25,25,21,26,32,29,28,25,25,24,51,89,75,44,27,19,23,23,24,22,19,25,35,49,38,32,36,27,24,30,41,33,36,30,35,39,28,29,29,36,34,29,33,32,35,34,33,31,24,19,21,28,19,23,22,18,21,19,19,20,20,22,19,21,19,39,69,40,22,27,20,18,18,23,22,21,24,24,23,22,21,25,28,21,19,21,20,24,25,23,24,21,23,25,34,66,115,113,78,52,33,25,28,25,39,80,99,104,120,161,186,181,167,165,159,156,161,169,157,155,150,145,161,172,168,181,177,152,114,108,128,158,180,187,176,165,160,160,164,171,171,176,169,168,173,171,171,172,177,175,169,171,173,174,177,170,153,137,130,123,125,139,142,151,160,167,160,157,159,151,159,174,163,152,146,150,152,148,145,134,141,137,129,128,136,131,129,132,145,143,138,104,91,85,51,49,72,134,184,206,206,206,236,244,251,251,236,111,3,0,6,10,12,12,12,12,14,14,15,14,121,83,52,51,44,37,46,53,61,76,73,66,40,41,60,66,94,110,120,120,124,133,148,158,172,179,178,190,191,191,192,193,191,188,185,179,166,78,34,50,78,132,147,145,117,95,84,74,73,69,72,57,60,61,53,60,54,40,23,23,21,23,33,27,28,23,21,26,25,19,22,27,20,20,22,28,36,44,47,53,47,80,129,125,126,128,119,68,24,17,12,20,20,24,29,27,23,24,22,24,19,23,22,21,28,33,39,31,39,49,57,62,57,57,46,41,35,31,27,22,25,28,26,29,45,64,78,87,82,81,86,94,99,124,154,157,163,162,160,152,148,151,149,145,134,128,134,132,131,137,137,134,136,136,142,142,146,151,150,147,147,149,152,152,155,147,148,147,145,147,143,143,141,139,145,147,140,148,152,152,147,145,147,152,155,147,148,145,147,152,147,139,137,141,134,137,145,141,147,146,133,131,139,139,137,140,136,137,141,141,136,136,141,139,131,125,119,125,138,142,142,141,141,140,140,135,131,130,132,132,123,129,145,151,156,150,148,146,143,135,134,132,131,134,123,122,122,128,137,129,125,122,111,111,111,95,100,110,112,114,122,127,120,117,114,112,108,113,120,104,105,98,96,94,76,77,75,65,59,60,61,63,53,38,41,41,39,27,93,181,203,251,252,252,252,241,167,90,27,11,21,33,50,62,72,81,84,77,78,72,64,54,48,53,54,52,53,48,53,60,64,66,56,55,56,55,57,52,57,57,55,59,59,55,54,56,55,55,51,56,53,53,51,53,55,53,49,51,57,51,54,53,49,50,52,54,49,49,47,46,53,45,50,47,44,53,46,48,46,43,46,47,47,43,45,42,45,40,36,39,34,39,37,35,42,34,38,39,41,36,35,38,34,42,31,33,39,33,40,39,39,35,32,36,36,31,32,32,29,29,35,41,35,31,36,34,31,33,31,30,29,30,29,33,36,31,31,29,27,32,31,32,27,28,32,25,27,28,24,27,26,27,27,25,27,27,24,31,26,23,27,21,21,26,24,22,24,24,27,29,25,30,21,27,32,24,31,26,27,31,28,29,28,37,28,27,34,32,25,36,73,134,160,147,132,87,55,39,29,24,22,26,23,26,27,31,27,21,29,22,25,24,29,25,26,29,23,26,27,29,30,65,95,71,30,22,20,24,41,27,23,27,38,45,38,38,32,27,26,30,36,40,34,32,36,38,28,30,33,29,36,32,30,34,34,35,32,27,24,18,22,24,19,20,21,22,22,19,21,18,20,24,21,22,28,54,46,27,21,24,23,18,22,18,19,24,25,21,24,24,21,28,23,22,24,22,27,31,29,20,22,20,31,68,109,118,84,55,36,24,32,24,23,43,87,108,106,115,154,190,184,171,171,163,157,164,169,165,156,153,158,162,168,171,170,173,173,169,143,112,98,109,145,167,166,171,162,159,169,168,165,168,166,170,170,174,177,178,181,177,176,171,171,169,177,176,165,153,150,153,152,152,158,162,160,166,157,151,151,141,151,169,175,163,142,136,136,144,143,139,135,134,130,121,118,119,128,145,162,165,169,155,150,134,83,61,47,74,106,125,130,136,183,201,210,218,215,116,5,1,7,10,13,13,13,12,14,15,15,15,47,31,29,42,32,36,37,46,58,63,81,84,52,50,65,94,155,174,193,186,188,193,191,191,190,190,184,183,179,178,174,172,164,149,138,132,100,36,31,39,64,97,100,105,94,94,100,100,92,87,53,66,51,38,35,33,28,27,27,25,15,25,24,18,29,23,24,22,19,27,23,27,21,19,23,30,38,46,78,98,116,154,181,155,145,141,131,73,14,16,15,18,19,25,28,20,24,30,25,27,23,26,25,28,37,46,43,42,40,34,31,29,34,23,22,25,27,30,27,29,34,45,55,72,122,164,194,207,194,191,199,198,192,184,174,160,150,148,142,142,146,142,139,131,127,126,128,134,129,134,131,123,125,122,127,133,132,132,136,134,140,139,133,142,148,149,146,145,143,134,135,142,147,153,153,149,150,151,152,147,136,144,140,139,142,139,139,139,140,137,131,127,127,130,121,118,122,119,131,129,121,122,123,129,128,133,139,139,143,141,138,141,144,141,130,125,120,122,129,133,148,137,128,128,131,139,144,141,137,130,126,130,141,137,129,133,128,118,124,131,141,137,131,126,117,113,103,112,121,120,130,125,120,127,132,139,139,139,141,146,158,168,167,161,150,128,119,116,102,90,90,95,96,88,93,97,75,80,78,77,84,80,81,70,43,37,39,34,79,136,134,179,249,253,252,252,252,235,154,83,22,5,24,31,55,69,71,71,72,64,60,47,47,54,49,49,49,50,54,60,63,57,55,61,53,54,61,53,59,57,57,56,57,59,49,51,50,54,56,53,57,54,55,50,48,52,50,52,49,48,51,50,52,53,52,50,53,49,42,49,47,46,50,51,51,48,45,44,46,42,42,42,45,44,44,42,40,43,35,38,38,37,37,37,38,39,40,39,39,40,37,35,36,36,36,35,35,37,39,31,35,33,35,39,32,33,33,34,34,36,36,29,35,33,33,37,29,30,29,30,32,33,35,26,29,32,24,29,32,31,31,27,28,30,29,26,25,25,27,31,28,19,29,25,27,30,24,31,24,22,27,21,21,24,22,24,25,21,26,28,27,25,27,27,25,29,22,24,28,29,22,36,41,33,37,31,29,28,22,25,27,37,56,99,151,156,145,127,84,55,68,33,25,22,27,25,24,23,27,26,27,29,30,27,25,29,30,33,31,26,29,35,71,84,48,32,16,35,51,22,20,25,38,45,41,42,34,21,27,34,34,40,31,34,38,29,30,33,29,35,28,30,33,28,40,37,34,26,18,16,22,20,19,27,24,21,21,20,19,24,24,23,24,22,52,58,29,19,23,24,21,21,22,21,22,22,23,23,21,22,19,19,22,27,24,23,24,23,24,24,39,66,116,124,89,60,37,30,29,26,21,25,49,84,113,110,104,134,185,194,177,174,175,163,163,168,168,166,157,168,175,172,174,172,165,165,164,170,162,140,116,93,103,132,163,179,179,177,173,171,167,167,170,171,167,168,166,166,170,171,173,169,165,168,174,175,171,158,155,151,154,147,156,158,155,159,157,150,144,142,156,177,183,171,153,149,153,159,157,146,149,150,149,129,121,125,132,145,163,169,175,178,186,178,152,139,115,105,100,85,63,65,111,133,160,171,186,119,8,2,8,11,12,10,15,13,13,14,14,14,17,34,40,43,36,42,38,44,58,77,124,141,78,48,72,116,165,191,203,194,194,190,183,175,168,164,152,144,136,128,122,113,107,92,79,66,39,25,39,36,68,107,117,118,113,106,85,61,39,32,33,25,22,19,18,21,26,23,29,27,23,27,21,23,25,26,22,20,24,24,27,24,18,30,28,27,31,57,116,160,182,196,194,154,140,142,139,84,24,11,12,16,26,31,27,30,31,32,40,36,36,42,37,36,41,37,35,27,24,25,24,22,26,24,23,26,36,41,46,59,77,124,161,190,210,211,206,198,183,182,181,181,178,164,162,157,149,149,147,146,137,130,132,130,135,136,141,139,142,139,134,141,130,122,124,120,118,117,129,138,136,125,117,124,132,130,133,137,142,146,146,145,136,134,134,145,141,133,127,117,128,130,127,124,125,131,134,130,130,129,127,139,140,143,134,122,127,131,132,129,129,125,132,128,119,125,132,131,131,126,111,117,130,137,132,130,130,113,107,120,129,125,121,136,142,141,148,142,141,136,128,131,137,130,111,109,116,125,139,137,137,126,122,118,114,129,116,100,97,113,127,129,118,131,141,132,142,126,121,137,151,148,134,142,133,115,100,83,84,79,85,81,83,97,95,89,74,75,81,77,83,90,74,70,66,48,45,36,92,122,82,98,129,188,252,252,252,252,252,240,159,85,23,6,12,27,38,45,60,66,66,57,60,59,49,46,50,51,52,56,60,61,60,61,60,57,59,57,57,55,55,58,49,55,59,52,53,55,53,55,57,53,53,49,53,48,52,50,48,50,52,51,47,54,50,52,53,49,46,43,46,49,49,40,47,46,43,49,43,44,45,48,41,41,44,46,40,39,42,34,37,40,38,37,37,38,40,37,38,37,35,35,36,36,37,40,35,34,38,33,32,34,35,34,34,34,36,35,29,38,33,30,33,30,33,29,35,35,33,29,29,31,31,33,29,29,32,29,30,34,32,35,28,27,28,25,29,25,26,25,26,25,32,27,28,30,21,26,22,32,26,26,23,23,24,27,22,22,23,24,27,24,24,26,27,29,26,23,29,27,33,43,38,38,46,32,21,25,29,31,23,23,28,32,45,78,127,154,161,153,128,96,62,46,29,19,23,21,22,24,31,27,24,31,29,28,30,32,27,26,26,26,42,76,81,48,23,31,29,18,24,28,38,46,39,37,42,33,31,44,39,34,28,36,38,29,33,27,36,33,31,30,27,37,35,33,38,25,17,21,21,17,24,23,18,23,19,21,24,21,20,24,21,34,59,37,23,23,22,22,16,23,23,18,24,23,18,23,23,24,22,23,28,25,21,21,22,24,48,83,119,115,89,58,34,32,29,27,23,22,37,64,98,118,115,103,119,168,190,174,162,169,170,165,165,167,167,163,165,167,170,170,164,164,165,162,162,165,165,160,149,113,92,101,134,170,182,181,177,168,165,175,176,169,165,157,151,151,157,166,164,160,158,162,174,173,165,150,139,139,137,142,147,148,153,165,166,155,152,152,164,173,178,173,162,170,169,162,155,155,160,168,167,148,146,147,142,154,169,170,179,188,199,200,193,191,175,164,142,113,64,28,51,72,104,130,152,111,15,2,10,12,13,11,14,12,13,15,15,15,49,49,45,48,45,45,45,46,51,63,107,117,59,46,61,94,148,167,174,160,152,137,125,113,110,92,92,87,69,73,70,66,72,74,74,73,46,30,26,28,41,51,53,44,40,36,24,27,19,20,22,16,22,22,22,22,22,24,29,26,24,26,26,24,22,23,24,22,23,22,21,27,24,21,24,24,27,46,85,118,130,140,142,118,125,134,135,86,23,16,17,28,32,39,39,39,43,41,39,35,34,29,29,21,28,30,29,31,19,23,25,19,28,34,36,54,71,108,122,137,184,203,201,202,184,169,163,161,159,156,158,153,152,149,149,152,149,150,149,146,146,138,137,137,141,139,137,146,137,127,118,127,139,136,131,125,125,122,131,140,142,134,125,133,133,131,129,133,147,146,135,125,109,111,122,120,111,98,103,118,120,121,123,123,110,130,127,135,143,146,143,142,148,145,135,132,135,125,136,125,120,125,128,124,116,124,123,128,117,105,107,120,128,132,126,122,112,94,101,108,119,117,122,115,119,132,135,136,137,120,112,120,124,131,121,123,130,129,136,127,115,101,95,109,124,127,118,113,99,91,95,89,87,92,99,90,77,82,88,104,99,85,98,111,116,118,118,102,94,91,89,97,96,90,92,89,63,76,86,81,70,82,64,67,70,64,60,42,54,94,94,92,86,106,150,205,253,253,252,252,252,242,142,81,17,2,9,13,34,48,59,58,60,59,50,49,53,54,50,57,64,59,59,66,61,58,56,57,57,52,57,53,54,52,52,59,55,57,52,54,54,50,54,54,49,53,50,51,56,50,49,52,49,50,55,53,49,50,50,49,48,45,49,46,43,46,48,44,41,49,46,41,44,37,42,42,39,39,40,41,37,41,36,33,37,43,39,33,39,39,35,35,36,38,34,35,38,36,33,35,35,34,34,34,42,28,32,38,31,37,29,24,36,30,30,37,29,33,34,30,29,30,33,27,36,29,28,34,27,33,28,25,30,23,28,29,24,24,29,27,21,31,27,25,27,21,27,24,24,26,23,23,27,23,23,25,22,22,23,18,22,24,24,28,23,24,24,23,26,30,35,36,33,35,34,23,29,30,29,29,27,30,26,28,32,32,34,48,76,130,100,162,154,138,104,67,48,35,27,29,23,22,26,26,31,35,28,23,29,30,24,29,27,49,81,73,45,23,20,23,29,29,38,43,38,39,37,39,46,39,40,41,38,38,34,33,35,36,36,34,29,31,29,34,36,32,37,25,21,16,20,23,20,23,19,21,24,19,19,21,21,23,27,53,49,24,21,23,19,21,21,17,21,23,22,19,24,21,22,24,23,23,24,30,21,37,67,97,123,120,89,50,41,27,28,29,18,24,25,41,79,108,124,115,105,113,155,187,172,160,161,167,167,166,172,167,162,160,160,165,164,160,160,157,162,168,162,163,167,168,168,150,130,105,102,127,156,175,180,174,166,168,163,160,158,158,151,146,156,166,163,160,157,165,176,175,165,150,146,141,143,143,146,151,156,168,169,162,153,156,163,169,167,158,154,163,163,158,153,148,154,165,170,159,155,149,151,158,170,176,182,191,202,208,204,205,197,192,185,162,114,70,56,42,65,78,113,105,17,4,11,10,15,12,14,13,13,15,14,15,63,63,41,50,48,42,51,49,52,52,72,75,47,42,49,69,105,120,113,97,81,76,75,78,75,78,83,84,89,96,88,80,78,65,50,44,34,26,25,19,23,23,25,26,22,24,22,24,24,20,19,19,23,23,24,21,21,23,24,29,24,26,25,20,26,23,21,23,20,24,22,22,21,22,20,21,27,40,64,71,87,106,122,127,142,146,139,87,33,29,24,37,45,36,40,34,30,31,27,24,24,25,24,17,27,30,28,28,29,36,40,41,53,63,88,134,170,183,195,201,198,194,174,156,158,155,149,153,151,152,159,162,158,156,155,148,143,139,139,143,141,143,146,140,138,127,130,128,135,130,113,116,128,147,141,136,132,123,132,135,131,127,120,124,131,123,115,120,110,95,94,87,95,110,112,111,94,94,105,110,108,103,100,94,91,83,93,105,116,117,101,103,105,112,100,98,107,112,121,113,117,113,119,131,131,128,130,127,112,110,114,124,125,121,120,113,114,108,104,110,106,102,92,93,109,112,106,112,119,107,105,108,112,121,115,117,117,114,124,116,116,110,114,127,128,116,97,98,103,97,84,81,82,101,92,74,99,102,98,98,104,120,128,138,130,123,128,125,111,105,125,120,107,96,91,94,96,88,80,76,74,80,70,67,69,66,68,53,52,67,93,143,170,162,136,142,171,219,253,253,252,252,252,248,181,110,44,7,6,11,19,26,46,52,53,55,55,56,57,61,67,61,55,57,56,57,57,59,60,54,50,59,53,54,57,53,51,51,55,49,53,53,51,53,53,53,50,54,47,50,52,48,46,52,52,50,49,50,49,44,47,45,47,42,46,43,46,50,45,45,42,39,43,41,42,43,38,42,38,35,38,34,36,35,35,36,35,34,39,41,36,36,35,34,34,35,33,33,34,35,36,35,35,38,34,30,36,33,31,32,31,30,32,33,29,35,33,27,35,29,32,27,28,33,28,33,33,28,31,29,27,29,25,29,28,28,28,27,28,29,29,24,24,27,27,25,23,31,22,24,24,23,29,22,20,21,23,27,25,19,24,27,21,26,27,23,25,47,42,22,29,26,32,31,28,35,30,26,33,36,31,29,24,28,31,25,26,29,30,36,43,71,115,155,162,159,148,134,108,68,52,43,36,29,29,29,28,22,27,26,26,27,27,23,46,78,69,46,22,18,24,26,33,34,36,36,37,33,36,48,50,51,42,39,39,35,34,30,36,34,29,34,34,31,31,34,39,26,20,20,21,19,19,23,19,22,21,23,24,23,22,23,53,53,31,21,21,20,19,20,24,18,20,27,20,21,24,19,22,23,20,31,39,61,89,131,146,107,71,47,35,31,27,26,23,21,24,30,53,80,116,111,100,104,108,151,185,186,171,159,161,165,163,163,170,166,156,152,159,161,158,165,162,163,171,163,160,165,169,173,179,179,169,139,105,95,113,153,183,182,171,168,160,156,159,163,162,162,163,169,172,169,169,174,179,177,170,160,150,151,148,150,153,154,161,162,166,163,158,160,167,170,168,167,162,162,155,151,148,143,143,155,168,157,148,151,151,153,163,165,166,176,189,198,200,200,200,195,188,189,166,136,110,71,59,49,76,87,21,4,12,10,15,13,13,14,14,14,14,14,50,50,48,49,51,56,56,56,58,56,59,49,37,43,46,66,86,92,96,97,100,100,120,106,106,102,97,58,57,48,34,27,32,27,24,20,27,27,21,20,22,26,21,22,27,27,23,21,25,24,18,26,20,21,25,18,20,24,26,26,24,28,24,21,25,26,24,24,21,22,23,21,23,17,22,22,31,50,83,106,118,133,137,136,130,122,95,63,40,28,23,28,33,31,27,22,27,27,24,26,19,21,24,20,27,30,29,34,41,69,109,141,160,168,182,203,212,198,191,184,180,179,165,162,160,159,167,154,148,154,155,159,160,156,147,141,139,142,141,135,134,139,141,133,124,109,105,118,136,137,128,130,137,144,140,140,130,120,131,117,128,124,103,114,119,128,128,123,108,98,103,120,127,131,127,132,130,123,127,107,125,105,122,115,112,77,98,103,83,83,80,82,99,94,91,113,95,115,105,119,136,126,122,126,128,110,103,101,92,114,103,115,114,108,112,116,134,110,99,92,79,86,94,98,99,92,89,97,108,100,102,106,111,118,104,105,113,101,88,99,114,114,116,116,111,81,71,86,106,86,91,94,101,100,107,126,130,126,120,130,146,148,150,137,112,103,98,103,110,111,122,119,104,96,107,105,99,89,91,105,103,91,74,66,65,65,64,57,64,63,66,109,168,123,110,110,125,136,167,177,253,253,252,252,252,252,202,133,69,15,4,9,14,35,49,56,53,56,57,62,63,57,61,57,57,57,56,55,56,55,56,57,57,56,53,52,53,53,52,51,54,56,54,53,53,50,48,52,52,47,45,49,51,54,54,45,47,49,47,45,45,45,41,43,46,46,45,41,43,38,40,42,43,43,37,39,38,38,39,36,35,38,39,36,36,36,34,35,34,35,39,35,34,32,33,33,33,37,35,35,36,35,33,29,37,32,33,29,27,39,29,32,33,29,34,33,30,33,29,29,33,28,30,33,29,28,28,29,29,31,27,27,31,25,27,29,24,27,28,29,26,23,23,24,30,23,29,26,22,25,26,24,20,23,23,22,22,21,20,25,21,23,21,22,27,21,35,49,34,25,23,21,27,24,33,30,32,33,29,34,26,24,30,26,30,29,28,25,23,37,29,27,34,41,55,99,100,167,167,159,151,144,137,114,106,60,45,37,31,25,24,32,22,26,29,47,77,67,45,30,22,24,37,39,33,45,51,77,126,137,98,56,47,45,40,34,26,31,31,34,31,31,33,26,33,29,36,27,23,30,22,24,18,20,22,22,22,19,21,19,21,42,56,35,22,23,22,22,19,19,19,22,20,19,25,22,19,27,36,43,63,88,128,153,130,88,54,42,31,29,30,20,21,21,22,25,39,60,83,106,109,92,104,99,130,175,182,177,157,155,155,155,158,157,159,159,155,153,157,158,160,163,167,163,161,160,159,165,159,157,173,178,178,160,134,105,88,113,154,175,178,177,169,169,165,169,169,165,173,174,175,170,166,173,177,178,170,161,143,139,139,148,152,162,169,169,169,167,163,166,168,169,181,185,173,162,156,154,155,156,156,167,179,162,150,152,151,158,157,155,158,160,179,195,196,198,198,193,187,187,184,171,155,121,102,84,88,87,20,2,11,10,14,12,13,12,13,15,13,13,56,55,53,66,64,72,77,80,82,71,57,39,30,34,45,69,105,115,103,98,92,76,55,46,38,32,26,26,24,21,18,21,29,21,23,23,24,31,24,22,23,23,22,24,25,21,21,22,23,24,20,22,19,21,20,19,22,22,22,22,22,26,29,27,24,22,27,24,25,24,23,27,23,23,23,28,33,53,78,100,108,83,71,52,51,58,46,40,27,19,16,24,27,29,28,23,22,23,23,24,23,22,24,23,27,25,29,37,65,152,212,227,217,201,186,175,174,161,153,154,149,154,154,146,147,136,128,131,133,140,146,145,137,139,120,107,110,117,129,131,129,128,133,123,119,117,109,108,120,137,141,138,140,137,131,139,125,113,126,128,129,127,124,136,136,131,143,148,136,138,145,153,155,145,148,144,144,140,141,149,144,147,152,146,145,128,113,112,114,127,126,129,130,136,135,137,130,127,143,149,153,139,127,120,105,103,99,108,121,125,124,117,102,95,105,118,116,99,93,105,118,123,119,118,125,114,116,127,130,136,147,146,150,148,145,152,144,140,128,125,131,111,113,126,114,105,101,113,117,118,122,118,117,124,122,112,104,93,96,103,101,100,105,96,75,75,79,82,92,103,97,78,74,81,91,96,97,91,89,91,82,66,57,55,57,55,55,56,57,54,41,35,39,57,75,116,144,112,86,93,141,204,253,253,252,252,252,252,239,165,96,34,5,9,22,36,51,51,53,59,61,63,64,57,61,61,55,59,60,56,56,55,50,59,59,48,56,54,52,55,54,53,53,53,50,51,48,53,49,53,52,50,50,47,48,49,49,45,46,45,43,45,45,45,47,40,39,44,42,44,43,41,40,42,43,41,38,35,36,40,38,33,38,36,39,38,34,35,28,38,34,34,36,34,33,37,38,35,37,31,29,38,34,32,30,30,35,31,34,33,33,33,32,32,34,34,27,32,29,32,33,29,33,27,28,29,29,26,28,28,21,31,27,25,31,26,23,26,27,28,25,26,27,20,34,28,23,26,24,24,19,26,26,19,25,24,24,25,24,22,19,19,23,25,22,17,27,27,22,29,27,24,21,26,30,27,25,30,25,23,26,27,26,32,38,30,27,25,31,31,27,28,27,30,27,31,31,42,62,86,125,153,170,166,173,165,156,147,141,132,117,93,71,66,59,60,92,125,117,94,65,92,124,135,155,167,196,209,212,198,133,64,53,51,47,37,23,30,35,30,28,32,29,29,33,33,28,31,44,41,39,36,27,28,21,16,21,19,22,21,40,51,38,23,16,22,20,16,24,16,21,24,22,35,39,52,66,82,122,137,149,129,84,66,43,34,30,27,29,21,19,21,21,27,36,50,70,85,94,98,96,97,100,117,157,177,170,159,157,157,159,157,157,156,162,167,160,163,165,164,164,167,165,158,164,160,161,159,152,154,161,167,169,169,171,147,107,92,111,137,163,182,178,176,174,174,170,166,169,170,169,170,165,169,177,179,171,162,155,155,154,159,169,174,177,177,176,171,168,165,165,175,184,184,170,158,157,162,168,163,165,178,178,162,150,154,154,158,165,159,151,156,181,198,205,207,203,191,178,184,182,181,168,155,152,132,136,99,15,1,9,9,13,12,13,12,13,14,14,14,73,89,95,109,118,123,124,87,123,103,61,30,22,25,27,35,37,36,36,27,30,21,24,23,18,21,21,21,19,22,21,20,22,21,22,24,24,27,26,28,22,24,24,23,27,26,28,22,20,24,21,26,22,20,21,19,24,18,21,27,26,26,23,28,24,27,28,26,31,29,29,33,33,33,34,37,39,40,39,41,39,32,24,31,30,37,40,30,22,17,22,23,30,32,24,25,25,23,21,27,25,19,21,23,22,19,21,20,51,121,164,174,160,134,138,109,112,107,110,114,120,125,125,120,110,120,115,103,109,117,129,132,131,137,134,118,125,117,131,128,137,136,124,122,131,134,128,107,101,115,116,119,110,114,118,125,106,96,111,129,129,134,123,117,107,94,86,94,105,115,110,113,113,99,101,87,85,80,91,107,122,100,117,108,105,105,97,97,120,122,125,122,120,128,120,127,127,101,128,125,93,91,98,96,87,87,124,114,118,118,131,112,88,84,86,104,95,105,128,141,143,136,116,112,117,99,118,118,123,128,128,121,121,134,124,121,136,137,128,135,130,119,95,114,126,115,117,132,132,133,122,117,133,121,113,110,106,107,97,95,84,77,83,84,68,91,89,84,96,89,87,93,98,105,88,94,86,75,72,74,69,59,53,61,61,62,63,57,67,60,46,48,30,46,68,105,145,171,122,130,101,123,159,202,245,253,252,252,252,252,250,187,90,35,6,10,29,34,45,60,60,59,61,61,60,60,56,54,57,53,53,51,56,60,54,55,54,57,54,54,53,51,51,53,53,45,47,52,51,51,54,49,42,49,46,48,49,45,50,44,48,42,43,45,39,43,40,43,45,44,40,40,42,40,40,37,32,39,35,33,35,37,39,36,35,33,32,35,32,34,33,33,39,38,34,35,32,29,33,30,36,28,30,31,31,35,32,32,32,30,27,36,31,31,33,27,30,31,27,33,30,21,32,30,26,28,26,27,28,27,29,25,27,26,27,24,27,30,27,27,27,27,26,22,28,27,23,18,22,21,24,28,23,27,23,23,29,19,20,26,20,25,22,21,24,21,24,24,25,24,23,26,27,24,22,26,26,25,23,31,24,27,27,31,34,22,33,32,27,38,30,24,29,27,26,32,23,26,31,31,34,42,52,60,81,116,137,152,169,172,177,174,173,178,167,158,155,177,199,183,184,201,198,202,193,191,172,153,136,101,51,31,35,35,42,35,32,29,31,34,29,29,28,30,30,31,32,34,41,48,51,55,49,48,40,40,41,32,34,53,65,41,31,53,52,34,35,39,45,75,55,68,88,88,142,146,146,137,100,68,53,75,34,33,27,29,22,19,24,22,21,22,30,46,56,76,86,92,96,97,99,100,113,145,177,177,165,167,168,169,169,168,164,165,173,170,165,162,165,164,162,162,162,160,160,163,163,159,155,159,162,160,164,172,183,177,147,118,93,97,136,171,184,184,175,174,171,171,173,165,169,167,167,169,169,171,164,162,170,168,165,169,171,181,181,177,177,175,170,168,168,170,176,171,162,159,161,167,169,172,170,170,171,160,155,155,152,160,162,160,162,173,197,214,217,210,203,190,178,182,183,174,169,163,165,159,157,107,13,1,9,9,12,10,13,13,14,14,12,13,123,137,134,134,122,113,96,73,47,33,33,22,21,22,18,23,21,24,21,22,23,19,23,22,23,23,26,22,24,21,18,21,22,24,20,21,21,22,27,29,24,25,21,24,27,21,24,23,24,22,22,22,19,22,20,19,22,24,21,28,30,27,27,31,34,35,34,35,41,41,40,35,39,35,29,32,27,28,24,27,29,23,23,24,22,22,21,28,25,21,24,23,33,36,31,33,35,33,34,30,28,24,26,25,22,24,29,34,46,74,96,123,130,122,98,81,89,89,92,104,116,113,100,95,103,108,108,119,112,105,115,120,129,147,142,141,141,137,154,158,165,163,155,144,144,144,133,132,111,101,93,81,90,83,84,101,90,86,101,105,112,109,92,96,100,84,77,77,90,93,79,81,77,63,67,47,45,55,49,48,45,47,55,62,70,76,77,77,76,81,76,88,87,89,92,84,81,65,46,33,36,47,63,68,80,97,105,111,103,99,93,88,77,73,87,95,104,109,110,118,113,94,84,78,76,77,90,112,114,102,93,83,82,80,76,87,77,72,78,93,103,79,81,106,113,108,96,97,100,106,107,101,100,103,103,108,119,111,96,87,76,62,69,75,65,70,77,78,76,71,81,81,80,79,79,84,68,57,57,63,61,59,70,69,68,68,76,78,62,66,64,62,65,57,70,87,128,160,186,191,168,137,104,109,130,167,216,251,252,252,252,252,204,139,86,49,32,17,19,23,33,33,41,49,51,56,56,60,56,53,55,53,58,61,54,60,54,50,50,49,57,53,50,53,46,53,52,48,50,47,49,50,46,46,47,51,49,47,52,44,40,43,41,44,45,46,41,42,45,42,43,44,39,39,41,39,37,38,39,37,36,34,42,33,37,34,34,29,32,40,35,40,36,32,34,38,34,35,32,29,33,35,32,30,38,32,26,32,32,30,34,29,29,30,30,37,31,28,29,30,28,25,32,29,26,26,30,33,27,23,24,27,23,29,28,24,28,23,23,24,30,28,21,27,25,21,24,27,26,22,25,27,23,22,21,21,24,19,24,22,27,28,20,29,24,20,22,26,22,24,24,24,22,25,28,25,29,22,24,26,24,30,27,29,24,27,36,25,54,50,26,28,26,28,30,32,23,25,29,29,33,29,32,27,29,25,28,34,43,52,56,69,71,84,102,107,124,131,122,131,145,148,139,101,71,36,35,36,19,42,65,37,24,22,35,39,23,35,28,25,33,29,33,28,27,33,33,31,23,33,45,49,60,63,62,68,71,66,103,121,101,98,86,92,96,103,117,136,141,130,144,146,141,120,83,63,52,40,41,29,27,27,22,27,19,22,24,21,21,25,25,42,61,71,72,86,95,82,100,102,94,112,149,179,181,170,167,173,174,170,173,167,163,164,163,165,158,156,162,160,163,164,162,163,163,160,163,163,165,165,158,160,162,168,177,175,170,153,119,89,99,135,162,179,181,173,171,169,169,165,162,170,168,164,160,157,158,165,168,166,169,170,178,180,176,178,176,180,177,171,171,172,171,168,166,164,169,170,177,177,170,167,166,168,170,162,154,154,158,159,157,170,193,207,213,208,198,185,175,179,178,174,166,159,168,158,164,111,11,2,9,9,14,10,13,13,13,14,13,14,75,61,41,35,28,25,18,39,17,22,24,19,20,21,20,21,22,26,25,19,20,28,29,28,29,30,28,24,23,18,19,21,22,21,19,22,22,18,26,23,24,24,23,22,26,24,21,27,23,24,22,24,24,22,24,21,24,25,25,35,40,40,37,39,44,37,39,41,34,33,34,29,26,22,21,24,22,22,31,26,24,24,22,22,22,29,23,22,29,22,28,30,41,54,68,86,91,90,86,78,69,64,63,69,66,105,100,93,95,105,122,135,137,112,109,95,96,89,93,103,108,97,84,72,78,98,102,103,96,89,96,105,105,103,94,101,118,112,116,108,134,134,134,129,120,120,118,113,115,112,103,100,104,100,99,101,101,102,115,109,106,112,103,122,137,141,138,133,126,110,128,129,107,100,122,130,136,131,98,68,69,69,75,91,96,105,107,94,98,93,94,101,92,83,102,75,68,83,53,87,94,105,111,102,112,102,88,112,102,86,87,92,90,96,107,122,106,104,91,94,96,96,87,77,82,82,99,108,108,106,103,101,95,97,90,80,67,78,69,87,90,87,102,112,106,92,79,71,85,88,98,97,82,86,94,92,83,97,90,77,81,74,80,72,70,68,68,87,77,76,94,79,84,81,72,80,62,67,66,63,68,64,64,74,63,69,75,76,64,54,60,63,62,70,55,33,85,87,139,162,199,176,153,124,102,107,122,160,212,251,252,252,240,210,172,141,104,66,43,25,15,11,13,14,24,35,42,53,56,57,60,59,56,57,51,55,56,53,54,54,56,48,50,54,51,52,50,50,50,51,48,49,46,49,47,48,50,49,42,43,43,39,44,44,43,46,43,45,44,43,41,41,42,42,36,39,40,37,40,33,35,35,37,39,35,37,35,30,32,35,39,35,32,33,32,35,28,30,36,31,37,34,33,29,29,37,31,29,29,32,27,31,30,29,31,23,32,29,25,32,29,30,24,28,29,32,26,31,28,23,28,27,29,23,27,25,27,24,23,28,26,24,25,28,24,23,21,21,24,23,25,20,20,22,22,22,19,22,22,21,21,25,24,22,22,22,24,17,19,20,24,24,24,29,24,22,24,22,24,24,24,25,28,29,28,31,24,39,59,39,27,29,27,32,29,27,27,30,29,30,26,28,31,30,22,24,30,29,28,28,28,27,23,29,32,28,36,35,29,32,51,63,74,67,53,46,47,23,47,145,122,47,26,27,41,36,29,30,32,33,30,31,31,31,30,32,31,27,19,22,25,24,39,46,41,60,71,63,76,88,93,95,100,70,72,91,91,81,76,80,53,52,39,68,33,29,31,29,23,22,24,21,19,24,22,21,24,27,30,37,53,64,74,82,76,90,90,81,98,92,102,143,181,182,165,157,154,153,160,159,153,149,146,147,151,150,157,157,159,163,160,163,160,162,161,160,165,163,168,165,159,159,158,156,159,167,172,171,147,111,93,94,124,158,167,171,166,165,166,159,164,167,165,163,160,157,156,163,169,169,167,169,167,164,163,162,165,167,165,168,172,173,176,171,169,170,175,177,174,171,164,167,173,173,174,168,159,159,160,154,155,167,173,191,193,194,192,184,178,180,178,171,170,160,162,157,159,111,13,1,9,9,12,11,13,11,12,13,14,14,18,20,21,20,18,16,17,19,19,22,21,24,24,25,22,23,21,23,26,22,26,26,29,40,44,44,47,47,35,26,21,18,23,20,17,18,23,19,25,24,26,27,19,24,27,24,24,27,21,24,29,26,29,28,30,34,34,36,39,38,41,37,34,35,34,37,29,27,26,23,23,22,21,23,22,23,21,27,29,22,28,25,27,25,22,28,24,23,29,37,52,61,92,135,174,202,207,206,207,216,205,191,188,192,195,189,169,147,137,135,128,122,109,105,114,118,124,124,121,117,125,128,113,99,92,97,94,96,86,81,100,104,101,85,76,89,97,90,75,57,60,70,74,79,95,96,94,106,112,123,126,123,125,116,118,136,142,141,132,116,119,117,115,136,146,145,137,124,119,122,131,135,131,129,136,139,151,156,136,111,104,105,110,116,128,137,131,115,122,139,137,144,137,138,124,95,99,116,137,153,158,165,156,131,138,140,130,120,109,105,101,102,105,118,124,106,97,92,79,79,81,78,91,98,99,92,95,105,103,113,114,107,101,88,94,104,101,96,91,102,116,115,110,107,93,91,92,81,79,87,100,103,101,98,90,87,85,84,89,95,100,89,94,87,81,91,96,99,100,111,108,90,89,87,84,84,76,83,80,81,78,67,59,57,63,61,66,70,63,65,63,70,68,61,59,48,57,59,75,103,119,147,160,173,179,152,117,105,117,141,182,196,185,193,194,190,181,161,151,150,146,111,66,27,7,10,12,15,26,41,51,49,52,58,53,55,55,50,57,54,52,51,53,52,50,54,48,47,53,46,50,47,46,48,46,49,45,48,45,44,48,39,45,41,48,48,40,47,38,43,41,39,39,37,43,44,42,36,33,34,31,35,34,34,34,28,39,37,34,31,31,33,36,34,35,30,32,36,36,36,30,29,30,31,29,33,29,25,29,32,32,31,30,27,28,31,27,29,31,23,30,31,29,29,27,31,22,24,29,24,26,27,27,24,25,27,28,23,22,26,23,23,24,26,24,24,24,25,24,19,25,22,20,23,22,21,21,25,24,22,22,21,24,21,19,25,24,23,20,22,22,18,24,23,23,22,27,24,24,28,26,27,24,33,25,24,27,22,30,27,24,32,29,37,39,29,29,27,32,30,27,31,30,24,30,29,22,24,27,29,26,27,31,30,28,30,25,23,25,26,26,40,63,68,77,77,95,110,169,226,150,53,38,41,48,44,42,48,47,49,46,48,43,36,40,38,44,33,22,17,22,24,21,31,37,45,39,32,33,29,35,40,29,34,34,29,33,30,29,27,27,25,21,26,19,21,23,18,25,23,22,25,25,20,24,24,25,41,50,63,65,79,84,72,77,86,88,87,95,92,132,177,184,174,157,155,148,147,152,145,146,145,144,152,152,160,165,160,164,161,161,163,160,161,159,156,160,160,160,152,147,151,148,152,156,160,170,168,163,145,121,96,92,119,140,162,176,169,160,147,151,154,157,159,158,155,155,162,165,162,162,158,149,149,148,141,134,142,150,158,164,163,167,165,158,162,169,166,165,166,162,160,162,159,159,155,155,162,155,152,152,159,168,175,188,195,194,190,188,190,184,180,176,169,169,156,166,113,11,2,9,10,12,11,13,12,12,14,14,13,21,21,17,19,19,21,17,17,20,20,21,24,25,21,21,27,20,18,21,24,27,29,33,49,57,61,69,66,52,35,20,17,21,17,21,16,21,25,22,26,27,29,26,22,29,29,29,27,30,36,35,37,39,42,39,42,33,34,35,29,38,28,29,25,22,24,21,23,24,20,24,23,20,18,21,23,24,25,24,24,29,29,23,25,24,24,29,26,44,64,67,137,96,162,132,144,153,153,163,155,194,139,158,149,138,143,125,118,117,111,101,88,98,105,124,141,145,147,133,129,128,122,123,120,117,108,114,122,109,101,95,93,92,96,90,92,96,97,74,78,75,84,93,91,98,101,101,104,110,116,118,104,115,117,123,131,136,123,128,119,112,116,110,118,116,117,106,97,90,88,98,95,88,85,92,105,114,134,128,112,125,127,122,114,110,111,108,98,110,123,131,123,136,131,109,96,108,118,130,119,121,125,118,104,110,113,111,96,95,93,93,93,84,90,105,87,84,84,78,84,78,90,108,116,108,96,100,100,99,105,100,93,98,84,95,92,99,103,110,110,114,116,120,110,102,109,101,94,90,95,94,97,94,88,84,83,78,89,82,82,83,86,93,91,93,95,89,91,94,83,93,80,86,83,81,78,74,81,87,81,71,71,59,60,61,61,61,64,65,66,69,59,64,66,56,54,52,44,35,61,51,108,142,175,193,184,171,138,101,94,123,125,122,137,148,169,180,191,208,249,252,252,231,180,133,87,37,8,9,11,13,21,35,43,49,56,57,58,55,52,51,51,54,52,50,49,47,52,47,49,50,48,46,46,44,48,48,44,47,45,45,43,43,42,41,42,46,42,39,39,37,41,37,44,42,36,33,37,35,33,37,35,39,37,33,33,33,33,34,31,31,32,34,35,36,34,31,35,31,30,31,31,29,31,33,29,32,32,27,28,29,33,27,29,29,27,28,29,27,31,33,23,30,29,26,24,27,25,22,26,28,25,26,27,22,28,29,25,22,24,23,26,28,23,26,23,22,22,21,22,20,20,27,24,25,25,19,24,24,21,20,17,20,25,23,24,24,19,24,22,21,19,18,23,22,22,26,24,25,29,28,27,24,26,25,28,24,23,23,27,30,29,26,39,35,27,35,33,27,29,27,29,25,22,27,27,27,27,28,27,27,24,24,30,27,23,25,29,24,25,24,36,40,45,59,68,69,68,123,125,68,46,41,39,51,75,109,98,98,112,103,90,78,81,89,90,73,48,27,26,32,30,38,37,39,37,21,23,21,19,25,24,27,25,23,22,22,19,21,22,24,19,19,24,21,20,21,29,23,23,24,22,24,25,28,30,42,55,62,66,68,78,76,69,74,95,89,83,96,113,161,184,181,168,159,162,155,152,160,158,160,158,153,159,164,166,167,163,164,161,165,163,160,160,156,155,156,155,147,143,141,143,148,154,157,156,158,161,162,158,152,121,93,88,103,147,166,171,166,152,150,153,153,152,156,158,155,156,154,154,152,150,151,146,145,139,137,141,143,151,154,149,145,145,149,155,159,159,162,161,160,157,158,156,153,152,155,160,158,157,159,164,165,171,183,194,200,199,198,191,188,184,181,172,171,164,169,113,11,2,9,10,14,10,14,13,14,14,14,15,21,21,18,21,17,21,19,19,18,18,21,20,27,23,19,21,21,21,19,23,25,27,41,51,60,63,76,77,54,32,19,22,17,21,22,19,23,19,31,33,30,33,33,37,35,39,37,35,39,40,38,37,36,31,31,26,23,19,19,27,30,25,22,21,22,26,26,22,23,21,22,22,21,23,19,21,29,21,21,30,23,25,29,23,29,31,30,33,49,63,71,79,74,65,66,62,48,44,54,67,66,64,54,39,43,60,74,90,103,97,102,106,95,96,97,90,89,83,81,63,62,84,94,105,110,118,123,130,135,121,92,84,103,112,104,101,100,108,118,111,110,124,123,109,103,107,102,95,90,76,70,77,89,90,91,90,86,94,114,115,99,89,76,75,79,78,79,81,73,78,87,83,78,76,74,78,87,94,98,97,107,104,101,106,92,86,84,78,80,86,88,90,86,91,86,83,83,78,83,71,73,76,71,77,74,69,72,72,83,81,82,87,86,89,89,88,88,94,90,93,101,101,110,111,114,110,101,101,94,97,93,89,101,97,99,99,105,108,106,109,110,107,103,106,108,105,102,108,111,104,105,101,95,89,96,97,96,103,101,101,97,88,101,97,98,102,102,102,89,89,80,73,86,83,81,75,72,78,80,84,85,79,71,68,63,64,72,71,68,61,63,70,69,68,64,61,59,59,49,41,50,68,83,90,103,131,137,128,139,159,171,130,79,74,95,114,132,140,162,228,253,253,252,252,252,252,201,155,103,60,21,6,11,12,17,19,40,45,48,53,50,53,50,49,51,55,54,57,49,46,48,46,47,48,46,44,47,54,49,45,43,44,44,43,41,42,43,40,41,39,39,39,35,43,35,32,38,32,39,32,32,37,33,35,36,37,36,29,34,28,29,35,33,36,36,32,33,29,33,35,29,32,30,29,31,36,30,31,31,29,34,31,29,25,26,29,29,30,31,24,29,28,27,28,23,27,26,26,27,25,30,24,25,24,28,28,19,26,29,20,24,29,19,27,19,25,24,19,24,21,25,22,24,24,24,22,20,21,23,23,23,19,23,23,21,19,20,23,18,24,22,19,22,21,21,24,22,25,26,20,27,23,24,27,28,25,18,27,24,26,27,27,27,27,29,28,29,31,35,30,25,29,24,29,31,26,30,25,30,26,31,26,23,30,27,25,24,27,27,27,31,38,38,32,40,39,29,27,43,49,34,36,34,33,48,106,155,141,143,151,145,132,120,134,149,150,141,91,36,27,31,29,32,28,21,24,22,23,23,19,24,20,22,28,26,21,21,23,22,22,19,23,23,19,23,22,22,26,24,20,24,31,31,39,42,47,55,52,66,72,70,84,71,70,96,89,84,93,122,164,184,177,168,167,166,165,157,162,166,162,163,162,158,162,166,165,165,163,165,162,165,160,160,162,161,160,163,158,155,155,153,157,156,165,164,160,160,157,166,165,161,153,126,102,86,105,142,162,175,172,168,162,158,154,156,162,159,155,159,154,150,149,148,155,157,155,152,155,155,158,156,149,147,151,151,157,161,161,164,163,162,160,162,156,155,157,158,166,163,165,165,167,172,175,179,187,194,194,192,189,188,184,181,174,173,165,173,114,10,2,8,10,12,10,13,12,13,14,13,13,18,21,21,19,21,17,17,19,18,19,18,19,24,21,21,21,26,21,19,23,21,29,34,50,57,63,71,66,51,30,22,22,20,20,19,25,30,30,34,38,42,43,39,39,44,38,37,32,33,28,23,23,22,26,19,22,24,19,24,27,27,26,23,24,23,23,24,24,23,25,23,24,21,20,23,17,19,24,20,18,25,27,33,34,30,43,42,36,39,36,49,50,58,57,52,50,44,48,46,59,71,73,84,93,96,97,88,118,133,104,132,113,103,94,89,66,70,83,81,81,87,90,116,120,131,137,136,131,129,132,98,87,96,124,131,109,106,130,118,108,97,96,84,74,75,84,83,64,56,57,62,77,60,53,49,56,78,55,57,91,72,59,61,85,71,77,97,89,81,94,78,72,75,82,83,83,87,95,88,79,83,86,95,105,109,105,83,80,76,71,78,86,83,80,85,91,83,76,69,67,68,81,77,89,88,84,93,96,105,98,99,97,99,101,99,101,105,113,104,104,107,106,108,106,107,103,110,106,105,106,109,114,109,103,105,105,124,120,119,117,111,107,105,108,97,109,106,116,114,115,121,118,122,121,117,120,115,112,118,108,107,99,97,100,95,101,94,93,91,82,90,87,89,81,81,83,71,81,96,99,83,76,63,62,66,73,78,66,73,73,77,71,74,69,71,69,67,66,62,55,46,46,39,38,36,34,39,73,110,152,177,130,84,66,67,68,59,71,94,154,230,252,253,253,252,252,252,252,252,220,175,128,83,46,12,9,11,12,21,33,43,45,50,50,54,50,52,52,46,46,45,46,45,47,43,44,48,55,55,42,42,42,39,44,42,38,41,39,42,39,34,38,39,39,37,37,38,37,36,38,34,35,39,35,30,31,35,38,35,33,34,36,34,31,29,34,34,25,31,30,32,33,33,36,27,32,32,34,34,27,24,29,29,26,30,29,24,23,27,23,30,32,24,29,27,30,25,26,26,25,22,26,29,20,22,24,24,26,29,25,25,23,21,24,26,20,24,21,20,29,24,22,23,22,19,24,21,21,21,23,24,16,26,22,19,24,19,19,23,22,19,19,24,19,21,19,19,24,24,27,23,27,22,28,23,29,54,35,25,23,25,26,28,37,32,32,30,36,42,26,27,33,27,27,24,28,31,26,23,28,28,26,24,24,30,28,28,25,24,29,29,38,40,39,36,36,31,23,30,30,29,33,32,39,46,81,142,136,137,142,138,134,124,126,130,153,157,111,37,14,20,19,24,20,23,27,18,24,27,21,27,19,20,24,20,22,24,23,24,25,24,24,21,21,24,20,21,26,25,22,31,36,39,48,48,48,55,65,75,68,71,78,75,88,91,81,92,122,167,184,177,170,162,160,162,165,162,164,168,168,171,166,157,160,159,161,165,160,163,163,166,160,160,163,160,162,166,164,166,167,163,168,166,167,164,163,167,165,165,165,169,164,155,137,103,88,97,131,166,180,179,173,168,163,162,160,158,159,158,151,148,152,158,158,159,164,165,158,161,166,160,158,159,159,157,157,161,162,160,162,167,162,162,162,165,162,162,171,171,168,169,172,170,176,179,186,186,184,188,181,181,176,173,170,172,162,170,116,10,2,9,10,12,11,14,12,13,14,14,14,23,20,19,19,19,20,19,18,22,18,20,18,18,23,21,24,21,25,20,22,24,24,35,44,48,56,59,63,49,29,29,24,27,27,31,31,36,36,34,42,39,34,36,32,29,29,27,23,22,24,23,20,23,23,24,23,20,23,22,26,27,25,24,24,24,22,23,24,24,25,22,21,23,18,16,17,21,21,19,19,23,29,38,37,30,38,37,39,39,31,37,49,52,49,49,52,45,44,52,63,76,90,92,105,120,109,98,87,91,93,87,105,100,91,81,71,81,85,101,102,102,96,87,91,83,87,88,74,69,84,92,82,80,83,96,107,104,108,109,98,82,68,76,80,80,86,80,85,86,92,96,90,84,76,80,80,85,83,83,79,82,94,98,106,106,114,120,121,116,113,107,95,95,100,103,111,105,107,106,97,99,93,96,104,110,113,101,97,95,92,98,97,94,100,101,104,104,108,110,99,98,98,97,107,104,107,104,100,110,104,108,108,105,103,103,112,113,114,112,107,110,112,111,105,108,107,104,111,116,119,116,109,116,116,118,120,128,131,123,120,112,116,120,113,111,107,113,122,116,117,122,120,123,117,118,111,108,115,104,99,99,102,106,97,96,93,94,92,89,103,105,97,98,95,104,110,103,96,95,90,87,76,69,71,64,67,65,67,80,77,71,67,72,65,62,69,61,57,56,55,54,52,49,41,38,34,33,30,46,80,107,110,101,89,77,60,46,43,48,70,123,159,193,225,238,253,253,253,252,252,253,253,247,211,170,122,86,48,17,8,11,11,18,36,34,41,47,44,35,42,47,39,49,46,47,48,45,50,49,50,40,43,41,41,41,38,46,39,34,33,38,39,34,36,37,41,34,37,38,36,35,31,34,32,31,33,36,29,37,31,30,33,27,32,32,32,34,32,30,35,31,32,27,33,29,33,28,26,32,24,34,25,29,29,25,27,27,26,27,33,23,22,29,30,25,25,24,23,21,25,24,24,26,23,26,27,28,23,22,25,21,19,21,29,19,24,26,21,27,16,19,21,21,20,22,23,21,24,23,22,19,22,23,22,21,26,22,19,23,20,21,19,16,21,22,21,22,19,18,23,24,30,27,30,22,50,61,25,24,24,24,23,30,27,33,32,30,34,23,30,28,28,27,34,33,26,28,28,33,32,26,25,28,27,28,29,33,37,33,27,32,37,39,42,38,37,29,24,28,35,35,35,29,41,45,68,119,125,124,126,132,129,119,101,115,141,156,119,39,14,14,14,23,24,24,22,19,26,23,21,23,24,17,21,24,18,26,22,23,23,23,24,19,24,20,25,27,19,28,29,42,44,42,52,50,56,62,69,78,64,76,90,76,87,88,90,113,151,181,173,166,156,146,145,153,163,164,167,171,169,172,167,158,162,156,163,162,160,162,159,162,160,161,162,162,163,166,167,167,165,167,168,168,168,166,170,168,166,168,167,165,166,169,166,139,104,84,91,128,159,179,181,178,173,165,164,155,153,155,151,153,157,163,162,162,161,160,160,158,160,158,157,158,153,150,153,161,160,158,158,155,155,159,163,170,168,165,169,167,168,166,164,167,169,173,177,176,175,174,170,172,166,169,168,170,166,174,115,10,0,9,10,12,11,13,12,13,14,14,14,21,22,16,19,17,17,20,19,18,16,22,20,21,24,19,21,21,23,27,23,20,25,31,36,39,43,47,49,42,31,42,30,31,37,28,36,26,32,28,24,31,24,28,23,19,23,24,22,20,24,23,19,23,22,22,21,20,21,22,24,30,28,23,29,26,19,23,24,24,23,17,23,23,17,18,21,22,17,21,18,20,29,29,31,29,27,27,31,32,31,32,32,33,35,38,39,38,36,36,37,37,40,42,40,39,45,67,37,39,39,33,65,41,40,42,40,39,47,49,53,57,78,59,46,33,38,46,35,38,34,74,35,71,71,59,69,91,84,90,89,88,83,93,92,98,96,93,96,94,109,112,105,104,106,105,102,111,100,111,105,103,99,110,111,116,110,105,117,117,112,112,101,109,112,112,104,105,109,106,107,103,99,98,97,103,113,107,119,116,118,121,115,107,107,113,118,110,110,107,115,115,116,119,112,108,105,107,112,113,115,116,111,118,117,114,119,122,123,122,125,120,124,117,114,122,116,118,110,114,111,110,116,113,122,122,116,117,115,116,116,120,114,124,124,118,116,114,117,118,117,110,107,110,107,105,112,116,114,110,110,116,111,109,107,101,102,97,97,102,99,102,98,104,110,107,108,95,89,91,85,89,86,75,79,72,79,69,67,77,71,70,73,70,69,64,63,58,52,52,55,55,53,49,51,53,57,63,48,49,63,82,85,81,83,85,79,69,62,51,48,68,121,103,125,147,178,196,218,252,252,252,252,253,253,252,252,250,195,152,122,84,44,14,9,56,12,24,36,36,40,47,46,42,44,46,46,42,45,49,46,44,44,42,42,42,38,40,41,39,39,36,39,35,40,39,38,35,31,34,42,36,35,38,25,38,35,33,32,29,37,27,27,29,26,32,29,29,33,30,33,35,28,30,35,29,30,28,28,30,27,29,29,29,27,27,25,27,24,30,29,24,25,33,26,24,23,22,26,17,22,24,24,24,26,29,26,24,27,24,20,23,26,25,20,24,24,21,24,21,19,21,19,22,21,23,27,23,24,18,19,24,19,23,23,22,21,21,24,21,18,23,18,19,22,19,24,18,19,21,21,22,20,24,28,24,31,35,21,24,25,24,28,20,29,23,30,29,21,28,27,29,30,38,34,28,28,30,34,35,24,29,26,25,31,27,34,40,41,27,22,33,38,43,42,34,36,27,23,28,32,32,31,37,36,44,53,94,105,101,107,115,113,102,97,106,130,147,111,39,15,17,16,25,24,20,24,20,19,22,25,24,21,24,26,19,23,22,24,27,23,19,23,21,20,23,24,22,29,34,39,44,42,47,51,54,57,66,72,66,67,84,89,79,83,88,108,149,164,167,165,160,148,138,139,151,162,156,160,161,162,168,163,162,164,157,159,157,154,158,159,160,157,162,163,160,164,162,159,157,159,157,159,158,158,163,160,163,160,159,162,164,164,168,169,159,144,114,85,91,119,154,177,181,177,168,164,160,157,161,156,159,162,162,165,160,162,160,155,160,160,157,160,156,156,157,154,153,152,151,150,152,153,154,156,163,160,159,160,157,159,157,156,158,163,160,167,165,163,164,159,164,163,165,164,168,161,174,116,10,1,8,10,13,11,13,13,13,13,14,13,18,17,21,18,19,19,19,17,21,20,21,23,24,24,24,24,22,25,28,29,30,29,32,34,32,33,39,34,37,33,29,34,24,21,27,24,22,21,28,26,23,22,19,25,24,25,27,24,21,23,21,21,23,22,24,19,24,21,24,23,26,28,21,23,20,20,24,20,17,18,20,17,19,17,20,18,20,18,18,21,22,31,40,49,46,48,53,59,61,59,57,54,55,52,48,43,41,43,40,45,51,52,46,42,42,42,46,51,42,41,38,41,47,37,40,45,46,48,52,53,59,69,85,81,75,83,83,87,80,79,78,74,82,79,88,85,88,103,99,98,98,100,106,105,108,110,108,108,102,105,120,128,123,117,116,108,111,113,118,120,110,116,122,125,119,113,100,98,106,112,112,107,117,117,114,111,108,114,111,105,105,110,112,111,113,118,117,118,127,117,127,120,117,125,119,120,114,116,114,114,118,123,120,122,112,113,121,118,125,118,120,122,120,121,120,122,124,125,127,122,123,124,126,127,125,125,117,111,111,111,110,107,112,117,117,111,107,108,111,113,116,123,129,123,125,124,115,112,100,103,112,115,119,119,118,117,118,119,118,114,117,114,106,100,104,98,94,92,99,100,87,94,100,98,87,74,86,92,89,79,74,73,74,87,88,83,75,68,75,90,83,73,74,81,77,77,66,56,59,53,57,57,55,60,69,81,90,72,69,77,72,67,60,58,72,93,97,99,96,114,132,111,107,101,88,104,111,126,155,187,218,239,253,253,252,252,252,252,252,252,244,213,184,153,114,90,37,6,10,11,23,33,38,42,39,44,44,42,45,51,47,45,40,40,39,35,37,39,33,36,39,37,41,42,46,41,31,37,35,33,35,33,36,36,33,29,28,32,36,33,29,34,28,27,28,31,33,24,35,33,22,33,31,30,31,28,31,33,32,21,29,29,26,26,22,29,23,23,34,22,20,26,19,29,24,23,24,17,29,27,24,26,25,25,21,24,22,29,22,24,25,21,28,25,24,24,22,19,21,23,22,20,24,19,22,23,19,24,19,20,22,21,22,20,20,19,23,21,16,23,19,23,24,20,21,21,21,22,22,21,19,20,23,19,22,24,27,29,26,23,23,26,24,25,25,26,20,30,32,25,27,33,39,28,23,31,34,32,37,31,24,31,28,29,31,29,32,29,24,26,33,39,41,37,36,37,27,21,27,32,33,34,35,35,39,48,63,85,90,95,98,89,93,85,104,107,127,107,36,24,17,17,24,22,23,20,23,21,22,25,18,28,22,23,24,17,26,21,21,23,24,22,20,27,24,29,25,33,42,35,47,44,49,60,56,59,64,71,73,72,91,81,76,92,103,149,171,163,167,163,163,163,152,153,159,154,147,147,155,157,163,162,160,166,159,160,159,155,157,157,154,153,163,162,160,165,160,157,160,151,148,148,144,144,147,148,150,155,152,151,153,158,160,166,171,171,155,122,93,83,116,145,169,175,172,171,162,165,162,159,162,164,159,160,162,159,160,162,161,163,165,169,165,164,167,161,155,153,158,155,152,155,155,154,155,154,150,148,144,147,150,151,153,152,153,158,157,159,160,158,162,163,165,165,167,162,170,113,12,2,8,10,13,11,13,12,14,15,13,14,22,20,17,23,18,19,19,22,20,21,24,20,31,28,28,34,33,33,34,36,37,38,36,35,35,31,32,29,24,25,24,20,22,19,17,21,22,24,24,20,25,22,23,29,23,23,27,22,24,23,22,20,19,23,19,21,21,18,24,21,22,24,18,22,19,17,21,21,19,21,18,20,17,17,18,19,20,16,24,23,21,31,45,54,63,63,74,89,62,64,64,60,59,57,63,57,58,61,66,73,66,53,55,46,42,37,53,52,49,46,53,59,57,52,57,57,62,70,54,47,47,72,97,109,103,108,113,104,114,122,134,130,129,107,113,115,107,111,107,108,107,110,109,112,118,114,117,113,107,113,115,118,117,113,115,108,107,107,112,117,118,117,124,131,127,116,116,113,117,124,124,124,121,122,128,122,118,118,116,110,115,115,123,126,120,123,113,117,117,118,119,118,129,125,132,124,122,124,116,122,118,113,128,126,126,121,119,126,122,124,123,119,126,130,128,127,125,123,122,118,114,125,125,122,125,122,122,117,119,121,117,120,119,121,122,123,122,121,123,123,127,113,119,120,117,122,119,114,113,120,118,122,121,118,119,121,122,117,110,111,108,116,108,109,105,103,92,99,98,89,88,86,89,93,84,84,87,86,92,85,92,94,82,85,93,77,72,66,76,73,66,66,70,76,77,75,68,62,60,59,63,63,63,63,70,62,79,70,74,81,84,71,59,59,71,81,81,87,98,104,117,93,111,105,107,105,88,71,76,89,111,137,168,194,211,235,252,252,253,253,252,252,252,252,199,228,154,120,108,64,25,8,9,17,24,28,34,41,40,46,50,43,36,40,40,38,38,39,39,36,39,41,34,36,37,42,37,34,35,34,39,33,34,34,33,35,30,33,29,30,31,30,33,24,29,29,24,30,25,28,30,25,31,34,30,29,32,29,25,26,24,27,24,24,27,21,32,27,29,22,21,19,24,26,26,25,27,28,23,27,26,27,21,26,26,19,24,21,21,25,27,20,22,22,19,20,23,21,25,19,23,26,18,20,22,22,21,19,19,22,21,22,23,19,20,21,22,19,21,21,22,20,17,17,21,21,18,19,21,22,19,24,23,18,22,18,24,24,25,27,24,29,26,23,26,24,27,34,30,25,27,25,28,27,32,32,31,42,42,34,29,28,29,29,32,32,28,29,25,32,35,39,44,36,38,35,25,24,31,32,39,32,34,38,42,43,67,104,112,114,108,97,95,95,109,110,142,126,50,23,12,16,21,20,20,19,24,24,18,23,24,20,21,26,21,20,20,21,24,20,21,25,21,24,30,29,31,33,33,39,51,46,57,58,59,62,74,75,75,81,83,88,93,107,144,171,174,162,159,163,169,165,163,165,163,161,150,153,159,158,159,159,162,167,166,168,162,159,156,160,162,157,163,164,164,163,158,159,164,158,157,156,145,148,151,146,152,156,156,155,148,153,162,167,177,179,174,160,137,103,87,104,135,165,177,179,168,162,165,161,165,161,159,160,159,168,169,167,171,172,169,173,170,171,171,163,160,156,161,166,157,158,155,155,163,158,154,150,149,148,152,155,152,151,153,161,159,158,162,160,160,162,164,160,163,153,169,115,10,1,9,10,12,10,14,12,12,14,14,14,21,20,22,21,23,20,24,27,22,29,29,27,33,35,33,34,36,33,34,30,29,27,21,27,26,21,23,22,26,20,17,21,18,19,18,18,18,22,21,26,24,22,23,23,23,17,23,22,21,24,19,19,18,18,21,18,17,17,24,20,19,21,17,17,17,17,17,17,19,19,19,18,16,17,17,18,19,19,19,18,18,29,39,53,57,50,45,42,49,53,56,55,52,54,58,57,63,67,70,69,62,57,59,54,50,50,49,50,51,49,51,59,61,62,64,66,71,65,57,51,51,53,66,81,90,98,86,77,83,105,116,121,122,125,132,120,117,117,114,118,116,117,112,107,116,113,106,111,113,112,117,117,111,112,113,110,112,110,117,122,114,120,117,117,120,117,108,115,128,137,138,122,116,115,122,127,123,116,115,116,124,124,126,124,120,119,118,112,110,109,116,112,110,110,111,125,109,111,117,118,123,118,110,112,112,115,118,123,131,127,129,127,131,132,134,128,117,124,124,115,121,121,125,124,119,122,122,122,125,127,129,129,136,134,128,135,126,124,130,122,115,106,111,118,119,122,125,129,134,127,116,116,115,118,124,127,127,127,125,124,120,122,126,121,119,110,117,109,103,89,74,76,81,93,89,86,91,81,83,85,93,105,90,83,76,70,69,67,64,60,60,64,72,74,71,74,72,71,71,68,68,65,58,53,54,59,66,65,74,77,76,74,61,46,54,64,57,57,59,78,80,62,84,112,138,149,134,115,89,66,53,53,64,83,108,136,162,184,205,220,237,246,253,253,253,253,220,248,250,211,177,149,147,114,55,30,12,9,14,21,37,38,35,32,36,33,37,42,34,34,36,38,32,33,39,41,33,34,39,34,35,32,32,35,32,32,32,31,29,37,32,27,29,29,25,27,28,27,24,27,29,29,29,29,30,24,23,28,32,27,27,24,24,31,26,27,26,22,25,25,29,27,26,23,27,29,25,23,28,23,19,26,23,24,25,24,23,25,24,23,21,23,28,21,19,21,25,26,23,22,22,19,20,21,20,21,21,22,23,21,23,20,19,24,19,19,20,19,23,20,18,22,22,22,21,19,18,18,21,20,19,21,19,20,19,23,22,16,19,24,22,24,27,24,27,24,37,35,29,36,32,26,30,31,31,31,42,53,36,33,29,32,27,27,31,27,27,26,32,29,35,39,41,41,39,42,27,24,32,34,38,34,37,39,42,43,77,137,145,135,135,118,113,109,127,134,167,150,63,27,11,14,21,22,24,18,24,25,19,23,24,23,19,19,25,21,23,24,22,21,21,23,27,27,22,27,34,35,37,43,50,54,56,56,63,68,78,79,78,87,96,92,105,152,173,179,169,157,160,160,165,169,162,162,160,164,168,165,165,160,159,164,167,170,166,167,163,160,155,161,165,163,171,165,160,155,149,148,159,162,166,163,160,160,156,153,158,165,164,159,157,160,161,161,165,172,173,176,170,136,104,84,101,132,163,182,174,169,166,166,167,160,158,159,162,164,165,169,167,166,164,161,159,162,164,158,154,159,166,165,161,159,156,162,170,163,163,163,158,160,164,165,163,165,168,174,175,170,165,165,161,160,162,154,154,148,163,114,11,1,9,10,12,11,13,11,13,14,14,14,24,22,25,27,33,26,32,33,27,34,33,34,33,31,33,27,26,24,27,23,19,22,19,19,22,19,23,22,20,18,23,23,18,21,18,17,20,24,27,20,25,24,19,22,22,24,19,18,20,19,18,17,20,20,17,21,19,19,20,22,21,16,18,18,19,18,18,17,20,21,19,21,18,20,18,18,19,18,19,18,19,33,37,51,54,45,48,57,56,57,54,54,63,57,74,65,66,66,89,89,89,85,76,63,76,66,59,63,66,72,70,83,89,86,87,88,103,99,90,82,68,72,79,77,79,86,85,86,71,95,76,88,112,108,128,124,125,124,127,126,125,123,119,120,119,118,119,115,122,121,128,131,126,118,115,121,125,123,125,125,118,122,119,115,117,122,122,118,126,127,129,120,118,124,121,123,126,120,122,127,125,129,128,121,118,122,120,123,124,120,118,118,115,106,108,107,122,127,121,127,126,111,107,110,113,110,115,125,126,130,122,115,123,126,128,121,118,129,126,118,117,121,123,124,124,120,125,124,123,129,125,134,134,128,112,109,114,109,111,110,120,123,123,121,118,116,120,117,121,128,120,124,120,130,127,128,135,129,131,132,131,134,141,138,134,138,136,129,120,102,92,93,96,96,90,82,77,72,63,63,87,95,94,96,78,83,89,83,82,79,84,73,92,93,88,76,68,73,70,78,79,64,59,54,60,57,57,60,57,61,61,54,48,49,42,46,54,52,51,66,71,64,92,120,139,156,148,156,154,143,127,108,90,91,84,89,101,127,118,130,150,165,189,215,236,210,217,253,253,253,252,252,252,241,221,194,153,115,82,112,26,9,16,19,24,36,33,30,35,37,33,33,32,34,36,36,39,35,34,27,34,32,33,32,30,34,33,33,28,28,25,27,30,30,27,24,26,27,30,26,24,24,21,29,23,25,27,23,25,27,29,24,28,26,24,24,26,27,22,25,28,24,30,25,25,25,20,24,22,22,27,24,23,27,28,24,24,24,24,23,26,22,24,20,21,27,20,19,20,17,22,24,21,19,19,22,21,22,20,21,21,18,22,20,21,21,17,19,21,22,21,21,21,23,21,21,21,19,24,19,21,19,20,19,18,21,20,21,19,23,24,24,25,25,23,36,33,24,30,29,29,29,35,27,30,31,34,35,29,35,32,33,35,31,26,27,30,33,31,24,30,41,42,45,41,40,27,23,29,40,40,32,40,36,38,41,63,113,116,123,116,98,98,103,112,109,146,130,55,27,15,16,24,21,20,22,24,21,17,24,20,21,21,20,25,23,22,19,20,25,23,23,29,29,27,25,31,39,40,45,56,54,56,62,64,70,80,80,86,108,89,105,149,174,180,172,171,164,159,165,172,162,156,157,156,164,165,162,163,155,158,165,155,160,163,161,156,155,152,156,160,160,166,162,160,149,136,141,159,162,165,166,161,165,160,157,165,169,163,159,148,146,145,141,148,151,157,163,172,163,137,103,84,98,127,163,177,177,173,170,173,163,162,161,158,162,155,158,156,151,154,151,151,155,156,154,158,161,167,166,159,162,162,164,167,163,164,160,163,163,168,170,168,171,175,180,177,172,170,162,159,160,162,156,157,148,163,113,12,1,8,10,13,11,12,12,12,14,13,13,30,32,37,33,35,36,31,31,30,28,25,23,25,27,22,18,19,20,17,18,22,21,18,22,19,20,21,20,23,19,21,21,18,19,20,19,22,24,24,22,18,22,22,21,18,21,19,16,21,18,16,17,18,17,17,21,21,26,24,19,23,19,19,19,17,24,21,21,19,21,21,19,20,20,19,15,22,19,19,20,21,30,36,49,45,46,54,61,71,67,76,83,79,79,89,109,112,105,106,107,109,104,89,68,62,51,46,51,54,66,75,95,106,103,104,102,118,124,120,99,93,91,93,92,87,106,107,96,87,87,77,89,100,111,120,121,130,118,125,129,121,132,131,126,126,129,133,128,130,127,125,128,127,131,127,126,129,121,125,134,128,125,128,129,131,134,125,120,117,117,121,120,126,125,121,120,114,110,117,119,125,125,124,122,119,124,132,134,134,134,134,130,125,116,115,131,131,131,133,125,128,125,120,128,123,120,118,116,125,120,122,115,112,125,133,132,136,143,127,116,118,124,123,122,131,129,127,124,130,130,130,129,125,127,113,120,118,118,125,121,132,133,131,129,124,124,125,125,130,127,127,133,130,128,118,112,107,113,122,127,133,136,139,137,138,130,128,129,131,118,111,110,108,104,87,84,95,93,101,89,90,98,100,110,105,103,109,101,97,95,85,92,91,87,92,83,75,77,75,74,74,73,61,59,59,61,67,57,53,52,50,51,46,46,48,47,54,51,49,67,81,80,95,106,126,146,143,163,185,186,182,173,164,147,130,122,113,92,83,75,69,72,90,130,157,148,184,234,241,251,239,242,252,252,252,252,252,249,238,226,198,147,113,78,49,19,6,15,22,27,36,31,31,36,33,34,36,34,31,29,33,30,32,30,29,38,26,30,29,28,32,27,29,27,26,25,26,24,26,24,27,23,25,25,22,28,25,29,27,24,25,24,22,24,24,29,24,25,27,24,27,22,26,24,22,25,24,24,24,26,24,22,28,25,22,22,20,23,27,25,23,23,19,21,24,23,21,18,22,23,20,21,20,22,25,24,21,20,22,21,16,23,23,16,22,20,17,26,17,21,24,20,21,21,23,20,23,18,20,22,17,20,24,20,18,22,23,19,19,19,19,19,22,21,25,33,25,27,32,25,29,33,29,29,31,33,31,29,31,38,37,48,44,27,31,31,34,33,29,28,34,43,42,35,40,39,27,24,26,41,44,35,42,30,34,46,48,61,67,67,61,54,52,58,54,56,74,73,55,26,15,17,18,25,21,19,24,26,22,22,23,21,25,21,20,22,21,22,24,22,23,24,28,28,28,26,26,39,43,52,54,53,65,65,65,74,83,85,96,98,106,147,173,177,166,159,165,163,162,160,162,156,152,153,149,153,155,154,153,155,157,155,148,151,157,155,153,157,151,158,158,154,163,160,157,155,153,156,165,163,165,161,163,171,163,165,169,167,164,153,147,141,139,137,139,143,147,161,166,169,163,139,113,89,89,125,157,173,173,169,171,165,160,163,160,159,155,155,152,152,155,154,150,155,155,162,167,164,168,165,161,162,158,161,163,153,156,153,156,164,165,164,163,168,169,170,168,165,163,157,156,161,164,155,163,158,167,114,11,2,8,10,13,11,13,12,13,13,13,13,36,29,30,29,28,27,24,22,16,19,23,19,23,19,20,22,21,27,20,18,21,21,20,17,25,24,21,22,24,24,17,23,20,22,19,18,24,19,19,17,20,20,17,18,18,18,18,19,17,19,19,16,19,17,17,20,19,19,22,20,17,19,16,18,18,19,22,17,19,20,21,18,17,22,18,17,18,19,20,18,21,27,27,33,31,33,42,42,39,48,47,57,57,60,62,59,57,64,69,71,70,67,61,49,48,38,38,44,39,39,44,55,64,65,67,71,66,82,63,61,50,69,68,49,45,50,64,55,48,43,47,51,63,89,89,81,75,80,88,98,96,101,104,110,109,117,128,128,128,120,118,111,119,128,128,129,121,123,129,133,129,124,125,124,119,118,116,117,113,108,117,115,115,122,125,126,128,122,126,135,128,127,124,125,128,133,138,134,136,129,124,128,123,127,131,134,139,130,129,125,126,124,128,138,136,134,129,127,125,133,129,124,128,130,134,134,137,126,122,128,127,131,131,129,131,124,122,123,124,129,131,128,128,137,134,132,138,136,142,139,134,129,125,131,131,125,124,132,133,129,133,132,128,124,114,117,122,117,123,127,127,126,123,118,110,110,110,110,108,113,113,111,103,108,108,110,116,115,117,106,106,110,107,104,103,107,99,88,81,83,83,92,92,75,75,75,74,65,57,66,67,67,71,66,68,69,73,60,61,57,54,53,48,50,51,60,62,53,55,73,85,81,108,87,81,85,105,100,102,102,98,95,89,100,109,110,113,106,97,89,93,52,51,66,64,57,107,131,138,159,169,179,194,218,234,245,252,252,252,252,253,253,242,215,201,171,136,114,117,55,22,15,14,25,28,25,29,26,31,27,29,34,29,29,29,26,27,31,31,28,29,27,29,30,29,28,24,27,24,28,27,26,27,29,27,32,25,27,24,24,29,21,26,20,28,25,25,27,24,24,20,26,24,21,28,24,20,27,24,21,24,24,19,25,24,23,28,23,20,24,24,22,23,23,17,23,20,22,22,19,24,23,21,19,23,23,20,18,18,20,20,22,19,19,19,19,22,20,23,21,18,22,23,21,21,22,22,15,24,27,19,23,22,19,22,21,19,19,22,24,20,17,20,19,22,23,22,25,26,28,26,28,29,34,34,30,36,36,35,39,40,49,39,28,29,30,43,42,27,31,33,39,44,43,40,39,28,26,33,39,43,37,42,40,41,41,42,51,46,51,41,33,41,36,38,38,48,49,41,27,17,18,18,21,24,21,21,22,26,24,19,18,21,22,21,26,22,19,23,19,24,22,23,27,26,29,35,35,40,56,55,57,70,67,68,86,86,86,97,113,150,174,175,163,156,158,164,158,155,156,160,153,157,156,151,150,147,151,157,153,155,161,156,159,160,158,162,165,162,163,157,153,162,155,154,161,160,163,168,162,160,157,157,162,154,156,159,162,160,160,152,153,158,151,153,156,163,160,164,165,166,162,153,128,84,83,112,140,156,165,165,159,159,160,162,164,164,162,157,160,163,159,155,159,162,168,169,160,160,158,158,160,159,158,159,156,153,155,158,160,163,159,159,160,163,165,161,162,160,158,160,160,163,162,167,161,171,115,11,2,10,10,12,11,14,12,13,14,14,13,19,25,22,17,25,20,16,17,17,20,22,26,21,21,22,21,23,20,21,20,22,22,21,22,19,21,20,23,24,19,19,18,21,23,16,17,17,16,19,17,20,21,15,23,22,16,21,18,19,18,17,19,16,21,19,17,18,20,18,17,19,17,18,18,18,18,17,21,20,20,19,16,17,17,20,19,16,21,21,18,19,21,20,19,21,19,19,21,22,28,26,32,35,39,35,33,30,31,30,34,35,36,36,33,44,40,42,44,36,38,38,34,41,39,45,46,42,43,39,48,51,53,50,49,46,47,43,37,37,38,43,46,54,60,59,62,66,54,59,74,79,87,93,101,108,114,125,124,124,121,116,113,112,128,127,122,128,129,128,127,125,120,125,116,104,105,111,122,122,113,116,120,119,124,131,130,129,128,134,134,135,132,130,132,130,131,127,122,121,126,126,125,128,129,126,129,129,134,137,125,128,128,131,141,146,140,137,136,134,132,132,133,135,139,133,123,128,130,122,122,131,138,134,133,135,133,128,124,127,129,136,134,132,142,141,143,139,137,139,134,135,131,128,130,123,120,121,128,135,130,129,131,125,128,130,135,140,142,141,133,129,125,117,109,110,107,105,111,113,110,116,113,108,117,112,119,114,99,110,106,110,107,89,89,89,92,86,74,79,73,74,88,88,75,81,84,72,73,63,63,67,65,69,74,74,73,67,59,70,69,64,66,62,58,51,54,53,51,60,65,80,70,69,69,59,65,51,47,48,43,57,60,63,71,80,88,103,119,130,136,132,121,91,87,52,25,50,38,36,59,64,81,99,129,151,163,186,207,220,241,252,252,252,252,252,252,251,247,223,200,186,157,127,95,59,32,25,15,26,28,26,28,24,31,24,23,24,25,26,27,29,30,28,25,30,26,27,26,29,29,27,29,32,32,23,28,25,25,25,23,26,23,25,28,23,24,25,27,23,20,29,23,21,23,23,26,24,24,23,22,25,24,18,22,24,22,21,23,25,24,23,19,20,21,22,21,22,24,24,21,22,22,16,20,18,21,23,18,21,21,20,19,22,18,23,19,18,23,23,21,22,22,19,21,18,21,24,20,20,23,18,19,19,22,25,20,16,20,21,19,21,17,22,21,18,19,22,24,23,27,23,26,32,29,36,46,45,38,39,35,34,32,31,35,27,29,52,38,19,32,38,39,45,42,44,36,29,28,34,47,42,39,41,35,40,41,46,50,45,46,34,29,32,35,33,39,40,39,40,30,22,17,19,18,22,22,18,22,24,21,20,21,21,19,24,22,17,23,19,19,25,25,24,30,27,27,36,35,46,56,59,64,74,77,86,95,91,92,115,159,181,179,172,162,163,162,155,150,153,156,158,159,163,163,163,164,165,162,160,160,168,168,167,165,164,163,166,165,155,163,157,161,168,164,169,171,165,160,162,159,160,152,152,155,150,152,151,155,159,160,161,164,167,164,165,163,166,166,165,163,162,169,173,156,117,83,77,97,131,158,168,168,166,166,165,170,168,168,167,166,165,166,161,162,162,163,166,162,162,159,160,165,160,164,166,164,166,165,163,161,162,162,161,166,165,164,165,162,162,162,159,158,163,162,167,157,166,115,11,0,9,10,12,11,13,11,12,13,14,13,19,21,20,16,17,17,18,19,22,16,21,23,19,21,23,20,15,23,21,22,21,16,19,19,18,17,19,19,17,17,19,18,17,19,18,17,19,17,16,20,19,17,17,16,19,19,18,17,16,17,18,18,20,19,17,15,21,19,18,21,16,19,16,19,21,19,22,22,23,20,19,18,19,19,18,21,19,18,19,22,19,17,21,18,19,22,19,22,20,19,21,21,26,24,27,24,23,29,29,31,32,36,44,43,49,54,52,57,52,50,46,39,43,42,56,52,47,47,45,52,61,66,70,69,61,59,50,54,55,52,65,66,82,75,78,84,85,92,77,106,99,128,128,123,130,130,128,131,128,132,128,125,125,124,128,130,128,131,126,124,129,129,130,130,129,126,127,133,134,125,127,130,131,130,128,124,124,125,128,130,131,129,131,132,120,118,114,111,126,128,127,130,124,125,126,128,135,131,128,126,126,128,131,133,137,137,136,131,126,129,123,124,130,133,130,126,132,131,131,139,134,133,135,141,141,136,133,138,139,135,135,132,133,141,146,139,136,132,132,135,140,138,135,133,135,139,134,142,141,144,133,131,134,133,130,133,139,136,132,137,122,123,123,125,115,114,125,127,123,120,119,122,118,120,111,107,101,93,107,113,110,104,90,82,80,89,84,82,80,77,79,90,84,81,92,77,85,87,75,68,69,74,66,65,73,72,74,68,70,78,74,75,65,69,61,55,56,59,60,56,64,56,60,56,61,52,50,44,44,40,71,49,52,74,71,67,99,103,127,128,127,143,146,141,86,57,87,86,90,68,58,55,48,53,69,87,99,122,147,168,197,215,226,232,236,245,246,248,251,251,252,249,236,218,205,200,155,123,117,87,66,43,27,24,26,25,24,28,28,25,29,24,27,24,28,28,24,28,28,30,27,33,26,26,30,24,29,27,29,24,27,21,26,29,21,23,21,24,26,25,24,25,26,26,24,23,23,24,21,21,23,19,23,28,21,29,20,22,21,19,24,20,21,20,21,29,24,20,21,19,19,23,17,23,21,18,24,19,18,17,24,26,19,23,22,17,18,21,18,18,21,21,25,22,21,23,21,22,24,20,24,21,19,22,19,22,17,21,19,18,20,20,21,17,24,22,15,21,22,19,23,26,28,30,44,50,36,35,39,32,36,40,33,33,26,29,35,26,27,34,34,43,45,40,49,43,24,29,41,47,39,43,41,37,45,42,45,46,43,42,39,35,33,34,33,36,39,45,42,26,25,19,20,21,21,24,16,20,19,21,22,18,23,19,22,20,23,26,21,21,22,25,24,24,30,28,36,40,46,52,53,69,79,84,100,91,89,123,167,183,182,174,164,166,161,159,160,152,154,159,162,158,162,163,171,171,163,165,163,160,159,159,155,155,160,160,157,154,156,160,159,163,168,165,169,168,158,159,165,165,164,157,162,167,161,156,153,155,152,151,157,162,165,160,155,157,158,163,165,159,159,160,176,172,147,124,95,77,90,129,159,175,179,174,171,164,164,166,167,167,167,168,166,163,163,166,164,166,165,160,163,163,165,162,164,169,169,165,162,165,168,167,167,171,171,169,167,169,170,165,161,156,164,161,166,159,166,114,12,2,8,10,13,11,14,13,14,14,12,14,22,23,19,20,18,21,21,18,19,18,22,19,20,21,19,22,19,21,18,17,20,17,17,18,19,19,20,17,16,17,17,19,17,19,19,18,17,16,17,16,17,16,19,21,16,18,19,17,20,18,17,17,18,19,17,19,19,17,19,18,16,18,18,22,19,21,23,22,20,20,20,16,18,17,18,19,17,19,18,19,22,26,28,24,23,28,26,24,27,23,23,30,32,37,43,42,45,47,50,52,50,49,54,55,61,65,71,81,74,67,65,70,72,73,71,62,60,55,50,55,50,47,57,69,74,65,63,68,80,88,91,93,96,92,87,89,84,83,89,101,112,117,122,124,127,128,128,126,127,136,136,132,125,126,122,123,127,125,128,130,130,134,147,142,140,139,137,141,143,137,131,130,132,132,131,128,129,125,125,125,127,127,127,121,121,123,120,127,132,136,121,120,131,128,136,135,128,130,122,123,131,128,132,129,122,118,119,126,120,123,127,131,131,135,141,135,144,146,143,144,141,141,141,139,141,141,143,150,145,144,146,148,154,153,144,134,136,139,146,142,143,149,148,154,153,153,153,153,155,155,152,155,157,155,148,140,143,147,147,147,141,139,139,136,128,141,153,148,145,133,126,130,132,134,127,124,116,121,128,121,120,107,97,92,84,91,85,74,78,81,85,77,80,67,59,66,72,77,69,79,83,76,85,79,78,89,84,76,67,54,64,67,70,68,53,62,55,54,49,51,55,54,48,48,51,48,46,48,50,44,49,43,45,46,48,51,56,86,105,110,112,124,149,159,117,117,158,165,167,162,130,101,71,69,76,64,58,47,48,67,89,113,136,152,162,183,196,206,224,231,235,236,235,250,251,237,229,227,234,227,215,197,183,179,129,87,66,57,36,20,30,25,26,21,20,29,27,26,25,22,22,27,26,28,29,29,24,24,28,22,24,21,24,27,30,23,21,26,25,29,27,21,23,23,21,22,25,22,23,25,21,28,22,24,23,17,24,18,19,21,21,22,21,21,24,20,18,21,24,17,19,19,19,23,21,21,21,23,19,21,19,19,22,20,23,20,22,24,16,21,24,19,20,22,19,23,21,19,18,19,18,20,21,19,21,18,24,18,19,21,21,20,17,22,23,23,19,18,18,20,23,22,24,25,34,36,32,33,34,39,38,37,32,29,29,31,31,25,34,34,30,45,47,44,45,41,33,26,40,46,44,42,39,44,44,42,43,46,42,39,45,35,35,34,29,34,38,44,36,24,23,23,21,22,23,23,19,18,21,21,21,22,22,22,23,24,23,23,23,22,21,20,29,28,28,29,30,41,43,53,62,78,84,84,90,82,105,155,173,171,165,162,167,160,160,166,167,166,164,160,155,149,155,158,163,162,156,152,153,152,151,149,150,147,148,156,157,161,161,159,155,153,155,156,160,159,154,158,160,162,162,159,163,167,165,160,161,160,151,150,157,162,165,155,147,147,152,154,158,155,150,159,168,166,162,160,135,102,86,93,125,153,174,174,164,160,148,149,155,156,160,160,160,160,158,161,160,164,171,166,164,166,164,166,163,160,160,155,158,158,163,165,159,166,168,169,174,171,171,166,164,161,166,163,163,159,165,113,12,2,8,10,13,10,12,12,13,13,14,15,23,20,18,19,18,17,20,20,18,19,19,17,19,18,20,19,17,21,16,18,17,18,20,17,17,17,17,18,18,18,16,16,17,16,17,17,19,17,17,20,16,18,20,17,18,19,19,19,18,18,18,17,19,19,17,19,18,22,17,19,18,20,24,17,21,22,19,19,21,20,21,17,16,18,15,18,21,18,22,18,23,33,29,32,37,33,32,32,34,33,35,34,35,43,39,48,49,39,56,56,49,45,51,57,58,49,55,66,77,83,55,57,73,65,59,59,72,66,65,59,52,47,48,46,50,47,40,55,66,68,73,76,87,89,84,77,63,55,80,92,106,107,114,103,98,104,107,108,111,118,119,127,133,131,130,115,117,124,116,117,116,108,110,117,131,127,118,120,131,137,141,141,132,129,133,135,130,119,121,128,132,130,126,118,117,135,139,138,140,138,137,139,141,142,137,134,139,143,139,143,145,142,133,118,114,125,132,133,131,137,140,145,146,145,141,137,140,135,139,142,144,147,141,145,146,145,146,151,155,151,149,151,148,136,134,139,139,135,136,136,138,132,141,136,134,133,140,142,145,142,143,146,161,174,160,160,142,164,145,144,142,142,141,136,145,146,145,137,130,122,119,117,112,115,112,108,113,117,120,109,106,100,85,100,83,95,83,73,79,79,63,61,57,59,67,67,65,71,67,83,99,84,81,84,75,83,72,78,64,72,81,68,53,57,57,57,54,53,54,57,51,55,59,54,58,57,56,55,50,52,49,54,65,58,61,58,60,83,81,78,94,97,110,129,99,118,142,146,162,162,134,116,113,113,120,105,95,69,50,38,72,46,43,52,66,92,110,121,141,149,158,174,194,205,210,217,214,224,232,239,242,247,251,234,218,202,195,193,171,149,139,134,101,52,25,24,30,28,28,23,43,26,24,24,30,23,27,29,23,23,23,23,24,26,23,25,24,24,28,25,23,21,24,23,21,21,24,27,23,27,21,23,23,21,23,22,22,22,24,24,21,21,21,19,21,19,19,21,22,19,20,20,15,24,19,21,28,17,22,19,21,21,19,21,18,23,19,22,19,17,22,21,17,19,25,18,23,25,22,21,18,19,22,17,22,19,21,21,18,21,20,24,21,21,22,24,20,22,22,19,24,19,19,26,26,27,28,34,36,34,40,38,34,33,29,33,29,33,34,32,40,45,49,46,45,37,27,29,44,46,48,44,44,43,42,46,39,48,47,39,40,35,36,36,28,34,33,33,35,25,19,17,21,19,17,20,20,19,22,23,21,24,20,21,19,19,20,22,23,21,21,24,25,27,32,30,33,39,44,47,67,81,87,89,87,120,145,155,159,150,148,156,154,155,162,161,162,164,155,153,156,145,155,158,164,157,151,151,150,146,147,151,160,149,148,151,156,159,160,160,155,153,149,145,147,151,152,152,153,152,152,151,155,155,155,158,162,163,160,162,166,170,163,154,150,156,155,154,149,149,154,153,160,160,156,160,159,141,117,92,83,112,144,159,168,160,146,139,145,148,150,151,155,158,152,153,155,163,159,161,168,160,161,162,158,158,156,155,157,160,160,158,155,158,161,167,171,170,167,165,165,161,167,164,165,156,168,116,11,2,9,10,12,11,13,11,12,14,14,14,20,20,20,21,18,17,17,19,19,16,17,18,19,18,16,17,17,18,17,18,17,18,18,16,17,18,17,16,17,16,17,20,18,17,16,18,17,16,16,16,17,16,18,18,21,19,17,17,17,17,17,21,17,19,20,16,17,18,19,18,19,18,19,19,17,21,19,20,18,18,19,19,19,17,17,20,20,17,20,20,19,25,21,26,25,25,29,30,33,24,24,28,29,31,32,28,30,29,30,29,27,22,30,33,30,34,30,28,27,31,37,36,38,37,44,54,61,57,49,49,50,44,44,38,32,32,31,25,37,47,50,61,70,81,82,82,81,77,82,92,104,95,91,89,83,87,94,104,101,103,110,122,128,128,132,133,129,136,134,129,116,95,97,108,123,113,104,113,117,118,124,127,126,126,126,136,128,122,133,131,136,137,132,133,137,139,141,142,147,148,146,153,151,141,139,144,149,154,157,157,157,148,144,138,135,139,129,134,134,128,124,122,130,128,127,121,120,129,127,121,118,104,102,111,126,129,126,129,129,129,114,108,114,125,136,137,135,132,128,113,109,115,110,111,107,105,103,100,105,108,110,113,125,127,125,129,132,134,132,131,125,113,120,134,130,122,116,107,107,107,108,107,102,102,96,94,100,110,104,93,101,94,90,110,115,103,86,77,90,86,77,64,79,90,84,77,68,68,88,104,96,86,73,63,64,65,64,90,92,83,75,59,63,57,60,60,53,59,57,57,55,58,61,60,65,70,67,66,58,62,70,84,91,68,71,78,72,76,73,68,75,65,77,91,69,82,77,80,102,89,86,99,116,148,147,135,137,131,118,105,88,65,57,43,42,53,43,34,32,39,57,79,97,113,136,148,157,160,174,192,198,202,205,214,208,209,221,229,229,237,241,228,200,178,162,147,126,108,87,89,84,29,23,34,24,27,22,25,23,27,27,21,23,24,28,25,22,21,25,25,21,25,22,22,26,24,21,25,26,22,24,23,21,17,24,22,21,24,24,23,22,16,18,21,21,22,19,21,20,21,21,19,25,22,21,21,16,20,21,22,17,19,21,16,22,21,18,20,22,23,16,19,21,16,19,22,17,25,22,17,22,19,22,19,22,18,22,20,20,21,20,22,21,25,18,22,22,19,21,21,21,20,22,21,21,23,28,35,33,37,39,38,40,34,36,35,29,37,43,40,41,54,49,46,44,39,27,31,48,46,42,45,45,43,42,39,44,51,47,45,36,38,39,35,32,33,36,34,34,29,19,20,17,20,22,19,24,20,19,22,23,20,21,23,19,25,17,22,26,20,21,23,26,23,27,33,31,46,48,48,66,77,95,113,141,164,165,165,162,159,162,161,155,154,154,151,151,159,162,157,159,159,160,157,165,172,166,161,156,148,146,156,160,145,147,155,148,148,151,154,160,160,160,154,153,159,155,159,155,150,147,151,158,155,150,150,155,165,166,165,168,161,161,160,162,166,163,158,153,154,155,155,157,156,155,160,162,169,154,123,97,83,105,131,158,171,156,149,153,155,157,155,159,160,158,160,154,155,154,152,158,156,156,158,157,157,157,155,157,161,162,160,155,157,156,162,169,169,170,164,163,160,162,162,165,164,169,113,11,2,9,10,12,11,14,12,12,14,13,13,20,16,17,20,18,16,18,17,16,18,17,16,17,16,17,17,17,17,18,19,17,16,17,16,16,16,17,17,17,17,16,17,17,17,16,17,17,16,18,17,16,22,18,18,20,16,18,19,16,17,17,18,18,16,17,17,18,17,17,18,20,16,21,20,17,22,17,21,17,20,21,18,19,17,20,17,21,20,18,21,19,19,24,27,32,30,28,31,30,28,26,29,26,26,28,33,26,19,25,27,26,26,23,24,24,26,28,24,30,33,33,39,37,48,60,61,64,63,55,53,52,52,46,45,42,41,38,44,44,49,57,53,54,60,73,65,71,100,99,76,80,63,54,75,89,102,114,118,117,117,117,124,113,110,112,120,138,146,139,136,139,132,128,127,120,116,118,118,117,108,105,108,120,113,129,130,128,137,137,136,131,130,130,123,130,131,125,130,123,121,111,103,106,110,113,117,108,109,114,107,110,116,125,129,132,136,123,122,122,122,118,120,131,122,135,128,122,112,97,76,71,73,87,109,123,130,130,117,107,106,109,119,122,130,133,130,134,128,123,123,121,116,118,122,116,108,77,86,99,100,102,106,105,94,84,88,91,83,91,97,99,104,118,120,114,110,104,113,112,114,122,115,99,98,89,96,102,107,102,100,116,112,109,117,104,99,96,88,115,101,95,82,83,94,92,101,101,116,98,101,86,73,55,48,60,74,82,96,81,62,59,61,57,62,55,56,59,53,52,57,50,52,55,54,54,50,53,53,54,51,53,63,67,65,70,63,55,55,55,60,61,53,46,53,51,47,53,39,42,35,61,60,94,115,111,104,129,143,117,132,117,109,131,110,101,91,74,62,53,60,63,63,31,69,46,53,67,73,87,111,123,130,145,153,165,174,183,189,203,212,200,212,210,205,210,211,209,214,218,202,144,107,110,97,88,61,39,40,45,32,27,26,21,23,23,22,19,21,22,20,22,26,25,23,22,22,23,21,23,22,21,21,22,26,23,22,25,20,20,26,17,23,21,22,26,15,23,22,18,23,20,19,24,16,20,21,19,19,21,20,18,18,19,16,17,24,21,19,20,19,21,18,21,23,18,21,18,19,21,22,21,16,20,19,22,19,21,24,15,21,20,19,19,19,22,21,21,18,21,19,24,22,19,21,19,22,27,26,27,37,35,36,41,34,32,37,34,44,39,30,45,49,50,53,45,36,24,26,45,46,48,46,42,42,43,42,43,55,46,43,40,35,35,35,37,32,35,37,35,24,23,16,19,22,18,20,18,21,20,21,21,19,21,19,22,23,22,25,22,22,24,24,26,23,25,30,37,43,43,48,74,85,112,165,158,170,176,167,175,172,168,167,166,163,163,159,158,165,159,165,163,162,164,158,166,164,166,160,161,160,152,161,159,151,159,157,146,144,153,159,161,160,166,168,163,171,168,167,166,157,160,162,165,160,156,151,156,162,156,155,152,151,154,154,160,160,160,159,153,157,158,155,157,162,159,160,169,174,173,155,127,98,83,98,133,160,169,167,162,160,161,157,157,157,158,160,149,149,145,146,150,146,153,154,152,155,160,159,159,159,163,159,155,159,162,168,171,170,168,165,160,155,156,155,165,157,168,115,11,1,8,10,12,11,13,12,14,13,13,13,18,17,17,17,16,17,16,17,17,17,17,16,17,16,17,16,17,17,17,16,16,16,17,18,16,17,18,16,18,18,16,19,16,17,17,16,17,16,19,19,16,18,20,18,17,18,19,17,18,18,17,16,19,20,17,19,19,17,17,17,20,20,17,19,17,17,18,18,20,19,18,18,17,18,18,18,22,18,20,20,19,24,23,29,30,33,33,30,32,26,28,22,24,26,27,26,25,27,29,29,36,32,34,31,30,33,26,34,39,39,44,42,40,45,51,61,81,97,87,62,50,49,51,49,45,44,40,35,39,38,37,40,37,40,38,44,53,50,51,50,52,63,75,87,103,118,137,141,134,136,137,132,123,122,125,128,127,131,127,133,146,150,149,137,134,130,134,141,133,126,117,117,118,119,128,134,137,141,143,131,123,119,110,108,115,123,122,118,117,98,81,78,84,91,93,87,71,66,71,60,68,88,104,113,120,128,115,128,133,118,118,125,137,142,143,137,137,132,113,101,115,129,145,153,153,148,132,124,130,139,139,136,132,131,130,126,122,130,142,142,143,142,141,150,143,131,125,130,137,127,125,133,138,129,119,117,110,112,120,118,117,122,139,146,138,125,119,120,127,128,125,122,116,116,103,103,104,104,101,105,112,107,107,103,85,81,87,95,110,104,106,96,83,95,100,123,128,111,100,74,65,63,59,62,63,76,91,87,60,59,62,53,58,57,61,60,51,55,57,56,54,54,51,48,53,53,54,55,54,66,61,62,63,52,56,51,48,51,53,50,53,49,46,46,44,49,44,41,44,41,50,62,65,79,69,64,73,88,95,96,121,129,128,116,117,120,110,104,98,109,98,78,67,59,62,45,46,37,27,34,39,50,61,71,86,99,112,126,128,142,151,160,173,184,197,197,203,214,199,200,191,179,190,186,179,178,183,173,132,100,91,83,70,54,36,31,40,40,26,23,24,22,21,21,21,18,24,20,21,22,19,24,26,20,22,20,18,23,20,20,24,21,19,19,20,22,16,21,23,22,22,19,25,17,23,25,19,24,19,20,20,19,19,21,19,18,23,21,19,22,16,27,21,16,24,18,22,19,19,21,20,23,22,21,17,22,22,18,19,22,19,23,22,22,21,19,19,22,19,21,21,18,27,20,15,21,18,27,25,27,34,39,39,39,35,32,37,35,30,34,43,50,57,55,53,37,23,30,45,45,43,45,42,46,46,45,46,45,42,41,33,33,32,32,37,28,36,32,32,22,18,23,17,22,17,20,21,19,22,19,23,21,20,22,19,22,22,20,24,21,22,26,26,25,23,34,39,41,39,53,68,75,122,152,157,167,168,176,175,169,165,163,168,166,159,159,159,157,155,147,150,160,160,160,159,154,151,154,165,165,165,170,166,163,166,165,157,162,169,166,162,160,159,159,161,167,166,168,168,162,165,165,163,163,158,159,159,160,151,150,154,147,152,152,149,155,153,153,156,157,159,156,156,161,162,163,163,170,172,170,158,134,108,83,99,131,152,170,171,168,162,153,152,152,154,159,147,143,140,145,151,148,153,152,151,156,158,159,157,161,162,158,159,163,162,167,170,167,170,163,163,159,159,158,160,158,165,112,13,2,9,10,13,11,13,12,13,13,13,13,17,17,18,17,18,18,17,20,16,17,18,16,17,17,17,16,19,18,18,17,16,17,20,19,16,19,16,19,17,16,17,18,17,19,21,17,17,16,19,20,17,21,17,17,19,20,19,16,19,19,16,19,19,16,17,17,18,18,18,18,16,17,17,19,19,18,19,18,17,18,19,16,18,19,17,17,19,24,19,21,23,25,27,22,21,30,23,23,23,21,22,20,20,21,19,23,25,23,27,21,28,28,22,26,25,23,24,23,24,31,34,34,35,35,39,37,44,49,53,58,61,56,52,43,46,36,42,41,32,37,40,42,42,47,47,40,45,47,47,46,47,59,81,100,106,119,134,139,143,142,139,130,136,136,130,127,125,127,127,139,147,141,141,146,148,146,147,143,143,143,143,141,128,131,140,137,135,145,136,131,120,118,124,118,125,123,125,119,131,112,109,116,139,135,130,121,114,103,113,112,116,123,119,109,111,119,113,107,106,121,123,126,139,145,149,148,139,133,143,152,155,162,161,151,139,132,135,131,125,123,127,143,139,139,137,125,131,132,130,135,147,147,153,149,149,154,145,148,137,135,140,143,144,144,139,137,141,142,145,145,139,144,153,147,139,133,127,135,133,134,116,111,116,122,119,119,117,114,106,105,109,102,104,95,80,81,81,97,79,97,106,106,103,106,105,101,104,81,81,66,70,71,71,75,71,66,63,56,61,65,58,54,56,63,65,59,51,53,59,59,57,57,57,59,58,59,71,71,59,83,75,71,59,49,56,56,53,59,52,57,56,51,53,49,48,49,53,48,51,53,53,61,55,58,50,50,55,75,76,76,87,92,47,60,87,84,99,102,107,123,122,92,107,116,103,92,89,74,67,63,63,57,55,46,41,40,42,46,64,60,70,95,115,130,125,143,153,158,171,178,174,170,185,189,195,199,200,190,184,184,187,180,136,168,171,175,154,100,72,76,89,44,43,36,39,47,37,27,25,24,23,17,15,17,23,20,19,19,19,19,16,21,20,20,18,15,21,22,21,18,24,23,19,19,22,23,20,19,20,17,23,22,17,20,20,21,19,19,23,20,22,21,17,23,19,21,19,17,22,18,17,19,21,19,19,21,19,22,17,24,18,19,19,19,26,18,21,20,24,21,21,24,18,21,21,20,22,22,23,27,27,33,37,37,36,25,31,32,25,36,46,49,49,54,51,40,31,40,56,50,49,46,45,44,47,49,44,35,33,36,34,29,34,31,33,29,29,34,29,23,23,20,19,21,18,23,20,22,20,22,19,17,20,22,21,19,25,21,24,27,25,24,25,24,31,34,36,36,42,53,66,73,83,105,133,158,171,178,159,160,168,165,165,162,154,150,146,144,146,147,155,157,152,159,160,155,156,153,162,163,164,166,165,163,169,170,169,177,177,169,161,163,155,147,149,161,160,166,170,161,160,157,155,155,153,160,163,161,159,163,159,155,158,152,153,153,156,157,153,156,155,155,156,159,159,157,156,158,163,161,164,162,143,113,91,98,124,152,171,174,170,156,152,157,155,157,152,148,144,147,152,152,158,154,151,152,154,158,157,157,160,157,159,162,161,164,165,163,165,164,165,164,163,162,165,151,160,113,12,1,9,9,12,11,14,12,12,14,13,13,19,17,17,18,16,17,18,16,17,17,17,17,16,16,16,16,17,17,18,17,17,19,17,17,16,18,19,17,18,16,17,21,17,17,18,17,19,19,16,20,17,18,20,20,21,15,17,17,19,17,17,19,17,19,16,17,19,17,20,17,19,19,18,19,20,22,18,17,22,18,20,17,19,19,16,22,19,21,19,19,23,25,26,31,31,36,30,26,30,26,30,24,24,23,18,26,21,24,22,22,29,24,28,26,24,34,27,30,34,26,28,29,34,37,46,46,45,45,50,53,50,54,53,55,58,58,55,57,51,46,48,51,59,57,50,55,54,60,56,47,44,63,87,98,110,107,101,99,101,105,115,121,121,118,111,113,118,119,120,123,121,117,116,116,120,121,132,141,134,136,141,147,139,129,139,136,133,134,127,116,120,134,141,139,127,117,116,124,128,128,139,153,156,148,144,151,152,147,164,170,169,163,140,115,114,120,119,124,130,132,133,137,136,143,149,145,141,134,141,144,151,148,139,139,136,133,131,121,122,136,134,142,140,132,133,125,127,132,142,144,143,143,133,135,141,137,141,141,140,136,134,138,139,142,137,141,140,149,154,143,137,134,135,127,126,134,135,131,139,131,119,123,118,125,129,133,130,125,121,117,108,93,101,99,107,110,104,104,100,100,113,120,115,116,107,99,80,68,71,78,84,72,83,96,76,69,66,59,55,55,63,66,65,55,55,59,56,62,54,52,57,59,55,60,61,53,56,60,59,59,55,52,52,50,47,55,54,52,50,48,52,50,55,50,53,54,52,53,52,62,54,48,51,48,44,51,72,76,74,76,76,77,69,79,95,97,94,101,104,113,101,93,99,110,116,114,123,122,137,136,125,108,108,103,84,77,55,49,27,29,34,30,28,36,51,54,72,83,89,110,124,138,154,160,154,149,157,165,177,187,185,175,181,202,208,205,187,177,174,174,163,148,162,176,169,127,89,81,72,58,47,43,49,67,53,27,29,25,27,23,19,22,18,21,18,23,20,15,17,21,19,16,21,22,18,19,19,18,24,19,21,18,17,21,21,26,18,21,19,22,23,18,21,17,17,22,17,19,19,15,22,20,17,22,19,19,16,19,23,21,17,22,21,18,19,19,24,22,20,21,17,20,20,20,24,21,18,21,24,20,27,27,34,38,33,31,29,32,34,41,43,45,48,44,51,48,48,68,69,57,54,45,47,45,46,48,44,41,30,33,28,27,30,30,36,29,32,31,32,22,19,19,19,21,18,20,16,24,22,20,22,20,22,23,21,22,22,22,25,26,21,22,27,26,28,35,36,37,46,69,81,66,73,84,110,146,163,160,145,153,160,162,164,159,156,153,153,153,158,157,157,155,146,160,167,160,157,153,158,158,159,158,150,155,160,164,167,172,167,160,165,165,158,151,154,162,164,167,164,160,165,157,157,164,163,168,160,159,160,161,166,159,163,165,163,163,163,159,151,157,160,158,156,156,157,158,152,152,152,154,154,162,168,144,120,94,87,112,143,165,174,165,160,157,159,160,159,161,151,156,155,154,153,149,151,155,156,156,155,156,157,156,160,160,160,160,157,156,155,155,162,165,171,167,164,154,159,112,12,1,9,9,12,10,14,12,12,14,13,13,15,16,16,16,16,16,17,17,17,17,17,17,16,16,18,16,17,16,17,18,15,18,17,17,18,16,16,17,18,18,17,17,17,17,16,23,19,18,21,21,20,22,22,17,17,17,17,17,17,17,17,16,19,18,20,18,17,17,17,20,17,19,19,18,22,19,21,20,17,21,18,16,17,17,20,20,17,19,17,23,24,29,25,34,35,37,39,35,36,34,34,28,29,30,29,28,26,26,33,32,31,30,34,36,38,41,40,43,35,32,34,38,49,45,49,50,48,55,53,50,46,51,51,65,83,82,70,70,63,60,57,50,76,65,63,67,76,70,75,67,70,91,101,122,124,118,107,91,96,94,96,95,106,108,110,107,105,111,111,115,107,96,94,99,121,106,118,133,131,127,131,132,124,128,127,131,128,135,122,126,128,135,144,136,142,137,136,141,141,133,130,138,134,131,135,142,141,146,153,156,158,143,126,114,136,149,147,145,157,162,159,146,133,132,137,137,131,137,144,139,137,142,141,139,139,138,139,140,148,147,146,152,131,132,131,127,122,132,136,132,131,124,115,123,129,134,131,147,140,141,139,141,141,139,131,137,141,137,137,137,134,129,128,132,134,130,129,130,135,142,136,129,137,129,126,120,117,110,111,113,110,100,100,98,105,111,110,111,108,113,117,119,120,105,98,88,79,76,85,79,83,85,86,69,69,65,69,62,64,63,57,62,63,61,60,57,62,67,59,64,63,61,63,63,62,59,53,54,61,53,59,53,49,49,53,61,52,50,56,51,48,49,51,59,57,55,57,47,50,58,46,51,44,46,51,54,67,68,72,75,107,100,71,96,98,97,99,94,99,83,75,77,83,98,100,97,107,116,128,131,101,114,116,119,92,94,103,89,71,67,54,41,43,36,47,47,25,21,25,29,30,42,84,70,77,77,98,106,125,140,143,146,149,164,166,175,176,177,177,173,162,185,208,189,170,146,141,152,148,137,144,153,175,163,111,85,90,98,84,58,57,65,39,25,29,57,32,28,23,24,22,18,19,21,21,19,18,22,19,20,19,15,21,18,19,19,15,18,18,19,22,20,21,21,16,17,19,22,21,21,21,17,17,20,17,18,17,17,22,18,19,18,20,21,17,22,19,17,19,19,27,23,17,24,19,22,26,20,22,20,30,26,30,37,34,34,31,29,34,34,40,48,47,44,47,51,48,65,73,66,61,46,46,42,44,50,44,41,33,30,35,31,32,36,29,38,34,28,32,22,20,18,17,17,20,21,20,21,19,22,18,20,18,25,26,17,27,23,23,27,22,26,30,29,33,37,44,56,66,81,92,85,78,80,94,125,131,137,147,159,157,151,150,147,156,161,170,165,168,166,162,157,153,163,161,158,143,134,140,151,146,155,150,146,150,153,149,150,156,159,161,160,155,165,173,170,166,163,158,159,161,160,165,169,168,166,163,161,162,162,160,164,169,170,171,169,168,164,155,156,161,161,162,162,159,160,157,157,162,156,162,163,166,163,150,126,89,87,103,134,162,171,174,169,166,166,163,165,162,160,162,156,157,152,154,159,162,160,154,156,156,158,159,162,163,158,151,149,148,146,153,159,163,163,166,151,159,113,12,1,8,10,13,11,12,12,13,13,14,13,17,17,17,17,17,18,17,17,18,17,16,19,18,17,18,19,18,18,17,16,17,16,16,17,17,19,16,17,18,18,18,19,19,19,17,23,22,21,21,19,24,19,20,17,17,19,17,17,19,19,19,18,16,16,17,17,16,20,18,17,19,18,19,19,20,18,19,23,19,17,18,18,18,18,19,19,17,19,18,18,21,26,23,25,26,26,26,24,31,31,34,40,41,39,34,35,33,36,38,37,49,47,49,49,46,52,49,56,50,45,48,46,56,57,51,51,53,57,65,63,57,55,53,71,86,88,79,79,83,75,74,76,92,103,106,116,124,111,97,103,113,123,126,133,141,139,129,127,128,119,108,105,114,126,125,124,110,106,115,118,118,115,120,133,129,120,120,125,123,111,106,105,106,109,116,113,111,118,118,120,119,114,104,107,112,119,128,139,138,134,131,118,105,104,112,114,116,108,108,106,103,97,99,110,129,134,130,137,135,139,136,138,130,123,129,134,137,136,134,130,129,129,141,136,133,134,139,138,136,146,132,132,124,118,119,117,118,120,129,130,125,116,114,117,124,123,123,130,131,132,134,131,139,138,139,140,129,132,134,130,128,124,122,116,114,117,115,111,114,119,128,133,129,117,100,98,95,100,106,114,118,111,109,98,100,97,87,95,114,122,117,114,98,95,81,73,83,85,80,73,76,82,78,71,71,71,71,75,77,75,74,64,62,64,63,61,63,72,67,63,65,63,63,63,65,57,56,58,61,61,60,61,53,54,53,53,60,56,53,54,53,57,61,61,61,54,59,49,50,55,42,49,50,51,54,52,57,54,56,61,61,69,61,50,45,51,53,46,51,51,52,55,52,62,69,59,59,66,77,70,63,77,91,94,90,101,113,119,110,103,95,93,76,59,67,66,62,46,41,42,37,35,33,34,35,36,41,33,30,39,59,70,89,100,105,119,121,120,128,137,135,139,141,139,136,131,137,152,139,150,168,150,142,144,133,139,145,154,153,139,155,130,100,96,95,105,93,87,86,81,60,55,59,46,39,37,31,27,25,24,27,23,20,17,16,21,18,19,17,17,21,21,19,20,21,19,16,19,19,19,22,19,17,18,19,16,18,16,17,22,19,24,21,20,20,22,21,19,21,19,19,20,24,23,22,22,26,23,26,25,25,29,31,36,34,40,28,29,34,34,43,47,42,45,54,47,36,46,59,63,60,54,49,44,48,50,46,42,36,29,35,31,29,35,29,35,31,33,30,18,22,19,19,23,21,24,21,21,21,17,24,22,20,23,18,22,25,20,25,30,27,30,37,42,53,54,57,73,76,86,82,77,82,70,84,97,110,135,147,161,150,142,139,137,157,170,176,169,164,162,154,158,160,162,157,152,153,148,151,150,154,162,153,151,154,148,139,146,155,158,159,157,153,152,157,155,155,151,148,155,159,162,167,168,162,165,167,164,164,160,161,157,159,163,160,163,162,159,151,153,158,157,162,166,168,169,165,163,166,168,163,164,170,166,165,156,133,103,92,98,127,156,173,179,172,167,169,171,160,161,158,163,160,152,159,160,162,156,153,159,158,159,159,159,161,157,156,153,151,151,153,160,164,158,159,153,159,111,14,0,9,10,13,11,13,12,13,14,14,13,19,18,16,17,20,18,19,18,17,17,18,18,19,19,18,19,20,17,16,17,19,16,16,17,19,18,16,19,17,19,21,17,21,24,20,20,21,21,23,17,18,19,20,21,20,17,17,18,16,19,17,17,18,17,18,17,17,17,18,21,17,18,20,17,19,18,19,18,19,19,18,20,15,19,19,17,17,17,17,22,30,30,38,40,34,31,26,31,42,49,53,55,51,44,43,37,38,43,44,50,61,64,57,59,61,54,54,52,45,36,38,42,38,36,42,44,41,47,50,53,52,47,43,50,51,51,58,53,44,41,41,46,62,57,54,57,87,112,94,128,117,115,99,90,90,112,117,116,123,114,106,102,105,105,115,111,108,110,105,119,125,122,124,130,131,131,119,121,119,110,107,107,112,112,120,103,92,100,117,109,104,118,105,103,104,119,122,132,139,131,122,109,107,104,103,105,104,109,113,109,113,107,110,117,128,112,106,105,103,104,110,108,108,112,121,128,132,131,116,116,125,131,132,127,125,123,121,118,122,116,112,121,124,126,118,123,127,132,139,140,139,133,122,126,134,128,126,125,128,126,126,126,128,131,132,141,139,128,119,113,107,100,105,115,105,111,108,99,97,104,118,120,116,121,116,105,117,115,116,109,108,106,104,97,110,101,99,102,101,100,95,103,89,96,93,85,95,101,89,70,69,70,75,83,87,83,68,60,61,64,60,52,52,53,60,58,64,61,49,54,57,55,62,55,56,58,49,57,56,55,53,45,54,51,51,54,51,55,54,51,57,54,56,57,55,63,52,45,51,51,54,44,49,53,51,54,51,53,53,51,53,47,44,49,48,48,48,43,39,46,42,47,47,51,57,50,56,59,61,69,53,59,60,75,73,78,85,93,92,84,84,98,82,68,110,78,74,99,87,76,69,64,63,51,45,45,38,36,39,38,39,39,41,42,39,42,36,39,45,49,63,62,73,85,93,96,102,112,112,123,124,110,113,115,134,138,123,137,142,133,142,137,127,135,139,133,145,141,145,112,136,149,139,120,111,93,84,84,70,71,67,53,47,41,38,39,34,31,29,33,29,40,46,24,35,18,24,22,19,21,17,21,17,16,19,21,19,18,18,20,20,22,20,17,20,22,24,19,21,21,22,22,19,26,19,22,26,22,27,29,28,29,29,29,36,39,42,36,33,31,41,47,42,49,49,45,30,38,48,56,60,57,57,50,54,51,52,51,32,33,35,30,34,33,32,35,31,31,35,24,18,18,17,17,22,20,21,21,18,22,20,25,22,24,25,27,28,28,39,39,40,45,52,56,63,68,74,71,75,78,74,76,72,69,79,85,93,110,123,132,129,128,135,147,156,159,160,158,157,158,151,155,155,151,148,159,157,158,166,161,164,172,167,166,173,159,154,170,168,166,162,158,150,137,137,139,151,150,148,157,160,155,157,159,159,157,155,158,163,158,154,150,156,159,152,154,152,150,148,151,150,152,157,158,164,166,160,159,164,163,161,165,168,165,168,172,155,142,115,97,106,122,153,171,175,174,168,165,157,153,158,158,162,159,159,164,162,159,156,155,153,154,155,155,160,163,160,159,161,161,163,161,164,158,158,146,157,113,12,1,9,10,12,10,13,12,12,14,13,13,17,17,18,18,16,17,19,23,16,18,19,18,19,20,16,18,20,17,19,17,18,17,18,17,17,18,17,19,19,16,19,20,19,23,16,21,21,21,25,20,20,17,19,19,16,17,17,19,16,18,22,18,17,18,16,17,17,17,18,17,18,18,17,20,19,18,17,17,19,20,18,18,20,17,19,20,19,19,20,19,33,34,33,40,39,37,36,43,49,57,55,56,43,40,42,29,30,29,24,30,32,33,32,27,29,26,29,29,28,26,21,26,28,30,34,38,46,41,37,48,44,45,44,46,39,40,39,29,34,33,30,37,31,34,39,39,43,60,77,93,91,79,77,66,69,91,106,108,109,107,102,98,101,108,108,112,112,120,124,117,116,117,122,127,120,119,120,115,119,117,122,116,116,117,126,130,122,122,120,119,118,131,136,132,125,123,118,119,121,122,126,118,116,117,121,120,122,121,130,130,133,129,125,131,130,125,125,126,122,122,103,107,107,106,117,122,127,128,125,125,133,134,136,130,128,133,128,118,110,108,113,125,125,125,125,130,136,139,136,135,137,137,138,137,145,142,139,137,135,132,133,128,129,117,116,119,113,117,110,107,114,118,122,123,120,113,119,112,104,117,116,113,123,120,117,119,116,122,117,96,93,98,96,95,107,109,101,95,85,78,74,96,107,108,106,101,110,107,90,79,73,67,76,74,76,71,55,53,50,52,55,47,53,53,53,57,52,51,55,55,56,48,53,54,48,56,56,57,55,52,53,51,53,54,48,51,55,53,53,54,50,53,51,51,57,55,50,43,54,48,46,50,42,49,49,48,49,47,50,48,53,57,55,58,58,57,58,56,58,53,54,48,49,50,54,50,49,65,74,75,57,55,69,63,59,57,61,56,72,68,69,91,74,62,66,71,65,51,59,61,78,100,113,107,102,92,84,80,69,59,48,42,39,42,42,39,39,36,36,39,40,47,45,45,50,44,44,61,44,63,72,78,92,84,104,100,99,113,116,114,123,127,136,130,126,141,126,129,126,124,124,130,127,128,131,122,121,120,128,135,137,132,129,119,113,117,112,110,92,91,91,74,87,76,64,66,57,49,40,42,43,39,36,29,29,27,29,23,16,25,19,20,19,17,19,19,21,17,20,24,23,19,19,17,23,21,21,26,24,26,26,28,28,27,33,40,37,34,30,26,40,43,47,52,53,47,33,40,51,54,55,56,63,59,57,55,46,45,40,39,35,31,34,27,32,37,29,34,35,24,19,17,20,19,19,24,21,27,25,27,32,29,33,37,41,43,41,45,50,53,55,60,59,56,65,61,65,63,64,68,70,83,80,71,77,77,83,89,101,107,109,142,162,160,157,144,138,144,153,159,153,151,151,142,135,134,141,150,152,151,152,158,155,158,167,166,163,160,160,165,166,160,149,141,144,154,161,158,156,162,153,149,154,152,156,151,148,153,157,152,152,151,154,160,150,152,155,152,149,154,156,151,148,146,151,152,151,154,158,156,154,156,156,156,158,165,165,155,143,124,104,97,114,145,162,173,172,161,152,143,147,155,159,164,162,160,160,158,159,162,161,159,160,158,162,162,161,165,161,165,168,164,165,158,158,149,159,111,12,1,9,10,13,12,13,12,13,14,14,14,16,16,18,17,17,17,18,18,17,16,17,17,17,17,18,17,16,18,17,17,19,19,17,16,17,17,18,20,19,18,18,18,18,21,23,19,21,23,23,24,20,18,17,16,20,21,16,18,17,19,19,15,19,18,16,18,17,20,18,16,16,18,17,20,20,16,18,16,19,19,19,22,17,18,20,16,19,17,19,29,30,38,42,45,43,43,48,51,57,59,55,48,44,42,46,46,36,36,33,32,29,31,27,26,31,26,27,26,27,28,31,37,37,37,42,41,45,47,36,37,42,46,38,37,34,35,41,35,35,36,36,33,30,36,38,42,48,48,57,68,78,81,87,92,90,106,113,117,108,106,110,104,114,114,110,121,116,116,122,126,122,126,128,135,115,132,125,125,128,123,118,118,113,115,122,127,124,117,120,125,126,128,128,141,132,124,115,108,109,118,109,111,116,118,118,119,120,114,110,116,123,119,124,119,114,122,119,131,131,128,123,116,120,112,130,141,142,130,132,128,130,125,133,135,138,140,144,129,123,130,131,133,127,128,127,128,130,120,119,127,137,154,152,144,144,142,141,140,132,124,127,125,122,114,110,114,124,131,133,136,134,137,138,127,123,131,129,128,127,115,114,123,121,118,111,94,93,97,94,92,100,107,97,100,98,84,75,76,79,80,78,95,95,102,102,97,97,105,100,90,101,80,77,57,57,64,66,70,63,60,53,56,58,55,48,55,49,55,57,53,59,52,56,55,54,63,54,54,57,53,53,53,54,54,55,57,49,56,56,54,54,51,56,53,47,50,52,48,53,46,49,49,51,47,46,53,44,52,59,46,50,56,56,59,56,55,58,59,61,71,63,54,44,48,51,48,57,56,57,60,56,71,67,54,57,63,54,61,58,57,51,66,50,49,43,42,53,50,53,64,73,92,102,98,103,96,106,113,76,99,90,86,83,79,74,69,53,55,51,42,52,48,53,45,37,44,46,47,39,45,47,45,66,55,50,51,56,58,60,66,80,85,90,88,89,103,93,107,107,93,97,108,105,101,118,107,114,122,132,131,131,131,137,120,133,151,156,148,112,118,132,100,116,139,103,141,107,139,123,119,126,123,96,91,100,90,96,74,53,57,57,49,38,31,54,44,46,25,22,26,27,20,18,26,20,21,22,22,19,18,25,24,24,26,28,33,33,29,27,21,29,40,43,48,56,51,27,38,55,57,57,54,56,57,64,53,50,46,31,34,35,33,29,25,33,29,26,35,36,25,21,26,27,27,31,36,38,38,39,42,43,45,51,45,52,53,50,53,51,53,51,56,57,49,51,49,53,59,65,74,77,82,76,74,71,71,78,90,102,106,122,158,172,172,155,133,129,135,145,153,155,158,159,149,139,141,144,156,145,153,143,144,153,152,151,150,147,142,141,151,156,154,151,154,159,157,167,162,160,163,152,152,153,155,158,157,158,155,156,154,153,149,154,159,152,160,165,163,164,165,164,157,154,147,146,152,151,151,157,156,155,157,153,152,154,158,151,151,147,140,128,94,84,104,133,157,164,165,156,146,148,153,163,165,162,161,160,163,160,162,162,159,159,158,160,160,155,157,160,162,166,164,162,158,163,153,162,113,12,1,8,10,13,11,12,12,13,14,13,13,17,15,19,19,16,17,16,17,17,19,18,18,20,17,17,17,17,18,16,17,19,17,16,18,18,19,18,20,17,19,19,19,21,19,22,24,22,22,18,21,21,18,18,17,17,16,18,20,17,15,19,17,18,19,16,18,17,17,17,16,19,19,16,19,20,20,19,17,20,22,18,21,17,20,20,19,21,15,22,24,27,27,29,34,39,36,31,37,36,40,44,41,31,29,34,39,36,35,34,32,29,27,29,21,27,27,28,27,24,34,29,27,31,32,30,29,28,32,27,23,23,24,28,21,30,30,30,34,33,29,34,32,31,37,36,40,40,53,59,59,63,78,92,95,110,117,119,117,111,117,117,112,115,112,114,109,103,111,113,123,122,119,115,102,106,105,109,110,111,110,114,108,107,113,111,115,111,113,113,110,117,122,114,120,120,123,119,110,112,117,127,126,121,114,111,112,113,111,109,107,105,106,103,97,98,94,105,114,115,120,113,123,121,116,116,117,126,127,122,119,113,101,103,103,102,124,127,122,123,127,132,134,133,123,121,119,116,117,118,124,141,149,146,130,127,136,137,129,120,118,123,120,125,120,128,141,139,145,136,128,123,114,118,125,128,125,125,134,128,125,119,118,118,104,111,110,105,103,98,103,112,110,103,100,92,84,72,67,83,89,82,81,74,78,98,86,82,97,100,97,100,92,82,74,80,86,93,88,77,73,66,63,67,63,57,58,55,65,66,59,62,53,58,63,57,55,53,55,51,52,56,53,55,52,53,54,56,57,59,58,50,55,55,48,55,54,52,55,55,55,53,52,55,52,51,54,56,49,51,46,48,50,44,50,50,50,50,50,49,54,56,47,46,47,53,49,49,50,43,46,44,51,55,45,46,46,48,39,49,49,47,50,46,56,46,46,52,69,63,59,72,64,66,60,60,59,56,66,69,67,69,75,81,95,104,99,98,79,76,78,80,89,80,77,73,61,55,59,45,54,48,42,50,37,48,41,46,48,37,41,41,47,46,46,53,52,50,56,55,61,58,66,61,74,93,82,91,102,107,101,108,112,103,106,123,125,126,132,114,125,120,108,128,127,128,131,141,152,145,135,141,151,151,149,145,149,161,142,130,141,133,131,117,116,104,87,89,83,90,77,52,51,42,27,28,41,59,55,61,62,21,8,15,24,24,23,31,29,24,19,23,31,36,43,53,41,23,40,59,59,61,55,51,54,59,57,53,44,29,32,33,29,28,29,37,29,29,35,36,37,41,42,43,44,50,48,50,57,50,53,58,51,50,49,47,47,45,45,37,48,45,41,46,42,50,53,59,57,66,81,82,82,70,73,72,66,81,87,113,118,132,167,176,179,170,146,129,131,139,147,149,150,161,165,158,159,159,163,158,157,166,159,155,152,151,144,135,133,143,155,150,145,153,161,157,157,154,147,154,159,156,157,160,162,160,157,158,158,161,163,160,153,158,165,161,165,169,167,168,171,168,165,160,157,158,158,158,155,158,162,160,161,160,156,159,162,157,152,148,153,153,125,101,88,97,127,151,170,174,169,165,164,165,168,165,165,163,166,162,162,162,161,165,162,162,154,151,152,151,158,161,160,160,156,161,155,162,112,13,1,8,9,13,11,12,12,14,14,13,13,20,17,18,18,17,19,17,17,20,21,21,21,19,19,21,19,19,18,19,21,20,20,22,19,18,17,19,21,18,17,18,20,18,19,25,19,22,21,21,22,16,19,18,16,18,17,19,17,17,18,18,17,17,19,16,16,17,18,19,19,20,18,19,21,16,18,22,20,19,17,20,19,19,19,18,21,17,21,23,19,18,22,22,27,23,19,22,18,20,24,29,27,24,24,27,25,23,30,23,20,29,20,21,23,22,20,24,29,24,23,24,25,29,24,26,30,34,35,35,30,30,29,27,39,43,46,48,42,43,41,48,45,44,49,48,46,44,46,50,66,76,85,90,92,86,86,96,107,102,118,115,113,105,103,101,97,105,103,103,102,99,102,93,84,83,89,96,107,104,104,110,105,106,105,117,123,120,122,118,113,112,118,112,113,110,114,116,116,124,114,127,118,107,109,115,115,119,119,119,127,113,103,116,114,116,120,109,114,107,112,116,113,118,111,116,115,108,108,101,103,100,95,92,88,95,97,99,95,102,109,110,112,107,110,111,117,117,118,113,110,112,115,116,111,121,122,123,123,118,119,118,117,132,122,131,140,137,129,120,111,108,113,111,114,118,120,113,114,112,106,106,104,110,115,122,122,116,105,108,100,105,102,105,112,101,97,95,87,91,86,79,72,66,74,81,87,95,84,85,97,95,93,108,112,112,104,91,89,95,87,96,94,93,96,95,85,87,82,83,61,59,58,57,63,61,53,53,50,51,49,53,57,52,51,52,52,56,54,53,50,52,50,51,55,50,51,57,49,46,46,50,53,53,55,49,50,50,51,52,49,49,45,39,42,47,48,43,45,41,43,42,43,43,42,43,44,44,43,46,43,47,45,45,41,40,41,40,42,46,40,50,59,56,55,60,60,51,48,46,46,48,47,46,48,47,43,43,53,48,53,51,56,57,64,74,75,68,68,64,73,86,93,100,92,87,72,65,73,68,68,62,57,59,52,48,51,46,42,47,45,43,38,43,39,43,44,35,42,42,38,45,43,43,46,50,49,44,53,55,47,57,63,61,71,66,79,86,87,83,97,92,96,104,113,118,105,117,138,116,113,116,122,138,125,124,134,144,145,125,133,138,150,157,157,141,137,138,163,153,143,137,145,154,160,177,198,218,224,223,207,184,184,170,158,139,136,91,39,30,46,66,39,9,11,16,26,22,39,53,58,63,57,50,47,51,54,56,43,27,30,31,30,35,37,35,33,31,36,42,53,57,49,57,54,53,53,46,51,47,43,45,44,39,36,38,36,34,32,36,39,39,46,38,46,53,49,61,55,63,70,66,67,59,55,53,56,59,64,92,100,112,139,145,153,156,150,149,144,147,151,154,154,159,163,159,161,159,163,165,165,177,165,153,151,147,140,135,138,150,159,159,153,156,165,162,154,154,150,150,155,154,161,164,163,156,153,155,160,171,174,170,162,160,163,161,160,160,160,158,163,170,165,163,165,164,165,157,154,162,163,164,159,159,161,161,164,160,159,157,162,166,157,142,118,95,94,119,149,170,172,171,162,159,160,159,152,153,163,160,159,165,165,166,160,160,160,151,150,156,159,162,158,156,155,162,152,160,112,12,1,9,10,12,10,13,12,13,13,13,12,24,28,31,29,29,29,31,34,29,34,31,33,38,38,42,36,40,41,38,39,36,39,36,39,40,32,28,21,18,19,18,19,17,21,22,17,19,24,22,19,20,17,17,17,17,17,15,18,18,17,17,17,18,16,20,20,16,19,17,17,21,17,17,17,18,17,19,20,21,17,19,21,15,19,21,18,21,23,21,22,28,27,26,24,23,26,22,24,27,31,31,31,39,28,29,34,32,33,31,33,32,29,30,30,30,29,25,27,23,23,27,25,29,27,33,38,35,42,40,33,32,26,34,33,34,44,47,51,48,53,61,52,57,55,53,56,51,55,65,77,89,96,92,84,80,82,90,96,91,101,110,108,106,104,116,107,110,108,97,106,103,105,109,105,108,108,109,113,112,107,108,97,92,101,111,119,115,120,122,119,121,119,117,124,122,117,108,104,108,110,109,105,108,115,118,120,118,111,114,117,119,121,122,128,136,129,120,117,117,117,112,115,116,120,119,118,118,111,105,103,107,102,102,101,87,85,77,85,100,101,100,96,98,101,106,109,114,114,112,106,101,99,103,104,115,118,111,121,127,130,130,133,141,128,126,127,114,114,120,122,126,122,115,113,108,112,103,96,93,92,97,95,103,105,108,112,108,110,101,103,108,105,105,102,103,112,109,101,93,89,97,91,84,70,75,76,72,72,72,83,89,88,89,91,89,84,80,84,90,93,99,97,100,107,104,106,76,68,81,64,62,60,59,59,55,55,54,56,55,56,59,57,55,51,58,54,59,58,53,55,50,48,53,53,57,54,53,54,45,53,51,49,53,48,49,47,47,49,49,43,44,44,44,46,48,46,42,45,52,49,52,47,44,45,43,46,50,44,43,48,49,49,43,43,47,44,45,43,47,51,60,61,59,66,71,63,54,49,46,47,41,38,43,45,41,44,49,47,44,51,48,40,46,52,51,47,61,64,62,62,67,71,66,73,64,59,68,70,66,68,77,83,70,64,67,66,66,66,66,59,55,53,56,55,51,48,51,49,47,47,42,40,40,41,40,39,39,36,40,41,41,39,43,41,36,49,48,50,50,53,57,65,74,74,77,63,87,98,82,95,93,99,113,112,106,109,136,125,122,141,136,149,152,157,159,166,167,154,153,163,188,217,232,234,237,249,251,251,250,250,250,250,253,253,251,251,243,229,233,245,249,237,185,141,94,18,2,11,9,17,37,53,53,53,55,54,57,42,29,35,27,30,37,39,38,33,34,30,39,48,51,51,46,41,44,44,42,39,37,36,33,31,34,31,33,36,34,33,36,40,39,43,44,44,52,50,50,50,54,60,55,49,51,48,46,49,56,52,67,81,92,108,110,125,138,157,168,158,155,157,160,160,161,159,157,160,159,166,168,174,175,155,150,149,145,141,141,147,154,160,156,153,157,168,171,169,164,157,152,144,149,158,159,160,152,152,152,155,163,166,164,159,160,163,165,163,154,148,153,159,158,164,161,160,168,163,159,157,163,166,162,163,162,158,158,159,158,157,159,165,165,159,162,145,123,101,88,108,134,153,160,160,158,154,151,148,144,149,152,156,163,166,166,166,168,163,160,160,160,165,165,163,160,155,158,149,160,113,12,0,10,10,12,10,13,12,12,14,13,12,59,58,62,59,58,63,62,66,63,66,71,71,76,79,87,89,93,105,107,113,111,110,109,108,92,69,54,42,31,28,19,16,18,16,23,18,19,21,17,22,20,16,20,16,16,16,16,17,17,17,16,17,16,17,17,18,19,17,17,17,17,18,21,18,18,19,17,15,22,20,20,21,19,16,20,19,20,21,21,26,26,22,25,29,31,22,28,32,29,39,46,47,42,41,39,36,43,42,36,34,30,30,31,27,24,24,22,18,23,21,24,18,21,29,28,28,23,29,26,25,30,27,31,29,24,35,38,37,47,45,56,45,38,38,41,42,45,50,62,69,75,75,46,49,67,72,77,84,83,89,87,78,83,96,104,103,108,101,105,107,105,116,118,118,119,125,122,124,121,117,120,118,118,114,110,112,112,117,121,114,119,118,115,127,120,114,112,107,111,114,117,118,113,110,113,110,108,113,115,125,123,119,125,122,125,128,120,128,120,121,118,116,125,114,117,117,122,125,126,124,120,115,109,102,89,89,103,113,123,127,122,113,108,113,116,127,122,126,124,126,131,129,123,118,113,116,109,117,131,137,140,142,130,121,114,108,109,114,121,121,114,122,128,125,120,114,106,105,110,106,107,96,93,101,100,98,103,104,91,92,90,93,97,105,99,101,99,92,92,79,83,73,66,77,81,66,71,83,59,84,81,51,49,50,58,58,65,54,61,68,80,61,60,63,77,87,59,53,59,59,71,59,56,60,61,61,64,59,55,57,65,69,57,59,62,59,63,50,55,55,52,57,54,57,55,53,57,54,50,46,51,53,52,50,51,49,49,49,48,42,43,48,42,44,44,43,49,48,51,57,55,51,53,54,50,54,48,48,52,46,55,54,44,50,46,36,48,43,40,50,46,40,46,45,55,46,43,41,44,46,42,41,44,42,37,45,46,45,48,50,44,39,40,46,56,57,61,57,57,57,54,47,49,63,51,51,57,59,63,63,65,66,69,65,68,69,71,77,77,76,69,70,67,65,72,63,63,63,60,61,53,55,49,48,52,51,45,46,47,44,43,42,41,37,34,35,39,39,37,36,39,42,53,43,53,45,45,55,48,57,59,59,68,73,75,77,91,93,91,101,124,125,136,139,127,134,145,156,179,209,235,247,251,245,248,251,252,252,252,252,252,252,252,252,252,252,253,253,253,253,252,252,252,252,244,187,75,26,5,5,13,9,21,37,47,57,54,48,38,34,35,29,39,35,31,35,35,38,34,39,41,38,34,32,37,37,32,32,34,33,30,32,31,29,35,35,38,39,39,39,41,37,37,51,45,42,48,45,56,58,54,57,49,49,49,53,53,56,66,78,89,81,93,113,137,160,165,155,156,147,151,157,167,160,155,153,156,163,174,167,173,158,151,154,155,151,157,153,153,162,159,154,161,169,179,174,166,158,146,147,150,152,155,154,155,156,160,157,158,157,155,153,155,164,168,164,154,152,153,155,158,158,158,160,163,160,155,155,158,160,161,158,160,157,155,153,153,156,157,155,153,156,152,156,152,124,96,81,103,127,148,162,165,162,159,150,149,149,150,154,157,161,160,165,164,161,159,158,158,158,162,160,162,155,159,152,157,112,12,1,9,9,13,11,13,12,13,13,13,13,131,126,125,124,131,134,134,139,136,144,145,156,160,162,171,171,177,174,174,171,162,162,148,150,139,98,66,45,33,25,22,18,13,17,17,15,19,18,17,22,16,18,18,14,17,18,15,15,15,16,16,15,18,16,17,17,17,18,20,19,16,17,17,18,17,19,18,17,18,16,18,17,17,18,19,18,19,18,18,21,18,19,23,24,21,22,20,27,36,35,42,40,34,31,28,27,29,31,26,25,20,24,29,23,22,23,26,24,23,22,22,31,27,27,29,22,32,33,29,33,41,41,37,40,38,44,47,52,52,53,57,59,55,47,44,38,33,40,54,57,64,62,64,66,65,71,72,83,87,86,81,78,80,87,101,95,94,93,102,110,111,110,113,119,120,126,122,120,118,118,124,126,121,112,107,105,106,113,115,111,111,113,110,110,113,116,114,122,126,122,125,112,113,114,111,112,107,110,117,113,117,114,109,115,115,117,121,118,118,118,121,123,119,113,107,112,118,125,128,131,130,128,131,124,120,127,129,128,125,125,120,120,124,125,125,127,125,124,123,120,125,123,117,114,117,113,107,110,109,109,109,115,117,111,109,99,94,110,117,113,114,116,113,115,109,107,112,117,118,111,113,106,106,97,92,95,97,95,84,84,78,88,101,100,99,99,105,98,91,75,81,83,87,94,99,95,99,102,94,92,82,77,78,76,75,75,62,58,59,50,65,54,49,59,57,73,60,54,56,54,66,59,54,61,66,66,60,54,51,60,57,56,57,57,57,53,57,54,50,61,52,50,54,50,53,52,52,55,53,53,56,53,52,49,51,49,51,47,52,50,49,50,49,47,46,45,48,51,46,47,47,48,46,49,43,45,45,42,46,43,47,51,44,44,45,46,42,38,46,42,43,42,37,41,42,40,44,43,36,45,45,39,41,49,42,35,45,40,42,45,39,42,43,45,47,48,46,42,46,52,50,41,38,49,44,46,46,52,57,49,48,50,53,51,51,46,53,56,53,54,53,54,55,55,56,54,55,60,63,64,66,69,60,64,68,59,56,56,62,60,56,58,46,47,45,49,47,50,49,40,43,41,45,46,43,40,41,44,39,45,41,43,47,46,48,48,53,46,56,55,53,66,72,83,88,96,115,136,160,180,194,205,208,210,217,226,233,240,253,253,253,253,252,252,252,252,253,253,253,253,252,252,252,252,252,252,214,178,150,117,55,7,6,11,10,19,39,52,46,39,34,32,32,40,39,35,33,34,36,29,34,31,27,36,29,34,36,33,33,33,35,34,36,35,42,39,37,42,34,39,41,36,41,43,42,39,49,53,55,57,57,57,57,55,54,60,54,60,69,71,73,75,85,104,130,145,141,133,134,140,141,150,159,163,154,146,151,154,151,153,152,146,150,151,154,158,153,153,152,153,159,158,159,160,162,165,153,149,150,149,159,160,155,157,156,163,168,163,157,155,152,155,162,163,169,169,163,163,160,158,156,159,162,159,161,159,153,154,152,151,152,157,155,151,151,150,157,159,160,159,156,155,160,159,163,155,131,108,92,101,125,150,172,178,174,166,160,160,155,152,156,155,149,153,155,153,156,151,148,150,155,159,159,154,156,150,159,112,13,2,9,10,13,11,12,12,13,13,13,13,137,135,139,138,145,146,146,151,147,157,165,162,165,163,162,154,148,139,112,106,95,75,57,45,43,42,41,30,26,21,18,16,15,18,15,17,21,17,17,18,20,17,16,19,20,16,15,16,17,17,16,17,17,17,16,17,19,19,16,16,18,17,19,19,17,17,17,17,18,16,20,21,17,17,20,20,19,22,24,24,27,33,27,24,29,26,28,30,36,38,38,33,30,30,31,33,31,33,39,36,31,37,32,27,31,33,34,32,27,35,44,40,35,35,39,40,38,34,46,46,47,46,43,35,41,45,47,58,61,68,67,65,52,55,47,45,50,54,69,65,88,92,93,101,94,96,95,97,99,103,101,107,112,111,112,112,105,107,109,119,117,116,110,112,110,113,113,112,116,113,115,121,109,107,105,107,113,113,113,107,112,115,118,118,117,122,122,120,129,120,114,112,112,117,121,118,114,120,117,115,115,112,119,117,122,122,112,118,115,119,118,114,117,109,113,115,117,122,124,123,123,122,120,118,118,118,118,115,116,117,110,123,126,123,124,117,118,120,111,114,115,112,115,122,117,115,108,104,103,103,106,106,108,101,101,99,102,109,115,119,106,105,111,104,107,114,115,121,117,116,118,117,114,107,107,105,100,92,99,89,92,97,102,102,96,113,113,98,102,95,97,94,93,92,99,120,123,116,113,109,105,107,91,100,79,79,83,78,71,56,67,70,69,76,64,73,71,59,56,56,58,53,54,64,55,61,59,50,57,56,56,55,49,59,56,55,54,47,54,54,51,52,48,50,52,52,49,51,57,56,57,51,46,53,53,49,55,53,52,54,51,53,48,47,49,48,48,51,48,48,48,41,42,41,43,44,40,44,44,45,44,38,48,43,39,41,42,41,45,41,39,43,42,40,42,39,40,44,42,41,44,44,46,40,44,42,39,39,39,42,42,46,41,41,39,45,47,42,39,39,45,41,39,39,41,41,38,39,40,43,43,36,42,41,39,42,40,47,42,45,43,46,50,42,52,47,53,57,57,60,56,61,62,59,64,61,63,63,65,65,59,69,62,61,69,70,76,68,57,59,56,54,57,60,57,49,56,58,50,45,44,49,50,47,44,44,45,47,44,48,50,45,49,45,42,53,54,61,68,83,89,94,103,106,128,137,141,160,176,187,204,224,239,251,252,252,253,243,253,253,234,252,252,252,253,253,251,251,252,252,234,134,125,25,1,9,10,19,33,37,38,34,40,38,38,38,36,35,35,35,29,38,35,35,41,33,34,37,39,37,37,37,31,35,35,34,37,34,36,36,36,33,35,35,35,41,42,45,51,51,48,54,57,56,52,56,54,53,58,54,60,55,74,80,96,96,110,130,142,150,136,140,137,146,142,130,133,129,121,127,129,128,146,132,144,146,147,143,149,153,154,151,151,146,149,146,143,147,144,148,155,155,160,159,162,150,156,157,162,159,146,146,151,160,164,165,166,161,156,151,150,152,159,162,159,160,154,158,162,155,155,159,160,158,152,150,153,152,155,160,158,160,161,163,167,162,160,138,113,96,89,120,147,169,182,174,170,162,159,156,153,154,148,152,156,156,155,151,149,148,148,153,158,153,158,150,159,113,12,1,10,10,12,10,13,12,13,14,13,13,125,126,128,132,134,129,128,126,126,133,120,118,100,89,79,65,54,41,35,32,31,34,27,26,29,29,27,21,24,17,18,18,16,17,21,21,21,19,19,17,17,21,16,15,18,17,18,16,16,19,17,17,17,17,19,18,18,17,20,20,17,19,20,17,17,17,16,18,19,23,16,16,18,18,22,22,21,26,29,34,43,37,36,37,40,40,47,46,48,46,44,43,41,43,37,36,42,39,33,36,34,30,28,28,33,31,31,31,34,34,40,44,40,38,31,33,36,33,40,46,47,44,39,35,41,44,41,45,47,53,51,53,48,53,56,59,62,60,86,101,114,121,121,119,120,123,118,116,115,122,126,126,121,114,124,121,122,121,117,115,119,118,118,112,110,113,112,118,118,117,122,122,121,116,118,123,119,117,118,117,117,122,126,122,115,118,122,131,126,118,122,122,128,124,123,122,121,127,125,119,129,130,130,131,125,131,129,128,130,119,120,123,128,127,125,125,124,125,125,129,122,114,115,116,122,121,122,123,122,119,114,124,122,117,118,120,119,125,129,127,123,127,138,136,134,129,123,127,129,130,122,123,113,111,116,118,124,127,125,117,113,111,113,118,117,117,120,124,119,114,117,114,121,118,120,123,117,114,116,117,115,120,113,105,103,103,98,93,106,105,103,95,87,79,87,88,92,89,91,103,98,95,94,89,74,85,94,94,89,60,72,68,64,68,65,71,61,62,60,63,68,67,66,60,65,58,49,56,51,57,57,55,56,55,63,53,56,54,53,60,49,55,55,55,61,50,51,51,55,57,50,51,49,47,51,50,52,51,51,56,50,47,48,46,52,51,46,49,49,48,44,44,46,46,48,48,45,43,42,43,44,40,40,45,43,40,43,44,42,38,46,52,45,42,40,44,45,46,44,42,42,46,47,44,43,50,47,42,42,44,44,42,39,44,48,46,48,47,46,46,47,44,43,45,40,41,39,42,42,40,40,39,41,39,42,44,46,44,42,47,43,46,39,43,46,46,45,47,54,45,45,50,47,57,60,57,57,51,57,58,57,67,56,53,59,58,69,63,60,61,60,63,57,61,61,62,72,73,61,60,67,66,65,67,60,59,56,53,55,50,54,53,53,61,57,53,51,45,46,43,53,53,42,48,50,45,46,53,65,67,85,103,118,138,151,186,185,156,187,228,239,250,253,253,253,253,253,253,252,252,252,252,242,221,156,84,21,2,9,11,24,24,26,31,33,32,24,29,34,30,36,37,34,42,37,36,34,41,40,33,40,37,33,34,33,31,38,37,33,30,30,33,31,31,39,39,36,38,44,48,44,51,51,50,53,57,53,51,49,53,54,53,62,58,69,84,105,127,154,158,136,139,140,149,145,131,134,127,123,130,139,143,150,150,154,158,153,150,148,148,149,146,147,143,144,146,141,147,146,144,148,150,145,148,149,139,145,152,150,150,140,139,148,153,160,152,152,157,157,160,158,157,162,159,161,162,156,162,163,162,160,166,167,160,157,152,155,151,157,158,159,158,160,165,165,168,163,160,139,114,91,84,109,137,163,169,170,170,164,156,152,153,154,161,163,161,163,162,159,155,156,153,158,157,159,154,164,114,12,0,9,10,13,10,13,12,12,14,13,13,118,123,119,113,110,96,78,76,73,49,46,37,39,31,32,35,29,29,24,29,22,27,28,23,24,22,28,27,20,26,22,17,21,21,21,18,21,19,19,19,16,17,20,18,16,18,18,18,16,16,17,20,20,16,17,21,19,18,19,15,18,19,16,21,19,20,19,16,21,17,18,21,17,16,18,20,20,25,21,28,30,28,32,33,28,28,38,22,31,33,28,37,29,29,31,28,29,29,27,28,33,37,31,29,31,31,32,39,38,44,44,40,39,29,35,33,29,31,27,24,27,37,25,29,34,28,34,33,42,40,46,49,44,47,46,53,56,59,68,81,88,102,111,122,117,115,122,119,125,122,113,117,112,118,114,112,115,118,123,124,128,126,124,125,123,123,122,122,125,124,125,123,120,125,121,125,127,122,122,119,126,130,132,127,119,126,128,124,128,126,128,128,128,128,126,122,124,123,118,113,126,122,128,124,122,123,124,122,119,119,126,133,128,127,131,127,128,122,121,120,122,119,118,124,128,128,125,118,122,123,119,123,117,124,127,125,129,130,127,125,122,128,127,125,128,129,125,128,128,128,126,121,126,127,133,127,134,130,116,113,107,116,118,124,119,118,121,117,114,98,106,107,109,113,116,113,106,114,112,115,106,106,95,90,89,89,78,90,91,79,75,91,83,75,68,68,80,81,93,99,75,95,93,80,70,82,92,74,78,60,70,55,51,59,51,60,50,54,57,62,60,66,58,61,64,55,56,53,55,55,58,54,55,57,53,58,66,56,59,57,57,59,54,61,56,53,55,53,54,56,51,49,51,49,55,49,50,50,55,56,44,53,50,45,53,48,44,49,47,43,48,51,44,45,53,51,47,45,45,44,44,42,45,44,45,43,39,44,45,46,43,46,47,44,44,44,47,48,44,40,43,47,41,45,47,43,45,43,46,48,48,45,42,44,43,45,46,45,43,41,43,41,48,44,42,45,42,40,38,45,42,40,46,38,39,46,42,43,45,43,41,48,44,40,42,39,42,43,47,45,36,47,47,43,49,45,50,40,42,47,42,54,47,42,40,48,50,47,55,51,53,48,45,51,54,54,64,65,65,66,59,62,65,67,68,62,61,62,61,64,71,75,81,76,76,77,70,77,61,66,90,95,80,68,78,76,58,66,71,59,55,46,46,48,57,91,78,37,56,132,156,174,213,250,251,250,240,253,253,253,253,253,252,252,246,246,208,145,59,5,5,10,12,14,12,14,14,22,36,34,35,41,36,36,38,36,39,32,34,34,30,39,33,27,33,33,34,33,30,27,32,27,31,33,34,39,34,37,39,44,51,49,43,49,49,57,62,59,57,52,56,65,70,65,76,85,89,92,125,134,141,135,145,134,120,125,133,148,152,163,164,169,164,166,171,169,154,158,156,157,154,157,163,156,160,156,150,149,150,149,145,142,145,144,144,142,151,157,156,153,157,153,150,154,149,144,150,154,158,163,163,155,158,161,159,159,152,153,160,158,162,166,161,152,153,158,158,162,156,157,161,159,163,166,168,167,165,160,156,148,121,101,88,101,130,154,171,171,170,164,156,153,156,165,165,166,165,167,165,163,162,160,161,159,166,159,165,113,12,1,9,10,12,10,13,12,13,13,13,13,92,86,69,53,44,38,35,31,28,28,23,28,25,23,26,27,26,22,23,25,26,27,27,26,24,22,25,28,26,19,20,21,18,21,22,20,22,22,15,19,21,15,21,20,17,17,17,17,19,18,17,18,19,16,21,19,17,19,15,17,18,21,18,18,19,18,18,19,22,17,21,19,18,19,17,24,23,20,21,27,23,21,26,22,19,20,29,22,22,24,29,26,27,31,27,33,30,28,27,25,34,36,29,33,34,33,34,34,41,36,37,31,26,36,35,38,31,33,39,32,36,34,34,26,27,31,34,36,42,44,41,40,45,47,48,54,56,54,54,52,63,84,102,105,98,96,100,106,108,107,109,115,113,116,117,113,113,119,125,123,120,113,117,117,122,120,123,125,125,123,121,120,122,127,121,123,127,125,124,122,122,123,130,129,122,122,115,117,121,124,127,123,119,118,118,116,117,117,111,105,107,104,102,105,101,103,106,116,117,117,133,130,130,131,136,131,126,122,113,118,114,110,114,113,116,115,114,114,113,105,112,122,121,126,124,123,123,124,122,118,112,114,120,117,125,122,122,116,107,111,106,122,123,125,127,126,127,114,117,115,117,124,123,121,112,101,101,109,110,108,113,123,126,119,111,113,112,108,116,102,91,93,82,91,93,93,95,97,94,89,94,97,90,84,81,76,83,90,89,89,99,101,94,73,53,57,54,57,71,53,54,42,45,56,50,52,50,56,48,52,56,50,61,61,67,62,51,57,53,60,55,60,60,55,59,48,57,55,54,55,48,53,49,56,56,51,56,51,55,54,54,54,61,56,50,60,54,52,54,53,54,50,49,54,48,50,50,50,49,48,53,48,51,50,48,47,48,49,45,44,44,43,48,47,39,45,42,40,44,43,43,36,46,40,40,47,42,44,41,42,38,44,43,43,44,42,45,41,43,46,44,45,44,40,40,42,41,35,38,46,39,41,43,40,43,40,38,41,42,39,39,41,41,44,44,40,40,40,40,44,37,46,40,39,43,40,40,36,41,44,41,41,43,36,38,41,35,42,38,39,40,39,37,34,41,36,36,50,46,42,45,43,43,41,46,48,51,55,55,50,49,58,53,54,57,66,71,71,63,61,74,76,78,68,73,77,72,74,79,92,110,115,116,116,127,131,137,153,154,142,127,107,112,108,107,120,72,22,27,64,92,107,125,160,201,175,182,250,253,253,252,252,253,253,252,252,250,250,229,205,200,190,195,200,194,193,178,204,171,45,29,39,28,35,29,30,36,29,31,36,32,32,29,29,32,30,33,30,30,24,24,27,33,31,31,37,37,37,35,39,47,50,45,44,50,59,64,64,62,61,62,71,83,76,90,89,84,101,117,116,114,124,117,105,97,117,140,152,160,163,169,171,174,163,161,165,155,155,163,164,160,167,170,169,165,157,151,151,153,158,155,154,153,155,153,148,160,162,162,177,176,170,165,155,152,146,150,151,154,163,159,158,159,163,160,160,155,153,158,158,158,159,155,153,152,155,161,161,164,160,158,154,160,168,166,166,163,164,160,160,156,132,108,89,96,125,154,170,170,165,162,157,158,168,170,169,163,165,165,159,163,155,160,159,162,158,163,113,12,1,9,10,13,10,13,12,13,13,13,13,34,31,35,24,24,27,19,24,20,22,21,19,25,21,21,29,28,24,29,24,22,23,28,27,25,27,24,27,29,19,17,18,17,17,21,21,17,18,17,19,17,17,18,18,19,19,17,20,19,17,18,19,18,16,19,17,17,17,17,20,19,17,19,23,16,18,19,19,18,21,22,18,18,21,19,20,22,20,24,20,21,26,21,27,30,27,33,38,35,33,34,36,39,41,35,37,36,35,28,29,29,30,32,36,29,26,35,27,31,29,36,35,29,36,33,35,46,44,46,49,45,45,37,38,34,36,40,38,45,47,53,55,60,67,72,76,75,75,85,89,103,108,120,103,104,99,104,110,99,107,101,112,112,118,117,112,122,118,118,117,110,107,111,115,118,118,121,122,117,114,116,118,119,124,118,115,109,108,110,105,108,108,103,100,101,98,107,109,108,112,119,123,117,108,114,116,121,116,110,109,104,110,112,112,115,116,110,112,110,127,127,122,122,131,132,130,132,122,124,124,125,124,120,122,122,123,122,115,108,109,115,127,122,113,118,125,124,125,124,117,123,127,127,129,126,125,120,106,103,112,115,125,128,120,122,118,115,116,123,129,126,126,118,106,101,109,110,114,122,125,129,120,114,115,125,125,112,110,103,104,108,116,127,122,119,121,113,119,113,105,107,111,115,100,97,83,78,87,91,100,85,83,84,71,50,55,64,78,72,72,63,49,51,61,56,57,57,65,56,56,55,50,55,66,62,56,60,56,58,57,60,56,57,60,54,56,52,57,58,53,56,53,57,57,50,56,58,63,55,55,57,66,60,53,62,56,60,55,52,53,53,55,47,54,51,50,54,49,52,51,50,53,55,54,47,49,49,44,46,49,43,49,42,44,47,44,43,39,43,46,42,43,44,35,43,41,39,44,38,42,40,45,48,41,43,41,44,39,39,42,42,41,41,43,41,39,40,43,40,38,38,42,40,40,42,42,39,39,38,38,44,44,39,37,38,39,42,40,36,42,44,35,39,42,39,37,40,36,36,42,39,42,38,38,41,38,39,35,40,42,33,37,40,33,34,39,34,40,35,36,43,35,40,38,41,43,41,46,48,45,48,54,52,54,59,63,62,54,53,60,60,65,66,59,66,69,79,75,75,89,101,121,125,124,135,136,152,156,155,153,133,159,182,169,165,154,131,98,120,129,141,125,97,97,139,76,117,210,251,252,252,252,253,253,252,252,253,253,252,252,252,252,252,252,252,252,251,251,226,67,32,33,25,31,26,29,28,27,29,29,29,29,26,27,25,28,24,29,27,22,27,24,24,33,24,30,34,29,36,37,37,42,42,42,43,52,60,62,61,55,57,63,75,70,93,85,109,122,112,107,109,121,110,123,112,122,131,146,149,147,152,158,155,150,151,155,160,170,179,173,163,160,162,158,155,151,151,152,158,165,161,162,163,157,157,151,155,153,158,175,174,170,162,159,156,152,155,154,153,155,159,159,161,165,162,161,159,159,159,154,154,149,155,152,154,155,157,161,161,161,153,149,157,155,158,160,160,159,157,164,162,162,136,106,87,93,121,143,162,166,166,164,160,167,165,163,158,156,160,159,156,156,160,158,160,151,160,113,12,0,9,9,12,10,13,11,12,14,13,13,21,19,24,22,22,20,20,24,23,24,21,24,25,23,24,23,27,25,24,24,22,26,25,29,27,21,25,23,20,24,21,15,21,20,16,18,17,19,20,17,17,19,17,18,17,17,21,16,17,16,17,18,17,20,17,17,18,18,19,19,21,18,20,19,18,19,19,20,19,19,20,18,22,23,16,22,18,23,23,22,29,26,29,33,34,36,39,33,32,26,27,30,34,33,40,39,37,43,39,41,45,49,43,43,42,35,37,41,43,44,45,46,43,40,43,48,48,45,46,47,43,42,50,49,47,45,49,40,42,50,53,61,73,85,96,100,98,99,95,103,101,98,96,101,117,118,121,117,126,122,117,116,111,115,113,117,114,114,118,117,110,104,110,120,125,120,122,118,113,116,116,116,116,119,117,114,110,105,103,110,112,108,111,113,113,117,119,119,118,119,123,122,117,115,115,119,127,127,124,120,125,125,124,127,125,120,116,110,107,113,121,113,111,114,115,114,109,114,122,130,132,130,127,129,131,125,129,127,123,122,123,127,119,122,125,122,125,127,125,125,129,131,128,127,131,127,128,123,118,129,127,131,127,126,119,118,117,117,129,119,125,124,108,110,117,113,116,115,116,113,105,109,111,116,115,115,112,108,116,118,119,130,129,132,128,123,125,131,122,111,112,111,110,110,109,97,90,88,77,71,68,67,80,77,85,95,96,98,93,93,84,65,66,66,69,70,73,80,58,58,51,45,61,58,59,59,62,61,60,63,57,57,55,55,60,57,59,57,58,62,61,58,54,57,55,56,55,54,53,50,56,53,57,53,46,53,49,50,51,48,55,50,48,53,49,47,47,52,50,51,52,47,49,49,47,49,49,47,46,48,43,44,45,47,44,44,45,45,47,45,45,46,42,41,48,42,41,44,45,42,43,46,43,43,40,42,44,43,41,38,39,43,41,43,49,46,46,45,40,44,44,46,43,45,44,42,40,40,45,41,45,40,39,42,38,40,40,34,40,44,37,41,38,34,38,36,38,38,36,37,39,43,41,41,45,44,44,38,38,41,38,41,40,34,41,41,35,40,36,33,36,39,38,42,42,42,41,46,50,40,46,49,46,51,53,55,49,51,54,53,51,55,58,54,62,70,75,68,67,81,91,100,113,113,115,116,106,106,105,113,122,137,162,150,168,172,142,143,160,188,189,150,113,109,104,57,72,133,148,178,217,248,253,253,252,252,253,253,252,252,253,253,252,252,253,253,252,252,226,44,21,21,12,31,21,27,27,30,28,29,27,27,24,27,27,21,30,27,27,23,21,27,28,27,29,28,28,33,30,32,34,33,31,36,39,42,50,52,52,54,57,54,64,62,67,79,97,117,105,104,115,134,161,150,133,137,132,136,143,137,133,130,139,153,166,168,165,170,171,166,154,153,157,162,160,157,158,159,159,162,163,161,159,160,151,154,154,145,154,160,160,153,153,157,155,152,156,150,148,150,151,156,156,160,157,162,159,155,159,155,150,151,150,155,155,151,154,153,160,165,161,150,148,150,144,151,155,155,154,158,162,156,152,132,101,86,88,108,137,160,170,170,164,162,160,158,153,157,158,157,163,158,162,160,160,154,160,113,13,1,9,10,12,11,14,12,12,14,13,13,19,17,20,19,24,22,22,22,24,23,18,22,22,24,25,23,25,27,24,25,25,22,27,27,26,26,29,24,19,22,16,18,18,19,22,19,21,16,19,22,17,17,17,19,16,17,17,19,21,17,16,18,17,19,18,17,20,20,17,20,21,17,21,18,18,19,18,22,18,17,16,19,18,19,19,18,22,21,22,27,32,29,25,29,31,29,28,25,26,19,25,28,33,33,30,27,29,37,35,37,36,36,37,33,38,38,31,46,50,46,45,39,35,43,40,40,39,36,35,36,38,41,39,47,46,45,47,46,48,42,39,42,59,71,80,91,94,100,95,98,103,102,108,111,119,113,121,108,124,125,121,123,125,120,124,120,116,114,110,116,119,121,114,122,125,116,120,123,122,124,125,124,121,127,122,123,121,123,122,118,125,130,131,129,130,127,130,126,123,123,119,123,120,115,122,116,118,116,124,127,118,120,119,118,120,121,126,123,123,120,122,118,116,118,115,119,124,116,120,119,122,122,122,122,122,126,128,128,124,125,122,126,126,120,123,125,125,125,122,121,123,122,124,128,125,129,135,131,131,130,132,127,125,122,119,120,121,122,119,112,108,110,115,117,117,116,107,98,103,106,107,111,110,103,101,101,105,111,110,106,101,98,104,106,105,108,103,104,93,90,90,92,96,105,107,112,108,102,92,79,85,82,92,97,102,99,103,98,88,97,94,95,100,104,103,100,93,95,80,89,80,74,79,61,65,61,66,59,54,60,56,53,56,55,56,60,55,56,57,62,60,56,59,59,54,54,57,54,54,49,53,53,50,50,48,51,51,51,49,50,53,55,50,50,49,46,52,49,47,47,50,48,48,48,42,47,44,46,50,46,46,47,49,47,49,43,46,47,37,48,43,44,49,41,48,43,44,41,40,44,41,43,42,43,48,41,45,42,36,40,41,39,44,42,41,48,39,38,44,41,42,47,46,43,39,39,42,42,41,39,46,41,38,41,39,42,41,41,42,40,39,42,36,36,37,39,41,37,40,39,39,38,43,38,40,44,37,36,39,38,41,45,41,36,36,39,36,33,36,37,38,36,38,40,40,39,39,40,37,44,45,42,42,45,46,44,47,50,43,46,47,52,50,49,57,53,61,57,58,68,64,66,83,85,59,63,73,82,101,98,100,105,124,126,142,132,108,122,140,165,160,149,172,192,146,101,97,116,105,103,117,141,178,208,233,249,253,253,252,250,253,253,252,252,253,253,252,252,209,38,16,13,12,29,17,30,27,24,26,27,25,31,29,25,26,22,28,23,24,27,24,22,21,26,29,29,35,32,28,35,39,32,29,33,35,42,39,47,52,54,57,52,57,59,51,60,74,89,98,114,130,145,164,138,122,125,130,145,156,151,142,137,143,153,166,160,154,160,164,146,154,151,158,164,165,164,165,161,158,155,153,158,161,160,161,164,160,153,152,155,152,147,146,146,150,148,146,146,143,141,142,146,148,150,151,156,157,155,157,157,152,152,155,158,158,156,156,157,160,160,160,156,154,151,151,151,151,155,155,155,153,157,151,150,133,114,93,81,103,130,154,164,164,162,156,154,150,152,156,161,163,163,165,161,169,159,166,113,11,1,9,10,13,11,12,12,13,13,13,13,21,20,22,21,24,24,18,24,22,24,20,19,22,24,26,24,26,24,24,28,23,26,27,23,23,24,27,20,21,19,17,18,17,19,19,19,16,21,19,20,18,18,19,18,18,17,17,17,17,19,19,18,20,19,18,17,16,17,16,21,18,17,21,19,21,21,18,18,17,20,18,19,22,19,18,18,19,23,22,28,29,23,24,27,23,27,28,23,22,22,25,22,22,29,25,27,31,31,30,30,27,29,27,21,27,28,24,29,30,36,35,36,32,29,29,30,34,30,35,42,36,41,38,38,45,42,47,45,42,42,42,39,47,55,61,76,81,93,93,99,106,111,118,117,116,102,99,99,107,112,122,130,130,128,124,125,117,125,127,127,130,130,122,120,122,128,128,123,120,127,129,122,121,128,130,128,131,132,128,123,125,127,124,126,125,122,125,122,122,125,123,122,126,126,128,127,122,121,124,124,130,134,125,124,129,134,138,137,139,137,134,129,128,137,136,134,131,132,134,128,131,129,128,128,124,121,125,122,122,129,129,129,121,124,130,124,128,129,128,125,125,124,126,137,134,130,135,133,129,137,134,130,126,122,121,126,127,122,124,122,118,116,120,122,128,117,116,114,117,117,115,126,118,115,114,117,113,109,104,97,93,98,104,103,104,98,88,86,86,89,81,84,93,101,108,111,112,113,109,107,105,97,103,104,107,102,105,102,86,103,118,116,123,118,118,104,102,106,102,120,110,107,102,80,74,61,57,55,59,55,54,59,56,59,54,63,57,55,67,64,56,53,56,53,55,57,53,57,55,51,53,52,54,50,53,57,51,55,52,51,53,50,51,48,53,52,51,50,48,54,50,47,49,45,47,49,51,50,40,49,51,46,50,46,47,48,47,47,42,40,43,46,47,43,45,40,43,45,42,45,42,43,40,45,44,42,44,44,43,40,39,43,36,43,45,42,44,39,46,42,37,45,42,37,43,42,36,39,41,38,41,37,37,39,42,39,37,42,36,40,40,39,40,38,41,41,42,36,39,40,39,41,35,37,39,36,35,38,36,41,41,42,39,39,44,38,39,36,39,38,34,38,38,39,34,37,42,35,35,40,43,36,42,39,39,46,42,53,44,40,49,45,48,48,53,45,46,56,51,55,54,49,57,61,49,48,53,72,72,86,82,72,89,95,114,92,97,108,112,132,125,152,190,209,179,125,135,161,145,114,86,74,79,98,127,148,189,204,190,198,202,198,197,199,204,210,222,251,179,19,15,9,18,29,21,23,26,29,27,28,29,26,21,25,27,31,29,24,24,22,26,27,23,32,31,30,32,35,34,32,39,32,36,35,36,41,39,50,51,51,51,52,53,51,54,61,61,75,94,120,133,139,139,113,103,110,129,152,165,165,157,155,155,155,151,145,146,155,161,162,159,151,152,162,166,167,168,160,156,148,153,153,152,161,156,161,159,160,164,159,160,154,152,151,147,141,147,148,155,155,147,148,146,143,139,143,146,148,150,153,155,160,160,157,156,158,163,160,162,164,165,161,162,162,155,158,160,158,155,159,157,159,160,160,158,151,128,98,85,95,124,148,159,167,165,159,152,153,152,155,157,156,161,160,164,159,169,114,11,1,9,10,13,11,12,12,13,14,13,13,28,21,20,20,24,21,19,23,24,24,23,21,22,27,23,24,24,26,24,21,21,24,28,26,31,28,26,24,19,18,18,18,19,20,19,19,17,21,20,16,19,23,16,20,21,17,19,17,19,16,19,20,17,18,17,18,19,18,21,19,16,21,18,19,20,19,21,18,18,21,19,16,19,22,17,20,22,24,25,24,21,25,24,25,28,27,27,27,26,29,26,23,26,22,24,28,26,24,29,24,27,27,24,25,25,31,28,27,36,35,35,34,32,31,28,29,31,35,37,37,38,38,42,48,42,41,48,43,50,42,40,46,44,51,55,53,64,69,79,89,90,93,102,105,112,108,116,122,127,129,128,126,123,115,111,111,116,120,117,124,126,127,130,124,126,119,118,120,121,125,124,124,130,129,132,133,128,129,126,118,115,123,128,130,134,128,128,131,132,137,128,133,128,121,131,127,129,134,126,137,133,131,114,120,128,136,132,137,134,140,143,138,131,141,136,139,145,146,146,139,132,133,131,130,125,127,124,123,128,129,121,129,136,135,137,130,131,133,134,139,138,136,137,139,129,130,136,132,135,132,136,129,131,139,133,136,135,141,145,147,141,132,127,132,128,128,127,127,119,125,128,131,122,112,114,113,118,118,117,113,121,129,133,133,122,113,118,103,125,110,101,110,107,112,106,95,89,84,99,106,102,92,100,110,107,105,112,108,84,107,93,81,70,84,85,84,89,81,84,95,88,115,82,62,69,67,71,82,71,81,86,78,69,60,62,62,61,61,53,53,49,55,54,51,54,52,51,47,61,55,53,54,52,57,56,54,58,53,51,53,51,53,51,55,51,51,49,50,49,50,52,45,48,46,45,51,44,42,47,47,46,46,48,43,48,46,44,51,41,38,43,43,46,44,45,45,42,44,45,42,41,46,44,42,38,45,46,38,43,42,40,42,42,41,44,42,40,44,45,39,37,41,36,39,46,41,40,37,34,39,38,36,41,37,42,40,38,41,34,40,39,36,39,39,37,38,40,35,38,39,37,39,34,42,38,38,38,35,37,39,40,41,39,37,39,41,38,39,38,33,37,38,37,39,33,36,38,37,35,40,38,36,41,39,41,42,44,45,39,46,41,34,49,45,43,43,36,42,45,47,47,44,46,51,51,53,57,53,66,67,62,57,59,73,77,60,74,78,82,101,101,126,153,169,149,119,134,171,165,164,142,125,92,128,150,131,147,139,138,125,99,90,97,98,101,107,126,177,93,16,24,9,21,24,19,26,20,27,28,25,24,24,24,24,27,23,26,24,26,24,25,24,24,29,25,30,32,33,38,38,32,34,34,38,41,39,43,47,47,49,49,51,51,55,62,60,62,64,87,92,99,102,115,84,100,110,116,125,139,151,162,171,163,157,152,156,154,165,169,165,159,151,150,156,158,156,156,156,150,142,141,143,149,150,154,151,153,159,160,162,161,158,155,151,147,147,155,163,165,167,162,159,153,144,142,139,142,146,148,152,155,157,155,151,149,153,157,157,154,153,159,162,162,161,156,156,162,158,153,153,153,155,155,163,155,159,147,129,108,79,91,112,142,162,170,171,166,162,158,152,148,148,151,152,159,152,167,115,11,1,9,10,12,11,14,12,13,14,14,13,22,24,17,21,21,19,23,22,21,24,18,21,22,22,23,23,25,23,22,21,25,27,24,21,30,22,22,25,24,23,16,16,17,19,19,16,20,20,19,19,19,19,19,16,17,17,17,17,23,21,16,20,20,21,19,17,22,21,19,19,19,16,24,23,17,19,18,23,19,22,21,19,20,19,24,19,20,21,21,25,19,24,19,20,28,21,24,26,20,24,24,23,25,22,21,22,24,23,22,26,23,26,29,20,27,25,27,33,27,27,32,29,29,29,29,26,31,35,37,33,29,34,33,38,40,39,41,43,37,37,42,47,54,55,53,57,57,66,71,80,81,79,93,103,116,124,131,129,132,129,124,118,122,124,120,121,118,121,121,123,124,125,125,127,122,123,126,131,126,127,131,129,129,128,128,125,127,124,122,127,133,136,134,135,133,137,141,131,130,132,127,124,122,122,130,134,134,129,125,118,114,114,106,116,127,132,124,111,118,127,131,129,128,133,130,134,136,140,142,132,133,128,133,136,130,133,129,130,130,126,122,123,127,131,133,132,129,132,132,131,132,128,122,120,122,122,126,130,132,136,127,126,137,141,139,141,141,138,135,131,135,132,130,128,128,127,125,113,118,121,122,125,117,117,114,115,114,126,128,125,128,132,127,130,134,120,116,118,111,107,106,108,118,117,105,98,95,87,78,87,90,88,94,90,87,92,98,83,75,65,59,50,50,59,54,64,64,57,57,60,55,60,51,39,61,68,83,79,77,92,84,72,68,68,64,61,56,57,59,52,60,58,55,59,56,52,51,56,58,54,54,54,52,56,57,49,56,55,51,51,54,56,51,59,56,49,54,52,48,49,52,51,56,45,50,50,50,48,48,51,44,44,46,46,45,46,46,48,43,49,45,41,48,45,45,44,45,42,45,42,39,44,44,46,42,42,39,42,44,39,44,41,39,40,38,39,42,41,41,41,41,41,42,39,45,42,41,46,41,41,41,39,42,45,43,45,44,40,36,37,46,42,39,37,34,37,41,37,36,39,40,39,38,38,40,42,39,40,38,37,37,39,41,36,39,37,40,34,36,39,33,39,34,37,37,34,37,37,37,35,38,35,37,40,38,43,34,40,43,40,41,36,38,36,42,41,35,39,36,42,44,40,43,46,43,51,57,57,56,52,47,50,56,55,53,49,60,54,61,81,83,99,113,125,118,110,117,141,200,223,205,190,180,187,203,196,184,147,105,74,62,74,84,78,70,42,45,77,39,28,29,10,23,22,23,25,17,24,21,26,25,22,25,27,27,17,29,28,27,24,22,31,27,24,26,30,35,32,39,39,34,37,38,39,44,45,46,53,47,48,52,54,57,57,60,65,67,64,69,85,83,86,104,98,110,122,110,102,115,137,159,170,165,159,157,158,160,169,170,163,155,151,153,155,156,149,147,153,152,140,148,152,152,155,153,154,154,159,158,153,153,153,154,159,157,153,162,164,165,167,165,161,159,160,157,154,153,159,155,156,155,155,157,146,146,151,158,154,148,150,150,154,152,157,161,159,161,160,154,152,149,151,154,153,156,158,159,155,136,111,91,87,110,139,162,173,178,174,168,166,158,151,151,146,148,148,162,112,13,1,10,10,12,11,14,12,13,14,14,13,22,20,17,18,19,23,22,22,21,21,22,24,23,23,24,21,24,27,22,23,26,24,23,23,28,20,23,24,18,17,20,18,17,19,16,17,16,21,20,17,19,16,17,16,17,21,19,18,18,19,19,17,19,19,18,18,21,19,18,18,18,19,18,17,20,23,20,22,19,18,20,19,21,17,21,21,24,21,22,20,19,24,22,24,24,22,23,21,24,27,22,22,24,20,22,24,22,30,24,24,27,24,26,24,25,24,25,30,27,24,29,24,29,31,30,29,28,31,33,27,27,27,34,37,36,40,41,40,44,47,51,55,61,57,61,61,59,55,51,54,57,67,100,111,113,108,106,99,95,98,106,115,126,129,129,127,127,124,135,137,133,127,128,128,124,128,130,128,128,130,127,121,125,128,126,123,125,128,125,130,135,139,129,123,126,122,126,125,125,129,128,131,127,132,136,127,125,118,127,120,113,116,115,111,124,118,115,124,118,117,120,118,130,123,124,126,125,125,133,137,136,132,134,135,132,137,138,125,121,126,119,122,114,128,126,125,129,129,125,116,117,112,111,113,117,124,126,128,127,125,128,129,134,140,136,136,128,122,115,110,105,105,117,107,114,120,114,110,119,116,118,121,119,124,111,123,115,114,114,116,122,127,128,126,118,111,119,123,112,119,123,110,122,115,103,122,134,120,106,102,88,92,96,103,93,84,83,65,68,76,83,61,55,70,60,66,67,40,51,61,39,64,59,51,41,65,45,78,72,58,52,47,55,56,64,49,51,61,53,57,57,53,54,61,60,59,64,59,60,55,57,56,53,55,53,55,52,55,55,52,55,53,53,49,48,54,51,55,53,55,51,49,59,53,55,51,49,53,53,44,45,53,51,53,48,43,48,48,46,51,52,42,44,48,46,41,47,45,41,45,44,46,43,41,43,42,44,39,47,42,40,47,38,42,39,41,45,44,43,46,39,40,44,40,44,40,46,42,38,42,42,41,38,41,42,39,45,42,36,39,39,41,45,36,40,43,35,40,39,36,40,39,33,40,40,39,38,37,40,37,38,37,34,42,34,37,36,34,38,35,36,39,34,37,36,37,39,32,36,39,35,33,39,37,38,39,38,42,35,39,39,37,41,34,35,41,33,40,36,37,40,41,43,41,48,57,57,46,48,48,51,54,50,55,61,67,67,55,62,80,84,102,107,98,97,104,104,120,170,192,187,179,171,171,172,161,148,130,121,121,127,140,137,146,129,103,109,108,43,18,27,9,22,26,17,23,23,23,20,23,25,20,26,23,24,26,22,29,24,25,27,23,23,30,32,29,32,35,39,35,36,41,40,43,47,47,49,48,51,56,58,63,62,66,63,73,66,65,80,94,101,102,119,114,125,147,134,121,134,145,154,141,136,130,135,141,140,147,150,149,147,143,147,152,153,152,154,155,160,146,163,165,167,162,162,160,161,162,160,152,153,159,164,163,158,157,162,162,162,162,154,155,155,155,159,159,158,163,165,160,159,160,160,153,151,155,156,158,155,155,153,150,150,151,151,154,155,155,156,155,147,145,145,152,151,157,151,155,147,135,118,95,90,101,135,157,170,175,174,171,162,150,148,145,146,147,161,112,13,1,9,10,14,11,13,12,13,14,13,12,22,22,16,24,22,19,22,18,24,24,22,21,23,22,24,24,19,24,23,21,26,24,23,24,23,24,22,20,22,19,17,17,18,17,17,17,17,16,19,18,18,17,17,21,18,20,19,18,19,17,17,18,17,18,19,18,18,19,21,17,22,21,20,21,17,20,19,21,17,19,22,19,22,19,17,20,21,27,25,27,27,31,34,28,26,27,31,33,38,35,27,30,32,25,30,29,25,26,25,31,30,35,31,29,36,27,27,29,25,28,27,31,33,29,34,33,29,40,43,41,39,36,41,38,43,48,45,48,53,56,57,57,69,72,69,78,71,70,56,53,55,57,77,76,75,73,73,76,85,100,112,119,126,128,128,127,128,126,129,127,127,127,123,132,130,128,125,128,126,124,124,119,125,125,127,126,125,126,123,131,131,124,125,124,122,123,123,124,128,130,131,135,132,130,128,122,118,118,127,128,130,135,134,136,127,125,124,129,133,128,134,139,138,136,134,130,117,116,122,121,134,132,131,130,129,133,128,127,132,133,129,127,127,126,123,126,129,126,120,118,124,126,125,130,140,145,141,140,127,125,126,129,133,130,132,135,131,123,122,117,122,118,110,113,113,115,126,124,123,122,119,114,113,114,109,112,107,108,111,118,114,117,110,101,106,104,118,128,126,129,139,136,126,113,101,111,130,125,119,120,103,100,116,114,101,105,113,116,128,127,114,98,96,92,76,78,82,83,81,77,81,84,81,77,86,73,78,84,76,67,61,65,67,74,69,60,57,55,53,48,55,47,59,61,55,65,66,68,65,50,53,52,47,49,51,49,51,54,51,53,48,54,50,52,50,45,50,48,56,49,55,53,49,54,51,51,49,52,51,48,51,49,48,47,52,47,47,50,45,46,48,45,44,41,48,46,43,46,46,45,45,46,39,45,48,42,40,49,43,40,51,44,45,40,42,43,40,46,44,44,42,44,46,44,42,40,45,42,38,43,44,39,44,41,39,44,42,42,43,41,41,43,46,42,39,42,38,37,41,37,37,41,40,38,38,39,39,39,40,42,40,36,37,36,38,39,37,39,38,34,36,33,36,42,39,39,38,41,39,38,36,35,44,41,40,39,39,42,34,39,41,42,40,41,37,37,36,36,41,40,44,44,47,49,55,63,59,48,54,58,60,51,46,64,78,79,67,56,61,74,82,103,98,71,76,93,87,92,124,140,146,143,133,124,116,109,103,107,134,165,187,196,177,168,181,184,183,156,64,30,25,13,28,22,27,25,23,31,22,27,26,25,27,26,26,23,28,27,29,29,29,32,29,30,28,31,39,35,39,44,40,41,44,48,53,53,55,57,59,60,62,67,71,68,61,63,66,67,93,123,120,121,133,125,132,149,151,142,154,161,150,139,127,117,121,128,122,133,139,141,142,137,142,149,154,159,161,160,156,153,159,159,159,160,158,159,158,165,167,164,163,163,163,162,165,165,162,162,162,160,162,158,156,156,154,152,151,160,159,159,156,157,163,159,158,160,162,165,163,162,164,160,152,147,146,146,150,156,155,154,150,147,145,144,152,154,151,154,152,153,149,118,92,83,95,122,146,167,173,165,163,152,150,144,147,146,155,111,14,1,9,10,14,11,13,12,13,14,14,14,19,21,23,21,25,19,23,20,21,27,18,23,24,17,24,24,23,23,24,25,21,28,23,18,27,24,21,25,21,19,17,21,19,18,20,18,18,17,19,18,22,20,17,17,22,19,16,19,18,18,21,17,16,18,19,22,19,17,19,18,19,22,19,17,23,21,20,22,17,20,20,22,22,19,21,21,23,27,26,29,31,32,35,28,30,39,43,43,38,41,46,45,44,37,31,30,35,30,31,41,35,38,38,38,34,35,36,28,33,32,34,37,36,39,39,42,36,49,53,47,45,46,45,48,54,59,61,60,54,56,59,70,86,96,110,100,87,99,78,84,80,81,86,99,94,97,89,91,100,109,118,119,122,120,120,117,115,112,107,120,122,121,125,123,127,125,123,127,125,128,126,125,120,121,123,121,128,130,136,135,131,132,131,132,132,131,131,129,131,134,134,134,130,133,130,124,125,128,138,136,136,141,141,142,145,144,136,138,140,138,142,143,148,152,145,129,116,115,125,128,127,131,136,133,124,125,136,137,134,132,135,126,126,127,125,131,133,131,129,125,130,130,138,137,134,134,129,127,125,125,128,133,129,141,134,127,122,127,127,133,137,134,138,139,141,141,138,136,135,136,136,134,120,121,122,123,131,128,129,120,112,107,99,91,93,106,109,107,102,102,111,110,106,95,92,98,94,102,119,119,112,118,122,100,86,96,107,107,113,122,122,94,102,98,90,89,88,93,94,84,81,79,84,87,108,78,74,74,90,77,80,80,69,66,73,57,55,53,55,58,55,63,57,49,49,50,54,53,54,49,52,54,51,54,50,47,47,47,50,49,55,50,49,53,51,50,49,52,50,54,52,55,52,47,49,47,47,45,48,47,47,47,44,50,47,44,46,45,46,46,42,44,43,44,45,46,48,49,43,44,49,47,45,43,45,42,44,43,45,44,41,44,40,44,43,44,40,41,46,41,42,44,47,43,43,41,40,39,41,42,40,42,44,42,42,41,37,39,41,45,42,42,43,42,38,39,40,39,42,39,40,38,37,38,39,42,36,43,39,36,43,37,41,36,35,42,35,42,37,36,37,37,36,32,38,38,36,39,43,38,38,42,38,36,41,36,34,36,38,41,39,38,39,39,35,37,37,36,42,40,44,45,41,48,51,50,51,48,52,53,54,46,48,56,54,59,55,43,52,50,55,73,61,54,44,69,62,57,75,98,106,90,78,60,97,107,102,92,104,122,142,149,129,125,138,167,173,160,92,41,24,17,30,24,27,29,23,29,25,30,27,29,29,22,32,29,26,29,22,30,33,27,29,29,36,35,34,40,41,41,44,41,44,47,49,50,56,57,56,60,62,60,66,63,59,55,55,70,93,114,120,123,124,110,111,139,145,129,144,141,149,141,139,143,140,141,149,153,152,151,148,146,146,155,166,161,160,163,152,151,162,161,158,156,151,150,149,153,159,155,152,153,154,154,151,154,151,157,156,158,164,162,159,152,148,150,149,151,153,150,151,156,157,157,157,163,160,160,161,159,156,158,159,152,147,145,147,149,146,143,146,142,141,145,147,149,145,152,154,151,150,141,122,97,82,89,115,139,157,161,160,153,147,144,144,139,152,109,14,1,10,10,12,11,14,12,12,14,13,13,20,22,19,22,23,22,23,21,24,22,21,18,26,27,22,25,24,24,22,22,22,25,22,24,24,23,24,24,22,18,20,19,18,17,17,19,19,19,20,19,16,19,20,19,15,21,22,17,19,17,18,17,19,18,19,19,16,19,21,16,20,21,18,20,19,18,21,27,17,20,24,19,21,17,24,25,23,17,24,30,27,35,31,32,33,38,40,34,37,38,38,42,43,45,41,33,41,37,35,36,32,36,35,34,36,32,30,34,32,33,36,39,37,39,39,36,40,35,38,43,44,45,44,45,49,49,52,51,51,54,57,55,71,84,95,108,89,93,93,103,113,117,132,125,130,130,125,120,122,118,118,121,118,116,115,110,107,104,106,120,127,126,116,114,110,110,108,118,124,121,123,122,127,130,130,131,133,135,133,139,135,129,128,128,129,127,125,125,130,128,127,128,130,127,127,125,128,137,137,135,124,118,123,131,136,141,139,136,134,133,139,142,143,141,132,129,136,137,142,134,128,127,133,132,133,137,133,128,129,128,127,126,128,133,133,141,141,140,141,139,141,144,140,129,122,121,118,125,129,140,142,137,137,141,141,140,139,135,130,124,125,127,125,135,143,145,147,137,145,144,139,127,124,133,128,129,131,133,112,95,100,101,95,101,111,105,93,90,86,81,86,83,87,80,86,98,92,90,101,118,118,128,130,100,75,64,71,72,75,77,75,83,96,90,93,89,83,86,89,84,72,63,75,81,75,70,60,59,60,50,52,53,50,57,55,53,48,50,54,58,70,62,61,57,53,61,49,63,69,64,68,61,63,64,59,58,63,63,55,50,60,62,59,63,54,54,51,53,55,53,54,49,52,49,47,52,52,45,46,49,48,51,50,47,49,51,49,50,48,50,40,46,53,47,53,51,47,49,47,48,47,47,50,45,44,49,43,45,45,45,48,43,42,47,47,43,44,44,46,44,42,40,42,44,46,40,41,41,42,41,39,40,43,42,38,42,42,41,37,41,42,39,41,36,39,44,43,38,38,40,37,39,36,40,39,40,37,44,44,37,39,39,43,37,35,39,40,39,38,40,36,34,42,34,38,39,38,40,38,39,38,44,43,36,40,35,33,39,36,44,32,35,41,37,43,41,40,39,42,44,48,46,41,47,49,48,53,50,47,49,52,54,54,52,42,45,46,44,51,43,46,50,53,53,51,56,49,36,46,73,81,56,45,66,97,115,108,83,77,77,95,101,85,82,83,115,144,149,108,47,22,19,27,28,29,28,25,30,28,30,32,28,29,28,29,29,27,27,29,29,32,29,36,32,32,37,38,40,34,37,44,44,44,49,48,47,57,52,50,57,59,61,62,67,57,56,59,72,90,102,116,122,116,101,117,132,127,113,116,116,114,132,162,173,164,161,165,173,162,159,153,148,151,160,164,159,158,158,158,162,166,164,160,157,151,152,153,155,157,154,147,147,147,142,144,143,142,147,148,152,160,162,157,153,153,148,146,147,148,149,146,148,151,151,153,153,153,155,153,151,152,153,156,155,152,150,149,150,139,141,143,145,147,146,142,138,142,144,146,144,147,149,137,125,101,89,90,105,132,148,162,158,160,152,147,143,150,108,14,1,10,10,12,11,14,13,13,14,13,13,21,19,22,22,19,19,23,18,20,23,23,23,21,22,24,24,21,21,23,22,25,23,28,24,21,25,27,24,19,19,16,16,19,18,18,17,18,19,19,18,19,20,21,19,20,20,16,17,17,19,19,19,21,18,18,19,17,20,21,20,21,19,21,19,19,22,20,20,25,18,19,23,20,19,23,21,24,24,21,25,27,29,28,24,27,25,23,26,31,24,25,30,29,33,31,32,30,33,33,29,31,35,34,35,28,33,38,32,36,36,36,42,37,42,42,41,41,37,37,41,42,42,43,47,45,47,51,48,48,49,50,56,67,69,75,79,78,85,73,77,101,103,113,106,115,122,126,126,135,132,124,123,122,124,127,131,123,134,135,137,131,128,128,119,117,118,120,125,118,120,116,121,130,131,133,132,130,130,130,130,128,128,129,126,123,125,129,128,131,130,123,120,123,130,127,125,128,131,130,122,118,119,122,132,133,123,126,127,121,117,129,129,129,130,132,140,136,133,131,127,124,129,134,137,133,132,132,131,130,129,127,127,135,141,139,140,135,141,143,144,159,155,153,145,135,143,146,146,149,147,142,144,143,146,138,146,140,139,139,141,139,134,131,130,132,134,139,136,137,125,115,106,103,116,126,120,121,120,111,113,113,119,119,122,112,96,94,111,122,123,113,113,107,99,103,116,101,101,109,111,114,119,116,101,106,111,89,103,95,99,88,88,90,86,90,85,62,76,71,79,48,70,74,74,45,42,64,65,55,47,55,64,68,63,70,70,68,72,78,83,77,83,78,75,80,76,68,100,87,81,80,69,83,77,81,92,90,84,73,62,65,75,74,69,60,50,56,57,51,51,55,51,47,49,52,50,51,51,51,49,55,51,46,53,48,54,53,55,55,51,53,50,54,54,51,52,53,53,51,46,42,51,48,53,50,36,46,44,46,44,43,46,45,47,41,46,43,42,44,41,44,44,45,42,42,39,40,39,40,43,41,39,33,44,42,42,43,38,38,38,37,40,41,39,40,39,41,38,37,41,37,40,43,34,40,39,35,42,36,34,46,37,36,36,33,44,38,38,39,40,38,37,41,33,38,39,39,39,37,40,42,38,38,40,35,35,42,38,35,36,37,35,37,39,37,38,41,46,41,41,44,43,50,48,50,46,50,48,52,69,68,69,63,52,45,46,53,54,52,48,54,55,52,60,66,67,65,46,60,64,88,81,71,79,87,98,104,95,103,93,97,94,92,82,66,83,102,115,94,44,28,26,27,28,33,31,29,30,29,34,30,30,30,24,28,32,33,31,26,35,29,29,33,33,37,30,37,36,33,42,37,42,44,37,46,44,48,47,50,55,55,57,57,66,54,53,55,64,78,96,109,123,121,117,128,134,131,124,118,116,123,139,160,164,163,171,172,161,148,148,143,146,153,154,155,149,158,159,158,160,162,161,160,163,157,150,152,151,154,154,150,150,152,149,154,155,152,156,155,152,159,159,163,163,159,154,145,143,154,152,145,146,143,142,148,151,153,155,152,152,148,144,149,149,150,151,150,152,141,141,148,147,150,148,144,143,142,144,144,143,136,137,141,143,131,112,95,83,102,125,144,155,161,159,154,146,154,108,14,1,9,10,13,11,13,12,13,14,13,14,21,21,17,23,22,20,21,21,19,20,18,21,25,24,27,20,24,21,21,29,23,24,24,26,22,23,26,21,20,17,17,18,17,19,21,17,20,17,17,20,18,19,19,20,19,19,19,18,21,20,17,19,19,19,20,19,18,21,24,20,17,22,23,20,22,18,22,22,21,21,17,24,22,20,29,21,22,22,23,24,23,23,21,25,21,24,27,27,27,22,23,27,32,24,26,32,30,29,27,31,30,30,34,34,34,29,29,32,35,37,39,42,40,43,45,43,46,46,44,43,45,44,44,46,46,46,48,45,46,46,46,53,66,59,63,69,74,91,87,95,93,91,93,87,95,103,119,134,141,141,137,137,128,132,141,139,141,141,137,137,132,130,130,127,134,144,144,142,138,136,139,134,132,127,127,133,132,133,128,128,124,124,130,134,140,139,143,142,146,144,134,132,134,137,136,128,126,122,115,116,116,123,132,136,135,131,135,130,131,131,129,125,121,129,134,135,130,119,127,135,141,143,144,134,135,141,145,141,130,133,136,137,141,149,141,137,134,141,148,140,142,144,147,146,146,151,144,146,142,134,134,130,131,132,131,131,132,136,141,144,144,141,134,128,127,125,132,127,133,130,125,122,123,127,120,125,119,125,133,143,144,138,141,144,136,126,124,139,141,136,143,148,141,122,123,134,129,114,98,100,101,100,94,90,100,98,105,108,122,124,103,97,93,93,98,93,95,99,94,83,91,89,82,77,73,81,79,79,79,72,73,76,86,95,101,94,89,90,92,81,77,76,81,64,64,83,76,77,57,61,72,71,82,72,78,89,90,88,86,67,64,67,68,69,61,57,60,58,47,54,53,49,51,49,55,46,53,54,50,54,49,57,50,54,53,48,53,51,55,52,52,50,54,50,53,48,50,53,46,48,46,43,46,45,44,42,42,46,48,49,46,45,42,46,43,46,43,39,46,41,46,46,42,42,41,43,43,40,42,40,42,37,41,41,39,39,39,41,37,42,37,41,45,39,46,41,37,40,41,39,36,40,39,41,36,37,41,37,41,38,41,38,37,42,33,37,41,41,39,33,39,38,36,35,41,39,35,41,36,41,44,37,40,41,39,39,39,41,36,36,38,41,39,37,40,41,39,42,41,40,39,44,51,44,46,47,47,45,59,62,56,65,59,55,48,49,61,65,54,59,60,53,66,71,81,95,81,73,73,71,95,102,93,84,69,78,96,104,106,92,93,85,87,86,59,60,65,83,80,45,35,27,26,32,32,29,30,34,32,30,32,30,33,29,32,34,30,32,31,29,31,31,31,32,32,35,37,36,36,39,41,42,41,43,44,41,47,47,48,51,50,57,57,61,56,53,53,62,70,68,99,116,120,127,132,125,130,139,129,125,138,149,150,149,157,164,153,146,137,145,152,155,154,152,151,147,152,158,160,156,155,154,158,165,161,155,153,158,159,164,162,159,157,153,162,169,163,158,155,154,152,155,160,163,168,168,162,152,155,156,150,151,148,150,153,153,157,160,162,162,160,157,155,150,149,145,146,151,148,151,149,150,150,149,151,150,146,149,145,139,139,137,139,146,146,136,114,88,85,94,122,142,161,162,162,153,158,112,14,1,9,10,13,11,13,12,13,14,14,14,18,21,20,26,24,22,21,23,24,17,22,22,22,22,21,24,25,22,24,24,24,27,24,28,24,24,24,18,22,19,19,18,21,22,17,19,17,19,17,19,18,19,22,19,18,20,19,22,21,18,21,19,20,19,20,18,20,21,19,21,21,19,23,23,19,23,19,26,22,21,25,18,21,22,23,21,24,23,23,21,21,22,22,27,24,26,30,25,29,27,33,30,29,32,31,35,33,39,34,28,39,38,33,35,36,39,39,44,45,39,54,46,50,54,47,50,52,52,56,54,50,57,49,56,53,45,55,51,55,53,67,70,77,76,88,84,82,89,110,111,107,92,92,90,91,86,99,110,117,120,123,125,122,127,125,127,128,127,130,131,125,123,133,135,143,147,145,139,128,137,136,130,133,125,127,130,124,122,123,123,118,127,120,133,136,147,151,153,153,152,138,149,134,139,134,133,130,129,123,127,128,131,140,141,137,139,131,136,134,131,136,128,131,131,131,130,125,132,139,139,139,142,149,145,141,147,145,137,141,137,132,129,132,125,129,124,128,130,122,124,121,122,130,132,136,125,128,127,122,120,106,107,109,119,124,125,119,115,127,135,126,144,135,118,115,122,132,113,127,134,131,132,128,121,122,119,120,123,131,151,131,122,131,130,131,126,120,124,126,136,139,133,128,126,126,120,113,99,95,94,91,89,80,79,61,87,90,86,85,102,83,85,82,88,114,78,106,98,104,108,102,94,68,65,78,72,84,67,73,69,66,66,70,80,89,75,70,72,73,50,51,60,53,54,52,67,53,49,55,57,58,60,66,62,61,65,72,70,70,57,59,64,65,70,62,62,58,64,71,61,57,49,50,53,52,56,48,49,53,45,50,49,50,50,45,49,44,48,50,48,50,49,43,51,47,42,47,45,48,45,43,46,42,46,44,44,49,43,43,47,49,44,44,44,42,46,41,47,44,39,46,39,44,44,39,45,44,41,40,42,38,46,38,39,42,36,41,38,42,42,38,42,38,40,40,38,44,37,41,42,33,39,39,36,41,39,37,40,35,41,38,39,41,37,40,40,42,34,41,44,37,40,40,42,41,41,39,39,43,40,44,44,39,41,38,44,41,39,41,38,43,39,42,40,40,40,37,42,40,39,41,40,42,46,43,44,46,45,44,45,47,52,49,47,50,55,63,60,54,57,61,59,67,67,74,88,71,63,66,69,80,80,81,85,68,65,73,78,84,55,54,60,61,63,54,50,55,66,65,48,37,24,32,34,29,29,35,29,31,36,30,32,31,29,29,28,30,34,33,30,30,34,32,31,35,29,38,33,30,42,38,41,42,39,44,45,46,48,48,50,55,54,59,60,64,58,59,73,79,68,77,80,96,107,105,104,111,132,146,122,132,141,133,134,133,148,145,147,147,153,157,163,154,149,148,145,147,151,153,152,153,148,154,159,159,159,156,148,152,155,153,157,154,156,159,162,162,155,151,148,151,148,152,153,154,155,158,154,152,150,147,151,151,150,153,152,158,155,160,157,158,159,159,158,155,152,147,151,147,149,152,145,148,150,149,147,147,149,147,148,141,144,142,143,145,139,129,106,86,75,90,115,141,152,160,160,163,111,14,1,10,10,12,11,14,12,13,14,14,13,21,22,20,19,19,19,26,23,19,23,21,24,19,27,26,19,24,27,21,19,24,29,25,23,22,23,24,21,23,19,18,18,17,20,20,17,19,18,17,21,17,23,21,21,20,16,21,19,17,20,22,18,18,19,21,20,21,19,23,23,22,21,21,23,21,21,19,19,24,21,23,22,19,25,27,18,24,22,21,24,23,22,25,30,28,34,29,28,37,30,22,27,30,31,38,27,34,33,29,34,37,37,38,42,43,46,45,47,50,49,52,53,57,56,53,55,51,56,56,51,48,46,51,53,57,54,61,67,79,88,94,92,92,97,97,91,81,77,80,93,89,89,84,80,81,79,87,92,100,105,114,132,133,131,132,125,130,124,125,127,127,126,130,134,130,129,120,120,117,114,122,122,125,122,121,126,122,131,128,134,135,131,137,134,133,127,131,133,131,134,140,141,132,127,127,134,136,136,136,137,141,139,143,139,134,131,131,128,121,127,132,131,128,127,122,125,132,131,137,135,142,145,147,149,139,130,130,135,134,131,123,120,126,138,137,131,125,123,119,115,117,128,137,131,127,122,124,133,127,118,117,118,126,129,122,118,110,109,116,130,145,150,139,125,125,113,105,97,105,112,110,108,110,106,100,117,125,136,137,129,115,105,107,106,124,124,117,124,122,131,131,124,114,93,87,92,96,98,100,98,96,94,81,84,92,88,83,68,76,80,71,75,69,78,71,54,57,60,73,78,96,83,55,55,49,62,57,53,65,64,66,70,69,75,72,64,67,64,61,60,61,57,58,58,57,58,54,62,57,55,62,60,60,57,53,56,57,55,55,50,56,54,61,65,61,60,61,64,61,62,55,59,56,55,53,54,53,47,56,50,49,49,48,54,51,46,46,45,44,46,52,42,46,49,47,45,46,46,48,50,46,51,50,45,47,48,50,44,44,49,48,45,48,47,44,44,42,46,42,41,46,43,39,44,46,45,45,47,40,38,46,43,39,42,39,42,45,39,43,44,39,41,41,38,43,39,40,46,37,42,41,43,41,42,45,39,44,41,45,43,38,45,43,43,45,46,48,42,44,46,48,47,46,43,45,45,43,47,43,40,38,42,42,40,39,43,39,39,38,37,39,39,42,40,36,39,39,41,45,42,44,43,40,43,46,44,45,49,50,48,55,60,48,47,54,61,61,55,54,57,57,53,57,62,62,65,58,53,62,67,66,57,73,93,80,64,58,60,71,63,59,45,48,61,53,57,51,51,53,50,41,32,34,32,34,35,35,35,31,34,33,32,32,29,37,35,33,34,32,35,29,34,36,32,32,33,39,33,37,41,36,44,44,43,43,42,47,49,48,52,53,57,62,65,67,64,63,80,86,67,61,67,78,90,98,87,96,125,130,118,127,139,127,127,139,146,145,154,162,164,171,170,153,146,143,143,145,145,145,145,152,148,149,148,145,146,147,150,149,153,154,150,152,151,157,165,165,160,159,159,158,154,149,146,140,141,151,150,151,148,148,154,155,152,150,155,157,157,153,150,153,150,155,160,163,154,150,153,153,158,156,155,156,153,152,148,139,141,142,139,144,147,146,147,143,144,141,132,115,91,81,79,103,126,149,152,167,117,12,2,10,10,13,11,14,12,13,14,14,13,22,19,21,23,20,22,20,21,22,20,25,23,22,25,25,24,21,25,24,23,21,24,25,22,25,26,25,19,19,19,21,20,18,18,17,21,19,19,18,20,20,17,17,21,20,17,19,22,19,19,23,19,17,21,19,18,21,22,17,21,21,18,21,21,20,20,21,24,24,19,23,26,24,20,21,21,20,23,21,26,29,24,24,27,22,29,31,27,29,29,32,26,25,26,30,27,25,34,29,36,31,29,34,41,39,42,48,48,50,54,55,50,61,55,56,53,46,49,44,49,57,56,49,48,49,55,73,88,85,99,86,87,83,85,84,82,76,75,82,83,79,95,76,97,93,100,104,111,116,120,123,128,131,138,140,139,134,132,129,129,126,123,127,126,129,125,125,122,121,129,134,134,139,138,139,137,134,131,137,135,141,141,141,140,125,129,128,118,118,129,117,137,122,112,108,120,129,122,129,135,137,132,131,129,127,118,121,135,131,137,132,141,140,137,140,141,134,133,141,142,135,127,120,134,129,121,136,138,139,129,123,132,130,133,132,147,132,137,134,137,137,139,135,132,130,131,139,142,145,137,130,128,122,122,123,124,122,119,120,125,132,137,132,133,128,121,117,116,125,124,127,127,114,122,136,133,133,142,132,122,114,109,123,129,127,125,131,117,123,122,129,133,127,108,116,122,126,128,129,120,136,137,132,120,122,117,112,96,96,94,91,97,92,77,80,68,69,70,74,94,95,93,84,72,67,80,77,76,93,102,101,95,91,81,91,83,84,86,65,79,56,59,66,69,76,77,69,66,59,55,57,60,55,58,60,54,53,51,54,54,51,51,55,63,58,59,53,52,54,57,61,59,60,58,55,60,60,55,57,53,51,51,53,52,52,53,49,48,50,47,48,47,46,49,48,47,47,47,42,50,49,47,53,47,47,47,46,47,46,49,45,46,48,48,43,45,43,43,45,44,47,41,43,45,45,45,45,45,40,39,43,41,43,43,43,42,40,40,41,42,39,44,43,36,43,49,43,40,44,42,42,44,40,44,40,40,40,40,43,41,42,46,43,42,46,44,46,45,43,42,43,46,47,42,47,44,41,39,39,41,42,41,40,41,41,41,43,37,37,38,37,39,39,41,41,36,39,41,36,40,41,37,41,44,47,48,53,48,52,54,53,57,46,48,53,53,58,56,50,51,53,51,52,58,59,59,52,49,64,70,66,68,84,90,87,85,75,91,86,76,84,56,48,63,57,57,47,51,48,39,43,36,32,34,29,34,36,31,36,33,35,36,35,35,31,29,39,39,35,30,33,34,39,36,36,38,37,37,37,42,39,42,48,41,43,43,45,51,49,54,50,53,57,56,61,60,60,63,63,62,59,57,65,86,101,95,94,127,144,130,140,152,138,137,145,149,155,160,162,168,174,169,161,154,149,144,158,158,162,158,160,160,158,146,139,138,152,157,159,158,152,139,137,144,157,162,168,165,162,164,159,157,158,157,148,144,140,145,150,151,149,155,155,148,147,150,152,149,143,141,139,145,148,152,152,154,153,152,157,157,154,154,158,153,150,144,141,146,141,139,139,140,142,142,146,147,152,154,145,126,96,79,83,93,125,143,162,114,14,2,10,11,13,11,13,12,13,14,14,14,19,19,17,21,20,19,24,19,21,19,22,24,27,31,24,22,25,21,27,19,24,28,25,26,25,25,19,20,20,19,20,16,17,18,16,24,18,19,23,17,23,18,17,22,22,18,16,22,19,20,23,17,21,20,21,19,20,22,17,19,19,19,25,24,18,21,19,24,24,17,27,21,19,27,22,23,24,29,27,28,35,24,25,28,24,26,27,27,27,32,24,27,32,26,29,29,30,31,32,31,27,33,30,35,35,41,46,38,50,45,44,51,49,53,56,56,59,63,64,70,76,79,81,78,77,81,87,84,87,72,74,82,77,79,79,84,80,80,86,91,103,114,121,121,123,125,122,126,128,125,120,115,115,111,118,119,125,125,124,125,126,131,126,131,137,139,151,152,145,142,146,146,153,155,145,141,130,131,125,123,124,122,130,129,129,127,128,133,132,128,135,140,141,133,120,117,126,131,131,135,135,128,127,131,132,133,137,145,144,149,145,139,146,147,151,148,151,149,145,139,134,131,122,129,129,132,141,142,137,136,130,125,135,126,122,107,107,126,134,133,119,118,123,127,141,142,146,146,144,142,138,136,125,131,136,143,137,123,128,122,121,123,125,129,130,129,127,139,144,135,137,132,134,139,145,148,136,131,120,120,129,148,146,130,131,128,124,116,114,131,140,138,141,142,150,153,154,150,132,136,146,155,148,146,141,135,133,120,117,108,112,119,113,103,96,89,101,84,71,80,90,100,87,84,80,87,93,97,101,99,88,80,78,69,72,80,87,74,65,60,55,59,61,71,71,61,71,68,63,71,66,59,52,61,70,73,63,59,57,58,53,53,59,54,50,50,56,48,51,52,56,59,48,57,56,51,51,55,50,48,54,51,53,45,53,54,52,51,49,51,51,51,49,49,45,51,52,45,46,48,45,48,44,45,47,43,43,48,46,44,45,41,45,43,45,44,42,43,42,49,47,43,42,42,47,46,46,45,44,44,48,43,43,43,43,43,40,42,43,44,46,49,43,42,43,41,41,41,34,40,41,41,42,37,40,38,42,41,41,41,39,46,40,41,41,43,41,42,42,40,43,43,43,41,44,43,40,42,41,40,40,36,42,41,36,43,38,39,38,36,42,36,40,38,35,43,41,40,42,36,40,42,43,45,46,54,46,46,42,46,49,40,44,44,41,45,47,45,50,45,51,49,52,57,61,63,53,55,67,72,64,60,77,81,89,101,88,90,94,84,72,48,55,68,53,48,49,48,44,45,43,38,29,32,38,35,37,36,37,31,38,36,35,42,34,33,36,35,37,39,32,34,40,35,37,33,38,41,39,39,43,45,45,43,45,47,46,50,52,55,57,51,53,55,53,55,57,53,54,52,59,53,52,80,97,89,92,129,154,138,148,160,145,143,146,154,164,165,161,159,171,179,172,166,160,166,174,170,173,177,175,170,166,160,152,154,161,165,170,166,154,136,137,148,157,159,162,161,159,159,161,164,167,169,157,151,151,150,153,154,154,154,155,151,146,150,152,152,144,136,142,145,146,147,153,153,151,151,150,152,152,155,154,155,154,151,152,152,150,147,141,141,141,142,145,144,149,152,157,151,135,109,91,81,95,112,143,112,16,2,10,10,14,12,13,12,13,14,14,14,19,19,21,19,19,21,21,21,20,23,24,19,25,23,22,25,22,24,23,21,23,25,25,19,24,26,21,24,20,19,16,19,21,16,17,20,18,19,21,18,19,18,22,22,21,20,21,20,18,22,20,20,22,22,24,22,22,27,22,22,25,21,21,21,24,22,27,25,20,21,20,28,19,22,28,26,22,22,23,24,30,24,27,25,23,32,28,28,31,29,27,29,31,33,35,29,34,36,36,36,30,33,41,38,45,47,47,48,51,50,45,49,47,53,60,77,103,114,77,117,108,105,103,103,78,108,74,70,75,65,95,85,117,96,94,97,96,96,108,121,131,132,130,128,123,128,123,120,120,121,121,120,126,121,117,121,122,125,126,130,133,140,143,145,145,146,142,147,142,134,127,119,116,124,126,130,135,130,128,119,118,122,130,133,128,132,141,135,146,148,156,162,141,157,153,152,143,136,141,146,141,139,137,138,149,151,153,155,151,148,138,146,150,143,137,132,136,142,143,137,139,141,143,139,130,128,132,130,131,131,130,135,139,113,128,120,131,133,134,135,132,137,141,141,142,141,143,141,137,139,138,136,136,141,152,140,141,150,148,145,143,138,134,131,132,136,141,140,128,123,115,121,119,132,147,136,121,117,111,117,125,125,122,117,118,122,119,124,131,117,115,116,129,136,137,128,122,122,127,122,120,123,117,114,108,104,104,93,96,91,93,90,90,94,98,88,96,85,69,70,68,66,72,77,77,80,82,82,72,78,69,44,65,50,52,48,50,53,53,56,50,60,60,52,57,60,62,69,66,63,66,59,54,59,64,68,76,66,64,61,57,60,55,54,51,46,53,56,52,57,54,57,53,47,51,48,50,53,50,49,49,46,48,50,51,52,47,53,50,47,53,53,51,47,50,52,48,48,50,47,42,45,43,41,41,46,48,42,42,46,45,45,44,43,44,43,45,42,46,40,47,46,44,43,43,45,44,46,45,49,47,43,44,44,41,41,47,44,42,41,45,44,42,42,40,42,42,40,42,42,39,41,41,41,39,42,42,39,37,38,41,36,39,41,37,39,39,36,39,42,38,36,42,42,42,38,38,41,36,35,38,37,33,38,37,36,39,36,42,42,41,40,37,41,34,42,43,39,42,48,47,41,43,43,44,47,44,44,47,41,42,46,42,46,42,50,53,45,46,45,51,56,62,61,57,57,57,58,66,63,66,72,84,76,77,79,57,56,63,58,56,54,56,61,56,55,45,45,42,35,42,42,34,32,34,36,37,35,34,36,39,34,39,36,35,35,33,41,37,38,36,39,36,34,37,38,37,39,41,43,43,44,46,43,48,45,48,50,49,55,56,52,53,53,51,53,53,55,60,51,58,61,55,71,82,75,78,116,137,121,134,147,140,143,147,151,164,163,150,145,157,174,177,171,161,163,164,167,173,170,173,160,164,163,160,160,159,160,165,163,157,151,148,149,156,158,157,153,152,148,150,161,159,158,157,151,149,152,154,155,153,149,154,155,153,153,151,153,147,142,146,148,149,151,148,151,150,141,148,149,147,151,149,151,153,152,150,151,150,145,146,141,140,142,137,143,139,144,147,147,147,132,119,90,82,87,111,103,19,2,12,10,14,11,14,12,12,14,14,13,20,17,23,19,19,19,19,22,24,21,18,25,24,22,22,24,24,18,22,22,23,24,24,30,28,21,23,24,20,20,16,17,19,19,17,19,18,19,21,19,23,15,19,22,19,22,17,23,22,16,21,22,19,22,22,24,20,19,27,21,25,24,26,24,20,29,22,24,24,25,22,24,27,24,29,29,24,25,26,27,26,24,29,25,25,25,29,26,28,33,29,31,31,36,31,23,35,30,30,30,34,34,33,36,42,45,45,48,48,51,52,54,53,59,66,70,70,69,76,71,71,66,65,68,69,62,53,51,59,55,65,79,87,102,101,105,110,115,133,139,141,134,134,131,131,129,125,122,121,124,124,131,136,136,138,133,133,128,132,135,136,143,138,143,143,133,130,125,113,111,114,114,121,129,127,135,132,130,130,133,134,137,141,136,140,141,135,137,138,136,136,132,135,142,149,147,151,149,141,136,131,130,127,131,133,131,131,135,143,153,152,155,155,142,134,127,129,127,122,124,130,130,127,127,130,137,129,130,129,136,140,131,145,136,141,144,150,149,136,138,141,144,144,140,136,130,140,141,138,141,143,142,133,135,132,137,144,147,152,147,137,126,132,137,146,153,148,145,136,126,135,141,148,150,145,144,143,145,145,136,117,101,94,99,101,107,119,128,118,101,93,88,93,111,118,96,84,100,108,105,92,92,87,85,80,80,84,73,85,81,69,67,74,88,102,92,97,97,81,76,61,56,60,73,81,78,75,78,69,66,61,51,61,48,46,43,47,55,57,55,57,59,55,58,59,50,50,54,55,64,66,63,57,59,54,62,66,58,57,57,59,61,60,57,54,57,59,57,62,56,61,59,54,55,54,61,63,63,65,59,60,59,60,60,53,47,53,54,52,53,52,51,51,53,51,51,50,53,45,49,48,45,50,47,44,46,47,43,48,48,45,46,47,44,43,43,42,43,42,44,44,44,39,41,45,44,46,36,39,42,41,45,42,43,44,45,43,43,40,41,47,42,44,42,47,41,41,47,42,44,42,47,45,43,42,39,43,43,41,39,35,44,43,40,39,39,39,37,41,39,41,40,37,39,43,40,43,41,33,40,39,41,42,37,41,42,40,40,40,47,43,43,46,41,38,45,49,41,47,45,46,47,44,49,50,46,47,53,56,49,49,47,45,47,55,62,63,57,52,55,55,59,69,61,50,60,57,58,63,54,69,87,93,76,66,59,50,57,56,55,64,60,56,56,49,56,48,42,48,50,45,42,39,37,32,35,40,33,35,38,34,37,39,40,33,36,41,45,40,38,37,37,38,34,42,37,37,40,46,46,39,44,47,47,44,49,48,41,56,54,55,56,53,55,55,57,51,61,69,54,71,66,63,66,57,59,67,105,123,108,118,130,136,145,141,145,160,160,139,131,144,155,168,172,159,149,151,154,160,158,152,150,152,159,156,157,155,153,160,159,160,153,149,154,154,150,149,146,142,143,147,143,141,146,145,151,151,154,158,159,160,157,162,165,160,156,155,154,152,150,149,152,150,148,153,155,158,155,152,153,154,154,149,149,151,151,151,153,151,150,151,145,146,142,142,144,141,139,142,142,144,144,136,117,92,75,86,86,23,3,12,10,14,12,14,13,12,14,14,14,20,19,24,21,19,22,17,20,23,19,21,27,24,22,25,29,24,19,21,24,27,24,25,23,25,31,24,24,19,17,20,19,21,18,21,19,17,24,19,19,22,17,24,19,19,27,20,19,19,23,27,17,24,23,23,22,24,24,17,21,24,23,26,23,22,25,22,23,23,25,21,24,25,28,26,23,32,29,26,29,26,25,36,35,34,33,30,36,33,33,34,33,31,33,33,32,38,33,32,38,35,36,35,42,45,41,45,47,50,52,55,51,52,55,56,55,53,54,56,53,53,48,55,52,67,51,44,44,41,51,44,51,60,76,94,96,113,122,124,132,136,136,146,149,157,160,144,148,145,150,150,145,144,139,141,143,139,139,139,137,131,134,127,130,129,127,132,122,122,122,124,133,141,142,135,130,135,141,148,148,148,144,141,141,141,141,135,130,127,122,120,121,126,131,135,139,139,135,136,141,140,141,135,129,122,116,118,122,131,142,147,148,145,142,141,143,143,141,132,130,139,138,136,139,144,143,145,141,142,144,143,139,132,131,133,139,144,137,130,127,121,124,128,123,131,134,142,148,145,148,142,135,130,127,127,131,129,135,139,131,127,128,125,129,138,131,142,145,151,154,150,148,133,128,141,145,134,127,127,124,119,112,118,118,113,122,128,122,111,114,120,114,104,98,86,96,84,77,92,92,99,99,90,86,92,101,101,92,107,108,103,110,94,106,95,82,82,79,109,89,71,60,52,51,59,62,65,71,73,69,68,77,77,72,60,65,74,75,70,64,62,65,63,62,59,55,60,60,56,56,58,55,50,63,61,54,60,54,59,52,58,60,61,61,54,59,60,57,55,55,59,52,50,54,50,55,56,57,62,59,55,55,61,56,53,54,51,49,51,55,55,53,51,51,47,51,51,47,50,52,47,51,50,47,49,50,49,48,45,46,47,47,46,41,46,43,40,45,46,41,45,44,42,42,42,43,40,45,40,41,44,38,48,42,40,42,39,45,42,42,44,39,40,39,40,40,39,38,43,44,41,40,46,41,38,40,40,42,39,39,43,42,41,45,42,38,41,39,37,39,43,39,41,42,44,45,36,42,41,42,46,46,46,43,41,50,46,43,44,44,47,45,42,43,44,43,44,43,43,46,44,49,49,45,50,50,50,49,50,49,53,54,50,58,51,59,61,54,55,47,52,58,57,50,50,49,56,55,50,51,59,70,76,66,59,50,56,53,56,67,63,57,56,61,58,59,57,47,48,45,42,39,36,37,38,34,33,37,37,37,36,38,38,39,35,41,38,38,39,37,41,35,33,42,38,36,39,43,41,39,42,41,42,42,45,47,45,44,47,49,45,47,57,47,51,54,55,58,73,64,76,72,80,80,74,73,94,128,130,113,122,125,132,139,134,141,160,167,153,138,141,141,164,171,155,147,144,147,151,148,146,149,138,148,152,146,151,154,157,153,148,153,151,149,148,147,141,141,144,144,145,149,143,143,148,148,150,156,159,160,162,158,157,163,163,157,157,160,152,149,148,148,149,150,151,153,154,154,156,153,151,155,150,151,150,148,153,153,151,153,152,148,148,151,146,146,139,145,142,143,150,143,145,131,115,96,80,71,23,4,12,11,15,13,13,14,13,14,14,14,21,23,21,21,20,23,22,21,22,24,26,19,24,26,24,23,24,27,23,28,27,23,24,29,23,29,29,24,23,15,19,17,19,20,17,22,21,19,18,20,20,18,23,20,22,21,19,24,18,21,25,23,23,23,21,19,24,21,22,25,24,24,23,26,23,21,22,27,30,21,25,22,21,27,27,26,25,31,30,34,38,39,39,45,41,37,39,36,39,36,37,42,38,41,40,42,39,39,45,36,41,47,44,41,46,45,45,50,50,51,53,49,56,50,44,44,45,53,50,47,44,43,53,64,79,68,74,68,63,59,48,50,54,77,95,101,103,99,104,114,122,122,127,131,141,151,157,150,146,137,128,130,126,137,139,135,134,131,139,135,128,129,122,125,130,130,132,132,132,134,136,139,137,137,137,137,137,142,147,147,142,141,141,143,139,137,136,133,136,132,132,136,137,137,131,129,128,131,130,135,134,134,128,128,129,122,120,117,122,127,129,133,129,130,133,137,144,146,147,139,146,150,151,149,148,150,140,140,137,142,136,129,141,137,145,146,145,139,128,130,131,137,140,142,143,141,141,137,143,147,141,131,124,132,130,124,122,121,126,141,142,128,122,117,113,110,114,120,118,113,110,102,97,97,96,93,89,90,83,86,103,128,138,130,124,124,124,127,129,142,150,135,128,127,125,111,99,98,104,113,116,114,100,95,111,125,117,108,126,133,129,121,109,104,84,64,56,50,74,95,82,72,71,64,64,59,64,76,73,72,73,68,95,90,88,88,83,77,64,59,54,61,59,65,73,79,73,63,51,54,60,63,64,66,58,54,55,47,54,54,51,55,63,53,52,57,52,51,56,55,47,50,53,53,53,53,53,51,57,53,51,50,54,50,51,55,49,52,53,53,48,52,57,49,48,51,49,53,52,50,50,48,50,54,53,49,47,52,46,49,51,48,44,42,48,53,43,46,50,48,47,48,49,48,46,47,44,41,48,45,43,42,44,39,43,41,40,45,43,40,39,39,36,44,37,41,42,41,44,39,45,45,45,47,43,42,46,42,48,46,43,39,38,46,39,42,41,35,43,38,39,38,38,45,41,43,40,42,49,43,44,46,44,45,40,44,45,46,43,44,45,46,43,40,46,43,44,45,45,47,41,45,49,48,49,50,49,49,48,51,52,53,53,54,50,44,54,54,48,48,45,49,48,52,47,47,47,48,51,46,48,51,58,54,55,57,50,53,59,60,55,54,53,59,60,58,53,53,48,44,41,38,37,37,38,34,33,35,39,35,37,39,36,39,37,36,39,41,36,36,39,36,39,39,39,39,39,42,41,39,41,44,42,44,48,42,42,42,45,49,44,46,49,53,53,55,49,60,81,78,84,78,91,100,102,121,126,137,138,128,141,132,131,136,132,146,166,179,171,150,144,148,164,171,159,150,152,151,153,156,153,151,145,151,147,141,150,153,157,150,148,153,151,151,158,153,148,148,148,152,160,164,160,160,159,161,156,156,155,158,163,155,155,158,157,161,166,163,160,164,160,155,153,152,158,154,159,162,158,155,152,150,148,149,149,146,145,144,148,146,145,145,144,146,146,146,146,148,150,146,147,150,148,142,138,123,99,77,21,3,11,11,14,12,12,13,13,14,14,13,23,23,22,23,21,21,20,23,23,25,26,22,25,24,24,24,26,29,26,26,24,25,26,24,28,22,23,29,21,21,24,19,19,19,21,23,19,21,22,19,21,24,26,24,19,24,24,22,24,20,23,25,21,24,25,23,23,26,27,24,25,29,27,25,28,28,30,27,31,27,25,29,29,26,29,24,27,31,26,33,31,34,32,32,37,33,36,40,42,41,39,43,50,41,46,46,49,53,45,51,55,53,53,65,73,74,84,78,76,81,92,110,112,119,127,131,134,137,130,126,115,110,108,88,93,80,80,83,89,104,105,107,96,98,96,91,94,92,96,94,99,99,102,98,89,97,101,107,114,118,128,134,136,139,135,137,131,135,142,140,148,148,149,145,137,137,139,139,136,139,141,141,137,134,141,136,137,139,136,135,138,136,136,141,147,153,151,139,133,136,134,139,143,142,134,137,143,150,155,150,148,148,147,146,152,150,146,151,155,154,148,146,148,154,158,160,152,145,145,136,138,125,124,127,120,125,121,131,134,137,139,139,137,130,131,129,129,127,134,146,147,155,157,157,156,155,158,140,126,122,132,145,151,155,153,153,151,147,131,121,131,134,141,152,150,145,145,155,156,149,141,134,145,154,149,142,140,144,142,136,122,120,126,124,131,131,131,134,121,106,115,119,124,132,120,108,115,132,137,129,130,131,132,134,127,124,127,131,130,122,112,96,96,113,120,125,138,128,112,83,69,82,93,101,100,101,102,97,102,106,95,81,85,76,66,53,49,63,65,72,71,66,59,70,66,61,65,66,76,81,78,78,72,71,63,64,79,80,87,79,72,62,73,69,55,55,50,51,55,50,51,50,49,57,51,53,52,45,48,47,51,48,48,53,53,47,51,55,41,46,53,47,49,49,45,49,49,51,53,49,51,54,51,51,48,51,52,52,53,53,55,56,53,47,49,49,55,53,53,46,50,50,50,50,53,49,45,50,51,44,49,47,44,46,45,46,41,48,44,44,45,46,44,43,43,43,45,43,46,44,45,42,48,45,45,51,42,43,42,43,46,45,44,45,43,41,41,46,43,43,49,45,42,42,46,49,45,45,45,46,45,41,44,47,43,43,46,44,44,45,46,47,42,45,42,38,46,45,47,45,50,47,41,44,49,45,46,46,46,49,43,47,46,42,44,47,45,46,48,47,48,47,45,48,48,48,49,51,47,48,54,50,54,51,56,53,50,59,53,55,56,58,56,49,51,48,49,49,50,45,39,43,42,38,41,41,41,39,39,40,40,37,36,38,42,37,40,41,38,42,38,42,39,40,44,37,42,39,44,46,41,40,46,51,41,45,48,45,50,43,48,48,49,54,56,63,61,74,69,62,77,78,87,91,99,119,113,101,93,113,146,135,139,147,153,162,162,163,168,172,174,159,151,157,165,165,163,164,160,160,160,160,158,162,162,162,170,163,165,164,155,159,152,145,152,158,162,159,152,155,155,152,151,150,156,160,158,158,150,148,155,157,152,144,142,146,148,151,148,149,148,146,152,150,151,150,152,152,149,149,148,149,147,154,155,147,146,143,141,139,134,141,139,139,137,129,130,131,131,134,136,139,144,141,145,139,143,105,15,1,10,10,13,12,14,12,13,14,14,13,23,23,22,23,21,21,20,23,23,25,26,22,25,24,24,24,26,29,26,26,24,25,26,24,28,22,23,29,21,21,24,19,19,19,21,23,19,21,22,19,21,24,26,24,19,24,24,22,24,20,23,25,21,24,25,23,23,26,27,24,25,29,27,25,28,28,30,27,31,27,25,29,29,26,29,24,27,31,26,33,31,34,32,32,37,33,36,40,42,41,39,43,50,41,46,46,49,53,45,51,55,53,53,65,73,74,84,78,76,81,92,110,112,119,127,131,134,137,130,126,115,110,108,88,93,80,80,83,89,104,105,107,96,98,96,91,94,92,96,94,99,99,102,98,89,97,101,107,114,118,128,134,136,139,135,137,131,135,142,140,148,148,149,145,137,137,139,139,136,139,141,141,137,134,141,136,137,139,136,135,138,136,136,141,147,153,151,139,133,136,134,139,143,142,134,137,143,150,155,150,148,148,147,146,152,150,146,151,155,154,148,146,148,154,158,160,152,145,145,136,138,125,124,127,120,125,121,131,134,137,139,139,137,130,131,129,129,127,134,146,147,155,157,157,156,155,158,140,126,122,132,145,151,155,153,153,151,147,131,121,131,134,141,152,150,145,145,155,156,149,141,134,145,154,149,142,140,144,142,136,122,120,126,124,131,131,131,134,121,106,115,119,124,132,120,108,115,132,137,129,130,131,132,134,127,124,127,131,130,122,112,96,96,113,120,125,138,128,112,83,69,82,93,101,100,101,102,97,102,106,95,81,85,76,66,53,49,63,65,72,71,66,59,70,66,61,65,66,76,81,78,78,72,71,63,64,79,80,87,79,72,62,73,69,55,55,50,51,55,50,51,50,49,57,51,53,52,45,48,47,51,48,48,53,53,47,51,55,41,46,53,47,49,49,45,49,49,51,53,49,51,54,51,51,48,51,52,52,53,53,55,56,53,47,49,49,55,53,53,46,50,50,50,50,53,49,45,50,51,44,49,47,44,46,45,46,41,48,44,44,45,46,44,43,43,43,45,43,46,44,45,42,48,45,45,51,42,43,42,43,46,45,44,45,43,41,41,46,43,43,49,45,42,42,46,49,45,45,45,46,45,41,44,47,43,43,46,44,44,45,46,47,42,45,42,38,46,45,47,45,50,47,41,44,49,45,46,46,46,49,43,47,46,42,44,47,45,46,48,47,48,47,45,48,48,48,49,51,47,48,54,50,54,51,56,53,50,59,53,55,56,58,56,49,51,48,49,49,50,45,39,43,42,38,41,41,41,39,39,40,40,37,36,38,42,37,40,41,38,42,38,42,39,40,44,37,42,39,44,46,41,40,46,51,41,45,48,45,50,43,48,48,49,54,56,63,61,74,69,62,77,78,87,91,99,119,113,101,93,113,146,135,139,147,153,162,162,163,168,172,174,159,151,157,165,165,163,164,160,160,160,160,158,162,162,162,170,163,165,164,155,159,152,145,152,158,162,159,152,155,155,152,151,150,156,160,158,158,150,148,155,157,152,144,142,146,148,151,148,149,148,146,152,150,151,150,152,152,149,149,148,149,147,154,155,147,146,143,141,139,134,141,139,139,137,129,130,131,131,134,136,139,144,141,145,139,143,105,15,1,10,10,13,12,14,12,13,14,14,13,29,24,24,21,24,25,23,29,24,26,26,29,29,27,25,27,30,24,27,24,27,26,29,28,26,27,24,29,24,23,25,23,24,21,21,25,23,22,24,26,26,21,25,24,27,27,21,27,26,22,29,27,29,30,23,29,32,27,26,29,30,29,27,33,29,27,35,27,27,29,30,28,33,32,30,34,29,29,28,37,30,28,32,33,36,33,33,35,36,35,41,42,49,46,49,52,49,55,59,57,57,64,63,63,73,82,97,87,98,108,102,109,101,107,111,107,110,115,112,111,105,101,110,110,122,111,117,122,124,128,119,128,128,131,134,134,140,138,141,134,129,126,124,128,132,141,144,155,160,152,144,141,144,144,145,147,147,149,149,147,145,141,136,135,138,139,139,138,138,141,139,139,141,139,145,145,141,144,142,147,146,142,138,127,127,128,136,142,150,153,142,140,139,144,147,148,149,148,138,129,133,141,144,137,135,127,123,128,132,135,141,147,145,150,143,134,133,139,136,134,143,141,141,139,136,147,147,148,145,142,145,146,149,153,148,146,145,140,148,146,144,146,141,141,139,141,148,147,145,139,134,133,138,143,135,128,127,142,153,142,133,119,112,114,123,124,119,129,126,126,133,136,131,129,127,128,121,144,111,15,2,10,10,14,11,14,12,12,14,13,13,15,13,13,13,13,14,13,14,14,14,14,14,14,14,14,14,15,15,14,14,14,14,15,14,15,14,14,15,15,15,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,14,14,15,15,15,15,15,15,16,16,15,15,15,15,16,15,15,15,16,15,16,17,16,16,16,15,16,15,16,16,16,16,15,16,15,16,16,15,16,16,16,16,16,16,17,16,16,16,16,16,16,16,16,17,16,17,17,16,16,16,16,16,16,16,16,16,16,16,16,17,17,16,16,16,16,16,16,16,16,16,16,16,16,16,17,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,16,16,16,16,16,16,16,16,16,17,16,16,16,16,16,16,17,16,16,16,16,17,16,16,16,17,17,16,16,16,17,17,16,17,16,17,16,16,16,16,17,17,17,17,16,17,16,17,17,16,16,16,17,16,17,17,16,17,17,17,16,16,17,16,17,17,16,17,16,17,16,16,16,16,17,16,16,16,16,17,16,16,16,16,17,17,17,16,16,17,16,17,16,17,16,16,17,17,16,16,17,17,16,17,17,17,17,17,16,17,17,16,17,17,16,16,16,17,17,16,17,17,16,16,16,16,16,17,17,16,16,16,17,16,16,16,16,17,16,17,16,16,17,16,17,17,17,16,16,17,16,17,16,16,16,17,17,16,17,17,17,17,16,16,17,17,17,16,17,16,17,17,16,17,16,17,17,17,16,16,17,17,17,17,16,16,16,17,17,16,16,17,17,17,17,16,17,17,17,17,16,16,17,17,17,16,16,17,17,17,16,16,17,17,17,17,16,16,17,17,16,16,16,16,17,16,16,17,16,17,16,17,16,16,17,16,17,17,16,17,16,17,16,17,17,17,17,17,16,16,17,17,17,17,16,17,16,16,17,16,17,16,17,17,16,17,16,17,16,16,16,16,17,17,17,17,29,24,24,21,24,25,23,29,24,26,26,29,29,27,25,27,30,24,27,24,27,26,29,28,26,27,24,29,24,23,25,23,24,21,21,25,23,22,24,26,26,21,25,24,27,27,21,27,26,22,29,27,29,30,23,29,32,27,26,29,30,29,27,33,29,27,35,27,27,29,30,28,33,32,30,34,29,29,28,37,30,28,32,33,36,33,33,35,36,35,41,42,49,46,49,52,49,55,59,57,57,64,63,63,73,82,97,87,98,108,102,109,101,107,111,107,110,115,112,111,105,101,110,110,122,111,117,122,124,128,119,128,128,131,134,134,140,138,141,134,129,126,124,128,132,141,144,155,160,152,144,141,144,144,145,147,147,149,149,147,145,141,136,135,138,139,139,138,138,141,139,139,141,139,145,145,141,144,142,147,146,142,138,127,127,128,136,142,150,153,142,140,139,144,147,148,149,148,138,129,133,141,144,137,135,127,123,128,132,135,141,147,145,150,143,134,133,139,136,134,143,141,141,139,136,147,147,148,145,142,145,146,149,153,148,146,145,140,148,146,144,146,141,141,139,141,148,147,145,139,134,133,138,143,135,128,127,142,153,142,133,119,112,114,123,124,119,129,126,126,133,136,131,129,127,128,121,144,111,15,2,10,10,14,11,14,12,12,14,13,13,15,13,13,13,13,14,13,14,14,14,14,14,14,14,14,14,15,15,14,14,14,14,15,14,15,14,14,15,15,15,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,14,14,15,15,15,15,15,15,16,16,15,15,15,15,16,15,15,15,16,15,16,17,16,16,16,15,16,15,16,16,16,16,15,16,15,16,16,15,16,16,16,16,16,16,17,16,16,16,16,16,16,16,16,17,16,17,17,16,16,16,16,16,16,16,16,16,16,16,16,17,17,16,16,16,16,16,16,16,16,16,16,16,16,16,17,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,16,16,16,16,16,16,16,16,16,17,16,16,16,16,16,16,17,16,16,16,16,17,16,16,16,17,17,16,16,16,17,17,16,17,16,17,16,16,16,16,17,17,17,17,16,17,16,17,17,16,16,16,17,16,17,17,16,17,17,17,16,16,17,16,17,17,16,17,16,17,16,16,16,16,17,16,16,16,16,17,16,16,16,16,17,17,17,16,16,17,16,17,16,17,16,16,17,17,16,16,17,17,16,17,17,17,17,17,16,17,17,16,17,17,16,16,16,17,17,16,17,17,16,16,16,16,16,17,17,16,16,16,17,16,16,16,16,17,16,17,16,16,17,16,17,17,17,16,16,17,16,17,16,16,16,17,17,16,17,17,17,17,16,16,17,17,17,16,17,16,17,17,16,17,16,17,17,17,16,16,17,17,17,17,16,16,16,17,17,16,16,17,17,17,17,16,17,17,17,17,16,16,17,17,17,16,16,17,17,17,16,16,17,17,17,17,16,16,17,17,16,16,16,16,17,16,16,17,16,17,16,17,16,16,17,16,17,17,16,17,16,17,16,17,17,17,17,17,16,16,17,17,17,17,16,17,16,16,17,16,17,16,17,17,16,17,16,17,16,16,16,16,17,17,17,17, \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/libvpx/codereview.settings b/presentation/src/main/cpp/third_party/libvpx/codereview.settings deleted file mode 100644 index ccba2eee..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/codereview.settings +++ /dev/null @@ -1,4 +0,0 @@ -# This file is used by git cl to get repository specific information. -GERRIT_HOST: True -CODE_REVIEW_SERVER: chromium-review.googlesource.com -GERRIT_SQUASH_UPLOADS: False diff --git a/presentation/src/main/cpp/third_party/libvpx/configure b/presentation/src/main/cpp/third_party/libvpx/configure deleted file mode 100644 index 457bd6b3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/configure +++ /dev/null @@ -1,840 +0,0 @@ -#!/bin/sh -## -## configure -## -## This script is the front-end to the build system. It provides a similar -## interface to standard configure scripts with some extra bits for dealing -## with toolchains that differ from the standard POSIX interface and -## for extracting subsets of the source tree. In theory, reusable parts -## of this script were intended to live in build/make/configure.sh, -## but in practice, the line is pretty blurry. -## -## This build system is based in part on the FFmpeg configure script. -## - -#source_path="`dirname \"$0\"`" -source_path=${0%/*} -. "${source_path}/build/make/configure.sh" - -show_help(){ - show_help_pre - cat << EOF -Advanced options: - ${toggle_libs} libraries - ${toggle_examples} examples - ${toggle_tools} tools - ${toggle_docs} documentation - ${toggle_unit_tests} unit tests - ${toggle_decode_perf_tests} build decoder perf tests with unit tests - ${toggle_encode_perf_tests} build encoder perf tests with unit tests - --cpu=CPU tune for the specified CPU (ARM: cortex-a8, X86: sse3) - --libc=PATH path to alternate libc - --size-limit=WxH max size to allow in the decoder - --as={yasm|nasm|auto} use specified assembler [auto, yasm preferred] - ${toggle_codec_srcs} in/exclude codec library source code - ${toggle_debug_libs} in/exclude debug version of libraries - ${toggle_static_msvcrt} use static MSVCRT (VS builds only) - ${toggle_vp9_highbitdepth} use VP9 high bit depth (10/12) profiles - ${toggle_better_hw_compatibility} - enable encoder to produce streams with better - hardware decoder compatibility - ${toggle_vp8} VP8 codec support - ${toggle_vp9} VP9 codec support - ${toggle_internal_stats} output of encoder internal stats for debug, if supported (encoders) - ${toggle_postproc} postprocessing - ${toggle_vp9_postproc} vp9 specific postprocessing - ${toggle_multithread} multithreaded encoding and decoding - ${toggle_spatial_resampling} spatial sampling (scaling) support - ${toggle_realtime_only} enable this option while building for real-time encoding - ${toggle_onthefly_bitpacking} enable on-the-fly bitpacking in real-time encoding - ${toggle_error_concealment} enable this option to get a decoder which is able to conceal losses - ${toggle_coefficient_range_checking} - enable decoder to check if intermediate - transform coefficients are in valid range - ${toggle_runtime_cpu_detect} runtime cpu detection - ${toggle_shared} shared library support - ${toggle_static} static library support - ${toggle_small} favor smaller size over speed - ${toggle_postproc_visualizer} macro block / block level visualizers - ${toggle_multi_res_encoding} enable multiple-resolution encoding - ${toggle_temporal_denoising} enable temporal denoising and disable the spatial denoiser - ${toggle_vp9_temporal_denoising} - enable vp9 temporal denoising - ${toggle_webm_io} enable input from and output to WebM container - ${toggle_libyuv} enable libyuv - -Codecs: - Codecs can be selectively enabled or disabled individually, or by family: - --disable- - is equivalent to: - --disable--encoder - --disable--decoder - - Codecs available in this distribution: -EOF -#restore editor state ' - - family=""; - last_family=""; - c=""; - str=""; - for c in ${CODECS}; do - family=${c%_*} - if [ "${family}" != "${last_family}" ]; then - [ -z "${str}" ] || echo "${str}" - str="$(printf ' %10s:' ${family})" - fi - str="${str} $(printf '%10s' ${c#*_})" - last_family=${family} - done - echo "${str}" - show_help_post -} - -## -## BEGIN APPLICATION SPECIFIC CONFIGURATION -## - -# all_platforms is a list of all supported target platforms. Maintain -# alphabetically by architecture, generic-gnu last. -all_platforms="${all_platforms} arm64-android-gcc" -all_platforms="${all_platforms} arm64-darwin-gcc" -all_platforms="${all_platforms} arm64-darwin20-gcc" -all_platforms="${all_platforms} arm64-darwin21-gcc" -all_platforms="${all_platforms} arm64-darwin22-gcc" -all_platforms="${all_platforms} arm64-darwin23-gcc" -all_platforms="${all_platforms} arm64-darwin24-gcc" -all_platforms="${all_platforms} arm64-linux-gcc" -all_platforms="${all_platforms} arm64-win64-gcc" -all_platforms="${all_platforms} arm64-win64-vs15" -all_platforms="${all_platforms} arm64-win64-vs16" -all_platforms="${all_platforms} arm64-win64-vs16-clangcl" -all_platforms="${all_platforms} arm64-win64-vs17" -all_platforms="${all_platforms} arm64-win64-vs17-clangcl" -all_platforms="${all_platforms} armv7-android-gcc" #neon Cortex-A8 -all_platforms="${all_platforms} armv7-darwin-gcc" #neon Cortex-A8 -all_platforms="${all_platforms} armv7-linux-rvct" #neon Cortex-A8 -all_platforms="${all_platforms} armv7-linux-gcc" #neon Cortex-A8 -all_platforms="${all_platforms} armv7-none-rvct" #neon Cortex-A8 -all_platforms="${all_platforms} armv7-win32-gcc" -all_platforms="${all_platforms} armv7-win32-vs14" -all_platforms="${all_platforms} armv7-win32-vs15" -all_platforms="${all_platforms} armv7-win32-vs16" -all_platforms="${all_platforms} armv7-win32-vs17" -all_platforms="${all_platforms} armv7s-darwin-gcc" -all_platforms="${all_platforms} armv8-linux-gcc" -all_platforms="${all_platforms} loongarch32-linux-gcc" -all_platforms="${all_platforms} loongarch64-linux-gcc" -all_platforms="${all_platforms} mips32-linux-gcc" -all_platforms="${all_platforms} mips64-linux-gcc" -all_platforms="${all_platforms} ppc64le-linux-gcc" -all_platforms="${all_platforms} sparc-solaris-gcc" -all_platforms="${all_platforms} x86-android-gcc" -all_platforms="${all_platforms} x86-darwin8-gcc" -all_platforms="${all_platforms} x86-darwin8-icc" -all_platforms="${all_platforms} x86-darwin9-gcc" -all_platforms="${all_platforms} x86-darwin9-icc" -all_platforms="${all_platforms} x86-darwin10-gcc" -all_platforms="${all_platforms} x86-darwin11-gcc" -all_platforms="${all_platforms} x86-darwin12-gcc" -all_platforms="${all_platforms} x86-darwin13-gcc" -all_platforms="${all_platforms} x86-darwin14-gcc" -all_platforms="${all_platforms} x86-darwin15-gcc" -all_platforms="${all_platforms} x86-darwin16-gcc" -all_platforms="${all_platforms} x86-darwin17-gcc" -all_platforms="${all_platforms} x86-iphonesimulator-gcc" -all_platforms="${all_platforms} x86-linux-gcc" -all_platforms="${all_platforms} x86-linux-icc" -all_platforms="${all_platforms} x86-os2-gcc" -all_platforms="${all_platforms} x86-solaris-gcc" -all_platforms="${all_platforms} x86-win32-gcc" -all_platforms="${all_platforms} x86-win32-vs14" -all_platforms="${all_platforms} x86-win32-vs15" -all_platforms="${all_platforms} x86-win32-vs16" -all_platforms="${all_platforms} x86-win32-vs17" -all_platforms="${all_platforms} x86_64-android-gcc" -all_platforms="${all_platforms} x86_64-darwin9-gcc" -all_platforms="${all_platforms} x86_64-darwin10-gcc" -all_platforms="${all_platforms} x86_64-darwin11-gcc" -all_platforms="${all_platforms} x86_64-darwin12-gcc" -all_platforms="${all_platforms} x86_64-darwin13-gcc" -all_platforms="${all_platforms} x86_64-darwin14-gcc" -all_platforms="${all_platforms} x86_64-darwin15-gcc" -all_platforms="${all_platforms} x86_64-darwin16-gcc" -all_platforms="${all_platforms} x86_64-darwin17-gcc" -all_platforms="${all_platforms} x86_64-darwin18-gcc" -all_platforms="${all_platforms} x86_64-darwin19-gcc" -all_platforms="${all_platforms} x86_64-darwin20-gcc" -all_platforms="${all_platforms} x86_64-darwin21-gcc" -all_platforms="${all_platforms} x86_64-darwin22-gcc" -all_platforms="${all_platforms} x86_64-darwin23-gcc" -all_platforms="${all_platforms} x86_64-darwin24-gcc" -all_platforms="${all_platforms} x86_64-iphonesimulator-gcc" -all_platforms="${all_platforms} x86_64-linux-gcc" -all_platforms="${all_platforms} x86_64-linux-icc" -all_platforms="${all_platforms} x86_64-solaris-gcc" -all_platforms="${all_platforms} x86_64-win64-gcc" -all_platforms="${all_platforms} x86_64-win64-vs14" -all_platforms="${all_platforms} x86_64-win64-vs15" -all_platforms="${all_platforms} x86_64-win64-vs16" -all_platforms="${all_platforms} x86_64-win64-vs17" -all_platforms="${all_platforms} generic-gnu" - -# all_targets is a list of all targets that can be configured -# note that these should be in dependency order for now. -all_targets="libs examples tools docs" - -# all targets available are enabled, by default. -for t in ${all_targets}; do - [ -f "${source_path}/${t}.mk" ] && enable_feature ${t} -done - -if ! diff --version >/dev/null; then - die "diff missing: Try installing diffutils via your package manager." -fi - -if ! perl --version >/dev/null; then - die "Perl is required to build" -fi - -if [ "`cd \"${source_path}\" && pwd`" != "`pwd`" ]; then - # test to see if source_path already configured - if [ -f "${source_path}/vpx_config.h" ]; then - die "source directory already configured; run 'make distclean' there first" - fi -fi - -# check installed doxygen version -doxy_version=$(doxygen --version 2>/dev/null) -doxy_major=${doxy_version%%.*} -if [ ${doxy_major:-0} -ge 1 ]; then - doxy_version=${doxy_version#*.} - doxy_minor=${doxy_version%%.*} - doxy_patch=${doxy_version##*.} - - [ $doxy_major -gt 1 ] && enable_feature doxygen - [ $doxy_minor -gt 5 ] && enable_feature doxygen - [ $doxy_minor -eq 5 ] && [ $doxy_patch -ge 3 ] && enable_feature doxygen -fi - -# disable codecs when their source directory does not exist -[ -d "${source_path}/vp8" ] || disable_codec vp8 -[ -d "${source_path}/vp9" ] || disable_codec vp9 - -# install everything except the sources, by default. sources will have -# to be enabled when doing dist builds, since that's no longer a common -# case. -enabled doxygen && enable_feature install_docs -enable_feature install_bins -enable_feature install_libs - -enable_feature static -enable_feature optimizations -enable_feature dependency_tracking -enable_feature spatial_resampling -enable_feature multithread -enable_feature os_support -enable_feature temporal_denoising - -CODECS=" - vp8_encoder - vp8_decoder - vp9_encoder - vp9_decoder -" -CODEC_FAMILIES=" - vp8 - vp9 -" - -ARCH_LIST=" - arm - aarch64 - mips - x86 - x86_64 - ppc - loongarch -" - -ARCH_EXT_LIST_AARCH64=" - neon - neon_dotprod - neon_i8mm - sve - sve2 -" - -ARCH_EXT_LIST_X86=" - mmx - sse - sse2 - sse3 - ssse3 - sse4_1 - avx - avx2 - avx512 -" - -ARCH_EXT_LIST_LOONGSON=" - mmi - lsx - lasx -" - -ARCH_EXT_LIST=" - neon_asm - ${ARCH_EXT_LIST_AARCH64} - - mips32 - dspr2 - msa - mips64 - - ${ARCH_EXT_LIST_X86} - - vsx - - ${ARCH_EXT_LIST_LOONGSON} -" -HAVE_LIST=" - ${ARCH_EXT_LIST} - vpx_ports - pthread_h - unistd_h -" -EXPERIMENT_LIST=" - fp_mb_stats - emulate_hardware - non_greedy_mv - rate_ctrl - collect_component_timing -" -CONFIG_LIST=" - dependency_tracking - external_build - install_docs - install_bins - install_libs - install_srcs - debug - gprof - gcov - rvct - gcc - msvs - pic - big_endian - - codec_srcs - debug_libs - - dequant_tokens - dc_recon - runtime_cpu_detect - postproc - vp9_postproc - multithread - internal_stats - ${CODECS} - ${CODEC_FAMILIES} - encoders - decoders - static_msvcrt - spatial_resampling - realtime_only - onthefly_bitpacking - error_concealment - shared - static - small - postproc_visualizer - os_support - unit_tests - webm_io - libyuv - decode_perf_tests - encode_perf_tests - multi_res_encoding - temporal_denoising - vp9_temporal_denoising - coefficient_range_checking - vp9_highbitdepth - better_hw_compatibility - experimental - size_limit - always_adjust_bpm - bitstream_debug - mismatch_debug - ${EXPERIMENT_LIST} -" -CMDLINE_SELECT=" - dependency_tracking - external_build - extra_warnings - werror - install_docs - install_bins - install_libs - install_srcs - debug - profile - gprof - gcov - pic - optimizations - ccache - runtime_cpu_detect - thumb - - libs - examples - tools - docs - libc - as - size_limit - codec_srcs - debug_libs - - dequant_tokens - dc_recon - postproc - vp9_postproc - multithread - internal_stats - ${CODECS} - ${CODEC_FAMILIES} - static_msvcrt - spatial_resampling - realtime_only - onthefly_bitpacking - error_concealment - shared - static - small - postproc_visualizer - unit_tests - webm_io - libyuv - decode_perf_tests - encode_perf_tests - multi_res_encoding - temporal_denoising - vp9_temporal_denoising - coefficient_range_checking - better_hw_compatibility - vp9_highbitdepth - experimental - always_adjust_bpm - bitstream_debug - mismatch_debug -" - -process_cmdline() { - for opt do - optval="${opt#*=}" - case "$opt" in - --disable-codecs) - for c in ${CODEC_FAMILIES}; do disable_codec $c; done - ;; - --enable-?*|--disable-?*) - eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'` - if is_in ${option} ${EXPERIMENT_LIST}; then - if enabled experimental; then - ${action}_feature $option - else - log_echo "Ignoring $opt -- not in experimental mode." - fi - elif is_in ${option} "${CODECS} ${CODEC_FAMILIES}"; then - ${action}_codec ${option} - else - process_common_cmdline $opt - fi - ;; - *) process_common_cmdline "$opt" - ;; - esac - done -} - -post_process_cmdline() { - if enabled coefficient_range_checking; then - echo "coefficient-range-checking is for decoders only, disabling encoders:" - soft_disable vp8_encoder - soft_disable vp9_encoder - fi - - c="" - - # Enable all detected codecs, if they haven't been disabled - for c in ${CODECS}; do soft_enable $c; done - - # Enable the codec family if any component of that family is enabled - for c in ${CODECS}; do - enabled $c && enable_feature ${c%_*} - done - - # Set the {en,de}coders variable if any algorithm in that class is enabled - for c in ${CODECS}; do - enabled ${c} && enable_feature ${c##*_}s - done -} - - -process_targets() { - enabled child || write_common_config_banner - write_common_target_config_h ${BUILD_PFX}vpx_config.h - write_common_config_targets - enabled win_arm64_neon_h_workaround && write_win_arm64_neon_h_workaround ${BUILD_PFX}arm_neon.h - - # Calculate the default distribution name, based on the enabled features - cf="" - DIST_DIR=vpx - for cf in $CODEC_FAMILIES; do - if enabled ${cf}_encoder && enabled ${cf}_decoder; then - DIST_DIR="${DIST_DIR}-${cf}" - elif enabled ${cf}_encoder; then - DIST_DIR="${DIST_DIR}-${cf}cx" - elif enabled ${cf}_decoder; then - DIST_DIR="${DIST_DIR}-${cf}dx" - fi - done - enabled debug_libs && DIST_DIR="${DIST_DIR}-debug" - enabled codec_srcs && DIST_DIR="${DIST_DIR}-src" - ! enabled postproc && ! enabled vp9_postproc && DIST_DIR="${DIST_DIR}-nopost" - ! enabled multithread && DIST_DIR="${DIST_DIR}-nomt" - ! enabled install_docs && DIST_DIR="${DIST_DIR}-nodocs" - DIST_DIR="${DIST_DIR}-${tgt_isa}-${tgt_os}" - case "${tgt_os}" in - win*) enabled static_msvcrt && DIST_DIR="${DIST_DIR}mt" || DIST_DIR="${DIST_DIR}md" - DIST_DIR="${DIST_DIR}-${tgt_cc}" - ;; - esac - if [ -f "${source_path}/build/make/version.sh" ]; then - ver=`"$source_path/build/make/version.sh" --bare "$source_path"` - DIST_DIR="${DIST_DIR}-${ver}" - VERSION_STRING=${ver} - ver=${ver%%-*} - VERSION_PATCH=${ver##*.} - ver=${ver%.*} - VERSION_MINOR=${ver##*.} - ver=${ver#v} - VERSION_MAJOR=${ver%.*} - fi - enabled child || cat <> config.mk - -PREFIX=${prefix} -ifeq (\$(MAKECMDGOALS),dist) -DIST_DIR?=${DIST_DIR} -else -DIST_DIR?=\$(DESTDIR)${prefix} -endif -LIBSUBDIR=${libdir##${prefix}/} - -VERSION_STRING=${VERSION_STRING} - -VERSION_MAJOR=${VERSION_MAJOR} -VERSION_MINOR=${VERSION_MINOR} -VERSION_PATCH=${VERSION_PATCH} - -CONFIGURE_ARGS=${CONFIGURE_ARGS} -EOF - enabled child || echo "CONFIGURE_ARGS?=${CONFIGURE_ARGS}" >> config.mk - - # - # Write makefiles for all enabled targets - # - for tgt in libs examples tools docs solution; do - tgt_fn="$tgt-$toolchain.mk" - - if enabled $tgt; then - echo "Creating makefiles for ${toolchain} ${tgt}" - write_common_target_config_mk $tgt_fn ${BUILD_PFX}vpx_config.h - #write_${tgt}_config - fi - done - -} - -process_detect() { - if enabled shared; then - # Can only build shared libs on a subset of platforms. Doing this check - # here rather than at option parse time because the target auto-detect - # magic happens after the command line has been parsed. - case "${tgt_os}" in - linux|os2|solaris|darwin*|iphonesimulator*) - # Supported platforms - ;; - *) - if enabled gnu; then - echo "--enable-shared is only supported on ELF; assuming this is OK" - else - die "--enable-shared only supported on ELF, OS/2, and Darwin for now" - fi - ;; - esac - fi - if [ -z "$CC" ] || enabled external_build; then - echo "Bypassing toolchain for environment detection." - enable_feature external_build - check_header() { - log fake_check_header "$@" - header=$1 - shift - var=`echo $header | sed 's/[^A-Za-z0-9_]/_/g'` - disable_feature $var - # Headers common to all environments - case $header in - stdio.h) - true; - ;; - *) - result=false - for d in "$@"; do - [ -f "${d##-I}/$header" ] && result=true && break - done - ${result:-true} - esac && enable_feature $var - - # Specialize windows and POSIX environments. - case $toolchain in - *-win*-*) - # Don't check for any headers in Windows builds. - false - ;; - *) - case $header in - pthread.h) true;; - unistd.h) true;; - *) false;; - esac && enable_feature $var - esac - enabled $var - } - check_ld() { - true - } - check_lib() { - true - } - fi - check_header stdio.h || die "Unable to invoke compiler: ${CC} ${CFLAGS}" - check_ld < -#include -int main(void) { return pthread_create(NULL, NULL, NULL, NULL); } -EOF - check_header unistd.h # for sysconf(3) and friends. - - check_header vpx/vpx_integer.h -I${source_path} && enable_feature vpx_ports - - if enabled neon && ! enabled external_build; then - check_header arm_neon.h || die "Unable to find arm_neon.h" - fi -} - -process_toolchain() { - process_common_toolchain - - # Enable some useful compiler flags - if enabled gcc; then - enabled werror && check_add_cflags -Werror - check_add_cflags -Wall - check_add_cflags -Wdisabled-optimization - check_add_cflags -Wextra-semi - check_add_cflags -Wextra-semi-stmt - check_add_cflags -Wfloat-conversion - check_add_cflags -Wformat=2 - check_add_cflags -Wparentheses-equality - check_add_cflags -Wpointer-arith - check_add_cflags -Wtype-limits - check_add_cflags -Wcast-qual - check_add_cflags -Wvla - check_add_cflags -Wimplicit-function-declaration - check_add_cflags -Wmissing-declarations - check_add_cflags -Wmissing-prototypes - check_add_cflags -Wshadow - check_add_cflags -Wstrict-prototypes - check_add_cflags -Wuninitialized - check_add_cflags -Wunreachable-code-aggressive - check_add_cflags -Wunused - check_add_cflags -Wextra - # check_add_cflags also adds to cxxflags. gtest does not do well with - # these flags so add them explicitly to CFLAGS only. - check_cflags -Wundef && add_cflags_only -Wundef - check_cflags -Wframe-larger-than=52000 && \ - add_cflags_only -Wframe-larger-than=52000 - if enabled mips || [ -z "${INLINE}" ]; then - enabled extra_warnings || check_add_cflags -Wno-unused-function - fi - # Enforce C99 for C files. Allow GNU extensions. - check_cflags -std=gnu99 && add_cflags_only -std=gnu99 - # Avoid this warning for third_party C++ sources. Some reorganization - # would be needed to apply this only to test/*.cc. - check_cflags -Wshorten-64-to-32 && add_cflags_only -Wshorten-64-to-32 - - # Do not allow implicit vector type conversions on Clang builds (this - # is already the default on GCC builds). - check_add_cflags -flax-vector-conversions=none - - # Quiet gcc 6 vs 7 abi warnings: - # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77728 - if enabled arm; then - check_add_cxxflags -Wno-psabi - fi - - # Enforce C++11 compatibility. - check_add_cxxflags -Wc++14-extensions - check_add_cxxflags -Wc++17-extensions - check_add_cxxflags -Wc++20-extensions - check_add_cxxflags -Wnon-virtual-dtor - - # disable some warnings specific to libyuv / libwebm. - check_cxxflags -Wno-missing-declarations \ - && LIBYUV_CXXFLAGS="${LIBYUV_CXXFLAGS} -Wno-missing-declarations" - check_cxxflags -Wno-missing-prototypes \ - && LIBYUV_CXXFLAGS="${LIBYUV_CXXFLAGS} -Wno-missing-prototypes" - check_cxxflags -Wno-pass-failed \ - && LIBYUV_CXXFLAGS="${LIBYUV_CXXFLAGS} -Wno-pass-failed" - check_cxxflags -Wno-shadow \ - && LIBWEBM_CXXFLAGS="${LIBWEBM_CXXFLAGS} -Wno-shadow" \ - && LIBYUV_CXXFLAGS="${LIBYUV_CXXFLAGS} -Wno-shadow" - check_cxxflags -Wno-unused-parameter \ - && LIBYUV_CXXFLAGS="${LIBYUV_CXXFLAGS} -Wno-unused-parameter" - fi - - if enabled icc; then - enabled werror && check_add_cflags -Werror - check_add_cflags -Wall - check_add_cflags -Wpointer-arith - - # ICC has a number of floating point optimizations that we disable - # in favor of deterministic output WRT to other compilers - add_cflags -fp-model precise - fi - - # Enable extra, harmless warnings. These might provide additional insight - # to what the compiler is doing and why, but in general, but they shouldn't - # be treated as fatal, even if we're treating warnings as errors. - GCC_EXTRA_WARNINGS=" - -Wdisabled-optimization - -Winline - " - enabled gcc && EXTRA_WARNINGS="${GCC_EXTRA_WARNINGS}" - RVCT_EXTRA_WARNINGS=" - --remarks - " - enabled rvct && EXTRA_WARNINGS="${RVCT_EXTRA_WARNINGS}" - if enabled extra_warnings; then - for w in ${EXTRA_WARNINGS}; do - check_add_cflags ${w} - enabled gcc && enabled werror && check_add_cflags -Wno-error=${w} - done - fi - - # ccache only really works on gcc toolchains - enabled gcc || soft_disable ccache - if enabled mips; then - enable_feature dequant_tokens - enable_feature dc_recon - fi - - if enabled internal_stats; then - enable_feature vp9_postproc - fi - - # Enable the postbuild target if building for visual studio. - case "$tgt_cc" in - vs*) enable_feature msvs - enable_feature solution - vs_version=${tgt_cc##vs} - VCPROJ_SFX=vcxproj - gen_vcproj_cmd=${source_path}/build/make/gen_msvs_vcxproj.sh - enabled werror && gen_vcproj_cmd="${gen_vcproj_cmd} --enable-werror" - all_targets="${all_targets} solution" - INLINE="__inline" - ;; - esac - - # Other toolchain specific defaults - case $toolchain in x86*) soft_enable postproc;; esac - - if enabled postproc_visualizer; then - enabled postproc || die "postproc_visualizer requires postproc to be enabled" - fi - - # Enable unit tests by default if we have a working C++ compiler. - case "$toolchain" in - *-vs*) - soft_enable unit_tests - soft_enable webm_io - soft_enable libyuv - ;; - *-android-*) - check_add_cxxflags -std=gnu++11 && soft_enable webm_io - soft_enable libyuv - # GTestLog must be modified to use Android logging utilities. - ;; - *-darwin-*) - check_add_cxxflags -std=gnu++11 - # iOS/ARM builds do not work with gtest. This does not match - # x86 targets. - ;; - *-iphonesimulator-*) - check_add_cxxflags -std=gnu++11 && soft_enable webm_io - soft_enable libyuv - ;; - *-win*) - # Some mingw toolchains don't have pthread available by default. - # Treat these more like visual studio where threading in gtest - # would be disabled for the same reason. - check_add_cxxflags -std=gnu++11 && soft_enable unit_tests \ - && soft_enable webm_io - check_cxx "$@" <> ${BUILD_PFX}vpx_config.c -#include "vpx/vpx_codec.h" -static const char* const cfg = "$CONFIGURE_ARGS"; -const char *vpx_codec_build_config(void) {return cfg;} -EOF diff --git a/presentation/src/main/cpp/third_party/libvpx/docs.mk b/presentation/src/main/cpp/third_party/libvpx/docs.mk deleted file mode 100644 index 889d1825..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/docs.mk +++ /dev/null @@ -1,48 +0,0 @@ -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - - -INSTALL_MAPS += docs/% docs/% -INSTALL_MAPS += src/% % -INSTALL_MAPS += % % - -# Static documentation authored in doxygen -CODEC_DOX := mainpage.dox \ - keywords.dox \ - usage.dox \ - usage_cx.dox \ - usage_dx.dox \ - -# Other doxy files sourced in Markdown -TXT_DOX = $(call enabled,TXT_DOX) - -EXAMPLE_PATH += $(SRC_PATH_BARE) #for CHANGELOG, README, etc -EXAMPLE_PATH += $(SRC_PATH_BARE)/examples - -doxyfile: $(if $(findstring examples, $(ALL_TARGETS)),examples.doxy) -doxyfile: libs.doxy_template libs.doxy - @echo " [CREATE] $@" - @cat $^ > $@ - @echo "STRIP_FROM_PATH += $(SRC_PATH_BARE) $(BUILD_ROOT)" >> $@ - @echo "INPUT += $(addprefix $(SRC_PATH_BARE)/,$(CODEC_DOX))" >> $@; - @echo "INPUT += $(TXT_DOX)" >> $@; - @echo "EXAMPLE_PATH += $(EXAMPLE_PATH)" >> $@ - -CLEAN-OBJS += doxyfile $(wildcard docs/html/*) -docs/html/index.html: doxyfile $(CODEC_DOX) $(TXT_DOX) - @echo " [DOXYGEN] $<" - @doxygen $< -DOCS-yes += docs/html/index.html - -DIST-DOCS-yes = $(wildcard docs/html/*) -DIST-DOCS-$(CONFIG_CODEC_SRCS) += $(addprefix src/,$(CODEC_DOX)) -DIST-DOCS-$(CONFIG_CODEC_SRCS) += src/libs.doxy_template -DIST-DOCS-yes += CHANGELOG -DIST-DOCS-yes += README diff --git a/presentation/src/main/cpp/third_party/libvpx/examples.mk b/presentation/src/main/cpp/third_party/libvpx/examples.mk deleted file mode 100644 index 48fcc293..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/examples.mk +++ /dev/null @@ -1,405 +0,0 @@ -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -LIBYUV_SRCS += third_party/libyuv/include/libyuv/basic_types.h \ - third_party/libyuv/include/libyuv/convert.h \ - third_party/libyuv/include/libyuv/convert_argb.h \ - third_party/libyuv/include/libyuv/convert_from.h \ - third_party/libyuv/include/libyuv/cpu_id.h \ - third_party/libyuv/include/libyuv/planar_functions.h \ - third_party/libyuv/include/libyuv/rotate.h \ - third_party/libyuv/include/libyuv/row.h \ - third_party/libyuv/include/libyuv/scale.h \ - third_party/libyuv/include/libyuv/scale_row.h \ - third_party/libyuv/source/cpu_id.cc \ - third_party/libyuv/source/planar_functions.cc \ - third_party/libyuv/source/row_any.cc \ - third_party/libyuv/source/row_common.cc \ - third_party/libyuv/source/row_gcc.cc \ - third_party/libyuv/source/row_msa.cc \ - third_party/libyuv/source/row_neon.cc \ - third_party/libyuv/source/row_neon64.cc \ - third_party/libyuv/source/row_win.cc \ - third_party/libyuv/source/scale.cc \ - third_party/libyuv/source/scale_any.cc \ - third_party/libyuv/source/scale_common.cc \ - third_party/libyuv/source/scale_gcc.cc \ - third_party/libyuv/source/scale_msa.cc \ - third_party/libyuv/source/scale_neon.cc \ - third_party/libyuv/source/scale_neon64.cc \ - third_party/libyuv/source/scale_win.cc \ - -LIBWEBM_COMMON_SRCS += third_party/libwebm/common/hdr_util.cc \ - third_party/libwebm/common/hdr_util.h \ - third_party/libwebm/common/webmids.h - -LIBWEBM_MUXER_SRCS += third_party/libwebm/mkvmuxer/mkvmuxer.cc \ - third_party/libwebm/mkvmuxer/mkvmuxerutil.cc \ - third_party/libwebm/mkvmuxer/mkvwriter.cc \ - third_party/libwebm/mkvmuxer/mkvmuxer.h \ - third_party/libwebm/mkvmuxer/mkvmuxertypes.h \ - third_party/libwebm/mkvmuxer/mkvmuxerutil.h \ - third_party/libwebm/mkvparser/mkvparser.h \ - third_party/libwebm/mkvmuxer/mkvwriter.h - -LIBWEBM_PARSER_SRCS = third_party/libwebm/mkvparser/mkvparser.cc \ - third_party/libwebm/mkvparser/mkvreader.cc \ - third_party/libwebm/mkvparser/mkvparser.h \ - third_party/libwebm/mkvparser/mkvreader.h - -# Add compile flags and include path for libwebm sources. -ifeq ($(CONFIG_WEBM_IO),yes) - CXXFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS - $(BUILD_PFX)third_party/libwebm/%.cc.o: CXXFLAGS += $(LIBWEBM_CXXFLAGS) - INC_PATH-yes += $(SRC_PATH_BARE)/third_party/libwebm -endif - - -# List of examples to build. UTILS are tools meant for distribution -# while EXAMPLES demonstrate specific portions of the API. -UTILS-$(CONFIG_DECODERS) += vpxdec.c -vpxdec.SRCS += md5_utils.c md5_utils.h -vpxdec.SRCS += vpx_ports/compiler_attributes.h -vpxdec.SRCS += vpx_ports/mem_ops.h -vpxdec.SRCS += vpx_ports/mem_ops_aligned.h -vpxdec.SRCS += vpx_ports/vpx_timer.h -vpxdec.SRCS += vpx/vpx_integer.h -vpxdec.SRCS += args.c args.h -vpxdec.SRCS += ivfdec.c ivfdec.h -vpxdec.SRCS += y4minput.c y4minput.h -vpxdec.SRCS += tools_common.c tools_common.h -vpxdec.SRCS += y4menc.c y4menc.h -ifeq ($(CONFIG_LIBYUV),yes) - vpxdec.SRCS += $(LIBYUV_SRCS) - $(BUILD_PFX)third_party/libyuv/%.cc.o: CXXFLAGS += ${LIBYUV_CXXFLAGS} -endif -ifeq ($(CONFIG_WEBM_IO),yes) - vpxdec.SRCS += $(LIBWEBM_PARSER_SRCS) - vpxdec.SRCS += webmdec.cc webmdec.h -endif -vpxdec.GUID = BA5FE66F-38DD-E034-F542-B1578C5FB950 -vpxdec.DESCRIPTION = Full featured decoder -UTILS-$(CONFIG_ENCODERS) += vpxenc.c -vpxenc.SRCS += args.c args.h y4minput.c y4minput.h vpxenc.h -vpxenc.SRCS += ivfdec.c ivfdec.h -vpxenc.SRCS += ivfenc.c ivfenc.h -vpxenc.SRCS += rate_hist.c rate_hist.h -vpxenc.SRCS += tools_common.c tools_common.h -vpxenc.SRCS += warnings.c warnings.h -vpxenc.SRCS += vpx_ports/mem_ops.h -vpxenc.SRCS += vpx_ports/mem_ops_aligned.h -vpxenc.SRCS += vpx_ports/vpx_timer.h -vpxenc.SRCS += vpxstats.c vpxstats.h -ifeq ($(CONFIG_LIBYUV),yes) - vpxenc.SRCS += $(LIBYUV_SRCS) -endif -ifeq ($(CONFIG_WEBM_IO),yes) - vpxenc.SRCS += $(LIBWEBM_COMMON_SRCS) - vpxenc.SRCS += $(LIBWEBM_MUXER_SRCS) - vpxenc.SRCS += $(LIBWEBM_PARSER_SRCS) - vpxenc.SRCS += webmenc.cc webmenc.h -endif -vpxenc.GUID = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1 -vpxenc.DESCRIPTION = Full featured encoder - -EXAMPLES-$(CONFIG_VP9_ENCODER) += vp9_spatial_svc_encoder.c -vp9_spatial_svc_encoder.SRCS += args.c args.h -vp9_spatial_svc_encoder.SRCS += ivfenc.c ivfenc.h -vp9_spatial_svc_encoder.SRCS += y4minput.c y4minput.h -vp9_spatial_svc_encoder.SRCS += tools_common.c tools_common.h -vp9_spatial_svc_encoder.SRCS += video_common.h -vp9_spatial_svc_encoder.SRCS += video_writer.h video_writer.c -vp9_spatial_svc_encoder.SRCS += vpxstats.c vpxstats.h -vp9_spatial_svc_encoder.SRCS += examples/svc_encodeframe.c -vp9_spatial_svc_encoder.SRCS += examples/svc_context.h -vp9_spatial_svc_encoder.GUID = 4A38598D-627D-4505-9C7B-D4020C84100D -vp9_spatial_svc_encoder.DESCRIPTION = VP9 Spatial SVC Encoder - -EXAMPLES-$(CONFIG_ENCODERS) += vpx_temporal_svc_encoder.c -vpx_temporal_svc_encoder.SRCS += ivfenc.c ivfenc.h -vpx_temporal_svc_encoder.SRCS += y4minput.c y4minput.h -vpx_temporal_svc_encoder.SRCS += tools_common.c tools_common.h -vpx_temporal_svc_encoder.SRCS += video_common.h -vpx_temporal_svc_encoder.SRCS += video_writer.h video_writer.c -vpx_temporal_svc_encoder.GUID = B18C08F2-A439-4502-A78E-849BE3D60947 -vpx_temporal_svc_encoder.DESCRIPTION = Temporal SVC Encoder -EXAMPLES-$(CONFIG_DECODERS) += simple_decoder.c -simple_decoder.GUID = D3BBF1E9-2427-450D-BBFF-B2843C1D44CC -simple_decoder.SRCS += ivfdec.h ivfdec.c -simple_decoder.SRCS += y4minput.c y4minput.h -simple_decoder.SRCS += tools_common.h tools_common.c -simple_decoder.SRCS += video_common.h -simple_decoder.SRCS += video_reader.h video_reader.c -simple_decoder.SRCS += vpx_ports/mem_ops.h -simple_decoder.SRCS += vpx_ports/mem_ops_aligned.h -simple_decoder.DESCRIPTION = Simplified decoder loop -EXAMPLES-$(CONFIG_DECODERS) += postproc.c -postproc.SRCS += ivfdec.h ivfdec.c -postproc.SRCS += y4minput.c y4minput.h -postproc.SRCS += tools_common.h tools_common.c -postproc.SRCS += video_common.h -postproc.SRCS += video_reader.h video_reader.c -postproc.SRCS += vpx_ports/mem_ops.h -postproc.SRCS += vpx_ports/mem_ops_aligned.h -postproc.GUID = 65E33355-F35E-4088-884D-3FD4905881D7 -postproc.DESCRIPTION = Decoder postprocessor control -EXAMPLES-$(CONFIG_DECODERS) += decode_to_md5.c -decode_to_md5.SRCS += md5_utils.h md5_utils.c -decode_to_md5.SRCS += ivfdec.h ivfdec.c -decode_to_md5.SRCS += y4minput.c y4minput.h -decode_to_md5.SRCS += tools_common.h tools_common.c -decode_to_md5.SRCS += video_common.h -decode_to_md5.SRCS += video_reader.h video_reader.c -decode_to_md5.SRCS += vpx_ports/compiler_attributes.h -decode_to_md5.SRCS += vpx_ports/mem_ops.h -decode_to_md5.SRCS += vpx_ports/mem_ops_aligned.h -decode_to_md5.GUID = 59120B9B-2735-4BFE-B022-146CA340FE42 -decode_to_md5.DESCRIPTION = Frame by frame MD5 checksum -EXAMPLES-$(CONFIG_ENCODERS) += simple_encoder.c -simple_encoder.SRCS += ivfenc.h ivfenc.c -simple_encoder.SRCS += y4minput.c y4minput.h -simple_encoder.SRCS += tools_common.h tools_common.c -simple_encoder.SRCS += video_common.h -simple_encoder.SRCS += video_writer.h video_writer.c -simple_encoder.GUID = 4607D299-8A71-4D2C-9B1D-071899B6FBFD -simple_encoder.DESCRIPTION = Simplified encoder loop -EXAMPLES-$(CONFIG_VP9_ENCODER) += vp9_lossless_encoder.c -vp9_lossless_encoder.SRCS += ivfenc.h ivfenc.c -vp9_lossless_encoder.SRCS += y4minput.c y4minput.h -vp9_lossless_encoder.SRCS += tools_common.h tools_common.c -vp9_lossless_encoder.SRCS += video_common.h -vp9_lossless_encoder.SRCS += video_writer.h video_writer.c -vp9_lossless_encoder.GUID = B63C7C88-5348-46DC-A5A6-CC151EF93366 -vp9_lossless_encoder.DESCRIPTION = Simplified lossless VP9 encoder -EXAMPLES-$(CONFIG_ENCODERS) += twopass_encoder.c -twopass_encoder.SRCS += ivfenc.h ivfenc.c -twopass_encoder.SRCS += y4minput.c y4minput.h -twopass_encoder.SRCS += tools_common.h tools_common.c -twopass_encoder.SRCS += video_common.h -twopass_encoder.SRCS += video_writer.h video_writer.c -twopass_encoder.GUID = 73494FA6-4AF9-4763-8FBB-265C92402FD8 -twopass_encoder.DESCRIPTION = Two-pass encoder loop -EXAMPLES-$(CONFIG_DECODERS) += decode_with_drops.c -decode_with_drops.SRCS += ivfdec.h ivfdec.c -decode_with_drops.SRCS += y4minput.c y4minput.h -decode_with_drops.SRCS += tools_common.h tools_common.c -decode_with_drops.SRCS += video_common.h -decode_with_drops.SRCS += video_reader.h video_reader.c -decode_with_drops.SRCS += vpx_ports/mem_ops.h -decode_with_drops.SRCS += vpx_ports/mem_ops_aligned.h -decode_with_drops.GUID = CE5C53C4-8DDA-438A-86ED-0DDD3CDB8D26 -decode_with_drops.DESCRIPTION = Drops frames while decoding -EXAMPLES-$(CONFIG_ENCODERS) += set_maps.c -set_maps.SRCS += ivfenc.h ivfenc.c -set_maps.SRCS += y4minput.c y4minput.h -set_maps.SRCS += tools_common.h tools_common.c -set_maps.SRCS += video_common.h -set_maps.SRCS += video_writer.h video_writer.c -set_maps.GUID = ECB2D24D-98B8-4015-A465-A4AF3DCC145F -set_maps.DESCRIPTION = Set active and ROI maps -EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8cx_set_ref.c -vp8cx_set_ref.SRCS += ivfenc.h ivfenc.c -vp8cx_set_ref.SRCS += y4minput.c y4minput.h -vp8cx_set_ref.SRCS += tools_common.h tools_common.c -vp8cx_set_ref.SRCS += video_common.h -vp8cx_set_ref.SRCS += video_writer.h video_writer.c -vp8cx_set_ref.GUID = C5E31F7F-96F6-48BD-BD3E-10EBF6E8057A -vp8cx_set_ref.DESCRIPTION = VP8 set encoder reference frame - -ifeq ($(CONFIG_VP9_ENCODER),yes) -ifeq ($(CONFIG_DECODERS),yes) -EXAMPLES-yes += vp9cx_set_ref.c -vp9cx_set_ref.SRCS += ivfenc.h ivfenc.c -vp9cx_set_ref.SRCS += y4minput.c y4minput.h -vp9cx_set_ref.SRCS += tools_common.h tools_common.c -vp9cx_set_ref.SRCS += video_common.h -vp9cx_set_ref.SRCS += video_writer.h video_writer.c -vp9cx_set_ref.GUID = 65D7F14A-2EE6-4293-B958-AB5107A03B55 -vp9cx_set_ref.DESCRIPTION = VP9 set encoder reference frame -endif -endif - -ifeq ($(CONFIG_MULTI_RES_ENCODING),yes) -ifeq ($(CONFIG_LIBYUV),yes) -EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8_multi_resolution_encoder.c -vp8_multi_resolution_encoder.SRCS += ivfenc.h ivfenc.c -vp8_multi_resolution_encoder.SRCS += y4minput.c y4minput.h -vp8_multi_resolution_encoder.SRCS += tools_common.h tools_common.c -vp8_multi_resolution_encoder.SRCS += video_writer.h video_writer.c -vp8_multi_resolution_encoder.SRCS += $(LIBYUV_SRCS) -vp8_multi_resolution_encoder.GUID = 04f8738e-63c8-423b-90fa-7c2703a374de -vp8_multi_resolution_encoder.DESCRIPTION = VP8 Multiple-resolution Encoding -endif -endif - -# Handle extra library flags depending on codec configuration - -# We should not link to math library (libm) on RVCT -# when building for bare-metal targets -ifeq ($(CONFIG_OS_SUPPORT), yes) -CODEC_EXTRA_LIBS-$(CONFIG_VP8) += m -CODEC_EXTRA_LIBS-$(CONFIG_VP9) += m -else - ifeq ($(CONFIG_GCC), yes) - CODEC_EXTRA_LIBS-$(CONFIG_VP8) += m - CODEC_EXTRA_LIBS-$(CONFIG_VP9) += m - endif -endif -# -# End of specified files. The rest of the build rules should happen -# automagically from here. -# - - -# Examples need different flags based on whether we're building -# from an installed tree or a version controlled tree. Determine -# the proper paths. -ifeq ($(HAVE_ALT_TREE_LAYOUT),yes) - LIB_PATH-yes := $(SRC_PATH_BARE)/../lib - INC_PATH-yes := $(SRC_PATH_BARE)/../include -else - LIB_PATH-yes += $(if $(BUILD_PFX),$(BUILD_PFX),.) - INC_PATH-$(CONFIG_VP8_DECODER) += $(SRC_PATH_BARE)/vp8 - INC_PATH-$(CONFIG_VP8_ENCODER) += $(SRC_PATH_BARE)/vp8 - INC_PATH-$(CONFIG_VP9_DECODER) += $(SRC_PATH_BARE)/vp9 - INC_PATH-$(CONFIG_VP9_ENCODER) += $(SRC_PATH_BARE)/vp9 -endif -INC_PATH-$(CONFIG_LIBYUV) += $(SRC_PATH_BARE)/third_party/libyuv/include -LIB_PATH := $(call enabled,LIB_PATH) -INC_PATH := $(call enabled,INC_PATH) -INTERNAL_CFLAGS = $(addprefix -I,$(INC_PATH)) -INTERNAL_LDFLAGS += $(addprefix -L,$(LIB_PATH)) - - -# Expand list of selected examples to build (as specified above) -UTILS = $(call enabled,UTILS) -EXAMPLES = $(addprefix examples/,$(call enabled,EXAMPLES)) -ALL_EXAMPLES = $(UTILS) $(EXAMPLES) -UTIL_SRCS = $(foreach ex,$(UTILS),$($(ex:.c=).SRCS)) -ALL_SRCS = $(foreach ex,$(ALL_EXAMPLES),$($(notdir $(ex:.c=)).SRCS)) -CODEC_EXTRA_LIBS=$(sort $(call enabled,CODEC_EXTRA_LIBS)) - - -# Expand all example sources into a variable containing all sources -# for that example (not just them main one specified in UTILS/EXAMPLES) -# and add this file to the list (for MSVS workspace generation) -$(foreach ex,$(ALL_EXAMPLES),$(eval $(notdir $(ex:.c=)).SRCS += $(ex) examples.mk)) - - -# Create build/install dependencies for all examples. The common case -# is handled here. The MSVS case is handled below. -NOT_MSVS = $(if $(CONFIG_MSVS),,yes) -DIST-BINS-$(NOT_MSVS) += $(addprefix bin/,$(ALL_EXAMPLES:.c=$(EXE_SFX))) -INSTALL-BINS-$(NOT_MSVS) += $(addprefix bin/,$(UTILS:.c=$(EXE_SFX))) -DIST-SRCS-yes += $(ALL_SRCS) -INSTALL-SRCS-yes += $(UTIL_SRCS) -OBJS-$(NOT_MSVS) += $(call objs,$(ALL_SRCS)) -BINS-$(NOT_MSVS) += $(addprefix $(BUILD_PFX),$(ALL_EXAMPLES:.c=$(EXE_SFX))) - - -# Instantiate linker template for all examples. -CODEC_LIB=$(if $(CONFIG_DEBUG_LIBS),vpx_g,vpx) -ifneq ($(filter darwin%,$(TGT_OS)),) -SHARED_LIB_SUF=.dylib -else -ifneq ($(filter os2%,$(TGT_OS)),) -SHARED_LIB_SUF=_dll.a -else -SHARED_LIB_SUF=.so -endif -endif -CODEC_LIB_SUF=$(if $(CONFIG_SHARED),$(SHARED_LIB_SUF),.a) -$(foreach bin,$(BINS-yes),\ - $(eval $(bin):$(LIB_PATH)/lib$(CODEC_LIB)$(CODEC_LIB_SUF))\ - $(eval $(call linker_template,$(bin),\ - $(call objs,$($(notdir $(bin:$(EXE_SFX)=)).SRCS)) \ - -l$(CODEC_LIB) $(addprefix -l,$(CODEC_EXTRA_LIBS))\ - ))) - -# The following pairs define a mapping of locations in the distribution -# tree to locations in the source/build trees. -INSTALL_MAPS += src/%.c %.c -INSTALL_MAPS += src/% $(SRC_PATH_BARE)/% -INSTALL_MAPS += bin/% % -INSTALL_MAPS += % % - - -# Set up additional MSVS environment -ifeq ($(CONFIG_MSVS),yes) -CODEC_LIB=$(if $(CONFIG_SHARED),vpx,$(if $(CONFIG_STATIC_MSVCRT),vpxmt,vpxmd)) -# This variable uses deferred expansion intentionally, since the results of -# $(wildcard) may change during the course of the Make. -VS_PLATFORMS = $(foreach d,$(wildcard */Release/$(CODEC_LIB).lib),$(word 1,$(subst /, ,$(d)))) -INSTALL_MAPS += $(foreach p,$(VS_PLATFORMS),bin/$(p)/% $(p)/Release/%) -endif - -# Build Visual Studio Projects. We use a template here to instantiate -# explicit rules rather than using an implicit rule because we want to -# leverage make's VPATH searching rather than specifying the paths on -# each file in ALL_EXAMPLES. This has the unfortunate side effect that -# touching the source files trigger a rebuild of the project files -# even though there is no real dependency there (the dependency is on -# the makefiles). We may want to revisit this. -define vcproj_template -$(1): $($(1:.$(VCPROJ_SFX)=).SRCS) vpx.$(VCPROJ_SFX) - $(if $(quiet),@echo " [vcproj] $$@") - $(qexec)$$(GEN_VCPROJ)\ - --exe\ - --target=$$(TOOLCHAIN)\ - --name=$$(@:.$(VCPROJ_SFX)=)\ - --ver=$$(CONFIG_VS_VERSION)\ - --proj-guid=$$($$(@:.$(VCPROJ_SFX)=).GUID)\ - --src-path-bare="$(SRC_PATH_BARE)" \ - --as=$$(AS) \ - $$(if $$(CONFIG_STATIC_MSVCRT),--static-crt) \ - --out=$$@ $$(INTERNAL_CFLAGS) $$(CFLAGS) \ - $$(INTERNAL_LDFLAGS) $$(LDFLAGS) -l$$(CODEC_LIB) $$^ -endef -ALL_EXAMPLES_BASENAME := $(notdir $(ALL_EXAMPLES)) -PROJECTS-$(CONFIG_MSVS) += $(ALL_EXAMPLES_BASENAME:.c=.$(VCPROJ_SFX)) -INSTALL-BINS-$(CONFIG_MSVS) += $(foreach p,$(VS_PLATFORMS),\ - $(addprefix bin/$(p)/,$(ALL_EXAMPLES_BASENAME:.c=.exe))) -$(foreach proj,$(call enabled,PROJECTS),\ - $(eval $(call vcproj_template,$(proj)))) - -# -# Documentation Rules -# -%.dox: %.c - @echo " [DOXY] $@" - @mkdir -p $(dir $@) - @echo "/*!\page example_$(@F:.dox=) $(@F:.dox=)" > $@ - @echo " \includelineno $(> $@ - @echo "*/" >> $@ - -samples.dox: examples.mk - @echo " [DOXY] $@" - @echo "/*!\page samples Sample Code" > $@ - @echo " This SDK includes a number of sample applications."\ - "Each sample documents a feature of the SDK in both prose"\ - "and the associated C code."\ - "The following samples are included: ">>$@ - @$(foreach ex,$(sort $(notdir $(EXAMPLES:.c=))),\ - echo " - \subpage example_$(ex) $($(ex).DESCRIPTION)" >> $@;) - @echo >> $@ - @echo " In addition, the SDK contains a number of utilities."\ - "Since these utilities are built upon the concepts described"\ - "in the sample code listed above, they are not documented in"\ - "pieces like the samples are. Their source is included here"\ - "for reference. The following utilities are included:" >> $@ - @$(foreach ex,$(sort $(UTILS:.c=)),\ - echo " - \subpage example_$(ex) $($(ex).DESCRIPTION)" >> $@;) - @echo "*/" >> $@ - -CLEAN-OBJS += examples.doxy samples.dox $(ALL_EXAMPLES:.c=.dox) -DOCS-yes += examples.doxy samples.dox -examples.doxy: samples.dox $(ALL_EXAMPLES:.c=.dox) - @echo "INPUT += $^" > $@ - @echo "ENABLED_SECTIONS += samples" >> $@ diff --git a/presentation/src/main/cpp/third_party/libvpx/examples/decode_to_md5.c b/presentation/src/main/cpp/third_party/libvpx/examples/decode_to_md5.c deleted file mode 100644 index 51959f37..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/examples/decode_to_md5.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Frame-by-frame MD5 Checksum -// =========================== -// -// This example builds upon the simple decoder loop to show how checksums -// of the decoded output can be generated. These are used for validating -// decoder implementations against the reference implementation, for example. -// -// MD5 algorithm -// ------------- -// The Message-Digest 5 (MD5) is a well known hash function. We have provided -// an implementation derived from the RSA Data Security, Inc. MD5 Message-Digest -// Algorithm for your use. Our implmentation only changes the interface of this -// reference code. You must include the `md5_utils.h` header for access to these -// functions. -// -// Processing The Decoded Data -// --------------------------- -// Each row of the image is passed to the MD5 accumulator. First the Y plane -// is processed, then U, then V. It is important to honor the image's `stride` -// values. - -#include -#include -#include - -#include "vpx/vp8dx.h" -#include "vpx/vpx_decoder.h" - -#include "../md5_utils.h" -#include "../tools_common.h" -#include "../video_reader.h" -#include "./vpx_config.h" - -static void get_image_md5(const vpx_image_t *img, unsigned char digest[16]) { - int plane, y; - MD5Context md5; - - MD5Init(&md5); - - for (plane = 0; plane < 3; ++plane) { - const unsigned char *buf = img->planes[plane]; - const int stride = img->stride[plane]; - const int w = plane ? (img->d_w + 1) >> 1 : img->d_w; - const int h = plane ? (img->d_h + 1) >> 1 : img->d_h; - - for (y = 0; y < h; ++y) { - MD5Update(&md5, buf, w); - buf += stride; - } - } - - MD5Final(digest, &md5); -} - -static void print_md5(FILE *stream, unsigned char digest[16]) { - int i; - - for (i = 0; i < 16; ++i) fprintf(stream, "%02x", digest[i]); -} - -static const char *exec_name; - -void usage_exit(void) { - fprintf(stderr, "Usage: %s \n", exec_name); - exit(EXIT_FAILURE); -} - -int main(int argc, char **argv) { - int frame_cnt = 0; - FILE *outfile = NULL; - vpx_codec_ctx_t codec; - VpxVideoReader *reader = NULL; - const VpxVideoInfo *info = NULL; - const VpxInterface *decoder = NULL; - - exec_name = argv[0]; - - if (argc != 3) die("Invalid number of arguments."); - - reader = vpx_video_reader_open(argv[1]); - if (!reader) die("Failed to open %s for reading.", argv[1]); - - if (!(outfile = fopen(argv[2], "wb"))) - die("Failed to open %s for writing.", argv[2]); - - info = vpx_video_reader_get_info(reader); - - decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc); - if (!decoder) die("Unknown input codec."); - - printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface())); - - if (vpx_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0)) - die_codec(&codec, "Failed to initialize decoder"); - - while (vpx_video_reader_read_frame(reader)) { - vpx_codec_iter_t iter = NULL; - vpx_image_t *img = NULL; - size_t frame_size = 0; - const unsigned char *frame = - vpx_video_reader_get_frame(reader, &frame_size); - if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0)) - die_codec(&codec, "Failed to decode frame"); - - while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL) { - unsigned char digest[16]; - - get_image_md5(img, digest); - print_md5(outfile, digest); - fprintf(outfile, " img-%dx%d-%04d.i420\n", img->d_w, img->d_h, - ++frame_cnt); - } - } - - printf("Processed %d frames.\n", frame_cnt); - if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec."); - - vpx_video_reader_close(reader); - - fclose(outfile); - return EXIT_SUCCESS; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/examples/decode_with_drops.c b/presentation/src/main/cpp/third_party/libvpx/examples/decode_with_drops.c deleted file mode 100644 index 03c79a45..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/examples/decode_with_drops.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Decode With Drops Example -// ========================= -// -// This is an example utility which drops a series of frames, as specified -// on the command line. This is useful for observing the error recovery -// features of the codec. -// -// Usage -// ----- -// This example adds a single argument to the `simple_decoder` example, -// which specifies the range or pattern of frames to drop. The parameter is -// parsed as follows: -// -// Dropping A Range Of Frames -// -------------------------- -// To drop a range of frames, specify the starting frame and the ending -// frame to drop, separated by a dash. The following command will drop -// frames 5 through 10 (base 1). -// -// $ ./decode_with_drops in.ivf out.i420 5-10 -// -// -// Dropping A Pattern Of Frames -// ---------------------------- -// To drop a pattern of frames, specify the number of frames to drop and -// the number of frames after which to repeat the pattern, separated by -// a forward-slash. The following command will drop 3 of 7 frames. -// Specifically, it will decode 4 frames, then drop 3 frames, and then -// repeat. -// -// $ ./decode_with_drops in.ivf out.i420 3/7 -// -// -// Extra Variables -// --------------- -// This example maintains the pattern passed on the command line in the -// `n`, `m`, and `is_range` variables: -// -// -// Making The Drop Decision -// ------------------------ -// The example decides whether to drop the frame based on the current -// frame number, immediately before decoding the frame. - -#include -#include -#include - -#include "vpx/vp8dx.h" -#include "vpx/vpx_decoder.h" - -#include "../tools_common.h" -#include "../video_reader.h" -#include "./vpx_config.h" - -static const char *exec_name; - -void usage_exit(void) { - fprintf(stderr, "Usage: %s \n", exec_name); - exit(EXIT_FAILURE); -} - -int main(int argc, char **argv) { - int frame_cnt = 0; - FILE *outfile = NULL; - vpx_codec_ctx_t codec; - const VpxInterface *decoder = NULL; - VpxVideoReader *reader = NULL; - const VpxVideoInfo *info = NULL; - int n = 0; - int m = 0; - int is_range = 0; - char *nptr = NULL; - - exec_name = argv[0]; - - if (argc != 4) die("Invalid number of arguments."); - - reader = vpx_video_reader_open(argv[1]); - if (!reader) die("Failed to open %s for reading.", argv[1]); - - if (!(outfile = fopen(argv[2], "wb"))) - die("Failed to open %s for writing.", argv[2]); - - n = (int)strtol(argv[3], &nptr, 0); - m = (int)strtol(nptr + 1, NULL, 0); - is_range = (*nptr == '-'); - if (!n || !m || (*nptr != '-' && *nptr != '/')) - die("Couldn't parse pattern %s.\n", argv[3]); - - info = vpx_video_reader_get_info(reader); - - decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc); - if (!decoder) die("Unknown input codec."); - - printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface())); - - if (vpx_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0)) - die("Failed to initialize decoder."); - - while (vpx_video_reader_read_frame(reader)) { - vpx_codec_iter_t iter = NULL; - vpx_image_t *img = NULL; - size_t frame_size = 0; - int skip; - const unsigned char *frame = - vpx_video_reader_get_frame(reader, &frame_size); - if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0)) - die_codec(&codec, "Failed to decode frame."); - - ++frame_cnt; - - skip = (is_range && frame_cnt >= n && frame_cnt <= m) || - (!is_range && m - (frame_cnt - 1) % m <= n); - - if (!skip) { - putc('.', stdout); - - while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL) - vpx_img_write(img, outfile); - } else { - putc('X', stdout); - } - - fflush(stdout); - } - - printf("Processed %d frames.\n", frame_cnt); - if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec."); - - printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n", - info->frame_width, info->frame_height, argv[2]); - - vpx_video_reader_close(reader); - fclose(outfile); - - return EXIT_SUCCESS; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/examples/postproc.c b/presentation/src/main/cpp/third_party/libvpx/examples/postproc.c deleted file mode 100644 index b53c15ea..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/examples/postproc.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Postprocessing Decoder -// ====================== -// -// This example adds postprocessing to the simple decoder loop. -// -// Initializing Postprocessing -// --------------------------- -// You must inform the codec that you might request postprocessing at -// initialization time. This is done by passing the VPX_CODEC_USE_POSTPROC -// flag to `vpx_codec_dec_init`. If the codec does not support -// postprocessing, this call will return VPX_CODEC_INCAPABLE. For -// demonstration purposes, we also fall back to default initialization if -// the codec does not provide support. -// -// Using Adaptive Postprocessing -// ----------------------------- -// VP6 provides "adaptive postprocessing." It will automatically select the -// best postprocessing filter on a frame by frame basis based on the amount -// of time remaining before the user's specified deadline expires. The -// special value 0 indicates that the codec should take as long as -// necessary to provide the best quality frame. This example gives the -// codec 15ms (15000us) to return a frame. Remember that this is a soft -// deadline, and the codec may exceed it doing its regular processing. In -// these cases, no additional postprocessing will be done. -// -// Codec Specific Postprocessing Controls -// -------------------------------------- -// Some codecs provide fine grained controls over their built-in -// postprocessors. VP8 is one example. The following sample code toggles -// postprocessing on and off every 15 frames. - -#include -#include -#include - -#include "vpx/vp8dx.h" -#include "vpx/vpx_decoder.h" - -#include "../tools_common.h" -#include "../video_reader.h" -#include "./vpx_config.h" - -static const char *exec_name; - -void usage_exit(void) { - fprintf(stderr, "Usage: %s \n", exec_name); - exit(EXIT_FAILURE); -} - -int main(int argc, char **argv) { - int frame_cnt = 0; - FILE *outfile = NULL; - vpx_codec_ctx_t codec; - vpx_codec_err_t res; - VpxVideoReader *reader = NULL; - const VpxInterface *decoder = NULL; - const VpxVideoInfo *info = NULL; - - exec_name = argv[0]; - - if (argc != 3) die("Invalid number of arguments."); - - reader = vpx_video_reader_open(argv[1]); - if (!reader) die("Failed to open %s for reading.", argv[1]); - - if (!(outfile = fopen(argv[2], "wb"))) - die("Failed to open %s for writing", argv[2]); - - info = vpx_video_reader_get_info(reader); - - decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc); - if (!decoder) die("Unknown input codec."); - - printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface())); - - res = vpx_codec_dec_init(&codec, decoder->codec_interface(), NULL, - VPX_CODEC_USE_POSTPROC); - if (res == VPX_CODEC_INCAPABLE) - die("Postproc not supported by this decoder."); - - if (res) die("Failed to initialize decoder."); - - while (vpx_video_reader_read_frame(reader)) { - vpx_codec_iter_t iter = NULL; - vpx_image_t *img = NULL; - size_t frame_size = 0; - const unsigned char *frame = - vpx_video_reader_get_frame(reader, &frame_size); - - ++frame_cnt; - - if (frame_cnt % 30 == 1) { - vp8_postproc_cfg_t pp = { 0, 0, 0 }; - - if (vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp)) - die_codec(&codec, "Failed to turn off postproc."); - } else if (frame_cnt % 30 == 16) { - vp8_postproc_cfg_t pp = { VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE, 4, - 0 }; - if (vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp)) - die_codec(&codec, "Failed to turn on postproc."); - } - - // Decode the frame with 15ms deadline - if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 15000)) - die_codec(&codec, "Failed to decode frame"); - - while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL) { - vpx_img_write(img, outfile); - } - } - - printf("Processed %d frames.\n", frame_cnt); - if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec"); - - printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n", - info->frame_width, info->frame_height, argv[2]); - - vpx_video_reader_close(reader); - - fclose(outfile); - return EXIT_SUCCESS; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/examples/set_maps.c b/presentation/src/main/cpp/third_party/libvpx/examples/set_maps.c deleted file mode 100644 index 867e473a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/examples/set_maps.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// VP8 Set Active and ROI Maps -// =========================== -// -// This is an example demonstrating how to control the VP8 encoder's -// ROI and Active maps. -// -// ROI (Reigon of Interest) maps are a way for the application to assign -// each macroblock in the image to a region, and then set quantizer and -// filtering parameters on that image. -// -// Active maps are a way for the application to specify on a -// macroblock-by-macroblock basis whether there is any activity in that -// macroblock. -// -// -// Configuration -// ------------- -// An ROI map is set on frame 22. If the width of the image in macroblocks -// is evenly divisble by 4, then the output will appear to have distinct -// columns, where the quantizer, loopfilter, and static threshold differ -// from column to column. -// -// An active map is set on frame 33. If the width of the image in macroblocks -// is evenly divisble by 4, then the output will appear to have distinct -// columns, where one column will have motion and the next will not. -// -// The active map is cleared on frame 44. -// -// Observing The Effects -// --------------------- -// Use the `simple_decoder` example to decode this sample, and observe -// the change in the image at frames 22, 33, and 44. - -#include -#include -#include -#include - -#include "vpx/vp8cx.h" -#include "vpx/vpx_encoder.h" - -#include "../tools_common.h" -#include "../video_writer.h" - -static const char *exec_name; - -void usage_exit(void) { - fprintf(stderr, "Usage: %s \n", - exec_name); - exit(EXIT_FAILURE); -} - -static void set_roi_map(const vpx_codec_enc_cfg_t *cfg, - vpx_codec_ctx_t *codec) { - unsigned int i; - vpx_roi_map_t roi; - memset(&roi, 0, sizeof(roi)); - - roi.rows = (cfg->g_h + 15) / 16; - roi.cols = (cfg->g_w + 15) / 16; - - roi.delta_q[0] = 0; - roi.delta_q[1] = -2; - roi.delta_q[2] = -4; - roi.delta_q[3] = -6; - - roi.delta_lf[0] = 0; - roi.delta_lf[1] = 1; - roi.delta_lf[2] = 2; - roi.delta_lf[3] = 3; - - roi.static_threshold[0] = 1500; - roi.static_threshold[1] = 1000; - roi.static_threshold[2] = 500; - roi.static_threshold[3] = 0; - - roi.roi_map = (uint8_t *)malloc(roi.rows * roi.cols); - for (i = 0; i < roi.rows * roi.cols; ++i) roi.roi_map[i] = i % 4; - - if (vpx_codec_control(codec, VP8E_SET_ROI_MAP, &roi)) - die_codec(codec, "Failed to set ROI map"); - - free(roi.roi_map); -} - -static void set_active_map(const vpx_codec_enc_cfg_t *cfg, - vpx_codec_ctx_t *codec) { - unsigned int i; - vpx_active_map_t map = { 0, 0, 0 }; - - map.rows = (cfg->g_h + 15) / 16; - map.cols = (cfg->g_w + 15) / 16; - - map.active_map = (uint8_t *)malloc(map.rows * map.cols); - for (i = 0; i < map.rows * map.cols; ++i) map.active_map[i] = i % 2; - - if (vpx_codec_control(codec, VP8E_SET_ACTIVEMAP, &map)) - die_codec(codec, "Failed to set active map"); - - free(map.active_map); -} - -static void unset_active_map(const vpx_codec_enc_cfg_t *cfg, - vpx_codec_ctx_t *codec) { - vpx_active_map_t map = { 0, 0, 0 }; - - map.rows = (cfg->g_h + 15) / 16; - map.cols = (cfg->g_w + 15) / 16; - map.active_map = NULL; - - if (vpx_codec_control(codec, VP8E_SET_ACTIVEMAP, &map)) - die_codec(codec, "Failed to set active map"); -} - -static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img, - int frame_index, VpxVideoWriter *writer) { - int got_pkts = 0; - vpx_codec_iter_t iter = NULL; - const vpx_codec_cx_pkt_t *pkt = NULL; - const vpx_codec_err_t res = - vpx_codec_encode(codec, img, frame_index, 1, 0, VPX_DL_GOOD_QUALITY); - if (res != VPX_CODEC_OK) die_codec(codec, "Failed to encode frame"); - - while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) { - got_pkts = 1; - - if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { - const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0; - if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf, - pkt->data.frame.sz, - pkt->data.frame.pts)) { - die_codec(codec, "Failed to write compressed frame"); - } - - printf(keyframe ? "K" : "."); - fflush(stdout); - } - } - - return got_pkts; -} - -int main(int argc, char **argv) { - FILE *infile = NULL; - vpx_codec_ctx_t codec; - vpx_codec_enc_cfg_t cfg; - int frame_count = 0; - vpx_image_t raw; - vpx_codec_err_t res; - VpxVideoInfo info; - VpxVideoWriter *writer = NULL; - const VpxInterface *encoder = NULL; - const int fps = 2; // TODO(dkovalev) add command line argument - const double bits_per_pixel_per_frame = 0.067; - - exec_name = argv[0]; - if (argc != 6) die("Invalid number of arguments"); - - memset(&info, 0, sizeof(info)); - - encoder = get_vpx_encoder_by_name(argv[1]); - if (encoder == NULL) { - die("Unsupported codec."); - } - assert(encoder != NULL); - info.codec_fourcc = encoder->fourcc; - info.frame_width = (int)strtol(argv[2], NULL, 0); - info.frame_height = (int)strtol(argv[3], NULL, 0); - info.time_base.numerator = 1; - info.time_base.denominator = fps; - - if (info.frame_width <= 0 || info.frame_height <= 0 || - (info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) { - die("Invalid frame size: %dx%d", info.frame_width, info.frame_height); - } - - if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, info.frame_width, - info.frame_height, 1)) { - die("Failed to allocate image."); - } - - printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface())); - - res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0); - if (res) die_codec(&codec, "Failed to get default codec config."); - - cfg.g_w = info.frame_width; - cfg.g_h = info.frame_height; - cfg.g_timebase.num = info.time_base.numerator; - cfg.g_timebase.den = info.time_base.denominator; - cfg.rc_target_bitrate = - (unsigned int)(bits_per_pixel_per_frame * cfg.g_w * cfg.g_h * fps / 1000); - cfg.g_lag_in_frames = 0; - - writer = vpx_video_writer_open(argv[5], kContainerIVF, &info); - if (!writer) die("Failed to open %s for writing.", argv[5]); - - if (!(infile = fopen(argv[4], "rb"))) - die("Failed to open %s for reading.", argv[4]); - - if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0)) - die("Failed to initialize encoder"); - - // Encode frames. - while (vpx_img_read(&raw, infile)) { - ++frame_count; - - if (frame_count == 22 && encoder->fourcc == VP8_FOURCC) { - set_roi_map(&cfg, &codec); - } else if (frame_count == 33) { - set_active_map(&cfg, &codec); - } else if (frame_count == 44) { - unset_active_map(&cfg, &codec); - } - - encode_frame(&codec, &raw, frame_count, writer); - } - - // Flush encoder. - while (encode_frame(&codec, NULL, -1, writer)) { - } - - printf("\n"); - fclose(infile); - printf("Processed %d frames.\n", frame_count); - - vpx_img_free(&raw); - if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec."); - - vpx_video_writer_close(writer); - - return EXIT_SUCCESS; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/examples/simple_decoder.c b/presentation/src/main/cpp/third_party/libvpx/examples/simple_decoder.c deleted file mode 100644 index d089e826..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/examples/simple_decoder.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Simple Decoder -// ============== -// -// This is an example of a simple decoder loop. It takes an input file -// containing the compressed data (in IVF format), passes it through the -// decoder, and writes the decompressed frames to disk. Other decoder -// examples build upon this one. -// -// The details of the IVF format have been elided from this example for -// simplicity of presentation, as IVF files will not generally be used by -// your application. In general, an IVF file consists of a file header, -// followed by a variable number of frames. Each frame consists of a frame -// header followed by a variable length payload. The length of the payload -// is specified in the first four bytes of the frame header. The payload is -// the raw compressed data. -// -// Standard Includes -// ----------------- -// For decoders, you only have to include `vpx_decoder.h` and then any -// header files for the specific codecs you use. In this case, we're using -// vp8. -// -// Initializing The Codec -// ---------------------- -// The libvpx decoder is initialized by the call to vpx_codec_dec_init(). -// Determining the codec interface to use is handled by VpxVideoReader and the -// functions prefixed with vpx_video_reader_. Discussion of those functions is -// beyond the scope of this example, but the main gist is to open the input file -// and parse just enough of it to determine if it's a VPx file and which VPx -// codec is contained within the file. -// Note the NULL pointer passed to vpx_codec_dec_init(). We do that in this -// example because we want the algorithm to determine the stream configuration -// (width/height) and allocate memory automatically. -// -// Decoding A Frame -// ---------------- -// Once the frame has been read into memory, it is decoded using the -// `vpx_codec_decode` function. The call takes a pointer to the data -// (`frame`) and the length of the data (`frame_size`). No application data -// is associated with the frame in this example, so the `user_priv` -// parameter is NULL. The `deadline` parameter is left at zero for this -// example. This parameter is generally only used when doing adaptive post -// processing. -// -// Codecs may produce a variable number of output frames for every call to -// `vpx_codec_decode`. These frames are retrieved by the -// `vpx_codec_get_frame` iterator function. The iterator variable `iter` is -// initialized to NULL each time `vpx_codec_decode` is called. -// `vpx_codec_get_frame` is called in a loop, returning a pointer to a -// decoded image or NULL to indicate the end of list. -// -// Processing The Decoded Data -// --------------------------- -// In this example, we simply write the encoded data to disk. It is -// important to honor the image's `stride` values. -// -// Cleanup -// ------- -// The `vpx_codec_destroy` call frees any memory allocated by the codec. -// -// Error Handling -// -------------- -// This example does not special case any error return codes. If there was -// an error, a descriptive message is printed and the program exits. With -// few exceptions, vpx_codec functions return an enumerated error status, -// with the value `0` indicating success. - -#include -#include -#include - -#include "vpx/vpx_decoder.h" - -#include "../tools_common.h" -#include "../video_reader.h" -#include "./vpx_config.h" - -static const char *exec_name; - -void usage_exit(void) { - fprintf(stderr, "Usage: %s \n", exec_name); - exit(EXIT_FAILURE); -} - -int main(int argc, char **argv) { - int frame_cnt = 0; - FILE *outfile = NULL; - vpx_codec_ctx_t codec; - VpxVideoReader *reader = NULL; - const VpxInterface *decoder = NULL; - const VpxVideoInfo *info = NULL; - - exec_name = argv[0]; - - if (argc != 3) die("Invalid number of arguments."); - - reader = vpx_video_reader_open(argv[1]); - if (!reader) die("Failed to open %s for reading.", argv[1]); - - if (!(outfile = fopen(argv[2], "wb"))) - die("Failed to open %s for writing.", argv[2]); - - info = vpx_video_reader_get_info(reader); - - decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc); - if (!decoder) die("Unknown input codec."); - - printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface())); - - if (vpx_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0)) - die("Failed to initialize decoder."); - - while (vpx_video_reader_read_frame(reader)) { - vpx_codec_iter_t iter = NULL; - vpx_image_t *img = NULL; - size_t frame_size = 0; - const unsigned char *frame = - vpx_video_reader_get_frame(reader, &frame_size); - if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0)) - die_codec(&codec, "Failed to decode frame."); - - while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL) { - vpx_img_write(img, outfile); - ++frame_cnt; - } - } - - printf("Processed %d frames.\n", frame_cnt); - if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec"); - - printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n", - info->frame_width, info->frame_height, argv[2]); - - vpx_video_reader_close(reader); - - fclose(outfile); - - return EXIT_SUCCESS; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/examples/simple_encoder.c b/presentation/src/main/cpp/third_party/libvpx/examples/simple_encoder.c deleted file mode 100644 index dffdd6d7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/examples/simple_encoder.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Simple Encoder -// ============== -// -// This is an example of a simple encoder loop. It takes an input file in -// YV12 format, passes it through the encoder, and writes the compressed -// frames to disk in IVF format. Other decoder examples build upon this -// one. -// -// The details of the IVF format have been elided from this example for -// simplicity of presentation, as IVF files will not generally be used by -// your application. In general, an IVF file consists of a file header, -// followed by a variable number of frames. Each frame consists of a frame -// header followed by a variable length payload. The length of the payload -// is specified in the first four bytes of the frame header. The payload is -// the raw compressed data. -// -// Standard Includes -// ----------------- -// For encoders, you only have to include `vpx_encoder.h` and then any -// header files for the specific codecs you use. In this case, we're using -// vp8. -// -// Getting The Default Configuration -// --------------------------------- -// Encoders have the notion of "usage profiles." For example, an encoder -// may want to publish default configurations for both a video -// conferencing application and a best quality offline encoder. These -// obviously have very different default settings. Consult the -// documentation for your codec to see if it provides any default -// configurations. All codecs provide a default configuration, number 0, -// which is valid for material in the vacinity of QCIF/QVGA. -// -// Updating The Configuration -// --------------------------------- -// Almost all applications will want to update the default configuration -// with settings specific to their usage. Here we set the width and height -// of the video file to that specified on the command line. We also scale -// the default bitrate based on the ratio between the default resolution -// and the resolution specified on the command line. -// -// Initializing The Codec -// ---------------------- -// The encoder is initialized by the following code. -// -// Encoding A Frame -// ---------------- -// The frame is read as a continuous block (size width * height * 3 / 2) -// from the input file. If a frame was read (the input file has not hit -// EOF) then the frame is passed to the encoder. Otherwise, a NULL -// is passed, indicating the End-Of-Stream condition to the encoder. The -// `frame_cnt` is reused as the presentation time stamp (PTS) and each -// frame is shown for one frame-time in duration. The flags parameter is -// unused in this example. The deadline is set to VPX_DL_REALTIME to -// make the example run as quickly as possible. - -// Forced Keyframes -// ---------------- -// Keyframes can be forced by setting the VPX_EFLAG_FORCE_KF bit of the -// flags passed to `vpx_codec_control()`. In this example, we force a -// keyframe every frames. Note, the output stream can -// contain additional keyframes beyond those that have been forced using the -// VPX_EFLAG_FORCE_KF flag because of automatic keyframe placement by the -// encoder. -// -// Processing The Encoded Data -// --------------------------- -// Each packet of type `VPX_CODEC_CX_FRAME_PKT` contains the encoded data -// for this frame. We write a IVF frame header, followed by the raw data. -// -// Cleanup -// ------- -// The `vpx_codec_destroy` call frees any memory allocated by the codec. -// -// Error Handling -// -------------- -// This example does not special case any error return codes. If there was -// an error, a descriptive message is printed and the program exits. With -// few exeptions, vpx_codec functions return an enumerated error status, -// with the value `0` indicating success. -// -// Error Resiliency Features -// ------------------------- -// Error resiliency is controlled by the g_error_resilient member of the -// configuration structure. Use the `decode_with_drops` example to decode with -// frames 5-10 dropped. Compare the output for a file encoded with this example -// versus one encoded with the `simple_encoder` example. - -#include -#include -#include - -#include "vpx/vpx_encoder.h" - -#include "../tools_common.h" -#include "../video_writer.h" - -static const char *exec_name; - -void usage_exit(void) { - fprintf(stderr, - "Usage: %s " - " \n" - "See comments in simple_encoder.c for more information.\n", - exec_name); - exit(EXIT_FAILURE); -} - -static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img, - int frame_index, int flags, VpxVideoWriter *writer) { - int got_pkts = 0; - vpx_codec_iter_t iter = NULL; - const vpx_codec_cx_pkt_t *pkt = NULL; - const vpx_codec_err_t res = - vpx_codec_encode(codec, img, frame_index, 1, flags, VPX_DL_GOOD_QUALITY); - if (res != VPX_CODEC_OK) die_codec(codec, "Failed to encode frame"); - - while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) { - got_pkts = 1; - - if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { - const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0; - if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf, - pkt->data.frame.sz, - pkt->data.frame.pts)) { - die_codec(codec, "Failed to write compressed frame"); - } - printf(keyframe ? "K" : "."); - fflush(stdout); - } - } - - return got_pkts; -} - -// TODO(tomfinegan): Improve command line parsing and add args for bitrate/fps. -int main(int argc, char **argv) { - FILE *infile = NULL; - vpx_codec_ctx_t codec; - vpx_codec_enc_cfg_t cfg; - int frame_count = 0; - vpx_image_t raw; - vpx_codec_err_t res; - VpxVideoInfo info = { 0, 0, 0, { 0, 0 } }; - VpxVideoWriter *writer = NULL; - const VpxInterface *encoder = NULL; - const int fps = 30; - const int bitrate = 200; - int keyframe_interval = 0; - int max_frames = 0; - int frames_encoded = 0; - const char *codec_arg = NULL; - const char *width_arg = NULL; - const char *height_arg = NULL; - const char *infile_arg = NULL; - const char *outfile_arg = NULL; - const char *keyframe_interval_arg = NULL; - - exec_name = argv[0]; - - if (argc != 9) die("Invalid number of arguments"); - - codec_arg = argv[1]; - width_arg = argv[2]; - height_arg = argv[3]; - infile_arg = argv[4]; - outfile_arg = argv[5]; - keyframe_interval_arg = argv[6]; - max_frames = (int)strtol(argv[8], NULL, 0); - - encoder = get_vpx_encoder_by_name(codec_arg); - if (!encoder) die("Unsupported codec."); - - info.codec_fourcc = encoder->fourcc; - info.frame_width = (int)strtol(width_arg, NULL, 0); - info.frame_height = (int)strtol(height_arg, NULL, 0); - info.time_base.numerator = 1; - info.time_base.denominator = fps; - - if (info.frame_width <= 0 || info.frame_height <= 0 || - (info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) { - die("Invalid frame size: %dx%d", info.frame_width, info.frame_height); - } - - if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, info.frame_width, - info.frame_height, 1)) { - die("Failed to allocate image."); - } - - keyframe_interval = (int)strtol(keyframe_interval_arg, NULL, 0); - if (keyframe_interval < 0) die("Invalid keyframe interval value."); - - printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface())); - - res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0); - if (res) die_codec(&codec, "Failed to get default codec config."); - - cfg.g_w = info.frame_width; - cfg.g_h = info.frame_height; - cfg.g_timebase.num = info.time_base.numerator; - cfg.g_timebase.den = info.time_base.denominator; - cfg.rc_target_bitrate = bitrate; - cfg.g_error_resilient = (vpx_codec_er_flags_t)strtoul(argv[7], NULL, 0); - - writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info); - if (!writer) die("Failed to open %s for writing.", outfile_arg); - - if (!(infile = fopen(infile_arg, "rb"))) - die("Failed to open %s for reading.", infile_arg); - - if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0)) - die("Failed to initialize encoder"); - - // Encode frames. - while (vpx_img_read(&raw, infile)) { - int flags = 0; - if (keyframe_interval > 0 && frame_count % keyframe_interval == 0) - flags |= VPX_EFLAG_FORCE_KF; - encode_frame(&codec, &raw, frame_count++, flags, writer); - frames_encoded++; - if (max_frames > 0 && frames_encoded >= max_frames) break; - } - - // Flush encoder. - while (encode_frame(&codec, NULL, -1, 0, writer)) { - } - - printf("\n"); - fclose(infile); - printf("Processed %d frames.\n", frame_count); - - vpx_img_free(&raw); - if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec."); - - vpx_video_writer_close(writer); - - return EXIT_SUCCESS; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/examples/svc_context.h b/presentation/src/main/cpp/third_party/libvpx/examples/svc_context.h deleted file mode 100644 index c5779ce8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/examples/svc_context.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/** - * SvcContext - input parameters and state to encode a multi-layered - * spatial SVC frame - */ - -#ifndef VPX_EXAMPLES_SVC_CONTEXT_H_ -#define VPX_EXAMPLES_SVC_CONTEXT_H_ - -#include "vpx/vp8cx.h" -#include "vpx/vpx_encoder.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum SVC_LOG_LEVEL { - SVC_LOG_ERROR, - SVC_LOG_INFO, - SVC_LOG_DEBUG -} SVC_LOG_LEVEL; - -typedef struct { - // public interface to svc_command options - int spatial_layers; // number of spatial layers - int temporal_layers; // number of temporal layers - int temporal_layering_mode; - SVC_LOG_LEVEL log_level; // amount of information to display - int output_rc_stat; // for outputting rc stats - int speed; // speed setting for codec - int threads; - int aqmode; // turns on aq-mode=3 (cyclic_refresh): 0=off, 1=on. - // private storage for vpx_svc_encode - void *internal; -} SvcContext; - -#define OPTION_BUFFER_SIZE 1024 -#define COMPONENTS 4 // psnr & sse statistics maintained for total, y, u, v - -typedef struct SvcInternal { - char options[OPTION_BUFFER_SIZE]; // set by vpx_svc_set_options - - // values extracted from option, quantizers - vpx_svc_extra_cfg_t svc_params; - int enable_auto_alt_ref[VPX_SS_MAX_LAYERS]; - int bitrates[VPX_MAX_LAYERS]; - - // accumulated statistics - double psnr_sum[VPX_SS_MAX_LAYERS][COMPONENTS]; // total/Y/U/V - uint64_t sse_sum[VPX_SS_MAX_LAYERS][COMPONENTS]; - uint32_t bytes_sum[VPX_SS_MAX_LAYERS]; - - // codec encoding values - int width; // width of highest layer - int height; // height of highest layer - int kf_dist; // distance between keyframes - - // state variables - int psnr_pkt_received; - int layer; - int use_multiple_frame_contexts; - - vpx_codec_ctx_t *codec_ctx; -} SvcInternal_t; - -/** - * Set SVC options - * options are supplied as a single string separated by spaces - * Format: encoding-mode= - * layers= - * scaling-factors=/,/,... - * quantizers=,,... - */ -vpx_codec_err_t vpx_svc_set_options(SvcContext *svc_ctx, const char *options); - -/** - * initialize SVC encoding - */ -vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx, - vpx_codec_iface_t *iface, - vpx_codec_enc_cfg_t *cfg); -/** - * encode a frame of video with multiple layers - */ -vpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx, - struct vpx_image *rawimg, vpx_codec_pts_t pts, - int64_t duration, int deadline); - -/** - * finished with svc encoding, release allocated resources - */ -void vpx_svc_release(SvcContext *svc_ctx); - -/** - * dump accumulated statistics and reset accumulated values - */ -void vpx_svc_dump_statistics(SvcContext *svc_ctx); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_EXAMPLES_SVC_CONTEXT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/examples/svc_encodeframe.c b/presentation/src/main/cpp/third_party/libvpx/examples/svc_encodeframe.c deleted file mode 100644 index 1dd73176..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/examples/svc_encodeframe.c +++ /dev/null @@ -1,634 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/** - * @file - * VP9 SVC encoding support via libvpx - */ - -#include -#include -#include -#include -#include -#include -#include -#define VPX_DISABLE_CTRL_TYPECHECKS 1 -#include "../tools_common.h" -#include "./vpx_config.h" -#include "./svc_context.h" -#include "vpx/vp8cx.h" -#include "vpx/vpx_encoder.h" -#include "vpx_mem/vpx_mem.h" -#include "vp9/common/vp9_onyxc_int.h" - -#ifdef __MINGW32__ -#define strtok_r strtok_s -#ifndef MINGW_HAS_SECURE_API -// proto from /usr/x86_64-w64-mingw32/include/sec_api/string_s.h -_CRTIMP char *__cdecl strtok_s(char *str, const char *delim, char **context); -#endif /* MINGW_HAS_SECURE_API */ -#endif /* __MINGW32__ */ - -#ifdef _MSC_VER -#define strdup _strdup -#define strtok_r strtok_s -#endif - -#define SVC_REFERENCE_FRAMES 8 -#define SUPERFRAME_SLOTS (8) -#define SUPERFRAME_BUFFER_SIZE (SUPERFRAME_SLOTS * sizeof(uint32_t) + 2) - -#define MAX_QUANTIZER 63 - -static const int DEFAULT_SCALE_FACTORS_NUM[VPX_SS_MAX_LAYERS] = { 4, 5, 7, 11, - 16 }; - -static const int DEFAULT_SCALE_FACTORS_DEN[VPX_SS_MAX_LAYERS] = { 16, 16, 16, - 16, 16 }; - -static const int DEFAULT_SCALE_FACTORS_NUM_2x[VPX_SS_MAX_LAYERS] = { 1, 2, 4 }; - -static const int DEFAULT_SCALE_FACTORS_DEN_2x[VPX_SS_MAX_LAYERS] = { 4, 4, 4 }; - -typedef enum { - QUANTIZER = 0, - BITRATE, - SCALE_FACTOR, - AUTO_ALT_REF, - ALL_OPTION_TYPES -} LAYER_OPTION_TYPE; - -static const int option_max_values[ALL_OPTION_TYPES] = { 63, INT_MAX, INT_MAX, - 1 }; - -static const int option_min_values[ALL_OPTION_TYPES] = { 0, 0, 1, 0 }; - -// One encoded frame -typedef struct FrameData { - void *buf; // compressed data buffer - size_t size; // length of compressed data - vpx_codec_frame_flags_t flags; /**< flags for this frame */ - struct FrameData *next; -} FrameData; - -static SvcInternal_t *get_svc_internal(SvcContext *svc_ctx) { - if (svc_ctx == NULL) return NULL; - if (svc_ctx->internal == NULL) { - SvcInternal_t *const si = (SvcInternal_t *)malloc(sizeof(*si)); - if (si != NULL) { - memset(si, 0, sizeof(*si)); - } - svc_ctx->internal = si; - } - return (SvcInternal_t *)svc_ctx->internal; -} - -static const SvcInternal_t *get_const_svc_internal(const SvcContext *svc_ctx) { - if (svc_ctx == NULL) return NULL; - return (const SvcInternal_t *)svc_ctx->internal; -} - -static VPX_TOOLS_FORMAT_PRINTF(3, 4) int svc_log(SvcContext *svc_ctx, - SVC_LOG_LEVEL level, - const char *fmt, ...) { - char buf[512]; - int retval = 0; - va_list ap; - - if (level > svc_ctx->log_level) { - return retval; - } - - va_start(ap, fmt); - retval = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - - printf("%s", buf); - - return retval; -} - -static vpx_codec_err_t extract_option(LAYER_OPTION_TYPE type, char *input, - int *value0, int *value1) { - if (type == SCALE_FACTOR) { - *value0 = (int)strtol(input, &input, 10); - if (*input++ != '/') return VPX_CODEC_INVALID_PARAM; - *value1 = (int)strtol(input, &input, 10); - - if (*value0 < option_min_values[SCALE_FACTOR] || - *value1 < option_min_values[SCALE_FACTOR] || - *value0 > option_max_values[SCALE_FACTOR] || - *value1 > option_max_values[SCALE_FACTOR] || - *value0 > *value1) // num shouldn't be greater than den - return VPX_CODEC_INVALID_PARAM; - } else { - *value0 = atoi(input); - if (*value0 < option_min_values[type] || *value0 > option_max_values[type]) - return VPX_CODEC_INVALID_PARAM; - } - return VPX_CODEC_OK; -} - -static vpx_codec_err_t parse_layer_options_from_string(SvcContext *svc_ctx, - LAYER_OPTION_TYPE type, - const char *input, - int *option0, - int *option1) { - int i; - vpx_codec_err_t res = VPX_CODEC_OK; - char *input_string; - char *token; - const char *delim = ","; - char *save_ptr; - int num_layers = svc_ctx->spatial_layers; - if (type == BITRATE) - num_layers = svc_ctx->spatial_layers * svc_ctx->temporal_layers; - - if (input == NULL || option0 == NULL || - (option1 == NULL && type == SCALE_FACTOR)) - return VPX_CODEC_INVALID_PARAM; - - input_string = strdup(input); - if (input_string == NULL) return VPX_CODEC_MEM_ERROR; - token = strtok_r(input_string, delim, &save_ptr); - for (i = 0; i < num_layers; ++i) { - if (token != NULL) { - res = extract_option(type, token, option0 + i, option1 + i); - if (res != VPX_CODEC_OK) break; - token = strtok_r(NULL, delim, &save_ptr); - } else { - break; - } - } - if (res == VPX_CODEC_OK && i != num_layers) { - svc_log(svc_ctx, SVC_LOG_ERROR, - "svc: layer params type: %d %d values required, " - "but only %d specified\n", - type, num_layers, i); - res = VPX_CODEC_INVALID_PARAM; - } - free(input_string); - return res; -} - -/** - * Parse SVC encoding options - * Format: encoding-mode=,layers= - * scale-factors=/,/,... - * quantizers=,,... - * svc_mode = [i|ip|alt_ip|gf] - */ -static vpx_codec_err_t parse_options(SvcContext *svc_ctx, const char *options) { - char *input_string; - char *option_name; - char *option_value; - char *input_ptr = NULL; - SvcInternal_t *const si = get_svc_internal(svc_ctx); - vpx_codec_err_t res = VPX_CODEC_OK; - int i, alt_ref_enabled = 0; - - if (options == NULL) return VPX_CODEC_OK; - input_string = strdup(options); - if (input_string == NULL) return VPX_CODEC_MEM_ERROR; - - // parse option name - option_name = strtok_r(input_string, "=", &input_ptr); - while (option_name != NULL) { - // parse option value - option_value = strtok_r(NULL, " ", &input_ptr); - if (option_value == NULL) { - svc_log(svc_ctx, SVC_LOG_ERROR, "option missing value: %s\n", - option_name); - res = VPX_CODEC_INVALID_PARAM; - break; - } - if (strcmp("spatial-layers", option_name) == 0) { - svc_ctx->spatial_layers = atoi(option_value); - } else if (strcmp("temporal-layers", option_name) == 0) { - svc_ctx->temporal_layers = atoi(option_value); - } else if (strcmp("scale-factors", option_name) == 0) { - res = parse_layer_options_from_string(svc_ctx, SCALE_FACTOR, option_value, - si->svc_params.scaling_factor_num, - si->svc_params.scaling_factor_den); - if (res != VPX_CODEC_OK) break; - } else if (strcmp("max-quantizers", option_name) == 0) { - res = - parse_layer_options_from_string(svc_ctx, QUANTIZER, option_value, - si->svc_params.max_quantizers, NULL); - if (res != VPX_CODEC_OK) break; - } else if (strcmp("min-quantizers", option_name) == 0) { - res = - parse_layer_options_from_string(svc_ctx, QUANTIZER, option_value, - si->svc_params.min_quantizers, NULL); - if (res != VPX_CODEC_OK) break; - } else if (strcmp("auto-alt-refs", option_name) == 0) { - res = parse_layer_options_from_string(svc_ctx, AUTO_ALT_REF, option_value, - si->enable_auto_alt_ref, NULL); - if (res != VPX_CODEC_OK) break; - } else if (strcmp("bitrates", option_name) == 0) { - res = parse_layer_options_from_string(svc_ctx, BITRATE, option_value, - si->bitrates, NULL); - if (res != VPX_CODEC_OK) break; - } else if (strcmp("multi-frame-contexts", option_name) == 0) { - si->use_multiple_frame_contexts = atoi(option_value); - } else { - svc_log(svc_ctx, SVC_LOG_ERROR, "invalid option: %s\n", option_name); - res = VPX_CODEC_INVALID_PARAM; - break; - } - option_name = strtok_r(NULL, "=", &input_ptr); - } - free(input_string); - - for (i = 0; i < svc_ctx->spatial_layers; ++i) { - if (si->svc_params.max_quantizers[i] > MAX_QUANTIZER || - si->svc_params.max_quantizers[i] < 0 || - si->svc_params.min_quantizers[i] > si->svc_params.max_quantizers[i] || - si->svc_params.min_quantizers[i] < 0) - res = VPX_CODEC_INVALID_PARAM; - } - - if (si->use_multiple_frame_contexts && - (svc_ctx->spatial_layers > 3 || - svc_ctx->spatial_layers * svc_ctx->temporal_layers > 4)) - res = VPX_CODEC_INVALID_PARAM; - - for (i = 0; i < svc_ctx->spatial_layers; ++i) - alt_ref_enabled += si->enable_auto_alt_ref[i]; - if (alt_ref_enabled > REF_FRAMES - svc_ctx->spatial_layers) { - svc_log(svc_ctx, SVC_LOG_ERROR, - "svc: auto alt ref: Maxinum %d(REF_FRAMES - layers) layers could" - "enabled auto alt reference frame, but %d layers are enabled\n", - REF_FRAMES - svc_ctx->spatial_layers, alt_ref_enabled); - res = VPX_CODEC_INVALID_PARAM; - } - - return res; -} - -vpx_codec_err_t vpx_svc_set_options(SvcContext *svc_ctx, const char *options) { - SvcInternal_t *const si = get_svc_internal(svc_ctx); - if (svc_ctx == NULL || options == NULL || si == NULL) { - return VPX_CODEC_INVALID_PARAM; - } - strncpy(si->options, options, sizeof(si->options) - 1); - si->options[sizeof(si->options) - 1] = '\0'; - return VPX_CODEC_OK; -} - -static vpx_codec_err_t assign_layer_bitrates( - const SvcContext *svc_ctx, vpx_codec_enc_cfg_t *const enc_cfg) { - int i; - const SvcInternal_t *const si = get_const_svc_internal(svc_ctx); - int sl, tl, spatial_layer_target; - - if (svc_ctx->temporal_layering_mode != 0) { - if (si->bitrates[0] != 0) { - unsigned int total_bitrate = 0; - for (sl = 0; sl < svc_ctx->spatial_layers; ++sl) { - total_bitrate += si->bitrates[sl * svc_ctx->temporal_layers + - svc_ctx->temporal_layers - 1]; - for (tl = 0; tl < svc_ctx->temporal_layers; ++tl) { - enc_cfg->ss_target_bitrate[sl * svc_ctx->temporal_layers] += - (unsigned int)si->bitrates[sl * svc_ctx->temporal_layers + tl]; - enc_cfg->layer_target_bitrate[sl * svc_ctx->temporal_layers + tl] = - si->bitrates[sl * svc_ctx->temporal_layers + tl]; - if (tl > 0 && (si->bitrates[sl * svc_ctx->temporal_layers + tl] <= - si->bitrates[sl * svc_ctx->temporal_layers + tl - 1])) - return VPX_CODEC_INVALID_PARAM; - } - } - if (total_bitrate != enc_cfg->rc_target_bitrate) - return VPX_CODEC_INVALID_PARAM; - } else { - float total = 0; - float alloc_ratio[VPX_MAX_LAYERS] = { 0 }; - - for (sl = 0; sl < svc_ctx->spatial_layers; ++sl) { - if (si->svc_params.scaling_factor_den[sl] > 0) { - alloc_ratio[sl] = (float)(pow(2, sl)); - total += alloc_ratio[sl]; - } - } - - for (sl = 0; sl < svc_ctx->spatial_layers; ++sl) { - enc_cfg->ss_target_bitrate[sl] = spatial_layer_target = - (unsigned int)(enc_cfg->rc_target_bitrate * alloc_ratio[sl] / - total); - if (svc_ctx->temporal_layering_mode == 3) { - enc_cfg->layer_target_bitrate[sl * svc_ctx->temporal_layers] = - (spatial_layer_target * 6) / 10; // 60% - enc_cfg->layer_target_bitrate[sl * svc_ctx->temporal_layers + 1] = - (spatial_layer_target * 8) / 10; // 80% - enc_cfg->layer_target_bitrate[sl * svc_ctx->temporal_layers + 2] = - spatial_layer_target; - } else if (svc_ctx->temporal_layering_mode == 2 || - svc_ctx->temporal_layering_mode == 1) { - enc_cfg->layer_target_bitrate[sl * svc_ctx->temporal_layers] = - spatial_layer_target * 2 / 3; - enc_cfg->layer_target_bitrate[sl * svc_ctx->temporal_layers + 1] = - spatial_layer_target; - } else { - // User should explicitly assign bitrates in this case. - assert(0); - } - } - } - } else { - if (si->bitrates[0] != 0) { - unsigned int total_bitrate = 0; - for (i = 0; i < svc_ctx->spatial_layers; ++i) { - enc_cfg->ss_target_bitrate[i] = (unsigned int)si->bitrates[i]; - enc_cfg->layer_target_bitrate[i] = (unsigned int)si->bitrates[i]; - total_bitrate += si->bitrates[i]; - } - if (total_bitrate != enc_cfg->rc_target_bitrate) - return VPX_CODEC_INVALID_PARAM; - } else { - float total = 0; - float alloc_ratio[VPX_MAX_LAYERS] = { 0 }; - - for (i = 0; i < svc_ctx->spatial_layers; ++i) { - if (si->svc_params.scaling_factor_den[i] > 0) { - alloc_ratio[i] = (float)(si->svc_params.scaling_factor_num[i] * 1.0 / - si->svc_params.scaling_factor_den[i]); - - alloc_ratio[i] *= alloc_ratio[i]; - total += alloc_ratio[i]; - } - } - for (i = 0; i < VPX_SS_MAX_LAYERS; ++i) { - if (total > 0) { - enc_cfg->layer_target_bitrate[i] = - (unsigned int)(enc_cfg->rc_target_bitrate * alloc_ratio[i] / - total); - } - } - } - } - return VPX_CODEC_OK; -} - -vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx, - vpx_codec_iface_t *iface, - vpx_codec_enc_cfg_t *enc_cfg) { - vpx_codec_err_t res; - int sl, tl; - SvcInternal_t *const si = get_svc_internal(svc_ctx); - if (svc_ctx == NULL || codec_ctx == NULL || iface == NULL || - enc_cfg == NULL) { - return VPX_CODEC_INVALID_PARAM; - } - if (si == NULL) return VPX_CODEC_MEM_ERROR; - - si->codec_ctx = codec_ctx; - - si->width = enc_cfg->g_w; - si->height = enc_cfg->g_h; - - si->kf_dist = enc_cfg->kf_max_dist; - - if (svc_ctx->spatial_layers == 0) - svc_ctx->spatial_layers = VPX_SS_DEFAULT_LAYERS; - if (svc_ctx->spatial_layers < 1 || - svc_ctx->spatial_layers > VPX_SS_MAX_LAYERS) { - svc_log(svc_ctx, SVC_LOG_ERROR, "spatial layers: invalid value: %d\n", - svc_ctx->spatial_layers); - return VPX_CODEC_INVALID_PARAM; - } - - // Note: temporal_layering_mode only applies to one-pass CBR - // si->svc_params.temporal_layering_mode = svc_ctx->temporal_layering_mode; - if (svc_ctx->temporal_layering_mode == 3) { - svc_ctx->temporal_layers = 3; - } else if (svc_ctx->temporal_layering_mode == 2 || - svc_ctx->temporal_layering_mode == 1) { - svc_ctx->temporal_layers = 2; - } - - for (sl = 0; sl < VPX_SS_MAX_LAYERS; ++sl) { - si->svc_params.scaling_factor_num[sl] = DEFAULT_SCALE_FACTORS_NUM[sl]; - si->svc_params.scaling_factor_den[sl] = DEFAULT_SCALE_FACTORS_DEN[sl]; - si->svc_params.speed_per_layer[sl] = svc_ctx->speed; - } - if (enc_cfg->rc_end_usage == VPX_CBR && enc_cfg->g_pass == VPX_RC_ONE_PASS && - svc_ctx->spatial_layers <= 3) { - for (sl = 0; sl < svc_ctx->spatial_layers; ++sl) { - int sl2 = (svc_ctx->spatial_layers == 2) ? sl + 1 : sl; - si->svc_params.scaling_factor_num[sl] = DEFAULT_SCALE_FACTORS_NUM_2x[sl2]; - si->svc_params.scaling_factor_den[sl] = DEFAULT_SCALE_FACTORS_DEN_2x[sl2]; - } - if (svc_ctx->spatial_layers == 1) { - si->svc_params.scaling_factor_num[0] = 1; - si->svc_params.scaling_factor_den[0] = 1; - } - } - for (tl = 0; tl < svc_ctx->temporal_layers; ++tl) { - for (sl = 0; sl < svc_ctx->spatial_layers; ++sl) { - const int i = sl * svc_ctx->temporal_layers + tl; - si->svc_params.max_quantizers[i] = MAX_QUANTIZER; - si->svc_params.min_quantizers[i] = 0; - if (enc_cfg->rc_end_usage == VPX_CBR && - enc_cfg->g_pass == VPX_RC_ONE_PASS) { - si->svc_params.max_quantizers[i] = 56; - si->svc_params.min_quantizers[i] = 2; - } - } - } - - // Parse aggregate command line options. Options must start with - // "layers=xx" then followed by other options - res = parse_options(svc_ctx, si->options); - if (res != VPX_CODEC_OK) return res; - - if (svc_ctx->spatial_layers < 1) svc_ctx->spatial_layers = 1; - if (svc_ctx->spatial_layers > VPX_SS_MAX_LAYERS) - svc_ctx->spatial_layers = VPX_SS_MAX_LAYERS; - - if (svc_ctx->temporal_layers < 1) svc_ctx->temporal_layers = 1; - if (svc_ctx->temporal_layers > VPX_TS_MAX_LAYERS) - svc_ctx->temporal_layers = VPX_TS_MAX_LAYERS; - - if (svc_ctx->temporal_layers * svc_ctx->spatial_layers > VPX_MAX_LAYERS) { - svc_log( - svc_ctx, SVC_LOG_ERROR, - "spatial layers * temporal layers (%d) exceeds the maximum number of " - "allowed layers of %d\n", - svc_ctx->spatial_layers * svc_ctx->temporal_layers, VPX_MAX_LAYERS); - return VPX_CODEC_INVALID_PARAM; - } - res = assign_layer_bitrates(svc_ctx, enc_cfg); - if (res != VPX_CODEC_OK) { - svc_log(svc_ctx, SVC_LOG_ERROR, - "layer bitrates incorrect: \n" - "1) spatial layer bitrates should sum up to target \n" - "2) temporal layer bitrates should be increasing within \n" - "a spatial layer \n"); - return VPX_CODEC_INVALID_PARAM; - } - - if (svc_ctx->temporal_layers > 1) { - int i; - for (i = 0; i < svc_ctx->temporal_layers; ++i) { - enc_cfg->ts_target_bitrate[i] = - enc_cfg->rc_target_bitrate / svc_ctx->temporal_layers; - enc_cfg->ts_rate_decimator[i] = 1 << (svc_ctx->temporal_layers - 1 - i); - } - } - - if (svc_ctx->threads) enc_cfg->g_threads = svc_ctx->threads; - - // Modify encoder configuration - enc_cfg->ss_number_layers = svc_ctx->spatial_layers; - enc_cfg->ts_number_layers = svc_ctx->temporal_layers; - - if (enc_cfg->rc_end_usage == VPX_CBR) { - enc_cfg->rc_resize_allowed = 0; - enc_cfg->rc_min_quantizer = 2; - enc_cfg->rc_max_quantizer = 56; - enc_cfg->rc_undershoot_pct = 50; - enc_cfg->rc_overshoot_pct = 50; - enc_cfg->rc_buf_initial_sz = 500; - enc_cfg->rc_buf_optimal_sz = 600; - enc_cfg->rc_buf_sz = 1000; - } - - for (tl = 0; tl < svc_ctx->temporal_layers; ++tl) { - for (sl = 0; sl < svc_ctx->spatial_layers; ++sl) { - const int i = sl * svc_ctx->temporal_layers + tl; - if (enc_cfg->rc_end_usage == VPX_CBR && - enc_cfg->g_pass == VPX_RC_ONE_PASS) { - si->svc_params.max_quantizers[i] = enc_cfg->rc_max_quantizer; - si->svc_params.min_quantizers[i] = enc_cfg->rc_min_quantizer; - } - } - } - - if (enc_cfg->g_error_resilient == 0 && si->use_multiple_frame_contexts == 0) - enc_cfg->g_error_resilient = 1; - - // Initialize codec - res = vpx_codec_enc_init(codec_ctx, iface, enc_cfg, VPX_CODEC_USE_PSNR); - if (res != VPX_CODEC_OK) { - svc_log(svc_ctx, SVC_LOG_ERROR, "svc_enc_init error\n"); - return res; - } - if (svc_ctx->spatial_layers > 1 || svc_ctx->temporal_layers > 1) { - vpx_codec_control(codec_ctx, VP9E_SET_SVC, 1); - vpx_codec_control(codec_ctx, VP9E_SET_SVC_PARAMETERS, &si->svc_params); - } - return VPX_CODEC_OK; -} - -/** - * Encode a frame into multiple layers - * Create a superframe containing the individual layers - */ -vpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx, - struct vpx_image *rawimg, vpx_codec_pts_t pts, - int64_t duration, int deadline) { - vpx_codec_err_t res; - vpx_codec_iter_t iter; - const vpx_codec_cx_pkt_t *cx_pkt; - SvcInternal_t *const si = get_svc_internal(svc_ctx); - if (svc_ctx == NULL || codec_ctx == NULL || si == NULL) { - return VPX_CODEC_INVALID_PARAM; - } - - res = - vpx_codec_encode(codec_ctx, rawimg, pts, (uint32_t)duration, 0, deadline); - if (res != VPX_CODEC_OK) { - return res; - } - // save compressed data - iter = NULL; - while ((cx_pkt = vpx_codec_get_cx_data(codec_ctx, &iter))) { - switch (cx_pkt->kind) { - case VPX_CODEC_PSNR_PKT: ++si->psnr_pkt_received; break; - default: break; - } - } - - return VPX_CODEC_OK; -} - -static double calc_psnr(double d) { - if (d == 0) return 100; - return -10.0 * log(d) / log(10.0); -} - -// dump accumulated statistics and reset accumulated values -void vpx_svc_dump_statistics(SvcContext *svc_ctx) { - int number_of_frames; - int i, j; - uint32_t bytes_total = 0; - double scale[COMPONENTS]; - double psnr[COMPONENTS]; - double mse[COMPONENTS]; - double y_scale; - - SvcInternal_t *const si = get_svc_internal(svc_ctx); - if (svc_ctx == NULL || si == NULL) return; - - number_of_frames = si->psnr_pkt_received; - if (number_of_frames <= 0) return; - - svc_log(svc_ctx, SVC_LOG_INFO, "\n"); - for (i = 0; i < svc_ctx->spatial_layers; ++i) { - svc_log(svc_ctx, SVC_LOG_INFO, - "Layer %d Average PSNR=[%2.3f, %2.3f, %2.3f, %2.3f], Bytes=[%u]\n", - i, si->psnr_sum[i][0] / number_of_frames, - si->psnr_sum[i][1] / number_of_frames, - si->psnr_sum[i][2] / number_of_frames, - si->psnr_sum[i][3] / number_of_frames, si->bytes_sum[i]); - // the following psnr calculation is deduced from ffmpeg.c#print_report - y_scale = si->width * si->height * 255.0 * 255.0 * number_of_frames; - scale[1] = y_scale; - scale[2] = scale[3] = y_scale / 4; // U or V - scale[0] = y_scale * 1.5; // total - - for (j = 0; j < COMPONENTS; j++) { - psnr[j] = calc_psnr(si->sse_sum[i][j] / scale[j]); - mse[j] = si->sse_sum[i][j] * 255.0 * 255.0 / scale[j]; - } - svc_log(svc_ctx, SVC_LOG_INFO, - "Layer %d Overall PSNR=[%2.3f, %2.3f, %2.3f, %2.3f]\n", i, psnr[0], - psnr[1], psnr[2], psnr[3]); - svc_log(svc_ctx, SVC_LOG_INFO, - "Layer %d Overall MSE=[%2.3f, %2.3f, %2.3f, %2.3f]\n", i, mse[0], - mse[1], mse[2], mse[3]); - - bytes_total += si->bytes_sum[i]; - // Clear sums for next time. - si->bytes_sum[i] = 0; - for (j = 0; j < COMPONENTS; ++j) { - si->psnr_sum[i][j] = 0; - si->sse_sum[i][j] = 0; - } - } - - // only display statistics once - si->psnr_pkt_received = 0; - - svc_log(svc_ctx, SVC_LOG_INFO, "Total Bytes=[%u]\n", bytes_total); -} - -void vpx_svc_release(SvcContext *svc_ctx) { - SvcInternal_t *si; - if (svc_ctx == NULL) return; - // do not use get_svc_internal as it will unnecessarily allocate an - // SvcInternal_t if it was not already allocated - si = (SvcInternal_t *)svc_ctx->internal; - if (si != NULL) { - free(si); - svc_ctx->internal = NULL; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/examples/twopass_encoder.c b/presentation/src/main/cpp/third_party/libvpx/examples/twopass_encoder.c deleted file mode 100644 index 07a10d9c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/examples/twopass_encoder.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Two Pass Encoder -// ================ -// -// This is an example of a two pass encoder loop. It takes an input file in -// YV12 format, passes it through the encoder twice, and writes the compressed -// frames to disk in IVF format. It builds upon the simple_encoder example. -// -// Twopass Variables -// ----------------- -// Twopass mode needs to track the current pass number and the buffer of -// statistics packets. -// -// Updating The Configuration -// --------------------------------- -// In two pass mode, the configuration has to be updated on each pass. The -// statistics buffer is passed on the last pass. -// -// Encoding A Frame -// ---------------- -// Encoding a frame in two pass mode is identical to the simple encoder -// example. To increase the quality while sacrificing encoding speed, -// VPX_DL_BEST_QUALITY can be used in place of VPX_DL_GOOD_QUALITY. -// -// Processing Statistics Packets -// ----------------------------- -// Each packet of type `VPX_CODEC_CX_FRAME_PKT` contains the encoded data -// for this frame. We write a IVF frame header, followed by the raw data. -// -// -// Pass Progress Reporting -// ----------------------------- -// It's sometimes helpful to see when each pass completes. -// -// -// Clean-up -// ----------------------------- -// Destruction of the encoder instance must be done on each pass. The -// raw image should be destroyed at the end as usual. - -#include -#include -#include - -#include "vpx/vpx_encoder.h" - -#include "../tools_common.h" -#include "../video_writer.h" - -static const char *exec_name; - -void usage_exit(void) { - fprintf(stderr, - "Usage: %s " - "\n", - exec_name); - exit(EXIT_FAILURE); -} - -static int get_frame_stats(vpx_codec_ctx_t *ctx, const vpx_image_t *img, - vpx_codec_pts_t pts, unsigned int duration, - vpx_enc_frame_flags_t flags, unsigned int deadline, - vpx_fixed_buf_t *stats) { - int got_pkts = 0; - vpx_codec_iter_t iter = NULL; - const vpx_codec_cx_pkt_t *pkt = NULL; - const vpx_codec_err_t res = - vpx_codec_encode(ctx, img, pts, duration, flags, deadline); - if (res != VPX_CODEC_OK) die_codec(ctx, "Failed to get frame stats."); - - while ((pkt = vpx_codec_get_cx_data(ctx, &iter)) != NULL) { - got_pkts = 1; - - if (pkt->kind == VPX_CODEC_STATS_PKT) { - const uint8_t *const pkt_buf = pkt->data.twopass_stats.buf; - const size_t pkt_size = pkt->data.twopass_stats.sz; - stats->buf = realloc(stats->buf, stats->sz + pkt_size); - if (!stats->buf) die("Failed to reallocate stats buffer."); - memcpy((uint8_t *)stats->buf + stats->sz, pkt_buf, pkt_size); - stats->sz += pkt_size; - } - } - - return got_pkts; -} - -static int encode_frame(vpx_codec_ctx_t *ctx, const vpx_image_t *img, - vpx_codec_pts_t pts, unsigned int duration, - vpx_enc_frame_flags_t flags, unsigned int deadline, - VpxVideoWriter *writer) { - int got_pkts = 0; - vpx_codec_iter_t iter = NULL; - const vpx_codec_cx_pkt_t *pkt = NULL; - const vpx_codec_err_t res = - vpx_codec_encode(ctx, img, pts, duration, flags, deadline); - if (res != VPX_CODEC_OK) die_codec(ctx, "Failed to encode frame."); - - while ((pkt = vpx_codec_get_cx_data(ctx, &iter)) != NULL) { - got_pkts = 1; - if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { - const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0; - - if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf, - pkt->data.frame.sz, - pkt->data.frame.pts)) - die_codec(ctx, "Failed to write compressed frame."); - printf(keyframe ? "K" : "."); - fflush(stdout); - } - } - - return got_pkts; -} - -static vpx_fixed_buf_t pass0(vpx_image_t *raw, FILE *infile, - const VpxInterface *encoder, - const vpx_codec_enc_cfg_t *cfg, int max_frames) { - vpx_codec_ctx_t codec; - int frame_count = 0; - vpx_fixed_buf_t stats = { NULL, 0 }; - - if (vpx_codec_enc_init(&codec, encoder->codec_interface(), cfg, 0)) - die("Failed to initialize encoder"); - - // Calculate frame statistics. - while (vpx_img_read(raw, infile)) { - ++frame_count; - get_frame_stats(&codec, raw, frame_count, 1, 0, VPX_DL_GOOD_QUALITY, - &stats); - if (max_frames > 0 && frame_count >= max_frames) break; - } - - // Flush encoder. - while (get_frame_stats(&codec, NULL, frame_count, 1, 0, VPX_DL_GOOD_QUALITY, - &stats)) { - } - - printf("Pass 0 complete. Processed %d frames.\n", frame_count); - if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec."); - - return stats; -} - -static void pass1(vpx_image_t *raw, FILE *infile, const char *outfile_name, - const VpxInterface *encoder, const vpx_codec_enc_cfg_t *cfg, - int max_frames) { - VpxVideoInfo info = { encoder->fourcc, - cfg->g_w, - cfg->g_h, - { cfg->g_timebase.num, cfg->g_timebase.den } }; - VpxVideoWriter *writer = NULL; - vpx_codec_ctx_t codec; - int frame_count = 0; - - writer = vpx_video_writer_open(outfile_name, kContainerIVF, &info); - if (!writer) die("Failed to open %s for writing", outfile_name); - - if (vpx_codec_enc_init(&codec, encoder->codec_interface(), cfg, 0)) - die("Failed to initialize encoder"); - - // Encode frames. - while (vpx_img_read(raw, infile)) { - ++frame_count; - encode_frame(&codec, raw, frame_count, 1, 0, VPX_DL_GOOD_QUALITY, writer); - - if (max_frames > 0 && frame_count >= max_frames) break; - } - - // Flush encoder. - while (encode_frame(&codec, NULL, -1, 1, 0, VPX_DL_GOOD_QUALITY, writer)) { - } - - printf("\n"); - - if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec."); - - vpx_video_writer_close(writer); - - printf("Pass 1 complete. Processed %d frames.\n", frame_count); -} - -int main(int argc, char **argv) { - FILE *infile = NULL; - int w, h; - vpx_codec_ctx_t codec; - vpx_codec_enc_cfg_t cfg; - vpx_image_t raw; - vpx_codec_err_t res; - vpx_fixed_buf_t stats; - - const VpxInterface *encoder = NULL; - const int fps = 30; // TODO(dkovalev) add command line argument - const int bitrate = 200; // kbit/s TODO(dkovalev) add command line argument - const char *const codec_arg = argv[1]; - const char *const width_arg = argv[2]; - const char *const height_arg = argv[3]; - const char *const infile_arg = argv[4]; - const char *const outfile_arg = argv[5]; - int max_frames = 0; - exec_name = argv[0]; - - if (argc != 7) die("Invalid number of arguments."); - - max_frames = (int)strtol(argv[6], NULL, 0); - - encoder = get_vpx_encoder_by_name(codec_arg); - if (!encoder) die("Unsupported codec."); - - w = (int)strtol(width_arg, NULL, 0); - h = (int)strtol(height_arg, NULL, 0); - - if (w <= 0 || h <= 0 || (w % 2) != 0 || (h % 2) != 0) - die("Invalid frame size: %dx%d", w, h); - - if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, w, h, 1)) - die("Failed to allocate image (%dx%d)", w, h); - - printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface())); - - // Configuration - res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0); - if (res) die_codec(&codec, "Failed to get default codec config."); - - cfg.g_w = w; - cfg.g_h = h; - cfg.g_timebase.num = 1; - cfg.g_timebase.den = fps; - cfg.rc_target_bitrate = bitrate; - - if (!(infile = fopen(infile_arg, "rb"))) - die("Failed to open %s for reading", infile_arg); - - // Pass 0 - cfg.g_pass = VPX_RC_FIRST_PASS; - stats = pass0(&raw, infile, encoder, &cfg, max_frames); - - // Pass 1 - rewind(infile); - cfg.g_pass = VPX_RC_LAST_PASS; - cfg.rc_twopass_stats_in = stats; - pass1(&raw, infile, outfile_arg, encoder, &cfg, max_frames); - free(stats.buf); - - vpx_img_free(&raw); - fclose(infile); - - return EXIT_SUCCESS; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/examples/vp8_multi_resolution_encoder.c b/presentation/src/main/cpp/third_party/libvpx/examples/vp8_multi_resolution_encoder.c deleted file mode 100644 index 62d96de5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/examples/vp8_multi_resolution_encoder.c +++ /dev/null @@ -1,666 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * This is an example demonstrating multi-resolution encoding in VP8. - * High-resolution input video is down-sampled to lower-resolutions. The - * encoder then encodes the video and outputs multiple bitstreams with - * different resolutions. - * - * This test also allows for settings temporal layers for each spatial layer. - * Different number of temporal layers per spatial stream may be used. - * Currently up to 3 temporal layers per spatial stream (encoder) are supported - * in this test. - */ - -#include "./vpx_config.h" - -#include -#include -#include -#include -#include -#include -#include -#include "vpx_ports/vpx_timer.h" -#include "vpx/vpx_encoder.h" -#include "vpx/vp8cx.h" -#include "vpx_ports/mem_ops.h" -#include "../tools_common.h" -#define interface (vpx_codec_vp8_cx()) -#define fourcc 0x30385056 - -void usage_exit(void) { exit(EXIT_FAILURE); } - -/* - * The input video frame is downsampled several times to generate a multi-level - * hierarchical structure. NUM_ENCODERS is defined as the number of encoding - * levels required. For example, if the size of input video is 1280x720, - * NUM_ENCODERS is 3, and down-sampling factor is 2, the encoder outputs 3 - * bitstreams with resolution of 1280x720(level 0), 640x360(level 1), and - * 320x180(level 2) respectively. - */ - -/* Number of encoders (spatial resolutions) used in this test. */ -#define NUM_ENCODERS 3 - -/* Maximum number of temporal layers allowed for this test. */ -#define MAX_NUM_TEMPORAL_LAYERS 3 - -/* This example uses the scaler function in libyuv. */ -#include "third_party/libyuv/include/libyuv/basic_types.h" -#include "third_party/libyuv/include/libyuv/scale.h" -#include "third_party/libyuv/include/libyuv/cpu_id.h" - -int (*read_frame_p)(FILE *f, vpx_image_t *img); - -static int mulres_read_frame(FILE *f, vpx_image_t *img) { - size_t nbytes, to_read; - int res = 1; - - to_read = img->w * img->h * 3 / 2; - nbytes = fread(img->planes[0], 1, to_read, f); - if (nbytes != to_read) { - res = 0; - if (nbytes > 0) - printf("Warning: Read partial frame. Check your width & height!\n"); - } - return res; -} - -static int mulres_read_frame_by_row(FILE *f, vpx_image_t *img) { - size_t nbytes, to_read; - int res = 1; - int plane; - - for (plane = 0; plane < 3; plane++) { - unsigned char *ptr; - int w = (plane ? (1 + img->d_w) / 2 : img->d_w); - int h = (plane ? (1 + img->d_h) / 2 : img->d_h); - int r; - - /* Determine the correct plane based on the image format. The for-loop - * always counts in Y,U,V order, but this may not match the order of - * the data on disk. - */ - switch (plane) { - case 1: - ptr = img->planes[img->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_V - : VPX_PLANE_U]; - break; - case 2: - ptr = img->planes[img->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_U - : VPX_PLANE_V]; - break; - default: ptr = img->planes[plane]; - } - - for (r = 0; r < h; r++) { - to_read = w; - - nbytes = fread(ptr, 1, to_read, f); - if (nbytes != to_read) { - res = 0; - if (nbytes > 0) - printf("Warning: Read partial frame. Check your width & height!\n"); - break; - } - - ptr += img->stride[plane]; - } - if (!res) break; - } - - return res; -} - -static void write_ivf_file_header(FILE *outfile, const vpx_codec_enc_cfg_t *cfg, - int frame_cnt) { - char header[32]; - - if (cfg->g_pass != VPX_RC_ONE_PASS && cfg->g_pass != VPX_RC_LAST_PASS) return; - header[0] = 'D'; - header[1] = 'K'; - header[2] = 'I'; - header[3] = 'F'; - mem_put_le16(header + 4, 0); /* version */ - mem_put_le16(header + 6, 32); /* headersize */ - mem_put_le32(header + 8, fourcc); /* headersize */ - mem_put_le16(header + 12, cfg->g_w); /* width */ - mem_put_le16(header + 14, cfg->g_h); /* height */ - mem_put_le32(header + 16, cfg->g_timebase.den); /* rate */ - mem_put_le32(header + 20, cfg->g_timebase.num); /* scale */ - mem_put_le32(header + 24, frame_cnt); /* length */ - mem_put_le32(header + 28, 0); /* unused */ - - (void)fwrite(header, 1, 32, outfile); -} - -static void write_ivf_frame_header(FILE *outfile, - const vpx_codec_cx_pkt_t *pkt) { - char header[12]; - vpx_codec_pts_t pts; - - if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return; - - pts = pkt->data.frame.pts; - mem_put_le32(header, (int)pkt->data.frame.sz); - mem_put_le32(header + 4, pts & 0xFFFFFFFF); - mem_put_le32(header + 8, pts >> 32); - - (void)fwrite(header, 1, 12, outfile); -} - -/* Temporal scaling parameters */ -/* This sets all the temporal layer parameters given |num_temporal_layers|, - * including the target bit allocation across temporal layers. Bit allocation - * parameters will be passed in as user parameters in another version. - */ -static void set_temporal_layer_pattern(int num_temporal_layers, - vpx_codec_enc_cfg_t *cfg, int bitrate, - int *layer_flags) { - assert(num_temporal_layers <= MAX_NUM_TEMPORAL_LAYERS); - switch (num_temporal_layers) { - case 1: { - /* 1-layer */ - cfg->ts_number_layers = 1; - cfg->ts_periodicity = 1; - cfg->ts_rate_decimator[0] = 1; - cfg->ts_layer_id[0] = 0; - cfg->ts_target_bitrate[0] = bitrate; - - // Update L only. - layer_flags[0] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; - break; - } - - case 2: { - /* 2-layers, with sync point at first frame of layer 1. */ - cfg->ts_number_layers = 2; - cfg->ts_periodicity = 2; - cfg->ts_rate_decimator[0] = 2; - cfg->ts_rate_decimator[1] = 1; - cfg->ts_layer_id[0] = 0; - cfg->ts_layer_id[1] = 1; - // Use 60/40 bit allocation as example. - cfg->ts_target_bitrate[0] = (int)(0.6f * bitrate); - cfg->ts_target_bitrate[1] = bitrate; - - /* 0=L, 1=GF */ - // ARF is used as predictor for all frames, and is only updated on - // key frame. Sync point every 8 frames. - - // Layer 0: predict from L and ARF, update L and G. - layer_flags[0] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF; - - // Layer 1: sync point: predict from L and ARF, and update G. - layer_flags[1] = - VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF; - - // Layer 0, predict from L and ARF, update L. - layer_flags[2] = - VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; - - // Layer 1: predict from L, G and ARF, and update G. - layer_flags[3] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | - VP8_EFLAG_NO_UPD_ENTROPY; - - // Layer 0 - layer_flags[4] = layer_flags[2]; - - // Layer 1 - layer_flags[5] = layer_flags[3]; - - // Layer 0 - layer_flags[6] = layer_flags[4]; - - // Layer 1 - layer_flags[7] = layer_flags[5]; - break; - } - - case 3: - default: { - // 3-layers structure where ARF is used as predictor for all frames, - // and is only updated on key frame. - // Sync points for layer 1 and 2 every 8 frames. - cfg->ts_number_layers = 3; - cfg->ts_periodicity = 4; - cfg->ts_rate_decimator[0] = 4; - cfg->ts_rate_decimator[1] = 2; - cfg->ts_rate_decimator[2] = 1; - cfg->ts_layer_id[0] = 0; - cfg->ts_layer_id[1] = 2; - cfg->ts_layer_id[2] = 1; - cfg->ts_layer_id[3] = 2; - // Use 45/20/35 bit allocation as example. - cfg->ts_target_bitrate[0] = (int)(0.45f * bitrate); - cfg->ts_target_bitrate[1] = (int)(0.65f * bitrate); - cfg->ts_target_bitrate[2] = bitrate; - - /* 0=L, 1=GF, 2=ARF */ - - // Layer 0: predict from L and ARF; update L and G. - layer_flags[0] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF; - - // Layer 2: sync point: predict from L and ARF; update none. - layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | - VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | - VP8_EFLAG_NO_UPD_ENTROPY; - - // Layer 1: sync point: predict from L and ARF; update G. - layer_flags[2] = - VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; - - // Layer 2: predict from L, G, ARF; update none. - layer_flags[3] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | - VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY; - - // Layer 0: predict from L and ARF; update L. - layer_flags[4] = - VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF; - - // Layer 2: predict from L, G, ARF; update none. - layer_flags[5] = layer_flags[3]; - - // Layer 1: predict from L, G, ARF; update G. - layer_flags[6] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; - - // Layer 2: predict from L, G, ARF; update none. - layer_flags[7] = layer_flags[3]; - break; - } - } -} - -/* The periodicity of the pattern given the number of temporal layers. */ -static int periodicity_to_num_layers[MAX_NUM_TEMPORAL_LAYERS] = { 1, 8, 8 }; - -int main(int argc, char **argv) { - FILE *infile, *outfile[NUM_ENCODERS]; - FILE *downsampled_input[NUM_ENCODERS - 1]; - char filename[50]; - vpx_codec_ctx_t codec[NUM_ENCODERS]; - vpx_codec_enc_cfg_t cfg[NUM_ENCODERS]; - int frame_cnt = 0; - vpx_image_t raw[NUM_ENCODERS]; - vpx_codec_err_t res[NUM_ENCODERS]; - - int i; - int width; - int height; - int length_frame; - int frame_avail; - int got_data; - int flags = 0; - int layer_id = 0; - - int layer_flags[VPX_TS_MAX_PERIODICITY * NUM_ENCODERS] = { 0 }; - int flag_periodicity; - - /*Currently, only realtime mode is supported in multi-resolution encoding.*/ - int arg_deadline = VPX_DL_REALTIME; - - /* Set show_psnr to 1/0 to show/not show PSNR. Choose show_psnr=0 if you - don't need to know PSNR, which will skip PSNR calculation and save - encoding time. */ - int show_psnr = 0; - int key_frame_insert = 0; - uint64_t psnr_sse_total[NUM_ENCODERS] = { 0 }; - uint64_t psnr_samples_total[NUM_ENCODERS] = { 0 }; - double psnr_totals[NUM_ENCODERS][4] = { { 0, 0 } }; - int psnr_count[NUM_ENCODERS] = { 0 }; - - int64_t cx_time = 0; - - /* Set the required target bitrates for each resolution level. - * If target bitrate for highest-resolution level is set to 0, - * (i.e. target_bitrate[0]=0), we skip encoding at that level. - */ - unsigned int target_bitrate[NUM_ENCODERS] = { 1000, 500, 100 }; - - /* Enter the frame rate of the input video */ - int framerate = 30; - - /* Set down-sampling factor for each resolution level. - dsf[0] controls down sampling from level 0 to level 1; - dsf[1] controls down sampling from level 1 to level 2; - dsf[2] is not used. */ - vpx_rational_t dsf[NUM_ENCODERS] = { { 2, 1 }, { 2, 1 }, { 1, 1 } }; - - /* Set the number of temporal layers for each encoder/resolution level, - * starting from highest resoln down to lowest resoln. */ - unsigned int num_temporal_layers[NUM_ENCODERS] = { 3, 3, 3 }; - - if (argc != (7 + 3 * NUM_ENCODERS)) - die("Usage: %s " - " \n", - argv[0]); - - printf("Using %s\n", vpx_codec_iface_name(interface)); - - width = (int)strtol(argv[1], NULL, 0); - height = (int)strtol(argv[2], NULL, 0); - framerate = (int)strtol(argv[3], NULL, 0); - - if (width < 16 || width % 2 || height < 16 || height % 2) - die("Invalid resolution: %dx%d", width, height); - - /* Open input video file for encoding */ - if (!(infile = fopen(argv[4], "rb"))) - die("Failed to open %s for reading", argv[4]); - - /* Open output file for each encoder to output bitstreams */ - for (i = 0; i < NUM_ENCODERS; i++) { - if (!target_bitrate[i]) { - outfile[i] = NULL; - continue; - } - - if (!(outfile[i] = fopen(argv[i + 5], "wb"))) - die("Failed to open %s for writing", argv[i + 4]); - } - - // Bitrates per spatial layer: overwrite default rates above. - for (i = 0; i < NUM_ENCODERS; i++) { - target_bitrate[i] = (int)strtol(argv[NUM_ENCODERS + 5 + i], NULL, 0); - } - - // Temporal layers per spatial layers: overwrite default settings above. - for (i = 0; i < NUM_ENCODERS; i++) { - num_temporal_layers[i] = - (int)strtol(argv[2 * NUM_ENCODERS + 5 + i], NULL, 0); - if (num_temporal_layers[i] < 1 || num_temporal_layers[i] > 3) - die("Invalid temporal layers: %d, Must be 1, 2, or 3. \n", - num_temporal_layers[i]); - } - - /* Open file to write out each spatially downsampled input stream. */ - for (i = 0; i < NUM_ENCODERS - 1; i++) { - // Highest resoln is encoder 0. - if (sprintf(filename, "ds%d.yuv", NUM_ENCODERS - i) < 0) { - return EXIT_FAILURE; - } - downsampled_input[i] = fopen(filename, "wb"); - } - - key_frame_insert = (int)strtol(argv[3 * NUM_ENCODERS + 5], NULL, 0); - - show_psnr = (int)strtol(argv[3 * NUM_ENCODERS + 6], NULL, 0); - - /* Populate default encoder configuration */ - for (i = 0; i < NUM_ENCODERS; i++) { - res[i] = vpx_codec_enc_config_default(interface, &cfg[i], 0); - if (res[i]) { - printf("Failed to get config: %s\n", vpx_codec_err_to_string(res[i])); - return EXIT_FAILURE; - } - } - - /* - * Update the default configuration according to needs of the application. - */ - /* Highest-resolution encoder settings */ - cfg[0].g_w = width; - cfg[0].g_h = height; - cfg[0].rc_dropframe_thresh = 0; - cfg[0].rc_end_usage = VPX_CBR; - cfg[0].rc_resize_allowed = 0; - cfg[0].rc_min_quantizer = 2; - cfg[0].rc_max_quantizer = 56; - cfg[0].rc_undershoot_pct = 100; - cfg[0].rc_overshoot_pct = 15; - cfg[0].rc_buf_initial_sz = 500; - cfg[0].rc_buf_optimal_sz = 600; - cfg[0].rc_buf_sz = 1000; - cfg[0].g_error_resilient = 1; /* Enable error resilient mode */ - cfg[0].g_lag_in_frames = 0; - - /* Disable automatic keyframe placement */ - /* Note: These 3 settings are copied to all levels. But, except the lowest - * resolution level, all other levels are set to VPX_KF_DISABLED internally. - */ - cfg[0].kf_mode = VPX_KF_AUTO; - cfg[0].kf_min_dist = 3000; - cfg[0].kf_max_dist = 3000; - - cfg[0].rc_target_bitrate = target_bitrate[0]; /* Set target bitrate */ - cfg[0].g_timebase.num = 1; /* Set fps */ - cfg[0].g_timebase.den = framerate; - - /* Other-resolution encoder settings */ - for (i = 1; i < NUM_ENCODERS; i++) { - memcpy(&cfg[i], &cfg[0], sizeof(vpx_codec_enc_cfg_t)); - - cfg[i].rc_target_bitrate = target_bitrate[i]; - - /* Note: Width & height of other-resolution encoders are calculated - * from the highest-resolution encoder's size and the corresponding - * down_sampling_factor. - */ - { - unsigned int iw = cfg[i - 1].g_w * dsf[i - 1].den + dsf[i - 1].num - 1; - unsigned int ih = cfg[i - 1].g_h * dsf[i - 1].den + dsf[i - 1].num - 1; - cfg[i].g_w = iw / dsf[i - 1].num; - cfg[i].g_h = ih / dsf[i - 1].num; - } - - /* Make width & height to be multiplier of 2. */ - // Should support odd size ??? - if ((cfg[i].g_w) % 2) cfg[i].g_w++; - if ((cfg[i].g_h) % 2) cfg[i].g_h++; - } - - // Set the number of threads per encode/spatial layer. - // (1, 1, 1) means no encoder threading. - cfg[0].g_threads = 1; - cfg[1].g_threads = 1; - cfg[2].g_threads = 1; - - /* Allocate image for each encoder */ - for (i = 0; i < NUM_ENCODERS; i++) - if (!vpx_img_alloc(&raw[i], VPX_IMG_FMT_I420, cfg[i].g_w, cfg[i].g_h, 32)) - die("Failed to allocate image (%dx%d)", cfg[i].g_w, cfg[i].g_h); - - if (raw[0].stride[VPX_PLANE_Y] == (int)raw[0].d_w) - read_frame_p = mulres_read_frame; - else - read_frame_p = mulres_read_frame_by_row; - - for (i = 0; i < NUM_ENCODERS; i++) - if (outfile[i]) write_ivf_file_header(outfile[i], &cfg[i], 0); - - /* Temporal layers settings */ - for (i = 0; i < NUM_ENCODERS; i++) { - set_temporal_layer_pattern(num_temporal_layers[i], &cfg[i], - cfg[i].rc_target_bitrate, - &layer_flags[i * VPX_TS_MAX_PERIODICITY]); - } - - /* Initialize multi-encoder */ - if (vpx_codec_enc_init_multi(&codec[0], interface, &cfg[0], NUM_ENCODERS, - (show_psnr ? VPX_CODEC_USE_PSNR : 0), &dsf[0])) - die_codec(&codec[0], "Failed to initialize encoder"); - - /* The extra encoding configuration parameters can be set as follows. */ - /* Set encoding speed */ - for (i = 0; i < NUM_ENCODERS; i++) { - int speed = -6; - /* Lower speed for the lowest resolution. */ - if (i == NUM_ENCODERS - 1) speed = -4; - if (vpx_codec_control(&codec[i], VP8E_SET_CPUUSED, speed)) - die_codec(&codec[i], "Failed to set cpu_used"); - } - - /* Set static threshold = 1 for all encoders */ - for (i = 0; i < NUM_ENCODERS; i++) { - if (vpx_codec_control(&codec[i], VP8E_SET_STATIC_THRESHOLD, 1)) - die_codec(&codec[i], "Failed to set static threshold"); - } - - /* Set NOISE_SENSITIVITY to do TEMPORAL_DENOISING */ - /* Enable denoising for the highest-resolution encoder. */ - if (vpx_codec_control(&codec[0], VP8E_SET_NOISE_SENSITIVITY, 1)) - die_codec(&codec[0], "Failed to set noise_sensitivity"); - if (vpx_codec_control(&codec[1], VP8E_SET_NOISE_SENSITIVITY, 1)) - die_codec(&codec[1], "Failed to set noise_sensitivity"); - for (i = 2; i < NUM_ENCODERS; i++) { - if (vpx_codec_control(&codec[i], VP8E_SET_NOISE_SENSITIVITY, 0)) - die_codec(&codec[i], "Failed to set noise_sensitivity"); - } - - /* Set the number of token partitions */ - for (i = 0; i < NUM_ENCODERS; i++) { - if (vpx_codec_control(&codec[i], VP8E_SET_TOKEN_PARTITIONS, 1)) - die_codec(&codec[i], "Failed to set static threshold"); - } - - /* Set the max intra target bitrate */ - for (i = 0; i < NUM_ENCODERS; i++) { - unsigned int max_intra_size_pct = - (int)(((double)cfg[0].rc_buf_optimal_sz * 0.5) * framerate / 10); - if (vpx_codec_control(&codec[i], VP8E_SET_MAX_INTRA_BITRATE_PCT, - max_intra_size_pct)) - die_codec(&codec[i], "Failed to set static threshold"); - // printf("%d %d \n",i,max_intra_size_pct); - } - - frame_avail = 1; - got_data = 0; - - while (frame_avail || got_data) { - struct vpx_usec_timer timer; - vpx_codec_iter_t iter[NUM_ENCODERS] = { NULL }; - const vpx_codec_cx_pkt_t *pkt[NUM_ENCODERS]; - - flags = 0; - frame_avail = read_frame_p(infile, &raw[0]); - - if (frame_avail) { - for (i = 1; i < NUM_ENCODERS; i++) { - /*Scale the image down a number of times by downsampling factor*/ - /* FilterMode 1 or 2 give better psnr than FilterMode 0. */ - I420Scale( - raw[i - 1].planes[VPX_PLANE_Y], raw[i - 1].stride[VPX_PLANE_Y], - raw[i - 1].planes[VPX_PLANE_U], raw[i - 1].stride[VPX_PLANE_U], - raw[i - 1].planes[VPX_PLANE_V], raw[i - 1].stride[VPX_PLANE_V], - raw[i - 1].d_w, raw[i - 1].d_h, raw[i].planes[VPX_PLANE_Y], - raw[i].stride[VPX_PLANE_Y], raw[i].planes[VPX_PLANE_U], - raw[i].stride[VPX_PLANE_U], raw[i].planes[VPX_PLANE_V], - raw[i].stride[VPX_PLANE_V], raw[i].d_w, raw[i].d_h, 1); - /* Write out down-sampled input. */ - length_frame = cfg[i].g_w * cfg[i].g_h * 3 / 2; - if (fwrite(raw[i].planes[0], 1, length_frame, - downsampled_input[NUM_ENCODERS - i - 1]) != - (unsigned int)length_frame) { - return EXIT_FAILURE; - } - } - } - - /* Set the flags (reference and update) for all the encoders.*/ - for (i = 0; i < NUM_ENCODERS; i++) { - layer_id = cfg[i].ts_layer_id[frame_cnt % cfg[i].ts_periodicity]; - flags = 0; - flag_periodicity = periodicity_to_num_layers[num_temporal_layers[i] - 1]; - flags = layer_flags[i * VPX_TS_MAX_PERIODICITY + - frame_cnt % flag_periodicity]; - // Key frame flag for first frame. - if (frame_cnt == 0) { - flags |= VPX_EFLAG_FORCE_KF; - } - if (frame_cnt > 0 && frame_cnt == key_frame_insert) { - flags = VPX_EFLAG_FORCE_KF; - } - - vpx_codec_control(&codec[i], VP8E_SET_FRAME_FLAGS, flags); - vpx_codec_control(&codec[i], VP8E_SET_TEMPORAL_LAYER_ID, layer_id); - } - - /* Encode each frame at multi-levels */ - /* Note the flags must be set to 0 in the encode call if they are set - for each frame with the vpx_codec_control(), as done above. */ - vpx_usec_timer_start(&timer); - if (vpx_codec_encode(&codec[0], frame_avail ? &raw[0] : NULL, frame_cnt, 1, - 0, arg_deadline)) { - die_codec(&codec[0], "Failed to encode frame"); - } - vpx_usec_timer_mark(&timer); - cx_time += vpx_usec_timer_elapsed(&timer); - - for (i = NUM_ENCODERS - 1; i >= 0; i--) { - got_data = 0; - while ((pkt[i] = vpx_codec_get_cx_data(&codec[i], &iter[i]))) { - got_data = 1; - switch (pkt[i]->kind) { - case VPX_CODEC_CX_FRAME_PKT: - write_ivf_frame_header(outfile[i], pkt[i]); - (void)fwrite(pkt[i]->data.frame.buf, 1, pkt[i]->data.frame.sz, - outfile[i]); - break; - case VPX_CODEC_PSNR_PKT: - if (show_psnr) { - int j; - - psnr_sse_total[i] += pkt[i]->data.psnr.sse[0]; - psnr_samples_total[i] += pkt[i]->data.psnr.samples[0]; - for (j = 0; j < 4; j++) { - psnr_totals[i][j] += pkt[i]->data.psnr.psnr[j]; - } - psnr_count[i]++; - } - - break; - default: break; - } - fflush(stdout); - } - } - frame_cnt++; - } - printf("\n"); - printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n", - frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000), - 1000000 * (double)frame_cnt / (double)cx_time); - - fclose(infile); - - printf("Processed %ld frames.\n", (long int)frame_cnt - 1); - for (i = 0; i < NUM_ENCODERS; i++) { - /* Calculate PSNR and print it out */ - if ((show_psnr) && (psnr_count[i] > 0)) { - int j; - double ovpsnr = - sse_to_psnr(psnr_samples_total[i], 255.0, psnr_sse_total[i]); - - fprintf(stderr, "\n ENC%d PSNR (Overall/Avg/Y/U/V)", i); - - fprintf(stderr, " %.3lf", ovpsnr); - for (j = 0; j < 4; j++) { - fprintf(stderr, " %.3lf", psnr_totals[i][j] / psnr_count[i]); - } - } - - if (vpx_codec_destroy(&codec[i])) - die_codec(&codec[i], "Failed to destroy codec"); - - vpx_img_free(&raw[i]); - - if (!outfile[i]) continue; - - /* Try to rewrite the file header with the actual frame count */ - if (!fseek(outfile[i], 0, SEEK_SET)) - write_ivf_file_header(outfile[i], &cfg[i], frame_cnt - 1); - fclose(outfile[i]); - } - - return EXIT_SUCCESS; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/examples/vp8cx_set_ref.c b/presentation/src/main/cpp/third_party/libvpx/examples/vp8cx_set_ref.c deleted file mode 100644 index ca528f9e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/examples/vp8cx_set_ref.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// VP8 Set Reference Frame -// ======================= -// -// This is an example demonstrating how to overwrite the VP8 encoder's -// internal reference frame. In the sample we set the last frame to the -// current frame. If this is done at a cut scene it will avoid a keyframe. -// This technique could be used to bounce between two cameras. -// -// Note that the decoder would also have to set the reference frame to the -// same value on the same frame, or the video will become corrupt. -// -// Usage -// ----- -// This example adds a single argument to the `simple_encoder` example, -// which specifies the frame number to update the reference frame on. -// The parameter is parsed as follows: -// -// -// Extra Variables -// --------------- -// This example maintains the frame number passed on the command line -// in the `update_frame_num` variable. -// -// -// Configuration -// ------------- -// -// The reference frame is updated on the frame specified on the command -// line. -// -// Observing The Effects -// --------------------- -// Use the `simple_encoder` example to encode a sample with a cut scene. -// Determine the frame number of the cut scene by looking for a generated -// key-frame (indicated by a 'K'). Supply that frame number as an argument -// to this example, and observe that no key-frame is generated. - -#include -#include -#include - -#include "vpx/vp8cx.h" -#include "vpx/vpx_encoder.h" -#include "vp8/common/common.h" - -#include "../tools_common.h" -#include "../video_writer.h" - -static const char *exec_name; - -void usage_exit(void) { - fprintf(stderr, "Usage: %s \n", - exec_name); - exit(EXIT_FAILURE); -} - -static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img, - int frame_index, VpxVideoWriter *writer) { - int got_pkts = 0; - vpx_codec_iter_t iter = NULL; - const vpx_codec_cx_pkt_t *pkt = NULL; - const vpx_codec_err_t res = - vpx_codec_encode(codec, img, frame_index, 1, 0, VPX_DL_GOOD_QUALITY); - if (res != VPX_CODEC_OK) die_codec(codec, "Failed to encode frame"); - - while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) { - got_pkts = 1; - - if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { - const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0; - if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf, - pkt->data.frame.sz, - pkt->data.frame.pts)) { - die_codec(codec, "Failed to write compressed frame"); - } - - printf(keyframe ? "K" : "."); - fflush(stdout); - } - } - - return got_pkts; -} - -int main(int argc, char **argv) { - FILE *infile = NULL; - vpx_codec_ctx_t codec; - vpx_codec_enc_cfg_t cfg; - int frame_count = 0; - vpx_image_t raw; - vpx_codec_err_t res; - VpxVideoInfo info; - VpxVideoWriter *writer = NULL; - const VpxInterface *encoder = NULL; - int update_frame_num = 0; - const int fps = 30; // TODO(dkovalev) add command line argument - const int bitrate = 200; // kbit/s TODO(dkovalev) add command line argument - - vp8_zero(codec); - vp8_zero(cfg); - vp8_zero(info); - - exec_name = argv[0]; - - if (argc != 6) die("Invalid number of arguments"); - - // TODO(dkovalev): add vp9 support and rename the file accordingly - encoder = get_vpx_encoder_by_name("vp8"); - if (!encoder) die("Unsupported codec."); - - update_frame_num = atoi(argv[5]); - if (!update_frame_num) die("Couldn't parse frame number '%s'\n", argv[5]); - - info.codec_fourcc = encoder->fourcc; - info.frame_width = (int)strtol(argv[1], NULL, 0); - info.frame_height = (int)strtol(argv[2], NULL, 0); - info.time_base.numerator = 1; - info.time_base.denominator = fps; - - if (info.frame_width <= 0 || info.frame_height <= 0 || - (info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) { - die("Invalid frame size: %dx%d", info.frame_width, info.frame_height); - } - - if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, info.frame_width, - info.frame_height, 1)) { - die("Failed to allocate image."); - } - - printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface())); - - res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0); - if (res) die_codec(&codec, "Failed to get default codec config."); - - cfg.g_w = info.frame_width; - cfg.g_h = info.frame_height; - cfg.g_timebase.num = info.time_base.numerator; - cfg.g_timebase.den = info.time_base.denominator; - cfg.rc_target_bitrate = bitrate; - - writer = vpx_video_writer_open(argv[4], kContainerIVF, &info); - if (!writer) die("Failed to open %s for writing.", argv[4]); - - if (!(infile = fopen(argv[3], "rb"))) - die("Failed to open %s for reading.", argv[3]); - - if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0)) - die("Failed to initialize encoder"); - - // Encode frames. - while (vpx_img_read(&raw, infile)) { - if (frame_count + 1 == update_frame_num) { - vpx_ref_frame_t ref; - ref.frame_type = VP8_LAST_FRAME; - ref.img = raw; - if (vpx_codec_control(&codec, VP8_SET_REFERENCE, &ref)) - die_codec(&codec, "Failed to set reference frame"); - } - - encode_frame(&codec, &raw, frame_count++, writer); - } - - // Flush encoder. - while (encode_frame(&codec, NULL, -1, writer)) { - } - - printf("\n"); - fclose(infile); - printf("Processed %d frames.\n", frame_count); - - vpx_img_free(&raw); - if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec."); - - vpx_video_writer_close(writer); - - return EXIT_SUCCESS; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/examples/vp9_lossless_encoder.c b/presentation/src/main/cpp/third_party/libvpx/examples/vp9_lossless_encoder.c deleted file mode 100644 index c4eb3a8b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/examples/vp9_lossless_encoder.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "vpx/vpx_encoder.h" -#include "vpx/vp8cx.h" -#include "vp9/common/vp9_common.h" - -#include "../tools_common.h" -#include "../video_writer.h" - -static const char *exec_name; - -void usage_exit(void) { - fprintf(stderr, - "vp9_lossless_encoder: Example demonstrating VP9 lossless " - "encoding feature. Supports raw input only.\n"); - fprintf(stderr, "Usage: %s \n", exec_name); - exit(EXIT_FAILURE); -} - -static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img, - int frame_index, int flags, VpxVideoWriter *writer) { - int got_pkts = 0; - vpx_codec_iter_t iter = NULL; - const vpx_codec_cx_pkt_t *pkt = NULL; - const vpx_codec_err_t res = - vpx_codec_encode(codec, img, frame_index, 1, flags, VPX_DL_GOOD_QUALITY); - if (res != VPX_CODEC_OK) die_codec(codec, "Failed to encode frame"); - - while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) { - got_pkts = 1; - - if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { - const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0; - if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf, - pkt->data.frame.sz, - pkt->data.frame.pts)) { - die_codec(codec, "Failed to write compressed frame"); - } - printf(keyframe ? "K" : "."); - fflush(stdout); - } - } - - return got_pkts; -} - -int main(int argc, char **argv) { - FILE *infile = NULL; - vpx_codec_ctx_t codec; - vpx_codec_enc_cfg_t cfg; - int frame_count = 0; - vpx_image_t raw; - vpx_codec_err_t res; - VpxVideoInfo info; - VpxVideoWriter *writer = NULL; - const VpxInterface *encoder = NULL; - const int fps = 30; - - vp9_zero(info); - - exec_name = argv[0]; - - if (argc < 5) die("Invalid number of arguments"); - - encoder = get_vpx_encoder_by_name("vp9"); - if (!encoder) die("Unsupported codec."); - - info.codec_fourcc = encoder->fourcc; - info.frame_width = (int)strtol(argv[1], NULL, 0); - info.frame_height = (int)strtol(argv[2], NULL, 0); - info.time_base.numerator = 1; - info.time_base.denominator = fps; - - if (info.frame_width <= 0 || info.frame_height <= 0 || - (info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) { - die("Invalid frame size: %dx%d", info.frame_width, info.frame_height); - } - - if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, info.frame_width, - info.frame_height, 1)) { - die("Failed to allocate image."); - } - - printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface())); - - res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0); - if (res) die_codec(&codec, "Failed to get default codec config."); - - cfg.g_w = info.frame_width; - cfg.g_h = info.frame_height; - cfg.g_timebase.num = info.time_base.numerator; - cfg.g_timebase.den = info.time_base.denominator; - - writer = vpx_video_writer_open(argv[4], kContainerIVF, &info); - if (!writer) die("Failed to open %s for writing.", argv[4]); - - if (!(infile = fopen(argv[3], "rb"))) - die("Failed to open %s for reading.", argv[3]); - - if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0)) - die("Failed to initialize encoder"); - - if (vpx_codec_control_(&codec, VP9E_SET_LOSSLESS, 1)) - die_codec(&codec, "Failed to use lossless mode"); - - // Encode frames. - while (vpx_img_read(&raw, infile)) { - encode_frame(&codec, &raw, frame_count++, 0, writer); - } - - // Flush encoder. - while (encode_frame(&codec, NULL, -1, 0, writer)) { - } - - printf("\n"); - fclose(infile); - printf("Processed %d frames.\n", frame_count); - - vpx_img_free(&raw); - if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec."); - - vpx_video_writer_close(writer); - - return EXIT_SUCCESS; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/examples/vp9_spatial_svc_encoder.c b/presentation/src/main/cpp/third_party/libvpx/examples/vp9_spatial_svc_encoder.c deleted file mode 100644 index 27f06cc6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/examples/vp9_spatial_svc_encoder.c +++ /dev/null @@ -1,1218 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * This is an example demonstrating how to implement a multi-layer - * VP9 encoding scheme based on spatial scalability for video applications - * that benefit from a scalable bitstream. - */ - -#include -#include -#include -#include -#include -#include - -#include "../args.h" -#include "../tools_common.h" -#include "../video_writer.h" - -#include "../vpx_ports/vpx_timer.h" -#include "./svc_context.h" -#include "vpx/vp8cx.h" -#include "vpx/vpx_encoder.h" -#include "../vpxstats.h" -#include "vp9/encoder/vp9_encoder.h" -#include "./y4minput.h" - -#define OUTPUT_FRAME_STATS 0 -#define OUTPUT_RC_STATS 1 - -#define SIMULCAST_MODE 0 - -static const arg_def_t outputfile = - ARG_DEF("o", "output", 1, "Output filename"); -static const arg_def_t skip_frames_arg = - ARG_DEF("s", "skip-frames", 1, "input frames to skip"); -static const arg_def_t frames_arg = - ARG_DEF("f", "frames", 1, "number of frames to encode"); -static const arg_def_t threads_arg = - ARG_DEF("th", "threads", 1, "number of threads to use"); -#if OUTPUT_RC_STATS -static const arg_def_t output_rc_stats_arg = - ARG_DEF("rcstat", "output_rc_stats", 1, "output rc stats"); -#endif -static const arg_def_t width_arg = ARG_DEF("w", "width", 1, "source width"); -static const arg_def_t height_arg = ARG_DEF("h", "height", 1, "source height"); -static const arg_def_t timebase_arg = - ARG_DEF("t", "timebase", 1, "timebase (num/den)"); -static const arg_def_t bitrate_arg = ARG_DEF( - "b", "target-bitrate", 1, "encoding bitrate, in kilobits per second"); -static const arg_def_t spatial_layers_arg = - ARG_DEF("sl", "spatial-layers", 1, "number of spatial SVC layers"); -static const arg_def_t temporal_layers_arg = - ARG_DEF("tl", "temporal-layers", 1, "number of temporal SVC layers"); -static const arg_def_t temporal_layering_mode_arg = - ARG_DEF("tlm", "temporal-layering-mode", 1, - "temporal layering scheme." - "VP9E_TEMPORAL_LAYERING_MODE"); -static const arg_def_t kf_dist_arg = - ARG_DEF("k", "kf-dist", 1, "number of frames between keyframes"); -static const arg_def_t scale_factors_arg = - ARG_DEF("r", "scale-factors", 1, "scale factors (lowest to highest layer)"); -static const arg_def_t min_q_arg = - ARG_DEF(NULL, "min-q", 1, "Minimum quantizer"); -static const arg_def_t max_q_arg = - ARG_DEF(NULL, "max-q", 1, "Maximum quantizer"); -static const arg_def_t min_bitrate_arg = - ARG_DEF(NULL, "min-bitrate", 1, "Minimum bitrate"); -static const arg_def_t max_bitrate_arg = - ARG_DEF(NULL, "max-bitrate", 1, "Maximum bitrate"); -static const arg_def_t lag_in_frame_arg = - ARG_DEF(NULL, "lag-in-frames", 1, - "Number of frame to input before " - "generating any outputs"); -static const arg_def_t rc_end_usage_arg = - ARG_DEF(NULL, "rc-end-usage", 1, "0 - 3: VBR, CBR, CQ, Q"); -static const arg_def_t speed_arg = - ARG_DEF("sp", "speed", 1, "speed configuration"); -static const arg_def_t aqmode_arg = - ARG_DEF("aq", "aqmode", 1, "aq-mode off/on"); -static const arg_def_t bitrates_arg = - ARG_DEF("bl", "bitrates", 1, "bitrates[sl * num_tl + tl]"); -static const arg_def_t dropframe_thresh_arg = - ARG_DEF(NULL, "drop-frame", 1, "Temporal resampling threshold (buf %)"); -static const struct arg_enum_list tune_content_enum[] = { - { "default", VP9E_CONTENT_DEFAULT }, - { "screen", VP9E_CONTENT_SCREEN }, - { "film", VP9E_CONTENT_FILM }, - { NULL, 0 } -}; - -static const arg_def_t tune_content_arg = ARG_DEF_ENUM( - NULL, "tune-content", 1, "Tune content type", tune_content_enum); -static const arg_def_t inter_layer_pred_arg = ARG_DEF( - NULL, "inter-layer-pred", 1, "0 - 3: On, Off, Key-frames, Constrained"); - -#if CONFIG_VP9_HIGHBITDEPTH -static const struct arg_enum_list bitdepth_enum[] = { - { "8", VPX_BITS_8 }, { "10", VPX_BITS_10 }, { "12", VPX_BITS_12 }, { NULL, 0 } -}; - -static const arg_def_t bitdepth_arg = ARG_DEF_ENUM( - "d", "bit-depth", 1, "Bit depth for codec 8, 10 or 12. ", bitdepth_enum); -#endif // CONFIG_VP9_HIGHBITDEPTH - -static const arg_def_t *svc_args[] = { &frames_arg, - &outputfile, - &width_arg, - &height_arg, - &timebase_arg, - &bitrate_arg, - &skip_frames_arg, - &spatial_layers_arg, - &kf_dist_arg, - &scale_factors_arg, - &min_q_arg, - &max_q_arg, - &min_bitrate_arg, - &max_bitrate_arg, - &temporal_layers_arg, - &temporal_layering_mode_arg, - &lag_in_frame_arg, - &threads_arg, - &aqmode_arg, -#if OUTPUT_RC_STATS - &output_rc_stats_arg, -#endif - -#if CONFIG_VP9_HIGHBITDEPTH - &bitdepth_arg, -#endif - &speed_arg, - &rc_end_usage_arg, - &bitrates_arg, - &dropframe_thresh_arg, - &tune_content_arg, - &inter_layer_pred_arg, - NULL }; - -static const uint32_t default_frames_to_skip = 0; -static const uint32_t default_frames_to_code = 60 * 60; -static const uint32_t default_width = 1920; -static const uint32_t default_height = 1080; -static const uint32_t default_timebase_num = 1; -static const uint32_t default_timebase_den = 60; -static const uint32_t default_bitrate = 1000; -static const uint32_t default_spatial_layers = 5; -static const uint32_t default_temporal_layers = 1; -static const uint32_t default_kf_dist = 100; -static const uint32_t default_temporal_layering_mode = 0; -static const uint32_t default_output_rc_stats = 0; -static const int32_t default_speed = -1; // -1 means use library default. -static const uint32_t default_threads = 0; // zero means use library default. - -typedef struct { - const char *output_filename; - uint32_t frames_to_code; - uint32_t frames_to_skip; - struct VpxInputContext input_ctx; - stats_io_t rc_stats; - int tune_content; - int inter_layer_pred; -} AppInput; - -static const char *exec_name; - -void usage_exit(void) { - fprintf(stderr, "Usage: %s input_filename -o output_filename\n", - exec_name); - fprintf(stderr, "Options:\n"); - arg_show_usage(stderr, svc_args); - exit(EXIT_FAILURE); -} - -static void parse_command_line(int argc, const char **argv_, - AppInput *app_input, SvcContext *svc_ctx, - vpx_codec_enc_cfg_t *enc_cfg) { - struct arg arg; - char **argv = NULL; - char **argi = NULL; - char **argj = NULL; - vpx_codec_err_t res; - unsigned int min_bitrate = 0; - unsigned int max_bitrate = 0; - char string_options[1024] = { 0 }; - - // initialize SvcContext with parameters that will be passed to vpx_svc_init - svc_ctx->log_level = SVC_LOG_DEBUG; - svc_ctx->spatial_layers = default_spatial_layers; - svc_ctx->temporal_layers = default_temporal_layers; - svc_ctx->temporal_layering_mode = default_temporal_layering_mode; -#if OUTPUT_RC_STATS - svc_ctx->output_rc_stat = default_output_rc_stats; -#endif - svc_ctx->speed = default_speed; - svc_ctx->threads = default_threads; - - // start with default encoder configuration - res = vpx_codec_enc_config_default(vpx_codec_vp9_cx(), enc_cfg, 0); - if (res) { - die("Failed to get config: %s\n", vpx_codec_err_to_string(res)); - } - // update enc_cfg with app default values - enc_cfg->g_w = default_width; - enc_cfg->g_h = default_height; - enc_cfg->g_timebase.num = default_timebase_num; - enc_cfg->g_timebase.den = default_timebase_den; - enc_cfg->rc_target_bitrate = default_bitrate; - enc_cfg->kf_min_dist = default_kf_dist; - enc_cfg->kf_max_dist = default_kf_dist; - enc_cfg->rc_end_usage = VPX_CQ; - - // initialize AppInput with default values - app_input->frames_to_code = default_frames_to_code; - app_input->frames_to_skip = default_frames_to_skip; - - // process command line options - argv = argv_dup(argc - 1, argv_ + 1); - if (!argv) { - fprintf(stderr, "Error allocating argument list\n"); - exit(EXIT_FAILURE); - } - for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { - arg.argv_step = 1; - - if (arg_match(&arg, &frames_arg, argi)) { - app_input->frames_to_code = arg_parse_uint(&arg); - } else if (arg_match(&arg, &outputfile, argi)) { - app_input->output_filename = arg.val; - } else if (arg_match(&arg, &width_arg, argi)) { - enc_cfg->g_w = arg_parse_uint(&arg); - } else if (arg_match(&arg, &height_arg, argi)) { - enc_cfg->g_h = arg_parse_uint(&arg); - } else if (arg_match(&arg, &timebase_arg, argi)) { - enc_cfg->g_timebase = arg_parse_rational(&arg); - } else if (arg_match(&arg, &bitrate_arg, argi)) { - enc_cfg->rc_target_bitrate = arg_parse_uint(&arg); - } else if (arg_match(&arg, &skip_frames_arg, argi)) { - app_input->frames_to_skip = arg_parse_uint(&arg); - } else if (arg_match(&arg, &spatial_layers_arg, argi)) { - svc_ctx->spatial_layers = arg_parse_uint(&arg); - } else if (arg_match(&arg, &temporal_layers_arg, argi)) { - svc_ctx->temporal_layers = arg_parse_uint(&arg); -#if OUTPUT_RC_STATS - } else if (arg_match(&arg, &output_rc_stats_arg, argi)) { - svc_ctx->output_rc_stat = arg_parse_uint(&arg); -#endif - } else if (arg_match(&arg, &speed_arg, argi)) { - svc_ctx->speed = arg_parse_uint(&arg); - if (svc_ctx->speed > 9) { - warn("Mapping speed %d to speed 9.\n", svc_ctx->speed); - } - } else if (arg_match(&arg, &aqmode_arg, argi)) { - svc_ctx->aqmode = arg_parse_uint(&arg); - } else if (arg_match(&arg, &threads_arg, argi)) { - svc_ctx->threads = arg_parse_uint(&arg); - } else if (arg_match(&arg, &temporal_layering_mode_arg, argi)) { - svc_ctx->temporal_layering_mode = enc_cfg->temporal_layering_mode = - arg_parse_int(&arg); - if (svc_ctx->temporal_layering_mode) { - enc_cfg->g_error_resilient = 1; - } - } else if (arg_match(&arg, &kf_dist_arg, argi)) { - enc_cfg->kf_min_dist = arg_parse_uint(&arg); - enc_cfg->kf_max_dist = enc_cfg->kf_min_dist; - } else if (arg_match(&arg, &scale_factors_arg, argi)) { - strncat(string_options, " scale-factors=", - sizeof(string_options) - strlen(string_options) - 1); - strncat(string_options, arg.val, - sizeof(string_options) - strlen(string_options) - 1); - } else if (arg_match(&arg, &bitrates_arg, argi)) { - strncat(string_options, " bitrates=", - sizeof(string_options) - strlen(string_options) - 1); - strncat(string_options, arg.val, - sizeof(string_options) - strlen(string_options) - 1); - } else if (arg_match(&arg, &min_q_arg, argi)) { - strncat(string_options, " min-quantizers=", - sizeof(string_options) - strlen(string_options) - 1); - strncat(string_options, arg.val, - sizeof(string_options) - strlen(string_options) - 1); - } else if (arg_match(&arg, &max_q_arg, argi)) { - strncat(string_options, " max-quantizers=", - sizeof(string_options) - strlen(string_options) - 1); - strncat(string_options, arg.val, - sizeof(string_options) - strlen(string_options) - 1); - } else if (arg_match(&arg, &min_bitrate_arg, argi)) { - min_bitrate = arg_parse_uint(&arg); - } else if (arg_match(&arg, &max_bitrate_arg, argi)) { - max_bitrate = arg_parse_uint(&arg); - } else if (arg_match(&arg, &lag_in_frame_arg, argi)) { - enc_cfg->g_lag_in_frames = arg_parse_uint(&arg); - } else if (arg_match(&arg, &rc_end_usage_arg, argi)) { - enc_cfg->rc_end_usage = arg_parse_uint(&arg); -#if CONFIG_VP9_HIGHBITDEPTH - } else if (arg_match(&arg, &bitdepth_arg, argi)) { - enc_cfg->g_bit_depth = arg_parse_enum_or_int(&arg); - switch (enc_cfg->g_bit_depth) { - case VPX_BITS_8: - enc_cfg->g_input_bit_depth = 8; - enc_cfg->g_profile = 0; - break; - case VPX_BITS_10: - enc_cfg->g_input_bit_depth = 10; - enc_cfg->g_profile = 2; - break; - case VPX_BITS_12: - enc_cfg->g_input_bit_depth = 12; - enc_cfg->g_profile = 2; - break; - default: - die("Error: Invalid bit depth selected (%d)\n", enc_cfg->g_bit_depth); - } -#endif // CONFIG_VP9_HIGHBITDEPTH - } else if (arg_match(&arg, &dropframe_thresh_arg, argi)) { - enc_cfg->rc_dropframe_thresh = arg_parse_uint(&arg); - } else if (arg_match(&arg, &tune_content_arg, argi)) { - app_input->tune_content = arg_parse_uint(&arg); - } else if (arg_match(&arg, &inter_layer_pred_arg, argi)) { - app_input->inter_layer_pred = arg_parse_uint(&arg); - } else { - ++argj; - } - } - - // There will be a space in front of the string options - if (strlen(string_options) > 0) - vpx_svc_set_options(svc_ctx, string_options + 1); - - enc_cfg->g_pass = VPX_RC_ONE_PASS; - - if (enc_cfg->rc_target_bitrate > 0) { - if (min_bitrate > 0) { - enc_cfg->rc_2pass_vbr_minsection_pct = - min_bitrate * 100 / enc_cfg->rc_target_bitrate; - } - if (max_bitrate > 0) { - enc_cfg->rc_2pass_vbr_maxsection_pct = - max_bitrate * 100 / enc_cfg->rc_target_bitrate; - } - } - - // Check for unrecognized options - for (argi = argv; *argi; ++argi) - if (argi[0][0] == '-' && strlen(argi[0]) > 1) - die("Error: Unrecognized option %s\n", *argi); - - if (argv[0] == NULL) { - usage_exit(); - } - app_input->input_ctx.filename = argv[0]; - free(argv); - - open_input_file(&app_input->input_ctx); - if (app_input->input_ctx.file_type == FILE_TYPE_Y4M) { - enc_cfg->g_w = app_input->input_ctx.width; - enc_cfg->g_h = app_input->input_ctx.height; - enc_cfg->g_timebase.den = app_input->input_ctx.framerate.numerator; - enc_cfg->g_timebase.num = app_input->input_ctx.framerate.denominator; - } - - if (enc_cfg->g_w < 16 || enc_cfg->g_w % 2 || enc_cfg->g_h < 16 || - enc_cfg->g_h % 2) - die("Invalid resolution: %d x %d\n", enc_cfg->g_w, enc_cfg->g_h); - - printf( - "Codec %s\nframes: %d, skip: %d\n" - "layers: %d\n" - "width %d, height: %d,\n" - "num: %d, den: %d, bitrate: %d,\n" - "gop size: %d\n", - vpx_codec_iface_name(vpx_codec_vp9_cx()), app_input->frames_to_code, - app_input->frames_to_skip, svc_ctx->spatial_layers, enc_cfg->g_w, - enc_cfg->g_h, enc_cfg->g_timebase.num, enc_cfg->g_timebase.den, - enc_cfg->rc_target_bitrate, enc_cfg->kf_max_dist); -} - -#if OUTPUT_RC_STATS -// For rate control encoding stats. -struct RateControlStats { - // Number of input frames per layer. - int layer_input_frames[VPX_MAX_LAYERS]; - // Total (cumulative) number of encoded frames per layer. - int layer_tot_enc_frames[VPX_MAX_LAYERS]; - // Number of encoded non-key frames per layer. - int layer_enc_frames[VPX_MAX_LAYERS]; - // Framerate per layer (cumulative). - double layer_framerate[VPX_MAX_LAYERS]; - // Target average frame size per layer (per-frame-bandwidth per layer). - double layer_pfb[VPX_MAX_LAYERS]; - // Actual average frame size per layer. - double layer_avg_frame_size[VPX_MAX_LAYERS]; - // Average rate mismatch per layer (|target - actual| / target). - double layer_avg_rate_mismatch[VPX_MAX_LAYERS]; - // Actual encoding bitrate per layer (cumulative). - double layer_encoding_bitrate[VPX_MAX_LAYERS]; - // Average of the short-time encoder actual bitrate. - // TODO(marpan): Should we add these short-time stats for each layer? - double avg_st_encoding_bitrate; - // Variance of the short-time encoder actual bitrate. - double variance_st_encoding_bitrate; - // Window (number of frames) for computing short-time encoding bitrate. - int window_size; - // Number of window measurements. - int window_count; -}; - -// Note: these rate control stats assume only 1 key frame in the -// sequence (i.e., first frame only). -static void set_rate_control_stats(struct RateControlStats *rc, - vpx_codec_enc_cfg_t *cfg) { - unsigned int sl, tl; - // Set the layer (cumulative) framerate and the target layer (non-cumulative) - // per-frame-bandwidth, for the rate control encoding stats below. - const double framerate = cfg->g_timebase.den / cfg->g_timebase.num; - - for (sl = 0; sl < cfg->ss_number_layers; ++sl) { - for (tl = 0; tl < cfg->ts_number_layers; ++tl) { - const int layer = sl * cfg->ts_number_layers + tl; - if (cfg->ts_number_layers == 1) - rc->layer_framerate[layer] = framerate; - else - rc->layer_framerate[layer] = framerate / cfg->ts_rate_decimator[tl]; - if (tl > 0) { - rc->layer_pfb[layer] = - 1000.0 * - (cfg->layer_target_bitrate[layer] - - cfg->layer_target_bitrate[layer - 1]) / - (rc->layer_framerate[layer] - rc->layer_framerate[layer - 1]); - } else { - rc->layer_pfb[layer] = 1000.0 * cfg->layer_target_bitrate[layer] / - rc->layer_framerate[layer]; - } - rc->layer_input_frames[layer] = 0; - rc->layer_enc_frames[layer] = 0; - rc->layer_tot_enc_frames[layer] = 0; - rc->layer_encoding_bitrate[layer] = 0.0; - rc->layer_avg_frame_size[layer] = 0.0; - rc->layer_avg_rate_mismatch[layer] = 0.0; - } - } - rc->window_count = 0; - rc->window_size = 15; - rc->avg_st_encoding_bitrate = 0.0; - rc->variance_st_encoding_bitrate = 0.0; -} - -static void printout_rate_control_summary(struct RateControlStats *rc, - vpx_codec_enc_cfg_t *cfg, - int frame_cnt) { - unsigned int sl, tl; - double perc_fluctuation = 0.0; - int tot_num_frames = 0; - printf("Total number of processed frames: %d\n\n", frame_cnt - 1); - printf("Rate control layer stats for sl%d tl%d layer(s):\n\n", - cfg->ss_number_layers, cfg->ts_number_layers); - for (sl = 0; sl < cfg->ss_number_layers; ++sl) { - tot_num_frames = 0; - for (tl = 0; tl < cfg->ts_number_layers; ++tl) { - const int layer = sl * cfg->ts_number_layers + tl; - const int num_dropped = - (tl > 0) - ? (rc->layer_input_frames[layer] - rc->layer_enc_frames[layer]) - : (rc->layer_input_frames[layer] - rc->layer_enc_frames[layer] - - 1); - tot_num_frames += rc->layer_input_frames[layer]; - rc->layer_encoding_bitrate[layer] = 0.001 * rc->layer_framerate[layer] * - rc->layer_encoding_bitrate[layer] / - tot_num_frames; - rc->layer_avg_frame_size[layer] = - rc->layer_avg_frame_size[layer] / rc->layer_enc_frames[layer]; - rc->layer_avg_rate_mismatch[layer] = 100.0 * - rc->layer_avg_rate_mismatch[layer] / - rc->layer_enc_frames[layer]; - printf("For layer#: sl%d tl%d \n", sl, tl); - printf("Bitrate (target vs actual): %d %f.0 kbps\n", - cfg->layer_target_bitrate[layer], - rc->layer_encoding_bitrate[layer]); - printf("Average frame size (target vs actual): %f %f bits\n", - rc->layer_pfb[layer], rc->layer_avg_frame_size[layer]); - printf("Average rate_mismatch: %f\n", rc->layer_avg_rate_mismatch[layer]); - printf( - "Number of input frames, encoded (non-key) frames, " - "and percent dropped frames: %d %d %f.0 \n", - rc->layer_input_frames[layer], rc->layer_enc_frames[layer], - 100.0 * num_dropped / rc->layer_input_frames[layer]); - printf("\n"); - } - } - rc->avg_st_encoding_bitrate = rc->avg_st_encoding_bitrate / rc->window_count; - rc->variance_st_encoding_bitrate = - rc->variance_st_encoding_bitrate / rc->window_count - - (rc->avg_st_encoding_bitrate * rc->avg_st_encoding_bitrate); - perc_fluctuation = 100.0 * sqrt(rc->variance_st_encoding_bitrate) / - rc->avg_st_encoding_bitrate; - printf("Short-time stats, for window of %d frames: \n", rc->window_size); - printf("Average, rms-variance, and percent-fluct: %f %f %f \n", - rc->avg_st_encoding_bitrate, sqrt(rc->variance_st_encoding_bitrate), - perc_fluctuation); - printf("Num of input, num of encoded (super) frames: %d %d \n", frame_cnt, - tot_num_frames); -} - -static vpx_codec_err_t parse_superframe_index(const uint8_t *data, - size_t data_sz, uint64_t sizes[8], - int *count) { - // A chunk ending with a byte matching 0xc0 is an invalid chunk unless - // it is a super frame index. If the last byte of real video compression - // data is 0xc0 the encoder must add a 0 byte. If we have the marker but - // not the associated matching marker byte at the front of the index we have - // an invalid bitstream and need to return an error. - - uint8_t marker; - - marker = *(data + data_sz - 1); - *count = 0; - - if ((marker & 0xe0) == 0xc0) { - const uint32_t frames = (marker & 0x7) + 1; - const uint32_t mag = ((marker >> 3) & 0x3) + 1; - const size_t index_sz = 2 + mag * frames; - - // This chunk is marked as having a superframe index but doesn't have - // enough data for it, thus it's an invalid superframe index. - if (data_sz < index_sz) return VPX_CODEC_CORRUPT_FRAME; - - { - const uint8_t marker2 = *(data + data_sz - index_sz); - - // This chunk is marked as having a superframe index but doesn't have - // the matching marker byte at the front of the index therefore it's an - // invalid chunk. - if (marker != marker2) return VPX_CODEC_CORRUPT_FRAME; - } - - { - // Found a valid superframe index. - uint32_t i, j; - const uint8_t *x = &data[data_sz - index_sz + 1]; - - for (i = 0; i < frames; ++i) { - uint32_t this_sz = 0; - - for (j = 0; j < mag; ++j) this_sz |= (*x++) << (j * 8); - sizes[i] = this_sz; - } - *count = frames; - } - } - return VPX_CODEC_OK; -} -#endif - -// Example pattern for spatial layers and 2 temporal layers used in the -// bypass/flexible mode. The pattern corresponds to the pattern -// VP9E_TEMPORAL_LAYERING_MODE_0101 (temporal_layering_mode == 2) used in -// non-flexible mode. -static void set_frame_flags_bypass_mode_ex0( - int tl, int num_spatial_layers, int is_key_frame, - vpx_svc_ref_frame_config_t *ref_frame_config) { - int sl; - for (sl = 0; sl < num_spatial_layers; ++sl) - ref_frame_config->update_buffer_slot[sl] = 0; - - for (sl = 0; sl < num_spatial_layers; ++sl) { - // Set the buffer idx. - if (tl == 0) { - ref_frame_config->lst_fb_idx[sl] = sl; - if (sl) { - if (is_key_frame) { - ref_frame_config->lst_fb_idx[sl] = sl - 1; - ref_frame_config->gld_fb_idx[sl] = sl; - } else { - ref_frame_config->gld_fb_idx[sl] = sl - 1; - } - } else { - ref_frame_config->gld_fb_idx[sl] = 0; - } - ref_frame_config->alt_fb_idx[sl] = 0; - } else if (tl == 1) { - ref_frame_config->lst_fb_idx[sl] = sl; - ref_frame_config->gld_fb_idx[sl] = - (sl == 0) ? 0 : num_spatial_layers + sl - 1; - ref_frame_config->alt_fb_idx[sl] = num_spatial_layers + sl; - } - // Set the reference and update flags. - if (!tl) { - if (!sl) { - // Base spatial and base temporal (sl = 0, tl = 0) - ref_frame_config->reference_last[sl] = 1; - ref_frame_config->reference_golden[sl] = 0; - ref_frame_config->reference_alt_ref[sl] = 0; - ref_frame_config->update_buffer_slot[sl] |= - 1 << ref_frame_config->lst_fb_idx[sl]; - } else { - if (is_key_frame) { - ref_frame_config->reference_last[sl] = 1; - ref_frame_config->reference_golden[sl] = 0; - ref_frame_config->reference_alt_ref[sl] = 0; - ref_frame_config->update_buffer_slot[sl] |= - 1 << ref_frame_config->gld_fb_idx[sl]; - } else { - // Non-zero spatiall layer. - ref_frame_config->reference_last[sl] = 1; - ref_frame_config->reference_golden[sl] = 1; - ref_frame_config->reference_alt_ref[sl] = 1; - ref_frame_config->update_buffer_slot[sl] |= - 1 << ref_frame_config->lst_fb_idx[sl]; - } - } - } else if (tl == 1) { - if (!sl) { - // Base spatial and top temporal (tl = 1) - ref_frame_config->reference_last[sl] = 1; - ref_frame_config->reference_golden[sl] = 0; - ref_frame_config->reference_alt_ref[sl] = 0; - ref_frame_config->update_buffer_slot[sl] |= - 1 << ref_frame_config->alt_fb_idx[sl]; - } else { - // Non-zero spatial. - if (sl < num_spatial_layers - 1) { - ref_frame_config->reference_last[sl] = 1; - ref_frame_config->reference_golden[sl] = 1; - ref_frame_config->reference_alt_ref[sl] = 0; - ref_frame_config->update_buffer_slot[sl] |= - 1 << ref_frame_config->alt_fb_idx[sl]; - } else if (sl == num_spatial_layers - 1) { - // Top spatial and top temporal (non-reference -- doesn't update any - // reference buffers) - ref_frame_config->reference_last[sl] = 1; - ref_frame_config->reference_golden[sl] = 1; - ref_frame_config->reference_alt_ref[sl] = 0; - } - } - } - } -} - -// Example pattern for 2 spatial layers and 2 temporal layers used in the -// bypass/flexible mode, except only 1 spatial layer when temporal_layer_id = 1. -static void set_frame_flags_bypass_mode_ex1( - int tl, int num_spatial_layers, int is_key_frame, - vpx_svc_ref_frame_config_t *ref_frame_config) { - int sl; - for (sl = 0; sl < num_spatial_layers; ++sl) - ref_frame_config->update_buffer_slot[sl] = 0; - - if (tl == 0) { - if (is_key_frame) { - ref_frame_config->lst_fb_idx[1] = 0; - ref_frame_config->gld_fb_idx[1] = 1; - } else { - ref_frame_config->lst_fb_idx[1] = 1; - ref_frame_config->gld_fb_idx[1] = 0; - } - ref_frame_config->alt_fb_idx[1] = 0; - - ref_frame_config->lst_fb_idx[0] = 0; - ref_frame_config->gld_fb_idx[0] = 0; - ref_frame_config->alt_fb_idx[0] = 0; - } - if (tl == 1) { - ref_frame_config->lst_fb_idx[0] = 0; - ref_frame_config->gld_fb_idx[0] = 1; - ref_frame_config->alt_fb_idx[0] = 2; - - ref_frame_config->lst_fb_idx[1] = 1; - ref_frame_config->gld_fb_idx[1] = 2; - ref_frame_config->alt_fb_idx[1] = 3; - } - // Set the reference and update flags. - if (tl == 0) { - // Base spatial and base temporal (sl = 0, tl = 0) - ref_frame_config->reference_last[0] = 1; - ref_frame_config->reference_golden[0] = 0; - ref_frame_config->reference_alt_ref[0] = 0; - ref_frame_config->update_buffer_slot[0] |= - 1 << ref_frame_config->lst_fb_idx[0]; - - if (is_key_frame) { - ref_frame_config->reference_last[1] = 1; - ref_frame_config->reference_golden[1] = 0; - ref_frame_config->reference_alt_ref[1] = 0; - ref_frame_config->update_buffer_slot[1] |= - 1 << ref_frame_config->gld_fb_idx[1]; - } else { - // Non-zero spatiall layer. - ref_frame_config->reference_last[1] = 1; - ref_frame_config->reference_golden[1] = 1; - ref_frame_config->reference_alt_ref[1] = 1; - ref_frame_config->update_buffer_slot[1] |= - 1 << ref_frame_config->lst_fb_idx[1]; - } - } - if (tl == 1) { - // Top spatial and top temporal (non-reference -- doesn't update any - // reference buffers) - ref_frame_config->reference_last[1] = 1; - ref_frame_config->reference_golden[1] = 0; - ref_frame_config->reference_alt_ref[1] = 0; - } -} - -#if CONFIG_VP9_DECODER && !SIMULCAST_MODE -static void test_decode(vpx_codec_ctx_t *encoder, vpx_codec_ctx_t *decoder, - const int frames_out, int *mismatch_seen) { - vpx_image_t enc_img, dec_img; - struct vp9_ref_frame ref_enc, ref_dec; - if (*mismatch_seen) return; - /* Get the internal reference frame */ - ref_enc.idx = 0; - ref_dec.idx = 0; - vpx_codec_control(encoder, VP9_GET_REFERENCE, &ref_enc); - enc_img = ref_enc.img; - vpx_codec_control(decoder, VP9_GET_REFERENCE, &ref_dec); - dec_img = ref_dec.img; -#if CONFIG_VP9_HIGHBITDEPTH - if ((enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) != - (dec_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH)) { - if (enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) { - vpx_img_alloc(&enc_img, enc_img.fmt - VPX_IMG_FMT_HIGHBITDEPTH, - enc_img.d_w, enc_img.d_h, 16); - vpx_img_truncate_16_to_8(&enc_img, &ref_enc.img); - } - if (dec_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) { - vpx_img_alloc(&dec_img, dec_img.fmt - VPX_IMG_FMT_HIGHBITDEPTH, - dec_img.d_w, dec_img.d_h, 16); - vpx_img_truncate_16_to_8(&dec_img, &ref_dec.img); - } - } -#endif - - if (!compare_img(&enc_img, &dec_img)) { - int y[4], u[4], v[4]; -#if CONFIG_VP9_HIGHBITDEPTH - if (enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) { - find_mismatch_high(&enc_img, &dec_img, y, u, v); - } else { - find_mismatch(&enc_img, &dec_img, y, u, v); - } -#else - find_mismatch(&enc_img, &dec_img, y, u, v); -#endif - decoder->err = 1; - printf( - "Encode/decode mismatch on frame %d at" - " Y[%d, %d] {%d/%d}," - " U[%d, %d] {%d/%d}," - " V[%d, %d] {%d/%d}\n", - frames_out, y[0], y[1], y[2], y[3], u[0], u[1], u[2], u[3], v[0], v[1], - v[2], v[3]); - *mismatch_seen = frames_out; - } - - vpx_img_free(&enc_img); - vpx_img_free(&dec_img); -} -#endif - -#if OUTPUT_RC_STATS -static void svc_output_rc_stats( - vpx_codec_ctx_t *codec, vpx_codec_enc_cfg_t *enc_cfg, - vpx_svc_layer_id_t *layer_id, const vpx_codec_cx_pkt_t *cx_pkt, - struct RateControlStats *rc, VpxVideoWriter **outfile, - const uint32_t frame_cnt, const double framerate) { - int num_layers_encoded = 0; - unsigned int sl, tl; - uint64_t sizes[8]; - uint64_t sizes_parsed[8]; - int count = 0; - double sum_bitrate = 0.0; - double sum_bitrate2 = 0.0; - vp9_zero(sizes); - vp9_zero(sizes_parsed); - vpx_codec_control(codec, VP9E_GET_SVC_LAYER_ID, layer_id); - parse_superframe_index(cx_pkt->data.frame.buf, cx_pkt->data.frame.sz, - sizes_parsed, &count); - if (enc_cfg->ss_number_layers == 1) { - sizes[0] = cx_pkt->data.frame.sz; - } else { - for (sl = 0; sl < enc_cfg->ss_number_layers; ++sl) { - sizes[sl] = 0; - if (cx_pkt->data.frame.spatial_layer_encoded[sl]) { - sizes[sl] = sizes_parsed[num_layers_encoded]; - num_layers_encoded++; - } - } - } - for (sl = 0; sl < enc_cfg->ss_number_layers; ++sl) { - unsigned int sl2; - uint64_t tot_size = 0; -#if SIMULCAST_MODE - for (sl2 = 0; sl2 < sl; ++sl2) { - if (cx_pkt->data.frame.spatial_layer_encoded[sl2]) tot_size += sizes[sl2]; - } - vpx_video_writer_write_frame(outfile[sl], - (uint8_t *)(cx_pkt->data.frame.buf) + tot_size, - (size_t)(sizes[sl]), cx_pkt->data.frame.pts); -#else - for (sl2 = 0; sl2 <= sl; ++sl2) { - if (cx_pkt->data.frame.spatial_layer_encoded[sl2]) tot_size += sizes[sl2]; - } - if (tot_size > 0) - vpx_video_writer_write_frame(outfile[sl], cx_pkt->data.frame.buf, - (size_t)(tot_size), cx_pkt->data.frame.pts); -#endif // SIMULCAST_MODE - } - for (sl = 0; sl < enc_cfg->ss_number_layers; ++sl) { - if (cx_pkt->data.frame.spatial_layer_encoded[sl]) { - for (tl = layer_id->temporal_layer_id; tl < enc_cfg->ts_number_layers; - ++tl) { - const int layer = sl * enc_cfg->ts_number_layers + tl; - ++rc->layer_tot_enc_frames[layer]; - rc->layer_encoding_bitrate[layer] += 8.0 * sizes[sl]; - // Keep count of rate control stats per layer, for non-key - // frames. - if (tl == (unsigned int)layer_id->temporal_layer_id && - !(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY)) { - rc->layer_avg_frame_size[layer] += 8.0 * sizes[sl]; - rc->layer_avg_rate_mismatch[layer] += - fabs(8.0 * sizes[sl] - rc->layer_pfb[layer]) / - rc->layer_pfb[layer]; - ++rc->layer_enc_frames[layer]; - } - } - } - } - - // Update for short-time encoding bitrate states, for moving - // window of size rc->window, shifted by rc->window / 2. - // Ignore first window segment, due to key frame. - if (frame_cnt > (unsigned int)rc->window_size) { - for (sl = 0; sl < enc_cfg->ss_number_layers; ++sl) { - if (cx_pkt->data.frame.spatial_layer_encoded[sl]) - sum_bitrate += 0.001 * 8.0 * sizes[sl] * framerate; - } - if (frame_cnt % rc->window_size == 0) { - rc->window_count += 1; - rc->avg_st_encoding_bitrate += sum_bitrate / rc->window_size; - rc->variance_st_encoding_bitrate += - (sum_bitrate / rc->window_size) * (sum_bitrate / rc->window_size); - } - } - - // Second shifted window. - if (frame_cnt > (unsigned int)(rc->window_size + rc->window_size / 2)) { - for (sl = 0; sl < enc_cfg->ss_number_layers; ++sl) { - sum_bitrate2 += 0.001 * 8.0 * sizes[sl] * framerate; - } - - if (frame_cnt > (unsigned int)(2 * rc->window_size) && - frame_cnt % rc->window_size == 0) { - rc->window_count += 1; - rc->avg_st_encoding_bitrate += sum_bitrate2 / rc->window_size; - rc->variance_st_encoding_bitrate += - (sum_bitrate2 / rc->window_size) * (sum_bitrate2 / rc->window_size); - } - } -} -#endif - -int main(int argc, const char **argv) { - AppInput app_input; - VpxVideoWriter *writer = NULL; - VpxVideoInfo info; - vpx_codec_ctx_t encoder; - vpx_codec_enc_cfg_t enc_cfg; - SvcContext svc_ctx; - vpx_svc_frame_drop_t svc_drop_frame; - uint32_t i; - uint32_t frame_cnt = 0; - vpx_image_t raw; - vpx_codec_err_t res; - int pts = 0; /* PTS starts at 0 */ - int frame_duration = 1; /* 1 timebase tick per frame */ - int end_of_stream = 0; -#if OUTPUT_FRAME_STATS - int frames_received = 0; -#endif -#if OUTPUT_RC_STATS - VpxVideoWriter *outfile[VPX_SS_MAX_LAYERS] = { NULL }; - struct RateControlStats rc; - vpx_svc_layer_id_t layer_id; - vpx_svc_ref_frame_config_t ref_frame_config; - unsigned int sl; - double framerate = 30.0; -#endif - struct vpx_usec_timer timer; - int64_t cx_time = 0; -#if CONFIG_INTERNAL_STATS - FILE *f = fopen("opsnr.stt", "a"); -#endif -#if CONFIG_VP9_DECODER && !SIMULCAST_MODE - int mismatch_seen = 0; - vpx_codec_ctx_t decoder; -#endif - memset(&svc_ctx, 0, sizeof(svc_ctx)); - memset(&app_input, 0, sizeof(AppInput)); - memset(&info, 0, sizeof(VpxVideoInfo)); - memset(&layer_id, 0, sizeof(vpx_svc_layer_id_t)); - memset(&rc, 0, sizeof(struct RateControlStats)); - exec_name = argv[0]; - - /* Setup default input stream settings */ - app_input.input_ctx.framerate.numerator = 30; - app_input.input_ctx.framerate.denominator = 1; - app_input.input_ctx.only_i420 = 1; - app_input.input_ctx.bit_depth = 0; - - parse_command_line(argc, argv, &app_input, &svc_ctx, &enc_cfg); - - // Y4M reader handles its own allocation. - if (app_input.input_ctx.file_type != FILE_TYPE_Y4M) { -// Allocate image buffer -#if CONFIG_VP9_HIGHBITDEPTH - if (!vpx_img_alloc(&raw, - enc_cfg.g_input_bit_depth == 8 ? VPX_IMG_FMT_I420 - : VPX_IMG_FMT_I42016, - enc_cfg.g_w, enc_cfg.g_h, 32)) { - die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h); - } -#else - if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, enc_cfg.g_w, enc_cfg.g_h, 32)) { - die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h); - } -#endif // CONFIG_VP9_HIGHBITDEPTH - } - - // Initialize codec - if (vpx_svc_init(&svc_ctx, &encoder, vpx_codec_vp9_cx(), &enc_cfg) != - VPX_CODEC_OK) - die("Failed to initialize encoder\n"); -#if CONFIG_VP9_DECODER && !SIMULCAST_MODE - if (vpx_codec_dec_init( - &decoder, get_vpx_decoder_by_name("vp9")->codec_interface(), NULL, 0)) - die("Failed to initialize decoder\n"); -#endif - -#if OUTPUT_RC_STATS - rc.window_count = 1; - rc.window_size = 15; // Silence a static analysis warning. - rc.avg_st_encoding_bitrate = 0.0; - rc.variance_st_encoding_bitrate = 0.0; - if (svc_ctx.output_rc_stat) { - set_rate_control_stats(&rc, &enc_cfg); - framerate = enc_cfg.g_timebase.den / enc_cfg.g_timebase.num; - } -#endif - - info.codec_fourcc = VP9_FOURCC; - info.frame_width = enc_cfg.g_w; - info.frame_height = enc_cfg.g_h; - info.time_base.numerator = enc_cfg.g_timebase.num; - info.time_base.denominator = enc_cfg.g_timebase.den; - - writer = - vpx_video_writer_open(app_input.output_filename, kContainerIVF, &info); - if (!writer) - die("Failed to open %s for writing\n", app_input.output_filename); - -#if OUTPUT_RC_STATS - // Write out spatial layer stream. - // TODO(marpan/jianj): allow for writing each spatial and temporal stream. - if (svc_ctx.output_rc_stat) { - for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) { - char file_name[PATH_MAX]; - - snprintf(file_name, sizeof(file_name), "%s_s%d.ivf", - app_input.output_filename, sl); - outfile[sl] = vpx_video_writer_open(file_name, kContainerIVF, &info); - if (!outfile[sl]) die("Failed to open %s for writing", file_name); - } - } -#endif - - // skip initial frames - for (i = 0; i < app_input.frames_to_skip; ++i) - read_frame(&app_input.input_ctx, &raw); - - if (svc_ctx.speed != -1) - vpx_codec_control(&encoder, VP8E_SET_CPUUSED, svc_ctx.speed); - if (svc_ctx.threads) { - vpx_codec_control(&encoder, VP9E_SET_TILE_COLUMNS, - get_msb(svc_ctx.threads)); - if (svc_ctx.threads > 1) - vpx_codec_control(&encoder, VP9E_SET_ROW_MT, 1); - else - vpx_codec_control(&encoder, VP9E_SET_ROW_MT, 0); - } - if (svc_ctx.speed >= 5 && svc_ctx.aqmode == 1) - vpx_codec_control(&encoder, VP9E_SET_AQ_MODE, 3); - if (svc_ctx.speed >= 5) - vpx_codec_control(&encoder, VP8E_SET_STATIC_THRESHOLD, 1); - vpx_codec_control(&encoder, VP8E_SET_MAX_INTRA_BITRATE_PCT, 900); - - vpx_codec_control(&encoder, VP9E_SET_SVC_INTER_LAYER_PRED, - app_input.inter_layer_pred); - - vpx_codec_control(&encoder, VP9E_SET_NOISE_SENSITIVITY, 0); - - vpx_codec_control(&encoder, VP9E_SET_TUNE_CONTENT, app_input.tune_content); - - vpx_codec_control(&encoder, VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, 0); - vpx_codec_control(&encoder, VP9E_SET_DISABLE_LOOPFILTER, 0); - - svc_drop_frame.framedrop_mode = FULL_SUPERFRAME_DROP; - for (sl = 0; sl < (unsigned int)svc_ctx.spatial_layers; ++sl) - svc_drop_frame.framedrop_thresh[sl] = enc_cfg.rc_dropframe_thresh; - svc_drop_frame.max_consec_drop = INT_MAX; - vpx_codec_control(&encoder, VP9E_SET_SVC_FRAME_DROP_LAYER, &svc_drop_frame); - - // Encode frames - while (!end_of_stream) { - vpx_codec_iter_t iter = NULL; - const vpx_codec_cx_pkt_t *cx_pkt; - // Example patterns for bypass/flexible mode: - // example_pattern = 0: 2 temporal layers, and spatial_layers = 1,2,3. Exact - // to fixed SVC patterns. example_pattern = 1: 2 spatial and 2 temporal - // layers, with SL0 only has TL0, and SL1 has both TL0 and TL1. This example - // uses the extended API. - int example_pattern = 0; - if (frame_cnt >= app_input.frames_to_code || - !read_frame(&app_input.input_ctx, &raw)) { - // We need one extra vpx_svc_encode call at end of stream to flush - // encoder and get remaining data - end_of_stream = 1; - } - - // For BYPASS/FLEXIBLE mode, set the frame flags (reference and updates) - // and the buffer indices for each spatial layer of the current - // (super)frame to be encoded. The spatial and temporal layer_id for the - // current frame also needs to be set. - // TODO(marpan): Should rename the "VP9E_TEMPORAL_LAYERING_MODE_BYPASS" - // mode to "VP9E_LAYERING_MODE_BYPASS". - if (svc_ctx.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) { - layer_id.spatial_layer_id = 0; - // Example for 2 temporal layers. - if (frame_cnt % 2 == 0) { - layer_id.temporal_layer_id = 0; - for (i = 0; i < VPX_SS_MAX_LAYERS; i++) - layer_id.temporal_layer_id_per_spatial[i] = 0; - } else { - layer_id.temporal_layer_id = 1; - for (i = 0; i < VPX_SS_MAX_LAYERS; i++) - layer_id.temporal_layer_id_per_spatial[i] = 1; - } - if (example_pattern == 1) { - // example_pattern 1 is hard-coded for 2 spatial and 2 temporal layers. - assert(svc_ctx.spatial_layers == 2); - assert(svc_ctx.temporal_layers == 2); - if (frame_cnt % 2 == 0) { - // Spatial layer 0 and 1 are encoded. - layer_id.temporal_layer_id_per_spatial[0] = 0; - layer_id.temporal_layer_id_per_spatial[1] = 0; - layer_id.spatial_layer_id = 0; - } else { - // Only spatial layer 1 is encoded here. - layer_id.temporal_layer_id_per_spatial[1] = 1; - layer_id.spatial_layer_id = 1; - } - } - vpx_codec_control(&encoder, VP9E_SET_SVC_LAYER_ID, &layer_id); - // TODO(jianj): Fix the parameter passing for "is_key_frame" in - // set_frame_flags_bypass_model() for case of periodic key frames. - if (example_pattern == 0) { - set_frame_flags_bypass_mode_ex0(layer_id.temporal_layer_id, - svc_ctx.spatial_layers, frame_cnt == 0, - &ref_frame_config); - } else if (example_pattern == 1) { - set_frame_flags_bypass_mode_ex1(layer_id.temporal_layer_id, - svc_ctx.spatial_layers, frame_cnt == 0, - &ref_frame_config); - } - ref_frame_config.duration[0] = frame_duration * 1; - ref_frame_config.duration[1] = frame_duration * 1; - - vpx_codec_control(&encoder, VP9E_SET_SVC_REF_FRAME_CONFIG, - &ref_frame_config); - // Keep track of input frames, to account for frame drops in rate control - // stats/metrics. - for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) { - ++rc.layer_input_frames[sl * enc_cfg.ts_number_layers + - layer_id.temporal_layer_id]; - } - } else { - // For the fixed pattern SVC, temporal layer is given by superframe count. - unsigned int tl = 0; - if (enc_cfg.ts_number_layers == 2) - tl = (frame_cnt % 2 != 0); - else if (enc_cfg.ts_number_layers == 3) { - if (frame_cnt % 2 != 0) tl = 2; - if ((frame_cnt > 1) && ((frame_cnt - 2) % 4 == 0)) tl = 1; - } - for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) - ++rc.layer_input_frames[sl * enc_cfg.ts_number_layers + tl]; - } - - vpx_usec_timer_start(&timer); - res = vpx_svc_encode( - &svc_ctx, &encoder, (end_of_stream ? NULL : &raw), pts, frame_duration, - svc_ctx.speed >= 5 ? VPX_DL_REALTIME : VPX_DL_GOOD_QUALITY); - vpx_usec_timer_mark(&timer); - cx_time += vpx_usec_timer_elapsed(&timer); - - fflush(stdout); - if (res != VPX_CODEC_OK) { - die_codec(&encoder, "Failed to encode frame"); - } - - while ((cx_pkt = vpx_codec_get_cx_data(&encoder, &iter)) != NULL) { - switch (cx_pkt->kind) { - case VPX_CODEC_CX_FRAME_PKT: { - SvcInternal_t *const si = (SvcInternal_t *)svc_ctx.internal; - if (cx_pkt->data.frame.sz > 0) { - vpx_video_writer_write_frame(writer, cx_pkt->data.frame.buf, - cx_pkt->data.frame.sz, - cx_pkt->data.frame.pts); -#if OUTPUT_RC_STATS - if (svc_ctx.output_rc_stat) { - svc_output_rc_stats(&encoder, &enc_cfg, &layer_id, cx_pkt, &rc, - outfile, frame_cnt, framerate); - } -#endif - } -#if OUTPUT_FRAME_STATS - printf("SVC frame: %d, kf: %d, size: %d, pts: %d\n", frames_received, - !!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY), - (int)cx_pkt->data.frame.sz, (int)cx_pkt->data.frame.pts); - ++frames_received; -#endif - if (enc_cfg.ss_number_layers == 1 && enc_cfg.ts_number_layers == 1) - si->bytes_sum[0] += (int)cx_pkt->data.frame.sz; -#if CONFIG_VP9_DECODER && !SIMULCAST_MODE - if (vpx_codec_decode(&decoder, cx_pkt->data.frame.buf, - (unsigned int)cx_pkt->data.frame.sz, NULL, 0)) - die_codec(&decoder, "Failed to decode frame."); -#endif - break; - } - case VPX_CODEC_STATS_PKT: { - stats_write(&app_input.rc_stats, cx_pkt->data.twopass_stats.buf, - cx_pkt->data.twopass_stats.sz); - break; - } - default: { - break; - } - } - -#if CONFIG_VP9_DECODER && !SIMULCAST_MODE - vpx_codec_control(&encoder, VP9E_GET_SVC_LAYER_ID, &layer_id); - // Don't look for mismatch on top spatial and top temporal layers as they - // are non reference frames. Don't look at frames whose top spatial layer - // is dropped. - if ((enc_cfg.ss_number_layers > 1 || enc_cfg.ts_number_layers > 1) && - cx_pkt->data.frame - .spatial_layer_encoded[enc_cfg.ss_number_layers - 1] && - !(layer_id.temporal_layer_id > 0 && - layer_id.temporal_layer_id == (int)enc_cfg.ts_number_layers - 1)) { - test_decode(&encoder, &decoder, frame_cnt, &mismatch_seen); - } -#endif - } - - if (!end_of_stream) { - ++frame_cnt; - pts += frame_duration; - } - } - - printf("Processed %d frames\n", frame_cnt); - - close_input_file(&app_input.input_ctx); - -#if OUTPUT_RC_STATS - if (svc_ctx.output_rc_stat) { - printout_rate_control_summary(&rc, &enc_cfg, frame_cnt); - printf("\n"); - } -#endif - if (vpx_codec_destroy(&encoder)) - die_codec(&encoder, "Failed to destroy codec"); - if (writer) { - vpx_video_writer_close(writer); - } -#if OUTPUT_RC_STATS - if (svc_ctx.output_rc_stat) { - for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) { - vpx_video_writer_close(outfile[sl]); - } - } -#endif -#if CONFIG_INTERNAL_STATS - if (mismatch_seen) { - fprintf(f, "First mismatch occurred in frame %d\n", mismatch_seen); - } else { - fprintf(f, "No mismatch detected in recon buffers\n"); - } - fclose(f); -#endif - printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n", - frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000), - 1000000 * (double)frame_cnt / (double)cx_time); - if (app_input.input_ctx.file_type != FILE_TYPE_Y4M) { - vpx_img_free(&raw); - } - // display average size, psnr - vpx_svc_dump_statistics(&svc_ctx); - vpx_svc_release(&svc_ctx); - return EXIT_SUCCESS; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/examples/vp9cx_set_ref.c b/presentation/src/main/cpp/third_party/libvpx/examples/vp9cx_set_ref.c deleted file mode 100644 index 6e12d668..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/examples/vp9cx_set_ref.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// VP9 Set Reference Frame -// ============================ -// -// This is an example demonstrating how to overwrite the VP9 encoder's -// internal reference frame. In the sample we set the last frame to the -// current frame. This technique could be used to bounce between two cameras. -// -// The decoder would also have to set the reference frame to the same value -// on the same frame, or the video will become corrupt. The 'test_decode' -// variable is set to 1 in this example that tests if the encoder and decoder -// results are matching. -// -// Usage -// ----- -// This example encodes a raw video. And the last argument passed in specifies -// the frame number to update the reference frame on. For example, run -// examples/vp9cx_set_ref 352 288 in.yuv out.ivf 4 30 -// The parameter is parsed as follows: -// -// -// Extra Variables -// --------------- -// This example maintains the frame number passed on the command line -// in the `update_frame_num` variable. -// -// -// Configuration -// ------------- -// -// The reference frame is updated on the frame specified on the command -// line. -// -// Observing The Effects -// --------------------- -// The encoder and decoder results should be matching when the same reference -// frame setting operation is done in both encoder and decoder. Otherwise, -// the encoder/decoder mismatch would be seen. - -#include -#include -#include - -#include "vpx/vp8cx.h" -#include "vpx/vpx_decoder.h" -#include "vpx/vpx_encoder.h" -#include "vp9/common/vp9_common.h" - -#include "./tools_common.h" -#include "./video_writer.h" - -static const char *exec_name; - -void usage_exit(void) { - fprintf(stderr, - "Usage: %s " - " \n", - exec_name); - exit(EXIT_FAILURE); -} - -static void testing_decode(vpx_codec_ctx_t *encoder, vpx_codec_ctx_t *decoder, - unsigned int frame_out, int *mismatch_seen) { - vpx_image_t enc_img, dec_img; - struct vp9_ref_frame ref_enc, ref_dec; - - if (*mismatch_seen) return; - - ref_enc.idx = 0; - ref_dec.idx = 0; - if (vpx_codec_control(encoder, VP9_GET_REFERENCE, &ref_enc)) - die_codec(encoder, "Failed to get encoder reference frame"); - enc_img = ref_enc.img; - if (vpx_codec_control(decoder, VP9_GET_REFERENCE, &ref_dec)) - die_codec(decoder, "Failed to get decoder reference frame"); - dec_img = ref_dec.img; - - if (!compare_img(&enc_img, &dec_img)) { - int y[4], u[4], v[4]; - - *mismatch_seen = 1; - - find_mismatch(&enc_img, &dec_img, y, u, v); - printf( - "Encode/decode mismatch on frame %d at" - " Y[%d, %d] {%d/%d}," - " U[%d, %d] {%d/%d}," - " V[%d, %d] {%d/%d}", - frame_out, y[0], y[1], y[2], y[3], u[0], u[1], u[2], u[3], v[0], v[1], - v[2], v[3]); - } - - vpx_img_free(&enc_img); - vpx_img_free(&dec_img); -} - -static int encode_frame(vpx_codec_ctx_t *ecodec, vpx_image_t *img, - unsigned int frame_in, VpxVideoWriter *writer, - int test_decode, vpx_codec_ctx_t *dcodec, - unsigned int *frame_out, int *mismatch_seen) { - int got_pkts = 0; - vpx_codec_iter_t iter = NULL; - const vpx_codec_cx_pkt_t *pkt = NULL; - int got_data; - const vpx_codec_err_t res = - vpx_codec_encode(ecodec, img, frame_in, 1, 0, VPX_DL_GOOD_QUALITY); - if (res != VPX_CODEC_OK) die_codec(ecodec, "Failed to encode frame"); - - got_data = 0; - - while ((pkt = vpx_codec_get_cx_data(ecodec, &iter)) != NULL) { - got_pkts = 1; - - if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { - const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0; - - if (!(pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT)) { - *frame_out += 1; - } - - if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf, - pkt->data.frame.sz, - pkt->data.frame.pts)) { - die_codec(ecodec, "Failed to write compressed frame"); - } - printf(keyframe ? "K" : "."); - fflush(stdout); - got_data = 1; - - // Decode 1 frame. - if (test_decode) { - if (vpx_codec_decode(dcodec, pkt->data.frame.buf, - (unsigned int)pkt->data.frame.sz, NULL, 0)) - die_codec(dcodec, "Failed to decode frame."); - } - } - } - - // Mismatch checking - if (got_data && test_decode) { - testing_decode(ecodec, dcodec, *frame_out, mismatch_seen); - } - - return got_pkts; -} - -int main(int argc, char **argv) { - FILE *infile = NULL; - // Encoder - vpx_codec_ctx_t ecodec; - vpx_codec_enc_cfg_t cfg; - unsigned int frame_in = 0; - vpx_image_t raw; - vpx_codec_err_t res; - VpxVideoInfo info; - VpxVideoWriter *writer = NULL; - const VpxInterface *encoder = NULL; - - // Test encoder/decoder mismatch. - int test_decode = 1; - // Decoder - vpx_codec_ctx_t dcodec; - unsigned int frame_out = 0; - - // The frame number to set reference frame on - unsigned int update_frame_num = 0; - int mismatch_seen = 0; - - const int fps = 30; - const int bitrate = 500; - - const char *width_arg = NULL; - const char *height_arg = NULL; - const char *infile_arg = NULL; - const char *outfile_arg = NULL; - const char *update_frame_num_arg = NULL; - unsigned int limit = 0; - - vp9_zero(ecodec); - vp9_zero(cfg); - vp9_zero(info); - - exec_name = argv[0]; - - if (argc < 6) die("Invalid number of arguments"); - - width_arg = argv[1]; - height_arg = argv[2]; - infile_arg = argv[3]; - outfile_arg = argv[4]; - update_frame_num_arg = argv[5]; - - encoder = get_vpx_encoder_by_name("vp9"); - if (!encoder) die("Unsupported codec."); - - update_frame_num = (unsigned int)strtoul(update_frame_num_arg, NULL, 0); - // In VP9, the reference buffers (cm->buffer_pool->frame_bufs[i].buf) are - // allocated while calling vpx_codec_encode(), thus, setting reference for - // 1st frame isn't supported. - if (update_frame_num <= 1) { - die("Couldn't parse frame number '%s'\n", update_frame_num_arg); - } - - if (argc > 6) { - limit = (unsigned int)strtoul(argv[6], NULL, 0); - if (update_frame_num > limit) - die("Update frame number couldn't larger than limit\n"); - } - - info.codec_fourcc = encoder->fourcc; - info.frame_width = (int)strtol(width_arg, NULL, 0); - info.frame_height = (int)strtol(height_arg, NULL, 0); - info.time_base.numerator = 1; - info.time_base.denominator = fps; - - if (info.frame_width <= 0 || info.frame_height <= 0 || - (info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) { - die("Invalid frame size: %dx%d", info.frame_width, info.frame_height); - } - - if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, info.frame_width, - info.frame_height, 1)) { - die("Failed to allocate image."); - } - - printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface())); - - res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0); - if (res) die_codec(&ecodec, "Failed to get default codec config."); - - cfg.g_w = info.frame_width; - cfg.g_h = info.frame_height; - cfg.g_timebase.num = info.time_base.numerator; - cfg.g_timebase.den = info.time_base.denominator; - cfg.rc_target_bitrate = bitrate; - cfg.g_lag_in_frames = 3; - - writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info); - if (!writer) die("Failed to open %s for writing.", outfile_arg); - - if (!(infile = fopen(infile_arg, "rb"))) - die("Failed to open %s for reading.", infile_arg); - - if (vpx_codec_enc_init(&ecodec, encoder->codec_interface(), &cfg, 0)) - die("Failed to initialize encoder"); - - // Disable alt_ref. - if (vpx_codec_control(&ecodec, VP8E_SET_ENABLEAUTOALTREF, 0)) - die_codec(&ecodec, "Failed to set enable auto alt ref"); - - if (test_decode) { - const VpxInterface *decoder = get_vpx_decoder_by_name("vp9"); - if (vpx_codec_dec_init(&dcodec, decoder->codec_interface(), NULL, 0)) - die_codec(&dcodec, "Failed to initialize decoder."); - } - - // Encode frames. - while (vpx_img_read(&raw, infile)) { - if (limit && frame_in >= limit) break; - if (update_frame_num > 1 && frame_out + 1 == update_frame_num) { - vpx_ref_frame_t ref; - ref.frame_type = VP8_LAST_FRAME; - ref.img = raw; - // Set reference frame in encoder. - if (vpx_codec_control(&ecodec, VP8_SET_REFERENCE, &ref)) - die_codec(&ecodec, "Failed to set reference frame"); - printf(" "); - - // If set_reference in decoder is commented out, the enc/dec mismatch - // would be seen. - if (test_decode) { - if (vpx_codec_control(&dcodec, VP8_SET_REFERENCE, &ref)) - die_codec(&dcodec, "Failed to set reference frame"); - } - } - - encode_frame(&ecodec, &raw, frame_in, writer, test_decode, &dcodec, - &frame_out, &mismatch_seen); - frame_in++; - if (mismatch_seen) break; - } - - // Flush encoder. - if (!mismatch_seen) - while (encode_frame(&ecodec, NULL, frame_in, writer, test_decode, &dcodec, - &frame_out, &mismatch_seen)) { - } - - printf("\n"); - fclose(infile); - printf("Processed %d frames.\n", frame_out); - - if (test_decode) { - if (!mismatch_seen) - printf("Encoder/decoder results are matching.\n"); - else - printf("Encoder/decoder results are NOT matching.\n"); - } - - if (test_decode) - if (vpx_codec_destroy(&dcodec)) - die_codec(&dcodec, "Failed to destroy decoder"); - - vpx_img_free(&raw); - if (vpx_codec_destroy(&ecodec)) - die_codec(&ecodec, "Failed to destroy encoder."); - - vpx_video_writer_close(writer); - - return EXIT_SUCCESS; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/examples/vpx_dec_fuzzer.cc b/presentation/src/main/cpp/third_party/libvpx/examples/vpx_dec_fuzzer.cc deleted file mode 100644 index 13ea295f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/examples/vpx_dec_fuzzer.cc +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * Fuzzer for libvpx decoders - * ========================== - * Requirements - * -------------- - * Requires Clang 6.0 or above as -fsanitize=fuzzer is used as a linker - * option. - - * Steps to build - * -------------- - * Clone libvpx repository - $git clone https://chromium.googlesource.com/webm/libvpx - - * Create a directory in parallel to libvpx and change directory - $mkdir vpx_dec_fuzzer - $cd vpx_dec_fuzzer/ - - * Enable sanitizers (Supported: address integer memory thread undefined) - $source ../libvpx/tools/set_analyzer_env.sh address - - * Configure libvpx. - * Note --size-limit and VPX_MAX_ALLOCABLE_MEMORY are defined to avoid - * Out of memory errors when running generated fuzzer binary - $../libvpx/configure --disable-unit-tests --size-limit=12288x12288 \ - --extra-cflags="-fsanitize=fuzzer-no-link \ - -DVPX_MAX_ALLOCABLE_MEMORY=1073741824" \ - --disable-webm-io --enable-debug --disable-vp8-encoder \ - --disable-vp9-encoder --disable-examples - - * Build libvpx - $make -j32 - - * Build vp9 fuzzer - $ $CXX $CXXFLAGS -std=gnu++11 -DDECODER=vp9 \ - -fsanitize=fuzzer -I../libvpx -I. -Wl,--start-group \ - ../libvpx/examples/vpx_dec_fuzzer.cc -o ./vpx_dec_fuzzer_vp9 \ - ./libvpx.a -Wl,--end-group - - * DECODER should be defined as vp9 or vp8 to enable vp9/vp8 - * - * create a corpus directory and copy some ivf files there. - * Based on which codec (vp8/vp9) is being tested, it is recommended to - * have corresponding ivf files in corpus directory - * Empty corpus directoy also is acceptable, though not recommended - $mkdir CORPUS && cp some-files CORPUS - - * Run fuzzing: - $./vpx_dec_fuzzer_vp9 CORPUS - - * References: - * http://llvm.org/docs/LibFuzzer.html - * https://github.com/google/oss-fuzz - */ - -#include -#include -#include -#include -#include -#include - -#include "vpx/vp8dx.h" -#include "vpx/vpx_decoder.h" -#include "vpx_ports/mem_ops.h" - -#define IVF_FRAME_HDR_SZ (4 + 8) /* 4 byte size + 8 byte timestamp */ -#define IVF_FILE_HDR_SZ 32 - -#define VPXD_INTERFACE(name) VPXD_INTERFACE_(name) -#define VPXD_INTERFACE_(name) vpx_codec_##name##_dx() - -extern "C" void usage_exit(void) { exit(EXIT_FAILURE); } - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - if (size <= IVF_FILE_HDR_SZ) { - return 0; - } - - vpx_codec_ctx_t codec; - // Set thread count in the range [1, 64]. - const unsigned int threads = (data[IVF_FILE_HDR_SZ] & 0x3f) + 1; - vpx_codec_dec_cfg_t cfg = { threads, 0, 0 }; - if (vpx_codec_dec_init(&codec, VPXD_INTERFACE(DECODER), &cfg, 0)) { - return 0; - } - - if (threads > 1) { - const int enable = (data[IVF_FILE_HDR_SZ] & 0xa0) != 0; - const vpx_codec_err_t err = - vpx_codec_control(&codec, VP9D_SET_LOOP_FILTER_OPT, enable); - static_cast(err); - } - - data += IVF_FILE_HDR_SZ; - size -= IVF_FILE_HDR_SZ; - - while (size > IVF_FRAME_HDR_SZ) { - size_t frame_size = mem_get_le32(data); - size -= IVF_FRAME_HDR_SZ; - data += IVF_FRAME_HDR_SZ; - frame_size = std::min(size, frame_size); - - vpx_codec_stream_info_t stream_info; - stream_info.sz = sizeof(stream_info); - vpx_codec_err_t err = vpx_codec_peek_stream_info(VPXD_INTERFACE(DECODER), - data, size, &stream_info); - static_cast(err); - - err = vpx_codec_decode(&codec, data, frame_size, nullptr, 0); - static_cast(err); - vpx_codec_iter_t iter = nullptr; - vpx_image_t *img = nullptr; - while ((img = vpx_codec_get_frame(&codec, &iter)) != nullptr) { - } - data += frame_size; - size -= frame_size; - } - vpx_codec_destroy(&codec); - return 0; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/examples/vpx_temporal_svc_encoder.c b/presentation/src/main/cpp/third_party/libvpx/examples/vpx_temporal_svc_encoder.c deleted file mode 100644 index a8002782..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/examples/vpx_temporal_svc_encoder.c +++ /dev/null @@ -1,1069 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// This is an example demonstrating how to implement a multi-layer VPx -// encoding scheme based on temporal scalability for video applications -// that benefit from a scalable bitstream. - -#include -#include -#include -#include -#include - -#include "./vpx_config.h" -#include "./y4minput.h" -#include "../vpx_ports/vpx_timer.h" -#include "vpx/vp8cx.h" -#include "vpx/vpx_encoder.h" -#include "vpx_ports/bitops.h" - -#include "../tools_common.h" -#include "../video_writer.h" - -#define ROI_MAP 0 - -#define zero(Dest) memset(&(Dest), 0, sizeof(Dest)) - -static const char *exec_name; - -void usage_exit(void) { exit(EXIT_FAILURE); } - -// Denoiser states for vp8, for temporal denoising. -enum denoiserStateVp8 { - kVp8DenoiserOff, - kVp8DenoiserOnYOnly, - kVp8DenoiserOnYUV, - kVp8DenoiserOnYUVAggressive, - kVp8DenoiserOnAdaptive -}; - -// Denoiser states for vp9, for temporal denoising. -enum denoiserStateVp9 { - kVp9DenoiserOff, - kVp9DenoiserOnYOnly, - // For SVC: denoise the top two spatial layers. - kVp9DenoiserOnYTwoSpatialLayers -}; - -static int mode_to_num_layers[13] = { 1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3, 3 }; - -// For rate control encoding stats. -struct RateControlMetrics { - // Number of input frames per layer. - int layer_input_frames[VPX_TS_MAX_LAYERS]; - // Total (cumulative) number of encoded frames per layer. - int layer_tot_enc_frames[VPX_TS_MAX_LAYERS]; - // Number of encoded non-key frames per layer. - int layer_enc_frames[VPX_TS_MAX_LAYERS]; - // Framerate per layer layer (cumulative). - double layer_framerate[VPX_TS_MAX_LAYERS]; - // Target average frame size per layer (per-frame-bandwidth per layer). - double layer_pfb[VPX_TS_MAX_LAYERS]; - // Actual average frame size per layer. - double layer_avg_frame_size[VPX_TS_MAX_LAYERS]; - // Average rate mismatch per layer (|target - actual| / target). - double layer_avg_rate_mismatch[VPX_TS_MAX_LAYERS]; - // Actual encoding bitrate per layer (cumulative). - double layer_encoding_bitrate[VPX_TS_MAX_LAYERS]; - // Average of the short-time encoder actual bitrate. - // TODO(marpan): Should we add these short-time stats for each layer? - double avg_st_encoding_bitrate; - // Variance of the short-time encoder actual bitrate. - double variance_st_encoding_bitrate; - // Window (number of frames) for computing short-timee encoding bitrate. - int window_size; - // Number of window measurements. - int window_count; - int layer_target_bitrate[VPX_MAX_LAYERS]; -}; - -// Note: these rate control metrics assume only 1 key frame in the -// sequence (i.e., first frame only). So for temporal pattern# 7 -// (which has key frame for every frame on base layer), the metrics -// computation will be off/wrong. -// TODO(marpan): Update these metrics to account for multiple key frames -// in the stream. -static void set_rate_control_metrics(struct RateControlMetrics *rc, - vpx_codec_enc_cfg_t *cfg) { - int i = 0; - // Set the layer (cumulative) framerate and the target layer (non-cumulative) - // per-frame-bandwidth, for the rate control encoding stats below. - const double framerate = cfg->g_timebase.den / cfg->g_timebase.num; - const int ts_number_layers = cfg->ts_number_layers; - rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0]; - rc->layer_pfb[0] = - 1000.0 * rc->layer_target_bitrate[0] / rc->layer_framerate[0]; - for (i = 0; i < ts_number_layers; ++i) { - if (i > 0) { - rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i]; - rc->layer_pfb[i] = - 1000.0 * - (rc->layer_target_bitrate[i] - rc->layer_target_bitrate[i - 1]) / - (rc->layer_framerate[i] - rc->layer_framerate[i - 1]); - } - rc->layer_input_frames[i] = 0; - rc->layer_enc_frames[i] = 0; - rc->layer_tot_enc_frames[i] = 0; - rc->layer_encoding_bitrate[i] = 0.0; - rc->layer_avg_frame_size[i] = 0.0; - rc->layer_avg_rate_mismatch[i] = 0.0; - } - rc->window_count = 0; - rc->window_size = 15; - rc->avg_st_encoding_bitrate = 0.0; - rc->variance_st_encoding_bitrate = 0.0; - // Target bandwidth for the whole stream. - // Set to layer_target_bitrate for highest layer (total bitrate). - cfg->rc_target_bitrate = rc->layer_target_bitrate[ts_number_layers - 1]; -} - -static void printout_rate_control_summary(struct RateControlMetrics *rc, - vpx_codec_enc_cfg_t *cfg, - int frame_cnt) { - unsigned int i = 0; - int tot_num_frames = 0; - double perc_fluctuation = 0.0; - printf("Total number of processed frames: %d\n\n", frame_cnt - 1); - printf("Rate control layer stats for %d layer(s):\n\n", - cfg->ts_number_layers); - for (i = 0; i < cfg->ts_number_layers; ++i) { - const int num_dropped = - (i > 0) ? (rc->layer_input_frames[i] - rc->layer_enc_frames[i]) - : (rc->layer_input_frames[i] - rc->layer_enc_frames[i] - 1); - tot_num_frames += rc->layer_input_frames[i]; - rc->layer_encoding_bitrate[i] = 0.001 * rc->layer_framerate[i] * - rc->layer_encoding_bitrate[i] / - tot_num_frames; - rc->layer_avg_frame_size[i] = - rc->layer_avg_frame_size[i] / rc->layer_enc_frames[i]; - rc->layer_avg_rate_mismatch[i] = - 100.0 * rc->layer_avg_rate_mismatch[i] / rc->layer_enc_frames[i]; - printf("For layer#: %d \n", i); - printf("Bitrate (target vs actual): %d %f \n", rc->layer_target_bitrate[i], - rc->layer_encoding_bitrate[i]); - printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i], - rc->layer_avg_frame_size[i]); - printf("Average rate_mismatch: %f \n", rc->layer_avg_rate_mismatch[i]); - printf( - "Number of input frames, encoded (non-key) frames, " - "and perc dropped frames: %d %d %f \n", - rc->layer_input_frames[i], rc->layer_enc_frames[i], - 100.0 * num_dropped / rc->layer_input_frames[i]); - printf("\n"); - } - rc->avg_st_encoding_bitrate = rc->avg_st_encoding_bitrate / rc->window_count; - rc->variance_st_encoding_bitrate = - rc->variance_st_encoding_bitrate / rc->window_count - - (rc->avg_st_encoding_bitrate * rc->avg_st_encoding_bitrate); - perc_fluctuation = 100.0 * sqrt(rc->variance_st_encoding_bitrate) / - rc->avg_st_encoding_bitrate; - printf("Short-time stats, for window of %d frames: \n", rc->window_size); - printf("Average, rms-variance, and percent-fluct: %f %f %f \n", - rc->avg_st_encoding_bitrate, sqrt(rc->variance_st_encoding_bitrate), - perc_fluctuation); - if ((frame_cnt - 1) != tot_num_frames) - die("Error: Number of input frames not equal to output! \n"); -} - -#if ROI_MAP -static void set_roi_map(const char *enc_name, vpx_codec_enc_cfg_t *cfg, - vpx_roi_map_t *roi) { - unsigned int i, j; - int block_size = 0; - uint8_t is_vp8 = strncmp(enc_name, "vp8", 3) == 0 ? 1 : 0; - uint8_t is_vp9 = strncmp(enc_name, "vp9", 3) == 0 ? 1 : 0; - if (!is_vp8 && !is_vp9) { - die("unsupported codec."); - } - zero(*roi); - - block_size = is_vp9 && !is_vp8 ? 8 : 16; - - // ROI is based on the segments (4 for vp8, 8 for vp9), smallest unit for - // segment is 16x16 for vp8, 8x8 for vp9. - roi->rows = (cfg->g_h + block_size - 1) / block_size; - roi->cols = (cfg->g_w + block_size - 1) / block_size; - - // Applies delta QP on the segment blocks, varies from -63 to 63. - // Setting to negative means lower QP (better quality). - // Below we set delta_q to the extreme (-63) to show strong effect. - // VP8 uses the first 4 segments. VP9 uses all 8 segments. - zero(roi->delta_q); - roi->delta_q[1] = -63; - - // Applies delta loopfilter strength on the segment blocks, varies from -63 to - // 63. Setting to positive means stronger loopfilter. VP8 uses the first 4 - // segments. VP9 uses all 8 segments. - zero(roi->delta_lf); - - if (is_vp8) { - // Applies skip encoding threshold on the segment blocks, varies from 0 to - // UINT_MAX. Larger value means more skipping of encoding is possible. - // This skip threshold only applies on delta frames. - zero(roi->static_threshold); - } - - if (is_vp9) { - // Apply skip segment. Setting to 1 means this block will be copied from - // previous frame. - zero(roi->skip); - } - - if (is_vp9) { - // Apply ref frame segment. - // -1 : Do not apply this segment. - // 0 : Froce using intra. - // 1 : Force using last. - // 2 : Force using golden. - // 3 : Force using alfref but not used in non-rd pickmode for 0 lag. - memset(roi->ref_frame, -1, sizeof(roi->ref_frame)); - roi->ref_frame[1] = 1; - } - - // Use 2 states: 1 is center square, 0 is the rest. - roi->roi_map = - (uint8_t *)calloc(roi->rows * roi->cols, sizeof(*roi->roi_map)); - for (i = 0; i < roi->rows; ++i) { - for (j = 0; j < roi->cols; ++j) { - if (i > (roi->rows >> 2) && i < ((roi->rows * 3) >> 2) && - j > (roi->cols >> 2) && j < ((roi->cols * 3) >> 2)) { - roi->roi_map[i * roi->cols + j] = 1; - } - } - } -} - -static void set_roi_skip_map(vpx_codec_enc_cfg_t *cfg, vpx_roi_map_t *roi, - int *skip_map, int *prev_mask_map, int frame_num) { - const int block_size = 8; - unsigned int i, j; - roi->rows = (cfg->g_h + block_size - 1) / block_size; - roi->cols = (cfg->g_w + block_size - 1) / block_size; - zero(roi->skip); - zero(roi->delta_q); - zero(roi->delta_lf); - memset(roi->ref_frame, -1, sizeof(roi->ref_frame)); - roi->ref_frame[1] = 1; - // Use segment 3 for skip. - roi->skip[3] = 1; - roi->roi_map = - (uint8_t *)calloc(roi->rows * roi->cols, sizeof(*roi->roi_map)); - for (i = 0; i < roi->rows; ++i) { - for (j = 0; j < roi->cols; ++j) { - const int idx = i * roi->cols + j; - // Use segment 3 for skip. - // prev_mask_map keeps track of blocks that have been stably on segment 3 - // for the past 10 frames. Only skip when the block is on segment 3 in - // both current map and prev_mask_map. - if (skip_map[idx] == 1 && prev_mask_map[idx] == 1) roi->roi_map[idx] = 3; - // Reset it every 10 frames so it doesn't propagate for too many frames. - if (frame_num % 10 == 0) - prev_mask_map[idx] = skip_map[idx]; - else if (prev_mask_map[idx] == 1 && skip_map[idx] == 0) - prev_mask_map[idx] = 0; - } - } -} -#endif - -// Temporal scaling parameters: -// NOTE: The 3 prediction frames cannot be used interchangeably due to -// differences in the way they are handled throughout the code. The -// frames should be allocated to layers in the order LAST, GF, ARF. -// Other combinations work, but may produce slightly inferior results. -static void set_temporal_layer_pattern(int layering_mode, - vpx_codec_enc_cfg_t *cfg, - int *layer_flags, - int *flag_periodicity) { - switch (layering_mode) { - case 0: { - // 1-layer. - int ids[1] = { 0 }; - cfg->ts_periodicity = 1; - *flag_periodicity = 1; - cfg->ts_number_layers = 1; - cfg->ts_rate_decimator[0] = 1; - memcpy(cfg->ts_layer_id, ids, sizeof(ids)); - // Update L only. - layer_flags[0] = - VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; - break; - } - case 1: { - // 2-layers, 2-frame period. - int ids[2] = { 0, 1 }; - cfg->ts_periodicity = 2; - *flag_periodicity = 2; - cfg->ts_number_layers = 2; - cfg->ts_rate_decimator[0] = 2; - cfg->ts_rate_decimator[1] = 1; - memcpy(cfg->ts_layer_id, ids, sizeof(ids)); -#if 1 - // 0=L, 1=GF, Intra-layer prediction enabled. - layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF | - VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF | - VP8_EFLAG_NO_REF_ARF; - layer_flags[1] = - VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_REF_ARF; -#else - // 0=L, 1=GF, Intra-layer prediction disabled. - layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF | - VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF | - VP8_EFLAG_NO_REF_ARF; - layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | - VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_LAST; -#endif - break; - } - case 2: { - // 2-layers, 3-frame period. - int ids[3] = { 0, 1, 1 }; - cfg->ts_periodicity = 3; - *flag_periodicity = 3; - cfg->ts_number_layers = 2; - cfg->ts_rate_decimator[0] = 3; - cfg->ts_rate_decimator[1] = 1; - memcpy(cfg->ts_layer_id, ids, sizeof(ids)); - // 0=L, 1=GF, Intra-layer prediction enabled. - layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | - VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | - VP8_EFLAG_NO_UPD_ARF; - layer_flags[1] = layer_flags[2] = - VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF | - VP8_EFLAG_NO_UPD_LAST; - break; - } - case 3: { - // 3-layers, 6-frame period. - int ids[6] = { 0, 2, 2, 1, 2, 2 }; - cfg->ts_periodicity = 6; - *flag_periodicity = 6; - cfg->ts_number_layers = 3; - cfg->ts_rate_decimator[0] = 6; - cfg->ts_rate_decimator[1] = 3; - cfg->ts_rate_decimator[2] = 1; - memcpy(cfg->ts_layer_id, ids, sizeof(ids)); - // 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled. - layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | - VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | - VP8_EFLAG_NO_UPD_ARF; - layer_flags[3] = - VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; - layer_flags[1] = layer_flags[2] = layer_flags[4] = layer_flags[5] = - VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST; - break; - } - case 4: { - // 3-layers, 4-frame period. - int ids[4] = { 0, 2, 1, 2 }; - cfg->ts_periodicity = 4; - *flag_periodicity = 4; - cfg->ts_number_layers = 3; - cfg->ts_rate_decimator[0] = 4; - cfg->ts_rate_decimator[1] = 2; - cfg->ts_rate_decimator[2] = 1; - memcpy(cfg->ts_layer_id, ids, sizeof(ids)); - // 0=L, 1=GF, 2=ARF, Intra-layer prediction disabled. - layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | - VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | - VP8_EFLAG_NO_UPD_ARF; - layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | - VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; - layer_flags[1] = layer_flags[3] = - VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | - VP8_EFLAG_NO_UPD_ARF; - break; - } - case 5: { - // 3-layers, 4-frame period. - int ids[4] = { 0, 2, 1, 2 }; - cfg->ts_periodicity = 4; - *flag_periodicity = 4; - cfg->ts_number_layers = 3; - cfg->ts_rate_decimator[0] = 4; - cfg->ts_rate_decimator[1] = 2; - cfg->ts_rate_decimator[2] = 1; - memcpy(cfg->ts_layer_id, ids, sizeof(ids)); - // 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled in layer 1, disabled - // in layer 2. - layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | - VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | - VP8_EFLAG_NO_UPD_ARF; - layer_flags[2] = - VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF; - layer_flags[1] = layer_flags[3] = - VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | - VP8_EFLAG_NO_UPD_ARF; - break; - } - case 6: { - // 3-layers, 4-frame period. - int ids[4] = { 0, 2, 1, 2 }; - cfg->ts_periodicity = 4; - *flag_periodicity = 4; - cfg->ts_number_layers = 3; - cfg->ts_rate_decimator[0] = 4; - cfg->ts_rate_decimator[1] = 2; - cfg->ts_rate_decimator[2] = 1; - memcpy(cfg->ts_layer_id, ids, sizeof(ids)); - // 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled. - layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | - VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | - VP8_EFLAG_NO_UPD_ARF; - layer_flags[2] = - VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF; - layer_flags[1] = layer_flags[3] = - VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF; - break; - } - case 7: { - // NOTE: Probably of academic interest only. - // 5-layers, 16-frame period. - int ids[16] = { 0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4 }; - cfg->ts_periodicity = 16; - *flag_periodicity = 16; - cfg->ts_number_layers = 5; - cfg->ts_rate_decimator[0] = 16; - cfg->ts_rate_decimator[1] = 8; - cfg->ts_rate_decimator[2] = 4; - cfg->ts_rate_decimator[3] = 2; - cfg->ts_rate_decimator[4] = 1; - memcpy(cfg->ts_layer_id, ids, sizeof(ids)); - layer_flags[0] = VPX_EFLAG_FORCE_KF; - layer_flags[1] = layer_flags[3] = layer_flags[5] = layer_flags[7] = - layer_flags[9] = layer_flags[11] = layer_flags[13] = layer_flags[15] = - VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | - VP8_EFLAG_NO_UPD_ARF; - layer_flags[2] = layer_flags[6] = layer_flags[10] = layer_flags[14] = - VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_GF; - layer_flags[4] = layer_flags[12] = - VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_ARF; - layer_flags[8] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF; - break; - } - case 8: { - // 2-layers, with sync point at first frame of layer 1. - int ids[2] = { 0, 1 }; - cfg->ts_periodicity = 2; - *flag_periodicity = 8; - cfg->ts_number_layers = 2; - cfg->ts_rate_decimator[0] = 2; - cfg->ts_rate_decimator[1] = 1; - memcpy(cfg->ts_layer_id, ids, sizeof(ids)); - // 0=L, 1=GF. - // ARF is used as predictor for all frames, and is only updated on - // key frame. Sync point every 8 frames. - - // Layer 0: predict from L and ARF, update L and G. - layer_flags[0] = - VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF; - // Layer 1: sync point: predict from L and ARF, and update G. - layer_flags[1] = - VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF; - // Layer 0, predict from L and ARF, update L. - layer_flags[2] = - VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; - // Layer 1: predict from L, G and ARF, and update G. - layer_flags[3] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | - VP8_EFLAG_NO_UPD_ENTROPY; - // Layer 0. - layer_flags[4] = layer_flags[2]; - // Layer 1. - layer_flags[5] = layer_flags[3]; - // Layer 0. - layer_flags[6] = layer_flags[4]; - // Layer 1. - layer_flags[7] = layer_flags[5]; - break; - } - case 9: { - // 3-layers: Sync points for layer 1 and 2 every 8 frames. - int ids[4] = { 0, 2, 1, 2 }; - cfg->ts_periodicity = 4; - *flag_periodicity = 8; - cfg->ts_number_layers = 3; - cfg->ts_rate_decimator[0] = 4; - cfg->ts_rate_decimator[1] = 2; - cfg->ts_rate_decimator[2] = 1; - memcpy(cfg->ts_layer_id, ids, sizeof(ids)); - // 0=L, 1=GF, 2=ARF. - layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | - VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | - VP8_EFLAG_NO_UPD_ARF; - layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | - VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF; - layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | - VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF; - layer_flags[3] = layer_flags[5] = - VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF; - layer_flags[4] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | - VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; - layer_flags[6] = - VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF; - layer_flags[7] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | - VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_ENTROPY; - break; - } - case 10: { - // 3-layers structure where ARF is used as predictor for all frames, - // and is only updated on key frame. - // Sync points for layer 1 and 2 every 8 frames. - - int ids[4] = { 0, 2, 1, 2 }; - cfg->ts_periodicity = 4; - *flag_periodicity = 8; - cfg->ts_number_layers = 3; - cfg->ts_rate_decimator[0] = 4; - cfg->ts_rate_decimator[1] = 2; - cfg->ts_rate_decimator[2] = 1; - memcpy(cfg->ts_layer_id, ids, sizeof(ids)); - // 0=L, 1=GF, 2=ARF. - // Layer 0: predict from L and ARF; update L and G. - layer_flags[0] = - VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF; - // Layer 2: sync point: predict from L and ARF; update none. - layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | - VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | - VP8_EFLAG_NO_UPD_ENTROPY; - // Layer 1: sync point: predict from L and ARF; update G. - layer_flags[2] = - VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; - // Layer 2: predict from L, G, ARF; update none. - layer_flags[3] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | - VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY; - // Layer 0: predict from L and ARF; update L. - layer_flags[4] = - VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF; - // Layer 2: predict from L, G, ARF; update none. - layer_flags[5] = layer_flags[3]; - // Layer 1: predict from L, G, ARF; update G. - layer_flags[6] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; - // Layer 2: predict from L, G, ARF; update none. - layer_flags[7] = layer_flags[3]; - break; - } - case 11: { - // 3-layers structure with one reference frame. - // This works same as temporal_layering_mode 3. - // This was added to compare with vp9_spatial_svc_encoder. - - // 3-layers, 4-frame period. - int ids[4] = { 0, 2, 1, 2 }; - cfg->ts_periodicity = 4; - *flag_periodicity = 4; - cfg->ts_number_layers = 3; - cfg->ts_rate_decimator[0] = 4; - cfg->ts_rate_decimator[1] = 2; - cfg->ts_rate_decimator[2] = 1; - memcpy(cfg->ts_layer_id, ids, sizeof(ids)); - // 0=L, 1=GF, 2=ARF, Intra-layer prediction disabled. - layer_flags[0] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | - VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; - layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | - VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; - layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | - VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF; - layer_flags[3] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_ARF | - VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF; - break; - } - case 12: - default: { - // 3-layers structure as in case 10, but no sync/refresh points for - // layer 1 and 2. - int ids[4] = { 0, 2, 1, 2 }; - cfg->ts_periodicity = 4; - *flag_periodicity = 8; - cfg->ts_number_layers = 3; - cfg->ts_rate_decimator[0] = 4; - cfg->ts_rate_decimator[1] = 2; - cfg->ts_rate_decimator[2] = 1; - memcpy(cfg->ts_layer_id, ids, sizeof(ids)); - // 0=L, 1=GF, 2=ARF. - // Layer 0: predict from L and ARF; update L. - layer_flags[0] = - VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF; - layer_flags[4] = layer_flags[0]; - // Layer 1: predict from L, G, ARF; update G. - layer_flags[2] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; - layer_flags[6] = layer_flags[2]; - // Layer 2: predict from L, G, ARF; update none. - layer_flags[1] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | - VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY; - layer_flags[3] = layer_flags[1]; - layer_flags[5] = layer_flags[1]; - layer_flags[7] = layer_flags[1]; - break; - } - } -} - -#if ROI_MAP -static void read_mask(FILE *mask_file, int *seg_map) { - int mask_rows, mask_cols, i, j; - int *map_start = seg_map; - fscanf(mask_file, "%d %d\n", &mask_cols, &mask_rows); - for (i = 0; i < mask_rows; i++) { - for (j = 0; j < mask_cols; j++) { - fscanf(mask_file, "%d ", &seg_map[j]); - // reverse the bit - seg_map[j] = 1 - seg_map[j]; - } - seg_map += mask_cols; - } - seg_map = map_start; -} -#endif - -int main(int argc, char **argv) { - VpxVideoWriter *outfile[VPX_TS_MAX_LAYERS] = { NULL }; - vpx_codec_ctx_t codec; - vpx_codec_enc_cfg_t cfg; - int frame_cnt = 0; - vpx_image_t raw; - vpx_codec_err_t res; - unsigned int width; - unsigned int height; - uint32_t error_resilient = 0; - int speed; - int frame_avail; - int got_data; - int flags = 0; - unsigned int i; - int pts = 0; // PTS starts at 0. - int frame_duration = 1; // 1 timebase tick per frame. - int layering_mode = 0; - int layer_flags[VPX_TS_MAX_PERIODICITY] = { 0 }; - int flag_periodicity = 1; -#if ROI_MAP - vpx_roi_map_t roi; -#endif - vpx_svc_layer_id_t layer_id; - const VpxInterface *encoder = NULL; - struct VpxInputContext input_ctx; - struct RateControlMetrics rc; - int64_t cx_time = 0; - const int min_args_base = 13; -#if CONFIG_VP9_HIGHBITDEPTH - vpx_bit_depth_t bit_depth = VPX_BITS_8; - int input_bit_depth = 8; - const int min_args = min_args_base + 1; -#else - const int min_args = min_args_base; -#endif // CONFIG_VP9_HIGHBITDEPTH - double sum_bitrate = 0.0; - double sum_bitrate2 = 0.0; - double framerate = 30.0; -#if ROI_MAP - FILE *mask_file = NULL; - int block_size = 8; - int mask_rows = 0; - int mask_cols = 0; - int *mask_map; - int *prev_mask_map; -#endif - zero(rc.layer_target_bitrate); - memset(&layer_id, 0, sizeof(vpx_svc_layer_id_t)); - memset(&input_ctx, 0, sizeof(input_ctx)); - /* Setup default input stream settings */ - input_ctx.framerate.numerator = 30; - input_ctx.framerate.denominator = 1; - input_ctx.only_i420 = 1; - input_ctx.bit_depth = 0; - - exec_name = argv[0]; - // Check usage and arguments. - if (argc < min_args) { -#if CONFIG_VP9_HIGHBITDEPTH - die("Usage: %s " - " " - " " - " ... \n", - argv[0]); -#else - die("Usage: %s " - " " - " " - " ... \n", - argv[0]); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - - encoder = get_vpx_encoder_by_name(argv[3]); - if (!encoder) die("Unsupported codec."); - - printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface())); - - width = (unsigned int)strtoul(argv[4], NULL, 0); - height = (unsigned int)strtoul(argv[5], NULL, 0); - if (width < 16 || width % 2 || height < 16 || height % 2) { - die("Invalid resolution: %d x %d", width, height); - } - - layering_mode = (int)strtol(argv[12], NULL, 0); - if (layering_mode < 0 || layering_mode > 13) { - die("Invalid layering mode (0..12) %s", argv[12]); - } - -#if ROI_MAP - if (argc != min_args + mode_to_num_layers[layering_mode] + 1) { - die("Invalid number of arguments"); - } -#else - if (argc != min_args + mode_to_num_layers[layering_mode]) { - die("Invalid number of arguments"); - } -#endif - - input_ctx.filename = argv[1]; - open_input_file(&input_ctx); - -#if CONFIG_VP9_HIGHBITDEPTH - switch (strtol(argv[argc - 1], NULL, 0)) { - case 8: - bit_depth = VPX_BITS_8; - input_bit_depth = 8; - break; - case 10: - bit_depth = VPX_BITS_10; - input_bit_depth = 10; - break; - case 12: - bit_depth = VPX_BITS_12; - input_bit_depth = 12; - break; - default: die("Invalid bit depth (8, 10, 12) %s", argv[argc - 1]); - } - - // Y4M reader has its own allocation. - if (input_ctx.file_type != FILE_TYPE_Y4M) { - if (!vpx_img_alloc( - &raw, - bit_depth == VPX_BITS_8 ? VPX_IMG_FMT_I420 : VPX_IMG_FMT_I42016, - width, height, 32)) { - die("Failed to allocate image (%dx%d)", width, height); - } - } -#else - // Y4M reader has its own allocation. - if (input_ctx.file_type != FILE_TYPE_Y4M) { - if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 32)) { - die("Failed to allocate image (%dx%d)", width, height); - } - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - // Populate encoder configuration. - res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0); - if (res) { - printf("Failed to get config: %s\n", vpx_codec_err_to_string(res)); - return EXIT_FAILURE; - } - - // Update the default configuration with our settings. - cfg.g_w = width; - cfg.g_h = height; - -#if CONFIG_VP9_HIGHBITDEPTH - if (bit_depth != VPX_BITS_8) { - cfg.g_bit_depth = bit_depth; - cfg.g_input_bit_depth = input_bit_depth; - cfg.g_profile = 2; - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - // Timebase format e.g. 30fps: numerator=1, demoninator = 30. - cfg.g_timebase.num = (int)strtol(argv[6], NULL, 0); - cfg.g_timebase.den = (int)strtol(argv[7], NULL, 0); - - speed = (int)strtol(argv[8], NULL, 0); - if (speed < 0) { - die("Invalid speed setting: must be positive"); - } - if (strncmp(encoder->name, "vp9", 3) == 0 && speed > 9) { - warn("Mapping speed %d to speed 9.\n", speed); - } - - for (i = min_args_base; - (int)i < min_args_base + mode_to_num_layers[layering_mode]; ++i) { - rc.layer_target_bitrate[i - 13] = (int)strtol(argv[i], NULL, 0); - if (strncmp(encoder->name, "vp8", 3) == 0) - cfg.ts_target_bitrate[i - 13] = rc.layer_target_bitrate[i - 13]; - else if (strncmp(encoder->name, "vp9", 3) == 0) - cfg.layer_target_bitrate[i - 13] = rc.layer_target_bitrate[i - 13]; - } - - // Real time parameters. - cfg.rc_dropframe_thresh = (unsigned int)strtoul(argv[9], NULL, 0); - cfg.rc_end_usage = VPX_CBR; - cfg.rc_min_quantizer = 2; - cfg.rc_max_quantizer = 56; - if (strncmp(encoder->name, "vp9", 3) == 0) cfg.rc_max_quantizer = 52; - cfg.rc_undershoot_pct = 50; - cfg.rc_overshoot_pct = 50; - cfg.rc_buf_initial_sz = 600; - cfg.rc_buf_optimal_sz = 600; - cfg.rc_buf_sz = 1000; - - // Disable dynamic resizing by default. - cfg.rc_resize_allowed = 0; - - // Use 1 thread as default. - cfg.g_threads = (unsigned int)strtoul(argv[11], NULL, 0); - - error_resilient = (uint32_t)strtoul(argv[10], NULL, 0); - if (error_resilient != 0 && error_resilient != 1) { - die("Invalid value for error resilient (0, 1): %d.", error_resilient); - } - // Enable error resilient mode. - cfg.g_error_resilient = error_resilient; - cfg.g_lag_in_frames = 0; - cfg.kf_mode = VPX_KF_AUTO; - - // Disable automatic keyframe placement. - cfg.kf_min_dist = cfg.kf_max_dist = 3000; - - cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS; - - set_temporal_layer_pattern(layering_mode, &cfg, layer_flags, - &flag_periodicity); - - set_rate_control_metrics(&rc, &cfg); - - if (input_ctx.file_type == FILE_TYPE_Y4M) { - if (input_ctx.width != cfg.g_w || input_ctx.height != cfg.g_h) { - die("Incorrect width or height: %d x %d", cfg.g_w, cfg.g_h); - } - if (input_ctx.framerate.numerator != cfg.g_timebase.den || - input_ctx.framerate.denominator != cfg.g_timebase.num) { - die("Incorrect framerate: numerator %d denominator %d", - cfg.g_timebase.num, cfg.g_timebase.den); - } - } - - framerate = cfg.g_timebase.den / cfg.g_timebase.num; - // Open an output file for each stream. - for (i = 0; i < cfg.ts_number_layers; ++i) { - char file_name[PATH_MAX]; - VpxVideoInfo info; - info.codec_fourcc = encoder->fourcc; - info.frame_width = cfg.g_w; - info.frame_height = cfg.g_h; - info.time_base.numerator = cfg.g_timebase.num; - info.time_base.denominator = cfg.g_timebase.den; - - snprintf(file_name, sizeof(file_name), "%s_%d.ivf", argv[2], i); - outfile[i] = vpx_video_writer_open(file_name, kContainerIVF, &info); - if (!outfile[i]) die("Failed to open %s for writing", file_name); - - assert(outfile[i] != NULL); - } - // No spatial layers in this encoder. - cfg.ss_number_layers = 1; - -// Initialize codec. -#if CONFIG_VP9_HIGHBITDEPTH - if (vpx_codec_enc_init( - &codec, encoder->codec_interface(), &cfg, - bit_depth == VPX_BITS_8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH)) -#else - if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0)) -#endif // CONFIG_VP9_HIGHBITDEPTH - die("Failed to initialize encoder"); - -#if ROI_MAP - mask_rows = (cfg.g_h + block_size - 1) / block_size; - mask_cols = (cfg.g_w + block_size - 1) / block_size; - mask_map = (int *)calloc(mask_rows * mask_cols, sizeof(*mask_map)); - prev_mask_map = (int *)calloc(mask_rows * mask_cols, sizeof(*mask_map)); -#endif - - if (strncmp(encoder->name, "vp8", 3) == 0) { - vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed); - vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kVp8DenoiserOff); - vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1); - vpx_codec_control(&codec, VP8E_SET_GF_CBR_BOOST_PCT, 0); -#if ROI_MAP - set_roi_map(encoder->name, &cfg, &roi); - if (vpx_codec_control(&codec, VP8E_SET_ROI_MAP, &roi)) - die_codec(&codec, "Failed to set ROI map"); -#endif - } else if (strncmp(encoder->name, "vp9", 3) == 0) { - vpx_svc_extra_cfg_t svc_params; - memset(&svc_params, 0, sizeof(svc_params)); - vpx_codec_control(&codec, VP9E_SET_POSTENCODE_DROP, 0); - vpx_codec_control(&codec, VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, 0); - vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed); - vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3); - vpx_codec_control(&codec, VP9E_SET_GF_CBR_BOOST_PCT, 0); - vpx_codec_control(&codec, VP9E_SET_FRAME_PARALLEL_DECODING, 0); - vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0); - vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kVp9DenoiserOff); - vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1); - vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0); - vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, get_msb(cfg.g_threads)); - vpx_codec_control(&codec, VP9E_SET_DISABLE_LOOPFILTER, 0); - - if (cfg.g_threads > 1) - vpx_codec_control(&codec, VP9E_SET_ROW_MT, 1); - else - vpx_codec_control(&codec, VP9E_SET_ROW_MT, 0); - if (vpx_codec_control(&codec, VP9E_SET_SVC, layering_mode > 0 ? 1 : 0)) - die_codec(&codec, "Failed to set SVC"); - for (i = 0; i < cfg.ts_number_layers; ++i) { - svc_params.max_quantizers[i] = cfg.rc_max_quantizer; - svc_params.min_quantizers[i] = cfg.rc_min_quantizer; - } - svc_params.scaling_factor_num[0] = cfg.g_h; - svc_params.scaling_factor_den[0] = cfg.g_h; - vpx_codec_control(&codec, VP9E_SET_SVC_PARAMETERS, &svc_params); - } - if (strncmp(encoder->name, "vp8", 3) == 0) { - vpx_codec_control(&codec, VP8E_SET_SCREEN_CONTENT_MODE, 0); - } - vpx_codec_control(&codec, VP8E_SET_TOKEN_PARTITIONS, 1); - // This controls the maximum target size of the key frame. - // For generating smaller key frames, use a smaller max_intra_size_pct - // value, like 100 or 200. - { - const int max_intra_size_pct = 1000; - vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT, - max_intra_size_pct); - } - - frame_avail = 1; - while (frame_avail || got_data) { - struct vpx_usec_timer timer; - vpx_codec_iter_t iter = NULL; - const vpx_codec_cx_pkt_t *pkt; -#if ROI_MAP - char mask_file_name[255]; -#endif - // Update the temporal layer_id. No spatial layers in this test. - layer_id.spatial_layer_id = 0; - layer_id.temporal_layer_id = - cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity]; - layer_id.temporal_layer_id_per_spatial[0] = layer_id.temporal_layer_id; - if (strncmp(encoder->name, "vp9", 3) == 0) { - vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id); - } else if (strncmp(encoder->name, "vp8", 3) == 0) { - vpx_codec_control(&codec, VP8E_SET_TEMPORAL_LAYER_ID, - layer_id.temporal_layer_id); - } - flags = layer_flags[frame_cnt % flag_periodicity]; - if (layering_mode == 0) flags = 0; -#if ROI_MAP - snprintf(mask_file_name, sizeof(mask_file_name), "%s%05d.txt", - argv[argc - 1], frame_cnt); - mask_file = fopen(mask_file_name, "r"); - if (mask_file != NULL) { - read_mask(mask_file, mask_map); - fclose(mask_file); - // set_roi_map(encoder->name, &cfg, &roi); - set_roi_skip_map(&cfg, &roi, mask_map, prev_mask_map, frame_cnt); - if (vpx_codec_control(&codec, VP9E_SET_ROI_MAP, &roi)) - die_codec(&codec, "Failed to set ROI map"); - } -#endif - frame_avail = read_frame(&input_ctx, &raw); - if (frame_avail) ++rc.layer_input_frames[layer_id.temporal_layer_id]; - vpx_usec_timer_start(&timer); - if (vpx_codec_encode(&codec, frame_avail ? &raw : NULL, pts, 1, flags, - VPX_DL_REALTIME)) { - die_codec(&codec, "Failed to encode frame"); - } - vpx_usec_timer_mark(&timer); - cx_time += vpx_usec_timer_elapsed(&timer); - // Reset KF flag. - if (layering_mode != 7) { - layer_flags[0] &= ~VPX_EFLAG_FORCE_KF; - } - got_data = 0; - while ((pkt = vpx_codec_get_cx_data(&codec, &iter))) { - got_data = 1; - switch (pkt->kind) { - case VPX_CODEC_CX_FRAME_PKT: - for (i = cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity]; - i < cfg.ts_number_layers; ++i) { - vpx_video_writer_write_frame(outfile[i], pkt->data.frame.buf, - pkt->data.frame.sz, pts); - ++rc.layer_tot_enc_frames[i]; - rc.layer_encoding_bitrate[i] += 8.0 * pkt->data.frame.sz; - // Keep count of rate control stats per layer (for non-key frames). - if (i == cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity] && - !(pkt->data.frame.flags & VPX_FRAME_IS_KEY)) { - rc.layer_avg_frame_size[i] += 8.0 * pkt->data.frame.sz; - rc.layer_avg_rate_mismatch[i] += - fabs(8.0 * pkt->data.frame.sz - rc.layer_pfb[i]) / - rc.layer_pfb[i]; - ++rc.layer_enc_frames[i]; - } - } - // Update for short-time encoding bitrate states, for moving window - // of size rc->window, shifted by rc->window / 2. - // Ignore first window segment, due to key frame. - if (rc.window_size == 0) rc.window_size = 15; - if (frame_cnt > rc.window_size) { - sum_bitrate += 0.001 * 8.0 * pkt->data.frame.sz * framerate; - if (frame_cnt % rc.window_size == 0) { - rc.window_count += 1; - rc.avg_st_encoding_bitrate += sum_bitrate / rc.window_size; - rc.variance_st_encoding_bitrate += - (sum_bitrate / rc.window_size) * - (sum_bitrate / rc.window_size); - sum_bitrate = 0.0; - } - } - // Second shifted window. - if (frame_cnt > rc.window_size + rc.window_size / 2) { - sum_bitrate2 += 0.001 * 8.0 * pkt->data.frame.sz * framerate; - if (frame_cnt > 2 * rc.window_size && - frame_cnt % rc.window_size == 0) { - rc.window_count += 1; - rc.avg_st_encoding_bitrate += sum_bitrate2 / rc.window_size; - rc.variance_st_encoding_bitrate += - (sum_bitrate2 / rc.window_size) * - (sum_bitrate2 / rc.window_size); - sum_bitrate2 = 0.0; - } - } - break; - default: break; - } - } - ++frame_cnt; - pts += frame_duration; - } -#if ROI_MAP - free(mask_map); - free(prev_mask_map); -#endif - close_input_file(&input_ctx); - printout_rate_control_summary(&rc, &cfg, frame_cnt); - printf("\n"); - printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n", - frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000), - 1000000 * (double)frame_cnt / (double)cx_time); - - if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec"); - - // Try to rewrite the output file headers with the actual frame count. - for (i = 0; i < cfg.ts_number_layers; ++i) vpx_video_writer_close(outfile[i]); - - if (input_ctx.file_type != FILE_TYPE_Y4M) { - vpx_img_free(&raw); - } - -#if ROI_MAP - free(roi.roi_map); -#endif - return EXIT_SUCCESS; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/ivfdec.c b/presentation/src/main/cpp/third_party/libvpx/ivfdec.c deleted file mode 100644 index 3e179bc6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/ivfdec.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "vpx_ports/mem_ops.h" - -#include "./ivfdec.h" - -static const char *IVF_SIGNATURE = "DKIF"; - -static void fix_framerate(int *num, int *den) { - // Some versions of vpxenc used 1/(2*fps) for the timebase, so - // we can guess the framerate using only the timebase in this - // case. Other files would require reading ahead to guess the - // timebase, like we do for webm. - if (*den > 0 && *den < 1000000000 && *num > 0 && *num < 1000) { - // Correct for the factor of 2 applied to the timebase in the encoder. - if (*num & 1) - *den *= 2; - else - *num /= 2; - } else { - // Don't know FPS for sure, and don't have readahead code - // (yet?), so just default to 30fps. - *num = 30; - *den = 1; - } -} - -int file_is_ivf(struct VpxInputContext *input_ctx) { - char raw_hdr[32]; - int is_ivf = 0; - - if (fread(raw_hdr, 1, 32, input_ctx->file) == 32) { - if (memcmp(IVF_SIGNATURE, raw_hdr, 4) == 0) { - is_ivf = 1; - - if (mem_get_le16(raw_hdr + 4) != 0) { - fprintf(stderr, - "Error: Unrecognized IVF version! This file may not" - " decode properly."); - } - - input_ctx->fourcc = mem_get_le32(raw_hdr + 8); - input_ctx->width = mem_get_le16(raw_hdr + 12); - input_ctx->height = mem_get_le16(raw_hdr + 14); - input_ctx->framerate.numerator = mem_get_le32(raw_hdr + 16); - input_ctx->framerate.denominator = mem_get_le32(raw_hdr + 20); - fix_framerate(&input_ctx->framerate.numerator, - &input_ctx->framerate.denominator); - } - } - - if (!is_ivf) { - rewind(input_ctx->file); - input_ctx->detect.buf_read = 0; - } else { - input_ctx->detect.position = 4; - } - return is_ivf; -} - -int ivf_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read, - size_t *buffer_size) { - char raw_header[IVF_FRAME_HDR_SZ] = { 0 }; - size_t frame_size = 0; - - if (fread(raw_header, IVF_FRAME_HDR_SZ, 1, infile) != 1) { - if (!feof(infile)) warn("Failed to read frame size"); - } else { - frame_size = mem_get_le32(raw_header); - - if (frame_size > 256 * 1024 * 1024) { - warn("Read invalid frame size (%u)", (unsigned int)frame_size); - frame_size = 0; - } - - if (frame_size > *buffer_size) { - uint8_t *new_buffer = realloc(*buffer, 2 * frame_size); - - if (new_buffer) { - *buffer = new_buffer; - *buffer_size = 2 * frame_size; - } else { - warn("Failed to allocate compressed data buffer"); - frame_size = 0; - } - } - } - - if (!feof(infile)) { - if (fread(*buffer, 1, frame_size, infile) != frame_size) { - warn("Failed to read full frame"); - return 1; - } - - *bytes_read = frame_size; - return 0; - } - - return 1; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/ivfdec.h b/presentation/src/main/cpp/third_party/libvpx/ivfdec.h deleted file mode 100644 index 847cd79f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/ivfdec.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_IVFDEC_H_ -#define VPX_IVFDEC_H_ - -#include "./tools_common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int file_is_ivf(struct VpxInputContext *input); - -int ivf_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read, - size_t *buffer_size); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif // VPX_IVFDEC_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/ivfenc.c b/presentation/src/main/cpp/third_party/libvpx/ivfenc.c deleted file mode 100644 index 2e8e0428..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/ivfenc.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./ivfenc.h" - -#include "vpx/vpx_encoder.h" -#include "vpx_ports/mem_ops.h" - -void ivf_write_file_header_with_video_info(FILE *outfile, unsigned int fourcc, - int frame_cnt, int frame_width, - int frame_height, - vpx_rational_t timebase) { - char header[32]; - - header[0] = 'D'; - header[1] = 'K'; - header[2] = 'I'; - header[3] = 'F'; - mem_put_le16(header + 4, 0); // version - mem_put_le16(header + 6, 32); // header size - mem_put_le32(header + 8, fourcc); // fourcc - mem_put_le16(header + 12, frame_width); // width - mem_put_le16(header + 14, frame_height); // height - mem_put_le32(header + 16, timebase.den); // rate - mem_put_le32(header + 20, timebase.num); // scale - mem_put_le32(header + 24, frame_cnt); // length - mem_put_le32(header + 28, 0); // unused - - fwrite(header, 1, 32, outfile); -} - -void ivf_write_file_header(FILE *outfile, const struct vpx_codec_enc_cfg *cfg, - unsigned int fourcc, int frame_cnt) { - ivf_write_file_header_with_video_info(outfile, fourcc, frame_cnt, cfg->g_w, - cfg->g_h, cfg->g_timebase); -} - -void ivf_write_frame_header(FILE *outfile, int64_t pts, size_t frame_size) { - char header[12]; - - mem_put_le32(header, (int)frame_size); - mem_put_le32(header + 4, (int)(pts & 0xFFFFFFFF)); - mem_put_le32(header + 8, (int)(pts >> 32)); - fwrite(header, 1, 12, outfile); -} - -void ivf_write_frame_size(FILE *outfile, size_t frame_size) { - char header[4]; - - mem_put_le32(header, (int)frame_size); - fwrite(header, 1, 4, outfile); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/ivfenc.h b/presentation/src/main/cpp/third_party/libvpx/ivfenc.h deleted file mode 100644 index 27b69108..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/ivfenc.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_IVFENC_H_ -#define VPX_IVFENC_H_ - -#include "./tools_common.h" - -#include "vpx/vpx_encoder.h" - -struct vpx_codec_enc_cfg; -struct vpx_codec_cx_pkt; - -#ifdef __cplusplus -extern "C" { -#endif - -void ivf_write_file_header_with_video_info(FILE *outfile, unsigned int fourcc, - int frame_cnt, int frame_width, - int frame_height, - vpx_rational_t timebase); - -void ivf_write_file_header(FILE *outfile, const struct vpx_codec_enc_cfg *cfg, - uint32_t fourcc, int frame_cnt); - -void ivf_write_frame_header(FILE *outfile, int64_t pts, size_t frame_size); - -void ivf_write_frame_size(FILE *outfile, size_t frame_size); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif // VPX_IVFENC_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/keywords.dox b/presentation/src/main/cpp/third_party/libvpx/keywords.dox deleted file mode 100644 index 56f53689..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/keywords.dox +++ /dev/null @@ -1,51 +0,0 @@ -/*!\page rfc2119 RFC2119 Keywords - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL - NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and - "OPTIONAL" in this document are to be interpreted as described in - RFC 2119. - -Specifically, the following definitions are used: - -\section MUST -\anchor REQUIRED -\anchor SHALL - This word, or the terms "REQUIRED" or "SHALL", mean that the - definition is an absolute requirement of the specification. - -\section MUSTNOT MUST NOT -\anchor SHALLNOT - This phrase, or the phrase "SHALL NOT", mean that the - definition is an absolute prohibition of the specification. - -\section SHOULD -\anchor RECOMMENDED - This word, or the adjective "RECOMMENDED", mean that there - may exist valid reasons in particular circumstances to ignore a - particular item, but the full implications must be understood and - carefully weighed before choosing a different course. - -\section SHOULDNOT SHOULD NOT -\anchor NOTRECOMMENDED - This phrase, or the phrase "NOT RECOMMENDED" mean that - there may exist valid reasons in particular circumstances when the - particular behavior is acceptable or even useful, but the full - implications should be understood and the case carefully weighed - before implementing any behavior described with this label. - -\section MAY -\anchor OPTIONAL - This word, or the adjective "OPTIONAL", mean that an item is - truly optional. One vendor may choose to include the item because a - particular marketplace requires it or because the vendor feels that - it enhances the product while another vendor may omit the same item. - An implementation which does not include a particular option \ref MUST be - prepared to interoperate with another implementation which does - include the option, though perhaps with reduced functionality. In the - same vein an implementation which does include a particular option - \ref MUST be prepared to interoperate with another implementation which - does not include the option (except, of course, for the feature the - option provides.) - - -*/ diff --git a/presentation/src/main/cpp/third_party/libvpx/libs.doxy_template b/presentation/src/main/cpp/third_party/libvpx/libs.doxy_template deleted file mode 100644 index 6d05162d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/libs.doxy_template +++ /dev/null @@ -1,1252 +0,0 @@ -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - - -# Doxyfile 1.5.4 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file that -# follow. The default is UTF-8 which is also the encoding used for all text before -# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into -# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of -# possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = "WebM Codec SDK" - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = docs - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, -# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, -# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, -# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to java_doc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a java_doc-style -# comment as the brief description. If set to NO, the java_doc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for Java. -# For instance, namespaces will be presented as packages, qualified scopes -# will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to -# include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the defqault) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct (or union) is -# documented as struct with the name of the typedef. So -# typedef struct type_s {} type_t, will appear in the documentation as a struct -# with name type_t. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named type_s. This can typically -# be useful for C code where the coding convention is that all structs are -# typedef'ed and only the typedef is referenced never the struct's name. - -TYPEDEF_HIDES_STRUCT = NO - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be extracted -# and appear in the documentation as a namespace called 'anonymous_namespace{file}', -# where file will be replaced with the base name of the file that contains the anonymous -# namespace. By default anonymous namespace are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = NO - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from the -# version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = YES - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = - -# This tag can be used to specify the character encoding of the source files that -# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default -# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. -# See http://www.gnu.org/software/libiconv for the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the output. -# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, -# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH -# then you must also enable this option. If you don't then doxygen will produce -# a warning and turn it on anyway - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentstion. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# java_script and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# java_script, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the la_te_x output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = YES - -# The LATEX_OUTPUT tag is used to specify where the la_te_x docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the la_te_x command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for la_te_x. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# la_te_x documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = YES - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = letter - -# The EXTRA_PACKAGES tag can be to specify one or more names of la_te_x -# packages that should be included in the la_te_x output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal la_te_x header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the la_te_x that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated la_te_x files. This will instruct la_te_x to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the auto_gen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an auto_gen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and la_te_x code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = YES - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = *.h - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# If the CLASS_GRAPH tag is set to YES (or GRAPH) then doxygen will generate a -# graph for each documented class showing the direct and indirect inheritance -# relations. In case HAVE_DOT is set as well dot will be used to draw the graph, -# otherwise the built-in generator will be used. If the CLASS_GRAPH tag is set -# to TEXT the direct and indirect inheritance relations will be shown as texts / -# links. -# Possible values are: NO, YES, TEXT and GRAPH. -# The default value is: YES. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will -# generate a call dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will -# generate a caller dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable caller graphs for selected -# functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the number -# of direct children of the root node in a graph is already larger than -# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO diff --git a/presentation/src/main/cpp/third_party/libvpx/libs.mk b/presentation/src/main/cpp/third_party/libvpx/libs.mk deleted file mode 100644 index 4a28b115..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/libs.mk +++ /dev/null @@ -1,801 +0,0 @@ -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - - -# ARM assembly files are written in RVCT-style. We use some make magic to -# filter those files to allow GCC compilation -ifeq ($(VPX_ARCH_ARM),yes) - ASM:=$(if $(filter yes,$(CONFIG_GCC)$(CONFIG_MSVS)),.asm.S,.asm) -else - ASM:=.asm -endif - -# -# Rule to generate runtime cpu detection files -# -define rtcd_h_template -$$(BUILD_PFX)$(1).h: $$(SRC_PATH_BARE)/$(2) - @echo " [CREATE] $$@" - $$(qexec)$$(SRC_PATH_BARE)/build/make/rtcd.pl --arch=$$(TGT_ISA) \ - --sym=$(1) \ - --config=$$(CONFIG_DIR)$$(target)-$$(TOOLCHAIN).mk \ - $$(RTCD_OPTIONS) $$^ > $$@ -CLEAN-OBJS += $$(BUILD_PFX)$(1).h -RTCD += $$(BUILD_PFX)$(1).h -endef - -CODEC_SRCS-yes += CHANGELOG -CODEC_SRCS-yes += libs.mk - -include $(SRC_PATH_BARE)/vpx/vpx_codec.mk -CODEC_SRCS-yes += $(addprefix vpx/,$(call enabled,API_SRCS)) -CODEC_DOC_SRCS += $(addprefix vpx/,$(call enabled,API_DOC_SRCS)) - -include $(SRC_PATH_BARE)/vpx_mem/vpx_mem.mk -CODEC_SRCS-yes += $(addprefix vpx_mem/,$(call enabled,MEM_SRCS)) - -include $(SRC_PATH_BARE)/vpx_scale/vpx_scale.mk -CODEC_SRCS-yes += $(addprefix vpx_scale/,$(call enabled,SCALE_SRCS)) - -include $(SRC_PATH_BARE)/vpx_ports/vpx_ports.mk -CODEC_SRCS-yes += $(addprefix vpx_ports/,$(call enabled,PORTS_SRCS)) - -include $(SRC_PATH_BARE)/vpx_dsp/vpx_dsp.mk -CODEC_SRCS-yes += $(addprefix vpx_dsp/,$(call enabled,DSP_SRCS)) - -include $(SRC_PATH_BARE)/vpx_util/vpx_util.mk -CODEC_SRCS-yes += $(addprefix vpx_util/,$(call enabled,UTIL_SRCS)) - -ifeq ($(CONFIG_VP8),yes) - VP8_PREFIX=vp8/ - include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8_common.mk -endif - -ifeq ($(CONFIG_VP8_ENCODER),yes) - include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8cx.mk - CODEC_SRCS-yes += $(addprefix $(VP8_PREFIX),$(call enabled,VP8_CX_SRCS)) - CODEC_EXPORTS-yes += $(addprefix $(VP8_PREFIX),$(VP8_CX_EXPORTS)) - INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8cx.h - INSTALL-LIBS-yes += include/vpx/vpx_ext_ratectrl.h - INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP8_PREFIX)/% - CODEC_DOC_SECTIONS += vp8 vp8_encoder -endif - -ifeq ($(CONFIG_VP8_DECODER),yes) - include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8dx.mk - CODEC_SRCS-yes += $(addprefix $(VP8_PREFIX),$(call enabled,VP8_DX_SRCS)) - CODEC_EXPORTS-yes += $(addprefix $(VP8_PREFIX),$(VP8_DX_EXPORTS)) - INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8dx.h - INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP8_PREFIX)/% - CODEC_DOC_SECTIONS += vp8 vp8_decoder -endif - -ifeq ($(CONFIG_VP9),yes) - VP9_PREFIX=vp9/ - include $(SRC_PATH_BARE)/$(VP9_PREFIX)vp9_common.mk -endif - -ifeq ($(CONFIG_VP9_ENCODER),yes) - VP9_PREFIX=vp9/ - include $(SRC_PATH_BARE)/$(VP9_PREFIX)vp9cx.mk - CODEC_SRCS-yes += $(addprefix $(VP9_PREFIX),$(call enabled,VP9_CX_SRCS)) - CODEC_EXPORTS-yes += $(addprefix $(VP9_PREFIX),$(VP9_CX_EXPORTS)) - CODEC_SRCS-yes += $(VP9_PREFIX)vp9cx.mk vpx/vp8.h vpx/vp8cx.h - CODEC_SRCS-yes += vpx/vpx_ext_ratectrl.h - INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8cx.h - INSTALL-LIBS-yes += include/vpx/vpx_ext_ratectrl.h - INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP9_PREFIX)/% - CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8cx.h vpx/vpx_ext_ratectrl.h - CODEC_DOC_SECTIONS += vp9 vp9_encoder -endif - -RC_RTC_SRCS := vpx/vp8.h vpx/vp8cx.h -RC_RTC_SRCS += vpx/vpx_ext_ratectrl.h -RC_RTC_SRCS += vpx/internal/vpx_ratectrl_rtc.h -ifeq ($(CONFIG_VP9_ENCODER),yes) - VP9_PREFIX=vp9/ - RC_RTC_SRCS += $(addprefix $(VP9_PREFIX),$(call enabled,VP9_CX_SRCS)) - RC_RTC_SRCS += $(VP9_PREFIX)vp9cx.mk - RC_RTC_SRCS += $(VP9_PREFIX)ratectrl_rtc.cc - RC_RTC_SRCS += $(VP9_PREFIX)ratectrl_rtc.h - INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(VP9_PREFIX)ratectrl_rtc.cc - INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(VP9_PREFIX)ratectrl_rtc.h -endif -ifeq ($(CONFIG_VP8_ENCODER),yes) - VP8_PREFIX=vp8/ - RC_RTC_SRCS += $(addprefix $(VP8_PREFIX),$(call enabled,VP8_CX_SRCS)) - RC_RTC_SRCS += $(VP8_PREFIX)vp8_ratectrl_rtc.cc - RC_RTC_SRCS += $(VP8_PREFIX)vp8_ratectrl_rtc.h - INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(VP8_PREFIX)vp8_ratectrl_rtc.cc - INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(VP8_PREFIX)vp8_ratectrl_rtc.h -endif - -ifeq ($(CONFIG_VP9_DECODER),yes) - VP9_PREFIX=vp9/ - include $(SRC_PATH_BARE)/$(VP9_PREFIX)vp9dx.mk - CODEC_SRCS-yes += $(addprefix $(VP9_PREFIX),$(call enabled,VP9_DX_SRCS)) - CODEC_EXPORTS-yes += $(addprefix $(VP9_PREFIX),$(VP9_DX_EXPORTS)) - CODEC_SRCS-yes += $(VP9_PREFIX)vp9dx.mk vpx/vp8.h vpx/vp8dx.h - INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8dx.h - INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP9_PREFIX)/% - CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8dx.h - CODEC_DOC_SECTIONS += vp9 vp9_decoder -endif - -ifeq ($(CONFIG_ENCODERS),yes) - CODEC_DOC_SECTIONS += encoder -endif -ifeq ($(CONFIG_DECODERS),yes) - CODEC_DOC_SECTIONS += decoder -endif - -ifeq ($(CONFIG_MSVS),yes) -CODEC_LIB=$(if $(CONFIG_STATIC_MSVCRT),vpxmt,vpxmd) -GTEST_LIB=$(if $(CONFIG_STATIC_MSVCRT),gtestmt,gtestmd) -RC_RTC_LIB=$(if $(CONFIG_STATIC_MSVCRT),vpxrcmt,vpxrcmd) -# This variable uses deferred expansion intentionally, since the results of -# $(wildcard) may change during the course of the Make. -VS_PLATFORMS = $(foreach d,$(wildcard */Release/$(CODEC_LIB).lib),$(word 1,$(subst /, ,$(d)))) -endif - -# The following pairs define a mapping of locations in the distribution -# tree to locations in the source/build trees. -INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/vpx/% -INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/vpx_ports/% -INSTALL_MAPS += $(LIBSUBDIR)/% % -INSTALL_MAPS += src/% $(SRC_PATH_BARE)/% -ifeq ($(CONFIG_MSVS),yes) -INSTALL_MAPS += $(foreach p,$(VS_PLATFORMS),$(LIBSUBDIR)/$(p)/% $(p)/Release/%) -INSTALL_MAPS += $(foreach p,$(VS_PLATFORMS),$(LIBSUBDIR)/$(p)/% $(p)/Debug/%) -endif - -CODEC_SRCS-yes += build/make/version.sh -CODEC_SRCS-yes += build/make/rtcd.pl -CODEC_SRCS-yes += vpx_ports/emmintrin_compat.h -CODEC_SRCS-yes += vpx_ports/mem_ops.h -CODEC_SRCS-yes += vpx_ports/mem_ops_aligned.h -CODEC_SRCS-yes += vpx_ports/vpx_once.h -CODEC_SRCS-yes += $(BUILD_PFX)vpx_config.c -INSTALL-SRCS-no += $(BUILD_PFX)vpx_config.c -ifeq ($(VPX_ARCH_X86)$(VPX_ARCH_X86_64),yes) -INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += third_party/x86inc/x86inc.asm -INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += vpx_dsp/x86/bitdepth_conversion_sse2.asm -endif -CODEC_EXPORTS-yes += vpx/exports_com -CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_enc -CODEC_EXPORTS-$(CONFIG_DECODERS) += vpx/exports_dec - -INSTALL-LIBS-yes += include/vpx/vpx_codec.h -INSTALL-LIBS-yes += include/vpx/vpx_frame_buffer.h -INSTALL-LIBS-yes += include/vpx/vpx_image.h -INSTALL-LIBS-yes += include/vpx/vpx_integer.h -INSTALL-LIBS-$(CONFIG_DECODERS) += include/vpx/vpx_decoder.h -INSTALL-LIBS-$(CONFIG_ENCODERS) += include/vpx/vpx_encoder.h -INSTALL-LIBS-$(CONFIG_ENCODERS) += include/vpx/vpx_tpl.h -ifeq ($(CONFIG_EXTERNAL_BUILD),yes) -ifeq ($(CONFIG_MSVS),yes) -INSTALL-LIBS-yes += $(foreach p,$(VS_PLATFORMS),$(LIBSUBDIR)/$(p)/$(CODEC_LIB).lib) -INSTALL-LIBS-$(CONFIG_DEBUG_LIBS) += $(foreach p,$(VS_PLATFORMS),$(LIBSUBDIR)/$(p)/$(CODEC_LIB)d.lib) -INSTALL-LIBS-$(CONFIG_SHARED) += $(foreach p,$(VS_PLATFORMS),$(LIBSUBDIR)/$(p)/vpx.dll) -INSTALL-LIBS-$(CONFIG_SHARED) += $(foreach p,$(VS_PLATFORMS),$(LIBSUBDIR)/$(p)/vpx.exp) -endif -else -INSTALL-LIBS-$(CONFIG_STATIC) += $(LIBSUBDIR)/libvpx.a -INSTALL-LIBS-$(CONFIG_DEBUG_LIBS) += $(LIBSUBDIR)/libvpx_g.a -endif - -ifeq ($(CONFIG_VP9_ENCODER)$(CONFIG_RATE_CTRL),yesyes) - SIMPLE_ENCODE_SRCS := $(call enabled,CODEC_SRCS) - SIMPLE_ENCODE_SRCS += $(VP9_PREFIX)simple_encode.cc - SIMPLE_ENCODE_SRCS += $(VP9_PREFIX)simple_encode.h - SIMPLE_ENCODE_SRCS += ivfenc.h - SIMPLE_ENCODE_SRCS += ivfenc.c - INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(VP9_PREFIX)simple_encode.cc - INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(VP9_PREFIX)simple_encode.h -endif - -CODEC_SRCS=$(call enabled,CODEC_SRCS) - -INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(CODEC_SRCS) -INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(call enabled,CODEC_EXPORTS) - - -# Generate a list of all enabled sources, in particular for exporting to gyp -# based build systems. -libvpx_srcs.txt: - @echo " [CREATE] $@" - @echo $(CODEC_SRCS) | xargs -n1 echo | LC_ALL=C sort -u > $@ -CLEAN-OBJS += libvpx_srcs.txt - -# Assembly files that are included, but don't define symbols themselves. -# Filtered out to avoid Windows build warnings. -ASM_INCLUDES := \ - third_party/x86inc/x86inc.asm \ - vpx_config.asm \ - vpx_ports/x86_abi_support.asm \ - vpx_dsp/x86/bitdepth_conversion_sse2.asm \ - -ifeq ($(CONFIG_EXTERNAL_BUILD),yes) -ifeq ($(CONFIG_MSVS),yes) - -vpx.def: $(call enabled,CODEC_EXPORTS) - @echo " [CREATE] $@" - $(qexec)$(SRC_PATH_BARE)/build/make/gen_msvs_def.sh\ - --name=vpx\ - --out=$@ $^ -CLEAN-OBJS += vpx.def - -vpx.$(VCPROJ_SFX): VCPROJ_SRCS=$(filter-out $(addprefix %, $(ASM_INCLUDES)), $^) - -vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def - @echo " [CREATE] $@" - $(qexec)$(GEN_VCPROJ) \ - $(if $(CONFIG_SHARED),--dll,--lib) \ - --target=$(TOOLCHAIN) \ - $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \ - --name=vpx \ - --proj-guid=DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74 \ - --module-def=vpx.def \ - --ver=$(CONFIG_VS_VERSION) \ - --src-path-bare="$(SRC_PATH_BARE)" \ - --out=$@ $(CFLAGS) \ - --as=$(AS) \ - $(filter $(SRC_PATH_BARE)/vp8/%.c, $(VCPROJ_SRCS)) \ - $(filter $(SRC_PATH_BARE)/vp8/%.h, $(VCPROJ_SRCS)) \ - $(filter $(SRC_PATH_BARE)/vp9/%.c, $(VCPROJ_SRCS)) \ - $(filter $(SRC_PATH_BARE)/vp9/%.h, $(VCPROJ_SRCS)) \ - $(filter $(SRC_PATH_BARE)/vpx/%, $(VCPROJ_SRCS)) \ - $(filter $(SRC_PATH_BARE)/vpx_dsp/%, $(VCPROJ_SRCS)) \ - $(filter-out $(addprefix $(SRC_PATH_BARE)/, \ - vp8/%.c vp8/%.h vp9/%.c vp9/%.h vpx/% vpx_dsp/%), \ - $(VCPROJ_SRCS)) \ - --src-path-bare="$(SRC_PATH_BARE)" \ - -PROJECTS-yes += vpx.$(VCPROJ_SFX) - -vpx.$(VCPROJ_SFX): vpx_config.asm -vpx.$(VCPROJ_SFX): $(RTCD) - -vpxrc.$(VCPROJ_SFX): \ - VCPROJ_SRCS=$(filter-out $(addprefix %, $(ASM_INCLUDES)), $^) - -vpxrc.$(VCPROJ_SFX): $(RC_RTC_SRCS) - @echo " [CREATE] $@" - $(qexec)$(GEN_VCPROJ) \ - $(if $(CONFIG_SHARED),--dll,--lib) \ - --target=$(TOOLCHAIN) \ - $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \ - --name=vpxrc \ - --proj-guid=C26FF952-9494-4838-9A3F-7F3D4F613385 \ - --ver=$(CONFIG_VS_VERSION) \ - --src-path-bare="$(SRC_PATH_BARE)" \ - --out=$@ $(CFLAGS) \ - --as=$(AS) \ - $(filter $(SRC_PATH_BARE)/vp9/%.c, $(VCPROJ_SRCS)) \ - $(filter $(SRC_PATH_BARE)/vp9/%.cc, $(VCPROJ_SRCS)) \ - $(filter $(SRC_PATH_BARE)/vp9/%.h, $(VCPROJ_SRCS)) \ - $(filter $(SRC_PATH_BARE)/vpx/%, $(VCPROJ_SRCS)) \ - $(filter $(SRC_PATH_BARE)/vpx_dsp/%, $(VCPROJ_SRCS)) \ - $(filter-out $(addprefix $(SRC_PATH_BARE)/, \ - vp8/%.c vp8/%.h vp9/%.c vp9/%.cc vp9/%.h vpx/% \ - vpx_dsp/%), \ - $(VCPROJ_SRCS)) \ - --src-path-bare="$(SRC_PATH_BARE)" \ - -PROJECTS-yes += vpxrc.$(VCPROJ_SFX) - -vpxrc.$(VCPROJ_SFX): vpx_config.asm -vpxrc.$(VCPROJ_SFX): $(RTCD) - -endif # ifeq ($(CONFIG_MSVS),yes) -else # ifeq ($(CONFIG_EXTERNAL_BUILD),yes) -LIBVPX_OBJS=$(call objs, $(filter-out $(ASM_INCLUDES), $(CODEC_SRCS))) -OBJS-yes += $(LIBVPX_OBJS) -LIBS-$(if yes,$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a -$(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS) - -# Updating version info. -# https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info -# For libtool: c=, a=, r= -# libtool generates .so file as .so.[c-a].a.r, while -version-info c:r:a is -# passed to libtool. -# -# libvpx library file is generated as libvpx.so... -# MAJOR = c-a, MINOR = a, PATCH = r -# -# To determine SO_VERSION_{MAJOR,MINOR,PATCH}, calculate c,a,r with current -# SO_VERSION_* then follow the rules in the link to detemine the new version -# (c1, a1, r1) and set MAJOR to [c1-a1], MINOR to a1 and PATCH to r1 -SO_VERSION_MAJOR := 11 -SO_VERSION_MINOR := 0 -SO_VERSION_PATCH := 1 -ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS)) -LIBVPX_SO := libvpx.$(SO_VERSION_MAJOR).dylib -SHARED_LIB_SUF := .dylib -EXPORT_FILE := libvpx.syms -LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, \ - libvpx.dylib ) -else -ifeq ($(filter iphonesimulator%,$(TGT_OS)),$(TGT_OS)) -LIBVPX_SO := libvpx.$(SO_VERSION_MAJOR).dylib -SHARED_LIB_SUF := .dylib -EXPORT_FILE := libvpx.syms -LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, libvpx.dylib) -else -ifeq ($(filter os2%,$(TGT_OS)),$(TGT_OS)) -LIBVPX_SO := libvpx$(SO_VERSION_MAJOR).dll -SHARED_LIB_SUF := _dll.a -EXPORT_FILE := libvpx.def -LIBVPX_SO_SYMLINKS := -LIBVPX_SO_IMPLIB := libvpx_dll.a -else -LIBVPX_SO := libvpx.so.$(SO_VERSION_MAJOR).$(SO_VERSION_MINOR).$(SO_VERSION_PATCH) -SHARED_LIB_SUF := .so -EXPORT_FILE := libvpx.ver -LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, \ - libvpx.so libvpx.so.$(SO_VERSION_MAJOR) \ - libvpx.so.$(SO_VERSION_MAJOR).$(SO_VERSION_MINOR)) -endif -endif -endif - -LIBS-$(CONFIG_SHARED) += $(BUILD_PFX)$(LIBVPX_SO)\ - $(notdir $(LIBVPX_SO_SYMLINKS)) \ - $(if $(LIBVPX_SO_IMPLIB), $(BUILD_PFX)$(LIBVPX_SO_IMPLIB)) -$(BUILD_PFX)$(LIBVPX_SO): $(LIBVPX_OBJS) $(EXPORT_FILE) -$(BUILD_PFX)$(LIBVPX_SO): extralibs += -lm -$(BUILD_PFX)$(LIBVPX_SO): SONAME = libvpx.so.$(SO_VERSION_MAJOR) -$(BUILD_PFX)$(LIBVPX_SO): EXPORTS_FILE = $(EXPORT_FILE) - -libvpx.def: $(call enabled,CODEC_EXPORTS) - @echo " [CREATE] $@" - $(qexec)echo LIBRARY $(LIBVPX_SO:.dll=) INITINSTANCE TERMINSTANCE > $@ - $(qexec)echo "DATA MULTIPLE NONSHARED" >> $@ - $(qexec)echo "EXPORTS" >> $@ - $(qexec)awk '!/vpx_svc_*/ {print "_"$$2}' $^ >>$@ -CLEAN-OBJS += libvpx.def - -libvpx_dll.a: $(LIBVPX_SO) - @echo " [IMPLIB] $@" - $(qexec)emximp -o $@ $< -CLEAN-OBJS += libvpx_dll.a - -define libvpx_symlink_template -$(1): $(2) - @echo " [LN] $(2) $$@" - $(qexec)mkdir -p $$(dir $$@) - $(qexec)ln -sf $(2) $$@ -endef - -$(eval $(call libvpx_symlink_template,\ - $(addprefix $(BUILD_PFX),$(notdir $(LIBVPX_SO_SYMLINKS))),\ - $(BUILD_PFX)$(LIBVPX_SO))) -$(eval $(call libvpx_symlink_template,\ - $(addprefix $(DIST_DIR)/,$(LIBVPX_SO_SYMLINKS)),\ - $(LIBVPX_SO))) - - -INSTALL-LIBS-$(CONFIG_SHARED) += $(LIBVPX_SO_SYMLINKS) -INSTALL-LIBS-$(CONFIG_SHARED) += $(LIBSUBDIR)/$(LIBVPX_SO) -INSTALL-LIBS-$(CONFIG_SHARED) += $(if $(LIBVPX_SO_IMPLIB),$(LIBSUBDIR)/$(LIBVPX_SO_IMPLIB)) - - -LIBS-yes += vpx.pc -vpx.pc: config.mk libs.mk - @echo " [CREATE] $@" - $(qexec)echo '# pkg-config file from libvpx $(VERSION_STRING)' > $@ - $(qexec)echo 'prefix=$(PREFIX)' >> $@ - $(qexec)echo 'exec_prefix=$${prefix}' >> $@ - $(qexec)echo 'libdir=$${prefix}/$(LIBSUBDIR)' >> $@ - $(qexec)echo 'includedir=$${prefix}/include' >> $@ - $(qexec)echo '' >> $@ - $(qexec)echo 'Name: vpx' >> $@ - $(qexec)echo 'Description: WebM Project VPx codec implementation' >> $@ - $(qexec)echo 'Version: $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)' >> $@ - $(qexec)echo 'Requires:' >> $@ - $(qexec)echo 'Conflicts:' >> $@ - $(qexec)echo 'Libs: -L$${libdir} -lvpx -lm' >> $@ -ifeq ($(HAVE_PTHREAD_H),yes) - $(qexec)echo 'Libs.private: -lm -lpthread' >> $@ -else - $(qexec)echo 'Libs.private: -lm' >> $@ -endif - $(qexec)echo 'Cflags: -I$${includedir}' >> $@ -INSTALL-LIBS-yes += $(LIBSUBDIR)/pkgconfig/vpx.pc -INSTALL_MAPS += $(LIBSUBDIR)/pkgconfig/%.pc %.pc -CLEAN-OBJS += vpx.pc - -ifeq ($(CONFIG_ENCODERS),yes) - RC_RTC_OBJS=$(call objs,$(RC_RTC_SRCS)) - OBJS-yes += $(RC_RTC_OBJS) - LIBS-yes += $(BUILD_PFX)libvpxrc.a $(BUILD_PFX)libvpxrc_g.a - $(BUILD_PFX)libvpxrc_g.a: $(RC_RTC_OBJS) -endif - -ifeq ($(CONFIG_VP9_ENCODER)$(CONFIG_RATE_CTRL),yesyes) - SIMPLE_ENCODE_OBJS=$(call objs,$(SIMPLE_ENCODE_SRCS)) - OBJS-yes += $(SIMPLE_ENCODE_OBJS) - LIBS-yes += $(BUILD_PFX)libsimple_encode.a $(BUILD_PFX)libsimple_encode_g.a - $(BUILD_PFX)libsimple_encode_g.a: $(SIMPLE_ENCODE_OBJS) -endif - -endif # ifeq ($(CONFIG_EXTERNAL_BUILD),yes) - -libvpx.ver: $(call enabled,CODEC_EXPORTS) - @echo " [CREATE] $@" - $(qexec)echo "{ global:" > $@ - $(qexec)for f in $?; do awk '{print $$2";"}' < $$f >>$@; done - $(qexec)echo "local: *; };" >> $@ -CLEAN-OBJS += libvpx.ver - -libvpx.syms: $(call enabled,CODEC_EXPORTS) - @echo " [CREATE] $@" - $(qexec)awk '{print "_"$$2}' $^ >$@ -CLEAN-OBJS += libvpx.syms - -# -# Rule to make assembler configuration file from C configuration file -# -ifeq ($(VPX_ARCH_X86)$(VPX_ARCH_X86_64),yes) -# YASM -$(BUILD_PFX)vpx_config.asm: $(BUILD_PFX)vpx_config.h - @echo " [CREATE] $@" - @LC_ALL=C grep -E "#define [A-Z0-9_]+ [01]" $< \ - | awk '{print $$2 " equ " $$3}' > $@ -else -ADS2GAS=$(if $(filter yes,$(CONFIG_GCC)),| $(ASM_CONVERSION)) -$(BUILD_PFX)vpx_config.asm: $(BUILD_PFX)vpx_config.h - @echo " [CREATE] $@" - @LC_ALL=C grep -E "#define [A-Z0-9_]+ [01]" $< \ - | awk '{print $$2 " EQU " $$3}' $(ADS2GAS) > $@ - @echo " END" $(ADS2GAS) >> $@ -CLEAN-OBJS += $(BUILD_PFX)vpx_config.asm -endif - -# -# Add assembler dependencies for configuration. -# -$(filter %.S.o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm -$(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm - - -$(shell $(SRC_PATH_BARE)/build/make/version.sh "$(SRC_PATH_BARE)" $(BUILD_PFX)vpx_version.h) -CLEAN-OBJS += $(BUILD_PFX)vpx_version.h - -# -# Add include path for libwebm sources. -# -ifeq ($(CONFIG_WEBM_IO),yes) - CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/libwebm -endif - -## -## libvpx test directives -## -ifeq ($(CONFIG_UNIT_TESTS),yes) -LIBVPX_TEST_DATA_PATH ?= . - -include $(SRC_PATH_BARE)/test/test.mk - -# addprefix_clean behaves like addprefix if the target doesn't start with "../" -# However, if the target starts with "../", instead of adding prefix, -# it will remove "../". -# Using addprefix_clean, we can avoid two different targets building the -# same file, i.e. -# test/../ivfenc.c.d: ivfenc.o -# ivfenc.c.d: ivfenc.o -# Note that the other way to solve this problem is using "realpath". -# The "realpath" is supported by make 3.81 or later. -addprefix_clean=$(patsubst $(1)../%,%,$(addprefix $(1), $(2))) -LIBVPX_TEST_SRCS=$(call addprefix_clean,test/,$(call enabled,LIBVPX_TEST_SRCS)) - -LIBVPX_TEST_BIN=./test_libvpx$(EXE_SFX) -LIBVPX_TEST_DATA=$(addprefix $(LIBVPX_TEST_DATA_PATH)/,\ - $(call enabled,LIBVPX_TEST_DATA)) -libvpx_test_data_url=https://storage.googleapis.com/downloads.webmproject.org/test_data/libvpx/$(1) - -TEST_INTRA_PRED_SPEED_BIN=./test_intra_pred_speed$(EXE_SFX) -TEST_INTRA_PRED_SPEED_SRCS=$(call addprefix_clean,test/,\ - $(call enabled,TEST_INTRA_PRED_SPEED_SRCS)) -TEST_INTRA_PRED_SPEED_OBJS := $(sort $(call objs,$(TEST_INTRA_PRED_SPEED_SRCS))) - -ifeq ($(CONFIG_ENCODERS),yes) -RC_INTERFACE_TEST_BIN=./test_rc_interface$(EXE_SFX) -RC_INTERFACE_TEST_SRCS=$(call addprefix_clean,test/,\ - $(call enabled,RC_INTERFACE_TEST_SRCS)) -RC_INTERFACE_TEST_OBJS := $(sort $(call objs,$(RC_INTERFACE_TEST_SRCS))) -endif - -SIMPLE_ENCODE_TEST_BIN=./test_simple_encode$(EXE_SFX) -SIMPLE_ENCODE_TEST_SRCS=$(call addprefix_clean,test/,\ - $(call enabled,SIMPLE_ENCODE_TEST_SRCS)) -SIMPLE_ENCODE_TEST_OBJS := $(sort $(call objs,$(SIMPLE_ENCODE_TEST_SRCS))) - -libvpx_test_srcs.txt: - @echo " [CREATE] $@" - @echo $(LIBVPX_TEST_SRCS) | xargs -n1 echo | LC_ALL=C sort -u > $@ -CLEAN-OBJS += libvpx_test_srcs.txt - -# Attempt to download the file using curl, retrying once if it fails for a -# partial file (18). -$(LIBVPX_TEST_DATA): $(SRC_PATH_BARE)/test/test-data.sha1 - @echo " [DOWNLOAD] $@" - $(qexec)( \ - trap 'rm -f $@' INT TERM; \ - curl="curl -S -s --retry 1 -L -o $@ $(call libvpx_test_data_url,$(@F))"; \ - $$curl; ret=$$?; \ - case "$$ret" in \ - 18) $$curl -C - ;; \ - *) exit $$ret ;; \ - esac \ - ) - -testdata: $(LIBVPX_TEST_DATA) - $(qexec)[ -x "$$(which sha1sum)" ] && sha1sum=sha1sum;\ - [ -x "$$(which shasum)" ] && sha1sum=shasum;\ - [ -x "$$(which sha1)" ] && sha1sum=sha1;\ - if [ -n "$${sha1sum}" ]; then\ - set -e;\ - echo "Checking test data:";\ - for f in $(call enabled,LIBVPX_TEST_DATA); do\ - grep $$f $(SRC_PATH_BARE)/test/test-data.sha1 |\ - (cd "$(LIBVPX_TEST_DATA_PATH)"; $${sha1sum} -c);\ - done; \ - else\ - echo "Skipping test data integrity check, sha1sum not found.";\ - fi - -ifeq ($(CONFIG_EXTERNAL_BUILD),yes) -ifeq ($(CONFIG_MSVS),yes) - -gtest.$(VCPROJ_SFX): $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc - @echo " [CREATE] $@" - $(qexec)$(GEN_VCPROJ) \ - --lib \ - --target=$(TOOLCHAIN) \ - $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \ - --name=gtest \ - --proj-guid=EC00E1EC-AF68-4D92-A255-181690D1C9B1 \ - --ver=$(CONFIG_VS_VERSION) \ - --src-path-bare="$(SRC_PATH_BARE)" \ - --as=$(AS) \ - -D_VARIADIC_MAX=10 \ - --out=gtest.$(VCPROJ_SFX) $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc \ - -I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" -I"$(SRC_PATH_BARE)/third_party/googletest/src" - -PROJECTS-$(CONFIG_MSVS) += gtest.$(VCPROJ_SFX) - -test_libvpx.$(VCPROJ_SFX): $(LIBVPX_TEST_SRCS) vpx.$(VCPROJ_SFX) gtest.$(VCPROJ_SFX) - @echo " [CREATE] $@" - $(qexec)$(GEN_VCPROJ) \ - --exe \ - --target=$(TOOLCHAIN) \ - --name=test_libvpx \ - -D_VARIADIC_MAX=10 \ - --proj-guid=CD837F5F-52D8-4314-A370-895D614166A7 \ - --ver=$(CONFIG_VS_VERSION) \ - --src-path-bare="$(SRC_PATH_BARE)" \ - --as=$(AS) \ - $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \ - --out=$@ $(INTERNAL_CFLAGS) $(CFLAGS) \ - -I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" \ - $(if $(CONFIG_WEBM_IO),-I"$(SRC_PATH_BARE)/third_party/libwebm") \ - -L. -l$(CODEC_LIB) -l$(GTEST_LIB) $^ - -PROJECTS-$(CONFIG_MSVS) += test_libvpx.$(VCPROJ_SFX) - -LIBVPX_TEST_BIN := $(addprefix $(TGT_OS:win64=x64)/Release/,$(notdir $(LIBVPX_TEST_BIN))) - -ifneq ($(strip $(TEST_INTRA_PRED_SPEED_OBJS)),) -PROJECTS-$(CONFIG_MSVS) += test_intra_pred_speed.$(VCPROJ_SFX) -test_intra_pred_speed.$(VCPROJ_SFX): $(TEST_INTRA_PRED_SPEED_SRCS) vpx.$(VCPROJ_SFX) gtest.$(VCPROJ_SFX) - @echo " [CREATE] $@" - $(qexec)$(GEN_VCPROJ) \ - --exe \ - --target=$(TOOLCHAIN) \ - --name=test_intra_pred_speed \ - -D_VARIADIC_MAX=10 \ - --proj-guid=CD837F5F-52D8-4314-A370-895D614166A7 \ - --ver=$(CONFIG_VS_VERSION) \ - --src-path-bare="$(SRC_PATH_BARE)" \ - --as=$(AS) \ - $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \ - --out=$@ $(INTERNAL_CFLAGS) $(CFLAGS) \ - -I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" \ - -L. -l$(CODEC_LIB) -l$(GTEST_LIB) $^ -endif # TEST_INTRA_PRED_SPEED - -ifeq ($(CONFIG_ENCODERS),yes) -ifneq ($(strip $(RC_INTERFACE_TEST_OBJS)),) -PROJECTS-$(CONFIG_MSVS) += test_rc_interface.$(VCPROJ_SFX) -test_rc_interface.$(VCPROJ_SFX): $(RC_INTERFACE_TEST_SRCS) vpx.$(VCPROJ_SFX) \ - vpxrc.$(VCPROJ_SFX) gtest.$(VCPROJ_SFX) - @echo " [CREATE] $@" - $(qexec)$(GEN_VCPROJ) \ - --exe \ - --target=$(TOOLCHAIN) \ - --name=test_rc_interface \ - -D_VARIADIC_MAX=10 \ - --proj-guid=30458F88-1BC6-4689-B41C-50F3737AAB27 \ - --ver=$(CONFIG_VS_VERSION) \ - --as=$(AS) \ - --src-path-bare="$(SRC_PATH_BARE)" \ - $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \ - --out=$@ $(INTERNAL_CFLAGS) $(CFLAGS) \ - -I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" \ - -L. -l$(CODEC_LIB) -l$(RC_RTC_LIB) -l$(GTEST_LIB) $^ -endif # RC_INTERFACE_TEST -endif # CONFIG_ENCODERS -endif # CONFIG_MSVS -else - -include $(SRC_PATH_BARE)/third_party/googletest/gtest.mk -GTEST_SRCS := $(addprefix third_party/googletest/src/,$(call enabled,GTEST_SRCS)) -GTEST_OBJS=$(call objs,$(GTEST_SRCS)) -ifeq ($(filter win%,$(TGT_OS)),$(TGT_OS)) -# Disabling pthreads globally will cause issues on darwin and possibly elsewhere -$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -DGTEST_HAS_PTHREAD=0 -endif -GTEST_INCLUDES := -I$(SRC_PATH_BARE)/third_party/googletest/src -GTEST_INCLUDES += -I$(SRC_PATH_BARE)/third_party/googletest/src/include -$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += $(GTEST_INCLUDES) -OBJS-yes += $(GTEST_OBJS) -LIBS-yes += $(BUILD_PFX)libgtest.a $(BUILD_PFX)libgtest_g.a -$(BUILD_PFX)libgtest_g.a: $(GTEST_OBJS) - -LIBVPX_TEST_OBJS=$(sort $(call objs,$(LIBVPX_TEST_SRCS))) -$(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CXXFLAGS += $(GTEST_INCLUDES) -OBJS-yes += $(LIBVPX_TEST_OBJS) -BINS-yes += $(LIBVPX_TEST_BIN) - -CODEC_LIB=$(if $(CONFIG_DEBUG_LIBS),vpx_g,vpx) -CODEC_LIB_SUF=$(if $(CONFIG_SHARED),$(SHARED_LIB_SUF),.a) -TEST_LIBS := lib$(CODEC_LIB)$(CODEC_LIB_SUF) libgtest.a -$(LIBVPX_TEST_BIN): $(TEST_LIBS) -$(eval $(call linkerxx_template,$(LIBVPX_TEST_BIN), \ - $(LIBVPX_TEST_OBJS) \ - -L. -lvpx -lgtest $(extralibs) -lm)) - -ifneq ($(strip $(TEST_INTRA_PRED_SPEED_OBJS)),) -$(TEST_INTRA_PRED_SPEED_OBJS) $(TEST_INTRA_PRED_SPEED_OBJS:.o=.d): CXXFLAGS += $(GTEST_INCLUDES) -OBJS-yes += $(TEST_INTRA_PRED_SPEED_OBJS) -BINS-yes += $(TEST_INTRA_PRED_SPEED_BIN) - -$(TEST_INTRA_PRED_SPEED_BIN): $(TEST_LIBS) -$(eval $(call linkerxx_template,$(TEST_INTRA_PRED_SPEED_BIN), \ - $(TEST_INTRA_PRED_SPEED_OBJS) \ - -L. -lvpx -lgtest $(extralibs) -lm)) -endif # TEST_INTRA_PRED_SPEED - -ifeq ($(CONFIG_ENCODERS),yes) -ifneq ($(strip $(RC_INTERFACE_TEST_OBJS)),) -$(RC_INTERFACE_TEST_OBJS) $(RC_INTERFACE_TEST_OBJS:.o=.d): \ - CXXFLAGS += $(GTEST_INCLUDES) -OBJS-yes += $(RC_INTERFACE_TEST_OBJS) -BINS-yes += $(RC_INTERFACE_TEST_BIN) - -$(RC_INTERFACE_TEST_BIN): $(TEST_LIBS) libvpxrc.a -$(eval $(call linkerxx_template,$(RC_INTERFACE_TEST_BIN), \ - $(RC_INTERFACE_TEST_OBJS) \ - -L. -lvpx -lgtest -lvpxrc $(extralibs) -lm)) -endif # RC_INTERFACE_TEST -endif # CONFIG_ENCODERS - -ifneq ($(strip $(SIMPLE_ENCODE_TEST_OBJS)),) -$(SIMPLE_ENCODE_TEST_OBJS) $(SIMPLE_ENCODE_TEST_OBJS:.o=.d): \ - CXXFLAGS += $(GTEST_INCLUDES) -OBJS-yes += $(SIMPLE_ENCODE_TEST_OBJS) -BINS-yes += $(SIMPLE_ENCODE_TEST_BIN) - -$(SIMPLE_ENCODE_TEST_BIN): $(TEST_LIBS) libsimple_encode.a -$(eval $(call linkerxx_template,$(SIMPLE_ENCODE_TEST_BIN), \ - $(SIMPLE_ENCODE_TEST_OBJS) \ - -L. -lsimple_encode -lvpx -lgtest $(extralibs) -lm)) -endif # SIMPLE_ENCODE_TEST - -endif # CONFIG_EXTERNAL_BUILD - -# Install test sources only if codec source is included -INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(patsubst $(SRC_PATH_BARE)/%,%,\ - $(shell find $(SRC_PATH_BARE)/third_party/googletest -type f)) -INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(LIBVPX_TEST_SRCS) -INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(TEST_INTRA_PRED_SPEED_SRCS) -INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(RC_INTERFACE_TEST_SRCS) - -define test_shard_template -test: test_shard.$(1) -test-no-data-check: test_shard_ndc.$(1) -test_shard.$(1) test_shard_ndc.$(1): $(LIBVPX_TEST_BIN) - @set -e; \ - export GTEST_SHARD_INDEX=$(1); \ - export GTEST_TOTAL_SHARDS=$(2); \ - $(LIBVPX_TEST_BIN) -test_shard.$(1): testdata -.PHONY: test_shard.$(1) test_shard_ndc.$(1) -endef - -NUM_SHARDS := 10 -SHARDS := 0 1 2 3 4 5 6 7 8 9 -$(foreach s,$(SHARDS),$(eval $(call test_shard_template,$(s),$(NUM_SHARDS)))) - -endif # CONFIG_UNIT_TESTS - -## -## documentation directives -## -CLEAN-OBJS += libs.doxy -DOCS-yes += libs.doxy -libs.doxy: $(CODEC_DOC_SRCS) - @echo " [CREATE] $@" - @rm -f $@ - @echo "INPUT += $^" >> $@ - @echo "INCLUDE_PATH += ." >> $@; - @echo "ENABLED_SECTIONS += $(sort $(CODEC_DOC_SECTIONS))" >> $@ - -## Generate rtcd.h for all objects -ifeq ($(CONFIG_DEPENDENCY_TRACKING),yes) -$(OBJS-yes:.o=.d): $(RTCD) -else -$(OBJS-yes): $(RTCD) -endif - -## Update the global src list -SRCS += $(CODEC_SRCS) $(LIBVPX_TEST_SRCS) $(GTEST_SRCS) -SRCS += $(RC_INTERFACE_TEST_SRCS) - -## -## vpxdec/vpxenc tests. -## -ifeq ($(CONFIG_UNIT_TESTS),yes) -TEST_BIN_PATH = . -ifeq ($(CONFIG_MSVS),yes) -# MSVC will build both Debug and Release configurations of tools in a -# sub directory named for the current target. Assume the user wants to -# run the Release tools, and assign TEST_BIN_PATH accordingly. -# TODO(tomfinegan): Is this adequate for ARM? -# TODO(tomfinegan): Support running the debug versions of tools? -TEST_BIN_PATH := $(addsuffix /$(TGT_OS:win64=x64)/Release, $(TEST_BIN_PATH)) -endif -utiltest utiltest-no-data-check: - $(qexec)$(SRC_PATH_BARE)/test/vpxdec.sh \ - --test-data-path "$(LIBVPX_TEST_DATA_PATH)" \ - --bin-path $(TEST_BIN_PATH) - $(qexec)$(SRC_PATH_BARE)/test/vpxenc.sh \ - --test-data-path "$(LIBVPX_TEST_DATA_PATH)" \ - --bin-path $(TEST_BIN_PATH) -utiltest: testdata -else -utiltest utiltest-no-data-check: - @echo Unit tests must be enabled to make the utiltest target. -endif - -## -## Example tests. -## -ifeq ($(CONFIG_UNIT_TESTS),yes) -# All non-MSVC targets output example targets in a sub dir named examples. -EXAMPLES_BIN_PATH = examples -ifeq ($(CONFIG_MSVS),yes) -# MSVC will build both Debug and Release configurations of the examples in a -# sub directory named for the current target. Assume the user wants to -# run the Release tools, and assign EXAMPLES_BIN_PATH accordingly. -# TODO(tomfinegan): Is this adequate for ARM? -# TODO(tomfinegan): Support running the debug versions of tools? -EXAMPLES_BIN_PATH := $(TGT_OS:win64=x64)/Release -endif -exampletest exampletest-no-data-check: examples - $(qexec)$(SRC_PATH_BARE)/test/examples.sh \ - --test-data-path "$(LIBVPX_TEST_DATA_PATH)" \ - --bin-path $(EXAMPLES_BIN_PATH) -exampletest: testdata -else -exampletest exampletest-no-data-check: - @echo Unit tests must be enabled to make the exampletest target. -endif diff --git a/presentation/src/main/cpp/third_party/libvpx/mainpage.dox b/presentation/src/main/cpp/third_party/libvpx/mainpage.dox deleted file mode 100644 index 4b0dff08..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/mainpage.dox +++ /dev/null @@ -1,55 +0,0 @@ -/*!\mainpage WebM Codec SDK - - \section main_contents Page Contents - - \ref main_intro - - \ref main_startpoints - - \ref main_support - - \section main_intro Introduction - Welcome to the WebM Codec SDK. This SDK allows you to integrate your - applications with the VP8 and VP9 video codecs, high quality, royalty free, - open source codecs deployed on billions of computers and devices worldwide. - - This distribution of the WebM Codec SDK includes the following support: - - \if vp8_encoder - - \ref vp8_encoder - \endif - \if vp8_decoder - - \ref vp8_decoder - \endif - - - \section main_startpoints Starting Points - - Consult the \ref changelog for a complete list of improvements in this - release. - - The \ref readme contains instructions on recompiling the sample applications. - - Read the \ref usage "usage" for a narrative on codec usage. - \if samples - - Read the \ref samples "sample code" for examples of how to interact with the - codec. - \endif - - \ref codec reference - \if encoder - - \ref encoder reference - \endif - \if decoder - - \ref decoder reference - \endif - - \section main_support Support Options & FAQ - The WebM project is an open source project supported by its community. For - questions about this SDK, please mail the apps-devel@webmproject.org list. - To contribute, see http://www.webmproject.org/code/contribute and mail - codec-devel@webmproject.org. -*/ - -/*!\page changelog CHANGELOG - \verbinclude CHANGELOG -*/ - -/*!\page readme README - \verbinclude README -*/ - -/*!\defgroup codecs Supported Codecs */ diff --git a/presentation/src/main/cpp/third_party/libvpx/md5_utils.c b/presentation/src/main/cpp/third_party/libvpx/md5_utils.c deleted file mode 100644 index abd8d43c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/md5_utils.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * This code implements the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - * - * Changed so as no longer to depend on Colin Plumb's `usual.h' header - * definitions - * - Ian Jackson . - * Still in the public domain. - */ - -#include /* for memcpy() */ - -#include "md5_utils.h" -#include "vpx_ports/compiler_attributes.h" - -static void byteSwap(UWORD32 *buf, unsigned words) { - md5byte *p; - - /* Only swap bytes for big endian machines */ - int i = 1; - - if (*(char *)&i == 1) return; - - p = (md5byte *)buf; - - do { - *buf++ = (UWORD32)((unsigned)p[3] << 8 | p[2]) << 16 | - ((unsigned)p[1] << 8 | p[0]); - p += 4; - } while (--words); -} - -/* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. - */ -void MD5Init(struct MD5Context *ctx) { - ctx->buf[0] = 0x67452301; - ctx->buf[1] = 0xefcdab89; - ctx->buf[2] = 0x98badcfe; - ctx->buf[3] = 0x10325476; - - ctx->bytes[0] = 0; - ctx->bytes[1] = 0; -} - -/* - * Update context to reflect the concatenation of another buffer full - * of bytes. - */ -void MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len) { - UWORD32 t; - - /* Update byte count */ - - t = ctx->bytes[0]; - - if ((ctx->bytes[0] = t + len) < t) - ctx->bytes[1]++; /* Carry from low to high */ - - t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */ - - if (t > len) { - memcpy((md5byte *)ctx->in + 64 - t, buf, len); - return; - } - - /* First chunk is an odd size */ - memcpy((md5byte *)ctx->in + 64 - t, buf, t); - byteSwap(ctx->in, 16); - MD5Transform(ctx->buf, ctx->in); - buf += t; - len -= t; - - /* Process data in 64-byte chunks */ - while (len >= 64) { - memcpy(ctx->in, buf, 64); - byteSwap(ctx->in, 16); - MD5Transform(ctx->buf, ctx->in); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - memcpy(ctx->in, buf, len); -} - -/* - * Final wrapup - pad to 64-byte boundary with the bit pattern - * 1 0* (64-bit count of bits processed, MSB-first) - */ -void MD5Final(md5byte digest[16], struct MD5Context *ctx) { - int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ - md5byte *p = (md5byte *)ctx->in + count; - - /* Set the first char of padding to 0x80. There is always room. */ - *p++ = 0x80; - - /* Bytes of padding needed to make 56 bytes (-8..55) */ - count = 56 - 1 - count; - - if (count < 0) { /* Padding forces an extra block */ - memset(p, 0, count + 8); - byteSwap(ctx->in, 16); - MD5Transform(ctx->buf, ctx->in); - p = (md5byte *)ctx->in; - count = 56; - } - - memset(p, 0, count); - byteSwap(ctx->in, 14); - - /* Append length in bits and transform */ - ctx->in[14] = ctx->bytes[0] << 3; - ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; - MD5Transform(ctx->buf, ctx->in); - - byteSwap(ctx->buf, 4); - memcpy(digest, ctx->buf, 16); - memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ -} - -#ifndef ASM_MD5 - -/* The four core functions - F1 is optimized somewhat */ - -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define MD5STEP(f, w, x, y, z, in, s) \ - (w += f(x, y, z) + in, w = (w << s | w >> (32 - s)) + x) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - */ -VPX_NO_UNSIGNED_OVERFLOW_CHECK VPX_NO_UNSIGNED_SHIFT_CHECK void MD5Transform( - UWORD32 buf[4], UWORD32 const in[16]) { - UWORD32 a, b, c, d; - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/md5_utils.h b/presentation/src/main/cpp/third_party/libvpx/md5_utils.h deleted file mode 100644 index e0d5a2d1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/md5_utils.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This is the header file for the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - * - * Changed so as no longer to depend on Colin Plumb's `usual.h' - * header definitions - * - Ian Jackson . - * Still in the public domain. - */ - -#ifndef VPX_MD5_UTILS_H_ -#define VPX_MD5_UTILS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define md5byte unsigned char -#define UWORD32 unsigned int - -typedef struct MD5Context MD5Context; -struct MD5Context { - UWORD32 buf[4]; - UWORD32 bytes[2]; - UWORD32 in[16]; -}; - -void MD5Init(struct MD5Context *context); -void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len); -void MD5Final(unsigned char digest[16], struct MD5Context *context); -void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_MD5_UTILS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/rate_hist.c b/presentation/src/main/cpp/third_party/libvpx/rate_hist.c deleted file mode 100644 index 6a056cac..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/rate_hist.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include -#include - -#include "./rate_hist.h" - -#define RATE_BINS 100 -#define HIST_BAR_MAX 40 - -struct hist_bucket { - int low; - int high; - int count; -}; - -struct rate_hist { - int64_t *pts; - int *sz; - int samples; - int frames; - struct hist_bucket bucket[RATE_BINS]; - int total; -}; - -struct rate_hist *init_rate_histogram(const vpx_codec_enc_cfg_t *cfg, - const vpx_rational_t *fps) { - int i; - struct rate_hist *hist = calloc(1, sizeof(*hist)); - - if (hist == NULL || cfg == NULL || fps == NULL || fps->num == 0 || - fps->den == 0) { - destroy_rate_histogram(hist); - return NULL; - } - - // Determine the number of samples in the buffer. Use the file's framerate - // to determine the number of frames in rc_buf_sz milliseconds, with an - // adjustment (5/4) to account for alt-refs - hist->samples = - (int)((int64_t)cfg->rc_buf_sz * 5 / 4 * fps->num / fps->den / 1000); - - // prevent division by zero - if (hist->samples == 0) hist->samples = 1; - - hist->frames = 0; - hist->total = 0; - - hist->pts = calloc(hist->samples, sizeof(*hist->pts)); - hist->sz = calloc(hist->samples, sizeof(*hist->sz)); - for (i = 0; i < RATE_BINS; i++) { - hist->bucket[i].low = INT_MAX; - hist->bucket[i].high = 0; - hist->bucket[i].count = 0; - } - - return hist; -} - -void destroy_rate_histogram(struct rate_hist *hist) { - if (hist) { - free(hist->pts); - free(hist->sz); - free(hist); - } -} - -void update_rate_histogram(struct rate_hist *hist, - const vpx_codec_enc_cfg_t *cfg, - const vpx_codec_cx_pkt_t *pkt) { - int i; - int64_t then = 0; - int64_t avg_bitrate = 0; - int64_t sum_sz = 0; - const int64_t now = pkt->data.frame.pts * 1000 * - (uint64_t)cfg->g_timebase.num / - (uint64_t)cfg->g_timebase.den; - - int idx; - - if (hist == NULL || cfg == NULL || pkt == NULL) return; - - idx = hist->frames++ % hist->samples; - hist->pts[idx] = now; - hist->sz[idx] = (int)pkt->data.frame.sz; - - if (now < cfg->rc_buf_initial_sz) return; - - if (!cfg->rc_target_bitrate) return; - - then = now; - - /* Sum the size over the past rc_buf_sz ms */ - for (i = hist->frames; i > 0 && hist->frames - i < hist->samples; i--) { - const int i_idx = (i - 1) % hist->samples; - - then = hist->pts[i_idx]; - if (now - then > cfg->rc_buf_sz) break; - sum_sz += hist->sz[i_idx]; - } - - if (now == then) return; - - avg_bitrate = sum_sz * 8 * 1000 / (now - then); - idx = (int)(avg_bitrate * (RATE_BINS / 2) / (cfg->rc_target_bitrate * 1000)); - if (idx < 0) idx = 0; - if (idx > RATE_BINS - 1) idx = RATE_BINS - 1; - if (hist->bucket[idx].low > avg_bitrate) - hist->bucket[idx].low = (int)avg_bitrate; - if (hist->bucket[idx].high < avg_bitrate) - hist->bucket[idx].high = (int)avg_bitrate; - hist->bucket[idx].count++; - hist->total++; -} - -static int merge_hist_buckets(struct hist_bucket *bucket, int max_buckets, - int *num_buckets) { - int small_bucket = 0, merge_bucket = INT_MAX, big_bucket = 0; - int buckets; - int i; - - assert(bucket != NULL); - assert(num_buckets != NULL); - - buckets = *num_buckets; - - /* Find the extrema for this list of buckets */ - big_bucket = small_bucket = 0; - for (i = 0; i < buckets; i++) { - if (bucket[i].count < bucket[small_bucket].count) small_bucket = i; - if (bucket[i].count > bucket[big_bucket].count) big_bucket = i; - } - - /* If we have too many buckets, merge the smallest with an adjacent - * bucket. - */ - while (buckets > max_buckets) { - int last_bucket = buckets - 1; - - /* merge the small bucket with an adjacent one. */ - if (small_bucket == 0) - merge_bucket = 1; - else if (small_bucket == last_bucket) - merge_bucket = last_bucket - 1; - else if (bucket[small_bucket - 1].count < bucket[small_bucket + 1].count) - merge_bucket = small_bucket - 1; - else - merge_bucket = small_bucket + 1; - - assert(abs(merge_bucket - small_bucket) <= 1); - assert(small_bucket < buckets); - assert(big_bucket < buckets); - assert(merge_bucket < buckets); - - if (merge_bucket < small_bucket) { - bucket[merge_bucket].high = bucket[small_bucket].high; - bucket[merge_bucket].count += bucket[small_bucket].count; - } else { - bucket[small_bucket].high = bucket[merge_bucket].high; - bucket[small_bucket].count += bucket[merge_bucket].count; - merge_bucket = small_bucket; - } - - assert(bucket[merge_bucket].low != bucket[merge_bucket].high); - - buckets--; - - /* Remove the merge_bucket from the list, and find the new small - * and big buckets while we're at it - */ - big_bucket = small_bucket = 0; - for (i = 0; i < buckets; i++) { - if (i > merge_bucket) bucket[i] = bucket[i + 1]; - - if (bucket[i].count < bucket[small_bucket].count) small_bucket = i; - if (bucket[i].count > bucket[big_bucket].count) big_bucket = i; - } - } - - *num_buckets = buckets; - return bucket[big_bucket].count; -} - -static void show_histogram(const struct hist_bucket *bucket, int buckets, - int total, int scale) { - int width1, width2; - int i; - - if (!buckets) return; - assert(bucket != NULL); - assert(buckets > 0); - - switch ((int)(log(bucket[buckets - 1].high) / log(10)) + 1) { - case 1: - case 2: - width1 = 4; - width2 = 2; - break; - case 3: - width1 = 5; - width2 = 3; - break; - case 4: - width1 = 6; - width2 = 4; - break; - case 5: - width1 = 7; - width2 = 5; - break; - case 6: - width1 = 8; - width2 = 6; - break; - case 7: - width1 = 9; - width2 = 7; - break; - default: - width1 = 12; - width2 = 10; - break; - } - - for (i = 0; i < buckets; i++) { - int len; - int j; - float pct; - - pct = (float)(100.0 * bucket[i].count / total); - len = HIST_BAR_MAX * bucket[i].count / scale; - if (len < 1) len = 1; - assert(len <= HIST_BAR_MAX); - - if (bucket[i].low == bucket[i].high) - fprintf(stderr, "%*d %*s: ", width1, bucket[i].low, width2, ""); - else - fprintf(stderr, "%*d-%*d: ", width1, bucket[i].low, width2, - bucket[i].high); - - for (j = 0; j < HIST_BAR_MAX; j++) fprintf(stderr, j < len ? "=" : " "); - fprintf(stderr, "\t%5d (%6.2f%%)\n", bucket[i].count, pct); - } -} - -void show_q_histogram(const int counts[64], int max_buckets) { - struct hist_bucket bucket[64]; - int buckets = 0; - int total = 0; - int scale; - int i; - - for (i = 0; i < 64; i++) { - if (counts[i]) { - bucket[buckets].low = bucket[buckets].high = i; - bucket[buckets].count = counts[i]; - buckets++; - total += counts[i]; - } - } - - fprintf(stderr, "\nQuantizer Selection:\n"); - scale = merge_hist_buckets(bucket, max_buckets, &buckets); - show_histogram(bucket, buckets, total, scale); -} - -void show_rate_histogram(struct rate_hist *hist, const vpx_codec_enc_cfg_t *cfg, - int max_buckets) { - int i, scale; - int buckets = 0; - - if (hist == NULL || cfg == NULL) return; - - for (i = 0; i < RATE_BINS; i++) { - if (hist->bucket[i].low == INT_MAX) continue; - hist->bucket[buckets++] = hist->bucket[i]; - } - - fprintf(stderr, "\nRate (over %dms window):\n", cfg->rc_buf_sz); - scale = merge_hist_buckets(hist->bucket, max_buckets, &buckets); - show_histogram(hist->bucket, buckets, hist->total, scale); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/rate_hist.h b/presentation/src/main/cpp/third_party/libvpx/rate_hist.h deleted file mode 100644 index d6a4c685..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/rate_hist.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_RATE_HIST_H_ -#define VPX_RATE_HIST_H_ - -#include "vpx/vpx_encoder.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct rate_hist; - -struct rate_hist *init_rate_histogram(const vpx_codec_enc_cfg_t *cfg, - const vpx_rational_t *fps); - -void destroy_rate_histogram(struct rate_hist *hist); - -void update_rate_histogram(struct rate_hist *hist, - const vpx_codec_enc_cfg_t *cfg, - const vpx_codec_cx_pkt_t *pkt); - -void show_q_histogram(const int counts[64], int max_buckets); - -void show_rate_histogram(struct rate_hist *hist, const vpx_codec_enc_cfg_t *cfg, - int max_buckets); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_RATE_HIST_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/solution.mk b/presentation/src/main/cpp/third_party/libvpx/solution.mk deleted file mode 100644 index 145adc0d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/solution.mk +++ /dev/null @@ -1,31 +0,0 @@ -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -# libvpx reverse dependencies (targets that depend on libvpx) -VPX_NONDEPS=$(addsuffix .$(VCPROJ_SFX),vpx gtest) -VPX_RDEPS=$(foreach vcp,\ - $(filter-out $(VPX_NONDEPS),$^), --dep=$(vcp:.$(VCPROJ_SFX)=):vpx) - -vpx.sln: $(wildcard *.$(VCPROJ_SFX)) - @echo " [CREATE] $@" - $(SRC_PATH_BARE)/build/make/gen_msvs_sln.sh \ - $(if $(filter vpx.$(VCPROJ_SFX),$^),$(VPX_RDEPS)) \ - --dep=test_libvpx:gtest \ - --ver=$(CONFIG_VS_VERSION)\ - --out=$@ $^ -vpx.sln.mk: vpx.sln - @true - -PROJECTS-yes += vpx.sln vpx.sln.mk --include vpx.sln.mk - -# Always install this file, as it is an unconditional post-build rule. -INSTALL_MAPS += src/% $(SRC_PATH_BARE)/% -INSTALL-SRCS-yes += $(target).mk diff --git a/presentation/src/main/cpp/third_party/libvpx/test/acm_random.h b/presentation/src/main/cpp/third_party/libvpx/test/acm_random.h deleted file mode 100644 index 6ebb6002..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/acm_random.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_TEST_ACM_RANDOM_H_ -#define VPX_TEST_ACM_RANDOM_H_ - -#include - -#include - -#include "gtest/gtest.h" - -#include "vpx/vpx_integer.h" - -namespace libvpx_test { - -class ACMRandom { - public: - ACMRandom() : random_(DeterministicSeed()) {} - - explicit ACMRandom(int seed) : random_(seed) {} - - void Reset(int seed) { random_.Reseed(seed); } - uint16_t Rand16() { - const uint32_t value = - random_.Generate(testing::internal::Random::kMaxRange); - return (value >> 15) & 0xffff; - } - - int32_t Rand20Signed() { - // Use 20 bits: values between 524287 and -524288. - const uint32_t value = random_.Generate(1048576); - return static_cast(value) - 524288; - } - - int16_t Rand16Signed() { - // Use 16 bits: values between 32767 and -32768. - return static_cast(random_.Generate(65536)); - } - - uint16_t Rand12() { - const uint32_t value = - random_.Generate(testing::internal::Random::kMaxRange); - // There's a bit more entropy in the upper bits of this implementation. - return (value >> 19) & 0xfff; - } - - uint8_t Rand8() { - const uint32_t value = - random_.Generate(testing::internal::Random::kMaxRange); - // There's a bit more entropy in the upper bits of this implementation. - return (value >> 23) & 0xff; - } - - uint8_t Rand8Extremes() { - // Returns a random value near 0 or near 255, to better exercise - // saturation behavior. - const uint8_t r = Rand8(); - return static_cast((r < 128) ? r << 4 : r >> 4); - } - - uint32_t RandRange(const uint32_t range) { - // testing::internal::Random::Generate provides values in the range - // testing::internal::Random::kMaxRange. - assert(range <= testing::internal::Random::kMaxRange); - return random_.Generate(range); - } - - int PseudoUniform(int range) { return random_.Generate(range); } - - int operator()(int n) { return PseudoUniform(n); } - - static int DeterministicSeed() { return 0xbaba; } - - private: - testing::internal::Random random_; -}; - -} // namespace libvpx_test - -#endif // VPX_TEST_ACM_RANDOM_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/active_map_refresh_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/active_map_refresh_test.cc deleted file mode 100644 index a0b46059..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/active_map_refresh_test.cc +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/util.h" -#include "test/y4m_video_source.h" - -namespace { - -// Check if any pixel in a 16x16 macroblock varies between frames. -int CheckMb(const vpx_image_t ¤t, const vpx_image_t &previous, int mb_r, - int mb_c) { - for (int plane = 0; plane < 3; plane++) { - int r = 16 * mb_r; - int c0 = 16 * mb_c; - int r_top = std::min(r + 16, static_cast(current.d_h)); - int c_top = std::min(c0 + 16, static_cast(current.d_w)); - r = std::max(r, 0); - c0 = std::max(c0, 0); - if (plane > 0 && current.x_chroma_shift) { - c_top = (c_top + 1) >> 1; - c0 >>= 1; - } - if (plane > 0 && current.y_chroma_shift) { - r_top = (r_top + 1) >> 1; - r >>= 1; - } - for (; r < r_top; ++r) { - for (int c = c0; c < c_top; ++c) { - if (current.planes[plane][current.stride[plane] * r + c] != - previous.planes[plane][previous.stride[plane] * r + c]) { - return 1; - } - } - } - } - return 0; -} - -void GenerateMap(int mb_rows, int mb_cols, const vpx_image_t ¤t, - const vpx_image_t &previous, uint8_t *map) { - for (int mb_r = 0; mb_r < mb_rows; ++mb_r) { - for (int mb_c = 0; mb_c < mb_cols; ++mb_c) { - map[mb_r * mb_cols + mb_c] = CheckMb(current, previous, mb_r, mb_c); - } - } -} - -const int kAqModeCyclicRefresh = 3; - -class ActiveMapRefreshTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith2Params { - protected: - ActiveMapRefreshTest() : EncoderTest(GET_PARAM(0)) {} - ~ActiveMapRefreshTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(GET_PARAM(1)); - cpu_used_ = GET_PARAM(2); - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - ::libvpx_test::Y4mVideoSource *y4m_video = - static_cast(video); - if (video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, cpu_used_); - encoder->Control(VP9E_SET_AQ_MODE, kAqModeCyclicRefresh); - } else if (video->frame() >= 2 && video->img()) { - vpx_image_t *current = video->img(); - vpx_image_t *previous = y4m_holder_->img(); - ASSERT_NE(previous, nullptr); - vpx_active_map_t map = vpx_active_map_t(); - const int width = static_cast(current->d_w); - const int height = static_cast(current->d_h); - const int mb_width = (width + 15) / 16; - const int mb_height = (height + 15) / 16; - uint8_t *active_map = new uint8_t[mb_width * mb_height]; - GenerateMap(mb_height, mb_width, *current, *previous, active_map); - map.cols = mb_width; - map.rows = mb_height; - map.active_map = active_map; - encoder->Control(VP8E_SET_ACTIVEMAP, &map); - delete[] active_map; - } - if (video->img()) { - y4m_video->SwapBuffers(y4m_holder_); - } - } - - int cpu_used_; - ::libvpx_test::Y4mVideoSource *y4m_holder_; -}; - -TEST_P(ActiveMapRefreshTest, Test) { - cfg_.g_lag_in_frames = 0; - cfg_.g_profile = 1; - cfg_.rc_target_bitrate = 600; - cfg_.rc_resize_allowed = 0; - cfg_.rc_min_quantizer = 8; - cfg_.rc_max_quantizer = 30; - cfg_.g_pass = VPX_RC_ONE_PASS; - cfg_.rc_end_usage = VPX_CBR; - cfg_.kf_max_dist = 90000; - - ::libvpx_test::Y4mVideoSource video("desktop_credits.y4m", 0, 30); - ::libvpx_test::Y4mVideoSource video_holder("desktop_credits.y4m", 0, 30); - video_holder.Begin(); - y4m_holder_ = &video_holder; - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -VP9_INSTANTIATE_TEST_SUITE(ActiveMapRefreshTest, - ::testing::Values(::libvpx_test::kRealTime), - ::testing::Range(5, 6)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/active_map_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/active_map_test.cc deleted file mode 100644 index e8976b41..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/active_map_test.cc +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" - -namespace { - -class ActiveMapTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith3Params { - protected: - static const int kWidth = 208; - static const int kHeight = 144; - - ActiveMapTest() : EncoderTest(GET_PARAM(0)) {} - ~ActiveMapTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(GET_PARAM(1)); - cpu_used_ = GET_PARAM(2); - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, cpu_used_); - encoder->Control(VP9E_SET_AQ_MODE, GET_PARAM(3)); - } else if (video->frame() == 3) { - vpx_active_map_t map = vpx_active_map_t(); - /* clang-format off */ - uint8_t active_map[9 * 13] = { - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, - 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, - 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, - }; - /* clang-format on */ - map.cols = (kWidth + 15) / 16; - map.rows = (kHeight + 15) / 16; - ASSERT_EQ(map.cols, 13u); - ASSERT_EQ(map.rows, 9u); - map.active_map = active_map; - encoder->Control(VP8E_SET_ACTIVEMAP, &map); - } else if (video->frame() == 15) { - vpx_active_map_t map = vpx_active_map_t(); - map.cols = (kWidth + 15) / 16; - map.rows = (kHeight + 15) / 16; - map.active_map = nullptr; - encoder->Control(VP8E_SET_ACTIVEMAP, &map); - } - } - - int cpu_used_; -}; - -TEST_P(ActiveMapTest, Test) { - // Validate that this non multiple of 64 wide clip encodes - cfg_.g_lag_in_frames = 0; - cfg_.rc_target_bitrate = 400; - cfg_.rc_resize_allowed = 0; - cfg_.g_pass = VPX_RC_ONE_PASS; - cfg_.rc_end_usage = VPX_CBR; - cfg_.kf_max_dist = 90000; - - ::libvpx_test::I420VideoSource video("hantro_odd.yuv", kWidth, kHeight, 30, 1, - 0, 20); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -VP9_INSTANTIATE_TEST_SUITE(ActiveMapTest, - ::testing::Values(::libvpx_test::kRealTime), - ::testing::Range(5, 10), ::testing::Values(0, 3)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/add_noise_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/add_noise_test.cc deleted file mode 100644 index 31bc7441..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/add_noise_test.cc +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include - -#include "gtest/gtest.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_config.h" -#include "vpx_dsp/postproc.h" -#include "vpx_mem/vpx_mem.h" - -namespace { - -static const int kNoiseSize = 3072; - -typedef void (*AddNoiseFunc)(uint8_t *start, const int8_t *noise, - int blackclamp, int whiteclamp, int width, - int height, int pitch); - -typedef std::tuple AddNoiseTestFPParam; - -class AddNoiseTest : public ::testing::Test, - public ::testing::WithParamInterface { - public: - void TearDown() override { libvpx_test::ClearSystemState(); } - ~AddNoiseTest() override = default; -}; - -double stddev6(char a, char b, char c, char d, char e, char f) { - const double n = (a + b + c + d + e + f) / 6.0; - const double v = ((a - n) * (a - n) + (b - n) * (b - n) + (c - n) * (c - n) + - (d - n) * (d - n) + (e - n) * (e - n) + (f - n) * (f - n)) / - 6.0; - return sqrt(v); -} - -TEST_P(AddNoiseTest, CheckNoiseAdded) { - const int width = 64; - const int height = 64; - const int image_size = width * height; - int8_t noise[kNoiseSize]; - const int clamp = vpx_setup_noise(GET_PARAM(0), noise, kNoiseSize); - uint8_t *const s = - reinterpret_cast(vpx_calloc(image_size, sizeof(*s))); - ASSERT_NE(s, nullptr); - memset(s, 99, image_size * sizeof(*s)); - - ASM_REGISTER_STATE_CHECK( - GET_PARAM(1)(s, noise, clamp, clamp, width, height, width)); - - // Check to make sure we don't end up having either the same or no added - // noise either vertically or horizontally. - for (int i = 0; i < image_size - 6 * width - 6; ++i) { - const double hd = stddev6(s[i] - 99, s[i + 1] - 99, s[i + 2] - 99, - s[i + 3] - 99, s[i + 4] - 99, s[i + 5] - 99); - const double vd = stddev6(s[i] - 99, s[i + width] - 99, - s[i + 2 * width] - 99, s[i + 3 * width] - 99, - s[i + 4 * width] - 99, s[i + 5 * width] - 99); - - EXPECT_NE(hd, 0); - EXPECT_NE(vd, 0); - } - - // Initialize pixels in the image to 255 and check for roll over. - memset(s, 255, image_size); - - ASM_REGISTER_STATE_CHECK( - GET_PARAM(1)(s, noise, clamp, clamp, width, height, width)); - - // Check to make sure don't roll over. - for (int i = 0; i < image_size; ++i) { - EXPECT_GT(static_cast(s[i]), clamp) << "i = " << i; - } - - // Initialize pixels in the image to 0 and check for roll under. - memset(s, 0, image_size); - - ASM_REGISTER_STATE_CHECK( - GET_PARAM(1)(s, noise, clamp, clamp, width, height, width)); - - // Check to make sure don't roll under. - for (int i = 0; i < image_size; ++i) { - EXPECT_LT(static_cast(s[i]), 255 - clamp) << "i = " << i; - } - - vpx_free(s); -} - -TEST_P(AddNoiseTest, CheckCvsAssembly) { - const int width = 64; - const int height = 64; - const int image_size = width * height; - int8_t noise[kNoiseSize]; - const int clamp = vpx_setup_noise(4.4, noise, kNoiseSize); - - uint8_t *const s = reinterpret_cast(vpx_calloc(image_size, 1)); - uint8_t *const d = reinterpret_cast(vpx_calloc(image_size, 1)); - ASSERT_NE(s, nullptr); - ASSERT_NE(d, nullptr); - - memset(s, 99, image_size); - memset(d, 99, image_size); - - srand(0); - ASM_REGISTER_STATE_CHECK( - GET_PARAM(1)(s, noise, clamp, clamp, width, height, width)); - srand(0); - ASM_REGISTER_STATE_CHECK( - vpx_plane_add_noise_c(d, noise, clamp, clamp, width, height, width)); - - for (int i = 0; i < image_size; ++i) { - EXPECT_EQ(static_cast(s[i]), static_cast(d[i])) << "i = " << i; - } - - vpx_free(d); - vpx_free(s); -} - -using std::make_tuple; - -INSTANTIATE_TEST_SUITE_P( - C, AddNoiseTest, - ::testing::Values(make_tuple(3.25, vpx_plane_add_noise_c), - make_tuple(4.4, vpx_plane_add_noise_c))); - -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P( - SSE2, AddNoiseTest, - ::testing::Values(make_tuple(3.25, vpx_plane_add_noise_sse2), - make_tuple(4.4, vpx_plane_add_noise_sse2))); -#endif - -#if HAVE_MSA -INSTANTIATE_TEST_SUITE_P( - MSA, AddNoiseTest, - ::testing::Values(make_tuple(3.25, vpx_plane_add_noise_msa), - make_tuple(4.4, vpx_plane_add_noise_msa))); -#endif -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/alt_ref_aq_segment_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/alt_ref_aq_segment_test.cc deleted file mode 100644 index ade82d7e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/alt_ref_aq_segment_test.cc +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" - -namespace { - -class AltRefAqSegmentTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith2Params { - protected: - AltRefAqSegmentTest() : EncoderTest(GET_PARAM(0)) {} - ~AltRefAqSegmentTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(GET_PARAM(1)); - set_cpu_used_ = GET_PARAM(2); - aq_mode_ = 0; - alt_ref_aq_mode_ = 0; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_); - encoder->Control(VP9E_SET_ALT_REF_AQ, alt_ref_aq_mode_); - encoder->Control(VP9E_SET_AQ_MODE, aq_mode_); - encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 100); - } - } - - int set_cpu_used_; - int aq_mode_; - int alt_ref_aq_mode_; -}; - -// Validate that this ALT_REF_AQ/AQ segmentation mode -// (ALT_REF_AQ=0, AQ=0/no_aq) -// encodes and decodes without a mismatch. -TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ0) { - cfg_.rc_min_quantizer = 8; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_VBR; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_target_bitrate = 300; - - aq_mode_ = 0; - alt_ref_aq_mode_ = 1; - - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 100); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -// Validate that this ALT_REF_AQ/AQ segmentation mode -// (ALT_REF_AQ=0, AQ=1/variance_aq) -// encodes and decodes without a mismatch. -TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ1) { - cfg_.rc_min_quantizer = 8; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_VBR; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_target_bitrate = 300; - - aq_mode_ = 1; - alt_ref_aq_mode_ = 1; - - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 100); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -// Validate that this ALT_REF_AQ/AQ segmentation mode -// (ALT_REF_AQ=0, AQ=2/complexity_aq) -// encodes and decodes without a mismatch. -TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ2) { - cfg_.rc_min_quantizer = 8; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_VBR; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_target_bitrate = 300; - - aq_mode_ = 2; - alt_ref_aq_mode_ = 1; - - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 100); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -// Validate that this ALT_REF_AQ/AQ segmentation mode -// (ALT_REF_AQ=0, AQ=3/cyclicrefresh_aq) -// encodes and decodes without a mismatch. -TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ3) { - cfg_.rc_min_quantizer = 8; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_VBR; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_target_bitrate = 300; - - aq_mode_ = 3; - alt_ref_aq_mode_ = 1; - - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 100); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -// Validate that this ALT_REF_AQ/AQ segmentation mode -// (ALT_REF_AQ=0, AQ=4/equator360_aq) -// encodes and decodes without a mismatch. -TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ4) { - cfg_.rc_min_quantizer = 8; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_VBR; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_target_bitrate = 300; - - aq_mode_ = 4; - alt_ref_aq_mode_ = 1; - - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 100); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -VP9_INSTANTIATE_TEST_SUITE(AltRefAqSegmentTest, - ::testing::Values(::libvpx_test::kOnePassGood, - ::libvpx_test::kTwoPassGood), - ::testing::Range(2, 5)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/altref_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/altref_test.cc deleted file mode 100644 index e98edcba..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/altref_test.cc +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" -#include "vpx_config.h" -namespace { - -#if CONFIG_VP8_ENCODER - -// lookahead range: [kLookAheadMin, kLookAheadMax). -const int kLookAheadMin = 5; -const int kLookAheadMax = 26; - -class AltRefTest : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWithParam { - protected: - AltRefTest() : EncoderTest(GET_PARAM(0)), altref_count_(0) {} - ~AltRefTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(libvpx_test::kTwoPassGood); - } - - void BeginPassHook(unsigned int /*pass*/) override { altref_count_ = 0; } - - void PreEncodeFrameHook(libvpx_test::VideoSource *video, - libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); - encoder->Control(VP8E_SET_CPUUSED, 3); - } - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - if (pkt->data.frame.flags & VPX_FRAME_IS_INVISIBLE) ++altref_count_; - } - - int altref_count() const { return altref_count_; } - - private: - int altref_count_; -}; - -TEST_P(AltRefTest, MonotonicTimestamps) { - const vpx_rational timebase = { 33333333, 1000000000 }; - cfg_.g_timebase = timebase; - cfg_.rc_target_bitrate = 1000; - cfg_.g_lag_in_frames = GET_PARAM(1); - - libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - timebase.den, timebase.num, 0, 30); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - EXPECT_GE(altref_count(), 1); -} - -VP8_INSTANTIATE_TEST_SUITE(AltRefTest, - ::testing::Range(kLookAheadMin, kLookAheadMax)); - -#endif // CONFIG_VP8_ENCODER - -class AltRefForcedKeyTestLarge - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith2Params { - protected: - AltRefForcedKeyTestLarge() - : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)), - cpu_used_(GET_PARAM(2)), forced_kf_frame_num_(1), frame_num_(0) {} - ~AltRefForcedKeyTestLarge() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(encoding_mode_); - cfg_.rc_end_usage = VPX_VBR; - cfg_.g_threads = 0; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, cpu_used_); - encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); -#if CONFIG_VP9_ENCODER - // override test default for tile columns if necessary. - if (GET_PARAM(0) == &libvpx_test::kVP9) { - encoder->Control(VP9E_SET_TILE_COLUMNS, 6); - } -#endif - } - frame_flags_ = - (video->frame() == forced_kf_frame_num_) ? VPX_EFLAG_FORCE_KF : 0; - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - if (frame_num_ == forced_kf_frame_num_) { - ASSERT_TRUE(!!(pkt->data.frame.flags & VPX_FRAME_IS_KEY)) - << "Frame #" << frame_num_ << " isn't a keyframe!"; - } - ++frame_num_; - } - - ::libvpx_test::TestMode encoding_mode_; - int cpu_used_; - unsigned int forced_kf_frame_num_; - unsigned int frame_num_; -}; - -TEST_P(AltRefForcedKeyTestLarge, Frame1IsKey) { - const vpx_rational timebase = { 1, 30 }; - const int lag_values[] = { 3, 15, 25, -1 }; - - forced_kf_frame_num_ = 1; - for (int i = 0; lag_values[i] != -1; ++i) { - frame_num_ = 0; - cfg_.g_lag_in_frames = lag_values[i]; - libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - timebase.den, timebase.num, 0, 30); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - } -} - -TEST_P(AltRefForcedKeyTestLarge, ForcedFrameIsKey) { - const vpx_rational timebase = { 1, 30 }; - const int lag_values[] = { 3, 15, 25, -1 }; - - for (int i = 0; lag_values[i] != -1; ++i) { - frame_num_ = 0; - forced_kf_frame_num_ = lag_values[i] - 1; - cfg_.g_lag_in_frames = lag_values[i]; - libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - timebase.den, timebase.num, 0, 30); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - } -} - -VP8_INSTANTIATE_TEST_SUITE(AltRefForcedKeyTestLarge, - ::testing::Values(::libvpx_test::kOnePassGood), - ::testing::Range(0, 9)); - -VP9_INSTANTIATE_TEST_SUITE(AltRefForcedKeyTestLarge, - ::testing::Values(::libvpx_test::kOnePassGood), - ::testing::Range(0, 9)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/android/Android.mk b/presentation/src/main/cpp/third_party/libvpx/test/android/Android.mk deleted file mode 100644 index 9a7533eb..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/android/Android.mk +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright (c) 2013 The WebM project authors. All Rights Reserved. -# -# Use of this source code is governed by a BSD-style license -# that can be found in the LICENSE file in the root of the source -# tree. An additional intellectual property rights grant can be found -# in the file PATENTS. All contributing project authors may -# be found in the AUTHORS file in the root of the source tree. -# -# This make file builds vpx_test app for android. -# The test app itself runs on the command line through adb shell -# The paths are really messed up as the libvpx make file -# expects to be made from a parent directory. - -# Ignore this file during non-NDK builds. -ifdef NDK_ROOT -CUR_WD := $(call my-dir) -BINDINGS_DIR := $(CUR_WD)/../../.. -LOCAL_PATH := $(CUR_WD)/../../.. - -#libwebm -include $(CLEAR_VARS) -include $(BINDINGS_DIR)/libvpx/third_party/libwebm/Android.mk -LOCAL_PATH := $(CUR_WD)/../../.. - -#libvpx -include $(CLEAR_VARS) -LOCAL_STATIC_LIBRARIES := libwebm -include $(BINDINGS_DIR)/libvpx/build/make/Android.mk -LOCAL_PATH := $(CUR_WD)/../.. - -#libgtest -include $(CLEAR_VARS) -LOCAL_ARM_MODE := arm -LOCAL_CPP_EXTENSION := .cc -LOCAL_MODULE := gtest -LOCAL_C_INCLUDES := $(LOCAL_PATH)/third_party/googletest/src/ -LOCAL_C_INCLUDES += $(LOCAL_PATH)/third_party/googletest/src/include/ -LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/third_party/googletest/src/include/ -LOCAL_SRC_FILES := ./third_party/googletest/src/src/gtest-all.cc -LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../LICENSE $(LOCAL_PATH)/../../PATENTS -include $(BUILD_STATIC_LIBRARY) - -#libvpx_test -include $(CLEAR_VARS) -LOCAL_ARM_MODE := arm -LOCAL_MODULE := libvpx_test -LOCAL_STATIC_LIBRARIES := gtest libwebm - -ifeq ($(ENABLE_SHARED),1) - LOCAL_SHARED_LIBRARIES := vpx -else - LOCAL_STATIC_LIBRARIES += vpx -endif - -LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../LICENSE $(LOCAL_PATH)/../../PATENTS -include $(LOCAL_PATH)/test/test.mk -LOCAL_C_INCLUDES := $(BINDINGS_DIR) -FILTERED_SRC := $(sort $(filter %.cc %.c, $(LIBVPX_TEST_SRCS-yes))) -LOCAL_SRC_FILES := $(addprefix ./test/, $(FILTERED_SRC)) -# some test files depend on *_rtcd.h, ensure they're generated first. -$(eval $(call rtcd_dep_template)) -include $(BUILD_EXECUTABLE) -endif # NDK_ROOT diff --git a/presentation/src/main/cpp/third_party/libvpx/test/android/README b/presentation/src/main/cpp/third_party/libvpx/test/android/README deleted file mode 100644 index 0cd30779..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/android/README +++ /dev/null @@ -1,33 +0,0 @@ -Android.mk will build vpx unittests on android. -1) Configure libvpx from the parent directory: -./libvpx/configure --target=armv7-android-gcc --enable-external-build \ - --enable-postproc --disable-install-srcs --enable-multi-res-encoding \ - --enable-temporal-denoising --disable-unit-tests --disable-install-docs \ - --disable-examples --disable-runtime-cpu-detect - -2) From the parent directory, invoke ndk-build: -NDK_PROJECT_PATH=. ndk-build APP_BUILD_SCRIPT=./libvpx/test/android/Android.mk \ - APP_ABI=armeabi-v7a APP_PLATFORM=android-18 APP_OPTIM=release \ - APP_STL=c++_static - -Note: Both adb and ndk-build are available at: - https://developer.android.com/studio#downloads - https://developer.android.com/ndk/downloads - -3) Run get_files.py to download the test files: -python get_files.py -i /path/to/test-data.sha1 -o /path/to/put/files \ - -u https://storage.googleapis.com/downloads.webmproject.org/test_data/libvpx - -4) Transfer files to device using adb. Ensure you have proper permissions for -the target - -adb push /path/to/test_files /data/local/tmp -adb push /path/to/built_libs /data/local/tmp - -NOTE: Built_libs defaults to parent_dir/libs/armeabi-v7a - -5) Run tests: -adb shell -(on device) -cd /data/local/tmp -LD_LIBRARY_PATH=. ./vpx_test diff --git a/presentation/src/main/cpp/third_party/libvpx/test/android/get_files.py b/presentation/src/main/cpp/third_party/libvpx/test/android/get_files.py deleted file mode 100644 index 98ce7b19..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/android/get_files.py +++ /dev/null @@ -1,119 +0,0 @@ -# Copyright (c) 2013 The WebM project authors. All Rights Reserved. -# -# Use of this source code is governed by a BSD-style license -# that can be found in the LICENSE file in the root of the source -# tree. An additional intellectual property rights grant can be found -# in the file PATENTS. All contributing project authors may -# be found in the AUTHORS file in the root of the source tree. -# -# This simple script pulls test files from the webm homepage -# It is intelligent enough to only pull files if -# 1) File / test_data folder does not exist -# 2) SHA mismatch - -import pycurl -import csv -import hashlib -import re -import os.path -import time -import itertools -import sys -import getopt - -#globals -url = '' -file_list_path = '' -local_resource_path = '' - -# Helper functions: -# A simple function which returns the sha hash of a file in hex -def get_file_sha(filename): - try: - sha_hash = hashlib.sha1() - with open(filename, 'rb') as file: - buf = file.read(HASH_CHUNK) - while len(buf) > 0: - sha_hash.update(buf) - buf = file.read(HASH_CHUNK) - return sha_hash.hexdigest() - except IOError: - print("Error reading " + filename) - -# Downloads a file from a url, and then checks the sha against the passed -# in sha -def download_and_check_sha(url, filename, sha): - path = os.path.join(local_resource_path, filename) - fp = open(path, "wb") - curl = pycurl.Curl() - curl.setopt(pycurl.URL, url + "/" + filename) - curl.setopt(pycurl.WRITEDATA, fp) - curl.perform() - curl.close() - fp.close() - return get_file_sha(path) == sha - -#constants -ftp_retries = 3 - -SHA_COL = 0 -NAME_COL = 1 -EXPECTED_COL = 2 -HASH_CHUNK = 65536 - -# Main script -try: - opts, args = \ - getopt.getopt(sys.argv[1:], \ - "u:i:o:", ["url=", "input_csv=", "output_dir="]) -except: - print('get_files.py -u -i -o ') - sys.exit(2) - -for opt, arg in opts: - if opt == '-u': - url = arg - elif opt in ("-i", "--input_csv"): - file_list_path = os.path.join(arg) - elif opt in ("-o", "--output_dir"): - local_resource_path = os.path.join(arg) - -if len(sys.argv) != 7: - print("Expects two paths and a url!") - exit(1) - -if not os.path.isdir(local_resource_path): - os.makedirs(local_resource_path) - -file_list_csv = open(file_list_path, "rb") - -# Our 'csv' file uses multiple spaces as a delimiter, python's -# csv class only uses single character delimiters, so we convert them below -file_list_reader = csv.reader((re.sub(' +', ' ', line.decode('utf-8')) \ - for line in file_list_csv), delimiter = ' ') - -file_shas = [] -file_names = [] - -for row in file_list_reader: - if len(row) != EXPECTED_COL: - continue - file_shas.append(row[SHA_COL]) - file_names.append(row[NAME_COL]) - -file_list_csv.close() - -# Download files, only if they don't already exist and have correct shas -for filename, sha in zip(file_names, file_shas): - filename = filename.lstrip('*') - path = os.path.join(local_resource_path, filename) - if os.path.isfile(path) \ - and get_file_sha(path) == sha: - print(path + ' exists, skipping') - continue - for retry in range(0, ftp_retries): - print("Downloading " + path) - if not download_and_check_sha(url, filename, sha): - print("Sha does not match, retrying...") - else: - break diff --git a/presentation/src/main/cpp/third_party/libvpx/test/android/scrape_gtest_log.py b/presentation/src/main/cpp/third_party/libvpx/test/android/scrape_gtest_log.py deleted file mode 100644 index 487845c2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/android/scrape_gtest_log.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (c) 2014 The WebM project authors. All Rights Reserved. -# -# Use of this source code is governed by a BSD-style license -# that can be found in the LICENSE file in the root of the source -# tree. An additional intellectual property rights grant can be found -# in the file PATENTS. All contributing project authors may -# be found in the AUTHORS file in the root of the source tree. - -"""Standalone script which parses a gtest log for json. - -Json is returned returns as an array. This script is used by the libvpx -waterfall to gather json results mixed in with gtest logs. This is -dubious software engineering. -""" - -import getopt -import json -import os -import re -import sys - - -def main(): - if len(sys.argv) != 3: - print "Expects a file to write json to!" - exit(1) - - try: - opts, _ = \ - getopt.getopt(sys.argv[1:], \ - 'o:', ['output-json=']) - except getopt.GetOptError: - print 'scrape_gtest_log.py -o ' - sys.exit(2) - - output_json = '' - for opt, arg in opts: - if opt in ('-o', '--output-json'): - output_json = os.path.join(arg) - - blob = sys.stdin.read() - json_string = '[' + ','.join('{' + x + '}' for x in - re.findall(r'{([^}]*.?)}', blob)) + ']' - print blob - - output = json.dumps(json.loads(json_string), indent=4, sort_keys=True) - print output - - path = os.path.dirname(output_json) - if path and not os.path.exists(path): - os.makedirs(path) - - outfile = open(output_json, 'w') - outfile.write(output) - -if __name__ == '__main__': - sys.exit(main()) diff --git a/presentation/src/main/cpp/third_party/libvpx/test/aq_segment_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/aq_segment_test.cc deleted file mode 100644 index f7e9a118..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/aq_segment_test.cc +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" - -namespace { - -class AqSegmentTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith2Params { - protected: - AqSegmentTest() : EncoderTest(GET_PARAM(0)) {} - ~AqSegmentTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(GET_PARAM(1)); - set_cpu_used_ = GET_PARAM(2); - aq_mode_ = 0; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_); - encoder->Control(VP9E_SET_AQ_MODE, aq_mode_); - encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 100); - } - } - - int set_cpu_used_; - int aq_mode_; -}; - -// Validate that this AQ segmentation mode (AQ=1, variance_ap) -// encodes and decodes without a mismatch. -TEST_P(AqSegmentTest, TestNoMisMatchAQ1) { - cfg_.rc_min_quantizer = 8; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_target_bitrate = 300; - - aq_mode_ = 1; - - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 100); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -// Validate that this AQ segmentation mode (AQ=2, complexity_aq) -// encodes and decodes without a mismatch. -TEST_P(AqSegmentTest, TestNoMisMatchAQ2) { - cfg_.rc_min_quantizer = 8; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_target_bitrate = 300; - - aq_mode_ = 2; - - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 100); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -// Validate that this AQ segmentation mode (AQ=3, cyclic_refresh_aq) -// encodes and decodes without a mismatch. -TEST_P(AqSegmentTest, TestNoMisMatchAQ3) { - cfg_.rc_min_quantizer = 8; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_target_bitrate = 300; - - aq_mode_ = 3; - - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 100); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -VP9_INSTANTIATE_TEST_SUITE(AqSegmentTest, - ::testing::Values(::libvpx_test::kRealTime, - ::libvpx_test::kOnePassGood), - ::testing::Range(3, 9)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/avg_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/avg_test.cc deleted file mode 100644 index 271d3dc0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/avg_test.cc +++ /dev/null @@ -1,766 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "test/acm_random.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vpx/vpx_codec.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/vpx_timer.h" - -using libvpx_test::ACMRandom; - -namespace { - -template -class AverageTestBase : public ::testing::Test { - public: - AverageTestBase(int width, int height) - : width_(width), height_(height), source_data_(nullptr), - source_stride_(0), bit_depth_(8) {} - - void TearDown() override { - vpx_free(source_data_); - source_data_ = nullptr; - libvpx_test::ClearSystemState(); - } - - protected: - // Handle blocks up to 4 blocks 64x64 with stride up to 128 - static const int kDataAlignment = 16; - static const int kDataBlockSize = 64 * 128; - - void SetUp() override { - source_data_ = reinterpret_cast( - vpx_memalign(kDataAlignment, kDataBlockSize * sizeof(source_data_[0]))); - ASSERT_NE(source_data_, nullptr); - source_stride_ = (width_ + 31) & ~31; - bit_depth_ = 8; - rnd_.Reset(ACMRandom::DeterministicSeed()); - } - - // Sum Pixels - static unsigned int ReferenceAverage8x8(const Pixel *source, int pitch) { - unsigned int average = 0; - for (int h = 0; h < 8; ++h) { - for (int w = 0; w < 8; ++w) average += source[h * pitch + w]; - } - return ((average + 32) >> 6); - } - - static unsigned int ReferenceAverage4x4(const Pixel *source, int pitch) { - unsigned int average = 0; - for (int h = 0; h < 4; ++h) { - for (int w = 0; w < 4; ++w) average += source[h * pitch + w]; - } - return ((average + 8) >> 4); - } - - void FillConstant(Pixel fill_constant) { - for (int i = 0; i < width_ * height_; ++i) { - source_data_[i] = fill_constant; - } - } - - void FillRandom() { - for (int i = 0; i < width_ * height_; ++i) { - source_data_[i] = rnd_.Rand16() & ((1 << bit_depth_) - 1); - } - } - - int width_, height_; - Pixel *source_data_; - int source_stride_; - int bit_depth_; - - ACMRandom rnd_; -}; -typedef unsigned int (*AverageFunction)(const uint8_t *s, int pitch); - -typedef std::tuple AvgFunc; - -class AverageTest : public AverageTestBase, - public ::testing::WithParamInterface { - public: - AverageTest() : AverageTestBase(GET_PARAM(0), GET_PARAM(1)) {} - - protected: - void CheckAverages() { - const int block_size = GET_PARAM(3); - unsigned int expected = 0; - if (block_size == 8) { - expected = - ReferenceAverage8x8(source_data_ + GET_PARAM(2), source_stride_); - } else if (block_size == 4) { - expected = - ReferenceAverage4x4(source_data_ + GET_PARAM(2), source_stride_); - } - - ASM_REGISTER_STATE_CHECK( - GET_PARAM(4)(source_data_ + GET_PARAM(2), source_stride_)); - unsigned int actual = - GET_PARAM(4)(source_data_ + GET_PARAM(2), source_stride_); - - EXPECT_EQ(expected, actual); - } -}; - -#if CONFIG_VP9_HIGHBITDEPTH -class AverageTestHBD : public AverageTestBase, - public ::testing::WithParamInterface { - public: - AverageTestHBD() : AverageTestBase(GET_PARAM(0), GET_PARAM(1)) {} - - protected: - void CheckAverages() { - const int block_size = GET_PARAM(3); - unsigned int expected = 0; - if (block_size == 8) { - expected = - ReferenceAverage8x8(source_data_ + GET_PARAM(2), source_stride_); - } else if (block_size == 4) { - expected = - ReferenceAverage4x4(source_data_ + GET_PARAM(2), source_stride_); - } - - ASM_REGISTER_STATE_CHECK(GET_PARAM(4)( - CONVERT_TO_BYTEPTR(source_data_ + GET_PARAM(2)), source_stride_)); - unsigned int actual = GET_PARAM(4)( - CONVERT_TO_BYTEPTR(source_data_ + GET_PARAM(2)), source_stride_); - - EXPECT_EQ(expected, actual); - } -}; -#endif // CONFIG_VP9_HIGHBITDEPTH - -#if HAVE_NEON || HAVE_SSE2 || HAVE_MSA -typedef void (*IntProRowFunc)(int16_t hbuf[16], uint8_t const *ref, - const int ref_stride, const int height); - -typedef std::tuple IntProRowParam; - -class IntProRowTest : public AverageTestBase, - public ::testing::WithParamInterface { - public: - IntProRowTest() - : AverageTestBase(16, GET_PARAM(0)), hbuf_asm_(nullptr), - hbuf_c_(nullptr) { - asm_func_ = GET_PARAM(1); - c_func_ = GET_PARAM(2); - } - - protected: - void SetUp() override { - source_data_ = reinterpret_cast( - vpx_memalign(kDataAlignment, kDataBlockSize * sizeof(source_data_[0]))); - ASSERT_NE(source_data_, nullptr); - - hbuf_asm_ = reinterpret_cast( - vpx_memalign(kDataAlignment, sizeof(*hbuf_asm_) * 16)); - hbuf_c_ = reinterpret_cast( - vpx_memalign(kDataAlignment, sizeof(*hbuf_c_) * 16)); - } - - void TearDown() override { - vpx_free(source_data_); - source_data_ = nullptr; - vpx_free(hbuf_c_); - hbuf_c_ = nullptr; - vpx_free(hbuf_asm_); - hbuf_asm_ = nullptr; - } - - void RunComparison() { - ASM_REGISTER_STATE_CHECK(c_func_(hbuf_c_, source_data_, width_, height_)); - ASM_REGISTER_STATE_CHECK( - asm_func_(hbuf_asm_, source_data_, width_, height_)); - EXPECT_EQ(0, memcmp(hbuf_c_, hbuf_asm_, sizeof(*hbuf_c_) * 16)) - << "Output mismatch"; - } - - private: - IntProRowFunc asm_func_; - IntProRowFunc c_func_; - int16_t *hbuf_asm_; - int16_t *hbuf_c_; -}; -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(IntProRowTest); - -typedef int16_t (*IntProColFunc)(uint8_t const *ref, const int width); - -typedef std::tuple IntProColParam; - -class IntProColTest : public AverageTestBase, - public ::testing::WithParamInterface { - public: - IntProColTest() : AverageTestBase(GET_PARAM(0), 1), sum_asm_(0), sum_c_(0) { - asm_func_ = GET_PARAM(1); - c_func_ = GET_PARAM(2); - } - - protected: - void RunComparison() { - ASM_REGISTER_STATE_CHECK(sum_c_ = c_func_(source_data_, width_)); - ASM_REGISTER_STATE_CHECK(sum_asm_ = asm_func_(source_data_, width_)); - EXPECT_EQ(sum_c_, sum_asm_) << "Output mismatch"; - } - - private: - IntProColFunc asm_func_; - IntProColFunc c_func_; - int16_t sum_asm_; - int16_t sum_c_; -}; -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(IntProColTest); -#endif // HAVE_NEON || HAVE_SSE2 || HAVE_MSA - -typedef int (*SatdFunc)(const tran_low_t *coeffs, int length); -typedef std::tuple SatdTestParam; - -class SatdTest : public ::testing::Test, - public ::testing::WithParamInterface { - protected: - void SetUp() override { - satd_size_ = GET_PARAM(0); - satd_func_ = GET_PARAM(1); - rnd_.Reset(ACMRandom::DeterministicSeed()); - src_ = reinterpret_cast( - vpx_memalign(16, sizeof(*src_) * satd_size_)); - ASSERT_NE(src_, nullptr); - } - - void TearDown() override { - libvpx_test::ClearSystemState(); - vpx_free(src_); - } - - void FillConstant(const tran_low_t val) { - for (int i = 0; i < satd_size_; ++i) src_[i] = val; - } - - virtual void FillRandom() = 0; - - void Check(const int expected) { - int total; - ASM_REGISTER_STATE_CHECK(total = satd_func_(src_, satd_size_)); - EXPECT_EQ(expected, total); - } - - tran_low_t *GetCoeff() const { return src_; } - - int satd_size_; - ACMRandom rnd_; - tran_low_t *src_; - - private: - SatdFunc satd_func_; -}; - -class SatdLowbdTest : public SatdTest { - protected: - void FillRandom() override { - for (int i = 0; i < satd_size_; ++i) { - const int16_t tmp = rnd_.Rand16Signed(); - src_[i] = (tran_low_t)tmp; - } - } -}; - -typedef int64_t (*BlockErrorFunc)(const tran_low_t *coeff, - const tran_low_t *dqcoeff, int block_size); -typedef std::tuple BlockErrorTestFPParam; - -class BlockErrorTestFP - : public ::testing::Test, - public ::testing::WithParamInterface { - protected: - void SetUp() override { - txfm_size_ = GET_PARAM(0); - block_error_func_ = GET_PARAM(1); - rnd_.Reset(ACMRandom::DeterministicSeed()); - coeff_ = reinterpret_cast( - vpx_memalign(16, sizeof(*coeff_) * txfm_size_)); - dqcoeff_ = reinterpret_cast( - vpx_memalign(16, sizeof(*dqcoeff_) * txfm_size_)); - ASSERT_NE(coeff_, nullptr); - ASSERT_NE(dqcoeff_, nullptr); - } - - void TearDown() override { - libvpx_test::ClearSystemState(); - vpx_free(coeff_); - vpx_free(dqcoeff_); - } - - void FillConstant(const tran_low_t coeff_val, const tran_low_t dqcoeff_val) { - for (int i = 0; i < txfm_size_; ++i) coeff_[i] = coeff_val; - for (int i = 0; i < txfm_size_; ++i) dqcoeff_[i] = dqcoeff_val; - } - - void FillRandom() { - // Just two fixed seeds - rnd_.Reset(0xb0b9); - for (int i = 0; i < txfm_size_; ++i) coeff_[i] = rnd_.Rand16() >> 1; - rnd_.Reset(0xb0c8); - for (int i = 0; i < txfm_size_; ++i) dqcoeff_[i] = rnd_.Rand16() >> 1; - } - - void Check(const int64_t expected) { - int64_t total; - ASM_REGISTER_STATE_CHECK( - total = block_error_func_(coeff_, dqcoeff_, txfm_size_)); - EXPECT_EQ(expected, total); - } - - tran_low_t *GetCoeff() const { return coeff_; } - - tran_low_t *GetDQCoeff() const { return dqcoeff_; } - - int txfm_size_; - - private: - tran_low_t *coeff_; - tran_low_t *dqcoeff_; - BlockErrorFunc block_error_func_; - ACMRandom rnd_; -}; - -TEST_P(AverageTest, MinValue) { - FillConstant(0); - CheckAverages(); -} - -TEST_P(AverageTest, MaxValue) { - FillConstant(255); - CheckAverages(); -} - -TEST_P(AverageTest, Random) { - // The reference frame, but not the source frame, may be unaligned for - // certain types of searches. - for (int i = 0; i < 1000; i++) { - FillRandom(); - CheckAverages(); - } -} -#if CONFIG_VP9_HIGHBITDEPTH -TEST_P(AverageTestHBD, MinValue) { - FillConstant(0); - CheckAverages(); -} - -TEST_P(AverageTestHBD, MaxValue) { - FillConstant((1 << VPX_BITS_12) - 1); - CheckAverages(); -} - -TEST_P(AverageTestHBD, Random) { - bit_depth_ = VPX_BITS_12; - // The reference frame, but not the source frame, may be unaligned for - // certain types of searches. - for (int i = 0; i < 1000; i++) { - FillRandom(); - CheckAverages(); - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -#if HAVE_NEON || HAVE_SSE2 || HAVE_MSA -TEST_P(IntProRowTest, MinValue) { - FillConstant(0); - RunComparison(); -} - -TEST_P(IntProRowTest, MaxValue) { - FillConstant(255); - RunComparison(); -} - -TEST_P(IntProRowTest, Random) { - FillRandom(); - RunComparison(); -} - -TEST_P(IntProColTest, MinValue) { - FillConstant(0); - RunComparison(); -} - -TEST_P(IntProColTest, MaxValue) { - FillConstant(255); - RunComparison(); -} - -TEST_P(IntProColTest, Random) { - FillRandom(); - RunComparison(); -} -#endif - -TEST_P(SatdLowbdTest, MinValue) { - const int kMin = -32640; - const int expected = -kMin * satd_size_; - FillConstant(kMin); - Check(expected); -} - -TEST_P(SatdLowbdTest, MaxValue) { - const int kMax = 32640; - const int expected = kMax * satd_size_; - FillConstant(kMax); - Check(expected); -} - -TEST_P(SatdLowbdTest, Random) { - int expected; - switch (satd_size_) { - case 16: expected = 261036; break; - case 64: expected = 991732; break; - case 256: expected = 4136358; break; - case 1024: expected = 16677592; break; - default: - FAIL() << "Invalid satd size (" << satd_size_ - << ") valid: 16/64/256/1024"; - } - FillRandom(); - Check(expected); -} - -TEST_P(SatdLowbdTest, DISABLED_Speed) { - const int kCountSpeedTestBlock = 20000; - vpx_usec_timer timer; - const int blocksize = GET_PARAM(0); - FillRandom(); - tran_low_t *coeff = GetCoeff(); - - vpx_usec_timer_start(&timer); - for (int i = 0; i < kCountSpeedTestBlock; ++i) { - GET_PARAM(1)(coeff, blocksize); - } - vpx_usec_timer_mark(&timer); - const int elapsed_time = static_cast(vpx_usec_timer_elapsed(&timer)); - printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time); -} - -#if CONFIG_VP9_HIGHBITDEPTH -class SatdHighbdTest : public SatdTest { - protected: - void FillRandom() override { - for (int i = 0; i < satd_size_; ++i) { - src_[i] = rnd_.Rand20Signed(); - } - } -}; - -TEST_P(SatdHighbdTest, MinValue) { - const int kMin = -524280; - const int expected = -kMin * satd_size_; - FillConstant(kMin); - Check(expected); -} - -TEST_P(SatdHighbdTest, MaxValue) { - const int kMax = 524280; - const int expected = kMax * satd_size_; - FillConstant(kMax); - Check(expected); -} - -TEST_P(SatdHighbdTest, Random) { - int expected; - switch (satd_size_) { - case 16: expected = 5249712; break; - case 64: expected = 18362120; break; - case 256: expected = 66100520; break; - case 1024: expected = 266094734; break; - default: - FAIL() << "Invalid satd size (" << satd_size_ - << ") valid: 16/64/256/1024"; - } - FillRandom(); - Check(expected); -} - -TEST_P(SatdHighbdTest, DISABLED_Speed) { - const int kCountSpeedTestBlock = 20000; - vpx_usec_timer timer; - const int blocksize = GET_PARAM(0); - FillRandom(); - tran_low_t *coeff = GetCoeff(); - - vpx_usec_timer_start(&timer); - for (int i = 0; i < kCountSpeedTestBlock; ++i) { - GET_PARAM(1)(coeff, blocksize); - } - vpx_usec_timer_mark(&timer); - const int elapsed_time = static_cast(vpx_usec_timer_elapsed(&timer)); - printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -TEST_P(BlockErrorTestFP, MinValue) { - const int64_t kMin = -32640; - const int64_t expected = kMin * kMin * txfm_size_; - FillConstant(kMin, 0); - Check(expected); -} - -TEST_P(BlockErrorTestFP, MaxValue) { - const int64_t kMax = 32640; - const int64_t expected = kMax * kMax * txfm_size_; - FillConstant(kMax, 0); - Check(expected); -} - -TEST_P(BlockErrorTestFP, Random) { - int64_t expected; - switch (txfm_size_) { - case 16: expected = 2051681432; break; - case 64: expected = 11075114379; break; - case 256: expected = 44386271116; break; - case 1024: expected = 184774996089; break; - default: - FAIL() << "Invalid satd size (" << txfm_size_ - << ") valid: 16/64/256/1024"; - } - FillRandom(); - Check(expected); -} - -TEST_P(BlockErrorTestFP, DISABLED_Speed) { - const int kCountSpeedTestBlock = 20000; - vpx_usec_timer timer; - const int blocksize = GET_PARAM(0); - FillRandom(); - tran_low_t *coeff = GetCoeff(); - tran_low_t *dqcoeff = GetDQCoeff(); - - vpx_usec_timer_start(&timer); - for (int i = 0; i < kCountSpeedTestBlock; ++i) { - GET_PARAM(1)(coeff, dqcoeff, blocksize); - } - vpx_usec_timer_mark(&timer); - const int elapsed_time = static_cast(vpx_usec_timer_elapsed(&timer)); - printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time); -} - -using std::make_tuple; - -INSTANTIATE_TEST_SUITE_P( - C, AverageTest, - ::testing::Values(make_tuple(16, 16, 1, 8, &vpx_avg_8x8_c), - make_tuple(16, 16, 1, 4, &vpx_avg_4x4_c))); - -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - C, AverageTestHBD, - ::testing::Values(make_tuple(16, 16, 1, 8, &vpx_highbd_avg_8x8_c), - make_tuple(16, 16, 1, 4, &vpx_highbd_avg_4x4_c))); - -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P( - SSE2, AverageTestHBD, - ::testing::Values(make_tuple(16, 16, 1, 8, &vpx_highbd_avg_8x8_sse2), - make_tuple(16, 16, 1, 4, &vpx_highbd_avg_4x4_sse2))); -#endif // HAVE_SSE2 - -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P( - NEON, AverageTestHBD, - ::testing::Values(make_tuple(16, 16, 1, 8, &vpx_highbd_avg_8x8_neon), - make_tuple(16, 16, 1, 4, &vpx_highbd_avg_4x4_neon))); -#endif // HAVE_NEON - -INSTANTIATE_TEST_SUITE_P(C, SatdHighbdTest, - ::testing::Values(make_tuple(16, &vpx_satd_c), - make_tuple(64, &vpx_satd_c), - make_tuple(256, &vpx_satd_c), - make_tuple(1024, &vpx_satd_c))); -#endif // CONFIG_VP9_HIGHBITDEPTH - -INSTANTIATE_TEST_SUITE_P(C, SatdLowbdTest, - ::testing::Values(make_tuple(16, &vpx_satd_c), - make_tuple(64, &vpx_satd_c), - make_tuple(256, &vpx_satd_c), - make_tuple(1024, &vpx_satd_c))); - -INSTANTIATE_TEST_SUITE_P( - C, BlockErrorTestFP, - ::testing::Values(make_tuple(16, &vp9_block_error_fp_c), - make_tuple(64, &vp9_block_error_fp_c), - make_tuple(256, &vp9_block_error_fp_c), - make_tuple(1024, &vp9_block_error_fp_c))); - -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P( - SSE2, AverageTest, - ::testing::Values(make_tuple(16, 16, 0, 8, &vpx_avg_8x8_sse2), - make_tuple(16, 16, 5, 8, &vpx_avg_8x8_sse2), - make_tuple(32, 32, 15, 8, &vpx_avg_8x8_sse2), - make_tuple(16, 16, 0, 4, &vpx_avg_4x4_sse2), - make_tuple(16, 16, 5, 4, &vpx_avg_4x4_sse2), - make_tuple(32, 32, 15, 4, &vpx_avg_4x4_sse2))); - -INSTANTIATE_TEST_SUITE_P( - SSE2, IntProRowTest, - ::testing::Values(make_tuple(16, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c), - make_tuple(32, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c), - make_tuple(64, &vpx_int_pro_row_sse2, - &vpx_int_pro_row_c))); - -INSTANTIATE_TEST_SUITE_P( - SSE2, IntProColTest, - ::testing::Values(make_tuple(16, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c), - make_tuple(32, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c), - make_tuple(64, &vpx_int_pro_col_sse2, - &vpx_int_pro_col_c))); - -INSTANTIATE_TEST_SUITE_P(SSE2, SatdLowbdTest, - ::testing::Values(make_tuple(16, &vpx_satd_sse2), - make_tuple(64, &vpx_satd_sse2), - make_tuple(256, &vpx_satd_sse2), - make_tuple(1024, &vpx_satd_sse2))); - -INSTANTIATE_TEST_SUITE_P( - SSE2, BlockErrorTestFP, - ::testing::Values(make_tuple(16, &vp9_block_error_fp_sse2), - make_tuple(64, &vp9_block_error_fp_sse2), - make_tuple(256, &vp9_block_error_fp_sse2), - make_tuple(1024, &vp9_block_error_fp_sse2))); -#endif // HAVE_SSE2 - -#if HAVE_AVX2 -INSTANTIATE_TEST_SUITE_P(AVX2, SatdLowbdTest, - ::testing::Values(make_tuple(16, &vpx_satd_avx2), - make_tuple(64, &vpx_satd_avx2), - make_tuple(256, &vpx_satd_avx2), - make_tuple(1024, &vpx_satd_avx2))); - -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - AVX2, SatdHighbdTest, - ::testing::Values(make_tuple(16, &vpx_highbd_satd_avx2), - make_tuple(64, &vpx_highbd_satd_avx2), - make_tuple(256, &vpx_highbd_satd_avx2), - make_tuple(1024, &vpx_highbd_satd_avx2))); -#endif // CONFIG_VP9_HIGHBITDEPTH - -INSTANTIATE_TEST_SUITE_P( - AVX2, BlockErrorTestFP, - ::testing::Values(make_tuple(16, &vp9_block_error_fp_avx2), - make_tuple(64, &vp9_block_error_fp_avx2), - make_tuple(256, &vp9_block_error_fp_avx2), - make_tuple(1024, &vp9_block_error_fp_avx2))); -#endif - -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P( - NEON, AverageTest, - ::testing::Values(make_tuple(16, 16, 0, 8, &vpx_avg_8x8_neon), - make_tuple(16, 16, 5, 8, &vpx_avg_8x8_neon), - make_tuple(32, 32, 15, 8, &vpx_avg_8x8_neon), - make_tuple(16, 16, 0, 4, &vpx_avg_4x4_neon), - make_tuple(16, 16, 5, 4, &vpx_avg_4x4_neon), - make_tuple(32, 32, 15, 4, &vpx_avg_4x4_neon))); - -INSTANTIATE_TEST_SUITE_P( - NEON, IntProRowTest, - ::testing::Values(make_tuple(16, &vpx_int_pro_row_neon, &vpx_int_pro_row_c), - make_tuple(32, &vpx_int_pro_row_neon, &vpx_int_pro_row_c), - make_tuple(64, &vpx_int_pro_row_neon, - &vpx_int_pro_row_c))); - -INSTANTIATE_TEST_SUITE_P( - NEON, IntProColTest, - ::testing::Values(make_tuple(16, &vpx_int_pro_col_neon, &vpx_int_pro_col_c), - make_tuple(32, &vpx_int_pro_col_neon, &vpx_int_pro_col_c), - make_tuple(64, &vpx_int_pro_col_neon, - &vpx_int_pro_col_c))); - -INSTANTIATE_TEST_SUITE_P(NEON, SatdLowbdTest, - ::testing::Values(make_tuple(16, &vpx_satd_neon), - make_tuple(64, &vpx_satd_neon), - make_tuple(256, &vpx_satd_neon), - make_tuple(1024, &vpx_satd_neon))); - -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - NEON, SatdHighbdTest, - ::testing::Values(make_tuple(16, &vpx_highbd_satd_neon), - make_tuple(64, &vpx_highbd_satd_neon), - make_tuple(256, &vpx_highbd_satd_neon), - make_tuple(1024, &vpx_highbd_satd_neon))); -#endif // CONFIG_VP9_HIGHBITDEPTH - -INSTANTIATE_TEST_SUITE_P( - NEON, BlockErrorTestFP, - ::testing::Values(make_tuple(16, &vp9_block_error_fp_neon), - make_tuple(64, &vp9_block_error_fp_neon), - make_tuple(256, &vp9_block_error_fp_neon), - make_tuple(1024, &vp9_block_error_fp_neon))); -#endif // HAVE_NEON - -#if HAVE_SVE -INSTANTIATE_TEST_SUITE_P( - SVE, BlockErrorTestFP, - ::testing::Values(make_tuple(16, &vp9_block_error_fp_sve), - make_tuple(64, &vp9_block_error_fp_sve), - make_tuple(256, &vp9_block_error_fp_sve), - make_tuple(1024, &vp9_block_error_fp_sve))); -#endif // HAVE_SVE - -#if HAVE_MSA -INSTANTIATE_TEST_SUITE_P( - MSA, AverageTest, - ::testing::Values(make_tuple(16, 16, 0, 8, &vpx_avg_8x8_msa), - make_tuple(16, 16, 5, 8, &vpx_avg_8x8_msa), - make_tuple(32, 32, 15, 8, &vpx_avg_8x8_msa), - make_tuple(16, 16, 0, 4, &vpx_avg_4x4_msa), - make_tuple(16, 16, 5, 4, &vpx_avg_4x4_msa), - make_tuple(32, 32, 15, 4, &vpx_avg_4x4_msa))); - -INSTANTIATE_TEST_SUITE_P( - MSA, IntProRowTest, - ::testing::Values(make_tuple(16, &vpx_int_pro_row_msa, &vpx_int_pro_row_c), - make_tuple(32, &vpx_int_pro_row_msa, &vpx_int_pro_row_c), - make_tuple(64, &vpx_int_pro_row_msa, - &vpx_int_pro_row_c))); - -INSTANTIATE_TEST_SUITE_P( - MSA, IntProColTest, - ::testing::Values(make_tuple(16, &vpx_int_pro_col_msa, &vpx_int_pro_col_c), - make_tuple(32, &vpx_int_pro_col_msa, &vpx_int_pro_col_c), - make_tuple(64, &vpx_int_pro_col_msa, - &vpx_int_pro_col_c))); - -// TODO(jingning): Remove the highbitdepth flag once the SIMD functions are -// in place. -#if !CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P(MSA, SatdLowbdTest, - ::testing::Values(make_tuple(16, &vpx_satd_msa), - make_tuple(64, &vpx_satd_msa), - make_tuple(256, &vpx_satd_msa), - make_tuple(1024, &vpx_satd_msa))); -#endif // !CONFIG_VP9_HIGHBITDEPTH -#endif // HAVE_MSA - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/bench.cc b/presentation/src/main/cpp/third_party/libvpx/test/bench.cc deleted file mode 100644 index 0783f2a7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/bench.cc +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "test/bench.h" -#include "vpx_ports/vpx_timer.h" - -void AbstractBench::RunNTimes(int n) { - for (int r = 0; r < VPX_BENCH_ROBUST_ITER; r++) { - vpx_usec_timer timer; - vpx_usec_timer_start(&timer); - for (int j = 0; j < n; ++j) { - Run(); - } - vpx_usec_timer_mark(&timer); - times_[r] = static_cast(vpx_usec_timer_elapsed(&timer)); - } -} - -void AbstractBench::PrintMedian(const char *title) { - std::sort(times_, times_ + VPX_BENCH_ROBUST_ITER); - const int med = times_[VPX_BENCH_ROBUST_ITER >> 1]; - int sad = 0; - for (int t = 0; t < VPX_BENCH_ROBUST_ITER; t++) { - sad += abs(times_[t] - med); - } - printf("[%10s] %s %.1f ms ( ±%.1f ms )\n", "BENCH ", title, med / 1000.0, - sad / (VPX_BENCH_ROBUST_ITER * 1000.0)); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/test/bench.h b/presentation/src/main/cpp/third_party/libvpx/test/bench.h deleted file mode 100644 index 203e4d24..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/bench.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_TEST_BENCH_H_ -#define VPX_TEST_BENCH_H_ - -// Number of iterations used to compute median run time. -#define VPX_BENCH_ROBUST_ITER 15 - -class AbstractBench { - public: - virtual ~AbstractBench() = default; - - void RunNTimes(int n); - void PrintMedian(const char *title); - - protected: - // Implement this method and put the code to benchmark in it. - virtual void Run() = 0; - - private: - int times_[VPX_BENCH_ROBUST_ITER]; -}; - -#endif // VPX_TEST_BENCH_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/blockiness_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/blockiness_test.cc deleted file mode 100644 index 1415d419..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/blockiness_test.cc +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vpx_config.h" -#if CONFIG_VP9_ENCODER -#include "./vp9_rtcd.h" -#endif - -#include "test/acm_random.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" - -#include "vpx_mem/vpx_mem.h" -#include "vp9/encoder/vp9_blockiness.h" - -using libvpx_test::ACMRandom; - -namespace { -class BlockinessTestBase : public ::testing::Test { - public: - BlockinessTestBase(int width, int height) : width_(width), height_(height) {} - - static void SetUpTestSuite() { - source_data_ = reinterpret_cast( - vpx_memalign(kDataAlignment, kDataBufferSize)); - reference_data_ = reinterpret_cast( - vpx_memalign(kDataAlignment, kDataBufferSize)); - } - - static void TearDownTestSuite() { - vpx_free(source_data_); - source_data_ = nullptr; - vpx_free(reference_data_); - reference_data_ = nullptr; - } - - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - // Handle frames up to 640x480 - static const int kDataAlignment = 16; - static const int kDataBufferSize = 640 * 480; - - void SetUp() override { - source_stride_ = (width_ + 31) & ~31; - reference_stride_ = width_ * 2; - rnd_.Reset(ACMRandom::DeterministicSeed()); - } - - void FillConstant(uint8_t *data, int stride, uint8_t fill_constant, int width, - int height) { - for (int h = 0; h < height; ++h) { - for (int w = 0; w < width; ++w) { - data[h * stride + w] = fill_constant; - } - } - } - - void FillConstant(uint8_t *data, int stride, uint8_t fill_constant) { - FillConstant(data, stride, fill_constant, width_, height_); - } - - void FillRandom(uint8_t *data, int stride, int width, int height) { - for (int h = 0; h < height; ++h) { - for (int w = 0; w < width; ++w) { - data[h * stride + w] = rnd_.Rand8(); - } - } - } - - void FillRandom(uint8_t *data, int stride) { - FillRandom(data, stride, width_, height_); - } - - void FillRandomBlocky(uint8_t *data, int stride) { - for (int h = 0; h < height_; h += 4) { - for (int w = 0; w < width_; w += 4) { - FillRandom(data + h * stride + w, stride, 4, 4); - } - } - } - - void FillCheckerboard(uint8_t *data, int stride) { - for (int h = 0; h < height_; h += 4) { - for (int w = 0; w < width_; w += 4) { - if (((h / 4) ^ (w / 4)) & 1) { - FillConstant(data + h * stride + w, stride, 255, 4, 4); - } else { - FillConstant(data + h * stride + w, stride, 0, 4, 4); - } - } - } - } - - void Blur(uint8_t *data, int stride, int taps) { - int sum = 0; - int half_taps = taps / 2; - for (int h = 0; h < height_; ++h) { - for (int w = 0; w < taps; ++w) { - sum += data[w + h * stride]; - } - for (int w = taps; w < width_; ++w) { - sum += data[w + h * stride] - data[w - taps + h * stride]; - data[w - half_taps + h * stride] = (sum + half_taps) / taps; - } - } - for (int w = 0; w < width_; ++w) { - for (int h = 0; h < taps; ++h) { - sum += data[h + w * stride]; - } - for (int h = taps; h < height_; ++h) { - sum += data[w + h * stride] - data[(h - taps) * stride + w]; - data[(h - half_taps) * stride + w] = (sum + half_taps) / taps; - } - } - } - int width_, height_; - static uint8_t *source_data_; - int source_stride_; - static uint8_t *reference_data_; - int reference_stride_; - - ACMRandom rnd_; -}; - -#if CONFIG_VP9_ENCODER -typedef std::tuple BlockinessParam; -class BlockinessVP9Test - : public BlockinessTestBase, - public ::testing::WithParamInterface { - public: - BlockinessVP9Test() : BlockinessTestBase(GET_PARAM(0), GET_PARAM(1)) {} - - protected: - double GetBlockiness() const { - return vp9_get_blockiness(source_data_, source_stride_, reference_data_, - reference_stride_, width_, height_); - } -}; -#endif // CONFIG_VP9_ENCODER - -uint8_t *BlockinessTestBase::source_data_ = nullptr; -uint8_t *BlockinessTestBase::reference_data_ = nullptr; - -#if CONFIG_VP9_ENCODER -TEST_P(BlockinessVP9Test, SourceBlockierThanReference) { - // Source is blockier than reference. - FillRandomBlocky(source_data_, source_stride_); - FillConstant(reference_data_, reference_stride_, 128); - const double super_blocky = GetBlockiness(); - - EXPECT_DOUBLE_EQ(0.0, super_blocky) - << "Blocky source should produce 0 blockiness."; -} - -TEST_P(BlockinessVP9Test, ReferenceBlockierThanSource) { - // Source is blockier than reference. - FillConstant(source_data_, source_stride_, 128); - FillRandomBlocky(reference_data_, reference_stride_); - const double super_blocky = GetBlockiness(); - - EXPECT_GT(super_blocky, 0.0) - << "Blocky reference should score high for blockiness."; -} - -TEST_P(BlockinessVP9Test, BlurringDecreasesBlockiness) { - // Source is blockier than reference. - FillConstant(source_data_, source_stride_, 128); - FillRandomBlocky(reference_data_, reference_stride_); - const double super_blocky = GetBlockiness(); - - Blur(reference_data_, reference_stride_, 4); - const double less_blocky = GetBlockiness(); - - EXPECT_GT(super_blocky, less_blocky) - << "A straight blur should decrease blockiness."; -} - -TEST_P(BlockinessVP9Test, WorstCaseBlockiness) { - // Source is blockier than reference. - FillConstant(source_data_, source_stride_, 128); - FillCheckerboard(reference_data_, reference_stride_); - - const double super_blocky = GetBlockiness(); - - Blur(reference_data_, reference_stride_, 4); - const double less_blocky = GetBlockiness(); - - EXPECT_GT(super_blocky, less_blocky) - << "A straight blur should decrease blockiness."; -} -#endif // CONFIG_VP9_ENCODER - -using std::make_tuple; - -//------------------------------------------------------------------------------ -// C functions - -#if CONFIG_VP9_ENCODER -const BlockinessParam c_vp9_tests[] = { make_tuple(320, 240), - make_tuple(318, 242), - make_tuple(318, 238) }; -INSTANTIATE_TEST_SUITE_P(C, BlockinessVP9Test, - ::testing::ValuesIn(c_vp9_tests)); -#endif - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/borders_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/borders_test.cc deleted file mode 100644 index 57ee179a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/borders_test.cc +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" -#include "vpx_config.h" - -namespace { - -class BordersTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWithParam { - protected: - BordersTest() : EncoderTest(GET_PARAM(0)) {} - ~BordersTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(GET_PARAM(1)); - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, 1); - encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); - encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7); - encoder->Control(VP8E_SET_ARNR_STRENGTH, 5); - encoder->Control(VP8E_SET_ARNR_TYPE, 3); - } - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) { - } - } -}; - -TEST_P(BordersTest, TestEncodeHighBitrate) { - // Validate that this non multiple of 64 wide clip encodes and decodes - // without a mismatch when passing in a very low max q. This pushes - // the encoder to producing lots of big partitions which will likely - // extend into the border and test the border condition. - cfg_.g_lag_in_frames = 25; - cfg_.rc_2pass_vbr_minsection_pct = 5; - cfg_.rc_2pass_vbr_maxsection_pct = 2000; - cfg_.rc_target_bitrate = 2000; - cfg_.rc_max_quantizer = 10; - - ::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0, - 40); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} -TEST_P(BordersTest, TestLowBitrate) { - // Validate that this clip encodes and decodes without a mismatch - // when passing in a very high min q. This pushes the encoder to producing - // lots of small partitions which might will test the other condition. - - cfg_.g_lag_in_frames = 25; - cfg_.rc_2pass_vbr_minsection_pct = 5; - cfg_.rc_2pass_vbr_maxsection_pct = 2000; - cfg_.rc_target_bitrate = 200; - cfg_.rc_min_quantizer = 40; - - ::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0, - 40); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -#if CONFIG_REALTIME_ONLY -VP9_INSTANTIATE_TEST_SUITE(BordersTest, - ::testing::Values(::libvpx_test::kRealTime)); -#else -VP9_INSTANTIATE_TEST_SUITE(BordersTest, - ::testing::Values(::libvpx_test::kTwoPassGood)); -#endif -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/buffer.h b/presentation/src/main/cpp/third_party/libvpx/test/buffer.h deleted file mode 100644 index f2846323..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/buffer.h +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_TEST_BUFFER_H_ -#define VPX_TEST_BUFFER_H_ - -#include - -#include - -#include "gtest/gtest.h" - -#include "test/acm_random.h" -#include "vpx/vpx_integer.h" -#include "vpx_mem/vpx_mem.h" - -namespace libvpx_test { - -template -class Buffer { - public: - Buffer(int width, int height, int top_padding, int left_padding, - int right_padding, int bottom_padding) - : width_(width), height_(height), top_padding_(top_padding), - left_padding_(left_padding), right_padding_(right_padding), - bottom_padding_(bottom_padding), alignment_(0), padding_value_(0), - stride_(0), raw_size_(0), num_elements_(0), raw_buffer_(nullptr) {} - - Buffer(int width, int height, int top_padding, int left_padding, - int right_padding, int bottom_padding, unsigned int alignment) - : width_(width), height_(height), top_padding_(top_padding), - left_padding_(left_padding), right_padding_(right_padding), - bottom_padding_(bottom_padding), alignment_(alignment), - padding_value_(0), stride_(0), raw_size_(0), num_elements_(0), - raw_buffer_(nullptr) {} - - Buffer(int width, int height, int padding) - : width_(width), height_(height), top_padding_(padding), - left_padding_(padding), right_padding_(padding), - bottom_padding_(padding), alignment_(0), padding_value_(0), stride_(0), - raw_size_(0), num_elements_(0), raw_buffer_(nullptr) {} - - Buffer(int width, int height, int padding, unsigned int alignment) - : width_(width), height_(height), top_padding_(padding), - left_padding_(padding), right_padding_(padding), - bottom_padding_(padding), alignment_(alignment), padding_value_(0), - stride_(0), raw_size_(0), num_elements_(0), raw_buffer_(nullptr) {} - - ~Buffer() { - if (alignment_) { - vpx_free(raw_buffer_); - } else { - delete[] raw_buffer_; - } - } - - T *TopLeftPixel() const; - - int stride() const { return stride_; } - - // Set the buffer (excluding padding) to 'value'. - void Set(const T value); - - // Set the buffer (excluding padding) to the output of ACMRandom function - // 'rand_func'. - void Set(ACMRandom *rand_class, T (ACMRandom::*rand_func)()); - - // Set the buffer (excluding padding) to the output of ACMRandom function - // 'RandRange' with range 'low' to 'high' which typically must be within - // testing::internal::Random::kMaxRange (1u << 31). However, because we want - // to allow negative low (and high) values, it is restricted to INT32_MAX - // here. - void Set(ACMRandom *rand_class, const T low, const T high); - - // Copy the contents of Buffer 'a' (excluding padding). - void CopyFrom(const Buffer &a); - - void DumpBuffer() const; - - // Highlight the differences between two buffers if they are the same size. - void PrintDifference(const Buffer &a) const; - - bool HasPadding() const; - - // Sets all the values in the buffer to 'padding_value'. - void SetPadding(const T padding_value); - - // Checks if all the values (excluding padding) are equal to 'value' if the - // Buffers are the same size. - bool CheckValues(const T value) const; - - // Check that padding matches the expected value or there is no padding. - bool CheckPadding() const; - - // Compare the non-padding portion of two buffers if they are the same size. - bool CheckValues(const Buffer &a) const; - - bool Init() { - if (raw_buffer_ != nullptr) return false; - EXPECT_GT(width_, 0); - EXPECT_GT(height_, 0); - EXPECT_GE(top_padding_, 0); - EXPECT_GE(left_padding_, 0); - EXPECT_GE(right_padding_, 0); - EXPECT_GE(bottom_padding_, 0); - stride_ = left_padding_ + width_ + right_padding_; - num_elements_ = stride_ * (top_padding_ + height_ + bottom_padding_); - raw_size_ = num_elements_ * sizeof(T); - if (alignment_) { - EXPECT_GE(alignment_, sizeof(T)); - // Ensure alignment of the first value will be preserved. - EXPECT_EQ((left_padding_ * sizeof(T)) % alignment_, 0u); - // Ensure alignment of the subsequent rows will be preserved when there is - // a stride. - if (stride_ != width_) { - EXPECT_EQ((stride_ * sizeof(T)) % alignment_, 0u); - } - raw_buffer_ = reinterpret_cast(vpx_memalign(alignment_, raw_size_)); - } else { - raw_buffer_ = new (std::nothrow) T[num_elements_]; - } - EXPECT_NE(raw_buffer_, nullptr); - SetPadding(std::numeric_limits::max()); - return !::testing::Test::HasFailure(); - } - - private: - bool BufferSizesMatch(const Buffer &a) const; - - const int width_; - const int height_; - const int top_padding_; - const int left_padding_; - const int right_padding_; - const int bottom_padding_; - const unsigned int alignment_; - T padding_value_; - int stride_; - int raw_size_; - int num_elements_; - T *raw_buffer_; -}; - -template -T *Buffer::TopLeftPixel() const { - if (!raw_buffer_) return nullptr; - return raw_buffer_ + (top_padding_ * stride_) + left_padding_; -} - -template -void Buffer::Set(const T value) { - if (!raw_buffer_) return; - T *src = TopLeftPixel(); - for (int height = 0; height < height_; ++height) { - for (int width = 0; width < width_; ++width) { - src[width] = value; - } - src += stride_; - } -} - -template -void Buffer::Set(ACMRandom *rand_class, T (ACMRandom::*rand_func)()) { - if (!raw_buffer_) return; - T *src = TopLeftPixel(); - for (int height = 0; height < height_; ++height) { - for (int width = 0; width < width_; ++width) { - src[width] = (*rand_class.*rand_func)(); - } - src += stride_; - } -} - -template -void Buffer::Set(ACMRandom *rand_class, const T low, const T high) { - if (!raw_buffer_) return; - - EXPECT_LE(low, high); - EXPECT_LE(static_cast(high) - low, - std::numeric_limits::max()); - - T *src = TopLeftPixel(); - for (int height = 0; height < height_; ++height) { - for (int width = 0; width < width_; ++width) { - // 'low' will be promoted to unsigned given the return type of RandRange. - // Store the value as an int to avoid unsigned overflow warnings when - // 'low' is negative. - const int32_t value = - static_cast((*rand_class).RandRange(high - low)); - src[width] = static_cast(value + low); - } - src += stride_; - } -} - -template -void Buffer::CopyFrom(const Buffer &a) { - if (!raw_buffer_) return; - if (!BufferSizesMatch(a)) return; - - T *a_src = a.TopLeftPixel(); - T *b_src = this->TopLeftPixel(); - for (int height = 0; height < height_; ++height) { - for (int width = 0; width < width_; ++width) { - b_src[width] = a_src[width]; - } - a_src += a.stride(); - b_src += this->stride(); - } -} - -template -void Buffer::DumpBuffer() const { - if (!raw_buffer_) return; - for (int height = 0; height < height_ + top_padding_ + bottom_padding_; - ++height) { - for (int width = 0; width < stride_; ++width) { - printf("%4d", raw_buffer_[height + width * stride_]); - } - printf("\n"); - } -} - -template -bool Buffer::HasPadding() const { - if (!raw_buffer_) return false; - return top_padding_ || left_padding_ || right_padding_ || bottom_padding_; -} - -template -void Buffer::PrintDifference(const Buffer &a) const { - if (!raw_buffer_) return; - if (!BufferSizesMatch(a)) return; - - T *a_src = a.TopLeftPixel(); - T *b_src = TopLeftPixel(); - - printf("This buffer:\n"); - for (int height = 0; height < height_; ++height) { - for (int width = 0; width < width_; ++width) { - if (a_src[width] != b_src[width]) { - printf("*%3d", b_src[width]); - } else { - printf("%4d", b_src[width]); - } - } - printf("\n"); - a_src += a.stride(); - b_src += this->stride(); - } - - a_src = a.TopLeftPixel(); - b_src = TopLeftPixel(); - - printf("Reference buffer:\n"); - for (int height = 0; height < height_; ++height) { - for (int width = 0; width < width_; ++width) { - if (a_src[width] != b_src[width]) { - printf("*%3d", a_src[width]); - } else { - printf("%4d", a_src[width]); - } - } - printf("\n"); - a_src += a.stride(); - b_src += this->stride(); - } -} - -template -void Buffer::SetPadding(const T padding_value) { - if (!raw_buffer_) return; - padding_value_ = padding_value; - - T *src = raw_buffer_; - for (int i = 0; i < num_elements_; ++i) { - src[i] = padding_value; - } -} - -template -bool Buffer::CheckValues(const T value) const { - if (!raw_buffer_) return false; - T *src = TopLeftPixel(); - for (int height = 0; height < height_; ++height) { - for (int width = 0; width < width_; ++width) { - if (value != src[width]) { - return false; - } - } - src += stride_; - } - return true; -} - -template -bool Buffer::CheckPadding() const { - if (!raw_buffer_) return false; - if (!HasPadding()) return true; - - // Top padding. - T const *top = raw_buffer_; - for (int i = 0; i < stride_ * top_padding_; ++i) { - if (padding_value_ != top[i]) { - return false; - } - } - - // Left padding. - T const *left = TopLeftPixel() - left_padding_; - for (int height = 0; height < height_; ++height) { - for (int width = 0; width < left_padding_; ++width) { - if (padding_value_ != left[width]) { - return false; - } - } - left += stride_; - } - - // Right padding. - T const *right = TopLeftPixel() + width_; - for (int height = 0; height < height_; ++height) { - for (int width = 0; width < right_padding_; ++width) { - if (padding_value_ != right[width]) { - return false; - } - } - right += stride_; - } - - // Bottom padding - T const *bottom = raw_buffer_ + (top_padding_ + height_) * stride_; - for (int i = 0; i < stride_ * bottom_padding_; ++i) { - if (padding_value_ != bottom[i]) { - return false; - } - } - - return true; -} - -template -bool Buffer::CheckValues(const Buffer &a) const { - if (!raw_buffer_) return false; - if (!BufferSizesMatch(a)) return false; - - T *a_src = a.TopLeftPixel(); - T *b_src = this->TopLeftPixel(); - for (int height = 0; height < height_; ++height) { - for (int width = 0; width < width_; ++width) { - if (a_src[width] != b_src[width]) { - return false; - } - } - a_src += a.stride(); - b_src += this->stride(); - } - return true; -} - -template -bool Buffer::BufferSizesMatch(const Buffer &a) const { - if (!raw_buffer_) return false; - if (a.width_ != this->width_ || a.height_ != this->height_) { - printf( - "Reference buffer of size %dx%d does not match this buffer which is " - "size %dx%d\n", - a.width_, a.height_, this->width_, this->height_); - return false; - } - - return true; -} -} // namespace libvpx_test -#endif // VPX_TEST_BUFFER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/byte_alignment_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/byte_alignment_test.cc deleted file mode 100644 index ba6fffc5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/byte_alignment_test.cc +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "test/codec_factory.h" -#include "test/decode_test_driver.h" -#include "test/md5_helper.h" -#include "test/util.h" -#if CONFIG_WEBM_IO -#include "test/webm_video_source.h" -#endif - -namespace { - -#if CONFIG_WEBM_IO - -const int kLegacyByteAlignment = 0; -const int kLegacyYPlaneByteAlignment = 32; -const int kNumPlanesToCheck = 3; -const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm"; -const char kVP9Md5File[] = "vp90-2-02-size-lf-1920x1080.webm.md5"; - -struct ByteAlignmentTestParam { - int byte_alignment; - vpx_codec_err_t expected_value; - bool decode_remaining; -}; - -const ByteAlignmentTestParam kBaTestParams[] = { - { kLegacyByteAlignment, VPX_CODEC_OK, true }, - { 32, VPX_CODEC_OK, true }, - { 64, VPX_CODEC_OK, true }, - { 128, VPX_CODEC_OK, true }, - { 256, VPX_CODEC_OK, true }, - { 512, VPX_CODEC_OK, true }, - { 1024, VPX_CODEC_OK, true }, - { 1, VPX_CODEC_INVALID_PARAM, false }, - { -2, VPX_CODEC_INVALID_PARAM, false }, - { 4, VPX_CODEC_INVALID_PARAM, false }, - { 16, VPX_CODEC_INVALID_PARAM, false }, - { 255, VPX_CODEC_INVALID_PARAM, false }, - { 2048, VPX_CODEC_INVALID_PARAM, false }, -}; - -// Class for testing byte alignment of reference buffers. -class ByteAlignmentTest - : public ::testing::TestWithParam { - protected: - ByteAlignmentTest() - : video_(nullptr), decoder_(nullptr), md5_file_(nullptr) {} - - void SetUp() override { - video_ = new libvpx_test::WebMVideoSource(kVP9TestFile); - ASSERT_NE(video_, nullptr); - video_->Init(); - video_->Begin(); - - const vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t(); - decoder_ = new libvpx_test::VP9Decoder(cfg, 0); - ASSERT_NE(decoder_, nullptr); - - OpenMd5File(kVP9Md5File); - } - - void TearDown() override { - if (md5_file_ != nullptr) fclose(md5_file_); - - delete decoder_; - delete video_; - } - - void SetByteAlignment(int byte_alignment, vpx_codec_err_t expected_value) { - decoder_->Control(VP9_SET_BYTE_ALIGNMENT, byte_alignment, expected_value); - } - - vpx_codec_err_t DecodeOneFrame(int byte_alignment_to_check) { - const vpx_codec_err_t res = - decoder_->DecodeFrame(video_->cxdata(), video_->frame_size()); - CheckDecodedFrames(byte_alignment_to_check); - if (res == VPX_CODEC_OK) video_->Next(); - return res; - } - - vpx_codec_err_t DecodeRemainingFrames(int byte_alignment_to_check) { - for (; video_->cxdata() != nullptr; video_->Next()) { - const vpx_codec_err_t res = - decoder_->DecodeFrame(video_->cxdata(), video_->frame_size()); - if (res != VPX_CODEC_OK) return res; - CheckDecodedFrames(byte_alignment_to_check); - } - return VPX_CODEC_OK; - } - - private: - // Check if |data| is aligned to |byte_alignment_to_check|. - // |byte_alignment_to_check| must be a power of 2. - void CheckByteAlignment(const uint8_t *data, int byte_alignment_to_check) { - ASSERT_EQ(0u, reinterpret_cast(data) % byte_alignment_to_check); - } - - // Iterate through the planes of the decoded frames and check for - // alignment based off |byte_alignment_to_check|. - void CheckDecodedFrames(int byte_alignment_to_check) { - libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData(); - const vpx_image_t *img; - - // Get decompressed data - while ((img = dec_iter.Next()) != nullptr) { - if (byte_alignment_to_check == kLegacyByteAlignment) { - CheckByteAlignment(img->planes[0], kLegacyYPlaneByteAlignment); - } else { - for (int i = 0; i < kNumPlanesToCheck; ++i) { - CheckByteAlignment(img->planes[i], byte_alignment_to_check); - } - } - CheckMd5(*img); - } - } - - // TODO(fgalligan): Move the MD5 testing code into another class. - void OpenMd5File(const std::string &md5_file_name_) { - md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_); - ASSERT_NE(md5_file_, nullptr) - << "MD5 file open failed. Filename: " << md5_file_name_; - } - - void CheckMd5(const vpx_image_t &img) { - ASSERT_NE(md5_file_, nullptr); - char expected_md5[33]; - char junk[128]; - - // Read correct md5 checksums. - const int res = fscanf(md5_file_, "%s %s", expected_md5, junk); - ASSERT_NE(EOF, res) << "Read md5 data failed"; - expected_md5[32] = '\0'; - - ::libvpx_test::MD5 md5_res; - md5_res.Add(&img); - const char *const actual_md5 = md5_res.Get(); - - // Check md5 match. - ASSERT_STREQ(expected_md5, actual_md5) << "MD5 checksums don't match"; - } - - libvpx_test::WebMVideoSource *video_; - libvpx_test::VP9Decoder *decoder_; - FILE *md5_file_; -}; - -TEST_F(ByteAlignmentTest, SwitchByteAlignment) { - const int num_elements = 14; - const int byte_alignments[] = { 0, 32, 64, 128, 256, 512, 1024, - 0, 1024, 32, 512, 64, 256, 128 }; - - for (int i = 0; i < num_elements; ++i) { - SetByteAlignment(byte_alignments[i], VPX_CODEC_OK); - ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame(byte_alignments[i])); - } - SetByteAlignment(byte_alignments[0], VPX_CODEC_OK); - ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames(byte_alignments[0])); -} - -TEST_P(ByteAlignmentTest, TestAlignment) { - const ByteAlignmentTestParam t = GetParam(); - SetByteAlignment(t.byte_alignment, t.expected_value); - if (t.decode_remaining) { - ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames(t.byte_alignment)); - } -} - -INSTANTIATE_TEST_SUITE_P(Alignments, ByteAlignmentTest, - ::testing::ValuesIn(kBaTestParams)); - -#endif // CONFIG_WEBM_IO - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/clear_system_state.h b/presentation/src/main/cpp/third_party/libvpx/test/clear_system_state.h deleted file mode 100644 index ba3c0b38..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/clear_system_state.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_TEST_CLEAR_SYSTEM_STATE_H_ -#define VPX_TEST_CLEAR_SYSTEM_STATE_H_ - -#include "./vpx_config.h" -#include "vpx_ports/system_state.h" - -namespace libvpx_test { - -// Reset system to a known state. This function should be used for all non-API -// test cases. -inline void ClearSystemState() { vpx_clear_system_state(); } - -} // namespace libvpx_test -#endif // VPX_TEST_CLEAR_SYSTEM_STATE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/codec_factory.h b/presentation/src/main/cpp/third_party/libvpx/test/codec_factory.h deleted file mode 100644 index 179ccdf0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/codec_factory.h +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_TEST_CODEC_FACTORY_H_ -#define VPX_TEST_CODEC_FACTORY_H_ - -#include - -#include "./vpx_config.h" -#include "vpx/vpx_decoder.h" -#include "vpx/vpx_encoder.h" -#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER -#include "vpx/vp8cx.h" -#endif -#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER -#include "vpx/vp8dx.h" -#endif - -#include "test/decode_test_driver.h" -#include "test/encode_test_driver.h" -namespace libvpx_test { - -const int kCodecFactoryParam = 0; - -class CodecFactory { - public: - CodecFactory() {} - - virtual ~CodecFactory() {} - - virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg) const = 0; - - virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg, - const vpx_codec_flags_t flags) const = 0; - - virtual Encoder *CreateEncoder(vpx_codec_enc_cfg_t cfg, - vpx_enc_deadline_t deadline, - const unsigned long init_flags, - TwopassStatsStore *stats) const = 0; - - virtual vpx_codec_err_t DefaultEncoderConfig(vpx_codec_enc_cfg_t *cfg, - int usage) const = 0; -}; - -/* Provide CodecTestWithParams classes for a variable number of parameters - * to avoid having to include a pointer to the CodecFactory in every test - * definition. - */ -template -class CodecTestWithParam - : public ::testing::TestWithParam< - std::tuple > {}; - -template -class CodecTestWith2Params - : public ::testing::TestWithParam< - std::tuple > {}; - -template -class CodecTestWith3Params - : public ::testing::TestWithParam< - std::tuple > {}; - -template -class CodecTestWith4Params - : public ::testing::TestWithParam< - std::tuple > {}; - -/* - * VP8 Codec Definitions - */ -#if CONFIG_VP8 -class VP8Decoder : public Decoder { - public: - explicit VP8Decoder(vpx_codec_dec_cfg_t cfg) : Decoder(cfg) {} - - VP8Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag) - : Decoder(cfg, flag) {} - - protected: - vpx_codec_iface_t *CodecInterface() const override { -#if CONFIG_VP8_DECODER - return &vpx_codec_vp8_dx_algo; -#else - return nullptr; -#endif - } -}; - -class VP8Encoder : public Encoder { - public: - VP8Encoder(vpx_codec_enc_cfg_t cfg, vpx_enc_deadline_t deadline, - const unsigned long init_flags, TwopassStatsStore *stats) - : Encoder(cfg, deadline, init_flags, stats) {} - - protected: - vpx_codec_iface_t *CodecInterface() const override { -#if CONFIG_VP8_ENCODER - return &vpx_codec_vp8_cx_algo; -#else - return nullptr; -#endif - } -}; - -class VP8CodecFactory : public CodecFactory { - public: - VP8CodecFactory() : CodecFactory() {} - - Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg) const override { - return CreateDecoder(cfg, 0); - } - - Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg, - const vpx_codec_flags_t flags) const override { -#if CONFIG_VP8_DECODER - return new VP8Decoder(cfg, flags); -#else - (void)cfg; - (void)flags; - return nullptr; -#endif - } - - Encoder *CreateEncoder(vpx_codec_enc_cfg_t cfg, vpx_enc_deadline_t deadline, - const unsigned long init_flags, - TwopassStatsStore *stats) const override { -#if CONFIG_VP8_ENCODER - return new VP8Encoder(cfg, deadline, init_flags, stats); -#else - (void)cfg; - (void)deadline; - (void)init_flags; - (void)stats; - return nullptr; -#endif - } - - vpx_codec_err_t DefaultEncoderConfig(vpx_codec_enc_cfg_t *cfg, - int usage) const override { -#if CONFIG_VP8_ENCODER - return vpx_codec_enc_config_default(&vpx_codec_vp8_cx_algo, cfg, usage); -#else - (void)cfg; - (void)usage; - return VPX_CODEC_INCAPABLE; -#endif - } -}; - -const libvpx_test::VP8CodecFactory kVP8; - -#define VP8_INSTANTIATE_TEST_SUITE(test, ...) \ - INSTANTIATE_TEST_SUITE_P( \ - VP8, test, \ - ::testing::Combine( \ - ::testing::Values(static_cast( \ - &libvpx_test::kVP8)), \ - __VA_ARGS__)) -#else -// static_assert() is used to avoid warnings about an extra ';' outside of a -// function. -#define VP8_INSTANTIATE_TEST_SUITE(test, ...) static_assert(CONFIG_VP8 == 0, "") -#endif // CONFIG_VP8 - -/* - * VP9 Codec Definitions - */ -#if CONFIG_VP9 -class VP9Decoder : public Decoder { - public: - explicit VP9Decoder(vpx_codec_dec_cfg_t cfg) : Decoder(cfg) {} - - VP9Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag) - : Decoder(cfg, flag) {} - - protected: - vpx_codec_iface_t *CodecInterface() const override { -#if CONFIG_VP9_DECODER - return &vpx_codec_vp9_dx_algo; -#else - return nullptr; -#endif - } -}; - -class VP9Encoder : public Encoder { - public: - VP9Encoder(vpx_codec_enc_cfg_t cfg, vpx_enc_deadline_t deadline, - const unsigned long init_flags, TwopassStatsStore *stats) - : Encoder(cfg, deadline, init_flags, stats) {} - - protected: - vpx_codec_iface_t *CodecInterface() const override { -#if CONFIG_VP9_ENCODER - return &vpx_codec_vp9_cx_algo; -#else - return nullptr; -#endif - } -}; - -class VP9CodecFactory : public CodecFactory { - public: - VP9CodecFactory() : CodecFactory() {} - - Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg) const override { - return CreateDecoder(cfg, 0); - } - - Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg, - const vpx_codec_flags_t flags) const override { -#if CONFIG_VP9_DECODER - return new VP9Decoder(cfg, flags); -#else - (void)cfg; - (void)flags; - return nullptr; -#endif - } - - Encoder *CreateEncoder(vpx_codec_enc_cfg_t cfg, vpx_enc_deadline_t deadline, - const unsigned long init_flags, - TwopassStatsStore *stats) const override { -#if CONFIG_VP9_ENCODER - return new VP9Encoder(cfg, deadline, init_flags, stats); -#else - (void)cfg; - (void)deadline; - (void)init_flags; - (void)stats; - return nullptr; -#endif - } - - vpx_codec_err_t DefaultEncoderConfig(vpx_codec_enc_cfg_t *cfg, - int usage) const override { -#if CONFIG_VP9_ENCODER - return vpx_codec_enc_config_default(&vpx_codec_vp9_cx_algo, cfg, usage); -#else - (void)cfg; - (void)usage; - return VPX_CODEC_INCAPABLE; -#endif - } -}; - -const libvpx_test::VP9CodecFactory kVP9; - -#define VP9_INSTANTIATE_TEST_SUITE(test, ...) \ - INSTANTIATE_TEST_SUITE_P( \ - VP9, test, \ - ::testing::Combine( \ - ::testing::Values(static_cast( \ - &libvpx_test::kVP9)), \ - __VA_ARGS__)) -#else -// static_assert() is used to avoid warnings about an extra ';' outside of a -// function. -#define VP9_INSTANTIATE_TEST_SUITE(test, ...) static_assert(CONFIG_VP9 == 0, "") -#endif // CONFIG_VP9 - -} // namespace libvpx_test -#endif // VPX_TEST_CODEC_FACTORY_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/comp_avg_pred_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/comp_avg_pred_test.cc deleted file mode 100644 index de9842a8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/comp_avg_pred_test.cc +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "gtest/gtest.h" - -#include "./vpx_dsp_rtcd.h" - -#include "test/acm_random.h" -#include "test/buffer.h" -#include "test/register_state_check.h" -#include "vpx_config.h" -#include "vpx_ports/vpx_timer.h" - -namespace { - -using ::libvpx_test::ACMRandom; -using ::libvpx_test::Buffer; - -template -Pixel avg_with_rounding(Pixel a, Pixel b) { - return (a + b + 1) >> 1; -} - -template -void reference_pred(const Buffer &pred, const Buffer &ref, - int width, int height, Buffer *avg) { - ASSERT_NE(avg->TopLeftPixel(), nullptr); - ASSERT_NE(pred.TopLeftPixel(), nullptr); - ASSERT_NE(ref.TopLeftPixel(), nullptr); - - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - avg->TopLeftPixel()[y * avg->stride() + x] = - avg_with_rounding(pred.TopLeftPixel()[y * pred.stride() + x], - ref.TopLeftPixel()[y * ref.stride() + x]); - } - } -} - -using AvgPredFunc = void (*)(uint8_t *a, const uint8_t *b, int w, int h, - const uint8_t *c, int c_stride); - -template -class AvgPredTest : public ::testing::TestWithParam { - public: - void SetUp() override { - avg_pred_func_ = GetParam(); - rnd_.Reset(ACMRandom::DeterministicSeed()); - } - - void TestSizeCombinations(); - void TestCompareReferenceRandom(); - void TestSpeed(); - - protected: - AvgPredFunc avg_pred_func_; - ACMRandom rnd_; -}; - -template -void AvgPredTest::TestSizeCombinations() { - // This is called as part of the sub pixel variance. As such it must be one of - // the variance block sizes. - for (int width_pow = 2; width_pow <= 6; ++width_pow) { - for (int height_pow = width_pow - 1; height_pow <= width_pow + 1; - ++height_pow) { - // Don't test 4x2 or 64x128 - if (height_pow == 1 || height_pow == 7) continue; - - // The sse2 special-cases when ref width == stride, so make sure to test - // it. - for (int ref_padding = 0; ref_padding < 2; ref_padding++) { - const int width = 1 << width_pow; - const int height = 1 << height_pow; - // Only the reference buffer may have a stride not equal to width. - Buffer ref = Buffer(width, height, ref_padding ? 8 : 0); - ASSERT_TRUE(ref.Init()); - Buffer pred = Buffer(width, height, 0, 32); - ASSERT_TRUE(pred.Init()); - Buffer avg_ref = Buffer(width, height, 0, 32); - ASSERT_TRUE(avg_ref.Init()); - Buffer avg_chk = Buffer(width, height, 0, 32); - ASSERT_TRUE(avg_chk.Init()); - const int bitdepth_mask = (1 << bitdepth) - 1; - for (int h = 0; h < height; ++h) { - for (int w = 0; w < width; ++w) { - ref.TopLeftPixel()[w + h * width] = rnd_.Rand16() & bitdepth_mask; - } - } - for (int h = 0; h < height; ++h) { - for (int w = 0; w < width; ++w) { - pred.TopLeftPixel()[w + h * width] = rnd_.Rand16() & bitdepth_mask; - } - } - - reference_pred(pred, ref, width, height, &avg_ref); - ASM_REGISTER_STATE_CHECK(avg_pred_func_( - (uint8_t *)avg_chk.TopLeftPixel(), (uint8_t *)pred.TopLeftPixel(), - width, height, (uint8_t *)ref.TopLeftPixel(), ref.stride())); - - EXPECT_TRUE(avg_chk.CheckValues(avg_ref)); - if (HasFailure()) { - printf("Width: %d Height: %d\n", width, height); - avg_chk.PrintDifference(avg_ref); - return; - } - } - } - } -} - -template -void AvgPredTest::TestCompareReferenceRandom() { - const int width = 64; - const int height = 32; - Buffer ref = Buffer(width, height, 8); - ASSERT_TRUE(ref.Init()); - Buffer pred = Buffer(width, height, 0, 32); - ASSERT_TRUE(pred.Init()); - Buffer avg_ref = Buffer(width, height, 0, 32); - ASSERT_TRUE(avg_ref.Init()); - Buffer avg_chk = Buffer(width, height, 0, 32); - ASSERT_TRUE(avg_chk.Init()); - - for (int i = 0; i < 500; ++i) { - const int bitdepth_mask = (1 << bitdepth) - 1; - for (int h = 0; h < height; ++h) { - for (int w = 0; w < width; ++w) { - ref.TopLeftPixel()[w + h * width] = rnd_.Rand16() & bitdepth_mask; - } - } - for (int h = 0; h < height; ++h) { - for (int w = 0; w < width; ++w) { - pred.TopLeftPixel()[w + h * width] = rnd_.Rand16() & bitdepth_mask; - } - } - - reference_pred(pred, ref, width, height, &avg_ref); - ASM_REGISTER_STATE_CHECK(avg_pred_func_( - (uint8_t *)avg_chk.TopLeftPixel(), (uint8_t *)pred.TopLeftPixel(), - width, height, (uint8_t *)ref.TopLeftPixel(), ref.stride())); - EXPECT_TRUE(avg_chk.CheckValues(avg_ref)); - if (HasFailure()) { - printf("Width: %d Height: %d\n", width, height); - avg_chk.PrintDifference(avg_ref); - return; - } - } -} - -template -void AvgPredTest::TestSpeed() { - for (int width_pow = 2; width_pow <= 6; ++width_pow) { - for (int height_pow = width_pow - 1; height_pow <= width_pow + 1; - ++height_pow) { - // Don't test 4x2 or 64x128 - if (height_pow == 1 || height_pow == 7) continue; - - for (int ref_padding = 0; ref_padding < 2; ref_padding++) { - const int width = 1 << width_pow; - const int height = 1 << height_pow; - Buffer ref = Buffer(width, height, ref_padding ? 8 : 0); - ASSERT_TRUE(ref.Init()); - Buffer pred = Buffer(width, height, 0, 32); - ASSERT_TRUE(pred.Init()); - Buffer avg = Buffer(width, height, 0, 32); - ASSERT_TRUE(avg.Init()); - const int bitdepth_mask = (1 << bitdepth) - 1; - for (int h = 0; h < height; ++h) { - for (int w = 0; w < width; ++w) { - ref.TopLeftPixel()[w + h * width] = rnd_.Rand16() & bitdepth_mask; - } - } - for (int h = 0; h < height; ++h) { - for (int w = 0; w < width; ++w) { - pred.TopLeftPixel()[w + h * width] = rnd_.Rand16() & bitdepth_mask; - } - } - - vpx_usec_timer timer; - vpx_usec_timer_start(&timer); - for (int i = 0; i < 100000000 / (width * height); ++i) { - avg_pred_func_((uint8_t *)avg.TopLeftPixel(), - (uint8_t *)pred.TopLeftPixel(), width, height, - (uint8_t *)ref.TopLeftPixel(), ref.stride()); - } - vpx_usec_timer_mark(&timer); - - const int elapsed_time = - static_cast(vpx_usec_timer_elapsed(&timer)); - printf("Average Test (ref_padding: %d) %dx%d time: %5d us\n", - ref_padding, width, height, elapsed_time); - } - } - } -} - -using AvgPredTestLBD = AvgPredTest<8, uint8_t>; - -TEST_P(AvgPredTestLBD, SizeCombinations) { TestSizeCombinations(); } - -TEST_P(AvgPredTestLBD, CompareReferenceRandom) { TestCompareReferenceRandom(); } - -TEST_P(AvgPredTestLBD, DISABLED_Speed) { TestSpeed(); } - -INSTANTIATE_TEST_SUITE_P(C, AvgPredTestLBD, - ::testing::Values(&vpx_comp_avg_pred_c)); - -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P(SSE2, AvgPredTestLBD, - ::testing::Values(&vpx_comp_avg_pred_sse2)); -#endif // HAVE_SSE2 - -#if HAVE_AVX2 -INSTANTIATE_TEST_SUITE_P(AVX2, AvgPredTestLBD, - ::testing::Values(&vpx_comp_avg_pred_avx2)); -#endif // HAVE_AVX2 - -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P(NEON, AvgPredTestLBD, - ::testing::Values(&vpx_comp_avg_pred_neon)); -#endif // HAVE_NEON - -#if HAVE_VSX -INSTANTIATE_TEST_SUITE_P(VSX, AvgPredTestLBD, - ::testing::Values(&vpx_comp_avg_pred_vsx)); -#endif // HAVE_VSX - -#if HAVE_LSX -INSTANTIATE_TEST_SUITE_P(LSX, AvgPredTestLBD, - ::testing::Values(&vpx_comp_avg_pred_lsx)); -#endif // HAVE_LSX - -#if CONFIG_VP9_HIGHBITDEPTH -using HighbdAvgPredFunc = void (*)(uint16_t *a, const uint16_t *b, int w, int h, - const uint16_t *c, int c_stride); - -template -void highbd_wrapper(uint8_t *a, const uint8_t *b, int w, int h, - const uint8_t *c, int c_stride) { - fn((uint16_t *)a, (const uint16_t *)b, w, h, (const uint16_t *)c, c_stride); -} - -using AvgPredTestHBD = AvgPredTest<12, uint16_t>; - -TEST_P(AvgPredTestHBD, SizeCombinations) { TestSizeCombinations(); } - -TEST_P(AvgPredTestHBD, CompareReferenceRandom) { TestCompareReferenceRandom(); } - -TEST_P(AvgPredTestHBD, DISABLED_Speed) { TestSpeed(); } - -INSTANTIATE_TEST_SUITE_P( - C, AvgPredTestHBD, - ::testing::Values(&highbd_wrapper)); - -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P( - SSE2, AvgPredTestHBD, - ::testing::Values(&highbd_wrapper)); -#endif // HAVE_SSE2 - -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P( - NEON, AvgPredTestHBD, - ::testing::Values(&highbd_wrapper)); -#endif // HAVE_NEON - -#endif // CONFIG_VP9_HIGHBITDEPTH -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/config_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/config_test.cc deleted file mode 100644 index d3aca4cf..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/config_test.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/util.h" -#include "test/video_source.h" - -namespace { - -class ConfigTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWithParam { - protected: - ConfigTest() - : EncoderTest(GET_PARAM(0)), frame_count_in_(0), frame_count_out_(0), - frame_count_max_(0) {} - ~ConfigTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(GET_PARAM(1)); - } - - void BeginPassHook(unsigned int /*pass*/) override { - frame_count_in_ = 0; - frame_count_out_ = 0; - } - - void PreEncodeFrameHook(libvpx_test::VideoSource * /*video*/) override { - ++frame_count_in_; - abort_ |= (frame_count_in_ >= frame_count_max_); - } - - void FramePktHook(const vpx_codec_cx_pkt_t * /*pkt*/) override { - ++frame_count_out_; - } - - unsigned int frame_count_in_; - unsigned int frame_count_out_; - unsigned int frame_count_max_; -}; - -TEST_P(ConfigTest, LagIsDisabled) { - frame_count_max_ = 2; - cfg_.g_lag_in_frames = 15; - - libvpx_test::DummyVideoSource video; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - EXPECT_EQ(frame_count_in_, frame_count_out_); -} - -VP8_INSTANTIATE_TEST_SUITE(ConfigTest, ONE_PASS_TEST_MODES); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/consistency_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/consistency_test.cc deleted file mode 100644 index dc74bedd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/consistency_test.cc +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vpx_config.h" -#if CONFIG_VP9_ENCODER -#include "./vp9_rtcd.h" -#endif - -#include "test/acm_random.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vpx_dsp/ssim.h" -#include "vpx_mem/vpx_mem.h" - -extern "C" double vpx_get_ssim_metrics(uint8_t *img1, int img1_pitch, - uint8_t *img2, int img2_pitch, int width, - int height, Ssimv *sv2, Metrics *m, - int do_inconsistency); - -using libvpx_test::ACMRandom; - -namespace { -class ConsistencyTestBase : public ::testing::Test { - public: - ConsistencyTestBase(int width, int height) : width_(width), height_(height) {} - - static void SetUpTestSuite() { - source_data_[0] = reinterpret_cast( - vpx_memalign(kDataAlignment, kDataBufferSize)); - reference_data_[0] = reinterpret_cast( - vpx_memalign(kDataAlignment, kDataBufferSize)); - source_data_[1] = reinterpret_cast( - vpx_memalign(kDataAlignment, kDataBufferSize)); - reference_data_[1] = reinterpret_cast( - vpx_memalign(kDataAlignment, kDataBufferSize)); - ssim_array_ = new Ssimv[kDataBufferSize / 16]; - } - - static void ClearSsim() { memset(ssim_array_, 0, kDataBufferSize / 16); } - static void TearDownTestSuite() { - vpx_free(source_data_[0]); - source_data_[0] = nullptr; - vpx_free(reference_data_[0]); - reference_data_[0] = nullptr; - vpx_free(source_data_[1]); - source_data_[1] = nullptr; - vpx_free(reference_data_[1]); - reference_data_[1] = nullptr; - - delete[] ssim_array_; - } - - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - // Handle frames up to 640x480 - static const int kDataAlignment = 16; - static const int kDataBufferSize = 640 * 480; - - void SetUp() override { - source_stride_ = (width_ + 31) & ~31; - reference_stride_ = width_ * 2; - rnd_.Reset(ACMRandom::DeterministicSeed()); - } - - void FillRandom(uint8_t *data, int stride, int width, int height) { - for (int h = 0; h < height; ++h) { - for (int w = 0; w < width; ++w) { - data[h * stride + w] = rnd_.Rand8(); - } - } - } - - void FillRandom(uint8_t *data, int stride) { - FillRandom(data, stride, width_, height_); - } - - void Copy(uint8_t *reference, uint8_t *source) { - memcpy(reference, source, kDataBufferSize); - } - - void Blur(uint8_t *data, int stride, int taps) { - int sum = 0; - int half_taps = taps / 2; - for (int h = 0; h < height_; ++h) { - for (int w = 0; w < taps; ++w) { - sum += data[w + h * stride]; - } - for (int w = taps; w < width_; ++w) { - sum += data[w + h * stride] - data[w - taps + h * stride]; - data[w - half_taps + h * stride] = (sum + half_taps) / taps; - } - } - for (int w = 0; w < width_; ++w) { - for (int h = 0; h < taps; ++h) { - sum += data[h + w * stride]; - } - for (int h = taps; h < height_; ++h) { - sum += data[w + h * stride] - data[(h - taps) * stride + w]; - data[(h - half_taps) * stride + w] = (sum + half_taps) / taps; - } - } - } - int width_, height_; - static uint8_t *source_data_[2]; - int source_stride_; - static uint8_t *reference_data_[2]; - int reference_stride_; - static Ssimv *ssim_array_; - Metrics metrics_; - - ACMRandom rnd_; -}; - -#if CONFIG_VP9_ENCODER -typedef std::tuple ConsistencyParam; -class ConsistencyVP9Test - : public ConsistencyTestBase, - public ::testing::WithParamInterface { - public: - ConsistencyVP9Test() : ConsistencyTestBase(GET_PARAM(0), GET_PARAM(1)) {} - - protected: - double CheckConsistency(int frame) { - EXPECT_LT(frame, 2) << "Frame to check has to be less than 2."; - return vpx_get_ssim_metrics(source_data_[frame], source_stride_, - reference_data_[frame], reference_stride_, - width_, height_, ssim_array_, &metrics_, 1); - } -}; -#endif // CONFIG_VP9_ENCODER - -uint8_t *ConsistencyTestBase::source_data_[2] = { nullptr, nullptr }; -uint8_t *ConsistencyTestBase::reference_data_[2] = { nullptr, nullptr }; -Ssimv *ConsistencyTestBase::ssim_array_ = nullptr; - -#if CONFIG_VP9_ENCODER -TEST_P(ConsistencyVP9Test, ConsistencyIsZero) { - FillRandom(source_data_[0], source_stride_); - Copy(source_data_[1], source_data_[0]); - Copy(reference_data_[0], source_data_[0]); - Blur(reference_data_[0], reference_stride_, 3); - Copy(reference_data_[1], source_data_[0]); - Blur(reference_data_[1], reference_stride_, 3); - - double inconsistency = CheckConsistency(1); - inconsistency = CheckConsistency(0); - EXPECT_EQ(inconsistency, 0.0) - << "Should have 0 inconsistency if they are exactly the same."; - - // If sources are not consistent reference frames inconsistency should - // be less than if the source is consistent. - FillRandom(source_data_[0], source_stride_); - FillRandom(source_data_[1], source_stride_); - FillRandom(reference_data_[0], reference_stride_); - FillRandom(reference_data_[1], reference_stride_); - CheckConsistency(0); - inconsistency = CheckConsistency(1); - - Copy(source_data_[1], source_data_[0]); - CheckConsistency(0); - double inconsistency2 = CheckConsistency(1); - EXPECT_LT(inconsistency, inconsistency2) - << "Should have less inconsistency if source itself is inconsistent."; - - // Less of a blur should be less inconsistent than more blur coming off a - // a frame with no blur. - ClearSsim(); - FillRandom(source_data_[0], source_stride_); - Copy(source_data_[1], source_data_[0]); - Copy(reference_data_[0], source_data_[0]); - Copy(reference_data_[1], source_data_[0]); - Blur(reference_data_[1], reference_stride_, 4); - CheckConsistency(0); - inconsistency = CheckConsistency(1); - ClearSsim(); - Copy(reference_data_[1], source_data_[0]); - Blur(reference_data_[1], reference_stride_, 8); - CheckConsistency(0); - inconsistency2 = CheckConsistency(1); - - EXPECT_LT(inconsistency, inconsistency2) - << "Stronger Blur should produce more inconsistency."; -} -#endif // CONFIG_VP9_ENCODER - -using std::make_tuple; - -//------------------------------------------------------------------------------ -// C functions - -#if CONFIG_VP9_ENCODER -const ConsistencyParam c_vp9_tests[] = { make_tuple(320, 240), - make_tuple(318, 242), - make_tuple(318, 238) }; -INSTANTIATE_TEST_SUITE_P(C, ConsistencyVP9Test, - ::testing::ValuesIn(c_vp9_tests)); -#endif - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/convolve_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/convolve_test.cc deleted file mode 100644 index d9471795..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/convolve_test.cc +++ /dev/null @@ -1,1610 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "gtest/gtest.h" - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "test/acm_random.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_filter.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/vpx_timer.h" - -namespace { - -static const unsigned int kMaxDimension = 64; - -typedef void (*ConvolveFunc)(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h); - -typedef void (*WrapperFilterBlock2d8Func)( - const uint8_t *src_ptr, const unsigned int src_stride, - const int16_t *hfilter, const int16_t *vfilter, uint8_t *dst_ptr, - unsigned int dst_stride, unsigned int output_width, - unsigned int output_height, int use_highbd); - -struct ConvolveFunctions { - ConvolveFunctions(ConvolveFunc copy, ConvolveFunc avg, ConvolveFunc h8, - ConvolveFunc h8_avg, ConvolveFunc v8, ConvolveFunc v8_avg, - ConvolveFunc hv8, ConvolveFunc hv8_avg, ConvolveFunc sh8, - ConvolveFunc sh8_avg, ConvolveFunc sv8, - ConvolveFunc sv8_avg, ConvolveFunc shv8, - ConvolveFunc shv8_avg, int bd) - : use_highbd_(bd) { - copy_[0] = copy; - copy_[1] = avg; - h8_[0] = h8; - h8_[1] = h8_avg; - v8_[0] = v8; - v8_[1] = v8_avg; - hv8_[0] = hv8; - hv8_[1] = hv8_avg; - sh8_[0] = sh8; - sh8_[1] = sh8_avg; - sv8_[0] = sv8; - sv8_[1] = sv8_avg; - shv8_[0] = shv8; - shv8_[1] = shv8_avg; - } - - ConvolveFunc copy_[2]; - ConvolveFunc h8_[2]; - ConvolveFunc v8_[2]; - ConvolveFunc hv8_[2]; - ConvolveFunc sh8_[2]; // scaled horiz - ConvolveFunc sv8_[2]; // scaled vert - ConvolveFunc shv8_[2]; // scaled horiz/vert - int use_highbd_; // 0 if high bitdepth not used, else the actual bit depth. -}; - -typedef std::tuple ConvolveParam; - -#define ALL_SIZES(convolve_fn) \ - make_tuple(4, 4, &convolve_fn), make_tuple(8, 4, &convolve_fn), \ - make_tuple(4, 8, &convolve_fn), make_tuple(8, 8, &convolve_fn), \ - make_tuple(16, 8, &convolve_fn), make_tuple(8, 16, &convolve_fn), \ - make_tuple(16, 16, &convolve_fn), make_tuple(32, 16, &convolve_fn), \ - make_tuple(16, 32, &convolve_fn), make_tuple(32, 32, &convolve_fn), \ - make_tuple(64, 32, &convolve_fn), make_tuple(32, 64, &convolve_fn), \ - make_tuple(64, 64, &convolve_fn) - -// Reference 8-tap subpixel filter, slightly modified to fit into this test. -#define VP9_FILTER_WEIGHT 128 -#define VP9_FILTER_SHIFT 7 -uint8_t clip_pixel(int x) { return x < 0 ? 0 : x > 255 ? 255 : x; } - -void filter_block2d_8_c(const uint8_t *src_ptr, const unsigned int src_stride, - const int16_t *hfilter, const int16_t *vfilter, - uint8_t *dst_ptr, unsigned int dst_stride, - unsigned int output_width, unsigned int output_height) { - // Between passes, we use an intermediate buffer whose height is extended to - // have enough horizontally filtered values as input for the vertical pass. - // This buffer is allocated to be big enough for the largest block type we - // support. - const int kInterp_Extend = 4; - const unsigned int intermediate_height = - (kInterp_Extend - 1) + output_height + kInterp_Extend; - unsigned int i, j; - - // Size of intermediate_buffer is max_intermediate_height * filter_max_width, - // where max_intermediate_height = (kInterp_Extend - 1) + filter_max_height - // + kInterp_Extend - // = 3 + 16 + 4 - // = 23 - // and filter_max_width = 16 - // - uint8_t intermediate_buffer[71 * kMaxDimension]; - vp9_zero(intermediate_buffer); - const int intermediate_next_stride = - 1 - static_cast(intermediate_height * output_width); - - // Horizontal pass (src -> transposed intermediate). - uint8_t *output_ptr = intermediate_buffer; - const int src_next_row_stride = src_stride - output_width; - src_ptr -= (kInterp_Extend - 1) * src_stride + (kInterp_Extend - 1); - for (i = 0; i < intermediate_height; ++i) { - for (j = 0; j < output_width; ++j) { - // Apply filter... - const int temp = (src_ptr[0] * hfilter[0]) + (src_ptr[1] * hfilter[1]) + - (src_ptr[2] * hfilter[2]) + (src_ptr[3] * hfilter[3]) + - (src_ptr[4] * hfilter[4]) + (src_ptr[5] * hfilter[5]) + - (src_ptr[6] * hfilter[6]) + (src_ptr[7] * hfilter[7]) + - (VP9_FILTER_WEIGHT >> 1); // Rounding - - // Normalize back to 0-255... - *output_ptr = clip_pixel(temp >> VP9_FILTER_SHIFT); - ++src_ptr; - output_ptr += intermediate_height; - } - src_ptr += src_next_row_stride; - output_ptr += intermediate_next_stride; - } - - // Vertical pass (transposed intermediate -> dst). - src_ptr = intermediate_buffer; - const int dst_next_row_stride = dst_stride - output_width; - for (i = 0; i < output_height; ++i) { - for (j = 0; j < output_width; ++j) { - // Apply filter... - const int temp = (src_ptr[0] * vfilter[0]) + (src_ptr[1] * vfilter[1]) + - (src_ptr[2] * vfilter[2]) + (src_ptr[3] * vfilter[3]) + - (src_ptr[4] * vfilter[4]) + (src_ptr[5] * vfilter[5]) + - (src_ptr[6] * vfilter[6]) + (src_ptr[7] * vfilter[7]) + - (VP9_FILTER_WEIGHT >> 1); // Rounding - - // Normalize back to 0-255... - *dst_ptr++ = clip_pixel(temp >> VP9_FILTER_SHIFT); - src_ptr += intermediate_height; - } - src_ptr += intermediate_next_stride; - dst_ptr += dst_next_row_stride; - } -} - -void block2d_average_c(uint8_t *src, unsigned int src_stride, - uint8_t *output_ptr, unsigned int output_stride, - unsigned int output_width, unsigned int output_height) { - unsigned int i, j; - for (i = 0; i < output_height; ++i) { - for (j = 0; j < output_width; ++j) { - output_ptr[j] = (output_ptr[j] + src[i * src_stride + j] + 1) >> 1; - } - output_ptr += output_stride; - } -} - -void filter_average_block2d_8_c(const uint8_t *src_ptr, - const unsigned int src_stride, - const int16_t *hfilter, const int16_t *vfilter, - uint8_t *dst_ptr, unsigned int dst_stride, - unsigned int output_width, - unsigned int output_height) { - uint8_t tmp[kMaxDimension * kMaxDimension]; - - assert(output_width <= kMaxDimension); - assert(output_height <= kMaxDimension); - filter_block2d_8_c(src_ptr, src_stride, hfilter, vfilter, tmp, 64, - output_width, output_height); - block2d_average_c(tmp, 64, dst_ptr, dst_stride, output_width, output_height); -} - -#if CONFIG_VP9_HIGHBITDEPTH -void highbd_filter_block2d_8_c(const uint16_t *src_ptr, - const unsigned int src_stride, - const int16_t *hfilter, const int16_t *vfilter, - uint16_t *dst_ptr, unsigned int dst_stride, - unsigned int output_width, - unsigned int output_height, int bd) { - // Between passes, we use an intermediate buffer whose height is extended to - // have enough horizontally filtered values as input for the vertical pass. - // This buffer is allocated to be big enough for the largest block type we - // support. - const int kInterp_Extend = 4; - const unsigned int intermediate_height = - (kInterp_Extend - 1) + output_height + kInterp_Extend; - - /* Size of intermediate_buffer is max_intermediate_height * filter_max_width, - * where max_intermediate_height = (kInterp_Extend - 1) + filter_max_height - * + kInterp_Extend - * = 3 + 16 + 4 - * = 23 - * and filter_max_width = 16 - */ - uint16_t intermediate_buffer[71 * kMaxDimension]; - const int intermediate_next_stride = - 1 - static_cast(intermediate_height * output_width); - - vp9_zero(intermediate_buffer); - - // Horizontal pass (src -> transposed intermediate). - { - uint16_t *output_ptr = intermediate_buffer; - const int src_next_row_stride = src_stride - output_width; - unsigned int i, j; - src_ptr -= (kInterp_Extend - 1) * src_stride + (kInterp_Extend - 1); - for (i = 0; i < intermediate_height; ++i) { - for (j = 0; j < output_width; ++j) { - // Apply filter... - const int temp = (src_ptr[0] * hfilter[0]) + (src_ptr[1] * hfilter[1]) + - (src_ptr[2] * hfilter[2]) + (src_ptr[3] * hfilter[3]) + - (src_ptr[4] * hfilter[4]) + (src_ptr[5] * hfilter[5]) + - (src_ptr[6] * hfilter[6]) + (src_ptr[7] * hfilter[7]) + - (VP9_FILTER_WEIGHT >> 1); // Rounding - - // Normalize back to 0-255... - *output_ptr = clip_pixel_highbd(temp >> VP9_FILTER_SHIFT, bd); - ++src_ptr; - output_ptr += intermediate_height; - } - src_ptr += src_next_row_stride; - output_ptr += intermediate_next_stride; - } - } - - // Vertical pass (transposed intermediate -> dst). - { - src_ptr = intermediate_buffer; - const int dst_next_row_stride = dst_stride - output_width; - unsigned int i, j; - for (i = 0; i < output_height; ++i) { - for (j = 0; j < output_width; ++j) { - // Apply filter... - const int temp = (src_ptr[0] * vfilter[0]) + (src_ptr[1] * vfilter[1]) + - (src_ptr[2] * vfilter[2]) + (src_ptr[3] * vfilter[3]) + - (src_ptr[4] * vfilter[4]) + (src_ptr[5] * vfilter[5]) + - (src_ptr[6] * vfilter[6]) + (src_ptr[7] * vfilter[7]) + - (VP9_FILTER_WEIGHT >> 1); // Rounding - - // Normalize back to 0-255... - *dst_ptr++ = clip_pixel_highbd(temp >> VP9_FILTER_SHIFT, bd); - src_ptr += intermediate_height; - } - src_ptr += intermediate_next_stride; - dst_ptr += dst_next_row_stride; - } - } -} - -void highbd_block2d_average_c(uint16_t *src, unsigned int src_stride, - uint16_t *output_ptr, unsigned int output_stride, - unsigned int output_width, - unsigned int output_height) { - unsigned int i, j; - for (i = 0; i < output_height; ++i) { - for (j = 0; j < output_width; ++j) { - output_ptr[j] = (output_ptr[j] + src[i * src_stride + j] + 1) >> 1; - } - output_ptr += output_stride; - } -} - -void highbd_filter_average_block2d_8_c( - const uint16_t *src_ptr, const unsigned int src_stride, - const int16_t *hfilter, const int16_t *vfilter, uint16_t *dst_ptr, - unsigned int dst_stride, unsigned int output_width, - unsigned int output_height, int bd) { - uint16_t tmp[kMaxDimension * kMaxDimension]; - - assert(output_width <= kMaxDimension); - assert(output_height <= kMaxDimension); - highbd_filter_block2d_8_c(src_ptr, src_stride, hfilter, vfilter, tmp, 64, - output_width, output_height, bd); - highbd_block2d_average_c(tmp, 64, dst_ptr, dst_stride, output_width, - output_height); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -void wrapper_filter_average_block2d_8_c( - const uint8_t *src_ptr, const unsigned int src_stride, - const int16_t *hfilter, const int16_t *vfilter, uint8_t *dst_ptr, - unsigned int dst_stride, unsigned int output_width, - unsigned int output_height, int use_highbd) { -#if CONFIG_VP9_HIGHBITDEPTH - if (use_highbd == 0) { - filter_average_block2d_8_c(src_ptr, src_stride, hfilter, vfilter, dst_ptr, - dst_stride, output_width, output_height); - } else { - highbd_filter_average_block2d_8_c(CAST_TO_SHORTPTR(src_ptr), src_stride, - hfilter, vfilter, - CAST_TO_SHORTPTR(dst_ptr), dst_stride, - output_width, output_height, use_highbd); - } -#else - ASSERT_EQ(0, use_highbd); - filter_average_block2d_8_c(src_ptr, src_stride, hfilter, vfilter, dst_ptr, - dst_stride, output_width, output_height); -#endif -} - -void wrapper_filter_block2d_8_c(const uint8_t *src_ptr, - const unsigned int src_stride, - const int16_t *hfilter, const int16_t *vfilter, - uint8_t *dst_ptr, unsigned int dst_stride, - unsigned int output_width, - unsigned int output_height, int use_highbd) { -#if CONFIG_VP9_HIGHBITDEPTH - if (use_highbd == 0) { - filter_block2d_8_c(src_ptr, src_stride, hfilter, vfilter, dst_ptr, - dst_stride, output_width, output_height); - } else { - highbd_filter_block2d_8_c(CAST_TO_SHORTPTR(src_ptr), src_stride, hfilter, - vfilter, CAST_TO_SHORTPTR(dst_ptr), dst_stride, - output_width, output_height, use_highbd); - } -#else - ASSERT_EQ(0, use_highbd); - filter_block2d_8_c(src_ptr, src_stride, hfilter, vfilter, dst_ptr, dst_stride, - output_width, output_height); -#endif -} - -class ConvolveTest : public ::testing::TestWithParam { - public: - static void SetUpTestSuite() { - // Force input_ to be unaligned, output to be 16 byte aligned. - input_ = reinterpret_cast( - vpx_memalign(kDataAlignment, kInputBufferSize + 1)) + - 1; - output_ = reinterpret_cast( - vpx_memalign(kDataAlignment, kOutputBufferSize)); - output_ref_ = reinterpret_cast( - vpx_memalign(kDataAlignment, kOutputBufferSize)); -#if CONFIG_VP9_HIGHBITDEPTH - input16_ = reinterpret_cast(vpx_memalign( - kDataAlignment, (kInputBufferSize + 1) * sizeof(uint16_t))) + - 1; - output16_ = reinterpret_cast( - vpx_memalign(kDataAlignment, (kOutputBufferSize) * sizeof(uint16_t))); - output16_ref_ = reinterpret_cast( - vpx_memalign(kDataAlignment, (kOutputBufferSize) * sizeof(uint16_t))); -#endif - } - - void TearDown() override { libvpx_test::ClearSystemState(); } - - static void TearDownTestSuite() { - vpx_free(input_ - 1); - input_ = nullptr; - vpx_free(output_); - output_ = nullptr; - vpx_free(output_ref_); - output_ref_ = nullptr; -#if CONFIG_VP9_HIGHBITDEPTH - vpx_free(input16_ - 1); - input16_ = nullptr; - vpx_free(output16_); - output16_ = nullptr; - vpx_free(output16_ref_); - output16_ref_ = nullptr; -#endif - } - - protected: - static const int kDataAlignment = 16; - static const int kOuterBlockSize = 256; - static const int kInputStride = kOuterBlockSize; - static const int kOutputStride = kOuterBlockSize; - static const int kInputBufferSize = kOuterBlockSize * kOuterBlockSize; - static const int kOutputBufferSize = kOuterBlockSize * kOuterBlockSize; - - int Width() const { return GET_PARAM(0); } - int Height() const { return GET_PARAM(1); } - int BorderLeft() const { - const int center = (kOuterBlockSize - Width()) / 2; - return (center + (kDataAlignment - 1)) & ~(kDataAlignment - 1); - } - int BorderTop() const { return (kOuterBlockSize - Height()) / 2; } - - bool IsIndexInBorder(int i) { - return (i < BorderTop() * kOuterBlockSize || - i >= (BorderTop() + Height()) * kOuterBlockSize || - i % kOuterBlockSize < BorderLeft() || - i % kOuterBlockSize >= (BorderLeft() + Width())); - } - - void SetUp() override { - UUT_ = GET_PARAM(2); -#if CONFIG_VP9_HIGHBITDEPTH - if (UUT_->use_highbd_ != 0) { - mask_ = (1 << UUT_->use_highbd_) - 1; - } else { - mask_ = 255; - } -#endif - /* Set up guard blocks for an inner block centered in the outer block */ - for (int i = 0; i < kOutputBufferSize; ++i) { - if (IsIndexInBorder(i)) { - output_[i] = 255; -#if CONFIG_VP9_HIGHBITDEPTH - output16_[i] = mask_; -#endif - } else { - output_[i] = 0; -#if CONFIG_VP9_HIGHBITDEPTH - output16_[i] = 0; -#endif - } - } - - ::libvpx_test::ACMRandom prng; - for (int i = 0; i < kInputBufferSize; ++i) { - if (i & 1) { - input_[i] = 255; -#if CONFIG_VP9_HIGHBITDEPTH - input16_[i] = mask_; -#endif - } else { - input_[i] = prng.Rand8Extremes(); -#if CONFIG_VP9_HIGHBITDEPTH - input16_[i] = prng.Rand16() & mask_; -#endif - } - } - } - - void SetConstantInput(int value) { - memset(input_, value, kInputBufferSize); -#if CONFIG_VP9_HIGHBITDEPTH - vpx_memset16(input16_, value, kInputBufferSize); -#endif - } - - void CopyOutputToRef() { - memcpy(output_ref_, output_, kOutputBufferSize); -#if CONFIG_VP9_HIGHBITDEPTH - memcpy(output16_ref_, output16_, - kOutputBufferSize * sizeof(output16_ref_[0])); -#endif - } - - void CheckGuardBlocks() { - for (int i = 0; i < kOutputBufferSize; ++i) { - if (IsIndexInBorder(i)) { - EXPECT_EQ(255, output_[i]); - } - } - } - - uint8_t *input() const { - const int offset = BorderTop() * kOuterBlockSize + BorderLeft(); -#if CONFIG_VP9_HIGHBITDEPTH - if (UUT_->use_highbd_ == 0) { - return input_ + offset; - } else { - return CAST_TO_BYTEPTR(input16_ + offset); - } -#else - return input_ + offset; -#endif - } - - uint8_t *output() const { - const int offset = BorderTop() * kOuterBlockSize + BorderLeft(); -#if CONFIG_VP9_HIGHBITDEPTH - if (UUT_->use_highbd_ == 0) { - return output_ + offset; - } else { - return CAST_TO_BYTEPTR(output16_ + offset); - } -#else - return output_ + offset; -#endif - } - - uint8_t *output_ref() const { - const int offset = BorderTop() * kOuterBlockSize + BorderLeft(); -#if CONFIG_VP9_HIGHBITDEPTH - if (UUT_->use_highbd_ == 0) { - return output_ref_ + offset; - } else { - return CAST_TO_BYTEPTR(output16_ref_ + offset); - } -#else - return output_ref_ + offset; -#endif - } - - uint16_t lookup(uint8_t *list, int index) const { -#if CONFIG_VP9_HIGHBITDEPTH - if (UUT_->use_highbd_ == 0) { - return list[index]; - } else { - return CAST_TO_SHORTPTR(list)[index]; - } -#else - return list[index]; -#endif - } - - void assign_val(uint8_t *list, int index, uint16_t val) const { -#if CONFIG_VP9_HIGHBITDEPTH - if (UUT_->use_highbd_ == 0) { - list[index] = (uint8_t)val; - } else { - CAST_TO_SHORTPTR(list)[index] = val; - } -#else - list[index] = (uint8_t)val; -#endif - } - - const ConvolveFunctions *UUT_; - static uint8_t *input_; - static uint8_t *output_; - static uint8_t *output_ref_; -#if CONFIG_VP9_HIGHBITDEPTH - static uint16_t *input16_; - static uint16_t *output16_; - static uint16_t *output16_ref_; - int mask_; -#endif -}; - -uint8_t *ConvolveTest::input_ = nullptr; -uint8_t *ConvolveTest::output_ = nullptr; -uint8_t *ConvolveTest::output_ref_ = nullptr; -#if CONFIG_VP9_HIGHBITDEPTH -uint16_t *ConvolveTest::input16_ = nullptr; -uint16_t *ConvolveTest::output16_ = nullptr; -uint16_t *ConvolveTest::output16_ref_ = nullptr; -#endif - -TEST_P(ConvolveTest, GuardBlocks) { CheckGuardBlocks(); } - -TEST_P(ConvolveTest, DISABLED_Copy_Speed) { - const uint8_t *const in = input(); - uint8_t *const out = output(); - const int kNumTests = 5000000; - const int width = Width(); - const int height = Height(); - vpx_usec_timer timer; - - vpx_usec_timer_start(&timer); - for (int n = 0; n < kNumTests; ++n) { - UUT_->copy_[0](in, kInputStride, out, kOutputStride, nullptr, 0, 0, 0, 0, - width, height); - } - vpx_usec_timer_mark(&timer); - - const int elapsed_time = static_cast(vpx_usec_timer_elapsed(&timer)); - printf("convolve_copy_%dx%d_%d: %d us\n", width, height, - UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time); -} - -TEST_P(ConvolveTest, DISABLED_Avg_Speed) { - const uint8_t *const in = input(); - uint8_t *const out = output(); - const int kNumTests = 5000000; - const int width = Width(); - const int height = Height(); - vpx_usec_timer timer; - - vpx_usec_timer_start(&timer); - for (int n = 0; n < kNumTests; ++n) { - UUT_->copy_[1](in, kInputStride, out, kOutputStride, nullptr, 0, 0, 0, 0, - width, height); - } - vpx_usec_timer_mark(&timer); - - const int elapsed_time = static_cast(vpx_usec_timer_elapsed(&timer)); - printf("convolve_avg_%dx%d_%d: %d us\n", width, height, - UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time); -} - -TEST_P(ConvolveTest, DISABLED_Scale_Speed) { - const uint8_t *const in = input(); - uint8_t *const out = output(); - const InterpKernel *const eighttap = vp9_filter_kernels[EIGHTTAP]; - const int kNumTests = 5000000; - const int width = Width(); - const int height = Height(); - vpx_usec_timer timer; - - SetConstantInput(127); - - vpx_usec_timer_start(&timer); - for (int n = 0; n < kNumTests; ++n) { - UUT_->shv8_[0](in, kInputStride, out, kOutputStride, eighttap, 8, 16, 8, 16, - width, height); - } - vpx_usec_timer_mark(&timer); - - const int elapsed_time = static_cast(vpx_usec_timer_elapsed(&timer)); - printf("convolve_scale_%dx%d_%d: %d us\n", width, height, - UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time); -} - -TEST_P(ConvolveTest, DISABLED_8Tap_Speed) { - const uint8_t *const in = input(); - uint8_t *const out = output(); - const InterpKernel *const eighttap = vp9_filter_kernels[EIGHTTAP_SHARP]; - const int kNumTests = 5000000; - const int width = Width(); - const int height = Height(); - vpx_usec_timer timer; - - SetConstantInput(127); - - vpx_usec_timer_start(&timer); - for (int n = 0; n < kNumTests; ++n) { - UUT_->hv8_[0](in, kInputStride, out, kOutputStride, eighttap, 8, 16, 8, 16, - width, height); - } - vpx_usec_timer_mark(&timer); - - const int elapsed_time = static_cast(vpx_usec_timer_elapsed(&timer)); - printf("convolve8_%dx%d_%d: %d us\n", width, height, - UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time); -} - -TEST_P(ConvolveTest, DISABLED_8Tap_Horiz_Speed) { - const uint8_t *const in = input(); - uint8_t *const out = output(); - const InterpKernel *const eighttap = vp9_filter_kernels[EIGHTTAP_SHARP]; - const int kNumTests = 5000000; - const int width = Width(); - const int height = Height(); - vpx_usec_timer timer; - - SetConstantInput(127); - - vpx_usec_timer_start(&timer); - for (int n = 0; n < kNumTests; ++n) { - UUT_->h8_[0](in, kInputStride, out, kOutputStride, eighttap, 8, 16, 8, 16, - width, height); - } - vpx_usec_timer_mark(&timer); - - const int elapsed_time = static_cast(vpx_usec_timer_elapsed(&timer)); - printf("convolve8_horiz_%dx%d_%d: %d us\n", width, height, - UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time); -} - -TEST_P(ConvolveTest, DISABLED_8Tap_Vert_Speed) { - const uint8_t *const in = input(); - uint8_t *const out = output(); - const InterpKernel *const eighttap = vp9_filter_kernels[EIGHTTAP_SHARP]; - const int kNumTests = 5000000; - const int width = Width(); - const int height = Height(); - vpx_usec_timer timer; - - SetConstantInput(127); - - vpx_usec_timer_start(&timer); - for (int n = 0; n < kNumTests; ++n) { - UUT_->v8_[0](in, kInputStride, out, kOutputStride, eighttap, 8, 16, 8, 16, - width, height); - } - vpx_usec_timer_mark(&timer); - - const int elapsed_time = static_cast(vpx_usec_timer_elapsed(&timer)); - printf("convolve8_vert_%dx%d_%d: %d us\n", width, height, - UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time); -} - -TEST_P(ConvolveTest, DISABLED_4Tap_Speed) { - const uint8_t *const in = input(); - uint8_t *const out = output(); - const InterpKernel *const fourtap = vp9_filter_kernels[FOURTAP]; - const int kNumTests = 5000000; - const int width = Width(); - const int height = Height(); - vpx_usec_timer timer; - - SetConstantInput(127); - - vpx_usec_timer_start(&timer); - for (int n = 0; n < kNumTests; ++n) { - UUT_->hv8_[0](in, kInputStride, out, kOutputStride, fourtap, 8, 16, 8, 16, - width, height); - } - vpx_usec_timer_mark(&timer); - - const int elapsed_time = static_cast(vpx_usec_timer_elapsed(&timer)); - printf("convolve4_%dx%d_%d: %d us\n", width, height, - UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time); -} - -TEST_P(ConvolveTest, DISABLED_4Tap_Horiz_Speed) { - const uint8_t *const in = input(); - uint8_t *const out = output(); - const InterpKernel *const fourtap = vp9_filter_kernels[FOURTAP]; - const int kNumTests = 5000000; - const int width = Width(); - const int height = Height(); - vpx_usec_timer timer; - - SetConstantInput(127); - - vpx_usec_timer_start(&timer); - for (int n = 0; n < kNumTests; ++n) { - UUT_->h8_[0](in, kInputStride, out, kOutputStride, fourtap, 8, 16, 8, 16, - width, height); - } - vpx_usec_timer_mark(&timer); - - const int elapsed_time = static_cast(vpx_usec_timer_elapsed(&timer)); - printf("convolve4_horiz_%dx%d_%d: %d us\n", width, height, - UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time); -} - -TEST_P(ConvolveTest, DISABLED_4Tap_Vert_Speed) { - const uint8_t *const in = input(); - uint8_t *const out = output(); - const InterpKernel *const fourtap = vp9_filter_kernels[FOURTAP]; - const int kNumTests = 5000000; - const int width = Width(); - const int height = Height(); - vpx_usec_timer timer; - - SetConstantInput(127); - - vpx_usec_timer_start(&timer); - for (int n = 0; n < kNumTests; ++n) { - UUT_->v8_[0](in, kInputStride, out, kOutputStride, fourtap, 8, 16, 8, 16, - width, height); - } - vpx_usec_timer_mark(&timer); - - const int elapsed_time = static_cast(vpx_usec_timer_elapsed(&timer)); - printf("convolve4_vert_%dx%d_%d: %d us\n", width, height, - UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time); -} -TEST_P(ConvolveTest, DISABLED_8Tap_Avg_Speed) { - const uint8_t *const in = input(); - uint8_t *const out = output(); - const InterpKernel *const eighttap = vp9_filter_kernels[EIGHTTAP_SHARP]; - const int kNumTests = 5000000; - const int width = Width(); - const int height = Height(); - vpx_usec_timer timer; - - SetConstantInput(127); - - vpx_usec_timer_start(&timer); - for (int n = 0; n < kNumTests; ++n) { - UUT_->hv8_[1](in, kInputStride, out, kOutputStride, eighttap, 8, 16, 8, 16, - width, height); - } - vpx_usec_timer_mark(&timer); - - const int elapsed_time = static_cast(vpx_usec_timer_elapsed(&timer)); - printf("convolve8_avg_%dx%d_%d: %d us\n", width, height, - UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time); -} - -TEST_P(ConvolveTest, Copy) { - uint8_t *const in = input(); - uint8_t *const out = output(); - - ASM_REGISTER_STATE_CHECK(UUT_->copy_[0](in, kInputStride, out, kOutputStride, - nullptr, 0, 0, 0, 0, Width(), - Height())); - - CheckGuardBlocks(); - - for (int y = 0; y < Height(); ++y) { - for (int x = 0; x < Width(); ++x) - ASSERT_EQ(lookup(out, y * kOutputStride + x), - lookup(in, y * kInputStride + x)) - << "(" << x << "," << y << ")"; - } -} - -TEST_P(ConvolveTest, Avg) { - uint8_t *const in = input(); - uint8_t *const out = output(); - uint8_t *const out_ref = output_ref(); - CopyOutputToRef(); - - ASM_REGISTER_STATE_CHECK(UUT_->copy_[1](in, kInputStride, out, kOutputStride, - nullptr, 0, 0, 0, 0, Width(), - Height())); - - CheckGuardBlocks(); - - for (int y = 0; y < Height(); ++y) { - for (int x = 0; x < Width(); ++x) - ASSERT_EQ(lookup(out, y * kOutputStride + x), - ROUND_POWER_OF_TWO(lookup(in, y * kInputStride + x) + - lookup(out_ref, y * kOutputStride + x), - 1)) - << "(" << x << "," << y << ")"; - } -} - -TEST_P(ConvolveTest, CopyHoriz) { - uint8_t *const in = input(); - uint8_t *const out = output(); - - ASM_REGISTER_STATE_CHECK(UUT_->sh8_[0](in, kInputStride, out, kOutputStride, - vp9_filter_kernels[0], 0, 16, 0, 16, - Width(), Height())); - - CheckGuardBlocks(); - - for (int y = 0; y < Height(); ++y) { - for (int x = 0; x < Width(); ++x) - ASSERT_EQ(lookup(out, y * kOutputStride + x), - lookup(in, y * kInputStride + x)) - << "(" << x << "," << y << ")"; - } -} - -TEST_P(ConvolveTest, CopyVert) { - uint8_t *const in = input(); - uint8_t *const out = output(); - - ASM_REGISTER_STATE_CHECK(UUT_->sv8_[0](in, kInputStride, out, kOutputStride, - vp9_filter_kernels[0], 0, 16, 0, 16, - Width(), Height())); - - CheckGuardBlocks(); - - for (int y = 0; y < Height(); ++y) { - for (int x = 0; x < Width(); ++x) - ASSERT_EQ(lookup(out, y * kOutputStride + x), - lookup(in, y * kInputStride + x)) - << "(" << x << "," << y << ")"; - } -} - -TEST_P(ConvolveTest, Copy2D) { - uint8_t *const in = input(); - uint8_t *const out = output(); - - ASM_REGISTER_STATE_CHECK(UUT_->shv8_[0](in, kInputStride, out, kOutputStride, - vp9_filter_kernels[0], 0, 16, 0, 16, - Width(), Height())); - - CheckGuardBlocks(); - - for (int y = 0; y < Height(); ++y) { - for (int x = 0; x < Width(); ++x) - ASSERT_EQ(lookup(out, y * kOutputStride + x), - lookup(in, y * kInputStride + x)) - << "(" << x << "," << y << ")"; - } -} - -const int kNumFilterBanks = 5; -const int kNumFilters = 16; - -TEST(ConvolveTest, FiltersWontSaturateWhenAddedPairwise) { - for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) { - const InterpKernel *filters = - vp9_filter_kernels[static_cast(filter_bank)]; - for (int i = 0; i < kNumFilters; i++) { - const int p0 = filters[i][0] + filters[i][1]; - const int p1 = filters[i][2] + filters[i][3]; - const int p2 = filters[i][4] + filters[i][5]; - const int p3 = filters[i][6] + filters[i][7]; - EXPECT_LE(p0, 128); - EXPECT_LE(p1, 128); - EXPECT_LE(p2, 128); - EXPECT_LE(p3, 128); - EXPECT_LE(p0 + p3, 128); - EXPECT_LE(p0 + p3 + p1, 128); - EXPECT_LE(p0 + p3 + p1 + p2, 128); - EXPECT_EQ(p0 + p1 + p2 + p3, 128); - } - } -} - -const WrapperFilterBlock2d8Func wrapper_filter_block2d_8[2] = { - wrapper_filter_block2d_8_c, wrapper_filter_average_block2d_8_c -}; - -TEST_P(ConvolveTest, MatchesReferenceSubpixelFilter) { - for (int i = 0; i < 2; ++i) { - uint8_t *const in = input(); - uint8_t *const out = output(); -#if CONFIG_VP9_HIGHBITDEPTH - uint8_t ref8[kOutputStride * kMaxDimension]; - uint16_t ref16[kOutputStride * kMaxDimension]; - uint8_t *ref; - if (UUT_->use_highbd_ == 0) { - ref = ref8; - } else { - ref = CAST_TO_BYTEPTR(ref16); - } -#else - uint8_t ref[kOutputStride * kMaxDimension]; -#endif - - // Populate ref and out with some random data - ::libvpx_test::ACMRandom prng; - for (int y = 0; y < Height(); ++y) { - for (int x = 0; x < Width(); ++x) { - uint16_t r; -#if CONFIG_VP9_HIGHBITDEPTH - if (UUT_->use_highbd_ == 0 || UUT_->use_highbd_ == 8) { - r = prng.Rand8Extremes(); - } else { - r = prng.Rand16() & mask_; - } -#else - r = prng.Rand8Extremes(); -#endif - - assign_val(out, y * kOutputStride + x, r); - assign_val(ref, y * kOutputStride + x, r); - } - } - - for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) { - const InterpKernel *filters = - vp9_filter_kernels[static_cast(filter_bank)]; - - for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) { - for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) { - wrapper_filter_block2d_8[i](in, kInputStride, filters[filter_x], - filters[filter_y], ref, kOutputStride, - Width(), Height(), UUT_->use_highbd_); - - if (filter_x && filter_y) - ASM_REGISTER_STATE_CHECK( - UUT_->hv8_[i](in, kInputStride, out, kOutputStride, filters, - filter_x, 16, filter_y, 16, Width(), Height())); - else if (filter_y) - ASM_REGISTER_STATE_CHECK( - UUT_->v8_[i](in, kInputStride, out, kOutputStride, filters, 0, - 16, filter_y, 16, Width(), Height())); - else if (filter_x) - ASM_REGISTER_STATE_CHECK( - UUT_->h8_[i](in, kInputStride, out, kOutputStride, filters, - filter_x, 16, 0, 16, Width(), Height())); - else - ASM_REGISTER_STATE_CHECK( - UUT_->copy_[i](in, kInputStride, out, kOutputStride, nullptr, 0, - 0, 0, 0, Width(), Height())); - - CheckGuardBlocks(); - - for (int y = 0; y < Height(); ++y) { - for (int x = 0; x < Width(); ++x) - ASSERT_EQ(lookup(ref, y * kOutputStride + x), - lookup(out, y * kOutputStride + x)) - << "mismatch at (" << x << "," << y << "), " - << "filters (" << filter_bank << "," << filter_x << "," - << filter_y << ")"; - } - } - } - } - } -} - -TEST_P(ConvolveTest, FilterExtremes) { - uint8_t *const in = input(); - uint8_t *const out = output(); -#if CONFIG_VP9_HIGHBITDEPTH - uint8_t ref8[kOutputStride * kMaxDimension]; - uint16_t ref16[kOutputStride * kMaxDimension]; - uint8_t *ref; - if (UUT_->use_highbd_ == 0) { - ref = ref8; - } else { - ref = CAST_TO_BYTEPTR(ref16); - } -#else - uint8_t ref[kOutputStride * kMaxDimension]; -#endif - - // Populate ref and out with some random data - ::libvpx_test::ACMRandom prng; - for (int y = 0; y < Height(); ++y) { - for (int x = 0; x < Width(); ++x) { - uint16_t r; -#if CONFIG_VP9_HIGHBITDEPTH - if (UUT_->use_highbd_ == 0 || UUT_->use_highbd_ == 8) { - r = prng.Rand8Extremes(); - } else { - r = prng.Rand16() & mask_; - } -#else - r = prng.Rand8Extremes(); -#endif - assign_val(out, y * kOutputStride + x, r); - assign_val(ref, y * kOutputStride + x, r); - } - } - - for (int axis = 0; axis < 2; axis++) { - int seed_val = 0; - while (seed_val < 256) { - for (int y = 0; y < 8; ++y) { - for (int x = 0; x < 8; ++x) { -#if CONFIG_VP9_HIGHBITDEPTH - assign_val(in, y * kOutputStride + x - SUBPEL_TAPS / 2 + 1, - ((seed_val >> (axis ? y : x)) & 1) * mask_); -#else - assign_val(in, y * kOutputStride + x - SUBPEL_TAPS / 2 + 1, - ((seed_val >> (axis ? y : x)) & 1) * 255); -#endif - if (axis) seed_val++; - } - if (axis) { - seed_val -= 8; - } else { - seed_val++; - } - } - if (axis) seed_val += 8; - - for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) { - const InterpKernel *filters = - vp9_filter_kernels[static_cast(filter_bank)]; - for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) { - for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) { - wrapper_filter_block2d_8_c(in, kInputStride, filters[filter_x], - filters[filter_y], ref, kOutputStride, - Width(), Height(), UUT_->use_highbd_); - if (filter_x && filter_y) - ASM_REGISTER_STATE_CHECK( - UUT_->hv8_[0](in, kInputStride, out, kOutputStride, filters, - filter_x, 16, filter_y, 16, Width(), Height())); - else if (filter_y) - ASM_REGISTER_STATE_CHECK( - UUT_->v8_[0](in, kInputStride, out, kOutputStride, filters, 0, - 16, filter_y, 16, Width(), Height())); - else if (filter_x) - ASM_REGISTER_STATE_CHECK( - UUT_->h8_[0](in, kInputStride, out, kOutputStride, filters, - filter_x, 16, 0, 16, Width(), Height())); - else - ASM_REGISTER_STATE_CHECK( - UUT_->copy_[0](in, kInputStride, out, kOutputStride, nullptr, - 0, 0, 0, 0, Width(), Height())); - - for (int y = 0; y < Height(); ++y) { - for (int x = 0; x < Width(); ++x) - ASSERT_EQ(lookup(ref, y * kOutputStride + x), - lookup(out, y * kOutputStride + x)) - << "mismatch at (" << x << "," << y << "), " - << "filters (" << filter_bank << "," << filter_x << "," - << filter_y << ")"; - } - } - } - } - } - } -} - -/* This test exercises that enough rows and columns are filtered with every - possible initial fractional positions and scaling steps. */ -#if !CONFIG_VP9_HIGHBITDEPTH -static const ConvolveFunc scaled_2d_c_funcs[2] = { vpx_scaled_2d_c, - vpx_scaled_avg_2d_c }; - -TEST_P(ConvolveTest, CheckScalingFiltering) { - uint8_t *const in = input(); - uint8_t *const out = output(); - uint8_t ref[kOutputStride * kMaxDimension]; - - ::libvpx_test::ACMRandom prng; - for (int y = 0; y < Height(); ++y) { - for (int x = 0; x < Width(); ++x) { - const uint16_t r = prng.Rand8Extremes(); - assign_val(in, y * kInputStride + x, r); - } - } - - for (int i = 0; i < 2; ++i) { - for (INTERP_FILTER filter_type = 0; filter_type < 4; ++filter_type) { - const InterpKernel *const eighttap = vp9_filter_kernels[filter_type]; - for (int frac = 0; frac < 16; ++frac) { - for (int step = 1; step <= 32; ++step) { - /* Test the horizontal and vertical filters in combination. */ - scaled_2d_c_funcs[i](in, kInputStride, ref, kOutputStride, eighttap, - frac, step, frac, step, Width(), Height()); - ASM_REGISTER_STATE_CHECK( - UUT_->shv8_[i](in, kInputStride, out, kOutputStride, eighttap, - frac, step, frac, step, Width(), Height())); - - CheckGuardBlocks(); - - for (int y = 0; y < Height(); ++y) { - for (int x = 0; x < Width(); ++x) { - ASSERT_EQ(lookup(ref, y * kOutputStride + x), - lookup(out, y * kOutputStride + x)) - << "x == " << x << ", y == " << y << ", frac == " << frac - << ", step == " << step; - } - } - } - } - } - } -} -#endif - -using std::make_tuple; - -#if CONFIG_VP9_HIGHBITDEPTH -#define WRAP(func, bd) \ - void wrap_##func##_##bd( \ - const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, \ - ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, \ - int x_step_q4, int y0_q4, int y_step_q4, int w, int h) { \ - vpx_highbd_##func(reinterpret_cast(src), src_stride, \ - reinterpret_cast(dst), dst_stride, filter, \ - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h, bd); \ - } - -#if HAVE_SSE2 && VPX_ARCH_X86_64 -WRAP(convolve_copy_sse2, 8) -WRAP(convolve_avg_sse2, 8) -WRAP(convolve_copy_sse2, 10) -WRAP(convolve_avg_sse2, 10) -WRAP(convolve_copy_sse2, 12) -WRAP(convolve_avg_sse2, 12) -WRAP(convolve8_horiz_sse2, 8) -WRAP(convolve8_avg_horiz_sse2, 8) -WRAP(convolve8_vert_sse2, 8) -WRAP(convolve8_avg_vert_sse2, 8) -WRAP(convolve8_sse2, 8) -WRAP(convolve8_avg_sse2, 8) -WRAP(convolve8_horiz_sse2, 10) -WRAP(convolve8_avg_horiz_sse2, 10) -WRAP(convolve8_vert_sse2, 10) -WRAP(convolve8_avg_vert_sse2, 10) -WRAP(convolve8_sse2, 10) -WRAP(convolve8_avg_sse2, 10) -WRAP(convolve8_horiz_sse2, 12) -WRAP(convolve8_avg_horiz_sse2, 12) -WRAP(convolve8_vert_sse2, 12) -WRAP(convolve8_avg_vert_sse2, 12) -WRAP(convolve8_sse2, 12) -WRAP(convolve8_avg_sse2, 12) -#endif // HAVE_SSE2 && VPX_ARCH_X86_64 - -#if HAVE_AVX2 -WRAP(convolve_copy_avx2, 8) -WRAP(convolve_avg_avx2, 8) -WRAP(convolve8_horiz_avx2, 8) -WRAP(convolve8_avg_horiz_avx2, 8) -WRAP(convolve8_vert_avx2, 8) -WRAP(convolve8_avg_vert_avx2, 8) -WRAP(convolve8_avx2, 8) -WRAP(convolve8_avg_avx2, 8) - -WRAP(convolve_copy_avx2, 10) -WRAP(convolve_avg_avx2, 10) -WRAP(convolve8_avx2, 10) -WRAP(convolve8_horiz_avx2, 10) -WRAP(convolve8_vert_avx2, 10) -WRAP(convolve8_avg_avx2, 10) -WRAP(convolve8_avg_horiz_avx2, 10) -WRAP(convolve8_avg_vert_avx2, 10) - -WRAP(convolve_copy_avx2, 12) -WRAP(convolve_avg_avx2, 12) -WRAP(convolve8_avx2, 12) -WRAP(convolve8_horiz_avx2, 12) -WRAP(convolve8_vert_avx2, 12) -WRAP(convolve8_avg_avx2, 12) -WRAP(convolve8_avg_horiz_avx2, 12) -WRAP(convolve8_avg_vert_avx2, 12) -#endif // HAVE_AVX2 - -#if HAVE_NEON -WRAP(convolve_copy_neon, 8) -WRAP(convolve_avg_neon, 8) -WRAP(convolve_copy_neon, 10) -WRAP(convolve_avg_neon, 10) -WRAP(convolve_copy_neon, 12) -WRAP(convolve_avg_neon, 12) -WRAP(convolve8_horiz_neon, 8) -WRAP(convolve8_avg_horiz_neon, 8) -WRAP(convolve8_vert_neon, 8) -WRAP(convolve8_avg_vert_neon, 8) -WRAP(convolve8_neon, 8) -WRAP(convolve8_avg_neon, 8) -WRAP(convolve8_horiz_neon, 10) -WRAP(convolve8_avg_horiz_neon, 10) -WRAP(convolve8_vert_neon, 10) -WRAP(convolve8_avg_vert_neon, 10) -WRAP(convolve8_neon, 10) -WRAP(convolve8_avg_neon, 10) -WRAP(convolve8_horiz_neon, 12) -WRAP(convolve8_avg_horiz_neon, 12) -WRAP(convolve8_vert_neon, 12) -WRAP(convolve8_avg_vert_neon, 12) -WRAP(convolve8_neon, 12) -WRAP(convolve8_avg_neon, 12) -#endif // HAVE_NEON - -#if HAVE_SVE -WRAP(convolve8_horiz_sve, 8) -WRAP(convolve8_avg_horiz_sve, 8) -WRAP(convolve8_horiz_sve, 10) -WRAP(convolve8_avg_horiz_sve, 10) -WRAP(convolve8_horiz_sve, 12) -WRAP(convolve8_avg_horiz_sve, 12) -#endif // HAVE_SVE - -#if HAVE_SVE2 -WRAP(convolve8_sve2, 8) -WRAP(convolve8_avg_sve2, 8) -WRAP(convolve8_vert_sve2, 8) -WRAP(convolve8_avg_vert_sve2, 8) -WRAP(convolve8_sve2, 10) -WRAP(convolve8_avg_sve2, 10) -WRAP(convolve8_vert_sve2, 10) -WRAP(convolve8_avg_vert_sve2, 10) -WRAP(convolve8_sve2, 12) -WRAP(convolve8_avg_sve2, 12) -WRAP(convolve8_vert_sve2, 12) -WRAP(convolve8_avg_vert_sve2, 12) -#endif // HAVE_SVE2 - -WRAP(convolve_copy_c, 8) -WRAP(convolve_avg_c, 8) -WRAP(convolve8_horiz_c, 8) -WRAP(convolve8_avg_horiz_c, 8) -WRAP(convolve8_vert_c, 8) -WRAP(convolve8_avg_vert_c, 8) -WRAP(convolve8_c, 8) -WRAP(convolve8_avg_c, 8) -WRAP(convolve_copy_c, 10) -WRAP(convolve_avg_c, 10) -WRAP(convolve8_horiz_c, 10) -WRAP(convolve8_avg_horiz_c, 10) -WRAP(convolve8_vert_c, 10) -WRAP(convolve8_avg_vert_c, 10) -WRAP(convolve8_c, 10) -WRAP(convolve8_avg_c, 10) -WRAP(convolve_copy_c, 12) -WRAP(convolve_avg_c, 12) -WRAP(convolve8_horiz_c, 12) -WRAP(convolve8_avg_horiz_c, 12) -WRAP(convolve8_vert_c, 12) -WRAP(convolve8_avg_vert_c, 12) -WRAP(convolve8_c, 12) -WRAP(convolve8_avg_c, 12) -#undef WRAP - -const ConvolveFunctions convolve8_c( - wrap_convolve_copy_c_8, wrap_convolve_avg_c_8, wrap_convolve8_horiz_c_8, - wrap_convolve8_avg_horiz_c_8, wrap_convolve8_vert_c_8, - wrap_convolve8_avg_vert_c_8, wrap_convolve8_c_8, wrap_convolve8_avg_c_8, - wrap_convolve8_horiz_c_8, wrap_convolve8_avg_horiz_c_8, - wrap_convolve8_vert_c_8, wrap_convolve8_avg_vert_c_8, wrap_convolve8_c_8, - wrap_convolve8_avg_c_8, 8); -const ConvolveFunctions convolve10_c( - wrap_convolve_copy_c_10, wrap_convolve_avg_c_10, wrap_convolve8_horiz_c_10, - wrap_convolve8_avg_horiz_c_10, wrap_convolve8_vert_c_10, - wrap_convolve8_avg_vert_c_10, wrap_convolve8_c_10, wrap_convolve8_avg_c_10, - wrap_convolve8_horiz_c_10, wrap_convolve8_avg_horiz_c_10, - wrap_convolve8_vert_c_10, wrap_convolve8_avg_vert_c_10, wrap_convolve8_c_10, - wrap_convolve8_avg_c_10, 10); -const ConvolveFunctions convolve12_c( - wrap_convolve_copy_c_12, wrap_convolve_avg_c_12, wrap_convolve8_horiz_c_12, - wrap_convolve8_avg_horiz_c_12, wrap_convolve8_vert_c_12, - wrap_convolve8_avg_vert_c_12, wrap_convolve8_c_12, wrap_convolve8_avg_c_12, - wrap_convolve8_horiz_c_12, wrap_convolve8_avg_horiz_c_12, - wrap_convolve8_vert_c_12, wrap_convolve8_avg_vert_c_12, wrap_convolve8_c_12, - wrap_convolve8_avg_c_12, 12); -const ConvolveParam kArrayConvolve_c[] = { ALL_SIZES(convolve8_c), - ALL_SIZES(convolve10_c), - ALL_SIZES(convolve12_c) }; - -#else -const ConvolveFunctions convolve8_c( - vpx_convolve_copy_c, vpx_convolve_avg_c, vpx_convolve8_horiz_c, - vpx_convolve8_avg_horiz_c, vpx_convolve8_vert_c, vpx_convolve8_avg_vert_c, - vpx_convolve8_c, vpx_convolve8_avg_c, vpx_scaled_horiz_c, - vpx_scaled_avg_horiz_c, vpx_scaled_vert_c, vpx_scaled_avg_vert_c, - vpx_scaled_2d_c, vpx_scaled_avg_2d_c, 0); -const ConvolveParam kArrayConvolve_c[] = { ALL_SIZES(convolve8_c) }; -#endif -INSTANTIATE_TEST_SUITE_P(C, ConvolveTest, - ::testing::ValuesIn(kArrayConvolve_c)); - -#if HAVE_SSE2 && VPX_ARCH_X86_64 -#if CONFIG_VP9_HIGHBITDEPTH -const ConvolveFunctions convolve8_sse2( - wrap_convolve_copy_sse2_8, wrap_convolve_avg_sse2_8, - wrap_convolve8_horiz_sse2_8, wrap_convolve8_avg_horiz_sse2_8, - wrap_convolve8_vert_sse2_8, wrap_convolve8_avg_vert_sse2_8, - wrap_convolve8_sse2_8, wrap_convolve8_avg_sse2_8, - wrap_convolve8_horiz_sse2_8, wrap_convolve8_avg_horiz_sse2_8, - wrap_convolve8_vert_sse2_8, wrap_convolve8_avg_vert_sse2_8, - wrap_convolve8_sse2_8, wrap_convolve8_avg_sse2_8, 8); -const ConvolveFunctions convolve10_sse2( - wrap_convolve_copy_sse2_10, wrap_convolve_avg_sse2_10, - wrap_convolve8_horiz_sse2_10, wrap_convolve8_avg_horiz_sse2_10, - wrap_convolve8_vert_sse2_10, wrap_convolve8_avg_vert_sse2_10, - wrap_convolve8_sse2_10, wrap_convolve8_avg_sse2_10, - wrap_convolve8_horiz_sse2_10, wrap_convolve8_avg_horiz_sse2_10, - wrap_convolve8_vert_sse2_10, wrap_convolve8_avg_vert_sse2_10, - wrap_convolve8_sse2_10, wrap_convolve8_avg_sse2_10, 10); -const ConvolveFunctions convolve12_sse2( - wrap_convolve_copy_sse2_12, wrap_convolve_avg_sse2_12, - wrap_convolve8_horiz_sse2_12, wrap_convolve8_avg_horiz_sse2_12, - wrap_convolve8_vert_sse2_12, wrap_convolve8_avg_vert_sse2_12, - wrap_convolve8_sse2_12, wrap_convolve8_avg_sse2_12, - wrap_convolve8_horiz_sse2_12, wrap_convolve8_avg_horiz_sse2_12, - wrap_convolve8_vert_sse2_12, wrap_convolve8_avg_vert_sse2_12, - wrap_convolve8_sse2_12, wrap_convolve8_avg_sse2_12, 12); -const ConvolveParam kArrayConvolve_sse2[] = { ALL_SIZES(convolve8_sse2), - ALL_SIZES(convolve10_sse2), - ALL_SIZES(convolve12_sse2) }; -#else -const ConvolveFunctions convolve8_sse2( - vpx_convolve_copy_sse2, vpx_convolve_avg_sse2, vpx_convolve8_horiz_sse2, - vpx_convolve8_avg_horiz_sse2, vpx_convolve8_vert_sse2, - vpx_convolve8_avg_vert_sse2, vpx_convolve8_sse2, vpx_convolve8_avg_sse2, - vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, vpx_scaled_vert_c, - vpx_scaled_avg_vert_c, vpx_scaled_2d_c, vpx_scaled_avg_2d_c, 0); - -const ConvolveParam kArrayConvolve_sse2[] = { ALL_SIZES(convolve8_sse2) }; -#endif // CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P(SSE2, ConvolveTest, - ::testing::ValuesIn(kArrayConvolve_sse2)); -#endif - -#if HAVE_SSSE3 -const ConvolveFunctions convolve8_ssse3( - vpx_convolve_copy_c, vpx_convolve_avg_c, vpx_convolve8_horiz_ssse3, - vpx_convolve8_avg_horiz_ssse3, vpx_convolve8_vert_ssse3, - vpx_convolve8_avg_vert_ssse3, vpx_convolve8_ssse3, vpx_convolve8_avg_ssse3, - vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, vpx_scaled_vert_c, - vpx_scaled_avg_vert_c, vpx_scaled_2d_ssse3, vpx_scaled_avg_2d_c, 0); - -const ConvolveParam kArrayConvolve8_ssse3[] = { ALL_SIZES(convolve8_ssse3) }; -INSTANTIATE_TEST_SUITE_P(SSSE3, ConvolveTest, - ::testing::ValuesIn(kArrayConvolve8_ssse3)); -#endif - -#if HAVE_AVX2 -#if CONFIG_VP9_HIGHBITDEPTH -const ConvolveFunctions convolve8_avx2( - wrap_convolve_copy_avx2_8, wrap_convolve_avg_avx2_8, - wrap_convolve8_horiz_avx2_8, wrap_convolve8_avg_horiz_avx2_8, - wrap_convolve8_vert_avx2_8, wrap_convolve8_avg_vert_avx2_8, - wrap_convolve8_avx2_8, wrap_convolve8_avg_avx2_8, wrap_convolve8_horiz_c_8, - wrap_convolve8_avg_horiz_c_8, wrap_convolve8_vert_c_8, - wrap_convolve8_avg_vert_c_8, wrap_convolve8_c_8, wrap_convolve8_avg_c_8, 8); -const ConvolveFunctions convolve10_avx2( - wrap_convolve_copy_avx2_10, wrap_convolve_avg_avx2_10, - wrap_convolve8_horiz_avx2_10, wrap_convolve8_avg_horiz_avx2_10, - wrap_convolve8_vert_avx2_10, wrap_convolve8_avg_vert_avx2_10, - wrap_convolve8_avx2_10, wrap_convolve8_avg_avx2_10, - wrap_convolve8_horiz_c_10, wrap_convolve8_avg_horiz_c_10, - wrap_convolve8_vert_c_10, wrap_convolve8_avg_vert_c_10, wrap_convolve8_c_10, - wrap_convolve8_avg_c_10, 10); -const ConvolveFunctions convolve12_avx2( - wrap_convolve_copy_avx2_12, wrap_convolve_avg_avx2_12, - wrap_convolve8_horiz_avx2_12, wrap_convolve8_avg_horiz_avx2_12, - wrap_convolve8_vert_avx2_12, wrap_convolve8_avg_vert_avx2_12, - wrap_convolve8_avx2_12, wrap_convolve8_avg_avx2_12, - wrap_convolve8_horiz_c_12, wrap_convolve8_avg_horiz_c_12, - wrap_convolve8_vert_c_12, wrap_convolve8_avg_vert_c_12, wrap_convolve8_c_12, - wrap_convolve8_avg_c_12, 12); -const ConvolveParam kArrayConvolve8_avx2[] = { ALL_SIZES(convolve8_avx2), - ALL_SIZES(convolve10_avx2), - ALL_SIZES(convolve12_avx2) }; -INSTANTIATE_TEST_SUITE_P(AVX2, ConvolveTest, - ::testing::ValuesIn(kArrayConvolve8_avx2)); -#else // !CONFIG_VP9_HIGHBITDEPTH -const ConvolveFunctions convolve8_avx2( - vpx_convolve_copy_c, vpx_convolve_avg_c, vpx_convolve8_horiz_avx2, - vpx_convolve8_avg_horiz_avx2, vpx_convolve8_vert_avx2, - vpx_convolve8_avg_vert_avx2, vpx_convolve8_avx2, vpx_convolve8_avg_avx2, - vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, vpx_scaled_vert_c, - vpx_scaled_avg_vert_c, vpx_scaled_2d_c, vpx_scaled_avg_2d_c, 0); -const ConvolveParam kArrayConvolve8_avx2[] = { ALL_SIZES(convolve8_avx2) }; -INSTANTIATE_TEST_SUITE_P(AVX2, ConvolveTest, - ::testing::ValuesIn(kArrayConvolve8_avx2)); -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif // HAVE_AVX2 - -#if HAVE_NEON -#if CONFIG_VP9_HIGHBITDEPTH -const ConvolveFunctions convolve8_neon( - wrap_convolve_copy_neon_8, wrap_convolve_avg_neon_8, - wrap_convolve8_horiz_neon_8, wrap_convolve8_avg_horiz_neon_8, - wrap_convolve8_vert_neon_8, wrap_convolve8_avg_vert_neon_8, - wrap_convolve8_neon_8, wrap_convolve8_avg_neon_8, - wrap_convolve8_horiz_neon_8, wrap_convolve8_avg_horiz_neon_8, - wrap_convolve8_vert_neon_8, wrap_convolve8_avg_vert_neon_8, - wrap_convolve8_neon_8, wrap_convolve8_avg_neon_8, 8); -const ConvolveFunctions convolve10_neon( - wrap_convolve_copy_neon_10, wrap_convolve_avg_neon_10, - wrap_convolve8_horiz_neon_10, wrap_convolve8_avg_horiz_neon_10, - wrap_convolve8_vert_neon_10, wrap_convolve8_avg_vert_neon_10, - wrap_convolve8_neon_10, wrap_convolve8_avg_neon_10, - wrap_convolve8_horiz_neon_10, wrap_convolve8_avg_horiz_neon_10, - wrap_convolve8_vert_neon_10, wrap_convolve8_avg_vert_neon_10, - wrap_convolve8_neon_10, wrap_convolve8_avg_neon_10, 10); -const ConvolveFunctions convolve12_neon( - wrap_convolve_copy_neon_12, wrap_convolve_avg_neon_12, - wrap_convolve8_horiz_neon_12, wrap_convolve8_avg_horiz_neon_12, - wrap_convolve8_vert_neon_12, wrap_convolve8_avg_vert_neon_12, - wrap_convolve8_neon_12, wrap_convolve8_avg_neon_12, - wrap_convolve8_horiz_neon_12, wrap_convolve8_avg_horiz_neon_12, - wrap_convolve8_vert_neon_12, wrap_convolve8_avg_vert_neon_12, - wrap_convolve8_neon_12, wrap_convolve8_avg_neon_12, 12); -const ConvolveParam kArrayConvolve_neon[] = { ALL_SIZES(convolve8_neon), - ALL_SIZES(convolve10_neon), - ALL_SIZES(convolve12_neon) }; -#else -const ConvolveFunctions convolve8_neon( - vpx_convolve_copy_neon, vpx_convolve_avg_neon, vpx_convolve8_horiz_neon, - vpx_convolve8_avg_horiz_neon, vpx_convolve8_vert_neon, - vpx_convolve8_avg_vert_neon, vpx_convolve8_neon, vpx_convolve8_avg_neon, - vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, vpx_scaled_vert_c, - vpx_scaled_avg_vert_c, vpx_scaled_2d_neon, vpx_scaled_avg_2d_c, 0); - -const ConvolveParam kArrayConvolve_neon[] = { ALL_SIZES(convolve8_neon) }; -#endif // CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P(NEON, ConvolveTest, - ::testing::ValuesIn(kArrayConvolve_neon)); -#endif // HAVE_NEON - -#if HAVE_NEON_DOTPROD -const ConvolveFunctions convolve8_neon_dotprod( - vpx_convolve_copy_c, vpx_convolve_avg_c, vpx_convolve8_horiz_neon_dotprod, - vpx_convolve8_avg_horiz_neon_dotprod, vpx_convolve8_vert_neon_dotprod, - vpx_convolve8_avg_vert_neon_dotprod, vpx_convolve8_neon_dotprod, - vpx_convolve8_avg_neon_dotprod, vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, - vpx_scaled_vert_c, vpx_scaled_avg_vert_c, vpx_scaled_2d_c, - vpx_scaled_avg_2d_c, 0); - -const ConvolveParam kArrayConvolve_neon_dotprod[] = { ALL_SIZES( - convolve8_neon_dotprod) }; -INSTANTIATE_TEST_SUITE_P(NEON_DOTPROD, ConvolveTest, - ::testing::ValuesIn(kArrayConvolve_neon_dotprod)); -#endif // HAVE_NEON_DOTPROD - -#if HAVE_SVE -#if CONFIG_VP9_HIGHBITDEPTH -const ConvolveFunctions convolve8_sve( - wrap_convolve_copy_c_8, wrap_convolve_avg_c_8, wrap_convolve8_horiz_sve_8, - wrap_convolve8_avg_horiz_sve_8, wrap_convolve8_vert_c_8, - wrap_convolve8_avg_vert_c_8, wrap_convolve8_c_8, wrap_convolve8_avg_c_8, - wrap_convolve8_horiz_c_8, wrap_convolve8_avg_horiz_c_8, - wrap_convolve8_vert_c_8, wrap_convolve8_avg_vert_c_8, wrap_convolve8_c_8, - wrap_convolve8_avg_c_8, 8); -const ConvolveFunctions convolve10_sve( - wrap_convolve_copy_c_10, wrap_convolve_avg_c_10, - wrap_convolve8_horiz_sve_10, wrap_convolve8_avg_horiz_sve_10, - wrap_convolve8_vert_c_10, wrap_convolve8_avg_vert_c_10, wrap_convolve8_c_10, - wrap_convolve8_avg_c_10, wrap_convolve8_horiz_c_10, - wrap_convolve8_avg_horiz_c_10, wrap_convolve8_vert_c_10, - wrap_convolve8_avg_vert_c_10, wrap_convolve8_c_10, wrap_convolve8_avg_c_10, - 10); -const ConvolveFunctions convolve12_sve( - wrap_convolve_copy_c_12, wrap_convolve_avg_c_12, - wrap_convolve8_horiz_sve_12, wrap_convolve8_avg_horiz_sve_12, - wrap_convolve8_vert_c_12, wrap_convolve8_avg_vert_c_12, wrap_convolve8_c_12, - wrap_convolve8_avg_c_12, wrap_convolve8_horiz_c_12, - wrap_convolve8_avg_horiz_c_12, wrap_convolve8_vert_c_12, - wrap_convolve8_avg_vert_c_12, wrap_convolve8_c_12, wrap_convolve8_avg_c_12, - 12); - -const ConvolveParam kArrayConvolve_sve[] = { ALL_SIZES(convolve8_sve), - ALL_SIZES(convolve10_sve), - ALL_SIZES(convolve12_sve) }; -INSTANTIATE_TEST_SUITE_P(SVE, ConvolveTest, - ::testing::ValuesIn(kArrayConvolve_sve)); -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif // HAVE_SVE - -#if HAVE_SVE2 -#if CONFIG_VP9_HIGHBITDEPTH -const ConvolveFunctions convolve8_sve2( - wrap_convolve_copy_c_8, wrap_convolve_avg_c_8, wrap_convolve8_horiz_c_8, - wrap_convolve8_avg_horiz_c_8, wrap_convolve8_vert_sve2_8, - wrap_convolve8_avg_vert_sve2_8, wrap_convolve8_sve2_8, - wrap_convolve8_avg_sve2_8, wrap_convolve8_horiz_c_8, - wrap_convolve8_avg_horiz_c_8, wrap_convolve8_vert_c_8, - wrap_convolve8_avg_vert_c_8, wrap_convolve8_c_8, wrap_convolve8_avg_c_8, 8); -const ConvolveFunctions convolve10_sve2( - wrap_convolve_copy_c_10, wrap_convolve_avg_c_10, wrap_convolve8_horiz_c_10, - wrap_convolve8_avg_horiz_c_10, wrap_convolve8_vert_sve2_10, - wrap_convolve8_avg_vert_sve2_10, wrap_convolve8_sve2_10, - wrap_convolve8_avg_sve2_10, wrap_convolve8_horiz_c_10, - wrap_convolve8_avg_horiz_c_10, wrap_convolve8_vert_c_10, - wrap_convolve8_avg_vert_c_10, wrap_convolve8_c_10, wrap_convolve8_avg_c_10, - 10); -const ConvolveFunctions convolve12_sve2( - wrap_convolve_copy_c_12, wrap_convolve_avg_c_12, wrap_convolve8_horiz_c_12, - wrap_convolve8_avg_horiz_c_12, wrap_convolve8_vert_sve2_12, - wrap_convolve8_avg_vert_sve2_12, wrap_convolve8_sve2_12, - wrap_convolve8_avg_sve2_12, wrap_convolve8_horiz_c_12, - wrap_convolve8_avg_horiz_c_12, wrap_convolve8_vert_c_12, - wrap_convolve8_avg_vert_c_12, wrap_convolve8_c_12, wrap_convolve8_avg_c_12, - 12); - -const ConvolveParam kArrayConvolve_sve2[] = { ALL_SIZES(convolve8_sve2), - ALL_SIZES(convolve10_sve2), - ALL_SIZES(convolve12_sve2) }; -INSTANTIATE_TEST_SUITE_P(SVE2, ConvolveTest, - ::testing::ValuesIn(kArrayConvolve_sve2)); -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif // HAVE_SVE2 - -#if HAVE_NEON_I8MM -const ConvolveFunctions convolve8_neon_i8mm( - vpx_convolve_copy_c, vpx_convolve_avg_c, vpx_convolve8_horiz_neon_i8mm, - vpx_convolve8_avg_horiz_neon_i8mm, vpx_convolve8_vert_neon_i8mm, - vpx_convolve8_avg_vert_neon_i8mm, vpx_convolve8_neon_i8mm, - vpx_convolve8_avg_neon_i8mm, vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, - vpx_scaled_vert_c, vpx_scaled_avg_vert_c, vpx_scaled_2d_c, - vpx_scaled_avg_2d_c, 0); - -const ConvolveParam kArrayConvolve_neon_i8mm[] = { ALL_SIZES( - convolve8_neon_i8mm) }; -INSTANTIATE_TEST_SUITE_P(NEON_I8MM, ConvolveTest, - ::testing::ValuesIn(kArrayConvolve_neon_i8mm)); -#endif // HAVE_NEON_I8MM - -#if HAVE_DSPR2 -const ConvolveFunctions convolve8_dspr2( - vpx_convolve_copy_dspr2, vpx_convolve_avg_dspr2, vpx_convolve8_horiz_dspr2, - vpx_convolve8_avg_horiz_dspr2, vpx_convolve8_vert_dspr2, - vpx_convolve8_avg_vert_dspr2, vpx_convolve8_dspr2, vpx_convolve8_avg_dspr2, - vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, vpx_scaled_vert_c, - vpx_scaled_avg_vert_c, vpx_scaled_2d_c, vpx_scaled_avg_2d_c, 0); - -const ConvolveParam kArrayConvolve8_dspr2[] = { ALL_SIZES(convolve8_dspr2) }; -INSTANTIATE_TEST_SUITE_P(DSPR2, ConvolveTest, - ::testing::ValuesIn(kArrayConvolve8_dspr2)); -#endif // HAVE_DSPR2 - -#if HAVE_MSA -const ConvolveFunctions convolve8_msa( - vpx_convolve_copy_msa, vpx_convolve_avg_msa, vpx_convolve8_horiz_msa, - vpx_convolve8_avg_horiz_msa, vpx_convolve8_vert_msa, - vpx_convolve8_avg_vert_msa, vpx_convolve8_msa, vpx_convolve8_avg_msa, - vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, vpx_scaled_vert_c, - vpx_scaled_avg_vert_c, vpx_scaled_2d_msa, vpx_scaled_avg_2d_c, 0); - -const ConvolveParam kArrayConvolve8_msa[] = { ALL_SIZES(convolve8_msa) }; -INSTANTIATE_TEST_SUITE_P(MSA, ConvolveTest, - ::testing::ValuesIn(kArrayConvolve8_msa)); -#endif // HAVE_MSA - -#if HAVE_LSX -const ConvolveFunctions convolve8_lsx( - vpx_convolve_copy_lsx, vpx_convolve_avg_lsx, vpx_convolve8_horiz_lsx, - vpx_convolve8_avg_horiz_lsx, vpx_convolve8_vert_lsx, - vpx_convolve8_avg_vert_lsx, vpx_convolve8_lsx, vpx_convolve8_avg_lsx, - vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, vpx_scaled_vert_c, - vpx_scaled_avg_vert_c, vpx_scaled_2d_c, vpx_scaled_avg_2d_c, 0); - -const ConvolveParam kArrayConvolve8_lsx[] = { ALL_SIZES(convolve8_lsx) }; -INSTANTIATE_TEST_SUITE_P(LSX, ConvolveTest, - ::testing::ValuesIn(kArrayConvolve8_lsx)); -#endif // HAVE_LSX - -#if HAVE_VSX -const ConvolveFunctions convolve8_vsx( - vpx_convolve_copy_vsx, vpx_convolve_avg_vsx, vpx_convolve8_horiz_vsx, - vpx_convolve8_avg_horiz_vsx, vpx_convolve8_vert_vsx, - vpx_convolve8_avg_vert_vsx, vpx_convolve8_vsx, vpx_convolve8_avg_vsx, - vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, vpx_scaled_vert_c, - vpx_scaled_avg_vert_c, vpx_scaled_2d_c, vpx_scaled_avg_2d_c, 0); -const ConvolveParam kArrayConvolve_vsx[] = { ALL_SIZES(convolve8_vsx) }; -INSTANTIATE_TEST_SUITE_P(VSX, ConvolveTest, - ::testing::ValuesIn(kArrayConvolve_vsx)); -#endif // HAVE_VSX - -#if HAVE_MMI -const ConvolveFunctions convolve8_mmi( - vpx_convolve_copy_c, vpx_convolve_avg_mmi, vpx_convolve8_horiz_mmi, - vpx_convolve8_avg_horiz_mmi, vpx_convolve8_vert_mmi, - vpx_convolve8_avg_vert_mmi, vpx_convolve8_mmi, vpx_convolve8_avg_mmi, - vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, vpx_scaled_vert_c, - vpx_scaled_avg_vert_c, vpx_scaled_2d_c, vpx_scaled_avg_2d_c, 0); -const ConvolveParam kArrayConvolve_mmi[] = { ALL_SIZES(convolve8_mmi) }; -INSTANTIATE_TEST_SUITE_P(MMI, ConvolveTest, - ::testing::ValuesIn(kArrayConvolve_mmi)); -#endif // HAVE_MMI -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/cpu_speed_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/cpu_speed_test.cc deleted file mode 100644 index 6e0a0466..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/cpu_speed_test.cc +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" -#include "test/y4m_video_source.h" - -namespace { - -const int kMaxPSNR = 100; - -class CpuSpeedTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith2Params { - protected: - CpuSpeedTest() - : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)), - set_cpu_used_(GET_PARAM(2)), min_psnr_(kMaxPSNR), - tune_content_(VP9E_CONTENT_DEFAULT) {} - ~CpuSpeedTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(encoding_mode_); - if (encoding_mode_ != ::libvpx_test::kRealTime) { - cfg_.g_lag_in_frames = 25; - cfg_.rc_end_usage = VPX_VBR; - } else { - cfg_.g_lag_in_frames = 0; - cfg_.rc_end_usage = VPX_CBR; - } - } - - void BeginPassHook(unsigned int /*pass*/) override { min_psnr_ = kMaxPSNR; } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_); - encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_); - if (encoding_mode_ != ::libvpx_test::kRealTime) { - encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); - encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7); - encoder->Control(VP8E_SET_ARNR_STRENGTH, 5); - encoder->Control(VP8E_SET_ARNR_TYPE, 3); - } - } - } - - void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) override { - if (pkt->data.psnr.psnr[0] < min_psnr_) min_psnr_ = pkt->data.psnr.psnr[0]; - } - - ::libvpx_test::TestMode encoding_mode_; - int set_cpu_used_; - double min_psnr_; - int tune_content_; -}; - -TEST_P(CpuSpeedTest, TestQ0) { - // Validate that this non multiple of 64 wide clip encodes and decodes - // without a mismatch when passing in a very low max q. This pushes - // the encoder to producing lots of big partitions which will likely - // extend into the border and test the border condition. - cfg_.rc_2pass_vbr_minsection_pct = 5; - cfg_.rc_2pass_vbr_maxsection_pct = 2000; - cfg_.rc_target_bitrate = 400; - cfg_.rc_max_quantizer = 0; - cfg_.rc_min_quantizer = 0; - - ::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0, - 20); - - init_flags_ = VPX_CODEC_USE_PSNR; - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - EXPECT_GE(min_psnr_, kMaxPSNR); -} - -TEST_P(CpuSpeedTest, TestScreencastQ0) { - ::libvpx_test::Y4mVideoSource video("screendata.y4m", 0, 25); - cfg_.g_timebase = video.timebase(); - cfg_.rc_2pass_vbr_minsection_pct = 5; - cfg_.rc_2pass_vbr_maxsection_pct = 2000; - cfg_.rc_target_bitrate = 400; - cfg_.rc_max_quantizer = 0; - cfg_.rc_min_quantizer = 0; - - init_flags_ = VPX_CODEC_USE_PSNR; - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - EXPECT_GE(min_psnr_, kMaxPSNR); -} - -TEST_P(CpuSpeedTest, TestTuneScreen) { - ::libvpx_test::Y4mVideoSource video("screendata.y4m", 0, 25); - cfg_.g_timebase = video.timebase(); - cfg_.rc_2pass_vbr_minsection_pct = 5; - cfg_.rc_2pass_vbr_maxsection_pct = 2000; - cfg_.rc_target_bitrate = 2000; - cfg_.rc_max_quantizer = 63; - cfg_.rc_min_quantizer = 0; - tune_content_ = VP9E_CONTENT_SCREEN; - - init_flags_ = VPX_CODEC_USE_PSNR; - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -TEST_P(CpuSpeedTest, TestEncodeHighBitrate) { - // Validate that this non multiple of 64 wide clip encodes and decodes - // without a mismatch when passing in a very low max q. This pushes - // the encoder to producing lots of big partitions which will likely - // extend into the border and test the border condition. - cfg_.rc_2pass_vbr_minsection_pct = 5; - cfg_.rc_2pass_vbr_maxsection_pct = 2000; - cfg_.rc_target_bitrate = 12000; - cfg_.rc_max_quantizer = 10; - cfg_.rc_min_quantizer = 0; - - ::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0, - 20); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -TEST_P(CpuSpeedTest, TestLowBitrate) { - // Validate that this clip encodes and decodes without a mismatch - // when passing in a very high min q. This pushes the encoder to producing - // lots of small partitions which might will test the other condition. - cfg_.rc_2pass_vbr_minsection_pct = 5; - cfg_.rc_2pass_vbr_maxsection_pct = 2000; - cfg_.rc_target_bitrate = 200; - cfg_.rc_min_quantizer = 40; - - ::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0, - 20); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -VP9_INSTANTIATE_TEST_SUITE(CpuSpeedTest, ONE_PASS_TEST_MODES, - ::testing::Range(0, 10)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/cq_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/cq_test.cc deleted file mode 100644 index 794f3b68..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/cq_test.cc +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" -#include "vpx_config.h" - -namespace { - -// CQ level range: [kCQLevelMin, kCQLevelMax). -const int kCQLevelMin = 4; -const int kCQLevelMax = 63; -const int kCQLevelStep = 8; -const unsigned int kCQTargetBitrate = 2000; - -class CQTest : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWithParam { - public: - // maps the cqlevel to the bitrate produced. - typedef std::map BitrateMap; - - static void SetUpTestSuite() { bitrates_.clear(); } - - static void TearDownTestSuite() { - ASSERT_TRUE(!HasFailure()) - << "skipping bitrate validation due to earlier failure."; - uint32_t prev_actual_bitrate = kCQTargetBitrate; - for (BitrateMap::const_iterator iter = bitrates_.begin(); - iter != bitrates_.end(); ++iter) { - const uint32_t cq_actual_bitrate = iter->second; - EXPECT_LE(cq_actual_bitrate, prev_actual_bitrate) - << "cq_level: " << iter->first - << ", bitrate should decrease with increase in CQ level."; - prev_actual_bitrate = cq_actual_bitrate; - } - } - - protected: - CQTest() : EncoderTest(GET_PARAM(0)), cq_level_(GET_PARAM(1)) { - init_flags_ = VPX_CODEC_USE_PSNR; - } - - ~CQTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(libvpx_test::kTwoPassGood); - } - - void BeginPassHook(unsigned int /*pass*/) override { - file_size_ = 0; - psnr_ = 0.0; - n_frames_ = 0; - } - - void PreEncodeFrameHook(libvpx_test::VideoSource *video, - libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - if (cfg_.rc_end_usage == VPX_CQ) { - encoder->Control(VP8E_SET_CQ_LEVEL, cq_level_); - } - encoder->Control(VP8E_SET_CPUUSED, 3); - } - } - - void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) override { - psnr_ += pow(10.0, pkt->data.psnr.psnr[0] / 10.0); - n_frames_++; - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - file_size_ += pkt->data.frame.sz; - } - - double GetLinearPSNROverBitrate() const { - double avg_psnr = log10(psnr_ / n_frames_) * 10.0; - return pow(10.0, avg_psnr / 10.0) / file_size_; - } - - int cq_level() const { return cq_level_; } - size_t file_size() const { return file_size_; } - int n_frames() const { return n_frames_; } - - static BitrateMap bitrates_; - - private: - int cq_level_; - size_t file_size_; - double psnr_; - int n_frames_; -}; - -CQTest::BitrateMap CQTest::bitrates_; - -TEST_P(CQTest, LinearPSNRIsHigherForCQLevel) { - const vpx_rational timebase = { 33333333, 1000000000 }; -#if CONFIG_REALTIME_ONlY - GTEST_SKIP() - << "Non-zero g_lag_in_frames is unsupported with CONFIG_REALTIME_ONLY"; -#else - cfg_.g_timebase = timebase; - cfg_.rc_target_bitrate = kCQTargetBitrate; - cfg_.g_lag_in_frames = 25; - - cfg_.rc_end_usage = VPX_CQ; - libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - timebase.den, timebase.num, 0, 30); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - const double cq_psnr_lin = GetLinearPSNROverBitrate(); - const unsigned int cq_actual_bitrate = - static_cast(file_size()) * 8 * 30 / (n_frames() * 1000); - EXPECT_LE(cq_actual_bitrate, kCQTargetBitrate); - bitrates_[cq_level()] = cq_actual_bitrate; - - // try targeting the approximate same bitrate with VBR mode - cfg_.rc_end_usage = VPX_VBR; - cfg_.rc_target_bitrate = cq_actual_bitrate; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - const double vbr_psnr_lin = GetLinearPSNROverBitrate(); - EXPECT_GE(cq_psnr_lin, vbr_psnr_lin); -#endif // CONFIG_REALTIME_ONLY -} - -VP8_INSTANTIATE_TEST_SUITE(CQTest, ::testing::Range(kCQLevelMin, kCQLevelMax, - kCQLevelStep)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/cx_set_ref.sh b/presentation/src/main/cpp/third_party/libvpx/test/cx_set_ref.sh deleted file mode 100644 index 0a3d50ce..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/cx_set_ref.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2016 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## This file tests the libvpx cx_set_ref example. To add new tests to this -## file, do the following: -## 1. Write a shell function (this is your test). -## 2. Add the function to cx_set_ref_tests (on a new line). -## -. $(dirname $0)/tools_common.sh - -# Environment check: $YUV_RAW_INPUT is required. -cx_set_ref_verify_environment() { - if [ ! -e "${YUV_RAW_INPUT}" ]; then - echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH." - return 1 - fi -} - -# Runs cx_set_ref and updates the reference frame before encoding frame 90. -# $1 is the codec name. -vpx_set_ref() { - local codec="$1" - local encoder="${LIBVPX_BIN_PATH}/${codec}cx_set_ref${VPX_TEST_EXE_SUFFIX}" - local output_file="${VPX_TEST_OUTPUT_DIR}/${codec}cx_set_ref_${codec}.ivf" - local ref_frame_num=90 - - if [ ! -x "${encoder}" ]; then - elog "${encoder} does not exist or is not executable." - return 1 - fi - - eval "${VPX_TEST_PREFIX}" "${encoder}" "${YUV_RAW_INPUT_WIDTH}" \ - "${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" \ - "${ref_frame_num}" ${devnull} || return 1 - - [ -e "${output_file}" ] || return 1 -} - -cx_set_ref_vp8() { - if [ "$(vp8_encode_available)" = "yes" ]; then - vpx_set_ref vp8 || return 1 - fi -} - -cx_set_ref_vp9() { - if [ "$(vp9_encode_available)" = "yes" ]; then - vpx_set_ref vp9 || return 1 - fi -} - -cx_set_ref_tests="cx_set_ref_vp8 cx_set_ref_vp9" - -run_tests cx_set_ref_verify_environment "${cx_set_ref_tests}" diff --git a/presentation/src/main/cpp/third_party/libvpx/test/dct16x16_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/dct16x16_test.cc deleted file mode 100644 index cf0cc776..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/dct16x16_test.cc +++ /dev/null @@ -1,1029 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vp9_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "test/acm_random.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vp9/common/vp9_entropy.h" -#include "vp9/common/vp9_scan.h" -#include "vpx/vpx_codec.h" -#include "vpx/vpx_integer.h" -#include "vpx_config.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/vpx_timer.h" - -using libvpx_test::ACMRandom; - -namespace { - -const int kNumCoeffs = 256; -const double C1 = 0.995184726672197; -const double C2 = 0.98078528040323; -const double C3 = 0.956940335732209; -const double C4 = 0.923879532511287; -const double C5 = 0.881921264348355; -const double C6 = 0.831469612302545; -const double C7 = 0.773010453362737; -const double C8 = 0.707106781186548; -const double C9 = 0.634393284163646; -const double C10 = 0.555570233019602; -const double C11 = 0.471396736825998; -const double C12 = 0.38268343236509; -const double C13 = 0.290284677254462; -const double C14 = 0.195090322016128; -const double C15 = 0.098017140329561; - -void butterfly_16x16_dct_1d(double input[16], double output[16]) { - double step[16]; - double intermediate[16]; - double temp1, temp2; - - // step 1 - step[0] = input[0] + input[15]; - step[1] = input[1] + input[14]; - step[2] = input[2] + input[13]; - step[3] = input[3] + input[12]; - step[4] = input[4] + input[11]; - step[5] = input[5] + input[10]; - step[6] = input[6] + input[9]; - step[7] = input[7] + input[8]; - step[8] = input[7] - input[8]; - step[9] = input[6] - input[9]; - step[10] = input[5] - input[10]; - step[11] = input[4] - input[11]; - step[12] = input[3] - input[12]; - step[13] = input[2] - input[13]; - step[14] = input[1] - input[14]; - step[15] = input[0] - input[15]; - - // step 2 - output[0] = step[0] + step[7]; - output[1] = step[1] + step[6]; - output[2] = step[2] + step[5]; - output[3] = step[3] + step[4]; - output[4] = step[3] - step[4]; - output[5] = step[2] - step[5]; - output[6] = step[1] - step[6]; - output[7] = step[0] - step[7]; - - temp1 = step[8] * C7; - temp2 = step[15] * C9; - output[8] = temp1 + temp2; - - temp1 = step[9] * C11; - temp2 = step[14] * C5; - output[9] = temp1 - temp2; - - temp1 = step[10] * C3; - temp2 = step[13] * C13; - output[10] = temp1 + temp2; - - temp1 = step[11] * C15; - temp2 = step[12] * C1; - output[11] = temp1 - temp2; - - temp1 = step[11] * C1; - temp2 = step[12] * C15; - output[12] = temp2 + temp1; - - temp1 = step[10] * C13; - temp2 = step[13] * C3; - output[13] = temp2 - temp1; - - temp1 = step[9] * C5; - temp2 = step[14] * C11; - output[14] = temp2 + temp1; - - temp1 = step[8] * C9; - temp2 = step[15] * C7; - output[15] = temp2 - temp1; - - // step 3 - step[0] = output[0] + output[3]; - step[1] = output[1] + output[2]; - step[2] = output[1] - output[2]; - step[3] = output[0] - output[3]; - - temp1 = output[4] * C14; - temp2 = output[7] * C2; - step[4] = temp1 + temp2; - - temp1 = output[5] * C10; - temp2 = output[6] * C6; - step[5] = temp1 + temp2; - - temp1 = output[5] * C6; - temp2 = output[6] * C10; - step[6] = temp2 - temp1; - - temp1 = output[4] * C2; - temp2 = output[7] * C14; - step[7] = temp2 - temp1; - - step[8] = output[8] + output[11]; - step[9] = output[9] + output[10]; - step[10] = output[9] - output[10]; - step[11] = output[8] - output[11]; - - step[12] = output[12] + output[15]; - step[13] = output[13] + output[14]; - step[14] = output[13] - output[14]; - step[15] = output[12] - output[15]; - - // step 4 - output[0] = (step[0] + step[1]); - output[8] = (step[0] - step[1]); - - temp1 = step[2] * C12; - temp2 = step[3] * C4; - temp1 = temp1 + temp2; - output[4] = 2 * (temp1 * C8); - - temp1 = step[2] * C4; - temp2 = step[3] * C12; - temp1 = temp2 - temp1; - output[12] = 2 * (temp1 * C8); - - output[2] = 2 * ((step[4] + step[5]) * C8); - output[14] = 2 * ((step[7] - step[6]) * C8); - - temp1 = step[4] - step[5]; - temp2 = step[6] + step[7]; - output[6] = (temp1 + temp2); - output[10] = (temp1 - temp2); - - intermediate[8] = step[8] + step[14]; - intermediate[9] = step[9] + step[15]; - - temp1 = intermediate[8] * C12; - temp2 = intermediate[9] * C4; - temp1 = temp1 - temp2; - output[3] = 2 * (temp1 * C8); - - temp1 = intermediate[8] * C4; - temp2 = intermediate[9] * C12; - temp1 = temp2 + temp1; - output[13] = 2 * (temp1 * C8); - - output[9] = 2 * ((step[10] + step[11]) * C8); - - intermediate[11] = step[10] - step[11]; - intermediate[12] = step[12] + step[13]; - intermediate[13] = step[12] - step[13]; - intermediate[14] = step[8] - step[14]; - intermediate[15] = step[9] - step[15]; - - output[15] = (intermediate[11] + intermediate[12]); - output[1] = -(intermediate[11] - intermediate[12]); - - output[7] = 2 * (intermediate[13] * C8); - - temp1 = intermediate[14] * C12; - temp2 = intermediate[15] * C4; - temp1 = temp1 - temp2; - output[11] = -2 * (temp1 * C8); - - temp1 = intermediate[14] * C4; - temp2 = intermediate[15] * C12; - temp1 = temp2 + temp1; - output[5] = 2 * (temp1 * C8); -} - -void reference_16x16_dct_2d(int16_t input[256], double output[256]) { - // First transform columns - for (int i = 0; i < 16; ++i) { - double temp_in[16], temp_out[16]; - for (int j = 0; j < 16; ++j) temp_in[j] = input[j * 16 + i]; - butterfly_16x16_dct_1d(temp_in, temp_out); - for (int j = 0; j < 16; ++j) output[j * 16 + i] = temp_out[j]; - } - // Then transform rows - for (int i = 0; i < 16; ++i) { - double temp_in[16], temp_out[16]; - for (int j = 0; j < 16; ++j) temp_in[j] = output[j + i * 16]; - butterfly_16x16_dct_1d(temp_in, temp_out); - // Scale by some magic number - for (int j = 0; j < 16; ++j) output[j + i * 16] = temp_out[j] / 2; - } -} - -typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride); -typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride); -typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride, - int tx_type); -typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride, - int tx_type); - -typedef std::tuple Dct16x16Param; -typedef std::tuple Ht16x16Param; -typedef std::tuple Idct16x16Param; - -void fdct16x16_ref(const int16_t *in, tran_low_t *out, int stride, - int /*tx_type*/) { - vpx_fdct16x16_c(in, out, stride); -} - -void idct16x16_ref(const tran_low_t *in, uint8_t *dest, int stride, - int /*tx_type*/) { - vpx_idct16x16_256_add_c(in, dest, stride); -} - -void fht16x16_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) { - vp9_fht16x16_c(in, out, stride, tx_type); -} - -void iht16x16_ref(const tran_low_t *in, uint8_t *dest, int stride, - int tx_type) { - vp9_iht16x16_256_add_c(in, dest, stride, tx_type); -} - -#if CONFIG_VP9_HIGHBITDEPTH -void idct16x16_10(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, 10); -} - -void idct16x16_12(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, 12); -} - -void idct16x16_10_ref(const tran_low_t *in, uint8_t *out, int stride, - int /*tx_type*/) { - idct16x16_10(in, out, stride); -} - -void idct16x16_12_ref(const tran_low_t *in, uint8_t *out, int stride, - int /*tx_type*/) { - idct16x16_12(in, out, stride); -} - -void iht16x16_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) { - vp9_highbd_iht16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 10); -} - -void iht16x16_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) { - vp9_highbd_iht16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 12); -} - -#if HAVE_SSE2 -void idct16x16_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct16x16_10_add_c(in, CAST_TO_SHORTPTR(out), stride, 10); -} - -void idct16x16_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct16x16_10_add_c(in, CAST_TO_SHORTPTR(out), stride, 12); -} - -void idct16x16_256_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct16x16_256_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10); -} - -void idct16x16_256_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct16x16_256_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12); -} - -void idct16x16_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct16x16_10_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10); -} - -void idct16x16_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct16x16_10_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12); -} -#endif // HAVE_SSE2 -#endif // CONFIG_VP9_HIGHBITDEPTH - -class Trans16x16TestBase { - public: - virtual ~Trans16x16TestBase() = default; - - protected: - virtual void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) = 0; - - virtual void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) = 0; - - void RunAccuracyCheck() { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - uint32_t max_error = 0; - int64_t total_error = 0; - const int count_test_block = 10000; - for (int i = 0; i < count_test_block; ++i) { - DECLARE_ALIGNED(16, int16_t, test_input_block[kNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]); -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); - DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]); -#endif - - // Initialize a test block with input range [-mask_, mask_]. - for (int j = 0; j < kNumCoeffs; ++j) { - if (bit_depth_ == VPX_BITS_8) { - src[j] = rnd.Rand8(); - dst[j] = rnd.Rand8(); - test_input_block[j] = src[j] - dst[j]; -#if CONFIG_VP9_HIGHBITDEPTH - } else { - src16[j] = rnd.Rand16() & mask_; - dst16[j] = rnd.Rand16() & mask_; - test_input_block[j] = src16[j] - dst16[j]; -#endif - } - } - - ASM_REGISTER_STATE_CHECK( - RunFwdTxfm(test_input_block, test_temp_block, pitch_)); - if (bit_depth_ == VPX_BITS_8) { - ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_)); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - ASM_REGISTER_STATE_CHECK( - RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_)); -#endif - } - - for (int j = 0; j < kNumCoeffs; ++j) { -#if CONFIG_VP9_HIGHBITDEPTH - const int32_t diff = - bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j]; -#else - const int32_t diff = dst[j] - src[j]; -#endif - const uint32_t error = diff * diff; - if (max_error < error) max_error = error; - total_error += error; - } - } - - EXPECT_GE(1u << 2 * (bit_depth_ - 8), max_error) - << "Error: 16x16 FHT/IHT has an individual round trip error > 1"; - - EXPECT_GE(count_test_block << 2 * (bit_depth_ - 8), total_error) - << "Error: 16x16 FHT/IHT has average round trip error > 1 per block"; - } - - void RunCoeffCheck() { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 1000; - DECLARE_ALIGNED(16, int16_t, input_block[kNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]); - - for (int i = 0; i < count_test_block; ++i) { - // Initialize a test block with input range [-mask_, mask_]. - for (int j = 0; j < kNumCoeffs; ++j) { - input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_); - } - - fwd_txfm_ref(input_block, output_ref_block, pitch_, tx_type_); - ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_)); - - // The minimum quant value is 4. - for (int j = 0; j < kNumCoeffs; ++j) - EXPECT_EQ(output_block[j], output_ref_block[j]); - } - } - - void RunMemCheck() { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 1000; - DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]); - - for (int i = 0; i < count_test_block; ++i) { - // Initialize a test block with input range [-mask_, mask_]. - for (int j = 0; j < kNumCoeffs; ++j) { - input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_; - } - if (i == 0) { - for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_; - } else if (i == 1) { - for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_; - } - - fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_); - ASM_REGISTER_STATE_CHECK( - RunFwdTxfm(input_extreme_block, output_block, pitch_)); - - // The minimum quant value is 4. - for (int j = 0; j < kNumCoeffs; ++j) { - EXPECT_EQ(output_block[j], output_ref_block[j]); - EXPECT_GE(4 * DCT_MAX_VALUE << (bit_depth_ - 8), abs(output_block[j])) - << "Error: 16x16 FDCT has coefficient larger than 4*DCT_MAX_VALUE"; - } - } - } - - void RunQuantCheck(int dc_thred, int ac_thred) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 100000; - DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]); - - DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]); -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); - DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]); -#endif - - for (int i = 0; i < count_test_block; ++i) { - // Initialize a test block with input range [-mask_, mask_]. - for (int j = 0; j < kNumCoeffs; ++j) { - input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_; - } - if (i == 0) { - for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_; - } - if (i == 1) { - for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_; - } - - fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_); - - // clear reconstructed pixel buffers - memset(dst, 0, kNumCoeffs * sizeof(uint8_t)); - memset(ref, 0, kNumCoeffs * sizeof(uint8_t)); -#if CONFIG_VP9_HIGHBITDEPTH - memset(dst16, 0, kNumCoeffs * sizeof(uint16_t)); - memset(ref16, 0, kNumCoeffs * sizeof(uint16_t)); -#endif - - // quantization with maximum allowed step sizes - output_ref_block[0] = (output_ref_block[0] / dc_thred) * dc_thred; - for (int j = 1; j < kNumCoeffs; ++j) { - output_ref_block[j] = (output_ref_block[j] / ac_thred) * ac_thred; - } - if (bit_depth_ == VPX_BITS_8) { - inv_txfm_ref(output_ref_block, ref, pitch_, tx_type_); - ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_)); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - inv_txfm_ref(output_ref_block, CAST_TO_BYTEPTR(ref16), pitch_, - tx_type_); - ASM_REGISTER_STATE_CHECK( - RunInvTxfm(output_ref_block, CAST_TO_BYTEPTR(dst16), pitch_)); -#endif - } - if (bit_depth_ == VPX_BITS_8) { - for (int j = 0; j < kNumCoeffs; ++j) EXPECT_EQ(ref[j], dst[j]); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - for (int j = 0; j < kNumCoeffs; ++j) EXPECT_EQ(ref16[j], dst16[j]); -#endif - } - } - } - - void RunInvAccuracyCheck() { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 1000; - DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]); -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); - DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]); -#endif // CONFIG_VP9_HIGHBITDEPTH - - for (int i = 0; i < count_test_block; ++i) { - double out_r[kNumCoeffs]; - - // Initialize a test block with input range [-255, 255]. - for (int j = 0; j < kNumCoeffs; ++j) { - if (bit_depth_ == VPX_BITS_8) { - src[j] = rnd.Rand8(); - dst[j] = rnd.Rand8(); - in[j] = src[j] - dst[j]; -#if CONFIG_VP9_HIGHBITDEPTH - } else { - src16[j] = rnd.Rand16() & mask_; - dst16[j] = rnd.Rand16() & mask_; - in[j] = src16[j] - dst16[j]; -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - - reference_16x16_dct_2d(in, out_r); - for (int j = 0; j < kNumCoeffs; ++j) { - coeff[j] = static_cast(round(out_r[j])); - } - - if (bit_depth_ == VPX_BITS_8) { - ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16)); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), 16)); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - - for (int j = 0; j < kNumCoeffs; ++j) { -#if CONFIG_VP9_HIGHBITDEPTH - const uint32_t diff = - bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j]; -#else - const uint32_t diff = dst[j] - src[j]; -#endif // CONFIG_VP9_HIGHBITDEPTH - const uint32_t error = diff * diff; - EXPECT_GE(1u, error) - << "Error: 16x16 IDCT has error " << error << " at index " << j; - } - } - } - - void RunSpeedTest() { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 10000; - int c_sum_time = 0; - int simd_sum_time = 0; - - DECLARE_ALIGNED(32, int16_t, input_block[kNumCoeffs]); - DECLARE_ALIGNED(32, tran_low_t, output_ref_block[kNumCoeffs]); - DECLARE_ALIGNED(32, tran_low_t, output_block[kNumCoeffs]); - - // Initialize a test block with input range [-mask_, mask_]. - for (int j = 0; j < kNumCoeffs; ++j) { - input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_); - } - - vpx_usec_timer timer_c; - vpx_usec_timer_start(&timer_c); - for (int i = 0; i < count_test_block; ++i) { - vpx_fdct16x16_c(input_block, output_ref_block, pitch_); - } - vpx_usec_timer_mark(&timer_c); - c_sum_time += static_cast(vpx_usec_timer_elapsed(&timer_c)); - - vpx_usec_timer timer_mod; - vpx_usec_timer_start(&timer_mod); - for (int i = 0; i < count_test_block; ++i) { - RunFwdTxfm(input_block, output_block, pitch_); - } - - vpx_usec_timer_mark(&timer_mod); - simd_sum_time += static_cast(vpx_usec_timer_elapsed(&timer_mod)); - - printf( - "c_time = %d \t simd_time = %d \t Gain = %4.2f \n", c_sum_time, - simd_sum_time, - (static_cast(c_sum_time) / static_cast(simd_sum_time))); - } - - void CompareInvReference(IdctFunc ref_txfm, int thresh) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 10000; - const int eob = 10; - const int16_t *scan = vp9_default_scan_orders[TX_16X16].scan; - DECLARE_ALIGNED(32, tran_low_t, coeff[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]); -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); - DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]); -#endif // CONFIG_VP9_HIGHBITDEPTH - - for (int i = 0; i < count_test_block; ++i) { - for (int j = 0; j < kNumCoeffs; ++j) { - if (j < eob) { - // Random values less than the threshold, either positive or negative - coeff[scan[j]] = rnd(thresh) * (1 - 2 * (i % 2)); - } else { - coeff[scan[j]] = 0; - } - if (bit_depth_ == VPX_BITS_8) { - dst[j] = 0; - ref[j] = 0; -#if CONFIG_VP9_HIGHBITDEPTH - } else { - dst16[j] = 0; - ref16[j] = 0; -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - if (bit_depth_ == VPX_BITS_8) { - ref_txfm(coeff, ref, pitch_); - ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_)); - } else { -#if CONFIG_VP9_HIGHBITDEPTH - ref_txfm(coeff, CAST_TO_BYTEPTR(ref16), pitch_); - ASM_REGISTER_STATE_CHECK( - RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_)); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - - for (int j = 0; j < kNumCoeffs; ++j) { -#if CONFIG_VP9_HIGHBITDEPTH - const uint32_t diff = - bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j]; -#else - const uint32_t diff = dst[j] - ref[j]; -#endif // CONFIG_VP9_HIGHBITDEPTH - const uint32_t error = diff * diff; - EXPECT_EQ(0u, error) << "Error: 16x16 IDCT Comparison has error " - << error << " at index " << j; - } - } - } - - void RunInvTrans16x16SpeedTest(IdctFunc ref_txfm, int thresh) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 10000; - const int eob = 10; - const int16_t *scan = vp9_default_scan_orders[TX_16X16].scan; - int64_t c_sum_time = 0; - int64_t simd_sum_time = 0; - DECLARE_ALIGNED(32, tran_low_t, coeff[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]); -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); - DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]); -#endif // CONFIG_VP9_HIGHBITDEPTH - - for (int j = 0; j < kNumCoeffs; ++j) { - if (j < eob) { - // Random values less than the threshold, either positive or negative - coeff[scan[j]] = rnd(thresh); - } else { - coeff[scan[j]] = 0; - } - if (bit_depth_ == VPX_BITS_8) { - dst[j] = 0; - ref[j] = 0; -#if CONFIG_VP9_HIGHBITDEPTH - } else { - dst16[j] = 0; - ref16[j] = 0; -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - - if (bit_depth_ == VPX_BITS_8) { - vpx_usec_timer timer_c; - vpx_usec_timer_start(&timer_c); - for (int i = 0; i < count_test_block; ++i) { - ref_txfm(coeff, ref, pitch_); - } - vpx_usec_timer_mark(&timer_c); - c_sum_time += vpx_usec_timer_elapsed(&timer_c); - - vpx_usec_timer timer_mod; - vpx_usec_timer_start(&timer_mod); - for (int i = 0; i < count_test_block; ++i) { - RunInvTxfm(coeff, dst, pitch_); - } - vpx_usec_timer_mark(&timer_mod); - simd_sum_time += vpx_usec_timer_elapsed(&timer_mod); - } else { -#if CONFIG_VP9_HIGHBITDEPTH - vpx_usec_timer timer_c; - vpx_usec_timer_start(&timer_c); - for (int i = 0; i < count_test_block; ++i) { - ref_txfm(coeff, CAST_TO_BYTEPTR(ref16), pitch_); - } - vpx_usec_timer_mark(&timer_c); - c_sum_time += vpx_usec_timer_elapsed(&timer_c); - - vpx_usec_timer timer_mod; - vpx_usec_timer_start(&timer_mod); - for (int i = 0; i < count_test_block; ++i) { - RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_); - } - vpx_usec_timer_mark(&timer_mod); - simd_sum_time += vpx_usec_timer_elapsed(&timer_mod); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - printf( - "c_time = %" PRId64 " \t simd_time = %" PRId64 " \t Gain = %4.2f \n", - c_sum_time, simd_sum_time, - (static_cast(c_sum_time) / static_cast(simd_sum_time))); - } - - int pitch_; - int tx_type_; - vpx_bit_depth_t bit_depth_; - int mask_; - FhtFunc fwd_txfm_ref; - IhtFunc inv_txfm_ref; -}; - -class Trans16x16DCT : public Trans16x16TestBase, - public ::testing::TestWithParam { - public: - ~Trans16x16DCT() override = default; - - void SetUp() override { - fwd_txfm_ = GET_PARAM(0); - inv_txfm_ = GET_PARAM(1); - tx_type_ = GET_PARAM(2); - bit_depth_ = GET_PARAM(3); - pitch_ = 16; - fwd_txfm_ref = fdct16x16_ref; - inv_txfm_ref = idct16x16_ref; - mask_ = (1 << bit_depth_) - 1; -#if CONFIG_VP9_HIGHBITDEPTH - switch (bit_depth_) { - case VPX_BITS_10: inv_txfm_ref = idct16x16_10_ref; break; - case VPX_BITS_12: inv_txfm_ref = idct16x16_12_ref; break; - default: inv_txfm_ref = idct16x16_ref; break; - } -#else - inv_txfm_ref = idct16x16_ref; -#endif - } - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) override { - fwd_txfm_(in, out, stride); - } - void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) override { - inv_txfm_(out, dst, stride); - } - - FdctFunc fwd_txfm_; - IdctFunc inv_txfm_; -}; - -TEST_P(Trans16x16DCT, AccuracyCheck) { RunAccuracyCheck(); } - -TEST_P(Trans16x16DCT, CoeffCheck) { RunCoeffCheck(); } - -TEST_P(Trans16x16DCT, MemCheck) { RunMemCheck(); } - -TEST_P(Trans16x16DCT, QuantCheck) { - // Use maximally allowed quantization step sizes for DC and AC - // coefficients respectively. - RunQuantCheck(1336, 1828); -} - -TEST_P(Trans16x16DCT, InvAccuracyCheck) { RunInvAccuracyCheck(); } - -TEST_P(Trans16x16DCT, DISABLED_Speed) { RunSpeedTest(); } - -class Trans16x16HT : public Trans16x16TestBase, - public ::testing::TestWithParam { - public: - ~Trans16x16HT() override = default; - - void SetUp() override { - fwd_txfm_ = GET_PARAM(0); - inv_txfm_ = GET_PARAM(1); - tx_type_ = GET_PARAM(2); - bit_depth_ = GET_PARAM(3); - pitch_ = 16; - fwd_txfm_ref = fht16x16_ref; - inv_txfm_ref = iht16x16_ref; - mask_ = (1 << bit_depth_) - 1; -#if CONFIG_VP9_HIGHBITDEPTH - switch (bit_depth_) { - case VPX_BITS_10: inv_txfm_ref = iht16x16_10; break; - case VPX_BITS_12: inv_txfm_ref = iht16x16_12; break; - default: inv_txfm_ref = iht16x16_ref; break; - } -#else - inv_txfm_ref = iht16x16_ref; -#endif - } - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) override { - fwd_txfm_(in, out, stride, tx_type_); - } - void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) override { - inv_txfm_(out, dst, stride, tx_type_); - } - - FhtFunc fwd_txfm_; - IhtFunc inv_txfm_; -}; - -TEST_P(Trans16x16HT, AccuracyCheck) { RunAccuracyCheck(); } - -TEST_P(Trans16x16HT, CoeffCheck) { RunCoeffCheck(); } - -TEST_P(Trans16x16HT, MemCheck) { RunMemCheck(); } - -TEST_P(Trans16x16HT, QuantCheck) { - // The encoder skips any non-DC intra prediction modes, - // when the quantization step size goes beyond 988. - RunQuantCheck(429, 729); -} - -class InvTrans16x16DCT : public Trans16x16TestBase, - public ::testing::TestWithParam { - public: - ~InvTrans16x16DCT() override = default; - - void SetUp() override { - ref_txfm_ = GET_PARAM(0); - inv_txfm_ = GET_PARAM(1); - thresh_ = GET_PARAM(2); - bit_depth_ = GET_PARAM(3); - pitch_ = 16; - mask_ = (1 << bit_depth_) - 1; - } - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - void RunFwdTxfm(int16_t * /*in*/, tran_low_t * /*out*/, - int /*stride*/) override {} - void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) override { - inv_txfm_(out, dst, stride); - } - - IdctFunc ref_txfm_; - IdctFunc inv_txfm_; - int thresh_; -}; -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InvTrans16x16DCT); - -TEST_P(InvTrans16x16DCT, CompareReference) { - CompareInvReference(ref_txfm_, thresh_); -} - -TEST_P(InvTrans16x16DCT, DISABLED_Speed) { - RunInvTrans16x16SpeedTest(ref_txfm_, thresh_); -} - -using std::make_tuple; - -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - C, Trans16x16DCT, - ::testing::Values( - make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_10, 0, VPX_BITS_10), - make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_12, 0, VPX_BITS_12), - make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 0, VPX_BITS_8))); -#else -INSTANTIATE_TEST_SUITE_P(C, Trans16x16DCT, - ::testing::Values(make_tuple(&vpx_fdct16x16_c, - &vpx_idct16x16_256_add_c, - 0, VPX_BITS_8))); -#endif // CONFIG_VP9_HIGHBITDEPTH - -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - C, Trans16x16HT, - ::testing::Values( - make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 0, VPX_BITS_10), - make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 1, VPX_BITS_10), - make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 2, VPX_BITS_10), - make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 3, VPX_BITS_10), - make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 0, VPX_BITS_12), - make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 1, VPX_BITS_12), - make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 2, VPX_BITS_12), - make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 3, VPX_BITS_12), - make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 0, VPX_BITS_8), - make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8), - make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8), - make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8))); -#else -INSTANTIATE_TEST_SUITE_P( - C, Trans16x16HT, - ::testing::Values( - make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 0, VPX_BITS_8), - make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8), - make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8), - make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8))); - -INSTANTIATE_TEST_SUITE_P(C, InvTrans16x16DCT, - ::testing::Values(make_tuple(&vpx_idct16x16_256_add_c, - &vpx_idct16x16_256_add_c, - 6225, VPX_BITS_8))); - -#endif // CONFIG_VP9_HIGHBITDEPTH - -#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P( - NEON, Trans16x16DCT, - ::testing::Values(make_tuple(&vpx_fdct16x16_neon, - &vpx_idct16x16_256_add_neon, 0, VPX_BITS_8))); -#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE - -#if HAVE_NEON && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P( - NEON, Trans16x16DCT, - ::testing::Values( - make_tuple(&vpx_highbd_fdct16x16_neon, &idct16x16_10, 0, VPX_BITS_10), - make_tuple(&vpx_highbd_fdct16x16_neon, &idct16x16_12, 0, VPX_BITS_12), - make_tuple(&vpx_fdct16x16_neon, &vpx_idct16x16_256_add_c, 0, - VPX_BITS_8))); -#endif // HAVE_NEON && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE - -#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P( - SSE2, Trans16x16DCT, - ::testing::Values(make_tuple(&vpx_fdct16x16_sse2, - &vpx_idct16x16_256_add_sse2, 0, VPX_BITS_8))); -INSTANTIATE_TEST_SUITE_P( - SSE2, Trans16x16HT, - ::testing::Values(make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, - 0, VPX_BITS_8), - make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, - 1, VPX_BITS_8), - make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, - 2, VPX_BITS_8), - make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, - 3, VPX_BITS_8))); - -INSTANTIATE_TEST_SUITE_P(SSE2, InvTrans16x16DCT, - ::testing::Values(make_tuple( - &vpx_idct16x16_256_add_c, - &vpx_idct16x16_256_add_sse2, 6225, VPX_BITS_8))); -#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE - -#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P( - AVX2, Trans16x16DCT, - ::testing::Values(make_tuple(&vpx_fdct16x16_avx2, - &vpx_idct16x16_256_add_sse2, 0, VPX_BITS_8))); - -INSTANTIATE_TEST_SUITE_P(AVX2, InvTrans16x16DCT, - ::testing::Values(make_tuple( - &vpx_idct16x16_256_add_c, - &vpx_idct16x16_256_add_avx2, 6225, VPX_BITS_8))); -#endif // HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE - -#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P( - SSE2, Trans16x16DCT, - ::testing::Values( - make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_10, 0, VPX_BITS_10), - make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_256_add_10_sse2, 0, - VPX_BITS_10), - make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_12, 0, VPX_BITS_12), - make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_256_add_12_sse2, 0, - VPX_BITS_12), - make_tuple(&vpx_fdct16x16_sse2, &vpx_idct16x16_256_add_c, 0, - VPX_BITS_8))); -INSTANTIATE_TEST_SUITE_P( - SSE2, Trans16x16HT, - ::testing::Values( - make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 0, VPX_BITS_8), - make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8), - make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8), - make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 3, - VPX_BITS_8))); -// Optimizations take effect at a threshold of 3155, so we use a value close to -// that to test both branches. -INSTANTIATE_TEST_SUITE_P( - SSE2, InvTrans16x16DCT, - ::testing::Values(make_tuple(&idct16x16_10_add_10_c, - &idct16x16_10_add_10_sse2, 3167, VPX_BITS_10), - make_tuple(&idct16x16_10, &idct16x16_256_add_10_sse2, - 3167, VPX_BITS_10), - make_tuple(&idct16x16_10_add_12_c, - &idct16x16_10_add_12_sse2, 3167, VPX_BITS_12), - make_tuple(&idct16x16_12, &idct16x16_256_add_12_sse2, - 3167, VPX_BITS_12))); -#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE - -#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P( - MSA, Trans16x16DCT, - ::testing::Values(make_tuple(&vpx_fdct16x16_msa, &vpx_idct16x16_256_add_msa, - 0, VPX_BITS_8))); -INSTANTIATE_TEST_SUITE_P( - MSA, Trans16x16HT, - ::testing::Values( - make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 0, VPX_BITS_8), - make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 1, VPX_BITS_8), - make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 2, VPX_BITS_8), - make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 3, - VPX_BITS_8))); -#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE - -#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P( - VSX, Trans16x16DCT, - ::testing::Values(make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_vsx, - 0, VPX_BITS_8))); -#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE - -#if HAVE_LSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P(LSX, Trans16x16DCT, - ::testing::Values(make_tuple(&vpx_fdct16x16_lsx, - &vpx_idct16x16_256_add_c, - 0, VPX_BITS_8))); -#endif // HAVE_LSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/dct32x32_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/dct32x32_test.cc deleted file mode 100644 index abb2eafe..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/dct32x32_test.cc +++ /dev/null @@ -1,604 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "test/acm_random.h" -#include "test/bench.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vp9/common/vp9_entropy.h" -#include "vp9/common/vp9_scan.h" -#include "vpx/vpx_codec.h" -#include "vpx/vpx_integer.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/vpx_timer.h" - -using libvpx_test::ACMRandom; - -namespace { - -const int kNumCoeffs = 1024; -const double kPi = 3.141592653589793238462643383279502884; -void reference_32x32_dct_1d(const double in[32], double out[32]) { - const double kInvSqrt2 = 0.707106781186547524400844362104; - for (int k = 0; k < 32; k++) { - out[k] = 0.0; - for (int n = 0; n < 32; n++) { - out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 64.0); - } - if (k == 0) out[k] = out[k] * kInvSqrt2; - } -} - -void reference_32x32_dct_2d(const int16_t input[kNumCoeffs], - double output[kNumCoeffs]) { - // First transform columns - for (int i = 0; i < 32; ++i) { - double temp_in[32], temp_out[32]; - for (int j = 0; j < 32; ++j) temp_in[j] = input[j * 32 + i]; - reference_32x32_dct_1d(temp_in, temp_out); - for (int j = 0; j < 32; ++j) output[j * 32 + i] = temp_out[j]; - } - // Then transform rows - for (int i = 0; i < 32; ++i) { - double temp_in[32], temp_out[32]; - for (int j = 0; j < 32; ++j) temp_in[j] = output[j + i * 32]; - reference_32x32_dct_1d(temp_in, temp_out); - // Scale by some magic number - for (int j = 0; j < 32; ++j) output[j + i * 32] = temp_out[j] / 4; - } -} - -typedef void (*FwdTxfmFunc)(const int16_t *in, tran_low_t *out, int stride); -typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride); - -typedef std::tuple - Trans32x32Param; - -typedef std::tuple - InvTrans32x32Param; - -#if CONFIG_VP9_HIGHBITDEPTH -void idct32x32_10(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct32x32_1024_add_c(in, CAST_TO_SHORTPTR(out), stride, 10); -} - -void idct32x32_12(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct32x32_1024_add_c(in, CAST_TO_SHORTPTR(out), stride, 12); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -class Trans32x32Test : public AbstractBench, - public ::testing::TestWithParam { - public: - ~Trans32x32Test() override = default; - void SetUp() override { - fwd_txfm_ = GET_PARAM(0); - inv_txfm_ = GET_PARAM(1); - version_ = GET_PARAM(2); // 0: high precision forward transform - // 1: low precision version for rd loop - bit_depth_ = GET_PARAM(3); - mask_ = (1 << bit_depth_) - 1; - } - - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - int version_; - vpx_bit_depth_t bit_depth_; - int mask_; - FwdTxfmFunc fwd_txfm_; - InvTxfmFunc inv_txfm_; - - int16_t *bench_in_; - tran_low_t *bench_out_; - void Run() override; -}; - -void Trans32x32Test::Run() { fwd_txfm_(bench_in_, bench_out_, 32); } - -TEST_P(Trans32x32Test, AccuracyCheck) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - uint32_t max_error = 0; - int64_t total_error = 0; - const int count_test_block = 10000; - DECLARE_ALIGNED(16, int16_t, test_input_block[kNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]); -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); - DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]); -#endif - - for (int i = 0; i < count_test_block; ++i) { - // Initialize a test block with input range [-mask_, mask_]. - for (int j = 0; j < kNumCoeffs; ++j) { - if (bit_depth_ == VPX_BITS_8) { - src[j] = rnd.Rand8(); - dst[j] = rnd.Rand8(); - test_input_block[j] = src[j] - dst[j]; -#if CONFIG_VP9_HIGHBITDEPTH - } else { - src16[j] = rnd.Rand16() & mask_; - dst16[j] = rnd.Rand16() & mask_; - test_input_block[j] = src16[j] - dst16[j]; -#endif - } - } - - ASM_REGISTER_STATE_CHECK(fwd_txfm_(test_input_block, test_temp_block, 32)); - if (bit_depth_ == VPX_BITS_8) { - ASM_REGISTER_STATE_CHECK(inv_txfm_(test_temp_block, dst, 32)); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - ASM_REGISTER_STATE_CHECK( - inv_txfm_(test_temp_block, CAST_TO_BYTEPTR(dst16), 32)); -#endif - } - - for (int j = 0; j < kNumCoeffs; ++j) { -#if CONFIG_VP9_HIGHBITDEPTH - const int32_t diff = - bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j]; -#else - const int32_t diff = dst[j] - src[j]; -#endif - const uint32_t error = diff * diff; - if (max_error < error) max_error = error; - total_error += error; - } - } - - if (version_ == 1) { - max_error /= 2; - total_error /= 45; - } - - EXPECT_GE(1u << 2 * (bit_depth_ - 8), max_error) - << "Error: 32x32 FDCT/IDCT has an individual round-trip error > 1"; - - EXPECT_GE(count_test_block << 2 * (bit_depth_ - 8), total_error) - << "Error: 32x32 FDCT/IDCT has average round-trip error > 1 per block"; -} - -TEST_P(Trans32x32Test, CoeffCheck) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 1000; - - DECLARE_ALIGNED(16, int16_t, input_block[kNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]); - - for (int i = 0; i < count_test_block; ++i) { - for (int j = 0; j < kNumCoeffs; ++j) { - input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_); - } - - const int stride = 32; - vpx_fdct32x32_c(input_block, output_ref_block, stride); - ASM_REGISTER_STATE_CHECK(fwd_txfm_(input_block, output_block, stride)); - - if (version_ == 0) { - for (int j = 0; j < kNumCoeffs; ++j) - EXPECT_EQ(output_block[j], output_ref_block[j]) - << "Error: 32x32 FDCT versions have mismatched coefficients"; - } else { - for (int j = 0; j < kNumCoeffs; ++j) - EXPECT_GE(6, abs(output_block[j] - output_ref_block[j])) - << "Error: 32x32 FDCT rd has mismatched coefficients"; - } - } -} - -TEST_P(Trans32x32Test, MemCheck) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 2000; - - DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]); - - for (int i = 0; i < count_test_block; ++i) { - // Initialize a test block with input range [-mask_, mask_]. - for (int j = 0; j < kNumCoeffs; ++j) { - input_extreme_block[j] = rnd.Rand8() & 1 ? mask_ : -mask_; - } - if (i == 0) { - for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_; - } else if (i == 1) { - for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_; - } - - const int stride = 32; - vpx_fdct32x32_c(input_extreme_block, output_ref_block, stride); - ASM_REGISTER_STATE_CHECK( - fwd_txfm_(input_extreme_block, output_block, stride)); - - // The minimum quant value is 4. - for (int j = 0; j < kNumCoeffs; ++j) { - if (version_ == 0) { - EXPECT_EQ(output_block[j], output_ref_block[j]) - << "Error: 32x32 FDCT versions have mismatched coefficients"; - } else { - EXPECT_GE(6, abs(output_block[j] - output_ref_block[j])) - << "Error: 32x32 FDCT rd has mismatched coefficients"; - } - EXPECT_GE(4 * DCT_MAX_VALUE << (bit_depth_ - 8), abs(output_ref_block[j])) - << "Error: 32x32 FDCT C has coefficient larger than 4*DCT_MAX_VALUE"; - EXPECT_GE(4 * DCT_MAX_VALUE << (bit_depth_ - 8), abs(output_block[j])) - << "Error: 32x32 FDCT has coefficient larger than " - << "4*DCT_MAX_VALUE"; - } - } -} - -TEST_P(Trans32x32Test, DISABLED_Speed) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - - DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]); - - bench_in_ = input_extreme_block; - bench_out_ = output_block; - - RunNTimes(INT16_MAX); - PrintMedian("32x32"); -} - -TEST_P(Trans32x32Test, InverseAccuracy) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 1000; - DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]); -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); - DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]); -#endif - - for (int i = 0; i < count_test_block; ++i) { - double out_r[kNumCoeffs]; - - // Initialize a test block with input range [-255, 255] - for (int j = 0; j < kNumCoeffs; ++j) { - if (bit_depth_ == VPX_BITS_8) { - src[j] = rnd.Rand8(); - dst[j] = rnd.Rand8(); - in[j] = src[j] - dst[j]; -#if CONFIG_VP9_HIGHBITDEPTH - } else { - src16[j] = rnd.Rand16() & mask_; - dst16[j] = rnd.Rand16() & mask_; - in[j] = src16[j] - dst16[j]; -#endif - } - } - - reference_32x32_dct_2d(in, out_r); - for (int j = 0; j < kNumCoeffs; ++j) { - coeff[j] = static_cast(round(out_r[j])); - } - if (bit_depth_ == VPX_BITS_8) { - ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, dst, 32)); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, CAST_TO_BYTEPTR(dst16), 32)); -#endif - } - for (int j = 0; j < kNumCoeffs; ++j) { -#if CONFIG_VP9_HIGHBITDEPTH - const int diff = - bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j]; -#else - const int diff = dst[j] - src[j]; -#endif - const int error = diff * diff; - EXPECT_GE(1, error) << "Error: 32x32 IDCT has error " << error - << " at index " << j; - } - } -} - -class InvTrans32x32Test : public ::testing::TestWithParam { - public: - ~InvTrans32x32Test() override = default; - void SetUp() override { - ref_txfm_ = GET_PARAM(0); - inv_txfm_ = GET_PARAM(1); - version_ = GET_PARAM(2); // 0: high precision forward transform - // 1: low precision version for rd loop - bit_depth_ = GET_PARAM(3); - eob_ = GET_PARAM(4); - thresh_ = GET_PARAM(4); - mask_ = (1 << bit_depth_) - 1; - pitch_ = 32; - } - - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - void RunRefTxfm(tran_low_t *out, uint8_t *dst, int stride) { - ref_txfm_(out, dst, stride); - } - void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) { - inv_txfm_(out, dst, stride); - } - int version_; - vpx_bit_depth_t bit_depth_; - int mask_; - int eob_; - int thresh_; - - InvTxfmFunc ref_txfm_; - InvTxfmFunc inv_txfm_; - int pitch_; - - void RunInvTrans32x32SpeedTest() { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 10000; - int64_t c_sum_time = 0; - int64_t simd_sum_time = 0; - const int16_t *scan = vp9_default_scan_orders[TX_32X32].scan; - DECLARE_ALIGNED(32, tran_low_t, coeff[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]); -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); - DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]); -#endif // CONFIG_VP9_HIGHBITDEPTH - - for (int j = 0; j < kNumCoeffs; ++j) { - if (j < eob_) { - // Random values less than the threshold, either positive or negative - coeff[scan[j]] = rnd(thresh_); - } else { - coeff[scan[j]] = 0; - } - if (bit_depth_ == VPX_BITS_8) { - dst[j] = 0; - ref[j] = 0; -#if CONFIG_VP9_HIGHBITDEPTH - } else { - dst16[j] = 0; - ref16[j] = 0; -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - - if (bit_depth_ == VPX_BITS_8) { - vpx_usec_timer timer_c; - vpx_usec_timer_start(&timer_c); - for (int i = 0; i < count_test_block; ++i) { - RunRefTxfm(coeff, ref, pitch_); - } - vpx_usec_timer_mark(&timer_c); - c_sum_time += vpx_usec_timer_elapsed(&timer_c); - - vpx_usec_timer timer_mod; - vpx_usec_timer_start(&timer_mod); - for (int i = 0; i < count_test_block; ++i) { - RunInvTxfm(coeff, dst, pitch_); - } - vpx_usec_timer_mark(&timer_mod); - simd_sum_time += vpx_usec_timer_elapsed(&timer_mod); - } else { -#if CONFIG_VP9_HIGHBITDEPTH - vpx_usec_timer timer_c; - vpx_usec_timer_start(&timer_c); - for (int i = 0; i < count_test_block; ++i) { - RunRefTxfm(coeff, CAST_TO_BYTEPTR(ref16), pitch_); - } - vpx_usec_timer_mark(&timer_c); - c_sum_time += vpx_usec_timer_elapsed(&timer_c); - - vpx_usec_timer timer_mod; - vpx_usec_timer_start(&timer_mod); - for (int i = 0; i < count_test_block; ++i) { - RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_); - } - vpx_usec_timer_mark(&timer_mod); - simd_sum_time += vpx_usec_timer_elapsed(&timer_mod); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - printf( - "c_time = %" PRId64 " \t simd_time = %" PRId64 " \t Gain = %4.2f \n", - c_sum_time, simd_sum_time, - (static_cast(c_sum_time) / static_cast(simd_sum_time))); - } - - void CompareInvReference32x32() { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 10000; - const int eob = 31; - const int16_t *scan = vp9_default_scan_orders[TX_32X32].scan; - DECLARE_ALIGNED(32, tran_low_t, coeff[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]); -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); - DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]); -#endif // CONFIG_VP9_HIGHBITDEPTH - - for (int i = 0; i < count_test_block; ++i) { - for (int j = 0; j < kNumCoeffs; ++j) { - if (j < eob) { - coeff[scan[j]] = rnd.Rand8Extremes(); - } else { - coeff[scan[j]] = 0; - } - if (bit_depth_ == VPX_BITS_8) { - dst[j] = 0; - ref[j] = 0; -#if CONFIG_VP9_HIGHBITDEPTH - } else { - dst16[j] = 0; - ref16[j] = 0; -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - if (bit_depth_ == VPX_BITS_8) { - RunRefTxfm(coeff, ref, pitch_); - RunInvTxfm(coeff, dst, pitch_); - } else { -#if CONFIG_VP9_HIGHBITDEPTH - RunRefTxfm(coeff, CAST_TO_BYTEPTR(ref16), pitch_); - ASM_REGISTER_STATE_CHECK( - RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_)); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - - for (int j = 0; j < kNumCoeffs; ++j) { -#if CONFIG_VP9_HIGHBITDEPTH - const uint32_t diff = - bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j]; -#else - const uint32_t diff = dst[j] - ref[j]; -#endif // CONFIG_VP9_HIGHBITDEPTH - const uint32_t error = diff * diff; - EXPECT_EQ(0u, error) << "Error: 32x32 IDCT Comparison has error " - << error << " at index " << j; - } - } - } -}; - -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InvTrans32x32Test); - -TEST_P(InvTrans32x32Test, DISABLED_Speed) { RunInvTrans32x32SpeedTest(); } -TEST_P(InvTrans32x32Test, CompareReference) { CompareInvReference32x32(); } - -using std::make_tuple; - -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - C, Trans32x32Test, - ::testing::Values( - make_tuple(&vpx_highbd_fdct32x32_c, &idct32x32_10, 0, VPX_BITS_10), - make_tuple(&vpx_highbd_fdct32x32_rd_c, &idct32x32_10, 1, VPX_BITS_10), - make_tuple(&vpx_highbd_fdct32x32_c, &idct32x32_12, 0, VPX_BITS_12), - make_tuple(&vpx_highbd_fdct32x32_rd_c, &idct32x32_12, 1, VPX_BITS_12), - make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 0, VPX_BITS_8), - make_tuple(&vpx_fdct32x32_rd_c, &vpx_idct32x32_1024_add_c, 1, - VPX_BITS_8))); -#else -INSTANTIATE_TEST_SUITE_P( - C, Trans32x32Test, - ::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 0, - VPX_BITS_8), - make_tuple(&vpx_fdct32x32_rd_c, &vpx_idct32x32_1024_add_c, - 1, VPX_BITS_8))); - -INSTANTIATE_TEST_SUITE_P( - C, InvTrans32x32Test, - ::testing::Values( - (make_tuple(&vpx_idct32x32_1024_add_c, &vpx_idct32x32_1024_add_c, 0, - VPX_BITS_8, 32, 6225)), - make_tuple(&vpx_idct32x32_135_add_c, &vpx_idct32x32_135_add_c, 0, - VPX_BITS_8, 16, 6255))); -#endif // CONFIG_VP9_HIGHBITDEPTH - -#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P( - NEON, Trans32x32Test, - ::testing::Values(make_tuple(&vpx_fdct32x32_neon, - &vpx_idct32x32_1024_add_neon, 0, VPX_BITS_8), - make_tuple(&vpx_fdct32x32_rd_neon, - &vpx_idct32x32_1024_add_neon, 1, VPX_BITS_8))); -#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE - -#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P( - SSE2, Trans32x32Test, - ::testing::Values(make_tuple(&vpx_fdct32x32_sse2, - &vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8), - make_tuple(&vpx_fdct32x32_rd_sse2, - &vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8))); - -INSTANTIATE_TEST_SUITE_P( - SSE2, InvTrans32x32Test, - ::testing::Values( - (make_tuple(&vpx_idct32x32_1024_add_c, &vpx_idct32x32_1024_add_sse2, 0, - VPX_BITS_8, 32, 6225)), - make_tuple(&vpx_idct32x32_135_add_c, &vpx_idct32x32_135_add_sse2, 0, - VPX_BITS_8, 16, 6225))); -#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE - -#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P( - SSE2, Trans32x32Test, - ::testing::Values( - make_tuple(&vpx_highbd_fdct32x32_sse2, &idct32x32_10, 0, VPX_BITS_10), - make_tuple(&vpx_highbd_fdct32x32_rd_sse2, &idct32x32_10, 1, - VPX_BITS_10), - make_tuple(&vpx_highbd_fdct32x32_sse2, &idct32x32_12, 0, VPX_BITS_12), - make_tuple(&vpx_highbd_fdct32x32_rd_sse2, &idct32x32_12, 1, - VPX_BITS_12), - make_tuple(&vpx_fdct32x32_sse2, &vpx_idct32x32_1024_add_c, 0, - VPX_BITS_8), - make_tuple(&vpx_fdct32x32_rd_sse2, &vpx_idct32x32_1024_add_c, 1, - VPX_BITS_8))); -#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE - -#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P( - AVX2, Trans32x32Test, - ::testing::Values(make_tuple(&vpx_fdct32x32_avx2, - &vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8), - make_tuple(&vpx_fdct32x32_rd_avx2, - &vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8))); - -INSTANTIATE_TEST_SUITE_P( - AVX2, InvTrans32x32Test, - ::testing::Values( - (make_tuple(&vpx_idct32x32_1024_add_c, &vpx_idct32x32_1024_add_avx2, 0, - VPX_BITS_8, 32, 6225)), - make_tuple(&vpx_idct32x32_135_add_c, &vpx_idct32x32_135_add_avx2, 0, - VPX_BITS_8, 16, 6225))); -#endif // HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE - -#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P( - MSA, Trans32x32Test, - ::testing::Values(make_tuple(&vpx_fdct32x32_msa, - &vpx_idct32x32_1024_add_msa, 0, VPX_BITS_8), - make_tuple(&vpx_fdct32x32_rd_msa, - &vpx_idct32x32_1024_add_msa, 1, VPX_BITS_8))); -#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE - -#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P( - VSX, Trans32x32Test, - ::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_vsx, - 0, VPX_BITS_8), - make_tuple(&vpx_fdct32x32_rd_vsx, - &vpx_idct32x32_1024_add_vsx, 1, VPX_BITS_8))); -#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE - -#if HAVE_LSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P( - LSX, Trans32x32Test, - ::testing::Values(make_tuple(&vpx_fdct32x32_lsx, - &vpx_idct32x32_1024_add_lsx, 0, VPX_BITS_8), - make_tuple(&vpx_fdct32x32_rd_lsx, - &vpx_idct32x32_1024_add_lsx, 1, VPX_BITS_8))); -#endif // HAVE_LSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/dct_partial_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/dct_partial_test.cc deleted file mode 100644 index 97356de5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/dct_partial_test.cc +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vpx_dsp_rtcd.h" -#include "test/acm_random.h" -#include "test/buffer.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vpx_config.h" -#include "vpx/vpx_codec.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/vpx_dsp_common.h" - -using libvpx_test::ACMRandom; -using libvpx_test::Buffer; -using std::make_tuple; -using std::tuple; - -namespace { -typedef void (*PartialFdctFunc)(const int16_t *in, tran_low_t *out, int stride); - -typedef tuple - PartialFdctParam; - -tran_low_t partial_fdct_ref(const Buffer &in, int size) { - int64_t sum = 0; - if (in.TopLeftPixel() != nullptr) { - for (int y = 0; y < size; ++y) { - for (int x = 0; x < size; ++x) { - sum += in.TopLeftPixel()[y * in.stride() + x]; - } - } - } else { - assert(0); - } - - switch (size) { - case 4: sum *= 2; break; - case 8: /*sum = sum;*/ break; - case 16: sum >>= 1; break; - case 32: sum >>= 3; break; - } - - return static_cast(sum); -} - -class PartialFdctTest : public ::testing::TestWithParam { - public: - PartialFdctTest() { - fwd_txfm_ = GET_PARAM(0); - size_ = GET_PARAM(1); - bit_depth_ = GET_PARAM(2); - } - - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - void RunTest() { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int16_t maxvalue = - clip_pixel_highbd(std::numeric_limits::max(), bit_depth_); - const int16_t minvalue = -maxvalue; - Buffer input_block = - Buffer(size_, size_, 8, size_ == 4 ? 0 : 16); - ASSERT_TRUE(input_block.Init()); - Buffer output_block = Buffer(size_, size_, 0, 16); - ASSERT_TRUE(output_block.Init()); - - if (output_block.TopLeftPixel() != nullptr) { - for (int i = 0; i < 100; ++i) { - if (i == 0) { - input_block.Set(maxvalue); - } else if (i == 1) { - input_block.Set(minvalue); - } else { - input_block.Set(&rnd, minvalue, maxvalue); - } - - ASM_REGISTER_STATE_CHECK(fwd_txfm_(input_block.TopLeftPixel(), - output_block.TopLeftPixel(), - input_block.stride())); - - EXPECT_EQ(partial_fdct_ref(input_block, size_), - output_block.TopLeftPixel()[0]); - } - } else { - assert(0); - } - } - - PartialFdctFunc fwd_txfm_; - vpx_bit_depth_t bit_depth_; - int size_; -}; - -TEST_P(PartialFdctTest, PartialFdctTest) { RunTest(); } - -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - C, PartialFdctTest, - ::testing::Values(make_tuple(&vpx_highbd_fdct32x32_1_c, 32, VPX_BITS_12), - make_tuple(&vpx_highbd_fdct32x32_1_c, 32, VPX_BITS_10), - make_tuple(&vpx_fdct32x32_1_c, 32, VPX_BITS_8), - make_tuple(&vpx_highbd_fdct16x16_1_c, 16, VPX_BITS_12), - make_tuple(&vpx_highbd_fdct16x16_1_c, 16, VPX_BITS_10), - make_tuple(&vpx_fdct16x16_1_c, 16, VPX_BITS_8), - make_tuple(&vpx_highbd_fdct8x8_1_c, 8, VPX_BITS_12), - make_tuple(&vpx_highbd_fdct8x8_1_c, 8, VPX_BITS_10), - make_tuple(&vpx_fdct8x8_1_c, 8, VPX_BITS_8), - make_tuple(&vpx_fdct4x4_1_c, 4, VPX_BITS_8))); -#else -INSTANTIATE_TEST_SUITE_P( - C, PartialFdctTest, - ::testing::Values(make_tuple(&vpx_fdct32x32_1_c, 32, VPX_BITS_8), - make_tuple(&vpx_fdct16x16_1_c, 16, VPX_BITS_8), - make_tuple(&vpx_fdct8x8_1_c, 8, VPX_BITS_8), - make_tuple(&vpx_fdct4x4_1_c, 4, VPX_BITS_8))); -#endif // CONFIG_VP9_HIGHBITDEPTH - -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P( - SSE2, PartialFdctTest, - ::testing::Values(make_tuple(&vpx_fdct32x32_1_sse2, 32, VPX_BITS_8), - make_tuple(&vpx_fdct16x16_1_sse2, 16, VPX_BITS_8), - make_tuple(&vpx_fdct8x8_1_sse2, 8, VPX_BITS_8), - make_tuple(&vpx_fdct4x4_1_sse2, 4, VPX_BITS_8))); -#endif // HAVE_SSE2 - -#if HAVE_NEON -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - NEON, PartialFdctTest, - ::testing::Values(make_tuple(&vpx_highbd_fdct32x32_1_neon, 32, VPX_BITS_12), - make_tuple(&vpx_highbd_fdct32x32_1_neon, 32, VPX_BITS_10), - make_tuple(&vpx_highbd_fdct32x32_1_neon, 32, VPX_BITS_8), - make_tuple(&vpx_highbd_fdct16x16_1_neon, 16, VPX_BITS_12), - make_tuple(&vpx_highbd_fdct16x16_1_neon, 16, VPX_BITS_10), - make_tuple(&vpx_highbd_fdct16x16_1_neon, 16, VPX_BITS_8), - make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_12), - make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_10), - make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_8), - make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_12), - make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_10), - make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_8))); -#else -INSTANTIATE_TEST_SUITE_P( - NEON, PartialFdctTest, - ::testing::Values(make_tuple(&vpx_fdct32x32_1_neon, 32, VPX_BITS_8), - make_tuple(&vpx_fdct16x16_1_neon, 16, VPX_BITS_8), - make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_8), - make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_8))); -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif // HAVE_NEON - -#if HAVE_MSA -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P(MSA, PartialFdctTest, - ::testing::Values(make_tuple(&vpx_fdct8x8_1_msa, 8, - VPX_BITS_8))); -#else // !CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - MSA, PartialFdctTest, - ::testing::Values(make_tuple(&vpx_fdct32x32_1_msa, 32, VPX_BITS_8), - make_tuple(&vpx_fdct16x16_1_msa, 16, VPX_BITS_8), - make_tuple(&vpx_fdct8x8_1_msa, 8, VPX_BITS_8))); -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif // HAVE_MSA -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/dct_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/dct_test.cc deleted file mode 100644 index 8a65a660..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/dct_test.cc +++ /dev/null @@ -1,791 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vp9_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "test/acm_random.h" -#include "test/buffer.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vp9/common/vp9_entropy.h" -#include "vpx_config.h" -#include "vpx/vpx_codec.h" -#include "vpx/vpx_integer.h" -#include "vpx_ports/mem.h" - -using libvpx_test::ACMRandom; -using libvpx_test::Buffer; -using std::make_tuple; -using std::tuple; - -namespace { -typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride); -typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride); -typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride, - int tx_type); -typedef void (*FhtFuncRef)(const Buffer &in, Buffer *out, - int size, int tx_type); -typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride, - int tx_type); -typedef void (*IhtWithBdFunc)(const tran_low_t *in, uint8_t *out, int stride, - int tx_type, int bd); - -template -void fdct_wrapper(const int16_t *in, tran_low_t *out, int stride, int tx_type) { - (void)tx_type; - fn(in, out, stride); -} - -template -void idct_wrapper(const tran_low_t *in, uint8_t *out, int stride, int tx_type, - int bd) { - (void)tx_type; - (void)bd; - fn(in, out, stride); -} - -template -void iht_wrapper(const tran_low_t *in, uint8_t *out, int stride, int tx_type, - int bd) { - (void)bd; - fn(in, out, stride, tx_type); -} - -#if CONFIG_VP9_HIGHBITDEPTH -typedef void (*HighbdIdctFunc)(const tran_low_t *in, uint16_t *out, int stride, - int bd); - -typedef void (*HighbdIhtFunc)(const tran_low_t *in, uint16_t *out, int stride, - int tx_type, int bd); - -template -void highbd_idct_wrapper(const tran_low_t *in, uint8_t *out, int stride, - int tx_type, int bd) { - (void)tx_type; - fn(in, CAST_TO_SHORTPTR(out), stride, bd); -} - -template -void highbd_iht_wrapper(const tran_low_t *in, uint8_t *out, int stride, - int tx_type, int bd) { - fn(in, CAST_TO_SHORTPTR(out), stride, tx_type, bd); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -struct FuncInfo { - FhtFunc ft_func; - IhtWithBdFunc it_func; - int size; - int pixel_size; -}; - -/* forward transform, inverse transform, size, transform type, bit depth */ -typedef tuple DctParam; - -void fdct_ref(const Buffer &in, Buffer *out, int size, - int /*tx_type*/) { - const int16_t *i = in.TopLeftPixel(); - const int i_stride = in.stride(); - tran_low_t *o = out->TopLeftPixel(); - if (size == 4) { - vpx_fdct4x4_c(i, o, i_stride); - } else if (size == 8) { - vpx_fdct8x8_c(i, o, i_stride); - } else if (size == 16) { - vpx_fdct16x16_c(i, o, i_stride); - } else if (size == 32) { - vpx_fdct32x32_c(i, o, i_stride); - } -} - -void fht_ref(const Buffer &in, Buffer *out, int size, - int tx_type) { - const int16_t *i = in.TopLeftPixel(); - const int i_stride = in.stride(); - tran_low_t *o = out->TopLeftPixel(); - if (size == 4) { - vp9_fht4x4_c(i, o, i_stride, tx_type); - } else if (size == 8) { - vp9_fht8x8_c(i, o, i_stride, tx_type); - } else if (size == 16) { - vp9_fht16x16_c(i, o, i_stride, tx_type); - } -} - -void fwht_ref(const Buffer &in, Buffer *out, int size, - int /*tx_type*/) { - ASSERT_EQ(size, 4); - vp9_fwht4x4_c(in.TopLeftPixel(), out->TopLeftPixel(), in.stride()); -} - -class TransTestBase : public ::testing::TestWithParam { - public: - void SetUp() override { - rnd_.Reset(ACMRandom::DeterministicSeed()); - const int idx = GET_PARAM(0); - const FuncInfo *func_info = &(GET_PARAM(1)[idx]); - tx_type_ = GET_PARAM(2); - bit_depth_ = GET_PARAM(3); - fwd_txfm_ = func_info->ft_func; - inv_txfm_ = func_info->it_func; - size_ = func_info->size; - pixel_size_ = func_info->pixel_size; - max_pixel_value_ = (1 << bit_depth_) - 1; - - // Randomize stride_ to a value less than or equal to 1024 - stride_ = rnd_(1024) + 1; - if (stride_ < size_) { - stride_ = size_; - } - // Align stride_ to 16 if it's bigger than 16. - if (stride_ > 16) { - stride_ &= ~15; - } - - block_size_ = size_ * stride_; - - src_ = reinterpret_cast( - vpx_memalign(16, pixel_size_ * block_size_)); - ASSERT_NE(src_, nullptr); - dst_ = reinterpret_cast( - vpx_memalign(16, pixel_size_ * block_size_)); - ASSERT_NE(dst_, nullptr); - } - - void TearDown() override { - vpx_free(src_); - src_ = nullptr; - vpx_free(dst_); - dst_ = nullptr; - libvpx_test::ClearSystemState(); - } - - void InitMem() { - if (pixel_size_ == 1 && bit_depth_ > VPX_BITS_8) return; - if (pixel_size_ == 1) { - for (int j = 0; j < block_size_; ++j) { - src_[j] = rnd_.Rand16() & max_pixel_value_; - } - for (int j = 0; j < block_size_; ++j) { - dst_[j] = rnd_.Rand16() & max_pixel_value_; - } - } else { - ASSERT_EQ(pixel_size_, 2); - uint16_t *const src = reinterpret_cast(src_); - uint16_t *const dst = reinterpret_cast(dst_); - for (int j = 0; j < block_size_; ++j) { - src[j] = rnd_.Rand16() & max_pixel_value_; - } - for (int j = 0; j < block_size_; ++j) { - dst[j] = rnd_.Rand16() & max_pixel_value_; - } - } - } - - void RunFwdTxfm(const Buffer &in, Buffer *out) { - fwd_txfm_(in.TopLeftPixel(), out->TopLeftPixel(), in.stride(), tx_type_); - } - - void RunInvTxfm(const Buffer &in, uint8_t *out) { - inv_txfm_(in.TopLeftPixel(), out, stride_, tx_type_, bit_depth_); - } - - protected: - void RunAccuracyCheck(int limit) { - if (pixel_size_ == 1 && bit_depth_ > VPX_BITS_8) return; - ACMRandom rnd(ACMRandom::DeterministicSeed()); - Buffer test_input_block = - Buffer(size_, size_, 8, size_ == 4 ? 0 : 16); - ASSERT_TRUE(test_input_block.Init()); - ASSERT_NE(test_input_block.TopLeftPixel(), nullptr); - Buffer test_temp_block = - Buffer(size_, size_, 0, 16); - ASSERT_TRUE(test_temp_block.Init()); - uint32_t max_error = 0; - int64_t total_error = 0; - const int count_test_block = 10000; - for (int i = 0; i < count_test_block; ++i) { - InitMem(); - for (int h = 0; h < size_; ++h) { - for (int w = 0; w < size_; ++w) { - if (pixel_size_ == 1) { - test_input_block.TopLeftPixel()[h * test_input_block.stride() + w] = - src_[h * stride_ + w] - dst_[h * stride_ + w]; - } else { - ASSERT_EQ(pixel_size_, 2); - const uint16_t *const src = reinterpret_cast(src_); - const uint16_t *const dst = reinterpret_cast(dst_); - test_input_block.TopLeftPixel()[h * test_input_block.stride() + w] = - src[h * stride_ + w] - dst[h * stride_ + w]; - } - } - } - - ASM_REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block, &test_temp_block)); - ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst_)); - - for (int h = 0; h < size_; ++h) { - for (int w = 0; w < size_; ++w) { - int diff; - if (pixel_size_ == 1) { - diff = dst_[h * stride_ + w] - src_[h * stride_ + w]; - } else { - ASSERT_EQ(pixel_size_, 2); - const uint16_t *const src = reinterpret_cast(src_); - const uint16_t *const dst = reinterpret_cast(dst_); - diff = dst[h * stride_ + w] - src[h * stride_ + w]; - } - const uint32_t error = diff * diff; - if (max_error < error) max_error = error; - total_error += error; - } - } - } - - EXPECT_GE(static_cast(limit), max_error) - << "Error: " << size_ << "x" << size_ - << " transform/inverse transform has an individual round trip error > " - << limit; - - EXPECT_GE(count_test_block * limit, total_error) - << "Error: " << size_ << "x" << size_ - << " transform/inverse transform has average round trip error > " - << limit << " per block"; - } - - void RunCoeffCheck() { - if (pixel_size_ == 1 && bit_depth_ > VPX_BITS_8) return; - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 5000; - Buffer input_block = - Buffer(size_, size_, 8, size_ == 4 ? 0 : 16); - ASSERT_TRUE(input_block.Init()); - Buffer output_ref_block = Buffer(size_, size_, 0); - ASSERT_TRUE(output_ref_block.Init()); - Buffer output_block = Buffer(size_, size_, 0, 16); - ASSERT_TRUE(output_block.Init()); - - for (int i = 0; i < count_test_block; ++i) { - // Initialize a test block with input range [-max_pixel_value_, - // max_pixel_value_]. - input_block.Set(&rnd, -max_pixel_value_, max_pixel_value_); - - fwd_txfm_ref(input_block, &output_ref_block, size_, tx_type_); - ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, &output_block)); - - // The minimum quant value is 4. - EXPECT_TRUE(output_block.CheckValues(output_ref_block)); - if (::testing::Test::HasFailure()) { - printf("Size: %d Transform type: %d\n", size_, tx_type_); - output_block.PrintDifference(output_ref_block); - return; - } - } - } - - void RunMemCheck() { - if (pixel_size_ == 1 && bit_depth_ > VPX_BITS_8) return; - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 5000; - Buffer input_extreme_block = - Buffer(size_, size_, 8, size_ == 4 ? 0 : 16); - ASSERT_TRUE(input_extreme_block.Init()); - Buffer output_ref_block = Buffer(size_, size_, 0); - ASSERT_TRUE(output_ref_block.Init()); - Buffer output_block = Buffer(size_, size_, 0, 16); - ASSERT_TRUE(output_block.Init()); - - for (int i = 0; i < count_test_block; ++i) { - // Initialize a test block with -max_pixel_value_ or max_pixel_value_. - if (i == 0) { - input_extreme_block.Set(max_pixel_value_); - } else if (i == 1) { - input_extreme_block.Set(-max_pixel_value_); - } else { - ASSERT_NE(input_extreme_block.TopLeftPixel(), nullptr); - for (int h = 0; h < size_; ++h) { - for (int w = 0; w < size_; ++w) { - input_extreme_block - .TopLeftPixel()[h * input_extreme_block.stride() + w] = - rnd.Rand8() % 2 ? max_pixel_value_ : -max_pixel_value_; - } - } - } - - fwd_txfm_ref(input_extreme_block, &output_ref_block, size_, tx_type_); - ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block, &output_block)); - - // The minimum quant value is 4. - EXPECT_TRUE(output_block.CheckValues(output_ref_block)); - ASSERT_NE(output_block.TopLeftPixel(), nullptr); - for (int h = 0; h < size_; ++h) { - for (int w = 0; w < size_; ++w) { - EXPECT_GE( - 4 * DCT_MAX_VALUE << (bit_depth_ - 8), - abs(output_block.TopLeftPixel()[h * output_block.stride() + w])) - << "Error: " << size_ << "x" << size_ - << " transform has coefficient larger than 4*DCT_MAX_VALUE" - << " at " << w << "," << h; - if (::testing::Test::HasFailure()) { - printf("Size: %d Transform type: %d\n", size_, tx_type_); - output_block.DumpBuffer(); - return; - } - } - } - } - } - - void RunInvAccuracyCheck(int limit) { - if (pixel_size_ == 1 && bit_depth_ > VPX_BITS_8) return; - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 1000; - Buffer in = Buffer(size_, size_, 4); - ASSERT_TRUE(in.Init()); - Buffer coeff = Buffer(size_, size_, 0, 16); - ASSERT_TRUE(coeff.Init()); - - for (int i = 0; i < count_test_block; ++i) { - InitMem(); - ASSERT_NE(in.TopLeftPixel(), nullptr); - // Initialize a test block with input range [-max_pixel_value_, - // max_pixel_value_]. - for (int h = 0; h < size_; ++h) { - for (int w = 0; w < size_; ++w) { - if (pixel_size_ == 1) { - in.TopLeftPixel()[h * in.stride() + w] = - src_[h * stride_ + w] - dst_[h * stride_ + w]; - } else { - ASSERT_EQ(pixel_size_, 2); - const uint16_t *const src = reinterpret_cast(src_); - const uint16_t *const dst = reinterpret_cast(dst_); - in.TopLeftPixel()[h * in.stride() + w] = - src[h * stride_ + w] - dst[h * stride_ + w]; - } - } - } - - fwd_txfm_ref(in, &coeff, size_, tx_type_); - - ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst_)); - - for (int h = 0; h < size_; ++h) { - for (int w = 0; w < size_; ++w) { - int diff; - if (pixel_size_ == 1) { - diff = dst_[h * stride_ + w] - src_[h * stride_ + w]; - } else { - ASSERT_EQ(pixel_size_, 2); - const uint16_t *const src = reinterpret_cast(src_); - const uint16_t *const dst = reinterpret_cast(dst_); - diff = dst[h * stride_ + w] - src[h * stride_ + w]; - } - const uint32_t error = diff * diff; - EXPECT_GE(static_cast(limit), error) - << "Error: " << size_ << "x" << size_ - << " inverse transform has error " << error << " at " << w << "," - << h; - if (::testing::Test::HasFailure()) { - printf("Size: %d Transform type: %d\n", size_, tx_type_); - return; - } - } - } - } - } - - FhtFunc fwd_txfm_; - FhtFuncRef fwd_txfm_ref; - IhtWithBdFunc inv_txfm_; - ACMRandom rnd_; - uint8_t *src_; - uint8_t *dst_; - vpx_bit_depth_t bit_depth_; - int tx_type_; - int max_pixel_value_; - int size_; - int stride_; - int pixel_size_; - int block_size_; -}; - -/* -------------------------------------------------------------------------- */ - -class TransDCT : public TransTestBase { - public: - TransDCT() { fwd_txfm_ref = fdct_ref; } -}; - -TEST_P(TransDCT, AccuracyCheck) { - int t = 1; - if (size_ == 16 && bit_depth_ > 10 && pixel_size_ == 2) { - t = 2; - } else if (size_ == 32 && bit_depth_ > 10 && pixel_size_ == 2) { - t = 7; - } - RunAccuracyCheck(t); -} - -TEST_P(TransDCT, CoeffCheck) { RunCoeffCheck(); } - -TEST_P(TransDCT, MemCheck) { RunMemCheck(); } - -TEST_P(TransDCT, InvAccuracyCheck) { RunInvAccuracyCheck(1); } - -static const FuncInfo dct_c_func_info[] = { -#if CONFIG_VP9_HIGHBITDEPTH - { &fdct_wrapper, - &highbd_idct_wrapper, 4, 2 }, - { &fdct_wrapper, - &highbd_idct_wrapper, 8, 2 }, - { &fdct_wrapper, - &highbd_idct_wrapper, 16, 2 }, - { &fdct_wrapper, - &highbd_idct_wrapper, 32, 2 }, -#endif - { &fdct_wrapper, &idct_wrapper, 4, 1 }, - { &fdct_wrapper, &idct_wrapper, 8, 1 }, - { &fdct_wrapper, &idct_wrapper, 16, - 1 }, - { &fdct_wrapper, &idct_wrapper, 32, - 1 } -}; - -INSTANTIATE_TEST_SUITE_P( - C, TransDCT, - ::testing::Combine( - ::testing::Range(0, static_cast(sizeof(dct_c_func_info) / - sizeof(dct_c_func_info[0]))), - ::testing::Values(dct_c_func_info), ::testing::Values(0), - ::testing::Values(VPX_BITS_8, VPX_BITS_10, VPX_BITS_12))); - -#if !CONFIG_EMULATE_HARDWARE - -#if HAVE_SSE2 -static const FuncInfo dct_sse2_func_info[] = { -#if CONFIG_VP9_HIGHBITDEPTH - { &fdct_wrapper, - &highbd_idct_wrapper, 4, 2 }, - { &fdct_wrapper, - &highbd_idct_wrapper, 8, 2 }, - { &fdct_wrapper, - &highbd_idct_wrapper, 16, 2 }, - { &fdct_wrapper, - &highbd_idct_wrapper, 32, 2 }, -#endif - { &fdct_wrapper, &idct_wrapper, 4, - 1 }, - { &fdct_wrapper, &idct_wrapper, 8, - 1 }, - { &fdct_wrapper, - &idct_wrapper, 16, 1 }, - { &fdct_wrapper, - &idct_wrapper, 32, 1 } -}; - -INSTANTIATE_TEST_SUITE_P( - SSE2, TransDCT, - ::testing::Combine( - ::testing::Range(0, static_cast(sizeof(dct_sse2_func_info) / - sizeof(dct_sse2_func_info[0]))), - ::testing::Values(dct_sse2_func_info), ::testing::Values(0), - ::testing::Values(VPX_BITS_8, VPX_BITS_10, VPX_BITS_12))); -#endif // HAVE_SSE2 - -#if HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH && VPX_ARCH_X86_64 -// vpx_fdct8x8_ssse3 is only available in 64 bit builds. -static const FuncInfo dct_ssse3_func_info = { - &fdct_wrapper, &idct_wrapper, 8, 1 -}; - -// TODO(johannkoenig): high bit depth fdct8x8. -INSTANTIATE_TEST_SUITE_P(SSSE3, TransDCT, - ::testing::Values(make_tuple(0, &dct_ssse3_func_info, - 0, VPX_BITS_8))); -#endif // HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH && VPX_ARCH_X86_64 - -#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH -static const FuncInfo dct_avx2_func_info = { - &fdct_wrapper, &idct_wrapper, - 32, 1 -}; - -// TODO(johannkoenig): high bit depth fdct32x32. -INSTANTIATE_TEST_SUITE_P(AVX2, TransDCT, - ::testing::Values(make_tuple(0, &dct_avx2_func_info, 0, - VPX_BITS_8))); -#endif // HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH - -#if HAVE_NEON -#if CONFIG_VP9_HIGHBITDEPTH -static const FuncInfo dct_neon_func_info[] = { - { &fdct_wrapper, - &highbd_idct_wrapper, 4, 2 }, - { &fdct_wrapper, - &highbd_idct_wrapper, 8, 2 }, - { &fdct_wrapper, - &highbd_idct_wrapper, 16, 2 }, - /* { &fdct_wrapper, - &highbd_idct_wrapper, 32, 2 },*/ -}; -#else -static const FuncInfo dct_neon_func_info[4] = { - { &fdct_wrapper, &idct_wrapper, 4, - 1 }, - { &fdct_wrapper, &idct_wrapper, 8, - 1 }, - { &fdct_wrapper, - &idct_wrapper, 16, 1 }, - { &fdct_wrapper, - &idct_wrapper, 32, 1 } -}; -#endif // CONFIG_VP9_HIGHBITDEPTH - -INSTANTIATE_TEST_SUITE_P( - NEON, TransDCT, - ::testing::Combine( - ::testing::Range(0, static_cast(sizeof(dct_neon_func_info) / - sizeof(dct_neon_func_info[0]))), - ::testing::Values(dct_neon_func_info), ::testing::Values(0), - ::testing::Values(VPX_BITS_8, VPX_BITS_10, VPX_BITS_12))); -#endif // HAVE_NEON - -#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH -static const FuncInfo dct_msa_func_info[4] = { - { &fdct_wrapper, &idct_wrapper, 4, - 1 }, - { &fdct_wrapper, &idct_wrapper, 8, - 1 }, - { &fdct_wrapper, &idct_wrapper, - 16, 1 }, - { &fdct_wrapper, &idct_wrapper, - 32, 1 } -}; - -INSTANTIATE_TEST_SUITE_P( - MSA, TransDCT, - ::testing::Combine(::testing::Range(0, 4), - ::testing::Values(dct_msa_func_info), - ::testing::Values(0), ::testing::Values(VPX_BITS_8))); -#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH - -#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH -static const FuncInfo dct_vsx_func_info = { - &fdct_wrapper, &idct_wrapper, 4, 1 -}; - -INSTANTIATE_TEST_SUITE_P(VSX, TransDCT, - ::testing::Values(make_tuple(0, &dct_vsx_func_info, 0, - VPX_BITS_8))); -#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && - -#if HAVE_LSX && !CONFIG_VP9_HIGHBITDEPTH -static const FuncInfo dct_lsx_func_info[4] = { - { &fdct_wrapper, &idct_wrapper, 4, 1 }, - { &fdct_wrapper, &idct_wrapper, 8, 1 }, - { &fdct_wrapper, &idct_wrapper, - 16, 1 }, - { &fdct_wrapper, &idct_wrapper, - 32, 1 } -}; - -INSTANTIATE_TEST_SUITE_P( - LSX, TransDCT, - ::testing::Combine(::testing::Range(0, 4), - ::testing::Values(dct_lsx_func_info), - ::testing::Values(0), ::testing::Values(VPX_BITS_8))); -#endif // HAVE_LSX && !CONFIG_VP9_HIGHBITDEPTH - -#endif // !CONFIG_EMULATE_HARDWARE - -/* -------------------------------------------------------------------------- */ - -class TransHT : public TransTestBase { - public: - TransHT() { fwd_txfm_ref = fht_ref; } -}; - -TEST_P(TransHT, AccuracyCheck) { - RunAccuracyCheck(size_ == 16 && bit_depth_ > 10 && pixel_size_ == 2 ? 2 : 1); -} - -TEST_P(TransHT, CoeffCheck) { RunCoeffCheck(); } - -TEST_P(TransHT, MemCheck) { RunMemCheck(); } - -TEST_P(TransHT, InvAccuracyCheck) { RunInvAccuracyCheck(1); } - -static const FuncInfo ht_c_func_info[] = { -#if CONFIG_VP9_HIGHBITDEPTH - { &vp9_highbd_fht4x4_c, &highbd_iht_wrapper, 4, - 2 }, - { &vp9_highbd_fht8x8_c, &highbd_iht_wrapper, 8, - 2 }, - { &vp9_highbd_fht16x16_c, &highbd_iht_wrapper, - 16, 2 }, -#endif - { &vp9_fht4x4_c, &iht_wrapper, 4, 1 }, - { &vp9_fht8x8_c, &iht_wrapper, 8, 1 }, - { &vp9_fht16x16_c, &iht_wrapper, 16, 1 } -}; - -INSTANTIATE_TEST_SUITE_P( - C, TransHT, - ::testing::Combine( - ::testing::Range(0, static_cast(sizeof(ht_c_func_info) / - sizeof(ht_c_func_info[0]))), - ::testing::Values(ht_c_func_info), ::testing::Range(0, 4), - ::testing::Values(VPX_BITS_8, VPX_BITS_10, VPX_BITS_12))); - -#if !CONFIG_EMULATE_HARDWARE - -#if HAVE_NEON - -static const FuncInfo ht_neon_func_info[] = { -#if CONFIG_VP9_HIGHBITDEPTH - { &vp9_highbd_fht4x4_c, &highbd_iht_wrapper, 4, - 2 }, - { &vp9_highbd_fht4x4_neon, &highbd_iht_wrapper, - 4, 2 }, - { &vp9_highbd_fht8x8_c, &highbd_iht_wrapper, 8, - 2 }, - { &vp9_highbd_fht8x8_neon, &highbd_iht_wrapper, - 8, 2 }, - { &vp9_highbd_fht16x16_c, - &highbd_iht_wrapper, 16, 2 }, - { &vp9_highbd_fht16x16_neon, - &highbd_iht_wrapper, 16, 2 }, -#endif - { &vp9_fht4x4_c, &iht_wrapper, 4, 1 }, - { &vp9_fht4x4_neon, &iht_wrapper, 4, 1 }, - { &vp9_fht8x8_c, &iht_wrapper, 8, 1 }, - { &vp9_fht8x8_neon, &iht_wrapper, 8, 1 }, - { &vp9_fht16x16_c, &iht_wrapper, 16, 1 }, - { &vp9_fht16x16_neon, &iht_wrapper, 16, 1 } -}; - -INSTANTIATE_TEST_SUITE_P( - NEON, TransHT, - ::testing::Combine( - ::testing::Range(0, static_cast(sizeof(ht_neon_func_info) / - sizeof(ht_neon_func_info[0]))), - ::testing::Values(ht_neon_func_info), ::testing::Range(0, 4), - ::testing::Values(VPX_BITS_8, VPX_BITS_10, VPX_BITS_12))); -#endif // HAVE_NEON - -#if HAVE_SSE2 - -static const FuncInfo ht_sse2_func_info[3] = { - { &vp9_fht4x4_sse2, &iht_wrapper, 4, 1 }, - { &vp9_fht8x8_sse2, &iht_wrapper, 8, 1 }, - { &vp9_fht16x16_sse2, &iht_wrapper, 16, 1 } -}; - -INSTANTIATE_TEST_SUITE_P( - SSE2, TransHT, - ::testing::Combine(::testing::Range(0, 3), - ::testing::Values(ht_sse2_func_info), - ::testing::Range(0, 4), ::testing::Values(VPX_BITS_8))); -#endif // HAVE_SSE2 - -#if HAVE_SSE4_1 && CONFIG_VP9_HIGHBITDEPTH -static const FuncInfo ht_sse4_1_func_info[3] = { - { &vp9_highbd_fht4x4_c, &highbd_iht_wrapper, - 4, 2 }, - { vp9_highbd_fht8x8_c, &highbd_iht_wrapper, - 8, 2 }, - { &vp9_highbd_fht16x16_c, - &highbd_iht_wrapper, 16, 2 } -}; - -INSTANTIATE_TEST_SUITE_P( - SSE4_1, TransHT, - ::testing::Combine(::testing::Range(0, 3), - ::testing::Values(ht_sse4_1_func_info), - ::testing::Range(0, 4), - ::testing::Values(VPX_BITS_8, VPX_BITS_10, - VPX_BITS_12))); -#endif // HAVE_SSE4_1 && CONFIG_VP9_HIGHBITDEPTH - -#if HAVE_VSX && !CONFIG_EMULATE_HARDWARE && !CONFIG_VP9_HIGHBITDEPTH -static const FuncInfo ht_vsx_func_info[3] = { - { &vp9_fht4x4_c, &iht_wrapper, 4, 1 }, - { &vp9_fht8x8_c, &iht_wrapper, 8, 1 }, - { &vp9_fht16x16_c, &iht_wrapper, 16, 1 } -}; - -INSTANTIATE_TEST_SUITE_P(VSX, TransHT, - ::testing::Combine(::testing::Range(0, 3), - ::testing::Values(ht_vsx_func_info), - ::testing::Range(0, 4), - ::testing::Values(VPX_BITS_8))); -#endif // HAVE_VSX -#endif // !CONFIG_EMULATE_HARDWARE - -/* -------------------------------------------------------------------------- */ - -class TransWHT : public TransTestBase { - public: - TransWHT() { fwd_txfm_ref = fwht_ref; } -}; - -TEST_P(TransWHT, AccuracyCheck) { RunAccuracyCheck(0); } - -TEST_P(TransWHT, CoeffCheck) { RunCoeffCheck(); } - -TEST_P(TransWHT, MemCheck) { RunMemCheck(); } - -TEST_P(TransWHT, InvAccuracyCheck) { RunInvAccuracyCheck(0); } - -static const FuncInfo wht_c_func_info[] = { -#if CONFIG_VP9_HIGHBITDEPTH - { &fdct_wrapper, - &highbd_idct_wrapper, 4, 2 }, -#endif - { &fdct_wrapper, &idct_wrapper, 4, 1 } -}; - -INSTANTIATE_TEST_SUITE_P( - C, TransWHT, - ::testing::Combine( - ::testing::Range(0, static_cast(sizeof(wht_c_func_info) / - sizeof(wht_c_func_info[0]))), - ::testing::Values(wht_c_func_info), ::testing::Values(0), - ::testing::Values(VPX_BITS_8, VPX_BITS_10, VPX_BITS_12))); - -#if HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE -static const FuncInfo wht_sse2_func_info = { - &fdct_wrapper, &idct_wrapper, 4, 1 -}; - -INSTANTIATE_TEST_SUITE_P(SSE2, TransWHT, - ::testing::Values(make_tuple(0, &wht_sse2_func_info, 0, - VPX_BITS_8))); -#endif // HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE - -#if HAVE_VSX && !CONFIG_EMULATE_HARDWARE && !CONFIG_VP9_HIGHBITDEPTH -static const FuncInfo wht_vsx_func_info = { - &fdct_wrapper, &idct_wrapper, 4, 1 -}; - -INSTANTIATE_TEST_SUITE_P(VSX, TransWHT, - ::testing::Values(make_tuple(0, &wht_vsx_func_info, 0, - VPX_BITS_8))); -#endif // HAVE_VSX && !CONFIG_EMULATE_HARDWARE - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/decode_api_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/decode_api_test.cc deleted file mode 100644 index d7436ca3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/decode_api_test.cc +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "gtest/gtest.h" - -#include "./vpx_config.h" -#include "test/ivf_video_source.h" -#include "vpx/vp8dx.h" -#include "vpx/vpx_decoder.h" - -namespace { - -#define NELEMENTS(x) static_cast(sizeof(x) / sizeof(x[0])) - -TEST(DecodeAPI, InvalidParams) { - static vpx_codec_iface_t *kCodecs[] = { -#if CONFIG_VP8_DECODER - &vpx_codec_vp8_dx_algo, -#endif -#if CONFIG_VP9_DECODER - &vpx_codec_vp9_dx_algo, -#endif - }; - uint8_t buf[1] = { 0 }; - vpx_codec_ctx_t dec; - - EXPECT_EQ(vpx_codec_dec_init(nullptr, nullptr, nullptr, 0), - VPX_CODEC_INVALID_PARAM); - EXPECT_EQ(vpx_codec_dec_init(&dec, nullptr, nullptr, 0), - VPX_CODEC_INVALID_PARAM); - EXPECT_EQ(vpx_codec_decode(nullptr, nullptr, 0, nullptr, 0), - VPX_CODEC_INVALID_PARAM); - EXPECT_EQ(vpx_codec_decode(nullptr, buf, 0, nullptr, 0), - VPX_CODEC_INVALID_PARAM); - EXPECT_EQ(vpx_codec_decode(nullptr, buf, NELEMENTS(buf), nullptr, 0), - VPX_CODEC_INVALID_PARAM); - EXPECT_EQ(vpx_codec_decode(nullptr, nullptr, NELEMENTS(buf), nullptr, 0), - VPX_CODEC_INVALID_PARAM); - EXPECT_EQ(vpx_codec_destroy(nullptr), VPX_CODEC_INVALID_PARAM); - EXPECT_NE(vpx_codec_error(nullptr), nullptr); - EXPECT_EQ(vpx_codec_error_detail(nullptr), nullptr); - - for (int i = 0; i < NELEMENTS(kCodecs); ++i) { - EXPECT_EQ(VPX_CODEC_INVALID_PARAM, - vpx_codec_dec_init(nullptr, kCodecs[i], nullptr, 0)); - - EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, kCodecs[i], nullptr, 0)); - EXPECT_EQ(VPX_CODEC_UNSUP_BITSTREAM, - vpx_codec_decode(&dec, buf, NELEMENTS(buf), nullptr, 0)); - EXPECT_EQ(VPX_CODEC_INVALID_PARAM, - vpx_codec_decode(&dec, nullptr, NELEMENTS(buf), nullptr, 0)); - EXPECT_EQ(VPX_CODEC_INVALID_PARAM, - vpx_codec_decode(&dec, buf, 0, nullptr, 0)); - - EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec)); - } -} - -#if CONFIG_VP8_DECODER -TEST(DecodeAPI, OptionalParams) { - vpx_codec_ctx_t dec; - -#if CONFIG_ERROR_CONCEALMENT - EXPECT_EQ(VPX_CODEC_OK, - vpx_codec_dec_init(&dec, &vpx_codec_vp8_dx_algo, nullptr, - VPX_CODEC_USE_ERROR_CONCEALMENT)); -#else - EXPECT_EQ(VPX_CODEC_INCAPABLE, - vpx_codec_dec_init(&dec, &vpx_codec_vp8_dx_algo, nullptr, - VPX_CODEC_USE_ERROR_CONCEALMENT)); -#endif // CONFIG_ERROR_CONCEALMENT -} -#endif // CONFIG_VP8_DECODER - -#if CONFIG_VP9_DECODER -// Test VP9 codec controls after a decode error to ensure the code doesn't -// misbehave. -void TestVp9Controls(vpx_codec_ctx_t *dec) { - static const int kControls[] = { VP8D_GET_LAST_REF_UPDATES, - VP8D_GET_FRAME_CORRUPTED, - VP9D_GET_DISPLAY_SIZE, VP9D_GET_FRAME_SIZE }; - int val[2]; - - for (int i = 0; i < NELEMENTS(kControls); ++i) { - const vpx_codec_err_t res = vpx_codec_control_(dec, kControls[i], val); - switch (kControls[i]) { - case VP8D_GET_FRAME_CORRUPTED: - EXPECT_EQ(VPX_CODEC_ERROR, res) << kControls[i]; - break; - default: EXPECT_EQ(VPX_CODEC_OK, res) << kControls[i]; break; - } - EXPECT_EQ(VPX_CODEC_INVALID_PARAM, - vpx_codec_control_(dec, kControls[i], nullptr)); - } - - vp9_ref_frame_t ref; - ref.idx = 0; - EXPECT_EQ(VPX_CODEC_ERROR, vpx_codec_control(dec, VP9_GET_REFERENCE, &ref)); - EXPECT_EQ(VPX_CODEC_INVALID_PARAM, - vpx_codec_control(dec, VP9_GET_REFERENCE, nullptr)); - - vpx_ref_frame_t ref_copy; - const int width = 352; - const int height = 288; - EXPECT_NE(vpx_img_alloc(&ref_copy.img, VPX_IMG_FMT_I420, width, height, 1), - nullptr); - ref_copy.frame_type = VP8_LAST_FRAME; - EXPECT_EQ(VPX_CODEC_ERROR, - vpx_codec_control(dec, VP8_COPY_REFERENCE, &ref_copy)); - EXPECT_EQ(VPX_CODEC_INVALID_PARAM, - vpx_codec_control(dec, VP8_COPY_REFERENCE, nullptr)); - vpx_img_free(&ref_copy.img); -} - -TEST(DecodeAPI, Vp9InvalidDecode) { - vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo; - const char filename[] = - "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf"; - libvpx_test::IVFVideoSource video(filename); - video.Init(); - video.Begin(); - ASSERT_TRUE(!HasFailure()); - - vpx_codec_ctx_t dec; - EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, nullptr, 0)); - const uint32_t frame_size = static_cast(video.frame_size()); -#if CONFIG_VP9_HIGHBITDEPTH - EXPECT_EQ(VPX_CODEC_MEM_ERROR, - vpx_codec_decode(&dec, video.cxdata(), frame_size, nullptr, 0)); -#else - EXPECT_EQ(VPX_CODEC_UNSUP_BITSTREAM, - vpx_codec_decode(&dec, video.cxdata(), frame_size, nullptr, 0)); -#endif - vpx_codec_iter_t iter = nullptr; - EXPECT_EQ(nullptr, vpx_codec_get_frame(&dec, &iter)); - - TestVp9Controls(&dec); - EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec)); -} - -void TestPeekInfo(const uint8_t *const data, uint32_t data_sz, - uint32_t peek_size) { - vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo; - // Verify behavior of vpx_codec_decode. vpx_codec_decode doesn't even get - // to decoder_peek_si_internal on frames of size < 8. - if (data_sz >= 8) { - vpx_codec_ctx_t dec; - EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, nullptr, 0)); - EXPECT_EQ((data_sz < peek_size) ? VPX_CODEC_UNSUP_BITSTREAM - : VPX_CODEC_CORRUPT_FRAME, - vpx_codec_decode(&dec, data, data_sz, nullptr, 0)); - vpx_codec_iter_t iter = nullptr; - EXPECT_EQ(nullptr, vpx_codec_get_frame(&dec, &iter)); - EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec)); - } - - // Verify behavior of vpx_codec_peek_stream_info. - vpx_codec_stream_info_t si; - si.sz = sizeof(si); - EXPECT_EQ((data_sz < peek_size) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_OK, - vpx_codec_peek_stream_info(codec, data, data_sz, &si)); -} - -TEST(DecodeAPI, Vp9PeekStreamInfo) { - // The first 9 bytes are valid and the rest of the bytes are made up. Until - // size 10, this should return VPX_CODEC_UNSUP_BITSTREAM and after that it - // should return VPX_CODEC_CORRUPT_FRAME. - const uint8_t data[32] = { - 0x85, 0xa4, 0xc1, 0xa1, 0x38, 0x81, 0xa3, 0x49, 0x83, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - }; - - for (uint32_t data_sz = 1; data_sz <= 32; ++data_sz) { - TestPeekInfo(data, data_sz, 10); - } -} - -TEST(DecodeAPI, Vp9PeekStreamInfoTruncated) { - // This profile 1 header requires 10.25 bytes, ensure - // vpx_codec_peek_stream_info doesn't over read. - const uint8_t profile1_data[10] = { 0xa4, 0xe9, 0x30, 0x68, 0x53, - 0xe9, 0x30, 0x68, 0x53, 0x04 }; - - for (uint32_t data_sz = 1; data_sz <= 10; ++data_sz) { - TestPeekInfo(profile1_data, data_sz, 11); - } -} -#endif // CONFIG_VP9_DECODER - -TEST(DecodeAPI, HighBitDepthCapability) { -// VP8 should not claim VP9 HBD as a capability. -#if CONFIG_VP8_DECODER - const vpx_codec_caps_t vp8_caps = vpx_codec_get_caps(&vpx_codec_vp8_dx_algo); - EXPECT_EQ(vp8_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0); -#endif - -#if CONFIG_VP9_DECODER - const vpx_codec_caps_t vp9_caps = vpx_codec_get_caps(&vpx_codec_vp9_dx_algo); -#if CONFIG_VP9_HIGHBITDEPTH - EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, VPX_CODEC_CAP_HIGHBITDEPTH); -#else - EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0); -#endif -#endif -} - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/decode_corrupted.cc b/presentation/src/main/cpp/third_party/libvpx/test/decode_corrupted.cc deleted file mode 100644 index 8e51fb3c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/decode_corrupted.cc +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "gtest/gtest.h" - -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/util.h" -#include "test/i420_video_source.h" -#include "vpx_config.h" -#include "vpx_mem/vpx_mem.h" - -namespace { - -class DecodeCorruptedFrameTest - : public ::libvpx_test::EncoderTest, - public ::testing::TestWithParam< - std::tuple > { - public: - DecodeCorruptedFrameTest() : EncoderTest(GET_PARAM(0)) {} - - protected: - ~DecodeCorruptedFrameTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - cfg_.g_lag_in_frames = 0; - cfg_.rc_end_usage = VPX_CBR; - cfg_.rc_buf_sz = 1000; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 600; - - // Set small key frame distance such that we insert more key frames. - cfg_.kf_max_dist = 3; - dec_cfg_.threads = 1; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) encoder->Control(VP8E_SET_CPUUSED, 7); - } - - void MismatchHook(const vpx_image_t * /*img1*/, - const vpx_image_t * /*img2*/) override {} - - const vpx_codec_cx_pkt_t *MutateEncoderOutputHook( - const vpx_codec_cx_pkt_t *pkt) override { - // Don't edit frame packet on key frame. - if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) return pkt; - if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return pkt; - - memcpy(&modified_pkt_, pkt, sizeof(*pkt)); - - // Halve the size so it's corrupted to decoder. - modified_pkt_.data.frame.sz = modified_pkt_.data.frame.sz / 2; - - return &modified_pkt_; - } - - bool HandleDecodeResult(const vpx_codec_err_t res_dec, - const libvpx_test::VideoSource & /*video*/, - libvpx_test::Decoder *decoder) override { - EXPECT_NE(res_dec, VPX_CODEC_MEM_ERROR) << decoder->DecodeError(); - return VPX_CODEC_MEM_ERROR != res_dec; - } - - vpx_codec_cx_pkt_t modified_pkt_; -}; - -TEST_P(DecodeCorruptedFrameTest, DecodeCorruptedFrame) { - cfg_.rc_target_bitrate = 200; - cfg_.g_error_resilient = 0; - - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 300); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -#if CONFIG_VP9 -INSTANTIATE_TEST_SUITE_P( - VP9, DecodeCorruptedFrameTest, - ::testing::Values( - static_cast(&libvpx_test::kVP9))); -#endif // CONFIG_VP9 - -#if CONFIG_VP8 -INSTANTIATE_TEST_SUITE_P( - VP8, DecodeCorruptedFrameTest, - ::testing::Values( - static_cast(&libvpx_test::kVP8))); -#endif // CONFIG_VP8 - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/decode_perf_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/decode_perf_test.cc deleted file mode 100644 index 8952b3a9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/decode_perf_test.cc +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "test/codec_factory.h" -#include "test/decode_test_driver.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/ivf_video_source.h" -#include "test/md5_helper.h" -#include "test/util.h" -#include "test/webm_video_source.h" -#include "vpx/vpx_codec.h" -#include "vpx_ports/vpx_timer.h" -#include "./ivfenc.h" - -using std::make_tuple; - -namespace { - -#define VIDEO_NAME 0 -#define THREADS 1 - -const double kUsecsInSec = 1000000.0; -const char kNewEncodeOutputFile[] = "new_encode.ivf"; - -/* - DecodePerfTest takes a tuple of filename + number of threads to decode with - */ -typedef std::tuple DecodePerfParam; - -const DecodePerfParam kVP9DecodePerfVectors[] = { - make_tuple("vp90-2-bbb_426x240_tile_1x1_180kbps.webm", 1), - make_tuple("vp90-2-bbb_640x360_tile_1x2_337kbps.webm", 2), - make_tuple("vp90-2-bbb_854x480_tile_1x2_651kbps.webm", 2), - make_tuple("vp90-2-bbb_1280x720_tile_1x4_1310kbps.webm", 4), - make_tuple("vp90-2-bbb_1920x1080_tile_1x1_2581kbps.webm", 1), - make_tuple("vp90-2-bbb_1920x1080_tile_1x4_2586kbps.webm", 4), - make_tuple("vp90-2-bbb_1920x1080_tile_1x4_fpm_2304kbps.webm", 4), - make_tuple("vp90-2-sintel_426x182_tile_1x1_171kbps.webm", 1), - make_tuple("vp90-2-sintel_640x272_tile_1x2_318kbps.webm", 2), - make_tuple("vp90-2-sintel_854x364_tile_1x2_621kbps.webm", 2), - make_tuple("vp90-2-sintel_1280x546_tile_1x4_1257kbps.webm", 4), - make_tuple("vp90-2-sintel_1920x818_tile_1x4_fpm_2279kbps.webm", 4), - make_tuple("vp90-2-tos_426x178_tile_1x1_181kbps.webm", 1), - make_tuple("vp90-2-tos_640x266_tile_1x2_336kbps.webm", 2), - make_tuple("vp90-2-tos_854x356_tile_1x2_656kbps.webm", 2), - make_tuple("vp90-2-tos_854x356_tile_1x2_fpm_546kbps.webm", 2), - make_tuple("vp90-2-tos_1280x534_tile_1x4_1306kbps.webm", 4), - make_tuple("vp90-2-tos_1280x534_tile_1x4_fpm_952kbps.webm", 4), - make_tuple("vp90-2-tos_1920x800_tile_1x4_fpm_2335kbps.webm", 4), -}; - -/* - In order to reflect real world performance as much as possible, Perf tests - *DO NOT* do any correctness checks. Please run them alongside correctness - tests to ensure proper codec integrity. Furthermore, in this test we - deliberately limit the amount of system calls we make to avoid OS - preemption. - - TODO(joshualitt) create a more detailed perf measurement test to collect - power/temp/min max frame decode times/etc - */ - -class DecodePerfTest : public ::testing::TestWithParam {}; - -TEST_P(DecodePerfTest, PerfTest) { - const char *const video_name = GET_PARAM(VIDEO_NAME); - const unsigned threads = GET_PARAM(THREADS); - - libvpx_test::WebMVideoSource video(video_name); - video.Init(); - - vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t(); - cfg.threads = threads; - libvpx_test::VP9Decoder decoder(cfg, 0); - - vpx_usec_timer t; - vpx_usec_timer_start(&t); - - for (video.Begin(); video.cxdata() != nullptr; video.Next()) { - decoder.DecodeFrame(video.cxdata(), video.frame_size()); - } - - vpx_usec_timer_mark(&t); - const double elapsed_secs = double(vpx_usec_timer_elapsed(&t)) / kUsecsInSec; - const unsigned frames = video.frame_number(); - const double fps = double(frames) / elapsed_secs; - - printf("{\n"); - printf("\t\"type\" : \"decode_perf_test\",\n"); - printf("\t\"version\" : \"%s\",\n", vpx_codec_version_str()); - printf("\t\"videoName\" : \"%s\",\n", video_name); - printf("\t\"threadCount\" : %u,\n", threads); - printf("\t\"decodeTimeSecs\" : %f,\n", elapsed_secs); - printf("\t\"totalFrames\" : %u,\n", frames); - printf("\t\"framesPerSecond\" : %f\n", fps); - printf("}\n"); -} - -INSTANTIATE_TEST_SUITE_P(VP9, DecodePerfTest, - ::testing::ValuesIn(kVP9DecodePerfVectors)); - -class VP9NewEncodeDecodePerfTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWithParam { - protected: - VP9NewEncodeDecodePerfTest() - : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)), speed_(0), - outfile_(nullptr), out_frames_(0) {} - - ~VP9NewEncodeDecodePerfTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(encoding_mode_); - - cfg_.g_lag_in_frames = 25; - cfg_.rc_min_quantizer = 2; - cfg_.rc_max_quantizer = 56; - cfg_.rc_dropframe_thresh = 0; - cfg_.rc_undershoot_pct = 50; - cfg_.rc_overshoot_pct = 50; - cfg_.rc_buf_sz = 1000; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 600; - cfg_.rc_resize_allowed = 0; - cfg_.rc_end_usage = VPX_VBR; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, speed_); - encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1); - encoder->Control(VP9E_SET_TILE_COLUMNS, 2); - } - } - - void BeginPassHook(unsigned int /*pass*/) override { - const std::string data_path = getenv("LIBVPX_TEST_DATA_PATH"); - const std::string path_to_source = data_path + "/" + kNewEncodeOutputFile; - outfile_ = fopen(path_to_source.c_str(), "wb"); - ASSERT_NE(outfile_, nullptr); - } - - void EndPassHook() override { - if (outfile_ != nullptr) { - if (!fseek(outfile_, 0, SEEK_SET)) { - ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_); - } - fclose(outfile_); - outfile_ = nullptr; - } - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - ++out_frames_; - - // Write initial file header if first frame. - if (pkt->data.frame.pts == 0) { - ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_); - } - - // Write frame header and data. - ivf_write_frame_header(outfile_, out_frames_, pkt->data.frame.sz); - ASSERT_EQ(fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz, outfile_), - pkt->data.frame.sz); - } - - bool DoDecode() const override { return false; } - - void set_speed(unsigned int speed) { speed_ = speed; } - - private: - libvpx_test::TestMode encoding_mode_; - uint32_t speed_; - FILE *outfile_; - uint32_t out_frames_; -}; - -struct EncodePerfTestVideo { - EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_, - uint32_t bitrate_, int frames_) - : name(name_), width(width_), height(height_), bitrate(bitrate_), - frames(frames_) {} - const char *name; - uint32_t width; - uint32_t height; - uint32_t bitrate; - int frames; -}; - -const EncodePerfTestVideo kVP9EncodePerfTestVectors[] = { - EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470), -}; - -TEST_P(VP9NewEncodeDecodePerfTest, PerfTest) { - SetUp(); - - // TODO(JBB): Make this work by going through the set of given files. - const int i = 0; - const vpx_rational timebase = { 33333333, 1000000000 }; - cfg_.g_timebase = timebase; - cfg_.rc_target_bitrate = kVP9EncodePerfTestVectors[i].bitrate; - - init_flags_ = VPX_CODEC_USE_PSNR; - - const char *video_name = kVP9EncodePerfTestVectors[i].name; - libvpx_test::I420VideoSource video( - video_name, kVP9EncodePerfTestVectors[i].width, - kVP9EncodePerfTestVectors[i].height, timebase.den, timebase.num, 0, - kVP9EncodePerfTestVectors[i].frames); - set_speed(2); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - const uint32_t threads = 4; - - libvpx_test::IVFVideoSource decode_video(kNewEncodeOutputFile); - decode_video.Init(); - - vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t(); - cfg.threads = threads; - libvpx_test::VP9Decoder decoder(cfg, 0); - - vpx_usec_timer t; - vpx_usec_timer_start(&t); - - for (decode_video.Begin(); decode_video.cxdata() != nullptr; - decode_video.Next()) { - decoder.DecodeFrame(decode_video.cxdata(), decode_video.frame_size()); - } - - vpx_usec_timer_mark(&t); - const double elapsed_secs = - static_cast(vpx_usec_timer_elapsed(&t)) / kUsecsInSec; - const unsigned decode_frames = decode_video.frame_number(); - const double fps = static_cast(decode_frames) / elapsed_secs; - - printf("{\n"); - printf("\t\"type\" : \"decode_perf_test\",\n"); - printf("\t\"version\" : \"%s\",\n", vpx_codec_version_str()); - printf("\t\"videoName\" : \"%s\",\n", kNewEncodeOutputFile); - printf("\t\"threadCount\" : %u,\n", threads); - printf("\t\"decodeTimeSecs\" : %f,\n", elapsed_secs); - printf("\t\"totalFrames\" : %u,\n", decode_frames); - printf("\t\"framesPerSecond\" : %f\n", fps); - printf("}\n"); -} - -VP9_INSTANTIATE_TEST_SUITE(VP9NewEncodeDecodePerfTest, - ::testing::Values(::libvpx_test::kTwoPassGood)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/decode_svc_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/decode_svc_test.cc deleted file mode 100644 index 7098e7b2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/decode_svc_test.cc +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "test/codec_factory.h" -#include "test/decode_test_driver.h" -#include "test/ivf_video_source.h" -#include "test/test_vectors.h" -#include "test/util.h" - -namespace { - -const unsigned int kNumFrames = 19; - -class DecodeSvcTest : public ::libvpx_test::DecoderTest, - public ::libvpx_test::CodecTestWithParam { - protected: - DecodeSvcTest() : DecoderTest(GET_PARAM(::libvpx_test::kCodecFactoryParam)) {} - ~DecodeSvcTest() override = default; - - void PreDecodeFrameHook(const libvpx_test::CompressedVideoSource &video, - libvpx_test::Decoder *decoder) override { - if (video.frame_number() == 0) - decoder->Control(VP9_DECODE_SVC_SPATIAL_LAYER, spatial_layer_); - } - - void DecompressedFrameHook(const vpx_image_t &img, - const unsigned int frame_number) override { - ASSERT_EQ(img.d_w, width_); - ASSERT_EQ(img.d_h, height_); - total_frames_ = frame_number; - } - - int spatial_layer_; - unsigned int width_; - unsigned int height_; - unsigned int total_frames_; -}; - -// SVC test vector is 1280x720, with 3 spatial layers, and 20 frames. - -// Decode the SVC test vector, which has 3 spatial layers, and decode up to -// spatial layer 0. Verify the resolution of each decoded frame and the total -// number of frames decoded. This results in 1/4x1/4 resolution (320x180). -TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer0) { - const std::string filename = GET_PARAM(1); - std::unique_ptr video; - video.reset(new libvpx_test::IVFVideoSource(filename)); - ASSERT_NE(video.get(), nullptr); - video->Init(); - total_frames_ = 0; - spatial_layer_ = 0; - width_ = 320; - height_ = 180; - ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); - ASSERT_EQ(total_frames_, kNumFrames); -} - -// Decode the SVC test vector, which has 3 spatial layers, and decode up to -// spatial layer 1. Verify the resolution of each decoded frame and the total -// number of frames decoded. This results in 1/2x1/2 resolution (640x360). -TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer1) { - const std::string filename = GET_PARAM(1); - std::unique_ptr video; - video.reset(new libvpx_test::IVFVideoSource(filename)); - ASSERT_NE(video.get(), nullptr); - video->Init(); - total_frames_ = 0; - spatial_layer_ = 1; - width_ = 640; - height_ = 360; - ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); - ASSERT_EQ(total_frames_, kNumFrames); -} - -// Decode the SVC test vector, which has 3 spatial layers, and decode up to -// spatial layer 2. Verify the resolution of each decoded frame and the total -// number of frames decoded. This results in the full resolution (1280x720). -TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer2) { - const std::string filename = GET_PARAM(1); - std::unique_ptr video; - video.reset(new libvpx_test::IVFVideoSource(filename)); - ASSERT_NE(video.get(), nullptr); - video->Init(); - total_frames_ = 0; - spatial_layer_ = 2; - width_ = 1280; - height_ = 720; - ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); - ASSERT_EQ(total_frames_, kNumFrames); -} - -// Decode the SVC test vector, which has 3 spatial layers, and decode up to -// spatial layer 10. Verify the resolution of each decoded frame and the total -// number of frames decoded. This is beyond the number of spatial layers, so -// the decoding should result in the full resolution (1280x720). -TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer10) { - const std::string filename = GET_PARAM(1); - std::unique_ptr video; - video.reset(new libvpx_test::IVFVideoSource(filename)); - ASSERT_NE(video.get(), nullptr); - video->Init(); - total_frames_ = 0; - spatial_layer_ = 10; - width_ = 1280; - height_ = 720; - ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); - ASSERT_EQ(total_frames_, kNumFrames); -} - -VP9_INSTANTIATE_TEST_SUITE( - DecodeSvcTest, ::testing::ValuesIn(libvpx_test::kVP9TestVectorsSvc, - libvpx_test::kVP9TestVectorsSvc + - libvpx_test::kNumVP9TestVectorsSvc)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/decode_test_driver.cc b/presentation/src/main/cpp/third_party/libvpx/test/decode_test_driver.cc deleted file mode 100644 index 794e367e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/decode_test_driver.cc +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "gtest/gtest.h" - -#include "test/codec_factory.h" -#include "test/decode_test_driver.h" -#include "test/register_state_check.h" -#include "test/video_source.h" - -namespace libvpx_test { - -const char kVP8Name[] = "WebM Project VP8"; - -vpx_codec_err_t Decoder::PeekStream(const uint8_t *cxdata, size_t size, - vpx_codec_stream_info_t *stream_info) { - return vpx_codec_peek_stream_info( - CodecInterface(), cxdata, static_cast(size), stream_info); -} - -vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size) { - return DecodeFrame(cxdata, size, nullptr); -} - -vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size, - void *user_priv) { - vpx_codec_err_t res_dec; - InitOnce(); - API_REGISTER_STATE_CHECK( - res_dec = vpx_codec_decode( - &decoder_, cxdata, static_cast(size), user_priv, 0)); - return res_dec; -} - -bool Decoder::IsVP8() const { - const char *codec_name = GetDecoderName(); - return strncmp(kVP8Name, codec_name, sizeof(kVP8Name) - 1) == 0; -} - -void DecoderTest::HandlePeekResult(Decoder *const decoder, - CompressedVideoSource *video, - const vpx_codec_err_t res_peek) { - const bool is_vp8 = decoder->IsVP8(); - if (is_vp8) { - /* Vp8's implementation of PeekStream returns an error if the frame you - * pass it is not a keyframe, so we only expect VPX_CODEC_OK on the first - * frame, which must be a keyframe. */ - if (video->frame_number() == 0) { - ASSERT_EQ(VPX_CODEC_OK, res_peek) - << "Peek return failed: " << vpx_codec_err_to_string(res_peek); - } - } else { - /* The Vp9 implementation of PeekStream returns an error only if the - * data passed to it isn't a valid Vp9 chunk. */ - ASSERT_EQ(VPX_CODEC_OK, res_peek) - << "Peek return failed: " << vpx_codec_err_to_string(res_peek); - } -} - -void DecoderTest::RunLoop(CompressedVideoSource *video, - const vpx_codec_dec_cfg_t &dec_cfg) { - Decoder *const decoder = codec_->CreateDecoder(dec_cfg, flags_); - ASSERT_NE(decoder, nullptr); - bool end_of_file = false; - - // Decode frames. - for (video->Begin(); !::testing::Test::HasFailure() && !end_of_file; - video->Next()) { - PreDecodeFrameHook(*video, decoder); - - vpx_codec_stream_info_t stream_info; - stream_info.sz = sizeof(stream_info); - - if (video->cxdata() != nullptr) { - const vpx_codec_err_t res_peek = decoder->PeekStream( - video->cxdata(), video->frame_size(), &stream_info); - HandlePeekResult(decoder, video, res_peek); - ASSERT_FALSE(::testing::Test::HasFailure()); - - vpx_codec_err_t res_dec = - decoder->DecodeFrame(video->cxdata(), video->frame_size()); - if (!HandleDecodeResult(res_dec, *video, decoder)) break; - } else { - // Signal end of the file to the decoder. - const vpx_codec_err_t res_dec = decoder->DecodeFrame(nullptr, 0); - ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError(); - end_of_file = true; - } - - DxDataIterator dec_iter = decoder->GetDxData(); - const vpx_image_t *img = nullptr; - - // Get decompressed data - while (!::testing::Test::HasFailure() && (img = dec_iter.Next())) { - DecompressedFrameHook(*img, video->frame_number()); - } - } - delete decoder; -} - -void DecoderTest::RunLoop(CompressedVideoSource *video) { - vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t(); - RunLoop(video, dec_cfg); -} - -void DecoderTest::set_cfg(const vpx_codec_dec_cfg_t &dec_cfg) { - memcpy(&cfg_, &dec_cfg, sizeof(cfg_)); -} - -void DecoderTest::set_flags(const vpx_codec_flags_t flags) { flags_ = flags; } - -} // namespace libvpx_test diff --git a/presentation/src/main/cpp/third_party/libvpx/test/decode_test_driver.h b/presentation/src/main/cpp/third_party/libvpx/test/decode_test_driver.h deleted file mode 100644 index 81f5001e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/decode_test_driver.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_TEST_DECODE_TEST_DRIVER_H_ -#define VPX_TEST_DECODE_TEST_DRIVER_H_ -#include -#include "gtest/gtest.h" -#include "./vpx_config.h" -#include "vpx/vpx_decoder.h" - -namespace libvpx_test { - -class CodecFactory; -class CompressedVideoSource; - -// Provides an object to handle decoding output -class DxDataIterator { - public: - explicit DxDataIterator(vpx_codec_ctx_t *decoder) - : decoder_(decoder), iter_(nullptr) {} - - const vpx_image_t *Next() { return vpx_codec_get_frame(decoder_, &iter_); } - - private: - vpx_codec_ctx_t *decoder_; - vpx_codec_iter_t iter_; -}; - -// Provides a simplified interface to manage one video decoding. -// Similar to Encoder class, the exact services should be added -// as more tests are added. -class Decoder { - public: - explicit Decoder(vpx_codec_dec_cfg_t cfg) - : cfg_(cfg), flags_(0), init_done_(false) { - memset(&decoder_, 0, sizeof(decoder_)); - } - - Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag) - : cfg_(cfg), flags_(flag), init_done_(false) { - memset(&decoder_, 0, sizeof(decoder_)); - } - - virtual ~Decoder() { vpx_codec_destroy(&decoder_); } - - vpx_codec_err_t PeekStream(const uint8_t *cxdata, size_t size, - vpx_codec_stream_info_t *stream_info); - - vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size); - - vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size, - void *user_priv); - - DxDataIterator GetDxData() { return DxDataIterator(&decoder_); } - - void Control(int ctrl_id, int arg) { Control(ctrl_id, arg, VPX_CODEC_OK); } - - void Control(int ctrl_id, const void *arg) { - InitOnce(); - const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg); - ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); - } - - void Control(int ctrl_id, int arg, vpx_codec_err_t expected_value) { - InitOnce(); - const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg); - ASSERT_EQ(expected_value, res) << DecodeError(); - } - - const char *DecodeError() { - const char *detail = vpx_codec_error_detail(&decoder_); - return detail ? detail : vpx_codec_error(&decoder_); - } - - // Passes the external frame buffer information to libvpx. - vpx_codec_err_t SetFrameBufferFunctions( - vpx_get_frame_buffer_cb_fn_t cb_get, - vpx_release_frame_buffer_cb_fn_t cb_release, void *user_priv) { - InitOnce(); - return vpx_codec_set_frame_buffer_functions(&decoder_, cb_get, cb_release, - user_priv); - } - - const char *GetDecoderName() const { - return vpx_codec_iface_name(CodecInterface()); - } - - bool IsVP8() const; - - vpx_codec_ctx_t *GetDecoder() { return &decoder_; } - - protected: - virtual vpx_codec_iface_t *CodecInterface() const = 0; - - void InitOnce() { - if (!init_done_) { - const vpx_codec_err_t res = - vpx_codec_dec_init(&decoder_, CodecInterface(), &cfg_, flags_); - ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); - init_done_ = true; - } - } - - vpx_codec_ctx_t decoder_; - vpx_codec_dec_cfg_t cfg_; - vpx_codec_flags_t flags_; - bool init_done_; -}; - -// Common test functionality for all Decoder tests. -class DecoderTest { - public: - // Main decoding loop - virtual void RunLoop(CompressedVideoSource *video); - virtual void RunLoop(CompressedVideoSource *video, - const vpx_codec_dec_cfg_t &dec_cfg); - - virtual void set_cfg(const vpx_codec_dec_cfg_t &dec_cfg); - virtual void set_flags(const vpx_codec_flags_t flags); - - // Hook to be called before decompressing every frame. - virtual void PreDecodeFrameHook(const CompressedVideoSource & /*video*/, - Decoder * /*decoder*/) {} - - // Hook to be called to handle decode result. Return true to continue. - virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec, - const CompressedVideoSource & /*video*/, - Decoder *decoder) { - EXPECT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError(); - return VPX_CODEC_OK == res_dec; - } - - // Hook to be called on every decompressed frame. - virtual void DecompressedFrameHook(const vpx_image_t & /*img*/, - const unsigned int /*frame_number*/) {} - - // Hook to be called on peek result - virtual void HandlePeekResult(Decoder *const decoder, - CompressedVideoSource *video, - const vpx_codec_err_t res_peek); - - protected: - explicit DecoderTest(const CodecFactory *codec) - : codec_(codec), cfg_(), flags_(0) {} - - virtual ~DecoderTest() {} - - const CodecFactory *codec_; - vpx_codec_dec_cfg_t cfg_; - vpx_codec_flags_t flags_; -}; - -} // namespace libvpx_test - -#endif // VPX_TEST_DECODE_TEST_DRIVER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/decode_to_md5.sh b/presentation/src/main/cpp/third_party/libvpx/test/decode_to_md5.sh deleted file mode 100644 index 15eee39f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/decode_to_md5.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2014 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## This file tests the libvpx decode_to_md5 example. To add new tests to this -## file, do the following: -## 1. Write a shell function (this is your test). -## 2. Add the function to decode_to_md5_tests (on a new line). -## -. $(dirname $0)/tools_common.sh - -# Environment check: Make sure input is available: -# $VP8_IVF_FILE and $VP9_IVF_FILE are required. -decode_to_md5_verify_environment() { - if [ ! -e "${VP8_IVF_FILE}" ] || [ ! -e "${VP9_IVF_FILE}" ]; then - echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH." - return 1 - fi -} - -# Runs decode_to_md5 on $1 and captures the md5 sum for the final frame. $2 is -# interpreted as codec name and used solely to name the output file. $3 is the -# expected md5 sum: It must match that of the final frame. -decode_to_md5() { - local decoder="${LIBVPX_BIN_PATH}/decode_to_md5${VPX_TEST_EXE_SUFFIX}" - local input_file="$1" - local codec="$2" - local expected_md5="$3" - local output_file="${VPX_TEST_OUTPUT_DIR}/decode_to_md5_${codec}" - - if [ ! -x "${decoder}" ]; then - elog "${decoder} does not exist or is not executable." - return 1 - fi - - eval "${VPX_TEST_PREFIX}" "${decoder}" "${input_file}" "${output_file}" \ - ${devnull} || return 1 - - [ -e "${output_file}" ] || return 1 - - local md5_last_frame="$(tail -n1 "${output_file}" | awk '{print $1}')" - local actual_md5="$(echo "${md5_last_frame}" | awk '{print $1}')" - [ "${actual_md5}" = "${expected_md5}" ] || return 1 -} - -decode_to_md5_vp8() { - # expected MD5 sum for the last frame. - local expected_md5="56794d911b02190212bca92f88ad60c6" - - if [ "$(vp8_decode_available)" = "yes" ]; then - decode_to_md5 "${VP8_IVF_FILE}" "vp8" "${expected_md5}" - fi -} - -decode_to_md5_vp9() { - # expected MD5 sum for the last frame. - local expected_md5="2952c0eae93f3dadd1aa84c50d3fd6d2" - - if [ "$(vp9_decode_available)" = "yes" ]; then - decode_to_md5 "${VP9_IVF_FILE}" "vp9" "${expected_md5}" - fi -} - -decode_to_md5_tests="decode_to_md5_vp8 - decode_to_md5_vp9" - -run_tests decode_to_md5_verify_environment "${decode_to_md5_tests}" diff --git a/presentation/src/main/cpp/third_party/libvpx/test/decode_with_drops.sh b/presentation/src/main/cpp/third_party/libvpx/test/decode_with_drops.sh deleted file mode 100644 index 2c826045..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/decode_with_drops.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2014 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## This file tests the libvpx decode_with_drops example. To add new tests to -## this file, do the following: -## 1. Write a shell function (this is your test). -## 2. Add the function to decode_with_drops_tests (on a new line). -## -. $(dirname $0)/tools_common.sh - -# Environment check: Make sure input is available: -# $VP8_IVF_FILE and $VP9_IVF_FILE are required. -decode_with_drops_verify_environment() { - if [ ! -e "${VP8_IVF_FILE}" ] || [ ! -e "${VP9_IVF_FILE}" ]; then - echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH." - return 1 - fi -} - -# Runs decode_with_drops on $1, $2 is interpreted as codec name and used solely -# to name the output file. $3 is the drop mode, and is passed directly to -# decode_with_drops. -decode_with_drops() { - local decoder="${LIBVPX_BIN_PATH}/decode_with_drops${VPX_TEST_EXE_SUFFIX}" - local input_file="$1" - local codec="$2" - local output_file="${VPX_TEST_OUTPUT_DIR}/decode_with_drops_${codec}" - local drop_mode="$3" - - if [ ! -x "${decoder}" ]; then - elog "${decoder} does not exist or is not executable." - return 1 - fi - - eval "${VPX_TEST_PREFIX}" "${decoder}" "${input_file}" "${output_file}" \ - "${drop_mode}" ${devnull} || return 1 - - [ -e "${output_file}" ] || return 1 -} - -# Decodes $VP8_IVF_FILE while dropping frames, twice: once in sequence mode, -# and once in pattern mode. -# Note: This test assumes that $VP8_IVF_FILE has exactly 29 frames, and could -# break if the file is modified. -decode_with_drops_vp8() { - if [ "$(vp8_decode_available)" = "yes" ]; then - # Test sequence mode: Drop frames 2-28. - decode_with_drops "${VP8_IVF_FILE}" "vp8" "2-28" || return 1 - - # Test pattern mode: Drop 3 of every 4 frames. - decode_with_drops "${VP8_IVF_FILE}" "vp8" "3/4" || return 1 - fi -} - -# Decodes $VP9_IVF_FILE while dropping frames, twice: once in sequence mode, -# and once in pattern mode. -# Note: This test assumes that $VP9_IVF_FILE has exactly 20 frames, and could -# break if the file is modified. -decode_with_drops_vp9() { - if [ "$(vp9_decode_available)" = "yes" ]; then - # Test sequence mode: Drop frames 2-28. - decode_with_drops "${VP9_IVF_FILE}" "vp9" "2-19" || return 1 - - # Test pattern mode: Drop 3 of every 4 frames. - decode_with_drops "${VP9_IVF_FILE}" "vp9" "3/4" || return 1 - fi -} - -decode_with_drops_tests="decode_with_drops_vp8 - decode_with_drops_vp9" - -run_tests decode_with_drops_verify_environment "${decode_with_drops_tests}" diff --git a/presentation/src/main/cpp/third_party/libvpx/test/encode_api_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/encode_api_test.cc deleted file mode 100644 index 05d31e67..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/encode_api_test.cc +++ /dev/null @@ -1,1927 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gtest/gtest.h" -#include "test/acm_random.h" -#include "test/video_source.h" -#include "test/y4m_video_source.h" - -#include "./vpx_config.h" -#include "vpx/vp8cx.h" -#include "vpx/vpx_codec.h" -#include "vpx/vpx_encoder.h" -#include "vpx/vpx_image.h" - -namespace { - -vpx_codec_iface_t *kCodecIfaces[] = { -#if CONFIG_VP8_ENCODER - &vpx_codec_vp8_cx_algo, -#endif -#if CONFIG_VP9_ENCODER - &vpx_codec_vp9_cx_algo, -#endif -}; - -bool IsVP9(vpx_codec_iface_t *iface) { - static const char kVP9Name[] = "WebM Project VP9"; - return strncmp(kVP9Name, vpx_codec_iface_name(iface), sizeof(kVP9Name) - 1) == - 0; -} - -void *Memset16(void *dest, int val, size_t length) { - uint16_t *dest16 = reinterpret_cast(dest); - for (size_t i = 0; i < length; i++) { - *dest16++ = val; - } - return dest; -} - -vpx_image_t *CreateImage(vpx_bit_depth_t bit_depth, vpx_img_fmt_t fmt, - unsigned int width, unsigned int height) { - assert(fmt != VPX_IMG_FMT_NV12); - if (bit_depth > VPX_BITS_8) { - fmt = static_cast(fmt | VPX_IMG_FMT_HIGHBITDEPTH); - } - vpx_image_t *image = vpx_img_alloc(nullptr, fmt, width, height, 1); - if (!image) return image; - - const int val = 1 << (bit_depth - 1); - const unsigned int uv_h = - (image->d_h + image->y_chroma_shift) >> image->y_chroma_shift; - const unsigned int uv_w = - (image->d_w + image->x_chroma_shift) >> image->x_chroma_shift; - if (bit_depth > VPX_BITS_8) { - for (unsigned int i = 0; i < image->d_h; ++i) { - Memset16(image->planes[0] + i * image->stride[0], val, image->d_w); - } - for (unsigned int i = 0; i < uv_h; ++i) { - Memset16(image->planes[1] + i * image->stride[1], val, uv_w); - Memset16(image->planes[2] + i * image->stride[2], val, uv_w); - } - } else { - for (unsigned int i = 0; i < image->d_h; ++i) { - memset(image->planes[0] + i * image->stride[0], val, image->d_w); - } - for (unsigned int i = 0; i < uv_h; ++i) { - memset(image->planes[1] + i * image->stride[1], val, uv_w); - memset(image->planes[2] + i * image->stride[2], val, uv_w); - } - } - - return image; -} - -void InitCodec(vpx_codec_iface_t &iface, int width, int height, - vpx_codec_ctx_t *enc, vpx_codec_enc_cfg_t *cfg) { - cfg->g_w = width; - cfg->g_h = height; - cfg->g_lag_in_frames = 0; - cfg->g_pass = VPX_RC_ONE_PASS; - ASSERT_EQ(vpx_codec_enc_init(enc, &iface, cfg, 0), VPX_CODEC_OK); - - ASSERT_EQ(vpx_codec_control_(enc, VP8E_SET_CPUUSED, 2), VPX_CODEC_OK); -} - -// Encodes 1 frame of size |cfg.g_w| x |cfg.g_h| setting |enc|'s configuration -// to |cfg|. -void EncodeWithConfig(const vpx_codec_enc_cfg_t &cfg, vpx_codec_ctx_t *enc) { - libvpx_test::DummyVideoSource video; - video.SetSize(cfg.g_w, cfg.g_h); - video.Begin(); - EXPECT_EQ(vpx_codec_enc_config_set(enc, &cfg), VPX_CODEC_OK) - << vpx_codec_error_detail(enc); - - EXPECT_EQ(vpx_codec_encode(enc, video.img(), video.pts(), video.duration(), - /*flags=*/0, VPX_DL_GOOD_QUALITY), - VPX_CODEC_OK) - << vpx_codec_error_detail(enc); -} - -TEST(EncodeAPI, InvalidParams) { - uint8_t buf[1] = { 0 }; - vpx_image_t img; - vpx_codec_ctx_t enc; - vpx_codec_enc_cfg_t cfg; - - EXPECT_EQ(&img, vpx_img_wrap(&img, VPX_IMG_FMT_I420, 1, 1, 1, buf)); - - EXPECT_EQ(VPX_CODEC_INVALID_PARAM, - vpx_codec_enc_init(nullptr, nullptr, nullptr, 0)); - EXPECT_EQ(VPX_CODEC_INVALID_PARAM, - vpx_codec_enc_init(&enc, nullptr, nullptr, 0)); - EXPECT_EQ(VPX_CODEC_INVALID_PARAM, - vpx_codec_encode(nullptr, nullptr, 0, 0, 0, 0)); - EXPECT_EQ(VPX_CODEC_INVALID_PARAM, - vpx_codec_encode(nullptr, &img, 0, 0, 0, 0)); - EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_destroy(nullptr)); - EXPECT_EQ(VPX_CODEC_INVALID_PARAM, - vpx_codec_enc_config_default(nullptr, nullptr, 0)); - EXPECT_EQ(VPX_CODEC_INVALID_PARAM, - vpx_codec_enc_config_default(nullptr, &cfg, 0)); - EXPECT_NE(vpx_codec_error(nullptr), nullptr); - - for (const auto *iface : kCodecIfaces) { - SCOPED_TRACE(vpx_codec_iface_name(iface)); - EXPECT_EQ(VPX_CODEC_INVALID_PARAM, - vpx_codec_enc_init(nullptr, iface, nullptr, 0)); - EXPECT_EQ(VPX_CODEC_INVALID_PARAM, - vpx_codec_enc_init(&enc, iface, nullptr, 0)); - EXPECT_EQ(VPX_CODEC_INVALID_PARAM, - vpx_codec_enc_config_default(iface, &cfg, 1)); - - EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_config_default(iface, &cfg, 0)); - EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_init(&enc, iface, &cfg, 0)); - EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, nullptr, 0, 0, 0, 0)); - - EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&enc)); - } -} - -TEST(EncodeAPI, HighBitDepthCapability) { -// VP8 should not claim VP9 HBD as a capability. -#if CONFIG_VP8_ENCODER - const vpx_codec_caps_t vp8_caps = vpx_codec_get_caps(&vpx_codec_vp8_cx_algo); - EXPECT_EQ(vp8_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0); -#endif - -#if CONFIG_VP9_ENCODER - const vpx_codec_caps_t vp9_caps = vpx_codec_get_caps(&vpx_codec_vp9_cx_algo); -#if CONFIG_VP9_HIGHBITDEPTH - EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, VPX_CODEC_CAP_HIGHBITDEPTH); -#else - EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0); -#endif -#endif -} - -#if CONFIG_VP8_ENCODER -TEST(EncodeAPI, ImageSizeSetting) { - const int width = 711; - const int height = 360; - const int bps = 12; - vpx_image_t img; - vpx_codec_ctx_t enc; - vpx_codec_enc_cfg_t cfg; - uint8_t *img_buf = reinterpret_cast( - calloc(width * height * bps / 8, sizeof(*img_buf))); - vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &cfg, 0); - - cfg.g_w = width; - cfg.g_h = height; - - vpx_img_wrap(&img, VPX_IMG_FMT_I420, width, height, 1, img_buf); - - vpx_codec_enc_init(&enc, vpx_codec_vp8_cx(), &cfg, 0); - - EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, &img, 0, 1, 0, 0)); - - free(img_buf); - - vpx_codec_destroy(&enc); -} - -// Verifies the fix for a float-cast-overflow in vp8_change_config(). -// -// Causes cpi->framerate to become the largest possible value (10,000,000) in -// VP8 by setting cfg.g_timebase to 1/10000000 and passing a duration of 1 to -// vpx_codec_encode(). -TEST(EncodeAPI, HugeFramerateVp8) { - vpx_codec_iface_t *const iface = vpx_codec_vp8_cx(); - vpx_codec_enc_cfg_t cfg; - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); - cfg.g_w = 271; - cfg.g_h = 1080; - cfg.g_timebase.num = 1; - // Largest value (VP8's TICKS_PER_SEC) such that frame duration is nonzero (1 - // tick). - cfg.g_timebase.den = 10000000; - cfg.g_pass = VPX_RC_ONE_PASS; - cfg.g_lag_in_frames = 0; - cfg.rc_end_usage = VPX_CBR; - - vpx_codec_ctx_t enc; - // Before we encode the first frame, cpi->framerate is set to a guess (the - // reciprocal of cfg.g_timebase). If this guess doesn't seem reasonable - // (> 180), cpi->framerate is set to 30. - ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK); - - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_CPUUSED, -12), VPX_CODEC_OK); - - vpx_image_t *const image = - vpx_img_alloc(nullptr, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h, 1); - ASSERT_NE(image, nullptr); - - for (unsigned int i = 0; i < image->d_h; ++i) { - memset(image->planes[0] + i * image->stride[0], 128, image->d_w); - } - const unsigned int uv_h = (image->d_h + 1) / 2; - const unsigned int uv_w = (image->d_w + 1) / 2; - for (unsigned int i = 0; i < uv_h; ++i) { - memset(image->planes[1] + i * image->stride[1], 128, uv_w); - memset(image->planes[2] + i * image->stride[2], 128, uv_w); - } - - // Encode a frame. - // Up to this point cpi->framerate is 30. Now pass a duration of only 1. This - // causes cpi->framerate to become 10,000,000. - ASSERT_EQ(vpx_codec_encode(&enc, image, 0, 1, 0, VPX_DL_REALTIME), - VPX_CODEC_OK); - - // Change to the same config. Since cpi->framerate is now huge, when it is - // used to calculate raw_target_rate (bit rate of uncompressed frames), the - // result is likely to overflow an unsigned int. - ASSERT_EQ(vpx_codec_enc_config_set(&enc, &cfg), VPX_CODEC_OK); - - vpx_img_free(image); - ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK); -} - -// A test that reproduces https://crbug.com/webm/1831. -TEST(EncodeAPI, RandomPixelsVp8) { - // Initialize libvpx encoder - vpx_codec_iface_t *const iface = vpx_codec_vp8_cx(); - vpx_codec_enc_cfg_t cfg; - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); - - cfg.rc_target_bitrate = 2000; - cfg.g_w = 1280; - cfg.g_h = 720; - - vpx_codec_ctx_t enc; - ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK); - - // Generate random frame data and encode - libvpx_test::RandomVideoSource video; - video.SetSize(cfg.g_w, cfg.g_h); - video.SetImageFormat(VPX_IMG_FMT_I420); - video.Begin(); - ASSERT_EQ(vpx_codec_encode(&enc, video.img(), video.pts(), video.duration(), - /*flags=*/0, VPX_DL_BEST_QUALITY), - VPX_CODEC_OK); - - // Destroy libvpx encoder - vpx_codec_destroy(&enc); -} - -TEST(EncodeAPI, ChangeToL1T3AndSetBitrateVp8) { - // Initialize libvpx encoder - vpx_codec_iface_t *const iface = vpx_codec_vp8_cx(); - vpx_codec_enc_cfg_t cfg; - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); - - cfg.g_threads = 1; - cfg.g_profile = 0; - cfg.g_w = 1; - cfg.g_h = 64; - cfg.g_bit_depth = VPX_BITS_8; - cfg.g_input_bit_depth = 8; - cfg.g_timebase.num = 1; - cfg.g_timebase.den = 1000000; - cfg.g_pass = VPX_RC_ONE_PASS; - cfg.g_lag_in_frames = 0; - cfg.rc_dropframe_thresh = 0; // Don't drop frames - cfg.rc_resize_allowed = 0; - cfg.rc_end_usage = VPX_VBR; - cfg.rc_target_bitrate = 10; - cfg.rc_min_quantizer = 2; - cfg.rc_max_quantizer = 58; - cfg.kf_mode = VPX_KF_AUTO; - cfg.kf_min_dist = 0; - cfg.kf_max_dist = 10000; - - vpx_codec_ctx_t enc; - ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK); - - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_CPUUSED, -6), VPX_CODEC_OK); - - // Generate random frame data and encode - uint8_t img[1 * 64 * 3 / 2]; - libvpx_test::ACMRandom rng; - for (size_t i = 0; i < sizeof(img); ++i) { - img[i] = rng.Rand8(); - } - vpx_image_t img_wrapper; - ASSERT_EQ( - vpx_img_wrap(&img_wrapper, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h, 1, img), - &img_wrapper); - vpx_enc_frame_flags_t flags = VPX_EFLAG_FORCE_KF; - ASSERT_EQ( - vpx_codec_encode(&enc, &img_wrapper, 0, 500000, flags, VPX_DL_REALTIME), - VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_encode(&enc, nullptr, -1, 0, 0, 0), VPX_CODEC_OK); - - cfg.rc_target_bitrate = 4294967; - // Set the scalability mode to L1T3. - cfg.ts_number_layers = 3; - cfg.ts_periodicity = 4; - cfg.ts_layer_id[0] = 0; - cfg.ts_layer_id[1] = 2; - cfg.ts_layer_id[2] = 1; - cfg.ts_layer_id[3] = 2; - cfg.ts_rate_decimator[0] = 4; - cfg.ts_rate_decimator[1] = 2; - cfg.ts_rate_decimator[2] = 1; - // Bitrate allocation L0: 50% L1: 20% L2: 30% - cfg.layer_target_bitrate[0] = cfg.ts_target_bitrate[0] = - 50 * cfg.rc_target_bitrate / 100; - cfg.layer_target_bitrate[1] = cfg.ts_target_bitrate[1] = - 70 * cfg.rc_target_bitrate / 100; - cfg.layer_target_bitrate[2] = cfg.ts_target_bitrate[2] = - cfg.rc_target_bitrate; - cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_0212; - cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT; - ASSERT_EQ(vpx_codec_enc_config_set(&enc, &cfg), VPX_CODEC_OK); - - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_TEMPORAL_LAYER_ID, 2), - VPX_CODEC_OK); - - constexpr vpx_enc_frame_flags_t VP8_UPDATE_NOTHING = - VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST; - // Layer 2: only reference last frame, no updates - // It only depends on layer 0 - flags = VP8_UPDATE_NOTHING | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_GF; - ASSERT_EQ( - vpx_codec_encode(&enc, &img_wrapper, 0, 500000, flags, VPX_DL_REALTIME), - VPX_CODEC_OK); - - // Destroy libvpx encoder - vpx_codec_destroy(&enc); -} - -// Emulates the WebCodecs VideoEncoder interface. -class VP8Encoder { - public: - explicit VP8Encoder(int speed) : speed_(speed) {} - ~VP8Encoder(); - - void Configure(unsigned int threads, unsigned int width, unsigned int height, - vpx_rc_mode end_usage, vpx_enc_deadline_t deadline); - void Encode(bool key_frame); - - private: - const int speed_; - bool initialized_ = false; - vpx_codec_enc_cfg_t cfg_; - vpx_codec_ctx_t enc_; - int frame_index_ = 0; - vpx_enc_deadline_t deadline_ = 0; -}; - -VP8Encoder::~VP8Encoder() { - if (initialized_) { - EXPECT_EQ(vpx_codec_destroy(&enc_), VPX_CODEC_OK); - } -} - -void VP8Encoder::Configure(unsigned int threads, unsigned int width, - unsigned int height, vpx_rc_mode end_usage, - vpx_enc_deadline_t deadline) { - deadline_ = deadline; - - if (!initialized_) { - vpx_codec_iface_t *const iface = vpx_codec_vp8_cx(); - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg_, /*usage=*/0), - VPX_CODEC_OK); - cfg_.g_threads = threads; - cfg_.g_w = width; - cfg_.g_h = height; - cfg_.g_timebase.num = 1; - cfg_.g_timebase.den = 1000 * 1000; // microseconds - cfg_.g_pass = VPX_RC_ONE_PASS; - cfg_.g_lag_in_frames = 0; - cfg_.rc_end_usage = end_usage; - cfg_.rc_min_quantizer = 2; - cfg_.rc_max_quantizer = 58; - ASSERT_EQ(vpx_codec_enc_init(&enc_, iface, &cfg_, 0), VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc_, VP8E_SET_CPUUSED, speed_), VPX_CODEC_OK); - initialized_ = true; - return; - } - - cfg_.g_threads = threads; - cfg_.g_w = width; - cfg_.g_h = height; - cfg_.rc_end_usage = end_usage; - ASSERT_EQ(vpx_codec_enc_config_set(&enc_, &cfg_), VPX_CODEC_OK) - << vpx_codec_error_detail(&enc_); -} - -void VP8Encoder::Encode(bool key_frame) { - assert(initialized_); - const vpx_codec_cx_pkt_t *pkt; - vpx_image_t *image = - CreateImage(VPX_BITS_8, VPX_IMG_FMT_I420, cfg_.g_w, cfg_.g_h); - ASSERT_NE(image, nullptr); - const vpx_enc_frame_flags_t flags = key_frame ? VPX_EFLAG_FORCE_KF : 0; - ASSERT_EQ(vpx_codec_encode(&enc_, image, frame_index_, 1, flags, deadline_), - VPX_CODEC_OK); - ++frame_index_; - vpx_codec_iter_t iter = nullptr; - while ((pkt = vpx_codec_get_cx_data(&enc_, &iter)) != nullptr) { - ASSERT_EQ(pkt->kind, VPX_CODEC_CX_FRAME_PKT); - if (key_frame) { - ASSERT_EQ(pkt->data.frame.flags & VPX_FRAME_IS_KEY, VPX_FRAME_IS_KEY); - } - } - vpx_img_free(image); -} - -// This is the reproducer testcase for crbug.com/324459561. However, -// just running this test is not enough to reproduce the bug. We also -// need to send signals to the test. -TEST(EncodeAPI, Chromium324459561) { - VP8Encoder encoder(-12); - - encoder.Configure(11, 1685, 652, VPX_CBR, VPX_DL_REALTIME); - - encoder.Encode(true); - encoder.Encode(true); - encoder.Encode(true); - - encoder.Configure(0, 1685, 1, VPX_VBR, VPX_DL_REALTIME); -} - -TEST(EncodeAPI, VP8GlobalHeaders) { - constexpr int kWidth = 320; - constexpr int kHeight = 240; - - vpx_codec_enc_cfg_t cfg = {}; - struct Encoder { - ~Encoder() { EXPECT_EQ(vpx_codec_destroy(&ctx), VPX_CODEC_OK); } - vpx_codec_ctx_t ctx = {}; - } enc; - - ASSERT_EQ(vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &cfg, 0), - VPX_CODEC_OK); - ASSERT_NO_FATAL_FAILURE( - InitCodec(*vpx_codec_vp8_cx(), kWidth, kHeight, &enc.ctx, &cfg)); - EXPECT_EQ(vpx_codec_get_global_headers(&enc.ctx), nullptr); - EXPECT_NO_FATAL_FAILURE(EncodeWithConfig(cfg, &enc.ctx)); - EXPECT_EQ(vpx_codec_get_global_headers(&enc.ctx), nullptr); -} - -TEST(EncodeAPI, AomediaIssue3509VbrMinSection2PercentVP8) { - // Initialize libvpx encoder. - vpx_codec_iface_t *const iface = vpx_codec_vp8_cx(); - vpx_codec_ctx_t enc; - vpx_codec_enc_cfg_t cfg; - - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); - - cfg.g_w = 1920; - cfg.g_h = 1080; - cfg.g_lag_in_frames = 0; - cfg.rc_target_bitrate = 1000000; - // Set this to more than 1 percent to cause a signed integer overflow in the - // multiplication cpi->av_per_frame_bandwidth * - // cpi->oxcf.two_pass_vbrmin_section in vp8_new_framerate() if the - // multiplication is done in the `int` type. - cfg.rc_2pass_vbr_minsection_pct = 2; - - ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK); - - // Create input image. - vpx_image_t *const image = - CreateImage(VPX_BITS_8, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h); - ASSERT_NE(image, nullptr); - - // Encode frame. - // `duration` can go as high as 300, but the UBSan error is gone if - // `duration` is 301 or higher. - ASSERT_EQ( - vpx_codec_encode(&enc, image, 0, /*duration=*/300, 0, VPX_DL_REALTIME), - VPX_CODEC_OK); - - // Free resources. - vpx_img_free(image); - ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK); -} - -TEST(EncodeAPI, AomediaIssue3509VbrMinSection101PercentVP8) { - // Initialize libvpx encoder. - vpx_codec_iface_t *const iface = vpx_codec_vp8_cx(); - vpx_codec_ctx_t enc; - vpx_codec_enc_cfg_t cfg; - - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); - - cfg.g_w = 1920; - cfg.g_h = 1080; - cfg.g_lag_in_frames = 0; - cfg.rc_target_bitrate = 1000000; - // Set this to more than 100 percent to cause an error when vbr_min_bits is - // cast to `int` in vp8_new_framerate() if vbr_min_bits is not clamped to - // INT_MAX. - cfg.rc_2pass_vbr_minsection_pct = 101; - - ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK); - - // Create input image. - vpx_image_t *const image = - CreateImage(VPX_BITS_8, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h); - ASSERT_NE(image, nullptr); - - // Encode frame. - // `duration` can go as high as 300, but the UBSan error is gone if - // `duration` is 301 or higher. - ASSERT_EQ( - vpx_codec_encode(&enc, image, 0, /*duration=*/300, 0, VPX_DL_REALTIME), - VPX_CODEC_OK); - - // Free resources. - vpx_img_free(image); - ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK); -} - -TEST(EncodeAPI, OssFuzz69100) { - // Initialize libvpx encoder. - vpx_codec_iface_t *const iface = vpx_codec_vp8_cx(); - vpx_codec_ctx_t enc; - vpx_codec_enc_cfg_t cfg; - - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); - - cfg.g_w = 64; - cfg.g_h = 64; - cfg.g_lag_in_frames = 25; - cfg.g_timebase.num = 1; - cfg.g_timebase.den = 6240592; - cfg.rc_target_bitrate = 1202607620; - cfg.kf_max_dist = 24377; - - ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK); - - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_CPUUSED, 1), VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_ARNR_MAXFRAMES, 0), VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_ARNR_STRENGTH, 3), VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control_(&enc, VP8E_SET_ARNR_TYPE, 3), - VPX_CODEC_OK); // deprecated - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_NOISE_SENSITIVITY, 0), - VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_TOKEN_PARTITIONS, 0), - VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_STATIC_THRESHOLD, 0), - VPX_CODEC_OK); - - libvpx_test::RandomVideoSource video; - video.set_limit(30); - video.SetSize(cfg.g_w, cfg.g_h); - video.SetImageFormat(VPX_IMG_FMT_I420); - video.Begin(); - do { - ASSERT_EQ(vpx_codec_encode(&enc, video.img(), video.pts(), video.duration(), - /*flags=*/0, VPX_DL_GOOD_QUALITY), - VPX_CODEC_OK); - video.Next(); - } while (video.img() != nullptr); - - ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK); -} - -void EncodeOssFuzz69906(int cpu_used, vpx_enc_deadline_t deadline) { - char str[80]; - snprintf(str, sizeof(str), "cpu_used: %d deadline: %d", cpu_used, - static_cast(deadline)); - SCOPED_TRACE(str); - - // Initialize libvpx encoder. - vpx_codec_iface_t *const iface = vpx_codec_vp8_cx(); - vpx_codec_ctx_t enc; - vpx_codec_enc_cfg_t cfg; - - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); - - cfg.g_w = 4097; - cfg.g_h = 16; - cfg.rc_target_bitrate = 1237084865; - cfg.kf_max_dist = 4336; - - ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK); - - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_CPUUSED, cpu_used), VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_ARNR_MAXFRAMES, 0), VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_ARNR_STRENGTH, 3), VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control_(&enc, VP8E_SET_ARNR_TYPE, 3), - VPX_CODEC_OK); // deprecated - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_NOISE_SENSITIVITY, 0), - VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_TOKEN_PARTITIONS, 0), - VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_STATIC_THRESHOLD, 0), - VPX_CODEC_OK); - - libvpx_test::Y4mVideoSource video("repro-oss-fuzz-69906.y4m", /*start=*/0, - /*limit=*/3); - video.Begin(); - do { - ASSERT_EQ(vpx_codec_encode(&enc, video.img(), video.pts(), video.duration(), - /*flags=*/0, deadline), - VPX_CODEC_OK); - video.Next(); - } while (video.img() != nullptr); - - ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK); -} - -TEST(EncodeAPI, OssFuzz69906) { - // Note the original bug report was for speed 1, good quality. The remainder - // of the settings are for added coverage. - for (int cpu_used = 0; cpu_used <= 5; ++cpu_used) { - EncodeOssFuzz69906(cpu_used, VPX_DL_GOOD_QUALITY); - } - - for (int cpu_used = -16; cpu_used <= -5; ++cpu_used) { - EncodeOssFuzz69906(cpu_used, VPX_DL_REALTIME); - } -} -#endif // CONFIG_VP8_ENCODER - -// Set up 2 spatial streams with 2 temporal layers per stream, and generate -// invalid configuration by setting the temporal layer rate allocation -// (ts_target_bitrate[]) to 0 for both layers. This should fail independent of -// CONFIG_MULTI_RES_ENCODING. -TEST(EncodeAPI, MultiResEncode) { - const int width = 1280; - const int height = 720; - const int width_down = width / 2; - const int height_down = height / 2; - const int target_bitrate = 1000; - const int framerate = 30; - - for (const auto *iface : kCodecIfaces) { - vpx_codec_ctx_t enc[2]; - vpx_codec_enc_cfg_t cfg[2]; - vpx_rational_t dsf[2] = { { 2, 1 }, { 2, 1 } }; - - memset(enc, 0, sizeof(enc)); - - for (int i = 0; i < 2; i++) { - vpx_codec_enc_config_default(iface, &cfg[i], 0); - } - - /* Highest-resolution encoder settings */ - cfg[0].g_w = width; - cfg[0].g_h = height; - cfg[0].rc_dropframe_thresh = 0; - cfg[0].rc_end_usage = VPX_CBR; - cfg[0].rc_resize_allowed = 0; - cfg[0].rc_min_quantizer = 2; - cfg[0].rc_max_quantizer = 56; - cfg[0].rc_undershoot_pct = 100; - cfg[0].rc_overshoot_pct = 15; - cfg[0].rc_buf_initial_sz = 500; - cfg[0].rc_buf_optimal_sz = 600; - cfg[0].rc_buf_sz = 1000; - cfg[0].g_error_resilient = 1; /* Enable error resilient mode */ - cfg[0].g_lag_in_frames = 0; - - cfg[0].kf_mode = VPX_KF_AUTO; - cfg[0].kf_min_dist = 3000; - cfg[0].kf_max_dist = 3000; - - cfg[0].rc_target_bitrate = target_bitrate; /* Set target bitrate */ - cfg[0].g_timebase.num = 1; /* Set fps */ - cfg[0].g_timebase.den = framerate; - - memcpy(&cfg[1], &cfg[0], sizeof(cfg[0])); - cfg[1].rc_target_bitrate = 500; - cfg[1].g_w = width_down; - cfg[1].g_h = height_down; - - for (int i = 0; i < 2; i++) { - cfg[i].ts_number_layers = 2; - cfg[i].ts_periodicity = 2; - cfg[i].ts_rate_decimator[0] = 2; - cfg[i].ts_rate_decimator[1] = 1; - cfg[i].ts_layer_id[0] = 0; - cfg[i].ts_layer_id[1] = 1; - // Invalid parameters. - cfg[i].ts_target_bitrate[0] = 0; - cfg[i].ts_target_bitrate[1] = 0; - } - - // VP9 should report incapable, VP8 invalid for all configurations. - EXPECT_EQ(IsVP9(iface) ? VPX_CODEC_INCAPABLE : VPX_CODEC_INVALID_PARAM, - vpx_codec_enc_init_multi(&enc[0], iface, &cfg[0], 2, 0, &dsf[0])); - - for (int i = 0; i < 2; i++) { - vpx_codec_destroy(&enc[i]); - } - } -} - -TEST(EncodeAPI, SetRoi) { - static struct { - vpx_codec_iface_t *iface; - int ctrl_id; - } kCodecs[] = { -#if CONFIG_VP8_ENCODER - { &vpx_codec_vp8_cx_algo, VP8E_SET_ROI_MAP }, -#endif -#if CONFIG_VP9_ENCODER - { &vpx_codec_vp9_cx_algo, VP9E_SET_ROI_MAP }, -#endif - }; - constexpr int kWidth = 64; - constexpr int kHeight = 64; - - for (const auto &codec : kCodecs) { - SCOPED_TRACE(vpx_codec_iface_name(codec.iface)); - vpx_codec_ctx_t enc; - vpx_codec_enc_cfg_t cfg; - - EXPECT_EQ(vpx_codec_enc_config_default(codec.iface, &cfg, 0), VPX_CODEC_OK); - cfg.g_w = kWidth; - cfg.g_h = kHeight; - EXPECT_EQ(vpx_codec_enc_init(&enc, codec.iface, &cfg, 0), VPX_CODEC_OK); - - vpx_roi_map_t roi = {}; - uint8_t roi_map[kWidth * kHeight] = {}; - if (IsVP9(codec.iface)) { - roi.rows = (cfg.g_w + 7) >> 3; - roi.cols = (cfg.g_h + 7) >> 3; - } else { - roi.rows = (cfg.g_w + 15) >> 4; - roi.cols = (cfg.g_h + 15) >> 4; - } - EXPECT_EQ(vpx_codec_control_(&enc, codec.ctrl_id, &roi), VPX_CODEC_OK); - - roi.roi_map = roi_map; - // VP8 only. This value isn't range checked. - roi.static_threshold[1] = 1000; - roi.static_threshold[2] = UINT_MAX / 2 + 1; - roi.static_threshold[3] = UINT_MAX; - - for (const auto delta : { -63, -1, 0, 1, 63 }) { - for (int i = 0; i < 8; ++i) { - roi.delta_q[i] = delta; - roi.delta_lf[i] = delta; - // VP9 only. - roi.skip[i] ^= 1; - roi.ref_frame[i] = (roi.ref_frame[i] + 1) % 4; - EXPECT_EQ(vpx_codec_control_(&enc, codec.ctrl_id, &roi), VPX_CODEC_OK); - } - } - - vpx_codec_err_t expected_error; - for (const auto delta : { -64, 64, INT_MIN, INT_MAX }) { - expected_error = VPX_CODEC_INVALID_PARAM; - for (int i = 0; i < 8; ++i) { - roi.delta_q[i] = delta; - // The max segment count for VP8 is 4, the remainder of the entries are - // ignored. - if (i >= 4 && !IsVP9(codec.iface)) expected_error = VPX_CODEC_OK; - - EXPECT_EQ(vpx_codec_control_(&enc, codec.ctrl_id, &roi), expected_error) - << "delta_q[" << i << "]: " << delta; - roi.delta_q[i] = 0; - - roi.delta_lf[i] = delta; - EXPECT_EQ(vpx_codec_control_(&enc, codec.ctrl_id, &roi), expected_error) - << "delta_lf[" << i << "]: " << delta; - roi.delta_lf[i] = 0; - } - } - - // VP8 should ignore skip[] and ref_frame[] values. - expected_error = - IsVP9(codec.iface) ? VPX_CODEC_INVALID_PARAM : VPX_CODEC_OK; - for (const auto skip : { -2, 2, INT_MIN, INT_MAX }) { - for (int i = 0; i < 8; ++i) { - roi.skip[i] = skip; - EXPECT_EQ(vpx_codec_control_(&enc, codec.ctrl_id, &roi), expected_error) - << "skip[" << i << "]: " << skip; - roi.skip[i] = 0; - } - } - - // VP9 allows negative values to be used to disable segmentation. - for (int ref_frame = -3; ref_frame < 0; ++ref_frame) { - for (int i = 0; i < 8; ++i) { - roi.ref_frame[i] = ref_frame; - EXPECT_EQ(vpx_codec_control_(&enc, codec.ctrl_id, &roi), VPX_CODEC_OK) - << "ref_frame[" << i << "]: " << ref_frame; - roi.ref_frame[i] = 0; - } - } - - for (const auto ref_frame : { 4, INT_MIN, INT_MAX }) { - for (int i = 0; i < 8; ++i) { - roi.ref_frame[i] = ref_frame; - EXPECT_EQ(vpx_codec_control_(&enc, codec.ctrl_id, &roi), expected_error) - << "ref_frame[" << i << "]: " << ref_frame; - roi.ref_frame[i] = 0; - } - } - - EXPECT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK); - } -} - -TEST(EncodeAPI, ConfigChangeThreadCount) { - constexpr int kWidth = 1920; - constexpr int kHeight = 1080; - - for (const auto *iface : kCodecIfaces) { - SCOPED_TRACE(vpx_codec_iface_name(iface)); - for (int i = 0; i < (IsVP9(iface) ? 2 : 1); ++i) { - vpx_codec_enc_cfg_t cfg = {}; - struct Encoder { - ~Encoder() { EXPECT_EQ(vpx_codec_destroy(&ctx), VPX_CODEC_OK); } - vpx_codec_ctx_t ctx = {}; - } enc; - - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); - EXPECT_NO_FATAL_FAILURE( - InitCodec(*iface, kWidth, kHeight, &enc.ctx, &cfg)); - if (IsVP9(iface)) { - EXPECT_EQ(vpx_codec_control_(&enc.ctx, VP9E_SET_TILE_COLUMNS, 6), - VPX_CODEC_OK); - EXPECT_EQ(vpx_codec_control_(&enc.ctx, VP9E_SET_ROW_MT, i), - VPX_CODEC_OK); - } - - for (const auto threads : { 1, 4, 8, 6, 2, 1 }) { - cfg.g_threads = threads; - EXPECT_NO_FATAL_FAILURE(EncodeWithConfig(cfg, &enc.ctx)) - << "iteration: " << i << " threads: " << threads; - } - } - } -} - -TEST(EncodeAPI, ConfigResizeChangeThreadCount) { - constexpr int kInitWidth = 1024; - constexpr int kInitHeight = 1024; - - for (const auto *iface : kCodecIfaces) { - SCOPED_TRACE(vpx_codec_iface_name(iface)); - for (int i = 0; i < (IsVP9(iface) ? 2 : 1); ++i) { - vpx_codec_enc_cfg_t cfg = {}; - struct Encoder { - ~Encoder() { EXPECT_EQ(vpx_codec_destroy(&ctx), VPX_CODEC_OK); } - vpx_codec_ctx_t ctx = {}; - } enc; - - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); - // Start in threaded mode to ensure resolution and thread related - // allocations are updated correctly across changes in resolution and - // thread counts. See https://crbug.com/1486441. - cfg.g_threads = 4; - EXPECT_NO_FATAL_FAILURE( - InitCodec(*iface, kInitWidth, kInitHeight, &enc.ctx, &cfg)); - if (IsVP9(iface)) { - EXPECT_EQ(vpx_codec_control_(&enc.ctx, VP9E_SET_TILE_COLUMNS, 6), - VPX_CODEC_OK); - EXPECT_EQ(vpx_codec_control_(&enc.ctx, VP9E_SET_ROW_MT, i), - VPX_CODEC_OK); - } - - cfg.g_w = 1000; - cfg.g_h = 608; - EXPECT_EQ(vpx_codec_enc_config_set(&enc.ctx, &cfg), VPX_CODEC_OK) - << vpx_codec_error_detail(&enc.ctx); - - cfg.g_w = 1000; - cfg.g_h = 720; - - for (const auto threads : { 1, 4, 8, 6, 2, 1 }) { - cfg.g_threads = threads; - EXPECT_NO_FATAL_FAILURE(EncodeWithConfig(cfg, &enc.ctx)) - << "iteration: " << i << " threads: " << threads; - } - } - } -} - -TEST(EncodeAPI, ConfigResizeBiggerAfterInit) { - for (const auto *iface : kCodecIfaces) { - SCOPED_TRACE(vpx_codec_iface_name(iface)); - vpx_codec_enc_cfg_t cfg; - vpx_codec_ctx_t enc; - - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); - EXPECT_NO_FATAL_FAILURE(InitCodec(*iface, 1, 1, &enc, &cfg)); - - cfg.g_w = 1920; - cfg.g_h = 1; - EXPECT_EQ(vpx_codec_enc_config_set(&enc, &cfg), - IsVP9(iface) ? VPX_CODEC_OK : VPX_CODEC_INVALID_PARAM); - - EXPECT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK); - } -} - -TEST(EncodeAPI, ConfigResizeBiggerAfterEncode) { - for (const auto *iface : kCodecIfaces) { - SCOPED_TRACE(vpx_codec_iface_name(iface)); - vpx_codec_enc_cfg_t cfg; - vpx_codec_ctx_t enc; - - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); - EXPECT_NO_FATAL_FAILURE(InitCodec(*iface, 1, 1, &enc, &cfg)); - EXPECT_NO_FATAL_FAILURE(EncodeWithConfig(cfg, &enc)); - - cfg.g_w = 1920; - cfg.g_h = 1; - EXPECT_EQ(vpx_codec_enc_config_set(&enc, &cfg), - IsVP9(iface) ? VPX_CODEC_OK : VPX_CODEC_INVALID_PARAM); - - cfg.g_w = 1920; - cfg.g_h = 1080; - EXPECT_EQ(vpx_codec_enc_config_set(&enc, &cfg), - IsVP9(iface) ? VPX_CODEC_OK : VPX_CODEC_INVALID_PARAM); - - EXPECT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK); - } -} - -TEST(EncodeAPI, PtsSmallerThanInitialPts) { - for (const auto *iface : kCodecIfaces) { - // Initialize libvpx encoder. - vpx_codec_ctx_t enc; - vpx_codec_enc_cfg_t cfg; - - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); - - ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK); - - // Create input image. - vpx_image_t *const image = - CreateImage(VPX_BITS_8, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h); - ASSERT_NE(image, nullptr); - - // Encode frame. - ASSERT_EQ(vpx_codec_encode(&enc, image, 12, 1, 0, VPX_DL_BEST_QUALITY), - VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_encode(&enc, image, 13, 1, 0, VPX_DL_BEST_QUALITY), - VPX_CODEC_OK); - // pts (10) is smaller than the initial pts (12). - ASSERT_EQ(vpx_codec_encode(&enc, image, 10, 1, 0, VPX_DL_BEST_QUALITY), - VPX_CODEC_INVALID_PARAM); - - // Free resources. - vpx_img_free(image); - ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK); - } -} - -TEST(EncodeAPI, PtsOrDurationTooBig) { - for (const auto *iface : kCodecIfaces) { - // Initialize libvpx encoder. - vpx_codec_ctx_t enc; - vpx_codec_enc_cfg_t cfg; - - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); - - ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK); - - // Create input image. - vpx_image_t *const image = - CreateImage(VPX_BITS_8, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h); - ASSERT_NE(image, nullptr); - - // Encode frame. - ASSERT_EQ(vpx_codec_encode(&enc, image, 0, 1, 0, VPX_DL_BEST_QUALITY), - VPX_CODEC_OK); -#if ULONG_MAX > INT64_MAX - // duration is too big. - ASSERT_EQ(vpx_codec_encode(&enc, image, 0, (1ul << 63), 0, 2), - VPX_CODEC_INVALID_PARAM); -#endif - // pts, when converted to ticks, is too big. - ASSERT_EQ(vpx_codec_encode(&enc, image, INT64_MAX / 1000000 + 1, 1, 0, - VPX_DL_BEST_QUALITY), - VPX_CODEC_INVALID_PARAM); -#if ULONG_MAX > INT64_MAX - // duration is too big. - ASSERT_EQ( - vpx_codec_encode(&enc, image, 0, (1ul << 63), 0, VPX_DL_BEST_QUALITY), - VPX_CODEC_INVALID_PARAM); - // pts + duration is too big. - ASSERT_EQ( - vpx_codec_encode(&enc, image, 1, INT64_MAX, 0, VPX_DL_BEST_QUALITY), - VPX_CODEC_INVALID_PARAM); -#endif - // pts + duration, when converted to ticks, is too big. -#if ULONG_MAX > INT64_MAX - ASSERT_EQ(vpx_codec_encode(&enc, image, 0, 0xbd6b566b15c7, 0, - VPX_DL_BEST_QUALITY), - VPX_CODEC_INVALID_PARAM); -#endif - ASSERT_EQ(vpx_codec_encode(&enc, image, INT64_MAX / 1000000, 1, 0, - VPX_DL_BEST_QUALITY), - VPX_CODEC_INVALID_PARAM); - - // Free resources. - vpx_img_free(image); - ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK); - } -} - -#if CONFIG_VP9_ENCODER -// Frame size needed to trigger the overflow exceeds the max buffer allowed on -// 32-bit systems defined by VPX_MAX_ALLOCABLE_MEMORY -#if VPX_ARCH_X86_64 || VPX_ARCH_AARCH64 -TEST(EncodeAPI, ConfigLargeTargetBitrateVp9) { -#ifdef CHROMIUM - GTEST_SKIP() << "Under Chromium's configuration the allocator is unable" - "to provide the space required for the frames below."; -#else - constexpr int kWidth = 12383; - constexpr int kHeight = 8192; - constexpr auto *iface = &vpx_codec_vp9_cx_algo; - SCOPED_TRACE(vpx_codec_iface_name(iface)); - vpx_codec_enc_cfg_t cfg = {}; - struct Encoder { - ~Encoder() { EXPECT_EQ(vpx_codec_destroy(&ctx), VPX_CODEC_OK); } - vpx_codec_ctx_t ctx = {}; - } enc; - - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); - // The following setting will cause avg_frame_bandwidth in rate control to be - // larger than INT_MAX - cfg.rc_target_bitrate = INT_MAX; - // Framerate 0.1 (equivalent to timebase 10) is the smallest framerate allowed - // by libvpx - cfg.g_timebase.den = 1; - cfg.g_timebase.num = 10; - EXPECT_NO_FATAL_FAILURE(InitCodec(*iface, kWidth, kHeight, &enc.ctx, &cfg)) - << "target bitrate: " << cfg.rc_target_bitrate << " framerate: " - << static_cast(cfg.g_timebase.den) / cfg.g_timebase.num; -#endif // defined(CHROMIUM) -} -#endif // VPX_ARCH_X86_64 || VPX_ARCH_AARCH64 - -// Emulates the WebCodecs VideoEncoder interface. -class VP9Encoder { - public: - explicit VP9Encoder(int speed) - : speed_(speed), row_mt_(0), bit_depth_(VPX_BITS_8), - fmt_(VPX_IMG_FMT_I420) {} - // The image format `fmt` must not have the VPX_IMG_FMT_HIGHBITDEPTH bit set. - // If bit_depth > 8, we will set the VPX_IMG_FMT_HIGHBITDEPTH bit before - // passing the image format to vpx_img_alloc(). - VP9Encoder(int speed, unsigned int row_mt, vpx_bit_depth_t bit_depth, - vpx_img_fmt_t fmt) - : speed_(speed), row_mt_(row_mt), bit_depth_(bit_depth), fmt_(fmt) {} - ~VP9Encoder(); - - void Configure(unsigned int threads, unsigned int width, unsigned int height, - vpx_rc_mode end_usage, vpx_enc_deadline_t deadline); - void Encode(bool key_frame); - - private: - const int speed_; - const unsigned int row_mt_; - const vpx_bit_depth_t bit_depth_; - const vpx_img_fmt_t fmt_; - bool initialized_ = false; - vpx_codec_enc_cfg_t cfg_; - vpx_codec_ctx_t enc_; - int frame_index_ = 0; - vpx_enc_deadline_t deadline_ = 0; -}; - -VP9Encoder::~VP9Encoder() { - if (initialized_) { - EXPECT_EQ(vpx_codec_destroy(&enc_), VPX_CODEC_OK); - } -} - -void VP9Encoder::Configure(unsigned int threads, unsigned int width, - unsigned int height, vpx_rc_mode end_usage, - vpx_enc_deadline_t deadline) { - deadline_ = deadline; - - if (!initialized_) { - ASSERT_EQ(fmt_ & VPX_IMG_FMT_HIGHBITDEPTH, 0); - const bool high_bit_depth = bit_depth_ > VPX_BITS_8; - const bool is_420 = fmt_ == VPX_IMG_FMT_I420; - vpx_codec_iface_t *const iface = vpx_codec_vp9_cx(); - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg_, /*usage=*/0), - VPX_CODEC_OK); - cfg_.g_threads = threads; - // In profiles 0 and 2, only 4:2:0 format is allowed. In profiles 1 and 3, - // all other subsampling formats are allowed. In profiles 0 and 1, only bit - // depth 8 is allowed. In profiles 2 and 3, only bit depths 10 and 12 are - // allowed. - cfg_.g_profile = 2 * high_bit_depth + !is_420; - cfg_.g_w = width; - cfg_.g_h = height; - cfg_.g_bit_depth = bit_depth_; - cfg_.g_input_bit_depth = bit_depth_; - cfg_.g_timebase.num = 1; - cfg_.g_timebase.den = 1000 * 1000; // microseconds - cfg_.g_pass = VPX_RC_ONE_PASS; - cfg_.g_lag_in_frames = 0; - cfg_.rc_end_usage = end_usage; - cfg_.rc_min_quantizer = 2; - cfg_.rc_max_quantizer = 58; - ASSERT_EQ( - vpx_codec_enc_init(&enc_, iface, &cfg_, - high_bit_depth ? VPX_CODEC_USE_HIGHBITDEPTH : 0), - VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc_, VP8E_SET_CPUUSED, speed_), VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc_, VP9E_SET_ROW_MT, row_mt_), VPX_CODEC_OK); - initialized_ = true; - return; - } - - cfg_.g_threads = threads; - cfg_.g_w = width; - cfg_.g_h = height; - cfg_.rc_end_usage = end_usage; - ASSERT_EQ(vpx_codec_enc_config_set(&enc_, &cfg_), VPX_CODEC_OK) - << vpx_codec_error_detail(&enc_); -} - -void VP9Encoder::Encode(bool key_frame) { - assert(initialized_); - const vpx_codec_cx_pkt_t *pkt; - vpx_image_t *image = CreateImage(bit_depth_, fmt_, cfg_.g_w, cfg_.g_h); - ASSERT_NE(image, nullptr); - const vpx_enc_frame_flags_t frame_flags = key_frame ? VPX_EFLAG_FORCE_KF : 0; - ASSERT_EQ( - vpx_codec_encode(&enc_, image, frame_index_, 1, frame_flags, deadline_), - VPX_CODEC_OK); - ++frame_index_; - vpx_codec_iter_t iter = nullptr; - while ((pkt = vpx_codec_get_cx_data(&enc_, &iter)) != nullptr) { - ASSERT_EQ(pkt->kind, VPX_CODEC_CX_FRAME_PKT); - } - vpx_img_free(image); -} - -// This is a test case from clusterfuzz. -TEST(EncodeAPI, PrevMiCheckNullptr) { - VP9Encoder encoder(0); - encoder.Configure(0, 1554, 644, VPX_VBR, VPX_DL_REALTIME); - - // First step: encode, without forcing KF. - encoder.Encode(false); - // Second step: change config - encoder.Configure(0, 1131, 644, VPX_CBR, VPX_DL_GOOD_QUALITY); - // Third step: encode, without forcing KF - encoder.Encode(false); -} - -// This is a test case from clusterfuzz: based on b/310477034. -// Encode a few frames with multiple change config calls -// with different frame sizes. -TEST(EncodeAPI, MultipleChangeConfigResize) { - VP9Encoder encoder(3); - - // Set initial config. - encoder.Configure(3, 41, 1, VPX_VBR, VPX_DL_REALTIME); - - // Encode first frame. - encoder.Encode(true); - - // Change config. - encoder.Configure(16, 31, 1, VPX_VBR, VPX_DL_GOOD_QUALITY); - - // Change config again. - encoder.Configure(0, 17, 1, VPX_CBR, VPX_DL_REALTIME); - - // Encode 2nd frame with new config, set delta frame. - encoder.Encode(false); - - // Encode 3rd frame with same config, set delta frame. - encoder.Encode(false); -} - -// This is a test case from clusterfuzz: based on b/310663186. -// Encode set of frames while varying the deadline on the fly from -// good to realtime to best and back to realtime. -TEST(EncodeAPI, DynamicDeadlineChange) { - // Use realtime speed: 5 to 9. - VP9Encoder encoder(5); - - // Set initial config, in particular set deadline to GOOD mode. - encoder.Configure(0, 1, 1, VPX_VBR, VPX_DL_GOOD_QUALITY); - - // Encode 1st frame. - encoder.Encode(true); - - // Encode 2nd frame, delta frame. - encoder.Encode(false); - - // Change config: change deadline to REALTIME. - encoder.Configure(0, 1, 1, VPX_VBR, VPX_DL_REALTIME); - - // Encode 3rd frame with new config, set key frame. - encoder.Encode(true); - - // Encode 4th frame with same config, delta frame. - encoder.Encode(false); - - // Encode 5th frame with same config, key frame. - encoder.Encode(true); - - // Change config: change deadline to BEST. - encoder.Configure(0, 1, 1, VPX_VBR, VPX_DL_BEST_QUALITY); - - // Encode 6th frame with new config, set delta frame. - encoder.Encode(false); - - // Change config: change deadline to REALTIME. - encoder.Configure(0, 1, 1, VPX_VBR, VPX_DL_REALTIME); - - // Encode 7th frame with new config, set delta frame. - encoder.Encode(false); - - // Encode 8th frame with new config, set key frame. - encoder.Encode(true); - - // Encode 9th frame with new config, set delta frame. - encoder.Encode(false); -} - -TEST(EncodeAPI, Buganizer310340241) { - VP9Encoder encoder(-6); - - // Set initial config, in particular set deadline to GOOD mode. - encoder.Configure(0, 1, 1, VPX_VBR, VPX_DL_GOOD_QUALITY); - - // Encode 1st frame. - encoder.Encode(true); - - // Encode 2nd frame, delta frame. - encoder.Encode(false); - - // Change config: change deadline to REALTIME. - encoder.Configure(0, 1, 1, VPX_VBR, VPX_DL_REALTIME); - - // Encode 3rd frame with new config, set key frame. - encoder.Encode(true); -} - -// This is a test case from clusterfuzz: based on b/312517065. -TEST(EncodeAPI, Buganizer312517065) { - VP9Encoder encoder(4); - encoder.Configure(0, 1060, 437, VPX_CBR, VPX_DL_REALTIME); - encoder.Encode(true); - encoder.Configure(10, 33, 437, VPX_VBR, VPX_DL_GOOD_QUALITY); - encoder.Encode(false); - encoder.Configure(6, 327, 269, VPX_VBR, VPX_DL_GOOD_QUALITY); - encoder.Configure(15, 1060, 437, VPX_CBR, VPX_DL_REALTIME); - encoder.Encode(false); -} - -// This is a test case from clusterfuzz: based on b/311489136. -// Encode a few frames with multiple change config calls -// with different frame sizes. -TEST(EncodeAPI, Buganizer311489136) { - VP9Encoder encoder(1); - - // Set initial config. - encoder.Configure(12, 1678, 620, VPX_VBR, VPX_DL_GOOD_QUALITY); - - // Encode first frame. - encoder.Encode(true); - - // Change config. - encoder.Configure(3, 1678, 202, VPX_CBR, VPX_DL_GOOD_QUALITY); - - // Encode 2nd frame with new config, set delta frame. - encoder.Encode(false); - - // Change config again. - encoder.Configure(8, 1037, 476, VPX_CBR, VPX_DL_REALTIME); - - // Encode 3rd frame with new config, set delta frame. - encoder.Encode(false); - - // Change config again. - encoder.Configure(0, 580, 620, VPX_CBR, VPX_DL_GOOD_QUALITY); - - // Encode 4th frame with same config, set delta frame. - encoder.Encode(false); -} - -// This is a test case from clusterfuzz: based on b/312656387. -// Encode a few frames with multiple change config calls -// with different frame sizes. -TEST(EncodeAPI, Buganizer312656387) { - VP9Encoder encoder(1); - - // Set initial config. - encoder.Configure(16, 1, 1024, VPX_CBR, VPX_DL_REALTIME); - - // Change config. - encoder.Configure(15, 1, 1024, VPX_VBR, VPX_DL_REALTIME); - - // Encode first frame. - encoder.Encode(true); - - // Change config again. - encoder.Configure(14, 1, 595, VPX_VBR, VPX_DL_GOOD_QUALITY); - - // Encode 2nd frame with new config. - encoder.Encode(true); - - // Change config again. - encoder.Configure(2, 1, 1024, VPX_VBR, VPX_DL_GOOD_QUALITY); - - // Encode 3rd frame with new config, set delta frame. - encoder.Encode(false); -} - -// This is a test case from clusterfuzz: based on b/310329177. -// Encode a few frames with multiple change config calls -// with different frame sizes. -TEST(EncodeAPI, Buganizer310329177) { - VP9Encoder encoder(6); - - // Set initial config. - encoder.Configure(10, 41, 1, VPX_VBR, VPX_DL_REALTIME); - - // Encode first frame. - encoder.Encode(true); - - // Change config. - encoder.Configure(16, 1, 1, VPX_VBR, VPX_DL_REALTIME); - - // Encode 2nd frame with new config, set delta frame. - encoder.Encode(false); -} - -// This is a test case from clusterfuzz: based on b/311394513. -// Encode a few frames with multiple change config calls -// with different frame sizes. -TEST(EncodeAPI, Buganizer311394513) { - VP9Encoder encoder(-7); - - // Set initial config. - encoder.Configure(0, 5, 9, VPX_VBR, VPX_DL_REALTIME); - - // Encode first frame. - encoder.Encode(false); - - // Change config. - encoder.Configure(5, 2, 1, VPX_VBR, VPX_DL_REALTIME); - - // Encode 2nd frame with new config. - encoder.Encode(true); -} - -TEST(EncodeAPI, Buganizer311985118) { - VP9Encoder encoder(0); - - // Set initial config, in particular set deadline to GOOD mode. - encoder.Configure(12, 1678, 620, VPX_VBR, VPX_DL_GOOD_QUALITY); - - // Encode 1st frame. - encoder.Encode(false); - - // Change config: change threads and width. - encoder.Configure(0, 1574, 620, VPX_VBR, VPX_DL_GOOD_QUALITY); - - // Change config: change threads, width and height. - encoder.Configure(16, 837, 432, VPX_VBR, VPX_DL_GOOD_QUALITY); - - // Encode 2nd frame. - encoder.Encode(false); -} - -// This is a test case from clusterfuzz: based on b/314857577. -// Encode a few frames with multiple change config calls -// with different frame sizes. -TEST(EncodeAPI, Buganizer314857577) { - VP9Encoder encoder(4); - - // Set initial config. - encoder.Configure(12, 1060, 437, VPX_VBR, VPX_DL_REALTIME); - - // Encode first frame. - encoder.Encode(false); - - // Change config. - encoder.Configure(16, 1060, 1, VPX_CBR, VPX_DL_REALTIME); - - // Encode 2nd frame with new config. - encoder.Encode(false); - - // Encode 3rd frame with new config. - encoder.Encode(true); - - // Change config. - encoder.Configure(15, 33, 437, VPX_VBR, VPX_DL_GOOD_QUALITY); - - // Encode 4th frame with new config. - encoder.Encode(true); - - // Encode 5th frame with new config. - encoder.Encode(false); - - // Change config. - encoder.Configure(5, 327, 269, VPX_VBR, VPX_DL_REALTIME); - - // Change config. - encoder.Configure(15, 1060, 437, VPX_CBR, VPX_DL_REALTIME); - - // Encode 6th frame with new config. - encoder.Encode(false); - - // Encode 7th frame with new config. - encoder.Encode(false); - - // Change config. - encoder.Configure(4, 1060, 437, VPX_VBR, VPX_DL_REALTIME); - - // Encode 8th frame with new config. - encoder.Encode(false); -} - -TEST(EncodeAPI, Buganizer312875957PredBufferStride) { - VP9Encoder encoder(-1); - - encoder.Configure(12, 1678, 620, VPX_VBR, VPX_DL_REALTIME); - encoder.Encode(true); - encoder.Encode(false); - encoder.Configure(0, 456, 486, VPX_VBR, VPX_DL_REALTIME); - encoder.Encode(true); - encoder.Configure(0, 1678, 620, VPX_CBR, 1000000); - encoder.Encode(false); - encoder.Encode(false); -} - -// This is a test case from clusterfuzz: based on b/311294795 -// Encode a few frames with multiple change config calls -// with different frame sizes. -TEST(EncodeAPI, Buganizer311294795) { - VP9Encoder encoder(1); - - // Set initial config. - encoder.Configure(12, 1678, 620, VPX_VBR, VPX_DL_REALTIME); - - // Encode first frame. - encoder.Encode(false); - - // Change config. - encoder.Configure(16, 632, 620, VPX_VBR, VPX_DL_GOOD_QUALITY); - - // Encode 2nd frame with new config - encoder.Encode(true); - - // Change config. - encoder.Configure(16, 1678, 342, VPX_VBR, VPX_DL_GOOD_QUALITY); - - // Encode 3rd frame with new config. - encoder.Encode(false); - - // Change config. - encoder.Configure(0, 1574, 618, VPX_VBR, VPX_DL_REALTIME); - // Encode more frames with new config. - encoder.Encode(false); - encoder.Encode(false); -} - -TEST(EncodeAPI, Buganizer317105128) { - VP9Encoder encoder(-9); - encoder.Configure(0, 1, 1, VPX_CBR, VPX_DL_GOOD_QUALITY); - encoder.Configure(16, 1920, 1, VPX_CBR, VPX_DL_REALTIME); -} - -TEST(EncodeAPI, Buganizer319964497) { - VP9Encoder encoder(7); - encoder.Configure(/*threads=*/1, /*width=*/320, /*height=*/240, VPX_VBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/true); - encoder.Encode(/*key_frame=*/true); - encoder.Encode(/*key_frame=*/false); - encoder.Configure(/*threads=*/1, /*width=*/1, /*height=*/1, VPX_VBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/false); - encoder.Configure(/*threads=*/1, /*width=*/2, /*height=*/2, VPX_CBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/false); -} - -TEST(EncodeAPI, Buganizer329088759RowMT0) { - VP9Encoder encoder(8, 0, VPX_BITS_8, VPX_IMG_FMT_I444); - encoder.Configure(/*threads=*/8, /*width=*/1686, /*height=*/398, VPX_VBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/true); - encoder.Encode(/*key_frame=*/false); - encoder.Configure(/*threads=*/0, /*width=*/1686, /*height=*/1, VPX_VBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/true); - encoder.Configure(/*threads=*/0, /*width=*/1482, /*height=*/113, VPX_CBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/true); - encoder.Configure(/*threads=*/0, /*width=*/881, /*height=*/59, VPX_CBR, - VPX_DL_REALTIME); - encoder.Configure(/*threads=*/13, /*width=*/1271, /*height=*/385, VPX_CBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/false); - encoder.Configure(/*threads=*/2, /*width=*/1, /*height=*/62, VPX_VBR, - VPX_DL_REALTIME); -} - -TEST(EncodeAPI, Buganizer329088759RowMT1) { - VP9Encoder encoder(8, 1, VPX_BITS_8, VPX_IMG_FMT_I444); - encoder.Configure(/*threads=*/8, /*width=*/1686, /*height=*/398, VPX_VBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/true); - encoder.Encode(/*key_frame=*/false); - // Needs to set threads to non-zero to repro the issue. - encoder.Configure(/*threads=*/2, /*width=*/1686, /*height=*/1, VPX_VBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/true); - encoder.Configure(/*threads=*/2, /*width=*/1482, /*height=*/113, VPX_CBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/true); - encoder.Configure(/*threads=*/2, /*width=*/881, /*height=*/59, VPX_CBR, - VPX_DL_REALTIME); - encoder.Configure(/*threads=*/13, /*width=*/1271, /*height=*/385, VPX_CBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/false); - encoder.Configure(/*threads=*/2, /*width=*/1, /*height=*/62, VPX_VBR, - VPX_DL_REALTIME); -} - -TEST(EncodeAPI, Buganizer331086799) { - VP9Encoder encoder(6, 1, VPX_BITS_8, VPX_IMG_FMT_I420); - encoder.Configure(0, 1385, 1, VPX_CBR, VPX_DL_REALTIME); - encoder.Configure(0, 1, 1, VPX_VBR, VPX_DL_REALTIME); - encoder.Encode(false); - encoder.Configure(16, 1385, 1, VPX_VBR, VPX_DL_GOOD_QUALITY); - encoder.Encode(false); - encoder.Encode(false); - encoder.Configure(0, 1, 1, VPX_CBR, VPX_DL_REALTIME); - encoder.Encode(true); -} - -TEST(EncodeAPI, Buganizer331108729) { - VP9Encoder encoder(1, 1, VPX_BITS_8, VPX_IMG_FMT_I422); - encoder.Configure(0, 1919, 260, VPX_VBR, VPX_DL_REALTIME); - encoder.Configure(9, 440, 1, VPX_CBR, VPX_DL_GOOD_QUALITY); - encoder.Encode(true); - encoder.Configure(8, 1919, 260, VPX_VBR, VPX_DL_REALTIME); - encoder.Encode(false); -} - -TEST(EncodeAPI, Buganizer331108922BitDepth8) { - VP9Encoder encoder(9, 1, VPX_BITS_8, VPX_IMG_FMT_I420); - encoder.Configure(/*threads=*/1, /*width=*/1, /*height=*/1080, VPX_VBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/false); - encoder.Configure(/*threads=*/0, /*width=*/1, /*height=*/1080, VPX_CBR, - VPX_DL_GOOD_QUALITY); - encoder.Configure(/*threads=*/16, /*width=*/1, /*height=*/394, VPX_CBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/false); - encoder.Encode(/*key_frame=*/true); - encoder.Configure(/*threads=*/16, /*width=*/1, /*height=*/798, VPX_CBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/false); -} - -#if CONFIG_VP9_HIGHBITDEPTH -TEST(EncodeAPI, Buganizer329674887RowMT0BitDepth12) { - VP9Encoder encoder(8, 0, VPX_BITS_12, VPX_IMG_FMT_I444); - encoder.Configure(/*threads=*/2, /*width=*/1030, /*height=*/583, VPX_VBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/true); - encoder.Configure(/*threads=*/0, /*width=*/1030, /*height=*/1, VPX_CBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/true); - encoder.Configure(/*threads=*/0, /*width=*/548, /*height=*/322, VPX_VBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/false); - encoder.Configure(/*threads=*/16, /*width=*/24, /*height=*/583, VPX_CBR, - VPX_DL_GOOD_QUALITY); -} - -TEST(EncodeAPI, Buganizer329179808RowMT0BitDepth10) { - VP9Encoder encoder(4, 0, VPX_BITS_10, VPX_IMG_FMT_I444); - encoder.Configure(/*threads=*/16, /*width=*/1488, /*height=*/5, VPX_VBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/true); - encoder.Configure(/*threads=*/16, /*width=*/839, /*height=*/1, VPX_CBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/false); - encoder.Configure(/*threads=*/11, /*width=*/657, /*height=*/5, VPX_CBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/false); -} - -TEST(EncodeAPI, Buganizer329179808RowMT1BitDepth10) { - VP9Encoder encoder(4, 1, VPX_BITS_10, VPX_IMG_FMT_I444); - encoder.Configure(/*threads=*/16, /*width=*/1488, /*height=*/5, VPX_VBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/true); - encoder.Configure(/*threads=*/16, /*width=*/839, /*height=*/1, VPX_CBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/false); - encoder.Configure(/*threads=*/11, /*width=*/657, /*height=*/5, VPX_CBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/false); -} - -TEST(EncodeAPI, Buganizer331108922BitDepth12) { - VP9Encoder encoder(9, 1, VPX_BITS_12, VPX_IMG_FMT_I444); - encoder.Configure(/*threads=*/1, /*width=*/1, /*height=*/1080, VPX_VBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/false); - encoder.Configure(/*threads=*/0, /*width=*/1, /*height=*/1080, VPX_CBR, - VPX_DL_GOOD_QUALITY); - encoder.Configure(/*threads=*/16, /*width=*/1, /*height=*/394, VPX_CBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/false); - encoder.Encode(/*key_frame=*/true); - encoder.Configure(/*threads=*/16, /*width=*/1, /*height=*/798, VPX_CBR, - VPX_DL_REALTIME); - encoder.Encode(/*key_frame=*/false); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -TEST(EncodeAPI, VP9GlobalHeaders) { - constexpr int kWidth = 320; - constexpr int kHeight = 240; - - libvpx_test::DummyVideoSource video; - video.SetSize(kWidth, kHeight); - -#if CONFIG_VP9_HIGHBITDEPTH - const int profiles[] = { 0, 1, 2, 3 }; -#else - const int profiles[] = { 0, 1 }; -#endif - char str[80]; - for (const int profile : profiles) { - std::vector bitdepths; - std::vector formats; - switch (profile) { - case 0: - bitdepths = { VPX_BITS_8 }; - formats = { VPX_IMG_FMT_I420 }; - break; - case 1: - bitdepths = { VPX_BITS_8 }; - formats = { VPX_IMG_FMT_I422, VPX_IMG_FMT_I444 }; - break; -#if CONFIG_VP9_HIGHBITDEPTH - case 2: - bitdepths = { VPX_BITS_10, VPX_BITS_12 }; - formats = { VPX_IMG_FMT_I42016 }; - break; - case 3: - bitdepths = { VPX_BITS_10, VPX_BITS_12 }; - formats = { VPX_IMG_FMT_I42216, VPX_IMG_FMT_I44416 }; - break; -#endif - } - - for (const auto format : formats) { - for (const auto bitdepth : bitdepths) { - snprintf(str, sizeof(str), "profile: %d bitdepth: %d format: %d", - profile, bitdepth, format); - SCOPED_TRACE(str); - - vpx_codec_enc_cfg_t cfg = {}; - struct Encoder { - ~Encoder() { EXPECT_EQ(vpx_codec_destroy(&ctx), VPX_CODEC_OK); } - vpx_codec_ctx_t ctx = {}; - } enc; - vpx_codec_ctx_t *const ctx = &enc.ctx; - - ASSERT_EQ(vpx_codec_enc_config_default(vpx_codec_vp9_cx(), &cfg, 0), - VPX_CODEC_OK); - cfg.g_w = kWidth; - cfg.g_h = kHeight; - cfg.g_lag_in_frames = 0; - cfg.g_pass = VPX_RC_ONE_PASS; - cfg.g_profile = profile; - cfg.g_bit_depth = bitdepth; - ASSERT_EQ( - vpx_codec_enc_init(ctx, vpx_codec_vp9_cx(), &cfg, - bitdepth == 8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH), - VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control_(ctx, VP8E_SET_CPUUSED, 2), VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control_(ctx, VP9E_SET_TARGET_LEVEL, 62), - VPX_CODEC_OK); - - vpx_fixed_buf_t *global_headers = vpx_codec_get_global_headers(ctx); - EXPECT_NE(global_headers, nullptr); - EXPECT_EQ(global_headers->sz, size_t{ 9 }); - - video.SetImageFormat(format); - video.Begin(); - EXPECT_EQ( - vpx_codec_encode(ctx, video.img(), video.pts(), video.duration(), - /*flags=*/0, VPX_DL_GOOD_QUALITY), - VPX_CODEC_OK) - << vpx_codec_error_detail(ctx); - - global_headers = vpx_codec_get_global_headers(ctx); - EXPECT_NE(global_headers, nullptr); - EXPECT_EQ(global_headers->sz, size_t{ 12 }); - uint8_t chroma_subsampling; - if ((format & VPX_IMG_FMT_I420) == VPX_IMG_FMT_I420) { - chroma_subsampling = 1; - } else if ((format & VPX_IMG_FMT_I422) == VPX_IMG_FMT_I422) { - chroma_subsampling = 2; - } else { // VPX_IMG_FMT_I444 - chroma_subsampling = 3; - } - const uint8_t expected_headers[] = { 1, - 1, - static_cast(profile), - 2, - 1, - /*level,*/ 3, - 1, - static_cast(bitdepth), - 4, - 1, - chroma_subsampling }; - const uint8_t *actual_headers = - reinterpret_cast(global_headers->buf); - for (int i = 0; i < 5; ++i) { - EXPECT_EQ(expected_headers[i], actual_headers[i]) << "index: " << i; - } - EXPECT_NE(actual_headers[6], 0); // level - for (int i = 5; i < 11; ++i) { - EXPECT_EQ(expected_headers[i], actual_headers[i + 1]) - << "index: " << i + 1; - } - } - } - } -} - -TEST(EncodeAPI, AomediaIssue3509VbrMinSection2PercentVP9) { - // Initialize libvpx encoder. - vpx_codec_iface_t *const iface = vpx_codec_vp9_cx(); - vpx_codec_ctx_t enc; - vpx_codec_enc_cfg_t cfg; - - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); - - cfg.g_w = 1920; - cfg.g_h = 1080; - cfg.g_lag_in_frames = 0; - cfg.rc_target_bitrate = 1000000; - // Set this to more than 1 percent to cause a signed integer overflow in the - // multiplication rc->avg_frame_bandwidth * oxcf->rc_cfg.vbrmin_section in - // vp9_rc_update_framerate() if the multiplication is done in the `int` type. - cfg.rc_2pass_vbr_minsection_pct = 2; - - ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK); - - // Create input image. - vpx_image_t *const image = - CreateImage(VPX_BITS_8, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h); - ASSERT_NE(image, nullptr); - - // Encode frame. - // `duration` can go as high as 300, but the UBSan error is gone if - // `duration` is 301 or higher. - ASSERT_EQ( - vpx_codec_encode(&enc, image, 0, /*duration=*/300, 0, VPX_DL_REALTIME), - VPX_CODEC_OK); - - // Free resources. - vpx_img_free(image); - ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK); -} - -TEST(EncodeAPI, AomediaIssue3509VbrMinSection101PercentVP9) { - // Initialize libvpx encoder. - vpx_codec_iface_t *const iface = vpx_codec_vp9_cx(); - vpx_codec_ctx_t enc; - vpx_codec_enc_cfg_t cfg; - - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); - - cfg.g_w = 1920; - cfg.g_h = 1080; - cfg.g_lag_in_frames = 0; - cfg.rc_target_bitrate = 1000000; - // Set this to more than 100 percent to cause an error when vbr_min_bits is - // cast to `int` in vp9_rc_update_framerate() if vbr_min_bits is not clamped - // to INT_MAX. - cfg.rc_2pass_vbr_minsection_pct = 101; - - ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK); - - // Create input image. - vpx_image_t *const image = - CreateImage(VPX_BITS_8, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h); - ASSERT_NE(image, nullptr); - - // Encode frame. - // `duration` can go as high as 300, but the UBSan error is gone if - // `duration` is 301 or higher. - ASSERT_EQ( - vpx_codec_encode(&enc, image, 0, /*duration=*/300, 0, VPX_DL_REALTIME), - VPX_CODEC_OK); - - // Free resources. - vpx_img_free(image); - ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK); -} - -TEST(EncodeAPI, Chromium352414650) { - // Initialize libvpx encoder. - vpx_codec_iface_t *const iface = vpx_codec_vp9_cx(); - vpx_codec_ctx_t enc; - vpx_codec_enc_cfg_t cfg; - - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); - - cfg.g_w = 1024; - cfg.g_h = 1024; - cfg.g_profile = 0; - cfg.g_pass = VPX_RC_ONE_PASS; - cfg.g_lag_in_frames = 0; - cfg.rc_max_quantizer = 58; - cfg.rc_min_quantizer = 2; - cfg.g_threads = 4; - cfg.rc_resize_allowed = 0; - cfg.rc_dropframe_thresh = 0; - cfg.g_timebase.num = 1; - cfg.g_timebase.den = 1000000; - cfg.kf_min_dist = 0; - cfg.kf_max_dist = 10000; - cfg.rc_end_usage = VPX_CBR; - cfg.rc_target_bitrate = 754974; - cfg.ts_number_layers = 3; - cfg.ts_periodicity = 4; - cfg.ts_layer_id[0] = 0; - cfg.ts_layer_id[1] = 2; - cfg.ts_layer_id[2] = 1; - cfg.ts_layer_id[3] = 2; - cfg.ts_rate_decimator[0] = 4; - cfg.ts_rate_decimator[1] = 2; - cfg.ts_rate_decimator[2] = 1; - cfg.layer_target_bitrate[0] = 2147483; - cfg.layer_target_bitrate[1] = 3006476; - cfg.layer_target_bitrate[2] = 4294967; - cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_0212; - cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT; - - ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK); - - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_CPUUSED, 7), VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc, VP9E_SET_TILE_COLUMNS, 2), VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc, VP9E_SET_ROW_MT, 1), VPX_CODEC_OK); - - vpx_svc_extra_cfg_t svc_cfg = {}; - svc_cfg.max_quantizers[0] = svc_cfg.max_quantizers[1] = - svc_cfg.max_quantizers[2] = 58; - svc_cfg.min_quantizers[0] = svc_cfg.min_quantizers[1] = - svc_cfg.min_quantizers[2] = 2; - svc_cfg.scaling_factor_num[0] = svc_cfg.scaling_factor_num[1] = - svc_cfg.scaling_factor_num[2] = 1; - svc_cfg.scaling_factor_den[0] = svc_cfg.scaling_factor_den[1] = - svc_cfg.scaling_factor_den[2] = 1; - ASSERT_EQ(vpx_codec_control(&enc, VP9E_SET_SVC_PARAMETERS, &svc_cfg), - VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc, VP9E_SET_SVC, 1), VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc, VP9E_SET_AQ_MODE, 3), VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_STATIC_THRESHOLD, 1), - VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc, VP9E_SET_COLOR_SPACE, VPX_CS_SMPTE_170), - VPX_CODEC_OK); - ASSERT_EQ(vpx_codec_control(&enc, VP9E_SET_COLOR_RANGE, VPX_CR_STUDIO_RANGE), - VPX_CODEC_OK); - - // Create input image. - vpx_image_t *const image = - CreateImage(VPX_BITS_8, VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h); - ASSERT_NE(image, nullptr); - - // Encode frame. - ASSERT_EQ(vpx_codec_encode(&enc, image, 0, /*duration=*/500000, - VPX_EFLAG_FORCE_KF, VPX_DL_REALTIME), - VPX_CODEC_OK); - - // Free resources. - vpx_img_free(image); - ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK); -} - -#endif // CONFIG_VP9_ENCODER - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/encode_perf_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/encode_perf_test.cc deleted file mode 100644 index 75d6838f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/encode_perf_test.cc +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" -#include "test/y4m_video_source.h" -#include "vpx/vpx_codec.h" -#include "vpx_ports/vpx_timer.h" - -namespace { - -const int kMaxPsnr = 100; -const double kUsecsInSec = 1000000.0; - -struct EncodePerfTestVideo { - EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_, - uint32_t bitrate_, int frames_) - : name(name_), width(width_), height(height_), bitrate(bitrate_), - frames(frames_) {} - const char *name; - uint32_t width; - uint32_t height; - uint32_t bitrate; - int frames; -}; - -const EncodePerfTestVideo kVP9EncodePerfTestVectors[] = { - EncodePerfTestVideo("desktop_640_360_30.yuv", 640, 360, 200, 2484), - EncodePerfTestVideo("kirland_640_480_30.yuv", 640, 480, 200, 300), - EncodePerfTestVideo("macmarcomoving_640_480_30.yuv", 640, 480, 200, 987), - EncodePerfTestVideo("macmarcostationary_640_480_30.yuv", 640, 480, 200, 718), - EncodePerfTestVideo("niklas_640_480_30.yuv", 640, 480, 200, 471), - EncodePerfTestVideo("tacomanarrows_640_480_30.yuv", 640, 480, 200, 300), - EncodePerfTestVideo("tacomasmallcameramovement_640_480_30.yuv", 640, 480, 200, - 300), - EncodePerfTestVideo("thaloundeskmtg_640_480_30.yuv", 640, 480, 200, 300), - EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470), -}; - -const int kEncodePerfTestSpeeds[] = { 5, 6, 7, 8, 9 }; -const int kEncodePerfTestThreads[] = { 1, 2, 4 }; - -#define NELEMENTS(x) (sizeof((x)) / sizeof((x)[0])) - -class VP9EncodePerfTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWithParam { - protected: - VP9EncodePerfTest() - : EncoderTest(GET_PARAM(0)), min_psnr_(kMaxPsnr), nframes_(0), - encoding_mode_(GET_PARAM(1)), speed_(0), threads_(1) {} - - ~VP9EncodePerfTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(encoding_mode_); - - cfg_.g_lag_in_frames = 0; - cfg_.rc_min_quantizer = 2; - cfg_.rc_max_quantizer = 56; - cfg_.rc_dropframe_thresh = 0; - cfg_.rc_undershoot_pct = 50; - cfg_.rc_overshoot_pct = 50; - cfg_.rc_buf_sz = 1000; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 600; - cfg_.rc_resize_allowed = 0; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_error_resilient = 1; - cfg_.g_threads = threads_; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - const int log2_tile_columns = 3; - encoder->Control(VP8E_SET_CPUUSED, speed_); - encoder->Control(VP9E_SET_TILE_COLUMNS, log2_tile_columns); - encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1); - encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 0); - } - } - - void BeginPassHook(unsigned int /*pass*/) override { - min_psnr_ = kMaxPsnr; - nframes_ = 0; - } - - void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) override { - if (pkt->data.psnr.psnr[0] < min_psnr_) { - min_psnr_ = pkt->data.psnr.psnr[0]; - } - } - - // for performance reasons don't decode - bool DoDecode() const override { return false; } - - double min_psnr() const { return min_psnr_; } - - void set_speed(unsigned int speed) { speed_ = speed; } - - void set_threads(unsigned int threads) { threads_ = threads; } - - private: - double min_psnr_; - unsigned int nframes_; - libvpx_test::TestMode encoding_mode_; - unsigned speed_; - unsigned int threads_; -}; - -TEST_P(VP9EncodePerfTest, PerfTest) { - for (size_t i = 0; i < NELEMENTS(kVP9EncodePerfTestVectors); ++i) { - for (size_t j = 0; j < NELEMENTS(kEncodePerfTestSpeeds); ++j) { - for (size_t k = 0; k < NELEMENTS(kEncodePerfTestThreads); ++k) { - if (kVP9EncodePerfTestVectors[i].width < 512 && - kEncodePerfTestThreads[k] > 1) { - continue; - } else if (kVP9EncodePerfTestVectors[i].width < 1024 && - kEncodePerfTestThreads[k] > 2) { - continue; - } - - set_threads(kEncodePerfTestThreads[k]); - SetUp(); - - const vpx_rational timebase = { 33333333, 1000000000 }; - cfg_.g_timebase = timebase; - cfg_.rc_target_bitrate = kVP9EncodePerfTestVectors[i].bitrate; - - init_flags_ = VPX_CODEC_USE_PSNR; - - const unsigned frames = kVP9EncodePerfTestVectors[i].frames; - const char *video_name = kVP9EncodePerfTestVectors[i].name; - libvpx_test::I420VideoSource video( - video_name, kVP9EncodePerfTestVectors[i].width, - kVP9EncodePerfTestVectors[i].height, timebase.den, timebase.num, 0, - kVP9EncodePerfTestVectors[i].frames); - set_speed(kEncodePerfTestSpeeds[j]); - - vpx_usec_timer t; - vpx_usec_timer_start(&t); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - vpx_usec_timer_mark(&t); - const double elapsed_secs = vpx_usec_timer_elapsed(&t) / kUsecsInSec; - const double fps = frames / elapsed_secs; - const double minimum_psnr = min_psnr(); - std::string display_name(video_name); - if (kEncodePerfTestThreads[k] > 1) { - char thread_count[32]; - snprintf(thread_count, sizeof(thread_count), "_t-%d", - kEncodePerfTestThreads[k]); - display_name += thread_count; - } - - printf("{\n"); - printf("\t\"type\" : \"encode_perf_test\",\n"); - printf("\t\"version\" : \"%s\",\n", vpx_codec_version_str()); - printf("\t\"videoName\" : \"%s\",\n", display_name.c_str()); - printf("\t\"encodeTimeSecs\" : %f,\n", elapsed_secs); - printf("\t\"totalFrames\" : %u,\n", frames); - printf("\t\"framesPerSecond\" : %f,\n", fps); - printf("\t\"minPsnr\" : %f,\n", minimum_psnr); - printf("\t\"speed\" : %d,\n", kEncodePerfTestSpeeds[j]); - printf("\t\"threads\" : %d\n", kEncodePerfTestThreads[k]); - printf("}\n"); - } - } - } -} - -VP9_INSTANTIATE_TEST_SUITE(VP9EncodePerfTest, - ::testing::Values(::libvpx_test::kRealTime)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/encode_test_driver.cc b/presentation/src/main/cpp/third_party/libvpx/test/encode_test_driver.cc deleted file mode 100644 index 770f410d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/encode_test_driver.cc +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "gtest/gtest.h" - -#include "./vpx_config.h" -#include "test/codec_factory.h" -#include "test/decode_test_driver.h" -#include "test/encode_test_driver.h" -#include "test/register_state_check.h" -#include "test/video_source.h" - -namespace libvpx_test { -void Encoder::InitEncoder(VideoSource *video) { - vpx_codec_err_t res; - const vpx_image_t *img = video->img(); - - if (video->img() && !encoder_.priv) { - cfg_.g_w = img->d_w; - cfg_.g_h = img->d_h; - cfg_.g_timebase = video->timebase(); - cfg_.rc_twopass_stats_in = stats_->buf(); - - res = vpx_codec_enc_init(&encoder_, CodecInterface(), &cfg_, init_flags_); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); - -#if CONFIG_VP9_ENCODER - if (CodecInterface() == &vpx_codec_vp9_cx_algo) { - // Default to 1 tile column for VP9. - const int log2_tile_columns = 0; - res = vpx_codec_control_(&encoder_, VP9E_SET_TILE_COLUMNS, - log2_tile_columns); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); - } else -#endif - { -#if CONFIG_VP8_ENCODER - ASSERT_EQ(&vpx_codec_vp8_cx_algo, CodecInterface()) - << "Unknown Codec Interface"; -#endif - } - } -} - -void Encoder::EncodeFrame(VideoSource *video, - const vpx_enc_frame_flags_t frame_flags) { - if (video->img()) { - EncodeFrameInternal(*video, frame_flags); - } else { - Flush(); - } - - // Handle twopass stats - CxDataIterator iter = GetCxData(); - - while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) { - if (pkt->kind != VPX_CODEC_STATS_PKT) continue; - - stats_->Append(*pkt); - } -} - -void Encoder::EncodeFrameInternal(const VideoSource &video, - const vpx_enc_frame_flags_t frame_flags) { - vpx_codec_err_t res; - const vpx_image_t *img = video.img(); - - // Handle frame resizing - if (cfg_.g_w != img->d_w || cfg_.g_h != img->d_h) { - cfg_.g_w = img->d_w; - cfg_.g_h = img->d_h; - res = vpx_codec_enc_config_set(&encoder_, &cfg_); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); - } - - // Encode the frame - API_REGISTER_STATE_CHECK(res = vpx_codec_encode(&encoder_, img, video.pts(), - video.duration(), frame_flags, - deadline_)); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); -} - -void Encoder::Flush() { - const vpx_codec_err_t res = - vpx_codec_encode(&encoder_, nullptr, 0, 0, 0, deadline_); - if (!encoder_.priv) - ASSERT_EQ(VPX_CODEC_ERROR, res) << EncoderError(); - else - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); -} - -void EncoderTest::InitializeConfig() { - const vpx_codec_err_t res = codec_->DefaultEncoderConfig(&cfg_, 0); - dec_cfg_ = vpx_codec_dec_cfg_t(); - ASSERT_EQ(VPX_CODEC_OK, res); -} - -void EncoderTest::SetMode(TestMode mode) { - switch (mode) { - case kRealTime: deadline_ = VPX_DL_REALTIME; break; - - case kOnePassGood: - case kTwoPassGood: deadline_ = VPX_DL_GOOD_QUALITY; break; - - case kOnePassBest: - case kTwoPassBest: deadline_ = VPX_DL_BEST_QUALITY; break; - - default: ASSERT_TRUE(false) << "Unexpected mode " << mode; - } - - if (mode == kTwoPassGood || mode == kTwoPassBest) { - passes_ = 2; - } else { - passes_ = 1; - } -} -// The function should return "true" most of the time, therefore no early -// break-out is implemented within the match checking process. -static bool compare_img(const vpx_image_t *img1, const vpx_image_t *img2) { - bool match = (img1->fmt == img2->fmt) && (img1->cs == img2->cs) && - (img1->d_w == img2->d_w) && (img1->d_h == img2->d_h); - - if (!match) return false; - - const unsigned int width_y = img1->d_w; - const unsigned int height_y = img1->d_h; - unsigned int i; - for (i = 0; i < height_y; ++i) { - match = (memcmp(img1->planes[VPX_PLANE_Y] + i * img1->stride[VPX_PLANE_Y], - img2->planes[VPX_PLANE_Y] + i * img2->stride[VPX_PLANE_Y], - width_y) == 0) && - match; - } - const unsigned int width_uv = (img1->d_w + 1) >> 1; - const unsigned int height_uv = (img1->d_h + 1) >> 1; - for (i = 0; i < height_uv; ++i) { - match = (memcmp(img1->planes[VPX_PLANE_U] + i * img1->stride[VPX_PLANE_U], - img2->planes[VPX_PLANE_U] + i * img2->stride[VPX_PLANE_U], - width_uv) == 0) && - match; - } - for (i = 0; i < height_uv; ++i) { - match = (memcmp(img1->planes[VPX_PLANE_V] + i * img1->stride[VPX_PLANE_V], - img2->planes[VPX_PLANE_V] + i * img2->stride[VPX_PLANE_V], - width_uv) == 0) && - match; - } - return match; -} - -void EncoderTest::MismatchHook(const vpx_image_t * /*img1*/, - const vpx_image_t * /*img2*/) { - ASSERT_TRUE(0) << "Encode/Decode mismatch found"; -} - -void EncoderTest::RunLoop(VideoSource *video) { - vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t(); - - stats_.Reset(); - - ASSERT_TRUE(passes_ == 1 || passes_ == 2); - for (unsigned int pass = 0; pass < passes_; pass++) { - vpx_codec_pts_t last_pts = 0; - - if (passes_ == 1) { - cfg_.g_pass = VPX_RC_ONE_PASS; - } else if (pass == 0) { - cfg_.g_pass = VPX_RC_FIRST_PASS; - } else { - cfg_.g_pass = VPX_RC_LAST_PASS; - } - - BeginPassHook(pass); - std::unique_ptr encoder( - codec_->CreateEncoder(cfg_, deadline_, init_flags_, &stats_)); - ASSERT_NE(encoder.get(), nullptr); - - ASSERT_NO_FATAL_FAILURE(video->Begin()); - encoder->InitEncoder(video); - ASSERT_FALSE(::testing::Test::HasFatalFailure()); - - unsigned long dec_init_flags = 0; // NOLINT - // Use fragment decoder if encoder outputs partitions. - // NOTE: fragment decoder and partition encoder are only supported by VP8. - if (init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) { - dec_init_flags |= VPX_CODEC_USE_INPUT_FRAGMENTS; - } - std::unique_ptr decoder( - codec_->CreateDecoder(dec_cfg, dec_init_flags)); - bool again; - for (again = true; again; video->Next()) { - again = (video->img() != nullptr); - - PreEncodeFrameHook(video); - PreEncodeFrameHook(video, encoder.get()); - encoder->EncodeFrame(video, frame_flags_); - - PostEncodeFrameHook(encoder.get()); - - CxDataIterator iter = encoder->GetCxData(); - - bool has_cxdata = false; - bool has_dxdata = false; - while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) { - pkt = MutateEncoderOutputHook(pkt); - again = true; - switch (pkt->kind) { - case VPX_CODEC_CX_FRAME_PKT: - has_cxdata = true; - if (decoder != nullptr && DoDecode()) { - PreDecodeFrameHook(video, decoder.get()); - vpx_codec_err_t res_dec = decoder->DecodeFrame( - (const uint8_t *)pkt->data.frame.buf, pkt->data.frame.sz); - - if (!HandleDecodeResult(res_dec, *video, decoder.get())) break; - - has_dxdata = true; - } - ASSERT_GE(pkt->data.frame.pts, last_pts); - last_pts = pkt->data.frame.pts; - FramePktHook(pkt); - break; - - case VPX_CODEC_PSNR_PKT: PSNRPktHook(pkt); break; - - case VPX_CODEC_STATS_PKT: StatsPktHook(pkt); break; - - default: break; - } - } - - // Flush the decoder when there are no more fragments. - if ((init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) && has_dxdata) { - const vpx_codec_err_t res_dec = decoder->DecodeFrame(nullptr, 0); - if (!HandleDecodeResult(res_dec, *video, decoder.get())) break; - } - - if (has_dxdata && has_cxdata) { - const vpx_image_t *img_enc = encoder->GetPreviewFrame(); - DxDataIterator dec_iter = decoder->GetDxData(); - const vpx_image_t *img_dec = dec_iter.Next(); - if (img_enc && img_dec) { - const bool res = compare_img(img_enc, img_dec); - if (!res) { // Mismatch - MismatchHook(img_enc, img_dec); - } - } - if (img_dec) DecompressedFrameHook(*img_dec, video->pts()); - } - if (!Continue()) break; - } - - EndPassHook(); - - if (!Continue()) break; - } -} - -} // namespace libvpx_test diff --git a/presentation/src/main/cpp/third_party/libvpx/test/encode_test_driver.h b/presentation/src/main/cpp/third_party/libvpx/test/encode_test_driver.h deleted file mode 100644 index c9a7c154..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/encode_test_driver.h +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_TEST_ENCODE_TEST_DRIVER_H_ -#define VPX_TEST_ENCODE_TEST_DRIVER_H_ - -#include -#include - -#include "gtest/gtest.h" - -#include "./vpx_config.h" -#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER -#include "vpx/vp8cx.h" -#endif -#include "vpx/vpx_tpl.h" - -namespace libvpx_test { - -class CodecFactory; -class VideoSource; - -enum TestMode { - kRealTime, - kOnePassGood, - kOnePassBest, - kTwoPassGood, - kTwoPassBest -}; - -#if CONFIG_REALTIME_ONLY -#define ALL_TEST_MODES ::testing::Values(::libvpx_test::kRealTime) -#define ONE_PASS_TEST_MODES ::testing::Values(::libvpx_test::kRealTime) -#define ONE_OR_TWO_PASS_TEST_MODES ::testing::Values(::libvpx_test::kRealTime) -#else -#define ALL_TEST_MODES \ - ::testing::Values(::libvpx_test::kRealTime, ::libvpx_test::kOnePassGood, \ - ::libvpx_test::kOnePassBest, ::libvpx_test::kTwoPassGood, \ - ::libvpx_test::kTwoPassBest) -#define ONE_PASS_TEST_MODES \ - ::testing::Values(::libvpx_test::kRealTime, ::libvpx_test::kOnePassGood, \ - ::libvpx_test::kOnePassBest) - -#define ONE_OR_TWO_PASS_TEST_MODES \ - ::testing::Values(::libvpx_test::kOnePassGood, ::libvpx_test::kTwoPassGood) -#endif - -#define TWO_PASS_TEST_MODES \ - ::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kTwoPassBest) - -// Provides an object to handle the libvpx get_cx_data() iteration pattern -class CxDataIterator { - public: - explicit CxDataIterator(vpx_codec_ctx_t *encoder) - : encoder_(encoder), iter_(nullptr) {} - - const vpx_codec_cx_pkt_t *Next() { - return vpx_codec_get_cx_data(encoder_, &iter_); - } - - private: - vpx_codec_ctx_t *encoder_; - vpx_codec_iter_t iter_; -}; - -// Implements an in-memory store for libvpx twopass statistics -class TwopassStatsStore { - public: - void Append(const vpx_codec_cx_pkt_t &pkt) { - buffer_.append(reinterpret_cast(pkt.data.twopass_stats.buf), - pkt.data.twopass_stats.sz); - } - - vpx_fixed_buf_t buf() { - const vpx_fixed_buf_t buf = { &buffer_[0], buffer_.size() }; - return buf; - } - - void Reset() { buffer_.clear(); } - - protected: - std::string buffer_; -}; - -// Provides a simplified interface to manage one video encoding pass, given -// a configuration and video source. -// -// TODO(jkoleszar): The exact services it provides and the appropriate -// level of abstraction will be fleshed out as more tests are written. -class Encoder { - public: - Encoder(vpx_codec_enc_cfg_t cfg, vpx_enc_deadline_t deadline, - const unsigned long init_flags, TwopassStatsStore *stats) - : cfg_(cfg), deadline_(deadline), init_flags_(init_flags), stats_(stats) { - memset(&encoder_, 0, sizeof(encoder_)); - } - - virtual ~Encoder() { vpx_codec_destroy(&encoder_); } - - CxDataIterator GetCxData() { return CxDataIterator(&encoder_); } - - void InitEncoder(VideoSource *video); - - const vpx_image_t *GetPreviewFrame() { - return vpx_codec_get_preview_frame(&encoder_); - } - // This is a thin wrapper around vpx_codec_encode(), so refer to - // vpx_encoder.h for its semantics. - void EncodeFrame(VideoSource *video, vpx_enc_frame_flags_t frame_flags); - - // Convenience wrapper for EncodeFrame() - void EncodeFrame(VideoSource *video) { EncodeFrame(video, 0); } - - void Control(int ctrl_id, int arg) { - const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); - } - - void Control(int ctrl_id, int *arg) { - const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); - } - - void Control(int ctrl_id, struct vpx_scaling_mode *arg) { - const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); - } - - void Control(int ctrl_id, struct vpx_svc_layer_id *arg) { - const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); - } - - void Control(int ctrl_id, struct vpx_svc_ref_frame_config *arg) { - const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); - } - - void Control(int ctrl_id, struct vpx_svc_parameters *arg) { - const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); - } - - void Control(int ctrl_id, struct vpx_svc_frame_drop *arg) { - const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); - } - - void Control(int ctrl_id, struct vpx_svc_spatial_layer_sync *arg) { - const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); - } - -#if CONFIG_VP9_ENCODER - void Control(int ctrl_id, vpx_rc_funcs_t *arg) { - const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); - } - - void Control(int ctrl_id, VpxTplGopStats *arg) { - const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); - } -#endif // CONFIG_VP9_ENCODER - -#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER - void Control(int ctrl_id, vpx_active_map_t *arg) { - const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); - } - - void Control(int ctrl_id, vpx_roi_map_t *arg) { - const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); - } -#endif - void Config(const vpx_codec_enc_cfg_t *cfg) { - const vpx_codec_err_t res = vpx_codec_enc_config_set(&encoder_, cfg); - ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); - cfg_ = *cfg; - } - - void set_deadline(vpx_enc_deadline_t deadline) { deadline_ = deadline; } - - protected: - virtual vpx_codec_iface_t *CodecInterface() const = 0; - - const char *EncoderError() { - const char *detail = vpx_codec_error_detail(&encoder_); - return detail ? detail : vpx_codec_error(&encoder_); - } - - // Encode an image - void EncodeFrameInternal(const VideoSource &video, - vpx_enc_frame_flags_t frame_flags); - - // Flush the encoder on EOS - void Flush(); - - vpx_codec_ctx_t encoder_; - vpx_codec_enc_cfg_t cfg_; - vpx_enc_deadline_t deadline_; - unsigned long init_flags_; - TwopassStatsStore *stats_; -}; - -// Common test functionality for all Encoder tests. -// -// This class is a mixin which provides the main loop common to all -// encoder tests. It provides hooks which can be overridden by subclasses -// to implement each test's specific behavior, while centralizing the bulk -// of the boilerplate. Note that it doesn't inherit the gtest testing -// classes directly, so that tests can be parameterized differently. -class EncoderTest { - protected: - explicit EncoderTest(const CodecFactory *codec) - : codec_(codec), abort_(false), init_flags_(0), frame_flags_(0) { - // Default to 1 thread. - cfg_.g_threads = 1; - } - - virtual ~EncoderTest() {} - - // Initialize the cfg_ member with the default configuration. - void InitializeConfig(); - - // Map the TestMode enum to the deadline_ and passes_ variables. - void SetMode(TestMode mode); - - // Set encoder flag. - void set_init_flags(unsigned long flag) { // NOLINT(runtime/int) - init_flags_ = flag; - } - - // Main loop - virtual void RunLoop(VideoSource *video); - - // Hook to be called at the beginning of a pass. - virtual void BeginPassHook(unsigned int /*pass*/) {} - - // Hook to be called at the end of a pass. - virtual void EndPassHook() {} - - // Hook to be called before encoding a frame. - virtual void PreEncodeFrameHook(VideoSource * /*video*/) {} - virtual void PreEncodeFrameHook(VideoSource * /*video*/, - Encoder * /*encoder*/) {} - - virtual void PreDecodeFrameHook(VideoSource * /*video*/, - Decoder * /*decoder*/) {} - - virtual void PostEncodeFrameHook(Encoder * /*encoder*/) {} - - // Hook to be called on every compressed data packet. - virtual void FramePktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {} - - // Hook to be called on every PSNR packet. - virtual void PSNRPktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {} - - // Hook to be called on every first pass stats packet. - virtual void StatsPktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {} - - // Hook to determine whether the encode loop should continue. - virtual bool Continue() const { - return !(::testing::Test::HasFatalFailure() || abort_); - } - - const CodecFactory *codec_; - // Hook to determine whether to decode frame after encoding - virtual bool DoDecode() const { return true; } - - // Hook to handle encode/decode mismatch - virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2); - - // Hook to be called on every decompressed frame. - virtual void DecompressedFrameHook(const vpx_image_t & /*img*/, - vpx_codec_pts_t /*pts*/) {} - - // Hook to be called to handle decode result. Return true to continue. - virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec, - const VideoSource & /*video*/, - Decoder *decoder) { - EXPECT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError(); - return VPX_CODEC_OK == res_dec; - } - - // Hook that can modify the encoder's output data - virtual const vpx_codec_cx_pkt_t *MutateEncoderOutputHook( - const vpx_codec_cx_pkt_t *pkt) { - return pkt; - } - - bool abort_; - vpx_codec_enc_cfg_t cfg_; - vpx_codec_dec_cfg_t dec_cfg_; - unsigned int passes_; - vpx_enc_deadline_t deadline_; - TwopassStatsStore stats_; - unsigned long init_flags_; - vpx_enc_frame_flags_t frame_flags_; -}; - -} // namespace libvpx_test - -#endif // VPX_TEST_ENCODE_TEST_DRIVER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/error_resilience_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/error_resilience_test.cc deleted file mode 100644 index 9bd43b72..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/error_resilience_test.cc +++ /dev/null @@ -1,588 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" -#include "vpx_config.h" - -namespace { - -const int kMaxErrorFrames = 12; -const int kMaxDroppableFrames = 12; - -class ErrorResilienceTestLarge - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith2Params { - protected: - ErrorResilienceTestLarge() - : EncoderTest(GET_PARAM(0)), svc_support_(GET_PARAM(2)), psnr_(0.0), - nframes_(0), mismatch_psnr_(0.0), mismatch_nframes_(0), - encoding_mode_(GET_PARAM(1)) { - Reset(); - } - - ~ErrorResilienceTestLarge() override = default; - - void Reset() { - error_nframes_ = 0; - droppable_nframes_ = 0; - pattern_switch_ = 0; - } - - void SetUp() override { - InitializeConfig(); - SetMode(encoding_mode_); - } - - void BeginPassHook(unsigned int /*pass*/) override { - psnr_ = 0.0; - nframes_ = 0; - mismatch_psnr_ = 0.0; - mismatch_nframes_ = 0; - } - - void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) override { - psnr_ += pkt->data.psnr.psnr[0]; - nframes_++; - } - - // - // Frame flags and layer id for temporal layers. - // For two layers, test pattern is: - // 1 3 - // 0 2 ..... - // LAST is updated on base/layer 0, GOLDEN updated on layer 1. - // Non-zero pattern_switch parameter means pattern will switch to - // not using LAST for frame_num >= pattern_switch. - int SetFrameFlags(int frame_num, int num_temp_layers, int pattern_switch) { - int frame_flags = 0; - if (num_temp_layers == 2) { - if (frame_num % 2 == 0) { - if (frame_num < pattern_switch || pattern_switch == 0) { - // Layer 0: predict from LAST and ARF, update LAST. - frame_flags = - VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; - } else { - // Layer 0: predict from GF and ARF, update GF. - frame_flags = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_LAST | - VP8_EFLAG_NO_UPD_ARF; - } - } else { - if (frame_num < pattern_switch || pattern_switch == 0) { - // Layer 1: predict from L, GF, and ARF, update GF. - frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; - } else { - // Layer 1: predict from GF and ARF, update GF. - frame_flags = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_LAST | - VP8_EFLAG_NO_UPD_ARF; - } - } - } - return frame_flags; - } - - void PreEncodeFrameHook(libvpx_test::VideoSource *video) override { - frame_flags_ &= - ~(VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF); - // For temporal layer case. - if (cfg_.ts_number_layers > 1) { - frame_flags_ = - SetFrameFlags(video->frame(), cfg_.ts_number_layers, pattern_switch_); - for (unsigned int i = 0; i < droppable_nframes_; ++i) { - if (droppable_frames_[i] == video->frame()) { - std::cout << "Encoding droppable frame: " << droppable_frames_[i] - << "\n"; - } - } - } else { - if (droppable_nframes_ > 0 && - (cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) { - for (unsigned int i = 0; i < droppable_nframes_; ++i) { - if (droppable_frames_[i] == video->frame()) { - std::cout << "Encoding droppable frame: " << droppable_frames_[i] - << "\n"; - frame_flags_ |= (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | - VP8_EFLAG_NO_UPD_ARF); - return; - } - } - } - } - } - - double GetAveragePsnr() const { - if (nframes_) return psnr_ / nframes_; - return 0.0; - } - - double GetAverageMismatchPsnr() const { - if (mismatch_nframes_) return mismatch_psnr_ / mismatch_nframes_; - return 0.0; - } - - bool DoDecode() const override { - if (error_nframes_ > 0 && - (cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) { - for (unsigned int i = 0; i < error_nframes_; ++i) { - if (error_frames_[i] == nframes_ - 1) { - std::cout << " Skipping decoding frame: " - << error_frames_[i] << "\n"; - return false; - } - } - } - return true; - } - - void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) override { - double mismatch_psnr = compute_psnr(img1, img2); - mismatch_psnr_ += mismatch_psnr; - ++mismatch_nframes_; - // std::cout << "Mismatch frame psnr: " << mismatch_psnr << "\n"; - } - - void SetErrorFrames(int num, unsigned int *list) { - if (num > kMaxErrorFrames) { - num = kMaxErrorFrames; - } else if (num < 0) { - num = 0; - } - error_nframes_ = num; - for (unsigned int i = 0; i < error_nframes_; ++i) { - error_frames_[i] = list[i]; - } - } - - void SetDroppableFrames(int num, unsigned int *list) { - if (num > kMaxDroppableFrames) { - num = kMaxDroppableFrames; - } else if (num < 0) { - num = 0; - } - droppable_nframes_ = num; - for (unsigned int i = 0; i < droppable_nframes_; ++i) { - droppable_frames_[i] = list[i]; - } - } - - unsigned int GetMismatchFrames() { return mismatch_nframes_; } - - void SetPatternSwitch(int frame_switch) { pattern_switch_ = frame_switch; } - - bool svc_support_; - - private: - double psnr_; - unsigned int nframes_; - unsigned int error_nframes_; - unsigned int droppable_nframes_; - unsigned int pattern_switch_; - double mismatch_psnr_; - unsigned int mismatch_nframes_; - unsigned int error_frames_[kMaxErrorFrames]; - unsigned int droppable_frames_[kMaxDroppableFrames]; - libvpx_test::TestMode encoding_mode_; -}; - -TEST_P(ErrorResilienceTestLarge, OnVersusOff) { -#if CONFIG_REALTIME_ONLY - GTEST_SKIP() - << "Non-zero g_lag_in_frames is unsupported with CONFIG_REALTIME_ONLY"; -#else - const vpx_rational timebase = { 33333333, 1000000000 }; - cfg_.g_timebase = timebase; - cfg_.rc_target_bitrate = 2000; - cfg_.g_lag_in_frames = 10; - - init_flags_ = VPX_CODEC_USE_PSNR; - - libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - timebase.den, timebase.num, 0, 30); - - // Error resilient mode OFF. - cfg_.g_error_resilient = 0; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - const double psnr_resilience_off = GetAveragePsnr(); - EXPECT_GT(psnr_resilience_off, 25.0); - - // Error resilient mode ON. - cfg_.g_error_resilient = 1; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - const double psnr_resilience_on = GetAveragePsnr(); - EXPECT_GT(psnr_resilience_on, 25.0); - - // Test that turning on error resilient mode hurts by 10% at most. - if (psnr_resilience_off > 0.0) { - const double psnr_ratio = psnr_resilience_on / psnr_resilience_off; - EXPECT_GE(psnr_ratio, 0.9); - EXPECT_LE(psnr_ratio, 1.1); - } -#endif // CONFIG_REALTIME_ONLY -} - -// Check for successful decoding and no encoder/decoder mismatch -// if we lose (i.e., drop before decoding) a set of droppable -// frames (i.e., frames that don't update any reference buffers). -// Check both isolated and consecutive loss. -TEST_P(ErrorResilienceTestLarge, DropFramesWithoutRecovery) { - const vpx_rational timebase = { 33333333, 1000000000 }; - cfg_.g_timebase = timebase; - cfg_.rc_target_bitrate = 500; - // FIXME(debargha): Fix this to work for any lag. - // Currently this test only works for lag = 0 - cfg_.g_lag_in_frames = 0; - - init_flags_ = VPX_CODEC_USE_PSNR; - - libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - timebase.den, timebase.num, 0, 40); - - // Error resilient mode ON. - cfg_.g_error_resilient = 1; - cfg_.kf_mode = VPX_KF_DISABLED; - - // Set an arbitrary set of error frames same as droppable frames. - // In addition to isolated loss/drop, add a long consecutive series - // (of size 9) of dropped frames. - unsigned int num_droppable_frames = 11; - unsigned int droppable_frame_list[] = { 5, 16, 22, 23, 24, 25, - 26, 27, 28, 29, 30 }; - SetDroppableFrames(num_droppable_frames, droppable_frame_list); - SetErrorFrames(num_droppable_frames, droppable_frame_list); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - // Test that no mismatches have been found - std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n"; - EXPECT_EQ(GetMismatchFrames(), (unsigned int)0); - - // Reset previously set of error/droppable frames. - Reset(); - -#if 0 - // TODO(jkoleszar): This test is disabled for the time being as too - // sensitive. It's not clear how to set a reasonable threshold for - // this behavior. - - // Now set an arbitrary set of error frames that are non-droppable - unsigned int num_error_frames = 3; - unsigned int error_frame_list[] = {3, 10, 20}; - SetErrorFrames(num_error_frames, error_frame_list); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - // Test that dropping an arbitrary set of inter frames does not hurt too much - // Note the Average Mismatch PSNR is the average of the PSNR between - // decoded frame and encoder's version of the same frame for all frames - // with mismatch. - const double psnr_resilience_mismatch = GetAverageMismatchPsnr(); - std::cout << " Mismatch PSNR: " - << psnr_resilience_mismatch << "\n"; - EXPECT_GT(psnr_resilience_mismatch, 20.0); -#endif -} - -// Check for successful decoding and no encoder/decoder mismatch -// if we lose (i.e., drop before decoding) the enhancement layer frames for a -// two layer temporal pattern. The base layer does not predict from the top -// layer, so successful decoding is expected. -TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) { - // This test doesn't run if SVC is not supported. - if (!svc_support_) return; - - const vpx_rational timebase = { 33333333, 1000000000 }; - cfg_.g_timebase = timebase; - cfg_.rc_target_bitrate = 500; - cfg_.g_lag_in_frames = 0; - - cfg_.rc_end_usage = VPX_CBR; - // 2 Temporal layers, no spatial layers, CBR mode. - cfg_.ss_number_layers = 1; - cfg_.ts_number_layers = 2; - cfg_.ts_rate_decimator[0] = 2; - cfg_.ts_rate_decimator[1] = 1; - cfg_.ts_periodicity = 2; - cfg_.ts_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100; - cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate; - - init_flags_ = VPX_CODEC_USE_PSNR; - - libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - timebase.den, timebase.num, 0, 40); - - // Error resilient mode ON. - cfg_.g_error_resilient = 1; - cfg_.kf_mode = VPX_KF_DISABLED; - SetPatternSwitch(0); - - // The odd frames are the enhancement layer for 2 layer pattern, so set - // those frames as droppable. Drop the last 7 frames. - unsigned int num_droppable_frames = 7; - unsigned int droppable_frame_list[] = { 27, 29, 31, 33, 35, 37, 39 }; - SetDroppableFrames(num_droppable_frames, droppable_frame_list); - SetErrorFrames(num_droppable_frames, droppable_frame_list); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - // Test that no mismatches have been found - std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n"; - EXPECT_EQ(GetMismatchFrames(), (unsigned int)0); - - // Reset previously set of error/droppable frames. - Reset(); -} - -// Check for successful decoding and no encoder/decoder mismatch -// for a two layer temporal pattern, where at some point in the -// sequence, the LAST ref is not used anymore. -TEST_P(ErrorResilienceTestLarge, 2LayersNoRefLast) { - // This test doesn't run if SVC is not supported. - if (!svc_support_) return; - - const vpx_rational timebase = { 33333333, 1000000000 }; - cfg_.g_timebase = timebase; - cfg_.rc_target_bitrate = 500; - cfg_.g_lag_in_frames = 0; - - cfg_.rc_end_usage = VPX_CBR; - // 2 Temporal layers, no spatial layers, CBR mode. - cfg_.ss_number_layers = 1; - cfg_.ts_number_layers = 2; - cfg_.ts_rate_decimator[0] = 2; - cfg_.ts_rate_decimator[1] = 1; - cfg_.ts_periodicity = 2; - cfg_.ts_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100; - cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate; - - init_flags_ = VPX_CODEC_USE_PSNR; - - libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - timebase.den, timebase.num, 0, 100); - - // Error resilient mode ON. - cfg_.g_error_resilient = 1; - cfg_.kf_mode = VPX_KF_DISABLED; - SetPatternSwitch(60); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - // Test that no mismatches have been found - std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n"; - EXPECT_EQ(GetMismatchFrames(), (unsigned int)0); - - // Reset previously set of error/droppable frames. - Reset(); -} - -class ErrorResilienceTestLargeCodecControls - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWithParam { - protected: - ErrorResilienceTestLargeCodecControls() - : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)) { - Reset(); - } - - ~ErrorResilienceTestLargeCodecControls() override = default; - - void Reset() { - last_pts_ = 0; - tot_frame_number_ = 0; - // For testing up to 3 layers. - for (int i = 0; i < 3; ++i) { - bits_total_[i] = 0; - } - duration_ = 0.0; - } - - void SetUp() override { - InitializeConfig(); - SetMode(encoding_mode_); - } - - // - // Frame flags and layer id for temporal layers. - // - - // For two layers, test pattern is: - // 1 3 - // 0 2 ..... - // For three layers, test pattern is: - // 1 3 5 7 - // 2 6 - // 0 4 .... - // LAST is always update on base/layer 0, GOLDEN is updated on layer 1, - // and ALTREF is updated on top layer for 3 layer pattern. - int SetFrameFlags(int frame_num, int num_temp_layers) { - int frame_flags = 0; - if (num_temp_layers == 2) { - if (frame_num % 2 == 0) { - // Layer 0: predict from L and ARF, update L. - frame_flags = - VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; - } else { - // Layer 1: predict from L, G and ARF, and update G. - frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | - VP8_EFLAG_NO_UPD_ENTROPY; - } - } else if (num_temp_layers == 3) { - if (frame_num % 4 == 0) { - // Layer 0: predict from L, update L. - frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | - VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF; - } else if ((frame_num - 2) % 4 == 0) { - // Layer 1: predict from L, G, update G. - frame_flags = - VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_REF_ARF; - } else if ((frame_num - 1) % 2 == 0) { - // Layer 2: predict from L, G, ARF; update ARG. - frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST; - } - } - return frame_flags; - } - - int SetLayerId(int frame_num, int num_temp_layers) { - int layer_id = 0; - if (num_temp_layers == 2) { - if (frame_num % 2 == 0) { - layer_id = 0; - } else { - layer_id = 1; - } - } else if (num_temp_layers == 3) { - if (frame_num % 4 == 0) { - layer_id = 0; - } else if ((frame_num - 2) % 4 == 0) { - layer_id = 1; - } else if ((frame_num - 1) % 2 == 0) { - layer_id = 2; - } - } - return layer_id; - } - - void PreEncodeFrameHook(libvpx_test::VideoSource *video, - libvpx_test::Encoder *encoder) override { - if (cfg_.ts_number_layers > 1) { - int layer_id = SetLayerId(video->frame(), cfg_.ts_number_layers); - int frame_flags = SetFrameFlags(video->frame(), cfg_.ts_number_layers); - if (video->frame() > 0) { - encoder->Control(VP8E_SET_TEMPORAL_LAYER_ID, layer_id); - encoder->Control(VP8E_SET_FRAME_FLAGS, frame_flags); - } - const vpx_rational_t tb = video->timebase(); - timebase_ = static_cast(tb.num) / tb.den; - duration_ = 0; - return; - } - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - // Time since last timestamp = duration. - vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_; - if (duration > 1) { - // Update counter for total number of frames (#frames input to encoder). - // Needed for setting the proper layer_id below. - tot_frame_number_ += static_cast(duration - 1); - } - int layer = SetLayerId(tot_frame_number_, cfg_.ts_number_layers); - const size_t frame_size_in_bits = pkt->data.frame.sz * 8; - // Update the total encoded bits. For temporal layers, update the cumulative - // encoded bits per layer. - for (int i = layer; i < static_cast(cfg_.ts_number_layers); ++i) { - bits_total_[i] += frame_size_in_bits; - } - // Update the most recent pts. - last_pts_ = pkt->data.frame.pts; - ++tot_frame_number_; - } - - void EndPassHook() override { - duration_ = (last_pts_ + 1) * timebase_; - if (cfg_.ts_number_layers > 1) { - for (int layer = 0; layer < static_cast(cfg_.ts_number_layers); - ++layer) { - if (bits_total_[layer]) { - // Effective file datarate: - effective_datarate_[layer] = - (bits_total_[layer] / 1000.0) / duration_; - } - } - } - } - - double effective_datarate_[3]; - - private: - libvpx_test::TestMode encoding_mode_; - vpx_codec_pts_t last_pts_; - double timebase_; - int64_t bits_total_[3]; - double duration_; - int tot_frame_number_; -}; - -// Check two codec controls used for: -// (1) for setting temporal layer id, and (2) for settings encoder flags. -// This test invokes those controls for each frame, and verifies encoder/decoder -// mismatch and basic rate control response. -// TODO(marpan): Maybe move this test to datarate_test.cc. -TEST_P(ErrorResilienceTestLargeCodecControls, CodecControl3TemporalLayers) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 1; - cfg_.rc_min_quantizer = 2; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - cfg_.rc_dropframe_thresh = 1; - cfg_.g_lag_in_frames = 0; - cfg_.kf_mode = VPX_KF_DISABLED; - cfg_.g_error_resilient = 1; - - // 3 Temporal layers. Framerate decimation (4, 2, 1). - cfg_.ts_number_layers = 3; - cfg_.ts_rate_decimator[0] = 4; - cfg_.ts_rate_decimator[1] = 2; - cfg_.ts_rate_decimator[2] = 1; - cfg_.ts_periodicity = 4; - cfg_.ts_layer_id[0] = 0; - cfg_.ts_layer_id[1] = 2; - cfg_.ts_layer_id[2] = 1; - cfg_.ts_layer_id[3] = 2; - - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 200); - for (int i = 200; i <= 800; i += 200) { - cfg_.rc_target_bitrate = i; - Reset(); - // 40-20-40 bitrate allocation for 3 temporal layers. - cfg_.ts_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100; - cfg_.ts_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100; - cfg_.ts_target_bitrate[2] = cfg_.rc_target_bitrate; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - for (int j = 0; j < static_cast(cfg_.ts_number_layers); ++j) { - ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.75) - << " The datarate for the file is lower than target by too much, " - "for layer: " - << j; - ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.25) - << " The datarate for the file is greater than target by too much, " - "for layer: " - << j; - } - } -} - -VP8_INSTANTIATE_TEST_SUITE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES, - ::testing::Values(true)); -VP8_INSTANTIATE_TEST_SUITE(ErrorResilienceTestLargeCodecControls, - ONE_PASS_TEST_MODES); -VP9_INSTANTIATE_TEST_SUITE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES, - ::testing::Values(true)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/examples.sh b/presentation/src/main/cpp/third_party/libvpx/test/examples.sh deleted file mode 100644 index 629f0423..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/examples.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2014 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## This file runs all of the tests for the libvpx examples. -## -. $(dirname $0)/tools_common.sh - -example_tests=$(ls $(dirname $0)/*.sh) - -# List of script names to exclude. -exclude_list="examples stress tools_common" - -# Filter out the scripts in $exclude_list. -for word in ${exclude_list}; do - example_tests=$(filter_strings "${example_tests}" "${word}" exclude) -done - -for test in ${example_tests}; do - # Source each test script so that exporting variables can be avoided. - VPX_TEST_NAME="$(basename ${test%.*})" - . "${test}" -done diff --git a/presentation/src/main/cpp/third_party/libvpx/test/external_frame_buffer_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/external_frame_buffer_test.cc deleted file mode 100644 index 7b9a836f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/external_frame_buffer_test.cc +++ /dev/null @@ -1,518 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "test/codec_factory.h" -#include "test/decode_test_driver.h" -#include "test/ivf_video_source.h" -#include "test/md5_helper.h" -#include "test/test_vectors.h" -#include "test/util.h" -#if CONFIG_WEBM_IO -#include "test/webm_video_source.h" -#endif - -namespace { - -const int kVideoNameParam = 1; - -struct ExternalFrameBuffer { - uint8_t *data; - size_t size; - int in_use; -}; - -// Class to manipulate a list of external frame buffers. -class ExternalFrameBufferList { - public: - ExternalFrameBufferList() - : num_buffers_(0), num_used_buffers_(0), ext_fb_list_(nullptr) {} - - virtual ~ExternalFrameBufferList() { - for (int i = 0; i < num_buffers_; ++i) { - delete[] ext_fb_list_[i].data; - } - delete[] ext_fb_list_; - } - - // Creates the list to hold the external buffers. Returns true on success. - bool CreateBufferList(int num_buffers) { - if (num_buffers < 0) return false; - - num_buffers_ = num_buffers; - ext_fb_list_ = new ExternalFrameBuffer[num_buffers_]; - EXPECT_NE(ext_fb_list_, nullptr); - memset(ext_fb_list_, 0, sizeof(ext_fb_list_[0]) * num_buffers_); - return true; - } - - // Searches the frame buffer list for a free frame buffer. Makes sure - // that the frame buffer is at least |min_size| in bytes. Marks that the - // frame buffer is in use by libvpx. Finally sets |fb| to point to the - // external frame buffer. Returns < 0 on an error. - int GetFreeFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) { - EXPECT_NE(fb, nullptr); - const int idx = FindFreeBufferIndex(); - if (idx == num_buffers_) return -1; - - if (ext_fb_list_[idx].size < min_size) { - delete[] ext_fb_list_[idx].data; - ext_fb_list_[idx].data = new uint8_t[min_size]; - memset(ext_fb_list_[idx].data, 0, min_size); - ext_fb_list_[idx].size = min_size; - } - - SetFrameBuffer(idx, fb); - - num_used_buffers_++; - return 0; - } - - // Test function that will not allocate any data for the frame buffer. - // Returns < 0 on an error. - int GetZeroFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) { - EXPECT_NE(fb, nullptr); - const int idx = FindFreeBufferIndex(); - if (idx == num_buffers_) return -1; - - if (ext_fb_list_[idx].size < min_size) { - delete[] ext_fb_list_[idx].data; - ext_fb_list_[idx].data = nullptr; - ext_fb_list_[idx].size = min_size; - } - - SetFrameBuffer(idx, fb); - return 0; - } - - // Marks the external frame buffer that |fb| is pointing to as free. - // Returns < 0 on an error. - int ReturnFrameBuffer(vpx_codec_frame_buffer_t *fb) { - if (fb == nullptr) { - EXPECT_NE(fb, nullptr); - return -1; - } - ExternalFrameBuffer *const ext_fb = - reinterpret_cast(fb->priv); - if (ext_fb == nullptr) { - EXPECT_NE(ext_fb, nullptr); - return -1; - } - EXPECT_EQ(1, ext_fb->in_use); - ext_fb->in_use = 0; - num_used_buffers_--; - return 0; - } - - // Checks that the vpx_image_t data is contained within the external frame - // buffer private data passed back in the vpx_image_t. - void CheckImageFrameBuffer(const vpx_image_t *img) { - if (img->fb_priv != nullptr) { - const struct ExternalFrameBuffer *const ext_fb = - reinterpret_cast(img->fb_priv); - - ASSERT_TRUE(img->planes[0] >= ext_fb->data && - img->planes[0] < (ext_fb->data + ext_fb->size)); - } - } - - int num_used_buffers() const { return num_used_buffers_; } - - private: - // Returns the index of the first free frame buffer. Returns |num_buffers_| - // if there are no free frame buffers. - int FindFreeBufferIndex() { - int i; - // Find a free frame buffer. - for (i = 0; i < num_buffers_; ++i) { - if (!ext_fb_list_[i].in_use) break; - } - return i; - } - - // Sets |fb| to an external frame buffer. idx is the index into the frame - // buffer list. - void SetFrameBuffer(int idx, vpx_codec_frame_buffer_t *fb) { - ASSERT_NE(fb, nullptr); - fb->data = ext_fb_list_[idx].data; - fb->size = ext_fb_list_[idx].size; - ASSERT_EQ(0, ext_fb_list_[idx].in_use); - ext_fb_list_[idx].in_use = 1; - fb->priv = &ext_fb_list_[idx]; - } - - int num_buffers_; - int num_used_buffers_; - ExternalFrameBuffer *ext_fb_list_; -}; - -#if CONFIG_WEBM_IO - -// Callback used by libvpx to request the application to return a frame -// buffer of at least |min_size| in bytes. -int get_vp9_frame_buffer(void *user_priv, size_t min_size, - vpx_codec_frame_buffer_t *fb) { - ExternalFrameBufferList *const fb_list = - reinterpret_cast(user_priv); - return fb_list->GetFreeFrameBuffer(min_size, fb); -} - -// Callback used by libvpx to tell the application that |fb| is not needed -// anymore. -int release_vp9_frame_buffer(void *user_priv, vpx_codec_frame_buffer_t *fb) { - ExternalFrameBufferList *const fb_list = - reinterpret_cast(user_priv); - return fb_list->ReturnFrameBuffer(fb); -} - -// Callback will not allocate data for frame buffer. -int get_vp9_zero_frame_buffer(void *user_priv, size_t min_size, - vpx_codec_frame_buffer_t *fb) { - ExternalFrameBufferList *const fb_list = - reinterpret_cast(user_priv); - return fb_list->GetZeroFrameBuffer(min_size, fb); -} - -// Callback will allocate one less byte than |min_size|. -int get_vp9_one_less_byte_frame_buffer(void *user_priv, size_t min_size, - vpx_codec_frame_buffer_t *fb) { - ExternalFrameBufferList *const fb_list = - reinterpret_cast(user_priv); - return fb_list->GetFreeFrameBuffer(min_size - 1, fb); -} - -// Callback will not release the external frame buffer. -int do_not_release_vp9_frame_buffer(void *user_priv, - vpx_codec_frame_buffer_t *fb) { - (void)user_priv; - (void)fb; - return 0; -} - -#endif // CONFIG_WEBM_IO - -// Class for testing passing in external frame buffers to libvpx. -class ExternalFrameBufferMD5Test - : public ::libvpx_test::DecoderTest, - public ::libvpx_test::CodecTestWithParam { - protected: - ExternalFrameBufferMD5Test() - : DecoderTest(GET_PARAM(::libvpx_test::kCodecFactoryParam)), - md5_file_(nullptr), num_buffers_(0) {} - - ~ExternalFrameBufferMD5Test() override { - if (md5_file_ != nullptr) fclose(md5_file_); - } - - void PreDecodeFrameHook(const libvpx_test::CompressedVideoSource &video, - libvpx_test::Decoder *decoder) override { - if (num_buffers_ > 0 && video.frame_number() == 0) { - // Have libvpx use frame buffers we create. - ASSERT_TRUE(fb_list_.CreateBufferList(num_buffers_)); - ASSERT_EQ(VPX_CODEC_OK, - decoder->SetFrameBufferFunctions(GetVP9FrameBuffer, - ReleaseVP9FrameBuffer, this)); - } - } - - void OpenMD5File(const std::string &md5_file_name_) { - md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_); - ASSERT_NE(md5_file_, nullptr) - << "Md5 file open failed. Filename: " << md5_file_name_; - } - - void DecompressedFrameHook(const vpx_image_t &img, - const unsigned int frame_number) override { - ASSERT_NE(md5_file_, nullptr); - char expected_md5[33]; - char junk[128]; - - // Read correct md5 checksums. - const int res = fscanf(md5_file_, "%s %s", expected_md5, junk); - ASSERT_NE(EOF, res) << "Read md5 data failed"; - expected_md5[32] = '\0'; - - ::libvpx_test::MD5 md5_res; - md5_res.Add(&img); - const char *const actual_md5 = md5_res.Get(); - - // Check md5 match. - ASSERT_STREQ(expected_md5, actual_md5) - << "Md5 checksums don't match: frame number = " << frame_number; - } - - // Callback to get a free external frame buffer. Return value < 0 is an - // error. - static int GetVP9FrameBuffer(void *user_priv, size_t min_size, - vpx_codec_frame_buffer_t *fb) { - ExternalFrameBufferMD5Test *const md5Test = - reinterpret_cast(user_priv); - return md5Test->fb_list_.GetFreeFrameBuffer(min_size, fb); - } - - // Callback to release an external frame buffer. Return value < 0 is an - // error. - static int ReleaseVP9FrameBuffer(void *user_priv, - vpx_codec_frame_buffer_t *fb) { - ExternalFrameBufferMD5Test *const md5Test = - reinterpret_cast(user_priv); - return md5Test->fb_list_.ReturnFrameBuffer(fb); - } - - void set_num_buffers(int num_buffers) { num_buffers_ = num_buffers; } - int num_buffers() const { return num_buffers_; } - - private: - FILE *md5_file_; - int num_buffers_; - ExternalFrameBufferList fb_list_; -}; - -#if CONFIG_WEBM_IO -const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm"; -const char kVP9NonRefTestFile[] = "vp90-2-22-svc_1280x720_1.webm"; - -// Class for testing passing in external frame buffers to libvpx. -class ExternalFrameBufferTest : public ::testing::Test { - protected: - ExternalFrameBufferTest() - : video_(nullptr), decoder_(nullptr), num_buffers_(0) {} - - void SetUp() override { - video_ = new libvpx_test::WebMVideoSource(kVP9TestFile); - ASSERT_NE(video_, nullptr); - video_->Init(); - video_->Begin(); - - vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t(); - decoder_ = new libvpx_test::VP9Decoder(cfg, 0); - ASSERT_NE(decoder_, nullptr); - } - - void TearDown() override { - delete decoder_; - decoder_ = nullptr; - delete video_; - video_ = nullptr; - } - - // Passes the external frame buffer information to libvpx. - vpx_codec_err_t SetFrameBufferFunctions( - int num_buffers, vpx_get_frame_buffer_cb_fn_t cb_get, - vpx_release_frame_buffer_cb_fn_t cb_release) { - if (num_buffers > 0) { - num_buffers_ = num_buffers; - EXPECT_TRUE(fb_list_.CreateBufferList(num_buffers_)); - } - - return decoder_->SetFrameBufferFunctions(cb_get, cb_release, &fb_list_); - } - - vpx_codec_err_t DecodeOneFrame() { - const vpx_codec_err_t res = - decoder_->DecodeFrame(video_->cxdata(), video_->frame_size()); - CheckDecodedFrames(); - if (res == VPX_CODEC_OK) video_->Next(); - return res; - } - - vpx_codec_err_t DecodeRemainingFrames() { - for (; video_->cxdata() != nullptr; video_->Next()) { - const vpx_codec_err_t res = - decoder_->DecodeFrame(video_->cxdata(), video_->frame_size()); - if (res != VPX_CODEC_OK) return res; - CheckDecodedFrames(); - } - return VPX_CODEC_OK; - } - - void CheckDecodedFrames() { - libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData(); - const vpx_image_t *img = nullptr; - - // Get decompressed data - while ((img = dec_iter.Next()) != nullptr) { - fb_list_.CheckImageFrameBuffer(img); - } - } - - libvpx_test::WebMVideoSource *video_; - libvpx_test::VP9Decoder *decoder_; - int num_buffers_; - ExternalFrameBufferList fb_list_; -}; - -class ExternalFrameBufferNonRefTest : public ExternalFrameBufferTest { - protected: - void SetUp() override { - video_ = new libvpx_test::WebMVideoSource(kVP9NonRefTestFile); - ASSERT_NE(video_, nullptr); - video_->Init(); - video_->Begin(); - - vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t(); - decoder_ = new libvpx_test::VP9Decoder(cfg, 0); - ASSERT_NE(decoder_, nullptr); - } - - virtual void CheckFrameBufferRelease() { - TearDown(); - ASSERT_EQ(0, fb_list_.num_used_buffers()); - } -}; -#endif // CONFIG_WEBM_IO - -// This test runs through the set of test vectors, and decodes them. -// Libvpx will call into the application to allocate a frame buffer when -// needed. The md5 checksums are computed for each frame in the video file. -// If md5 checksums match the correct md5 data, then the test is passed. -// Otherwise, the test failed. -TEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) { - const std::string filename = GET_PARAM(kVideoNameParam); - - // Number of buffers equals #VP9_MAXIMUM_REF_BUFFERS + - // #VPX_MAXIMUM_WORK_BUFFERS + four jitter buffers. - const int jitter_buffers = 4; - const int num_buffers = - VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS + jitter_buffers; - set_num_buffers(num_buffers); - -#if CONFIG_VP8_DECODER - // Tell compiler we are not using kVP8TestVectors. - (void)libvpx_test::kVP8TestVectors; -#endif - - // Open compressed video file. - std::unique_ptr video; - if (filename.substr(filename.length() - 3, 3) == "ivf") { - video.reset(new libvpx_test::IVFVideoSource(filename)); - } else { -#if CONFIG_WEBM_IO - video.reset(new libvpx_test::WebMVideoSource(filename)); -#else - fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n", - filename.c_str()); - return; -#endif - } - ASSERT_NE(video.get(), nullptr); - video->Init(); - - // Construct md5 file name. - const std::string md5_filename = filename + ".md5"; - OpenMD5File(md5_filename); - - // Decode frame, and check the md5 matching. - ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); -} - -#if CONFIG_WEBM_IO -TEST_F(ExternalFrameBufferTest, MinFrameBuffers) { - // Minimum number of external frame buffers for VP9 is - // #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS. - const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; - ASSERT_EQ(VPX_CODEC_OK, - SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer, - release_vp9_frame_buffer)); - ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames()); -} - -TEST_F(ExternalFrameBufferTest, EightJitterBuffers) { - // Number of buffers equals #VP9_MAXIMUM_REF_BUFFERS + - // #VPX_MAXIMUM_WORK_BUFFERS + eight jitter buffers. - const int jitter_buffers = 8; - const int num_buffers = - VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS + jitter_buffers; - ASSERT_EQ(VPX_CODEC_OK, - SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer, - release_vp9_frame_buffer)); - ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames()); -} - -TEST_F(ExternalFrameBufferTest, NotEnoughBuffers) { - // Minimum number of external frame buffers for VP9 is - // #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS. Most files will - // only use 5 frame buffers at one time. - const int num_buffers = 2; - ASSERT_EQ(VPX_CODEC_OK, - SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer, - release_vp9_frame_buffer)); - ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame()); - // Only run this on long clips. Decoding a very short clip will return - // VPX_CODEC_OK even with only 2 buffers. - ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeRemainingFrames()); -} - -TEST_F(ExternalFrameBufferTest, NoRelease) { - const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; - ASSERT_EQ(VPX_CODEC_OK, - SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer, - do_not_release_vp9_frame_buffer)); - ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame()); - ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeRemainingFrames()); -} - -TEST_F(ExternalFrameBufferTest, NullRealloc) { - const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; - ASSERT_EQ(VPX_CODEC_OK, - SetFrameBufferFunctions(num_buffers, get_vp9_zero_frame_buffer, - release_vp9_frame_buffer)); - ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeOneFrame()); -} - -TEST_F(ExternalFrameBufferTest, ReallocOneLessByte) { - const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; - ASSERT_EQ(VPX_CODEC_OK, SetFrameBufferFunctions( - num_buffers, get_vp9_one_less_byte_frame_buffer, - release_vp9_frame_buffer)); - ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeOneFrame()); -} - -TEST_F(ExternalFrameBufferTest, NullGetFunction) { - const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; - ASSERT_EQ( - VPX_CODEC_INVALID_PARAM, - SetFrameBufferFunctions(num_buffers, nullptr, release_vp9_frame_buffer)); -} - -TEST_F(ExternalFrameBufferTest, NullReleaseFunction) { - const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; - ASSERT_EQ( - VPX_CODEC_INVALID_PARAM, - SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer, nullptr)); -} - -TEST_F(ExternalFrameBufferTest, SetAfterDecode) { - const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; - ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame()); - ASSERT_EQ(VPX_CODEC_ERROR, - SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer, - release_vp9_frame_buffer)); -} - -TEST_F(ExternalFrameBufferNonRefTest, ReleaseNonRefFrameBuffer) { - const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; - ASSERT_EQ(VPX_CODEC_OK, - SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer, - release_vp9_frame_buffer)); - ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames()); - CheckFrameBufferRelease(); -} -#endif // CONFIG_WEBM_IO - -VP9_INSTANTIATE_TEST_SUITE( - ExternalFrameBufferMD5Test, - ::testing::ValuesIn(libvpx_test::kVP9TestVectors, - libvpx_test::kVP9TestVectors + - libvpx_test::kNumVP9TestVectors)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/fdct8x8_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/fdct8x8_test.cc deleted file mode 100644 index d8778f98..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/fdct8x8_test.cc +++ /dev/null @@ -1,792 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vp9_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "test/acm_random.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vp9/common/vp9_entropy.h" -#include "vp9/common/vp9_scan.h" -#include "vpx_config.h" -#include "vpx/vpx_codec.h" -#include "vpx/vpx_integer.h" -#include "vpx_ports/mem.h" - -using libvpx_test::ACMRandom; - -namespace { - -const int kNumCoeffs = 64; -const double kPi = 3.141592653589793238462643383279502884; - -const int kSignBiasMaxDiff255 = 1500; -const int kSignBiasMaxDiff15 = 10000; - -typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride); -typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride); -typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride, - int tx_type); -typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride, - int tx_type); - -typedef std::tuple Dct8x8Param; -typedef std::tuple Ht8x8Param; -typedef std::tuple Idct8x8Param; - -void reference_8x8_dct_1d(const double in[8], double out[8]) { - const double kInvSqrt2 = 0.707106781186547524400844362104; - for (int k = 0; k < 8; k++) { - out[k] = 0.0; - for (int n = 0; n < 8; n++) { - out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 16.0); - } - if (k == 0) out[k] = out[k] * kInvSqrt2; - } -} - -void reference_8x8_dct_2d(const int16_t input[kNumCoeffs], - double output[kNumCoeffs]) { - // First transform columns - for (int i = 0; i < 8; ++i) { - double temp_in[8], temp_out[8]; - for (int j = 0; j < 8; ++j) temp_in[j] = input[j * 8 + i]; - reference_8x8_dct_1d(temp_in, temp_out); - for (int j = 0; j < 8; ++j) output[j * 8 + i] = temp_out[j]; - } - // Then transform rows - for (int i = 0; i < 8; ++i) { - double temp_in[8], temp_out[8]; - for (int j = 0; j < 8; ++j) temp_in[j] = output[j + i * 8]; - reference_8x8_dct_1d(temp_in, temp_out); - // Scale by some magic number - for (int j = 0; j < 8; ++j) output[j + i * 8] = temp_out[j] * 2; - } -} - -void fdct8x8_ref(const int16_t *in, tran_low_t *out, int stride, - int /*tx_type*/) { - vpx_fdct8x8_c(in, out, stride); -} - -void fht8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) { - vp9_fht8x8_c(in, out, stride, tx_type); -} - -#if CONFIG_VP9_HIGHBITDEPTH -void idct8x8_10(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, 10); -} - -void idct8x8_12(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, 12); -} - -void iht8x8_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) { - vp9_highbd_iht8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 10); -} - -void iht8x8_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) { - vp9_highbd_iht8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 12); -} - -#if HAVE_SSE2 - -void idct8x8_12_add_10_c(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct8x8_12_add_c(in, CAST_TO_SHORTPTR(out), stride, 10); -} - -void idct8x8_12_add_12_c(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct8x8_12_add_c(in, CAST_TO_SHORTPTR(out), stride, 12); -} - -void idct8x8_12_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct8x8_12_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10); -} - -void idct8x8_12_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct8x8_12_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12); -} - -void idct8x8_64_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct8x8_64_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10); -} - -void idct8x8_64_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) { - vpx_highbd_idct8x8_64_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12); -} -#endif // HAVE_SSE2 -#endif // CONFIG_VP9_HIGHBITDEPTH - -// Visual Studio 2022 (cl.exe) targeting AArch64 with optimizations enabled -// produces invalid code in RunExtremalCheck() and RunInvAccuracyCheck(). -// See: -// https://developercommunity.visualstudio.com/t/1770-preview-1:-Misoptimization-for-AR/10369786 -// TODO(jzern): check the compiler version after a fix for the issue is -// released. -#if defined(_MSC_VER) && defined(_M_ARM64) && !defined(__clang__) -#pragma optimize("", off) -#endif -class FwdTrans8x8TestBase { - public: - virtual ~FwdTrans8x8TestBase() = default; - - protected: - virtual void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) = 0; - virtual void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) = 0; - - void RunSignBiasCheck() { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - DECLARE_ALIGNED(16, int16_t, test_input_block[64]); - DECLARE_ALIGNED(16, tran_low_t, test_output_block[64]); - int count_sign_block[64][2]; - const int count_test_block = 100000; - - memset(count_sign_block, 0, sizeof(count_sign_block)); - - for (int i = 0; i < count_test_block; ++i) { - // Initialize a test block with input range [-255, 255]. - for (int j = 0; j < 64; ++j) { - test_input_block[j] = ((rnd.Rand16() >> (16 - bit_depth_)) & mask_) - - ((rnd.Rand16() >> (16 - bit_depth_)) & mask_); - } - ASM_REGISTER_STATE_CHECK( - RunFwdTxfm(test_input_block, test_output_block, pitch_)); - - for (int j = 0; j < 64; ++j) { - if (test_output_block[j] < 0) { - ++count_sign_block[j][0]; - } else if (test_output_block[j] > 0) { - ++count_sign_block[j][1]; - } - } - } - - for (int j = 0; j < 64; ++j) { - const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]); - const int max_diff = kSignBiasMaxDiff255; - ASSERT_LT(diff, max_diff << (bit_depth_ - 8)) - << "Error: 8x8 FDCT/FHT has a sign bias > " - << 1. * max_diff / count_test_block * 100 << "%" - << " for input range [-255, 255] at index " << j - << " count0: " << count_sign_block[j][0] - << " count1: " << count_sign_block[j][1] << " diff: " << diff; - } - - memset(count_sign_block, 0, sizeof(count_sign_block)); - - for (int i = 0; i < count_test_block; ++i) { - // Initialize a test block with input range [-mask_ / 16, mask_ / 16]. - for (int j = 0; j < 64; ++j) { - test_input_block[j] = - ((rnd.Rand16() & mask_) >> 4) - ((rnd.Rand16() & mask_) >> 4); - } - ASM_REGISTER_STATE_CHECK( - RunFwdTxfm(test_input_block, test_output_block, pitch_)); - - for (int j = 0; j < 64; ++j) { - if (test_output_block[j] < 0) { - ++count_sign_block[j][0]; - } else if (test_output_block[j] > 0) { - ++count_sign_block[j][1]; - } - } - } - - for (int j = 0; j < 64; ++j) { - const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]); - const int max_diff = kSignBiasMaxDiff15; - ASSERT_LT(diff, max_diff << (bit_depth_ - 8)) - << "Error: 8x8 FDCT/FHT has a sign bias > " - << 1. * max_diff / count_test_block * 100 << "%" - << " for input range [-15, 15] at index " << j - << " count0: " << count_sign_block[j][0] - << " count1: " << count_sign_block[j][1] << " diff: " << diff; - } - } - - void RunRoundTripErrorCheck() { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - int max_error = 0; - int total_error = 0; - const int count_test_block = 100000; - DECLARE_ALIGNED(16, int16_t, test_input_block[64]); - DECLARE_ALIGNED(16, tran_low_t, test_temp_block[64]); - DECLARE_ALIGNED(16, uint8_t, dst[64]); - DECLARE_ALIGNED(16, uint8_t, src[64]); -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, dst16[64]); - DECLARE_ALIGNED(16, uint16_t, src16[64]); -#endif - - for (int i = 0; i < count_test_block; ++i) { - // Initialize a test block with input range [-mask_, mask_]. - for (int j = 0; j < 64; ++j) { - if (bit_depth_ == VPX_BITS_8) { - src[j] = rnd.Rand8(); - dst[j] = rnd.Rand8(); - test_input_block[j] = src[j] - dst[j]; -#if CONFIG_VP9_HIGHBITDEPTH - } else { - src16[j] = rnd.Rand16() & mask_; - dst16[j] = rnd.Rand16() & mask_; - test_input_block[j] = src16[j] - dst16[j]; -#endif - } - } - - ASM_REGISTER_STATE_CHECK( - RunFwdTxfm(test_input_block, test_temp_block, pitch_)); - for (int j = 0; j < 64; ++j) { - if (test_temp_block[j] > 0) { - test_temp_block[j] += 2; - test_temp_block[j] /= 4; - test_temp_block[j] *= 4; - } else { - test_temp_block[j] -= 2; - test_temp_block[j] /= 4; - test_temp_block[j] *= 4; - } - } - if (bit_depth_ == VPX_BITS_8) { - ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_)); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - ASM_REGISTER_STATE_CHECK( - RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_)); -#endif - } - - for (int j = 0; j < 64; ++j) { -#if CONFIG_VP9_HIGHBITDEPTH - const int diff = - bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j]; -#else - const int diff = dst[j] - src[j]; -#endif - const int error = diff * diff; - if (max_error < error) max_error = error; - total_error += error; - } - } - - ASSERT_GE(1 << 2 * (bit_depth_ - 8), max_error) - << "Error: 8x8 FDCT/IDCT or FHT/IHT has an individual" - << " roundtrip error > 1"; - - ASSERT_GE((count_test_block << 2 * (bit_depth_ - 8)) / 5, total_error) - << "Error: 8x8 FDCT/IDCT or FHT/IHT has average roundtrip " - << "error > 1/5 per block"; - } - - void RunExtremalCheck() { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - int max_error = 0; - int total_error = 0; - int total_coeff_error = 0; - const int count_test_block = 100000; - DECLARE_ALIGNED(16, int16_t, test_input_block[64]); - DECLARE_ALIGNED(16, tran_low_t, test_temp_block[64]); - DECLARE_ALIGNED(16, tran_low_t, ref_temp_block[64]); - DECLARE_ALIGNED(16, uint8_t, dst[64]); - DECLARE_ALIGNED(16, uint8_t, src[64]); -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, dst16[64]); - DECLARE_ALIGNED(16, uint16_t, src16[64]); -#endif - - for (int i = 0; i < count_test_block; ++i) { - // Initialize a test block with input range [-mask_, mask_]. - for (int j = 0; j < 64; ++j) { - if (bit_depth_ == VPX_BITS_8) { - if (i == 0) { - src[j] = 255; - dst[j] = 0; - } else if (i == 1) { - src[j] = 0; - dst[j] = 255; - } else { - src[j] = rnd.Rand8() % 2 ? 255 : 0; - dst[j] = rnd.Rand8() % 2 ? 255 : 0; - } - test_input_block[j] = src[j] - dst[j]; -#if CONFIG_VP9_HIGHBITDEPTH - } else { - if (i == 0) { - src16[j] = mask_; - dst16[j] = 0; - } else if (i == 1) { - src16[j] = 0; - dst16[j] = mask_; - } else { - src16[j] = rnd.Rand8() % 2 ? mask_ : 0; - dst16[j] = rnd.Rand8() % 2 ? mask_ : 0; - } - test_input_block[j] = src16[j] - dst16[j]; -#endif - } - } - - ASM_REGISTER_STATE_CHECK( - RunFwdTxfm(test_input_block, test_temp_block, pitch_)); - ASM_REGISTER_STATE_CHECK( - fwd_txfm_ref(test_input_block, ref_temp_block, pitch_, tx_type_)); - if (bit_depth_ == VPX_BITS_8) { - ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_)); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - ASM_REGISTER_STATE_CHECK( - RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_)); -#endif - } - - for (int j = 0; j < 64; ++j) { -#if CONFIG_VP9_HIGHBITDEPTH - const int diff = - bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j]; -#else - const int diff = dst[j] - src[j]; -#endif - const int error = diff * diff; - if (max_error < error) max_error = error; - total_error += error; - - const int coeff_diff = test_temp_block[j] - ref_temp_block[j]; - total_coeff_error += abs(coeff_diff); - } - - ASSERT_GE(1 << 2 * (bit_depth_ - 8), max_error) - << "Error: Extremal 8x8 FDCT/IDCT or FHT/IHT has" - << " an individual roundtrip error > 1"; - - ASSERT_GE((count_test_block << 2 * (bit_depth_ - 8)) / 5, total_error) - << "Error: Extremal 8x8 FDCT/IDCT or FHT/IHT has average" - << " roundtrip error > 1/5 per block"; - - ASSERT_EQ(0, total_coeff_error) - << "Error: Extremal 8x8 FDCT/FHT has" - << " overflow issues in the intermediate steps > 1"; - } - } - - void RunInvAccuracyCheck() { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 1000; - DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]); -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]); - DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); -#endif - - for (int i = 0; i < count_test_block; ++i) { - double out_r[kNumCoeffs]; - - // Initialize a test block with input range [-255, 255]. - for (int j = 0; j < kNumCoeffs; ++j) { - if (bit_depth_ == VPX_BITS_8) { - src[j] = rnd.Rand8() % 2 ? 255 : 0; - dst[j] = src[j] > 0 ? 0 : 255; - in[j] = src[j] - dst[j]; -#if CONFIG_VP9_HIGHBITDEPTH - } else { - src16[j] = rnd.Rand8() % 2 ? mask_ : 0; - dst16[j] = src16[j] > 0 ? 0 : mask_; - in[j] = src16[j] - dst16[j]; -#endif - } - } - - reference_8x8_dct_2d(in, out_r); - for (int j = 0; j < kNumCoeffs; ++j) { - coeff[j] = static_cast(round(out_r[j])); - } - - if (bit_depth_ == VPX_BITS_8) { - ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_)); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - ASM_REGISTER_STATE_CHECK( - RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_)); -#endif - } - - for (int j = 0; j < kNumCoeffs; ++j) { -#if CONFIG_VP9_HIGHBITDEPTH - const int diff = - bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j]; -#else - const int diff = dst[j] - src[j]; -#endif - const uint32_t error = diff * diff; - ASSERT_GE(1u << 2 * (bit_depth_ - 8), error) - << "Error: 8x8 IDCT has error " << error << " at index " << j; - } - } - } - - void RunFwdAccuracyCheck() { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 1000; - DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, coeff_r[kNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]); - - for (int i = 0; i < count_test_block; ++i) { - double out_r[kNumCoeffs]; - - // Initialize a test block with input range [-mask_, mask_]. - for (int j = 0; j < kNumCoeffs; ++j) { - in[j] = rnd.Rand8() % 2 == 0 ? mask_ : -mask_; - } - - RunFwdTxfm(in, coeff, pitch_); - reference_8x8_dct_2d(in, out_r); - for (int j = 0; j < kNumCoeffs; ++j) { - coeff_r[j] = static_cast(round(out_r[j])); - } - - for (int j = 0; j < kNumCoeffs; ++j) { - const int32_t diff = coeff[j] - coeff_r[j]; - const uint32_t error = diff * diff; - ASSERT_GE(9u << 2 * (bit_depth_ - 8), error) - << "Error: 8x8 DCT has error " << error << " at index " << j; - } - } - } - - void CompareInvReference(IdctFunc ref_txfm, int thresh) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 10000; - const int eob = 12; - DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); - DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]); -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); - DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]); -#endif - const int16_t *scan = vp9_default_scan_orders[TX_8X8].scan; - - for (int i = 0; i < count_test_block; ++i) { - for (int j = 0; j < kNumCoeffs; ++j) { - if (j < eob) { - // Random values less than the threshold, either positive or negative - coeff[scan[j]] = rnd(thresh) * (1 - 2 * (i % 2)); - } else { - coeff[scan[j]] = 0; - } - if (bit_depth_ == VPX_BITS_8) { - dst[j] = 0; - ref[j] = 0; -#if CONFIG_VP9_HIGHBITDEPTH - } else { - dst16[j] = 0; - ref16[j] = 0; -#endif - } - } - if (bit_depth_ == VPX_BITS_8) { - ref_txfm(coeff, ref, pitch_); - ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_)); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - ref_txfm(coeff, CAST_TO_BYTEPTR(ref16), pitch_); - ASM_REGISTER_STATE_CHECK( - RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_)); -#endif - } - - for (int j = 0; j < kNumCoeffs; ++j) { -#if CONFIG_VP9_HIGHBITDEPTH - const int diff = - bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j]; -#else - const int diff = dst[j] - ref[j]; -#endif - const uint32_t error = diff * diff; - ASSERT_EQ(0u, error) - << "Error: 8x8 IDCT has error " << error << " at index " << j; - } - } - } - int pitch_; - int tx_type_; - FhtFunc fwd_txfm_ref; - vpx_bit_depth_t bit_depth_; - int mask_; -}; -#if defined(_MSC_VER) && defined(_M_ARM64) && !defined(__clang__) -#pragma optimize("", on) -#endif - -class FwdTrans8x8DCT : public FwdTrans8x8TestBase, - public ::testing::TestWithParam { - public: - ~FwdTrans8x8DCT() override = default; - - void SetUp() override { - fwd_txfm_ = GET_PARAM(0); - inv_txfm_ = GET_PARAM(1); - tx_type_ = GET_PARAM(2); - pitch_ = 8; - fwd_txfm_ref = fdct8x8_ref; - bit_depth_ = GET_PARAM(3); - mask_ = (1 << bit_depth_) - 1; - } - - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) override { - fwd_txfm_(in, out, stride); - } - void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) override { - inv_txfm_(out, dst, stride); - } - - FdctFunc fwd_txfm_; - IdctFunc inv_txfm_; -}; - -TEST_P(FwdTrans8x8DCT, SignBiasCheck) { RunSignBiasCheck(); } - -TEST_P(FwdTrans8x8DCT, RoundTripErrorCheck) { RunRoundTripErrorCheck(); } - -TEST_P(FwdTrans8x8DCT, ExtremalCheck) { RunExtremalCheck(); } - -TEST_P(FwdTrans8x8DCT, FwdAccuracyCheck) { RunFwdAccuracyCheck(); } - -TEST_P(FwdTrans8x8DCT, InvAccuracyCheck) { RunInvAccuracyCheck(); } - -class FwdTrans8x8HT : public FwdTrans8x8TestBase, - public ::testing::TestWithParam { - public: - ~FwdTrans8x8HT() override = default; - - void SetUp() override { - fwd_txfm_ = GET_PARAM(0); - inv_txfm_ = GET_PARAM(1); - tx_type_ = GET_PARAM(2); - pitch_ = 8; - fwd_txfm_ref = fht8x8_ref; - bit_depth_ = GET_PARAM(3); - mask_ = (1 << bit_depth_) - 1; - } - - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) override { - fwd_txfm_(in, out, stride, tx_type_); - } - void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) override { - inv_txfm_(out, dst, stride, tx_type_); - } - - FhtFunc fwd_txfm_; - IhtFunc inv_txfm_; -}; - -TEST_P(FwdTrans8x8HT, SignBiasCheck) { RunSignBiasCheck(); } - -TEST_P(FwdTrans8x8HT, RoundTripErrorCheck) { RunRoundTripErrorCheck(); } - -TEST_P(FwdTrans8x8HT, ExtremalCheck) { RunExtremalCheck(); } - -#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -class InvTrans8x8DCT : public FwdTrans8x8TestBase, - public ::testing::TestWithParam { - public: - ~InvTrans8x8DCT() override = default; - - void SetUp() override { - ref_txfm_ = GET_PARAM(0); - inv_txfm_ = GET_PARAM(1); - thresh_ = GET_PARAM(2); - pitch_ = 8; - bit_depth_ = GET_PARAM(3); - mask_ = (1 << bit_depth_) - 1; - } - - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) override { - inv_txfm_(out, dst, stride); - } - void RunFwdTxfm(int16_t * /*out*/, tran_low_t * /*dst*/, - int /*stride*/) override {} - - IdctFunc ref_txfm_; - IdctFunc inv_txfm_; - int thresh_; -}; -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InvTrans8x8DCT); - -TEST_P(InvTrans8x8DCT, CompareReference) { - CompareInvReference(ref_txfm_, thresh_); -} -#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE - -using std::make_tuple; - -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - C, FwdTrans8x8DCT, - ::testing::Values( - make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c, 0, VPX_BITS_8), - make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_10, 0, VPX_BITS_10), - make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_12, 0, VPX_BITS_12))); -#else -INSTANTIATE_TEST_SUITE_P(C, FwdTrans8x8DCT, - ::testing::Values(make_tuple(&vpx_fdct8x8_c, - &vpx_idct8x8_64_add_c, 0, - VPX_BITS_8))); -#endif // CONFIG_VP9_HIGHBITDEPTH - -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - C, FwdTrans8x8HT, - ::testing::Values( - make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 0, VPX_BITS_8), - make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 0, VPX_BITS_10), - make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 1, VPX_BITS_10), - make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 2, VPX_BITS_10), - make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 3, VPX_BITS_10), - make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 0, VPX_BITS_12), - make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 1, VPX_BITS_12), - make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 2, VPX_BITS_12), - make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 3, VPX_BITS_12), - make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8), - make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8), - make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8))); -#else -INSTANTIATE_TEST_SUITE_P( - C, FwdTrans8x8HT, - ::testing::Values( - make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 0, VPX_BITS_8), - make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8), - make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8), - make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8))); -#endif // CONFIG_VP9_HIGHBITDEPTH - -#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P(NEON, FwdTrans8x8DCT, - ::testing::Values(make_tuple(&vpx_fdct8x8_neon, - &vpx_idct8x8_64_add_neon, - 0, VPX_BITS_8))); - -#if !CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - NEON, FwdTrans8x8HT, - ::testing::Values( - make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 0, VPX_BITS_8), - make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 1, VPX_BITS_8), - make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 2, VPX_BITS_8), - make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 3, VPX_BITS_8))); -#endif // !CONFIG_VP9_HIGHBITDEPTH -#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE - -#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P(SSE2, FwdTrans8x8DCT, - ::testing::Values(make_tuple(&vpx_fdct8x8_sse2, - &vpx_idct8x8_64_add_sse2, - 0, VPX_BITS_8))); -INSTANTIATE_TEST_SUITE_P( - SSE2, FwdTrans8x8HT, - ::testing::Values( - make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 0, VPX_BITS_8), - make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 1, VPX_BITS_8), - make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 2, VPX_BITS_8), - make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 3, VPX_BITS_8))); -#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE - -#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P( - SSE2, FwdTrans8x8DCT, - ::testing::Values(make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_c, 0, - VPX_BITS_8), - make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_64_add_10_sse2, - 12, VPX_BITS_10), - make_tuple(&vpx_highbd_fdct8x8_sse2, - &idct8x8_64_add_10_sse2, 12, VPX_BITS_10), - make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_64_add_12_sse2, - 12, VPX_BITS_12), - make_tuple(&vpx_highbd_fdct8x8_sse2, - &idct8x8_64_add_12_sse2, 12, VPX_BITS_12))); - -INSTANTIATE_TEST_SUITE_P( - SSE2, FwdTrans8x8HT, - ::testing::Values( - make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_c, 0, VPX_BITS_8), - make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8), - make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8), - make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8))); - -// Optimizations take effect at a threshold of 6201, so we use a value close to -// that to test both branches. -INSTANTIATE_TEST_SUITE_P( - SSE2, InvTrans8x8DCT, - ::testing::Values( - make_tuple(&idct8x8_12_add_10_c, &idct8x8_12_add_10_sse2, 6225, - VPX_BITS_10), - make_tuple(&idct8x8_10, &idct8x8_64_add_10_sse2, 6225, VPX_BITS_10), - make_tuple(&idct8x8_12_add_12_c, &idct8x8_12_add_12_sse2, 6225, - VPX_BITS_12), - make_tuple(&idct8x8_12, &idct8x8_64_add_12_sse2, 6225, VPX_BITS_12))); -#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE - -#if HAVE_SSSE3 && VPX_ARCH_X86_64 && !CONFIG_VP9_HIGHBITDEPTH && \ - !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P(SSSE3, FwdTrans8x8DCT, - ::testing::Values(make_tuple(&vpx_fdct8x8_ssse3, - &vpx_idct8x8_64_add_sse2, - 0, VPX_BITS_8))); -#endif - -#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P(MSA, FwdTrans8x8DCT, - ::testing::Values(make_tuple(&vpx_fdct8x8_msa, - &vpx_idct8x8_64_add_msa, - 0, VPX_BITS_8))); -INSTANTIATE_TEST_SUITE_P( - MSA, FwdTrans8x8HT, - ::testing::Values( - make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 0, VPX_BITS_8), - make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 1, VPX_BITS_8), - make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 2, VPX_BITS_8), - make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 3, VPX_BITS_8))); -#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE - -#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P(VSX, FwdTrans8x8DCT, - ::testing::Values(make_tuple(&vpx_fdct8x8_c, - &vpx_idct8x8_64_add_vsx, - 0, VPX_BITS_8))); -#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE - -#if HAVE_LSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -INSTANTIATE_TEST_SUITE_P(LSX, FwdTrans8x8DCT, - ::testing::Values(make_tuple(&vpx_fdct8x8_lsx, - &vpx_idct8x8_64_add_c, 0, - VPX_BITS_8))); -#endif // HAVE_LSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/frame_size_tests.cc b/presentation/src/main/cpp/third_party/libvpx/test/frame_size_tests.cc deleted file mode 100644 index a86ca9a4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/frame_size_tests.cc +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include - -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/register_state_check.h" -#include "test/video_source.h" -#include "vpx_config.h" - -namespace { - -class EncoderWithExpectedError : public ::libvpx_test::Encoder { - public: - EncoderWithExpectedError(vpx_codec_enc_cfg_t cfg, vpx_enc_deadline_t deadline, - const unsigned long init_flags, // NOLINT - ::libvpx_test::TwopassStatsStore *stats) - : ::libvpx_test::Encoder(cfg, deadline, init_flags, stats) {} - // This overrides with expected error code. - void EncodeFrame(::libvpx_test::VideoSource *video, - const unsigned long frame_flags, // NOLINT - const vpx_codec_err_t expected_err) { - if (video->img()) { - EncodeFrameInternal(*video, frame_flags, expected_err); - } else { - Flush(); - } - - // Handle twopass stats - ::libvpx_test::CxDataIterator iter = GetCxData(); - - while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) { - if (pkt->kind != VPX_CODEC_STATS_PKT) continue; - - stats_->Append(*pkt); - } - } - - protected: - void EncodeFrameInternal(const ::libvpx_test::VideoSource &video, - const unsigned long frame_flags, // NOLINT - const vpx_codec_err_t expected_err) { - vpx_codec_err_t res; - const vpx_image_t *img = video.img(); - - // Handle frame resizing - if (cfg_.g_w != img->d_w || cfg_.g_h != img->d_h) { - cfg_.g_w = img->d_w; - cfg_.g_h = img->d_h; - res = vpx_codec_enc_config_set(&encoder_, &cfg_); - ASSERT_EQ(res, VPX_CODEC_OK) << EncoderError(); - } - - // Encode the frame - API_REGISTER_STATE_CHECK(res = vpx_codec_encode(&encoder_, img, video.pts(), - video.duration(), - frame_flags, deadline_)); - ASSERT_EQ(expected_err, res) << EncoderError(); - } - - vpx_codec_iface_t *CodecInterface() const override { -#if CONFIG_VP9_ENCODER - return &vpx_codec_vp9_cx_algo; -#else - return nullptr; -#endif - } -}; - -class VP9FrameSizeTestsLarge : public ::libvpx_test::EncoderTest, - public ::testing::Test { - protected: - VP9FrameSizeTestsLarge() - : EncoderTest(&::libvpx_test::kVP9), expected_res_(VPX_CODEC_OK) {} - ~VP9FrameSizeTestsLarge() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - } - - bool HandleDecodeResult(const vpx_codec_err_t res_dec, - const libvpx_test::VideoSource & /*video*/, - libvpx_test::Decoder *decoder) override { - EXPECT_EQ(expected_res_, res_dec) << decoder->DecodeError(); - return !::testing::Test::HasFailure(); - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, 7); - encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); - encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7); - encoder->Control(VP8E_SET_ARNR_STRENGTH, 5); - encoder->Control(VP8E_SET_ARNR_TYPE, 3); - } - } - - using ::libvpx_test::EncoderTest::RunLoop; - virtual void RunLoop(::libvpx_test::VideoSource *video, - const vpx_codec_err_t expected_err) { - stats_.Reset(); - - ASSERT_TRUE(passes_ == 1 || passes_ == 2); - for (unsigned int pass = 0; pass < passes_; pass++) { - vpx_codec_pts_t last_pts = 0; - - if (passes_ == 1) { - cfg_.g_pass = VPX_RC_ONE_PASS; - } else if (pass == 0) { - cfg_.g_pass = VPX_RC_FIRST_PASS; - } else { - cfg_.g_pass = VPX_RC_LAST_PASS; - } - - BeginPassHook(pass); - std::unique_ptr encoder( - new EncoderWithExpectedError(cfg_, deadline_, init_flags_, &stats_)); - ASSERT_NE(encoder.get(), nullptr); - - ASSERT_NO_FATAL_FAILURE(video->Begin()); - encoder->InitEncoder(video); - ASSERT_FALSE(::testing::Test::HasFatalFailure()); - for (bool again = true; again; video->Next()) { - again = (video->img() != nullptr); - - PreEncodeFrameHook(video, encoder.get()); - encoder->EncodeFrame(video, frame_flags_, expected_err); - - PostEncodeFrameHook(encoder.get()); - - ::libvpx_test::CxDataIterator iter = encoder->GetCxData(); - - while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) { - pkt = MutateEncoderOutputHook(pkt); - again = true; - switch (pkt->kind) { - case VPX_CODEC_CX_FRAME_PKT: - ASSERT_GE(pkt->data.frame.pts, last_pts); - last_pts = pkt->data.frame.pts; - FramePktHook(pkt); - break; - - case VPX_CODEC_PSNR_PKT: PSNRPktHook(pkt); break; - case VPX_CODEC_STATS_PKT: StatsPktHook(pkt); break; - default: break; - } - } - - if (!Continue()) break; - } - - EndPassHook(); - - if (!Continue()) break; - } - } - - vpx_codec_err_t expected_res_; -}; - -TEST_F(VP9FrameSizeTestsLarge, TestInvalidSizes) { -#ifdef CHROMIUM - GTEST_SKIP() << "16K framebuffers are not supported by Chromium's allocator."; -#else - ::libvpx_test::RandomVideoSource video; - -#if CONFIG_SIZE_LIMIT - video.SetSize(DECODE_WIDTH_LIMIT + 16, DECODE_HEIGHT_LIMIT + 16); - video.set_limit(2); - expected_res_ = VPX_CODEC_MEM_ERROR; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video, expected_res_)); -#endif - -#endif -} - -TEST_F(VP9FrameSizeTestsLarge, ValidSizes) { -#ifdef CHROMIUM - GTEST_SKIP() - << "Under Chromium's configuration the allocator is unable to provide" - "the space required for a single frame at the maximum resolution."; -#else - ::libvpx_test::RandomVideoSource video; - -#if CONFIG_SIZE_LIMIT - video.SetSize(DECODE_WIDTH_LIMIT, DECODE_HEIGHT_LIMIT); - video.set_limit(2); - expected_res_ = VPX_CODEC_OK; - ASSERT_NO_FATAL_FAILURE(::libvpx_test::EncoderTest::RunLoop(&video)); -#else -// This test produces a pretty large single frame allocation, (roughly -// 25 megabits). The encoder allocates a good number of these frames -// one for each lag in frames (for 2 pass), and then one for each possible -// reference buffer (8) - we can end up with up to 30 buffers of roughly this -// size or almost 1 gig of memory. -// In total the allocations will exceed 2GiB which may cause a failure with -// mingw + wine, use a smaller size in that case. -#if defined(_WIN32) && !defined(_WIN64) - video.SetSize(4096, 3072); -#else - video.SetSize(4096, 4096); -#endif - video.set_limit(2); - expected_res_ = VPX_CODEC_OK; - ASSERT_NO_FATAL_FAILURE(::libvpx_test::EncoderTest::RunLoop(&video)); -#endif - -#endif // defined(CHROMIUM) -} - -TEST_F(VP9FrameSizeTestsLarge, OneByOneVideo) { - ::libvpx_test::RandomVideoSource video; - - video.SetSize(1, 1); - video.set_limit(2); - expected_res_ = VPX_CODEC_OK; - ASSERT_NO_FATAL_FAILURE(::libvpx_test::EncoderTest::RunLoop(&video)); -} -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/hadamard_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/hadamard_test.cc deleted file mode 100644 index 12dc3fd8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/hadamard_test.cc +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "gtest/gtest.h" - -#include "./vpx_dsp_rtcd.h" -#include "vpx_ports/vpx_timer.h" - -#include "test/acm_random.h" -#include "test/register_state_check.h" -#include "vpx_config.h" - -namespace { - -using ::libvpx_test::ACMRandom; - -typedef void (*HadamardFunc)(const int16_t *a, ptrdiff_t a_stride, - tran_low_t *b); - -void hadamard_loop(const tran_low_t *a, tran_low_t *out) { - tran_low_t b[8]; - for (int i = 0; i < 8; i += 2) { - b[i + 0] = a[i * 8] + a[(i + 1) * 8]; - b[i + 1] = a[i * 8] - a[(i + 1) * 8]; - } - tran_low_t c[8]; - for (int i = 0; i < 8; i += 4) { - c[i + 0] = b[i + 0] + b[i + 2]; - c[i + 1] = b[i + 1] + b[i + 3]; - c[i + 2] = b[i + 0] - b[i + 2]; - c[i + 3] = b[i + 1] - b[i + 3]; - } - out[0] = c[0] + c[4]; - out[7] = c[1] + c[5]; - out[3] = c[2] + c[6]; - out[4] = c[3] + c[7]; - out[2] = c[0] - c[4]; - out[6] = c[1] - c[5]; - out[1] = c[2] - c[6]; - out[5] = c[3] - c[7]; -} - -void reference_hadamard8x8(const int16_t *a, int a_stride, tran_low_t *b) { - tran_low_t input[64]; - tran_low_t buf[64]; - for (int i = 0; i < 8; ++i) { - for (int j = 0; j < 8; ++j) { - input[i * 8 + j] = static_cast(a[i * a_stride + j]); - } - } - for (int i = 0; i < 8; ++i) hadamard_loop(input + i, buf + i * 8); - for (int i = 0; i < 8; ++i) hadamard_loop(buf + i, b + i * 8); -} - -void reference_hadamard16x16(const int16_t *a, int a_stride, tran_low_t *b) { - /* The source is a 16x16 block. The destination is rearranged to 8x32. - * Input is 9 bit. */ - reference_hadamard8x8(a + 0 + 0 * a_stride, a_stride, b + 0); - reference_hadamard8x8(a + 8 + 0 * a_stride, a_stride, b + 64); - reference_hadamard8x8(a + 0 + 8 * a_stride, a_stride, b + 128); - reference_hadamard8x8(a + 8 + 8 * a_stride, a_stride, b + 192); - - /* Overlay the 8x8 blocks and combine. */ - for (int i = 0; i < 64; ++i) { - /* 8x8 steps the range up to 15 bits. */ - const tran_low_t a0 = b[0]; - const tran_low_t a1 = b[64]; - const tran_low_t a2 = b[128]; - const tran_low_t a3 = b[192]; - - /* Prevent the result from escaping int16_t. */ - const tran_low_t b0 = (a0 + a1) >> 1; - const tran_low_t b1 = (a0 - a1) >> 1; - const tran_low_t b2 = (a2 + a3) >> 1; - const tran_low_t b3 = (a2 - a3) >> 1; - - /* Store a 16 bit value. */ - b[0] = b0 + b2; - b[64] = b1 + b3; - b[128] = b0 - b2; - b[192] = b1 - b3; - - ++b; - } -} - -void reference_hadamard32x32(const int16_t *a, int a_stride, tran_low_t *b) { - reference_hadamard16x16(a + 0 + 0 * a_stride, a_stride, b + 0); - reference_hadamard16x16(a + 16 + 0 * a_stride, a_stride, b + 256); - reference_hadamard16x16(a + 0 + 16 * a_stride, a_stride, b + 512); - reference_hadamard16x16(a + 16 + 16 * a_stride, a_stride, b + 768); - - for (int i = 0; i < 256; ++i) { - const tran_low_t a0 = b[0]; - const tran_low_t a1 = b[256]; - const tran_low_t a2 = b[512]; - const tran_low_t a3 = b[768]; - - const tran_low_t b0 = (a0 + a1) >> 2; - const tran_low_t b1 = (a0 - a1) >> 2; - const tran_low_t b2 = (a2 + a3) >> 2; - const tran_low_t b3 = (a2 - a3) >> 2; - - b[0] = b0 + b2; - b[256] = b1 + b3; - b[512] = b0 - b2; - b[768] = b1 - b3; - - ++b; - } -} - -struct HadamardFuncWithSize { - HadamardFuncWithSize(HadamardFunc f, int s) : func(f), block_size(s) {} - HadamardFunc func; - int block_size; -}; - -std::ostream &operator<<(std::ostream &os, const HadamardFuncWithSize &hfs) { - return os << "block size: " << hfs.block_size; -} - -class HadamardTestBase : public ::testing::TestWithParam { - public: - void SetUp() override { - h_func_ = GetParam().func; - bwh_ = GetParam().block_size; - block_size_ = bwh_ * bwh_; - rnd_.Reset(ACMRandom::DeterministicSeed()); - } - - // The Rand() function generates values in the range [-((1 << BitDepth) - 1), - // (1 << BitDepth) - 1]. This is because the input to the Hadamard transform - // is the residual pixel, which is defined as 'source pixel - predicted - // pixel'. Source pixel and predicted pixel take values in the range - // [0, (1 << BitDepth) - 1] and thus the residual pixel ranges from - // -((1 << BitDepth) - 1) to ((1 << BitDepth) - 1). - virtual int16_t Rand() = 0; - - void ReferenceHadamard(const int16_t *a, int a_stride, tran_low_t *b, - int bwh) { - if (bwh == 32) - reference_hadamard32x32(a, a_stride, b); - else if (bwh == 16) - reference_hadamard16x16(a, a_stride, b); - else - reference_hadamard8x8(a, a_stride, b); - } - - void CompareReferenceRandom() { - const int kMaxBlockSize = 32 * 32; - DECLARE_ALIGNED(16, int16_t, a[kMaxBlockSize]); - DECLARE_ALIGNED(16, tran_low_t, b[kMaxBlockSize]); - memset(a, 0, sizeof(a)); - memset(b, 0, sizeof(b)); - - tran_low_t b_ref[kMaxBlockSize]; - memset(b_ref, 0, sizeof(b_ref)); - - for (int i = 0; i < block_size_; ++i) a[i] = Rand(); - - ReferenceHadamard(a, bwh_, b_ref, bwh_); - ASM_REGISTER_STATE_CHECK(h_func_(a, bwh_, b)); - - // The order of the output is not important. Sort before checking. - std::sort(b, b + block_size_); - std::sort(b_ref, b_ref + block_size_); - EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b))); - } - - void ExtremeValuesTest() { - const int kMaxBlockSize = 32 * 32; - DECLARE_ALIGNED(16, int16_t, input_extreme_block[kMaxBlockSize]); - DECLARE_ALIGNED(16, tran_low_t, b[kMaxBlockSize]); - memset(b, 0, sizeof(b)); - - tran_low_t b_ref[kMaxBlockSize]; - memset(b_ref, 0, sizeof(b_ref)); - - for (int i = 0; i < 2; ++i) { - // Initialize a test block with input range [-mask_, mask_]. - const int sign = (i == 0) ? 1 : -1; - for (int j = 0; j < kMaxBlockSize; ++j) - input_extreme_block[j] = sign * 255; - - ReferenceHadamard(input_extreme_block, bwh_, b_ref, bwh_); - ASM_REGISTER_STATE_CHECK(h_func_(input_extreme_block, bwh_, b)); - - // The order of the output is not important. Sort before checking. - std::sort(b, b + block_size_); - std::sort(b_ref, b_ref + block_size_); - EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b))); - } - } - - void VaryStride() { - const int kMaxBlockSize = 32 * 32; - DECLARE_ALIGNED(16, int16_t, a[kMaxBlockSize * 8]); - DECLARE_ALIGNED(16, tran_low_t, b[kMaxBlockSize]); - memset(a, 0, sizeof(a)); - for (int i = 0; i < block_size_ * 8; ++i) a[i] = Rand(); - - tran_low_t b_ref[kMaxBlockSize]; - for (int i = 8; i < 64; i += 8) { - memset(b, 0, sizeof(b)); - memset(b_ref, 0, sizeof(b_ref)); - - ReferenceHadamard(a, i, b_ref, bwh_); - ASM_REGISTER_STATE_CHECK(h_func_(a, i, b)); - - // The order of the output is not important. Sort before checking. - std::sort(b, b + block_size_); - std::sort(b_ref, b_ref + block_size_); - EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b))); - } - } - - void SpeedTest(int times) { - const int kMaxBlockSize = 32 * 32; - DECLARE_ALIGNED(16, int16_t, input[kMaxBlockSize]); - DECLARE_ALIGNED(16, tran_low_t, output[kMaxBlockSize]); - memset(input, 1, sizeof(input)); - memset(output, 0, sizeof(output)); - - vpx_usec_timer timer; - vpx_usec_timer_start(&timer); - for (int i = 0; i < times; ++i) { - h_func_(input, bwh_, output); - } - vpx_usec_timer_mark(&timer); - - const int elapsed_time = static_cast(vpx_usec_timer_elapsed(&timer)); - printf("Hadamard%dx%d[%12d runs]: %d us\n", bwh_, bwh_, times, - elapsed_time); - } - - protected: - int bwh_; - int block_size_; - HadamardFunc h_func_; - ACMRandom rnd_; -}; - -class HadamardLowbdTest : public HadamardTestBase { - protected: - // Use values between -255 (0xFF01) and 255 (0x00FF) - int16_t Rand() override { - int16_t src = rnd_.Rand8(); - int16_t pred = rnd_.Rand8(); - return src - pred; - } -}; - -TEST_P(HadamardLowbdTest, CompareReferenceRandom) { CompareReferenceRandom(); } - -TEST_P(HadamardLowbdTest, ExtremeValuesTest) { ExtremeValuesTest(); } - -TEST_P(HadamardLowbdTest, VaryStride) { VaryStride(); } - -TEST_P(HadamardLowbdTest, DISABLED_Speed) { - SpeedTest(10); - SpeedTest(10000); - SpeedTest(10000000); -} - -INSTANTIATE_TEST_SUITE_P( - C, HadamardLowbdTest, - ::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_c, 8), - HadamardFuncWithSize(&vpx_hadamard_16x16_c, 16), - HadamardFuncWithSize(&vpx_hadamard_32x32_c, 32))); - -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P( - SSE2, HadamardLowbdTest, - ::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_sse2, 8), - HadamardFuncWithSize(&vpx_hadamard_16x16_sse2, 16), - HadamardFuncWithSize(&vpx_hadamard_32x32_sse2, 32))); -#endif // HAVE_SSE2 - -#if HAVE_AVX2 -INSTANTIATE_TEST_SUITE_P( - AVX2, HadamardLowbdTest, - ::testing::Values(HadamardFuncWithSize(&vpx_hadamard_16x16_avx2, 16), - HadamardFuncWithSize(&vpx_hadamard_32x32_avx2, 32))); -#endif // HAVE_AVX2 - -#if HAVE_SSSE3 && VPX_ARCH_X86_64 -INSTANTIATE_TEST_SUITE_P( - SSSE3, HadamardLowbdTest, - ::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_ssse3, 8))); -#endif // HAVE_SSSE3 && VPX_ARCH_X86_64 - -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P( - NEON, HadamardLowbdTest, - ::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_neon, 8), - HadamardFuncWithSize(&vpx_hadamard_16x16_neon, 16), - HadamardFuncWithSize(&vpx_hadamard_32x32_neon, 32))); -#endif // HAVE_NEON - -// TODO(jingning): Remove highbitdepth flag when the SIMD functions are -// in place and turn on the unit test. -#if !CONFIG_VP9_HIGHBITDEPTH -#if HAVE_MSA -INSTANTIATE_TEST_SUITE_P( - MSA, HadamardLowbdTest, - ::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_msa, 8), - HadamardFuncWithSize(&vpx_hadamard_16x16_msa, 16))); -#endif // HAVE_MSA -#endif // !CONFIG_VP9_HIGHBITDEPTH - -#if HAVE_VSX -INSTANTIATE_TEST_SUITE_P( - VSX, HadamardLowbdTest, - ::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_vsx, 8), - HadamardFuncWithSize(&vpx_hadamard_16x16_vsx, 16))); -#endif // HAVE_VSX - -#if HAVE_LSX -INSTANTIATE_TEST_SUITE_P( - LSX, HadamardLowbdTest, - ::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_lsx, 8), - HadamardFuncWithSize(&vpx_hadamard_16x16_lsx, 16))); -#endif // HAVE_LSX - -#if CONFIG_VP9_HIGHBITDEPTH -class HadamardHighbdTest : public HadamardTestBase { - protected: - // Use values between -4095 (0xF001) and 4095 (0x0FFF) - int16_t Rand() override { - int16_t src = rnd_.Rand12(); - int16_t pred = rnd_.Rand12(); - return src - pred; - } -}; - -TEST_P(HadamardHighbdTest, CompareReferenceRandom) { CompareReferenceRandom(); } - -TEST_P(HadamardHighbdTest, VaryStride) { VaryStride(); } - -TEST_P(HadamardHighbdTest, DISABLED_Speed) { - SpeedTest(10); - SpeedTest(10000); - SpeedTest(10000000); -} - -INSTANTIATE_TEST_SUITE_P( - C, HadamardHighbdTest, - ::testing::Values(HadamardFuncWithSize(&vpx_highbd_hadamard_8x8_c, 8), - HadamardFuncWithSize(&vpx_highbd_hadamard_16x16_c, 16), - HadamardFuncWithSize(&vpx_highbd_hadamard_32x32_c, 32))); - -#if HAVE_AVX2 -INSTANTIATE_TEST_SUITE_P( - AVX2, HadamardHighbdTest, - ::testing::Values(HadamardFuncWithSize(&vpx_highbd_hadamard_8x8_avx2, 8), - HadamardFuncWithSize(&vpx_highbd_hadamard_16x16_avx2, 16), - HadamardFuncWithSize(&vpx_highbd_hadamard_32x32_avx2, - 32))); -#endif // HAVE_AVX2 - -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P( - NEON, HadamardHighbdTest, - ::testing::Values(HadamardFuncWithSize(&vpx_highbd_hadamard_8x8_neon, 8), - HadamardFuncWithSize(&vpx_highbd_hadamard_16x16_neon, 16), - HadamardFuncWithSize(&vpx_highbd_hadamard_32x32_neon, - 32))); -#endif - -#endif // CONFIG_VP9_HIGHBITDEPTH -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/i420_video_source.h b/presentation/src/main/cpp/third_party/libvpx/test/i420_video_source.h deleted file mode 100644 index 97473b5c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/i420_video_source.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_TEST_I420_VIDEO_SOURCE_H_ -#define VPX_TEST_I420_VIDEO_SOURCE_H_ -#include -#include -#include - -#include "test/yuv_video_source.h" - -namespace libvpx_test { - -// This class extends VideoSource to allow parsing of raw yv12 -// so that we can do actual file encodes. -class I420VideoSource : public YUVVideoSource { - public: - I420VideoSource(const std::string &file_name, unsigned int width, - unsigned int height, int rate_numerator, int rate_denominator, - unsigned int start, int limit) - : YUVVideoSource(file_name, VPX_IMG_FMT_I420, width, height, - rate_numerator, rate_denominator, start, limit) {} -}; - -} // namespace libvpx_test - -#endif // VPX_TEST_I420_VIDEO_SOURCE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/idct8x8_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/idct8x8_test.cc deleted file mode 100644 index 28ab257e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/idct8x8_test.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vpx_dsp_rtcd.h" -#include "test/acm_random.h" -#include "vpx/vpx_integer.h" - -using libvpx_test::ACMRandom; - -namespace { - -void reference_dct_1d(double input[8], double output[8]) { - const double kPi = 3.141592653589793238462643383279502884; - const double kInvSqrt2 = 0.707106781186547524400844362104; - for (int k = 0; k < 8; k++) { - output[k] = 0.0; - for (int n = 0; n < 8; n++) { - output[k] += input[n] * cos(kPi * (2 * n + 1) * k / 16.0); - } - if (k == 0) output[k] = output[k] * kInvSqrt2; - } -} - -void reference_dct_2d(int16_t input[64], double output[64]) { - // First transform columns - for (int i = 0; i < 8; ++i) { - double temp_in[8], temp_out[8]; - for (int j = 0; j < 8; ++j) temp_in[j] = input[j * 8 + i]; - reference_dct_1d(temp_in, temp_out); - for (int j = 0; j < 8; ++j) output[j * 8 + i] = temp_out[j]; - } - // Then transform rows - for (int i = 0; i < 8; ++i) { - double temp_in[8], temp_out[8]; - for (int j = 0; j < 8; ++j) temp_in[j] = output[j + i * 8]; - reference_dct_1d(temp_in, temp_out); - for (int j = 0; j < 8; ++j) output[j + i * 8] = temp_out[j]; - } - // Scale by some magic number - for (int i = 0; i < 64; ++i) output[i] *= 2; -} - -TEST(VP9Idct8x8Test, AccuracyCheck) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 10000; - for (int i = 0; i < count_test_block; ++i) { - int16_t input[64]; - tran_low_t coeff[64]; - double output_r[64]; - uint8_t dst[64], src[64]; - - for (int j = 0; j < 64; ++j) { - src[j] = rnd.Rand8(); - dst[j] = rnd.Rand8(); - } - // Initialize a test block with input range [-255, 255]. - for (int j = 0; j < 64; ++j) input[j] = src[j] - dst[j]; - - reference_dct_2d(input, output_r); - for (int j = 0; j < 64; ++j) { - coeff[j] = static_cast(round(output_r[j])); - } - vpx_idct8x8_64_add_c(coeff, dst, 8); - for (int j = 0; j < 64; ++j) { - const int diff = dst[j] - src[j]; - const int error = diff * diff; - EXPECT_GE(1, error) << "Error: 8x8 FDCT/IDCT has error " << error - << " at index " << j; - } - } -} - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/idct_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/idct_test.cc deleted file mode 100644 index 6f171e8f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/idct_test.cc +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "./vp8_rtcd.h" - -#include "gtest/gtest.h" - -#include "test/buffer.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "vpx/vpx_integer.h" - -typedef void (*IdctFunc)(int16_t *input, unsigned char *pred_ptr, - int pred_stride, unsigned char *dst_ptr, - int dst_stride); -namespace { - -using libvpx_test::Buffer; - -class IDCTTest : public ::testing::TestWithParam { - protected: - void SetUp() override { - UUT = GetParam(); - - input = new Buffer(4, 4, 0); - ASSERT_NE(input, nullptr); - ASSERT_TRUE(input->Init()); - predict = new Buffer(4, 4, 3); - ASSERT_NE(predict, nullptr); - ASSERT_TRUE(predict->Init()); - output = new Buffer(4, 4, 3); - ASSERT_NE(output, nullptr); - ASSERT_TRUE(output->Init()); - } - - void TearDown() override { - delete input; - delete predict; - delete output; - libvpx_test::ClearSystemState(); - } - - IdctFunc UUT; - Buffer *input; - Buffer *predict; - Buffer *output; -}; - -TEST_P(IDCTTest, TestAllZeros) { - // When the input is '0' the output will be '0'. - input->Set(0); - predict->Set(0); - output->Set(0); - - ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(), - predict->stride(), output->TopLeftPixel(), - output->stride())); - - ASSERT_TRUE(input->CheckValues(0)); - ASSERT_TRUE(input->CheckPadding()); - ASSERT_TRUE(output->CheckValues(0)); - ASSERT_TRUE(output->CheckPadding()); -} - -TEST_P(IDCTTest, TestAllOnes) { - input->Set(0); - ASSERT_NE(input->TopLeftPixel(), nullptr); - // When the first element is '4' it will fill the output buffer with '1'. - input->TopLeftPixel()[0] = 4; - predict->Set(0); - output->Set(0); - - ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(), - predict->stride(), output->TopLeftPixel(), - output->stride())); - - ASSERT_TRUE(output->CheckValues(1)); - ASSERT_TRUE(output->CheckPadding()); -} - -TEST_P(IDCTTest, TestAddOne) { - // Set the transform output to '1' and make sure it gets added to the - // prediction buffer. - input->Set(0); - ASSERT_NE(input->TopLeftPixel(), nullptr); - input->TopLeftPixel()[0] = 4; - output->Set(0); - - uint8_t *pred = predict->TopLeftPixel(); - for (int y = 0; y < 4; ++y) { - for (int x = 0; x < 4; ++x) { - pred[y * predict->stride() + x] = y * 4 + x; - } - } - - ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(), - predict->stride(), output->TopLeftPixel(), - output->stride())); - - uint8_t const *out = output->TopLeftPixel(); - for (int y = 0; y < 4; ++y) { - for (int x = 0; x < 4; ++x) { - EXPECT_EQ(1 + y * 4 + x, out[y * output->stride() + x]); - } - } - - if (HasFailure()) { - output->DumpBuffer(); - } - - ASSERT_TRUE(output->CheckPadding()); -} - -TEST_P(IDCTTest, TestWithData) { - // Test a single known input. - predict->Set(0); - - int16_t *in = input->TopLeftPixel(); - for (int y = 0; y < 4; ++y) { - for (int x = 0; x < 4; ++x) { - in[y * input->stride() + x] = y * 4 + x; - } - } - - ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(), - predict->stride(), output->TopLeftPixel(), - output->stride())); - - uint8_t *out = output->TopLeftPixel(); - for (int y = 0; y < 4; ++y) { - for (int x = 0; x < 4; ++x) { - switch (y * 4 + x) { - case 0: EXPECT_EQ(11, out[y * output->stride() + x]); break; - case 2: - case 5: - case 8: EXPECT_EQ(3, out[y * output->stride() + x]); break; - case 10: EXPECT_EQ(1, out[y * output->stride() + x]); break; - default: EXPECT_EQ(0, out[y * output->stride() + x]); - } - } - } - - if (HasFailure()) { - output->DumpBuffer(); - } - - ASSERT_TRUE(output->CheckPadding()); -} - -INSTANTIATE_TEST_SUITE_P(C, IDCTTest, - ::testing::Values(vp8_short_idct4x4llm_c)); - -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P(NEON, IDCTTest, - ::testing::Values(vp8_short_idct4x4llm_neon)); -#endif // HAVE_NEON - -#if HAVE_MMX -INSTANTIATE_TEST_SUITE_P(MMX, IDCTTest, - ::testing::Values(vp8_short_idct4x4llm_mmx)); -#endif // HAVE_MMX - -#if HAVE_MSA -INSTANTIATE_TEST_SUITE_P(MSA, IDCTTest, - ::testing::Values(vp8_short_idct4x4llm_msa)); -#endif // HAVE_MSA - -#if HAVE_MMI -INSTANTIATE_TEST_SUITE_P(MMI, IDCTTest, - ::testing::Values(vp8_short_idct4x4llm_mmi)); -#endif // HAVE_MMI -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/init_vpx_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/init_vpx_test.cc deleted file mode 100644 index 11e3863c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/init_vpx_test.cc +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "test/init_vpx_test.h" - -#include "./vpx_config.h" - -#if !CONFIG_SHARED -#include -#include "gtest/gtest.h" -#if VPX_ARCH_ARM -#include "vpx_ports/arm.h" -#endif -#if VPX_ARCH_X86 || VPX_ARCH_X86_64 -#include "vpx_ports/x86.h" -#endif -extern "C" { -#if CONFIG_VP8 -extern void vp8_rtcd(); -#endif // CONFIG_VP8 -#if CONFIG_VP9 -extern void vp9_rtcd(); -#endif // CONFIG_VP9 -extern void vpx_dsp_rtcd(); -extern void vpx_scale_rtcd(); -} - -#if VPX_ARCH_ARM || VPX_ARCH_X86 || VPX_ARCH_X86_64 -static void append_negative_gtest_filter(const char *str) { - std::string filter = GTEST_FLAG_GET(filter); - // Negative patterns begin with one '-' followed by a ':' separated list. - if (filter.find('-') == std::string::npos) filter += '-'; - filter += str; - GTEST_FLAG_SET(filter, filter); -} -#endif // VPX_ARCH_ARM || VPX_ARCH_X86 || VPX_ARCH_X86_64 -#endif // !CONFIG_SHARED - -namespace libvpx_test { -void init_vpx_test() { -#if !CONFIG_SHARED -#if VPX_ARCH_AARCH64 - const int caps = arm_cpu_caps(); - if (!(caps & HAS_NEON_DOTPROD)) { - append_negative_gtest_filter(":NEON_DOTPROD.*:NEON_DOTPROD/*"); - } - if (!(caps & HAS_NEON_I8MM)) { - append_negative_gtest_filter(":NEON_I8MM.*:NEON_I8MM/*"); - } - if (!(caps & HAS_SVE)) { - append_negative_gtest_filter(":SVE.*:SVE/*"); - } - if (!(caps & HAS_SVE2)) { - append_negative_gtest_filter(":SVE2.*:SVE2/*"); - } -#elif VPX_ARCH_ARM - const int caps = arm_cpu_caps(); - if (!(caps & HAS_NEON)) append_negative_gtest_filter(":NEON.*:NEON/*"); -#endif // VPX_ARCH_ARM - -#if VPX_ARCH_X86 || VPX_ARCH_X86_64 - const int simd_caps = x86_simd_caps(); - if (!(simd_caps & HAS_MMX)) append_negative_gtest_filter(":MMX.*:MMX/*"); - if (!(simd_caps & HAS_SSE)) append_negative_gtest_filter(":SSE.*:SSE/*"); - if (!(simd_caps & HAS_SSE2)) append_negative_gtest_filter(":SSE2.*:SSE2/*"); - if (!(simd_caps & HAS_SSE3)) append_negative_gtest_filter(":SSE3.*:SSE3/*"); - if (!(simd_caps & HAS_SSSE3)) { - append_negative_gtest_filter(":SSSE3.*:SSSE3/*"); - } - if (!(simd_caps & HAS_SSE4_1)) { - append_negative_gtest_filter(":SSE4_1.*:SSE4_1/*"); - } - if (!(simd_caps & HAS_AVX)) append_negative_gtest_filter(":AVX.*:AVX/*"); - if (!(simd_caps & HAS_AVX2)) append_negative_gtest_filter(":AVX2.*:AVX2/*"); - if (!(simd_caps & HAS_AVX512)) { - append_negative_gtest_filter(":AVX512.*:AVX512/*"); - } -#endif // VPX_ARCH_X86 || VPX_ARCH_X86_64 - - // Shared library builds don't support whitebox tests that exercise internal - // symbols. -#if CONFIG_VP8 - vp8_rtcd(); -#endif // CONFIG_VP8 -#if CONFIG_VP9 - vp9_rtcd(); -#endif // CONFIG_VP9 - vpx_dsp_rtcd(); - vpx_scale_rtcd(); -#endif // !CONFIG_SHARED -} -} // namespace libvpx_test diff --git a/presentation/src/main/cpp/third_party/libvpx/test/init_vpx_test.h b/presentation/src/main/cpp/third_party/libvpx/test/init_vpx_test.h deleted file mode 100644 index 5e0dbb0e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/init_vpx_test.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef TEST_INIT_VPX_TEST_H_ -#define TEST_INIT_VPX_TEST_H_ - -namespace libvpx_test { -void init_vpx_test(); -} - -#endif // TEST_INIT_VPX_TEST_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/invalid_file_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/invalid_file_test.cc deleted file mode 100644 index 0b895ed9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/invalid_file_test.cc +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include -#include "gtest/gtest.h" -#include "./vpx_config.h" -#include "test/codec_factory.h" -#include "test/decode_test_driver.h" -#include "test/ivf_video_source.h" -#include "test/util.h" -#if CONFIG_WEBM_IO -#include "test/webm_video_source.h" -#endif -#include "vpx_mem/vpx_mem.h" - -namespace { - -struct DecodeParam { - int threads; - const char *filename; -}; - -std::ostream &operator<<(std::ostream &os, const DecodeParam &dp) { - return os << "threads: " << dp.threads << " file: " << dp.filename; -} - -class InvalidFileTest : public ::libvpx_test::DecoderTest, - public ::libvpx_test::CodecTestWithParam { - protected: - InvalidFileTest() : DecoderTest(GET_PARAM(0)), res_file_(nullptr) {} - - ~InvalidFileTest() override { - if (res_file_ != nullptr) fclose(res_file_); - } - - void OpenResFile(const std::string &res_file_name_) { - res_file_ = libvpx_test::OpenTestDataFile(res_file_name_); - ASSERT_NE(res_file_, nullptr) - << "Result file open failed. Filename: " << res_file_name_; - } - - bool HandleDecodeResult(const vpx_codec_err_t res_dec, - const libvpx_test::CompressedVideoSource &video, - libvpx_test::Decoder *decoder) override { - EXPECT_NE(res_file_, nullptr); - int expected_res_dec; - - // Read integer result. - const int res = fscanf(res_file_, "%d", &expected_res_dec); - EXPECT_NE(res, EOF) << "Read result data failed"; - - // Check results match. - const DecodeParam input = GET_PARAM(1); - if (input.threads > 1) { - // The serial decode check is too strict for tile-threaded decoding as - // there is no guarantee on the decode order nor which specific error - // will take precedence. Currently a tile-level error is not forwarded so - // the frame will simply be marked corrupt. - EXPECT_TRUE(res_dec == expected_res_dec || - res_dec == VPX_CODEC_CORRUPT_FRAME) - << "Results don't match: frame number = " << video.frame_number() - << ". (" << decoder->DecodeError() - << "). Expected: " << expected_res_dec << " or " - << VPX_CODEC_CORRUPT_FRAME; - } else { - EXPECT_EQ(expected_res_dec, res_dec) - << "Results don't match: frame number = " << video.frame_number() - << ". (" << decoder->DecodeError() << ")"; - } - - return !HasFailure(); - } - - void RunTest() { - const DecodeParam input = GET_PARAM(1); - vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t(); - cfg.threads = input.threads; - const std::string filename = input.filename; - - // Open compressed video file. - std::unique_ptr video; - if (filename.substr(filename.length() - 3, 3) == "ivf") { - video.reset(new libvpx_test::IVFVideoSource(filename)); - } else if (filename.substr(filename.length() - 4, 4) == "webm") { -#if CONFIG_WEBM_IO - video.reset(new libvpx_test::WebMVideoSource(filename)); -#else - fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n", - filename.c_str()); - return; -#endif - } - ASSERT_NE(video.get(), nullptr); - video->Init(); - - // Construct result file name. The file holds a list of expected integer - // results, one for each decoded frame. Any result that doesn't match - // the files list will cause a test failure. - const std::string res_filename = filename + ".res"; - OpenResFile(res_filename); - - // Decode frame, and check the md5 matching. - ASSERT_NO_FATAL_FAILURE(RunLoop(video.get(), cfg)); - } - - private: - FILE *res_file_; -}; - -TEST_P(InvalidFileTest, ReturnCode) { RunTest(); } - -#if CONFIG_VP8_DECODER -const DecodeParam kVP8InvalidFileTests[] = { - { 1, "invalid-bug-1443.ivf" }, - { 1, "invalid-bug-148271109.ivf" }, - { 1, "invalid-token-partition.ivf" }, - { 1, "invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf" }, -}; - -VP8_INSTANTIATE_TEST_SUITE(InvalidFileTest, - ::testing::ValuesIn(kVP8InvalidFileTests)); -#endif // CONFIG_VP8_DECODER - -#if CONFIG_VP9_DECODER -const DecodeParam kVP9InvalidFileTests[] = { - { 1, "invalid-vp90-02-v2.webm" }, -#if CONFIG_VP9_HIGHBITDEPTH - { 1, "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf" }, - { 1, - "invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-." - "ivf" }, -#endif - { 1, "invalid-vp90-03-v3.webm" }, - { 1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf" }, - { 1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf" }, -// This file will cause a large allocation which is expected to fail in 32-bit -// environments. Test x86 for coverage purposes as the allocation failure will -// be in platform agnostic code. -#if VPX_ARCH_X86 - { 1, "invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf" }, -#endif - { 1, "invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf" }, - { 1, "invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf" }, - { 1, "invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf" }, - { 1, "invalid-vp91-2-mixedrefcsp-444to420.ivf" }, - { 1, "invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf" }, - { 1, "invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf" }, - { 1, "invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf" }, - { 1, - "invalid-vp90-2-10-show-existing-frame.webm.ivf.s180315_r01-05_b6-.ivf" }, - { 1, "invalid-crbug-667044.webm" }, -}; - -VP9_INSTANTIATE_TEST_SUITE(InvalidFileTest, - ::testing::ValuesIn(kVP9InvalidFileTests)); -#endif // CONFIG_VP9_DECODER - -// This class will include test vectors that are expected to fail -// peek. However they are still expected to have no fatal failures. -class InvalidFileInvalidPeekTest : public InvalidFileTest { - protected: - InvalidFileInvalidPeekTest() : InvalidFileTest() {} - void HandlePeekResult(libvpx_test::Decoder *const /*decoder*/, - libvpx_test::CompressedVideoSource * /*video*/, - const vpx_codec_err_t /*res_peek*/) override {} -}; - -TEST_P(InvalidFileInvalidPeekTest, ReturnCode) { RunTest(); } - -#if CONFIG_VP8_DECODER -const DecodeParam kVP8InvalidPeekTests[] = { - { 1, "invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf" }, -}; - -VP8_INSTANTIATE_TEST_SUITE(InvalidFileInvalidPeekTest, - ::testing::ValuesIn(kVP8InvalidPeekTests)); -#endif // CONFIG_VP8_DECODER - -#if CONFIG_VP9_DECODER -const DecodeParam kVP9InvalidFileInvalidPeekTests[] = { - { 1, "invalid-vp90-01-v3.webm" }, -}; - -VP9_INSTANTIATE_TEST_SUITE( - InvalidFileInvalidPeekTest, - ::testing::ValuesIn(kVP9InvalidFileInvalidPeekTests)); - -const DecodeParam kMultiThreadedVP9InvalidFileTests[] = { - { 4, "invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm" }, - { 4, - "invalid-" - "vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf" }, - { 4, - "invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf" }, - { 2, "invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf" }, - { 4, "invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf" }, - { 2, "invalid-crbug-629481.webm" }, - { 3, "invalid-crbug-1558.ivf" }, - { 4, "invalid-crbug-1562.ivf" }, -}; - -INSTANTIATE_TEST_SUITE_P( - VP9MultiThreaded, InvalidFileTest, - ::testing::Combine( - ::testing::Values( - static_cast(&libvpx_test::kVP9)), - ::testing::ValuesIn(kMultiThreadedVP9InvalidFileTests))); -#endif // CONFIG_VP9_DECODER -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/ivf_video_source.h b/presentation/src/main/cpp/third_party/libvpx/test/ivf_video_source.h deleted file mode 100644 index 3ccac62b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/ivf_video_source.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_TEST_IVF_VIDEO_SOURCE_H_ -#define VPX_TEST_IVF_VIDEO_SOURCE_H_ -#include -#include -#include -#include -#include "test/video_source.h" - -namespace libvpx_test { -const unsigned int kCodeBufferSize = 256 * 1024 * 1024; -const unsigned int kIvfFileHdrSize = 32; -const unsigned int kIvfFrameHdrSize = 12; - -static unsigned int MemGetLe32(const uint8_t *mem) { - return (mem[3] << 24) | (mem[2] << 16) | (mem[1] << 8) | (mem[0]); -} - -// This class extends VideoSource to allow parsing of ivf files, -// so that we can do actual file decodes. -class IVFVideoSource : public CompressedVideoSource { - public: - explicit IVFVideoSource(const std::string &file_name) - : file_name_(file_name), input_file_(nullptr), - compressed_frame_buf_(nullptr), frame_sz_(0), frame_(0), - end_of_file_(false) {} - - ~IVFVideoSource() override { - delete[] compressed_frame_buf_; - - if (input_file_) fclose(input_file_); - } - - void Init() override { - // Allocate a buffer for read in the compressed video frame. - compressed_frame_buf_ = new uint8_t[libvpx_test::kCodeBufferSize]; - ASSERT_NE(compressed_frame_buf_, nullptr) << "Allocate frame buffer failed"; - } - - void Begin() override { - input_file_ = OpenTestDataFile(file_name_); - ASSERT_NE(input_file_, nullptr) - << "Input file open failed. Filename: " << file_name_; - - // Read file header - uint8_t file_hdr[kIvfFileHdrSize]; - ASSERT_EQ(kIvfFileHdrSize, fread(file_hdr, 1, kIvfFileHdrSize, input_file_)) - << "File header read failed."; - // Check file header - ASSERT_TRUE(file_hdr[0] == 'D' && file_hdr[1] == 'K' && - file_hdr[2] == 'I' && file_hdr[3] == 'F') - << "Input is not an IVF file."; - - FillFrame(); - } - - void Next() override { - ++frame_; - FillFrame(); - } - - void FillFrame() { - ASSERT_NE(input_file_, nullptr); - uint8_t frame_hdr[kIvfFrameHdrSize]; - // Check frame header and read a frame from input_file. - if (fread(frame_hdr, 1, kIvfFrameHdrSize, input_file_) != - kIvfFrameHdrSize) { - end_of_file_ = true; - } else { - end_of_file_ = false; - - frame_sz_ = MemGetLe32(frame_hdr); - ASSERT_LE(frame_sz_, kCodeBufferSize) - << "Frame is too big for allocated code buffer"; - ASSERT_EQ(frame_sz_, - fread(compressed_frame_buf_, 1, frame_sz_, input_file_)) - << "Failed to read complete frame"; - } - } - - const uint8_t *cxdata() const override { - return end_of_file_ ? nullptr : compressed_frame_buf_; - } - size_t frame_size() const override { return frame_sz_; } - unsigned int frame_number() const override { return frame_; } - - protected: - std::string file_name_; - FILE *input_file_; - uint8_t *compressed_frame_buf_; - size_t frame_sz_; - unsigned int frame_; - bool end_of_file_; -}; - -} // namespace libvpx_test - -#endif // VPX_TEST_IVF_VIDEO_SOURCE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/keyframe_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/keyframe_test.cc deleted file mode 100644 index c49ea91b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/keyframe_test.cc +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include -#include -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" -#include "./vpx_config.h" -#include "vpx/vp8cx.h" -#include "vpx/vpx_codec.h" -#include "vpx/vpx_encoder.h" -#include "vpx/vpx_image.h" - -namespace { - -class KeyframeTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWithParam { - protected: - KeyframeTest() : EncoderTest(GET_PARAM(0)) {} - ~KeyframeTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(GET_PARAM(1)); - kf_count_ = 0; - kf_count_max_ = INT_MAX; - kf_do_force_kf_ = false; - set_cpu_used_ = 0; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (kf_do_force_kf_) { - frame_flags_ = (video->frame() % 3) ? 0 : VPX_EFLAG_FORCE_KF; - } - if (set_cpu_used_ && video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_); - } - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) { - kf_pts_list_.push_back(pkt->data.frame.pts); - kf_count_++; - abort_ |= kf_count_ > kf_count_max_; - } - } - - bool kf_do_force_kf_; - int kf_count_; - int kf_count_max_; - std::vector kf_pts_list_; - int set_cpu_used_; -}; - -TEST_P(KeyframeTest, TestRandomVideoSource) { - // Validate that encoding the RandomVideoSource produces multiple keyframes. - // This validates the results of the TestDisableKeyframes test. - kf_count_max_ = 2; // early exit successful tests. - - ::libvpx_test::RandomVideoSource video; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - // In realtime mode - auto placed keyframes are exceedingly rare, don't - // bother with this check if(GetParam() > 0) - if (GET_PARAM(1) > 0) { - EXPECT_GT(kf_count_, 1); - } -} - -TEST_P(KeyframeTest, TestDisableKeyframes) { - cfg_.kf_mode = VPX_KF_DISABLED; - kf_count_max_ = 1; // early exit failed tests. - - ::libvpx_test::RandomVideoSource video; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - EXPECT_EQ(1, kf_count_); -} - -TEST_P(KeyframeTest, TestForceKeyframe) { - cfg_.kf_mode = VPX_KF_DISABLED; - kf_do_force_kf_ = true; - - ::libvpx_test::DummyVideoSource video; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - // verify that every third frame is a keyframe. - for (std::vector::const_iterator iter = kf_pts_list_.begin(); - iter != kf_pts_list_.end(); ++iter) { - ASSERT_EQ(0, *iter % 3) << "Unexpected keyframe at frame " << *iter; - } -} - -TEST_P(KeyframeTest, TestKeyframeMaxDistance) { - cfg_.kf_max_dist = 25; - - ::libvpx_test::DummyVideoSource video; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - // verify that keyframe interval matches kf_max_dist - for (std::vector::const_iterator iter = kf_pts_list_.begin(); - iter != kf_pts_list_.end(); ++iter) { - ASSERT_EQ(0, *iter % 25) << "Unexpected keyframe at frame " << *iter; - } -} - -TEST_P(KeyframeTest, TestAutoKeyframe) { - cfg_.kf_mode = VPX_KF_AUTO; - kf_do_force_kf_ = false; - - // Force a deterministic speed step in Real Time mode, as the faster modes - // may not produce a keyframe like we expect. This is necessary when running - // on very slow environments (like Valgrind). The step -11 was determined - // experimentally as the fastest mode that still throws the keyframe. - if (deadline_ == VPX_DL_REALTIME) set_cpu_used_ = -11; - - // This clip has a cut scene every 30 frames -> Frame 0, 30, 60, 90, 120. - // I check only the first 40 frames to make sure there's a keyframe at frame - // 0 and 30. - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 40); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - // In realtime mode - auto placed keyframes are exceedingly rare, don't - // bother with this check - if (GET_PARAM(1) > 0) { - EXPECT_EQ(2u, kf_pts_list_.size()) << " Not the right number of keyframes "; - } - - // Verify that keyframes match the file keyframes in the file. - for (std::vector::const_iterator iter = kf_pts_list_.begin(); - iter != kf_pts_list_.end(); ++iter) { - if (deadline_ == VPX_DL_REALTIME && *iter > 0) - EXPECT_EQ(0, (*iter - 1) % 30) - << "Unexpected keyframe at frame " << *iter; - else - EXPECT_EQ(0, *iter % 30) << "Unexpected keyframe at frame " << *iter; - } -} - -VP8_INSTANTIATE_TEST_SUITE(KeyframeTest, ALL_TEST_MODES); - -bool IsVP9(vpx_codec_iface_t *iface) { - static const char kVP9Name[] = "WebM Project VP9"; - return strncmp(kVP9Name, vpx_codec_iface_name(iface), sizeof(kVP9Name) - 1) == - 0; -} - -vpx_image_t *CreateGrayImage(vpx_img_fmt_t fmt, unsigned int w, - unsigned int h) { - vpx_image_t *const image = vpx_img_alloc(nullptr, fmt, w, h, 1); - if (!image) return image; - - for (unsigned int i = 0; i < image->d_h; ++i) { - memset(image->planes[0] + i * image->stride[0], 128, image->d_w); - } - const unsigned int uv_h = (image->d_h + 1) / 2; - const unsigned int uv_w = (image->d_w + 1) / 2; - for (unsigned int i = 0; i < uv_h; ++i) { - memset(image->planes[1] + i * image->stride[1], 128, uv_w); - memset(image->planes[2] + i * image->stride[2], 128, uv_w); - } - return image; -} - -// Tests kf_max_dist in one-pass encoding with zero lag. -void TestKeyframeMaximumInterval(vpx_codec_iface_t *iface, - vpx_enc_deadline_t deadline, - unsigned int kf_max_dist) { - vpx_codec_enc_cfg_t cfg; - ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, /*usage=*/0), - VPX_CODEC_OK); - cfg.g_w = 320; - cfg.g_h = 240; - cfg.g_pass = VPX_RC_ONE_PASS; - cfg.g_lag_in_frames = 0; - cfg.kf_mode = VPX_KF_AUTO; - cfg.kf_min_dist = 0; - cfg.kf_max_dist = kf_max_dist; - - vpx_codec_ctx_t enc; - ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK); - - const int speed = IsVP9(iface) ? 9 : -12; - ASSERT_EQ(vpx_codec_control(&enc, VP8E_SET_CPUUSED, speed), VPX_CODEC_OK); - - vpx_image_t *image = CreateGrayImage(VPX_IMG_FMT_I420, cfg.g_w, cfg.g_h); - ASSERT_NE(image, nullptr); - - // Encode frames. - const vpx_codec_cx_pkt_t *pkt; - const unsigned int num_frames = kf_max_dist == 0 ? 4 : 3 * kf_max_dist + 1; - for (unsigned int i = 0; i < num_frames; ++i) { - ASSERT_EQ(vpx_codec_encode(&enc, image, i, 1, 0, deadline), VPX_CODEC_OK); - vpx_codec_iter_t iter = nullptr; - while ((pkt = vpx_codec_get_cx_data(&enc, &iter)) != nullptr) { - ASSERT_EQ(pkt->kind, VPX_CODEC_CX_FRAME_PKT); - if (kf_max_dist == 0 || i % kf_max_dist == 0) { - ASSERT_EQ(pkt->data.frame.flags & VPX_FRAME_IS_KEY, VPX_FRAME_IS_KEY); - } else { - ASSERT_EQ(pkt->data.frame.flags & VPX_FRAME_IS_KEY, 0u); - } - } - } - - // Flush the encoder. - bool got_data; - do { - ASSERT_EQ(vpx_codec_encode(&enc, nullptr, 0, 1, 0, deadline), VPX_CODEC_OK); - got_data = false; - vpx_codec_iter_t iter = nullptr; - while ((pkt = vpx_codec_get_cx_data(&enc, &iter)) != nullptr) { - ASSERT_EQ(pkt->kind, VPX_CODEC_CX_FRAME_PKT); - got_data = true; - } - } while (got_data); - - vpx_img_free(image); - ASSERT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK); -} - -TEST(KeyframeIntervalTest, KeyframeMaximumInterval) { - std::vector ifaces; -#if CONFIG_VP8_ENCODER - ifaces.push_back(vpx_codec_vp8_cx()); -#endif -#if CONFIG_VP9_ENCODER - ifaces.push_back(vpx_codec_vp9_cx()); -#endif - for (vpx_codec_iface_t *iface : ifaces) { - for (vpx_enc_deadline_t deadline : - { VPX_DL_REALTIME, VPX_DL_GOOD_QUALITY, VPX_DL_BEST_QUALITY }) { - // Test 0 and 1 (both mean all intra), some powers of 2, some multiples - // of 10, and some prime numbers. - for (unsigned int kf_max_dist : - { 0, 1, 2, 3, 4, 7, 10, 13, 16, 20, 23, 29, 32 }) { - TestKeyframeMaximumInterval(iface, deadline, kf_max_dist); - } - } - } -} - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/level_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/level_test.cc deleted file mode 100644 index 03217a29..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/level_test.cc +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" -#include "vpx_config.h" - -namespace { -class LevelTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith2Params { - protected: - LevelTest() - : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)), - cpu_used_(GET_PARAM(2)), min_gf_internal_(24), target_level_(0), - level_(0) {} - ~LevelTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(encoding_mode_); - if (encoding_mode_ != ::libvpx_test::kRealTime) { - cfg_.g_lag_in_frames = 25; - cfg_.rc_end_usage = VPX_VBR; - } else { - cfg_.g_lag_in_frames = 0; - cfg_.rc_end_usage = VPX_CBR; - } - cfg_.rc_2pass_vbr_minsection_pct = 5; - cfg_.rc_2pass_vbr_maxsection_pct = 2000; - cfg_.rc_target_bitrate = 400; - cfg_.rc_max_quantizer = 63; - cfg_.rc_min_quantizer = 0; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, cpu_used_); - encoder->Control(VP9E_SET_TARGET_LEVEL, target_level_); - encoder->Control(VP9E_SET_MIN_GF_INTERVAL, min_gf_internal_); - if (encoding_mode_ != ::libvpx_test::kRealTime) { - encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); - encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7); - encoder->Control(VP8E_SET_ARNR_STRENGTH, 5); - encoder->Control(VP8E_SET_ARNR_TYPE, 3); - } - } - encoder->Control(VP9E_GET_LEVEL, &level_); - ASSERT_LE(level_, 51); - ASSERT_GE(level_, 0); - } - - ::libvpx_test::TestMode encoding_mode_; - int cpu_used_; - int min_gf_internal_; - int target_level_; - int level_; -}; - -TEST_P(LevelTest, TestTargetLevel11Large) { -#if CONFIG_REALTIME_ONLY - GTEST_SKIP(); -#else - ASSERT_NE(encoding_mode_, ::libvpx_test::kRealTime); - ::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0, - 60); - target_level_ = 11; - cfg_.rc_target_bitrate = 150; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(target_level_, level_); -#endif -} - -TEST_P(LevelTest, TestTargetLevel20Large) { -#if CONFIG_REALTIME_ONLY - GTEST_SKIP(); -#else - ASSERT_NE(encoding_mode_, ::libvpx_test::kRealTime); - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 60); - target_level_ = 20; - cfg_.rc_target_bitrate = 1200; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(target_level_, level_); -#endif -} - -TEST_P(LevelTest, TestTargetLevel31Large) { -#if CONFIG_REALTIME_ONLY - GTEST_SKIP(); -#else - ASSERT_NE(encoding_mode_, ::libvpx_test::kRealTime); - ::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30, - 1, 0, 60); - target_level_ = 31; - cfg_.rc_target_bitrate = 8000; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(target_level_, level_); -#endif -} - -// Test for keeping level stats only -TEST_P(LevelTest, TestTargetLevel0) { - ::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0, - 40); - target_level_ = 0; - min_gf_internal_ = 4; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(11, level_); - - cfg_.rc_target_bitrate = 1600; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(20, level_); -} - -// Test for level control being turned off -TEST_P(LevelTest, TestTargetLevel255) { - ::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0, - 30); - target_level_ = 255; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -TEST_P(LevelTest, TestTargetLevelApi) { - ::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0, 1); - static vpx_codec_iface_t *codec = &vpx_codec_vp9_cx_algo; - vpx_codec_ctx_t enc; - vpx_codec_enc_cfg_t cfg; - EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_config_default(codec, &cfg, 0)); - cfg.rc_target_bitrate = 100; - EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_init(&enc, codec, &cfg, 0)); - for (int level = 0; level <= 256; ++level) { - if (level == 10 || level == 11 || level == 20 || level == 21 || - level == 30 || level == 31 || level == 40 || level == 41 || - level == 50 || level == 51 || level == 52 || level == 60 || - level == 61 || level == 62 || level == 0 || level == 1 || level == 255) - EXPECT_EQ(VPX_CODEC_OK, - vpx_codec_control(&enc, VP9E_SET_TARGET_LEVEL, level)); - else - EXPECT_EQ(VPX_CODEC_INVALID_PARAM, - vpx_codec_control(&enc, VP9E_SET_TARGET_LEVEL, level)); - } - EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&enc)); -} - -VP9_INSTANTIATE_TEST_SUITE(LevelTest, ONE_OR_TWO_PASS_TEST_MODES, - ::testing::Range(0, 9)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/lpf_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/lpf_test.cc deleted file mode 100644 index 9045e054..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/lpf_test.cc +++ /dev/null @@ -1,721 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "test/acm_random.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vp9/common/vp9_entropy.h" -#include "vp9/common/vp9_loopfilter.h" -#include "vpx/vpx_integer.h" - -using libvpx_test::ACMRandom; - -namespace { -// Horizontally and Vertically need 32x32: 8 Coeffs preceeding filtered section -// 16 Coefs within filtered section -// 8 Coeffs following filtered section -const int kNumCoeffs = 1024; - -const int number_of_iterations = 10000; - -#if CONFIG_VP9_HIGHBITDEPTH -typedef uint16_t Pixel; -#define PIXEL_WIDTH 16 - -typedef void (*loop_op_t)(Pixel *s, int p, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh, int bd); -typedef void (*dual_loop_op_t)(Pixel *s, int p, const uint8_t *blimit0, - const uint8_t *limit0, const uint8_t *thresh0, - const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1, int bd); -#else -typedef uint8_t Pixel; -#define PIXEL_WIDTH 8 - -typedef void (*loop_op_t)(Pixel *s, int p, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh); -typedef void (*dual_loop_op_t)(Pixel *s, int p, const uint8_t *blimit0, - const uint8_t *limit0, const uint8_t *thresh0, - const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1); -#endif // CONFIG_VP9_HIGHBITDEPTH - -typedef std::tuple loop8_param_t; -typedef std::tuple dualloop8_param_t; - -void InitInput(Pixel *s, Pixel *ref_s, ACMRandom *rnd, const uint8_t limit, - const int mask, const int32_t p, const int i) { - uint16_t tmp_s[kNumCoeffs]; - - for (int j = 0; j < kNumCoeffs;) { - const uint8_t val = rnd->Rand8(); - if (val & 0x80) { // 50% chance to choose a new value. - tmp_s[j] = rnd->Rand16(); - j++; - } else { // 50% chance to repeat previous value in row X times. - int k = 0; - while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) { - if (j < 1) { - tmp_s[j] = rnd->Rand16(); - } else if (val & 0x20) { // Increment by a value within the limit. - tmp_s[j] = static_cast(tmp_s[j - 1] + (limit - 1)); - } else { // Decrement by a value within the limit. - tmp_s[j] = static_cast(tmp_s[j - 1] - (limit - 1)); - } - j++; - } - } - } - - for (int j = 0; j < kNumCoeffs;) { - const uint8_t val = rnd->Rand8(); - if (val & 0x80) { - j++; - } else { // 50% chance to repeat previous value in column X times. - int k = 0; - while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) { - if (j < 1) { - tmp_s[j] = rnd->Rand16(); - } else if (val & 0x20) { // Increment by a value within the limit. - tmp_s[(j % 32) * 32 + j / 32] = static_cast( - tmp_s[((j - 1) % 32) * 32 + (j - 1) / 32] + (limit - 1)); - } else { // Decrement by a value within the limit. - tmp_s[(j % 32) * 32 + j / 32] = static_cast( - tmp_s[((j - 1) % 32) * 32 + (j - 1) / 32] - (limit - 1)); - } - j++; - } - } - } - - for (int j = 0; j < kNumCoeffs; j++) { - if (i % 2) { - s[j] = tmp_s[j] & mask; - } else { - s[j] = tmp_s[p * (j % p) + j / p] & mask; - } - ref_s[j] = s[j]; - } -} - -uint8_t GetOuterThresh(ACMRandom *rnd) { - return static_cast(rnd->RandRange(3 * MAX_LOOP_FILTER + 5)); -} - -uint8_t GetInnerThresh(ACMRandom *rnd) { - return static_cast(rnd->RandRange(MAX_LOOP_FILTER + 1)); -} - -uint8_t GetHevThresh(ACMRandom *rnd) { - return static_cast(rnd->RandRange(MAX_LOOP_FILTER + 1) >> 4); -} - -class Loop8Test6Param : public ::testing::TestWithParam { - public: - ~Loop8Test6Param() override = default; - void SetUp() override { - loopfilter_op_ = GET_PARAM(0); - ref_loopfilter_op_ = GET_PARAM(1); - bit_depth_ = GET_PARAM(2); - mask_ = (1 << bit_depth_) - 1; - } - - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - int bit_depth_; - int mask_; - loop_op_t loopfilter_op_; - loop_op_t ref_loopfilter_op_; -}; -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Loop8Test6Param); - -#if HAVE_NEON || HAVE_SSE2 || (HAVE_LSX && !CONFIG_VP9_HIGHBITDEPTH) || \ - (HAVE_DSPR2 || HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH) -class Loop8Test9Param : public ::testing::TestWithParam { - public: - ~Loop8Test9Param() override = default; - void SetUp() override { - loopfilter_op_ = GET_PARAM(0); - ref_loopfilter_op_ = GET_PARAM(1); - bit_depth_ = GET_PARAM(2); - mask_ = (1 << bit_depth_) - 1; - } - - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - int bit_depth_; - int mask_; - dual_loop_op_t loopfilter_op_; - dual_loop_op_t ref_loopfilter_op_; -}; -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Loop8Test9Param); -#endif // HAVE_NEON || HAVE_SSE2 || (HAVE_DSPR2 || HAVE_MSA && - // (!CONFIG_VP9_HIGHBITDEPTH) || (HAVE_LSX && !CONFIG_VP9_HIGHBITDEPTH)) - -TEST_P(Loop8Test6Param, OperationCheck) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = number_of_iterations; - const int32_t p = kNumCoeffs / 32; - DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, s[kNumCoeffs]); - DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, ref_s[kNumCoeffs]); - int err_count_total = 0; - int first_failure = -1; - for (int i = 0; i < count_test_block; ++i) { - int err_count = 0; - uint8_t tmp = GetOuterThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - tmp = GetInnerThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - tmp = GetHevThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - InitInput(s, ref_s, &rnd, *limit, mask_, p, i); -#if CONFIG_VP9_HIGHBITDEPTH - ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_); - ASM_REGISTER_STATE_CHECK( - loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_)); -#else - ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh); - ASM_REGISTER_STATE_CHECK( - loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh)); -#endif // CONFIG_VP9_HIGHBITDEPTH - - for (int j = 0; j < kNumCoeffs; ++j) { - err_count += ref_s[j] != s[j]; - } - if (err_count && !err_count_total) { - first_failure = i; - } - err_count_total += err_count; - } - EXPECT_EQ(0, err_count_total) - << "Error: Loop8Test6Param, C output doesn't match SSE2 " - "loopfilter output. " - << "First failed at test case " << first_failure; -} - -TEST_P(Loop8Test6Param, ValueCheck) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = number_of_iterations; - DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, s[kNumCoeffs]); - DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, ref_s[kNumCoeffs]); - int err_count_total = 0; - int first_failure = -1; - - // NOTE: The code in vp9_loopfilter.c:update_sharpness computes mblim as a - // function of sharpness_lvl and the loopfilter lvl as: - // block_inside_limit = lvl >> ((sharpness_lvl > 0) + (sharpness_lvl > 4)); - // ... - // memset(lfi->lfthr[lvl].mblim, (2 * (lvl + 2) + block_inside_limit), - // SIMD_WIDTH); - // This means that the largest value for mblim will occur when sharpness_lvl - // is equal to 0, and lvl is equal to its greatest value (MAX_LOOP_FILTER). - // In this case block_inside_limit will be equal to MAX_LOOP_FILTER and - // therefore mblim will be equal to (2 * (lvl + 2) + block_inside_limit) = - // 2 * (MAX_LOOP_FILTER + 2) + MAX_LOOP_FILTER = 3 * MAX_LOOP_FILTER + 4 - - for (int i = 0; i < count_test_block; ++i) { - int err_count = 0; - uint8_t tmp = GetOuterThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - tmp = GetInnerThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - tmp = GetHevThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - int32_t p = kNumCoeffs / 32; - for (int j = 0; j < kNumCoeffs; ++j) { - s[j] = rnd.Rand16() & mask_; - ref_s[j] = s[j]; - } -#if CONFIG_VP9_HIGHBITDEPTH - ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_); - ASM_REGISTER_STATE_CHECK( - loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_)); -#else - ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh); - ASM_REGISTER_STATE_CHECK( - loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh)); -#endif // CONFIG_VP9_HIGHBITDEPTH - - for (int j = 0; j < kNumCoeffs; ++j) { - err_count += ref_s[j] != s[j]; - } - if (err_count && !err_count_total) { - first_failure = i; - } - err_count_total += err_count; - } - EXPECT_EQ(0, err_count_total) - << "Error: Loop8Test6Param, C output doesn't match SSE2 " - "loopfilter output. " - << "First failed at test case " << first_failure; -} - -#if HAVE_NEON || HAVE_SSE2 || (HAVE_LSX && (!CONFIG_VP9_HIGHBITDEPTH)) || \ - (HAVE_DSPR2 || HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)) -TEST_P(Loop8Test9Param, OperationCheck) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = number_of_iterations; - DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, s[kNumCoeffs]); - DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, ref_s[kNumCoeffs]); - int err_count_total = 0; - int first_failure = -1; - for (int i = 0; i < count_test_block; ++i) { - int err_count = 0; - uint8_t tmp = GetOuterThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - tmp = GetInnerThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - tmp = GetHevThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - tmp = GetOuterThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - tmp = GetInnerThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - tmp = GetHevThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - int32_t p = kNumCoeffs / 32; - const uint8_t limit = *limit0 < *limit1 ? *limit0 : *limit1; - InitInput(s, ref_s, &rnd, limit, mask_, p, i); -#if CONFIG_VP9_HIGHBITDEPTH - ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1, - limit1, thresh1, bit_depth_); - ASM_REGISTER_STATE_CHECK(loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, - thresh0, blimit1, limit1, thresh1, - bit_depth_)); -#else - ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1, - limit1, thresh1); - ASM_REGISTER_STATE_CHECK(loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, - thresh0, blimit1, limit1, thresh1)); -#endif // CONFIG_VP9_HIGHBITDEPTH - - for (int j = 0; j < kNumCoeffs; ++j) { - err_count += ref_s[j] != s[j]; - } - if (err_count && !err_count_total) { - first_failure = i; - } - err_count_total += err_count; - } - EXPECT_EQ(0, err_count_total) - << "Error: Loop8Test9Param, C output doesn't match SSE2 " - "loopfilter output. " - << "First failed at test case " << first_failure; -} - -TEST_P(Loop8Test9Param, ValueCheck) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = number_of_iterations; - DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, s[kNumCoeffs]); - DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, ref_s[kNumCoeffs]); - int err_count_total = 0; - int first_failure = -1; - for (int i = 0; i < count_test_block; ++i) { - int err_count = 0; - uint8_t tmp = GetOuterThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - tmp = GetInnerThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - tmp = GetHevThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - tmp = GetOuterThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - tmp = GetInnerThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - tmp = GetHevThresh(&rnd); - DECLARE_ALIGNED(16, const uint8_t, - thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, - tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; - int32_t p = kNumCoeffs / 32; // TODO(pdlf) can we have non-square here? - for (int j = 0; j < kNumCoeffs; ++j) { - s[j] = rnd.Rand16() & mask_; - ref_s[j] = s[j]; - } -#if CONFIG_VP9_HIGHBITDEPTH - ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1, - limit1, thresh1, bit_depth_); - ASM_REGISTER_STATE_CHECK(loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, - thresh0, blimit1, limit1, thresh1, - bit_depth_)); -#else - ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1, - limit1, thresh1); - ASM_REGISTER_STATE_CHECK(loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, - thresh0, blimit1, limit1, thresh1)); -#endif // CONFIG_VP9_HIGHBITDEPTH - - for (int j = 0; j < kNumCoeffs; ++j) { - err_count += ref_s[j] != s[j]; - } - if (err_count && !err_count_total) { - first_failure = i; - } - err_count_total += err_count; - } - EXPECT_EQ(0, err_count_total) - << "Error: Loop8Test9Param, C output doesn't match SSE2" - "loopfilter output. " - << "First failed at test case " << first_failure; -} -#endif // HAVE_NEON || HAVE_SSE2 || (HAVE_DSPR2 || HAVE_MSA && - // (!CONFIG_VP9_HIGHBITDEPTH)) || (HAVE_LSX && - // (!CONFIG_VP9_HIGHBITDEPTH)) - -using std::make_tuple; - -#if HAVE_SSE2 -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - SSE2, Loop8Test6Param, - ::testing::Values(make_tuple(&vpx_highbd_lpf_horizontal_4_sse2, - &vpx_highbd_lpf_horizontal_4_c, 8), - make_tuple(&vpx_highbd_lpf_vertical_4_sse2, - &vpx_highbd_lpf_vertical_4_c, 8), - make_tuple(&vpx_highbd_lpf_horizontal_8_sse2, - &vpx_highbd_lpf_horizontal_8_c, 8), - make_tuple(&vpx_highbd_lpf_horizontal_16_sse2, - &vpx_highbd_lpf_horizontal_16_c, 8), - make_tuple(&vpx_highbd_lpf_horizontal_16_dual_sse2, - &vpx_highbd_lpf_horizontal_16_dual_c, 8), - make_tuple(&vpx_highbd_lpf_vertical_8_sse2, - &vpx_highbd_lpf_vertical_8_c, 8), - make_tuple(&vpx_highbd_lpf_vertical_16_sse2, - &vpx_highbd_lpf_vertical_16_c, 8), - make_tuple(&vpx_highbd_lpf_horizontal_4_sse2, - &vpx_highbd_lpf_horizontal_4_c, 10), - make_tuple(&vpx_highbd_lpf_vertical_4_sse2, - &vpx_highbd_lpf_vertical_4_c, 10), - make_tuple(&vpx_highbd_lpf_horizontal_8_sse2, - &vpx_highbd_lpf_horizontal_8_c, 10), - make_tuple(&vpx_highbd_lpf_horizontal_16_sse2, - &vpx_highbd_lpf_horizontal_16_c, 10), - make_tuple(&vpx_highbd_lpf_horizontal_16_dual_sse2, - &vpx_highbd_lpf_horizontal_16_dual_c, 10), - make_tuple(&vpx_highbd_lpf_vertical_8_sse2, - &vpx_highbd_lpf_vertical_8_c, 10), - make_tuple(&vpx_highbd_lpf_vertical_16_sse2, - &vpx_highbd_lpf_vertical_16_c, 10), - make_tuple(&vpx_highbd_lpf_horizontal_4_sse2, - &vpx_highbd_lpf_horizontal_4_c, 12), - make_tuple(&vpx_highbd_lpf_vertical_4_sse2, - &vpx_highbd_lpf_vertical_4_c, 12), - make_tuple(&vpx_highbd_lpf_horizontal_8_sse2, - &vpx_highbd_lpf_horizontal_8_c, 12), - make_tuple(&vpx_highbd_lpf_horizontal_16_sse2, - &vpx_highbd_lpf_horizontal_16_c, 12), - make_tuple(&vpx_highbd_lpf_horizontal_16_dual_sse2, - &vpx_highbd_lpf_horizontal_16_dual_c, 12), - make_tuple(&vpx_highbd_lpf_vertical_8_sse2, - &vpx_highbd_lpf_vertical_8_c, 12), - make_tuple(&vpx_highbd_lpf_vertical_16_sse2, - &vpx_highbd_lpf_vertical_16_c, 12), - make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2, - &vpx_highbd_lpf_vertical_16_dual_c, 8), - make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2, - &vpx_highbd_lpf_vertical_16_dual_c, 10), - make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2, - &vpx_highbd_lpf_vertical_16_dual_c, 12))); -#else -INSTANTIATE_TEST_SUITE_P( - SSE2, Loop8Test6Param, - ::testing::Values( - make_tuple(&vpx_lpf_horizontal_4_sse2, &vpx_lpf_horizontal_4_c, 8), - make_tuple(&vpx_lpf_horizontal_8_sse2, &vpx_lpf_horizontal_8_c, 8), - make_tuple(&vpx_lpf_horizontal_16_sse2, &vpx_lpf_horizontal_16_c, 8), - make_tuple(&vpx_lpf_horizontal_16_dual_sse2, - &vpx_lpf_horizontal_16_dual_c, 8), - make_tuple(&vpx_lpf_vertical_4_sse2, &vpx_lpf_vertical_4_c, 8), - make_tuple(&vpx_lpf_vertical_8_sse2, &vpx_lpf_vertical_8_c, 8), - make_tuple(&vpx_lpf_vertical_16_sse2, &vpx_lpf_vertical_16_c, 8), - make_tuple(&vpx_lpf_vertical_16_dual_sse2, &vpx_lpf_vertical_16_dual_c, - 8))); -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif - -#if HAVE_AVX2 && (!CONFIG_VP9_HIGHBITDEPTH) -INSTANTIATE_TEST_SUITE_P( - AVX2, Loop8Test6Param, - ::testing::Values(make_tuple(&vpx_lpf_horizontal_16_avx2, - &vpx_lpf_horizontal_16_c, 8), - make_tuple(&vpx_lpf_horizontal_16_dual_avx2, - &vpx_lpf_horizontal_16_dual_c, 8))); -#endif - -#if HAVE_SSE2 -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - SSE2, Loop8Test9Param, - ::testing::Values(make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2, - &vpx_highbd_lpf_horizontal_4_dual_c, 8), - make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2, - &vpx_highbd_lpf_horizontal_8_dual_c, 8), - make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2, - &vpx_highbd_lpf_vertical_4_dual_c, 8), - make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2, - &vpx_highbd_lpf_vertical_8_dual_c, 8), - make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2, - &vpx_highbd_lpf_horizontal_4_dual_c, 10), - make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2, - &vpx_highbd_lpf_horizontal_8_dual_c, 10), - make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2, - &vpx_highbd_lpf_vertical_4_dual_c, 10), - make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2, - &vpx_highbd_lpf_vertical_8_dual_c, 10), - make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2, - &vpx_highbd_lpf_horizontal_4_dual_c, 12), - make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2, - &vpx_highbd_lpf_horizontal_8_dual_c, 12), - make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2, - &vpx_highbd_lpf_vertical_4_dual_c, 12), - make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2, - &vpx_highbd_lpf_vertical_8_dual_c, 12))); -#else -INSTANTIATE_TEST_SUITE_P( - SSE2, Loop8Test9Param, - ::testing::Values(make_tuple(&vpx_lpf_horizontal_4_dual_sse2, - &vpx_lpf_horizontal_4_dual_c, 8), - make_tuple(&vpx_lpf_horizontal_8_dual_sse2, - &vpx_lpf_horizontal_8_dual_c, 8), - make_tuple(&vpx_lpf_vertical_4_dual_sse2, - &vpx_lpf_vertical_4_dual_c, 8), - make_tuple(&vpx_lpf_vertical_8_dual_sse2, - &vpx_lpf_vertical_8_dual_c, 8))); -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif - -#if HAVE_NEON -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - NEON, Loop8Test6Param, - ::testing::Values(make_tuple(&vpx_highbd_lpf_horizontal_4_neon, - &vpx_highbd_lpf_horizontal_4_c, 8), - make_tuple(&vpx_highbd_lpf_horizontal_4_neon, - &vpx_highbd_lpf_horizontal_4_c, 10), - make_tuple(&vpx_highbd_lpf_horizontal_4_neon, - &vpx_highbd_lpf_horizontal_4_c, 12), - make_tuple(&vpx_highbd_lpf_horizontal_8_neon, - &vpx_highbd_lpf_horizontal_8_c, 8), - make_tuple(&vpx_highbd_lpf_horizontal_8_neon, - &vpx_highbd_lpf_horizontal_8_c, 10), - make_tuple(&vpx_highbd_lpf_horizontal_8_neon, - &vpx_highbd_lpf_horizontal_8_c, 12), - make_tuple(&vpx_highbd_lpf_horizontal_16_neon, - &vpx_highbd_lpf_horizontal_16_c, 8), - make_tuple(&vpx_highbd_lpf_horizontal_16_neon, - &vpx_highbd_lpf_horizontal_16_c, 10), - make_tuple(&vpx_highbd_lpf_horizontal_16_neon, - &vpx_highbd_lpf_horizontal_16_c, 12), - make_tuple(&vpx_highbd_lpf_horizontal_16_dual_neon, - &vpx_highbd_lpf_horizontal_16_dual_c, 8), - make_tuple(&vpx_highbd_lpf_horizontal_16_dual_neon, - &vpx_highbd_lpf_horizontal_16_dual_c, 10), - make_tuple(&vpx_highbd_lpf_horizontal_16_dual_neon, - &vpx_highbd_lpf_horizontal_16_dual_c, 12), - make_tuple(&vpx_highbd_lpf_vertical_4_neon, - &vpx_highbd_lpf_vertical_4_c, 8), - make_tuple(&vpx_highbd_lpf_vertical_4_neon, - &vpx_highbd_lpf_vertical_4_c, 10), - make_tuple(&vpx_highbd_lpf_vertical_4_neon, - &vpx_highbd_lpf_vertical_4_c, 12), - make_tuple(&vpx_highbd_lpf_vertical_8_neon, - &vpx_highbd_lpf_vertical_8_c, 8), - make_tuple(&vpx_highbd_lpf_vertical_8_neon, - &vpx_highbd_lpf_vertical_8_c, 10), - make_tuple(&vpx_highbd_lpf_vertical_8_neon, - &vpx_highbd_lpf_vertical_8_c, 12), - make_tuple(&vpx_highbd_lpf_vertical_16_neon, - &vpx_highbd_lpf_vertical_16_c, 8), - make_tuple(&vpx_highbd_lpf_vertical_16_neon, - &vpx_highbd_lpf_vertical_16_c, 10), - make_tuple(&vpx_highbd_lpf_vertical_16_neon, - &vpx_highbd_lpf_vertical_16_c, 12), - make_tuple(&vpx_highbd_lpf_vertical_16_dual_neon, - &vpx_highbd_lpf_vertical_16_dual_c, 8), - make_tuple(&vpx_highbd_lpf_vertical_16_dual_neon, - &vpx_highbd_lpf_vertical_16_dual_c, 10), - make_tuple(&vpx_highbd_lpf_vertical_16_dual_neon, - &vpx_highbd_lpf_vertical_16_dual_c, 12))); -INSTANTIATE_TEST_SUITE_P( - NEON, Loop8Test9Param, - ::testing::Values(make_tuple(&vpx_highbd_lpf_horizontal_4_dual_neon, - &vpx_highbd_lpf_horizontal_4_dual_c, 8), - make_tuple(&vpx_highbd_lpf_horizontal_4_dual_neon, - &vpx_highbd_lpf_horizontal_4_dual_c, 10), - make_tuple(&vpx_highbd_lpf_horizontal_4_dual_neon, - &vpx_highbd_lpf_horizontal_4_dual_c, 12), - make_tuple(&vpx_highbd_lpf_horizontal_8_dual_neon, - &vpx_highbd_lpf_horizontal_8_dual_c, 8), - make_tuple(&vpx_highbd_lpf_horizontal_8_dual_neon, - &vpx_highbd_lpf_horizontal_8_dual_c, 10), - make_tuple(&vpx_highbd_lpf_horizontal_8_dual_neon, - &vpx_highbd_lpf_horizontal_8_dual_c, 12), - make_tuple(&vpx_highbd_lpf_vertical_4_dual_neon, - &vpx_highbd_lpf_vertical_4_dual_c, 8), - make_tuple(&vpx_highbd_lpf_vertical_4_dual_neon, - &vpx_highbd_lpf_vertical_4_dual_c, 10), - make_tuple(&vpx_highbd_lpf_vertical_4_dual_neon, - &vpx_highbd_lpf_vertical_4_dual_c, 12), - make_tuple(&vpx_highbd_lpf_vertical_8_dual_neon, - &vpx_highbd_lpf_vertical_8_dual_c, 8), - make_tuple(&vpx_highbd_lpf_vertical_8_dual_neon, - &vpx_highbd_lpf_vertical_8_dual_c, 10), - make_tuple(&vpx_highbd_lpf_vertical_8_dual_neon, - &vpx_highbd_lpf_vertical_8_dual_c, 12))); -#else -INSTANTIATE_TEST_SUITE_P( - NEON, Loop8Test6Param, - ::testing::Values( - make_tuple(&vpx_lpf_horizontal_16_neon, &vpx_lpf_horizontal_16_c, 8), - make_tuple(&vpx_lpf_horizontal_16_dual_neon, - &vpx_lpf_horizontal_16_dual_c, 8), - make_tuple(&vpx_lpf_vertical_16_neon, &vpx_lpf_vertical_16_c, 8), - make_tuple(&vpx_lpf_vertical_16_dual_neon, &vpx_lpf_vertical_16_dual_c, - 8), - make_tuple(&vpx_lpf_horizontal_8_neon, &vpx_lpf_horizontal_8_c, 8), - make_tuple(&vpx_lpf_vertical_8_neon, &vpx_lpf_vertical_8_c, 8), - make_tuple(&vpx_lpf_horizontal_4_neon, &vpx_lpf_horizontal_4_c, 8), - make_tuple(&vpx_lpf_vertical_4_neon, &vpx_lpf_vertical_4_c, 8))); -INSTANTIATE_TEST_SUITE_P( - NEON, Loop8Test9Param, - ::testing::Values(make_tuple(&vpx_lpf_horizontal_8_dual_neon, - &vpx_lpf_horizontal_8_dual_c, 8), - make_tuple(&vpx_lpf_vertical_8_dual_neon, - &vpx_lpf_vertical_8_dual_c, 8), - make_tuple(&vpx_lpf_horizontal_4_dual_neon, - &vpx_lpf_horizontal_4_dual_c, 8), - make_tuple(&vpx_lpf_vertical_4_dual_neon, - &vpx_lpf_vertical_4_dual_c, 8))); -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif // HAVE_NEON - -#if HAVE_DSPR2 && !CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - DSPR2, Loop8Test6Param, - ::testing::Values( - make_tuple(&vpx_lpf_horizontal_4_dspr2, &vpx_lpf_horizontal_4_c, 8), - make_tuple(&vpx_lpf_horizontal_8_dspr2, &vpx_lpf_horizontal_8_c, 8), - make_tuple(&vpx_lpf_horizontal_16_dspr2, &vpx_lpf_horizontal_16_c, 8), - make_tuple(&vpx_lpf_horizontal_16_dual_dspr2, - &vpx_lpf_horizontal_16_dual_c, 8), - make_tuple(&vpx_lpf_vertical_4_dspr2, &vpx_lpf_vertical_4_c, 8), - make_tuple(&vpx_lpf_vertical_8_dspr2, &vpx_lpf_vertical_8_c, 8), - make_tuple(&vpx_lpf_vertical_16_dspr2, &vpx_lpf_vertical_16_c, 8), - make_tuple(&vpx_lpf_vertical_16_dual_dspr2, &vpx_lpf_vertical_16_dual_c, - 8))); - -INSTANTIATE_TEST_SUITE_P( - DSPR2, Loop8Test9Param, - ::testing::Values(make_tuple(&vpx_lpf_horizontal_4_dual_dspr2, - &vpx_lpf_horizontal_4_dual_c, 8), - make_tuple(&vpx_lpf_horizontal_8_dual_dspr2, - &vpx_lpf_horizontal_8_dual_c, 8), - make_tuple(&vpx_lpf_vertical_4_dual_dspr2, - &vpx_lpf_vertical_4_dual_c, 8), - make_tuple(&vpx_lpf_vertical_8_dual_dspr2, - &vpx_lpf_vertical_8_dual_c, 8))); -#endif // HAVE_DSPR2 && !CONFIG_VP9_HIGHBITDEPTH - -#if HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH) -INSTANTIATE_TEST_SUITE_P( - MSA, Loop8Test6Param, - ::testing::Values( - make_tuple(&vpx_lpf_horizontal_4_msa, &vpx_lpf_horizontal_4_c, 8), - make_tuple(&vpx_lpf_horizontal_8_msa, &vpx_lpf_horizontal_8_c, 8), - make_tuple(&vpx_lpf_horizontal_16_msa, &vpx_lpf_horizontal_16_c, 8), - make_tuple(&vpx_lpf_horizontal_16_dual_msa, - &vpx_lpf_horizontal_16_dual_c, 8), - make_tuple(&vpx_lpf_vertical_4_msa, &vpx_lpf_vertical_4_c, 8), - make_tuple(&vpx_lpf_vertical_8_msa, &vpx_lpf_vertical_8_c, 8), - make_tuple(&vpx_lpf_vertical_16_msa, &vpx_lpf_vertical_16_c, 8))); - -INSTANTIATE_TEST_SUITE_P( - MSA, Loop8Test9Param, - ::testing::Values(make_tuple(&vpx_lpf_horizontal_4_dual_msa, - &vpx_lpf_horizontal_4_dual_c, 8), - make_tuple(&vpx_lpf_horizontal_8_dual_msa, - &vpx_lpf_horizontal_8_dual_c, 8), - make_tuple(&vpx_lpf_vertical_4_dual_msa, - &vpx_lpf_vertical_4_dual_c, 8), - make_tuple(&vpx_lpf_vertical_8_dual_msa, - &vpx_lpf_vertical_8_dual_c, 8))); -#endif // HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH) - -#if HAVE_LSX && (!CONFIG_VP9_HIGHBITDEPTH) -INSTANTIATE_TEST_SUITE_P( - LSX, Loop8Test6Param, - ::testing::Values( - make_tuple(&vpx_lpf_horizontal_4_lsx, &vpx_lpf_horizontal_4_c, 8), - make_tuple(&vpx_lpf_horizontal_8_lsx, &vpx_lpf_horizontal_8_c, 8), - make_tuple(&vpx_lpf_horizontal_16_dual_lsx, - &vpx_lpf_horizontal_16_dual_c, 8), - make_tuple(&vpx_lpf_vertical_4_lsx, &vpx_lpf_vertical_4_c, 8), - make_tuple(&vpx_lpf_vertical_8_lsx, &vpx_lpf_vertical_8_c, 8), - make_tuple(&vpx_lpf_vertical_16_dual_lsx, &vpx_lpf_vertical_16_dual_c, - 8))); - -INSTANTIATE_TEST_SUITE_P( - LSX, Loop8Test9Param, - ::testing::Values(make_tuple(&vpx_lpf_horizontal_4_dual_lsx, - &vpx_lpf_horizontal_4_dual_c, 8), - make_tuple(&vpx_lpf_horizontal_8_dual_lsx, - &vpx_lpf_horizontal_8_dual_c, 8), - make_tuple(&vpx_lpf_vertical_4_dual_lsx, - &vpx_lpf_vertical_4_dual_c, 8), - make_tuple(&vpx_lpf_vertical_8_dual_lsx, - &vpx_lpf_vertical_8_dual_c, 8))); -#endif // HAVE_LSX && (!CONFIG_VP9_HIGHBITDEPTH) - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/md5_helper.h b/presentation/src/main/cpp/third_party/libvpx/test/md5_helper.h deleted file mode 100644 index 9095d96a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/md5_helper.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_TEST_MD5_HELPER_H_ -#define VPX_TEST_MD5_HELPER_H_ - -#include "./md5_utils.h" -#include "vpx/vpx_decoder.h" - -namespace libvpx_test { -class MD5 { - public: - MD5() { MD5Init(&md5_); } - - void Add(const vpx_image_t *img) { - for (int plane = 0; plane < 3; ++plane) { - const uint8_t *buf = img->planes[plane]; - // Calculate the width and height to do the md5 check. For the chroma - // plane, we never want to round down and thus skip a pixel so if - // we are shifting by 1 (chroma_shift) we add 1 before doing the shift. - // This works only for chroma_shift of 0 and 1. - const int bytes_per_sample = - (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1; - const int h = - plane ? (img->d_h + img->y_chroma_shift) >> img->y_chroma_shift - : img->d_h; - const int w = - (plane ? (img->d_w + img->x_chroma_shift) >> img->x_chroma_shift - : img->d_w) * - bytes_per_sample; - - for (int y = 0; y < h; ++y) { - MD5Update(&md5_, buf, w); - buf += img->stride[plane]; - } - } - } - - void Add(const uint8_t *data, size_t size) { - MD5Update(&md5_, data, static_cast(size)); - } - - const char *Get() { - static const char hex[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', - }; - uint8_t tmp[16]; - MD5Context ctx_tmp = md5_; - - MD5Final(tmp, &ctx_tmp); - for (int i = 0; i < 16; i++) { - res_[i * 2 + 0] = hex[tmp[i] >> 4]; - res_[i * 2 + 1] = hex[tmp[i] & 0xf]; - } - res_[32] = 0; - - return res_; - } - - protected: - char res_[33]; - MD5Context md5_; -}; - -} // namespace libvpx_test - -#endif // VPX_TEST_MD5_HELPER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/minmax_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/minmax_test.cc deleted file mode 100644 index 94a8bb73..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/minmax_test.cc +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "gtest/gtest.h" - -#include "vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_mem/vpx_mem.h" - -#include "test/acm_random.h" -#include "test/register_state_check.h" - -namespace { - -using ::libvpx_test::ACMRandom; - -typedef void (*MinMaxFunc)(const uint8_t *a, int a_stride, const uint8_t *b, - int b_stride, int *min, int *max); - -class MinMaxTest : public ::testing::TestWithParam { - public: - void SetUp() override { - mm_func_ = GetParam(); - rnd_.Reset(ACMRandom::DeterministicSeed()); - } - - protected: - MinMaxFunc mm_func_; - ACMRandom rnd_; -}; - -void reference_minmax(const uint8_t *a, int a_stride, const uint8_t *b, - int b_stride, int *min_ret, int *max_ret) { - int min = 255; - int max = 0; - for (int i = 0; i < 8; i++) { - for (int j = 0; j < 8; j++) { - const int diff = abs(a[i * a_stride + j] - b[i * b_stride + j]); - if (min > diff) min = diff; - if (max < diff) max = diff; - } - } - - *min_ret = min; - *max_ret = max; -} - -TEST_P(MinMaxTest, MinValue) { - for (int i = 0; i < 64; i++) { - uint8_t a[64], b[64]; - memset(a, 0, sizeof(a)); - memset(b, 255, sizeof(b)); - b[i] = i; // Set a minimum difference of i. - - int min, max; - ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max)); - EXPECT_EQ(255, max); - EXPECT_EQ(i, min); - } -} - -TEST_P(MinMaxTest, MaxValue) { - for (int i = 0; i < 64; i++) { - uint8_t a[64], b[64]; - memset(a, 0, sizeof(a)); - memset(b, 0, sizeof(b)); - b[i] = i; // Set a maximum difference of i. - - int min, max; - ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max)); - EXPECT_EQ(i, max); - EXPECT_EQ(0, min); - } -} - -TEST_P(MinMaxTest, CompareReference) { - uint8_t a[64], b[64]; - for (int j = 0; j < 64; j++) { - a[j] = rnd_.Rand8(); - b[j] = rnd_.Rand8(); - } - - int min_ref, max_ref, min, max; - reference_minmax(a, 8, b, 8, &min_ref, &max_ref); - ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max)); - EXPECT_EQ(max_ref, max); - EXPECT_EQ(min_ref, min); -} - -TEST_P(MinMaxTest, CompareReferenceAndVaryStride) { - uint8_t a[8 * 64], b[8 * 64]; - for (int i = 0; i < 8 * 64; i++) { - a[i] = rnd_.Rand8(); - b[i] = rnd_.Rand8(); - } - for (int a_stride = 8; a_stride <= 64; a_stride += 8) { - for (int b_stride = 8; b_stride <= 64; b_stride += 8) { - int min_ref, max_ref, min, max; - reference_minmax(a, a_stride, b, b_stride, &min_ref, &max_ref); - ASM_REGISTER_STATE_CHECK(mm_func_(a, a_stride, b, b_stride, &min, &max)); - EXPECT_EQ(max_ref, max) - << "when a_stride = " << a_stride << " and b_stride = " << b_stride; - EXPECT_EQ(min_ref, min) - << "when a_stride = " << a_stride << " and b_stride = " << b_stride; - } - } -} - -#if CONFIG_VP9_HIGHBITDEPTH - -using HBDMinMaxTest = MinMaxTest; - -void highbd_reference_minmax(const uint8_t *a, int a_stride, const uint8_t *b, - int b_stride, int *min_ret, int *max_ret) { - int min = 65535; - int max = 0; - const uint16_t *a_ptr = CONVERT_TO_SHORTPTR(a); - const uint16_t *b_ptr = CONVERT_TO_SHORTPTR(b); - for (int i = 0; i < 8; i++) { - for (int j = 0; j < 8; j++) { - const int diff = abs(a_ptr[i * a_stride + j] - b_ptr[i * b_stride + j]); - if (min > diff) min = diff; - if (max < diff) max = diff; - } - } - - *min_ret = min; - *max_ret = max; -} - -TEST_P(HBDMinMaxTest, MinValue) { - uint8_t *a = CONVERT_TO_BYTEPTR( - reinterpret_cast(vpx_malloc(64 * sizeof(uint16_t)))); - uint8_t *b = CONVERT_TO_BYTEPTR( - reinterpret_cast(vpx_malloc(64 * sizeof(uint16_t)))); - for (int i = 0; i < 64; i++) { - vpx_memset16(CONVERT_TO_SHORTPTR(a), 0, 64); - vpx_memset16(CONVERT_TO_SHORTPTR(b), 65535, 64); - CONVERT_TO_SHORTPTR(b)[i] = i; // Set a minimum difference of i. - - int min, max; - ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max)); - EXPECT_EQ(65535, max); - EXPECT_EQ(i, min); - } - vpx_free(CONVERT_TO_SHORTPTR(a)); - vpx_free(CONVERT_TO_SHORTPTR(b)); -} - -TEST_P(HBDMinMaxTest, MaxValue) { - uint8_t *a = CONVERT_TO_BYTEPTR( - reinterpret_cast(vpx_malloc(64 * sizeof(uint16_t)))); - uint8_t *b = CONVERT_TO_BYTEPTR( - reinterpret_cast(vpx_malloc(64 * sizeof(uint16_t)))); - for (int i = 0; i < 64; i++) { - vpx_memset16(CONVERT_TO_SHORTPTR(a), 0, 64); - vpx_memset16(CONVERT_TO_SHORTPTR(b), 0, 64); - CONVERT_TO_SHORTPTR(b)[i] = i; // Set a minimum difference of i. - - int min, max; - ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max)); - EXPECT_EQ(i, max); - EXPECT_EQ(0, min); - } - vpx_free(CONVERT_TO_SHORTPTR(a)); - vpx_free(CONVERT_TO_SHORTPTR(b)); -} - -TEST_P(HBDMinMaxTest, CompareReference) { - uint8_t *a = CONVERT_TO_BYTEPTR( - reinterpret_cast(vpx_malloc(64 * sizeof(uint16_t)))); - uint8_t *b = CONVERT_TO_BYTEPTR( - reinterpret_cast(vpx_malloc(64 * sizeof(uint16_t)))); - for (int j = 0; j < 64; j++) { - CONVERT_TO_SHORTPTR(a)[j] = rnd_.Rand16(); - CONVERT_TO_SHORTPTR(b)[j] = rnd_.Rand16(); - } - - int min_ref, max_ref, min, max; - highbd_reference_minmax(a, 8, b, 8, &min_ref, &max_ref); - ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max)); - vpx_free(CONVERT_TO_SHORTPTR(a)); - vpx_free(CONVERT_TO_SHORTPTR(b)); - EXPECT_EQ(max_ref, max); - EXPECT_EQ(min_ref, min); -} - -TEST_P(HBDMinMaxTest, CompareReferenceAndVaryStride) { - uint8_t *a = CONVERT_TO_BYTEPTR( - reinterpret_cast(vpx_malloc((8 * 64) * sizeof(uint16_t)))); - uint8_t *b = CONVERT_TO_BYTEPTR( - reinterpret_cast(vpx_malloc((8 * 64) * sizeof(uint16_t)))); - for (int i = 0; i < 8 * 64; i++) { - CONVERT_TO_SHORTPTR(a)[i] = rnd_.Rand16(); - CONVERT_TO_SHORTPTR(b)[i] = rnd_.Rand16(); - } - for (int a_stride = 8; a_stride <= 64; a_stride += 8) { - for (int b_stride = 8; b_stride <= 64; b_stride += 8) { - int min_ref, max_ref, min, max; - highbd_reference_minmax(a, a_stride, b, b_stride, &min_ref, &max_ref); - ASM_REGISTER_STATE_CHECK(mm_func_(a, a_stride, b, b_stride, &min, &max)); - EXPECT_EQ(max_ref, max) - << "when a_stride = " << a_stride << " and b_stride = " << b_stride; - EXPECT_EQ(min_ref, min) - << "when a_stride = " << a_stride << " and b_stride = " << b_stride; - } - } - vpx_free(CONVERT_TO_SHORTPTR(a)); - vpx_free(CONVERT_TO_SHORTPTR(b)); -} -#endif - -INSTANTIATE_TEST_SUITE_P(C, MinMaxTest, ::testing::Values(&vpx_minmax_8x8_c)); -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P(C, HBDMinMaxTest, - ::testing::Values(&vpx_highbd_minmax_8x8_c)); -#endif - -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P(SSE2, MinMaxTest, - ::testing::Values(&vpx_minmax_8x8_sse2)); -#endif - -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P(NEON, MinMaxTest, - ::testing::Values(&vpx_minmax_8x8_neon)); -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P(NEON, HBDMinMaxTest, - ::testing::Values(&vpx_highbd_minmax_8x8_neon)); -#endif -#endif - -#if HAVE_MSA -INSTANTIATE_TEST_SUITE_P(MSA, MinMaxTest, - ::testing::Values(&vpx_minmax_8x8_msa)); -#endif - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/non_greedy_mv_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/non_greedy_mv_test.cc deleted file mode 100644 index 6b5dcc65..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/non_greedy_mv_test.cc +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2019 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "gtest/gtest.h" -#include "vp9/encoder/vp9_non_greedy_mv.h" -#include "./vpx_dsp_rtcd.h" - -namespace { - -static void read_in_mf(const char *filename, int *rows_ptr, int *cols_ptr, - MV **buffer_ptr) { - FILE *input = fopen(filename, "rb"); - int row, col; - int idx; - - ASSERT_NE(input, nullptr) << "Cannot open file: " << filename << std::endl; - - fscanf(input, "%d,%d\n", rows_ptr, cols_ptr); - - *buffer_ptr = (MV *)malloc((*rows_ptr) * (*cols_ptr) * sizeof(MV)); - - for (idx = 0; idx < (*rows_ptr) * (*cols_ptr); ++idx) { - fscanf(input, "%d,%d;", &row, &col); - (*buffer_ptr)[idx].row = row; - (*buffer_ptr)[idx].col = col; - } - fclose(input); -} - -static void read_in_local_var(const char *filename, int *rows_ptr, - int *cols_ptr, - int (**M_ptr)[MF_LOCAL_STRUCTURE_SIZE]) { - FILE *input = fopen(filename, "rb"); - int M00, M01, M10, M11; - int idx; - int int_type; - - ASSERT_NE(input, nullptr) << "Cannot open file: " << filename << std::endl; - - fscanf(input, "%d,%d\n", rows_ptr, cols_ptr); - - *M_ptr = (int(*)[MF_LOCAL_STRUCTURE_SIZE])malloc( - (*rows_ptr) * (*cols_ptr) * MF_LOCAL_STRUCTURE_SIZE * sizeof(int_type)); - - for (idx = 0; idx < (*rows_ptr) * (*cols_ptr); ++idx) { - fscanf(input, "%d,%d,%d,%d;", &M00, &M01, &M10, &M11); - (*M_ptr)[idx][0] = M00; - (*M_ptr)[idx][1] = M01; - (*M_ptr)[idx][2] = M10; - (*M_ptr)[idx][3] = M11; - } - fclose(input); -} - -static void compare_mf(const MV *mf1, const MV *mf2, int rows, int cols, - float *mean_ptr, float *std_ptr) { - float float_type; - float *diffs = (float *)malloc(rows * cols * sizeof(float_type)); - int idx; - float accu = 0.0f; - for (idx = 0; idx < rows * cols; ++idx) { - MV mv1 = mf1[idx]; - MV mv2 = mf2[idx]; - float row_diff2 = (float)((mv1.row - mv2.row) * (mv1.row - mv2.row)); - float col_diff2 = (float)((mv1.col - mv2.col) * (mv1.col - mv2.col)); - diffs[idx] = sqrt(row_diff2 + col_diff2); - accu += diffs[idx]; - } - *mean_ptr = accu / rows / cols; - *std_ptr = 0; - for (idx = 0; idx < rows * cols; ++idx) { - *std_ptr += (diffs[idx] - (*mean_ptr)) * (diffs[idx] - (*mean_ptr)); - } - *std_ptr = sqrt(*std_ptr / rows / cols); - free(diffs); -} - -static void load_frame_info(const char *filename, - YV12_BUFFER_CONFIG *ref_frame_ptr) { - FILE *input = fopen(filename, "rb"); - int idx; - uint8_t data_type; - - ASSERT_NE(input, nullptr) << "Cannot open file: " << filename << std::endl; - - fscanf(input, "%d,%d\n", &(ref_frame_ptr->y_height), - &(ref_frame_ptr->y_width)); - - ref_frame_ptr->y_buffer = (uint8_t *)malloc( - (ref_frame_ptr->y_width) * (ref_frame_ptr->y_height) * sizeof(data_type)); - - for (idx = 0; idx < (ref_frame_ptr->y_width) * (ref_frame_ptr->y_height); - ++idx) { - int value; - fscanf(input, "%d,", &value); - ref_frame_ptr->y_buffer[idx] = (uint8_t)value; - } - - ref_frame_ptr->y_stride = ref_frame_ptr->y_width; - fclose(input); -} - -static int compare_local_var(const int (*local_var1)[MF_LOCAL_STRUCTURE_SIZE], - const int (*local_var2)[MF_LOCAL_STRUCTURE_SIZE], - int rows, int cols) { - int diff = 0; - int outter_idx, inner_idx; - for (outter_idx = 0; outter_idx < rows * cols; ++outter_idx) { - for (inner_idx = 0; inner_idx < MF_LOCAL_STRUCTURE_SIZE; ++inner_idx) { - diff += abs(local_var1[outter_idx][inner_idx] - - local_var2[outter_idx][inner_idx]); - } - } - return diff / rows / cols; -} - -TEST(non_greedy_mv, smooth_mf) { - const char *search_mf_file = "non_greedy_mv_test_files/exhaust_16x16.txt"; - const char *local_var_file = "non_greedy_mv_test_files/localVar_16x16.txt"; - const char *estimation_file = "non_greedy_mv_test_files/estimation_16x16.txt"; - const char *ground_truth_file = - "non_greedy_mv_test_files/ground_truth_16x16.txt"; - BLOCK_SIZE bsize = BLOCK_32X32; - MV *search_mf = nullptr; - MV *smooth_mf = nullptr; - MV *estimation = nullptr; - MV *ground_truth = nullptr; - int(*local_var)[MF_LOCAL_STRUCTURE_SIZE] = nullptr; - int rows = 0, cols = 0; - - int alpha = 100, max_iter = 100; - - read_in_mf(search_mf_file, &rows, &cols, &search_mf); - read_in_local_var(local_var_file, &rows, &cols, &local_var); - read_in_mf(estimation_file, &rows, &cols, &estimation); - read_in_mf(ground_truth_file, &rows, &cols, &ground_truth); - - float sm_mean, sm_std; - float est_mean, est_std; - - smooth_mf = (MV *)malloc(rows * cols * sizeof(MV)); - vp9_get_smooth_motion_field(search_mf, local_var, rows, cols, bsize, alpha, - max_iter, smooth_mf); - - compare_mf(smooth_mf, ground_truth, rows, cols, &sm_mean, &sm_std); - compare_mf(smooth_mf, estimation, rows, cols, &est_mean, &est_std); - - EXPECT_LE(sm_mean, 3); - EXPECT_LE(est_mean, 2); - - free(search_mf); - free(local_var); - free(estimation); - free(ground_truth); - free(smooth_mf); -} - -TEST(non_greedy_mv, local_var) { - const char *ref_frame_file = "non_greedy_mv_test_files/ref_frame_16x16.txt"; - const char *cur_frame_file = "non_greedy_mv_test_files/cur_frame_16x16.txt"; - const char *gt_local_var_file = "non_greedy_mv_test_files/localVar_16x16.txt"; - const char *search_mf_file = "non_greedy_mv_test_files/exhaust_16x16.txt"; - BLOCK_SIZE bsize = BLOCK_16X16; - int(*gt_local_var)[MF_LOCAL_STRUCTURE_SIZE] = nullptr; - int(*est_local_var)[MF_LOCAL_STRUCTURE_SIZE] = nullptr; - YV12_BUFFER_CONFIG ref_frame, cur_frame; - int rows, cols; - MV *search_mf; - int int_type; - int local_var_diff; - vp9_variance_fn_ptr_t fn; - - load_frame_info(ref_frame_file, &ref_frame); - load_frame_info(cur_frame_file, &cur_frame); - read_in_mf(search_mf_file, &rows, &cols, &search_mf); - - fn.sdf = vpx_sad16x16; - est_local_var = (int(*)[MF_LOCAL_STRUCTURE_SIZE])malloc( - rows * cols * MF_LOCAL_STRUCTURE_SIZE * sizeof(int_type)); - vp9_get_local_structure(&cur_frame, &ref_frame, search_mf, &fn, rows, cols, - bsize, est_local_var); - read_in_local_var(gt_local_var_file, &rows, &cols, >_local_var); - - local_var_diff = compare_local_var(est_local_var, gt_local_var, rows, cols); - - EXPECT_LE(local_var_diff, 1); - - free(gt_local_var); - free(est_local_var); - free(ref_frame.y_buffer); -} -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/partial_idct_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/partial_idct_test.cc deleted file mode 100644 index d7b1c884..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/partial_idct_test.cc +++ /dev/null @@ -1,974 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vp9_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "test/acm_random.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_scan.h" -#include "vpx/vpx_integer.h" -#include "vpx_config.h" -#include "vpx_ports/vpx_timer.h" - -using libvpx_test::ACMRandom; - -namespace { - -typedef void (*FwdTxfmFunc)(const int16_t *in, tran_low_t *out, int stride); -typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride); -typedef void (*InvTxfmWithBdFunc)(const tran_low_t *in, uint8_t *out, - int stride, int bd); - -template -void wrapper(const tran_low_t *in, uint8_t *out, int stride, int bd) { - (void)bd; - fn(in, out, stride); -} - -#if CONFIG_VP9_HIGHBITDEPTH -typedef void (*InvTxfmHighbdFunc)(const tran_low_t *in, uint16_t *out, - int stride, int bd); -template -void highbd_wrapper(const tran_low_t *in, uint8_t *out, int stride, int bd) { - fn(in, CAST_TO_SHORTPTR(out), stride, bd); -} -#endif - -typedef std::tuple - PartialInvTxfmParam; -const int kMaxNumCoeffs = 1024; -const int kCountTestBlock = 1000; - -class PartialIDctTest : public ::testing::TestWithParam { - public: - ~PartialIDctTest() override = default; - void SetUp() override { - rnd_.Reset(ACMRandom::DeterministicSeed()); - fwd_txfm_ = GET_PARAM(0); - full_inv_txfm_ = GET_PARAM(1); - partial_inv_txfm_ = GET_PARAM(2); - tx_size_ = GET_PARAM(3); - last_nonzero_ = GET_PARAM(4); - bit_depth_ = GET_PARAM(5); - pixel_size_ = GET_PARAM(6); - mask_ = (1 << bit_depth_) - 1; - - switch (tx_size_) { - case TX_4X4: size_ = 4; break; - case TX_8X8: size_ = 8; break; - case TX_16X16: size_ = 16; break; - case TX_32X32: size_ = 32; break; - default: FAIL() << "Wrong Size!"; - } - - // Randomize stride_ to a value less than or equal to 1024 - stride_ = rnd_(1024) + 1; - if (stride_ < size_) { - stride_ = size_; - } - // Align stride_ to 16 if it's bigger than 16. - if (stride_ > 16) { - stride_ &= ~15; - } - - input_block_size_ = size_ * size_; - output_block_size_ = size_ * stride_; - - input_block_ = reinterpret_cast( - vpx_memalign(16, sizeof(*input_block_) * input_block_size_)); - output_block_ = reinterpret_cast( - vpx_memalign(16, pixel_size_ * output_block_size_)); - output_block_ref_ = reinterpret_cast( - vpx_memalign(16, pixel_size_ * output_block_size_)); - } - - void TearDown() override { - vpx_free(input_block_); - input_block_ = nullptr; - vpx_free(output_block_); - output_block_ = nullptr; - vpx_free(output_block_ref_); - output_block_ref_ = nullptr; - libvpx_test::ClearSystemState(); - } - - void InitMem() { - memset(input_block_, 0, sizeof(*input_block_) * input_block_size_); - if (pixel_size_ == 1) { - for (int j = 0; j < output_block_size_; ++j) { - output_block_[j] = output_block_ref_[j] = rnd_.Rand16() & mask_; - } - } else { - ASSERT_EQ(2, pixel_size_); - uint16_t *const output = reinterpret_cast(output_block_); - uint16_t *const output_ref = - reinterpret_cast(output_block_ref_); - for (int j = 0; j < output_block_size_; ++j) { - output[j] = output_ref[j] = rnd_.Rand16() & mask_; - } - } - } - - void InitInput() { - const int64_t max_coeff = (32766 << (bit_depth_ - 8)) / 4; - int64_t max_energy_leftover = max_coeff * max_coeff; - for (int j = 0; j < last_nonzero_; ++j) { - tran_low_t coeff = static_cast( - sqrt(1.0 * max_energy_leftover) * (rnd_.Rand16() - 32768) / 65536); - max_energy_leftover -= static_cast(coeff) * coeff; - if (max_energy_leftover < 0) { - max_energy_leftover = 0; - coeff = 0; - } - input_block_[vp9_default_scan_orders[tx_size_].scan[j]] = coeff; - } - } - - void PrintDiff() { - if (memcmp(output_block_ref_, output_block_, - pixel_size_ * output_block_size_)) { - uint16_t ref, opt; - for (int y = 0; y < size_; y++) { - for (int x = 0; x < size_; x++) { - if (pixel_size_ == 1) { - ref = output_block_ref_[y * stride_ + x]; - opt = output_block_[y * stride_ + x]; - } else { - ref = reinterpret_cast( - output_block_ref_)[y * stride_ + x]; - opt = reinterpret_cast(output_block_)[y * stride_ + x]; - } - if (ref != opt) { - printf("dest[%d][%d] diff:%6d (ref),%6d (opt)\n", y, x, ref, opt); - } - } - } - - printf("\ninput_block_:\n"); - for (int y = 0; y < size_; y++) { - for (int x = 0; x < size_; x++) { - printf("%6d,", input_block_[y * size_ + x]); - } - printf("\n"); - } - } - } - - protected: - int last_nonzero_; - TX_SIZE tx_size_; - tran_low_t *input_block_; - uint8_t *output_block_; - uint8_t *output_block_ref_; - int size_; - int stride_; - int pixel_size_; - int input_block_size_; - int output_block_size_; - int bit_depth_; - int mask_; - FwdTxfmFunc fwd_txfm_; - InvTxfmWithBdFunc full_inv_txfm_; - InvTxfmWithBdFunc partial_inv_txfm_; - ACMRandom rnd_; -}; - -TEST_P(PartialIDctTest, RunQuantCheck) { - const int count_test_block = (size_ != 4) ? kCountTestBlock : 65536; - DECLARE_ALIGNED(16, int16_t, input_extreme_block[kMaxNumCoeffs]); - DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kMaxNumCoeffs]); - - InitMem(); - - for (int i = 0; i < count_test_block; ++i) { - // Initialize a test block with input range [-mask_, mask_]. - if (size_ != 4) { - if (i == 0) { - for (int k = 0; k < input_block_size_; ++k) { - input_extreme_block[k] = mask_; - } - } else if (i == 1) { - for (int k = 0; k < input_block_size_; ++k) { - input_extreme_block[k] = -mask_; - } - } else { - for (int k = 0; k < input_block_size_; ++k) { - input_extreme_block[k] = rnd_.Rand8() % 2 ? mask_ : -mask_; - } - } - } else { - // Try all possible combinations. - for (int k = 0; k < input_block_size_; ++k) { - input_extreme_block[k] = (i & (1 << k)) ? mask_ : -mask_; - } - } - - fwd_txfm_(input_extreme_block, output_ref_block, size_); - - // quantization with minimum allowed step sizes - input_block_[0] = (output_ref_block[0] / 4) * 4; - for (int k = 1; k < last_nonzero_; ++k) { - const int pos = vp9_default_scan_orders[tx_size_].scan[k]; - input_block_[pos] = (output_ref_block[pos] / 4) * 4; - } - - ASM_REGISTER_STATE_CHECK( - full_inv_txfm_(input_block_, output_block_ref_, stride_, bit_depth_)); - ASM_REGISTER_STATE_CHECK( - partial_inv_txfm_(input_block_, output_block_, stride_, bit_depth_)); - ASSERT_EQ(0, memcmp(output_block_ref_, output_block_, - pixel_size_ * output_block_size_)) - << "Error: partial inverse transform produces different results"; - } -} - -TEST_P(PartialIDctTest, ResultsMatch) { - for (int i = 0; i < kCountTestBlock; ++i) { - InitMem(); - InitInput(); - - ASM_REGISTER_STATE_CHECK( - full_inv_txfm_(input_block_, output_block_ref_, stride_, bit_depth_)); - ASM_REGISTER_STATE_CHECK( - partial_inv_txfm_(input_block_, output_block_, stride_, bit_depth_)); - ASSERT_EQ(0, memcmp(output_block_ref_, output_block_, - pixel_size_ * output_block_size_)) - << "Error: partial inverse transform produces different results"; - } -} - -TEST_P(PartialIDctTest, AddOutputBlock) { - for (int i = 0; i < kCountTestBlock; ++i) { - InitMem(); - for (int j = 0; j < last_nonzero_; ++j) { - input_block_[vp9_default_scan_orders[tx_size_].scan[j]] = 10; - } - - ASM_REGISTER_STATE_CHECK( - full_inv_txfm_(input_block_, output_block_ref_, stride_, bit_depth_)); - ASM_REGISTER_STATE_CHECK( - partial_inv_txfm_(input_block_, output_block_, stride_, bit_depth_)); - ASSERT_EQ(0, memcmp(output_block_ref_, output_block_, - pixel_size_ * output_block_size_)) - << "Error: Transform results are not correctly added to output."; - } -} - -TEST_P(PartialIDctTest, SingleExtremeCoeff) { - const int16_t max_coeff = std::numeric_limits::max(); - const int16_t min_coeff = std::numeric_limits::min(); - for (int i = 0; i < last_nonzero_; ++i) { - memset(input_block_, 0, sizeof(*input_block_) * input_block_size_); - // Run once for min and once for max. - for (int j = 0; j < 2; ++j) { - const int coeff = j ? min_coeff : max_coeff; - - memset(output_block_, 0, pixel_size_ * output_block_size_); - memset(output_block_ref_, 0, pixel_size_ * output_block_size_); - input_block_[vp9_default_scan_orders[tx_size_].scan[i]] = coeff; - - ASM_REGISTER_STATE_CHECK( - full_inv_txfm_(input_block_, output_block_ref_, stride_, bit_depth_)); - ASM_REGISTER_STATE_CHECK( - partial_inv_txfm_(input_block_, output_block_, stride_, bit_depth_)); - ASSERT_EQ(0, memcmp(output_block_ref_, output_block_, - pixel_size_ * output_block_size_)) - << "Error: Fails with single coeff of " << coeff << " at " << i - << "."; - } - } -} - -TEST_P(PartialIDctTest, DISABLED_Speed) { - // Keep runtime stable with transform size. - const int kCountSpeedTestBlock = 500000000 / input_block_size_; - InitMem(); - InitInput(); - - for (int i = 0; i < kCountSpeedTestBlock; ++i) { - ASM_REGISTER_STATE_CHECK( - full_inv_txfm_(input_block_, output_block_ref_, stride_, bit_depth_)); - } - vpx_usec_timer timer; - vpx_usec_timer_start(&timer); - for (int i = 0; i < kCountSpeedTestBlock; ++i) { - partial_inv_txfm_(input_block_, output_block_, stride_, bit_depth_); - } - libvpx_test::ClearSystemState(); - vpx_usec_timer_mark(&timer); - const int elapsed_time = - static_cast(vpx_usec_timer_elapsed(&timer) / 1000); - printf("idct%dx%d_%d (%s %d) time: %5d ms\n", size_, size_, last_nonzero_, - (pixel_size_ == 1) ? "bitdepth" : "high bitdepth", bit_depth_, - elapsed_time); - ASSERT_EQ(0, memcmp(output_block_ref_, output_block_, - pixel_size_ * output_block_size_)) - << "Error: partial inverse transform produces different results"; -} - -using std::make_tuple; - -const PartialInvTxfmParam c_partial_idct_tests[] = { -#if CONFIG_VP9_HIGHBITDEPTH - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 1024, 8, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 1024, 10, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 1024, 12, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 135, 8, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 135, 10, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 135, 12, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 34, 8, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 34, 10, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 34, 12, 2), - make_tuple(&vpx_highbd_fdct32x32_c, - &highbd_wrapper, - &highbd_wrapper, TX_32X32, 1, 8, 2), - make_tuple(&vpx_highbd_fdct32x32_c, - &highbd_wrapper, - &highbd_wrapper, TX_32X32, 1, 10, 2), - make_tuple(&vpx_highbd_fdct32x32_c, - &highbd_wrapper, - &highbd_wrapper, TX_32X32, 1, 12, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 256, 8, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 256, 10, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 256, 12, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 38, 8, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 38, 10, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 38, 12, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 10, 8, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 10, 10, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 10, 12, 2), - make_tuple(&vpx_highbd_fdct16x16_c, - &highbd_wrapper, - &highbd_wrapper, TX_16X16, 1, 8, 2), - make_tuple(&vpx_highbd_fdct16x16_c, - &highbd_wrapper, - &highbd_wrapper, TX_16X16, 1, 10, 2), - make_tuple(&vpx_highbd_fdct16x16_c, - &highbd_wrapper, - &highbd_wrapper, TX_16X16, 1, 12, 2), - make_tuple(&vpx_highbd_fdct8x8_c, - &highbd_wrapper, - &highbd_wrapper, TX_8X8, 64, 8, 2), - make_tuple(&vpx_highbd_fdct8x8_c, - &highbd_wrapper, - &highbd_wrapper, TX_8X8, 64, 10, 2), - make_tuple(&vpx_highbd_fdct8x8_c, - &highbd_wrapper, - &highbd_wrapper, TX_8X8, 64, 12, 2), - make_tuple(&vpx_highbd_fdct8x8_c, - &highbd_wrapper, - &highbd_wrapper, TX_8X8, 12, 8, 2), - make_tuple(&vpx_highbd_fdct8x8_c, - &highbd_wrapper, - &highbd_wrapper, TX_8X8, 12, 10, 2), - make_tuple(&vpx_highbd_fdct8x8_c, - &highbd_wrapper, - &highbd_wrapper, TX_8X8, 12, 12, 2), - make_tuple(&vpx_highbd_fdct8x8_c, - &highbd_wrapper, - &highbd_wrapper, TX_8X8, 1, 8, 2), - make_tuple(&vpx_highbd_fdct8x8_c, - &highbd_wrapper, - &highbd_wrapper, TX_8X8, 1, 10, 2), - make_tuple(&vpx_highbd_fdct8x8_c, - &highbd_wrapper, - &highbd_wrapper, TX_8X8, 1, 12, 2), - make_tuple(&vpx_highbd_fdct4x4_c, - &highbd_wrapper, - &highbd_wrapper, TX_4X4, 16, 8, 2), - make_tuple(&vpx_highbd_fdct4x4_c, - &highbd_wrapper, - &highbd_wrapper, TX_4X4, 16, 10, 2), - make_tuple(&vpx_highbd_fdct4x4_c, - &highbd_wrapper, - &highbd_wrapper, TX_4X4, 16, 12, 2), - make_tuple(&vpx_highbd_fdct4x4_c, - &highbd_wrapper, - &highbd_wrapper, TX_4X4, 1, 8, 2), - make_tuple(&vpx_highbd_fdct4x4_c, - &highbd_wrapper, - &highbd_wrapper, TX_4X4, 1, 10, 2), - make_tuple(&vpx_highbd_fdct4x4_c, - &highbd_wrapper, - &highbd_wrapper, TX_4X4, 1, 12, 2), -#endif // CONFIG_VP9_HIGHBITDEPTH - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 1024, 8, 1), - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 135, 8, 1), - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 34, 8, 1), - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 1, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 256, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 38, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 10, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 1, 8, 1), - make_tuple(&vpx_fdct8x8_c, &wrapper, - &wrapper, TX_8X8, 64, 8, 1), - make_tuple(&vpx_fdct8x8_c, &wrapper, - &wrapper, TX_8X8, 12, 8, 1), - make_tuple(&vpx_fdct8x8_c, &wrapper, - &wrapper, TX_8X8, 1, 8, 1), - make_tuple(&vpx_fdct4x4_c, &wrapper, - &wrapper, TX_4X4, 16, 8, 1), - make_tuple(&vpx_fdct4x4_c, &wrapper, - &wrapper, TX_4X4, 1, 8, 1) -}; - -INSTANTIATE_TEST_SUITE_P(C, PartialIDctTest, - ::testing::ValuesIn(c_partial_idct_tests)); - -#if !CONFIG_EMULATE_HARDWARE - -#if HAVE_NEON -const PartialInvTxfmParam neon_partial_idct_tests[] = { -#if CONFIG_VP9_HIGHBITDEPTH - make_tuple(&vpx_highbd_fdct32x32_c, - &highbd_wrapper, - &highbd_wrapper, TX_32X32, - 1024, 8, 2), - make_tuple(&vpx_highbd_fdct32x32_c, - &highbd_wrapper, - &highbd_wrapper, TX_32X32, - 1024, 10, 2), - make_tuple(&vpx_highbd_fdct32x32_c, - &highbd_wrapper, - &highbd_wrapper, TX_32X32, - 1024, 12, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 135, 8, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 135, 10, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 135, 12, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 34, 8, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 34, 10, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 34, 12, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 1, 8, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 1, 10, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 1, 12, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 256, 8, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 256, 10, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 256, 12, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 38, 8, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 38, 10, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 38, 12, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 10, 8, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 10, 10, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 10, 12, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 1, 8, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 1, 10, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 1, 12, 2), - make_tuple(&vpx_highbd_fdct8x8_c, - &highbd_wrapper, - &highbd_wrapper, TX_8X8, 64, 8, 2), - make_tuple( - &vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 64, 10, 2), - make_tuple( - &vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 64, 12, 2), - make_tuple(&vpx_highbd_fdct8x8_c, - &highbd_wrapper, - &highbd_wrapper, TX_8X8, 12, 8, 2), - make_tuple( - &vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 12, 10, 2), - make_tuple( - &vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 12, 12, 2), - make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 1, 8, 2), - make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 1, 10, 2), - make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 1, 12, 2), - make_tuple(&vpx_highbd_fdct4x4_c, - &highbd_wrapper, - &highbd_wrapper, TX_4X4, 16, 8, 2), - make_tuple( - &vpx_highbd_fdct4x4_c, &highbd_wrapper, - &highbd_wrapper, TX_4X4, 16, 10, 2), - make_tuple( - &vpx_highbd_fdct4x4_c, &highbd_wrapper, - &highbd_wrapper, TX_4X4, 16, 12, 2), - make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper, - &highbd_wrapper, TX_4X4, 1, 8, 2), - make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper, - &highbd_wrapper, TX_4X4, 1, 10, 2), - make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper, - &highbd_wrapper, TX_4X4, 1, 12, 2), -#endif // CONFIG_VP9_HIGHBITDEPTH - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 1024, 8, 1), - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 135, 8, 1), - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 34, 8, 1), - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 1, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 256, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 38, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 10, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 1, 8, 1), - make_tuple(&vpx_fdct8x8_c, &wrapper, - &wrapper, TX_8X8, 64, 8, 1), - make_tuple(&vpx_fdct8x8_c, &wrapper, - &wrapper, TX_8X8, 12, 8, 1), - make_tuple(&vpx_fdct8x8_c, &wrapper, - &wrapper, TX_8X8, 1, 8, 1), - make_tuple(&vpx_fdct4x4_c, &wrapper, - &wrapper, TX_4X4, 16, 8, 1), - make_tuple(&vpx_fdct4x4_c, &wrapper, - &wrapper, TX_4X4, 1, 8, 1) -}; - -INSTANTIATE_TEST_SUITE_P(NEON, PartialIDctTest, - ::testing::ValuesIn(neon_partial_idct_tests)); -#endif // HAVE_NEON - -#if HAVE_SSE2 -// 32x32_135_ is implemented using the 1024 version. -const PartialInvTxfmParam sse2_partial_idct_tests[] = { -#if CONFIG_VP9_HIGHBITDEPTH - make_tuple(&vpx_highbd_fdct32x32_c, - &highbd_wrapper, - &highbd_wrapper, TX_32X32, - 1024, 8, 2), - make_tuple(&vpx_highbd_fdct32x32_c, - &highbd_wrapper, - &highbd_wrapper, TX_32X32, - 1024, 10, 2), - make_tuple(&vpx_highbd_fdct32x32_c, - &highbd_wrapper, - &highbd_wrapper, TX_32X32, - 1024, 12, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 135, 8, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 135, 10, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 135, 12, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 34, 8, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 34, 10, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 34, 12, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 1, 8, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 1, 10, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 1, 12, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 256, 8, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 256, 10, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 256, 12, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 38, 8, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 38, 10, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 38, 12, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 10, 8, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 10, 10, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 10, 12, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 1, 8, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 1, 10, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 1, 12, 2), - make_tuple(&vpx_highbd_fdct8x8_c, - &highbd_wrapper, - &highbd_wrapper, TX_8X8, 64, 8, 2), - make_tuple( - &vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 64, 10, 2), - make_tuple( - &vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 64, 12, 2), - make_tuple(&vpx_highbd_fdct8x8_c, - &highbd_wrapper, - &highbd_wrapper, TX_8X8, 12, 8, 2), - make_tuple( - &vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 12, 10, 2), - make_tuple( - &vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 12, 12, 2), - make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 1, 8, 2), - make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 1, 10, 2), - make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 1, 12, 2), - make_tuple(&vpx_highbd_fdct4x4_c, - &highbd_wrapper, - &highbd_wrapper, TX_4X4, 16, 8, 2), - make_tuple( - &vpx_highbd_fdct4x4_c, &highbd_wrapper, - &highbd_wrapper, TX_4X4, 16, 10, 2), - make_tuple( - &vpx_highbd_fdct4x4_c, &highbd_wrapper, - &highbd_wrapper, TX_4X4, 16, 12, 2), - make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper, - &highbd_wrapper, TX_4X4, 1, 8, 2), - make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper, - &highbd_wrapper, TX_4X4, 1, 10, 2), - make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper, - &highbd_wrapper, TX_4X4, 1, 12, 2), -#endif // CONFIG_VP9_HIGHBITDEPTH - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 1024, 8, 1), - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 135, 8, 1), - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 34, 8, 1), - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 1, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 256, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 38, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 10, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 1, 8, 1), - make_tuple(&vpx_fdct8x8_c, &wrapper, - &wrapper, TX_8X8, 64, 8, 1), - make_tuple(&vpx_fdct8x8_c, &wrapper, - &wrapper, TX_8X8, 12, 8, 1), - make_tuple(&vpx_fdct8x8_c, &wrapper, - &wrapper, TX_8X8, 1, 8, 1), - make_tuple(&vpx_fdct4x4_c, &wrapper, - &wrapper, TX_4X4, 16, 8, 1), - make_tuple(&vpx_fdct4x4_c, &wrapper, - &wrapper, TX_4X4, 1, 8, 1) -}; - -INSTANTIATE_TEST_SUITE_P(SSE2, PartialIDctTest, - ::testing::ValuesIn(sse2_partial_idct_tests)); - -#endif // HAVE_SSE2 - -#if HAVE_SSSE3 -const PartialInvTxfmParam ssse3_partial_idct_tests[] = { - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 135, 8, 1), - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 34, 8, 1), - make_tuple(&vpx_fdct8x8_c, &wrapper, - &wrapper, TX_8X8, 12, 8, 1) -}; - -INSTANTIATE_TEST_SUITE_P(SSSE3, PartialIDctTest, - ::testing::ValuesIn(ssse3_partial_idct_tests)); -#endif // HAVE_SSSE3 - -#if HAVE_SSE4_1 && CONFIG_VP9_HIGHBITDEPTH -const PartialInvTxfmParam sse4_1_partial_idct_tests[] = { - make_tuple(&vpx_highbd_fdct32x32_c, - &highbd_wrapper, - &highbd_wrapper, TX_32X32, - 1024, 8, 2), - make_tuple(&vpx_highbd_fdct32x32_c, - &highbd_wrapper, - &highbd_wrapper, TX_32X32, - 1024, 10, 2), - make_tuple(&vpx_highbd_fdct32x32_c, - &highbd_wrapper, - &highbd_wrapper, TX_32X32, - 1024, 12, 2), - make_tuple(&vpx_highbd_fdct32x32_c, - &highbd_wrapper, - &highbd_wrapper, TX_32X32, - 135, 8, 2), - make_tuple(&vpx_highbd_fdct32x32_c, - &highbd_wrapper, - &highbd_wrapper, TX_32X32, - 135, 10, 2), - make_tuple(&vpx_highbd_fdct32x32_c, - &highbd_wrapper, - &highbd_wrapper, TX_32X32, - 135, 12, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 34, 8, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 34, 10, 2), - make_tuple( - &vpx_highbd_fdct32x32_c, &highbd_wrapper, - &highbd_wrapper, TX_32X32, 34, 12, 2), - make_tuple(&vpx_highbd_fdct16x16_c, - &highbd_wrapper, - &highbd_wrapper, TX_16X16, - 256, 8, 2), - make_tuple(&vpx_highbd_fdct16x16_c, - &highbd_wrapper, - &highbd_wrapper, TX_16X16, - 256, 10, 2), - make_tuple(&vpx_highbd_fdct16x16_c, - &highbd_wrapper, - &highbd_wrapper, TX_16X16, - 256, 12, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 38, 8, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 38, 10, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 38, 12, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 10, 8, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 10, 10, 2), - make_tuple( - &vpx_highbd_fdct16x16_c, &highbd_wrapper, - &highbd_wrapper, TX_16X16, 10, 12, 2), - make_tuple( - &vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 64, 8, 2), - make_tuple( - &vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 64, 10, 2), - make_tuple( - &vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 64, 12, 2), - make_tuple( - &vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 12, 8, 2), - make_tuple( - &vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 12, 10, 2), - make_tuple( - &vpx_highbd_fdct8x8_c, &highbd_wrapper, - &highbd_wrapper, TX_8X8, 12, 12, 2), - make_tuple( - &vpx_highbd_fdct4x4_c, &highbd_wrapper, - &highbd_wrapper, TX_4X4, 16, 8, 2), - make_tuple( - &vpx_highbd_fdct4x4_c, &highbd_wrapper, - &highbd_wrapper, TX_4X4, 16, 10, 2), - make_tuple( - &vpx_highbd_fdct4x4_c, &highbd_wrapper, - &highbd_wrapper, TX_4X4, 16, 12, 2) -}; - -INSTANTIATE_TEST_SUITE_P(SSE4_1, PartialIDctTest, - ::testing::ValuesIn(sse4_1_partial_idct_tests)); -#endif // HAVE_SSE4_1 && CONFIG_VP9_HIGHBITDEPTH - -#if HAVE_DSPR2 && !CONFIG_VP9_HIGHBITDEPTH -const PartialInvTxfmParam dspr2_partial_idct_tests[] = { - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 1024, 8, 1), - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 34, 8, 1), - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 1, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 256, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 10, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 1, 8, 1), - make_tuple(&vpx_fdct8x8_c, &wrapper, - &wrapper, TX_8X8, 64, 8, 1), - make_tuple(&vpx_fdct8x8_c, &wrapper, - &wrapper, TX_8X8, 12, 8, 1), - make_tuple(&vpx_fdct8x8_c, &wrapper, - &wrapper, TX_8X8, 1, 8, 1), - make_tuple(&vpx_fdct4x4_c, &wrapper, - &wrapper, TX_4X4, 16, 8, 1), - make_tuple(&vpx_fdct4x4_c, &wrapper, - &wrapper, TX_4X4, 1, 8, 1) -}; - -INSTANTIATE_TEST_SUITE_P(DSPR2, PartialIDctTest, - ::testing::ValuesIn(dspr2_partial_idct_tests)); -#endif // HAVE_DSPR2 && !CONFIG_VP9_HIGHBITDEPTH - -#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH -// 32x32_135_ is implemented using the 1024 version. -const PartialInvTxfmParam msa_partial_idct_tests[] = { - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 1024, 8, 1), - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 34, 8, 1), - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 1, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 256, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 10, 8, 1), - make_tuple(&vpx_fdct16x16_c, &wrapper, - &wrapper, TX_16X16, 1, 8, 1), - make_tuple(&vpx_fdct8x8_c, &wrapper, - &wrapper, TX_8X8, 64, 8, 1), - make_tuple(&vpx_fdct8x8_c, &wrapper, - &wrapper, TX_8X8, 12, 8, 1), - make_tuple(&vpx_fdct8x8_c, &wrapper, - &wrapper, TX_8X8, 1, 8, 1), - make_tuple(&vpx_fdct4x4_c, &wrapper, - &wrapper, TX_4X4, 16, 8, 1), - make_tuple(&vpx_fdct4x4_c, &wrapper, - &wrapper, TX_4X4, 1, 8, 1) -}; - -INSTANTIATE_TEST_SUITE_P(MSA, PartialIDctTest, - ::testing::ValuesIn(msa_partial_idct_tests)); -#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH - -#if HAVE_LSX && !CONFIG_VP9_HIGHBITDEPTH -const PartialInvTxfmParam lsx_partial_idct_tests[] = { - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 1024, 8, 1), - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 34, 8, 1), - make_tuple(&vpx_fdct32x32_c, &wrapper, - &wrapper, TX_32X32, 1, 8, 1), -}; - -INSTANTIATE_TEST_SUITE_P(LSX, PartialIDctTest, - ::testing::ValuesIn(lsx_partial_idct_tests)); -#endif // HAVE_LSX && !CONFIG_VP9_HIGHBITDEPTH - -#endif // !CONFIG_EMULATE_HARDWARE - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/postproc.sh b/presentation/src/main/cpp/third_party/libvpx/test/postproc.sh deleted file mode 100644 index 91ca9b26..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/postproc.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2014 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## This file tests the libvpx postproc example code. To add new tests to this -## file, do the following: -## 1. Write a shell function (this is your test). -## 2. Add the function to postproc_tests (on a new line). -## -. $(dirname $0)/tools_common.sh - -# Environment check: Make sure input is available: -# $VP8_IVF_FILE and $VP9_IVF_FILE are required. -postproc_verify_environment() { - if [ ! -e "${VP8_IVF_FILE}" ] || [ ! -e "${VP9_IVF_FILE}" ]; then - echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH." - return 1 - fi -} - -# Runs postproc using $1 as input file. $2 is the codec name, and is used -# solely to name the output file. -postproc() { - local decoder="${LIBVPX_BIN_PATH}/postproc${VPX_TEST_EXE_SUFFIX}" - local input_file="$1" - local codec="$2" - local output_file="${VPX_TEST_OUTPUT_DIR}/postproc_${codec}.raw" - - if [ ! -x "${decoder}" ]; then - elog "${decoder} does not exist or is not executable." - return 1 - fi - - eval "${VPX_TEST_PREFIX}" "${decoder}" "${input_file}" "${output_file}" \ - ${devnull} || return 1 - - [ -e "${output_file}" ] || return 1 -} - -postproc_vp8() { - if [ "$(vp8_decode_available)" = "yes" ]; then - postproc "${VP8_IVF_FILE}" vp8 || return 1 - fi -} - -postproc_vp9() { - if [ "$(vpx_config_option_enabled CONFIG_VP9_POSTPROC)" = "yes" ]; then - if [ "$(vp9_decode_available)" = "yes" ]; then - postproc "${VP9_IVF_FILE}" vp9 || return 1 - fi - fi -} - -postproc_tests="postproc_vp8 - postproc_vp9" - -run_tests postproc_verify_environment "${postproc_tests}" diff --git a/presentation/src/main/cpp/third_party/libvpx/test/pp_filter_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/pp_filter_test.cc deleted file mode 100644 index 10f23b33..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/pp_filter_test.cc +++ /dev/null @@ -1,575 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "gtest/gtest.h" -#include "test/acm_random.h" -#include "test/bench.h" -#include "test/buffer.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "vpx/vpx_integer.h" -#include "vpx_mem/vpx_mem.h" - -using libvpx_test::ACMRandom; -using libvpx_test::Buffer; - -typedef void (*VpxPostProcDownAndAcrossMbRowFunc)( - unsigned char *src_ptr, unsigned char *dst_ptr, int src_pixels_per_line, - int dst_pixels_per_line, int cols, unsigned char *flimit, int size); - -typedef void (*VpxMbPostProcAcrossIpFunc)(unsigned char *src, int pitch, - int rows, int cols, int flimit); - -typedef void (*VpxMbPostProcDownFunc)(unsigned char *dst, int pitch, int rows, - int cols, int flimit); - -namespace { -// Compute the filter level used in post proc from the loop filter strength -int q2mbl(int x) { - if (x < 20) x = 20; - - x = 50 + (x - 50) * 10 / 8; - return x * x / 3; -} - -class VpxPostProcDownAndAcrossMbRowTest - : public AbstractBench, - public ::testing::TestWithParam { - public: - VpxPostProcDownAndAcrossMbRowTest() - : mb_post_proc_down_and_across_(GetParam()) {} - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - void Run() override; - - const VpxPostProcDownAndAcrossMbRowFunc mb_post_proc_down_and_across_; - // Size of the underlying data block that will be filtered. - int block_width_; - int block_height_; - Buffer *src_image_; - Buffer *dst_image_; - uint8_t *flimits_; -}; - -void VpxPostProcDownAndAcrossMbRowTest::Run() { - mb_post_proc_down_and_across_( - src_image_->TopLeftPixel(), dst_image_->TopLeftPixel(), - src_image_->stride(), dst_image_->stride(), block_width_, flimits_, 16); -} - -// Test routine for the VPx post-processing function -// vpx_post_proc_down_and_across_mb_row_c. - -TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckFilterOutput) { - // Size of the underlying data block that will be filtered. - block_width_ = 16; - block_height_ = 16; - - // 5-tap filter needs 2 padding rows above and below the block in the input. - Buffer src_image = Buffer(block_width_, block_height_, 2); - ASSERT_TRUE(src_image.Init()); - - // Filter extends output block by 8 samples at left and right edges. - // Though the left padding is only 8 bytes, the assembly code tries to - // read 16 bytes before the pointer. - Buffer dst_image = - Buffer(block_width_, block_height_, 8, 16, 8, 8); - ASSERT_TRUE(dst_image.Init()); - - flimits_ = reinterpret_cast(vpx_memalign(16, block_width_)); - (void)memset(flimits_, 255, block_width_); - - // Initialize pixels in the input: - // block pixels to value 1, - // border pixels to value 10. - src_image.SetPadding(10); - src_image.Set(1); - - // Initialize pixels in the output to 99. - dst_image.Set(99); - - ASM_REGISTER_STATE_CHECK(mb_post_proc_down_and_across_( - src_image.TopLeftPixel(), dst_image.TopLeftPixel(), src_image.stride(), - dst_image.stride(), block_width_, flimits_, 16)); - - static const uint8_t kExpectedOutput[] = { 4, 3, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 4 }; - - uint8_t *pixel_ptr = dst_image.TopLeftPixel(); - for (int i = 0; i < block_height_; ++i) { - for (int j = 0; j < block_width_; ++j) { - ASSERT_EQ(kExpectedOutput[i], pixel_ptr[j]) - << "at (" << i << ", " << j << ")"; - } - pixel_ptr += dst_image.stride(); - } - - vpx_free(flimits_); -} - -TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckCvsAssembly) { - // Size of the underlying data block that will be filtered. - // Y blocks are always a multiple of 16 wide and exactly 16 high. U and V - // blocks are always a multiple of 8 wide and exactly 8 high. - block_width_ = 136; - block_height_ = 16; - - // 5-tap filter needs 2 padding rows above and below the block in the input. - // SSE2 reads in blocks of 16. Pad an extra 8 in case the width is not %16. - Buffer src_image = - Buffer(block_width_, block_height_, 2, 2, 10, 2); - ASSERT_TRUE(src_image.Init()); - - // Filter extends output block by 8 samples at left and right edges. - // Though the left padding is only 8 bytes, there is 'above' padding as well - // so when the assembly code tries to read 16 bytes before the pointer it is - // not a problem. - // SSE2 reads in blocks of 16. Pad an extra 8 in case the width is not %16. - Buffer dst_image = - Buffer(block_width_, block_height_, 8, 8, 16, 8); - ASSERT_TRUE(dst_image.Init()); - Buffer dst_image_ref = - Buffer(block_width_, block_height_, 8); - ASSERT_TRUE(dst_image_ref.Init()); - - // Filter values are set in blocks of 16 for Y and 8 for U/V. Each macroblock - // can have a different filter. SSE2 assembly reads flimits in blocks of 16 so - // it must be padded out. - const int flimits_width = block_width_ % 16 ? block_width_ + 8 : block_width_; - flimits_ = reinterpret_cast(vpx_memalign(16, flimits_width)); - - ACMRandom rnd; - rnd.Reset(ACMRandom::DeterministicSeed()); - // Initialize pixels in the input: - // block pixels to random values. - // border pixels to value 10. - src_image.SetPadding(10); - src_image.Set(&rnd, &ACMRandom::Rand8); - - for (int blocks = 0; blocks < block_width_; blocks += 8) { - (void)memset(flimits_, 0, sizeof(*flimits_) * flimits_width); - - for (int f = 0; f < 255; f++) { - (void)memset(flimits_ + blocks, f, sizeof(*flimits_) * 8); - dst_image.Set(0); - dst_image_ref.Set(0); - - vpx_post_proc_down_and_across_mb_row_c( - src_image.TopLeftPixel(), dst_image_ref.TopLeftPixel(), - src_image.stride(), dst_image_ref.stride(), block_width_, flimits_, - block_height_); - ASM_REGISTER_STATE_CHECK(mb_post_proc_down_and_across_( - src_image.TopLeftPixel(), dst_image.TopLeftPixel(), - src_image.stride(), dst_image.stride(), block_width_, flimits_, - block_height_)); - - ASSERT_TRUE(dst_image.CheckValues(dst_image_ref)); - } - } - - vpx_free(flimits_); -} - -TEST_P(VpxPostProcDownAndAcrossMbRowTest, DISABLED_Speed) { - // Size of the underlying data block that will be filtered. - block_width_ = 16; - block_height_ = 16; - - // 5-tap filter needs 2 padding rows above and below the block in the input. - Buffer src_image = Buffer(block_width_, block_height_, 2); - ASSERT_TRUE(src_image.Init()); - this->src_image_ = &src_image; - - // Filter extends output block by 8 samples at left and right edges. - // Though the left padding is only 8 bytes, the assembly code tries to - // read 16 bytes before the pointer. - Buffer dst_image = - Buffer(block_width_, block_height_, 8, 16, 8, 8); - ASSERT_TRUE(dst_image.Init()); - this->dst_image_ = &dst_image; - - flimits_ = reinterpret_cast(vpx_memalign(16, block_width_)); - (void)memset(flimits_, 255, block_width_); - - // Initialize pixels in the input: - // block pixels to value 1, - // border pixels to value 10. - src_image.SetPadding(10); - src_image.Set(1); - - // Initialize pixels in the output to 99. - dst_image.Set(99); - - RunNTimes(INT16_MAX); - PrintMedian("16x16"); - - vpx_free(flimits_); -} - -class VpxMbPostProcAcrossIpTest - : public AbstractBench, - public ::testing::TestWithParam { - public: - VpxMbPostProcAcrossIpTest() - : rows_(16), cols_(16), mb_post_proc_across_ip_(GetParam()), - src_(Buffer(rows_, cols_, 8, 8, 17, 8)) {} - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - void Run() override; - - void SetCols(unsigned char *s, int rows, int cols, int src_width) { - for (int r = 0; r < rows; r++) { - for (int c = 0; c < cols; c++) { - s[c] = c; - } - s += src_width; - } - } - - void RunComparison(const unsigned char *expected_output, unsigned char *src_c, - int rows, int cols, int src_pitch) { - for (int r = 0; r < rows; r++) { - for (int c = 0; c < cols; c++) { - ASSERT_EQ(expected_output[c], src_c[c]) - << "at (" << r << ", " << c << ")"; - } - src_c += src_pitch; - } - } - - void RunFilterLevel(unsigned char *s, int rows, int cols, int src_width, - int filter_level, const unsigned char *expected_output) { - ASM_REGISTER_STATE_CHECK( - GetParam()(s, src_width, rows, cols, filter_level)); - RunComparison(expected_output, s, rows, cols, src_width); - } - - const int rows_; - const int cols_; - const VpxMbPostProcAcrossIpFunc mb_post_proc_across_ip_; - Buffer src_; -}; - -void VpxMbPostProcAcrossIpTest::Run() { - mb_post_proc_across_ip_(src_.TopLeftPixel(), src_.stride(), rows_, cols_, - q2mbl(0)); -} - -TEST_P(VpxMbPostProcAcrossIpTest, CheckLowFilterOutput) { - ASSERT_TRUE(src_.Init()); - src_.SetPadding(10); - SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride()); - - Buffer expected_output = Buffer(cols_, rows_, 0); - ASSERT_TRUE(expected_output.Init()); - SetCols(expected_output.TopLeftPixel(), rows_, cols_, - expected_output.stride()); - - RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), q2mbl(0), - expected_output.TopLeftPixel()); -} - -TEST_P(VpxMbPostProcAcrossIpTest, CheckMediumFilterOutput) { - ASSERT_TRUE(src_.Init()); - src_.SetPadding(10); - SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride()); - - static const unsigned char kExpectedOutput[] = { - 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 13 - }; - - RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), q2mbl(70), - kExpectedOutput); -} - -TEST_P(VpxMbPostProcAcrossIpTest, CheckHighFilterOutput) { - ASSERT_TRUE(src_.Init()); - src_.SetPadding(10); - SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride()); - - static const unsigned char kExpectedOutput[] = { - 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13 - }; - - RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), INT_MAX, - kExpectedOutput); - - SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride()); - - RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), q2mbl(100), - kExpectedOutput); -} - -TEST_P(VpxMbPostProcAcrossIpTest, CheckCvsAssembly) { - Buffer c_mem = Buffer(cols_, rows_, 8, 8, 17, 8); - ASSERT_TRUE(c_mem.Init()); - Buffer asm_mem = Buffer(cols_, rows_, 8, 8, 17, 8); - ASSERT_TRUE(asm_mem.Init()); - - // When level >= 100, the filter behaves the same as the level = INT_MAX - // When level < 20, it behaves the same as the level = 0 - for (int level = 0; level < 100; level++) { - c_mem.SetPadding(10); - asm_mem.SetPadding(10); - SetCols(c_mem.TopLeftPixel(), rows_, cols_, c_mem.stride()); - SetCols(asm_mem.TopLeftPixel(), rows_, cols_, asm_mem.stride()); - - vpx_mbpost_proc_across_ip_c(c_mem.TopLeftPixel(), c_mem.stride(), rows_, - cols_, q2mbl(level)); - ASM_REGISTER_STATE_CHECK(GetParam()( - asm_mem.TopLeftPixel(), asm_mem.stride(), rows_, cols_, q2mbl(level))); - - ASSERT_TRUE(asm_mem.CheckValues(c_mem)); - } -} - -TEST_P(VpxMbPostProcAcrossIpTest, DISABLED_Speed) { - ASSERT_TRUE(src_.Init()); - src_.SetPadding(10); - - SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride()); - - RunNTimes(100000); - PrintMedian("16x16"); -} - -class VpxMbPostProcDownTest - : public AbstractBench, - public ::testing::TestWithParam { - public: - VpxMbPostProcDownTest() - : rows_(16), cols_(16), mb_post_proc_down_(GetParam()), - src_c_(Buffer(rows_, cols_, 8, 8, 8, 17)) {} - - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - void Run() override; - - void SetRows(unsigned char *src_c, int rows, int cols, int src_width) { - for (int r = 0; r < rows; r++) { - memset(src_c, r, cols); - src_c += src_width; - } - } - - void RunComparison(const unsigned char *expected_output, unsigned char *src_c, - int rows, int cols, int src_pitch) { - for (int r = 0; r < rows; r++) { - for (int c = 0; c < cols; c++) { - ASSERT_EQ(expected_output[r * rows + c], src_c[c]) - << "at (" << r << ", " << c << ")"; - } - src_c += src_pitch; - } - } - - void RunFilterLevel(unsigned char *s, int rows, int cols, int src_width, - int filter_level, const unsigned char *expected_output) { - ASM_REGISTER_STATE_CHECK( - mb_post_proc_down_(s, src_width, rows, cols, filter_level)); - RunComparison(expected_output, s, rows, cols, src_width); - } - - const int rows_; - const int cols_; - const VpxMbPostProcDownFunc mb_post_proc_down_; - Buffer src_c_; -}; - -void VpxMbPostProcDownTest::Run() { - mb_post_proc_down_(src_c_.TopLeftPixel(), src_c_.stride(), rows_, cols_, - q2mbl(0)); -} - -TEST_P(VpxMbPostProcDownTest, CheckHighFilterOutput) { - ASSERT_TRUE(src_c_.Init()); - src_c_.SetPadding(10); - - SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride()); - - static const unsigned char kExpectedOutput[] = { - 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, - 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 3, 4, 4, 3, 3, 3, - 4, 4, 3, 4, 4, 3, 3, 4, 5, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, - 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 8, 8, 8, 9, - 9, 8, 9, 9, 8, 8, 8, 9, 9, 10, 10, 9, 9, 9, 10, 10, 9, 10, 10, - 9, 9, 9, 10, 10, 10, 11, 10, 10, 10, 11, 10, 11, 10, 11, 10, 10, 10, 11, - 10, 11, 11, 11, 11, 11, 11, 11, 12, 11, 11, 11, 11, 11, 11, 11, 12, 11, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 12, - 13, 12, 13, 12, 12, 12, 13, 12, 13, 12, 13, 12, 13, 13, 13, 14, 13, 13, 13, - 13, 13, 13, 13, 14, 13, 13, 13, 13 - }; - - RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(), INT_MAX, - kExpectedOutput); - - src_c_.SetPadding(10); - SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride()); - RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(), - q2mbl(100), kExpectedOutput); -} - -TEST_P(VpxMbPostProcDownTest, CheckMediumFilterOutput) { - ASSERT_TRUE(src_c_.Init()); - src_c_.SetPadding(10); - - SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride()); - - static const unsigned char kExpectedOutput[] = { - 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, - 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 13, 12, - 13, 12, 13, 12, 12, 12, 13, 12, 13, 12, 13, 12, 13, 13, 13, 14, 13, 13, 13, - 13, 13, 13, 13, 14, 13, 13, 13, 13 - }; - - RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(), - q2mbl(70), kExpectedOutput); -} - -TEST_P(VpxMbPostProcDownTest, CheckLowFilterOutput) { - ASSERT_TRUE(src_c_.Init()); - src_c_.SetPadding(10); - - SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride()); - - std::unique_ptr expected_output( - new unsigned char[rows_ * cols_]); - ASSERT_NE(expected_output, nullptr); - SetRows(expected_output.get(), rows_, cols_, cols_); - - RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(), q2mbl(0), - expected_output.get()); -} - -TEST_P(VpxMbPostProcDownTest, CheckCvsAssembly) { - ACMRandom rnd; - rnd.Reset(ACMRandom::DeterministicSeed()); - - ASSERT_TRUE(src_c_.Init()); - Buffer src_asm = Buffer(cols_, rows_, 8, 8, 8, 17); - ASSERT_TRUE(src_asm.Init()); - - for (int level = 0; level < 100; level++) { - src_c_.SetPadding(10); - src_asm.SetPadding(10); - src_c_.Set(&rnd, &ACMRandom::Rand8); - src_asm.CopyFrom(src_c_); - - vpx_mbpost_proc_down_c(src_c_.TopLeftPixel(), src_c_.stride(), rows_, cols_, - q2mbl(level)); - ASM_REGISTER_STATE_CHECK(mb_post_proc_down_( - src_asm.TopLeftPixel(), src_asm.stride(), rows_, cols_, q2mbl(level))); - ASSERT_TRUE(src_asm.CheckValues(src_c_)); - - src_c_.SetPadding(10); - src_asm.SetPadding(10); - src_c_.Set(&rnd, &ACMRandom::Rand8Extremes); - src_asm.CopyFrom(src_c_); - - vpx_mbpost_proc_down_c(src_c_.TopLeftPixel(), src_c_.stride(), rows_, cols_, - q2mbl(level)); - ASM_REGISTER_STATE_CHECK(mb_post_proc_down_( - src_asm.TopLeftPixel(), src_asm.stride(), rows_, cols_, q2mbl(level))); - ASSERT_TRUE(src_asm.CheckValues(src_c_)); - } -} - -TEST_P(VpxMbPostProcDownTest, DISABLED_Speed) { - ASSERT_TRUE(src_c_.Init()); - src_c_.SetPadding(10); - - SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride()); - - RunNTimes(100000); - PrintMedian("16x16"); -} - -INSTANTIATE_TEST_SUITE_P( - C, VpxPostProcDownAndAcrossMbRowTest, - ::testing::Values(vpx_post_proc_down_and_across_mb_row_c)); - -INSTANTIATE_TEST_SUITE_P(C, VpxMbPostProcAcrossIpTest, - ::testing::Values(vpx_mbpost_proc_across_ip_c)); - -INSTANTIATE_TEST_SUITE_P(C, VpxMbPostProcDownTest, - ::testing::Values(vpx_mbpost_proc_down_c)); - -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P( - SSE2, VpxPostProcDownAndAcrossMbRowTest, - ::testing::Values(vpx_post_proc_down_and_across_mb_row_sse2)); - -INSTANTIATE_TEST_SUITE_P(SSE2, VpxMbPostProcAcrossIpTest, - ::testing::Values(vpx_mbpost_proc_across_ip_sse2)); - -INSTANTIATE_TEST_SUITE_P(SSE2, VpxMbPostProcDownTest, - ::testing::Values(vpx_mbpost_proc_down_sse2)); -#endif // HAVE_SSE2 - -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P( - NEON, VpxPostProcDownAndAcrossMbRowTest, - ::testing::Values(vpx_post_proc_down_and_across_mb_row_neon)); - -INSTANTIATE_TEST_SUITE_P(NEON, VpxMbPostProcAcrossIpTest, - ::testing::Values(vpx_mbpost_proc_across_ip_neon)); - -INSTANTIATE_TEST_SUITE_P(NEON, VpxMbPostProcDownTest, - ::testing::Values(vpx_mbpost_proc_down_neon)); -#endif // HAVE_NEON - -#if HAVE_MSA -INSTANTIATE_TEST_SUITE_P( - MSA, VpxPostProcDownAndAcrossMbRowTest, - ::testing::Values(vpx_post_proc_down_and_across_mb_row_msa)); - -INSTANTIATE_TEST_SUITE_P(MSA, VpxMbPostProcAcrossIpTest, - ::testing::Values(vpx_mbpost_proc_across_ip_msa)); - -INSTANTIATE_TEST_SUITE_P(MSA, VpxMbPostProcDownTest, - ::testing::Values(vpx_mbpost_proc_down_msa)); -#endif // HAVE_MSA - -#if HAVE_VSX -INSTANTIATE_TEST_SUITE_P( - VSX, VpxPostProcDownAndAcrossMbRowTest, - ::testing::Values(vpx_post_proc_down_and_across_mb_row_vsx)); - -INSTANTIATE_TEST_SUITE_P(VSX, VpxMbPostProcAcrossIpTest, - ::testing::Values(vpx_mbpost_proc_across_ip_vsx)); - -INSTANTIATE_TEST_SUITE_P(VSX, VpxMbPostProcDownTest, - ::testing::Values(vpx_mbpost_proc_down_vsx)); -#endif // HAVE_VSX - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/predict_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/predict_test.cc deleted file mode 100644 index eabcbd28..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/predict_test.cc +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vp8_rtcd.h" -#include "./vpx_config.h" -#include "test/acm_random.h" -#include "test/bench.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vpx/vpx_integer.h" -#include "vpx_mem/vpx_mem.h" - -namespace { - -using libvpx_test::ACMRandom; -using std::make_tuple; - -typedef void (*PredictFunc)(uint8_t *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, uint8_t *dst_ptr, - int dst_pitch); - -typedef std::tuple PredictParam; - -class PredictTestBase : public AbstractBench, - public ::testing::TestWithParam { - public: - PredictTestBase() - : width_(GET_PARAM(0)), height_(GET_PARAM(1)), predict_(GET_PARAM(2)), - src_(nullptr), padded_dst_(nullptr), dst_(nullptr), dst_c_(nullptr) {} - - void SetUp() override { - src_ = new uint8_t[kSrcSize]; - ASSERT_NE(src_, nullptr); - - // padded_dst_ provides a buffer of kBorderSize around the destination - // memory to facilitate detecting out of bounds writes. - dst_stride_ = kBorderSize + width_ + kBorderSize; - padded_dst_size_ = dst_stride_ * (kBorderSize + height_ + kBorderSize); - padded_dst_ = - reinterpret_cast(vpx_memalign(16, padded_dst_size_)); - ASSERT_NE(padded_dst_, nullptr); - dst_ = padded_dst_ + (kBorderSize * dst_stride_) + kBorderSize; - - dst_c_ = new uint8_t[16 * 16]; - ASSERT_NE(dst_c_, nullptr); - - memset(src_, 0, kSrcSize); - memset(padded_dst_, 128, padded_dst_size_); - memset(dst_c_, 0, 16 * 16); - } - - void TearDown() override { - delete[] src_; - src_ = nullptr; - vpx_free(padded_dst_); - padded_dst_ = nullptr; - dst_ = nullptr; - delete[] dst_c_; - dst_c_ = nullptr; - libvpx_test::ClearSystemState(); - } - - protected: - // Make reference arrays big enough for 16x16 functions. Six-tap filters need - // 5 extra pixels outside of the macroblock. - static const int kSrcStride = 21; - static const int kSrcSize = kSrcStride * kSrcStride; - static const int kBorderSize = 16; - - int width_; - int height_; - PredictFunc predict_; - uint8_t *src_; - uint8_t *padded_dst_; - uint8_t *dst_; - int padded_dst_size_; - uint8_t *dst_c_; - int dst_stride_; - - bool CompareBuffers(const uint8_t *a, int a_stride, const uint8_t *b, - int b_stride) const { - for (int height = 0; height < height_; ++height) { - EXPECT_EQ(0, memcmp(a + height * a_stride, b + height * b_stride, - sizeof(*a) * width_)) - << "Row " << height << " does not match."; - } - - return !HasFailure(); - } - - // Given a block of memory 'a' with size 'a_size', determine if all regions - // excepting block 'b' described by 'b_stride', 'b_height', and 'b_width' - // match pixel value 'c'. - bool CheckBorder(const uint8_t *a, int a_size, const uint8_t *b, int b_width, - int b_height, int b_stride, uint8_t c) const { - const uint8_t *a_end = a + a_size; - const int b_size = (b_stride * b_height) + b_width; - const uint8_t *b_end = b + b_size; - const int left_border = (b_stride - b_width) / 2; - const int right_border = left_border + ((b_stride - b_width) % 2); - - EXPECT_GE(b - left_border, a) << "'b' does not start within 'a'"; - EXPECT_LE(b_end + right_border, a_end) << "'b' does not end within 'a'"; - - // Top border. - for (int pixel = 0; pixel < b - a - left_border; ++pixel) { - EXPECT_EQ(c, a[pixel]) << "Mismatch at " << pixel << " in top border."; - } - - // Left border. - for (int height = 0; height < b_height; ++height) { - for (int width = left_border; width > 0; --width) { - EXPECT_EQ(c, b[height * b_stride - width]) - << "Mismatch at row " << height << " column " << left_border - width - << " in left border."; - } - } - - // Right border. - for (int height = 0; height < b_height; ++height) { - for (int width = b_width; width < b_width + right_border; ++width) { - EXPECT_EQ(c, b[height * b_stride + width]) - << "Mismatch at row " << height << " column " << width - b_width - << " in right border."; - } - } - - // Bottom border. - for (int pixel = static_cast(b - a + b_size); pixel < a_size; - ++pixel) { - EXPECT_EQ(c, a[pixel]) << "Mismatch at " << pixel << " in bottom border."; - } - - return !HasFailure(); - } - - void TestWithRandomData(PredictFunc reference) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - - // Run tests for almost all possible offsets. - for (int xoffset = 0; xoffset < 8; ++xoffset) { - for (int yoffset = 0; yoffset < 8; ++yoffset) { - if (xoffset == 0 && yoffset == 0) { - // This represents a copy which is not required to be handled by this - // module. - continue; - } - - for (int i = 0; i < kSrcSize; ++i) { - src_[i] = rnd.Rand8(); - } - reference(&src_[kSrcStride * 2 + 2], kSrcStride, xoffset, yoffset, - dst_c_, 16); - - ASM_REGISTER_STATE_CHECK(predict_(&src_[kSrcStride * 2 + 2], kSrcStride, - xoffset, yoffset, dst_, dst_stride_)); - - ASSERT_TRUE(CompareBuffers(dst_c_, 16, dst_, dst_stride_)); - ASSERT_TRUE(CheckBorder(padded_dst_, padded_dst_size_, dst_, width_, - height_, dst_stride_, 128)); - } - } - } - - void TestWithUnalignedDst(PredictFunc reference) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - - // Only the 4x4 need to be able to handle unaligned writes. - if (width_ == 4 && height_ == 4) { - for (int xoffset = 0; xoffset < 8; ++xoffset) { - for (int yoffset = 0; yoffset < 8; ++yoffset) { - if (xoffset == 0 && yoffset == 0) { - continue; - } - for (int i = 0; i < kSrcSize; ++i) { - src_[i] = rnd.Rand8(); - } - reference(&src_[kSrcStride * 2 + 2], kSrcStride, xoffset, yoffset, - dst_c_, 16); - - for (int i = 1; i < 4; ++i) { - memset(padded_dst_, 128, padded_dst_size_); - - ASM_REGISTER_STATE_CHECK(predict_(&src_[kSrcStride * 2 + 2], - kSrcStride, xoffset, yoffset, - dst_ + i, dst_stride_ + i)); - - ASSERT_TRUE(CompareBuffers(dst_c_, 16, dst_ + i, dst_stride_ + i)); - ASSERT_TRUE(CheckBorder(padded_dst_, padded_dst_size_, dst_ + i, - width_, height_, dst_stride_ + i, 128)); - } - } - } - } - } - - void Run() override { - for (int xoffset = 0; xoffset < 8; ++xoffset) { - for (int yoffset = 0; yoffset < 8; ++yoffset) { - if (xoffset == 0 && yoffset == 0) { - continue; - } - - predict_(&src_[kSrcStride * 2 + 2], kSrcStride, xoffset, yoffset, dst_, - dst_stride_); - } - } - } -}; // namespace - -class SixtapPredictTest : public PredictTestBase {}; - -TEST_P(SixtapPredictTest, TestWithRandomData) { - TestWithRandomData(vp8_sixtap_predict16x16_c); -} -TEST_P(SixtapPredictTest, TestWithUnalignedDst) { - TestWithUnalignedDst(vp8_sixtap_predict16x16_c); -} - -TEST_P(SixtapPredictTest, TestWithPresetData) { - // Test input - static const uint8_t kTestData[kSrcSize] = { - 184, 4, 191, 82, 92, 41, 0, 1, 226, 236, 172, 20, 182, 42, 226, - 177, 79, 94, 77, 179, 203, 206, 198, 22, 192, 19, 75, 17, 192, 44, - 233, 120, 48, 168, 203, 141, 210, 203, 143, 180, 184, 59, 201, 110, 102, - 171, 32, 182, 10, 109, 105, 213, 60, 47, 236, 253, 67, 55, 14, 3, - 99, 247, 124, 148, 159, 71, 34, 114, 19, 177, 38, 203, 237, 239, 58, - 83, 155, 91, 10, 166, 201, 115, 124, 5, 163, 104, 2, 231, 160, 16, - 234, 4, 8, 103, 153, 167, 174, 187, 26, 193, 109, 64, 141, 90, 48, - 200, 174, 204, 36, 184, 114, 237, 43, 238, 242, 207, 86, 245, 182, 247, - 6, 161, 251, 14, 8, 148, 182, 182, 79, 208, 120, 188, 17, 6, 23, - 65, 206, 197, 13, 242, 126, 128, 224, 170, 110, 211, 121, 197, 200, 47, - 188, 207, 208, 184, 221, 216, 76, 148, 143, 156, 100, 8, 89, 117, 14, - 112, 183, 221, 54, 197, 208, 180, 69, 176, 94, 180, 131, 215, 121, 76, - 7, 54, 28, 216, 238, 249, 176, 58, 142, 64, 215, 242, 72, 49, 104, - 87, 161, 32, 52, 216, 230, 4, 141, 44, 181, 235, 224, 57, 195, 89, - 134, 203, 144, 162, 163, 126, 156, 84, 185, 42, 148, 145, 29, 221, 194, - 134, 52, 100, 166, 105, 60, 140, 110, 201, 184, 35, 181, 153, 93, 121, - 243, 227, 68, 131, 134, 232, 2, 35, 60, 187, 77, 209, 76, 106, 174, - 15, 241, 227, 115, 151, 77, 175, 36, 187, 121, 221, 223, 47, 118, 61, - 168, 105, 32, 237, 236, 167, 213, 238, 202, 17, 170, 24, 226, 247, 131, - 145, 6, 116, 117, 121, 11, 194, 41, 48, 126, 162, 13, 93, 209, 131, - 154, 122, 237, 187, 103, 217, 99, 60, 200, 45, 78, 115, 69, 49, 106, - 200, 194, 112, 60, 56, 234, 72, 251, 19, 120, 121, 182, 134, 215, 135, - 10, 114, 2, 247, 46, 105, 209, 145, 165, 153, 191, 243, 12, 5, 36, - 119, 206, 231, 231, 11, 32, 209, 83, 27, 229, 204, 149, 155, 83, 109, - 35, 93, 223, 37, 84, 14, 142, 37, 160, 52, 191, 96, 40, 204, 101, - 77, 67, 52, 53, 43, 63, 85, 253, 147, 113, 226, 96, 6, 125, 179, - 115, 161, 17, 83, 198, 101, 98, 85, 139, 3, 137, 75, 99, 178, 23, - 201, 255, 91, 253, 52, 134, 60, 138, 131, 208, 251, 101, 48, 2, 227, - 228, 118, 132, 245, 202, 75, 91, 44, 160, 231, 47, 41, 50, 147, 220, - 74, 92, 219, 165, 89, 16 - }; - - // Expected results for xoffset = 2 and yoffset = 2. - static const int kExpectedDstStride = 16; - static const uint8_t kExpectedDst[256] = { - 117, 102, 74, 135, 42, 98, 175, 206, 70, 73, 222, 197, 50, 24, 39, - 49, 38, 105, 90, 47, 169, 40, 171, 215, 200, 73, 109, 141, 53, 85, - 177, 164, 79, 208, 124, 89, 212, 18, 81, 145, 151, 164, 217, 153, 91, - 154, 102, 102, 159, 75, 164, 152, 136, 51, 213, 219, 186, 116, 193, 224, - 186, 36, 231, 208, 84, 211, 155, 167, 35, 59, 42, 76, 216, 149, 73, - 201, 78, 149, 184, 100, 96, 196, 189, 198, 188, 235, 195, 117, 129, 120, - 129, 49, 25, 133, 113, 69, 221, 114, 70, 143, 99, 157, 108, 189, 140, - 78, 6, 55, 65, 240, 255, 245, 184, 72, 90, 100, 116, 131, 39, 60, - 234, 167, 33, 160, 88, 185, 200, 157, 159, 176, 127, 151, 138, 102, 168, - 106, 170, 86, 82, 219, 189, 76, 33, 115, 197, 106, 96, 198, 136, 97, - 141, 237, 151, 98, 137, 191, 185, 2, 57, 95, 142, 91, 255, 185, 97, - 137, 76, 162, 94, 173, 131, 193, 161, 81, 106, 72, 135, 222, 234, 137, - 66, 137, 106, 243, 210, 147, 95, 15, 137, 110, 85, 66, 16, 96, 167, - 147, 150, 173, 203, 140, 118, 196, 84, 147, 160, 19, 95, 101, 123, 74, - 132, 202, 82, 166, 12, 131, 166, 189, 170, 159, 85, 79, 66, 57, 152, - 132, 203, 194, 0, 1, 56, 146, 180, 224, 156, 28, 83, 181, 79, 76, - 80, 46, 160, 175, 59, 106, 43, 87, 75, 136, 85, 189, 46, 71, 200, - 90 - }; - - ASM_REGISTER_STATE_CHECK( - predict_(const_cast(kTestData) + kSrcStride * 2 + 2, - kSrcStride, 2, 2, dst_, dst_stride_)); - - ASSERT_TRUE( - CompareBuffers(kExpectedDst, kExpectedDstStride, dst_, dst_stride_)); -} - -INSTANTIATE_TEST_SUITE_P( - C, SixtapPredictTest, - ::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_c), - make_tuple(8, 8, &vp8_sixtap_predict8x8_c), - make_tuple(8, 4, &vp8_sixtap_predict8x4_c), - make_tuple(4, 4, &vp8_sixtap_predict4x4_c))); -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P( - NEON, SixtapPredictTest, - ::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_neon), - make_tuple(8, 8, &vp8_sixtap_predict8x8_neon), - make_tuple(8, 4, &vp8_sixtap_predict8x4_neon), - make_tuple(4, 4, &vp8_sixtap_predict4x4_neon))); -#endif -#if HAVE_MMX -INSTANTIATE_TEST_SUITE_P( - MMX, SixtapPredictTest, - ::testing::Values(make_tuple(4, 4, &vp8_sixtap_predict4x4_mmx))); -#endif -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P( - SSE2, SixtapPredictTest, - ::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_sse2), - make_tuple(8, 8, &vp8_sixtap_predict8x8_sse2), - make_tuple(8, 4, &vp8_sixtap_predict8x4_sse2))); -#endif -#if HAVE_SSSE3 -INSTANTIATE_TEST_SUITE_P( - SSSE3, SixtapPredictTest, - ::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_ssse3), - make_tuple(8, 8, &vp8_sixtap_predict8x8_ssse3), - make_tuple(8, 4, &vp8_sixtap_predict8x4_ssse3), - make_tuple(4, 4, &vp8_sixtap_predict4x4_ssse3))); -#endif -#if HAVE_MSA -INSTANTIATE_TEST_SUITE_P( - MSA, SixtapPredictTest, - ::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_msa), - make_tuple(8, 8, &vp8_sixtap_predict8x8_msa), - make_tuple(8, 4, &vp8_sixtap_predict8x4_msa), - make_tuple(4, 4, &vp8_sixtap_predict4x4_msa))); -#endif - -#if HAVE_MMI -INSTANTIATE_TEST_SUITE_P( - MMI, SixtapPredictTest, - ::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_mmi), - make_tuple(8, 8, &vp8_sixtap_predict8x8_mmi), - make_tuple(8, 4, &vp8_sixtap_predict8x4_mmi), - make_tuple(4, 4, &vp8_sixtap_predict4x4_mmi))); -#endif - -#if HAVE_LSX -INSTANTIATE_TEST_SUITE_P( - LSX, SixtapPredictTest, - ::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_lsx), - make_tuple(8, 8, &vp8_sixtap_predict8x8_lsx), - make_tuple(4, 4, &vp8_sixtap_predict4x4_lsx))); -#endif - -class BilinearPredictTest : public PredictTestBase {}; - -TEST_P(BilinearPredictTest, TestWithRandomData) { - TestWithRandomData(vp8_bilinear_predict16x16_c); -} -TEST_P(BilinearPredictTest, TestWithUnalignedDst) { - TestWithUnalignedDst(vp8_bilinear_predict16x16_c); -} -TEST_P(BilinearPredictTest, DISABLED_Speed) { - const int kCountSpeedTestBlock = 5000000 / (width_ * height_); - RunNTimes(kCountSpeedTestBlock); - - char title[16]; - snprintf(title, sizeof(title), "%dx%d", width_, height_); - PrintMedian(title); -} - -INSTANTIATE_TEST_SUITE_P( - C, BilinearPredictTest, - ::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_c), - make_tuple(8, 8, &vp8_bilinear_predict8x8_c), - make_tuple(8, 4, &vp8_bilinear_predict8x4_c), - make_tuple(4, 4, &vp8_bilinear_predict4x4_c))); -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P( - NEON, BilinearPredictTest, - ::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_neon), - make_tuple(8, 8, &vp8_bilinear_predict8x8_neon), - make_tuple(8, 4, &vp8_bilinear_predict8x4_neon), - make_tuple(4, 4, &vp8_bilinear_predict4x4_neon))); -#endif -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P( - SSE2, BilinearPredictTest, - ::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_sse2), - make_tuple(8, 8, &vp8_bilinear_predict8x8_sse2), - make_tuple(8, 4, &vp8_bilinear_predict8x4_sse2), - make_tuple(4, 4, &vp8_bilinear_predict4x4_sse2))); -#endif -#if HAVE_SSSE3 -INSTANTIATE_TEST_SUITE_P( - SSSE3, BilinearPredictTest, - ::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_ssse3), - make_tuple(8, 8, &vp8_bilinear_predict8x8_ssse3))); -#endif -#if HAVE_MSA -INSTANTIATE_TEST_SUITE_P( - MSA, BilinearPredictTest, - ::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_msa), - make_tuple(8, 8, &vp8_bilinear_predict8x8_msa), - make_tuple(8, 4, &vp8_bilinear_predict8x4_msa), - make_tuple(4, 4, &vp8_bilinear_predict4x4_msa))); -#endif -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/quantize_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/quantize_test.cc deleted file mode 100644 index 2ef04083..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/quantize_test.cc +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "gtest/gtest.h" - -#include "./vp8_rtcd.h" -#include "./vpx_config.h" -#include "test/acm_random.h" -#include "test/bench.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vp8/common/blockd.h" -#include "vp8/common/onyx.h" -#include "vp8/encoder/block.h" -#include "vp8/encoder/onyx_int.h" -#include "vp8/encoder/quantize.h" -#include "vpx/vpx_integer.h" -#include "vpx_mem/vpx_mem.h" - -namespace { - -const int kNumBlocks = 25; -const int kNumBlockEntries = 16; - -typedef void (*VP8Quantize)(BLOCK *b, BLOCKD *d); - -typedef std::tuple VP8QuantizeParam; - -using libvpx_test::ACMRandom; -using std::make_tuple; - -// Create and populate a VP8_COMP instance which has a complete set of -// quantization inputs as well as a second MACROBLOCKD for output. -class QuantizeTestBase { - public: - virtual ~QuantizeTestBase() { - vp8_remove_compressor(&vp8_comp_); - vp8_comp_ = nullptr; - vpx_free(macroblockd_dst_); - macroblockd_dst_ = nullptr; - libvpx_test::ClearSystemState(); - } - - protected: - void SetupCompressor() { - rnd_.Reset(ACMRandom::DeterministicSeed()); - - // The full configuration is necessary to generate the quantization tables. - VP8_CONFIG vp8_config; - memset(&vp8_config, 0, sizeof(vp8_config)); - - vp8_comp_ = vp8_create_compressor(&vp8_config); - - // Set the tables based on a quantizer of 0. - vp8_set_quantizer(vp8_comp_, 0); - - // Set up all the block/blockd pointers for the mb in vp8_comp_. - vp8cx_frame_init_quantizer(vp8_comp_); - - // Copy macroblockd from the reference to get pre-set-up dequant values. - macroblockd_dst_ = reinterpret_cast( - vpx_memalign(32, sizeof(*macroblockd_dst_))); - memcpy(macroblockd_dst_, &vp8_comp_->mb.e_mbd, sizeof(*macroblockd_dst_)); - // Fix block pointers - currently they point to the blocks in the reference - // structure. - vp8_setup_block_dptrs(macroblockd_dst_); - } - - void UpdateQuantizer(int q) { - vp8_set_quantizer(vp8_comp_, q); - - memcpy(macroblockd_dst_, &vp8_comp_->mb.e_mbd, sizeof(*macroblockd_dst_)); - vp8_setup_block_dptrs(macroblockd_dst_); - } - - void FillCoeffConstant(int16_t c) { - for (int i = 0; i < kNumBlocks * kNumBlockEntries; ++i) { - vp8_comp_->mb.coeff[i] = c; - } - } - - void FillCoeffRandom() { - for (int i = 0; i < kNumBlocks * kNumBlockEntries; ++i) { - vp8_comp_->mb.coeff[i] = rnd_.Rand8(); - } - } - - void CheckOutput() { - EXPECT_EQ(0, memcmp(vp8_comp_->mb.e_mbd.qcoeff, macroblockd_dst_->qcoeff, - sizeof(*macroblockd_dst_->qcoeff) * kNumBlocks * - kNumBlockEntries)) - << "qcoeff mismatch"; - EXPECT_EQ(0, memcmp(vp8_comp_->mb.e_mbd.dqcoeff, macroblockd_dst_->dqcoeff, - sizeof(*macroblockd_dst_->dqcoeff) * kNumBlocks * - kNumBlockEntries)) - << "dqcoeff mismatch"; - EXPECT_EQ(0, memcmp(vp8_comp_->mb.e_mbd.eobs, macroblockd_dst_->eobs, - sizeof(*macroblockd_dst_->eobs) * kNumBlocks)) - << "eobs mismatch"; - } - - VP8_COMP *vp8_comp_; - MACROBLOCKD *macroblockd_dst_; - - private: - ACMRandom rnd_; -}; - -class QuantizeTest : public QuantizeTestBase, - public ::testing::TestWithParam, - public AbstractBench { - protected: - void SetUp() override { - SetupCompressor(); - asm_quant_ = GET_PARAM(0); - c_quant_ = GET_PARAM(1); - } - - void Run() override { - asm_quant_(&vp8_comp_->mb.block[0], ¯oblockd_dst_->block[0]); - } - - void RunComparison() { - for (int i = 0; i < kNumBlocks; ++i) { - ASM_REGISTER_STATE_CHECK( - c_quant_(&vp8_comp_->mb.block[i], &vp8_comp_->mb.e_mbd.block[i])); - ASM_REGISTER_STATE_CHECK( - asm_quant_(&vp8_comp_->mb.block[i], ¯oblockd_dst_->block[i])); - } - - CheckOutput(); - } - - private: - VP8Quantize asm_quant_; - VP8Quantize c_quant_; -}; -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(QuantizeTest); - -TEST_P(QuantizeTest, TestZeroInput) { - FillCoeffConstant(0); - RunComparison(); -} - -TEST_P(QuantizeTest, TestLargeNegativeInput) { - FillCoeffConstant(0); - // Generate a qcoeff which contains 512/-512 (0x0100/0xFE00) to catch issues - // like BUG=883 where the constant being compared was incorrectly initialized. - vp8_comp_->mb.coeff[0] = -8191; - RunComparison(); -} - -TEST_P(QuantizeTest, TestRandomInput) { - FillCoeffRandom(); - RunComparison(); -} - -TEST_P(QuantizeTest, TestMultipleQ) { - for (int q = 0; q < QINDEX_RANGE; ++q) { - UpdateQuantizer(q); - FillCoeffRandom(); - RunComparison(); - } -} - -TEST_P(QuantizeTest, DISABLED_Speed) { - FillCoeffRandom(); - - RunNTimes(10000000); - PrintMedian("vp8 quantize"); -} - -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P( - SSE2, QuantizeTest, - ::testing::Values( - make_tuple(&vp8_fast_quantize_b_sse2, &vp8_fast_quantize_b_c), - make_tuple(&vp8_regular_quantize_b_sse2, &vp8_regular_quantize_b_c))); -#endif // HAVE_SSE2 - -#if HAVE_SSSE3 -INSTANTIATE_TEST_SUITE_P( - SSSE3, QuantizeTest, - ::testing::Values(make_tuple(&vp8_fast_quantize_b_ssse3, - &vp8_fast_quantize_b_c))); -#endif // HAVE_SSSE3 - -#if HAVE_SSE4_1 -INSTANTIATE_TEST_SUITE_P( - SSE4_1, QuantizeTest, - ::testing::Values(make_tuple(&vp8_regular_quantize_b_sse4_1, - &vp8_regular_quantize_b_c))); -#endif // HAVE_SSE4_1 - -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P(NEON, QuantizeTest, - ::testing::Values(make_tuple(&vp8_fast_quantize_b_neon, - &vp8_fast_quantize_b_c))); -#endif // HAVE_NEON - -#if HAVE_MSA -INSTANTIATE_TEST_SUITE_P( - MSA, QuantizeTest, - ::testing::Values( - make_tuple(&vp8_fast_quantize_b_msa, &vp8_fast_quantize_b_c), - make_tuple(&vp8_regular_quantize_b_msa, &vp8_regular_quantize_b_c))); -#endif // HAVE_MSA - -#if HAVE_MMI -INSTANTIATE_TEST_SUITE_P( - MMI, QuantizeTest, - ::testing::Values( - make_tuple(&vp8_fast_quantize_b_mmi, &vp8_fast_quantize_b_c), - make_tuple(&vp8_regular_quantize_b_mmi, &vp8_regular_quantize_b_c))); -#endif // HAVE_MMI - -#if HAVE_LSX -INSTANTIATE_TEST_SUITE_P( - LSX, QuantizeTest, - ::testing::Values(make_tuple(&vp8_regular_quantize_b_lsx, - &vp8_regular_quantize_b_c))); -#endif // HAVE_LSX -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/realtime_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/realtime_test.cc deleted file mode 100644 index b0cc929d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/realtime_test.cc +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include - -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/util.h" -#include "test/video_source.h" -#include "vpx_config.h" - -namespace { - -const int kVideoSourceWidth = 320; -const int kVideoSourceHeight = 240; -const int kFramesToEncode = 2; - -class RealtimeTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWithParam { - protected: - RealtimeTest() : EncoderTest(GET_PARAM(0)), frame_packets_(0) {} - ~RealtimeTest() override = default; - - void SetUp() override { - InitializeConfig(); - cfg_.g_lag_in_frames = 0; - SetMode(::libvpx_test::kRealTime); - } - - void BeginPassHook(unsigned int /*pass*/) override { -#if !CONFIG_REALTIME_ONLY - // TODO(tomfinegan): We're changing the pass value here to make sure - // we get frames when real time mode is combined with |g_pass| set to - // VPX_RC_FIRST_PASS. This is necessary because EncoderTest::RunLoop() sets - // the pass value based on the mode passed into EncoderTest::SetMode(), - // which overrides the one specified in SetUp() above. - cfg_.g_pass = VPX_RC_FIRST_PASS; -#endif - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0 && set_cpu_used_) { - encoder->Control(VP8E_SET_CPUUSED, 8); - } - } - - void FramePktHook(const vpx_codec_cx_pkt_t * /*pkt*/) override { - frame_packets_++; - } - - bool IsVP9() const { -#if CONFIG_VP9_ENCODER - return codec_ == &libvpx_test::kVP9; -#else - return false; -#endif - } - - void TestIntegerOverflow(unsigned int width, unsigned int height) { - ::libvpx_test::RandomVideoSource video; - video.SetSize(width, height); - video.set_limit(20); - cfg_.rc_target_bitrate = UINT_MAX; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - } - - void TestEncode() { - ::libvpx_test::RandomVideoSource video; - video.SetSize(kVideoSourceWidth, kVideoSourceHeight); - video.set_limit(kFramesToEncode); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - EXPECT_EQ(kFramesToEncode, frame_packets_); - } - - int frame_packets_; - bool set_cpu_used_ = true; -}; - -TEST_P(RealtimeTest, RealtimeFirstPassProducesFrames) { TestEncode(); } - -TEST_P(RealtimeTest, RealtimeDefaultCpuUsed) { - set_cpu_used_ = false; - TestEncode(); -} - -TEST_P(RealtimeTest, IntegerOverflow) { TestIntegerOverflow(2048, 2048); } - -TEST_P(RealtimeTest, IntegerOverflowLarge) { -#ifdef CHROMIUM - GTEST_SKIP() << "16K framebuffers are not supported by Chromium's allocator."; -#else - if (IsVP9()) { -#if VPX_ARCH_AARCH64 || VPX_ARCH_X86_64 - TestIntegerOverflow(16384, 16384); -#else - TestIntegerOverflow(4096, 4096); -#endif - } else { - GTEST_SKIP() - << "TODO(https://crbug.com/webm/1748,https://crbug.com/webm/1751):" - << " Enable this test after bitstream errors & undefined sanitizer " - "warnings are fixed."; - // TestIntegerOverflow(16383, 16383); - } -#endif // defined(CHROMIUM) -} - -VP8_INSTANTIATE_TEST_SUITE(RealtimeTest, - ::testing::Values(::libvpx_test::kRealTime)); -VP9_INSTANTIATE_TEST_SUITE(RealtimeTest, - ::testing::Values(::libvpx_test::kRealTime)); - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/register_state_check.h b/presentation/src/main/cpp/third_party/libvpx/test/register_state_check.h deleted file mode 100644 index 96795f65..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/register_state_check.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_TEST_REGISTER_STATE_CHECK_H_ -#define VPX_TEST_REGISTER_STATE_CHECK_H_ - -#include "gtest/gtest.h" -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" - -// ASM_REGISTER_STATE_CHECK(asm_function) -// Minimally validates the environment pre & post function execution. This -// variant should be used with assembly functions which are not expected to -// fully restore the system state. See platform implementations of -// RegisterStateCheck for details. -// -// API_REGISTER_STATE_CHECK(api_function) -// Performs all the checks done by ASM_REGISTER_STATE_CHECK() and any -// additional checks to ensure the environment is in a consistent state pre & -// post function execution. This variant should be used with API functions. -// See platform implementations of RegisterStateCheckXXX for details. -// - -#if defined(_WIN64) && VPX_ARCH_X86_64 - -#undef NOMINMAX -#define NOMINMAX -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#include -#include - -inline bool operator==(const M128A &lhs, const M128A &rhs) { - return (lhs.Low == rhs.Low && lhs.High == rhs.High); -} - -namespace libvpx_test { - -// Compares the state of xmm[6-15] at construction with their state at -// destruction. These registers should be preserved by the callee on -// Windows x64. -class RegisterStateCheck { - public: - RegisterStateCheck() { initialized_ = StoreRegisters(&pre_context_); } - ~RegisterStateCheck() { Check(); } - - private: - static bool StoreRegisters(CONTEXT *const context) { - const HANDLE this_thread = GetCurrentThread(); - EXPECT_NE(this_thread, nullptr); - context->ContextFlags = CONTEXT_FLOATING_POINT; - const bool context_saved = GetThreadContext(this_thread, context) == TRUE; - EXPECT_TRUE(context_saved) << "GetLastError: " << GetLastError(); - return context_saved; - } - - // Compares the register state. Returns true if the states match. - void Check() const { - ASSERT_TRUE(initialized_); - CONTEXT post_context; - ASSERT_TRUE(StoreRegisters(&post_context)); - - const M128A *xmm_pre = &pre_context_.Xmm6; - const M128A *xmm_post = &post_context.Xmm6; - for (int i = 6; i <= 15; ++i) { - EXPECT_EQ(*xmm_pre, *xmm_post) << "xmm" << i << " has been modified!"; - ++xmm_pre; - ++xmm_post; - } - } - - bool initialized_; - CONTEXT pre_context_; -}; - -#define ASM_REGISTER_STATE_CHECK(statement) \ - do { \ - { \ - libvpx_test::RegisterStateCheck reg_check; \ - statement; \ - } \ - _ReadWriteBarrier(); \ - } while (false) - -} // namespace libvpx_test - -#elif defined(CONFIG_SHARED) && defined(HAVE_NEON_ASM) && \ - defined(CONFIG_VP9) && !CONFIG_SHARED && HAVE_NEON_ASM && CONFIG_VP9 - -extern "C" { -// Save the d8-d15 registers into store. -void vpx_push_neon(int64_t *store); -} - -namespace libvpx_test { - -// Compares the state of d8-d15 at construction with their state at -// destruction. These registers should be preserved by the callee on -// arm platform. -class RegisterStateCheck { - public: - RegisterStateCheck() { vpx_push_neon(pre_store_); } - ~RegisterStateCheck() { Check(); } - - private: - // Compares the register state. Returns true if the states match. - void Check() const { - int64_t post_store[8]; - vpx_push_neon(post_store); - for (int i = 0; i < 8; ++i) { - EXPECT_EQ(pre_store_[i], post_store[i]) - << "d" << i + 8 << " has been modified"; - } - } - - int64_t pre_store_[8]; -}; - -#if defined(__GNUC__) -#define ASM_REGISTER_STATE_CHECK(statement) \ - do { \ - { \ - libvpx_test::RegisterStateCheck reg_check; \ - statement; \ - } \ - __asm__ volatile("" ::: "memory"); \ - } while (false) -#else -#define ASM_REGISTER_STATE_CHECK(statement) \ - do { \ - libvpx_test::RegisterStateCheck reg_check; \ - statement; \ - } while (false) -#endif - -} // namespace libvpx_test - -#else - -namespace libvpx_test { - -class RegisterStateCheck {}; -#define ASM_REGISTER_STATE_CHECK(statement) statement - -} // namespace libvpx_test - -#endif // _WIN64 && VPX_ARCH_X86_64 - -#if VPX_ARCH_X86 || VPX_ARCH_X86_64 -#if defined(__GNUC__) - -namespace libvpx_test { - -// Checks the FPU tag word pre/post execution to ensure emms has been called. -class RegisterStateCheckMMX { - public: - RegisterStateCheckMMX() { - __asm__ volatile("fstenv %0" : "=rm"(pre_fpu_env_)); - } - ~RegisterStateCheckMMX() { Check(); } - - private: - // Checks the FPU tag word pre/post execution, returning false if not cleared - // to 0xffff. - void Check() const { - EXPECT_EQ(0xffff, pre_fpu_env_[4]) - << "FPU was in an inconsistent state prior to call"; - - uint16_t post_fpu_env[14]; - __asm__ volatile("fstenv %0" : "=rm"(post_fpu_env)); - EXPECT_EQ(0xffff, post_fpu_env[4]) - << "FPU was left in an inconsistent state after call"; - } - - uint16_t pre_fpu_env_[14]; -}; - -#define API_REGISTER_STATE_CHECK(statement) \ - do { \ - { \ - libvpx_test::RegisterStateCheckMMX reg_check_mmx; \ - ASM_REGISTER_STATE_CHECK(statement); \ - } \ - __asm__ volatile("" ::: "memory"); \ - } while (false) - -} // namespace libvpx_test - -#endif // __GNUC__ -#endif // VPX_ARCH_X86 || VPX_ARCH_X86_64 - -#ifndef API_REGISTER_STATE_CHECK -#define API_REGISTER_STATE_CHECK ASM_REGISTER_STATE_CHECK -#endif - -#endif // VPX_TEST_REGISTER_STATE_CHECK_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/resize_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/resize_test.cc deleted file mode 100644 index 93e1bf65..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/resize_test.cc +++ /dev/null @@ -1,784 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" -#include "test/video_source.h" -#include "vpx_config.h" - -// Enable(1) or Disable(0) writing of the compressed bitstream. -#define WRITE_COMPRESSED_STREAM 0 - -namespace { - -#if WRITE_COMPRESSED_STREAM -static void mem_put_le16(char *const mem, const unsigned int val) { - mem[0] = val; - mem[1] = val >> 8; -} - -static void mem_put_le32(char *const mem, const unsigned int val) { - mem[0] = val; - mem[1] = val >> 8; - mem[2] = val >> 16; - mem[3] = val >> 24; -} - -static void write_ivf_file_header(const vpx_codec_enc_cfg_t *const cfg, - int frame_cnt, FILE *const outfile) { - char header[32]; - - header[0] = 'D'; - header[1] = 'K'; - header[2] = 'I'; - header[3] = 'F'; - mem_put_le16(header + 4, 0); /* version */ - mem_put_le16(header + 6, 32); /* headersize */ - mem_put_le32(header + 8, 0x30395056); /* fourcc (vp9) */ - mem_put_le16(header + 12, cfg->g_w); /* width */ - mem_put_le16(header + 14, cfg->g_h); /* height */ - mem_put_le32(header + 16, cfg->g_timebase.den); /* rate */ - mem_put_le32(header + 20, cfg->g_timebase.num); /* scale */ - mem_put_le32(header + 24, frame_cnt); /* length */ - mem_put_le32(header + 28, 0); /* unused */ - - (void)fwrite(header, 1, 32, outfile); -} - -static void write_ivf_frame_size(FILE *const outfile, const size_t size) { - char header[4]; - mem_put_le32(header, static_cast(size)); - (void)fwrite(header, 1, 4, outfile); -} - -static void write_ivf_frame_header(const vpx_codec_cx_pkt_t *const pkt, - FILE *const outfile) { - char header[12]; - vpx_codec_pts_t pts; - - if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return; - - pts = pkt->data.frame.pts; - mem_put_le32(header, static_cast(pkt->data.frame.sz)); - mem_put_le32(header + 4, pts & 0xFFFFFFFF); - mem_put_le32(header + 8, pts >> 32); - - (void)fwrite(header, 1, 12, outfile); -} -#endif // WRITE_COMPRESSED_STREAM - -const unsigned int kInitialWidth = 320; -const unsigned int kInitialHeight = 240; - -struct FrameInfo { - FrameInfo(vpx_codec_pts_t _pts, unsigned int _w, unsigned int _h) - : pts(_pts), w(_w), h(_h) {} - - vpx_codec_pts_t pts; - unsigned int w; - unsigned int h; -}; - -void ScaleForFrameNumber(unsigned int frame, unsigned int initial_w, - unsigned int initial_h, unsigned int *w, - unsigned int *h, bool flag_codec, - bool smaller_width_larger_size_) { - *w = initial_w; - *h = initial_h; - - if (smaller_width_larger_size_) { - if (frame < 30) { - return; - } - *w = initial_w * 7 / 10; - *h = initial_h * 16 / 10; - return; - } - if (frame < 10) { - return; - } - if (frame < 20) { - *w = initial_w * 3 / 4; - *h = initial_h * 3 / 4; - return; - } - if (frame < 30) { - *w = initial_w / 2; - *h = initial_h / 2; - return; - } - if (frame < 40) { - return; - } - if (frame < 50) { - *w = initial_w * 3 / 4; - *h = initial_h * 3 / 4; - return; - } - if (frame < 60) { - *w = initial_w / 2; - *h = initial_h / 2; - return; - } - if (frame < 70) { - return; - } - if (frame < 80) { - *w = initial_w * 3 / 4; - *h = initial_h * 3 / 4; - return; - } - if (frame < 90) { - *w = initial_w / 2; - *h = initial_h / 2; - return; - } - if (frame < 100) { - *w = initial_w * 3 / 4; - *h = initial_h * 3 / 4; - return; - } - if (frame < 110) { - return; - } - if (frame < 120) { - *w = initial_w * 3 / 4; - *h = initial_h * 3 / 4; - return; - } - if (frame < 130) { - *w = initial_w / 2; - *h = initial_h / 2; - return; - } - if (frame < 140) { - *w = initial_w * 3 / 4; - *h = initial_h * 3 / 4; - return; - } - if (frame < 150) { - return; - } - if (frame < 160) { - *w = initial_w * 3 / 4; - *h = initial_h * 3 / 4; - return; - } - if (frame < 170) { - *w = initial_w / 2; - *h = initial_h / 2; - return; - } - if (frame < 180) { - *w = initial_w * 3 / 4; - *h = initial_h * 3 / 4; - return; - } - if (frame < 190) { - return; - } - if (frame < 200) { - *w = initial_w * 3 / 4; - *h = initial_h * 3 / 4; - return; - } - if (frame < 210) { - *w = initial_w / 2; - *h = initial_h / 2; - return; - } - if (frame < 220) { - *w = initial_w * 3 / 4; - *h = initial_h * 3 / 4; - return; - } - if (frame < 230) { - return; - } - if (frame < 240) { - *w = initial_w * 3 / 4; - *h = initial_h * 3 / 4; - return; - } - if (frame < 250) { - *w = initial_w / 2; - *h = initial_h / 2; - return; - } - if (frame < 260) { - return; - } - // Go down very low. - if (frame < 270) { - *w = initial_w / 4; - *h = initial_h / 4; - return; - } - if (flag_codec == 1) { - // Cases that only works for VP9. - // For VP9: Swap width and height of original. - if (frame < 320) { - return; - } - } -} - -class ResizingVideoSource : public ::libvpx_test::DummyVideoSource { - public: - ResizingVideoSource() { - SetSize(kInitialWidth, kInitialHeight); - limit_ = 350; - smaller_width_larger_size_ = false; - } - bool flag_codec_; - bool smaller_width_larger_size_; - ~ResizingVideoSource() override = default; - - protected: - void Next() override { - ++frame_; - unsigned int width = 0; - unsigned int height = 0; - ScaleForFrameNumber(frame_, kInitialWidth, kInitialHeight, &width, &height, - flag_codec_, smaller_width_larger_size_); - SetSize(width, height); - FillFrame(); - } -}; - -class ResizeTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWithParam { - protected: - ResizeTest() : EncoderTest(GET_PARAM(0)) {} - - ~ResizeTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(GET_PARAM(1)); - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - ASSERT_NE(static_cast(pkt->data.frame.width[0]), 0); - ASSERT_NE(static_cast(pkt->data.frame.height[0]), 0); - encode_frame_width_.push_back(pkt->data.frame.width[0]); - encode_frame_height_.push_back(pkt->data.frame.height[0]); - } - - unsigned int GetFrameWidth(size_t idx) const { - return encode_frame_width_[idx]; - } - - unsigned int GetFrameHeight(size_t idx) const { - return encode_frame_height_[idx]; - } - - void DecompressedFrameHook(const vpx_image_t &img, - vpx_codec_pts_t pts) override { - frame_info_list_.push_back(FrameInfo(pts, img.d_w, img.d_h)); - } - - std::vector frame_info_list_; - std::vector encode_frame_width_; - std::vector encode_frame_height_; -}; - -TEST_P(ResizeTest, TestExternalResizeWorks) { - ResizingVideoSource video; - video.flag_codec_ = false; - video.smaller_width_larger_size_ = false; - cfg_.g_lag_in_frames = 0; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - for (std::vector::const_iterator info = frame_info_list_.begin(); - info != frame_info_list_.end(); ++info) { - const unsigned int frame = static_cast(info->pts); - unsigned int expected_w; - unsigned int expected_h; - const size_t idx = info - frame_info_list_.begin(); - ASSERT_EQ(info->w, GetFrameWidth(idx)); - ASSERT_EQ(info->h, GetFrameHeight(idx)); - ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w, - &expected_h, video.flag_codec_, - video.smaller_width_larger_size_); - EXPECT_EQ(expected_w, info->w) - << "Frame " << frame << " had unexpected width"; - EXPECT_EQ(expected_h, info->h) - << "Frame " << frame << " had unexpected height"; - } -} - -const unsigned int kStepDownFrame = 3; -const unsigned int kStepUpFrame = 6; - -class ResizeInternalTest : public ResizeTest { - protected: -#if WRITE_COMPRESSED_STREAM - ResizeInternalTest() - : ResizeTest(), frame0_psnr_(0.0), outfile_(nullptr), out_frames_(0) {} -#else - ResizeInternalTest() : ResizeTest(), frame0_psnr_(0.0) {} -#endif - - ~ResizeInternalTest() override = default; - - void BeginPassHook(unsigned int /*pass*/) override { -#if WRITE_COMPRESSED_STREAM - outfile_ = fopen("vp90-2-05-resize.ivf", "wb"); -#endif - } - - void EndPassHook() override { -#if WRITE_COMPRESSED_STREAM - if (outfile_) { - if (!fseek(outfile_, 0, SEEK_SET)) - write_ivf_file_header(&cfg_, out_frames_, outfile_); - fclose(outfile_); - outfile_ = nullptr; - } -#endif - } - - void PreEncodeFrameHook(libvpx_test::VideoSource *video, - libvpx_test::Encoder *encoder) override { - if (change_config_) { - int new_q = 60; - if (video->frame() == 0) { - struct vpx_scaling_mode mode = { VP8E_ONETWO, VP8E_ONETWO }; - encoder->Control(VP8E_SET_SCALEMODE, &mode); - } - if (video->frame() == 1) { - struct vpx_scaling_mode mode = { VP8E_NORMAL, VP8E_NORMAL }; - encoder->Control(VP8E_SET_SCALEMODE, &mode); - cfg_.rc_min_quantizer = cfg_.rc_max_quantizer = new_q; - encoder->Config(&cfg_); - } - } else { - if (video->frame() == kStepDownFrame) { - struct vpx_scaling_mode mode = { VP8E_FOURFIVE, VP8E_THREEFIVE }; - encoder->Control(VP8E_SET_SCALEMODE, &mode); - } - if (video->frame() == kStepUpFrame) { - struct vpx_scaling_mode mode = { VP8E_NORMAL, VP8E_NORMAL }; - encoder->Control(VP8E_SET_SCALEMODE, &mode); - } - } - } - - void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) override { - if (frame0_psnr_ == 0.) frame0_psnr_ = pkt->data.psnr.psnr[0]; - EXPECT_NEAR(pkt->data.psnr.psnr[0], frame0_psnr_, 2.0); - } - -#if WRITE_COMPRESSED_STREAM - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - ++out_frames_; - - // Write initial file header if first frame. - if (pkt->data.frame.pts == 0) write_ivf_file_header(&cfg_, 0, outfile_); - - // Write frame header and data. - write_ivf_frame_header(pkt, outfile_); - (void)fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz, outfile_); - } -#endif - - double frame0_psnr_; - bool change_config_; -#if WRITE_COMPRESSED_STREAM - FILE *outfile_; - unsigned int out_frames_; -#endif -}; - -TEST_P(ResizeInternalTest, TestInternalResizeWorks) { - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 10); - init_flags_ = VPX_CODEC_USE_PSNR; - change_config_ = false; - - // q picked such that initial keyframe on this clip is ~30dB PSNR - cfg_.rc_min_quantizer = cfg_.rc_max_quantizer = 48; - - // If the number of frames being encoded is smaller than g_lag_in_frames - // the encoded frame is unavailable using the current API. Comparing - // frames to detect mismatch would then not be possible. Set - // g_lag_in_frames = 0 to get around this. - cfg_.g_lag_in_frames = 0; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - for (std::vector::const_iterator info = frame_info_list_.begin(); - info != frame_info_list_.end(); ++info) { - const vpx_codec_pts_t pts = info->pts; - if (pts >= kStepDownFrame && pts < kStepUpFrame) { - ASSERT_EQ(282U, info->w) << "Frame " << pts << " had unexpected width"; - ASSERT_EQ(173U, info->h) << "Frame " << pts << " had unexpected height"; - } else { - EXPECT_EQ(352U, info->w) << "Frame " << pts << " had unexpected width"; - EXPECT_EQ(288U, info->h) << "Frame " << pts << " had unexpected height"; - } - } -} - -TEST_P(ResizeInternalTest, TestInternalResizeChangeConfig) { - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 10); - cfg_.g_w = 352; - cfg_.g_h = 288; - change_config_ = true; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -class ResizeRealtimeTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith2Params { - protected: - ResizeRealtimeTest() : EncoderTest(GET_PARAM(0)) {} - ~ResizeRealtimeTest() override = default; - - void PreEncodeFrameHook(libvpx_test::VideoSource *video, - libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP9E_SET_AQ_MODE, 3); - encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_); - } - - if (change_bitrate_ && video->frame() == 120) { - change_bitrate_ = false; - cfg_.rc_target_bitrate = 500; - encoder->Config(&cfg_); - } - } - - void SetUp() override { - InitializeConfig(); - SetMode(GET_PARAM(1)); - set_cpu_used_ = GET_PARAM(2); - } - - void DecompressedFrameHook(const vpx_image_t &img, - vpx_codec_pts_t pts) override { - frame_info_list_.push_back(FrameInfo(pts, img.d_w, img.d_h)); - } - - void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) override { - double mismatch_psnr = compute_psnr(img1, img2); - mismatch_psnr_ += mismatch_psnr; - ++mismatch_nframes_; - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - ASSERT_NE(static_cast(pkt->data.frame.width[0]), 0); - ASSERT_NE(static_cast(pkt->data.frame.height[0]), 0); - encode_frame_width_.push_back(pkt->data.frame.width[0]); - encode_frame_height_.push_back(pkt->data.frame.height[0]); - } - - unsigned int GetMismatchFrames() { return mismatch_nframes_; } - - unsigned int GetFrameWidth(size_t idx) const { - return encode_frame_width_[idx]; - } - - unsigned int GetFrameHeight(size_t idx) const { - return encode_frame_height_[idx]; - } - - void DefaultConfig() { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 600; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 2; - cfg_.rc_max_quantizer = 56; - cfg_.rc_undershoot_pct = 50; - cfg_.rc_overshoot_pct = 50; - cfg_.rc_end_usage = VPX_CBR; - cfg_.kf_mode = VPX_KF_AUTO; - cfg_.g_lag_in_frames = 0; - cfg_.kf_min_dist = cfg_.kf_max_dist = 3000; - // Enable dropped frames. - cfg_.rc_dropframe_thresh = 1; - // Enable error_resilience mode. - cfg_.g_error_resilient = 1; - // Enable dynamic resizing. - cfg_.rc_resize_allowed = 1; - // Run at low bitrate. - cfg_.rc_target_bitrate = 200; - } - - std::vector frame_info_list_; - int set_cpu_used_; - bool change_bitrate_; - double mismatch_psnr_; - int mismatch_nframes_; - std::vector encode_frame_width_; - std::vector encode_frame_height_; -}; - -TEST_P(ResizeRealtimeTest, TestExternalResizeWorks) { - ResizingVideoSource video; - video.flag_codec_ = true; - video.smaller_width_larger_size_ = false; - DefaultConfig(); - // Disable internal resize for this test. - cfg_.rc_resize_allowed = 0; - change_bitrate_ = false; - mismatch_psnr_ = 0.0; - mismatch_nframes_ = 0; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - for (std::vector::const_iterator info = frame_info_list_.begin(); - info != frame_info_list_.end(); ++info) { - const unsigned int frame = static_cast(info->pts); - unsigned int expected_w; - unsigned int expected_h; - ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w, - &expected_h, video.flag_codec_, - video.smaller_width_larger_size_); - EXPECT_EQ(expected_w, info->w) - << "Frame " << frame << " had unexpected width"; - EXPECT_EQ(expected_h, info->h) - << "Frame " << frame << " had unexpected height"; - EXPECT_EQ(static_cast(0), GetMismatchFrames()); - } -} - -TEST_P(ResizeRealtimeTest, TestExternalResizeSmallerWidthBiggerSize) { - ResizingVideoSource video; - video.flag_codec_ = true; - video.smaller_width_larger_size_ = true; - DefaultConfig(); - // Disable internal resize for this test. - cfg_.rc_resize_allowed = 0; - change_bitrate_ = false; - mismatch_psnr_ = 0.0; - mismatch_nframes_ = 0; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - for (std::vector::const_iterator info = frame_info_list_.begin(); - info != frame_info_list_.end(); ++info) { - const unsigned int frame = static_cast(info->pts); - unsigned int expected_w; - unsigned int expected_h; - ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w, - &expected_h, video.flag_codec_, - video.smaller_width_larger_size_); - EXPECT_EQ(expected_w, info->w) - << "Frame " << frame << " had unexpected width"; - EXPECT_EQ(expected_h, info->h) - << "Frame " << frame << " had unexpected height"; - EXPECT_EQ(static_cast(0), GetMismatchFrames()); - } -} - -// Verify the dynamic resizer behavior for real time, 1 pass CBR mode. -// Run at low bitrate, with resize_allowed = 1, and verify that we get -// one resize down event. -TEST_P(ResizeRealtimeTest, TestInternalResizeDown) { - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 299); - DefaultConfig(); - cfg_.g_w = 640; - cfg_.g_h = 480; - change_bitrate_ = false; - mismatch_psnr_ = 0.0; - mismatch_nframes_ = 0; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - -#if CONFIG_VP9_DECODER - unsigned int last_w = cfg_.g_w; - unsigned int last_h = cfg_.g_h; - int resize_count = 0; - for (std::vector::const_iterator info = frame_info_list_.begin(); - info != frame_info_list_.end(); ++info) { - if (info->w != last_w || info->h != last_h) { - // Verify that resize down occurs. - ASSERT_LT(info->w, last_w); - ASSERT_LT(info->h, last_h); - last_w = info->w; - last_h = info->h; - resize_count++; - } - } - - // Verify that we get 1 resize down event in this test. - ASSERT_EQ(1, resize_count) << "Resizing should occur."; - EXPECT_EQ(static_cast(0), GetMismatchFrames()); -#else - GTEST_SKIP() - << "Warning: VP9 decoder unavailable, unable to check resize count!\n"; -#endif -} - -// Verify the dynamic resizer behavior for real time, 1 pass CBR mode. -// Start at low target bitrate, raise the bitrate in the middle of the clip, -// scaling-up should occur after bitrate changed. -TEST_P(ResizeRealtimeTest, TestInternalResizeDownUpChangeBitRate) { - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - DefaultConfig(); - cfg_.g_w = 640; - cfg_.g_h = 480; - change_bitrate_ = true; - mismatch_psnr_ = 0.0; - mismatch_nframes_ = 0; - // Disable dropped frames. - cfg_.rc_dropframe_thresh = 0; - // Starting bitrate low. - cfg_.rc_target_bitrate = 80; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - unsigned int last_w = cfg_.g_w; - unsigned int last_h = cfg_.g_h; - int resize_count = 0; - for (std::vector::const_iterator info = frame_info_list_.begin(); - info != frame_info_list_.end(); ++info) { - const size_t idx = info - frame_info_list_.begin(); - ASSERT_EQ(info->w, GetFrameWidth(idx)); - ASSERT_EQ(info->h, GetFrameHeight(idx)); - if (info->w != last_w || info->h != last_h) { - resize_count++; - if (resize_count <= 2) { - // Verify that resize down occurs. - ASSERT_LT(info->w, last_w); - ASSERT_LT(info->h, last_h); - } else if (resize_count > 2) { - // Verify that resize up occurs. - ASSERT_GT(info->w, last_w); - ASSERT_GT(info->h, last_h); - } - last_w = info->w; - last_h = info->h; - } - } - -#if CONFIG_VP9_DECODER - // Verify that we get 4 resize events in this test. - ASSERT_EQ(resize_count, 4) << "Resizing should occur twice."; - EXPECT_EQ(static_cast(0), GetMismatchFrames()); -#else - GTEST_SKIP() - << "Warning: VP9 decoder unavailable, unable to check resize count!\n"; -#endif -} - -vpx_img_fmt_t CspForFrameNumber(int frame) { - if (frame < 10) return VPX_IMG_FMT_I420; - if (frame < 20) return VPX_IMG_FMT_I444; - return VPX_IMG_FMT_I420; -} - -class ResizeCspTest : public ResizeTest { - protected: -#if WRITE_COMPRESSED_STREAM - ResizeCspTest() - : ResizeTest(), frame0_psnr_(0.0), outfile_(nullptr), out_frames_(0) {} -#else - ResizeCspTest() : ResizeTest(), frame0_psnr_(0.0) {} -#endif - - ~ResizeCspTest() override = default; - - void BeginPassHook(unsigned int /*pass*/) override { -#if WRITE_COMPRESSED_STREAM - outfile_ = fopen("vp91-2-05-cspchape.ivf", "wb"); -#endif - } - - void EndPassHook() override { -#if WRITE_COMPRESSED_STREAM - if (outfile_) { - if (!fseek(outfile_, 0, SEEK_SET)) - write_ivf_file_header(&cfg_, out_frames_, outfile_); - fclose(outfile_); - outfile_ = nullptr; - } -#endif - } - - void PreEncodeFrameHook(libvpx_test::VideoSource *video, - libvpx_test::Encoder *encoder) override { - if (CspForFrameNumber(video->frame()) != VPX_IMG_FMT_I420 && - cfg_.g_profile != 1) { - cfg_.g_profile = 1; - encoder->Config(&cfg_); - } - if (CspForFrameNumber(video->frame()) == VPX_IMG_FMT_I420 && - cfg_.g_profile != 0) { - cfg_.g_profile = 0; - encoder->Config(&cfg_); - } - } - - void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) override { - if (frame0_psnr_ == 0.) frame0_psnr_ = pkt->data.psnr.psnr[0]; - EXPECT_NEAR(pkt->data.psnr.psnr[0], frame0_psnr_, 2.0); - } - -#if WRITE_COMPRESSED_STREAM - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - ++out_frames_; - - // Write initial file header if first frame. - if (pkt->data.frame.pts == 0) write_ivf_file_header(&cfg_, 0, outfile_); - - // Write frame header and data. - write_ivf_frame_header(pkt, outfile_); - (void)fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz, outfile_); - } -#endif - - double frame0_psnr_; -#if WRITE_COMPRESSED_STREAM - FILE *outfile_; - unsigned int out_frames_; -#endif -}; - -class ResizingCspVideoSource : public ::libvpx_test::DummyVideoSource { - public: - ResizingCspVideoSource() { - SetSize(kInitialWidth, kInitialHeight); - limit_ = 30; - } - - ~ResizingCspVideoSource() override = default; - - protected: - void Next() override { - ++frame_; - SetImageFormat(CspForFrameNumber(frame_)); - FillFrame(); - } -}; - -TEST_P(ResizeCspTest, TestResizeCspWorks) { - ResizingCspVideoSource video; - init_flags_ = VPX_CODEC_USE_PSNR; - cfg_.rc_min_quantizer = cfg_.rc_max_quantizer = 48; - cfg_.g_lag_in_frames = 0; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -VP8_INSTANTIATE_TEST_SUITE(ResizeTest, ONE_PASS_TEST_MODES); -VP9_INSTANTIATE_TEST_SUITE(ResizeTest, ONE_PASS_TEST_MODES); -VP9_INSTANTIATE_TEST_SUITE(ResizeInternalTest, - ::testing::Values(::libvpx_test::kOnePassBest)); -VP9_INSTANTIATE_TEST_SUITE(ResizeRealtimeTest, - ::testing::Values(::libvpx_test::kRealTime), - ::testing::Range(5, 9)); -VP9_INSTANTIATE_TEST_SUITE(ResizeCspTest, - ::testing::Values(::libvpx_test::kRealTime)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/sad_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/sad_test.cc deleted file mode 100644 index 73beb19e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/sad_test.cc +++ /dev/null @@ -1,2079 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "test/acm_random.h" -#include "test/bench.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vpx/vpx_codec.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/vpx_timer.h" - -// const[expr] should be sufficient for DECLARE_ALIGNED but early -// implementations of c++11 appear to have some issues with it. -#define kDataAlignment 32 - -template -struct TestParams { - TestParams(int w, int h, Function f, int bd = -1) - : width(w), height(h), bit_depth(bd), func(f) {} - int width, height, bit_depth; - Function func; -}; - -typedef unsigned int (*SadMxNFunc)(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride); -typedef TestParams SadMxNParam; - -typedef unsigned int (*SadSkipMxNFunc)(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride); -typedef TestParams SadSkipMxNParam; - -typedef unsigned int (*SadMxNAvgFunc)(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - const uint8_t *second_pred); -typedef TestParams SadMxNAvgParam; - -typedef void (*SadMxNx4Func)(const uint8_t *src_ptr, int src_stride, - const uint8_t *const ref_ptr[], int ref_stride, - unsigned int *sad_array); -typedef TestParams SadMxNx4Param; - -typedef void (*SadSkipMxNx4Func)(const uint8_t *src_ptr, int src_stride, - const uint8_t *const ref_ptr[], int ref_stride, - unsigned int *sad_array); -typedef TestParams SadSkipMxNx4Param; - -typedef void (*SadMxNx8Func)(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sad_array); - -using libvpx_test::ACMRandom; - -namespace { -template -class SADTestBase : public ::testing::TestWithParam { - public: - explicit SADTestBase(const ParamType ¶ms) : params_(params) {} - - void SetUp() override { - source_data8_ = reinterpret_cast( - vpx_memalign(kDataAlignment, kDataBlockSize)); - reference_data8_ = reinterpret_cast( - vpx_memalign(kDataAlignment, kDataBufferSize)); - second_pred8_ = - reinterpret_cast(vpx_memalign(kDataAlignment, 64 * 64)); - source_data16_ = reinterpret_cast( - vpx_memalign(kDataAlignment, kDataBlockSize * sizeof(uint16_t))); - reference_data16_ = reinterpret_cast( - vpx_memalign(kDataAlignment, kDataBufferSize * sizeof(uint16_t))); - second_pred16_ = reinterpret_cast( - vpx_memalign(kDataAlignment, 64 * 64 * sizeof(uint16_t))); - - if (params_.bit_depth == -1) { - use_high_bit_depth_ = false; - bit_depth_ = VPX_BITS_8; - source_data_ = source_data8_; - reference_data_ = reference_data8_; - second_pred_ = second_pred8_; -#if CONFIG_VP9_HIGHBITDEPTH - } else { - use_high_bit_depth_ = true; - bit_depth_ = static_cast(params_.bit_depth); - source_data_ = CONVERT_TO_BYTEPTR(source_data16_); - reference_data_ = CONVERT_TO_BYTEPTR(reference_data16_); - second_pred_ = CONVERT_TO_BYTEPTR(second_pred16_); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - mask_ = (1 << bit_depth_) - 1; - source_stride_ = (params_.width + 63) & ~63; - reference_stride_ = params_.width * 2; - rnd_.Reset(ACMRandom::DeterministicSeed()); - } - - void TearDown() override { - vpx_free(source_data8_); - source_data8_ = nullptr; - vpx_free(reference_data8_); - reference_data8_ = nullptr; - vpx_free(second_pred8_); - second_pred8_ = nullptr; - vpx_free(source_data16_); - source_data16_ = nullptr; - vpx_free(reference_data16_); - reference_data16_ = nullptr; - vpx_free(second_pred16_); - second_pred16_ = nullptr; - - libvpx_test::ClearSystemState(); - } - - protected: - // Handle blocks up to 4 blocks 64x64 with stride up to 128 - // crbug.com/webm/1660 - static const int kDataBlockSize = 64 * 128; - static const int kDataBufferSize = 4 * kDataBlockSize; - - int GetBlockRefOffset(int block_idx) const { - return block_idx * kDataBlockSize; - } - - uint8_t *GetReferenceFromOffset(int ref_offset) const { - assert((params_.height - 1) * reference_stride_ + params_.width - 1 + - ref_offset < - kDataBufferSize); -#if CONFIG_VP9_HIGHBITDEPTH - if (use_high_bit_depth_) { - return CONVERT_TO_BYTEPTR(CONVERT_TO_SHORTPTR(reference_data_) + - ref_offset); - } -#endif // CONFIG_VP9_HIGHBITDEPTH - return reference_data_ + ref_offset; - } - - uint8_t *GetReference(int block_idx) const { - return GetReferenceFromOffset(GetBlockRefOffset(block_idx)); - } - - // Sum of Absolute Differences. Given two blocks, calculate the absolute - // difference between two pixels in the same relative location; accumulate. - uint32_t ReferenceSAD(int ref_offset) const { - uint32_t sad = 0; - const uint8_t *const reference8 = GetReferenceFromOffset(ref_offset); - const uint8_t *const source8 = source_data_; -#if CONFIG_VP9_HIGHBITDEPTH - const uint16_t *const reference16 = - CONVERT_TO_SHORTPTR(GetReferenceFromOffset(ref_offset)); - const uint16_t *const source16 = CONVERT_TO_SHORTPTR(source_data_); -#endif // CONFIG_VP9_HIGHBITDEPTH - for (int h = 0; h < params_.height; ++h) { - for (int w = 0; w < params_.width; ++w) { - if (!use_high_bit_depth_) { - sad += abs(source8[h * source_stride_ + w] - - reference8[h * reference_stride_ + w]); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - sad += abs(source16[h * source_stride_ + w] - - reference16[h * reference_stride_ + w]); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - } - return sad; - } - - // Sum of Absolute Differences Skip rows. Given two blocks, calculate the - // absolute difference between two pixels in the same relative location every - // other row; accumulate and double the result at the end. - uint32_t ReferenceSADSkip(int ref_offset) const { - uint32_t sad = 0; - const uint8_t *const reference8 = GetReferenceFromOffset(ref_offset); - const uint8_t *const source8 = source_data_; -#if CONFIG_VP9_HIGHBITDEPTH - const uint16_t *const reference16 = - CONVERT_TO_SHORTPTR(GetReferenceFromOffset(ref_offset)); - const uint16_t *const source16 = CONVERT_TO_SHORTPTR(source_data_); -#endif // CONFIG_VP9_HIGHBITDEPTH - for (int h = 0; h < params_.height; h += 2) { - for (int w = 0; w < params_.width; ++w) { - if (!use_high_bit_depth_) { - sad += abs(source8[h * source_stride_ + w] - - reference8[h * reference_stride_ + w]); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - sad += abs(source16[h * source_stride_ + w] - - reference16[h * reference_stride_ + w]); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - } - return sad * 2; - } - - // Sum of Absolute Differences Average. Given two blocks, and a prediction - // calculate the absolute difference between one pixel and average of the - // corresponding and predicted pixels; accumulate. - unsigned int ReferenceSADavg(int block_idx) const { - unsigned int sad = 0; - const uint8_t *const reference8 = GetReference(block_idx); - const uint8_t *const source8 = source_data_; - const uint8_t *const second_pred8 = second_pred_; -#if CONFIG_VP9_HIGHBITDEPTH - const uint16_t *const reference16 = - CONVERT_TO_SHORTPTR(GetReference(block_idx)); - const uint16_t *const source16 = CONVERT_TO_SHORTPTR(source_data_); - const uint16_t *const second_pred16 = CONVERT_TO_SHORTPTR(second_pred_); -#endif // CONFIG_VP9_HIGHBITDEPTH - for (int h = 0; h < params_.height; ++h) { - for (int w = 0; w < params_.width; ++w) { - if (!use_high_bit_depth_) { - const int tmp = second_pred8[h * params_.width + w] + - reference8[h * reference_stride_ + w]; - const uint8_t comp_pred = ROUND_POWER_OF_TWO(tmp, 1); - sad += abs(source8[h * source_stride_ + w] - comp_pred); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - const int tmp = second_pred16[h * params_.width + w] + - reference16[h * reference_stride_ + w]; - const uint16_t comp_pred = ROUND_POWER_OF_TWO(tmp, 1); - sad += abs(source16[h * source_stride_ + w] - comp_pred); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - } - return sad; - } - - void FillConstant(uint8_t *data, int stride, uint16_t fill_constant) const { - uint8_t *data8 = data; -#if CONFIG_VP9_HIGHBITDEPTH - uint16_t *data16 = CONVERT_TO_SHORTPTR(data); -#endif // CONFIG_VP9_HIGHBITDEPTH - for (int h = 0; h < params_.height; ++h) { - for (int w = 0; w < params_.width; ++w) { - if (!use_high_bit_depth_) { - data8[h * stride + w] = static_cast(fill_constant); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - data16[h * stride + w] = fill_constant; -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - } - } - - void FillRandomWH(uint8_t *data, int stride, int w, int h) { - uint8_t *data8 = data; -#if CONFIG_VP9_HIGHBITDEPTH - uint16_t *data16 = CONVERT_TO_SHORTPTR(data); -#endif // CONFIG_VP9_HIGHBITDEPTH - for (int r = 0; r < h; ++r) { - for (int c = 0; c < w; ++c) { - if (!use_high_bit_depth_) { - data8[r * stride + c] = rnd_.Rand8(); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - data16[r * stride + c] = rnd_.Rand16() & mask_; -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - } - } - - void FillRandom(uint8_t *data, int stride) { - FillRandomWH(data, stride, params_.width, params_.height); - } - - uint32_t mask_; - vpx_bit_depth_t bit_depth_; - int source_stride_; - int reference_stride_; - bool use_high_bit_depth_; - - uint8_t *source_data_; - uint8_t *reference_data_; - uint8_t *second_pred_; - uint8_t *source_data8_; - uint8_t *reference_data8_; - uint8_t *second_pred8_; - uint16_t *source_data16_; - uint16_t *reference_data16_; - uint16_t *second_pred16_; - - ACMRandom rnd_; - ParamType params_; -}; - -class SADx4Test : public SADTestBase { - public: - SADx4Test() : SADTestBase(GetParam()) {} - - protected: - void SADs(unsigned int *results) const { - const uint8_t *references[] = { GetReference(0), GetReference(1), - GetReference(2), GetReference(3) }; - - ASM_REGISTER_STATE_CHECK(params_.func( - source_data_, source_stride_, references, reference_stride_, results)); - } - - void CheckSADs() const { - uint32_t reference_sad; - DECLARE_ALIGNED(kDataAlignment, uint32_t, exp_sad[4]); - - SADs(exp_sad); - for (int block = 0; block < 4; ++block) { - reference_sad = ReferenceSAD(GetBlockRefOffset(block)); - - EXPECT_EQ(reference_sad, exp_sad[block]) << "block " << block; - } - } -}; - -class SADSkipx4Test : public SADTestBase { - public: - SADSkipx4Test() : SADTestBase(GetParam()) {} - - protected: - void SADs(unsigned int *results) const { - const uint8_t *references[] = { GetReference(0), GetReference(1), - GetReference(2), GetReference(3) }; - - ASM_REGISTER_STATE_CHECK(params_.func( - source_data_, source_stride_, references, reference_stride_, results)); - } - - void CheckSADs() const { - uint32_t reference_sad; - DECLARE_ALIGNED(kDataAlignment, uint32_t, exp_sad[4]); - - SADs(exp_sad); - for (int block = 0; block < 4; ++block) { - reference_sad = ReferenceSADSkip(GetBlockRefOffset(block)); - - EXPECT_EQ(reference_sad, exp_sad[block]) << "block " << block; - } - } -}; - -class SADTest : public AbstractBench, public SADTestBase { - public: - SADTest() : SADTestBase(GetParam()) {} - - protected: - unsigned int SAD(int block_idx) const { - unsigned int ret; - const uint8_t *const reference = GetReference(block_idx); - - ASM_REGISTER_STATE_CHECK(ret = params_.func(source_data_, source_stride_, - reference, reference_stride_)); - return ret; - } - - void CheckSAD() const { - const unsigned int reference_sad = ReferenceSAD(GetBlockRefOffset(0)); - const unsigned int exp_sad = SAD(0); - - ASSERT_EQ(reference_sad, exp_sad); - } - - void Run() override { - params_.func(source_data_, source_stride_, reference_data_, - reference_stride_); - } -}; - -class SADSkipTest : public AbstractBench, public SADTestBase { - public: - SADSkipTest() : SADTestBase(GetParam()) {} - - protected: - unsigned int SAD(int block_idx) const { - unsigned int ret; - const uint8_t *const reference = GetReference(block_idx); - - ASM_REGISTER_STATE_CHECK(ret = params_.func(source_data_, source_stride_, - reference, reference_stride_)); - return ret; - } - - void CheckSAD() const { - const unsigned int reference_sad = ReferenceSADSkip(GetBlockRefOffset(0)); - const unsigned int exp_sad = SAD(0); - - ASSERT_EQ(reference_sad, exp_sad); - } - - void Run() override { - params_.func(source_data_, source_stride_, reference_data_, - reference_stride_); - } -}; - -class SADavgTest : public AbstractBench, public SADTestBase { - public: - SADavgTest() : SADTestBase(GetParam()) {} - - protected: - unsigned int SAD_avg(int block_idx) const { - unsigned int ret; - const uint8_t *const reference = GetReference(block_idx); - - ASM_REGISTER_STATE_CHECK(ret = params_.func(source_data_, source_stride_, - reference, reference_stride_, - second_pred_)); - return ret; - } - - void CheckSAD() const { - const unsigned int reference_sad = ReferenceSADavg(0); - const unsigned int exp_sad = SAD_avg(0); - - ASSERT_EQ(reference_sad, exp_sad); - } - - void Run() override { - params_.func(source_data_, source_stride_, reference_data_, - reference_stride_, second_pred_); - } -}; - -TEST_P(SADTest, MaxRef) { - FillConstant(source_data_, source_stride_, 0); - FillConstant(reference_data_, reference_stride_, mask_); - CheckSAD(); -} - -TEST_P(SADTest, MaxSrc) { - FillConstant(source_data_, source_stride_, mask_); - FillConstant(reference_data_, reference_stride_, 0); - CheckSAD(); -} - -TEST_P(SADTest, ShortRef) { - const int tmp_stride = reference_stride_; - reference_stride_ >>= 1; - FillRandom(source_data_, source_stride_); - FillRandom(reference_data_, reference_stride_); - CheckSAD(); - reference_stride_ = tmp_stride; -} - -TEST_P(SADTest, UnalignedRef) { - // The reference frame, but not the source frame, may be unaligned for - // certain types of searches. - const int tmp_stride = reference_stride_; - reference_stride_ -= 1; - FillRandom(source_data_, source_stride_); - FillRandom(reference_data_, reference_stride_); - CheckSAD(); - reference_stride_ = tmp_stride; -} - -TEST_P(SADTest, ShortSrc) { - const int tmp_stride = source_stride_; - source_stride_ >>= 1; - FillRandom(source_data_, source_stride_); - FillRandom(reference_data_, reference_stride_); - CheckSAD(); - source_stride_ = tmp_stride; -} - -TEST_P(SADTest, DISABLED_Speed) { - const int kCountSpeedTestBlock = 50000000 / (params_.width * params_.height); - FillRandom(source_data_, source_stride_); - - RunNTimes(kCountSpeedTestBlock); - - char title[16]; - snprintf(title, sizeof(title), "%dx%d", params_.width, params_.height); - PrintMedian(title); -} - -TEST_P(SADSkipTest, MaxRef) { - FillConstant(source_data_, source_stride_, 0); - FillConstant(reference_data_, reference_stride_, mask_); - CheckSAD(); -} - -TEST_P(SADSkipTest, MaxSrc) { - FillConstant(source_data_, source_stride_, mask_); - FillConstant(reference_data_, reference_stride_, 0); - CheckSAD(); -} - -TEST_P(SADSkipTest, ShortRef) { - const int tmp_stride = reference_stride_; - reference_stride_ >>= 1; - FillRandom(source_data_, source_stride_); - FillRandom(reference_data_, reference_stride_); - CheckSAD(); - reference_stride_ = tmp_stride; -} - -TEST_P(SADSkipTest, UnalignedRef) { - // The reference frame, but not the source frame, may be unaligned for - // certain types of searches. - const int tmp_stride = reference_stride_; - reference_stride_ -= 1; - FillRandom(source_data_, source_stride_); - FillRandom(reference_data_, reference_stride_); - CheckSAD(); - reference_stride_ = tmp_stride; -} - -TEST_P(SADSkipTest, ShortSrc) { - const int tmp_stride = source_stride_; - source_stride_ >>= 1; - FillRandom(source_data_, source_stride_); - FillRandom(reference_data_, reference_stride_); - CheckSAD(); - source_stride_ = tmp_stride; -} - -TEST_P(SADSkipTest, DISABLED_Speed) { - const int kCountSpeedTestBlock = 50000000 / (params_.width * params_.height); - FillRandom(source_data_, source_stride_); - - RunNTimes(kCountSpeedTestBlock); - - char title[16]; - snprintf(title, sizeof(title), "%dx%d", params_.width, params_.height); - PrintMedian(title); -} - -TEST_P(SADavgTest, MaxRef) { - FillConstant(source_data_, source_stride_, 0); - FillConstant(reference_data_, reference_stride_, mask_); - FillConstant(second_pred_, params_.width, 0); - CheckSAD(); -} -TEST_P(SADavgTest, MaxSrc) { - FillConstant(source_data_, source_stride_, mask_); - FillConstant(reference_data_, reference_stride_, 0); - FillConstant(second_pred_, params_.width, 0); - CheckSAD(); -} - -TEST_P(SADavgTest, ShortRef) { - const int tmp_stride = reference_stride_; - reference_stride_ >>= 1; - FillRandom(source_data_, source_stride_); - FillRandom(reference_data_, reference_stride_); - FillRandom(second_pred_, params_.width); - CheckSAD(); - reference_stride_ = tmp_stride; -} - -TEST_P(SADavgTest, UnalignedRef) { - // The reference frame, but not the source frame, may be unaligned for - // certain types of searches. - const int tmp_stride = reference_stride_; - reference_stride_ -= 1; - FillRandom(source_data_, source_stride_); - FillRandom(reference_data_, reference_stride_); - FillRandom(second_pred_, params_.width); - CheckSAD(); - reference_stride_ = tmp_stride; -} - -TEST_P(SADavgTest, ShortSrc) { - const int tmp_stride = source_stride_; - source_stride_ >>= 1; - FillRandom(source_data_, source_stride_); - FillRandom(reference_data_, reference_stride_); - FillRandom(second_pred_, params_.width); - CheckSAD(); - source_stride_ = tmp_stride; -} - -TEST_P(SADavgTest, DISABLED_Speed) { - const int kCountSpeedTestBlock = 50000000 / (params_.width * params_.height); - FillRandom(source_data_, source_stride_); - FillRandom(reference_data_, reference_stride_); - FillRandom(second_pred_, params_.width); - - RunNTimes(kCountSpeedTestBlock); - - char title[16]; - snprintf(title, sizeof(title), "%dx%d", params_.width, params_.height); - PrintMedian(title); -} - -TEST_P(SADx4Test, MaxRef) { - FillConstant(source_data_, source_stride_, 0); - FillConstant(GetReference(0), reference_stride_, mask_); - FillConstant(GetReference(1), reference_stride_, mask_); - FillConstant(GetReference(2), reference_stride_, mask_); - FillConstant(GetReference(3), reference_stride_, mask_); - CheckSADs(); -} - -TEST_P(SADx4Test, MaxSrc) { - FillConstant(source_data_, source_stride_, mask_); - FillConstant(GetReference(0), reference_stride_, 0); - FillConstant(GetReference(1), reference_stride_, 0); - FillConstant(GetReference(2), reference_stride_, 0); - FillConstant(GetReference(3), reference_stride_, 0); - CheckSADs(); -} - -TEST_P(SADx4Test, ShortRef) { - int tmp_stride = reference_stride_; - reference_stride_ >>= 1; - FillRandom(source_data_, source_stride_); - FillRandom(GetReference(0), reference_stride_); - FillRandom(GetReference(1), reference_stride_); - FillRandom(GetReference(2), reference_stride_); - FillRandom(GetReference(3), reference_stride_); - CheckSADs(); - reference_stride_ = tmp_stride; -} - -TEST_P(SADx4Test, UnalignedRef) { - // The reference frame, but not the source frame, may be unaligned for - // certain types of searches. - int tmp_stride = reference_stride_; - reference_stride_ -= 1; - FillRandom(source_data_, source_stride_); - FillRandom(GetReference(0), reference_stride_); - FillRandom(GetReference(1), reference_stride_); - FillRandom(GetReference(2), reference_stride_); - FillRandom(GetReference(3), reference_stride_); - CheckSADs(); - reference_stride_ = tmp_stride; -} - -TEST_P(SADx4Test, ShortSrc) { - int tmp_stride = source_stride_; - source_stride_ >>= 1; - FillRandom(source_data_, source_stride_); - FillRandom(GetReference(0), reference_stride_); - FillRandom(GetReference(1), reference_stride_); - FillRandom(GetReference(2), reference_stride_); - FillRandom(GetReference(3), reference_stride_); - CheckSADs(); - source_stride_ = tmp_stride; -} - -TEST_P(SADx4Test, SrcAlignedByWidth) { - uint8_t *tmp_source_data = source_data_; - source_data_ += params_.width; - FillRandom(source_data_, source_stride_); - FillRandom(GetReference(0), reference_stride_); - FillRandom(GetReference(1), reference_stride_); - FillRandom(GetReference(2), reference_stride_); - FillRandom(GetReference(3), reference_stride_); - CheckSADs(); - source_data_ = tmp_source_data; -} - -TEST_P(SADx4Test, DISABLED_Speed) { - int tmp_stride = reference_stride_; - reference_stride_ -= 1; - FillRandom(source_data_, source_stride_); - FillRandom(GetReference(0), reference_stride_); - FillRandom(GetReference(1), reference_stride_); - FillRandom(GetReference(2), reference_stride_); - FillRandom(GetReference(3), reference_stride_); - const int kCountSpeedTestBlock = 500000000 / (params_.width * params_.height); - uint32_t reference_sad[4]; - DECLARE_ALIGNED(kDataAlignment, uint32_t, exp_sad[4]); - vpx_usec_timer timer; - for (int block = 0; block < 4; ++block) { - reference_sad[block] = ReferenceSAD(GetBlockRefOffset(block)); - } - vpx_usec_timer_start(&timer); - for (int i = 0; i < kCountSpeedTestBlock; ++i) { - SADs(exp_sad); - } - vpx_usec_timer_mark(&timer); - for (int block = 0; block < 4; ++block) { - EXPECT_EQ(reference_sad[block], exp_sad[block]) << "block " << block; - } - const int elapsed_time = - static_cast(vpx_usec_timer_elapsed(&timer) / 1000); - printf("sad%dx%dx4 (%2dbit) time: %5d ms\n", params_.width, params_.height, - bit_depth_, elapsed_time); - - reference_stride_ = tmp_stride; -} - -TEST_P(SADSkipx4Test, MaxRef) { - FillConstant(source_data_, source_stride_, 0); - FillConstant(GetReference(0), reference_stride_, mask_); - FillConstant(GetReference(1), reference_stride_, mask_); - FillConstant(GetReference(2), reference_stride_, mask_); - FillConstant(GetReference(3), reference_stride_, mask_); - CheckSADs(); -} - -TEST_P(SADSkipx4Test, MaxSrc) { - FillConstant(source_data_, source_stride_, mask_); - FillConstant(GetReference(0), reference_stride_, 0); - FillConstant(GetReference(1), reference_stride_, 0); - FillConstant(GetReference(2), reference_stride_, 0); - FillConstant(GetReference(3), reference_stride_, 0); - CheckSADs(); -} - -TEST_P(SADSkipx4Test, ShortRef) { - int tmp_stride = reference_stride_; - reference_stride_ >>= 1; - FillRandom(source_data_, source_stride_); - FillRandom(GetReference(0), reference_stride_); - FillRandom(GetReference(1), reference_stride_); - FillRandom(GetReference(2), reference_stride_); - FillRandom(GetReference(3), reference_stride_); - CheckSADs(); - reference_stride_ = tmp_stride; -} - -TEST_P(SADSkipx4Test, UnalignedRef) { - // The reference frame, but not the source frame, may be unaligned for - // certain types of searches. - int tmp_stride = reference_stride_; - reference_stride_ -= 1; - FillRandom(source_data_, source_stride_); - FillRandom(GetReference(0), reference_stride_); - FillRandom(GetReference(1), reference_stride_); - FillRandom(GetReference(2), reference_stride_); - FillRandom(GetReference(3), reference_stride_); - CheckSADs(); - reference_stride_ = tmp_stride; -} - -TEST_P(SADSkipx4Test, ShortSrc) { - int tmp_stride = source_stride_; - source_stride_ >>= 1; - FillRandom(source_data_, source_stride_); - FillRandom(GetReference(0), reference_stride_); - FillRandom(GetReference(1), reference_stride_); - FillRandom(GetReference(2), reference_stride_); - FillRandom(GetReference(3), reference_stride_); - CheckSADs(); - source_stride_ = tmp_stride; -} - -TEST_P(SADSkipx4Test, SrcAlignedByWidth) { - uint8_t *tmp_source_data = source_data_; - source_data_ += params_.width; - FillRandom(source_data_, source_stride_); - FillRandom(GetReference(0), reference_stride_); - FillRandom(GetReference(1), reference_stride_); - FillRandom(GetReference(2), reference_stride_); - FillRandom(GetReference(3), reference_stride_); - CheckSADs(); - source_data_ = tmp_source_data; -} - -TEST_P(SADSkipx4Test, DISABLED_Speed) { - int tmp_stride = reference_stride_; - reference_stride_ -= 1; - FillRandom(source_data_, source_stride_); - FillRandom(GetReference(0), reference_stride_); - FillRandom(GetReference(1), reference_stride_); - FillRandom(GetReference(2), reference_stride_); - FillRandom(GetReference(3), reference_stride_); - const int kCountSpeedTestBlock = 500000000 / (params_.width * params_.height); - uint32_t reference_sad[4]; - DECLARE_ALIGNED(kDataAlignment, uint32_t, exp_sad[4]); - vpx_usec_timer timer; - for (int block = 0; block < 4; ++block) { - reference_sad[block] = ReferenceSADSkip(GetBlockRefOffset(block)); - } - vpx_usec_timer_start(&timer); - for (int i = 0; i < kCountSpeedTestBlock; ++i) { - SADs(exp_sad); - } - vpx_usec_timer_mark(&timer); - for (int block = 0; block < 4; ++block) { - EXPECT_EQ(reference_sad[block], exp_sad[block]) << "block " << block; - } - const int elapsed_time = - static_cast(vpx_usec_timer_elapsed(&timer) / 1000); - printf("sad%dx%dx4 (%2dbit) time: %5d ms\n", params_.width, params_.height, - bit_depth_, elapsed_time); - - reference_stride_ = tmp_stride; -} - -//------------------------------------------------------------------------------ -// C functions -const SadMxNParam c_tests[] = { - SadMxNParam(64, 64, &vpx_sad64x64_c), - SadMxNParam(64, 32, &vpx_sad64x32_c), - SadMxNParam(32, 64, &vpx_sad32x64_c), - SadMxNParam(32, 32, &vpx_sad32x32_c), - SadMxNParam(32, 16, &vpx_sad32x16_c), - SadMxNParam(16, 32, &vpx_sad16x32_c), - SadMxNParam(16, 16, &vpx_sad16x16_c), - SadMxNParam(16, 8, &vpx_sad16x8_c), - SadMxNParam(8, 16, &vpx_sad8x16_c), - SadMxNParam(8, 8, &vpx_sad8x8_c), - SadMxNParam(8, 4, &vpx_sad8x4_c), - SadMxNParam(4, 8, &vpx_sad4x8_c), - SadMxNParam(4, 4, &vpx_sad4x4_c), -#if CONFIG_VP9_HIGHBITDEPTH - SadMxNParam(64, 64, &vpx_highbd_sad64x64_c, 8), - SadMxNParam(64, 32, &vpx_highbd_sad64x32_c, 8), - SadMxNParam(32, 64, &vpx_highbd_sad32x64_c, 8), - SadMxNParam(32, 32, &vpx_highbd_sad32x32_c, 8), - SadMxNParam(32, 16, &vpx_highbd_sad32x16_c, 8), - SadMxNParam(16, 32, &vpx_highbd_sad16x32_c, 8), - SadMxNParam(16, 16, &vpx_highbd_sad16x16_c, 8), - SadMxNParam(16, 8, &vpx_highbd_sad16x8_c, 8), - SadMxNParam(8, 16, &vpx_highbd_sad8x16_c, 8), - SadMxNParam(8, 8, &vpx_highbd_sad8x8_c, 8), - SadMxNParam(8, 4, &vpx_highbd_sad8x4_c, 8), - SadMxNParam(4, 8, &vpx_highbd_sad4x8_c, 8), - SadMxNParam(4, 4, &vpx_highbd_sad4x4_c, 8), - SadMxNParam(64, 64, &vpx_highbd_sad64x64_c, 10), - SadMxNParam(64, 32, &vpx_highbd_sad64x32_c, 10), - SadMxNParam(32, 64, &vpx_highbd_sad32x64_c, 10), - SadMxNParam(32, 32, &vpx_highbd_sad32x32_c, 10), - SadMxNParam(32, 16, &vpx_highbd_sad32x16_c, 10), - SadMxNParam(16, 32, &vpx_highbd_sad16x32_c, 10), - SadMxNParam(16, 16, &vpx_highbd_sad16x16_c, 10), - SadMxNParam(16, 8, &vpx_highbd_sad16x8_c, 10), - SadMxNParam(8, 16, &vpx_highbd_sad8x16_c, 10), - SadMxNParam(8, 8, &vpx_highbd_sad8x8_c, 10), - SadMxNParam(8, 4, &vpx_highbd_sad8x4_c, 10), - SadMxNParam(4, 8, &vpx_highbd_sad4x8_c, 10), - SadMxNParam(4, 4, &vpx_highbd_sad4x4_c, 10), - SadMxNParam(64, 64, &vpx_highbd_sad64x64_c, 12), - SadMxNParam(64, 32, &vpx_highbd_sad64x32_c, 12), - SadMxNParam(32, 64, &vpx_highbd_sad32x64_c, 12), - SadMxNParam(32, 32, &vpx_highbd_sad32x32_c, 12), - SadMxNParam(32, 16, &vpx_highbd_sad32x16_c, 12), - SadMxNParam(16, 32, &vpx_highbd_sad16x32_c, 12), - SadMxNParam(16, 16, &vpx_highbd_sad16x16_c, 12), - SadMxNParam(16, 8, &vpx_highbd_sad16x8_c, 12), - SadMxNParam(8, 16, &vpx_highbd_sad8x16_c, 12), - SadMxNParam(8, 8, &vpx_highbd_sad8x8_c, 12), - SadMxNParam(8, 4, &vpx_highbd_sad8x4_c, 12), - SadMxNParam(4, 8, &vpx_highbd_sad4x8_c, 12), - SadMxNParam(4, 4, &vpx_highbd_sad4x4_c, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(C, SADTest, ::testing::ValuesIn(c_tests)); - -const SadSkipMxNParam skip_c_tests[] = { - SadSkipMxNParam(64, 64, &vpx_sad_skip_64x64_c), - SadSkipMxNParam(64, 32, &vpx_sad_skip_64x32_c), - SadSkipMxNParam(32, 64, &vpx_sad_skip_32x64_c), - SadSkipMxNParam(32, 32, &vpx_sad_skip_32x32_c), - SadSkipMxNParam(32, 16, &vpx_sad_skip_32x16_c), - SadSkipMxNParam(16, 32, &vpx_sad_skip_16x32_c), - SadSkipMxNParam(16, 16, &vpx_sad_skip_16x16_c), - SadSkipMxNParam(16, 8, &vpx_sad_skip_16x8_c), - SadSkipMxNParam(8, 16, &vpx_sad_skip_8x16_c), - SadSkipMxNParam(8, 8, &vpx_sad_skip_8x8_c), - SadSkipMxNParam(4, 8, &vpx_sad_skip_4x8_c), -#if CONFIG_VP9_HIGHBITDEPTH - SadSkipMxNParam(64, 64, &vpx_highbd_sad_skip_64x64_c, 8), - SadSkipMxNParam(64, 32, &vpx_highbd_sad_skip_64x32_c, 8), - SadSkipMxNParam(32, 64, &vpx_highbd_sad_skip_32x64_c, 8), - SadSkipMxNParam(32, 32, &vpx_highbd_sad_skip_32x32_c, 8), - SadSkipMxNParam(32, 16, &vpx_highbd_sad_skip_32x16_c, 8), - SadSkipMxNParam(16, 32, &vpx_highbd_sad_skip_16x32_c, 8), - SadSkipMxNParam(16, 16, &vpx_highbd_sad_skip_16x16_c, 8), - SadSkipMxNParam(16, 8, &vpx_highbd_sad_skip_16x8_c, 8), - SadSkipMxNParam(8, 16, &vpx_highbd_sad_skip_8x16_c, 8), - SadSkipMxNParam(8, 8, &vpx_highbd_sad_skip_8x8_c, 8), - SadSkipMxNParam(4, 8, &vpx_highbd_sad_skip_4x8_c, 8), - SadSkipMxNParam(64, 64, &vpx_highbd_sad_skip_64x64_c, 10), - SadSkipMxNParam(64, 32, &vpx_highbd_sad_skip_64x32_c, 10), - SadSkipMxNParam(32, 64, &vpx_highbd_sad_skip_32x64_c, 10), - SadSkipMxNParam(32, 32, &vpx_highbd_sad_skip_32x32_c, 10), - SadSkipMxNParam(32, 16, &vpx_highbd_sad_skip_32x16_c, 10), - SadSkipMxNParam(16, 32, &vpx_highbd_sad_skip_16x32_c, 10), - SadSkipMxNParam(16, 16, &vpx_highbd_sad_skip_16x16_c, 10), - SadSkipMxNParam(16, 8, &vpx_highbd_sad_skip_16x8_c, 10), - SadSkipMxNParam(8, 16, &vpx_highbd_sad_skip_8x16_c, 10), - SadSkipMxNParam(8, 8, &vpx_highbd_sad_skip_8x8_c, 10), - SadSkipMxNParam(4, 8, &vpx_highbd_sad_skip_4x8_c, 10), - SadSkipMxNParam(64, 64, &vpx_highbd_sad_skip_64x64_c, 12), - SadSkipMxNParam(64, 32, &vpx_highbd_sad_skip_64x32_c, 12), - SadSkipMxNParam(32, 64, &vpx_highbd_sad_skip_32x64_c, 12), - SadSkipMxNParam(32, 32, &vpx_highbd_sad_skip_32x32_c, 12), - SadSkipMxNParam(32, 16, &vpx_highbd_sad_skip_32x16_c, 12), - SadSkipMxNParam(16, 32, &vpx_highbd_sad_skip_16x32_c, 12), - SadSkipMxNParam(16, 16, &vpx_highbd_sad_skip_16x16_c, 12), - SadSkipMxNParam(16, 8, &vpx_highbd_sad_skip_16x8_c, 12), - SadSkipMxNParam(8, 16, &vpx_highbd_sad_skip_8x16_c, 12), - SadSkipMxNParam(8, 8, &vpx_highbd_sad_skip_8x8_c, 12), - SadSkipMxNParam(4, 8, &vpx_highbd_sad_skip_4x8_c, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(C, SADSkipTest, ::testing::ValuesIn(skip_c_tests)); - -const SadMxNAvgParam avg_c_tests[] = { - SadMxNAvgParam(64, 64, &vpx_sad64x64_avg_c), - SadMxNAvgParam(64, 32, &vpx_sad64x32_avg_c), - SadMxNAvgParam(32, 64, &vpx_sad32x64_avg_c), - SadMxNAvgParam(32, 32, &vpx_sad32x32_avg_c), - SadMxNAvgParam(32, 16, &vpx_sad32x16_avg_c), - SadMxNAvgParam(16, 32, &vpx_sad16x32_avg_c), - SadMxNAvgParam(16, 16, &vpx_sad16x16_avg_c), - SadMxNAvgParam(16, 8, &vpx_sad16x8_avg_c), - SadMxNAvgParam(8, 16, &vpx_sad8x16_avg_c), - SadMxNAvgParam(8, 8, &vpx_sad8x8_avg_c), - SadMxNAvgParam(8, 4, &vpx_sad8x4_avg_c), - SadMxNAvgParam(4, 8, &vpx_sad4x8_avg_c), - SadMxNAvgParam(4, 4, &vpx_sad4x4_avg_c), -#if CONFIG_VP9_HIGHBITDEPTH - SadMxNAvgParam(64, 64, &vpx_highbd_sad64x64_avg_c, 8), - SadMxNAvgParam(64, 32, &vpx_highbd_sad64x32_avg_c, 8), - SadMxNAvgParam(32, 64, &vpx_highbd_sad32x64_avg_c, 8), - SadMxNAvgParam(32, 32, &vpx_highbd_sad32x32_avg_c, 8), - SadMxNAvgParam(32, 16, &vpx_highbd_sad32x16_avg_c, 8), - SadMxNAvgParam(16, 32, &vpx_highbd_sad16x32_avg_c, 8), - SadMxNAvgParam(16, 16, &vpx_highbd_sad16x16_avg_c, 8), - SadMxNAvgParam(16, 8, &vpx_highbd_sad16x8_avg_c, 8), - SadMxNAvgParam(8, 16, &vpx_highbd_sad8x16_avg_c, 8), - SadMxNAvgParam(8, 8, &vpx_highbd_sad8x8_avg_c, 8), - SadMxNAvgParam(8, 4, &vpx_highbd_sad8x4_avg_c, 8), - SadMxNAvgParam(4, 8, &vpx_highbd_sad4x8_avg_c, 8), - SadMxNAvgParam(4, 4, &vpx_highbd_sad4x4_avg_c, 8), - SadMxNAvgParam(64, 64, &vpx_highbd_sad64x64_avg_c, 10), - SadMxNAvgParam(64, 32, &vpx_highbd_sad64x32_avg_c, 10), - SadMxNAvgParam(32, 64, &vpx_highbd_sad32x64_avg_c, 10), - SadMxNAvgParam(32, 32, &vpx_highbd_sad32x32_avg_c, 10), - SadMxNAvgParam(32, 16, &vpx_highbd_sad32x16_avg_c, 10), - SadMxNAvgParam(16, 32, &vpx_highbd_sad16x32_avg_c, 10), - SadMxNAvgParam(16, 16, &vpx_highbd_sad16x16_avg_c, 10), - SadMxNAvgParam(16, 8, &vpx_highbd_sad16x8_avg_c, 10), - SadMxNAvgParam(8, 16, &vpx_highbd_sad8x16_avg_c, 10), - SadMxNAvgParam(8, 8, &vpx_highbd_sad8x8_avg_c, 10), - SadMxNAvgParam(8, 4, &vpx_highbd_sad8x4_avg_c, 10), - SadMxNAvgParam(4, 8, &vpx_highbd_sad4x8_avg_c, 10), - SadMxNAvgParam(4, 4, &vpx_highbd_sad4x4_avg_c, 10), - SadMxNAvgParam(64, 64, &vpx_highbd_sad64x64_avg_c, 12), - SadMxNAvgParam(64, 32, &vpx_highbd_sad64x32_avg_c, 12), - SadMxNAvgParam(32, 64, &vpx_highbd_sad32x64_avg_c, 12), - SadMxNAvgParam(32, 32, &vpx_highbd_sad32x32_avg_c, 12), - SadMxNAvgParam(32, 16, &vpx_highbd_sad32x16_avg_c, 12), - SadMxNAvgParam(16, 32, &vpx_highbd_sad16x32_avg_c, 12), - SadMxNAvgParam(16, 16, &vpx_highbd_sad16x16_avg_c, 12), - SadMxNAvgParam(16, 8, &vpx_highbd_sad16x8_avg_c, 12), - SadMxNAvgParam(8, 16, &vpx_highbd_sad8x16_avg_c, 12), - SadMxNAvgParam(8, 8, &vpx_highbd_sad8x8_avg_c, 12), - SadMxNAvgParam(8, 4, &vpx_highbd_sad8x4_avg_c, 12), - SadMxNAvgParam(4, 8, &vpx_highbd_sad4x8_avg_c, 12), - SadMxNAvgParam(4, 4, &vpx_highbd_sad4x4_avg_c, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(C, SADavgTest, ::testing::ValuesIn(avg_c_tests)); - -const SadMxNx4Param x4d_c_tests[] = { - SadMxNx4Param(64, 64, &vpx_sad64x64x4d_c), - SadMxNx4Param(64, 32, &vpx_sad64x32x4d_c), - SadMxNx4Param(32, 64, &vpx_sad32x64x4d_c), - SadMxNx4Param(32, 32, &vpx_sad32x32x4d_c), - SadMxNx4Param(32, 16, &vpx_sad32x16x4d_c), - SadMxNx4Param(16, 32, &vpx_sad16x32x4d_c), - SadMxNx4Param(16, 16, &vpx_sad16x16x4d_c), - SadMxNx4Param(16, 8, &vpx_sad16x8x4d_c), - SadMxNx4Param(8, 16, &vpx_sad8x16x4d_c), - SadMxNx4Param(8, 8, &vpx_sad8x8x4d_c), - SadMxNx4Param(8, 4, &vpx_sad8x4x4d_c), - SadMxNx4Param(4, 8, &vpx_sad4x8x4d_c), - SadMxNx4Param(4, 4, &vpx_sad4x4x4d_c), -#if CONFIG_VP9_HIGHBITDEPTH - SadMxNx4Param(64, 64, &vpx_highbd_sad64x64x4d_c, 8), - SadMxNx4Param(64, 32, &vpx_highbd_sad64x32x4d_c, 8), - SadMxNx4Param(32, 64, &vpx_highbd_sad32x64x4d_c, 8), - SadMxNx4Param(32, 32, &vpx_highbd_sad32x32x4d_c, 8), - SadMxNx4Param(32, 16, &vpx_highbd_sad32x16x4d_c, 8), - SadMxNx4Param(16, 32, &vpx_highbd_sad16x32x4d_c, 8), - SadMxNx4Param(16, 16, &vpx_highbd_sad16x16x4d_c, 8), - SadMxNx4Param(16, 8, &vpx_highbd_sad16x8x4d_c, 8), - SadMxNx4Param(8, 16, &vpx_highbd_sad8x16x4d_c, 8), - SadMxNx4Param(8, 8, &vpx_highbd_sad8x8x4d_c, 8), - SadMxNx4Param(8, 4, &vpx_highbd_sad8x4x4d_c, 8), - SadMxNx4Param(4, 8, &vpx_highbd_sad4x8x4d_c, 8), - SadMxNx4Param(4, 4, &vpx_highbd_sad4x4x4d_c, 8), - SadMxNx4Param(64, 64, &vpx_highbd_sad64x64x4d_c, 10), - SadMxNx4Param(64, 32, &vpx_highbd_sad64x32x4d_c, 10), - SadMxNx4Param(32, 64, &vpx_highbd_sad32x64x4d_c, 10), - SadMxNx4Param(32, 32, &vpx_highbd_sad32x32x4d_c, 10), - SadMxNx4Param(32, 16, &vpx_highbd_sad32x16x4d_c, 10), - SadMxNx4Param(16, 32, &vpx_highbd_sad16x32x4d_c, 10), - SadMxNx4Param(16, 16, &vpx_highbd_sad16x16x4d_c, 10), - SadMxNx4Param(16, 8, &vpx_highbd_sad16x8x4d_c, 10), - SadMxNx4Param(8, 16, &vpx_highbd_sad8x16x4d_c, 10), - SadMxNx4Param(8, 8, &vpx_highbd_sad8x8x4d_c, 10), - SadMxNx4Param(8, 4, &vpx_highbd_sad8x4x4d_c, 10), - SadMxNx4Param(4, 8, &vpx_highbd_sad4x8x4d_c, 10), - SadMxNx4Param(4, 4, &vpx_highbd_sad4x4x4d_c, 10), - SadMxNx4Param(64, 64, &vpx_highbd_sad64x64x4d_c, 12), - SadMxNx4Param(64, 32, &vpx_highbd_sad64x32x4d_c, 12), - SadMxNx4Param(32, 64, &vpx_highbd_sad32x64x4d_c, 12), - SadMxNx4Param(32, 32, &vpx_highbd_sad32x32x4d_c, 12), - SadMxNx4Param(32, 16, &vpx_highbd_sad32x16x4d_c, 12), - SadMxNx4Param(16, 32, &vpx_highbd_sad16x32x4d_c, 12), - SadMxNx4Param(16, 16, &vpx_highbd_sad16x16x4d_c, 12), - SadMxNx4Param(16, 8, &vpx_highbd_sad16x8x4d_c, 12), - SadMxNx4Param(8, 16, &vpx_highbd_sad8x16x4d_c, 12), - SadMxNx4Param(8, 8, &vpx_highbd_sad8x8x4d_c, 12), - SadMxNx4Param(8, 4, &vpx_highbd_sad8x4x4d_c, 12), - SadMxNx4Param(4, 8, &vpx_highbd_sad4x8x4d_c, 12), - SadMxNx4Param(4, 4, &vpx_highbd_sad4x4x4d_c, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(C, SADx4Test, ::testing::ValuesIn(x4d_c_tests)); - -const SadSkipMxNx4Param skip_x4d_c_tests[] = { - SadSkipMxNx4Param(64, 64, &vpx_sad_skip_64x64x4d_c), - SadSkipMxNx4Param(64, 32, &vpx_sad_skip_64x32x4d_c), - SadSkipMxNx4Param(32, 64, &vpx_sad_skip_32x64x4d_c), - SadSkipMxNx4Param(32, 32, &vpx_sad_skip_32x32x4d_c), - SadSkipMxNx4Param(32, 16, &vpx_sad_skip_32x16x4d_c), - SadSkipMxNx4Param(16, 32, &vpx_sad_skip_16x32x4d_c), - SadSkipMxNx4Param(16, 16, &vpx_sad_skip_16x16x4d_c), - SadSkipMxNx4Param(16, 8, &vpx_sad_skip_16x8x4d_c), - SadSkipMxNx4Param(8, 16, &vpx_sad_skip_8x16x4d_c), - SadSkipMxNx4Param(8, 8, &vpx_sad_skip_8x8x4d_c), - SadSkipMxNx4Param(4, 8, &vpx_sad_skip_4x8x4d_c), -#if CONFIG_VP9_HIGHBITDEPTH - SadSkipMxNx4Param(64, 64, &vpx_highbd_sad_skip_64x64x4d_c, 8), - SadSkipMxNx4Param(64, 32, &vpx_highbd_sad_skip_64x32x4d_c, 8), - SadSkipMxNx4Param(32, 64, &vpx_highbd_sad_skip_32x64x4d_c, 8), - SadSkipMxNx4Param(32, 32, &vpx_highbd_sad_skip_32x32x4d_c, 8), - SadSkipMxNx4Param(32, 16, &vpx_highbd_sad_skip_32x16x4d_c, 8), - SadSkipMxNx4Param(16, 32, &vpx_highbd_sad_skip_16x32x4d_c, 8), - SadSkipMxNx4Param(16, 16, &vpx_highbd_sad_skip_16x16x4d_c, 8), - SadSkipMxNx4Param(16, 8, &vpx_highbd_sad_skip_16x8x4d_c, 8), - SadSkipMxNx4Param(8, 16, &vpx_highbd_sad_skip_8x16x4d_c, 8), - SadSkipMxNx4Param(8, 8, &vpx_highbd_sad_skip_8x8x4d_c, 8), - SadSkipMxNx4Param(4, 8, &vpx_highbd_sad_skip_4x8x4d_c, 8), - SadSkipMxNx4Param(64, 64, &vpx_highbd_sad_skip_64x64x4d_c, 10), - SadSkipMxNx4Param(64, 32, &vpx_highbd_sad_skip_64x32x4d_c, 10), - SadSkipMxNx4Param(32, 64, &vpx_highbd_sad_skip_32x64x4d_c, 10), - SadSkipMxNx4Param(32, 32, &vpx_highbd_sad_skip_32x32x4d_c, 10), - SadSkipMxNx4Param(32, 16, &vpx_highbd_sad_skip_32x16x4d_c, 10), - SadSkipMxNx4Param(16, 32, &vpx_highbd_sad_skip_16x32x4d_c, 10), - SadSkipMxNx4Param(16, 16, &vpx_highbd_sad_skip_16x16x4d_c, 10), - SadSkipMxNx4Param(16, 8, &vpx_highbd_sad_skip_16x8x4d_c, 10), - SadSkipMxNx4Param(8, 16, &vpx_highbd_sad_skip_8x16x4d_c, 10), - SadSkipMxNx4Param(8, 8, &vpx_highbd_sad_skip_8x8x4d_c, 10), - SadSkipMxNx4Param(4, 8, &vpx_highbd_sad_skip_4x8x4d_c, 10), - SadSkipMxNx4Param(64, 64, &vpx_highbd_sad_skip_64x64x4d_c, 12), - SadSkipMxNx4Param(64, 32, &vpx_highbd_sad_skip_64x32x4d_c, 12), - SadSkipMxNx4Param(32, 64, &vpx_highbd_sad_skip_32x64x4d_c, 12), - SadSkipMxNx4Param(32, 32, &vpx_highbd_sad_skip_32x32x4d_c, 12), - SadSkipMxNx4Param(32, 16, &vpx_highbd_sad_skip_32x16x4d_c, 12), - SadSkipMxNx4Param(16, 32, &vpx_highbd_sad_skip_16x32x4d_c, 12), - SadSkipMxNx4Param(16, 16, &vpx_highbd_sad_skip_16x16x4d_c, 12), - SadSkipMxNx4Param(16, 8, &vpx_highbd_sad_skip_16x8x4d_c, 12), - SadSkipMxNx4Param(8, 16, &vpx_highbd_sad_skip_8x16x4d_c, 12), - SadSkipMxNx4Param(8, 8, &vpx_highbd_sad_skip_8x8x4d_c, 12), - SadSkipMxNx4Param(4, 8, &vpx_highbd_sad_skip_4x8x4d_c, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(C, SADSkipx4Test, - ::testing::ValuesIn(skip_x4d_c_tests)); - -//------------------------------------------------------------------------------ -// ARM functions -#if HAVE_NEON -const SadMxNParam neon_tests[] = { - SadMxNParam(64, 64, &vpx_sad64x64_neon), - SadMxNParam(64, 32, &vpx_sad64x32_neon), - SadMxNParam(32, 32, &vpx_sad32x32_neon), - SadMxNParam(16, 32, &vpx_sad16x32_neon), - SadMxNParam(16, 16, &vpx_sad16x16_neon), - SadMxNParam(16, 8, &vpx_sad16x8_neon), - SadMxNParam(8, 16, &vpx_sad8x16_neon), - SadMxNParam(8, 8, &vpx_sad8x8_neon), - SadMxNParam(8, 4, &vpx_sad8x4_neon), - SadMxNParam(4, 8, &vpx_sad4x8_neon), - SadMxNParam(4, 4, &vpx_sad4x4_neon), -#if CONFIG_VP9_HIGHBITDEPTH - SadMxNParam(4, 4, &vpx_highbd_sad4x4_neon, 8), - SadMxNParam(4, 8, &vpx_highbd_sad4x8_neon, 8), - SadMxNParam(8, 4, &vpx_highbd_sad8x4_neon, 8), - SadMxNParam(8, 8, &vpx_highbd_sad8x8_neon, 8), - SadMxNParam(8, 16, &vpx_highbd_sad8x16_neon, 8), - SadMxNParam(16, 8, &vpx_highbd_sad16x8_neon, 8), - SadMxNParam(16, 16, &vpx_highbd_sad16x16_neon, 8), - SadMxNParam(16, 32, &vpx_highbd_sad16x32_neon, 8), - SadMxNParam(32, 32, &vpx_highbd_sad32x32_neon, 8), - SadMxNParam(32, 64, &vpx_highbd_sad32x64_neon, 8), - SadMxNParam(64, 32, &vpx_highbd_sad64x32_neon, 8), - SadMxNParam(64, 64, &vpx_highbd_sad64x64_neon, 8), - SadMxNParam(4, 4, &vpx_highbd_sad4x4_neon, 10), - SadMxNParam(4, 8, &vpx_highbd_sad4x8_neon, 10), - SadMxNParam(8, 4, &vpx_highbd_sad8x4_neon, 10), - SadMxNParam(8, 8, &vpx_highbd_sad8x8_neon, 10), - SadMxNParam(8, 16, &vpx_highbd_sad8x16_neon, 10), - SadMxNParam(16, 8, &vpx_highbd_sad16x8_neon, 10), - SadMxNParam(16, 16, &vpx_highbd_sad16x16_neon, 10), - SadMxNParam(16, 32, &vpx_highbd_sad16x32_neon, 10), - SadMxNParam(32, 32, &vpx_highbd_sad32x32_neon, 10), - SadMxNParam(32, 64, &vpx_highbd_sad32x64_neon, 10), - SadMxNParam(64, 32, &vpx_highbd_sad64x32_neon, 10), - SadMxNParam(64, 64, &vpx_highbd_sad64x64_neon, 10), - SadMxNParam(4, 4, &vpx_highbd_sad4x4_neon, 12), - SadMxNParam(4, 8, &vpx_highbd_sad4x8_neon, 12), - SadMxNParam(8, 4, &vpx_highbd_sad8x4_neon, 12), - SadMxNParam(8, 8, &vpx_highbd_sad8x8_neon, 12), - SadMxNParam(8, 16, &vpx_highbd_sad8x16_neon, 12), - SadMxNParam(16, 8, &vpx_highbd_sad16x8_neon, 12), - SadMxNParam(16, 16, &vpx_highbd_sad16x16_neon, 12), - SadMxNParam(16, 32, &vpx_highbd_sad16x32_neon, 12), - SadMxNParam(32, 32, &vpx_highbd_sad32x32_neon, 12), - SadMxNParam(32, 64, &vpx_highbd_sad32x64_neon, 12), - SadMxNParam(64, 32, &vpx_highbd_sad64x32_neon, 12), - SadMxNParam(64, 64, &vpx_highbd_sad64x64_neon, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH - -}; -INSTANTIATE_TEST_SUITE_P(NEON, SADTest, ::testing::ValuesIn(neon_tests)); - -#if HAVE_NEON_DOTPROD -const SadMxNParam neon_dotprod_tests[] = { - SadMxNParam(64, 64, &vpx_sad64x64_neon_dotprod), - SadMxNParam(64, 32, &vpx_sad64x32_neon_dotprod), - SadMxNParam(32, 64, &vpx_sad32x64_neon_dotprod), - SadMxNParam(32, 32, &vpx_sad32x32_neon_dotprod), - SadMxNParam(32, 16, &vpx_sad32x16_neon_dotprod), - SadMxNParam(16, 32, &vpx_sad16x32_neon_dotprod), - SadMxNParam(16, 16, &vpx_sad16x16_neon_dotprod), - SadMxNParam(16, 8, &vpx_sad16x8_neon_dotprod), -}; -INSTANTIATE_TEST_SUITE_P(NEON_DOTPROD, SADTest, - ::testing::ValuesIn(neon_dotprod_tests)); -#endif // HAVE_NEON_DOTPROD - -const SadSkipMxNParam skip_neon_tests[] = { - SadSkipMxNParam(64, 64, &vpx_sad_skip_64x64_neon), - SadSkipMxNParam(64, 32, &vpx_sad_skip_64x32_neon), - SadSkipMxNParam(32, 64, &vpx_sad_skip_32x64_neon), - SadSkipMxNParam(32, 32, &vpx_sad_skip_32x32_neon), - SadSkipMxNParam(32, 16, &vpx_sad_skip_32x16_neon), - SadSkipMxNParam(16, 32, &vpx_sad_skip_16x32_neon), - SadSkipMxNParam(16, 16, &vpx_sad_skip_16x16_neon), - SadSkipMxNParam(16, 8, &vpx_sad_skip_16x8_neon), - SadSkipMxNParam(8, 16, &vpx_sad_skip_8x16_neon), - SadSkipMxNParam(8, 8, &vpx_sad_skip_8x8_neon), - SadSkipMxNParam(8, 4, &vpx_sad_skip_8x4_neon), - SadSkipMxNParam(4, 8, &vpx_sad_skip_4x8_neon), - SadSkipMxNParam(4, 4, &vpx_sad_skip_4x4_neon), -#if CONFIG_VP9_HIGHBITDEPTH - SadSkipMxNParam(4, 4, &vpx_highbd_sad_skip_4x4_neon, 8), - SadSkipMxNParam(4, 8, &vpx_highbd_sad_skip_4x8_neon, 8), - SadSkipMxNParam(8, 4, &vpx_highbd_sad_skip_8x4_neon, 8), - SadSkipMxNParam(8, 8, &vpx_highbd_sad_skip_8x8_neon, 8), - SadSkipMxNParam(8, 16, &vpx_highbd_sad_skip_8x16_neon, 8), - SadSkipMxNParam(16, 8, &vpx_highbd_sad_skip_16x8_neon, 8), - SadSkipMxNParam(16, 16, &vpx_highbd_sad_skip_16x16_neon, 8), - SadSkipMxNParam(16, 32, &vpx_highbd_sad_skip_16x32_neon, 8), - SadSkipMxNParam(32, 16, &vpx_highbd_sad_skip_32x16_neon, 8), - SadSkipMxNParam(32, 32, &vpx_highbd_sad_skip_32x32_neon, 8), - SadSkipMxNParam(32, 64, &vpx_highbd_sad_skip_32x64_neon, 8), - SadSkipMxNParam(64, 32, &vpx_highbd_sad_skip_64x32_neon, 8), - SadSkipMxNParam(64, 64, &vpx_highbd_sad_skip_64x64_neon, 8), - SadSkipMxNParam(4, 4, &vpx_highbd_sad_skip_4x4_neon, 10), - SadSkipMxNParam(4, 8, &vpx_highbd_sad_skip_4x8_neon, 10), - SadSkipMxNParam(8, 4, &vpx_highbd_sad_skip_8x4_neon, 10), - SadSkipMxNParam(8, 8, &vpx_highbd_sad_skip_8x8_neon, 10), - SadSkipMxNParam(8, 16, &vpx_highbd_sad_skip_8x16_neon, 10), - SadSkipMxNParam(16, 8, &vpx_highbd_sad_skip_16x8_neon, 10), - SadSkipMxNParam(16, 16, &vpx_highbd_sad_skip_16x16_neon, 10), - SadSkipMxNParam(16, 32, &vpx_highbd_sad_skip_16x32_neon, 10), - SadSkipMxNParam(32, 16, &vpx_highbd_sad_skip_32x16_neon, 10), - SadSkipMxNParam(32, 32, &vpx_highbd_sad_skip_32x32_neon, 10), - SadSkipMxNParam(32, 64, &vpx_highbd_sad_skip_32x64_neon, 10), - SadSkipMxNParam(64, 32, &vpx_highbd_sad_skip_64x32_neon, 10), - SadSkipMxNParam(64, 64, &vpx_highbd_sad_skip_64x64_neon, 10), - SadSkipMxNParam(4, 4, &vpx_highbd_sad_skip_4x4_neon, 12), - SadSkipMxNParam(4, 8, &vpx_highbd_sad_skip_4x8_neon, 12), - SadSkipMxNParam(8, 4, &vpx_highbd_sad_skip_8x4_neon, 12), - SadSkipMxNParam(8, 8, &vpx_highbd_sad_skip_8x8_neon, 12), - SadSkipMxNParam(8, 16, &vpx_highbd_sad_skip_8x16_neon, 12), - SadSkipMxNParam(16, 8, &vpx_highbd_sad_skip_16x8_neon, 12), - SadSkipMxNParam(16, 16, &vpx_highbd_sad_skip_16x16_neon, 12), - SadSkipMxNParam(16, 32, &vpx_highbd_sad_skip_16x32_neon, 12), - SadSkipMxNParam(32, 16, &vpx_highbd_sad_skip_32x16_neon, 12), - SadSkipMxNParam(32, 32, &vpx_highbd_sad_skip_32x32_neon, 12), - SadSkipMxNParam(32, 64, &vpx_highbd_sad_skip_32x64_neon, 12), - SadSkipMxNParam(64, 32, &vpx_highbd_sad_skip_64x32_neon, 12), - SadSkipMxNParam(64, 64, &vpx_highbd_sad_skip_64x64_neon, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(NEON, SADSkipTest, - ::testing::ValuesIn(skip_neon_tests)); - -#if HAVE_NEON_DOTPROD -const SadSkipMxNParam skip_neon_dotprod_tests[] = { - SadSkipMxNParam(64, 64, &vpx_sad_skip_64x64_neon_dotprod), - SadSkipMxNParam(64, 32, &vpx_sad_skip_64x32_neon_dotprod), - SadSkipMxNParam(32, 64, &vpx_sad_skip_32x64_neon_dotprod), - SadSkipMxNParam(32, 32, &vpx_sad_skip_32x32_neon_dotprod), - SadSkipMxNParam(32, 16, &vpx_sad_skip_32x16_neon_dotprod), - SadSkipMxNParam(16, 32, &vpx_sad_skip_16x32_neon_dotprod), - SadSkipMxNParam(16, 16, &vpx_sad_skip_16x16_neon_dotprod), - SadSkipMxNParam(16, 8, &vpx_sad_skip_16x8_neon_dotprod), -}; -INSTANTIATE_TEST_SUITE_P(NEON_DOTPROD, SADSkipTest, - ::testing::ValuesIn(skip_neon_dotprod_tests)); -#endif // HAVE_NEON_DOTPROD - -const SadMxNAvgParam avg_neon_tests[] = { - SadMxNAvgParam(64, 64, &vpx_sad64x64_avg_neon), - SadMxNAvgParam(64, 32, &vpx_sad64x32_avg_neon), - SadMxNAvgParam(32, 64, &vpx_sad32x64_avg_neon), - SadMxNAvgParam(32, 32, &vpx_sad32x32_avg_neon), - SadMxNAvgParam(32, 16, &vpx_sad32x16_avg_neon), - SadMxNAvgParam(16, 32, &vpx_sad16x32_avg_neon), - SadMxNAvgParam(16, 16, &vpx_sad16x16_avg_neon), - SadMxNAvgParam(16, 8, &vpx_sad16x8_avg_neon), - SadMxNAvgParam(8, 16, &vpx_sad8x16_avg_neon), - SadMxNAvgParam(8, 8, &vpx_sad8x8_avg_neon), - SadMxNAvgParam(8, 4, &vpx_sad8x4_avg_neon), - SadMxNAvgParam(4, 8, &vpx_sad4x8_avg_neon), - SadMxNAvgParam(4, 4, &vpx_sad4x4_avg_neon), -#if CONFIG_VP9_HIGHBITDEPTH - SadMxNAvgParam(4, 4, &vpx_highbd_sad4x4_avg_neon, 8), - SadMxNAvgParam(4, 8, &vpx_highbd_sad4x8_avg_neon, 8), - SadMxNAvgParam(8, 4, &vpx_highbd_sad8x4_avg_neon, 8), - SadMxNAvgParam(8, 8, &vpx_highbd_sad8x8_avg_neon, 8), - SadMxNAvgParam(8, 16, &vpx_highbd_sad8x16_avg_neon, 8), - SadMxNAvgParam(16, 8, &vpx_highbd_sad16x8_avg_neon, 8), - SadMxNAvgParam(16, 16, &vpx_highbd_sad16x16_avg_neon, 8), - SadMxNAvgParam(16, 32, &vpx_highbd_sad16x32_avg_neon, 8), - SadMxNAvgParam(32, 16, &vpx_highbd_sad32x16_avg_neon, 8), - SadMxNAvgParam(32, 32, &vpx_highbd_sad32x32_avg_neon, 8), - SadMxNAvgParam(32, 64, &vpx_highbd_sad32x64_avg_neon, 8), - SadMxNAvgParam(64, 32, &vpx_highbd_sad64x32_avg_neon, 8), - SadMxNAvgParam(64, 64, &vpx_highbd_sad64x64_avg_neon, 8), - SadMxNAvgParam(4, 4, &vpx_highbd_sad4x4_avg_neon, 10), - SadMxNAvgParam(4, 8, &vpx_highbd_sad4x8_avg_neon, 10), - SadMxNAvgParam(8, 4, &vpx_highbd_sad8x4_avg_neon, 10), - SadMxNAvgParam(8, 8, &vpx_highbd_sad8x8_avg_neon, 10), - SadMxNAvgParam(8, 16, &vpx_highbd_sad8x16_avg_neon, 10), - SadMxNAvgParam(16, 8, &vpx_highbd_sad16x8_avg_neon, 10), - SadMxNAvgParam(16, 16, &vpx_highbd_sad16x16_avg_neon, 10), - SadMxNAvgParam(16, 32, &vpx_highbd_sad16x32_avg_neon, 10), - SadMxNAvgParam(32, 16, &vpx_highbd_sad32x16_avg_neon, 10), - SadMxNAvgParam(32, 32, &vpx_highbd_sad32x32_avg_neon, 10), - SadMxNAvgParam(32, 64, &vpx_highbd_sad32x64_avg_neon, 10), - SadMxNAvgParam(64, 32, &vpx_highbd_sad64x32_avg_neon, 10), - SadMxNAvgParam(64, 64, &vpx_highbd_sad64x64_avg_neon, 10), - SadMxNAvgParam(4, 4, &vpx_highbd_sad4x4_avg_neon, 12), - SadMxNAvgParam(4, 8, &vpx_highbd_sad4x8_avg_neon, 12), - SadMxNAvgParam(8, 4, &vpx_highbd_sad8x4_avg_neon, 12), - SadMxNAvgParam(8, 8, &vpx_highbd_sad8x8_avg_neon, 12), - SadMxNAvgParam(8, 16, &vpx_highbd_sad8x16_avg_neon, 12), - SadMxNAvgParam(16, 8, &vpx_highbd_sad16x8_avg_neon, 12), - SadMxNAvgParam(16, 16, &vpx_highbd_sad16x16_avg_neon, 12), - SadMxNAvgParam(16, 32, &vpx_highbd_sad16x32_avg_neon, 12), - SadMxNAvgParam(32, 16, &vpx_highbd_sad32x16_avg_neon, 12), - SadMxNAvgParam(32, 32, &vpx_highbd_sad32x32_avg_neon, 12), - SadMxNAvgParam(32, 64, &vpx_highbd_sad32x64_avg_neon, 12), - SadMxNAvgParam(64, 32, &vpx_highbd_sad64x32_avg_neon, 12), - SadMxNAvgParam(64, 64, &vpx_highbd_sad64x64_avg_neon, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(NEON, SADavgTest, ::testing::ValuesIn(avg_neon_tests)); - -#if HAVE_NEON_DOTPROD -const SadMxNAvgParam avg_neon_dotprod_tests[] = { - SadMxNAvgParam(64, 64, &vpx_sad64x64_avg_neon_dotprod), - SadMxNAvgParam(64, 32, &vpx_sad64x32_avg_neon_dotprod), - SadMxNAvgParam(32, 64, &vpx_sad32x64_avg_neon_dotprod), - SadMxNAvgParam(32, 32, &vpx_sad32x32_avg_neon_dotprod), - SadMxNAvgParam(32, 16, &vpx_sad32x16_avg_neon_dotprod), - SadMxNAvgParam(16, 32, &vpx_sad16x32_avg_neon_dotprod), - SadMxNAvgParam(16, 16, &vpx_sad16x16_avg_neon_dotprod), - SadMxNAvgParam(16, 8, &vpx_sad16x8_avg_neon_dotprod), -}; -INSTANTIATE_TEST_SUITE_P(NEON_DOTPROD, SADavgTest, - ::testing::ValuesIn(avg_neon_dotprod_tests)); -#endif // HAVE_NEON_DOTPROD - -const SadMxNx4Param x4d_neon_tests[] = { - SadMxNx4Param(64, 64, &vpx_sad64x64x4d_neon), - SadMxNx4Param(64, 32, &vpx_sad64x32x4d_neon), - SadMxNx4Param(32, 64, &vpx_sad32x64x4d_neon), - SadMxNx4Param(32, 32, &vpx_sad32x32x4d_neon), - SadMxNx4Param(32, 16, &vpx_sad32x16x4d_neon), - SadMxNx4Param(16, 32, &vpx_sad16x32x4d_neon), - SadMxNx4Param(16, 16, &vpx_sad16x16x4d_neon), - SadMxNx4Param(16, 8, &vpx_sad16x8x4d_neon), - SadMxNx4Param(8, 16, &vpx_sad8x16x4d_neon), - SadMxNx4Param(8, 8, &vpx_sad8x8x4d_neon), - SadMxNx4Param(8, 4, &vpx_sad8x4x4d_neon), - SadMxNx4Param(4, 8, &vpx_sad4x8x4d_neon), - SadMxNx4Param(4, 4, &vpx_sad4x4x4d_neon), -#if CONFIG_VP9_HIGHBITDEPTH - SadMxNx4Param(4, 4, &vpx_highbd_sad4x4x4d_neon, 8), - SadMxNx4Param(4, 8, &vpx_highbd_sad4x8x4d_neon, 8), - SadMxNx4Param(8, 4, &vpx_highbd_sad8x4x4d_neon, 8), - SadMxNx4Param(8, 8, &vpx_highbd_sad8x8x4d_neon, 8), - SadMxNx4Param(8, 16, &vpx_highbd_sad8x16x4d_neon, 8), - SadMxNx4Param(16, 8, &vpx_highbd_sad16x8x4d_neon, 8), - SadMxNx4Param(16, 16, &vpx_highbd_sad16x16x4d_neon, 8), - SadMxNx4Param(16, 32, &vpx_highbd_sad16x32x4d_neon, 8), - SadMxNx4Param(32, 32, &vpx_highbd_sad32x32x4d_neon, 8), - SadMxNx4Param(32, 64, &vpx_highbd_sad32x64x4d_neon, 8), - SadMxNx4Param(64, 32, &vpx_highbd_sad64x32x4d_neon, 8), - SadMxNx4Param(64, 64, &vpx_highbd_sad64x64x4d_neon, 8), - SadMxNx4Param(4, 4, &vpx_highbd_sad4x4x4d_neon, 10), - SadMxNx4Param(4, 8, &vpx_highbd_sad4x8x4d_neon, 10), - SadMxNx4Param(8, 4, &vpx_highbd_sad8x4x4d_neon, 10), - SadMxNx4Param(8, 8, &vpx_highbd_sad8x8x4d_neon, 10), - SadMxNx4Param(8, 16, &vpx_highbd_sad8x16x4d_neon, 10), - SadMxNx4Param(16, 8, &vpx_highbd_sad16x8x4d_neon, 10), - SadMxNx4Param(16, 16, &vpx_highbd_sad16x16x4d_neon, 10), - SadMxNx4Param(16, 32, &vpx_highbd_sad16x32x4d_neon, 10), - SadMxNx4Param(32, 32, &vpx_highbd_sad32x32x4d_neon, 10), - SadMxNx4Param(32, 64, &vpx_highbd_sad32x64x4d_neon, 10), - SadMxNx4Param(64, 32, &vpx_highbd_sad64x32x4d_neon, 10), - SadMxNx4Param(64, 64, &vpx_highbd_sad64x64x4d_neon, 10), - SadMxNx4Param(4, 4, &vpx_highbd_sad4x4x4d_neon, 12), - SadMxNx4Param(4, 8, &vpx_highbd_sad4x8x4d_neon, 12), - SadMxNx4Param(8, 4, &vpx_highbd_sad8x4x4d_neon, 12), - SadMxNx4Param(8, 8, &vpx_highbd_sad8x8x4d_neon, 12), - SadMxNx4Param(8, 16, &vpx_highbd_sad8x16x4d_neon, 12), - SadMxNx4Param(16, 8, &vpx_highbd_sad16x8x4d_neon, 12), - SadMxNx4Param(16, 16, &vpx_highbd_sad16x16x4d_neon, 12), - SadMxNx4Param(16, 32, &vpx_highbd_sad16x32x4d_neon, 12), - SadMxNx4Param(32, 32, &vpx_highbd_sad32x32x4d_neon, 12), - SadMxNx4Param(32, 64, &vpx_highbd_sad32x64x4d_neon, 12), - SadMxNx4Param(64, 32, &vpx_highbd_sad64x32x4d_neon, 12), - SadMxNx4Param(64, 64, &vpx_highbd_sad64x64x4d_neon, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(NEON, SADx4Test, ::testing::ValuesIn(x4d_neon_tests)); - -#if HAVE_NEON_DOTPROD -const SadMxNx4Param x4d_neon_dotprod_tests[] = { - SadMxNx4Param(64, 64, &vpx_sad64x64x4d_neon_dotprod), - SadMxNx4Param(64, 32, &vpx_sad64x32x4d_neon_dotprod), - SadMxNx4Param(32, 64, &vpx_sad32x64x4d_neon_dotprod), - SadMxNx4Param(32, 32, &vpx_sad32x32x4d_neon_dotprod), - SadMxNx4Param(32, 16, &vpx_sad32x16x4d_neon_dotprod), - SadMxNx4Param(16, 32, &vpx_sad16x32x4d_neon_dotprod), - SadMxNx4Param(16, 16, &vpx_sad16x16x4d_neon_dotprod), - SadMxNx4Param(16, 8, &vpx_sad16x8x4d_neon_dotprod), -}; -INSTANTIATE_TEST_SUITE_P(NEON_DOTPROD, SADx4Test, - ::testing::ValuesIn(x4d_neon_dotprod_tests)); -#endif // HAVE_NEON_DOTPROD - -const SadSkipMxNx4Param skip_x4d_neon_tests[] = { - SadSkipMxNx4Param(64, 64, &vpx_sad_skip_64x64x4d_neon), - SadSkipMxNx4Param(64, 32, &vpx_sad_skip_64x32x4d_neon), - SadSkipMxNx4Param(32, 64, &vpx_sad_skip_32x64x4d_neon), - SadSkipMxNx4Param(32, 32, &vpx_sad_skip_32x32x4d_neon), - SadSkipMxNx4Param(32, 16, &vpx_sad_skip_32x16x4d_neon), - SadSkipMxNx4Param(16, 32, &vpx_sad_skip_16x32x4d_neon), - SadSkipMxNx4Param(16, 16, &vpx_sad_skip_16x16x4d_neon), - SadSkipMxNx4Param(16, 8, &vpx_sad_skip_16x8x4d_neon), - SadSkipMxNx4Param(8, 16, &vpx_sad_skip_8x16x4d_neon), - SadSkipMxNx4Param(8, 8, &vpx_sad_skip_8x8x4d_neon), - SadSkipMxNx4Param(8, 4, &vpx_sad_skip_8x4x4d_neon), - SadSkipMxNx4Param(4, 8, &vpx_sad_skip_4x8x4d_neon), - SadSkipMxNx4Param(4, 4, &vpx_sad_skip_4x4x4d_neon), -#if CONFIG_VP9_HIGHBITDEPTH - SadSkipMxNx4Param(4, 4, &vpx_highbd_sad_skip_4x4x4d_neon, 8), - SadSkipMxNx4Param(4, 8, &vpx_highbd_sad_skip_4x8x4d_neon, 8), - SadSkipMxNx4Param(8, 4, &vpx_highbd_sad_skip_8x4x4d_neon, 8), - SadSkipMxNx4Param(8, 8, &vpx_highbd_sad_skip_8x8x4d_neon, 8), - SadSkipMxNx4Param(8, 16, &vpx_highbd_sad_skip_8x16x4d_neon, 8), - SadSkipMxNx4Param(16, 8, &vpx_highbd_sad_skip_16x8x4d_neon, 8), - SadSkipMxNx4Param(16, 16, &vpx_highbd_sad_skip_16x16x4d_neon, 8), - SadSkipMxNx4Param(16, 32, &vpx_highbd_sad_skip_16x32x4d_neon, 8), - SadSkipMxNx4Param(32, 32, &vpx_highbd_sad_skip_32x32x4d_neon, 8), - SadSkipMxNx4Param(32, 64, &vpx_highbd_sad_skip_32x64x4d_neon, 8), - SadSkipMxNx4Param(64, 32, &vpx_highbd_sad_skip_64x32x4d_neon, 8), - SadSkipMxNx4Param(64, 64, &vpx_highbd_sad_skip_64x64x4d_neon, 8), - SadSkipMxNx4Param(4, 4, &vpx_highbd_sad_skip_4x4x4d_neon, 10), - SadSkipMxNx4Param(4, 8, &vpx_highbd_sad_skip_4x8x4d_neon, 10), - SadSkipMxNx4Param(8, 4, &vpx_highbd_sad_skip_8x4x4d_neon, 10), - SadSkipMxNx4Param(8, 8, &vpx_highbd_sad_skip_8x8x4d_neon, 10), - SadSkipMxNx4Param(8, 16, &vpx_highbd_sad_skip_8x16x4d_neon, 10), - SadSkipMxNx4Param(16, 8, &vpx_highbd_sad_skip_16x8x4d_neon, 10), - SadSkipMxNx4Param(16, 16, &vpx_highbd_sad_skip_16x16x4d_neon, 10), - SadSkipMxNx4Param(16, 32, &vpx_highbd_sad_skip_16x32x4d_neon, 10), - SadSkipMxNx4Param(32, 32, &vpx_highbd_sad_skip_32x32x4d_neon, 10), - SadSkipMxNx4Param(32, 64, &vpx_highbd_sad_skip_32x64x4d_neon, 10), - SadSkipMxNx4Param(64, 32, &vpx_highbd_sad_skip_64x32x4d_neon, 10), - SadSkipMxNx4Param(64, 64, &vpx_highbd_sad_skip_64x64x4d_neon, 10), - SadSkipMxNx4Param(4, 4, &vpx_highbd_sad_skip_4x4x4d_neon, 12), - SadSkipMxNx4Param(4, 8, &vpx_highbd_sad_skip_4x8x4d_neon, 12), - SadSkipMxNx4Param(8, 4, &vpx_highbd_sad_skip_8x4x4d_neon, 12), - SadSkipMxNx4Param(8, 8, &vpx_highbd_sad_skip_8x8x4d_neon, 12), - SadSkipMxNx4Param(8, 16, &vpx_highbd_sad_skip_8x16x4d_neon, 12), - SadSkipMxNx4Param(16, 8, &vpx_highbd_sad_skip_16x8x4d_neon, 12), - SadSkipMxNx4Param(16, 16, &vpx_highbd_sad_skip_16x16x4d_neon, 12), - SadSkipMxNx4Param(16, 32, &vpx_highbd_sad_skip_16x32x4d_neon, 12), - SadSkipMxNx4Param(32, 32, &vpx_highbd_sad_skip_32x32x4d_neon, 12), - SadSkipMxNx4Param(32, 64, &vpx_highbd_sad_skip_32x64x4d_neon, 12), - SadSkipMxNx4Param(64, 32, &vpx_highbd_sad_skip_64x32x4d_neon, 12), - SadSkipMxNx4Param(64, 64, &vpx_highbd_sad_skip_64x64x4d_neon, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(NEON, SADSkipx4Test, - ::testing::ValuesIn(skip_x4d_neon_tests)); - -#if HAVE_NEONE_DOTPROD -const SadSkipMxNx4Param skip_x4d_neon_dotprod_tests[] = { - SadSkipMxNx4Param(64, 64, &vpx_sad_skip_64x64x4d_neon_dotprod), - SadSkipMxNx4Param(64, 32, &vpx_sad_skip_64x32x4d_neon_dotprod), - SadSkipMxNx4Param(32, 64, &vpx_sad_skip_32x64x4d_neon_dotprod), - SadSkipMxNx4Param(32, 32, &vpx_sad_skip_32x32x4d_neon_dotprod), - SadSkipMxNx4Param(32, 16, &vpx_sad_skip_32x16x4d_neon_dotprod), - SadSkipMxNx4Param(16, 32, &vpx_sad_skip_16x32x4d_neon_dotprod), - SadSkipMxNx4Param(16, 16, &vpx_sad_skip_16x16x4d_neon_dotprod), - SadSkipMxNx4Param(16, 8, &vpx_sad_skip_16x8x4d_neon_dotprod), -}; -INSTANTIATE_TEST_SUITE_P(NEON_DOTPROD, SADSkipx4Test, - ::testing::ValuesIn(skip_x4d_neon_dotprod_tests)); -#endif // HAVE_NEON_DOTPROD -#endif // HAVE_NEON - -//------------------------------------------------------------------------------ -// x86 functions -#if HAVE_SSE2 -const SadMxNParam sse2_tests[] = { - SadMxNParam(64, 64, &vpx_sad64x64_sse2), - SadMxNParam(64, 32, &vpx_sad64x32_sse2), - SadMxNParam(32, 64, &vpx_sad32x64_sse2), - SadMxNParam(32, 32, &vpx_sad32x32_sse2), - SadMxNParam(32, 16, &vpx_sad32x16_sse2), - SadMxNParam(16, 32, &vpx_sad16x32_sse2), - SadMxNParam(16, 16, &vpx_sad16x16_sse2), - SadMxNParam(16, 8, &vpx_sad16x8_sse2), - SadMxNParam(8, 16, &vpx_sad8x16_sse2), - SadMxNParam(8, 8, &vpx_sad8x8_sse2), - SadMxNParam(8, 4, &vpx_sad8x4_sse2), - SadMxNParam(4, 8, &vpx_sad4x8_sse2), - SadMxNParam(4, 4, &vpx_sad4x4_sse2), -#if CONFIG_VP9_HIGHBITDEPTH - SadMxNParam(64, 64, &vpx_highbd_sad64x64_sse2, 8), - SadMxNParam(64, 32, &vpx_highbd_sad64x32_sse2, 8), - SadMxNParam(32, 64, &vpx_highbd_sad32x64_sse2, 8), - SadMxNParam(32, 32, &vpx_highbd_sad32x32_sse2, 8), - SadMxNParam(32, 16, &vpx_highbd_sad32x16_sse2, 8), - SadMxNParam(16, 32, &vpx_highbd_sad16x32_sse2, 8), - SadMxNParam(16, 16, &vpx_highbd_sad16x16_sse2, 8), - SadMxNParam(16, 8, &vpx_highbd_sad16x8_sse2, 8), - SadMxNParam(8, 16, &vpx_highbd_sad8x16_sse2, 8), - SadMxNParam(8, 8, &vpx_highbd_sad8x8_sse2, 8), - SadMxNParam(8, 4, &vpx_highbd_sad8x4_sse2, 8), - SadMxNParam(64, 64, &vpx_highbd_sad64x64_sse2, 10), - SadMxNParam(64, 32, &vpx_highbd_sad64x32_sse2, 10), - SadMxNParam(32, 64, &vpx_highbd_sad32x64_sse2, 10), - SadMxNParam(32, 32, &vpx_highbd_sad32x32_sse2, 10), - SadMxNParam(32, 16, &vpx_highbd_sad32x16_sse2, 10), - SadMxNParam(16, 32, &vpx_highbd_sad16x32_sse2, 10), - SadMxNParam(16, 16, &vpx_highbd_sad16x16_sse2, 10), - SadMxNParam(16, 8, &vpx_highbd_sad16x8_sse2, 10), - SadMxNParam(8, 16, &vpx_highbd_sad8x16_sse2, 10), - SadMxNParam(8, 8, &vpx_highbd_sad8x8_sse2, 10), - SadMxNParam(8, 4, &vpx_highbd_sad8x4_sse2, 10), - SadMxNParam(64, 64, &vpx_highbd_sad64x64_sse2, 12), - SadMxNParam(64, 32, &vpx_highbd_sad64x32_sse2, 12), - SadMxNParam(32, 64, &vpx_highbd_sad32x64_sse2, 12), - SadMxNParam(32, 32, &vpx_highbd_sad32x32_sse2, 12), - SadMxNParam(32, 16, &vpx_highbd_sad32x16_sse2, 12), - SadMxNParam(16, 32, &vpx_highbd_sad16x32_sse2, 12), - SadMxNParam(16, 16, &vpx_highbd_sad16x16_sse2, 12), - SadMxNParam(16, 8, &vpx_highbd_sad16x8_sse2, 12), - SadMxNParam(8, 16, &vpx_highbd_sad8x16_sse2, 12), - SadMxNParam(8, 8, &vpx_highbd_sad8x8_sse2, 12), - SadMxNParam(8, 4, &vpx_highbd_sad8x4_sse2, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(SSE2, SADTest, ::testing::ValuesIn(sse2_tests)); - -const SadSkipMxNParam skip_sse2_tests[] = { - SadSkipMxNParam(64, 64, &vpx_sad_skip_64x64_sse2), - SadSkipMxNParam(64, 32, &vpx_sad_skip_64x32_sse2), - SadSkipMxNParam(32, 64, &vpx_sad_skip_32x64_sse2), - SadSkipMxNParam(32, 32, &vpx_sad_skip_32x32_sse2), - SadSkipMxNParam(32, 16, &vpx_sad_skip_32x16_sse2), - SadSkipMxNParam(16, 32, &vpx_sad_skip_16x32_sse2), - SadSkipMxNParam(16, 16, &vpx_sad_skip_16x16_sse2), - SadSkipMxNParam(16, 8, &vpx_sad_skip_16x8_sse2), - SadSkipMxNParam(8, 16, &vpx_sad_skip_8x16_sse2), - SadSkipMxNParam(8, 8, &vpx_sad_skip_8x8_sse2), - SadSkipMxNParam(4, 8, &vpx_sad_skip_4x8_sse2), -#if CONFIG_VP9_HIGHBITDEPTH - SadSkipMxNParam(64, 64, &vpx_highbd_sad_skip_64x64_sse2, 8), - SadSkipMxNParam(64, 32, &vpx_highbd_sad_skip_64x32_sse2, 8), - SadSkipMxNParam(32, 64, &vpx_highbd_sad_skip_32x64_sse2, 8), - SadSkipMxNParam(32, 32, &vpx_highbd_sad_skip_32x32_sse2, 8), - SadSkipMxNParam(32, 16, &vpx_highbd_sad_skip_32x16_sse2, 8), - SadSkipMxNParam(16, 32, &vpx_highbd_sad_skip_16x32_sse2, 8), - SadSkipMxNParam(16, 16, &vpx_highbd_sad_skip_16x16_sse2, 8), - SadSkipMxNParam(16, 8, &vpx_highbd_sad_skip_16x8_sse2, 8), - SadSkipMxNParam(8, 16, &vpx_highbd_sad_skip_8x16_sse2, 8), - SadSkipMxNParam(8, 8, &vpx_highbd_sad_skip_8x8_sse2, 8), - SadSkipMxNParam(64, 64, &vpx_highbd_sad_skip_64x64_sse2, 10), - SadSkipMxNParam(64, 32, &vpx_highbd_sad_skip_64x32_sse2, 10), - SadSkipMxNParam(32, 64, &vpx_highbd_sad_skip_32x64_sse2, 10), - SadSkipMxNParam(32, 32, &vpx_highbd_sad_skip_32x32_sse2, 10), - SadSkipMxNParam(32, 16, &vpx_highbd_sad_skip_32x16_sse2, 10), - SadSkipMxNParam(16, 32, &vpx_highbd_sad_skip_16x32_sse2, 10), - SadSkipMxNParam(16, 16, &vpx_highbd_sad_skip_16x16_sse2, 10), - SadSkipMxNParam(16, 8, &vpx_highbd_sad_skip_16x8_sse2, 10), - SadSkipMxNParam(8, 16, &vpx_highbd_sad_skip_8x16_sse2, 10), - SadSkipMxNParam(8, 8, &vpx_highbd_sad_skip_8x8_sse2, 10), - SadSkipMxNParam(64, 64, &vpx_highbd_sad_skip_64x64_sse2, 12), - SadSkipMxNParam(64, 32, &vpx_highbd_sad_skip_64x32_sse2, 12), - SadSkipMxNParam(32, 64, &vpx_highbd_sad_skip_32x64_sse2, 12), - SadSkipMxNParam(32, 32, &vpx_highbd_sad_skip_32x32_sse2, 12), - SadSkipMxNParam(32, 16, &vpx_highbd_sad_skip_32x16_sse2, 12), - SadSkipMxNParam(16, 32, &vpx_highbd_sad_skip_16x32_sse2, 12), - SadSkipMxNParam(16, 16, &vpx_highbd_sad_skip_16x16_sse2, 12), - SadSkipMxNParam(16, 8, &vpx_highbd_sad_skip_16x8_sse2, 12), - SadSkipMxNParam(8, 16, &vpx_highbd_sad_skip_8x16_sse2, 12), - SadSkipMxNParam(8, 8, &vpx_highbd_sad_skip_8x8_sse2, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(SSE2, SADSkipTest, - ::testing::ValuesIn(skip_sse2_tests)); - -const SadMxNAvgParam avg_sse2_tests[] = { - SadMxNAvgParam(64, 64, &vpx_sad64x64_avg_sse2), - SadMxNAvgParam(64, 32, &vpx_sad64x32_avg_sse2), - SadMxNAvgParam(32, 64, &vpx_sad32x64_avg_sse2), - SadMxNAvgParam(32, 32, &vpx_sad32x32_avg_sse2), - SadMxNAvgParam(32, 16, &vpx_sad32x16_avg_sse2), - SadMxNAvgParam(16, 32, &vpx_sad16x32_avg_sse2), - SadMxNAvgParam(16, 16, &vpx_sad16x16_avg_sse2), - SadMxNAvgParam(16, 8, &vpx_sad16x8_avg_sse2), - SadMxNAvgParam(8, 16, &vpx_sad8x16_avg_sse2), - SadMxNAvgParam(8, 8, &vpx_sad8x8_avg_sse2), - SadMxNAvgParam(8, 4, &vpx_sad8x4_avg_sse2), - SadMxNAvgParam(4, 8, &vpx_sad4x8_avg_sse2), - SadMxNAvgParam(4, 4, &vpx_sad4x4_avg_sse2), -#if CONFIG_VP9_HIGHBITDEPTH - SadMxNAvgParam(64, 64, &vpx_highbd_sad64x64_avg_sse2, 8), - SadMxNAvgParam(64, 32, &vpx_highbd_sad64x32_avg_sse2, 8), - SadMxNAvgParam(32, 64, &vpx_highbd_sad32x64_avg_sse2, 8), - SadMxNAvgParam(32, 32, &vpx_highbd_sad32x32_avg_sse2, 8), - SadMxNAvgParam(32, 16, &vpx_highbd_sad32x16_avg_sse2, 8), - SadMxNAvgParam(16, 32, &vpx_highbd_sad16x32_avg_sse2, 8), - SadMxNAvgParam(16, 16, &vpx_highbd_sad16x16_avg_sse2, 8), - SadMxNAvgParam(16, 8, &vpx_highbd_sad16x8_avg_sse2, 8), - SadMxNAvgParam(8, 16, &vpx_highbd_sad8x16_avg_sse2, 8), - SadMxNAvgParam(8, 8, &vpx_highbd_sad8x8_avg_sse2, 8), - SadMxNAvgParam(8, 4, &vpx_highbd_sad8x4_avg_sse2, 8), - SadMxNAvgParam(64, 64, &vpx_highbd_sad64x64_avg_sse2, 10), - SadMxNAvgParam(64, 32, &vpx_highbd_sad64x32_avg_sse2, 10), - SadMxNAvgParam(32, 64, &vpx_highbd_sad32x64_avg_sse2, 10), - SadMxNAvgParam(32, 32, &vpx_highbd_sad32x32_avg_sse2, 10), - SadMxNAvgParam(32, 16, &vpx_highbd_sad32x16_avg_sse2, 10), - SadMxNAvgParam(16, 32, &vpx_highbd_sad16x32_avg_sse2, 10), - SadMxNAvgParam(16, 16, &vpx_highbd_sad16x16_avg_sse2, 10), - SadMxNAvgParam(16, 8, &vpx_highbd_sad16x8_avg_sse2, 10), - SadMxNAvgParam(8, 16, &vpx_highbd_sad8x16_avg_sse2, 10), - SadMxNAvgParam(8, 8, &vpx_highbd_sad8x8_avg_sse2, 10), - SadMxNAvgParam(8, 4, &vpx_highbd_sad8x4_avg_sse2, 10), - SadMxNAvgParam(64, 64, &vpx_highbd_sad64x64_avg_sse2, 12), - SadMxNAvgParam(64, 32, &vpx_highbd_sad64x32_avg_sse2, 12), - SadMxNAvgParam(32, 64, &vpx_highbd_sad32x64_avg_sse2, 12), - SadMxNAvgParam(32, 32, &vpx_highbd_sad32x32_avg_sse2, 12), - SadMxNAvgParam(32, 16, &vpx_highbd_sad32x16_avg_sse2, 12), - SadMxNAvgParam(16, 32, &vpx_highbd_sad16x32_avg_sse2, 12), - SadMxNAvgParam(16, 16, &vpx_highbd_sad16x16_avg_sse2, 12), - SadMxNAvgParam(16, 8, &vpx_highbd_sad16x8_avg_sse2, 12), - SadMxNAvgParam(8, 16, &vpx_highbd_sad8x16_avg_sse2, 12), - SadMxNAvgParam(8, 8, &vpx_highbd_sad8x8_avg_sse2, 12), - SadMxNAvgParam(8, 4, &vpx_highbd_sad8x4_avg_sse2, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(SSE2, SADavgTest, ::testing::ValuesIn(avg_sse2_tests)); - -const SadMxNx4Param x4d_sse2_tests[] = { - SadMxNx4Param(64, 64, &vpx_sad64x64x4d_sse2), - SadMxNx4Param(64, 32, &vpx_sad64x32x4d_sse2), - SadMxNx4Param(32, 64, &vpx_sad32x64x4d_sse2), - SadMxNx4Param(32, 32, &vpx_sad32x32x4d_sse2), - SadMxNx4Param(32, 16, &vpx_sad32x16x4d_sse2), - SadMxNx4Param(16, 32, &vpx_sad16x32x4d_sse2), - SadMxNx4Param(16, 16, &vpx_sad16x16x4d_sse2), - SadMxNx4Param(16, 8, &vpx_sad16x8x4d_sse2), - SadMxNx4Param(8, 16, &vpx_sad8x16x4d_sse2), - SadMxNx4Param(8, 8, &vpx_sad8x8x4d_sse2), - SadMxNx4Param(8, 4, &vpx_sad8x4x4d_sse2), - SadMxNx4Param(4, 8, &vpx_sad4x8x4d_sse2), - SadMxNx4Param(4, 4, &vpx_sad4x4x4d_sse2), -#if CONFIG_VP9_HIGHBITDEPTH - SadMxNx4Param(64, 64, &vpx_highbd_sad64x64x4d_sse2, 8), - SadMxNx4Param(64, 32, &vpx_highbd_sad64x32x4d_sse2, 8), - SadMxNx4Param(32, 64, &vpx_highbd_sad32x64x4d_sse2, 8), - SadMxNx4Param(32, 32, &vpx_highbd_sad32x32x4d_sse2, 8), - SadMxNx4Param(32, 16, &vpx_highbd_sad32x16x4d_sse2, 8), - SadMxNx4Param(16, 32, &vpx_highbd_sad16x32x4d_sse2, 8), - SadMxNx4Param(16, 16, &vpx_highbd_sad16x16x4d_sse2, 8), - SadMxNx4Param(16, 8, &vpx_highbd_sad16x8x4d_sse2, 8), - SadMxNx4Param(8, 16, &vpx_highbd_sad8x16x4d_sse2, 8), - SadMxNx4Param(8, 8, &vpx_highbd_sad8x8x4d_sse2, 8), - SadMxNx4Param(8, 4, &vpx_highbd_sad8x4x4d_sse2, 8), - SadMxNx4Param(4, 8, &vpx_highbd_sad4x8x4d_sse2, 8), - SadMxNx4Param(4, 4, &vpx_highbd_sad4x4x4d_sse2, 8), - SadMxNx4Param(64, 64, &vpx_highbd_sad64x64x4d_sse2, 10), - SadMxNx4Param(64, 32, &vpx_highbd_sad64x32x4d_sse2, 10), - SadMxNx4Param(32, 64, &vpx_highbd_sad32x64x4d_sse2, 10), - SadMxNx4Param(32, 32, &vpx_highbd_sad32x32x4d_sse2, 10), - SadMxNx4Param(32, 16, &vpx_highbd_sad32x16x4d_sse2, 10), - SadMxNx4Param(16, 32, &vpx_highbd_sad16x32x4d_sse2, 10), - SadMxNx4Param(16, 16, &vpx_highbd_sad16x16x4d_sse2, 10), - SadMxNx4Param(16, 8, &vpx_highbd_sad16x8x4d_sse2, 10), - SadMxNx4Param(8, 16, &vpx_highbd_sad8x16x4d_sse2, 10), - SadMxNx4Param(8, 8, &vpx_highbd_sad8x8x4d_sse2, 10), - SadMxNx4Param(8, 4, &vpx_highbd_sad8x4x4d_sse2, 10), - SadMxNx4Param(4, 8, &vpx_highbd_sad4x8x4d_sse2, 10), - SadMxNx4Param(4, 4, &vpx_highbd_sad4x4x4d_sse2, 10), - SadMxNx4Param(64, 64, &vpx_highbd_sad64x64x4d_sse2, 12), - SadMxNx4Param(64, 32, &vpx_highbd_sad64x32x4d_sse2, 12), - SadMxNx4Param(32, 64, &vpx_highbd_sad32x64x4d_sse2, 12), - SadMxNx4Param(32, 32, &vpx_highbd_sad32x32x4d_sse2, 12), - SadMxNx4Param(32, 16, &vpx_highbd_sad32x16x4d_sse2, 12), - SadMxNx4Param(16, 32, &vpx_highbd_sad16x32x4d_sse2, 12), - SadMxNx4Param(16, 16, &vpx_highbd_sad16x16x4d_sse2, 12), - SadMxNx4Param(16, 8, &vpx_highbd_sad16x8x4d_sse2, 12), - SadMxNx4Param(8, 16, &vpx_highbd_sad8x16x4d_sse2, 12), - SadMxNx4Param(8, 8, &vpx_highbd_sad8x8x4d_sse2, 12), - SadMxNx4Param(8, 4, &vpx_highbd_sad8x4x4d_sse2, 12), - SadMxNx4Param(4, 8, &vpx_highbd_sad4x8x4d_sse2, 12), - SadMxNx4Param(4, 4, &vpx_highbd_sad4x4x4d_sse2, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(SSE2, SADx4Test, ::testing::ValuesIn(x4d_sse2_tests)); - -const SadSkipMxNx4Param skip_x4d_sse2_tests[] = { - SadSkipMxNx4Param(64, 64, &vpx_sad_skip_64x64x4d_sse2), - SadSkipMxNx4Param(64, 32, &vpx_sad_skip_64x32x4d_sse2), - SadSkipMxNx4Param(32, 64, &vpx_sad_skip_32x64x4d_sse2), - SadSkipMxNx4Param(32, 32, &vpx_sad_skip_32x32x4d_sse2), - SadSkipMxNx4Param(32, 16, &vpx_sad_skip_32x16x4d_sse2), - SadSkipMxNx4Param(16, 32, &vpx_sad_skip_16x32x4d_sse2), - SadSkipMxNx4Param(16, 16, &vpx_sad_skip_16x16x4d_sse2), - SadSkipMxNx4Param(16, 8, &vpx_sad_skip_16x8x4d_sse2), - SadSkipMxNx4Param(8, 16, &vpx_sad_skip_8x16x4d_sse2), - SadSkipMxNx4Param(8, 8, &vpx_sad_skip_8x8x4d_sse2), - SadSkipMxNx4Param(4, 8, &vpx_sad_skip_4x8x4d_sse2), -#if CONFIG_VP9_HIGHBITDEPTH - SadSkipMxNx4Param(64, 64, &vpx_highbd_sad_skip_64x64x4d_sse2, 8), - SadSkipMxNx4Param(64, 32, &vpx_highbd_sad_skip_64x32x4d_sse2, 8), - SadSkipMxNx4Param(32, 64, &vpx_highbd_sad_skip_32x64x4d_sse2, 8), - SadSkipMxNx4Param(32, 32, &vpx_highbd_sad_skip_32x32x4d_sse2, 8), - SadSkipMxNx4Param(32, 16, &vpx_highbd_sad_skip_32x16x4d_sse2, 8), - SadSkipMxNx4Param(16, 32, &vpx_highbd_sad_skip_16x32x4d_sse2, 8), - SadSkipMxNx4Param(16, 16, &vpx_highbd_sad_skip_16x16x4d_sse2, 8), - SadSkipMxNx4Param(16, 8, &vpx_highbd_sad_skip_16x8x4d_sse2, 8), - SadSkipMxNx4Param(8, 16, &vpx_highbd_sad_skip_8x16x4d_sse2, 8), - SadSkipMxNx4Param(8, 8, &vpx_highbd_sad_skip_8x8x4d_sse2, 8), - SadSkipMxNx4Param(4, 8, &vpx_highbd_sad_skip_4x8x4d_sse2, 8), - SadSkipMxNx4Param(64, 64, &vpx_highbd_sad_skip_64x64x4d_sse2, 10), - SadSkipMxNx4Param(64, 32, &vpx_highbd_sad_skip_64x32x4d_sse2, 10), - SadSkipMxNx4Param(32, 64, &vpx_highbd_sad_skip_32x64x4d_sse2, 10), - SadSkipMxNx4Param(32, 32, &vpx_highbd_sad_skip_32x32x4d_sse2, 10), - SadSkipMxNx4Param(32, 16, &vpx_highbd_sad_skip_32x16x4d_sse2, 10), - SadSkipMxNx4Param(16, 32, &vpx_highbd_sad_skip_16x32x4d_sse2, 10), - SadSkipMxNx4Param(16, 16, &vpx_highbd_sad_skip_16x16x4d_sse2, 10), - SadSkipMxNx4Param(16, 8, &vpx_highbd_sad_skip_16x8x4d_sse2, 10), - SadSkipMxNx4Param(8, 16, &vpx_highbd_sad_skip_8x16x4d_sse2, 10), - SadSkipMxNx4Param(8, 8, &vpx_highbd_sad_skip_8x8x4d_sse2, 10), - SadSkipMxNx4Param(4, 8, &vpx_highbd_sad_skip_4x8x4d_sse2, 10), - SadSkipMxNx4Param(64, 64, &vpx_highbd_sad_skip_64x64x4d_sse2, 12), - SadSkipMxNx4Param(64, 32, &vpx_highbd_sad_skip_64x32x4d_sse2, 12), - SadSkipMxNx4Param(32, 64, &vpx_highbd_sad_skip_32x64x4d_sse2, 12), - SadSkipMxNx4Param(32, 32, &vpx_highbd_sad_skip_32x32x4d_sse2, 12), - SadSkipMxNx4Param(32, 16, &vpx_highbd_sad_skip_32x16x4d_sse2, 12), - SadSkipMxNx4Param(16, 32, &vpx_highbd_sad_skip_16x32x4d_sse2, 12), - SadSkipMxNx4Param(16, 16, &vpx_highbd_sad_skip_16x16x4d_sse2, 12), - SadSkipMxNx4Param(16, 8, &vpx_highbd_sad_skip_16x8x4d_sse2, 12), - SadSkipMxNx4Param(8, 16, &vpx_highbd_sad_skip_8x16x4d_sse2, 12), - SadSkipMxNx4Param(8, 8, &vpx_highbd_sad_skip_8x8x4d_sse2, 12), - SadSkipMxNx4Param(4, 8, &vpx_highbd_sad_skip_4x8x4d_sse2, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(SSE2, SADSkipx4Test, - ::testing::ValuesIn(skip_x4d_sse2_tests)); -#endif // HAVE_SSE2 - -#if HAVE_SSE3 -// Only functions are x3, which do not have tests. -#endif // HAVE_SSE3 - -#if HAVE_SSSE3 -// Only functions are x3, which do not have tests. -#endif // HAVE_SSSE3 - -#if HAVE_AVX2 -const SadMxNParam avx2_tests[] = { - SadMxNParam(64, 64, &vpx_sad64x64_avx2), - SadMxNParam(64, 32, &vpx_sad64x32_avx2), - SadMxNParam(32, 64, &vpx_sad32x64_avx2), - SadMxNParam(32, 32, &vpx_sad32x32_avx2), - SadMxNParam(32, 16, &vpx_sad32x16_avx2), -#if CONFIG_VP9_HIGHBITDEPTH - SadMxNParam(64, 64, &vpx_highbd_sad64x64_avx2, 8), - SadMxNParam(64, 32, &vpx_highbd_sad64x32_avx2, 8), - SadMxNParam(32, 64, &vpx_highbd_sad32x64_avx2, 8), - SadMxNParam(32, 32, &vpx_highbd_sad32x32_avx2, 8), - SadMxNParam(32, 16, &vpx_highbd_sad32x16_avx2, 8), - SadMxNParam(16, 32, &vpx_highbd_sad16x32_avx2, 8), - SadMxNParam(16, 16, &vpx_highbd_sad16x16_avx2, 8), - SadMxNParam(16, 8, &vpx_highbd_sad16x8_avx2, 8), - - SadMxNParam(64, 64, &vpx_highbd_sad64x64_avx2, 10), - SadMxNParam(64, 32, &vpx_highbd_sad64x32_avx2, 10), - SadMxNParam(32, 64, &vpx_highbd_sad32x64_avx2, 10), - SadMxNParam(32, 32, &vpx_highbd_sad32x32_avx2, 10), - SadMxNParam(32, 16, &vpx_highbd_sad32x16_avx2, 10), - SadMxNParam(16, 32, &vpx_highbd_sad16x32_avx2, 10), - SadMxNParam(16, 16, &vpx_highbd_sad16x16_avx2, 10), - SadMxNParam(16, 8, &vpx_highbd_sad16x8_avx2, 10), - - SadMxNParam(64, 64, &vpx_highbd_sad64x64_avx2, 12), - SadMxNParam(64, 32, &vpx_highbd_sad64x32_avx2, 12), - SadMxNParam(32, 64, &vpx_highbd_sad32x64_avx2, 12), - SadMxNParam(32, 32, &vpx_highbd_sad32x32_avx2, 12), - SadMxNParam(32, 16, &vpx_highbd_sad32x16_avx2, 12), - SadMxNParam(16, 32, &vpx_highbd_sad16x32_avx2, 12), - SadMxNParam(16, 16, &vpx_highbd_sad16x16_avx2, 12), - SadMxNParam(16, 8, &vpx_highbd_sad16x8_avx2, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(AVX2, SADTest, ::testing::ValuesIn(avx2_tests)); - -const SadSkipMxNParam skip_avx2_tests[] = { - SadSkipMxNParam(64, 64, &vpx_sad_skip_64x64_avx2), - SadSkipMxNParam(64, 32, &vpx_sad_skip_64x32_avx2), - SadSkipMxNParam(32, 64, &vpx_sad_skip_32x64_avx2), - SadSkipMxNParam(32, 32, &vpx_sad_skip_32x32_avx2), - SadSkipMxNParam(32, 16, &vpx_sad_skip_32x16_avx2), -#if CONFIG_VP9_HIGHBITDEPTH - SadSkipMxNParam(64, 64, &vpx_highbd_sad_skip_64x64_avx2, 8), - SadSkipMxNParam(64, 32, &vpx_highbd_sad_skip_64x32_avx2, 8), - SadSkipMxNParam(32, 64, &vpx_highbd_sad_skip_32x64_avx2, 8), - SadSkipMxNParam(32, 32, &vpx_highbd_sad_skip_32x32_avx2, 8), - SadSkipMxNParam(32, 16, &vpx_highbd_sad_skip_32x16_avx2, 8), - SadSkipMxNParam(16, 32, &vpx_highbd_sad_skip_16x32_avx2, 8), - SadSkipMxNParam(16, 16, &vpx_highbd_sad_skip_16x16_avx2, 8), - SadSkipMxNParam(16, 8, &vpx_highbd_sad_skip_16x8_avx2, 8), - - SadSkipMxNParam(64, 64, &vpx_highbd_sad_skip_64x64_avx2, 10), - SadSkipMxNParam(64, 32, &vpx_highbd_sad_skip_64x32_avx2, 10), - SadSkipMxNParam(32, 64, &vpx_highbd_sad_skip_32x64_avx2, 10), - SadSkipMxNParam(32, 32, &vpx_highbd_sad_skip_32x32_avx2, 10), - SadSkipMxNParam(32, 16, &vpx_highbd_sad_skip_32x16_avx2, 10), - SadSkipMxNParam(16, 32, &vpx_highbd_sad_skip_16x32_avx2, 10), - SadSkipMxNParam(16, 16, &vpx_highbd_sad_skip_16x16_avx2, 10), - SadSkipMxNParam(16, 8, &vpx_highbd_sad_skip_16x8_avx2, 10), - - SadSkipMxNParam(64, 64, &vpx_highbd_sad_skip_64x64_avx2, 12), - SadSkipMxNParam(64, 32, &vpx_highbd_sad_skip_64x32_avx2, 12), - SadSkipMxNParam(32, 64, &vpx_highbd_sad_skip_32x64_avx2, 12), - SadSkipMxNParam(32, 32, &vpx_highbd_sad_skip_32x32_avx2, 12), - SadSkipMxNParam(32, 16, &vpx_highbd_sad_skip_32x16_avx2, 12), - SadSkipMxNParam(16, 32, &vpx_highbd_sad_skip_16x32_avx2, 12), - SadSkipMxNParam(16, 16, &vpx_highbd_sad_skip_16x16_avx2, 12), - SadSkipMxNParam(16, 8, &vpx_highbd_sad_skip_16x8_avx2, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(AVX2, SADSkipTest, - ::testing::ValuesIn(skip_avx2_tests)); - -const SadMxNAvgParam avg_avx2_tests[] = { - SadMxNAvgParam(64, 64, &vpx_sad64x64_avg_avx2), - SadMxNAvgParam(64, 32, &vpx_sad64x32_avg_avx2), - SadMxNAvgParam(32, 64, &vpx_sad32x64_avg_avx2), - SadMxNAvgParam(32, 32, &vpx_sad32x32_avg_avx2), - SadMxNAvgParam(32, 16, &vpx_sad32x16_avg_avx2), -#if CONFIG_VP9_HIGHBITDEPTH - SadMxNAvgParam(64, 64, &vpx_highbd_sad64x64_avg_avx2, 8), - SadMxNAvgParam(64, 32, &vpx_highbd_sad64x32_avg_avx2, 8), - SadMxNAvgParam(32, 64, &vpx_highbd_sad32x64_avg_avx2, 8), - SadMxNAvgParam(32, 32, &vpx_highbd_sad32x32_avg_avx2, 8), - SadMxNAvgParam(32, 16, &vpx_highbd_sad32x16_avg_avx2, 8), - SadMxNAvgParam(16, 32, &vpx_highbd_sad16x32_avg_avx2, 8), - SadMxNAvgParam(16, 16, &vpx_highbd_sad16x16_avg_avx2, 8), - SadMxNAvgParam(16, 8, &vpx_highbd_sad16x8_avg_avx2, 8), - SadMxNAvgParam(64, 64, &vpx_highbd_sad64x64_avg_avx2, 10), - SadMxNAvgParam(64, 32, &vpx_highbd_sad64x32_avg_avx2, 10), - SadMxNAvgParam(32, 64, &vpx_highbd_sad32x64_avg_avx2, 10), - SadMxNAvgParam(32, 32, &vpx_highbd_sad32x32_avg_avx2, 10), - SadMxNAvgParam(32, 16, &vpx_highbd_sad32x16_avg_avx2, 10), - SadMxNAvgParam(16, 32, &vpx_highbd_sad16x32_avg_avx2, 10), - SadMxNAvgParam(16, 16, &vpx_highbd_sad16x16_avg_avx2, 10), - SadMxNAvgParam(16, 8, &vpx_highbd_sad16x8_avg_avx2, 10), - SadMxNAvgParam(64, 64, &vpx_highbd_sad64x64_avg_avx2, 12), - SadMxNAvgParam(64, 32, &vpx_highbd_sad64x32_avg_avx2, 12), - SadMxNAvgParam(32, 64, &vpx_highbd_sad32x64_avg_avx2, 12), - SadMxNAvgParam(32, 32, &vpx_highbd_sad32x32_avg_avx2, 12), - SadMxNAvgParam(32, 16, &vpx_highbd_sad32x16_avg_avx2, 12), - SadMxNAvgParam(16, 32, &vpx_highbd_sad16x32_avg_avx2, 12), - SadMxNAvgParam(16, 16, &vpx_highbd_sad16x16_avg_avx2, 12), - SadMxNAvgParam(16, 8, &vpx_highbd_sad16x8_avg_avx2, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(AVX2, SADavgTest, ::testing::ValuesIn(avg_avx2_tests)); - -const SadMxNx4Param x4d_avx2_tests[] = { - SadMxNx4Param(64, 64, &vpx_sad64x64x4d_avx2), - SadMxNx4Param(32, 32, &vpx_sad32x32x4d_avx2), -#if CONFIG_VP9_HIGHBITDEPTH - SadMxNx4Param(64, 64, &vpx_highbd_sad64x64x4d_avx2, 8), - SadMxNx4Param(64, 32, &vpx_highbd_sad64x32x4d_avx2, 8), - SadMxNx4Param(32, 64, &vpx_highbd_sad32x64x4d_avx2, 8), - SadMxNx4Param(32, 32, &vpx_highbd_sad32x32x4d_avx2, 8), - SadMxNx4Param(32, 16, &vpx_highbd_sad32x16x4d_avx2, 8), - SadMxNx4Param(16, 32, &vpx_highbd_sad16x32x4d_avx2, 8), - SadMxNx4Param(16, 16, &vpx_highbd_sad16x16x4d_avx2, 8), - SadMxNx4Param(16, 8, &vpx_highbd_sad16x8x4d_avx2, 8), - SadMxNx4Param(64, 64, &vpx_highbd_sad64x64x4d_avx2, 10), - SadMxNx4Param(64, 32, &vpx_highbd_sad64x32x4d_avx2, 10), - SadMxNx4Param(32, 64, &vpx_highbd_sad32x64x4d_avx2, 10), - SadMxNx4Param(32, 32, &vpx_highbd_sad32x32x4d_avx2, 10), - SadMxNx4Param(32, 16, &vpx_highbd_sad32x16x4d_avx2, 10), - SadMxNx4Param(16, 32, &vpx_highbd_sad16x32x4d_avx2, 10), - SadMxNx4Param(16, 16, &vpx_highbd_sad16x16x4d_avx2, 10), - SadMxNx4Param(16, 8, &vpx_highbd_sad16x8x4d_avx2, 10), - SadMxNx4Param(64, 64, &vpx_highbd_sad64x64x4d_avx2, 12), - SadMxNx4Param(64, 32, &vpx_highbd_sad64x32x4d_avx2, 12), - SadMxNx4Param(32, 64, &vpx_highbd_sad32x64x4d_avx2, 12), - SadMxNx4Param(32, 32, &vpx_highbd_sad32x32x4d_avx2, 12), - SadMxNx4Param(32, 16, &vpx_highbd_sad32x16x4d_avx2, 12), - SadMxNx4Param(16, 32, &vpx_highbd_sad16x32x4d_avx2, 12), - SadMxNx4Param(16, 16, &vpx_highbd_sad16x16x4d_avx2, 12), - SadMxNx4Param(16, 8, &vpx_highbd_sad16x8x4d_avx2, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(AVX2, SADx4Test, ::testing::ValuesIn(x4d_avx2_tests)); - -const SadSkipMxNx4Param skip_x4d_avx2_tests[] = { - SadSkipMxNx4Param(64, 64, &vpx_sad_skip_64x64x4d_avx2), - SadSkipMxNx4Param(64, 32, &vpx_sad_skip_64x32x4d_avx2), - SadSkipMxNx4Param(32, 64, &vpx_sad_skip_32x64x4d_avx2), - SadSkipMxNx4Param(32, 32, &vpx_sad_skip_32x32x4d_avx2), - SadSkipMxNx4Param(32, 16, &vpx_sad_skip_32x16x4d_avx2), -#if CONFIG_VP9_HIGHBITDEPTH - SadSkipMxNx4Param(64, 64, &vpx_highbd_sad_skip_64x64x4d_avx2, 8), - SadSkipMxNx4Param(64, 32, &vpx_highbd_sad_skip_64x32x4d_avx2, 8), - SadSkipMxNx4Param(32, 64, &vpx_highbd_sad_skip_32x64x4d_avx2, 8), - SadSkipMxNx4Param(32, 32, &vpx_highbd_sad_skip_32x32x4d_avx2, 8), - SadSkipMxNx4Param(32, 16, &vpx_highbd_sad_skip_32x16x4d_avx2, 8), - SadSkipMxNx4Param(16, 32, &vpx_highbd_sad_skip_16x32x4d_avx2, 8), - SadSkipMxNx4Param(16, 16, &vpx_highbd_sad_skip_16x16x4d_avx2, 8), - SadSkipMxNx4Param(16, 8, &vpx_highbd_sad_skip_16x8x4d_avx2, 8), - SadSkipMxNx4Param(64, 64, &vpx_highbd_sad_skip_64x64x4d_avx2, 10), - SadSkipMxNx4Param(64, 32, &vpx_highbd_sad_skip_64x32x4d_avx2, 10), - SadSkipMxNx4Param(32, 64, &vpx_highbd_sad_skip_32x64x4d_avx2, 10), - SadSkipMxNx4Param(32, 32, &vpx_highbd_sad_skip_32x32x4d_avx2, 10), - SadSkipMxNx4Param(32, 16, &vpx_highbd_sad_skip_32x16x4d_avx2, 10), - SadSkipMxNx4Param(16, 32, &vpx_highbd_sad_skip_16x32x4d_avx2, 10), - SadSkipMxNx4Param(16, 16, &vpx_highbd_sad_skip_16x16x4d_avx2, 10), - SadSkipMxNx4Param(16, 8, &vpx_highbd_sad_skip_16x8x4d_avx2, 10), - SadSkipMxNx4Param(64, 64, &vpx_highbd_sad_skip_64x64x4d_avx2, 12), - SadSkipMxNx4Param(64, 32, &vpx_highbd_sad_skip_64x32x4d_avx2, 12), - SadSkipMxNx4Param(32, 64, &vpx_highbd_sad_skip_32x64x4d_avx2, 12), - SadSkipMxNx4Param(32, 32, &vpx_highbd_sad_skip_32x32x4d_avx2, 12), - SadSkipMxNx4Param(32, 16, &vpx_highbd_sad_skip_32x16x4d_avx2, 12), - SadSkipMxNx4Param(16, 32, &vpx_highbd_sad_skip_16x32x4d_avx2, 12), - SadSkipMxNx4Param(16, 16, &vpx_highbd_sad_skip_16x16x4d_avx2, 12), - SadSkipMxNx4Param(16, 8, &vpx_highbd_sad_skip_16x8x4d_avx2, 12), -#endif // CONFIG_VP9_HIGHBITDEPTH -}; -INSTANTIATE_TEST_SUITE_P(AVX2, SADSkipx4Test, - ::testing::ValuesIn(skip_x4d_avx2_tests)); - -#endif // HAVE_AVX2 - -#if HAVE_AVX512 -const SadMxNx4Param x4d_avx512_tests[] = { - SadMxNx4Param(64, 64, &vpx_sad64x64x4d_avx512), -}; -INSTANTIATE_TEST_SUITE_P(AVX512, SADx4Test, - ::testing::ValuesIn(x4d_avx512_tests)); -#endif // HAVE_AVX512 - -//------------------------------------------------------------------------------ -// MIPS functions -#if HAVE_MSA -const SadMxNParam msa_tests[] = { - SadMxNParam(64, 64, &vpx_sad64x64_msa), - SadMxNParam(64, 32, &vpx_sad64x32_msa), - SadMxNParam(32, 64, &vpx_sad32x64_msa), - SadMxNParam(32, 32, &vpx_sad32x32_msa), - SadMxNParam(32, 16, &vpx_sad32x16_msa), - SadMxNParam(16, 32, &vpx_sad16x32_msa), - SadMxNParam(16, 16, &vpx_sad16x16_msa), - SadMxNParam(16, 8, &vpx_sad16x8_msa), - SadMxNParam(8, 16, &vpx_sad8x16_msa), - SadMxNParam(8, 8, &vpx_sad8x8_msa), - SadMxNParam(8, 4, &vpx_sad8x4_msa), - SadMxNParam(4, 8, &vpx_sad4x8_msa), - SadMxNParam(4, 4, &vpx_sad4x4_msa), -}; -INSTANTIATE_TEST_SUITE_P(MSA, SADTest, ::testing::ValuesIn(msa_tests)); - -const SadMxNAvgParam avg_msa_tests[] = { - SadMxNAvgParam(64, 64, &vpx_sad64x64_avg_msa), - SadMxNAvgParam(64, 32, &vpx_sad64x32_avg_msa), - SadMxNAvgParam(32, 64, &vpx_sad32x64_avg_msa), - SadMxNAvgParam(32, 32, &vpx_sad32x32_avg_msa), - SadMxNAvgParam(32, 16, &vpx_sad32x16_avg_msa), - SadMxNAvgParam(16, 32, &vpx_sad16x32_avg_msa), - SadMxNAvgParam(16, 16, &vpx_sad16x16_avg_msa), - SadMxNAvgParam(16, 8, &vpx_sad16x8_avg_msa), - SadMxNAvgParam(8, 16, &vpx_sad8x16_avg_msa), - SadMxNAvgParam(8, 8, &vpx_sad8x8_avg_msa), - SadMxNAvgParam(8, 4, &vpx_sad8x4_avg_msa), - SadMxNAvgParam(4, 8, &vpx_sad4x8_avg_msa), - SadMxNAvgParam(4, 4, &vpx_sad4x4_avg_msa), -}; -INSTANTIATE_TEST_SUITE_P(MSA, SADavgTest, ::testing::ValuesIn(avg_msa_tests)); - -const SadMxNx4Param x4d_msa_tests[] = { - SadMxNx4Param(64, 64, &vpx_sad64x64x4d_msa), - SadMxNx4Param(64, 32, &vpx_sad64x32x4d_msa), - SadMxNx4Param(32, 64, &vpx_sad32x64x4d_msa), - SadMxNx4Param(32, 32, &vpx_sad32x32x4d_msa), - SadMxNx4Param(32, 16, &vpx_sad32x16x4d_msa), - SadMxNx4Param(16, 32, &vpx_sad16x32x4d_msa), - SadMxNx4Param(16, 16, &vpx_sad16x16x4d_msa), - SadMxNx4Param(16, 8, &vpx_sad16x8x4d_msa), - SadMxNx4Param(8, 16, &vpx_sad8x16x4d_msa), - SadMxNx4Param(8, 8, &vpx_sad8x8x4d_msa), - SadMxNx4Param(8, 4, &vpx_sad8x4x4d_msa), - SadMxNx4Param(4, 8, &vpx_sad4x8x4d_msa), - SadMxNx4Param(4, 4, &vpx_sad4x4x4d_msa), -}; -INSTANTIATE_TEST_SUITE_P(MSA, SADx4Test, ::testing::ValuesIn(x4d_msa_tests)); -#endif // HAVE_MSA - -//------------------------------------------------------------------------------ -// VSX functions -#if HAVE_VSX -const SadMxNParam vsx_tests[] = { - SadMxNParam(64, 64, &vpx_sad64x64_vsx), - SadMxNParam(64, 32, &vpx_sad64x32_vsx), - SadMxNParam(32, 64, &vpx_sad32x64_vsx), - SadMxNParam(32, 32, &vpx_sad32x32_vsx), - SadMxNParam(32, 16, &vpx_sad32x16_vsx), - SadMxNParam(16, 32, &vpx_sad16x32_vsx), - SadMxNParam(16, 16, &vpx_sad16x16_vsx), - SadMxNParam(16, 8, &vpx_sad16x8_vsx), - SadMxNParam(8, 16, &vpx_sad8x16_vsx), - SadMxNParam(8, 8, &vpx_sad8x8_vsx), - SadMxNParam(8, 4, &vpx_sad8x4_vsx), -}; -INSTANTIATE_TEST_SUITE_P(VSX, SADTest, ::testing::ValuesIn(vsx_tests)); - -const SadMxNAvgParam avg_vsx_tests[] = { - SadMxNAvgParam(64, 64, &vpx_sad64x64_avg_vsx), - SadMxNAvgParam(64, 32, &vpx_sad64x32_avg_vsx), - SadMxNAvgParam(32, 64, &vpx_sad32x64_avg_vsx), - SadMxNAvgParam(32, 32, &vpx_sad32x32_avg_vsx), - SadMxNAvgParam(32, 16, &vpx_sad32x16_avg_vsx), - SadMxNAvgParam(16, 32, &vpx_sad16x32_avg_vsx), - SadMxNAvgParam(16, 16, &vpx_sad16x16_avg_vsx), - SadMxNAvgParam(16, 8, &vpx_sad16x8_avg_vsx), -}; -INSTANTIATE_TEST_SUITE_P(VSX, SADavgTest, ::testing::ValuesIn(avg_vsx_tests)); - -const SadMxNx4Param x4d_vsx_tests[] = { - SadMxNx4Param(64, 64, &vpx_sad64x64x4d_vsx), - SadMxNx4Param(64, 32, &vpx_sad64x32x4d_vsx), - SadMxNx4Param(32, 64, &vpx_sad32x64x4d_vsx), - SadMxNx4Param(32, 32, &vpx_sad32x32x4d_vsx), - SadMxNx4Param(32, 16, &vpx_sad32x16x4d_vsx), - SadMxNx4Param(16, 32, &vpx_sad16x32x4d_vsx), - SadMxNx4Param(16, 16, &vpx_sad16x16x4d_vsx), - SadMxNx4Param(16, 8, &vpx_sad16x8x4d_vsx), -}; -INSTANTIATE_TEST_SUITE_P(VSX, SADx4Test, ::testing::ValuesIn(x4d_vsx_tests)); -#endif // HAVE_VSX - -//------------------------------------------------------------------------------ -// Loongson functions -#if HAVE_MMI -const SadMxNParam mmi_tests[] = { - SadMxNParam(64, 64, &vpx_sad64x64_mmi), - SadMxNParam(64, 32, &vpx_sad64x32_mmi), - SadMxNParam(32, 64, &vpx_sad32x64_mmi), - SadMxNParam(32, 32, &vpx_sad32x32_mmi), - SadMxNParam(32, 16, &vpx_sad32x16_mmi), - SadMxNParam(16, 32, &vpx_sad16x32_mmi), - SadMxNParam(16, 16, &vpx_sad16x16_mmi), - SadMxNParam(16, 8, &vpx_sad16x8_mmi), - SadMxNParam(8, 16, &vpx_sad8x16_mmi), - SadMxNParam(8, 8, &vpx_sad8x8_mmi), - SadMxNParam(8, 4, &vpx_sad8x4_mmi), - SadMxNParam(4, 8, &vpx_sad4x8_mmi), - SadMxNParam(4, 4, &vpx_sad4x4_mmi), -}; -INSTANTIATE_TEST_SUITE_P(MMI, SADTest, ::testing::ValuesIn(mmi_tests)); - -const SadMxNAvgParam avg_mmi_tests[] = { - SadMxNAvgParam(64, 64, &vpx_sad64x64_avg_mmi), - SadMxNAvgParam(64, 32, &vpx_sad64x32_avg_mmi), - SadMxNAvgParam(32, 64, &vpx_sad32x64_avg_mmi), - SadMxNAvgParam(32, 32, &vpx_sad32x32_avg_mmi), - SadMxNAvgParam(32, 16, &vpx_sad32x16_avg_mmi), - SadMxNAvgParam(16, 32, &vpx_sad16x32_avg_mmi), - SadMxNAvgParam(16, 16, &vpx_sad16x16_avg_mmi), - SadMxNAvgParam(16, 8, &vpx_sad16x8_avg_mmi), - SadMxNAvgParam(8, 16, &vpx_sad8x16_avg_mmi), - SadMxNAvgParam(8, 8, &vpx_sad8x8_avg_mmi), - SadMxNAvgParam(8, 4, &vpx_sad8x4_avg_mmi), - SadMxNAvgParam(4, 8, &vpx_sad4x8_avg_mmi), - SadMxNAvgParam(4, 4, &vpx_sad4x4_avg_mmi), -}; -INSTANTIATE_TEST_SUITE_P(MMI, SADavgTest, ::testing::ValuesIn(avg_mmi_tests)); - -const SadMxNx4Param x4d_mmi_tests[] = { - SadMxNx4Param(64, 64, &vpx_sad64x64x4d_mmi), - SadMxNx4Param(64, 32, &vpx_sad64x32x4d_mmi), - SadMxNx4Param(32, 64, &vpx_sad32x64x4d_mmi), - SadMxNx4Param(32, 32, &vpx_sad32x32x4d_mmi), - SadMxNx4Param(32, 16, &vpx_sad32x16x4d_mmi), - SadMxNx4Param(16, 32, &vpx_sad16x32x4d_mmi), - SadMxNx4Param(16, 16, &vpx_sad16x16x4d_mmi), - SadMxNx4Param(16, 8, &vpx_sad16x8x4d_mmi), - SadMxNx4Param(8, 16, &vpx_sad8x16x4d_mmi), - SadMxNx4Param(8, 8, &vpx_sad8x8x4d_mmi), - SadMxNx4Param(8, 4, &vpx_sad8x4x4d_mmi), - SadMxNx4Param(4, 8, &vpx_sad4x8x4d_mmi), - SadMxNx4Param(4, 4, &vpx_sad4x4x4d_mmi), -}; -INSTANTIATE_TEST_SUITE_P(MMI, SADx4Test, ::testing::ValuesIn(x4d_mmi_tests)); -#endif // HAVE_MMI - -//------------------------------------------------------------------------------ -// loongarch functions -#if HAVE_LSX -const SadMxNParam lsx_tests[] = { - SadMxNParam(64, 64, &vpx_sad64x64_lsx), - SadMxNParam(32, 32, &vpx_sad32x32_lsx), - SadMxNParam(16, 16, &vpx_sad16x16_lsx), - SadMxNParam(8, 8, &vpx_sad8x8_lsx), -}; -INSTANTIATE_TEST_SUITE_P(LSX, SADTest, ::testing::ValuesIn(lsx_tests)); - -const SadMxNAvgParam avg_lsx_tests[] = { - SadMxNAvgParam(64, 64, &vpx_sad64x64_avg_lsx), - SadMxNAvgParam(32, 32, &vpx_sad32x32_avg_lsx), -}; -INSTANTIATE_TEST_SUITE_P(LSX, SADavgTest, ::testing::ValuesIn(avg_lsx_tests)); - -const SadMxNx4Param x4d_lsx_tests[] = { - SadMxNx4Param(64, 64, &vpx_sad64x64x4d_lsx), - SadMxNx4Param(64, 32, &vpx_sad64x32x4d_lsx), - SadMxNx4Param(32, 64, &vpx_sad32x64x4d_lsx), - SadMxNx4Param(32, 32, &vpx_sad32x32x4d_lsx), - SadMxNx4Param(16, 16, &vpx_sad16x16x4d_lsx), - SadMxNx4Param(8, 8, &vpx_sad8x8x4d_lsx), -}; -INSTANTIATE_TEST_SUITE_P(LSX, SADx4Test, ::testing::ValuesIn(x4d_lsx_tests)); -#endif // HAVE_LSX - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/set_maps.sh b/presentation/src/main/cpp/third_party/libvpx/test/set_maps.sh deleted file mode 100644 index f45dc51f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/set_maps.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2014 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## This file tests the libvpx set_maps example. To add new tests to this file, -## do the following: -## 1. Write a shell function (this is your test). -## 2. Add the function to set_maps_tests (on a new line). -## -. $(dirname $0)/tools_common.sh - -# Environment check: $YUV_RAW_INPUT is required, and set_maps must exist in -# $LIBVPX_BIN_PATH. -set_maps_verify_environment() { - if [ ! -e "${YUV_RAW_INPUT}" ]; then - echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH." - return 1 - fi - if [ -z "$(vpx_tool_path set_maps)" ]; then - elog "set_maps not found. It must exist in LIBVPX_BIN_PATH or its parent." - return 1 - fi -} - -# Runs set_maps using the codec specified by $1. -set_maps() { - local encoder="$(vpx_tool_path set_maps)" - local codec="$1" - local output_file="${VPX_TEST_OUTPUT_DIR}/set_maps_${codec}.ivf" - - eval "${VPX_TEST_PREFIX}" "${encoder}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \ - "${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" \ - ${devnull} || return 1 - - [ -e "${output_file}" ] || return 1 -} - -set_maps_vp8() { - if [ "$(vp8_encode_available)" = "yes" ]; then - set_maps vp8 || return 1 - fi -} - -set_maps_vp9() { - if [ "$(vp9_encode_available)" = "yes" ]; then - set_maps vp9 || return 1 - fi -} - -set_maps_tests="set_maps_vp8 - set_maps_vp9" - -run_tests set_maps_verify_environment "${set_maps_tests}" diff --git a/presentation/src/main/cpp/third_party/libvpx/test/set_roi.cc b/presentation/src/main/cpp/third_party/libvpx/test/set_roi.cc deleted file mode 100644 index ac07ca16..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/set_roi.cc +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include -#include - -#include "gtest/gtest.h" -#include "test/acm_random.h" -#include "vp8/encoder/onyx_int.h" -#include "vpx/vpx_integer.h" -#include "vpx_mem/vpx_mem.h" - -using libvpx_test::ACMRandom; - -namespace { - -TEST(VP8RoiMapTest, ParameterCheck) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - int delta_q[MAX_MB_SEGMENTS] = { -2, -25, 0, 31 }; - int delta_lf[MAX_MB_SEGMENTS] = { -2, -25, 0, 31 }; - unsigned int threshold[MAX_MB_SEGMENTS] = { 0, 100, 200, 300 }; - - const int internalq_trans[] = { - 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19, - 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 35, 37, 39, 41, - 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 64, 67, 70, 73, 76, 79, - 82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, 127, - }; - - // Initialize elements of cpi with valid defaults. - VP8_COMP cpi; - cpi.mb.e_mbd.mb_segment_abs_delta = SEGMENT_DELTADATA; - cpi.cyclic_refresh_mode_enabled = 0; - cpi.mb.e_mbd.segmentation_enabled = 0; - cpi.mb.e_mbd.update_mb_segmentation_map = 0; - cpi.mb.e_mbd.update_mb_segmentation_data = 0; - cpi.common.mb_rows = 240 >> 4; - cpi.common.mb_cols = 320 >> 4; - const int mbs = (cpi.common.mb_rows * cpi.common.mb_cols); - memset(cpi.segment_feature_data, 0, sizeof(cpi.segment_feature_data)); - - // Segment map - cpi.segmentation_map = reinterpret_cast(vpx_calloc(mbs, 1)); - - // Allocate memory for the source memory map. - unsigned char *roi_map = - reinterpret_cast(vpx_calloc(mbs, 1)); - memset(&roi_map[mbs >> 2], 1, (mbs >> 2)); - memset(&roi_map[mbs >> 1], 2, (mbs >> 2)); - memset(&roi_map[mbs - (mbs >> 2)], 3, (mbs >> 2)); - - // Do a test call with valid parameters. - int roi_retval = - vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols, - delta_q, delta_lf, threshold); - EXPECT_EQ(0, roi_retval) - << "vp8_set_roimap roi failed with default test parameters"; - - // Check that the values in the cpi structure get set as expected. - if (roi_retval == 0) { - // Check that the segment map got set. - const int mapcompare = memcmp(roi_map, cpi.segmentation_map, mbs); - EXPECT_EQ(0, mapcompare) << "segment map error"; - - // Check the q deltas (note the need to translate into - // the interanl range of 0-127. - for (int i = 0; i < MAX_MB_SEGMENTS; ++i) { - const int transq = internalq_trans[abs(delta_q[i])]; - if (abs(cpi.segment_feature_data[MB_LVL_ALT_Q][i]) != transq) { - EXPECT_EQ(transq, cpi.segment_feature_data[MB_LVL_ALT_Q][i]) - << "segment delta_q error"; - break; - } - } - - // Check the loop filter deltas - for (int i = 0; i < MAX_MB_SEGMENTS; ++i) { - if (cpi.segment_feature_data[MB_LVL_ALT_LF][i] != delta_lf[i]) { - EXPECT_EQ(delta_lf[i], cpi.segment_feature_data[MB_LVL_ALT_LF][i]) - << "segment delta_lf error"; - break; - } - } - - // Check the breakout thresholds - for (int i = 0; i < MAX_MB_SEGMENTS; ++i) { - unsigned int breakout = - static_cast(cpi.segment_encode_breakout[i]); - - if (threshold[i] != breakout) { - EXPECT_EQ(threshold[i], breakout) << "breakout threshold error"; - break; - } - } - - // Segmentation, and segmentation update flages should be set. - EXPECT_EQ(1, cpi.mb.e_mbd.segmentation_enabled) - << "segmentation_enabled error"; - EXPECT_EQ(1, cpi.mb.e_mbd.update_mb_segmentation_map) - << "update_mb_segmentation_map error"; - EXPECT_EQ(1, cpi.mb.e_mbd.update_mb_segmentation_data) - << "update_mb_segmentation_data error"; - - // Try a range of delta q and lf parameters (some legal, some not) - for (int i = 0; i < 1000; ++i) { - int rand_deltas[4]; - int deltas_valid; - rand_deltas[0] = rnd(160) - 80; - rand_deltas[1] = rnd(160) - 80; - rand_deltas[2] = rnd(160) - 80; - rand_deltas[3] = rnd(160) - 80; - - deltas_valid = - ((abs(rand_deltas[0]) <= 63) && (abs(rand_deltas[1]) <= 63) && - (abs(rand_deltas[2]) <= 63) && (abs(rand_deltas[3]) <= 63)) - ? 0 - : -1; - - // Test with random delta q values. - roi_retval = - vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols, - rand_deltas, delta_lf, threshold); - EXPECT_EQ(deltas_valid, roi_retval) << "dq range check error"; - - // One delta_q error shown at a time - if (deltas_valid != roi_retval) break; - - // Test with random loop filter values. - roi_retval = - vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols, - delta_q, rand_deltas, threshold); - EXPECT_EQ(deltas_valid, roi_retval) << "dlf range check error"; - - // One delta loop filter error shown at a time - if (deltas_valid != roi_retval) break; - } - - // Test invalid number of rows or colums. - roi_retval = - vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows + 1, - cpi.common.mb_cols, delta_q, delta_lf, threshold); - EXPECT_EQ(-1, roi_retval) << "MB rows bounds check error"; - - roi_retval = - vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, - cpi.common.mb_cols - 1, delta_q, delta_lf, threshold); - EXPECT_EQ(-1, roi_retval) << "MB cols bounds check error"; - } - - // Free allocated memory - if (cpi.segmentation_map) vpx_free(cpi.segmentation_map); - if (roi_map) vpx_free(roi_map); -} - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/simple_decoder.sh b/presentation/src/main/cpp/third_party/libvpx/test/simple_decoder.sh deleted file mode 100644 index 65fc4828..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/simple_decoder.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2014 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## This file tests the libvpx simple_decoder example code. To add new tests to -## this file, do the following: -## 1. Write a shell function (this is your test). -## 2. Add the function to simple_decoder_tests (on a new line). -## -. $(dirname $0)/tools_common.sh - -# Environment check: Make sure input is available: -# $VP8_IVF_FILE and $VP9_IVF_FILE are required. -simple_decoder_verify_environment() { - if [ ! -e "${VP8_IVF_FILE}" ] || [ ! -e "${VP9_IVF_FILE}" ]; then - echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH." - return 1 - fi -} - -# Runs simple_decoder using $1 as input file. $2 is the codec name, and is used -# solely to name the output file. -simple_decoder() { - local decoder="${LIBVPX_BIN_PATH}/simple_decoder${VPX_TEST_EXE_SUFFIX}" - local input_file="$1" - local codec="$2" - local output_file="${VPX_TEST_OUTPUT_DIR}/simple_decoder_${codec}.raw" - - if [ ! -x "${decoder}" ]; then - elog "${decoder} does not exist or is not executable." - return 1 - fi - - eval "${VPX_TEST_PREFIX}" "${decoder}" "${input_file}" "${output_file}" \ - ${devnull} || return 1 - - [ -e "${output_file}" ] || return 1 -} - -simple_decoder_vp8() { - if [ "$(vp8_decode_available)" = "yes" ]; then - simple_decoder "${VP8_IVF_FILE}" vp8 || return 1 - fi -} - -simple_decoder_vp9() { - if [ "$(vp9_decode_available)" = "yes" ]; then - simple_decoder "${VP9_IVF_FILE}" vp9 || return 1 - fi -} - -simple_decoder_tests="simple_decoder_vp8 - simple_decoder_vp9" - -run_tests simple_decoder_verify_environment "${simple_decoder_tests}" diff --git a/presentation/src/main/cpp/third_party/libvpx/test/simple_encode_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/simple_encode_test.cc deleted file mode 100644 index 0f8671ca..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/simple_encode_test.cc +++ /dev/null @@ -1,574 +0,0 @@ -/* - * Copyright (c) 2019 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include "gtest/gtest.h" -#include "test/video_source.h" -#include "vp9/simple_encode.h" - -namespace vp9 { -namespace { - -double GetBitrateInKbps(size_t bit_size, int num_frames, int frame_rate_num, - int frame_rate_den) { - return static_cast(bit_size) / num_frames * frame_rate_num / - frame_rate_den / 1000.0; -} - -// Returns the number of unit in size of 4. -// For example, if size is 7, return 2. -int GetNumUnit4x4(int size) { return (size + 3) >> 2; } - -class SimpleEncodeTest : public ::testing::Test { - protected: - const int width_ = 352; - const int height_ = 288; - const int frame_rate_num_ = 30; - const int frame_rate_den_ = 1; - const int target_bitrate_ = 1000; - const int num_frames_ = 17; - const int target_level_ = LEVEL_UNKNOWN; - const std::string in_file_path_str_ = - libvpx_test::GetDataPath() + "/bus_352x288_420_f20_b8.yuv"; -}; - -TEST_F(SimpleEncodeTest, ComputeFirstPassStats) { - SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, - target_bitrate_, num_frames_, target_level_, - in_file_path_str_.c_str()); - simple_encode.ComputeFirstPassStats(); - std::vector> frame_stats = - simple_encode.ObserveFirstPassStats(); - EXPECT_EQ(frame_stats.size(), static_cast(num_frames_)); - const size_t data_num = frame_stats[0].size(); - // Read ObserveFirstPassStats before changing FIRSTPASS_STATS. - EXPECT_EQ(data_num, static_cast(25)); - for (size_t i = 0; i < frame_stats.size(); ++i) { - EXPECT_EQ(frame_stats[i].size(), data_num); - // FIRSTPASS_STATS's first element is frame - EXPECT_EQ(frame_stats[i][0], i); - // FIRSTPASS_STATS's last element is count, and the count is 1 for single - // frame stats - EXPECT_EQ(frame_stats[i][data_num - 1], 1); - } -} - -TEST_F(SimpleEncodeTest, ObserveFirstPassMotionVectors) { - SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, - target_bitrate_, num_frames_, target_level_, - in_file_path_str_.c_str()); - simple_encode.ComputeFirstPassStats(); - std::vector> fps_motion_vectors = - simple_encode.ObserveFirstPassMotionVectors(); - EXPECT_EQ(fps_motion_vectors.size(), static_cast(num_frames_)); - const size_t num_blocks = ((width_ + 15) >> 4) * ((height_ + 15) >> 4); - EXPECT_EQ(num_blocks, fps_motion_vectors[0].size()); - for (size_t i = 0; i < fps_motion_vectors.size(); ++i) { - EXPECT_EQ(num_blocks, fps_motion_vectors[i].size()); - for (size_t j = 0; j < num_blocks; ++j) { - const int mv_count = fps_motion_vectors[i][j].mv_count; - const int ref_count = - (fps_motion_vectors[i][j].ref_frame[0] != kRefFrameTypeNone) + - (fps_motion_vectors[i][j].ref_frame[1] != kRefFrameTypeNone); - EXPECT_EQ(mv_count, ref_count); - } - } -} - -TEST_F(SimpleEncodeTest, GetCodingFrameNum) { - SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, - target_bitrate_, num_frames_, target_level_, - in_file_path_str_.c_str()); - simple_encode.ComputeFirstPassStats(); - const int num_coding_frames = simple_encode.GetCodingFrameNum(); - EXPECT_EQ(num_coding_frames, 19); -} - -TEST_F(SimpleEncodeTest, EncodeFrame) { - SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, - target_bitrate_, num_frames_, target_level_, - in_file_path_str_.c_str()); - simple_encode.ComputeFirstPassStats(); - int num_coding_frames = simple_encode.GetCodingFrameNum(); - EXPECT_GE(num_coding_frames, num_frames_); - simple_encode.StartEncode(); - size_t total_data_bit_size = 0; - int coded_show_frame_count = 0; - int frame_coding_index = 0; - while (coded_show_frame_count < num_frames_) { - const GroupOfPicture group_of_picture = - simple_encode.ObserveGroupOfPicture(); - const std::vector &encode_frame_list = - group_of_picture.encode_frame_list; - for (size_t group_index = 0; group_index < encode_frame_list.size(); - ++group_index) { - EncodeFrameResult encode_frame_result; - simple_encode.EncodeFrame(&encode_frame_result); - EXPECT_EQ(encode_frame_result.show_idx, - encode_frame_list[group_index].show_idx); - EXPECT_EQ(encode_frame_result.frame_type, - encode_frame_list[group_index].frame_type); - EXPECT_EQ(encode_frame_list[group_index].coding_index, - frame_coding_index); - EXPECT_GE(encode_frame_result.psnr, 34) - << "The psnr is supposed to be greater than 34 given the " - "target_bitrate 1000 kbps"; - EXPECT_EQ(encode_frame_result.ref_frame_info, - encode_frame_list[group_index].ref_frame_info); - total_data_bit_size += encode_frame_result.coding_data_bit_size; - ++frame_coding_index; - } - coded_show_frame_count += group_of_picture.show_frame_count; - } - const double bitrate = GetBitrateInKbps(total_data_bit_size, num_frames_, - frame_rate_num_, frame_rate_den_); - const double off_target_threshold = 150; - EXPECT_LE(fabs(target_bitrate_ - bitrate), off_target_threshold); - simple_encode.EndEncode(); -} - -TEST_F(SimpleEncodeTest, ObserveKeyFrameMap) { - SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, - target_bitrate_, num_frames_, target_level_, - in_file_path_str_.c_str()); - simple_encode.ComputeFirstPassStats(); - std::vector key_frame_map = simple_encode.ObserveKeyFrameMap(); - EXPECT_EQ(key_frame_map.size(), static_cast(num_frames_)); - simple_encode.StartEncode(); - int coded_show_frame_count = 0; - while (coded_show_frame_count < num_frames_) { - const GroupOfPicture group_of_picture = - simple_encode.ObserveGroupOfPicture(); - const std::vector &encode_frame_list = - group_of_picture.encode_frame_list; - for (size_t group_index = 0; group_index < encode_frame_list.size(); - ++group_index) { - EncodeFrameResult encode_frame_result; - simple_encode.EncodeFrame(&encode_frame_result); - if (encode_frame_result.frame_type == kFrameTypeKey) { - EXPECT_EQ(key_frame_map[encode_frame_result.show_idx], 1); - } else { - EXPECT_EQ(key_frame_map[encode_frame_result.show_idx], 0); - } - } - coded_show_frame_count += group_of_picture.show_frame_count; - } - simple_encode.EndEncode(); -} - -TEST_F(SimpleEncodeTest, EncodeFrameWithTargetFrameBits) { - SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, - target_bitrate_, num_frames_, target_level_, - in_file_path_str_.c_str()); - simple_encode.ComputeFirstPassStats(); - const int num_coding_frames = simple_encode.GetCodingFrameNum(); - simple_encode.StartEncode(); - for (int i = 0; i < num_coding_frames; ++i) { - EncodeFrameInfo encode_frame_info = simple_encode.GetNextEncodeFrameInfo(); - int target_frame_bits; - switch (encode_frame_info.frame_type) { - case kFrameTypeInter: target_frame_bits = 20000; break; - case kFrameTypeKey: - case kFrameTypeAltRef: - case kFrameTypeGolden: target_frame_bits = 100000; break; - case kFrameTypeOverlay: target_frame_bits = 2000; break; - default: target_frame_bits = 20000; - } - - double percent_diff = 15; - if (encode_frame_info.frame_type == kFrameTypeOverlay) { - percent_diff = 100; - } - EncodeFrameResult encode_frame_result; - simple_encode.EncodeFrameWithTargetFrameBits( - &encode_frame_result, target_frame_bits, percent_diff); - const int recode_count = encode_frame_result.recode_count; - // TODO(angiebird): Replace 7 by RATE_CTRL_MAX_RECODE_NUM - EXPECT_LE(recode_count, 7); - EXPECT_GE(recode_count, 1); - - const double diff = fabs((double)encode_frame_result.coding_data_bit_size - - target_frame_bits); - EXPECT_LE(diff * 100 / target_frame_bits, percent_diff); - } - simple_encode.EndEncode(); -} - -TEST_F(SimpleEncodeTest, EncodeFrameWithQuantizeIndex) { - SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, - target_bitrate_, num_frames_, target_level_, - in_file_path_str_.c_str()); - simple_encode.ComputeFirstPassStats(); - const int num_coding_frames = simple_encode.GetCodingFrameNum(); - simple_encode.StartEncode(); - for (int i = 0; i < num_coding_frames; ++i) { - const int assigned_quantize_index = 100 + i; - EncodeFrameResult encode_frame_result; - simple_encode.EncodeFrameWithQuantizeIndex(&encode_frame_result, - assigned_quantize_index); - EXPECT_EQ(encode_frame_result.quantize_index, assigned_quantize_index); - } - simple_encode.EndEncode(); -} - -// This test encodes the video using EncodeFrame(), where quantize indexes -// are selected by vp9 rate control. -// Encode stats and the quantize_indexes are collected. -// Then the test encodes the video again using EncodeFrameWithQuantizeIndex() -// using the quantize indexes collected from the first run. -// Then test whether the encode stats of the two encoding runs match. -TEST_F(SimpleEncodeTest, EncodeConsistencyTest) { - std::vector quantize_index_list; - std::vector ref_sse_list; - std::vector ref_psnr_list; - std::vector ref_bit_size_list; - std::vector ref_frame_type_list; - std::vector ref_show_idx_list; - { - // The first encode. - SimpleEncode simple_encode(width_, height_, frame_rate_num_, - frame_rate_den_, target_bitrate_, num_frames_, - target_level_, in_file_path_str_.c_str()); - simple_encode.ComputeFirstPassStats(); - const int num_coding_frames = simple_encode.GetCodingFrameNum(); - simple_encode.StartEncode(); - for (int i = 0; i < num_coding_frames; ++i) { - EncodeFrameResult encode_frame_result; - simple_encode.EncodeFrame(&encode_frame_result); - quantize_index_list.push_back(encode_frame_result.quantize_index); - ref_sse_list.push_back(encode_frame_result.sse); - ref_psnr_list.push_back(encode_frame_result.psnr); - ref_bit_size_list.push_back(encode_frame_result.coding_data_bit_size); - ref_frame_type_list.push_back(encode_frame_result.frame_type); - ref_show_idx_list.push_back(encode_frame_result.show_idx); - } - simple_encode.EndEncode(); - } - { - // The second encode with quantize index got from the first encode. - SimpleEncode simple_encode(width_, height_, frame_rate_num_, - frame_rate_den_, target_bitrate_, num_frames_, - target_level_, in_file_path_str_.c_str()); - simple_encode.ComputeFirstPassStats(); - const int num_coding_frames = simple_encode.GetCodingFrameNum(); - EXPECT_EQ(static_cast(num_coding_frames), - quantize_index_list.size()); - simple_encode.StartEncode(); - for (int i = 0; i < num_coding_frames; ++i) { - EncodeFrameResult encode_frame_result; - simple_encode.EncodeFrameWithQuantizeIndex(&encode_frame_result, - quantize_index_list[i]); - EXPECT_EQ(encode_frame_result.quantize_index, quantize_index_list[i]); - EXPECT_EQ(encode_frame_result.sse, ref_sse_list[i]); - EXPECT_DOUBLE_EQ(encode_frame_result.psnr, ref_psnr_list[i]); - EXPECT_EQ(encode_frame_result.coding_data_bit_size, ref_bit_size_list[i]); - EXPECT_EQ(encode_frame_result.frame_type, ref_frame_type_list[i]); - EXPECT_EQ(encode_frame_result.show_idx, ref_show_idx_list[i]); - } - simple_encode.EndEncode(); - } -} - -// Test the information (partition info and motion vector info) stored in -// encoder is the same between two encode runs. -TEST_F(SimpleEncodeTest, EncodeConsistencyTest2) { - const int num_rows_4x4 = GetNumUnit4x4(width_); - const int num_cols_4x4 = GetNumUnit4x4(height_); - const int num_units_4x4 = num_rows_4x4 * num_cols_4x4; - // The first encode. - SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, - target_bitrate_, num_frames_, target_level_, - in_file_path_str_.c_str()); - simple_encode.ComputeFirstPassStats(); - const int num_coding_frames = simple_encode.GetCodingFrameNum(); - std::vector partition_info_list(num_units_4x4 * - num_coding_frames); - std::vector motion_vector_info_list(num_units_4x4 * - num_coding_frames); - simple_encode.StartEncode(); - for (int i = 0; i < num_coding_frames; ++i) { - EncodeFrameResult encode_frame_result; - simple_encode.EncodeFrame(&encode_frame_result); - for (int j = 0; j < num_rows_4x4 * num_cols_4x4; ++j) { - partition_info_list[i * num_units_4x4 + j] = - encode_frame_result.partition_info[j]; - motion_vector_info_list[i * num_units_4x4 + j] = - encode_frame_result.motion_vector_info[j]; - } - } - simple_encode.EndEncode(); - // The second encode. - SimpleEncode simple_encode_2(width_, height_, frame_rate_num_, - frame_rate_den_, target_bitrate_, num_frames_, - target_level_, in_file_path_str_.c_str()); - simple_encode_2.ComputeFirstPassStats(); - const int num_coding_frames_2 = simple_encode_2.GetCodingFrameNum(); - simple_encode_2.StartEncode(); - for (int i = 0; i < num_coding_frames_2; ++i) { - EncodeFrameResult encode_frame_result; - simple_encode_2.EncodeFrame(&encode_frame_result); - for (int j = 0; j < num_rows_4x4 * num_cols_4x4; ++j) { - EXPECT_EQ(encode_frame_result.partition_info[j].row, - partition_info_list[i * num_units_4x4 + j].row); - EXPECT_EQ(encode_frame_result.partition_info[j].column, - partition_info_list[i * num_units_4x4 + j].column); - EXPECT_EQ(encode_frame_result.partition_info[j].row_start, - partition_info_list[i * num_units_4x4 + j].row_start); - EXPECT_EQ(encode_frame_result.partition_info[j].column_start, - partition_info_list[i * num_units_4x4 + j].column_start); - EXPECT_EQ(encode_frame_result.partition_info[j].width, - partition_info_list[i * num_units_4x4 + j].width); - EXPECT_EQ(encode_frame_result.partition_info[j].height, - partition_info_list[i * num_units_4x4 + j].height); - - EXPECT_EQ(encode_frame_result.motion_vector_info[j].mv_count, - motion_vector_info_list[i * num_units_4x4 + j].mv_count); - EXPECT_EQ(encode_frame_result.motion_vector_info[j].ref_frame[0], - motion_vector_info_list[i * num_units_4x4 + j].ref_frame[0]); - EXPECT_EQ(encode_frame_result.motion_vector_info[j].ref_frame[1], - motion_vector_info_list[i * num_units_4x4 + j].ref_frame[1]); - EXPECT_EQ(encode_frame_result.motion_vector_info[j].mv_row[0], - motion_vector_info_list[i * num_units_4x4 + j].mv_row[0]); - EXPECT_EQ(encode_frame_result.motion_vector_info[j].mv_column[0], - motion_vector_info_list[i * num_units_4x4 + j].mv_column[0]); - EXPECT_EQ(encode_frame_result.motion_vector_info[j].mv_row[1], - motion_vector_info_list[i * num_units_4x4 + j].mv_row[1]); - EXPECT_EQ(encode_frame_result.motion_vector_info[j].mv_column[1], - motion_vector_info_list[i * num_units_4x4 + j].mv_column[1]); - } - } - simple_encode_2.EndEncode(); -} - -// Test the information stored in encoder is the same between two encode runs. -TEST_F(SimpleEncodeTest, EncodeConsistencyTest3) { - std::vector quantize_index_list; - const int num_rows_4x4 = GetNumUnit4x4(width_); - const int num_cols_4x4 = GetNumUnit4x4(height_); - const int num_units_4x4 = num_rows_4x4 * num_cols_4x4; - // The first encode. - SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, - target_bitrate_, num_frames_, target_level_, - in_file_path_str_.c_str()); - simple_encode.ComputeFirstPassStats(); - const int num_coding_frames = simple_encode.GetCodingFrameNum(); - std::vector partition_info_list(num_units_4x4 * - num_coding_frames); - simple_encode.StartEncode(); - for (int i = 0; i < num_coding_frames; ++i) { - EncodeFrameResult encode_frame_result; - simple_encode.EncodeFrame(&encode_frame_result); - quantize_index_list.push_back(encode_frame_result.quantize_index); - for (int j = 0; j < num_rows_4x4 * num_cols_4x4; ++j) { - partition_info_list[i * num_units_4x4 + j] = - encode_frame_result.partition_info[j]; - } - } - simple_encode.EndEncode(); - // The second encode. - SimpleEncode simple_encode_2(width_, height_, frame_rate_num_, - frame_rate_den_, target_bitrate_, num_frames_, - target_level_, in_file_path_str_.c_str()); - simple_encode_2.ComputeFirstPassStats(); - const int num_coding_frames_2 = simple_encode_2.GetCodingFrameNum(); - simple_encode_2.StartEncode(); - for (int i = 0; i < num_coding_frames_2; ++i) { - EncodeFrameResult encode_frame_result; - simple_encode_2.EncodeFrameWithQuantizeIndex(&encode_frame_result, - quantize_index_list[i]); - for (int j = 0; j < num_rows_4x4 * num_cols_4x4; ++j) { - EXPECT_EQ(encode_frame_result.partition_info[j].row, - partition_info_list[i * num_units_4x4 + j].row); - EXPECT_EQ(encode_frame_result.partition_info[j].column, - partition_info_list[i * num_units_4x4 + j].column); - EXPECT_EQ(encode_frame_result.partition_info[j].row_start, - partition_info_list[i * num_units_4x4 + j].row_start); - EXPECT_EQ(encode_frame_result.partition_info[j].column_start, - partition_info_list[i * num_units_4x4 + j].column_start); - EXPECT_EQ(encode_frame_result.partition_info[j].width, - partition_info_list[i * num_units_4x4 + j].width); - EXPECT_EQ(encode_frame_result.partition_info[j].height, - partition_info_list[i * num_units_4x4 + j].height); - } - } - simple_encode_2.EndEncode(); -} - -// Encode with default VP9 decision first. -// Get QPs and arf locations from the first encode. -// Set external arfs and QPs for the second encode. -// Expect to get matched results. -TEST_F(SimpleEncodeTest, EncodeConsistencySetExternalGroupOfPicturesMap) { - std::vector quantize_index_list; - std::vector ref_sse_list; - std::vector ref_psnr_list; - std::vector ref_bit_size_list; - std::vector gop_map(num_frames_, 0); - { - // The first encode. - SimpleEncode simple_encode(width_, height_, frame_rate_num_, - frame_rate_den_, target_bitrate_, num_frames_, - target_level_, in_file_path_str_.c_str()); - simple_encode.ComputeFirstPassStats(); - simple_encode.StartEncode(); - - int coded_show_frame_count = 0; - while (coded_show_frame_count < num_frames_) { - const GroupOfPicture group_of_picture = - simple_encode.ObserveGroupOfPicture(); - gop_map[coded_show_frame_count] |= kGopMapFlagStart; - if (group_of_picture.use_alt_ref) { - gop_map[coded_show_frame_count] |= kGopMapFlagUseAltRef; - } - const std::vector &encode_frame_list = - group_of_picture.encode_frame_list; - for (size_t group_index = 0; group_index < encode_frame_list.size(); - ++group_index) { - EncodeFrameResult encode_frame_result; - simple_encode.EncodeFrame(&encode_frame_result); - quantize_index_list.push_back(encode_frame_result.quantize_index); - ref_sse_list.push_back(encode_frame_result.sse); - ref_psnr_list.push_back(encode_frame_result.psnr); - ref_bit_size_list.push_back(encode_frame_result.coding_data_bit_size); - } - coded_show_frame_count += group_of_picture.show_frame_count; - } - simple_encode.EndEncode(); - } - { - // The second encode with quantize index got from the first encode. - // The external arfs are the same as the first encode. - SimpleEncode simple_encode(width_, height_, frame_rate_num_, - frame_rate_den_, target_bitrate_, num_frames_, - target_level_, in_file_path_str_.c_str()); - simple_encode.ComputeFirstPassStats(); - simple_encode.SetExternalGroupOfPicturesMap(gop_map.data(), gop_map.size()); - const int num_coding_frames = simple_encode.GetCodingFrameNum(); - EXPECT_EQ(static_cast(num_coding_frames), - quantize_index_list.size()); - simple_encode.StartEncode(); - for (int i = 0; i < num_coding_frames; ++i) { - EncodeFrameResult encode_frame_result; - simple_encode.EncodeFrameWithQuantizeIndex(&encode_frame_result, - quantize_index_list[i]); - EXPECT_EQ(encode_frame_result.quantize_index, quantize_index_list[i]); - EXPECT_EQ(encode_frame_result.sse, ref_sse_list[i]); - EXPECT_DOUBLE_EQ(encode_frame_result.psnr, ref_psnr_list[i]); - EXPECT_EQ(encode_frame_result.coding_data_bit_size, ref_bit_size_list[i]); - } - simple_encode.EndEncode(); - } -} - -TEST_F(SimpleEncodeTest, SetExternalGroupOfPicturesMap) { - SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, - target_bitrate_, num_frames_, target_level_, - in_file_path_str_.c_str()); - simple_encode.ComputeFirstPassStats(); - - std::vector gop_map(num_frames_, 0); - - // Should be the first gop group. - gop_map[0] = 0; - - // Second gop group with an alt ref. - gop_map[5] |= kGopMapFlagStart | kGopMapFlagUseAltRef; - - // Third gop group without an alt ref. - gop_map[10] |= kGopMapFlagStart; - - // Last gop group. - gop_map[14] |= kGopMapFlagStart | kGopMapFlagUseAltRef; - - simple_encode.SetExternalGroupOfPicturesMap(gop_map.data(), gop_map.size()); - - std::vector observed_gop_map = - simple_encode.ObserveExternalGroupOfPicturesMap(); - - // First gop group. - // There is always a key frame at show_idx 0 and key frame should always be - // the start of a gop. We expect ObserveExternalGroupOfPicturesMap() will - // insert an extra gop start here. - EXPECT_EQ(observed_gop_map[0], kGopMapFlagStart | kGopMapFlagUseAltRef); - - // Second gop group with an alt ref. - EXPECT_EQ(observed_gop_map[5], kGopMapFlagStart | kGopMapFlagUseAltRef); - - // Third gop group without an alt ref. - EXPECT_EQ(observed_gop_map[10], kGopMapFlagStart); - - // Last gop group. The last gop is not supposed to use an alt ref. We expect - // ObserveExternalGroupOfPicturesMap() will remove the alt ref flag here. - EXPECT_EQ(observed_gop_map[14], kGopMapFlagStart); - - int ref_gop_show_frame_count_list[4] = { 5, 5, 4, 3 }; - size_t ref_gop_coded_frame_count_list[4] = { 6, 6, 4, 3 }; - int gop_count = 0; - - simple_encode.StartEncode(); - int coded_show_frame_count = 0; - while (coded_show_frame_count < num_frames_) { - const GroupOfPicture group_of_picture = - simple_encode.ObserveGroupOfPicture(); - const std::vector &encode_frame_list = - group_of_picture.encode_frame_list; - EXPECT_EQ(encode_frame_list.size(), - ref_gop_coded_frame_count_list[gop_count]); - EXPECT_EQ(group_of_picture.show_frame_count, - ref_gop_show_frame_count_list[gop_count]); - for (size_t group_index = 0; group_index < encode_frame_list.size(); - ++group_index) { - EncodeFrameResult encode_frame_result; - simple_encode.EncodeFrame(&encode_frame_result); - } - coded_show_frame_count += group_of_picture.show_frame_count; - ++gop_count; - } - EXPECT_EQ(gop_count, 4); - simple_encode.EndEncode(); -} - -TEST_F(SimpleEncodeTest, GetEncodeFrameInfo) { - // Makes sure that the encode_frame_info obtained from GetEncodeFrameInfo() - // matches the counterpart in encode_frame_result obtained from EncodeFrame() - SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, - target_bitrate_, num_frames_, target_level_, - in_file_path_str_.c_str()); - simple_encode.ComputeFirstPassStats(); - const int num_coding_frames = simple_encode.GetCodingFrameNum(); - simple_encode.StartEncode(); - for (int i = 0; i < num_coding_frames; ++i) { - EncodeFrameInfo encode_frame_info = simple_encode.GetNextEncodeFrameInfo(); - EncodeFrameResult encode_frame_result; - simple_encode.EncodeFrame(&encode_frame_result); - EXPECT_EQ(encode_frame_info.show_idx, encode_frame_result.show_idx); - EXPECT_EQ(encode_frame_info.frame_type, encode_frame_result.frame_type); - } - simple_encode.EndEncode(); -} - -TEST_F(SimpleEncodeTest, GetFramePixelCount) { - SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, - target_bitrate_, num_frames_, target_level_, - in_file_path_str_.c_str()); - EXPECT_EQ(simple_encode.GetFramePixelCount(), - static_cast(width_ * height_ * 3 / 2)); -} - -} // namespace -} // namespace vp9 - -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/test/simple_encoder.sh b/presentation/src/main/cpp/third_party/libvpx/test/simple_encoder.sh deleted file mode 100644 index dc7f46ff..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/simple_encoder.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2014 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## This file tests the libvpx simple_encoder example. To add new tests to this -## file, do the following: -## 1. Write a shell function (this is your test). -## 2. Add the function to simple_encoder_tests (on a new line). -## -. $(dirname $0)/tools_common.sh - -# Environment check: $YUV_RAW_INPUT is required. -simple_encoder_verify_environment() { - if [ ! -e "${YUV_RAW_INPUT}" ]; then - echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH." - return 1 - fi -} - -# Runs simple_encoder using the codec specified by $1 with a frame limit of 100. -simple_encoder() { - local encoder="${LIBVPX_BIN_PATH}/simple_encoder${VPX_TEST_EXE_SUFFIX}" - local codec="$1" - local output_file="${VPX_TEST_OUTPUT_DIR}/simple_encoder_${codec}.ivf" - - if [ ! -x "${encoder}" ]; then - elog "${encoder} does not exist or is not executable." - return 1 - fi - - eval "${VPX_TEST_PREFIX}" "${encoder}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \ - "${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" 9999 0 100 \ - ${devnull} || return 1 - - [ -e "${output_file}" ] || return 1 -} - -simple_encoder_vp8() { - if [ "$(vp8_encode_available)" = "yes" ]; then - simple_encoder vp8 || return 1 - fi -} - -simple_encoder_vp9() { - if [ "$(vp9_encode_available)" = "yes" ]; then - simple_encoder vp9 || return 1 - fi -} - -simple_encoder_tests="simple_encoder_vp8 - simple_encoder_vp9" - -run_tests simple_encoder_verify_environment "${simple_encoder_tests}" diff --git a/presentation/src/main/cpp/third_party/libvpx/test/stress.sh b/presentation/src/main/cpp/third_party/libvpx/test/stress.sh deleted file mode 100644 index ba79a52a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/stress.sh +++ /dev/null @@ -1,183 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2016 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## This file performs a stress test. It runs (STRESS_ONEPASS_MAX_JOBS, -## default=5) one, (STRESS_TWOPASS_MAX_JOBS, default=5) two pass & -## (STRESS_RT_MAX_JOBS, default=5) encodes and (STRESS__DECODE_MAX_JOBS, -## default=30) decodes in parallel. - -. $(dirname $0)/tools_common.sh - -YUV="${LIBVPX_TEST_DATA_PATH}/niklas_1280_720_30.yuv" -VP8="${LIBVPX_TEST_DATA_PATH}/tos_vp8.webm" -VP9="${LIBVPX_TEST_DATA_PATH}/vp90-2-sintel_1920x818_tile_1x4_fpm_2279kbps.webm" -DATA_URL="https://storage.googleapis.com/downloads.webmproject.org/test_data/libvpx/" -SHA1_FILE="$(dirname $0)/test-data.sha1" - -# Set sha1sum to proper sha program (sha1sum, shasum, sha1). This code is -# cribbed from libs.mk. -[ -x "$(which sha1sum)" ] && sha1sum=sha1sum -[ -x "$(which shasum)" ] && sha1sum=shasum -[ -x "$(which sha1)" ] && sha1sum=sha1 - -# Download a file from the url and check its sha1sum. -download_and_check_file() { - # Get the file from the file path. - local root="${1#${LIBVPX_TEST_DATA_PATH}/}" - - # Download the file using curl. Trap to insure non partial file. - (trap "rm -f $1" INT TERM \ - && eval "curl --retry 1 -L -o $1 ${DATA_URL}${root} ${devnull}") - - # Check the sha1 sum of the file. - if [ -n "${sha1sum}" ]; then - set -e - grep ${root} ${SHA1_FILE} \ - | (cd ${LIBVPX_TEST_DATA_PATH}; ${sha1sum} -c); - fi -} - -# Environment check: Make sure input is available. -stress_verify_environment() { - if [ ! -e "${SHA1_FILE}" ] ; then - echo "Missing ${SHA1_FILE}" - return 1 - fi - for file in "${YUV}" "${VP8}" "${VP9}"; do - if [ ! -e "${file}" ] ; then - download_and_check_file "${file}" || return 1 - fi - done - if [ ! -e "${YUV}" ] || [ ! -e "${VP8}" ] || [ ! -e "${VP9}" ] ; then - elog "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH." - return 1 - fi - if [ -z "$(vpx_tool_path vpxenc)" ]; then - elog "vpxenc not found. It must exist in LIBVPX_BIN_PATH or its parent." - return 1 - fi - if [ -z "$(vpx_tool_path vpxdec)" ]; then - elog "vpxdec not found. It must exist in LIBVPX_BIN_PATH or its parent." - return 1 - fi -} - -# This function runs tests on libvpx that run multiple encodes and decodes -# in parallel in hopes of catching synchronization and/or threading issues. -stress() { - local decoder="$(vpx_tool_path vpxdec)" - local encoder="$(vpx_tool_path vpxenc)" - local codec="$1" - local webm="$2" - local decode_count="$3" - local threads="$4" - local enc_args="$5" - local pids="" - local rt_max_jobs=${STRESS_RT_MAX_JOBS:-5} - local onepass_max_jobs=${STRESS_ONEPASS_MAX_JOBS:-5} - local twopass_max_jobs=${STRESS_TWOPASS_MAX_JOBS:-5} - - # Enable job control, so we can run multiple processes. - set -m - - # Start $onepass_max_jobs encode jobs in parallel. - for i in $(seq ${onepass_max_jobs}); do - bitrate=$(($i * 20 + 300)) - eval "${VPX_TEST_PREFIX}" "${encoder}" "--codec=${codec} -w 1280 -h 720" \ - "${YUV}" "-t ${threads} --limit=150 --test-decode=fatal --passes=1" \ - "--target-bitrate=${bitrate} -o ${VPX_TEST_OUTPUT_DIR}/${i}.1pass.webm" \ - "${enc_args}" ${devnull} & - pids="${pids} $!" - done - - # Start $twopass_max_jobs encode jobs in parallel. - for i in $(seq ${twopass_max_jobs}); do - bitrate=$(($i * 20 + 300)) - eval "${VPX_TEST_PREFIX}" "${encoder}" "--codec=${codec} -w 1280 -h 720" \ - "${YUV}" "-t ${threads} --limit=150 --test-decode=fatal --passes=2" \ - "--target-bitrate=${bitrate} -o ${VPX_TEST_OUTPUT_DIR}/${i}.2pass.webm" \ - "${enc_args}" ${devnull} & - pids="${pids} $!" - done - - # Start $rt_max_jobs rt encode jobs in parallel. - for i in $(seq ${rt_max_jobs}); do - bitrate=$(($i * 20 + 300)) - eval "${VPX_TEST_PREFIX}" "${encoder}" "--codec=${codec} -w 1280 -h 720" \ - "${YUV}" "-t ${threads} --limit=150 --test-decode=fatal " \ - "--target-bitrate=${bitrate} --lag-in-frames=0 --error-resilient=1" \ - "--kf-min-dist=3000 --kf-max-dist=3000 --cpu-used=-6 --static-thresh=1" \ - "--end-usage=cbr --min-q=2 --max-q=56 --undershoot-pct=100" \ - "--overshoot-pct=15 --buf-sz=1000 --buf-initial-sz=500" \ - "--buf-optimal-sz=600 --max-intra-rate=900 --resize-allowed=0" \ - "--drop-frame=0 --passes=1 --rt --noise-sensitivity=4" \ - "-o ${VPX_TEST_OUTPUT_DIR}/${i}.rt.webm" ${devnull} & - pids="${pids} $!" - done - - # Start $decode_count decode jobs in parallel. - for i in $(seq "${decode_count}"); do - eval "${decoder}" "-t ${threads}" "${webm}" "--noblit" ${devnull} & - pids="${pids} $!" - done - - # Wait for all parallel jobs to finish. - fail=0 - for job in "${pids}"; do - wait $job || fail=$(($fail + 1)) - done - return $fail -} - -vp8_stress_test() { - local vp8_max_jobs=${STRESS_VP8_DECODE_MAX_JOBS:-40} - if [ "$(vp8_decode_available)" = "yes" -a \ - "$(vp8_encode_available)" = "yes" ]; then - stress vp8 "${VP8}" "${vp8_max_jobs}" 4 - fi -} - -vp8_stress_test_token_parititions() { - local vp8_max_jobs=${STRESS_VP8_DECODE_MAX_JOBS:-40} - if [ "$(vp8_decode_available)" = "yes" -a \ - "$(vp8_encode_available)" = "yes" ]; then - for threads in 2 4 8; do - for token_partitions in 1 2 3; do - stress vp8 "${VP8}" "${vp8_max_jobs}" ${threads} \ - "--token-parts=$token_partitions" - done - done - fi -} - -vp9_stress() { - local vp9_max_jobs=${STRESS_VP9_DECODE_MAX_JOBS:-25} - - if [ "$(vp9_decode_available)" = "yes" -a \ - "$(vp9_encode_available)" = "yes" ]; then - stress vp9 "${VP9}" "${vp9_max_jobs}" "$@" - fi -} - -vp9_stress_test() { - for threads in 4 8 64; do - vp9_stress "$threads" "--row-mt=0" - done -} - -vp9_stress_test_row_mt() { - for threads in 4 8 64; do - vp9_stress "$threads" "--row-mt=1" - done -} - -run_tests stress_verify_environment \ - "vp8_stress_test vp8_stress_test_token_parititions - vp9_stress_test vp9_stress_test_row_mt" diff --git a/presentation/src/main/cpp/third_party/libvpx/test/sum_squares_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/sum_squares_test.cc deleted file mode 100644 index 11c92e56..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/sum_squares_test.cc +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "test/acm_random.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/vpx_timer.h" - -using libvpx_test::ACMRandom; -using ::testing::Combine; -using ::testing::Range; -using ::testing::ValuesIn; - -namespace { -const int kNumIterations = 10000; - -typedef uint64_t (*SSI16Func)(const int16_t *src, int stride, int size); -typedef std::tuple SumSquaresParam; - -class SumSquaresTest : public ::testing::TestWithParam { - public: - ~SumSquaresTest() override = default; - void SetUp() override { - ref_func_ = GET_PARAM(0); - tst_func_ = GET_PARAM(1); - } - - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - SSI16Func ref_func_; - SSI16Func tst_func_; -}; -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SumSquaresTest); - -TEST_P(SumSquaresTest, OperationCheck) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - DECLARE_ALIGNED(16, int16_t, src[256 * 256]); - const int msb = 11; // Up to 12 bit input - const int limit = 1 << (msb + 1); - - for (int k = 0; k < kNumIterations; k++) { - const int size = 4 << rnd(6); // Up to 128x128 - int stride = 4 << rnd(7); // Up to 256 stride - while (stride < size) { // Make sure it's valid - stride = 4 << rnd(7); - } - - for (int i = 0; i < size; ++i) { - for (int j = 0; j < size; ++j) { - src[i * stride + j] = rnd(2) ? rnd(limit) : -rnd(limit); - } - } - - const uint64_t res_ref = ref_func_(src, stride, size); - uint64_t res_tst; - ASM_REGISTER_STATE_CHECK(res_tst = tst_func_(src, stride, size)); - - ASSERT_EQ(res_ref, res_tst) << "Error: Sum Squares Test" - << " C output does not match optimized output."; - } -} - -TEST_P(SumSquaresTest, ExtremeValues) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - DECLARE_ALIGNED(16, int16_t, src[256 * 256]); - const int msb = 11; // Up to 12 bit input - const int limit = 1 << (msb + 1); - - for (int k = 0; k < kNumIterations; k++) { - const int size = 4 << rnd(6); // Up to 128x128 - int stride = 4 << rnd(7); // Up to 256 stride - while (stride < size) { // Make sure it's valid - stride = 4 << rnd(7); - } - - const int val = rnd(2) ? limit - 1 : -(limit - 1); - for (int i = 0; i < size; ++i) { - for (int j = 0; j < size; ++j) { - src[i * stride + j] = val; - } - } - - const uint64_t res_ref = ref_func_(src, stride, size); - uint64_t res_tst; - ASM_REGISTER_STATE_CHECK(res_tst = tst_func_(src, stride, size)); - - ASSERT_EQ(res_ref, res_tst) << "Error: Sum Squares Test" - << " C output does not match optimized output."; - } -} - -using std::make_tuple; - -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P( - NEON, SumSquaresTest, - ::testing::Values(make_tuple(&vpx_sum_squares_2d_i16_c, - &vpx_sum_squares_2d_i16_neon))); -#endif // HAVE_NEON - -#if HAVE_SVE -INSTANTIATE_TEST_SUITE_P( - SVE, SumSquaresTest, - ::testing::Values(make_tuple(&vpx_sum_squares_2d_i16_c, - &vpx_sum_squares_2d_i16_sve))); -#endif // HAVE_SVE - -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P( - SSE2, SumSquaresTest, - ::testing::Values(make_tuple(&vpx_sum_squares_2d_i16_c, - &vpx_sum_squares_2d_i16_sse2))); -#endif // HAVE_SSE2 - -#if HAVE_MSA -INSTANTIATE_TEST_SUITE_P( - MSA, SumSquaresTest, - ::testing::Values(make_tuple(&vpx_sum_squares_2d_i16_c, - &vpx_sum_squares_2d_i16_msa))); -#endif // HAVE_MSA - -typedef int64_t (*SSEFunc)(const uint8_t *a, int a_stride, const uint8_t *b, - int b_stride, int width, int height); - -struct TestSSEFuncs { - TestSSEFuncs(SSEFunc ref = nullptr, SSEFunc tst = nullptr, int depth = 0) - : ref_func(ref), tst_func(tst), bit_depth(depth) {} - SSEFunc ref_func; // Pointer to reference function - SSEFunc tst_func; // Pointer to tested function - int bit_depth; -}; - -typedef std::tuple SSETestParam; - -class SSETest : public ::testing::TestWithParam { - public: - ~SSETest() override = default; - void SetUp() override { - params_ = GET_PARAM(0); - width_ = GET_PARAM(1); - is_hbd_ = -#if CONFIG_VP9_HIGHBITDEPTH - params_.ref_func == vpx_highbd_sse_c; -#else - false; -#endif - rnd_.Reset(ACMRandom::DeterministicSeed()); - src_ = reinterpret_cast(vpx_memalign(32, 256 * 256 * 2)); - ref_ = reinterpret_cast(vpx_memalign(32, 256 * 256 * 2)); - ASSERT_NE(src_, nullptr); - ASSERT_NE(ref_, nullptr); - } - - void TearDown() override { - vpx_free(src_); - vpx_free(ref_); - } - void RunTest(bool is_random, int width, int height, int run_times); - - void GenRandomData(int width, int height, int stride) { - uint16_t *src16 = reinterpret_cast(src_); - uint16_t *ref16 = reinterpret_cast(ref_); - const int msb = 11; // Up to 12 bit input - const int limit = 1 << (msb + 1); - for (int ii = 0; ii < height; ii++) { - for (int jj = 0; jj < width; jj++) { - if (!is_hbd_) { - src_[ii * stride + jj] = rnd_.Rand8(); - ref_[ii * stride + jj] = rnd_.Rand8(); - } else { - src16[ii * stride + jj] = rnd_(limit); - ref16[ii * stride + jj] = rnd_(limit); - } - } - } - } - - void GenExtremeData(int width, int height, int stride, uint8_t *data, - int16_t val) { - uint16_t *data16 = reinterpret_cast(data); - for (int ii = 0; ii < height; ii++) { - for (int jj = 0; jj < width; jj++) { - if (!is_hbd_) { - data[ii * stride + jj] = static_cast(val); - } else { - data16[ii * stride + jj] = val; - } - } - } - } - - protected: - bool is_hbd_; - int width_; - TestSSEFuncs params_; - uint8_t *src_; - uint8_t *ref_; - ACMRandom rnd_; -}; -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SSETest); - -void SSETest::RunTest(bool is_random, int width, int height, int run_times) { - int failed = 0; - vpx_usec_timer ref_timer, test_timer; - for (int k = 0; k < 3; k++) { - int stride = 4 << rnd_(7); // Up to 256 stride - while (stride < width) { // Make sure it's valid - stride = 4 << rnd_(7); - } - if (is_random) { - GenRandomData(width, height, stride); - } else { - const int msb = is_hbd_ ? 12 : 8; // Up to 12 bit input - const int limit = (1 << msb) - 1; - if (k == 0) { - GenExtremeData(width, height, stride, src_, 0); - GenExtremeData(width, height, stride, ref_, limit); - } else { - GenExtremeData(width, height, stride, src_, limit); - GenExtremeData(width, height, stride, ref_, 0); - } - } - int64_t res_ref, res_tst; - uint8_t *src = src_; - uint8_t *ref = ref_; -#if CONFIG_VP9_HIGHBITDEPTH - if (is_hbd_) { - src = CONVERT_TO_BYTEPTR(src_); - ref = CONVERT_TO_BYTEPTR(ref_); - } -#endif - res_ref = params_.ref_func(src, stride, ref, stride, width, height); - res_tst = params_.tst_func(src, stride, ref, stride, width, height); - if (run_times > 1) { - vpx_usec_timer_start(&ref_timer); - for (int j = 0; j < run_times; j++) { - params_.ref_func(src, stride, ref, stride, width, height); - } - vpx_usec_timer_mark(&ref_timer); - const int elapsed_time_c = - static_cast(vpx_usec_timer_elapsed(&ref_timer)); - - vpx_usec_timer_start(&test_timer); - for (int j = 0; j < run_times; j++) { - params_.tst_func(src, stride, ref, stride, width, height); - } - vpx_usec_timer_mark(&test_timer); - const int elapsed_time_simd = - static_cast(vpx_usec_timer_elapsed(&test_timer)); - - printf( - "c_time=%d \t simd_time=%d \t " - "gain=%d\n", - elapsed_time_c, elapsed_time_simd, - (elapsed_time_c / elapsed_time_simd)); - } else { - if (!failed) { - failed = res_ref != res_tst; - EXPECT_EQ(res_ref, res_tst) - << "Error:" << (is_hbd_ ? "hbd " : " ") << k << " SSE Test [" - << width << "x" << height - << "] C output does not match optimized output."; - } - } - } -} - -TEST_P(SSETest, OperationCheck) { - for (int height = 4; height <= 128; height += 4) { - RunTest(true, width_, height, 1); // GenRandomData - } -} - -TEST_P(SSETest, ExtremeValues) { - for (int height = 4; height <= 128; height += 4) { - RunTest(false, width_, height, 1); - } -} - -TEST_P(SSETest, DISABLED_Speed) { - for (int height = 4; height <= 128; height += 4) { - RunTest(true, width_, height, 100); - } -} - -#if HAVE_NEON -TestSSEFuncs sse_neon[] = { - TestSSEFuncs(&vpx_sse_c, &vpx_sse_neon), -#if CONFIG_VP9_HIGHBITDEPTH - TestSSEFuncs(&vpx_highbd_sse_c, &vpx_highbd_sse_neon) -#endif -}; -INSTANTIATE_TEST_SUITE_P(NEON, SSETest, - Combine(ValuesIn(sse_neon), Range(4, 129, 4))); -#endif // HAVE_NEON - -#if HAVE_NEON_DOTPROD -TestSSEFuncs sse_neon_dotprod[] = { - TestSSEFuncs(&vpx_sse_c, &vpx_sse_neon_dotprod), -}; -INSTANTIATE_TEST_SUITE_P(NEON_DOTPROD, SSETest, - Combine(ValuesIn(sse_neon_dotprod), Range(4, 129, 4))); -#endif // HAVE_NEON_DOTPROD - -#if HAVE_SSE4_1 -TestSSEFuncs sse_sse4[] = { - TestSSEFuncs(&vpx_sse_c, &vpx_sse_sse4_1), -#if CONFIG_VP9_HIGHBITDEPTH - TestSSEFuncs(&vpx_highbd_sse_c, &vpx_highbd_sse_sse4_1) -#endif -}; -INSTANTIATE_TEST_SUITE_P(SSE4_1, SSETest, - Combine(ValuesIn(sse_sse4), Range(4, 129, 4))); -#endif // HAVE_SSE4_1 - -#if HAVE_AVX2 - -TestSSEFuncs sse_avx2[] = { - TestSSEFuncs(&vpx_sse_c, &vpx_sse_avx2), -#if CONFIG_VP9_HIGHBITDEPTH - TestSSEFuncs(&vpx_highbd_sse_c, &vpx_highbd_sse_avx2) -#endif -}; -INSTANTIATE_TEST_SUITE_P(AVX2, SSETest, - Combine(ValuesIn(sse_avx2), Range(4, 129, 4))); -#endif // HAVE_AVX2 -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/superframe_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/superframe_test.cc deleted file mode 100644 index c761f0a1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/superframe_test.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include - -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" - -namespace { - -const int kTestMode = 0; - -typedef std::tuple SuperframeTestParam; - -class SuperframeTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWithParam { - protected: - SuperframeTest() - : EncoderTest(GET_PARAM(0)), modified_buf_(nullptr), last_sf_pts_(0) {} - ~SuperframeTest() override = default; - - void SetUp() override { - InitializeConfig(); - const SuperframeTestParam input = GET_PARAM(1); - const libvpx_test::TestMode mode = std::get(input); - SetMode(mode); - sf_count_ = 0; - sf_count_max_ = INT_MAX; - } - - void TearDown() override { delete[] modified_buf_; } - - void PreEncodeFrameHook(libvpx_test::VideoSource *video, - libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); - } - } - - const vpx_codec_cx_pkt_t *MutateEncoderOutputHook( - const vpx_codec_cx_pkt_t *pkt) override { - if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return pkt; - - const uint8_t *buffer = reinterpret_cast(pkt->data.frame.buf); - const uint8_t marker = buffer[pkt->data.frame.sz - 1]; - const int frames = (marker & 0x7) + 1; - const int mag = ((marker >> 3) & 3) + 1; - const unsigned int index_sz = 2 + mag * frames; - if ((marker & 0xe0) == 0xc0 && pkt->data.frame.sz >= index_sz && - buffer[pkt->data.frame.sz - index_sz] == marker) { - // frame is a superframe. strip off the index. - if (modified_buf_) delete[] modified_buf_; - modified_buf_ = new uint8_t[pkt->data.frame.sz - index_sz]; - memcpy(modified_buf_, pkt->data.frame.buf, pkt->data.frame.sz - index_sz); - modified_pkt_ = *pkt; - modified_pkt_.data.frame.buf = modified_buf_; - modified_pkt_.data.frame.sz -= index_sz; - - sf_count_++; - last_sf_pts_ = pkt->data.frame.pts; - return &modified_pkt_; - } - - // Make sure we do a few frames after the last SF - abort_ |= - sf_count_ > sf_count_max_ && pkt->data.frame.pts - last_sf_pts_ >= 5; - return pkt; - } - - int sf_count_; - int sf_count_max_; - vpx_codec_cx_pkt_t modified_pkt_; - uint8_t *modified_buf_; - vpx_codec_pts_t last_sf_pts_; -}; - -TEST_P(SuperframeTest, TestSuperframeIndexIsOptional) { - sf_count_max_ = 0; // early exit on successful test. - cfg_.g_lag_in_frames = 25; - - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 40); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - EXPECT_EQ(sf_count_, 1); -} - -VP9_INSTANTIATE_TEST_SUITE( - SuperframeTest, - ::testing::Combine(::testing::Values(::libvpx_test::kTwoPassGood), - ::testing::Values(0))); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/svc_datarate_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/svc_datarate_test.cc deleted file mode 100644 index 0ff0c8a5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/svc_datarate_test.cc +++ /dev/null @@ -1,1796 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "./vpx_config.h" -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/svc_test.h" -#include "test/util.h" -#include "test/y4m_video_source.h" -#include "vp9/common/vp9_onyxc_int.h" -#include "vpx/vpx_codec.h" -#include "vpx_ports/bitops.h" - -namespace svc_test { -namespace { - -typedef enum { - // Inter-layer prediction is on on all frames. - INTER_LAYER_PRED_ON, - // Inter-layer prediction is off on all frames. - INTER_LAYER_PRED_OFF, - // Inter-layer prediction is off on non-key frames and non-sync frames. - INTER_LAYER_PRED_OFF_NONKEY, - // Inter-layer prediction is on on all frames, but constrained such - // that any layer S (> 0) can only predict from previous spatial - // layer S-1, from the same superframe. - INTER_LAYER_PRED_ON_CONSTRAINED -} INTER_LAYER_PRED; - -class DatarateOnePassCbrSvc : public OnePassCbrSvc { - public: - explicit DatarateOnePassCbrSvc(const ::libvpx_test::CodecFactory *codec) - : OnePassCbrSvc(codec) { - inter_layer_pred_mode_ = 0; - } - - protected: - ~DatarateOnePassCbrSvc() override = default; - - virtual void ResetModel() { - last_pts_ = 0; - duration_ = 0.0; - mismatch_psnr_ = 0.0; - mismatch_nframes_ = 0; - denoiser_on_ = 0; - tune_content_ = 0; - base_speed_setting_ = 5; - spatial_layer_id_ = 0; - temporal_layer_id_ = 0; - update_pattern_ = 0; - memset(bits_in_buffer_model_, 0, sizeof(bits_in_buffer_model_)); - memset(bits_total_, 0, sizeof(bits_total_)); - memset(layer_target_avg_bandwidth_, 0, sizeof(layer_target_avg_bandwidth_)); - dynamic_drop_layer_ = false; - single_layer_resize_ = false; - change_bitrate_ = false; - last_pts_ref_ = 0; - middle_bitrate_ = 0; - top_bitrate_ = 0; - superframe_count_ = -1; - key_frame_spacing_ = 9999; - num_nonref_frames_ = 0; - layer_framedrop_ = 0; - force_key_ = 0; - force_key_test_ = 0; - insert_layer_sync_ = 0; - layer_sync_on_base_ = 0; - force_intra_only_frame_ = 0; - superframe_has_intra_only_ = 0; - use_post_encode_drop_ = 0; - denoiser_off_on_ = false; - denoiser_enable_layers_ = false; - num_resize_down_ = 0; - num_resize_up_ = 0; - for (int i = 0; i < VPX_MAX_LAYERS; i++) { - prev_frame_width[i] = 320; - prev_frame_height[i] = 240; - } - ksvc_flex_noupd_tlenh_ = false; - } - void BeginPassHook(unsigned int /*pass*/) override {} - - // Example pattern for spatial layers and 2 temporal layers used in the - // bypass/flexible mode. The pattern corresponds to the pattern - // VP9E_TEMPORAL_LAYERING_MODE_0101 (temporal_layering_mode == 2) used in - // non-flexible mode, except that we disable inter-layer prediction. - void set_frame_flags_bypass_mode(int tl, int num_spatial_layers, - int is_key_frame, - vpx_svc_ref_frame_config_t *ref_frame_config, - int noupdate_tlenh) { - for (int sl = 0; sl < num_spatial_layers; ++sl) - ref_frame_config->update_buffer_slot[sl] = 0; - - for (int sl = 0; sl < num_spatial_layers; ++sl) { - if (tl == 0) { - ref_frame_config->lst_fb_idx[sl] = sl; - if (sl) { - if (is_key_frame) { - ref_frame_config->lst_fb_idx[sl] = sl - 1; - ref_frame_config->gld_fb_idx[sl] = sl; - } else { - ref_frame_config->gld_fb_idx[sl] = sl - 1; - } - } else { - ref_frame_config->gld_fb_idx[sl] = 0; - } - ref_frame_config->alt_fb_idx[sl] = 0; - } else if (tl == 1) { - ref_frame_config->lst_fb_idx[sl] = sl; - ref_frame_config->gld_fb_idx[sl] = - VPXMIN(REF_FRAMES - 1, num_spatial_layers + sl - 1); - ref_frame_config->alt_fb_idx[sl] = - VPXMIN(REF_FRAMES - 1, num_spatial_layers + sl); - } - if (!tl) { - if (!sl) { - ref_frame_config->reference_last[sl] = 1; - ref_frame_config->reference_golden[sl] = 0; - ref_frame_config->reference_alt_ref[sl] = 0; - ref_frame_config->update_buffer_slot[sl] |= - 1 << ref_frame_config->lst_fb_idx[sl]; - } else { - if (is_key_frame) { - ref_frame_config->reference_last[sl] = 1; - ref_frame_config->reference_golden[sl] = 0; - ref_frame_config->reference_alt_ref[sl] = 0; - ref_frame_config->update_buffer_slot[sl] |= - 1 << ref_frame_config->gld_fb_idx[sl]; - } else { - ref_frame_config->reference_last[sl] = 1; - ref_frame_config->reference_golden[sl] = 0; - ref_frame_config->reference_alt_ref[sl] = 0; - ref_frame_config->update_buffer_slot[sl] |= - 1 << ref_frame_config->lst_fb_idx[sl]; - } - } - } else if (tl == 1) { - if (!sl) { - ref_frame_config->reference_last[sl] = 1; - ref_frame_config->reference_golden[sl] = 0; - ref_frame_config->reference_alt_ref[sl] = 0; - ref_frame_config->update_buffer_slot[sl] |= - 1 << ref_frame_config->alt_fb_idx[sl]; - } else { - ref_frame_config->reference_last[sl] = 1; - ref_frame_config->reference_golden[sl] = 0; - ref_frame_config->reference_alt_ref[sl] = 0; - // Non reference frame on top temporal top spatial. - ref_frame_config->update_buffer_slot[sl] = 0; - } - // Force no update on all spatial layers for temporal enhancement layer - // frames. - if (noupdate_tlenh) ref_frame_config->update_buffer_slot[sl] = 0; - } - } - } - - void CheckLayerRateTargeting(int num_spatial_layers, int num_temporal_layers, - double thresh_overshoot, - double thresh_undershoot) const { - for (int sl = 0; sl < num_spatial_layers; ++sl) - for (int tl = 0; tl < num_temporal_layers; ++tl) { - const int layer = sl * num_temporal_layers + tl; - ASSERT_GE(cfg_.layer_target_bitrate[layer], - file_datarate_[layer] * thresh_overshoot) - << " The datarate for the file exceeds the target by too much!"; - ASSERT_LE(cfg_.layer_target_bitrate[layer], - file_datarate_[layer] * thresh_undershoot) - << " The datarate for the file is lower than the target by too " - "much!"; - } - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - PreEncodeFrameHookSetup(video, encoder); - - if (video->frame() == 0) { - if (force_intra_only_frame_) { - // Decoder sets the color_space for Intra-only frames - // to BT_601 (see line 1810 in vp9_decodeframe.c). - // So set it here in these tess to avoid encoder-decoder - // mismatch check on color space setting. - encoder->Control(VP9E_SET_COLOR_SPACE, VPX_CS_BT_601); - } - encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_); - encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_); - encoder->Control(VP9E_SET_SVC_INTER_LAYER_PRED, inter_layer_pred_mode_); - - if (layer_framedrop_) { - vpx_svc_frame_drop_t svc_drop_frame; - svc_drop_frame.framedrop_mode = LAYER_DROP; - for (int i = 0; i < number_spatial_layers_; i++) - svc_drop_frame.framedrop_thresh[i] = 30; - svc_drop_frame.max_consec_drop = 30; - encoder->Control(VP9E_SET_SVC_FRAME_DROP_LAYER, &svc_drop_frame); - } - - if (use_post_encode_drop_) { - encoder->Control(VP9E_SET_POSTENCODE_DROP, use_post_encode_drop_); - } - } - - if (denoiser_off_on_) { - encoder->Control(VP9E_SET_AQ_MODE, 3); - // Set inter_layer_pred to INTER_LAYER_PRED_OFF_NONKEY (K-SVC). - encoder->Control(VP9E_SET_SVC_INTER_LAYER_PRED, 2); - if (!denoiser_enable_layers_) { - if (video->frame() == 0) - encoder->Control(VP9E_SET_NOISE_SENSITIVITY, 0); - else if (video->frame() == 100) - encoder->Control(VP9E_SET_NOISE_SENSITIVITY, 1); - } else { - // Cumulative bitrates for top spatial layers, for - // 3 temporal layers. - if (video->frame() == 0) { - encoder->Control(VP9E_SET_NOISE_SENSITIVITY, 0); - // Change layer bitrates to set top spatial layer to 0. - // This is for 3 spatial 3 temporal layers. - // This will trigger skip encoding/dropping of top spatial layer. - cfg_.rc_target_bitrate -= cfg_.layer_target_bitrate[8]; - for (int i = 0; i < 3; i++) - bitrate_sl3_[i] = cfg_.layer_target_bitrate[i + 6]; - cfg_.layer_target_bitrate[6] = 0; - cfg_.layer_target_bitrate[7] = 0; - cfg_.layer_target_bitrate[8] = 0; - encoder->Config(&cfg_); - } else if (video->frame() == 100) { - // Change layer bitrates to non-zero on top spatial layer. - // This will trigger skip encoding of top spatial layer - // on key frame (period = 100). - for (int i = 0; i < 3; i++) - cfg_.layer_target_bitrate[i + 6] = bitrate_sl3_[i]; - cfg_.rc_target_bitrate += cfg_.layer_target_bitrate[8]; - encoder->Config(&cfg_); - } else if (video->frame() == 120) { - // Enable denoiser and top spatial layer after key frame (period is - // 100). - encoder->Control(VP9E_SET_NOISE_SENSITIVITY, 1); - } - } - } - - if (ksvc_flex_noupd_tlenh_) { - vpx_svc_layer_id_t layer_id; - layer_id.spatial_layer_id = 0; - layer_id.temporal_layer_id = (video->frame() % 2 != 0); - temporal_layer_id_ = layer_id.temporal_layer_id; - for (int i = 0; i < number_spatial_layers_; i++) { - layer_id.temporal_layer_id_per_spatial[i] = temporal_layer_id_; - ref_frame_config_.duration[i] = 1; - } - encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id); - set_frame_flags_bypass_mode(layer_id.temporal_layer_id, - number_spatial_layers_, 0, &ref_frame_config_, - 1); - encoder->Control(VP9E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config_); - } - - if (update_pattern_ && video->frame() >= 100) { - vpx_svc_layer_id_t layer_id; - if (video->frame() == 100) { - cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS; - encoder->Config(&cfg_); - } - // Set layer id since the pattern changed. - layer_id.spatial_layer_id = 0; - layer_id.temporal_layer_id = (video->frame() % 2 != 0); - temporal_layer_id_ = layer_id.temporal_layer_id; - for (int i = 0; i < number_spatial_layers_; i++) { - layer_id.temporal_layer_id_per_spatial[i] = temporal_layer_id_; - ref_frame_config_.duration[i] = 1; - } - encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id); - set_frame_flags_bypass_mode(layer_id.temporal_layer_id, - number_spatial_layers_, 0, &ref_frame_config_, - 0); - encoder->Control(VP9E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config_); - } - - if (change_bitrate_ && video->frame() == 200) { - duration_ = (last_pts_ + 1) * timebase_; - for (int sl = 0; sl < number_spatial_layers_; ++sl) { - for (int tl = 0; tl < number_temporal_layers_; ++tl) { - const int layer = sl * number_temporal_layers_ + tl; - const double file_size_in_kb = bits_total_[layer] / 1000.; - file_datarate_[layer] = file_size_in_kb / duration_; - } - } - - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, - 0.78, 1.15); - - memset(file_datarate_, 0, sizeof(file_datarate_)); - memset(bits_total_, 0, sizeof(bits_total_)); - int64_t bits_in_buffer_model_tmp[VPX_MAX_LAYERS]; - last_pts_ref_ = last_pts_; - // Set new target bitarate. - cfg_.rc_target_bitrate = cfg_.rc_target_bitrate >> 1; - // Buffer level should not reset on dynamic bitrate change. - memcpy(bits_in_buffer_model_tmp, bits_in_buffer_model_, - sizeof(bits_in_buffer_model_)); - AssignLayerBitrates(); - memcpy(bits_in_buffer_model_, bits_in_buffer_model_tmp, - sizeof(bits_in_buffer_model_)); - - // Change config to update encoder with new bitrate configuration. - encoder->Config(&cfg_); - } - - if (dynamic_drop_layer_ && !single_layer_resize_) { - if (video->frame() == 0) { - // Change layer bitrates to set top layers to 0. This will trigger skip - // encoding/dropping of top two spatial layers. - cfg_.rc_target_bitrate -= - (cfg_.layer_target_bitrate[1] + cfg_.layer_target_bitrate[2]); - middle_bitrate_ = cfg_.layer_target_bitrate[1]; - top_bitrate_ = cfg_.layer_target_bitrate[2]; - cfg_.layer_target_bitrate[1] = 0; - cfg_.layer_target_bitrate[2] = 0; - encoder->Config(&cfg_); - } else if (video->frame() == 50) { - // Change layer bitrates to non-zero on two top spatial layers. - // This will trigger skip encoding of top two spatial layers. - cfg_.layer_target_bitrate[1] = middle_bitrate_; - cfg_.layer_target_bitrate[2] = top_bitrate_; - cfg_.rc_target_bitrate += - cfg_.layer_target_bitrate[2] + cfg_.layer_target_bitrate[1]; - encoder->Config(&cfg_); - } else if (video->frame() == 100) { - // Change layer bitrates to set top layers to 0. This will trigger skip - // encoding/dropping of top two spatial layers. - cfg_.rc_target_bitrate -= - (cfg_.layer_target_bitrate[1] + cfg_.layer_target_bitrate[2]); - middle_bitrate_ = cfg_.layer_target_bitrate[1]; - top_bitrate_ = cfg_.layer_target_bitrate[2]; - cfg_.layer_target_bitrate[1] = 0; - cfg_.layer_target_bitrate[2] = 0; - encoder->Config(&cfg_); - } else if (video->frame() == 150) { - // Change layer bitrate on second layer to non-zero to start - // encoding it again. - cfg_.layer_target_bitrate[1] = middle_bitrate_; - cfg_.rc_target_bitrate += cfg_.layer_target_bitrate[1]; - encoder->Config(&cfg_); - } else if (video->frame() == 200) { - // Change layer bitrate on top layer to non-zero to start - // encoding it again. - cfg_.layer_target_bitrate[2] = top_bitrate_; - cfg_.rc_target_bitrate += cfg_.layer_target_bitrate[2]; - encoder->Config(&cfg_); - } - } else if (dynamic_drop_layer_ && single_layer_resize_) { - // Change layer bitrates to set top layers to 0. This will trigger skip - // encoding/dropping of top spatial layers. - if (video->frame() == 2) { - cfg_.rc_target_bitrate -= - (cfg_.layer_target_bitrate[1] + cfg_.layer_target_bitrate[2]); - middle_bitrate_ = cfg_.layer_target_bitrate[1]; - top_bitrate_ = cfg_.layer_target_bitrate[2]; - cfg_.layer_target_bitrate[1] = 0; - cfg_.layer_target_bitrate[2] = 0; - // Set spatial layer 0 to a very low bitrate to trigger resize. - cfg_.layer_target_bitrate[0] = 30; - cfg_.rc_target_bitrate = cfg_.layer_target_bitrate[0]; - encoder->Config(&cfg_); - } else if (video->frame() == 100) { - // Set base spatial layer to very high to go back up to original size. - cfg_.layer_target_bitrate[0] = 400; - cfg_.rc_target_bitrate = cfg_.layer_target_bitrate[0]; - encoder->Config(&cfg_); - } - } else if (!dynamic_drop_layer_ && single_layer_resize_) { - if (video->frame() == 2) { - cfg_.layer_target_bitrate[0] = 30; - cfg_.layer_target_bitrate[1] = 50; - cfg_.rc_target_bitrate = - (cfg_.layer_target_bitrate[0] + cfg_.layer_target_bitrate[1]); - encoder->Config(&cfg_); - } else if (video->frame() == 160) { - cfg_.layer_target_bitrate[0] = 1500; - cfg_.layer_target_bitrate[1] = 2000; - cfg_.rc_target_bitrate = - (cfg_.layer_target_bitrate[0] + cfg_.layer_target_bitrate[1]); - encoder->Config(&cfg_); - } - } - if (force_key_test_ && force_key_) frame_flags_ = VPX_EFLAG_FORCE_KF; - - if (insert_layer_sync_) { - vpx_svc_spatial_layer_sync_t svc_layer_sync; - svc_layer_sync.base_layer_intra_only = 0; - for (int i = 0; i < number_spatial_layers_; i++) - svc_layer_sync.spatial_layer_sync[i] = 0; - if (force_intra_only_frame_) { - superframe_has_intra_only_ = 0; - if (video->frame() == 0) { - svc_layer_sync.base_layer_intra_only = 1; - svc_layer_sync.spatial_layer_sync[0] = 1; - encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync); - superframe_has_intra_only_ = 1; - } else if (video->frame() == 100) { - svc_layer_sync.base_layer_intra_only = 1; - svc_layer_sync.spatial_layer_sync[0] = 1; - encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync); - superframe_has_intra_only_ = 1; - } - } else { - layer_sync_on_base_ = 0; - if (video->frame() == 150) { - svc_layer_sync.spatial_layer_sync[1] = 1; - encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync); - } else if (video->frame() == 240) { - svc_layer_sync.spatial_layer_sync[2] = 1; - encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync); - } else if (video->frame() == 320) { - svc_layer_sync.spatial_layer_sync[0] = 1; - layer_sync_on_base_ = 1; - encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync); - } - } - } - - const vpx_rational_t tb = video->timebase(); - timebase_ = static_cast(tb.num) / tb.den; - duration_ = 0; - } - - vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz, - uint32_t sizes[8], int *count) { - uint8_t marker; - marker = *(data + data_sz - 1); - *count = 0; - if ((marker & 0xe0) == 0xc0) { - const uint32_t frames = (marker & 0x7) + 1; - const uint32_t mag = ((marker >> 3) & 0x3) + 1; - const size_t index_sz = 2 + mag * frames; - // This chunk is marked as having a superframe index but doesn't have - // enough data for it, thus it's an invalid superframe index. - if (data_sz < index_sz) return VPX_CODEC_CORRUPT_FRAME; - { - const uint8_t marker2 = *(data + data_sz - index_sz); - // This chunk is marked as having a superframe index but doesn't have - // the matching marker byte at the front of the index therefore it's an - // invalid chunk. - if (marker != marker2) return VPX_CODEC_CORRUPT_FRAME; - } - { - uint32_t i, j; - const uint8_t *x = &data[data_sz - index_sz + 1]; - for (i = 0; i < frames; ++i) { - uint32_t this_sz = 0; - - for (j = 0; j < mag; ++j) this_sz |= (*x++) << (j * 8); - sizes[i] = this_sz; - } - *count = frames; - } - } - return VPX_CODEC_OK; - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - uint32_t sizes[8] = { 0 }; - uint32_t sizes_parsed[8] = { 0 }; - int count = 0; - int num_layers_encoded = 0; - last_pts_ = pkt->data.frame.pts; - const bool key_frame = - (pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false; - if (key_frame) { - // For test that inserts layer sync frames: requesting a layer_sync on - // the base layer must force key frame. So if any key frame occurs after - // first superframe it must due to layer sync on base spatial layer. - if (superframe_count_ > 0 && insert_layer_sync_ && - !force_intra_only_frame_) { - ASSERT_EQ(layer_sync_on_base_, 1); - } - temporal_layer_id_ = 0; - superframe_count_ = 0; - } - parse_superframe_index(static_cast(pkt->data.frame.buf), - pkt->data.frame.sz, sizes_parsed, &count); - // Count may be less than number of spatial layers because of frame drops. - if (number_spatial_layers_ > 1) { - for (int sl = 0; sl < number_spatial_layers_; ++sl) { - if (pkt->data.frame.spatial_layer_encoded[sl]) { - sizes[sl] = sizes_parsed[num_layers_encoded]; - num_layers_encoded++; - } - } - } - // For superframe with Intra-only count will be +1 larger - // because of no-show frame. - if (force_intra_only_frame_ && superframe_has_intra_only_) - ASSERT_EQ(count, num_layers_encoded + 1); - else - ASSERT_EQ(count, num_layers_encoded); - - // In the constrained frame drop mode, if a given spatial is dropped all - // upper layers must be dropped too. - if (!layer_framedrop_) { - int num_layers_dropped = 0; - for (int sl = 0; sl < number_spatial_layers_; ++sl) { - if (!pkt->data.frame.spatial_layer_encoded[sl]) { - // Check that all upper layers are dropped. - num_layers_dropped++; - for (int sl2 = sl + 1; sl2 < number_spatial_layers_; ++sl2) - ASSERT_EQ(pkt->data.frame.spatial_layer_encoded[sl2], 0); - } - } - if (num_layers_dropped == number_spatial_layers_ - 1) - force_key_ = 1; - else - force_key_ = 0; - } - // Keep track of number of non-reference frames, needed for mismatch check. - // Non-reference frames are top spatial and temporal layer frames, - // for TL > 0. - if (temporal_layer_id_ == number_temporal_layers_ - 1 && - temporal_layer_id_ > 0 && - pkt->data.frame.spatial_layer_encoded[number_spatial_layers_ - 1]) - num_nonref_frames_++; - for (int sl = 0; sl < number_spatial_layers_; ++sl) { - sizes[sl] = sizes[sl] << 3; - // Update the total encoded bits per layer. - // For temporal layers, update the cumulative encoded bits per layer. - for (int tl = temporal_layer_id_; tl < number_temporal_layers_; ++tl) { - const int layer = sl * number_temporal_layers_ + tl; - bits_total_[layer] += static_cast(sizes[sl]); - // Update the per-layer buffer level with the encoded frame size. - bits_in_buffer_model_[layer] -= static_cast(sizes[sl]); - // There should be no buffer underrun, except on the base - // temporal layer, since there may be key frames there. - // Fo short key frame spacing, buffer can underrun on individual frames. - if (!key_frame && tl > 0 && key_frame_spacing_ < 100) { - ASSERT_GE(bits_in_buffer_model_[layer], 0) - << "Buffer Underrun at frame " << pkt->data.frame.pts; - } - } - - if (!single_layer_resize_) { - unsigned int scaled_width = top_sl_width_ * - svc_params_.scaling_factor_num[sl] / - svc_params_.scaling_factor_den[sl]; - if (scaled_width % 2 != 0) scaled_width += 1; - ASSERT_EQ(pkt->data.frame.width[sl], scaled_width); - unsigned int scaled_height = top_sl_height_ * - svc_params_.scaling_factor_num[sl] / - svc_params_.scaling_factor_den[sl]; - if (scaled_height % 2 != 0) scaled_height += 1; - ASSERT_EQ(pkt->data.frame.height[sl], scaled_height); - } else if (superframe_count_ > 0) { - if (pkt->data.frame.width[sl] < prev_frame_width[sl] && - pkt->data.frame.height[sl] < prev_frame_height[sl]) - num_resize_down_ += 1; - if (pkt->data.frame.width[sl] > prev_frame_width[sl] && - pkt->data.frame.height[sl] > prev_frame_height[sl]) - num_resize_up_ += 1; - } - prev_frame_width[sl] = pkt->data.frame.width[sl]; - prev_frame_height[sl] = pkt->data.frame.height[sl]; - } - } - - void EndPassHook() override { - if (change_bitrate_) last_pts_ = last_pts_ - last_pts_ref_; - duration_ = (last_pts_ + 1) * timebase_; - for (int sl = 0; sl < number_spatial_layers_; ++sl) { - for (int tl = 0; tl < number_temporal_layers_; ++tl) { - const int layer = sl * number_temporal_layers_ + tl; - const double file_size_in_kb = bits_total_[layer] / 1000.; - file_datarate_[layer] = file_size_in_kb / duration_; - } - } - } - - void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) override { - // TODO(marpan): Look into why an assert is triggered in compute_psnr - // for mismatch frames for the special test case: ksvc_flex_noupd_tlenh. - // Has to do with dropped frames in bypass/flexible svc mode. - if (!ksvc_flex_noupd_tlenh_) { - double mismatch_psnr = compute_psnr(img1, img2); - mismatch_psnr_ += mismatch_psnr; - ++mismatch_nframes_; - } - } - - unsigned int GetMismatchFrames() { return mismatch_nframes_; } - unsigned int GetNonRefFrames() { return num_nonref_frames_; } - - vpx_codec_pts_t last_pts_; - double timebase_; - int64_t bits_total_[VPX_MAX_LAYERS]; - double duration_; - double file_datarate_[VPX_MAX_LAYERS]; - size_t bits_in_last_frame_; - double mismatch_psnr_; - int denoiser_on_; - int tune_content_; - int spatial_layer_id_; - bool dynamic_drop_layer_; - bool single_layer_resize_; - unsigned int top_sl_width_; - unsigned int top_sl_height_; - vpx_svc_ref_frame_config_t ref_frame_config_; - int update_pattern_; - bool change_bitrate_; - vpx_codec_pts_t last_pts_ref_; - int middle_bitrate_; - int top_bitrate_; - int key_frame_spacing_; - int layer_framedrop_; - int force_key_; - int force_key_test_; - int inter_layer_pred_mode_; - int insert_layer_sync_; - int layer_sync_on_base_; - int force_intra_only_frame_; - int superframe_has_intra_only_; - int use_post_encode_drop_; - int bitrate_sl3_[3]; - // Denoiser switched on the fly. - bool denoiser_off_on_; - // Top layer enabled on the fly. - bool denoiser_enable_layers_; - int num_resize_up_; - int num_resize_down_; - unsigned int prev_frame_width[VPX_MAX_LAYERS]; - unsigned int prev_frame_height[VPX_MAX_LAYERS]; - bool ksvc_flex_noupd_tlenh_; - - private: - void SetConfig(const int num_temporal_layer) override { - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.g_error_resilient = 1; - if (num_temporal_layer == 3) { - cfg_.ts_rate_decimator[0] = 4; - cfg_.ts_rate_decimator[1] = 2; - cfg_.ts_rate_decimator[2] = 1; - cfg_.temporal_layering_mode = 3; - } else if (num_temporal_layer == 2) { - cfg_.ts_rate_decimator[0] = 2; - cfg_.ts_rate_decimator[1] = 1; - cfg_.temporal_layering_mode = 2; - } else if (num_temporal_layer == 1) { - cfg_.ts_rate_decimator[0] = 1; - cfg_.temporal_layering_mode = 0; - } - } - - unsigned int num_nonref_frames_; - unsigned int mismatch_nframes_; -}; - -// Params: speed setting. -class DatarateOnePassCbrSvcSingleBR - : public DatarateOnePassCbrSvc, - public ::libvpx_test::CodecTestWithParam { - public: - DatarateOnePassCbrSvcSingleBR() : DatarateOnePassCbrSvc(GET_PARAM(0)) { - memset(&svc_params_, 0, sizeof(svc_params_)); - } - ~DatarateOnePassCbrSvcSingleBR() override = default; - - protected: - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - speed_setting_ = GET_PARAM(1); - ResetModel(); - } -}; - -// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3 -// temporal layers, for 4:4:4 Profile 1. -TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TL444Profile1) { - SetSvcConfig(3, 3); - ::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140); - cfg_.g_profile = 1; - cfg_.g_bit_depth = VPX_BITS_8; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 0; - cfg_.kf_max_dist = 9999; - - top_sl_width_ = 352; - top_sl_height_ = 288; - cfg_.rc_target_bitrate = 500; - ResetModel(); - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78, - 1.15); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 3 -// temporal layers, for 4:2:2 Profile 1. -TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2SL3TL422Profile1) { - SetSvcConfig(2, 3); - ::libvpx_test::Y4mVideoSource video("park_joy_90p_8_422.y4m", 0, 20); - cfg_.g_profile = 1; - cfg_.g_bit_depth = VPX_BITS_8; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 0; - cfg_.kf_max_dist = 9999; - - top_sl_width_ = 160; - top_sl_height_ = 90; - cfg_.rc_target_bitrate = 500; - ResetModel(); - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - // Use large under/over shoot thresholds as this is a very short clip, - // so not good for testing rate-targeting. - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.5, - 1.7); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -#if CONFIG_VP9_HIGHBITDEPTH -// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3 -// temporal layers, for Profle 2 10bit. -TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TL10bitProfile2) { - SetSvcConfig(3, 3); - ::libvpx_test::Y4mVideoSource video("park_joy_90p_10_420_20f.y4m", 0, 20); - cfg_.g_profile = 2; - cfg_.g_bit_depth = VPX_BITS_10; - cfg_.g_input_bit_depth = VPX_BITS_10; - if (cfg_.g_bit_depth > 8) init_flags_ |= VPX_CODEC_USE_HIGHBITDEPTH; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 0; - cfg_.kf_max_dist = 9999; - - top_sl_width_ = 160; - top_sl_height_ = 90; - cfg_.rc_target_bitrate = 500; - ResetModel(); - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - // TODO(marpan/jianj): Comment out the rate-target checking for now - // as superframe parsing to get frame size needs to be fixed for - // high bitdepth. - /* - // Use large under/over shoot thresholds as this is a very short clip, - // so not good for testing rate-targeting. - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.5, - 1.7); - */ -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3 -// temporal layers, for Profle 2 12bit. -TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TL12bitProfile2) { - SetSvcConfig(3, 3); - ::libvpx_test::Y4mVideoSource video("park_joy_90p_12_420_20f.y4m", 0, 20); - cfg_.g_profile = 2; - cfg_.g_bit_depth = VPX_BITS_12; - cfg_.g_input_bit_depth = VPX_BITS_12; - if (cfg_.g_bit_depth > 8) init_flags_ |= VPX_CODEC_USE_HIGHBITDEPTH; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 0; - cfg_.kf_max_dist = 9999; - - top_sl_width_ = 160; - top_sl_height_ = 90; - cfg_.rc_target_bitrate = 500; - ResetModel(); - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - // TODO(marpan/jianj): Comment out the rate-target checking for now - // as superframe parsing to get frame size needs to be fixed for - // high bitdepth. - /* - // Use large under/over shoot thresholds as this is a very short clip, - // so not good for testing rate-targeting. - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.5, - 1.7); - */ -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} -#endif - -// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 1 -// temporal layer, with screen content mode on and same speed setting for all -// layers. -TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2SL1TLScreenContent1) { - SetSvcConfig(2, 1); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 10; - cfg_.kf_max_dist = 9999; - - ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60); - top_sl_width_ = 1280; - top_sl_height_ = 720; - cfg_.rc_target_bitrate = 500; - ResetModel(); - tune_content_ = 1; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78, - 1.15); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and -// 3 temporal layers, with force key frame after frame drop -TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TLForceKey) { - SetSvcConfig(3, 3); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 9999; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - top_sl_width_ = 640; - top_sl_height_ = 480; - cfg_.rc_target_bitrate = 100; - ResetModel(); - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78, - 1.25); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and -// 2 temporal layers, with a change on the fly from the fixed SVC pattern to one -// generate via SVC_SET_REF_FRAME_CONFIG. The new pattern also disables -// inter-layer prediction. -TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL2TLDynamicPatternChange) { - SetSvcConfig(3, 2); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 9999; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - top_sl_width_ = 640; - top_sl_height_ = 480; - cfg_.rc_target_bitrate = 800; - ResetModel(); - // Change SVC pattern on the fly. - update_pattern_ = 1; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78, - 1.15); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Check basic rate targeting for 1 pass CBR SVC with 3 spatial and 3 temporal -// layers, for inter_layer_pred=OffKey (K-SVC) and on the fly switching -// of denoiser from off to on (on at frame = 100). Key frame period is set to -// 1000 so denoise is enabled on non-key. -TEST_P(DatarateOnePassCbrSvcSingleBR, - OnePassCbrSvc3SL3TL_DenoiserOffOnFixedLayers) { - SetSvcConfig(3, 3); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 1000; - ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", 1280, - 720, 30, 1, 0, 300); - top_sl_width_ = 1280; - top_sl_height_ = 720; - cfg_.rc_target_bitrate = 1000; - ResetModel(); - denoiser_off_on_ = true; - denoiser_enable_layers_ = false; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - // Don't check rate targeting on two top spatial layer since they will be - // skipped for part of the sequence. - CheckLayerRateTargeting(number_spatial_layers_ - 2, number_temporal_layers_, - 0.78, 1.15); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Check basic rate targeting for 1 pass CBR SVC with 3 spatial and 3 temporal -// layers, for inter_layer_pred=OffKey (K-SVC) and on the fly switching -// of denoiser from off to on, for dynamic layers. Start at 2 spatial layers -// and enable 3rd spatial layer at frame = 100. Use periodic key frame with -// period 100 so enabling of spatial layer occurs at key frame. Enable denoiser -// at frame > 100, after the key frame sync. -TEST_P(DatarateOnePassCbrSvcSingleBR, - OnePassCbrSvc3SL3TL_DenoiserOffOnEnableLayers) { - SetSvcConfig(3, 3); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 0; - cfg_.kf_max_dist = 100; - ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", 1280, - 720, 30, 1, 0, 300); - top_sl_width_ = 1280; - top_sl_height_ = 720; - cfg_.rc_target_bitrate = 1000; - ResetModel(); - denoiser_off_on_ = true; - denoiser_enable_layers_ = true; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - // Don't check rate targeting on two top spatial layer since they will be - // skipped for part of the sequence. - CheckLayerRateTargeting(number_spatial_layers_ - 2, number_temporal_layers_, - 0.78, 1.15); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Check basic rate targeting for 1 pass CBR SVC with 3 spatial layers and on -// the fly switching to 1 and then 2 and back to 3 spatial layers. This switch -// is done by setting spatial layer bitrates to 0, and then back to non-zero, -// during the sequence. -TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL_DisableEnableLayers) { - SetSvcConfig(3, 1); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.temporal_layering_mode = 0; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 9999; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - top_sl_width_ = 640; - top_sl_height_ = 480; - cfg_.rc_target_bitrate = 800; - ResetModel(); - dynamic_drop_layer_ = true; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - // Don't check rate targeting on two top spatial layer since they will be - // skipped for part of the sequence. - CheckLayerRateTargeting(number_spatial_layers_ - 2, number_temporal_layers_, - 0.78, 1.15); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Check basic rate targeting for 1 pass CBR SVC with 2 spatial layers and on -// the fly switching to 1 spatial layer with dynamic resize enabled. -// The resizer will resize the single layer down and back up again, as the -// bitrate goes back up. -TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2SL_SingleLayerResize) { - SetSvcConfig(2, 1); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.temporal_layering_mode = 0; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 9999; - cfg_.rc_resize_allowed = 1; - ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", 1280, - 720, 15, 1, 0, 300); - top_sl_width_ = 1280; - top_sl_height_ = 720; - cfg_.rc_target_bitrate = 800; - ResetModel(); - dynamic_drop_layer_ = true; - single_layer_resize_ = true; - base_speed_setting_ = speed_setting_; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - // Expect at least one resize down and at least one resize back up. - EXPECT_GE(num_resize_down_, 1); - EXPECT_GE(num_resize_up_, 1); - // Don't check rate targeting on two top spatial layer since they will be - // skipped for part of the sequence. - CheckLayerRateTargeting(number_spatial_layers_ - 2, number_temporal_layers_, - 0.78, 1.15); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// For pass CBR SVC with 1 spatial and 2 temporal layers with dynamic resize -// and denoiser enabled. The resizer will resize the single layer down and back -// up again, as the bitrate goes back up. -TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc1SL2TL_DenoiseResize) { - SetSvcConfig(1, 2); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.temporal_layering_mode = 2; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 9999; - cfg_.rc_resize_allowed = 1; - ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", 1280, - 720, 12, 1, 0, 300); - top_sl_width_ = 1280; - top_sl_height_ = 720; - cfg_.rc_target_bitrate = 800; - ResetModel(); - dynamic_drop_layer_ = false; - single_layer_resize_ = true; - denoiser_on_ = 1; - base_speed_setting_ = speed_setting_; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - // Expect at least one resize down and at least one resize back up. - EXPECT_GE(num_resize_down_, 1); - EXPECT_GE(num_resize_up_, 1); -} - -// Run SVC encoder for 1 temporal layer, 2 spatial layers, with spatial -// downscale 5x5. -TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2SL1TL5x5MultipleRuns) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.ss_number_layers = 2; - cfg_.ts_number_layers = 1; - cfg_.ts_rate_decimator[0] = 1; - cfg_.g_error_resilient = 1; - cfg_.g_threads = 3; - cfg_.temporal_layering_mode = 0; - svc_params_.scaling_factor_num[0] = 256; - svc_params_.scaling_factor_den[0] = 1280; - svc_params_.scaling_factor_num[1] = 1280; - svc_params_.scaling_factor_den[1] = 1280; - cfg_.rc_dropframe_thresh = 10; - cfg_.kf_max_dist = 999999; - cfg_.kf_min_dist = 0; - cfg_.ss_target_bitrate[0] = 300; - cfg_.ss_target_bitrate[1] = 1400; - cfg_.layer_target_bitrate[0] = 300; - cfg_.layer_target_bitrate[1] = 1400; - cfg_.rc_target_bitrate = 1700; - number_spatial_layers_ = cfg_.ss_number_layers; - number_temporal_layers_ = cfg_.ts_number_layers; - ResetModel(); - layer_target_avg_bandwidth_[0] = cfg_.layer_target_bitrate[0] * 1000 / 30; - bits_in_buffer_model_[0] = - cfg_.layer_target_bitrate[0] * cfg_.rc_buf_initial_sz; - layer_target_avg_bandwidth_[1] = cfg_.layer_target_bitrate[1] * 1000 / 30; - bits_in_buffer_model_[1] = - cfg_.layer_target_bitrate[1] * cfg_.rc_buf_initial_sz; - ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60); - top_sl_width_ = 1280; - top_sl_height_ = 720; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78, - 1.15); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Params: speed setting and index for bitrate array. -class DatarateOnePassCbrSvcMultiBR - : public DatarateOnePassCbrSvc, - public ::libvpx_test::CodecTestWith2Params { - public: - DatarateOnePassCbrSvcMultiBR() : DatarateOnePassCbrSvc(GET_PARAM(0)) { - memset(&svc_params_, 0, sizeof(svc_params_)); - } - ~DatarateOnePassCbrSvcMultiBR() override = default; - - protected: - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - speed_setting_ = GET_PARAM(1); - ResetModel(); - } -}; - -// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and -// 3 temporal layers. Run CIF clip with 1 thread. -TEST_P(DatarateOnePassCbrSvcMultiBR, OnePassCbrSvc2SL3TL) { - SetSvcConfig(2, 3); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 9999; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - top_sl_width_ = 640; - top_sl_height_ = 480; - const int bitrates[3] = { 200, 400, 600 }; - // TODO(marpan): Check that effective_datarate for each layer hits the - // layer target_bitrate. - cfg_.rc_target_bitrate = bitrates[GET_PARAM(2)]; - ResetModel(); - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.75, - 1.2); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Check basic rate targeting for 1 pass VBR SVC: 2 spatial layers and -// 3 temporal layers. Run VGA clip with 1 thread. -TEST_P(DatarateOnePassCbrSvcMultiBR, OnePassVbrSvc2SL3TL) { - SetSvcConfig(2, 3); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 2; - cfg_.rc_max_quantizer = 56; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 9999; - cfg_.rc_end_usage = VPX_VBR; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - top_sl_width_ = 640; - top_sl_height_ = 480; - const int bitrates[3] = { 200, 400, 600 }; - cfg_.rc_target_bitrate = bitrates[GET_PARAM(2)]; - ResetModel(); - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.70, - 1.3); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Params: speed setting, layer framedrop control and index for bitrate array. -class DatarateOnePassCbrSvcFrameDropMultiBR - : public DatarateOnePassCbrSvc, - public ::libvpx_test::CodecTestWith3Params { - public: - DatarateOnePassCbrSvcFrameDropMultiBR() - : DatarateOnePassCbrSvc(GET_PARAM(0)) { - memset(&svc_params_, 0, sizeof(svc_params_)); - } - ~DatarateOnePassCbrSvcFrameDropMultiBR() override = default; - - protected: - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - speed_setting_ = GET_PARAM(1); - ResetModel(); - } -}; - -// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and -// 3 temporal layers. Run HD clip with 4 threads. -TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR, OnePassCbrSvc2SL3TL4Threads) { - SetSvcConfig(2, 3); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 4; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 9999; - ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60); - top_sl_width_ = 1280; - top_sl_height_ = 720; - layer_framedrop_ = 0; - const int bitrates[3] = { 200, 400, 600 }; - cfg_.rc_target_bitrate = bitrates[GET_PARAM(3)]; - ResetModel(); - layer_framedrop_ = GET_PARAM(2); - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.64, - 1.45); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and -// 3 temporal layers. Run HD clip with 4 threads. -TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR, OnePassCbrSvc3SL3TL4Threads) { - SetSvcConfig(3, 3); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 4; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 9999; - ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60); - top_sl_width_ = 1280; - top_sl_height_ = 720; - layer_framedrop_ = 0; - const int bitrates[3] = { 200, 400, 600 }; - cfg_.rc_target_bitrate = bitrates[GET_PARAM(3)]; - ResetModel(); - layer_framedrop_ = GET_PARAM(2); - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.58, - 1.2); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and -// 2 temporal layers, for KSVC in flexible mode with no update of reference -// frames for all spatial layers on TL > 0 superframes. -// Run HD clip with 4 threads. -TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR, OnePassCbrSvc3SL2TL4ThKSVCFlex) { - SetSvcConfig(3, 2); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 4; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 9999; - ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60); - top_sl_width_ = 1280; - top_sl_height_ = 720; - layer_framedrop_ = 0; - const int bitrates[3] = { 200, 400, 600 }; - cfg_.rc_target_bitrate = bitrates[GET_PARAM(3)]; - ResetModel(); - layer_framedrop_ = GET_PARAM(2); - AssignLayerBitrates(); - ksvc_flex_noupd_tlenh_ = true; - cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.58, - 1.2); -} - -// Params: speed setting, inter-layer prediction mode. -class DatarateOnePassCbrSvcInterLayerPredSingleBR - : public DatarateOnePassCbrSvc, - public ::libvpx_test::CodecTestWith2Params { - public: - DatarateOnePassCbrSvcInterLayerPredSingleBR() - : DatarateOnePassCbrSvc(GET_PARAM(0)) { - memset(&svc_params_, 0, sizeof(svc_params_)); - } - ~DatarateOnePassCbrSvcInterLayerPredSingleBR() override = default; - - protected: - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - speed_setting_ = GET_PARAM(1); - inter_layer_pred_mode_ = GET_PARAM(2); - ResetModel(); - } -}; - -// Check basic rate targeting with different inter-layer prediction modes for 1 -// pass CBR SVC: 3 spatial layers and 3 temporal layers. Run CIF clip with 1 -// thread. -TEST_P(DatarateOnePassCbrSvcInterLayerPredSingleBR, OnePassCbrSvc3SL3TL) { - // Disable test for inter-layer pred off for now since simulcast_mode fails. - if (inter_layer_pred_mode_ == INTER_LAYER_PRED_OFF) return; - SetSvcConfig(3, 3); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.temporal_layering_mode = 3; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 9999; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - top_sl_width_ = 640; - top_sl_height_ = 480; - cfg_.rc_target_bitrate = 800; - ResetModel(); - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78, - 1.15); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Check rate targeting with different inter-layer prediction modes for 1 pass -// CBR SVC: 3 spatial layers and 3 temporal layers, changing the target bitrate -// at the middle of encoding. -TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TLDynamicBitrateChange) { - SetSvcConfig(3, 3); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 9999; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - top_sl_width_ = 640; - top_sl_height_ = 480; - cfg_.rc_target_bitrate = 800; - ResetModel(); - change_bitrate_ = true; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78, - 1.15); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -#if CONFIG_VP9_TEMPORAL_DENOISING -// Params: speed setting, noise sensitivity, index for bitrate array and inter -// layer pred mode. -class DatarateOnePassCbrSvcDenoiser - : public DatarateOnePassCbrSvc, - public ::libvpx_test::CodecTestWith4Params { - public: - DatarateOnePassCbrSvcDenoiser() : DatarateOnePassCbrSvc(GET_PARAM(0)) { - memset(&svc_params_, 0, sizeof(svc_params_)); - } - ~DatarateOnePassCbrSvcDenoiser() override = default; - - protected: - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - speed_setting_ = GET_PARAM(1); - inter_layer_pred_mode_ = GET_PARAM(3); - ResetModel(); - } -}; - -// Check basic rate targeting for 1 pass CBR SVC with denoising. -// 2 spatial layers and 3 temporal layer. Run HD clip with 2 threads. -TEST_P(DatarateOnePassCbrSvcDenoiser, OnePassCbrSvc2SL3TLDenoiserOn) { - SetSvcConfig(2, 3); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 2; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 9999; - number_spatial_layers_ = cfg_.ss_number_layers; - number_temporal_layers_ = cfg_.ts_number_layers; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - top_sl_width_ = 640; - top_sl_height_ = 480; - const int bitrates[3] = { 600, 800, 1000 }; - // TODO(marpan): Check that effective_datarate for each layer hits the - // layer target_bitrate. - // For SVC, noise_sen = 1 means denoising only the top spatial layer - // noise_sen = 2 means denoising the two top spatial layers. - cfg_.rc_target_bitrate = bitrates[GET_PARAM(3)]; - ResetModel(); - denoiser_on_ = GET_PARAM(2); - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78, - 1.15); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} -#endif - -// Params: speed setting, key frame dist. -class DatarateOnePassCbrSvcSmallKF - : public DatarateOnePassCbrSvc, - public ::libvpx_test::CodecTestWith2Params { - public: - DatarateOnePassCbrSvcSmallKF() : DatarateOnePassCbrSvc(GET_PARAM(0)) { - memset(&svc_params_, 0, sizeof(svc_params_)); - } - ~DatarateOnePassCbrSvcSmallKF() override = default; - - protected: - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - speed_setting_ = GET_PARAM(1); - ResetModel(); - } -}; - -// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3 -// temporal layers. Run CIF clip with 1 thread, and few short key frame periods. -TEST_P(DatarateOnePassCbrSvcSmallKF, OnePassCbrSvc3SL3TLSmallKf) { - SetSvcConfig(3, 3); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 10; - cfg_.rc_target_bitrate = 800; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - top_sl_width_ = 640; - top_sl_height_ = 480; - // For this 3 temporal layer case, pattern repeats every 4 frames, so choose - // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2). - const int kf_dist = GET_PARAM(2); - cfg_.kf_max_dist = kf_dist; - key_frame_spacing_ = kf_dist; - ResetModel(); - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.70, - 1.15); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 3 -// temporal layers. Run CIF clip with 1 thread, and few short key frame periods. -TEST_P(DatarateOnePassCbrSvcSmallKF, OnePassCbrSvc2SL3TLSmallKf) { - SetSvcConfig(2, 3); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 10; - cfg_.rc_target_bitrate = 400; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - top_sl_width_ = 640; - top_sl_height_ = 480; - // For this 3 temporal layer case, pattern repeats every 4 frames, so choose - // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2). - const int kf_dist = GET_PARAM(2) + 32; - cfg_.kf_max_dist = kf_dist; - key_frame_spacing_ = kf_dist; - ResetModel(); - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78, - 1.15); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3 -// temporal layers. Run VGA clip with 1 thread, and place layer sync frames: -// one at middle layer first, then another one for top layer, and another -// insert for base spatial layer (which forces key frame). -TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TLSyncFrames) { - SetSvcConfig(3, 3); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.kf_max_dist = 9999; - cfg_.rc_dropframe_thresh = 10; - cfg_.rc_target_bitrate = 400; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - top_sl_width_ = 640; - top_sl_height_ = 480; - ResetModel(); - insert_layer_sync_ = 1; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78, - 1.15); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Run SVC encoder for 3 spatial layers, 1 temporal layer, with -// intra-only frame as sync frame on base spatial layer. -// Intra_only is inserted at start and in middle of sequence. -TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL1TLSyncWithIntraOnly) { - SetSvcConfig(3, 1); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 4; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 9999; - cfg_.rc_target_bitrate = 400; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - top_sl_width_ = 640; - top_sl_height_ = 480; - ResetModel(); - insert_layer_sync_ = 1; - // Use intra_only frame for sync on base layer. - force_intra_only_frame_ = 1; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.73, - 1.2); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Run SVC encoder for 2 quality layers (same resolution different, -// bitrates), 1 temporal layer, with screen content mode. -TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2QL1TLScreen) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.ss_number_layers = 2; - cfg_.ts_number_layers = 1; - cfg_.ts_rate_decimator[0] = 1; - cfg_.temporal_layering_mode = 0; - cfg_.g_error_resilient = 1; - cfg_.g_threads = 2; - svc_params_.scaling_factor_num[0] = 1; - svc_params_.scaling_factor_den[0] = 1; - svc_params_.scaling_factor_num[1] = 1; - svc_params_.scaling_factor_den[1] = 1; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 9999; - number_spatial_layers_ = cfg_.ss_number_layers; - number_temporal_layers_ = cfg_.ts_number_layers; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - top_sl_width_ = 640; - top_sl_height_ = 480; - ResetModel(); - tune_content_ = 1; - // Set the layer bitrates, for 2 spatial layers, 1 temporal. - cfg_.rc_target_bitrate = 400; - cfg_.ss_target_bitrate[0] = 100; - cfg_.ss_target_bitrate[1] = 300; - cfg_.layer_target_bitrate[0] = 100; - cfg_.layer_target_bitrate[1] = 300; - for (int sl = 0; sl < 2; ++sl) { - float layer_framerate = 30.0; - layer_target_avg_bandwidth_[sl] = static_cast( - cfg_.layer_target_bitrate[sl] * 1000.0 / layer_framerate); - bits_in_buffer_model_[sl] = - cfg_.layer_target_bitrate[sl] * cfg_.rc_buf_initial_sz; - } - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.73, - 1.25); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Params: speed setting. -class DatarateOnePassCbrSvcPostencodeDrop - : public DatarateOnePassCbrSvc, - public ::libvpx_test::CodecTestWithParam { - public: - DatarateOnePassCbrSvcPostencodeDrop() : DatarateOnePassCbrSvc(GET_PARAM(0)) { - memset(&svc_params_, 0, sizeof(svc_params_)); - } - ~DatarateOnePassCbrSvcPostencodeDrop() override = default; - - protected: - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - speed_setting_ = GET_PARAM(1); - ResetModel(); - } -}; - -// Run SVC encoder for 2 quality layers (same resolution different, -// bitrates), 1 temporal layer, with screen content mode. -TEST_P(DatarateOnePassCbrSvcPostencodeDrop, OnePassCbrSvc2QL1TLScreen) { - cfg_.rc_buf_initial_sz = 200; - cfg_.rc_buf_optimal_sz = 200; - cfg_.rc_buf_sz = 400; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 52; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.ss_number_layers = 2; - cfg_.ts_number_layers = 1; - cfg_.ts_rate_decimator[0] = 1; - cfg_.temporal_layering_mode = 0; - cfg_.g_error_resilient = 1; - cfg_.g_threads = 2; - svc_params_.scaling_factor_num[0] = 1; - svc_params_.scaling_factor_den[0] = 1; - svc_params_.scaling_factor_num[1] = 1; - svc_params_.scaling_factor_den[1] = 1; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 9999; - number_spatial_layers_ = cfg_.ss_number_layers; - number_temporal_layers_ = cfg_.ts_number_layers; - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 300); - top_sl_width_ = 352; - top_sl_height_ = 288; - ResetModel(); - base_speed_setting_ = speed_setting_; - tune_content_ = 1; - use_post_encode_drop_ = 1; - // Set the layer bitrates, for 2 spatial layers, 1 temporal. - cfg_.rc_target_bitrate = 400; - cfg_.ss_target_bitrate[0] = 100; - cfg_.ss_target_bitrate[1] = 300; - cfg_.layer_target_bitrate[0] = 100; - cfg_.layer_target_bitrate[1] = 300; - for (int sl = 0; sl < 2; ++sl) { - float layer_framerate = 30.0; - layer_target_avg_bandwidth_[sl] = static_cast( - cfg_.layer_target_bitrate[sl] * 1000.0 / layer_framerate); - bits_in_buffer_model_[sl] = - cfg_.layer_target_bitrate[sl] * cfg_.rc_buf_initial_sz; - } - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.73, - 1.25); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcSingleBR, - ::testing::Range(5, 10)); - -VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcPostencodeDrop, - ::testing::Range(5, 6)); - -VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcInterLayerPredSingleBR, - ::testing::Range(5, 10), ::testing::Range(0, 3)); - -VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcMultiBR, - ::testing::Range(5, 10), ::testing::Range(0, 3)); - -VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcFrameDropMultiBR, - ::testing::Range(5, 10), ::testing::Range(0, 2), - ::testing::Range(0, 3)); - -#if CONFIG_VP9_TEMPORAL_DENOISING -VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcDenoiser, - ::testing::Range(5, 10), ::testing::Range(1, 3), - ::testing::Range(0, 3), ::testing::Range(0, 4)); -#endif - -VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcSmallKF, - ::testing::Range(5, 10), ::testing::Range(32, 36)); -} // namespace -} // namespace svc_test diff --git a/presentation/src/main/cpp/third_party/libvpx/test/svc_end_to_end_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/svc_end_to_end_test.cc deleted file mode 100644 index ea60ddc6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/svc_end_to_end_test.cc +++ /dev/null @@ -1,825 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "./vpx_config.h" -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/svc_test.h" -#include "test/util.h" -#include "test/y4m_video_source.h" -#include "vp9/common/vp9_onyxc_int.h" -#include "vpx/vpx_codec.h" -#include "vpx_ports/bitops.h" - -namespace svc_test { -namespace { - -typedef enum { - // Inter-layer prediction is on on all frames. - INTER_LAYER_PRED_ON, - // Inter-layer prediction is off on all frames. - INTER_LAYER_PRED_OFF, - // Inter-layer prediction is off on non-key frames and non-sync frames. - INTER_LAYER_PRED_OFF_NONKEY, - // Inter-layer prediction is on on all frames, but constrained such - // that any layer S (> 0) can only predict from previous spatial - // layer S-1, from the same superframe. - INTER_LAYER_PRED_ON_CONSTRAINED -} INTER_LAYER_PRED; - -class ScalePartitionOnePassCbrSvc - : public OnePassCbrSvc, - public ::testing::TestWithParam { - public: - ScalePartitionOnePassCbrSvc() - : OnePassCbrSvc(GetParam()), mismatch_nframes_(0), num_nonref_frames_(0) { - SetMode(::libvpx_test::kRealTime); - } - - protected: - ~ScalePartitionOnePassCbrSvc() override = default; - - void SetUp() override { - InitializeConfig(); - speed_setting_ = 7; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - PreEncodeFrameHookSetup(video, encoder); - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - // Keep track of number of non-reference frames, needed for mismatch check. - // Non-reference frames are top spatial and temporal layer frames, - // for TL > 0. - if (temporal_layer_id_ == number_temporal_layers_ - 1 && - temporal_layer_id_ > 0 && - pkt->data.frame.spatial_layer_encoded[number_spatial_layers_ - 1]) - num_nonref_frames_++; - } - - void MismatchHook(const vpx_image_t * /*img1*/, - const vpx_image_t * /*img2*/) override { - ++mismatch_nframes_; - } - - void SetConfig(const int /*num_temporal_layer*/) override {} - - unsigned int GetMismatchFrames() const { return mismatch_nframes_; } - unsigned int GetNonRefFrames() const { return num_nonref_frames_; } - - private: - unsigned int mismatch_nframes_; - unsigned int num_nonref_frames_; -}; - -TEST_P(ScalePartitionOnePassCbrSvc, OnePassCbrSvc3SL3TL1080P) { - SetSvcConfig(3, 3); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 10; - cfg_.rc_target_bitrate = 800; - cfg_.kf_max_dist = 9999; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.g_error_resilient = 1; - cfg_.ts_rate_decimator[0] = 4; - cfg_.ts_rate_decimator[1] = 2; - cfg_.ts_rate_decimator[2] = 1; - cfg_.temporal_layering_mode = 3; - ::libvpx_test::I420VideoSource video( - "slides_code_term_web_plot.1920_1080.yuv", 1920, 1080, 30, 1, 0, 100); - // For this 3 temporal layer case, pattern repeats every 4 frames, so choose - // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2). - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Params: Inter layer prediction modes. -class SyncFrameOnePassCbrSvc : public OnePassCbrSvc, - public ::libvpx_test::CodecTestWithParam { - public: - SyncFrameOnePassCbrSvc() - : OnePassCbrSvc(GET_PARAM(0)), current_video_frame_(0), - frame_to_start_decode_(0), frame_to_sync_(0), - inter_layer_pred_mode_(GET_PARAM(1)), decode_to_layer_before_sync_(-1), - decode_to_layer_after_sync_(-1), denoiser_on_(0), - intra_only_test_(false), loopfilter_off_(0), mismatch_nframes_(0), - num_nonref_frames_(0) { - SetMode(::libvpx_test::kRealTime); - memset(&svc_layer_sync_, 0, sizeof(svc_layer_sync_)); - } - - protected: - ~SyncFrameOnePassCbrSvc() override = default; - - void SetUp() override { - InitializeConfig(); - speed_setting_ = 7; - } - - bool DoDecode() const override { - return current_video_frame_ >= frame_to_start_decode_; - } - - // Example pattern for spatial layers and 2 temporal layers used in the - // bypass/flexible mode. The pattern corresponds to the pattern - // VP9E_TEMPORAL_LAYERING_MODE_0101 (temporal_layering_mode == 2) used in - // non-flexible mode. - void set_frame_flags_bypass_mode( - int tl, int num_spatial_layers, int is_key_frame, - vpx_svc_ref_frame_config_t *ref_frame_config) { - int sl; - for (sl = 0; sl < num_spatial_layers; ++sl) - ref_frame_config->update_buffer_slot[sl] = 0; - - for (sl = 0; sl < num_spatial_layers; ++sl) { - // Set the buffer idx. - if (tl == 0) { - ref_frame_config->lst_fb_idx[sl] = sl; - if (sl) { - if (is_key_frame) { - ref_frame_config->lst_fb_idx[sl] = sl - 1; - ref_frame_config->gld_fb_idx[sl] = sl; - } else { - ref_frame_config->gld_fb_idx[sl] = sl - 1; - } - } else { - ref_frame_config->gld_fb_idx[sl] = 0; - } - ref_frame_config->alt_fb_idx[sl] = 0; - } else if (tl == 1) { - ref_frame_config->lst_fb_idx[sl] = sl; - ref_frame_config->gld_fb_idx[sl] = - (sl == 0) ? 0 : num_spatial_layers + sl - 1; - ref_frame_config->alt_fb_idx[sl] = num_spatial_layers + sl; - } - // Set the reference and update flags. - if (!tl) { - if (!sl) { - // Base spatial and base temporal (sl = 0, tl = 0) - ref_frame_config->reference_last[sl] = 1; - ref_frame_config->reference_golden[sl] = 0; - ref_frame_config->reference_alt_ref[sl] = 0; - ref_frame_config->update_buffer_slot[sl] |= - 1 << ref_frame_config->lst_fb_idx[sl]; - } else { - if (is_key_frame) { - ref_frame_config->reference_last[sl] = 1; - ref_frame_config->reference_golden[sl] = 0; - ref_frame_config->reference_alt_ref[sl] = 0; - ref_frame_config->update_buffer_slot[sl] |= - 1 << ref_frame_config->gld_fb_idx[sl]; - } else { - // Non-zero spatiall layer. - ref_frame_config->reference_last[sl] = 1; - ref_frame_config->reference_golden[sl] = 1; - ref_frame_config->reference_alt_ref[sl] = 1; - ref_frame_config->update_buffer_slot[sl] |= - 1 << ref_frame_config->lst_fb_idx[sl]; - } - } - } else if (tl == 1) { - if (!sl) { - // Base spatial and top temporal (tl = 1) - ref_frame_config->reference_last[sl] = 1; - ref_frame_config->reference_golden[sl] = 0; - ref_frame_config->reference_alt_ref[sl] = 0; - ref_frame_config->update_buffer_slot[sl] |= - 1 << ref_frame_config->alt_fb_idx[sl]; - } else { - // Non-zero spatial. - if (sl < num_spatial_layers - 1) { - ref_frame_config->reference_last[sl] = 1; - ref_frame_config->reference_golden[sl] = 1; - ref_frame_config->reference_alt_ref[sl] = 0; - ref_frame_config->update_buffer_slot[sl] |= - 1 << ref_frame_config->alt_fb_idx[sl]; - } else if (sl == num_spatial_layers - 1) { - // Top spatial and top temporal (non-reference -- doesn't - // update any reference buffers). - ref_frame_config->reference_last[sl] = 1; - ref_frame_config->reference_golden[sl] = 1; - ref_frame_config->reference_alt_ref[sl] = 0; - } - } - } - } - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - current_video_frame_ = video->frame(); - PreEncodeFrameHookSetup(video, encoder); - if (video->frame() == 0) { - // Do not turn off inter-layer pred completely because simulcast mode - // fails. - if (inter_layer_pred_mode_ != INTER_LAYER_PRED_OFF) - encoder->Control(VP9E_SET_SVC_INTER_LAYER_PRED, inter_layer_pred_mode_); - encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_); - if (intra_only_test_) - // Decoder sets the color_space for Intra-only frames - // to BT_601 (see line 1810 in vp9_decodeframe.c). - // So set it here in these tess to avoid encoder-decoder - // mismatch check on color space setting. - encoder->Control(VP9E_SET_COLOR_SPACE, VPX_CS_BT_601); - - encoder->Control(VP9E_SET_DISABLE_LOOPFILTER, loopfilter_off_); - } - if (flexible_mode_) { - vpx_svc_layer_id_t layer_id; - layer_id.spatial_layer_id = 0; - layer_id.temporal_layer_id = (video->frame() % 2 != 0); - temporal_layer_id_ = layer_id.temporal_layer_id; - for (int i = 0; i < number_spatial_layers_; i++) { - layer_id.temporal_layer_id_per_spatial[i] = temporal_layer_id_; - ref_frame_config_.duration[i] = 1; - } - encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id); - set_frame_flags_bypass_mode(layer_id.temporal_layer_id, - number_spatial_layers_, 0, - &ref_frame_config_); - encoder->Control(VP9E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config_); - } - if (video->frame() == frame_to_sync_) { - encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync_); - } - } - -#if CONFIG_VP9_DECODER - void PreDecodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Decoder *decoder) override { - if (video->frame() < frame_to_sync_) { - if (decode_to_layer_before_sync_ >= 0) - decoder->Control(VP9_DECODE_SVC_SPATIAL_LAYER, - decode_to_layer_before_sync_); - } else { - if (decode_to_layer_after_sync_ >= 0) { - int decode_to_layer = decode_to_layer_after_sync_; - // Overlay frame is additional layer for intra-only. - if (video->frame() == frame_to_sync_ && intra_only_test_ && - decode_to_layer_after_sync_ == 0 && number_spatial_layers_ > 1) - decode_to_layer += 1; - decoder->Control(VP9_DECODE_SVC_SPATIAL_LAYER, decode_to_layer); - } - } - } -#endif - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - // Keep track of number of non-reference frames, needed for mismatch check. - // Non-reference frames are top spatial and temporal layer frames, - // for TL > 0. - if (temporal_layer_id_ == number_temporal_layers_ - 1 && - temporal_layer_id_ > 0 && - pkt->data.frame.spatial_layer_encoded[number_spatial_layers_ - 1] && - current_video_frame_ >= frame_to_sync_) - num_nonref_frames_++; - - if (intra_only_test_ && current_video_frame_ == frame_to_sync_) { - // Intra-only frame is only generated for spatial layers > 1 and <= 3, - // among other conditions (see constraint in set_intra_only_frame(). If - // intra-only is no allowed then encoder will insert key frame instead. - const bool key_frame = - (pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false; - if (number_spatial_layers_ == 1 || number_spatial_layers_ > 3) - ASSERT_TRUE(key_frame); - else - ASSERT_FALSE(key_frame); - } - } - - void MismatchHook(const vpx_image_t * /*img1*/, - const vpx_image_t * /*img2*/) override { - if (current_video_frame_ >= frame_to_sync_) ++mismatch_nframes_; - } - - unsigned int GetMismatchFrames() const { return mismatch_nframes_; } - unsigned int GetNonRefFrames() const { return num_nonref_frames_; } - - unsigned int current_video_frame_; - unsigned int frame_to_start_decode_; - unsigned int frame_to_sync_; - int inter_layer_pred_mode_; - int decode_to_layer_before_sync_; - int decode_to_layer_after_sync_; - int denoiser_on_; - bool intra_only_test_; - int loopfilter_off_; - vpx_svc_spatial_layer_sync_t svc_layer_sync_; - unsigned int mismatch_nframes_; - unsigned int num_nonref_frames_; - bool flexible_mode_; - vpx_svc_ref_frame_config_t ref_frame_config_; - - private: - void SetConfig(const int num_temporal_layer) override { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.g_error_resilient = 1; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 30; - cfg_.kf_max_dist = 9999; - if (num_temporal_layer == 3) { - cfg_.ts_rate_decimator[0] = 4; - cfg_.ts_rate_decimator[1] = 2; - cfg_.ts_rate_decimator[2] = 1; - cfg_.temporal_layering_mode = 3; - } else if (num_temporal_layer == 2) { - cfg_.ts_rate_decimator[0] = 2; - cfg_.ts_rate_decimator[1] = 1; - cfg_.temporal_layering_mode = 2; - } else if (num_temporal_layer == 1) { - cfg_.ts_rate_decimator[0] = 1; - cfg_.temporal_layering_mode = 0; - } - } -}; - -// Test for sync layer for 1 pass CBR SVC: 3 spatial layers and -// 3 temporal layers. Only start decoding on the sync layer. -// Full sync: insert key frame on base layer. -TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLFullSync) { - SetSvcConfig(3, 3); - // Sync is on base layer so the frame to sync and the frame to start decoding - // is the same. - frame_to_start_decode_ = 20; - frame_to_sync_ = 20; - decode_to_layer_before_sync_ = -1; - decode_to_layer_after_sync_ = 2; - - // Set up svc layer sync structure. - svc_layer_sync_.base_layer_intra_only = 0; - svc_layer_sync_.spatial_layer_sync[0] = 1; - - ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60); - - cfg_.rc_target_bitrate = 600; - flexible_mode_ = false; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Test for sync layer for 1 pass CBR SVC: 2 spatial layers and -// 3 temporal layers. Decoding QVGA before sync frame and decode up to -// VGA on and after sync. -TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc2SL3TLSyncToVGA) { - SetSvcConfig(2, 3); - frame_to_start_decode_ = 0; - frame_to_sync_ = 100; - decode_to_layer_before_sync_ = 0; - decode_to_layer_after_sync_ = 1; - - // Set up svc layer sync structure. - svc_layer_sync_.base_layer_intra_only = 0; - svc_layer_sync_.spatial_layer_sync[0] = 0; - svc_layer_sync_.spatial_layer_sync[1] = 1; - - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - cfg_.rc_target_bitrate = 400; - flexible_mode_ = false; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Test for sync layer for 1 pass CBR SVC: 3 spatial layers and -// 3 temporal layers. Decoding QVGA and VGA before sync frame and decode up to -// HD on and after sync. -TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncToHD) { - SetSvcConfig(3, 3); - frame_to_start_decode_ = 0; - frame_to_sync_ = 20; - decode_to_layer_before_sync_ = 1; - decode_to_layer_after_sync_ = 2; - - // Set up svc layer sync structure. - svc_layer_sync_.base_layer_intra_only = 0; - svc_layer_sync_.spatial_layer_sync[0] = 0; - svc_layer_sync_.spatial_layer_sync[1] = 0; - svc_layer_sync_.spatial_layer_sync[2] = 1; - - ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60); - cfg_.rc_target_bitrate = 600; - flexible_mode_ = false; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Test for sync layer for 1 pass CBR SVC: 3 spatial layers and -// 3 temporal layers. Decoding QVGA before sync frame and decode up to -// HD on and after sync. -TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncToVGAHD) { - SetSvcConfig(3, 3); - frame_to_start_decode_ = 0; - frame_to_sync_ = 20; - decode_to_layer_before_sync_ = 0; - decode_to_layer_after_sync_ = 2; - - // Set up svc layer sync structure. - svc_layer_sync_.base_layer_intra_only = 0; - svc_layer_sync_.spatial_layer_sync[0] = 0; - svc_layer_sync_.spatial_layer_sync[1] = 1; - svc_layer_sync_.spatial_layer_sync[2] = 1; - - ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60); - cfg_.rc_target_bitrate = 600; - flexible_mode_ = false; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -#if CONFIG_VP9_TEMPORAL_DENOISING -// Test for sync layer for 1 pass CBR SVC: 2 spatial layers and -// 3 temporal layers. Decoding QVGA before sync frame and decode up to -// VGA on and after sync. -TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc2SL3TLSyncFrameVGADenoise) { - SetSvcConfig(2, 3); - frame_to_start_decode_ = 0; - frame_to_sync_ = 100; - decode_to_layer_before_sync_ = 0; - decode_to_layer_after_sync_ = 1; - - denoiser_on_ = 1; - // Set up svc layer sync structure. - svc_layer_sync_.base_layer_intra_only = 0; - svc_layer_sync_.spatial_layer_sync[0] = 0; - svc_layer_sync_.spatial_layer_sync[1] = 1; - - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - cfg_.rc_target_bitrate = 400; - flexible_mode_ = false; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} -#endif - -// Encode 3 spatial, 2 temporal layer in flexible mode but don't -// start decoding. During the sequence insert intra-only on base/qvga -// layer at frame 20 and start decoding only QVGA layer from there. -TEST_P(SyncFrameOnePassCbrSvc, - OnePassCbrSvc3SL3TLSyncFrameStartDecodeOnIntraOnlyQVGAFlex) { - SetSvcConfig(3, 2); - frame_to_start_decode_ = 20; - frame_to_sync_ = 20; - decode_to_layer_before_sync_ = 2; - decode_to_layer_after_sync_ = 0; - intra_only_test_ = true; - - // Set up svc layer sync structure. - svc_layer_sync_.base_layer_intra_only = 1; - svc_layer_sync_.spatial_layer_sync[0] = 1; - svc_layer_sync_.spatial_layer_sync[1] = 0; - svc_layer_sync_.spatial_layer_sync[2] = 0; - - ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60); - cfg_.rc_target_bitrate = 600; - flexible_mode_ = true; - AssignLayerBitrates(); - cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - // Can't check mismatch here because only base is decoded at - // frame sync, whereas encoder continues encoding all layers. -} - -// Encode 3 spatial, 3 temporal layer but don't start decoding. -// During the sequence insert intra-only on base/qvga layer at frame 20 -// and start decoding only QVGA layer from there. -TEST_P(SyncFrameOnePassCbrSvc, - OnePassCbrSvc3SL3TLSyncFrameStartDecodeOnIntraOnlyQVGA) { - SetSvcConfig(3, 3); - frame_to_start_decode_ = 20; - frame_to_sync_ = 20; - decode_to_layer_before_sync_ = 2; - decode_to_layer_after_sync_ = 0; - intra_only_test_ = true; - - // Set up svc layer sync structure. - svc_layer_sync_.base_layer_intra_only = 1; - svc_layer_sync_.spatial_layer_sync[0] = 1; - svc_layer_sync_.spatial_layer_sync[1] = 0; - svc_layer_sync_.spatial_layer_sync[2] = 0; - - ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60); - cfg_.rc_target_bitrate = 600; - flexible_mode_ = false; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - // Can't check mismatch here because only base is decoded at - // frame sync, whereas encoder continues encoding all layers. -} - -// Start decoding from beginning of sequence, during sequence insert intra-only -// on base/qvga layer. Decode all layers. -TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncFrameIntraOnlyQVGA) { - SetSvcConfig(3, 3); - frame_to_start_decode_ = 0; - frame_to_sync_ = 20; - decode_to_layer_before_sync_ = 2; - // The superframe containing intra-only layer will have +1 frames. Thus set - // the layer to decode after sync frame to +1 from - // decode_to_layer_before_sync. - decode_to_layer_after_sync_ = 3; - intra_only_test_ = true; - - // Set up svc layer sync structure. - svc_layer_sync_.base_layer_intra_only = 1; - svc_layer_sync_.spatial_layer_sync[0] = 1; - svc_layer_sync_.spatial_layer_sync[1] = 0; - svc_layer_sync_.spatial_layer_sync[2] = 0; - - ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60); - cfg_.rc_target_bitrate = 600; - flexible_mode_ = false; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Start decoding from beginning of sequence, during sequence insert intra-only -// on base/qvga layer and sync_layer on middle/VGA layer. Decode all layers. -TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncFrameIntraOnlyVGA) { - SetSvcConfig(3, 3); - frame_to_start_decode_ = 0; - frame_to_sync_ = 20; - decode_to_layer_before_sync_ = 2; - // The superframe containing intra-only layer will have +1 frames. Thus set - // the layer to decode after sync frame to +1 from - // decode_to_layer_before_sync. - decode_to_layer_after_sync_ = 3; - intra_only_test_ = true; - - // Set up svc layer sync structure. - svc_layer_sync_.base_layer_intra_only = 1; - svc_layer_sync_.spatial_layer_sync[0] = 1; - svc_layer_sync_.spatial_layer_sync[1] = 1; - svc_layer_sync_.spatial_layer_sync[2] = 0; - - ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60); - cfg_.rc_target_bitrate = 600; - flexible_mode_ = false; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Start decoding from sync frame, insert intra-only on base/qvga layer. Decode -// all layers. For 1 spatial layer, it inserts a key frame. -TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc1SL3TLSyncFrameIntraOnlyQVGA) { - SetSvcConfig(1, 3); - frame_to_start_decode_ = 20; - frame_to_sync_ = 20; - decode_to_layer_before_sync_ = 0; - decode_to_layer_after_sync_ = 0; - intra_only_test_ = true; - - // Set up svc layer sync structure. - svc_layer_sync_.base_layer_intra_only = 1; - svc_layer_sync_.spatial_layer_sync[0] = 1; - - ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60); - cfg_.rc_target_bitrate = 600; - flexible_mode_ = false; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -#if CONFIG_VP9_DECODER - // The non-reference frames are expected to be mismatched frames as the - // encoder will avoid loopfilter on these frames. - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); -#endif -} - -// Params: Loopfilter modes. -class LoopfilterOnePassCbrSvc : public OnePassCbrSvc, - public ::libvpx_test::CodecTestWithParam { - public: - LoopfilterOnePassCbrSvc() - : OnePassCbrSvc(GET_PARAM(0)), loopfilter_off_(GET_PARAM(1)), - mismatch_nframes_(0), num_nonref_frames_(0) { - SetMode(::libvpx_test::kRealTime); - } - - protected: - ~LoopfilterOnePassCbrSvc() override = default; - - void SetUp() override { - InitializeConfig(); - speed_setting_ = 7; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - PreEncodeFrameHookSetup(video, encoder); - if (number_temporal_layers_ > 1 || number_spatial_layers_ > 1) { - // Consider 3 cases: - if (loopfilter_off_ == 0) { - // loopfilter is on for all spatial layers on every superrframe. - for (int i = 0; i < VPX_SS_MAX_LAYERS; ++i) { - svc_params_.loopfilter_ctrl[i] = 0; - } - } else if (loopfilter_off_ == 1) { - // loopfilter is off for non-reference frames for all spatial layers. - for (int i = 0; i < VPX_SS_MAX_LAYERS; ++i) { - svc_params_.loopfilter_ctrl[i] = 1; - } - } else { - // loopfilter is off for all SL0 frames, and off only for non-reference - // frames for SL > 0. - svc_params_.loopfilter_ctrl[0] = 2; - for (int i = 1; i < VPX_SS_MAX_LAYERS; ++i) { - svc_params_.loopfilter_ctrl[i] = 1; - } - } - encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_); - } else if (number_temporal_layers_ == 1 && number_spatial_layers_ == 1) { - // For non-SVC mode use the single layer control. - encoder->Control(VP9E_SET_DISABLE_LOOPFILTER, loopfilter_off_); - } - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - // Keep track of number of non-reference frames, needed for mismatch check. - // Non-reference frames are top spatial and temporal layer frames, - // for TL > 0. - if (temporal_layer_id_ == number_temporal_layers_ - 1 && - temporal_layer_id_ > 0 && - pkt->data.frame.spatial_layer_encoded[number_spatial_layers_ - 1]) - num_nonref_frames_++; - } - - void MismatchHook(const vpx_image_t * /*img1*/, - const vpx_image_t * /*img2*/) override { - ++mismatch_nframes_; - } - - void SetConfig(const int /*num_temporal_layer*/) override {} - - int GetMismatchFrames() const { return mismatch_nframes_; } - int GetNonRefFrames() const { return num_nonref_frames_; } - - int loopfilter_off_; - - private: - int mismatch_nframes_; - int num_nonref_frames_; -}; - -TEST_P(LoopfilterOnePassCbrSvc, OnePassCbrSvc1SL1TLLoopfilterOff) { - SetSvcConfig(1, 1); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 0; - cfg_.rc_target_bitrate = 800; - cfg_.kf_max_dist = 9999; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.g_error_resilient = 1; - cfg_.ts_rate_decimator[0] = 1; - cfg_.temporal_layering_mode = 0; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - cfg_.rc_target_bitrate = 600; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -#if CONFIG_VP9_DECODER - if (loopfilter_off_ == 0) - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); - else - EXPECT_EQ(GetMismatchFrames(), 0); -#endif -} - -TEST_P(LoopfilterOnePassCbrSvc, OnePassCbrSvc1SL3TLLoopfilterOff) { - SetSvcConfig(1, 3); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 0; - cfg_.rc_target_bitrate = 800; - cfg_.kf_max_dist = 9999; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.g_error_resilient = 1; - cfg_.ts_rate_decimator[0] = 4; - cfg_.ts_rate_decimator[1] = 2; - cfg_.ts_rate_decimator[2] = 1; - cfg_.temporal_layering_mode = 3; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - cfg_.rc_target_bitrate = 600; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -#if CONFIG_VP9_DECODER - if (loopfilter_off_ == 0) - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); - else - EXPECT_EQ(GetMismatchFrames(), 0); -#endif -} - -TEST_P(LoopfilterOnePassCbrSvc, OnePassCbrSvc3SL3TLLoopfilterOff) { - SetSvcConfig(3, 3); - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_threads = 1; - cfg_.rc_dropframe_thresh = 0; - cfg_.rc_target_bitrate = 800; - cfg_.kf_max_dist = 9999; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.g_error_resilient = 1; - cfg_.ts_rate_decimator[0] = 4; - cfg_.ts_rate_decimator[1] = 2; - cfg_.ts_rate_decimator[2] = 1; - cfg_.temporal_layering_mode = 3; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - cfg_.rc_target_bitrate = 600; - AssignLayerBitrates(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -#if CONFIG_VP9_DECODER - if (loopfilter_off_ == 0) - EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); - else - EXPECT_EQ(GetMismatchFrames(), 0); -#endif -} - -VP9_INSTANTIATE_TEST_SUITE(SyncFrameOnePassCbrSvc, ::testing::Range(0, 3)); - -VP9_INSTANTIATE_TEST_SUITE(LoopfilterOnePassCbrSvc, ::testing::Range(0, 3)); - -INSTANTIATE_TEST_SUITE_P( - VP9, ScalePartitionOnePassCbrSvc, - ::testing::Values( - static_cast(&libvpx_test::kVP9))); - -} // namespace -} // namespace svc_test diff --git a/presentation/src/main/cpp/third_party/libvpx/test/svc_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/svc_test.cc deleted file mode 100644 index cbc0abe0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/svc_test.cc +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "test/svc_test.h" - -namespace svc_test { -void OnePassCbrSvc::SetSvcConfig(const int num_spatial_layer, - const int num_temporal_layer) { - SetConfig(num_temporal_layer); - cfg_.ss_number_layers = num_spatial_layer; - cfg_.ts_number_layers = num_temporal_layer; - if (num_spatial_layer == 1) { - svc_params_.scaling_factor_num[0] = 288; - svc_params_.scaling_factor_den[0] = 288; - } else if (num_spatial_layer == 2) { - svc_params_.scaling_factor_num[0] = 144; - svc_params_.scaling_factor_den[0] = 288; - svc_params_.scaling_factor_num[1] = 288; - svc_params_.scaling_factor_den[1] = 288; - } else if (num_spatial_layer == 3) { - svc_params_.scaling_factor_num[0] = 72; - svc_params_.scaling_factor_den[0] = 288; - svc_params_.scaling_factor_num[1] = 144; - svc_params_.scaling_factor_den[1] = 288; - svc_params_.scaling_factor_num[2] = 288; - svc_params_.scaling_factor_den[2] = 288; - } - number_spatial_layers_ = cfg_.ss_number_layers; - number_temporal_layers_ = cfg_.ts_number_layers; -} - -void OnePassCbrSvc::PreEncodeFrameHookSetup(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) { - if (video->frame() == 0) { - for (int i = 0; i < VPX_MAX_LAYERS; ++i) { - svc_params_.max_quantizers[i] = 63; - svc_params_.min_quantizers[i] = 0; - } - if (number_temporal_layers_ > 1 || number_spatial_layers_ > 1) { - svc_params_.speed_per_layer[0] = base_speed_setting_; - for (int i = 1; i < VPX_SS_MAX_LAYERS; ++i) { - svc_params_.speed_per_layer[i] = speed_setting_; - } - encoder->Control(VP9E_SET_SVC, 1); - encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_); - } - encoder->Control(VP8E_SET_CPUUSED, speed_setting_); - encoder->Control(VP9E_SET_AQ_MODE, 3); - encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 300); - encoder->Control(VP9E_SET_TILE_COLUMNS, get_msb(cfg_.g_threads)); - encoder->Control(VP9E_SET_ROW_MT, 1); - encoder->Control(VP8E_SET_STATIC_THRESHOLD, 1); - } - - superframe_count_++; - temporal_layer_id_ = 0; - if (number_temporal_layers_ == 2) { - temporal_layer_id_ = (superframe_count_ % 2 != 0); - } else if (number_temporal_layers_ == 3) { - if (superframe_count_ % 2 != 0) temporal_layer_id_ = 2; - if (superframe_count_ > 1) { - if ((superframe_count_ - 2) % 4 == 0) temporal_layer_id_ = 1; - } - } - - frame_flags_ = 0; -} - -void OnePassCbrSvc::PostEncodeFrameHook(::libvpx_test::Encoder *encoder) { - vpx_svc_layer_id_t layer_id; - encoder->Control(VP9E_GET_SVC_LAYER_ID, &layer_id); - temporal_layer_id_ = layer_id.temporal_layer_id; - for (int sl = 0; sl < number_spatial_layers_; ++sl) { - for (int tl = temporal_layer_id_; tl < number_temporal_layers_; ++tl) { - const int layer = sl * number_temporal_layers_ + tl; - bits_in_buffer_model_[layer] += - static_cast(layer_target_avg_bandwidth_[layer]); - } - } -} - -void OnePassCbrSvc::AssignLayerBitrates() { - int sl, spatial_layer_target; - int spatial_layers = cfg_.ss_number_layers; - int temporal_layers = cfg_.ts_number_layers; - float total = 0; - float alloc_ratio[VPX_MAX_LAYERS] = { 0 }; - float framerate = 30.0; - for (sl = 0; sl < spatial_layers; ++sl) { - if (svc_params_.scaling_factor_den[sl] > 0) { - alloc_ratio[sl] = - static_cast((svc_params_.scaling_factor_num[sl] * 1.0 / - svc_params_.scaling_factor_den[sl])); - total += alloc_ratio[sl]; - } - } - for (sl = 0; sl < spatial_layers; ++sl) { - cfg_.ss_target_bitrate[sl] = spatial_layer_target = - static_cast(cfg_.rc_target_bitrate * alloc_ratio[sl] / - total); - const int index = sl * temporal_layers; - if (cfg_.temporal_layering_mode == 3) { - cfg_.layer_target_bitrate[index] = spatial_layer_target >> 1; - cfg_.layer_target_bitrate[index + 1] = - (spatial_layer_target >> 1) + (spatial_layer_target >> 2); - cfg_.layer_target_bitrate[index + 2] = spatial_layer_target; - } else if (cfg_.temporal_layering_mode == 2) { - cfg_.layer_target_bitrate[index] = spatial_layer_target * 2 / 3; - cfg_.layer_target_bitrate[index + 1] = spatial_layer_target; - } else if (cfg_.temporal_layering_mode <= 1) { - cfg_.layer_target_bitrate[index] = spatial_layer_target; - } - } - for (sl = 0; sl < spatial_layers; ++sl) { - for (int tl = 0; tl < temporal_layers; ++tl) { - const int layer = sl * temporal_layers + tl; - float layer_framerate = framerate; - if (temporal_layers == 2 && tl == 0) layer_framerate = framerate / 2; - if (temporal_layers == 3 && tl == 0) layer_framerate = framerate / 4; - if (temporal_layers == 3 && tl == 1) layer_framerate = framerate / 2; - layer_target_avg_bandwidth_[layer] = static_cast( - cfg_.layer_target_bitrate[layer] * 1000.0 / layer_framerate); - bits_in_buffer_model_[layer] = - cfg_.layer_target_bitrate[layer] * cfg_.rc_buf_initial_sz; - } - } -} -} // namespace svc_test diff --git a/presentation/src/main/cpp/third_party/libvpx/test/svc_test.h b/presentation/src/main/cpp/third_party/libvpx/test/svc_test.h deleted file mode 100644 index de39412f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/svc_test.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_TEST_SVC_TEST_H_ -#define VPX_TEST_SVC_TEST_H_ - -#include "./vpx_config.h" -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" -#include "test/y4m_video_source.h" -#include "vpx/vpx_codec.h" -#include "vpx_ports/bitops.h" - -namespace svc_test { -class OnePassCbrSvc : public ::libvpx_test::EncoderTest { - public: - explicit OnePassCbrSvc(const ::libvpx_test::CodecFactory *codec) - : EncoderTest(codec), base_speed_setting_(0), speed_setting_(0), - superframe_count_(0), temporal_layer_id_(0), number_temporal_layers_(0), - number_spatial_layers_(0) { - memset(&svc_params_, 0, sizeof(svc_params_)); - memset(bits_in_buffer_model_, 0, - sizeof(bits_in_buffer_model_[0]) * VPX_MAX_LAYERS); - memset(layer_target_avg_bandwidth_, 0, - sizeof(layer_target_avg_bandwidth_[0]) * VPX_MAX_LAYERS); - } - - protected: - ~OnePassCbrSvc() override {} - - virtual void SetConfig(const int num_temporal_layer) = 0; - - virtual void SetSvcConfig(const int num_spatial_layer, - const int num_temporal_layer); - - virtual void PreEncodeFrameHookSetup(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder); - - void PostEncodeFrameHook(::libvpx_test::Encoder *encoder) override; - - virtual void AssignLayerBitrates(); - - void MismatchHook(const vpx_image_t *, const vpx_image_t *) override {} - - vpx_svc_extra_cfg_t svc_params_; - int64_t bits_in_buffer_model_[VPX_MAX_LAYERS]; - int layer_target_avg_bandwidth_[VPX_MAX_LAYERS]; - int base_speed_setting_; - int speed_setting_; - int superframe_count_; - int temporal_layer_id_; - int number_temporal_layers_; - int number_spatial_layers_; -}; -} // namespace svc_test - -#endif // VPX_TEST_SVC_TEST_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/test-data.mk b/presentation/src/main/cpp/third_party/libvpx/test/test-data.mk deleted file mode 100644 index 75110fc2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/test-data.mk +++ /dev/null @@ -1,901 +0,0 @@ -LIBVPX_TEST_SRCS-yes += test-data.mk - -# Encoder test source -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += hantro_collage_w352h288.yuv -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += hantro_collage_w352h288_nv12.yuv -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += hantro_odd.yuv -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += desktop_office1.1280_720-020.yuv -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += slides_code_term_web_plot.1920_1080.yuv -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += desktopqvga.320_240.yuv - -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_420_20f.y4m -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_422_20f.y4m -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_444_20f.y4m -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_440.yuv -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_420_20f.y4m -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_422_20f.y4m -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_444_20f.y4m -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_440.yuv -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_420_a10-1.y4m -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_420.y4m -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_422.y4m -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_444.y4m -LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_440.yuv - -LIBVPX_TEST_DATA-$(CONFIG_VP8_ENCODER) += repro-oss-fuzz-69906.y4m - -LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += desktop_credits.y4m -LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.y4m -LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += noisy_clip_640_360.y4m -LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rush_hour_444.y4m -LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += screendata.y4m -LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_640_480_30.yuv -LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += bus_352x288_420_f20_b8.yuv -LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += crowd_run_360p_10_150f.y4m - -# Test vectors -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-001.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-001.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-002.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-002.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-003.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-003.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-004.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-004.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-005.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-005.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-006.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-006.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-007.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-007.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-008.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-008.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-009.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-009.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-010.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-010.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-011.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-011.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-012.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-012.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-013.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-013.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-014.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-014.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-015.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-015.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-016.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-016.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-017.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-017.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-018.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-018.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-01-intra-1400.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-01-intra-1400.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-01-intra-1411.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-01-intra-1411.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-01-intra-1416.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-01-intra-1416.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-01-intra-1417.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-01-intra-1417.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-02-inter-1402.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-02-inter-1402.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-02-inter-1412.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-02-inter-1412.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-02-inter-1418.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-02-inter-1418.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-02-inter-1424.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-02-inter-1424.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-01.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-01.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-02.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-02.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-03.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-03.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-04.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-04.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1401.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1401.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1403.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1403.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1407.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1407.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1408.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1408.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1409.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1409.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1410.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1410.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1413.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1413.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1414.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1414.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1415.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1415.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1425.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1425.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1426.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1426.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1427.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1427.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1432.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1432.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1435.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1435.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1436.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1436.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1437.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1437.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1441.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1441.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1442.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-03-segmentation-1442.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-04-partitions-1404.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-04-partitions-1404.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-04-partitions-1405.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-04-partitions-1405.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-04-partitions-1406.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-04-partitions-1406.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1428.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1428.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1429.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1429.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1430.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1430.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1431.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1431.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1433.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1433.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1434.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1434.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1438.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1438.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1439.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1439.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1440.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1440.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1443.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-05-sharpness-1443.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-06-smallsize.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-06-smallsize.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-00.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-00.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-01.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-01.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-02.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-02.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-03.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-03.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-04.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-04.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-05.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-05.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-06.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-06.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-07.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-07.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-08.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-08.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-09.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-09.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-10.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-10.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-11.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-11.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-12.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-12.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-13.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-13.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-14.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-14.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-15.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-15.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-16.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-16.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-17.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-17.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-18.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-18.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-19.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-19.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-20.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-20.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-21.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-21.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-22.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-22.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-23.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-23.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-24.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-24.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-25.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-25.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-26.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-26.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-27.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-27.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-28.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-28.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-29.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-29.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-30.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-30.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-31.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-31.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-32.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-32.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-33.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-33.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-34.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-34.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-35.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-35.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-36.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-36.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-37.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-37.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-38.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-38.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-39.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-39.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-40.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-40.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-41.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-41.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-42.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-42.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-43.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-43.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-44.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-44.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-45.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-45.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-46.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-46.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-47.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-47.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-48.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-48.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-49.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-49.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-50.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-50.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-51.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-51.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-52.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-52.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-53.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-53.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-54.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-54.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-55.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-55.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-56.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-56.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-57.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-57.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-58.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-58.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-59.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-59.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-60.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-60.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-61.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-61.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-62.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-62.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-63.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-00-quantizer-63.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-1.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-1.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-3.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-3.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-5.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-5.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-6.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-6.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-7.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-01-sharpness-7.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x08.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x08.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x10.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x10.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x16.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x16.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x18.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x18.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x32.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x32.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x34.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x34.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x64.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x64.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x66.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-08x66.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x08.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x08.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x10.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x10.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x16.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x16.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x18.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x18.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x32.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x32.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x34.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x34.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x64.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x64.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x66.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-10x66.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x08.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x08.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x10.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x10.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x16.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x16.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x18.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x18.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x32.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x32.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x34.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x34.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x64.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x64.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x66.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-16x66.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x08.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x08.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x10.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x10.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x16.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x16.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x18.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x18.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x32.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x32.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x34.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x34.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x64.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x64.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x66.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-18x66.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x08.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x08.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x10.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x10.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x16.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x16.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x18.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x18.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x32.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x32.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x34.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x34.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x64.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x64.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x66.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-32x66.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x08.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x08.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x10.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x10.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x16.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x16.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x18.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x18.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x32.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x32.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x34.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x34.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x64.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x64.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x66.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-34x66.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x08.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x08.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x10.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x10.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x16.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x16.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x18.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x18.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x32.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x32.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x34.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x34.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x64.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x64.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x66.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-64x66.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x08.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x08.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x10.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x10.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x16.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x16.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x18.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x18.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x32.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x32.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x34.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x34.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x64.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x64.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x66.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x66.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-130x132.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-130x132.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-132x130.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-132x130.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-132x132.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-132x132.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-178x180.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-178x180.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-180x178.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-180x178.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-180x180.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-180x180.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-lf-1920x1080.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-lf-1920x1080.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-deltaq.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-deltaq.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x196.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x196.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x198.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x198.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x200.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x200.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x202.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x202.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x208.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x208.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x210.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x210.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x224.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x224.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x226.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-196x226.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x196.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x196.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x198.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x198.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x200.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x200.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x202.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x202.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x208.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x208.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x210.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x210.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x224.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x224.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x226.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-198x226.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x196.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x196.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x198.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x198.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x200.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x200.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x202.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x202.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x208.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x208.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x210.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x210.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x224.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x224.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x226.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-200x226.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x196.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x196.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x198.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x198.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x200.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x200.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x202.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x202.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x208.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x208.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x210.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x210.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x224.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x224.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x226.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-202x226.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x196.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x196.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x198.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x198.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x200.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x200.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x202.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x202.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x208.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x208.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x210.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x210.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x224.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x224.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x226.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-208x226.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x196.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x196.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x198.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x198.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x200.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x200.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x202.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x202.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x208.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x208.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x210.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x210.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x224.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x224.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x226.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-210x226.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x196.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x196.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x198.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x198.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x200.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x200.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x202.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x202.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x208.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x208.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x210.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x210.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x224.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x224.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x226.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-224x226.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x196.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x196.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x198.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x198.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x200.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x200.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x202.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x202.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x208.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x208.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x210.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x210.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x224.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x224.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x226.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x226.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-352x288.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-352x288.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-05-resize.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-05-resize.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-06-bilinear.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-06-bilinear.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-07-frame_parallel.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-07-frame_parallel.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-07-frame_parallel-1.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-07-frame_parallel-1.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile-4x1.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile-4x1.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile-4x4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile-4x4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x2_frame_parallel.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x2_frame_parallel.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x4_frame_parallel.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x4_frame_parallel.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x8.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x8.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x8_frame_parallel.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile_1x8_frame_parallel.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-09-aq2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-09-aq2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-09-lf_deltas.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-09-lf_deltas.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-09-subpixel-00.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-09-subpixel-00.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-10-show-existing-frame.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-10-show-existing-frame.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-10-show-existing-frame2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-10-show-existing-frame2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-11-size-351x287.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-11-size-351x287.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-11-size-351x288.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-11-size-351x288.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-11-size-352x287.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-11-size-352x287.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-12-droppable_1.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-12-droppable_1.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-12-droppable_2.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-12-droppable_2.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-12-droppable_3.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-12-droppable_3.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-13-largescaling.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-13-largescaling.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-16.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-16.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-2-4-8-16.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-2-4-8-16.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-8.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-1-8.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-1.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-1.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-8-4-2-1.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-8-4-2-1.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-8.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-16-8.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-2-1.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-2-1.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-2-16.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-2-16.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-2-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-2-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-2-8.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-2-8.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-4-1.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-4-1.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-4-16.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-4-16.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-4-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-4-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-4-8.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-4-8.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-1.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-1.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-16.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-16.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-2-4-8.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-2-4-8.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-8.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-8.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-1.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-1.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-8.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-8.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-1.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-1.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-8.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-8.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-1.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-1.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-4-2-1.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-4-2-1.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-15-segkey.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-15-segkey.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-15-segkey_adpq.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-15-segkey_adpq.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-16-intra-only.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-16-intra-only.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-17-show-existing-frame.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-17-show-existing-frame.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-18-resize.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-18-resize.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip-01.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip-01.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip-02.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip-02.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv422.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv422.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv440.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv440.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv444.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv444.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-20-big_superframe-01.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-20-big_superframe-01.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-20-big_superframe-02.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-20-big_superframe-02.webm.md5 -ifeq ($(CONFIG_VP9_HIGHBITDEPTH),yes) -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp92-2-20-10bit-yuv420.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp92-2-20-10bit-yuv420.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp92-2-20-12bit-yuv420.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp92-2-20-12bit-yuv420.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv422.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv422.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv422.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv422.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv440.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv440.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv440.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv440.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv444.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv444.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv444.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv444.webm.md5 -endif # CONFIG_VP9_HIGHBITDEPTH - -# Invalid files for testing libvpx error checking. -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-bug-1443.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-bug-1443.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-bug-148271109.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-bug-148271109.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-token-partition.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-token-partition.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v3.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v3.webm.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02-v2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02-v2.webm.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03-v3.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03-v3.webm.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-10-show-existing-frame.webm.ivf.s180315_r01-05_b6-.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-10-show-existing-frame.webm.ivf.s180315_r01-05_b6-.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp91-2-mixedrefcsp-444to420.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp91-2-mixedrefcsp-444to420.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-1.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-3.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-629481.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-629481.webm.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-1558.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-1558.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-1562.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-1562.ivf.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-667044.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-667044.webm.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += crbug-1539.rawfile - -ifeq ($(CONFIG_DECODE_PERF_TESTS),yes) -# Encode / Decode test -LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.yuv -# BBB VP9 streams -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_426x240_tile_1x1_180kbps.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_640x360_tile_1x2_337kbps.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_854x480_tile_1x2_651kbps.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_1280x720_tile_1x4_1310kbps.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_1920x1080_tile_1x1_2581kbps.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_1920x1080_tile_1x4_2586kbps.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_1920x1080_tile_1x4_fpm_2304kbps.webm -# Sintel VP9 streams -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-sintel_426x182_tile_1x1_171kbps.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-sintel_640x272_tile_1x2_318kbps.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-sintel_854x364_tile_1x2_621kbps.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-sintel_1280x546_tile_1x4_1257kbps.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-sintel_1920x818_tile_1x4_fpm_2279kbps.webm -# TOS VP9 streams -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-tos_426x178_tile_1x1_181kbps.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-tos_640x266_tile_1x2_336kbps.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-tos_854x356_tile_1x2_656kbps.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-tos_854x356_tile_1x2_fpm_546kbps.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-tos_1280x534_tile_1x4_1306kbps.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-tos_1280x534_tile_1x4_fpm_952kbps.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-tos_1920x800_tile_1x4_fpm_2335kbps.webm -endif # CONFIG_DECODE_PERF_TESTS - -ifeq ($(CONFIG_ENCODE_PERF_TESTS),yes) -LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += desktop_640_360_30.yuv -LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += kirland_640_480_30.yuv -LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += macmarcomoving_640_480_30.yuv -LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += macmarcostationary_640_480_30.yuv -LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.yuv -LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += tacomanarrows_640_480_30.yuv -LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += tacomasmallcameramovement_640_480_30.yuv -LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += thaloundeskmtg_640_480_30.yuv -endif # CONFIG_ENCODE_PERF_TESTS - -# sort and remove duplicates -LIBVPX_TEST_DATA-yes := $(sort $(LIBVPX_TEST_DATA-yes)) - -# VP9 dynamic resizing test (decoder) -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_5_1-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_5_1-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_5_3-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_5_3-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_7_1-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_7_1-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_7_3-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_7_3-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_5_1-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_5_1-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_5_3-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_5_3-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_7_1-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_7_1-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_7_3-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_7_3-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_5_1-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_5_1-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_5_3-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_5_3-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_7_1-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_7_1-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_7_3-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_7_3-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_5_1-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_5_1-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_5_3-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_5_3-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_7_1-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_7_1-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_7_3-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_7_3-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_5_1-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_5_1-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_5_3-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_5_3-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_7_1-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_7_1-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_7_3-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_7_3-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_5_1-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_5_1-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_5_3-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_5_3-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_1-2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_1-2.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_3-4.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_3-4.webm.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-22-svc_1280x720_3.ivf -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-22-svc_1280x720_3.ivf.md5 -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-22-svc_1280x720_1.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-22-svc_1280x720_1.webm.md5 diff --git a/presentation/src/main/cpp/third_party/libvpx/test/test-data.sha1 b/presentation/src/main/cpp/third_party/libvpx/test/test-data.sha1 deleted file mode 100644 index 49f816f8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/test-data.sha1 +++ /dev/null @@ -1,874 +0,0 @@ -3eaf216d9fc8b4b9bb8c3956311f49a85974806c *bus_352x288_420_f20_b8.yuv -d5dfb0151c9051f8c85999255645d7a23916d3c0 *hantro_collage_w352h288.yuv -b87815bf86020c592ccc7a846ba2e28ec8043902 *hantro_odd.yuv -76024eb753cdac6a5e5703aaea189d35c3c30ac7 *invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf -7448d8798a4380162d4b56f9b452e2f6f9e24e7a *invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf.res -83f50908c8dc0ef8760595447a2ff7727489542e *invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf -456d1493e52d32a5c30edf44a27debc1fa6b253a *invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf.res -c123d1f9f02fb4143abb5e271916e3a3080de8f6 *invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf -456d1493e52d32a5c30edf44a27debc1fa6b253a *invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf.res -efafb92b7567bc04c3f1432ea6c268c1c31affd5 *invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-.ivf -5d9474c0309b7ca09a182d888f73b37a8fe1362c *invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-.ivf.res -fe346136b9b8c1e6f6084cc106485706915795e4 *invalid-vp90-01-v3.webm -5d9474c0309b7ca09a182d888f73b37a8fe1362c *invalid-vp90-01-v3.webm.res -d78e2fceba5ac942246503ec8366f879c4775ca5 *invalid-vp90-02-v2.webm -8e2eff4af87d2b561cce2365713269e301457ef3 *invalid-vp90-02-v2.webm.res -df1a1453feb3c00d7d89746c7003b4163523bff3 *invalid-vp90-03-v3.webm -4935c62becc68c13642a03db1e6d3e2331c1c612 *invalid-vp90-03-v3.webm.res -d637297561dd904eb2c97a9015deeb31c4a1e8d2 *invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm -3a204bdbeaa3c6458b77bcebb8366d107267f55d *invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm.res -9aa21d8b2cb9d39abe8a7bb6032dc66955fb4342 *noisy_clip_640_360.y4m -0936b837708ae68c034719f8e07596021c2c214f *park_joy_90p_10_420_20f.y4m -5727a853c083c1099f837d27967bc1322d50ed4f *park_joy_90p_10_422_20f.y4m -e13489470ef8e8b2a871a5640d795a42a39be58d *park_joy_90p_10_444_20f.y4m -c934da6fb8cc54ee2a8c17c54cf6076dac37ead0 *park_joy_90p_10_440.yuv -79b0dc1784635a7f291e21c4e8d66a29c496ab99 *park_joy_90p_12_420_20f.y4m -9cf22b0f809f7464c8b9058f0cfa9d905921cbd1 *park_joy_90p_12_422_20f.y4m -22b2a4abaecc4a9ade6bb503d25fb82367947e85 *park_joy_90p_12_444_20f.y4m -82c1bfcca368c2f22bad7d693d690d5499ecdd11 *park_joy_90p_12_440.yuv -b9e1e90aece2be6e2c90d89e6ab2372d5f8c792d *park_joy_90p_8_420_a10-1.y4m -4e0eb61e76f0684188d9bc9f3ce61f6b6b77bb2c *park_joy_90p_8_420.y4m -7a193ff7dfeb96ba5f82b2afd7afa9e1fe83d947 *park_joy_90p_8_422.y4m -bdb7856e6bc93599bdda05c2e773a9f22b6c6d03 *park_joy_90p_8_444.y4m -81e1f3843748438b8f2e71db484eb22daf72e939 *park_joy_90p_8_440.yuv -b1f1c3ec79114b9a0651af24ce634afb44a9a419 *rush_hour_444.y4m -5184c46ddca8b1fadd16742e8500115bc8f749da *vp80-00-comprehensive-001.ivf -65bf1bbbced81b97bd030f376d1b7f61a224793f *vp80-00-comprehensive-002.ivf -906b4c1e99eb734504c504b3f1ad8052137ce672 *vp80-00-comprehensive-003.ivf -ec144b1af53af895db78355785650b96dd3f0ade *vp80-00-comprehensive-004.ivf -afc7091785c62f1c121c4554a2830c30704587d9 *vp80-00-comprehensive-005.ivf -42ea9d55c818145d06a9b633b8e85c6a6164fd3e *vp80-00-comprehensive-006.ivf -e5b3a73ab79fe024c14309d653d6bed92902ee3b *vp80-00-comprehensive-007.ivf -f3c50a58875930adfb84525c0ef59d7e4c08540c *vp80-00-comprehensive-008.ivf -4b2841fdb83db51ae322096ae468bbb9dc2c8362 *vp80-00-comprehensive-009.ivf -efbff736e3a91ab6a98c5bc2dce65d645944c7b1 *vp80-00-comprehensive-010.ivf -6b315102cae008d22a3d2c231be92cb704a222f8 *vp80-00-comprehensive-011.ivf -f3214a4fea14c2d5ec689936c1613f274c859ee8 *vp80-00-comprehensive-012.ivf -e4094e96d308c8a35b74c480a43d853c5294cd34 *vp80-00-comprehensive-013.ivf -5b0adfaf60a69e0aaf3ec021a39d0a68fc0e1b5a *vp80-00-comprehensive-014.ivf -e8467688ddf26b5000664f904faf0d70506aa653 *vp80-00-comprehensive-015.ivf -aab55582337dfd2a39ff54fb2576a91910d49337 *vp80-00-comprehensive-016.ivf -1ba24724f80203c9bae4f1d0f99d534721980016 *vp80-00-comprehensive-017.ivf -143a15512b46f436280ddb4d0e6411eb4af434f2 *vp80-00-comprehensive-018.ivf -c5baeaf5714fdfb3a8bc960a8e33ac438e83b16b *vp80-01-intra-1400.ivf -f383955229afe3408453e316d11553d923ca60d5 *vp80-01-intra-1411.ivf -84e1f4343f174c9f3c83f834bac3196fb325bf2c *vp80-01-intra-1416.ivf -fb6e712a47dd57a28a3727d2ae2c97a8b7c7ca51 *vp80-01-intra-1417.ivf -71ea772d3e9d315b8cbecf41207b8a237c34853b *vp80-02-inter-1402.ivf -d85dbc4271525dcd128c503f936fe69091d1f8d0 *vp80-02-inter-1412.ivf -d4e5d3ad56511867d025f93724d090f92ba6ec3d *vp80-02-inter-1418.ivf -91791cbcc37c60f35dbd8090bacb54e5ec6dd4fa *vp80-02-inter-1424.ivf -17fbfe2fea70f6e2f3fa6ca4efaae6c0b03b5f02 *vp80-03-segmentation-01.ivf -3c3600dbbcde08e20d54c66fe3b7eadd4f09bdbb *vp80-03-segmentation-02.ivf -c156778d5340967d4b369c490848076e92f1f875 *vp80-03-segmentation-03.ivf -d25dcff6c60e87a1af70945b8911b6b4998533b0 *vp80-03-segmentation-04.ivf -362baba2ce454c9db21218f35e81c27a5ed0b730 *vp80-03-segmentation-1401.ivf -d223ae7ee748ce07e74c4679bfd219e84aa9f4b0 *vp80-03-segmentation-1403.ivf -033adf7f3a13836a3f1cffcb87c1972900f2b5c6 *vp80-03-segmentation-1407.ivf -4d51dfbf9f3e2c590ec99d1d6f59dd731d04375f *vp80-03-segmentation-1408.ivf -f37a62b197c2600d75e0ccfbb31b60efdedac251 *vp80-03-segmentation-1409.ivf -eb25bd7bfba5b2f6935018a930f42d123b1e7fcd *vp80-03-segmentation-1410.ivf -b9d5c436663a30c27cfff84b53a002e501258843 *vp80-03-segmentation-1413.ivf -6da92b9d1a180cc3a8afe348ab12258f5a37be1a *vp80-03-segmentation-1414.ivf -a4f5842602886bd669f115f93d8a35c035cb0948 *vp80-03-segmentation-1415.ivf -f295dceb8ef278b77251b3f9df8aee22e161d547 *vp80-03-segmentation-1425.ivf -198dbf9f36f733200e432664cc8c5752d59779de *vp80-03-segmentation-1426.ivf -7704804e32f5de976803929934a7fafe101ac7b0 *vp80-03-segmentation-1427.ivf -831ccd862ea95ca025d2f3bd8b88678752f5416d *vp80-03-segmentation-1432.ivf -b3c11978529289f9109f2766fcaba3ebc40e11ef *vp80-03-segmentation-1435.ivf -a835a731f5520ebfc1002c40121264d0020559ac *vp80-03-segmentation-1436.ivf -1d1732942f773bb2a5775fcb9689b1579ce28eab *vp80-03-segmentation-1437.ivf -db04799adfe089dfdf74dbd43cc05ede7161f99e *vp80-03-segmentation-1441.ivf -7caf39b3f20cfd52b998210878062e52a5edf1e6 *vp80-03-segmentation-1442.ivf -3607f6bb4ee106c38fa1ea370dc4ff8b8cde2261 *vp80-04-partitions-1404.ivf -93cc323b6b6867f1b12dd48773424549c6960a6b *vp80-04-partitions-1405.ivf -047eedb14b865bdac8a3538e63801054e0295e9c *vp80-04-partitions-1406.ivf -0f1233bd2bc33f56ce5e495dbd455d122339f384 *vp80-05-sharpness-1428.ivf -51767fc136488a9535c2a4c38067c542ee2048df *vp80-05-sharpness-1429.ivf -9805aa107672de25d6fb8c35e20d06deca5efe18 *vp80-05-sharpness-1430.ivf -61db6b965f9c27aebe71b85bf2d5877e58e4bbdf *vp80-05-sharpness-1431.ivf -10420d266290d2923555f84af38eeb96edbd3ae8 *vp80-05-sharpness-1433.ivf -3ed24f9a80cddfdf75824ba95cdb4ff9286cb443 *vp80-05-sharpness-1434.ivf -c87599cbecd72d4cd4f7ace3313b7a6bc6eb8163 *vp80-05-sharpness-1438.ivf -aff51d865c2621b60510459244ea83e958e4baed *vp80-05-sharpness-1439.ivf -da386e72b19b5485a6af199c5eb60ef25e510dd1 *vp80-05-sharpness-1440.ivf -6759a095203d96ccd267ce09b1b050b8cc4c2f1f *vp80-05-sharpness-1443.ivf -b95d3cc1d0df991e63e150a801710a72f20d9ba0 *vp80-06-smallsize.ivf -db55ec7fd02c864ba996ff060b25b1e08611330b *vp80-00-comprehensive-001.ivf.md5 -29db0ad011cba1e45f856d5623cd38dac3e3bf19 *vp80-00-comprehensive-002.ivf.md5 -e84f258f69e173e7d68f8f8c037a0a3766902182 *vp80-00-comprehensive-003.ivf.md5 -eb7912eaf69559a16fd82bc3f5fb1524cf4a4466 *vp80-00-comprehensive-004.ivf.md5 -4206f71c94894bd5b5b376f6c09b3817dbc65206 *vp80-00-comprehensive-005.ivf.md5 -4f89b356f6f2fecb928f330a10f804f00f5325f5 *vp80-00-comprehensive-006.ivf.md5 -2813236a32964dd8007e17648bcf035a20fcda6c *vp80-00-comprehensive-007.ivf.md5 -10746c72098f872803c900e17c5680e451f5f498 *vp80-00-comprehensive-008.ivf.md5 -39a23d0692ce64421a7bb7cdf6ccec5928d37fff *vp80-00-comprehensive-009.ivf.md5 -f6e3de8931a0cc659bda8fbc14050346955e72d4 *vp80-00-comprehensive-010.ivf.md5 -101683ec195b6e944f7cd1e468fc8921439363e6 *vp80-00-comprehensive-011.ivf.md5 -1f592751ce46d8688998fa0fa4fbdcda0fd4058c *vp80-00-comprehensive-012.ivf.md5 -6066176f90ca790251e795fca1a5797d59999841 *vp80-00-comprehensive-013.ivf.md5 -2656da94ba93691f23edc4d60b3a09e2be46c217 *vp80-00-comprehensive-014.ivf.md5 -c6e0d5f5d61460c8ac8edfa4e701f10312c03133 *vp80-00-comprehensive-015.ivf.md5 -ee60fee501d8493e34e8d6a1fe315b51ed09b24a *vp80-00-comprehensive-016.ivf.md5 -9f1914ceffcad4546c0a29de3ef591d8bea304dc *vp80-00-comprehensive-017.ivf.md5 -e0305178fe288a9fd8082b39e2d03181edb19054 *vp80-00-comprehensive-018.ivf.md5 -612494da2fa799cc9d76dcdd835ae6c7cb2e5c05 *vp80-01-intra-1400.ivf.md5 -48ea06097ac8269c5e8c2131d3d0639f431fcf0e *vp80-01-intra-1411.ivf.md5 -6e2ab4e7677ad0ba868083ca6bc387ee922b400c *vp80-01-intra-1416.ivf.md5 -eca0a90348959ce3854142f8d8641b13050e8349 *vp80-01-intra-1417.ivf.md5 -920feea203145d5c2258a91c4e6991934a79a99e *vp80-02-inter-1402.ivf.md5 -f71d97909fe2b3dd65be7e1f56c72237f0cef200 *vp80-02-inter-1412.ivf.md5 -e911254569a30bbb2a237ff8b79f69ed9da0672d *vp80-02-inter-1418.ivf.md5 -58c789c50c9bb9cc90580bed291164a0939d28ba *vp80-02-inter-1424.ivf.md5 -ff3e2f441327b9c20a0b37c524e0f5a48a36de7b *vp80-03-segmentation-01.ivf.md5 -0791f417f076a542ae66fbc3426ab4d94cbd6c75 *vp80-03-segmentation-02.ivf.md5 -722e50f1a6a91c34302d68681faffc1c26d1cc57 *vp80-03-segmentation-03.ivf.md5 -c701f1885bcfb27fb8e70cc65606b289172ef889 *vp80-03-segmentation-04.ivf.md5 -f79bc9ec189a2b4807632a3d0c5bf04a178b5300 *vp80-03-segmentation-1401.ivf.md5 -b9aa4c74c0219b639811c44760d0b24cd8bb436a *vp80-03-segmentation-1403.ivf.md5 -70d5a2207ca1891bcaebd5cf6dd88ce8d57b4334 *vp80-03-segmentation-1407.ivf.md5 -265f962ee781531f9a93b9309461316fd32b2a1d *vp80-03-segmentation-1408.ivf.md5 -0c4ecbbd6dc042d30e626d951b65f460dd6cd563 *vp80-03-segmentation-1409.ivf.md5 -cf779af36a937f06570a0fca9db64ba133451dee *vp80-03-segmentation-1410.ivf.md5 -0e6c5036d51ab078842f133934926c598a9cff02 *vp80-03-segmentation-1413.ivf.md5 -eb3930aaf229116c80d507516c34759c3f6cdf69 *vp80-03-segmentation-1414.ivf.md5 -123d6c0f72ee87911c4ae7538e87b7d163b22d6c *vp80-03-segmentation-1415.ivf.md5 -e70551d1a38920e097a5d8782390b79ecaeb7505 *vp80-03-segmentation-1425.ivf.md5 -44e8f4117e46dbb302b2cfd81171cc1a1846e431 *vp80-03-segmentation-1426.ivf.md5 -52636e54aee5f95bbace37021bd67de5db767e9a *vp80-03-segmentation-1427.ivf.md5 -b1ad3eff20215c28e295b15ef3636ed926d59cba *vp80-03-segmentation-1432.ivf.md5 -24c22a552fa28a90e5978f67f57181cc2d7546d7 *vp80-03-segmentation-1435.ivf.md5 -96c49c390abfced18a7a8c9b9ea10af778e10edb *vp80-03-segmentation-1436.ivf.md5 -f95eb6214571434f1f73ab7833b9ccdf47588020 *vp80-03-segmentation-1437.ivf.md5 -1c0700ca27c9b0090a7747a4b0b4dc21d1843181 *vp80-03-segmentation-1441.ivf.md5 -81d4f23ca32667ee958bae579c8f5e97ba72eb97 *vp80-03-segmentation-1442.ivf.md5 -272efcef07a3a30fbca51bfd566063d8258ec0be *vp80-04-partitions-1404.ivf.md5 -66ed219ab812ac801b256d35cf495d193d4cf478 *vp80-04-partitions-1405.ivf.md5 -36083f37f56f502bd60ec5e07502ee9e6b8699b0 *vp80-04-partitions-1406.ivf.md5 -6ca909bf168a64c09415626294665dc1be3d1973 *vp80-05-sharpness-1428.ivf.md5 -1667d2ee2334e5fdea8a8a866f4ccf3cf76f033a *vp80-05-sharpness-1429.ivf.md5 -71bcbe5357d36a19df5b07fbe3e27bffa8893f0a *vp80-05-sharpness-1430.ivf.md5 -89a09b1dffce2d55770a89e58d9925c70ef79bf8 *vp80-05-sharpness-1431.ivf.md5 -08444a18b4e6ba3450c0796dd728d48c399a2dc9 *vp80-05-sharpness-1433.ivf.md5 -6d6223719a90c13e848aa2a8a6642098cdb5977a *vp80-05-sharpness-1434.ivf.md5 -41d70bb5fa45bc88da1604a0af466930b8dd77b5 *vp80-05-sharpness-1438.ivf.md5 -086c56378df81b6cee264d7540a7b8f2b405c7a4 *vp80-05-sharpness-1439.ivf.md5 -d32dc2c4165eb266ea4c23c14a45459b363def32 *vp80-05-sharpness-1440.ivf.md5 -8c69dc3d8e563f56ffab5ad1e400d9e689dd23df *vp80-05-sharpness-1443.ivf.md5 -d6f246df012c241b5fa6c1345019a3703d85c419 *vp80-06-smallsize.ivf.md5 -ce881e567fe1d0fbcb2d3e9e6281a1a8d74d82e0 *vp90-2-00-quantizer-00.webm -ac5eda33407d0521c7afca43a63fd305c0cd9d13 *vp90-2-00-quantizer-00.webm.md5 -2ca0463f2cfb93d25d7dded174db70b7cb87cb48 *vp90-2-00-quantizer-01.webm -10d98884fc6d9a5f47a2057922b8e25dd48d7786 *vp90-2-00-quantizer-01.webm.md5 -d80a2920a5e0819d69dcba8fe260c01f820f8982 *vp90-2-00-quantizer-02.webm -c964c8e5e04165fabbf1c6ee8ee5121d35921965 *vp90-2-00-quantizer-02.webm.md5 -fdef046777b5b75c962b715d809dbe2ea331afb9 *vp90-2-00-quantizer-03.webm -f270bee0b0c7aa2bf4c5afe098556b4f3f890faf *vp90-2-00-quantizer-03.webm.md5 -66d98609e809394a6ac730787e6724e3badc075a *vp90-2-00-quantizer-04.webm -427433bfe121c4aea1095ec3124fdc174d200e3a *vp90-2-00-quantizer-04.webm.md5 -e6e42626d8cadf0b5be16313f69212981b96fee5 *vp90-2-00-quantizer-05.webm -c98f6a9a1af4cfd71416792827304266aad4bd46 *vp90-2-00-quantizer-05.webm.md5 -413ef09b721f5dcec1a96e937a97e5873c2e6db6 *vp90-2-00-quantizer-06.webm -5080e940a23805c82e578e21b57fc2c511e76376 *vp90-2-00-quantizer-06.webm.md5 -4a50a5f4ac717c30dfaae8bb46702e3542e867de *vp90-2-00-quantizer-07.webm -76c429a02b56762e10ee4db88729d8834b3a70f4 *vp90-2-00-quantizer-07.webm.md5 -d2f4e464780bf8b7e647efa18ac777a930e62bc0 *vp90-2-00-quantizer-08.webm -ab94aabf9316111b52d7c531962ed4123313b6ba *vp90-2-00-quantizer-08.webm.md5 -174bc58433936dd79550398d744f1072ce7f5693 *vp90-2-00-quantizer-09.webm -e1f7690cd83ccc56d045e17cce552544a5f03810 *vp90-2-00-quantizer-09.webm.md5 -52bc1dfd3a97b24d922eb8a31d07527891561f2a *vp90-2-00-quantizer-10.webm -9b37bed893b5f6a4e12f2aa40f02dd40f944d0f8 *vp90-2-00-quantizer-10.webm.md5 -10031eecafde1e1d8e6323fe2b2a1d7e77a66869 *vp90-2-00-quantizer-11.webm -fe4620a4bb0e4f5cb9bbfedc4039a22b81b0f5c0 *vp90-2-00-quantizer-11.webm.md5 -78e9f7bb77e8e348155bbdfa12790789d1d50c34 *vp90-2-00-quantizer-12.webm -0961d060cc8dd469c6dac8d7d75f927c0bb971b8 *vp90-2-00-quantizer-12.webm.md5 -133b77a3bbcef652552d74ffc46afbfe3b8a1cba *vp90-2-00-quantizer-13.webm -df29e5e0f95772af482f540d776f6b9dea4bfa29 *vp90-2-00-quantizer-13.webm.md5 -27323afdaf8987e025c27129c74c86502315a206 *vp90-2-00-quantizer-14.webm -ce96a2cc312942f0427a463f15a392870dd69764 *vp90-2-00-quantizer-14.webm.md5 -ab58d0b41037829f6bc993910999f4af0212aafd *vp90-2-00-quantizer-15.webm -40f700db606501aa7cb49049624cbdde6409b122 *vp90-2-00-quantizer-15.webm.md5 -cd948e66448aafb65998815ce37241f95d7c9ee7 *vp90-2-00-quantizer-16.webm -039b742d149c945ed79c7b9a6384352852a1c116 *vp90-2-00-quantizer-16.webm.md5 -62f56e663e13c576764e491cf08f19bd46a71999 *vp90-2-00-quantizer-17.webm -90c5a39bf76e6b3e0a1c0d3e9b68a9fd78be963e *vp90-2-00-quantizer-17.webm.md5 -f26ecad7263cd66a614e53ba5d7c00df181affeb *vp90-2-00-quantizer-18.webm -cda0a1c0fca2ec2976ae55124a8a67305508bae6 *vp90-2-00-quantizer-18.webm.md5 -94bfc4c04fcfe139a63b98c569e8c14ba98c401f *vp90-2-00-quantizer-19.webm -5b8ec169ccf67d8a0a8e46a62eb173f5a1dbaf4f *vp90-2-00-quantizer-19.webm.md5 -0ee88e9318985e1e245de78c2c4a665885ab76a7 *vp90-2-00-quantizer-20.webm -4b26f7edb4fcd3a1b4cce9ba3cb8650e3ee6e063 *vp90-2-00-quantizer-20.webm.md5 -6a995cb2b1db33da8087321df1e646f95c3e32d1 *vp90-2-00-quantizer-21.webm -e216b4a1eceac03efcc433759be54ab8ea87b24b *vp90-2-00-quantizer-21.webm.md5 -aa7722fc427e7180115f3c9cd96bb6b2768e7296 *vp90-2-00-quantizer-22.webm -1aa813bd45ae831bf5e79ace4d73dfd25989a07d *vp90-2-00-quantizer-22.webm.md5 -7677e5b929ed6d142041f19b8a9cd5822ee1504a *vp90-2-00-quantizer-23.webm -0de0af34abd843d5b37e58baf3ed96a6104b64c3 *vp90-2-00-quantizer-23.webm.md5 -b2995cbe1128b2d4926f1b28d01c501ecb6be8c8 *vp90-2-00-quantizer-24.webm -db6033af2ba2f2bca62468fb4b8808e474f93923 *vp90-2-00-quantizer-24.webm.md5 -8135ba35587fd92cd4667be7896323d9b634401c *vp90-2-00-quantizer-25.webm -3499e00c2cc15876f61f07e3d3cfca54ebcd98fd *vp90-2-00-quantizer-25.webm.md5 -af0fa2907746db82d345f6d831fcc1b2862a29fb *vp90-2-00-quantizer-26.webm -cd6fe3d14dab48886ebf65be00e6ed9616ebe5a7 *vp90-2-00-quantizer-26.webm.md5 -bd0002e91323776beb5ff11e06edcf19fc08e9b9 *vp90-2-00-quantizer-27.webm -fe72154ef196067d6c272521012dd79706496cac *vp90-2-00-quantizer-27.webm.md5 -fc15eb606f81455ff03df16bf3432296b002c43c *vp90-2-00-quantizer-28.webm -40b2e24b542206a6bfd746ef199e49ccea07678a *vp90-2-00-quantizer-28.webm.md5 -3090bbf913cad0b2eddca7228f5ed51a58378b8d *vp90-2-00-quantizer-29.webm -eb59745e0912d8ed6c928268bcf265237c9ba93f *vp90-2-00-quantizer-29.webm.md5 -c615abdca9c25e1cb110d908edbedfb3b7c92b91 *vp90-2-00-quantizer-30.webm -ad0f4fe6733e4e7cdfe8ef8722bb341dcc7538c0 *vp90-2-00-quantizer-30.webm.md5 -037d9f242086cfb085518f6416259defa82d5fc2 *vp90-2-00-quantizer-31.webm -4654b40792572f0a790874c6347ef9196d86c1a7 *vp90-2-00-quantizer-31.webm.md5 -505899f3f3515044c5c8b3213d9b9d16f614619d *vp90-2-00-quantizer-32.webm -659a2e6dd02df323f62600626859006640b445df *vp90-2-00-quantizer-32.webm.md5 -8b32ec9c3b7e5ca8ddc6b8aea1c1cb7ca996bccc *vp90-2-00-quantizer-33.webm -5b175ef1120ddeba4feae1247bf381bbc4e816ce *vp90-2-00-quantizer-33.webm.md5 -4d283755d17e287b1d099a80604398f60d7fb6ea *vp90-2-00-quantizer-34.webm -22a739de95acfeb27524e3700b8f678a9ad744d8 *vp90-2-00-quantizer-34.webm.md5 -4296f56a892a412d3d4f64824718dd566c4e6459 *vp90-2-00-quantizer-35.webm -c532c9c8dc7b3506fc6a51e5c20c17ef0ac039e7 *vp90-2-00-quantizer-35.webm.md5 -6f54e11da461e4410dd9075b015e2d9bc1d07dfb *vp90-2-00-quantizer-36.webm -0b3573f5addea4e3eb11a0b85f068299d5bdad78 *vp90-2-00-quantizer-36.webm.md5 -210581682a26c2c4375efc785c36e07539888bc2 *vp90-2-00-quantizer-37.webm -2b4fb6f8ba975237858e61cc8f560bcfc87cb38e *vp90-2-00-quantizer-37.webm.md5 -a15ef31283dfc4860f837fe200eb32a445f59629 *vp90-2-00-quantizer-38.webm -fb76771f3a795054b9936f70da7505c3ac585284 *vp90-2-00-quantizer-38.webm.md5 -1df8433a441412831daae6726df89fa70d21b14d *vp90-2-00-quantizer-39.webm -39e162c09a20e7e684868097766347014371fee6 *vp90-2-00-quantizer-39.webm.md5 -5330e4788ab9129dbb25a7a7d5411104521248b6 *vp90-2-00-quantizer-40.webm -872cc0f2cc9dbf000f89eadb4d8f9940e48e00b1 *vp90-2-00-quantizer-40.webm.md5 -d88d03b982889e399a78d7a06eeb1cf30e6c2da2 *vp90-2-00-quantizer-41.webm -5b4f7217e57fa2a221011d0b32f8d0409496b7b6 *vp90-2-00-quantizer-41.webm.md5 -9e16406e3e26955a6e17d455ef1ef64bbfa26e53 *vp90-2-00-quantizer-42.webm -0219d090cf37daabe19256ba8e932ba4874b92e4 *vp90-2-00-quantizer-42.webm.md5 -a9b15843486fb05f8cd15437ef279782a42b75db *vp90-2-00-quantizer-43.webm -3c9b0b4c607f9579a31726bfcf56729334ddc686 *vp90-2-00-quantizer-43.webm.md5 -1dbc931ac446c91eabe7213efff55b596cccf07c *vp90-2-00-quantizer-44.webm -73bc8f675103abaef3d9f73a2742b3bffd726d23 *vp90-2-00-quantizer-44.webm.md5 -7c6c1be15beb9d6201204b018966c8c4f9777efc *vp90-2-00-quantizer-45.webm -c907b29da821f790c6748de61f592689312e4e36 *vp90-2-00-quantizer-45.webm.md5 -07b434da1a467580f73b32177ee11b3e00f65a0d *vp90-2-00-quantizer-46.webm -7b2b7ce60c50bc970bc0ada46d7a7ce440148da3 *vp90-2-00-quantizer-46.webm.md5 -233d0465fb1a6fa36e9f89bd2193ac79bd4d2809 *vp90-2-00-quantizer-47.webm -527e0a9fb932efe915027ffe077f9e8d3a4fb139 *vp90-2-00-quantizer-47.webm.md5 -719613df7307e205c3fdb6acfb373849c5ab23c7 *vp90-2-00-quantizer-48.webm -65ab6c9d1b682c183b201c7ff42b90343ce3e304 *vp90-2-00-quantizer-48.webm.md5 -3bf04a598325ed0eabae1598ec7f718f715ec672 *vp90-2-00-quantizer-49.webm -ac68c4387ce11fcc998d8ba455ab9b2bb361d240 *vp90-2-00-quantizer-49.webm.md5 -d59238fb3a654931c9b65a11e7321b40d1f702e9 *vp90-2-00-quantizer-50.webm -d0576bfede46fd55659f028f2fd28554ceb3e6cc *vp90-2-00-quantizer-50.webm.md5 -3f579785101d4209360dd96f8c2ffe9beddf3bee *vp90-2-00-quantizer-51.webm -89fcfe04f4457a7f02ab4a2f94aacbb88aee5789 *vp90-2-00-quantizer-51.webm.md5 -28be5836e2fedefe4babf12fc9b79e460ab0a0f4 *vp90-2-00-quantizer-52.webm -f3dd52b70c18345fee740220f35da9c4def2017a *vp90-2-00-quantizer-52.webm.md5 -488ad4058c17170665b6acd1021fade9a02771e4 *vp90-2-00-quantizer-53.webm -1cdcb1d4f3a37cf83ad235eb27ec62ed2a01afc7 *vp90-2-00-quantizer-53.webm.md5 -682978289cb28cc8c9d39bc797300e45d6039de7 *vp90-2-00-quantizer-54.webm -36c35353f2c03cb099bd710d9994de7d9ed88834 *vp90-2-00-quantizer-54.webm.md5 -c398ce49af762a48f10cc4da9fae0769aae5f226 *vp90-2-00-quantizer-55.webm -2cf3570542d984f167ab087f59493c7fb47e0ed2 *vp90-2-00-quantizer-55.webm.md5 -3071f18b2fce261aa82d61f81a7ae4ca9a75d0e3 *vp90-2-00-quantizer-56.webm -d3f93f8272b6de31cffb011a26f11abb514efb12 *vp90-2-00-quantizer-56.webm.md5 -f4e8e14b1f278801a7eb6f11734780a01b1668e9 *vp90-2-00-quantizer-57.webm -6478fdf1d7faf6db5f19dffc5e1363af358699ee *vp90-2-00-quantizer-57.webm.md5 -307dc264f57cc618fff211fa44d7f52767ed9660 *vp90-2-00-quantizer-58.webm -cf231d4a52d492fa692ea4194ec5eb7511fec54e *vp90-2-00-quantizer-58.webm.md5 -1fd7cd596170afce2de0b1441b7674bda5723440 *vp90-2-00-quantizer-59.webm -4681f7ef96f63e085c41bb1a964b0df7e67e0b38 *vp90-2-00-quantizer-59.webm.md5 -34cdcc81c0ba7085aefbb22d7b4aa9bca3dd7c62 *vp90-2-00-quantizer-60.webm -58691ef53b6b623810e2c57ded374c77535df935 *vp90-2-00-quantizer-60.webm.md5 -e6e812406aab81021bb16e772c1db03f75906cb6 *vp90-2-00-quantizer-61.webm -76436eace62f08ff92b61a0845e66667a027db1b *vp90-2-00-quantizer-61.webm.md5 -84d811bceed70c950a6a08e572a6e274866e72b1 *vp90-2-00-quantizer-62.webm -2d937cc011eeddd95222b960982da5cd18db580f *vp90-2-00-quantizer-62.webm.md5 -0912b295ba0ea09359315315ffd67d22d046f883 *vp90-2-00-quantizer-63.webm -5a829031055d70565f57dbcd47a6ac33619952b3 *vp90-2-00-quantizer-63.webm.md5 -0cf9e5ebe0112bdb47b5887ee5d58eb9d4727c00 *vp90-2-01-sharpness-1.webm -5a0476be4448bae8f8ca17ea236c98793a755948 *vp90-2-01-sharpness-1.webm.md5 -51e02d7911810cdf5be8b68ac40aedab479a3179 *vp90-2-01-sharpness-2.webm -a0ca5bc87a5ed7c7051f59078daa0d03be1b45b6 *vp90-2-01-sharpness-2.webm.md5 -0603f8ad239c07a531d948187f4dafcaf51eda8d *vp90-2-01-sharpness-3.webm -3af8000a69c72fe77881e3176f026c2affb78cc7 *vp90-2-01-sharpness-3.webm.md5 -4ca4839f48146252fb261ed88838d80211804841 *vp90-2-01-sharpness-4.webm -08832a1494f84fa9edd40e080bcf2c0e80100c76 *vp90-2-01-sharpness-4.webm.md5 -95099dc8f9cbaf9b9a7dd65311923e441ff70731 *vp90-2-01-sharpness-5.webm -93ceee30c140f0b406726c0d896b9db6031c4c7f *vp90-2-01-sharpness-5.webm.md5 -ceb4116fb7b078d266d153233b6d62a255a34e4c *vp90-2-01-sharpness-6.webm -da83efe59e537ce538e8b03a6eac63cf25849c9a *vp90-2-01-sharpness-6.webm.md5 -b5f7cd19aece3880f9d616a778e5cc24c6b9b505 *vp90-2-01-sharpness-7.webm -2957408d20deac8633941a2169f801bae6f086e1 *vp90-2-01-sharpness-7.webm.md5 -ffc096c2ce1050450ad462b5fabd2a5220846319 *vp90-2-02-size-08x08.webm -e36d2ed6fa2746347710b750586aafa6a01ff3ae *vp90-2-02-size-08x08.webm.md5 -895b986f9fd55cd879472b31c6a06b82094418c8 *vp90-2-02-size-08x10.webm -079157a19137ccaebba606f2871f45a397347150 *vp90-2-02-size-08x10.webm.md5 -1c5992203e62a2b83040ccbecd748b604e19f4c0 *vp90-2-02-size-08x16.webm -9aa45ffdf2078f883bbed01450031b691819c144 *vp90-2-02-size-08x16.webm.md5 -d0a8953da1f85f484487408fee5da9e2a8391901 *vp90-2-02-size-08x18.webm -59a5cc17d354c6a23e5e959d666b1456a5d49c56 *vp90-2-02-size-08x18.webm.md5 -1b13461a9fc65cb041bacfe4ea6f02d363397d61 *vp90-2-02-size-08x32.webm -2bdddd6878f05d37d84cde056a3f5e7f926ba3d6 *vp90-2-02-size-08x32.webm.md5 -2861f0a0daadb62295b0504a1fbe5b50c79a8f59 *vp90-2-02-size-08x34.webm -6b5812cfb8a82d378ea2913bf009e93668020147 *vp90-2-02-size-08x34.webm.md5 -02f948216d4246579dc53c47fe55d8fb264ba251 *vp90-2-02-size-08x64.webm -84b55fdee6d9aa820c7a8c62822446184b191767 *vp90-2-02-size-08x64.webm.md5 -4b011242cbf42516efd2b197baebb61dd34562c9 *vp90-2-02-size-08x66.webm -6b1fa0a885947b3cc0fe58f75f838e662bd9bb8b *vp90-2-02-size-08x66.webm.md5 -4057796be9dd12df48ab607f502ae6aa70eeeab6 *vp90-2-02-size-10x08.webm -71c752c51aec9f48de286b93f4c20e9c11cad7d0 *vp90-2-02-size-10x08.webm.md5 -6583c853fa43fc53d51743eac5f3a43a359d45d0 *vp90-2-02-size-10x10.webm -1da524d24af1944b671d4d3f2b398d6e336584c3 *vp90-2-02-size-10x10.webm.md5 -ba442fc03ccd3a705c64c83b36f5ada67d198874 *vp90-2-02-size-10x16.webm -7cfd960f232c34c641a4a2a9411b6fd0efb2fc50 *vp90-2-02-size-10x16.webm.md5 -cc92ed40eef14f52e4d080cb2c57939dd8326374 *vp90-2-02-size-10x18.webm -db5626275cc55ce970b91c995e74f6838d943aca *vp90-2-02-size-10x18.webm.md5 -3a93d501d22325e9fd4c9d8b82e2a432de33c351 *vp90-2-02-size-10x32.webm -5cae51b0c71cfc131651f345f87583eb2903afaf *vp90-2-02-size-10x32.webm.md5 -50d2f2b15a9a5178153db44a9e03aaf32b227f67 *vp90-2-02-size-10x34.webm -bb0efe058122641e7f73e94497dda2b9e6c21efd *vp90-2-02-size-10x34.webm.md5 -01624ec173e533e0b33fd9bdb91eb7360c7c9175 *vp90-2-02-size-10x64.webm -b9c0e3b054463546356acf5157f9be92fd34732f *vp90-2-02-size-10x64.webm.md5 -2942879baf1c09e96b14d0fc84806abfe129c706 *vp90-2-02-size-10x66.webm -bab5f539c2f91952e187456b4beafbb4c01e25ee *vp90-2-02-size-10x66.webm.md5 -88d2b63ca5e9ee163d8f20e8886f3df3ff301a66 *vp90-2-02-size-16x08.webm -7f48a0fcf8c25963f3057d7f6669c5f2415834b8 *vp90-2-02-size-16x08.webm.md5 -59261eb34c15ea9b5ddd2d416215c1a8b9e6dc1f *vp90-2-02-size-16x10.webm -73a7c209a46dd051c9f7339b6e02ccd5b3b9fc81 *vp90-2-02-size-16x10.webm.md5 -066834fef9cf5b9a72932cf4dea5f253e14a976d *vp90-2-02-size-16x16.webm -faec542f52f37601cb9c480d887ae9355be99372 *vp90-2-02-size-16x16.webm.md5 -195307b4eb3192271ee4a935b0e48deef0c54cc2 *vp90-2-02-size-16x18.webm -5a92e19e624c0376321d4d0e22c0c91995bc23e1 *vp90-2-02-size-16x18.webm.md5 -14f3f884216d7ae16ec521f024a2f2d31bbf9c1a *vp90-2-02-size-16x32.webm -ea622d1c817dd174556f7ee7ccfe4942b34d4845 *vp90-2-02-size-16x32.webm.md5 -2e0501100578a5da9dd47e4beea160f945bdd1ba *vp90-2-02-size-16x34.webm -1b8645ef64239334921c5f56b24ce815e6070b05 *vp90-2-02-size-16x34.webm.md5 -89a6797fbebebe93215f367229a9152277f5dcfe *vp90-2-02-size-16x64.webm -a03d8c1179ca626a8856fb416d635dbf377979cd *vp90-2-02-size-16x64.webm.md5 -0f3a182e0750fcbae0b9eae80c7a53aabafdd18d *vp90-2-02-size-16x66.webm -8cb6736dc2d897c1283919a32068af377d66c59c *vp90-2-02-size-16x66.webm.md5 -68fe70dc7914cc1d8d6dcd97388b79196ba3e7f1 *vp90-2-02-size-18x08.webm -874c7fb505be9db3160c57cb405c4dbd5b990dc2 *vp90-2-02-size-18x08.webm.md5 -0546352dd78496d4dd86c3727ac2ff36c9e72032 *vp90-2-02-size-18x10.webm -1d80eb36557ea5f25a386495a36f93da0f25316b *vp90-2-02-size-18x10.webm.md5 -60fe99e5f5cc99706efa3e0b894e45cbcf0d6330 *vp90-2-02-size-18x16.webm -1ab6cdd89a53662995d103546e6611c84f9292ab *vp90-2-02-size-18x16.webm.md5 -f9a8f5fb749d69fd555db6ca093b7f77800c7b4f *vp90-2-02-size-18x18.webm -ace8a66328f7802b15f9989c2720c029c6abd279 *vp90-2-02-size-18x18.webm.md5 -a197123a527ec25913a9bf52dc8c347749e00045 *vp90-2-02-size-18x32.webm -34fbd7036752232d1663e70d7f7cdc93f7129202 *vp90-2-02-size-18x32.webm.md5 -f219655a639a774a2c9c0a9f45c28dc0b5e75e24 *vp90-2-02-size-18x34.webm -2c4d622a9ea548791c1a07903d3702e9774388bb *vp90-2-02-size-18x34.webm.md5 -5308578da48c677d477a5404e19391d1303033c9 *vp90-2-02-size-18x64.webm -e7fd4462527bac38559518ba80e41847db880f15 *vp90-2-02-size-18x64.webm.md5 -e109a7e013bd179f97e378542e1e81689ed06802 *vp90-2-02-size-18x66.webm -45c04e422fb383c1f3be04beefaa4490e83bdb1a *vp90-2-02-size-18x66.webm.md5 -38844cae5d99caf445f7de33c3ae78494ce36c01 *vp90-2-02-size-32x08.webm -ad018be39e493ca2405225034b1a5b7a42af6f3a *vp90-2-02-size-32x08.webm.md5 -7b57eaad55906f9de9903c8657a3fcb2aaf792ea *vp90-2-02-size-32x10.webm -2294425d4e55d275af5e25a0beac9738a1b4ee73 *vp90-2-02-size-32x10.webm.md5 -f47ca2ced0d47f761bb0a5fdcd911d3f450fdcc1 *vp90-2-02-size-32x16.webm -ae10981d93913f0ab1f28c1146255e01769aa8c0 *vp90-2-02-size-32x16.webm.md5 -08b23ad838b6cf1fbfe3ad7e7775d95573e815fc *vp90-2-02-size-32x18.webm -1ba76f4c4a4ac7aabfa3ce195c1b473535eb7cc8 *vp90-2-02-size-32x18.webm.md5 -d5b88ae6c8c25c53dee74d9f1e6ca64244349a57 *vp90-2-02-size-32x32.webm -e39c067a8ee2da52a51641eb1cb7f8eba935eb6b *vp90-2-02-size-32x32.webm.md5 -529429920dc36bd899059fa75a767f02c8c60874 *vp90-2-02-size-32x34.webm -56888e7834f52b106e8911e3a7fc0f473b609995 *vp90-2-02-size-32x34.webm.md5 -38e848e160391c2b1a55040aadde613b9f4bf15e *vp90-2-02-size-32x64.webm -8950485fb3f68b0e8be234db860e4ec5f5490fd0 *vp90-2-02-size-32x64.webm.md5 -5e8670f0b8ec9cefa8795b8959ffbe1a8e1aea94 *vp90-2-02-size-32x66.webm -225df9d7d72ec711b0b60f4aeb65311c97db054a *vp90-2-02-size-32x66.webm.md5 -695f929e2ce6fb11a1f180322d46c5cb1c97fa61 *vp90-2-02-size-34x08.webm -5bb4262030018dd01883965c6aa6070185924ef6 *vp90-2-02-size-34x08.webm.md5 -5adf74ec906d2ad3f7526e06bd29f5ad7d966a90 *vp90-2-02-size-34x10.webm -71c100b437d3e8701632ae8d65c3555339b1c68f *vp90-2-02-size-34x10.webm.md5 -d0918923c987fba2d00193d83797b21289fe54aa *vp90-2-02-size-34x16.webm -5d5a52f3535b4d2698dd3d87f4a13fdc9b57163d *vp90-2-02-size-34x16.webm.md5 -553ab0042cf87f5e668ec31b2e4b2a4b6ec196fd *vp90-2-02-size-34x18.webm -a164c7f3c424987df2340496e6a8cf76e973f0f1 *vp90-2-02-size-34x18.webm.md5 -baf3e233634f150de81c18ba5d8848068e1c3c54 *vp90-2-02-size-34x32.webm -22a79d3bd1c9b85dfe8c70bb2e19f08a92a8be03 *vp90-2-02-size-34x32.webm.md5 -6d50a533774a7167350e4a7ef43c94a5622179a2 *vp90-2-02-size-34x34.webm -0c099638e79c273546523e06704553e42eb00b00 *vp90-2-02-size-34x34.webm.md5 -698cdd0a5e895cc202c488675e682a8c537ede4f *vp90-2-02-size-34x64.webm -9317b63987cddab8389510a27b86f9f3d46e3fa5 *vp90-2-02-size-34x64.webm.md5 -4b5335ca06f082b6b69f584eb8e7886bdcafefd3 *vp90-2-02-size-34x66.webm -e18d68b35428f46a84a947c646804a51ef1d7cec *vp90-2-02-size-34x66.webm.md5 -a54ae7b494906ec928a876e8290e5574f2f9f6a2 *vp90-2-02-size-64x08.webm -87f9f7087b6489d45e9e4b38ede2c5aef4a4928f *vp90-2-02-size-64x08.webm.md5 -24522c70804a3c23d937df2d829ae63965b23f38 *vp90-2-02-size-64x10.webm -447ce03938ab53bffcb4a841ee0bfaa90462dcb9 *vp90-2-02-size-64x10.webm.md5 -2a5035d035d214ae614af8051930690ef623989b *vp90-2-02-size-64x16.webm -84e355761dd2e0361b904c84c52a0dd0384d89cf *vp90-2-02-size-64x16.webm.md5 -3a293ef4e270a19438e59b817fbe5f43eed4d36b *vp90-2-02-size-64x18.webm -666824e5ba746779eb46079e0631853dcc86d48b *vp90-2-02-size-64x18.webm.md5 -ed32fae837095c9e8fc95d223ec68101812932c2 *vp90-2-02-size-64x32.webm -97086eadedce1d0d9c072b585ba7b49aec69b1e7 *vp90-2-02-size-64x32.webm.md5 -696c7a7250bdfff594f4dfd88af34239092ecd00 *vp90-2-02-size-64x34.webm -253a1d38d452e7826b086846c6f872f829c276bb *vp90-2-02-size-64x34.webm.md5 -fc508e0e3c2e6872c60919a60b812c5232e9c2b0 *vp90-2-02-size-64x64.webm -2cd6ebeca0f82e9f505616825c07950371b905ab *vp90-2-02-size-64x64.webm.md5 -0f8a4fc1d6521187660425c283f08dff8c66e476 *vp90-2-02-size-64x66.webm -5806be11a1d346be235f88d3683e69f73746166c *vp90-2-02-size-64x66.webm.md5 -273b0c36e3658685cde250408a478116d7ae92f1 *vp90-2-02-size-66x08.webm -23c3cd0dca20a2f71f036e77ea92025ff4e7a298 *vp90-2-02-size-66x08.webm.md5 -4844c59c3306d1e671bb0568f00e344bf797e66e *vp90-2-02-size-66x10.webm -e041eaf6841d775f8fde8bbb4949d2733fdaab7f *vp90-2-02-size-66x10.webm.md5 -bdf3f1582b234fcd2805ffec59f9d716a2345302 *vp90-2-02-size-66x16.webm -2ec85ee18119e6798968571ea6e1b93ca386e3af *vp90-2-02-size-66x16.webm.md5 -0acce9af12b13b025d5274013da7ef6f568f075f *vp90-2-02-size-66x18.webm -77c4d53e2a5c96b70af9d575fe6811e0f5ee627b *vp90-2-02-size-66x18.webm.md5 -682b36a25774bbdedcd603f504d18eb63f0167d4 *vp90-2-02-size-66x32.webm -53728fae2a428f16d376a29f341a64ddca97996a *vp90-2-02-size-66x32.webm.md5 -e71b70e901e29eaa6672a6aa4f37f6f5faa02bd6 *vp90-2-02-size-66x34.webm -f69a6a555e3f614b0a35f9bfc313d8ebb35bc725 *vp90-2-02-size-66x34.webm.md5 -4151b8c29452d5c2266397a7b9bf688899a2937b *vp90-2-02-size-66x64.webm -69486e7fd9e380b6c97a03d3e167affc79f73840 *vp90-2-02-size-66x64.webm.md5 -68784a1ecac776fe2a3f230345af32f06f123536 *vp90-2-02-size-66x66.webm -7f008c7f48d55e652fbd6bac405b51e0015c94f2 *vp90-2-02-size-66x66.webm.md5 -7e1bc449231ac1c5c2a11c9a6333b3e828763798 *vp90-2-03-size-196x196.webm -6788a561466dace32d500194bf042e19cccc35e1 *vp90-2-03-size-196x196.webm.md5 -a170c9a88ec1dd854c7a471ff55fb2a97ac31870 *vp90-2-03-size-196x198.webm -6bf9d6a8e2bdc5bf4f8a78071a3fed5ca02ad6f2 *vp90-2-03-size-196x198.webm.md5 -68f861d21c4c8b03d572c3d3fcd9f4fbf1f4503f *vp90-2-03-size-196x200.webm -bbfc260b2bfd872cc6054272bb6b7f959a9e1c6e *vp90-2-03-size-196x200.webm.md5 -fc34889feeca2b7e5b27b4f1ce22d2e2b8e3e4b1 *vp90-2-03-size-196x202.webm -158ee72af578f39aad0c3b8f4cbed2fc78b57e0f *vp90-2-03-size-196x202.webm.md5 -dd28fb7247af534bdf5e6795a3ac429610489a0b *vp90-2-03-size-196x208.webm -7546be847efce2d1c0a23f807bfb03f91b764e1e *vp90-2-03-size-196x208.webm.md5 -41d5cf5ed65b722a1b6dc035e67f978ea8ffecf8 *vp90-2-03-size-196x210.webm -9444fdf632d6a1b6143f4cb10fed8f63c1d67ec1 *vp90-2-03-size-196x210.webm.md5 -5007bc618143437c009d6dde5fc2e86f72d37dc2 *vp90-2-03-size-196x224.webm -858361d8f79b44df5545feabbc9754ec9ede632f *vp90-2-03-size-196x224.webm.md5 -0bcbe357fbc776c3fa68e7117179574ed7564a44 *vp90-2-03-size-196x226.webm -72006a5f42031a43d70a2cd9fc1958962a86628f *vp90-2-03-size-196x226.webm.md5 -000239f048cceaac055558e97ef07078ebf65502 *vp90-2-03-size-198x196.webm -2d6841901b72000c5340f30be602853438c1b787 *vp90-2-03-size-198x196.webm.md5 -ae75b766306a6404c3b3b35a6b6d53633c14fbdb *vp90-2-03-size-198x198.webm -3f2544b4f3b4b643a98f2c3b15ea5826fc702fa1 *vp90-2-03-size-198x198.webm.md5 -95ffd573fa84ccef1cd59e1583e6054f56a5c83d *vp90-2-03-size-198x200.webm -5d537e3c9b9c54418c79677543454c4cda3de1af *vp90-2-03-size-198x200.webm.md5 -ecc845bf574375f469bc91bf5c75c79dc00073d6 *vp90-2-03-size-198x202.webm -1b59f5e111265615a7a459eeda8cc9045178d228 *vp90-2-03-size-198x202.webm.md5 -432fb27144fe421b9f51cf44d2750a26133ed585 *vp90-2-03-size-198x208.webm -a58a67f4fb357c73ca078aeecbc0f782975630b1 *vp90-2-03-size-198x208.webm.md5 -ff5058e7e6a47435046612afc8536f2040989e6f *vp90-2-03-size-198x210.webm -18d3be7935e52217e2e9400b6f2c681a9e45dc89 *vp90-2-03-size-198x210.webm.md5 -a0d55263c1ed2c03817454dd4ec4090d36dbc864 *vp90-2-03-size-198x224.webm -efa366a299817e2da51c00623b165aab9fbb8d91 *vp90-2-03-size-198x224.webm.md5 -ccd142fa2920fc85bb753f049160c1c353ad1574 *vp90-2-03-size-198x226.webm -534524a0b2dbff852e0b92ef09939db072f83243 *vp90-2-03-size-198x226.webm.md5 -0d483b94ed40abc8ab6e49f960432ee54ad9c7f1 *vp90-2-03-size-200x196.webm -41795f548181717906e7a504ba551f06c32102ae *vp90-2-03-size-200x196.webm.md5 -f6c2dc54e0989d50f01333fe40c91661fcbf849a *vp90-2-03-size-200x198.webm -43df5d8c46a40089441392e6d096c588c1079a68 *vp90-2-03-size-200x198.webm.md5 -2f6e9df82e44fc145f0d9212dcccbed3de605e23 *vp90-2-03-size-200x200.webm -757b2ef96b82093255725bab9690bbafe27f3caf *vp90-2-03-size-200x200.webm.md5 -40c5ea60415642a4a2e75c0d127b06309baadfab *vp90-2-03-size-200x202.webm -3022c4a1c625b5dc04fdb1052d17d45b4171cfba *vp90-2-03-size-200x202.webm.md5 -6942ed5b27476bb8506d10e600d6ff60887780ca *vp90-2-03-size-200x208.webm -c4ab8c66f3cf2dc8e8dd7abae9ac21f4d32cd6be *vp90-2-03-size-200x208.webm.md5 -71dbc99b83c49d1da45589b91eabb98e2f4a7b1e *vp90-2-03-size-200x210.webm -3f0b40da7eef7974b9bc326562f251feb67d9c7c *vp90-2-03-size-200x210.webm.md5 -6b6b8489081cfefb377cc5f18eb754ec2383f655 *vp90-2-03-size-200x224.webm -a259df2ac0e294492e3f9d4315baa34cab044f04 *vp90-2-03-size-200x224.webm.md5 -c9adc1c9bb07559349a0b054df4af56f7a6edbb9 *vp90-2-03-size-200x226.webm -714cec61e3575581e4f1a0e3921f4dfdbbd316c5 *vp90-2-03-size-200x226.webm.md5 -f9bdc936bdf53f8be9ce78fecd41a21d31ff3943 *vp90-2-03-size-202x196.webm -5b8e2e50fcea2c43b12fc067b8a9cc117af77bda *vp90-2-03-size-202x196.webm.md5 -c7b66ea3da87613deb47ff24a111247d3c384fec *vp90-2-03-size-202x198.webm -517e91204b25586da943556f4adc5951c9be8bee *vp90-2-03-size-202x198.webm.md5 -935ef56b01cfdb4265a7e24696645209ccb20970 *vp90-2-03-size-202x200.webm -55b8ec4a2513183144a8e27564596c06c7576fce *vp90-2-03-size-202x200.webm.md5 -849acf75e4f1d8d90046704e1103a18c64f30e35 *vp90-2-03-size-202x202.webm -c79afc6660df2824e7df314e5bfd71f0d8acf76b *vp90-2-03-size-202x202.webm.md5 -17b3a4d55576b770626ccb856b9f1a6c8f6ae476 *vp90-2-03-size-202x208.webm -0b887ff30409c58f2ccdc3bfacd6be7c69f8997a *vp90-2-03-size-202x208.webm.md5 -032d0ade4230fb2eef6d19915a7a1c9aa4a52617 *vp90-2-03-size-202x210.webm -f78f8e79533c0c88dd2bfdcec9b1c07848568ece *vp90-2-03-size-202x210.webm.md5 -915a38c31fe425d5b93c837121cfa8082f5ea5bc *vp90-2-03-size-202x224.webm -bf52a104074d0c5942aa7a5b31e11db47e43d48e *vp90-2-03-size-202x224.webm.md5 -be5cfde35666fa435e47d544d9258215beb1cf29 *vp90-2-03-size-202x226.webm -2fa2f87502fda756b319389c8975204e130a2e3f *vp90-2-03-size-202x226.webm.md5 -15d908e97862b5b4bf295610df011fb9aa09909b *vp90-2-03-size-208x196.webm -50c60792305d6a99be376dd596a6ff979325e6cc *vp90-2-03-size-208x196.webm.md5 -a367c7bc9fde56d6f4848cc573c7d4c1ce75e348 *vp90-2-03-size-208x198.webm -be85fb2c8d435a75484231356f07d06ebddd13cd *vp90-2-03-size-208x198.webm.md5 -05fd46deb7288e7253742091f56e54a9a441a187 *vp90-2-03-size-208x200.webm -74f8ec3b3a2fe81767ed1ab36a47bc0062d6223c *vp90-2-03-size-208x200.webm.md5 -d8985c4b386513a7385a4b3639bf91e469f1378b *vp90-2-03-size-208x202.webm -0614a1e8d92048852adcf605a51333f5fabc7f03 *vp90-2-03-size-208x202.webm.md5 -28b002242238479165ba4fb87ee6b442c64b32e4 *vp90-2-03-size-208x208.webm -37de5aca59bb900228400b0e115d3229edb9dcc0 *vp90-2-03-size-208x208.webm.md5 -c545be0050c2fad7c68427dbf86c62a739e94ab3 *vp90-2-03-size-208x210.webm -d646eccb3cd578f94b54777e32b88898bef6e17a *vp90-2-03-size-208x210.webm.md5 -63a0cfe295b661026dd7b1bebb67acace1db766f *vp90-2-03-size-208x224.webm -85c0361d93bf85a335248fef2767ff43eeef23db *vp90-2-03-size-208x224.webm.md5 -f911cc718d66e4fe8a865226088939c9eb1b7825 *vp90-2-03-size-208x226.webm -a6d583a57876e7b7ec48625b2b2cdbcf70cab837 *vp90-2-03-size-208x226.webm.md5 -5bbb0f36da9a4683cf04e724124d8696332911bf *vp90-2-03-size-210x196.webm -a3580fc7816d7fbcfb54fdba501cabbd06ba2f1d *vp90-2-03-size-210x196.webm.md5 -8db64d6f9ce36dd382013b42ae4e292deba697bc *vp90-2-03-size-210x198.webm -eda20f8268c7f4147bead4059e9c4897e09140a9 *vp90-2-03-size-210x198.webm.md5 -ce391505eeaf1d12406563101cd6b2dbbbb44bfc *vp90-2-03-size-210x200.webm -79d73b7f623082d2a00aa33e95c79d11c7d9c3a8 *vp90-2-03-size-210x200.webm.md5 -852db6fdc206e72391fc69b807f1954934679949 *vp90-2-03-size-210x202.webm -f69414c5677ed2f2b8b37ae76429e509a92276a5 *vp90-2-03-size-210x202.webm.md5 -c424cc3edd2308da7d33f27acb36b54db5bf2595 *vp90-2-03-size-210x208.webm -27b18562faa1b3184256f4eae8114b539b3e9d3e *vp90-2-03-size-210x208.webm.md5 -dd029eba719d50a2851592fa8b9b2efe88904930 *vp90-2-03-size-210x210.webm -c853a1670465eaa04ca31b3511995f1b6ed4f58f *vp90-2-03-size-210x210.webm.md5 -d962e8ae676c54d0c3ea04ec7c04b37ae6a786e3 *vp90-2-03-size-210x224.webm -93b793e79d987065b39ad8e2e71244368435fc25 *vp90-2-03-size-210x224.webm.md5 -3d0825fe83bcc125be1f78145ff43ca6d7588784 *vp90-2-03-size-210x226.webm -5230f31a57ca3b5311698a12035d2644533b3ec4 *vp90-2-03-size-210x226.webm.md5 -6622f8bd9279e1ce45509a58a31a990052d45e14 *vp90-2-03-size-224x196.webm -65411da07f60113f2be05c807879072b161d561e *vp90-2-03-size-224x196.webm.md5 -6744ff2ee2c41eb08c62ff30880833b6d77b585b *vp90-2-03-size-224x198.webm -46ea3641d41acd4bff347b224646c060d5620385 *vp90-2-03-size-224x198.webm.md5 -8eb91f3416a1404705f370caecd74b2b458351b1 *vp90-2-03-size-224x200.webm -196aefb854c8b95b9330263d6690b7ee15693ecf *vp90-2-03-size-224x200.webm.md5 -256a5a23ef4e6d5ef2871af5afb8cd13d28cec00 *vp90-2-03-size-224x202.webm -840ad8455dcf2be378c14b007e66fa642fc8196d *vp90-2-03-size-224x202.webm.md5 -db4606480ab48b96c9a6ff5e639f1f1aea2a12e4 *vp90-2-03-size-224x208.webm -40b9801d5620467499ac70fa6b7c40aaa5e1c331 *vp90-2-03-size-224x208.webm.md5 -e37159e687fe1cb24cffddfae059301adbaf4212 *vp90-2-03-size-224x210.webm -1e4acd4b6334ae260c3eed08652d0ba8122073f2 *vp90-2-03-size-224x210.webm.md5 -0de1eb4bb6285ae621e4f2b613d2aa4a8c95a130 *vp90-2-03-size-224x224.webm -37db449ad86fb286c2c02d94aa8fe0379c05044a *vp90-2-03-size-224x224.webm.md5 -32ebbf903a7d7881bcfe59639f1d472371f3bf27 *vp90-2-03-size-224x226.webm -5cc3ac5dc9f6912491aa2ddac863f8187f34c569 *vp90-2-03-size-224x226.webm.md5 -9480ff5c2c32b1870ac760c87514912616e6cf01 *vp90-2-03-size-226x196.webm -fe83655c0f1888f0af7b047785f01ba7ca9f1324 *vp90-2-03-size-226x196.webm.md5 -09cad4221996315cdddad4e502dbfabf53ca1d6a *vp90-2-03-size-226x198.webm -e3ddfdc650acb95adb45abd9b634e1f09ea8ac96 *vp90-2-03-size-226x198.webm.md5 -c34f49d55fe39e3f0b607e3cc95e30244225cecb *vp90-2-03-size-226x200.webm -abb83edc868a3523ccd4e5523fac2efbe7c3df1f *vp90-2-03-size-226x200.webm.md5 -d17bc08eedfc60c4c23d576a6c964a21bf854d1f *vp90-2-03-size-226x202.webm -1d22d2d0f375251c2d5a1acb4714bc35d963865b *vp90-2-03-size-226x202.webm.md5 -9bd537c4f92a25596ccd29fedfe181feac948b92 *vp90-2-03-size-226x208.webm -6feb0e7325386275719f3511ada9e248a2ae7df4 *vp90-2-03-size-226x208.webm.md5 -4487067f6cedd495b93696b44b37fe0a3e7eda14 *vp90-2-03-size-226x210.webm -49a8fa87945f47208168d541c068e78d878075d5 *vp90-2-03-size-226x210.webm.md5 -559fea2f8da42b33c1aa1dbc34d1d6781009847a *vp90-2-03-size-226x224.webm -83c6d8f2969b759e10e5c6542baca1265c874c29 *vp90-2-03-size-226x224.webm.md5 -fe0af2ee47b1e5f6a66db369e2d7e9d870b38dce *vp90-2-03-size-226x226.webm -94ad19b8b699cea105e2ff18f0df2afd7242bcf7 *vp90-2-03-size-226x226.webm.md5 -52bc1dfd3a97b24d922eb8a31d07527891561f2a *vp90-2-03-size-352x288.webm -3084d6d0a1eec22e85a394422fbc8faae58930a5 *vp90-2-03-size-352x288.webm.md5 -b6524e4084d15b5d0caaa3d3d1368db30cbee69c *vp90-2-03-deltaq.webm -65f45ec9a55537aac76104818278e0978f94a678 *vp90-2-03-deltaq.webm.md5 -4dbb87494c7f565ffc266c98d17d0d8c7a5c5aba *vp90-2-05-resize.ivf -7f6d8879336239a43dbb6c9f13178cb11cf7ed09 *vp90-2-05-resize.ivf.md5 -bf61ddc1f716eba58d4c9837d4e91031d9ce4ffe *vp90-2-06-bilinear.webm -f6235f937552e11d8eb331ec55da6b3aa596b9ac *vp90-2-06-bilinear.webm.md5 -0c83a1e414fde3bccd6dc451bbaee68e59974c76 *vp90-2-07-frame_parallel.webm -e5c2c9fb383e5bf3b563480adaeba5b7e3475ecd *vp90-2-07-frame_parallel.webm.md5 -086c7edcffd699ae7d99d710fd7e53b18910ca5b *vp90-2-08-tile_1x2_frame_parallel.webm -e981ecaabb29a80e0cbc1f4002384965ce8e95bb *vp90-2-08-tile_1x2_frame_parallel.webm.md5 -ed79be026a6f28646c5825da1c12d1fbc70f96a4 *vp90-2-08-tile_1x2.webm -45b404e025841c9750895fc1a9f6bd384fe6a315 *vp90-2-08-tile_1x2.webm.md5 -cf8ea970c776797aae71dac8317ea926d9431cab *vp90-2-08-tile_1x4_frame_parallel.webm -a481fbea465010b57af5a19ebf6d4a5cfe5b9278 *vp90-2-08-tile_1x4_frame_parallel.webm.md5 -0203ec456277a01aec401e7fb6c72c9a7e5e3f9d *vp90-2-08-tile_1x4.webm -c9b237dfcc01c1b414fbcaa481d014a906ef7998 *vp90-2-08-tile_1x4.webm.md5 -20c75157e91ab41f82f70ffa73d5d01df8469287 *vp90-2-08-tile-4x4.webm -ae7451810247fd13975cc257aa0301ff17102255 *vp90-2-08-tile-4x4.webm.md5 -2ec6e15422ac7a61af072dc5f27fcaf1942ce116 *vp90-2-08-tile-4x1.webm -0094f5ee5e46345017c30e0aa4835b550212d853 *vp90-2-08-tile-4x1.webm.md5 -edea45dac4a3c2e5372339f8851d24c9bef803d6 *vp90-2-09-subpixel-00.ivf -5428efc4bf92191faedf4a727fcd1d94966a7abc *vp90-2-09-subpixel-00.ivf.md5 -8cdd435d89029987ee196896e21520e5f879f04d *vp90-2-bbb_1280x720_tile_1x4_1310kbps.webm -091b373aa2ecb59aa5c647affd5bcafcc7547364 *vp90-2-bbb_1920x1080_tile_1x1_2581kbps.webm -87ee28032b0963a44b73a850fcc816a6dc83efbb *vp90-2-bbb_1920x1080_tile_1x4_2586kbps.webm -c6ce25c4bfd4bdfc2932b70428e3dfe11210ec4f *vp90-2-bbb_1920x1080_tile_1x4_fpm_2304kbps.webm -2064bdb22aa71c2691e0469fb62e8087a43f08f8 *vp90-2-bbb_426x240_tile_1x1_180kbps.webm -8080eda22694910162f0996e8a962612f381a57f *vp90-2-bbb_640x360_tile_1x2_337kbps.webm -a484b335c27ea189c0f0d77babea4a510ce12d50 *vp90-2-bbb_854x480_tile_1x2_651kbps.webm -3eacf1f006250be4cc5c92a7ef146e385ee62653 *vp90-2-sintel_1280x546_tile_1x4_1257kbps.webm -217f089a16447490823127b36ce0d945522accfd *vp90-2-sintel_1920x818_tile_1x4_fpm_2279kbps.webm -eedb3c641e60dacbe082491a16df529a5c9187df *vp90-2-sintel_426x182_tile_1x1_171kbps.webm -cb7e4955af183dff33bcba0c837f0922ab066400 *vp90-2-sintel_640x272_tile_1x2_318kbps.webm -48613f9380e2580002f8a09d6e412ea4e89a52b9 *vp90-2-sintel_854x364_tile_1x2_621kbps.webm -990a91f24dd284562d21d714ae773dff5452cad8 *vp90-2-tos_1280x534_tile_1x4_1306kbps.webm -aa402217577a659cfc670157735b4b8e9aa670fe *vp90-2-tos_1280x534_tile_1x4_fpm_952kbps.webm -b6dd558c90bca466b4bcbd03b3371648186465a7 *vp90-2-tos_1920x800_tile_1x4_fpm_2335kbps.webm -1a9c2914ba932a38f0a143efc1ad0e318e78888b *vp90-2-tos_426x178_tile_1x1_181kbps.webm -a3d2b09f24debad4747a1b3066f572be4273bced *vp90-2-tos_640x266_tile_1x2_336kbps.webm -c64b03b5c090e6888cb39685c31f00a6b79fa45c *vp90-2-tos_854x356_tile_1x2_656kbps.webm -94b533dbcf94292001e27cc51fec87f9e8c90c0b *vp90-2-tos_854x356_tile_1x2_fpm_546kbps.webm -0e7cd4135b231c9cea8d76c19f9e84b6fd77acec *vp90-2-08-tile_1x8_frame_parallel.webm -c9b6850af28579b031791066457f4cb40df6e1c7 *vp90-2-08-tile_1x8_frame_parallel.webm.md5 -e448b6e83490bca0f8d58b4f4b1126a17baf4b0c *vp90-2-08-tile_1x8.webm -5e524165f0397e6141d914f4f0a66267d7658376 *vp90-2-08-tile_1x8.webm.md5 -a34e14923d6d17b1144254d8187d7f85b700a63c *vp90-2-02-size-lf-1920x1080.webm -e3b28ddcfaeb37fb4d132b93f92642a9ad17c22d *vp90-2-02-size-lf-1920x1080.webm.md5 -d48c5db1b0f8e60521a7c749696b8067886033a3 *vp90-2-09-aq2.webm -84c1599298aac78f2fc05ae2274575d10569dfa0 *vp90-2-09-aq2.webm.md5 -55fc55ed73d578ed60fad05692579873f8bad758 *vp90-2-09-lf_deltas.webm -54638c38009198c38c8f3b25c182b709b6c1fd2e *vp90-2-09-lf_deltas.webm.md5 -510d95f3beb3b51c572611fdaeeece12277dac30 *vp90-2-10-show-existing-frame.webm -14d631096f4bfa2d71f7f739aec1448fb3c33bad *vp90-2-10-show-existing-frame.webm.md5 -d2feea7728e8d2c615981d0f47427a4a5a45d881 *vp90-2-10-show-existing-frame2.webm -5f7c7811baa3e4f03be1dd78c33971b727846821 *vp90-2-10-show-existing-frame2.webm.md5 -b4318e75f73a6a08992c7326de2fb589c2a794c7 *vp90-2-11-size-351x287.webm -b3c48382cf7d0454e83a02497c229d27720f9e20 *vp90-2-11-size-351x287.webm.md5 -8e0096475ea2535bac71d3e2fc09e0c451c444df *vp90-2-11-size-351x288.webm -19e003804ec1dfc5464813b32339a15d5ba7b42f *vp90-2-11-size-351x288.webm.md5 -40cd1d6a188d7a88b21ebac1e573d3f270ab261e *vp90-2-11-size-352x287.webm -68f515abe3858fc1eded46c8e6b2f727d43b5331 *vp90-2-11-size-352x287.webm.md5 -9a510769ff23db410880ec3029d433e87d17f7fc *vp90-2-12-droppable_1.ivf -952eaac6eefa6f62179ed1db3e922fd42fecc624 *vp90-2-12-droppable_1.ivf.md5 -9a510769ff23db410880ec3029d433e87d17f7fc *vp90-2-12-droppable_2.ivf -92a756469fa438220524e7fa6ac1d38c89514d17 *vp90-2-12-droppable_2.ivf.md5 -c21e97e4ba486520118d78b01a5cb6e6dc33e190 *vp90-2-12-droppable_3.ivf -601abc9e4176c70f82ac0381365e9b151fdd24cd *vp90-2-12-droppable_3.ivf.md5 -61c640dad23cd4f7ad811b867e7b7e3521f4e3ba *vp90-2-13-largescaling.webm -bca1b02eebdb088fa3f389fe0e7571e75a71f523 *vp90-2-13-largescaling.webm.md5 -c740708fa390806eebaf669909c1285ab464f886 *vp90-2-14-resize-fp-tiles-1-2.webm -c7b85ffd8e11500f73f52e7dc5a47f57c393d47f *vp90-2-14-resize-fp-tiles-1-2.webm.md5 -ec8faa352a08f7033c60f29f80d505e2d7daa103 *vp90-2-14-resize-fp-tiles-1-4.webm -6852c783fb421bda5ded3d4c5a3ffc46de03fbc1 *vp90-2-14-resize-fp-tiles-1-4.webm.md5 -8af61853ac0d07c4cb5bf7c2016661ba350b3497 *vp90-2-14-resize-fp-tiles-1-8.webm -571353bac89fea60b5706073409aa3c0d42aefe9 *vp90-2-14-resize-fp-tiles-1-8.webm.md5 -b1c187ed69931496b82ec194017a79831bafceef *vp90-2-14-resize-fp-tiles-1-16.webm -1c199a41afe42ce303944d70089eaaa2263b4a09 *vp90-2-14-resize-fp-tiles-1-16.webm.md5 -8eaae5a6f2dff934610b0c7a917d7f583ba74aa5 *vp90-2-14-resize-fp-tiles-2-1.webm -db18fcf915f7ffaea6c39feab8bda6c1688af011 *vp90-2-14-resize-fp-tiles-2-1.webm.md5 -bc3046d138941e2a20e9ceec0ff6d25c25d12af3 *vp90-2-14-resize-fp-tiles-4-1.webm -393211b808030d09a79927b17a4374b2f68a60ae *vp90-2-14-resize-fp-tiles-4-1.webm.md5 -6e8f8e31721a0f7f68a2964e36e0e698c2e276b1 *vp90-2-14-resize-fp-tiles-8-1.webm -491fd3cd78fb0577bfe905bb64bbf64bd7d29140 *vp90-2-14-resize-fp-tiles-8-1.webm.md5 -cc5958da2a7edf739cd2cfeb18bd05e77903087e *vp90-2-14-resize-fp-tiles-16-1.webm -0b58daf55aaf9063bf5b4fb33393d18b417dc428 *vp90-2-14-resize-fp-tiles-16-1.webm.md5 -821eeecc9d8c6a316134dd42d1ff057787d8047b *vp90-2-14-resize-fp-tiles-2-4.webm -374c549f2839a3d0b732c4e3650700144037e76c *vp90-2-14-resize-fp-tiles-2-4.webm.md5 -dff8c8e49aacea9f4c7f22cb882da984e2a1b405 *vp90-2-14-resize-fp-tiles-2-8.webm -e5b8820a7c823b21297d6e889e57ec401882c210 *vp90-2-14-resize-fp-tiles-2-8.webm.md5 -77629e4b23e32896aadf6e994c78bd4ffa1c7797 *vp90-2-14-resize-fp-tiles-2-16.webm -1937f5df032664ac345d4613ad4417b4967b1230 *vp90-2-14-resize-fp-tiles-2-16.webm.md5 -380ba5702bb1ec7947697314ab0300b5c56a1665 *vp90-2-14-resize-fp-tiles-4-2.webm -fde7b30d2aa64c1e851a4852f655d79fc542cf66 *vp90-2-14-resize-fp-tiles-4-2.webm.md5 -dc784b258ffa2abc2ae693d11792acf0bb9cb74f *vp90-2-14-resize-fp-tiles-8-2.webm -edf26f0130aeee8342d49c2c8f0793ad008782d9 *vp90-2-14-resize-fp-tiles-8-2.webm.md5 -8e575789fd63ebf69e8eff1b9a4351a249a73bee *vp90-2-14-resize-fp-tiles-16-2.webm -b6415318c1c589a1f64b9d569ce3cabbec2e0d52 *vp90-2-14-resize-fp-tiles-16-2.webm.md5 -e3adc944a11c4c5517e63664c84ebb0847b64d81 *vp90-2-14-resize-fp-tiles-4-8.webm -03cba0532bc90a05b1990db830bf5701e24e7982 *vp90-2-14-resize-fp-tiles-4-8.webm.md5 -3b27a991eb6d78dce38efab35b7db682e8cbbee3 *vp90-2-14-resize-fp-tiles-4-16.webm -5d16b7f82bf59f802724ddfd97abb487150b1c9d *vp90-2-14-resize-fp-tiles-4-16.webm.md5 -d5fed8c28c1d4c7e232ebbd25cf758757313ed96 *vp90-2-14-resize-fp-tiles-8-4.webm -5a8ff8a52cbbde7bfab569beb6d971c5f8b904f7 *vp90-2-14-resize-fp-tiles-8-4.webm.md5 -17a5faa023d77ee9dad423a4e0d3145796bbc500 *vp90-2-14-resize-fp-tiles-16-4.webm -2ef8daa3c3e750fd745130d0a76a39fe86f0448f *vp90-2-14-resize-fp-tiles-16-4.webm.md5 -9361e031f5cc990d8740863e310abb5167ae351e *vp90-2-14-resize-fp-tiles-8-16.webm -57f13a2197486584f4e1a4f82ad969f3abc5a1a2 *vp90-2-14-resize-fp-tiles-8-16.webm.md5 -5803fc6fcbfb47b7661f3fcc6499158a32b56675 *vp90-2-14-resize-fp-tiles-16-8.webm -be0fe64a1a4933696ff92d93f9bdecdbd886dc13 *vp90-2-14-resize-fp-tiles-16-8.webm.md5 -0ac0f6d20a0afed77f742a3b9acb59fd7b9cb093 *vp90-2-14-resize-fp-tiles-1-2-4-8-16.webm -1765315acccfe6cd12230e731369fcb15325ebfa *vp90-2-14-resize-fp-tiles-1-2-4-8-16.webm.md5 -4a2b7a683576fe8e330c7d1c4f098ff4e70a43a8 *vp90-2-14-resize-fp-tiles-16-8-4-2-1.webm -1ef480392112b3509cb190afbb96f9a38dd9fbac *vp90-2-14-resize-fp-tiles-16-8-4-2-1.webm.md5 -e615575ded499ea1d992f3b38e3baa434509cdcd *vp90-2-15-segkey.webm -e3ab35d4316c5e81325c50f5236ceca4bc0d35df *vp90-2-15-segkey.webm.md5 -9b7ca2cac09d34c4a5d296c1900f93b1e2f69d0d *vp90-2-15-segkey_adpq.webm -8f46ba5f785d0c2170591a153e0d0d146a7c8090 *vp90-2-15-segkey_adpq.webm.md5 -698a6910a97486b833073ef0c0b18d75dce57ee8 *vp90-2-16-intra-only.webm -5661b0168752969f055eec37b05fa9fa947dc7eb *vp90-2-16-intra-only.webm.md5 -c01bb7938f9a9f25e0c37afdec2f2fb73b6cc7fa *vp90-2-17-show-existing-frame.webm -cc75f351818b9a619818f5cc77b9bc013d0c1e11 *vp90-2-17-show-existing-frame.webm.md5 -013708bd043f0821a3e56fb8404d82e7a0c7af6c *vp91-2-04-yuv422.webm -1e58a7d23adad830a672f1733c9d2ae17890d59c *vp91-2-04-yuv422.webm.md5 -25d78f28948789d159a9453ebc13048b818251b1 *vp91-2-04-yuv440.webm -81b3870b27a7f695ef6a43e87ab04bbdb5aee2f5 *vp91-2-04-yuv440.webm.md5 -0321d507ce62dedc8a51b4e9011f7a19aed9c3dc *vp91-2-04-yuv444.webm -367e423dd41fdb49aa028574a2cfec5c2f325c5c *vp91-2-04-yuv444.webm.md5 -f77673b566f686853adefe0c578ad251b7241281 *vp92-2-20-10bit-yuv420.webm -abdedfaddacbbe1a15ac7a54e86360f03629fb7a *vp92-2-20-10bit-yuv420.webm.md5 -0c2c355a1b17b28537c5a3b19997c8783b69f1af *vp92-2-20-12bit-yuv420.webm -afb2c2798703e039189b0a15c8ac5685aa51d33f *vp92-2-20-12bit-yuv420.webm.md5 -0d661bc6e83da33238981481efd1b1802d323d88 *vp93-2-20-10bit-yuv422.webm -10318907063db22eb02fad332556edbbecd443cc *vp93-2-20-10bit-yuv422.webm.md5 -ebc6be2f7511a0bdeac0b18c67f84ba7168839c7 *vp93-2-20-12bit-yuv422.webm -235232267c6a1dc8a11e45d600f1c99d2f8b42d4 *vp93-2-20-12bit-yuv422.webm.md5 -f76b11b26d4beaceac7a7e7729dd5054d095164f *vp93-2-20-10bit-yuv440.webm -757b33b5ac969c5999999488a731a3d1e6d9fb88 *vp93-2-20-10bit-yuv440.webm.md5 -df8807dbd29bec795c2db9c3c18e511fbb988101 *vp93-2-20-12bit-yuv440.webm -ea4100930c3f59a1c23fbb33ab0ea01151cae159 *vp93-2-20-12bit-yuv440.webm.md5 -189c1b5f404ff41a50a7fc96341085ad541314a9 *vp93-2-20-10bit-yuv444.webm -2dd0177c2f9d970b6e698892634c653630f91f40 *vp93-2-20-10bit-yuv444.webm.md5 -bd44cf6e1c27343e3639df9ac21346aedd5d6973 *vp93-2-20-12bit-yuv444.webm -f36e5bdf5ec3213f32c0ddc82f95d82c5133bf27 *vp93-2-20-12bit-yuv444.webm.md5 -eb438c6540eb429f74404eedfa3228d409c57874 *desktop_640_360_30.yuv -89e70ebd22c27d275fe14dc2f1a41841a6d8b9ab *kirland_640_480_30.yuv -33c533192759e5bb4f07abfbac389dc259db4686 *macmarcomoving_640_480_30.yuv -8bfaab121080821b8f03b23467911e59ec59b8fe *macmarcostationary_640_480_30.yuv -70894878d916a599842d9ad0dcd24e10c13e5467 *niklas_640_480_30.yuv -8784b6df2d8cc946195a90ac00540500d2e522e4 *tacomanarrows_640_480_30.yuv -edd86a1f5e62fd9da9a9d46078247759c2638009 *tacomasmallcameramovement_640_480_30.yuv -9a70e8b7d14fba9234d0e51dce876635413ce444 *thaloundeskmtg_640_480_30.yuv -e7d315dbf4f3928779e0dc624311196d44491d32 *niklas_1280_720_30.yuv -c77e4a26616add298a05dd5d12397be22c0e40c5 *vp90-2-18-resize.ivf -c12918cf0a716417fba2de35c3fc5ab90e52dfce *vp90-2-18-resize.ivf.md5 -717da707afcaa1f692ff1946f291054eb75a4f06 *screendata.y4m -b7c1296630cdf1a7ef493d15ff4f9eb2999202f6 *invalid-vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf -0a3884edb3fd8f9d9b500223e650f7de257b67d8 *invalid-vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf.res -359e138dfb66863828397b77000ea7a83c844d02 *invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf -bbd33de01c17b165b4ce00308e8a19a942023ab8 *invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf.res -fac89b5735be8a86b0dc05159f996a5c3208ae32 *invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf -0a3884edb3fd8f9d9b500223e650f7de257b67d8 *invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf.res -4506dfdcdf8ee4250924b075a0dcf1f070f72e5a *invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf -bcdedaf168ac225575468fda77502d2dc9fd5baa *invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf.res -65e93f9653bcf65b022f7d225268d1a90a76e7bb *vp90-2-19-skip.webm -368dccdde5288c13c25695d2eacdc7402cadf613 *vp90-2-19-skip.webm.md5 -ffe460282df2b0e7d4603c2158653ad96f574b02 *vp90-2-19-skip-01.webm -bd21bc9eda4a4a36b221d71ede3a139fc3c7bd85 *vp90-2-19-skip-01.webm.md5 -178f5bd239e38cc1cc2657a7a5e1a9f52ad2d3fe *vp90-2-19-skip-02.webm -9020d5e260bd7df08e2b3d4b86f8623cee3daea2 *vp90-2-19-skip-02.webm.md5 -b03c408cf23158638da18dbc3323b99a1635c68a *invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf -0a3884edb3fd8f9d9b500223e650f7de257b67d8 *invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf.res -5e67e24e7f53fd189e565513cef8519b1bd6c712 *invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf -741158f67c0d9d23726624d06bdc482ad368afc9 *invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf.res -8b1f7bf7e86c0976d277f60e8fcd9539e75a079a *invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf -9c6bdf048fb2e66f07d4b4db5b32e6f303bd6109 *invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf.res -552e372e9b78127389fb06b34545df2cec15ba6d *invalid-vp91-2-mixedrefcsp-444to420.ivf -a61774cf03fc584bd9f0904fc145253bb8ea6c4c *invalid-vp91-2-mixedrefcsp-444to420.ivf.res -812d05a64a0d83c1b504d0519927ddc5a2cdb273 *invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf -1e472baaf5f6113459f0399a38a5a5e68d17799d *invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf.res -f97088c7359fc8d3d5aa5eafe57bc7308b3ee124 *vp90-2-20-big_superframe-01.webm -47d7d409785afa33b123376de0c907336e6c7bd7 *vp90-2-20-big_superframe-01.webm.md5 -65ade6d2786209582c50d34cfe22b3cdb033abaf *vp90-2-20-big_superframe-02.webm -7c0ed8d04c4d06c5411dd2e5de2411d37f092db5 *vp90-2-20-big_superframe-02.webm.md5 -667ec8718c982aef6be07eb94f083c2efb9d2d16 *vp90-2-07-frame_parallel-1.webm -bfc82bf848e9c05020d61e3ffc1e62f25df81d19 *vp90-2-07-frame_parallel-1.webm.md5 -efd5a51d175cfdacd169ed23477729dc558030dc *invalid-vp90-2-07-frame_parallel-1.webm -9f912712ec418be69adb910e2ca886a63c4cec08 *invalid-vp90-2-07-frame_parallel-2.webm -445f5a53ca9555341852997ccdd480a51540bd14 *invalid-vp90-2-07-frame_parallel-3.webm -d18c90709a0d03c82beadf10898b27d88fff719c *invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf -d06285d109ecbaef63b0cbcc44d70a129186f51c *invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf.res -e60d859b0ef2b331b21740cf6cb83fabe469b079 *invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf -0ae808dca4d3c1152a9576e14830b6faa39f1b4a *invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf.res -9cfc855459e7549fd015c79e8eca512b2f2cb7e3 *niklas_1280_720_30.y4m -5b5763b388b1b52a81bb82b39f7ec25c4bd3d0e1 *desktop_credits.y4m -85771f6ab44e4a0226e206c0cde8351dd5918953 *vp90-2-02-size-130x132.webm -512dad5eabbed37b4bbbc64ce153f1a5484427b8 *vp90-2-02-size-130x132.webm.md5 -01f7127d40360289db63b27f61cb9afcda350e95 *vp90-2-02-size-132x130.webm -4a94275328ae076cf60f966c097a8721010fbf5a *vp90-2-02-size-132x130.webm.md5 -f41c0400b5716b4b70552c40dd03d44be131e1cc *vp90-2-02-size-132x132.webm -1a69e989f697e424bfe3e3e8a77bb0c0992c8e47 *vp90-2-02-size-132x132.webm.md5 -94a5cbfacacba100e0c5f7861c72a1b417feca0f *vp90-2-02-size-178x180.webm -dedfecf1d784bcf70629592fa5e6f01d5441ccc9 *vp90-2-02-size-178x180.webm.md5 -4828b62478c04014bba3095a83106911a71cf387 *vp90-2-02-size-180x178.webm -423da2b861050c969d78ed8e8f8f14045d1d8199 *vp90-2-02-size-180x178.webm.md5 -338f7c9282f43e29940f5391118aadd17e4f9234 *vp90-2-02-size-180x180.webm -6c2ef013392310778dca5dd5351160eca66b0a60 *vp90-2-02-size-180x180.webm.md5 -679fa7d6807e936ff937d7b282e7dbd8ac76447e *vp90-2-14-resize-10frames-fp-tiles-1-2-4-8.webm -fc7267ab8fc2bf5d6c234e34ee6c078a967b4888 *vp90-2-14-resize-10frames-fp-tiles-1-2-4-8.webm.md5 -9d33a137c819792209c5ce4e4e1ee5da73d574fe *vp90-2-14-resize-10frames-fp-tiles-1-2.webm -0c78a154956a8605d050bdd75e0dcc4d39c040a6 *vp90-2-14-resize-10frames-fp-tiles-1-2.webm.md5 -d6a8d8c57f66a91d23e8e7df480f9ae841e56c37 *vp90-2-14-resize-10frames-fp-tiles-1-4.webm -e9b4e8c7b33b5fda745d340c3f47e6623ae40cf2 *vp90-2-14-resize-10frames-fp-tiles-1-4.webm.md5 -aa6fe043a0c4a42b49c87ebbe812d4afd9945bec *vp90-2-14-resize-10frames-fp-tiles-1-8.webm -028520578994c2d013d4c0129033d4f2ff31bbe0 *vp90-2-14-resize-10frames-fp-tiles-1-8.webm.md5 -d1d5463c9ea7b5cc5f609ddedccddf656f348d1a *vp90-2-14-resize-10frames-fp-tiles-2-1.webm -92d5872f5bdffbed721703b7e959b4f885e3d77a *vp90-2-14-resize-10frames-fp-tiles-2-1.webm.md5 -677cb29de1215d97346015af5807a9b1faad54cf *vp90-2-14-resize-10frames-fp-tiles-2-4.webm -a5db19f977094ec3fd60b4f7671b3e6740225e12 *vp90-2-14-resize-10frames-fp-tiles-2-4.webm.md5 -cdd3c52ba21067efdbb2de917fe2a965bf27332e *vp90-2-14-resize-10frames-fp-tiles-2-8.webm -db17ec5d894ea8b8d0b7f32206d0dd3d46dcfa6d *vp90-2-14-resize-10frames-fp-tiles-2-8.webm.md5 -0f6093c472125d05b764d7d1965c1d56771c0ea2 *vp90-2-14-resize-10frames-fp-tiles-4-1.webm -bc7c79e1bee07926dd970462ce6f64fc30eec3e1 *vp90-2-14-resize-10frames-fp-tiles-4-1.webm.md5 -c5142e2bff4091338196c8ea8bc9266e64f548bc *vp90-2-14-resize-10frames-fp-tiles-4-2.webm -22aa3dd430b69fd3d92f6561bac86deeed90486d *vp90-2-14-resize-10frames-fp-tiles-4-2.webm.md5 -ede8b1466d2f26e1b1bd9602addb9cd1017e1d8c *vp90-2-14-resize-10frames-fp-tiles-4-8.webm -508d5ebb9c0eac2a4100281a3ee052ec2fc19217 *vp90-2-14-resize-10frames-fp-tiles-4-8.webm.md5 -2b292e3392854cd1d76ae597a6f53656cf741cfa *vp90-2-14-resize-10frames-fp-tiles-8-1.webm -1c24e54fa19e94e1722f24676404444e941c3d31 *vp90-2-14-resize-10frames-fp-tiles-8-1.webm.md5 -61beda21064e09634564caa6697ab90bd53c9af7 *vp90-2-14-resize-10frames-fp-tiles-8-2.webm -9c0657b4d9e1d0e4c9d28a90e5a8630a65519124 *vp90-2-14-resize-10frames-fp-tiles-8-2.webm.md5 -1758c50a11a7c92522749b4a251664705f1f0d4b *vp90-2-14-resize-10frames-fp-tiles-8-4-2-1.webm -4f454a06750614314ae15a44087b79016fe2db97 *vp90-2-14-resize-10frames-fp-tiles-8-4-2-1.webm.md5 -3920c95ba94f1f048a731d9d9b416043b44aa4bd *vp90-2-14-resize-10frames-fp-tiles-8-4.webm -4eb347a0456d2c49a1e1d8de5aa1c51acc39887e *vp90-2-14-resize-10frames-fp-tiles-8-4.webm.md5 -4b95a74c032a473b6683d7ad5754db1b0ec378e9 *vp90-2-21-resize_inter_1280x720_5_1-2.webm -a7826dd386bedfe69d02736969bfb47fb6a40a5e *vp90-2-21-resize_inter_1280x720_5_1-2.webm.md5 -5cfff79e82c4d69964ccb8e75b4f0c53b9295167 *vp90-2-21-resize_inter_1280x720_5_3-4.webm -a18f57db4a25e1f543a99f2ceb182e00db0ee22f *vp90-2-21-resize_inter_1280x720_5_3-4.webm.md5 -d26db0811bf30eb4131d928669713e2485f8e833 *vp90-2-21-resize_inter_1280x720_7_1-2.webm -fd6f9f332cd5bea4c0f0d57be4297bea493cc5a1 *vp90-2-21-resize_inter_1280x720_7_1-2.webm.md5 -5c7d73d4d268e2ba9593b31cb091fd339505c7fd *vp90-2-21-resize_inter_1280x720_7_3-4.webm -7bbb949cabc1e70dadcc74582739f63b833034e0 *vp90-2-21-resize_inter_1280x720_7_3-4.webm.md5 -f2d2a41a60eb894aff0c5854afca15931f1445a8 *vp90-2-21-resize_inter_1920x1080_5_1-2.webm -66d7789992613ac9d678ff905ff1059daa1b89e4 *vp90-2-21-resize_inter_1920x1080_5_1-2.webm.md5 -764edb75fe7dd64e73a1b4f3b4b2b1bf237a4dea *vp90-2-21-resize_inter_1920x1080_5_3-4.webm -f78bea1075983fd990e7f25d4f31438f9b5efa34 *vp90-2-21-resize_inter_1920x1080_5_3-4.webm.md5 -96496f2ade764a5de9f0c27917c7df1f120fb2ef *vp90-2-21-resize_inter_1920x1080_7_1-2.webm -2632b635135ed5ecd67fd22dec7990d29c4f4cb5 *vp90-2-21-resize_inter_1920x1080_7_1-2.webm.md5 -74889ea42001bf41428cb742ca74e65129c886dc *vp90-2-21-resize_inter_1920x1080_7_3-4.webm -d2cf3b25956415bb579d368e7098097e482dd73a *vp90-2-21-resize_inter_1920x1080_7_3-4.webm.md5 -4658986a8ce36ebfcc80a1903e446eaab3985336 *vp90-2-21-resize_inter_320x180_5_1-2.webm -8a3d8cf325109ffa913cc9426c32eea8c202a09a *vp90-2-21-resize_inter_320x180_5_1-2.webm.md5 -16303aa45176520ee42c2c425247aadc1506b881 *vp90-2-21-resize_inter_320x180_5_3-4.webm -41cab1ddf7715b680a4dbce42faa9bcd72af4e5c *vp90-2-21-resize_inter_320x180_5_3-4.webm.md5 -56648adcee66dd0e5cb6ac947f5ee1b9cc8ba129 *vp90-2-21-resize_inter_320x180_7_1-2.webm -70047377787003cc03dda7b2394e6d7eaa666d9e *vp90-2-21-resize_inter_320x180_7_1-2.webm.md5 -d2ff99165488499cc55f75929f1ce5ca9c9e359b *vp90-2-21-resize_inter_320x180_7_3-4.webm -e69019e378114a4643db283b66d1a7e304761a56 *vp90-2-21-resize_inter_320x180_7_3-4.webm.md5 -4834d129bed0f4289d3a88f2ae3a1736f77621b0 *vp90-2-21-resize_inter_320x240_5_1-2.webm -a75653c53d22b623c1927fc0088da21dafef21f4 *vp90-2-21-resize_inter_320x240_5_1-2.webm.md5 -19818e1b7fd1c1e63d8873c31b0babe29dd33ba6 *vp90-2-21-resize_inter_320x240_5_3-4.webm -8d89814ff469a186312111651b16601dfbce4336 *vp90-2-21-resize_inter_320x240_5_3-4.webm.md5 -ac8057bae52498f324ce92a074d5f8207cc4a4a7 *vp90-2-21-resize_inter_320x240_7_1-2.webm -2643440898c83c08cc47bc744245af696b877c24 *vp90-2-21-resize_inter_320x240_7_1-2.webm.md5 -cf4a4cd38ac8b18c42d8c25a3daafdb39132256b *vp90-2-21-resize_inter_320x240_7_3-4.webm -70ba8ec9120b26e9b0ffa2c79b432f16cbcb50ec *vp90-2-21-resize_inter_320x240_7_3-4.webm.md5 -669f10409fe1c4a054010162ca47773ea1fdbead *vp90-2-21-resize_inter_640x360_5_1-2.webm -6355a04249004a35fb386dd1024214234f044383 *vp90-2-21-resize_inter_640x360_5_1-2.webm.md5 -c23763b950b8247c1775d1f8158d93716197676c *vp90-2-21-resize_inter_640x360_5_3-4.webm -59e6fc381e3ec3b7bdaac586334e0bc944d18fb6 *vp90-2-21-resize_inter_640x360_5_3-4.webm.md5 -71b45cbfdd068baa1f679a69e5e6f421d256a85f *vp90-2-21-resize_inter_640x360_7_1-2.webm -1416fc761b690c54a955c4cf017fa078520e8c18 *vp90-2-21-resize_inter_640x360_7_1-2.webm.md5 -6c409903279448a697e4db63bab1061784bcd8d2 *vp90-2-21-resize_inter_640x360_7_3-4.webm -60de1299793433a630b71130cf76c9f5965758e2 *vp90-2-21-resize_inter_640x360_7_3-4.webm.md5 -852b597b8af096d90c80bf0ed6ed3b336b851f19 *vp90-2-21-resize_inter_640x480_5_1-2.webm -f6856f19236ee46ed462bd0a2e7e72b9c3b9cea6 *vp90-2-21-resize_inter_640x480_5_1-2.webm.md5 -792a16c6f60043bd8dceb515f0b95b8891647858 *vp90-2-21-resize_inter_640x480_5_3-4.webm -68ffe59877e9a7863805e1c0a3ce18ce037d7c9d *vp90-2-21-resize_inter_640x480_5_3-4.webm.md5 -61e044c4759972a35ea3db8c1478a988910a4ef4 *vp90-2-21-resize_inter_640x480_7_1-2.webm -7739bfca167b1b43fea72f807f01e097b7cb98d8 *vp90-2-21-resize_inter_640x480_7_1-2.webm.md5 -7291af354b4418917eee00e3a7e366086a0b7a10 *vp90-2-21-resize_inter_640x480_7_3-4.webm -4a18b09ccb36564193f0215f599d745d95bb558c *vp90-2-21-resize_inter_640x480_7_3-4.webm.md5 -a000d568431d07379dd5a8ec066061c07e560b47 *invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf -1e75aad3433c5c21c194a7b53fc393970f0a8d7f *invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf.res -235182f9a1c5c8841552510dd4288487447bfc40 *invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf -787f04f0483320d536894282f3358a4f8cac1cf9 *invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf.res -91d3cefd0deb98f3b0caf3a2d900ec7a7605e53a *invalid-vp90-2-10-show-existing-frame.webm.ivf.s180315_r01-05_b6-.ivf -1e472baaf5f6113459f0399a38a5a5e68d17799d *invalid-vp90-2-10-show-existing-frame.webm.ivf.s180315_r01-05_b6-.ivf.res -70057835bf29d14e66699ce5f022df2551fb6b37 *invalid-crbug-629481.webm -5d9474c0309b7ca09a182d888f73b37a8fe1362c *invalid-crbug-629481.webm.res -7602e00378161ca36ae93cc6ee12dd30b5ba1e1d *vp90-2-22-svc_1280x720_3.ivf -02e53e3eefbf25ec0929047fe50876acdeb040bd *vp90-2-22-svc_1280x720_3.ivf.md5 -6fa3d3ac306a3d9ce1d610b78441dc00d2c2d4b9 *tos_vp8.webm -e402cbbf9e550ae017a1e9f1f73931c1d18474e8 *invalid-crbug-667044.webm -d3964f9dad9f60363c81b688324d95b4ec7c8038 *invalid-crbug-667044.webm.res -fd9df7f3f6992af1d7a9dde975c9a0d6f28c053d *invalid-bug-1443.ivf -fd3020fa6e9ca5966206738654c97dec313b0a95 *invalid-bug-1443.ivf.res -1a0e405606939f2febab1a21b30c37cb8f2c8cb1 *invalid-token-partition.ivf -90a8a95e7024f015b87f5483a65036609b3d1b74 *invalid-token-partition.ivf.res -17696cd21e875f1d6e5d418cbf89feab02c8850a *vp90-2-22-svc_1280x720_1.webm -e2f9e1e47a791b4e939a9bdc50bf7a25b3761f77 *vp90-2-22-svc_1280x720_1.webm.md5 -a0fbbbc5dd50fd452096f4455a58c1a8c9f66697 *invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf -a61774cf03fc584bd9f0904fc145253bb8ea6c4c *invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf.res -894fae3afee0290546590823974203ab4b8abd95 *crbug-1539.rawfile -f1026c03efd5da21b381c8eb21f0d64e6d7e4ba3 *invalid-crbug-1558.ivf -eb198c25f861c3fe2cbd310de11eb96843019345 *invalid-crbug-1558.ivf.res -c62b005a9fd32c36a1b3f67de6840330f9915e34 *invalid-crbug-1562.ivf -f0cd8389948ad16085714d96567612136f6a46c5 *invalid-crbug-1562.ivf.res -bac455906360b45338a16dd626ac5f19bc36a307 *desktop_office1.1280_720-020.yuv -094be4b80fa30bd227149ea16ab6476d549ea092 *slides_code_term_web_plot.1920_1080.yuv -518a0be998afece76d3df76047d51e256c591ff2 *invalid-bug-148271109.ivf -d3964f9dad9f60363c81b688324d95b4ec7c8038 *invalid-bug-148271109.ivf.res -ad18ca16f0a249fb3b7c38de0d9b327fed273f96 *hantro_collage_w352h288_nv12.yuv -8a0b2c350539859463d3546a67876c83ff6ff0ac *desktopqvga.320_240.yuv -ad9942a073e245585c93f764ea299382a65939a7 *crowd_run_360p_10_150f.y4m -f9a73e921552598a5804911e9f84fec2318e056a *repro-oss-fuzz-69906.y4m diff --git a/presentation/src/main/cpp/third_party/libvpx/test/test.mk b/presentation/src/main/cpp/third_party/libvpx/test/test.mk deleted file mode 100644 index 28fe9dbb..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/test.mk +++ /dev/null @@ -1,243 +0,0 @@ -LIBVPX_TEST_SRCS-yes += acm_random.h -LIBVPX_TEST_SRCS-yes += bench.h -LIBVPX_TEST_SRCS-yes += bench.cc -LIBVPX_TEST_SRCS-yes += buffer.h -LIBVPX_TEST_SRCS-yes += clear_system_state.h -LIBVPX_TEST_SRCS-yes += codec_factory.h -LIBVPX_TEST_SRCS-yes += md5_helper.h -LIBVPX_TEST_SRCS-yes += register_state_check.h -LIBVPX_TEST_SRCS-yes += test.mk -LIBVPX_TEST_SRCS-yes += init_vpx_test.cc -LIBVPX_TEST_SRCS-yes += init_vpx_test.h -LIBVPX_TEST_SRCS-yes += test_libvpx.cc -LIBVPX_TEST_SRCS-yes += test_vectors.cc -LIBVPX_TEST_SRCS-yes += test_vectors.h -LIBVPX_TEST_SRCS-yes += util.h -LIBVPX_TEST_SRCS-yes += video_source.h - -## -## BLACK BOX TESTS -## -## Black box tests only use the public API. -## -LIBVPX_TEST_SRCS-yes += ../md5_utils.h ../md5_utils.c -LIBVPX_TEST_SRCS-yes += vpx_image_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ivf_video_source.h -LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += ../y4minput.h ../y4minput.c -ifneq ($(CONFIG_REALTIME_ONLY),yes) -LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += altref_test.cc -endif -LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += encode_api_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += error_resilience_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += i420_video_source.h -LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += realtime_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += resize_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += y4m_video_source.h -LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += yuv_video_source.h - -ifneq ($(CONFIG_REALTIME_ONLY),yes) -LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += config_test.cc -endif -LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += cq_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += keyframe_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += vp8_datarate_test.cc - -LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += byte_alignment_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += decode_svc_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += external_frame_buffer_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += user_priv_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += active_map_refresh_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += active_map_test.cc -ifneq ($(CONFIG_REALTIME_ONLY),yes) -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += alt_ref_aq_segment_test.cc -endif -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += aq_segment_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += borders_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += cpu_speed_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += frame_size_tests.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_lossless_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_end_to_end_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += decode_corrupted.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_ethread_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_motion_vector_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += level_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_datarate_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_test.h -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_end_to_end_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += timestamp_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_datarate_test.cc -ifneq ($(CONFIG_REALTIME_ONLY),yes) -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_ext_ratectrl_test.cc -endif -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += ../vp9/simple_encode.h - -LIBVPX_TEST_SRCS-yes += decode_test_driver.cc -LIBVPX_TEST_SRCS-yes += decode_test_driver.h -LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += encode_test_driver.cc -LIBVPX_TEST_SRCS-yes += encode_test_driver.h - -## IVF writing. -LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += ../ivfenc.c ../ivfenc.h - -## Y4m parsing. -LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += y4m_test.cc ../y4menc.c ../y4menc.h - -## WebM Parsing -ifeq ($(CONFIG_WEBM_IO), yes) -LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvparser.cc -LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvreader.cc -LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvparser.h -LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvreader.h -LIBWEBM_PARSER_SRCS += ../third_party/libwebm/common/webmids.h -LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += $(LIBWEBM_PARSER_SRCS) -LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../tools_common.h -LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../webmdec.cc -LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../webmdec.h -LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += webm_video_source.h -LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_skip_loopfilter_test.cc -$(BUILD_PFX)third_party/libwebm/%.cc.o: CXXFLAGS += $(LIBWEBM_CXXFLAGS) -endif - -LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += decode_api_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += test_vector_test.cc - -# Currently we only support decoder perf tests for vp9. Also they read from WebM -# files, so WebM IO is required. -ifeq ($(CONFIG_DECODE_PERF_TESTS)$(CONFIG_VP9_DECODER)$(CONFIG_WEBM_IO), \ - yesyesyes) -LIBVPX_TEST_SRCS-yes += decode_perf_test.cc -endif - -# encode perf tests are vp9 only -ifeq ($(CONFIG_ENCODE_PERF_TESTS)$(CONFIG_VP9_ENCODER), yesyes) -LIBVPX_TEST_SRCS-yes += encode_perf_test.cc -endif - -## Multi-codec blackbox tests. -ifeq ($(findstring yes,$(CONFIG_VP8_DECODER)$(CONFIG_VP9_DECODER)), yes) -LIBVPX_TEST_SRCS-yes += invalid_file_test.cc -endif - -## -## WHITE BOX TESTS -## -## Whitebox tests invoke functions not exposed via the public API. Certain -## shared library builds don't make these functions accessible. -## -ifeq ($(CONFIG_SHARED),) - -## VP8 -ifeq ($(CONFIG_VP8),yes) - -# These tests require both the encoder and decoder to be built. -ifeq ($(CONFIG_VP8_ENCODER)$(CONFIG_VP8_DECODER),yesyes) -LIBVPX_TEST_SRCS-yes += vp8_boolcoder_test.cc -LIBVPX_TEST_SRCS-yes += vp8_fragments_test.cc -endif -LIBVPX_TEST_SRCS-$(CONFIG_POSTPROC) += add_noise_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_POSTPROC) += pp_filter_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP8_DECODER) += vp8_decrypt_test.cc -ifneq (, $(filter yes, $(HAVE_SSE2) $(HAVE_SSSE3) $(HAVE_SSE4_1) $(HAVE_NEON) \ - $(HAVE_MSA) $(HAVE_MMI))) -LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += quantize_test.cc -endif -LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += set_roi.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += variance_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += vp8_fdct4x4_test.cc - -LIBVPX_TEST_SRCS-yes += idct_test.cc -LIBVPX_TEST_SRCS-yes += predict_test.cc -LIBVPX_TEST_SRCS-yes += vpx_scale_test.cc -LIBVPX_TEST_SRCS-yes += vpx_scale_test.h - -ifeq ($(CONFIG_VP8_ENCODER)$(CONFIG_TEMPORAL_DENOISING),yesyes) -LIBVPX_TEST_SRCS-$(HAVE_SSE2) += vp8_denoiser_sse2_test.cc -endif - -endif # VP8 - -## VP9 -ifeq ($(CONFIG_VP9),yes) - -# These tests require both the encoder and decoder to be built. -ifeq ($(CONFIG_VP9_ENCODER)$(CONFIG_VP9_DECODER),yesyes) -# IDCT test currently depends on FDCT function -LIBVPX_TEST_SRCS-yes += idct8x8_test.cc -LIBVPX_TEST_SRCS-yes += partial_idct_test.cc -LIBVPX_TEST_SRCS-yes += superframe_test.cc -LIBVPX_TEST_SRCS-yes += tile_independence_test.cc -LIBVPX_TEST_SRCS-yes += vp9_boolcoder_test.cc -LIBVPX_TEST_SRCS-yes += vp9_encoder_parms_get_to_decoder.cc -LIBVPX_TEST_SRCS-yes += vp9_roi_test.cc -endif - -LIBVPX_TEST_SRCS-yes += convolve_test.cc -LIBVPX_TEST_SRCS-yes += lpf_test.cc -LIBVPX_TEST_SRCS-yes += vp9_intrapred_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_decrypt_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_thread_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += avg_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += comp_avg_pred_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct16x16_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct32x32_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct_partial_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += fdct8x8_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += hadamard_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += minmax_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_scale_test.cc -ifneq ($(CONFIG_REALTIME_ONLY),yes) -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += yuv_temporal_filter_test.cc -endif -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += variance_test.cc -ifneq (, $(filter yes, $(HAVE_SSE2) $(HAVE_AVX2) $(HAVE_NEON))) -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_block_error_test.cc -endif -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_quantize_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_subtract_test.cc - -ifeq ($(CONFIG_VP9_ENCODER),yes) -LIBVPX_TEST_SRCS-$(CONFIG_INTERNAL_STATS) += blockiness_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_INTERNAL_STATS) += consistency_test.cc -endif - -ifeq ($(CONFIG_VP9_ENCODER),yes) -LIBVPX_TEST_SRCS-$(CONFIG_NON_GREEDY_MV) += non_greedy_mv_test.cc -endif - -ifeq ($(CONFIG_VP9_ENCODER)$(CONFIG_VP9_TEMPORAL_DENOISING),yesyes) -LIBVPX_TEST_SRCS-yes += vp9_denoiser_test.cc -endif -LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_arf_freq_test.cc - -ifeq ($(CONFIG_VP9_ENCODER),yes) -SIMPLE_ENCODE_TEST_SRCS-$(CONFIG_RATE_CTRL) := simple_encode_test.cc -endif - -endif # VP9 - -## Multi-codec / unconditional whitebox tests. - -LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += sad_test.cc -ifneq (, $(filter yes, $(HAVE_NEON) $(HAVE_SSE2) $(HAVE_MSA))) -LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += sum_squares_test.cc -endif - -TEST_INTRA_PRED_SPEED_SRCS-yes := test_intra_pred_speed.cc -TEST_INTRA_PRED_SPEED_SRCS-yes += ../md5_utils.h ../md5_utils.c -TEST_INTRA_PRED_SPEED_SRCS-yes += init_vpx_test.cc -TEST_INTRA_PRED_SPEED_SRCS-yes += init_vpx_test.h - -RC_INTERFACE_TEST_SRCS-yes := test_rc_interface.cc -RC_INTERFACE_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_ratectrl_rtc_test.cc -RC_INTERFACE_TEST_SRCS-$(CONFIG_VP8_ENCODER) += vp8_ratectrl_rtc_test.cc -RC_INTERFACE_TEST_SRCS-$(CONFIG_ENCODERS) += encode_test_driver.cc -RC_INTERFACE_TEST_SRCS-$(CONFIG_ENCODERS) += encode_test_driver.h -RC_INTERFACE_TEST_SRCS-yes += decode_test_driver.cc -RC_INTERFACE_TEST_SRCS-yes += decode_test_driver.h -RC_INTERFACE_TEST_SRCS-yes += codec_factory.h - -endif # CONFIG_SHARED - -include $(SRC_PATH_BARE)/test/test-data.mk diff --git a/presentation/src/main/cpp/third_party/libvpx/test/test_intra_pred_speed.cc b/presentation/src/main/cpp/third_party/libvpx/test/test_intra_pred_speed.cc deleted file mode 100644 index b122c345..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/test_intra_pred_speed.cc +++ /dev/null @@ -1,616 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -// Test and time VPX intra-predictor functions - -#include -#include - -#include "gtest/gtest.h" - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "test/acm_random.h" -#include "test/clear_system_state.h" -#include "test/init_vpx_test.h" -#include "test/md5_helper.h" -#include "vpx/vpx_integer.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/vpx_timer.h" - -// ----------------------------------------------------------------------------- - -namespace { - -typedef void (*VpxPredFunc)(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left); - -const int kBPS = 32; -const int kTotalPixels = 32 * kBPS; -const int kNumVp9IntraPredFuncs = 13; -const char *kVp9IntraPredNames[kNumVp9IntraPredFuncs] = { - "DC_PRED", "DC_LEFT_PRED", "DC_TOP_PRED", "DC_128_PRED", "V_PRED", - "H_PRED", "D45_PRED", "D135_PRED", "D117_PRED", "D153_PRED", - "D207_PRED", "D63_PRED", "TM_PRED" -}; - -template -struct IntraPredTestMem { - void Init(int block_size, int bd) { - libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed()); - Pixel *const above = above_mem + 16; - const int mask = (1 << bd) - 1; - for (int i = 0; i < kTotalPixels; ++i) ref_src[i] = rnd.Rand16() & mask; - for (int i = 0; i < kBPS; ++i) left[i] = rnd.Rand16() & mask; - for (int i = -1; i < kBPS; ++i) above[i] = rnd.Rand16() & mask; - - // d45/d63 require the top row to be extended. - ASSERT_LE(block_size, kBPS); - for (int i = block_size; i < 2 * block_size; ++i) { - above[i] = above[block_size - 1]; - } - } - - DECLARE_ALIGNED(16, Pixel, src[kTotalPixels]); - DECLARE_ALIGNED(16, Pixel, ref_src[kTotalPixels]); - DECLARE_ALIGNED(16, Pixel, left[kBPS]); - DECLARE_ALIGNED(16, Pixel, above_mem[2 * kBPS + 16]); -}; - -typedef IntraPredTestMem Vp9IntraPredTestMem; - -void CheckMd5Signature(const char name[], const char *const signatures[], - const void *data, size_t data_size, int elapsed_time, - int idx) { - libvpx_test::MD5 md5; - md5.Add(reinterpret_cast(data), data_size); - printf("Mode %s[%12s]: %5d ms MD5: %s\n", name, kVp9IntraPredNames[idx], - elapsed_time, md5.Get()); - EXPECT_STREQ(signatures[idx], md5.Get()); -} - -void TestIntraPred(const char name[], VpxPredFunc const *pred_funcs, - const char *const signatures[], int block_size) { - const int kNumTests = static_cast( - 2.e10 / (block_size * block_size * kNumVp9IntraPredFuncs)); - Vp9IntraPredTestMem intra_pred_test_mem; - const uint8_t *const above = intra_pred_test_mem.above_mem + 16; - - intra_pred_test_mem.Init(block_size, 8); - - for (int k = 0; k < kNumVp9IntraPredFuncs; ++k) { - if (pred_funcs[k] == nullptr) continue; - memcpy(intra_pred_test_mem.src, intra_pred_test_mem.ref_src, - sizeof(intra_pred_test_mem.src)); - vpx_usec_timer timer; - vpx_usec_timer_start(&timer); - for (int num_tests = 0; num_tests < kNumTests; ++num_tests) { - pred_funcs[k](intra_pred_test_mem.src, kBPS, above, - intra_pred_test_mem.left); - } - libvpx_test::ClearSystemState(); - vpx_usec_timer_mark(&timer); - const int elapsed_time = - static_cast(vpx_usec_timer_elapsed(&timer) / 1000); - CheckMd5Signature(name, signatures, intra_pred_test_mem.src, - sizeof(intra_pred_test_mem.src), elapsed_time, k); - } -} - -void TestIntraPred4(VpxPredFunc const *pred_funcs) { - static const char *const kSignatures[kNumVp9IntraPredFuncs] = { - "e7ed7353c3383fff942e500e9bfe82fe", "2a4a26fcc6ce005eadc08354d196c8a9", - "269d92eff86f315d9c38fe7640d85b15", "ae2960eea9f71ee3dabe08b282ec1773", - "6c1abcc44e90148998b51acd11144e9c", "f7bb3186e1ef8a2b326037ff898cad8e", - "364c1f3fb2f445f935aec2a70a67eaa4", "141624072a4a56773f68fadbdd07c4a7", - "7be49b08687a5f24df3a2c612fca3876", "459bb5d9fd5b238348179c9a22108cd6", - "73edb8831bf1bdfce21ae8eaa43b1234", "2e2457f2009c701a355a8b25eb74fcda", - "52ae4e8bdbe41494c1f43051d4dd7f0b" - }; - TestIntraPred("Intra4", pred_funcs, kSignatures, 4); -} - -void TestIntraPred8(VpxPredFunc const *pred_funcs) { - static const char *const kSignatures[kNumVp9IntraPredFuncs] = { - "d8bbae5d6547cfc17e4f5f44c8730e88", "373bab6d931868d41a601d9d88ce9ac3", - "6fdd5ff4ff79656c14747598ca9e3706", "d9661c2811d6a73674f40ffb2b841847", - "7c722d10b19ccff0b8c171868e747385", "f81dd986eb2b50f750d3a7da716b7e27", - "d500f2c8fc78f46a4c74e4dcf51f14fb", "0e3523f9cab2142dd37fd07ec0760bce", - "79ac4efe907f0a0f1885d43066cfedee", "19ecf2432ac305057de3b6578474eec6", - "4f985b61acc6dd5d2d2585fa89ea2e2d", "f1bb25a9060dd262f405f15a38f5f674", - "209ea00801584829e9a0f7be7d4a74ba" - }; - TestIntraPred("Intra8", pred_funcs, kSignatures, 8); -} - -void TestIntraPred16(VpxPredFunc const *pred_funcs) { - static const char *const kSignatures[kNumVp9IntraPredFuncs] = { - "50971c07ce26977d30298538fffec619", "527a6b9e0dc5b21b98cf276305432bef", - "7eff2868f80ebc2c43a4f367281d80f7", "67cd60512b54964ef6aff1bd4816d922", - "48371c87dc95c08a33b2048f89cf6468", "b0acf2872ee411d7530af6d2625a7084", - "f32aafed4d8d3776ed58bcb6188756d5", "dae208f3dca583529cff49b73f7c4183", - "7af66a2f4c8e0b4908e40f047e60c47c", "125e3ab6ab9bc961f183ec366a7afa88", - "6b90f25b23983c35386b9fd704427622", "f8d6b11d710edc136a7c62c917435f93", - "ed308f18614a362917f411c218aee532" - }; - TestIntraPred("Intra16", pred_funcs, kSignatures, 16); -} - -void TestIntraPred32(VpxPredFunc const *pred_funcs) { - static const char *const kSignatures[kNumVp9IntraPredFuncs] = { - "a0a618c900e65ae521ccc8af789729f2", "985aaa7c72b4a6c2fb431d32100cf13a", - "10662d09febc3ca13ee4e700120daeb5", "b3b01379ba08916ef6b1b35f7d9ad51c", - "9f4261755795af97e34679c333ec7004", "bc2c9da91ad97ef0d1610fb0a9041657", - "75c79b1362ad18abfcdb1aa0aacfc21d", "4039bb7da0f6860090d3c57b5c85468f", - "b29fff7b61804e68383e3a609b33da58", "e1aa5e49067fd8dba66c2eb8d07b7a89", - "4e042822909c1c06d3b10a88281df1eb", "72eb9d9e0e67c93f4c66b70348e9fef7", - "a22d102bcb51ca798aac12ca4ae8f2e8" - }; - TestIntraPred("Intra32", pred_funcs, kSignatures, 32); -} - -} // namespace - -// Defines a test case for |arch| (e.g., C, SSE2, ...) passing the predictors -// to |test_func|. The test name is 'arch.test_func', e.g., C.TestIntraPred4. -#define INTRA_PRED_TEST(arch, test_func, dc, dc_left, dc_top, dc_128, v, h, \ - d45, d135, d117, d153, d207, d63, tm) \ - TEST(arch, test_func) { \ - static const VpxPredFunc vpx_intra_pred[] = { \ - dc, dc_left, dc_top, dc_128, v, h, d45, d135, d117, d153, d207, d63, tm \ - }; \ - test_func(vpx_intra_pred); \ - } - -// ----------------------------------------------------------------------------- - -INTRA_PRED_TEST(C, TestIntraPred4, vpx_dc_predictor_4x4_c, - vpx_dc_left_predictor_4x4_c, vpx_dc_top_predictor_4x4_c, - vpx_dc_128_predictor_4x4_c, vpx_v_predictor_4x4_c, - vpx_h_predictor_4x4_c, vpx_d45_predictor_4x4_c, - vpx_d135_predictor_4x4_c, vpx_d117_predictor_4x4_c, - vpx_d153_predictor_4x4_c, vpx_d207_predictor_4x4_c, - vpx_d63_predictor_4x4_c, vpx_tm_predictor_4x4_c) - -INTRA_PRED_TEST(C, TestIntraPred8, vpx_dc_predictor_8x8_c, - vpx_dc_left_predictor_8x8_c, vpx_dc_top_predictor_8x8_c, - vpx_dc_128_predictor_8x8_c, vpx_v_predictor_8x8_c, - vpx_h_predictor_8x8_c, vpx_d45_predictor_8x8_c, - vpx_d135_predictor_8x8_c, vpx_d117_predictor_8x8_c, - vpx_d153_predictor_8x8_c, vpx_d207_predictor_8x8_c, - vpx_d63_predictor_8x8_c, vpx_tm_predictor_8x8_c) - -INTRA_PRED_TEST(C, TestIntraPred16, vpx_dc_predictor_16x16_c, - vpx_dc_left_predictor_16x16_c, vpx_dc_top_predictor_16x16_c, - vpx_dc_128_predictor_16x16_c, vpx_v_predictor_16x16_c, - vpx_h_predictor_16x16_c, vpx_d45_predictor_16x16_c, - vpx_d135_predictor_16x16_c, vpx_d117_predictor_16x16_c, - vpx_d153_predictor_16x16_c, vpx_d207_predictor_16x16_c, - vpx_d63_predictor_16x16_c, vpx_tm_predictor_16x16_c) - -INTRA_PRED_TEST(C, TestIntraPred32, vpx_dc_predictor_32x32_c, - vpx_dc_left_predictor_32x32_c, vpx_dc_top_predictor_32x32_c, - vpx_dc_128_predictor_32x32_c, vpx_v_predictor_32x32_c, - vpx_h_predictor_32x32_c, vpx_d45_predictor_32x32_c, - vpx_d135_predictor_32x32_c, vpx_d117_predictor_32x32_c, - vpx_d153_predictor_32x32_c, vpx_d207_predictor_32x32_c, - vpx_d63_predictor_32x32_c, vpx_tm_predictor_32x32_c) - -#if HAVE_SSE2 -INTRA_PRED_TEST(SSE2, TestIntraPred4, vpx_dc_predictor_4x4_sse2, - vpx_dc_left_predictor_4x4_sse2, vpx_dc_top_predictor_4x4_sse2, - vpx_dc_128_predictor_4x4_sse2, vpx_v_predictor_4x4_sse2, - vpx_h_predictor_4x4_sse2, vpx_d45_predictor_4x4_sse2, nullptr, - nullptr, nullptr, vpx_d207_predictor_4x4_sse2, nullptr, - vpx_tm_predictor_4x4_sse2) - -INTRA_PRED_TEST(SSE2, TestIntraPred8, vpx_dc_predictor_8x8_sse2, - vpx_dc_left_predictor_8x8_sse2, vpx_dc_top_predictor_8x8_sse2, - vpx_dc_128_predictor_8x8_sse2, vpx_v_predictor_8x8_sse2, - vpx_h_predictor_8x8_sse2, vpx_d45_predictor_8x8_sse2, nullptr, - nullptr, nullptr, nullptr, nullptr, vpx_tm_predictor_8x8_sse2) - -INTRA_PRED_TEST(SSE2, TestIntraPred16, vpx_dc_predictor_16x16_sse2, - vpx_dc_left_predictor_16x16_sse2, - vpx_dc_top_predictor_16x16_sse2, - vpx_dc_128_predictor_16x16_sse2, vpx_v_predictor_16x16_sse2, - vpx_h_predictor_16x16_sse2, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, vpx_tm_predictor_16x16_sse2) - -INTRA_PRED_TEST(SSE2, TestIntraPred32, vpx_dc_predictor_32x32_sse2, - vpx_dc_left_predictor_32x32_sse2, - vpx_dc_top_predictor_32x32_sse2, - vpx_dc_128_predictor_32x32_sse2, vpx_v_predictor_32x32_sse2, - vpx_h_predictor_32x32_sse2, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, vpx_tm_predictor_32x32_sse2) -#endif // HAVE_SSE2 - -#if HAVE_SSSE3 -INTRA_PRED_TEST(SSSE3, TestIntraPred4, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, - vpx_d153_predictor_4x4_ssse3, nullptr, - vpx_d63_predictor_4x4_ssse3, nullptr) -INTRA_PRED_TEST(SSSE3, TestIntraPred8, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, - vpx_d153_predictor_8x8_ssse3, vpx_d207_predictor_8x8_ssse3, - vpx_d63_predictor_8x8_ssse3, nullptr) -INTRA_PRED_TEST(SSSE3, TestIntraPred16, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, vpx_d45_predictor_16x16_ssse3, nullptr, - nullptr, vpx_d153_predictor_16x16_ssse3, - vpx_d207_predictor_16x16_ssse3, vpx_d63_predictor_16x16_ssse3, - nullptr) -INTRA_PRED_TEST(SSSE3, TestIntraPred32, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, vpx_d45_predictor_32x32_ssse3, nullptr, - nullptr, vpx_d153_predictor_32x32_ssse3, - vpx_d207_predictor_32x32_ssse3, vpx_d63_predictor_32x32_ssse3, - nullptr) -#endif // HAVE_SSSE3 - -#if HAVE_DSPR2 -INTRA_PRED_TEST(DSPR2, TestIntraPred4, vpx_dc_predictor_4x4_dspr2, nullptr, - nullptr, nullptr, nullptr, vpx_h_predictor_4x4_dspr2, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, - vpx_tm_predictor_4x4_dspr2) -INTRA_PRED_TEST(DSPR2, TestIntraPred8, vpx_dc_predictor_8x8_dspr2, nullptr, - nullptr, nullptr, nullptr, vpx_h_predictor_8x8_dspr2, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, - vpx_tm_predictor_8x8_c) -INTRA_PRED_TEST(DSPR2, TestIntraPred16, vpx_dc_predictor_16x16_dspr2, nullptr, - nullptr, nullptr, nullptr, vpx_h_predictor_16x16_dspr2, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr) -#endif // HAVE_DSPR2 - -#if HAVE_NEON -INTRA_PRED_TEST(NEON, TestIntraPred4, vpx_dc_predictor_4x4_neon, - vpx_dc_left_predictor_4x4_neon, vpx_dc_top_predictor_4x4_neon, - vpx_dc_128_predictor_4x4_neon, vpx_v_predictor_4x4_neon, - vpx_h_predictor_4x4_neon, vpx_d45_predictor_4x4_neon, - vpx_d135_predictor_4x4_neon, vpx_d117_predictor_4x4_neon, - vpx_d153_predictor_4x4_neon, vpx_d207_predictor_4x4_neon, - vpx_d63_predictor_4x4_neon, vpx_tm_predictor_4x4_neon) -INTRA_PRED_TEST(NEON, TestIntraPred8, vpx_dc_predictor_8x8_neon, - vpx_dc_left_predictor_8x8_neon, vpx_dc_top_predictor_8x8_neon, - vpx_dc_128_predictor_8x8_neon, vpx_v_predictor_8x8_neon, - vpx_h_predictor_8x8_neon, vpx_d45_predictor_8x8_neon, - vpx_d135_predictor_8x8_neon, vpx_d117_predictor_8x8_neon, - vpx_d153_predictor_8x8_neon, vpx_d207_predictor_8x8_neon, - vpx_d63_predictor_8x8_neon, vpx_tm_predictor_8x8_neon) -INTRA_PRED_TEST(NEON, TestIntraPred16, vpx_dc_predictor_16x16_neon, - vpx_dc_left_predictor_16x16_neon, - vpx_dc_top_predictor_16x16_neon, - vpx_dc_128_predictor_16x16_neon, vpx_v_predictor_16x16_neon, - vpx_h_predictor_16x16_neon, vpx_d45_predictor_16x16_neon, - vpx_d135_predictor_16x16_neon, vpx_d117_predictor_16x16_neon, - vpx_d153_predictor_16x16_neon, vpx_d207_predictor_16x16_neon, - vpx_d63_predictor_16x16_neon, vpx_tm_predictor_16x16_neon) -INTRA_PRED_TEST(NEON, TestIntraPred32, vpx_dc_predictor_32x32_neon, - vpx_dc_left_predictor_32x32_neon, - vpx_dc_top_predictor_32x32_neon, - vpx_dc_128_predictor_32x32_neon, vpx_v_predictor_32x32_neon, - vpx_h_predictor_32x32_neon, vpx_d45_predictor_32x32_neon, - vpx_d135_predictor_32x32_neon, vpx_d117_predictor_32x32_neon, - vpx_d153_predictor_32x32_neon, vpx_d207_predictor_32x32_neon, - vpx_d63_predictor_32x32_neon, vpx_tm_predictor_32x32_neon) -#endif // HAVE_NEON - -#if HAVE_MSA -INTRA_PRED_TEST(MSA, TestIntraPred4, vpx_dc_predictor_4x4_msa, - vpx_dc_left_predictor_4x4_msa, vpx_dc_top_predictor_4x4_msa, - vpx_dc_128_predictor_4x4_msa, vpx_v_predictor_4x4_msa, - vpx_h_predictor_4x4_msa, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, vpx_tm_predictor_4x4_msa) -INTRA_PRED_TEST(MSA, TestIntraPred8, vpx_dc_predictor_8x8_msa, - vpx_dc_left_predictor_8x8_msa, vpx_dc_top_predictor_8x8_msa, - vpx_dc_128_predictor_8x8_msa, vpx_v_predictor_8x8_msa, - vpx_h_predictor_8x8_msa, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, vpx_tm_predictor_8x8_msa) -INTRA_PRED_TEST(MSA, TestIntraPred16, vpx_dc_predictor_16x16_msa, - vpx_dc_left_predictor_16x16_msa, vpx_dc_top_predictor_16x16_msa, - vpx_dc_128_predictor_16x16_msa, vpx_v_predictor_16x16_msa, - vpx_h_predictor_16x16_msa, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, vpx_tm_predictor_16x16_msa) -INTRA_PRED_TEST(MSA, TestIntraPred32, vpx_dc_predictor_32x32_msa, - vpx_dc_left_predictor_32x32_msa, vpx_dc_top_predictor_32x32_msa, - vpx_dc_128_predictor_32x32_msa, vpx_v_predictor_32x32_msa, - vpx_h_predictor_32x32_msa, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, vpx_tm_predictor_32x32_msa) -#endif // HAVE_MSA - -#if HAVE_VSX -// TODO(crbug.com/webm/1522): Fix test failures. -#if 0 -INTRA_PRED_TEST(VSX, TestIntraPred4, nullptr, nullptr, nullptr, nullptr, - nullptr, vpx_h_predictor_4x4_vsx, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, vpx_tm_predictor_4x4_vsx) - -INTRA_PRED_TEST(VSX, TestIntraPred8, vpx_dc_predictor_8x8_vsx, nullptr, nullptr, - nullptr, nullptr, vpx_h_predictor_8x8_vsx, - vpx_d45_predictor_8x8_vsx, nullptr, nullptr, nullptr, nullptr, - vpx_d63_predictor_8x8_vsx, vpx_tm_predictor_8x8_vsx) -#endif - -INTRA_PRED_TEST(VSX, TestIntraPred16, vpx_dc_predictor_16x16_vsx, - vpx_dc_left_predictor_16x16_vsx, vpx_dc_top_predictor_16x16_vsx, - vpx_dc_128_predictor_16x16_vsx, vpx_v_predictor_16x16_vsx, - vpx_h_predictor_16x16_vsx, vpx_d45_predictor_16x16_vsx, nullptr, - nullptr, nullptr, nullptr, vpx_d63_predictor_16x16_vsx, - vpx_tm_predictor_16x16_vsx) - -INTRA_PRED_TEST(VSX, TestIntraPred32, vpx_dc_predictor_32x32_vsx, - vpx_dc_left_predictor_32x32_vsx, vpx_dc_top_predictor_32x32_vsx, - vpx_dc_128_predictor_32x32_vsx, vpx_v_predictor_32x32_vsx, - vpx_h_predictor_32x32_vsx, vpx_d45_predictor_32x32_vsx, nullptr, - nullptr, nullptr, nullptr, vpx_d63_predictor_32x32_vsx, - vpx_tm_predictor_32x32_vsx) -#endif // HAVE_VSX - -#if HAVE_LSX -INTRA_PRED_TEST(LSX, TestIntraPred8, vpx_dc_predictor_8x8_lsx, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr) -INTRA_PRED_TEST(LSX, TestIntraPred16, vpx_dc_predictor_16x16_lsx, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr) -#endif // HAVE_LSX - -// ----------------------------------------------------------------------------- - -#if CONFIG_VP9_HIGHBITDEPTH -namespace { - -typedef void (*VpxHighbdPredFunc)(uint16_t *dst, ptrdiff_t y_stride, - const uint16_t *above, const uint16_t *left, - int bd); - -typedef IntraPredTestMem Vp9HighbdIntraPredTestMem; - -void TestHighbdIntraPred(const char name[], VpxHighbdPredFunc const *pred_funcs, - const char *const signatures[], int block_size) { - const int kNumTests = static_cast( - 2.e10 / (block_size * block_size * kNumVp9IntraPredFuncs)); - Vp9HighbdIntraPredTestMem intra_pred_test_mem; - const uint16_t *const above = intra_pred_test_mem.above_mem + 16; - - intra_pred_test_mem.Init(block_size, 12); - - for (int k = 0; k < kNumVp9IntraPredFuncs; ++k) { - if (pred_funcs[k] == nullptr) continue; - memcpy(intra_pred_test_mem.src, intra_pred_test_mem.ref_src, - sizeof(intra_pred_test_mem.src)); - vpx_usec_timer timer; - vpx_usec_timer_start(&timer); - for (int num_tests = 0; num_tests < kNumTests; ++num_tests) { - pred_funcs[k](intra_pred_test_mem.src, kBPS, above, - intra_pred_test_mem.left, 12); - } - libvpx_test::ClearSystemState(); - vpx_usec_timer_mark(&timer); - const int elapsed_time = - static_cast(vpx_usec_timer_elapsed(&timer) / 1000); - CheckMd5Signature(name, signatures, intra_pred_test_mem.src, - sizeof(intra_pred_test_mem.src), elapsed_time, k); - } -} - -void TestHighbdIntraPred4(VpxHighbdPredFunc const *pred_funcs) { - static const char *const kSignatures[kNumVp9IntraPredFuncs] = { - "11f74af6c5737df472f3275cbde062fa", "51bea056b6447c93f6eb8f6b7e8f6f71", - "27e97f946766331795886f4de04c5594", "53ab15974b049111fb596c5168ec7e3f", - "f0b640bb176fbe4584cf3d32a9b0320a", "729783ca909e03afd4b47111c80d967b", - "fbf1c30793d9f32812e4d9f905d53530", "293fc903254a33754133314c6cdba81f", - "f8074d704233e73dfd35b458c6092374", "aa6363d08544a1ec4da33d7a0be5640d", - "462abcfdfa3d087bb33c9a88f2aec491", "863eab65d22550dd44a2397277c1ec71", - "23d61df1574d0fa308f9731811047c4b" - }; - TestHighbdIntraPred("Intra4", pred_funcs, kSignatures, 4); -} - -void TestHighbdIntraPred8(VpxHighbdPredFunc const *pred_funcs) { - static const char *const kSignatures[kNumVp9IntraPredFuncs] = { - "03da8829fe94663047fd108c5fcaa71d", "ecdb37b8120a2d3a4c706b016bd1bfd7", - "1d4543ed8d2b9368cb96898095fe8a75", "f791c9a67b913cbd82d9da8ecede30e2", - "065c70646f4dbaff913282f55a45a441", "51f87123616662ef7c35691497dfd0ba", - "2a5b0131ef4716f098ee65e6df01e3dd", "9ffe186a6bc7db95275f1bbddd6f7aba", - "a3258a2eae2e2bd55cb8f71351b22998", "8d909f0a2066e39b3216092c6289ece4", - "d183abb30b9f24c886a0517e991b22c7", "702a42fe4c7d665dc561b2aeeb60f311", - "7b5dbbbe7ae3a4ac2948731600bde5d6" - }; - TestHighbdIntraPred("Intra8", pred_funcs, kSignatures, 8); -} - -void TestHighbdIntraPred16(VpxHighbdPredFunc const *pred_funcs) { - static const char *const kSignatures[kNumVp9IntraPredFuncs] = { - "e33cb3f56a878e2fddb1b2fc51cdd275", "c7bff6f04b6052c8ab335d726dbbd52d", - "d0b0b47b654a9bcc5c6008110a44589b", "78f5da7b10b2b9ab39f114a33b6254e9", - "c78e31d23831abb40d6271a318fdd6f3", "90d1347f4ec9198a0320daecb6ff90b8", - "d2c623746cbb64a0c9e29c10f2c57041", "cf28bd387b81ad3e5f1a1c779a4b70a0", - "24c304330431ddeaf630f6ce94af2eac", "91a329798036bf64e8e00a87b131b8b1", - "d39111f22885307f920796a42084c872", "e2e702f7250ece98dd8f3f2854c31eeb", - "e2fb05b01eb8b88549e85641d8ce5b59" - }; - TestHighbdIntraPred("Intra16", pred_funcs, kSignatures, 16); -} - -void TestHighbdIntraPred32(VpxHighbdPredFunc const *pred_funcs) { - static const char *const kSignatures[kNumVp9IntraPredFuncs] = { - "a3e8056ba7e36628cce4917cd956fedd", "cc7d3024fe8748b512407edee045377e", - "2aab0a0f330a1d3e19b8ecb8f06387a3", "a547bc3fb7b06910bf3973122a426661", - "26f712514da95042f93d6e8dc8e431dc", "bb08c6e16177081daa3d936538dbc2e3", - "8f031af3e2650e89620d8d2c3a843d8b", "42867c8553285e94ee8e4df7abafbda8", - "6496bdee96100667833f546e1be3d640", "2ebfa25bf981377e682e580208504300", - "3e8ae52fd1f607f348aa4cb436c71ab7", "3d4efe797ca82193613696753ea624c4", - "cb8aab6d372278f3131e8d99efde02d9" - }; - TestHighbdIntraPred("Intra32", pred_funcs, kSignatures, 32); -} - -} // namespace - -// Defines a test case for |arch| (e.g., C, SSE2, ...) passing the predictors -// to |test_func|. The test name is 'arch.test_func', e.g., C.TestIntraPred4. -#define HIGHBD_INTRA_PRED_TEST(arch, test_func, dc, dc_left, dc_top, dc_128, \ - v, h, d45, d135, d117, d153, d207, d63, tm) \ - TEST(arch, test_func) { \ - static const VpxHighbdPredFunc vpx_intra_pred[] = { \ - dc, dc_left, dc_top, dc_128, v, h, d45, d135, d117, d153, d207, d63, tm \ - }; \ - test_func(vpx_intra_pred); \ - } - -// ----------------------------------------------------------------------------- - -HIGHBD_INTRA_PRED_TEST( - C, TestHighbdIntraPred4, vpx_highbd_dc_predictor_4x4_c, - vpx_highbd_dc_left_predictor_4x4_c, vpx_highbd_dc_top_predictor_4x4_c, - vpx_highbd_dc_128_predictor_4x4_c, vpx_highbd_v_predictor_4x4_c, - vpx_highbd_h_predictor_4x4_c, vpx_highbd_d45_predictor_4x4_c, - vpx_highbd_d135_predictor_4x4_c, vpx_highbd_d117_predictor_4x4_c, - vpx_highbd_d153_predictor_4x4_c, vpx_highbd_d207_predictor_4x4_c, - vpx_highbd_d63_predictor_4x4_c, vpx_highbd_tm_predictor_4x4_c) - -HIGHBD_INTRA_PRED_TEST( - C, TestHighbdIntraPred8, vpx_highbd_dc_predictor_8x8_c, - vpx_highbd_dc_left_predictor_8x8_c, vpx_highbd_dc_top_predictor_8x8_c, - vpx_highbd_dc_128_predictor_8x8_c, vpx_highbd_v_predictor_8x8_c, - vpx_highbd_h_predictor_8x8_c, vpx_highbd_d45_predictor_8x8_c, - vpx_highbd_d135_predictor_8x8_c, vpx_highbd_d117_predictor_8x8_c, - vpx_highbd_d153_predictor_8x8_c, vpx_highbd_d207_predictor_8x8_c, - vpx_highbd_d63_predictor_8x8_c, vpx_highbd_tm_predictor_8x8_c) - -HIGHBD_INTRA_PRED_TEST( - C, TestHighbdIntraPred16, vpx_highbd_dc_predictor_16x16_c, - vpx_highbd_dc_left_predictor_16x16_c, vpx_highbd_dc_top_predictor_16x16_c, - vpx_highbd_dc_128_predictor_16x16_c, vpx_highbd_v_predictor_16x16_c, - vpx_highbd_h_predictor_16x16_c, vpx_highbd_d45_predictor_16x16_c, - vpx_highbd_d135_predictor_16x16_c, vpx_highbd_d117_predictor_16x16_c, - vpx_highbd_d153_predictor_16x16_c, vpx_highbd_d207_predictor_16x16_c, - vpx_highbd_d63_predictor_16x16_c, vpx_highbd_tm_predictor_16x16_c) - -HIGHBD_INTRA_PRED_TEST( - C, TestHighbdIntraPred32, vpx_highbd_dc_predictor_32x32_c, - vpx_highbd_dc_left_predictor_32x32_c, vpx_highbd_dc_top_predictor_32x32_c, - vpx_highbd_dc_128_predictor_32x32_c, vpx_highbd_v_predictor_32x32_c, - vpx_highbd_h_predictor_32x32_c, vpx_highbd_d45_predictor_32x32_c, - vpx_highbd_d135_predictor_32x32_c, vpx_highbd_d117_predictor_32x32_c, - vpx_highbd_d153_predictor_32x32_c, vpx_highbd_d207_predictor_32x32_c, - vpx_highbd_d63_predictor_32x32_c, vpx_highbd_tm_predictor_32x32_c) - -#if HAVE_SSE2 -HIGHBD_INTRA_PRED_TEST( - SSE2, TestHighbdIntraPred4, vpx_highbd_dc_predictor_4x4_sse2, - vpx_highbd_dc_left_predictor_4x4_sse2, vpx_highbd_dc_top_predictor_4x4_sse2, - vpx_highbd_dc_128_predictor_4x4_sse2, vpx_highbd_v_predictor_4x4_sse2, - vpx_highbd_h_predictor_4x4_sse2, nullptr, - vpx_highbd_d135_predictor_4x4_sse2, vpx_highbd_d117_predictor_4x4_sse2, - vpx_highbd_d153_predictor_4x4_sse2, vpx_highbd_d207_predictor_4x4_sse2, - vpx_highbd_d63_predictor_4x4_sse2, vpx_highbd_tm_predictor_4x4_c) - -HIGHBD_INTRA_PRED_TEST( - SSE2, TestHighbdIntraPred8, vpx_highbd_dc_predictor_8x8_sse2, - vpx_highbd_dc_left_predictor_8x8_sse2, vpx_highbd_dc_top_predictor_8x8_sse2, - vpx_highbd_dc_128_predictor_8x8_sse2, vpx_highbd_v_predictor_8x8_sse2, - vpx_highbd_h_predictor_8x8_sse2, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, vpx_highbd_tm_predictor_8x8_sse2) - -HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred16, - vpx_highbd_dc_predictor_16x16_sse2, - vpx_highbd_dc_left_predictor_16x16_sse2, - vpx_highbd_dc_top_predictor_16x16_sse2, - vpx_highbd_dc_128_predictor_16x16_sse2, - vpx_highbd_v_predictor_16x16_sse2, - vpx_highbd_h_predictor_16x16_sse2, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - vpx_highbd_tm_predictor_16x16_sse2) - -HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred32, - vpx_highbd_dc_predictor_32x32_sse2, - vpx_highbd_dc_left_predictor_32x32_sse2, - vpx_highbd_dc_top_predictor_32x32_sse2, - vpx_highbd_dc_128_predictor_32x32_sse2, - vpx_highbd_v_predictor_32x32_sse2, - vpx_highbd_h_predictor_32x32_sse2, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - vpx_highbd_tm_predictor_32x32_sse2) -#endif // HAVE_SSE2 - -#if HAVE_SSSE3 -HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred4, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, - vpx_highbd_d45_predictor_4x4_ssse3, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr) -HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred8, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, - vpx_highbd_d45_predictor_8x8_ssse3, - vpx_highbd_d135_predictor_8x8_ssse3, - vpx_highbd_d117_predictor_8x8_ssse3, - vpx_highbd_d153_predictor_8x8_ssse3, - vpx_highbd_d207_predictor_8x8_ssse3, - vpx_highbd_d63_predictor_8x8_ssse3, nullptr) -HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred16, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, - vpx_highbd_d45_predictor_16x16_ssse3, - vpx_highbd_d135_predictor_16x16_ssse3, - vpx_highbd_d117_predictor_16x16_ssse3, - vpx_highbd_d153_predictor_16x16_ssse3, - vpx_highbd_d207_predictor_16x16_ssse3, - vpx_highbd_d63_predictor_16x16_ssse3, nullptr) -HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred32, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, - vpx_highbd_d45_predictor_32x32_ssse3, - vpx_highbd_d135_predictor_32x32_ssse3, - vpx_highbd_d117_predictor_32x32_ssse3, - vpx_highbd_d153_predictor_32x32_ssse3, - vpx_highbd_d207_predictor_32x32_ssse3, - vpx_highbd_d63_predictor_32x32_ssse3, nullptr) -#endif // HAVE_SSSE3 - -#if HAVE_NEON -HIGHBD_INTRA_PRED_TEST( - NEON, TestHighbdIntraPred4, vpx_highbd_dc_predictor_4x4_neon, - vpx_highbd_dc_left_predictor_4x4_neon, vpx_highbd_dc_top_predictor_4x4_neon, - vpx_highbd_dc_128_predictor_4x4_neon, vpx_highbd_v_predictor_4x4_neon, - vpx_highbd_h_predictor_4x4_neon, vpx_highbd_d45_predictor_4x4_neon, - vpx_highbd_d135_predictor_4x4_neon, vpx_highbd_d117_predictor_4x4_neon, - vpx_highbd_d153_predictor_4x4_neon, vpx_highbd_d207_predictor_4x4_neon, - vpx_highbd_d63_predictor_4x4_neon, vpx_highbd_tm_predictor_4x4_neon) -HIGHBD_INTRA_PRED_TEST( - NEON, TestHighbdIntraPred8, vpx_highbd_dc_predictor_8x8_neon, - vpx_highbd_dc_left_predictor_8x8_neon, vpx_highbd_dc_top_predictor_8x8_neon, - vpx_highbd_dc_128_predictor_8x8_neon, vpx_highbd_v_predictor_8x8_neon, - vpx_highbd_h_predictor_8x8_neon, vpx_highbd_d45_predictor_8x8_neon, - vpx_highbd_d135_predictor_8x8_neon, vpx_highbd_d117_predictor_8x8_neon, - vpx_highbd_d153_predictor_8x8_neon, vpx_highbd_d207_predictor_8x8_neon, - vpx_highbd_d63_predictor_8x8_neon, vpx_highbd_tm_predictor_8x8_neon) -HIGHBD_INTRA_PRED_TEST( - NEON, TestHighbdIntraPred16, vpx_highbd_dc_predictor_16x16_neon, - vpx_highbd_dc_left_predictor_16x16_neon, - vpx_highbd_dc_top_predictor_16x16_neon, - vpx_highbd_dc_128_predictor_16x16_neon, vpx_highbd_v_predictor_16x16_neon, - vpx_highbd_h_predictor_16x16_neon, vpx_highbd_d45_predictor_16x16_neon, - vpx_highbd_d135_predictor_16x16_neon, vpx_highbd_d117_predictor_16x16_neon, - vpx_highbd_d153_predictor_16x16_neon, vpx_highbd_d207_predictor_16x16_neon, - vpx_highbd_d63_predictor_16x16_neon, vpx_highbd_tm_predictor_16x16_neon) -HIGHBD_INTRA_PRED_TEST( - NEON, TestHighbdIntraPred32, vpx_highbd_dc_predictor_32x32_neon, - vpx_highbd_dc_left_predictor_32x32_neon, - vpx_highbd_dc_top_predictor_32x32_neon, - vpx_highbd_dc_128_predictor_32x32_neon, vpx_highbd_v_predictor_32x32_neon, - vpx_highbd_h_predictor_32x32_neon, vpx_highbd_d45_predictor_32x32_neon, - vpx_highbd_d135_predictor_32x32_neon, vpx_highbd_d117_predictor_32x32_neon, - vpx_highbd_d153_predictor_32x32_neon, vpx_highbd_d207_predictor_32x32_neon, - vpx_highbd_d63_predictor_32x32_neon, vpx_highbd_tm_predictor_32x32_neon) -#endif // HAVE_NEON - -#endif // CONFIG_VP9_HIGHBITDEPTH - -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - ::libvpx_test::init_vpx_test(); - return RUN_ALL_TESTS(); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/test/test_libvpx.cc b/presentation/src/main/cpp/third_party/libvpx/test/test_libvpx.cc deleted file mode 100644 index ba271023..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/test_libvpx.cc +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "gtest/gtest.h" -#include "test/init_vpx_test.h" - -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - ::libvpx_test::init_vpx_test(); - return RUN_ALL_TESTS(); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/test/test_rc_interface.cc b/presentation/src/main/cpp/third_party/libvpx/test/test_rc_interface.cc deleted file mode 100644 index 840a299f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/test_rc_interface.cc +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2021 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "gtest/gtest.h" - -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/test/test_vector_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/test_vector_test.cc deleted file mode 100644 index 8112ca05..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/test_vector_test.cc +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include -#include - -#include "gtest/gtest.h" -#include "../tools_common.h" -#include "./vpx_config.h" -#include "test/codec_factory.h" -#include "test/decode_test_driver.h" -#include "test/ivf_video_source.h" -#include "test/md5_helper.h" -#include "test/test_vectors.h" -#include "test/util.h" -#if CONFIG_WEBM_IO -#include "test/webm_video_source.h" -#endif -#include "vpx_mem/vpx_mem.h" - -namespace { - -const int kThreads = 0; -const int kMtMode = 1; -const int kFileName = 2; - -typedef std::tuple DecodeParam; - -class TestVectorTest : public ::libvpx_test::DecoderTest, - public ::libvpx_test::CodecTestWithParam { - protected: - TestVectorTest() : DecoderTest(GET_PARAM(0)), md5_file_(nullptr) { -#if CONFIG_VP9_DECODER - resize_clips_.insert(::libvpx_test::kVP9TestVectorsResize, - ::libvpx_test::kVP9TestVectorsResize + - ::libvpx_test::kNumVP9TestVectorsResize); -#endif - } - - ~TestVectorTest() override { - if (md5_file_) fclose(md5_file_); - } - - void OpenMD5File(const std::string &md5_file_name_) { - md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_); - ASSERT_NE(md5_file_, nullptr) - << "Md5 file open failed. Filename: " << md5_file_name_; - } - -#if CONFIG_VP9_DECODER - void PreDecodeFrameHook(const libvpx_test::CompressedVideoSource &video, - libvpx_test::Decoder *decoder) override { - if (video.frame_number() == 0 && mt_mode_ >= 0) { - if (mt_mode_ == 1) { - decoder->Control(VP9D_SET_LOOP_FILTER_OPT, 1); - decoder->Control(VP9D_SET_ROW_MT, 0); - } else if (mt_mode_ == 2) { - decoder->Control(VP9D_SET_LOOP_FILTER_OPT, 0); - decoder->Control(VP9D_SET_ROW_MT, 1); - } else { - decoder->Control(VP9D_SET_LOOP_FILTER_OPT, 0); - decoder->Control(VP9D_SET_ROW_MT, 0); - } - } - } -#endif - - void DecompressedFrameHook(const vpx_image_t &img, - const unsigned int frame_number) override { - ASSERT_NE(md5_file_, nullptr); - char expected_md5[33]; - char junk[128]; - - // Read correct md5 checksums. - const int res = fscanf(md5_file_, "%s %s", expected_md5, junk); - ASSERT_NE(res, EOF) << "Read md5 data failed"; - expected_md5[32] = '\0'; - - ::libvpx_test::MD5 md5_res; - md5_res.Add(&img); - const char *actual_md5 = md5_res.Get(); - - // Check md5 match. - ASSERT_STREQ(expected_md5, actual_md5) - << "Md5 checksums don't match: frame number = " << frame_number; - } - -#if CONFIG_VP9_DECODER - std::set resize_clips_; -#endif - int mt_mode_; - - private: - FILE *md5_file_; -}; - -// This test runs through the whole set of test vectors, and decodes them. -// The md5 checksums are computed for each frame in the video file. If md5 -// checksums match the correct md5 data, then the test is passed. Otherwise, -// the test failed. -TEST_P(TestVectorTest, MD5Match) { - const DecodeParam input = GET_PARAM(1); - const std::string filename = std::get(input); - vpx_codec_flags_t flags = 0; - vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t(); - char str[256]; - - cfg.threads = std::get(input); - mt_mode_ = std::get(input); - snprintf(str, sizeof(str) / sizeof(str[0]) - 1, - "file: %s threads: %d MT mode: %d", filename.c_str(), cfg.threads, - mt_mode_); - SCOPED_TRACE(str); - - // Open compressed video file. - std::unique_ptr video; - if (filename.substr(filename.length() - 3, 3) == "ivf") { - video.reset(new libvpx_test::IVFVideoSource(filename)); - } else if (filename.substr(filename.length() - 4, 4) == "webm") { -#if CONFIG_WEBM_IO - video.reset(new libvpx_test::WebMVideoSource(filename)); -#else - fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n", - filename.c_str()); - return; -#endif - } - ASSERT_NE(video.get(), nullptr); - video->Init(); - - // Construct md5 file name. - const std::string md5_filename = filename + ".md5"; - OpenMD5File(md5_filename); - - // Set decode config and flags. - set_cfg(cfg); - set_flags(flags); - - // Decode frame, and check the md5 matching. - ASSERT_NO_FATAL_FAILURE(RunLoop(video.get(), cfg)); -} - -#if CONFIG_VP8_DECODER -VP8_INSTANTIATE_TEST_SUITE( - TestVectorTest, - ::testing::Combine( - ::testing::Values(1), // Single thread. - ::testing::Values(-1), // LPF opt and Row MT is not applicable - ::testing::ValuesIn(libvpx_test::kVP8TestVectors, - libvpx_test::kVP8TestVectors + - libvpx_test::kNumVP8TestVectors))); - -// Test VP8 decode in with different numbers of threads. -INSTANTIATE_TEST_SUITE_P( - VP8MultiThreaded, TestVectorTest, - ::testing::Combine( - ::testing::Values( - static_cast(&libvpx_test::kVP8)), - ::testing::Combine( - ::testing::Range(2, 9), // With 2 ~ 8 threads. - ::testing::Values(-1), // LPF opt and Row MT is not applicable - ::testing::ValuesIn(libvpx_test::kVP8TestVectors, - libvpx_test::kVP8TestVectors + - libvpx_test::kNumVP8TestVectors)))); - -#endif // CONFIG_VP8_DECODER - -#if CONFIG_VP9_DECODER -VP9_INSTANTIATE_TEST_SUITE( - TestVectorTest, - ::testing::Combine( - ::testing::Values(1), // Single thread. - ::testing::Values(-1), // LPF opt and Row MT is not applicable - ::testing::ValuesIn(libvpx_test::kVP9TestVectors, - libvpx_test::kVP9TestVectors + - libvpx_test::kNumVP9TestVectors))); - -INSTANTIATE_TEST_SUITE_P( - VP9MultiThreaded, TestVectorTest, - ::testing::Combine( - ::testing::Values( - static_cast(&libvpx_test::kVP9)), - ::testing::Combine( - ::testing::Range(2, 9), // With 2 ~ 8 threads. - ::testing::Range(0, 3), // With multi threads modes 0 ~ 2 - // 0: LPF opt and Row MT disabled - // 1: LPF opt enabled - // 2: Row MT enabled - ::testing::ValuesIn(libvpx_test::kVP9TestVectors, - libvpx_test::kVP9TestVectors + - libvpx_test::kNumVP9TestVectors)))); -#endif -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/test_vectors.cc b/presentation/src/main/cpp/third_party/libvpx/test/test_vectors.cc deleted file mode 100644 index 954ff771..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/test_vectors.cc +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "test/test_vectors.h" -#include "vpx_config.h" - -namespace libvpx_test { - -#define NELEMENTS(x) static_cast(sizeof(x) / sizeof(x[0])) - -#if CONFIG_VP8_DECODER -const char *const kVP8TestVectors[] = { - "vp80-00-comprehensive-001.ivf", "vp80-00-comprehensive-002.ivf", - "vp80-00-comprehensive-003.ivf", "vp80-00-comprehensive-004.ivf", - "vp80-00-comprehensive-005.ivf", "vp80-00-comprehensive-006.ivf", - "vp80-00-comprehensive-007.ivf", "vp80-00-comprehensive-008.ivf", - "vp80-00-comprehensive-009.ivf", "vp80-00-comprehensive-010.ivf", - "vp80-00-comprehensive-011.ivf", "vp80-00-comprehensive-012.ivf", - "vp80-00-comprehensive-013.ivf", "vp80-00-comprehensive-014.ivf", - "vp80-00-comprehensive-015.ivf", "vp80-00-comprehensive-016.ivf", - "vp80-00-comprehensive-017.ivf", "vp80-00-comprehensive-018.ivf", - "vp80-01-intra-1400.ivf", "vp80-01-intra-1411.ivf", - "vp80-01-intra-1416.ivf", "vp80-01-intra-1417.ivf", - "vp80-02-inter-1402.ivf", "vp80-02-inter-1412.ivf", - "vp80-02-inter-1418.ivf", "vp80-02-inter-1424.ivf", - "vp80-03-segmentation-01.ivf", "vp80-03-segmentation-02.ivf", - "vp80-03-segmentation-03.ivf", "vp80-03-segmentation-04.ivf", - "vp80-03-segmentation-1401.ivf", "vp80-03-segmentation-1403.ivf", - "vp80-03-segmentation-1407.ivf", "vp80-03-segmentation-1408.ivf", - "vp80-03-segmentation-1409.ivf", "vp80-03-segmentation-1410.ivf", - "vp80-03-segmentation-1413.ivf", "vp80-03-segmentation-1414.ivf", - "vp80-03-segmentation-1415.ivf", "vp80-03-segmentation-1425.ivf", - "vp80-03-segmentation-1426.ivf", "vp80-03-segmentation-1427.ivf", - "vp80-03-segmentation-1432.ivf", "vp80-03-segmentation-1435.ivf", - "vp80-03-segmentation-1436.ivf", "vp80-03-segmentation-1437.ivf", - "vp80-03-segmentation-1441.ivf", "vp80-03-segmentation-1442.ivf", - "vp80-04-partitions-1404.ivf", "vp80-04-partitions-1405.ivf", - "vp80-04-partitions-1406.ivf", "vp80-05-sharpness-1428.ivf", - "vp80-05-sharpness-1429.ivf", "vp80-05-sharpness-1430.ivf", - "vp80-05-sharpness-1431.ivf", "vp80-05-sharpness-1433.ivf", - "vp80-05-sharpness-1434.ivf", "vp80-05-sharpness-1438.ivf", - "vp80-05-sharpness-1439.ivf", "vp80-05-sharpness-1440.ivf", - "vp80-05-sharpness-1443.ivf", "vp80-06-smallsize.ivf" -}; -const int kNumVP8TestVectors = NELEMENTS(kVP8TestVectors); -#endif // CONFIG_VP8_DECODER -#if CONFIG_VP9_DECODER -#define RESIZE_TEST_VECTORS \ - "vp90-2-21-resize_inter_320x180_5_1-2.webm", \ - "vp90-2-21-resize_inter_320x180_5_3-4.webm", \ - "vp90-2-21-resize_inter_320x180_7_1-2.webm", \ - "vp90-2-21-resize_inter_320x180_7_3-4.webm", \ - "vp90-2-21-resize_inter_320x240_5_1-2.webm", \ - "vp90-2-21-resize_inter_320x240_5_3-4.webm", \ - "vp90-2-21-resize_inter_320x240_7_1-2.webm", \ - "vp90-2-21-resize_inter_320x240_7_3-4.webm", \ - "vp90-2-21-resize_inter_640x360_5_1-2.webm", \ - "vp90-2-21-resize_inter_640x360_5_3-4.webm", \ - "vp90-2-21-resize_inter_640x360_7_1-2.webm", \ - "vp90-2-21-resize_inter_640x360_7_3-4.webm", \ - "vp90-2-21-resize_inter_640x480_5_1-2.webm", \ - "vp90-2-21-resize_inter_640x480_5_3-4.webm", \ - "vp90-2-21-resize_inter_640x480_7_1-2.webm", \ - "vp90-2-21-resize_inter_640x480_7_3-4.webm", \ - "vp90-2-21-resize_inter_1280x720_5_1-2.webm", \ - "vp90-2-21-resize_inter_1280x720_5_3-4.webm", \ - "vp90-2-21-resize_inter_1280x720_7_1-2.webm", \ - "vp90-2-21-resize_inter_1280x720_7_3-4.webm", \ - "vp90-2-21-resize_inter_1920x1080_5_1-2.webm", \ - "vp90-2-21-resize_inter_1920x1080_5_3-4.webm", \ - "vp90-2-21-resize_inter_1920x1080_7_1-2.webm", \ - "vp90-2-21-resize_inter_1920x1080_7_3-4.webm", - -const char *const kVP9TestVectors[] = { - "vp90-2-00-quantizer-00.webm", - "vp90-2-00-quantizer-01.webm", - "vp90-2-00-quantizer-02.webm", - "vp90-2-00-quantizer-03.webm", - "vp90-2-00-quantizer-04.webm", - "vp90-2-00-quantizer-05.webm", - "vp90-2-00-quantizer-06.webm", - "vp90-2-00-quantizer-07.webm", - "vp90-2-00-quantizer-08.webm", - "vp90-2-00-quantizer-09.webm", - "vp90-2-00-quantizer-10.webm", - "vp90-2-00-quantizer-11.webm", - "vp90-2-00-quantizer-12.webm", - "vp90-2-00-quantizer-13.webm", - "vp90-2-00-quantizer-14.webm", - "vp90-2-00-quantizer-15.webm", - "vp90-2-00-quantizer-16.webm", - "vp90-2-00-quantizer-17.webm", - "vp90-2-00-quantizer-18.webm", - "vp90-2-00-quantizer-19.webm", - "vp90-2-00-quantizer-20.webm", - "vp90-2-00-quantizer-21.webm", - "vp90-2-00-quantizer-22.webm", - "vp90-2-00-quantizer-23.webm", - "vp90-2-00-quantizer-24.webm", - "vp90-2-00-quantizer-25.webm", - "vp90-2-00-quantizer-26.webm", - "vp90-2-00-quantizer-27.webm", - "vp90-2-00-quantizer-28.webm", - "vp90-2-00-quantizer-29.webm", - "vp90-2-00-quantizer-30.webm", - "vp90-2-00-quantizer-31.webm", - "vp90-2-00-quantizer-32.webm", - "vp90-2-00-quantizer-33.webm", - "vp90-2-00-quantizer-34.webm", - "vp90-2-00-quantizer-35.webm", - "vp90-2-00-quantizer-36.webm", - "vp90-2-00-quantizer-37.webm", - "vp90-2-00-quantizer-38.webm", - "vp90-2-00-quantizer-39.webm", - "vp90-2-00-quantizer-40.webm", - "vp90-2-00-quantizer-41.webm", - "vp90-2-00-quantizer-42.webm", - "vp90-2-00-quantizer-43.webm", - "vp90-2-00-quantizer-44.webm", - "vp90-2-00-quantizer-45.webm", - "vp90-2-00-quantizer-46.webm", - "vp90-2-00-quantizer-47.webm", - "vp90-2-00-quantizer-48.webm", - "vp90-2-00-quantizer-49.webm", - "vp90-2-00-quantizer-50.webm", - "vp90-2-00-quantizer-51.webm", - "vp90-2-00-quantizer-52.webm", - "vp90-2-00-quantizer-53.webm", - "vp90-2-00-quantizer-54.webm", - "vp90-2-00-quantizer-55.webm", - "vp90-2-00-quantizer-56.webm", - "vp90-2-00-quantizer-57.webm", - "vp90-2-00-quantizer-58.webm", - "vp90-2-00-quantizer-59.webm", - "vp90-2-00-quantizer-60.webm", - "vp90-2-00-quantizer-61.webm", - "vp90-2-00-quantizer-62.webm", - "vp90-2-00-quantizer-63.webm", - "vp90-2-01-sharpness-1.webm", - "vp90-2-01-sharpness-2.webm", - "vp90-2-01-sharpness-3.webm", - "vp90-2-01-sharpness-4.webm", - "vp90-2-01-sharpness-5.webm", - "vp90-2-01-sharpness-6.webm", - "vp90-2-01-sharpness-7.webm", - "vp90-2-02-size-08x08.webm", - "vp90-2-02-size-08x10.webm", - "vp90-2-02-size-08x16.webm", - "vp90-2-02-size-08x18.webm", - "vp90-2-02-size-08x32.webm", - "vp90-2-02-size-08x34.webm", - "vp90-2-02-size-08x64.webm", - "vp90-2-02-size-08x66.webm", - "vp90-2-02-size-10x08.webm", - "vp90-2-02-size-10x10.webm", - "vp90-2-02-size-10x16.webm", - "vp90-2-02-size-10x18.webm", - "vp90-2-02-size-10x32.webm", - "vp90-2-02-size-10x34.webm", - "vp90-2-02-size-10x64.webm", - "vp90-2-02-size-10x66.webm", - "vp90-2-02-size-16x08.webm", - "vp90-2-02-size-16x10.webm", - "vp90-2-02-size-16x16.webm", - "vp90-2-02-size-16x18.webm", - "vp90-2-02-size-16x32.webm", - "vp90-2-02-size-16x34.webm", - "vp90-2-02-size-16x64.webm", - "vp90-2-02-size-16x66.webm", - "vp90-2-02-size-18x08.webm", - "vp90-2-02-size-18x10.webm", - "vp90-2-02-size-18x16.webm", - "vp90-2-02-size-18x18.webm", - "vp90-2-02-size-18x32.webm", - "vp90-2-02-size-18x34.webm", - "vp90-2-02-size-18x64.webm", - "vp90-2-02-size-18x66.webm", - "vp90-2-02-size-32x08.webm", - "vp90-2-02-size-32x10.webm", - "vp90-2-02-size-32x16.webm", - "vp90-2-02-size-32x18.webm", - "vp90-2-02-size-32x32.webm", - "vp90-2-02-size-32x34.webm", - "vp90-2-02-size-32x64.webm", - "vp90-2-02-size-32x66.webm", - "vp90-2-02-size-34x08.webm", - "vp90-2-02-size-34x10.webm", - "vp90-2-02-size-34x16.webm", - "vp90-2-02-size-34x18.webm", - "vp90-2-02-size-34x32.webm", - "vp90-2-02-size-34x34.webm", - "vp90-2-02-size-34x64.webm", - "vp90-2-02-size-34x66.webm", - "vp90-2-02-size-64x08.webm", - "vp90-2-02-size-64x10.webm", - "vp90-2-02-size-64x16.webm", - "vp90-2-02-size-64x18.webm", - "vp90-2-02-size-64x32.webm", - "vp90-2-02-size-64x34.webm", - "vp90-2-02-size-64x64.webm", - "vp90-2-02-size-64x66.webm", - "vp90-2-02-size-66x08.webm", - "vp90-2-02-size-66x10.webm", - "vp90-2-02-size-66x16.webm", - "vp90-2-02-size-66x18.webm", - "vp90-2-02-size-66x32.webm", - "vp90-2-02-size-66x34.webm", - "vp90-2-02-size-66x64.webm", - "vp90-2-02-size-66x66.webm", - "vp90-2-02-size-130x132.webm", - "vp90-2-02-size-132x130.webm", - "vp90-2-02-size-132x132.webm", - "vp90-2-02-size-178x180.webm", - "vp90-2-02-size-180x178.webm", - "vp90-2-02-size-180x180.webm", - "vp90-2-03-size-196x196.webm", - "vp90-2-03-size-196x198.webm", - "vp90-2-03-size-196x200.webm", - "vp90-2-03-size-196x202.webm", - "vp90-2-03-size-196x208.webm", - "vp90-2-03-size-196x210.webm", - "vp90-2-03-size-196x224.webm", - "vp90-2-03-size-196x226.webm", - "vp90-2-03-size-198x196.webm", - "vp90-2-03-size-198x198.webm", - "vp90-2-03-size-198x200.webm", - "vp90-2-03-size-198x202.webm", - "vp90-2-03-size-198x208.webm", - "vp90-2-03-size-198x210.webm", - "vp90-2-03-size-198x224.webm", - "vp90-2-03-size-198x226.webm", - "vp90-2-03-size-200x196.webm", - "vp90-2-03-size-200x198.webm", - "vp90-2-03-size-200x200.webm", - "vp90-2-03-size-200x202.webm", - "vp90-2-03-size-200x208.webm", - "vp90-2-03-size-200x210.webm", - "vp90-2-03-size-200x224.webm", - "vp90-2-03-size-200x226.webm", - "vp90-2-03-size-202x196.webm", - "vp90-2-03-size-202x198.webm", - "vp90-2-03-size-202x200.webm", - "vp90-2-03-size-202x202.webm", - "vp90-2-03-size-202x208.webm", - "vp90-2-03-size-202x210.webm", - "vp90-2-03-size-202x224.webm", - "vp90-2-03-size-202x226.webm", - "vp90-2-03-size-208x196.webm", - "vp90-2-03-size-208x198.webm", - "vp90-2-03-size-208x200.webm", - "vp90-2-03-size-208x202.webm", - "vp90-2-03-size-208x208.webm", - "vp90-2-03-size-208x210.webm", - "vp90-2-03-size-208x224.webm", - "vp90-2-03-size-208x226.webm", - "vp90-2-03-size-210x196.webm", - "vp90-2-03-size-210x198.webm", - "vp90-2-03-size-210x200.webm", - "vp90-2-03-size-210x202.webm", - "vp90-2-03-size-210x208.webm", - "vp90-2-03-size-210x210.webm", - "vp90-2-03-size-210x224.webm", - "vp90-2-03-size-210x226.webm", - "vp90-2-03-size-224x196.webm", - "vp90-2-03-size-224x198.webm", - "vp90-2-03-size-224x200.webm", - "vp90-2-03-size-224x202.webm", - "vp90-2-03-size-224x208.webm", - "vp90-2-03-size-224x210.webm", - "vp90-2-03-size-224x224.webm", - "vp90-2-03-size-224x226.webm", - "vp90-2-03-size-226x196.webm", - "vp90-2-03-size-226x198.webm", - "vp90-2-03-size-226x200.webm", - "vp90-2-03-size-226x202.webm", - "vp90-2-03-size-226x208.webm", - "vp90-2-03-size-226x210.webm", - "vp90-2-03-size-226x224.webm", - "vp90-2-03-size-226x226.webm", - "vp90-2-03-size-352x288.webm", - "vp90-2-03-deltaq.webm", - "vp90-2-05-resize.ivf", - "vp90-2-06-bilinear.webm", - "vp90-2-07-frame_parallel.webm", - "vp90-2-08-tile_1x2_frame_parallel.webm", - "vp90-2-08-tile_1x2.webm", - "vp90-2-08-tile_1x4_frame_parallel.webm", - "vp90-2-08-tile_1x4.webm", - "vp90-2-08-tile_1x8_frame_parallel.webm", - "vp90-2-08-tile_1x8.webm", - "vp90-2-08-tile-4x4.webm", - "vp90-2-08-tile-4x1.webm", - "vp90-2-09-subpixel-00.ivf", - "vp90-2-02-size-lf-1920x1080.webm", - "vp90-2-09-aq2.webm", - "vp90-2-09-lf_deltas.webm", - "vp90-2-10-show-existing-frame.webm", - "vp90-2-10-show-existing-frame2.webm", - "vp90-2-11-size-351x287.webm", - "vp90-2-11-size-351x288.webm", - "vp90-2-11-size-352x287.webm", - "vp90-2-12-droppable_1.ivf", - "vp90-2-12-droppable_2.ivf", - "vp90-2-12-droppable_3.ivf", -#if !CONFIG_SIZE_LIMIT || \ - (DECODE_WIDTH_LIMIT >= 20400 && DECODE_HEIGHT_LIMIT >= 120) - "vp90-2-13-largescaling.webm", -#endif - "vp90-2-14-resize-fp-tiles-1-16.webm", - "vp90-2-14-resize-fp-tiles-1-2-4-8-16.webm", - "vp90-2-14-resize-fp-tiles-1-2.webm", - "vp90-2-14-resize-fp-tiles-1-4.webm", - "vp90-2-14-resize-fp-tiles-16-1.webm", - "vp90-2-14-resize-fp-tiles-16-2.webm", - "vp90-2-14-resize-fp-tiles-16-4.webm", - "vp90-2-14-resize-fp-tiles-16-8-4-2-1.webm", - "vp90-2-14-resize-fp-tiles-16-8.webm", - "vp90-2-14-resize-fp-tiles-1-8.webm", - "vp90-2-14-resize-fp-tiles-2-16.webm", - "vp90-2-14-resize-fp-tiles-2-1.webm", - "vp90-2-14-resize-fp-tiles-2-4.webm", - "vp90-2-14-resize-fp-tiles-2-8.webm", - "vp90-2-14-resize-fp-tiles-4-16.webm", - "vp90-2-14-resize-fp-tiles-4-1.webm", - "vp90-2-14-resize-fp-tiles-4-2.webm", - "vp90-2-14-resize-fp-tiles-4-8.webm", - "vp90-2-14-resize-fp-tiles-8-16.webm", - "vp90-2-14-resize-fp-tiles-8-1.webm", - "vp90-2-14-resize-fp-tiles-8-2.webm", - "vp90-2-14-resize-fp-tiles-8-4.webm", - "vp90-2-14-resize-10frames-fp-tiles-1-2-4-8.webm", - "vp90-2-14-resize-10frames-fp-tiles-1-2.webm", - "vp90-2-14-resize-10frames-fp-tiles-1-4.webm", - "vp90-2-14-resize-10frames-fp-tiles-1-8.webm", - "vp90-2-14-resize-10frames-fp-tiles-2-1.webm", - "vp90-2-14-resize-10frames-fp-tiles-2-4.webm", - "vp90-2-14-resize-10frames-fp-tiles-2-8.webm", - "vp90-2-14-resize-10frames-fp-tiles-4-1.webm", - "vp90-2-14-resize-10frames-fp-tiles-4-2.webm", - "vp90-2-14-resize-10frames-fp-tiles-4-8.webm", - "vp90-2-14-resize-10frames-fp-tiles-8-1.webm", - "vp90-2-14-resize-10frames-fp-tiles-8-2.webm", - "vp90-2-14-resize-10frames-fp-tiles-8-4-2-1.webm", - "vp90-2-14-resize-10frames-fp-tiles-8-4.webm", - "vp90-2-15-segkey.webm", - "vp90-2-15-segkey_adpq.webm", - "vp90-2-16-intra-only.webm", - "vp90-2-17-show-existing-frame.webm", - "vp90-2-18-resize.ivf", - "vp90-2-19-skip.webm", - "vp90-2-19-skip-01.webm", - "vp90-2-19-skip-02.webm", - "vp91-2-04-yuv444.webm", - "vp91-2-04-yuv422.webm", - "vp91-2-04-yuv440.webm", -#if CONFIG_VP9_HIGHBITDEPTH - "vp92-2-20-10bit-yuv420.webm", - "vp92-2-20-12bit-yuv420.webm", - "vp93-2-20-10bit-yuv422.webm", - "vp93-2-20-12bit-yuv422.webm", - "vp93-2-20-10bit-yuv440.webm", - "vp93-2-20-12bit-yuv440.webm", - "vp93-2-20-10bit-yuv444.webm", - "vp93-2-20-12bit-yuv444.webm", -#endif // CONFIG_VP9_HIGHBITDEPTH - "vp90-2-20-big_superframe-01.webm", - "vp90-2-20-big_superframe-02.webm", - "vp90-2-22-svc_1280x720_1.webm", - RESIZE_TEST_VECTORS -}; -const char *const kVP9TestVectorsSvc[] = { "vp90-2-22-svc_1280x720_3.ivf" }; -const int kNumVP9TestVectors = NELEMENTS(kVP9TestVectors); -const int kNumVP9TestVectorsSvc = NELEMENTS(kVP9TestVectorsSvc); -const char *const kVP9TestVectorsResize[] = { RESIZE_TEST_VECTORS }; -const int kNumVP9TestVectorsResize = NELEMENTS(kVP9TestVectorsResize); -#undef RESIZE_TEST_VECTORS -#endif // CONFIG_VP9_DECODER - -} // namespace libvpx_test diff --git a/presentation/src/main/cpp/third_party/libvpx/test/test_vectors.h b/presentation/src/main/cpp/third_party/libvpx/test/test_vectors.h deleted file mode 100644 index 0a4be0f1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/test_vectors.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_TEST_TEST_VECTORS_H_ -#define VPX_TEST_TEST_VECTORS_H_ - -#include "./vpx_config.h" - -namespace libvpx_test { - -#if CONFIG_VP8_DECODER -extern const int kNumVP8TestVectors; -extern const char *const kVP8TestVectors[]; -#endif - -#if CONFIG_VP9_DECODER -extern const int kNumVP9TestVectors; -extern const char *const kVP9TestVectors[]; -extern const int kNumVP9TestVectorsSvc; -extern const char *const kVP9TestVectorsSvc[]; -extern const int kNumVP9TestVectorsResize; -extern const char *const kVP9TestVectorsResize[]; -#endif // CONFIG_VP9_DECODER - -} // namespace libvpx_test - -#endif // VPX_TEST_TEST_VECTORS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/tile_independence_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/tile_independence_test.cc deleted file mode 100644 index 6bf20357..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/tile_independence_test.cc +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/md5_helper.h" -#include "test/util.h" -#include "vpx_mem/vpx_mem.h" - -namespace { -class TileIndependenceTest : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWithParam { - protected: - TileIndependenceTest() - : EncoderTest(GET_PARAM(0)), md5_fw_order_(), md5_inv_order_(), - n_tiles_(GET_PARAM(1)) { - init_flags_ = VPX_CODEC_USE_PSNR; - vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t(); - cfg.w = 704; - cfg.h = 144; - cfg.threads = 1; - fw_dec_ = codec_->CreateDecoder(cfg, 0); - inv_dec_ = codec_->CreateDecoder(cfg, 0); - inv_dec_->Control(VP9_INVERT_TILE_DECODE_ORDER, 1); - } - - ~TileIndependenceTest() override { - delete fw_dec_; - delete inv_dec_; - } - - void SetUp() override { - InitializeConfig(); - SetMode(libvpx_test::kTwoPassGood); - } - - void PreEncodeFrameHook(libvpx_test::VideoSource *video, - libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP9E_SET_TILE_COLUMNS, n_tiles_); - } - } - - void UpdateMD5(::libvpx_test::Decoder *dec, const vpx_codec_cx_pkt_t *pkt, - ::libvpx_test::MD5 *md5) { - const vpx_codec_err_t res = dec->DecodeFrame( - reinterpret_cast(pkt->data.frame.buf), pkt->data.frame.sz); - if (res != VPX_CODEC_OK) { - abort_ = true; - ASSERT_EQ(VPX_CODEC_OK, res); - } - const vpx_image_t *img = dec->GetDxData().Next(); - md5->Add(img); - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - UpdateMD5(fw_dec_, pkt, &md5_fw_order_); - UpdateMD5(inv_dec_, pkt, &md5_inv_order_); - } - - ::libvpx_test::MD5 md5_fw_order_, md5_inv_order_; - ::libvpx_test::Decoder *fw_dec_, *inv_dec_; - - private: - int n_tiles_; -}; - -// run an encode with 2 or 4 tiles, and do the decode both in normal and -// inverted tile ordering. Ensure that the MD5 of the output in both cases -// is identical. If so, tiles are considered independent and the test passes. -TEST_P(TileIndependenceTest, MD5Match) { - const vpx_rational timebase = { 33333333, 1000000000 }; - cfg_.g_timebase = timebase; - cfg_.rc_target_bitrate = 500; - cfg_.g_lag_in_frames = 25; - cfg_.rc_end_usage = VPX_VBR; - - libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 704, 144, - timebase.den, timebase.num, 0, 30); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - const char *md5_fw_str = md5_fw_order_.Get(); - const char *md5_inv_str = md5_inv_order_.Get(); - - // could use ASSERT_EQ(!memcmp(.., .., 16) here, but this gives nicer - // output if it fails. Not sure if it's helpful since it's really just - // a MD5... - ASSERT_STREQ(md5_fw_str, md5_inv_str); -} - -VP9_INSTANTIATE_TEST_SUITE(TileIndependenceTest, ::testing::Range(0, 2, 1)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/timestamp_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/timestamp_test.cc deleted file mode 100644 index 3567824d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/timestamp_test.cc +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2019 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/util.h" -#include "test/video_source.h" -#include "vpx_config.h" - -namespace { - -const int kVideoSourceWidth = 320; -const int kVideoSourceHeight = 240; -const int kFramesToEncode = 3; - -// A video source that exposes functions to set the timebase, framerate and -// starting pts. -class DummyTimebaseVideoSource : public ::libvpx_test::DummyVideoSource { - public: - // Parameters num and den set the timebase for the video source. - DummyTimebaseVideoSource(int num, int den) - : timebase_({ num, den }), framerate_numerator_(30), - framerate_denominator_(1), starting_pts_(0) { - SetSize(kVideoSourceWidth, kVideoSourceHeight); - set_limit(kFramesToEncode); - } - - void SetFramerate(int numerator, int denominator) { - framerate_numerator_ = numerator; - framerate_denominator_ = denominator; - } - - // Returns one frames duration in timebase units as a double. - double FrameDuration() const { - return (static_cast(timebase_.den) / timebase_.num) / - (static_cast(framerate_numerator_) / framerate_denominator_); - } - - vpx_codec_pts_t pts() const override { - return static_cast(frame_ * FrameDuration() + - starting_pts_ + 0.5); - } - - unsigned long duration() const override { - return static_cast(FrameDuration() + 0.5); - } - - vpx_rational_t timebase() const override { return timebase_; } - - void set_starting_pts(int64_t starting_pts) { starting_pts_ = starting_pts; } - - private: - vpx_rational_t timebase_; - int framerate_numerator_; - int framerate_denominator_; - int64_t starting_pts_; -}; - -class TimestampTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWithParam { - protected: - TimestampTest() : EncoderTest(GET_PARAM(0)) {} - ~TimestampTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(GET_PARAM(1)); - } -}; - -// Tests encoding in millisecond timebase. -TEST_P(TimestampTest, EncodeFrames) { - DummyTimebaseVideoSource video(1, 1000); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -TEST_P(TimestampTest, TestMicrosecondTimebase) { - // Set the timebase to microseconds. - DummyTimebaseVideoSource video(1, 1000000); - video.set_limit(1); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -TEST_P(TimestampTest, TestVpxRollover) { - DummyTimebaseVideoSource video(1, 1000); - video.set_starting_pts(922337170351ll); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -#if CONFIG_REALTIME_ONLY -VP8_INSTANTIATE_TEST_SUITE(TimestampTest, - ::testing::Values(::libvpx_test::kRealTime)); -VP9_INSTANTIATE_TEST_SUITE(TimestampTest, - ::testing::Values(::libvpx_test::kRealTime)); -#else -VP8_INSTANTIATE_TEST_SUITE(TimestampTest, - ::testing::Values(::libvpx_test::kTwoPassGood)); -VP9_INSTANTIATE_TEST_SUITE(TimestampTest, - ::testing::Values(::libvpx_test::kTwoPassGood)); -#endif -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/tools_common.sh b/presentation/src/main/cpp/third_party/libvpx/test/tools_common.sh deleted file mode 100644 index d0dd24df..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/tools_common.sh +++ /dev/null @@ -1,447 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2014 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## This file contains shell code shared by test scripts for libvpx tools. - -# Use $VPX_TEST_TOOLS_COMMON_SH as a pseudo include guard. -if [ -z "${VPX_TEST_TOOLS_COMMON_SH}" ]; then -VPX_TEST_TOOLS_COMMON_SH=included - -set -e -devnull='> /dev/null 2>&1' -VPX_TEST_PREFIX="" - -elog() { - echo "$@" 1>&2 -} - -vlog() { - if [ "${VPX_TEST_VERBOSE_OUTPUT}" = "yes" ]; then - echo "$@" - fi -} - -# Sets $VPX_TOOL_TEST to the name specified by positional parameter one. -test_begin() { - VPX_TOOL_TEST="${1}" -} - -# Clears the VPX_TOOL_TEST variable after confirming that $VPX_TOOL_TEST matches -# positional parameter one. -test_end() { - if [ "$1" != "${VPX_TOOL_TEST}" ]; then - echo "FAIL completed test mismatch!." - echo " completed test: ${1}" - echo " active test: ${VPX_TOOL_TEST}." - return 1 - fi - VPX_TOOL_TEST='' -} - -# Echoes the target configuration being tested. -test_configuration_target() { - vpx_config_mk="${LIBVPX_CONFIG_PATH}/config.mk" - # Find the TOOLCHAIN line, split it using ':=' as the field separator, and - # print the last field to get the value. Then pipe the value to tr to consume - # any leading/trailing spaces while allowing tr to echo the output to stdout. - awk -F ':=' '/TOOLCHAIN/ { print $NF }' "${vpx_config_mk}" | tr -d ' ' -} - -# Trap function used for failure reports and tool output directory removal. -# When the contents of $VPX_TOOL_TEST do not match the string '', reports -# failure of test stored in $VPX_TOOL_TEST. -cleanup() { - if [ -n "${VPX_TOOL_TEST}" ] && [ "${VPX_TOOL_TEST}" != '' ]; then - echo "FAIL: $VPX_TOOL_TEST" - fi - if [ -n "${VPX_TEST_OUTPUT_DIR}" ] && [ -d "${VPX_TEST_OUTPUT_DIR}" ]; then - rm -rf "${VPX_TEST_OUTPUT_DIR}" - fi -} - -# Echoes the git hash portion of the VERSION_STRING variable defined in -# $LIBVPX_CONFIG_PATH/config.mk to stdout, or the version number string when -# no git hash is contained in VERSION_STRING. -config_hash() { - vpx_config_mk="${LIBVPX_CONFIG_PATH}/config.mk" - # Find VERSION_STRING line, split it with "-g" and print the last field to - # output the git hash to stdout. - vpx_version=$(awk -F -g '/VERSION_STRING/ {print $NF}' "${vpx_config_mk}") - # Handle two situations here: - # 1. The default case: $vpx_version is a git hash, so echo it unchanged. - # 2. When being run a non-dev tree, the -g portion is not present in the - # version string: It's only the version number. - # In this case $vpx_version is something like 'VERSION_STRING=v1.3.0', so - # we echo only what is after the '='. - echo "${vpx_version##*=}" -} - -# Echoes the short form of the current git hash. -current_hash() { - if git --version > /dev/null 2>&1; then - (cd "$(dirname "${0}")" - git rev-parse --short HEAD) - else - # Return the config hash if git is unavailable: Fail silently, git hashes - # are used only for warnings. - config_hash - fi -} - -# Echoes warnings to stdout when git hash in vpx_config.h does not match the -# current git hash. -check_git_hashes() { - hash_at_configure_time=$(config_hash) - hash_now=$(current_hash) - - if [ "${hash_at_configure_time}" != "${hash_now}" ]; then - echo "Warning: git hash has changed since last configure." - fi -} - -# $1 is the name of an environment variable containing a directory name to -# test. -test_env_var_dir() { - local dir=$(eval echo "\${$1}") - if [ ! -d "${dir}" ]; then - elog "'${dir}': No such directory" - elog "The $1 environment variable must be set to a valid directory." - return 1 - fi -} - -# This script requires that the LIBVPX_BIN_PATH, LIBVPX_CONFIG_PATH, and -# LIBVPX_TEST_DATA_PATH variables are in the environment: Confirm that -# the variables are set and that they all evaluate to directory paths. -verify_vpx_test_environment() { - test_env_var_dir "LIBVPX_BIN_PATH" \ - && test_env_var_dir "LIBVPX_CONFIG_PATH" \ - && test_env_var_dir "LIBVPX_TEST_DATA_PATH" -} - -# Greps vpx_config.h in LIBVPX_CONFIG_PATH for positional parameter one, which -# should be a LIBVPX preprocessor flag. Echoes yes to stdout when the feature -# is available. -vpx_config_option_enabled() { - vpx_config_option="${1}" - vpx_config_file="${LIBVPX_CONFIG_PATH}/vpx_config.h" - config_line=$(grep "${vpx_config_option}" "${vpx_config_file}") - if echo "${config_line}" | grep -E -q '1$'; then - echo yes - fi -} - -# Echoes yes when output of test_configuration_target() contains win32 or win64. -is_windows_target() { - if test_configuration_target \ - | grep -q -e win32 -e win64 > /dev/null 2>&1; then - echo yes - fi -} - -# Echoes path to $1 when it's executable and exists in ${LIBVPX_BIN_PATH}, or an -# empty string. Caller is responsible for testing the string once the function -# returns. -vpx_tool_path() { - local tool_name="$1" - local tool_path="${LIBVPX_BIN_PATH}/${tool_name}${VPX_TEST_EXE_SUFFIX}" - if [ ! -x "${tool_path}" ]; then - # Try one directory up: when running via examples.sh the tool could be in - # the parent directory of $LIBVPX_BIN_PATH. - tool_path="${LIBVPX_BIN_PATH}/../${tool_name}${VPX_TEST_EXE_SUFFIX}" - fi - - if [ ! -x "${tool_path}" ]; then - tool_path="" - fi - echo "${tool_path}" -} - -# Echoes yes to stdout when the file named by positional parameter one exists -# in LIBVPX_BIN_PATH, and is executable. -vpx_tool_available() { - local tool_name="$1" - local tool="${LIBVPX_BIN_PATH}/${tool_name}${VPX_TEST_EXE_SUFFIX}" - [ -x "${tool}" ] && echo yes -} - -# Echoes yes to stdout when vpx_config_option_enabled() reports yes for -# CONFIG_VP8_DECODER. -vp8_decode_available() { - [ "$(vpx_config_option_enabled CONFIG_VP8_DECODER)" = "yes" ] && echo yes -} - -# Echoes yes to stdout when vpx_config_option_enabled() reports yes for -# CONFIG_VP8_ENCODER. -vp8_encode_available() { - [ "$(vpx_config_option_enabled CONFIG_VP8_ENCODER)" = "yes" ] && echo yes -} - -# Echoes yes to stdout when vpx_config_option_enabled() reports yes for -# CONFIG_VP9_DECODER. -vp9_decode_available() { - [ "$(vpx_config_option_enabled CONFIG_VP9_DECODER)" = "yes" ] && echo yes -} - -# Echoes yes to stdout when vpx_config_option_enabled() reports yes for -# CONFIG_VP9_ENCODER. -vp9_encode_available() { - [ "$(vpx_config_option_enabled CONFIG_VP9_ENCODER)" = "yes" ] && echo yes -} - -# Echoes yes to stdout when vpx_config_option_enabled() reports yes for -# CONFIG_WEBM_IO. -webm_io_available() { - [ "$(vpx_config_option_enabled CONFIG_WEBM_IO)" = "yes" ] && echo yes -} - -# Filters strings from $1 using the filter specified by $2. Filter behavior -# depends on the presence of $3. When $3 is present, strings that match the -# filter are excluded. When $3 is omitted, strings matching the filter are -# included. -# The filtered result is echoed to stdout. -filter_strings() { - strings=${1} - filter=${2} - exclude=${3} - - if [ -n "${exclude}" ]; then - # When positional parameter three exists the caller wants to remove strings. - # Tell grep to invert matches using the -v argument. - exclude='-v' - else - unset exclude - fi - - if [ -n "${filter}" ]; then - for s in ${strings}; do - if echo "${s}" | grep -E -q ${exclude} "${filter}" > /dev/null 2>&1; then - filtered_strings="${filtered_strings} ${s}" - fi - done - else - filtered_strings="${strings}" - fi - echo "${filtered_strings}" -} - -# Runs user test functions passed via positional parameters one and two. -# Functions in positional parameter one are treated as environment verification -# functions and are run unconditionally. Functions in positional parameter two -# are run according to the rules specified in vpx_test_usage(). -run_tests() { - local env_tests="verify_vpx_test_environment $1" - local tests_to_filter="$2" - local test_name="${VPX_TEST_NAME}" - - if [ -z "${test_name}" ]; then - test_name="$(basename "${0%.*}")" - fi - - if [ "${VPX_TEST_RUN_DISABLED_TESTS}" != "yes" ]; then - # Filter out DISABLED tests. - tests_to_filter=$(filter_strings "${tests_to_filter}" ^DISABLED exclude) - fi - - if [ -n "${VPX_TEST_FILTER}" ]; then - # Remove tests not matching the user's filter. - tests_to_filter=$(filter_strings "${tests_to_filter}" ${VPX_TEST_FILTER}) - fi - - # User requested test listing: Dump test names and return. - if [ "${VPX_TEST_LIST_TESTS}" = "yes" ]; then - for test_name in $tests_to_filter; do - echo ${test_name} - done - return - fi - - # Don't bother with the environment tests if everything else was disabled. - [ -z "${tests_to_filter}" ] && return - - # Combine environment and actual tests. - local tests_to_run="${env_tests} ${tests_to_filter}" - - check_git_hashes - - # Run tests. - for test in ${tests_to_run}; do - test_begin "${test}" - vlog " RUN ${test}" - "${test}" - vlog " PASS ${test}" - test_end "${test}" - done - - # C vs SIMD tests are run for x86 32-bit, 64-bit and ARM platform - if [ "${test_name}" = "vp9_c_vs_simd_encode" ]; then - local tested_config="$(current_hash)" - else - local tested_config="$(test_configuration_target) @ $(current_hash)" - fi - echo "${test_name}: Done, all tests pass for ${tested_config}." -} - -vpx_test_usage() { -cat << EOF - Usage: ${0##*/} [arguments] - --bin-path - --config-path - --filter : User test filter. Only tests matching filter are run. - --run-disabled-tests: Run disabled tests. - --help: Display this message and exit. - --test-data-path - --show-program-output: Shows output from all programs being tested. - --prefix: Allows for a user specified prefix to be inserted before all test - programs. Grants the ability, for example, to run test programs - within valgrind. - --list-tests: List all test names and exit without actually running tests. - --verbose: Verbose output. - - When the --bin-path option is not specified the script attempts to use - \$LIBVPX_BIN_PATH and then the current directory. - - When the --config-path option is not specified the script attempts to use - \$LIBVPX_CONFIG_PATH and then the current directory. - - When the -test-data-path option is not specified the script attempts to use - \$LIBVPX_TEST_DATA_PATH and then the current directory. -EOF -} - -# Returns non-zero (failure) when required environment variables are empty -# strings. -vpx_test_check_environment() { - if [ -z "${LIBVPX_BIN_PATH}" ] || \ - [ -z "${LIBVPX_CONFIG_PATH}" ] || \ - [ -z "${LIBVPX_TEST_DATA_PATH}" ]; then - return 1 - fi -} - -# Parse the command line. -while [ -n "$1" ]; do - case "$1" in - --bin-path) - LIBVPX_BIN_PATH="$2" - shift - ;; - --config-path) - LIBVPX_CONFIG_PATH="$2" - shift - ;; - --filter) - VPX_TEST_FILTER="$2" - shift - ;; - --run-disabled-tests) - VPX_TEST_RUN_DISABLED_TESTS=yes - ;; - --help) - vpx_test_usage - exit - ;; - --test-data-path) - LIBVPX_TEST_DATA_PATH="$2" - shift - ;; - --prefix) - VPX_TEST_PREFIX="$2" - shift - ;; - --verbose) - VPX_TEST_VERBOSE_OUTPUT=yes - ;; - --show-program-output) - devnull= - ;; - --list-tests) - VPX_TEST_LIST_TESTS=yes - ;; - *) - vpx_test_usage - exit 1 - ;; - esac - shift -done - -# Handle running the tests from a build directory without arguments when running -# the tests on *nix/macosx. -LIBVPX_BIN_PATH="${LIBVPX_BIN_PATH:-.}" -LIBVPX_CONFIG_PATH="${LIBVPX_CONFIG_PATH:-.}" -LIBVPX_TEST_DATA_PATH="${LIBVPX_TEST_DATA_PATH:-.}" - -# Create a temporary directory for output files, and a trap to clean it up. -if [ -n "${TMPDIR}" ]; then - VPX_TEST_TEMP_ROOT="${TMPDIR}" -elif [ -n "${TEMPDIR}" ]; then - VPX_TEST_TEMP_ROOT="${TEMPDIR}" -else - VPX_TEST_TEMP_ROOT=/tmp -fi - -VPX_TEST_OUTPUT_DIR="${VPX_TEST_TEMP_ROOT}/vpx_test_$$" - -if ! mkdir -p "${VPX_TEST_OUTPUT_DIR}" || \ - [ ! -d "${VPX_TEST_OUTPUT_DIR}" ]; then - echo "${0##*/}: Cannot create output directory, giving up." - echo "${0##*/}: VPX_TEST_OUTPUT_DIR=${VPX_TEST_OUTPUT_DIR}" - exit 1 -fi - -if [ "$(is_windows_target)" = "yes" ]; then - VPX_TEST_EXE_SUFFIX=".exe" -fi - -# Variables shared by tests. -VP8_IVF_FILE="${LIBVPX_TEST_DATA_PATH}/vp80-00-comprehensive-001.ivf" -VP9_IVF_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-09-subpixel-00.ivf" - -VP9_WEBM_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-00-quantizer-00.webm" -VP9_FPM_WEBM_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-07-frame_parallel-1.webm" -VP9_LT_50_FRAMES_WEBM_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-02-size-32x08.webm" - -VP9_RAW_FILE="${LIBVPX_TEST_DATA_PATH}/crbug-1539.rawfile" - -YUV_RAW_INPUT="${LIBVPX_TEST_DATA_PATH}/hantro_collage_w352h288.yuv" -YUV_RAW_INPUT_WIDTH=352 -YUV_RAW_INPUT_HEIGHT=288 - -Y4M_NOSQ_PAR_INPUT="${LIBVPX_TEST_DATA_PATH}/park_joy_90p_8_420_a10-1.y4m" -Y4M_720P_INPUT="${LIBVPX_TEST_DATA_PATH}/niklas_1280_720_30.y4m" -Y4M_720P_INPUT_WIDTH=1280 -Y4M_720P_INPUT_HEIGHT=720 - -# Setup a trap function to clean up after tests complete. -trap cleanup EXIT - -vlog "$(basename "${0%.*}") test configuration: - LIBVPX_BIN_PATH=${LIBVPX_BIN_PATH} - LIBVPX_CONFIG_PATH=${LIBVPX_CONFIG_PATH} - LIBVPX_TEST_DATA_PATH=${LIBVPX_TEST_DATA_PATH} - VP8_IVF_FILE=${VP8_IVF_FILE} - VP9_IVF_FILE=${VP9_IVF_FILE} - VP9_WEBM_FILE=${VP9_WEBM_FILE} - VPX_TEST_EXE_SUFFIX=${VPX_TEST_EXE_SUFFIX} - VPX_TEST_FILTER=${VPX_TEST_FILTER} - VPX_TEST_LIST_TESTS=${VPX_TEST_LIST_TESTS} - VPX_TEST_OUTPUT_DIR=${VPX_TEST_OUTPUT_DIR} - VPX_TEST_PREFIX=${VPX_TEST_PREFIX} - VPX_TEST_RUN_DISABLED_TESTS=${VPX_TEST_RUN_DISABLED_TESTS} - VPX_TEST_SHOW_PROGRAM_OUTPUT=${VPX_TEST_SHOW_PROGRAM_OUTPUT} - VPX_TEST_TEMP_ROOT=${VPX_TEST_TEMP_ROOT} - VPX_TEST_VERBOSE_OUTPUT=${VPX_TEST_VERBOSE_OUTPUT} - YUV_RAW_INPUT=${YUV_RAW_INPUT} - YUV_RAW_INPUT_WIDTH=${YUV_RAW_INPUT_WIDTH} - YUV_RAW_INPUT_HEIGHT=${YUV_RAW_INPUT_HEIGHT} - Y4M_NOSQ_PAR_INPUT=${Y4M_NOSQ_PAR_INPUT}" - -fi # End $VPX_TEST_TOOLS_COMMON_SH pseudo include guard. diff --git a/presentation/src/main/cpp/third_party/libvpx/test/twopass_encoder.sh b/presentation/src/main/cpp/third_party/libvpx/test/twopass_encoder.sh deleted file mode 100644 index 69ecbacd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/twopass_encoder.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2014 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## This file tests the libvpx twopass_encoder example. To add new tests to this -## file, do the following: -## 1. Write a shell function (this is your test). -## 2. Add the function to twopass_encoder_tests (on a new line). -## -. $(dirname $0)/tools_common.sh - -# Environment check: $YUV_RAW_INPUT is required. -twopass_encoder_verify_environment() { - if [ ! -e "${YUV_RAW_INPUT}" ]; then - echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH." - return 1 - fi -} - -# Runs twopass_encoder using the codec specified by $1 with a frame limit of -# 100. -twopass_encoder() { - local encoder="${LIBVPX_BIN_PATH}/twopass_encoder${VPX_TEST_EXE_SUFFIX}" - local codec="$1" - local output_file="${VPX_TEST_OUTPUT_DIR}/twopass_encoder_${codec}.ivf" - - if [ ! -x "${encoder}" ]; then - elog "${encoder} does not exist or is not executable." - return 1 - fi - - eval "${VPX_TEST_PREFIX}" "${encoder}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \ - "${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" 100 \ - ${devnull} || return 1 - - [ -e "${output_file}" ] || return 1 -} - -twopass_encoder_vp8() { - if [ "$(vp8_encode_available)" = "yes" ]; then - twopass_encoder vp8 || return 1 - fi -} - -twopass_encoder_vp9() { - if [ "$(vp9_encode_available)" = "yes" ]; then - twopass_encoder vp9 || return 1 - fi -} - - -if [ "$(vpx_config_option_enabled CONFIG_REALTIME_ONLY)" != "yes" ]; then - twopass_encoder_tests="twopass_encoder_vp8 - twopass_encoder_vp9" - - run_tests twopass_encoder_verify_environment "${twopass_encoder_tests}" -fi diff --git a/presentation/src/main/cpp/third_party/libvpx/test/user_priv_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/user_priv_test.cc deleted file mode 100644 index 0f45b082..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/user_priv_test.cc +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include "gtest/gtest.h" -#include "./vpx_config.h" -#include "test/acm_random.h" -#include "test/codec_factory.h" -#include "test/decode_test_driver.h" -#include "test/ivf_video_source.h" -#include "test/md5_helper.h" -#include "test/util.h" -#if CONFIG_WEBM_IO -#include "test/webm_video_source.h" -#endif -#include "vpx_mem/vpx_mem.h" -#include "vpx/vp8.h" - -namespace { - -using libvpx_test::ACMRandom; -using std::string; - -#if CONFIG_WEBM_IO - -void CheckUserPrivateData(void *user_priv, int *target) { - // actual pointer value should be the same as expected. - EXPECT_EQ(reinterpret_cast(target), user_priv) - << "user_priv pointer value does not match."; -} - -// Decodes |filename|. Passes in user_priv data when calling DecodeFrame and -// compares the user_priv from return img with the original user_priv to see if -// they match. Both the pointer values and the values inside the addresses -// should match. -string DecodeFile(const string &filename) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - libvpx_test::WebMVideoSource video(filename); - video.Init(); - - vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t(); - libvpx_test::VP9Decoder decoder(cfg, 0); - - libvpx_test::MD5 md5; - int frame_num = 0; - for (video.Begin(); !::testing::Test::HasFailure() && video.cxdata(); - video.Next()) { - void *user_priv = reinterpret_cast(&frame_num); - const vpx_codec_err_t res = - decoder.DecodeFrame(video.cxdata(), video.frame_size(), - (frame_num == 0) ? nullptr : user_priv); - if (res != VPX_CODEC_OK) { - EXPECT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError(); - break; - } - libvpx_test::DxDataIterator dec_iter = decoder.GetDxData(); - const vpx_image_t *img = nullptr; - - // Get decompressed data. - while ((img = dec_iter.Next())) { - if (frame_num == 0) { - CheckUserPrivateData(img->user_priv, nullptr); - } else { - CheckUserPrivateData(img->user_priv, &frame_num); - - // Also test ctrl_get_reference api. - struct vp9_ref_frame ref = vp9_ref_frame(); - // Randomly fetch a reference frame. - ref.idx = rnd.Rand8() % 3; - decoder.Control(VP9_GET_REFERENCE, &ref); - - CheckUserPrivateData(ref.img.user_priv, nullptr); - } - md5.Add(img); - } - - frame_num++; - } - return string(md5.Get()); -} - -TEST(UserPrivTest, VideoDecode) { - // no tiles or frame parallel; this exercises the decoding to test the - // user_priv. - EXPECT_STREQ("b35a1b707b28e82be025d960aba039bc", - DecodeFile("vp90-2-03-size-226x226.webm").c_str()); -} - -#endif // CONFIG_WEBM_IO - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/util.h b/presentation/src/main/cpp/third_party/libvpx/test/util.h deleted file mode 100644 index 94bab664..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/util.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_TEST_UTIL_H_ -#define VPX_TEST_UTIL_H_ - -#include -#include -#include - -#include "gtest/gtest.h" -#include "vpx/vpx_image.h" - -// Macros -#define GET_PARAM(k) std::get(GetParam()) - -inline double compute_psnr(const vpx_image_t *img1, const vpx_image_t *img2) { - assert((img1->fmt == img2->fmt) && (img1->d_w == img2->d_w) && - (img1->d_h == img2->d_h)); - - const unsigned int width_y = img1->d_w; - const unsigned int height_y = img1->d_h; - unsigned int i, j; - - int64_t sqrerr = 0; - for (i = 0; i < height_y; ++i) { - for (j = 0; j < width_y; ++j) { - int64_t d = img1->planes[VPX_PLANE_Y][i * img1->stride[VPX_PLANE_Y] + j] - - img2->planes[VPX_PLANE_Y][i * img2->stride[VPX_PLANE_Y] + j]; - sqrerr += d * d; - } - } - double mse = static_cast(sqrerr) / (width_y * height_y); - double psnr = 100.0; - if (mse > 0.0) { - psnr = 10 * log10(255.0 * 255.0 / mse); - } - return psnr; -} - -#endif // VPX_TEST_UTIL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/variance_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/variance_test.cc deleted file mode 100644 index 660e412b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/variance_test.cc +++ /dev/null @@ -1,2214 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "gtest/gtest.h" - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "test/acm_random.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "vpx/vpx_codec.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/variance.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/vpx_timer.h" - -namespace { - -typedef unsigned int (*Get4x4SseFunc)(const uint8_t *a, int a_stride, - const uint8_t *b, int b_stride); -typedef void (*GetVarianceFunc)(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - uint32_t *sse, int *sum); -typedef unsigned int (*SumOfSquaresFunction)(const int16_t *src); - -using libvpx_test::ACMRandom; - -// Truncate high bit depth results by downshifting (with rounding) by: -// 2 * (bit_depth - 8) for sse -// (bit_depth - 8) for se -static void RoundHighBitDepth(int bit_depth, int64_t *se, uint64_t *sse) { - switch (bit_depth) { - case VPX_BITS_12: - *sse = (*sse + 128) >> 8; - *se = (*se + 8) >> 4; - break; - case VPX_BITS_10: - *sse = (*sse + 8) >> 4; - *se = (*se + 2) >> 2; - break; - case VPX_BITS_8: - default: break; - } -} - -static unsigned int mb_ss_ref(const int16_t *src) { - unsigned int res = 0; - for (int i = 0; i < 256; ++i) { - res += src[i] * src[i]; - } - return res; -} - -/* Note: - * Our codebase calculates the "diff" value in the variance algorithm by - * (src - ref). - */ -static void variance(const uint8_t *src, int src_stride, const uint8_t *ref, - int ref_stride, int w, int h, bool use_high_bit_depth_, - uint64_t *sse, int64_t *se, vpx_bit_depth_t bit_depth) { - int64_t se_long = 0; - uint64_t sse_long = 0; - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - int diff = 0; - if (!use_high_bit_depth_) { - diff = src[y * src_stride + x] - ref[y * ref_stride + x]; -#if CONFIG_VP9_HIGHBITDEPTH - } else { - diff = CONVERT_TO_SHORTPTR(src)[y * src_stride + x] - - CONVERT_TO_SHORTPTR(ref)[y * ref_stride + x]; -#endif // CONFIG_VP9_HIGHBITDEPTH - } - se_long += diff; - sse_long += diff * diff; - } - } - - RoundHighBitDepth(bit_depth, &se_long, &sse_long); - - *sse = sse_long; - *se = se_long; -} - -static void get_variance_ref(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, int l2w, - int l2h, bool use_high_bit_depth_, uint32_t *sse, - int *se, vpx_bit_depth_t bit_depth) { - const int w = 1 << l2w; - const int h = 1 << l2h; - int64_t se_long = 0; - uint64_t sse_long = 0; - - variance(src, src_stride, ref, ref_stride, w, h, use_high_bit_depth_, - &sse_long, &se_long, bit_depth); - - *sse = static_cast(sse_long); - *se = static_cast(se_long); -} - -static uint32_t variance_ref(const uint8_t *src, const uint8_t *ref, int l2w, - int l2h, int src_stride, int ref_stride, - uint32_t *sse_ptr, bool use_high_bit_depth_, - vpx_bit_depth_t bit_depth) { - const int w = 1 << l2w; - const int h = 1 << l2h; - int64_t se_long = 0; - uint64_t sse_long = 0; - - variance(src, src_stride, ref, ref_stride, w, h, use_high_bit_depth_, - &sse_long, &se_long, bit_depth); - - *sse_ptr = static_cast(sse_long); - return static_cast( - sse_long - ((static_cast(se_long) * se_long) >> (l2w + l2h))); -} - -/* The subpel reference functions differ from the codec version in one aspect: - * they calculate the bilinear factors directly instead of using a lookup table - * and therefore upshift xoff and yoff by 1. Only every other calculated value - * is used so the codec version shrinks the table to save space and maintain - * compatibility with vp8. - */ -static uint32_t subpel_variance_ref(const uint8_t *ref, const uint8_t *src, - int l2w, int l2h, int xoff, int yoff, - uint32_t *sse_ptr, bool use_high_bit_depth_, - vpx_bit_depth_t bit_depth) { - int64_t se = 0; - uint64_t sse = 0; - const int w = 1 << l2w; - const int h = 1 << l2h; - - xoff <<= 1; - yoff <<= 1; - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - // Bilinear interpolation at a 16th pel step. - if (!use_high_bit_depth_) { - const int a1 = ref[(w + 1) * (y + 0) + x + 0]; - const int a2 = ref[(w + 1) * (y + 0) + x + 1]; - const int b1 = ref[(w + 1) * (y + 1) + x + 0]; - const int b2 = ref[(w + 1) * (y + 1) + x + 1]; - const int a = a1 + (((a2 - a1) * xoff + 8) >> 4); - const int b = b1 + (((b2 - b1) * xoff + 8) >> 4); - const int r = a + (((b - a) * yoff + 8) >> 4); - const int diff = r - src[w * y + x]; - se += diff; - sse += diff * diff; -#if CONFIG_VP9_HIGHBITDEPTH - } else { - uint16_t *ref16 = CONVERT_TO_SHORTPTR(ref); - uint16_t *src16 = CONVERT_TO_SHORTPTR(src); - const int a1 = ref16[(w + 1) * (y + 0) + x + 0]; - const int a2 = ref16[(w + 1) * (y + 0) + x + 1]; - const int b1 = ref16[(w + 1) * (y + 1) + x + 0]; - const int b2 = ref16[(w + 1) * (y + 1) + x + 1]; - const int a = a1 + (((a2 - a1) * xoff + 8) >> 4); - const int b = b1 + (((b2 - b1) * xoff + 8) >> 4); - const int r = a + (((b - a) * yoff + 8) >> 4); - const int diff = r - src16[w * y + x]; - se += diff; - sse += diff * diff; -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - } - RoundHighBitDepth(bit_depth, &se, &sse); - *sse_ptr = static_cast(sse); - return static_cast( - sse - ((static_cast(se) * se) >> (l2w + l2h))); -} - -static uint32_t subpel_avg_variance_ref(const uint8_t *ref, const uint8_t *src, - const uint8_t *second_pred, int l2w, - int l2h, int xoff, int yoff, - uint32_t *sse_ptr, - bool use_high_bit_depth, - vpx_bit_depth_t bit_depth) { - int64_t se = 0; - uint64_t sse = 0; - const int w = 1 << l2w; - const int h = 1 << l2h; - - xoff <<= 1; - yoff <<= 1; - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - // bilinear interpolation at a 16th pel step - if (!use_high_bit_depth) { - const int a1 = ref[(w + 1) * (y + 0) + x + 0]; - const int a2 = ref[(w + 1) * (y + 0) + x + 1]; - const int b1 = ref[(w + 1) * (y + 1) + x + 0]; - const int b2 = ref[(w + 1) * (y + 1) + x + 1]; - const int a = a1 + (((a2 - a1) * xoff + 8) >> 4); - const int b = b1 + (((b2 - b1) * xoff + 8) >> 4); - const int r = a + (((b - a) * yoff + 8) >> 4); - const int diff = - ((r + second_pred[w * y + x] + 1) >> 1) - src[w * y + x]; - se += diff; - sse += diff * diff; -#if CONFIG_VP9_HIGHBITDEPTH - } else { - const uint16_t *ref16 = CONVERT_TO_SHORTPTR(ref); - const uint16_t *src16 = CONVERT_TO_SHORTPTR(src); - const uint16_t *sec16 = CONVERT_TO_SHORTPTR(second_pred); - const int a1 = ref16[(w + 1) * (y + 0) + x + 0]; - const int a2 = ref16[(w + 1) * (y + 0) + x + 1]; - const int b1 = ref16[(w + 1) * (y + 1) + x + 0]; - const int b2 = ref16[(w + 1) * (y + 1) + x + 1]; - const int a = a1 + (((a2 - a1) * xoff + 8) >> 4); - const int b = b1 + (((b2 - b1) * xoff + 8) >> 4); - const int r = a + (((b - a) * yoff + 8) >> 4); - const int diff = ((r + sec16[w * y + x] + 1) >> 1) - src16[w * y + x]; - se += diff; - sse += diff * diff; -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - } - RoundHighBitDepth(bit_depth, &se, &sse); - *sse_ptr = static_cast(sse); - return static_cast( - sse - ((static_cast(se) * se) >> (l2w + l2h))); -} - -//////////////////////////////////////////////////////////////////////////////// - -class SumOfSquaresTest : public ::testing::TestWithParam { - public: - SumOfSquaresTest() : func_(GetParam()) {} - - ~SumOfSquaresTest() override { libvpx_test::ClearSystemState(); } - - protected: - void ConstTest(); - void RefTest(); - - SumOfSquaresFunction func_; - ACMRandom rnd_; -}; - -void SumOfSquaresTest::ConstTest() { - int16_t mem[256]; - unsigned int res; - for (int v = 0; v < 256; ++v) { - for (int i = 0; i < 256; ++i) { - mem[i] = v; - } - ASM_REGISTER_STATE_CHECK(res = func_(mem)); - EXPECT_EQ(256u * (v * v), res); - } -} - -void SumOfSquaresTest::RefTest() { - int16_t mem[256]; - for (int i = 0; i < 100; ++i) { - for (int j = 0; j < 256; ++j) { - mem[j] = rnd_.Rand8() - rnd_.Rand8(); - } - - const unsigned int expected = mb_ss_ref(mem); - unsigned int res; - ASM_REGISTER_STATE_CHECK(res = func_(mem)); - EXPECT_EQ(expected, res); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Encapsulating struct to store the function to test along with -// some testing context. -// Can be used for MSE, SSE, Variance, etc. - -template -struct TestParams { - TestParams(int log2w = 0, int log2h = 0, Func function = nullptr, - int bit_depth_value = 0) - : log2width(log2w), log2height(log2h), func(function) { - use_high_bit_depth = (bit_depth_value > 0); - if (use_high_bit_depth) { - bit_depth = static_cast(bit_depth_value); - } else { - bit_depth = VPX_BITS_8; - } - width = 1 << log2width; - height = 1 << log2height; - block_size = width * height; - mask = (1u << bit_depth) - 1; - } - - int log2width, log2height; - int width, height; - int block_size; - Func func; - vpx_bit_depth_t bit_depth; - bool use_high_bit_depth; - uint32_t mask; -}; - -template -std::ostream &operator<<(std::ostream &os, const TestParams &p) { - return os << "log2width/height:" << p.log2width << "/" << p.log2height - << " function:" << reinterpret_cast(p.func) - << " bit-depth:" << p.bit_depth; -} - -// Main class for testing a function type -template -class MainTestClass - : public ::testing::TestWithParam > { - public: - void SetUp() override { - params_ = this->GetParam(); - - rnd_.Reset(ACMRandom::DeterministicSeed()); - const size_t unit = - use_high_bit_depth() ? sizeof(uint16_t) : sizeof(uint8_t); - src_ = reinterpret_cast(vpx_memalign(16, block_size() * unit)); - ref_ = new uint8_t[block_size() * unit]; - ASSERT_NE(src_, nullptr); - ASSERT_NE(ref_, nullptr); -#if CONFIG_VP9_HIGHBITDEPTH - if (use_high_bit_depth()) { - // TODO(skal): remove! - src_ = CONVERT_TO_BYTEPTR(src_); - ref_ = CONVERT_TO_BYTEPTR(ref_); - } -#endif - } - - void TearDown() override { -#if CONFIG_VP9_HIGHBITDEPTH - if (use_high_bit_depth()) { - // TODO(skal): remove! - src_ = reinterpret_cast(CONVERT_TO_SHORTPTR(src_)); - ref_ = reinterpret_cast(CONVERT_TO_SHORTPTR(ref_)); - } -#endif - - vpx_free(src_); - delete[] ref_; - src_ = nullptr; - ref_ = nullptr; - libvpx_test::ClearSystemState(); - } - - protected: - // We could sub-class MainTestClass into dedicated class for Variance - // and MSE/SSE, but it involves a lot of 'this->xxx' dereferencing - // to access top class fields xxx. That's cumbersome, so for now we'll just - // implement the testing methods here: - - // Variance tests - void ZeroTest(); - void RefTest(); - void RefStrideTest(); - void OneQuarterTest(); - void SpeedTest(); - - // GetVariance tests - void RefTestGetVar(); - - // MSE/SSE tests - void RefTestMse(); - void RefTestSse(); - void MaxTestMse(); - void MaxTestSse(); - - protected: - ACMRandom rnd_; - uint8_t *src_; - uint8_t *ref_; - TestParams params_; - - // some relay helpers - bool use_high_bit_depth() const { return params_.use_high_bit_depth; } - int byte_shift() const { return params_.bit_depth - 8; } - int block_size() const { return params_.block_size; } - int width() const { return params_.width; } - int height() const { return params_.height; } - uint32_t mask() const { return params_.mask; } -}; - -//////////////////////////////////////////////////////////////////////////////// -// Tests related to variance. - -template -void MainTestClass::ZeroTest() { - for (int i = 0; i <= 255; ++i) { - if (!use_high_bit_depth()) { - memset(src_, i, block_size()); - } else { - uint16_t *const src16 = CONVERT_TO_SHORTPTR(src_); - for (int k = 0; k < block_size(); ++k) src16[k] = i << byte_shift(); - } - for (int j = 0; j <= 255; ++j) { - if (!use_high_bit_depth()) { - memset(ref_, j, block_size()); - } else { - uint16_t *const ref16 = CONVERT_TO_SHORTPTR(ref_); - for (int k = 0; k < block_size(); ++k) ref16[k] = j << byte_shift(); - } - unsigned int sse, var; - ASM_REGISTER_STATE_CHECK( - var = params_.func(src_, width(), ref_, width(), &sse)); - EXPECT_EQ(0u, var) << "src values: " << i << " ref values: " << j; - } - } -} - -template -void MainTestClass::RefTest() { - for (int i = 0; i < 10; ++i) { - for (int j = 0; j < block_size(); j++) { - if (!use_high_bit_depth()) { - src_[j] = rnd_.Rand8(); - ref_[j] = rnd_.Rand8(); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - CONVERT_TO_SHORTPTR(src_)[j] = rnd_.Rand16() & mask(); - CONVERT_TO_SHORTPTR(ref_)[j] = rnd_.Rand16() & mask(); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - unsigned int sse1, sse2, var1, var2; - const int stride = width(); - ASM_REGISTER_STATE_CHECK( - var1 = params_.func(src_, stride, ref_, stride, &sse1)); - var2 = - variance_ref(src_, ref_, params_.log2width, params_.log2height, stride, - stride, &sse2, use_high_bit_depth(), params_.bit_depth); - EXPECT_EQ(sse1, sse2) << "Error at test index: " << i; - EXPECT_EQ(var1, var2) << "Error at test index: " << i; - } -} - -template -void MainTestClass::RefStrideTest() { - for (int i = 0; i < 10; ++i) { - const int ref_stride = (i & 1) * width(); - const int src_stride = ((i >> 1) & 1) * width(); - for (int j = 0; j < block_size(); j++) { - const int ref_ind = (j / width()) * ref_stride + j % width(); - const int src_ind = (j / width()) * src_stride + j % width(); - if (!use_high_bit_depth()) { - src_[src_ind] = rnd_.Rand8(); - ref_[ref_ind] = rnd_.Rand8(); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - CONVERT_TO_SHORTPTR(src_)[src_ind] = rnd_.Rand16() & mask(); - CONVERT_TO_SHORTPTR(ref_)[ref_ind] = rnd_.Rand16() & mask(); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - unsigned int sse1, sse2; - unsigned int var1, var2; - - ASM_REGISTER_STATE_CHECK( - var1 = params_.func(src_, src_stride, ref_, ref_stride, &sse1)); - var2 = variance_ref(src_, ref_, params_.log2width, params_.log2height, - src_stride, ref_stride, &sse2, use_high_bit_depth(), - params_.bit_depth); - EXPECT_EQ(sse1, sse2) << "Error at test index: " << i; - EXPECT_EQ(var1, var2) << "Error at test index: " << i; - } -} - -template -void MainTestClass::OneQuarterTest() { - const int half = block_size() / 2; - if (!use_high_bit_depth()) { - memset(src_, 255, block_size()); - memset(ref_, 255, half); - memset(ref_ + half, 0, half); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - vpx_memset16(CONVERT_TO_SHORTPTR(src_), 255 << byte_shift(), block_size()); - vpx_memset16(CONVERT_TO_SHORTPTR(ref_), 255 << byte_shift(), half); - vpx_memset16(CONVERT_TO_SHORTPTR(ref_) + half, 0, half); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - unsigned int sse, var, expected; - ASM_REGISTER_STATE_CHECK( - var = params_.func(src_, width(), ref_, width(), &sse)); - expected = block_size() * 255 * 255 / 4; - EXPECT_EQ(expected, var); -} - -template -void MainTestClass::SpeedTest() { - const int half = block_size() / 2; - if (!use_high_bit_depth()) { - memset(src_, 255, block_size()); - memset(ref_, 255, half); - memset(ref_ + half, 0, half); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - vpx_memset16(CONVERT_TO_SHORTPTR(src_), 255 << byte_shift(), block_size()); - vpx_memset16(CONVERT_TO_SHORTPTR(ref_), 255 << byte_shift(), half); - vpx_memset16(CONVERT_TO_SHORTPTR(ref_) + half, 0, half); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - unsigned int sse; - - vpx_usec_timer timer; - vpx_usec_timer_start(&timer); - for (int i = 0; i < (1 << 30) / block_size(); ++i) { - const uint32_t variance = params_.func(src_, width(), ref_, width(), &sse); - // Ignore return value. - (void)variance; - } - vpx_usec_timer_mark(&timer); - const int elapsed_time = static_cast(vpx_usec_timer_elapsed(&timer)); - printf("Variance %dx%d %dbpp time: %5d ms\n", width(), height(), - params_.bit_depth, elapsed_time / 1000); -} - -//////////////////////////////////////////////////////////////////////////////// -// Tests related to GetVariance. -template -void MainTestClass::RefTestGetVar() { - for (int i = 0; i < 10; ++i) { - for (int j = 0; j < block_size(); j++) { - if (!use_high_bit_depth()) { - src_[j] = rnd_.Rand8(); - ref_[j] = rnd_.Rand8(); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - CONVERT_TO_SHORTPTR(src_)[j] = rnd_.Rand16() & mask(); - CONVERT_TO_SHORTPTR(ref_)[j] = rnd_.Rand16() & mask(); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - unsigned int sse1, sse2; - int sum1, sum2; - const int stride = width(); - ASM_REGISTER_STATE_CHECK( - params_.func(src_, stride, ref_, stride, &sse1, &sum1)); - get_variance_ref(src_, stride, ref_, stride, params_.log2width, - params_.log2height, use_high_bit_depth(), &sse2, &sum2, - params_.bit_depth); - EXPECT_EQ(sse1, sse2) << "Error at test index: " << i; - EXPECT_EQ(sum1, sum2) << "Error at test index: " << i; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Tests related to MSE / SSE. - -template -void MainTestClass::RefTestMse() { - for (int i = 0; i < 10; ++i) { - for (int j = 0; j < block_size(); ++j) { - if (!use_high_bit_depth()) { - src_[j] = rnd_.Rand8(); - ref_[j] = rnd_.Rand8(); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - CONVERT_TO_SHORTPTR(src_)[j] = rnd_.Rand16() & mask(); - CONVERT_TO_SHORTPTR(ref_)[j] = rnd_.Rand16() & mask(); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - unsigned int sse1, sse2; - const int stride = width(); - ASM_REGISTER_STATE_CHECK(params_.func(src_, stride, ref_, stride, &sse1)); - variance_ref(src_, ref_, params_.log2width, params_.log2height, stride, - stride, &sse2, use_high_bit_depth(), params_.bit_depth); - EXPECT_EQ(sse1, sse2); - } -} - -template -void MainTestClass::RefTestSse() { - for (int i = 0; i < 10; ++i) { - for (int j = 0; j < block_size(); ++j) { - src_[j] = rnd_.Rand8(); - ref_[j] = rnd_.Rand8(); - } - unsigned int sse2; - unsigned int var1; - const int stride = width(); - ASM_REGISTER_STATE_CHECK(var1 = params_.func(src_, stride, ref_, stride)); - variance_ref(src_, ref_, params_.log2width, params_.log2height, stride, - stride, &sse2, false, VPX_BITS_8); - EXPECT_EQ(var1, sse2); - } -} - -template -void MainTestClass::MaxTestMse() { - if (!use_high_bit_depth()) { - memset(src_, 255, block_size()); - memset(ref_, 0, block_size()); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - vpx_memset16(CONVERT_TO_SHORTPTR(src_), 255 << byte_shift(), block_size()); - vpx_memset16(CONVERT_TO_SHORTPTR(ref_), 0, block_size()); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - unsigned int sse; - ASM_REGISTER_STATE_CHECK(params_.func(src_, width(), ref_, width(), &sse)); - const unsigned int expected = block_size() * 255 * 255; - EXPECT_EQ(expected, sse); -} - -template -void MainTestClass::MaxTestSse() { - memset(src_, 255, block_size()); - memset(ref_, 0, block_size()); - unsigned int var; - ASM_REGISTER_STATE_CHECK(var = params_.func(src_, width(), ref_, width())); - const unsigned int expected = block_size() * 255 * 255; - EXPECT_EQ(expected, var); -} - -//////////////////////////////////////////////////////////////////////////////// - -template -class SubpelVarianceTest - : public ::testing::TestWithParam > { - public: - void SetUp() override { - params_ = this->GetParam(); - - rnd_.Reset(ACMRandom::DeterministicSeed()); - if (!use_high_bit_depth()) { - src_ = reinterpret_cast(vpx_memalign(16, block_size())); - sec_ = reinterpret_cast(vpx_memalign(16, block_size())); - ref_ = reinterpret_cast( - vpx_malloc(block_size() + width() + height() + 1)); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - src_ = CONVERT_TO_BYTEPTR(reinterpret_cast( - vpx_memalign(16, block_size() * sizeof(uint16_t)))); - sec_ = CONVERT_TO_BYTEPTR(reinterpret_cast( - vpx_memalign(16, block_size() * sizeof(uint16_t)))); - ref_ = CONVERT_TO_BYTEPTR(reinterpret_cast(vpx_malloc( - (block_size() + width() + height() + 1) * sizeof(uint16_t)))); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - ASSERT_NE(src_, nullptr); - ASSERT_NE(sec_, nullptr); - ASSERT_NE(ref_, nullptr); - } - - void TearDown() override { - if (!use_high_bit_depth()) { - vpx_free(src_); - vpx_free(sec_); - vpx_free(ref_); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - vpx_free(CONVERT_TO_SHORTPTR(src_)); - vpx_free(CONVERT_TO_SHORTPTR(ref_)); - vpx_free(CONVERT_TO_SHORTPTR(sec_)); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - libvpx_test::ClearSystemState(); - } - - protected: - void RefTest(); - void ExtremeRefTest(); - void SpeedTest(); - - ACMRandom rnd_; - uint8_t *src_; - uint8_t *ref_; - uint8_t *sec_; - TestParams params_; - - // some relay helpers - bool use_high_bit_depth() const { return params_.use_high_bit_depth; } - int byte_shift() const { return params_.bit_depth - 8; } - int block_size() const { return params_.block_size; } - int width() const { return params_.width; } - int height() const { return params_.height; } - uint32_t mask() const { return params_.mask; } -}; - -template -void SubpelVarianceTest::RefTest() { - for (int x = 0; x < 8; ++x) { - for (int y = 0; y < 8; ++y) { - if (!use_high_bit_depth()) { - for (int j = 0; j < block_size(); j++) { - src_[j] = rnd_.Rand8(); - } - for (int j = 0; j < block_size() + width() + height() + 1; j++) { - ref_[j] = rnd_.Rand8(); - } -#if CONFIG_VP9_HIGHBITDEPTH - } else { - for (int j = 0; j < block_size(); j++) { - CONVERT_TO_SHORTPTR(src_)[j] = rnd_.Rand16() & mask(); - } - for (int j = 0; j < block_size() + width() + height() + 1; j++) { - CONVERT_TO_SHORTPTR(ref_)[j] = rnd_.Rand16() & mask(); - } -#endif // CONFIG_VP9_HIGHBITDEPTH - } - unsigned int sse1, sse2; - unsigned int var1; - ASM_REGISTER_STATE_CHECK( - var1 = params_.func(ref_, width() + 1, x, y, src_, width(), &sse1)); - const unsigned int var2 = subpel_variance_ref( - ref_, src_, params_.log2width, params_.log2height, x, y, &sse2, - use_high_bit_depth(), params_.bit_depth); - EXPECT_EQ(sse1, sse2) << "at position " << x << ", " << y; - EXPECT_EQ(var1, var2) << "at position " << x << ", " << y; - } - } -} - -template -void SubpelVarianceTest::ExtremeRefTest() { - // Compare against reference. - // Src: Set the first half of values to 0, the second half to the maximum. - // Ref: Set the first half of values to the maximum, the second half to 0. - for (int x = 0; x < 8; ++x) { - for (int y = 0; y < 8; ++y) { - const int half = block_size() / 2; - if (!use_high_bit_depth()) { - memset(src_, 0, half); - memset(src_ + half, 255, half); - memset(ref_, 255, half); - memset(ref_ + half, 0, half + width() + height() + 1); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - vpx_memset16(CONVERT_TO_SHORTPTR(src_), mask(), half); - vpx_memset16(CONVERT_TO_SHORTPTR(src_) + half, 0, half); - vpx_memset16(CONVERT_TO_SHORTPTR(ref_), 0, half); - vpx_memset16(CONVERT_TO_SHORTPTR(ref_) + half, mask(), - half + width() + height() + 1); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - unsigned int sse1, sse2; - unsigned int var1; - ASM_REGISTER_STATE_CHECK( - var1 = params_.func(ref_, width() + 1, x, y, src_, width(), &sse1)); - const unsigned int var2 = subpel_variance_ref( - ref_, src_, params_.log2width, params_.log2height, x, y, &sse2, - use_high_bit_depth(), params_.bit_depth); - EXPECT_EQ(sse1, sse2) << "for xoffset " << x << " and yoffset " << y; - EXPECT_EQ(var1, var2) << "for xoffset " << x << " and yoffset " << y; - } - } -} - -template -void SubpelVarianceTest::SpeedTest() { - // The only interesting points are 0, 4, and anything else. To make the loops - // simple we will use 0, 2 and 4. - for (int x = 0; x <= 4; x += 2) { - for (int y = 0; y <= 4; y += 2) { - if (!use_high_bit_depth()) { - memset(src_, 25, block_size()); - memset(ref_, 50, block_size()); -#if CONFIG_VP9_HIGHBITDEPTH - } else { - vpx_memset16(CONVERT_TO_SHORTPTR(src_), 25, block_size()); - vpx_memset16(CONVERT_TO_SHORTPTR(ref_), 50, block_size()); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - unsigned int sse; - vpx_usec_timer timer; - vpx_usec_timer_start(&timer); - for (int i = 0; i < 1000000000 / block_size(); ++i) { - const uint32_t variance = - params_.func(ref_, width() + 1, x, y, src_, width(), &sse); - (void)variance; - } - vpx_usec_timer_mark(&timer); - const int elapsed_time = static_cast(vpx_usec_timer_elapsed(&timer)); - printf("SubpelVariance %dx%d xoffset: %d yoffset: %d time: %5d ms\n", - width(), height(), x, y, elapsed_time / 1000); - } - } -} - -template <> -void SubpelVarianceTest::RefTest() { - for (int x = 0; x < 8; ++x) { - for (int y = 0; y < 8; ++y) { - if (!use_high_bit_depth()) { - for (int j = 0; j < block_size(); j++) { - src_[j] = rnd_.Rand8(); - sec_[j] = rnd_.Rand8(); - } - for (int j = 0; j < block_size() + width() + height() + 1; j++) { - ref_[j] = rnd_.Rand8(); - } -#if CONFIG_VP9_HIGHBITDEPTH - } else { - for (int j = 0; j < block_size(); j++) { - CONVERT_TO_SHORTPTR(src_)[j] = rnd_.Rand16() & mask(); - CONVERT_TO_SHORTPTR(sec_)[j] = rnd_.Rand16() & mask(); - } - for (int j = 0; j < block_size() + width() + height() + 1; j++) { - CONVERT_TO_SHORTPTR(ref_)[j] = rnd_.Rand16() & mask(); - } -#endif // CONFIG_VP9_HIGHBITDEPTH - } - uint32_t sse1, sse2; - uint32_t var1, var2; - ASM_REGISTER_STATE_CHECK(var1 = params_.func(ref_, width() + 1, x, y, - src_, width(), &sse1, sec_)); - var2 = subpel_avg_variance_ref(ref_, src_, sec_, params_.log2width, - params_.log2height, x, y, &sse2, - use_high_bit_depth(), params_.bit_depth); - EXPECT_EQ(sse1, sse2) << "at position " << x << ", " << y; - EXPECT_EQ(var1, var2) << "at position " << x << ", " << y; - } - } -} - -typedef MainTestClass VpxSseTest; -typedef MainTestClass VpxMseTest; -typedef MainTestClass VpxVarianceTest; -typedef MainTestClass VpxGetVarianceTest; -typedef SubpelVarianceTest VpxSubpelVarianceTest; -typedef SubpelVarianceTest VpxSubpelAvgVarianceTest; - -TEST_P(VpxSseTest, RefSse) { RefTestSse(); } -TEST_P(VpxSseTest, MaxSse) { MaxTestSse(); } -TEST_P(VpxMseTest, RefMse) { RefTestMse(); } -TEST_P(VpxMseTest, MaxMse) { MaxTestMse(); } -TEST_P(VpxMseTest, DISABLED_Speed) { SpeedTest(); } -TEST_P(VpxVarianceTest, Zero) { ZeroTest(); } -TEST_P(VpxVarianceTest, Ref) { RefTest(); } -TEST_P(VpxVarianceTest, RefStride) { RefStrideTest(); } -TEST_P(VpxVarianceTest, OneQuarter) { OneQuarterTest(); } -TEST_P(VpxVarianceTest, DISABLED_Speed) { SpeedTest(); } -TEST_P(VpxGetVarianceTest, RefGetVar) { RefTestGetVar(); } -TEST_P(SumOfSquaresTest, Const) { ConstTest(); } -TEST_P(SumOfSquaresTest, Ref) { RefTest(); } -TEST_P(VpxSubpelVarianceTest, Ref) { RefTest(); } -TEST_P(VpxSubpelVarianceTest, ExtremeRef) { ExtremeRefTest(); } -TEST_P(VpxSubpelVarianceTest, DISABLED_Speed) { SpeedTest(); } -TEST_P(VpxSubpelAvgVarianceTest, Ref) { RefTest(); } - -INSTANTIATE_TEST_SUITE_P(C, SumOfSquaresTest, - ::testing::Values(vpx_get_mb_ss_c)); - -typedef TestParams SseParams; -INSTANTIATE_TEST_SUITE_P(C, VpxSseTest, - ::testing::Values(SseParams(2, 2, - &vpx_get4x4sse_cs_c))); - -typedef TestParams MseParams; -INSTANTIATE_TEST_SUITE_P(C, VpxMseTest, - ::testing::Values(MseParams(4, 4, &vpx_mse16x16_c), - MseParams(4, 3, &vpx_mse16x8_c), - MseParams(3, 4, &vpx_mse8x16_c), - MseParams(3, 3, &vpx_mse8x8_c))); - -typedef TestParams VarianceParams; -INSTANTIATE_TEST_SUITE_P( - C, VpxVarianceTest, - ::testing::Values(VarianceParams(6, 6, &vpx_variance64x64_c), - VarianceParams(6, 5, &vpx_variance64x32_c), - VarianceParams(5, 6, &vpx_variance32x64_c), - VarianceParams(5, 5, &vpx_variance32x32_c), - VarianceParams(5, 4, &vpx_variance32x16_c), - VarianceParams(4, 5, &vpx_variance16x32_c), - VarianceParams(4, 4, &vpx_variance16x16_c), - VarianceParams(4, 3, &vpx_variance16x8_c), - VarianceParams(3, 4, &vpx_variance8x16_c), - VarianceParams(3, 3, &vpx_variance8x8_c), - VarianceParams(3, 2, &vpx_variance8x4_c), - VarianceParams(2, 3, &vpx_variance4x8_c), - VarianceParams(2, 2, &vpx_variance4x4_c))); - -typedef TestParams GetVarianceParams; -INSTANTIATE_TEST_SUITE_P( - C, VpxGetVarianceTest, - ::testing::Values(GetVarianceParams(4, 4, &vpx_get16x16var_c), - GetVarianceParams(3, 3, &vpx_get8x8var_c), - GetVarianceParams(4, 4, &vpx_get16x16var_c), - GetVarianceParams(3, 3, &vpx_get8x8var_c), - GetVarianceParams(4, 4, &vpx_get16x16var_c), - GetVarianceParams(3, 3, &vpx_get8x8var_c))); - -typedef TestParams SubpelVarianceParams; -INSTANTIATE_TEST_SUITE_P( - C, VpxSubpelVarianceTest, - ::testing::Values( - SubpelVarianceParams(6, 6, &vpx_sub_pixel_variance64x64_c, 0), - SubpelVarianceParams(6, 5, &vpx_sub_pixel_variance64x32_c, 0), - SubpelVarianceParams(5, 6, &vpx_sub_pixel_variance32x64_c, 0), - SubpelVarianceParams(5, 5, &vpx_sub_pixel_variance32x32_c, 0), - SubpelVarianceParams(5, 4, &vpx_sub_pixel_variance32x16_c, 0), - SubpelVarianceParams(4, 5, &vpx_sub_pixel_variance16x32_c, 0), - SubpelVarianceParams(4, 4, &vpx_sub_pixel_variance16x16_c, 0), - SubpelVarianceParams(4, 3, &vpx_sub_pixel_variance16x8_c, 0), - SubpelVarianceParams(3, 4, &vpx_sub_pixel_variance8x16_c, 0), - SubpelVarianceParams(3, 3, &vpx_sub_pixel_variance8x8_c, 0), - SubpelVarianceParams(3, 2, &vpx_sub_pixel_variance8x4_c, 0), - SubpelVarianceParams(2, 3, &vpx_sub_pixel_variance4x8_c, 0), - SubpelVarianceParams(2, 2, &vpx_sub_pixel_variance4x4_c, 0))); - -typedef TestParams SubpelAvgVarianceParams; -INSTANTIATE_TEST_SUITE_P( - C, VpxSubpelAvgVarianceTest, - ::testing::Values( - SubpelAvgVarianceParams(6, 6, &vpx_sub_pixel_avg_variance64x64_c, 0), - SubpelAvgVarianceParams(6, 5, &vpx_sub_pixel_avg_variance64x32_c, 0), - SubpelAvgVarianceParams(5, 6, &vpx_sub_pixel_avg_variance32x64_c, 0), - SubpelAvgVarianceParams(5, 5, &vpx_sub_pixel_avg_variance32x32_c, 0), - SubpelAvgVarianceParams(5, 4, &vpx_sub_pixel_avg_variance32x16_c, 0), - SubpelAvgVarianceParams(4, 5, &vpx_sub_pixel_avg_variance16x32_c, 0), - SubpelAvgVarianceParams(4, 4, &vpx_sub_pixel_avg_variance16x16_c, 0), - SubpelAvgVarianceParams(4, 3, &vpx_sub_pixel_avg_variance16x8_c, 0), - SubpelAvgVarianceParams(3, 4, &vpx_sub_pixel_avg_variance8x16_c, 0), - SubpelAvgVarianceParams(3, 3, &vpx_sub_pixel_avg_variance8x8_c, 0), - SubpelAvgVarianceParams(3, 2, &vpx_sub_pixel_avg_variance8x4_c, 0), - SubpelAvgVarianceParams(2, 3, &vpx_sub_pixel_avg_variance4x8_c, 0), - SubpelAvgVarianceParams(2, 2, &vpx_sub_pixel_avg_variance4x4_c, 0))); - -#if CONFIG_VP9_HIGHBITDEPTH -typedef MainTestClass VpxHBDVarianceTest; -typedef MainTestClass VpxHBDGetVarianceTest; -typedef SubpelVarianceTest VpxHBDSubpelVarianceTest; -typedef SubpelVarianceTest - VpxHBDSubpelAvgVarianceTest; - -TEST_P(VpxHBDVarianceTest, Zero) { ZeroTest(); } -TEST_P(VpxHBDVarianceTest, Ref) { RefTest(); } -TEST_P(VpxHBDVarianceTest, RefStride) { RefStrideTest(); } -TEST_P(VpxHBDVarianceTest, OneQuarter) { OneQuarterTest(); } -TEST_P(VpxHBDVarianceTest, DISABLED_Speed) { SpeedTest(); } -TEST_P(VpxHBDGetVarianceTest, RefGetVar) { RefTestGetVar(); } -TEST_P(VpxHBDSubpelVarianceTest, Ref) { RefTest(); } -TEST_P(VpxHBDSubpelVarianceTest, ExtremeRef) { ExtremeRefTest(); } -TEST_P(VpxHBDSubpelAvgVarianceTest, Ref) { RefTest(); } - -typedef MainTestClass VpxHBDMseTest; -TEST_P(VpxHBDMseTest, RefMse) { RefTestMse(); } -TEST_P(VpxHBDMseTest, MaxMse) { MaxTestMse(); } -TEST_P(VpxHBDMseTest, DISABLED_Speed) { SpeedTest(); } -INSTANTIATE_TEST_SUITE_P( - C, VpxHBDMseTest, - ::testing::Values(MseParams(4, 4, &vpx_highbd_12_mse16x16_c, VPX_BITS_12), - MseParams(4, 3, &vpx_highbd_12_mse16x8_c, VPX_BITS_12), - MseParams(3, 4, &vpx_highbd_12_mse8x16_c, VPX_BITS_12), - MseParams(3, 3, &vpx_highbd_12_mse8x8_c, VPX_BITS_12), - MseParams(4, 4, &vpx_highbd_10_mse16x16_c, VPX_BITS_10), - MseParams(4, 3, &vpx_highbd_10_mse16x8_c, VPX_BITS_10), - MseParams(3, 4, &vpx_highbd_10_mse8x16_c, VPX_BITS_10), - MseParams(3, 3, &vpx_highbd_10_mse8x8_c, VPX_BITS_10), - MseParams(4, 4, &vpx_highbd_8_mse16x16_c, VPX_BITS_8), - MseParams(4, 3, &vpx_highbd_8_mse16x8_c, VPX_BITS_8), - MseParams(3, 4, &vpx_highbd_8_mse8x16_c, VPX_BITS_8), - MseParams(3, 3, &vpx_highbd_8_mse8x8_c, VPX_BITS_8))); - -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VpxHBDMseTest); - -INSTANTIATE_TEST_SUITE_P( - C, VpxHBDVarianceTest, - ::testing::Values(VarianceParams(6, 6, &vpx_highbd_12_variance64x64_c, 12), - VarianceParams(6, 5, &vpx_highbd_12_variance64x32_c, 12), - VarianceParams(5, 6, &vpx_highbd_12_variance32x64_c, 12), - VarianceParams(5, 5, &vpx_highbd_12_variance32x32_c, 12), - VarianceParams(5, 4, &vpx_highbd_12_variance32x16_c, 12), - VarianceParams(4, 5, &vpx_highbd_12_variance16x32_c, 12), - VarianceParams(4, 4, &vpx_highbd_12_variance16x16_c, 12), - VarianceParams(4, 3, &vpx_highbd_12_variance16x8_c, 12), - VarianceParams(3, 4, &vpx_highbd_12_variance8x16_c, 12), - VarianceParams(3, 3, &vpx_highbd_12_variance8x8_c, 12), - VarianceParams(3, 2, &vpx_highbd_12_variance8x4_c, 12), - VarianceParams(2, 3, &vpx_highbd_12_variance4x8_c, 12), - VarianceParams(2, 2, &vpx_highbd_12_variance4x4_c, 12), - VarianceParams(6, 6, &vpx_highbd_10_variance64x64_c, 10), - VarianceParams(6, 5, &vpx_highbd_10_variance64x32_c, 10), - VarianceParams(5, 6, &vpx_highbd_10_variance32x64_c, 10), - VarianceParams(5, 5, &vpx_highbd_10_variance32x32_c, 10), - VarianceParams(5, 4, &vpx_highbd_10_variance32x16_c, 10), - VarianceParams(4, 5, &vpx_highbd_10_variance16x32_c, 10), - VarianceParams(4, 4, &vpx_highbd_10_variance16x16_c, 10), - VarianceParams(4, 3, &vpx_highbd_10_variance16x8_c, 10), - VarianceParams(3, 4, &vpx_highbd_10_variance8x16_c, 10), - VarianceParams(3, 3, &vpx_highbd_10_variance8x8_c, 10), - VarianceParams(3, 2, &vpx_highbd_10_variance8x4_c, 10), - VarianceParams(2, 3, &vpx_highbd_10_variance4x8_c, 10), - VarianceParams(2, 2, &vpx_highbd_10_variance4x4_c, 10), - VarianceParams(6, 6, &vpx_highbd_8_variance64x64_c, 8), - VarianceParams(6, 5, &vpx_highbd_8_variance64x32_c, 8), - VarianceParams(5, 6, &vpx_highbd_8_variance32x64_c, 8), - VarianceParams(5, 5, &vpx_highbd_8_variance32x32_c, 8), - VarianceParams(5, 4, &vpx_highbd_8_variance32x16_c, 8), - VarianceParams(4, 5, &vpx_highbd_8_variance16x32_c, 8), - VarianceParams(4, 4, &vpx_highbd_8_variance16x16_c, 8), - VarianceParams(4, 3, &vpx_highbd_8_variance16x8_c, 8), - VarianceParams(3, 4, &vpx_highbd_8_variance8x16_c, 8), - VarianceParams(3, 3, &vpx_highbd_8_variance8x8_c, 8), - VarianceParams(3, 2, &vpx_highbd_8_variance8x4_c, 8), - VarianceParams(2, 3, &vpx_highbd_8_variance4x8_c, 8), - VarianceParams(2, 2, &vpx_highbd_8_variance4x4_c, 8))); - -INSTANTIATE_TEST_SUITE_P( - C, VpxHBDGetVarianceTest, - ::testing::Values(GetVarianceParams(4, 4, &vpx_highbd_12_get16x16var_c, 12), - GetVarianceParams(3, 3, &vpx_highbd_12_get8x8var_c, 12), - GetVarianceParams(4, 4, &vpx_highbd_10_get16x16var_c, 10), - GetVarianceParams(3, 3, &vpx_highbd_10_get8x8var_c, 10), - GetVarianceParams(4, 4, &vpx_highbd_8_get16x16var_c, 8), - GetVarianceParams(3, 3, &vpx_highbd_8_get8x8var_c, 8))); - -INSTANTIATE_TEST_SUITE_P( - C, VpxHBDSubpelVarianceTest, - ::testing::Values( - SubpelVarianceParams(6, 6, &vpx_highbd_8_sub_pixel_variance64x64_c, 8), - SubpelVarianceParams(6, 5, &vpx_highbd_8_sub_pixel_variance64x32_c, 8), - SubpelVarianceParams(5, 6, &vpx_highbd_8_sub_pixel_variance32x64_c, 8), - SubpelVarianceParams(5, 5, &vpx_highbd_8_sub_pixel_variance32x32_c, 8), - SubpelVarianceParams(5, 4, &vpx_highbd_8_sub_pixel_variance32x16_c, 8), - SubpelVarianceParams(4, 5, &vpx_highbd_8_sub_pixel_variance16x32_c, 8), - SubpelVarianceParams(4, 4, &vpx_highbd_8_sub_pixel_variance16x16_c, 8), - SubpelVarianceParams(4, 3, &vpx_highbd_8_sub_pixel_variance16x8_c, 8), - SubpelVarianceParams(3, 4, &vpx_highbd_8_sub_pixel_variance8x16_c, 8), - SubpelVarianceParams(3, 3, &vpx_highbd_8_sub_pixel_variance8x8_c, 8), - SubpelVarianceParams(3, 2, &vpx_highbd_8_sub_pixel_variance8x4_c, 8), - SubpelVarianceParams(2, 3, &vpx_highbd_8_sub_pixel_variance4x8_c, 8), - SubpelVarianceParams(2, 2, &vpx_highbd_8_sub_pixel_variance4x4_c, 8), - SubpelVarianceParams(6, 6, &vpx_highbd_10_sub_pixel_variance64x64_c, - 10), - SubpelVarianceParams(6, 5, &vpx_highbd_10_sub_pixel_variance64x32_c, - 10), - SubpelVarianceParams(5, 6, &vpx_highbd_10_sub_pixel_variance32x64_c, - 10), - SubpelVarianceParams(5, 5, &vpx_highbd_10_sub_pixel_variance32x32_c, - 10), - SubpelVarianceParams(5, 4, &vpx_highbd_10_sub_pixel_variance32x16_c, - 10), - SubpelVarianceParams(4, 5, &vpx_highbd_10_sub_pixel_variance16x32_c, - 10), - SubpelVarianceParams(4, 4, &vpx_highbd_10_sub_pixel_variance16x16_c, - 10), - SubpelVarianceParams(4, 3, &vpx_highbd_10_sub_pixel_variance16x8_c, 10), - SubpelVarianceParams(3, 4, &vpx_highbd_10_sub_pixel_variance8x16_c, 10), - SubpelVarianceParams(3, 3, &vpx_highbd_10_sub_pixel_variance8x8_c, 10), - SubpelVarianceParams(3, 2, &vpx_highbd_10_sub_pixel_variance8x4_c, 10), - SubpelVarianceParams(2, 3, &vpx_highbd_10_sub_pixel_variance4x8_c, 10), - SubpelVarianceParams(2, 2, &vpx_highbd_10_sub_pixel_variance4x4_c, 10), - SubpelVarianceParams(6, 6, &vpx_highbd_12_sub_pixel_variance64x64_c, - 12), - SubpelVarianceParams(6, 5, &vpx_highbd_12_sub_pixel_variance64x32_c, - 12), - SubpelVarianceParams(5, 6, &vpx_highbd_12_sub_pixel_variance32x64_c, - 12), - SubpelVarianceParams(5, 5, &vpx_highbd_12_sub_pixel_variance32x32_c, - 12), - SubpelVarianceParams(5, 4, &vpx_highbd_12_sub_pixel_variance32x16_c, - 12), - SubpelVarianceParams(4, 5, &vpx_highbd_12_sub_pixel_variance16x32_c, - 12), - SubpelVarianceParams(4, 4, &vpx_highbd_12_sub_pixel_variance16x16_c, - 12), - SubpelVarianceParams(4, 3, &vpx_highbd_12_sub_pixel_variance16x8_c, 12), - SubpelVarianceParams(3, 4, &vpx_highbd_12_sub_pixel_variance8x16_c, 12), - SubpelVarianceParams(3, 3, &vpx_highbd_12_sub_pixel_variance8x8_c, 12), - SubpelVarianceParams(3, 2, &vpx_highbd_12_sub_pixel_variance8x4_c, 12), - SubpelVarianceParams(2, 3, &vpx_highbd_12_sub_pixel_variance4x8_c, 12), - SubpelVarianceParams(2, 2, &vpx_highbd_12_sub_pixel_variance4x4_c, - 12))); - -INSTANTIATE_TEST_SUITE_P( - C, VpxHBDSubpelAvgVarianceTest, - ::testing::Values( - SubpelAvgVarianceParams(6, 6, - &vpx_highbd_8_sub_pixel_avg_variance64x64_c, 8), - SubpelAvgVarianceParams(6, 5, - &vpx_highbd_8_sub_pixel_avg_variance64x32_c, 8), - SubpelAvgVarianceParams(5, 6, - &vpx_highbd_8_sub_pixel_avg_variance32x64_c, 8), - SubpelAvgVarianceParams(5, 5, - &vpx_highbd_8_sub_pixel_avg_variance32x32_c, 8), - SubpelAvgVarianceParams(5, 4, - &vpx_highbd_8_sub_pixel_avg_variance32x16_c, 8), - SubpelAvgVarianceParams(4, 5, - &vpx_highbd_8_sub_pixel_avg_variance16x32_c, 8), - SubpelAvgVarianceParams(4, 4, - &vpx_highbd_8_sub_pixel_avg_variance16x16_c, 8), - SubpelAvgVarianceParams(4, 3, - &vpx_highbd_8_sub_pixel_avg_variance16x8_c, 8), - SubpelAvgVarianceParams(3, 4, - &vpx_highbd_8_sub_pixel_avg_variance8x16_c, 8), - SubpelAvgVarianceParams(3, 3, &vpx_highbd_8_sub_pixel_avg_variance8x8_c, - 8), - SubpelAvgVarianceParams(3, 2, &vpx_highbd_8_sub_pixel_avg_variance8x4_c, - 8), - SubpelAvgVarianceParams(2, 3, &vpx_highbd_8_sub_pixel_avg_variance4x8_c, - 8), - SubpelAvgVarianceParams(2, 2, &vpx_highbd_8_sub_pixel_avg_variance4x4_c, - 8), - SubpelAvgVarianceParams(6, 6, - &vpx_highbd_10_sub_pixel_avg_variance64x64_c, - 10), - SubpelAvgVarianceParams(6, 5, - &vpx_highbd_10_sub_pixel_avg_variance64x32_c, - 10), - SubpelAvgVarianceParams(5, 6, - &vpx_highbd_10_sub_pixel_avg_variance32x64_c, - 10), - SubpelAvgVarianceParams(5, 5, - &vpx_highbd_10_sub_pixel_avg_variance32x32_c, - 10), - SubpelAvgVarianceParams(5, 4, - &vpx_highbd_10_sub_pixel_avg_variance32x16_c, - 10), - SubpelAvgVarianceParams(4, 5, - &vpx_highbd_10_sub_pixel_avg_variance16x32_c, - 10), - SubpelAvgVarianceParams(4, 4, - &vpx_highbd_10_sub_pixel_avg_variance16x16_c, - 10), - SubpelAvgVarianceParams(4, 3, - &vpx_highbd_10_sub_pixel_avg_variance16x8_c, - 10), - SubpelAvgVarianceParams(3, 4, - &vpx_highbd_10_sub_pixel_avg_variance8x16_c, - 10), - SubpelAvgVarianceParams(3, 3, - &vpx_highbd_10_sub_pixel_avg_variance8x8_c, 10), - SubpelAvgVarianceParams(3, 2, - &vpx_highbd_10_sub_pixel_avg_variance8x4_c, 10), - SubpelAvgVarianceParams(2, 3, - &vpx_highbd_10_sub_pixel_avg_variance4x8_c, 10), - SubpelAvgVarianceParams(2, 2, - &vpx_highbd_10_sub_pixel_avg_variance4x4_c, 10), - SubpelAvgVarianceParams(6, 6, - &vpx_highbd_12_sub_pixel_avg_variance64x64_c, - 12), - SubpelAvgVarianceParams(6, 5, - &vpx_highbd_12_sub_pixel_avg_variance64x32_c, - 12), - SubpelAvgVarianceParams(5, 6, - &vpx_highbd_12_sub_pixel_avg_variance32x64_c, - 12), - SubpelAvgVarianceParams(5, 5, - &vpx_highbd_12_sub_pixel_avg_variance32x32_c, - 12), - SubpelAvgVarianceParams(5, 4, - &vpx_highbd_12_sub_pixel_avg_variance32x16_c, - 12), - SubpelAvgVarianceParams(4, 5, - &vpx_highbd_12_sub_pixel_avg_variance16x32_c, - 12), - SubpelAvgVarianceParams(4, 4, - &vpx_highbd_12_sub_pixel_avg_variance16x16_c, - 12), - SubpelAvgVarianceParams(4, 3, - &vpx_highbd_12_sub_pixel_avg_variance16x8_c, - 12), - SubpelAvgVarianceParams(3, 4, - &vpx_highbd_12_sub_pixel_avg_variance8x16_c, - 12), - SubpelAvgVarianceParams(3, 3, - &vpx_highbd_12_sub_pixel_avg_variance8x8_c, 12), - SubpelAvgVarianceParams(3, 2, - &vpx_highbd_12_sub_pixel_avg_variance8x4_c, 12), - SubpelAvgVarianceParams(2, 3, - &vpx_highbd_12_sub_pixel_avg_variance4x8_c, 12), - SubpelAvgVarianceParams(2, 2, - &vpx_highbd_12_sub_pixel_avg_variance4x4_c, - 12))); -#endif // CONFIG_VP9_HIGHBITDEPTH - -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P(SSE2, SumOfSquaresTest, - ::testing::Values(vpx_get_mb_ss_sse2)); - -INSTANTIATE_TEST_SUITE_P(SSE2, VpxMseTest, - ::testing::Values(MseParams(4, 4, &vpx_mse16x16_sse2), - MseParams(4, 3, &vpx_mse16x8_sse2), - MseParams(3, 4, &vpx_mse8x16_sse2), - MseParams(3, 3, &vpx_mse8x8_sse2))); - -INSTANTIATE_TEST_SUITE_P( - SSE2, VpxVarianceTest, - ::testing::Values(VarianceParams(6, 6, &vpx_variance64x64_sse2), - VarianceParams(6, 5, &vpx_variance64x32_sse2), - VarianceParams(5, 6, &vpx_variance32x64_sse2), - VarianceParams(5, 5, &vpx_variance32x32_sse2), - VarianceParams(5, 4, &vpx_variance32x16_sse2), - VarianceParams(4, 5, &vpx_variance16x32_sse2), - VarianceParams(4, 4, &vpx_variance16x16_sse2), - VarianceParams(4, 3, &vpx_variance16x8_sse2), - VarianceParams(3, 4, &vpx_variance8x16_sse2), - VarianceParams(3, 3, &vpx_variance8x8_sse2), - VarianceParams(3, 2, &vpx_variance8x4_sse2), - VarianceParams(2, 3, &vpx_variance4x8_sse2), - VarianceParams(2, 2, &vpx_variance4x4_sse2))); - -INSTANTIATE_TEST_SUITE_P( - SSE2, VpxGetVarianceTest, - ::testing::Values(GetVarianceParams(4, 4, &vpx_get16x16var_sse2), - GetVarianceParams(3, 3, &vpx_get8x8var_sse2), - GetVarianceParams(4, 4, &vpx_get16x16var_sse2), - GetVarianceParams(3, 3, &vpx_get8x8var_sse2), - GetVarianceParams(4, 4, &vpx_get16x16var_sse2), - GetVarianceParams(3, 3, &vpx_get8x8var_sse2))); - -INSTANTIATE_TEST_SUITE_P( - SSE2, VpxSubpelVarianceTest, - ::testing::Values( - SubpelVarianceParams(6, 6, &vpx_sub_pixel_variance64x64_sse2, 0), - SubpelVarianceParams(6, 5, &vpx_sub_pixel_variance64x32_sse2, 0), - SubpelVarianceParams(5, 6, &vpx_sub_pixel_variance32x64_sse2, 0), - SubpelVarianceParams(5, 5, &vpx_sub_pixel_variance32x32_sse2, 0), - SubpelVarianceParams(5, 4, &vpx_sub_pixel_variance32x16_sse2, 0), - SubpelVarianceParams(4, 5, &vpx_sub_pixel_variance16x32_sse2, 0), - SubpelVarianceParams(4, 4, &vpx_sub_pixel_variance16x16_sse2, 0), - SubpelVarianceParams(4, 3, &vpx_sub_pixel_variance16x8_sse2, 0), - SubpelVarianceParams(3, 4, &vpx_sub_pixel_variance8x16_sse2, 0), - SubpelVarianceParams(3, 3, &vpx_sub_pixel_variance8x8_sse2, 0), - SubpelVarianceParams(3, 2, &vpx_sub_pixel_variance8x4_sse2, 0), - SubpelVarianceParams(2, 3, &vpx_sub_pixel_variance4x8_sse2, 0), - SubpelVarianceParams(2, 2, &vpx_sub_pixel_variance4x4_sse2, 0))); - -INSTANTIATE_TEST_SUITE_P( - SSE2, VpxSubpelAvgVarianceTest, - ::testing::Values( - SubpelAvgVarianceParams(6, 6, &vpx_sub_pixel_avg_variance64x64_sse2, 0), - SubpelAvgVarianceParams(6, 5, &vpx_sub_pixel_avg_variance64x32_sse2, 0), - SubpelAvgVarianceParams(5, 6, &vpx_sub_pixel_avg_variance32x64_sse2, 0), - SubpelAvgVarianceParams(5, 5, &vpx_sub_pixel_avg_variance32x32_sse2, 0), - SubpelAvgVarianceParams(5, 4, &vpx_sub_pixel_avg_variance32x16_sse2, 0), - SubpelAvgVarianceParams(4, 5, &vpx_sub_pixel_avg_variance16x32_sse2, 0), - SubpelAvgVarianceParams(4, 4, &vpx_sub_pixel_avg_variance16x16_sse2, 0), - SubpelAvgVarianceParams(4, 3, &vpx_sub_pixel_avg_variance16x8_sse2, 0), - SubpelAvgVarianceParams(3, 4, &vpx_sub_pixel_avg_variance8x16_sse2, 0), - SubpelAvgVarianceParams(3, 3, &vpx_sub_pixel_avg_variance8x8_sse2, 0), - SubpelAvgVarianceParams(3, 2, &vpx_sub_pixel_avg_variance8x4_sse2, 0), - SubpelAvgVarianceParams(2, 3, &vpx_sub_pixel_avg_variance4x8_sse2, 0), - SubpelAvgVarianceParams(2, 2, &vpx_sub_pixel_avg_variance4x4_sse2, 0))); - -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - SSE2, VpxHBDMseTest, - ::testing::Values( - MseParams(4, 4, &vpx_highbd_12_mse16x16_sse2, VPX_BITS_12), - MseParams(3, 3, &vpx_highbd_12_mse8x8_sse2, VPX_BITS_12), - MseParams(4, 4, &vpx_highbd_10_mse16x16_sse2, VPX_BITS_10), - MseParams(3, 3, &vpx_highbd_10_mse8x8_sse2, VPX_BITS_10), - MseParams(4, 4, &vpx_highbd_8_mse16x16_sse2, VPX_BITS_8), - MseParams(3, 3, &vpx_highbd_8_mse8x8_sse2, VPX_BITS_8))); - -INSTANTIATE_TEST_SUITE_P( - SSE2, VpxHBDVarianceTest, - ::testing::Values( - VarianceParams(6, 6, &vpx_highbd_12_variance64x64_sse2, 12), - VarianceParams(6, 5, &vpx_highbd_12_variance64x32_sse2, 12), - VarianceParams(5, 6, &vpx_highbd_12_variance32x64_sse2, 12), - VarianceParams(5, 5, &vpx_highbd_12_variance32x32_sse2, 12), - VarianceParams(5, 4, &vpx_highbd_12_variance32x16_sse2, 12), - VarianceParams(4, 5, &vpx_highbd_12_variance16x32_sse2, 12), - VarianceParams(4, 4, &vpx_highbd_12_variance16x16_sse2, 12), - VarianceParams(4, 3, &vpx_highbd_12_variance16x8_sse2, 12), - VarianceParams(3, 4, &vpx_highbd_12_variance8x16_sse2, 12), - VarianceParams(3, 3, &vpx_highbd_12_variance8x8_sse2, 12), - VarianceParams(6, 6, &vpx_highbd_10_variance64x64_sse2, 10), - VarianceParams(6, 5, &vpx_highbd_10_variance64x32_sse2, 10), - VarianceParams(5, 6, &vpx_highbd_10_variance32x64_sse2, 10), - VarianceParams(5, 5, &vpx_highbd_10_variance32x32_sse2, 10), - VarianceParams(5, 4, &vpx_highbd_10_variance32x16_sse2, 10), - VarianceParams(4, 5, &vpx_highbd_10_variance16x32_sse2, 10), - VarianceParams(4, 4, &vpx_highbd_10_variance16x16_sse2, 10), - VarianceParams(4, 3, &vpx_highbd_10_variance16x8_sse2, 10), - VarianceParams(3, 4, &vpx_highbd_10_variance8x16_sse2, 10), - VarianceParams(3, 3, &vpx_highbd_10_variance8x8_sse2, 10), - VarianceParams(6, 6, &vpx_highbd_8_variance64x64_sse2, 8), - VarianceParams(6, 5, &vpx_highbd_8_variance64x32_sse2, 8), - VarianceParams(5, 6, &vpx_highbd_8_variance32x64_sse2, 8), - VarianceParams(5, 5, &vpx_highbd_8_variance32x32_sse2, 8), - VarianceParams(5, 4, &vpx_highbd_8_variance32x16_sse2, 8), - VarianceParams(4, 5, &vpx_highbd_8_variance16x32_sse2, 8), - VarianceParams(4, 4, &vpx_highbd_8_variance16x16_sse2, 8), - VarianceParams(4, 3, &vpx_highbd_8_variance16x8_sse2, 8), - VarianceParams(3, 4, &vpx_highbd_8_variance8x16_sse2, 8), - VarianceParams(3, 3, &vpx_highbd_8_variance8x8_sse2, 8))); - -INSTANTIATE_TEST_SUITE_P( - SSE2, VpxHBDGetVarianceTest, - ::testing::Values( - GetVarianceParams(4, 4, &vpx_highbd_12_get16x16var_sse2, 12), - GetVarianceParams(3, 3, &vpx_highbd_12_get8x8var_sse2, 12), - GetVarianceParams(4, 4, &vpx_highbd_10_get16x16var_sse2, 10), - GetVarianceParams(3, 3, &vpx_highbd_10_get8x8var_sse2, 10), - GetVarianceParams(4, 4, &vpx_highbd_8_get16x16var_sse2, 8), - GetVarianceParams(3, 3, &vpx_highbd_8_get8x8var_sse2, 8))); - -INSTANTIATE_TEST_SUITE_P( - SSE2, VpxHBDSubpelVarianceTest, - ::testing::Values( - SubpelVarianceParams(6, 6, &vpx_highbd_12_sub_pixel_variance64x64_sse2, - 12), - SubpelVarianceParams(6, 5, &vpx_highbd_12_sub_pixel_variance64x32_sse2, - 12), - SubpelVarianceParams(5, 6, &vpx_highbd_12_sub_pixel_variance32x64_sse2, - 12), - SubpelVarianceParams(5, 5, &vpx_highbd_12_sub_pixel_variance32x32_sse2, - 12), - SubpelVarianceParams(5, 4, &vpx_highbd_12_sub_pixel_variance32x16_sse2, - 12), - SubpelVarianceParams(4, 5, &vpx_highbd_12_sub_pixel_variance16x32_sse2, - 12), - SubpelVarianceParams(4, 4, &vpx_highbd_12_sub_pixel_variance16x16_sse2, - 12), - SubpelVarianceParams(4, 3, &vpx_highbd_12_sub_pixel_variance16x8_sse2, - 12), - SubpelVarianceParams(3, 4, &vpx_highbd_12_sub_pixel_variance8x16_sse2, - 12), - SubpelVarianceParams(3, 3, &vpx_highbd_12_sub_pixel_variance8x8_sse2, - 12), - SubpelVarianceParams(3, 2, &vpx_highbd_12_sub_pixel_variance8x4_sse2, - 12), - SubpelVarianceParams(6, 6, &vpx_highbd_10_sub_pixel_variance64x64_sse2, - 10), - SubpelVarianceParams(6, 5, &vpx_highbd_10_sub_pixel_variance64x32_sse2, - 10), - SubpelVarianceParams(5, 6, &vpx_highbd_10_sub_pixel_variance32x64_sse2, - 10), - SubpelVarianceParams(5, 5, &vpx_highbd_10_sub_pixel_variance32x32_sse2, - 10), - SubpelVarianceParams(5, 4, &vpx_highbd_10_sub_pixel_variance32x16_sse2, - 10), - SubpelVarianceParams(4, 5, &vpx_highbd_10_sub_pixel_variance16x32_sse2, - 10), - SubpelVarianceParams(4, 4, &vpx_highbd_10_sub_pixel_variance16x16_sse2, - 10), - SubpelVarianceParams(4, 3, &vpx_highbd_10_sub_pixel_variance16x8_sse2, - 10), - SubpelVarianceParams(3, 4, &vpx_highbd_10_sub_pixel_variance8x16_sse2, - 10), - SubpelVarianceParams(3, 3, &vpx_highbd_10_sub_pixel_variance8x8_sse2, - 10), - SubpelVarianceParams(3, 2, &vpx_highbd_10_sub_pixel_variance8x4_sse2, - 10), - SubpelVarianceParams(6, 6, &vpx_highbd_8_sub_pixel_variance64x64_sse2, - 8), - SubpelVarianceParams(6, 5, &vpx_highbd_8_sub_pixel_variance64x32_sse2, - 8), - SubpelVarianceParams(5, 6, &vpx_highbd_8_sub_pixel_variance32x64_sse2, - 8), - SubpelVarianceParams(5, 5, &vpx_highbd_8_sub_pixel_variance32x32_sse2, - 8), - SubpelVarianceParams(5, 4, &vpx_highbd_8_sub_pixel_variance32x16_sse2, - 8), - SubpelVarianceParams(4, 5, &vpx_highbd_8_sub_pixel_variance16x32_sse2, - 8), - SubpelVarianceParams(4, 4, &vpx_highbd_8_sub_pixel_variance16x16_sse2, - 8), - SubpelVarianceParams(4, 3, &vpx_highbd_8_sub_pixel_variance16x8_sse2, - 8), - SubpelVarianceParams(3, 4, &vpx_highbd_8_sub_pixel_variance8x16_sse2, - 8), - SubpelVarianceParams(3, 3, &vpx_highbd_8_sub_pixel_variance8x8_sse2, 8), - SubpelVarianceParams(3, 2, &vpx_highbd_8_sub_pixel_variance8x4_sse2, - 8))); - -INSTANTIATE_TEST_SUITE_P( - SSE2, VpxHBDSubpelAvgVarianceTest, - ::testing::Values( - SubpelAvgVarianceParams(6, 6, - &vpx_highbd_12_sub_pixel_avg_variance64x64_sse2, - 12), - SubpelAvgVarianceParams(6, 5, - &vpx_highbd_12_sub_pixel_avg_variance64x32_sse2, - 12), - SubpelAvgVarianceParams(5, 6, - &vpx_highbd_12_sub_pixel_avg_variance32x64_sse2, - 12), - SubpelAvgVarianceParams(5, 5, - &vpx_highbd_12_sub_pixel_avg_variance32x32_sse2, - 12), - SubpelAvgVarianceParams(5, 4, - &vpx_highbd_12_sub_pixel_avg_variance32x16_sse2, - 12), - SubpelAvgVarianceParams(4, 5, - &vpx_highbd_12_sub_pixel_avg_variance16x32_sse2, - 12), - SubpelAvgVarianceParams(4, 4, - &vpx_highbd_12_sub_pixel_avg_variance16x16_sse2, - 12), - SubpelAvgVarianceParams(4, 3, - &vpx_highbd_12_sub_pixel_avg_variance16x8_sse2, - 12), - SubpelAvgVarianceParams(3, 4, - &vpx_highbd_12_sub_pixel_avg_variance8x16_sse2, - 12), - SubpelAvgVarianceParams(3, 3, - &vpx_highbd_12_sub_pixel_avg_variance8x8_sse2, - 12), - SubpelAvgVarianceParams(3, 2, - &vpx_highbd_12_sub_pixel_avg_variance8x4_sse2, - 12), - SubpelAvgVarianceParams(6, 6, - &vpx_highbd_10_sub_pixel_avg_variance64x64_sse2, - 10), - SubpelAvgVarianceParams(6, 5, - &vpx_highbd_10_sub_pixel_avg_variance64x32_sse2, - 10), - SubpelAvgVarianceParams(5, 6, - &vpx_highbd_10_sub_pixel_avg_variance32x64_sse2, - 10), - SubpelAvgVarianceParams(5, 5, - &vpx_highbd_10_sub_pixel_avg_variance32x32_sse2, - 10), - SubpelAvgVarianceParams(5, 4, - &vpx_highbd_10_sub_pixel_avg_variance32x16_sse2, - 10), - SubpelAvgVarianceParams(4, 5, - &vpx_highbd_10_sub_pixel_avg_variance16x32_sse2, - 10), - SubpelAvgVarianceParams(4, 4, - &vpx_highbd_10_sub_pixel_avg_variance16x16_sse2, - 10), - SubpelAvgVarianceParams(4, 3, - &vpx_highbd_10_sub_pixel_avg_variance16x8_sse2, - 10), - SubpelAvgVarianceParams(3, 4, - &vpx_highbd_10_sub_pixel_avg_variance8x16_sse2, - 10), - SubpelAvgVarianceParams(3, 3, - &vpx_highbd_10_sub_pixel_avg_variance8x8_sse2, - 10), - SubpelAvgVarianceParams(3, 2, - &vpx_highbd_10_sub_pixel_avg_variance8x4_sse2, - 10), - SubpelAvgVarianceParams(6, 6, - &vpx_highbd_8_sub_pixel_avg_variance64x64_sse2, - 8), - SubpelAvgVarianceParams(6, 5, - &vpx_highbd_8_sub_pixel_avg_variance64x32_sse2, - 8), - SubpelAvgVarianceParams(5, 6, - &vpx_highbd_8_sub_pixel_avg_variance32x64_sse2, - 8), - SubpelAvgVarianceParams(5, 5, - &vpx_highbd_8_sub_pixel_avg_variance32x32_sse2, - 8), - SubpelAvgVarianceParams(5, 4, - &vpx_highbd_8_sub_pixel_avg_variance32x16_sse2, - 8), - SubpelAvgVarianceParams(4, 5, - &vpx_highbd_8_sub_pixel_avg_variance16x32_sse2, - 8), - SubpelAvgVarianceParams(4, 4, - &vpx_highbd_8_sub_pixel_avg_variance16x16_sse2, - 8), - SubpelAvgVarianceParams(4, 3, - &vpx_highbd_8_sub_pixel_avg_variance16x8_sse2, - 8), - SubpelAvgVarianceParams(3, 4, - &vpx_highbd_8_sub_pixel_avg_variance8x16_sse2, - 8), - SubpelAvgVarianceParams(3, 3, - &vpx_highbd_8_sub_pixel_avg_variance8x8_sse2, - 8), - SubpelAvgVarianceParams(3, 2, - &vpx_highbd_8_sub_pixel_avg_variance8x4_sse2, - 8))); -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif // HAVE_SSE2 - -#if HAVE_SSSE3 -INSTANTIATE_TEST_SUITE_P( - SSSE3, VpxSubpelVarianceTest, - ::testing::Values( - SubpelVarianceParams(6, 6, &vpx_sub_pixel_variance64x64_ssse3, 0), - SubpelVarianceParams(6, 5, &vpx_sub_pixel_variance64x32_ssse3, 0), - SubpelVarianceParams(5, 6, &vpx_sub_pixel_variance32x64_ssse3, 0), - SubpelVarianceParams(5, 5, &vpx_sub_pixel_variance32x32_ssse3, 0), - SubpelVarianceParams(5, 4, &vpx_sub_pixel_variance32x16_ssse3, 0), - SubpelVarianceParams(4, 5, &vpx_sub_pixel_variance16x32_ssse3, 0), - SubpelVarianceParams(4, 4, &vpx_sub_pixel_variance16x16_ssse3, 0), - SubpelVarianceParams(4, 3, &vpx_sub_pixel_variance16x8_ssse3, 0), - SubpelVarianceParams(3, 4, &vpx_sub_pixel_variance8x16_ssse3, 0), - SubpelVarianceParams(3, 3, &vpx_sub_pixel_variance8x8_ssse3, 0), - SubpelVarianceParams(3, 2, &vpx_sub_pixel_variance8x4_ssse3, 0), - SubpelVarianceParams(2, 3, &vpx_sub_pixel_variance4x8_ssse3, 0), - SubpelVarianceParams(2, 2, &vpx_sub_pixel_variance4x4_ssse3, 0))); - -INSTANTIATE_TEST_SUITE_P( - SSSE3, VpxSubpelAvgVarianceTest, - ::testing::Values( - SubpelAvgVarianceParams(6, 6, &vpx_sub_pixel_avg_variance64x64_ssse3, - 0), - SubpelAvgVarianceParams(6, 5, &vpx_sub_pixel_avg_variance64x32_ssse3, - 0), - SubpelAvgVarianceParams(5, 6, &vpx_sub_pixel_avg_variance32x64_ssse3, - 0), - SubpelAvgVarianceParams(5, 5, &vpx_sub_pixel_avg_variance32x32_ssse3, - 0), - SubpelAvgVarianceParams(5, 4, &vpx_sub_pixel_avg_variance32x16_ssse3, - 0), - SubpelAvgVarianceParams(4, 5, &vpx_sub_pixel_avg_variance16x32_ssse3, - 0), - SubpelAvgVarianceParams(4, 4, &vpx_sub_pixel_avg_variance16x16_ssse3, - 0), - SubpelAvgVarianceParams(4, 3, &vpx_sub_pixel_avg_variance16x8_ssse3, 0), - SubpelAvgVarianceParams(3, 4, &vpx_sub_pixel_avg_variance8x16_ssse3, 0), - SubpelAvgVarianceParams(3, 3, &vpx_sub_pixel_avg_variance8x8_ssse3, 0), - SubpelAvgVarianceParams(3, 2, &vpx_sub_pixel_avg_variance8x4_ssse3, 0), - SubpelAvgVarianceParams(2, 3, &vpx_sub_pixel_avg_variance4x8_ssse3, 0), - SubpelAvgVarianceParams(2, 2, &vpx_sub_pixel_avg_variance4x4_ssse3, - 0))); -#endif // HAVE_SSSE3 - -#if HAVE_AVX2 -INSTANTIATE_TEST_SUITE_P(AVX2, VpxMseTest, - ::testing::Values(MseParams(4, 4, &vpx_mse16x16_avx2), - MseParams(4, 3, &vpx_mse16x8_avx2))); - -INSTANTIATE_TEST_SUITE_P( - AVX2, VpxVarianceTest, - ::testing::Values(VarianceParams(6, 6, &vpx_variance64x64_avx2), - VarianceParams(6, 5, &vpx_variance64x32_avx2), - VarianceParams(5, 6, &vpx_variance32x64_avx2), - VarianceParams(5, 5, &vpx_variance32x32_avx2), - VarianceParams(5, 4, &vpx_variance32x16_avx2), - VarianceParams(4, 5, &vpx_variance16x32_avx2), - VarianceParams(4, 4, &vpx_variance16x16_avx2), - VarianceParams(4, 3, &vpx_variance16x8_avx2), - VarianceParams(3, 4, &vpx_variance8x16_avx2), - VarianceParams(3, 3, &vpx_variance8x8_avx2), - VarianceParams(3, 2, &vpx_variance8x4_avx2))); - -INSTANTIATE_TEST_SUITE_P( - AVX2, VpxSubpelVarianceTest, - ::testing::Values( - SubpelVarianceParams(6, 6, &vpx_sub_pixel_variance64x64_avx2, 0), - SubpelVarianceParams(5, 5, &vpx_sub_pixel_variance32x32_avx2, 0))); - -INSTANTIATE_TEST_SUITE_P( - AVX2, VpxSubpelAvgVarianceTest, - ::testing::Values( - SubpelAvgVarianceParams(6, 6, &vpx_sub_pixel_avg_variance64x64_avx2, 0), - SubpelAvgVarianceParams(5, 5, &vpx_sub_pixel_avg_variance32x32_avx2, - 0))); -#endif // HAVE_AVX2 - -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P(NEON, VpxSseTest, - ::testing::Values(SseParams(2, 2, - &vpx_get4x4sse_cs_neon))); - -INSTANTIATE_TEST_SUITE_P(NEON, VpxMseTest, - ::testing::Values(MseParams(4, 4, &vpx_mse16x16_neon), - MseParams(4, 3, &vpx_mse16x8_neon), - MseParams(3, 4, &vpx_mse8x16_neon), - MseParams(3, 3, &vpx_mse8x8_neon))); - -INSTANTIATE_TEST_SUITE_P( - NEON, VpxVarianceTest, - ::testing::Values(VarianceParams(6, 6, &vpx_variance64x64_neon), - VarianceParams(6, 5, &vpx_variance64x32_neon), - VarianceParams(5, 6, &vpx_variance32x64_neon), - VarianceParams(5, 5, &vpx_variance32x32_neon), - VarianceParams(5, 4, &vpx_variance32x16_neon), - VarianceParams(4, 5, &vpx_variance16x32_neon), - VarianceParams(4, 4, &vpx_variance16x16_neon), - VarianceParams(4, 3, &vpx_variance16x8_neon), - VarianceParams(3, 4, &vpx_variance8x16_neon), - VarianceParams(3, 3, &vpx_variance8x8_neon), - VarianceParams(3, 2, &vpx_variance8x4_neon), - VarianceParams(2, 3, &vpx_variance4x8_neon), - VarianceParams(2, 2, &vpx_variance4x4_neon))); - -INSTANTIATE_TEST_SUITE_P( - NEON, VpxGetVarianceTest, - ::testing::Values(GetVarianceParams(4, 4, &vpx_get16x16var_neon), - GetVarianceParams(3, 3, &vpx_get8x8var_neon), - GetVarianceParams(4, 4, &vpx_get16x16var_neon), - GetVarianceParams(3, 3, &vpx_get8x8var_neon), - GetVarianceParams(4, 4, &vpx_get16x16var_neon), - GetVarianceParams(3, 3, &vpx_get8x8var_neon))); - -#if HAVE_NEON_DOTPROD -INSTANTIATE_TEST_SUITE_P( - NEON_DOTPROD, VpxSseTest, - ::testing::Values(SseParams(2, 2, &vpx_get4x4sse_cs_neon_dotprod))); - -INSTANTIATE_TEST_SUITE_P( - NEON_DOTPROD, VpxMseTest, - ::testing::Values(MseParams(4, 4, &vpx_mse16x16_neon_dotprod), - MseParams(4, 3, &vpx_mse16x8_neon_dotprod), - MseParams(3, 4, &vpx_mse8x16_neon_dotprod), - MseParams(3, 3, &vpx_mse8x8_neon_dotprod))); - -INSTANTIATE_TEST_SUITE_P( - NEON_DOTPROD, VpxVarianceTest, - ::testing::Values(VarianceParams(6, 6, &vpx_variance64x64_neon_dotprod), - VarianceParams(6, 5, &vpx_variance64x32_neon_dotprod), - VarianceParams(5, 6, &vpx_variance32x64_neon_dotprod), - VarianceParams(5, 5, &vpx_variance32x32_neon_dotprod), - VarianceParams(5, 4, &vpx_variance32x16_neon_dotprod), - VarianceParams(4, 5, &vpx_variance16x32_neon_dotprod), - VarianceParams(4, 4, &vpx_variance16x16_neon_dotprod), - VarianceParams(4, 3, &vpx_variance16x8_neon_dotprod), - VarianceParams(3, 4, &vpx_variance8x16_neon_dotprod), - VarianceParams(3, 3, &vpx_variance8x8_neon_dotprod), - VarianceParams(3, 2, &vpx_variance8x4_neon_dotprod), - VarianceParams(2, 3, &vpx_variance4x8_neon_dotprod), - VarianceParams(2, 2, &vpx_variance4x4_neon_dotprod))); - -INSTANTIATE_TEST_SUITE_P( - NEON_DOTPROD, VpxGetVarianceTest, - ::testing::Values(GetVarianceParams(4, 4, &vpx_get16x16var_neon_dotprod), - GetVarianceParams(3, 3, &vpx_get8x8var_neon_dotprod), - GetVarianceParams(4, 4, &vpx_get16x16var_neon_dotprod), - GetVarianceParams(3, 3, &vpx_get8x8var_neon_dotprod), - GetVarianceParams(4, 4, &vpx_get16x16var_neon_dotprod), - GetVarianceParams(3, 3, &vpx_get8x8var_neon_dotprod))); -#endif // HAVE_NEON_DOTPROD - -INSTANTIATE_TEST_SUITE_P( - NEON, VpxSubpelVarianceTest, - ::testing::Values( - SubpelVarianceParams(6, 6, &vpx_sub_pixel_variance64x64_neon, 0), - SubpelVarianceParams(6, 5, &vpx_sub_pixel_variance64x32_neon, 0), - SubpelVarianceParams(5, 6, &vpx_sub_pixel_variance32x64_neon, 0), - SubpelVarianceParams(5, 5, &vpx_sub_pixel_variance32x32_neon, 0), - SubpelVarianceParams(5, 4, &vpx_sub_pixel_variance32x16_neon, 0), - SubpelVarianceParams(4, 5, &vpx_sub_pixel_variance16x32_neon, 0), - SubpelVarianceParams(4, 4, &vpx_sub_pixel_variance16x16_neon, 0), - SubpelVarianceParams(4, 3, &vpx_sub_pixel_variance16x8_neon, 0), - SubpelVarianceParams(3, 4, &vpx_sub_pixel_variance8x16_neon, 0), - SubpelVarianceParams(3, 3, &vpx_sub_pixel_variance8x8_neon, 0), - SubpelVarianceParams(3, 2, &vpx_sub_pixel_variance8x4_neon, 0), - SubpelVarianceParams(2, 3, &vpx_sub_pixel_variance4x8_neon, 0), - SubpelVarianceParams(2, 2, &vpx_sub_pixel_variance4x4_neon, 0))); - -INSTANTIATE_TEST_SUITE_P( - NEON, VpxSubpelAvgVarianceTest, - ::testing::Values( - SubpelAvgVarianceParams(6, 6, &vpx_sub_pixel_avg_variance64x64_neon, 0), - SubpelAvgVarianceParams(6, 5, &vpx_sub_pixel_avg_variance64x32_neon, 0), - SubpelAvgVarianceParams(5, 6, &vpx_sub_pixel_avg_variance32x64_neon, 0), - SubpelAvgVarianceParams(5, 5, &vpx_sub_pixel_avg_variance32x32_neon, 0), - SubpelAvgVarianceParams(5, 4, &vpx_sub_pixel_avg_variance32x16_neon, 0), - SubpelAvgVarianceParams(4, 5, &vpx_sub_pixel_avg_variance16x32_neon, 0), - SubpelAvgVarianceParams(4, 4, &vpx_sub_pixel_avg_variance16x16_neon, 0), - SubpelAvgVarianceParams(4, 3, &vpx_sub_pixel_avg_variance16x8_neon, 0), - SubpelAvgVarianceParams(3, 4, &vpx_sub_pixel_avg_variance8x16_neon, 0), - SubpelAvgVarianceParams(3, 3, &vpx_sub_pixel_avg_variance8x8_neon, 0), - SubpelAvgVarianceParams(3, 2, &vpx_sub_pixel_avg_variance8x4_neon, 0), - SubpelAvgVarianceParams(2, 3, &vpx_sub_pixel_avg_variance4x8_neon, 0), - SubpelAvgVarianceParams(2, 2, &vpx_sub_pixel_avg_variance4x4_neon, 0))); - -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - NEON, VpxHBDMseTest, - ::testing::Values( - MseParams(4, 4, &vpx_highbd_12_mse16x16_neon, VPX_BITS_12), - MseParams(4, 3, &vpx_highbd_12_mse16x8_neon, VPX_BITS_12), - MseParams(3, 4, &vpx_highbd_12_mse8x16_neon, VPX_BITS_12), - MseParams(3, 3, &vpx_highbd_12_mse8x8_neon, VPX_BITS_12), - MseParams(4, 4, &vpx_highbd_10_mse16x16_neon, VPX_BITS_10), - MseParams(4, 3, &vpx_highbd_10_mse16x8_neon, VPX_BITS_10), - MseParams(3, 4, &vpx_highbd_10_mse8x16_neon, VPX_BITS_10), - MseParams(3, 3, &vpx_highbd_10_mse8x8_neon, VPX_BITS_10), - MseParams(4, 4, &vpx_highbd_8_mse16x16_neon, VPX_BITS_8), - MseParams(4, 3, &vpx_highbd_8_mse16x8_neon, VPX_BITS_8), - MseParams(3, 4, &vpx_highbd_8_mse8x16_neon, VPX_BITS_8), - MseParams(3, 3, &vpx_highbd_8_mse8x8_neon, VPX_BITS_8))); - -#if HAVE_NEON_DOTPROD -INSTANTIATE_TEST_SUITE_P( - NEON_DOTPROD, VpxHBDMseTest, - ::testing::Values( - MseParams(4, 4, &vpx_highbd_8_mse16x16_neon_dotprod, VPX_BITS_8), - MseParams(4, 3, &vpx_highbd_8_mse16x8_neon_dotprod, VPX_BITS_8), - MseParams(3, 4, &vpx_highbd_8_mse8x16_neon_dotprod, VPX_BITS_8), - MseParams(3, 3, &vpx_highbd_8_mse8x8_neon_dotprod, VPX_BITS_8))); -#endif // HAVE_NEON_DOTPROD - -#if HAVE_SVE -INSTANTIATE_TEST_SUITE_P( - SVE, VpxHBDMseTest, - ::testing::Values(MseParams(4, 4, &vpx_highbd_12_mse16x16_sve, VPX_BITS_12), - MseParams(4, 3, &vpx_highbd_12_mse16x8_sve, VPX_BITS_12), - MseParams(3, 4, &vpx_highbd_12_mse8x16_sve, VPX_BITS_12), - MseParams(3, 3, &vpx_highbd_12_mse8x8_sve, VPX_BITS_12), - MseParams(4, 4, &vpx_highbd_10_mse16x16_sve, VPX_BITS_10), - MseParams(4, 3, &vpx_highbd_10_mse16x8_sve, VPX_BITS_10), - MseParams(3, 4, &vpx_highbd_10_mse8x16_sve, VPX_BITS_10), - MseParams(3, 3, &vpx_highbd_10_mse8x8_sve, VPX_BITS_10))); -#endif // HAVE_SVE - -INSTANTIATE_TEST_SUITE_P( - NEON, VpxHBDVarianceTest, - ::testing::Values( - VarianceParams(6, 6, &vpx_highbd_12_variance64x64_neon, 12), - VarianceParams(6, 5, &vpx_highbd_12_variance64x32_neon, 12), - VarianceParams(5, 6, &vpx_highbd_12_variance32x64_neon, 12), - VarianceParams(5, 5, &vpx_highbd_12_variance32x32_neon, 12), - VarianceParams(5, 4, &vpx_highbd_12_variance32x16_neon, 12), - VarianceParams(4, 5, &vpx_highbd_12_variance16x32_neon, 12), - VarianceParams(4, 4, &vpx_highbd_12_variance16x16_neon, 12), - VarianceParams(4, 3, &vpx_highbd_12_variance16x8_neon, 12), - VarianceParams(3, 4, &vpx_highbd_12_variance8x16_neon, 12), - VarianceParams(3, 3, &vpx_highbd_12_variance8x8_neon, 12), - VarianceParams(3, 2, &vpx_highbd_12_variance8x4_neon, 12), - VarianceParams(2, 3, &vpx_highbd_12_variance4x8_neon, 12), - VarianceParams(2, 2, &vpx_highbd_12_variance4x4_neon, 12), - VarianceParams(6, 6, &vpx_highbd_10_variance64x64_neon, 10), - VarianceParams(6, 5, &vpx_highbd_10_variance64x32_neon, 10), - VarianceParams(5, 6, &vpx_highbd_10_variance32x64_neon, 10), - VarianceParams(5, 5, &vpx_highbd_10_variance32x32_neon, 10), - VarianceParams(5, 4, &vpx_highbd_10_variance32x16_neon, 10), - VarianceParams(4, 5, &vpx_highbd_10_variance16x32_neon, 10), - VarianceParams(4, 4, &vpx_highbd_10_variance16x16_neon, 10), - VarianceParams(4, 3, &vpx_highbd_10_variance16x8_neon, 10), - VarianceParams(3, 4, &vpx_highbd_10_variance8x16_neon, 10), - VarianceParams(3, 3, &vpx_highbd_10_variance8x8_neon, 10), - VarianceParams(3, 2, &vpx_highbd_10_variance8x4_neon, 10), - VarianceParams(2, 3, &vpx_highbd_10_variance4x8_neon, 10), - VarianceParams(2, 2, &vpx_highbd_10_variance4x4_neon, 10), - VarianceParams(6, 6, &vpx_highbd_8_variance64x64_neon, 8), - VarianceParams(6, 5, &vpx_highbd_8_variance64x32_neon, 8), - VarianceParams(5, 6, &vpx_highbd_8_variance32x64_neon, 8), - VarianceParams(5, 5, &vpx_highbd_8_variance32x32_neon, 8), - VarianceParams(5, 4, &vpx_highbd_8_variance32x16_neon, 8), - VarianceParams(4, 5, &vpx_highbd_8_variance16x32_neon, 8), - VarianceParams(4, 4, &vpx_highbd_8_variance16x16_neon, 8), - VarianceParams(4, 3, &vpx_highbd_8_variance16x8_neon, 8), - VarianceParams(3, 4, &vpx_highbd_8_variance8x16_neon, 8), - VarianceParams(3, 3, &vpx_highbd_8_variance8x8_neon, 8), - VarianceParams(3, 2, &vpx_highbd_8_variance8x4_neon, 8), - VarianceParams(2, 3, &vpx_highbd_8_variance4x8_neon, 8), - VarianceParams(2, 2, &vpx_highbd_8_variance4x4_neon, 8))); - -INSTANTIATE_TEST_SUITE_P( - NEON, VpxHBDGetVarianceTest, - ::testing::Values( - GetVarianceParams(4, 4, &vpx_highbd_12_get16x16var_neon, 12), - GetVarianceParams(3, 3, &vpx_highbd_12_get8x8var_neon, 12), - GetVarianceParams(4, 4, &vpx_highbd_10_get16x16var_neon, 10), - GetVarianceParams(3, 3, &vpx_highbd_10_get8x8var_neon, 10), - GetVarianceParams(4, 4, &vpx_highbd_8_get16x16var_neon, 8), - GetVarianceParams(3, 3, &vpx_highbd_8_get8x8var_neon, 8))); - -#if HAVE_SVE -INSTANTIATE_TEST_SUITE_P( - SVE, VpxHBDGetVarianceTest, - ::testing::Values( - GetVarianceParams(4, 4, &vpx_highbd_12_get16x16var_sve, 12), - GetVarianceParams(3, 3, &vpx_highbd_12_get8x8var_sve, 12), - GetVarianceParams(4, 4, &vpx_highbd_10_get16x16var_sve, 10), - GetVarianceParams(3, 3, &vpx_highbd_10_get8x8var_sve, 10), - GetVarianceParams(4, 4, &vpx_highbd_8_get16x16var_sve, 8), - GetVarianceParams(3, 3, &vpx_highbd_8_get8x8var_sve, 8))); -#endif // HAVE_SVE - -INSTANTIATE_TEST_SUITE_P( - NEON, VpxHBDSubpelVarianceTest, - ::testing::Values( - SubpelVarianceParams(6, 6, &vpx_highbd_12_sub_pixel_variance64x64_neon, - 12), - SubpelVarianceParams(6, 5, &vpx_highbd_12_sub_pixel_variance64x32_neon, - 12), - SubpelVarianceParams(5, 6, &vpx_highbd_12_sub_pixel_variance32x64_neon, - 12), - SubpelVarianceParams(5, 5, &vpx_highbd_12_sub_pixel_variance32x32_neon, - 12), - SubpelVarianceParams(5, 4, &vpx_highbd_12_sub_pixel_variance32x16_neon, - 12), - SubpelVarianceParams(4, 5, &vpx_highbd_12_sub_pixel_variance16x32_neon, - 12), - SubpelVarianceParams(4, 4, &vpx_highbd_12_sub_pixel_variance16x16_neon, - 12), - SubpelVarianceParams(4, 3, &vpx_highbd_12_sub_pixel_variance16x8_neon, - 12), - SubpelVarianceParams(3, 4, &vpx_highbd_12_sub_pixel_variance8x16_neon, - 12), - SubpelVarianceParams(3, 3, &vpx_highbd_12_sub_pixel_variance8x8_neon, - 12), - SubpelVarianceParams(3, 2, &vpx_highbd_12_sub_pixel_variance8x4_neon, - 12), - SubpelVarianceParams(2, 3, &vpx_highbd_12_sub_pixel_variance4x8_neon, - 12), - SubpelVarianceParams(2, 2, &vpx_highbd_12_sub_pixel_variance4x4_neon, - 12), - SubpelVarianceParams(6, 6, &vpx_highbd_10_sub_pixel_variance64x64_neon, - 10), - SubpelVarianceParams(6, 5, &vpx_highbd_10_sub_pixel_variance64x32_neon, - 10), - SubpelVarianceParams(5, 6, &vpx_highbd_10_sub_pixel_variance32x64_neon, - 10), - SubpelVarianceParams(5, 5, &vpx_highbd_10_sub_pixel_variance32x32_neon, - 10), - SubpelVarianceParams(5, 4, &vpx_highbd_10_sub_pixel_variance32x16_neon, - 10), - SubpelVarianceParams(4, 5, &vpx_highbd_10_sub_pixel_variance16x32_neon, - 10), - SubpelVarianceParams(4, 4, &vpx_highbd_10_sub_pixel_variance16x16_neon, - 10), - SubpelVarianceParams(4, 3, &vpx_highbd_10_sub_pixel_variance16x8_neon, - 10), - SubpelVarianceParams(3, 4, &vpx_highbd_10_sub_pixel_variance8x16_neon, - 10), - SubpelVarianceParams(3, 3, &vpx_highbd_10_sub_pixel_variance8x8_neon, - 10), - SubpelVarianceParams(3, 2, &vpx_highbd_10_sub_pixel_variance8x4_neon, - 10), - SubpelVarianceParams(2, 3, &vpx_highbd_10_sub_pixel_variance4x8_neon, - 10), - SubpelVarianceParams(2, 2, &vpx_highbd_10_sub_pixel_variance4x4_neon, - 10), - SubpelVarianceParams(6, 6, &vpx_highbd_8_sub_pixel_variance64x64_neon, - 8), - SubpelVarianceParams(6, 5, &vpx_highbd_8_sub_pixel_variance64x32_neon, - 8), - SubpelVarianceParams(5, 6, &vpx_highbd_8_sub_pixel_variance32x64_neon, - 8), - SubpelVarianceParams(5, 5, &vpx_highbd_8_sub_pixel_variance32x32_neon, - 8), - SubpelVarianceParams(5, 4, &vpx_highbd_8_sub_pixel_variance32x16_neon, - 8), - SubpelVarianceParams(4, 5, &vpx_highbd_8_sub_pixel_variance16x32_neon, - 8), - SubpelVarianceParams(4, 4, &vpx_highbd_8_sub_pixel_variance16x16_neon, - 8), - SubpelVarianceParams(4, 3, &vpx_highbd_8_sub_pixel_variance16x8_neon, - 8), - SubpelVarianceParams(3, 4, &vpx_highbd_8_sub_pixel_variance8x16_neon, - 8), - SubpelVarianceParams(3, 3, &vpx_highbd_8_sub_pixel_variance8x8_neon, 8), - SubpelVarianceParams(3, 2, &vpx_highbd_8_sub_pixel_variance8x4_neon, 8), - SubpelVarianceParams(2, 3, &vpx_highbd_8_sub_pixel_variance4x8_neon, 8), - SubpelVarianceParams(2, 2, &vpx_highbd_8_sub_pixel_variance4x4_neon, - 8))); - -INSTANTIATE_TEST_SUITE_P( - NEON, VpxHBDSubpelAvgVarianceTest, - ::testing::Values( - SubpelAvgVarianceParams(6, 6, - &vpx_highbd_12_sub_pixel_avg_variance64x64_neon, - 12), - SubpelAvgVarianceParams(6, 5, - &vpx_highbd_12_sub_pixel_avg_variance64x32_neon, - 12), - SubpelAvgVarianceParams(5, 6, - &vpx_highbd_12_sub_pixel_avg_variance32x64_neon, - 12), - SubpelAvgVarianceParams(5, 5, - &vpx_highbd_12_sub_pixel_avg_variance32x32_neon, - 12), - SubpelAvgVarianceParams(5, 4, - &vpx_highbd_12_sub_pixel_avg_variance32x16_neon, - 12), - SubpelAvgVarianceParams(4, 5, - &vpx_highbd_12_sub_pixel_avg_variance16x32_neon, - 12), - SubpelAvgVarianceParams(4, 4, - &vpx_highbd_12_sub_pixel_avg_variance16x16_neon, - 12), - SubpelAvgVarianceParams(4, 3, - &vpx_highbd_12_sub_pixel_avg_variance16x8_neon, - 12), - SubpelAvgVarianceParams(3, 4, - &vpx_highbd_12_sub_pixel_avg_variance8x16_neon, - 12), - SubpelAvgVarianceParams(3, 3, - &vpx_highbd_12_sub_pixel_avg_variance8x8_neon, - 12), - SubpelAvgVarianceParams(3, 2, - &vpx_highbd_12_sub_pixel_avg_variance8x4_neon, - 12), - SubpelAvgVarianceParams(2, 3, - &vpx_highbd_12_sub_pixel_avg_variance4x8_neon, - 12), - SubpelAvgVarianceParams(2, 2, - &vpx_highbd_12_sub_pixel_avg_variance4x4_neon, - 12), - SubpelAvgVarianceParams(6, 6, - &vpx_highbd_10_sub_pixel_avg_variance64x64_neon, - 10), - SubpelAvgVarianceParams(6, 5, - &vpx_highbd_10_sub_pixel_avg_variance64x32_neon, - 10), - SubpelAvgVarianceParams(5, 6, - &vpx_highbd_10_sub_pixel_avg_variance32x64_neon, - 10), - SubpelAvgVarianceParams(5, 5, - &vpx_highbd_10_sub_pixel_avg_variance32x32_neon, - 10), - SubpelAvgVarianceParams(5, 4, - &vpx_highbd_10_sub_pixel_avg_variance32x16_neon, - 10), - SubpelAvgVarianceParams(4, 5, - &vpx_highbd_10_sub_pixel_avg_variance16x32_neon, - 10), - SubpelAvgVarianceParams(4, 4, - &vpx_highbd_10_sub_pixel_avg_variance16x16_neon, - 10), - SubpelAvgVarianceParams(4, 3, - &vpx_highbd_10_sub_pixel_avg_variance16x8_neon, - 10), - SubpelAvgVarianceParams(3, 4, - &vpx_highbd_10_sub_pixel_avg_variance8x16_neon, - 10), - SubpelAvgVarianceParams(3, 3, - &vpx_highbd_10_sub_pixel_avg_variance8x8_neon, - 10), - SubpelAvgVarianceParams(3, 2, - &vpx_highbd_10_sub_pixel_avg_variance8x4_neon, - 10), - SubpelAvgVarianceParams(2, 3, - &vpx_highbd_10_sub_pixel_avg_variance4x8_neon, - 10), - SubpelAvgVarianceParams(2, 2, - &vpx_highbd_10_sub_pixel_avg_variance4x4_neon, - 10), - SubpelAvgVarianceParams(6, 6, - &vpx_highbd_8_sub_pixel_avg_variance64x64_neon, - 8), - SubpelAvgVarianceParams(6, 5, - &vpx_highbd_8_sub_pixel_avg_variance64x32_neon, - 8), - SubpelAvgVarianceParams(5, 6, - &vpx_highbd_8_sub_pixel_avg_variance32x64_neon, - 8), - SubpelAvgVarianceParams(5, 5, - &vpx_highbd_8_sub_pixel_avg_variance32x32_neon, - 8), - SubpelAvgVarianceParams(5, 4, - &vpx_highbd_8_sub_pixel_avg_variance32x16_neon, - 8), - SubpelAvgVarianceParams(4, 5, - &vpx_highbd_8_sub_pixel_avg_variance16x32_neon, - 8), - SubpelAvgVarianceParams(4, 4, - &vpx_highbd_8_sub_pixel_avg_variance16x16_neon, - 8), - SubpelAvgVarianceParams(4, 3, - &vpx_highbd_8_sub_pixel_avg_variance16x8_neon, - 8), - SubpelAvgVarianceParams(3, 4, - &vpx_highbd_8_sub_pixel_avg_variance8x16_neon, - 8), - SubpelAvgVarianceParams(3, 3, - &vpx_highbd_8_sub_pixel_avg_variance8x8_neon, - 8), - SubpelAvgVarianceParams(3, 2, - &vpx_highbd_8_sub_pixel_avg_variance8x4_neon, - 8), - SubpelAvgVarianceParams(2, 3, - &vpx_highbd_8_sub_pixel_avg_variance4x8_neon, - 8), - SubpelAvgVarianceParams(2, 2, - &vpx_highbd_8_sub_pixel_avg_variance4x4_neon, - 8))); - -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif // HAVE_NEON - -#if HAVE_SVE -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - SVE, VpxHBDVarianceTest, - ::testing::Values( - VarianceParams(6, 6, &vpx_highbd_12_variance64x64_sve, 12), - VarianceParams(6, 5, &vpx_highbd_12_variance64x32_sve, 12), - VarianceParams(5, 6, &vpx_highbd_12_variance32x64_sve, 12), - VarianceParams(5, 5, &vpx_highbd_12_variance32x32_sve, 12), - VarianceParams(5, 4, &vpx_highbd_12_variance32x16_sve, 12), - VarianceParams(4, 5, &vpx_highbd_12_variance16x32_sve, 12), - VarianceParams(4, 4, &vpx_highbd_12_variance16x16_sve, 12), - VarianceParams(4, 3, &vpx_highbd_12_variance16x8_sve, 12), - VarianceParams(3, 4, &vpx_highbd_12_variance8x16_sve, 12), - VarianceParams(3, 3, &vpx_highbd_12_variance8x8_sve, 12), - VarianceParams(3, 2, &vpx_highbd_12_variance8x4_sve, 12), - VarianceParams(2, 3, &vpx_highbd_12_variance4x8_sve, 12), - VarianceParams(2, 2, &vpx_highbd_12_variance4x4_sve, 12), - VarianceParams(6, 6, &vpx_highbd_10_variance64x64_sve, 10), - VarianceParams(6, 5, &vpx_highbd_10_variance64x32_sve, 10), - VarianceParams(5, 6, &vpx_highbd_10_variance32x64_sve, 10), - VarianceParams(5, 5, &vpx_highbd_10_variance32x32_sve, 10), - VarianceParams(5, 4, &vpx_highbd_10_variance32x16_sve, 10), - VarianceParams(4, 5, &vpx_highbd_10_variance16x32_sve, 10), - VarianceParams(4, 4, &vpx_highbd_10_variance16x16_sve, 10), - VarianceParams(4, 3, &vpx_highbd_10_variance16x8_sve, 10), - VarianceParams(3, 4, &vpx_highbd_10_variance8x16_sve, 10), - VarianceParams(3, 3, &vpx_highbd_10_variance8x8_sve, 10), - VarianceParams(3, 2, &vpx_highbd_10_variance8x4_sve, 10), - VarianceParams(2, 3, &vpx_highbd_10_variance4x8_sve, 10), - VarianceParams(2, 2, &vpx_highbd_10_variance4x4_sve, 10), - VarianceParams(6, 6, &vpx_highbd_8_variance64x64_sve, 8), - VarianceParams(6, 5, &vpx_highbd_8_variance64x32_sve, 8), - VarianceParams(5, 6, &vpx_highbd_8_variance32x64_sve, 8), - VarianceParams(5, 5, &vpx_highbd_8_variance32x32_sve, 8), - VarianceParams(5, 4, &vpx_highbd_8_variance32x16_sve, 8), - VarianceParams(4, 5, &vpx_highbd_8_variance16x32_sve, 8), - VarianceParams(4, 4, &vpx_highbd_8_variance16x16_sve, 8), - VarianceParams(4, 3, &vpx_highbd_8_variance16x8_sve, 8), - VarianceParams(3, 4, &vpx_highbd_8_variance8x16_sve, 8), - VarianceParams(3, 3, &vpx_highbd_8_variance8x8_sve, 8), - VarianceParams(3, 2, &vpx_highbd_8_variance8x4_sve, 8), - VarianceParams(2, 3, &vpx_highbd_8_variance4x8_sve, 8), - VarianceParams(2, 2, &vpx_highbd_8_variance4x4_sve, 8))); -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif // HAVE_SVE - -#if HAVE_MSA -INSTANTIATE_TEST_SUITE_P(MSA, SumOfSquaresTest, - ::testing::Values(vpx_get_mb_ss_msa)); - -INSTANTIATE_TEST_SUITE_P(MSA, VpxSseTest, - ::testing::Values(SseParams(2, 2, - &vpx_get4x4sse_cs_msa))); - -INSTANTIATE_TEST_SUITE_P(MSA, VpxMseTest, - ::testing::Values(MseParams(4, 4, &vpx_mse16x16_msa), - MseParams(4, 3, &vpx_mse16x8_msa), - MseParams(3, 4, &vpx_mse8x16_msa), - MseParams(3, 3, &vpx_mse8x8_msa))); - -INSTANTIATE_TEST_SUITE_P( - MSA, VpxVarianceTest, - ::testing::Values(VarianceParams(6, 6, &vpx_variance64x64_msa), - VarianceParams(6, 5, &vpx_variance64x32_msa), - VarianceParams(5, 6, &vpx_variance32x64_msa), - VarianceParams(5, 5, &vpx_variance32x32_msa), - VarianceParams(5, 4, &vpx_variance32x16_msa), - VarianceParams(4, 5, &vpx_variance16x32_msa), - VarianceParams(4, 4, &vpx_variance16x16_msa), - VarianceParams(4, 3, &vpx_variance16x8_msa), - VarianceParams(3, 4, &vpx_variance8x16_msa), - VarianceParams(3, 3, &vpx_variance8x8_msa), - VarianceParams(3, 2, &vpx_variance8x4_msa), - VarianceParams(2, 3, &vpx_variance4x8_msa), - VarianceParams(2, 2, &vpx_variance4x4_msa))); - -INSTANTIATE_TEST_SUITE_P( - MSA, VpxGetVarianceTest, - ::testing::Values(GetVarianceParams(4, 4, &vpx_get16x16var_msa), - GetVarianceParams(3, 3, &vpx_get8x8var_msa), - GetVarianceParams(4, 4, &vpx_get16x16var_msa), - GetVarianceParams(3, 3, &vpx_get8x8var_msa), - GetVarianceParams(4, 4, &vpx_get16x16var_msa), - GetVarianceParams(3, 3, &vpx_get8x8var_msa))); - -INSTANTIATE_TEST_SUITE_P( - MSA, VpxSubpelVarianceTest, - ::testing::Values( - SubpelVarianceParams(2, 2, &vpx_sub_pixel_variance4x4_msa, 0), - SubpelVarianceParams(2, 3, &vpx_sub_pixel_variance4x8_msa, 0), - SubpelVarianceParams(3, 2, &vpx_sub_pixel_variance8x4_msa, 0), - SubpelVarianceParams(3, 3, &vpx_sub_pixel_variance8x8_msa, 0), - SubpelVarianceParams(3, 4, &vpx_sub_pixel_variance8x16_msa, 0), - SubpelVarianceParams(4, 3, &vpx_sub_pixel_variance16x8_msa, 0), - SubpelVarianceParams(4, 4, &vpx_sub_pixel_variance16x16_msa, 0), - SubpelVarianceParams(4, 5, &vpx_sub_pixel_variance16x32_msa, 0), - SubpelVarianceParams(5, 4, &vpx_sub_pixel_variance32x16_msa, 0), - SubpelVarianceParams(5, 5, &vpx_sub_pixel_variance32x32_msa, 0), - SubpelVarianceParams(5, 6, &vpx_sub_pixel_variance32x64_msa, 0), - SubpelVarianceParams(6, 5, &vpx_sub_pixel_variance64x32_msa, 0), - SubpelVarianceParams(6, 6, &vpx_sub_pixel_variance64x64_msa, 0))); - -INSTANTIATE_TEST_SUITE_P( - MSA, VpxSubpelAvgVarianceTest, - ::testing::Values( - SubpelAvgVarianceParams(6, 6, &vpx_sub_pixel_avg_variance64x64_msa, 0), - SubpelAvgVarianceParams(6, 5, &vpx_sub_pixel_avg_variance64x32_msa, 0), - SubpelAvgVarianceParams(5, 6, &vpx_sub_pixel_avg_variance32x64_msa, 0), - SubpelAvgVarianceParams(5, 5, &vpx_sub_pixel_avg_variance32x32_msa, 0), - SubpelAvgVarianceParams(5, 4, &vpx_sub_pixel_avg_variance32x16_msa, 0), - SubpelAvgVarianceParams(4, 5, &vpx_sub_pixel_avg_variance16x32_msa, 0), - SubpelAvgVarianceParams(4, 4, &vpx_sub_pixel_avg_variance16x16_msa, 0), - SubpelAvgVarianceParams(4, 3, &vpx_sub_pixel_avg_variance16x8_msa, 0), - SubpelAvgVarianceParams(3, 4, &vpx_sub_pixel_avg_variance8x16_msa, 0), - SubpelAvgVarianceParams(3, 3, &vpx_sub_pixel_avg_variance8x8_msa, 0), - SubpelAvgVarianceParams(3, 2, &vpx_sub_pixel_avg_variance8x4_msa, 0), - SubpelAvgVarianceParams(2, 3, &vpx_sub_pixel_avg_variance4x8_msa, 0), - SubpelAvgVarianceParams(2, 2, &vpx_sub_pixel_avg_variance4x4_msa, 0))); -#endif // HAVE_MSA - -#if HAVE_VSX -INSTANTIATE_TEST_SUITE_P(VSX, SumOfSquaresTest, - ::testing::Values(vpx_get_mb_ss_vsx)); - -INSTANTIATE_TEST_SUITE_P(VSX, VpxSseTest, - ::testing::Values(SseParams(2, 2, - &vpx_get4x4sse_cs_vsx))); -INSTANTIATE_TEST_SUITE_P(VSX, VpxMseTest, - ::testing::Values(MseParams(4, 4, &vpx_mse16x16_vsx), - MseParams(4, 3, &vpx_mse16x8_vsx), - MseParams(3, 4, &vpx_mse8x16_vsx), - MseParams(3, 3, &vpx_mse8x8_vsx))); - -INSTANTIATE_TEST_SUITE_P( - VSX, VpxVarianceTest, - ::testing::Values(VarianceParams(6, 6, &vpx_variance64x64_vsx), - VarianceParams(6, 5, &vpx_variance64x32_vsx), - VarianceParams(5, 6, &vpx_variance32x64_vsx), - VarianceParams(5, 5, &vpx_variance32x32_vsx), - VarianceParams(5, 4, &vpx_variance32x16_vsx), - VarianceParams(4, 5, &vpx_variance16x32_vsx), - VarianceParams(4, 4, &vpx_variance16x16_vsx), - VarianceParams(4, 3, &vpx_variance16x8_vsx), - VarianceParams(3, 4, &vpx_variance8x16_vsx), - VarianceParams(3, 3, &vpx_variance8x8_vsx), - VarianceParams(3, 2, &vpx_variance8x4_vsx), - VarianceParams(2, 3, &vpx_variance4x8_vsx), - VarianceParams(2, 2, &vpx_variance4x4_vsx))); - -INSTANTIATE_TEST_SUITE_P( - VSX, VpxGetVarianceTest, - ::testing::Values(GetVarianceParams(4, 4, &vpx_get16x16var_vsx), - GetVarianceParams(3, 3, &vpx_get8x8var_vsx), - GetVarianceParams(4, 4, &vpx_get16x16var_vsx), - GetVarianceParams(3, 3, &vpx_get8x8var_vsx), - GetVarianceParams(4, 4, &vpx_get16x16var_vsx), - GetVarianceParams(3, 3, &vpx_get8x8var_vsx))); -#endif // HAVE_VSX - -#if HAVE_MMI -INSTANTIATE_TEST_SUITE_P(MMI, VpxMseTest, - ::testing::Values(MseParams(4, 4, &vpx_mse16x16_mmi), - MseParams(4, 3, &vpx_mse16x8_mmi), - MseParams(3, 4, &vpx_mse8x16_mmi), - MseParams(3, 3, &vpx_mse8x8_mmi))); - -INSTANTIATE_TEST_SUITE_P( - MMI, VpxVarianceTest, - ::testing::Values(VarianceParams(6, 6, &vpx_variance64x64_mmi), - VarianceParams(6, 5, &vpx_variance64x32_mmi), - VarianceParams(5, 6, &vpx_variance32x64_mmi), - VarianceParams(5, 5, &vpx_variance32x32_mmi), - VarianceParams(5, 4, &vpx_variance32x16_mmi), - VarianceParams(4, 5, &vpx_variance16x32_mmi), - VarianceParams(4, 4, &vpx_variance16x16_mmi), - VarianceParams(4, 3, &vpx_variance16x8_mmi), - VarianceParams(3, 4, &vpx_variance8x16_mmi), - VarianceParams(3, 3, &vpx_variance8x8_mmi), - VarianceParams(3, 2, &vpx_variance8x4_mmi), - VarianceParams(2, 3, &vpx_variance4x8_mmi), - VarianceParams(2, 2, &vpx_variance4x4_mmi))); - -INSTANTIATE_TEST_SUITE_P( - MMI, VpxSubpelVarianceTest, - ::testing::Values( - SubpelVarianceParams(6, 6, &vpx_sub_pixel_variance64x64_mmi, 0), - SubpelVarianceParams(6, 5, &vpx_sub_pixel_variance64x32_mmi, 0), - SubpelVarianceParams(5, 6, &vpx_sub_pixel_variance32x64_mmi, 0), - SubpelVarianceParams(5, 5, &vpx_sub_pixel_variance32x32_mmi, 0), - SubpelVarianceParams(5, 4, &vpx_sub_pixel_variance32x16_mmi, 0), - SubpelVarianceParams(4, 5, &vpx_sub_pixel_variance16x32_mmi, 0), - SubpelVarianceParams(4, 4, &vpx_sub_pixel_variance16x16_mmi, 0), - SubpelVarianceParams(4, 3, &vpx_sub_pixel_variance16x8_mmi, 0), - SubpelVarianceParams(3, 4, &vpx_sub_pixel_variance8x16_mmi, 0), - SubpelVarianceParams(3, 3, &vpx_sub_pixel_variance8x8_mmi, 0), - SubpelVarianceParams(3, 2, &vpx_sub_pixel_variance8x4_mmi, 0), - SubpelVarianceParams(2, 3, &vpx_sub_pixel_variance4x8_mmi, 0), - SubpelVarianceParams(2, 2, &vpx_sub_pixel_variance4x4_mmi, 0))); - -INSTANTIATE_TEST_SUITE_P( - MMI, VpxSubpelAvgVarianceTest, - ::testing::Values( - SubpelAvgVarianceParams(6, 6, &vpx_sub_pixel_avg_variance64x64_mmi, 0), - SubpelAvgVarianceParams(6, 5, &vpx_sub_pixel_avg_variance64x32_mmi, 0), - SubpelAvgVarianceParams(5, 6, &vpx_sub_pixel_avg_variance32x64_mmi, 0), - SubpelAvgVarianceParams(5, 5, &vpx_sub_pixel_avg_variance32x32_mmi, 0), - SubpelAvgVarianceParams(5, 4, &vpx_sub_pixel_avg_variance32x16_mmi, 0), - SubpelAvgVarianceParams(4, 5, &vpx_sub_pixel_avg_variance16x32_mmi, 0), - SubpelAvgVarianceParams(4, 4, &vpx_sub_pixel_avg_variance16x16_mmi, 0), - SubpelAvgVarianceParams(4, 3, &vpx_sub_pixel_avg_variance16x8_mmi, 0), - SubpelAvgVarianceParams(3, 4, &vpx_sub_pixel_avg_variance8x16_mmi, 0), - SubpelAvgVarianceParams(3, 3, &vpx_sub_pixel_avg_variance8x8_mmi, 0), - SubpelAvgVarianceParams(3, 2, &vpx_sub_pixel_avg_variance8x4_mmi, 0), - SubpelAvgVarianceParams(2, 3, &vpx_sub_pixel_avg_variance4x8_mmi, 0), - SubpelAvgVarianceParams(2, 2, &vpx_sub_pixel_avg_variance4x4_mmi, 0))); -#endif // HAVE_MMI - -#if HAVE_LSX -INSTANTIATE_TEST_SUITE_P(LSX, VpxMseTest, - ::testing::Values(MseParams(4, 4, &vpx_mse16x16_lsx))); - -INSTANTIATE_TEST_SUITE_P( - LSX, VpxVarianceTest, - ::testing::Values(VarianceParams(6, 6, &vpx_variance64x64_lsx), - VarianceParams(5, 5, &vpx_variance32x32_lsx), - VarianceParams(4, 4, &vpx_variance16x16_lsx), - VarianceParams(3, 3, &vpx_variance8x8_lsx))); - -INSTANTIATE_TEST_SUITE_P( - LSX, VpxSubpelVarianceTest, - ::testing::Values( - SubpelVarianceParams(3, 3, &vpx_sub_pixel_variance8x8_lsx, 0), - SubpelVarianceParams(4, 4, &vpx_sub_pixel_variance16x16_lsx, 0), - SubpelVarianceParams(5, 5, &vpx_sub_pixel_variance32x32_lsx, 0))); - -INSTANTIATE_TEST_SUITE_P(LSX, VpxSubpelAvgVarianceTest, - ::testing::Values(SubpelAvgVarianceParams( - 6, 6, &vpx_sub_pixel_avg_variance64x64_lsx, 0))); -#endif -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/video_source.h b/presentation/src/main/cpp/third_party/libvpx/test/video_source.h deleted file mode 100644 index 419d1625..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/video_source.h +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_TEST_VIDEO_SOURCE_H_ -#define VPX_TEST_VIDEO_SOURCE_H_ - -#if defined(_WIN32) -#undef NOMINMAX -#define NOMINMAX -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#endif -#include -#include -#include -#include -#include - -#if !defined(_WIN32) -#include "gtest/gtest.h" -#endif -#include "test/acm_random.h" -#include "vpx/vpx_encoder.h" - -namespace libvpx_test { - -// Helper macros to ensure LIBVPX_TEST_DATA_PATH is a quoted string. -// These are undefined right below GetDataPath -// NOTE: LIBVPX_TEST_DATA_PATH MUST NOT be a quoted string before -// Stringification or the GetDataPath will fail at runtime -#define TO_STRING(S) #S -#define STRINGIFY(S) TO_STRING(S) - -// A simple function to encapsulate cross platform retrieval of test data path -static std::string GetDataPath() { - const char *const data_path = getenv("LIBVPX_TEST_DATA_PATH"); - if (data_path == nullptr) { -#ifdef LIBVPX_TEST_DATA_PATH - // In some environments, we cannot set environment variables - // Instead, we set the data path by using a preprocessor symbol - // which can be set from make files - return STRINGIFY(LIBVPX_TEST_DATA_PATH); -#else - return "."; -#endif - } - return data_path; -} - -// Undefining stringification macros because they are not used elsewhere -#undef TO_STRING -#undef STRINGIFY - -inline FILE *OpenTestDataFile(const std::string &file_name) { - const std::string path_to_source = GetDataPath() + "/" + file_name; - return fopen(path_to_source.c_str(), "rb"); -} - -static FILE *GetTempOutFile(std::string *file_name, const char *io_mode) { - file_name->clear(); -#if defined(_WIN32) - char fname[MAX_PATH]; - char tmppath[MAX_PATH]; - if (GetTempPathA(MAX_PATH, tmppath)) { - // Assume for now that the filename generated is unique per process - if (GetTempFileNameA(tmppath, "lvx", 0, fname)) { - file_name->assign(fname); - return fopen(fname, io_mode); - } - } - return nullptr; -#else - std::string temp_dir = testing::TempDir(); - if (temp_dir.empty()) return nullptr; - // Versions of testing::TempDir() prior to release-1.11.0-214-g5e6a5336 may - // use the value of an environment variable without checking for a trailing - // path delimiter. - if (temp_dir[temp_dir.size() - 1] != '/') temp_dir += '/'; - const char name_template[] = "libvpxtest.XXXXXX"; - std::unique_ptr temp_file_name( - new char[temp_dir.size() + sizeof(name_template)]); - if (temp_file_name == nullptr) return nullptr; - memcpy(temp_file_name.get(), temp_dir.data(), temp_dir.size()); - memcpy(temp_file_name.get() + temp_dir.size(), name_template, - sizeof(name_template)); - const int fd = mkstemp(temp_file_name.get()); - if (fd == -1) return nullptr; - *file_name = temp_file_name.get(); - return fdopen(fd, io_mode); -#endif -} - -class TempOutFile { - public: - TempOutFile() { file_ = GetTempOutFile(&file_name_, "wb+"); } - TempOutFile(const char *io_mode) { - file_ = GetTempOutFile(&file_name_, io_mode); - } - ~TempOutFile() { - CloseFile(); - if (!file_name_.empty()) { - EXPECT_EQ(0, remove(file_name_.c_str())); - } - } - FILE *file() { return file_; } - const std::string &file_name() { return file_name_; } - - protected: - void CloseFile() { - if (file_) { - fclose(file_); - file_ = nullptr; - } - } - FILE *file_; - std::string file_name_; -}; - -// Abstract base class for test video sources, which provide a stream of -// vpx_image_t images with associated timestamps and duration. -class VideoSource { - public: - virtual ~VideoSource() {} - - // Prepare the stream for reading, rewind/open as necessary. - virtual void Begin() = 0; - - // Advance the cursor to the next frame - virtual void Next() = 0; - - // Get the current video frame, or nullptr on End-Of-Stream. - virtual vpx_image_t *img() const = 0; - - // Get the presentation timestamp of the current frame. - virtual vpx_codec_pts_t pts() const = 0; - - // Get the current frame's duration - virtual unsigned long duration() const = 0; - - // Get the timebase for the stream - virtual vpx_rational_t timebase() const = 0; - - // Get the current frame counter, starting at 0. - virtual unsigned int frame() const = 0; - - // Get the current file limit. - virtual unsigned int limit() const = 0; -}; - -class DummyVideoSource : public VideoSource { - public: - DummyVideoSource() - : img_(nullptr), limit_(100), width_(80), height_(64), - format_(VPX_IMG_FMT_I420) { - ReallocImage(); - } - - ~DummyVideoSource() override { vpx_img_free(img_); } - - void Begin() override { - frame_ = 0; - FillFrame(); - } - - void Next() override { - ++frame_; - FillFrame(); - } - - vpx_image_t *img() const override { - return (frame_ < limit_) ? img_ : nullptr; - } - - // Models a stream where Timebase = 1/FPS, so pts == frame. - vpx_codec_pts_t pts() const override { return frame_; } - - unsigned long duration() const override { return 1; } - - vpx_rational_t timebase() const override { - const vpx_rational_t t = { 1, 30 }; - return t; - } - - unsigned int frame() const override { return frame_; } - - unsigned int limit() const override { return limit_; } - - void set_limit(unsigned int limit) { limit_ = limit; } - - void SetSize(unsigned int width, unsigned int height) { - if (width != width_ || height != height_) { - width_ = width; - height_ = height; - ReallocImage(); - } - } - - void SetImageFormat(vpx_img_fmt_t format) { - if (format_ != format) { - format_ = format; - ReallocImage(); - } - } - - protected: - virtual void FillFrame() { - if (img_) memset(img_->img_data, 0, raw_sz_); - } - - void ReallocImage() { - vpx_img_free(img_); - img_ = vpx_img_alloc(nullptr, format_, width_, height_, 32); - ASSERT_NE(img_, nullptr); - raw_sz_ = ((img_->w + 31) & ~31u) * img_->h * img_->bps / 8; - } - - vpx_image_t *img_; - size_t raw_sz_; - unsigned int limit_; - unsigned int frame_; - unsigned int width_; - unsigned int height_; - vpx_img_fmt_t format_; -}; - -class RandomVideoSource : public DummyVideoSource { - public: - RandomVideoSource(int seed = ACMRandom::DeterministicSeed()) - : rnd_(seed), seed_(seed) {} - - // Reset the RNG to get a matching stream for the second pass - void Begin() override { - frame_ = 0; - rnd_.Reset(seed_); - FillFrame(); - } - - protected: - // 15 frames of noise, followed by 15 static frames. Reset to 0 rather - // than holding previous frames to encourage keyframes to be thrown. - void FillFrame() override { - if (img_) { - if (frame_ % 30 < 15) { - for (size_t i = 0; i < raw_sz_; ++i) img_->img_data[i] = rnd_.Rand8(); - } else { - memset(img_->img_data, 0, raw_sz_); - } - } - } - - ACMRandom rnd_; - int seed_; -}; - -// Abstract base class for test video sources, which provide a stream of -// decompressed images to the decoder. -class CompressedVideoSource { - public: - virtual ~CompressedVideoSource() {} - - virtual void Init() = 0; - - // Prepare the stream for reading, rewind/open as necessary. - virtual void Begin() = 0; - - // Advance the cursor to the next frame - virtual void Next() = 0; - - virtual const uint8_t *cxdata() const = 0; - - virtual size_t frame_size() const = 0; - - virtual unsigned int frame_number() const = 0; -}; - -} // namespace libvpx_test - -#endif // VPX_TEST_VIDEO_SOURCE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp8_boolcoder_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp8_boolcoder_test.cc deleted file mode 100644 index 0e2c7b77..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp8_boolcoder_test.cc +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "test/acm_random.h" -#include "vp8/decoder/dboolhuff.h" -#include "vp8/encoder/boolhuff.h" -#include "vpx/vpx_integer.h" - -namespace { -const int num_tests = 10; - -// In a real use the 'decrypt_state' parameter will be a pointer to a struct -// with whatever internal state the decryptor uses. For testing we'll just -// xor with a constant key, and decrypt_state will point to the start of -// the original buffer. -const uint8_t secret_key[16] = { - 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, - 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0 -}; - -void encrypt_buffer(uint8_t *buffer, size_t size) { - for (size_t i = 0; i < size; ++i) { - buffer[i] ^= secret_key[i & 15]; - } -} - -void test_decrypt_cb(void *decrypt_state, const uint8_t *input, uint8_t *output, - int count) { - const size_t offset = input - reinterpret_cast(decrypt_state); - for (int i = 0; i < count; i++) { - output[i] = input[i] ^ secret_key[(offset + i) & 15]; - } -} - -} // namespace - -using libvpx_test::ACMRandom; - -TEST(VP8, TestBitIO) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - for (int n = 0; n < num_tests; ++n) { - for (int method = 0; method <= 7; ++method) { // we generate various proba - const int kBitsToTest = 1000; - uint8_t probas[kBitsToTest]; - - for (int i = 0; i < kBitsToTest; ++i) { - const int parity = i & 1; - /* clang-format off */ - probas[i] = - (method == 0) ? 0 : (method == 1) ? 255 : - (method == 2) ? 128 : - (method == 3) ? rnd.Rand8() : - (method == 4) ? (parity ? 0 : 255) : - // alternate between low and high proba: - (method == 5) ? (parity ? rnd(128) : 255 - rnd(128)) : - (method == 6) ? - (parity ? rnd(64) : 255 - rnd(64)) : - (parity ? rnd(32) : 255 - rnd(32)); - /* clang-format on */ - } - for (int bit_method = 0; bit_method <= 3; ++bit_method) { - const int random_seed = 6432; - const int kBufferSize = 10000; - ACMRandom bit_rnd(random_seed); - BOOL_CODER bw; - uint8_t bw_buffer[kBufferSize]; - vp8_start_encode(&bw, bw_buffer, bw_buffer + kBufferSize); - - int bit = (bit_method == 0) ? 0 : (bit_method == 1) ? 1 : 0; - for (int i = 0; i < kBitsToTest; ++i) { - if (bit_method == 2) { - bit = (i & 1); - } else if (bit_method == 3) { - bit = bit_rnd(2); - } - vp8_encode_bool(&bw, bit, static_cast(probas[i])); - } - - vp8_stop_encode(&bw); - // vp8dx_bool_decoder_fill() may read into uninitialized data that - // isn't used meaningfully, but may trigger an MSan warning. - memset(bw_buffer + bw.pos, 0, sizeof(VP8_BD_VALUE) - 1); - - BOOL_DECODER br; - encrypt_buffer(bw_buffer, kBufferSize); - vp8dx_start_decode(&br, bw_buffer, kBufferSize, test_decrypt_cb, - reinterpret_cast(bw_buffer)); - bit_rnd.Reset(random_seed); - for (int i = 0; i < kBitsToTest; ++i) { - if (bit_method == 2) { - bit = (i & 1); - } else if (bit_method == 3) { - bit = bit_rnd(2); - } - GTEST_ASSERT_EQ(vp8dx_decode_bool(&br, probas[i]), bit) - << "pos: " << i << " / " << kBitsToTest - << " bit_method: " << bit_method << " method: " << method; - } - } - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp8_datarate_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp8_datarate_test.cc deleted file mode 100644 index 4b464949..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp8_datarate_test.cc +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "./vpx_config.h" -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" -#include "test/y4m_video_source.h" -#include "vpx/vpx_encoder.h" - -namespace { - -class DatarateTestLarge - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith2Params { - public: - DatarateTestLarge() : EncoderTest(GET_PARAM(0)) {} - - ~DatarateTestLarge() override = default; - - protected: - void SetUp() override { - InitializeConfig(); - SetMode(GET_PARAM(1)); - set_cpu_used_ = GET_PARAM(2); - ResetModel(); - } - - virtual void ResetModel() { - last_pts_ = 0; - bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz; - frame_number_ = 0; - first_drop_ = 0; - bits_total_ = 0; - duration_ = 0.0; - denoiser_offon_test_ = 0; - denoiser_offon_period_ = -1; - gf_boost_ = 0; - use_roi_ = false; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_); - encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_); - encoder->Control(VP8E_SET_GF_CBR_BOOST_PCT, gf_boost_); - } - - if (use_roi_) { - encoder->Control(VP8E_SET_ROI_MAP, &roi_); - } - - if (denoiser_offon_test_) { - ASSERT_GT(denoiser_offon_period_, 0) - << "denoiser_offon_period_ is not positive."; - if ((video->frame() + 1) % denoiser_offon_period_ == 0) { - // Flip denoiser_on_ periodically - denoiser_on_ ^= 1; - } - encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_); - } - - const vpx_rational_t tb = video->timebase(); - timebase_ = static_cast(tb.num) / tb.den; - duration_ = 0; - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - // Time since last timestamp = duration. - vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_; - - // TODO(jimbankoski): Remove these lines when the issue: - // http://code.google.com/p/webm/issues/detail?id=496 is fixed. - // For now the codec assumes buffer starts at starting buffer rate - // plus one frame's time. - if (last_pts_ == 0) duration = 1; - - // Add to the buffer the bits we'd expect from a constant bitrate server. - bits_in_buffer_model_ += static_cast( - duration * timebase_ * cfg_.rc_target_bitrate * 1000); - - /* Test the buffer model here before subtracting the frame. Do so because - * the way the leaky bucket model works in libvpx is to allow the buffer to - * empty - and then stop showing frames until we've got enough bits to - * show one. As noted in comment below (issue 495), this does not currently - * apply to key frames. For now exclude key frames in condition below. */ - const bool key_frame = - (pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false; - if (!key_frame) { - ASSERT_GE(bits_in_buffer_model_, 0) - << "Buffer Underrun at frame " << pkt->data.frame.pts; - } - - const int64_t frame_size_in_bits = pkt->data.frame.sz * 8; - - // Subtract from the buffer the bits associated with a played back frame. - bits_in_buffer_model_ -= frame_size_in_bits; - - // Update the running total of bits for end of test datarate checks. - bits_total_ += frame_size_in_bits; - - // If first drop not set and we have a drop set it to this time. - if (!first_drop_ && duration > 1) first_drop_ = last_pts_ + 1; - - // Update the most recent pts. - last_pts_ = pkt->data.frame.pts; - - // We update this so that we can calculate the datarate minus the last - // frame encoded in the file. - bits_in_last_frame_ = frame_size_in_bits; - - ++frame_number_; - } - - void EndPassHook() override { - if (bits_total_) { - const double file_size_in_kb = bits_total_ / 1000.; // bits per kilobit - - duration_ = (last_pts_ + 1) * timebase_; - - // Effective file datarate includes the time spent prebuffering. - effective_datarate_ = (bits_total_ - bits_in_last_frame_) / 1000.0 / - (cfg_.rc_buf_initial_sz / 1000.0 + duration_); - - file_datarate_ = file_size_in_kb / duration_; - } - } - - virtual void DenoiserLevelsTest() { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_dropframe_thresh = 1; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, - 288, 30, 1, 0, 140); - for (int j = 1; j < 5; ++j) { - // Run over the denoiser levels. - // For the temporal denoiser (#if CONFIG_TEMPORAL_DENOISING) the level j - // refers to the 4 denoiser modes: denoiserYonly, denoiserOnYUV, - // denoiserOnAggressive, and denoiserOnAdaptive. - denoiser_on_ = j; - cfg_.rc_target_bitrate = 300; - ResetModel(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95) - << " The datarate for the file exceeds the target!"; - - ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4) - << " The datarate for the file missed the target!"; - } - } - - virtual void DenoiserOffOnTest() { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_dropframe_thresh = 1; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, - 288, 30, 1, 0, 299); - cfg_.rc_target_bitrate = 300; - ResetModel(); - // The denoiser is off by default. - denoiser_on_ = 0; - // Set the offon test flag. - denoiser_offon_test_ = 1; - denoiser_offon_period_ = 100; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95) - << " The datarate for the file exceeds the target!"; - ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4) - << " The datarate for the file missed the target!"; - } - - virtual void BasicBufferModelTest() { - denoiser_on_ = 0; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_dropframe_thresh = 1; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - // 2 pass cbr datarate control has a bug hidden by the small # of - // frames selected in this encode. The problem is that even if the buffer is - // negative we produce a keyframe on a cutscene. Ignoring datarate - // constraints - // TODO(jimbankoski): ( Fix when issue - // http://code.google.com/p/webm/issues/detail?id=495 is addressed. ) - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, - 288, 30, 1, 0, 140); - - // There is an issue for low bitrates in real-time mode, where the - // effective_datarate slightly overshoots the target bitrate. - // This is same the issue as noted about (#495). - // TODO(jimbankoski/marpan): Update test to run for lower bitrates (< 100), - // when the issue is resolved. - for (int i = 100; i < 800; i += 200) { - cfg_.rc_target_bitrate = i; - ResetModel(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95) - << " The datarate for the file exceeds the target!"; - ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4) - << " The datarate for the file missed the target!"; - } - } - - virtual void ChangingDropFrameThreshTest() { - denoiser_on_ = 0; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_max_quantizer = 36; - cfg_.rc_end_usage = VPX_CBR; - cfg_.rc_target_bitrate = 200; - cfg_.kf_mode = VPX_KF_DISABLED; - - const int frame_count = 40; - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, - 288, 30, 1, 0, frame_count); - - // Here we check that the first dropped frame gets earlier and earlier - // as the drop frame threshold is increased. - - const int kDropFrameThreshTestStep = 30; - vpx_codec_pts_t last_drop = frame_count; - for (int i = 1; i < 91; i += kDropFrameThreshTestStep) { - cfg_.rc_dropframe_thresh = i; - ResetModel(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_LE(first_drop_, last_drop) - << " The first dropped frame for drop_thresh " << i - << " > first dropped frame for drop_thresh " - << i - kDropFrameThreshTestStep; - last_drop = first_drop_; - } - } - - virtual void DropFramesMultiThreadsTest() { - denoiser_on_ = 0; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_dropframe_thresh = 30; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_threads = 2; - - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, - 288, 30, 1, 0, 140); - cfg_.rc_target_bitrate = 200; - ResetModel(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95) - << " The datarate for the file exceeds the target!"; - - ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4) - << " The datarate for the file missed the target!"; - } - - virtual void MultiThreadsPSNRTest() { - denoiser_on_ = 0; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_dropframe_thresh = 0; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_threads = 4; - init_flags_ = VPX_CODEC_USE_PSNR; - - ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", - 1280, 720, 30, 1, 0, 30); - cfg_.rc_target_bitrate = 1000; - ResetModel(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.5) - << " The datarate for the file exceeds the target!"; - - ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 2.0) - << " The datarate for the file missed the target!"; - } - - vpx_codec_pts_t last_pts_; - int64_t bits_in_buffer_model_; - double timebase_; - int frame_number_; - vpx_codec_pts_t first_drop_; - int64_t bits_total_; - double duration_; - double file_datarate_; - double effective_datarate_; - int64_t bits_in_last_frame_; - int denoiser_on_; - int denoiser_offon_test_; - int denoiser_offon_period_; - int set_cpu_used_; - int gf_boost_; - bool use_roi_; - vpx_roi_map_t roi_; -}; - -#if CONFIG_TEMPORAL_DENOISING -// Check basic datarate targeting, for a single bitrate, but loop over the -// various denoiser settings. -TEST_P(DatarateTestLarge, DenoiserLevels) { DenoiserLevelsTest(); } - -// Check basic datarate targeting, for a single bitrate, when denoiser is off -// and on. -TEST_P(DatarateTestLarge, DenoiserOffOn) { DenoiserOffOnTest(); } -#endif // CONFIG_TEMPORAL_DENOISING - -TEST_P(DatarateTestLarge, BasicBufferModel) { BasicBufferModelTest(); } - -TEST_P(DatarateTestLarge, ChangingDropFrameThresh) { - ChangingDropFrameThreshTest(); -} - -TEST_P(DatarateTestLarge, DropFramesMultiThreads) { - DropFramesMultiThreadsTest(); -} - -class DatarateTestRealTime : public DatarateTestLarge { - public: - ~DatarateTestRealTime() override = default; -}; - -#if CONFIG_TEMPORAL_DENOISING -// Check basic datarate targeting, for a single bitrate, but loop over the -// various denoiser settings. -TEST_P(DatarateTestRealTime, DenoiserLevels) { DenoiserLevelsTest(); } - -// Check basic datarate targeting, for a single bitrate, when denoiser is off -// and on. -TEST_P(DatarateTestRealTime, DenoiserOffOn) {} -#endif // CONFIG_TEMPORAL_DENOISING - -TEST_P(DatarateTestRealTime, BasicBufferModel) { BasicBufferModelTest(); } - -TEST_P(DatarateTestRealTime, ChangingDropFrameThresh) { - ChangingDropFrameThreshTest(); -} - -TEST_P(DatarateTestRealTime, DropFramesMultiThreads) { - DropFramesMultiThreadsTest(); -} - -TEST_P(DatarateTestRealTime, MultiThreadsPSNR) { MultiThreadsPSNRTest(); } - -TEST_P(DatarateTestRealTime, RegionOfInterest) { - denoiser_on_ = 0; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_dropframe_thresh = 0; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - // Encode using multiple threads. - cfg_.g_threads = 2; - - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 300); - cfg_.rc_target_bitrate = 450; - cfg_.g_w = 352; - cfg_.g_h = 288; - - ResetModel(); - - // Set ROI parameters - use_roi_ = true; - memset(&roi_, 0, sizeof(roi_)); - - roi_.rows = (cfg_.g_h + 15) / 16; - roi_.cols = (cfg_.g_w + 15) / 16; - - roi_.delta_q[0] = 0; - roi_.delta_q[1] = -20; - roi_.delta_q[2] = 0; - roi_.delta_q[3] = 0; - - roi_.delta_lf[0] = 0; - roi_.delta_lf[1] = -20; - roi_.delta_lf[2] = 0; - roi_.delta_lf[3] = 0; - - roi_.static_threshold[0] = 0; - roi_.static_threshold[1] = 1000; - roi_.static_threshold[2] = 0; - roi_.static_threshold[3] = 0; - - // Use 2 states: 1 is center square, 0 is the rest. - roi_.roi_map = - (uint8_t *)calloc(roi_.rows * roi_.cols, sizeof(*roi_.roi_map)); - for (unsigned int i = 0; i < roi_.rows; ++i) { - for (unsigned int j = 0; j < roi_.cols; ++j) { - if (i > (roi_.rows >> 2) && i < ((roi_.rows * 3) >> 2) && - j > (roi_.cols >> 2) && j < ((roi_.cols * 3) >> 2)) { - roi_.roi_map[i * roi_.cols + j] = 1; - } - } - } - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95) - << " The datarate for the file exceeds the target!"; - - ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4) - << " The datarate for the file missed the target!"; - - free(roi_.roi_map); -} - -TEST_P(DatarateTestRealTime, GFBoost) { - denoiser_on_ = 0; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_dropframe_thresh = 0; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_error_resilient = 0; - - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 300); - cfg_.rc_target_bitrate = 300; - ResetModel(); - // Apply a gf boost. - gf_boost_ = 50; - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95) - << " The datarate for the file exceeds the target!"; - - ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4) - << " The datarate for the file missed the target!"; -} - -TEST_P(DatarateTestRealTime, NV12) { - denoiser_on_ = 0; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_dropframe_thresh = 0; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_error_resilient = 0; - ::libvpx_test::YUVVideoSource video("hantro_collage_w352h288_nv12.yuv", - VPX_IMG_FMT_NV12, 352, 288, 30, 1, 0, - 100); - - cfg_.rc_target_bitrate = 200; - ResetModel(); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95) - << " The datarate for the file exceeds the target!"; - - ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4) - << " The datarate for the file missed the target!"; -} - -VP8_INSTANTIATE_TEST_SUITE(DatarateTestLarge, ALL_TEST_MODES, - ::testing::Values(0)); -VP8_INSTANTIATE_TEST_SUITE(DatarateTestRealTime, - ::testing::Values(::libvpx_test::kRealTime), - ::testing::Values(-6, -12)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp8_decrypt_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp8_decrypt_test.cc deleted file mode 100644 index e00620b1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp8_decrypt_test.cc +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/ivf_video_source.h" - -namespace { -// In a real use the 'decrypt_state' parameter will be a pointer to a struct -// with whatever internal state the decryptor uses. For testing we'll just -// xor with a constant key, and decrypt_state will point to the start of -// the original buffer. -const uint8_t test_key[16] = { 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, - 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0 }; - -void encrypt_buffer(const uint8_t *src, uint8_t *dst, size_t size, - ptrdiff_t offset) { - for (size_t i = 0; i < size; ++i) { - dst[i] = src[i] ^ test_key[(offset + i) & 15]; - } -} - -void test_decrypt_cb(void *decrypt_state, const uint8_t *input, uint8_t *output, - int count) { - encrypt_buffer(input, output, count, - input - reinterpret_cast(decrypt_state)); -} - -} // namespace - -namespace libvpx_test { - -TEST(TestDecrypt, DecryptWorksVp8) { - libvpx_test::IVFVideoSource video("vp80-00-comprehensive-001.ivf"); - video.Init(); - - vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t(); - VP8Decoder decoder(dec_cfg, 0); - - video.Begin(); - - // no decryption - vpx_codec_err_t res = decoder.DecodeFrame(video.cxdata(), video.frame_size()); - ASSERT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError(); - - // decrypt frame - video.Next(); - - std::vector encrypted(video.frame_size()); - encrypt_buffer(video.cxdata(), &encrypted[0], video.frame_size(), 0); - vpx_decrypt_init di = { test_decrypt_cb, &encrypted[0] }; - decoder.Control(VPXD_SET_DECRYPTOR, &di); - - res = decoder.DecodeFrame(&encrypted[0], encrypted.size()); - ASSERT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError(); -} - -} // namespace libvpx_test diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp8_denoiser_sse2_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp8_denoiser_sse2_test.cc deleted file mode 100644 index 6c68355d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp8_denoiser_sse2_test.cc +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "gtest/gtest.h" -#include "test/acm_random.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" - -#include "vp8/encoder/denoising.h" -#include "vp8/common/reconinter.h" -#include "vpx/vpx_integer.h" -#include "vpx_config.h" -#include "vpx_mem/vpx_mem.h" - -using libvpx_test::ACMRandom; - -namespace { - -const int kNumPixels = 16 * 16; -class VP8DenoiserTest : public ::testing::TestWithParam { - public: - ~VP8DenoiserTest() override = default; - - void SetUp() override { increase_denoising_ = GetParam(); } - - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - int increase_denoising_; -}; - -// TODO(https://crbug.com/webm/1718): This test fails with gcc 8-10. -#if defined(__GNUC__) && __GNUC__ >= 8 -TEST_P(VP8DenoiserTest, DISABLED_BitexactCheck) { -#else -TEST_P(VP8DenoiserTest, BitexactCheck) { -#endif - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 4000; - const int stride = 16; - - // Allocate the space for input and output, - // where sig_block_c/_sse2 is the block to be denoised, - // mc_avg_block is the denoised reference block, - // avg_block_c is the denoised result from C code, - // avg_block_sse2 is the denoised result from SSE2 code. - DECLARE_ALIGNED(16, uint8_t, sig_block_c[kNumPixels]); - // Since in VP8 denoiser, the source signal will be changed, - // we need another copy of the source signal as the input of sse2 code. - DECLARE_ALIGNED(16, uint8_t, sig_block_sse2[kNumPixels]); - DECLARE_ALIGNED(16, uint8_t, mc_avg_block[kNumPixels]); - DECLARE_ALIGNED(16, uint8_t, avg_block_c[kNumPixels]); - DECLARE_ALIGNED(16, uint8_t, avg_block_sse2[kNumPixels]); - - for (int i = 0; i < count_test_block; ++i) { - // Generate random motion magnitude, 20% of which exceed the threshold. - const int motion_magnitude_ran = - rnd.Rand8() % static_cast(MOTION_MAGNITUDE_THRESHOLD * 1.2); - - // Initialize a test block with random number in range [0, 255]. - for (int j = 0; j < kNumPixels; ++j) { - int temp = 0; - sig_block_sse2[j] = sig_block_c[j] = rnd.Rand8(); - // The pixels in mc_avg_block are generated by adding a random - // number in range [-19, 19] to corresponding pixels in sig_block. - temp = - sig_block_c[j] + (rnd.Rand8() % 2 == 0 ? -1 : 1) * (rnd.Rand8() % 20); - // Clip. - mc_avg_block[j] = (temp < 0) ? 0 : ((temp > 255) ? 255 : temp); - } - - // Test denosiser on Y component. - ASM_REGISTER_STATE_CHECK(vp8_denoiser_filter_c( - mc_avg_block, stride, avg_block_c, stride, sig_block_c, stride, - motion_magnitude_ran, increase_denoising_)); - - ASM_REGISTER_STATE_CHECK(vp8_denoiser_filter_sse2( - mc_avg_block, stride, avg_block_sse2, stride, sig_block_sse2, stride, - motion_magnitude_ran, increase_denoising_)); - - // Check bitexactness. - for (int h = 0; h < 16; ++h) { - for (int w = 0; w < 16; ++w) { - ASSERT_EQ(avg_block_c[h * stride + w], avg_block_sse2[h * stride + w]); - } - } - - // Test denoiser on UV component. - ASM_REGISTER_STATE_CHECK(vp8_denoiser_filter_uv_c( - mc_avg_block, stride, avg_block_c, stride, sig_block_c, stride, - motion_magnitude_ran, increase_denoising_)); - - ASM_REGISTER_STATE_CHECK(vp8_denoiser_filter_uv_sse2( - mc_avg_block, stride, avg_block_sse2, stride, sig_block_sse2, stride, - motion_magnitude_ran, increase_denoising_)); - - // Check bitexactness. - for (int h = 0; h < 16; ++h) { - for (int w = 0; w < 16; ++w) { - ASSERT_EQ(avg_block_c[h * stride + w], avg_block_sse2[h * stride + w]); - } - } - } -} - -// Test for all block size. -INSTANTIATE_TEST_SUITE_P(SSE2, VP8DenoiserTest, ::testing::Values(0, 1)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp8_fdct4x4_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp8_fdct4x4_test.cc deleted file mode 100644 index a7c05ac9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp8_fdct4x4_test.cc +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vpx_config.h" -#include "./vp8_rtcd.h" -#include "test/acm_random.h" -#include "vpx/vpx_integer.h" -#include "vpx_ports/mem.h" - -namespace { - -typedef void (*FdctFunc)(int16_t *a, int16_t *b, int a_stride); - -const int cospi8sqrt2minus1 = 20091; -const int sinpi8sqrt2 = 35468; - -void reference_idct4x4(const int16_t *input, int16_t *output) { - const int16_t *ip = input; - int16_t *op = output; - - for (int i = 0; i < 4; ++i) { - const int a1 = ip[0] + ip[8]; - const int b1 = ip[0] - ip[8]; - const int temp1 = (ip[4] * sinpi8sqrt2) >> 16; - const int temp2 = ip[12] + ((ip[12] * cospi8sqrt2minus1) >> 16); - const int c1 = temp1 - temp2; - const int temp3 = ip[4] + ((ip[4] * cospi8sqrt2minus1) >> 16); - const int temp4 = (ip[12] * sinpi8sqrt2) >> 16; - const int d1 = temp3 + temp4; - op[0] = a1 + d1; - op[12] = a1 - d1; - op[4] = b1 + c1; - op[8] = b1 - c1; - ++ip; - ++op; - } - ip = output; - op = output; - for (int i = 0; i < 4; ++i) { - const int a1 = ip[0] + ip[2]; - const int b1 = ip[0] - ip[2]; - const int temp1 = (ip[1] * sinpi8sqrt2) >> 16; - const int temp2 = ip[3] + ((ip[3] * cospi8sqrt2minus1) >> 16); - const int c1 = temp1 - temp2; - const int temp3 = ip[1] + ((ip[1] * cospi8sqrt2minus1) >> 16); - const int temp4 = (ip[3] * sinpi8sqrt2) >> 16; - const int d1 = temp3 + temp4; - op[0] = (a1 + d1 + 4) >> 3; - op[3] = (a1 - d1 + 4) >> 3; - op[1] = (b1 + c1 + 4) >> 3; - op[2] = (b1 - c1 + 4) >> 3; - ip += 4; - op += 4; - } -} - -using libvpx_test::ACMRandom; - -class FdctTest : public ::testing::TestWithParam { - public: - void SetUp() override { - fdct_func_ = GetParam(); - rnd_.Reset(ACMRandom::DeterministicSeed()); - } - - protected: - FdctFunc fdct_func_; - ACMRandom rnd_; -}; - -TEST_P(FdctTest, SignBiasCheck) { - int16_t test_input_block[16]; - DECLARE_ALIGNED(16, int16_t, test_output_block[16]); - const int pitch = 8; - int count_sign_block[16][2]; - const int count_test_block = 1000000; - - memset(count_sign_block, 0, sizeof(count_sign_block)); - - for (int i = 0; i < count_test_block; ++i) { - // Initialize a test block with input range [-255, 255]. - for (int j = 0; j < 16; ++j) { - test_input_block[j] = rnd_.Rand8() - rnd_.Rand8(); - } - - fdct_func_(test_input_block, test_output_block, pitch); - - for (int j = 0; j < 16; ++j) { - if (test_output_block[j] < 0) { - ++count_sign_block[j][0]; - } else if (test_output_block[j] > 0) { - ++count_sign_block[j][1]; - } - } - } - - bool bias_acceptable = true; - for (int j = 0; j < 16; ++j) { - bias_acceptable = - bias_acceptable && - (abs(count_sign_block[j][0] - count_sign_block[j][1]) < 10000); - } - - EXPECT_EQ(true, bias_acceptable) - << "Error: 4x4 FDCT has a sign bias > 1% for input range [-255, 255]"; - - memset(count_sign_block, 0, sizeof(count_sign_block)); - - for (int i = 0; i < count_test_block; ++i) { - // Initialize a test block with input range [-15, 15]. - for (int j = 0; j < 16; ++j) { - test_input_block[j] = (rnd_.Rand8() >> 4) - (rnd_.Rand8() >> 4); - } - - fdct_func_(test_input_block, test_output_block, pitch); - - for (int j = 0; j < 16; ++j) { - if (test_output_block[j] < 0) { - ++count_sign_block[j][0]; - } else if (test_output_block[j] > 0) { - ++count_sign_block[j][1]; - } - } - } - - bias_acceptable = true; - for (int j = 0; j < 16; ++j) { - bias_acceptable = - bias_acceptable && - (abs(count_sign_block[j][0] - count_sign_block[j][1]) < 100000); - } - - EXPECT_EQ(true, bias_acceptable) - << "Error: 4x4 FDCT has a sign bias > 10% for input range [-15, 15]"; -} - -TEST_P(FdctTest, RoundTripErrorCheck) { - int max_error = 0; - double total_error = 0; - const int count_test_block = 1000000; - for (int i = 0; i < count_test_block; ++i) { - int16_t test_input_block[16]; - int16_t test_output_block[16]; - DECLARE_ALIGNED(16, int16_t, test_temp_block[16]); - - // Initialize a test block with input range [-255, 255]. - for (int j = 0; j < 16; ++j) { - test_input_block[j] = rnd_.Rand8() - rnd_.Rand8(); - } - - const int pitch = 8; - fdct_func_(test_input_block, test_temp_block, pitch); - reference_idct4x4(test_temp_block, test_output_block); - - for (int j = 0; j < 16; ++j) { - const int diff = test_input_block[j] - test_output_block[j]; - const int error = diff * diff; - if (max_error < error) max_error = error; - total_error += error; - } - } - - EXPECT_GE(1, max_error) - << "Error: FDCT/IDCT has an individual roundtrip error > 1"; - - EXPECT_GE(count_test_block, total_error) - << "Error: FDCT/IDCT has average roundtrip error > 1 per block"; -} - -INSTANTIATE_TEST_SUITE_P(C, FdctTest, ::testing::Values(vp8_short_fdct4x4_c)); - -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P(NEON, FdctTest, - ::testing::Values(vp8_short_fdct4x4_neon)); -#endif // HAVE_NEON - -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P(SSE2, FdctTest, - ::testing::Values(vp8_short_fdct4x4_sse2)); -#endif // HAVE_SSE2 - -#if HAVE_MSA -INSTANTIATE_TEST_SUITE_P(MSA, FdctTest, - ::testing::Values(vp8_short_fdct4x4_msa)); -#endif // HAVE_MSA -#if HAVE_MMI -INSTANTIATE_TEST_SUITE_P(MMI, FdctTest, - ::testing::Values(vp8_short_fdct4x4_mmi)); -#endif // HAVE_MMI - -#if HAVE_LSX -INSTANTIATE_TEST_SUITE_P(LSX, FdctTest, - ::testing::Values(vp8_short_fdct4x4_lsx)); -#endif // HAVE_LSX -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp8_fragments_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp8_fragments_test.cc deleted file mode 100644 index 1f13cde8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp8_fragments_test.cc +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/video_source.h" - -namespace { - -class VP8FragmentsTest : public ::libvpx_test::EncoderTest, - public ::testing::Test { - protected: - VP8FragmentsTest() : EncoderTest(&::libvpx_test::kVP8) {} - ~VP8FragmentsTest() override = default; - - void SetUp() override { - const unsigned long init_flags = // NOLINT(runtime/int) - VPX_CODEC_USE_OUTPUT_PARTITION; - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - set_init_flags(init_flags); - } -}; - -TEST_F(VP8FragmentsTest, TestFragmentsEncodeDecode) { - ::libvpx_test::RandomVideoSource video; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp8_multi_resolution_encoder.sh b/presentation/src/main/cpp/third_party/libvpx/test/vp8_multi_resolution_encoder.sh deleted file mode 100644 index 1e96f94c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp8_multi_resolution_encoder.sh +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2014 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## This file tests the libvpx vp8_multi_resolution_encoder example. To add new -## tests to this file, do the following: -## 1. Write a shell function (this is your test). -## 2. Add the function to vp8_mre_tests (on a new line). -## -. $(dirname $0)/tools_common.sh - -# Environment check: $YUV_RAW_INPUT is required. -vp8_multi_resolution_encoder_verify_environment() { - if [ "$(vpx_config_option_enabled CONFIG_MULTI_RES_ENCODING)" = "yes" ]; then - if [ ! -e "${YUV_RAW_INPUT}" ]; then - elog "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH." - return 1 - fi - local app="vp8_multi_resolution_encoder" - if [ -z "$(vpx_tool_path "${app}")" ]; then - elog "${app} not found. It must exist in LIBVPX_BIN_PATH or its parent." - return 1 - fi - fi -} - -# Runs vp8_multi_resolution_encoder. Simply forwards all arguments to -# vp8_multi_resolution_encoder after building path to the executable. -vp8_mre() { - local encoder="$(vpx_tool_path vp8_multi_resolution_encoder)" - if [ ! -x "${encoder}" ]; then - elog "${encoder} does not exist or is not executable." - return 1 - fi - - eval "${VPX_TEST_PREFIX}" "${encoder}" "$@" ${devnull} -} - -vp8_multi_resolution_encoder_three_formats() { - local output_files="${VPX_TEST_OUTPUT_DIR}/vp8_mre_0.ivf - ${VPX_TEST_OUTPUT_DIR}/vp8_mre_1.ivf - ${VPX_TEST_OUTPUT_DIR}/vp8_mre_2.ivf" - local layer_bitrates="150 80 50" - local keyframe_insert="200" - local temporal_layers="3 3 3" - local framerate="30" - - if [ "$(vpx_config_option_enabled CONFIG_MULTI_RES_ENCODING)" = "yes" ]; then - if [ "$(vp8_encode_available)" = "yes" ]; then - # Param order: - # Input width - # Input height - # Framerate - # Input file path - # Output file names - # Layer bitrates - # Temporal layers - # Keyframe insert - # Output PSNR - vp8_mre "${YUV_RAW_INPUT_WIDTH}" \ - "${YUV_RAW_INPUT_HEIGHT}" \ - "${framerate}" \ - "${YUV_RAW_INPUT}" \ - ${output_files} \ - ${layer_bitrates} \ - ${temporal_layers} \ - "${keyframe_insert}" \ - 0 || return 1 - - for output_file in ${output_files}; do - if [ ! -e "${output_file}" ]; then - elog "Missing output file: ${output_file}" - return 1 - fi - done - fi - fi -} - -vp8_mre_tests="vp8_multi_resolution_encoder_three_formats" -run_tests vp8_multi_resolution_encoder_verify_environment "${vp8_mre_tests}" diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp8_ratectrl_rtc_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp8_ratectrl_rtc_test.cc deleted file mode 100644 index 74a8cde7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp8_ratectrl_rtc_test.cc +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright (c) 2021 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // NOLINT -#include - -#include "./vpx_config.h" -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" -#include "test/video_source.h" -#include "vp8/vp8_ratectrl_rtc.h" -#include "vpx/vpx_codec.h" -#include "vpx_ports/bitops.h" - -namespace { - -struct Vp8RCTestVideo { - Vp8RCTestVideo() = default; - Vp8RCTestVideo(const char *name_, int width_, int height_, - unsigned int frames_) - : name(name_), width(width_), height(height_), frames(frames_) {} - - friend std::ostream &operator<<(std::ostream &os, - const Vp8RCTestVideo &video) { - os << video.name << " " << video.width << " " << video.height << " " - << video.frames; - return os; - } - const char *name; - int width; - int height; - unsigned int frames; -}; - -const Vp8RCTestVideo kVp8RCTestVectors[] = { - Vp8RCTestVideo("niklas_640_480_30.yuv", 640, 480, 470), - Vp8RCTestVideo("desktop_office1.1280_720-020.yuv", 1280, 720, 300), - Vp8RCTestVideo("hantro_collage_w352h288.yuv", 352, 288, 100), -}; - -class Vp8RcInterfaceTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith2Params { - public: - Vp8RcInterfaceTest() - : EncoderTest(GET_PARAM(0)), key_interval_(3000), encoder_exit_(false), - frame_drop_thresh_(0) {} - ~Vp8RcInterfaceTest() override = default; - - protected: - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - } - - // From error_resilience_test.cc - int SetFrameFlags(int frame_num, int num_temp_layers) { - int frame_flags = 0; - if (num_temp_layers == 2) { - if (frame_num % 2 == 0) { - // Layer 0: predict from L and ARF, update L. - frame_flags = - VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; - } else { - // Layer 1: predict from L, G and ARF, and update G. - frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | - VP8_EFLAG_NO_UPD_ENTROPY; - } - } else if (num_temp_layers == 3) { - if (frame_num % 4 == 0) { - // Layer 0: predict from L, update L. - frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | - VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF; - } else if ((frame_num - 2) % 4 == 0) { - // Layer 1: predict from L, G, update G. - frame_flags = - VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_REF_ARF; - } else if ((frame_num - 1) % 2 == 0) { - // Layer 2: predict from L, G, ARF; update ARG. - frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST; - } - } - return frame_flags; - } - - int SetLayerId(int frame_num, int num_temp_layers) { - int layer_id = 0; - if (num_temp_layers == 2) { - if (frame_num % 2 == 0) { - layer_id = 0; - } else { - layer_id = 1; - } - } else if (num_temp_layers == 3) { - if (frame_num % 4 == 0) { - layer_id = 0; - } else if ((frame_num - 2) % 4 == 0) { - layer_id = 1; - } else if ((frame_num - 1) % 2 == 0) { - layer_id = 2; - } - } - return layer_id; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (rc_cfg_.ts_number_layers > 1) { - const int layer_id = SetLayerId(video->frame(), cfg_.ts_number_layers); - const int frame_flags = - SetFrameFlags(video->frame(), cfg_.ts_number_layers); - frame_params_.temporal_layer_id = layer_id; - if (video->frame() > 0) { - encoder->Control(VP8E_SET_TEMPORAL_LAYER_ID, layer_id); - encoder->Control(VP8E_SET_FRAME_FLAGS, frame_flags); - } - } else { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, -6); - encoder->Control(VP8E_SET_RTC_EXTERNAL_RATECTRL, 1); - encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 1000); - if (rc_cfg_.is_screen) { - encoder->Control(VP8E_SET_SCREEN_CONTENT_MODE, 1); - } - } else if (frame_params_.frame_type == libvpx::RcFrameType::kInterFrame) { - // Disable golden frame update. - frame_flags_ |= VP8_EFLAG_NO_UPD_GF; - frame_flags_ |= VP8_EFLAG_NO_UPD_ARF; - } - } - frame_params_.frame_type = video->frame() % key_interval_ == 0 - ? libvpx::RcFrameType::kKeyFrame - : libvpx::RcFrameType::kInterFrame; - encoder_exit_ = video->frame() == test_video_.frames; - } - - void PostEncodeFrameHook(::libvpx_test::Encoder *encoder) override { - if (encoder_exit_) { - return; - } - int qp; - libvpx::UVDeltaQP uv_delta_qp; - encoder->Control(VP8E_GET_LAST_QUANTIZER, &qp); - if (rc_api_->ComputeQP(frame_params_) == libvpx::FrameDropDecision::kOk) { - ASSERT_EQ(rc_api_->GetQP(), qp); - uv_delta_qp = rc_api_->GetUVDeltaQP(); - // delta_qp for UV channel is only set for screen. - if (!rc_cfg_.is_screen) { - ASSERT_EQ(uv_delta_qp.uvdc_delta_q, 0); - ASSERT_EQ(uv_delta_qp.uvac_delta_q, 0); - } - } else { - num_drops_++; - } - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - rc_api_->PostEncodeUpdate(pkt->data.frame.sz); - } - - void RunOneLayer() { - test_video_ = GET_PARAM(2); - target_bitrate_ = GET_PARAM(1); - SetConfig(); - rc_api_ = libvpx::VP8RateControlRTC::Create(rc_cfg_); - ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_)); - - ::libvpx_test::I420VideoSource video(test_video_.name, test_video_.width, - test_video_.height, 30, 1, 0, - test_video_.frames); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - } - - void RunOneLayerScreen() { - test_video_ = GET_PARAM(2); - target_bitrate_ = GET_PARAM(1); - SetConfig(); - rc_cfg_.is_screen = true; - rc_api_ = libvpx::VP8RateControlRTC::Create(rc_cfg_); - ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_)); - - ::libvpx_test::I420VideoSource video(test_video_.name, test_video_.width, - test_video_.height, 30, 1, 0, - test_video_.frames); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - } - - void RunOneLayerDropFrames() { - test_video_ = GET_PARAM(2); - target_bitrate_ = GET_PARAM(1); - frame_drop_thresh_ = 30; - num_drops_ = 0; - // Use lower target_bitrate and max_quantizer to trigger drops. - target_bitrate_ = target_bitrate_ >> 2; - SetConfig(); - rc_cfg_.max_quantizer = 56; - cfg_.rc_max_quantizer = 56; - rc_api_ = libvpx::VP8RateControlRTC::Create(rc_cfg_); - ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_)); - - ::libvpx_test::I420VideoSource video(test_video_.name, test_video_.width, - test_video_.height, 30, 1, 0, - test_video_.frames); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - // Check that some frames were dropped, otherwise test has no value. - ASSERT_GE(num_drops_, 1); - } - - void RunPeriodicKey() { - test_video_ = GET_PARAM(2); - target_bitrate_ = GET_PARAM(1); - key_interval_ = 100; - frame_drop_thresh_ = 30; - SetConfig(); - rc_api_ = libvpx::VP8RateControlRTC::Create(rc_cfg_); - ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_)); - - ::libvpx_test::I420VideoSource video(test_video_.name, test_video_.width, - test_video_.height, 30, 1, 0, - test_video_.frames); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - } - - void RunTemporalLayers2TL() { - test_video_ = GET_PARAM(2); - target_bitrate_ = GET_PARAM(1); - SetConfigTemporalLayers(2); - rc_api_ = libvpx::VP8RateControlRTC::Create(rc_cfg_); - ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_)); - - ::libvpx_test::I420VideoSource video(test_video_.name, test_video_.width, - test_video_.height, 30, 1, 0, - test_video_.frames); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - } - - void RunTemporalLayers3TL() { - test_video_ = GET_PARAM(2); - target_bitrate_ = GET_PARAM(1); - SetConfigTemporalLayers(3); - rc_api_ = libvpx::VP8RateControlRTC::Create(rc_cfg_); - ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_)); - - ::libvpx_test::I420VideoSource video(test_video_.name, test_video_.width, - test_video_.height, 30, 1, 0, - test_video_.frames); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - } - - void RunTemporalLayers3TLDropFrames() { - test_video_ = GET_PARAM(2); - target_bitrate_ = GET_PARAM(1); - frame_drop_thresh_ = 30; - num_drops_ = 0; - // Use lower target_bitrate and max_quantizer to trigger drops. - target_bitrate_ = target_bitrate_ >> 2; - SetConfigTemporalLayers(3); - rc_cfg_.max_quantizer = 56; - cfg_.rc_max_quantizer = 56; - rc_api_ = libvpx::VP8RateControlRTC::Create(rc_cfg_); - ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_)); - - ::libvpx_test::I420VideoSource video(test_video_.name, test_video_.width, - test_video_.height, 30, 1, 0, - test_video_.frames); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - // Check that some frames were dropped, otherwise test has no value. - ASSERT_GE(num_drops_, 1); - } - - private: - void SetConfig() { - rc_cfg_.width = test_video_.width; - rc_cfg_.height = test_video_.height; - rc_cfg_.max_quantizer = 60; - rc_cfg_.min_quantizer = 2; - rc_cfg_.target_bandwidth = target_bitrate_; - rc_cfg_.buf_initial_sz = 600; - rc_cfg_.buf_optimal_sz = 600; - rc_cfg_.buf_sz = target_bitrate_; - rc_cfg_.undershoot_pct = 50; - rc_cfg_.overshoot_pct = 50; - rc_cfg_.max_intra_bitrate_pct = 1000; - rc_cfg_.framerate = 30.0; - rc_cfg_.layer_target_bitrate[0] = target_bitrate_; - rc_cfg_.frame_drop_thresh = frame_drop_thresh_; - - // Encoder settings for ground truth. - cfg_.g_w = test_video_.width; - cfg_.g_h = test_video_.height; - cfg_.rc_undershoot_pct = 50; - cfg_.rc_overshoot_pct = 50; - cfg_.rc_buf_initial_sz = 600; - cfg_.rc_buf_optimal_sz = 600; - cfg_.rc_buf_sz = target_bitrate_; - cfg_.rc_dropframe_thresh = 0; - cfg_.rc_min_quantizer = 2; - cfg_.rc_max_quantizer = 60; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.g_error_resilient = 1; - cfg_.rc_target_bitrate = target_bitrate_; - cfg_.kf_min_dist = key_interval_; - cfg_.kf_max_dist = key_interval_; - cfg_.rc_dropframe_thresh = frame_drop_thresh_; - } - - void SetConfigTemporalLayers(int temporal_layers) { - rc_cfg_.width = test_video_.width; - rc_cfg_.height = test_video_.height; - rc_cfg_.max_quantizer = 60; - rc_cfg_.min_quantizer = 2; - rc_cfg_.target_bandwidth = target_bitrate_; - rc_cfg_.buf_initial_sz = 600; - rc_cfg_.buf_optimal_sz = 600; - rc_cfg_.buf_sz = target_bitrate_; - rc_cfg_.undershoot_pct = 50; - rc_cfg_.overshoot_pct = 50; - rc_cfg_.max_intra_bitrate_pct = 1000; - rc_cfg_.framerate = 30.0; - rc_cfg_.frame_drop_thresh = frame_drop_thresh_; - if (temporal_layers == 2) { - rc_cfg_.layer_target_bitrate[0] = 60 * target_bitrate_ / 100; - rc_cfg_.layer_target_bitrate[1] = target_bitrate_; - rc_cfg_.ts_rate_decimator[0] = 2; - rc_cfg_.ts_rate_decimator[1] = 1; - } else if (temporal_layers == 3) { - rc_cfg_.layer_target_bitrate[0] = 40 * target_bitrate_ / 100; - rc_cfg_.layer_target_bitrate[1] = 60 * target_bitrate_ / 100; - rc_cfg_.layer_target_bitrate[2] = target_bitrate_; - rc_cfg_.ts_rate_decimator[0] = 4; - rc_cfg_.ts_rate_decimator[1] = 2; - rc_cfg_.ts_rate_decimator[2] = 1; - } - - rc_cfg_.ts_number_layers = temporal_layers; - - // Encoder settings for ground truth. - cfg_.g_w = test_video_.width; - cfg_.g_h = test_video_.height; - cfg_.rc_undershoot_pct = 50; - cfg_.rc_overshoot_pct = 50; - cfg_.rc_buf_initial_sz = 600; - cfg_.rc_buf_optimal_sz = 600; - cfg_.rc_buf_sz = target_bitrate_; - cfg_.rc_dropframe_thresh = 0; - cfg_.rc_min_quantizer = 2; - cfg_.rc_max_quantizer = 60; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.g_error_resilient = 1; - cfg_.rc_target_bitrate = target_bitrate_; - cfg_.kf_min_dist = key_interval_; - cfg_.kf_max_dist = key_interval_; - cfg_.rc_dropframe_thresh = frame_drop_thresh_; - // 2 Temporal layers, no spatial layers, CBR mode. - cfg_.ss_number_layers = 1; - cfg_.ts_number_layers = temporal_layers; - if (temporal_layers == 2) { - cfg_.ts_rate_decimator[0] = 2; - cfg_.ts_rate_decimator[1] = 1; - cfg_.ts_periodicity = 2; - cfg_.ts_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100; - cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate; - } else if (temporal_layers == 3) { - cfg_.ts_rate_decimator[0] = 4; - cfg_.ts_rate_decimator[1] = 2; - cfg_.ts_rate_decimator[2] = 1; - cfg_.ts_periodicity = 4; - cfg_.ts_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100; - cfg_.ts_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100; - cfg_.ts_target_bitrate[2] = cfg_.rc_target_bitrate; - } - } - - std::unique_ptr rc_api_; - libvpx::VP8RateControlRtcConfig rc_cfg_; - int key_interval_; - int target_bitrate_; - Vp8RCTestVideo test_video_; - libvpx::VP8FrameParamsQpRTC frame_params_; - bool encoder_exit_; - int frame_drop_thresh_; - int num_drops_; -}; - -TEST_P(Vp8RcInterfaceTest, OneLayer) { RunOneLayer(); } - -TEST_P(Vp8RcInterfaceTest, OneLayerScreen) { RunOneLayerScreen(); } - -TEST_P(Vp8RcInterfaceTest, OneLayerDropFrames) { RunOneLayerDropFrames(); } - -TEST_P(Vp8RcInterfaceTest, OneLayerPeriodicKey) { RunPeriodicKey(); } - -TEST_P(Vp8RcInterfaceTest, TemporalLayers2TL) { RunTemporalLayers2TL(); } - -TEST_P(Vp8RcInterfaceTest, TemporalLayers3TL) { RunTemporalLayers3TL(); } - -TEST_P(Vp8RcInterfaceTest, TemporalLayers3TLDropFrames) { - RunTemporalLayers3TLDropFrames(); -} - -VP8_INSTANTIATE_TEST_SUITE(Vp8RcInterfaceTest, - ::testing::Values(200, 400, 1000), - ::testing::ValuesIn(kVp8RCTestVectors)); - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_arf_freq_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_arf_freq_test.cc deleted file mode 100644 index af428592..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_arf_freq_test.cc +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "gtest/gtest.h" - -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/util.h" -#include "test/y4m_video_source.h" -#include "test/yuv_video_source.h" -#include "vp9/encoder/vp9_ratectrl.h" -#include "vpx_config.h" - -namespace { - -const unsigned int kFrames = 100; -const int kBitrate = 500; - -#define ARF_NOT_SEEN 1000001 -#define ARF_SEEN_ONCE 1000000 - -typedef struct { - const char *filename; - unsigned int width; - unsigned int height; - unsigned int framerate_num; - unsigned int framerate_den; - unsigned int input_bit_depth; - vpx_img_fmt fmt; - vpx_bit_depth_t bit_depth; - unsigned int profile; -} TestVideoParam; - -typedef struct { - libvpx_test::TestMode mode; - int cpu_used; -} TestEncodeParam; - -const TestVideoParam kTestVectors[] = { - // artificially increase framerate to trigger default check - { "hantro_collage_w352h288.yuv", 352, 288, 5000, 1, 8, VPX_IMG_FMT_I420, - VPX_BITS_8, 0 }, - { "hantro_collage_w352h288.yuv", 352, 288, 30, 1, 8, VPX_IMG_FMT_I420, - VPX_BITS_8, 0 }, - { "rush_hour_444.y4m", 352, 288, 30, 1, 8, VPX_IMG_FMT_I444, VPX_BITS_8, 1 }, -#if CONFIG_VP9_HIGHBITDEPTH -// Add list of profile 2/3 test videos here ... -#endif // CONFIG_VP9_HIGHBITDEPTH -}; - -const TestEncodeParam kEncodeVectors[] = { - { ::libvpx_test::kOnePassGood, 2 }, { ::libvpx_test::kOnePassGood, 5 }, - { ::libvpx_test::kTwoPassGood, 1 }, { ::libvpx_test::kTwoPassGood, 2 }, - { ::libvpx_test::kTwoPassGood, 5 }, { ::libvpx_test::kRealTime, 5 }, -}; - -const int kMinArfVectors[] = { - // NOTE: 0 refers to the default built-in logic in: - // vp9_rc_get_default_min_gf_interval(...) - 0, 4, 8, 12, 15 -}; - -int is_extension_y4m(const char *filename) { - const char *dot = strrchr(filename, '.'); - if (!dot || dot == filename) { - return 0; - } else { - return !strcmp(dot, ".y4m"); - } -} - -class ArfFreqTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith3Params { - protected: - ArfFreqTest() - : EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(1)), - test_encode_param_(GET_PARAM(2)), min_arf_requested_(GET_PARAM(3)) {} - - ~ArfFreqTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(test_encode_param_.mode); - if (test_encode_param_.mode != ::libvpx_test::kRealTime) { - cfg_.g_lag_in_frames = 25; - cfg_.rc_end_usage = VPX_VBR; - } else { - cfg_.g_lag_in_frames = 0; - cfg_.rc_end_usage = VPX_CBR; - cfg_.rc_buf_sz = 1000; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 600; - } - dec_cfg_.threads = 4; - } - - void BeginPassHook(unsigned int) override { - min_run_ = ARF_NOT_SEEN; - run_of_visible_frames_ = 0; - } - - int GetNumFramesInPkt(const vpx_codec_cx_pkt_t *pkt) { - const uint8_t *buffer = reinterpret_cast(pkt->data.frame.buf); - const uint8_t marker = buffer[pkt->data.frame.sz - 1]; - const int mag = ((marker >> 3) & 3) + 1; - int frames = (marker & 0x7) + 1; - const unsigned int index_sz = 2 + mag * frames; - // Check for superframe or not. - // Assume superframe has only one visible frame, the rest being - // invisible. If superframe index is not found, then there is only - // one frame. - if (!((marker & 0xe0) == 0xc0 && pkt->data.frame.sz >= index_sz && - buffer[pkt->data.frame.sz - index_sz] == marker)) { - frames = 1; - } - return frames; - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return; - const int frames = GetNumFramesInPkt(pkt); - if (frames == 1) { - run_of_visible_frames_++; - } else if (frames == 2) { - if (min_run_ == ARF_NOT_SEEN) { - min_run_ = ARF_SEEN_ONCE; - } else if (min_run_ == ARF_SEEN_ONCE || - run_of_visible_frames_ < min_run_) { - min_run_ = run_of_visible_frames_; - } - run_of_visible_frames_ = 1; - } else { - min_run_ = 0; - run_of_visible_frames_ = 1; - } - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1); - encoder->Control(VP9E_SET_TILE_COLUMNS, 4); - encoder->Control(VP8E_SET_CPUUSED, test_encode_param_.cpu_used); - encoder->Control(VP9E_SET_MIN_GF_INTERVAL, min_arf_requested_); - if (test_encode_param_.mode != ::libvpx_test::kRealTime) { - encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); - encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7); - encoder->Control(VP8E_SET_ARNR_STRENGTH, 5); - encoder->Control(VP8E_SET_ARNR_TYPE, 3); - } - } - } - - int GetMinVisibleRun() const { return min_run_; } - - int GetMinArfDistanceRequested() const { - if (min_arf_requested_) { - return min_arf_requested_; - } else { - return vp9_rc_get_default_min_gf_interval( - test_video_param_.width, test_video_param_.height, - (double)test_video_param_.framerate_num / - test_video_param_.framerate_den); - } - } - - TestVideoParam test_video_param_; - TestEncodeParam test_encode_param_; - - private: - int min_arf_requested_; - int min_run_; - int run_of_visible_frames_; -}; - -TEST_P(ArfFreqTest, MinArfFreqTest) { - cfg_.rc_target_bitrate = kBitrate; - cfg_.g_error_resilient = 0; - cfg_.g_profile = test_video_param_.profile; - cfg_.g_input_bit_depth = test_video_param_.input_bit_depth; - cfg_.g_bit_depth = test_video_param_.bit_depth; - init_flags_ = VPX_CODEC_USE_PSNR; - if (cfg_.g_bit_depth > 8) init_flags_ |= VPX_CODEC_USE_HIGHBITDEPTH; - - std::unique_ptr video; - if (is_extension_y4m(test_video_param_.filename)) { - video.reset(new libvpx_test::Y4mVideoSource(test_video_param_.filename, 0, - kFrames)); - } else { - video.reset(new libvpx_test::YUVVideoSource( - test_video_param_.filename, test_video_param_.fmt, - test_video_param_.width, test_video_param_.height, - test_video_param_.framerate_num, test_video_param_.framerate_den, 0, - kFrames)); - } - - ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); - const int min_run = GetMinVisibleRun(); - const int min_arf_dist_requested = GetMinArfDistanceRequested(); - if (min_run != ARF_NOT_SEEN && min_run != ARF_SEEN_ONCE) { - const int min_arf_dist = min_run + 1; - EXPECT_GE(min_arf_dist, min_arf_dist_requested); - } -} - -VP9_INSTANTIATE_TEST_SUITE(ArfFreqTest, ::testing::ValuesIn(kTestVectors), - ::testing::ValuesIn(kEncodeVectors), - ::testing::ValuesIn(kMinArfVectors)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_block_error_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_block_error_test.cc deleted file mode 100644 index e202ada8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_block_error_test.cc +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vpx_config.h" -#include "./vp9_rtcd.h" -#include "test/acm_random.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vp9/common/vp9_entropy.h" -#include "vpx/vpx_codec.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/vpx_dsp_common.h" - -using libvpx_test::ACMRandom; - -namespace { -const int kNumIterations = 1000; - -typedef int64_t (*HBDBlockErrorFunc)(const tran_low_t *coeff, - const tran_low_t *dqcoeff, - intptr_t block_size, int64_t *ssz, - int bps); - -typedef std::tuple - BlockErrorParam; - -typedef int64_t (*BlockErrorFunc)(const tran_low_t *coeff, - const tran_low_t *dqcoeff, - intptr_t block_size, int64_t *ssz); - -template -int64_t BlockError8BitWrapper(const tran_low_t *coeff, - const tran_low_t *dqcoeff, intptr_t block_size, - int64_t *ssz, int bps) { - EXPECT_EQ(bps, 8); - return fn(coeff, dqcoeff, block_size, ssz); -} - -class BlockErrorTest : public ::testing::TestWithParam { - public: - ~BlockErrorTest() override = default; - void SetUp() override { - error_block_op_ = GET_PARAM(0); - ref_error_block_op_ = GET_PARAM(1); - bit_depth_ = GET_PARAM(2); - } - - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - vpx_bit_depth_t bit_depth_; - HBDBlockErrorFunc error_block_op_; - HBDBlockErrorFunc ref_error_block_op_; -}; -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BlockErrorTest); - -TEST_P(BlockErrorTest, OperationCheck) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - DECLARE_ALIGNED(16, tran_low_t, coeff[4096]); - DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]); - int err_count_total = 0; - int first_failure = -1; - intptr_t block_size; - int64_t ssz; - int64_t ret; - int64_t ref_ssz; - int64_t ref_ret; - const int msb = bit_depth_ + 8 - 1; - for (int i = 0; i < kNumIterations; ++i) { - int err_count = 0; - block_size = 16 << (i % 9); // All block sizes from 4x4, 8x4 ..64x64 - for (int j = 0; j < block_size; j++) { - // coeff and dqcoeff will always have at least the same sign, and this - // can be used for optimization, so generate test input precisely. - if (rnd(2)) { - // Positive number - coeff[j] = rnd(1 << msb); - dqcoeff[j] = rnd(1 << msb); - } else { - // Negative number - coeff[j] = -rnd(1 << msb); - dqcoeff[j] = -rnd(1 << msb); - } - } - ref_ret = - ref_error_block_op_(coeff, dqcoeff, block_size, &ref_ssz, bit_depth_); - ASM_REGISTER_STATE_CHECK( - ret = error_block_op_(coeff, dqcoeff, block_size, &ssz, bit_depth_)); - err_count += (ref_ret != ret) | (ref_ssz != ssz); - if (err_count && !err_count_total) { - first_failure = i; - } - err_count_total += err_count; - } - EXPECT_EQ(0, err_count_total) - << "Error: Error Block Test, C output doesn't match optimized output. " - << "First failed at test case " << first_failure; -} - -TEST_P(BlockErrorTest, ExtremeValues) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - DECLARE_ALIGNED(16, tran_low_t, coeff[4096]); - DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]); - int err_count_total = 0; - int first_failure = -1; - intptr_t block_size; - int64_t ssz; - int64_t ret; - int64_t ref_ssz; - int64_t ref_ret; - const int msb = bit_depth_ + 8 - 1; - int max_val = ((1 << msb) - 1); - for (int i = 0; i < kNumIterations; ++i) { - int err_count = 0; - int k = (i / 9) % 9; - - // Change the maximum coeff value, to test different bit boundaries - if (k == 8 && (i % 9) == 0) { - max_val >>= 1; - } - block_size = 16 << (i % 9); // All block sizes from 4x4, 8x4 ..64x64 - for (int j = 0; j < block_size; j++) { - if (k < 4) { - // Test at positive maximum values - coeff[j] = k % 2 ? max_val : 0; - dqcoeff[j] = (k >> 1) % 2 ? max_val : 0; - } else if (k < 8) { - // Test at negative maximum values - coeff[j] = k % 2 ? -max_val : 0; - dqcoeff[j] = (k >> 1) % 2 ? -max_val : 0; - } else { - if (rnd(2)) { - // Positive number - coeff[j] = rnd(1 << 14); - dqcoeff[j] = rnd(1 << 14); - } else { - // Negative number - coeff[j] = -rnd(1 << 14); - dqcoeff[j] = -rnd(1 << 14); - } - } - } - ref_ret = - ref_error_block_op_(coeff, dqcoeff, block_size, &ref_ssz, bit_depth_); - ASM_REGISTER_STATE_CHECK( - ret = error_block_op_(coeff, dqcoeff, block_size, &ssz, bit_depth_)); - err_count += (ref_ret != ret) | (ref_ssz != ssz); - if (err_count && !err_count_total) { - first_failure = i; - } - err_count_total += err_count; - } - EXPECT_EQ(0, err_count_total) - << "Error: Error Block Test, C output doesn't match optimized output. " - << "First failed at test case " << first_failure; -} - -using std::make_tuple; - -#if HAVE_SSE2 -const BlockErrorParam sse2_block_error_tests[] = { -#if CONFIG_VP9_HIGHBITDEPTH - make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c, - VPX_BITS_10), - make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c, - VPX_BITS_12), - make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c, - VPX_BITS_8), -#endif // CONFIG_VP9_HIGHBITDEPTH - make_tuple(&BlockError8BitWrapper, - &BlockError8BitWrapper, VPX_BITS_8) -}; - -INSTANTIATE_TEST_SUITE_P(SSE2, BlockErrorTest, - ::testing::ValuesIn(sse2_block_error_tests)); -#endif // HAVE_SSE2 - -#if HAVE_AVX2 -INSTANTIATE_TEST_SUITE_P( - AVX2, BlockErrorTest, - ::testing::Values(make_tuple(&BlockError8BitWrapper, - &BlockError8BitWrapper, - VPX_BITS_8))); -#endif // HAVE_AVX2 - -#if HAVE_NEON -const BlockErrorParam neon_block_error_tests[] = { -#if CONFIG_VP9_HIGHBITDEPTH - make_tuple(&vp9_highbd_block_error_neon, &vp9_highbd_block_error_c, - VPX_BITS_10), - make_tuple(&vp9_highbd_block_error_neon, &vp9_highbd_block_error_c, - VPX_BITS_12), - make_tuple(&vp9_highbd_block_error_neon, &vp9_highbd_block_error_c, - VPX_BITS_8), -#endif // CONFIG_VP9_HIGHBITDEPTH - make_tuple(&BlockError8BitWrapper, - &BlockError8BitWrapper, VPX_BITS_8) -}; - -INSTANTIATE_TEST_SUITE_P(NEON, BlockErrorTest, - ::testing::ValuesIn(neon_block_error_tests)); -#endif // HAVE_NEON - -#if HAVE_SVE -const BlockErrorParam sve_block_error_tests[] = { make_tuple( - &BlockError8BitWrapper, - &BlockError8BitWrapper, VPX_BITS_8) }; - -INSTANTIATE_TEST_SUITE_P(SVE, BlockErrorTest, - ::testing::ValuesIn(sve_block_error_tests)); -#endif // HAVE_SVE -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_boolcoder_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_boolcoder_test.cc deleted file mode 100644 index fbbdb194..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_boolcoder_test.cc +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "gtest/gtest.h" - -#include "test/acm_random.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/bitreader.h" -#include "vpx_dsp/bitwriter.h" - -using libvpx_test::ACMRandom; - -namespace { -const int num_tests = 10; -} // namespace - -TEST(VP9, TestBitIO) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - for (int n = 0; n < num_tests; ++n) { - for (int method = 0; method <= 7; ++method) { // we generate various proba - const int kBitsToTest = 1000; - uint8_t probas[kBitsToTest]; - - for (int i = 0; i < kBitsToTest; ++i) { - const int parity = i & 1; - /* clang-format off */ - probas[i] = - (method == 0) ? 0 : (method == 1) ? 255 : - (method == 2) ? 128 : - (method == 3) ? rnd.Rand8() : - (method == 4) ? (parity ? 0 : 255) : - // alternate between low and high proba: - (method == 5) ? (parity ? rnd(128) : 255 - rnd(128)) : - (method == 6) ? - (parity ? rnd(64) : 255 - rnd(64)) : - (parity ? rnd(32) : 255 - rnd(32)); - /* clang-format on */ - } - for (int bit_method = 0; bit_method <= 3; ++bit_method) { - const int random_seed = 6432; - const int kBufferSize = 10000; - ACMRandom bit_rnd(random_seed); - vpx_writer bw; - uint8_t bw_buffer[kBufferSize]; - vpx_start_encode(&bw, bw_buffer, sizeof(bw_buffer)); - - int bit = (bit_method == 0) ? 0 : (bit_method == 1) ? 1 : 0; - for (int i = 0; i < kBitsToTest; ++i) { - if (bit_method == 2) { - bit = (i & 1); - } else if (bit_method == 3) { - bit = bit_rnd(2); - } - vpx_write(&bw, bit, static_cast(probas[i])); - } - - GTEST_ASSERT_EQ(vpx_stop_encode(&bw), 0); - // vpx_reader_fill() may read into uninitialized data that - // isn't used meaningfully, but may trigger an MSan warning. - memset(bw_buffer + bw.pos, 0, sizeof(BD_VALUE) - 1); - - // First bit should be zero - GTEST_ASSERT_EQ(bw_buffer[0] & 0x80, 0); - - vpx_reader br; - vpx_reader_init(&br, bw_buffer, kBufferSize, nullptr, nullptr); - bit_rnd.Reset(random_seed); - for (int i = 0; i < kBitsToTest; ++i) { - if (bit_method == 2) { - bit = (i & 1); - } else if (bit_method == 3) { - bit = bit_rnd(2); - } - GTEST_ASSERT_EQ(vpx_read(&br, probas[i]), bit) - << "pos: " << i << " / " << kBitsToTest - << " bit_method: " << bit_method << " method: " << method; - } - } - } - } -} - -TEST(VP9, TestBitIOBufferSize0) { - vpx_writer bw; - uint8_t bw_buffer[1]; - vpx_start_encode(&bw, bw_buffer, 0); - GTEST_ASSERT_EQ(vpx_stop_encode(&bw), -1); -} - -TEST(VP9, TestBitIOBufferSize1) { - vpx_writer bw; - uint8_t bw_buffer[1]; - vpx_start_encode(&bw, bw_buffer, sizeof(bw_buffer)); - GTEST_ASSERT_EQ(vpx_stop_encode(&bw), -1); -} - -TEST(VP9, TestBitIOBufferSize2) { - vpx_writer bw; - uint8_t bw_buffer[2]; - vpx_start_encode(&bw, bw_buffer, sizeof(bw_buffer)); - GTEST_ASSERT_EQ(vpx_stop_encode(&bw), 0); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_c_vs_simd_encode.sh b/presentation/src/main/cpp/third_party/libvpx/test/vp9_c_vs_simd_encode.sh deleted file mode 100644 index 03843610..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_c_vs_simd_encode.sh +++ /dev/null @@ -1,420 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2023 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## This script checks the bit exactness between C and SIMD -## implementations of VP9 encoder. -## -. $(dirname $0)/tools_common.sh - -TEST_BITRATES="1600 6400" -PRESETS="good rt" -TEST_CLIPS="yuv_raw_input y4m_360p_10bit_input yuv_480p_raw_input y4m_720p_input" -OUT_FILE_SUFFIX=".ivf" -SCRIPT_DIR=$(dirname "$0") -LIBVPX_SOURCE_DIR=$(cd "${SCRIPT_DIR}/.."; pwd) - -# Clips used in test. -YUV_RAW_INPUT="${LIBVPX_TEST_DATA_PATH}/hantro_collage_w352h288.yuv" -YUV_480P_RAW_INPUT="${LIBVPX_TEST_DATA_PATH}/niklas_640_480_30.yuv" -Y4M_360P_10BIT_INPUT="${LIBVPX_TEST_DATA_PATH}/crowd_run_360p_10_150f.y4m" -Y4M_720P_INPUT="${LIBVPX_TEST_DATA_PATH}/niklas_1280_720_30.y4m" - -# Number of frames to test. -VP9_ENCODE_C_VS_SIMD_TEST_FRAME_LIMIT=20 - -# Create a temporary directory for output files. -if [ -n "${TMPDIR}" ]; then - VPX_TEST_TEMP_ROOT="${TMPDIR}" -elif [ -n "${TEMPDIR}" ]; then - VPX_TEST_TEMP_ROOT="${TEMPDIR}" -else - VPX_TEST_TEMP_ROOT=/tmp -fi - -VPX_TEST_OUTPUT_DIR="${VPX_TEST_TEMP_ROOT}/vpx_test_$$" - -if ! mkdir -p "${VPX_TEST_OUTPUT_DIR}" || \ - [ ! -d "${VPX_TEST_OUTPUT_DIR}" ]; then - echo "${0##*/}: Cannot create output directory, giving up." - echo "${0##*/}: VPX_TEST_OUTPUT_DIR=${VPX_TEST_OUTPUT_DIR}" - exit 1 -fi - -elog() { - echo "$@" 1>&2 -} - -# Echoes path to $1 when it's executable and exists in ${VPX_TEST_OUTPUT_DIR}, -# or an empty string. Caller is responsible for testing the string once the -# function returns. -vp9_enc_tool_path() { - local target="$1" - local tool_path="${VPX_TEST_OUTPUT_DIR}/build_target_${target}/vpxenc" - - if [ ! -x "${tool_path}" ]; then - tool_path="" - fi - echo "${tool_path}" -} - -# Environment check: Make sure input and source directories are available. -vp9_c_vs_simd_enc_verify_environment() { - if [ ! -e "${YUV_RAW_INPUT}" ]; then - elog "libvpx test data must exist in LIBVPX_TEST_DATA_PATH." - return 1 - fi - if [ ! -e "${YUV_480P_RAW_INPUT}" ]; then - elog "libvpx test data must exist in LIBVPX_TEST_DATA_PATH." - return 1 - fi - if [ ! -e "${Y4M_720P_INPUT}" ]; then - elog "libvpx test data must exist in LIBVPX_TEST_DATA_PATH." - return 1 - fi - if [ ! -e "${Y4M_360P_10BIT_INPUT}" ]; then - elog "libvpx test data must exist in LIBVPX_TEST_DATA_PATH." - return 1 - fi - if [ ! -d "$LIBVPX_SOURCE_DIR" ]; then - elog "LIBVPX_SOURCE_DIR does not exist." - return 1 - fi -} - -# This is not needed since tools_common.sh does the same cleanup. -# Keep the code here for our reference. -# cleanup() { -# rm -rf ${VPX_TEST_OUTPUT_DIR} -# } - -# Echo VPX_SIMD_CAPS_MASK for different instruction set architecture. -avx512f() { - echo "0x1FF" -} - -avx2() { - echo "0x0FF" -} - -sse4_1() { - echo "0x03F" -} - -ssse3() { - echo "0x01F" -} - -sse2() { - echo "0x007" -} - -# Echo clip details to be used as input to vpxenc. -yuv_raw_input() { - echo ""${YUV_RAW_INPUT}" - --width=352 - --height=288 - --bit-depth=8 - --profile=0" -} - -yuv_480p_raw_input() { - echo ""${YUV_480P_RAW_INPUT}" - --width=640 - --height=480 - --bit-depth=8 - --profile=0" -} - -y4m_720p_input() { - echo ""${Y4M_720P_INPUT}" - --bit-depth=8 - --profile=0" -} - -y4m_360p_10bit_input() { - echo ""${Y4M_360P_10BIT_INPUT}" - --bit-depth=10 - --profile=2" -} - -has_x86_isa_extn() { - instruction_set=$1 - if ! grep -q "$instruction_set" /proc/cpuinfo; then - # This instruction_set is not supported. - return 1 - fi - # This instruction_set is supported. - return 0 -} - -# Echo good encode params for use with VP9 encoder. -vp9_encode_good_params() { - echo "--codec=vp9 \ - --good \ - --test-decode=fatal \ - --ivf \ - --threads=1 \ - --static-thresh=0 \ - --tile-columns=0 \ - --end-usage=vbr \ - --kf-max-dist=160 \ - --kf-min-dist=0 \ - --lag-in-frames=19 \ - --max-q=63 \ - --min-q=0 \ - --passes=2 \ - --undershoot-pct=100 \ - --overshoot-pct=100 \ - --verbose \ - --auto-alt-ref=1 \ - --drop-frame=0 \ - --bias-pct=50 \ - --minsection-pct=0 \ - --maxsection-pct=2000 \ - --arnr-maxframes=7 \ - --arnr-strength=5 \ - --sharpness=0 \ - --frame-parallel=0" -} - -# Echo realtime encode params for use with VP9 encoder. -vp9_encode_rt_params() { - echo "--codec=vp9 \ - --rt \ - --test-decode=fatal \ - --ivf \ - --threads=1 \ - --static-thresh=0 \ - --tile-columns=0 \ - --tile-rows=0 \ - --end-usage=cbr \ - --kf-max-dist=90000 \ - --lag-in-frames=0 \ - --max-q=58 \ - --min-q=2 \ - --passes=1 \ - --undershoot-pct=50 \ - --overshoot-pct=50 \ - --verbose \ - --row-mt=0 \ - --buf-sz=1000 \ - --buf-initial-sz=500 \ - --buf-optimal-sz=600 \ - --max-intra-rate=300 \ - --resize-allowed=0 \ - --noise-sensitivity=0 \ - --aq-mode=3 \ - --error-resilient=0" -} - -# Configures for the given target in the -# ${VPX_TEST_OUTPUT_DIR}/build_target_${target} directory. -vp9_enc_build() { - local target=$1 - local configure="$2" - local tmp_build_dir=${VPX_TEST_OUTPUT_DIR}/build_target_${target} - mkdir -p "$tmp_build_dir" - local save_dir="$PWD" - cd "$tmp_build_dir" - - echo "Building target: ${target}" - local config_args="--disable-install-docs \ - --enable-unit-tests \ - --enable-debug \ - --enable-postproc \ - --enable-vp9-postproc \ - --enable-vp9-temporal-denoising \ - --enable-vp9-highbitdepth" - - eval "$configure" --target="${target}" "${config_args}" ${devnull} - eval make -j$(nproc) ${devnull} - echo "Done building target: ${target}" - cd "${save_dir}" -} - -compare_enc_output() { - local target=$1 - local cpu=$2 - local clip=$3 - local bitrate=$4 - local preset=$5 - if ! diff -q ${VPX_TEST_OUTPUT_DIR}/Out-generic-gnu-"${clip}"-${preset}-${bitrate}kbps-cpu${cpu}${OUT_FILE_SUFFIX} \ - ${VPX_TEST_OUTPUT_DIR}/Out-${target}-"${clip}"-${preset}-${bitrate}kbps-cpu${cpu}${OUT_FILE_SUFFIX}; then - elog "C vs ${target} encode mismatches for ${clip}, at ${bitrate} kbps, speed ${cpu}, ${preset} preset" - return 1 - fi -} - -vp9_enc_test() { - local encoder="$1" - local target=$2 - if [ -z "$(vp9_enc_tool_path "${target}")" ]; then - elog "vpxenc not found. It must exist in ${VPX_TEST_OUTPUT_DIR}/build_target_${target} path" - return 1 - fi - - local tmp_build_dir=${VPX_TEST_OUTPUT_DIR}/build_target_${target} - local save_dir="$PWD" - cd "$tmp_build_dir" - for preset in ${PRESETS}; do - if [ "${preset}" = "good" ]; then - local max_cpu_used=5 - local test_params=vp9_encode_good_params - elif [ "${preset}" = "rt" ]; then - local max_cpu_used=9 - local test_params=vp9_encode_rt_params - else - elog "Invalid preset" - cd "${save_dir}" - return 1 - fi - - # Enable armv8 test for real-time only - if [ "${preset}" = "good" ] && [ "${target}" = "armv8-linux-gcc" ]; then - continue - fi - - for cpu in $(seq 0 $max_cpu_used); do - for clip in ${TEST_CLIPS}; do - for bitrate in ${TEST_BITRATES}; do - eval "${encoder}" $($clip) $($test_params) \ - "--limit=${VP9_ENCODE_C_VS_SIMD_TEST_FRAME_LIMIT}" \ - "--cpu-used=${cpu}" "--target-bitrate=${bitrate}" "-o" \ - ${VPX_TEST_OUTPUT_DIR}/Out-${target}-"${clip}"-${preset}-${bitrate}kbps-cpu${cpu}${OUT_FILE_SUFFIX} \ - ${devnull} - - if [ "${target}" != "generic-gnu" ]; then - if ! compare_enc_output ${target} $cpu ${clip} $bitrate ${preset}; then - # Find the mismatch - cd "${save_dir}" - return 1 - fi - fi - done - done - done - done - cd "${save_dir}" -} - -vp9_test_generic() { - local configure="$LIBVPX_SOURCE_DIR/configure" - local target="generic-gnu" - - echo "Build for: ${target}" - vp9_enc_build ${target} ${configure} - local encoder="$(vp9_enc_tool_path "${target}")" - vp9_enc_test $encoder "${target}" -} - -# This function encodes VP9 bitstream by enabling SSE2, SSSE3, SSE4_1, AVX2, AVX512f as there are -# no functions with MMX, SSE, SSE3 and AVX specialization. -# The value of environment variable 'VPX_SIMD_CAPS' controls enabling of different instruction -# set extension optimizations. The value of the flag 'VPX_SIMD_CAPS' and the corresponding -# instruction set extension optimization enabled are as follows: -# AVX512 AVX2 AVX SSE4_1 SSSE3 SSE3 SSE2 SSE MMX -# 1 1 1 1 1 1 1 1 1 -> 0x1FF -> Enable AVX512 and lower variants -# 0 1 1 1 1 1 1 1 1 -> 0x0FF -> Enable AVX2 and lower variants -# 0 0 1 1 1 1 1 1 1 -> 0x07F -> Enable AVX and lower variants -# 0 0 0 1 1 1 1 1 1 -> 0x03F -> Enable SSE4_1 and lower variants -# 0 0 0 0 1 1 1 1 1 -> 0x01F -> Enable SSSE3 and lower variants -# 0 0 0 0 0 1 1 1 1 -> 0x00F -> Enable SSE3 and lower variants -# 0 0 0 0 0 0 1 1 1 -> 0x007 -> Enable SSE2 and lower variants -# 0 0 0 0 0 0 0 1 1 -> 0x003 -> Enable SSE and lower variants -# 0 0 0 0 0 0 0 0 1 -> 0x001 -> Enable MMX -## NOTE: In x86_64 platform, it is not possible to enable sse/mmx/c using "VPX_SIMD_CAPS_MASK" as -# all x86_64 platforms implement sse2. -vp9_test_x86() { - local arch=$1 - - if ! uname -m | grep -q "x86"; then - elog "Machine architecture is not x86 or x86_64" - return 0 - fi - - if [ $arch = "x86" ]; then - local target="x86-linux-gcc" - elif [ $arch = "x86_64" ]; then - local target="x86_64-linux-gcc" - fi - - local x86_isa_variants="avx512f avx2 sse4_1 ssse3 sse2" - local configure="$LIBVPX_SOURCE_DIR/configure" - - echo "Build for x86: ${target}" - vp9_enc_build ${target} ${configure} - local encoder="$(vp9_enc_tool_path "${target}")" - for isa in $x86_isa_variants; do - # Note that if has_x86_isa_extn returns 1, it is false, and vice versa. - if ! has_x86_isa_extn $isa; then - echo "${isa} is not supported in this machine" - continue - fi - export VPX_SIMD_CAPS_MASK=$($isa) - if ! vp9_enc_test $encoder ${target}; then - # Find the mismatch - return 1 - fi - unset VPX_SIMD_CAPS_MASK - done -} - -vp9_test_arm() { - local target="armv8-linux-gcc" - local configure="CROSS=aarch64-linux-gnu- $LIBVPX_SOURCE_DIR/configure --extra-cflags=-march=armv8.4-a \ - --extra-cxxflags=-march=armv8.4-a" - echo "Build for arm64: ${target}" - vp9_enc_build ${target} "${configure}" - - local encoder="$(vp9_enc_tool_path "${target}")" - if ! vp9_enc_test "qemu-aarch64 -L /usr/aarch64-linux-gnu ${encoder}" ${target}; then - # Find the mismatch - return 1 - fi -} - -vp9_c_vs_simd_enc_test() { - # Test Generic - vp9_test_generic - - # Test x86 (32 bit) - echo "vp9 test for x86 (32 bit): Started." - if ! vp9_test_x86 "x86"; then - echo "vp9 test for x86 (32 bit): Done, test failed." - return 1 - else - echo "vp9 test for x86 (32 bit): Done, all tests passed." - fi - - # Test x86_64 (64 bit) - if [ "$(eval uname -m)" = "x86_64" ]; then - echo "vp9 test for x86_64 (64 bit): Started." - if ! vp9_test_x86 "x86_64"; then - echo "vp9 test for x86_64 (64 bit): Done, test failed." - return 1 - else - echo "vp9 test for x86_64 (64 bit): Done, all tests passed." - fi - fi - - # Test ARM - echo "vp9_test_arm: Started." - if ! vp9_test_arm; then - echo "vp9 test for arm: Done, test failed." - return 1 - else - echo "vp9 test for arm: Done, all tests passed." - fi -} - -# Setup a trap function to clean up build, and output files after tests complete. -# trap cleanup EXIT - -run_tests vp9_c_vs_simd_enc_verify_environment vp9_c_vs_simd_enc_test diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_datarate_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_datarate_test.cc deleted file mode 100644 index ec9c5a1e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_datarate_test.cc +++ /dev/null @@ -1,1096 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "./vpx_config.h" -#include "gtest/gtest.h" -#include "test/acm_random.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" -#include "test/y4m_video_source.h" -#include "vpx/vpx_codec.h" -#include "vpx_ports/bitops.h" - -namespace { - -class DatarateTestVP9 : public ::libvpx_test::EncoderTest { - public: - explicit DatarateTestVP9(const ::libvpx_test::CodecFactory *codec) - : EncoderTest(codec) { - tune_content_ = 0; - } - - protected: - ~DatarateTestVP9() override = default; - - virtual void ResetModel() { - last_pts_ = 0; - bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz; - frame_number_ = 0; - tot_frame_number_ = 0; - first_drop_ = 0; - num_drops_ = 0; - aq_mode_ = 3; - // Denoiser is off by default. - denoiser_on_ = 0; - // For testing up to 3 layers. - for (int i = 0; i < 3; ++i) { - bits_total_[i] = 0; - } - denoiser_offon_test_ = 0; - denoiser_offon_period_ = -1; - frame_parallel_decoding_mode_ = 1; - delta_q_uv_ = 0; - use_roi_ = false; - } - - // - // Frame flags and layer id for temporal layers. - // - - // For two layers, test pattern is: - // 1 3 - // 0 2 ..... - // For three layers, test pattern is: - // 1 3 5 7 - // 2 6 - // 0 4 .... - // LAST is always update on base/layer 0, GOLDEN is updated on layer 1. - // For this 3 layer example, the 2nd enhancement layer (layer 2) updates - // the altref frame. - static int GetFrameFlags(int frame_num, int num_temp_layers) { - int frame_flags = 0; - if (num_temp_layers == 2) { - if (frame_num % 2 == 0) { - // Layer 0: predict from L and ARF, update L. - frame_flags = - VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF; - } else { - // Layer 1: predict from L, G and ARF, and update G. - frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | - VP8_EFLAG_NO_UPD_ENTROPY; - } - } else if (num_temp_layers == 3) { - if (frame_num % 4 == 0) { - // Layer 0: predict from L and ARF; update L. - frame_flags = - VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF; - } else if ((frame_num - 2) % 4 == 0) { - // Layer 1: predict from L, G, ARF; update G. - frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; - } else if ((frame_num - 1) % 2 == 0) { - // Layer 2: predict from L, G, ARF; update ARF. - frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST; - } - } - return frame_flags; - } - - static int SetLayerId(int frame_num, int num_temp_layers) { - int layer_id = 0; - if (num_temp_layers == 2) { - if (frame_num % 2 == 0) { - layer_id = 0; - } else { - layer_id = 1; - } - } else if (num_temp_layers == 3) { - if (frame_num % 4 == 0) { - layer_id = 0; - } else if ((frame_num - 2) % 4 == 0) { - layer_id = 1; - } else if ((frame_num - 1) % 2 == 0) { - layer_id = 2; - } - } - return layer_id; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_); - encoder->Control(VP9E_SET_AQ_MODE, aq_mode_); - encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_); - } - - if (denoiser_offon_test_) { - ASSERT_GT(denoiser_offon_period_, 0) - << "denoiser_offon_period_ is not positive."; - if ((video->frame() + 1) % denoiser_offon_period_ == 0) { - // Flip denoiser_on_ periodically - denoiser_on_ ^= 1; - } - } - - encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_); - encoder->Control(VP9E_SET_TILE_COLUMNS, get_msb(cfg_.g_threads)); - encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, - frame_parallel_decoding_mode_); - - if (use_roi_) { - encoder->Control(VP9E_SET_ROI_MAP, &roi_); - encoder->Control(VP9E_SET_AQ_MODE, 0); - } - - if (delta_q_uv_ != 0) { - encoder->Control(VP9E_SET_DELTA_Q_UV, delta_q_uv_); - } - - if (cfg_.ts_number_layers > 1) { - if (video->frame() == 0) { - encoder->Control(VP9E_SET_SVC, 1); - } - if (cfg_.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) { - vpx_svc_layer_id_t layer_id; - frame_flags_ = GetFrameFlags(video->frame(), cfg_.ts_number_layers); - layer_id.spatial_layer_id = 0; - layer_id.temporal_layer_id = - SetLayerId(video->frame(), cfg_.ts_number_layers); - layer_id.temporal_layer_id_per_spatial[0] = - SetLayerId(video->frame(), cfg_.ts_number_layers); - encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id); - } - } - const vpx_rational_t tb = video->timebase(); - timebase_ = static_cast(tb.num) / tb.den; - duration_ = 0; - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - // Time since last timestamp = duration. - vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_; - - if (duration > 1) { - // If first drop not set and we have a drop set it to this time. - if (!first_drop_) first_drop_ = last_pts_ + 1; - // Update the number of frame drops. - num_drops_ += static_cast(duration - 1); - // Update counter for total number of frames (#frames input to encoder). - // Needed for setting the proper layer_id below. - tot_frame_number_ += static_cast(duration - 1); - } - - int layer = SetLayerId(tot_frame_number_, cfg_.ts_number_layers); - - // Add to the buffer the bits we'd expect from a constant bitrate server. - bits_in_buffer_model_ += static_cast( - duration * timebase_ * cfg_.rc_target_bitrate * 1000); - - // Buffer should not go negative. - ASSERT_GE(bits_in_buffer_model_, 0) - << "Buffer Underrun at frame " << pkt->data.frame.pts; - - const size_t frame_size_in_bits = pkt->data.frame.sz * 8; - - // Update the total encoded bits. For temporal layers, update the cumulative - // encoded bits per layer. - for (int i = layer; i < static_cast(cfg_.ts_number_layers); ++i) { - bits_total_[i] += frame_size_in_bits; - } - - // Update the most recent pts. - last_pts_ = pkt->data.frame.pts; - ++frame_number_; - ++tot_frame_number_; - } - - void EndPassHook() override { - for (int layer = 0; layer < static_cast(cfg_.ts_number_layers); - ++layer) { - duration_ = (last_pts_ + 1) * timebase_; - if (bits_total_[layer]) { - // Effective file datarate: - effective_datarate_[layer] = (bits_total_[layer] / 1000.0) / duration_; - } - } - } - - vpx_codec_pts_t last_pts_; - double timebase_; - int tune_content_; - int frame_number_; // Counter for number of non-dropped/encoded frames. - int tot_frame_number_; // Counter for total number of input frames. - int64_t bits_total_[3]; - double duration_; - double effective_datarate_[3]; - int set_cpu_used_; - int64_t bits_in_buffer_model_; - vpx_codec_pts_t first_drop_; - int num_drops_; - int aq_mode_; - int denoiser_on_; - int denoiser_offon_test_; - int denoiser_offon_period_; - int frame_parallel_decoding_mode_; - int delta_q_uv_; - bool use_roi_; - vpx_roi_map_t roi_; -}; - -// Params: test mode, speed setting and index for bitrate array. -class DatarateTestVP9RealTimeMultiBR - : public DatarateTestVP9, - public ::libvpx_test::CodecTestWith2Params { - public: - DatarateTestVP9RealTimeMultiBR() : DatarateTestVP9(GET_PARAM(0)) {} - - protected: - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - set_cpu_used_ = GET_PARAM(1); - ResetModel(); - } -}; - -// Params: speed setting and index for bitrate array. -class DatarateTestVP9LargeVBR - : public DatarateTestVP9, - public ::libvpx_test::CodecTestWith2Params { - public: - DatarateTestVP9LargeVBR() : DatarateTestVP9(GET_PARAM(0)) {} - - protected: - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - set_cpu_used_ = GET_PARAM(1); - ResetModel(); - } -}; - -// Check basic rate targeting for VBR mode with 0 lag. -TEST_P(DatarateTestVP9LargeVBR, BasicRateTargetingVBRLagZero) { - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_error_resilient = 0; - cfg_.rc_end_usage = VPX_VBR; - cfg_.g_lag_in_frames = 0; - - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 300); - - const int bitrates[2] = { 400, 800 }; - const int bitrate_index = GET_PARAM(2); - cfg_.rc_target_bitrate = bitrates[bitrate_index]; - ResetModel(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75) - << " The datarate for the file is lower than target by too much!"; - ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.36) - << " The datarate for the file is greater than target by too much!"; -} - -// Check basic rate targeting for VBR mode with non-zero lag. -TEST_P(DatarateTestVP9LargeVBR, BasicRateTargetingVBRLagNonZero) { - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_error_resilient = 0; - cfg_.rc_end_usage = VPX_VBR; - // For non-zero lag, rate control will work (be within bounds) for - // real-time mode. - if (deadline_ == VPX_DL_REALTIME) { - cfg_.g_lag_in_frames = 15; - } else { - cfg_.g_lag_in_frames = 0; - } - - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 300); - const int bitrates[2] = { 400, 800 }; - const int bitrate_index = GET_PARAM(2); - cfg_.rc_target_bitrate = bitrates[bitrate_index]; - ResetModel(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75) - << " The datarate for the file is lower than target by too much!"; - ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.35) - << " The datarate for the file is greater than target by too much!"; -} - -// Check basic rate targeting for VBR mode with non-zero lag, with -// frame_parallel_decoding_mode off. This enables the adapt_coeff/mode/mv probs -// since error_resilience is off. -TEST_P(DatarateTestVP9LargeVBR, BasicRateTargetingVBRLagNonZeroFrameParDecOff) { - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.g_error_resilient = 0; - cfg_.rc_end_usage = VPX_VBR; - // For non-zero lag, rate control will work (be within bounds) for - // real-time mode. - if (deadline_ == VPX_DL_REALTIME) { - cfg_.g_lag_in_frames = 15; - } else { - cfg_.g_lag_in_frames = 0; - } - - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 300); - const int bitrates[2] = { 400, 800 }; - const int bitrate_index = GET_PARAM(2); - cfg_.rc_target_bitrate = bitrates[bitrate_index]; - ResetModel(); - frame_parallel_decoding_mode_ = 0; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75) - << " The datarate for the file is lower than target by too much!"; - ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.35) - << " The datarate for the file is greater than target by too much!"; -} - -// Check basic rate targeting for CBR mode. -TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargeting) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 1; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - const int bitrates[4] = { 150, 350, 550, 750 }; - const int bitrate_index = GET_PARAM(2); - cfg_.rc_target_bitrate = bitrates[bitrate_index]; - ResetModel(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85) - << " The datarate for the file is lower than target by too much!"; - ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15) - << " The datarate for the file is greater than target by too much!"; -} - -// Check basic rate targeting for CBR mode, with frame_parallel_decoding_mode -// off( and error_resilience off). -TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargetingFrameParDecOff) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 1; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.g_error_resilient = 0; - - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - const int bitrates[4] = { 150, 350, 550, 750 }; - const int bitrate_index = GET_PARAM(2); - cfg_.rc_target_bitrate = bitrates[bitrate_index]; - ResetModel(); - frame_parallel_decoding_mode_ = 0; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85) - << " The datarate for the file is lower than target by too much!"; - ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15) - << " The datarate for the file is greater than target by too much!"; -} - -// Check basic rate targeting for CBR. -TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargeting444) { - ::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140); - - cfg_.g_profile = 1; - cfg_.g_timebase = video.timebase(); - - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 1; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.rc_end_usage = VPX_CBR; - const int bitrates[4] = { 250, 450, 650, 850 }; - const int bitrate_index = GET_PARAM(2); - cfg_.rc_target_bitrate = bitrates[bitrate_index]; - ResetModel(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(static_cast(cfg_.rc_target_bitrate), - effective_datarate_[0] * 0.80) - << " The datarate for the file exceeds the target by too much!"; - ASSERT_LE(static_cast(cfg_.rc_target_bitrate), - effective_datarate_[0] * 1.15) - << " The datarate for the file missed the target!" - << cfg_.rc_target_bitrate << " " << effective_datarate_; -} - -// Check that (1) the first dropped frame gets earlier and earlier -// as the drop frame threshold is increased, and (2) that the total number of -// frame drops does not decrease as we increase frame drop threshold. -// Use a lower qp-max to force some frame drops. -TEST_P(DatarateTestVP9RealTimeMultiBR, ChangingDropFrameThresh) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_undershoot_pct = 20; - cfg_.rc_undershoot_pct = 20; - cfg_.rc_dropframe_thresh = 10; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 50; - cfg_.rc_end_usage = VPX_CBR; - cfg_.rc_target_bitrate = 200; - cfg_.g_lag_in_frames = 0; - // TODO(marpan): Investigate datarate target failures with a smaller keyframe - // interval (128). - cfg_.kf_max_dist = 9999; - - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - - const int kDropFrameThreshTestStep = 30; - const int bitrates[2] = { 50, 150 }; - const int bitrate_index = GET_PARAM(2); - if (bitrate_index > 1) return; - cfg_.rc_target_bitrate = bitrates[bitrate_index]; - vpx_codec_pts_t last_drop = 140; - int last_num_drops = 0; - for (int i = 10; i < 100; i += kDropFrameThreshTestStep) { - cfg_.rc_dropframe_thresh = i; - ResetModel(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85) - << " The datarate for the file is lower than target by too much!"; - ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25) - << " The datarate for the file is greater than target by too much!"; - ASSERT_LE(first_drop_, last_drop) - << " The first dropped frame for drop_thresh " << i - << " > first dropped frame for drop_thresh " - << i - kDropFrameThreshTestStep; - ASSERT_GE(num_drops_, last_num_drops * 0.85) - << " The number of dropped frames for drop_thresh " << i - << " < number of dropped frames for drop_thresh " - << i - kDropFrameThreshTestStep; - last_drop = first_drop_; - last_num_drops = num_drops_; - } -} // namespace - -// Check basic rate targeting for 2 temporal layers. -TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargeting2TemporalLayers) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 1; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - - // 2 Temporal layers, no spatial layers: Framerate decimation (2, 1). - cfg_.ss_number_layers = 1; - cfg_.ts_number_layers = 2; - cfg_.ts_rate_decimator[0] = 2; - cfg_.ts_rate_decimator[1] = 1; - - cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS; - - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - const int bitrates[4] = { 200, 400, 600, 800 }; - const int bitrate_index = GET_PARAM(2); - cfg_.rc_target_bitrate = bitrates[bitrate_index]; - ResetModel(); - // 60-40 bitrate allocation for 2 temporal layers. - cfg_.layer_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100; - cfg_.layer_target_bitrate[1] = cfg_.rc_target_bitrate; - aq_mode_ = 0; - if (deadline_ == VPX_DL_REALTIME) { - aq_mode_ = 3; - cfg_.g_error_resilient = 1; - } - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - for (int j = 0; j < static_cast(cfg_.ts_number_layers); ++j) { - ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85) - << " The datarate for the file is lower than target by too much, " - "for layer: " - << j; - ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15) - << " The datarate for the file is greater than target by too much, " - "for layer: " - << j; - } -} - -// Check basic rate targeting for 3 temporal layers. -TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargeting3TemporalLayers) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 1; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - - // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1). - cfg_.ss_number_layers = 1; - cfg_.ts_number_layers = 3; - cfg_.ts_rate_decimator[0] = 4; - cfg_.ts_rate_decimator[1] = 2; - cfg_.ts_rate_decimator[2] = 1; - - cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS; - - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - const int bitrates[4] = { 200, 400, 600, 800 }; - const int bitrate_index = GET_PARAM(2); - cfg_.rc_target_bitrate = bitrates[bitrate_index]; - ResetModel(); - // 40-20-40 bitrate allocation for 3 temporal layers. - cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100; - cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100; - cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate; - aq_mode_ = 0; - if (deadline_ == VPX_DL_REALTIME) { - aq_mode_ = 3; - cfg_.g_error_resilient = 1; - } - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - for (int j = 0; j < static_cast(cfg_.ts_number_layers); ++j) { - // TODO(yaowu): Work out more stable rc control strategy and - // Adjust the thresholds to be tighter than .75. - ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.75) - << " The datarate for the file is lower than target by too much, " - "for layer: " - << j; - // TODO(yaowu): Work out more stable rc control strategy and - // Adjust the thresholds to be tighter than 1.25. - ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.25) - << " The datarate for the file is greater than target by too much, " - "for layer: " - << j; - } -} - -// Params: speed setting. -class DatarateTestVP9RealTime : public DatarateTestVP9, - public ::libvpx_test::CodecTestWithParam { - public: - DatarateTestVP9RealTime() : DatarateTestVP9(GET_PARAM(0)) {} - ~DatarateTestVP9RealTime() override = default; - - protected: - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - set_cpu_used_ = GET_PARAM(1); - ResetModel(); - } -}; - -// Check basic rate targeting for CBR mode, with 2 threads and dropped frames. -TEST_P(DatarateTestVP9RealTime, BasicRateTargetingDropFramesMultiThreads) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 30; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - // Encode using multiple threads. - cfg_.g_threads = 2; - - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - cfg_.rc_target_bitrate = 200; - ResetModel(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85) - << " The datarate for the file is lower than target by too much!"; - ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15) - << " The datarate for the file is greater than target by too much!"; -} - -// Check basic rate targeting for 3 temporal layers, with frame dropping. -// Only for one (low) bitrate with lower max_quantizer, and somewhat higher -// frame drop threshold, to force frame dropping. -TEST_P(DatarateTestVP9RealTime, - BasicRateTargeting3TemporalLayersFrameDropping) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - // Set frame drop threshold and rc_max_quantizer to force some frame drops. - cfg_.rc_dropframe_thresh = 20; - cfg_.rc_max_quantizer = 45; - cfg_.rc_min_quantizer = 0; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - - // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1). - cfg_.ss_number_layers = 1; - cfg_.ts_number_layers = 3; - cfg_.ts_rate_decimator[0] = 4; - cfg_.ts_rate_decimator[1] = 2; - cfg_.ts_rate_decimator[2] = 1; - - cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS; - - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - cfg_.rc_target_bitrate = 200; - ResetModel(); - // 40-20-40 bitrate allocation for 3 temporal layers. - cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100; - cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100; - cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate; - aq_mode_ = 0; - if (deadline_ == VPX_DL_REALTIME) { - aq_mode_ = 3; - cfg_.g_error_resilient = 1; - } - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - for (int j = 0; j < static_cast(cfg_.ts_number_layers); ++j) { - ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85) - << " The datarate for the file is lower than target by too much, " - "for layer: " - << j; - ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.20) - << " The datarate for the file is greater than target by too much, " - "for layer: " - << j; - // Expect some frame drops in this test: for this 200 frames test, - // expect at least 10% and not more than 60% drops. - ASSERT_GE(num_drops_, 20); - ASSERT_LE(num_drops_, 280); - } -} - -// Check VP9 region of interest feature. -TEST_P(DatarateTestVP9RealTime, RegionOfInterest) { - if (deadline_ != VPX_DL_REALTIME || set_cpu_used_ < 5) return; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 0; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - - cfg_.rc_target_bitrate = 450; - cfg_.g_w = 640; - cfg_.g_h = 480; - - ResetModel(); - - // Set ROI parameters - use_roi_ = true; - memset(&roi_, 0, sizeof(roi_)); - - roi_.rows = (cfg_.g_h + 7) / 8; - roi_.cols = (cfg_.g_w + 7) / 8; - - roi_.delta_q[1] = -20; - roi_.delta_lf[1] = -20; - memset(roi_.ref_frame, -1, sizeof(roi_.ref_frame)); - roi_.ref_frame[1] = 1; - - // Use 2 states: 1 is center square, 0 is the rest. - roi_.roi_map = reinterpret_cast( - calloc(roi_.rows * roi_.cols, sizeof(*roi_.roi_map))); - ASSERT_NE(roi_.roi_map, nullptr); - - for (unsigned int i = 0; i < roi_.rows; ++i) { - for (unsigned int j = 0; j < roi_.cols; ++j) { - if (i > (roi_.rows >> 2) && i < ((roi_.rows * 3) >> 2) && - j > (roi_.cols >> 2) && j < ((roi_.cols * 3) >> 2)) { - roi_.roi_map[i * roi_.cols + j] = 1; - } - } - } - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_[0] * 0.90) - << " The datarate for the file exceeds the target!"; - - ASSERT_LE(cfg_.rc_target_bitrate, effective_datarate_[0] * 1.4) - << " The datarate for the file missed the target!"; - - free(roi_.roi_map); -} - -// Params: speed setting, delta q UV. -class DatarateTestVP9RealTimeDeltaQUV - : public DatarateTestVP9, - public ::libvpx_test::CodecTestWith2Params { - public: - DatarateTestVP9RealTimeDeltaQUV() : DatarateTestVP9(GET_PARAM(0)) {} - ~DatarateTestVP9RealTimeDeltaQUV() override = default; - - protected: - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - set_cpu_used_ = GET_PARAM(1); - ResetModel(); - } -}; - -TEST_P(DatarateTestVP9RealTimeDeltaQUV, DeltaQUV) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 0; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - - cfg_.rc_target_bitrate = 450; - cfg_.g_w = 640; - cfg_.g_h = 480; - - ResetModel(); - - delta_q_uv_ = GET_PARAM(2); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_[0] * 0.90) - << " The datarate for the file exceeds the target!"; - - ASSERT_LE(cfg_.rc_target_bitrate, effective_datarate_[0] * 1.4) - << " The datarate for the file missed the target!"; -} - -// Params: test mode, speed setting and index for bitrate array. -class DatarateTestVP9PostEncodeDrop - : public DatarateTestVP9, - public ::libvpx_test::CodecTestWithParam { - public: - DatarateTestVP9PostEncodeDrop() : DatarateTestVP9(GET_PARAM(0)) {} - - protected: - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - set_cpu_used_ = GET_PARAM(1); - ResetModel(); - } -}; - -// Check basic rate targeting for CBR mode, with 2 threads and dropped frames. -TEST_P(DatarateTestVP9PostEncodeDrop, PostEncodeDropScreenContent) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 30; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - // Encode using multiple threads. - cfg_.g_threads = 2; - cfg_.g_error_resilient = 0; - tune_content_ = 1; - ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - 30, 1, 0, 300); - cfg_.rc_target_bitrate = 300; - ResetModel(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85) - << " The datarate for the file is lower than target by too much!"; - ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15) - << " The datarate for the file is greater than target by too much!"; -} - -using libvpx_test::ACMRandom; - -class DatarateTestVP9FrameQp - : public DatarateTestVP9, - public ::testing::TestWithParam { - public: - DatarateTestVP9FrameQp() : DatarateTestVP9(GetParam()), frame_(0) {} - ~DatarateTestVP9FrameQp() override = default; - - protected: - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - ResetModel(); - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - set_cpu_used_ = 7; - DatarateTestVP9::PreEncodeFrameHook(video, encoder); - frame_qp_ = static_cast(rnd_.RandRange(64)); - encoder->Control(VP9E_SET_QUANTIZER_ONE_PASS, frame_qp_); - frame_++; - } - - void PostEncodeFrameHook(::libvpx_test::Encoder *encoder) override { - int qp = 0; - vpx_svc_layer_id_t layer_id; - if (frame_ >= total_frame_) return; - encoder->Control(VP8E_GET_LAST_QUANTIZER_64, &qp); - ASSERT_EQ(frame_qp_, qp); - encoder->Control(VP9E_GET_SVC_LAYER_ID, &layer_id); - temporal_layer_id_ = layer_id.temporal_layer_id; - } - - void MismatchHook(const vpx_image_t * /*img1*/, - const vpx_image_t * /*img2*/) override { - if (frame_ >= total_frame_) return; - ASSERT_TRUE(cfg_.temporal_layering_mode == - VP9E_TEMPORAL_LAYERING_MODE_0212 && - temporal_layer_id_ == 2); - } - - protected: - int total_frame_; - - private: - ACMRandom rnd_; - int frame_qp_; - int frame_; - int temporal_layer_id_; -}; - -TEST_P(DatarateTestVP9FrameQp, VP9SetFrameQp) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 0; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 63; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - - total_frame_ = 400; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, total_frame_); - ResetModel(); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -TEST_P(DatarateTestVP9FrameQp, VP9SetFrameQp3TemporalLayersBypass) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 0; - cfg_.rc_max_quantizer = 63; - cfg_.rc_min_quantizer = 0; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - - // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1). - cfg_.ss_number_layers = 1; - cfg_.ts_number_layers = 3; - cfg_.ts_rate_decimator[0] = 4; - cfg_.ts_rate_decimator[1] = 2; - cfg_.ts_rate_decimator[2] = 1; - - cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS; - cfg_.rc_target_bitrate = 200; - total_frame_ = 400; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, total_frame_); - ResetModel(); - cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100; - cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100; - cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -TEST_P(DatarateTestVP9FrameQp, VP9SetFrameQp3TemporalLayersFixedMode) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 0; - cfg_.rc_max_quantizer = 63; - cfg_.rc_min_quantizer = 0; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - - // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1). - cfg_.ss_number_layers = 1; - cfg_.ts_number_layers = 3; - cfg_.ts_rate_decimator[0] = 4; - cfg_.ts_rate_decimator[1] = 2; - cfg_.ts_rate_decimator[2] = 1; - - cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_0212; - cfg_.rc_target_bitrate = 200; - cfg_.g_error_resilient = 1; - total_frame_ = 400; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, total_frame_); - ResetModel(); - cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100; - cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100; - cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -#if CONFIG_VP9_TEMPORAL_DENOISING -// Params: speed setting. -class DatarateTestVP9RealTimeDenoiser : public DatarateTestVP9RealTime { - public: - ~DatarateTestVP9RealTimeDenoiser() override = default; -}; - -// Check basic datarate targeting, for a single bitrate, when denoiser is on. -TEST_P(DatarateTestVP9RealTimeDenoiser, LowNoise) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 1; - cfg_.rc_min_quantizer = 2; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - - // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING), - // there is only one denoiser mode: denoiserYonly(which is 1), - // but may add more modes in the future. - cfg_.rc_target_bitrate = 400; - ResetModel(); - // Turn on the denoiser. - denoiser_on_ = 1; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85) - << " The datarate for the file is lower than target by too much!"; - ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15) - << " The datarate for the file is greater than target by too much!"; -} - -// Check basic datarate targeting, for a single bitrate, when denoiser is on, -// for clip with high noise level. Use 2 threads. -TEST_P(DatarateTestVP9RealTimeDenoiser, HighNoise) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 1; - cfg_.rc_min_quantizer = 2; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.g_threads = 2; - - ::libvpx_test::Y4mVideoSource video("noisy_clip_640_360.y4m", 0, 200); - - // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING), - // there is only one denoiser mode: kDenoiserOnYOnly(which is 1), - // but may add more modes in the future. - cfg_.rc_target_bitrate = 1000; - ResetModel(); - // Turn on the denoiser. - denoiser_on_ = 1; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85) - << " The datarate for the file is lower than target by too much!"; - ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15) - << " The datarate for the file is greater than target by too much!"; -} - -// Check basic datarate targeting, for a single bitrate, when denoiser is on, -// for 1280x720 clip with 4 threads. -TEST_P(DatarateTestVP9RealTimeDenoiser, 4threads) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 1; - cfg_.rc_min_quantizer = 2; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.g_threads = 4; - - ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300); - - // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING), - // there is only one denoiser mode: denoiserYonly(which is 1), - // but may add more modes in the future. - cfg_.rc_target_bitrate = 1000; - ResetModel(); - // Turn on the denoiser. - denoiser_on_ = 1; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85) - << " The datarate for the file is lower than target by too much!"; - ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.29) - << " The datarate for the file is greater than target by too much!"; -} - -// Check basic datarate targeting, for a single bitrate, when denoiser is off -// and on. -TEST_P(DatarateTestVP9RealTimeDenoiser, DenoiserOffOn) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 1; - cfg_.rc_min_quantizer = 2; - cfg_.rc_max_quantizer = 56; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - - // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING), - // there is only one denoiser mode: denoiserYonly(which is 1), - // but may add more modes in the future. - cfg_.rc_target_bitrate = 400; - ResetModel(); - // The denoiser is off by default. - denoiser_on_ = 0; - // Set the offon test flag. - denoiser_offon_test_ = 1; - denoiser_offon_period_ = 100; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85) - << " The datarate for the file is lower than target by too much!"; - ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15) - << " The datarate for the file is greater than target by too much!"; -} -#endif // CONFIG_VP9_TEMPORAL_DENOISING - -VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9RealTimeMultiBR, - ::testing::Range(5, 10), ::testing::Range(0, 4)); - -VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9LargeVBR, ::testing::Range(5, 9), - ::testing::Range(0, 2)); - -VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9RealTime, ::testing::Range(5, 10)); - -#if CONFIG_VP9 -INSTANTIATE_TEST_SUITE_P( - VP9, DatarateTestVP9FrameQp, - ::testing::Values( - static_cast(&libvpx_test::kVP9))); -#endif - -VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9RealTimeDeltaQUV, - ::testing::Range(5, 10), - ::testing::Values(-5, -10, -15)); - -VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9PostEncodeDrop, - ::testing::Range(5, 6)); - -#if CONFIG_VP9_TEMPORAL_DENOISING -VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9RealTimeDenoiser, - ::testing::Range(5, 10)); -#endif -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_decrypt_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_decrypt_test.cc deleted file mode 100644 index 558ee703..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_decrypt_test.cc +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/ivf_video_source.h" - -namespace { -// In a real use the 'decrypt_state' parameter will be a pointer to a struct -// with whatever internal state the decryptor uses. For testing we'll just -// xor with a constant key, and decrypt_state will point to the start of -// the original buffer. -const uint8_t test_key[16] = { 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, - 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0 }; - -void encrypt_buffer(const uint8_t *src, uint8_t *dst, size_t size, - ptrdiff_t offset) { - for (size_t i = 0; i < size; ++i) { - dst[i] = src[i] ^ test_key[(offset + i) & 15]; - } -} - -void test_decrypt_cb(void *decrypt_state, const uint8_t *input, uint8_t *output, - int count) { - encrypt_buffer(input, output, count, - input - reinterpret_cast(decrypt_state)); -} - -} // namespace - -namespace libvpx_test { - -TEST(TestDecrypt, DecryptWorksVp9) { - libvpx_test::IVFVideoSource video("vp90-2-05-resize.ivf"); - video.Init(); - - vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t(); - VP9Decoder decoder(dec_cfg, 0); - - video.Begin(); - - // no decryption - vpx_codec_err_t res = decoder.DecodeFrame(video.cxdata(), video.frame_size()); - ASSERT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError(); - - // decrypt frame - video.Next(); - - std::vector encrypted(video.frame_size()); - encrypt_buffer(video.cxdata(), &encrypted[0], video.frame_size(), 0); - vpx_decrypt_init di = { test_decrypt_cb, &encrypted[0] }; - decoder.Control(VPXD_SET_DECRYPTOR, &di); - - res = decoder.DecodeFrame(&encrypted[0], encrypted.size()); - ASSERT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError(); -} - -} // namespace libvpx_test diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_denoiser_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_denoiser_test.cc deleted file mode 100644 index f2a1cae4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_denoiser_test.cc +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "gtest/gtest.h" -#include "test/acm_random.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" - -#include "vpx_scale/yv12config.h" -#include "vpx/vpx_integer.h" -#include "vp9/common/vp9_reconinter.h" -#include "vp9/encoder/vp9_context_tree.h" -#include "vp9/encoder/vp9_denoiser.h" -#include "vpx_config.h" - -using libvpx_test::ACMRandom; - -namespace { - -const int kNumPixels = 64 * 64; - -typedef int (*Vp9DenoiserFilterFunc)(const uint8_t *sig, int sig_stride, - const uint8_t *mc_avg, int mc_avg_stride, - uint8_t *avg, int avg_stride, - int increase_denoising, BLOCK_SIZE bs, - int motion_magnitude); -typedef std::tuple VP9DenoiserTestParam; - -class VP9DenoiserTest - : public ::testing::Test, - public ::testing::WithParamInterface { - public: - ~VP9DenoiserTest() override = default; - - void SetUp() override { bs_ = GET_PARAM(1); } - - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - BLOCK_SIZE bs_; -}; -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VP9DenoiserTest); - -TEST_P(VP9DenoiserTest, BitexactCheck) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int count_test_block = 4000; - - // Allocate the space for input and output, - // where sig_block is the block to be denoised, - // mc_avg_block is the denoised reference block, - // avg_block_c is the denoised result from C code, - // avg_block_sse2 is the denoised result from SSE2 code. - DECLARE_ALIGNED(16, uint8_t, sig_block[kNumPixels]); - DECLARE_ALIGNED(16, uint8_t, mc_avg_block[kNumPixels]); - DECLARE_ALIGNED(16, uint8_t, avg_block_c[kNumPixels]); - DECLARE_ALIGNED(16, uint8_t, avg_block_sse2[kNumPixels]); - - for (int i = 0; i < count_test_block; ++i) { - // Generate random motion magnitude, 20% of which exceed the threshold. - const int motion_magnitude_random = - rnd.Rand8() % static_cast(MOTION_MAGNITUDE_THRESHOLD * 1.2); - - // Initialize a test block with random number in range [0, 255]. - for (int j = 0; j < kNumPixels; ++j) { - int temp = 0; - sig_block[j] = rnd.Rand8(); - // The pixels in mc_avg_block are generated by adding a random - // number in range [-19, 19] to corresponding pixels in sig_block. - temp = - sig_block[j] + ((rnd.Rand8() % 2 == 0) ? -1 : 1) * (rnd.Rand8() % 20); - // Clip. - mc_avg_block[j] = (temp < 0) ? 0 : ((temp > 255) ? 255 : temp); - } - - ASM_REGISTER_STATE_CHECK(vp9_denoiser_filter_c(sig_block, 64, mc_avg_block, - 64, avg_block_c, 64, 0, bs_, - motion_magnitude_random)); - - ASM_REGISTER_STATE_CHECK(GET_PARAM(0)(sig_block, 64, mc_avg_block, 64, - avg_block_sse2, 64, 0, bs_, - motion_magnitude_random)); - - // Test bitexactness. - for (int h = 0; h < (4 << b_height_log2_lookup[bs_]); ++h) { - for (int w = 0; w < (4 << b_width_log2_lookup[bs_]); ++w) { - EXPECT_EQ(avg_block_c[h * 64 + w], avg_block_sse2[h * 64 + w]); - } - } - } -} - -using std::make_tuple; - -// Test for all block size. -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P( - SSE2, VP9DenoiserTest, - ::testing::Values(make_tuple(&vp9_denoiser_filter_sse2, BLOCK_8X8), - make_tuple(&vp9_denoiser_filter_sse2, BLOCK_8X16), - make_tuple(&vp9_denoiser_filter_sse2, BLOCK_16X8), - make_tuple(&vp9_denoiser_filter_sse2, BLOCK_16X16), - make_tuple(&vp9_denoiser_filter_sse2, BLOCK_16X32), - make_tuple(&vp9_denoiser_filter_sse2, BLOCK_32X16), - make_tuple(&vp9_denoiser_filter_sse2, BLOCK_32X32), - make_tuple(&vp9_denoiser_filter_sse2, BLOCK_32X64), - make_tuple(&vp9_denoiser_filter_sse2, BLOCK_64X32), - make_tuple(&vp9_denoiser_filter_sse2, BLOCK_64X64))); -#endif // HAVE_SSE2 - -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P( - NEON, VP9DenoiserTest, - ::testing::Values(make_tuple(&vp9_denoiser_filter_neon, BLOCK_8X8), - make_tuple(&vp9_denoiser_filter_neon, BLOCK_8X16), - make_tuple(&vp9_denoiser_filter_neon, BLOCK_16X8), - make_tuple(&vp9_denoiser_filter_neon, BLOCK_16X16), - make_tuple(&vp9_denoiser_filter_neon, BLOCK_16X32), - make_tuple(&vp9_denoiser_filter_neon, BLOCK_32X16), - make_tuple(&vp9_denoiser_filter_neon, BLOCK_32X32), - make_tuple(&vp9_denoiser_filter_neon, BLOCK_32X64), - make_tuple(&vp9_denoiser_filter_neon, BLOCK_64X32), - make_tuple(&vp9_denoiser_filter_neon, BLOCK_64X64))); -#endif -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_encoder_parms_get_to_decoder.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_encoder_parms_get_to_decoder.cc deleted file mode 100644 index 00860789..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_encoder_parms_get_to_decoder.cc +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "gtest/gtest.h" - -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/util.h" -#include "test/y4m_video_source.h" -#include "vp9/vp9_dx_iface.h" - -namespace { - -const int kCpuUsed = 2; - -struct EncodePerfTestVideo { - const char *name; - uint32_t width; - uint32_t height; - uint32_t bitrate; - int frames; -}; - -const EncodePerfTestVideo kVP9EncodePerfTestVectors[] = { - { "niklas_1280_720_30.y4m", 1280, 720, 600, 10 }, -}; - -struct EncodeParameters { - int32_t tile_rows; - int32_t tile_cols; - int32_t lossless; - int32_t error_resilient; - int32_t frame_parallel; - vpx_color_range_t color_range; - vpx_color_space_t cs; - int render_size[2]; - // TODO(JBB): quantizers / bitrate -}; - -const EncodeParameters kVP9EncodeParameterSet[] = { - { 0, 0, 0, 1, 0, VPX_CR_STUDIO_RANGE, VPX_CS_BT_601, { 0, 0 } }, - { 0, 0, 0, 0, 0, VPX_CR_FULL_RANGE, VPX_CS_BT_709, { 0, 0 } }, - { 0, 0, 1, 0, 0, VPX_CR_FULL_RANGE, VPX_CS_BT_2020, { 0, 0 } }, - { 0, 2, 0, 0, 1, VPX_CR_STUDIO_RANGE, VPX_CS_UNKNOWN, { 640, 480 } }, - // TODO(JBB): Test profiles (requires more work). -}; - -class VpxEncoderParmsGetToDecoder - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith2Params { - protected: - VpxEncoderParmsGetToDecoder() - : EncoderTest(GET_PARAM(0)), encode_parms(GET_PARAM(1)) {} - - ~VpxEncoderParmsGetToDecoder() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kTwoPassGood); - cfg_.g_lag_in_frames = 25; - cfg_.g_error_resilient = encode_parms.error_resilient; - dec_cfg_.threads = 4; - test_video_ = GET_PARAM(2); - cfg_.rc_target_bitrate = test_video_.bitrate; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP9E_SET_COLOR_SPACE, encode_parms.cs); - encoder->Control(VP9E_SET_COLOR_RANGE, encode_parms.color_range); - encoder->Control(VP9E_SET_LOSSLESS, encode_parms.lossless); - encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, - encode_parms.frame_parallel); - encoder->Control(VP9E_SET_TILE_ROWS, encode_parms.tile_rows); - encoder->Control(VP9E_SET_TILE_COLUMNS, encode_parms.tile_cols); - encoder->Control(VP8E_SET_CPUUSED, kCpuUsed); - encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); - encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7); - encoder->Control(VP8E_SET_ARNR_STRENGTH, 5); - encoder->Control(VP8E_SET_ARNR_TYPE, 3); - if (encode_parms.render_size[0] > 0 && encode_parms.render_size[1] > 0) { - encoder->Control(VP9E_SET_RENDER_SIZE, encode_parms.render_size); - } - } - } - - bool HandleDecodeResult(const vpx_codec_err_t res_dec, - const libvpx_test::VideoSource & /*video*/, - libvpx_test::Decoder *decoder) override { - vpx_codec_ctx_t *const vp9_decoder = decoder->GetDecoder(); - vpx_codec_alg_priv_t *const priv = - reinterpret_cast(vp9_decoder->priv); - VP9_COMMON *const common = &priv->pbi->common; - - if (encode_parms.lossless) { - EXPECT_EQ(0, common->base_qindex); - EXPECT_EQ(0, common->y_dc_delta_q); - EXPECT_EQ(0, common->uv_dc_delta_q); - EXPECT_EQ(0, common->uv_ac_delta_q); - EXPECT_EQ(ONLY_4X4, common->tx_mode); - } - EXPECT_EQ(encode_parms.error_resilient, common->error_resilient_mode); - if (encode_parms.error_resilient) { - EXPECT_EQ(1, common->frame_parallel_decoding_mode); - EXPECT_EQ(0, common->use_prev_frame_mvs); - } else { - EXPECT_EQ(encode_parms.frame_parallel, - common->frame_parallel_decoding_mode); - } - EXPECT_EQ(encode_parms.color_range, common->color_range); - EXPECT_EQ(encode_parms.cs, common->color_space); - if (encode_parms.render_size[0] > 0 && encode_parms.render_size[1] > 0) { - EXPECT_EQ(encode_parms.render_size[0], common->render_width); - EXPECT_EQ(encode_parms.render_size[1], common->render_height); - } - EXPECT_EQ(encode_parms.tile_cols, common->log2_tile_cols); - EXPECT_EQ(encode_parms.tile_rows, common->log2_tile_rows); - - EXPECT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError(); - return VPX_CODEC_OK == res_dec; - } - - EncodePerfTestVideo test_video_; - - private: - EncodeParameters encode_parms; -}; - -TEST_P(VpxEncoderParmsGetToDecoder, BitstreamParms) { - init_flags_ = VPX_CODEC_USE_PSNR; - - std::unique_ptr video( - new libvpx_test::Y4mVideoSource(test_video_.name, 0, test_video_.frames)); - ASSERT_NE(video.get(), nullptr); - - ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); -} - -VP9_INSTANTIATE_TEST_SUITE(VpxEncoderParmsGetToDecoder, - ::testing::ValuesIn(kVP9EncodeParameterSet), - ::testing::ValuesIn(kVP9EncodePerfTestVectors)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_end_to_end_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_end_to_end_test.cc deleted file mode 100644 index 61e6119e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_end_to_end_test.cc +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "memory" - -#include "gtest/gtest.h" - -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" -#include "test/y4m_video_source.h" -#include "test/yuv_video_source.h" -#include "vpx_config.h" - -namespace { - -const unsigned int kWidth = 160; -const unsigned int kHeight = 90; -const unsigned int kFramerate = 50; -const unsigned int kFrames = 20; -const int kBitrate = 500; -// List of psnr thresholds for speed settings 0-7 and 5 encoding modes -const double kPsnrThreshold[][5] = { - { 36.0, 37.0, 37.0, 37.0, 37.0 }, { 35.0, 36.0, 36.0, 36.0, 36.0 }, - { 34.0, 35.0, 35.0, 35.0, 35.0 }, { 33.0, 34.0, 34.0, 34.0, 34.0 }, - { 32.0, 33.0, 33.0, 33.0, 33.0 }, { 28.0, 32.0, 32.0, 32.0, 32.0 }, - { 28.4, 31.0, 31.0, 31.0, 31.0 }, { 27.5, 30.0, 30.0, 30.0, 30.0 }, -}; - -typedef struct { - const char *filename; - unsigned int input_bit_depth; - vpx_img_fmt fmt; - vpx_bit_depth_t bit_depth; - unsigned int profile; -} TestVideoParam; - -const TestVideoParam kTestVectors[] = { - { "park_joy_90p_8_420.y4m", 8, VPX_IMG_FMT_I420, VPX_BITS_8, 0 }, - { "park_joy_90p_8_422.y4m", 8, VPX_IMG_FMT_I422, VPX_BITS_8, 1 }, - { "park_joy_90p_8_444.y4m", 8, VPX_IMG_FMT_I444, VPX_BITS_8, 1 }, - { "park_joy_90p_8_440.yuv", 8, VPX_IMG_FMT_I440, VPX_BITS_8, 1 }, -#if CONFIG_VP9_HIGHBITDEPTH - { "park_joy_90p_10_420_20f.y4m", 10, VPX_IMG_FMT_I42016, VPX_BITS_10, 2 }, - { "park_joy_90p_10_422_20f.y4m", 10, VPX_IMG_FMT_I42216, VPX_BITS_10, 3 }, - { "park_joy_90p_10_444_20f.y4m", 10, VPX_IMG_FMT_I44416, VPX_BITS_10, 3 }, - { "park_joy_90p_10_440.yuv", 10, VPX_IMG_FMT_I44016, VPX_BITS_10, 3 }, - { "park_joy_90p_12_420_20f.y4m", 12, VPX_IMG_FMT_I42016, VPX_BITS_12, 2 }, - { "park_joy_90p_12_422_20f.y4m", 12, VPX_IMG_FMT_I42216, VPX_BITS_12, 3 }, - { "park_joy_90p_12_444_20f.y4m", 12, VPX_IMG_FMT_I44416, VPX_BITS_12, 3 }, - { "park_joy_90p_12_440.yuv", 12, VPX_IMG_FMT_I44016, VPX_BITS_12, 3 }, -#endif // CONFIG_VP9_HIGHBITDEPTH -}; - -const TestVideoParam kTestVectorsNv12[] = { - { "hantro_collage_w352h288_nv12.yuv", 8, VPX_IMG_FMT_NV12, VPX_BITS_8, 0 }, -}; - -// Encoding modes tested -const libvpx_test::TestMode kEncodingModeVectors[] = { -#if !CONFIG_REALTIME_ONLY - ::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood, -#endif - ::libvpx_test::kRealTime -}; - -// Speed settings tested -const int kCpuUsedVectors[] = { 1, 2, 3, 5, 6, 7 }; - -int is_extension_y4m(const char *filename) { - const char *dot = strrchr(filename, '.'); - if (!dot || dot == filename) { - return 0; - } else { - return !strcmp(dot, ".y4m"); - } -} - -class EndToEndTestAdaptiveRDThresh - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith2Params { - protected: - EndToEndTestAdaptiveRDThresh() - : EncoderTest(GET_PARAM(0)), cpu_used_start_(GET_PARAM(1)), - cpu_used_end_(GET_PARAM(2)) {} - - ~EndToEndTestAdaptiveRDThresh() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - cfg_.g_lag_in_frames = 0; - cfg_.rc_end_usage = VPX_CBR; - cfg_.rc_buf_sz = 1000; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 600; - dec_cfg_.threads = 4; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, cpu_used_start_); - encoder->Control(VP9E_SET_ROW_MT, 1); - encoder->Control(VP9E_SET_TILE_COLUMNS, 2); - } - if (video->frame() == 100) - encoder->Control(VP8E_SET_CPUUSED, cpu_used_end_); - } - - private: - int cpu_used_start_; - int cpu_used_end_; -}; - -class EndToEndTestLarge - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith3Params { - protected: - EndToEndTestLarge() - : EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(2)), - cpu_used_(GET_PARAM(3)), psnr_(0.0), nframes_(0), - encoding_mode_(GET_PARAM(1)) { - cyclic_refresh_ = 0; - denoiser_on_ = 0; - } - - ~EndToEndTestLarge() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(encoding_mode_); - if (encoding_mode_ != ::libvpx_test::kRealTime) { - cfg_.g_lag_in_frames = 5; - cfg_.rc_end_usage = VPX_VBR; - } else { - cfg_.g_lag_in_frames = 0; - cfg_.rc_end_usage = VPX_CBR; - cfg_.rc_buf_sz = 1000; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 600; - } - dec_cfg_.threads = 4; - } - - void BeginPassHook(unsigned int) override { - psnr_ = 0.0; - nframes_ = 0; - } - - void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) override { - psnr_ += pkt->data.psnr.psnr[0]; - nframes_++; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1); - encoder->Control(VP9E_SET_TILE_COLUMNS, 4); - encoder->Control(VP8E_SET_CPUUSED, cpu_used_); - if (encoding_mode_ != ::libvpx_test::kRealTime) { - encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); - encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7); - encoder->Control(VP8E_SET_ARNR_STRENGTH, 5); - encoder->Control(VP8E_SET_ARNR_TYPE, 3); - } else { - encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_); - encoder->Control(VP9E_SET_AQ_MODE, cyclic_refresh_); - } - } - } - - double GetAveragePsnr() const { - if (nframes_) return psnr_ / nframes_; - return 0.0; - } - - double GetPsnrThreshold() { - return kPsnrThreshold[cpu_used_][encoding_mode_]; - } - - TestVideoParam test_video_param_; - int cpu_used_; - int cyclic_refresh_; - int denoiser_on_; - - private: - double psnr_; - unsigned int nframes_; - libvpx_test::TestMode encoding_mode_; -}; - -#if CONFIG_VP9_DECODER -// The test parameters control VP9D_SET_LOOP_FILTER_OPT and the number of -// decoder threads. -class EndToEndTestLoopFilterThreading - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith2Params { - protected: - EndToEndTestLoopFilterThreading() - : EncoderTest(GET_PARAM(0)), use_loop_filter_opt_(GET_PARAM(1)) {} - - ~EndToEndTestLoopFilterThreading() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - cfg_.g_threads = 2; - cfg_.g_lag_in_frames = 0; - cfg_.rc_target_bitrate = 500; - cfg_.rc_end_usage = VPX_CBR; - cfg_.kf_min_dist = 1; - cfg_.kf_max_dist = 1; - dec_cfg_.threads = GET_PARAM(2); - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, 8); - } - encoder->Control(VP9E_SET_TILE_COLUMNS, 4 - video->frame() % 5); - } - - void PreDecodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Decoder *decoder) override { - if (video->frame() == 0) { - decoder->Control(VP9D_SET_LOOP_FILTER_OPT, use_loop_filter_opt_ ? 1 : 0); - } - } - - private: - const bool use_loop_filter_opt_; -}; -#endif // CONFIG_VP9_DECODER - -class EndToEndNV12 : public EndToEndTestLarge {}; - -TEST_P(EndToEndNV12, EndtoEndNV12Test) { - cfg_.rc_target_bitrate = kBitrate; - cfg_.g_error_resilient = 0; - cfg_.g_profile = test_video_param_.profile; - cfg_.g_input_bit_depth = test_video_param_.input_bit_depth; - cfg_.g_bit_depth = test_video_param_.bit_depth; - init_flags_ = VPX_CODEC_USE_PSNR; - if (cfg_.g_bit_depth > 8) init_flags_ |= VPX_CODEC_USE_HIGHBITDEPTH; - - std::unique_ptr video; - - video.reset(new libvpx_test::YUVVideoSource(test_video_param_.filename, - test_video_param_.fmt, 352, 288, - 30, 1, 0, 100)); - ASSERT_NE(video.get(), nullptr); - - ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); -} - -TEST_P(EndToEndTestLarge, EndtoEndPSNRTest) { - cfg_.rc_target_bitrate = kBitrate; - cfg_.g_error_resilient = 0; - cfg_.g_profile = test_video_param_.profile; - cfg_.g_input_bit_depth = test_video_param_.input_bit_depth; - cfg_.g_bit_depth = test_video_param_.bit_depth; - init_flags_ = VPX_CODEC_USE_PSNR; - if (cfg_.g_bit_depth > 8) init_flags_ |= VPX_CODEC_USE_HIGHBITDEPTH; - - std::unique_ptr video; - if (is_extension_y4m(test_video_param_.filename)) { - video.reset(new libvpx_test::Y4mVideoSource(test_video_param_.filename, 0, - kFrames)); - } else { - video.reset(new libvpx_test::YUVVideoSource( - test_video_param_.filename, test_video_param_.fmt, kWidth, kHeight, - kFramerate, 1, 0, kFrames)); - } - ASSERT_NE(video.get(), nullptr); - - ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); - const double psnr = GetAveragePsnr(); - EXPECT_GT(psnr, GetPsnrThreshold()); -} - -TEST_P(EndToEndTestLarge, EndtoEndPSNRDenoiserAQTest) { - cfg_.rc_target_bitrate = kBitrate; - cfg_.g_error_resilient = 0; - cfg_.g_profile = test_video_param_.profile; - cfg_.g_input_bit_depth = test_video_param_.input_bit_depth; - cfg_.g_bit_depth = test_video_param_.bit_depth; - init_flags_ = VPX_CODEC_USE_PSNR; - cyclic_refresh_ = 3; - denoiser_on_ = 1; - if (cfg_.g_bit_depth > 8) init_flags_ |= VPX_CODEC_USE_HIGHBITDEPTH; - - std::unique_ptr video; - if (is_extension_y4m(test_video_param_.filename)) { - video.reset(new libvpx_test::Y4mVideoSource(test_video_param_.filename, 0, - kFrames)); - } else { - video.reset(new libvpx_test::YUVVideoSource( - test_video_param_.filename, test_video_param_.fmt, kWidth, kHeight, - kFramerate, 1, 0, kFrames)); - } - ASSERT_NE(video.get(), nullptr); - - ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); - const double psnr = GetAveragePsnr(); - EXPECT_GT(psnr, GetPsnrThreshold()); -} - -TEST_P(EndToEndTestAdaptiveRDThresh, EndtoEndAdaptiveRDThreshRowMT) { - cfg_.rc_target_bitrate = kBitrate; - cfg_.g_error_resilient = 0; - cfg_.g_threads = 2; - ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, - 0, 400); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} - -#if CONFIG_VP9_DECODER -TEST_P(EndToEndTestLoopFilterThreading, TileCountChange) { - ::libvpx_test::RandomVideoSource video; - video.SetSize(4096, 2160); - video.set_limit(10); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} -#endif // CONFIG_VP9_DECODER - -VP9_INSTANTIATE_TEST_SUITE(EndToEndTestLarge, - ::testing::ValuesIn(kEncodingModeVectors), - ::testing::ValuesIn(kTestVectors), - ::testing::ValuesIn(kCpuUsedVectors)); - -VP9_INSTANTIATE_TEST_SUITE(EndToEndNV12, - ::testing::Values(::libvpx_test::kRealTime), - ::testing::ValuesIn(kTestVectorsNv12), - ::testing::Values(6, 7, 8)); - -VP9_INSTANTIATE_TEST_SUITE(EndToEndTestAdaptiveRDThresh, - ::testing::Values(5, 6, 7), ::testing::Values(8, 9)); - -#if CONFIG_VP9_DECODER -VP9_INSTANTIATE_TEST_SUITE(EndToEndTestLoopFilterThreading, ::testing::Bool(), - ::testing::Range(2, 6)); -#endif // CONFIG_VP9_DECODER -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_ethread_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_ethread_test.cc deleted file mode 100644 index 9e366eb3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_ethread_test.cc +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/md5_helper.h" -#include "test/util.h" -#include "test/y4m_video_source.h" -#include "vp9/encoder/vp9_firstpass.h" -#include "vpx_config.h" - -namespace { -// FIRSTPASS_STATS struct: -// { -// 26 double members; -// 1 int64_t member; -// } -// Whenever FIRSTPASS_STATS struct is modified, the following constants need to -// be revisited. -const int kDbl = 26; -const int kInt = 1; -const size_t kFirstPassStatsSz = kDbl * sizeof(double) + kInt * sizeof(int64_t); - -class VPxFirstPassEncoderThreadTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith2Params { - protected: - VPxFirstPassEncoderThreadTest() - : EncoderTest(GET_PARAM(0)), encoder_initialized_(false), tiles_(0), - encoding_mode_(GET_PARAM(1)), set_cpu_used_(GET_PARAM(2)) { - init_flags_ = VPX_CODEC_USE_PSNR; - - row_mt_mode_ = 1; - first_pass_only_ = true; - firstpass_stats_.buf = nullptr; - firstpass_stats_.sz = 0; - } - ~VPxFirstPassEncoderThreadTest() override { free(firstpass_stats_.buf); } - - void SetUp() override { - InitializeConfig(); - SetMode(encoding_mode_); - - cfg_.rc_end_usage = VPX_VBR; - cfg_.rc_2pass_vbr_minsection_pct = 5; - cfg_.rc_2pass_vbr_maxsection_pct = 2000; - cfg_.rc_max_quantizer = 56; - cfg_.rc_min_quantizer = 0; - } - - void BeginPassHook(unsigned int /*pass*/) override { - encoder_initialized_ = false; - abort_ = false; - } - - void EndPassHook() override { - // For first pass stats test, only run first pass encoder. - if (first_pass_only_ && cfg_.g_pass == VPX_RC_FIRST_PASS) - abort_ |= first_pass_only_; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource * /*video*/, - ::libvpx_test::Encoder *encoder) override { - if (!encoder_initialized_) { - // Encode in 2-pass mode. - encoder->Control(VP9E_SET_TILE_COLUMNS, tiles_); - encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_); - encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); - encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7); - encoder->Control(VP8E_SET_ARNR_STRENGTH, 5); - encoder->Control(VP8E_SET_ARNR_TYPE, 3); - encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 0); - - if (encoding_mode_ == ::libvpx_test::kTwoPassGood) - encoder->Control(VP9E_SET_ROW_MT, row_mt_mode_); - - encoder_initialized_ = true; - } - } - - void StatsPktHook(const vpx_codec_cx_pkt_t *pkt) override { - const uint8_t *const pkt_buf = - reinterpret_cast(pkt->data.twopass_stats.buf); - const size_t pkt_size = pkt->data.twopass_stats.sz; - - // First pass stats size equals sizeof(FIRSTPASS_STATS) - EXPECT_EQ(pkt_size, kFirstPassStatsSz) - << "Error: First pass stats size doesn't equal kFirstPassStatsSz"; - - firstpass_stats_.buf = - realloc(firstpass_stats_.buf, firstpass_stats_.sz + pkt_size); - ASSERT_NE(firstpass_stats_.buf, nullptr); - memcpy((uint8_t *)firstpass_stats_.buf + firstpass_stats_.sz, pkt_buf, - pkt_size); - firstpass_stats_.sz += pkt_size; - } - - bool encoder_initialized_; - int tiles_; - ::libvpx_test::TestMode encoding_mode_; - int set_cpu_used_; - int row_mt_mode_; - bool first_pass_only_; - vpx_fixed_buf_t firstpass_stats_; -}; - -#if !CONFIG_REALTIME_ONLY -static void compare_fp_stats(vpx_fixed_buf_t *fp_stats, double factor) { - // fp_stats consists of 2 set of first pass encoding stats. These 2 set of - // stats are compared to check if the stats match or at least are very close. - FIRSTPASS_STATS *stats1 = reinterpret_cast(fp_stats->buf); - int nframes_ = (int)(fp_stats->sz / sizeof(FIRSTPASS_STATS)); - FIRSTPASS_STATS *stats2 = stats1 + nframes_ / 2; - int i, j; - - // The total stats are also output and included in the first pass stats. Here - // ignore that in the comparison. - for (i = 0; i < (nframes_ / 2 - 1); ++i) { - const double *frame_stats1 = reinterpret_cast(stats1); - const double *frame_stats2 = reinterpret_cast(stats2); - - for (j = 0; j < kDbl; ++j) { - ASSERT_LE(fabs(*frame_stats1 - *frame_stats2), - fabs(*frame_stats1) / factor) - << "First failure @ frame #" << i << " stat #" << j << " (" - << *frame_stats1 << " vs. " << *frame_stats2 << ")"; - frame_stats1++; - frame_stats2++; - } - - stats1++; - stats2++; - } - - // Reset firstpass_stats_ to 0. - memset((uint8_t *)fp_stats->buf, 0, fp_stats->sz); - fp_stats->sz = 0; -} - -static void compare_fp_stats_md5(vpx_fixed_buf_t *fp_stats) { - // fp_stats consists of 2 set of first pass encoding stats. These 2 set of - // stats are compared to check if the stats match. - uint8_t *stats1 = reinterpret_cast(fp_stats->buf); - uint8_t *stats2 = stats1 + fp_stats->sz / 2; - ::libvpx_test::MD5 md5_row_mt_0, md5_row_mt_1; - - md5_row_mt_0.Add(stats1, fp_stats->sz / 2); - const char *md5_row_mt_0_str = md5_row_mt_0.Get(); - - md5_row_mt_1.Add(stats2, fp_stats->sz / 2); - const char *md5_row_mt_1_str = md5_row_mt_1.Get(); - - // Check md5 match. - ASSERT_STREQ(md5_row_mt_0_str, md5_row_mt_1_str) - << "MD5 checksums don't match"; - - // Reset firstpass_stats_ to 0. - memset((uint8_t *)fp_stats->buf, 0, fp_stats->sz); - fp_stats->sz = 0; -} -#endif // !CONFIG_REALTIME_ONLY - -TEST_P(VPxFirstPassEncoderThreadTest, FirstPassStatsTest) { -#if CONFIG_REALTIME_ONLY - GTEST_SKIP(); -#else - ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60); - - first_pass_only_ = true; - cfg_.rc_target_bitrate = 1000; - - // Test row_mt_mode: 0 vs 1 at single thread case(threads = 1, tiles_ = 0) - tiles_ = 0; - cfg_.g_threads = 1; - - row_mt_mode_ = 0; - init_flags_ = VPX_CODEC_USE_PSNR; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - row_mt_mode_ = 1; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - // Compare to check if using or not using row-mt generates close stats. - ASSERT_NO_FATAL_FAILURE(compare_fp_stats(&firstpass_stats_, 400.0)); - - // Test single thread vs multiple threads - row_mt_mode_ = 1; - tiles_ = 0; - - cfg_.g_threads = 1; - init_flags_ = VPX_CODEC_USE_PSNR; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - cfg_.g_threads = 4; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - // Compare to check if single-thread and multi-thread stats are close enough. - ASSERT_NO_FATAL_FAILURE(compare_fp_stats(&firstpass_stats_, 400.0)); - - // Bit exact test in row_mt mode. - // When row_mt_mode_=1 and using >1 threads, the encoder generates bit exact - // result. - row_mt_mode_ = 1; - tiles_ = 2; - - cfg_.g_threads = 2; - init_flags_ = VPX_CODEC_USE_PSNR; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - cfg_.g_threads = 8; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - - // Compare to check if stats match with row-mt=0/1. - compare_fp_stats_md5(&firstpass_stats_); -#endif // CONFIG_REALTIME_ONLY -} - -class VPxEncoderThreadTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith4Params { - protected: - VPxEncoderThreadTest() - : EncoderTest(GET_PARAM(0)), encoder_initialized_(false), - tiles_(GET_PARAM(3)), threads_(GET_PARAM(4)), - encoding_mode_(GET_PARAM(1)), set_cpu_used_(GET_PARAM(2)) { - init_flags_ = VPX_CODEC_USE_PSNR; - md5_.clear(); - row_mt_mode_ = 1; - psnr_ = 0.0; - nframes_ = 0; - } - ~VPxEncoderThreadTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(encoding_mode_); - - if (encoding_mode_ != ::libvpx_test::kRealTime) { - cfg_.rc_end_usage = VPX_VBR; - cfg_.rc_2pass_vbr_minsection_pct = 5; - cfg_.rc_2pass_vbr_maxsection_pct = 2000; - } else { - cfg_.g_lag_in_frames = 0; - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_error_resilient = 1; - } - cfg_.rc_max_quantizer = 56; - cfg_.rc_min_quantizer = 0; - } - - void BeginPassHook(unsigned int /*pass*/) override { - encoder_initialized_ = false; - psnr_ = 0.0; - nframes_ = 0; - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource * /*video*/, - ::libvpx_test::Encoder *encoder) override { - if (!encoder_initialized_) { - // Encode 4 column tiles. - encoder->Control(VP9E_SET_TILE_COLUMNS, tiles_); - encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_); - if (encoding_mode_ != ::libvpx_test::kRealTime) { - encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); - encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7); - encoder->Control(VP8E_SET_ARNR_STRENGTH, 5); - encoder->Control(VP8E_SET_ARNR_TYPE, 3); - encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 0); - } else { - encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 0); - encoder->Control(VP9E_SET_AQ_MODE, 3); - } - encoder->Control(VP9E_SET_ROW_MT, row_mt_mode_); - - encoder_initialized_ = true; - } - } - - void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) override { - psnr_ += pkt->data.psnr.psnr[0]; - nframes_++; - } - - void DecompressedFrameHook(const vpx_image_t &img, - vpx_codec_pts_t /*pts*/) override { - ::libvpx_test::MD5 md5_res; - md5_res.Add(&img); - md5_.push_back(md5_res.Get()); - } - - bool HandleDecodeResult(const vpx_codec_err_t res, - const libvpx_test::VideoSource & /*video*/, - libvpx_test::Decoder * /*decoder*/) override { - if (res != VPX_CODEC_OK) { - EXPECT_EQ(VPX_CODEC_OK, res); - return false; - } - - return true; - } - - double GetAveragePsnr() const { return nframes_ ? (psnr_ / nframes_) : 0.0; } - - bool encoder_initialized_; - int tiles_; - int threads_; - ::libvpx_test::TestMode encoding_mode_; - int set_cpu_used_; - int row_mt_mode_; - double psnr_; - unsigned int nframes_; - std::vector md5_; -}; - -TEST_P(VPxEncoderThreadTest, EncoderResultTest) { - ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 15, 20); - cfg_.rc_target_bitrate = 1000; - - // Part 1: Bit exact test for row_mt_mode_ = 0. - // This part keeps original unit tests done before row-mt code is checked in. - row_mt_mode_ = 0; - - // Encode using single thread. - cfg_.g_threads = 1; - init_flags_ = VPX_CODEC_USE_PSNR; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - const std::vector single_thr_md5 = md5_; - md5_.clear(); - - // Encode using multiple threads. - cfg_.g_threads = threads_; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - const std::vector multi_thr_md5 = md5_; - md5_.clear(); - - // Compare to check if two vectors are equal. - ASSERT_EQ(single_thr_md5, multi_thr_md5); - - // Part 2: row_mt_mode_ = 0 vs row_mt_mode_ = 1 single thread bit exact test. - row_mt_mode_ = 1; - - // Encode using single thread - cfg_.g_threads = 1; - init_flags_ = VPX_CODEC_USE_PSNR; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - std::vector row_mt_single_thr_md5 = md5_; - md5_.clear(); - - ASSERT_EQ(single_thr_md5, row_mt_single_thr_md5); - - // Part 3: Bit exact test with row-mt on - // When row_mt_mode_=1 and using >1 threads, the encoder generates bit exact - // result. - row_mt_mode_ = 1; - row_mt_single_thr_md5.clear(); - - // Encode using 2 threads. - cfg_.g_threads = 2; - init_flags_ = VPX_CODEC_USE_PSNR; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - row_mt_single_thr_md5 = md5_; - md5_.clear(); - - // Encode using multiple threads. - cfg_.g_threads = threads_; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - const std::vector row_mt_multi_thr_md5 = md5_; - md5_.clear(); - - // Compare to check if two vectors are equal. - ASSERT_EQ(row_mt_single_thr_md5, row_mt_multi_thr_md5); - - // Part 4: PSNR test with bit_match_mode_ = 0 - row_mt_mode_ = 1; - - // Encode using single thread. - cfg_.g_threads = 1; - init_flags_ = VPX_CODEC_USE_PSNR; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - const double single_thr_psnr = GetAveragePsnr(); - - // Encode using multiple threads. - cfg_.g_threads = threads_; - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - const double multi_thr_psnr = GetAveragePsnr(); - - EXPECT_NEAR(single_thr_psnr, multi_thr_psnr, 0.2); -} - -INSTANTIATE_TEST_SUITE_P( - VP9, VPxFirstPassEncoderThreadTest, - ::testing::Combine( - ::testing::Values( - static_cast(&libvpx_test::kVP9)), - ::testing::Values(::libvpx_test::kTwoPassGood), - ::testing::Range(0, 4))); // cpu_used - -constexpr libvpx_test::TestMode kOnePassTestModes[] = { - libvpx_test::kRealTime, -#if !CONFIG_REALTIME_ONLY - libvpx_test::kOnePassGood, -#endif -}; - -// Split this into multiple instantiations so that we can distinguish -// between very slow runs ( i.e., cpu_speed 0 ) vs ones that can be -// run nightly by adding Large to the title. -INSTANTIATE_TEST_SUITE_P( - VP9, VPxEncoderThreadTest, - ::testing::Combine( - ::testing::Values( - static_cast(&libvpx_test::kVP9)), - ::testing::ValuesIn(kOnePassTestModes), - ::testing::Range(3, 10), // cpu_used - ::testing::Range(0, 3), // tile_columns - ::testing::Range(2, 5))); // threads - -INSTANTIATE_TEST_SUITE_P( - VP9Large, VPxEncoderThreadTest, - ::testing::Combine( - ::testing::Values( - static_cast(&libvpx_test::kVP9)), - ::testing::ValuesIn(kOnePassTestModes), - ::testing::Range(0, 3), // cpu_used - ::testing::Range(0, 3), // tile_columns - ::testing::Range(2, 5))); // threads - -#if !CONFIG_REALTIME_ONLY -INSTANTIATE_TEST_SUITE_P( - VP9LargeBest, VPxEncoderThreadTest, - ::testing::Combine( - ::testing::Values( - static_cast(&libvpx_test::kVP9)), - ::testing::Values(libvpx_test::kOnePassBest), - ::testing::Range(0, 10), // cpu_used - ::testing::Range(0, 3), // tile_columns - ::testing::Range(2, 5))); // threads -#endif - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_ext_ratectrl_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_ext_ratectrl_test.cc deleted file mode 100644 index 8f7372e7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_ext_ratectrl_test.cc +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (c) 2020 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "./vpx_config.h" - -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/util.h" -#include "test/yuv_video_source.h" -#if CONFIG_VP9_DECODER -#include "vpx/vp8dx.h" -#endif -#include "vp9/simple_encode.h" -#include "vpx/vpx_codec.h" -#include "vpx/vpx_encoder.h" -#include "vpx/vpx_ext_ratectrl.h" -#include "vpx/vpx_image.h" -#include "vpx/vpx_tpl.h" -#include "vpx_dsp/vpx_dsp_common.h" - -namespace { - -constexpr int kShowFrameCount = 10; -constexpr int kKeyframeQp = 10; -constexpr int kLeafQp = 40; -constexpr int kArfQp = 15; - -// Simple external rate controller for testing. -class RateControllerForTest { - public: - RateControllerForTest() : current_gop_(-1) {} - ~RateControllerForTest() {} - - void StartNextGop() { ++current_gop_; } - - vpx_rc_gop_decision_t GetCurrentGop() const { - vpx_rc_gop_decision_t gop_decision; - if (current_gop_ == 0) { - gop_decision.use_key_frame = 1; - gop_decision.use_alt_ref = 1; - gop_decision.gop_coding_frames = - kShowFrameCount - 1 + gop_decision.use_alt_ref; - // key frame - gop_decision.update_type[0] = VPX_RC_KF_UPDATE; - gop_decision.update_ref_index[0] = 0; - gop_decision.ref_frame_list[0] = get_kf_ref_frame(); - // arf - gop_decision.update_type[1] = VPX_RC_ARF_UPDATE; - gop_decision.update_ref_index[1] = 1; - gop_decision.ref_frame_list[1] = get_arf_ref_frame(); - // leafs - for (int i = 2; i < gop_decision.gop_coding_frames; ++i) { - gop_decision.update_type[i] = VPX_RC_LF_UPDATE; - gop_decision.update_ref_index[i] = 2; - gop_decision.ref_frame_list[i] = get_leaf_ref_frame(i); - } - } else { - // Pad a overlay-only GOP as the last GOP. - EXPECT_EQ(current_gop_, 1); - gop_decision.use_key_frame = 0; - gop_decision.use_alt_ref = 0; - gop_decision.gop_coding_frames = 1; - - gop_decision.update_type[0] = VPX_RC_OVERLAY_UPDATE; - gop_decision.update_ref_index[0] = 1; - gop_decision.ref_frame_list[0] = get_ovl_ref_frame(); - } - return gop_decision; - } - - int CalculateFrameDecision(int frame_index) { - if (current_gop_ == 0 && frame_index == 0) { - // Key frame, first frame in the first GOP. - return kKeyframeQp; - } else if (frame_index == 1) { - // ARF, we always use ARF for this test. - return kArfQp; - } else { - return kLeafQp; - } - } - - private: - vpx_rc_ref_frame_t get_kf_ref_frame() const { - vpx_rc_ref_frame_t ref_frame; - ref_frame.index[0] = -1; - ref_frame.index[1] = -1; - ref_frame.index[2] = -1; - ref_frame.name[0] = VPX_RC_INVALID_REF_FRAME; - ref_frame.name[1] = VPX_RC_INVALID_REF_FRAME; - ref_frame.name[2] = VPX_RC_INVALID_REF_FRAME; - return ref_frame; - } - vpx_rc_ref_frame_t get_arf_ref_frame() const { - vpx_rc_ref_frame_t ref_frame; - ref_frame.index[0] = 0; - ref_frame.index[1] = -1; - ref_frame.index[2] = -1; - ref_frame.name[0] = VPX_RC_GOLDEN_FRAME; - ref_frame.name[1] = VPX_RC_INVALID_REF_FRAME; - ref_frame.name[2] = VPX_RC_INVALID_REF_FRAME; - return ref_frame; - } - vpx_rc_ref_frame_t get_leaf_ref_frame(int count) const { - vpx_rc_ref_frame_t ref_frame; - ref_frame.index[0] = 0; - ref_frame.index[1] = 1; - ref_frame.index[2] = count > 2 ? 2 : -1; - ref_frame.name[0] = VPX_RC_GOLDEN_FRAME; - ref_frame.name[1] = VPX_RC_ALTREF_FRAME; - ref_frame.name[2] = - count > 2 ? VPX_RC_LAST_FRAME : VPX_RC_INVALID_REF_FRAME; - return ref_frame; - } - vpx_rc_ref_frame_t get_ovl_ref_frame() const { - vpx_rc_ref_frame_t ref_frame; - ref_frame.index[0] = 1; - ref_frame.index[1] = -1; - ref_frame.index[2] = -1; - ref_frame.name[0] = VPX_RC_ALTREF_FRAME; - ref_frame.name[1] = VPX_RC_INVALID_REF_FRAME; - ref_frame.name[2] = VPX_RC_INVALID_REF_FRAME; - return ref_frame; - } - - int current_gop_; -}; - -// Callbacks used in this test. -vpx_rc_status_t rc_test_create_model( - void * /*priv*/, const vpx_rc_config_t * /*ratectrl_config*/, - vpx_rc_model_t *rate_ctrl_model_ptr) { - std::unique_ptr test_controller( - new RateControllerForTest()); - *rate_ctrl_model_ptr = test_controller.release(); - return VPX_RC_OK; -} - -vpx_rc_status_t rc_test_send_firstpass_stats( - vpx_rc_model_t /*rate_ctrl_model*/, - const vpx_rc_firstpass_stats_t *first_pass_stats) { - EXPECT_EQ(first_pass_stats->num_frames, kShowFrameCount); - for (int i = 0; i < first_pass_stats->num_frames; ++i) { - EXPECT_DOUBLE_EQ(first_pass_stats->frame_stats[i].frame, i); - } - return VPX_RC_OK; -} - -vpx_rc_status_t rc_test_send_tpl_gop_stats( - vpx_rc_model_t /*rate_ctrl_model*/, const VpxTplGopStats *tpl_gop_stats) { - EXPECT_GT(tpl_gop_stats->size, 0); - - for (int i = 0; i < tpl_gop_stats->size; ++i) { - EXPECT_GT(tpl_gop_stats->frame_stats_list[i].num_blocks, 0); - } - return VPX_RC_OK; -} - -vpx_rc_status_t rc_test_get_encodeframe_decision( - vpx_rc_model_t rate_ctrl_model, const int frame_gop_index, - vpx_rc_encodeframe_decision_t *frame_decision) { - RateControllerForTest *test_controller = - static_cast(rate_ctrl_model); - frame_decision->q_index = - test_controller->CalculateFrameDecision(frame_gop_index); - return VPX_RC_OK; -} - -vpx_rc_status_t rc_test_get_gop_decision(vpx_rc_model_t rate_ctrl_model, - vpx_rc_gop_decision_t *gop_decision) { - RateControllerForTest *test_controller = - static_cast(rate_ctrl_model); - test_controller->StartNextGop(); - *gop_decision = test_controller->GetCurrentGop(); - return VPX_RC_OK; -} - -vpx_rc_status_t rc_delete_model(vpx_rc_model_t rate_ctrl_model) { - RateControllerForTest *test_controller = - static_cast(rate_ctrl_model); - delete test_controller; - return VPX_RC_OK; -} - -class ExtRateCtrlTest : public ::libvpx_test::EncoderTest, - public ::testing::Test { - protected: - ExtRateCtrlTest() - : EncoderTest(&::libvpx_test::kVP9), received_show_frame_count_(0), - current_frame_qp_(0) {} - - ~ExtRateCtrlTest() override = default; - - void SetUp() override { - InitializeConfig(); -#if CONFIG_REALTIME_ONLY - SetMode(::libvpx_test::kRealTime); -#else - SetMode(::libvpx_test::kTwoPassGood); -#endif - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - vpx_rc_funcs_t rc_funcs = {}; - rc_funcs.rc_type = VPX_RC_GOP_QP; - rc_funcs.create_model = rc_test_create_model; - rc_funcs.send_firstpass_stats = rc_test_send_firstpass_stats; - rc_funcs.send_tpl_gop_stats = rc_test_send_tpl_gop_stats; - rc_funcs.get_gop_decision = rc_test_get_gop_decision; - rc_funcs.get_encodeframe_decision = rc_test_get_encodeframe_decision; - rc_funcs.delete_model = rc_delete_model; - encoder->Control(VP9E_SET_EXTERNAL_RATE_CONTROL, &rc_funcs); - } - } - -#if CONFIG_VP9_DECODER - bool HandleDecodeResult(const vpx_codec_err_t res_dec, - const ::libvpx_test::VideoSource & /*video*/, - ::libvpx_test::Decoder *decoder) override { - EXPECT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError(); - decoder->Control(VPXD_GET_LAST_QUANTIZER, ¤t_frame_qp_); - return VPX_CODEC_OK == res_dec; - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - // We are not comparing current_frame_qp_ here because the encoder will - // pack ARF and the next show frame into one pkt. Therefore, we might - // receive two frames in one pkt. However, one thing we are sure is that - // each pkt will have just one show frame. Therefore, we can check if the - // received show frame count match the actual show frame count. - if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { - ++received_show_frame_count_; - } - } -#endif // CONFIG_VP9_DECODER - - int received_show_frame_count_; - int current_frame_qp_; -}; - -TEST_F(ExtRateCtrlTest, EncodeTest) { - cfg_.rc_target_bitrate = 4000; - cfg_.g_lag_in_frames = 25; - - std::unique_ptr video; - video.reset(new (std::nothrow) libvpx_test::YUVVideoSource( - "bus_352x288_420_f20_b8.yuv", VPX_IMG_FMT_I420, 352, 288, 30, 1, 0, - kShowFrameCount)); - - ASSERT_NE(video, nullptr); - ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); - EXPECT_EQ(received_show_frame_count_, kShowFrameCount); -} - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_intrapred_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_intrapred_test.cc deleted file mode 100644 index b63cb873..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_intrapred_test.cc +++ /dev/null @@ -1,1207 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "gtest/gtest.h" - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "test/acm_random.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_pred_common.h" -#include "vpx_mem/vpx_mem.h" - -namespace { - -using libvpx_test::ACMRandom; - -const int count_test_block = 100000; - -typedef void (*IntraPredFunc)(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left); - -struct IntraPredParam { - IntraPredParam(IntraPredFunc pred = nullptr, IntraPredFunc ref = nullptr, - int block_size_value = 0, int bit_depth_value = 0) - : pred_fn(pred), ref_fn(ref), block_size(block_size_value), - bit_depth(bit_depth_value) {} - - IntraPredFunc pred_fn; - IntraPredFunc ref_fn; - int block_size; - int bit_depth; -}; - -template -class IntraPredTest : public ::testing::TestWithParam { - public: - void RunTest(Pixel *left_col, Pixel *above_data, Pixel *dst, Pixel *ref_dst) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - const int block_size = params_.block_size; - above_row_ = above_data + 16; - left_col_ = left_col; - dst_ = dst; - ref_dst_ = ref_dst; - int error_count = 0; - for (int i = 0; i < count_test_block; ++i) { - // TODO(webm:1797): Some of the optimised predictor implementations rely - // on the trailing half of the above_row_ being a copy of the final - // element, however relying on this in some cases can cause the MD5 tests - // to fail. We have fixed all of these cases for Neon, so fill the whole - // of above_row_ randomly. -#if HAVE_NEON - // Fill edges with random data, try first with saturated values. - for (int x = -1; x < 2 * block_size; x++) { - if (i == 0) { - above_row_[x] = mask_; - } else { - above_row_[x] = rnd.Rand16() & mask_; - } - } -#else - // Fill edges with random data, try first with saturated values. - for (int x = -1; x < block_size; x++) { - if (i == 0) { - above_row_[x] = mask_; - } else { - above_row_[x] = rnd.Rand16() & mask_; - } - } - for (int x = block_size; x < 2 * block_size; x++) { - above_row_[x] = above_row_[block_size - 1]; - } -#endif - for (int y = 0; y < block_size; y++) { - if (i == 0) { - left_col_[y] = mask_; - } else { - left_col_[y] = rnd.Rand16() & mask_; - } - } - Predict(); - CheckPrediction(i, &error_count); - } - ASSERT_EQ(0, error_count); - } - - protected: - void SetUp() override { - params_ = this->GetParam(); - stride_ = params_.block_size * 3; - mask_ = (1 << params_.bit_depth) - 1; - } - - void Predict(); - - void CheckPrediction(int test_case_number, int *error_count) const { - // For each pixel ensure that the calculated value is the same as reference. - const int block_size = params_.block_size; - for (int y = 0; y < block_size; y++) { - for (int x = 0; x < block_size; x++) { - *error_count += ref_dst_[x + y * stride_] != dst_[x + y * stride_]; - if (*error_count == 1) { - ASSERT_EQ(ref_dst_[x + y * stride_], dst_[x + y * stride_]) - << " Failed on Test Case Number " << test_case_number; - } - } - } - } - - Pixel *above_row_; - Pixel *left_col_; - Pixel *dst_; - Pixel *ref_dst_; - ptrdiff_t stride_; - int mask_; - - PredParam params_; -}; - -template <> -void IntraPredTest::Predict() { - params_.ref_fn(ref_dst_, stride_, above_row_, left_col_); - ASM_REGISTER_STATE_CHECK( - params_.pred_fn(dst_, stride_, above_row_, left_col_)); -} - -typedef IntraPredTest VP9IntraPredTest; - -TEST_P(VP9IntraPredTest, IntraPredTests) { - // max block size is 32 - DECLARE_ALIGNED(16, uint8_t, left_col[2 * 32]); - DECLARE_ALIGNED(16, uint8_t, above_data[2 * 32 + 32]); - DECLARE_ALIGNED(16, uint8_t, dst[3 * 32 * 32]); - DECLARE_ALIGNED(16, uint8_t, ref_dst[3 * 32 * 32]); - RunTest(left_col, above_data, dst, ref_dst); -} - -// Instantiate a token test to avoid -Wuninitialized warnings when none of the -// other tests are enabled. -INSTANTIATE_TEST_SUITE_P( - C, VP9IntraPredTest, - ::testing::Values(IntraPredParam(&vpx_d45_predictor_4x4_c, - &vpx_d45_predictor_4x4_c, 4, 8))); -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P( - SSE2, VP9IntraPredTest, - ::testing::Values( - IntraPredParam(&vpx_d45_predictor_4x4_sse2, &vpx_d45_predictor_4x4_c, 4, - 8), - IntraPredParam(&vpx_d45_predictor_8x8_sse2, &vpx_d45_predictor_8x8_c, 8, - 8), - IntraPredParam(&vpx_d207_predictor_4x4_sse2, &vpx_d207_predictor_4x4_c, - 4, 8), - IntraPredParam(&vpx_dc_128_predictor_4x4_sse2, - &vpx_dc_128_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_dc_128_predictor_8x8_sse2, - &vpx_dc_128_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_dc_128_predictor_16x16_sse2, - &vpx_dc_128_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_dc_128_predictor_32x32_sse2, - &vpx_dc_128_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_dc_left_predictor_4x4_sse2, - &vpx_dc_left_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_dc_left_predictor_8x8_sse2, - &vpx_dc_left_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_dc_left_predictor_16x16_sse2, - &vpx_dc_left_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_dc_left_predictor_32x32_sse2, - &vpx_dc_left_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_dc_predictor_4x4_sse2, &vpx_dc_predictor_4x4_c, 4, - 8), - IntraPredParam(&vpx_dc_predictor_8x8_sse2, &vpx_dc_predictor_8x8_c, 8, - 8), - IntraPredParam(&vpx_dc_predictor_16x16_sse2, &vpx_dc_predictor_16x16_c, - 16, 8), - IntraPredParam(&vpx_dc_predictor_32x32_sse2, &vpx_dc_predictor_32x32_c, - 32, 8), - IntraPredParam(&vpx_dc_top_predictor_4x4_sse2, - &vpx_dc_top_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_dc_top_predictor_8x8_sse2, - &vpx_dc_top_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_dc_top_predictor_16x16_sse2, - &vpx_dc_top_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_dc_top_predictor_32x32_sse2, - &vpx_dc_top_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_h_predictor_4x4_sse2, &vpx_h_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_h_predictor_8x8_sse2, &vpx_h_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_h_predictor_16x16_sse2, &vpx_h_predictor_16x16_c, - 16, 8), - IntraPredParam(&vpx_h_predictor_32x32_sse2, &vpx_h_predictor_32x32_c, - 32, 8), - IntraPredParam(&vpx_tm_predictor_4x4_sse2, &vpx_tm_predictor_4x4_c, 4, - 8), - IntraPredParam(&vpx_tm_predictor_8x8_sse2, &vpx_tm_predictor_8x8_c, 8, - 8), - IntraPredParam(&vpx_tm_predictor_16x16_sse2, &vpx_tm_predictor_16x16_c, - 16, 8), - IntraPredParam(&vpx_tm_predictor_32x32_sse2, &vpx_tm_predictor_32x32_c, - 32, 8), - IntraPredParam(&vpx_v_predictor_4x4_sse2, &vpx_v_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_v_predictor_8x8_sse2, &vpx_v_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_v_predictor_16x16_sse2, &vpx_v_predictor_16x16_c, - 16, 8), - IntraPredParam(&vpx_v_predictor_32x32_sse2, &vpx_v_predictor_32x32_c, - 32, 8))); -#endif // HAVE_SSE2 - -#if HAVE_SSSE3 -INSTANTIATE_TEST_SUITE_P( - SSSE3, VP9IntraPredTest, - ::testing::Values(IntraPredParam(&vpx_d45_predictor_16x16_ssse3, - &vpx_d45_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_d45_predictor_32x32_ssse3, - &vpx_d45_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_d63_predictor_4x4_ssse3, - &vpx_d63_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_d63_predictor_8x8_ssse3, - &vpx_d63_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_d63_predictor_16x16_ssse3, - &vpx_d63_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_d63_predictor_32x32_ssse3, - &vpx_d63_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_d153_predictor_4x4_ssse3, - &vpx_d153_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_d153_predictor_8x8_ssse3, - &vpx_d153_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_d153_predictor_16x16_ssse3, - &vpx_d153_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_d153_predictor_32x32_ssse3, - &vpx_d153_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_d207_predictor_8x8_ssse3, - &vpx_d207_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_d207_predictor_16x16_ssse3, - &vpx_d207_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_d207_predictor_32x32_ssse3, - &vpx_d207_predictor_32x32_c, 32, 8))); -#endif // HAVE_SSSE3 - -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P( - NEON, VP9IntraPredTest, - ::testing::Values( - IntraPredParam(&vpx_d45_predictor_4x4_neon, &vpx_d45_predictor_4x4_c, 4, - 8), - IntraPredParam(&vpx_d45_predictor_8x8_neon, &vpx_d45_predictor_8x8_c, 8, - 8), - IntraPredParam(&vpx_d45_predictor_16x16_neon, - &vpx_d45_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_d45_predictor_32x32_neon, - &vpx_d45_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_d63_predictor_4x4_neon, &vpx_d63_predictor_4x4_c, 4, - 8), - IntraPredParam(&vpx_d63_predictor_8x8_neon, &vpx_d63_predictor_8x8_c, 8, - 8), - IntraPredParam(&vpx_d63_predictor_16x16_neon, - &vpx_d63_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_d63_predictor_32x32_neon, - &vpx_d63_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_d117_predictor_4x4_neon, &vpx_d117_predictor_4x4_c, - 4, 8), - IntraPredParam(&vpx_d117_predictor_8x8_neon, &vpx_d117_predictor_8x8_c, - 8, 8), - IntraPredParam(&vpx_d117_predictor_16x16_neon, - &vpx_d117_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_d117_predictor_32x32_neon, - &vpx_d117_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_d135_predictor_4x4_neon, &vpx_d135_predictor_4x4_c, - 4, 8), - IntraPredParam(&vpx_d135_predictor_8x8_neon, &vpx_d135_predictor_8x8_c, - 8, 8), - IntraPredParam(&vpx_d135_predictor_16x16_neon, - &vpx_d135_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_d135_predictor_32x32_neon, - &vpx_d135_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_d153_predictor_4x4_neon, &vpx_d153_predictor_4x4_c, - 4, 8), - IntraPredParam(&vpx_d153_predictor_8x8_neon, &vpx_d153_predictor_8x8_c, - 8, 8), - IntraPredParam(&vpx_d153_predictor_16x16_neon, - &vpx_d153_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_d153_predictor_32x32_neon, - &vpx_d153_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_d207_predictor_4x4_neon, &vpx_d207_predictor_4x4_c, - 4, 8), - IntraPredParam(&vpx_d207_predictor_8x8_neon, &vpx_d207_predictor_8x8_c, - 8, 8), - IntraPredParam(&vpx_d207_predictor_16x16_neon, - &vpx_d207_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_d207_predictor_32x32_neon, - &vpx_d207_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_dc_128_predictor_4x4_neon, - &vpx_dc_128_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_dc_128_predictor_8x8_neon, - &vpx_dc_128_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_dc_128_predictor_16x16_neon, - &vpx_dc_128_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_dc_128_predictor_32x32_neon, - &vpx_dc_128_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_dc_left_predictor_4x4_neon, - &vpx_dc_left_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_dc_left_predictor_8x8_neon, - &vpx_dc_left_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_dc_left_predictor_16x16_neon, - &vpx_dc_left_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_dc_left_predictor_32x32_neon, - &vpx_dc_left_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_dc_predictor_4x4_neon, &vpx_dc_predictor_4x4_c, 4, - 8), - IntraPredParam(&vpx_dc_predictor_8x8_neon, &vpx_dc_predictor_8x8_c, 8, - 8), - IntraPredParam(&vpx_dc_predictor_16x16_neon, &vpx_dc_predictor_16x16_c, - 16, 8), - IntraPredParam(&vpx_dc_predictor_32x32_neon, &vpx_dc_predictor_32x32_c, - 32, 8), - IntraPredParam(&vpx_dc_top_predictor_4x4_neon, - &vpx_dc_top_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_dc_top_predictor_8x8_neon, - &vpx_dc_top_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_dc_top_predictor_16x16_neon, - &vpx_dc_top_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_dc_top_predictor_32x32_neon, - &vpx_dc_top_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_h_predictor_4x4_neon, &vpx_h_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_h_predictor_8x8_neon, &vpx_h_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_h_predictor_16x16_neon, &vpx_h_predictor_16x16_c, - 16, 8), - IntraPredParam(&vpx_h_predictor_32x32_neon, &vpx_h_predictor_32x32_c, - 32, 8), - IntraPredParam(&vpx_tm_predictor_4x4_neon, &vpx_tm_predictor_4x4_c, 4, - 8), - IntraPredParam(&vpx_tm_predictor_8x8_neon, &vpx_tm_predictor_8x8_c, 8, - 8), - IntraPredParam(&vpx_tm_predictor_16x16_neon, &vpx_tm_predictor_16x16_c, - 16, 8), - IntraPredParam(&vpx_tm_predictor_32x32_neon, &vpx_tm_predictor_32x32_c, - 32, 8), - IntraPredParam(&vpx_v_predictor_4x4_neon, &vpx_v_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_v_predictor_8x8_neon, &vpx_v_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_v_predictor_16x16_neon, &vpx_v_predictor_16x16_c, - 16, 8), - IntraPredParam(&vpx_v_predictor_32x32_neon, &vpx_v_predictor_32x32_c, - 32, 8))); -#endif // HAVE_NEON - -#if HAVE_DSPR2 -INSTANTIATE_TEST_SUITE_P( - DSPR2, VP9IntraPredTest, - ::testing::Values(IntraPredParam(&vpx_dc_predictor_4x4_dspr2, - &vpx_dc_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_dc_predictor_8x8_dspr2, - &vpx_dc_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_dc_predictor_16x16_dspr2, - &vpx_dc_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_h_predictor_4x4_dspr2, - &vpx_h_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_h_predictor_8x8_dspr2, - &vpx_h_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_h_predictor_16x16_dspr2, - &vpx_h_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_tm_predictor_4x4_dspr2, - &vpx_tm_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_tm_predictor_8x8_dspr2, - &vpx_tm_predictor_8x8_c, 8, 8))); -#endif // HAVE_DSPR2 - -#if HAVE_MSA -INSTANTIATE_TEST_SUITE_P( - MSA, VP9IntraPredTest, - ::testing::Values( - IntraPredParam(&vpx_dc_128_predictor_4x4_msa, - &vpx_dc_128_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_dc_128_predictor_8x8_msa, - &vpx_dc_128_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_dc_128_predictor_16x16_msa, - &vpx_dc_128_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_dc_128_predictor_32x32_msa, - &vpx_dc_128_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_dc_left_predictor_4x4_msa, - &vpx_dc_left_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_dc_left_predictor_8x8_msa, - &vpx_dc_left_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_dc_left_predictor_16x16_msa, - &vpx_dc_left_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_dc_left_predictor_32x32_msa, - &vpx_dc_left_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_dc_predictor_4x4_msa, &vpx_dc_predictor_4x4_c, 4, - 8), - IntraPredParam(&vpx_dc_predictor_8x8_msa, &vpx_dc_predictor_8x8_c, 8, - 8), - IntraPredParam(&vpx_dc_predictor_16x16_msa, &vpx_dc_predictor_16x16_c, - 16, 8), - IntraPredParam(&vpx_dc_predictor_32x32_msa, &vpx_dc_predictor_32x32_c, - 32, 8), - IntraPredParam(&vpx_dc_top_predictor_4x4_msa, - &vpx_dc_top_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_dc_top_predictor_8x8_msa, - &vpx_dc_top_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_dc_top_predictor_16x16_msa, - &vpx_dc_top_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_dc_top_predictor_32x32_msa, - &vpx_dc_top_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_h_predictor_4x4_msa, &vpx_h_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_h_predictor_8x8_msa, &vpx_h_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_h_predictor_16x16_msa, &vpx_h_predictor_16x16_c, 16, - 8), - IntraPredParam(&vpx_h_predictor_32x32_msa, &vpx_h_predictor_32x32_c, 32, - 8), - IntraPredParam(&vpx_tm_predictor_4x4_msa, &vpx_tm_predictor_4x4_c, 4, - 8), - IntraPredParam(&vpx_tm_predictor_8x8_msa, &vpx_tm_predictor_8x8_c, 8, - 8), - IntraPredParam(&vpx_tm_predictor_16x16_msa, &vpx_tm_predictor_16x16_c, - 16, 8), - IntraPredParam(&vpx_tm_predictor_32x32_msa, &vpx_tm_predictor_32x32_c, - 32, 8), - IntraPredParam(&vpx_v_predictor_4x4_msa, &vpx_v_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_v_predictor_8x8_msa, &vpx_v_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_v_predictor_16x16_msa, &vpx_v_predictor_16x16_c, 16, - 8), - IntraPredParam(&vpx_v_predictor_32x32_msa, &vpx_v_predictor_32x32_c, 32, - 8))); -#endif // HAVE_MSA - -// TODO(crbug.com/webm/1522): Fix test failures. -#if 0 - IntraPredParam(&vpx_d45_predictor_8x8_vsx, &vpx_d45_predictor_8x8_c, 8, - 8), - IntraPredParam(&vpx_d63_predictor_8x8_vsx, &vpx_d63_predictor_8x8_c, 8, - 8), - IntraPredParam(&vpx_dc_predictor_8x8_vsx, &vpx_dc_predictor_8x8_c, 8, - 8), - IntraPredParam(&vpx_h_predictor_4x4_vsx, &vpx_h_predictor_4x4_c, 4, 8), - IntraPredParam(&vpx_h_predictor_8x8_vsx, &vpx_h_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_tm_predictor_4x4_vsx, &vpx_tm_predictor_4x4_c, 4, - 8), - IntraPredParam(&vpx_tm_predictor_8x8_vsx, &vpx_tm_predictor_8x8_c, 8, - 8), -#endif - -#if HAVE_VSX -INSTANTIATE_TEST_SUITE_P( - VSX, VP9IntraPredTest, - ::testing::Values(IntraPredParam(&vpx_d45_predictor_16x16_vsx, - &vpx_d45_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_d45_predictor_32x32_vsx, - &vpx_d45_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_d63_predictor_16x16_vsx, - &vpx_d63_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_d63_predictor_32x32_vsx, - &vpx_d63_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_dc_128_predictor_16x16_vsx, - &vpx_dc_128_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_dc_128_predictor_32x32_vsx, - &vpx_dc_128_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_dc_left_predictor_16x16_vsx, - &vpx_dc_left_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_dc_left_predictor_32x32_vsx, - &vpx_dc_left_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_dc_predictor_16x16_vsx, - &vpx_dc_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_dc_predictor_32x32_vsx, - &vpx_dc_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_dc_top_predictor_16x16_vsx, - &vpx_dc_top_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_dc_top_predictor_32x32_vsx, - &vpx_dc_top_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_h_predictor_16x16_vsx, - &vpx_h_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_h_predictor_32x32_vsx, - &vpx_h_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_tm_predictor_16x16_vsx, - &vpx_tm_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_tm_predictor_32x32_vsx, - &vpx_tm_predictor_32x32_c, 32, 8), - IntraPredParam(&vpx_v_predictor_16x16_vsx, - &vpx_v_predictor_16x16_c, 16, 8), - IntraPredParam(&vpx_v_predictor_32x32_vsx, - &vpx_v_predictor_32x32_c, 32, 8))); -#endif // HAVE_VSX - -#if HAVE_LSX -INSTANTIATE_TEST_SUITE_P( - LSX, VP9IntraPredTest, - ::testing::Values(IntraPredParam(&vpx_dc_predictor_8x8_lsx, - &vpx_dc_predictor_8x8_c, 8, 8), - IntraPredParam(&vpx_dc_predictor_16x16_lsx, - &vpx_dc_predictor_16x16_c, 16, 8))); -#endif // HAVE_LSX - -#if CONFIG_VP9_HIGHBITDEPTH -typedef void (*HighbdIntraPred)(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, const uint16_t *left, - int bps); -struct HighbdIntraPredParam { - HighbdIntraPredParam(HighbdIntraPred pred = nullptr, - HighbdIntraPred ref = nullptr, int block_size_value = 0, - int bit_depth_value = 0) - : pred_fn(pred), ref_fn(ref), block_size(block_size_value), - bit_depth(bit_depth_value) {} - - HighbdIntraPred pred_fn; - HighbdIntraPred ref_fn; - int block_size; - int bit_depth; -}; - -#if HAVE_SSSE3 || HAVE_NEON || HAVE_SSE2 -template <> -void IntraPredTest::Predict() { - const int bit_depth = params_.bit_depth; - params_.ref_fn(ref_dst_, stride_, above_row_, left_col_, bit_depth); - ASM_REGISTER_STATE_CHECK( - params_.pred_fn(dst_, stride_, above_row_, left_col_, bit_depth)); -} - -typedef IntraPredTest VP9HighbdIntraPredTest; -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VP9HighbdIntraPredTest); - -TEST_P(VP9HighbdIntraPredTest, HighbdIntraPredTests) { - // max block size is 32 - DECLARE_ALIGNED(16, uint16_t, left_col[2 * 32]); - DECLARE_ALIGNED(16, uint16_t, above_data[2 * 32 + 32]); - DECLARE_ALIGNED(16, uint16_t, dst[3 * 32 * 32]); - DECLARE_ALIGNED(16, uint16_t, ref_dst[3 * 32 * 32]); - RunTest(left_col, above_data, dst, ref_dst); -} -#endif - -#if HAVE_SSSE3 -INSTANTIATE_TEST_SUITE_P( - SSSE3_TO_C_8, VP9HighbdIntraPredTest, - ::testing::Values( - HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_ssse3, - &vpx_highbd_d45_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_ssse3, - &vpx_highbd_d45_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_ssse3, - &vpx_highbd_d45_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_ssse3, - &vpx_highbd_d45_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_8x8_ssse3, - &vpx_highbd_d63_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_16x16_ssse3, - &vpx_highbd_d63_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_32x32_c, - &vpx_highbd_d63_predictor_32x32_ssse3, 32, 8), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_8x8_ssse3, - &vpx_highbd_d117_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_16x16_ssse3, - &vpx_highbd_d117_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_32x32_c, - &vpx_highbd_d117_predictor_32x32_ssse3, 32, 8), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_ssse3, - &vpx_highbd_d135_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_ssse3, - &vpx_highbd_d135_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_ssse3, - &vpx_highbd_d135_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_8x8_ssse3, - &vpx_highbd_d153_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_16x16_ssse3, - &vpx_highbd_d153_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_32x32_ssse3, - &vpx_highbd_d153_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_8x8_ssse3, - &vpx_highbd_d207_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_16x16_ssse3, - &vpx_highbd_d207_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_32x32_ssse3, - &vpx_highbd_d207_predictor_32x32_c, 32, 8))); - -INSTANTIATE_TEST_SUITE_P( - SSSE3_TO_C_10, VP9HighbdIntraPredTest, - ::testing::Values( - HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_ssse3, - &vpx_highbd_d45_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_ssse3, - &vpx_highbd_d45_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_ssse3, - &vpx_highbd_d45_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_ssse3, - &vpx_highbd_d45_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_8x8_ssse3, - &vpx_highbd_d63_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_16x16_ssse3, - &vpx_highbd_d63_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_32x32_c, - &vpx_highbd_d63_predictor_32x32_ssse3, 32, 10), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_8x8_ssse3, - &vpx_highbd_d117_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_16x16_ssse3, - &vpx_highbd_d117_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_32x32_c, - &vpx_highbd_d117_predictor_32x32_ssse3, 32, 10), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_ssse3, - &vpx_highbd_d135_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_ssse3, - &vpx_highbd_d135_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_ssse3, - &vpx_highbd_d135_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_8x8_ssse3, - &vpx_highbd_d153_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_16x16_ssse3, - &vpx_highbd_d153_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_32x32_ssse3, - &vpx_highbd_d153_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_8x8_ssse3, - &vpx_highbd_d207_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_16x16_ssse3, - &vpx_highbd_d207_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_32x32_ssse3, - &vpx_highbd_d207_predictor_32x32_c, 32, 10))); - -INSTANTIATE_TEST_SUITE_P( - SSSE3_TO_C_12, VP9HighbdIntraPredTest, - ::testing::Values( - HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_ssse3, - &vpx_highbd_d45_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_ssse3, - &vpx_highbd_d45_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_ssse3, - &vpx_highbd_d45_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_ssse3, - &vpx_highbd_d45_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_8x8_ssse3, - &vpx_highbd_d63_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_16x16_ssse3, - &vpx_highbd_d63_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_32x32_c, - &vpx_highbd_d63_predictor_32x32_ssse3, 32, 12), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_8x8_ssse3, - &vpx_highbd_d117_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_16x16_ssse3, - &vpx_highbd_d117_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_32x32_c, - &vpx_highbd_d117_predictor_32x32_ssse3, 32, 12), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_ssse3, - &vpx_highbd_d135_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_ssse3, - &vpx_highbd_d135_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_ssse3, - &vpx_highbd_d135_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_8x8_ssse3, - &vpx_highbd_d153_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_16x16_ssse3, - &vpx_highbd_d153_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_32x32_ssse3, - &vpx_highbd_d153_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_8x8_ssse3, - &vpx_highbd_d207_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_16x16_ssse3, - &vpx_highbd_d207_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_32x32_ssse3, - &vpx_highbd_d207_predictor_32x32_c, 32, 12))); -#endif // HAVE_SSSE3 - -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P( - SSE2_TO_C_8, VP9HighbdIntraPredTest, - ::testing::Values( - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_sse2, - &vpx_highbd_dc_128_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_sse2, - &vpx_highbd_dc_128_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_sse2, - &vpx_highbd_dc_128_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_sse2, - &vpx_highbd_dc_128_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_4x4_sse2, - &vpx_highbd_d63_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_4x4_sse2, - &vpx_highbd_d117_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_sse2, - &vpx_highbd_d135_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_4x4_sse2, - &vpx_highbd_d153_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_4x4_sse2, - &vpx_highbd_d207_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_sse2, - &vpx_highbd_dc_left_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_sse2, - &vpx_highbd_dc_left_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_sse2, - &vpx_highbd_dc_left_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_sse2, - &vpx_highbd_dc_left_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_sse2, - &vpx_highbd_dc_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_sse2, - &vpx_highbd_dc_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_16x16_sse2, - &vpx_highbd_dc_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_sse2, - &vpx_highbd_dc_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_sse2, - &vpx_highbd_dc_top_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_sse2, - &vpx_highbd_dc_top_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_sse2, - &vpx_highbd_dc_top_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_sse2, - &vpx_highbd_dc_top_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_sse2, - &vpx_highbd_tm_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_sse2, - &vpx_highbd_tm_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_16x16_sse2, - &vpx_highbd_tm_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_sse2, - &vpx_highbd_tm_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_sse2, - &vpx_highbd_h_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_sse2, - &vpx_highbd_h_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_sse2, - &vpx_highbd_h_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_sse2, - &vpx_highbd_h_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_sse2, - &vpx_highbd_v_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_sse2, - &vpx_highbd_v_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_v_predictor_16x16_sse2, - &vpx_highbd_v_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_v_predictor_32x32_sse2, - &vpx_highbd_v_predictor_32x32_c, 32, 8))); - -INSTANTIATE_TEST_SUITE_P( - SSE2_TO_C_10, VP9HighbdIntraPredTest, - ::testing::Values( - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_sse2, - &vpx_highbd_dc_128_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_sse2, - &vpx_highbd_dc_128_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_sse2, - &vpx_highbd_dc_128_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_sse2, - &vpx_highbd_dc_128_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_4x4_sse2, - &vpx_highbd_d63_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_4x4_sse2, - &vpx_highbd_d117_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_sse2, - &vpx_highbd_d135_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_4x4_sse2, - &vpx_highbd_d153_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_4x4_sse2, - &vpx_highbd_d207_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_sse2, - &vpx_highbd_dc_left_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_sse2, - &vpx_highbd_dc_left_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_sse2, - &vpx_highbd_dc_left_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_sse2, - &vpx_highbd_dc_left_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_sse2, - &vpx_highbd_dc_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_sse2, - &vpx_highbd_dc_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_16x16_sse2, - &vpx_highbd_dc_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_sse2, - &vpx_highbd_dc_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_sse2, - &vpx_highbd_dc_top_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_sse2, - &vpx_highbd_dc_top_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_sse2, - &vpx_highbd_dc_top_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_sse2, - &vpx_highbd_dc_top_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_sse2, - &vpx_highbd_tm_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_sse2, - &vpx_highbd_tm_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_16x16_sse2, - &vpx_highbd_tm_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_sse2, - &vpx_highbd_tm_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_sse2, - &vpx_highbd_h_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_sse2, - &vpx_highbd_h_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_sse2, - &vpx_highbd_h_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_sse2, - &vpx_highbd_h_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_sse2, - &vpx_highbd_v_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_sse2, - &vpx_highbd_v_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_v_predictor_16x16_sse2, - &vpx_highbd_v_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_v_predictor_32x32_sse2, - &vpx_highbd_v_predictor_32x32_c, 32, 10))); - -INSTANTIATE_TEST_SUITE_P( - SSE2_TO_C_12, VP9HighbdIntraPredTest, - ::testing::Values( - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_sse2, - &vpx_highbd_dc_128_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_sse2, - &vpx_highbd_dc_128_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_sse2, - &vpx_highbd_dc_128_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_sse2, - &vpx_highbd_dc_128_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_4x4_sse2, - &vpx_highbd_d63_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_4x4_sse2, - &vpx_highbd_d117_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_sse2, - &vpx_highbd_d135_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_4x4_sse2, - &vpx_highbd_d153_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_4x4_sse2, - &vpx_highbd_d207_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_sse2, - &vpx_highbd_dc_left_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_sse2, - &vpx_highbd_dc_left_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_sse2, - &vpx_highbd_dc_left_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_sse2, - &vpx_highbd_dc_left_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_sse2, - &vpx_highbd_dc_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_sse2, - &vpx_highbd_dc_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_16x16_sse2, - &vpx_highbd_dc_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_sse2, - &vpx_highbd_dc_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_sse2, - &vpx_highbd_dc_top_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_sse2, - &vpx_highbd_dc_top_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_sse2, - &vpx_highbd_dc_top_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_sse2, - &vpx_highbd_dc_top_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_sse2, - &vpx_highbd_tm_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_sse2, - &vpx_highbd_tm_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_16x16_sse2, - &vpx_highbd_tm_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_sse2, - &vpx_highbd_tm_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_sse2, - &vpx_highbd_h_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_sse2, - &vpx_highbd_h_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_sse2, - &vpx_highbd_h_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_sse2, - &vpx_highbd_h_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_sse2, - &vpx_highbd_v_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_sse2, - &vpx_highbd_v_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_v_predictor_16x16_sse2, - &vpx_highbd_v_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_v_predictor_32x32_sse2, - &vpx_highbd_v_predictor_32x32_c, 32, 12))); -#endif // HAVE_SSE2 - -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P( - NEON_TO_C_8, VP9HighbdIntraPredTest, - ::testing::Values( - HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_neon, - &vpx_highbd_d45_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_neon, - &vpx_highbd_d45_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_neon, - &vpx_highbd_d45_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_neon, - &vpx_highbd_d45_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_4x4_neon, - &vpx_highbd_d63_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_8x8_neon, - &vpx_highbd_d63_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_16x16_neon, - &vpx_highbd_d63_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_32x32_neon, - &vpx_highbd_d63_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_4x4_neon, - &vpx_highbd_d117_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_8x8_neon, - &vpx_highbd_d117_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_16x16_neon, - &vpx_highbd_d117_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_32x32_neon, - &vpx_highbd_d117_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_neon, - &vpx_highbd_d135_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_neon, - &vpx_highbd_d135_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_neon, - &vpx_highbd_d135_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_neon, - &vpx_highbd_d135_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_4x4_neon, - &vpx_highbd_d153_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_8x8_neon, - &vpx_highbd_d153_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_16x16_neon, - &vpx_highbd_d153_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_32x32_neon, - &vpx_highbd_d153_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_4x4_neon, - &vpx_highbd_d207_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_8x8_neon, - &vpx_highbd_d207_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_16x16_neon, - &vpx_highbd_d207_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_32x32_neon, - &vpx_highbd_d207_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_neon, - &vpx_highbd_dc_128_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_neon, - &vpx_highbd_dc_128_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_neon, - &vpx_highbd_dc_128_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_neon, - &vpx_highbd_dc_128_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_neon, - &vpx_highbd_dc_left_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_neon, - &vpx_highbd_dc_left_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_neon, - &vpx_highbd_dc_left_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_neon, - &vpx_highbd_dc_left_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_neon, - &vpx_highbd_dc_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_neon, - &vpx_highbd_dc_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_16x16_neon, - &vpx_highbd_dc_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_neon, - &vpx_highbd_dc_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_neon, - &vpx_highbd_dc_top_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_neon, - &vpx_highbd_dc_top_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_neon, - &vpx_highbd_dc_top_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_neon, - &vpx_highbd_dc_top_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_neon, - &vpx_highbd_h_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_neon, - &vpx_highbd_h_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_neon, - &vpx_highbd_h_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_neon, - &vpx_highbd_h_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_neon, - &vpx_highbd_tm_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_neon, - &vpx_highbd_tm_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_16x16_neon, - &vpx_highbd_tm_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_neon, - &vpx_highbd_tm_predictor_32x32_c, 32, 8), - HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_neon, - &vpx_highbd_v_predictor_4x4_c, 4, 8), - HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_neon, - &vpx_highbd_v_predictor_8x8_c, 8, 8), - HighbdIntraPredParam(&vpx_highbd_v_predictor_16x16_neon, - &vpx_highbd_v_predictor_16x16_c, 16, 8), - HighbdIntraPredParam(&vpx_highbd_v_predictor_32x32_neon, - &vpx_highbd_v_predictor_32x32_c, 32, 8))); - -INSTANTIATE_TEST_SUITE_P( - NEON_TO_C_10, VP9HighbdIntraPredTest, - ::testing::Values( - HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_neon, - &vpx_highbd_d45_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_neon, - &vpx_highbd_d45_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_neon, - &vpx_highbd_d45_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_neon, - &vpx_highbd_d45_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_4x4_neon, - &vpx_highbd_d63_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_8x8_neon, - &vpx_highbd_d63_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_16x16_neon, - &vpx_highbd_d63_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_32x32_neon, - &vpx_highbd_d63_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_4x4_neon, - &vpx_highbd_d117_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_8x8_neon, - &vpx_highbd_d117_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_16x16_neon, - &vpx_highbd_d117_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_32x32_neon, - &vpx_highbd_d117_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_neon, - &vpx_highbd_d135_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_neon, - &vpx_highbd_d135_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_neon, - &vpx_highbd_d135_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_neon, - &vpx_highbd_d135_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_4x4_neon, - &vpx_highbd_d153_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_8x8_neon, - &vpx_highbd_d153_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_16x16_neon, - &vpx_highbd_d153_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_32x32_neon, - &vpx_highbd_d153_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_4x4_neon, - &vpx_highbd_d207_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_8x8_neon, - &vpx_highbd_d207_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_16x16_neon, - &vpx_highbd_d207_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_32x32_neon, - &vpx_highbd_d207_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_neon, - &vpx_highbd_dc_128_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_neon, - &vpx_highbd_dc_128_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_neon, - &vpx_highbd_dc_128_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_neon, - &vpx_highbd_dc_128_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_neon, - &vpx_highbd_dc_left_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_neon, - &vpx_highbd_dc_left_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_neon, - &vpx_highbd_dc_left_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_neon, - &vpx_highbd_dc_left_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_neon, - &vpx_highbd_dc_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_neon, - &vpx_highbd_dc_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_16x16_neon, - &vpx_highbd_dc_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_neon, - &vpx_highbd_dc_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_neon, - &vpx_highbd_dc_top_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_neon, - &vpx_highbd_dc_top_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_neon, - &vpx_highbd_dc_top_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_neon, - &vpx_highbd_dc_top_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_neon, - &vpx_highbd_h_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_neon, - &vpx_highbd_h_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_neon, - &vpx_highbd_h_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_neon, - &vpx_highbd_h_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_neon, - &vpx_highbd_tm_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_neon, - &vpx_highbd_tm_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_16x16_neon, - &vpx_highbd_tm_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_neon, - &vpx_highbd_tm_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_neon, - &vpx_highbd_v_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_neon, - &vpx_highbd_v_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_v_predictor_16x16_neon, - &vpx_highbd_v_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_v_predictor_32x32_neon, - &vpx_highbd_v_predictor_32x32_c, 32, 10))); - -INSTANTIATE_TEST_SUITE_P( - NEON_TO_C_12, VP9HighbdIntraPredTest, - ::testing::Values( - HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_neon, - &vpx_highbd_d45_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_neon, - &vpx_highbd_d45_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_neon, - &vpx_highbd_d45_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_neon, - &vpx_highbd_d45_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_4x4_neon, - &vpx_highbd_d63_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_8x8_neon, - &vpx_highbd_d63_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_16x16_neon, - &vpx_highbd_d63_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_d63_predictor_32x32_neon, - &vpx_highbd_d63_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_4x4_neon, - &vpx_highbd_d117_predictor_4x4_c, 4, 10), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_8x8_neon, - &vpx_highbd_d117_predictor_8x8_c, 8, 10), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_16x16_neon, - &vpx_highbd_d117_predictor_16x16_c, 16, 10), - HighbdIntraPredParam(&vpx_highbd_d117_predictor_32x32_neon, - &vpx_highbd_d117_predictor_32x32_c, 32, 10), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_neon, - &vpx_highbd_d135_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_neon, - &vpx_highbd_d135_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_neon, - &vpx_highbd_d135_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_neon, - &vpx_highbd_d135_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_4x4_neon, - &vpx_highbd_d153_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_8x8_neon, - &vpx_highbd_d153_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_16x16_neon, - &vpx_highbd_d153_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_d153_predictor_32x32_neon, - &vpx_highbd_d153_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_4x4_neon, - &vpx_highbd_d207_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_8x8_neon, - &vpx_highbd_d207_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_16x16_neon, - &vpx_highbd_d207_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_d207_predictor_32x32_neon, - &vpx_highbd_d207_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_neon, - &vpx_highbd_dc_128_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_neon, - &vpx_highbd_dc_128_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_neon, - &vpx_highbd_dc_128_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_neon, - &vpx_highbd_dc_128_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_neon, - &vpx_highbd_dc_left_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_neon, - &vpx_highbd_dc_left_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_neon, - &vpx_highbd_dc_left_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_neon, - &vpx_highbd_dc_left_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_neon, - &vpx_highbd_dc_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_neon, - &vpx_highbd_dc_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_16x16_neon, - &vpx_highbd_dc_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_neon, - &vpx_highbd_dc_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_neon, - &vpx_highbd_dc_top_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_neon, - &vpx_highbd_dc_top_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_neon, - &vpx_highbd_dc_top_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_neon, - &vpx_highbd_dc_top_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_neon, - &vpx_highbd_h_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_neon, - &vpx_highbd_h_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_neon, - &vpx_highbd_h_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_neon, - &vpx_highbd_h_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_neon, - &vpx_highbd_tm_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_neon, - &vpx_highbd_tm_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_16x16_neon, - &vpx_highbd_tm_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_neon, - &vpx_highbd_tm_predictor_32x32_c, 32, 12), - HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_neon, - &vpx_highbd_v_predictor_4x4_c, 4, 12), - HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_neon, - &vpx_highbd_v_predictor_8x8_c, 8, 12), - HighbdIntraPredParam(&vpx_highbd_v_predictor_16x16_neon, - &vpx_highbd_v_predictor_16x16_c, 16, 12), - HighbdIntraPredParam(&vpx_highbd_v_predictor_32x32_neon, - &vpx_highbd_v_predictor_32x32_c, 32, 12))); -#endif // HAVE_NEON - -#endif // CONFIG_VP9_HIGHBITDEPTH -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_lossless_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_lossless_test.cc deleted file mode 100644 index 48839a7a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_lossless_test.cc +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "gtest/gtest.h" - -#include "./vpx_config.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" -#include "test/y4m_video_source.h" - -namespace { - -const int kMaxPsnr = 100; - -class LosslessTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWithParam { - protected: - LosslessTest() - : EncoderTest(GET_PARAM(0)), psnr_(kMaxPsnr), nframes_(0), - encoding_mode_(GET_PARAM(1)) {} - - ~LosslessTest() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(encoding_mode_); - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - // Only call Control if quantizer > 0 to verify that using quantizer - // alone will activate lossless - if (cfg_.rc_max_quantizer > 0 || cfg_.rc_min_quantizer > 0) { - encoder->Control(VP9E_SET_LOSSLESS, 1); - } - } - } - - void BeginPassHook(unsigned int /*pass*/) override { - psnr_ = kMaxPsnr; - nframes_ = 0; - } - - void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) override { - if (pkt->data.psnr.psnr[0] < psnr_) psnr_ = pkt->data.psnr.psnr[0]; - } - - double GetMinPsnr() const { return psnr_; } - - private: - double psnr_; - unsigned int nframes_; - libvpx_test::TestMode encoding_mode_; -}; - -TEST_P(LosslessTest, TestLossLessEncoding) { - const vpx_rational timebase = { 33333333, 1000000000 }; - cfg_.g_timebase = timebase; - cfg_.rc_target_bitrate = 2000; - cfg_.g_lag_in_frames = 25; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 0; - - init_flags_ = VPX_CODEC_USE_PSNR; - - // intentionally changed the dimension for better testing coverage - libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - timebase.den, timebase.num, 0, 10); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - const double psnr_lossless = GetMinPsnr(); - EXPECT_GE(psnr_lossless, kMaxPsnr); -} - -TEST_P(LosslessTest, TestLossLessEncoding444) { - libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 10); - - cfg_.g_profile = 1; - cfg_.g_timebase = video.timebase(); - cfg_.rc_target_bitrate = 2000; - cfg_.g_lag_in_frames = 25; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 0; - - init_flags_ = VPX_CODEC_USE_PSNR; - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - const double psnr_lossless = GetMinPsnr(); - EXPECT_GE(psnr_lossless, kMaxPsnr); -} - -TEST_P(LosslessTest, TestLossLessEncodingCtrl) { - const vpx_rational timebase = { 33333333, 1000000000 }; - cfg_.g_timebase = timebase; - cfg_.rc_target_bitrate = 2000; - cfg_.g_lag_in_frames = 25; - // Intentionally set Q > 0, to make sure control can be used to activate - // lossless - cfg_.rc_min_quantizer = 10; - cfg_.rc_max_quantizer = 20; - - init_flags_ = VPX_CODEC_USE_PSNR; - - libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, - timebase.den, timebase.num, 0, 10); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - const double psnr_lossless = GetMinPsnr(); - EXPECT_GE(psnr_lossless, kMaxPsnr); -} - -#if CONFIG_REALTIME_ONLY -VP9_INSTANTIATE_TEST_SUITE(LosslessTest, - ::testing::Values(::libvpx_test::kRealTime)); -#else -VP9_INSTANTIATE_TEST_SUITE(LosslessTest, - ::testing::Values(::libvpx_test::kRealTime, - ::libvpx_test::kOnePassGood, - ::libvpx_test::kTwoPassGood)); -#endif -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_motion_vector_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_motion_vector_test.cc deleted file mode 100644 index b47f5309..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_motion_vector_test.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "gtest/gtest.h" - -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/util.h" -#include "test/yuv_video_source.h" -#include "vpx_config.h" - -namespace { -#define MAX_EXTREME_MV 1 -#define MIN_EXTREME_MV 2 - -// Encoding modes -const libvpx_test::TestMode kEncodingModeVectors[] = { -#if !CONFIG_REALTIME_ONLY - ::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood, -#endif - ::libvpx_test::kRealTime -}; - -// Encoding speeds -const int kCpuUsedVectors[] = { 0, 1, 2, 3, 4, 5, 6 }; - -// MV test modes: 1 - always use maximum MV; 2 - always use minimum MV. -const int kMVTestModes[] = { MAX_EXTREME_MV, MIN_EXTREME_MV }; - -class MotionVectorTestLarge - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith3Params { - protected: - MotionVectorTestLarge() - : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)), - cpu_used_(GET_PARAM(2)), mv_test_mode_(GET_PARAM(3)) {} - - ~MotionVectorTestLarge() override = default; - - void SetUp() override { - InitializeConfig(); - SetMode(encoding_mode_); - if (encoding_mode_ != ::libvpx_test::kRealTime) { - cfg_.g_lag_in_frames = 3; - cfg_.rc_end_usage = VPX_VBR; - } else { - cfg_.g_lag_in_frames = 0; - cfg_.rc_end_usage = VPX_CBR; - cfg_.rc_buf_sz = 1000; - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 600; - } - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, cpu_used_); - encoder->Control(VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, mv_test_mode_); - if (encoding_mode_ != ::libvpx_test::kRealTime) { - encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); - encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7); - encoder->Control(VP8E_SET_ARNR_STRENGTH, 5); - encoder->Control(VP8E_SET_ARNR_TYPE, 3); - } - } - } - - libvpx_test::TestMode encoding_mode_; - int cpu_used_; - int mv_test_mode_; -}; - -TEST_P(MotionVectorTestLarge, OverallTest) { - cfg_.rc_target_bitrate = 24000; - cfg_.g_profile = 0; - init_flags_ = VPX_CODEC_USE_PSNR; - - std::unique_ptr video; - video.reset(new libvpx_test::YUVVideoSource( - "niklas_640_480_30.yuv", VPX_IMG_FMT_I420, 3840, 2160, // 2048, 1080, - 30, 1, 0, 5)); - - ASSERT_NE(video.get(), nullptr); - ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); -} - -VP9_INSTANTIATE_TEST_SUITE(MotionVectorTestLarge, - ::testing::ValuesIn(kEncodingModeVectors), - ::testing::ValuesIn(kCpuUsedVectors), - ::testing::ValuesIn(kMVTestModes)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_quantize_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_quantize_test.cc deleted file mode 100644 index 86463b87..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_quantize_test.cc +++ /dev/null @@ -1,725 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "test/acm_random.h" -#include "test/bench.h" -#include "test/buffer.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vp9/common/vp9_entropy.h" -#include "vp9/common/vp9_scan.h" -#include "vp9/encoder/vp9_block.h" -#include "vpx/vpx_codec.h" -#include "vpx/vpx_integer.h" -#include "vpx_ports/vpx_timer.h" - -using libvpx_test::ACMRandom; -using libvpx_test::Buffer; - -namespace { -const int number_of_iterations = 100; - -typedef void (*QuantizeFunc)(const tran_low_t *coeff, intptr_t count, - const macroblock_plane *mb_plane, - tran_low_t *qcoeff, tran_low_t *dqcoeff, - const int16_t *dequant, uint16_t *eob, - const struct ScanOrder *const scan_order); -typedef std::tuple - QuantizeParam; - -// Wrapper for 32x32 version which does not use count -typedef void (*Quantize32x32Func)(const tran_low_t *coeff, - const macroblock_plane *const mb_plane, - tran_low_t *qcoeff, tran_low_t *dqcoeff, - const int16_t *dequant, uint16_t *eob, - const struct ScanOrder *const scan_order); - -template -void Quant32x32Wrapper(const tran_low_t *coeff, intptr_t count, - const macroblock_plane *const mb_plane, - tran_low_t *qcoeff, tran_low_t *dqcoeff, - const int16_t *dequant, uint16_t *eob, - const struct ScanOrder *const scan_order) { - (void)count; - fn(coeff, mb_plane, qcoeff, dqcoeff, dequant, eob, scan_order); -} - -// Wrapper for FP version which does not use zbin or quant_shift. -typedef void (*QuantizeFPFunc)(const tran_low_t *coeff, intptr_t count, - const macroblock_plane *const mb_plane, - tran_low_t *qcoeff, tran_low_t *dqcoeff, - const int16_t *dequant, uint16_t *eob, - const struct ScanOrder *const scan_order); - -template -void QuantFPWrapper(const tran_low_t *coeff, intptr_t count, - const macroblock_plane *const mb_plane, tran_low_t *qcoeff, - tran_low_t *dqcoeff, const int16_t *dequant, uint16_t *eob, - const struct ScanOrder *const scan_order) { - fn(coeff, count, mb_plane, qcoeff, dqcoeff, dequant, eob, scan_order); -} - -void GenerateHelperArrays(ACMRandom *rnd, int16_t *zbin, int16_t *round, - int16_t *quant, int16_t *quant_shift, - int16_t *dequant, int16_t *round_fp, - int16_t *quant_fp) { - // Max when q == 0. Otherwise, it is 48 for Y and 42 for U/V. - constexpr int kMaxQRoundingFactorFp = 64; - - for (int j = 0; j < 2; j++) { - // The range is 4 to 1828 in the VP9 tables. - const int qlookup = rnd->RandRange(1825) + 4; - round_fp[j] = (kMaxQRoundingFactorFp * qlookup) >> 7; - quant_fp[j] = (1 << 16) / qlookup; - - // Values determined by deconstructing vp9_init_quantizer(). - // zbin may be up to 1143 for 8 and 10 bit Y values, or 1200 for 12 bit Y - // values or U/V values of any bit depth. This is because y_delta is not - // factored into the vp9_ac_quant() call. - zbin[j] = rnd->RandRange(1200); - - // round may be up to 685 for Y values or 914 for U/V. - round[j] = rnd->RandRange(914); - // quant ranges from 1 to -32703 - quant[j] = static_cast(rnd->RandRange(32704)) - 32703; - // quant_shift goes up to 1 << 16. - quant_shift[j] = rnd->RandRange(16384); - // dequant maxes out at 1828 for all cases. - dequant[j] = rnd->RandRange(1828); - } - for (int j = 2; j < 8; j++) { - zbin[j] = zbin[1]; - round_fp[j] = round_fp[1]; - quant_fp[j] = quant_fp[1]; - round[j] = round[1]; - quant[j] = quant[1]; - quant_shift[j] = quant_shift[1]; - dequant[j] = dequant[1]; - } -} - -class VP9QuantizeBase : public AbstractBench { - public: - VP9QuantizeBase(vpx_bit_depth_t bit_depth, int max_size, bool is_fp) - : bit_depth_(bit_depth), max_size_(max_size), is_fp_(is_fp), - coeff_(Buffer(max_size_, max_size_, 0, 16)), - qcoeff_(Buffer(max_size_, max_size_, 0, 32)), - dqcoeff_(Buffer(max_size_, max_size_, 0, 32)) { - // TODO(jianj): SSSE3 and AVX2 tests fail on extreme values. -#if HAVE_NEON - max_value_ = (1 << (7 + bit_depth_)) - 1; -#else - max_value_ = (1 << bit_depth_) - 1; -#endif - - mb_plane_ = reinterpret_cast( - vpx_memalign(16, sizeof(macroblock_plane))); - - zbin_ptr_ = mb_plane_->zbin = - reinterpret_cast(vpx_memalign(16, 8 * sizeof(*zbin_ptr_))); - round_fp_ptr_ = mb_plane_->round_fp = reinterpret_cast( - vpx_memalign(16, 8 * sizeof(*round_fp_ptr_))); - quant_fp_ptr_ = mb_plane_->quant_fp = reinterpret_cast( - vpx_memalign(16, 8 * sizeof(*quant_fp_ptr_))); - round_ptr_ = mb_plane_->round = - reinterpret_cast(vpx_memalign(16, 8 * sizeof(*round_ptr_))); - quant_ptr_ = mb_plane_->quant = - reinterpret_cast(vpx_memalign(16, 8 * sizeof(*quant_ptr_))); - quant_shift_ptr_ = mb_plane_->quant_shift = reinterpret_cast( - vpx_memalign(16, 8 * sizeof(*quant_shift_ptr_))); - dequant_ptr_ = reinterpret_cast( - vpx_memalign(16, 8 * sizeof(*dequant_ptr_))); - - r_ptr_ = (is_fp_) ? round_fp_ptr_ : round_ptr_; - q_ptr_ = (is_fp_) ? quant_fp_ptr_ : quant_ptr_; - } - - ~VP9QuantizeBase() override { - vpx_free(mb_plane_); - vpx_free(zbin_ptr_); - vpx_free(round_fp_ptr_); - vpx_free(quant_fp_ptr_); - vpx_free(round_ptr_); - vpx_free(quant_ptr_); - vpx_free(quant_shift_ptr_); - vpx_free(dequant_ptr_); - mb_plane_ = nullptr; - zbin_ptr_ = nullptr; - round_fp_ptr_ = nullptr; - quant_fp_ptr_ = nullptr; - round_ptr_ = nullptr; - quant_ptr_ = nullptr; - quant_shift_ptr_ = nullptr; - dequant_ptr_ = nullptr; - libvpx_test::ClearSystemState(); - } - - protected: - macroblock_plane *mb_plane_; - int16_t *zbin_ptr_; - int16_t *quant_fp_ptr_; - int16_t *round_fp_ptr_; - int16_t *round_ptr_; - int16_t *quant_ptr_; - int16_t *quant_shift_ptr_; - int16_t *dequant_ptr_; - const vpx_bit_depth_t bit_depth_; - int max_value_; - const int max_size_; - const bool is_fp_; - Buffer coeff_; - Buffer qcoeff_; - Buffer dqcoeff_; - int16_t *r_ptr_; - int16_t *q_ptr_; - int count_; - const ScanOrder *scan_; - uint16_t eob_; -}; - -class VP9QuantizeTest : public VP9QuantizeBase, - public ::testing::TestWithParam { - public: - VP9QuantizeTest() - : VP9QuantizeBase(GET_PARAM(2), GET_PARAM(3), GET_PARAM(4)), - quantize_op_(GET_PARAM(0)), ref_quantize_op_(GET_PARAM(1)) {} - - protected: - void Run() override; - void Speed(bool is_median); - const QuantizeFunc quantize_op_; - const QuantizeFunc ref_quantize_op_; -}; - -void VP9QuantizeTest::Run() { - quantize_op_(coeff_.TopLeftPixel(), count_, mb_plane_, qcoeff_.TopLeftPixel(), - dqcoeff_.TopLeftPixel(), dequant_ptr_, &eob_, scan_); -} - -void VP9QuantizeTest::Speed(bool is_median) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - ASSERT_TRUE(coeff_.Init()); - ASSERT_TRUE(qcoeff_.Init()); - ASSERT_TRUE(dqcoeff_.Init()); - TX_SIZE starting_sz, ending_sz; - - if (max_size_ == 16) { - starting_sz = TX_4X4; - ending_sz = TX_16X16; - } else { - starting_sz = TX_32X32; - ending_sz = TX_32X32; - } - - for (TX_SIZE sz = starting_sz; sz <= ending_sz; ++sz) { - // zbin > coeff, zbin < coeff. - for (int i = 0; i < 2; ++i) { - // TX_TYPE defines the scan order. That is not relevant to the speed test. - // Pick the first one. - const TX_TYPE tx_type = DCT_DCT; - count_ = (4 << sz) * (4 << sz); - scan_ = &vp9_scan_orders[sz][tx_type]; - - GenerateHelperArrays(&rnd, zbin_ptr_, round_ptr_, quant_ptr_, - quant_shift_ptr_, dequant_ptr_, round_fp_ptr_, - quant_fp_ptr_); - - if (i == 0) { - // When |coeff values| are less than zbin the results are 0. - int threshold = 100; - if (max_size_ == 32) { - // For 32x32, the threshold is halved. Double it to keep the values - // from clearing it. - threshold = 200; - } - for (int j = 0; j < 8; ++j) zbin_ptr_[j] = threshold; - coeff_.Set(&rnd, -99, 99); - } else if (i == 1) { - for (int j = 0; j < 8; ++j) zbin_ptr_[j] = 50; - coeff_.Set(&rnd, -500, 500); - } - - const char *type = - (i == 0) ? "Bypass calculations " : "Full calculations "; - char block_size[16]; - snprintf(block_size, sizeof(block_size), "%dx%d", 4 << sz, 4 << sz); - char title[100]; - snprintf(title, sizeof(title), "%25s %8s ", type, block_size); - - if (is_median) { - RunNTimes(10000000 / count_); - PrintMedian(title); - } else { - Buffer ref_qcoeff = - Buffer(max_size_, max_size_, 0, 32); - ASSERT_TRUE(ref_qcoeff.Init()); - Buffer ref_dqcoeff = - Buffer(max_size_, max_size_, 0, 32); - ASSERT_TRUE(ref_dqcoeff.Init()); - uint16_t ref_eob = 0; - - const int kNumTests = 5000000; - vpx_usec_timer timer, simd_timer; - - vpx_usec_timer_start(&timer); - for (int n = 0; n < kNumTests; ++n) { - ref_quantize_op_(coeff_.TopLeftPixel(), count_, mb_plane_, - ref_qcoeff.TopLeftPixel(), - ref_dqcoeff.TopLeftPixel(), dequant_ptr_, &ref_eob, - scan_); - } - vpx_usec_timer_mark(&timer); - - vpx_usec_timer_start(&simd_timer); - for (int n = 0; n < kNumTests; ++n) { - quantize_op_(coeff_.TopLeftPixel(), count_, mb_plane_, - qcoeff_.TopLeftPixel(), dqcoeff_.TopLeftPixel(), - dequant_ptr_, &eob_, scan_); - } - vpx_usec_timer_mark(&simd_timer); - - const int elapsed_time = - static_cast(vpx_usec_timer_elapsed(&timer)); - const int simd_elapsed_time = - static_cast(vpx_usec_timer_elapsed(&simd_timer)); - printf("%s c_time = %d \t simd_time = %d \t Gain = %f \n", title, - elapsed_time, simd_elapsed_time, - ((float)elapsed_time / simd_elapsed_time)); - } - } - } -} - -// This quantizer compares the AC coefficients to the quantization step size to -// determine if further multiplication operations are needed. -// Based on vp9_quantize_fp_sse2(). -inline void quant_fp_nz(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order, - int is_32x32) { - int i, eob = -1; - const int thr = dequant_ptr[1] >> (1 + is_32x32); - const int16_t *round_ptr = mb_plane->round_fp; - const int16_t *quant_ptr = mb_plane->quant_fp; - const int16_t *scan = scan_order->scan; - - // Quantization pass: All coefficients with index >= zero_flag are - // skippable. Note: zero_flag can be zero. - for (i = 0; i < n_coeffs; i += 16) { - int y; - int nzflag_cnt = 0; - int abs_coeff[16]; - int coeff_sign[16]; - - // count nzflag for each row (16 tran_low_t) - for (y = 0; y < 16; ++y) { - const int rc = i + y; - const int coeff = coeff_ptr[rc]; - coeff_sign[y] = (coeff >> 31); - abs_coeff[y] = (coeff ^ coeff_sign[y]) - coeff_sign[y]; - // The first 16 are skipped in the sse2 code. Do the same here to match. - if (i >= 16 && (abs_coeff[y] <= thr)) { - nzflag_cnt++; - } - } - - for (y = 0; y < 16; ++y) { - const int rc = i + y; - // If all of the AC coeffs in a row has magnitude less than the - // quantization step_size/2, quantize to zero. - if (nzflag_cnt < 16) { - int tmp; - int _round; - - if (is_32x32) { - _round = ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1); - } else { - _round = round_ptr[rc != 0]; - } - tmp = clamp(abs_coeff[y] + _round, INT16_MIN, INT16_MAX); - tmp = (tmp * quant_ptr[rc != 0]) >> (16 - is_32x32); - qcoeff_ptr[rc] = (tmp ^ coeff_sign[y]) - coeff_sign[y]; - dqcoeff_ptr[rc] = - static_cast(qcoeff_ptr[rc] * dequant_ptr[rc != 0]); - - if (is_32x32) { - dqcoeff_ptr[rc] = static_cast(qcoeff_ptr[rc] * - dequant_ptr[rc != 0] / 2); - } else { - dqcoeff_ptr[rc] = - static_cast(qcoeff_ptr[rc] * dequant_ptr[rc != 0]); - } - } else { - qcoeff_ptr[rc] = 0; - dqcoeff_ptr[rc] = 0; - } - } - } - - // Scan for eob. - for (i = 0; i < n_coeffs; i++) { - // Use the scan order to find the correct eob. - const int rc = scan[i]; - if (qcoeff_ptr[rc]) { - eob = i; - } - } - *eob_ptr = eob + 1; -} - -void quantize_fp_nz_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - quant_fp_nz(coeff_ptr, n_coeffs, mb_plane, qcoeff_ptr, dqcoeff_ptr, - dequant_ptr, eob_ptr, scan_order, 0); -} - -void quantize_fp_32x32_nz_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - quant_fp_nz(coeff_ptr, n_coeffs, mb_plane, qcoeff_ptr, dqcoeff_ptr, - dequant_ptr, eob_ptr, scan_order, 1); -} - -TEST_P(VP9QuantizeTest, OperationCheck) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - ASSERT_TRUE(coeff_.Init()); - ASSERT_TRUE(qcoeff_.Init()); - ASSERT_TRUE(dqcoeff_.Init()); - Buffer ref_qcoeff = - Buffer(max_size_, max_size_, 0, 32); - ASSERT_TRUE(ref_qcoeff.Init()); - Buffer ref_dqcoeff = - Buffer(max_size_, max_size_, 0, 32); - ASSERT_TRUE(ref_dqcoeff.Init()); - uint16_t ref_eob = 0; - eob_ = 0; - - for (int i = 0; i < number_of_iterations; ++i) { - TX_SIZE sz; - if (max_size_ == 16) { - sz = static_cast(i % 3); // TX_4X4, TX_8X8 TX_16X16 - } else { - sz = TX_32X32; - } - const TX_TYPE tx_type = static_cast((i >> 2) % 3); - scan_ = &vp9_scan_orders[sz][tx_type]; - count_ = (4 << sz) * (4 << sz); - coeff_.Set(&rnd, -max_value_, max_value_); - GenerateHelperArrays(&rnd, zbin_ptr_, round_ptr_, quant_ptr_, - quant_shift_ptr_, dequant_ptr_, round_fp_ptr_, - quant_fp_ptr_); - ref_quantize_op_(coeff_.TopLeftPixel(), count_, mb_plane_, - ref_qcoeff.TopLeftPixel(), ref_dqcoeff.TopLeftPixel(), - dequant_ptr_, &ref_eob, scan_); - - ASM_REGISTER_STATE_CHECK(quantize_op_( - coeff_.TopLeftPixel(), count_, mb_plane_, qcoeff_.TopLeftPixel(), - dqcoeff_.TopLeftPixel(), dequant_ptr_, &eob_, scan_)); - - EXPECT_TRUE(qcoeff_.CheckValues(ref_qcoeff)); - EXPECT_TRUE(dqcoeff_.CheckValues(ref_dqcoeff)); - - EXPECT_EQ(eob_, ref_eob); - - if (HasFailure()) { - printf("Failure on iteration %d.\n", i); - qcoeff_.PrintDifference(ref_qcoeff); - dqcoeff_.PrintDifference(ref_dqcoeff); - return; - } - } -} - -TEST_P(VP9QuantizeTest, EOBCheck) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - ASSERT_TRUE(coeff_.Init()); - ASSERT_TRUE(qcoeff_.Init()); - ASSERT_TRUE(dqcoeff_.Init()); - Buffer ref_qcoeff = - Buffer(max_size_, max_size_, 0, 32); - ASSERT_TRUE(ref_qcoeff.Init()); - Buffer ref_dqcoeff = - Buffer(max_size_, max_size_, 0, 32); - ASSERT_TRUE(ref_dqcoeff.Init()); - uint16_t ref_eob = 0; - eob_ = 0; - const uint32_t max_index = max_size_ * max_size_ - 1; - - for (int i = 0; i < number_of_iterations; ++i) { - TX_SIZE sz; - if (max_size_ == 16) { - sz = static_cast(i % 3); // TX_4X4, TX_8X8 TX_16X16 - } else { - sz = TX_32X32; - } - const TX_TYPE tx_type = static_cast((i >> 2) % 3); - scan_ = &vp9_scan_orders[sz][tx_type]; - count_ = (4 << sz) * (4 << sz); - // Two random entries - coeff_.Set(0); - coeff_.TopLeftPixel()[rnd.RandRange(count_) & max_index] = - static_cast(rnd.RandRange(max_value_ * 2)) - max_value_; - coeff_.TopLeftPixel()[rnd.RandRange(count_) & max_index] = - static_cast(rnd.RandRange(max_value_ * 2)) - max_value_; - GenerateHelperArrays(&rnd, zbin_ptr_, round_ptr_, quant_ptr_, - quant_shift_ptr_, dequant_ptr_, round_fp_ptr_, - quant_fp_ptr_); - ref_quantize_op_(coeff_.TopLeftPixel(), count_, mb_plane_, - ref_qcoeff.TopLeftPixel(), ref_dqcoeff.TopLeftPixel(), - dequant_ptr_, &ref_eob, scan_); - - ASM_REGISTER_STATE_CHECK(quantize_op_( - coeff_.TopLeftPixel(), count_, mb_plane_, qcoeff_.TopLeftPixel(), - dqcoeff_.TopLeftPixel(), dequant_ptr_, &eob_, scan_)); - - EXPECT_TRUE(qcoeff_.CheckValues(ref_qcoeff)); - EXPECT_TRUE(dqcoeff_.CheckValues(ref_dqcoeff)); - - EXPECT_EQ(eob_, ref_eob); - - if (HasFailure()) { - printf("Failure on iteration %d.\n", i); - qcoeff_.PrintDifference(ref_qcoeff); - dqcoeff_.PrintDifference(ref_dqcoeff); - return; - } - } -} - -TEST_P(VP9QuantizeTest, DISABLED_Speed) { Speed(false); } - -TEST_P(VP9QuantizeTest, DISABLED_SpeedMedian) { Speed(true); } - -using std::make_tuple; - -#if HAVE_SSE2 -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - SSE2, VP9QuantizeTest, - ::testing::Values( - make_tuple(vpx_quantize_b_sse2, vpx_quantize_b_c, VPX_BITS_8, 16, - false), - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, VPX_BITS_8, 16, true), - make_tuple(vpx_highbd_quantize_b_sse2, vpx_highbd_quantize_b_c, - VPX_BITS_8, 16, false), - make_tuple(vpx_highbd_quantize_b_sse2, vpx_highbd_quantize_b_c, - VPX_BITS_10, 16, false), - make_tuple(vpx_highbd_quantize_b_sse2, vpx_highbd_quantize_b_c, - VPX_BITS_12, 16, false), - make_tuple(&Quant32x32Wrapper, - &Quant32x32Wrapper, - VPX_BITS_8, 32, false), - make_tuple(&Quant32x32Wrapper, - &Quant32x32Wrapper, - VPX_BITS_10, 32, false), - make_tuple(&Quant32x32Wrapper, - &Quant32x32Wrapper, - VPX_BITS_12, 32, false))); - -#else -INSTANTIATE_TEST_SUITE_P( - SSE2, VP9QuantizeTest, - ::testing::Values(make_tuple(vpx_quantize_b_sse2, vpx_quantize_b_c, - VPX_BITS_8, 16, false), - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, VPX_BITS_8, - 16, true))); -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif // HAVE_SSE2 - -#if HAVE_SSSE3 -INSTANTIATE_TEST_SUITE_P( - SSSE3, VP9QuantizeTest, - ::testing::Values(make_tuple(vpx_quantize_b_ssse3, vpx_quantize_b_c, - VPX_BITS_8, 16, false), - make_tuple(&Quant32x32Wrapper, - &Quant32x32Wrapper, - VPX_BITS_8, 32, false), - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, VPX_BITS_8, - 16, true), - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, - VPX_BITS_8, 32, true))); -#endif // HAVE_SSSE3 - -#if HAVE_AVX -INSTANTIATE_TEST_SUITE_P( - AVX, VP9QuantizeTest, - ::testing::Values(make_tuple(vpx_quantize_b_avx, vpx_quantize_b_c, - VPX_BITS_8, 16, false), - make_tuple(&Quant32x32Wrapper, - &Quant32x32Wrapper, - VPX_BITS_8, 32, false))); -#endif // HAVE_AVX - -#if VPX_ARCH_X86_64 && HAVE_AVX2 -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - AVX2, VP9QuantizeTest, - ::testing::Values( - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, VPX_BITS_8, 16, true), - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, VPX_BITS_12, 16, - true), - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, VPX_BITS_12, - 32, true), - make_tuple(vpx_quantize_b_avx2, vpx_quantize_b_c, VPX_BITS_8, 16, - false), - make_tuple(vpx_highbd_quantize_b_avx2, vpx_highbd_quantize_b_c, - VPX_BITS_8, 16, false), - make_tuple(vpx_highbd_quantize_b_avx2, vpx_highbd_quantize_b_c, - VPX_BITS_10, 16, false), - make_tuple(vpx_highbd_quantize_b_avx2, vpx_highbd_quantize_b_c, - VPX_BITS_12, 16, false), - make_tuple(&Quant32x32Wrapper, - &Quant32x32Wrapper, VPX_BITS_8, 32, - false), - make_tuple(&Quant32x32Wrapper, - &Quant32x32Wrapper, - VPX_BITS_8, 32, false), - make_tuple(&Quant32x32Wrapper, - &Quant32x32Wrapper, - VPX_BITS_10, 32, false), - make_tuple(&Quant32x32Wrapper, - &Quant32x32Wrapper, - VPX_BITS_12, 32, false))); -#else -INSTANTIATE_TEST_SUITE_P( - AVX2, VP9QuantizeTest, - ::testing::Values(make_tuple(&QuantFPWrapper, - &QuantFPWrapper, VPX_BITS_8, - 16, true), - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, - VPX_BITS_8, 32, true), - make_tuple(vpx_quantize_b_avx2, vpx_quantize_b_c, - VPX_BITS_8, 16, false), - make_tuple(&Quant32x32Wrapper, - &Quant32x32Wrapper, - VPX_BITS_8, 32, false))); -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif // HAVE_AVX2 - -#if HAVE_NEON -#if CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - NEON, VP9QuantizeTest, - ::testing::Values( - make_tuple(&vpx_quantize_b_neon, &vpx_quantize_b_c, VPX_BITS_8, 16, - false), - make_tuple(vpx_highbd_quantize_b_neon, vpx_highbd_quantize_b_c, - VPX_BITS_8, 16, false), - make_tuple(vpx_highbd_quantize_b_neon, vpx_highbd_quantize_b_c, - VPX_BITS_10, 16, false), - make_tuple(vpx_highbd_quantize_b_neon, vpx_highbd_quantize_b_c, - VPX_BITS_12, 16, false), - make_tuple(&Quant32x32Wrapper, - &Quant32x32Wrapper, VPX_BITS_8, 32, - false), - make_tuple(&Quant32x32Wrapper, - &Quant32x32Wrapper, - VPX_BITS_8, 32, false), - make_tuple(&Quant32x32Wrapper, - &Quant32x32Wrapper, - VPX_BITS_10, 32, false), - make_tuple(&Quant32x32Wrapper, - &Quant32x32Wrapper, - VPX_BITS_12, 32, false), - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, VPX_BITS_8, 16, true), - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, VPX_BITS_8, 32, - true))); -#else -INSTANTIATE_TEST_SUITE_P( - NEON, VP9QuantizeTest, - ::testing::Values(make_tuple(&vpx_quantize_b_neon, &vpx_quantize_b_c, - VPX_BITS_8, 16, false), - make_tuple(&Quant32x32Wrapper, - &Quant32x32Wrapper, - VPX_BITS_8, 32, false), - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, VPX_BITS_8, - 16, true), - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, - VPX_BITS_8, 32, true))); -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif // HAVE_NEON - -#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - VSX, VP9QuantizeTest, - ::testing::Values(make_tuple(&vpx_quantize_b_vsx, &vpx_quantize_b_c, - VPX_BITS_8, 16, false), - make_tuple(&vpx_quantize_b_32x32_vsx, - &vpx_quantize_b_32x32_c, VPX_BITS_8, 32, - false), - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, VPX_BITS_8, - 16, true), - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, - VPX_BITS_8, 32, true))); -#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH - -#if HAVE_LSX && !CONFIG_VP9_HIGHBITDEPTH -INSTANTIATE_TEST_SUITE_P( - LSX, VP9QuantizeTest, - ::testing::Values(make_tuple(&vpx_quantize_b_lsx, &vpx_quantize_b_c, - VPX_BITS_8, 16, false), - make_tuple(&Quant32x32Wrapper, - &Quant32x32Wrapper, - VPX_BITS_8, 32, false))); -#endif // HAVE_LSX && !CONFIG_VP9_HIGHBITDEPTH - -// Only useful to compare "Speed" test results. -INSTANTIATE_TEST_SUITE_P( - DISABLED_C, VP9QuantizeTest, - ::testing::Values( - make_tuple(&vpx_quantize_b_c, &vpx_quantize_b_c, VPX_BITS_8, 16, false), - make_tuple(&Quant32x32Wrapper, - &Quant32x32Wrapper, VPX_BITS_8, 32, - false), - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, VPX_BITS_8, 16, true), - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, VPX_BITS_8, 16, true), - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, VPX_BITS_8, 32, - true), - make_tuple(&QuantFPWrapper, - &QuantFPWrapper, VPX_BITS_8, 32, - true))); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_ratectrl_rtc_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_ratectrl_rtc_test.cc deleted file mode 100644 index e58f0a0d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_ratectrl_rtc_test.cc +++ /dev/null @@ -1,675 +0,0 @@ -/* - * Copyright (c) 2020 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "vp9/ratectrl_rtc.h" - -#include -#include // NOLINT -#include - -#include "./vpx_config.h" -#include "gtest/gtest.h" -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" -#include "test/video_source.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_svc_layercontext.h" -#include "vpx/vpx_codec.h" -#include "vpx_ports/bitops.h" - -namespace { - -const size_t kNumFrames = 300; - -const int kTemporalId3Layer[4] = { 0, 2, 1, 2 }; -const int kTemporalId2Layer[2] = { 0, 1 }; -const int kTemporalRateAllocation3Layer[3] = { 50, 70, 100 }; -const int kTemporalRateAllocation2Layer[2] = { 60, 100 }; -const int kSpatialLayerBitrate[3] = { 200, 400, 1000 }; -const int kSpatialLayerBitrateLow[3] = { 50, 100, 400 }; - -class RcInterfaceTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith2Params { - public: - RcInterfaceTest() - : EncoderTest(GET_PARAM(0)), aq_mode_(GET_PARAM(1)), key_interval_(3000), - encoder_exit_(false), frame_drop_thresh_(0), num_drops_(0) {} - - ~RcInterfaceTest() override = default; - - protected: - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - } - - void PreEncodeFrameHook(libvpx_test::VideoSource *video, - libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, 7); - encoder->Control(VP9E_SET_AQ_MODE, aq_mode_); - if (rc_cfg_.is_screen) { - encoder->Control(VP9E_SET_TUNE_CONTENT, VP9E_CONTENT_SCREEN); - } else { - encoder->Control(VP9E_SET_TUNE_CONTENT, VP9E_CONTENT_DEFAULT); - } - encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 1000); - encoder->Control(VP9E_SET_RTC_EXTERNAL_RATECTRL, 1); - } - frame_params_.frame_type = video->frame() % key_interval_ == 0 - ? libvpx::RcFrameType::kKeyFrame - : libvpx::RcFrameType::kInterFrame; - if (rc_cfg_.rc_mode == VPX_CBR && - frame_params_.frame_type == libvpx::RcFrameType::kInterFrame) { - // Disable golden frame update. - frame_flags_ |= VP8_EFLAG_NO_UPD_GF; - frame_flags_ |= VP8_EFLAG_NO_UPD_ARF; - } - encoder_exit_ = video->frame() == kNumFrames; - } - - void PostEncodeFrameHook(::libvpx_test::Encoder *encoder) override { - if (encoder_exit_) { - return; - } - int loopfilter_level, qp; - encoder->Control(VP9E_GET_LOOPFILTER_LEVEL, &loopfilter_level); - encoder->Control(VP8E_GET_LAST_QUANTIZER, &qp); - if (rc_api_->ComputeQP(frame_params_) == libvpx::FrameDropDecision::kOk) { - ASSERT_EQ(rc_api_->GetQP(), qp); - ASSERT_EQ(rc_api_->GetLoopfilterLevel(), loopfilter_level); - } else { - num_drops_++; - } - } - - void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override { - rc_api_->PostEncodeUpdate(pkt->data.frame.sz, frame_params_); - } - - void RunOneLayer() { - SetConfig(GET_PARAM(2)); - rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); - frame_params_.spatial_layer_id = 0; - frame_params_.temporal_layer_id = 0; - - ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", - 1280, 720, 30, 1, 0, kNumFrames); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - } - - void RunOneLayerScreen() { - SetConfig(GET_PARAM(2)); - rc_cfg_.is_screen = true; - rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); - frame_params_.spatial_layer_id = 0; - frame_params_.temporal_layer_id = 0; - - ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", - 1280, 720, 30, 1, 0, kNumFrames); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - } - - void RunOneLayerDropFramesCBR() { - if (GET_PARAM(2) != VPX_CBR) { - GTEST_SKIP() << "Frame dropping is only for CBR mode."; - } - frame_drop_thresh_ = 30; - SetConfig(GET_PARAM(2)); - // Use lower bitrate, lower max-q, and enable frame dropper. - rc_cfg_.target_bandwidth = 200; - cfg_.rc_target_bitrate = 200; - rc_cfg_.max_quantizer = 50; - cfg_.rc_max_quantizer = 50; - rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); - frame_params_.spatial_layer_id = 0; - frame_params_.temporal_layer_id = 0; - - ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", - 1280, 720, 30, 1, 0, kNumFrames); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - // Check that some frames were dropped, otherwise test has no value. - ASSERT_GE(num_drops_, 1); - } - - void RunOneLayerVBRPeriodicKey() { - if (GET_PARAM(2) != VPX_VBR) return; - key_interval_ = 100; - SetConfig(VPX_VBR); - rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); - frame_params_.spatial_layer_id = 0; - frame_params_.temporal_layer_id = 0; - - ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", - 1280, 720, 30, 1, 0, kNumFrames); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - } - - private: - void SetConfig(vpx_rc_mode rc_mode) { - rc_cfg_.width = 1280; - rc_cfg_.height = 720; - rc_cfg_.max_quantizer = 52; - rc_cfg_.min_quantizer = 2; - rc_cfg_.target_bandwidth = 1000; - rc_cfg_.buf_initial_sz = 600; - rc_cfg_.buf_optimal_sz = 600; - rc_cfg_.buf_sz = 1000; - rc_cfg_.undershoot_pct = 50; - rc_cfg_.overshoot_pct = 50; - rc_cfg_.max_intra_bitrate_pct = 1000; - rc_cfg_.framerate = 30.0; - rc_cfg_.ss_number_layers = 1; - rc_cfg_.ts_number_layers = 1; - rc_cfg_.scaling_factor_num[0] = 1; - rc_cfg_.scaling_factor_den[0] = 1; - rc_cfg_.layer_target_bitrate[0] = 1000; - rc_cfg_.max_quantizers[0] = 52; - rc_cfg_.min_quantizers[0] = 2; - rc_cfg_.rc_mode = rc_mode; - rc_cfg_.aq_mode = aq_mode_; - rc_cfg_.frame_drop_thresh = frame_drop_thresh_; - - // Encoder settings for ground truth. - cfg_.g_w = 1280; - cfg_.g_h = 720; - cfg_.rc_undershoot_pct = 50; - cfg_.rc_overshoot_pct = 50; - cfg_.rc_buf_initial_sz = 600; - cfg_.rc_buf_optimal_sz = 600; - cfg_.rc_buf_sz = 1000; - cfg_.rc_dropframe_thresh = 0; - cfg_.rc_min_quantizer = 2; - cfg_.rc_max_quantizer = 52; - cfg_.rc_end_usage = rc_mode; - cfg_.g_lag_in_frames = 0; - cfg_.g_error_resilient = 0; - cfg_.rc_target_bitrate = 1000; - cfg_.kf_min_dist = key_interval_; - cfg_.kf_max_dist = key_interval_; - cfg_.rc_dropframe_thresh = frame_drop_thresh_; - } - - std::unique_ptr rc_api_; - libvpx::VP9RateControlRtcConfig rc_cfg_; - int aq_mode_; - int key_interval_; - libvpx::VP9FrameParamsQpRTC frame_params_; - bool encoder_exit_; - int frame_drop_thresh_; - int num_drops_; -}; - -class RcInterfaceSvcTest - : public ::libvpx_test::EncoderTest, - public ::libvpx_test::CodecTestWith2Params { - public: - RcInterfaceSvcTest() - : EncoderTest(GET_PARAM(0)), aq_mode_(GET_PARAM(1)), key_interval_(3000), - dynamic_spatial_layers_(0), inter_layer_pred_off_(GET_PARAM(2)), - parallel_spatial_layers_(false), frame_drop_thresh_(0), - max_consec_drop_(INT_MAX), num_drops_(0) {} - ~RcInterfaceSvcTest() override = default; - - protected: - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - } - - void PreEncodeFrameHook(libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - current_superframe_ = 0; - encoder->Control(VP8E_SET_CPUUSED, 7); - encoder->Control(VP9E_SET_AQ_MODE, aq_mode_); - encoder->Control(VP9E_SET_TUNE_CONTENT, 0); - encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 900); - encoder->Control(VP9E_SET_RTC_EXTERNAL_RATECTRL, 1); - encoder->Control(VP9E_SET_SVC, 1); - encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_); - if (inter_layer_pred_off_) { - encoder->Control(VP9E_SET_SVC_INTER_LAYER_PRED, - INTER_LAYER_PRED_OFF_NONKEY); - } - if (frame_drop_thresh_ > 0) { - vpx_svc_frame_drop_t svc_drop_frame; - svc_drop_frame.framedrop_mode = FULL_SUPERFRAME_DROP; - for (int sl = 0; sl < rc_cfg_.ss_number_layers; ++sl) - svc_drop_frame.framedrop_thresh[sl] = frame_drop_thresh_; - svc_drop_frame.max_consec_drop = max_consec_drop_; - encoder->Control(VP9E_SET_SVC_FRAME_DROP_LAYER, &svc_drop_frame); - } - } - frame_params_.frame_type = video->frame() % key_interval_ == 0 - ? libvpx::RcFrameType::kKeyFrame - : libvpx::RcFrameType::kInterFrame; - encoder_exit_ = video->frame() == kNumFrames; - if (dynamic_spatial_layers_ == 1) { - if (video->frame() == 100) { - // Go down to 2 spatial layers: set top SL to 0 bitrate. - // Update the encoder config. - cfg_.rc_target_bitrate -= cfg_.layer_target_bitrate[8]; - cfg_.layer_target_bitrate[6] = 0; - cfg_.layer_target_bitrate[7] = 0; - cfg_.layer_target_bitrate[8] = 0; - encoder->Config(&cfg_); - // Update the RC config. - rc_cfg_.target_bandwidth -= rc_cfg_.layer_target_bitrate[8]; - rc_cfg_.layer_target_bitrate[6] = 0; - rc_cfg_.layer_target_bitrate[7] = 0; - rc_cfg_.layer_target_bitrate[8] = 0; - ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_)); - } else if (video->frame() == 200) { - // Go down to 1 spatial layer. - // Update the encoder config. - cfg_.rc_target_bitrate -= cfg_.layer_target_bitrate[5]; - cfg_.layer_target_bitrate[3] = 0; - cfg_.layer_target_bitrate[4] = 0; - cfg_.layer_target_bitrate[5] = 0; - encoder->Config(&cfg_); - // Update the RC config. - rc_cfg_.target_bandwidth -= rc_cfg_.layer_target_bitrate[5]; - rc_cfg_.layer_target_bitrate[3] = 0; - rc_cfg_.layer_target_bitrate[4] = 0; - rc_cfg_.layer_target_bitrate[5] = 0; - ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_)); - } else if (/*DISABLES CODE*/ (false) && video->frame() == 280) { - // TODO(marpan): Re-enable this going back up when issue is fixed. - // Go back up to 3 spatial layers. - // Update the encoder config: use the original bitrates. - SetEncoderConfigSvc(3, 3); - encoder->Config(&cfg_); - // Update the RC config. - SetRCConfigSvc(3, 3); - ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_)); - } - } - } - - virtual void SetFrameParamsSvc(int sl) { - frame_params_.spatial_layer_id = sl; - if (rc_cfg_.ts_number_layers == 3) - frame_params_.temporal_layer_id = - kTemporalId3Layer[current_superframe_ % 4]; - else if (rc_cfg_.ts_number_layers == 2) - frame_params_.temporal_layer_id = - kTemporalId2Layer[current_superframe_ % 2]; - else - frame_params_.temporal_layer_id = 0; - frame_params_.frame_type = - current_superframe_ % key_interval_ == 0 && sl == 0 - ? libvpx::RcFrameType::kKeyFrame - : libvpx::RcFrameType::kInterFrame; - } - - void PostEncodeFrameHook(::libvpx_test::Encoder *encoder) override { - if (encoder_exit_) { - return; - } - int superframe_is_dropped = false; - ::libvpx_test::CxDataIterator iter = encoder->GetCxData(); - for (int sl = 0; sl < rc_cfg_.ss_number_layers; sl++) sizes_[sl] = 0; - std::vector rc_qp; - // For FULL_SUPERFRAME_DROP: the full superframe drop decision is - // determined on the base spatial layer. - SetFrameParamsSvc(0); - if (rc_api_->ComputeQP(frame_params_) == libvpx::FrameDropDecision::kDrop) { - superframe_is_dropped = true; - num_drops_++; - } - while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) { - ASSERT_EQ(superframe_is_dropped, false); - ParseSuperframeSizes(static_cast(pkt->data.frame.buf), - pkt->data.frame.sz); - if (!parallel_spatial_layers_ || current_superframe_ == 0) { - for (int sl = 0; sl < rc_cfg_.ss_number_layers; sl++) { - if (sizes_[sl] > 0) { - SetFrameParamsSvc(sl); - // For sl=0 ComputeQP() is already called above (line 310). - if (sl > 0) rc_api_->ComputeQP(frame_params_); - rc_api_->PostEncodeUpdate(sizes_[sl], frame_params_); - rc_qp.push_back(rc_api_->GetQP()); - } - } - } else { - for (int sl = 0; sl < rc_cfg_.ss_number_layers; sl++) { - // For sl=0 ComputeQP() is already called above (line 310). - if (sizes_[sl] > 0 && sl > 0) { - SetFrameParamsSvc(sl); - rc_api_->ComputeQP(frame_params_); - } - } - for (int sl = 0; sl < rc_cfg_.ss_number_layers; sl++) { - if (sizes_[sl] > 0) { - SetFrameParamsSvc(sl); - rc_api_->PostEncodeUpdate(sizes_[sl], frame_params_); - rc_qp.push_back(rc_api_->GetQP()); - } - } - } - } - if (!superframe_is_dropped) { - int loopfilter_level; - std::vector encoder_qp(VPX_SS_MAX_LAYERS, 0); - encoder->Control(VP9E_GET_LOOPFILTER_LEVEL, &loopfilter_level); - encoder->Control(VP9E_GET_LAST_QUANTIZER_SVC_LAYERS, encoder_qp.data()); - encoder_qp.resize(rc_qp.size()); - ASSERT_EQ(rc_qp, encoder_qp); - ASSERT_EQ(rc_api_->GetLoopfilterLevel(), loopfilter_level); - current_superframe_++; - } - } - // This method needs to be overridden because non-reference frames are - // expected to be mismatched frames as the encoder will avoid loopfilter on - // these frames. - void MismatchHook(const vpx_image_t * /*img1*/, - const vpx_image_t * /*img2*/) override {} - - void RunSvc() { - SetRCConfigSvc(3, 3); - rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); - SetEncoderConfigSvc(3, 3); - - ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", - 1280, 720, 30, 1, 0, kNumFrames); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - } - - void RunSvcDropFramesCBR() { - max_consec_drop_ = 10; - frame_drop_thresh_ = 30; - SetRCConfigSvc(3, 3); - rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); - SetEncoderConfigSvc(3, 3); - - ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", - 1280, 720, 30, 1, 0, kNumFrames); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - // Check that some frames were dropped, otherwise test has no value. - ASSERT_GE(num_drops_, 1); - } - - void RunSvcPeriodicKey() { - SetRCConfigSvc(3, 3); - key_interval_ = 100; - rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); - SetEncoderConfigSvc(3, 3); - - ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", - 1280, 720, 30, 1, 0, kNumFrames); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - } - - void RunSvcDynamicSpatial() { - dynamic_spatial_layers_ = 1; - SetRCConfigSvc(3, 3); - rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); - SetEncoderConfigSvc(3, 3); - - ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", - 1280, 720, 30, 1, 0, kNumFrames); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - } - - void RunSvcParallelSpatialLayers() { - if (!inter_layer_pred_off_) return; - parallel_spatial_layers_ = true; - SetRCConfigSvc(3, 3); - rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); - SetEncoderConfigSvc(3, 3); - - ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", - 1280, 720, 30, 1, 0, kNumFrames); - - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); - } - - private: - vpx_codec_err_t ParseSuperframeSizes(const uint8_t *data, size_t data_sz) { - uint8_t marker = *(data + data_sz - 1); - if ((marker & 0xe0) == 0xc0) { - const uint32_t frames = (marker & 0x7) + 1; - const uint32_t mag = ((marker >> 3) & 0x3) + 1; - const size_t index_sz = 2 + mag * frames; - // This chunk is marked as having a superframe index but doesn't have - // enough data for it, thus it's an invalid superframe index. - if (data_sz < index_sz) return VPX_CODEC_CORRUPT_FRAME; - { - const uint8_t marker2 = *(data + data_sz - index_sz); - // This chunk is marked as having a superframe index but doesn't have - // the matching marker byte at the front of the index therefore it's an - // invalid chunk. - if (marker != marker2) return VPX_CODEC_CORRUPT_FRAME; - } - const uint8_t *x = &data[data_sz - index_sz + 1]; - for (uint32_t i = 0; i < frames; ++i) { - uint32_t this_sz = 0; - - for (uint32_t j = 0; j < mag; ++j) this_sz |= (*x++) << (j * 8); - sizes_[i] = this_sz; - } - } - return VPX_CODEC_OK; - } - - void SetEncoderConfigSvc(int number_spatial_layers, - int number_temporal_layers) { - cfg_.g_w = 1280; - cfg_.g_h = 720; - cfg_.ss_number_layers = number_spatial_layers; - cfg_.ts_number_layers = number_temporal_layers; - cfg_.g_timebase.num = 1; - cfg_.g_timebase.den = 30; - if (number_spatial_layers == 3) { - svc_params_.scaling_factor_num[0] = 1; - svc_params_.scaling_factor_den[0] = 4; - svc_params_.scaling_factor_num[1] = 2; - svc_params_.scaling_factor_den[1] = 4; - svc_params_.scaling_factor_num[2] = 4; - svc_params_.scaling_factor_den[2] = 4; - } else if (number_spatial_layers == 2) { - svc_params_.scaling_factor_num[0] = 1; - svc_params_.scaling_factor_den[0] = 2; - svc_params_.scaling_factor_num[1] = 2; - svc_params_.scaling_factor_den[1] = 2; - } else if (number_spatial_layers == 1) { - svc_params_.scaling_factor_num[0] = 1; - svc_params_.scaling_factor_den[0] = 1; - } - - for (int i = 0; i < VPX_MAX_LAYERS; ++i) { - svc_params_.max_quantizers[i] = 56; - svc_params_.min_quantizers[i] = 2; - svc_params_.speed_per_layer[i] = 7; - svc_params_.loopfilter_ctrl[i] = LOOPFILTER_ALL; - } - cfg_.rc_end_usage = VPX_CBR; - cfg_.g_lag_in_frames = 0; - cfg_.g_error_resilient = 0; - - if (number_temporal_layers == 3) { - cfg_.ts_rate_decimator[0] = 4; - cfg_.ts_rate_decimator[1] = 2; - cfg_.ts_rate_decimator[2] = 1; - cfg_.temporal_layering_mode = 3; - } else if (number_temporal_layers == 2) { - cfg_.ts_rate_decimator[0] = 2; - cfg_.ts_rate_decimator[1] = 1; - cfg_.temporal_layering_mode = 2; - } else if (number_temporal_layers == 1) { - cfg_.ts_rate_decimator[0] = 1; - cfg_.temporal_layering_mode = 0; - } - - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 600; - cfg_.rc_buf_sz = 1000; - cfg_.rc_min_quantizer = 2; - cfg_.rc_max_quantizer = 56; - cfg_.g_threads = 1; - cfg_.kf_max_dist = 9999; - cfg_.rc_overshoot_pct = 50; - cfg_.rc_undershoot_pct = 50; - cfg_.rc_dropframe_thresh = frame_drop_thresh_; - - cfg_.rc_target_bitrate = 0; - for (int sl = 0; sl < number_spatial_layers; sl++) { - int spatial_bitrate = 0; - if (number_spatial_layers <= 3) - spatial_bitrate = frame_drop_thresh_ > 0 ? kSpatialLayerBitrateLow[sl] - : kSpatialLayerBitrate[sl]; - for (int tl = 0; tl < number_temporal_layers; tl++) { - int layer = sl * number_temporal_layers + tl; - if (number_temporal_layers == 3) - cfg_.layer_target_bitrate[layer] = - kTemporalRateAllocation3Layer[tl] * spatial_bitrate / 100; - else if (number_temporal_layers == 2) - cfg_.layer_target_bitrate[layer] = - kTemporalRateAllocation2Layer[tl] * spatial_bitrate / 100; - else if (number_temporal_layers == 1) - cfg_.layer_target_bitrate[layer] = spatial_bitrate; - } - cfg_.rc_target_bitrate += spatial_bitrate; - } - - cfg_.kf_min_dist = key_interval_; - cfg_.kf_max_dist = key_interval_; - } - - void SetRCConfigSvc(int number_spatial_layers, int number_temporal_layers) { - rc_cfg_.width = 1280; - rc_cfg_.height = 720; - rc_cfg_.ss_number_layers = number_spatial_layers; - rc_cfg_.ts_number_layers = number_temporal_layers; - rc_cfg_.max_quantizer = 56; - rc_cfg_.min_quantizer = 2; - rc_cfg_.buf_initial_sz = 500; - rc_cfg_.buf_optimal_sz = 600; - rc_cfg_.buf_sz = 1000; - rc_cfg_.undershoot_pct = 50; - rc_cfg_.overshoot_pct = 50; - rc_cfg_.max_intra_bitrate_pct = 900; - rc_cfg_.framerate = 30.0; - rc_cfg_.rc_mode = VPX_CBR; - rc_cfg_.aq_mode = aq_mode_; - rc_cfg_.frame_drop_thresh = frame_drop_thresh_; - rc_cfg_.max_consec_drop = max_consec_drop_; - - if (number_spatial_layers == 3) { - rc_cfg_.scaling_factor_num[0] = 1; - rc_cfg_.scaling_factor_den[0] = 4; - rc_cfg_.scaling_factor_num[1] = 2; - rc_cfg_.scaling_factor_den[1] = 4; - rc_cfg_.scaling_factor_num[2] = 4; - rc_cfg_.scaling_factor_den[2] = 4; - } else if (number_spatial_layers == 2) { - rc_cfg_.scaling_factor_num[0] = 1; - rc_cfg_.scaling_factor_den[0] = 2; - rc_cfg_.scaling_factor_num[1] = 2; - rc_cfg_.scaling_factor_den[1] = 2; - } else if (number_spatial_layers == 1) { - rc_cfg_.scaling_factor_num[0] = 1; - rc_cfg_.scaling_factor_den[0] = 1; - } - - if (number_temporal_layers == 3) { - rc_cfg_.ts_rate_decimator[0] = 4; - rc_cfg_.ts_rate_decimator[1] = 2; - rc_cfg_.ts_rate_decimator[2] = 1; - } else if (number_temporal_layers == 2) { - rc_cfg_.ts_rate_decimator[0] = 2; - rc_cfg_.ts_rate_decimator[1] = 1; - } else if (number_temporal_layers == 1) { - rc_cfg_.ts_rate_decimator[0] = 1; - } - - rc_cfg_.target_bandwidth = 0; - for (int sl = 0; sl < number_spatial_layers; sl++) { - int spatial_bitrate = 0; - if (number_spatial_layers <= 3) - spatial_bitrate = frame_drop_thresh_ > 0 ? kSpatialLayerBitrateLow[sl] - : kSpatialLayerBitrate[sl]; - for (int tl = 0; tl < number_temporal_layers; tl++) { - int layer = sl * number_temporal_layers + tl; - if (number_temporal_layers == 3) - rc_cfg_.layer_target_bitrate[layer] = - kTemporalRateAllocation3Layer[tl] * spatial_bitrate / 100; - else if (number_temporal_layers == 2) - rc_cfg_.layer_target_bitrate[layer] = - kTemporalRateAllocation2Layer[tl] * spatial_bitrate / 100; - else if (number_temporal_layers == 1) - rc_cfg_.layer_target_bitrate[layer] = spatial_bitrate; - } - rc_cfg_.target_bandwidth += spatial_bitrate; - } - - for (int sl = 0; sl < rc_cfg_.ss_number_layers; ++sl) { - for (int tl = 0; tl < rc_cfg_.ts_number_layers; ++tl) { - const int i = sl * rc_cfg_.ts_number_layers + tl; - rc_cfg_.max_quantizers[i] = 56; - rc_cfg_.min_quantizers[i] = 2; - } - } - } - - int aq_mode_; - std::unique_ptr rc_api_; - libvpx::VP9RateControlRtcConfig rc_cfg_; - vpx_svc_extra_cfg_t svc_params_; - libvpx::VP9FrameParamsQpRTC frame_params_; - bool encoder_exit_; - int current_superframe_; - uint32_t sizes_[8]; - int key_interval_; - int dynamic_spatial_layers_; - bool inter_layer_pred_off_; - // ComputeQP() and PostEncodeUpdate() don't need to be sequential for KSVC. - bool parallel_spatial_layers_; - int frame_drop_thresh_; - int max_consec_drop_; - int num_drops_; -}; - -TEST_P(RcInterfaceTest, OneLayer) { RunOneLayer(); } - -TEST_P(RcInterfaceTest, OneLayerDropFramesCBR) { RunOneLayerDropFramesCBR(); } - -TEST_P(RcInterfaceTest, OneLayerScreen) { RunOneLayerScreen(); } - -TEST_P(RcInterfaceTest, OneLayerVBRPeriodicKey) { RunOneLayerVBRPeriodicKey(); } - -TEST_P(RcInterfaceSvcTest, Svc) { RunSvc(); } - -TEST_P(RcInterfaceSvcTest, SvcDropFramesCBR) { RunSvcDropFramesCBR(); } - -TEST_P(RcInterfaceSvcTest, SvcParallelSpatialLayers) { - RunSvcParallelSpatialLayers(); -} - -TEST_P(RcInterfaceSvcTest, SvcPeriodicKey) { RunSvcPeriodicKey(); } - -TEST_P(RcInterfaceSvcTest, SvcDynamicSpatial) { RunSvcDynamicSpatial(); } - -VP9_INSTANTIATE_TEST_SUITE(RcInterfaceTest, ::testing::Values(0, 3), - ::testing::Values(VPX_CBR, VPX_VBR)); -VP9_INSTANTIATE_TEST_SUITE(RcInterfaceSvcTest, ::testing::Values(0, 3), - ::testing::Values(true, false)); -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_roi_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_roi_test.cc deleted file mode 100644 index 9427796a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_roi_test.cc +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "gtest/gtest.h" - -#include "test/codec_factory.h" -#include "test/encode_test_driver.h" -#include "test/i420_video_source.h" -#include "test/util.h" -#include "test/video_source.h" -#include "test/y4m_video_source.h" -#include "test/yuv_video_source.h" -#include "vpx/vp8cx.h" -#include "vpx/vpx_encoder.h" - -#define MASK_WIDTH 40 -#define MASK_HEIGHT 30 -#define MASK_SIZE MASK_WIDTH *MASK_HEIGHT - -namespace { - -const int mask[MASK_SIZE] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0 -}; - -class RoiMaskBackgroundSkip : public ::libvpx_test::EncoderTest, - public ::testing::Test { - protected: - RoiMaskBackgroundSkip() : EncoderTest(&::libvpx_test::kVP9) {} - ~RoiMaskBackgroundSkip() override { free(roi_.roi_map); } - - void SetUp() override { - InitializeConfig(); - SetMode(::libvpx_test::kRealTime); - SetRoi(); - } - - void SetRoi() { - const int block_size = 8; - unsigned int i, j; - roi_.rows = (cfg_.g_h + block_size - 1) / block_size; - roi_.cols = (cfg_.g_w + block_size - 1) / block_size; - memset(&roi_.skip, 0, sizeof(roi_.skip)); - memset(&roi_.delta_q, 0, sizeof(roi_.delta_q)); - memset(&roi_.delta_lf, 0, sizeof(roi_.delta_lf)); - memset(roi_.ref_frame, -1, sizeof(roi_.ref_frame)); - roi_.ref_frame[1] = 1; - // Use segment 3 for skip. - roi_.skip[3] = 1; - roi_.roi_map = - (uint8_t *)calloc(roi_.rows * roi_.cols, sizeof(*roi_.roi_map)); - for (i = 0; i < roi_.rows; ++i) { - for (j = 0; j < roi_.cols; ++j) { - const int idx = i * roi_.cols + j; - if (mask[idx] == 1) roi_.roi_map[idx] = 3; - } - } - } - - void PreEncodeFrameHook(::libvpx_test::VideoSource *video, - ::libvpx_test::Encoder *encoder) override { - if (video->frame() == 0) { - encoder->Control(VP8E_SET_CPUUSED, 7); - encoder->Control(VP9E_SET_AQ_MODE, 3); - } - encoder->Control(VP9E_SET_ROI_MAP, &roi_); - } - - private: - vpx_roi_map_t roi_; -}; - -TEST_F(RoiMaskBackgroundSkip, RoiMaskNoMismatch) { - cfg_.rc_buf_initial_sz = 500; - cfg_.rc_buf_optimal_sz = 500; - cfg_.rc_buf_sz = 1000; - cfg_.rc_undershoot_pct = 20; - cfg_.rc_undershoot_pct = 20; - cfg_.rc_dropframe_thresh = 10; - cfg_.rc_min_quantizer = 0; - cfg_.rc_max_quantizer = 50; - cfg_.rc_end_usage = VPX_CBR; - cfg_.rc_target_bitrate = 200; - cfg_.g_lag_in_frames = 0; - cfg_.kf_max_dist = 9999; - - ::libvpx_test::I420VideoSource video("desktopqvga.320_240.yuv", 320, 240, 30, - 1, 0, 150); - ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); -} -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_scale_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_scale_test.cc deleted file mode 100644 index 15211a14..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_scale_test.cc +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "gtest/gtest.h" - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "./vpx_scale_rtcd.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/vpx_scale_test.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/vpx_timer.h" -#include "vpx_scale/yv12config.h" - -namespace libvpx_test { - -typedef void (*ScaleFrameFunc)(const YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst, - INTERP_FILTER filter_type, int phase_scaler); - -class ScaleTest : public VpxScaleBase, - public ::testing::TestWithParam { - public: - ~ScaleTest() override = default; - - protected: - void SetUp() override { scale_fn_ = GetParam(); } - - void ReferenceScaleFrame(INTERP_FILTER filter_type, int phase_scaler) { - vp9_scale_and_extend_frame_c(&img_, &ref_img_, filter_type, phase_scaler); - } - - void ScaleFrame(INTERP_FILTER filter_type, int phase_scaler) { - ASM_REGISTER_STATE_CHECK( - scale_fn_(&img_, &dst_img_, filter_type, phase_scaler)); - } - - void RunTest(INTERP_FILTER filter_type) { - static const int kNumSizesToTest = 22; - static const int kNumScaleFactorsToTest = 4; - static const int kSizesToTest[] = { 1, 2, 3, 4, 6, 8, 10, 12, - 14, 16, 18, 20, 22, 24, 26, 28, - 30, 32, 34, 68, 128, 134 }; - static const int kScaleFactors[] = { 1, 2, 3, 4 }; - for (int phase_scaler = 0; phase_scaler < 16; ++phase_scaler) { - for (int h = 0; h < kNumSizesToTest; ++h) { - const int src_height = kSizesToTest[h]; - for (int w = 0; w < kNumSizesToTest; ++w) { - const int src_width = kSizesToTest[w]; - for (int sf_up_idx = 0; sf_up_idx < kNumScaleFactorsToTest; - ++sf_up_idx) { - const int sf_up = kScaleFactors[sf_up_idx]; - for (int sf_down_idx = 0; sf_down_idx < kNumScaleFactorsToTest; - ++sf_down_idx) { - const int sf_down = kScaleFactors[sf_down_idx]; - const int dst_width = src_width * sf_up / sf_down; - const int dst_height = src_height * sf_up / sf_down; - if (sf_up == sf_down && sf_up != 1) { - continue; - } - // I420 frame width and height must be even. - if (!dst_width || !dst_height || dst_width & 1 || - dst_height & 1) { - continue; - } - // vpx_convolve8_c() has restriction on the step which cannot - // exceed 64 (ratio 1 to 4). - if (src_width > 4 * dst_width || src_height > 4 * dst_height) { - continue; - } - ASSERT_NO_FATAL_FAILURE(ResetScaleImages(src_width, src_height, - dst_width, dst_height)); - ReferenceScaleFrame(filter_type, phase_scaler); - ScaleFrame(filter_type, phase_scaler); - if (memcmp(dst_img_.buffer_alloc, ref_img_.buffer_alloc, - ref_img_.frame_size)) { - printf( - "filter_type = %d, phase_scaler = %d, src_width = %4d, " - "src_height = %4d, dst_width = %4d, dst_height = %4d, " - "scale factor = %d:%d\n", - filter_type, phase_scaler, src_width, src_height, dst_width, - dst_height, sf_down, sf_up); - PrintDiff(); - } - CompareImages(dst_img_); - DeallocScaleImages(); - } - } - } - } - } - } - - void PrintDiffComponent(const uint8_t *const ref, const uint8_t *const opt, - const int stride, const int width, const int height, - const int plane_idx) const { - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - if (ref[y * stride + x] != opt[y * stride + x]) { - printf("Plane %d pixel[%d][%d] diff:%6d (ref),%6d (opt)\n", plane_idx, - y, x, ref[y * stride + x], opt[y * stride + x]); - break; - } - } - } - } - - void PrintDiff() const { - assert(ref_img_.y_stride == dst_img_.y_stride); - assert(ref_img_.y_width == dst_img_.y_width); - assert(ref_img_.y_height == dst_img_.y_height); - assert(ref_img_.uv_stride == dst_img_.uv_stride); - assert(ref_img_.uv_width == dst_img_.uv_width); - assert(ref_img_.uv_height == dst_img_.uv_height); - - if (memcmp(dst_img_.buffer_alloc, ref_img_.buffer_alloc, - ref_img_.frame_size)) { - PrintDiffComponent(ref_img_.y_buffer, dst_img_.y_buffer, - ref_img_.y_stride, ref_img_.y_width, ref_img_.y_height, - 0); - PrintDiffComponent(ref_img_.u_buffer, dst_img_.u_buffer, - ref_img_.uv_stride, ref_img_.uv_width, - ref_img_.uv_height, 1); - PrintDiffComponent(ref_img_.v_buffer, dst_img_.v_buffer, - ref_img_.uv_stride, ref_img_.uv_width, - ref_img_.uv_height, 2); - } - } - - ScaleFrameFunc scale_fn_; -}; - -TEST_P(ScaleTest, ScaleFrame_EightTap) { RunTest(EIGHTTAP); } -TEST_P(ScaleTest, ScaleFrame_EightTapSmooth) { RunTest(EIGHTTAP_SMOOTH); } -TEST_P(ScaleTest, ScaleFrame_EightTapSharp) { RunTest(EIGHTTAP_SHARP); } -TEST_P(ScaleTest, ScaleFrame_Bilinear) { RunTest(BILINEAR); } - -TEST_P(ScaleTest, DISABLED_Speed) { - static const int kCountSpeedTestBlock = 100; - static const int kNumScaleFactorsToTest = 4; - static const int kScaleFactors[] = { 1, 2, 3, 4 }; - const int src_width = 1280; - const int src_height = 720; - for (INTERP_FILTER filter_type = 2; filter_type < 4; ++filter_type) { - for (int phase_scaler = 0; phase_scaler < 2; ++phase_scaler) { - for (int sf_up_idx = 0; sf_up_idx < kNumScaleFactorsToTest; ++sf_up_idx) { - const int sf_up = kScaleFactors[sf_up_idx]; - for (int sf_down_idx = 0; sf_down_idx < kNumScaleFactorsToTest; - ++sf_down_idx) { - const int sf_down = kScaleFactors[sf_down_idx]; - const int dst_width = src_width * sf_up / sf_down; - const int dst_height = src_height * sf_up / sf_down; - if (sf_up == sf_down && sf_up != 1) { - continue; - } - // I420 frame width and height must be even. - if (dst_width & 1 || dst_height & 1) { - continue; - } - ASSERT_NO_FATAL_FAILURE( - ResetScaleImages(src_width, src_height, dst_width, dst_height)); - ASM_REGISTER_STATE_CHECK( - ReferenceScaleFrame(filter_type, phase_scaler)); - - vpx_usec_timer timer; - vpx_usec_timer_start(&timer); - for (int i = 0; i < kCountSpeedTestBlock; ++i) { - ScaleFrame(filter_type, phase_scaler); - } - libvpx_test::ClearSystemState(); - vpx_usec_timer_mark(&timer); - const int elapsed_time = - static_cast(vpx_usec_timer_elapsed(&timer) / 1000); - CompareImages(dst_img_); - DeallocScaleImages(); - - printf( - "filter_type = %d, phase_scaler = %d, src_width = %4d, " - "src_height = %4d, dst_width = %4d, dst_height = %4d, " - "scale factor = %d:%d, scale time: %5d ms\n", - filter_type, phase_scaler, src_width, src_height, dst_width, - dst_height, sf_down, sf_up, elapsed_time); - } - } - } - } -} - -INSTANTIATE_TEST_SUITE_P(C, ScaleTest, - ::testing::Values(vp9_scale_and_extend_frame_c)); - -#if HAVE_SSSE3 -INSTANTIATE_TEST_SUITE_P(SSSE3, ScaleTest, - ::testing::Values(vp9_scale_and_extend_frame_ssse3)); -#endif // HAVE_SSSE3 - -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P(NEON, ScaleTest, - ::testing::Values(vp9_scale_and_extend_frame_neon)); -#endif // HAVE_NEON - -} // namespace libvpx_test diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_skip_loopfilter_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_skip_loopfilter_test.cc deleted file mode 100644 index c080a2ca..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_skip_loopfilter_test.cc +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "test/codec_factory.h" -#include "test/decode_test_driver.h" -#include "test/md5_helper.h" -#include "test/util.h" -#include "test/webm_video_source.h" - -namespace { - -const char kVp9TestFile[] = "vp90-2-08-tile_1x8_frame_parallel.webm"; -const char kVp9Md5File[] = "vp90-2-08-tile_1x8_frame_parallel.webm.md5"; - -// Class for testing shutting off the loop filter. -class SkipLoopFilterTest { - public: - SkipLoopFilterTest() - : video_(nullptr), decoder_(nullptr), md5_file_(nullptr) {} - - ~SkipLoopFilterTest() { - if (md5_file_ != nullptr) fclose(md5_file_); - delete decoder_; - delete video_; - } - - // If |threads| > 0 then set the decoder with that number of threads. - bool Init(int num_threads) { - expected_md5_[0] = '\0'; - junk_[0] = '\0'; - video_ = new libvpx_test::WebMVideoSource(kVp9TestFile); - if (video_ == nullptr) { - EXPECT_NE(video_, nullptr); - return false; - } - video_->Init(); - video_->Begin(); - - vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t(); - if (num_threads > 0) cfg.threads = num_threads; - decoder_ = new libvpx_test::VP9Decoder(cfg, 0); - if (decoder_ == nullptr) { - EXPECT_NE(decoder_, nullptr); - return false; - } - - OpenMd5File(kVp9Md5File); - return !::testing::Test::HasFailure(); - } - - // Set the VP9 skipLoopFilter control value. - void SetSkipLoopFilter(int value, vpx_codec_err_t expected_value) { - ASSERT_NE(decoder_, nullptr); - decoder_->Control(VP9_SET_SKIP_LOOP_FILTER, value, expected_value); - } - - vpx_codec_err_t DecodeOneFrame() { - const vpx_codec_err_t res = - decoder_->DecodeFrame(video_->cxdata(), video_->frame_size()); - if (res == VPX_CODEC_OK) { - ReadMd5(); - video_->Next(); - } - return res; - } - - vpx_codec_err_t DecodeRemainingFrames() { - for (; video_->cxdata() != nullptr; video_->Next()) { - const vpx_codec_err_t res = - decoder_->DecodeFrame(video_->cxdata(), video_->frame_size()); - if (res != VPX_CODEC_OK) return res; - ReadMd5(); - } - return VPX_CODEC_OK; - } - - // Checks if MD5 matches or doesn't. - void CheckMd5(bool matches) { - libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData(); - const vpx_image_t *img = dec_iter.Next(); - CheckMd5Vpx(*img, matches); - } - - private: - // TODO(fgalligan): Move the MD5 testing code into another class. - void OpenMd5File(const std::string &md5_file_name) { - md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name); - ASSERT_NE(md5_file_, nullptr) - << "MD5 file open failed. Filename: " << md5_file_name; - } - - // Reads the next line of the MD5 file. - void ReadMd5() { - ASSERT_NE(md5_file_, nullptr); - const int res = fscanf(md5_file_, "%s %s", expected_md5_, junk_); - ASSERT_NE(EOF, res) << "Read md5 data failed"; - expected_md5_[32] = '\0'; - } - - // Checks if the last read MD5 matches |img| or doesn't. - void CheckMd5Vpx(const vpx_image_t &img, bool matches) { - ::libvpx_test::MD5 md5_res; - md5_res.Add(&img); - const char *const actual_md5 = md5_res.Get(); - - // Check MD5. - if (matches) - ASSERT_STREQ(expected_md5_, actual_md5) << "MD5 checksums don't match"; - else - ASSERT_STRNE(expected_md5_, actual_md5) << "MD5 checksums match"; - } - - libvpx_test::WebMVideoSource *video_; - libvpx_test::VP9Decoder *decoder_; - FILE *md5_file_; - char expected_md5_[33]; - char junk_[128]; -}; - -TEST(SkipLoopFilterTest, ShutOffLoopFilter) { - const int non_zero_value = 1; - const int num_threads = 0; - SkipLoopFilterTest skip_loop_filter; - ASSERT_TRUE(skip_loop_filter.Init(num_threads)); - skip_loop_filter.SetSkipLoopFilter(non_zero_value, VPX_CODEC_OK); - ASSERT_EQ(VPX_CODEC_OK, skip_loop_filter.DecodeRemainingFrames()); - skip_loop_filter.CheckMd5(false); -} - -TEST(SkipLoopFilterTest, ShutOffLoopFilterSingleThread) { - const int non_zero_value = 1; - const int num_threads = 1; - SkipLoopFilterTest skip_loop_filter; - ASSERT_TRUE(skip_loop_filter.Init(num_threads)); - skip_loop_filter.SetSkipLoopFilter(non_zero_value, VPX_CODEC_OK); - ASSERT_EQ(VPX_CODEC_OK, skip_loop_filter.DecodeRemainingFrames()); - skip_loop_filter.CheckMd5(false); -} - -TEST(SkipLoopFilterTest, ShutOffLoopFilter8Threads) { - const int non_zero_value = 1; - const int num_threads = 8; - SkipLoopFilterTest skip_loop_filter; - ASSERT_TRUE(skip_loop_filter.Init(num_threads)); - skip_loop_filter.SetSkipLoopFilter(non_zero_value, VPX_CODEC_OK); - ASSERT_EQ(VPX_CODEC_OK, skip_loop_filter.DecodeRemainingFrames()); - skip_loop_filter.CheckMd5(false); -} - -TEST(SkipLoopFilterTest, WithLoopFilter) { - const int non_zero_value = 1; - const int num_threads = 0; - SkipLoopFilterTest skip_loop_filter; - ASSERT_TRUE(skip_loop_filter.Init(num_threads)); - skip_loop_filter.SetSkipLoopFilter(non_zero_value, VPX_CODEC_OK); - skip_loop_filter.SetSkipLoopFilter(0, VPX_CODEC_OK); - ASSERT_EQ(VPX_CODEC_OK, skip_loop_filter.DecodeRemainingFrames()); - skip_loop_filter.CheckMd5(true); -} - -TEST(SkipLoopFilterTest, ToggleLoopFilter) { - const int num_threads = 0; - SkipLoopFilterTest skip_loop_filter; - ASSERT_TRUE(skip_loop_filter.Init(num_threads)); - - for (int i = 0; i < 10; ++i) { - skip_loop_filter.SetSkipLoopFilter(i % 2, VPX_CODEC_OK); - ASSERT_EQ(VPX_CODEC_OK, skip_loop_filter.DecodeOneFrame()); - } - ASSERT_EQ(VPX_CODEC_OK, skip_loop_filter.DecodeRemainingFrames()); - skip_loop_filter.CheckMd5(false); -} - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_subtract_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_subtract_test.cc deleted file mode 100644 index 41775977..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_subtract_test.cc +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include - -#include "gtest/gtest.h" - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "test/acm_random.h" -#include "test/bench.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/util.h" -#include "vp9/common/vp9_blockd.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/vpx_timer.h" - -typedef void (*SubtractFunc)(int rows, int cols, int16_t *diff_ptr, - ptrdiff_t diff_stride, const uint8_t *src_ptr, - ptrdiff_t src_stride, const uint8_t *pred_ptr, - ptrdiff_t pred_stride); - -namespace vp9 { - -class VP9SubtractBlockTest : public AbstractBench, - public ::testing::TestWithParam { - public: - void TearDown() override { libvpx_test::ClearSystemState(); } - - protected: - void Run() override { - GetParam()(block_height_, block_width_, diff_, block_width_, src_, - block_width_, pred_, block_width_); - } - - void SetupBlocks(BLOCK_SIZE bsize) { - block_width_ = 4 * num_4x4_blocks_wide_lookup[bsize]; - block_height_ = 4 * num_4x4_blocks_high_lookup[bsize]; - diff_ = reinterpret_cast( - vpx_memalign(16, sizeof(*diff_) * block_width_ * block_height_ * 2)); - pred_ = reinterpret_cast( - vpx_memalign(16, block_width_ * block_height_ * 2)); - src_ = reinterpret_cast( - vpx_memalign(16, block_width_ * block_height_ * 2)); - } - - int block_width_; - int block_height_; - int16_t *diff_; - uint8_t *pred_; - uint8_t *src_; -}; - -using libvpx_test::ACMRandom; - -TEST_P(VP9SubtractBlockTest, DISABLED_Speed) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - - for (BLOCK_SIZE bsize = BLOCK_4X4; bsize < BLOCK_SIZES; - bsize = static_cast(static_cast(bsize) + 1)) { - SetupBlocks(bsize); - - RunNTimes(100000000 / (block_height_ * block_width_)); - char block_size[16]; - snprintf(block_size, sizeof(block_size), "%dx%d", block_height_, - block_width_); - char title[100]; - snprintf(title, sizeof(title), "%8s ", block_size); - PrintMedian(title); - - vpx_free(diff_); - vpx_free(pred_); - vpx_free(src_); - } -} - -TEST_P(VP9SubtractBlockTest, SimpleSubtract) { - ACMRandom rnd(ACMRandom::DeterministicSeed()); - - for (BLOCK_SIZE bsize = BLOCK_4X4; bsize < BLOCK_SIZES; - bsize = static_cast(static_cast(bsize) + 1)) { - SetupBlocks(bsize); - - for (int n = 0; n < 100; n++) { - for (int r = 0; r < block_height_; ++r) { - for (int c = 0; c < block_width_ * 2; ++c) { - src_[r * block_width_ * 2 + c] = rnd.Rand8(); - pred_[r * block_width_ * 2 + c] = rnd.Rand8(); - } - } - - GetParam()(block_height_, block_width_, diff_, block_width_, src_, - block_width_, pred_, block_width_); - - for (int r = 0; r < block_height_; ++r) { - for (int c = 0; c < block_width_; ++c) { - EXPECT_EQ(diff_[r * block_width_ + c], - (src_[r * block_width_ + c] - pred_[r * block_width_ + c])) - << "r = " << r << ", c = " << c - << ", bs = " << static_cast(bsize); - } - } - - GetParam()(block_height_, block_width_, diff_, block_width_ * 2, src_, - block_width_ * 2, pred_, block_width_ * 2); - - for (int r = 0; r < block_height_; ++r) { - for (int c = 0; c < block_width_; ++c) { - EXPECT_EQ(diff_[r * block_width_ * 2 + c], - (src_[r * block_width_ * 2 + c] - - pred_[r * block_width_ * 2 + c])) - << "r = " << r << ", c = " << c - << ", bs = " << static_cast(bsize); - } - } - } - vpx_free(diff_); - vpx_free(pred_); - vpx_free(src_); - } -} - -INSTANTIATE_TEST_SUITE_P(C, VP9SubtractBlockTest, - ::testing::Values(vpx_subtract_block_c)); - -#if HAVE_SSE2 -INSTANTIATE_TEST_SUITE_P(SSE2, VP9SubtractBlockTest, - ::testing::Values(vpx_subtract_block_sse2)); -#endif -#if HAVE_AVX2 -INSTANTIATE_TEST_SUITE_P(AVX2, VP9SubtractBlockTest, - ::testing::Values(vpx_subtract_block_avx2)); -#endif -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P(NEON, VP9SubtractBlockTest, - ::testing::Values(vpx_subtract_block_neon)); -#endif -#if HAVE_MSA -INSTANTIATE_TEST_SUITE_P(MSA, VP9SubtractBlockTest, - ::testing::Values(vpx_subtract_block_msa)); -#endif - -#if HAVE_MMI -INSTANTIATE_TEST_SUITE_P(MMI, VP9SubtractBlockTest, - ::testing::Values(vpx_subtract_block_mmi)); -#endif - -#if HAVE_VSX -INSTANTIATE_TEST_SUITE_P(VSX, VP9SubtractBlockTest, - ::testing::Values(vpx_subtract_block_vsx)); -#endif - -#if HAVE_LSX -INSTANTIATE_TEST_SUITE_P(LSX, VP9SubtractBlockTest, - ::testing::Values(vpx_subtract_block_lsx)); -#endif - -#if CONFIG_VP9_HIGHBITDEPTH - -typedef void (*HBDSubtractFunc)(int rows, int cols, int16_t *diff_ptr, - ptrdiff_t diff_stride, const uint8_t *src_ptr, - ptrdiff_t src_stride, const uint8_t *pred_ptr, - ptrdiff_t pred_stride, int bd); - -// -using Params = std::tuple; - -class VPXHBDSubtractBlockTest : public ::testing::TestWithParam { - public: - void SetUp() override { - block_width_ = 4 * num_4x4_blocks_wide_lookup[GET_PARAM(0)]; - block_height_ = 4 * num_4x4_blocks_high_lookup[GET_PARAM(0)]; - bit_depth_ = static_cast(GET_PARAM(1)); - func_ = GET_PARAM(2); - ref_func_ = GET_PARAM(3); - - rnd_.Reset(ACMRandom::DeterministicSeed()); - - constexpr size_t kMaxWidth = 128; - constexpr size_t kMaxBlockSize = kMaxWidth * kMaxWidth; - src_ = CONVERT_TO_BYTEPTR(reinterpret_cast( - vpx_memalign(16, kMaxBlockSize * sizeof(uint16_t)))); - ASSERT_NE(src_, nullptr); - pred_ = CONVERT_TO_BYTEPTR(reinterpret_cast( - vpx_memalign(16, kMaxBlockSize * sizeof(uint16_t)))); - ASSERT_NE(pred_, nullptr); - diff_ = reinterpret_cast( - vpx_memalign(16, kMaxBlockSize * sizeof(int16_t))); - ASSERT_NE(diff_, nullptr); - } - - void TearDown() override { - vpx_free(CONVERT_TO_SHORTPTR(src_)); - vpx_free(CONVERT_TO_SHORTPTR(pred_)); - vpx_free(diff_); - } - - protected: - void CheckResult(); - void RunForSpeed(); - - private: - ACMRandom rnd_; - int block_height_; - int block_width_; - vpx_bit_depth_t bit_depth_; - HBDSubtractFunc func_; - HBDSubtractFunc ref_func_; - uint8_t *src_; - uint8_t *pred_; - int16_t *diff_; -}; - -void VPXHBDSubtractBlockTest::CheckResult() { - constexpr int kTestNum = 100; - constexpr int kMaxWidth = 128; - constexpr int kMaxBlockSize = kMaxWidth * kMaxWidth; - const int mask = (1 << bit_depth_) - 1; - for (int i = 0; i < kTestNum; ++i) { - for (int j = 0; j < kMaxBlockSize; ++j) { - CONVERT_TO_SHORTPTR(src_)[j] = rnd_.Rand16() & mask; - CONVERT_TO_SHORTPTR(pred_)[j] = rnd_.Rand16() & mask; - } - - func_(block_height_, block_width_, diff_, block_width_, src_, block_width_, - pred_, block_width_, bit_depth_); - - for (int r = 0; r < block_height_; ++r) { - for (int c = 0; c < block_width_; ++c) { - EXPECT_EQ(diff_[r * block_width_ + c], - (CONVERT_TO_SHORTPTR(src_)[r * block_width_ + c] - - CONVERT_TO_SHORTPTR(pred_)[r * block_width_ + c])) - << "r = " << r << ", c = " << c << ", test: " << i; - } - } - } -} - -TEST_P(VPXHBDSubtractBlockTest, CheckResult) { CheckResult(); } - -void VPXHBDSubtractBlockTest::RunForSpeed() { - constexpr int kTestNum = 200000; - constexpr int kMaxWidth = 128; - constexpr int kMaxBlockSize = kMaxWidth * kMaxWidth; - const int mask = (1 << bit_depth_) - 1; - - if (ref_func_ == func_) GTEST_SKIP(); - - for (int j = 0; j < kMaxBlockSize; ++j) { - CONVERT_TO_SHORTPTR(src_)[j] = rnd_.Rand16() & mask; - CONVERT_TO_SHORTPTR(pred_)[j] = rnd_.Rand16() & mask; - } - - vpx_usec_timer ref_timer; - vpx_usec_timer_start(&ref_timer); - for (int i = 0; i < kTestNum; ++i) { - ref_func_(block_height_, block_width_, diff_, block_width_, src_, - block_width_, pred_, block_width_, bit_depth_); - } - vpx_usec_timer_mark(&ref_timer); - const int64_t ref_elapsed_time = vpx_usec_timer_elapsed(&ref_timer); - - for (int j = 0; j < kMaxBlockSize; ++j) { - CONVERT_TO_SHORTPTR(src_)[j] = rnd_.Rand16() & mask; - CONVERT_TO_SHORTPTR(pred_)[j] = rnd_.Rand16() & mask; - } - - vpx_usec_timer timer; - vpx_usec_timer_start(&timer); - for (int i = 0; i < kTestNum; ++i) { - func_(block_height_, block_width_, diff_, block_width_, src_, block_width_, - pred_, block_width_, bit_depth_); - } - vpx_usec_timer_mark(&timer); - const int64_t elapsed_time = vpx_usec_timer_elapsed(&timer); - - printf( - "[%dx%d]: " - "ref_time=%6" PRId64 " \t simd_time=%6" PRId64 - " \t " - "gain=%f \n", - block_width_, block_height_, ref_elapsed_time, elapsed_time, - static_cast(ref_elapsed_time) / - static_cast(elapsed_time)); -} - -TEST_P(VPXHBDSubtractBlockTest, DISABLED_Speed) { RunForSpeed(); } - -const BLOCK_SIZE kValidBlockSize[] = { BLOCK_4X4, BLOCK_4X8, BLOCK_8X4, - BLOCK_8X8, BLOCK_8X16, BLOCK_16X8, - BLOCK_16X16, BLOCK_16X32, BLOCK_32X16, - BLOCK_32X32, BLOCK_32X64, BLOCK_64X32, - BLOCK_64X64 }; - -INSTANTIATE_TEST_SUITE_P( - C, VPXHBDSubtractBlockTest, - ::testing::Combine(::testing::ValuesIn(kValidBlockSize), - ::testing::Values(12), - ::testing::Values(&vpx_highbd_subtract_block_c), - ::testing::Values(&vpx_highbd_subtract_block_c))); - -#if HAVE_AVX2 -INSTANTIATE_TEST_SUITE_P( - AVX2, VPXHBDSubtractBlockTest, - ::testing::Combine(::testing::ValuesIn(kValidBlockSize), - ::testing::Values(12), - ::testing::Values(&vpx_highbd_subtract_block_avx2), - ::testing::Values(&vpx_highbd_subtract_block_c))); -#endif // HAVE_AVX2 - -#endif // CONFIG_VP9_HIGHBITDEPTH -} // namespace vp9 diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vp9_thread_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vp9_thread_test.cc deleted file mode 100644 index 387bb405..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vp9_thread_test.cc +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "gtest/gtest.h" -#include "./vpx_config.h" -#include "test/codec_factory.h" -#include "test/decode_test_driver.h" -#include "test/md5_helper.h" -#if CONFIG_WEBM_IO -#include "test/webm_video_source.h" -#endif -#include "vpx_util/vpx_thread.h" - -namespace { - -using std::string; - -class VPxWorkerThreadTest : public ::testing::TestWithParam { - protected: - ~VPxWorkerThreadTest() override = default; - void SetUp() override { vpx_get_worker_interface()->init(&worker_); } - - void TearDown() override { vpx_get_worker_interface()->end(&worker_); } - - void Run(VPxWorker *worker) { - const bool synchronous = GetParam(); - if (synchronous) { - vpx_get_worker_interface()->execute(worker); - } else { - vpx_get_worker_interface()->launch(worker); - } - } - - VPxWorker worker_; -}; - -int ThreadHook(void *data, void *return_value) { - int *const hook_data = reinterpret_cast(data); - *hook_data = 5; - return *reinterpret_cast(return_value); -} - -TEST_P(VPxWorkerThreadTest, HookSuccess) { - // should be a no-op. - EXPECT_NE(vpx_get_worker_interface()->sync(&worker_), 0); - - for (int i = 0; i < 2; ++i) { - EXPECT_NE(vpx_get_worker_interface()->reset(&worker_), 0); - - int hook_data = 0; - int return_value = 1; // return successfully from the hook - worker_.hook = ThreadHook; - worker_.data1 = &hook_data; - worker_.data2 = &return_value; - - Run(&worker_); - EXPECT_NE(vpx_get_worker_interface()->sync(&worker_), 0); - EXPECT_FALSE(worker_.had_error); - EXPECT_EQ(5, hook_data); - - // should be a no-op. - EXPECT_NE(vpx_get_worker_interface()->sync(&worker_), 0); - } -} - -TEST_P(VPxWorkerThreadTest, HookFailure) { - EXPECT_NE(vpx_get_worker_interface()->reset(&worker_), 0); - - int hook_data = 0; - int return_value = 0; // return failure from the hook - worker_.hook = ThreadHook; - worker_.data1 = &hook_data; - worker_.data2 = &return_value; - - Run(&worker_); - EXPECT_FALSE(vpx_get_worker_interface()->sync(&worker_)); - EXPECT_EQ(1, worker_.had_error); - - // Ensure _reset() clears the error and _launch() can be called again. - return_value = 1; - EXPECT_NE(vpx_get_worker_interface()->reset(&worker_), 0); - EXPECT_FALSE(worker_.had_error); - vpx_get_worker_interface()->launch(&worker_); - EXPECT_NE(vpx_get_worker_interface()->sync(&worker_), 0); - EXPECT_FALSE(worker_.had_error); -} - -TEST_P(VPxWorkerThreadTest, EndWithoutSync) { - // Create a large number of threads to increase the chances of detecting a - // race. Doing more work in the hook is no guarantee as any race would occur - // post hook execution in the main thread loop driver. - static const int kNumWorkers = 64; - VPxWorker workers[kNumWorkers]; - int hook_data[kNumWorkers]; - int return_value[kNumWorkers]; - - for (int n = 0; n < kNumWorkers; ++n) { - vpx_get_worker_interface()->init(&workers[n]); - return_value[n] = 1; // return successfully from the hook - workers[n].hook = ThreadHook; - workers[n].data1 = &hook_data[n]; - workers[n].data2 = &return_value[n]; - } - - for (int i = 0; i < 2; ++i) { - for (int n = 0; n < kNumWorkers; ++n) { - EXPECT_NE(vpx_get_worker_interface()->reset(&workers[n]), 0); - hook_data[n] = 0; - } - - for (int n = 0; n < kNumWorkers; ++n) { - Run(&workers[n]); - } - - for (int n = kNumWorkers - 1; n >= 0; --n) { - vpx_get_worker_interface()->end(&workers[n]); - } - } -} - -TEST(VPxWorkerThreadTest, TestInterfaceAPI) { - EXPECT_EQ(0, vpx_set_worker_interface(nullptr)); - EXPECT_NE(vpx_get_worker_interface(), nullptr); - for (int i = 0; i < 6; ++i) { - VPxWorkerInterface winterface = *vpx_get_worker_interface(); - switch (i) { - default: - case 0: winterface.init = nullptr; break; - case 1: winterface.reset = nullptr; break; - case 2: winterface.sync = nullptr; break; - case 3: winterface.launch = nullptr; break; - case 4: winterface.execute = nullptr; break; - case 5: winterface.end = nullptr; break; - } - EXPECT_EQ(0, vpx_set_worker_interface(&winterface)); - } -} - -// ----------------------------------------------------------------------------- -// Multi-threaded decode tests -#if CONFIG_WEBM_IO -// Decodes |filename| with |num_threads|. Returns the md5 of the decoded frames. -string DecodeFile(const string &filename, int num_threads) { - libvpx_test::WebMVideoSource video(filename); - video.Init(); - - vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t(); - cfg.threads = num_threads; - libvpx_test::VP9Decoder decoder(cfg, 0); - - libvpx_test::MD5 md5; - for (video.Begin(); video.cxdata(); video.Next()) { - const vpx_codec_err_t res = - decoder.DecodeFrame(video.cxdata(), video.frame_size()); - if (res != VPX_CODEC_OK) { - EXPECT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError(); - break; - } - - libvpx_test::DxDataIterator dec_iter = decoder.GetDxData(); - const vpx_image_t *img = nullptr; - - // Get decompressed data - while ((img = dec_iter.Next())) { - md5.Add(img); - } - } - return string(md5.Get()); -} - -// Trivial serialized thread worker interface implementation. -// Note any worker that requires synchronization between other workers will -// hang. -namespace impl { -namespace { - -void Init(VPxWorker *const worker) { memset(worker, 0, sizeof(*worker)); } -int Reset(VPxWorker *const /*worker*/) { return 1; } -int Sync(VPxWorker *const worker) { return !worker->had_error; } - -void Execute(VPxWorker *const worker) { - worker->had_error |= !worker->hook(worker->data1, worker->data2); -} - -void Launch(VPxWorker *const worker) { Execute(worker); } -void End(VPxWorker *const /*worker*/) {} - -} // namespace -} // namespace impl - -TEST(VPxWorkerThreadTest, TestSerialInterface) { - static const VPxWorkerInterface serial_interface = { - impl::Init, impl::Reset, impl::Sync, impl::Launch, impl::Execute, impl::End - }; - static const char expected_md5[] = "b35a1b707b28e82be025d960aba039bc"; - static const char filename[] = "vp90-2-03-size-226x226.webm"; - VPxWorkerInterface default_interface = *vpx_get_worker_interface(); - - EXPECT_NE(vpx_set_worker_interface(&serial_interface), 0); - EXPECT_EQ(expected_md5, DecodeFile(filename, 2)); - - // Reset the interface. - EXPECT_NE(vpx_set_worker_interface(&default_interface), 0); - EXPECT_EQ(expected_md5, DecodeFile(filename, 2)); -} - -struct FileParam { - const char *name; - const char *expected_md5; - friend std::ostream &operator<<(std::ostream &os, const FileParam ¶m) { - return os << "file name: " << param.name - << " digest: " << param.expected_md5; - } -}; - -class VP9DecodeMultiThreadedTest : public ::testing::TestWithParam { -}; - -TEST_P(VP9DecodeMultiThreadedTest, Decode) { - for (int t = 1; t <= 8; ++t) { - EXPECT_EQ(GetParam().expected_md5, DecodeFile(GetParam().name, t)) - << "threads = " << t; - } -} - -const FileParam kNoTilesNonFrameParallelFiles[] = { - { "vp90-2-03-size-226x226.webm", "b35a1b707b28e82be025d960aba039bc" } -}; - -const FileParam kFrameParallelFiles[] = { - { "vp90-2-08-tile_1x2_frame_parallel.webm", - "68ede6abd66bae0a2edf2eb9232241b6" }, - { "vp90-2-08-tile_1x4_frame_parallel.webm", - "368ebc6ebf3a5e478d85b2c3149b2848" }, - { "vp90-2-08-tile_1x8_frame_parallel.webm", - "17e439da2388aff3a0f69cb22579c6c1" }, -}; - -const FileParam kFrameParallelResizeFiles[] = { - { "vp90-2-14-resize-fp-tiles-1-16.webm", "0cd5e632c326297e975f38949c31ea94" }, - { "vp90-2-14-resize-fp-tiles-1-2-4-8-16.webm", - "5c78a96a42e7f4a4f6b2edcdb791e44c" }, - { "vp90-2-14-resize-fp-tiles-1-2.webm", "e030450ae85c3277be2a418769df98e2" }, - { "vp90-2-14-resize-fp-tiles-1-4.webm", "312eed4e2b64eb7a4e7f18916606a430" }, - { "vp90-2-14-resize-fp-tiles-16-1.webm", "1755c16d8af16a9cb3fe7338d90abe52" }, - { "vp90-2-14-resize-fp-tiles-16-2.webm", "500300592d3fcb6f12fab25e48aaf4df" }, - { "vp90-2-14-resize-fp-tiles-16-4.webm", "47c48379fa6331215d91c67648e1af6e" }, - { "vp90-2-14-resize-fp-tiles-16-8-4-2-1.webm", - "eecf17290739bc708506fa4827665989" }, - { "vp90-2-14-resize-fp-tiles-16-8.webm", "29b6bb54e4c26b5ca85d5de5fed94e76" }, - { "vp90-2-14-resize-fp-tiles-1-8.webm", "1b6f175e08cd82cf84bb800ac6d1caa3" }, - { "vp90-2-14-resize-fp-tiles-2-16.webm", "ca3b03e4197995d8d5444ede7a6c0804" }, - { "vp90-2-14-resize-fp-tiles-2-1.webm", "99aec065369d70bbb78ccdff65afed3f" }, - { "vp90-2-14-resize-fp-tiles-2-4.webm", "22d0ebdb49b87d2920a85aea32e1afd5" }, - { "vp90-2-14-resize-fp-tiles-2-8.webm", "c2115cf051c62e0f7db1d4a783831541" }, - { "vp90-2-14-resize-fp-tiles-4-16.webm", "c690d7e1719b31367564cac0af0939cb" }, - { "vp90-2-14-resize-fp-tiles-4-1.webm", "a926020b2cc3e15ad4cc271853a0ff26" }, - { "vp90-2-14-resize-fp-tiles-4-2.webm", "42699063d9e581f1993d0cf890c2be78" }, - { "vp90-2-14-resize-fp-tiles-4-8.webm", "7f76d96036382f45121e3d5aa6f8ec52" }, - { "vp90-2-14-resize-fp-tiles-8-16.webm", "76a43fcdd7e658542913ea43216ec55d" }, - { "vp90-2-14-resize-fp-tiles-8-1.webm", "8e3fbe89486ca60a59299dea9da91378" }, - { "vp90-2-14-resize-fp-tiles-8-2.webm", "ae96f21f21b6370cc0125621b441fc52" }, - { "vp90-2-14-resize-fp-tiles-8-4.webm", "3eb4f24f10640d42218f7fd7b9fd30d4" }, -}; - -const FileParam kNonFrameParallelFiles[] = { - { "vp90-2-08-tile_1x2.webm", "570b4a5d5a70d58b5359671668328a16" }, - { "vp90-2-08-tile_1x4.webm", "988d86049e884c66909d2d163a09841a" }, - { "vp90-2-08-tile_1x8.webm", "0941902a52e9092cb010905eab16364c" }, - { "vp90-2-08-tile-4x1.webm", "06505aade6647c583c8e00a2f582266f" }, - { "vp90-2-08-tile-4x4.webm", "85c2299892460d76e2c600502d52bfe2" }, -}; - -INSTANTIATE_TEST_SUITE_P(NoTilesNonFrameParallel, VP9DecodeMultiThreadedTest, - ::testing::ValuesIn(kNoTilesNonFrameParallelFiles)); -INSTANTIATE_TEST_SUITE_P(FrameParallel, VP9DecodeMultiThreadedTest, - ::testing::ValuesIn(kFrameParallelFiles)); -INSTANTIATE_TEST_SUITE_P(FrameParallelResize, VP9DecodeMultiThreadedTest, - ::testing::ValuesIn(kFrameParallelResizeFiles)); -INSTANTIATE_TEST_SUITE_P(NonFrameParallel, VP9DecodeMultiThreadedTest, - ::testing::ValuesIn(kNonFrameParallelFiles)); -#endif // CONFIG_WEBM_IO - -INSTANTIATE_TEST_SUITE_P(Synchronous, VPxWorkerThreadTest, ::testing::Bool()); - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vpx_image_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vpx_image_test.cc deleted file mode 100644 index 7c32035e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vpx_image_test.cc +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2024 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "vpx/vpx_image.h" -#include "gtest/gtest.h" - -TEST(VpxImageTest, VpxImgWrapInvalidAlign) { - const int kWidth = 128; - const int kHeight = 128; - unsigned char buf[kWidth * kHeight * 3]; - - vpx_image_t img; - // Set img_data and img_data_owner to junk values. vpx_img_wrap() should - // not read these values on failure. - unsigned char empty[] = ""; - img.img_data = empty; - img.img_data_owner = 1; - - vpx_img_fmt_t format = VPX_IMG_FMT_I444; - // 'align' must be a power of 2 but is not. This causes the vpx_img_wrap() - // call to fail. The test verifies we do not read the junk values in 'img'. - unsigned int align = 31; - EXPECT_EQ(vpx_img_wrap(&img, format, kWidth, kHeight, align, buf), nullptr); -} - -TEST(VpxImageTest, VpxImgSetRectOverflow) { - const int kWidth = 128; - const int kHeight = 128; - unsigned char buf[kWidth * kHeight * 3]; - - vpx_image_t img; - vpx_img_fmt_t format = VPX_IMG_FMT_I444; - unsigned int align = 32; - EXPECT_EQ(vpx_img_wrap(&img, format, kWidth, kHeight, align, buf), &img); - - EXPECT_EQ(vpx_img_set_rect(&img, 0, 0, kWidth, kHeight), 0); - // This would result in overflow because -1 is cast to UINT_MAX. - EXPECT_NE(vpx_img_set_rect(&img, static_cast(-1), - static_cast(-1), kWidth, kHeight), - 0); -} - -TEST(VpxImageTest, VpxImgAllocNone) { - const int kWidth = 128; - const int kHeight = 128; - - vpx_image_t img; - vpx_img_fmt_t format = VPX_IMG_FMT_NONE; - unsigned int align = 32; - ASSERT_EQ(vpx_img_alloc(&img, format, kWidth, kHeight, align), nullptr); -} - -TEST(VpxImageTest, VpxImgAllocNv12) { - const int kWidth = 128; - const int kHeight = 128; - - vpx_image_t img; - vpx_img_fmt_t format = VPX_IMG_FMT_NV12; - unsigned int align = 32; - EXPECT_EQ(vpx_img_alloc(&img, format, kWidth, kHeight, align), &img); - EXPECT_EQ(img.stride[VPX_PLANE_U], img.stride[VPX_PLANE_Y]); - EXPECT_EQ(img.stride[VPX_PLANE_V], img.stride[VPX_PLANE_U]); - EXPECT_EQ(img.planes[VPX_PLANE_V], img.planes[VPX_PLANE_U] + 1); - vpx_img_free(&img); -} - -TEST(VpxImageTest, VpxImgAllocHugeWidth) { - // The stride (0x80000000 * 2) would overflow unsigned int. - vpx_image_t *image = - vpx_img_alloc(nullptr, VPX_IMG_FMT_I42016, 0x80000000, 1, 1); - ASSERT_EQ(image, nullptr); - - // The stride (0x80000000) would overflow int. - image = vpx_img_alloc(nullptr, VPX_IMG_FMT_I420, 0x80000000, 1, 1); - ASSERT_EQ(image, nullptr); - - // The aligned width (UINT_MAX + 1) would overflow unsigned int. - image = vpx_img_alloc(nullptr, VPX_IMG_FMT_I420, UINT_MAX, 1, 1); - ASSERT_EQ(image, nullptr); - - image = vpx_img_alloc(nullptr, VPX_IMG_FMT_I420, 0x7ffffffe, 1, 1); - if (image) { - vpx_img_free(image); - } - - image = vpx_img_alloc(nullptr, VPX_IMG_FMT_I420, 285245883, 64, 1); - if (image) { - vpx_img_free(image); - } - - image = vpx_img_alloc(nullptr, VPX_IMG_FMT_NV12, 285245883, 64, 1); - if (image) { - vpx_img_free(image); - } - - image = vpx_img_alloc(nullptr, VPX_IMG_FMT_YV12, 285245883, 64, 1); - if (image) { - vpx_img_free(image); - } - - image = vpx_img_alloc(nullptr, VPX_IMG_FMT_I42016, 65536, 2, 1); - if (image) { - uint16_t *y_plane = - reinterpret_cast(image->planes[VPX_PLANE_Y]); - y_plane[0] = 0; - y_plane[image->d_w - 1] = 0; - vpx_img_free(image); - } - - image = vpx_img_alloc(nullptr, VPX_IMG_FMT_I42016, 285245883, 2, 1); - if (image) { - uint16_t *y_plane = - reinterpret_cast(image->planes[VPX_PLANE_Y]); - y_plane[0] = 0; - y_plane[image->d_w - 1] = 0; - vpx_img_free(image); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vpx_scale_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/vpx_scale_test.cc deleted file mode 100644 index f17d2b83..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vpx_scale_test.cc +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "gtest/gtest.h" - -#include "./vpx_config.h" -#include "./vpx_scale_rtcd.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "test/vpx_scale_test.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/vpx_timer.h" -#include "vpx_scale/yv12config.h" - -namespace libvpx_test { -namespace { - -#if VPX_ARCH_ARM || (VPX_ARCH_MIPS && !HAVE_MIPS64) || VPX_ARCH_X86 -// Avoid OOM failures on 32-bit platforms. -const int kNumSizesToTest = 7; -#else -const int kNumSizesToTest = 8; -#endif -const int kSizesToTest[] = { 1, 15, 33, 145, 512, 1025, 3840, 16383 }; - -typedef void (*ExtendFrameBorderFunc)(YV12_BUFFER_CONFIG *ybf); -typedef void (*CopyFrameFunc)(const YV12_BUFFER_CONFIG *src_ybf, - YV12_BUFFER_CONFIG *dst_ybf); - -class ExtendBorderTest - : public VpxScaleBase, - public ::testing::TestWithParam { - public: - ~ExtendBorderTest() override = default; - - protected: - void SetUp() override { extend_fn_ = GetParam(); } - - void ExtendBorder() { ASM_REGISTER_STATE_CHECK(extend_fn_(&img_)); } - - void RunTest() { - for (int h = 0; h < kNumSizesToTest; ++h) { - for (int w = 0; w < kNumSizesToTest; ++w) { - ASSERT_NO_FATAL_FAILURE(ResetImages(kSizesToTest[w], kSizesToTest[h])); - ReferenceCopyFrame(); - ExtendBorder(); - CompareImages(img_); - DeallocImages(); - } - } - } - - ExtendFrameBorderFunc extend_fn_; -}; - -TEST_P(ExtendBorderTest, ExtendBorder) { ASSERT_NO_FATAL_FAILURE(RunTest()); } - -INSTANTIATE_TEST_SUITE_P(C, ExtendBorderTest, - ::testing::Values(vp8_yv12_extend_frame_borders_c)); - -class CopyFrameTest : public VpxScaleBase, - public ::testing::TestWithParam { - public: - ~CopyFrameTest() override = default; - - protected: - void SetUp() override { copy_frame_fn_ = GetParam(); } - - void CopyFrame() { - ASM_REGISTER_STATE_CHECK(copy_frame_fn_(&img_, &dst_img_)); - } - - void RunTest() { - for (int h = 0; h < kNumSizesToTest; ++h) { - for (int w = 0; w < kNumSizesToTest; ++w) { - ASSERT_NO_FATAL_FAILURE(ResetImages(kSizesToTest[w], kSizesToTest[h])); - ReferenceCopyFrame(); - CopyFrame(); - CompareImages(dst_img_); - DeallocImages(); - } - } - } - - CopyFrameFunc copy_frame_fn_; -}; - -TEST_P(CopyFrameTest, CopyFrame) { ASSERT_NO_FATAL_FAILURE(RunTest()); } - -INSTANTIATE_TEST_SUITE_P(C, CopyFrameTest, - ::testing::Values(vp8_yv12_copy_frame_c)); - -} // namespace -} // namespace libvpx_test diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vpx_scale_test.h b/presentation/src/main/cpp/third_party/libvpx/test/vpx_scale_test.h deleted file mode 100644 index 89d62fcd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vpx_scale_test.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_TEST_VPX_SCALE_TEST_H_ -#define VPX_TEST_VPX_SCALE_TEST_H_ - -#include "gtest/gtest.h" - -#include "./vpx_config.h" -#include "./vpx_scale_rtcd.h" -#include "test/acm_random.h" -#include "test/clear_system_state.h" -#include "test/register_state_check.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_scale/yv12config.h" - -using libvpx_test::ACMRandom; - -namespace libvpx_test { - -class VpxScaleBase { - public: - virtual ~VpxScaleBase() { libvpx_test::ClearSystemState(); } - - void ResetImage(YV12_BUFFER_CONFIG *const img, const int width, - const int height) { - memset(img, 0, sizeof(*img)); - ASSERT_EQ( - 0, vp8_yv12_alloc_frame_buffer(img, width, height, VP8BORDERINPIXELS)) - << "for width: " << width << " height: " << height; - memset(img->buffer_alloc, kBufFiller, img->frame_size); - } - - void ResetImages(const int width, const int height) { - ResetImage(&img_, width, height); - ResetImage(&ref_img_, width, height); - ResetImage(&dst_img_, width, height); - - FillPlane(img_.y_buffer, img_.y_crop_width, img_.y_crop_height, - img_.y_stride); - FillPlane(img_.u_buffer, img_.uv_crop_width, img_.uv_crop_height, - img_.uv_stride); - FillPlane(img_.v_buffer, img_.uv_crop_width, img_.uv_crop_height, - img_.uv_stride); - } - - void ResetScaleImage(YV12_BUFFER_CONFIG *const img, const int width, - const int height) { - memset(img, 0, sizeof(*img)); -#if CONFIG_VP9_HIGHBITDEPTH - ASSERT_EQ(0, vpx_alloc_frame_buffer(img, width, height, 1, 1, 0, - VP9_ENC_BORDER_IN_PIXELS, 0)); -#else - ASSERT_EQ(0, vpx_alloc_frame_buffer(img, width, height, 1, 1, - VP9_ENC_BORDER_IN_PIXELS, 0)); -#endif - memset(img->buffer_alloc, kBufFiller, img->frame_size); - } - - void ResetScaleImages(const int src_width, const int src_height, - const int dst_width, const int dst_height) { - ResetScaleImage(&img_, src_width, src_height); - ResetScaleImage(&ref_img_, dst_width, dst_height); - ResetScaleImage(&dst_img_, dst_width, dst_height); - FillPlaneExtreme(img_.y_buffer, img_.y_crop_width, img_.y_crop_height, - img_.y_stride); - FillPlaneExtreme(img_.u_buffer, img_.uv_crop_width, img_.uv_crop_height, - img_.uv_stride); - FillPlaneExtreme(img_.v_buffer, img_.uv_crop_width, img_.uv_crop_height, - img_.uv_stride); - } - - void DeallocImages() { - vp8_yv12_de_alloc_frame_buffer(&img_); - vp8_yv12_de_alloc_frame_buffer(&ref_img_); - vp8_yv12_de_alloc_frame_buffer(&dst_img_); - } - - void DeallocScaleImages() { - vpx_free_frame_buffer(&img_); - vpx_free_frame_buffer(&ref_img_); - vpx_free_frame_buffer(&dst_img_); - } - - protected: - static const int kBufFiller = 123; - static const int kBufMax = kBufFiller - 1; - - static void FillPlane(uint8_t *const buf, const int width, const int height, - const int stride) { - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - buf[x + (y * stride)] = (x + (width * y)) % kBufMax; - } - } - } - - static void FillPlaneExtreme(uint8_t *const buf, const int width, - const int height, const int stride) { - ACMRandom rnd; - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - buf[x + (y * stride)] = rnd.Rand8() % 2 ? 255 : 0; - } - } - } - - static void ExtendPlane(uint8_t *buf, int crop_width, int crop_height, - int width, int height, int stride, int padding) { - // Copy the outermost visible pixel to a distance of at least 'padding.' - // The buffers are allocated such that there may be excess space outside the - // padding. As long as the minimum amount of padding is achieved it is not - // necessary to fill this space as well. - uint8_t *left = buf - padding; - uint8_t *right = buf + crop_width; - const int right_extend = padding + (width - crop_width); - const int bottom_extend = padding + (height - crop_height); - - // Fill the border pixels from the nearest image pixel. - for (int y = 0; y < crop_height; ++y) { - memset(left, left[padding], padding); - memset(right, right[-1], right_extend); - left += stride; - right += stride; - } - - left = buf - padding; - uint8_t *top = left - (stride * padding); - // The buffer does not always extend as far as the stride. - // Equivalent to padding + width + padding. - const int extend_width = padding + crop_width + right_extend; - - // The first row was already extended to the left and right. Copy it up. - for (int y = 0; y < padding; ++y) { - memcpy(top, left, extend_width); - top += stride; - } - - uint8_t *bottom = left + (crop_height * stride); - for (int y = 0; y < bottom_extend; ++y) { - memcpy(bottom, left + (crop_height - 1) * stride, extend_width); - bottom += stride; - } - } - - void ReferenceExtendBorder() { - ExtendPlane(ref_img_.y_buffer, ref_img_.y_crop_width, - ref_img_.y_crop_height, ref_img_.y_width, ref_img_.y_height, - ref_img_.y_stride, ref_img_.border); - ExtendPlane(ref_img_.u_buffer, ref_img_.uv_crop_width, - ref_img_.uv_crop_height, ref_img_.uv_width, ref_img_.uv_height, - ref_img_.uv_stride, ref_img_.border / 2); - ExtendPlane(ref_img_.v_buffer, ref_img_.uv_crop_width, - ref_img_.uv_crop_height, ref_img_.uv_width, ref_img_.uv_height, - ref_img_.uv_stride, ref_img_.border / 2); - } - - void ReferenceCopyFrame() { - // Copy img_ to ref_img_ and extend frame borders. This will be used for - // verifying extend_fn_ as well as copy_frame_fn_. - EXPECT_EQ(ref_img_.frame_size, img_.frame_size); - for (int y = 0; y < img_.y_crop_height; ++y) { - for (int x = 0; x < img_.y_crop_width; ++x) { - ref_img_.y_buffer[x + y * ref_img_.y_stride] = - img_.y_buffer[x + y * img_.y_stride]; - } - } - - for (int y = 0; y < img_.uv_crop_height; ++y) { - for (int x = 0; x < img_.uv_crop_width; ++x) { - ref_img_.u_buffer[x + y * ref_img_.uv_stride] = - img_.u_buffer[x + y * img_.uv_stride]; - ref_img_.v_buffer[x + y * ref_img_.uv_stride] = - img_.v_buffer[x + y * img_.uv_stride]; - } - } - - ReferenceExtendBorder(); - } - - void CompareImages(const YV12_BUFFER_CONFIG actual) { - EXPECT_EQ(ref_img_.frame_size, actual.frame_size); - EXPECT_EQ(0, memcmp(ref_img_.buffer_alloc, actual.buffer_alloc, - ref_img_.frame_size)); - } - - YV12_BUFFER_CONFIG img_; - YV12_BUFFER_CONFIG ref_img_; - YV12_BUFFER_CONFIG dst_img_; -}; - -} // namespace libvpx_test - -#endif // VPX_TEST_VPX_SCALE_TEST_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vpx_temporal_svc_encoder.sh b/presentation/src/main/cpp/third_party/libvpx/test/vpx_temporal_svc_encoder.sh deleted file mode 100644 index 69c734da..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vpx_temporal_svc_encoder.sh +++ /dev/null @@ -1,334 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2014 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## This file tests the libvpx vpx_temporal_svc_encoder example. To add new -## tests to this file, do the following: -## 1. Write a shell function (this is your test). -## 2. Add the function to vpx_tsvc_encoder_tests (on a new line). -## -. $(dirname $0)/tools_common.sh - -# Environment check: $YUV_RAW_INPUT is required. -vpx_tsvc_encoder_verify_environment() { - if [ ! -e "${YUV_RAW_INPUT}" ]; then - echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH." - return 1 - fi - if [ "$(vpx_config_option_enabled CONFIG_TEMPORAL_DENOISING)" != "yes" ]; then - elog "Warning: Temporal denoising is disabled! Spatial denoising will be " \ - "used instead, which is probably not what you want for this test." - fi -} - -# Runs vpx_temporal_svc_encoder using the codec specified by $1 and output file -# name by $2. Additional positional parameters are passed directly to -# vpx_temporal_svc_encoder. -vpx_tsvc_encoder() { - local encoder="${LIBVPX_BIN_PATH}/vpx_temporal_svc_encoder" - encoder="${encoder}${VPX_TEST_EXE_SUFFIX}" - local codec="$1" - local output_file_base="$2" - local output_file="${VPX_TEST_OUTPUT_DIR}/${output_file_base}" - local timebase_num="1" - local timebase_den="1000" - local timebase_den_y4m="30" - local speed="6" - local frame_drop_thresh="30" - local max_threads="4" - local error_resilient="1" - - shift 2 - - if [ ! -x "${encoder}" ]; then - elog "${encoder} does not exist or is not executable." - return 1 - fi - - # TODO(tomfinegan): Verify file output for all thread runs. - for threads in $(seq $max_threads); do - if [ "$(vpx_config_option_enabled CONFIG_VP9_HIGHBITDEPTH)" != "yes" ]; then - eval "${VPX_TEST_PREFIX}" "${encoder}" "${YUV_RAW_INPUT}" \ - "${output_file}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \ - "${YUV_RAW_INPUT_HEIGHT}" "${timebase_num}" "${timebase_den}" \ - "${speed}" "${frame_drop_thresh}" "${error_resilient}" "${threads}" \ - "$@" ${devnull} || return 1 - # Test for y4m input. - eval "${VPX_TEST_PREFIX}" "${encoder}" "${Y4M_720P_INPUT}" \ - "${output_file}" "${codec}" "${Y4M_720P_INPUT_WIDTH}" \ - "${Y4M_720P_INPUT_HEIGHT}" "${timebase_num}" "${timebase_den_y4m}" \ - "${speed}" "${frame_drop_thresh}" "${error_resilient}" "${threads}" \ - "$@" ${devnull} || return 1 - else - eval "${VPX_TEST_PREFIX}" "${encoder}" "${YUV_RAW_INPUT}" \ - "${output_file}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \ - "${YUV_RAW_INPUT_HEIGHT}" "${timebase_num}" "${timebase_den}" \ - "${speed}" "${frame_drop_thresh}" "${error_resilient}" "${threads}" \ - "$@" "8" ${devnull} || return 1 - fi - done -} - -# Confirms that all expected output files exist given the output file name -# passed to vpx_temporal_svc_encoder. -# The file name passed to vpx_temporal_svc_encoder is joined with the stream -# number and the extension .ivf to produce per stream output files. Here $1 is -# file name, and $2 is expected number of files. -files_exist() { - local file_name="${VPX_TEST_OUTPUT_DIR}/$1" - local num_files="$(($2 - 1))" - for stream_num in $(seq 0 ${num_files}); do - [ -e "${file_name}_${stream_num}.ivf" ] || return 1 - done -} - -# Run vpx_temporal_svc_encoder in all supported modes for vp8 and vp9. - -vpx_tsvc_encoder_vp8_mode_0() { - if [ "$(vp8_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp8_mode_0" - vpx_tsvc_encoder vp8 "${output_basename}" 0 200 || return 1 - # Mode 0 produces 1 stream - files_exist "${output_basename}" 1 || return 1 - fi -} - -vpx_tsvc_encoder_vp8_mode_1() { - if [ "$(vp8_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp8_mode_1" - vpx_tsvc_encoder vp8 "${output_basename}" 1 200 400 || return 1 - # Mode 1 produces 2 streams - files_exist "${output_basename}" 2 || return 1 - fi -} - -vpx_tsvc_encoder_vp8_mode_2() { - if [ "$(vp8_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp8_mode_2" - vpx_tsvc_encoder vp8 "${output_basename}" 2 200 400 || return 1 - # Mode 2 produces 2 streams - files_exist "${output_basename}" 2 || return 1 - fi -} - -vpx_tsvc_encoder_vp8_mode_3() { - if [ "$(vp8_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp8_mode_3" - vpx_tsvc_encoder vp8 "${output_basename}" 3 200 400 600 || return 1 - # Mode 3 produces 3 streams - files_exist "${output_basename}" 3 || return 1 - fi -} - -vpx_tsvc_encoder_vp8_mode_4() { - if [ "$(vp8_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp8_mode_4" - vpx_tsvc_encoder vp8 "${output_basename}" 4 200 400 600 || return 1 - # Mode 4 produces 3 streams - files_exist "${output_basename}" 3 || return 1 - fi -} - -vpx_tsvc_encoder_vp8_mode_5() { - if [ "$(vp8_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp8_mode_5" - vpx_tsvc_encoder vp8 "${output_basename}" 5 200 400 600 || return 1 - # Mode 5 produces 3 streams - files_exist "${output_basename}" 3 || return 1 - fi -} - -vpx_tsvc_encoder_vp8_mode_6() { - if [ "$(vp8_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp8_mode_6" - vpx_tsvc_encoder vp8 "${output_basename}" 6 200 400 600 || return 1 - # Mode 6 produces 3 streams - files_exist "${output_basename}" 3 || return 1 - fi -} - -vpx_tsvc_encoder_vp8_mode_7() { - if [ "$(vp8_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp8_mode_7" - vpx_tsvc_encoder vp8 "${output_basename}" 7 200 400 600 800 1000 || return 1 - # Mode 7 produces 5 streams - files_exist "${output_basename}" 5 || return 1 - fi -} - -vpx_tsvc_encoder_vp8_mode_8() { - if [ "$(vp8_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp8_mode_8" - vpx_tsvc_encoder vp8 "${output_basename}" 8 200 400 || return 1 - # Mode 8 produces 2 streams - files_exist "${output_basename}" 2 || return 1 - fi -} - -vpx_tsvc_encoder_vp8_mode_9() { - if [ "$(vp8_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp8_mode_9" - vpx_tsvc_encoder vp8 "${output_basename}" 9 200 400 600 || return 1 - # Mode 9 produces 3 streams - files_exist "${output_basename}" 3 || return 1 - fi -} - -vpx_tsvc_encoder_vp8_mode_10() { - if [ "$(vp8_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp8_mode_10" - vpx_tsvc_encoder vp8 "${output_basename}" 10 200 400 600 || return 1 - # Mode 10 produces 3 streams - files_exist "${output_basename}" 3 || return 1 - fi -} - -vpx_tsvc_encoder_vp8_mode_11() { - if [ "$(vp8_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp8_mode_11" - vpx_tsvc_encoder vp8 "${output_basename}" 11 200 400 600 || return 1 - # Mode 11 produces 3 streams - files_exist "${output_basename}" 3 || return 1 - fi -} - -vpx_tsvc_encoder_vp9_mode_0() { - if [ "$(vp9_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp9_mode_0" - vpx_tsvc_encoder vp9 "${output_basename}" 0 200 || return 1 - # Mode 0 produces 1 stream - files_exist "${output_basename}" 1 || return 1 - fi -} - -vpx_tsvc_encoder_vp9_mode_1() { - if [ "$(vp9_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp9_mode_1" - vpx_tsvc_encoder vp9 "${output_basename}" 1 200 400 || return 1 - # Mode 1 produces 2 streams - files_exist "${output_basename}" 2 || return 1 - fi -} - -vpx_tsvc_encoder_vp9_mode_2() { - if [ "$(vp9_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp9_mode_2" - vpx_tsvc_encoder vp9 "${output_basename}" 2 200 400 || return 1 - # Mode 2 produces 2 streams - files_exist "${output_basename}" 2 || return 1 - fi -} - -vpx_tsvc_encoder_vp9_mode_3() { - if [ "$(vp9_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp9_mode_3" - vpx_tsvc_encoder vp9 "${output_basename}" 3 200 400 600 || return 1 - # Mode 3 produces 3 streams - files_exist "${output_basename}" 3 || return 1 - fi -} - -vpx_tsvc_encoder_vp9_mode_4() { - if [ "$(vp9_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp9_mode_4" - vpx_tsvc_encoder vp9 "${output_basename}" 4 200 400 600 || return 1 - # Mode 4 produces 3 streams - files_exist "${output_basename}" 3 || return 1 - fi -} - -vpx_tsvc_encoder_vp9_mode_5() { - if [ "$(vp9_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp9_mode_5" - vpx_tsvc_encoder vp9 "${output_basename}" 5 200 400 600 || return 1 - # Mode 5 produces 3 streams - files_exist "${output_basename}" 3 || return 1 - fi -} - -vpx_tsvc_encoder_vp9_mode_6() { - if [ "$(vp9_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp9_mode_6" - vpx_tsvc_encoder vp9 "${output_basename}" 6 200 400 600 || return 1 - # Mode 6 produces 3 streams - files_exist "${output_basename}" 3 || return 1 - fi -} - -vpx_tsvc_encoder_vp9_mode_7() { - if [ "$(vp9_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp9_mode_7" - vpx_tsvc_encoder vp9 "${output_basename}" 7 200 400 600 800 1000 || return 1 - # Mode 7 produces 5 streams - files_exist "${output_basename}" 5 || return 1 - fi -} - -vpx_tsvc_encoder_vp9_mode_8() { - if [ "$(vp9_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp9_mode_8" - vpx_tsvc_encoder vp9 "${output_basename}" 8 200 400 || return 1 - # Mode 8 produces 2 streams - files_exist "${output_basename}" 2 || return 1 - fi -} - -vpx_tsvc_encoder_vp9_mode_9() { - if [ "$(vp9_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp9_mode_9" - vpx_tsvc_encoder vp9 "${output_basename}" 9 200 400 600 || return 1 - # Mode 9 produces 3 streams - files_exist "${output_basename}" 3 || return 1 - fi -} - -vpx_tsvc_encoder_vp9_mode_10() { - if [ "$(vp9_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp9_mode_10" - vpx_tsvc_encoder vp9 "${output_basename}" 10 200 400 600 || return 1 - # Mode 10 produces 3 streams - files_exist "${output_basename}" 3 || return 1 - fi -} - -vpx_tsvc_encoder_vp9_mode_11() { - if [ "$(vp9_encode_available)" = "yes" ]; then - local output_basename="vpx_tsvc_encoder_vp9_mode_11" - vpx_tsvc_encoder vp9 "${output_basename}" 11 200 400 600 || return 1 - # Mode 11 produces 3 streams - files_exist "${output_basename}" 3 || return 1 - fi -} - -vpx_tsvc_encoder_tests="vpx_tsvc_encoder_vp8_mode_0 - vpx_tsvc_encoder_vp8_mode_1 - vpx_tsvc_encoder_vp8_mode_2 - vpx_tsvc_encoder_vp8_mode_3 - vpx_tsvc_encoder_vp8_mode_4 - vpx_tsvc_encoder_vp8_mode_5 - vpx_tsvc_encoder_vp8_mode_6 - vpx_tsvc_encoder_vp8_mode_7 - vpx_tsvc_encoder_vp8_mode_8 - vpx_tsvc_encoder_vp8_mode_9 - vpx_tsvc_encoder_vp8_mode_10 - vpx_tsvc_encoder_vp8_mode_11 - vpx_tsvc_encoder_vp9_mode_0 - vpx_tsvc_encoder_vp9_mode_1 - vpx_tsvc_encoder_vp9_mode_2 - vpx_tsvc_encoder_vp9_mode_3 - vpx_tsvc_encoder_vp9_mode_4 - vpx_tsvc_encoder_vp9_mode_5 - vpx_tsvc_encoder_vp9_mode_6 - vpx_tsvc_encoder_vp9_mode_7 - vpx_tsvc_encoder_vp9_mode_8 - vpx_tsvc_encoder_vp9_mode_9 - vpx_tsvc_encoder_vp9_mode_10 - vpx_tsvc_encoder_vp9_mode_11" - -run_tests vpx_tsvc_encoder_verify_environment "${vpx_tsvc_encoder_tests}" diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vpxdec.sh b/presentation/src/main/cpp/third_party/libvpx/test/vpxdec.sh deleted file mode 100644 index 199feae5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vpxdec.sh +++ /dev/null @@ -1,135 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2014 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## This file tests vpxdec. To add new tests to this file, do the following: -## 1. Write a shell function (this is your test). -## 2. Add the function to vpxdec_tests (on a new line). -## -. $(dirname $0)/tools_common.sh - -# Environment check: Make sure input is available. -vpxdec_verify_environment() { - if [ ! -e "${VP8_IVF_FILE}" ] || [ ! -e "${VP9_WEBM_FILE}" ] || \ - [ ! -e "${VP9_FPM_WEBM_FILE}" ] || \ - [ ! -e "${VP9_LT_50_FRAMES_WEBM_FILE}" ] || \ - [ ! -e "${VP9_RAW_FILE}" ]; then - elog "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH." - return 1 - fi - if [ -z "$(vpx_tool_path vpxdec)" ]; then - elog "vpxdec not found. It must exist in LIBVPX_BIN_PATH or its parent." - return 1 - fi -} - -# Wrapper function for running vpxdec with pipe input. Requires that -# LIBVPX_BIN_PATH points to the directory containing vpxdec. $1 is used as the -# input file path and shifted away. All remaining parameters are passed through -# to vpxdec. -vpxdec_pipe() { - local decoder="$(vpx_tool_path vpxdec)" - local input="$1" - shift - cat "${input}" | eval "${VPX_TEST_PREFIX}" "${decoder}" - "$@" ${devnull} -} - -# Wrapper function for running vpxdec. Requires that LIBVPX_BIN_PATH points to -# the directory containing vpxdec. $1 one is used as the input file path and -# shifted away. All remaining parameters are passed through to vpxdec. -vpxdec() { - local decoder="$(vpx_tool_path vpxdec)" - local input="$1" - shift - eval "${VPX_TEST_PREFIX}" "${decoder}" "$input" "$@" ${devnull} -} - -vpxdec_can_decode_vp8() { - if [ "$(vp8_decode_available)" = "yes" ]; then - echo yes - fi -} - -vpxdec_can_decode_vp9() { - if [ "$(vp9_decode_available)" = "yes" ]; then - echo yes - fi -} - -vpxdec_vp8_ivf() { - if [ "$(vpxdec_can_decode_vp8)" = "yes" ]; then - vpxdec "${VP8_IVF_FILE}" --summary --noblit - fi -} - -vpxdec_vp8_ivf_pipe_input() { - if [ "$(vpxdec_can_decode_vp8)" = "yes" ]; then - vpxdec_pipe "${VP8_IVF_FILE}" --summary --noblit - fi -} - -vpxdec_vp9_webm() { - if [ "$(vpxdec_can_decode_vp9)" = "yes" ] && \ - [ "$(webm_io_available)" = "yes" ]; then - vpxdec "${VP9_WEBM_FILE}" --summary --noblit - fi -} - -vpxdec_vp9_webm_frame_parallel() { - if [ "$(vpxdec_can_decode_vp9)" = "yes" ] && \ - [ "$(webm_io_available)" = "yes" ]; then - for threads in 2 3 4 5 6 7 8; do - vpxdec "${VP9_FPM_WEBM_FILE}" --summary --noblit --threads=$threads \ - --frame-parallel || return 1 - done - fi -} - -vpxdec_vp9_webm_less_than_50_frames() { - # ensure that reaching eof in webm_guess_framerate doesn't result in invalid - # frames in actual webm_read_frame calls. - if [ "$(vpxdec_can_decode_vp9)" = "yes" ] && \ - [ "$(webm_io_available)" = "yes" ]; then - local decoder="$(vpx_tool_path vpxdec)" - local expected=10 - local num_frames=$(${VPX_TEST_PREFIX} "${decoder}" \ - "${VP9_LT_50_FRAMES_WEBM_FILE}" --summary --noblit 2>&1 \ - | awk '/^[0-9]+ decoded frames/ { print $1 }') - if [ "$num_frames" -ne "$expected" ]; then - elog "Output frames ($num_frames) != expected ($expected)" - return 1 - fi - fi -} - -# Ensures VP9_RAW_FILE correctly produces 1 frame instead of causing a hang. -vpxdec_vp9_raw_file() { - # Ensure a raw file properly reports eof and doesn't cause a hang. - if [ "$(vpxdec_can_decode_vp9)" = "yes" ]; then - local decoder="$(vpx_tool_path vpxdec)" - local expected=1 - [ -x /usr/bin/timeout ] && local TIMEOUT="/usr/bin/timeout 30s" - local num_frames=$(${TIMEOUT} ${VPX_TEST_PREFIX} "${decoder}" \ - "${VP9_RAW_FILE}" --summary --noblit 2>&1 \ - | awk '/^[0-9]+ decoded frames/ { print $1 }') - if [ -z "$num_frames" ] || [ "$num_frames" -ne "$expected" ]; then - elog "Output frames ($num_frames) != expected ($expected)" - return 1 - fi - fi -} - -vpxdec_tests="vpxdec_vp8_ivf - vpxdec_vp8_ivf_pipe_input - vpxdec_vp9_webm - vpxdec_vp9_webm_frame_parallel - vpxdec_vp9_webm_less_than_50_frames - vpxdec_vp9_raw_file" - -run_tests vpxdec_verify_environment "${vpxdec_tests}" diff --git a/presentation/src/main/cpp/third_party/libvpx/test/vpxenc.sh b/presentation/src/main/cpp/third_party/libvpx/test/vpxenc.sh deleted file mode 100644 index 172349a2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/vpxenc.sh +++ /dev/null @@ -1,489 +0,0 @@ -#!/bin/sh -## -## Copyright (c) 2014 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## This file tests vpxenc using hantro_collage_w352h288.yuv as input. To add -## new tests to this file, do the following: -## 1. Write a shell function (this is your test). -## 2. Add the function to vpxenc_tests (on a new line). -## -. $(dirname $0)/tools_common.sh - -readonly TEST_FRAMES=10 - -# Environment check: Make sure input is available. -vpxenc_verify_environment() { - if [ ! -e "${YUV_RAW_INPUT}" ]; then - elog "The file ${YUV_RAW_INPUT##*/} must exist in LIBVPX_TEST_DATA_PATH." - return 1 - fi - if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then - if [ ! -e "${Y4M_NOSQ_PAR_INPUT}" ]; then - elog "The file ${Y4M_NOSQ_PAR_INPUT##*/} must exist in" - elog "LIBVPX_TEST_DATA_PATH." - return 1 - fi - fi - if [ -z "$(vpx_tool_path vpxenc)" ]; then - elog "vpxenc not found. It must exist in LIBVPX_BIN_PATH or its parent." - return 1 - fi -} - -vpxenc_can_encode_vp8() { - if [ "$(vp8_encode_available)" = "yes" ]; then - echo yes - fi -} - -vpxenc_can_encode_vp9() { - if [ "$(vp9_encode_available)" = "yes" ]; then - echo yes - fi -} - -# Echo vpxenc command line parameters allowing use of -# hantro_collage_w352h288.yuv as input. -yuv_input_hantro_collage() { - echo ""${YUV_RAW_INPUT}" - --width="${YUV_RAW_INPUT_WIDTH}" - --height="${YUV_RAW_INPUT_HEIGHT}"" -} - -y4m_input_non_square_par() { - echo ""${Y4M_NOSQ_PAR_INPUT}"" -} - -y4m_input_720p() { - echo ""${Y4M_720P_INPUT}"" -} - -# Echo default vpxenc real time encoding params. $1 is the codec, which defaults -# to vp8 if unspecified. -vpxenc_rt_params() { - local codec="${1:-vp8}" - echo "--codec=${codec} - --buf-initial-sz=500 - --buf-optimal-sz=600 - --buf-sz=1000 - --cpu-used=-6 - --end-usage=cbr - --error-resilient=1 - --kf-max-dist=90000 - --lag-in-frames=0 - --max-intra-rate=300 - --max-q=56 - --min-q=2 - --noise-sensitivity=0 - --overshoot-pct=50 - --passes=1 - --profile=0 - --resize-allowed=0 - --rt - --static-thresh=0 - --undershoot-pct=50" -} - -# Forces --passes to 1 with CONFIG_REALTIME_ONLY. -vpxenc_passes_param() { - if [ "$(vpx_config_option_enabled CONFIG_REALTIME_ONLY)" = "yes" ]; then - echo "--passes=1" - else - echo "--passes=2" - fi -} - -# Wrapper function for running vpxenc with pipe input. Requires that -# LIBVPX_BIN_PATH points to the directory containing vpxenc. $1 is used as the -# input file path and shifted away. All remaining parameters are passed through -# to vpxenc. -vpxenc_pipe() { - local encoder="$(vpx_tool_path vpxenc)" - local input="$1" - shift - cat "${input}" | eval "${VPX_TEST_PREFIX}" "${encoder}" - \ - --test-decode=fatal \ - "$@" ${devnull} -} - -# Wrapper function for running vpxenc. Requires that LIBVPX_BIN_PATH points to -# the directory containing vpxenc. $1 one is used as the input file path and -# shifted away. All remaining parameters are passed through to vpxenc. -vpxenc() { - local encoder="$(vpx_tool_path vpxenc)" - local input="$1" - shift - eval "${VPX_TEST_PREFIX}" "${encoder}" "${input}" \ - --test-decode=fatal \ - "$@" ${devnull} -} - -vpxenc_vp8_ivf() { - if [ "$(vpxenc_can_encode_vp8)" = "yes" ]; then - local output="${VPX_TEST_OUTPUT_DIR}/vp8.ivf" - vpxenc $(yuv_input_hantro_collage) \ - --codec=vp8 \ - --limit="${TEST_FRAMES}" \ - --ivf \ - --output="${output}" || return 1 - - if [ ! -e "${output}" ]; then - elog "Output file does not exist." - return 1 - fi - fi -} - -vpxenc_vp8_webm() { - if [ "$(vpxenc_can_encode_vp8)" = "yes" ] && \ - [ "$(webm_io_available)" = "yes" ]; then - local output="${VPX_TEST_OUTPUT_DIR}/vp8.webm" - vpxenc $(yuv_input_hantro_collage) \ - --codec=vp8 \ - --limit="${TEST_FRAMES}" \ - --output="${output}" || return 1 - - if [ ! -e "${output}" ]; then - elog "Output file does not exist." - return 1 - fi - fi -} - -vpxenc_vp8_webm_rt() { - if [ "$(vpxenc_can_encode_vp8)" = "yes" ] && \ - [ "$(webm_io_available)" = "yes" ]; then - local output="${VPX_TEST_OUTPUT_DIR}/vp8_rt.webm" - vpxenc $(yuv_input_hantro_collage) \ - $(vpxenc_rt_params vp8) \ - --output="${output}" || return 1 - - if [ ! -e "${output}" ]; then - elog "Output file does not exist." - return 1 - fi - fi -} - -vpxenc_vp8_webm_2pass() { - if [ "$(vpxenc_can_encode_vp8)" = "yes" ] && \ - [ "$(webm_io_available)" = "yes" ]; then - local output="${VPX_TEST_OUTPUT_DIR}/vp8.webm" - vpxenc $(yuv_input_hantro_collage) \ - --codec=vp8 \ - --limit="${TEST_FRAMES}" \ - --output="${output}" \ - --passes=2 || return 1 - - if [ ! -e "${output}" ]; then - elog "Output file does not exist." - return 1 - fi - fi -} - -vpxenc_vp8_webm_lag10_frames20() { - if [ "$(vpxenc_can_encode_vp8)" = "yes" ] && \ - [ "$(webm_io_available)" = "yes" ]; then - local lag_total_frames=20 - local lag_frames=10 - local output="${VPX_TEST_OUTPUT_DIR}/vp8_lag10_frames20.webm" - vpxenc $(yuv_input_hantro_collage) \ - --codec=vp8 \ - --limit="${lag_total_frames}" \ - --lag-in-frames="${lag_frames}" \ - --output="${output}" \ - --auto-alt-ref=1 \ - --passes=2 || return 1 - - if [ ! -e "${output}" ]; then - elog "Output file does not exist." - return 1 - fi - fi -} - -vpxenc_vp8_ivf_piped_input() { - if [ "$(vpxenc_can_encode_vp8)" = "yes" ]; then - local output="${VPX_TEST_OUTPUT_DIR}/vp8_piped_input.ivf" - vpxenc_pipe $(yuv_input_hantro_collage) \ - --codec=vp8 \ - --limit="${TEST_FRAMES}" \ - --ivf \ - --output="${output}" || return 1 - - if [ ! -e "${output}" ]; then - elog "Output file does not exist." - return 1 - fi - fi -} - -vpxenc_vp9_ivf() { - if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then - local output="${VPX_TEST_OUTPUT_DIR}/vp9.ivf" - local passes=$(vpxenc_passes_param) - vpxenc $(yuv_input_hantro_collage) \ - --codec=vp9 \ - --limit="${TEST_FRAMES}" \ - "${passes}" \ - --ivf \ - --output="${output}" || return 1 - - if [ ! -e "${output}" ]; then - elog "Output file does not exist." - return 1 - fi - fi -} - -vpxenc_vp9_webm() { - if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \ - [ "$(webm_io_available)" = "yes" ]; then - local output="${VPX_TEST_OUTPUT_DIR}/vp9.webm" - local passes=$(vpxenc_passes_param) - vpxenc $(yuv_input_hantro_collage) \ - --codec=vp9 \ - --limit="${TEST_FRAMES}" \ - "${passes}" \ - --output="${output}" || return 1 - - if [ ! -e "${output}" ]; then - elog "Output file does not exist." - return 1 - fi - fi -} - -vpxenc_vp9_webm_rt() { - if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \ - [ "$(webm_io_available)" = "yes" ]; then - local output="${VPX_TEST_OUTPUT_DIR}/vp9_rt.webm" - vpxenc $(yuv_input_hantro_collage) \ - $(vpxenc_rt_params vp9) \ - --output="${output}" || return 1 - - if [ ! -e "${output}" ]; then - elog "Output file does not exist." - return 1 - fi - fi -} - -vpxenc_vp9_webm_rt_multithread_tiled() { - if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \ - [ "$(webm_io_available)" = "yes" ]; then - local output="${VPX_TEST_OUTPUT_DIR}/vp9_rt_multithread_tiled.webm" - local tilethread_min=2 - local tilethread_max=4 - local num_threads="$(seq ${tilethread_min} ${tilethread_max})" - local num_tile_cols="$(seq ${tilethread_min} ${tilethread_max})" - - for threads in ${num_threads}; do - for tile_cols in ${num_tile_cols}; do - vpxenc $(y4m_input_720p) \ - $(vpxenc_rt_params vp9) \ - --threads=${threads} \ - --tile-columns=${tile_cols} \ - --output="${output}" || return 1 - - if [ ! -e "${output}" ]; then - elog "Output file does not exist." - return 1 - fi - rm "${output}" - done - done - fi -} - -vpxenc_vp9_webm_rt_multithread_tiled_frameparallel() { - if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \ - [ "$(webm_io_available)" = "yes" ]; then - local output="${VPX_TEST_OUTPUT_DIR}/vp9_rt_mt_t_fp.webm" - local tilethread_min=2 - local tilethread_max=4 - local num_threads="$(seq ${tilethread_min} ${tilethread_max})" - local num_tile_cols="$(seq ${tilethread_min} ${tilethread_max})" - - for threads in ${num_threads}; do - for tile_cols in ${num_tile_cols}; do - vpxenc $(y4m_input_720p) \ - $(vpxenc_rt_params vp9) \ - --threads=${threads} \ - --tile-columns=${tile_cols} \ - --frame-parallel=1 \ - --output="${output}" || return 1 - - if [ ! -e "${output}" ]; then - elog "Output file does not exist." - return 1 - fi - rm "${output}" - done - done - fi -} - -vpxenc_vp9_webm_2pass() { - if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \ - [ "$(webm_io_available)" = "yes" ]; then - local output="${VPX_TEST_OUTPUT_DIR}/vp9.webm" - vpxenc $(yuv_input_hantro_collage) \ - --codec=vp9 \ - --limit="${TEST_FRAMES}" \ - --output="${output}" \ - --passes=2 || return 1 - - if [ ! -e "${output}" ]; then - elog "Output file does not exist." - return 1 - fi - fi -} - -vpxenc_vp9_ivf_lossless() { - if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then - local output="${VPX_TEST_OUTPUT_DIR}/vp9_lossless.ivf" - local passes=$(vpxenc_passes_param) - vpxenc $(yuv_input_hantro_collage) \ - --codec=vp9 \ - --limit="${TEST_FRAMES}" \ - --ivf \ - --output="${output}" \ - "${passes}" \ - --lossless=1 || return 1 - - if [ ! -e "${output}" ]; then - elog "Output file does not exist." - return 1 - fi - fi -} - -vpxenc_vp9_ivf_minq0_maxq0() { - if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then - local output="${VPX_TEST_OUTPUT_DIR}/vp9_lossless_minq0_maxq0.ivf" - local passes=$(vpxenc_passes_param) - vpxenc $(yuv_input_hantro_collage) \ - --codec=vp9 \ - --limit="${TEST_FRAMES}" \ - --ivf \ - --output="${output}" \ - "${passes}" \ - --min-q=0 \ - --max-q=0 || return 1 - - if [ ! -e "${output}" ]; then - elog "Output file does not exist." - return 1 - fi - fi -} - -vpxenc_vp9_webm_lag10_frames20() { - if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \ - [ "$(webm_io_available)" = "yes" ]; then - local lag_total_frames=20 - local lag_frames=10 - local output="${VPX_TEST_OUTPUT_DIR}/vp9_lag10_frames20.webm" - local passes=$(vpxenc_passes_param) - vpxenc $(yuv_input_hantro_collage) \ - --codec=vp9 \ - --limit="${lag_total_frames}" \ - --lag-in-frames="${lag_frames}" \ - --output="${output}" \ - "${passes}" \ - --auto-alt-ref=1 || return 1 - - if [ ! -e "${output}" ]; then - elog "Output file does not exist." - return 1 - fi - fi -} - -# TODO(fgalligan): Test that DisplayWidth is different than video width. -vpxenc_vp9_webm_non_square_par() { - if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \ - [ "$(webm_io_available)" = "yes" ]; then - local output="${VPX_TEST_OUTPUT_DIR}/vp9_non_square_par.webm" - local passes=$(vpxenc_passes_param) - vpxenc $(y4m_input_non_square_par) \ - --codec=vp9 \ - --limit="${TEST_FRAMES}" \ - "${passes}" \ - --output="${output}" || return 1 - - if [ ! -e "${output}" ]; then - elog "Output file does not exist." - return 1 - fi - fi -} - -vpxenc_vp9_webm_sharpness() { - if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then - local sharpnesses="0 1 2 3 4 5 6 7" - local output="${VPX_TEST_OUTPUT_DIR}/vpxenc_vp9_webm_sharpness.ivf" - local last_size=0 - local this_size=0 - - for sharpness in ${sharpnesses}; do - - vpxenc $(yuv_input_hantro_collage) \ - --sharpness="${sharpness}" \ - --codec=vp9 \ - --limit=1 \ - --cpu-used=2 \ - --end-usage=q \ - --cq-level=40 \ - --output="${output}" \ - "${passes}" || return 1 - - if [ ! -e "${output}" ]; then - elog "Output file does not exist." - return 1 - fi - - this_size=$(stat -c '%s' "${output}") - if [ "${this_size}" -lt "${last_size}" ]; then - elog "Higher sharpness value yielded lower file size." - echo "${this_size}" " < " "${last_size}" - return 1 - fi - last_size="${this_size}" - - done - fi -} - -vpxenc_tests="vpxenc_vp8_ivf - vpxenc_vp8_webm - vpxenc_vp8_webm_rt - vpxenc_vp8_ivf_piped_input - vpxenc_vp9_ivf - vpxenc_vp9_webm - vpxenc_vp9_webm_rt - vpxenc_vp9_webm_rt_multithread_tiled - vpxenc_vp9_webm_rt_multithread_tiled_frameparallel - vpxenc_vp9_ivf_lossless - vpxenc_vp9_ivf_minq0_maxq0 - vpxenc_vp9_webm_lag10_frames20 - vpxenc_vp9_webm_non_square_par - vpxenc_vp9_webm_sharpness" - -if [ "$(vpx_config_option_enabled CONFIG_REALTIME_ONLY)" != "yes" ]; then - vpxenc_tests="$vpxenc_tests - vpxenc_vp8_webm_2pass - vpxenc_vp8_webm_lag10_frames20 - vpxenc_vp9_webm_2pass" -fi - -run_tests vpxenc_verify_environment "${vpxenc_tests}" diff --git a/presentation/src/main/cpp/third_party/libvpx/test/webm_video_source.h b/presentation/src/main/cpp/third_party/libvpx/test/webm_video_source.h deleted file mode 100644 index 6ab50c84..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/webm_video_source.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_TEST_WEBM_VIDEO_SOURCE_H_ -#define VPX_TEST_WEBM_VIDEO_SOURCE_H_ -#include -#include -#include -#include -#include -#include "../tools_common.h" -#include "../webmdec.h" -#include "test/video_source.h" - -namespace libvpx_test { - -// This class extends VideoSource to allow parsing of WebM files, -// so that we can do actual file decodes. -class WebMVideoSource : public CompressedVideoSource { - public: - explicit WebMVideoSource(const std::string &file_name) - : file_name_(file_name), vpx_ctx_(new VpxInputContext()), - webm_ctx_(new WebmInputContext()), buf_(nullptr), buf_sz_(0), frame_(0), - end_of_file_(false) {} - - ~WebMVideoSource() override { - if (vpx_ctx_->file != nullptr) fclose(vpx_ctx_->file); - webm_free(webm_ctx_); - delete vpx_ctx_; - delete webm_ctx_; - } - - void Init() override {} - - void Begin() override { - vpx_ctx_->file = OpenTestDataFile(file_name_); - ASSERT_NE(vpx_ctx_->file, nullptr) - << "Input file open failed. Filename: " << file_name_; - - ASSERT_EQ(file_is_webm(webm_ctx_, vpx_ctx_), 1) << "file is not WebM"; - - FillFrame(); - } - - void Next() override { - ++frame_; - FillFrame(); - } - - void FillFrame() { - ASSERT_NE(vpx_ctx_->file, nullptr); - const int status = webm_read_frame(webm_ctx_, &buf_, &buf_sz_); - ASSERT_GE(status, 0) << "webm_read_frame failed"; - if (status == 1) { - end_of_file_ = true; - } - } - - void SeekToNextKeyFrame() { - ASSERT_NE(vpx_ctx_->file, nullptr); - do { - const int status = webm_read_frame(webm_ctx_, &buf_, &buf_sz_); - ASSERT_GE(status, 0) << "webm_read_frame failed"; - ++frame_; - if (status == 1) { - end_of_file_ = true; - } - } while (!webm_ctx_->is_key_frame && !end_of_file_); - } - - const uint8_t *cxdata() const override { - return end_of_file_ ? nullptr : buf_; - } - size_t frame_size() const override { return buf_sz_; } - unsigned int frame_number() const override { return frame_; } - - protected: - std::string file_name_; - VpxInputContext *vpx_ctx_; - WebmInputContext *webm_ctx_; - uint8_t *buf_; - size_t buf_sz_; - unsigned int frame_; - bool end_of_file_; -}; - -} // namespace libvpx_test - -#endif // VPX_TEST_WEBM_VIDEO_SOURCE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/y4m_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/y4m_test.cc deleted file mode 100644 index 3865880b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/y4m_test.cc +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "gtest/gtest.h" - -#include "./vpx_config.h" -#include "./y4menc.h" -#include "test/md5_helper.h" -#include "test/util.h" -#include "test/y4m_video_source.h" - -namespace { - -using std::string; - -static const unsigned int kWidth = 160; -static const unsigned int kHeight = 90; -static const unsigned int kFrames = 10; - -struct Y4mTestParam { - const char *filename; - unsigned int bit_depth; - vpx_img_fmt format; - const char *md5raw; -}; - -const Y4mTestParam kY4mTestVectors[] = { - { "park_joy_90p_8_420.y4m", 8, VPX_IMG_FMT_I420, - "e5406275b9fc6bb3436c31d4a05c1cab" }, - { "park_joy_90p_8_422.y4m", 8, VPX_IMG_FMT_I422, - "284a47a47133b12884ec3a14e959a0b6" }, - { "park_joy_90p_8_444.y4m", 8, VPX_IMG_FMT_I444, - "90517ff33843d85de712fd4fe60dbed0" }, - { "park_joy_90p_10_420_20f.y4m", 10, VPX_IMG_FMT_I42016, - "2f56ab9809269f074df7e3daf1ce0be6" }, - { "park_joy_90p_10_422_20f.y4m", 10, VPX_IMG_FMT_I42216, - "1b5c73d2e8e8c4e02dc4889ecac41c83" }, - { "park_joy_90p_10_444_20f.y4m", 10, VPX_IMG_FMT_I44416, - "ec4ab5be53195c5b838d1d19e1bc2674" }, - { "park_joy_90p_12_420_20f.y4m", 12, VPX_IMG_FMT_I42016, - "3370856c8ddebbd1f9bb2e66f97677f4" }, - { "park_joy_90p_12_422_20f.y4m", 12, VPX_IMG_FMT_I42216, - "4eab364318dd8201acbb182e43bd4966" }, - { "park_joy_90p_12_444_20f.y4m", 12, VPX_IMG_FMT_I44416, - "f189dfbbd92119fc8e5f211a550166be" }, -}; - -static void write_image_file(const vpx_image_t *img, FILE *file) { - int plane, y; - for (plane = 0; plane < 3; ++plane) { - const unsigned char *buf = img->planes[plane]; - const int stride = img->stride[plane]; - const int bytes_per_sample = (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1; - const int h = - (plane ? (img->d_h + img->y_chroma_shift) >> img->y_chroma_shift - : img->d_h); - const int w = - (plane ? (img->d_w + img->x_chroma_shift) >> img->x_chroma_shift - : img->d_w); - for (y = 0; y < h; ++y) { - fwrite(buf, bytes_per_sample, w, file); - buf += stride; - } - } -} - -class Y4mVideoSourceTest : public ::testing::TestWithParam, - public ::libvpx_test::Y4mVideoSource { - protected: - Y4mVideoSourceTest() : Y4mVideoSource("", 0, 0) {} - - ~Y4mVideoSourceTest() override { CloseSource(); } - - virtual void Init(const std::string &file_name, int limit) { - file_name_ = file_name; - start_ = 0; - limit_ = limit; - frame_ = 0; - Begin(); - } - - // Checks y4m header information - void HeaderChecks(unsigned int bit_depth, vpx_img_fmt_t fmt) { - ASSERT_NE(input_file_, nullptr); - ASSERT_EQ(y4m_.pic_w, (int)kWidth); - ASSERT_EQ(y4m_.pic_h, (int)kHeight); - ASSERT_EQ(img()->d_w, kWidth); - ASSERT_EQ(img()->d_h, kHeight); - ASSERT_EQ(y4m_.bit_depth, bit_depth); - ASSERT_EQ(y4m_.vpx_fmt, fmt); - if (fmt == VPX_IMG_FMT_I420 || fmt == VPX_IMG_FMT_I42016) { - ASSERT_EQ(y4m_.bps, (int)y4m_.bit_depth * 3 / 2); - ASSERT_EQ(img()->x_chroma_shift, 1U); - ASSERT_EQ(img()->y_chroma_shift, 1U); - } - if (fmt == VPX_IMG_FMT_I422 || fmt == VPX_IMG_FMT_I42216) { - ASSERT_EQ(y4m_.bps, (int)y4m_.bit_depth * 2); - ASSERT_EQ(img()->x_chroma_shift, 1U); - ASSERT_EQ(img()->y_chroma_shift, 0U); - } - if (fmt == VPX_IMG_FMT_I444 || fmt == VPX_IMG_FMT_I44416) { - ASSERT_EQ(y4m_.bps, (int)y4m_.bit_depth * 3); - ASSERT_EQ(img()->x_chroma_shift, 0U); - ASSERT_EQ(img()->y_chroma_shift, 0U); - } - } - - // Checks MD5 of the raw frame data - void Md5Check(const string &expected_md5) { - ASSERT_NE(input_file_, nullptr); - libvpx_test::MD5 md5; - for (unsigned int i = start_; i < limit_; i++) { - md5.Add(img()); - Next(); - } - ASSERT_EQ(string(md5.Get()), expected_md5); - } -}; - -TEST_P(Y4mVideoSourceTest, SourceTest) { - const Y4mTestParam t = GetParam(); - Init(t.filename, kFrames); - HeaderChecks(t.bit_depth, t.format); - Md5Check(t.md5raw); -} - -INSTANTIATE_TEST_SUITE_P(C, Y4mVideoSourceTest, - ::testing::ValuesIn(kY4mTestVectors)); - -class Y4mVideoWriteTest : public Y4mVideoSourceTest { - protected: - Y4mVideoWriteTest() : tmpfile_(nullptr) {} - - ~Y4mVideoWriteTest() override { - delete tmpfile_; - input_file_ = nullptr; - } - - void ReplaceInputFile(FILE *input_file) { - CloseSource(); - frame_ = 0; - input_file_ = input_file; - rewind(input_file_); - ReadSourceToStart(); - } - - // Writes out a y4m file and then reads it back - void WriteY4mAndReadBack() { - ASSERT_NE(input_file_, nullptr); - char buf[Y4M_BUFFER_SIZE] = { 0 }; - const struct VpxRational framerate = { y4m_.fps_n, y4m_.fps_d }; - tmpfile_ = new libvpx_test::TempOutFile; - ASSERT_NE(tmpfile_->file(), nullptr); - y4m_write_file_header(buf, sizeof(buf), kWidth, kHeight, &framerate, - y4m_.vpx_fmt, y4m_.bit_depth); - fputs(buf, tmpfile_->file()); - for (unsigned int i = start_; i < limit_; i++) { - y4m_write_frame_header(buf, sizeof(buf)); - fputs(buf, tmpfile_->file()); - write_image_file(img(), tmpfile_->file()); - Next(); - } - ReplaceInputFile(tmpfile_->file()); - } - - void Init(const std::string &file_name, int limit) override { - Y4mVideoSourceTest::Init(file_name, limit); - WriteY4mAndReadBack(); - } - libvpx_test::TempOutFile *tmpfile_; -}; - -TEST_P(Y4mVideoWriteTest, WriteTest) { - const Y4mTestParam t = GetParam(); - Init(t.filename, kFrames); - HeaderChecks(t.bit_depth, t.format); - Md5Check(t.md5raw); -} - -INSTANTIATE_TEST_SUITE_P(C, Y4mVideoWriteTest, - ::testing::ValuesIn(kY4mTestVectors)); - -static const char kY4MRegularHeader[] = - "YUV4MPEG2 W4 H4 F30:1 Ip A0:0 C420jpeg XYSCSS=420JPEG\n" - "FRAME\n" - "012345678912345601230123"; - -TEST(Y4MHeaderTest, RegularHeader) { - libvpx_test::TempOutFile f; - ASSERT_NE(f.file(), nullptr); - fwrite(kY4MRegularHeader, 1, sizeof(kY4MRegularHeader), f.file()); - fflush(f.file()); - EXPECT_EQ(0, fseek(f.file(), 0, 0)); - - y4m_input y4m; - EXPECT_EQ(y4m_input_open(&y4m, f.file(), /*skip_buffer=*/nullptr, - /*num_skip=*/0, /*only_420=*/0), - 0); - EXPECT_EQ(y4m.pic_w, 4); - EXPECT_EQ(y4m.pic_h, 4); - EXPECT_EQ(y4m.fps_n, 30); - EXPECT_EQ(y4m.fps_d, 1); - EXPECT_EQ(y4m.interlace, 'p'); - EXPECT_EQ(strcmp("420jpeg", y4m.chroma_type), 0); - y4m_input_close(&y4m); -} - -// Testing that headers over 100 characters can be parsed. -static const char kY4MLongHeader[] = - "YUV4MPEG2 W4 H4 F30:1 Ip A0:0 C420jpeg XYSCSS=420JPEG " - "XCOLORRANGE=LIMITED XSOME_UNKNOWN_METADATA XOTHER_UNKNOWN_METADATA\n" - "FRAME\n" - "012345678912345601230123"; - -TEST(Y4MHeaderTest, LongHeader) { - libvpx_test::TempOutFile f; - ASSERT_NE(f.file(), nullptr); - fwrite(kY4MLongHeader, 1, sizeof(kY4MLongHeader), f.file()); - fflush(f.file()); - EXPECT_EQ(fseek(f.file(), 0, 0), 0); - - y4m_input y4m; - EXPECT_EQ(y4m_input_open(&y4m, f.file(), /*skip_buffer=*/nullptr, - /*num_skip=*/0, /*only_420=*/0), - 0); - EXPECT_EQ(y4m.pic_w, 4); - EXPECT_EQ(y4m.pic_h, 4); - EXPECT_EQ(y4m.fps_n, 30); - EXPECT_EQ(y4m.fps_d, 1); - EXPECT_EQ(y4m.interlace, 'p'); - EXPECT_EQ(strcmp("420jpeg", y4m.chroma_type), 0); - y4m_input_close(&y4m); -} - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/y4m_video_source.h b/presentation/src/main/cpp/third_party/libvpx/test/y4m_video_source.h deleted file mode 100644 index e43e37d9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/y4m_video_source.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_TEST_Y4M_VIDEO_SOURCE_H_ -#define VPX_TEST_Y4M_VIDEO_SOURCE_H_ -#include -#include -#include - -#include "test/video_source.h" -#include "./y4minput.h" - -namespace libvpx_test { - -// This class extends VideoSource to allow parsing of raw yv12 -// so that we can do actual file encodes. -class Y4mVideoSource : public VideoSource { - public: - Y4mVideoSource(const std::string &file_name, unsigned int start, int limit) - : file_name_(file_name), input_file_(nullptr), img_(new vpx_image_t()), - start_(start), limit_(limit), frame_(0), framerate_numerator_(0), - framerate_denominator_(0), y4m_() {} - - ~Y4mVideoSource() override { - vpx_img_free(img_.get()); - CloseSource(); - } - - virtual void OpenSource() { - CloseSource(); - input_file_ = OpenTestDataFile(file_name_); - ASSERT_NE(input_file_, nullptr) - << "Input file open failed. Filename: " << file_name_; - } - - virtual void ReadSourceToStart() { - ASSERT_NE(input_file_, nullptr); - ASSERT_FALSE(y4m_input_open(&y4m_, input_file_, nullptr, 0, 0)); - framerate_numerator_ = y4m_.fps_n; - framerate_denominator_ = y4m_.fps_d; - frame_ = 0; - for (unsigned int i = 0; i < start_; i++) { - Next(); - } - FillFrame(); - } - - void Begin() override { - OpenSource(); - ReadSourceToStart(); - } - - void Next() override { - ++frame_; - FillFrame(); - } - - vpx_image_t *img() const override { - return (frame_ < limit_) ? img_.get() : nullptr; - } - - // Models a stream where Timebase = 1/FPS, so pts == frame. - vpx_codec_pts_t pts() const override { return frame_; } - - unsigned long duration() const override { return 1; } - - vpx_rational_t timebase() const override { - const vpx_rational_t t = { framerate_denominator_, framerate_numerator_ }; - return t; - } - - unsigned int frame() const override { return frame_; } - - unsigned int limit() const override { return limit_; } - - virtual void FillFrame() { - ASSERT_NE(input_file_, nullptr); - // Read a frame from input_file. - y4m_input_fetch_frame(&y4m_, input_file_, img_.get()); - } - - // Swap buffers with another y4m source. This allows reading a new frame - // while keeping the old frame around. A whole Y4mSource is required and - // not just a vpx_image_t because of how the y4m reader manipulates - // vpx_image_t internals, - void SwapBuffers(Y4mVideoSource *other) { - std::swap(other->y4m_.dst_buf, y4m_.dst_buf); - vpx_image_t *tmp; - tmp = other->img_.release(); - other->img_.reset(img_.release()); - img_.reset(tmp); - } - - protected: - void CloseSource() { - y4m_input_close(&y4m_); - y4m_ = y4m_input(); - if (input_file_ != nullptr) { - fclose(input_file_); - input_file_ = nullptr; - } - } - - std::string file_name_; - FILE *input_file_; - std::unique_ptr img_; - unsigned int start_; - unsigned int limit_; - unsigned int frame_; - int framerate_numerator_; - int framerate_denominator_; - y4m_input y4m_; -}; - -} // namespace libvpx_test - -#endif // VPX_TEST_Y4M_VIDEO_SOURCE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/test/yuv_temporal_filter_test.cc b/presentation/src/main/cpp/third_party/libvpx/test/yuv_temporal_filter_test.cc deleted file mode 100644 index 45fb7860..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/yuv_temporal_filter_test.cc +++ /dev/null @@ -1,727 +0,0 @@ -/* - * Copyright (c) 2019 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "gtest/gtest.h" - -#include "./vp9_rtcd.h" -#include "test/acm_random.h" -#include "test/buffer.h" -#include "test/register_state_check.h" -#include "vpx_config.h" -#include "vpx_ports/vpx_timer.h" - -namespace { - -using ::libvpx_test::ACMRandom; -using ::libvpx_test::Buffer; - -typedef void (*YUVTemporalFilterFunc)( - const uint8_t *y_src, int y_src_stride, const uint8_t *y_pre, - int y_pre_stride, const uint8_t *u_src, const uint8_t *v_src, - int uv_src_stride, const uint8_t *u_pre, const uint8_t *v_pre, - int uv_pre_stride, unsigned int block_width, unsigned int block_height, - int ss_x, int ss_y, int strength, const int *const blk_fw, int use_32x32, - uint32_t *y_accumulator, uint16_t *y_count, uint32_t *u_accumulator, - uint16_t *u_count, uint32_t *v_accumulator, uint16_t *v_count); - -struct TemporalFilterWithBd { - TemporalFilterWithBd(YUVTemporalFilterFunc func, int bitdepth) - : temporal_filter(func), bd(bitdepth) {} - - YUVTemporalFilterFunc temporal_filter; - int bd; -}; - -std::ostream &operator<<(std::ostream &os, const TemporalFilterWithBd &tf) { - return os << "Bitdepth: " << tf.bd; -} - -int GetFilterWeight(unsigned int row, unsigned int col, - unsigned int block_height, unsigned int block_width, - const int *const blk_fw, int use_32x32) { - if (use_32x32) { - return blk_fw[0]; - } - - return blk_fw[2 * (row >= block_height / 2) + (col >= block_width / 2)]; -} - -template -int GetModIndex(int sum_dist, int index, int rounding, int strength, - int filter_weight) { - int mod = sum_dist * 3 / index; - mod += rounding; - mod >>= strength; - - mod = VPXMIN(16, mod); - - mod = 16 - mod; - mod *= filter_weight; - - return mod; -} - -template <> -int GetModIndex(int sum_dist, int index, int rounding, int strength, - int filter_weight) { - unsigned int index_mult[14] = { 0, 0, 0, 0, 49152, - 39322, 32768, 28087, 24576, 21846, - 19661, 17874, 0, 15124 }; - - assert(index >= 0 && index <= 13); - assert(index_mult[index] != 0); - - int mod = (clamp(sum_dist, 0, UINT16_MAX) * index_mult[index]) >> 16; - mod += rounding; - mod >>= strength; - - mod = VPXMIN(16, mod); - - mod = 16 - mod; - mod *= filter_weight; - - return mod; -} - -template <> -int GetModIndex(int sum_dist, int index, int rounding, int strength, - int filter_weight) { - int64_t index_mult[14] = { 0U, 0U, 0U, 0U, - 3221225472U, 2576980378U, 2147483648U, 1840700270U, - 1610612736U, 1431655766U, 1288490189U, 1171354718U, - 0U, 991146300U }; - - assert(index >= 0 && index <= 13); - assert(index_mult[index] != 0); - - int mod = static_cast((sum_dist * index_mult[index]) >> 32); - mod += rounding; - mod >>= strength; - - mod = VPXMIN(16, mod); - - mod = 16 - mod; - mod *= filter_weight; - - return mod; -} - -template -void ApplyReferenceFilter( - const Buffer &y_src, const Buffer &y_pre, - const Buffer &u_src, const Buffer &v_src, - const Buffer &u_pre, const Buffer &v_pre, - unsigned int block_width, unsigned int block_height, int ss_x, int ss_y, - int strength, const int *const blk_fw, int use_32x32, - Buffer *y_accumulator, Buffer *y_counter, - Buffer *u_accumulator, Buffer *u_counter, - Buffer *v_accumulator, Buffer *v_counter) { - const PixelType *y_src_ptr = y_src.TopLeftPixel(); - const PixelType *y_pre_ptr = y_pre.TopLeftPixel(); - const PixelType *u_src_ptr = u_src.TopLeftPixel(); - const PixelType *u_pre_ptr = u_pre.TopLeftPixel(); - const PixelType *v_src_ptr = v_src.TopLeftPixel(); - const PixelType *v_pre_ptr = v_pre.TopLeftPixel(); - - const int uv_block_width = block_width >> ss_x, - uv_block_height = block_height >> ss_y; - const int y_src_stride = y_src.stride(), y_pre_stride = y_pre.stride(); - const int uv_src_stride = u_src.stride(), uv_pre_stride = u_pre.stride(); - const int y_diff_stride = block_width, uv_diff_stride = uv_block_width; - - Buffer y_dif = Buffer(block_width, block_height, 0); - Buffer u_dif = Buffer(uv_block_width, uv_block_height, 0); - Buffer v_dif = Buffer(uv_block_width, uv_block_height, 0); - - ASSERT_TRUE(y_dif.Init()); - ASSERT_TRUE(u_dif.Init()); - ASSERT_TRUE(v_dif.Init()); - y_dif.Set(0); - u_dif.Set(0); - v_dif.Set(0); - - int *y_diff_ptr = y_dif.TopLeftPixel(); - int *u_diff_ptr = u_dif.TopLeftPixel(); - int *v_diff_ptr = v_dif.TopLeftPixel(); - - uint32_t *y_accum = y_accumulator->TopLeftPixel(); - uint32_t *u_accum = u_accumulator->TopLeftPixel(); - uint32_t *v_accum = v_accumulator->TopLeftPixel(); - uint16_t *y_count = y_counter->TopLeftPixel(); - uint16_t *u_count = u_counter->TopLeftPixel(); - uint16_t *v_count = v_counter->TopLeftPixel(); - - const int y_accum_stride = y_accumulator->stride(); - const int u_accum_stride = u_accumulator->stride(); - const int v_accum_stride = v_accumulator->stride(); - const int y_count_stride = y_counter->stride(); - const int u_count_stride = u_counter->stride(); - const int v_count_stride = v_counter->stride(); - - const int rounding = (1 << strength) >> 1; - - // Get the square diffs - for (int row = 0; row < static_cast(block_height); row++) { - for (int col = 0; col < static_cast(block_width); col++) { - const int diff = y_src_ptr[row * y_src_stride + col] - - y_pre_ptr[row * y_pre_stride + col]; - y_diff_ptr[row * y_diff_stride + col] = diff * diff; - } - } - - for (int row = 0; row < uv_block_height; row++) { - for (int col = 0; col < uv_block_width; col++) { - const int u_diff = u_src_ptr[row * uv_src_stride + col] - - u_pre_ptr[row * uv_pre_stride + col]; - const int v_diff = v_src_ptr[row * uv_src_stride + col] - - v_pre_ptr[row * uv_pre_stride + col]; - u_diff_ptr[row * uv_diff_stride + col] = u_diff * u_diff; - v_diff_ptr[row * uv_diff_stride + col] = v_diff * v_diff; - } - } - - // Apply the filter to luma - for (int row = 0; row < static_cast(block_height); row++) { - for (int col = 0; col < static_cast(block_width); col++) { - const int uv_row = row >> ss_y; - const int uv_col = col >> ss_x; - const int filter_weight = GetFilterWeight(row, col, block_height, - block_width, blk_fw, use_32x32); - - // First we get the modifier for the current y pixel - const int y_pixel = y_pre_ptr[row * y_pre_stride + col]; - int y_num_used = 0; - int y_mod = 0; - - // Sum the neighboring 3x3 y pixels - for (int row_step = -1; row_step <= 1; row_step++) { - for (int col_step = -1; col_step <= 1; col_step++) { - const int sub_row = row + row_step; - const int sub_col = col + col_step; - - if (sub_row >= 0 && sub_row < static_cast(block_height) && - sub_col >= 0 && sub_col < static_cast(block_width)) { - y_mod += y_diff_ptr[sub_row * y_diff_stride + sub_col]; - y_num_used++; - } - } - } - - // Sum the corresponding uv pixels to the current y modifier - // Note we are rounding down instead of rounding to the nearest pixel. - y_mod += u_diff_ptr[uv_row * uv_diff_stride + uv_col]; - y_mod += v_diff_ptr[uv_row * uv_diff_stride + uv_col]; - - y_num_used += 2; - - // Set the modifier - y_mod = GetModIndex(y_mod, y_num_used, rounding, strength, - filter_weight); - - // Accumulate the result - y_count[row * y_count_stride + col] += y_mod; - y_accum[row * y_accum_stride + col] += y_mod * y_pixel; - } - } - - // Apply the filter to chroma - for (int uv_row = 0; uv_row < uv_block_height; uv_row++) { - for (int uv_col = 0; uv_col < uv_block_width; uv_col++) { - const int y_row = uv_row << ss_y; - const int y_col = uv_col << ss_x; - const int filter_weight = GetFilterWeight( - uv_row, uv_col, uv_block_height, uv_block_width, blk_fw, use_32x32); - - const int u_pixel = u_pre_ptr[uv_row * uv_pre_stride + uv_col]; - const int v_pixel = v_pre_ptr[uv_row * uv_pre_stride + uv_col]; - - int uv_num_used = 0; - int u_mod = 0, v_mod = 0; - - // Sum the neighboring 3x3 chromal pixels to the chroma modifier - for (int row_step = -1; row_step <= 1; row_step++) { - for (int col_step = -1; col_step <= 1; col_step++) { - const int sub_row = uv_row + row_step; - const int sub_col = uv_col + col_step; - - if (sub_row >= 0 && sub_row < uv_block_height && sub_col >= 0 && - sub_col < uv_block_width) { - u_mod += u_diff_ptr[sub_row * uv_diff_stride + sub_col]; - v_mod += v_diff_ptr[sub_row * uv_diff_stride + sub_col]; - uv_num_used++; - } - } - } - - // Sum all the luma pixels associated with the current luma pixel - for (int row_step = 0; row_step < 1 + ss_y; row_step++) { - for (int col_step = 0; col_step < 1 + ss_x; col_step++) { - const int sub_row = y_row + row_step; - const int sub_col = y_col + col_step; - const int y_diff = y_diff_ptr[sub_row * y_diff_stride + sub_col]; - - u_mod += y_diff; - v_mod += y_diff; - uv_num_used++; - } - } - - // Set the modifier - u_mod = GetModIndex(u_mod, uv_num_used, rounding, strength, - filter_weight); - v_mod = GetModIndex(v_mod, uv_num_used, rounding, strength, - filter_weight); - - // Accumulate the result - u_count[uv_row * u_count_stride + uv_col] += u_mod; - u_accum[uv_row * u_accum_stride + uv_col] += u_mod * u_pixel; - v_count[uv_row * v_count_stride + uv_col] += v_mod; - v_accum[uv_row * v_accum_stride + uv_col] += v_mod * v_pixel; - } - } -} - -class YUVTemporalFilterTest - : public ::testing::TestWithParam { - public: - void SetUp() override { - filter_func_ = GetParam().temporal_filter; - bd_ = GetParam().bd; - use_highbd_ = (bd_ != 8); - - rnd_.Reset(ACMRandom::DeterministicSeed()); - saturate_test_ = 0; - num_repeats_ = 10; - - ASSERT_TRUE(bd_ == 8 || bd_ == 10 || bd_ == 12); - } - - protected: - template - void CompareTestWithParam(int width, int height, int ss_x, int ss_y, - int filter_strength, int use_32x32, - const int *filter_weight); - template - void RunTestFilterWithParam(int width, int height, int ss_x, int ss_y, - int filter_strength, int use_32x32, - const int *filter_weight); - YUVTemporalFilterFunc filter_func_; - ACMRandom rnd_; - int saturate_test_; - int num_repeats_; - int use_highbd_; - int bd_; -}; - -template -void YUVTemporalFilterTest::CompareTestWithParam(int width, int height, - int ss_x, int ss_y, - int filter_strength, - int use_32x32, - const int *filter_weight) { - const int uv_width = width >> ss_x, uv_height = height >> ss_y; - - Buffer y_src = Buffer(width, height, 0); - Buffer y_pre = Buffer(width, height, 0); - Buffer y_count_ref = Buffer(width, height, 0); - Buffer y_accum_ref = Buffer(width, height, 0); - Buffer y_count_tst = Buffer(width, height, 0); - Buffer y_accum_tst = Buffer(width, height, 0); - - Buffer u_src = Buffer(uv_width, uv_height, 0); - Buffer u_pre = Buffer(uv_width, uv_height, 0); - Buffer u_count_ref = Buffer(uv_width, uv_height, 0); - Buffer u_accum_ref = Buffer(uv_width, uv_height, 0); - Buffer u_count_tst = Buffer(uv_width, uv_height, 0); - Buffer u_accum_tst = Buffer(uv_width, uv_height, 0); - - Buffer v_src = Buffer(uv_width, uv_height, 0); - Buffer v_pre = Buffer(uv_width, uv_height, 0); - Buffer v_count_ref = Buffer(uv_width, uv_height, 0); - Buffer v_accum_ref = Buffer(uv_width, uv_height, 0); - Buffer v_count_tst = Buffer(uv_width, uv_height, 0); - Buffer v_accum_tst = Buffer(uv_width, uv_height, 0); - - ASSERT_TRUE(y_src.Init()); - ASSERT_TRUE(y_pre.Init()); - ASSERT_TRUE(y_count_ref.Init()); - ASSERT_TRUE(y_accum_ref.Init()); - ASSERT_TRUE(y_count_tst.Init()); - ASSERT_TRUE(y_accum_tst.Init()); - ASSERT_TRUE(u_src.Init()); - ASSERT_TRUE(u_pre.Init()); - ASSERT_TRUE(u_count_ref.Init()); - ASSERT_TRUE(u_accum_ref.Init()); - ASSERT_TRUE(u_count_tst.Init()); - ASSERT_TRUE(u_accum_tst.Init()); - - ASSERT_TRUE(v_src.Init()); - ASSERT_TRUE(v_pre.Init()); - ASSERT_TRUE(v_count_ref.Init()); - ASSERT_TRUE(v_accum_ref.Init()); - ASSERT_TRUE(v_count_tst.Init()); - ASSERT_TRUE(v_accum_tst.Init()); - - y_accum_ref.Set(0); - y_accum_tst.Set(0); - y_count_ref.Set(0); - y_count_tst.Set(0); - u_accum_ref.Set(0); - u_accum_tst.Set(0); - u_count_ref.Set(0); - u_count_tst.Set(0); - v_accum_ref.Set(0); - v_accum_tst.Set(0); - v_count_ref.Set(0); - v_count_tst.Set(0); - - for (int repeats = 0; repeats < num_repeats_; repeats++) { - if (saturate_test_) { - const int max_val = (1 << bd_) - 1; - y_src.Set(max_val); - y_pre.Set(0); - u_src.Set(max_val); - u_pre.Set(0); - v_src.Set(max_val); - v_pre.Set(0); - } else { - y_src.Set(&rnd_, 0, 7 << (bd_ - 8)); - y_pre.Set(&rnd_, 0, 7 << (bd_ - 8)); - u_src.Set(&rnd_, 0, 7 << (bd_ - 8)); - u_pre.Set(&rnd_, 0, 7 << (bd_ - 8)); - v_src.Set(&rnd_, 0, 7 << (bd_ - 8)); - v_pre.Set(&rnd_, 0, 7 << (bd_ - 8)); - } - - ApplyReferenceFilter( - y_src, y_pre, u_src, v_src, u_pre, v_pre, width, height, ss_x, ss_y, - filter_strength, filter_weight, use_32x32, &y_accum_ref, &y_count_ref, - &u_accum_ref, &u_count_ref, &v_accum_ref, &v_count_ref); - - ASM_REGISTER_STATE_CHECK(filter_func_( - reinterpret_cast(y_src.TopLeftPixel()), y_src.stride(), - reinterpret_cast(y_pre.TopLeftPixel()), y_pre.stride(), - reinterpret_cast(u_src.TopLeftPixel()), - reinterpret_cast(v_src.TopLeftPixel()), u_src.stride(), - reinterpret_cast(u_pre.TopLeftPixel()), - reinterpret_cast(v_pre.TopLeftPixel()), u_pre.stride(), - width, height, ss_x, ss_y, filter_strength, filter_weight, use_32x32, - y_accum_tst.TopLeftPixel(), y_count_tst.TopLeftPixel(), - u_accum_tst.TopLeftPixel(), u_count_tst.TopLeftPixel(), - v_accum_tst.TopLeftPixel(), v_count_tst.TopLeftPixel())); - - EXPECT_TRUE(y_accum_tst.CheckValues(y_accum_ref)); - EXPECT_TRUE(y_count_tst.CheckValues(y_count_ref)); - EXPECT_TRUE(u_accum_tst.CheckValues(u_accum_ref)); - EXPECT_TRUE(u_count_tst.CheckValues(u_count_ref)); - EXPECT_TRUE(v_accum_tst.CheckValues(v_accum_ref)); - EXPECT_TRUE(v_count_tst.CheckValues(v_count_ref)); - - if (HasFailure()) { - if (use_32x32) { - printf("SS_X: %d, SS_Y: %d, Strength: %d, Weight: %d\n", ss_x, ss_y, - filter_strength, *filter_weight); - } else { - printf("SS_X: %d, SS_Y: %d, Strength: %d, Weights: %d,%d,%d,%d\n", ss_x, - ss_y, filter_strength, filter_weight[0], filter_weight[1], - filter_weight[2], filter_weight[3]); - } - y_accum_tst.PrintDifference(y_accum_ref); - y_count_tst.PrintDifference(y_count_ref); - u_accum_tst.PrintDifference(u_accum_ref); - u_count_tst.PrintDifference(u_count_ref); - v_accum_tst.PrintDifference(v_accum_ref); - v_count_tst.PrintDifference(v_count_ref); - - return; - } - } -} - -template -void YUVTemporalFilterTest::RunTestFilterWithParam(int width, int height, - int ss_x, int ss_y, - int filter_strength, - int use_32x32, - const int *filter_weight) { - const int uv_width = width >> ss_x, uv_height = height >> ss_y; - - Buffer y_src = Buffer(width, height, 0); - Buffer y_pre = Buffer(width, height, 0); - Buffer y_count = Buffer(width, height, 0); - Buffer y_accum = Buffer(width, height, 0); - - Buffer u_src = Buffer(uv_width, uv_height, 0); - Buffer u_pre = Buffer(uv_width, uv_height, 0); - Buffer u_count = Buffer(uv_width, uv_height, 0); - Buffer u_accum = Buffer(uv_width, uv_height, 0); - - Buffer v_src = Buffer(uv_width, uv_height, 0); - Buffer v_pre = Buffer(uv_width, uv_height, 0); - Buffer v_count = Buffer(uv_width, uv_height, 0); - Buffer v_accum = Buffer(uv_width, uv_height, 0); - - ASSERT_TRUE(y_src.Init()); - ASSERT_TRUE(y_pre.Init()); - ASSERT_TRUE(y_count.Init()); - ASSERT_TRUE(y_accum.Init()); - - ASSERT_TRUE(u_src.Init()); - ASSERT_TRUE(u_pre.Init()); - ASSERT_TRUE(u_count.Init()); - ASSERT_TRUE(u_accum.Init()); - - ASSERT_TRUE(v_src.Init()); - ASSERT_TRUE(v_pre.Init()); - ASSERT_TRUE(v_count.Init()); - ASSERT_TRUE(v_accum.Init()); - - y_accum.Set(0); - y_count.Set(0); - - u_accum.Set(0); - u_count.Set(0); - - v_accum.Set(0); - v_count.Set(0); - - y_src.Set(&rnd_, 0, 7 << (bd_ - 8)); - y_pre.Set(&rnd_, 0, 7 << (bd_ - 8)); - u_src.Set(&rnd_, 0, 7 << (bd_ - 8)); - u_pre.Set(&rnd_, 0, 7 << (bd_ - 8)); - v_src.Set(&rnd_, 0, 7 << (bd_ - 8)); - v_pre.Set(&rnd_, 0, 7 << (bd_ - 8)); - - for (int repeats = 0; repeats < num_repeats_; repeats++) { - ASM_REGISTER_STATE_CHECK(filter_func_( - reinterpret_cast(y_src.TopLeftPixel()), y_src.stride(), - reinterpret_cast(y_pre.TopLeftPixel()), y_pre.stride(), - reinterpret_cast(u_src.TopLeftPixel()), - reinterpret_cast(v_src.TopLeftPixel()), u_src.stride(), - reinterpret_cast(u_pre.TopLeftPixel()), - reinterpret_cast(v_pre.TopLeftPixel()), u_pre.stride(), - width, height, ss_x, ss_y, filter_strength, filter_weight, use_32x32, - y_accum.TopLeftPixel(), y_count.TopLeftPixel(), u_accum.TopLeftPixel(), - u_count.TopLeftPixel(), v_accum.TopLeftPixel(), - v_count.TopLeftPixel())); - } -} - -TEST_P(YUVTemporalFilterTest, Use32x32) { - const int width = 32, height = 32; - const int use_32x32 = 1; - - for (int ss_x = 0; ss_x <= 1; ss_x++) { - for (int ss_y = 0; ss_y <= 1; ss_y++) { - for (int filter_strength = 0; filter_strength <= 6; - filter_strength += 2) { - for (int filter_weight = 0; filter_weight <= 2; filter_weight++) { - if (use_highbd_) { - const int adjusted_strength = filter_strength + 2 * (bd_ - 8); - CompareTestWithParam(width, height, ss_x, ss_y, - adjusted_strength, use_32x32, - &filter_weight); - } else { - CompareTestWithParam(width, height, ss_x, ss_y, - filter_strength, use_32x32, - &filter_weight); - } - ASSERT_FALSE(HasFailure()); - } - } - } - } -} - -TEST_P(YUVTemporalFilterTest, Use16x16) { - const int width = 32, height = 32; - const int use_32x32 = 0; - - for (int ss_x = 0; ss_x <= 1; ss_x++) { - for (int ss_y = 0; ss_y <= 1; ss_y++) { - for (int filter_idx = 0; filter_idx < 3 * 3 * 3 * 3; filter_idx++) { - // Set up the filter - int filter_weight[4]; - int filter_idx_cp = filter_idx; - for (int idx = 0; idx < 4; idx++) { - filter_weight[idx] = filter_idx_cp % 3; - filter_idx_cp /= 3; - } - - // Test each parameter - for (int filter_strength = 0; filter_strength <= 6; - filter_strength += 2) { - if (use_highbd_) { - const int adjusted_strength = filter_strength + 2 * (bd_ - 8); - CompareTestWithParam(width, height, ss_x, ss_y, - adjusted_strength, use_32x32, - filter_weight); - } else { - CompareTestWithParam(width, height, ss_x, ss_y, - filter_strength, use_32x32, - filter_weight); - } - - ASSERT_FALSE(HasFailure()); - } - } - } - } -} - -TEST_P(YUVTemporalFilterTest, SaturationTest) { - const int width = 32, height = 32; - const int use_32x32 = 1; - const int filter_weight = 1; - saturate_test_ = 1; - - for (int ss_x = 0; ss_x <= 1; ss_x++) { - for (int ss_y = 0; ss_y <= 1; ss_y++) { - for (int filter_strength = 0; filter_strength <= 6; - filter_strength += 2) { - if (use_highbd_) { - const int adjusted_strength = filter_strength + 2 * (bd_ - 8); - CompareTestWithParam(width, height, ss_x, ss_y, - adjusted_strength, use_32x32, - &filter_weight); - } else { - CompareTestWithParam(width, height, ss_x, ss_y, - filter_strength, use_32x32, - &filter_weight); - } - - ASSERT_FALSE(HasFailure()); - } - } - } -} - -TEST_P(YUVTemporalFilterTest, DISABLED_Speed) { - const int width = 32, height = 32; - num_repeats_ = 1000; - - for (int use_32x32 = 0; use_32x32 <= 1; use_32x32++) { - const int num_filter_weights = use_32x32 ? 3 : 3 * 3 * 3 * 3; - for (int ss_x = 0; ss_x <= 1; ss_x++) { - for (int ss_y = 0; ss_y <= 1; ss_y++) { - for (int filter_idx = 0; filter_idx < num_filter_weights; - filter_idx++) { - // Set up the filter - int filter_weight[4]; - int filter_idx_cp = filter_idx; - for (int idx = 0; idx < 4; idx++) { - filter_weight[idx] = filter_idx_cp % 3; - filter_idx_cp /= 3; - } - - // Test each parameter - for (int filter_strength = 0; filter_strength <= 6; - filter_strength += 2) { - vpx_usec_timer timer; - vpx_usec_timer_start(&timer); - - if (use_highbd_) { - RunTestFilterWithParam(width, height, ss_x, ss_y, - filter_strength, use_32x32, - filter_weight); - } else { - RunTestFilterWithParam(width, height, ss_x, ss_y, - filter_strength, use_32x32, - filter_weight); - } - - vpx_usec_timer_mark(&timer); - const int elapsed_time = - static_cast(vpx_usec_timer_elapsed(&timer)); - - printf( - "Bitdepth: %d, Use 32X32: %d, SS_X: %d, SS_Y: %d, Weight Idx: " - "%d, Strength: %d, Time: %5d\n", - bd_, use_32x32, ss_x, ss_y, filter_idx, filter_strength, - elapsed_time); - } - } - } - } - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -#define WRAP_HIGHBD_FUNC(func, bd) \ - void wrap_##func##_##bd( \ - const uint8_t *y_src, int y_src_stride, const uint8_t *y_pre, \ - int y_pre_stride, const uint8_t *u_src, const uint8_t *v_src, \ - int uv_src_stride, const uint8_t *u_pre, const uint8_t *v_pre, \ - int uv_pre_stride, unsigned int block_width, unsigned int block_height, \ - int ss_x, int ss_y, int strength, const int *const blk_fw, \ - int use_32x32, uint32_t *y_accumulator, uint16_t *y_count, \ - uint32_t *u_accumulator, uint16_t *u_count, uint32_t *v_accumulator, \ - uint16_t *v_count) { \ - func(reinterpret_cast(y_src), y_src_stride, \ - reinterpret_cast(y_pre), y_pre_stride, \ - reinterpret_cast(u_src), \ - reinterpret_cast(v_src), uv_src_stride, \ - reinterpret_cast(u_pre), \ - reinterpret_cast(v_pre), uv_pre_stride, \ - block_width, block_height, ss_x, ss_y, strength, blk_fw, use_32x32, \ - y_accumulator, y_count, u_accumulator, u_count, v_accumulator, \ - v_count); \ - } - -WRAP_HIGHBD_FUNC(vp9_highbd_apply_temporal_filter_c, 10) -WRAP_HIGHBD_FUNC(vp9_highbd_apply_temporal_filter_c, 12) - -INSTANTIATE_TEST_SUITE_P( - C, YUVTemporalFilterTest, - ::testing::Values( - TemporalFilterWithBd(&wrap_vp9_highbd_apply_temporal_filter_c_10, 10), - TemporalFilterWithBd(&wrap_vp9_highbd_apply_temporal_filter_c_12, 12))); -#if HAVE_SSE4_1 -WRAP_HIGHBD_FUNC(vp9_highbd_apply_temporal_filter_sse4_1, 10) -WRAP_HIGHBD_FUNC(vp9_highbd_apply_temporal_filter_sse4_1, 12) - -INSTANTIATE_TEST_SUITE_P( - SSE4_1, YUVTemporalFilterTest, - ::testing::Values( - TemporalFilterWithBd(&wrap_vp9_highbd_apply_temporal_filter_sse4_1_10, - 10), - TemporalFilterWithBd(&wrap_vp9_highbd_apply_temporal_filter_sse4_1_12, - 12))); -#endif // HAVE_SSE4_1 -#if HAVE_NEON -WRAP_HIGHBD_FUNC(vp9_highbd_apply_temporal_filter_neon, 10) -WRAP_HIGHBD_FUNC(vp9_highbd_apply_temporal_filter_neon, 12) - -INSTANTIATE_TEST_SUITE_P( - NEON, YUVTemporalFilterTest, - ::testing::Values( - TemporalFilterWithBd(&wrap_vp9_highbd_apply_temporal_filter_neon_10, - 10), - TemporalFilterWithBd(&wrap_vp9_highbd_apply_temporal_filter_neon_12, - 12))); -#endif // HAVE_NEON -#else -INSTANTIATE_TEST_SUITE_P( - C, YUVTemporalFilterTest, - ::testing::Values(TemporalFilterWithBd(&vp9_apply_temporal_filter_c, 8))); - -#if HAVE_SSE4_1 -INSTANTIATE_TEST_SUITE_P(SSE4_1, YUVTemporalFilterTest, - ::testing::Values(TemporalFilterWithBd( - &vp9_apply_temporal_filter_sse4_1, 8))); -#endif // HAVE_SSE4_1 -#if HAVE_NEON -INSTANTIATE_TEST_SUITE_P(NEON, YUVTemporalFilterTest, - ::testing::Values(TemporalFilterWithBd( - &vp9_apply_temporal_filter_neon, 8))); -#endif // HAVE_NEON -#endif // CONFIG_VP9_HIGHBITDEPTH - -} // namespace diff --git a/presentation/src/main/cpp/third_party/libvpx/test/yuv_video_source.h b/presentation/src/main/cpp/third_party/libvpx/test/yuv_video_source.h deleted file mode 100644 index bb5eec5b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/test/yuv_video_source.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_TEST_YUV_VIDEO_SOURCE_H_ -#define VPX_TEST_YUV_VIDEO_SOURCE_H_ - -#include -#include -#include - -#include "test/video_source.h" -#include "vpx/vpx_image.h" - -namespace libvpx_test { - -// This class extends VideoSource to allow parsing of raw YUV -// formats of various color sampling and bit-depths so that we can -// do actual file encodes. -class YUVVideoSource : public VideoSource { - public: - YUVVideoSource(const std::string &file_name, vpx_img_fmt format, - unsigned int width, unsigned int height, int rate_numerator, - int rate_denominator, unsigned int start, int limit) - : file_name_(file_name), input_file_(nullptr), img_(nullptr), - start_(start), limit_(limit), frame_(0), width_(0), height_(0), - format_(VPX_IMG_FMT_NONE), framerate_numerator_(rate_numerator), - framerate_denominator_(rate_denominator) { - // This initializes format_, raw_size_, width_, height_ and allocates img. - SetSize(width, height, format); - } - - ~YUVVideoSource() override { - vpx_img_free(img_); - if (input_file_) fclose(input_file_); - } - - void Begin() override { - if (input_file_) fclose(input_file_); - input_file_ = OpenTestDataFile(file_name_); - ASSERT_NE(input_file_, nullptr) - << "Input file open failed. Filename: " << file_name_; - if (start_) { - fseek(input_file_, static_cast(raw_size_) * start_, SEEK_SET); - } - - frame_ = start_; - FillFrame(); - } - - void Next() override { - ++frame_; - FillFrame(); - } - - vpx_image_t *img() const override { - return (frame_ < limit_) ? img_ : nullptr; - } - - // Models a stream where Timebase = 1/FPS, so pts == frame. - vpx_codec_pts_t pts() const override { return frame_; } - - unsigned long duration() const override { return 1; } - - vpx_rational_t timebase() const override { - const vpx_rational_t t = { framerate_denominator_, framerate_numerator_ }; - return t; - } - - unsigned int frame() const override { return frame_; } - - unsigned int limit() const override { return limit_; } - - virtual void SetSize(unsigned int width, unsigned int height, - vpx_img_fmt format) { - if (width != width_ || height != height_ || format != format_) { - vpx_img_free(img_); - img_ = vpx_img_alloc(nullptr, format, width, height, 1); - ASSERT_NE(img_, nullptr); - width_ = width; - height_ = height; - format_ = format; - switch (format) { - case VPX_IMG_FMT_NV12: - case VPX_IMG_FMT_I420: raw_size_ = width * height * 3 / 2; break; - case VPX_IMG_FMT_I422: raw_size_ = width * height * 2; break; - case VPX_IMG_FMT_I440: raw_size_ = width * height * 2; break; - case VPX_IMG_FMT_I444: raw_size_ = width * height * 3; break; - case VPX_IMG_FMT_I42016: raw_size_ = width * height * 3; break; - case VPX_IMG_FMT_I42216: raw_size_ = width * height * 4; break; - case VPX_IMG_FMT_I44016: raw_size_ = width * height * 4; break; - case VPX_IMG_FMT_I44416: raw_size_ = width * height * 6; break; - default: ASSERT_TRUE(0); - } - } - } - - virtual void FillFrame() { - ASSERT_NE(input_file_, nullptr); - // Read a frame from input_file. - if (fread(img_->img_data, raw_size_, 1, input_file_) == 0) { - limit_ = frame_; - } - } - - protected: - std::string file_name_; - FILE *input_file_; - vpx_image_t *img_; - size_t raw_size_; - unsigned int start_; - unsigned int limit_; - unsigned int frame_; - unsigned int width_; - unsigned int height_; - vpx_img_fmt format_; - int framerate_numerator_; - int framerate_denominator_; -}; - -} // namespace libvpx_test - -#endif // VPX_TEST_YUV_VIDEO_SOURCE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/README.libvpx b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/README.libvpx deleted file mode 100644 index 5f6b01b0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/README.libvpx +++ /dev/null @@ -1,29 +0,0 @@ -URL: https://github.com/google/googletest.git -Version: release-1.12.1 -License: BSD -License File: LICENSE - -Description: -Google's framework for writing C++ tests on a variety of platforms -(Linux, Mac OS X, Windows, Windows CE, Symbian, etc). Based on the -xUnit architecture. Supports automatic test discovery, a rich set of -assertions, user-defined assertions, death tests, fatal and non-fatal -failures, various options for running the tests, and XML test report -generation. - -Local Modifications: -- Remove everything but: - .clang-format - CONTRIBUTORS - googletest/ - include - README.md - src - LICENSE -- Move .clang-format, CONTRIBUTORS, and LICENSE into googletest/ -- In googletest/include/gtest/internal/custom/gtest-port.h, define - GTEST_HAS_NOTIFICATION_ as 1 and use a stub Notification class to fix - the mingw32 g++ compilation errors caused by the lack of std::mutex - and std::condition_variable in the and - headers if mingw32 is configured with the win32 threads option. See - https://stackoverflow.com/questions/17242516/mingw-w64-threads-posix-vs-win32 diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/gtest.mk b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/gtest.mk deleted file mode 100644 index 0de3113c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/gtest.mk +++ /dev/null @@ -1 +0,0 @@ -GTEST_SRCS-yes += src/gtest-all.cc diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/.clang-format b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/.clang-format deleted file mode 100644 index 5b9bfe6d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/.clang-format +++ /dev/null @@ -1,4 +0,0 @@ -# Run manually to reformat a file: -# clang-format -i --style=file -Language: Cpp -BasedOnStyle: Google diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/CONTRIBUTORS b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/CONTRIBUTORS deleted file mode 100644 index 77397a5b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/CONTRIBUTORS +++ /dev/null @@ -1,65 +0,0 @@ -# This file contains a list of people who've made non-trivial -# contribution to the Google C++ Testing Framework project. People -# who commit code to the project are encouraged to add their names -# here. Please keep the list sorted by first names. - -Ajay Joshi -Balázs Dán -Benoit Sigoure -Bharat Mediratta -Bogdan Piloca -Chandler Carruth -Chris Prince -Chris Taylor -Dan Egnor -Dave MacLachlan -David Anderson -Dean Sturtevant -Eric Roman -Gene Volovich -Hady Zalek -Hal Burch -Jeffrey Yasskin -Jim Keller -Joe Walnes -Jon Wray -Jói Sigurðsson -Keir Mierle -Keith Ray -Kenton Varda -Kostya Serebryany -Krystian Kuzniarek -Lev Makhlis -Manuel Klimek -Mario Tanev -Mark Paskin -Markus Heule -Martijn Vels -Matthew Simmons -Mika Raento -Mike Bland -Miklós Fazekas -Neal Norwitz -Nermin Ozkiranartli -Owen Carlsen -Paneendra Ba -Pasi Valminen -Patrick Hanna -Patrick Riley -Paul Menage -Peter Kaminski -Piotr Kaminski -Preston Jackson -Rainer Klaffenboeck -Russ Cox -Russ Rufer -Sean Mcafee -Sigurður Ásgeirsson -Sverre Sundsdal -Szymon Sobik -Takeshi Yoshino -Tracy Bialik -Vadim Berman -Vlad Losev -Wolfgang Klier -Zhanyong Wan diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/LICENSE b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/LICENSE deleted file mode 100644 index 1941a11f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright 2008, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/README.md b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/README.md deleted file mode 100644 index d26b309e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/README.md +++ /dev/null @@ -1,217 +0,0 @@ -### Generic Build Instructions - -#### Setup - -To build GoogleTest and your tests that use it, you need to tell your build -system where to find its headers and source files. The exact way to do it -depends on which build system you use, and is usually straightforward. - -### Build with CMake - -GoogleTest comes with a CMake build script -([CMakeLists.txt](https://github.com/google/googletest/blob/master/CMakeLists.txt)) -that can be used on a wide range of platforms ("C" stands for cross-platform.). -If you don't have CMake installed already, you can download it for free from -. - -CMake works by generating native makefiles or build projects that can be used in -the compiler environment of your choice. You can either build GoogleTest as a -standalone project or it can be incorporated into an existing CMake build for -another project. - -#### Standalone CMake Project - -When building GoogleTest as a standalone project, the typical workflow starts -with - -``` -git clone https://github.com/google/googletest.git -b release-1.11.0 -cd googletest # Main directory of the cloned repository. -mkdir build # Create a directory to hold the build output. -cd build -cmake .. # Generate native build scripts for GoogleTest. -``` - -The above command also includes GoogleMock by default. And so, if you want to -build only GoogleTest, you should replace the last command with - -``` -cmake .. -DBUILD_GMOCK=OFF -``` - -If you are on a \*nix system, you should now see a Makefile in the current -directory. Just type `make` to build GoogleTest. And then you can simply install -GoogleTest if you are a system administrator. - -``` -make -sudo make install # Install in /usr/local/ by default -``` - -If you use Windows and have Visual Studio installed, a `gtest.sln` file and -several `.vcproj` files will be created. You can then build them using Visual -Studio. - -On Mac OS X with Xcode installed, a `.xcodeproj` file will be generated. - -#### Incorporating Into An Existing CMake Project - -If you want to use GoogleTest in a project which already uses CMake, the easiest -way is to get installed libraries and headers. - -* Import GoogleTest by using `find_package` (or `pkg_check_modules`). For - example, if `find_package(GTest CONFIG REQUIRED)` succeeds, you can use the - libraries as `GTest::gtest`, `GTest::gmock`. - -And a more robust and flexible approach is to build GoogleTest as part of that -project directly. This is done by making the GoogleTest source code available to -the main build and adding it using CMake's `add_subdirectory()` command. This -has the significant advantage that the same compiler and linker settings are -used between GoogleTest and the rest of your project, so issues associated with -using incompatible libraries (eg debug/release), etc. are avoided. This is -particularly useful on Windows. Making GoogleTest's source code available to the -main build can be done a few different ways: - -* Download the GoogleTest source code manually and place it at a known - location. This is the least flexible approach and can make it more difficult - to use with continuous integration systems, etc. -* Embed the GoogleTest source code as a direct copy in the main project's - source tree. This is often the simplest approach, but is also the hardest to - keep up to date. Some organizations may not permit this method. -* Add GoogleTest as a git submodule or equivalent. This may not always be - possible or appropriate. Git submodules, for example, have their own set of - advantages and drawbacks. -* Use CMake to download GoogleTest as part of the build's configure step. This - approach doesn't have the limitations of the other methods. - -The last of the above methods is implemented with a small piece of CMake code -that downloads and pulls the GoogleTest code into the main build. - -Just add to your `CMakeLists.txt`: - -```cmake -include(FetchContent) -FetchContent_Declare( - googletest - # Specify the commit you depend on and update it regularly. - URL https://github.com/google/googletest/archive/e2239ee6043f73722e7aa812a459f54a28552929.zip -) -# For Windows: Prevent overriding the parent project's compiler/linker settings -set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) -FetchContent_MakeAvailable(googletest) - -# Now simply link against gtest or gtest_main as needed. Eg -add_executable(example example.cpp) -target_link_libraries(example gtest_main) -add_test(NAME example_test COMMAND example) -``` - -Note that this approach requires CMake 3.14 or later due to its use of the -`FetchContent_MakeAvailable()` command. - -##### Visual Studio Dynamic vs Static Runtimes - -By default, new Visual Studio projects link the C runtimes dynamically but -GoogleTest links them statically. This will generate an error that looks -something like the following: gtest.lib(gtest-all.obj) : error LNK2038: mismatch -detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value -'MDd_DynamicDebug' in main.obj - -GoogleTest already has a CMake option for this: `gtest_force_shared_crt` - -Enabling this option will make gtest link the runtimes dynamically too, and -match the project in which it is included. - -#### C++ Standard Version - -An environment that supports C++11 is required in order to successfully build -GoogleTest. One way to ensure this is to specify the standard in the top-level -project, for example by using the `set(CMAKE_CXX_STANDARD 11)` command. If this -is not feasible, for example in a C project using GoogleTest for validation, -then it can be specified by adding it to the options for cmake via the -`DCMAKE_CXX_FLAGS` option. - -### Tweaking GoogleTest - -GoogleTest can be used in diverse environments. The default configuration may -not work (or may not work well) out of the box in some environments. However, -you can easily tweak GoogleTest by defining control macros on the compiler -command line. Generally, these macros are named like `GTEST_XYZ` and you define -them to either 1 or 0 to enable or disable a certain feature. - -We list the most frequently used macros below. For a complete list, see file -[include/gtest/internal/gtest-port.h](https://github.com/google/googletest/blob/master/googletest/include/gtest/internal/gtest-port.h). - -### Multi-threaded Tests - -GoogleTest is thread-safe where the pthread library is available. After -`#include "gtest/gtest.h"`, you can check the -`GTEST_IS_THREADSAFE` macro to see whether this is the case (yes if the macro is -`#defined` to 1, no if it's undefined.). - -If GoogleTest doesn't correctly detect whether pthread is available in your -environment, you can force it with - - -DGTEST_HAS_PTHREAD=1 - -or - - -DGTEST_HAS_PTHREAD=0 - -When GoogleTest uses pthread, you may need to add flags to your compiler and/or -linker to select the pthread library, or you'll get link errors. If you use the -CMake script, this is taken care of for you. If you use your own build script, -you'll need to read your compiler and linker's manual to figure out what flags -to add. - -### As a Shared Library (DLL) - -GoogleTest is compact, so most users can build and link it as a static library -for the simplicity. You can choose to use GoogleTest as a shared library (known -as a DLL on Windows) if you prefer. - -To compile *gtest* as a shared library, add - - -DGTEST_CREATE_SHARED_LIBRARY=1 - -to the compiler flags. You'll also need to tell the linker to produce a shared -library instead - consult your linker's manual for how to do it. - -To compile your *tests* that use the gtest shared library, add - - -DGTEST_LINKED_AS_SHARED_LIBRARY=1 - -to the compiler flags. - -Note: while the above steps aren't technically necessary today when using some -compilers (e.g. GCC), they may become necessary in the future, if we decide to -improve the speed of loading the library (see - for details). Therefore you are recommended -to always add the above flags when using GoogleTest as a shared library. -Otherwise a future release of GoogleTest may break your build script. - -### Avoiding Macro Name Clashes - -In C++, macros don't obey namespaces. Therefore two libraries that both define a -macro of the same name will clash if you `#include` both definitions. In case a -GoogleTest macro clashes with another library, you can force GoogleTest to -rename its macro to avoid the conflict. - -Specifically, if both GoogleTest and some other code define macro FOO, you can -add - - -DGTEST_DONT_DEFINE_FOO=1 - -to the compiler flags to tell GoogleTest to change the macro's name from `FOO` -to `GTEST_FOO`. Currently `FOO` can be `ASSERT_EQ`, `ASSERT_FALSE`, `ASSERT_GE`, -`ASSERT_GT`, `ASSERT_LE`, `ASSERT_LT`, `ASSERT_NE`, `ASSERT_TRUE`, -`EXPECT_FALSE`, `EXPECT_TRUE`, `FAIL`, `SUCCEED`, `TEST`, or `TEST_F`. For -example, with `-DGTEST_DONT_DEFINE_TEST=1`, you'll need to write - - GTEST_TEST(SomeTest, DoesThis) { ... } - -instead of - - TEST(SomeTest, DoesThis) { ... } - -in order to define a test. diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-assertion-result.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-assertion-result.h deleted file mode 100644 index addbb59c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-assertion-result.h +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The Google C++ Testing and Mocking Framework (Google Test) -// -// This file implements the AssertionResult type. - -// IWYU pragma: private, include "gtest/gtest.h" -// IWYU pragma: friend gtest/.* -// IWYU pragma: friend gmock/.* - -#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_ -#define GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_ - -#include -#include -#include -#include - -#include "gtest/gtest-message.h" -#include "gtest/internal/gtest-port.h" - -GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ -/* class A needs to have dll-interface to be used by clients of class B */) - -namespace testing { - -// A class for indicating whether an assertion was successful. When -// the assertion wasn't successful, the AssertionResult object -// remembers a non-empty message that describes how it failed. -// -// To create an instance of this class, use one of the factory functions -// (AssertionSuccess() and AssertionFailure()). -// -// This class is useful for two purposes: -// 1. Defining predicate functions to be used with Boolean test assertions -// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts -// 2. Defining predicate-format functions to be -// used with predicate assertions (ASSERT_PRED_FORMAT*, etc). -// -// For example, if you define IsEven predicate: -// -// testing::AssertionResult IsEven(int n) { -// if ((n % 2) == 0) -// return testing::AssertionSuccess(); -// else -// return testing::AssertionFailure() << n << " is odd"; -// } -// -// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) -// will print the message -// -// Value of: IsEven(Fib(5)) -// Actual: false (5 is odd) -// Expected: true -// -// instead of a more opaque -// -// Value of: IsEven(Fib(5)) -// Actual: false -// Expected: true -// -// in case IsEven is a simple Boolean predicate. -// -// If you expect your predicate to be reused and want to support informative -// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up -// about half as often as positive ones in our tests), supply messages for -// both success and failure cases: -// -// testing::AssertionResult IsEven(int n) { -// if ((n % 2) == 0) -// return testing::AssertionSuccess() << n << " is even"; -// else -// return testing::AssertionFailure() << n << " is odd"; -// } -// -// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print -// -// Value of: IsEven(Fib(6)) -// Actual: true (8 is even) -// Expected: false -// -// NB: Predicates that support negative Boolean assertions have reduced -// performance in positive ones so be careful not to use them in tests -// that have lots (tens of thousands) of positive Boolean assertions. -// -// To use this class with EXPECT_PRED_FORMAT assertions such as: -// -// // Verifies that Foo() returns an even number. -// EXPECT_PRED_FORMAT1(IsEven, Foo()); -// -// you need to define: -// -// testing::AssertionResult IsEven(const char* expr, int n) { -// if ((n % 2) == 0) -// return testing::AssertionSuccess(); -// else -// return testing::AssertionFailure() -// << "Expected: " << expr << " is even\n Actual: it's " << n; -// } -// -// If Foo() returns 5, you will see the following message: -// -// Expected: Foo() is even -// Actual: it's 5 -// -class GTEST_API_ AssertionResult { - public: - // Copy constructor. - // Used in EXPECT_TRUE/FALSE(assertion_result). - AssertionResult(const AssertionResult& other); - -// C4800 is a level 3 warning in Visual Studio 2015 and earlier. -// This warning is not emitted in Visual Studio 2017. -// This warning is off by default starting in Visual Studio 2019 but can be -// enabled with command-line options. -#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920) - GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */) -#endif - - // Used in the EXPECT_TRUE/FALSE(bool_expression). - // - // T must be contextually convertible to bool. - // - // The second parameter prevents this overload from being considered if - // the argument is implicitly convertible to AssertionResult. In that case - // we want AssertionResult's copy constructor to be used. - template - explicit AssertionResult( - const T& success, - typename std::enable_if< - !std::is_convertible::value>::type* - /*enabler*/ - = nullptr) - : success_(success) {} - -#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920) - GTEST_DISABLE_MSC_WARNINGS_POP_() -#endif - - // Assignment operator. - AssertionResult& operator=(AssertionResult other) { - swap(other); - return *this; - } - - // Returns true if and only if the assertion succeeded. - operator bool() const { return success_; } // NOLINT - - // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. - AssertionResult operator!() const; - - // Returns the text streamed into this AssertionResult. Test assertions - // use it when they fail (i.e., the predicate's outcome doesn't match the - // assertion's expectation). When nothing has been streamed into the - // object, returns an empty string. - const char* message() const { - return message_.get() != nullptr ? message_->c_str() : ""; - } - // Deprecated; please use message() instead. - const char* failure_message() const { return message(); } - - // Streams a custom failure message into this object. - template - AssertionResult& operator<<(const T& value) { - AppendMessage(Message() << value); - return *this; - } - - // Allows streaming basic output manipulators such as endl or flush into - // this object. - AssertionResult& operator<<( - ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) { - AppendMessage(Message() << basic_manipulator); - return *this; - } - - private: - // Appends the contents of message to message_. - void AppendMessage(const Message& a_message) { - if (message_.get() == nullptr) message_.reset(new ::std::string); - message_->append(a_message.GetString().c_str()); - } - - // Swap the contents of this AssertionResult with other. - void swap(AssertionResult& other); - - // Stores result of the assertion predicate. - bool success_; - // Stores the message describing the condition in case the expectation - // construct is not satisfied with the predicate's outcome. - // Referenced via a pointer to avoid taking too much stack frame space - // with test assertions. - std::unique_ptr< ::std::string> message_; -}; - -// Makes a successful assertion result. -GTEST_API_ AssertionResult AssertionSuccess(); - -// Makes a failed assertion result. -GTEST_API_ AssertionResult AssertionFailure(); - -// Makes a failed assertion result with the given failure message. -// Deprecated; use AssertionFailure() << msg. -GTEST_API_ AssertionResult AssertionFailure(const Message& msg); - -} // namespace testing - -GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 - -#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-death-test.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-death-test.h deleted file mode 100644 index 84e5a5bb..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-death-test.h +++ /dev/null @@ -1,345 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The Google C++ Testing and Mocking Framework (Google Test) -// -// This header file defines the public API for death tests. It is -// #included by gtest.h so a user doesn't need to include this -// directly. - -// IWYU pragma: private, include "gtest/gtest.h" -// IWYU pragma: friend gtest/.* -// IWYU pragma: friend gmock/.* - -#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ -#define GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ - -#include "gtest/internal/gtest-death-test-internal.h" - -// This flag controls the style of death tests. Valid values are "threadsafe", -// meaning that the death test child process will re-execute the test binary -// from the start, running only a single death test, or "fast", -// meaning that the child process will execute the test logic immediately -// after forking. -GTEST_DECLARE_string_(death_test_style); - -namespace testing { - -#if GTEST_HAS_DEATH_TEST - -namespace internal { - -// Returns a Boolean value indicating whether the caller is currently -// executing in the context of the death test child process. Tools such as -// Valgrind heap checkers may need this to modify their behavior in death -// tests. IMPORTANT: This is an internal utility. Using it may break the -// implementation of death tests. User code MUST NOT use it. -GTEST_API_ bool InDeathTestChild(); - -} // namespace internal - -// The following macros are useful for writing death tests. - -// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is -// executed: -// -// 1. It generates a warning if there is more than one active -// thread. This is because it's safe to fork() or clone() only -// when there is a single thread. -// -// 2. The parent process clone()s a sub-process and runs the death -// test in it; the sub-process exits with code 0 at the end of the -// death test, if it hasn't exited already. -// -// 3. The parent process waits for the sub-process to terminate. -// -// 4. The parent process checks the exit code and error message of -// the sub-process. -// -// Examples: -// -// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); -// for (int i = 0; i < 5; i++) { -// EXPECT_DEATH(server.ProcessRequest(i), -// "Invalid request .* in ProcessRequest()") -// << "Failed to die on request " << i; -// } -// -// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); -// -// bool KilledBySIGHUP(int exit_code) { -// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; -// } -// -// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); -// -// The final parameter to each of these macros is a matcher applied to any data -// the sub-process wrote to stderr. For compatibility with existing tests, a -// bare string is interpreted as a regular expression matcher. -// -// On the regular expressions used in death tests: -// -// On POSIX-compliant systems (*nix), we use the library, -// which uses the POSIX extended regex syntax. -// -// On other platforms (e.g. Windows or Mac), we only support a simple regex -// syntax implemented as part of Google Test. This limited -// implementation should be enough most of the time when writing -// death tests; though it lacks many features you can find in PCRE -// or POSIX extended regex syntax. For example, we don't support -// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and -// repetition count ("x{5,7}"), among others. -// -// Below is the syntax that we do support. We chose it to be a -// subset of both PCRE and POSIX extended regex, so it's easy to -// learn wherever you come from. In the following: 'A' denotes a -// literal character, period (.), or a single \\ escape sequence; -// 'x' and 'y' denote regular expressions; 'm' and 'n' are for -// natural numbers. -// -// c matches any literal character c -// \\d matches any decimal digit -// \\D matches any character that's not a decimal digit -// \\f matches \f -// \\n matches \n -// \\r matches \r -// \\s matches any ASCII whitespace, including \n -// \\S matches any character that's not a whitespace -// \\t matches \t -// \\v matches \v -// \\w matches any letter, _, or decimal digit -// \\W matches any character that \\w doesn't match -// \\c matches any literal character c, which must be a punctuation -// . matches any single character except \n -// A? matches 0 or 1 occurrences of A -// A* matches 0 or many occurrences of A -// A+ matches 1 or many occurrences of A -// ^ matches the beginning of a string (not that of each line) -// $ matches the end of a string (not that of each line) -// xy matches x followed by y -// -// If you accidentally use PCRE or POSIX extended regex features -// not implemented by us, you will get a run-time failure. In that -// case, please try to rewrite your regular expression within the -// above syntax. -// -// This implementation is *not* meant to be as highly tuned or robust -// as a compiled regex library, but should perform well enough for a -// death test, which already incurs significant overhead by launching -// a child process. -// -// Known caveats: -// -// A "threadsafe" style death test obtains the path to the test -// program from argv[0] and re-executes it in the sub-process. For -// simplicity, the current implementation doesn't search the PATH -// when launching the sub-process. This means that the user must -// invoke the test program via a path that contains at least one -// path separator (e.g. path/to/foo_test and -// /absolute/path/to/bar_test are fine, but foo_test is not). This -// is rarely a problem as people usually don't put the test binary -// directory in PATH. -// - -// Asserts that a given `statement` causes the program to exit, with an -// integer exit status that satisfies `predicate`, and emitting error output -// that matches `matcher`. -#define ASSERT_EXIT(statement, predicate, matcher) \ - GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_FATAL_FAILURE_) - -// Like `ASSERT_EXIT`, but continues on to successive tests in the -// test suite, if any: -#define EXPECT_EXIT(statement, predicate, matcher) \ - GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_NONFATAL_FAILURE_) - -// Asserts that a given `statement` causes the program to exit, either by -// explicitly exiting with a nonzero exit code or being killed by a -// signal, and emitting error output that matches `matcher`. -#define ASSERT_DEATH(statement, matcher) \ - ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher) - -// Like `ASSERT_DEATH`, but continues on to successive tests in the -// test suite, if any: -#define EXPECT_DEATH(statement, matcher) \ - EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher) - -// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: - -// Tests that an exit code describes a normal exit with a given exit code. -class GTEST_API_ ExitedWithCode { - public: - explicit ExitedWithCode(int exit_code); - ExitedWithCode(const ExitedWithCode&) = default; - void operator=(const ExitedWithCode& other) = delete; - bool operator()(int exit_status) const; - - private: - const int exit_code_; -}; - -#if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA -// Tests that an exit code describes an exit due to termination by a -// given signal. -class GTEST_API_ KilledBySignal { - public: - explicit KilledBySignal(int signum); - bool operator()(int exit_status) const; - - private: - const int signum_; -}; -#endif // !GTEST_OS_WINDOWS - -// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. -// The death testing framework causes this to have interesting semantics, -// since the sideeffects of the call are only visible in opt mode, and not -// in debug mode. -// -// In practice, this can be used to test functions that utilize the -// LOG(DFATAL) macro using the following style: -// -// int DieInDebugOr12(int* sideeffect) { -// if (sideeffect) { -// *sideeffect = 12; -// } -// LOG(DFATAL) << "death"; -// return 12; -// } -// -// TEST(TestSuite, TestDieOr12WorksInDgbAndOpt) { -// int sideeffect = 0; -// // Only asserts in dbg. -// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); -// -// #ifdef NDEBUG -// // opt-mode has sideeffect visible. -// EXPECT_EQ(12, sideeffect); -// #else -// // dbg-mode no visible sideeffect. -// EXPECT_EQ(0, sideeffect); -// #endif -// } -// -// This will assert that DieInDebugReturn12InOpt() crashes in debug -// mode, usually due to a DCHECK or LOG(DFATAL), but returns the -// appropriate fallback value (12 in this case) in opt mode. If you -// need to test that a function has appropriate side-effects in opt -// mode, include assertions against the side-effects. A general -// pattern for this is: -// -// EXPECT_DEBUG_DEATH({ -// // Side-effects here will have an effect after this statement in -// // opt mode, but none in debug mode. -// EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); -// }, "death"); -// -#ifdef NDEBUG - -#define EXPECT_DEBUG_DEATH(statement, regex) \ - GTEST_EXECUTE_STATEMENT_(statement, regex) - -#define ASSERT_DEBUG_DEATH(statement, regex) \ - GTEST_EXECUTE_STATEMENT_(statement, regex) - -#else - -#define EXPECT_DEBUG_DEATH(statement, regex) EXPECT_DEATH(statement, regex) - -#define ASSERT_DEBUG_DEATH(statement, regex) ASSERT_DEATH(statement, regex) - -#endif // NDEBUG for EXPECT_DEBUG_DEATH -#endif // GTEST_HAS_DEATH_TEST - -// This macro is used for implementing macros such as -// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where -// death tests are not supported. Those macros must compile on such systems -// if and only if EXPECT_DEATH and ASSERT_DEATH compile with the same parameters -// on systems that support death tests. This allows one to write such a macro on -// a system that does not support death tests and be sure that it will compile -// on a death-test supporting system. It is exposed publicly so that systems -// that have death-tests with stricter requirements than GTEST_HAS_DEATH_TEST -// can write their own equivalent of EXPECT_DEATH_IF_SUPPORTED and -// ASSERT_DEATH_IF_SUPPORTED. -// -// Parameters: -// statement - A statement that a macro such as EXPECT_DEATH would test -// for program termination. This macro has to make sure this -// statement is compiled but not executed, to ensure that -// EXPECT_DEATH_IF_SUPPORTED compiles with a certain -// parameter if and only if EXPECT_DEATH compiles with it. -// regex - A regex that a macro such as EXPECT_DEATH would use to test -// the output of statement. This parameter has to be -// compiled but not evaluated by this macro, to ensure that -// this macro only accepts expressions that a macro such as -// EXPECT_DEATH would accept. -// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED -// and a return statement for ASSERT_DEATH_IF_SUPPORTED. -// This ensures that ASSERT_DEATH_IF_SUPPORTED will not -// compile inside functions where ASSERT_DEATH doesn't -// compile. -// -// The branch that has an always false condition is used to ensure that -// statement and regex are compiled (and thus syntactically correct) but -// never executed. The unreachable code macro protects the terminator -// statement from generating an 'unreachable code' warning in case -// statement unconditionally returns or throws. The Message constructor at -// the end allows the syntax of streaming additional messages into the -// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. -#define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - GTEST_LOG_(WARNING) << "Death tests are not supported on this platform.\n" \ - << "Statement '" #statement "' cannot be verified."; \ - } else if (::testing::internal::AlwaysFalse()) { \ - ::testing::internal::RE::PartialMatch(".*", (regex)); \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - terminator; \ - } else \ - ::testing::Message() - -// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and -// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if -// death tests are supported; otherwise they just issue a warning. This is -// useful when you are combining death test assertions with normal test -// assertions in one test. -#if GTEST_HAS_DEATH_TEST -#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ - EXPECT_DEATH(statement, regex) -#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ - ASSERT_DEATH(statement, regex) -#else -#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ - GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, ) -#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ - GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return) -#endif - -} // namespace testing - -#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-matchers.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-matchers.h deleted file mode 100644 index bffa00c5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-matchers.h +++ /dev/null @@ -1,956 +0,0 @@ -// Copyright 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The Google C++ Testing and Mocking Framework (Google Test) -// -// This file implements just enough of the matcher interface to allow -// EXPECT_DEATH and friends to accept a matcher argument. - -// IWYU pragma: private, include "gtest/gtest.h" -// IWYU pragma: friend gtest/.* -// IWYU pragma: friend gmock/.* - -#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_ -#define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_ - -#include -#include -#include -#include -#include - -#include "gtest/gtest-printers.h" -#include "gtest/internal/gtest-internal.h" -#include "gtest/internal/gtest-port.h" - -// MSVC warning C5046 is new as of VS2017 version 15.8. -#if defined(_MSC_VER) && _MSC_VER >= 1915 -#define GTEST_MAYBE_5046_ 5046 -#else -#define GTEST_MAYBE_5046_ -#endif - -GTEST_DISABLE_MSC_WARNINGS_PUSH_( - 4251 GTEST_MAYBE_5046_ /* class A needs to have dll-interface to be used by - clients of class B */ - /* Symbol involving type with internal linkage not defined */) - -namespace testing { - -// To implement a matcher Foo for type T, define: -// 1. a class FooMatcherMatcher that implements the matcher interface: -// using is_gtest_matcher = void; -// bool MatchAndExplain(const T&, std::ostream*); -// (MatchResultListener* can also be used instead of std::ostream*) -// void DescribeTo(std::ostream*); -// void DescribeNegationTo(std::ostream*); -// -// 2. a factory function that creates a Matcher object from a -// FooMatcherMatcher. - -class MatchResultListener { - public: - // Creates a listener object with the given underlying ostream. The - // listener does not own the ostream, and does not dereference it - // in the constructor or destructor. - explicit MatchResultListener(::std::ostream* os) : stream_(os) {} - virtual ~MatchResultListener() = 0; // Makes this class abstract. - - // Streams x to the underlying ostream; does nothing if the ostream - // is NULL. - template - MatchResultListener& operator<<(const T& x) { - if (stream_ != nullptr) *stream_ << x; - return *this; - } - - // Returns the underlying ostream. - ::std::ostream* stream() { return stream_; } - - // Returns true if and only if the listener is interested in an explanation - // of the match result. A matcher's MatchAndExplain() method can use - // this information to avoid generating the explanation when no one - // intends to hear it. - bool IsInterested() const { return stream_ != nullptr; } - - private: - ::std::ostream* const stream_; - - MatchResultListener(const MatchResultListener&) = delete; - MatchResultListener& operator=(const MatchResultListener&) = delete; -}; - -inline MatchResultListener::~MatchResultListener() {} - -// An instance of a subclass of this knows how to describe itself as a -// matcher. -class GTEST_API_ MatcherDescriberInterface { - public: - virtual ~MatcherDescriberInterface() {} - - // Describes this matcher to an ostream. The function should print - // a verb phrase that describes the property a value matching this - // matcher should have. The subject of the verb phrase is the value - // being matched. For example, the DescribeTo() method of the Gt(7) - // matcher prints "is greater than 7". - virtual void DescribeTo(::std::ostream* os) const = 0; - - // Describes the negation of this matcher to an ostream. For - // example, if the description of this matcher is "is greater than - // 7", the negated description could be "is not greater than 7". - // You are not required to override this when implementing - // MatcherInterface, but it is highly advised so that your matcher - // can produce good error messages. - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "not ("; - DescribeTo(os); - *os << ")"; - } -}; - -// The implementation of a matcher. -template -class MatcherInterface : public MatcherDescriberInterface { - public: - // Returns true if and only if the matcher matches x; also explains the - // match result to 'listener' if necessary (see the next paragraph), in - // the form of a non-restrictive relative clause ("which ...", - // "whose ...", etc) that describes x. For example, the - // MatchAndExplain() method of the Pointee(...) matcher should - // generate an explanation like "which points to ...". - // - // Implementations of MatchAndExplain() should add an explanation of - // the match result *if and only if* they can provide additional - // information that's not already present (or not obvious) in the - // print-out of x and the matcher's description. Whether the match - // succeeds is not a factor in deciding whether an explanation is - // needed, as sometimes the caller needs to print a failure message - // when the match succeeds (e.g. when the matcher is used inside - // Not()). - // - // For example, a "has at least 10 elements" matcher should explain - // what the actual element count is, regardless of the match result, - // as it is useful information to the reader; on the other hand, an - // "is empty" matcher probably only needs to explain what the actual - // size is when the match fails, as it's redundant to say that the - // size is 0 when the value is already known to be empty. - // - // You should override this method when defining a new matcher. - // - // It's the responsibility of the caller (Google Test) to guarantee - // that 'listener' is not NULL. This helps to simplify a matcher's - // implementation when it doesn't care about the performance, as it - // can talk to 'listener' without checking its validity first. - // However, in order to implement dummy listeners efficiently, - // listener->stream() may be NULL. - virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0; - - // Inherits these methods from MatcherDescriberInterface: - // virtual void DescribeTo(::std::ostream* os) const = 0; - // virtual void DescribeNegationTo(::std::ostream* os) const; -}; - -namespace internal { - -struct AnyEq { - template - bool operator()(const A& a, const B& b) const { - return a == b; - } -}; -struct AnyNe { - template - bool operator()(const A& a, const B& b) const { - return a != b; - } -}; -struct AnyLt { - template - bool operator()(const A& a, const B& b) const { - return a < b; - } -}; -struct AnyGt { - template - bool operator()(const A& a, const B& b) const { - return a > b; - } -}; -struct AnyLe { - template - bool operator()(const A& a, const B& b) const { - return a <= b; - } -}; -struct AnyGe { - template - bool operator()(const A& a, const B& b) const { - return a >= b; - } -}; - -// A match result listener that ignores the explanation. -class DummyMatchResultListener : public MatchResultListener { - public: - DummyMatchResultListener() : MatchResultListener(nullptr) {} - - private: - DummyMatchResultListener(const DummyMatchResultListener&) = delete; - DummyMatchResultListener& operator=(const DummyMatchResultListener&) = delete; -}; - -// A match result listener that forwards the explanation to a given -// ostream. The difference between this and MatchResultListener is -// that the former is concrete. -class StreamMatchResultListener : public MatchResultListener { - public: - explicit StreamMatchResultListener(::std::ostream* os) - : MatchResultListener(os) {} - - private: - StreamMatchResultListener(const StreamMatchResultListener&) = delete; - StreamMatchResultListener& operator=(const StreamMatchResultListener&) = - delete; -}; - -struct SharedPayloadBase { - std::atomic ref{1}; - void Ref() { ref.fetch_add(1, std::memory_order_relaxed); } - bool Unref() { return ref.fetch_sub(1, std::memory_order_acq_rel) == 1; } -}; - -template -struct SharedPayload : SharedPayloadBase { - explicit SharedPayload(const T& v) : value(v) {} - explicit SharedPayload(T&& v) : value(std::move(v)) {} - - static void Destroy(SharedPayloadBase* shared) { - delete static_cast(shared); - } - - T value; -}; - -// An internal class for implementing Matcher, which will derive -// from it. We put functionalities common to all Matcher -// specializations here to avoid code duplication. -template -class MatcherBase : private MatcherDescriberInterface { - public: - // Returns true if and only if the matcher matches x; also explains the - // match result to 'listener'. - bool MatchAndExplain(const T& x, MatchResultListener* listener) const { - GTEST_CHECK_(vtable_ != nullptr); - return vtable_->match_and_explain(*this, x, listener); - } - - // Returns true if and only if this matcher matches x. - bool Matches(const T& x) const { - DummyMatchResultListener dummy; - return MatchAndExplain(x, &dummy); - } - - // Describes this matcher to an ostream. - void DescribeTo(::std::ostream* os) const final { - GTEST_CHECK_(vtable_ != nullptr); - vtable_->describe(*this, os, false); - } - - // Describes the negation of this matcher to an ostream. - void DescribeNegationTo(::std::ostream* os) const final { - GTEST_CHECK_(vtable_ != nullptr); - vtable_->describe(*this, os, true); - } - - // Explains why x matches, or doesn't match, the matcher. - void ExplainMatchResultTo(const T& x, ::std::ostream* os) const { - StreamMatchResultListener listener(os); - MatchAndExplain(x, &listener); - } - - // Returns the describer for this matcher object; retains ownership - // of the describer, which is only guaranteed to be alive when - // this matcher object is alive. - const MatcherDescriberInterface* GetDescriber() const { - if (vtable_ == nullptr) return nullptr; - return vtable_->get_describer(*this); - } - - protected: - MatcherBase() : vtable_(nullptr), buffer_() {} - - // Constructs a matcher from its implementation. - template - explicit MatcherBase(const MatcherInterface* impl) - : vtable_(nullptr), buffer_() { - Init(impl); - } - - template ::type::is_gtest_matcher> - MatcherBase(M&& m) : vtable_(nullptr), buffer_() { // NOLINT - Init(std::forward(m)); - } - - MatcherBase(const MatcherBase& other) - : vtable_(other.vtable_), buffer_(other.buffer_) { - if (IsShared()) buffer_.shared->Ref(); - } - - MatcherBase& operator=(const MatcherBase& other) { - if (this == &other) return *this; - Destroy(); - vtable_ = other.vtable_; - buffer_ = other.buffer_; - if (IsShared()) buffer_.shared->Ref(); - return *this; - } - - MatcherBase(MatcherBase&& other) - : vtable_(other.vtable_), buffer_(other.buffer_) { - other.vtable_ = nullptr; - } - - MatcherBase& operator=(MatcherBase&& other) { - if (this == &other) return *this; - Destroy(); - vtable_ = other.vtable_; - buffer_ = other.buffer_; - other.vtable_ = nullptr; - return *this; - } - - ~MatcherBase() override { Destroy(); } - - private: - struct VTable { - bool (*match_and_explain)(const MatcherBase&, const T&, - MatchResultListener*); - void (*describe)(const MatcherBase&, std::ostream*, bool negation); - // Returns the captured object if it implements the interface, otherwise - // returns the MatcherBase itself. - const MatcherDescriberInterface* (*get_describer)(const MatcherBase&); - // Called on shared instances when the reference count reaches 0. - void (*shared_destroy)(SharedPayloadBase*); - }; - - bool IsShared() const { - return vtable_ != nullptr && vtable_->shared_destroy != nullptr; - } - - // If the implementation uses a listener, call that. - template - static auto MatchAndExplainImpl(const MatcherBase& m, const T& value, - MatchResultListener* listener) - -> decltype(P::Get(m).MatchAndExplain(value, listener->stream())) { - return P::Get(m).MatchAndExplain(value, listener->stream()); - } - - template - static auto MatchAndExplainImpl(const MatcherBase& m, const T& value, - MatchResultListener* listener) - -> decltype(P::Get(m).MatchAndExplain(value, listener)) { - return P::Get(m).MatchAndExplain(value, listener); - } - - template - static void DescribeImpl(const MatcherBase& m, std::ostream* os, - bool negation) { - if (negation) { - P::Get(m).DescribeNegationTo(os); - } else { - P::Get(m).DescribeTo(os); - } - } - - template - static const MatcherDescriberInterface* GetDescriberImpl( - const MatcherBase& m) { - // If the impl is a MatcherDescriberInterface, then return it. - // Otherwise use MatcherBase itself. - // This allows us to implement the GetDescriber() function without support - // from the impl, but some users really want to get their impl back when - // they call GetDescriber(). - // We use std::get on a tuple as a workaround of not having `if constexpr`. - return std::get<( - std::is_convertible::value - ? 1 - : 0)>(std::make_tuple(&m, &P::Get(m))); - } - - template - const VTable* GetVTable() { - static constexpr VTable kVTable = {&MatchAndExplainImpl

, - &DescribeImpl

, &GetDescriberImpl

, - P::shared_destroy}; - return &kVTable; - } - - union Buffer { - // Add some types to give Buffer some common alignment/size use cases. - void* ptr; - double d; - int64_t i; - // And add one for the out-of-line cases. - SharedPayloadBase* shared; - }; - - void Destroy() { - if (IsShared() && buffer_.shared->Unref()) { - vtable_->shared_destroy(buffer_.shared); - } - } - - template - static constexpr bool IsInlined() { - return sizeof(M) <= sizeof(Buffer) && alignof(M) <= alignof(Buffer) && - std::is_trivially_copy_constructible::value && - std::is_trivially_destructible::value; - } - - template ()> - struct ValuePolicy { - static const M& Get(const MatcherBase& m) { - // When inlined along with Init, need to be explicit to avoid violating - // strict aliasing rules. - const M* ptr = - static_cast(static_cast(&m.buffer_)); - return *ptr; - } - static void Init(MatcherBase& m, M impl) { - ::new (static_cast(&m.buffer_)) M(impl); - } - static constexpr auto shared_destroy = nullptr; - }; - - template - struct ValuePolicy { - using Shared = SharedPayload; - static const M& Get(const MatcherBase& m) { - return static_cast(m.buffer_.shared)->value; - } - template - static void Init(MatcherBase& m, Arg&& arg) { - m.buffer_.shared = new Shared(std::forward(arg)); - } - static constexpr auto shared_destroy = &Shared::Destroy; - }; - - template - struct ValuePolicy*, B> { - using M = const MatcherInterface; - using Shared = SharedPayload>; - static const M& Get(const MatcherBase& m) { - return *static_cast(m.buffer_.shared)->value; - } - static void Init(MatcherBase& m, M* impl) { - m.buffer_.shared = new Shared(std::unique_ptr(impl)); - } - - static constexpr auto shared_destroy = &Shared::Destroy; - }; - - template - void Init(M&& m) { - using MM = typename std::decay::type; - using Policy = ValuePolicy; - vtable_ = GetVTable(); - Policy::Init(*this, std::forward(m)); - } - - const VTable* vtable_; - Buffer buffer_; -}; - -} // namespace internal - -// A Matcher is a copyable and IMMUTABLE (except by assignment) -// object that can check whether a value of type T matches. The -// implementation of Matcher is just a std::shared_ptr to const -// MatcherInterface. Don't inherit from Matcher! -template -class Matcher : public internal::MatcherBase { - public: - // Constructs a null matcher. Needed for storing Matcher objects in STL - // containers. A default-constructed matcher is not yet initialized. You - // cannot use it until a valid value has been assigned to it. - explicit Matcher() {} // NOLINT - - // Constructs a matcher from its implementation. - explicit Matcher(const MatcherInterface* impl) - : internal::MatcherBase(impl) {} - - template - explicit Matcher( - const MatcherInterface* impl, - typename std::enable_if::value>::type* = - nullptr) - : internal::MatcherBase(impl) {} - - template ::type::is_gtest_matcher> - Matcher(M&& m) : internal::MatcherBase(std::forward(m)) {} // NOLINT - - // Implicit constructor here allows people to write - // EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes - Matcher(T value); // NOLINT -}; - -// The following two specializations allow the user to write str -// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string -// matcher is expected. -template <> -class GTEST_API_ Matcher - : public internal::MatcherBase { - public: - Matcher() {} - - explicit Matcher(const MatcherInterface* impl) - : internal::MatcherBase(impl) {} - - template ::type::is_gtest_matcher> - Matcher(M&& m) // NOLINT - : internal::MatcherBase(std::forward(m)) {} - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a std::string object. - Matcher(const std::string& s); // NOLINT - - // Allows the user to write "foo" instead of Eq("foo") sometimes. - Matcher(const char* s); // NOLINT -}; - -template <> -class GTEST_API_ Matcher - : public internal::MatcherBase { - public: - Matcher() {} - - explicit Matcher(const MatcherInterface* impl) - : internal::MatcherBase(impl) {} - explicit Matcher(const MatcherInterface* impl) - : internal::MatcherBase(impl) {} - - template ::type::is_gtest_matcher> - Matcher(M&& m) // NOLINT - : internal::MatcherBase(std::forward(m)) {} - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a string object. - Matcher(const std::string& s); // NOLINT - - // Allows the user to write "foo" instead of Eq("foo") sometimes. - Matcher(const char* s); // NOLINT -}; - -#if GTEST_INTERNAL_HAS_STRING_VIEW -// The following two specializations allow the user to write str -// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view -// matcher is expected. -template <> -class GTEST_API_ Matcher - : public internal::MatcherBase { - public: - Matcher() {} - - explicit Matcher(const MatcherInterface* impl) - : internal::MatcherBase(impl) {} - - template ::type::is_gtest_matcher> - Matcher(M&& m) // NOLINT - : internal::MatcherBase(std::forward(m)) { - } - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a std::string object. - Matcher(const std::string& s); // NOLINT - - // Allows the user to write "foo" instead of Eq("foo") sometimes. - Matcher(const char* s); // NOLINT - - // Allows the user to pass absl::string_views or std::string_views directly. - Matcher(internal::StringView s); // NOLINT -}; - -template <> -class GTEST_API_ Matcher - : public internal::MatcherBase { - public: - Matcher() {} - - explicit Matcher(const MatcherInterface* impl) - : internal::MatcherBase(impl) {} - explicit Matcher(const MatcherInterface* impl) - : internal::MatcherBase(impl) {} - - template ::type::is_gtest_matcher> - Matcher(M&& m) // NOLINT - : internal::MatcherBase(std::forward(m)) {} - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a std::string object. - Matcher(const std::string& s); // NOLINT - - // Allows the user to write "foo" instead of Eq("foo") sometimes. - Matcher(const char* s); // NOLINT - - // Allows the user to pass absl::string_views or std::string_views directly. - Matcher(internal::StringView s); // NOLINT -}; -#endif // GTEST_INTERNAL_HAS_STRING_VIEW - -// Prints a matcher in a human-readable format. -template -std::ostream& operator<<(std::ostream& os, const Matcher& matcher) { - matcher.DescribeTo(&os); - return os; -} - -// The PolymorphicMatcher class template makes it easy to implement a -// polymorphic matcher (i.e. a matcher that can match values of more -// than one type, e.g. Eq(n) and NotNull()). -// -// To define a polymorphic matcher, a user should provide an Impl -// class that has a DescribeTo() method and a DescribeNegationTo() -// method, and define a member function (or member function template) -// -// bool MatchAndExplain(const Value& value, -// MatchResultListener* listener) const; -// -// See the definition of NotNull() for a complete example. -template -class PolymorphicMatcher { - public: - explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {} - - // Returns a mutable reference to the underlying matcher - // implementation object. - Impl& mutable_impl() { return impl_; } - - // Returns an immutable reference to the underlying matcher - // implementation object. - const Impl& impl() const { return impl_; } - - template - operator Matcher() const { - return Matcher(new MonomorphicImpl(impl_)); - } - - private: - template - class MonomorphicImpl : public MatcherInterface { - public: - explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {} - - void DescribeTo(::std::ostream* os) const override { impl_.DescribeTo(os); } - - void DescribeNegationTo(::std::ostream* os) const override { - impl_.DescribeNegationTo(os); - } - - bool MatchAndExplain(T x, MatchResultListener* listener) const override { - return impl_.MatchAndExplain(x, listener); - } - - private: - const Impl impl_; - }; - - Impl impl_; -}; - -// Creates a matcher from its implementation. -// DEPRECATED: Especially in the generic code, prefer: -// Matcher(new MyMatcherImpl(...)); -// -// MakeMatcher may create a Matcher that accepts its argument by value, which -// leads to unnecessary copies & lack of support for non-copyable types. -template -inline Matcher MakeMatcher(const MatcherInterface* impl) { - return Matcher(impl); -} - -// Creates a polymorphic matcher from its implementation. This is -// easier to use than the PolymorphicMatcher constructor as it -// doesn't require you to explicitly write the template argument, e.g. -// -// MakePolymorphicMatcher(foo); -// vs -// PolymorphicMatcher(foo); -template -inline PolymorphicMatcher MakePolymorphicMatcher(const Impl& impl) { - return PolymorphicMatcher(impl); -} - -namespace internal { -// Implements a matcher that compares a given value with a -// pre-supplied value using one of the ==, <=, <, etc, operators. The -// two values being compared don't have to have the same type. -// -// The matcher defined here is polymorphic (for example, Eq(5) can be -// used to match an int, a short, a double, etc). Therefore we use -// a template type conversion operator in the implementation. -// -// The following template definition assumes that the Rhs parameter is -// a "bare" type (i.e. neither 'const T' nor 'T&'). -template -class ComparisonBase { - public: - explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {} - - using is_gtest_matcher = void; - - template - bool MatchAndExplain(const Lhs& lhs, std::ostream*) const { - return Op()(lhs, Unwrap(rhs_)); - } - void DescribeTo(std::ostream* os) const { - *os << D::Desc() << " "; - UniversalPrint(Unwrap(rhs_), os); - } - void DescribeNegationTo(std::ostream* os) const { - *os << D::NegatedDesc() << " "; - UniversalPrint(Unwrap(rhs_), os); - } - - private: - template - static const T& Unwrap(const T& v) { - return v; - } - template - static const T& Unwrap(std::reference_wrapper v) { - return v; - } - - Rhs rhs_; -}; - -template -class EqMatcher : public ComparisonBase, Rhs, AnyEq> { - public: - explicit EqMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyEq>(rhs) {} - static const char* Desc() { return "is equal to"; } - static const char* NegatedDesc() { return "isn't equal to"; } -}; -template -class NeMatcher : public ComparisonBase, Rhs, AnyNe> { - public: - explicit NeMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyNe>(rhs) {} - static const char* Desc() { return "isn't equal to"; } - static const char* NegatedDesc() { return "is equal to"; } -}; -template -class LtMatcher : public ComparisonBase, Rhs, AnyLt> { - public: - explicit LtMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyLt>(rhs) {} - static const char* Desc() { return "is <"; } - static const char* NegatedDesc() { return "isn't <"; } -}; -template -class GtMatcher : public ComparisonBase, Rhs, AnyGt> { - public: - explicit GtMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyGt>(rhs) {} - static const char* Desc() { return "is >"; } - static const char* NegatedDesc() { return "isn't >"; } -}; -template -class LeMatcher : public ComparisonBase, Rhs, AnyLe> { - public: - explicit LeMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyLe>(rhs) {} - static const char* Desc() { return "is <="; } - static const char* NegatedDesc() { return "isn't <="; } -}; -template -class GeMatcher : public ComparisonBase, Rhs, AnyGe> { - public: - explicit GeMatcher(const Rhs& rhs) - : ComparisonBase, Rhs, AnyGe>(rhs) {} - static const char* Desc() { return "is >="; } - static const char* NegatedDesc() { return "isn't >="; } -}; - -template ::value>::type> -using StringLike = T; - -// Implements polymorphic matchers MatchesRegex(regex) and -// ContainsRegex(regex), which can be used as a Matcher as long as -// T can be converted to a string. -class MatchesRegexMatcher { - public: - MatchesRegexMatcher(const RE* regex, bool full_match) - : regex_(regex), full_match_(full_match) {} - -#if GTEST_INTERNAL_HAS_STRING_VIEW - bool MatchAndExplain(const internal::StringView& s, - MatchResultListener* listener) const { - return MatchAndExplain(std::string(s), listener); - } -#endif // GTEST_INTERNAL_HAS_STRING_VIEW - - // Accepts pointer types, particularly: - // const char* - // char* - // const wchar_t* - // wchar_t* - template - bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { - return s != nullptr && MatchAndExplain(std::string(s), listener); - } - - // Matches anything that can convert to std::string. - // - // This is a template, not just a plain function with const std::string&, - // because absl::string_view has some interfering non-explicit constructors. - template - bool MatchAndExplain(const MatcheeStringType& s, - MatchResultListener* /* listener */) const { - const std::string& s2(s); - return full_match_ ? RE::FullMatch(s2, *regex_) - : RE::PartialMatch(s2, *regex_); - } - - void DescribeTo(::std::ostream* os) const { - *os << (full_match_ ? "matches" : "contains") << " regular expression "; - UniversalPrinter::Print(regex_->pattern(), os); - } - - void DescribeNegationTo(::std::ostream* os) const { - *os << "doesn't " << (full_match_ ? "match" : "contain") - << " regular expression "; - UniversalPrinter::Print(regex_->pattern(), os); - } - - private: - const std::shared_ptr regex_; - const bool full_match_; -}; -} // namespace internal - -// Matches a string that fully matches regular expression 'regex'. -// The matcher takes ownership of 'regex'. -inline PolymorphicMatcher MatchesRegex( - const internal::RE* regex) { - return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true)); -} -template -PolymorphicMatcher MatchesRegex( - const internal::StringLike& regex) { - return MatchesRegex(new internal::RE(std::string(regex))); -} - -// Matches a string that contains regular expression 'regex'. -// The matcher takes ownership of 'regex'. -inline PolymorphicMatcher ContainsRegex( - const internal::RE* regex) { - return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false)); -} -template -PolymorphicMatcher ContainsRegex( - const internal::StringLike& regex) { - return ContainsRegex(new internal::RE(std::string(regex))); -} - -// Creates a polymorphic matcher that matches anything equal to x. -// Note: if the parameter of Eq() were declared as const T&, Eq("foo") -// wouldn't compile. -template -inline internal::EqMatcher Eq(T x) { - return internal::EqMatcher(x); -} - -// Constructs a Matcher from a 'value' of type T. The constructed -// matcher matches any value that's equal to 'value'. -template -Matcher::Matcher(T value) { - *this = Eq(value); -} - -// Creates a monomorphic matcher that matches anything with type Lhs -// and equal to rhs. A user may need to use this instead of Eq(...) -// in order to resolve an overloading ambiguity. -// -// TypedEq(x) is just a convenient short-hand for Matcher(Eq(x)) -// or Matcher(x), but more readable than the latter. -// -// We could define similar monomorphic matchers for other comparison -// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do -// it yet as those are used much less than Eq() in practice. A user -// can always write Matcher(Lt(5)) to be explicit about the type, -// for example. -template -inline Matcher TypedEq(const Rhs& rhs) { - return Eq(rhs); -} - -// Creates a polymorphic matcher that matches anything >= x. -template -inline internal::GeMatcher Ge(Rhs x) { - return internal::GeMatcher(x); -} - -// Creates a polymorphic matcher that matches anything > x. -template -inline internal::GtMatcher Gt(Rhs x) { - return internal::GtMatcher(x); -} - -// Creates a polymorphic matcher that matches anything <= x. -template -inline internal::LeMatcher Le(Rhs x) { - return internal::LeMatcher(x); -} - -// Creates a polymorphic matcher that matches anything < x. -template -inline internal::LtMatcher Lt(Rhs x) { - return internal::LtMatcher(x); -} - -// Creates a polymorphic matcher that matches anything != x. -template -inline internal::NeMatcher Ne(Rhs x) { - return internal::NeMatcher(x); -} -} // namespace testing - -GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046 - -#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-message.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-message.h deleted file mode 100644 index 6c8bf900..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-message.h +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The Google C++ Testing and Mocking Framework (Google Test) -// -// This header file defines the Message class. -// -// IMPORTANT NOTE: Due to limitation of the C++ language, we have to -// leave some internal implementation details in this header file. -// They are clearly marked by comments like this: -// -// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -// -// Such code is NOT meant to be used by a user directly, and is subject -// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user -// program! - -// IWYU pragma: private, include "gtest/gtest.h" -// IWYU pragma: friend gtest/.* -// IWYU pragma: friend gmock/.* - -#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ -#define GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ - -#include -#include -#include - -#include "gtest/internal/gtest-port.h" - -GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ -/* class A needs to have dll-interface to be used by clients of class B */) - -// Ensures that there is at least one operator<< in the global namespace. -// See Message& operator<<(...) below for why. -void operator<<(const testing::internal::Secret&, int); - -namespace testing { - -// The Message class works like an ostream repeater. -// -// Typical usage: -// -// 1. You stream a bunch of values to a Message object. -// It will remember the text in a stringstream. -// 2. Then you stream the Message object to an ostream. -// This causes the text in the Message to be streamed -// to the ostream. -// -// For example; -// -// testing::Message foo; -// foo << 1 << " != " << 2; -// std::cout << foo; -// -// will print "1 != 2". -// -// Message is not intended to be inherited from. In particular, its -// destructor is not virtual. -// -// Note that stringstream behaves differently in gcc and in MSVC. You -// can stream a NULL char pointer to it in the former, but not in the -// latter (it causes an access violation if you do). The Message -// class hides this difference by treating a NULL char pointer as -// "(null)". -class GTEST_API_ Message { - private: - // The type of basic IO manipulators (endl, ends, and flush) for - // narrow streams. - typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); - - public: - // Constructs an empty Message. - Message(); - - // Copy constructor. - Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT - *ss_ << msg.GetString(); - } - - // Constructs a Message from a C-string. - explicit Message(const char* str) : ss_(new ::std::stringstream) { - *ss_ << str; - } - - // Streams a non-pointer value to this object. - template - inline Message& operator<<(const T& val) { - // Some libraries overload << for STL containers. These - // overloads are defined in the global namespace instead of ::std. - // - // C++'s symbol lookup rule (i.e. Koenig lookup) says that these - // overloads are visible in either the std namespace or the global - // namespace, but not other namespaces, including the testing - // namespace which Google Test's Message class is in. - // - // To allow STL containers (and other types that has a << operator - // defined in the global namespace) to be used in Google Test - // assertions, testing::Message must access the custom << operator - // from the global namespace. With this using declaration, - // overloads of << defined in the global namespace and those - // visible via Koenig lookup are both exposed in this function. - using ::operator<<; - *ss_ << val; - return *this; - } - - // Streams a pointer value to this object. - // - // This function is an overload of the previous one. When you - // stream a pointer to a Message, this definition will be used as it - // is more specialized. (The C++ Standard, section - // [temp.func.order].) If you stream a non-pointer, then the - // previous definition will be used. - // - // The reason for this overload is that streaming a NULL pointer to - // ostream is undefined behavior. Depending on the compiler, you - // may get "0", "(nil)", "(null)", or an access violation. To - // ensure consistent result across compilers, we always treat NULL - // as "(null)". - template - inline Message& operator<<(T* const& pointer) { // NOLINT - if (pointer == nullptr) { - *ss_ << "(null)"; - } else { - *ss_ << pointer; - } - return *this; - } - - // Since the basic IO manipulators are overloaded for both narrow - // and wide streams, we have to provide this specialized definition - // of operator <<, even though its body is the same as the - // templatized version above. Without this definition, streaming - // endl or other basic IO manipulators to Message will confuse the - // compiler. - Message& operator<<(BasicNarrowIoManip val) { - *ss_ << val; - return *this; - } - - // Instead of 1/0, we want to see true/false for bool values. - Message& operator<<(bool b) { return *this << (b ? "true" : "false"); } - - // These two overloads allow streaming a wide C string to a Message - // using the UTF-8 encoding. - Message& operator<<(const wchar_t* wide_c_str); - Message& operator<<(wchar_t* wide_c_str); - -#if GTEST_HAS_STD_WSTRING - // Converts the given wide string to a narrow string using the UTF-8 - // encoding, and streams the result to this Message object. - Message& operator<<(const ::std::wstring& wstr); -#endif // GTEST_HAS_STD_WSTRING - - // Gets the text streamed to this object so far as an std::string. - // Each '\0' character in the buffer is replaced with "\\0". - // - // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - std::string GetString() const; - - private: - // We'll hold the text streamed to this object here. - const std::unique_ptr< ::std::stringstream> ss_; - - // We declare (but don't implement) this to prevent the compiler - // from implementing the assignment operator. - void operator=(const Message&); -}; - -// Streams a Message to an ostream. -inline std::ostream& operator<<(std::ostream& os, const Message& sb) { - return os << sb.GetString(); -} - -namespace internal { - -// Converts a streamable value to an std::string. A NULL pointer is -// converted to "(null)". When the input value is a ::string, -// ::std::string, ::wstring, or ::std::wstring object, each NUL -// character in it is replaced with "\\0". -template -std::string StreamableToString(const T& streamable) { - return (Message() << streamable).GetString(); -} - -} // namespace internal -} // namespace testing - -GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 - -#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-param-test.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-param-test.h deleted file mode 100644 index b55119ac..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-param-test.h +++ /dev/null @@ -1,510 +0,0 @@ -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Macros and functions for implementing parameterized tests -// in Google C++ Testing and Mocking Framework (Google Test) - -// IWYU pragma: private, include "gtest/gtest.h" -// IWYU pragma: friend gtest/.* -// IWYU pragma: friend gmock/.* - -#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ -#define GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ - -// Value-parameterized tests allow you to test your code with different -// parameters without writing multiple copies of the same test. -// -// Here is how you use value-parameterized tests: - -#if 0 - -// To write value-parameterized tests, first you should define a fixture -// class. It is usually derived from testing::TestWithParam (see below for -// another inheritance scheme that's sometimes useful in more complicated -// class hierarchies), where the type of your parameter values. -// TestWithParam is itself derived from testing::Test. T can be any -// copyable type. If it's a raw pointer, you are responsible for managing the -// lifespan of the pointed values. - -class FooTest : public ::testing::TestWithParam { - // You can implement all the usual class fixture members here. -}; - -// Then, use the TEST_P macro to define as many parameterized tests -// for this fixture as you want. The _P suffix is for "parameterized" -// or "pattern", whichever you prefer to think. - -TEST_P(FooTest, DoesBlah) { - // Inside a test, access the test parameter with the GetParam() method - // of the TestWithParam class: - EXPECT_TRUE(foo.Blah(GetParam())); - ... -} - -TEST_P(FooTest, HasBlahBlah) { - ... -} - -// Finally, you can use INSTANTIATE_TEST_SUITE_P to instantiate the test -// case with any set of parameters you want. Google Test defines a number -// of functions for generating test parameters. They return what we call -// (surprise!) parameter generators. Here is a summary of them, which -// are all in the testing namespace: -// -// -// Range(begin, end [, step]) - Yields values {begin, begin+step, -// begin+step+step, ...}. The values do not -// include end. step defaults to 1. -// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. -// ValuesIn(container) - Yields values from a C-style array, an STL -// ValuesIn(begin,end) container, or an iterator range [begin, end). -// Bool() - Yields sequence {false, true}. -// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product -// for the math savvy) of the values generated -// by the N generators. -// -// For more details, see comments at the definitions of these functions below -// in this file. -// -// The following statement will instantiate tests from the FooTest test suite -// each with parameter values "meeny", "miny", and "moe". - -INSTANTIATE_TEST_SUITE_P(InstantiationName, - FooTest, - Values("meeny", "miny", "moe")); - -// To distinguish different instances of the pattern, (yes, you -// can instantiate it more than once) the first argument to the -// INSTANTIATE_TEST_SUITE_P macro is a prefix that will be added to the -// actual test suite name. Remember to pick unique prefixes for different -// instantiations. The tests from the instantiation above will have -// these names: -// -// * InstantiationName/FooTest.DoesBlah/0 for "meeny" -// * InstantiationName/FooTest.DoesBlah/1 for "miny" -// * InstantiationName/FooTest.DoesBlah/2 for "moe" -// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" -// * InstantiationName/FooTest.HasBlahBlah/1 for "miny" -// * InstantiationName/FooTest.HasBlahBlah/2 for "moe" -// -// You can use these names in --gtest_filter. -// -// This statement will instantiate all tests from FooTest again, each -// with parameter values "cat" and "dog": - -const char* pets[] = {"cat", "dog"}; -INSTANTIATE_TEST_SUITE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); - -// The tests from the instantiation above will have these names: -// -// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" -// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" -// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" -// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" -// -// Please note that INSTANTIATE_TEST_SUITE_P will instantiate all tests -// in the given test suite, whether their definitions come before or -// AFTER the INSTANTIATE_TEST_SUITE_P statement. -// -// Please also note that generator expressions (including parameters to the -// generators) are evaluated in InitGoogleTest(), after main() has started. -// This allows the user on one hand, to adjust generator parameters in order -// to dynamically determine a set of tests to run and on the other hand, -// give the user a chance to inspect the generated tests with Google Test -// reflection API before RUN_ALL_TESTS() is executed. -// -// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc -// for more examples. -// -// In the future, we plan to publish the API for defining new parameter -// generators. But for now this interface remains part of the internal -// implementation and is subject to change. -// -// -// A parameterized test fixture must be derived from testing::Test and from -// testing::WithParamInterface, where T is the type of the parameter -// values. Inheriting from TestWithParam satisfies that requirement because -// TestWithParam inherits from both Test and WithParamInterface. In more -// complicated hierarchies, however, it is occasionally useful to inherit -// separately from Test and WithParamInterface. For example: - -class BaseTest : public ::testing::Test { - // You can inherit all the usual members for a non-parameterized test - // fixture here. -}; - -class DerivedTest : public BaseTest, public ::testing::WithParamInterface { - // The usual test fixture members go here too. -}; - -TEST_F(BaseTest, HasFoo) { - // This is an ordinary non-parameterized test. -} - -TEST_P(DerivedTest, DoesBlah) { - // GetParam works just the same here as if you inherit from TestWithParam. - EXPECT_TRUE(foo.Blah(GetParam())); -} - -#endif // 0 - -#include -#include - -#include "gtest/internal/gtest-internal.h" -#include "gtest/internal/gtest-param-util.h" -#include "gtest/internal/gtest-port.h" - -namespace testing { - -// Functions producing parameter generators. -// -// Google Test uses these generators to produce parameters for value- -// parameterized tests. When a parameterized test suite is instantiated -// with a particular generator, Google Test creates and runs tests -// for each element in the sequence produced by the generator. -// -// In the following sample, tests from test suite FooTest are instantiated -// each three times with parameter values 3, 5, and 8: -// -// class FooTest : public TestWithParam { ... }; -// -// TEST_P(FooTest, TestThis) { -// } -// TEST_P(FooTest, TestThat) { -// } -// INSTANTIATE_TEST_SUITE_P(TestSequence, FooTest, Values(3, 5, 8)); -// - -// Range() returns generators providing sequences of values in a range. -// -// Synopsis: -// Range(start, end) -// - returns a generator producing a sequence of values {start, start+1, -// start+2, ..., }. -// Range(start, end, step) -// - returns a generator producing a sequence of values {start, start+step, -// start+step+step, ..., }. -// Notes: -// * The generated sequences never include end. For example, Range(1, 5) -// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) -// returns a generator producing {1, 3, 5, 7}. -// * start and end must have the same type. That type may be any integral or -// floating-point type or a user defined type satisfying these conditions: -// * It must be assignable (have operator=() defined). -// * It must have operator+() (operator+(int-compatible type) for -// two-operand version). -// * It must have operator<() defined. -// Elements in the resulting sequences will also have that type. -// * Condition start < end must be satisfied in order for resulting sequences -// to contain any elements. -// -template -internal::ParamGenerator Range(T start, T end, IncrementT step) { - return internal::ParamGenerator( - new internal::RangeGenerator(start, end, step)); -} - -template -internal::ParamGenerator Range(T start, T end) { - return Range(start, end, 1); -} - -// ValuesIn() function allows generation of tests with parameters coming from -// a container. -// -// Synopsis: -// ValuesIn(const T (&array)[N]) -// - returns a generator producing sequences with elements from -// a C-style array. -// ValuesIn(const Container& container) -// - returns a generator producing sequences with elements from -// an STL-style container. -// ValuesIn(Iterator begin, Iterator end) -// - returns a generator producing sequences with elements from -// a range [begin, end) defined by a pair of STL-style iterators. These -// iterators can also be plain C pointers. -// -// Please note that ValuesIn copies the values from the containers -// passed in and keeps them to generate tests in RUN_ALL_TESTS(). -// -// Examples: -// -// This instantiates tests from test suite StringTest -// each with C-string values of "foo", "bar", and "baz": -// -// const char* strings[] = {"foo", "bar", "baz"}; -// INSTANTIATE_TEST_SUITE_P(StringSequence, StringTest, ValuesIn(strings)); -// -// This instantiates tests from test suite StlStringTest -// each with STL strings with values "a" and "b": -// -// ::std::vector< ::std::string> GetParameterStrings() { -// ::std::vector< ::std::string> v; -// v.push_back("a"); -// v.push_back("b"); -// return v; -// } -// -// INSTANTIATE_TEST_SUITE_P(CharSequence, -// StlStringTest, -// ValuesIn(GetParameterStrings())); -// -// -// This will also instantiate tests from CharTest -// each with parameter values 'a' and 'b': -// -// ::std::list GetParameterChars() { -// ::std::list list; -// list.push_back('a'); -// list.push_back('b'); -// return list; -// } -// ::std::list l = GetParameterChars(); -// INSTANTIATE_TEST_SUITE_P(CharSequence2, -// CharTest, -// ValuesIn(l.begin(), l.end())); -// -template -internal::ParamGenerator< - typename std::iterator_traits::value_type> -ValuesIn(ForwardIterator begin, ForwardIterator end) { - typedef typename std::iterator_traits::value_type ParamType; - return internal::ParamGenerator( - new internal::ValuesInIteratorRangeGenerator(begin, end)); -} - -template -internal::ParamGenerator ValuesIn(const T (&array)[N]) { - return ValuesIn(array, array + N); -} - -template -internal::ParamGenerator ValuesIn( - const Container& container) { - return ValuesIn(container.begin(), container.end()); -} - -// Values() allows generating tests from explicitly specified list of -// parameters. -// -// Synopsis: -// Values(T v1, T v2, ..., T vN) -// - returns a generator producing sequences with elements v1, v2, ..., vN. -// -// For example, this instantiates tests from test suite BarTest each -// with values "one", "two", and "three": -// -// INSTANTIATE_TEST_SUITE_P(NumSequence, -// BarTest, -// Values("one", "two", "three")); -// -// This instantiates tests from test suite BazTest each with values 1, 2, 3.5. -// The exact type of values will depend on the type of parameter in BazTest. -// -// INSTANTIATE_TEST_SUITE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); -// -// -template -internal::ValueArray Values(T... v) { - return internal::ValueArray(std::move(v)...); -} - -// Bool() allows generating tests with parameters in a set of (false, true). -// -// Synopsis: -// Bool() -// - returns a generator producing sequences with elements {false, true}. -// -// It is useful when testing code that depends on Boolean flags. Combinations -// of multiple flags can be tested when several Bool()'s are combined using -// Combine() function. -// -// In the following example all tests in the test suite FlagDependentTest -// will be instantiated twice with parameters false and true. -// -// class FlagDependentTest : public testing::TestWithParam { -// virtual void SetUp() { -// external_flag = GetParam(); -// } -// } -// INSTANTIATE_TEST_SUITE_P(BoolSequence, FlagDependentTest, Bool()); -// -inline internal::ParamGenerator Bool() { return Values(false, true); } - -// Combine() allows the user to combine two or more sequences to produce -// values of a Cartesian product of those sequences' elements. -// -// Synopsis: -// Combine(gen1, gen2, ..., genN) -// - returns a generator producing sequences with elements coming from -// the Cartesian product of elements from the sequences generated by -// gen1, gen2, ..., genN. The sequence elements will have a type of -// std::tuple where T1, T2, ..., TN are the types -// of elements from sequences produces by gen1, gen2, ..., genN. -// -// Example: -// -// This will instantiate tests in test suite AnimalTest each one with -// the parameter values tuple("cat", BLACK), tuple("cat", WHITE), -// tuple("dog", BLACK), and tuple("dog", WHITE): -// -// enum Color { BLACK, GRAY, WHITE }; -// class AnimalTest -// : public testing::TestWithParam > {...}; -// -// TEST_P(AnimalTest, AnimalLooksNice) {...} -// -// INSTANTIATE_TEST_SUITE_P(AnimalVariations, AnimalTest, -// Combine(Values("cat", "dog"), -// Values(BLACK, WHITE))); -// -// This will instantiate tests in FlagDependentTest with all variations of two -// Boolean flags: -// -// class FlagDependentTest -// : public testing::TestWithParam > { -// virtual void SetUp() { -// // Assigns external_flag_1 and external_flag_2 values from the tuple. -// std::tie(external_flag_1, external_flag_2) = GetParam(); -// } -// }; -// -// TEST_P(FlagDependentTest, TestFeature1) { -// // Test your code using external_flag_1 and external_flag_2 here. -// } -// INSTANTIATE_TEST_SUITE_P(TwoBoolSequence, FlagDependentTest, -// Combine(Bool(), Bool())); -// -template -internal::CartesianProductHolder Combine(const Generator&... g) { - return internal::CartesianProductHolder(g...); -} - -#define TEST_P(test_suite_name, test_name) \ - class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ - : public test_suite_name { \ - public: \ - GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \ - void TestBody() override; \ - \ - private: \ - static int AddToRegistry() { \ - ::testing::UnitTest::GetInstance() \ - ->parameterized_test_registry() \ - .GetTestSuitePatternHolder( \ - GTEST_STRINGIFY_(test_suite_name), \ - ::testing::internal::CodeLocation(__FILE__, __LINE__)) \ - ->AddTestPattern( \ - GTEST_STRINGIFY_(test_suite_name), GTEST_STRINGIFY_(test_name), \ - new ::testing::internal::TestMetaFactory(), \ - ::testing::internal::CodeLocation(__FILE__, __LINE__)); \ - return 0; \ - } \ - static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \ - GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ - (const GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &) = delete; \ - GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \ - const GTEST_TEST_CLASS_NAME_(test_suite_name, \ - test_name) &) = delete; /* NOLINT */ \ - }; \ - int GTEST_TEST_CLASS_NAME_(test_suite_name, \ - test_name)::gtest_registering_dummy_ = \ - GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::AddToRegistry(); \ - void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody() - -// The last argument to INSTANTIATE_TEST_SUITE_P allows the user to specify -// generator and an optional function or functor that generates custom test name -// suffixes based on the test parameters. Such a function or functor should -// accept one argument of type testing::TestParamInfo, and -// return std::string. -// -// testing::PrintToStringParamName is a builtin test suffix generator that -// returns the value of testing::PrintToString(GetParam()). -// -// Note: test names must be non-empty, unique, and may only contain ASCII -// alphanumeric characters or underscore. Because PrintToString adds quotes -// to std::string and C strings, it won't work for these types. - -#define GTEST_EXPAND_(arg) arg -#define GTEST_GET_FIRST_(first, ...) first -#define GTEST_GET_SECOND_(first, second, ...) second - -#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \ - static ::testing::internal::ParamGenerator \ - gtest_##prefix##test_suite_name##_EvalGenerator_() { \ - return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \ - } \ - static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \ - const ::testing::TestParamInfo& info) { \ - if (::testing::internal::AlwaysFalse()) { \ - ::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \ - __VA_ARGS__, \ - ::testing::internal::DefaultParamName, \ - DUMMY_PARAM_))); \ - auto t = std::make_tuple(__VA_ARGS__); \ - static_assert(std::tuple_size::value <= 2, \ - "Too Many Args!"); \ - } \ - return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \ - __VA_ARGS__, \ - ::testing::internal::DefaultParamName, \ - DUMMY_PARAM_))))(info); \ - } \ - static int gtest_##prefix##test_suite_name##_dummy_ \ - GTEST_ATTRIBUTE_UNUSED_ = \ - ::testing::UnitTest::GetInstance() \ - ->parameterized_test_registry() \ - .GetTestSuitePatternHolder( \ - GTEST_STRINGIFY_(test_suite_name), \ - ::testing::internal::CodeLocation(__FILE__, __LINE__)) \ - ->AddTestSuiteInstantiation( \ - GTEST_STRINGIFY_(prefix), \ - >est_##prefix##test_suite_name##_EvalGenerator_, \ - >est_##prefix##test_suite_name##_EvalGenerateName_, \ - __FILE__, __LINE__) - -// Allow Marking a Parameterized test class as not needing to be instantiated. -#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \ - namespace gtest_do_not_use_outside_namespace_scope {} \ - static const ::testing::internal::MarkAsIgnored gtest_allow_ignore_##T( \ - GTEST_STRINGIFY_(T)) - -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -#define INSTANTIATE_TEST_CASE_P \ - static_assert(::testing::internal::InstantiateTestCase_P_IsDeprecated(), \ - ""); \ - INSTANTIATE_TEST_SUITE_P -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - -} // namespace testing - -#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-printers.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-printers.h deleted file mode 100644 index a91e8b8b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-printers.h +++ /dev/null @@ -1,1048 +0,0 @@ -// Copyright 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Google Test - The Google C++ Testing and Mocking Framework -// -// This file implements a universal value printer that can print a -// value of any type T: -// -// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); -// -// A user can teach this function how to print a class type T by -// defining either operator<<() or PrintTo() in the namespace that -// defines T. More specifically, the FIRST defined function in the -// following list will be used (assuming T is defined in namespace -// foo): -// -// 1. foo::PrintTo(const T&, ostream*) -// 2. operator<<(ostream&, const T&) defined in either foo or the -// global namespace. -// -// However if T is an STL-style container then it is printed element-wise -// unless foo::PrintTo(const T&, ostream*) is defined. Note that -// operator<<() is ignored for container types. -// -// If none of the above is defined, it will print the debug string of -// the value if it is a protocol buffer, or print the raw bytes in the -// value otherwise. -// -// To aid debugging: when T is a reference type, the address of the -// value is also printed; when T is a (const) char pointer, both the -// pointer value and the NUL-terminated string it points to are -// printed. -// -// We also provide some convenient wrappers: -// -// // Prints a value to a string. For a (const or not) char -// // pointer, the NUL-terminated string (but not the pointer) is -// // printed. -// std::string ::testing::PrintToString(const T& value); -// -// // Prints a value tersely: for a reference type, the referenced -// // value (but not the address) is printed; for a (const or not) char -// // pointer, the NUL-terminated string (but not the pointer) is -// // printed. -// void ::testing::internal::UniversalTersePrint(const T& value, ostream*); -// -// // Prints value using the type inferred by the compiler. The difference -// // from UniversalTersePrint() is that this function prints both the -// // pointer and the NUL-terminated string for a (const or not) char pointer. -// void ::testing::internal::UniversalPrint(const T& value, ostream*); -// -// // Prints the fields of a tuple tersely to a string vector, one -// // element for each field. Tuple support must be enabled in -// // gtest-port.h. -// std::vector UniversalTersePrintTupleFieldsToStrings( -// const Tuple& value); -// -// Known limitation: -// -// The print primitives print the elements of an STL-style container -// using the compiler-inferred type of *iter where iter is a -// const_iterator of the container. When const_iterator is an input -// iterator but not a forward iterator, this inferred type may not -// match value_type, and the print output may be incorrect. In -// practice, this is rarely a problem as for most containers -// const_iterator is a forward iterator. We'll fix this if there's an -// actual need for it. Note that this fix cannot rely on value_type -// being defined as many user-defined container types don't have -// value_type. - -// IWYU pragma: private, include "gtest/gtest.h" -// IWYU pragma: friend gtest/.* -// IWYU pragma: friend gmock/.* - -#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ -#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ - -#include -#include -#include // NOLINT -#include -#include -#include -#include -#include -#include - -#include "gtest/internal/gtest-internal.h" -#include "gtest/internal/gtest-port.h" - -namespace testing { - -// Definitions in the internal* namespaces are subject to change without notice. -// DO NOT USE THEM IN USER CODE! -namespace internal { - -template -void UniversalPrint(const T& value, ::std::ostream* os); - -// Used to print an STL-style container when the user doesn't define -// a PrintTo() for it. -struct ContainerPrinter { - template (0)) == sizeof(IsContainer)) && - !IsRecursiveContainer::value>::type> - static void PrintValue(const T& container, std::ostream* os) { - const size_t kMaxCount = 32; // The maximum number of elements to print. - *os << '{'; - size_t count = 0; - for (auto&& elem : container) { - if (count > 0) { - *os << ','; - if (count == kMaxCount) { // Enough has been printed. - *os << " ..."; - break; - } - } - *os << ' '; - // We cannot call PrintTo(elem, os) here as PrintTo() doesn't - // handle `elem` being a native array. - internal::UniversalPrint(elem, os); - ++count; - } - - if (count > 0) { - *os << ' '; - } - *os << '}'; - } -}; - -// Used to print a pointer that is neither a char pointer nor a member -// pointer, when the user doesn't define PrintTo() for it. (A member -// variable pointer or member function pointer doesn't really point to -// a location in the address space. Their representation is -// implementation-defined. Therefore they will be printed as raw -// bytes.) -struct FunctionPointerPrinter { - template ::value>::type> - static void PrintValue(T* p, ::std::ostream* os) { - if (p == nullptr) { - *os << "NULL"; - } else { - // T is a function type, so '*os << p' doesn't do what we want - // (it just prints p as bool). We want to print p as a const - // void*. - *os << reinterpret_cast(p); - } - } -}; - -struct PointerPrinter { - template - static void PrintValue(T* p, ::std::ostream* os) { - if (p == nullptr) { - *os << "NULL"; - } else { - // T is not a function type. We just call << to print p, - // relying on ADL to pick up user-defined << for their pointer - // types, if any. - *os << p; - } - } -}; - -namespace internal_stream_operator_without_lexical_name_lookup { - -// The presence of an operator<< here will terminate lexical scope lookup -// straight away (even though it cannot be a match because of its argument -// types). Thus, the two operator<< calls in StreamPrinter will find only ADL -// candidates. -struct LookupBlocker {}; -void operator<<(LookupBlocker, LookupBlocker); - -struct StreamPrinter { - template ::value>::type, - // Only accept types for which we can find a streaming operator via - // ADL (possibly involving implicit conversions). - typename = decltype(std::declval() - << std::declval())> - static void PrintValue(const T& value, ::std::ostream* os) { - // Call streaming operator found by ADL, possibly with implicit conversions - // of the arguments. - *os << value; - } -}; - -} // namespace internal_stream_operator_without_lexical_name_lookup - -struct ProtobufPrinter { - // We print a protobuf using its ShortDebugString() when the string - // doesn't exceed this many characters; otherwise we print it using - // DebugString() for better readability. - static const size_t kProtobufOneLinerMaxLength = 50; - - template ::value>::type> - static void PrintValue(const T& value, ::std::ostream* os) { - std::string pretty_str = value.ShortDebugString(); - if (pretty_str.length() > kProtobufOneLinerMaxLength) { - pretty_str = "\n" + value.DebugString(); - } - *os << ("<" + pretty_str + ">"); - } -}; - -struct ConvertibleToIntegerPrinter { - // Since T has no << operator or PrintTo() but can be implicitly - // converted to BiggestInt, we print it as a BiggestInt. - // - // Most likely T is an enum type (either named or unnamed), in which - // case printing it as an integer is the desired behavior. In case - // T is not an enum, printing it as an integer is the best we can do - // given that it has no user-defined printer. - static void PrintValue(internal::BiggestInt value, ::std::ostream* os) { - *os << value; - } -}; - -struct ConvertibleToStringViewPrinter { -#if GTEST_INTERNAL_HAS_STRING_VIEW - static void PrintValue(internal::StringView value, ::std::ostream* os) { - internal::UniversalPrint(value, os); - } -#endif -}; - -// Prints the given number of bytes in the given object to the given -// ostream. -GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, - size_t count, ::std::ostream* os); -struct RawBytesPrinter { - // SFINAE on `sizeof` to make sure we have a complete type. - template - static void PrintValue(const T& value, ::std::ostream* os) { - PrintBytesInObjectTo( - static_cast( - // Load bearing cast to void* to support iOS - reinterpret_cast(std::addressof(value))), - sizeof(value), os); - } -}; - -struct FallbackPrinter { - template - static void PrintValue(const T&, ::std::ostream* os) { - *os << "(incomplete type)"; - } -}; - -// Try every printer in order and return the first one that works. -template -struct FindFirstPrinter : FindFirstPrinter {}; - -template -struct FindFirstPrinter< - T, decltype(Printer::PrintValue(std::declval(), nullptr)), - Printer, Printers...> { - using type = Printer; -}; - -// Select the best printer in the following order: -// - Print containers (they have begin/end/etc). -// - Print function pointers. -// - Print object pointers. -// - Use the stream operator, if available. -// - Print protocol buffers. -// - Print types convertible to BiggestInt. -// - Print types convertible to StringView, if available. -// - Fallback to printing the raw bytes of the object. -template -void PrintWithFallback(const T& value, ::std::ostream* os) { - using Printer = typename FindFirstPrinter< - T, void, ContainerPrinter, FunctionPointerPrinter, PointerPrinter, - internal_stream_operator_without_lexical_name_lookup::StreamPrinter, - ProtobufPrinter, ConvertibleToIntegerPrinter, - ConvertibleToStringViewPrinter, RawBytesPrinter, FallbackPrinter>::type; - Printer::PrintValue(value, os); -} - -// FormatForComparison::Format(value) formats a -// value of type ToPrint that is an operand of a comparison assertion -// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in -// the comparison, and is used to help determine the best way to -// format the value. In particular, when the value is a C string -// (char pointer) and the other operand is an STL string object, we -// want to format the C string as a string, since we know it is -// compared by value with the string object. If the value is a char -// pointer but the other operand is not an STL string object, we don't -// know whether the pointer is supposed to point to a NUL-terminated -// string, and thus want to print it as a pointer to be safe. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - -// The default case. -template -class FormatForComparison { - public: - static ::std::string Format(const ToPrint& value) { - return ::testing::PrintToString(value); - } -}; - -// Array. -template -class FormatForComparison { - public: - static ::std::string Format(const ToPrint* value) { - return FormatForComparison::Format(value); - } -}; - -// By default, print C string as pointers to be safe, as we don't know -// whether they actually point to a NUL-terminated string. - -#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \ - template \ - class FormatForComparison { \ - public: \ - static ::std::string Format(CharType* value) { \ - return ::testing::PrintToString(static_cast(value)); \ - } \ - } - -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char); -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char); -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t); -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t); -#ifdef __cpp_lib_char8_t -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char8_t); -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char8_t); -#endif -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char16_t); -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char16_t); -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char32_t); -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char32_t); - -#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_ - -// If a C string is compared with an STL string object, we know it's meant -// to point to a NUL-terminated string, and thus can print it as a string. - -#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \ - template <> \ - class FormatForComparison { \ - public: \ - static ::std::string Format(CharType* value) { \ - return ::testing::PrintToString(value); \ - } \ - } - -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); -#ifdef __cpp_char8_t -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char8_t, ::std::u8string); -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char8_t, ::std::u8string); -#endif -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char16_t, ::std::u16string); -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char16_t, ::std::u16string); -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char32_t, ::std::u32string); -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char32_t, ::std::u32string); - -#if GTEST_HAS_STD_WSTRING -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring); -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring); -#endif - -#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_ - -// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) -// operand to be used in a failure message. The type (but not value) -// of the other operand may affect the format. This allows us to -// print a char* as a raw pointer when it is compared against another -// char* or void*, and print it as a C string when it is compared -// against an std::string object, for example. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -template -std::string FormatForComparisonFailureMessage(const T1& value, - const T2& /* other_operand */) { - return FormatForComparison::Format(value); -} - -// UniversalPrinter::Print(value, ostream_ptr) prints the given -// value to the given ostream. The caller must ensure that -// 'ostream_ptr' is not NULL, or the behavior is undefined. -// -// We define UniversalPrinter as a class template (as opposed to a -// function template), as we need to partially specialize it for -// reference types, which cannot be done with function templates. -template -class UniversalPrinter; - -// Prints the given value using the << operator if it has one; -// otherwise prints the bytes in it. This is what -// UniversalPrinter::Print() does when PrintTo() is not specialized -// or overloaded for type T. -// -// A user can override this behavior for a class type Foo by defining -// an overload of PrintTo() in the namespace where Foo is defined. We -// give the user this option as sometimes defining a << operator for -// Foo is not desirable (e.g. the coding style may prevent doing it, -// or there is already a << operator but it doesn't do what the user -// wants). -template -void PrintTo(const T& value, ::std::ostream* os) { - internal::PrintWithFallback(value, os); -} - -// The following list of PrintTo() overloads tells -// UniversalPrinter::Print() how to print standard types (built-in -// types, strings, plain arrays, and pointers). - -// Overloads for various char types. -GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os); -GTEST_API_ void PrintTo(signed char c, ::std::ostream* os); -inline void PrintTo(char c, ::std::ostream* os) { - // When printing a plain char, we always treat it as unsigned. This - // way, the output won't be affected by whether the compiler thinks - // char is signed or not. - PrintTo(static_cast(c), os); -} - -// Overloads for other simple built-in types. -inline void PrintTo(bool x, ::std::ostream* os) { - *os << (x ? "true" : "false"); -} - -// Overload for wchar_t type. -// Prints a wchar_t as a symbol if it is printable or as its internal -// code otherwise and also as its decimal code (except for L'\0'). -// The L'\0' char is printed as "L'\\0'". The decimal code is printed -// as signed integer when wchar_t is implemented by the compiler -// as a signed type and is printed as an unsigned integer when wchar_t -// is implemented as an unsigned type. -GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os); - -GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os); -inline void PrintTo(char16_t c, ::std::ostream* os) { - PrintTo(ImplicitCast_(c), os); -} -#ifdef __cpp_char8_t -inline void PrintTo(char8_t c, ::std::ostream* os) { - PrintTo(ImplicitCast_(c), os); -} -#endif - -// gcc/clang __{u,}int128_t -#if defined(__SIZEOF_INT128__) -GTEST_API_ void PrintTo(__uint128_t v, ::std::ostream* os); -GTEST_API_ void PrintTo(__int128_t v, ::std::ostream* os); -#endif // __SIZEOF_INT128__ - -// Overloads for C strings. -GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); -inline void PrintTo(char* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); -} - -// signed/unsigned char is often used for representing binary data, so -// we print pointers to it as void* to be safe. -inline void PrintTo(const signed char* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); -} -inline void PrintTo(signed char* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); -} -inline void PrintTo(const unsigned char* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); -} -inline void PrintTo(unsigned char* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); -} -#ifdef __cpp_char8_t -// Overloads for u8 strings. -GTEST_API_ void PrintTo(const char8_t* s, ::std::ostream* os); -inline void PrintTo(char8_t* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); -} -#endif -// Overloads for u16 strings. -GTEST_API_ void PrintTo(const char16_t* s, ::std::ostream* os); -inline void PrintTo(char16_t* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); -} -// Overloads for u32 strings. -GTEST_API_ void PrintTo(const char32_t* s, ::std::ostream* os); -inline void PrintTo(char32_t* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); -} - -// MSVC can be configured to define wchar_t as a typedef of unsigned -// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native -// type. When wchar_t is a typedef, defining an overload for const -// wchar_t* would cause unsigned short* be printed as a wide string, -// possibly causing invalid memory accesses. -#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) -// Overloads for wide C strings -GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); -inline void PrintTo(wchar_t* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); -} -#endif - -// Overload for C arrays. Multi-dimensional arrays are printed -// properly. - -// Prints the given number of elements in an array, without printing -// the curly braces. -template -void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) { - UniversalPrint(a[0], os); - for (size_t i = 1; i != count; i++) { - *os << ", "; - UniversalPrint(a[i], os); - } -} - -// Overloads for ::std::string. -GTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os); -inline void PrintTo(const ::std::string& s, ::std::ostream* os) { - PrintStringTo(s, os); -} - -// Overloads for ::std::u8string -#ifdef __cpp_char8_t -GTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os); -inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) { - PrintU8StringTo(s, os); -} -#endif - -// Overloads for ::std::u16string -GTEST_API_ void PrintU16StringTo(const ::std::u16string& s, ::std::ostream* os); -inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) { - PrintU16StringTo(s, os); -} - -// Overloads for ::std::u32string -GTEST_API_ void PrintU32StringTo(const ::std::u32string& s, ::std::ostream* os); -inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) { - PrintU32StringTo(s, os); -} - -// Overloads for ::std::wstring. -#if GTEST_HAS_STD_WSTRING -GTEST_API_ void PrintWideStringTo(const ::std::wstring& s, ::std::ostream* os); -inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { - PrintWideStringTo(s, os); -} -#endif // GTEST_HAS_STD_WSTRING - -#if GTEST_INTERNAL_HAS_STRING_VIEW -// Overload for internal::StringView. -inline void PrintTo(internal::StringView sp, ::std::ostream* os) { - PrintTo(::std::string(sp), os); -} -#endif // GTEST_INTERNAL_HAS_STRING_VIEW - -inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; } - -#if GTEST_HAS_RTTI -inline void PrintTo(const std::type_info& info, std::ostream* os) { - *os << internal::GetTypeName(info); -} -#endif // GTEST_HAS_RTTI - -template -void PrintTo(std::reference_wrapper ref, ::std::ostream* os) { - UniversalPrinter::Print(ref.get(), os); -} - -inline const void* VoidifyPointer(const void* p) { return p; } -inline const void* VoidifyPointer(volatile const void* p) { - return const_cast(p); -} - -template -void PrintSmartPointer(const Ptr& ptr, std::ostream* os, char) { - if (ptr == nullptr) { - *os << "(nullptr)"; - } else { - // We can't print the value. Just print the pointer.. - *os << "(" << (VoidifyPointer)(ptr.get()) << ")"; - } -} -template ::value && - !std::is_array::value>::type> -void PrintSmartPointer(const Ptr& ptr, std::ostream* os, int) { - if (ptr == nullptr) { - *os << "(nullptr)"; - } else { - *os << "(ptr = " << (VoidifyPointer)(ptr.get()) << ", value = "; - UniversalPrinter::Print(*ptr, os); - *os << ")"; - } -} - -template -void PrintTo(const std::unique_ptr& ptr, std::ostream* os) { - (PrintSmartPointer)(ptr, os, 0); -} - -template -void PrintTo(const std::shared_ptr& ptr, std::ostream* os) { - (PrintSmartPointer)(ptr, os, 0); -} - -// Helper function for printing a tuple. T must be instantiated with -// a tuple type. -template -void PrintTupleTo(const T&, std::integral_constant, - ::std::ostream*) {} - -template -void PrintTupleTo(const T& t, std::integral_constant, - ::std::ostream* os) { - PrintTupleTo(t, std::integral_constant(), os); - GTEST_INTENTIONAL_CONST_COND_PUSH_() - if (I > 1) { - GTEST_INTENTIONAL_CONST_COND_POP_() - *os << ", "; - } - UniversalPrinter::type>::Print( - std::get(t), os); -} - -template -void PrintTo(const ::std::tuple& t, ::std::ostream* os) { - *os << "("; - PrintTupleTo(t, std::integral_constant(), os); - *os << ")"; -} - -// Overload for std::pair. -template -void PrintTo(const ::std::pair& value, ::std::ostream* os) { - *os << '('; - // We cannot use UniversalPrint(value.first, os) here, as T1 may be - // a reference type. The same for printing value.second. - UniversalPrinter::Print(value.first, os); - *os << ", "; - UniversalPrinter::Print(value.second, os); - *os << ')'; -} - -// Implements printing a non-reference type T by letting the compiler -// pick the right overload of PrintTo() for T. -template -class UniversalPrinter { - public: - // MSVC warns about adding const to a function type, so we want to - // disable the warning. - GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180) - - // Note: we deliberately don't call this PrintTo(), as that name - // conflicts with ::testing::internal::PrintTo in the body of the - // function. - static void Print(const T& value, ::std::ostream* os) { - // By default, ::testing::internal::PrintTo() is used for printing - // the value. - // - // Thanks to Koenig look-up, if T is a class and has its own - // PrintTo() function defined in its namespace, that function will - // be visible here. Since it is more specific than the generic ones - // in ::testing::internal, it will be picked by the compiler in the - // following statement - exactly what we want. - PrintTo(value, os); - } - - GTEST_DISABLE_MSC_WARNINGS_POP_() -}; - -// Remove any const-qualifiers before passing a type to UniversalPrinter. -template -class UniversalPrinter : public UniversalPrinter {}; - -#if GTEST_INTERNAL_HAS_ANY - -// Printer for std::any / absl::any - -template <> -class UniversalPrinter { - public: - static void Print(const Any& value, ::std::ostream* os) { - if (value.has_value()) { - *os << "value of type " << GetTypeName(value); - } else { - *os << "no value"; - } - } - - private: - static std::string GetTypeName(const Any& value) { -#if GTEST_HAS_RTTI - return internal::GetTypeName(value.type()); -#else - static_cast(value); // possibly unused - return ""; -#endif // GTEST_HAS_RTTI - } -}; - -#endif // GTEST_INTERNAL_HAS_ANY - -#if GTEST_INTERNAL_HAS_OPTIONAL - -// Printer for std::optional / absl::optional - -template -class UniversalPrinter> { - public: - static void Print(const Optional& value, ::std::ostream* os) { - *os << '('; - if (!value) { - *os << "nullopt"; - } else { - UniversalPrint(*value, os); - } - *os << ')'; - } -}; - -template <> -class UniversalPrinter { - public: - static void Print(decltype(Nullopt()), ::std::ostream* os) { - *os << "(nullopt)"; - } -}; - -#endif // GTEST_INTERNAL_HAS_OPTIONAL - -#if GTEST_INTERNAL_HAS_VARIANT - -// Printer for std::variant / absl::variant - -template -class UniversalPrinter> { - public: - static void Print(const Variant& value, ::std::ostream* os) { - *os << '('; -#if GTEST_HAS_ABSL - absl::visit(Visitor{os, value.index()}, value); -#else - std::visit(Visitor{os, value.index()}, value); -#endif // GTEST_HAS_ABSL - *os << ')'; - } - - private: - struct Visitor { - template - void operator()(const U& u) const { - *os << "'" << GetTypeName() << "(index = " << index - << ")' with value "; - UniversalPrint(u, os); - } - ::std::ostream* os; - std::size_t index; - }; -}; - -#endif // GTEST_INTERNAL_HAS_VARIANT - -// UniversalPrintArray(begin, len, os) prints an array of 'len' -// elements, starting at address 'begin'. -template -void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { - if (len == 0) { - *os << "{}"; - } else { - *os << "{ "; - const size_t kThreshold = 18; - const size_t kChunkSize = 8; - // If the array has more than kThreshold elements, we'll have to - // omit some details by printing only the first and the last - // kChunkSize elements. - if (len <= kThreshold) { - PrintRawArrayTo(begin, len, os); - } else { - PrintRawArrayTo(begin, kChunkSize, os); - *os << ", ..., "; - PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os); - } - *os << " }"; - } -} -// This overload prints a (const) char array compactly. -GTEST_API_ void UniversalPrintArray(const char* begin, size_t len, - ::std::ostream* os); - -#ifdef __cpp_char8_t -// This overload prints a (const) char8_t array compactly. -GTEST_API_ void UniversalPrintArray(const char8_t* begin, size_t len, - ::std::ostream* os); -#endif - -// This overload prints a (const) char16_t array compactly. -GTEST_API_ void UniversalPrintArray(const char16_t* begin, size_t len, - ::std::ostream* os); - -// This overload prints a (const) char32_t array compactly. -GTEST_API_ void UniversalPrintArray(const char32_t* begin, size_t len, - ::std::ostream* os); - -// This overload prints a (const) wchar_t array compactly. -GTEST_API_ void UniversalPrintArray(const wchar_t* begin, size_t len, - ::std::ostream* os); - -// Implements printing an array type T[N]. -template -class UniversalPrinter { - public: - // Prints the given array, omitting some elements when there are too - // many. - static void Print(const T (&a)[N], ::std::ostream* os) { - UniversalPrintArray(a, N, os); - } -}; - -// Implements printing a reference type T&. -template -class UniversalPrinter { - public: - // MSVC warns about adding const to a function type, so we want to - // disable the warning. - GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180) - - static void Print(const T& value, ::std::ostream* os) { - // Prints the address of the value. We use reinterpret_cast here - // as static_cast doesn't compile when T is a function type. - *os << "@" << reinterpret_cast(&value) << " "; - - // Then prints the value itself. - UniversalPrint(value, os); - } - - GTEST_DISABLE_MSC_WARNINGS_POP_() -}; - -// Prints a value tersely: for a reference type, the referenced value -// (but not the address) is printed; for a (const) char pointer, the -// NUL-terminated string (but not the pointer) is printed. - -template -class UniversalTersePrinter { - public: - static void Print(const T& value, ::std::ostream* os) { - UniversalPrint(value, os); - } -}; -template -class UniversalTersePrinter { - public: - static void Print(const T& value, ::std::ostream* os) { - UniversalPrint(value, os); - } -}; -template -class UniversalTersePrinter { - public: - static void Print(const T (&value)[N], ::std::ostream* os) { - UniversalPrinter::Print(value, os); - } -}; -template <> -class UniversalTersePrinter { - public: - static void Print(const char* str, ::std::ostream* os) { - if (str == nullptr) { - *os << "NULL"; - } else { - UniversalPrint(std::string(str), os); - } - } -}; -template <> -class UniversalTersePrinter : public UniversalTersePrinter { -}; - -#ifdef __cpp_char8_t -template <> -class UniversalTersePrinter { - public: - static void Print(const char8_t* str, ::std::ostream* os) { - if (str == nullptr) { - *os << "NULL"; - } else { - UniversalPrint(::std::u8string(str), os); - } - } -}; -template <> -class UniversalTersePrinter - : public UniversalTersePrinter {}; -#endif - -template <> -class UniversalTersePrinter { - public: - static void Print(const char16_t* str, ::std::ostream* os) { - if (str == nullptr) { - *os << "NULL"; - } else { - UniversalPrint(::std::u16string(str), os); - } - } -}; -template <> -class UniversalTersePrinter - : public UniversalTersePrinter {}; - -template <> -class UniversalTersePrinter { - public: - static void Print(const char32_t* str, ::std::ostream* os) { - if (str == nullptr) { - *os << "NULL"; - } else { - UniversalPrint(::std::u32string(str), os); - } - } -}; -template <> -class UniversalTersePrinter - : public UniversalTersePrinter {}; - -#if GTEST_HAS_STD_WSTRING -template <> -class UniversalTersePrinter { - public: - static void Print(const wchar_t* str, ::std::ostream* os) { - if (str == nullptr) { - *os << "NULL"; - } else { - UniversalPrint(::std::wstring(str), os); - } - } -}; -#endif - -template <> -class UniversalTersePrinter { - public: - static void Print(wchar_t* str, ::std::ostream* os) { - UniversalTersePrinter::Print(str, os); - } -}; - -template -void UniversalTersePrint(const T& value, ::std::ostream* os) { - UniversalTersePrinter::Print(value, os); -} - -// Prints a value using the type inferred by the compiler. The -// difference between this and UniversalTersePrint() is that for a -// (const) char pointer, this prints both the pointer and the -// NUL-terminated string. -template -void UniversalPrint(const T& value, ::std::ostream* os) { - // A workarond for the bug in VC++ 7.1 that prevents us from instantiating - // UniversalPrinter with T directly. - typedef T T1; - UniversalPrinter::Print(value, os); -} - -typedef ::std::vector<::std::string> Strings; - -// Tersely prints the first N fields of a tuple to a string vector, -// one element for each field. -template -void TersePrintPrefixToStrings(const Tuple&, std::integral_constant, - Strings*) {} -template -void TersePrintPrefixToStrings(const Tuple& t, - std::integral_constant, - Strings* strings) { - TersePrintPrefixToStrings(t, std::integral_constant(), - strings); - ::std::stringstream ss; - UniversalTersePrint(std::get(t), &ss); - strings->push_back(ss.str()); -} - -// Prints the fields of a tuple tersely to a string vector, one -// element for each field. See the comment before -// UniversalTersePrint() for how we define "tersely". -template -Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { - Strings result; - TersePrintPrefixToStrings( - value, std::integral_constant::value>(), - &result); - return result; -} - -} // namespace internal - -template -::std::string PrintToString(const T& value) { - ::std::stringstream ss; - internal::UniversalTersePrinter::Print(value, &ss); - return ss.str(); -} - -} // namespace testing - -// Include any custom printer added by the local installation. -// We must include this header at the end to make sure it can use the -// declarations from this file. -#include "gtest/internal/custom/gtest-printers.h" - -#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-spi.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-spi.h deleted file mode 100644 index bec8c481..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-spi.h +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Utilities for testing Google Test itself and code that uses Google Test -// (e.g. frameworks built on top of Google Test). - -#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_ -#define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_ - -#include "gtest/gtest.h" - -GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ -/* class A needs to have dll-interface to be used by clients of class B */) - -namespace testing { - -// This helper class can be used to mock out Google Test failure reporting -// so that we can test Google Test or code that builds on Google Test. -// -// An object of this class appends a TestPartResult object to the -// TestPartResultArray object given in the constructor whenever a Google Test -// failure is reported. It can either intercept only failures that are -// generated in the same thread that created this object or it can intercept -// all generated failures. The scope of this mock object can be controlled with -// the second argument to the two arguments constructor. -class GTEST_API_ ScopedFakeTestPartResultReporter - : public TestPartResultReporterInterface { - public: - // The two possible mocking modes of this object. - enum InterceptMode { - INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. - INTERCEPT_ALL_THREADS // Intercepts all failures. - }; - - // The c'tor sets this object as the test part result reporter used - // by Google Test. The 'result' parameter specifies where to report the - // results. This reporter will only catch failures generated in the current - // thread. DEPRECATED - explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); - - // Same as above, but you can choose the interception scope of this object. - ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, - TestPartResultArray* result); - - // The d'tor restores the previous test part result reporter. - ~ScopedFakeTestPartResultReporter() override; - - // Appends the TestPartResult object to the TestPartResultArray - // received in the constructor. - // - // This method is from the TestPartResultReporterInterface - // interface. - void ReportTestPartResult(const TestPartResult& result) override; - - private: - void Init(); - - const InterceptMode intercept_mode_; - TestPartResultReporterInterface* old_reporter_; - TestPartResultArray* const result_; - - ScopedFakeTestPartResultReporter(const ScopedFakeTestPartResultReporter&) = - delete; - ScopedFakeTestPartResultReporter& operator=( - const ScopedFakeTestPartResultReporter&) = delete; -}; - -namespace internal { - -// A helper class for implementing EXPECT_FATAL_FAILURE() and -// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given -// TestPartResultArray contains exactly one failure that has the given -// type and contains the given substring. If that's not the case, a -// non-fatal failure will be generated. -class GTEST_API_ SingleFailureChecker { - public: - // The constructor remembers the arguments. - SingleFailureChecker(const TestPartResultArray* results, - TestPartResult::Type type, const std::string& substr); - ~SingleFailureChecker(); - - private: - const TestPartResultArray* const results_; - const TestPartResult::Type type_; - const std::string substr_; - - SingleFailureChecker(const SingleFailureChecker&) = delete; - SingleFailureChecker& operator=(const SingleFailureChecker&) = delete; -}; - -} // namespace internal - -} // namespace testing - -GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 - -// A set of macros for testing Google Test assertions or code that's expected -// to generate Google Test fatal failures (e.g. a failure from an ASSERT_EQ, but -// not a non-fatal failure, as from EXPECT_EQ). It verifies that the given -// statement will cause exactly one fatal Google Test failure with 'substr' -// being part of the failure message. -// -// There are two different versions of this macro. EXPECT_FATAL_FAILURE only -// affects and considers failures generated in the current thread and -// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. -// -// The verification of the assertion is done correctly even when the statement -// throws an exception or aborts the current function. -// -// Known restrictions: -// - 'statement' cannot reference local non-static variables or -// non-static members of the current object. -// - 'statement' cannot return a value. -// - You cannot stream a failure message to this macro. -// -// Note that even though the implementations of the following two -// macros are much alike, we cannot refactor them to use a common -// helper macro, due to some peculiarity in how the preprocessor -// works. The AcceptsMacroThatExpandsToUnprotectedComma test in -// gtest_unittest.cc will fail to compile if we do that. -#define EXPECT_FATAL_FAILURE(statement, substr) \ - do { \ - class GTestExpectFatalFailureHelper { \ - public: \ - static void Execute() { statement; } \ - }; \ - ::testing::TestPartResultArray gtest_failures; \ - ::testing::internal::SingleFailureChecker gtest_checker( \ - >est_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \ - { \ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ - ::testing::ScopedFakeTestPartResultReporter:: \ - INTERCEPT_ONLY_CURRENT_THREAD, \ - >est_failures); \ - GTestExpectFatalFailureHelper::Execute(); \ - } \ - } while (::testing::internal::AlwaysFalse()) - -#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ - do { \ - class GTestExpectFatalFailureHelper { \ - public: \ - static void Execute() { statement; } \ - }; \ - ::testing::TestPartResultArray gtest_failures; \ - ::testing::internal::SingleFailureChecker gtest_checker( \ - >est_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \ - { \ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ - ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ - >est_failures); \ - GTestExpectFatalFailureHelper::Execute(); \ - } \ - } while (::testing::internal::AlwaysFalse()) - -// A macro for testing Google Test assertions or code that's expected to -// generate Google Test non-fatal failures (e.g. a failure from an EXPECT_EQ, -// but not from an ASSERT_EQ). It asserts that the given statement will cause -// exactly one non-fatal Google Test failure with 'substr' being part of the -// failure message. -// -// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only -// affects and considers failures generated in the current thread and -// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. -// -// 'statement' is allowed to reference local variables and members of -// the current object. -// -// The verification of the assertion is done correctly even when the statement -// throws an exception or aborts the current function. -// -// Known restrictions: -// - You cannot stream a failure message to this macro. -// -// Note that even though the implementations of the following two -// macros are much alike, we cannot refactor them to use a common -// helper macro, due to some peculiarity in how the preprocessor -// works. If we do that, the code won't compile when the user gives -// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that -// expands to code containing an unprotected comma. The -// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc -// catches that. -// -// For the same reason, we have to write -// if (::testing::internal::AlwaysTrue()) { statement; } -// instead of -// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) -// to avoid an MSVC warning on unreachable code. -#define EXPECT_NONFATAL_FAILURE(statement, substr) \ - do { \ - ::testing::TestPartResultArray gtest_failures; \ - ::testing::internal::SingleFailureChecker gtest_checker( \ - >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ - (substr)); \ - { \ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ - ::testing::ScopedFakeTestPartResultReporter:: \ - INTERCEPT_ONLY_CURRENT_THREAD, \ - >est_failures); \ - if (::testing::internal::AlwaysTrue()) { \ - statement; \ - } \ - } \ - } while (::testing::internal::AlwaysFalse()) - -#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ - do { \ - ::testing::TestPartResultArray gtest_failures; \ - ::testing::internal::SingleFailureChecker gtest_checker( \ - >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ - (substr)); \ - { \ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ - ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ - >est_failures); \ - if (::testing::internal::AlwaysTrue()) { \ - statement; \ - } \ - } \ - } while (::testing::internal::AlwaysFalse()) - -#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-test-part.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-test-part.h deleted file mode 100644 index 09cc8c34..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-test-part.h +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// IWYU pragma: private, include "gtest/gtest.h" -// IWYU pragma: friend gtest/.* -// IWYU pragma: friend gmock/.* - -#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ -#define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ - -#include -#include - -#include "gtest/internal/gtest-internal.h" -#include "gtest/internal/gtest-string.h" - -GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ -/* class A needs to have dll-interface to be used by clients of class B */) - -namespace testing { - -// A copyable object representing the result of a test part (i.e. an -// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). -// -// Don't inherit from TestPartResult as its destructor is not virtual. -class GTEST_API_ TestPartResult { - public: - // The possible outcomes of a test part (i.e. an assertion or an - // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). - enum Type { - kSuccess, // Succeeded. - kNonFatalFailure, // Failed but the test can continue. - kFatalFailure, // Failed and the test should be terminated. - kSkip // Skipped. - }; - - // C'tor. TestPartResult does NOT have a default constructor. - // Always use this constructor (with parameters) to create a - // TestPartResult object. - TestPartResult(Type a_type, const char* a_file_name, int a_line_number, - const char* a_message) - : type_(a_type), - file_name_(a_file_name == nullptr ? "" : a_file_name), - line_number_(a_line_number), - summary_(ExtractSummary(a_message)), - message_(a_message) {} - - // Gets the outcome of the test part. - Type type() const { return type_; } - - // Gets the name of the source file where the test part took place, or - // NULL if it's unknown. - const char* file_name() const { - return file_name_.empty() ? nullptr : file_name_.c_str(); - } - - // Gets the line in the source file where the test part took place, - // or -1 if it's unknown. - int line_number() const { return line_number_; } - - // Gets the summary of the failure message. - const char* summary() const { return summary_.c_str(); } - - // Gets the message associated with the test part. - const char* message() const { return message_.c_str(); } - - // Returns true if and only if the test part was skipped. - bool skipped() const { return type_ == kSkip; } - - // Returns true if and only if the test part passed. - bool passed() const { return type_ == kSuccess; } - - // Returns true if and only if the test part non-fatally failed. - bool nonfatally_failed() const { return type_ == kNonFatalFailure; } - - // Returns true if and only if the test part fatally failed. - bool fatally_failed() const { return type_ == kFatalFailure; } - - // Returns true if and only if the test part failed. - bool failed() const { return fatally_failed() || nonfatally_failed(); } - - private: - Type type_; - - // Gets the summary of the failure message by omitting the stack - // trace in it. - static std::string ExtractSummary(const char* message); - - // The name of the source file where the test part took place, or - // "" if the source file is unknown. - std::string file_name_; - // The line in the source file where the test part took place, or -1 - // if the line number is unknown. - int line_number_; - std::string summary_; // The test failure summary. - std::string message_; // The test failure message. -}; - -// Prints a TestPartResult object. -std::ostream& operator<<(std::ostream& os, const TestPartResult& result); - -// An array of TestPartResult objects. -// -// Don't inherit from TestPartResultArray as its destructor is not -// virtual. -class GTEST_API_ TestPartResultArray { - public: - TestPartResultArray() {} - - // Appends the given TestPartResult to the array. - void Append(const TestPartResult& result); - - // Returns the TestPartResult at the given index (0-based). - const TestPartResult& GetTestPartResult(int index) const; - - // Returns the number of TestPartResult objects in the array. - int size() const; - - private: - std::vector array_; - - TestPartResultArray(const TestPartResultArray&) = delete; - TestPartResultArray& operator=(const TestPartResultArray&) = delete; -}; - -// This interface knows how to report a test part result. -class GTEST_API_ TestPartResultReporterInterface { - public: - virtual ~TestPartResultReporterInterface() {} - - virtual void ReportTestPartResult(const TestPartResult& result) = 0; -}; - -namespace internal { - -// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a -// statement generates new fatal failures. To do so it registers itself as the -// current test part result reporter. Besides checking if fatal failures were -// reported, it only delegates the reporting to the former result reporter. -// The original result reporter is restored in the destructor. -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -class GTEST_API_ HasNewFatalFailureHelper - : public TestPartResultReporterInterface { - public: - HasNewFatalFailureHelper(); - ~HasNewFatalFailureHelper() override; - void ReportTestPartResult(const TestPartResult& result) override; - bool has_new_fatal_failure() const { return has_new_fatal_failure_; } - - private: - bool has_new_fatal_failure_; - TestPartResultReporterInterface* original_reporter_; - - HasNewFatalFailureHelper(const HasNewFatalFailureHelper&) = delete; - HasNewFatalFailureHelper& operator=(const HasNewFatalFailureHelper&) = delete; -}; - -} // namespace internal - -} // namespace testing - -GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 - -#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-typed-test.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-typed-test.h deleted file mode 100644 index bd35a326..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest-typed-test.h +++ /dev/null @@ -1,331 +0,0 @@ -// Copyright 2008 Google Inc. -// All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// IWYU pragma: private, include "gtest/gtest.h" -// IWYU pragma: friend gtest/.* -// IWYU pragma: friend gmock/.* - -#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ -#define GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ - -// This header implements typed tests and type-parameterized tests. - -// Typed (aka type-driven) tests repeat the same test for types in a -// list. You must know which types you want to test with when writing -// typed tests. Here's how you do it: - -#if 0 - -// First, define a fixture class template. It should be parameterized -// by a type. Remember to derive it from testing::Test. -template -class FooTest : public testing::Test { - public: - ... - typedef std::list List; - static T shared_; - T value_; -}; - -// Next, associate a list of types with the test suite, which will be -// repeated for each type in the list. The typedef is necessary for -// the macro to parse correctly. -typedef testing::Types MyTypes; -TYPED_TEST_SUITE(FooTest, MyTypes); - -// If the type list contains only one type, you can write that type -// directly without Types<...>: -// TYPED_TEST_SUITE(FooTest, int); - -// Then, use TYPED_TEST() instead of TEST_F() to define as many typed -// tests for this test suite as you want. -TYPED_TEST(FooTest, DoesBlah) { - // Inside a test, refer to the special name TypeParam to get the type - // parameter. Since we are inside a derived class template, C++ requires - // us to visit the members of FooTest via 'this'. - TypeParam n = this->value_; - - // To visit static members of the fixture, add the TestFixture:: - // prefix. - n += TestFixture::shared_; - - // To refer to typedefs in the fixture, add the "typename - // TestFixture::" prefix. - typename TestFixture::List values; - values.push_back(n); - ... -} - -TYPED_TEST(FooTest, HasPropertyA) { ... } - -// TYPED_TEST_SUITE takes an optional third argument which allows to specify a -// class that generates custom test name suffixes based on the type. This should -// be a class which has a static template function GetName(int index) returning -// a string for each type. The provided integer index equals the index of the -// type in the provided type list. In many cases the index can be ignored. -// -// For example: -// class MyTypeNames { -// public: -// template -// static std::string GetName(int) { -// if (std::is_same()) return "char"; -// if (std::is_same()) return "int"; -// if (std::is_same()) return "unsignedInt"; -// } -// }; -// TYPED_TEST_SUITE(FooTest, MyTypes, MyTypeNames); - -#endif // 0 - -// Type-parameterized tests are abstract test patterns parameterized -// by a type. Compared with typed tests, type-parameterized tests -// allow you to define the test pattern without knowing what the type -// parameters are. The defined pattern can be instantiated with -// different types any number of times, in any number of translation -// units. -// -// If you are designing an interface or concept, you can define a -// suite of type-parameterized tests to verify properties that any -// valid implementation of the interface/concept should have. Then, -// each implementation can easily instantiate the test suite to verify -// that it conforms to the requirements, without having to write -// similar tests repeatedly. Here's an example: - -#if 0 - -// First, define a fixture class template. It should be parameterized -// by a type. Remember to derive it from testing::Test. -template -class FooTest : public testing::Test { - ... -}; - -// Next, declare that you will define a type-parameterized test suite -// (the _P suffix is for "parameterized" or "pattern", whichever you -// prefer): -TYPED_TEST_SUITE_P(FooTest); - -// Then, use TYPED_TEST_P() to define as many type-parameterized tests -// for this type-parameterized test suite as you want. -TYPED_TEST_P(FooTest, DoesBlah) { - // Inside a test, refer to TypeParam to get the type parameter. - TypeParam n = 0; - ... -} - -TYPED_TEST_P(FooTest, HasPropertyA) { ... } - -// Now the tricky part: you need to register all test patterns before -// you can instantiate them. The first argument of the macro is the -// test suite name; the rest are the names of the tests in this test -// case. -REGISTER_TYPED_TEST_SUITE_P(FooTest, - DoesBlah, HasPropertyA); - -// Finally, you are free to instantiate the pattern with the types you -// want. If you put the above code in a header file, you can #include -// it in multiple C++ source files and instantiate it multiple times. -// -// To distinguish different instances of the pattern, the first -// argument to the INSTANTIATE_* macro is a prefix that will be added -// to the actual test suite name. Remember to pick unique prefixes for -// different instances. -typedef testing::Types MyTypes; -INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); - -// If the type list contains only one type, you can write that type -// directly without Types<...>: -// INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, int); -// -// Similar to the optional argument of TYPED_TEST_SUITE above, -// INSTANTIATE_TEST_SUITE_P takes an optional fourth argument which allows to -// generate custom names. -// INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes, MyTypeNames); - -#endif // 0 - -#include "gtest/internal/gtest-internal.h" -#include "gtest/internal/gtest-port.h" -#include "gtest/internal/gtest-type-util.h" - -// Implements typed tests. - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// Expands to the name of the typedef for the type parameters of the -// given test suite. -#define GTEST_TYPE_PARAMS_(TestSuiteName) gtest_type_params_##TestSuiteName##_ - -// Expands to the name of the typedef for the NameGenerator, responsible for -// creating the suffixes of the name. -#define GTEST_NAME_GENERATOR_(TestSuiteName) \ - gtest_type_params_##TestSuiteName##_NameGenerator - -#define TYPED_TEST_SUITE(CaseName, Types, ...) \ - typedef ::testing::internal::GenerateTypeList::type \ - GTEST_TYPE_PARAMS_(CaseName); \ - typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \ - GTEST_NAME_GENERATOR_(CaseName) - -#define TYPED_TEST(CaseName, TestName) \ - static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \ - "test-name must not be empty"); \ - template \ - class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ - : public CaseName { \ - private: \ - typedef CaseName TestFixture; \ - typedef gtest_TypeParam_ TypeParam; \ - void TestBody() override; \ - }; \ - static bool gtest_##CaseName##_##TestName##_registered_ \ - GTEST_ATTRIBUTE_UNUSED_ = ::testing::internal::TypeParameterizedTest< \ - CaseName, \ - ::testing::internal::TemplateSel, \ - GTEST_TYPE_PARAMS_( \ - CaseName)>::Register("", \ - ::testing::internal::CodeLocation( \ - __FILE__, __LINE__), \ - GTEST_STRINGIFY_(CaseName), \ - GTEST_STRINGIFY_(TestName), 0, \ - ::testing::internal::GenerateNames< \ - GTEST_NAME_GENERATOR_(CaseName), \ - GTEST_TYPE_PARAMS_(CaseName)>()); \ - template \ - void GTEST_TEST_CLASS_NAME_(CaseName, \ - TestName)::TestBody() - -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -#define TYPED_TEST_CASE \ - static_assert(::testing::internal::TypedTestCaseIsDeprecated(), ""); \ - TYPED_TEST_SUITE -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - -// Implements type-parameterized tests. - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// Expands to the namespace name that the type-parameterized tests for -// the given type-parameterized test suite are defined in. The exact -// name of the namespace is subject to change without notice. -#define GTEST_SUITE_NAMESPACE_(TestSuiteName) gtest_suite_##TestSuiteName##_ - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// Expands to the name of the variable used to remember the names of -// the defined tests in the given test suite. -#define GTEST_TYPED_TEST_SUITE_P_STATE_(TestSuiteName) \ - gtest_typed_test_suite_p_state_##TestSuiteName##_ - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. -// -// Expands to the name of the variable used to remember the names of -// the registered tests in the given test suite. -#define GTEST_REGISTERED_TEST_NAMES_(TestSuiteName) \ - gtest_registered_test_names_##TestSuiteName##_ - -// The variables defined in the type-parameterized test macros are -// static as typically these macros are used in a .h file that can be -// #included in multiple translation units linked together. -#define TYPED_TEST_SUITE_P(SuiteName) \ - static ::testing::internal::TypedTestSuitePState \ - GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName) - -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -#define TYPED_TEST_CASE_P \ - static_assert(::testing::internal::TypedTestCase_P_IsDeprecated(), ""); \ - TYPED_TEST_SUITE_P -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - -#define TYPED_TEST_P(SuiteName, TestName) \ - namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \ - template \ - class TestName : public SuiteName { \ - private: \ - typedef SuiteName TestFixture; \ - typedef gtest_TypeParam_ TypeParam; \ - void TestBody() override; \ - }; \ - static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ - GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \ - __FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \ - GTEST_STRINGIFY_(TestName)); \ - } \ - template \ - void GTEST_SUITE_NAMESPACE_( \ - SuiteName)::TestName::TestBody() - -// Note: this won't work correctly if the trailing arguments are macros. -#define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...) \ - namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \ - typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \ - } \ - static const char* const GTEST_REGISTERED_TEST_NAMES_( \ - SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \ - GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \ - GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__) - -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -#define REGISTER_TYPED_TEST_CASE_P \ - static_assert(::testing::internal::RegisterTypedTestCase_P_IsDeprecated(), \ - ""); \ - REGISTER_TYPED_TEST_SUITE_P -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - -#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \ - static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \ - "test-suit-prefix must not be empty"); \ - static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \ - ::testing::internal::TypeParameterizedTestSuite< \ - SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \ - ::testing::internal::GenerateTypeList::type>:: \ - Register(GTEST_STRINGIFY_(Prefix), \ - ::testing::internal::CodeLocation(__FILE__, __LINE__), \ - >EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \ - GTEST_STRINGIFY_(SuiteName), \ - GTEST_REGISTERED_TEST_NAMES_(SuiteName), \ - ::testing::internal::GenerateNames< \ - ::testing::internal::NameGeneratorSelector< \ - __VA_ARGS__>::type, \ - ::testing::internal::GenerateTypeList::type>()) - -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -#define INSTANTIATE_TYPED_TEST_CASE_P \ - static_assert( \ - ::testing::internal::InstantiateTypedTestCase_P_IsDeprecated(), ""); \ - INSTANTIATE_TYPED_TEST_SUITE_P -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - -#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest.h deleted file mode 100644 index d19a587a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest.h +++ /dev/null @@ -1,2297 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The Google C++ Testing and Mocking Framework (Google Test) -// -// This header file defines the public API for Google Test. It should be -// included by any test program that uses Google Test. -// -// IMPORTANT NOTE: Due to limitation of the C++ language, we have to -// leave some internal implementation details in this header file. -// They are clearly marked by comments like this: -// -// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -// -// Such code is NOT meant to be used by a user directly, and is subject -// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user -// program! -// -// Acknowledgment: Google Test borrowed the idea of automatic test -// registration from Barthelemy Dagenais' (barthelemy@prologique.com) -// easyUnit framework. - -#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_H_ -#define GOOGLETEST_INCLUDE_GTEST_GTEST_H_ - -#include -#include -#include -#include -#include -#include - -#include "gtest/gtest-assertion-result.h" -#include "gtest/gtest-death-test.h" -#include "gtest/gtest-matchers.h" -#include "gtest/gtest-message.h" -#include "gtest/gtest-param-test.h" -#include "gtest/gtest-printers.h" -#include "gtest/gtest-test-part.h" -#include "gtest/gtest-typed-test.h" -#include "gtest/gtest_pred_impl.h" -#include "gtest/gtest_prod.h" -#include "gtest/internal/gtest-internal.h" -#include "gtest/internal/gtest-string.h" - -GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ -/* class A needs to have dll-interface to be used by clients of class B */) - -// Declares the flags. - -// This flag temporary enables the disabled tests. -GTEST_DECLARE_bool_(also_run_disabled_tests); - -// This flag brings the debugger on an assertion failure. -GTEST_DECLARE_bool_(break_on_failure); - -// This flag controls whether Google Test catches all test-thrown exceptions -// and logs them as failures. -GTEST_DECLARE_bool_(catch_exceptions); - -// This flag enables using colors in terminal output. Available values are -// "yes" to enable colors, "no" (disable colors), or "auto" (the default) -// to let Google Test decide. -GTEST_DECLARE_string_(color); - -// This flag controls whether the test runner should continue execution past -// first failure. -GTEST_DECLARE_bool_(fail_fast); - -// This flag sets up the filter to select by name using a glob pattern -// the tests to run. If the filter is not given all tests are executed. -GTEST_DECLARE_string_(filter); - -// This flag controls whether Google Test installs a signal handler that dumps -// debugging information when fatal signals are raised. -GTEST_DECLARE_bool_(install_failure_signal_handler); - -// This flag causes the Google Test to list tests. None of the tests listed -// are actually run if the flag is provided. -GTEST_DECLARE_bool_(list_tests); - -// This flag controls whether Google Test emits a detailed XML report to a file -// in addition to its normal textual output. -GTEST_DECLARE_string_(output); - -// This flags control whether Google Test prints only test failures. -GTEST_DECLARE_bool_(brief); - -// This flags control whether Google Test prints the elapsed time for each -// test. -GTEST_DECLARE_bool_(print_time); - -// This flags control whether Google Test prints UTF8 characters as text. -GTEST_DECLARE_bool_(print_utf8); - -// This flag specifies the random number seed. -GTEST_DECLARE_int32_(random_seed); - -// This flag sets how many times the tests are repeated. The default value -// is 1. If the value is -1 the tests are repeating forever. -GTEST_DECLARE_int32_(repeat); - -// This flag controls whether Google Test Environments are recreated for each -// repeat of the tests. The default value is true. If set to false the global -// test Environment objects are only set up once, for the first iteration, and -// only torn down once, for the last. -GTEST_DECLARE_bool_(recreate_environments_when_repeating); - -// This flag controls whether Google Test includes Google Test internal -// stack frames in failure stack traces. -GTEST_DECLARE_bool_(show_internal_stack_frames); - -// When this flag is specified, tests' order is randomized on every iteration. -GTEST_DECLARE_bool_(shuffle); - -// This flag specifies the maximum number of stack frames to be -// printed in a failure message. -GTEST_DECLARE_int32_(stack_trace_depth); - -// When this flag is specified, a failed assertion will throw an -// exception if exceptions are enabled, or exit the program with a -// non-zero code otherwise. For use with an external test framework. -GTEST_DECLARE_bool_(throw_on_failure); - -// When this flag is set with a "host:port" string, on supported -// platforms test results are streamed to the specified port on -// the specified host machine. -GTEST_DECLARE_string_(stream_result_to); - -#if GTEST_USE_OWN_FLAGFILE_FLAG_ -GTEST_DECLARE_string_(flagfile); -#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ - -namespace testing { - -// Silence C4100 (unreferenced formal parameter) and 4805 -// unsafe mix of type 'const int' and type 'const bool' -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4805) -#pragma warning(disable : 4100) -#endif - -// The upper limit for valid stack trace depths. -const int kMaxStackTraceDepth = 100; - -namespace internal { - -class AssertHelper; -class DefaultGlobalTestPartResultReporter; -class ExecDeathTest; -class NoExecDeathTest; -class FinalSuccessChecker; -class GTestFlagSaver; -class StreamingListenerTest; -class TestResultAccessor; -class TestEventListenersAccessor; -class TestEventRepeater; -class UnitTestRecordPropertyTestHelper; -class WindowsDeathTest; -class FuchsiaDeathTest; -class UnitTestImpl* GetUnitTestImpl(); -void ReportFailureInUnknownLocation(TestPartResult::Type result_type, - const std::string& message); -std::set* GetIgnoredParameterizedTestSuites(); - -} // namespace internal - -// The friend relationship of some of these classes is cyclic. -// If we don't forward declare them the compiler might confuse the classes -// in friendship clauses with same named classes on the scope. -class Test; -class TestSuite; - -// Old API is still available but deprecated -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -using TestCase = TestSuite; -#endif -class TestInfo; -class UnitTest; - -// The abstract class that all tests inherit from. -// -// In Google Test, a unit test program contains one or many TestSuites, and -// each TestSuite contains one or many Tests. -// -// When you define a test using the TEST macro, you don't need to -// explicitly derive from Test - the TEST macro automatically does -// this for you. -// -// The only time you derive from Test is when defining a test fixture -// to be used in a TEST_F. For example: -// -// class FooTest : public testing::Test { -// protected: -// void SetUp() override { ... } -// void TearDown() override { ... } -// ... -// }; -// -// TEST_F(FooTest, Bar) { ... } -// TEST_F(FooTest, Baz) { ... } -// -// Test is not copyable. -class GTEST_API_ Test { - public: - friend class TestInfo; - - // The d'tor is virtual as we intend to inherit from Test. - virtual ~Test(); - - // Sets up the stuff shared by all tests in this test suite. - // - // Google Test will call Foo::SetUpTestSuite() before running the first - // test in test suite Foo. Hence a sub-class can define its own - // SetUpTestSuite() method to shadow the one defined in the super - // class. - static void SetUpTestSuite() {} - - // Tears down the stuff shared by all tests in this test suite. - // - // Google Test will call Foo::TearDownTestSuite() after running the last - // test in test suite Foo. Hence a sub-class can define its own - // TearDownTestSuite() method to shadow the one defined in the super - // class. - static void TearDownTestSuite() {} - - // Legacy API is deprecated but still available. Use SetUpTestSuite and - // TearDownTestSuite instead. -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - static void TearDownTestCase() {} - static void SetUpTestCase() {} -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - - // Returns true if and only if the current test has a fatal failure. - static bool HasFatalFailure(); - - // Returns true if and only if the current test has a non-fatal failure. - static bool HasNonfatalFailure(); - - // Returns true if and only if the current test was skipped. - static bool IsSkipped(); - - // Returns true if and only if the current test has a (either fatal or - // non-fatal) failure. - static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } - - // Logs a property for the current test, test suite, or for the entire - // invocation of the test program when used outside of the context of a - // test suite. Only the last value for a given key is remembered. These - // are public static so they can be called from utility functions that are - // not members of the test fixture. Calls to RecordProperty made during - // lifespan of the test (from the moment its constructor starts to the - // moment its destructor finishes) will be output in XML as attributes of - // the element. Properties recorded from fixture's - // SetUpTestSuite or TearDownTestSuite are logged as attributes of the - // corresponding element. Calls to RecordProperty made in the - // global context (before or after invocation of RUN_ALL_TESTS and from - // SetUp/TearDown method of Environment objects registered with Google - // Test) will be output as attributes of the element. - static void RecordProperty(const std::string& key, const std::string& value); - static void RecordProperty(const std::string& key, int value); - - protected: - // Creates a Test object. - Test(); - - // Sets up the test fixture. - virtual void SetUp(); - - // Tears down the test fixture. - virtual void TearDown(); - - private: - // Returns true if and only if the current test has the same fixture class - // as the first test in the current test suite. - static bool HasSameFixtureClass(); - - // Runs the test after the test fixture has been set up. - // - // A sub-class must implement this to define the test logic. - // - // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. - // Instead, use the TEST or TEST_F macro. - virtual void TestBody() = 0; - - // Sets up, executes, and tears down the test. - void Run(); - - // Deletes self. We deliberately pick an unusual name for this - // internal method to avoid clashing with names used in user TESTs. - void DeleteSelf_() { delete this; } - - const std::unique_ptr gtest_flag_saver_; - - // Often a user misspells SetUp() as Setup() and spends a long time - // wondering why it is never called by Google Test. The declaration of - // the following method is solely for catching such an error at - // compile time: - // - // - The return type is deliberately chosen to be not void, so it - // will be a conflict if void Setup() is declared in the user's - // test fixture. - // - // - This method is private, so it will be another compiler error - // if the method is called from the user's test fixture. - // - // DO NOT OVERRIDE THIS FUNCTION. - // - // If you see an error about overriding the following function or - // about it being private, you have mis-spelled SetUp() as Setup(). - struct Setup_should_be_spelled_SetUp {}; - virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; } - - // We disallow copying Tests. - Test(const Test&) = delete; - Test& operator=(const Test&) = delete; -}; - -typedef internal::TimeInMillis TimeInMillis; - -// A copyable object representing a user specified test property which can be -// output as a key/value string pair. -// -// Don't inherit from TestProperty as its destructor is not virtual. -class TestProperty { - public: - // C'tor. TestProperty does NOT have a default constructor. - // Always use this constructor (with parameters) to create a - // TestProperty object. - TestProperty(const std::string& a_key, const std::string& a_value) - : key_(a_key), value_(a_value) {} - - // Gets the user supplied key. - const char* key() const { return key_.c_str(); } - - // Gets the user supplied value. - const char* value() const { return value_.c_str(); } - - // Sets a new value, overriding the one supplied in the constructor. - void SetValue(const std::string& new_value) { value_ = new_value; } - - private: - // The key supplied by the user. - std::string key_; - // The value supplied by the user. - std::string value_; -}; - -// The result of a single Test. This includes a list of -// TestPartResults, a list of TestProperties, a count of how many -// death tests there are in the Test, and how much time it took to run -// the Test. -// -// TestResult is not copyable. -class GTEST_API_ TestResult { - public: - // Creates an empty TestResult. - TestResult(); - - // D'tor. Do not inherit from TestResult. - ~TestResult(); - - // Gets the number of all test parts. This is the sum of the number - // of successful test parts and the number of failed test parts. - int total_part_count() const; - - // Returns the number of the test properties. - int test_property_count() const; - - // Returns true if and only if the test passed (i.e. no test part failed). - bool Passed() const { return !Skipped() && !Failed(); } - - // Returns true if and only if the test was skipped. - bool Skipped() const; - - // Returns true if and only if the test failed. - bool Failed() const; - - // Returns true if and only if the test fatally failed. - bool HasFatalFailure() const; - - // Returns true if and only if the test has a non-fatal failure. - bool HasNonfatalFailure() const; - - // Returns the elapsed time, in milliseconds. - TimeInMillis elapsed_time() const { return elapsed_time_; } - - // Gets the time of the test case start, in ms from the start of the - // UNIX epoch. - TimeInMillis start_timestamp() const { return start_timestamp_; } - - // Returns the i-th test part result among all the results. i can range from 0 - // to total_part_count() - 1. If i is not in that range, aborts the program. - const TestPartResult& GetTestPartResult(int i) const; - - // Returns the i-th test property. i can range from 0 to - // test_property_count() - 1. If i is not in that range, aborts the - // program. - const TestProperty& GetTestProperty(int i) const; - - private: - friend class TestInfo; - friend class TestSuite; - friend class UnitTest; - friend class internal::DefaultGlobalTestPartResultReporter; - friend class internal::ExecDeathTest; - friend class internal::TestResultAccessor; - friend class internal::UnitTestImpl; - friend class internal::WindowsDeathTest; - friend class internal::FuchsiaDeathTest; - - // Gets the vector of TestPartResults. - const std::vector& test_part_results() const { - return test_part_results_; - } - - // Gets the vector of TestProperties. - const std::vector& test_properties() const { - return test_properties_; - } - - // Sets the start time. - void set_start_timestamp(TimeInMillis start) { start_timestamp_ = start; } - - // Sets the elapsed time. - void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } - - // Adds a test property to the list. The property is validated and may add - // a non-fatal failure if invalid (e.g., if it conflicts with reserved - // key names). If a property is already recorded for the same key, the - // value will be updated, rather than storing multiple values for the same - // key. xml_element specifies the element for which the property is being - // recorded and is used for validation. - void RecordProperty(const std::string& xml_element, - const TestProperty& test_property); - - // Adds a failure if the key is a reserved attribute of Google Test - // testsuite tags. Returns true if the property is valid. - // FIXME: Validate attribute names are legal and human readable. - static bool ValidateTestProperty(const std::string& xml_element, - const TestProperty& test_property); - - // Adds a test part result to the list. - void AddTestPartResult(const TestPartResult& test_part_result); - - // Returns the death test count. - int death_test_count() const { return death_test_count_; } - - // Increments the death test count, returning the new count. - int increment_death_test_count() { return ++death_test_count_; } - - // Clears the test part results. - void ClearTestPartResults(); - - // Clears the object. - void Clear(); - - // Protects mutable state of the property vector and of owned - // properties, whose values may be updated. - internal::Mutex test_properties_mutex_; - - // The vector of TestPartResults - std::vector test_part_results_; - // The vector of TestProperties - std::vector test_properties_; - // Running count of death tests. - int death_test_count_; - // The start time, in milliseconds since UNIX Epoch. - TimeInMillis start_timestamp_; - // The elapsed time, in milliseconds. - TimeInMillis elapsed_time_; - - // We disallow copying TestResult. - TestResult(const TestResult&) = delete; - TestResult& operator=(const TestResult&) = delete; -}; // class TestResult - -// A TestInfo object stores the following information about a test: -// -// Test suite name -// Test name -// Whether the test should be run -// A function pointer that creates the test object when invoked -// Test result -// -// The constructor of TestInfo registers itself with the UnitTest -// singleton such that the RUN_ALL_TESTS() macro knows which tests to -// run. -class GTEST_API_ TestInfo { - public: - // Destructs a TestInfo object. This function is not virtual, so - // don't inherit from TestInfo. - ~TestInfo(); - - // Returns the test suite name. - const char* test_suite_name() const { return test_suite_name_.c_str(); } - -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - const char* test_case_name() const { return test_suite_name(); } -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - - // Returns the test name. - const char* name() const { return name_.c_str(); } - - // Returns the name of the parameter type, or NULL if this is not a typed - // or a type-parameterized test. - const char* type_param() const { - if (type_param_.get() != nullptr) return type_param_->c_str(); - return nullptr; - } - - // Returns the text representation of the value parameter, or NULL if this - // is not a value-parameterized test. - const char* value_param() const { - if (value_param_.get() != nullptr) return value_param_->c_str(); - return nullptr; - } - - // Returns the file name where this test is defined. - const char* file() const { return location_.file.c_str(); } - - // Returns the line where this test is defined. - int line() const { return location_.line; } - - // Return true if this test should not be run because it's in another shard. - bool is_in_another_shard() const { return is_in_another_shard_; } - - // Returns true if this test should run, that is if the test is not - // disabled (or it is disabled but the also_run_disabled_tests flag has - // been specified) and its full name matches the user-specified filter. - // - // Google Test allows the user to filter the tests by their full names. - // The full name of a test Bar in test suite Foo is defined as - // "Foo.Bar". Only the tests that match the filter will run. - // - // A filter is a colon-separated list of glob (not regex) patterns, - // optionally followed by a '-' and a colon-separated list of - // negative patterns (tests to exclude). A test is run if it - // matches one of the positive patterns and does not match any of - // the negative patterns. - // - // For example, *A*:Foo.* is a filter that matches any string that - // contains the character 'A' or starts with "Foo.". - bool should_run() const { return should_run_; } - - // Returns true if and only if this test will appear in the XML report. - bool is_reportable() const { - // The XML report includes tests matching the filter, excluding those - // run in other shards. - return matches_filter_ && !is_in_another_shard_; - } - - // Returns the result of the test. - const TestResult* result() const { return &result_; } - - private: -#if GTEST_HAS_DEATH_TEST - friend class internal::DefaultDeathTestFactory; -#endif // GTEST_HAS_DEATH_TEST - friend class Test; - friend class TestSuite; - friend class internal::UnitTestImpl; - friend class internal::StreamingListenerTest; - friend TestInfo* internal::MakeAndRegisterTestInfo( - const char* test_suite_name, const char* name, const char* type_param, - const char* value_param, internal::CodeLocation code_location, - internal::TypeId fixture_class_id, internal::SetUpTestSuiteFunc set_up_tc, - internal::TearDownTestSuiteFunc tear_down_tc, - internal::TestFactoryBase* factory); - - // Constructs a TestInfo object. The newly constructed instance assumes - // ownership of the factory object. - TestInfo(const std::string& test_suite_name, const std::string& name, - const char* a_type_param, // NULL if not a type-parameterized test - const char* a_value_param, // NULL if not a value-parameterized test - internal::CodeLocation a_code_location, - internal::TypeId fixture_class_id, - internal::TestFactoryBase* factory); - - // Increments the number of death tests encountered in this test so - // far. - int increment_death_test_count() { - return result_.increment_death_test_count(); - } - - // Creates the test object, runs it, records its result, and then - // deletes it. - void Run(); - - // Skip and records the test result for this object. - void Skip(); - - static void ClearTestResult(TestInfo* test_info) { - test_info->result_.Clear(); - } - - // These fields are immutable properties of the test. - const std::string test_suite_name_; // test suite name - const std::string name_; // Test name - // Name of the parameter type, or NULL if this is not a typed or a - // type-parameterized test. - const std::unique_ptr type_param_; - // Text representation of the value parameter, or NULL if this is not a - // value-parameterized test. - const std::unique_ptr value_param_; - internal::CodeLocation location_; - const internal::TypeId fixture_class_id_; // ID of the test fixture class - bool should_run_; // True if and only if this test should run - bool is_disabled_; // True if and only if this test is disabled - bool matches_filter_; // True if this test matches the - // user-specified filter. - bool is_in_another_shard_; // Will be run in another shard. - internal::TestFactoryBase* const factory_; // The factory that creates - // the test object - - // This field is mutable and needs to be reset before running the - // test for the second time. - TestResult result_; - - TestInfo(const TestInfo&) = delete; - TestInfo& operator=(const TestInfo&) = delete; -}; - -// A test suite, which consists of a vector of TestInfos. -// -// TestSuite is not copyable. -class GTEST_API_ TestSuite { - public: - // Creates a TestSuite with the given name. - // - // TestSuite does NOT have a default constructor. Always use this - // constructor to create a TestSuite object. - // - // Arguments: - // - // name: name of the test suite - // a_type_param: the name of the test's type parameter, or NULL if - // this is not a type-parameterized test. - // set_up_tc: pointer to the function that sets up the test suite - // tear_down_tc: pointer to the function that tears down the test suite - TestSuite(const char* name, const char* a_type_param, - internal::SetUpTestSuiteFunc set_up_tc, - internal::TearDownTestSuiteFunc tear_down_tc); - - // Destructor of TestSuite. - virtual ~TestSuite(); - - // Gets the name of the TestSuite. - const char* name() const { return name_.c_str(); } - - // Returns the name of the parameter type, or NULL if this is not a - // type-parameterized test suite. - const char* type_param() const { - if (type_param_.get() != nullptr) return type_param_->c_str(); - return nullptr; - } - - // Returns true if any test in this test suite should run. - bool should_run() const { return should_run_; } - - // Gets the number of successful tests in this test suite. - int successful_test_count() const; - - // Gets the number of skipped tests in this test suite. - int skipped_test_count() const; - - // Gets the number of failed tests in this test suite. - int failed_test_count() const; - - // Gets the number of disabled tests that will be reported in the XML report. - int reportable_disabled_test_count() const; - - // Gets the number of disabled tests in this test suite. - int disabled_test_count() const; - - // Gets the number of tests to be printed in the XML report. - int reportable_test_count() const; - - // Get the number of tests in this test suite that should run. - int test_to_run_count() const; - - // Gets the number of all tests in this test suite. - int total_test_count() const; - - // Returns true if and only if the test suite passed. - bool Passed() const { return !Failed(); } - - // Returns true if and only if the test suite failed. - bool Failed() const { - return failed_test_count() > 0 || ad_hoc_test_result().Failed(); - } - - // Returns the elapsed time, in milliseconds. - TimeInMillis elapsed_time() const { return elapsed_time_; } - - // Gets the time of the test suite start, in ms from the start of the - // UNIX epoch. - TimeInMillis start_timestamp() const { return start_timestamp_; } - - // Returns the i-th test among all the tests. i can range from 0 to - // total_test_count() - 1. If i is not in that range, returns NULL. - const TestInfo* GetTestInfo(int i) const; - - // Returns the TestResult that holds test properties recorded during - // execution of SetUpTestSuite and TearDownTestSuite. - const TestResult& ad_hoc_test_result() const { return ad_hoc_test_result_; } - - private: - friend class Test; - friend class internal::UnitTestImpl; - - // Gets the (mutable) vector of TestInfos in this TestSuite. - std::vector& test_info_list() { return test_info_list_; } - - // Gets the (immutable) vector of TestInfos in this TestSuite. - const std::vector& test_info_list() const { - return test_info_list_; - } - - // Returns the i-th test among all the tests. i can range from 0 to - // total_test_count() - 1. If i is not in that range, returns NULL. - TestInfo* GetMutableTestInfo(int i); - - // Sets the should_run member. - void set_should_run(bool should) { should_run_ = should; } - - // Adds a TestInfo to this test suite. Will delete the TestInfo upon - // destruction of the TestSuite object. - void AddTestInfo(TestInfo* test_info); - - // Clears the results of all tests in this test suite. - void ClearResult(); - - // Clears the results of all tests in the given test suite. - static void ClearTestSuiteResult(TestSuite* test_suite) { - test_suite->ClearResult(); - } - - // Runs every test in this TestSuite. - void Run(); - - // Skips the execution of tests under this TestSuite - void Skip(); - - // Runs SetUpTestSuite() for this TestSuite. This wrapper is needed - // for catching exceptions thrown from SetUpTestSuite(). - void RunSetUpTestSuite() { - if (set_up_tc_ != nullptr) { - (*set_up_tc_)(); - } - } - - // Runs TearDownTestSuite() for this TestSuite. This wrapper is - // needed for catching exceptions thrown from TearDownTestSuite(). - void RunTearDownTestSuite() { - if (tear_down_tc_ != nullptr) { - (*tear_down_tc_)(); - } - } - - // Returns true if and only if test passed. - static bool TestPassed(const TestInfo* test_info) { - return test_info->should_run() && test_info->result()->Passed(); - } - - // Returns true if and only if test skipped. - static bool TestSkipped(const TestInfo* test_info) { - return test_info->should_run() && test_info->result()->Skipped(); - } - - // Returns true if and only if test failed. - static bool TestFailed(const TestInfo* test_info) { - return test_info->should_run() && test_info->result()->Failed(); - } - - // Returns true if and only if the test is disabled and will be reported in - // the XML report. - static bool TestReportableDisabled(const TestInfo* test_info) { - return test_info->is_reportable() && test_info->is_disabled_; - } - - // Returns true if and only if test is disabled. - static bool TestDisabled(const TestInfo* test_info) { - return test_info->is_disabled_; - } - - // Returns true if and only if this test will appear in the XML report. - static bool TestReportable(const TestInfo* test_info) { - return test_info->is_reportable(); - } - - // Returns true if the given test should run. - static bool ShouldRunTest(const TestInfo* test_info) { - return test_info->should_run(); - } - - // Shuffles the tests in this test suite. - void ShuffleTests(internal::Random* random); - - // Restores the test order to before the first shuffle. - void UnshuffleTests(); - - // Name of the test suite. - std::string name_; - // Name of the parameter type, or NULL if this is not a typed or a - // type-parameterized test. - const std::unique_ptr type_param_; - // The vector of TestInfos in their original order. It owns the - // elements in the vector. - std::vector test_info_list_; - // Provides a level of indirection for the test list to allow easy - // shuffling and restoring the test order. The i-th element in this - // vector is the index of the i-th test in the shuffled test list. - std::vector test_indices_; - // Pointer to the function that sets up the test suite. - internal::SetUpTestSuiteFunc set_up_tc_; - // Pointer to the function that tears down the test suite. - internal::TearDownTestSuiteFunc tear_down_tc_; - // True if and only if any test in this test suite should run. - bool should_run_; - // The start time, in milliseconds since UNIX Epoch. - TimeInMillis start_timestamp_; - // Elapsed time, in milliseconds. - TimeInMillis elapsed_time_; - // Holds test properties recorded during execution of SetUpTestSuite and - // TearDownTestSuite. - TestResult ad_hoc_test_result_; - - // We disallow copying TestSuites. - TestSuite(const TestSuite&) = delete; - TestSuite& operator=(const TestSuite&) = delete; -}; - -// An Environment object is capable of setting up and tearing down an -// environment. You should subclass this to define your own -// environment(s). -// -// An Environment object does the set-up and tear-down in virtual -// methods SetUp() and TearDown() instead of the constructor and the -// destructor, as: -// -// 1. You cannot safely throw from a destructor. This is a problem -// as in some cases Google Test is used where exceptions are enabled, and -// we may want to implement ASSERT_* using exceptions where they are -// available. -// 2. You cannot use ASSERT_* directly in a constructor or -// destructor. -class Environment { - public: - // The d'tor is virtual as we need to subclass Environment. - virtual ~Environment() {} - - // Override this to define how to set up the environment. - virtual void SetUp() {} - - // Override this to define how to tear down the environment. - virtual void TearDown() {} - - private: - // If you see an error about overriding the following function or - // about it being private, you have mis-spelled SetUp() as Setup(). - struct Setup_should_be_spelled_SetUp {}; - virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; } -}; - -#if GTEST_HAS_EXCEPTIONS - -// Exception which can be thrown from TestEventListener::OnTestPartResult. -class GTEST_API_ AssertionException - : public internal::GoogleTestFailureException { - public: - explicit AssertionException(const TestPartResult& result) - : GoogleTestFailureException(result) {} -}; - -#endif // GTEST_HAS_EXCEPTIONS - -// The interface for tracing execution of tests. The methods are organized in -// the order the corresponding events are fired. -class TestEventListener { - public: - virtual ~TestEventListener() {} - - // Fired before any test activity starts. - virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; - - // Fired before each iteration of tests starts. There may be more than - // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration - // index, starting from 0. - virtual void OnTestIterationStart(const UnitTest& unit_test, - int iteration) = 0; - - // Fired before environment set-up for each iteration of tests starts. - virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; - - // Fired after environment set-up for each iteration of tests ends. - virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; - - // Fired before the test suite starts. - virtual void OnTestSuiteStart(const TestSuite& /*test_suite*/) {} - - // Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - - // Fired before the test starts. - virtual void OnTestStart(const TestInfo& test_info) = 0; - - // Fired when a test is disabled - virtual void OnTestDisabled(const TestInfo& /*test_info*/) {} - - // Fired after a failed assertion or a SUCCEED() invocation. - // If you want to throw an exception from this function to skip to the next - // TEST, it must be AssertionException defined above, or inherited from it. - virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; - - // Fired after the test ends. - virtual void OnTestEnd(const TestInfo& test_info) = 0; - - // Fired after the test suite ends. - virtual void OnTestSuiteEnd(const TestSuite& /*test_suite*/) {} - -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - - // Fired before environment tear-down for each iteration of tests starts. - virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; - - // Fired after environment tear-down for each iteration of tests ends. - virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; - - // Fired after each iteration of tests finishes. - virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration) = 0; - - // Fired after all test activities have ended. - virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; -}; - -// The convenience class for users who need to override just one or two -// methods and are not concerned that a possible change to a signature of -// the methods they override will not be caught during the build. For -// comments about each method please see the definition of TestEventListener -// above. -class EmptyTestEventListener : public TestEventListener { - public: - void OnTestProgramStart(const UnitTest& /*unit_test*/) override {} - void OnTestIterationStart(const UnitTest& /*unit_test*/, - int /*iteration*/) override {} - void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) override {} - void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {} - void OnTestSuiteStart(const TestSuite& /*test_suite*/) override {} -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - void OnTestCaseStart(const TestCase& /*test_case*/) override {} -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - - void OnTestStart(const TestInfo& /*test_info*/) override {} - void OnTestDisabled(const TestInfo& /*test_info*/) override {} - void OnTestPartResult(const TestPartResult& /*test_part_result*/) override {} - void OnTestEnd(const TestInfo& /*test_info*/) override {} - void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {} -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - void OnTestCaseEnd(const TestCase& /*test_case*/) override {} -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - - void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) override {} - void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {} - void OnTestIterationEnd(const UnitTest& /*unit_test*/, - int /*iteration*/) override {} - void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {} -}; - -// TestEventListeners lets users add listeners to track events in Google Test. -class GTEST_API_ TestEventListeners { - public: - TestEventListeners(); - ~TestEventListeners(); - - // Appends an event listener to the end of the list. Google Test assumes - // the ownership of the listener (i.e. it will delete the listener when - // the test program finishes). - void Append(TestEventListener* listener); - - // Removes the given event listener from the list and returns it. It then - // becomes the caller's responsibility to delete the listener. Returns - // NULL if the listener is not found in the list. - TestEventListener* Release(TestEventListener* listener); - - // Returns the standard listener responsible for the default console - // output. Can be removed from the listeners list to shut down default - // console output. Note that removing this object from the listener list - // with Release transfers its ownership to the caller and makes this - // function return NULL the next time. - TestEventListener* default_result_printer() const { - return default_result_printer_; - } - - // Returns the standard listener responsible for the default XML output - // controlled by the --gtest_output=xml flag. Can be removed from the - // listeners list by users who want to shut down the default XML output - // controlled by this flag and substitute it with custom one. Note that - // removing this object from the listener list with Release transfers its - // ownership to the caller and makes this function return NULL the next - // time. - TestEventListener* default_xml_generator() const { - return default_xml_generator_; - } - - private: - friend class TestSuite; - friend class TestInfo; - friend class internal::DefaultGlobalTestPartResultReporter; - friend class internal::NoExecDeathTest; - friend class internal::TestEventListenersAccessor; - friend class internal::UnitTestImpl; - - // Returns repeater that broadcasts the TestEventListener events to all - // subscribers. - TestEventListener* repeater(); - - // Sets the default_result_printer attribute to the provided listener. - // The listener is also added to the listener list and previous - // default_result_printer is removed from it and deleted. The listener can - // also be NULL in which case it will not be added to the list. Does - // nothing if the previous and the current listener objects are the same. - void SetDefaultResultPrinter(TestEventListener* listener); - - // Sets the default_xml_generator attribute to the provided listener. The - // listener is also added to the listener list and previous - // default_xml_generator is removed from it and deleted. The listener can - // also be NULL in which case it will not be added to the list. Does - // nothing if the previous and the current listener objects are the same. - void SetDefaultXmlGenerator(TestEventListener* listener); - - // Controls whether events will be forwarded by the repeater to the - // listeners in the list. - bool EventForwardingEnabled() const; - void SuppressEventForwarding(); - - // The actual list of listeners. - internal::TestEventRepeater* repeater_; - // Listener responsible for the standard result output. - TestEventListener* default_result_printer_; - // Listener responsible for the creation of the XML output file. - TestEventListener* default_xml_generator_; - - // We disallow copying TestEventListeners. - TestEventListeners(const TestEventListeners&) = delete; - TestEventListeners& operator=(const TestEventListeners&) = delete; -}; - -// A UnitTest consists of a vector of TestSuites. -// -// This is a singleton class. The only instance of UnitTest is -// created when UnitTest::GetInstance() is first called. This -// instance is never deleted. -// -// UnitTest is not copyable. -// -// This class is thread-safe as long as the methods are called -// according to their specification. -class GTEST_API_ UnitTest { - public: - // Gets the singleton UnitTest object. The first time this method - // is called, a UnitTest object is constructed and returned. - // Consecutive calls will return the same object. - static UnitTest* GetInstance(); - - // Runs all tests in this UnitTest object and prints the result. - // Returns 0 if successful, or 1 otherwise. - // - // This method can only be called from the main thread. - // - // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - int Run() GTEST_MUST_USE_RESULT_; - - // Returns the working directory when the first TEST() or TEST_F() - // was executed. The UnitTest object owns the string. - const char* original_working_dir() const; - - // Returns the TestSuite object for the test that's currently running, - // or NULL if no test is running. - const TestSuite* current_test_suite() const GTEST_LOCK_EXCLUDED_(mutex_); - -// Legacy API is still available but deprecated -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - const TestCase* current_test_case() const GTEST_LOCK_EXCLUDED_(mutex_); -#endif - - // Returns the TestInfo object for the test that's currently running, - // or NULL if no test is running. - const TestInfo* current_test_info() const GTEST_LOCK_EXCLUDED_(mutex_); - - // Returns the random seed used at the start of the current test run. - int random_seed() const; - - // Returns the ParameterizedTestSuiteRegistry object used to keep track of - // value-parameterized tests and instantiate and register them. - // - // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - internal::ParameterizedTestSuiteRegistry& parameterized_test_registry() - GTEST_LOCK_EXCLUDED_(mutex_); - - // Gets the number of successful test suites. - int successful_test_suite_count() const; - - // Gets the number of failed test suites. - int failed_test_suite_count() const; - - // Gets the number of all test suites. - int total_test_suite_count() const; - - // Gets the number of all test suites that contain at least one test - // that should run. - int test_suite_to_run_count() const; - - // Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - int successful_test_case_count() const; - int failed_test_case_count() const; - int total_test_case_count() const; - int test_case_to_run_count() const; -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - - // Gets the number of successful tests. - int successful_test_count() const; - - // Gets the number of skipped tests. - int skipped_test_count() const; - - // Gets the number of failed tests. - int failed_test_count() const; - - // Gets the number of disabled tests that will be reported in the XML report. - int reportable_disabled_test_count() const; - - // Gets the number of disabled tests. - int disabled_test_count() const; - - // Gets the number of tests to be printed in the XML report. - int reportable_test_count() const; - - // Gets the number of all tests. - int total_test_count() const; - - // Gets the number of tests that should run. - int test_to_run_count() const; - - // Gets the time of the test program start, in ms from the start of the - // UNIX epoch. - TimeInMillis start_timestamp() const; - - // Gets the elapsed time, in milliseconds. - TimeInMillis elapsed_time() const; - - // Returns true if and only if the unit test passed (i.e. all test suites - // passed). - bool Passed() const; - - // Returns true if and only if the unit test failed (i.e. some test suite - // failed or something outside of all tests failed). - bool Failed() const; - - // Gets the i-th test suite among all the test suites. i can range from 0 to - // total_test_suite_count() - 1. If i is not in that range, returns NULL. - const TestSuite* GetTestSuite(int i) const; - -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - const TestCase* GetTestCase(int i) const; -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - - // Returns the TestResult containing information on test failures and - // properties logged outside of individual test suites. - const TestResult& ad_hoc_test_result() const; - - // Returns the list of event listeners that can be used to track events - // inside Google Test. - TestEventListeners& listeners(); - - private: - // Registers and returns a global test environment. When a test - // program is run, all global test environments will be set-up in - // the order they were registered. After all tests in the program - // have finished, all global test environments will be torn-down in - // the *reverse* order they were registered. - // - // The UnitTest object takes ownership of the given environment. - // - // This method can only be called from the main thread. - Environment* AddEnvironment(Environment* env); - - // Adds a TestPartResult to the current TestResult object. All - // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) - // eventually call this to report their results. The user code - // should use the assertion macros instead of calling this directly. - void AddTestPartResult(TestPartResult::Type result_type, - const char* file_name, int line_number, - const std::string& message, - const std::string& os_stack_trace) - GTEST_LOCK_EXCLUDED_(mutex_); - - // Adds a TestProperty to the current TestResult object when invoked from - // inside a test, to current TestSuite's ad_hoc_test_result_ when invoked - // from SetUpTestSuite or TearDownTestSuite, or to the global property set - // when invoked elsewhere. If the result already contains a property with - // the same key, the value will be updated. - void RecordProperty(const std::string& key, const std::string& value); - - // Gets the i-th test suite among all the test suites. i can range from 0 to - // total_test_suite_count() - 1. If i is not in that range, returns NULL. - TestSuite* GetMutableTestSuite(int i); - - // Accessors for the implementation object. - internal::UnitTestImpl* impl() { return impl_; } - const internal::UnitTestImpl* impl() const { return impl_; } - - // These classes and functions are friends as they need to access private - // members of UnitTest. - friend class ScopedTrace; - friend class Test; - friend class internal::AssertHelper; - friend class internal::StreamingListenerTest; - friend class internal::UnitTestRecordPropertyTestHelper; - friend Environment* AddGlobalTestEnvironment(Environment* env); - friend std::set* internal::GetIgnoredParameterizedTestSuites(); - friend internal::UnitTestImpl* internal::GetUnitTestImpl(); - friend void internal::ReportFailureInUnknownLocation( - TestPartResult::Type result_type, const std::string& message); - - // Creates an empty UnitTest. - UnitTest(); - - // D'tor - virtual ~UnitTest(); - - // Pushes a trace defined by SCOPED_TRACE() on to the per-thread - // Google Test trace stack. - void PushGTestTrace(const internal::TraceInfo& trace) - GTEST_LOCK_EXCLUDED_(mutex_); - - // Pops a trace from the per-thread Google Test trace stack. - void PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_); - - // Protects mutable state in *impl_. This is mutable as some const - // methods need to lock it too. - mutable internal::Mutex mutex_; - - // Opaque implementation object. This field is never changed once - // the object is constructed. We don't mark it as const here, as - // doing so will cause a warning in the constructor of UnitTest. - // Mutable state in *impl_ is protected by mutex_. - internal::UnitTestImpl* impl_; - - // We disallow copying UnitTest. - UnitTest(const UnitTest&) = delete; - UnitTest& operator=(const UnitTest&) = delete; -}; - -// A convenient wrapper for adding an environment for the test -// program. -// -// You should call this before RUN_ALL_TESTS() is called, probably in -// main(). If you use gtest_main, you need to call this before main() -// starts for it to take effect. For example, you can define a global -// variable like this: -// -// testing::Environment* const foo_env = -// testing::AddGlobalTestEnvironment(new FooEnvironment); -// -// However, we strongly recommend you to write your own main() and -// call AddGlobalTestEnvironment() there, as relying on initialization -// of global variables makes the code harder to read and may cause -// problems when you register multiple environments from different -// translation units and the environments have dependencies among them -// (remember that the compiler doesn't guarantee the order in which -// global variables from different translation units are initialized). -inline Environment* AddGlobalTestEnvironment(Environment* env) { - return UnitTest::GetInstance()->AddEnvironment(env); -} - -// Initializes Google Test. This must be called before calling -// RUN_ALL_TESTS(). In particular, it parses a command line for the -// flags that Google Test recognizes. Whenever a Google Test flag is -// seen, it is removed from argv, and *argc is decremented. -// -// No value is returned. Instead, the Google Test flag variables are -// updated. -// -// Calling the function for the second time has no user-visible effect. -GTEST_API_ void InitGoogleTest(int* argc, char** argv); - -// This overloaded version can be used in Windows programs compiled in -// UNICODE mode. -GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); - -// This overloaded version can be used on Arduino/embedded platforms where -// there is no argc/argv. -GTEST_API_ void InitGoogleTest(); - -namespace internal { - -// Separate the error generating code from the code path to reduce the stack -// frame size of CmpHelperEQ. This helps reduce the overhead of some sanitizers -// when calling EXPECT_* in a tight loop. -template -AssertionResult CmpHelperEQFailure(const char* lhs_expression, - const char* rhs_expression, const T1& lhs, - const T2& rhs) { - return EqFailure(lhs_expression, rhs_expression, - FormatForComparisonFailureMessage(lhs, rhs), - FormatForComparisonFailureMessage(rhs, lhs), false); -} - -// This block of code defines operator==/!= -// to block lexical scope lookup. -// It prevents using invalid operator==/!= defined at namespace scope. -struct faketype {}; -inline bool operator==(faketype, faketype) { return true; } -inline bool operator!=(faketype, faketype) { return false; } - -// The helper function for {ASSERT|EXPECT}_EQ. -template -AssertionResult CmpHelperEQ(const char* lhs_expression, - const char* rhs_expression, const T1& lhs, - const T2& rhs) { - if (lhs == rhs) { - return AssertionSuccess(); - } - - return CmpHelperEQFailure(lhs_expression, rhs_expression, lhs, rhs); -} - -class EqHelper { - public: - // This templatized version is for the general case. - template < - typename T1, typename T2, - // Disable this overload for cases where one argument is a pointer - // and the other is the null pointer constant. - typename std::enable_if::value || - !std::is_pointer::value>::type* = nullptr> - static AssertionResult Compare(const char* lhs_expression, - const char* rhs_expression, const T1& lhs, - const T2& rhs) { - return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs); - } - - // With this overloaded version, we allow anonymous enums to be used - // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous - // enums can be implicitly cast to BiggestInt. - // - // Even though its body looks the same as the above version, we - // cannot merge the two, as it will make anonymous enums unhappy. - static AssertionResult Compare(const char* lhs_expression, - const char* rhs_expression, BiggestInt lhs, - BiggestInt rhs) { - return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs); - } - - template - static AssertionResult Compare( - const char* lhs_expression, const char* rhs_expression, - // Handle cases where '0' is used as a null pointer literal. - std::nullptr_t /* lhs */, T* rhs) { - // We already know that 'lhs' is a null pointer. - return CmpHelperEQ(lhs_expression, rhs_expression, static_cast(nullptr), - rhs); - } -}; - -// Separate the error generating code from the code path to reduce the stack -// frame size of CmpHelperOP. This helps reduce the overhead of some sanitizers -// when calling EXPECT_OP in a tight loop. -template -AssertionResult CmpHelperOpFailure(const char* expr1, const char* expr2, - const T1& val1, const T2& val2, - const char* op) { - return AssertionFailure() - << "Expected: (" << expr1 << ") " << op << " (" << expr2 - << "), actual: " << FormatForComparisonFailureMessage(val1, val2) - << " vs " << FormatForComparisonFailureMessage(val2, val1); -} - -// A macro for implementing the helper functions needed to implement -// ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste -// of similar code. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - -#define GTEST_IMPL_CMP_HELPER_(op_name, op) \ - template \ - AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ - const T1& val1, const T2& val2) { \ - if (val1 op val2) { \ - return AssertionSuccess(); \ - } else { \ - return CmpHelperOpFailure(expr1, expr2, val1, val2, #op); \ - } \ - } - -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - -// Implements the helper function for {ASSERT|EXPECT}_NE -GTEST_IMPL_CMP_HELPER_(NE, !=) -// Implements the helper function for {ASSERT|EXPECT}_LE -GTEST_IMPL_CMP_HELPER_(LE, <=) -// Implements the helper function for {ASSERT|EXPECT}_LT -GTEST_IMPL_CMP_HELPER_(LT, <) -// Implements the helper function for {ASSERT|EXPECT}_GE -GTEST_IMPL_CMP_HELPER_(GE, >=) -// Implements the helper function for {ASSERT|EXPECT}_GT -GTEST_IMPL_CMP_HELPER_(GT, >) - -#undef GTEST_IMPL_CMP_HELPER_ - -// The helper function for {ASSERT|EXPECT}_STREQ. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -GTEST_API_ AssertionResult CmpHelperSTREQ(const char* s1_expression, - const char* s2_expression, - const char* s1, const char* s2); - -// The helper function for {ASSERT|EXPECT}_STRCASEEQ. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* s1_expression, - const char* s2_expression, - const char* s1, const char* s2); - -// The helper function for {ASSERT|EXPECT}_STRNE. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const char* s1, const char* s2); - -// The helper function for {ASSERT|EXPECT}_STRCASENE. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, - const char* s2_expression, - const char* s1, const char* s2); - -// Helper function for *_STREQ on wide strings. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -GTEST_API_ AssertionResult CmpHelperSTREQ(const char* s1_expression, - const char* s2_expression, - const wchar_t* s1, const wchar_t* s2); - -// Helper function for *_STRNE on wide strings. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const wchar_t* s1, const wchar_t* s2); - -} // namespace internal - -// IsSubstring() and IsNotSubstring() are intended to be used as the -// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by -// themselves. They check whether needle is a substring of haystack -// (NULL is considered a substring of itself only), and return an -// appropriate error message when they fail. -// -// The {needle,haystack}_expr arguments are the stringified -// expressions that generated the two real arguments. -GTEST_API_ AssertionResult IsSubstring(const char* needle_expr, - const char* haystack_expr, - const char* needle, - const char* haystack); -GTEST_API_ AssertionResult IsSubstring(const char* needle_expr, - const char* haystack_expr, - const wchar_t* needle, - const wchar_t* haystack); -GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr, - const char* haystack_expr, - const char* needle, - const char* haystack); -GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr, - const char* haystack_expr, - const wchar_t* needle, - const wchar_t* haystack); -GTEST_API_ AssertionResult IsSubstring(const char* needle_expr, - const char* haystack_expr, - const ::std::string& needle, - const ::std::string& haystack); -GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr, - const char* haystack_expr, - const ::std::string& needle, - const ::std::string& haystack); - -#if GTEST_HAS_STD_WSTRING -GTEST_API_ AssertionResult IsSubstring(const char* needle_expr, - const char* haystack_expr, - const ::std::wstring& needle, - const ::std::wstring& haystack); -GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr, - const char* haystack_expr, - const ::std::wstring& needle, - const ::std::wstring& haystack); -#endif // GTEST_HAS_STD_WSTRING - -namespace internal { - -// Helper template function for comparing floating-points. -// -// Template parameter: -// -// RawType: the raw floating-point type (either float or double) -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -template -AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression, - const char* rhs_expression, - RawType lhs_value, RawType rhs_value) { - const FloatingPoint lhs(lhs_value), rhs(rhs_value); - - if (lhs.AlmostEquals(rhs)) { - return AssertionSuccess(); - } - - ::std::stringstream lhs_ss; - lhs_ss << std::setprecision(std::numeric_limits::digits10 + 2) - << lhs_value; - - ::std::stringstream rhs_ss; - rhs_ss << std::setprecision(std::numeric_limits::digits10 + 2) - << rhs_value; - - return EqFailure(lhs_expression, rhs_expression, - StringStreamToString(&lhs_ss), StringStreamToString(&rhs_ss), - false); -} - -// Helper function for implementing ASSERT_NEAR. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, - const char* expr2, - const char* abs_error_expr, - double val1, double val2, - double abs_error); - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// A class that enables one to stream messages to assertion macros -class GTEST_API_ AssertHelper { - public: - // Constructor. - AssertHelper(TestPartResult::Type type, const char* file, int line, - const char* message); - ~AssertHelper(); - - // Message assignment is a semantic trick to enable assertion - // streaming; see the GTEST_MESSAGE_ macro below. - void operator=(const Message& message) const; - - private: - // We put our data in a struct so that the size of the AssertHelper class can - // be as small as possible. This is important because gcc is incapable of - // re-using stack space even for temporary variables, so every EXPECT_EQ - // reserves stack space for another AssertHelper. - struct AssertHelperData { - AssertHelperData(TestPartResult::Type t, const char* srcfile, int line_num, - const char* msg) - : type(t), file(srcfile), line(line_num), message(msg) {} - - TestPartResult::Type const type; - const char* const file; - int const line; - std::string const message; - - private: - AssertHelperData(const AssertHelperData&) = delete; - AssertHelperData& operator=(const AssertHelperData&) = delete; - }; - - AssertHelperData* const data_; - - AssertHelper(const AssertHelper&) = delete; - AssertHelper& operator=(const AssertHelper&) = delete; -}; - -} // namespace internal - -// The pure interface class that all value-parameterized tests inherit from. -// A value-parameterized class must inherit from both ::testing::Test and -// ::testing::WithParamInterface. In most cases that just means inheriting -// from ::testing::TestWithParam, but more complicated test hierarchies -// may need to inherit from Test and WithParamInterface at different levels. -// -// This interface has support for accessing the test parameter value via -// the GetParam() method. -// -// Use it with one of the parameter generator defining functions, like Range(), -// Values(), ValuesIn(), Bool(), and Combine(). -// -// class FooTest : public ::testing::TestWithParam { -// protected: -// FooTest() { -// // Can use GetParam() here. -// } -// ~FooTest() override { -// // Can use GetParam() here. -// } -// void SetUp() override { -// // Can use GetParam() here. -// } -// void TearDown override { -// // Can use GetParam() here. -// } -// }; -// TEST_P(FooTest, DoesBar) { -// // Can use GetParam() method here. -// Foo foo; -// ASSERT_TRUE(foo.DoesBar(GetParam())); -// } -// INSTANTIATE_TEST_SUITE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); - -template -class WithParamInterface { - public: - typedef T ParamType; - virtual ~WithParamInterface() {} - - // The current parameter value. Is also available in the test fixture's - // constructor. - static const ParamType& GetParam() { - GTEST_CHECK_(parameter_ != nullptr) - << "GetParam() can only be called inside a value-parameterized test " - << "-- did you intend to write TEST_P instead of TEST_F?"; - return *parameter_; - } - - private: - // Sets parameter value. The caller is responsible for making sure the value - // remains alive and unchanged throughout the current test. - static void SetParam(const ParamType* parameter) { parameter_ = parameter; } - - // Static value used for accessing parameter during a test lifetime. - static const ParamType* parameter_; - - // TestClass must be a subclass of WithParamInterface and Test. - template - friend class internal::ParameterizedTestFactory; -}; - -template -const T* WithParamInterface::parameter_ = nullptr; - -// Most value-parameterized classes can ignore the existence of -// WithParamInterface, and can just inherit from ::testing::TestWithParam. - -template -class TestWithParam : public Test, public WithParamInterface {}; - -// Macros for indicating success/failure in test code. - -// Skips test in runtime. -// Skipping test aborts current function. -// Skipped tests are neither successful nor failed. -#define GTEST_SKIP() GTEST_SKIP_("") - -// ADD_FAILURE unconditionally adds a failure to the current test. -// SUCCEED generates a success - it doesn't automatically make the -// current test successful, as a test is only successful when it has -// no failure. -// -// EXPECT_* verifies that a certain condition is satisfied. If not, -// it behaves like ADD_FAILURE. In particular: -// -// EXPECT_TRUE verifies that a Boolean condition is true. -// EXPECT_FALSE verifies that a Boolean condition is false. -// -// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except -// that they will also abort the current function on failure. People -// usually want the fail-fast behavior of FAIL and ASSERT_*, but those -// writing data-driven tests often find themselves using ADD_FAILURE -// and EXPECT_* more. - -// Generates a nonfatal failure with a generic message. -#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") - -// Generates a nonfatal failure at the given source file location with -// a generic message. -#define ADD_FAILURE_AT(file, line) \ - GTEST_MESSAGE_AT_(file, line, "Failed", \ - ::testing::TestPartResult::kNonFatalFailure) - -// Generates a fatal failure with a generic message. -#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") - -// Like GTEST_FAIL(), but at the given source file location. -#define GTEST_FAIL_AT(file, line) \ - GTEST_MESSAGE_AT_(file, line, "Failed", \ - ::testing::TestPartResult::kFatalFailure) - -// Define this macro to 1 to omit the definition of FAIL(), which is a -// generic name and clashes with some other libraries. -#if !GTEST_DONT_DEFINE_FAIL -#define FAIL() GTEST_FAIL() -#endif - -// Generates a success with a generic message. -#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded") - -// Define this macro to 1 to omit the definition of SUCCEED(), which -// is a generic name and clashes with some other libraries. -#if !GTEST_DONT_DEFINE_SUCCEED -#define SUCCEED() GTEST_SUCCEED() -#endif - -// Macros for testing exceptions. -// -// * {ASSERT|EXPECT}_THROW(statement, expected_exception): -// Tests that the statement throws the expected exception. -// * {ASSERT|EXPECT}_NO_THROW(statement): -// Tests that the statement doesn't throw any exception. -// * {ASSERT|EXPECT}_ANY_THROW(statement): -// Tests that the statement throws an exception. - -#define EXPECT_THROW(statement, expected_exception) \ - GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) -#define EXPECT_NO_THROW(statement) \ - GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) -#define EXPECT_ANY_THROW(statement) \ - GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) -#define ASSERT_THROW(statement, expected_exception) \ - GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) -#define ASSERT_NO_THROW(statement) \ - GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) -#define ASSERT_ANY_THROW(statement) \ - GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) - -// Boolean assertions. Condition can be either a Boolean expression or an -// AssertionResult. For more information on how to use AssertionResult with -// these macros see comments on that class. -#define GTEST_EXPECT_TRUE(condition) \ - GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ - GTEST_NONFATAL_FAILURE_) -#define GTEST_EXPECT_FALSE(condition) \ - GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ - GTEST_NONFATAL_FAILURE_) -#define GTEST_ASSERT_TRUE(condition) \ - GTEST_TEST_BOOLEAN_(condition, #condition, false, true, GTEST_FATAL_FAILURE_) -#define GTEST_ASSERT_FALSE(condition) \ - GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ - GTEST_FATAL_FAILURE_) - -// Define these macros to 1 to omit the definition of the corresponding -// EXPECT or ASSERT, which clashes with some users' own code. - -#if !GTEST_DONT_DEFINE_EXPECT_TRUE -#define EXPECT_TRUE(condition) GTEST_EXPECT_TRUE(condition) -#endif - -#if !GTEST_DONT_DEFINE_EXPECT_FALSE -#define EXPECT_FALSE(condition) GTEST_EXPECT_FALSE(condition) -#endif - -#if !GTEST_DONT_DEFINE_ASSERT_TRUE -#define ASSERT_TRUE(condition) GTEST_ASSERT_TRUE(condition) -#endif - -#if !GTEST_DONT_DEFINE_ASSERT_FALSE -#define ASSERT_FALSE(condition) GTEST_ASSERT_FALSE(condition) -#endif - -// Macros for testing equalities and inequalities. -// -// * {ASSERT|EXPECT}_EQ(v1, v2): Tests that v1 == v2 -// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 -// * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2 -// * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2 -// * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2 -// * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2 -// -// When they are not, Google Test prints both the tested expressions and -// their actual values. The values must be compatible built-in types, -// or you will get a compiler error. By "compatible" we mean that the -// values can be compared by the respective operator. -// -// Note: -// -// 1. It is possible to make a user-defined type work with -// {ASSERT|EXPECT}_??(), but that requires overloading the -// comparison operators and is thus discouraged by the Google C++ -// Usage Guide. Therefore, you are advised to use the -// {ASSERT|EXPECT}_TRUE() macro to assert that two objects are -// equal. -// -// 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on -// pointers (in particular, C strings). Therefore, if you use it -// with two C strings, you are testing how their locations in memory -// are related, not how their content is related. To compare two C -// strings by content, use {ASSERT|EXPECT}_STR*(). -// -// 3. {ASSERT|EXPECT}_EQ(v1, v2) is preferred to -// {ASSERT|EXPECT}_TRUE(v1 == v2), as the former tells you -// what the actual value is when it fails, and similarly for the -// other comparisons. -// -// 4. Do not depend on the order in which {ASSERT|EXPECT}_??() -// evaluate their arguments, which is undefined. -// -// 5. These macros evaluate their arguments exactly once. -// -// Examples: -// -// EXPECT_NE(Foo(), 5); -// EXPECT_EQ(a_pointer, NULL); -// ASSERT_LT(i, array_size); -// ASSERT_GT(records.size(), 0) << "There is no record left."; - -#define EXPECT_EQ(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2) -#define EXPECT_NE(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) -#define EXPECT_LE(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) -#define EXPECT_LT(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) -#define EXPECT_GE(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) -#define EXPECT_GT(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) - -#define GTEST_ASSERT_EQ(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2) -#define GTEST_ASSERT_NE(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) -#define GTEST_ASSERT_LE(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) -#define GTEST_ASSERT_LT(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) -#define GTEST_ASSERT_GE(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) -#define GTEST_ASSERT_GT(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) - -// Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of -// ASSERT_XY(), which clashes with some users' own code. - -#if !GTEST_DONT_DEFINE_ASSERT_EQ -#define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) -#endif - -#if !GTEST_DONT_DEFINE_ASSERT_NE -#define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) -#endif - -#if !GTEST_DONT_DEFINE_ASSERT_LE -#define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) -#endif - -#if !GTEST_DONT_DEFINE_ASSERT_LT -#define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) -#endif - -#if !GTEST_DONT_DEFINE_ASSERT_GE -#define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) -#endif - -#if !GTEST_DONT_DEFINE_ASSERT_GT -#define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) -#endif - -// C-string Comparisons. All tests treat NULL and any non-NULL string -// as different. Two NULLs are equal. -// -// * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 -// * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2 -// * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case -// * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case -// -// For wide or narrow string objects, you can use the -// {ASSERT|EXPECT}_??() macros. -// -// Don't depend on the order in which the arguments are evaluated, -// which is undefined. -// -// These macros evaluate their arguments exactly once. - -#define EXPECT_STREQ(s1, s2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, s1, s2) -#define EXPECT_STRNE(s1, s2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) -#define EXPECT_STRCASEEQ(s1, s2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, s1, s2) -#define EXPECT_STRCASENE(s1, s2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) - -#define ASSERT_STREQ(s1, s2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, s1, s2) -#define ASSERT_STRNE(s1, s2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) -#define ASSERT_STRCASEEQ(s1, s2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, s1, s2) -#define ASSERT_STRCASENE(s1, s2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) - -// Macros for comparing floating-point numbers. -// -// * {ASSERT|EXPECT}_FLOAT_EQ(val1, val2): -// Tests that two float values are almost equal. -// * {ASSERT|EXPECT}_DOUBLE_EQ(val1, val2): -// Tests that two double values are almost equal. -// * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): -// Tests that v1 and v2 are within the given distance to each other. -// -// Google Test uses ULP-based comparison to automatically pick a default -// error bound that is appropriate for the operands. See the -// FloatingPoint template class in gtest-internal.h if you are -// interested in the implementation details. - -#define EXPECT_FLOAT_EQ(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ - val1, val2) - -#define EXPECT_DOUBLE_EQ(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ - val1, val2) - -#define ASSERT_FLOAT_EQ(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ - val1, val2) - -#define ASSERT_DOUBLE_EQ(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ - val1, val2) - -#define EXPECT_NEAR(val1, val2, abs_error) \ - EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, val1, val2, \ - abs_error) - -#define ASSERT_NEAR(val1, val2, abs_error) \ - ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, val1, val2, \ - abs_error) - -// These predicate format functions work on floating-point values, and -// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. -// -// EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); - -// Asserts that val1 is less than, or almost equal to, val2. Fails -// otherwise. In particular, it fails if either val1 or val2 is NaN. -GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, - float val1, float val2); -GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, - double val1, double val2); - -#if GTEST_OS_WINDOWS - -// Macros that test for HRESULT failure and success, these are only useful -// on Windows, and rely on Windows SDK macros and APIs to compile. -// -// * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr) -// -// When expr unexpectedly fails or succeeds, Google Test prints the -// expected result and the actual result with both a human-readable -// string representation of the error, if available, as well as the -// hex result code. -#define EXPECT_HRESULT_SUCCEEDED(expr) \ - EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) - -#define ASSERT_HRESULT_SUCCEEDED(expr) \ - ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) - -#define EXPECT_HRESULT_FAILED(expr) \ - EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) - -#define ASSERT_HRESULT_FAILED(expr) \ - ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) - -#endif // GTEST_OS_WINDOWS - -// Macros that execute statement and check that it doesn't generate new fatal -// failures in the current thread. -// -// * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement); -// -// Examples: -// -// EXPECT_NO_FATAL_FAILURE(Process()); -// ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; -// -#define ASSERT_NO_FATAL_FAILURE(statement) \ - GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) -#define EXPECT_NO_FATAL_FAILURE(statement) \ - GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) - -// Causes a trace (including the given source file path and line number, -// and the given message) to be included in every test failure message generated -// by code in the scope of the lifetime of an instance of this class. The effect -// is undone with the destruction of the instance. -// -// The message argument can be anything streamable to std::ostream. -// -// Example: -// testing::ScopedTrace trace("file.cc", 123, "message"); -// -class GTEST_API_ ScopedTrace { - public: - // The c'tor pushes the given source file location and message onto - // a trace stack maintained by Google Test. - - // Template version. Uses Message() to convert the values into strings. - // Slow, but flexible. - template - ScopedTrace(const char* file, int line, const T& message) { - PushTrace(file, line, (Message() << message).GetString()); - } - - // Optimize for some known types. - ScopedTrace(const char* file, int line, const char* message) { - PushTrace(file, line, message ? message : "(null)"); - } - - ScopedTrace(const char* file, int line, const std::string& message) { - PushTrace(file, line, message); - } - - // The d'tor pops the info pushed by the c'tor. - // - // Note that the d'tor is not virtual in order to be efficient. - // Don't inherit from ScopedTrace! - ~ScopedTrace(); - - private: - void PushTrace(const char* file, int line, std::string message); - - ScopedTrace(const ScopedTrace&) = delete; - ScopedTrace& operator=(const ScopedTrace&) = delete; -} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its - // c'tor and d'tor. Therefore it doesn't - // need to be used otherwise. - -// Causes a trace (including the source file path, the current line -// number, and the given message) to be included in every test failure -// message generated by code in the current scope. The effect is -// undone when the control leaves the current scope. -// -// The message argument can be anything streamable to std::ostream. -// -// In the implementation, we include the current line number as part -// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s -// to appear in the same block - as long as they are on different -// lines. -// -// Assuming that each thread maintains its own stack of traces. -// Therefore, a SCOPED_TRACE() would (correctly) only affect the -// assertions in its own thread. -#define SCOPED_TRACE(message) \ - ::testing::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)( \ - __FILE__, __LINE__, (message)) - -// Compile-time assertion for type equality. -// StaticAssertTypeEq() compiles if and only if type1 and type2 -// are the same type. The value it returns is not interesting. -// -// Instead of making StaticAssertTypeEq a class template, we make it a -// function template that invokes a helper class template. This -// prevents a user from misusing StaticAssertTypeEq by -// defining objects of that type. -// -// CAVEAT: -// -// When used inside a method of a class template, -// StaticAssertTypeEq() is effective ONLY IF the method is -// instantiated. For example, given: -// -// template class Foo { -// public: -// void Bar() { testing::StaticAssertTypeEq(); } -// }; -// -// the code: -// -// void Test1() { Foo foo; } -// -// will NOT generate a compiler error, as Foo::Bar() is never -// actually instantiated. Instead, you need: -// -// void Test2() { Foo foo; foo.Bar(); } -// -// to cause a compiler error. -template -constexpr bool StaticAssertTypeEq() noexcept { - static_assert(std::is_same::value, "T1 and T2 are not the same type"); - return true; -} - -// Defines a test. -// -// The first parameter is the name of the test suite, and the second -// parameter is the name of the test within the test suite. -// -// The convention is to end the test suite name with "Test". For -// example, a test suite for the Foo class can be named FooTest. -// -// Test code should appear between braces after an invocation of -// this macro. Example: -// -// TEST(FooTest, InitializesCorrectly) { -// Foo foo; -// EXPECT_TRUE(foo.StatusIsOK()); -// } - -// Note that we call GetTestTypeId() instead of GetTypeId< -// ::testing::Test>() here to get the type ID of testing::Test. This -// is to work around a suspected linker bug when using Google Test as -// a framework on Mac OS X. The bug causes GetTypeId< -// ::testing::Test>() to return different values depending on whether -// the call is from the Google Test framework itself or from user test -// code. GetTestTypeId() is guaranteed to always return the same -// value, as it always calls GetTypeId<>() from the Google Test -// framework. -#define GTEST_TEST(test_suite_name, test_name) \ - GTEST_TEST_(test_suite_name, test_name, ::testing::Test, \ - ::testing::internal::GetTestTypeId()) - -// Define this macro to 1 to omit the definition of TEST(), which -// is a generic name and clashes with some other libraries. -#if !GTEST_DONT_DEFINE_TEST -#define TEST(test_suite_name, test_name) GTEST_TEST(test_suite_name, test_name) -#endif - -// Defines a test that uses a test fixture. -// -// The first parameter is the name of the test fixture class, which -// also doubles as the test suite name. The second parameter is the -// name of the test within the test suite. -// -// A test fixture class must be declared earlier. The user should put -// the test code between braces after using this macro. Example: -// -// class FooTest : public testing::Test { -// protected: -// void SetUp() override { b_.AddElement(3); } -// -// Foo a_; -// Foo b_; -// }; -// -// TEST_F(FooTest, InitializesCorrectly) { -// EXPECT_TRUE(a_.StatusIsOK()); -// } -// -// TEST_F(FooTest, ReturnsElementCountCorrectly) { -// EXPECT_EQ(a_.size(), 0); -// EXPECT_EQ(b_.size(), 1); -// } -#define GTEST_TEST_F(test_fixture, test_name) \ - GTEST_TEST_(test_fixture, test_name, test_fixture, \ - ::testing::internal::GetTypeId()) -#if !GTEST_DONT_DEFINE_TEST_F -#define TEST_F(test_fixture, test_name) GTEST_TEST_F(test_fixture, test_name) -#endif - -// Returns a path to temporary directory. -// Tries to determine an appropriate directory for the platform. -GTEST_API_ std::string TempDir(); - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -// Dynamically registers a test with the framework. -// -// This is an advanced API only to be used when the `TEST` macros are -// insufficient. The macros should be preferred when possible, as they avoid -// most of the complexity of calling this function. -// -// The `factory` argument is a factory callable (move-constructible) object or -// function pointer that creates a new instance of the Test object. It -// handles ownership to the caller. The signature of the callable is -// `Fixture*()`, where `Fixture` is the test fixture class for the test. All -// tests registered with the same `test_suite_name` must return the same -// fixture type. This is checked at runtime. -// -// The framework will infer the fixture class from the factory and will call -// the `SetUpTestSuite` and `TearDownTestSuite` for it. -// -// Must be called before `RUN_ALL_TESTS()` is invoked, otherwise behavior is -// undefined. -// -// Use case example: -// -// class MyFixture : public ::testing::Test { -// public: -// // All of these optional, just like in regular macro usage. -// static void SetUpTestSuite() { ... } -// static void TearDownTestSuite() { ... } -// void SetUp() override { ... } -// void TearDown() override { ... } -// }; -// -// class MyTest : public MyFixture { -// public: -// explicit MyTest(int data) : data_(data) {} -// void TestBody() override { ... } -// -// private: -// int data_; -// }; -// -// void RegisterMyTests(const std::vector& values) { -// for (int v : values) { -// ::testing::RegisterTest( -// "MyFixture", ("Test" + std::to_string(v)).c_str(), nullptr, -// std::to_string(v).c_str(), -// __FILE__, __LINE__, -// // Important to use the fixture type as the return type here. -// [=]() -> MyFixture* { return new MyTest(v); }); -// } -// } -// ... -// int main(int argc, char** argv) { -// ::testing::InitGoogleTest(&argc, argv); -// std::vector values_to_test = LoadValuesFromConfig(); -// RegisterMyTests(values_to_test); -// ... -// return RUN_ALL_TESTS(); -// } -// -template -TestInfo* RegisterTest(const char* test_suite_name, const char* test_name, - const char* type_param, const char* value_param, - const char* file, int line, Factory factory) { - using TestT = typename std::remove_pointer::type; - - class FactoryImpl : public internal::TestFactoryBase { - public: - explicit FactoryImpl(Factory f) : factory_(std::move(f)) {} - Test* CreateTest() override { return factory_(); } - - private: - Factory factory_; - }; - - return internal::MakeAndRegisterTestInfo( - test_suite_name, test_name, type_param, value_param, - internal::CodeLocation(file, line), internal::GetTypeId(), - internal::SuiteApiResolver::GetSetUpCaseOrSuite(file, line), - internal::SuiteApiResolver::GetTearDownCaseOrSuite(file, line), - new FactoryImpl{std::move(factory)}); -} - -} // namespace testing - -// Use this function in main() to run all tests. It returns 0 if all -// tests are successful, or 1 otherwise. -// -// RUN_ALL_TESTS() should be invoked after the command line has been -// parsed by InitGoogleTest(). -// -// This function was formerly a macro; thus, it is in the global -// namespace and has an all-caps name. -int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_; - -inline int RUN_ALL_TESTS() { return ::testing::UnitTest::GetInstance()->Run(); } - -GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 - -#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest_pred_impl.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest_pred_impl.h deleted file mode 100644 index 47a24aa6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest_pred_impl.h +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Implements a family of generic predicate assertion macros. - -// IWYU pragma: private, include "gtest/gtest.h" -// IWYU pragma: friend gtest/.* -// IWYU pragma: friend gmock/.* - -#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ -#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ - -#include "gtest/gtest-assertion-result.h" -#include "gtest/internal/gtest-internal.h" -#include "gtest/internal/gtest-port.h" - -namespace testing { - -// This header implements a family of generic predicate assertion -// macros: -// -// ASSERT_PRED_FORMAT1(pred_format, v1) -// ASSERT_PRED_FORMAT2(pred_format, v1, v2) -// ... -// -// where pred_format is a function or functor that takes n (in the -// case of ASSERT_PRED_FORMATn) values and their source expression -// text, and returns a testing::AssertionResult. See the definition -// of ASSERT_EQ in gtest.h for an example. -// -// If you don't care about formatting, you can use the more -// restrictive version: -// -// ASSERT_PRED1(pred, v1) -// ASSERT_PRED2(pred, v1, v2) -// ... -// -// where pred is an n-ary function or functor that returns bool, -// and the values v1, v2, ..., must support the << operator for -// streaming to std::ostream. -// -// We also define the EXPECT_* variations. -// -// For now we only support predicates whose arity is at most 5. -// Please email googletestframework@googlegroups.com if you need -// support for higher arities. - -// GTEST_ASSERT_ is the basic statement to which all of the assertions -// in this file reduce. Don't use this in your code. - -#define GTEST_ASSERT_(expression, on_failure) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (const ::testing::AssertionResult gtest_ar = (expression)) \ - ; \ - else \ - on_failure(gtest_ar.failure_message()) - -// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use -// this in your code. -template -AssertionResult AssertPred1Helper(const char* pred_text, const char* e1, - Pred pred, const T1& v1) { - if (pred(v1)) return AssertionSuccess(); - - return AssertionFailure() - << pred_text << "(" << e1 << ") evaluates to false, where" - << "\n" - << e1 << " evaluates to " << ::testing::PrintToString(v1); -} - -// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. -// Don't use this in your code. -#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure) \ - GTEST_ASSERT_(pred_format(#v1, v1), on_failure) - -// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use -// this in your code. -#define GTEST_PRED1_(pred, v1, on_failure) \ - GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, #v1, pred, v1), on_failure) - -// Unary predicate assertion macros. -#define EXPECT_PRED_FORMAT1(pred_format, v1) \ - GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) -#define EXPECT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) -#define ASSERT_PRED_FORMAT1(pred_format, v1) \ - GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) -#define ASSERT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) - -// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use -// this in your code. -template -AssertionResult AssertPred2Helper(const char* pred_text, const char* e1, - const char* e2, Pred pred, const T1& v1, - const T2& v2) { - if (pred(v1, v2)) return AssertionSuccess(); - - return AssertionFailure() - << pred_text << "(" << e1 << ", " << e2 - << ") evaluates to false, where" - << "\n" - << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n" - << e2 << " evaluates to " << ::testing::PrintToString(v2); -} - -// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. -// Don't use this in your code. -#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure) \ - GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure) - -// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use -// this in your code. -#define GTEST_PRED2_(pred, v1, v2, on_failure) \ - GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, #v1, #v2, pred, v1, v2), \ - on_failure) - -// Binary predicate assertion macros. -#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ - GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) -#define EXPECT_PRED2(pred, v1, v2) \ - GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) -#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ - GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) -#define ASSERT_PRED2(pred, v1, v2) \ - GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) - -// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use -// this in your code. -template -AssertionResult AssertPred3Helper(const char* pred_text, const char* e1, - const char* e2, const char* e3, Pred pred, - const T1& v1, const T2& v2, const T3& v3) { - if (pred(v1, v2, v3)) return AssertionSuccess(); - - return AssertionFailure() - << pred_text << "(" << e1 << ", " << e2 << ", " << e3 - << ") evaluates to false, where" - << "\n" - << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n" - << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n" - << e3 << " evaluates to " << ::testing::PrintToString(v3); -} - -// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. -// Don't use this in your code. -#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure) \ - GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), on_failure) - -// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use -// this in your code. -#define GTEST_PRED3_(pred, v1, v2, v3, on_failure) \ - GTEST_ASSERT_( \ - ::testing::AssertPred3Helper(#pred, #v1, #v2, #v3, pred, v1, v2, v3), \ - on_failure) - -// Ternary predicate assertion macros. -#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ - GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) -#define EXPECT_PRED3(pred, v1, v2, v3) \ - GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) -#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ - GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) -#define ASSERT_PRED3(pred, v1, v2, v3) \ - GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) - -// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use -// this in your code. -template -AssertionResult AssertPred4Helper(const char* pred_text, const char* e1, - const char* e2, const char* e3, - const char* e4, Pred pred, const T1& v1, - const T2& v2, const T3& v3, const T4& v4) { - if (pred(v1, v2, v3, v4)) return AssertionSuccess(); - - return AssertionFailure() - << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4 - << ") evaluates to false, where" - << "\n" - << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n" - << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n" - << e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n" - << e4 << " evaluates to " << ::testing::PrintToString(v4); -} - -// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. -// Don't use this in your code. -#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure) \ - GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), on_failure) - -// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use -// this in your code. -#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure) \ - GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, #v1, #v2, #v3, #v4, pred, \ - v1, v2, v3, v4), \ - on_failure) - -// 4-ary predicate assertion macros. -#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ - GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) -#define EXPECT_PRED4(pred, v1, v2, v3, v4) \ - GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) -#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ - GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) -#define ASSERT_PRED4(pred, v1, v2, v3, v4) \ - GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) - -// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use -// this in your code. -template -AssertionResult AssertPred5Helper(const char* pred_text, const char* e1, - const char* e2, const char* e3, - const char* e4, const char* e5, Pred pred, - const T1& v1, const T2& v2, const T3& v3, - const T4& v4, const T5& v5) { - if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); - - return AssertionFailure() - << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4 - << ", " << e5 << ") evaluates to false, where" - << "\n" - << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n" - << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n" - << e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n" - << e4 << " evaluates to " << ::testing::PrintToString(v4) << "\n" - << e5 << " evaluates to " << ::testing::PrintToString(v5); -} - -// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. -// Don't use this in your code. -#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure) \ - GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \ - on_failure) - -// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use -// this in your code. -#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure) \ - GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, #v1, #v2, #v3, #v4, #v5, \ - pred, v1, v2, v3, v4, v5), \ - on_failure) - -// 5-ary predicate assertion macros. -#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ - GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) -#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ - GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) -#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ - GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) -#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ - GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) - -} // namespace testing - -#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest_prod.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest_prod.h deleted file mode 100644 index 1f37dc31..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/gtest_prod.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Google C++ Testing and Mocking Framework definitions useful in production -// code. - -#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_ -#define GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_ - -// When you need to test the private or protected members of a class, -// use the FRIEND_TEST macro to declare your tests as friends of the -// class. For example: -// -// class MyClass { -// private: -// void PrivateMethod(); -// FRIEND_TEST(MyClassTest, PrivateMethodWorks); -// }; -// -// class MyClassTest : public testing::Test { -// // ... -// }; -// -// TEST_F(MyClassTest, PrivateMethodWorks) { -// // Can call MyClass::PrivateMethod() here. -// } -// -// Note: The test class must be in the same namespace as the class being tested. -// For example, putting MyClassTest in an anonymous namespace will not work. - -#define FRIEND_TEST(test_case_name, test_name) \ - friend class test_case_name##_##test_name##_Test - -#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/custom/README.md b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/custom/README.md deleted file mode 100644 index cb49e2c7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/custom/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# Customization Points - -The custom directory is an injection point for custom user configurations. - -## Header `gtest.h` - -### The following macros can be defined: - -* `GTEST_OS_STACK_TRACE_GETTER_` - The name of an implementation of - `OsStackTraceGetterInterface`. -* `GTEST_CUSTOM_TEMPDIR_FUNCTION_` - An override for `testing::TempDir()`. See - `testing::TempDir` for semantics and signature. - -## Header `gtest-port.h` - -The following macros can be defined: - -### Logging: - -* `GTEST_LOG_(severity)` -* `GTEST_CHECK_(condition)` -* Functions `LogToStderr()` and `FlushInfoLog()` have to be provided too. - -### Threading: - -* `GTEST_HAS_NOTIFICATION_` - Enabled if Notification is already provided. -* `GTEST_HAS_MUTEX_AND_THREAD_LOCAL_` - Enabled if `Mutex` and `ThreadLocal` - are already provided. Must also provide `GTEST_DECLARE_STATIC_MUTEX_(mutex)` - and `GTEST_DEFINE_STATIC_MUTEX_(mutex)` -* `GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)` -* `GTEST_LOCK_EXCLUDED_(locks)` - -### Underlying library support features - -* `GTEST_HAS_CXXABI_H_` - -### Exporting API symbols: - -* `GTEST_API_` - Specifier for exported symbols. - -## Header `gtest-printers.h` - -* See documentation at `gtest/gtest-printers.h` for details on how to define a - custom printer. diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/custom/gtest-port.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/custom/gtest-port.h deleted file mode 100644 index 9b7fb426..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/custom/gtest-port.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2015, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Injection point for custom user configurations. See README for details -// -// ** Custom implementation starts here ** - -#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ -#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ - -// Use a stub Notification class. -// -// The built-in Notification class in GoogleTest v1.12.1 uses std::mutex and -// std::condition_variable. The and headers of -// mingw32 g++ (GNU 10.0.0) define std::mutex and std::condition_variable only -// when configured with the posix threads option but don't define them when -// configured with the win32 threads option. The Notification class is only -// used in GoogleTest's internal tests. Since we don't build GoogleTest's -// internal tests, we don't need a working Notification class. Although it's -// not hard to fix the mingw32 g++ compilation errors by implementing the -// Notification class using Windows CRITICAL_SECTION and CONDITION_VARIABLE, -// it's simpler to just use a stub Notification class on all platforms. -// -// The default constructor of the stub class is deleted and the declaration of -// the Notify() method is commented out, so that compilation will fail if any -// code actually uses the Notification class. - -#define GTEST_HAS_NOTIFICATION_ 1 -namespace testing { -namespace internal { -class Notification { - public: - Notification() = delete; - Notification(const Notification&) = delete; - Notification& operator=(const Notification&) = delete; - // void Notify(); - void WaitForNotification() {} -}; -} // namespace internal -} // namespace testing - -#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/custom/gtest-printers.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/custom/gtest-printers.h deleted file mode 100644 index b9495d83..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/custom/gtest-printers.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2015, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// This file provides an injection point for custom printers in a local -// installation of gTest. -// It will be included from gtest-printers.h and the overrides in this file -// will be visible to everyone. -// -// Injection point for custom user configurations. See README for details -// -// ** Custom implementation starts here ** - -#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ -#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ - -#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/custom/gtest.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/custom/gtest.h deleted file mode 100644 index afaaf17b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/custom/gtest.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2015, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Injection point for custom user configurations. See README for details -// -// ** Custom implementation starts here ** - -#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ -#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ - -#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-death-test-internal.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-death-test-internal.h deleted file mode 100644 index 45580ae8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-death-test-internal.h +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The Google C++ Testing and Mocking Framework (Google Test) -// -// This header file defines internal utilities needed for implementing -// death tests. They are subject to change without notice. - -// IWYU pragma: private, include "gtest/gtest.h" -// IWYU pragma: friend gtest/.* -// IWYU pragma: friend gmock/.* - -#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ -#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ - -#include - -#include - -#include "gtest/gtest-matchers.h" -#include "gtest/internal/gtest-internal.h" - -GTEST_DECLARE_string_(internal_run_death_test); - -namespace testing { -namespace internal { - -// Names of the flags (needed for parsing Google Test flags). -const char kDeathTestStyleFlag[] = "death_test_style"; -const char kDeathTestUseFork[] = "death_test_use_fork"; -const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; - -#if GTEST_HAS_DEATH_TEST - -GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ -/* class A needs to have dll-interface to be used by clients of class B */) - -// DeathTest is a class that hides much of the complexity of the -// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method -// returns a concrete class that depends on the prevailing death test -// style, as defined by the --gtest_death_test_style and/or -// --gtest_internal_run_death_test flags. - -// In describing the results of death tests, these terms are used with -// the corresponding definitions: -// -// exit status: The integer exit information in the format specified -// by wait(2) -// exit code: The integer code passed to exit(3), _exit(2), or -// returned from main() -class GTEST_API_ DeathTest { - public: - // Create returns false if there was an error determining the - // appropriate action to take for the current death test; for example, - // if the gtest_death_test_style flag is set to an invalid value. - // The LastMessage method will return a more detailed message in that - // case. Otherwise, the DeathTest pointer pointed to by the "test" - // argument is set. If the death test should be skipped, the pointer - // is set to NULL; otherwise, it is set to the address of a new concrete - // DeathTest object that controls the execution of the current test. - static bool Create(const char* statement, Matcher matcher, - const char* file, int line, DeathTest** test); - DeathTest(); - virtual ~DeathTest() {} - - // A helper class that aborts a death test when it's deleted. - class ReturnSentinel { - public: - explicit ReturnSentinel(DeathTest* test) : test_(test) {} - ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } - - private: - DeathTest* const test_; - ReturnSentinel(const ReturnSentinel&) = delete; - ReturnSentinel& operator=(const ReturnSentinel&) = delete; - } GTEST_ATTRIBUTE_UNUSED_; - - // An enumeration of possible roles that may be taken when a death - // test is encountered. EXECUTE means that the death test logic should - // be executed immediately. OVERSEE means that the program should prepare - // the appropriate environment for a child process to execute the death - // test, then wait for it to complete. - enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; - - // An enumeration of the three reasons that a test might be aborted. - enum AbortReason { - TEST_ENCOUNTERED_RETURN_STATEMENT, - TEST_THREW_EXCEPTION, - TEST_DID_NOT_DIE - }; - - // Assumes one of the above roles. - virtual TestRole AssumeRole() = 0; - - // Waits for the death test to finish and returns its status. - virtual int Wait() = 0; - - // Returns true if the death test passed; that is, the test process - // exited during the test, its exit status matches a user-supplied - // predicate, and its stderr output matches a user-supplied regular - // expression. - // The user-supplied predicate may be a macro expression rather - // than a function pointer or functor, or else Wait and Passed could - // be combined. - virtual bool Passed(bool exit_status_ok) = 0; - - // Signals that the death test did not die as expected. - virtual void Abort(AbortReason reason) = 0; - - // Returns a human-readable outcome message regarding the outcome of - // the last death test. - static const char* LastMessage(); - - static void set_last_death_test_message(const std::string& message); - - private: - // A string containing a description of the outcome of the last death test. - static std::string last_death_test_message_; - - DeathTest(const DeathTest&) = delete; - DeathTest& operator=(const DeathTest&) = delete; -}; - -GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 - -// Factory interface for death tests. May be mocked out for testing. -class DeathTestFactory { - public: - virtual ~DeathTestFactory() {} - virtual bool Create(const char* statement, - Matcher matcher, const char* file, - int line, DeathTest** test) = 0; -}; - -// A concrete DeathTestFactory implementation for normal use. -class DefaultDeathTestFactory : public DeathTestFactory { - public: - bool Create(const char* statement, Matcher matcher, - const char* file, int line, DeathTest** test) override; -}; - -// Returns true if exit_status describes a process that was terminated -// by a signal, or exited normally with a nonzero exit code. -GTEST_API_ bool ExitedUnsuccessfully(int exit_status); - -// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads -// and interpreted as a regex (rather than an Eq matcher) for legacy -// compatibility. -inline Matcher MakeDeathTestMatcher( - ::testing::internal::RE regex) { - return ContainsRegex(regex.pattern()); -} -inline Matcher MakeDeathTestMatcher(const char* regex) { - return ContainsRegex(regex); -} -inline Matcher MakeDeathTestMatcher( - const ::std::string& regex) { - return ContainsRegex(regex); -} - -// If a Matcher is passed to EXPECT_DEATH (etc.), it's -// used directly. -inline Matcher MakeDeathTestMatcher( - Matcher matcher) { - return matcher; -} - -// Traps C++ exceptions escaping statement and reports them as test -// failures. Note that trapping SEH exceptions is not implemented here. -#if GTEST_HAS_EXCEPTIONS -#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } catch (const ::std::exception& gtest_exception) { \ - fprintf( \ - stderr, \ - "\n%s: Caught std::exception-derived exception escaping the " \ - "death test statement. Exception message: %s\n", \ - ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ - gtest_exception.what()); \ - fflush(stderr); \ - death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ - } catch (...) { \ - death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ - } - -#else -#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) - -#endif - -// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, -// ASSERT_EXIT*, and EXPECT_EXIT*. -#define GTEST_DEATH_TEST_(statement, predicate, regex_or_matcher, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - ::testing::internal::DeathTest* gtest_dt; \ - if (!::testing::internal::DeathTest::Create( \ - #statement, \ - ::testing::internal::MakeDeathTestMatcher(regex_or_matcher), \ - __FILE__, __LINE__, >est_dt)) { \ - goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ - } \ - if (gtest_dt != nullptr) { \ - std::unique_ptr< ::testing::internal::DeathTest> gtest_dt_ptr(gtest_dt); \ - switch (gtest_dt->AssumeRole()) { \ - case ::testing::internal::DeathTest::OVERSEE_TEST: \ - if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ - goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ - } \ - break; \ - case ::testing::internal::DeathTest::EXECUTE_TEST: { \ - ::testing::internal::DeathTest::ReturnSentinel gtest_sentinel( \ - gtest_dt); \ - GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ - gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ - break; \ - } \ - } \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__) \ - : fail(::testing::internal::DeathTest::LastMessage()) -// The symbol "fail" here expands to something into which a message -// can be streamed. - -// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in -// NDEBUG mode. In this case we need the statements to be executed and the macro -// must accept a streamed message even though the message is never printed. -// The regex object is not evaluated, but it is used to prevent "unused" -// warnings and to avoid an expression that doesn't compile in debug mode. -#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } else if (!::testing::internal::AlwaysTrue()) { \ - ::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \ - } else \ - ::testing::Message() - -// A class representing the parsed contents of the -// --gtest_internal_run_death_test flag, as it existed when -// RUN_ALL_TESTS was called. -class InternalRunDeathTestFlag { - public: - InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index, - int a_write_fd) - : file_(a_file), line_(a_line), index_(an_index), write_fd_(a_write_fd) {} - - ~InternalRunDeathTestFlag() { - if (write_fd_ >= 0) posix::Close(write_fd_); - } - - const std::string& file() const { return file_; } - int line() const { return line_; } - int index() const { return index_; } - int write_fd() const { return write_fd_; } - - private: - std::string file_; - int line_; - int index_; - int write_fd_; - - InternalRunDeathTestFlag(const InternalRunDeathTestFlag&) = delete; - InternalRunDeathTestFlag& operator=(const InternalRunDeathTestFlag&) = delete; -}; - -// Returns a newly created InternalRunDeathTestFlag object with fields -// initialized from the GTEST_FLAG(internal_run_death_test) flag if -// the flag is specified; otherwise returns NULL. -InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); - -#endif // GTEST_HAS_DEATH_TEST - -} // namespace internal -} // namespace testing - -#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-filepath.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-filepath.h deleted file mode 100644 index a2a60a96..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-filepath.h +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Google Test filepath utilities -// -// This header file declares classes and functions used internally by -// Google Test. They are subject to change without notice. -// -// This file is #included in gtest/internal/gtest-internal.h. -// Do not include this header file separately! - -// IWYU pragma: private, include "gtest/gtest.h" -// IWYU pragma: friend gtest/.* -// IWYU pragma: friend gmock/.* - -#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ -#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ - -#include "gtest/internal/gtest-string.h" - -GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ -/* class A needs to have dll-interface to be used by clients of class B */) - -namespace testing { -namespace internal { - -// FilePath - a class for file and directory pathname manipulation which -// handles platform-specific conventions (like the pathname separator). -// Used for helper functions for naming files in a directory for xml output. -// Except for Set methods, all methods are const or static, which provides an -// "immutable value object" -- useful for peace of mind. -// A FilePath with a value ending in a path separator ("like/this/") represents -// a directory, otherwise it is assumed to represent a file. In either case, -// it may or may not represent an actual file or directory in the file system. -// Names are NOT checked for syntax correctness -- no checking for illegal -// characters, malformed paths, etc. - -class GTEST_API_ FilePath { - public: - FilePath() : pathname_("") {} - FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {} - - explicit FilePath(const std::string& pathname) : pathname_(pathname) { - Normalize(); - } - - FilePath& operator=(const FilePath& rhs) { - Set(rhs); - return *this; - } - - void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; } - - const std::string& string() const { return pathname_; } - const char* c_str() const { return pathname_.c_str(); } - - // Returns the current working directory, or "" if unsuccessful. - static FilePath GetCurrentDir(); - - // Given directory = "dir", base_name = "test", number = 0, - // extension = "xml", returns "dir/test.xml". If number is greater - // than zero (e.g., 12), returns "dir/test_12.xml". - // On Windows platform, uses \ as the separator rather than /. - static FilePath MakeFileName(const FilePath& directory, - const FilePath& base_name, int number, - const char* extension); - - // Given directory = "dir", relative_path = "test.xml", - // returns "dir/test.xml". - // On Windows, uses \ as the separator rather than /. - static FilePath ConcatPaths(const FilePath& directory, - const FilePath& relative_path); - - // Returns a pathname for a file that does not currently exist. The pathname - // will be directory/base_name.extension or - // directory/base_name_.extension if directory/base_name.extension - // already exists. The number will be incremented until a pathname is found - // that does not already exist. - // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. - // There could be a race condition if two or more processes are calling this - // function at the same time -- they could both pick the same filename. - static FilePath GenerateUniqueFileName(const FilePath& directory, - const FilePath& base_name, - const char* extension); - - // Returns true if and only if the path is "". - bool IsEmpty() const { return pathname_.empty(); } - - // If input name has a trailing separator character, removes it and returns - // the name, otherwise return the name string unmodified. - // On Windows platform, uses \ as the separator, other platforms use /. - FilePath RemoveTrailingPathSeparator() const; - - // Returns a copy of the FilePath with the directory part removed. - // Example: FilePath("path/to/file").RemoveDirectoryName() returns - // FilePath("file"). If there is no directory part ("just_a_file"), it returns - // the FilePath unmodified. If there is no file part ("just_a_dir/") it - // returns an empty FilePath (""). - // On Windows platform, '\' is the path separator, otherwise it is '/'. - FilePath RemoveDirectoryName() const; - - // RemoveFileName returns the directory path with the filename removed. - // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". - // If the FilePath is "a_file" or "/a_file", RemoveFileName returns - // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does - // not have a file, like "just/a/dir/", it returns the FilePath unmodified. - // On Windows platform, '\' is the path separator, otherwise it is '/'. - FilePath RemoveFileName() const; - - // Returns a copy of the FilePath with the case-insensitive extension removed. - // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns - // FilePath("dir/file"). If a case-insensitive extension is not - // found, returns a copy of the original FilePath. - FilePath RemoveExtension(const char* extension) const; - - // Creates directories so that path exists. Returns true if successful or if - // the directories already exist; returns false if unable to create - // directories for any reason. Will also return false if the FilePath does - // not represent a directory (that is, it doesn't end with a path separator). - bool CreateDirectoriesRecursively() const; - - // Create the directory so that path exists. Returns true if successful or - // if the directory already exists; returns false if unable to create the - // directory for any reason, including if the parent directory does not - // exist. Not named "CreateDirectory" because that's a macro on Windows. - bool CreateFolder() const; - - // Returns true if FilePath describes something in the file-system, - // either a file, directory, or whatever, and that something exists. - bool FileOrDirectoryExists() const; - - // Returns true if pathname describes a directory in the file-system - // that exists. - bool DirectoryExists() const; - - // Returns true if FilePath ends with a path separator, which indicates that - // it is intended to represent a directory. Returns false otherwise. - // This does NOT check that a directory (or file) actually exists. - bool IsDirectory() const; - - // Returns true if pathname describes a root directory. (Windows has one - // root directory per disk drive.) - bool IsRootDirectory() const; - - // Returns true if pathname describes an absolute path. - bool IsAbsolutePath() const; - - private: - // Replaces multiple consecutive separators with a single separator. - // For example, "bar///foo" becomes "bar/foo". Does not eliminate other - // redundancies that might be in a pathname involving "." or "..". - // - // A pathname with multiple consecutive separators may occur either through - // user error or as a result of some scripts or APIs that generate a pathname - // with a trailing separator. On other platforms the same API or script - // may NOT generate a pathname with a trailing "/". Then elsewhere that - // pathname may have another "/" and pathname components added to it, - // without checking for the separator already being there. - // The script language and operating system may allow paths like "foo//bar" - // but some of the functions in FilePath will not handle that correctly. In - // particular, RemoveTrailingPathSeparator() only removes one separator, and - // it is called in CreateDirectoriesRecursively() assuming that it will change - // a pathname from directory syntax (trailing separator) to filename syntax. - // - // On Windows this method also replaces the alternate path separator '/' with - // the primary path separator '\\', so that for example "bar\\/\\foo" becomes - // "bar\\foo". - - void Normalize(); - - // Returns a pointer to the last occurrence of a valid path separator in - // the FilePath. On Windows, for example, both '/' and '\' are valid path - // separators. Returns NULL if no path separator was found. - const char* FindLastPathSeparator() const; - - std::string pathname_; -}; // class FilePath - -} // namespace internal -} // namespace testing - -GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 - -#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-internal.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-internal.h deleted file mode 100644 index 9b04e4c8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-internal.h +++ /dev/null @@ -1,1570 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The Google C++ Testing and Mocking Framework (Google Test) -// -// This header file declares functions and macros used internally by -// Google Test. They are subject to change without notice. - -// IWYU pragma: private, include "gtest/gtest.h" -// IWYU pragma: friend gtest/.* -// IWYU pragma: friend gmock/.* - -#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ -#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ - -#include "gtest/internal/gtest-port.h" - -#if GTEST_OS_LINUX -#include -#include -#include -#include -#endif // GTEST_OS_LINUX - -#if GTEST_HAS_EXCEPTIONS -#include -#endif - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gtest/gtest-message.h" -#include "gtest/internal/gtest-filepath.h" -#include "gtest/internal/gtest-string.h" -#include "gtest/internal/gtest-type-util.h" - -// Due to C++ preprocessor weirdness, we need double indirection to -// concatenate two tokens when one of them is __LINE__. Writing -// -// foo ## __LINE__ -// -// will result in the token foo__LINE__, instead of foo followed by -// the current line number. For more details, see -// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 -#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) -#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo##bar - -// Stringifies its argument. -// Work around a bug in visual studio which doesn't accept code like this: -// -// #define GTEST_STRINGIFY_(name) #name -// #define MACRO(a, b, c) ... GTEST_STRINGIFY_(a) ... -// MACRO(, x, y) -// -// Complaining about the argument to GTEST_STRINGIFY_ being empty. -// This is allowed by the spec. -#define GTEST_STRINGIFY_HELPER_(name, ...) #name -#define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, ) - -namespace proto2 { -class MessageLite; -} - -namespace testing { - -// Forward declarations. - -class AssertionResult; // Result of an assertion. -class Message; // Represents a failure message. -class Test; // Represents a test. -class TestInfo; // Information about a test. -class TestPartResult; // Result of a test part. -class UnitTest; // A collection of test suites. - -template -::std::string PrintToString(const T& value); - -namespace internal { - -struct TraceInfo; // Information about a trace point. -class TestInfoImpl; // Opaque implementation of TestInfo -class UnitTestImpl; // Opaque implementation of UnitTest - -// The text used in failure messages to indicate the start of the -// stack trace. -GTEST_API_ extern const char kStackTraceMarker[]; - -// An IgnoredValue object can be implicitly constructed from ANY value. -class IgnoredValue { - struct Sink {}; - - public: - // This constructor template allows any value to be implicitly - // converted to IgnoredValue. The object has no data member and - // doesn't try to remember anything about the argument. We - // deliberately omit the 'explicit' keyword in order to allow the - // conversion to be implicit. - // Disable the conversion if T already has a magical conversion operator. - // Otherwise we get ambiguity. - template ::value, - int>::type = 0> - IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit) -}; - -// Appends the user-supplied message to the Google-Test-generated message. -GTEST_API_ std::string AppendUserMessage(const std::string& gtest_msg, - const Message& user_msg); - -#if GTEST_HAS_EXCEPTIONS - -GTEST_DISABLE_MSC_WARNINGS_PUSH_( - 4275 /* an exported class was derived from a class that was not exported */) - -// This exception is thrown by (and only by) a failed Google Test -// assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions -// are enabled). We derive it from std::runtime_error, which is for -// errors presumably detectable only at run time. Since -// std::runtime_error inherits from std::exception, many testing -// frameworks know how to extract and print the message inside it. -class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error { - public: - explicit GoogleTestFailureException(const TestPartResult& failure); -}; - -GTEST_DISABLE_MSC_WARNINGS_POP_() // 4275 - -#endif // GTEST_HAS_EXCEPTIONS - -namespace edit_distance { -// Returns the optimal edits to go from 'left' to 'right'. -// All edits cost the same, with replace having lower priority than -// add/remove. -// Simple implementation of the Wagner-Fischer algorithm. -// See http://en.wikipedia.org/wiki/Wagner-Fischer_algorithm -enum EditType { kMatch, kAdd, kRemove, kReplace }; -GTEST_API_ std::vector CalculateOptimalEdits( - const std::vector& left, const std::vector& right); - -// Same as above, but the input is represented as strings. -GTEST_API_ std::vector CalculateOptimalEdits( - const std::vector& left, - const std::vector& right); - -// Create a diff of the input strings in Unified diff format. -GTEST_API_ std::string CreateUnifiedDiff(const std::vector& left, - const std::vector& right, - size_t context = 2); - -} // namespace edit_distance - -// Constructs and returns the message for an equality assertion -// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. -// -// The first four parameters are the expressions used in the assertion -// and their values, as strings. For example, for ASSERT_EQ(foo, bar) -// where foo is 5 and bar is 6, we have: -// -// expected_expression: "foo" -// actual_expression: "bar" -// expected_value: "5" -// actual_value: "6" -// -// The ignoring_case parameter is true if and only if the assertion is a -// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will -// be inserted into the message. -GTEST_API_ AssertionResult EqFailure(const char* expected_expression, - const char* actual_expression, - const std::string& expected_value, - const std::string& actual_value, - bool ignoring_case); - -// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. -GTEST_API_ std::string GetBoolAssertionFailureMessage( - const AssertionResult& assertion_result, const char* expression_text, - const char* actual_predicate_value, const char* expected_predicate_value); - -// This template class represents an IEEE floating-point number -// (either single-precision or double-precision, depending on the -// template parameters). -// -// The purpose of this class is to do more sophisticated number -// comparison. (Due to round-off error, etc, it's very unlikely that -// two floating-points will be equal exactly. Hence a naive -// comparison by the == operation often doesn't work.) -// -// Format of IEEE floating-point: -// -// The most-significant bit being the leftmost, an IEEE -// floating-point looks like -// -// sign_bit exponent_bits fraction_bits -// -// Here, sign_bit is a single bit that designates the sign of the -// number. -// -// For float, there are 8 exponent bits and 23 fraction bits. -// -// For double, there are 11 exponent bits and 52 fraction bits. -// -// More details can be found at -// http://en.wikipedia.org/wiki/IEEE_floating-point_standard. -// -// Template parameter: -// -// RawType: the raw floating-point type (either float or double) -template -class FloatingPoint { - public: - // Defines the unsigned integer type that has the same size as the - // floating point number. - typedef typename TypeWithSize::UInt Bits; - - // Constants. - - // # of bits in a number. - static const size_t kBitCount = 8 * sizeof(RawType); - - // # of fraction bits in a number. - static const size_t kFractionBitCount = - std::numeric_limits::digits - 1; - - // # of exponent bits in a number. - static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; - - // The mask for the sign bit. - static const Bits kSignBitMask = static_cast(1) << (kBitCount - 1); - - // The mask for the fraction bits. - static const Bits kFractionBitMask = ~static_cast(0) >> - (kExponentBitCount + 1); - - // The mask for the exponent bits. - static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); - - // How many ULP's (Units in the Last Place) we want to tolerate when - // comparing two numbers. The larger the value, the more error we - // allow. A 0 value means that two numbers must be exactly the same - // to be considered equal. - // - // The maximum error of a single floating-point operation is 0.5 - // units in the last place. On Intel CPU's, all floating-point - // calculations are done with 80-bit precision, while double has 64 - // bits. Therefore, 4 should be enough for ordinary use. - // - // See the following article for more details on ULP: - // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ - static const uint32_t kMaxUlps = 4; - - // Constructs a FloatingPoint from a raw floating-point number. - // - // On an Intel CPU, passing a non-normalized NAN (Not a Number) - // around may change its bits, although the new value is guaranteed - // to be also a NAN. Therefore, don't expect this constructor to - // preserve the bits in x when x is a NAN. - explicit FloatingPoint(const RawType& x) { u_.value_ = x; } - - // Static methods - - // Reinterprets a bit pattern as a floating-point number. - // - // This function is needed to test the AlmostEquals() method. - static RawType ReinterpretBits(const Bits bits) { - FloatingPoint fp(0); - fp.u_.bits_ = bits; - return fp.u_.value_; - } - - // Returns the floating-point number that represent positive infinity. - static RawType Infinity() { return ReinterpretBits(kExponentBitMask); } - - // Returns the maximum representable finite floating-point number. - static RawType Max(); - - // Non-static methods - - // Returns the bits that represents this number. - const Bits& bits() const { return u_.bits_; } - - // Returns the exponent bits of this number. - Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } - - // Returns the fraction bits of this number. - Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } - - // Returns the sign bit of this number. - Bits sign_bit() const { return kSignBitMask & u_.bits_; } - - // Returns true if and only if this is NAN (not a number). - bool is_nan() const { - // It's a NAN if the exponent bits are all ones and the fraction - // bits are not entirely zeros. - return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); - } - - // Returns true if and only if this number is at most kMaxUlps ULP's away - // from rhs. In particular, this function: - // - // - returns false if either number is (or both are) NAN. - // - treats really large numbers as almost equal to infinity. - // - thinks +0.0 and -0.0 are 0 DLP's apart. - bool AlmostEquals(const FloatingPoint& rhs) const { - // The IEEE standard says that any comparison operation involving - // a NAN must return false. - if (is_nan() || rhs.is_nan()) return false; - - return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <= - kMaxUlps; - } - - private: - // The data type used to store the actual floating-point number. - union FloatingPointUnion { - RawType value_; // The raw floating-point number. - Bits bits_; // The bits that represent the number. - }; - - // Converts an integer from the sign-and-magnitude representation to - // the biased representation. More precisely, let N be 2 to the - // power of (kBitCount - 1), an integer x is represented by the - // unsigned number x + N. - // - // For instance, - // - // -N + 1 (the most negative number representable using - // sign-and-magnitude) is represented by 1; - // 0 is represented by N; and - // N - 1 (the biggest number representable using - // sign-and-magnitude) is represented by 2N - 1. - // - // Read http://en.wikipedia.org/wiki/Signed_number_representations - // for more details on signed number representations. - static Bits SignAndMagnitudeToBiased(const Bits& sam) { - if (kSignBitMask & sam) { - // sam represents a negative number. - return ~sam + 1; - } else { - // sam represents a positive number. - return kSignBitMask | sam; - } - } - - // Given two numbers in the sign-and-magnitude representation, - // returns the distance between them as an unsigned number. - static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1, - const Bits& sam2) { - const Bits biased1 = SignAndMagnitudeToBiased(sam1); - const Bits biased2 = SignAndMagnitudeToBiased(sam2); - return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); - } - - FloatingPointUnion u_; -}; - -// We cannot use std::numeric_limits::max() as it clashes with the max() -// macro defined by . -template <> -inline float FloatingPoint::Max() { - return FLT_MAX; -} -template <> -inline double FloatingPoint::Max() { - return DBL_MAX; -} - -// Typedefs the instances of the FloatingPoint template class that we -// care to use. -typedef FloatingPoint Float; -typedef FloatingPoint Double; - -// In order to catch the mistake of putting tests that use different -// test fixture classes in the same test suite, we need to assign -// unique IDs to fixture classes and compare them. The TypeId type is -// used to hold such IDs. The user should treat TypeId as an opaque -// type: the only operation allowed on TypeId values is to compare -// them for equality using the == operator. -typedef const void* TypeId; - -template -class TypeIdHelper { - public: - // dummy_ must not have a const type. Otherwise an overly eager - // compiler (e.g. MSVC 7.1 & 8.0) may try to merge - // TypeIdHelper::dummy_ for different Ts as an "optimization". - static bool dummy_; -}; - -template -bool TypeIdHelper::dummy_ = false; - -// GetTypeId() returns the ID of type T. Different values will be -// returned for different types. Calling the function twice with the -// same type argument is guaranteed to return the same ID. -template -TypeId GetTypeId() { - // The compiler is required to allocate a different - // TypeIdHelper::dummy_ variable for each T used to instantiate - // the template. Therefore, the address of dummy_ is guaranteed to - // be unique. - return &(TypeIdHelper::dummy_); -} - -// Returns the type ID of ::testing::Test. Always call this instead -// of GetTypeId< ::testing::Test>() to get the type ID of -// ::testing::Test, as the latter may give the wrong result due to a -// suspected linker bug when compiling Google Test as a Mac OS X -// framework. -GTEST_API_ TypeId GetTestTypeId(); - -// Defines the abstract factory interface that creates instances -// of a Test object. -class TestFactoryBase { - public: - virtual ~TestFactoryBase() {} - - // Creates a test instance to run. The instance is both created and destroyed - // within TestInfoImpl::Run() - virtual Test* CreateTest() = 0; - - protected: - TestFactoryBase() {} - - private: - TestFactoryBase(const TestFactoryBase&) = delete; - TestFactoryBase& operator=(const TestFactoryBase&) = delete; -}; - -// This class provides implementation of TeastFactoryBase interface. -// It is used in TEST and TEST_F macros. -template -class TestFactoryImpl : public TestFactoryBase { - public: - Test* CreateTest() override { return new TestClass; } -}; - -#if GTEST_OS_WINDOWS - -// Predicate-formatters for implementing the HRESULT checking macros -// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} -// We pass a long instead of HRESULT to avoid causing an -// include dependency for the HRESULT type. -GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr, - long hr); // NOLINT -GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, - long hr); // NOLINT - -#endif // GTEST_OS_WINDOWS - -// Types of SetUpTestSuite() and TearDownTestSuite() functions. -using SetUpTestSuiteFunc = void (*)(); -using TearDownTestSuiteFunc = void (*)(); - -struct CodeLocation { - CodeLocation(const std::string& a_file, int a_line) - : file(a_file), line(a_line) {} - - std::string file; - int line; -}; - -// Helper to identify which setup function for TestCase / TestSuite to call. -// Only one function is allowed, either TestCase or TestSute but not both. - -// Utility functions to help SuiteApiResolver -using SetUpTearDownSuiteFuncType = void (*)(); - -inline SetUpTearDownSuiteFuncType GetNotDefaultOrNull( - SetUpTearDownSuiteFuncType a, SetUpTearDownSuiteFuncType def) { - return a == def ? nullptr : a; -} - -template -// Note that SuiteApiResolver inherits from T because -// SetUpTestSuite()/TearDownTestSuite() could be protected. This way -// SuiteApiResolver can access them. -struct SuiteApiResolver : T { - // testing::Test is only forward declared at this point. So we make it a - // dependent class for the compiler to be OK with it. - using Test = - typename std::conditional::type; - - static SetUpTearDownSuiteFuncType GetSetUpCaseOrSuite(const char* filename, - int line_num) { -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - SetUpTearDownSuiteFuncType test_case_fp = - GetNotDefaultOrNull(&T::SetUpTestCase, &Test::SetUpTestCase); - SetUpTearDownSuiteFuncType test_suite_fp = - GetNotDefaultOrNull(&T::SetUpTestSuite, &Test::SetUpTestSuite); - - GTEST_CHECK_(!test_case_fp || !test_suite_fp) - << "Test can not provide both SetUpTestSuite and SetUpTestCase, please " - "make sure there is only one present at " - << filename << ":" << line_num; - - return test_case_fp != nullptr ? test_case_fp : test_suite_fp; -#else - (void)(filename); - (void)(line_num); - return &T::SetUpTestSuite; -#endif - } - - static SetUpTearDownSuiteFuncType GetTearDownCaseOrSuite(const char* filename, - int line_num) { -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - SetUpTearDownSuiteFuncType test_case_fp = - GetNotDefaultOrNull(&T::TearDownTestCase, &Test::TearDownTestCase); - SetUpTearDownSuiteFuncType test_suite_fp = - GetNotDefaultOrNull(&T::TearDownTestSuite, &Test::TearDownTestSuite); - - GTEST_CHECK_(!test_case_fp || !test_suite_fp) - << "Test can not provide both TearDownTestSuite and TearDownTestCase," - " please make sure there is only one present at" - << filename << ":" << line_num; - - return test_case_fp != nullptr ? test_case_fp : test_suite_fp; -#else - (void)(filename); - (void)(line_num); - return &T::TearDownTestSuite; -#endif - } -}; - -// Creates a new TestInfo object and registers it with Google Test; -// returns the created object. -// -// Arguments: -// -// test_suite_name: name of the test suite -// name: name of the test -// type_param: the name of the test's type parameter, or NULL if -// this is not a typed or a type-parameterized test. -// value_param: text representation of the test's value parameter, -// or NULL if this is not a type-parameterized test. -// code_location: code location where the test is defined -// fixture_class_id: ID of the test fixture class -// set_up_tc: pointer to the function that sets up the test suite -// tear_down_tc: pointer to the function that tears down the test suite -// factory: pointer to the factory that creates a test object. -// The newly created TestInfo instance will assume -// ownership of the factory object. -GTEST_API_ TestInfo* MakeAndRegisterTestInfo( - const char* test_suite_name, const char* name, const char* type_param, - const char* value_param, CodeLocation code_location, - TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc, - TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory); - -// If *pstr starts with the given prefix, modifies *pstr to be right -// past the prefix and returns true; otherwise leaves *pstr unchanged -// and returns false. None of pstr, *pstr, and prefix can be NULL. -GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr); - -GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ -/* class A needs to have dll-interface to be used by clients of class B */) - -// State of the definition of a type-parameterized test suite. -class GTEST_API_ TypedTestSuitePState { - public: - TypedTestSuitePState() : registered_(false) {} - - // Adds the given test name to defined_test_names_ and return true - // if the test suite hasn't been registered; otherwise aborts the - // program. - bool AddTestName(const char* file, int line, const char* case_name, - const char* test_name) { - if (registered_) { - fprintf(stderr, - "%s Test %s must be defined before " - "REGISTER_TYPED_TEST_SUITE_P(%s, ...).\n", - FormatFileLocation(file, line).c_str(), test_name, case_name); - fflush(stderr); - posix::Abort(); - } - registered_tests_.insert( - ::std::make_pair(test_name, CodeLocation(file, line))); - return true; - } - - bool TestExists(const std::string& test_name) const { - return registered_tests_.count(test_name) > 0; - } - - const CodeLocation& GetCodeLocation(const std::string& test_name) const { - RegisteredTestsMap::const_iterator it = registered_tests_.find(test_name); - GTEST_CHECK_(it != registered_tests_.end()); - return it->second; - } - - // Verifies that registered_tests match the test names in - // defined_test_names_; returns registered_tests if successful, or - // aborts the program otherwise. - const char* VerifyRegisteredTestNames(const char* test_suite_name, - const char* file, int line, - const char* registered_tests); - - private: - typedef ::std::map RegisteredTestsMap; - - bool registered_; - RegisteredTestsMap registered_tests_; -}; - -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -using TypedTestCasePState = TypedTestSuitePState; -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - -GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 - -// Skips to the first non-space char after the first comma in 'str'; -// returns NULL if no comma is found in 'str'. -inline const char* SkipComma(const char* str) { - const char* comma = strchr(str, ','); - if (comma == nullptr) { - return nullptr; - } - while (IsSpace(*(++comma))) { - } - return comma; -} - -// Returns the prefix of 'str' before the first comma in it; returns -// the entire string if it contains no comma. -inline std::string GetPrefixUntilComma(const char* str) { - const char* comma = strchr(str, ','); - return comma == nullptr ? str : std::string(str, comma); -} - -// Splits a given string on a given delimiter, populating a given -// vector with the fields. -void SplitString(const ::std::string& str, char delimiter, - ::std::vector<::std::string>* dest); - -// The default argument to the template below for the case when the user does -// not provide a name generator. -struct DefaultNameGenerator { - template - static std::string GetName(int i) { - return StreamableToString(i); - } -}; - -template -struct NameGeneratorSelector { - typedef Provided type; -}; - -template -void GenerateNamesRecursively(internal::None, std::vector*, int) {} - -template -void GenerateNamesRecursively(Types, std::vector* result, int i) { - result->push_back(NameGenerator::template GetName(i)); - GenerateNamesRecursively(typename Types::Tail(), result, - i + 1); -} - -template -std::vector GenerateNames() { - std::vector result; - GenerateNamesRecursively(Types(), &result, 0); - return result; -} - -// TypeParameterizedTest::Register() -// registers a list of type-parameterized tests with Google Test. The -// return value is insignificant - we just need to return something -// such that we can call this function in a namespace scope. -// -// Implementation note: The GTEST_TEMPLATE_ macro declares a template -// template parameter. It's defined in gtest-type-util.h. -template -class TypeParameterizedTest { - public: - // 'index' is the index of the test in the type list 'Types' - // specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite, - // Types). Valid values for 'index' are [0, N - 1] where N is the - // length of Types. - static bool Register(const char* prefix, const CodeLocation& code_location, - const char* case_name, const char* test_names, int index, - const std::vector& type_names = - GenerateNames()) { - typedef typename Types::Head Type; - typedef Fixture FixtureClass; - typedef typename GTEST_BIND_(TestSel, Type) TestClass; - - // First, registers the first type-parameterized test in the type - // list. - MakeAndRegisterTestInfo( - (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + - "/" + type_names[static_cast(index)]) - .c_str(), - StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(), - GetTypeName().c_str(), - nullptr, // No value parameter. - code_location, GetTypeId(), - SuiteApiResolver::GetSetUpCaseOrSuite( - code_location.file.c_str(), code_location.line), - SuiteApiResolver::GetTearDownCaseOrSuite( - code_location.file.c_str(), code_location.line), - new TestFactoryImpl); - - // Next, recurses (at compile time) with the tail of the type list. - return TypeParameterizedTest::Register(prefix, - code_location, - case_name, - test_names, - index + 1, - type_names); - } -}; - -// The base case for the compile time recursion. -template -class TypeParameterizedTest { - public: - static bool Register(const char* /*prefix*/, const CodeLocation&, - const char* /*case_name*/, const char* /*test_names*/, - int /*index*/, - const std::vector& = - std::vector() /*type_names*/) { - return true; - } -}; - -GTEST_API_ void RegisterTypeParameterizedTestSuite(const char* test_suite_name, - CodeLocation code_location); -GTEST_API_ void RegisterTypeParameterizedTestSuiteInstantiation( - const char* case_name); - -// TypeParameterizedTestSuite::Register() -// registers *all combinations* of 'Tests' and 'Types' with Google -// Test. The return value is insignificant - we just need to return -// something such that we can call this function in a namespace scope. -template -class TypeParameterizedTestSuite { - public: - static bool Register(const char* prefix, CodeLocation code_location, - const TypedTestSuitePState* state, const char* case_name, - const char* test_names, - const std::vector& type_names = - GenerateNames()) { - RegisterTypeParameterizedTestSuiteInstantiation(case_name); - std::string test_name = - StripTrailingSpaces(GetPrefixUntilComma(test_names)); - if (!state->TestExists(test_name)) { - fprintf(stderr, "Failed to get code location for test %s.%s at %s.", - case_name, test_name.c_str(), - FormatFileLocation(code_location.file.c_str(), code_location.line) - .c_str()); - fflush(stderr); - posix::Abort(); - } - const CodeLocation& test_location = state->GetCodeLocation(test_name); - - typedef typename Tests::Head Head; - - // First, register the first test in 'Test' for each type in 'Types'. - TypeParameterizedTest::Register( - prefix, test_location, case_name, test_names, 0, type_names); - - // Next, recurses (at compile time) with the tail of the test list. - return TypeParameterizedTestSuite::Register(prefix, code_location, - state, case_name, - SkipComma(test_names), - type_names); - } -}; - -// The base case for the compile time recursion. -template -class TypeParameterizedTestSuite { - public: - static bool Register(const char* /*prefix*/, const CodeLocation&, - const TypedTestSuitePState* /*state*/, - const char* /*case_name*/, const char* /*test_names*/, - const std::vector& = - std::vector() /*type_names*/) { - return true; - } -}; - -// Returns the current OS stack trace as an std::string. -// -// The maximum number of stack frames to be included is specified by -// the gtest_stack_trace_depth flag. The skip_count parameter -// specifies the number of top frames to be skipped, which doesn't -// count against the number of frames to be included. -// -// For example, if Foo() calls Bar(), which in turn calls -// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in -// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. -GTEST_API_ std::string GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, - int skip_count); - -// Helpers for suppressing warnings on unreachable code or constant -// condition. - -// Always returns true. -GTEST_API_ bool AlwaysTrue(); - -// Always returns false. -inline bool AlwaysFalse() { return !AlwaysTrue(); } - -// Helper for suppressing false warning from Clang on a const char* -// variable declared in a conditional expression always being NULL in -// the else branch. -struct GTEST_API_ ConstCharPtr { - ConstCharPtr(const char* str) : value(str) {} - operator bool() const { return true; } - const char* value; -}; - -// Helper for declaring std::string within 'if' statement -// in pre C++17 build environment. -struct TrueWithString { - TrueWithString() = default; - explicit TrueWithString(const char* str) : value(str) {} - explicit TrueWithString(const std::string& str) : value(str) {} - explicit operator bool() const { return true; } - std::string value; -}; - -// A simple Linear Congruential Generator for generating random -// numbers with a uniform distribution. Unlike rand() and srand(), it -// doesn't use global state (and therefore can't interfere with user -// code). Unlike rand_r(), it's portable. An LCG isn't very random, -// but it's good enough for our purposes. -class GTEST_API_ Random { - public: - static const uint32_t kMaxRange = 1u << 31; - - explicit Random(uint32_t seed) : state_(seed) {} - - void Reseed(uint32_t seed) { state_ = seed; } - - // Generates a random number from [0, range). Crashes if 'range' is - // 0 or greater than kMaxRange. - uint32_t Generate(uint32_t range); - - private: - uint32_t state_; - Random(const Random&) = delete; - Random& operator=(const Random&) = delete; -}; - -// Turns const U&, U&, const U, and U all into U. -#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ - typename std::remove_const::type>::type - -// HasDebugStringAndShortDebugString::value is a compile-time bool constant -// that's true if and only if T has methods DebugString() and ShortDebugString() -// that return std::string. -template -class HasDebugStringAndShortDebugString { - private: - template - static auto CheckDebugString(C*) -> typename std::is_same< - std::string, decltype(std::declval().DebugString())>::type; - template - static std::false_type CheckDebugString(...); - - template - static auto CheckShortDebugString(C*) -> typename std::is_same< - std::string, decltype(std::declval().ShortDebugString())>::type; - template - static std::false_type CheckShortDebugString(...); - - using HasDebugStringType = decltype(CheckDebugString(nullptr)); - using HasShortDebugStringType = decltype(CheckShortDebugString(nullptr)); - - public: - static constexpr bool value = - HasDebugStringType::value && HasShortDebugStringType::value; -}; - -template -constexpr bool HasDebugStringAndShortDebugString::value; - -// When the compiler sees expression IsContainerTest(0), if C is an -// STL-style container class, the first overload of IsContainerTest -// will be viable (since both C::iterator* and C::const_iterator* are -// valid types and NULL can be implicitly converted to them). It will -// be picked over the second overload as 'int' is a perfect match for -// the type of argument 0. If C::iterator or C::const_iterator is not -// a valid type, the first overload is not viable, and the second -// overload will be picked. Therefore, we can determine whether C is -// a container class by checking the type of IsContainerTest(0). -// The value of the expression is insignificant. -// -// In C++11 mode we check the existence of a const_iterator and that an -// iterator is properly implemented for the container. -// -// For pre-C++11 that we look for both C::iterator and C::const_iterator. -// The reason is that C++ injects the name of a class as a member of the -// class itself (e.g. you can refer to class iterator as either -// 'iterator' or 'iterator::iterator'). If we look for C::iterator -// only, for example, we would mistakenly think that a class named -// iterator is an STL container. -// -// Also note that the simpler approach of overloading -// IsContainerTest(typename C::const_iterator*) and -// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++. -typedef int IsContainer; -template ().begin()), - class = decltype(::std::declval().end()), - class = decltype(++::std::declval()), - class = decltype(*::std::declval()), - class = typename C::const_iterator> -IsContainer IsContainerTest(int /* dummy */) { - return 0; -} - -typedef char IsNotContainer; -template -IsNotContainer IsContainerTest(long /* dummy */) { - return '\0'; -} - -// Trait to detect whether a type T is a hash table. -// The heuristic used is that the type contains an inner type `hasher` and does -// not contain an inner type `reverse_iterator`. -// If the container is iterable in reverse, then order might actually matter. -template -struct IsHashTable { - private: - template - static char test(typename U::hasher*, typename U::reverse_iterator*); - template - static int test(typename U::hasher*, ...); - template - static char test(...); - - public: - static const bool value = sizeof(test(nullptr, nullptr)) == sizeof(int); -}; - -template -const bool IsHashTable::value; - -template (0)) == sizeof(IsContainer)> -struct IsRecursiveContainerImpl; - -template -struct IsRecursiveContainerImpl : public std::false_type {}; - -// Since the IsRecursiveContainerImpl depends on the IsContainerTest we need to -// obey the same inconsistencies as the IsContainerTest, namely check if -// something is a container is relying on only const_iterator in C++11 and -// is relying on both const_iterator and iterator otherwise -template -struct IsRecursiveContainerImpl { - using value_type = decltype(*std::declval()); - using type = - std::is_same::type>::type, - C>; -}; - -// IsRecursiveContainer is a unary compile-time predicate that -// evaluates whether C is a recursive container type. A recursive container -// type is a container type whose value_type is equal to the container type -// itself. An example for a recursive container type is -// boost::filesystem::path, whose iterator has a value_type that is equal to -// boost::filesystem::path. -template -struct IsRecursiveContainer : public IsRecursiveContainerImpl::type {}; - -// Utilities for native arrays. - -// ArrayEq() compares two k-dimensional native arrays using the -// elements' operator==, where k can be any integer >= 0. When k is -// 0, ArrayEq() degenerates into comparing a single pair of values. - -template -bool ArrayEq(const T* lhs, size_t size, const U* rhs); - -// This generic version is used when k is 0. -template -inline bool ArrayEq(const T& lhs, const U& rhs) { - return lhs == rhs; -} - -// This overload is used when k >= 1. -template -inline bool ArrayEq(const T (&lhs)[N], const U (&rhs)[N]) { - return internal::ArrayEq(lhs, N, rhs); -} - -// This helper reduces code bloat. If we instead put its logic inside -// the previous ArrayEq() function, arrays with different sizes would -// lead to different copies of the template code. -template -bool ArrayEq(const T* lhs, size_t size, const U* rhs) { - for (size_t i = 0; i != size; i++) { - if (!internal::ArrayEq(lhs[i], rhs[i])) return false; - } - return true; -} - -// Finds the first element in the iterator range [begin, end) that -// equals elem. Element may be a native array type itself. -template -Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) { - for (Iter it = begin; it != end; ++it) { - if (internal::ArrayEq(*it, elem)) return it; - } - return end; -} - -// CopyArray() copies a k-dimensional native array using the elements' -// operator=, where k can be any integer >= 0. When k is 0, -// CopyArray() degenerates into copying a single value. - -template -void CopyArray(const T* from, size_t size, U* to); - -// This generic version is used when k is 0. -template -inline void CopyArray(const T& from, U* to) { - *to = from; -} - -// This overload is used when k >= 1. -template -inline void CopyArray(const T (&from)[N], U (*to)[N]) { - internal::CopyArray(from, N, *to); -} - -// This helper reduces code bloat. If we instead put its logic inside -// the previous CopyArray() function, arrays with different sizes -// would lead to different copies of the template code. -template -void CopyArray(const T* from, size_t size, U* to) { - for (size_t i = 0; i != size; i++) { - internal::CopyArray(from[i], to + i); - } -} - -// The relation between an NativeArray object (see below) and the -// native array it represents. -// We use 2 different structs to allow non-copyable types to be used, as long -// as RelationToSourceReference() is passed. -struct RelationToSourceReference {}; -struct RelationToSourceCopy {}; - -// Adapts a native array to a read-only STL-style container. Instead -// of the complete STL container concept, this adaptor only implements -// members useful for Google Mock's container matchers. New members -// should be added as needed. To simplify the implementation, we only -// support Element being a raw type (i.e. having no top-level const or -// reference modifier). It's the client's responsibility to satisfy -// this requirement. Element can be an array type itself (hence -// multi-dimensional arrays are supported). -template -class NativeArray { - public: - // STL-style container typedefs. - typedef Element value_type; - typedef Element* iterator; - typedef const Element* const_iterator; - - // Constructs from a native array. References the source. - NativeArray(const Element* array, size_t count, RelationToSourceReference) { - InitRef(array, count); - } - - // Constructs from a native array. Copies the source. - NativeArray(const Element* array, size_t count, RelationToSourceCopy) { - InitCopy(array, count); - } - - // Copy constructor. - NativeArray(const NativeArray& rhs) { - (this->*rhs.clone_)(rhs.array_, rhs.size_); - } - - ~NativeArray() { - if (clone_ != &NativeArray::InitRef) delete[] array_; - } - - // STL-style container methods. - size_t size() const { return size_; } - const_iterator begin() const { return array_; } - const_iterator end() const { return array_ + size_; } - bool operator==(const NativeArray& rhs) const { - return size() == rhs.size() && ArrayEq(begin(), size(), rhs.begin()); - } - - private: - static_assert(!std::is_const::value, "Type must not be const"); - static_assert(!std::is_reference::value, - "Type must not be a reference"); - - // Initializes this object with a copy of the input. - void InitCopy(const Element* array, size_t a_size) { - Element* const copy = new Element[a_size]; - CopyArray(array, a_size, copy); - array_ = copy; - size_ = a_size; - clone_ = &NativeArray::InitCopy; - } - - // Initializes this object with a reference of the input. - void InitRef(const Element* array, size_t a_size) { - array_ = array; - size_ = a_size; - clone_ = &NativeArray::InitRef; - } - - const Element* array_; - size_t size_; - void (NativeArray::*clone_)(const Element*, size_t); -}; - -// Backport of std::index_sequence. -template -struct IndexSequence { - using type = IndexSequence; -}; - -// Double the IndexSequence, and one if plus_one is true. -template -struct DoubleSequence; -template -struct DoubleSequence, sizeofT> { - using type = IndexSequence; -}; -template -struct DoubleSequence, sizeofT> { - using type = IndexSequence; -}; - -// Backport of std::make_index_sequence. -// It uses O(ln(N)) instantiation depth. -template -struct MakeIndexSequenceImpl - : DoubleSequence::type, - N / 2>::type {}; - -template <> -struct MakeIndexSequenceImpl<0> : IndexSequence<> {}; - -template -using MakeIndexSequence = typename MakeIndexSequenceImpl::type; - -template -using IndexSequenceFor = typename MakeIndexSequence::type; - -template -struct Ignore { - Ignore(...); // NOLINT -}; - -template -struct ElemFromListImpl; -template -struct ElemFromListImpl> { - // We make Ignore a template to solve a problem with MSVC. - // A non-template Ignore would work fine with `decltype(Ignore(I))...`, but - // MSVC doesn't understand how to deal with that pack expansion. - // Use `0 * I` to have a single instantiation of Ignore. - template - static R Apply(Ignore<0 * I>..., R (*)(), ...); -}; - -template -struct ElemFromList { - using type = - decltype(ElemFromListImpl::type>::Apply( - static_cast(nullptr)...)); -}; - -struct FlatTupleConstructTag {}; - -template -class FlatTuple; - -template -struct FlatTupleElemBase; - -template -struct FlatTupleElemBase, I> { - using value_type = typename ElemFromList::type; - FlatTupleElemBase() = default; - template - explicit FlatTupleElemBase(FlatTupleConstructTag, Arg&& t) - : value(std::forward(t)) {} - value_type value; -}; - -template -struct FlatTupleBase; - -template -struct FlatTupleBase, IndexSequence> - : FlatTupleElemBase, Idx>... { - using Indices = IndexSequence; - FlatTupleBase() = default; - template - explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args) - : FlatTupleElemBase, Idx>(FlatTupleConstructTag{}, - std::forward(args))... {} - - template - const typename ElemFromList::type& Get() const { - return FlatTupleElemBase, I>::value; - } - - template - typename ElemFromList::type& Get() { - return FlatTupleElemBase, I>::value; - } - - template - auto Apply(F&& f) -> decltype(std::forward(f)(this->Get()...)) { - return std::forward(f)(Get()...); - } - - template - auto Apply(F&& f) const -> decltype(std::forward(f)(this->Get()...)) { - return std::forward(f)(Get()...); - } -}; - -// Analog to std::tuple but with different tradeoffs. -// This class minimizes the template instantiation depth, thus allowing more -// elements than std::tuple would. std::tuple has been seen to require an -// instantiation depth of more than 10x the number of elements in some -// implementations. -// FlatTuple and ElemFromList are not recursive and have a fixed depth -// regardless of T... -// MakeIndexSequence, on the other hand, it is recursive but with an -// instantiation depth of O(ln(N)). -template -class FlatTuple - : private FlatTupleBase, - typename MakeIndexSequence::type> { - using Indices = typename FlatTupleBase< - FlatTuple, typename MakeIndexSequence::type>::Indices; - - public: - FlatTuple() = default; - template - explicit FlatTuple(FlatTupleConstructTag tag, Args&&... args) - : FlatTuple::FlatTupleBase(tag, std::forward(args)...) {} - - using FlatTuple::FlatTupleBase::Apply; - using FlatTuple::FlatTupleBase::Get; -}; - -// Utility functions to be called with static_assert to induce deprecation -// warnings. -GTEST_INTERNAL_DEPRECATED( - "INSTANTIATE_TEST_CASE_P is deprecated, please use " - "INSTANTIATE_TEST_SUITE_P") -constexpr bool InstantiateTestCase_P_IsDeprecated() { return true; } - -GTEST_INTERNAL_DEPRECATED( - "TYPED_TEST_CASE_P is deprecated, please use " - "TYPED_TEST_SUITE_P") -constexpr bool TypedTestCase_P_IsDeprecated() { return true; } - -GTEST_INTERNAL_DEPRECATED( - "TYPED_TEST_CASE is deprecated, please use " - "TYPED_TEST_SUITE") -constexpr bool TypedTestCaseIsDeprecated() { return true; } - -GTEST_INTERNAL_DEPRECATED( - "REGISTER_TYPED_TEST_CASE_P is deprecated, please use " - "REGISTER_TYPED_TEST_SUITE_P") -constexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; } - -GTEST_INTERNAL_DEPRECATED( - "INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use " - "INSTANTIATE_TYPED_TEST_SUITE_P") -constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; } - -} // namespace internal -} // namespace testing - -namespace std { -// Some standard library implementations use `struct tuple_size` and some use -// `class tuple_size`. Clang warns about the mismatch. -// https://reviews.llvm.org/D55466 -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wmismatched-tags" -#endif -template -struct tuple_size> - : std::integral_constant {}; -#ifdef __clang__ -#pragma clang diagnostic pop -#endif -} // namespace std - -#define GTEST_MESSAGE_AT_(file, line, message, result_type) \ - ::testing::internal::AssertHelper(result_type, file, line, message) = \ - ::testing::Message() - -#define GTEST_MESSAGE_(message, result_type) \ - GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) - -#define GTEST_FATAL_FAILURE_(message) \ - return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) - -#define GTEST_NONFATAL_FAILURE_(message) \ - GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) - -#define GTEST_SUCCESS_(message) \ - GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) - -#define GTEST_SKIP_(message) \ - return GTEST_MESSAGE_(message, ::testing::TestPartResult::kSkip) - -// Suppress MSVC warning 4072 (unreachable code) for the code following -// statement if it returns or throws (or doesn't return or throw in some -// situations). -// NOTE: The "else" is important to keep this expansion to prevent a top-level -// "else" from attaching to our "if". -#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ - if (::testing::internal::AlwaysTrue()) { \ - statement; \ - } else /* NOLINT */ \ - static_assert(true, "") // User must have a semicolon after expansion. - -#if GTEST_HAS_EXCEPTIONS - -namespace testing { -namespace internal { - -class NeverThrown { - public: - const char* what() const noexcept { - return "this exception should never be thrown"; - } -}; - -} // namespace internal -} // namespace testing - -#if GTEST_HAS_RTTI - -#define GTEST_EXCEPTION_TYPE_(e) ::testing::internal::GetTypeName(typeid(e)) - -#else // GTEST_HAS_RTTI - -#define GTEST_EXCEPTION_TYPE_(e) \ - std::string { "an std::exception-derived error" } - -#endif // GTEST_HAS_RTTI - -#define GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception) \ - catch (typename std::conditional< \ - std::is_same::type>::type, \ - std::exception>::value, \ - const ::testing::internal::NeverThrown&, const std::exception&>::type \ - e) { \ - gtest_msg.value = "Expected: " #statement \ - " throws an exception of type " #expected_exception \ - ".\n Actual: it throws "; \ - gtest_msg.value += GTEST_EXCEPTION_TYPE_(e); \ - gtest_msg.value += " with description \""; \ - gtest_msg.value += e.what(); \ - gtest_msg.value += "\"."; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } - -#else // GTEST_HAS_EXCEPTIONS - -#define GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception) - -#endif // GTEST_HAS_EXCEPTIONS - -#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::TrueWithString gtest_msg{}) { \ - bool gtest_caught_expected = false; \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } catch (expected_exception const&) { \ - gtest_caught_expected = true; \ - } \ - GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception) \ - catch (...) { \ - gtest_msg.value = "Expected: " #statement \ - " throws an exception of type " #expected_exception \ - ".\n Actual: it throws a different type."; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - if (!gtest_caught_expected) { \ - gtest_msg.value = "Expected: " #statement \ - " throws an exception of type " #expected_exception \ - ".\n Actual: it throws nothing."; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - } else /*NOLINT*/ \ - GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__) \ - : fail(gtest_msg.value.c_str()) - -#if GTEST_HAS_EXCEPTIONS - -#define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() \ - catch (std::exception const& e) { \ - gtest_msg.value = "it throws "; \ - gtest_msg.value += GTEST_EXCEPTION_TYPE_(e); \ - gtest_msg.value += " with description \""; \ - gtest_msg.value += e.what(); \ - gtest_msg.value += "\"."; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ - } - -#else // GTEST_HAS_EXCEPTIONS - -#define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() - -#endif // GTEST_HAS_EXCEPTIONS - -#define GTEST_TEST_NO_THROW_(statement, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::TrueWithString gtest_msg{}) { \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } \ - GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() \ - catch (...) { \ - gtest_msg.value = "it throws."; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__) \ - : fail(("Expected: " #statement " doesn't throw an exception.\n" \ - " Actual: " + \ - gtest_msg.value) \ - .c_str()) - -#define GTEST_TEST_ANY_THROW_(statement, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - bool gtest_caught_any = false; \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } catch (...) { \ - gtest_caught_any = true; \ - } \ - if (!gtest_caught_any) { \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__) \ - : fail("Expected: " #statement \ - " throws an exception.\n" \ - " Actual: it doesn't.") - -// Implements Boolean test assertions such as EXPECT_TRUE. expression can be -// either a boolean expression or an AssertionResult. text is a textual -// representation of expression as it was passed into the EXPECT_TRUE. -#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (const ::testing::AssertionResult gtest_ar_ = \ - ::testing::AssertionResult(expression)) \ - ; \ - else \ - fail(::testing::internal::GetBoolAssertionFailureMessage( \ - gtest_ar_, text, #actual, #expected) \ - .c_str()) - -#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__) \ - : fail("Expected: " #statement \ - " doesn't generate new fatal " \ - "failures in the current thread.\n" \ - " Actual: it does.") - -// Expands to the name of the class that implements the given test. -#define GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ - test_suite_name##_##test_name##_Test - -// Helper macro for defining tests. -#define GTEST_TEST_(test_suite_name, test_name, parent_class, parent_id) \ - static_assert(sizeof(GTEST_STRINGIFY_(test_suite_name)) > 1, \ - "test_suite_name must not be empty"); \ - static_assert(sizeof(GTEST_STRINGIFY_(test_name)) > 1, \ - "test_name must not be empty"); \ - class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ - : public parent_class { \ - public: \ - GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() = default; \ - ~GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() override = default; \ - GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ - (const GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &) = delete; \ - GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \ - const GTEST_TEST_CLASS_NAME_(test_suite_name, \ - test_name) &) = delete; /* NOLINT */ \ - GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ - (GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &&) noexcept = delete; \ - GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \ - GTEST_TEST_CLASS_NAME_(test_suite_name, \ - test_name) &&) noexcept = delete; /* NOLINT */ \ - \ - private: \ - void TestBody() override; \ - static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \ - }; \ - \ - ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \ - test_name)::test_info_ = \ - ::testing::internal::MakeAndRegisterTestInfo( \ - #test_suite_name, #test_name, nullptr, nullptr, \ - ::testing::internal::CodeLocation(__FILE__, __LINE__), (parent_id), \ - ::testing::internal::SuiteApiResolver< \ - parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__), \ - ::testing::internal::SuiteApiResolver< \ - parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__), \ - new ::testing::internal::TestFactoryImpl); \ - void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody() - -#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-param-util.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-param-util.h deleted file mode 100644 index e7af2f90..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-param-util.h +++ /dev/null @@ -1,956 +0,0 @@ -// Copyright 2008 Google Inc. -// All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Type and function utilities for implementing parameterized tests. - -// IWYU pragma: private, include "gtest/gtest.h" -// IWYU pragma: friend gtest/.* -// IWYU pragma: friend gmock/.* - -#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ -#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gtest/gtest-printers.h" -#include "gtest/gtest-test-part.h" -#include "gtest/internal/gtest-internal.h" -#include "gtest/internal/gtest-port.h" - -namespace testing { -// Input to a parameterized test name generator, describing a test parameter. -// Consists of the parameter value and the integer parameter index. -template -struct TestParamInfo { - TestParamInfo(const ParamType& a_param, size_t an_index) - : param(a_param), index(an_index) {} - ParamType param; - size_t index; -}; - -// A builtin parameterized test name generator which returns the result of -// testing::PrintToString. -struct PrintToStringParamName { - template - std::string operator()(const TestParamInfo& info) const { - return PrintToString(info.param); - } -}; - -namespace internal { - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// Utility Functions - -// Outputs a message explaining invalid registration of different -// fixture class for the same test suite. This may happen when -// TEST_P macro is used to define two tests with the same name -// but in different namespaces. -GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name, - CodeLocation code_location); - -template -class ParamGeneratorInterface; -template -class ParamGenerator; - -// Interface for iterating over elements provided by an implementation -// of ParamGeneratorInterface. -template -class ParamIteratorInterface { - public: - virtual ~ParamIteratorInterface() {} - // A pointer to the base generator instance. - // Used only for the purposes of iterator comparison - // to make sure that two iterators belong to the same generator. - virtual const ParamGeneratorInterface* BaseGenerator() const = 0; - // Advances iterator to point to the next element - // provided by the generator. The caller is responsible - // for not calling Advance() on an iterator equal to - // BaseGenerator()->End(). - virtual void Advance() = 0; - // Clones the iterator object. Used for implementing copy semantics - // of ParamIterator. - virtual ParamIteratorInterface* Clone() const = 0; - // Dereferences the current iterator and provides (read-only) access - // to the pointed value. It is the caller's responsibility not to call - // Current() on an iterator equal to BaseGenerator()->End(). - // Used for implementing ParamGenerator::operator*(). - virtual const T* Current() const = 0; - // Determines whether the given iterator and other point to the same - // element in the sequence generated by the generator. - // Used for implementing ParamGenerator::operator==(). - virtual bool Equals(const ParamIteratorInterface& other) const = 0; -}; - -// Class iterating over elements provided by an implementation of -// ParamGeneratorInterface. It wraps ParamIteratorInterface -// and implements the const forward iterator concept. -template -class ParamIterator { - public: - typedef T value_type; - typedef const T& reference; - typedef ptrdiff_t difference_type; - - // ParamIterator assumes ownership of the impl_ pointer. - ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} - ParamIterator& operator=(const ParamIterator& other) { - if (this != &other) impl_.reset(other.impl_->Clone()); - return *this; - } - - const T& operator*() const { return *impl_->Current(); } - const T* operator->() const { return impl_->Current(); } - // Prefix version of operator++. - ParamIterator& operator++() { - impl_->Advance(); - return *this; - } - // Postfix version of operator++. - ParamIterator operator++(int /*unused*/) { - ParamIteratorInterface* clone = impl_->Clone(); - impl_->Advance(); - return ParamIterator(clone); - } - bool operator==(const ParamIterator& other) const { - return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); - } - bool operator!=(const ParamIterator& other) const { - return !(*this == other); - } - - private: - friend class ParamGenerator; - explicit ParamIterator(ParamIteratorInterface* impl) : impl_(impl) {} - std::unique_ptr> impl_; -}; - -// ParamGeneratorInterface is the binary interface to access generators -// defined in other translation units. -template -class ParamGeneratorInterface { - public: - typedef T ParamType; - - virtual ~ParamGeneratorInterface() {} - - // Generator interface definition - virtual ParamIteratorInterface* Begin() const = 0; - virtual ParamIteratorInterface* End() const = 0; -}; - -// Wraps ParamGeneratorInterface and provides general generator syntax -// compatible with the STL Container concept. -// This class implements copy initialization semantics and the contained -// ParamGeneratorInterface instance is shared among all copies -// of the original object. This is possible because that instance is immutable. -template -class ParamGenerator { - public: - typedef ParamIterator iterator; - - explicit ParamGenerator(ParamGeneratorInterface* impl) : impl_(impl) {} - ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} - - ParamGenerator& operator=(const ParamGenerator& other) { - impl_ = other.impl_; - return *this; - } - - iterator begin() const { return iterator(impl_->Begin()); } - iterator end() const { return iterator(impl_->End()); } - - private: - std::shared_ptr> impl_; -}; - -// Generates values from a range of two comparable values. Can be used to -// generate sequences of user-defined types that implement operator+() and -// operator<(). -// This class is used in the Range() function. -template -class RangeGenerator : public ParamGeneratorInterface { - public: - RangeGenerator(T begin, T end, IncrementT step) - : begin_(begin), - end_(end), - step_(step), - end_index_(CalculateEndIndex(begin, end, step)) {} - ~RangeGenerator() override {} - - ParamIteratorInterface* Begin() const override { - return new Iterator(this, begin_, 0, step_); - } - ParamIteratorInterface* End() const override { - return new Iterator(this, end_, end_index_, step_); - } - - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, T value, int index, - IncrementT step) - : base_(base), value_(value), index_(index), step_(step) {} - ~Iterator() override {} - - const ParamGeneratorInterface* BaseGenerator() const override { - return base_; - } - void Advance() override { - value_ = static_cast(value_ + step_); - index_++; - } - ParamIteratorInterface* Clone() const override { - return new Iterator(*this); - } - const T* Current() const override { return &value_; } - bool Equals(const ParamIteratorInterface& other) const override { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const int other_index = - CheckedDowncastToActualType(&other)->index_; - return index_ == other_index; - } - - private: - Iterator(const Iterator& other) - : ParamIteratorInterface(), - base_(other.base_), - value_(other.value_), - index_(other.index_), - step_(other.step_) {} - - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); - - const ParamGeneratorInterface* const base_; - T value_; - int index_; - const IncrementT step_; - }; // class RangeGenerator::Iterator - - static int CalculateEndIndex(const T& begin, const T& end, - const IncrementT& step) { - int end_index = 0; - for (T i = begin; i < end; i = static_cast(i + step)) end_index++; - return end_index; - } - - // No implementation - assignment is unsupported. - void operator=(const RangeGenerator& other); - - const T begin_; - const T end_; - const IncrementT step_; - // The index for the end() iterator. All the elements in the generated - // sequence are indexed (0-based) to aid iterator comparison. - const int end_index_; -}; // class RangeGenerator - -// Generates values from a pair of STL-style iterators. Used in the -// ValuesIn() function. The elements are copied from the source range -// since the source can be located on the stack, and the generator -// is likely to persist beyond that stack frame. -template -class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { - public: - template - ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) - : container_(begin, end) {} - ~ValuesInIteratorRangeGenerator() override {} - - ParamIteratorInterface* Begin() const override { - return new Iterator(this, container_.begin()); - } - ParamIteratorInterface* End() const override { - return new Iterator(this, container_.end()); - } - - private: - typedef typename ::std::vector ContainerType; - - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - typename ContainerType::const_iterator iterator) - : base_(base), iterator_(iterator) {} - ~Iterator() override {} - - const ParamGeneratorInterface* BaseGenerator() const override { - return base_; - } - void Advance() override { - ++iterator_; - value_.reset(); - } - ParamIteratorInterface* Clone() const override { - return new Iterator(*this); - } - // We need to use cached value referenced by iterator_ because *iterator_ - // can return a temporary object (and of type other then T), so just - // having "return &*iterator_;" doesn't work. - // value_ is updated here and not in Advance() because Advance() - // can advance iterator_ beyond the end of the range, and we cannot - // detect that fact. The client code, on the other hand, is - // responsible for not calling Current() on an out-of-range iterator. - const T* Current() const override { - if (value_.get() == nullptr) value_.reset(new T(*iterator_)); - return value_.get(); - } - bool Equals(const ParamIteratorInterface& other) const override { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - return iterator_ == - CheckedDowncastToActualType(&other)->iterator_; - } - - private: - Iterator(const Iterator& other) - // The explicit constructor call suppresses a false warning - // emitted by gcc when supplied with the -Wextra option. - : ParamIteratorInterface(), - base_(other.base_), - iterator_(other.iterator_) {} - - const ParamGeneratorInterface* const base_; - typename ContainerType::const_iterator iterator_; - // A cached value of *iterator_. We keep it here to allow access by - // pointer in the wrapping iterator's operator->(). - // value_ needs to be mutable to be accessed in Current(). - // Use of std::unique_ptr helps manage cached value's lifetime, - // which is bound by the lifespan of the iterator itself. - mutable std::unique_ptr value_; - }; // class ValuesInIteratorRangeGenerator::Iterator - - // No implementation - assignment is unsupported. - void operator=(const ValuesInIteratorRangeGenerator& other); - - const ContainerType container_; -}; // class ValuesInIteratorRangeGenerator - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// Default parameterized test name generator, returns a string containing the -// integer test parameter index. -template -std::string DefaultParamName(const TestParamInfo& info) { - Message name_stream; - name_stream << info.index; - return name_stream.GetString(); -} - -template -void TestNotEmpty() { - static_assert(sizeof(T) == 0, "Empty arguments are not allowed."); -} -template -void TestNotEmpty(const T&) {} - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// Stores a parameter value and later creates tests parameterized with that -// value. -template -class ParameterizedTestFactory : public TestFactoryBase { - public: - typedef typename TestClass::ParamType ParamType; - explicit ParameterizedTestFactory(ParamType parameter) - : parameter_(parameter) {} - Test* CreateTest() override { - TestClass::SetParam(¶meter_); - return new TestClass(); - } - - private: - const ParamType parameter_; - - ParameterizedTestFactory(const ParameterizedTestFactory&) = delete; - ParameterizedTestFactory& operator=(const ParameterizedTestFactory&) = delete; -}; - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// TestMetaFactoryBase is a base class for meta-factories that create -// test factories for passing into MakeAndRegisterTestInfo function. -template -class TestMetaFactoryBase { - public: - virtual ~TestMetaFactoryBase() {} - - virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; -}; - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// TestMetaFactory creates test factories for passing into -// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives -// ownership of test factory pointer, same factory object cannot be passed -// into that method twice. But ParameterizedTestSuiteInfo is going to call -// it for each Test/Parameter value combination. Thus it needs meta factory -// creator class. -template -class TestMetaFactory - : public TestMetaFactoryBase { - public: - using ParamType = typename TestSuite::ParamType; - - TestMetaFactory() {} - - TestFactoryBase* CreateTestFactory(ParamType parameter) override { - return new ParameterizedTestFactory(parameter); - } - - private: - TestMetaFactory(const TestMetaFactory&) = delete; - TestMetaFactory& operator=(const TestMetaFactory&) = delete; -}; - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// ParameterizedTestSuiteInfoBase is a generic interface -// to ParameterizedTestSuiteInfo classes. ParameterizedTestSuiteInfoBase -// accumulates test information provided by TEST_P macro invocations -// and generators provided by INSTANTIATE_TEST_SUITE_P macro invocations -// and uses that information to register all resulting test instances -// in RegisterTests method. The ParameterizeTestSuiteRegistry class holds -// a collection of pointers to the ParameterizedTestSuiteInfo objects -// and calls RegisterTests() on each of them when asked. -class ParameterizedTestSuiteInfoBase { - public: - virtual ~ParameterizedTestSuiteInfoBase() {} - - // Base part of test suite name for display purposes. - virtual const std::string& GetTestSuiteName() const = 0; - // Test suite id to verify identity. - virtual TypeId GetTestSuiteTypeId() const = 0; - // UnitTest class invokes this method to register tests in this - // test suite right before running them in RUN_ALL_TESTS macro. - // This method should not be called more than once on any single - // instance of a ParameterizedTestSuiteInfoBase derived class. - virtual void RegisterTests() = 0; - - protected: - ParameterizedTestSuiteInfoBase() {} - - private: - ParameterizedTestSuiteInfoBase(const ParameterizedTestSuiteInfoBase&) = - delete; - ParameterizedTestSuiteInfoBase& operator=( - const ParameterizedTestSuiteInfoBase&) = delete; -}; - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// Report a the name of a test_suit as safe to ignore -// as the side effect of construction of this type. -struct GTEST_API_ MarkAsIgnored { - explicit MarkAsIgnored(const char* test_suite); -}; - -GTEST_API_ void InsertSyntheticTestCase(const std::string& name, - CodeLocation location, bool has_test_p); - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P -// macro invocations for a particular test suite and generators -// obtained from INSTANTIATE_TEST_SUITE_P macro invocations for that -// test suite. It registers tests with all values generated by all -// generators when asked. -template -class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { - public: - // ParamType and GeneratorCreationFunc are private types but are required - // for declarations of public methods AddTestPattern() and - // AddTestSuiteInstantiation(). - using ParamType = typename TestSuite::ParamType; - // A function that returns an instance of appropriate generator type. - typedef ParamGenerator(GeneratorCreationFunc)(); - using ParamNameGeneratorFunc = std::string(const TestParamInfo&); - - explicit ParameterizedTestSuiteInfo(const char* name, - CodeLocation code_location) - : test_suite_name_(name), code_location_(code_location) {} - - // Test suite base name for display purposes. - const std::string& GetTestSuiteName() const override { - return test_suite_name_; - } - // Test suite id to verify identity. - TypeId GetTestSuiteTypeId() const override { return GetTypeId(); } - // TEST_P macro uses AddTestPattern() to record information - // about a single test in a LocalTestInfo structure. - // test_suite_name is the base name of the test suite (without invocation - // prefix). test_base_name is the name of an individual test without - // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is - // test suite base name and DoBar is test base name. - void AddTestPattern(const char* test_suite_name, const char* test_base_name, - TestMetaFactoryBase* meta_factory, - CodeLocation code_location) { - tests_.push_back(std::shared_ptr(new TestInfo( - test_suite_name, test_base_name, meta_factory, code_location))); - } - // INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information - // about a generator. - int AddTestSuiteInstantiation(const std::string& instantiation_name, - GeneratorCreationFunc* func, - ParamNameGeneratorFunc* name_func, - const char* file, int line) { - instantiations_.push_back( - InstantiationInfo(instantiation_name, func, name_func, file, line)); - return 0; // Return value used only to run this method in namespace scope. - } - // UnitTest class invokes this method to register tests in this test suite - // right before running tests in RUN_ALL_TESTS macro. - // This method should not be called more than once on any single - // instance of a ParameterizedTestSuiteInfoBase derived class. - // UnitTest has a guard to prevent from calling this method more than once. - void RegisterTests() override { - bool generated_instantiations = false; - - for (typename TestInfoContainer::iterator test_it = tests_.begin(); - test_it != tests_.end(); ++test_it) { - std::shared_ptr test_info = *test_it; - for (typename InstantiationContainer::iterator gen_it = - instantiations_.begin(); - gen_it != instantiations_.end(); ++gen_it) { - const std::string& instantiation_name = gen_it->name; - ParamGenerator generator((*gen_it->generator)()); - ParamNameGeneratorFunc* name_func = gen_it->name_func; - const char* file = gen_it->file; - int line = gen_it->line; - - std::string test_suite_name; - if (!instantiation_name.empty()) - test_suite_name = instantiation_name + "/"; - test_suite_name += test_info->test_suite_base_name; - - size_t i = 0; - std::set test_param_names; - for (typename ParamGenerator::iterator param_it = - generator.begin(); - param_it != generator.end(); ++param_it, ++i) { - generated_instantiations = true; - - Message test_name_stream; - - std::string param_name = - name_func(TestParamInfo(*param_it, i)); - - GTEST_CHECK_(IsValidParamName(param_name)) - << "Parameterized test name '" << param_name - << "' is invalid, in " << file << " line " << line << std::endl; - - GTEST_CHECK_(test_param_names.count(param_name) == 0) - << "Duplicate parameterized test name '" << param_name << "', in " - << file << " line " << line << std::endl; - - test_param_names.insert(param_name); - - if (!test_info->test_base_name.empty()) { - test_name_stream << test_info->test_base_name << "/"; - } - test_name_stream << param_name; - MakeAndRegisterTestInfo( - test_suite_name.c_str(), test_name_stream.GetString().c_str(), - nullptr, // No type parameter. - PrintToString(*param_it).c_str(), test_info->code_location, - GetTestSuiteTypeId(), - SuiteApiResolver::GetSetUpCaseOrSuite(file, line), - SuiteApiResolver::GetTearDownCaseOrSuite(file, line), - test_info->test_meta_factory->CreateTestFactory(*param_it)); - } // for param_it - } // for gen_it - } // for test_it - - if (!generated_instantiations) { - // There are no generaotrs, or they all generate nothing ... - InsertSyntheticTestCase(GetTestSuiteName(), code_location_, - !tests_.empty()); - } - } // RegisterTests - - private: - // LocalTestInfo structure keeps information about a single test registered - // with TEST_P macro. - struct TestInfo { - TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name, - TestMetaFactoryBase* a_test_meta_factory, - CodeLocation a_code_location) - : test_suite_base_name(a_test_suite_base_name), - test_base_name(a_test_base_name), - test_meta_factory(a_test_meta_factory), - code_location(a_code_location) {} - - const std::string test_suite_base_name; - const std::string test_base_name; - const std::unique_ptr> test_meta_factory; - const CodeLocation code_location; - }; - using TestInfoContainer = ::std::vector>; - // Records data received from INSTANTIATE_TEST_SUITE_P macros: - // - struct InstantiationInfo { - InstantiationInfo(const std::string& name_in, - GeneratorCreationFunc* generator_in, - ParamNameGeneratorFunc* name_func_in, const char* file_in, - int line_in) - : name(name_in), - generator(generator_in), - name_func(name_func_in), - file(file_in), - line(line_in) {} - - std::string name; - GeneratorCreationFunc* generator; - ParamNameGeneratorFunc* name_func; - const char* file; - int line; - }; - typedef ::std::vector InstantiationContainer; - - static bool IsValidParamName(const std::string& name) { - // Check for empty string - if (name.empty()) return false; - - // Check for invalid characters - for (std::string::size_type index = 0; index < name.size(); ++index) { - if (!IsAlNum(name[index]) && name[index] != '_') return false; - } - - return true; - } - - const std::string test_suite_name_; - CodeLocation code_location_; - TestInfoContainer tests_; - InstantiationContainer instantiations_; - - ParameterizedTestSuiteInfo(const ParameterizedTestSuiteInfo&) = delete; - ParameterizedTestSuiteInfo& operator=(const ParameterizedTestSuiteInfo&) = - delete; -}; // class ParameterizedTestSuiteInfo - -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -template -using ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo; -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// ParameterizedTestSuiteRegistry contains a map of -// ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P -// and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding -// ParameterizedTestSuiteInfo descriptors. -class ParameterizedTestSuiteRegistry { - public: - ParameterizedTestSuiteRegistry() {} - ~ParameterizedTestSuiteRegistry() { - for (auto& test_suite_info : test_suite_infos_) { - delete test_suite_info; - } - } - - // Looks up or creates and returns a structure containing information about - // tests and instantiations of a particular test suite. - template - ParameterizedTestSuiteInfo* GetTestSuitePatternHolder( - const char* test_suite_name, CodeLocation code_location) { - ParameterizedTestSuiteInfo* typed_test_info = nullptr; - for (auto& test_suite_info : test_suite_infos_) { - if (test_suite_info->GetTestSuiteName() == test_suite_name) { - if (test_suite_info->GetTestSuiteTypeId() != GetTypeId()) { - // Complain about incorrect usage of Google Test facilities - // and terminate the program since we cannot guaranty correct - // test suite setup and tear-down in this case. - ReportInvalidTestSuiteType(test_suite_name, code_location); - posix::Abort(); - } else { - // At this point we are sure that the object we found is of the same - // type we are looking for, so we downcast it to that type - // without further checks. - typed_test_info = CheckedDowncastToActualType< - ParameterizedTestSuiteInfo>(test_suite_info); - } - break; - } - } - if (typed_test_info == nullptr) { - typed_test_info = new ParameterizedTestSuiteInfo( - test_suite_name, code_location); - test_suite_infos_.push_back(typed_test_info); - } - return typed_test_info; - } - void RegisterTests() { - for (auto& test_suite_info : test_suite_infos_) { - test_suite_info->RegisterTests(); - } - } -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - template - ParameterizedTestCaseInfo* GetTestCasePatternHolder( - const char* test_case_name, CodeLocation code_location) { - return GetTestSuitePatternHolder(test_case_name, code_location); - } - -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - - private: - using TestSuiteInfoContainer = ::std::vector; - - TestSuiteInfoContainer test_suite_infos_; - - ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) = - delete; - ParameterizedTestSuiteRegistry& operator=( - const ParameterizedTestSuiteRegistry&) = delete; -}; - -// Keep track of what type-parameterized test suite are defined and -// where as well as which are intatiated. This allows susequently -// identifying suits that are defined but never used. -class TypeParameterizedTestSuiteRegistry { - public: - // Add a suite definition - void RegisterTestSuite(const char* test_suite_name, - CodeLocation code_location); - - // Add an instantiation of a suit. - void RegisterInstantiation(const char* test_suite_name); - - // For each suit repored as defined but not reported as instantiation, - // emit a test that reports that fact (configurably, as an error). - void CheckForInstantiations(); - - private: - struct TypeParameterizedTestSuiteInfo { - explicit TypeParameterizedTestSuiteInfo(CodeLocation c) - : code_location(c), instantiated(false) {} - - CodeLocation code_location; - bool instantiated; - }; - - std::map suites_; -}; - -} // namespace internal - -// Forward declarations of ValuesIn(), which is implemented in -// include/gtest/gtest-param-test.h. -template -internal::ParamGenerator ValuesIn( - const Container& container); - -namespace internal { -// Used in the Values() function to provide polymorphic capabilities. - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4100) -#endif - -template -class ValueArray { - public: - explicit ValueArray(Ts... v) : v_(FlatTupleConstructTag{}, std::move(v)...) {} - - template - operator ParamGenerator() const { // NOLINT - return ValuesIn(MakeVector(MakeIndexSequence())); - } - - private: - template - std::vector MakeVector(IndexSequence) const { - return std::vector{static_cast(v_.template Get())...}; - } - - FlatTuple v_; -}; - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -template -class CartesianProductGenerator - : public ParamGeneratorInterface<::std::tuple> { - public: - typedef ::std::tuple ParamType; - - CartesianProductGenerator(const std::tuple...>& g) - : generators_(g) {} - ~CartesianProductGenerator() override {} - - ParamIteratorInterface* Begin() const override { - return new Iterator(this, generators_, false); - } - ParamIteratorInterface* End() const override { - return new Iterator(this, generators_, true); - } - - private: - template - class IteratorImpl; - template - class IteratorImpl> - : public ParamIteratorInterface { - public: - IteratorImpl(const ParamGeneratorInterface* base, - const std::tuple...>& generators, - bool is_end) - : base_(base), - begin_(std::get(generators).begin()...), - end_(std::get(generators).end()...), - current_(is_end ? end_ : begin_) { - ComputeCurrentValue(); - } - ~IteratorImpl() override {} - - const ParamGeneratorInterface* BaseGenerator() const override { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - void Advance() override { - assert(!AtEnd()); - // Advance the last iterator. - ++std::get(current_); - // if that reaches end, propagate that up. - AdvanceIfEnd(); - ComputeCurrentValue(); - } - ParamIteratorInterface* Clone() const override { - return new IteratorImpl(*this); - } - - const ParamType* Current() const override { return current_value_.get(); } - - bool Equals(const ParamIteratorInterface& other) const override { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const IteratorImpl* typed_other = - CheckedDowncastToActualType(&other); - - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - if (AtEnd() && typed_other->AtEnd()) return true; - - bool same = true; - bool dummy[] = { - (same = same && std::get(current_) == - std::get(typed_other->current_))...}; - (void)dummy; - return same; - } - - private: - template - void AdvanceIfEnd() { - if (std::get(current_) != std::get(end_)) return; - - bool last = ThisI == 0; - if (last) { - // We are done. Nothing else to propagate. - return; - } - - constexpr size_t NextI = ThisI - (ThisI != 0); - std::get(current_) = std::get(begin_); - ++std::get(current_); - AdvanceIfEnd(); - } - - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = std::make_shared(*std::get(current_)...); - } - bool AtEnd() const { - bool at_end = false; - bool dummy[] = { - (at_end = at_end || std::get(current_) == std::get(end_))...}; - (void)dummy; - return at_end; - } - - const ParamGeneratorInterface* const base_; - std::tuple::iterator...> begin_; - std::tuple::iterator...> end_; - std::tuple::iterator...> current_; - std::shared_ptr current_value_; - }; - - using Iterator = IteratorImpl::type>; - - std::tuple...> generators_; -}; - -template -class CartesianProductHolder { - public: - CartesianProductHolder(const Gen&... g) : generators_(g...) {} - template - operator ParamGenerator<::std::tuple>() const { - return ParamGenerator<::std::tuple>( - new CartesianProductGenerator(generators_)); - } - - private: - std::tuple generators_; -}; - -} // namespace internal -} // namespace testing - -#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-port-arch.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-port-arch.h deleted file mode 100644 index f025db76..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-port-arch.h +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2015, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The Google C++ Testing and Mocking Framework (Google Test) -// -// This header file defines the GTEST_OS_* macro. -// It is separate from gtest-port.h so that custom/gtest-port.h can include it. - -#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ -#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ - -// Determines the platform on which Google Test is compiled. -#ifdef __CYGWIN__ -#define GTEST_OS_CYGWIN 1 -#elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__) -#define GTEST_OS_WINDOWS_MINGW 1 -#define GTEST_OS_WINDOWS 1 -#elif defined _WIN32 -#define GTEST_OS_WINDOWS 1 -#ifdef _WIN32_WCE -#define GTEST_OS_WINDOWS_MOBILE 1 -#elif defined(WINAPI_FAMILY) -#include -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) -#define GTEST_OS_WINDOWS_DESKTOP 1 -#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) -#define GTEST_OS_WINDOWS_PHONE 1 -#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) -#define GTEST_OS_WINDOWS_RT 1 -#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE) -#define GTEST_OS_WINDOWS_PHONE 1 -#define GTEST_OS_WINDOWS_TV_TITLE 1 -#else -// WINAPI_FAMILY defined but no known partition matched. -// Default to desktop. -#define GTEST_OS_WINDOWS_DESKTOP 1 -#endif -#else -#define GTEST_OS_WINDOWS_DESKTOP 1 -#endif // _WIN32_WCE -#elif defined __OS2__ -#define GTEST_OS_OS2 1 -#elif defined __APPLE__ -#define GTEST_OS_MAC 1 -#include -#if TARGET_OS_IPHONE -#define GTEST_OS_IOS 1 -#endif -#elif defined __DragonFly__ -#define GTEST_OS_DRAGONFLY 1 -#elif defined __FreeBSD__ -#define GTEST_OS_FREEBSD 1 -#elif defined __Fuchsia__ -#define GTEST_OS_FUCHSIA 1 -#elif defined(__GNU__) -#define GTEST_OS_GNU_HURD 1 -#elif defined(__GLIBC__) && defined(__FreeBSD_kernel__) -#define GTEST_OS_GNU_KFREEBSD 1 -#elif defined __linux__ -#define GTEST_OS_LINUX 1 -#if defined __ANDROID__ -#define GTEST_OS_LINUX_ANDROID 1 -#endif -#elif defined __MVS__ -#define GTEST_OS_ZOS 1 -#elif defined(__sun) && defined(__SVR4) -#define GTEST_OS_SOLARIS 1 -#elif defined(_AIX) -#define GTEST_OS_AIX 1 -#elif defined(__hpux) -#define GTEST_OS_HPUX 1 -#elif defined __native_client__ -#define GTEST_OS_NACL 1 -#elif defined __NetBSD__ -#define GTEST_OS_NETBSD 1 -#elif defined __OpenBSD__ -#define GTEST_OS_OPENBSD 1 -#elif defined __QNX__ -#define GTEST_OS_QNX 1 -#elif defined(__HAIKU__) -#define GTEST_OS_HAIKU 1 -#elif defined ESP8266 -#define GTEST_OS_ESP8266 1 -#elif defined ESP32 -#define GTEST_OS_ESP32 1 -#elif defined(__XTENSA__) -#define GTEST_OS_XTENSA 1 -#endif // __CYGWIN__ - -#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-port.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-port.h deleted file mode 100644 index 0003d276..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-port.h +++ /dev/null @@ -1,2413 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Low-level types and utilities for porting Google Test to various -// platforms. All macros ending with _ and symbols defined in an -// internal namespace are subject to change without notice. Code -// outside Google Test MUST NOT USE THEM DIRECTLY. Macros that don't -// end with _ are part of Google Test's public API and can be used by -// code outside Google Test. -// -// This file is fundamental to Google Test. All other Google Test source -// files are expected to #include this. Therefore, it cannot #include -// any other Google Test header. - -// IWYU pragma: private, include "gtest/gtest.h" -// IWYU pragma: friend gtest/.* -// IWYU pragma: friend gmock/.* - -#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ -#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ - -// Environment-describing macros -// ----------------------------- -// -// Google Test can be used in many different environments. Macros in -// this section tell Google Test what kind of environment it is being -// used in, such that Google Test can provide environment-specific -// features and implementations. -// -// Google Test tries to automatically detect the properties of its -// environment, so users usually don't need to worry about these -// macros. However, the automatic detection is not perfect. -// Sometimes it's necessary for a user to define some of the following -// macros in the build script to override Google Test's decisions. -// -// If the user doesn't define a macro in the list, Google Test will -// provide a default definition. After this header is #included, all -// macros in this list will be defined to either 1 or 0. -// -// Notes to maintainers: -// - Each macro here is a user-tweakable knob; do not grow the list -// lightly. -// - Use #if to key off these macros. Don't use #ifdef or "#if -// defined(...)", which will not work as these macros are ALWAYS -// defined. -// -// GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2) -// is/isn't available. -// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions -// are enabled. -// GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular -// expressions are/aren't available. -// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that -// is/isn't available. -// GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't -// enabled. -// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that -// std::wstring does/doesn't work (Google Test can -// be used where std::wstring is unavailable). -// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the -// compiler supports Microsoft's "Structured -// Exception Handling". -// GTEST_HAS_STREAM_REDIRECTION -// - Define it to 1/0 to indicate whether the -// platform supports I/O stream redirection using -// dup() and dup2(). -// GTEST_LINKED_AS_SHARED_LIBRARY -// - Define to 1 when compiling tests that use -// Google Test as a shared library (known as -// DLL on Windows). -// GTEST_CREATE_SHARED_LIBRARY -// - Define to 1 when compiling Google Test itself -// as a shared library. -// GTEST_DEFAULT_DEATH_TEST_STYLE -// - The default value of --gtest_death_test_style. -// The legacy default has been "fast" in the open -// source version since 2008. The recommended value -// is "threadsafe", and can be set in -// custom/gtest-port.h. - -// Platform-indicating macros -// -------------------------- -// -// Macros indicating the platform on which Google Test is being used -// (a macro is defined to 1 if compiled on the given platform; -// otherwise UNDEFINED -- it's never defined to 0.). Google Test -// defines these macros automatically. Code outside Google Test MUST -// NOT define them. -// -// GTEST_OS_AIX - IBM AIX -// GTEST_OS_CYGWIN - Cygwin -// GTEST_OS_DRAGONFLY - DragonFlyBSD -// GTEST_OS_FREEBSD - FreeBSD -// GTEST_OS_FUCHSIA - Fuchsia -// GTEST_OS_GNU_HURD - GNU/Hurd -// GTEST_OS_GNU_KFREEBSD - GNU/kFreeBSD -// GTEST_OS_HAIKU - Haiku -// GTEST_OS_HPUX - HP-UX -// GTEST_OS_LINUX - Linux -// GTEST_OS_LINUX_ANDROID - Google Android -// GTEST_OS_MAC - Mac OS X -// GTEST_OS_IOS - iOS -// GTEST_OS_NACL - Google Native Client (NaCl) -// GTEST_OS_NETBSD - NetBSD -// GTEST_OS_OPENBSD - OpenBSD -// GTEST_OS_OS2 - OS/2 -// GTEST_OS_QNX - QNX -// GTEST_OS_SOLARIS - Sun Solaris -// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) -// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop -// GTEST_OS_WINDOWS_MINGW - MinGW -// GTEST_OS_WINDOWS_MOBILE - Windows Mobile -// GTEST_OS_WINDOWS_PHONE - Windows Phone -// GTEST_OS_WINDOWS_RT - Windows Store App/WinRT -// GTEST_OS_ZOS - z/OS -// -// Among the platforms, Cygwin, Linux, Mac OS X, and Windows have the -// most stable support. Since core members of the Google Test project -// don't have access to other platforms, support for them may be less -// stable. If you notice any problems on your platform, please notify -// googletestframework@googlegroups.com (patches for fixing them are -// even more welcome!). -// -// It is possible that none of the GTEST_OS_* macros are defined. - -// Feature-indicating macros -// ------------------------- -// -// Macros indicating which Google Test features are available (a macro -// is defined to 1 if the corresponding feature is supported; -// otherwise UNDEFINED -- it's never defined to 0.). Google Test -// defines these macros automatically. Code outside Google Test MUST -// NOT define them. -// -// These macros are public so that portable tests can be written. -// Such tests typically surround code using a feature with an #if -// which controls that code. For example: -// -// #if GTEST_HAS_DEATH_TEST -// EXPECT_DEATH(DoSomethingDeadly()); -// #endif -// -// GTEST_HAS_DEATH_TEST - death tests -// GTEST_HAS_TYPED_TEST - typed tests -// GTEST_HAS_TYPED_TEST_P - type-parameterized tests -// GTEST_IS_THREADSAFE - Google Test is thread-safe. -// GTEST_USES_RE2 - the RE2 regular expression library is used -// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with -// GTEST_HAS_POSIX_RE (see above) which users can -// define themselves. -// GTEST_USES_SIMPLE_RE - our own simple regex is used; -// the above RE\b(s) are mutually exclusive. - -// Misc public macros -// ------------------ -// -// GTEST_FLAG(flag_name) - references the variable corresponding to -// the given Google Test flag. - -// Internal utilities -// ------------------ -// -// The following macros and utilities are for Google Test's INTERNAL -// use only. Code outside Google Test MUST NOT USE THEM DIRECTLY. -// -// Macros for basic C++ coding: -// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. -// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a -// variable don't have to be used. -// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. -// GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is -// suppressed (constant conditional). -// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127 -// is suppressed. -// GTEST_INTERNAL_HAS_ANY - for enabling UniversalPrinter or -// UniversalPrinter specializations. -// GTEST_INTERNAL_HAS_OPTIONAL - for enabling UniversalPrinter -// or -// UniversalPrinter -// specializations. -// GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher or -// Matcher -// specializations. -// GTEST_INTERNAL_HAS_VARIANT - for enabling UniversalPrinter or -// UniversalPrinter -// specializations. -// -// Synchronization: -// Mutex, MutexLock, ThreadLocal, GetThreadCount() -// - synchronization primitives. -// -// Regular expressions: -// RE - a simple regular expression class using -// 1) the RE2 syntax on all platforms when built with RE2 -// and Abseil as dependencies -// 2) the POSIX Extended Regular Expression syntax on -// UNIX-like platforms, -// 3) A reduced regular exception syntax on other platforms, -// including Windows. -// Logging: -// GTEST_LOG_() - logs messages at the specified severity level. -// LogToStderr() - directs all log messages to stderr. -// FlushInfoLog() - flushes informational log messages. -// -// Stdout and stderr capturing: -// CaptureStdout() - starts capturing stdout. -// GetCapturedStdout() - stops capturing stdout and returns the captured -// string. -// CaptureStderr() - starts capturing stderr. -// GetCapturedStderr() - stops capturing stderr and returns the captured -// string. -// -// Integer types: -// TypeWithSize - maps an integer to a int type. -// TimeInMillis - integers of known sizes. -// BiggestInt - the biggest signed integer type. -// -// Command-line utilities: -// GetInjectableArgvs() - returns the command line as a vector of strings. -// -// Environment variable utilities: -// GetEnv() - gets the value of an environment variable. -// BoolFromGTestEnv() - parses a bool environment variable. -// Int32FromGTestEnv() - parses an int32_t environment variable. -// StringFromGTestEnv() - parses a string environment variable. -// -// Deprecation warnings: -// GTEST_INTERNAL_DEPRECATED(message) - attribute marking a function as -// deprecated; calling a marked function -// should generate a compiler warning - -#include // for isspace, etc -#include // for ptrdiff_t -#include -#include -#include - -#include -// #include // Guarded by GTEST_IS_THREADSAFE below -#include -#include -#include -#include -#include -#include -// #include // Guarded by GTEST_IS_THREADSAFE below -#include -#include -#include - -#ifndef _WIN32_WCE -#include -#include -#endif // !_WIN32_WCE - -#if defined __APPLE__ -#include -#include -#endif - -#include "gtest/internal/custom/gtest-port.h" -#include "gtest/internal/gtest-port-arch.h" - -#if GTEST_HAS_ABSL -#include "absl/flags/declare.h" -#include "absl/flags/flag.h" -#include "absl/flags/reflection.h" -#endif - -#if !defined(GTEST_DEV_EMAIL_) -#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" -#define GTEST_FLAG_PREFIX_ "gtest_" -#define GTEST_FLAG_PREFIX_DASH_ "gtest-" -#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" -#define GTEST_NAME_ "Google Test" -#define GTEST_PROJECT_URL_ "https://github.com/google/googletest/" -#endif // !defined(GTEST_DEV_EMAIL_) - -#if !defined(GTEST_INIT_GOOGLE_TEST_NAME_) -#define GTEST_INIT_GOOGLE_TEST_NAME_ "testing::InitGoogleTest" -#endif // !defined(GTEST_INIT_GOOGLE_TEST_NAME_) - -// Determines the version of gcc that is used to compile this. -#ifdef __GNUC__ -// 40302 means version 4.3.2. -#define GTEST_GCC_VER_ \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#endif // __GNUC__ - -// Macros for disabling Microsoft Visual C++ warnings. -// -// GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 4385) -// /* code that triggers warnings C4800 and C4385 */ -// GTEST_DISABLE_MSC_WARNINGS_POP_() -#if defined(_MSC_VER) -#define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) \ - __pragma(warning(push)) __pragma(warning(disable : warnings)) -#define GTEST_DISABLE_MSC_WARNINGS_POP_() __pragma(warning(pop)) -#else -// Not all compilers are MSVC -#define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) -#define GTEST_DISABLE_MSC_WARNINGS_POP_() -#endif - -// Clang on Windows does not understand MSVC's pragma warning. -// We need clang-specific way to disable function deprecation warning. -#ifdef __clang__ -#define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") \ - _Pragma("clang diagnostic ignored \"-Wdeprecated-implementations\"") -#define GTEST_DISABLE_MSC_DEPRECATED_POP_() _Pragma("clang diagnostic pop") -#else -#define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \ - GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) -#define GTEST_DISABLE_MSC_DEPRECATED_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_() -#endif - -// Brings in definitions for functions used in the testing::internal::posix -// namespace (read, write, close, chdir, isatty, stat). We do not currently -// use them on Windows Mobile. -#if GTEST_OS_WINDOWS -#if !GTEST_OS_WINDOWS_MOBILE -#include -#include -#endif -// In order to avoid having to include , use forward declaration -#if GTEST_OS_WINDOWS_MINGW && !defined(__MINGW64_VERSION_MAJOR) -// MinGW defined _CRITICAL_SECTION and _RTL_CRITICAL_SECTION as two -// separate (equivalent) structs, instead of using typedef -typedef struct _CRITICAL_SECTION GTEST_CRITICAL_SECTION; -#else -// Assume CRITICAL_SECTION is a typedef of _RTL_CRITICAL_SECTION. -// This assumption is verified by -// WindowsTypesTest.CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION. -typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; -#endif -#elif GTEST_OS_XTENSA -#include -// Xtensa toolchains define strcasecmp in the string.h header instead of -// strings.h. string.h is already included. -#else -// This assumes that non-Windows OSes provide unistd.h. For OSes where this -// is not the case, we need to include headers that provide the functions -// mentioned above. -#include -#include -#endif // GTEST_OS_WINDOWS - -#if GTEST_OS_LINUX_ANDROID -// Used to define __ANDROID_API__ matching the target NDK API level. -#include // NOLINT -#endif - -// Defines this to true if and only if Google Test can use POSIX regular -// expressions. -#ifndef GTEST_HAS_POSIX_RE -#if GTEST_OS_LINUX_ANDROID -// On Android, is only available starting with Gingerbread. -#define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) -#else -#define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS && !GTEST_OS_XTENSA) -#endif -#endif - -// Select the regular expression implementation. -#if GTEST_HAS_ABSL -// When using Abseil, RE2 is required. -#include "absl/strings/string_view.h" -#include "re2/re2.h" -#define GTEST_USES_RE2 1 -#elif GTEST_HAS_POSIX_RE -#include // NOLINT -#define GTEST_USES_POSIX_RE 1 -#else -// Use our own simple regex implementation. -#define GTEST_USES_SIMPLE_RE 1 -#endif - -#ifndef GTEST_HAS_EXCEPTIONS -// The user didn't tell us whether exceptions are enabled, so we need -// to figure it out. -#if defined(_MSC_VER) && defined(_CPPUNWIND) -// MSVC defines _CPPUNWIND to 1 if and only if exceptions are enabled. -#define GTEST_HAS_EXCEPTIONS 1 -#elif defined(__BORLANDC__) -// C++Builder's implementation of the STL uses the _HAS_EXCEPTIONS -// macro to enable exceptions, so we'll do the same. -// Assumes that exceptions are enabled by default. -#ifndef _HAS_EXCEPTIONS -#define _HAS_EXCEPTIONS 1 -#endif // _HAS_EXCEPTIONS -#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS -#elif defined(__clang__) -// clang defines __EXCEPTIONS if and only if exceptions are enabled before clang -// 220714, but if and only if cleanups are enabled after that. In Obj-C++ files, -// there can be cleanups for ObjC exceptions which also need cleanups, even if -// C++ exceptions are disabled. clang has __has_feature(cxx_exceptions) which -// checks for C++ exceptions starting at clang r206352, but which checked for -// cleanups prior to that. To reliably check for C++ exception availability with -// clang, check for -// __EXCEPTIONS && __has_feature(cxx_exceptions). -#define GTEST_HAS_EXCEPTIONS (__EXCEPTIONS && __has_feature(cxx_exceptions)) -#elif defined(__GNUC__) && __EXCEPTIONS -// gcc defines __EXCEPTIONS to 1 if and only if exceptions are enabled. -#define GTEST_HAS_EXCEPTIONS 1 -#elif defined(__SUNPRO_CC) -// Sun Pro CC supports exceptions. However, there is no compile-time way of -// detecting whether they are enabled or not. Therefore, we assume that -// they are enabled unless the user tells us otherwise. -#define GTEST_HAS_EXCEPTIONS 1 -#elif defined(__IBMCPP__) && __EXCEPTIONS -// xlC defines __EXCEPTIONS to 1 if and only if exceptions are enabled. -#define GTEST_HAS_EXCEPTIONS 1 -#elif defined(__HP_aCC) -// Exception handling is in effect by default in HP aCC compiler. It has to -// be turned of by +noeh compiler option if desired. -#define GTEST_HAS_EXCEPTIONS 1 -#else -// For other compilers, we assume exceptions are disabled to be -// conservative. -#define GTEST_HAS_EXCEPTIONS 0 -#endif // defined(_MSC_VER) || defined(__BORLANDC__) -#endif // GTEST_HAS_EXCEPTIONS - -#ifndef GTEST_HAS_STD_WSTRING -// The user didn't tell us whether ::std::wstring is available, so we need -// to figure it out. -// Cygwin 1.7 and below doesn't support ::std::wstring. -// Solaris' libc++ doesn't support it either. Android has -// no support for it at least as recent as Froyo (2.2). -#define GTEST_HAS_STD_WSTRING \ - (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ - GTEST_OS_HAIKU || GTEST_OS_ESP32 || GTEST_OS_ESP8266 || GTEST_OS_XTENSA)) - -#endif // GTEST_HAS_STD_WSTRING - -// Determines whether RTTI is available. -#ifndef GTEST_HAS_RTTI -// The user didn't tell us whether RTTI is enabled, so we need to -// figure it out. - -#ifdef _MSC_VER - -#ifdef _CPPRTTI // MSVC defines this macro if and only if RTTI is enabled. -#define GTEST_HAS_RTTI 1 -#else -#define GTEST_HAS_RTTI 0 -#endif - -// Starting with version 4.3.2, gcc defines __GXX_RTTI if and only if RTTI is -// enabled. -#elif defined(__GNUC__) - -#ifdef __GXX_RTTI -// When building against STLport with the Android NDK and with -// -frtti -fno-exceptions, the build fails at link time with undefined -// references to __cxa_bad_typeid. Note sure if STL or toolchain bug, -// so disable RTTI when detected. -#if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && !defined(__EXCEPTIONS) -#define GTEST_HAS_RTTI 0 -#else -#define GTEST_HAS_RTTI 1 -#endif // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS -#else -#define GTEST_HAS_RTTI 0 -#endif // __GXX_RTTI - -// Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends -// using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the -// first version with C++ support. -#elif defined(__clang__) - -#define GTEST_HAS_RTTI __has_feature(cxx_rtti) - -// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if -// both the typeid and dynamic_cast features are present. -#elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) - -#ifdef __RTTI_ALL__ -#define GTEST_HAS_RTTI 1 -#else -#define GTEST_HAS_RTTI 0 -#endif - -#else - -// For all other compilers, we assume RTTI is enabled. -#define GTEST_HAS_RTTI 1 - -#endif // _MSC_VER - -#endif // GTEST_HAS_RTTI - -// It's this header's responsibility to #include when RTTI -// is enabled. -#if GTEST_HAS_RTTI -#include -#endif - -// Determines whether Google Test can use the pthreads library. -#ifndef GTEST_HAS_PTHREAD -// The user didn't tell us explicitly, so we make reasonable assumptions about -// which platforms have pthreads support. -// -// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 -// to your compiler flags. -#define GTEST_HAS_PTHREAD \ - (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX || GTEST_OS_QNX || \ - GTEST_OS_FREEBSD || GTEST_OS_NACL || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \ - GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_OPENBSD || \ - GTEST_OS_HAIKU || GTEST_OS_GNU_HURD) -#endif // GTEST_HAS_PTHREAD - -#if GTEST_HAS_PTHREAD -// gtest-port.h guarantees to #include when GTEST_HAS_PTHREAD is -// true. -#include // NOLINT - -// For timespec and nanosleep, used below. -#include // NOLINT -#endif - -// Determines whether clone(2) is supported. -// Usually it will only be available on Linux, excluding -// Linux on the Itanium architecture. -// Also see http://linux.die.net/man/2/clone. -#ifndef GTEST_HAS_CLONE -// The user didn't tell us, so we need to figure it out. - -#if GTEST_OS_LINUX && !defined(__ia64__) -#if GTEST_OS_LINUX_ANDROID -// On Android, clone() became available at different API levels for each 32-bit -// architecture. -#if defined(__LP64__) || (defined(__arm__) && __ANDROID_API__ >= 9) || \ - (defined(__mips__) && __ANDROID_API__ >= 12) || \ - (defined(__i386__) && __ANDROID_API__ >= 17) -#define GTEST_HAS_CLONE 1 -#else -#define GTEST_HAS_CLONE 0 -#endif -#else -#define GTEST_HAS_CLONE 1 -#endif -#else -#define GTEST_HAS_CLONE 0 -#endif // GTEST_OS_LINUX && !defined(__ia64__) - -#endif // GTEST_HAS_CLONE - -// Determines whether to support stream redirection. This is used to test -// output correctness and to implement death tests. -#ifndef GTEST_HAS_STREAM_REDIRECTION -// By default, we assume that stream redirection is supported on all -// platforms except known mobile ones. -#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ - GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA -#define GTEST_HAS_STREAM_REDIRECTION 0 -#else -#define GTEST_HAS_STREAM_REDIRECTION 1 -#endif // !GTEST_OS_WINDOWS_MOBILE -#endif // GTEST_HAS_STREAM_REDIRECTION - -// Determines whether to support death tests. -// pops up a dialog window that cannot be suppressed programmatically. -#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ - (GTEST_OS_MAC && !GTEST_OS_IOS) || \ - (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER) || GTEST_OS_WINDOWS_MINGW || \ - GTEST_OS_AIX || GTEST_OS_HPUX || GTEST_OS_OPENBSD || GTEST_OS_QNX || \ - GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \ - GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_HAIKU || \ - GTEST_OS_GNU_HURD) -#define GTEST_HAS_DEATH_TEST 1 -#endif - -// Determines whether to support type-driven tests. - -// Typed tests need and variadic macros, which GCC, VC++ 8.0, -// Sun Pro CC, IBM Visual Age, and HP aCC support. -#if defined(__GNUC__) || defined(_MSC_VER) || defined(__SUNPRO_CC) || \ - defined(__IBMCPP__) || defined(__HP_aCC) -#define GTEST_HAS_TYPED_TEST 1 -#define GTEST_HAS_TYPED_TEST_P 1 -#endif - -// Determines whether the system compiler uses UTF-16 for encoding wide strings. -#define GTEST_WIDE_STRING_USES_UTF16_ \ - (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_AIX || GTEST_OS_OS2) - -// Determines whether test results can be streamed to a socket. -#if GTEST_OS_LINUX || GTEST_OS_GNU_KFREEBSD || GTEST_OS_DRAGONFLY || \ - GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_OPENBSD || \ - GTEST_OS_GNU_HURD -#define GTEST_CAN_STREAM_RESULTS_ 1 -#endif - -// Defines some utility macros. - -// The GNU compiler emits a warning if nested "if" statements are followed by -// an "else" statement and braces are not used to explicitly disambiguate the -// "else" binding. This leads to problems with code like: -// -// if (gate) -// ASSERT_*(condition) << "Some message"; -// -// The "switch (0) case 0:" idiom is used to suppress this. -#ifdef __INTEL_COMPILER -#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ -#else -#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - switch (0) \ - case 0: \ - default: // NOLINT -#endif - -// Use this annotation at the end of a struct/class definition to -// prevent the compiler from optimizing away instances that are never -// used. This is useful when all interesting logic happens inside the -// c'tor and / or d'tor. Example: -// -// struct Foo { -// Foo() { ... } -// } GTEST_ATTRIBUTE_UNUSED_; -// -// Also use it after a variable or parameter declaration to tell the -// compiler the variable/parameter does not have to be used. -#if defined(__GNUC__) && !defined(COMPILER_ICC) -#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused)) -#elif defined(__clang__) -#if __has_attribute(unused) -#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused)) -#endif -#endif -#ifndef GTEST_ATTRIBUTE_UNUSED_ -#define GTEST_ATTRIBUTE_UNUSED_ -#endif - -// Use this annotation before a function that takes a printf format string. -#if (defined(__GNUC__) || defined(__clang__)) && !defined(COMPILER_ICC) -#if defined(__MINGW_PRINTF_FORMAT) -// MinGW has two different printf implementations. Ensure the format macro -// matches the selected implementation. See -// https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/. -#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \ - __attribute__(( \ - __format__(__MINGW_PRINTF_FORMAT, string_index, first_to_check))) -#else -#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \ - __attribute__((__format__(__printf__, string_index, first_to_check))) -#endif -#else -#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) -#endif - -// Tell the compiler to warn about unused return values for functions declared -// with this macro. The macro should be used on function declarations -// following the argument list: -// -// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; -#if defined(__GNUC__) && !defined(COMPILER_ICC) -#define GTEST_MUST_USE_RESULT_ __attribute__((warn_unused_result)) -#else -#define GTEST_MUST_USE_RESULT_ -#endif // __GNUC__ && !COMPILER_ICC - -// MS C++ compiler emits warning when a conditional expression is compile time -// constant. In some contexts this warning is false positive and needs to be -// suppressed. Use the following two macros in such cases: -// -// GTEST_INTENTIONAL_CONST_COND_PUSH_() -// while (true) { -// GTEST_INTENTIONAL_CONST_COND_POP_() -// } -#define GTEST_INTENTIONAL_CONST_COND_PUSH_() \ - GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127) -#define GTEST_INTENTIONAL_CONST_COND_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_() - -// Determine whether the compiler supports Microsoft's Structured Exception -// Handling. This is supported by several Windows compilers but generally -// does not exist on any other system. -#ifndef GTEST_HAS_SEH -// The user didn't tell us, so we need to figure it out. - -#if defined(_MSC_VER) || defined(__BORLANDC__) -// These two compilers are known to support SEH. -#define GTEST_HAS_SEH 1 -#else -// Assume no SEH. -#define GTEST_HAS_SEH 0 -#endif - -#endif // GTEST_HAS_SEH - -#ifndef GTEST_IS_THREADSAFE - -#define GTEST_IS_THREADSAFE \ - (GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ || \ - (GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT) || \ - GTEST_HAS_PTHREAD) - -#endif // GTEST_IS_THREADSAFE - -#if GTEST_IS_THREADSAFE -// Some platforms don't support including these threading related headers. -#include // NOLINT -#include // NOLINT -#endif // GTEST_IS_THREADSAFE - -// GTEST_API_ qualifies all symbols that must be exported. The definitions below -// are guarded by #ifndef to give embedders a chance to define GTEST_API_ in -// gtest/internal/custom/gtest-port.h -#ifndef GTEST_API_ - -#ifdef _MSC_VER -#if GTEST_LINKED_AS_SHARED_LIBRARY -#define GTEST_API_ __declspec(dllimport) -#elif GTEST_CREATE_SHARED_LIBRARY -#define GTEST_API_ __declspec(dllexport) -#endif -#elif __GNUC__ >= 4 || defined(__clang__) -#define GTEST_API_ __attribute__((visibility("default"))) -#endif // _MSC_VER - -#endif // GTEST_API_ - -#ifndef GTEST_API_ -#define GTEST_API_ -#endif // GTEST_API_ - -#ifndef GTEST_DEFAULT_DEATH_TEST_STYLE -#define GTEST_DEFAULT_DEATH_TEST_STYLE "fast" -#endif // GTEST_DEFAULT_DEATH_TEST_STYLE - -#ifdef __GNUC__ -// Ask the compiler to never inline a given function. -#define GTEST_NO_INLINE_ __attribute__((noinline)) -#else -#define GTEST_NO_INLINE_ -#endif - -#if defined(__clang__) -// Nested ifs to avoid triggering MSVC warning. -#if __has_attribute(disable_tail_calls) -// Ask the compiler not to perform tail call optimization inside -// the marked function. -#define GTEST_NO_TAIL_CALL_ __attribute__((disable_tail_calls)) -#endif -#elif __GNUC__ -#define GTEST_NO_TAIL_CALL_ \ - __attribute__((optimize("no-optimize-sibling-calls"))) -#else -#define GTEST_NO_TAIL_CALL_ -#endif - -// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project. -#if !defined(GTEST_HAS_CXXABI_H_) -#if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER)) -#define GTEST_HAS_CXXABI_H_ 1 -#else -#define GTEST_HAS_CXXABI_H_ 0 -#endif -#endif - -// A function level attribute to disable checking for use of uninitialized -// memory when built with MemorySanitizer. -#if defined(__clang__) -#if __has_feature(memory_sanitizer) -#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ __attribute__((no_sanitize_memory)) -#else -#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ -#endif // __has_feature(memory_sanitizer) -#else -#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ -#endif // __clang__ - -// A function level attribute to disable AddressSanitizer instrumentation. -#if defined(__clang__) -#if __has_feature(address_sanitizer) -#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ \ - __attribute__((no_sanitize_address)) -#else -#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ -#endif // __has_feature(address_sanitizer) -#else -#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ -#endif // __clang__ - -// A function level attribute to disable HWAddressSanitizer instrumentation. -#if defined(__clang__) -#if __has_feature(hwaddress_sanitizer) -#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ \ - __attribute__((no_sanitize("hwaddress"))) -#else -#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ -#endif // __has_feature(hwaddress_sanitizer) -#else -#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ -#endif // __clang__ - -// A function level attribute to disable ThreadSanitizer instrumentation. -#if defined(__clang__) -#if __has_feature(thread_sanitizer) -#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ __attribute__((no_sanitize_thread)) -#else -#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ -#endif // __has_feature(thread_sanitizer) -#else -#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ -#endif // __clang__ - -namespace testing { - -class Message; - -// Legacy imports for backwards compatibility. -// New code should use std:: names directly. -using std::get; -using std::make_tuple; -using std::tuple; -using std::tuple_element; -using std::tuple_size; - -namespace internal { - -// A secret type that Google Test users don't know about. It has no -// definition on purpose. Therefore it's impossible to create a -// Secret object, which is what we want. -class Secret; - -// A helper for suppressing warnings on constant condition. It just -// returns 'condition'. -GTEST_API_ bool IsTrue(bool condition); - -// Defines RE. - -#if GTEST_USES_RE2 - -// This is almost `using RE = ::RE2`, except it is copy-constructible, and it -// needs to disambiguate the `std::string`, `absl::string_view`, and `const -// char*` constructors. -class GTEST_API_ RE { - public: - RE(absl::string_view regex) : regex_(regex) {} // NOLINT - RE(const char* regex) : RE(absl::string_view(regex)) {} // NOLINT - RE(const std::string& regex) : RE(absl::string_view(regex)) {} // NOLINT - RE(const RE& other) : RE(other.pattern()) {} - - const std::string& pattern() const { return regex_.pattern(); } - - static bool FullMatch(absl::string_view str, const RE& re) { - return RE2::FullMatch(str, re.regex_); - } - static bool PartialMatch(absl::string_view str, const RE& re) { - return RE2::PartialMatch(str, re.regex_); - } - - private: - RE2 regex_; -}; - -#elif GTEST_USES_POSIX_RE || GTEST_USES_SIMPLE_RE - -// A simple C++ wrapper for . It uses the POSIX Extended -// Regular Expression syntax. -class GTEST_API_ RE { - public: - // A copy constructor is required by the Standard to initialize object - // references from r-values. - RE(const RE& other) { Init(other.pattern()); } - - // Constructs an RE from a string. - RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT - - RE(const char* regex) { Init(regex); } // NOLINT - ~RE(); - - // Returns the string representation of the regex. - const char* pattern() const { return pattern_; } - - // FullMatch(str, re) returns true if and only if regular expression re - // matches the entire str. - // PartialMatch(str, re) returns true if and only if regular expression re - // matches a substring of str (including str itself). - static bool FullMatch(const ::std::string& str, const RE& re) { - return FullMatch(str.c_str(), re); - } - static bool PartialMatch(const ::std::string& str, const RE& re) { - return PartialMatch(str.c_str(), re); - } - - static bool FullMatch(const char* str, const RE& re); - static bool PartialMatch(const char* str, const RE& re); - - private: - void Init(const char* regex); - const char* pattern_; - bool is_valid_; - -#if GTEST_USES_POSIX_RE - - regex_t full_regex_; // For FullMatch(). - regex_t partial_regex_; // For PartialMatch(). - -#else // GTEST_USES_SIMPLE_RE - - const char* full_pattern_; // For FullMatch(); - -#endif -}; - -#endif // ::testing::internal::RE implementation - -// Formats a source file path and a line number as they would appear -// in an error message from the compiler used to compile this code. -GTEST_API_ ::std::string FormatFileLocation(const char* file, int line); - -// Formats a file location for compiler-independent XML output. -// Although this function is not platform dependent, we put it next to -// FormatFileLocation in order to contrast the two functions. -GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, - int line); - -// Defines logging utilities: -// GTEST_LOG_(severity) - logs messages at the specified severity level. The -// message itself is streamed into the macro. -// LogToStderr() - directs all log messages to stderr. -// FlushInfoLog() - flushes informational log messages. - -enum GTestLogSeverity { GTEST_INFO, GTEST_WARNING, GTEST_ERROR, GTEST_FATAL }; - -// Formats log entry severity, provides a stream object for streaming the -// log message, and terminates the message with a newline when going out of -// scope. -class GTEST_API_ GTestLog { - public: - GTestLog(GTestLogSeverity severity, const char* file, int line); - - // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. - ~GTestLog(); - - ::std::ostream& GetStream() { return ::std::cerr; } - - private: - const GTestLogSeverity severity_; - - GTestLog(const GTestLog&) = delete; - GTestLog& operator=(const GTestLog&) = delete; -}; - -#if !defined(GTEST_LOG_) - -#define GTEST_LOG_(severity) \ - ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ - __FILE__, __LINE__) \ - .GetStream() - -inline void LogToStderr() {} -inline void FlushInfoLog() { fflush(nullptr); } - -#endif // !defined(GTEST_LOG_) - -#if !defined(GTEST_CHECK_) -// INTERNAL IMPLEMENTATION - DO NOT USE. -// -// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition -// is not satisfied. -// Synopsis: -// GTEST_CHECK_(boolean_condition); -// or -// GTEST_CHECK_(boolean_condition) << "Additional message"; -// -// This checks the condition and if the condition is not satisfied -// it prints message about the condition violation, including the -// condition itself, plus additional message streamed into it, if any, -// and then it aborts the program. It aborts the program irrespective of -// whether it is built in the debug mode or not. -#define GTEST_CHECK_(condition) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::IsTrue(condition)) \ - ; \ - else \ - GTEST_LOG_(FATAL) << "Condition " #condition " failed. " -#endif // !defined(GTEST_CHECK_) - -// An all-mode assert to verify that the given POSIX-style function -// call returns 0 (indicating success). Known limitation: this -// doesn't expand to a balanced 'if' statement, so enclose the macro -// in {} if you need to use it as the only statement in an 'if' -// branch. -#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ - if (const int gtest_error = (posix_call)) \ - GTEST_LOG_(FATAL) << #posix_call << "failed with error " << gtest_error - -// Transforms "T" into "const T&" according to standard reference collapsing -// rules (this is only needed as a backport for C++98 compilers that do not -// support reference collapsing). Specifically, it transforms: -// -// char ==> const char& -// const char ==> const char& -// char& ==> char& -// const char& ==> const char& -// -// Note that the non-const reference will not have "const" added. This is -// standard, and necessary so that "T" can always bind to "const T&". -template -struct ConstRef { - typedef const T& type; -}; -template -struct ConstRef { - typedef T& type; -}; - -// The argument T must depend on some template parameters. -#define GTEST_REFERENCE_TO_CONST_(T) \ - typename ::testing::internal::ConstRef::type - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// -// Use ImplicitCast_ as a safe version of static_cast for upcasting in -// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a -// const Foo*). When you use ImplicitCast_, the compiler checks that -// the cast is safe. Such explicit ImplicitCast_s are necessary in -// surprisingly many situations where C++ demands an exact type match -// instead of an argument type convertible to a target type. -// -// The syntax for using ImplicitCast_ is the same as for static_cast: -// -// ImplicitCast_(expr) -// -// ImplicitCast_ would have been part of the C++ standard library, -// but the proposal was submitted too late. It will probably make -// its way into the language in the future. -// -// This relatively ugly name is intentional. It prevents clashes with -// similar functions users may have (e.g., implicit_cast). The internal -// namespace alone is not enough because the function can be found by ADL. -template -inline To ImplicitCast_(To x) { - return x; -} - -// When you upcast (that is, cast a pointer from type Foo to type -// SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts -// always succeed. When you downcast (that is, cast a pointer from -// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because -// how do you know the pointer is really of type SubclassOfFoo? It -// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, -// when you downcast, you should use this macro. In debug mode, we -// use dynamic_cast<> to double-check the downcast is legal (we die -// if it's not). In normal mode, we do the efficient static_cast<> -// instead. Thus, it's important to test in debug mode to make sure -// the cast is legal! -// This is the only place in the code we should use dynamic_cast<>. -// In particular, you SHOULDN'T be using dynamic_cast<> in order to -// do RTTI (eg code like this: -// if (dynamic_cast(foo)) HandleASubclass1Object(foo); -// if (dynamic_cast(foo)) HandleASubclass2Object(foo); -// You should design the code some other way not to need this. -// -// This relatively ugly name is intentional. It prevents clashes with -// similar functions users may have (e.g., down_cast). The internal -// namespace alone is not enough because the function can be found by ADL. -template // use like this: DownCast_(foo); -inline To DownCast_(From* f) { // so we only accept pointers - // Ensures that To is a sub-type of From *. This test is here only - // for compile-time type checking, and has no overhead in an - // optimized build at run-time, as it will be optimized away - // completely. - GTEST_INTENTIONAL_CONST_COND_PUSH_() - if (false) { - GTEST_INTENTIONAL_CONST_COND_POP_() - const To to = nullptr; - ::testing::internal::ImplicitCast_(to); - } - -#if GTEST_HAS_RTTI - // RTTI: debug mode only! - GTEST_CHECK_(f == nullptr || dynamic_cast(f) != nullptr); -#endif - return static_cast(f); -} - -// Downcasts the pointer of type Base to Derived. -// Derived must be a subclass of Base. The parameter MUST -// point to a class of type Derived, not any subclass of it. -// When RTTI is available, the function performs a runtime -// check to enforce this. -template -Derived* CheckedDowncastToActualType(Base* base) { -#if GTEST_HAS_RTTI - GTEST_CHECK_(typeid(*base) == typeid(Derived)); -#endif - -#if GTEST_HAS_DOWNCAST_ - return ::down_cast(base); -#elif GTEST_HAS_RTTI - return dynamic_cast(base); // NOLINT -#else - return static_cast(base); // Poor man's downcast. -#endif -} - -#if GTEST_HAS_STREAM_REDIRECTION - -// Defines the stderr capturer: -// CaptureStdout - starts capturing stdout. -// GetCapturedStdout - stops capturing stdout and returns the captured string. -// CaptureStderr - starts capturing stderr. -// GetCapturedStderr - stops capturing stderr and returns the captured string. -// -GTEST_API_ void CaptureStdout(); -GTEST_API_ std::string GetCapturedStdout(); -GTEST_API_ void CaptureStderr(); -GTEST_API_ std::string GetCapturedStderr(); - -#endif // GTEST_HAS_STREAM_REDIRECTION -// Returns the size (in bytes) of a file. -GTEST_API_ size_t GetFileSize(FILE* file); - -// Reads the entire content of a file as a string. -GTEST_API_ std::string ReadEntireFile(FILE* file); - -// All command line arguments. -GTEST_API_ std::vector GetArgvs(); - -#if GTEST_HAS_DEATH_TEST - -std::vector GetInjectableArgvs(); -// Deprecated: pass the args vector by value instead. -void SetInjectableArgvs(const std::vector* new_argvs); -void SetInjectableArgvs(const std::vector& new_argvs); -void ClearInjectableArgvs(); - -#endif // GTEST_HAS_DEATH_TEST - -// Defines synchronization primitives. -#if GTEST_IS_THREADSAFE - -#if GTEST_OS_WINDOWS -// Provides leak-safe Windows kernel handle ownership. -// Used in death tests and in threading support. -class GTEST_API_ AutoHandle { - public: - // Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to - // avoid including in this header file. Including is - // undesirable because it defines a lot of symbols and macros that tend to - // conflict with client code. This assumption is verified by - // WindowsTypesTest.HANDLEIsVoidStar. - typedef void* Handle; - AutoHandle(); - explicit AutoHandle(Handle handle); - - ~AutoHandle(); - - Handle Get() const; - void Reset(); - void Reset(Handle handle); - - private: - // Returns true if and only if the handle is a valid handle object that can be - // closed. - bool IsCloseable() const; - - Handle handle_; - - AutoHandle(const AutoHandle&) = delete; - AutoHandle& operator=(const AutoHandle&) = delete; -}; -#endif - -#if GTEST_HAS_NOTIFICATION_ -// Notification has already been imported into the namespace. -// Nothing to do here. - -#else -GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ -/* class A needs to have dll-interface to be used by clients of class B */) - -// Allows a controller thread to pause execution of newly created -// threads until notified. Instances of this class must be created -// and destroyed in the controller thread. -// -// This class is only for testing Google Test's own constructs. Do not -// use it in user tests, either directly or indirectly. -// TODO(b/203539622): Replace unconditionally with absl::Notification. -class GTEST_API_ Notification { - public: - Notification() : notified_(false) {} - Notification(const Notification&) = delete; - Notification& operator=(const Notification&) = delete; - - // Notifies all threads created with this notification to start. Must - // be called from the controller thread. - void Notify() { - std::lock_guard lock(mu_); - notified_ = true; - cv_.notify_all(); - } - - // Blocks until the controller thread notifies. Must be called from a test - // thread. - void WaitForNotification() { - std::unique_lock lock(mu_); - cv_.wait(lock, [this]() { return notified_; }); - } - - private: - std::mutex mu_; - std::condition_variable cv_; - bool notified_; -}; -GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 -#endif // GTEST_HAS_NOTIFICATION_ - -// On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD -// defined, but we don't want to use MinGW's pthreads implementation, which -// has conformance problems with some versions of the POSIX standard. -#if GTEST_HAS_PTHREAD && !GTEST_OS_WINDOWS_MINGW - -// As a C-function, ThreadFuncWithCLinkage cannot be templated itself. -// Consequently, it cannot select a correct instantiation of ThreadWithParam -// in order to call its Run(). Introducing ThreadWithParamBase as a -// non-templated base class for ThreadWithParam allows us to bypass this -// problem. -class ThreadWithParamBase { - public: - virtual ~ThreadWithParamBase() {} - virtual void Run() = 0; -}; - -// pthread_create() accepts a pointer to a function type with the C linkage. -// According to the Standard (7.5/1), function types with different linkages -// are different even if they are otherwise identical. Some compilers (for -// example, SunStudio) treat them as different types. Since class methods -// cannot be defined with C-linkage we need to define a free C-function to -// pass into pthread_create(). -extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { - static_cast(thread)->Run(); - return nullptr; -} - -// Helper class for testing Google Test's multi-threading constructs. -// To use it, write: -// -// void ThreadFunc(int param) { /* Do things with param */ } -// Notification thread_can_start; -// ... -// // The thread_can_start parameter is optional; you can supply NULL. -// ThreadWithParam thread(&ThreadFunc, 5, &thread_can_start); -// thread_can_start.Notify(); -// -// These classes are only for testing Google Test's own constructs. Do -// not use them in user tests, either directly or indirectly. -template -class ThreadWithParam : public ThreadWithParamBase { - public: - typedef void UserThreadFunc(T); - - ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start) - : func_(func), - param_(param), - thread_can_start_(thread_can_start), - finished_(false) { - ThreadWithParamBase* const base = this; - // The thread can be created only after all fields except thread_ - // have been initialized. - GTEST_CHECK_POSIX_SUCCESS_( - pthread_create(&thread_, nullptr, &ThreadFuncWithCLinkage, base)); - } - ~ThreadWithParam() override { Join(); } - - void Join() { - if (!finished_) { - GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, nullptr)); - finished_ = true; - } - } - - void Run() override { - if (thread_can_start_ != nullptr) thread_can_start_->WaitForNotification(); - func_(param_); - } - - private: - UserThreadFunc* const func_; // User-supplied thread function. - const T param_; // User-supplied parameter to the thread function. - // When non-NULL, used to block execution until the controller thread - // notifies. - Notification* const thread_can_start_; - bool finished_; // true if and only if we know that the thread function has - // finished. - pthread_t thread_; // The native thread object. - - ThreadWithParam(const ThreadWithParam&) = delete; - ThreadWithParam& operator=(const ThreadWithParam&) = delete; -}; -#endif // !GTEST_OS_WINDOWS && GTEST_HAS_PTHREAD || - // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ - -#if GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ -// Mutex and ThreadLocal have already been imported into the namespace. -// Nothing to do here. - -#elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT - -// Mutex implements mutex on Windows platforms. It is used in conjunction -// with class MutexLock: -// -// Mutex mutex; -// ... -// MutexLock lock(&mutex); // Acquires the mutex and releases it at the -// // end of the current scope. -// -// A static Mutex *must* be defined or declared using one of the following -// macros: -// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex); -// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); -// -// (A non-static Mutex is defined/declared in the usual way). -class GTEST_API_ Mutex { - public: - enum MutexType { kStatic = 0, kDynamic = 1 }; - // We rely on kStaticMutex being 0 as it is to what the linker initializes - // type_ in static mutexes. critical_section_ will be initialized lazily - // in ThreadSafeLazyInit(). - enum StaticConstructorSelector { kStaticMutex = 0 }; - - // This constructor intentionally does nothing. It relies on type_ being - // statically initialized to 0 (effectively setting it to kStatic) and on - // ThreadSafeLazyInit() to lazily initialize the rest of the members. - explicit Mutex(StaticConstructorSelector /*dummy*/) {} - - Mutex(); - ~Mutex(); - - void Lock(); - - void Unlock(); - - // Does nothing if the current thread holds the mutex. Otherwise, crashes - // with high probability. - void AssertHeld(); - - private: - // Initializes owner_thread_id_ and critical_section_ in static mutexes. - void ThreadSafeLazyInit(); - - // Per https://blogs.msdn.microsoft.com/oldnewthing/20040223-00/?p=40503, - // we assume that 0 is an invalid value for thread IDs. - unsigned int owner_thread_id_; - - // For static mutexes, we rely on these members being initialized to zeros - // by the linker. - MutexType type_; - long critical_section_init_phase_; // NOLINT - GTEST_CRITICAL_SECTION* critical_section_; - - Mutex(const Mutex&) = delete; - Mutex& operator=(const Mutex&) = delete; -}; - -#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ - extern ::testing::internal::Mutex mutex - -#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ - ::testing::internal::Mutex mutex(::testing::internal::Mutex::kStaticMutex) - -// We cannot name this class MutexLock because the ctor declaration would -// conflict with a macro named MutexLock, which is defined on some -// platforms. That macro is used as a defensive measure to prevent against -// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than -// "MutexLock l(&mu)". Hence the typedef trick below. -class GTestMutexLock { - public: - explicit GTestMutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); } - - ~GTestMutexLock() { mutex_->Unlock(); } - - private: - Mutex* const mutex_; - - GTestMutexLock(const GTestMutexLock&) = delete; - GTestMutexLock& operator=(const GTestMutexLock&) = delete; -}; - -typedef GTestMutexLock MutexLock; - -// Base class for ValueHolder. Allows a caller to hold and delete a value -// without knowing its type. -class ThreadLocalValueHolderBase { - public: - virtual ~ThreadLocalValueHolderBase() {} -}; - -// Provides a way for a thread to send notifications to a ThreadLocal -// regardless of its parameter type. -class ThreadLocalBase { - public: - // Creates a new ValueHolder object holding a default value passed to - // this ThreadLocal's constructor and returns it. It is the caller's - // responsibility not to call this when the ThreadLocal instance already - // has a value on the current thread. - virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const = 0; - - protected: - ThreadLocalBase() {} - virtual ~ThreadLocalBase() {} - - private: - ThreadLocalBase(const ThreadLocalBase&) = delete; - ThreadLocalBase& operator=(const ThreadLocalBase&) = delete; -}; - -// Maps a thread to a set of ThreadLocals that have values instantiated on that -// thread and notifies them when the thread exits. A ThreadLocal instance is -// expected to persist until all threads it has values on have terminated. -class GTEST_API_ ThreadLocalRegistry { - public: - // Registers thread_local_instance as having value on the current thread. - // Returns a value that can be used to identify the thread from other threads. - static ThreadLocalValueHolderBase* GetValueOnCurrentThread( - const ThreadLocalBase* thread_local_instance); - - // Invoked when a ThreadLocal instance is destroyed. - static void OnThreadLocalDestroyed( - const ThreadLocalBase* thread_local_instance); -}; - -class GTEST_API_ ThreadWithParamBase { - public: - void Join(); - - protected: - class Runnable { - public: - virtual ~Runnable() {} - virtual void Run() = 0; - }; - - ThreadWithParamBase(Runnable* runnable, Notification* thread_can_start); - virtual ~ThreadWithParamBase(); - - private: - AutoHandle thread_; -}; - -// Helper class for testing Google Test's multi-threading constructs. -template -class ThreadWithParam : public ThreadWithParamBase { - public: - typedef void UserThreadFunc(T); - - ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start) - : ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) {} - virtual ~ThreadWithParam() {} - - private: - class RunnableImpl : public Runnable { - public: - RunnableImpl(UserThreadFunc* func, T param) : func_(func), param_(param) {} - virtual ~RunnableImpl() {} - virtual void Run() { func_(param_); } - - private: - UserThreadFunc* const func_; - const T param_; - - RunnableImpl(const RunnableImpl&) = delete; - RunnableImpl& operator=(const RunnableImpl&) = delete; - }; - - ThreadWithParam(const ThreadWithParam&) = delete; - ThreadWithParam& operator=(const ThreadWithParam&) = delete; -}; - -// Implements thread-local storage on Windows systems. -// -// // Thread 1 -// ThreadLocal tl(100); // 100 is the default value for each thread. -// -// // Thread 2 -// tl.set(150); // Changes the value for thread 2 only. -// EXPECT_EQ(150, tl.get()); -// -// // Thread 1 -// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value. -// tl.set(200); -// EXPECT_EQ(200, tl.get()); -// -// The template type argument T must have a public copy constructor. -// In addition, the default ThreadLocal constructor requires T to have -// a public default constructor. -// -// The users of a TheadLocal instance have to make sure that all but one -// threads (including the main one) using that instance have exited before -// destroying it. Otherwise, the per-thread objects managed for them by the -// ThreadLocal instance are not guaranteed to be destroyed on all platforms. -// -// Google Test only uses global ThreadLocal objects. That means they -// will die after main() has returned. Therefore, no per-thread -// object managed by Google Test will be leaked as long as all threads -// using Google Test have exited when main() returns. -template -class ThreadLocal : public ThreadLocalBase { - public: - ThreadLocal() : default_factory_(new DefaultValueHolderFactory()) {} - explicit ThreadLocal(const T& value) - : default_factory_(new InstanceValueHolderFactory(value)) {} - - ~ThreadLocal() override { ThreadLocalRegistry::OnThreadLocalDestroyed(this); } - - T* pointer() { return GetOrCreateValue(); } - const T* pointer() const { return GetOrCreateValue(); } - const T& get() const { return *pointer(); } - void set(const T& value) { *pointer() = value; } - - private: - // Holds a value of T. Can be deleted via its base class without the caller - // knowing the type of T. - class ValueHolder : public ThreadLocalValueHolderBase { - public: - ValueHolder() : value_() {} - explicit ValueHolder(const T& value) : value_(value) {} - - T* pointer() { return &value_; } - - private: - T value_; - ValueHolder(const ValueHolder&) = delete; - ValueHolder& operator=(const ValueHolder&) = delete; - }; - - T* GetOrCreateValue() const { - return static_cast( - ThreadLocalRegistry::GetValueOnCurrentThread(this)) - ->pointer(); - } - - ThreadLocalValueHolderBase* NewValueForCurrentThread() const override { - return default_factory_->MakeNewHolder(); - } - - class ValueHolderFactory { - public: - ValueHolderFactory() {} - virtual ~ValueHolderFactory() {} - virtual ValueHolder* MakeNewHolder() const = 0; - - private: - ValueHolderFactory(const ValueHolderFactory&) = delete; - ValueHolderFactory& operator=(const ValueHolderFactory&) = delete; - }; - - class DefaultValueHolderFactory : public ValueHolderFactory { - public: - DefaultValueHolderFactory() {} - ValueHolder* MakeNewHolder() const override { return new ValueHolder(); } - - private: - DefaultValueHolderFactory(const DefaultValueHolderFactory&) = delete; - DefaultValueHolderFactory& operator=(const DefaultValueHolderFactory&) = - delete; - }; - - class InstanceValueHolderFactory : public ValueHolderFactory { - public: - explicit InstanceValueHolderFactory(const T& value) : value_(value) {} - ValueHolder* MakeNewHolder() const override { - return new ValueHolder(value_); - } - - private: - const T value_; // The value for each thread. - - InstanceValueHolderFactory(const InstanceValueHolderFactory&) = delete; - InstanceValueHolderFactory& operator=(const InstanceValueHolderFactory&) = - delete; - }; - - std::unique_ptr default_factory_; - - ThreadLocal(const ThreadLocal&) = delete; - ThreadLocal& operator=(const ThreadLocal&) = delete; -}; - -#elif GTEST_HAS_PTHREAD - -// MutexBase and Mutex implement mutex on pthreads-based platforms. -class MutexBase { - public: - // Acquires this mutex. - void Lock() { - GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); - owner_ = pthread_self(); - has_owner_ = true; - } - - // Releases this mutex. - void Unlock() { - // Since the lock is being released the owner_ field should no longer be - // considered valid. We don't protect writing to has_owner_ here, as it's - // the caller's responsibility to ensure that the current thread holds the - // mutex when this is called. - has_owner_ = false; - GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); - } - - // Does nothing if the current thread holds the mutex. Otherwise, crashes - // with high probability. - void AssertHeld() const { - GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self())) - << "The current thread is not holding the mutex @" << this; - } - - // A static mutex may be used before main() is entered. It may even - // be used before the dynamic initialization stage. Therefore we - // must be able to initialize a static mutex object at link time. - // This means MutexBase has to be a POD and its member variables - // have to be public. - public: - pthread_mutex_t mutex_; // The underlying pthread mutex. - // has_owner_ indicates whether the owner_ field below contains a valid thread - // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All - // accesses to the owner_ field should be protected by a check of this field. - // An alternative might be to memset() owner_ to all zeros, but there's no - // guarantee that a zero'd pthread_t is necessarily invalid or even different - // from pthread_self(). - bool has_owner_; - pthread_t owner_; // The thread holding the mutex. -}; - -// Forward-declares a static mutex. -#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ - extern ::testing::internal::MutexBase mutex - -// Defines and statically (i.e. at link time) initializes a static mutex. -// The initialization list here does not explicitly initialize each field, -// instead relying on default initialization for the unspecified fields. In -// particular, the owner_ field (a pthread_t) is not explicitly initialized. -// This allows initialization to work whether pthread_t is a scalar or struct. -// The flag -Wmissing-field-initializers must not be specified for this to work. -#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ - ::testing::internal::MutexBase mutex = {PTHREAD_MUTEX_INITIALIZER, false, 0} - -// The Mutex class can only be used for mutexes created at runtime. It -// shares its API with MutexBase otherwise. -class Mutex : public MutexBase { - public: - Mutex() { - GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr)); - has_owner_ = false; - } - ~Mutex() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); } - - private: - Mutex(const Mutex&) = delete; - Mutex& operator=(const Mutex&) = delete; -}; - -// We cannot name this class MutexLock because the ctor declaration would -// conflict with a macro named MutexLock, which is defined on some -// platforms. That macro is used as a defensive measure to prevent against -// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than -// "MutexLock l(&mu)". Hence the typedef trick below. -class GTestMutexLock { - public: - explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->Lock(); } - - ~GTestMutexLock() { mutex_->Unlock(); } - - private: - MutexBase* const mutex_; - - GTestMutexLock(const GTestMutexLock&) = delete; - GTestMutexLock& operator=(const GTestMutexLock&) = delete; -}; - -typedef GTestMutexLock MutexLock; - -// Helpers for ThreadLocal. - -// pthread_key_create() requires DeleteThreadLocalValue() to have -// C-linkage. Therefore it cannot be templatized to access -// ThreadLocal. Hence the need for class -// ThreadLocalValueHolderBase. -class ThreadLocalValueHolderBase { - public: - virtual ~ThreadLocalValueHolderBase() {} -}; - -// Called by pthread to delete thread-local data stored by -// pthread_setspecific(). -extern "C" inline void DeleteThreadLocalValue(void* value_holder) { - delete static_cast(value_holder); -} - -// Implements thread-local storage on pthreads-based systems. -template -class GTEST_API_ ThreadLocal { - public: - ThreadLocal() - : key_(CreateKey()), default_factory_(new DefaultValueHolderFactory()) {} - explicit ThreadLocal(const T& value) - : key_(CreateKey()), - default_factory_(new InstanceValueHolderFactory(value)) {} - - ~ThreadLocal() { - // Destroys the managed object for the current thread, if any. - DeleteThreadLocalValue(pthread_getspecific(key_)); - - // Releases resources associated with the key. This will *not* - // delete managed objects for other threads. - GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); - } - - T* pointer() { return GetOrCreateValue(); } - const T* pointer() const { return GetOrCreateValue(); } - const T& get() const { return *pointer(); } - void set(const T& value) { *pointer() = value; } - - private: - // Holds a value of type T. - class ValueHolder : public ThreadLocalValueHolderBase { - public: - ValueHolder() : value_() {} - explicit ValueHolder(const T& value) : value_(value) {} - - T* pointer() { return &value_; } - - private: - T value_; - ValueHolder(const ValueHolder&) = delete; - ValueHolder& operator=(const ValueHolder&) = delete; - }; - - static pthread_key_t CreateKey() { - pthread_key_t key; - // When a thread exits, DeleteThreadLocalValue() will be called on - // the object managed for that thread. - GTEST_CHECK_POSIX_SUCCESS_( - pthread_key_create(&key, &DeleteThreadLocalValue)); - return key; - } - - T* GetOrCreateValue() const { - ThreadLocalValueHolderBase* const holder = - static_cast(pthread_getspecific(key_)); - if (holder != nullptr) { - return CheckedDowncastToActualType(holder)->pointer(); - } - - ValueHolder* const new_holder = default_factory_->MakeNewHolder(); - ThreadLocalValueHolderBase* const holder_base = new_holder; - GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); - return new_holder->pointer(); - } - - class ValueHolderFactory { - public: - ValueHolderFactory() {} - virtual ~ValueHolderFactory() {} - virtual ValueHolder* MakeNewHolder() const = 0; - - private: - ValueHolderFactory(const ValueHolderFactory&) = delete; - ValueHolderFactory& operator=(const ValueHolderFactory&) = delete; - }; - - class DefaultValueHolderFactory : public ValueHolderFactory { - public: - DefaultValueHolderFactory() {} - ValueHolder* MakeNewHolder() const override { return new ValueHolder(); } - - private: - DefaultValueHolderFactory(const DefaultValueHolderFactory&) = delete; - DefaultValueHolderFactory& operator=(const DefaultValueHolderFactory&) = - delete; - }; - - class InstanceValueHolderFactory : public ValueHolderFactory { - public: - explicit InstanceValueHolderFactory(const T& value) : value_(value) {} - ValueHolder* MakeNewHolder() const override { - return new ValueHolder(value_); - } - - private: - const T value_; // The value for each thread. - - InstanceValueHolderFactory(const InstanceValueHolderFactory&) = delete; - InstanceValueHolderFactory& operator=(const InstanceValueHolderFactory&) = - delete; - }; - - // A key pthreads uses for looking up per-thread values. - const pthread_key_t key_; - std::unique_ptr default_factory_; - - ThreadLocal(const ThreadLocal&) = delete; - ThreadLocal& operator=(const ThreadLocal&) = delete; -}; - -#endif // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ - -#else // GTEST_IS_THREADSAFE - -// A dummy implementation of synchronization primitives (mutex, lock, -// and thread-local variable). Necessary for compiling Google Test where -// mutex is not supported - using Google Test in multiple threads is not -// supported on such platforms. - -class Mutex { - public: - Mutex() {} - void Lock() {} - void Unlock() {} - void AssertHeld() const {} -}; - -#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ - extern ::testing::internal::Mutex mutex - -#define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex - -// We cannot name this class MutexLock because the ctor declaration would -// conflict with a macro named MutexLock, which is defined on some -// platforms. That macro is used as a defensive measure to prevent against -// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than -// "MutexLock l(&mu)". Hence the typedef trick below. -class GTestMutexLock { - public: - explicit GTestMutexLock(Mutex*) {} // NOLINT -}; - -typedef GTestMutexLock MutexLock; - -template -class GTEST_API_ ThreadLocal { - public: - ThreadLocal() : value_() {} - explicit ThreadLocal(const T& value) : value_(value) {} - T* pointer() { return &value_; } - const T* pointer() const { return &value_; } - const T& get() const { return value_; } - void set(const T& value) { value_ = value; } - - private: - T value_; -}; - -#endif // GTEST_IS_THREADSAFE - -// Returns the number of threads running in the process, or 0 to indicate that -// we cannot detect it. -GTEST_API_ size_t GetThreadCount(); - -#if GTEST_OS_WINDOWS -#define GTEST_PATH_SEP_ "\\" -#define GTEST_HAS_ALT_PATH_SEP_ 1 -#else -#define GTEST_PATH_SEP_ "/" -#define GTEST_HAS_ALT_PATH_SEP_ 0 -#endif // GTEST_OS_WINDOWS - -// Utilities for char. - -// isspace(int ch) and friends accept an unsigned char or EOF. char -// may be signed, depending on the compiler (or compiler flags). -// Therefore we need to cast a char to unsigned char before calling -// isspace(), etc. - -inline bool IsAlpha(char ch) { - return isalpha(static_cast(ch)) != 0; -} -inline bool IsAlNum(char ch) { - return isalnum(static_cast(ch)) != 0; -} -inline bool IsDigit(char ch) { - return isdigit(static_cast(ch)) != 0; -} -inline bool IsLower(char ch) { - return islower(static_cast(ch)) != 0; -} -inline bool IsSpace(char ch) { - return isspace(static_cast(ch)) != 0; -} -inline bool IsUpper(char ch) { - return isupper(static_cast(ch)) != 0; -} -inline bool IsXDigit(char ch) { - return isxdigit(static_cast(ch)) != 0; -} -#ifdef __cpp_char8_t -inline bool IsXDigit(char8_t ch) { - return isxdigit(static_cast(ch)) != 0; -} -#endif -inline bool IsXDigit(char16_t ch) { - const unsigned char low_byte = static_cast(ch); - return ch == low_byte && isxdigit(low_byte) != 0; -} -inline bool IsXDigit(char32_t ch) { - const unsigned char low_byte = static_cast(ch); - return ch == low_byte && isxdigit(low_byte) != 0; -} -inline bool IsXDigit(wchar_t ch) { - const unsigned char low_byte = static_cast(ch); - return ch == low_byte && isxdigit(low_byte) != 0; -} - -inline char ToLower(char ch) { - return static_cast(tolower(static_cast(ch))); -} -inline char ToUpper(char ch) { - return static_cast(toupper(static_cast(ch))); -} - -inline std::string StripTrailingSpaces(std::string str) { - std::string::iterator it = str.end(); - while (it != str.begin() && IsSpace(*--it)) it = str.erase(it); - return str; -} - -// The testing::internal::posix namespace holds wrappers for common -// POSIX functions. These wrappers hide the differences between -// Windows/MSVC and POSIX systems. Since some compilers define these -// standard functions as macros, the wrapper cannot have the same name -// as the wrapped function. - -namespace posix { - -// Functions with a different name on Windows. - -#if GTEST_OS_WINDOWS - -typedef struct _stat StatStruct; - -#ifdef __BORLANDC__ -inline int DoIsATTY(int fd) { return isatty(fd); } -inline int StrCaseCmp(const char* s1, const char* s2) { - return stricmp(s1, s2); -} -inline char* StrDup(const char* src) { return strdup(src); } -#else // !__BORLANDC__ -#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS || GTEST_OS_IOS || \ - GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT || defined(ESP_PLATFORM) -inline int DoIsATTY(int /* fd */) { return 0; } -#else -inline int DoIsATTY(int fd) { return _isatty(fd); } -#endif // GTEST_OS_WINDOWS_MOBILE -inline int StrCaseCmp(const char* s1, const char* s2) { - return _stricmp(s1, s2); -} -inline char* StrDup(const char* src) { return _strdup(src); } -#endif // __BORLANDC__ - -#if GTEST_OS_WINDOWS_MOBILE -inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } -// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this -// time and thus not defined there. -#else -inline int FileNo(FILE* file) { return _fileno(file); } -inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } -inline int RmDir(const char* dir) { return _rmdir(dir); } -inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; } -#endif // GTEST_OS_WINDOWS_MOBILE - -#elif GTEST_OS_ESP8266 -typedef struct stat StatStruct; - -inline int FileNo(FILE* file) { return fileno(file); } -inline int DoIsATTY(int fd) { return isatty(fd); } -inline int Stat(const char* path, StatStruct* buf) { - // stat function not implemented on ESP8266 - return 0; -} -inline int StrCaseCmp(const char* s1, const char* s2) { - return strcasecmp(s1, s2); -} -inline char* StrDup(const char* src) { return strdup(src); } -inline int RmDir(const char* dir) { return rmdir(dir); } -inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } - -#else - -typedef struct stat StatStruct; - -inline int FileNo(FILE* file) { return fileno(file); } -inline int DoIsATTY(int fd) { return isatty(fd); } -inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } -inline int StrCaseCmp(const char* s1, const char* s2) { - return strcasecmp(s1, s2); -} -inline char* StrDup(const char* src) { return strdup(src); } -inline int RmDir(const char* dir) { return rmdir(dir); } -inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } - -#endif // GTEST_OS_WINDOWS - -inline int IsATTY(int fd) { - // DoIsATTY might change errno (for example ENOTTY in case you redirect stdout - // to a file on Linux), which is unexpected, so save the previous value, and - // restore it after the call. - int savedErrno = errno; - int isAttyValue = DoIsATTY(fd); - errno = savedErrno; - - return isAttyValue; -} - -// Functions deprecated by MSVC 8.0. - -GTEST_DISABLE_MSC_DEPRECATED_PUSH_() - -// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and -// StrError() aren't needed on Windows CE at this time and thus not -// defined there. - -#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && \ - !GTEST_OS_WINDOWS_RT && !GTEST_OS_ESP8266 && !GTEST_OS_XTENSA -inline int ChDir(const char* dir) { return chdir(dir); } -#endif -inline FILE* FOpen(const char* path, const char* mode) { -#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW - struct wchar_codecvt : public std::codecvt {}; - std::wstring_convert converter; - std::wstring wide_path = converter.from_bytes(path); - std::wstring wide_mode = converter.from_bytes(mode); - return _wfopen(wide_path.c_str(), wide_mode.c_str()); -#else // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW - return fopen(path, mode); -#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW -} -#if !GTEST_OS_WINDOWS_MOBILE -inline FILE* FReopen(const char* path, const char* mode, FILE* stream) { - return freopen(path, mode, stream); -} -inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } -#endif -inline int FClose(FILE* fp) { return fclose(fp); } -#if !GTEST_OS_WINDOWS_MOBILE -inline int Read(int fd, void* buf, unsigned int count) { - return static_cast(read(fd, buf, count)); -} -inline int Write(int fd, const void* buf, unsigned int count) { - return static_cast(write(fd, buf, count)); -} -inline int Close(int fd) { return close(fd); } -inline const char* StrError(int errnum) { return strerror(errnum); } -#endif -inline const char* GetEnv(const char* name) { -#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ - GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA - // We are on an embedded platform, which has no environment variables. - static_cast(name); // To prevent 'unused argument' warning. - return nullptr; -#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) - // Environment variables which we programmatically clear will be set to the - // empty string rather than unset (NULL). Handle that case. - const char* const env = getenv(name); - return (env != nullptr && env[0] != '\0') ? env : nullptr; -#else - return getenv(name); -#endif -} - -GTEST_DISABLE_MSC_DEPRECATED_POP_() - -#if GTEST_OS_WINDOWS_MOBILE -// Windows CE has no C library. The abort() function is used in -// several places in Google Test. This implementation provides a reasonable -// imitation of standard behaviour. -[[noreturn]] void Abort(); -#else -[[noreturn]] inline void Abort() { abort(); } -#endif // GTEST_OS_WINDOWS_MOBILE - -} // namespace posix - -// MSVC "deprecates" snprintf and issues warnings wherever it is used. In -// order to avoid these warnings, we need to use _snprintf or _snprintf_s on -// MSVC-based platforms. We map the GTEST_SNPRINTF_ macro to the appropriate -// function in order to achieve that. We use macro definition here because -// snprintf is a variadic function. -#if _MSC_VER && !GTEST_OS_WINDOWS_MOBILE -// MSVC 2005 and above support variadic macros. -#define GTEST_SNPRINTF_(buffer, size, format, ...) \ - _snprintf_s(buffer, size, size, format, __VA_ARGS__) -#elif defined(_MSC_VER) -// Windows CE does not define _snprintf_s -#define GTEST_SNPRINTF_ _snprintf -#else -#define GTEST_SNPRINTF_ snprintf -#endif - -// The biggest signed integer type the compiler supports. -// -// long long is guaranteed to be at least 64-bits in C++11. -using BiggestInt = long long; // NOLINT - -// The maximum number a BiggestInt can represent. -constexpr BiggestInt kMaxBiggestInt = (std::numeric_limits::max)(); - -// This template class serves as a compile-time function from size to -// type. It maps a size in bytes to a primitive type with that -// size. e.g. -// -// TypeWithSize<4>::UInt -// -// is typedef-ed to be unsigned int (unsigned integer made up of 4 -// bytes). -// -// Such functionality should belong to STL, but I cannot find it -// there. -// -// Google Test uses this class in the implementation of floating-point -// comparison. -// -// For now it only handles UInt (unsigned int) as that's all Google Test -// needs. Other types can be easily added in the future if need -// arises. -template -class TypeWithSize { - public: - // This prevents the user from using TypeWithSize with incorrect - // values of N. - using UInt = void; -}; - -// The specialization for size 4. -template <> -class TypeWithSize<4> { - public: - using Int = std::int32_t; - using UInt = std::uint32_t; -}; - -// The specialization for size 8. -template <> -class TypeWithSize<8> { - public: - using Int = std::int64_t; - using UInt = std::uint64_t; -}; - -// Integer types of known sizes. -using TimeInMillis = int64_t; // Represents time in milliseconds. - -// Utilities for command line flags and environment variables. - -// Macro for referencing flags. -#if !defined(GTEST_FLAG) -#define GTEST_FLAG_NAME_(name) gtest_##name -#define GTEST_FLAG(name) FLAGS_gtest_##name -#endif // !defined(GTEST_FLAG) - -// Pick a command line flags implementation. -#if GTEST_HAS_ABSL - -// Macros for defining flags. -#define GTEST_DEFINE_bool_(name, default_val, doc) \ - ABSL_FLAG(bool, GTEST_FLAG_NAME_(name), default_val, doc) -#define GTEST_DEFINE_int32_(name, default_val, doc) \ - ABSL_FLAG(int32_t, GTEST_FLAG_NAME_(name), default_val, doc) -#define GTEST_DEFINE_string_(name, default_val, doc) \ - ABSL_FLAG(std::string, GTEST_FLAG_NAME_(name), default_val, doc) - -// Macros for declaring flags. -#define GTEST_DECLARE_bool_(name) \ - ABSL_DECLARE_FLAG(bool, GTEST_FLAG_NAME_(name)) -#define GTEST_DECLARE_int32_(name) \ - ABSL_DECLARE_FLAG(int32_t, GTEST_FLAG_NAME_(name)) -#define GTEST_DECLARE_string_(name) \ - ABSL_DECLARE_FLAG(std::string, GTEST_FLAG_NAME_(name)) - -#define GTEST_FLAG_SAVER_ ::absl::FlagSaver - -#define GTEST_FLAG_GET(name) ::absl::GetFlag(GTEST_FLAG(name)) -#define GTEST_FLAG_SET(name, value) \ - (void)(::absl::SetFlag(>EST_FLAG(name), value)) -#define GTEST_USE_OWN_FLAGFILE_FLAG_ 0 - -#else // GTEST_HAS_ABSL - -// Macros for defining flags. -#define GTEST_DEFINE_bool_(name, default_val, doc) \ - namespace testing { \ - GTEST_API_ bool GTEST_FLAG(name) = (default_val); \ - } \ - static_assert(true, "no-op to require trailing semicolon") -#define GTEST_DEFINE_int32_(name, default_val, doc) \ - namespace testing { \ - GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val); \ - } \ - static_assert(true, "no-op to require trailing semicolon") -#define GTEST_DEFINE_string_(name, default_val, doc) \ - namespace testing { \ - GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val); \ - } \ - static_assert(true, "no-op to require trailing semicolon") - -// Macros for declaring flags. -#define GTEST_DECLARE_bool_(name) \ - namespace testing { \ - GTEST_API_ extern bool GTEST_FLAG(name); \ - } \ - static_assert(true, "no-op to require trailing semicolon") -#define GTEST_DECLARE_int32_(name) \ - namespace testing { \ - GTEST_API_ extern std::int32_t GTEST_FLAG(name); \ - } \ - static_assert(true, "no-op to require trailing semicolon") -#define GTEST_DECLARE_string_(name) \ - namespace testing { \ - GTEST_API_ extern ::std::string GTEST_FLAG(name); \ - } \ - static_assert(true, "no-op to require trailing semicolon") - -#define GTEST_FLAG_SAVER_ ::testing::internal::GTestFlagSaver - -#define GTEST_FLAG_GET(name) ::testing::GTEST_FLAG(name) -#define GTEST_FLAG_SET(name, value) (void)(::testing::GTEST_FLAG(name) = value) -#define GTEST_USE_OWN_FLAGFILE_FLAG_ 1 - -#endif // GTEST_HAS_ABSL - -// Thread annotations -#if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_) -#define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) -#define GTEST_LOCK_EXCLUDED_(locks) -#endif // !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_) - -// Parses 'str' for a 32-bit signed integer. If successful, writes the result -// to *value and returns true; otherwise leaves *value unchanged and returns -// false. -GTEST_API_ bool ParseInt32(const Message& src_text, const char* str, - int32_t* value); - -// Parses a bool/int32_t/string from the environment variable -// corresponding to the given Google Test flag. -bool BoolFromGTestEnv(const char* flag, bool default_val); -GTEST_API_ int32_t Int32FromGTestEnv(const char* flag, int32_t default_val); -std::string OutputFlagAlsoCheckEnvVar(); -const char* StringFromGTestEnv(const char* flag, const char* default_val); - -} // namespace internal -} // namespace testing - -#if !defined(GTEST_INTERNAL_DEPRECATED) - -// Internal Macro to mark an API deprecated, for googletest usage only -// Usage: class GTEST_INTERNAL_DEPRECATED(message) MyClass or -// GTEST_INTERNAL_DEPRECATED(message) myFunction(); Every usage of -// a deprecated entity will trigger a warning when compiled with -// `-Wdeprecated-declarations` option (clang, gcc, any __GNUC__ compiler). -// For msvc /W3 option will need to be used -// Note that for 'other' compilers this macro evaluates to nothing to prevent -// compilations errors. -#if defined(_MSC_VER) -#define GTEST_INTERNAL_DEPRECATED(message) __declspec(deprecated(message)) -#elif defined(__GNUC__) -#define GTEST_INTERNAL_DEPRECATED(message) __attribute__((deprecated(message))) -#else -#define GTEST_INTERNAL_DEPRECATED(message) -#endif - -#endif // !defined(GTEST_INTERNAL_DEPRECATED) - -#if GTEST_HAS_ABSL -// Always use absl::any for UniversalPrinter<> specializations if googletest -// is built with absl support. -#define GTEST_INTERNAL_HAS_ANY 1 -#include "absl/types/any.h" -namespace testing { -namespace internal { -using Any = ::absl::any; -} // namespace internal -} // namespace testing -#else -#ifdef __has_include -#if __has_include() && __cplusplus >= 201703L -// Otherwise for C++17 and higher use std::any for UniversalPrinter<> -// specializations. -#define GTEST_INTERNAL_HAS_ANY 1 -#include -namespace testing { -namespace internal { -using Any = ::std::any; -} // namespace internal -} // namespace testing -// The case where absl is configured NOT to alias std::any is not -// supported. -#endif // __has_include() && __cplusplus >= 201703L -#endif // __has_include -#endif // GTEST_HAS_ABSL - -#if GTEST_HAS_ABSL -// Always use absl::optional for UniversalPrinter<> specializations if -// googletest is built with absl support. -#define GTEST_INTERNAL_HAS_OPTIONAL 1 -#include "absl/types/optional.h" -namespace testing { -namespace internal { -template -using Optional = ::absl::optional; -inline ::absl::nullopt_t Nullopt() { return ::absl::nullopt; } -} // namespace internal -} // namespace testing -#else -#ifdef __has_include -#if __has_include() && __cplusplus >= 201703L -// Otherwise for C++17 and higher use std::optional for UniversalPrinter<> -// specializations. -#define GTEST_INTERNAL_HAS_OPTIONAL 1 -#include -namespace testing { -namespace internal { -template -using Optional = ::std::optional; -inline ::std::nullopt_t Nullopt() { return ::std::nullopt; } -} // namespace internal -} // namespace testing -// The case where absl is configured NOT to alias std::optional is not -// supported. -#endif // __has_include() && __cplusplus >= 201703L -#endif // __has_include -#endif // GTEST_HAS_ABSL - -#if GTEST_HAS_ABSL -// Always use absl::string_view for Matcher<> specializations if googletest -// is built with absl support. -#define GTEST_INTERNAL_HAS_STRING_VIEW 1 -#include "absl/strings/string_view.h" -namespace testing { -namespace internal { -using StringView = ::absl::string_view; -} // namespace internal -} // namespace testing -#else -#ifdef __has_include -#if __has_include() && __cplusplus >= 201703L -// Otherwise for C++17 and higher use std::string_view for Matcher<> -// specializations. -#define GTEST_INTERNAL_HAS_STRING_VIEW 1 -#include -namespace testing { -namespace internal { -using StringView = ::std::string_view; -} // namespace internal -} // namespace testing -// The case where absl is configured NOT to alias std::string_view is not -// supported. -#endif // __has_include() && __cplusplus >= 201703L -#endif // __has_include -#endif // GTEST_HAS_ABSL - -#if GTEST_HAS_ABSL -// Always use absl::variant for UniversalPrinter<> specializations if googletest -// is built with absl support. -#define GTEST_INTERNAL_HAS_VARIANT 1 -#include "absl/types/variant.h" -namespace testing { -namespace internal { -template -using Variant = ::absl::variant; -} // namespace internal -} // namespace testing -#else -#ifdef __has_include -#if __has_include() && __cplusplus >= 201703L -// Otherwise for C++17 and higher use std::variant for UniversalPrinter<> -// specializations. -#define GTEST_INTERNAL_HAS_VARIANT 1 -#include -namespace testing { -namespace internal { -template -using Variant = ::std::variant; -} // namespace internal -} // namespace testing -// The case where absl is configured NOT to alias std::variant is not supported. -#endif // __has_include() && __cplusplus >= 201703L -#endif // __has_include -#endif // GTEST_HAS_ABSL - -#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-string.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-string.h deleted file mode 100644 index cca2e1f2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-string.h +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The Google C++ Testing and Mocking Framework (Google Test) -// -// This header file declares the String class and functions used internally by -// Google Test. They are subject to change without notice. They should not used -// by code external to Google Test. -// -// This header file is #included by gtest-internal.h. -// It should not be #included by other files. - -// IWYU pragma: private, include "gtest/gtest.h" -// IWYU pragma: friend gtest/.* -// IWYU pragma: friend gmock/.* - -#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ -#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ - -#ifdef __BORLANDC__ -// string.h is not guaranteed to provide strcpy on C++ Builder. -#include -#endif - -#include - -#include -#include - -#include "gtest/internal/gtest-port.h" - -namespace testing { -namespace internal { - -// String - an abstract class holding static string utilities. -class GTEST_API_ String { - public: - // Static utility methods - - // Clones a 0-terminated C string, allocating memory using new. The - // caller is responsible for deleting the return value using - // delete[]. Returns the cloned string, or NULL if the input is - // NULL. - // - // This is different from strdup() in string.h, which allocates - // memory using malloc(). - static const char* CloneCString(const char* c_str); - -#if GTEST_OS_WINDOWS_MOBILE - // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be - // able to pass strings to Win32 APIs on CE we need to convert them - // to 'Unicode', UTF-16. - - // Creates a UTF-16 wide string from the given ANSI string, allocating - // memory using new. The caller is responsible for deleting the return - // value using delete[]. Returns the wide string, or NULL if the - // input is NULL. - // - // The wide string is created using the ANSI codepage (CP_ACP) to - // match the behaviour of the ANSI versions of Win32 calls and the - // C runtime. - static LPCWSTR AnsiToUtf16(const char* c_str); - - // Creates an ANSI string from the given wide string, allocating - // memory using new. The caller is responsible for deleting the return - // value using delete[]. Returns the ANSI string, or NULL if the - // input is NULL. - // - // The returned string is created using the ANSI codepage (CP_ACP) to - // match the behaviour of the ANSI versions of Win32 calls and the - // C runtime. - static const char* Utf16ToAnsi(LPCWSTR utf16_str); -#endif - - // Compares two C strings. Returns true if and only if they have the same - // content. - // - // Unlike strcmp(), this function can handle NULL argument(s). A - // NULL C string is considered different to any non-NULL C string, - // including the empty string. - static bool CStringEquals(const char* lhs, const char* rhs); - - // Converts a wide C string to a String using the UTF-8 encoding. - // NULL will be converted to "(null)". If an error occurred during - // the conversion, "(failed to convert from wide string)" is - // returned. - static std::string ShowWideCString(const wchar_t* wide_c_str); - - // Compares two wide C strings. Returns true if and only if they have the - // same content. - // - // Unlike wcscmp(), this function can handle NULL argument(s). A - // NULL C string is considered different to any non-NULL C string, - // including the empty string. - static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); - - // Compares two C strings, ignoring case. Returns true if and only if - // they have the same content. - // - // Unlike strcasecmp(), this function can handle NULL argument(s). - // A NULL C string is considered different to any non-NULL C string, - // including the empty string. - static bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs); - - // Compares two wide C strings, ignoring case. Returns true if and only if - // they have the same content. - // - // Unlike wcscasecmp(), this function can handle NULL argument(s). - // A NULL C string is considered different to any non-NULL wide C string, - // including the empty string. - // NB: The implementations on different platforms slightly differ. - // On windows, this method uses _wcsicmp which compares according to LC_CTYPE - // environment variable. On GNU platform this method uses wcscasecmp - // which compares according to LC_CTYPE category of the current locale. - // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the - // current locale. - static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, - const wchar_t* rhs); - - // Returns true if and only if the given string ends with the given suffix, - // ignoring case. Any string is considered to end with an empty suffix. - static bool EndsWithCaseInsensitive(const std::string& str, - const std::string& suffix); - - // Formats an int value as "%02d". - static std::string FormatIntWidth2(int value); // "%02d" for width == 2 - - // Formats an int value to given width with leading zeros. - static std::string FormatIntWidthN(int value, int width); - - // Formats an int value as "%X". - static std::string FormatHexInt(int value); - - // Formats an int value as "%X". - static std::string FormatHexUInt32(uint32_t value); - - // Formats a byte as "%02X". - static std::string FormatByte(unsigned char value); - - private: - String(); // Not meant to be instantiated. -}; // class String - -// Gets the content of the stringstream's buffer as an std::string. Each '\0' -// character in the buffer is replaced with "\\0". -GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); - -} // namespace internal -} // namespace testing - -#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-type-util.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-type-util.h deleted file mode 100644 index 6bc02a7d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/include/gtest/internal/gtest-type-util.h +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2008 Google Inc. -// All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Type utilities needed for implementing typed and type-parameterized -// tests. - -// IWYU pragma: private, include "gtest/gtest.h" -// IWYU pragma: friend gtest/.* -// IWYU pragma: friend gmock/.* - -#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ -#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ - -#include "gtest/internal/gtest-port.h" - -// #ifdef __GNUC__ is too general here. It is possible to use gcc without using -// libstdc++ (which is where cxxabi.h comes from). -#if GTEST_HAS_CXXABI_H_ -#include -#elif defined(__HP_aCC) -#include -#endif // GTEST_HASH_CXXABI_H_ - -namespace testing { -namespace internal { - -// Canonicalizes a given name with respect to the Standard C++ Library. -// This handles removing the inline namespace within `std` that is -// used by various standard libraries (e.g., `std::__1`). Names outside -// of namespace std are returned unmodified. -inline std::string CanonicalizeForStdLibVersioning(std::string s) { - static const char prefix[] = "std::__"; - if (s.compare(0, strlen(prefix), prefix) == 0) { - std::string::size_type end = s.find("::", strlen(prefix)); - if (end != s.npos) { - // Erase everything between the initial `std` and the second `::`. - s.erase(strlen("std"), end - strlen("std")); - } - } - return s; -} - -#if GTEST_HAS_RTTI -// GetTypeName(const std::type_info&) returns a human-readable name of type T. -inline std::string GetTypeName(const std::type_info& type) { - const char* const name = type.name(); -#if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) - int status = 0; - // gcc's implementation of typeid(T).name() mangles the type name, - // so we have to demangle it. -#if GTEST_HAS_CXXABI_H_ - using abi::__cxa_demangle; -#endif // GTEST_HAS_CXXABI_H_ - char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status); - const std::string name_str(status == 0 ? readable_name : name); - free(readable_name); - return CanonicalizeForStdLibVersioning(name_str); -#else - return name; -#endif // GTEST_HAS_CXXABI_H_ || __HP_aCC -} -#endif // GTEST_HAS_RTTI - -// GetTypeName() returns a human-readable name of type T if and only if -// RTTI is enabled, otherwise it returns a dummy type name. -// NB: This function is also used in Google Mock, so don't move it inside of -// the typed-test-only section below. -template -std::string GetTypeName() { -#if GTEST_HAS_RTTI - return GetTypeName(typeid(T)); -#else - return ""; -#endif // GTEST_HAS_RTTI -} - -// A unique type indicating an empty node -struct None {}; - -#define GTEST_TEMPLATE_ \ - template \ - class - -// The template "selector" struct TemplateSel is used to -// represent Tmpl, which must be a class template with one type -// parameter, as a type. TemplateSel::Bind::type is defined -// as the type Tmpl. This allows us to actually instantiate the -// template "selected" by TemplateSel. -// -// This trick is necessary for simulating typedef for class templates, -// which C++ doesn't support directly. -template -struct TemplateSel { - template - struct Bind { - typedef Tmpl type; - }; -}; - -#define GTEST_BIND_(TmplSel, T) TmplSel::template Bind::type - -template -struct Templates { - using Head = TemplateSel; - using Tail = Templates; -}; - -template -struct Templates { - using Head = TemplateSel; - using Tail = None; -}; - -// Tuple-like type lists -template -struct Types { - using Head = Head_; - using Tail = Types; -}; - -template -struct Types { - using Head = Head_; - using Tail = None; -}; - -// Helper metafunctions to tell apart a single type from types -// generated by ::testing::Types -template -struct ProxyTypeList { - using type = Types; -}; - -template -struct is_proxy_type_list : std::false_type {}; - -template -struct is_proxy_type_list> : std::true_type {}; - -// Generator which conditionally creates type lists. -// It recognizes if a requested type list should be created -// and prevents creating a new type list nested within another one. -template -struct GenerateTypeList { - private: - using proxy = typename std::conditional::value, T, - ProxyTypeList>::type; - - public: - using type = typename proxy::type; -}; - -} // namespace internal - -template -using Types = internal::ProxyTypeList; - -} // namespace testing - -#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-all.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-all.cc deleted file mode 100644 index 2a70ed88..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-all.cc +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// -// Google C++ Testing and Mocking Framework (Google Test) -// -// Sometimes it's desirable to build Google Test by compiling a single file. -// This file serves this purpose. - -// This line ensures that gtest.h can be compiled on its own, even -// when it's fused. -#include "gtest/gtest.h" - -// The following lines pull in the real gtest *.cc files. -#include "src/gtest-assertion-result.cc" -#include "src/gtest-death-test.cc" -#include "src/gtest-filepath.cc" -#include "src/gtest-matchers.cc" -#include "src/gtest-port.cc" -#include "src/gtest-printers.cc" -#include "src/gtest-test-part.cc" -#include "src/gtest-typed-test.cc" -#include "src/gtest.cc" diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-assertion-result.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-assertion-result.cc deleted file mode 100644 index f1c0b10d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-assertion-result.cc +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The Google C++ Testing and Mocking Framework (Google Test) -// -// This file defines the AssertionResult type. - -#include "gtest/gtest-assertion-result.h" - -#include -#include - -#include "gtest/gtest-message.h" - -namespace testing { - -// AssertionResult constructors. -// Used in EXPECT_TRUE/FALSE(assertion_result). -AssertionResult::AssertionResult(const AssertionResult& other) - : success_(other.success_), - message_(other.message_.get() != nullptr - ? new ::std::string(*other.message_) - : static_cast< ::std::string*>(nullptr)) {} - -// Swaps two AssertionResults. -void AssertionResult::swap(AssertionResult& other) { - using std::swap; - swap(success_, other.success_); - swap(message_, other.message_); -} - -// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. -AssertionResult AssertionResult::operator!() const { - AssertionResult negation(!success_); - if (message_.get() != nullptr) negation << *message_; - return negation; -} - -// Makes a successful assertion result. -AssertionResult AssertionSuccess() { return AssertionResult(true); } - -// Makes a failed assertion result. -AssertionResult AssertionFailure() { return AssertionResult(false); } - -// Makes a failed assertion result with the given failure message. -// Deprecated; use AssertionFailure() << message. -AssertionResult AssertionFailure(const Message& message) { - return AssertionFailure() << message; -} - -} // namespace testing diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-death-test.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-death-test.cc deleted file mode 100644 index e6abc627..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-death-test.cc +++ /dev/null @@ -1,1620 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// -// This file implements death tests. - -#include "gtest/gtest-death-test.h" - -#include -#include - -#include "gtest/internal/custom/gtest.h" -#include "gtest/internal/gtest-port.h" - -#if GTEST_HAS_DEATH_TEST - -#if GTEST_OS_MAC -#include -#endif // GTEST_OS_MAC - -#include -#include -#include - -#if GTEST_OS_LINUX -#include -#endif // GTEST_OS_LINUX - -#include - -#if GTEST_OS_WINDOWS -#include -#else -#include -#include -#endif // GTEST_OS_WINDOWS - -#if GTEST_OS_QNX -#include -#endif // GTEST_OS_QNX - -#if GTEST_OS_FUCHSIA -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif // GTEST_OS_FUCHSIA - -#endif // GTEST_HAS_DEATH_TEST - -#include "gtest/gtest-message.h" -#include "gtest/internal/gtest-string.h" -#include "src/gtest-internal-inl.h" - -namespace testing { - -// Constants. - -// The default death test style. -// -// This is defined in internal/gtest-port.h as "fast", but can be overridden by -// a definition in internal/custom/gtest-port.h. The recommended value, which is -// used internally at Google, is "threadsafe". -static const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE; - -} // namespace testing - -GTEST_DEFINE_string_( - death_test_style, - testing::internal::StringFromGTestEnv("death_test_style", - testing::kDefaultDeathTestStyle), - "Indicates how to run a death test in a forked child process: " - "\"threadsafe\" (child process re-executes the test binary " - "from the beginning, running only the specific death test) or " - "\"fast\" (child process runs the death test immediately " - "after forking)."); - -GTEST_DEFINE_bool_( - death_test_use_fork, - testing::internal::BoolFromGTestEnv("death_test_use_fork", false), - "Instructs to use fork()/_exit() instead of clone() in death tests. " - "Ignored and always uses fork() on POSIX systems where clone() is not " - "implemented. Useful when running under valgrind or similar tools if " - "those do not support clone(). Valgrind 3.3.1 will just fail if " - "it sees an unsupported combination of clone() flags. " - "It is not recommended to use this flag w/o valgrind though it will " - "work in 99% of the cases. Once valgrind is fixed, this flag will " - "most likely be removed."); - -GTEST_DEFINE_string_( - internal_run_death_test, "", - "Indicates the file, line number, temporal index of " - "the single death test to run, and a file descriptor to " - "which a success code may be sent, all separated by " - "the '|' characters. This flag is specified if and only if the " - "current process is a sub-process launched for running a thread-safe " - "death test. FOR INTERNAL USE ONLY."); - -namespace testing { - -#if GTEST_HAS_DEATH_TEST - -namespace internal { - -// Valid only for fast death tests. Indicates the code is running in the -// child process of a fast style death test. -#if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA -static bool g_in_fast_death_test_child = false; -#endif - -// Returns a Boolean value indicating whether the caller is currently -// executing in the context of the death test child process. Tools such as -// Valgrind heap checkers may need this to modify their behavior in death -// tests. IMPORTANT: This is an internal utility. Using it may break the -// implementation of death tests. User code MUST NOT use it. -bool InDeathTestChild() { -#if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA - - // On Windows and Fuchsia, death tests are thread-safe regardless of the value - // of the death_test_style flag. - return !GTEST_FLAG_GET(internal_run_death_test).empty(); - -#else - - if (GTEST_FLAG_GET(death_test_style) == "threadsafe") - return !GTEST_FLAG_GET(internal_run_death_test).empty(); - else - return g_in_fast_death_test_child; -#endif -} - -} // namespace internal - -// ExitedWithCode constructor. -ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {} - -// ExitedWithCode function-call operator. -bool ExitedWithCode::operator()(int exit_status) const { -#if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA - - return exit_status == exit_code_; - -#else - - return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; - -#endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA -} - -#if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA -// KilledBySignal constructor. -KilledBySignal::KilledBySignal(int signum) : signum_(signum) {} - -// KilledBySignal function-call operator. -bool KilledBySignal::operator()(int exit_status) const { -#if defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) - { - bool result; - if (GTEST_KILLED_BY_SIGNAL_OVERRIDE_(signum_, exit_status, &result)) { - return result; - } - } -#endif // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) - return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; -} -#endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA - -namespace internal { - -// Utilities needed for death tests. - -// Generates a textual description of a given exit code, in the format -// specified by wait(2). -static std::string ExitSummary(int exit_code) { - Message m; - -#if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA - - m << "Exited with exit status " << exit_code; - -#else - - if (WIFEXITED(exit_code)) { - m << "Exited with exit status " << WEXITSTATUS(exit_code); - } else if (WIFSIGNALED(exit_code)) { - m << "Terminated by signal " << WTERMSIG(exit_code); - } -#ifdef WCOREDUMP - if (WCOREDUMP(exit_code)) { - m << " (core dumped)"; - } -#endif -#endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA - - return m.GetString(); -} - -// Returns true if exit_status describes a process that was terminated -// by a signal, or exited normally with a nonzero exit code. -bool ExitedUnsuccessfully(int exit_status) { - return !ExitedWithCode(0)(exit_status); -} - -#if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA -// Generates a textual failure message when a death test finds more than -// one thread running, or cannot determine the number of threads, prior -// to executing the given statement. It is the responsibility of the -// caller not to pass a thread_count of 1. -static std::string DeathTestThreadWarning(size_t thread_count) { - Message msg; - msg << "Death tests use fork(), which is unsafe particularly" - << " in a threaded context. For this test, " << GTEST_NAME_ << " "; - if (thread_count == 0) { - msg << "couldn't detect the number of threads."; - } else { - msg << "detected " << thread_count << " threads."; - } - msg << " See " - "https://github.com/google/googletest/blob/master/docs/" - "advanced.md#death-tests-and-threads" - << " for more explanation and suggested solutions, especially if" - << " this is the last message you see before your test times out."; - return msg.GetString(); -} -#endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA - -// Flag characters for reporting a death test that did not die. -static const char kDeathTestLived = 'L'; -static const char kDeathTestReturned = 'R'; -static const char kDeathTestThrew = 'T'; -static const char kDeathTestInternalError = 'I'; - -#if GTEST_OS_FUCHSIA - -// File descriptor used for the pipe in the child process. -static const int kFuchsiaReadPipeFd = 3; - -#endif - -// An enumeration describing all of the possible ways that a death test can -// conclude. DIED means that the process died while executing the test -// code; LIVED means that process lived beyond the end of the test code; -// RETURNED means that the test statement attempted to execute a return -// statement, which is not allowed; THREW means that the test statement -// returned control by throwing an exception. IN_PROGRESS means the test -// has not yet concluded. -enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; - -// Routine for aborting the program which is safe to call from an -// exec-style death test child process, in which case the error -// message is propagated back to the parent process. Otherwise, the -// message is simply printed to stderr. In either case, the program -// then exits with status 1. -static void DeathTestAbort(const std::string& message) { - // On a POSIX system, this function may be called from a threadsafe-style - // death test child process, which operates on a very small stack. Use - // the heap for any additional non-minuscule memory requirements. - const InternalRunDeathTestFlag* const flag = - GetUnitTestImpl()->internal_run_death_test_flag(); - if (flag != nullptr) { - FILE* parent = posix::FDOpen(flag->write_fd(), "w"); - fputc(kDeathTestInternalError, parent); - fprintf(parent, "%s", message.c_str()); - fflush(parent); - _exit(1); - } else { - fprintf(stderr, "%s", message.c_str()); - fflush(stderr); - posix::Abort(); - } -} - -// A replacement for CHECK that calls DeathTestAbort if the assertion -// fails. -#define GTEST_DEATH_TEST_CHECK_(expression) \ - do { \ - if (!::testing::internal::IsTrue(expression)) { \ - DeathTestAbort(::std::string("CHECK failed: File ") + __FILE__ + \ - ", line " + \ - ::testing::internal::StreamableToString(__LINE__) + \ - ": " + #expression); \ - } \ - } while (::testing::internal::AlwaysFalse()) - -// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for -// evaluating any system call that fulfills two conditions: it must return -// -1 on failure, and set errno to EINTR when it is interrupted and -// should be tried again. The macro expands to a loop that repeatedly -// evaluates the expression as long as it evaluates to -1 and sets -// errno to EINTR. If the expression evaluates to -1 but errno is -// something other than EINTR, DeathTestAbort is called. -#define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ - do { \ - int gtest_retval; \ - do { \ - gtest_retval = (expression); \ - } while (gtest_retval == -1 && errno == EINTR); \ - if (gtest_retval == -1) { \ - DeathTestAbort(::std::string("CHECK failed: File ") + __FILE__ + \ - ", line " + \ - ::testing::internal::StreamableToString(__LINE__) + \ - ": " + #expression + " != -1"); \ - } \ - } while (::testing::internal::AlwaysFalse()) - -// Returns the message describing the last system error in errno. -std::string GetLastErrnoDescription() { - return errno == 0 ? "" : posix::StrError(errno); -} - -// This is called from a death test parent process to read a failure -// message from the death test child process and log it with the FATAL -// severity. On Windows, the message is read from a pipe handle. On other -// platforms, it is read from a file descriptor. -static void FailFromInternalError(int fd) { - Message error; - char buffer[256]; - int num_read; - - do { - while ((num_read = posix::Read(fd, buffer, 255)) > 0) { - buffer[num_read] = '\0'; - error << buffer; - } - } while (num_read == -1 && errno == EINTR); - - if (num_read == 0) { - GTEST_LOG_(FATAL) << error.GetString(); - } else { - const int last_error = errno; - GTEST_LOG_(FATAL) << "Error while reading death test internal: " - << GetLastErrnoDescription() << " [" << last_error << "]"; - } -} - -// Death test constructor. Increments the running death test count -// for the current test. -DeathTest::DeathTest() { - TestInfo* const info = GetUnitTestImpl()->current_test_info(); - if (info == nullptr) { - DeathTestAbort( - "Cannot run a death test outside of a TEST or " - "TEST_F construct"); - } -} - -// Creates and returns a death test by dispatching to the current -// death test factory. -bool DeathTest::Create(const char* statement, - Matcher matcher, const char* file, - int line, DeathTest** test) { - return GetUnitTestImpl()->death_test_factory()->Create( - statement, std::move(matcher), file, line, test); -} - -const char* DeathTest::LastMessage() { - return last_death_test_message_.c_str(); -} - -void DeathTest::set_last_death_test_message(const std::string& message) { - last_death_test_message_ = message; -} - -std::string DeathTest::last_death_test_message_; - -// Provides cross platform implementation for some death functionality. -class DeathTestImpl : public DeathTest { - protected: - DeathTestImpl(const char* a_statement, Matcher matcher) - : statement_(a_statement), - matcher_(std::move(matcher)), - spawned_(false), - status_(-1), - outcome_(IN_PROGRESS), - read_fd_(-1), - write_fd_(-1) {} - - // read_fd_ is expected to be closed and cleared by a derived class. - ~DeathTestImpl() override { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } - - void Abort(AbortReason reason) override; - bool Passed(bool status_ok) override; - - const char* statement() const { return statement_; } - bool spawned() const { return spawned_; } - void set_spawned(bool is_spawned) { spawned_ = is_spawned; } - int status() const { return status_; } - void set_status(int a_status) { status_ = a_status; } - DeathTestOutcome outcome() const { return outcome_; } - void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } - int read_fd() const { return read_fd_; } - void set_read_fd(int fd) { read_fd_ = fd; } - int write_fd() const { return write_fd_; } - void set_write_fd(int fd) { write_fd_ = fd; } - - // Called in the parent process only. Reads the result code of the death - // test child process via a pipe, interprets it to set the outcome_ - // member, and closes read_fd_. Outputs diagnostics and terminates in - // case of unexpected codes. - void ReadAndInterpretStatusByte(); - - // Returns stderr output from the child process. - virtual std::string GetErrorLogs(); - - private: - // The textual content of the code this object is testing. This class - // doesn't own this string and should not attempt to delete it. - const char* const statement_; - // A matcher that's expected to match the stderr output by the child process. - Matcher matcher_; - // True if the death test child process has been successfully spawned. - bool spawned_; - // The exit status of the child process. - int status_; - // How the death test concluded. - DeathTestOutcome outcome_; - // Descriptor to the read end of the pipe to the child process. It is - // always -1 in the child process. The child keeps its write end of the - // pipe in write_fd_. - int read_fd_; - // Descriptor to the child's write end of the pipe to the parent process. - // It is always -1 in the parent process. The parent keeps its end of the - // pipe in read_fd_. - int write_fd_; -}; - -// Called in the parent process only. Reads the result code of the death -// test child process via a pipe, interprets it to set the outcome_ -// member, and closes read_fd_. Outputs diagnostics and terminates in -// case of unexpected codes. -void DeathTestImpl::ReadAndInterpretStatusByte() { - char flag; - int bytes_read; - - // The read() here blocks until data is available (signifying the - // failure of the death test) or until the pipe is closed (signifying - // its success), so it's okay to call this in the parent before - // the child process has exited. - do { - bytes_read = posix::Read(read_fd(), &flag, 1); - } while (bytes_read == -1 && errno == EINTR); - - if (bytes_read == 0) { - set_outcome(DIED); - } else if (bytes_read == 1) { - switch (flag) { - case kDeathTestReturned: - set_outcome(RETURNED); - break; - case kDeathTestThrew: - set_outcome(THREW); - break; - case kDeathTestLived: - set_outcome(LIVED); - break; - case kDeathTestInternalError: - FailFromInternalError(read_fd()); // Does not return. - break; - default: - GTEST_LOG_(FATAL) << "Death test child process reported " - << "unexpected status byte (" - << static_cast(flag) << ")"; - } - } else { - GTEST_LOG_(FATAL) << "Read from death test child process failed: " - << GetLastErrnoDescription(); - } - GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); - set_read_fd(-1); -} - -std::string DeathTestImpl::GetErrorLogs() { return GetCapturedStderr(); } - -// Signals that the death test code which should have exited, didn't. -// Should be called only in a death test child process. -// Writes a status byte to the child's status file descriptor, then -// calls _exit(1). -void DeathTestImpl::Abort(AbortReason reason) { - // The parent process considers the death test to be a failure if - // it finds any data in our pipe. So, here we write a single flag byte - // to the pipe, then exit. - const char status_ch = reason == TEST_DID_NOT_DIE ? kDeathTestLived - : reason == TEST_THREW_EXCEPTION ? kDeathTestThrew - : kDeathTestReturned; - - GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); - // We are leaking the descriptor here because on some platforms (i.e., - // when built as Windows DLL), destructors of global objects will still - // run after calling _exit(). On such systems, write_fd_ will be - // indirectly closed from the destructor of UnitTestImpl, causing double - // close if it is also closed here. On debug configurations, double close - // may assert. As there are no in-process buffers to flush here, we are - // relying on the OS to close the descriptor after the process terminates - // when the destructors are not run. - _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) -} - -// Returns an indented copy of stderr output for a death test. -// This makes distinguishing death test output lines from regular log lines -// much easier. -static ::std::string FormatDeathTestOutput(const ::std::string& output) { - ::std::string ret; - for (size_t at = 0;;) { - const size_t line_end = output.find('\n', at); - ret += "[ DEATH ] "; - if (line_end == ::std::string::npos) { - ret += output.substr(at); - break; - } - ret += output.substr(at, line_end + 1 - at); - at = line_end + 1; - } - return ret; -} - -// Assesses the success or failure of a death test, using both private -// members which have previously been set, and one argument: -// -// Private data members: -// outcome: An enumeration describing how the death test -// concluded: DIED, LIVED, THREW, or RETURNED. The death test -// fails in the latter three cases. -// status: The exit status of the child process. On *nix, it is in the -// in the format specified by wait(2). On Windows, this is the -// value supplied to the ExitProcess() API or a numeric code -// of the exception that terminated the program. -// matcher_: A matcher that's expected to match the stderr output by the child -// process. -// -// Argument: -// status_ok: true if exit_status is acceptable in the context of -// this particular death test, which fails if it is false -// -// Returns true if and only if all of the above conditions are met. Otherwise, -// the first failing condition, in the order given above, is the one that is -// reported. Also sets the last death test message string. -bool DeathTestImpl::Passed(bool status_ok) { - if (!spawned()) return false; - - const std::string error_message = GetErrorLogs(); - - bool success = false; - Message buffer; - - buffer << "Death test: " << statement() << "\n"; - switch (outcome()) { - case LIVED: - buffer << " Result: failed to die.\n" - << " Error msg:\n" - << FormatDeathTestOutput(error_message); - break; - case THREW: - buffer << " Result: threw an exception.\n" - << " Error msg:\n" - << FormatDeathTestOutput(error_message); - break; - case RETURNED: - buffer << " Result: illegal return in test statement.\n" - << " Error msg:\n" - << FormatDeathTestOutput(error_message); - break; - case DIED: - if (status_ok) { - if (matcher_.Matches(error_message)) { - success = true; - } else { - std::ostringstream stream; - matcher_.DescribeTo(&stream); - buffer << " Result: died but not with expected error.\n" - << " Expected: " << stream.str() << "\n" - << "Actual msg:\n" - << FormatDeathTestOutput(error_message); - } - } else { - buffer << " Result: died but not with expected exit code:\n" - << " " << ExitSummary(status()) << "\n" - << "Actual msg:\n" - << FormatDeathTestOutput(error_message); - } - break; - case IN_PROGRESS: - default: - GTEST_LOG_(FATAL) - << "DeathTest::Passed somehow called before conclusion of test"; - } - - DeathTest::set_last_death_test_message(buffer.GetString()); - return success; -} - -#if GTEST_OS_WINDOWS -// WindowsDeathTest implements death tests on Windows. Due to the -// specifics of starting new processes on Windows, death tests there are -// always threadsafe, and Google Test considers the -// --gtest_death_test_style=fast setting to be equivalent to -// --gtest_death_test_style=threadsafe there. -// -// A few implementation notes: Like the Linux version, the Windows -// implementation uses pipes for child-to-parent communication. But due to -// the specifics of pipes on Windows, some extra steps are required: -// -// 1. The parent creates a communication pipe and stores handles to both -// ends of it. -// 2. The parent starts the child and provides it with the information -// necessary to acquire the handle to the write end of the pipe. -// 3. The child acquires the write end of the pipe and signals the parent -// using a Windows event. -// 4. Now the parent can release the write end of the pipe on its side. If -// this is done before step 3, the object's reference count goes down to -// 0 and it is destroyed, preventing the child from acquiring it. The -// parent now has to release it, or read operations on the read end of -// the pipe will not return when the child terminates. -// 5. The parent reads child's output through the pipe (outcome code and -// any possible error messages) from the pipe, and its stderr and then -// determines whether to fail the test. -// -// Note: to distinguish Win32 API calls from the local method and function -// calls, the former are explicitly resolved in the global namespace. -// -class WindowsDeathTest : public DeathTestImpl { - public: - WindowsDeathTest(const char* a_statement, Matcher matcher, - const char* file, int line) - : DeathTestImpl(a_statement, std::move(matcher)), - file_(file), - line_(line) {} - - // All of these virtual functions are inherited from DeathTest. - virtual int Wait(); - virtual TestRole AssumeRole(); - - private: - // The name of the file in which the death test is located. - const char* const file_; - // The line number on which the death test is located. - const int line_; - // Handle to the write end of the pipe to the child process. - AutoHandle write_handle_; - // Child process handle. - AutoHandle child_handle_; - // Event the child process uses to signal the parent that it has - // acquired the handle to the write end of the pipe. After seeing this - // event the parent can release its own handles to make sure its - // ReadFile() calls return when the child terminates. - AutoHandle event_handle_; -}; - -// Waits for the child in a death test to exit, returning its exit -// status, or 0 if no child process exists. As a side effect, sets the -// outcome data member. -int WindowsDeathTest::Wait() { - if (!spawned()) return 0; - - // Wait until the child either signals that it has acquired the write end - // of the pipe or it dies. - const HANDLE wait_handles[2] = {child_handle_.Get(), event_handle_.Get()}; - switch (::WaitForMultipleObjects(2, wait_handles, - FALSE, // Waits for any of the handles. - INFINITE)) { - case WAIT_OBJECT_0: - case WAIT_OBJECT_0 + 1: - break; - default: - GTEST_DEATH_TEST_CHECK_(false); // Should not get here. - } - - // The child has acquired the write end of the pipe or exited. - // We release the handle on our side and continue. - write_handle_.Reset(); - event_handle_.Reset(); - - ReadAndInterpretStatusByte(); - - // Waits for the child process to exit if it haven't already. This - // returns immediately if the child has already exited, regardless of - // whether previous calls to WaitForMultipleObjects synchronized on this - // handle or not. - GTEST_DEATH_TEST_CHECK_(WAIT_OBJECT_0 == - ::WaitForSingleObject(child_handle_.Get(), INFINITE)); - DWORD status_code; - GTEST_DEATH_TEST_CHECK_( - ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); - child_handle_.Reset(); - set_status(static_cast(status_code)); - return status(); -} - -// The AssumeRole process for a Windows death test. It creates a child -// process with the same executable as the current process to run the -// death test. The child process is given the --gtest_filter and -// --gtest_internal_run_death_test flags such that it knows to run the -// current death test only. -DeathTest::TestRole WindowsDeathTest::AssumeRole() { - const UnitTestImpl* const impl = GetUnitTestImpl(); - const InternalRunDeathTestFlag* const flag = - impl->internal_run_death_test_flag(); - const TestInfo* const info = impl->current_test_info(); - const int death_test_index = info->result()->death_test_count(); - - if (flag != nullptr) { - // ParseInternalRunDeathTestFlag() has performed all the necessary - // processing. - set_write_fd(flag->write_fd()); - return EXECUTE_TEST; - } - - // WindowsDeathTest uses an anonymous pipe to communicate results of - // a death test. - SECURITY_ATTRIBUTES handles_are_inheritable = {sizeof(SECURITY_ATTRIBUTES), - nullptr, TRUE}; - HANDLE read_handle, write_handle; - GTEST_DEATH_TEST_CHECK_(::CreatePipe(&read_handle, &write_handle, - &handles_are_inheritable, - 0) // Default buffer size. - != FALSE); - set_read_fd( - ::_open_osfhandle(reinterpret_cast(read_handle), O_RDONLY)); - write_handle_.Reset(write_handle); - event_handle_.Reset(::CreateEvent( - &handles_are_inheritable, - TRUE, // The event will automatically reset to non-signaled state. - FALSE, // The initial state is non-signalled. - nullptr)); // The even is unnamed. - GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != nullptr); - const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + - "filter=" + info->test_suite_name() + "." + - info->name(); - const std::string internal_flag = - std::string("--") + GTEST_FLAG_PREFIX_ + - "internal_run_death_test=" + file_ + "|" + StreamableToString(line_) + - "|" + StreamableToString(death_test_index) + "|" + - StreamableToString(static_cast(::GetCurrentProcessId())) + - // size_t has the same width as pointers on both 32-bit and 64-bit - // Windows platforms. - // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. - "|" + StreamableToString(reinterpret_cast(write_handle)) + "|" + - StreamableToString(reinterpret_cast(event_handle_.Get())); - - char executable_path[_MAX_PATH + 1]; // NOLINT - GTEST_DEATH_TEST_CHECK_(_MAX_PATH + 1 != ::GetModuleFileNameA(nullptr, - executable_path, - _MAX_PATH)); - - std::string command_line = std::string(::GetCommandLineA()) + " " + - filter_flag + " \"" + internal_flag + "\""; - - DeathTest::set_last_death_test_message(""); - - CaptureStderr(); - // Flush the log buffers since the log streams are shared with the child. - FlushInfoLog(); - - // The child process will share the standard handles with the parent. - STARTUPINFOA startup_info; - memset(&startup_info, 0, sizeof(STARTUPINFO)); - startup_info.dwFlags = STARTF_USESTDHANDLES; - startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); - startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); - startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); - - PROCESS_INFORMATION process_info; - GTEST_DEATH_TEST_CHECK_( - ::CreateProcessA( - executable_path, const_cast(command_line.c_str()), - nullptr, // Returned process handle is not inheritable. - nullptr, // Returned thread handle is not inheritable. - TRUE, // Child inherits all inheritable handles (for write_handle_). - 0x0, // Default creation flags. - nullptr, // Inherit the parent's environment. - UnitTest::GetInstance()->original_working_dir(), &startup_info, - &process_info) != FALSE); - child_handle_.Reset(process_info.hProcess); - ::CloseHandle(process_info.hThread); - set_spawned(true); - return OVERSEE_TEST; -} - -#elif GTEST_OS_FUCHSIA - -class FuchsiaDeathTest : public DeathTestImpl { - public: - FuchsiaDeathTest(const char* a_statement, Matcher matcher, - const char* file, int line) - : DeathTestImpl(a_statement, std::move(matcher)), - file_(file), - line_(line) {} - - // All of these virtual functions are inherited from DeathTest. - int Wait() override; - TestRole AssumeRole() override; - std::string GetErrorLogs() override; - - private: - // The name of the file in which the death test is located. - const char* const file_; - // The line number on which the death test is located. - const int line_; - // The stderr data captured by the child process. - std::string captured_stderr_; - - zx::process child_process_; - zx::channel exception_channel_; - zx::socket stderr_socket_; -}; - -// Utility class for accumulating command-line arguments. -class Arguments { - public: - Arguments() { args_.push_back(nullptr); } - - ~Arguments() { - for (std::vector::iterator i = args_.begin(); i != args_.end(); - ++i) { - free(*i); - } - } - void AddArgument(const char* argument) { - args_.insert(args_.end() - 1, posix::StrDup(argument)); - } - - template - void AddArguments(const ::std::vector& arguments) { - for (typename ::std::vector::const_iterator i = arguments.begin(); - i != arguments.end(); ++i) { - args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); - } - } - char* const* Argv() { return &args_[0]; } - - int size() { return static_cast(args_.size()) - 1; } - - private: - std::vector args_; -}; - -// Waits for the child in a death test to exit, returning its exit -// status, or 0 if no child process exists. As a side effect, sets the -// outcome data member. -int FuchsiaDeathTest::Wait() { - const int kProcessKey = 0; - const int kSocketKey = 1; - const int kExceptionKey = 2; - - if (!spawned()) return 0; - - // Create a port to wait for socket/task/exception events. - zx_status_t status_zx; - zx::port port; - status_zx = zx::port::create(0, &port); - GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); - - // Register to wait for the child process to terminate. - status_zx = - child_process_.wait_async(port, kProcessKey, ZX_PROCESS_TERMINATED, 0); - GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); - - // Register to wait for the socket to be readable or closed. - status_zx = stderr_socket_.wait_async( - port, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED, 0); - GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); - - // Register to wait for an exception. - status_zx = exception_channel_.wait_async(port, kExceptionKey, - ZX_CHANNEL_READABLE, 0); - GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); - - bool process_terminated = false; - bool socket_closed = false; - do { - zx_port_packet_t packet = {}; - status_zx = port.wait(zx::time::infinite(), &packet); - GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); - - if (packet.key == kExceptionKey) { - // Process encountered an exception. Kill it directly rather than - // letting other handlers process the event. We will get a kProcessKey - // event when the process actually terminates. - status_zx = child_process_.kill(); - GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); - } else if (packet.key == kProcessKey) { - // Process terminated. - GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type)); - GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_PROCESS_TERMINATED); - process_terminated = true; - } else if (packet.key == kSocketKey) { - GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type)); - if (packet.signal.observed & ZX_SOCKET_READABLE) { - // Read data from the socket. - constexpr size_t kBufferSize = 1024; - do { - size_t old_length = captured_stderr_.length(); - size_t bytes_read = 0; - captured_stderr_.resize(old_length + kBufferSize); - status_zx = - stderr_socket_.read(0, &captured_stderr_.front() + old_length, - kBufferSize, &bytes_read); - captured_stderr_.resize(old_length + bytes_read); - } while (status_zx == ZX_OK); - if (status_zx == ZX_ERR_PEER_CLOSED) { - socket_closed = true; - } else { - GTEST_DEATH_TEST_CHECK_(status_zx == ZX_ERR_SHOULD_WAIT); - status_zx = stderr_socket_.wait_async( - port, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED, 0); - GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); - } - } else { - GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_SOCKET_PEER_CLOSED); - socket_closed = true; - } - } - } while (!process_terminated && !socket_closed); - - ReadAndInterpretStatusByte(); - - zx_info_process_t buffer; - status_zx = child_process_.get_info(ZX_INFO_PROCESS, &buffer, sizeof(buffer), - nullptr, nullptr); - GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); - - GTEST_DEATH_TEST_CHECK_(buffer.flags & ZX_INFO_PROCESS_FLAG_EXITED); - set_status(static_cast(buffer.return_code)); - return status(); -} - -// The AssumeRole process for a Fuchsia death test. It creates a child -// process with the same executable as the current process to run the -// death test. The child process is given the --gtest_filter and -// --gtest_internal_run_death_test flags such that it knows to run the -// current death test only. -DeathTest::TestRole FuchsiaDeathTest::AssumeRole() { - const UnitTestImpl* const impl = GetUnitTestImpl(); - const InternalRunDeathTestFlag* const flag = - impl->internal_run_death_test_flag(); - const TestInfo* const info = impl->current_test_info(); - const int death_test_index = info->result()->death_test_count(); - - if (flag != nullptr) { - // ParseInternalRunDeathTestFlag() has performed all the necessary - // processing. - set_write_fd(kFuchsiaReadPipeFd); - return EXECUTE_TEST; - } - - // Flush the log buffers since the log streams are shared with the child. - FlushInfoLog(); - - // Build the child process command line. - const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + - "filter=" + info->test_suite_name() + "." + - info->name(); - const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ + - kInternalRunDeathTestFlag + "=" + file_ + - "|" + StreamableToString(line_) + "|" + - StreamableToString(death_test_index); - Arguments args; - args.AddArguments(GetInjectableArgvs()); - args.AddArgument(filter_flag.c_str()); - args.AddArgument(internal_flag.c_str()); - - // Build the pipe for communication with the child. - zx_status_t status; - zx_handle_t child_pipe_handle; - int child_pipe_fd; - status = fdio_pipe_half(&child_pipe_fd, &child_pipe_handle); - GTEST_DEATH_TEST_CHECK_(status == ZX_OK); - set_read_fd(child_pipe_fd); - - // Set the pipe handle for the child. - fdio_spawn_action_t spawn_actions[2] = {}; - fdio_spawn_action_t* add_handle_action = &spawn_actions[0]; - add_handle_action->action = FDIO_SPAWN_ACTION_ADD_HANDLE; - add_handle_action->h.id = PA_HND(PA_FD, kFuchsiaReadPipeFd); - add_handle_action->h.handle = child_pipe_handle; - - // Create a socket pair will be used to receive the child process' stderr. - zx::socket stderr_producer_socket; - status = zx::socket::create(0, &stderr_producer_socket, &stderr_socket_); - GTEST_DEATH_TEST_CHECK_(status >= 0); - int stderr_producer_fd = -1; - status = - fdio_fd_create(stderr_producer_socket.release(), &stderr_producer_fd); - GTEST_DEATH_TEST_CHECK_(status >= 0); - - // Make the stderr socket nonblocking. - GTEST_DEATH_TEST_CHECK_(fcntl(stderr_producer_fd, F_SETFL, 0) == 0); - - fdio_spawn_action_t* add_stderr_action = &spawn_actions[1]; - add_stderr_action->action = FDIO_SPAWN_ACTION_CLONE_FD; - add_stderr_action->fd.local_fd = stderr_producer_fd; - add_stderr_action->fd.target_fd = STDERR_FILENO; - - // Create a child job. - zx_handle_t child_job = ZX_HANDLE_INVALID; - status = zx_job_create(zx_job_default(), 0, &child_job); - GTEST_DEATH_TEST_CHECK_(status == ZX_OK); - zx_policy_basic_t policy; - policy.condition = ZX_POL_NEW_ANY; - policy.policy = ZX_POL_ACTION_ALLOW; - status = zx_job_set_policy(child_job, ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC, - &policy, 1); - GTEST_DEATH_TEST_CHECK_(status == ZX_OK); - - // Create an exception channel attached to the |child_job|, to allow - // us to suppress the system default exception handler from firing. - status = zx_task_create_exception_channel( - child_job, 0, exception_channel_.reset_and_get_address()); - GTEST_DEATH_TEST_CHECK_(status == ZX_OK); - - // Spawn the child process. - status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, args.Argv()[0], - args.Argv(), nullptr, 2, spawn_actions, - child_process_.reset_and_get_address(), nullptr); - GTEST_DEATH_TEST_CHECK_(status == ZX_OK); - - set_spawned(true); - return OVERSEE_TEST; -} - -std::string FuchsiaDeathTest::GetErrorLogs() { return captured_stderr_; } - -#else // We are neither on Windows, nor on Fuchsia. - -// ForkingDeathTest provides implementations for most of the abstract -// methods of the DeathTest interface. Only the AssumeRole method is -// left undefined. -class ForkingDeathTest : public DeathTestImpl { - public: - ForkingDeathTest(const char* statement, Matcher matcher); - - // All of these virtual functions are inherited from DeathTest. - int Wait() override; - - protected: - void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } - - private: - // PID of child process during death test; 0 in the child process itself. - pid_t child_pid_; -}; - -// Constructs a ForkingDeathTest. -ForkingDeathTest::ForkingDeathTest(const char* a_statement, - Matcher matcher) - : DeathTestImpl(a_statement, std::move(matcher)), child_pid_(-1) {} - -// Waits for the child in a death test to exit, returning its exit -// status, or 0 if no child process exists. As a side effect, sets the -// outcome data member. -int ForkingDeathTest::Wait() { - if (!spawned()) return 0; - - ReadAndInterpretStatusByte(); - - int status_value; - GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); - set_status(status_value); - return status_value; -} - -// A concrete death test class that forks, then immediately runs the test -// in the child process. -class NoExecDeathTest : public ForkingDeathTest { - public: - NoExecDeathTest(const char* a_statement, Matcher matcher) - : ForkingDeathTest(a_statement, std::move(matcher)) {} - TestRole AssumeRole() override; -}; - -// The AssumeRole process for a fork-and-run death test. It implements a -// straightforward fork, with a simple pipe to transmit the status byte. -DeathTest::TestRole NoExecDeathTest::AssumeRole() { - const size_t thread_count = GetThreadCount(); - if (thread_count != 1) { - GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); - } - - int pipe_fd[2]; - GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); - - DeathTest::set_last_death_test_message(""); - CaptureStderr(); - // When we fork the process below, the log file buffers are copied, but the - // file descriptors are shared. We flush all log files here so that closing - // the file descriptors in the child process doesn't throw off the - // synchronization between descriptors and buffers in the parent process. - // This is as close to the fork as possible to avoid a race condition in case - // there are multiple threads running before the death test, and another - // thread writes to the log file. - FlushInfoLog(); - - const pid_t child_pid = fork(); - GTEST_DEATH_TEST_CHECK_(child_pid != -1); - set_child_pid(child_pid); - if (child_pid == 0) { - GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); - set_write_fd(pipe_fd[1]); - // Redirects all logging to stderr in the child process to prevent - // concurrent writes to the log files. We capture stderr in the parent - // process and append the child process' output to a log. - LogToStderr(); - // Event forwarding to the listeners of event listener API mush be shut - // down in death test subprocesses. - GetUnitTestImpl()->listeners()->SuppressEventForwarding(); - g_in_fast_death_test_child = true; - return EXECUTE_TEST; - } else { - GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); - set_read_fd(pipe_fd[0]); - set_spawned(true); - return OVERSEE_TEST; - } -} - -// A concrete death test class that forks and re-executes the main -// program from the beginning, with command-line flags set that cause -// only this specific death test to be run. -class ExecDeathTest : public ForkingDeathTest { - public: - ExecDeathTest(const char* a_statement, Matcher matcher, - const char* file, int line) - : ForkingDeathTest(a_statement, std::move(matcher)), - file_(file), - line_(line) {} - TestRole AssumeRole() override; - - private: - static ::std::vector GetArgvsForDeathTestChildProcess() { - ::std::vector args = GetInjectableArgvs(); -#if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) - ::std::vector extra_args = - GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_(); - args.insert(args.end(), extra_args.begin(), extra_args.end()); -#endif // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) - return args; - } - // The name of the file in which the death test is located. - const char* const file_; - // The line number on which the death test is located. - const int line_; -}; - -// Utility class for accumulating command-line arguments. -class Arguments { - public: - Arguments() { args_.push_back(nullptr); } - - ~Arguments() { - for (std::vector::iterator i = args_.begin(); i != args_.end(); - ++i) { - free(*i); - } - } - void AddArgument(const char* argument) { - args_.insert(args_.end() - 1, posix::StrDup(argument)); - } - - template - void AddArguments(const ::std::vector& arguments) { - for (typename ::std::vector::const_iterator i = arguments.begin(); - i != arguments.end(); ++i) { - args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); - } - } - char* const* Argv() { return &args_[0]; } - - private: - std::vector args_; -}; - -// A struct that encompasses the arguments to the child process of a -// threadsafe-style death test process. -struct ExecDeathTestArgs { - char* const* argv; // Command-line arguments for the child's call to exec - int close_fd; // File descriptor to close; the read end of a pipe -}; - -#if GTEST_OS_QNX -extern "C" char** environ; -#else // GTEST_OS_QNX -// The main function for a threadsafe-style death test child process. -// This function is called in a clone()-ed process and thus must avoid -// any potentially unsafe operations like malloc or libc functions. -static int ExecDeathTestChildMain(void* child_arg) { - ExecDeathTestArgs* const args = static_cast(child_arg); - GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); - - // We need to execute the test program in the same environment where - // it was originally invoked. Therefore we change to the original - // working directory first. - const char* const original_dir = - UnitTest::GetInstance()->original_working_dir(); - // We can safely call chdir() as it's a direct system call. - if (chdir(original_dir) != 0) { - DeathTestAbort(std::string("chdir(\"") + original_dir + - "\") failed: " + GetLastErrnoDescription()); - return EXIT_FAILURE; - } - - // We can safely call execv() as it's almost a direct system call. We - // cannot use execvp() as it's a libc function and thus potentially - // unsafe. Since execv() doesn't search the PATH, the user must - // invoke the test program via a valid path that contains at least - // one path separator. - execv(args->argv[0], args->argv); - DeathTestAbort(std::string("execv(") + args->argv[0] + ", ...) in " + - original_dir + " failed: " + GetLastErrnoDescription()); - return EXIT_FAILURE; -} -#endif // GTEST_OS_QNX - -#if GTEST_HAS_CLONE -// Two utility routines that together determine the direction the stack -// grows. -// This could be accomplished more elegantly by a single recursive -// function, but we want to guard against the unlikely possibility of -// a smart compiler optimizing the recursion away. -// -// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining -// StackLowerThanAddress into StackGrowsDown, which then doesn't give -// correct answer. -static void StackLowerThanAddress(const void* ptr, - bool* result) GTEST_NO_INLINE_; -// Make sure sanitizers do not tamper with the stack here. -// Ideally, we want to use `__builtin_frame_address` instead of a local variable -// address with sanitizer disabled, but it does not work when the -// compiler optimizes the stack frame out, which happens on PowerPC targets. -// HWAddressSanitizer add a random tag to the MSB of the local variable address, -// making comparison result unpredictable. -GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ -GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ -static void StackLowerThanAddress(const void* ptr, bool* result) { - int dummy = 0; - *result = std::less()(&dummy, ptr); -} - -// Make sure AddressSanitizer does not tamper with the stack here. -GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ -GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ -static bool StackGrowsDown() { - int dummy = 0; - bool result; - StackLowerThanAddress(&dummy, &result); - return result; -} -#endif // GTEST_HAS_CLONE - -// Spawns a child process with the same executable as the current process in -// a thread-safe manner and instructs it to run the death test. The -// implementation uses fork(2) + exec. On systems where clone(2) is -// available, it is used instead, being slightly more thread-safe. On QNX, -// fork supports only single-threaded environments, so this function uses -// spawn(2) there instead. The function dies with an error message if -// anything goes wrong. -static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { - ExecDeathTestArgs args = {argv, close_fd}; - pid_t child_pid = -1; - -#if GTEST_OS_QNX - // Obtains the current directory and sets it to be closed in the child - // process. - const int cwd_fd = open(".", O_RDONLY); - GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); - GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); - // We need to execute the test program in the same environment where - // it was originally invoked. Therefore we change to the original - // working directory first. - const char* const original_dir = - UnitTest::GetInstance()->original_working_dir(); - // We can safely call chdir() as it's a direct system call. - if (chdir(original_dir) != 0) { - DeathTestAbort(std::string("chdir(\"") + original_dir + - "\") failed: " + GetLastErrnoDescription()); - return EXIT_FAILURE; - } - - int fd_flags; - // Set close_fd to be closed after spawn. - GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); - GTEST_DEATH_TEST_CHECK_SYSCALL_( - fcntl(close_fd, F_SETFD, fd_flags | FD_CLOEXEC)); - struct inheritance inherit = {0}; - // spawn is a system call. - child_pid = spawn(args.argv[0], 0, nullptr, &inherit, args.argv, environ); - // Restores the current working directory. - GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); - GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); - -#else // GTEST_OS_QNX -#if GTEST_OS_LINUX - // When a SIGPROF signal is received while fork() or clone() are executing, - // the process may hang. To avoid this, we ignore SIGPROF here and re-enable - // it after the call to fork()/clone() is complete. - struct sigaction saved_sigprof_action; - struct sigaction ignore_sigprof_action; - memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); - sigemptyset(&ignore_sigprof_action.sa_mask); - ignore_sigprof_action.sa_handler = SIG_IGN; - GTEST_DEATH_TEST_CHECK_SYSCALL_( - sigaction(SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); -#endif // GTEST_OS_LINUX - -#if GTEST_HAS_CLONE - const bool use_fork = GTEST_FLAG_GET(death_test_use_fork); - - if (!use_fork) { - static const bool stack_grows_down = StackGrowsDown(); - const auto stack_size = static_cast(getpagesize() * 2); - // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. - void* const stack = mmap(nullptr, stack_size, PROT_READ | PROT_WRITE, - MAP_ANON | MAP_PRIVATE, -1, 0); - GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); - - // Maximum stack alignment in bytes: For a downward-growing stack, this - // amount is subtracted from size of the stack space to get an address - // that is within the stack space and is aligned on all systems we care - // about. As far as I know there is no ABI with stack alignment greater - // than 64. We assume stack and stack_size already have alignment of - // kMaxStackAlignment. - const size_t kMaxStackAlignment = 64; - void* const stack_top = - static_cast(stack) + - (stack_grows_down ? stack_size - kMaxStackAlignment : 0); - GTEST_DEATH_TEST_CHECK_( - static_cast(stack_size) > kMaxStackAlignment && - reinterpret_cast(stack_top) % kMaxStackAlignment == 0); - - child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); - - GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); - } -#else - const bool use_fork = true; -#endif // GTEST_HAS_CLONE - - if (use_fork && (child_pid = fork()) == 0) { - ExecDeathTestChildMain(&args); - _exit(0); - } -#endif // GTEST_OS_QNX -#if GTEST_OS_LINUX - GTEST_DEATH_TEST_CHECK_SYSCALL_( - sigaction(SIGPROF, &saved_sigprof_action, nullptr)); -#endif // GTEST_OS_LINUX - - GTEST_DEATH_TEST_CHECK_(child_pid != -1); - return child_pid; -} - -// The AssumeRole process for a fork-and-exec death test. It re-executes the -// main program from the beginning, setting the --gtest_filter -// and --gtest_internal_run_death_test flags to cause only the current -// death test to be re-run. -DeathTest::TestRole ExecDeathTest::AssumeRole() { - const UnitTestImpl* const impl = GetUnitTestImpl(); - const InternalRunDeathTestFlag* const flag = - impl->internal_run_death_test_flag(); - const TestInfo* const info = impl->current_test_info(); - const int death_test_index = info->result()->death_test_count(); - - if (flag != nullptr) { - set_write_fd(flag->write_fd()); - return EXECUTE_TEST; - } - - int pipe_fd[2]; - GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); - // Clear the close-on-exec flag on the write end of the pipe, lest - // it be closed when the child process does an exec: - GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); - - const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + - "filter=" + info->test_suite_name() + "." + - info->name(); - const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ + - "internal_run_death_test=" + file_ + "|" + - StreamableToString(line_) + "|" + - StreamableToString(death_test_index) + "|" + - StreamableToString(pipe_fd[1]); - Arguments args; - args.AddArguments(GetArgvsForDeathTestChildProcess()); - args.AddArgument(filter_flag.c_str()); - args.AddArgument(internal_flag.c_str()); - - DeathTest::set_last_death_test_message(""); - - CaptureStderr(); - // See the comment in NoExecDeathTest::AssumeRole for why the next line - // is necessary. - FlushInfoLog(); - - const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); - GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); - set_child_pid(child_pid); - set_read_fd(pipe_fd[0]); - set_spawned(true); - return OVERSEE_TEST; -} - -#endif // !GTEST_OS_WINDOWS - -// Creates a concrete DeathTest-derived class that depends on the -// --gtest_death_test_style flag, and sets the pointer pointed to -// by the "test" argument to its address. If the test should be -// skipped, sets that pointer to NULL. Returns true, unless the -// flag is set to an invalid value. -bool DefaultDeathTestFactory::Create(const char* statement, - Matcher matcher, - const char* file, int line, - DeathTest** test) { - UnitTestImpl* const impl = GetUnitTestImpl(); - const InternalRunDeathTestFlag* const flag = - impl->internal_run_death_test_flag(); - const int death_test_index = - impl->current_test_info()->increment_death_test_count(); - - if (flag != nullptr) { - if (death_test_index > flag->index()) { - DeathTest::set_last_death_test_message( - "Death test count (" + StreamableToString(death_test_index) + - ") somehow exceeded expected maximum (" + - StreamableToString(flag->index()) + ")"); - return false; - } - - if (!(flag->file() == file && flag->line() == line && - flag->index() == death_test_index)) { - *test = nullptr; - return true; - } - } - -#if GTEST_OS_WINDOWS - - if (GTEST_FLAG_GET(death_test_style) == "threadsafe" || - GTEST_FLAG_GET(death_test_style) == "fast") { - *test = new WindowsDeathTest(statement, std::move(matcher), file, line); - } - -#elif GTEST_OS_FUCHSIA - - if (GTEST_FLAG_GET(death_test_style) == "threadsafe" || - GTEST_FLAG_GET(death_test_style) == "fast") { - *test = new FuchsiaDeathTest(statement, std::move(matcher), file, line); - } - -#else - - if (GTEST_FLAG_GET(death_test_style) == "threadsafe") { - *test = new ExecDeathTest(statement, std::move(matcher), file, line); - } else if (GTEST_FLAG_GET(death_test_style) == "fast") { - *test = new NoExecDeathTest(statement, std::move(matcher)); - } - -#endif // GTEST_OS_WINDOWS - - else { // NOLINT - this is more readable than unbalanced brackets inside #if. - DeathTest::set_last_death_test_message("Unknown death test style \"" + - GTEST_FLAG_GET(death_test_style) + - "\" encountered"); - return false; - } - - return true; -} - -#if GTEST_OS_WINDOWS -// Recreates the pipe and event handles from the provided parameters, -// signals the event, and returns a file descriptor wrapped around the pipe -// handle. This function is called in the child process only. -static int GetStatusFileDescriptor(unsigned int parent_process_id, - size_t write_handle_as_size_t, - size_t event_handle_as_size_t) { - AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, - FALSE, // Non-inheritable. - parent_process_id)); - if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { - DeathTestAbort("Unable to open parent process " + - StreamableToString(parent_process_id)); - } - - GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); - - const HANDLE write_handle = reinterpret_cast(write_handle_as_size_t); - HANDLE dup_write_handle; - - // The newly initialized handle is accessible only in the parent - // process. To obtain one accessible within the child, we need to use - // DuplicateHandle. - if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, - ::GetCurrentProcess(), &dup_write_handle, - 0x0, // Requested privileges ignored since - // DUPLICATE_SAME_ACCESS is used. - FALSE, // Request non-inheritable handler. - DUPLICATE_SAME_ACCESS)) { - DeathTestAbort("Unable to duplicate the pipe handle " + - StreamableToString(write_handle_as_size_t) + - " from the parent process " + - StreamableToString(parent_process_id)); - } - - const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); - HANDLE dup_event_handle; - - if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, - ::GetCurrentProcess(), &dup_event_handle, 0x0, FALSE, - DUPLICATE_SAME_ACCESS)) { - DeathTestAbort("Unable to duplicate the event handle " + - StreamableToString(event_handle_as_size_t) + - " from the parent process " + - StreamableToString(parent_process_id)); - } - - const int write_fd = - ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); - if (write_fd == -1) { - DeathTestAbort("Unable to convert pipe handle " + - StreamableToString(write_handle_as_size_t) + - " to a file descriptor"); - } - - // Signals the parent that the write end of the pipe has been acquired - // so the parent can release its own write end. - ::SetEvent(dup_event_handle); - - return write_fd; -} -#endif // GTEST_OS_WINDOWS - -// Returns a newly created InternalRunDeathTestFlag object with fields -// initialized from the GTEST_FLAG(internal_run_death_test) flag if -// the flag is specified; otherwise returns NULL. -InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { - if (GTEST_FLAG_GET(internal_run_death_test) == "") return nullptr; - - // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we - // can use it here. - int line = -1; - int index = -1; - ::std::vector< ::std::string> fields; - SplitString(GTEST_FLAG_GET(internal_run_death_test), '|', &fields); - int write_fd = -1; - -#if GTEST_OS_WINDOWS - - unsigned int parent_process_id = 0; - size_t write_handle_as_size_t = 0; - size_t event_handle_as_size_t = 0; - - if (fields.size() != 6 || !ParseNaturalNumber(fields[1], &line) || - !ParseNaturalNumber(fields[2], &index) || - !ParseNaturalNumber(fields[3], &parent_process_id) || - !ParseNaturalNumber(fields[4], &write_handle_as_size_t) || - !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { - DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + - GTEST_FLAG_GET(internal_run_death_test)); - } - write_fd = GetStatusFileDescriptor(parent_process_id, write_handle_as_size_t, - event_handle_as_size_t); - -#elif GTEST_OS_FUCHSIA - - if (fields.size() != 3 || !ParseNaturalNumber(fields[1], &line) || - !ParseNaturalNumber(fields[2], &index)) { - DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + - GTEST_FLAG_GET(internal_run_death_test)); - } - -#else - - if (fields.size() != 4 || !ParseNaturalNumber(fields[1], &line) || - !ParseNaturalNumber(fields[2], &index) || - !ParseNaturalNumber(fields[3], &write_fd)) { - DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + - GTEST_FLAG_GET(internal_run_death_test)); - } - -#endif // GTEST_OS_WINDOWS - - return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); -} - -} // namespace internal - -#endif // GTEST_HAS_DEATH_TEST - -} // namespace testing diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-filepath.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-filepath.cc deleted file mode 100644 index f6ee90cd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-filepath.cc +++ /dev/null @@ -1,367 +0,0 @@ -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "gtest/internal/gtest-filepath.h" - -#include - -#include "gtest/gtest-message.h" -#include "gtest/internal/gtest-port.h" - -#if GTEST_OS_WINDOWS_MOBILE -#include -#elif GTEST_OS_WINDOWS -#include -#include -#else -#include - -#include // Some Linux distributions define PATH_MAX here. -#endif // GTEST_OS_WINDOWS_MOBILE - -#include "gtest/internal/gtest-string.h" - -#if GTEST_OS_WINDOWS -#define GTEST_PATH_MAX_ _MAX_PATH -#elif defined(PATH_MAX) -#define GTEST_PATH_MAX_ PATH_MAX -#elif defined(_XOPEN_PATH_MAX) -#define GTEST_PATH_MAX_ _XOPEN_PATH_MAX -#else -#define GTEST_PATH_MAX_ _POSIX_PATH_MAX -#endif // GTEST_OS_WINDOWS - -namespace testing { -namespace internal { - -#if GTEST_OS_WINDOWS -// On Windows, '\\' is the standard path separator, but many tools and the -// Windows API also accept '/' as an alternate path separator. Unless otherwise -// noted, a file path can contain either kind of path separators, or a mixture -// of them. -const char kPathSeparator = '\\'; -const char kAlternatePathSeparator = '/'; -const char kAlternatePathSeparatorString[] = "/"; -#if GTEST_OS_WINDOWS_MOBILE -// Windows CE doesn't have a current directory. You should not use -// the current directory in tests on Windows CE, but this at least -// provides a reasonable fallback. -const char kCurrentDirectoryString[] = "\\"; -// Windows CE doesn't define INVALID_FILE_ATTRIBUTES -const DWORD kInvalidFileAttributes = 0xffffffff; -#else -const char kCurrentDirectoryString[] = ".\\"; -#endif // GTEST_OS_WINDOWS_MOBILE -#else -const char kPathSeparator = '/'; -const char kCurrentDirectoryString[] = "./"; -#endif // GTEST_OS_WINDOWS - -// Returns whether the given character is a valid path separator. -static bool IsPathSeparator(char c) { -#if GTEST_HAS_ALT_PATH_SEP_ - return (c == kPathSeparator) || (c == kAlternatePathSeparator); -#else - return c == kPathSeparator; -#endif -} - -// Returns the current working directory, or "" if unsuccessful. -FilePath FilePath::GetCurrentDir() { -#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ - GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_ESP32 || \ - GTEST_OS_XTENSA - // These platforms do not have a current directory, so we just return - // something reasonable. - return FilePath(kCurrentDirectoryString); -#elif GTEST_OS_WINDOWS - char cwd[GTEST_PATH_MAX_ + 1] = {'\0'}; - return FilePath(_getcwd(cwd, sizeof(cwd)) == nullptr ? "" : cwd); -#else - char cwd[GTEST_PATH_MAX_ + 1] = {'\0'}; - char* result = getcwd(cwd, sizeof(cwd)); -#if GTEST_OS_NACL - // getcwd will likely fail in NaCl due to the sandbox, so return something - // reasonable. The user may have provided a shim implementation for getcwd, - // however, so fallback only when failure is detected. - return FilePath(result == nullptr ? kCurrentDirectoryString : cwd); -#endif // GTEST_OS_NACL - return FilePath(result == nullptr ? "" : cwd); -#endif // GTEST_OS_WINDOWS_MOBILE -} - -// Returns a copy of the FilePath with the case-insensitive extension removed. -// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns -// FilePath("dir/file"). If a case-insensitive extension is not -// found, returns a copy of the original FilePath. -FilePath FilePath::RemoveExtension(const char* extension) const { - const std::string dot_extension = std::string(".") + extension; - if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { - return FilePath( - pathname_.substr(0, pathname_.length() - dot_extension.length())); - } - return *this; -} - -// Returns a pointer to the last occurrence of a valid path separator in -// the FilePath. On Windows, for example, both '/' and '\' are valid path -// separators. Returns NULL if no path separator was found. -const char* FilePath::FindLastPathSeparator() const { - const char* const last_sep = strrchr(c_str(), kPathSeparator); -#if GTEST_HAS_ALT_PATH_SEP_ - const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); - // Comparing two pointers of which only one is NULL is undefined. - if (last_alt_sep != nullptr && - (last_sep == nullptr || last_alt_sep > last_sep)) { - return last_alt_sep; - } -#endif - return last_sep; -} - -// Returns a copy of the FilePath with the directory part removed. -// Example: FilePath("path/to/file").RemoveDirectoryName() returns -// FilePath("file"). If there is no directory part ("just_a_file"), it returns -// the FilePath unmodified. If there is no file part ("just_a_dir/") it -// returns an empty FilePath (""). -// On Windows platform, '\' is the path separator, otherwise it is '/'. -FilePath FilePath::RemoveDirectoryName() const { - const char* const last_sep = FindLastPathSeparator(); - return last_sep ? FilePath(last_sep + 1) : *this; -} - -// RemoveFileName returns the directory path with the filename removed. -// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". -// If the FilePath is "a_file" or "/a_file", RemoveFileName returns -// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does -// not have a file, like "just/a/dir/", it returns the FilePath unmodified. -// On Windows platform, '\' is the path separator, otherwise it is '/'. -FilePath FilePath::RemoveFileName() const { - const char* const last_sep = FindLastPathSeparator(); - std::string dir; - if (last_sep) { - dir = std::string(c_str(), static_cast(last_sep + 1 - c_str())); - } else { - dir = kCurrentDirectoryString; - } - return FilePath(dir); -} - -// Helper functions for naming files in a directory for xml output. - -// Given directory = "dir", base_name = "test", number = 0, -// extension = "xml", returns "dir/test.xml". If number is greater -// than zero (e.g., 12), returns "dir/test_12.xml". -// On Windows platform, uses \ as the separator rather than /. -FilePath FilePath::MakeFileName(const FilePath& directory, - const FilePath& base_name, int number, - const char* extension) { - std::string file; - if (number == 0) { - file = base_name.string() + "." + extension; - } else { - file = - base_name.string() + "_" + StreamableToString(number) + "." + extension; - } - return ConcatPaths(directory, FilePath(file)); -} - -// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". -// On Windows, uses \ as the separator rather than /. -FilePath FilePath::ConcatPaths(const FilePath& directory, - const FilePath& relative_path) { - if (directory.IsEmpty()) return relative_path; - const FilePath dir(directory.RemoveTrailingPathSeparator()); - return FilePath(dir.string() + kPathSeparator + relative_path.string()); -} - -// Returns true if pathname describes something findable in the file-system, -// either a file, directory, or whatever. -bool FilePath::FileOrDirectoryExists() const { -#if GTEST_OS_WINDOWS_MOBILE - LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); - const DWORD attributes = GetFileAttributes(unicode); - delete[] unicode; - return attributes != kInvalidFileAttributes; -#else - posix::StatStruct file_stat{}; - return posix::Stat(pathname_.c_str(), &file_stat) == 0; -#endif // GTEST_OS_WINDOWS_MOBILE -} - -// Returns true if pathname describes a directory in the file-system -// that exists. -bool FilePath::DirectoryExists() const { - bool result = false; -#if GTEST_OS_WINDOWS - // Don't strip off trailing separator if path is a root directory on - // Windows (like "C:\\"). - const FilePath& path(IsRootDirectory() ? *this - : RemoveTrailingPathSeparator()); -#else - const FilePath& path(*this); -#endif - -#if GTEST_OS_WINDOWS_MOBILE - LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); - const DWORD attributes = GetFileAttributes(unicode); - delete[] unicode; - if ((attributes != kInvalidFileAttributes) && - (attributes & FILE_ATTRIBUTE_DIRECTORY)) { - result = true; - } -#else - posix::StatStruct file_stat{}; - result = - posix::Stat(path.c_str(), &file_stat) == 0 && posix::IsDir(file_stat); -#endif // GTEST_OS_WINDOWS_MOBILE - - return result; -} - -// Returns true if pathname describes a root directory. (Windows has one -// root directory per disk drive.) -bool FilePath::IsRootDirectory() const { -#if GTEST_OS_WINDOWS - return pathname_.length() == 3 && IsAbsolutePath(); -#else - return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); -#endif -} - -// Returns true if pathname describes an absolute path. -bool FilePath::IsAbsolutePath() const { - const char* const name = pathname_.c_str(); -#if GTEST_OS_WINDOWS - return pathname_.length() >= 3 && - ((name[0] >= 'a' && name[0] <= 'z') || - (name[0] >= 'A' && name[0] <= 'Z')) && - name[1] == ':' && IsPathSeparator(name[2]); -#else - return IsPathSeparator(name[0]); -#endif -} - -// Returns a pathname for a file that does not currently exist. The pathname -// will be directory/base_name.extension or -// directory/base_name_.extension if directory/base_name.extension -// already exists. The number will be incremented until a pathname is found -// that does not already exist. -// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. -// There could be a race condition if two or more processes are calling this -// function at the same time -- they could both pick the same filename. -FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, - const FilePath& base_name, - const char* extension) { - FilePath full_pathname; - int number = 0; - do { - full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); - } while (full_pathname.FileOrDirectoryExists()); - return full_pathname; -} - -// Returns true if FilePath ends with a path separator, which indicates that -// it is intended to represent a directory. Returns false otherwise. -// This does NOT check that a directory (or file) actually exists. -bool FilePath::IsDirectory() const { - return !pathname_.empty() && - IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); -} - -// Create directories so that path exists. Returns true if successful or if -// the directories already exist; returns false if unable to create directories -// for any reason. -bool FilePath::CreateDirectoriesRecursively() const { - if (!this->IsDirectory()) { - return false; - } - - if (pathname_.length() == 0 || this->DirectoryExists()) { - return true; - } - - const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); - return parent.CreateDirectoriesRecursively() && this->CreateFolder(); -} - -// Create the directory so that path exists. Returns true if successful or -// if the directory already exists; returns false if unable to create the -// directory for any reason, including if the parent directory does not -// exist. Not named "CreateDirectory" because that's a macro on Windows. -bool FilePath::CreateFolder() const { -#if GTEST_OS_WINDOWS_MOBILE - FilePath removed_sep(this->RemoveTrailingPathSeparator()); - LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); - int result = CreateDirectory(unicode, nullptr) ? 0 : -1; - delete[] unicode; -#elif GTEST_OS_WINDOWS - int result = _mkdir(pathname_.c_str()); -#elif GTEST_OS_ESP8266 || GTEST_OS_XTENSA - // do nothing - int result = 0; -#else - int result = mkdir(pathname_.c_str(), 0777); -#endif // GTEST_OS_WINDOWS_MOBILE - - if (result == -1) { - return this->DirectoryExists(); // An error is OK if the directory exists. - } - return true; // No error. -} - -// If input name has a trailing separator character, remove it and return the -// name, otherwise return the name string unmodified. -// On Windows platform, uses \ as the separator, other platforms use /. -FilePath FilePath::RemoveTrailingPathSeparator() const { - return IsDirectory() ? FilePath(pathname_.substr(0, pathname_.length() - 1)) - : *this; -} - -// Removes any redundant separators that might be in the pathname. -// For example, "bar///foo" becomes "bar/foo". Does not eliminate other -// redundancies that might be in a pathname involving "." or "..". -void FilePath::Normalize() { - auto out = pathname_.begin(); - - for (const char character : pathname_) { - if (!IsPathSeparator(character)) { - *(out++) = character; - } else if (out == pathname_.begin() || *std::prev(out) != kPathSeparator) { - *(out++) = kPathSeparator; - } else { - continue; - } - } - - pathname_.erase(out, pathname_.end()); -} - -} // namespace internal -} // namespace testing diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-internal-inl.h b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-internal-inl.h deleted file mode 100644 index 0b9e929c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-internal-inl.h +++ /dev/null @@ -1,1212 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Utility functions and classes used by the Google C++ testing framework.// -// This file contains purely Google Test's internal implementation. Please -// DO NOT #INCLUDE IT IN A USER PROGRAM. - -#ifndef GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_ -#define GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_ - -#ifndef _WIN32_WCE -#include -#endif // !_WIN32_WCE -#include -#include // For strtoll/_strtoul64/malloc/free. -#include // For memmove. - -#include -#include -#include -#include -#include - -#include "gtest/internal/gtest-port.h" - -#if GTEST_CAN_STREAM_RESULTS_ -#include // NOLINT -#include // NOLINT -#endif - -#if GTEST_OS_WINDOWS -#include // NOLINT -#endif // GTEST_OS_WINDOWS - -#include "gtest/gtest-spi.h" -#include "gtest/gtest.h" - -GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ -/* class A needs to have dll-interface to be used by clients of class B */) - -// Declares the flags. -// -// We don't want the users to modify this flag in the code, but want -// Google Test's own unit tests to be able to access it. Therefore we -// declare it here as opposed to in gtest.h. -GTEST_DECLARE_bool_(death_test_use_fork); - -namespace testing { -namespace internal { - -// The value of GetTestTypeId() as seen from within the Google Test -// library. This is solely for testing GetTestTypeId(). -GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; - -// A valid random seed must be in [1, kMaxRandomSeed]. -const int kMaxRandomSeed = 99999; - -// g_help_flag is true if and only if the --help flag or an equivalent form -// is specified on the command line. -GTEST_API_ extern bool g_help_flag; - -// Returns the current time in milliseconds. -GTEST_API_ TimeInMillis GetTimeInMillis(); - -// Returns true if and only if Google Test should use colors in the output. -GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); - -// Formats the given time in milliseconds as seconds. -GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); - -// Converts the given time in milliseconds to a date string in the ISO 8601 -// format, without the timezone information. N.B.: due to the use the -// non-reentrant localtime() function, this function is not thread safe. Do -// not use it in any code that can be called from multiple threads. -GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); - -// Parses a string for an Int32 flag, in the form of "--flag=value". -// -// On success, stores the value of the flag in *value, and returns -// true. On failure, returns false without changing *value. -GTEST_API_ bool ParseFlag(const char* str, const char* flag, int32_t* value); - -// Returns a random seed in range [1, kMaxRandomSeed] based on the -// given --gtest_random_seed flag value. -inline int GetRandomSeedFromFlag(int32_t random_seed_flag) { - const unsigned int raw_seed = - (random_seed_flag == 0) ? static_cast(GetTimeInMillis()) - : static_cast(random_seed_flag); - - // Normalizes the actual seed to range [1, kMaxRandomSeed] such that - // it's easy to type. - const int normalized_seed = - static_cast((raw_seed - 1U) % - static_cast(kMaxRandomSeed)) + - 1; - return normalized_seed; -} - -// Returns the first valid random seed after 'seed'. The behavior is -// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is -// considered to be 1. -inline int GetNextRandomSeed(int seed) { - GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) - << "Invalid random seed " << seed << " - must be in [1, " - << kMaxRandomSeed << "]."; - const int next_seed = seed + 1; - return (next_seed > kMaxRandomSeed) ? 1 : next_seed; -} - -// This class saves the values of all Google Test flags in its c'tor, and -// restores them in its d'tor. -class GTestFlagSaver { - public: - // The c'tor. - GTestFlagSaver() { - also_run_disabled_tests_ = GTEST_FLAG_GET(also_run_disabled_tests); - break_on_failure_ = GTEST_FLAG_GET(break_on_failure); - catch_exceptions_ = GTEST_FLAG_GET(catch_exceptions); - color_ = GTEST_FLAG_GET(color); - death_test_style_ = GTEST_FLAG_GET(death_test_style); - death_test_use_fork_ = GTEST_FLAG_GET(death_test_use_fork); - fail_fast_ = GTEST_FLAG_GET(fail_fast); - filter_ = GTEST_FLAG_GET(filter); - internal_run_death_test_ = GTEST_FLAG_GET(internal_run_death_test); - list_tests_ = GTEST_FLAG_GET(list_tests); - output_ = GTEST_FLAG_GET(output); - brief_ = GTEST_FLAG_GET(brief); - print_time_ = GTEST_FLAG_GET(print_time); - print_utf8_ = GTEST_FLAG_GET(print_utf8); - random_seed_ = GTEST_FLAG_GET(random_seed); - repeat_ = GTEST_FLAG_GET(repeat); - recreate_environments_when_repeating_ = - GTEST_FLAG_GET(recreate_environments_when_repeating); - shuffle_ = GTEST_FLAG_GET(shuffle); - stack_trace_depth_ = GTEST_FLAG_GET(stack_trace_depth); - stream_result_to_ = GTEST_FLAG_GET(stream_result_to); - throw_on_failure_ = GTEST_FLAG_GET(throw_on_failure); - } - - // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. - ~GTestFlagSaver() { - GTEST_FLAG_SET(also_run_disabled_tests, also_run_disabled_tests_); - GTEST_FLAG_SET(break_on_failure, break_on_failure_); - GTEST_FLAG_SET(catch_exceptions, catch_exceptions_); - GTEST_FLAG_SET(color, color_); - GTEST_FLAG_SET(death_test_style, death_test_style_); - GTEST_FLAG_SET(death_test_use_fork, death_test_use_fork_); - GTEST_FLAG_SET(filter, filter_); - GTEST_FLAG_SET(fail_fast, fail_fast_); - GTEST_FLAG_SET(internal_run_death_test, internal_run_death_test_); - GTEST_FLAG_SET(list_tests, list_tests_); - GTEST_FLAG_SET(output, output_); - GTEST_FLAG_SET(brief, brief_); - GTEST_FLAG_SET(print_time, print_time_); - GTEST_FLAG_SET(print_utf8, print_utf8_); - GTEST_FLAG_SET(random_seed, random_seed_); - GTEST_FLAG_SET(repeat, repeat_); - GTEST_FLAG_SET(recreate_environments_when_repeating, - recreate_environments_when_repeating_); - GTEST_FLAG_SET(shuffle, shuffle_); - GTEST_FLAG_SET(stack_trace_depth, stack_trace_depth_); - GTEST_FLAG_SET(stream_result_to, stream_result_to_); - GTEST_FLAG_SET(throw_on_failure, throw_on_failure_); - } - - private: - // Fields for saving the original values of flags. - bool also_run_disabled_tests_; - bool break_on_failure_; - bool catch_exceptions_; - std::string color_; - std::string death_test_style_; - bool death_test_use_fork_; - bool fail_fast_; - std::string filter_; - std::string internal_run_death_test_; - bool list_tests_; - std::string output_; - bool brief_; - bool print_time_; - bool print_utf8_; - int32_t random_seed_; - int32_t repeat_; - bool recreate_environments_when_repeating_; - bool shuffle_; - int32_t stack_trace_depth_; - std::string stream_result_to_; - bool throw_on_failure_; -} GTEST_ATTRIBUTE_UNUSED_; - -// Converts a Unicode code point to a narrow string in UTF-8 encoding. -// code_point parameter is of type UInt32 because wchar_t may not be -// wide enough to contain a code point. -// If the code_point is not a valid Unicode code point -// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted -// to "(Invalid Unicode 0xXXXXXXXX)". -GTEST_API_ std::string CodePointToUtf8(uint32_t code_point); - -// Converts a wide string to a narrow string in UTF-8 encoding. -// The wide string is assumed to have the following encoding: -// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin) -// UTF-32 if sizeof(wchar_t) == 4 (on Linux) -// Parameter str points to a null-terminated wide string. -// Parameter num_chars may additionally limit the number -// of wchar_t characters processed. -1 is used when the entire string -// should be processed. -// If the string contains code points that are not valid Unicode code points -// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output -// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding -// and contains invalid UTF-16 surrogate pairs, values in those pairs -// will be encoded as individual Unicode characters from Basic Normal Plane. -GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars); - -// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file -// if the variable is present. If a file already exists at this location, this -// function will write over it. If the variable is present, but the file cannot -// be created, prints an error and exits. -void WriteToShardStatusFileIfNeeded(); - -// Checks whether sharding is enabled by examining the relevant -// environment variable values. If the variables are present, -// but inconsistent (e.g., shard_index >= total_shards), prints -// an error and exits. If in_subprocess_for_death_test, sharding is -// disabled because it must only be applied to the original test -// process. Otherwise, we could filter out death tests we intended to execute. -GTEST_API_ bool ShouldShard(const char* total_shards_str, - const char* shard_index_str, - bool in_subprocess_for_death_test); - -// Parses the environment variable var as a 32-bit integer. If it is unset, -// returns default_val. If it is not a 32-bit integer, prints an error and -// and aborts. -GTEST_API_ int32_t Int32FromEnvOrDie(const char* env_var, int32_t default_val); - -// Given the total number of shards, the shard index, and the test id, -// returns true if and only if the test should be run on this shard. The test id -// is some arbitrary but unique non-negative integer assigned to each test -// method. Assumes that 0 <= shard_index < total_shards. -GTEST_API_ bool ShouldRunTestOnShard(int total_shards, int shard_index, - int test_id); - -// STL container utilities. - -// Returns the number of elements in the given container that satisfy -// the given predicate. -template -inline int CountIf(const Container& c, Predicate predicate) { - // Implemented as an explicit loop since std::count_if() in libCstd on - // Solaris has a non-standard signature. - int count = 0; - for (auto it = c.begin(); it != c.end(); ++it) { - if (predicate(*it)) ++count; - } - return count; -} - -// Applies a function/functor to each element in the container. -template -void ForEach(const Container& c, Functor functor) { - std::for_each(c.begin(), c.end(), functor); -} - -// Returns the i-th element of the vector, or default_value if i is not -// in range [0, v.size()). -template -inline E GetElementOr(const std::vector& v, int i, E default_value) { - return (i < 0 || i >= static_cast(v.size())) ? default_value - : v[static_cast(i)]; -} - -// Performs an in-place shuffle of a range of the vector's elements. -// 'begin' and 'end' are element indices as an STL-style range; -// i.e. [begin, end) are shuffled, where 'end' == size() means to -// shuffle to the end of the vector. -template -void ShuffleRange(internal::Random* random, int begin, int end, - std::vector* v) { - const int size = static_cast(v->size()); - GTEST_CHECK_(0 <= begin && begin <= size) - << "Invalid shuffle range start " << begin << ": must be in range [0, " - << size << "]."; - GTEST_CHECK_(begin <= end && end <= size) - << "Invalid shuffle range finish " << end << ": must be in range [" - << begin << ", " << size << "]."; - - // Fisher-Yates shuffle, from - // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle - for (int range_width = end - begin; range_width >= 2; range_width--) { - const int last_in_range = begin + range_width - 1; - const int selected = - begin + - static_cast(random->Generate(static_cast(range_width))); - std::swap((*v)[static_cast(selected)], - (*v)[static_cast(last_in_range)]); - } -} - -// Performs an in-place shuffle of the vector's elements. -template -inline void Shuffle(internal::Random* random, std::vector* v) { - ShuffleRange(random, 0, static_cast(v->size()), v); -} - -// A function for deleting an object. Handy for being used as a -// functor. -template -static void Delete(T* x) { - delete x; -} - -// A predicate that checks the key of a TestProperty against a known key. -// -// TestPropertyKeyIs is copyable. -class TestPropertyKeyIs { - public: - // Constructor. - // - // TestPropertyKeyIs has NO default constructor. - explicit TestPropertyKeyIs(const std::string& key) : key_(key) {} - - // Returns true if and only if the test name of test property matches on key_. - bool operator()(const TestProperty& test_property) const { - return test_property.key() == key_; - } - - private: - std::string key_; -}; - -// Class UnitTestOptions. -// -// This class contains functions for processing options the user -// specifies when running the tests. It has only static members. -// -// In most cases, the user can specify an option using either an -// environment variable or a command line flag. E.g. you can set the -// test filter using either GTEST_FILTER or --gtest_filter. If both -// the variable and the flag are present, the latter overrides the -// former. -class GTEST_API_ UnitTestOptions { - public: - // Functions for processing the gtest_output flag. - - // Returns the output format, or "" for normal printed output. - static std::string GetOutputFormat(); - - // Returns the absolute path of the requested output file, or the - // default (test_detail.xml in the original working directory) if - // none was explicitly specified. - static std::string GetAbsolutePathToOutputFile(); - - // Functions for processing the gtest_filter flag. - - // Returns true if and only if the user-specified filter matches the test - // suite name and the test name. - static bool FilterMatchesTest(const std::string& test_suite_name, - const std::string& test_name); - -#if GTEST_OS_WINDOWS - // Function for supporting the gtest_catch_exception flag. - - // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the - // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. - // This function is useful as an __except condition. - static int GTestShouldProcessSEH(DWORD exception_code); -#endif // GTEST_OS_WINDOWS - - // Returns true if "name" matches the ':' separated list of glob-style - // filters in "filter". - static bool MatchesFilter(const std::string& name, const char* filter); -}; - -// Returns the current application's name, removing directory path if that -// is present. Used by UnitTestOptions::GetOutputFile. -GTEST_API_ FilePath GetCurrentExecutableName(); - -// The role interface for getting the OS stack trace as a string. -class OsStackTraceGetterInterface { - public: - OsStackTraceGetterInterface() {} - virtual ~OsStackTraceGetterInterface() {} - - // Returns the current OS stack trace as an std::string. Parameters: - // - // max_depth - the maximum number of stack frames to be included - // in the trace. - // skip_count - the number of top frames to be skipped; doesn't count - // against max_depth. - virtual std::string CurrentStackTrace(int max_depth, int skip_count) = 0; - - // UponLeavingGTest() should be called immediately before Google Test calls - // user code. It saves some information about the current stack that - // CurrentStackTrace() will use to find and hide Google Test stack frames. - virtual void UponLeavingGTest() = 0; - - // This string is inserted in place of stack frames that are part of - // Google Test's implementation. - static const char* const kElidedFramesMarker; - - private: - OsStackTraceGetterInterface(const OsStackTraceGetterInterface&) = delete; - OsStackTraceGetterInterface& operator=(const OsStackTraceGetterInterface&) = - delete; -}; - -// A working implementation of the OsStackTraceGetterInterface interface. -class OsStackTraceGetter : public OsStackTraceGetterInterface { - public: - OsStackTraceGetter() {} - - std::string CurrentStackTrace(int max_depth, int skip_count) override; - void UponLeavingGTest() override; - - private: -#if GTEST_HAS_ABSL - Mutex mutex_; // Protects all internal state. - - // We save the stack frame below the frame that calls user code. - // We do this because the address of the frame immediately below - // the user code changes between the call to UponLeavingGTest() - // and any calls to the stack trace code from within the user code. - void* caller_frame_ = nullptr; -#endif // GTEST_HAS_ABSL - - OsStackTraceGetter(const OsStackTraceGetter&) = delete; - OsStackTraceGetter& operator=(const OsStackTraceGetter&) = delete; -}; - -// Information about a Google Test trace point. -struct TraceInfo { - const char* file; - int line; - std::string message; -}; - -// This is the default global test part result reporter used in UnitTestImpl. -// This class should only be used by UnitTestImpl. -class DefaultGlobalTestPartResultReporter - : public TestPartResultReporterInterface { - public: - explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); - // Implements the TestPartResultReporterInterface. Reports the test part - // result in the current test. - void ReportTestPartResult(const TestPartResult& result) override; - - private: - UnitTestImpl* const unit_test_; - - DefaultGlobalTestPartResultReporter( - const DefaultGlobalTestPartResultReporter&) = delete; - DefaultGlobalTestPartResultReporter& operator=( - const DefaultGlobalTestPartResultReporter&) = delete; -}; - -// This is the default per thread test part result reporter used in -// UnitTestImpl. This class should only be used by UnitTestImpl. -class DefaultPerThreadTestPartResultReporter - : public TestPartResultReporterInterface { - public: - explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); - // Implements the TestPartResultReporterInterface. The implementation just - // delegates to the current global test part result reporter of *unit_test_. - void ReportTestPartResult(const TestPartResult& result) override; - - private: - UnitTestImpl* const unit_test_; - - DefaultPerThreadTestPartResultReporter( - const DefaultPerThreadTestPartResultReporter&) = delete; - DefaultPerThreadTestPartResultReporter& operator=( - const DefaultPerThreadTestPartResultReporter&) = delete; -}; - -// The private implementation of the UnitTest class. We don't protect -// the methods under a mutex, as this class is not accessible by a -// user and the UnitTest class that delegates work to this class does -// proper locking. -class GTEST_API_ UnitTestImpl { - public: - explicit UnitTestImpl(UnitTest* parent); - virtual ~UnitTestImpl(); - - // There are two different ways to register your own TestPartResultReporter. - // You can register your own repoter to listen either only for test results - // from the current thread or for results from all threads. - // By default, each per-thread test result repoter just passes a new - // TestPartResult to the global test result reporter, which registers the - // test part result for the currently running test. - - // Returns the global test part result reporter. - TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); - - // Sets the global test part result reporter. - void SetGlobalTestPartResultReporter( - TestPartResultReporterInterface* reporter); - - // Returns the test part result reporter for the current thread. - TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); - - // Sets the test part result reporter for the current thread. - void SetTestPartResultReporterForCurrentThread( - TestPartResultReporterInterface* reporter); - - // Gets the number of successful test suites. - int successful_test_suite_count() const; - - // Gets the number of failed test suites. - int failed_test_suite_count() const; - - // Gets the number of all test suites. - int total_test_suite_count() const; - - // Gets the number of all test suites that contain at least one test - // that should run. - int test_suite_to_run_count() const; - - // Gets the number of successful tests. - int successful_test_count() const; - - // Gets the number of skipped tests. - int skipped_test_count() const; - - // Gets the number of failed tests. - int failed_test_count() const; - - // Gets the number of disabled tests that will be reported in the XML report. - int reportable_disabled_test_count() const; - - // Gets the number of disabled tests. - int disabled_test_count() const; - - // Gets the number of tests to be printed in the XML report. - int reportable_test_count() const; - - // Gets the number of all tests. - int total_test_count() const; - - // Gets the number of tests that should run. - int test_to_run_count() const; - - // Gets the time of the test program start, in ms from the start of the - // UNIX epoch. - TimeInMillis start_timestamp() const { return start_timestamp_; } - - // Gets the elapsed time, in milliseconds. - TimeInMillis elapsed_time() const { return elapsed_time_; } - - // Returns true if and only if the unit test passed (i.e. all test suites - // passed). - bool Passed() const { return !Failed(); } - - // Returns true if and only if the unit test failed (i.e. some test suite - // failed or something outside of all tests failed). - bool Failed() const { - return failed_test_suite_count() > 0 || ad_hoc_test_result()->Failed(); - } - - // Gets the i-th test suite among all the test suites. i can range from 0 to - // total_test_suite_count() - 1. If i is not in that range, returns NULL. - const TestSuite* GetTestSuite(int i) const { - const int index = GetElementOr(test_suite_indices_, i, -1); - return index < 0 ? nullptr : test_suites_[static_cast(i)]; - } - - // Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - const TestCase* GetTestCase(int i) const { return GetTestSuite(i); } -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - - // Gets the i-th test suite among all the test suites. i can range from 0 to - // total_test_suite_count() - 1. If i is not in that range, returns NULL. - TestSuite* GetMutableSuiteCase(int i) { - const int index = GetElementOr(test_suite_indices_, i, -1); - return index < 0 ? nullptr : test_suites_[static_cast(index)]; - } - - // Provides access to the event listener list. - TestEventListeners* listeners() { return &listeners_; } - - // Returns the TestResult for the test that's currently running, or - // the TestResult for the ad hoc test if no test is running. - TestResult* current_test_result(); - - // Returns the TestResult for the ad hoc test. - const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } - - // Sets the OS stack trace getter. - // - // Does nothing if the input and the current OS stack trace getter - // are the same; otherwise, deletes the old getter and makes the - // input the current getter. - void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); - - // Returns the current OS stack trace getter if it is not NULL; - // otherwise, creates an OsStackTraceGetter, makes it the current - // getter, and returns it. - OsStackTraceGetterInterface* os_stack_trace_getter(); - - // Returns the current OS stack trace as an std::string. - // - // The maximum number of stack frames to be included is specified by - // the gtest_stack_trace_depth flag. The skip_count parameter - // specifies the number of top frames to be skipped, which doesn't - // count against the number of frames to be included. - // - // For example, if Foo() calls Bar(), which in turn calls - // CurrentOsStackTraceExceptTop(1), Foo() will be included in the - // trace but Bar() and CurrentOsStackTraceExceptTop() won't. - std::string CurrentOsStackTraceExceptTop(int skip_count) - GTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_; - - // Finds and returns a TestSuite with the given name. If one doesn't - // exist, creates one and returns it. - // - // Arguments: - // - // test_suite_name: name of the test suite - // type_param: the name of the test's type parameter, or NULL if - // this is not a typed or a type-parameterized test. - // set_up_tc: pointer to the function that sets up the test suite - // tear_down_tc: pointer to the function that tears down the test suite - TestSuite* GetTestSuite(const char* test_suite_name, const char* type_param, - internal::SetUpTestSuiteFunc set_up_tc, - internal::TearDownTestSuiteFunc tear_down_tc); - -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - TestCase* GetTestCase(const char* test_case_name, const char* type_param, - internal::SetUpTestSuiteFunc set_up_tc, - internal::TearDownTestSuiteFunc tear_down_tc) { - return GetTestSuite(test_case_name, type_param, set_up_tc, tear_down_tc); - } -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - - // Adds a TestInfo to the unit test. - // - // Arguments: - // - // set_up_tc: pointer to the function that sets up the test suite - // tear_down_tc: pointer to the function that tears down the test suite - // test_info: the TestInfo object - void AddTestInfo(internal::SetUpTestSuiteFunc set_up_tc, - internal::TearDownTestSuiteFunc tear_down_tc, - TestInfo* test_info) { -#if GTEST_HAS_DEATH_TEST - // In order to support thread-safe death tests, we need to - // remember the original working directory when the test program - // was first invoked. We cannot do this in RUN_ALL_TESTS(), as - // the user may have changed the current directory before calling - // RUN_ALL_TESTS(). Therefore we capture the current directory in - // AddTestInfo(), which is called to register a TEST or TEST_F - // before main() is reached. - if (original_working_dir_.IsEmpty()) { - original_working_dir_.Set(FilePath::GetCurrentDir()); - GTEST_CHECK_(!original_working_dir_.IsEmpty()) - << "Failed to get the current working directory."; - } -#endif // GTEST_HAS_DEATH_TEST - - GetTestSuite(test_info->test_suite_name(), test_info->type_param(), - set_up_tc, tear_down_tc) - ->AddTestInfo(test_info); - } - - // Returns ParameterizedTestSuiteRegistry object used to keep track of - // value-parameterized tests and instantiate and register them. - internal::ParameterizedTestSuiteRegistry& parameterized_test_registry() { - return parameterized_test_registry_; - } - - std::set* ignored_parameterized_test_suites() { - return &ignored_parameterized_test_suites_; - } - - // Returns TypeParameterizedTestSuiteRegistry object used to keep track of - // type-parameterized tests and instantiations of them. - internal::TypeParameterizedTestSuiteRegistry& - type_parameterized_test_registry() { - return type_parameterized_test_registry_; - } - - // Sets the TestSuite object for the test that's currently running. - void set_current_test_suite(TestSuite* a_current_test_suite) { - current_test_suite_ = a_current_test_suite; - } - - // Sets the TestInfo object for the test that's currently running. If - // current_test_info is NULL, the assertion results will be stored in - // ad_hoc_test_result_. - void set_current_test_info(TestInfo* a_current_test_info) { - current_test_info_ = a_current_test_info; - } - - // Registers all parameterized tests defined using TEST_P and - // INSTANTIATE_TEST_SUITE_P, creating regular tests for each test/parameter - // combination. This method can be called more then once; it has guards - // protecting from registering the tests more then once. If - // value-parameterized tests are disabled, RegisterParameterizedTests is - // present but does nothing. - void RegisterParameterizedTests(); - - // Runs all tests in this UnitTest object, prints the result, and - // returns true if all tests are successful. If any exception is - // thrown during a test, this test is considered to be failed, but - // the rest of the tests will still be run. - bool RunAllTests(); - - // Clears the results of all tests, except the ad hoc tests. - void ClearNonAdHocTestResult() { - ForEach(test_suites_, TestSuite::ClearTestSuiteResult); - } - - // Clears the results of ad-hoc test assertions. - void ClearAdHocTestResult() { ad_hoc_test_result_.Clear(); } - - // Adds a TestProperty to the current TestResult object when invoked in a - // context of a test or a test suite, or to the global property set. If the - // result already contains a property with the same key, the value will be - // updated. - void RecordProperty(const TestProperty& test_property); - - enum ReactionToSharding { HONOR_SHARDING_PROTOCOL, IGNORE_SHARDING_PROTOCOL }; - - // Matches the full name of each test against the user-specified - // filter to decide whether the test should run, then records the - // result in each TestSuite and TestInfo object. - // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests - // based on sharding variables in the environment. - // Returns the number of tests that should run. - int FilterTests(ReactionToSharding shard_tests); - - // Prints the names of the tests matching the user-specified filter flag. - void ListTestsMatchingFilter(); - - const TestSuite* current_test_suite() const { return current_test_suite_; } - TestInfo* current_test_info() { return current_test_info_; } - const TestInfo* current_test_info() const { return current_test_info_; } - - // Returns the vector of environments that need to be set-up/torn-down - // before/after the tests are run. - std::vector& environments() { return environments_; } - - // Getters for the per-thread Google Test trace stack. - std::vector& gtest_trace_stack() { - return *(gtest_trace_stack_.pointer()); - } - const std::vector& gtest_trace_stack() const { - return gtest_trace_stack_.get(); - } - -#if GTEST_HAS_DEATH_TEST - void InitDeathTestSubprocessControlInfo() { - internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); - } - // Returns a pointer to the parsed --gtest_internal_run_death_test - // flag, or NULL if that flag was not specified. - // This information is useful only in a death test child process. - // Must not be called before a call to InitGoogleTest. - const InternalRunDeathTestFlag* internal_run_death_test_flag() const { - return internal_run_death_test_flag_.get(); - } - - // Returns a pointer to the current death test factory. - internal::DeathTestFactory* death_test_factory() { - return death_test_factory_.get(); - } - - void SuppressTestEventsIfInSubprocess(); - - friend class ReplaceDeathTestFactory; -#endif // GTEST_HAS_DEATH_TEST - - // Initializes the event listener performing XML output as specified by - // UnitTestOptions. Must not be called before InitGoogleTest. - void ConfigureXmlOutput(); - -#if GTEST_CAN_STREAM_RESULTS_ - // Initializes the event listener for streaming test results to a socket. - // Must not be called before InitGoogleTest. - void ConfigureStreamingOutput(); -#endif - - // Performs initialization dependent upon flag values obtained in - // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to - // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest - // this function is also called from RunAllTests. Since this function can be - // called more than once, it has to be idempotent. - void PostFlagParsingInit(); - - // Gets the random seed used at the start of the current test iteration. - int random_seed() const { return random_seed_; } - - // Gets the random number generator. - internal::Random* random() { return &random_; } - - // Shuffles all test suites, and the tests within each test suite, - // making sure that death tests are still run first. - void ShuffleTests(); - - // Restores the test suites and tests to their order before the first shuffle. - void UnshuffleTests(); - - // Returns the value of GTEST_FLAG(catch_exceptions) at the moment - // UnitTest::Run() starts. - bool catch_exceptions() const { return catch_exceptions_; } - - private: - friend class ::testing::UnitTest; - - // Used by UnitTest::Run() to capture the state of - // GTEST_FLAG(catch_exceptions) at the moment it starts. - void set_catch_exceptions(bool value) { catch_exceptions_ = value; } - - // The UnitTest object that owns this implementation object. - UnitTest* const parent_; - - // The working directory when the first TEST() or TEST_F() was - // executed. - internal::FilePath original_working_dir_; - - // The default test part result reporters. - DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; - DefaultPerThreadTestPartResultReporter - default_per_thread_test_part_result_reporter_; - - // Points to (but doesn't own) the global test part result reporter. - TestPartResultReporterInterface* global_test_part_result_repoter_; - - // Protects read and write access to global_test_part_result_reporter_. - internal::Mutex global_test_part_result_reporter_mutex_; - - // Points to (but doesn't own) the per-thread test part result reporter. - internal::ThreadLocal - per_thread_test_part_result_reporter_; - - // The vector of environments that need to be set-up/torn-down - // before/after the tests are run. - std::vector environments_; - - // The vector of TestSuites in their original order. It owns the - // elements in the vector. - std::vector test_suites_; - - // Provides a level of indirection for the test suite list to allow - // easy shuffling and restoring the test suite order. The i-th - // element of this vector is the index of the i-th test suite in the - // shuffled order. - std::vector test_suite_indices_; - - // ParameterizedTestRegistry object used to register value-parameterized - // tests. - internal::ParameterizedTestSuiteRegistry parameterized_test_registry_; - internal::TypeParameterizedTestSuiteRegistry - type_parameterized_test_registry_; - - // The set holding the name of parameterized - // test suites that may go uninstantiated. - std::set ignored_parameterized_test_suites_; - - // Indicates whether RegisterParameterizedTests() has been called already. - bool parameterized_tests_registered_; - - // Index of the last death test suite registered. Initially -1. - int last_death_test_suite_; - - // This points to the TestSuite for the currently running test. It - // changes as Google Test goes through one test suite after another. - // When no test is running, this is set to NULL and Google Test - // stores assertion results in ad_hoc_test_result_. Initially NULL. - TestSuite* current_test_suite_; - - // This points to the TestInfo for the currently running test. It - // changes as Google Test goes through one test after another. When - // no test is running, this is set to NULL and Google Test stores - // assertion results in ad_hoc_test_result_. Initially NULL. - TestInfo* current_test_info_; - - // Normally, a user only writes assertions inside a TEST or TEST_F, - // or inside a function called by a TEST or TEST_F. Since Google - // Test keeps track of which test is current running, it can - // associate such an assertion with the test it belongs to. - // - // If an assertion is encountered when no TEST or TEST_F is running, - // Google Test attributes the assertion result to an imaginary "ad hoc" - // test, and records the result in ad_hoc_test_result_. - TestResult ad_hoc_test_result_; - - // The list of event listeners that can be used to track events inside - // Google Test. - TestEventListeners listeners_; - - // The OS stack trace getter. Will be deleted when the UnitTest - // object is destructed. By default, an OsStackTraceGetter is used, - // but the user can set this field to use a custom getter if that is - // desired. - OsStackTraceGetterInterface* os_stack_trace_getter_; - - // True if and only if PostFlagParsingInit() has been called. - bool post_flag_parse_init_performed_; - - // The random number seed used at the beginning of the test run. - int random_seed_; - - // Our random number generator. - internal::Random random_; - - // The time of the test program start, in ms from the start of the - // UNIX epoch. - TimeInMillis start_timestamp_; - - // How long the test took to run, in milliseconds. - TimeInMillis elapsed_time_; - -#if GTEST_HAS_DEATH_TEST - // The decomposed components of the gtest_internal_run_death_test flag, - // parsed when RUN_ALL_TESTS is called. - std::unique_ptr internal_run_death_test_flag_; - std::unique_ptr death_test_factory_; -#endif // GTEST_HAS_DEATH_TEST - - // A per-thread stack of traces created by the SCOPED_TRACE() macro. - internal::ThreadLocal > gtest_trace_stack_; - - // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() - // starts. - bool catch_exceptions_; - - UnitTestImpl(const UnitTestImpl&) = delete; - UnitTestImpl& operator=(const UnitTestImpl&) = delete; -}; // class UnitTestImpl - -// Convenience function for accessing the global UnitTest -// implementation object. -inline UnitTestImpl* GetUnitTestImpl() { - return UnitTest::GetInstance()->impl(); -} - -#if GTEST_USES_SIMPLE_RE - -// Internal helper functions for implementing the simple regular -// expression matcher. -GTEST_API_ bool IsInSet(char ch, const char* str); -GTEST_API_ bool IsAsciiDigit(char ch); -GTEST_API_ bool IsAsciiPunct(char ch); -GTEST_API_ bool IsRepeat(char ch); -GTEST_API_ bool IsAsciiWhiteSpace(char ch); -GTEST_API_ bool IsAsciiWordChar(char ch); -GTEST_API_ bool IsValidEscape(char ch); -GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); -GTEST_API_ bool ValidateRegex(const char* regex); -GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); -GTEST_API_ bool MatchRepetitionAndRegexAtHead(bool escaped, char ch, - char repeat, const char* regex, - const char* str); -GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); - -#endif // GTEST_USES_SIMPLE_RE - -// Parses the command line for Google Test flags, without initializing -// other parts of Google Test. -GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); -GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); - -#if GTEST_HAS_DEATH_TEST - -// Returns the message describing the last system error, regardless of the -// platform. -GTEST_API_ std::string GetLastErrnoDescription(); - -// Attempts to parse a string into a positive integer pointed to by the -// number parameter. Returns true if that is possible. -// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use -// it here. -template -bool ParseNaturalNumber(const ::std::string& str, Integer* number) { - // Fail fast if the given string does not begin with a digit; - // this bypasses strtoXXX's "optional leading whitespace and plus - // or minus sign" semantics, which are undesirable here. - if (str.empty() || !IsDigit(str[0])) { - return false; - } - errno = 0; - - char* end; - // BiggestConvertible is the largest integer type that system-provided - // string-to-number conversion routines can return. - using BiggestConvertible = unsigned long long; // NOLINT - - const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); // NOLINT - const bool parse_success = *end == '\0' && errno == 0; - - GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); - - const Integer result = static_cast(parsed); - if (parse_success && static_cast(result) == parsed) { - *number = result; - return true; - } - return false; -} -#endif // GTEST_HAS_DEATH_TEST - -// TestResult contains some private methods that should be hidden from -// Google Test user but are required for testing. This class allow our tests -// to access them. -// -// This class is supplied only for the purpose of testing Google Test's own -// constructs. Do not use it in user tests, either directly or indirectly. -class TestResultAccessor { - public: - static void RecordProperty(TestResult* test_result, - const std::string& xml_element, - const TestProperty& property) { - test_result->RecordProperty(xml_element, property); - } - - static void ClearTestPartResults(TestResult* test_result) { - test_result->ClearTestPartResults(); - } - - static const std::vector& test_part_results( - const TestResult& test_result) { - return test_result.test_part_results(); - } -}; - -#if GTEST_CAN_STREAM_RESULTS_ - -// Streams test results to the given port on the given host machine. -class StreamingListener : public EmptyTestEventListener { - public: - // Abstract base class for writing strings to a socket. - class AbstractSocketWriter { - public: - virtual ~AbstractSocketWriter() {} - - // Sends a string to the socket. - virtual void Send(const std::string& message) = 0; - - // Closes the socket. - virtual void CloseConnection() {} - - // Sends a string and a newline to the socket. - void SendLn(const std::string& message) { Send(message + "\n"); } - }; - - // Concrete class for actually writing strings to a socket. - class SocketWriter : public AbstractSocketWriter { - public: - SocketWriter(const std::string& host, const std::string& port) - : sockfd_(-1), host_name_(host), port_num_(port) { - MakeConnection(); - } - - ~SocketWriter() override { - if (sockfd_ != -1) CloseConnection(); - } - - // Sends a string to the socket. - void Send(const std::string& message) override { - GTEST_CHECK_(sockfd_ != -1) - << "Send() can be called only when there is a connection."; - - const auto len = static_cast(message.length()); - if (write(sockfd_, message.c_str(), len) != static_cast(len)) { - GTEST_LOG_(WARNING) << "stream_result_to: failed to stream to " - << host_name_ << ":" << port_num_; - } - } - - private: - // Creates a client socket and connects to the server. - void MakeConnection(); - - // Closes the socket. - void CloseConnection() override { - GTEST_CHECK_(sockfd_ != -1) - << "CloseConnection() can be called only when there is a connection."; - - close(sockfd_); - sockfd_ = -1; - } - - int sockfd_; // socket file descriptor - const std::string host_name_; - const std::string port_num_; - - SocketWriter(const SocketWriter&) = delete; - SocketWriter& operator=(const SocketWriter&) = delete; - }; // class SocketWriter - - // Escapes '=', '&', '%', and '\n' characters in str as "%xx". - static std::string UrlEncode(const char* str); - - StreamingListener(const std::string& host, const std::string& port) - : socket_writer_(new SocketWriter(host, port)) { - Start(); - } - - explicit StreamingListener(AbstractSocketWriter* socket_writer) - : socket_writer_(socket_writer) { - Start(); - } - - void OnTestProgramStart(const UnitTest& /* unit_test */) override { - SendLn("event=TestProgramStart"); - } - - void OnTestProgramEnd(const UnitTest& unit_test) override { - // Note that Google Test current only report elapsed time for each - // test iteration, not for the entire test program. - SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed())); - - // Notify the streaming server to stop. - socket_writer_->CloseConnection(); - } - - void OnTestIterationStart(const UnitTest& /* unit_test */, - int iteration) override { - SendLn("event=TestIterationStart&iteration=" + - StreamableToString(iteration)); - } - - void OnTestIterationEnd(const UnitTest& unit_test, - int /* iteration */) override { - SendLn("event=TestIterationEnd&passed=" + FormatBool(unit_test.Passed()) + - "&elapsed_time=" + StreamableToString(unit_test.elapsed_time()) + - "ms"); - } - - // Note that "event=TestCaseStart" is a wire format and has to remain - // "case" for compatibility - void OnTestSuiteStart(const TestSuite& test_suite) override { - SendLn(std::string("event=TestCaseStart&name=") + test_suite.name()); - } - - // Note that "event=TestCaseEnd" is a wire format and has to remain - // "case" for compatibility - void OnTestSuiteEnd(const TestSuite& test_suite) override { - SendLn("event=TestCaseEnd&passed=" + FormatBool(test_suite.Passed()) + - "&elapsed_time=" + StreamableToString(test_suite.elapsed_time()) + - "ms"); - } - - void OnTestStart(const TestInfo& test_info) override { - SendLn(std::string("event=TestStart&name=") + test_info.name()); - } - - void OnTestEnd(const TestInfo& test_info) override { - SendLn("event=TestEnd&passed=" + - FormatBool((test_info.result())->Passed()) + "&elapsed_time=" + - StreamableToString((test_info.result())->elapsed_time()) + "ms"); - } - - void OnTestPartResult(const TestPartResult& test_part_result) override { - const char* file_name = test_part_result.file_name(); - if (file_name == nullptr) file_name = ""; - SendLn("event=TestPartResult&file=" + UrlEncode(file_name) + - "&line=" + StreamableToString(test_part_result.line_number()) + - "&message=" + UrlEncode(test_part_result.message())); - } - - private: - // Sends the given message and a newline to the socket. - void SendLn(const std::string& message) { socket_writer_->SendLn(message); } - - // Called at the start of streaming to notify the receiver what - // protocol we are using. - void Start() { SendLn("gtest_streaming_protocol_version=1.0"); } - - std::string FormatBool(bool value) { return value ? "1" : "0"; } - - const std::unique_ptr socket_writer_; - - StreamingListener(const StreamingListener&) = delete; - StreamingListener& operator=(const StreamingListener&) = delete; -}; // class StreamingListener - -#endif // GTEST_CAN_STREAM_RESULTS_ - -} // namespace internal -} // namespace testing - -GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 - -#endif // GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-matchers.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-matchers.cc deleted file mode 100644 index 7e3bcc0c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-matchers.cc +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// The Google C++ Testing and Mocking Framework (Google Test) -// -// This file implements just enough of the matcher interface to allow -// EXPECT_DEATH and friends to accept a matcher argument. - -#include "gtest/gtest-matchers.h" - -#include - -#include "gtest/internal/gtest-internal.h" -#include "gtest/internal/gtest-port.h" - -namespace testing { - -// Constructs a matcher that matches a const std::string& whose value is -// equal to s. -Matcher::Matcher(const std::string& s) { *this = Eq(s); } - -// Constructs a matcher that matches a const std::string& whose value is -// equal to s. -Matcher::Matcher(const char* s) { - *this = Eq(std::string(s)); -} - -// Constructs a matcher that matches a std::string whose value is equal to -// s. -Matcher::Matcher(const std::string& s) { *this = Eq(s); } - -// Constructs a matcher that matches a std::string whose value is equal to -// s. -Matcher::Matcher(const char* s) { *this = Eq(std::string(s)); } - -#if GTEST_INTERNAL_HAS_STRING_VIEW -// Constructs a matcher that matches a const StringView& whose value is -// equal to s. -Matcher::Matcher(const std::string& s) { - *this = Eq(s); -} - -// Constructs a matcher that matches a const StringView& whose value is -// equal to s. -Matcher::Matcher(const char* s) { - *this = Eq(std::string(s)); -} - -// Constructs a matcher that matches a const StringView& whose value is -// equal to s. -Matcher::Matcher(internal::StringView s) { - *this = Eq(std::string(s)); -} - -// Constructs a matcher that matches a StringView whose value is equal to -// s. -Matcher::Matcher(const std::string& s) { *this = Eq(s); } - -// Constructs a matcher that matches a StringView whose value is equal to -// s. -Matcher::Matcher(const char* s) { - *this = Eq(std::string(s)); -} - -// Constructs a matcher that matches a StringView whose value is equal to -// s. -Matcher::Matcher(internal::StringView s) { - *this = Eq(std::string(s)); -} -#endif // GTEST_INTERNAL_HAS_STRING_VIEW - -} // namespace testing diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-port.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-port.cc deleted file mode 100644 index d797fe4d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-port.cc +++ /dev/null @@ -1,1394 +0,0 @@ -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "gtest/internal/gtest-port.h" - -#include -#include -#include -#include - -#include -#include -#include - -#if GTEST_OS_WINDOWS -#include -#include -#include - -#include // Used in ThreadLocal. -#ifdef _MSC_VER -#include -#endif // _MSC_VER -#else -#include -#endif // GTEST_OS_WINDOWS - -#if GTEST_OS_MAC -#include -#include -#include -#endif // GTEST_OS_MAC - -#if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \ - GTEST_OS_NETBSD || GTEST_OS_OPENBSD -#include -#if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD -#include -#endif -#endif - -#if GTEST_OS_QNX -#include -#include -#include -#endif // GTEST_OS_QNX - -#if GTEST_OS_AIX -#include -#include -#endif // GTEST_OS_AIX - -#if GTEST_OS_FUCHSIA -#include -#include -#endif // GTEST_OS_FUCHSIA - -#include "gtest/gtest-message.h" -#include "gtest/gtest-spi.h" -#include "gtest/internal/gtest-internal.h" -#include "gtest/internal/gtest-string.h" -#include "src/gtest-internal-inl.h" - -namespace testing { -namespace internal { - -#if GTEST_OS_LINUX || GTEST_OS_GNU_HURD - -namespace { -template -T ReadProcFileField(const std::string& filename, int field) { - std::string dummy; - std::ifstream file(filename.c_str()); - while (field-- > 0) { - file >> dummy; - } - T output = 0; - file >> output; - return output; -} -} // namespace - -// Returns the number of active threads, or 0 when there is an error. -size_t GetThreadCount() { - const std::string filename = - (Message() << "/proc/" << getpid() << "/stat").GetString(); - return ReadProcFileField(filename, 19); -} - -#elif GTEST_OS_MAC - -size_t GetThreadCount() { - const task_t task = mach_task_self(); - mach_msg_type_number_t thread_count; - thread_act_array_t thread_list; - const kern_return_t status = task_threads(task, &thread_list, &thread_count); - if (status == KERN_SUCCESS) { - // task_threads allocates resources in thread_list and we need to free them - // to avoid leaks. - vm_deallocate(task, reinterpret_cast(thread_list), - sizeof(thread_t) * thread_count); - return static_cast(thread_count); - } else { - return 0; - } -} - -#elif GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \ - GTEST_OS_NETBSD - -#if GTEST_OS_NETBSD -#undef KERN_PROC -#define KERN_PROC KERN_PROC2 -#define kinfo_proc kinfo_proc2 -#endif - -#if GTEST_OS_DRAGONFLY -#define KP_NLWP(kp) (kp.kp_nthreads) -#elif GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD -#define KP_NLWP(kp) (kp.ki_numthreads) -#elif GTEST_OS_NETBSD -#define KP_NLWP(kp) (kp.p_nlwps) -#endif - -// Returns the number of threads running in the process, or 0 to indicate that -// we cannot detect it. -size_t GetThreadCount() { - int mib[] = { - CTL_KERN, - KERN_PROC, - KERN_PROC_PID, - getpid(), -#if GTEST_OS_NETBSD - sizeof(struct kinfo_proc), - 1, -#endif - }; - u_int miblen = sizeof(mib) / sizeof(mib[0]); - struct kinfo_proc info; - size_t size = sizeof(info); - if (sysctl(mib, miblen, &info, &size, NULL, 0)) { - return 0; - } - return static_cast(KP_NLWP(info)); -} -#elif GTEST_OS_OPENBSD - -// Returns the number of threads running in the process, or 0 to indicate that -// we cannot detect it. -size_t GetThreadCount() { - int mib[] = { - CTL_KERN, - KERN_PROC, - KERN_PROC_PID | KERN_PROC_SHOW_THREADS, - getpid(), - sizeof(struct kinfo_proc), - 0, - }; - u_int miblen = sizeof(mib) / sizeof(mib[0]); - - // get number of structs - size_t size; - if (sysctl(mib, miblen, NULL, &size, NULL, 0)) { - return 0; - } - - mib[5] = static_cast(size / static_cast(mib[4])); - - // populate array of structs - struct kinfo_proc info[mib[5]]; - if (sysctl(mib, miblen, &info, &size, NULL, 0)) { - return 0; - } - - // exclude empty members - size_t nthreads = 0; - for (size_t i = 0; i < size / static_cast(mib[4]); i++) { - if (info[i].p_tid != -1) nthreads++; - } - return nthreads; -} - -#elif GTEST_OS_QNX - -// Returns the number of threads running in the process, or 0 to indicate that -// we cannot detect it. -size_t GetThreadCount() { - const int fd = open("/proc/self/as", O_RDONLY); - if (fd < 0) { - return 0; - } - procfs_info process_info; - const int status = - devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), nullptr); - close(fd); - if (status == EOK) { - return static_cast(process_info.num_threads); - } else { - return 0; - } -} - -#elif GTEST_OS_AIX - -size_t GetThreadCount() { - struct procentry64 entry; - pid_t pid = getpid(); - int status = getprocs64(&entry, sizeof(entry), nullptr, 0, &pid, 1); - if (status == 1) { - return entry.pi_thcount; - } else { - return 0; - } -} - -#elif GTEST_OS_FUCHSIA - -size_t GetThreadCount() { - int dummy_buffer; - size_t avail; - zx_status_t status = - zx_object_get_info(zx_process_self(), ZX_INFO_PROCESS_THREADS, - &dummy_buffer, 0, nullptr, &avail); - if (status == ZX_OK) { - return avail; - } else { - return 0; - } -} - -#else - -size_t GetThreadCount() { - // There's no portable way to detect the number of threads, so we just - // return 0 to indicate that we cannot detect it. - return 0; -} - -#endif // GTEST_OS_LINUX - -#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS - -AutoHandle::AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} - -AutoHandle::AutoHandle(Handle handle) : handle_(handle) {} - -AutoHandle::~AutoHandle() { Reset(); } - -AutoHandle::Handle AutoHandle::Get() const { return handle_; } - -void AutoHandle::Reset() { Reset(INVALID_HANDLE_VALUE); } - -void AutoHandle::Reset(HANDLE handle) { - // Resetting with the same handle we already own is invalid. - if (handle_ != handle) { - if (IsCloseable()) { - ::CloseHandle(handle_); - } - handle_ = handle; - } else { - GTEST_CHECK_(!IsCloseable()) - << "Resetting a valid handle to itself is likely a programmer error " - "and thus not allowed."; - } -} - -bool AutoHandle::IsCloseable() const { - // Different Windows APIs may use either of these values to represent an - // invalid handle. - return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE; -} - -Mutex::Mutex() - : owner_thread_id_(0), - type_(kDynamic), - critical_section_init_phase_(0), - critical_section_(new CRITICAL_SECTION) { - ::InitializeCriticalSection(critical_section_); -} - -Mutex::~Mutex() { - // Static mutexes are leaked intentionally. It is not thread-safe to try - // to clean them up. - if (type_ == kDynamic) { - ::DeleteCriticalSection(critical_section_); - delete critical_section_; - critical_section_ = nullptr; - } -} - -void Mutex::Lock() { - ThreadSafeLazyInit(); - ::EnterCriticalSection(critical_section_); - owner_thread_id_ = ::GetCurrentThreadId(); -} - -void Mutex::Unlock() { - ThreadSafeLazyInit(); - // We don't protect writing to owner_thread_id_ here, as it's the - // caller's responsibility to ensure that the current thread holds the - // mutex when this is called. - owner_thread_id_ = 0; - ::LeaveCriticalSection(critical_section_); -} - -// Does nothing if the current thread holds the mutex. Otherwise, crashes -// with high probability. -void Mutex::AssertHeld() { - ThreadSafeLazyInit(); - GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId()) - << "The current thread is not holding the mutex @" << this; -} - -namespace { - -#ifdef _MSC_VER -// Use the RAII idiom to flag mem allocs that are intentionally never -// deallocated. The motivation is to silence the false positive mem leaks -// that are reported by the debug version of MS's CRT which can only detect -// if an alloc is missing a matching deallocation. -// Example: -// MemoryIsNotDeallocated memory_is_not_deallocated; -// critical_section_ = new CRITICAL_SECTION; -// -class MemoryIsNotDeallocated { - public: - MemoryIsNotDeallocated() : old_crtdbg_flag_(0) { - old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); - // Set heap allocation block type to _IGNORE_BLOCK so that MS debug CRT - // doesn't report mem leak if there's no matching deallocation. - (void)_CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF); - } - - ~MemoryIsNotDeallocated() { - // Restore the original _CRTDBG_ALLOC_MEM_DF flag - (void)_CrtSetDbgFlag(old_crtdbg_flag_); - } - - private: - int old_crtdbg_flag_; - - MemoryIsNotDeallocated(const MemoryIsNotDeallocated&) = delete; - MemoryIsNotDeallocated& operator=(const MemoryIsNotDeallocated&) = delete; -}; -#endif // _MSC_VER - -} // namespace - -// Initializes owner_thread_id_ and critical_section_ in static mutexes. -void Mutex::ThreadSafeLazyInit() { - // Dynamic mutexes are initialized in the constructor. - if (type_ == kStatic) { - switch ( - ::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) { - case 0: - // If critical_section_init_phase_ was 0 before the exchange, we - // are the first to test it and need to perform the initialization. - owner_thread_id_ = 0; - { - // Use RAII to flag that following mem alloc is never deallocated. -#ifdef _MSC_VER - MemoryIsNotDeallocated memory_is_not_deallocated; -#endif // _MSC_VER - critical_section_ = new CRITICAL_SECTION; - } - ::InitializeCriticalSection(critical_section_); - // Updates the critical_section_init_phase_ to 2 to signal - // initialization complete. - GTEST_CHECK_(::InterlockedCompareExchange(&critical_section_init_phase_, - 2L, 1L) == 1L); - break; - case 1: - // Somebody else is already initializing the mutex; spin until they - // are done. - while (::InterlockedCompareExchange(&critical_section_init_phase_, 2L, - 2L) != 2L) { - // Possibly yields the rest of the thread's time slice to other - // threads. - ::Sleep(0); - } - break; - - case 2: - break; // The mutex is already initialized and ready for use. - - default: - GTEST_CHECK_(false) - << "Unexpected value of critical_section_init_phase_ " - << "while initializing a static mutex."; - } - } -} - -namespace { - -class ThreadWithParamSupport : public ThreadWithParamBase { - public: - static HANDLE CreateThread(Runnable* runnable, - Notification* thread_can_start) { - ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start); - DWORD thread_id; - HANDLE thread_handle = ::CreateThread( - nullptr, // Default security. - 0, // Default stack size. - &ThreadWithParamSupport::ThreadMain, - param, // Parameter to ThreadMainStatic - 0x0, // Default creation flags. - &thread_id); // Need a valid pointer for the call to work under Win98. - GTEST_CHECK_(thread_handle != nullptr) - << "CreateThread failed with error " << ::GetLastError() << "."; - if (thread_handle == nullptr) { - delete param; - } - return thread_handle; - } - - private: - struct ThreadMainParam { - ThreadMainParam(Runnable* runnable, Notification* thread_can_start) - : runnable_(runnable), thread_can_start_(thread_can_start) {} - std::unique_ptr runnable_; - // Does not own. - Notification* thread_can_start_; - }; - - static DWORD WINAPI ThreadMain(void* ptr) { - // Transfers ownership. - std::unique_ptr param(static_cast(ptr)); - if (param->thread_can_start_ != nullptr) - param->thread_can_start_->WaitForNotification(); - param->runnable_->Run(); - return 0; - } - - // Prohibit instantiation. - ThreadWithParamSupport(); - - ThreadWithParamSupport(const ThreadWithParamSupport&) = delete; - ThreadWithParamSupport& operator=(const ThreadWithParamSupport&) = delete; -}; - -} // namespace - -ThreadWithParamBase::ThreadWithParamBase(Runnable* runnable, - Notification* thread_can_start) - : thread_( - ThreadWithParamSupport::CreateThread(runnable, thread_can_start)) {} - -ThreadWithParamBase::~ThreadWithParamBase() { Join(); } - -void ThreadWithParamBase::Join() { - GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0) - << "Failed to join the thread with error " << ::GetLastError() << "."; -} - -// Maps a thread to a set of ThreadIdToThreadLocals that have values -// instantiated on that thread and notifies them when the thread exits. A -// ThreadLocal instance is expected to persist until all threads it has -// values on have terminated. -class ThreadLocalRegistryImpl { - public: - // Registers thread_local_instance as having value on the current thread. - // Returns a value that can be used to identify the thread from other threads. - static ThreadLocalValueHolderBase* GetValueOnCurrentThread( - const ThreadLocalBase* thread_local_instance) { -#ifdef _MSC_VER - MemoryIsNotDeallocated memory_is_not_deallocated; -#endif // _MSC_VER - DWORD current_thread = ::GetCurrentThreadId(); - MutexLock lock(&mutex_); - ThreadIdToThreadLocals* const thread_to_thread_locals = - GetThreadLocalsMapLocked(); - ThreadIdToThreadLocals::iterator thread_local_pos = - thread_to_thread_locals->find(current_thread); - if (thread_local_pos == thread_to_thread_locals->end()) { - thread_local_pos = - thread_to_thread_locals - ->insert(std::make_pair(current_thread, ThreadLocalValues())) - .first; - StartWatcherThreadFor(current_thread); - } - ThreadLocalValues& thread_local_values = thread_local_pos->second; - ThreadLocalValues::iterator value_pos = - thread_local_values.find(thread_local_instance); - if (value_pos == thread_local_values.end()) { - value_pos = - thread_local_values - .insert(std::make_pair( - thread_local_instance, - std::shared_ptr( - thread_local_instance->NewValueForCurrentThread()))) - .first; - } - return value_pos->second.get(); - } - - static void OnThreadLocalDestroyed( - const ThreadLocalBase* thread_local_instance) { - std::vector > value_holders; - // Clean up the ThreadLocalValues data structure while holding the lock, but - // defer the destruction of the ThreadLocalValueHolderBases. - { - MutexLock lock(&mutex_); - ThreadIdToThreadLocals* const thread_to_thread_locals = - GetThreadLocalsMapLocked(); - for (ThreadIdToThreadLocals::iterator it = - thread_to_thread_locals->begin(); - it != thread_to_thread_locals->end(); ++it) { - ThreadLocalValues& thread_local_values = it->second; - ThreadLocalValues::iterator value_pos = - thread_local_values.find(thread_local_instance); - if (value_pos != thread_local_values.end()) { - value_holders.push_back(value_pos->second); - thread_local_values.erase(value_pos); - // This 'if' can only be successful at most once, so theoretically we - // could break out of the loop here, but we don't bother doing so. - } - } - } - // Outside the lock, let the destructor for 'value_holders' deallocate the - // ThreadLocalValueHolderBases. - } - - static void OnThreadExit(DWORD thread_id) { - GTEST_CHECK_(thread_id != 0) << ::GetLastError(); - std::vector > value_holders; - // Clean up the ThreadIdToThreadLocals data structure while holding the - // lock, but defer the destruction of the ThreadLocalValueHolderBases. - { - MutexLock lock(&mutex_); - ThreadIdToThreadLocals* const thread_to_thread_locals = - GetThreadLocalsMapLocked(); - ThreadIdToThreadLocals::iterator thread_local_pos = - thread_to_thread_locals->find(thread_id); - if (thread_local_pos != thread_to_thread_locals->end()) { - ThreadLocalValues& thread_local_values = thread_local_pos->second; - for (ThreadLocalValues::iterator value_pos = - thread_local_values.begin(); - value_pos != thread_local_values.end(); ++value_pos) { - value_holders.push_back(value_pos->second); - } - thread_to_thread_locals->erase(thread_local_pos); - } - } - // Outside the lock, let the destructor for 'value_holders' deallocate the - // ThreadLocalValueHolderBases. - } - - private: - // In a particular thread, maps a ThreadLocal object to its value. - typedef std::map > - ThreadLocalValues; - // Stores all ThreadIdToThreadLocals having values in a thread, indexed by - // thread's ID. - typedef std::map ThreadIdToThreadLocals; - - // Holds the thread id and thread handle that we pass from - // StartWatcherThreadFor to WatcherThreadFunc. - typedef std::pair ThreadIdAndHandle; - - static void StartWatcherThreadFor(DWORD thread_id) { - // The returned handle will be kept in thread_map and closed by - // watcher_thread in WatcherThreadFunc. - HANDLE thread = - ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id); - GTEST_CHECK_(thread != nullptr); - // We need to pass a valid thread ID pointer into CreateThread for it - // to work correctly under Win98. - DWORD watcher_thread_id; - HANDLE watcher_thread = ::CreateThread( - nullptr, // Default security. - 0, // Default stack size - &ThreadLocalRegistryImpl::WatcherThreadFunc, - reinterpret_cast(new ThreadIdAndHandle(thread_id, thread)), - CREATE_SUSPENDED, &watcher_thread_id); - GTEST_CHECK_(watcher_thread != nullptr) - << "CreateThread failed with error " << ::GetLastError() << "."; - // Give the watcher thread the same priority as ours to avoid being - // blocked by it. - ::SetThreadPriority(watcher_thread, - ::GetThreadPriority(::GetCurrentThread())); - ::ResumeThread(watcher_thread); - ::CloseHandle(watcher_thread); - } - - // Monitors exit from a given thread and notifies those - // ThreadIdToThreadLocals about thread termination. - static DWORD WINAPI WatcherThreadFunc(LPVOID param) { - const ThreadIdAndHandle* tah = - reinterpret_cast(param); - GTEST_CHECK_(::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0); - OnThreadExit(tah->first); - ::CloseHandle(tah->second); - delete tah; - return 0; - } - - // Returns map of thread local instances. - static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() { - mutex_.AssertHeld(); -#ifdef _MSC_VER - MemoryIsNotDeallocated memory_is_not_deallocated; -#endif // _MSC_VER - static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals(); - return map; - } - - // Protects access to GetThreadLocalsMapLocked() and its return value. - static Mutex mutex_; - // Protects access to GetThreadMapLocked() and its return value. - static Mutex thread_map_mutex_; -}; - -Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); // NOLINT -Mutex ThreadLocalRegistryImpl::thread_map_mutex_( - Mutex::kStaticMutex); // NOLINT - -ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread( - const ThreadLocalBase* thread_local_instance) { - return ThreadLocalRegistryImpl::GetValueOnCurrentThread( - thread_local_instance); -} - -void ThreadLocalRegistry::OnThreadLocalDestroyed( - const ThreadLocalBase* thread_local_instance) { - ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance); -} - -#endif // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS - -#if GTEST_USES_POSIX_RE - -// Implements RE. Currently only needed for death tests. - -RE::~RE() { - if (is_valid_) { - // regfree'ing an invalid regex might crash because the content - // of the regex is undefined. Since the regex's are essentially - // the same, one cannot be valid (or invalid) without the other - // being so too. - regfree(&partial_regex_); - regfree(&full_regex_); - } - free(const_cast(pattern_)); -} - -// Returns true if and only if regular expression re matches the entire str. -bool RE::FullMatch(const char* str, const RE& re) { - if (!re.is_valid_) return false; - - regmatch_t match; - return regexec(&re.full_regex_, str, 1, &match, 0) == 0; -} - -// Returns true if and only if regular expression re matches a substring of -// str (including str itself). -bool RE::PartialMatch(const char* str, const RE& re) { - if (!re.is_valid_) return false; - - regmatch_t match; - return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; -} - -// Initializes an RE from its string representation. -void RE::Init(const char* regex) { - pattern_ = posix::StrDup(regex); - - // Reserves enough bytes to hold the regular expression used for a - // full match. - const size_t full_regex_len = strlen(regex) + 10; - char* const full_pattern = new char[full_regex_len]; - - snprintf(full_pattern, full_regex_len, "^(%s)$", regex); - is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; - // We want to call regcomp(&partial_regex_, ...) even if the - // previous expression returns false. Otherwise partial_regex_ may - // not be properly initialized can may cause trouble when it's - // freed. - // - // Some implementation of POSIX regex (e.g. on at least some - // versions of Cygwin) doesn't accept the empty string as a valid - // regex. We change it to an equivalent form "()" to be safe. - if (is_valid_) { - const char* const partial_regex = (*regex == '\0') ? "()" : regex; - is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; - } - EXPECT_TRUE(is_valid_) - << "Regular expression \"" << regex - << "\" is not a valid POSIX Extended regular expression."; - - delete[] full_pattern; -} - -#elif GTEST_USES_SIMPLE_RE - -// Returns true if and only if ch appears anywhere in str (excluding the -// terminating '\0' character). -bool IsInSet(char ch, const char* str) { - return ch != '\0' && strchr(str, ch) != nullptr; -} - -// Returns true if and only if ch belongs to the given classification. -// Unlike similar functions in , these aren't affected by the -// current locale. -bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } -bool IsAsciiPunct(char ch) { - return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); -} -bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } -bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } -bool IsAsciiWordChar(char ch) { - return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || - ('0' <= ch && ch <= '9') || ch == '_'; -} - -// Returns true if and only if "\\c" is a supported escape sequence. -bool IsValidEscape(char c) { - return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); -} - -// Returns true if and only if the given atom (specified by escaped and -// pattern) matches ch. The result is undefined if the atom is invalid. -bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { - if (escaped) { // "\\p" where p is pattern_char. - switch (pattern_char) { - case 'd': - return IsAsciiDigit(ch); - case 'D': - return !IsAsciiDigit(ch); - case 'f': - return ch == '\f'; - case 'n': - return ch == '\n'; - case 'r': - return ch == '\r'; - case 's': - return IsAsciiWhiteSpace(ch); - case 'S': - return !IsAsciiWhiteSpace(ch); - case 't': - return ch == '\t'; - case 'v': - return ch == '\v'; - case 'w': - return IsAsciiWordChar(ch); - case 'W': - return !IsAsciiWordChar(ch); - } - return IsAsciiPunct(pattern_char) && pattern_char == ch; - } - - return (pattern_char == '.' && ch != '\n') || pattern_char == ch; -} - -// Helper function used by ValidateRegex() to format error messages. -static std::string FormatRegexSyntaxError(const char* regex, int index) { - return (Message() << "Syntax error at index " << index - << " in simple regular expression \"" << regex << "\": ") - .GetString(); -} - -// Generates non-fatal failures and returns false if regex is invalid; -// otherwise returns true. -bool ValidateRegex(const char* regex) { - if (regex == nullptr) { - ADD_FAILURE() << "NULL is not a valid simple regular expression."; - return false; - } - - bool is_valid = true; - - // True if and only if ?, *, or + can follow the previous atom. - bool prev_repeatable = false; - for (int i = 0; regex[i]; i++) { - if (regex[i] == '\\') { // An escape sequence - i++; - if (regex[i] == '\0') { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) - << "'\\' cannot appear at the end."; - return false; - } - - if (!IsValidEscape(regex[i])) { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) - << "invalid escape sequence \"\\" << regex[i] << "\"."; - is_valid = false; - } - prev_repeatable = true; - } else { // Not an escape sequence. - const char ch = regex[i]; - - if (ch == '^' && i > 0) { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i) - << "'^' can only appear at the beginning."; - is_valid = false; - } else if (ch == '$' && regex[i + 1] != '\0') { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i) - << "'$' can only appear at the end."; - is_valid = false; - } else if (IsInSet(ch, "()[]{}|")) { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch - << "' is unsupported."; - is_valid = false; - } else if (IsRepeat(ch) && !prev_repeatable) { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch - << "' can only follow a repeatable token."; - is_valid = false; - } - - prev_repeatable = !IsInSet(ch, "^$?*+"); - } - } - - return is_valid; -} - -// Matches a repeated regex atom followed by a valid simple regular -// expression. The regex atom is defined as c if escaped is false, -// or \c otherwise. repeat is the repetition meta character (?, *, -// or +). The behavior is undefined if str contains too many -// characters to be indexable by size_t, in which case the test will -// probably time out anyway. We are fine with this limitation as -// std::string has it too. -bool MatchRepetitionAndRegexAtHead(bool escaped, char c, char repeat, - const char* regex, const char* str) { - const size_t min_count = (repeat == '+') ? 1 : 0; - const size_t max_count = (repeat == '?') ? 1 : static_cast(-1) - 1; - // We cannot call numeric_limits::max() as it conflicts with the - // max() macro on Windows. - - for (size_t i = 0; i <= max_count; ++i) { - // We know that the atom matches each of the first i characters in str. - if (i >= min_count && MatchRegexAtHead(regex, str + i)) { - // We have enough matches at the head, and the tail matches too. - // Since we only care about *whether* the pattern matches str - // (as opposed to *how* it matches), there is no need to find a - // greedy match. - return true; - } - if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) return false; - } - return false; -} - -// Returns true if and only if regex matches a prefix of str. regex must -// be a valid simple regular expression and not start with "^", or the -// result is undefined. -bool MatchRegexAtHead(const char* regex, const char* str) { - if (*regex == '\0') // An empty regex matches a prefix of anything. - return true; - - // "$" only matches the end of a string. Note that regex being - // valid guarantees that there's nothing after "$" in it. - if (*regex == '$') return *str == '\0'; - - // Is the first thing in regex an escape sequence? - const bool escaped = *regex == '\\'; - if (escaped) ++regex; - if (IsRepeat(regex[1])) { - // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so - // here's an indirect recursion. It terminates as the regex gets - // shorter in each recursion. - return MatchRepetitionAndRegexAtHead(escaped, regex[0], regex[1], regex + 2, - str); - } else { - // regex isn't empty, isn't "$", and doesn't start with a - // repetition. We match the first atom of regex with the first - // character of str and recurse. - return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && - MatchRegexAtHead(regex + 1, str + 1); - } -} - -// Returns true if and only if regex matches any substring of str. regex must -// be a valid simple regular expression, or the result is undefined. -// -// The algorithm is recursive, but the recursion depth doesn't exceed -// the regex length, so we won't need to worry about running out of -// stack space normally. In rare cases the time complexity can be -// exponential with respect to the regex length + the string length, -// but usually it's must faster (often close to linear). -bool MatchRegexAnywhere(const char* regex, const char* str) { - if (regex == nullptr || str == nullptr) return false; - - if (*regex == '^') return MatchRegexAtHead(regex + 1, str); - - // A successful match can be anywhere in str. - do { - if (MatchRegexAtHead(regex, str)) return true; - } while (*str++ != '\0'); - return false; -} - -// Implements the RE class. - -RE::~RE() { - free(const_cast(pattern_)); - free(const_cast(full_pattern_)); -} - -// Returns true if and only if regular expression re matches the entire str. -bool RE::FullMatch(const char* str, const RE& re) { - return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); -} - -// Returns true if and only if regular expression re matches a substring of -// str (including str itself). -bool RE::PartialMatch(const char* str, const RE& re) { - return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); -} - -// Initializes an RE from its string representation. -void RE::Init(const char* regex) { - pattern_ = full_pattern_ = nullptr; - if (regex != nullptr) { - pattern_ = posix::StrDup(regex); - } - - is_valid_ = ValidateRegex(regex); - if (!is_valid_) { - // No need to calculate the full pattern when the regex is invalid. - return; - } - - const size_t len = strlen(regex); - // Reserves enough bytes to hold the regular expression used for a - // full match: we need space to prepend a '^', append a '$', and - // terminate the string with '\0'. - char* buffer = static_cast(malloc(len + 3)); - full_pattern_ = buffer; - - if (*regex != '^') - *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. - - // We don't use snprintf or strncpy, as they trigger a warning when - // compiled with VC++ 8.0. - memcpy(buffer, regex, len); - buffer += len; - - if (len == 0 || regex[len - 1] != '$') - *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. - - *buffer = '\0'; -} - -#endif // GTEST_USES_POSIX_RE - -const char kUnknownFile[] = "unknown file"; - -// Formats a source file path and a line number as they would appear -// in an error message from the compiler used to compile this code. -GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { - const std::string file_name(file == nullptr ? kUnknownFile : file); - - if (line < 0) { - return file_name + ":"; - } -#ifdef _MSC_VER - return file_name + "(" + StreamableToString(line) + "):"; -#else - return file_name + ":" + StreamableToString(line) + ":"; -#endif // _MSC_VER -} - -// Formats a file location for compiler-independent XML output. -// Although this function is not platform dependent, we put it next to -// FormatFileLocation in order to contrast the two functions. -// Note that FormatCompilerIndependentFileLocation() does NOT append colon -// to the file location it produces, unlike FormatFileLocation(). -GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, - int line) { - const std::string file_name(file == nullptr ? kUnknownFile : file); - - if (line < 0) - return file_name; - else - return file_name + ":" + StreamableToString(line); -} - -GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) - : severity_(severity) { - const char* const marker = severity == GTEST_INFO ? "[ INFO ]" - : severity == GTEST_WARNING ? "[WARNING]" - : severity == GTEST_ERROR ? "[ ERROR ]" - : "[ FATAL ]"; - GetStream() << ::std::endl - << marker << " " << FormatFileLocation(file, line).c_str() - << ": "; -} - -// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. -GTestLog::~GTestLog() { - GetStream() << ::std::endl; - if (severity_ == GTEST_FATAL) { - fflush(stderr); - posix::Abort(); - } -} - -// Disable Microsoft deprecation warnings for POSIX functions called from -// this class (creat, dup, dup2, and close) -GTEST_DISABLE_MSC_DEPRECATED_PUSH_() - -#if GTEST_HAS_STREAM_REDIRECTION - -// Object that captures an output stream (stdout/stderr). -class CapturedStream { - public: - // The ctor redirects the stream to a temporary file. - explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { -#if GTEST_OS_WINDOWS - char temp_dir_path[MAX_PATH + 1] = {'\0'}; // NOLINT - char temp_file_path[MAX_PATH + 1] = {'\0'}; // NOLINT - - ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); - const UINT success = ::GetTempFileNameA(temp_dir_path, "gtest_redir", - 0, // Generate unique file name. - temp_file_path); - GTEST_CHECK_(success != 0) - << "Unable to create a temporary file in " << temp_dir_path; - const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); - GTEST_CHECK_(captured_fd != -1) - << "Unable to open temporary file " << temp_file_path; - filename_ = temp_file_path; -#else - // There's no guarantee that a test has write access to the current - // directory, so we create the temporary file in a temporary directory. - std::string name_template; - -#if GTEST_OS_LINUX_ANDROID - // Note: Android applications are expected to call the framework's - // Context.getExternalStorageDirectory() method through JNI to get - // the location of the world-writable SD Card directory. However, - // this requires a Context handle, which cannot be retrieved - // globally from native code. Doing so also precludes running the - // code as part of a regular standalone executable, which doesn't - // run in a Dalvik process (e.g. when running it through 'adb shell'). - // - // The location /data/local/tmp is directly accessible from native code. - // '/sdcard' and other variants cannot be relied on, as they are not - // guaranteed to be mounted, or may have a delay in mounting. - name_template = "/data/local/tmp/"; -#elif GTEST_OS_IOS - char user_temp_dir[PATH_MAX + 1]; - - // Documented alternative to NSTemporaryDirectory() (for obtaining creating - // a temporary directory) at - // https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/RaceConditions.html#//apple_ref/doc/uid/TP40002585-SW10 - // - // _CS_DARWIN_USER_TEMP_DIR (as well as _CS_DARWIN_USER_CACHE_DIR) is not - // documented in the confstr() man page at - // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/confstr.3.html#//apple_ref/doc/man/3/confstr - // but are still available, according to the WebKit patches at - // https://trac.webkit.org/changeset/262004/webkit - // https://trac.webkit.org/changeset/263705/webkit - // - // The confstr() implementation falls back to getenv("TMPDIR"). See - // https://opensource.apple.com/source/Libc/Libc-1439.100.3/gen/confstr.c.auto.html - ::confstr(_CS_DARWIN_USER_TEMP_DIR, user_temp_dir, sizeof(user_temp_dir)); - - name_template = user_temp_dir; - if (name_template.back() != GTEST_PATH_SEP_[0]) - name_template.push_back(GTEST_PATH_SEP_[0]); -#else - name_template = "/tmp/"; -#endif - name_template.append("gtest_captured_stream.XXXXXX"); - - // mkstemp() modifies the string bytes in place, and does not go beyond the - // string's length. This results in well-defined behavior in C++17. - // - // The const_cast is needed below C++17. The constraints on std::string - // implementations in C++11 and above make assumption behind the const_cast - // fairly safe. - const int captured_fd = ::mkstemp(const_cast(name_template.data())); - if (captured_fd == -1) { - GTEST_LOG_(WARNING) - << "Failed to create tmp file " << name_template - << " for test; does the test have access to the /tmp directory?"; - } - filename_ = std::move(name_template); -#endif // GTEST_OS_WINDOWS - fflush(nullptr); - dup2(captured_fd, fd_); - close(captured_fd); - } - - ~CapturedStream() { remove(filename_.c_str()); } - - std::string GetCapturedString() { - if (uncaptured_fd_ != -1) { - // Restores the original stream. - fflush(nullptr); - dup2(uncaptured_fd_, fd_); - close(uncaptured_fd_); - uncaptured_fd_ = -1; - } - - FILE* const file = posix::FOpen(filename_.c_str(), "r"); - if (file == nullptr) { - GTEST_LOG_(FATAL) << "Failed to open tmp file " << filename_ - << " for capturing stream."; - } - const std::string content = ReadEntireFile(file); - posix::FClose(file); - return content; - } - - private: - const int fd_; // A stream to capture. - int uncaptured_fd_; - // Name of the temporary file holding the stderr output. - ::std::string filename_; - - CapturedStream(const CapturedStream&) = delete; - CapturedStream& operator=(const CapturedStream&) = delete; -}; - -GTEST_DISABLE_MSC_DEPRECATED_POP_() - -static CapturedStream* g_captured_stderr = nullptr; -static CapturedStream* g_captured_stdout = nullptr; - -// Starts capturing an output stream (stdout/stderr). -static void CaptureStream(int fd, const char* stream_name, - CapturedStream** stream) { - if (*stream != nullptr) { - GTEST_LOG_(FATAL) << "Only one " << stream_name - << " capturer can exist at a time."; - } - *stream = new CapturedStream(fd); -} - -// Stops capturing the output stream and returns the captured string. -static std::string GetCapturedStream(CapturedStream** captured_stream) { - const std::string content = (*captured_stream)->GetCapturedString(); - - delete *captured_stream; - *captured_stream = nullptr; - - return content; -} - -#if defined(_MSC_VER) || defined(__BORLANDC__) -// MSVC and C++Builder do not provide a definition of STDERR_FILENO. -const int kStdOutFileno = 1; -const int kStdErrFileno = 2; -#else -const int kStdOutFileno = STDOUT_FILENO; -const int kStdErrFileno = STDERR_FILENO; -#endif // defined(_MSC_VER) || defined(__BORLANDC__) - -// Starts capturing stdout. -void CaptureStdout() { - CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); -} - -// Starts capturing stderr. -void CaptureStderr() { - CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); -} - -// Stops capturing stdout and returns the captured string. -std::string GetCapturedStdout() { - return GetCapturedStream(&g_captured_stdout); -} - -// Stops capturing stderr and returns the captured string. -std::string GetCapturedStderr() { - return GetCapturedStream(&g_captured_stderr); -} - -#endif // GTEST_HAS_STREAM_REDIRECTION - -size_t GetFileSize(FILE* file) { - fseek(file, 0, SEEK_END); - return static_cast(ftell(file)); -} - -std::string ReadEntireFile(FILE* file) { - const size_t file_size = GetFileSize(file); - char* const buffer = new char[file_size]; - - size_t bytes_last_read = 0; // # of bytes read in the last fread() - size_t bytes_read = 0; // # of bytes read so far - - fseek(file, 0, SEEK_SET); - - // Keeps reading the file until we cannot read further or the - // pre-determined file size is reached. - do { - bytes_last_read = - fread(buffer + bytes_read, 1, file_size - bytes_read, file); - bytes_read += bytes_last_read; - } while (bytes_last_read > 0 && bytes_read < file_size); - - const std::string content(buffer, bytes_read); - delete[] buffer; - - return content; -} - -#if GTEST_HAS_DEATH_TEST -static const std::vector* g_injected_test_argvs = - nullptr; // Owned. - -std::vector GetInjectableArgvs() { - if (g_injected_test_argvs != nullptr) { - return *g_injected_test_argvs; - } - return GetArgvs(); -} - -void SetInjectableArgvs(const std::vector* new_argvs) { - if (g_injected_test_argvs != new_argvs) delete g_injected_test_argvs; - g_injected_test_argvs = new_argvs; -} - -void SetInjectableArgvs(const std::vector& new_argvs) { - SetInjectableArgvs( - new std::vector(new_argvs.begin(), new_argvs.end())); -} - -void ClearInjectableArgvs() { - delete g_injected_test_argvs; - g_injected_test_argvs = nullptr; -} -#endif // GTEST_HAS_DEATH_TEST - -#if GTEST_OS_WINDOWS_MOBILE -namespace posix { -void Abort() { - DebugBreak(); - TerminateProcess(GetCurrentProcess(), 1); -} -} // namespace posix -#endif // GTEST_OS_WINDOWS_MOBILE - -// Returns the name of the environment variable corresponding to the -// given flag. For example, FlagToEnvVar("foo") will return -// "GTEST_FOO" in the open-source version. -static std::string FlagToEnvVar(const char* flag) { - const std::string full_flag = - (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); - - Message env_var; - for (size_t i = 0; i != full_flag.length(); i++) { - env_var << ToUpper(full_flag.c_str()[i]); - } - - return env_var.GetString(); -} - -// Parses 'str' for a 32-bit signed integer. If successful, writes -// the result to *value and returns true; otherwise leaves *value -// unchanged and returns false. -bool ParseInt32(const Message& src_text, const char* str, int32_t* value) { - // Parses the environment variable as a decimal integer. - char* end = nullptr; - const long long_value = strtol(str, &end, 10); // NOLINT - - // Has strtol() consumed all characters in the string? - if (*end != '\0') { - // No - an invalid character was encountered. - Message msg; - msg << "WARNING: " << src_text - << " is expected to be a 32-bit integer, but actually" - << " has value \"" << str << "\".\n"; - printf("%s", msg.GetString().c_str()); - fflush(stdout); - return false; - } - - // Is the parsed value in the range of an int32_t? - const auto result = static_cast(long_value); - if (long_value == LONG_MAX || long_value == LONG_MIN || - // The parsed value overflows as a long. (strtol() returns - // LONG_MAX or LONG_MIN when the input overflows.) - result != long_value - // The parsed value overflows as an int32_t. - ) { - Message msg; - msg << "WARNING: " << src_text - << " is expected to be a 32-bit integer, but actually" - << " has value " << str << ", which overflows.\n"; - printf("%s", msg.GetString().c_str()); - fflush(stdout); - return false; - } - - *value = result; - return true; -} - -// Reads and returns the Boolean environment variable corresponding to -// the given flag; if it's not set, returns default_value. -// -// The value is considered true if and only if it's not "0". -bool BoolFromGTestEnv(const char* flag, bool default_value) { -#if defined(GTEST_GET_BOOL_FROM_ENV_) - return GTEST_GET_BOOL_FROM_ENV_(flag, default_value); -#else - const std::string env_var = FlagToEnvVar(flag); - const char* const string_value = posix::GetEnv(env_var.c_str()); - return string_value == nullptr ? default_value - : strcmp(string_value, "0") != 0; -#endif // defined(GTEST_GET_BOOL_FROM_ENV_) -} - -// Reads and returns a 32-bit integer stored in the environment -// variable corresponding to the given flag; if it isn't set or -// doesn't represent a valid 32-bit integer, returns default_value. -int32_t Int32FromGTestEnv(const char* flag, int32_t default_value) { -#if defined(GTEST_GET_INT32_FROM_ENV_) - return GTEST_GET_INT32_FROM_ENV_(flag, default_value); -#else - const std::string env_var = FlagToEnvVar(flag); - const char* const string_value = posix::GetEnv(env_var.c_str()); - if (string_value == nullptr) { - // The environment variable is not set. - return default_value; - } - - int32_t result = default_value; - if (!ParseInt32(Message() << "Environment variable " << env_var, string_value, - &result)) { - printf("The default value %s is used.\n", - (Message() << default_value).GetString().c_str()); - fflush(stdout); - return default_value; - } - - return result; -#endif // defined(GTEST_GET_INT32_FROM_ENV_) -} - -// As a special case for the 'output' flag, if GTEST_OUTPUT is not -// set, we look for XML_OUTPUT_FILE, which is set by the Bazel build -// system. The value of XML_OUTPUT_FILE is a filename without the -// "xml:" prefix of GTEST_OUTPUT. -// Note that this is meant to be called at the call site so it does -// not check that the flag is 'output' -// In essence this checks an env variable called XML_OUTPUT_FILE -// and if it is set we prepend "xml:" to its value, if it not set we return "" -std::string OutputFlagAlsoCheckEnvVar() { - std::string default_value_for_output_flag = ""; - const char* xml_output_file_env = posix::GetEnv("XML_OUTPUT_FILE"); - if (nullptr != xml_output_file_env) { - default_value_for_output_flag = std::string("xml:") + xml_output_file_env; - } - return default_value_for_output_flag; -} - -// Reads and returns the string environment variable corresponding to -// the given flag; if it's not set, returns default_value. -const char* StringFromGTestEnv(const char* flag, const char* default_value) { -#if defined(GTEST_GET_STRING_FROM_ENV_) - return GTEST_GET_STRING_FROM_ENV_(flag, default_value); -#else - const std::string env_var = FlagToEnvVar(flag); - const char* const value = posix::GetEnv(env_var.c_str()); - return value == nullptr ? default_value : value; -#endif // defined(GTEST_GET_STRING_FROM_ENV_) -} - -} // namespace internal -} // namespace testing diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-printers.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-printers.cc deleted file mode 100644 index f3976d23..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-printers.cc +++ /dev/null @@ -1,553 +0,0 @@ -// Copyright 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Google Test - The Google C++ Testing and Mocking Framework -// -// This file implements a universal value printer that can print a -// value of any type T: -// -// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); -// -// It uses the << operator when possible, and prints the bytes in the -// object otherwise. A user can override its behavior for a class -// type Foo by defining either operator<<(::std::ostream&, const Foo&) -// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that -// defines Foo. - -#include "gtest/gtest-printers.h" - -#include - -#include -#include -#include -#include // NOLINT -#include -#include - -#include "gtest/internal/gtest-port.h" -#include "src/gtest-internal-inl.h" - -namespace testing { - -namespace { - -using ::std::ostream; - -// Prints a segment of bytes in the given object. -GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ -GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ -GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ -GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ -void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, - size_t count, ostream* os) { - char text[5] = ""; - for (size_t i = 0; i != count; i++) { - const size_t j = start + i; - if (i != 0) { - // Organizes the bytes into groups of 2 for easy parsing by - // human. - if ((j % 2) == 0) - *os << ' '; - else - *os << '-'; - } - GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); - *os << text; - } -} - -// Prints the bytes in the given value to the given ostream. -void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, - ostream* os) { - // Tells the user how big the object is. - *os << count << "-byte object <"; - - const size_t kThreshold = 132; - const size_t kChunkSize = 64; - // If the object size is bigger than kThreshold, we'll have to omit - // some details by printing only the first and the last kChunkSize - // bytes. - if (count < kThreshold) { - PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); - } else { - PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); - *os << " ... "; - // Rounds up to 2-byte boundary. - const size_t resume_pos = (count - kChunkSize + 1) / 2 * 2; - PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); - } - *os << ">"; -} - -// Helpers for widening a character to char32_t. Since the standard does not -// specify if char / wchar_t is signed or unsigned, it is important to first -// convert it to the unsigned type of the same width before widening it to -// char32_t. -template -char32_t ToChar32(CharType in) { - return static_cast( - static_cast::type>(in)); -} - -} // namespace - -namespace internal { - -// Delegates to PrintBytesInObjectToImpl() to print the bytes in the -// given object. The delegation simplifies the implementation, which -// uses the << operator and thus is easier done outside of the -// ::testing::internal namespace, which contains a << operator that -// sometimes conflicts with the one in STL. -void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, - ostream* os) { - PrintBytesInObjectToImpl(obj_bytes, count, os); -} - -// Depending on the value of a char (or wchar_t), we print it in one -// of three formats: -// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), -// - as a hexadecimal escape sequence (e.g. '\x7F'), or -// - as a special escape sequence (e.g. '\r', '\n'). -enum CharFormat { kAsIs, kHexEscape, kSpecialEscape }; - -// Returns true if c is a printable ASCII character. We test the -// value of c directly instead of calling isprint(), which is buggy on -// Windows Mobile. -inline bool IsPrintableAscii(char32_t c) { return 0x20 <= c && c <= 0x7E; } - -// Prints c (of type char, char8_t, char16_t, char32_t, or wchar_t) as a -// character literal without the quotes, escaping it when necessary; returns how -// c was formatted. -template -static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { - const char32_t u_c = ToChar32(c); - switch (u_c) { - case L'\0': - *os << "\\0"; - break; - case L'\'': - *os << "\\'"; - break; - case L'\\': - *os << "\\\\"; - break; - case L'\a': - *os << "\\a"; - break; - case L'\b': - *os << "\\b"; - break; - case L'\f': - *os << "\\f"; - break; - case L'\n': - *os << "\\n"; - break; - case L'\r': - *os << "\\r"; - break; - case L'\t': - *os << "\\t"; - break; - case L'\v': - *os << "\\v"; - break; - default: - if (IsPrintableAscii(u_c)) { - *os << static_cast(c); - return kAsIs; - } else { - ostream::fmtflags flags = os->flags(); - *os << "\\x" << std::hex << std::uppercase << static_cast(u_c); - os->flags(flags); - return kHexEscape; - } - } - return kSpecialEscape; -} - -// Prints a char32_t c as if it's part of a string literal, escaping it when -// necessary; returns how c was formatted. -static CharFormat PrintAsStringLiteralTo(char32_t c, ostream* os) { - switch (c) { - case L'\'': - *os << "'"; - return kAsIs; - case L'"': - *os << "\\\""; - return kSpecialEscape; - default: - return PrintAsCharLiteralTo(c, os); - } -} - -static const char* GetCharWidthPrefix(char) { return ""; } - -static const char* GetCharWidthPrefix(signed char) { return ""; } - -static const char* GetCharWidthPrefix(unsigned char) { return ""; } - -#ifdef __cpp_char8_t -static const char* GetCharWidthPrefix(char8_t) { return "u8"; } -#endif - -static const char* GetCharWidthPrefix(char16_t) { return "u"; } - -static const char* GetCharWidthPrefix(char32_t) { return "U"; } - -static const char* GetCharWidthPrefix(wchar_t) { return "L"; } - -// Prints a char c as if it's part of a string literal, escaping it when -// necessary; returns how c was formatted. -static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { - return PrintAsStringLiteralTo(ToChar32(c), os); -} - -#ifdef __cpp_char8_t -static CharFormat PrintAsStringLiteralTo(char8_t c, ostream* os) { - return PrintAsStringLiteralTo(ToChar32(c), os); -} -#endif - -static CharFormat PrintAsStringLiteralTo(char16_t c, ostream* os) { - return PrintAsStringLiteralTo(ToChar32(c), os); -} - -static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { - return PrintAsStringLiteralTo(ToChar32(c), os); -} - -// Prints a character c (of type char, char8_t, char16_t, char32_t, or wchar_t) -// and its code. '\0' is printed as "'\\0'", other unprintable characters are -// also properly escaped using the standard C++ escape sequence. -template -void PrintCharAndCodeTo(Char c, ostream* os) { - // First, print c as a literal in the most readable form we can find. - *os << GetCharWidthPrefix(c) << "'"; - const CharFormat format = PrintAsCharLiteralTo(c, os); - *os << "'"; - - // To aid user debugging, we also print c's code in decimal, unless - // it's 0 (in which case c was printed as '\\0', making the code - // obvious). - if (c == 0) return; - *os << " (" << static_cast(c); - - // For more convenience, we print c's code again in hexadecimal, - // unless c was already printed in the form '\x##' or the code is in - // [1, 9]. - if (format == kHexEscape || (1 <= c && c <= 9)) { - // Do nothing. - } else { - *os << ", 0x" << String::FormatHexInt(static_cast(c)); - } - *os << ")"; -} - -void PrintTo(unsigned char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); } -void PrintTo(signed char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); } - -// Prints a wchar_t as a symbol if it is printable or as its internal -// code otherwise and also as its code. L'\0' is printed as "L'\\0'". -void PrintTo(wchar_t wc, ostream* os) { PrintCharAndCodeTo(wc, os); } - -// TODO(dcheng): Consider making this delegate to PrintCharAndCodeTo() as well. -void PrintTo(char32_t c, ::std::ostream* os) { - *os << std::hex << "U+" << std::uppercase << std::setfill('0') << std::setw(4) - << static_cast(c); -} - -// gcc/clang __{u,}int128_t -#if defined(__SIZEOF_INT128__) -void PrintTo(__uint128_t v, ::std::ostream* os) { - if (v == 0) { - *os << "0"; - return; - } - - // Buffer large enough for ceil(log10(2^128))==39 and the null terminator - char buf[40]; - char* p = buf + sizeof(buf); - - // Some configurations have a __uint128_t, but no support for built in - // division. Do manual long division instead. - - uint64_t high = static_cast(v >> 64); - uint64_t low = static_cast(v); - - *--p = 0; - while (high != 0 || low != 0) { - uint64_t high_mod = high % 10; - high = high / 10; - // This is the long division algorithm specialized for a divisor of 10 and - // only two elements. - // Notable values: - // 2^64 / 10 == 1844674407370955161 - // 2^64 % 10 == 6 - const uint64_t carry = 6 * high_mod + low % 10; - low = low / 10 + high_mod * 1844674407370955161 + carry / 10; - - char digit = static_cast(carry % 10); - *--p = '0' + digit; - } - *os << p; -} -void PrintTo(__int128_t v, ::std::ostream* os) { - __uint128_t uv = static_cast<__uint128_t>(v); - if (v < 0) { - *os << "-"; - uv = -uv; - } - PrintTo(uv, os); -} -#endif // __SIZEOF_INT128__ - -// Prints the given array of characters to the ostream. CharType must be either -// char, char8_t, char16_t, char32_t, or wchar_t. -// The array starts at begin, the length is len, it may include '\0' characters -// and may not be NUL-terminated. -template -GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ - GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ - GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat - PrintCharsAsStringTo(const CharType* begin, size_t len, ostream* os) { - const char* const quote_prefix = GetCharWidthPrefix(*begin); - *os << quote_prefix << "\""; - bool is_previous_hex = false; - CharFormat print_format = kAsIs; - for (size_t index = 0; index < len; ++index) { - const CharType cur = begin[index]; - if (is_previous_hex && IsXDigit(cur)) { - // Previous character is of '\x..' form and this character can be - // interpreted as another hexadecimal digit in its number. Break string to - // disambiguate. - *os << "\" " << quote_prefix << "\""; - } - is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; - // Remember if any characters required hex escaping. - if (is_previous_hex) { - print_format = kHexEscape; - } - } - *os << "\""; - return print_format; -} - -// Prints a (const) char/wchar_t array of 'len' elements, starting at address -// 'begin'. CharType must be either char or wchar_t. -template -GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ - GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ - GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static void - UniversalPrintCharArray(const CharType* begin, size_t len, - ostream* os) { - // The code - // const char kFoo[] = "foo"; - // generates an array of 4, not 3, elements, with the last one being '\0'. - // - // Therefore when printing a char array, we don't print the last element if - // it's '\0', such that the output matches the string literal as it's - // written in the source code. - if (len > 0 && begin[len - 1] == '\0') { - PrintCharsAsStringTo(begin, len - 1, os); - return; - } - - // If, however, the last element in the array is not '\0', e.g. - // const char kFoo[] = { 'f', 'o', 'o' }; - // we must print the entire array. We also print a message to indicate - // that the array is not NUL-terminated. - PrintCharsAsStringTo(begin, len, os); - *os << " (no terminating NUL)"; -} - -// Prints a (const) char array of 'len' elements, starting at address 'begin'. -void UniversalPrintArray(const char* begin, size_t len, ostream* os) { - UniversalPrintCharArray(begin, len, os); -} - -#ifdef __cpp_char8_t -// Prints a (const) char8_t array of 'len' elements, starting at address -// 'begin'. -void UniversalPrintArray(const char8_t* begin, size_t len, ostream* os) { - UniversalPrintCharArray(begin, len, os); -} -#endif - -// Prints a (const) char16_t array of 'len' elements, starting at address -// 'begin'. -void UniversalPrintArray(const char16_t* begin, size_t len, ostream* os) { - UniversalPrintCharArray(begin, len, os); -} - -// Prints a (const) char32_t array of 'len' elements, starting at address -// 'begin'. -void UniversalPrintArray(const char32_t* begin, size_t len, ostream* os) { - UniversalPrintCharArray(begin, len, os); -} - -// Prints a (const) wchar_t array of 'len' elements, starting at address -// 'begin'. -void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { - UniversalPrintCharArray(begin, len, os); -} - -namespace { - -// Prints a null-terminated C-style string to the ostream. -template -void PrintCStringTo(const Char* s, ostream* os) { - if (s == nullptr) { - *os << "NULL"; - } else { - *os << ImplicitCast_(s) << " pointing to "; - PrintCharsAsStringTo(s, std::char_traits::length(s), os); - } -} - -} // anonymous namespace - -void PrintTo(const char* s, ostream* os) { PrintCStringTo(s, os); } - -#ifdef __cpp_char8_t -void PrintTo(const char8_t* s, ostream* os) { PrintCStringTo(s, os); } -#endif - -void PrintTo(const char16_t* s, ostream* os) { PrintCStringTo(s, os); } - -void PrintTo(const char32_t* s, ostream* os) { PrintCStringTo(s, os); } - -// MSVC compiler can be configured to define whar_t as a typedef -// of unsigned short. Defining an overload for const wchar_t* in that case -// would cause pointers to unsigned shorts be printed as wide strings, -// possibly accessing more memory than intended and causing invalid -// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when -// wchar_t is implemented as a native type. -#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) -// Prints the given wide C string to the ostream. -void PrintTo(const wchar_t* s, ostream* os) { PrintCStringTo(s, os); } -#endif // wchar_t is native - -namespace { - -bool ContainsUnprintableControlCodes(const char* str, size_t length) { - const unsigned char* s = reinterpret_cast(str); - - for (size_t i = 0; i < length; i++) { - unsigned char ch = *s++; - if (std::iscntrl(ch)) { - switch (ch) { - case '\t': - case '\n': - case '\r': - break; - default: - return true; - } - } - } - return false; -} - -bool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t <= 0xbf; } - -bool IsValidUTF8(const char* str, size_t length) { - const unsigned char* s = reinterpret_cast(str); - - for (size_t i = 0; i < length;) { - unsigned char lead = s[i++]; - - if (lead <= 0x7f) { - continue; // single-byte character (ASCII) 0..7F - } - if (lead < 0xc2) { - return false; // trail byte or non-shortest form - } else if (lead <= 0xdf && (i + 1) <= length && IsUTF8TrailByte(s[i])) { - ++i; // 2-byte character - } else if (0xe0 <= lead && lead <= 0xef && (i + 2) <= length && - IsUTF8TrailByte(s[i]) && IsUTF8TrailByte(s[i + 1]) && - // check for non-shortest form and surrogate - (lead != 0xe0 || s[i] >= 0xa0) && - (lead != 0xed || s[i] < 0xa0)) { - i += 2; // 3-byte character - } else if (0xf0 <= lead && lead <= 0xf4 && (i + 3) <= length && - IsUTF8TrailByte(s[i]) && IsUTF8TrailByte(s[i + 1]) && - IsUTF8TrailByte(s[i + 2]) && - // check for non-shortest form - (lead != 0xf0 || s[i] >= 0x90) && - (lead != 0xf4 || s[i] < 0x90)) { - i += 3; // 4-byte character - } else { - return false; - } - } - return true; -} - -void ConditionalPrintAsText(const char* str, size_t length, ostream* os) { - if (!ContainsUnprintableControlCodes(str, length) && - IsValidUTF8(str, length)) { - *os << "\n As Text: \"" << str << "\""; - } -} - -} // anonymous namespace - -void PrintStringTo(const ::std::string& s, ostream* os) { - if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) { - if (GTEST_FLAG_GET(print_utf8)) { - ConditionalPrintAsText(s.data(), s.size(), os); - } - } -} - -#ifdef __cpp_char8_t -void PrintU8StringTo(const ::std::u8string& s, ostream* os) { - PrintCharsAsStringTo(s.data(), s.size(), os); -} -#endif - -void PrintU16StringTo(const ::std::u16string& s, ostream* os) { - PrintCharsAsStringTo(s.data(), s.size(), os); -} - -void PrintU32StringTo(const ::std::u32string& s, ostream* os) { - PrintCharsAsStringTo(s.data(), s.size(), os); -} - -#if GTEST_HAS_STD_WSTRING -void PrintWideStringTo(const ::std::wstring& s, ostream* os) { - PrintCharsAsStringTo(s.data(), s.size(), os); -} -#endif // GTEST_HAS_STD_WSTRING - -} // namespace internal - -} // namespace testing diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-test-part.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-test-part.cc deleted file mode 100644 index eb7c8d1c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-test-part.cc +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// -// The Google C++ Testing and Mocking Framework (Google Test) - -#include "gtest/gtest-test-part.h" - -#include "gtest/internal/gtest-port.h" -#include "src/gtest-internal-inl.h" - -namespace testing { - -using internal::GetUnitTestImpl; - -// Gets the summary of the failure message by omitting the stack trace -// in it. -std::string TestPartResult::ExtractSummary(const char* message) { - const char* const stack_trace = strstr(message, internal::kStackTraceMarker); - return stack_trace == nullptr ? message : std::string(message, stack_trace); -} - -// Prints a TestPartResult object. -std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { - return os << internal::FormatFileLocation(result.file_name(), - result.line_number()) - << " " - << (result.type() == TestPartResult::kSuccess ? "Success" - : result.type() == TestPartResult::kSkip ? "Skipped" - : result.type() == TestPartResult::kFatalFailure - ? "Fatal failure" - : "Non-fatal failure") - << ":\n" - << result.message() << std::endl; -} - -// Appends a TestPartResult to the array. -void TestPartResultArray::Append(const TestPartResult& result) { - array_.push_back(result); -} - -// Returns the TestPartResult at the given index (0-based). -const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { - if (index < 0 || index >= size()) { - printf("\nInvalid index (%d) into TestPartResultArray.\n", index); - internal::posix::Abort(); - } - - return array_[static_cast(index)]; -} - -// Returns the number of TestPartResult objects in the array. -int TestPartResultArray::size() const { - return static_cast(array_.size()); -} - -namespace internal { - -HasNewFatalFailureHelper::HasNewFatalFailureHelper() - : has_new_fatal_failure_(false), - original_reporter_( - GetUnitTestImpl()->GetTestPartResultReporterForCurrentThread()) { - GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); -} - -HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { - GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( - original_reporter_); -} - -void HasNewFatalFailureHelper::ReportTestPartResult( - const TestPartResult& result) { - if (result.fatally_failed()) has_new_fatal_failure_ = true; - original_reporter_->ReportTestPartResult(result); -} - -} // namespace internal - -} // namespace testing diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-typed-test.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-typed-test.cc deleted file mode 100644 index a2828b83..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest-typed-test.cc +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2008 Google Inc. -// All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "gtest/gtest-typed-test.h" - -#include "gtest/gtest.h" - -namespace testing { -namespace internal { - -// Skips to the first non-space char in str. Returns an empty string if str -// contains only whitespace characters. -static const char* SkipSpaces(const char* str) { - while (IsSpace(*str)) str++; - return str; -} - -static std::vector SplitIntoTestNames(const char* src) { - std::vector name_vec; - src = SkipSpaces(src); - for (; src != nullptr; src = SkipComma(src)) { - name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src))); - } - return name_vec; -} - -// Verifies that registered_tests match the test names in -// registered_tests_; returns registered_tests if successful, or -// aborts the program otherwise. -const char* TypedTestSuitePState::VerifyRegisteredTestNames( - const char* test_suite_name, const char* file, int line, - const char* registered_tests) { - RegisterTypeParameterizedTestSuite(test_suite_name, CodeLocation(file, line)); - - typedef RegisteredTestsMap::const_iterator RegisteredTestIter; - registered_ = true; - - std::vector name_vec = SplitIntoTestNames(registered_tests); - - Message errors; - - std::set tests; - for (std::vector::const_iterator name_it = name_vec.begin(); - name_it != name_vec.end(); ++name_it) { - const std::string& name = *name_it; - if (tests.count(name) != 0) { - errors << "Test " << name << " is listed more than once.\n"; - continue; - } - - if (registered_tests_.count(name) != 0) { - tests.insert(name); - } else { - errors << "No test named " << name - << " can be found in this test suite.\n"; - } - } - - for (RegisteredTestIter it = registered_tests_.begin(); - it != registered_tests_.end(); ++it) { - if (tests.count(it->first) == 0) { - errors << "You forgot to list test " << it->first << ".\n"; - } - } - - const std::string& errors_str = errors.GetString(); - if (errors_str != "") { - fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), - errors_str.c_str()); - fflush(stderr); - posix::Abort(); - } - - return registered_tests; -} - -} // namespace internal -} // namespace testing diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest.cc deleted file mode 100644 index 6f31dd22..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest.cc +++ /dev/null @@ -1,6795 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// -// The Google C++ Testing and Mocking Framework (Google Test) - -#include "gtest/gtest.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include // NOLINT -#include -#include -#include -#include -#include -#include -#include -#include -#include // NOLINT -#include -#include -#include - -#include "gtest/gtest-assertion-result.h" -#include "gtest/gtest-spi.h" -#include "gtest/internal/custom/gtest.h" - -#if GTEST_OS_LINUX - -#include // NOLINT -#include // NOLINT -#include // NOLINT -// Declares vsnprintf(). This header is not available on Windows. -#include // NOLINT -#include // NOLINT -#include // NOLINT -#include // NOLINT - -#include - -#elif GTEST_OS_ZOS -#include // NOLINT - -// On z/OS we additionally need strings.h for strcasecmp. -#include // NOLINT - -#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. - -#include // NOLINT -#undef min - -#elif GTEST_OS_WINDOWS // We are on Windows proper. - -#include // NOLINT -#undef min - -#ifdef _MSC_VER -#include // NOLINT -#endif - -#include // NOLINT -#include // NOLINT -#include // NOLINT -#include // NOLINT - -#if GTEST_OS_WINDOWS_MINGW -#include // NOLINT -#endif // GTEST_OS_WINDOWS_MINGW - -#else - -// cpplint thinks that the header is already included, so we want to -// silence it. -#include // NOLINT -#include // NOLINT - -#endif // GTEST_OS_LINUX - -#if GTEST_HAS_EXCEPTIONS -#include -#endif - -#if GTEST_CAN_STREAM_RESULTS_ -#include // NOLINT -#include // NOLINT -#include // NOLINT -#include // NOLINT -#endif - -#include "src/gtest-internal-inl.h" - -#if GTEST_OS_WINDOWS -#define vsnprintf _vsnprintf -#endif // GTEST_OS_WINDOWS - -#if GTEST_OS_MAC -#ifndef GTEST_OS_IOS -#include -#endif -#endif - -#if GTEST_HAS_ABSL -#include "absl/debugging/failure_signal_handler.h" -#include "absl/debugging/stacktrace.h" -#include "absl/debugging/symbolize.h" -#include "absl/flags/parse.h" -#include "absl/flags/usage.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_replace.h" -#endif // GTEST_HAS_ABSL - -namespace testing { - -using internal::CountIf; -using internal::ForEach; -using internal::GetElementOr; -using internal::Shuffle; - -// Constants. - -// A test whose test suite name or test name matches this filter is -// disabled and not run. -static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; - -// A test suite whose name matches this filter is considered a death -// test suite and will be run before test suites whose name doesn't -// match this filter. -static const char kDeathTestSuiteFilter[] = "*DeathTest:*DeathTest/*"; - -// A test filter that matches everything. -static const char kUniversalFilter[] = "*"; - -// The default output format. -static const char kDefaultOutputFormat[] = "xml"; -// The default output file. -static const char kDefaultOutputFile[] = "test_detail"; - -// The environment variable name for the test shard index. -static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; -// The environment variable name for the total number of test shards. -static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; -// The environment variable name for the test shard status file. -static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; - -namespace internal { - -// The text used in failure messages to indicate the start of the -// stack trace. -const char kStackTraceMarker[] = "\nStack trace:\n"; - -// g_help_flag is true if and only if the --help flag or an equivalent form -// is specified on the command line. -bool g_help_flag = false; - -// Utility function to Open File for Writing -static FILE* OpenFileForWriting(const std::string& output_file) { - FILE* fileout = nullptr; - FilePath output_file_path(output_file); - FilePath output_dir(output_file_path.RemoveFileName()); - - if (output_dir.CreateDirectoriesRecursively()) { - fileout = posix::FOpen(output_file.c_str(), "w"); - } - if (fileout == nullptr) { - GTEST_LOG_(FATAL) << "Unable to open file \"" << output_file << "\""; - } - return fileout; -} - -} // namespace internal - -// Bazel passes in the argument to '--test_filter' via the TESTBRIDGE_TEST_ONLY -// environment variable. -static const char* GetDefaultFilter() { - const char* const testbridge_test_only = - internal::posix::GetEnv("TESTBRIDGE_TEST_ONLY"); - if (testbridge_test_only != nullptr) { - return testbridge_test_only; - } - return kUniversalFilter; -} - -// Bazel passes in the argument to '--test_runner_fail_fast' via the -// TESTBRIDGE_TEST_RUNNER_FAIL_FAST environment variable. -static bool GetDefaultFailFast() { - const char* const testbridge_test_runner_fail_fast = - internal::posix::GetEnv("TESTBRIDGE_TEST_RUNNER_FAIL_FAST"); - if (testbridge_test_runner_fail_fast != nullptr) { - return strcmp(testbridge_test_runner_fail_fast, "1") == 0; - } - return false; -} - -} // namespace testing - -GTEST_DEFINE_bool_( - fail_fast, - testing::internal::BoolFromGTestEnv("fail_fast", - testing::GetDefaultFailFast()), - "True if and only if a test failure should stop further test execution."); - -GTEST_DEFINE_bool_( - also_run_disabled_tests, - testing::internal::BoolFromGTestEnv("also_run_disabled_tests", false), - "Run disabled tests too, in addition to the tests normally being run."); - -GTEST_DEFINE_bool_( - break_on_failure, - testing::internal::BoolFromGTestEnv("break_on_failure", false), - "True if and only if a failed assertion should be a debugger " - "break-point."); - -GTEST_DEFINE_bool_(catch_exceptions, - testing::internal::BoolFromGTestEnv("catch_exceptions", - true), - "True if and only if " GTEST_NAME_ - " should catch exceptions and treat them as test failures."); - -GTEST_DEFINE_string_( - color, testing::internal::StringFromGTestEnv("color", "auto"), - "Whether to use colors in the output. Valid values: yes, no, " - "and auto. 'auto' means to use colors if the output is " - "being sent to a terminal and the TERM environment variable " - "is set to a terminal type that supports colors."); - -GTEST_DEFINE_string_( - filter, - testing::internal::StringFromGTestEnv("filter", - testing::GetDefaultFilter()), - "A colon-separated list of glob (not regex) patterns " - "for filtering the tests to run, optionally followed by a " - "'-' and a : separated list of negative patterns (tests to " - "exclude). A test is run if it matches one of the positive " - "patterns and does not match any of the negative patterns."); - -GTEST_DEFINE_bool_( - install_failure_signal_handler, - testing::internal::BoolFromGTestEnv("install_failure_signal_handler", - false), - "If true and supported on the current platform, " GTEST_NAME_ - " should " - "install a signal handler that dumps debugging information when fatal " - "signals are raised."); - -GTEST_DEFINE_bool_(list_tests, false, "List all tests without running them."); - -// The net priority order after flag processing is thus: -// --gtest_output command line flag -// GTEST_OUTPUT environment variable -// XML_OUTPUT_FILE environment variable -// '' -GTEST_DEFINE_string_( - output, - testing::internal::StringFromGTestEnv( - "output", testing::internal::OutputFlagAlsoCheckEnvVar().c_str()), - "A format (defaults to \"xml\" but can be specified to be \"json\"), " - "optionally followed by a colon and an output file name or directory. " - "A directory is indicated by a trailing pathname separator. " - "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " - "If a directory is specified, output files will be created " - "within that directory, with file-names based on the test " - "executable's name and, if necessary, made unique by adding " - "digits."); - -GTEST_DEFINE_bool_( - brief, testing::internal::BoolFromGTestEnv("brief", false), - "True if only test failures should be displayed in text output."); - -GTEST_DEFINE_bool_(print_time, - testing::internal::BoolFromGTestEnv("print_time", true), - "True if and only if " GTEST_NAME_ - " should display elapsed time in text output."); - -GTEST_DEFINE_bool_(print_utf8, - testing::internal::BoolFromGTestEnv("print_utf8", true), - "True if and only if " GTEST_NAME_ - " prints UTF8 characters as text."); - -GTEST_DEFINE_int32_( - random_seed, testing::internal::Int32FromGTestEnv("random_seed", 0), - "Random number seed to use when shuffling test orders. Must be in range " - "[1, 99999], or 0 to use a seed based on the current time."); - -GTEST_DEFINE_int32_( - repeat, testing::internal::Int32FromGTestEnv("repeat", 1), - "How many times to repeat each test. Specify a negative number " - "for repeating forever. Useful for shaking out flaky tests."); - -GTEST_DEFINE_bool_( - recreate_environments_when_repeating, - testing::internal::BoolFromGTestEnv("recreate_environments_when_repeating", - false), - "Controls whether global test environments are recreated for each repeat " - "of the tests. If set to false the global test environments are only set " - "up once, for the first iteration, and only torn down once, for the last. " - "Useful for shaking out flaky tests with stable, expensive test " - "environments. If --gtest_repeat is set to a negative number, meaning " - "there is no last run, the environments will always be recreated to avoid " - "leaks."); - -GTEST_DEFINE_bool_(show_internal_stack_frames, false, - "True if and only if " GTEST_NAME_ - " should include internal stack frames when " - "printing test failure stack traces."); - -GTEST_DEFINE_bool_(shuffle, - testing::internal::BoolFromGTestEnv("shuffle", false), - "True if and only if " GTEST_NAME_ - " should randomize tests' order on every run."); - -GTEST_DEFINE_int32_( - stack_trace_depth, - testing::internal::Int32FromGTestEnv("stack_trace_depth", - testing::kMaxStackTraceDepth), - "The maximum number of stack frames to print when an " - "assertion fails. The valid range is 0 through 100, inclusive."); - -GTEST_DEFINE_string_( - stream_result_to, - testing::internal::StringFromGTestEnv("stream_result_to", ""), - "This flag specifies the host name and the port number on which to stream " - "test results. Example: \"localhost:555\". The flag is effective only on " - "Linux."); - -GTEST_DEFINE_bool_( - throw_on_failure, - testing::internal::BoolFromGTestEnv("throw_on_failure", false), - "When this flag is specified, a failed assertion will throw an exception " - "if exceptions are enabled or exit the program with a non-zero code " - "otherwise. For use with an external test framework."); - -#if GTEST_USE_OWN_FLAGFILE_FLAG_ -GTEST_DEFINE_string_( - flagfile, testing::internal::StringFromGTestEnv("flagfile", ""), - "This flag specifies the flagfile to read command-line flags from."); -#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ - -namespace testing { -namespace internal { - -// Generates a random number from [0, range), using a Linear -// Congruential Generator (LCG). Crashes if 'range' is 0 or greater -// than kMaxRange. -uint32_t Random::Generate(uint32_t range) { - // These constants are the same as are used in glibc's rand(3). - // Use wider types than necessary to prevent unsigned overflow diagnostics. - state_ = static_cast(1103515245ULL * state_ + 12345U) % kMaxRange; - - GTEST_CHECK_(range > 0) << "Cannot generate a number in the range [0, 0)."; - GTEST_CHECK_(range <= kMaxRange) - << "Generation of a number in [0, " << range << ") was requested, " - << "but this can only generate numbers in [0, " << kMaxRange << ")."; - - // Converting via modulus introduces a bit of downward bias, but - // it's simple, and a linear congruential generator isn't too good - // to begin with. - return state_ % range; -} - -// GTestIsInitialized() returns true if and only if the user has initialized -// Google Test. Useful for catching the user mistake of not initializing -// Google Test before calling RUN_ALL_TESTS(). -static bool GTestIsInitialized() { return GetArgvs().size() > 0; } - -// Iterates over a vector of TestSuites, keeping a running sum of the -// results of calling a given int-returning method on each. -// Returns the sum. -static int SumOverTestSuiteList(const std::vector& case_list, - int (TestSuite::*method)() const) { - int sum = 0; - for (size_t i = 0; i < case_list.size(); i++) { - sum += (case_list[i]->*method)(); - } - return sum; -} - -// Returns true if and only if the test suite passed. -static bool TestSuitePassed(const TestSuite* test_suite) { - return test_suite->should_run() && test_suite->Passed(); -} - -// Returns true if and only if the test suite failed. -static bool TestSuiteFailed(const TestSuite* test_suite) { - return test_suite->should_run() && test_suite->Failed(); -} - -// Returns true if and only if test_suite contains at least one test that -// should run. -static bool ShouldRunTestSuite(const TestSuite* test_suite) { - return test_suite->should_run(); -} - -// AssertHelper constructor. -AssertHelper::AssertHelper(TestPartResult::Type type, const char* file, - int line, const char* message) - : data_(new AssertHelperData(type, file, line, message)) {} - -AssertHelper::~AssertHelper() { delete data_; } - -// Message assignment, for assertion streaming support. -void AssertHelper::operator=(const Message& message) const { - UnitTest::GetInstance()->AddTestPartResult( - data_->type, data_->file, data_->line, - AppendUserMessage(data_->message, message), - UnitTest::GetInstance()->impl()->CurrentOsStackTraceExceptTop(1) - // Skips the stack frame for this function itself. - ); // NOLINT -} - -namespace { - -// When TEST_P is found without a matching INSTANTIATE_TEST_SUITE_P -// to creates test cases for it, a synthetic test case is -// inserted to report ether an error or a log message. -// -// This configuration bit will likely be removed at some point. -constexpr bool kErrorOnUninstantiatedParameterizedTest = true; -constexpr bool kErrorOnUninstantiatedTypeParameterizedTest = true; - -// A test that fails at a given file/line location with a given message. -class FailureTest : public Test { - public: - explicit FailureTest(const CodeLocation& loc, std::string error_message, - bool as_error) - : loc_(loc), - error_message_(std::move(error_message)), - as_error_(as_error) {} - - void TestBody() override { - if (as_error_) { - AssertHelper(TestPartResult::kNonFatalFailure, loc_.file.c_str(), - loc_.line, "") = Message() << error_message_; - } else { - std::cout << error_message_ << std::endl; - } - } - - private: - const CodeLocation loc_; - const std::string error_message_; - const bool as_error_; -}; - -} // namespace - -std::set* GetIgnoredParameterizedTestSuites() { - return UnitTest::GetInstance()->impl()->ignored_parameterized_test_suites(); -} - -// Add a given test_suit to the list of them allow to go un-instantiated. -MarkAsIgnored::MarkAsIgnored(const char* test_suite) { - GetIgnoredParameterizedTestSuites()->insert(test_suite); -} - -// If this parameterized test suite has no instantiations (and that -// has not been marked as okay), emit a test case reporting that. -void InsertSyntheticTestCase(const std::string& name, CodeLocation location, - bool has_test_p) { - const auto& ignored = *GetIgnoredParameterizedTestSuites(); - if (ignored.find(name) != ignored.end()) return; - - const char kMissingInstantiation[] = // - " is defined via TEST_P, but never instantiated. None of the test cases " - "will run. Either no INSTANTIATE_TEST_SUITE_P is provided or the only " - "ones provided expand to nothing." - "\n\n" - "Ideally, TEST_P definitions should only ever be included as part of " - "binaries that intend to use them. (As opposed to, for example, being " - "placed in a library that may be linked in to get other utilities.)"; - - const char kMissingTestCase[] = // - " is instantiated via INSTANTIATE_TEST_SUITE_P, but no tests are " - "defined via TEST_P . No test cases will run." - "\n\n" - "Ideally, INSTANTIATE_TEST_SUITE_P should only ever be invoked from " - "code that always depend on code that provides TEST_P. Failing to do " - "so is often an indication of dead code, e.g. the last TEST_P was " - "removed but the rest got left behind."; - - std::string message = - "Parameterized test suite " + name + - (has_test_p ? kMissingInstantiation : kMissingTestCase) + - "\n\n" - "To suppress this error for this test suite, insert the following line " - "(in a non-header) in the namespace it is defined in:" - "\n\n" - "GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(" + - name + ");"; - - std::string full_name = "UninstantiatedParameterizedTestSuite<" + name + ">"; - RegisterTest( // - "GoogleTestVerification", full_name.c_str(), - nullptr, // No type parameter. - nullptr, // No value parameter. - location.file.c_str(), location.line, [message, location] { - return new FailureTest(location, message, - kErrorOnUninstantiatedParameterizedTest); - }); -} - -void RegisterTypeParameterizedTestSuite(const char* test_suite_name, - CodeLocation code_location) { - GetUnitTestImpl()->type_parameterized_test_registry().RegisterTestSuite( - test_suite_name, code_location); -} - -void RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) { - GetUnitTestImpl()->type_parameterized_test_registry().RegisterInstantiation( - case_name); -} - -void TypeParameterizedTestSuiteRegistry::RegisterTestSuite( - const char* test_suite_name, CodeLocation code_location) { - suites_.emplace(std::string(test_suite_name), - TypeParameterizedTestSuiteInfo(code_location)); -} - -void TypeParameterizedTestSuiteRegistry::RegisterInstantiation( - const char* test_suite_name) { - auto it = suites_.find(std::string(test_suite_name)); - if (it != suites_.end()) { - it->second.instantiated = true; - } else { - GTEST_LOG_(ERROR) << "Unknown type parameterized test suit '" - << test_suite_name << "'"; - } -} - -void TypeParameterizedTestSuiteRegistry::CheckForInstantiations() { - const auto& ignored = *GetIgnoredParameterizedTestSuites(); - for (const auto& testcase : suites_) { - if (testcase.second.instantiated) continue; - if (ignored.find(testcase.first) != ignored.end()) continue; - - std::string message = - "Type parameterized test suite " + testcase.first + - " is defined via REGISTER_TYPED_TEST_SUITE_P, but never instantiated " - "via INSTANTIATE_TYPED_TEST_SUITE_P. None of the test cases will run." - "\n\n" - "Ideally, TYPED_TEST_P definitions should only ever be included as " - "part of binaries that intend to use them. (As opposed to, for " - "example, being placed in a library that may be linked in to get other " - "utilities.)" - "\n\n" - "To suppress this error for this test suite, insert the following line " - "(in a non-header) in the namespace it is defined in:" - "\n\n" - "GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(" + - testcase.first + ");"; - - std::string full_name = - "UninstantiatedTypeParameterizedTestSuite<" + testcase.first + ">"; - RegisterTest( // - "GoogleTestVerification", full_name.c_str(), - nullptr, // No type parameter. - nullptr, // No value parameter. - testcase.second.code_location.file.c_str(), - testcase.second.code_location.line, [message, testcase] { - return new FailureTest(testcase.second.code_location, message, - kErrorOnUninstantiatedTypeParameterizedTest); - }); - } -} - -// A copy of all command line arguments. Set by InitGoogleTest(). -static ::std::vector g_argvs; - -::std::vector GetArgvs() { -#if defined(GTEST_CUSTOM_GET_ARGVS_) - // GTEST_CUSTOM_GET_ARGVS_() may return a container of std::string or - // ::string. This code converts it to the appropriate type. - const auto& custom = GTEST_CUSTOM_GET_ARGVS_(); - return ::std::vector(custom.begin(), custom.end()); -#else // defined(GTEST_CUSTOM_GET_ARGVS_) - return g_argvs; -#endif // defined(GTEST_CUSTOM_GET_ARGVS_) -} - -// Returns the current application's name, removing directory path if that -// is present. -FilePath GetCurrentExecutableName() { - FilePath result; - -#if GTEST_OS_WINDOWS || GTEST_OS_OS2 - result.Set(FilePath(GetArgvs()[0]).RemoveExtension("exe")); -#else - result.Set(FilePath(GetArgvs()[0])); -#endif // GTEST_OS_WINDOWS - - return result.RemoveDirectoryName(); -} - -// Functions for processing the gtest_output flag. - -// Returns the output format, or "" for normal printed output. -std::string UnitTestOptions::GetOutputFormat() { - std::string s = GTEST_FLAG_GET(output); - const char* const gtest_output_flag = s.c_str(); - const char* const colon = strchr(gtest_output_flag, ':'); - return (colon == nullptr) - ? std::string(gtest_output_flag) - : std::string(gtest_output_flag, - static_cast(colon - gtest_output_flag)); -} - -// Returns the name of the requested output file, or the default if none -// was explicitly specified. -std::string UnitTestOptions::GetAbsolutePathToOutputFile() { - std::string s = GTEST_FLAG_GET(output); - const char* const gtest_output_flag = s.c_str(); - - std::string format = GetOutputFormat(); - if (format.empty()) format = std::string(kDefaultOutputFormat); - - const char* const colon = strchr(gtest_output_flag, ':'); - if (colon == nullptr) - return internal::FilePath::MakeFileName( - internal::FilePath( - UnitTest::GetInstance()->original_working_dir()), - internal::FilePath(kDefaultOutputFile), 0, format.c_str()) - .string(); - - internal::FilePath output_name(colon + 1); - if (!output_name.IsAbsolutePath()) - output_name = internal::FilePath::ConcatPaths( - internal::FilePath(UnitTest::GetInstance()->original_working_dir()), - internal::FilePath(colon + 1)); - - if (!output_name.IsDirectory()) return output_name.string(); - - internal::FilePath result(internal::FilePath::GenerateUniqueFileName( - output_name, internal::GetCurrentExecutableName(), - GetOutputFormat().c_str())); - return result.string(); -} - -// Returns true if and only if the wildcard pattern matches the string. Each -// pattern consists of regular characters, single-character wildcards (?), and -// multi-character wildcards (*). -// -// This function implements a linear-time string globbing algorithm based on -// https://research.swtch.com/glob. -static bool PatternMatchesString(const std::string& name_str, - const char* pattern, const char* pattern_end) { - const char* name = name_str.c_str(); - const char* const name_begin = name; - const char* const name_end = name + name_str.size(); - - const char* pattern_next = pattern; - const char* name_next = name; - - while (pattern < pattern_end || name < name_end) { - if (pattern < pattern_end) { - switch (*pattern) { - default: // Match an ordinary character. - if (name < name_end && *name == *pattern) { - ++pattern; - ++name; - continue; - } - break; - case '?': // Match any single character. - if (name < name_end) { - ++pattern; - ++name; - continue; - } - break; - case '*': - // Match zero or more characters. Start by skipping over the wildcard - // and matching zero characters from name. If that fails, restart and - // match one more character than the last attempt. - pattern_next = pattern; - name_next = name + 1; - ++pattern; - continue; - } - } - // Failed to match a character. Restart if possible. - if (name_begin < name_next && name_next <= name_end) { - pattern = pattern_next; - name = name_next; - continue; - } - return false; - } - return true; -} - -namespace { - -bool IsGlobPattern(const std::string& pattern) { - return std::any_of(pattern.begin(), pattern.end(), - [](const char c) { return c == '?' || c == '*'; }); -} - -class UnitTestFilter { - public: - UnitTestFilter() = default; - - // Constructs a filter from a string of patterns separated by `:`. - explicit UnitTestFilter(const std::string& filter) { - // By design "" filter matches "" string. - std::vector all_patterns; - SplitString(filter, ':', &all_patterns); - const auto exact_match_patterns_begin = std::partition( - all_patterns.begin(), all_patterns.end(), &IsGlobPattern); - - glob_patterns_.reserve(static_cast( - std::distance(all_patterns.begin(), exact_match_patterns_begin))); - std::move(all_patterns.begin(), exact_match_patterns_begin, - std::inserter(glob_patterns_, glob_patterns_.begin())); - std::move( - exact_match_patterns_begin, all_patterns.end(), - std::inserter(exact_match_patterns_, exact_match_patterns_.begin())); - } - - // Returns true if and only if name matches at least one of the patterns in - // the filter. - bool MatchesName(const std::string& name) const { - return exact_match_patterns_.count(name) > 0 || - std::any_of(glob_patterns_.begin(), glob_patterns_.end(), - [&name](const std::string& pattern) { - return PatternMatchesString( - name, pattern.c_str(), - pattern.c_str() + pattern.size()); - }); - } - - private: - std::vector glob_patterns_; - std::unordered_set exact_match_patterns_; -}; - -class PositiveAndNegativeUnitTestFilter { - public: - // Constructs a positive and a negative filter from a string. The string - // contains a positive filter optionally followed by a '-' character and a - // negative filter. In case only a negative filter is provided the positive - // filter will be assumed "*". - // A filter is a list of patterns separated by ':'. - explicit PositiveAndNegativeUnitTestFilter(const std::string& filter) { - std::vector positive_and_negative_filters; - - // NOTE: `SplitString` always returns a non-empty container. - SplitString(filter, '-', &positive_and_negative_filters); - const auto& positive_filter = positive_and_negative_filters.front(); - - if (positive_and_negative_filters.size() > 1) { - positive_filter_ = UnitTestFilter( - positive_filter.empty() ? kUniversalFilter : positive_filter); - - // TODO(b/214626361): Fail on multiple '-' characters - // For the moment to preserve old behavior we concatenate the rest of the - // string parts with `-` as separator to generate the negative filter. - auto negative_filter_string = positive_and_negative_filters[1]; - for (std::size_t i = 2; i < positive_and_negative_filters.size(); i++) - negative_filter_string = - negative_filter_string + '-' + positive_and_negative_filters[i]; - negative_filter_ = UnitTestFilter(negative_filter_string); - } else { - // In case we don't have a negative filter and positive filter is "" - // we do not use kUniversalFilter by design as opposed to when we have a - // negative filter. - positive_filter_ = UnitTestFilter(positive_filter); - } - } - - // Returns true if and only if test name (this is generated by appending test - // suit name and test name via a '.' character) matches the positive filter - // and does not match the negative filter. - bool MatchesTest(const std::string& test_suite_name, - const std::string& test_name) const { - return MatchesName(test_suite_name + "." + test_name); - } - - // Returns true if and only if name matches the positive filter and does not - // match the negative filter. - bool MatchesName(const std::string& name) const { - return positive_filter_.MatchesName(name) && - !negative_filter_.MatchesName(name); - } - - private: - UnitTestFilter positive_filter_; - UnitTestFilter negative_filter_; -}; -} // namespace - -bool UnitTestOptions::MatchesFilter(const std::string& name_str, - const char* filter) { - return UnitTestFilter(filter).MatchesName(name_str); -} - -// Returns true if and only if the user-specified filter matches the test -// suite name and the test name. -bool UnitTestOptions::FilterMatchesTest(const std::string& test_suite_name, - const std::string& test_name) { - // Split --gtest_filter at '-', if there is one, to separate into - // positive filter and negative filter portions - return PositiveAndNegativeUnitTestFilter(GTEST_FLAG_GET(filter)) - .MatchesTest(test_suite_name, test_name); -} - -#if GTEST_HAS_SEH -// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the -// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. -// This function is useful as an __except condition. -int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { - // Google Test should handle a SEH exception if: - // 1. the user wants it to, AND - // 2. this is not a breakpoint exception, AND - // 3. this is not a C++ exception (VC++ implements them via SEH, - // apparently). - // - // SEH exception code for C++ exceptions. - // (see http://support.microsoft.com/kb/185294 for more information). - const DWORD kCxxExceptionCode = 0xe06d7363; - - bool should_handle = true; - - if (!GTEST_FLAG_GET(catch_exceptions)) - should_handle = false; - else if (exception_code == EXCEPTION_BREAKPOINT) - should_handle = false; - else if (exception_code == kCxxExceptionCode) - should_handle = false; - - return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; -} -#endif // GTEST_HAS_SEH - -} // namespace internal - -// The c'tor sets this object as the test part result reporter used by -// Google Test. The 'result' parameter specifies where to report the -// results. Intercepts only failures from the current thread. -ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( - TestPartResultArray* result) - : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), result_(result) { - Init(); -} - -// The c'tor sets this object as the test part result reporter used by -// Google Test. The 'result' parameter specifies where to report the -// results. -ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( - InterceptMode intercept_mode, TestPartResultArray* result) - : intercept_mode_(intercept_mode), result_(result) { - Init(); -} - -void ScopedFakeTestPartResultReporter::Init() { - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - if (intercept_mode_ == INTERCEPT_ALL_THREADS) { - old_reporter_ = impl->GetGlobalTestPartResultReporter(); - impl->SetGlobalTestPartResultReporter(this); - } else { - old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); - impl->SetTestPartResultReporterForCurrentThread(this); - } -} - -// The d'tor restores the test part result reporter used by Google Test -// before. -ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - if (intercept_mode_ == INTERCEPT_ALL_THREADS) { - impl->SetGlobalTestPartResultReporter(old_reporter_); - } else { - impl->SetTestPartResultReporterForCurrentThread(old_reporter_); - } -} - -// Increments the test part result count and remembers the result. -// This method is from the TestPartResultReporterInterface interface. -void ScopedFakeTestPartResultReporter::ReportTestPartResult( - const TestPartResult& result) { - result_->Append(result); -} - -namespace internal { - -// Returns the type ID of ::testing::Test. We should always call this -// instead of GetTypeId< ::testing::Test>() to get the type ID of -// testing::Test. This is to work around a suspected linker bug when -// using Google Test as a framework on Mac OS X. The bug causes -// GetTypeId< ::testing::Test>() to return different values depending -// on whether the call is from the Google Test framework itself or -// from user test code. GetTestTypeId() is guaranteed to always -// return the same value, as it always calls GetTypeId<>() from the -// gtest.cc, which is within the Google Test framework. -TypeId GetTestTypeId() { return GetTypeId(); } - -// The value of GetTestTypeId() as seen from within the Google Test -// library. This is solely for testing GetTestTypeId(). -extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); - -// This predicate-formatter checks that 'results' contains a test part -// failure of the given type and that the failure message contains the -// given substring. -static AssertionResult HasOneFailure(const char* /* results_expr */, - const char* /* type_expr */, - const char* /* substr_expr */, - const TestPartResultArray& results, - TestPartResult::Type type, - const std::string& substr) { - const std::string expected(type == TestPartResult::kFatalFailure - ? "1 fatal failure" - : "1 non-fatal failure"); - Message msg; - if (results.size() != 1) { - msg << "Expected: " << expected << "\n" - << " Actual: " << results.size() << " failures"; - for (int i = 0; i < results.size(); i++) { - msg << "\n" << results.GetTestPartResult(i); - } - return AssertionFailure() << msg; - } - - const TestPartResult& r = results.GetTestPartResult(0); - if (r.type() != type) { - return AssertionFailure() << "Expected: " << expected << "\n" - << " Actual:\n" - << r; - } - - if (strstr(r.message(), substr.c_str()) == nullptr) { - return AssertionFailure() - << "Expected: " << expected << " containing \"" << substr << "\"\n" - << " Actual:\n" - << r; - } - - return AssertionSuccess(); -} - -// The constructor of SingleFailureChecker remembers where to look up -// test part results, what type of failure we expect, and what -// substring the failure message should contain. -SingleFailureChecker::SingleFailureChecker(const TestPartResultArray* results, - TestPartResult::Type type, - const std::string& substr) - : results_(results), type_(type), substr_(substr) {} - -// The destructor of SingleFailureChecker verifies that the given -// TestPartResultArray contains exactly one failure that has the given -// type and contains the given substring. If that's not the case, a -// non-fatal failure will be generated. -SingleFailureChecker::~SingleFailureChecker() { - EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); -} - -DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( - UnitTestImpl* unit_test) - : unit_test_(unit_test) {} - -void DefaultGlobalTestPartResultReporter::ReportTestPartResult( - const TestPartResult& result) { - unit_test_->current_test_result()->AddTestPartResult(result); - unit_test_->listeners()->repeater()->OnTestPartResult(result); -} - -DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( - UnitTestImpl* unit_test) - : unit_test_(unit_test) {} - -void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( - const TestPartResult& result) { - unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); -} - -// Returns the global test part result reporter. -TestPartResultReporterInterface* -UnitTestImpl::GetGlobalTestPartResultReporter() { - internal::MutexLock lock(&global_test_part_result_reporter_mutex_); - return global_test_part_result_repoter_; -} - -// Sets the global test part result reporter. -void UnitTestImpl::SetGlobalTestPartResultReporter( - TestPartResultReporterInterface* reporter) { - internal::MutexLock lock(&global_test_part_result_reporter_mutex_); - global_test_part_result_repoter_ = reporter; -} - -// Returns the test part result reporter for the current thread. -TestPartResultReporterInterface* -UnitTestImpl::GetTestPartResultReporterForCurrentThread() { - return per_thread_test_part_result_reporter_.get(); -} - -// Sets the test part result reporter for the current thread. -void UnitTestImpl::SetTestPartResultReporterForCurrentThread( - TestPartResultReporterInterface* reporter) { - per_thread_test_part_result_reporter_.set(reporter); -} - -// Gets the number of successful test suites. -int UnitTestImpl::successful_test_suite_count() const { - return CountIf(test_suites_, TestSuitePassed); -} - -// Gets the number of failed test suites. -int UnitTestImpl::failed_test_suite_count() const { - return CountIf(test_suites_, TestSuiteFailed); -} - -// Gets the number of all test suites. -int UnitTestImpl::total_test_suite_count() const { - return static_cast(test_suites_.size()); -} - -// Gets the number of all test suites that contain at least one test -// that should run. -int UnitTestImpl::test_suite_to_run_count() const { - return CountIf(test_suites_, ShouldRunTestSuite); -} - -// Gets the number of successful tests. -int UnitTestImpl::successful_test_count() const { - return SumOverTestSuiteList(test_suites_, &TestSuite::successful_test_count); -} - -// Gets the number of skipped tests. -int UnitTestImpl::skipped_test_count() const { - return SumOverTestSuiteList(test_suites_, &TestSuite::skipped_test_count); -} - -// Gets the number of failed tests. -int UnitTestImpl::failed_test_count() const { - return SumOverTestSuiteList(test_suites_, &TestSuite::failed_test_count); -} - -// Gets the number of disabled tests that will be reported in the XML report. -int UnitTestImpl::reportable_disabled_test_count() const { - return SumOverTestSuiteList(test_suites_, - &TestSuite::reportable_disabled_test_count); -} - -// Gets the number of disabled tests. -int UnitTestImpl::disabled_test_count() const { - return SumOverTestSuiteList(test_suites_, &TestSuite::disabled_test_count); -} - -// Gets the number of tests to be printed in the XML report. -int UnitTestImpl::reportable_test_count() const { - return SumOverTestSuiteList(test_suites_, &TestSuite::reportable_test_count); -} - -// Gets the number of all tests. -int UnitTestImpl::total_test_count() const { - return SumOverTestSuiteList(test_suites_, &TestSuite::total_test_count); -} - -// Gets the number of tests that should run. -int UnitTestImpl::test_to_run_count() const { - return SumOverTestSuiteList(test_suites_, &TestSuite::test_to_run_count); -} - -// Returns the current OS stack trace as an std::string. -// -// The maximum number of stack frames to be included is specified by -// the gtest_stack_trace_depth flag. The skip_count parameter -// specifies the number of top frames to be skipped, which doesn't -// count against the number of frames to be included. -// -// For example, if Foo() calls Bar(), which in turn calls -// CurrentOsStackTraceExceptTop(1), Foo() will be included in the -// trace but Bar() and CurrentOsStackTraceExceptTop() won't. -std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { - return os_stack_trace_getter()->CurrentStackTrace( - static_cast(GTEST_FLAG_GET(stack_trace_depth)), skip_count + 1 - // Skips the user-specified number of frames plus this function - // itself. - ); // NOLINT -} - -// A helper class for measuring elapsed times. -class Timer { - public: - Timer() : start_(std::chrono::steady_clock::now()) {} - - // Return time elapsed in milliseconds since the timer was created. - TimeInMillis Elapsed() { - return std::chrono::duration_cast( - std::chrono::steady_clock::now() - start_) - .count(); - } - - private: - std::chrono::steady_clock::time_point start_; -}; - -// Returns a timestamp as milliseconds since the epoch. Note this time may jump -// around subject to adjustments by the system, to measure elapsed time use -// Timer instead. -TimeInMillis GetTimeInMillis() { - return std::chrono::duration_cast( - std::chrono::system_clock::now() - - std::chrono::system_clock::from_time_t(0)) - .count(); -} - -// Utilities - -// class String. - -#if GTEST_OS_WINDOWS_MOBILE -// Creates a UTF-16 wide string from the given ANSI string, allocating -// memory using new. The caller is responsible for deleting the return -// value using delete[]. Returns the wide string, or NULL if the -// input is NULL. -LPCWSTR String::AnsiToUtf16(const char* ansi) { - if (!ansi) return nullptr; - const int length = strlen(ansi); - const int unicode_length = - MultiByteToWideChar(CP_ACP, 0, ansi, length, nullptr, 0); - WCHAR* unicode = new WCHAR[unicode_length + 1]; - MultiByteToWideChar(CP_ACP, 0, ansi, length, unicode, unicode_length); - unicode[unicode_length] = 0; - return unicode; -} - -// Creates an ANSI string from the given wide string, allocating -// memory using new. The caller is responsible for deleting the return -// value using delete[]. Returns the ANSI string, or NULL if the -// input is NULL. -const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { - if (!utf16_str) return nullptr; - const int ansi_length = WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, nullptr, - 0, nullptr, nullptr); - char* ansi = new char[ansi_length + 1]; - WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, ansi, ansi_length, nullptr, - nullptr); - ansi[ansi_length] = 0; - return ansi; -} - -#endif // GTEST_OS_WINDOWS_MOBILE - -// Compares two C strings. Returns true if and only if they have the same -// content. -// -// Unlike strcmp(), this function can handle NULL argument(s). A NULL -// C string is considered different to any non-NULL C string, -// including the empty string. -bool String::CStringEquals(const char* lhs, const char* rhs) { - if (lhs == nullptr) return rhs == nullptr; - - if (rhs == nullptr) return false; - - return strcmp(lhs, rhs) == 0; -} - -#if GTEST_HAS_STD_WSTRING - -// Converts an array of wide chars to a narrow string using the UTF-8 -// encoding, and streams the result to the given Message object. -static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, - Message* msg) { - for (size_t i = 0; i != length;) { // NOLINT - if (wstr[i] != L'\0') { - *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); - while (i != length && wstr[i] != L'\0') i++; - } else { - *msg << '\0'; - i++; - } - } -} - -#endif // GTEST_HAS_STD_WSTRING - -void SplitString(const ::std::string& str, char delimiter, - ::std::vector< ::std::string>* dest) { - ::std::vector< ::std::string> parsed; - ::std::string::size_type pos = 0; - while (::testing::internal::AlwaysTrue()) { - const ::std::string::size_type colon = str.find(delimiter, pos); - if (colon == ::std::string::npos) { - parsed.push_back(str.substr(pos)); - break; - } else { - parsed.push_back(str.substr(pos, colon - pos)); - pos = colon + 1; - } - } - dest->swap(parsed); -} - -} // namespace internal - -// Constructs an empty Message. -// We allocate the stringstream separately because otherwise each use of -// ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's -// stack frame leading to huge stack frames in some cases; gcc does not reuse -// the stack space. -Message::Message() : ss_(new ::std::stringstream) { - // By default, we want there to be enough precision when printing - // a double to a Message. - *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); -} - -// These two overloads allow streaming a wide C string to a Message -// using the UTF-8 encoding. -Message& Message::operator<<(const wchar_t* wide_c_str) { - return *this << internal::String::ShowWideCString(wide_c_str); -} -Message& Message::operator<<(wchar_t* wide_c_str) { - return *this << internal::String::ShowWideCString(wide_c_str); -} - -#if GTEST_HAS_STD_WSTRING -// Converts the given wide string to a narrow string using the UTF-8 -// encoding, and streams the result to this Message object. -Message& Message::operator<<(const ::std::wstring& wstr) { - internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); - return *this; -} -#endif // GTEST_HAS_STD_WSTRING - -// Gets the text streamed to this object so far as an std::string. -// Each '\0' character in the buffer is replaced with "\\0". -std::string Message::GetString() const { - return internal::StringStreamToString(ss_.get()); -} - -namespace internal { - -namespace edit_distance { -std::vector CalculateOptimalEdits(const std::vector& left, - const std::vector& right) { - std::vector > costs( - left.size() + 1, std::vector(right.size() + 1)); - std::vector > best_move( - left.size() + 1, std::vector(right.size() + 1)); - - // Populate for empty right. - for (size_t l_i = 0; l_i < costs.size(); ++l_i) { - costs[l_i][0] = static_cast(l_i); - best_move[l_i][0] = kRemove; - } - // Populate for empty left. - for (size_t r_i = 1; r_i < costs[0].size(); ++r_i) { - costs[0][r_i] = static_cast(r_i); - best_move[0][r_i] = kAdd; - } - - for (size_t l_i = 0; l_i < left.size(); ++l_i) { - for (size_t r_i = 0; r_i < right.size(); ++r_i) { - if (left[l_i] == right[r_i]) { - // Found a match. Consume it. - costs[l_i + 1][r_i + 1] = costs[l_i][r_i]; - best_move[l_i + 1][r_i + 1] = kMatch; - continue; - } - - const double add = costs[l_i + 1][r_i]; - const double remove = costs[l_i][r_i + 1]; - const double replace = costs[l_i][r_i]; - if (add < remove && add < replace) { - costs[l_i + 1][r_i + 1] = add + 1; - best_move[l_i + 1][r_i + 1] = kAdd; - } else if (remove < add && remove < replace) { - costs[l_i + 1][r_i + 1] = remove + 1; - best_move[l_i + 1][r_i + 1] = kRemove; - } else { - // We make replace a little more expensive than add/remove to lower - // their priority. - costs[l_i + 1][r_i + 1] = replace + 1.00001; - best_move[l_i + 1][r_i + 1] = kReplace; - } - } - } - - // Reconstruct the best path. We do it in reverse order. - std::vector best_path; - for (size_t l_i = left.size(), r_i = right.size(); l_i > 0 || r_i > 0;) { - EditType move = best_move[l_i][r_i]; - best_path.push_back(move); - l_i -= move != kAdd; - r_i -= move != kRemove; - } - std::reverse(best_path.begin(), best_path.end()); - return best_path; -} - -namespace { - -// Helper class to convert string into ids with deduplication. -class InternalStrings { - public: - size_t GetId(const std::string& str) { - IdMap::iterator it = ids_.find(str); - if (it != ids_.end()) return it->second; - size_t id = ids_.size(); - return ids_[str] = id; - } - - private: - typedef std::map IdMap; - IdMap ids_; -}; - -} // namespace - -std::vector CalculateOptimalEdits( - const std::vector& left, - const std::vector& right) { - std::vector left_ids, right_ids; - { - InternalStrings intern_table; - for (size_t i = 0; i < left.size(); ++i) { - left_ids.push_back(intern_table.GetId(left[i])); - } - for (size_t i = 0; i < right.size(); ++i) { - right_ids.push_back(intern_table.GetId(right[i])); - } - } - return CalculateOptimalEdits(left_ids, right_ids); -} - -namespace { - -// Helper class that holds the state for one hunk and prints it out to the -// stream. -// It reorders adds/removes when possible to group all removes before all -// adds. It also adds the hunk header before printint into the stream. -class Hunk { - public: - Hunk(size_t left_start, size_t right_start) - : left_start_(left_start), - right_start_(right_start), - adds_(), - removes_(), - common_() {} - - void PushLine(char edit, const char* line) { - switch (edit) { - case ' ': - ++common_; - FlushEdits(); - hunk_.push_back(std::make_pair(' ', line)); - break; - case '-': - ++removes_; - hunk_removes_.push_back(std::make_pair('-', line)); - break; - case '+': - ++adds_; - hunk_adds_.push_back(std::make_pair('+', line)); - break; - } - } - - void PrintTo(std::ostream* os) { - PrintHeader(os); - FlushEdits(); - for (std::list >::const_iterator it = - hunk_.begin(); - it != hunk_.end(); ++it) { - *os << it->first << it->second << "\n"; - } - } - - bool has_edits() const { return adds_ || removes_; } - - private: - void FlushEdits() { - hunk_.splice(hunk_.end(), hunk_removes_); - hunk_.splice(hunk_.end(), hunk_adds_); - } - - // Print a unified diff header for one hunk. - // The format is - // "@@ -, +, @@" - // where the left/right parts are omitted if unnecessary. - void PrintHeader(std::ostream* ss) const { - *ss << "@@ "; - if (removes_) { - *ss << "-" << left_start_ << "," << (removes_ + common_); - } - if (removes_ && adds_) { - *ss << " "; - } - if (adds_) { - *ss << "+" << right_start_ << "," << (adds_ + common_); - } - *ss << " @@\n"; - } - - size_t left_start_, right_start_; - size_t adds_, removes_, common_; - std::list > hunk_, hunk_adds_, hunk_removes_; -}; - -} // namespace - -// Create a list of diff hunks in Unified diff format. -// Each hunk has a header generated by PrintHeader above plus a body with -// lines prefixed with ' ' for no change, '-' for deletion and '+' for -// addition. -// 'context' represents the desired unchanged prefix/suffix around the diff. -// If two hunks are close enough that their contexts overlap, then they are -// joined into one hunk. -std::string CreateUnifiedDiff(const std::vector& left, - const std::vector& right, - size_t context) { - const std::vector edits = CalculateOptimalEdits(left, right); - - size_t l_i = 0, r_i = 0, edit_i = 0; - std::stringstream ss; - while (edit_i < edits.size()) { - // Find first edit. - while (edit_i < edits.size() && edits[edit_i] == kMatch) { - ++l_i; - ++r_i; - ++edit_i; - } - - // Find the first line to include in the hunk. - const size_t prefix_context = std::min(l_i, context); - Hunk hunk(l_i - prefix_context + 1, r_i - prefix_context + 1); - for (size_t i = prefix_context; i > 0; --i) { - hunk.PushLine(' ', left[l_i - i].c_str()); - } - - // Iterate the edits until we found enough suffix for the hunk or the input - // is over. - size_t n_suffix = 0; - for (; edit_i < edits.size(); ++edit_i) { - if (n_suffix >= context) { - // Continue only if the next hunk is very close. - auto it = edits.begin() + static_cast(edit_i); - while (it != edits.end() && *it == kMatch) ++it; - if (it == edits.end() || - static_cast(it - edits.begin()) - edit_i >= context) { - // There is no next edit or it is too far away. - break; - } - } - - EditType edit = edits[edit_i]; - // Reset count when a non match is found. - n_suffix = edit == kMatch ? n_suffix + 1 : 0; - - if (edit == kMatch || edit == kRemove || edit == kReplace) { - hunk.PushLine(edit == kMatch ? ' ' : '-', left[l_i].c_str()); - } - if (edit == kAdd || edit == kReplace) { - hunk.PushLine('+', right[r_i].c_str()); - } - - // Advance indices, depending on edit type. - l_i += edit != kAdd; - r_i += edit != kRemove; - } - - if (!hunk.has_edits()) { - // We are done. We don't want this hunk. - break; - } - - hunk.PrintTo(&ss); - } - return ss.str(); -} - -} // namespace edit_distance - -namespace { - -// The string representation of the values received in EqFailure() are already -// escaped. Split them on escaped '\n' boundaries. Leave all other escaped -// characters the same. -std::vector SplitEscapedString(const std::string& str) { - std::vector lines; - size_t start = 0, end = str.size(); - if (end > 2 && str[0] == '"' && str[end - 1] == '"') { - ++start; - --end; - } - bool escaped = false; - for (size_t i = start; i + 1 < end; ++i) { - if (escaped) { - escaped = false; - if (str[i] == 'n') { - lines.push_back(str.substr(start, i - start - 1)); - start = i + 1; - } - } else { - escaped = str[i] == '\\'; - } - } - lines.push_back(str.substr(start, end - start)); - return lines; -} - -} // namespace - -// Constructs and returns the message for an equality assertion -// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. -// -// The first four parameters are the expressions used in the assertion -// and their values, as strings. For example, for ASSERT_EQ(foo, bar) -// where foo is 5 and bar is 6, we have: -// -// lhs_expression: "foo" -// rhs_expression: "bar" -// lhs_value: "5" -// rhs_value: "6" -// -// The ignoring_case parameter is true if and only if the assertion is a -// *_STRCASEEQ*. When it's true, the string "Ignoring case" will -// be inserted into the message. -AssertionResult EqFailure(const char* lhs_expression, - const char* rhs_expression, - const std::string& lhs_value, - const std::string& rhs_value, bool ignoring_case) { - Message msg; - msg << "Expected equality of these values:"; - msg << "\n " << lhs_expression; - if (lhs_value != lhs_expression) { - msg << "\n Which is: " << lhs_value; - } - msg << "\n " << rhs_expression; - if (rhs_value != rhs_expression) { - msg << "\n Which is: " << rhs_value; - } - - if (ignoring_case) { - msg << "\nIgnoring case"; - } - - if (!lhs_value.empty() && !rhs_value.empty()) { - const std::vector lhs_lines = SplitEscapedString(lhs_value); - const std::vector rhs_lines = SplitEscapedString(rhs_value); - if (lhs_lines.size() > 1 || rhs_lines.size() > 1) { - msg << "\nWith diff:\n" - << edit_distance::CreateUnifiedDiff(lhs_lines, rhs_lines); - } - } - - return AssertionFailure() << msg; -} - -// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. -std::string GetBoolAssertionFailureMessage( - const AssertionResult& assertion_result, const char* expression_text, - const char* actual_predicate_value, const char* expected_predicate_value) { - const char* actual_message = assertion_result.message(); - Message msg; - msg << "Value of: " << expression_text - << "\n Actual: " << actual_predicate_value; - if (actual_message[0] != '\0') msg << " (" << actual_message << ")"; - msg << "\nExpected: " << expected_predicate_value; - return msg.GetString(); -} - -// Helper function for implementing ASSERT_NEAR. -AssertionResult DoubleNearPredFormat(const char* expr1, const char* expr2, - const char* abs_error_expr, double val1, - double val2, double abs_error) { - const double diff = fabs(val1 - val2); - if (diff <= abs_error) return AssertionSuccess(); - - // Find the value which is closest to zero. - const double min_abs = std::min(fabs(val1), fabs(val2)); - // Find the distance to the next double from that value. - const double epsilon = - nextafter(min_abs, std::numeric_limits::infinity()) - min_abs; - // Detect the case where abs_error is so small that EXPECT_NEAR is - // effectively the same as EXPECT_EQUAL, and give an informative error - // message so that the situation can be more easily understood without - // requiring exotic floating-point knowledge. - // Don't do an epsilon check if abs_error is zero because that implies - // that an equality check was actually intended. - if (!(std::isnan)(val1) && !(std::isnan)(val2) && abs_error > 0 && - abs_error < epsilon) { - return AssertionFailure() - << "The difference between " << expr1 << " and " << expr2 << " is " - << diff << ", where\n" - << expr1 << " evaluates to " << val1 << ",\n" - << expr2 << " evaluates to " << val2 << ".\nThe abs_error parameter " - << abs_error_expr << " evaluates to " << abs_error - << " which is smaller than the minimum distance between doubles for " - "numbers of this magnitude which is " - << epsilon - << ", thus making this EXPECT_NEAR check equivalent to " - "EXPECT_EQUAL. Consider using EXPECT_DOUBLE_EQ instead."; - } - return AssertionFailure() - << "The difference between " << expr1 << " and " << expr2 << " is " - << diff << ", which exceeds " << abs_error_expr << ", where\n" - << expr1 << " evaluates to " << val1 << ",\n" - << expr2 << " evaluates to " << val2 << ", and\n" - << abs_error_expr << " evaluates to " << abs_error << "."; -} - -// Helper template for implementing FloatLE() and DoubleLE(). -template -AssertionResult FloatingPointLE(const char* expr1, const char* expr2, - RawType val1, RawType val2) { - // Returns success if val1 is less than val2, - if (val1 < val2) { - return AssertionSuccess(); - } - - // or if val1 is almost equal to val2. - const FloatingPoint lhs(val1), rhs(val2); - if (lhs.AlmostEquals(rhs)) { - return AssertionSuccess(); - } - - // Note that the above two checks will both fail if either val1 or - // val2 is NaN, as the IEEE floating-point standard requires that - // any predicate involving a NaN must return false. - - ::std::stringstream val1_ss; - val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) - << val1; - - ::std::stringstream val2_ss; - val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) - << val2; - - return AssertionFailure() - << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" - << " Actual: " << StringStreamToString(&val1_ss) << " vs " - << StringStreamToString(&val2_ss); -} - -} // namespace internal - -// Asserts that val1 is less than, or almost equal to, val2. Fails -// otherwise. In particular, it fails if either val1 or val2 is NaN. -AssertionResult FloatLE(const char* expr1, const char* expr2, float val1, - float val2) { - return internal::FloatingPointLE(expr1, expr2, val1, val2); -} - -// Asserts that val1 is less than, or almost equal to, val2. Fails -// otherwise. In particular, it fails if either val1 or val2 is NaN. -AssertionResult DoubleLE(const char* expr1, const char* expr2, double val1, - double val2) { - return internal::FloatingPointLE(expr1, expr2, val1, val2); -} - -namespace internal { - -// The helper function for {ASSERT|EXPECT}_STREQ. -AssertionResult CmpHelperSTREQ(const char* lhs_expression, - const char* rhs_expression, const char* lhs, - const char* rhs) { - if (String::CStringEquals(lhs, rhs)) { - return AssertionSuccess(); - } - - return EqFailure(lhs_expression, rhs_expression, PrintToString(lhs), - PrintToString(rhs), false); -} - -// The helper function for {ASSERT|EXPECT}_STRCASEEQ. -AssertionResult CmpHelperSTRCASEEQ(const char* lhs_expression, - const char* rhs_expression, const char* lhs, - const char* rhs) { - if (String::CaseInsensitiveCStringEquals(lhs, rhs)) { - return AssertionSuccess(); - } - - return EqFailure(lhs_expression, rhs_expression, PrintToString(lhs), - PrintToString(rhs), true); -} - -// The helper function for {ASSERT|EXPECT}_STRNE. -AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, const char* s1, - const char* s2) { - if (!String::CStringEquals(s1, s2)) { - return AssertionSuccess(); - } else { - return AssertionFailure() - << "Expected: (" << s1_expression << ") != (" << s2_expression - << "), actual: \"" << s1 << "\" vs \"" << s2 << "\""; - } -} - -// The helper function for {ASSERT|EXPECT}_STRCASENE. -AssertionResult CmpHelperSTRCASENE(const char* s1_expression, - const char* s2_expression, const char* s1, - const char* s2) { - if (!String::CaseInsensitiveCStringEquals(s1, s2)) { - return AssertionSuccess(); - } else { - return AssertionFailure() - << "Expected: (" << s1_expression << ") != (" << s2_expression - << ") (ignoring case), actual: \"" << s1 << "\" vs \"" << s2 << "\""; - } -} - -} // namespace internal - -namespace { - -// Helper functions for implementing IsSubString() and IsNotSubstring(). - -// This group of overloaded functions return true if and only if needle -// is a substring of haystack. NULL is considered a substring of -// itself only. - -bool IsSubstringPred(const char* needle, const char* haystack) { - if (needle == nullptr || haystack == nullptr) return needle == haystack; - - return strstr(haystack, needle) != nullptr; -} - -bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { - if (needle == nullptr || haystack == nullptr) return needle == haystack; - - return wcsstr(haystack, needle) != nullptr; -} - -// StringType here can be either ::std::string or ::std::wstring. -template -bool IsSubstringPred(const StringType& needle, const StringType& haystack) { - return haystack.find(needle) != StringType::npos; -} - -// This function implements either IsSubstring() or IsNotSubstring(), -// depending on the value of the expected_to_be_substring parameter. -// StringType here can be const char*, const wchar_t*, ::std::string, -// or ::std::wstring. -template -AssertionResult IsSubstringImpl(bool expected_to_be_substring, - const char* needle_expr, - const char* haystack_expr, - const StringType& needle, - const StringType& haystack) { - if (IsSubstringPred(needle, haystack) == expected_to_be_substring) - return AssertionSuccess(); - - const bool is_wide_string = sizeof(needle[0]) > 1; - const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; - return AssertionFailure() - << "Value of: " << needle_expr << "\n" - << " Actual: " << begin_string_quote << needle << "\"\n" - << "Expected: " << (expected_to_be_substring ? "" : "not ") - << "a substring of " << haystack_expr << "\n" - << "Which is: " << begin_string_quote << haystack << "\""; -} - -} // namespace - -// IsSubstring() and IsNotSubstring() check whether needle is a -// substring of haystack (NULL is considered a substring of itself -// only), and return an appropriate error message when they fail. - -AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, - const char* needle, const char* haystack) { - return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); -} - -AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack) { - return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); -} - -AssertionResult IsNotSubstring(const char* needle_expr, - const char* haystack_expr, const char* needle, - const char* haystack) { - return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); -} - -AssertionResult IsNotSubstring(const char* needle_expr, - const char* haystack_expr, const wchar_t* needle, - const wchar_t* haystack) { - return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); -} - -AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, - const ::std::string& needle, - const ::std::string& haystack) { - return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); -} - -AssertionResult IsNotSubstring(const char* needle_expr, - const char* haystack_expr, - const ::std::string& needle, - const ::std::string& haystack) { - return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); -} - -#if GTEST_HAS_STD_WSTRING -AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, - const ::std::wstring& needle, - const ::std::wstring& haystack) { - return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); -} - -AssertionResult IsNotSubstring(const char* needle_expr, - const char* haystack_expr, - const ::std::wstring& needle, - const ::std::wstring& haystack) { - return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); -} -#endif // GTEST_HAS_STD_WSTRING - -namespace internal { - -#if GTEST_OS_WINDOWS - -namespace { - -// Helper function for IsHRESULT{SuccessFailure} predicates -AssertionResult HRESULTFailureHelper(const char* expr, const char* expected, - long hr) { // NOLINT -#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_TV_TITLE - - // Windows CE doesn't support FormatMessage. - const char error_text[] = ""; - -#else - - // Looks up the human-readable system message for the HRESULT code - // and since we're not passing any params to FormatMessage, we don't - // want inserts expanded. - const DWORD kFlags = - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS; - const DWORD kBufSize = 4096; - // Gets the system's human readable message string for this HRESULT. - char error_text[kBufSize] = {'\0'}; - DWORD message_length = ::FormatMessageA(kFlags, - 0, // no source, we're asking system - static_cast(hr), // the error - 0, // no line width restrictions - error_text, // output buffer - kBufSize, // buf size - nullptr); // no arguments for inserts - // Trims tailing white space (FormatMessage leaves a trailing CR-LF) - for (; message_length && IsSpace(error_text[message_length - 1]); - --message_length) { - error_text[message_length - 1] = '\0'; - } - -#endif // GTEST_OS_WINDOWS_MOBILE - - const std::string error_hex("0x" + String::FormatHexInt(hr)); - return ::testing::AssertionFailure() - << "Expected: " << expr << " " << expected << ".\n" - << " Actual: " << error_hex << " " << error_text << "\n"; -} - -} // namespace - -AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT - if (SUCCEEDED(hr)) { - return AssertionSuccess(); - } - return HRESULTFailureHelper(expr, "succeeds", hr); -} - -AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT - if (FAILED(hr)) { - return AssertionSuccess(); - } - return HRESULTFailureHelper(expr, "fails", hr); -} - -#endif // GTEST_OS_WINDOWS - -// Utility functions for encoding Unicode text (wide strings) in -// UTF-8. - -// A Unicode code-point can have up to 21 bits, and is encoded in UTF-8 -// like this: -// -// Code-point length Encoding -// 0 - 7 bits 0xxxxxxx -// 8 - 11 bits 110xxxxx 10xxxxxx -// 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx -// 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - -// The maximum code-point a one-byte UTF-8 sequence can represent. -constexpr uint32_t kMaxCodePoint1 = (static_cast(1) << 7) - 1; - -// The maximum code-point a two-byte UTF-8 sequence can represent. -constexpr uint32_t kMaxCodePoint2 = (static_cast(1) << (5 + 6)) - 1; - -// The maximum code-point a three-byte UTF-8 sequence can represent. -constexpr uint32_t kMaxCodePoint3 = - (static_cast(1) << (4 + 2 * 6)) - 1; - -// The maximum code-point a four-byte UTF-8 sequence can represent. -constexpr uint32_t kMaxCodePoint4 = - (static_cast(1) << (3 + 3 * 6)) - 1; - -// Chops off the n lowest bits from a bit pattern. Returns the n -// lowest bits. As a side effect, the original bit pattern will be -// shifted to the right by n bits. -inline uint32_t ChopLowBits(uint32_t* bits, int n) { - const uint32_t low_bits = *bits & ((static_cast(1) << n) - 1); - *bits >>= n; - return low_bits; -} - -// Converts a Unicode code point to a narrow string in UTF-8 encoding. -// code_point parameter is of type uint32_t because wchar_t may not be -// wide enough to contain a code point. -// If the code_point is not a valid Unicode code point -// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted -// to "(Invalid Unicode 0xXXXXXXXX)". -std::string CodePointToUtf8(uint32_t code_point) { - if (code_point > kMaxCodePoint4) { - return "(Invalid Unicode 0x" + String::FormatHexUInt32(code_point) + ")"; - } - - char str[5]; // Big enough for the largest valid code point. - if (code_point <= kMaxCodePoint1) { - str[1] = '\0'; - str[0] = static_cast(code_point); // 0xxxxxxx - } else if (code_point <= kMaxCodePoint2) { - str[2] = '\0'; - str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[0] = static_cast(0xC0 | code_point); // 110xxxxx - } else if (code_point <= kMaxCodePoint3) { - str[3] = '\0'; - str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[0] = static_cast(0xE0 | code_point); // 1110xxxx - } else { // code_point <= kMaxCodePoint4 - str[4] = '\0'; - str[3] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[0] = static_cast(0xF0 | code_point); // 11110xxx - } - return str; -} - -// The following two functions only make sense if the system -// uses UTF-16 for wide string encoding. All supported systems -// with 16 bit wchar_t (Windows, Cygwin) do use UTF-16. - -// Determines if the arguments constitute UTF-16 surrogate pair -// and thus should be combined into a single Unicode code point -// using CreateCodePointFromUtf16SurrogatePair. -inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { - return sizeof(wchar_t) == 2 && (first & 0xFC00) == 0xD800 && - (second & 0xFC00) == 0xDC00; -} - -// Creates a Unicode code point from UTF16 surrogate pair. -inline uint32_t CreateCodePointFromUtf16SurrogatePair(wchar_t first, - wchar_t second) { - const auto first_u = static_cast(first); - const auto second_u = static_cast(second); - const uint32_t mask = (1 << 10) - 1; - return (sizeof(wchar_t) == 2) - ? (((first_u & mask) << 10) | (second_u & mask)) + 0x10000 - : - // This function should not be called when the condition is - // false, but we provide a sensible default in case it is. - first_u; -} - -// Converts a wide string to a narrow string in UTF-8 encoding. -// The wide string is assumed to have the following encoding: -// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin) -// UTF-32 if sizeof(wchar_t) == 4 (on Linux) -// Parameter str points to a null-terminated wide string. -// Parameter num_chars may additionally limit the number -// of wchar_t characters processed. -1 is used when the entire string -// should be processed. -// If the string contains code points that are not valid Unicode code points -// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output -// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding -// and contains invalid UTF-16 surrogate pairs, values in those pairs -// will be encoded as individual Unicode characters from Basic Normal Plane. -std::string WideStringToUtf8(const wchar_t* str, int num_chars) { - if (num_chars == -1) num_chars = static_cast(wcslen(str)); - - ::std::stringstream stream; - for (int i = 0; i < num_chars; ++i) { - uint32_t unicode_code_point; - - if (str[i] == L'\0') { - break; - } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { - unicode_code_point = - CreateCodePointFromUtf16SurrogatePair(str[i], str[i + 1]); - i++; - } else { - unicode_code_point = static_cast(str[i]); - } - - stream << CodePointToUtf8(unicode_code_point); - } - return StringStreamToString(&stream); -} - -// Converts a wide C string to an std::string using the UTF-8 encoding. -// NULL will be converted to "(null)". -std::string String::ShowWideCString(const wchar_t* wide_c_str) { - if (wide_c_str == nullptr) return "(null)"; - - return internal::WideStringToUtf8(wide_c_str, -1); -} - -// Compares two wide C strings. Returns true if and only if they have the -// same content. -// -// Unlike wcscmp(), this function can handle NULL argument(s). A NULL -// C string is considered different to any non-NULL C string, -// including the empty string. -bool String::WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs) { - if (lhs == nullptr) return rhs == nullptr; - - if (rhs == nullptr) return false; - - return wcscmp(lhs, rhs) == 0; -} - -// Helper function for *_STREQ on wide strings. -AssertionResult CmpHelperSTREQ(const char* lhs_expression, - const char* rhs_expression, const wchar_t* lhs, - const wchar_t* rhs) { - if (String::WideCStringEquals(lhs, rhs)) { - return AssertionSuccess(); - } - - return EqFailure(lhs_expression, rhs_expression, PrintToString(lhs), - PrintToString(rhs), false); -} - -// Helper function for *_STRNE on wide strings. -AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, const wchar_t* s1, - const wchar_t* s2) { - if (!String::WideCStringEquals(s1, s2)) { - return AssertionSuccess(); - } - - return AssertionFailure() - << "Expected: (" << s1_expression << ") != (" << s2_expression - << "), actual: " << PrintToString(s1) << " vs " << PrintToString(s2); -} - -// Compares two C strings, ignoring case. Returns true if and only if they have -// the same content. -// -// Unlike strcasecmp(), this function can handle NULL argument(s). A -// NULL C string is considered different to any non-NULL C string, -// including the empty string. -bool String::CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) { - if (lhs == nullptr) return rhs == nullptr; - if (rhs == nullptr) return false; - return posix::StrCaseCmp(lhs, rhs) == 0; -} - -// Compares two wide C strings, ignoring case. Returns true if and only if they -// have the same content. -// -// Unlike wcscasecmp(), this function can handle NULL argument(s). -// A NULL C string is considered different to any non-NULL wide C string, -// including the empty string. -// NB: The implementations on different platforms slightly differ. -// On windows, this method uses _wcsicmp which compares according to LC_CTYPE -// environment variable. On GNU platform this method uses wcscasecmp -// which compares according to LC_CTYPE category of the current locale. -// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the -// current locale. -bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, - const wchar_t* rhs) { - if (lhs == nullptr) return rhs == nullptr; - - if (rhs == nullptr) return false; - -#if GTEST_OS_WINDOWS - return _wcsicmp(lhs, rhs) == 0; -#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID - return wcscasecmp(lhs, rhs) == 0; -#else - // Android, Mac OS X and Cygwin don't define wcscasecmp. - // Other unknown OSes may not define it either. - wint_t left, right; - do { - left = towlower(static_cast(*lhs++)); - right = towlower(static_cast(*rhs++)); - } while (left && left == right); - return left == right; -#endif // OS selector -} - -// Returns true if and only if str ends with the given suffix, ignoring case. -// Any string is considered to end with an empty suffix. -bool String::EndsWithCaseInsensitive(const std::string& str, - const std::string& suffix) { - const size_t str_len = str.length(); - const size_t suffix_len = suffix.length(); - return (str_len >= suffix_len) && - CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len, - suffix.c_str()); -} - -// Formats an int value as "%02d". -std::string String::FormatIntWidth2(int value) { - return FormatIntWidthN(value, 2); -} - -// Formats an int value to given width with leading zeros. -std::string String::FormatIntWidthN(int value, int width) { - std::stringstream ss; - ss << std::setfill('0') << std::setw(width) << value; - return ss.str(); -} - -// Formats an int value as "%X". -std::string String::FormatHexUInt32(uint32_t value) { - std::stringstream ss; - ss << std::hex << std::uppercase << value; - return ss.str(); -} - -// Formats an int value as "%X". -std::string String::FormatHexInt(int value) { - return FormatHexUInt32(static_cast(value)); -} - -// Formats a byte as "%02X". -std::string String::FormatByte(unsigned char value) { - std::stringstream ss; - ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase - << static_cast(value); - return ss.str(); -} - -// Converts the buffer in a stringstream to an std::string, converting NUL -// bytes to "\\0" along the way. -std::string StringStreamToString(::std::stringstream* ss) { - const ::std::string& str = ss->str(); - const char* const start = str.c_str(); - const char* const end = start + str.length(); - - std::string result; - result.reserve(static_cast(2 * (end - start))); - for (const char* ch = start; ch != end; ++ch) { - if (*ch == '\0') { - result += "\\0"; // Replaces NUL with "\\0"; - } else { - result += *ch; - } - } - - return result; -} - -// Appends the user-supplied message to the Google-Test-generated message. -std::string AppendUserMessage(const std::string& gtest_msg, - const Message& user_msg) { - // Appends the user message if it's non-empty. - const std::string user_msg_string = user_msg.GetString(); - if (user_msg_string.empty()) { - return gtest_msg; - } - if (gtest_msg.empty()) { - return user_msg_string; - } - return gtest_msg + "\n" + user_msg_string; -} - -} // namespace internal - -// class TestResult - -// Creates an empty TestResult. -TestResult::TestResult() - : death_test_count_(0), start_timestamp_(0), elapsed_time_(0) {} - -// D'tor. -TestResult::~TestResult() {} - -// Returns the i-th test part result among all the results. i can -// range from 0 to total_part_count() - 1. If i is not in that range, -// aborts the program. -const TestPartResult& TestResult::GetTestPartResult(int i) const { - if (i < 0 || i >= total_part_count()) internal::posix::Abort(); - return test_part_results_.at(static_cast(i)); -} - -// Returns the i-th test property. i can range from 0 to -// test_property_count() - 1. If i is not in that range, aborts the -// program. -const TestProperty& TestResult::GetTestProperty(int i) const { - if (i < 0 || i >= test_property_count()) internal::posix::Abort(); - return test_properties_.at(static_cast(i)); -} - -// Clears the test part results. -void TestResult::ClearTestPartResults() { test_part_results_.clear(); } - -// Adds a test part result to the list. -void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { - test_part_results_.push_back(test_part_result); -} - -// Adds a test property to the list. If a property with the same key as the -// supplied property is already represented, the value of this test_property -// replaces the old value for that key. -void TestResult::RecordProperty(const std::string& xml_element, - const TestProperty& test_property) { - if (!ValidateTestProperty(xml_element, test_property)) { - return; - } - internal::MutexLock lock(&test_properties_mutex_); - const std::vector::iterator property_with_matching_key = - std::find_if(test_properties_.begin(), test_properties_.end(), - internal::TestPropertyKeyIs(test_property.key())); - if (property_with_matching_key == test_properties_.end()) { - test_properties_.push_back(test_property); - return; - } - property_with_matching_key->SetValue(test_property.value()); -} - -// The list of reserved attributes used in the element of XML -// output. -static const char* const kReservedTestSuitesAttributes[] = { - "disabled", "errors", "failures", "name", - "random_seed", "tests", "time", "timestamp"}; - -// The list of reserved attributes used in the element of XML -// output. -static const char* const kReservedTestSuiteAttributes[] = { - "disabled", "errors", "failures", "name", - "tests", "time", "timestamp", "skipped"}; - -// The list of reserved attributes used in the element of XML output. -static const char* const kReservedTestCaseAttributes[] = { - "classname", "name", "status", "time", - "type_param", "value_param", "file", "line"}; - -// Use a slightly different set for allowed output to ensure existing tests can -// still RecordProperty("result") or "RecordProperty(timestamp") -static const char* const kReservedOutputTestCaseAttributes[] = { - "classname", "name", "status", "time", "type_param", - "value_param", "file", "line", "result", "timestamp"}; - -template -std::vector ArrayAsVector(const char* const (&array)[kSize]) { - return std::vector(array, array + kSize); -} - -static std::vector GetReservedAttributesForElement( - const std::string& xml_element) { - if (xml_element == "testsuites") { - return ArrayAsVector(kReservedTestSuitesAttributes); - } else if (xml_element == "testsuite") { - return ArrayAsVector(kReservedTestSuiteAttributes); - } else if (xml_element == "testcase") { - return ArrayAsVector(kReservedTestCaseAttributes); - } else { - GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element; - } - // This code is unreachable but some compilers may not realizes that. - return std::vector(); -} - -// TODO(jdesprez): Merge the two getReserved attributes once skip is improved -static std::vector GetReservedOutputAttributesForElement( - const std::string& xml_element) { - if (xml_element == "testsuites") { - return ArrayAsVector(kReservedTestSuitesAttributes); - } else if (xml_element == "testsuite") { - return ArrayAsVector(kReservedTestSuiteAttributes); - } else if (xml_element == "testcase") { - return ArrayAsVector(kReservedOutputTestCaseAttributes); - } else { - GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element; - } - // This code is unreachable but some compilers may not realizes that. - return std::vector(); -} - -static std::string FormatWordList(const std::vector& words) { - Message word_list; - for (size_t i = 0; i < words.size(); ++i) { - if (i > 0 && words.size() > 2) { - word_list << ", "; - } - if (i == words.size() - 1) { - word_list << "and "; - } - word_list << "'" << words[i] << "'"; - } - return word_list.GetString(); -} - -static bool ValidateTestPropertyName( - const std::string& property_name, - const std::vector& reserved_names) { - if (std::find(reserved_names.begin(), reserved_names.end(), property_name) != - reserved_names.end()) { - ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name - << " (" << FormatWordList(reserved_names) - << " are reserved by " << GTEST_NAME_ << ")"; - return false; - } - return true; -} - -// Adds a failure if the key is a reserved attribute of the element named -// xml_element. Returns true if the property is valid. -bool TestResult::ValidateTestProperty(const std::string& xml_element, - const TestProperty& test_property) { - return ValidateTestPropertyName(test_property.key(), - GetReservedAttributesForElement(xml_element)); -} - -// Clears the object. -void TestResult::Clear() { - test_part_results_.clear(); - test_properties_.clear(); - death_test_count_ = 0; - elapsed_time_ = 0; -} - -// Returns true off the test part was skipped. -static bool TestPartSkipped(const TestPartResult& result) { - return result.skipped(); -} - -// Returns true if and only if the test was skipped. -bool TestResult::Skipped() const { - return !Failed() && CountIf(test_part_results_, TestPartSkipped) > 0; -} - -// Returns true if and only if the test failed. -bool TestResult::Failed() const { - for (int i = 0; i < total_part_count(); ++i) { - if (GetTestPartResult(i).failed()) return true; - } - return false; -} - -// Returns true if and only if the test part fatally failed. -static bool TestPartFatallyFailed(const TestPartResult& result) { - return result.fatally_failed(); -} - -// Returns true if and only if the test fatally failed. -bool TestResult::HasFatalFailure() const { - return CountIf(test_part_results_, TestPartFatallyFailed) > 0; -} - -// Returns true if and only if the test part non-fatally failed. -static bool TestPartNonfatallyFailed(const TestPartResult& result) { - return result.nonfatally_failed(); -} - -// Returns true if and only if the test has a non-fatal failure. -bool TestResult::HasNonfatalFailure() const { - return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; -} - -// Gets the number of all test parts. This is the sum of the number -// of successful test parts and the number of failed test parts. -int TestResult::total_part_count() const { - return static_cast(test_part_results_.size()); -} - -// Returns the number of the test properties. -int TestResult::test_property_count() const { - return static_cast(test_properties_.size()); -} - -// class Test - -// Creates a Test object. - -// The c'tor saves the states of all flags. -Test::Test() : gtest_flag_saver_(new GTEST_FLAG_SAVER_) {} - -// The d'tor restores the states of all flags. The actual work is -// done by the d'tor of the gtest_flag_saver_ field, and thus not -// visible here. -Test::~Test() {} - -// Sets up the test fixture. -// -// A sub-class may override this. -void Test::SetUp() {} - -// Tears down the test fixture. -// -// A sub-class may override this. -void Test::TearDown() {} - -// Allows user supplied key value pairs to be recorded for later output. -void Test::RecordProperty(const std::string& key, const std::string& value) { - UnitTest::GetInstance()->RecordProperty(key, value); -} - -// Allows user supplied key value pairs to be recorded for later output. -void Test::RecordProperty(const std::string& key, int value) { - Message value_message; - value_message << value; - RecordProperty(key, value_message.GetString().c_str()); -} - -namespace internal { - -void ReportFailureInUnknownLocation(TestPartResult::Type result_type, - const std::string& message) { - // This function is a friend of UnitTest and as such has access to - // AddTestPartResult. - UnitTest::GetInstance()->AddTestPartResult( - result_type, - nullptr, // No info about the source file where the exception occurred. - -1, // We have no info on which line caused the exception. - message, - ""); // No stack trace, either. -} - -} // namespace internal - -// Google Test requires all tests in the same test suite to use the same test -// fixture class. This function checks if the current test has the -// same fixture class as the first test in the current test suite. If -// yes, it returns true; otherwise it generates a Google Test failure and -// returns false. -bool Test::HasSameFixtureClass() { - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - const TestSuite* const test_suite = impl->current_test_suite(); - - // Info about the first test in the current test suite. - const TestInfo* const first_test_info = test_suite->test_info_list()[0]; - const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; - const char* const first_test_name = first_test_info->name(); - - // Info about the current test. - const TestInfo* const this_test_info = impl->current_test_info(); - const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; - const char* const this_test_name = this_test_info->name(); - - if (this_fixture_id != first_fixture_id) { - // Is the first test defined using TEST? - const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); - // Is this test defined using TEST? - const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); - - if (first_is_TEST || this_is_TEST) { - // Both TEST and TEST_F appear in same test suite, which is incorrect. - // Tell the user how to fix this. - - // Gets the name of the TEST and the name of the TEST_F. Note - // that first_is_TEST and this_is_TEST cannot both be true, as - // the fixture IDs are different for the two tests. - const char* const TEST_name = - first_is_TEST ? first_test_name : this_test_name; - const char* const TEST_F_name = - first_is_TEST ? this_test_name : first_test_name; - - ADD_FAILURE() - << "All tests in the same test suite must use the same test fixture\n" - << "class, so mixing TEST_F and TEST in the same test suite is\n" - << "illegal. In test suite " << this_test_info->test_suite_name() - << ",\n" - << "test " << TEST_F_name << " is defined using TEST_F but\n" - << "test " << TEST_name << " is defined using TEST. You probably\n" - << "want to change the TEST to TEST_F or move it to another test\n" - << "case."; - } else { - // Two fixture classes with the same name appear in two different - // namespaces, which is not allowed. Tell the user how to fix this. - ADD_FAILURE() - << "All tests in the same test suite must use the same test fixture\n" - << "class. However, in test suite " - << this_test_info->test_suite_name() << ",\n" - << "you defined test " << first_test_name << " and test " - << this_test_name << "\n" - << "using two different test fixture classes. This can happen if\n" - << "the two classes are from different namespaces or translation\n" - << "units and have the same name. You should probably rename one\n" - << "of the classes to put the tests into different test suites."; - } - return false; - } - - return true; -} - -#if GTEST_HAS_SEH - -// Adds an "exception thrown" fatal failure to the current test. This -// function returns its result via an output parameter pointer because VC++ -// prohibits creation of objects with destructors on stack in functions -// using __try (see error C2712). -static std::string* FormatSehExceptionMessage(DWORD exception_code, - const char* location) { - Message message; - message << "SEH exception with code 0x" << std::setbase(16) << exception_code - << std::setbase(10) << " thrown in " << location << "."; - - return new std::string(message.GetString()); -} - -#endif // GTEST_HAS_SEH - -namespace internal { - -#if GTEST_HAS_EXCEPTIONS - -// Adds an "exception thrown" fatal failure to the current test. -static std::string FormatCxxExceptionMessage(const char* description, - const char* location) { - Message message; - if (description != nullptr) { - message << "C++ exception with description \"" << description << "\""; - } else { - message << "Unknown C++ exception"; - } - message << " thrown in " << location << "."; - - return message.GetString(); -} - -static std::string PrintTestPartResultToString( - const TestPartResult& test_part_result); - -GoogleTestFailureException::GoogleTestFailureException( - const TestPartResult& failure) - : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} - -#endif // GTEST_HAS_EXCEPTIONS - -// We put these helper functions in the internal namespace as IBM's xlC -// compiler rejects the code if they were declared static. - -// Runs the given method and handles SEH exceptions it throws, when -// SEH is supported; returns the 0-value for type Result in case of an -// SEH exception. (Microsoft compilers cannot handle SEH and C++ -// exceptions in the same function. Therefore, we provide a separate -// wrapper function for handling SEH exceptions.) -template -Result HandleSehExceptionsInMethodIfSupported(T* object, Result (T::*method)(), - const char* location) { -#if GTEST_HAS_SEH - __try { - return (object->*method)(); - } __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT - GetExceptionCode())) { - // We create the exception message on the heap because VC++ prohibits - // creation of objects with destructors on stack in functions using __try - // (see error C2712). - std::string* exception_message = - FormatSehExceptionMessage(GetExceptionCode(), location); - internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, - *exception_message); - delete exception_message; - return static_cast(0); - } -#else - (void)location; - return (object->*method)(); -#endif // GTEST_HAS_SEH -} - -// Runs the given method and catches and reports C++ and/or SEH-style -// exceptions, if they are supported; returns the 0-value for type -// Result in case of an SEH exception. -template -Result HandleExceptionsInMethodIfSupported(T* object, Result (T::*method)(), - const char* location) { - // NOTE: The user code can affect the way in which Google Test handles - // exceptions by setting GTEST_FLAG(catch_exceptions), but only before - // RUN_ALL_TESTS() starts. It is technically possible to check the flag - // after the exception is caught and either report or re-throw the - // exception based on the flag's value: - // - // try { - // // Perform the test method. - // } catch (...) { - // if (GTEST_FLAG_GET(catch_exceptions)) - // // Report the exception as failure. - // else - // throw; // Re-throws the original exception. - // } - // - // However, the purpose of this flag is to allow the program to drop into - // the debugger when the exception is thrown. On most platforms, once the - // control enters the catch block, the exception origin information is - // lost and the debugger will stop the program at the point of the - // re-throw in this function -- instead of at the point of the original - // throw statement in the code under test. For this reason, we perform - // the check early, sacrificing the ability to affect Google Test's - // exception handling in the method where the exception is thrown. - if (internal::GetUnitTestImpl()->catch_exceptions()) { -#if GTEST_HAS_EXCEPTIONS - try { - return HandleSehExceptionsInMethodIfSupported(object, method, location); - } catch (const AssertionException&) { // NOLINT - // This failure was reported already. - } catch (const internal::GoogleTestFailureException&) { // NOLINT - // This exception type can only be thrown by a failed Google - // Test assertion with the intention of letting another testing - // framework catch it. Therefore we just re-throw it. - throw; - } catch (const std::exception& e) { // NOLINT - internal::ReportFailureInUnknownLocation( - TestPartResult::kFatalFailure, - FormatCxxExceptionMessage(e.what(), location)); - } catch (...) { // NOLINT - internal::ReportFailureInUnknownLocation( - TestPartResult::kFatalFailure, - FormatCxxExceptionMessage(nullptr, location)); - } - return static_cast(0); -#else - return HandleSehExceptionsInMethodIfSupported(object, method, location); -#endif // GTEST_HAS_EXCEPTIONS - } else { - return (object->*method)(); - } -} - -} // namespace internal - -// Runs the test and updates the test result. -void Test::Run() { - if (!HasSameFixtureClass()) return; - - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); - // We will run the test only if SetUp() was successful and didn't call - // GTEST_SKIP(). - if (!HasFatalFailure() && !IsSkipped()) { - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported(this, &Test::TestBody, - "the test body"); - } - - // However, we want to clean up as much as possible. Hence we will - // always call TearDown(), even if SetUp() or the test body has - // failed. - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported(this, &Test::TearDown, - "TearDown()"); -} - -// Returns true if and only if the current test has a fatal failure. -bool Test::HasFatalFailure() { - return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); -} - -// Returns true if and only if the current test has a non-fatal failure. -bool Test::HasNonfatalFailure() { - return internal::GetUnitTestImpl() - ->current_test_result() - ->HasNonfatalFailure(); -} - -// Returns true if and only if the current test was skipped. -bool Test::IsSkipped() { - return internal::GetUnitTestImpl()->current_test_result()->Skipped(); -} - -// class TestInfo - -// Constructs a TestInfo object. It assumes ownership of the test factory -// object. -TestInfo::TestInfo(const std::string& a_test_suite_name, - const std::string& a_name, const char* a_type_param, - const char* a_value_param, - internal::CodeLocation a_code_location, - internal::TypeId fixture_class_id, - internal::TestFactoryBase* factory) - : test_suite_name_(a_test_suite_name), - name_(a_name), - type_param_(a_type_param ? new std::string(a_type_param) : nullptr), - value_param_(a_value_param ? new std::string(a_value_param) : nullptr), - location_(a_code_location), - fixture_class_id_(fixture_class_id), - should_run_(false), - is_disabled_(false), - matches_filter_(false), - is_in_another_shard_(false), - factory_(factory), - result_() {} - -// Destructs a TestInfo object. -TestInfo::~TestInfo() { delete factory_; } - -namespace internal { - -// Creates a new TestInfo object and registers it with Google Test; -// returns the created object. -// -// Arguments: -// -// test_suite_name: name of the test suite -// name: name of the test -// type_param: the name of the test's type parameter, or NULL if -// this is not a typed or a type-parameterized test. -// value_param: text representation of the test's value parameter, -// or NULL if this is not a value-parameterized test. -// code_location: code location where the test is defined -// fixture_class_id: ID of the test fixture class -// set_up_tc: pointer to the function that sets up the test suite -// tear_down_tc: pointer to the function that tears down the test suite -// factory: pointer to the factory that creates a test object. -// The newly created TestInfo instance will assume -// ownership of the factory object. -TestInfo* MakeAndRegisterTestInfo( - const char* test_suite_name, const char* name, const char* type_param, - const char* value_param, CodeLocation code_location, - TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc, - TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory) { - TestInfo* const test_info = - new TestInfo(test_suite_name, name, type_param, value_param, - code_location, fixture_class_id, factory); - GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); - return test_info; -} - -void ReportInvalidTestSuiteType(const char* test_suite_name, - CodeLocation code_location) { - Message errors; - errors - << "Attempted redefinition of test suite " << test_suite_name << ".\n" - << "All tests in the same test suite must use the same test fixture\n" - << "class. However, in test suite " << test_suite_name << ", you tried\n" - << "to define a test using a fixture class different from the one\n" - << "used earlier. This can happen if the two fixture classes are\n" - << "from different namespaces and have the same name. You should\n" - << "probably rename one of the classes to put the tests into different\n" - << "test suites."; - - GTEST_LOG_(ERROR) << FormatFileLocation(code_location.file.c_str(), - code_location.line) - << " " << errors.GetString(); -} -} // namespace internal - -namespace { - -// A predicate that checks the test name of a TestInfo against a known -// value. -// -// This is used for implementation of the TestSuite class only. We put -// it in the anonymous namespace to prevent polluting the outer -// namespace. -// -// TestNameIs is copyable. -class TestNameIs { - public: - // Constructor. - // - // TestNameIs has NO default constructor. - explicit TestNameIs(const char* name) : name_(name) {} - - // Returns true if and only if the test name of test_info matches name_. - bool operator()(const TestInfo* test_info) const { - return test_info && test_info->name() == name_; - } - - private: - std::string name_; -}; - -} // namespace - -namespace internal { - -// This method expands all parameterized tests registered with macros TEST_P -// and INSTANTIATE_TEST_SUITE_P into regular tests and registers those. -// This will be done just once during the program runtime. -void UnitTestImpl::RegisterParameterizedTests() { - if (!parameterized_tests_registered_) { - parameterized_test_registry_.RegisterTests(); - type_parameterized_test_registry_.CheckForInstantiations(); - parameterized_tests_registered_ = true; - } -} - -} // namespace internal - -// Creates the test object, runs it, records its result, and then -// deletes it. -void TestInfo::Run() { - TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); - if (!should_run_) { - if (is_disabled_ && matches_filter_) repeater->OnTestDisabled(*this); - return; - } - - // Tells UnitTest where to store test result. - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->set_current_test_info(this); - - // Notifies the unit test event listeners that a test is about to start. - repeater->OnTestStart(*this); - result_.set_start_timestamp(internal::GetTimeInMillis()); - internal::Timer timer; - impl->os_stack_trace_getter()->UponLeavingGTest(); - - // Creates the test object. - Test* const test = internal::HandleExceptionsInMethodIfSupported( - factory_, &internal::TestFactoryBase::CreateTest, - "the test fixture's constructor"); - - // Runs the test if the constructor didn't generate a fatal failure or invoke - // GTEST_SKIP(). - // Note that the object will not be null - if (!Test::HasFatalFailure() && !Test::IsSkipped()) { - // This doesn't throw as all user code that can throw are wrapped into - // exception handling code. - test->Run(); - } - - if (test != nullptr) { - // Deletes the test object. - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported( - test, &Test::DeleteSelf_, "the test fixture's destructor"); - } - - result_.set_elapsed_time(timer.Elapsed()); - - // Notifies the unit test event listener that a test has just finished. - repeater->OnTestEnd(*this); - - // Tells UnitTest to stop associating assertion results to this - // test. - impl->set_current_test_info(nullptr); -} - -// Skip and records a skipped test result for this object. -void TestInfo::Skip() { - if (!should_run_) return; - - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->set_current_test_info(this); - - TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); - - // Notifies the unit test event listeners that a test is about to start. - repeater->OnTestStart(*this); - - const TestPartResult test_part_result = - TestPartResult(TestPartResult::kSkip, this->file(), this->line(), ""); - impl->GetTestPartResultReporterForCurrentThread()->ReportTestPartResult( - test_part_result); - - // Notifies the unit test event listener that a test has just finished. - repeater->OnTestEnd(*this); - impl->set_current_test_info(nullptr); -} - -// class TestSuite - -// Gets the number of successful tests in this test suite. -int TestSuite::successful_test_count() const { - return CountIf(test_info_list_, TestPassed); -} - -// Gets the number of successful tests in this test suite. -int TestSuite::skipped_test_count() const { - return CountIf(test_info_list_, TestSkipped); -} - -// Gets the number of failed tests in this test suite. -int TestSuite::failed_test_count() const { - return CountIf(test_info_list_, TestFailed); -} - -// Gets the number of disabled tests that will be reported in the XML report. -int TestSuite::reportable_disabled_test_count() const { - return CountIf(test_info_list_, TestReportableDisabled); -} - -// Gets the number of disabled tests in this test suite. -int TestSuite::disabled_test_count() const { - return CountIf(test_info_list_, TestDisabled); -} - -// Gets the number of tests to be printed in the XML report. -int TestSuite::reportable_test_count() const { - return CountIf(test_info_list_, TestReportable); -} - -// Get the number of tests in this test suite that should run. -int TestSuite::test_to_run_count() const { - return CountIf(test_info_list_, ShouldRunTest); -} - -// Gets the number of all tests. -int TestSuite::total_test_count() const { - return static_cast(test_info_list_.size()); -} - -// Creates a TestSuite with the given name. -// -// Arguments: -// -// a_name: name of the test suite -// a_type_param: the name of the test suite's type parameter, or NULL if -// this is not a typed or a type-parameterized test suite. -// set_up_tc: pointer to the function that sets up the test suite -// tear_down_tc: pointer to the function that tears down the test suite -TestSuite::TestSuite(const char* a_name, const char* a_type_param, - internal::SetUpTestSuiteFunc set_up_tc, - internal::TearDownTestSuiteFunc tear_down_tc) - : name_(a_name), - type_param_(a_type_param ? new std::string(a_type_param) : nullptr), - set_up_tc_(set_up_tc), - tear_down_tc_(tear_down_tc), - should_run_(false), - start_timestamp_(0), - elapsed_time_(0) {} - -// Destructor of TestSuite. -TestSuite::~TestSuite() { - // Deletes every Test in the collection. - ForEach(test_info_list_, internal::Delete); -} - -// Returns the i-th test among all the tests. i can range from 0 to -// total_test_count() - 1. If i is not in that range, returns NULL. -const TestInfo* TestSuite::GetTestInfo(int i) const { - const int index = GetElementOr(test_indices_, i, -1); - return index < 0 ? nullptr : test_info_list_[static_cast(index)]; -} - -// Returns the i-th test among all the tests. i can range from 0 to -// total_test_count() - 1. If i is not in that range, returns NULL. -TestInfo* TestSuite::GetMutableTestInfo(int i) { - const int index = GetElementOr(test_indices_, i, -1); - return index < 0 ? nullptr : test_info_list_[static_cast(index)]; -} - -// Adds a test to this test suite. Will delete the test upon -// destruction of the TestSuite object. -void TestSuite::AddTestInfo(TestInfo* test_info) { - test_info_list_.push_back(test_info); - test_indices_.push_back(static_cast(test_indices_.size())); -} - -// Runs every test in this TestSuite. -void TestSuite::Run() { - if (!should_run_) return; - - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->set_current_test_suite(this); - - TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); - - // Call both legacy and the new API - repeater->OnTestSuiteStart(*this); -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - repeater->OnTestCaseStart(*this); -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported( - this, &TestSuite::RunSetUpTestSuite, "SetUpTestSuite()"); - - const bool skip_all = ad_hoc_test_result().Failed(); - - start_timestamp_ = internal::GetTimeInMillis(); - internal::Timer timer; - for (int i = 0; i < total_test_count(); i++) { - if (skip_all) { - GetMutableTestInfo(i)->Skip(); - } else { - GetMutableTestInfo(i)->Run(); - } - if (GTEST_FLAG_GET(fail_fast) && - GetMutableTestInfo(i)->result()->Failed()) { - for (int j = i + 1; j < total_test_count(); j++) { - GetMutableTestInfo(j)->Skip(); - } - break; - } - } - elapsed_time_ = timer.Elapsed(); - - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported( - this, &TestSuite::RunTearDownTestSuite, "TearDownTestSuite()"); - - // Call both legacy and the new API - repeater->OnTestSuiteEnd(*this); -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - repeater->OnTestCaseEnd(*this); -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - - impl->set_current_test_suite(nullptr); -} - -// Skips all tests under this TestSuite. -void TestSuite::Skip() { - if (!should_run_) return; - - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->set_current_test_suite(this); - - TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); - - // Call both legacy and the new API - repeater->OnTestSuiteStart(*this); -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - repeater->OnTestCaseStart(*this); -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - - for (int i = 0; i < total_test_count(); i++) { - GetMutableTestInfo(i)->Skip(); - } - - // Call both legacy and the new API - repeater->OnTestSuiteEnd(*this); - // Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - repeater->OnTestCaseEnd(*this); -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - - impl->set_current_test_suite(nullptr); -} - -// Clears the results of all tests in this test suite. -void TestSuite::ClearResult() { - ad_hoc_test_result_.Clear(); - ForEach(test_info_list_, TestInfo::ClearTestResult); -} - -// Shuffles the tests in this test suite. -void TestSuite::ShuffleTests(internal::Random* random) { - Shuffle(random, &test_indices_); -} - -// Restores the test order to before the first shuffle. -void TestSuite::UnshuffleTests() { - for (size_t i = 0; i < test_indices_.size(); i++) { - test_indices_[i] = static_cast(i); - } -} - -// Formats a countable noun. Depending on its quantity, either the -// singular form or the plural form is used. e.g. -// -// FormatCountableNoun(1, "formula", "formuli") returns "1 formula". -// FormatCountableNoun(5, "book", "books") returns "5 books". -static std::string FormatCountableNoun(int count, const char* singular_form, - const char* plural_form) { - return internal::StreamableToString(count) + " " + - (count == 1 ? singular_form : plural_form); -} - -// Formats the count of tests. -static std::string FormatTestCount(int test_count) { - return FormatCountableNoun(test_count, "test", "tests"); -} - -// Formats the count of test suites. -static std::string FormatTestSuiteCount(int test_suite_count) { - return FormatCountableNoun(test_suite_count, "test suite", "test suites"); -} - -// Converts a TestPartResult::Type enum to human-friendly string -// representation. Both kNonFatalFailure and kFatalFailure are translated -// to "Failure", as the user usually doesn't care about the difference -// between the two when viewing the test result. -static const char* TestPartResultTypeToString(TestPartResult::Type type) { - switch (type) { - case TestPartResult::kSkip: - return "Skipped\n"; - case TestPartResult::kSuccess: - return "Success"; - - case TestPartResult::kNonFatalFailure: - case TestPartResult::kFatalFailure: -#ifdef _MSC_VER - return "error: "; -#else - return "Failure\n"; -#endif - default: - return "Unknown result type"; - } -} - -namespace internal { -namespace { -enum class GTestColor { kDefault, kRed, kGreen, kYellow }; -} // namespace - -// Prints a TestPartResult to an std::string. -static std::string PrintTestPartResultToString( - const TestPartResult& test_part_result) { - return (Message() << internal::FormatFileLocation( - test_part_result.file_name(), - test_part_result.line_number()) - << " " - << TestPartResultTypeToString(test_part_result.type()) - << test_part_result.message()) - .GetString(); -} - -// Prints a TestPartResult. -static void PrintTestPartResult(const TestPartResult& test_part_result) { - const std::string& result = PrintTestPartResultToString(test_part_result); - printf("%s\n", result.c_str()); - fflush(stdout); - // If the test program runs in Visual Studio or a debugger, the - // following statements add the test part result message to the Output - // window such that the user can double-click on it to jump to the - // corresponding source code location; otherwise they do nothing. -#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE - // We don't call OutputDebugString*() on Windows Mobile, as printing - // to stdout is done by OutputDebugString() there already - we don't - // want the same message printed twice. - ::OutputDebugStringA(result.c_str()); - ::OutputDebugStringA("\n"); -#endif -} - -// class PrettyUnitTestResultPrinter -#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && \ - !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW - -// Returns the character attribute for the given color. -static WORD GetColorAttribute(GTestColor color) { - switch (color) { - case GTestColor::kRed: - return FOREGROUND_RED; - case GTestColor::kGreen: - return FOREGROUND_GREEN; - case GTestColor::kYellow: - return FOREGROUND_RED | FOREGROUND_GREEN; - default: - return 0; - } -} - -static int GetBitOffset(WORD color_mask) { - if (color_mask == 0) return 0; - - int bitOffset = 0; - while ((color_mask & 1) == 0) { - color_mask >>= 1; - ++bitOffset; - } - return bitOffset; -} - -static WORD GetNewColor(GTestColor color, WORD old_color_attrs) { - // Let's reuse the BG - static const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN | - BACKGROUND_RED | BACKGROUND_INTENSITY; - static const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN | - FOREGROUND_RED | FOREGROUND_INTENSITY; - const WORD existing_bg = old_color_attrs & background_mask; - - WORD new_color = - GetColorAttribute(color) | existing_bg | FOREGROUND_INTENSITY; - static const int bg_bitOffset = GetBitOffset(background_mask); - static const int fg_bitOffset = GetBitOffset(foreground_mask); - - if (((new_color & background_mask) >> bg_bitOffset) == - ((new_color & foreground_mask) >> fg_bitOffset)) { - new_color ^= FOREGROUND_INTENSITY; // invert intensity - } - return new_color; -} - -#else - -// Returns the ANSI color code for the given color. GTestColor::kDefault is -// an invalid input. -static const char* GetAnsiColorCode(GTestColor color) { - switch (color) { - case GTestColor::kRed: - return "1"; - case GTestColor::kGreen: - return "2"; - case GTestColor::kYellow: - return "3"; - default: - return nullptr; - } -} - -#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE - -// Returns true if and only if Google Test should use colors in the output. -bool ShouldUseColor(bool stdout_is_tty) { - std::string c = GTEST_FLAG_GET(color); - const char* const gtest_color = c.c_str(); - - if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { -#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW - // On Windows the TERM variable is usually not set, but the - // console there does support colors. - return stdout_is_tty; -#else - // On non-Windows platforms, we rely on the TERM variable. - const char* const term = posix::GetEnv("TERM"); - const bool term_supports_color = - String::CStringEquals(term, "xterm") || - String::CStringEquals(term, "xterm-color") || - String::CStringEquals(term, "xterm-256color") || - String::CStringEquals(term, "screen") || - String::CStringEquals(term, "screen-256color") || - String::CStringEquals(term, "tmux") || - String::CStringEquals(term, "tmux-256color") || - String::CStringEquals(term, "rxvt-unicode") || - String::CStringEquals(term, "rxvt-unicode-256color") || - String::CStringEquals(term, "linux") || - String::CStringEquals(term, "cygwin"); - return stdout_is_tty && term_supports_color; -#endif // GTEST_OS_WINDOWS - } - - return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || - String::CaseInsensitiveCStringEquals(gtest_color, "true") || - String::CaseInsensitiveCStringEquals(gtest_color, "t") || - String::CStringEquals(gtest_color, "1"); - // We take "yes", "true", "t", and "1" as meaning "yes". If the - // value is neither one of these nor "auto", we treat it as "no" to - // be conservative. -} - -// Helpers for printing colored strings to stdout. Note that on Windows, we -// cannot simply emit special characters and have the terminal change colors. -// This routine must actually emit the characters rather than return a string -// that would be colored when printed, as can be done on Linux. - -GTEST_ATTRIBUTE_PRINTF_(2, 3) -static void ColoredPrintf(GTestColor color, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - - static const bool in_color_mode = - ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); - const bool use_color = in_color_mode && (color != GTestColor::kDefault); - - if (!use_color) { - vprintf(fmt, args); - va_end(args); - return; - } - -#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && \ - !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW - const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); - - // Gets the current text color. - CONSOLE_SCREEN_BUFFER_INFO buffer_info; - GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); - const WORD old_color_attrs = buffer_info.wAttributes; - const WORD new_color = GetNewColor(color, old_color_attrs); - - // We need to flush the stream buffers into the console before each - // SetConsoleTextAttribute call lest it affect the text that is already - // printed but has not yet reached the console. - fflush(stdout); - SetConsoleTextAttribute(stdout_handle, new_color); - - vprintf(fmt, args); - - fflush(stdout); - // Restores the text color. - SetConsoleTextAttribute(stdout_handle, old_color_attrs); -#else - printf("\033[0;3%sm", GetAnsiColorCode(color)); - vprintf(fmt, args); - printf("\033[m"); // Resets the terminal to default. -#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE - va_end(args); -} - -// Text printed in Google Test's text output and --gtest_list_tests -// output to label the type parameter and value parameter for a test. -static const char kTypeParamLabel[] = "TypeParam"; -static const char kValueParamLabel[] = "GetParam()"; - -static void PrintFullTestCommentIfPresent(const TestInfo& test_info) { - const char* const type_param = test_info.type_param(); - const char* const value_param = test_info.value_param(); - - if (type_param != nullptr || value_param != nullptr) { - printf(", where "); - if (type_param != nullptr) { - printf("%s = %s", kTypeParamLabel, type_param); - if (value_param != nullptr) printf(" and "); - } - if (value_param != nullptr) { - printf("%s = %s", kValueParamLabel, value_param); - } - } -} - -// This class implements the TestEventListener interface. -// -// Class PrettyUnitTestResultPrinter is copyable. -class PrettyUnitTestResultPrinter : public TestEventListener { - public: - PrettyUnitTestResultPrinter() {} - static void PrintTestName(const char* test_suite, const char* test) { - printf("%s.%s", test_suite, test); - } - - // The following methods override what's in the TestEventListener class. - void OnTestProgramStart(const UnitTest& /*unit_test*/) override {} - void OnTestIterationStart(const UnitTest& unit_test, int iteration) override; - void OnEnvironmentsSetUpStart(const UnitTest& unit_test) override; - void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {} -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - void OnTestCaseStart(const TestCase& test_case) override; -#else - void OnTestSuiteStart(const TestSuite& test_suite) override; -#endif // OnTestCaseStart - - void OnTestStart(const TestInfo& test_info) override; - void OnTestDisabled(const TestInfo& test_info) override; - - void OnTestPartResult(const TestPartResult& result) override; - void OnTestEnd(const TestInfo& test_info) override; -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - void OnTestCaseEnd(const TestCase& test_case) override; -#else - void OnTestSuiteEnd(const TestSuite& test_suite) override; -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - - void OnEnvironmentsTearDownStart(const UnitTest& unit_test) override; - void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {} - void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override; - void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {} - - private: - static void PrintFailedTests(const UnitTest& unit_test); - static void PrintFailedTestSuites(const UnitTest& unit_test); - static void PrintSkippedTests(const UnitTest& unit_test); -}; - -// Fired before each iteration of tests starts. -void PrettyUnitTestResultPrinter::OnTestIterationStart( - const UnitTest& unit_test, int iteration) { - if (GTEST_FLAG_GET(repeat) != 1) - printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); - - std::string f = GTEST_FLAG_GET(filter); - const char* const filter = f.c_str(); - - // Prints the filter if it's not *. This reminds the user that some - // tests may be skipped. - if (!String::CStringEquals(filter, kUniversalFilter)) { - ColoredPrintf(GTestColor::kYellow, "Note: %s filter = %s\n", GTEST_NAME_, - filter); - } - - if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { - const int32_t shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); - ColoredPrintf(GTestColor::kYellow, "Note: This is test shard %d of %s.\n", - static_cast(shard_index) + 1, - internal::posix::GetEnv(kTestTotalShards)); - } - - if (GTEST_FLAG_GET(shuffle)) { - ColoredPrintf(GTestColor::kYellow, - "Note: Randomizing tests' orders with a seed of %d .\n", - unit_test.random_seed()); - } - - ColoredPrintf(GTestColor::kGreen, "[==========] "); - printf("Running %s from %s.\n", - FormatTestCount(unit_test.test_to_run_count()).c_str(), - FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str()); - fflush(stdout); -} - -void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( - const UnitTest& /*unit_test*/) { - ColoredPrintf(GTestColor::kGreen, "[----------] "); - printf("Global test environment set-up.\n"); - fflush(stdout); -} - -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { - const std::string counts = - FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); - ColoredPrintf(GTestColor::kGreen, "[----------] "); - printf("%s from %s", counts.c_str(), test_case.name()); - if (test_case.type_param() == nullptr) { - printf("\n"); - } else { - printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param()); - } - fflush(stdout); -} -#else -void PrettyUnitTestResultPrinter::OnTestSuiteStart( - const TestSuite& test_suite) { - const std::string counts = - FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests"); - ColoredPrintf(GTestColor::kGreen, "[----------] "); - printf("%s from %s", counts.c_str(), test_suite.name()); - if (test_suite.type_param() == nullptr) { - printf("\n"); - } else { - printf(", where %s = %s\n", kTypeParamLabel, test_suite.type_param()); - } - fflush(stdout); -} -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - -void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { - ColoredPrintf(GTestColor::kGreen, "[ RUN ] "); - PrintTestName(test_info.test_suite_name(), test_info.name()); - printf("\n"); - fflush(stdout); -} - -void PrettyUnitTestResultPrinter::OnTestDisabled(const TestInfo& test_info) { - ColoredPrintf(GTestColor::kYellow, "[ DISABLED ] "); - PrintTestName(test_info.test_suite_name(), test_info.name()); - printf("\n"); - fflush(stdout); -} - -// Called after an assertion failure. -void PrettyUnitTestResultPrinter::OnTestPartResult( - const TestPartResult& result) { - switch (result.type()) { - // If the test part succeeded, we don't need to do anything. - case TestPartResult::kSuccess: - return; - default: - // Print failure message from the assertion - // (e.g. expected this and got that). - PrintTestPartResult(result); - fflush(stdout); - } -} - -void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { - if (test_info.result()->Passed()) { - ColoredPrintf(GTestColor::kGreen, "[ OK ] "); - } else if (test_info.result()->Skipped()) { - ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] "); - } else { - ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); - } - PrintTestName(test_info.test_suite_name(), test_info.name()); - if (test_info.result()->Failed()) PrintFullTestCommentIfPresent(test_info); - - if (GTEST_FLAG_GET(print_time)) { - printf(" (%s ms)\n", - internal::StreamableToString(test_info.result()->elapsed_time()) - .c_str()); - } else { - printf("\n"); - } - fflush(stdout); -} - -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { - if (!GTEST_FLAG_GET(print_time)) return; - - const std::string counts = - FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); - ColoredPrintf(GTestColor::kGreen, "[----------] "); - printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_case.name(), - internal::StreamableToString(test_case.elapsed_time()).c_str()); - fflush(stdout); -} -#else -void PrettyUnitTestResultPrinter::OnTestSuiteEnd(const TestSuite& test_suite) { - if (!GTEST_FLAG_GET(print_time)) return; - - const std::string counts = - FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests"); - ColoredPrintf(GTestColor::kGreen, "[----------] "); - printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_suite.name(), - internal::StreamableToString(test_suite.elapsed_time()).c_str()); - fflush(stdout); -} -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - -void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( - const UnitTest& /*unit_test*/) { - ColoredPrintf(GTestColor::kGreen, "[----------] "); - printf("Global test environment tear-down\n"); - fflush(stdout); -} - -// Internal helper for printing the list of failed tests. -void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { - const int failed_test_count = unit_test.failed_test_count(); - ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); - printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); - - for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { - const TestSuite& test_suite = *unit_test.GetTestSuite(i); - if (!test_suite.should_run() || (test_suite.failed_test_count() == 0)) { - continue; - } - for (int j = 0; j < test_suite.total_test_count(); ++j) { - const TestInfo& test_info = *test_suite.GetTestInfo(j); - if (!test_info.should_run() || !test_info.result()->Failed()) { - continue; - } - ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); - printf("%s.%s", test_suite.name(), test_info.name()); - PrintFullTestCommentIfPresent(test_info); - printf("\n"); - } - } - printf("\n%2d FAILED %s\n", failed_test_count, - failed_test_count == 1 ? "TEST" : "TESTS"); -} - -// Internal helper for printing the list of test suite failures not covered by -// PrintFailedTests. -void PrettyUnitTestResultPrinter::PrintFailedTestSuites( - const UnitTest& unit_test) { - int suite_failure_count = 0; - for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { - const TestSuite& test_suite = *unit_test.GetTestSuite(i); - if (!test_suite.should_run()) { - continue; - } - if (test_suite.ad_hoc_test_result().Failed()) { - ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); - printf("%s: SetUpTestSuite or TearDownTestSuite\n", test_suite.name()); - ++suite_failure_count; - } - } - if (suite_failure_count > 0) { - printf("\n%2d FAILED TEST %s\n", suite_failure_count, - suite_failure_count == 1 ? "SUITE" : "SUITES"); - } -} - -// Internal helper for printing the list of skipped tests. -void PrettyUnitTestResultPrinter::PrintSkippedTests(const UnitTest& unit_test) { - const int skipped_test_count = unit_test.skipped_test_count(); - if (skipped_test_count == 0) { - return; - } - - for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { - const TestSuite& test_suite = *unit_test.GetTestSuite(i); - if (!test_suite.should_run() || (test_suite.skipped_test_count() == 0)) { - continue; - } - for (int j = 0; j < test_suite.total_test_count(); ++j) { - const TestInfo& test_info = *test_suite.GetTestInfo(j); - if (!test_info.should_run() || !test_info.result()->Skipped()) { - continue; - } - ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] "); - printf("%s.%s", test_suite.name(), test_info.name()); - printf("\n"); - } - } -} - -void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, - int /*iteration*/) { - ColoredPrintf(GTestColor::kGreen, "[==========] "); - printf("%s from %s ran.", - FormatTestCount(unit_test.test_to_run_count()).c_str(), - FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str()); - if (GTEST_FLAG_GET(print_time)) { - printf(" (%s ms total)", - internal::StreamableToString(unit_test.elapsed_time()).c_str()); - } - printf("\n"); - ColoredPrintf(GTestColor::kGreen, "[ PASSED ] "); - printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); - - const int skipped_test_count = unit_test.skipped_test_count(); - if (skipped_test_count > 0) { - ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] "); - printf("%s, listed below:\n", FormatTestCount(skipped_test_count).c_str()); - PrintSkippedTests(unit_test); - } - - if (!unit_test.Passed()) { - PrintFailedTests(unit_test); - PrintFailedTestSuites(unit_test); - } - - int num_disabled = unit_test.reportable_disabled_test_count(); - if (num_disabled && !GTEST_FLAG_GET(also_run_disabled_tests)) { - if (unit_test.Passed()) { - printf("\n"); // Add a spacer if no FAILURE banner is displayed. - } - ColoredPrintf(GTestColor::kYellow, " YOU HAVE %d DISABLED %s\n\n", - num_disabled, num_disabled == 1 ? "TEST" : "TESTS"); - } - // Ensure that Google Test output is printed before, e.g., heapchecker output. - fflush(stdout); -} - -// End PrettyUnitTestResultPrinter - -// This class implements the TestEventListener interface. -// -// Class BriefUnitTestResultPrinter is copyable. -class BriefUnitTestResultPrinter : public TestEventListener { - public: - BriefUnitTestResultPrinter() {} - static void PrintTestName(const char* test_suite, const char* test) { - printf("%s.%s", test_suite, test); - } - - // The following methods override what's in the TestEventListener class. - void OnTestProgramStart(const UnitTest& /*unit_test*/) override {} - void OnTestIterationStart(const UnitTest& /*unit_test*/, - int /*iteration*/) override {} - void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) override {} - void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {} -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - void OnTestCaseStart(const TestCase& /*test_case*/) override {} -#else - void OnTestSuiteStart(const TestSuite& /*test_suite*/) override {} -#endif // OnTestCaseStart - - void OnTestStart(const TestInfo& /*test_info*/) override {} - void OnTestDisabled(const TestInfo& /*test_info*/) override {} - - void OnTestPartResult(const TestPartResult& result) override; - void OnTestEnd(const TestInfo& test_info) override; -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - void OnTestCaseEnd(const TestCase& /*test_case*/) override {} -#else - void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {} -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - - void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) override {} - void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {} - void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override; - void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {} -}; - -// Called after an assertion failure. -void BriefUnitTestResultPrinter::OnTestPartResult( - const TestPartResult& result) { - switch (result.type()) { - // If the test part succeeded, we don't need to do anything. - case TestPartResult::kSuccess: - return; - default: - // Print failure message from the assertion - // (e.g. expected this and got that). - PrintTestPartResult(result); - fflush(stdout); - } -} - -void BriefUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { - if (test_info.result()->Failed()) { - ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); - PrintTestName(test_info.test_suite_name(), test_info.name()); - PrintFullTestCommentIfPresent(test_info); - - if (GTEST_FLAG_GET(print_time)) { - printf(" (%s ms)\n", - internal::StreamableToString(test_info.result()->elapsed_time()) - .c_str()); - } else { - printf("\n"); - } - fflush(stdout); - } -} - -void BriefUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, - int /*iteration*/) { - ColoredPrintf(GTestColor::kGreen, "[==========] "); - printf("%s from %s ran.", - FormatTestCount(unit_test.test_to_run_count()).c_str(), - FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str()); - if (GTEST_FLAG_GET(print_time)) { - printf(" (%s ms total)", - internal::StreamableToString(unit_test.elapsed_time()).c_str()); - } - printf("\n"); - ColoredPrintf(GTestColor::kGreen, "[ PASSED ] "); - printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); - - const int skipped_test_count = unit_test.skipped_test_count(); - if (skipped_test_count > 0) { - ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] "); - printf("%s.\n", FormatTestCount(skipped_test_count).c_str()); - } - - int num_disabled = unit_test.reportable_disabled_test_count(); - if (num_disabled && !GTEST_FLAG_GET(also_run_disabled_tests)) { - if (unit_test.Passed()) { - printf("\n"); // Add a spacer if no FAILURE banner is displayed. - } - ColoredPrintf(GTestColor::kYellow, " YOU HAVE %d DISABLED %s\n\n", - num_disabled, num_disabled == 1 ? "TEST" : "TESTS"); - } - // Ensure that Google Test output is printed before, e.g., heapchecker output. - fflush(stdout); -} - -// End BriefUnitTestResultPrinter - -// class TestEventRepeater -// -// This class forwards events to other event listeners. -class TestEventRepeater : public TestEventListener { - public: - TestEventRepeater() : forwarding_enabled_(true) {} - ~TestEventRepeater() override; - void Append(TestEventListener* listener); - TestEventListener* Release(TestEventListener* listener); - - // Controls whether events will be forwarded to listeners_. Set to false - // in death test child processes. - bool forwarding_enabled() const { return forwarding_enabled_; } - void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } - - void OnTestProgramStart(const UnitTest& unit_test) override; - void OnTestIterationStart(const UnitTest& unit_test, int iteration) override; - void OnEnvironmentsSetUpStart(const UnitTest& unit_test) override; - void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) override; -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - void OnTestCaseStart(const TestSuite& parameter) override; -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - void OnTestSuiteStart(const TestSuite& parameter) override; - void OnTestStart(const TestInfo& test_info) override; - void OnTestDisabled(const TestInfo& test_info) override; - void OnTestPartResult(const TestPartResult& result) override; - void OnTestEnd(const TestInfo& test_info) override; -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - void OnTestCaseEnd(const TestCase& parameter) override; -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - void OnTestSuiteEnd(const TestSuite& parameter) override; - void OnEnvironmentsTearDownStart(const UnitTest& unit_test) override; - void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) override; - void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override; - void OnTestProgramEnd(const UnitTest& unit_test) override; - - private: - // Controls whether events will be forwarded to listeners_. Set to false - // in death test child processes. - bool forwarding_enabled_; - // The list of listeners that receive events. - std::vector listeners_; - - TestEventRepeater(const TestEventRepeater&) = delete; - TestEventRepeater& operator=(const TestEventRepeater&) = delete; -}; - -TestEventRepeater::~TestEventRepeater() { - ForEach(listeners_, Delete); -} - -void TestEventRepeater::Append(TestEventListener* listener) { - listeners_.push_back(listener); -} - -TestEventListener* TestEventRepeater::Release(TestEventListener* listener) { - for (size_t i = 0; i < listeners_.size(); ++i) { - if (listeners_[i] == listener) { - listeners_.erase(listeners_.begin() + static_cast(i)); - return listener; - } - } - - return nullptr; -} - -// Since most methods are very similar, use macros to reduce boilerplate. -// This defines a member that forwards the call to all listeners. -#define GTEST_REPEATER_METHOD_(Name, Type) \ - void TestEventRepeater::Name(const Type& parameter) { \ - if (forwarding_enabled_) { \ - for (size_t i = 0; i < listeners_.size(); i++) { \ - listeners_[i]->Name(parameter); \ - } \ - } \ - } -// This defines a member that forwards the call to all listeners in reverse -// order. -#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ - void TestEventRepeater::Name(const Type& parameter) { \ - if (forwarding_enabled_) { \ - for (size_t i = listeners_.size(); i != 0; i--) { \ - listeners_[i - 1]->Name(parameter); \ - } \ - } \ - } - -GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) -GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -GTEST_REPEATER_METHOD_(OnTestCaseStart, TestSuite) -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -GTEST_REPEATER_METHOD_(OnTestSuiteStart, TestSuite) -GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) -GTEST_REPEATER_METHOD_(OnTestDisabled, TestInfo) -GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) -GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) -GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) -GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) -GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestSuite) -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -GTEST_REVERSE_REPEATER_METHOD_(OnTestSuiteEnd, TestSuite) -GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) - -#undef GTEST_REPEATER_METHOD_ -#undef GTEST_REVERSE_REPEATER_METHOD_ - -void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, - int iteration) { - if (forwarding_enabled_) { - for (size_t i = 0; i < listeners_.size(); i++) { - listeners_[i]->OnTestIterationStart(unit_test, iteration); - } - } -} - -void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, - int iteration) { - if (forwarding_enabled_) { - for (size_t i = listeners_.size(); i > 0; i--) { - listeners_[i - 1]->OnTestIterationEnd(unit_test, iteration); - } - } -} - -// End TestEventRepeater - -// This class generates an XML output file. -class XmlUnitTestResultPrinter : public EmptyTestEventListener { - public: - explicit XmlUnitTestResultPrinter(const char* output_file); - - void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override; - void ListTestsMatchingFilter(const std::vector& test_suites); - - // Prints an XML summary of all unit tests. - static void PrintXmlTestsList(std::ostream* stream, - const std::vector& test_suites); - - private: - // Is c a whitespace character that is normalized to a space character - // when it appears in an XML attribute value? - static bool IsNormalizableWhitespace(unsigned char c) { - return c == '\t' || c == '\n' || c == '\r'; - } - - // May c appear in a well-formed XML document? - // https://www.w3.org/TR/REC-xml/#charsets - static bool IsValidXmlCharacter(unsigned char c) { - return IsNormalizableWhitespace(c) || c >= 0x20; - } - - // Returns an XML-escaped copy of the input string str. If - // is_attribute is true, the text is meant to appear as an attribute - // value, and normalizable whitespace is preserved by replacing it - // with character references. - static std::string EscapeXml(const std::string& str, bool is_attribute); - - // Returns the given string with all characters invalid in XML removed. - static std::string RemoveInvalidXmlCharacters(const std::string& str); - - // Convenience wrapper around EscapeXml when str is an attribute value. - static std::string EscapeXmlAttribute(const std::string& str) { - return EscapeXml(str, true); - } - - // Convenience wrapper around EscapeXml when str is not an attribute value. - static std::string EscapeXmlText(const char* str) { - return EscapeXml(str, false); - } - - // Verifies that the given attribute belongs to the given element and - // streams the attribute as XML. - static void OutputXmlAttribute(std::ostream* stream, - const std::string& element_name, - const std::string& name, - const std::string& value); - - // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. - static void OutputXmlCDataSection(::std::ostream* stream, const char* data); - - // Streams a test suite XML stanza containing the given test result. - // - // Requires: result.Failed() - static void OutputXmlTestSuiteForTestResult(::std::ostream* stream, - const TestResult& result); - - // Streams an XML representation of a TestResult object. - static void OutputXmlTestResult(::std::ostream* stream, - const TestResult& result); - - // Streams an XML representation of a TestInfo object. - static void OutputXmlTestInfo(::std::ostream* stream, - const char* test_suite_name, - const TestInfo& test_info); - - // Prints an XML representation of a TestSuite object - static void PrintXmlTestSuite(::std::ostream* stream, - const TestSuite& test_suite); - - // Prints an XML summary of unit_test to output stream out. - static void PrintXmlUnitTest(::std::ostream* stream, - const UnitTest& unit_test); - - // Produces a string representing the test properties in a result as space - // delimited XML attributes based on the property key="value" pairs. - // When the std::string is not empty, it includes a space at the beginning, - // to delimit this attribute from prior attributes. - static std::string TestPropertiesAsXmlAttributes(const TestResult& result); - - // Streams an XML representation of the test properties of a TestResult - // object. - static void OutputXmlTestProperties(std::ostream* stream, - const TestResult& result); - - // The output file. - const std::string output_file_; - - XmlUnitTestResultPrinter(const XmlUnitTestResultPrinter&) = delete; - XmlUnitTestResultPrinter& operator=(const XmlUnitTestResultPrinter&) = delete; -}; - -// Creates a new XmlUnitTestResultPrinter. -XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) - : output_file_(output_file) { - if (output_file_.empty()) { - GTEST_LOG_(FATAL) << "XML output file may not be null"; - } -} - -// Called after the unit test ends. -void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, - int /*iteration*/) { - FILE* xmlout = OpenFileForWriting(output_file_); - std::stringstream stream; - PrintXmlUnitTest(&stream, unit_test); - fprintf(xmlout, "%s", StringStreamToString(&stream).c_str()); - fclose(xmlout); -} - -void XmlUnitTestResultPrinter::ListTestsMatchingFilter( - const std::vector& test_suites) { - FILE* xmlout = OpenFileForWriting(output_file_); - std::stringstream stream; - PrintXmlTestsList(&stream, test_suites); - fprintf(xmlout, "%s", StringStreamToString(&stream).c_str()); - fclose(xmlout); -} - -// Returns an XML-escaped copy of the input string str. If is_attribute -// is true, the text is meant to appear as an attribute value, and -// normalizable whitespace is preserved by replacing it with character -// references. -// -// Invalid XML characters in str, if any, are stripped from the output. -// It is expected that most, if not all, of the text processed by this -// module will consist of ordinary English text. -// If this module is ever modified to produce version 1.1 XML output, -// most invalid characters can be retained using character references. -std::string XmlUnitTestResultPrinter::EscapeXml(const std::string& str, - bool is_attribute) { - Message m; - - for (size_t i = 0; i < str.size(); ++i) { - const char ch = str[i]; - switch (ch) { - case '<': - m << "<"; - break; - case '>': - m << ">"; - break; - case '&': - m << "&"; - break; - case '\'': - if (is_attribute) - m << "'"; - else - m << '\''; - break; - case '"': - if (is_attribute) - m << """; - else - m << '"'; - break; - default: - if (IsValidXmlCharacter(static_cast(ch))) { - if (is_attribute && - IsNormalizableWhitespace(static_cast(ch))) - m << "&#x" << String::FormatByte(static_cast(ch)) - << ";"; - else - m << ch; - } - break; - } - } - - return m.GetString(); -} - -// Returns the given string with all characters invalid in XML removed. -// Currently invalid characters are dropped from the string. An -// alternative is to replace them with certain characters such as . or ?. -std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters( - const std::string& str) { - std::string output; - output.reserve(str.size()); - for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) - if (IsValidXmlCharacter(static_cast(*it))) - output.push_back(*it); - - return output; -} - -// The following routines generate an XML representation of a UnitTest -// object. -// -// This is how Google Test concepts map to the DTD: -// -// <-- corresponds to a UnitTest object -// <-- corresponds to a TestSuite object -// <-- corresponds to a TestInfo object -// ... -// ... -// ... -// <-- individual assertion failures -// -// -// - -// Formats the given time in milliseconds as seconds. -std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { - ::std::stringstream ss; - ss << (static_cast(ms) * 1e-3); - return ss.str(); -} - -static bool PortableLocaltime(time_t seconds, struct tm* out) { -#if defined(_MSC_VER) - return localtime_s(out, &seconds) == 0; -#elif defined(__MINGW32__) || defined(__MINGW64__) - // MINGW provides neither localtime_r nor localtime_s, but uses - // Windows' localtime(), which has a thread-local tm buffer. - struct tm* tm_ptr = localtime(&seconds); // NOLINT - if (tm_ptr == nullptr) return false; - *out = *tm_ptr; - return true; -#elif defined(__STDC_LIB_EXT1__) - // Uses localtime_s when available as localtime_r is only available from - // C23 standard. - return localtime_s(&seconds, out) != nullptr; -#else - return localtime_r(&seconds, out) != nullptr; -#endif -} - -// Converts the given epoch time in milliseconds to a date string in the ISO -// 8601 format, without the timezone information. -std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) { - struct tm time_struct; - if (!PortableLocaltime(static_cast(ms / 1000), &time_struct)) - return ""; - // YYYY-MM-DDThh:mm:ss.sss - return StreamableToString(time_struct.tm_year + 1900) + "-" + - String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" + - String::FormatIntWidth2(time_struct.tm_mday) + "T" + - String::FormatIntWidth2(time_struct.tm_hour) + ":" + - String::FormatIntWidth2(time_struct.tm_min) + ":" + - String::FormatIntWidth2(time_struct.tm_sec) + "." + - String::FormatIntWidthN(static_cast(ms % 1000), 3); -} - -// Streams an XML CDATA section, escaping invalid CDATA sequences as needed. -void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, - const char* data) { - const char* segment = data; - *stream << ""); - if (next_segment != nullptr) { - stream->write(segment, - static_cast(next_segment - segment)); - *stream << "]]>]]>"); - } else { - *stream << segment; - break; - } - } - *stream << "]]>"; -} - -void XmlUnitTestResultPrinter::OutputXmlAttribute( - std::ostream* stream, const std::string& element_name, - const std::string& name, const std::string& value) { - const std::vector& allowed_names = - GetReservedOutputAttributesForElement(element_name); - - GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != - allowed_names.end()) - << "Attribute " << name << " is not allowed for element <" << element_name - << ">."; - - *stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\""; -} - -// Streams a test suite XML stanza containing the given test result. -void XmlUnitTestResultPrinter::OutputXmlTestSuiteForTestResult( - ::std::ostream* stream, const TestResult& result) { - // Output the boilerplate for a minimal test suite with one test. - *stream << " "; - - // Output the boilerplate for a minimal test case with a single test. - *stream << " \n"; -} - -// Prints an XML representation of a TestInfo object. -void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, - const char* test_suite_name, - const TestInfo& test_info) { - const TestResult& result = *test_info.result(); - const std::string kTestsuite = "testcase"; - - if (test_info.is_in_another_shard()) { - return; - } - - *stream << " \n"; - return; - } - - OutputXmlAttribute(stream, kTestsuite, "status", - test_info.should_run() ? "run" : "notrun"); - OutputXmlAttribute(stream, kTestsuite, "result", - test_info.should_run() - ? (result.Skipped() ? "skipped" : "completed") - : "suppressed"); - OutputXmlAttribute(stream, kTestsuite, "time", - FormatTimeInMillisAsSeconds(result.elapsed_time())); - OutputXmlAttribute( - stream, kTestsuite, "timestamp", - FormatEpochTimeInMillisAsIso8601(result.start_timestamp())); - OutputXmlAttribute(stream, kTestsuite, "classname", test_suite_name); - - OutputXmlTestResult(stream, result); -} - -void XmlUnitTestResultPrinter::OutputXmlTestResult(::std::ostream* stream, - const TestResult& result) { - int failures = 0; - int skips = 0; - for (int i = 0; i < result.total_part_count(); ++i) { - const TestPartResult& part = result.GetTestPartResult(i); - if (part.failed()) { - if (++failures == 1 && skips == 0) { - *stream << ">\n"; - } - const std::string location = - internal::FormatCompilerIndependentFileLocation(part.file_name(), - part.line_number()); - const std::string summary = location + "\n" + part.summary(); - *stream << " "; - const std::string detail = location + "\n" + part.message(); - OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); - *stream << "\n"; - } else if (part.skipped()) { - if (++skips == 1 && failures == 0) { - *stream << ">\n"; - } - const std::string location = - internal::FormatCompilerIndependentFileLocation(part.file_name(), - part.line_number()); - const std::string summary = location + "\n" + part.summary(); - *stream << " "; - const std::string detail = location + "\n" + part.message(); - OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); - *stream << "\n"; - } - } - - if (failures == 0 && skips == 0 && result.test_property_count() == 0) { - *stream << " />\n"; - } else { - if (failures == 0 && skips == 0) { - *stream << ">\n"; - } - OutputXmlTestProperties(stream, result); - *stream << " \n"; - } -} - -// Prints an XML representation of a TestSuite object -void XmlUnitTestResultPrinter::PrintXmlTestSuite(std::ostream* stream, - const TestSuite& test_suite) { - const std::string kTestsuite = "testsuite"; - *stream << " <" << kTestsuite; - OutputXmlAttribute(stream, kTestsuite, "name", test_suite.name()); - OutputXmlAttribute(stream, kTestsuite, "tests", - StreamableToString(test_suite.reportable_test_count())); - if (!GTEST_FLAG_GET(list_tests)) { - OutputXmlAttribute(stream, kTestsuite, "failures", - StreamableToString(test_suite.failed_test_count())); - OutputXmlAttribute( - stream, kTestsuite, "disabled", - StreamableToString(test_suite.reportable_disabled_test_count())); - OutputXmlAttribute(stream, kTestsuite, "skipped", - StreamableToString(test_suite.skipped_test_count())); - - OutputXmlAttribute(stream, kTestsuite, "errors", "0"); - - OutputXmlAttribute(stream, kTestsuite, "time", - FormatTimeInMillisAsSeconds(test_suite.elapsed_time())); - OutputXmlAttribute( - stream, kTestsuite, "timestamp", - FormatEpochTimeInMillisAsIso8601(test_suite.start_timestamp())); - *stream << TestPropertiesAsXmlAttributes(test_suite.ad_hoc_test_result()); - } - *stream << ">\n"; - for (int i = 0; i < test_suite.total_test_count(); ++i) { - if (test_suite.GetTestInfo(i)->is_reportable()) - OutputXmlTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i)); - } - *stream << " \n"; -} - -// Prints an XML summary of unit_test to output stream out. -void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, - const UnitTest& unit_test) { - const std::string kTestsuites = "testsuites"; - - *stream << "\n"; - *stream << "<" << kTestsuites; - - OutputXmlAttribute(stream, kTestsuites, "tests", - StreamableToString(unit_test.reportable_test_count())); - OutputXmlAttribute(stream, kTestsuites, "failures", - StreamableToString(unit_test.failed_test_count())); - OutputXmlAttribute( - stream, kTestsuites, "disabled", - StreamableToString(unit_test.reportable_disabled_test_count())); - OutputXmlAttribute(stream, kTestsuites, "errors", "0"); - OutputXmlAttribute(stream, kTestsuites, "time", - FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); - OutputXmlAttribute( - stream, kTestsuites, "timestamp", - FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp())); - - if (GTEST_FLAG_GET(shuffle)) { - OutputXmlAttribute(stream, kTestsuites, "random_seed", - StreamableToString(unit_test.random_seed())); - } - *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result()); - - OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); - *stream << ">\n"; - - for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { - if (unit_test.GetTestSuite(i)->reportable_test_count() > 0) - PrintXmlTestSuite(stream, *unit_test.GetTestSuite(i)); - } - - // If there was a test failure outside of one of the test suites (like in a - // test environment) include that in the output. - if (unit_test.ad_hoc_test_result().Failed()) { - OutputXmlTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result()); - } - - *stream << "\n"; -} - -void XmlUnitTestResultPrinter::PrintXmlTestsList( - std::ostream* stream, const std::vector& test_suites) { - const std::string kTestsuites = "testsuites"; - - *stream << "\n"; - *stream << "<" << kTestsuites; - - int total_tests = 0; - for (auto test_suite : test_suites) { - total_tests += test_suite->total_test_count(); - } - OutputXmlAttribute(stream, kTestsuites, "tests", - StreamableToString(total_tests)); - OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); - *stream << ">\n"; - - for (auto test_suite : test_suites) { - PrintXmlTestSuite(stream, *test_suite); - } - *stream << "\n"; -} - -// Produces a string representing the test properties in a result as space -// delimited XML attributes based on the property key="value" pairs. -std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( - const TestResult& result) { - Message attributes; - for (int i = 0; i < result.test_property_count(); ++i) { - const TestProperty& property = result.GetTestProperty(i); - attributes << " " << property.key() << "=" - << "\"" << EscapeXmlAttribute(property.value()) << "\""; - } - return attributes.GetString(); -} - -void XmlUnitTestResultPrinter::OutputXmlTestProperties( - std::ostream* stream, const TestResult& result) { - const std::string kProperties = "properties"; - const std::string kProperty = "property"; - - if (result.test_property_count() <= 0) { - return; - } - - *stream << " <" << kProperties << ">\n"; - for (int i = 0; i < result.test_property_count(); ++i) { - const TestProperty& property = result.GetTestProperty(i); - *stream << " <" << kProperty; - *stream << " name=\"" << EscapeXmlAttribute(property.key()) << "\""; - *stream << " value=\"" << EscapeXmlAttribute(property.value()) << "\""; - *stream << "/>\n"; - } - *stream << " \n"; -} - -// End XmlUnitTestResultPrinter - -// This class generates an JSON output file. -class JsonUnitTestResultPrinter : public EmptyTestEventListener { - public: - explicit JsonUnitTestResultPrinter(const char* output_file); - - void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override; - - // Prints an JSON summary of all unit tests. - static void PrintJsonTestList(::std::ostream* stream, - const std::vector& test_suites); - - private: - // Returns an JSON-escaped copy of the input string str. - static std::string EscapeJson(const std::string& str); - - //// Verifies that the given attribute belongs to the given element and - //// streams the attribute as JSON. - static void OutputJsonKey(std::ostream* stream, - const std::string& element_name, - const std::string& name, const std::string& value, - const std::string& indent, bool comma = true); - static void OutputJsonKey(std::ostream* stream, - const std::string& element_name, - const std::string& name, int value, - const std::string& indent, bool comma = true); - - // Streams a test suite JSON stanza containing the given test result. - // - // Requires: result.Failed() - static void OutputJsonTestSuiteForTestResult(::std::ostream* stream, - const TestResult& result); - - // Streams a JSON representation of a TestResult object. - static void OutputJsonTestResult(::std::ostream* stream, - const TestResult& result); - - // Streams a JSON representation of a TestInfo object. - static void OutputJsonTestInfo(::std::ostream* stream, - const char* test_suite_name, - const TestInfo& test_info); - - // Prints a JSON representation of a TestSuite object - static void PrintJsonTestSuite(::std::ostream* stream, - const TestSuite& test_suite); - - // Prints a JSON summary of unit_test to output stream out. - static void PrintJsonUnitTest(::std::ostream* stream, - const UnitTest& unit_test); - - // Produces a string representing the test properties in a result as - // a JSON dictionary. - static std::string TestPropertiesAsJson(const TestResult& result, - const std::string& indent); - - // The output file. - const std::string output_file_; - - JsonUnitTestResultPrinter(const JsonUnitTestResultPrinter&) = delete; - JsonUnitTestResultPrinter& operator=(const JsonUnitTestResultPrinter&) = - delete; -}; - -// Creates a new JsonUnitTestResultPrinter. -JsonUnitTestResultPrinter::JsonUnitTestResultPrinter(const char* output_file) - : output_file_(output_file) { - if (output_file_.empty()) { - GTEST_LOG_(FATAL) << "JSON output file may not be null"; - } -} - -void JsonUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, - int /*iteration*/) { - FILE* jsonout = OpenFileForWriting(output_file_); - std::stringstream stream; - PrintJsonUnitTest(&stream, unit_test); - fprintf(jsonout, "%s", StringStreamToString(&stream).c_str()); - fclose(jsonout); -} - -// Returns an JSON-escaped copy of the input string str. -std::string JsonUnitTestResultPrinter::EscapeJson(const std::string& str) { - Message m; - - for (size_t i = 0; i < str.size(); ++i) { - const char ch = str[i]; - switch (ch) { - case '\\': - case '"': - case '/': - m << '\\' << ch; - break; - case '\b': - m << "\\b"; - break; - case '\t': - m << "\\t"; - break; - case '\n': - m << "\\n"; - break; - case '\f': - m << "\\f"; - break; - case '\r': - m << "\\r"; - break; - default: - if (ch < ' ') { - m << "\\u00" << String::FormatByte(static_cast(ch)); - } else { - m << ch; - } - break; - } - } - - return m.GetString(); -} - -// The following routines generate an JSON representation of a UnitTest -// object. - -// Formats the given time in milliseconds as seconds. -static std::string FormatTimeInMillisAsDuration(TimeInMillis ms) { - ::std::stringstream ss; - ss << (static_cast(ms) * 1e-3) << "s"; - return ss.str(); -} - -// Converts the given epoch time in milliseconds to a date string in the -// RFC3339 format, without the timezone information. -static std::string FormatEpochTimeInMillisAsRFC3339(TimeInMillis ms) { - struct tm time_struct; - if (!PortableLocaltime(static_cast(ms / 1000), &time_struct)) - return ""; - // YYYY-MM-DDThh:mm:ss - return StreamableToString(time_struct.tm_year + 1900) + "-" + - String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" + - String::FormatIntWidth2(time_struct.tm_mday) + "T" + - String::FormatIntWidth2(time_struct.tm_hour) + ":" + - String::FormatIntWidth2(time_struct.tm_min) + ":" + - String::FormatIntWidth2(time_struct.tm_sec) + "Z"; -} - -static inline std::string Indent(size_t width) { - return std::string(width, ' '); -} - -void JsonUnitTestResultPrinter::OutputJsonKey(std::ostream* stream, - const std::string& element_name, - const std::string& name, - const std::string& value, - const std::string& indent, - bool comma) { - const std::vector& allowed_names = - GetReservedOutputAttributesForElement(element_name); - - GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != - allowed_names.end()) - << "Key \"" << name << "\" is not allowed for value \"" << element_name - << "\"."; - - *stream << indent << "\"" << name << "\": \"" << EscapeJson(value) << "\""; - if (comma) *stream << ",\n"; -} - -void JsonUnitTestResultPrinter::OutputJsonKey( - std::ostream* stream, const std::string& element_name, - const std::string& name, int value, const std::string& indent, bool comma) { - const std::vector& allowed_names = - GetReservedOutputAttributesForElement(element_name); - - GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != - allowed_names.end()) - << "Key \"" << name << "\" is not allowed for value \"" << element_name - << "\"."; - - *stream << indent << "\"" << name << "\": " << StreamableToString(value); - if (comma) *stream << ",\n"; -} - -// Streams a test suite JSON stanza containing the given test result. -void JsonUnitTestResultPrinter::OutputJsonTestSuiteForTestResult( - ::std::ostream* stream, const TestResult& result) { - // Output the boilerplate for a new test suite. - *stream << Indent(4) << "{\n"; - OutputJsonKey(stream, "testsuite", "name", "NonTestSuiteFailure", Indent(6)); - OutputJsonKey(stream, "testsuite", "tests", 1, Indent(6)); - if (!GTEST_FLAG_GET(list_tests)) { - OutputJsonKey(stream, "testsuite", "failures", 1, Indent(6)); - OutputJsonKey(stream, "testsuite", "disabled", 0, Indent(6)); - OutputJsonKey(stream, "testsuite", "skipped", 0, Indent(6)); - OutputJsonKey(stream, "testsuite", "errors", 0, Indent(6)); - OutputJsonKey(stream, "testsuite", "time", - FormatTimeInMillisAsDuration(result.elapsed_time()), - Indent(6)); - OutputJsonKey(stream, "testsuite", "timestamp", - FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()), - Indent(6)); - } - *stream << Indent(6) << "\"testsuite\": [\n"; - - // Output the boilerplate for a new test case. - *stream << Indent(8) << "{\n"; - OutputJsonKey(stream, "testcase", "name", "", Indent(10)); - OutputJsonKey(stream, "testcase", "status", "RUN", Indent(10)); - OutputJsonKey(stream, "testcase", "result", "COMPLETED", Indent(10)); - OutputJsonKey(stream, "testcase", "timestamp", - FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()), - Indent(10)); - OutputJsonKey(stream, "testcase", "time", - FormatTimeInMillisAsDuration(result.elapsed_time()), - Indent(10)); - OutputJsonKey(stream, "testcase", "classname", "", Indent(10), false); - *stream << TestPropertiesAsJson(result, Indent(10)); - - // Output the actual test result. - OutputJsonTestResult(stream, result); - - // Finish the test suite. - *stream << "\n" << Indent(6) << "]\n" << Indent(4) << "}"; -} - -// Prints a JSON representation of a TestInfo object. -void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream, - const char* test_suite_name, - const TestInfo& test_info) { - const TestResult& result = *test_info.result(); - const std::string kTestsuite = "testcase"; - const std::string kIndent = Indent(10); - - *stream << Indent(8) << "{\n"; - OutputJsonKey(stream, kTestsuite, "name", test_info.name(), kIndent); - - if (test_info.value_param() != nullptr) { - OutputJsonKey(stream, kTestsuite, "value_param", test_info.value_param(), - kIndent); - } - if (test_info.type_param() != nullptr) { - OutputJsonKey(stream, kTestsuite, "type_param", test_info.type_param(), - kIndent); - } - - OutputJsonKey(stream, kTestsuite, "file", test_info.file(), kIndent); - OutputJsonKey(stream, kTestsuite, "line", test_info.line(), kIndent, false); - if (GTEST_FLAG_GET(list_tests)) { - *stream << "\n" << Indent(8) << "}"; - return; - } else { - *stream << ",\n"; - } - - OutputJsonKey(stream, kTestsuite, "status", - test_info.should_run() ? "RUN" : "NOTRUN", kIndent); - OutputJsonKey(stream, kTestsuite, "result", - test_info.should_run() - ? (result.Skipped() ? "SKIPPED" : "COMPLETED") - : "SUPPRESSED", - kIndent); - OutputJsonKey(stream, kTestsuite, "timestamp", - FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()), - kIndent); - OutputJsonKey(stream, kTestsuite, "time", - FormatTimeInMillisAsDuration(result.elapsed_time()), kIndent); - OutputJsonKey(stream, kTestsuite, "classname", test_suite_name, kIndent, - false); - *stream << TestPropertiesAsJson(result, kIndent); - - OutputJsonTestResult(stream, result); -} - -void JsonUnitTestResultPrinter::OutputJsonTestResult(::std::ostream* stream, - const TestResult& result) { - const std::string kIndent = Indent(10); - - int failures = 0; - for (int i = 0; i < result.total_part_count(); ++i) { - const TestPartResult& part = result.GetTestPartResult(i); - if (part.failed()) { - *stream << ",\n"; - if (++failures == 1) { - *stream << kIndent << "\"" - << "failures" - << "\": [\n"; - } - const std::string location = - internal::FormatCompilerIndependentFileLocation(part.file_name(), - part.line_number()); - const std::string message = EscapeJson(location + "\n" + part.message()); - *stream << kIndent << " {\n" - << kIndent << " \"failure\": \"" << message << "\",\n" - << kIndent << " \"type\": \"\"\n" - << kIndent << " }"; - } - } - - if (failures > 0) *stream << "\n" << kIndent << "]"; - *stream << "\n" << Indent(8) << "}"; -} - -// Prints an JSON representation of a TestSuite object -void JsonUnitTestResultPrinter::PrintJsonTestSuite( - std::ostream* stream, const TestSuite& test_suite) { - const std::string kTestsuite = "testsuite"; - const std::string kIndent = Indent(6); - - *stream << Indent(4) << "{\n"; - OutputJsonKey(stream, kTestsuite, "name", test_suite.name(), kIndent); - OutputJsonKey(stream, kTestsuite, "tests", test_suite.reportable_test_count(), - kIndent); - if (!GTEST_FLAG_GET(list_tests)) { - OutputJsonKey(stream, kTestsuite, "failures", - test_suite.failed_test_count(), kIndent); - OutputJsonKey(stream, kTestsuite, "disabled", - test_suite.reportable_disabled_test_count(), kIndent); - OutputJsonKey(stream, kTestsuite, "errors", 0, kIndent); - OutputJsonKey( - stream, kTestsuite, "timestamp", - FormatEpochTimeInMillisAsRFC3339(test_suite.start_timestamp()), - kIndent); - OutputJsonKey(stream, kTestsuite, "time", - FormatTimeInMillisAsDuration(test_suite.elapsed_time()), - kIndent, false); - *stream << TestPropertiesAsJson(test_suite.ad_hoc_test_result(), kIndent) - << ",\n"; - } - - *stream << kIndent << "\"" << kTestsuite << "\": [\n"; - - bool comma = false; - for (int i = 0; i < test_suite.total_test_count(); ++i) { - if (test_suite.GetTestInfo(i)->is_reportable()) { - if (comma) { - *stream << ",\n"; - } else { - comma = true; - } - OutputJsonTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i)); - } - } - *stream << "\n" << kIndent << "]\n" << Indent(4) << "}"; -} - -// Prints a JSON summary of unit_test to output stream out. -void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream, - const UnitTest& unit_test) { - const std::string kTestsuites = "testsuites"; - const std::string kIndent = Indent(2); - *stream << "{\n"; - - OutputJsonKey(stream, kTestsuites, "tests", unit_test.reportable_test_count(), - kIndent); - OutputJsonKey(stream, kTestsuites, "failures", unit_test.failed_test_count(), - kIndent); - OutputJsonKey(stream, kTestsuites, "disabled", - unit_test.reportable_disabled_test_count(), kIndent); - OutputJsonKey(stream, kTestsuites, "errors", 0, kIndent); - if (GTEST_FLAG_GET(shuffle)) { - OutputJsonKey(stream, kTestsuites, "random_seed", unit_test.random_seed(), - kIndent); - } - OutputJsonKey(stream, kTestsuites, "timestamp", - FormatEpochTimeInMillisAsRFC3339(unit_test.start_timestamp()), - kIndent); - OutputJsonKey(stream, kTestsuites, "time", - FormatTimeInMillisAsDuration(unit_test.elapsed_time()), kIndent, - false); - - *stream << TestPropertiesAsJson(unit_test.ad_hoc_test_result(), kIndent) - << ",\n"; - - OutputJsonKey(stream, kTestsuites, "name", "AllTests", kIndent); - *stream << kIndent << "\"" << kTestsuites << "\": [\n"; - - bool comma = false; - for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { - if (unit_test.GetTestSuite(i)->reportable_test_count() > 0) { - if (comma) { - *stream << ",\n"; - } else { - comma = true; - } - PrintJsonTestSuite(stream, *unit_test.GetTestSuite(i)); - } - } - - // If there was a test failure outside of one of the test suites (like in a - // test environment) include that in the output. - if (unit_test.ad_hoc_test_result().Failed()) { - OutputJsonTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result()); - } - - *stream << "\n" - << kIndent << "]\n" - << "}\n"; -} - -void JsonUnitTestResultPrinter::PrintJsonTestList( - std::ostream* stream, const std::vector& test_suites) { - const std::string kTestsuites = "testsuites"; - const std::string kIndent = Indent(2); - *stream << "{\n"; - int total_tests = 0; - for (auto test_suite : test_suites) { - total_tests += test_suite->total_test_count(); - } - OutputJsonKey(stream, kTestsuites, "tests", total_tests, kIndent); - - OutputJsonKey(stream, kTestsuites, "name", "AllTests", kIndent); - *stream << kIndent << "\"" << kTestsuites << "\": [\n"; - - for (size_t i = 0; i < test_suites.size(); ++i) { - if (i != 0) { - *stream << ",\n"; - } - PrintJsonTestSuite(stream, *test_suites[i]); - } - - *stream << "\n" - << kIndent << "]\n" - << "}\n"; -} -// Produces a string representing the test properties in a result as -// a JSON dictionary. -std::string JsonUnitTestResultPrinter::TestPropertiesAsJson( - const TestResult& result, const std::string& indent) { - Message attributes; - for (int i = 0; i < result.test_property_count(); ++i) { - const TestProperty& property = result.GetTestProperty(i); - attributes << ",\n" - << indent << "\"" << property.key() << "\": " - << "\"" << EscapeJson(property.value()) << "\""; - } - return attributes.GetString(); -} - -// End JsonUnitTestResultPrinter - -#if GTEST_CAN_STREAM_RESULTS_ - -// Checks if str contains '=', '&', '%' or '\n' characters. If yes, -// replaces them by "%xx" where xx is their hexadecimal value. For -// example, replaces "=" with "%3D". This algorithm is O(strlen(str)) -// in both time and space -- important as the input str may contain an -// arbitrarily long test failure message and stack trace. -std::string StreamingListener::UrlEncode(const char* str) { - std::string result; - result.reserve(strlen(str) + 1); - for (char ch = *str; ch != '\0'; ch = *++str) { - switch (ch) { - case '%': - case '=': - case '&': - case '\n': - result.append("%" + String::FormatByte(static_cast(ch))); - break; - default: - result.push_back(ch); - break; - } - } - return result; -} - -void StreamingListener::SocketWriter::MakeConnection() { - GTEST_CHECK_(sockfd_ == -1) - << "MakeConnection() can't be called when there is already a connection."; - - addrinfo hints; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. - hints.ai_socktype = SOCK_STREAM; - addrinfo* servinfo = nullptr; - - // Use the getaddrinfo() to get a linked list of IP addresses for - // the given host name. - const int error_num = - getaddrinfo(host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); - if (error_num != 0) { - GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " - << gai_strerror(error_num); - } - - // Loop through all the results and connect to the first we can. - for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != nullptr; - cur_addr = cur_addr->ai_next) { - sockfd_ = socket(cur_addr->ai_family, cur_addr->ai_socktype, - cur_addr->ai_protocol); - if (sockfd_ != -1) { - // Connect the client socket to the server socket. - if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { - close(sockfd_); - sockfd_ = -1; - } - } - } - - freeaddrinfo(servinfo); // all done with this structure - - if (sockfd_ == -1) { - GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " - << host_name_ << ":" << port_num_; - } -} - -// End of class Streaming Listener -#endif // GTEST_CAN_STREAM_RESULTS__ - -// class OsStackTraceGetter - -const char* const OsStackTraceGetterInterface::kElidedFramesMarker = - "... " GTEST_NAME_ " internal frames ..."; - -std::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count) - GTEST_LOCK_EXCLUDED_(mutex_) { -#if GTEST_HAS_ABSL - std::string result; - - if (max_depth <= 0) { - return result; - } - - max_depth = std::min(max_depth, kMaxStackTraceDepth); - - std::vector raw_stack(max_depth); - // Skips the frames requested by the caller, plus this function. - const int raw_stack_size = - absl::GetStackTrace(&raw_stack[0], max_depth, skip_count + 1); - - void* caller_frame = nullptr; - { - MutexLock lock(&mutex_); - caller_frame = caller_frame_; - } - - for (int i = 0; i < raw_stack_size; ++i) { - if (raw_stack[i] == caller_frame && - !GTEST_FLAG_GET(show_internal_stack_frames)) { - // Add a marker to the trace and stop adding frames. - absl::StrAppend(&result, kElidedFramesMarker, "\n"); - break; - } - - char tmp[1024]; - const char* symbol = "(unknown)"; - if (absl::Symbolize(raw_stack[i], tmp, sizeof(tmp))) { - symbol = tmp; - } - - char line[1024]; - snprintf(line, sizeof(line), " %p: %s\n", raw_stack[i], symbol); - result += line; - } - - return result; - -#else // !GTEST_HAS_ABSL - static_cast(max_depth); - static_cast(skip_count); - return ""; -#endif // GTEST_HAS_ABSL -} - -void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) { -#if GTEST_HAS_ABSL - void* caller_frame = nullptr; - if (absl::GetStackTrace(&caller_frame, 1, 3) <= 0) { - caller_frame = nullptr; - } - - MutexLock lock(&mutex_); - caller_frame_ = caller_frame; -#endif // GTEST_HAS_ABSL -} - -// A helper class that creates the premature-exit file in its -// constructor and deletes the file in its destructor. -class ScopedPrematureExitFile { - public: - explicit ScopedPrematureExitFile(const char* premature_exit_filepath) - : premature_exit_filepath_( - premature_exit_filepath ? premature_exit_filepath : "") { - // If a path to the premature-exit file is specified... - if (!premature_exit_filepath_.empty()) { - // create the file with a single "0" character in it. I/O - // errors are ignored as there's nothing better we can do and we - // don't want to fail the test because of this. - FILE* pfile = posix::FOpen(premature_exit_filepath_.c_str(), "w"); - fwrite("0", 1, 1, pfile); - fclose(pfile); - } - } - - ~ScopedPrematureExitFile() { -#if !defined GTEST_OS_ESP8266 - if (!premature_exit_filepath_.empty()) { - int retval = remove(premature_exit_filepath_.c_str()); - if (retval) { - GTEST_LOG_(ERROR) << "Failed to remove premature exit filepath \"" - << premature_exit_filepath_ << "\" with error " - << retval; - } - } -#endif - } - - private: - const std::string premature_exit_filepath_; - - ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete; - ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&) = delete; -}; - -} // namespace internal - -// class TestEventListeners - -TestEventListeners::TestEventListeners() - : repeater_(new internal::TestEventRepeater()), - default_result_printer_(nullptr), - default_xml_generator_(nullptr) {} - -TestEventListeners::~TestEventListeners() { delete repeater_; } - -// Returns the standard listener responsible for the default console -// output. Can be removed from the listeners list to shut down default -// console output. Note that removing this object from the listener list -// with Release transfers its ownership to the user. -void TestEventListeners::Append(TestEventListener* listener) { - repeater_->Append(listener); -} - -// Removes the given event listener from the list and returns it. It then -// becomes the caller's responsibility to delete the listener. Returns -// NULL if the listener is not found in the list. -TestEventListener* TestEventListeners::Release(TestEventListener* listener) { - if (listener == default_result_printer_) - default_result_printer_ = nullptr; - else if (listener == default_xml_generator_) - default_xml_generator_ = nullptr; - return repeater_->Release(listener); -} - -// Returns repeater that broadcasts the TestEventListener events to all -// subscribers. -TestEventListener* TestEventListeners::repeater() { return repeater_; } - -// Sets the default_result_printer attribute to the provided listener. -// The listener is also added to the listener list and previous -// default_result_printer is removed from it and deleted. The listener can -// also be NULL in which case it will not be added to the list. Does -// nothing if the previous and the current listener objects are the same. -void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { - if (default_result_printer_ != listener) { - // It is an error to pass this method a listener that is already in the - // list. - delete Release(default_result_printer_); - default_result_printer_ = listener; - if (listener != nullptr) Append(listener); - } -} - -// Sets the default_xml_generator attribute to the provided listener. The -// listener is also added to the listener list and previous -// default_xml_generator is removed from it and deleted. The listener can -// also be NULL in which case it will not be added to the list. Does -// nothing if the previous and the current listener objects are the same. -void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { - if (default_xml_generator_ != listener) { - // It is an error to pass this method a listener that is already in the - // list. - delete Release(default_xml_generator_); - default_xml_generator_ = listener; - if (listener != nullptr) Append(listener); - } -} - -// Controls whether events will be forwarded by the repeater to the -// listeners in the list. -bool TestEventListeners::EventForwardingEnabled() const { - return repeater_->forwarding_enabled(); -} - -void TestEventListeners::SuppressEventForwarding() { - repeater_->set_forwarding_enabled(false); -} - -// class UnitTest - -// Gets the singleton UnitTest object. The first time this method is -// called, a UnitTest object is constructed and returned. Consecutive -// calls will return the same object. -// -// We don't protect this under mutex_ as a user is not supposed to -// call this before main() starts, from which point on the return -// value will never change. -UnitTest* UnitTest::GetInstance() { - // CodeGear C++Builder insists on a public destructor for the - // default implementation. Use this implementation to keep good OO - // design with private destructor. - -#if defined(__BORLANDC__) - static UnitTest* const instance = new UnitTest; - return instance; -#else - static UnitTest instance; - return &instance; -#endif // defined(__BORLANDC__) -} - -// Gets the number of successful test suites. -int UnitTest::successful_test_suite_count() const { - return impl()->successful_test_suite_count(); -} - -// Gets the number of failed test suites. -int UnitTest::failed_test_suite_count() const { - return impl()->failed_test_suite_count(); -} - -// Gets the number of all test suites. -int UnitTest::total_test_suite_count() const { - return impl()->total_test_suite_count(); -} - -// Gets the number of all test suites that contain at least one test -// that should run. -int UnitTest::test_suite_to_run_count() const { - return impl()->test_suite_to_run_count(); -} - -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -int UnitTest::successful_test_case_count() const { - return impl()->successful_test_suite_count(); -} -int UnitTest::failed_test_case_count() const { - return impl()->failed_test_suite_count(); -} -int UnitTest::total_test_case_count() const { - return impl()->total_test_suite_count(); -} -int UnitTest::test_case_to_run_count() const { - return impl()->test_suite_to_run_count(); -} -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - -// Gets the number of successful tests. -int UnitTest::successful_test_count() const { - return impl()->successful_test_count(); -} - -// Gets the number of skipped tests. -int UnitTest::skipped_test_count() const { - return impl()->skipped_test_count(); -} - -// Gets the number of failed tests. -int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } - -// Gets the number of disabled tests that will be reported in the XML report. -int UnitTest::reportable_disabled_test_count() const { - return impl()->reportable_disabled_test_count(); -} - -// Gets the number of disabled tests. -int UnitTest::disabled_test_count() const { - return impl()->disabled_test_count(); -} - -// Gets the number of tests to be printed in the XML report. -int UnitTest::reportable_test_count() const { - return impl()->reportable_test_count(); -} - -// Gets the number of all tests. -int UnitTest::total_test_count() const { return impl()->total_test_count(); } - -// Gets the number of tests that should run. -int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } - -// Gets the time of the test program start, in ms from the start of the -// UNIX epoch. -internal::TimeInMillis UnitTest::start_timestamp() const { - return impl()->start_timestamp(); -} - -// Gets the elapsed time, in milliseconds. -internal::TimeInMillis UnitTest::elapsed_time() const { - return impl()->elapsed_time(); -} - -// Returns true if and only if the unit test passed (i.e. all test suites -// passed). -bool UnitTest::Passed() const { return impl()->Passed(); } - -// Returns true if and only if the unit test failed (i.e. some test suite -// failed or something outside of all tests failed). -bool UnitTest::Failed() const { return impl()->Failed(); } - -// Gets the i-th test suite among all the test suites. i can range from 0 to -// total_test_suite_count() - 1. If i is not in that range, returns NULL. -const TestSuite* UnitTest::GetTestSuite(int i) const { - return impl()->GetTestSuite(i); -} - -// Legacy API is deprecated but still available -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -const TestCase* UnitTest::GetTestCase(int i) const { - return impl()->GetTestCase(i); -} -#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - -// Returns the TestResult containing information on test failures and -// properties logged outside of individual test suites. -const TestResult& UnitTest::ad_hoc_test_result() const { - return *impl()->ad_hoc_test_result(); -} - -// Gets the i-th test suite among all the test suites. i can range from 0 to -// total_test_suite_count() - 1. If i is not in that range, returns NULL. -TestSuite* UnitTest::GetMutableTestSuite(int i) { - return impl()->GetMutableSuiteCase(i); -} - -// Returns the list of event listeners that can be used to track events -// inside Google Test. -TestEventListeners& UnitTest::listeners() { return *impl()->listeners(); } - -// Registers and returns a global test environment. When a test -// program is run, all global test environments will be set-up in the -// order they were registered. After all tests in the program have -// finished, all global test environments will be torn-down in the -// *reverse* order they were registered. -// -// The UnitTest object takes ownership of the given environment. -// -// We don't protect this under mutex_, as we only support calling it -// from the main thread. -Environment* UnitTest::AddEnvironment(Environment* env) { - if (env == nullptr) { - return nullptr; - } - - impl_->environments().push_back(env); - return env; -} - -// Adds a TestPartResult to the current TestResult object. All Google Test -// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call -// this to report their results. The user code should use the -// assertion macros instead of calling this directly. -void UnitTest::AddTestPartResult(TestPartResult::Type result_type, - const char* file_name, int line_number, - const std::string& message, - const std::string& os_stack_trace) - GTEST_LOCK_EXCLUDED_(mutex_) { - Message msg; - msg << message; - - internal::MutexLock lock(&mutex_); - if (impl_->gtest_trace_stack().size() > 0) { - msg << "\n" << GTEST_NAME_ << " trace:"; - - for (size_t i = impl_->gtest_trace_stack().size(); i > 0; --i) { - const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; - msg << "\n" - << internal::FormatFileLocation(trace.file, trace.line) << " " - << trace.message; - } - } - - if (os_stack_trace.c_str() != nullptr && !os_stack_trace.empty()) { - msg << internal::kStackTraceMarker << os_stack_trace; - } - - const TestPartResult result = TestPartResult( - result_type, file_name, line_number, msg.GetString().c_str()); - impl_->GetTestPartResultReporterForCurrentThread()->ReportTestPartResult( - result); - - if (result_type != TestPartResult::kSuccess && - result_type != TestPartResult::kSkip) { - // gtest_break_on_failure takes precedence over - // gtest_throw_on_failure. This allows a user to set the latter - // in the code (perhaps in order to use Google Test assertions - // with another testing framework) and specify the former on the - // command line for debugging. - if (GTEST_FLAG_GET(break_on_failure)) { -#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT - // Using DebugBreak on Windows allows gtest to still break into a debugger - // when a failure happens and both the --gtest_break_on_failure and - // the --gtest_catch_exceptions flags are specified. - DebugBreak(); -#elif (!defined(__native_client__)) && \ - ((defined(__clang__) || defined(__GNUC__)) && \ - (defined(__x86_64__) || defined(__i386__))) - // with clang/gcc we can achieve the same effect on x86 by invoking int3 - asm("int3"); -#else - // Dereference nullptr through a volatile pointer to prevent the compiler - // from removing. We use this rather than abort() or __builtin_trap() for - // portability: some debuggers don't correctly trap abort(). - *static_cast(nullptr) = 1; -#endif // GTEST_OS_WINDOWS - } else if (GTEST_FLAG_GET(throw_on_failure)) { -#if GTEST_HAS_EXCEPTIONS - throw internal::GoogleTestFailureException(result); -#else - // We cannot call abort() as it generates a pop-up in debug mode - // that cannot be suppressed in VC 7.1 or below. - exit(1); -#endif - } - } -} - -// Adds a TestProperty to the current TestResult object when invoked from -// inside a test, to current TestSuite's ad_hoc_test_result_ when invoked -// from SetUpTestSuite or TearDownTestSuite, or to the global property set -// when invoked elsewhere. If the result already contains a property with -// the same key, the value will be updated. -void UnitTest::RecordProperty(const std::string& key, - const std::string& value) { - impl_->RecordProperty(TestProperty(key, value)); -} - -// Runs all tests in this UnitTest object and prints the result. -// Returns 0 if successful, or 1 otherwise. -// -// We don't protect this under mutex_, as we only support calling it -// from the main thread. -int UnitTest::Run() { - const bool in_death_test_child_process = - GTEST_FLAG_GET(internal_run_death_test).length() > 0; - - // Google Test implements this protocol for catching that a test - // program exits before returning control to Google Test: - // - // 1. Upon start, Google Test creates a file whose absolute path - // is specified by the environment variable - // TEST_PREMATURE_EXIT_FILE. - // 2. When Google Test has finished its work, it deletes the file. - // - // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before - // running a Google-Test-based test program and check the existence - // of the file at the end of the test execution to see if it has - // exited prematurely. - - // If we are in the child process of a death test, don't - // create/delete the premature exit file, as doing so is unnecessary - // and will confuse the parent process. Otherwise, create/delete - // the file upon entering/leaving this function. If the program - // somehow exits before this function has a chance to return, the - // premature-exit file will be left undeleted, causing a test runner - // that understands the premature-exit-file protocol to report the - // test as having failed. - const internal::ScopedPrematureExitFile premature_exit_file( - in_death_test_child_process - ? nullptr - : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE")); - - // Captures the value of GTEST_FLAG(catch_exceptions). This value will be - // used for the duration of the program. - impl()->set_catch_exceptions(GTEST_FLAG_GET(catch_exceptions)); - -#if GTEST_OS_WINDOWS - // Either the user wants Google Test to catch exceptions thrown by the - // tests or this is executing in the context of death test child - // process. In either case the user does not want to see pop-up dialogs - // about crashes - they are expected. - if (impl()->catch_exceptions() || in_death_test_child_process) { -#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT - // SetErrorMode doesn't exist on CE. - SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | - SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); -#endif // !GTEST_OS_WINDOWS_MOBILE - -#if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE - // Death test children can be terminated with _abort(). On Windows, - // _abort() can show a dialog with a warning message. This forces the - // abort message to go to stderr instead. - _set_error_mode(_OUT_TO_STDERR); -#endif - -#if defined(_MSC_VER) && !GTEST_OS_WINDOWS_MOBILE - // In the debug version, Visual Studio pops up a separate dialog - // offering a choice to debug the aborted program. We need to suppress - // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement - // executed. Google Test will notify the user of any unexpected - // failure via stderr. - if (!GTEST_FLAG_GET(break_on_failure)) - _set_abort_behavior( - 0x0, // Clear the following flags: - _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. - - // In debug mode, the Windows CRT can crash with an assertion over invalid - // input (e.g. passing an invalid file descriptor). The default handling - // for these assertions is to pop up a dialog and wait for user input. - // Instead ask the CRT to dump such assertions to stderr non-interactively. - if (!IsDebuggerPresent()) { - (void)_CrtSetReportMode(_CRT_ASSERT, - _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); - (void)_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); - } -#endif - } -#endif // GTEST_OS_WINDOWS - - return internal::HandleExceptionsInMethodIfSupported( - impl(), &internal::UnitTestImpl::RunAllTests, - "auxiliary test code (environments or event listeners)") - ? 0 - : 1; -} - -// Returns the working directory when the first TEST() or TEST_F() was -// executed. -const char* UnitTest::original_working_dir() const { - return impl_->original_working_dir_.c_str(); -} - -// Returns the TestSuite object for the test that's currently running, -// or NULL if no test is running. -const TestSuite* UnitTest::current_test_suite() const - GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); - return impl_->current_test_suite(); -} - -// Legacy API is still available but deprecated -#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -const TestCase* UnitTest::current_test_case() const - GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); - return impl_->current_test_suite(); -} -#endif - -// Returns the TestInfo object for the test that's currently running, -// or NULL if no test is running. -const TestInfo* UnitTest::current_test_info() const - GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); - return impl_->current_test_info(); -} - -// Returns the random seed used at the start of the current test run. -int UnitTest::random_seed() const { return impl_->random_seed(); } - -// Returns ParameterizedTestSuiteRegistry object used to keep track of -// value-parameterized tests and instantiate and register them. -internal::ParameterizedTestSuiteRegistry& -UnitTest::parameterized_test_registry() GTEST_LOCK_EXCLUDED_(mutex_) { - return impl_->parameterized_test_registry(); -} - -// Creates an empty UnitTest. -UnitTest::UnitTest() { impl_ = new internal::UnitTestImpl(this); } - -// Destructor of UnitTest. -UnitTest::~UnitTest() { delete impl_; } - -// Pushes a trace defined by SCOPED_TRACE() on to the per-thread -// Google Test trace stack. -void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) - GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); - impl_->gtest_trace_stack().push_back(trace); -} - -// Pops a trace from the per-thread Google Test trace stack. -void UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); - impl_->gtest_trace_stack().pop_back(); -} - -namespace internal { - -UnitTestImpl::UnitTestImpl(UnitTest* parent) - : parent_(parent), - GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355 /* using this in initializer */) - default_global_test_part_result_reporter_(this), - default_per_thread_test_part_result_reporter_(this), - GTEST_DISABLE_MSC_WARNINGS_POP_() global_test_part_result_repoter_( - &default_global_test_part_result_reporter_), - per_thread_test_part_result_reporter_( - &default_per_thread_test_part_result_reporter_), - parameterized_test_registry_(), - parameterized_tests_registered_(false), - last_death_test_suite_(-1), - current_test_suite_(nullptr), - current_test_info_(nullptr), - ad_hoc_test_result_(), - os_stack_trace_getter_(nullptr), - post_flag_parse_init_performed_(false), - random_seed_(0), // Will be overridden by the flag before first use. - random_(0), // Will be reseeded before first use. - start_timestamp_(0), - elapsed_time_(0), -#if GTEST_HAS_DEATH_TEST - death_test_factory_(new DefaultDeathTestFactory), -#endif - // Will be overridden by the flag before first use. - catch_exceptions_(false) { - listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); -} - -UnitTestImpl::~UnitTestImpl() { - // Deletes every TestSuite. - ForEach(test_suites_, internal::Delete); - - // Deletes every Environment. - ForEach(environments_, internal::Delete); - - delete os_stack_trace_getter_; -} - -// Adds a TestProperty to the current TestResult object when invoked in a -// context of a test, to current test suite's ad_hoc_test_result when invoke -// from SetUpTestSuite/TearDownTestSuite, or to the global property set -// otherwise. If the result already contains a property with the same key, -// the value will be updated. -void UnitTestImpl::RecordProperty(const TestProperty& test_property) { - std::string xml_element; - TestResult* test_result; // TestResult appropriate for property recording. - - if (current_test_info_ != nullptr) { - xml_element = "testcase"; - test_result = &(current_test_info_->result_); - } else if (current_test_suite_ != nullptr) { - xml_element = "testsuite"; - test_result = &(current_test_suite_->ad_hoc_test_result_); - } else { - xml_element = "testsuites"; - test_result = &ad_hoc_test_result_; - } - test_result->RecordProperty(xml_element, test_property); -} - -#if GTEST_HAS_DEATH_TEST -// Disables event forwarding if the control is currently in a death test -// subprocess. Must not be called before InitGoogleTest. -void UnitTestImpl::SuppressTestEventsIfInSubprocess() { - if (internal_run_death_test_flag_.get() != nullptr) - listeners()->SuppressEventForwarding(); -} -#endif // GTEST_HAS_DEATH_TEST - -// Initializes event listeners performing XML output as specified by -// UnitTestOptions. Must not be called before InitGoogleTest. -void UnitTestImpl::ConfigureXmlOutput() { - const std::string& output_format = UnitTestOptions::GetOutputFormat(); - if (output_format == "xml") { - listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( - UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); - } else if (output_format == "json") { - listeners()->SetDefaultXmlGenerator(new JsonUnitTestResultPrinter( - UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); - } else if (output_format != "") { - GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \"" - << output_format << "\" ignored."; - } -} - -#if GTEST_CAN_STREAM_RESULTS_ -// Initializes event listeners for streaming test results in string form. -// Must not be called before InitGoogleTest. -void UnitTestImpl::ConfigureStreamingOutput() { - const std::string& target = GTEST_FLAG_GET(stream_result_to); - if (!target.empty()) { - const size_t pos = target.find(':'); - if (pos != std::string::npos) { - listeners()->Append( - new StreamingListener(target.substr(0, pos), target.substr(pos + 1))); - } else { - GTEST_LOG_(WARNING) << "unrecognized streaming target \"" << target - << "\" ignored."; - } - } -} -#endif // GTEST_CAN_STREAM_RESULTS_ - -// Performs initialization dependent upon flag values obtained in -// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to -// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest -// this function is also called from RunAllTests. Since this function can be -// called more than once, it has to be idempotent. -void UnitTestImpl::PostFlagParsingInit() { - // Ensures that this function does not execute more than once. - if (!post_flag_parse_init_performed_) { - post_flag_parse_init_performed_ = true; - -#if defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_) - // Register to send notifications about key process state changes. - listeners()->Append(new GTEST_CUSTOM_TEST_EVENT_LISTENER_()); -#endif // defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_) - -#if GTEST_HAS_DEATH_TEST - InitDeathTestSubprocessControlInfo(); - SuppressTestEventsIfInSubprocess(); -#endif // GTEST_HAS_DEATH_TEST - - // Registers parameterized tests. This makes parameterized tests - // available to the UnitTest reflection API without running - // RUN_ALL_TESTS. - RegisterParameterizedTests(); - - // Configures listeners for XML output. This makes it possible for users - // to shut down the default XML output before invoking RUN_ALL_TESTS. - ConfigureXmlOutput(); - - if (GTEST_FLAG_GET(brief)) { - listeners()->SetDefaultResultPrinter(new BriefUnitTestResultPrinter); - } - -#if GTEST_CAN_STREAM_RESULTS_ - // Configures listeners for streaming test results to the specified server. - ConfigureStreamingOutput(); -#endif // GTEST_CAN_STREAM_RESULTS_ - -#if GTEST_HAS_ABSL - if (GTEST_FLAG_GET(install_failure_signal_handler)) { - absl::FailureSignalHandlerOptions options; - absl::InstallFailureSignalHandler(options); - } -#endif // GTEST_HAS_ABSL - } -} - -// A predicate that checks the name of a TestSuite against a known -// value. -// -// This is used for implementation of the UnitTest class only. We put -// it in the anonymous namespace to prevent polluting the outer -// namespace. -// -// TestSuiteNameIs is copyable. -class TestSuiteNameIs { - public: - // Constructor. - explicit TestSuiteNameIs(const std::string& name) : name_(name) {} - - // Returns true if and only if the name of test_suite matches name_. - bool operator()(const TestSuite* test_suite) const { - return test_suite != nullptr && - strcmp(test_suite->name(), name_.c_str()) == 0; - } - - private: - std::string name_; -}; - -// Finds and returns a TestSuite with the given name. If one doesn't -// exist, creates one and returns it. It's the CALLER'S -// RESPONSIBILITY to ensure that this function is only called WHEN THE -// TESTS ARE NOT SHUFFLED. -// -// Arguments: -// -// test_suite_name: name of the test suite -// type_param: the name of the test suite's type parameter, or NULL if -// this is not a typed or a type-parameterized test suite. -// set_up_tc: pointer to the function that sets up the test suite -// tear_down_tc: pointer to the function that tears down the test suite -TestSuite* UnitTestImpl::GetTestSuite( - const char* test_suite_name, const char* type_param, - internal::SetUpTestSuiteFunc set_up_tc, - internal::TearDownTestSuiteFunc tear_down_tc) { - // Can we find a TestSuite with the given name? - const auto test_suite = - std::find_if(test_suites_.rbegin(), test_suites_.rend(), - TestSuiteNameIs(test_suite_name)); - - if (test_suite != test_suites_.rend()) return *test_suite; - - // No. Let's create one. - auto* const new_test_suite = - new TestSuite(test_suite_name, type_param, set_up_tc, tear_down_tc); - - const UnitTestFilter death_test_suite_filter(kDeathTestSuiteFilter); - // Is this a death test suite? - if (death_test_suite_filter.MatchesName(test_suite_name)) { - // Yes. Inserts the test suite after the last death test suite - // defined so far. This only works when the test suites haven't - // been shuffled. Otherwise we may end up running a death test - // after a non-death test. - ++last_death_test_suite_; - test_suites_.insert(test_suites_.begin() + last_death_test_suite_, - new_test_suite); - } else { - // No. Appends to the end of the list. - test_suites_.push_back(new_test_suite); - } - - test_suite_indices_.push_back(static_cast(test_suite_indices_.size())); - return new_test_suite; -} - -// Helpers for setting up / tearing down the given environment. They -// are for use in the ForEach() function. -static void SetUpEnvironment(Environment* env) { env->SetUp(); } -static void TearDownEnvironment(Environment* env) { env->TearDown(); } - -// Runs all tests in this UnitTest object, prints the result, and -// returns true if all tests are successful. If any exception is -// thrown during a test, the test is considered to be failed, but the -// rest of the tests will still be run. -// -// When parameterized tests are enabled, it expands and registers -// parameterized tests first in RegisterParameterizedTests(). -// All other functions called from RunAllTests() may safely assume that -// parameterized tests are ready to be counted and run. -bool UnitTestImpl::RunAllTests() { - // True if and only if Google Test is initialized before RUN_ALL_TESTS() is - // called. - const bool gtest_is_initialized_before_run_all_tests = GTestIsInitialized(); - - // Do not run any test if the --help flag was specified. - if (g_help_flag) return true; - - // Repeats the call to the post-flag parsing initialization in case the - // user didn't call InitGoogleTest. - PostFlagParsingInit(); - - // Even if sharding is not on, test runners may want to use the - // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding - // protocol. - internal::WriteToShardStatusFileIfNeeded(); - - // True if and only if we are in a subprocess for running a thread-safe-style - // death test. - bool in_subprocess_for_death_test = false; - -#if GTEST_HAS_DEATH_TEST - in_subprocess_for_death_test = - (internal_run_death_test_flag_.get() != nullptr); -#if defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_) - if (in_subprocess_for_death_test) { - GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_(); - } -#endif // defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_) -#endif // GTEST_HAS_DEATH_TEST - - const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, - in_subprocess_for_death_test); - - // Compares the full test names with the filter to decide which - // tests to run. - const bool has_tests_to_run = - FilterTests(should_shard ? HONOR_SHARDING_PROTOCOL - : IGNORE_SHARDING_PROTOCOL) > 0; - - // Lists the tests and exits if the --gtest_list_tests flag was specified. - if (GTEST_FLAG_GET(list_tests)) { - // This must be called *after* FilterTests() has been called. - ListTestsMatchingFilter(); - return true; - } - - random_seed_ = GetRandomSeedFromFlag(GTEST_FLAG_GET(random_seed)); - - // True if and only if at least one test has failed. - bool failed = false; - - TestEventListener* repeater = listeners()->repeater(); - - start_timestamp_ = GetTimeInMillis(); - repeater->OnTestProgramStart(*parent_); - - // How many times to repeat the tests? We don't want to repeat them - // when we are inside the subprocess of a death test. - const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG_GET(repeat); - - // Repeats forever if the repeat count is negative. - const bool gtest_repeat_forever = repeat < 0; - - // Should test environments be set up and torn down for each repeat, or only - // set up on the first and torn down on the last iteration? If there is no - // "last" iteration because the tests will repeat forever, always recreate the - // environments to avoid leaks in case one of the environments is using - // resources that are external to this process. Without this check there would - // be no way to clean up those external resources automatically. - const bool recreate_environments_when_repeating = - GTEST_FLAG_GET(recreate_environments_when_repeating) || - gtest_repeat_forever; - - for (int i = 0; gtest_repeat_forever || i != repeat; i++) { - // We want to preserve failures generated by ad-hoc test - // assertions executed before RUN_ALL_TESTS(). - ClearNonAdHocTestResult(); - - Timer timer; - - // Shuffles test suites and tests if requested. - if (has_tests_to_run && GTEST_FLAG_GET(shuffle)) { - random()->Reseed(static_cast(random_seed_)); - // This should be done before calling OnTestIterationStart(), - // such that a test event listener can see the actual test order - // in the event. - ShuffleTests(); - } - - // Tells the unit test event listeners that the tests are about to start. - repeater->OnTestIterationStart(*parent_, i); - - // Runs each test suite if there is at least one test to run. - if (has_tests_to_run) { - // Sets up all environments beforehand. If test environments aren't - // recreated for each iteration, only do so on the first iteration. - if (i == 0 || recreate_environments_when_repeating) { - repeater->OnEnvironmentsSetUpStart(*parent_); - ForEach(environments_, SetUpEnvironment); - repeater->OnEnvironmentsSetUpEnd(*parent_); - } - - // Runs the tests only if there was no fatal failure or skip triggered - // during global set-up. - if (Test::IsSkipped()) { - // Emit diagnostics when global set-up calls skip, as it will not be - // emitted by default. - TestResult& test_result = - *internal::GetUnitTestImpl()->current_test_result(); - for (int j = 0; j < test_result.total_part_count(); ++j) { - const TestPartResult& test_part_result = - test_result.GetTestPartResult(j); - if (test_part_result.type() == TestPartResult::kSkip) { - const std::string& result = test_part_result.message(); - printf("%s\n", result.c_str()); - } - } - fflush(stdout); - } else if (!Test::HasFatalFailure()) { - for (int test_index = 0; test_index < total_test_suite_count(); - test_index++) { - GetMutableSuiteCase(test_index)->Run(); - if (GTEST_FLAG_GET(fail_fast) && - GetMutableSuiteCase(test_index)->Failed()) { - for (int j = test_index + 1; j < total_test_suite_count(); j++) { - GetMutableSuiteCase(j)->Skip(); - } - break; - } - } - } else if (Test::HasFatalFailure()) { - // If there was a fatal failure during the global setup then we know we - // aren't going to run any tests. Explicitly mark all of the tests as - // skipped to make this obvious in the output. - for (int test_index = 0; test_index < total_test_suite_count(); - test_index++) { - GetMutableSuiteCase(test_index)->Skip(); - } - } - - // Tears down all environments in reverse order afterwards. If test - // environments aren't recreated for each iteration, only do so on the - // last iteration. - if (i == repeat - 1 || recreate_environments_when_repeating) { - repeater->OnEnvironmentsTearDownStart(*parent_); - std::for_each(environments_.rbegin(), environments_.rend(), - TearDownEnvironment); - repeater->OnEnvironmentsTearDownEnd(*parent_); - } - } - - elapsed_time_ = timer.Elapsed(); - - // Tells the unit test event listener that the tests have just finished. - repeater->OnTestIterationEnd(*parent_, i); - - // Gets the result and clears it. - if (!Passed()) { - failed = true; - } - - // Restores the original test order after the iteration. This - // allows the user to quickly repro a failure that happens in the - // N-th iteration without repeating the first (N - 1) iterations. - // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in - // case the user somehow changes the value of the flag somewhere - // (it's always safe to unshuffle the tests). - UnshuffleTests(); - - if (GTEST_FLAG_GET(shuffle)) { - // Picks a new random seed for each iteration. - random_seed_ = GetNextRandomSeed(random_seed_); - } - } - - repeater->OnTestProgramEnd(*parent_); - - if (!gtest_is_initialized_before_run_all_tests) { - ColoredPrintf( - GTestColor::kRed, - "\nIMPORTANT NOTICE - DO NOT IGNORE:\n" - "This test program did NOT call " GTEST_INIT_GOOGLE_TEST_NAME_ - "() before calling RUN_ALL_TESTS(). This is INVALID. Soon " GTEST_NAME_ - " will start to enforce the valid usage. " - "Please fix it ASAP, or IT WILL START TO FAIL.\n"); // NOLINT -#if GTEST_FOR_GOOGLE_ - ColoredPrintf(GTestColor::kRed, - "For more details, see http://wiki/Main/ValidGUnitMain.\n"); -#endif // GTEST_FOR_GOOGLE_ - } - - return !failed; -} - -// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file -// if the variable is present. If a file already exists at this location, this -// function will write over it. If the variable is present, but the file cannot -// be created, prints an error and exits. -void WriteToShardStatusFileIfNeeded() { - const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); - if (test_shard_file != nullptr) { - FILE* const file = posix::FOpen(test_shard_file, "w"); - if (file == nullptr) { - ColoredPrintf(GTestColor::kRed, - "Could not write to the test shard status file \"%s\" " - "specified by the %s environment variable.\n", - test_shard_file, kTestShardStatusFile); - fflush(stdout); - exit(EXIT_FAILURE); - } - fclose(file); - } -} - -// Checks whether sharding is enabled by examining the relevant -// environment variable values. If the variables are present, -// but inconsistent (i.e., shard_index >= total_shards), prints -// an error and exits. If in_subprocess_for_death_test, sharding is -// disabled because it must only be applied to the original test -// process. Otherwise, we could filter out death tests we intended to execute. -bool ShouldShard(const char* total_shards_env, const char* shard_index_env, - bool in_subprocess_for_death_test) { - if (in_subprocess_for_death_test) { - return false; - } - - const int32_t total_shards = Int32FromEnvOrDie(total_shards_env, -1); - const int32_t shard_index = Int32FromEnvOrDie(shard_index_env, -1); - - if (total_shards == -1 && shard_index == -1) { - return false; - } else if (total_shards == -1 && shard_index != -1) { - const Message msg = Message() << "Invalid environment variables: you have " - << kTestShardIndex << " = " << shard_index - << ", but have left " << kTestTotalShards - << " unset.\n"; - ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); - fflush(stdout); - exit(EXIT_FAILURE); - } else if (total_shards != -1 && shard_index == -1) { - const Message msg = Message() - << "Invalid environment variables: you have " - << kTestTotalShards << " = " << total_shards - << ", but have left " << kTestShardIndex << " unset.\n"; - ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); - fflush(stdout); - exit(EXIT_FAILURE); - } else if (shard_index < 0 || shard_index >= total_shards) { - const Message msg = - Message() << "Invalid environment variables: we require 0 <= " - << kTestShardIndex << " < " << kTestTotalShards - << ", but you have " << kTestShardIndex << "=" << shard_index - << ", " << kTestTotalShards << "=" << total_shards << ".\n"; - ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); - fflush(stdout); - exit(EXIT_FAILURE); - } - - return total_shards > 1; -} - -// Parses the environment variable var as an Int32. If it is unset, -// returns default_val. If it is not an Int32, prints an error -// and aborts. -int32_t Int32FromEnvOrDie(const char* var, int32_t default_val) { - const char* str_val = posix::GetEnv(var); - if (str_val == nullptr) { - return default_val; - } - - int32_t result; - if (!ParseInt32(Message() << "The value of environment variable " << var, - str_val, &result)) { - exit(EXIT_FAILURE); - } - return result; -} - -// Given the total number of shards, the shard index, and the test id, -// returns true if and only if the test should be run on this shard. The test id -// is some arbitrary but unique non-negative integer assigned to each test -// method. Assumes that 0 <= shard_index < total_shards. -bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { - return (test_id % total_shards) == shard_index; -} - -// Compares the name of each test with the user-specified filter to -// decide whether the test should be run, then records the result in -// each TestSuite and TestInfo object. -// If shard_tests == true, further filters tests based on sharding -// variables in the environment - see -// https://github.com/google/googletest/blob/master/googletest/docs/advanced.md -// . Returns the number of tests that should run. -int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { - const int32_t total_shards = shard_tests == HONOR_SHARDING_PROTOCOL - ? Int32FromEnvOrDie(kTestTotalShards, -1) - : -1; - const int32_t shard_index = shard_tests == HONOR_SHARDING_PROTOCOL - ? Int32FromEnvOrDie(kTestShardIndex, -1) - : -1; - - const PositiveAndNegativeUnitTestFilter gtest_flag_filter( - GTEST_FLAG_GET(filter)); - const UnitTestFilter disable_test_filter(kDisableTestFilter); - // num_runnable_tests are the number of tests that will - // run across all shards (i.e., match filter and are not disabled). - // num_selected_tests are the number of tests to be run on - // this shard. - int num_runnable_tests = 0; - int num_selected_tests = 0; - for (auto* test_suite : test_suites_) { - const std::string& test_suite_name = test_suite->name(); - test_suite->set_should_run(false); - - for (size_t j = 0; j < test_suite->test_info_list().size(); j++) { - TestInfo* const test_info = test_suite->test_info_list()[j]; - const std::string test_name(test_info->name()); - // A test is disabled if test suite name or test name matches - // kDisableTestFilter. - const bool is_disabled = - disable_test_filter.MatchesName(test_suite_name) || - disable_test_filter.MatchesName(test_name); - test_info->is_disabled_ = is_disabled; - - const bool matches_filter = - gtest_flag_filter.MatchesTest(test_suite_name, test_name); - test_info->matches_filter_ = matches_filter; - - const bool is_runnable = - (GTEST_FLAG_GET(also_run_disabled_tests) || !is_disabled) && - matches_filter; - - const bool is_in_another_shard = - shard_tests != IGNORE_SHARDING_PROTOCOL && - !ShouldRunTestOnShard(total_shards, shard_index, num_runnable_tests); - test_info->is_in_another_shard_ = is_in_another_shard; - const bool is_selected = is_runnable && !is_in_another_shard; - - num_runnable_tests += is_runnable; - num_selected_tests += is_selected; - - test_info->should_run_ = is_selected; - test_suite->set_should_run(test_suite->should_run() || is_selected); - } - } - return num_selected_tests; -} - -// Prints the given C-string on a single line by replacing all '\n' -// characters with string "\\n". If the output takes more than -// max_length characters, only prints the first max_length characters -// and "...". -static void PrintOnOneLine(const char* str, int max_length) { - if (str != nullptr) { - for (int i = 0; *str != '\0'; ++str) { - if (i >= max_length) { - printf("..."); - break; - } - if (*str == '\n') { - printf("\\n"); - i += 2; - } else { - printf("%c", *str); - ++i; - } - } - } -} - -// Prints the names of the tests matching the user-specified filter flag. -void UnitTestImpl::ListTestsMatchingFilter() { - // Print at most this many characters for each type/value parameter. - const int kMaxParamLength = 250; - - for (auto* test_suite : test_suites_) { - bool printed_test_suite_name = false; - - for (size_t j = 0; j < test_suite->test_info_list().size(); j++) { - const TestInfo* const test_info = test_suite->test_info_list()[j]; - if (test_info->matches_filter_) { - if (!printed_test_suite_name) { - printed_test_suite_name = true; - printf("%s.", test_suite->name()); - if (test_suite->type_param() != nullptr) { - printf(" # %s = ", kTypeParamLabel); - // We print the type parameter on a single line to make - // the output easy to parse by a program. - PrintOnOneLine(test_suite->type_param(), kMaxParamLength); - } - printf("\n"); - } - printf(" %s", test_info->name()); - if (test_info->value_param() != nullptr) { - printf(" # %s = ", kValueParamLabel); - // We print the value parameter on a single line to make the - // output easy to parse by a program. - PrintOnOneLine(test_info->value_param(), kMaxParamLength); - } - printf("\n"); - } - } - } - fflush(stdout); - const std::string& output_format = UnitTestOptions::GetOutputFormat(); - if (output_format == "xml" || output_format == "json") { - FILE* fileout = OpenFileForWriting( - UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); - std::stringstream stream; - if (output_format == "xml") { - XmlUnitTestResultPrinter( - UnitTestOptions::GetAbsolutePathToOutputFile().c_str()) - .PrintXmlTestsList(&stream, test_suites_); - } else if (output_format == "json") { - JsonUnitTestResultPrinter( - UnitTestOptions::GetAbsolutePathToOutputFile().c_str()) - .PrintJsonTestList(&stream, test_suites_); - } - fprintf(fileout, "%s", StringStreamToString(&stream).c_str()); - fclose(fileout); - } -} - -// Sets the OS stack trace getter. -// -// Does nothing if the input and the current OS stack trace getter are -// the same; otherwise, deletes the old getter and makes the input the -// current getter. -void UnitTestImpl::set_os_stack_trace_getter( - OsStackTraceGetterInterface* getter) { - if (os_stack_trace_getter_ != getter) { - delete os_stack_trace_getter_; - os_stack_trace_getter_ = getter; - } -} - -// Returns the current OS stack trace getter if it is not NULL; -// otherwise, creates an OsStackTraceGetter, makes it the current -// getter, and returns it. -OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { - if (os_stack_trace_getter_ == nullptr) { -#ifdef GTEST_OS_STACK_TRACE_GETTER_ - os_stack_trace_getter_ = new GTEST_OS_STACK_TRACE_GETTER_; -#else - os_stack_trace_getter_ = new OsStackTraceGetter; -#endif // GTEST_OS_STACK_TRACE_GETTER_ - } - - return os_stack_trace_getter_; -} - -// Returns the most specific TestResult currently running. -TestResult* UnitTestImpl::current_test_result() { - if (current_test_info_ != nullptr) { - return ¤t_test_info_->result_; - } - if (current_test_suite_ != nullptr) { - return ¤t_test_suite_->ad_hoc_test_result_; - } - return &ad_hoc_test_result_; -} - -// Shuffles all test suites, and the tests within each test suite, -// making sure that death tests are still run first. -void UnitTestImpl::ShuffleTests() { - // Shuffles the death test suites. - ShuffleRange(random(), 0, last_death_test_suite_ + 1, &test_suite_indices_); - - // Shuffles the non-death test suites. - ShuffleRange(random(), last_death_test_suite_ + 1, - static_cast(test_suites_.size()), &test_suite_indices_); - - // Shuffles the tests inside each test suite. - for (auto& test_suite : test_suites_) { - test_suite->ShuffleTests(random()); - } -} - -// Restores the test suites and tests to their order before the first shuffle. -void UnitTestImpl::UnshuffleTests() { - for (size_t i = 0; i < test_suites_.size(); i++) { - // Unshuffles the tests in each test suite. - test_suites_[i]->UnshuffleTests(); - // Resets the index of each test suite. - test_suite_indices_[i] = static_cast(i); - } -} - -// Returns the current OS stack trace as an std::string. -// -// The maximum number of stack frames to be included is specified by -// the gtest_stack_trace_depth flag. The skip_count parameter -// specifies the number of top frames to be skipped, which doesn't -// count against the number of frames to be included. -// -// For example, if Foo() calls Bar(), which in turn calls -// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in -// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. -GTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_ std::string -GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, int skip_count) { - // We pass skip_count + 1 to skip this wrapper function in addition - // to what the user really wants to skip. - return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); -} - -// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to -// suppress unreachable code warnings. -namespace { -class ClassUniqueToAlwaysTrue {}; -} // namespace - -bool IsTrue(bool condition) { return condition; } - -bool AlwaysTrue() { -#if GTEST_HAS_EXCEPTIONS - // This condition is always false so AlwaysTrue() never actually throws, - // but it makes the compiler think that it may throw. - if (IsTrue(false)) throw ClassUniqueToAlwaysTrue(); -#endif // GTEST_HAS_EXCEPTIONS - return true; -} - -// If *pstr starts with the given prefix, modifies *pstr to be right -// past the prefix and returns true; otherwise leaves *pstr unchanged -// and returns false. None of pstr, *pstr, and prefix can be NULL. -bool SkipPrefix(const char* prefix, const char** pstr) { - const size_t prefix_len = strlen(prefix); - if (strncmp(*pstr, prefix, prefix_len) == 0) { - *pstr += prefix_len; - return true; - } - return false; -} - -// Parses a string as a command line flag. The string should have -// the format "--flag=value". When def_optional is true, the "=value" -// part can be omitted. -// -// Returns the value of the flag, or NULL if the parsing failed. -static const char* ParseFlagValue(const char* str, const char* flag_name, - bool def_optional) { - // str and flag must not be NULL. - if (str == nullptr || flag_name == nullptr) return nullptr; - - // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. - const std::string flag_str = - std::string("--") + GTEST_FLAG_PREFIX_ + flag_name; - const size_t flag_len = flag_str.length(); - if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr; - - // Skips the flag name. - const char* flag_end = str + flag_len; - - // When def_optional is true, it's OK to not have a "=value" part. - if (def_optional && (flag_end[0] == '\0')) { - return flag_end; - } - - // If def_optional is true and there are more characters after the - // flag name, or if def_optional is false, there must be a '=' after - // the flag name. - if (flag_end[0] != '=') return nullptr; - - // Returns the string after "=". - return flag_end + 1; -} - -// Parses a string for a bool flag, in the form of either -// "--flag=value" or "--flag". -// -// In the former case, the value is taken as true as long as it does -// not start with '0', 'f', or 'F'. -// -// In the latter case, the value is taken as true. -// -// On success, stores the value of the flag in *value, and returns -// true. On failure, returns false without changing *value. -static bool ParseFlag(const char* str, const char* flag_name, bool* value) { - // Gets the value of the flag as a string. - const char* const value_str = ParseFlagValue(str, flag_name, true); - - // Aborts if the parsing failed. - if (value_str == nullptr) return false; - - // Converts the string value to a bool. - *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); - return true; -} - -// Parses a string for an int32_t flag, in the form of "--flag=value". -// -// On success, stores the value of the flag in *value, and returns -// true. On failure, returns false without changing *value. -bool ParseFlag(const char* str, const char* flag_name, int32_t* value) { - // Gets the value of the flag as a string. - const char* const value_str = ParseFlagValue(str, flag_name, false); - - // Aborts if the parsing failed. - if (value_str == nullptr) return false; - - // Sets *value to the value of the flag. - return ParseInt32(Message() << "The value of flag --" << flag_name, value_str, - value); -} - -// Parses a string for a string flag, in the form of "--flag=value". -// -// On success, stores the value of the flag in *value, and returns -// true. On failure, returns false without changing *value. -template -static bool ParseFlag(const char* str, const char* flag_name, String* value) { - // Gets the value of the flag as a string. - const char* const value_str = ParseFlagValue(str, flag_name, false); - - // Aborts if the parsing failed. - if (value_str == nullptr) return false; - - // Sets *value to the value of the flag. - *value = value_str; - return true; -} - -// Determines whether a string has a prefix that Google Test uses for its -// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. -// If Google Test detects that a command line flag has its prefix but is not -// recognized, it will print its help message. Flags starting with -// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test -// internal flags and do not trigger the help message. -static bool HasGoogleTestFlagPrefix(const char* str) { - return (SkipPrefix("--", &str) || SkipPrefix("-", &str) || - SkipPrefix("/", &str)) && - !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && - (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || - SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); -} - -// Prints a string containing code-encoded text. The following escape -// sequences can be used in the string to control the text color: -// -// @@ prints a single '@' character. -// @R changes the color to red. -// @G changes the color to green. -// @Y changes the color to yellow. -// @D changes to the default terminal text color. -// -static void PrintColorEncoded(const char* str) { - GTestColor color = GTestColor::kDefault; // The current color. - - // Conceptually, we split the string into segments divided by escape - // sequences. Then we print one segment at a time. At the end of - // each iteration, the str pointer advances to the beginning of the - // next segment. - for (;;) { - const char* p = strchr(str, '@'); - if (p == nullptr) { - ColoredPrintf(color, "%s", str); - return; - } - - ColoredPrintf(color, "%s", std::string(str, p).c_str()); - - const char ch = p[1]; - str = p + 2; - if (ch == '@') { - ColoredPrintf(color, "@"); - } else if (ch == 'D') { - color = GTestColor::kDefault; - } else if (ch == 'R') { - color = GTestColor::kRed; - } else if (ch == 'G') { - color = GTestColor::kGreen; - } else if (ch == 'Y') { - color = GTestColor::kYellow; - } else { - --str; - } - } -} - -static const char kColorEncodedHelpMessage[] = - "This program contains tests written using " GTEST_NAME_ - ". You can use the\n" - "following command line flags to control its behavior:\n" - "\n" - "Test Selection:\n" - " @G--" GTEST_FLAG_PREFIX_ - "list_tests@D\n" - " List the names of all tests instead of running them. The name of\n" - " TEST(Foo, Bar) is \"Foo.Bar\".\n" - " @G--" GTEST_FLAG_PREFIX_ - "filter=@YPOSITIVE_PATTERNS" - "[@G-@YNEGATIVE_PATTERNS]@D\n" - " Run only the tests whose name matches one of the positive patterns " - "but\n" - " none of the negative patterns. '?' matches any single character; " - "'*'\n" - " matches any substring; ':' separates two patterns.\n" - " @G--" GTEST_FLAG_PREFIX_ - "also_run_disabled_tests@D\n" - " Run all disabled tests too.\n" - "\n" - "Test Execution:\n" - " @G--" GTEST_FLAG_PREFIX_ - "repeat=@Y[COUNT]@D\n" - " Run the tests repeatedly; use a negative count to repeat forever.\n" - " @G--" GTEST_FLAG_PREFIX_ - "shuffle@D\n" - " Randomize tests' orders on every iteration.\n" - " @G--" GTEST_FLAG_PREFIX_ - "random_seed=@Y[NUMBER]@D\n" - " Random number seed to use for shuffling test orders (between 1 and\n" - " 99999, or 0 to use a seed based on the current time).\n" - " @G--" GTEST_FLAG_PREFIX_ - "recreate_environments_when_repeating@D\n" - " Sets up and tears down the global test environment on each repeat\n" - " of the test.\n" - "\n" - "Test Output:\n" - " @G--" GTEST_FLAG_PREFIX_ - "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" - " Enable/disable colored output. The default is @Gauto@D.\n" - " @G--" GTEST_FLAG_PREFIX_ - "brief=1@D\n" - " Only print test failures.\n" - " @G--" GTEST_FLAG_PREFIX_ - "print_time=0@D\n" - " Don't print the elapsed time of each test.\n" - " @G--" GTEST_FLAG_PREFIX_ - "output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G" GTEST_PATH_SEP_ - "@Y|@G:@YFILE_PATH]@D\n" - " Generate a JSON or XML report in the given directory or with the " - "given\n" - " file name. @YFILE_PATH@D defaults to @Gtest_detail.xml@D.\n" -#if GTEST_CAN_STREAM_RESULTS_ - " @G--" GTEST_FLAG_PREFIX_ - "stream_result_to=@YHOST@G:@YPORT@D\n" - " Stream test results to the given server.\n" -#endif // GTEST_CAN_STREAM_RESULTS_ - "\n" - "Assertion Behavior:\n" -#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS - " @G--" GTEST_FLAG_PREFIX_ - "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" - " Set the default death test style.\n" -#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS - " @G--" GTEST_FLAG_PREFIX_ - "break_on_failure@D\n" - " Turn assertion failures into debugger break-points.\n" - " @G--" GTEST_FLAG_PREFIX_ - "throw_on_failure@D\n" - " Turn assertion failures into C++ exceptions for use by an external\n" - " test framework.\n" - " @G--" GTEST_FLAG_PREFIX_ - "catch_exceptions=0@D\n" - " Do not report exceptions as test failures. Instead, allow them\n" - " to crash the program or throw a pop-up (on Windows).\n" - "\n" - "Except for @G--" GTEST_FLAG_PREFIX_ - "list_tests@D, you can alternatively set " - "the corresponding\n" - "environment variable of a flag (all letters in upper-case). For example, " - "to\n" - "disable colored text output, you can either specify " - "@G--" GTEST_FLAG_PREFIX_ - "color=no@D or set\n" - "the @G" GTEST_FLAG_PREFIX_UPPER_ - "COLOR@D environment variable to @Gno@D.\n" - "\n" - "For more information, please read the " GTEST_NAME_ - " documentation at\n" - "@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ - "\n" - "(not one in your own code or tests), please report it to\n" - "@G<" GTEST_DEV_EMAIL_ ">@D.\n"; - -static bool ParseGoogleTestFlag(const char* const arg) { -#define GTEST_INTERNAL_PARSE_FLAG(flag_name) \ - do { \ - auto value = GTEST_FLAG_GET(flag_name); \ - if (ParseFlag(arg, #flag_name, &value)) { \ - GTEST_FLAG_SET(flag_name, value); \ - return true; \ - } \ - } while (false) - - GTEST_INTERNAL_PARSE_FLAG(also_run_disabled_tests); - GTEST_INTERNAL_PARSE_FLAG(break_on_failure); - GTEST_INTERNAL_PARSE_FLAG(catch_exceptions); - GTEST_INTERNAL_PARSE_FLAG(color); - GTEST_INTERNAL_PARSE_FLAG(death_test_style); - GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork); - GTEST_INTERNAL_PARSE_FLAG(fail_fast); - GTEST_INTERNAL_PARSE_FLAG(filter); - GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test); - GTEST_INTERNAL_PARSE_FLAG(list_tests); - GTEST_INTERNAL_PARSE_FLAG(output); - GTEST_INTERNAL_PARSE_FLAG(brief); - GTEST_INTERNAL_PARSE_FLAG(print_time); - GTEST_INTERNAL_PARSE_FLAG(print_utf8); - GTEST_INTERNAL_PARSE_FLAG(random_seed); - GTEST_INTERNAL_PARSE_FLAG(repeat); - GTEST_INTERNAL_PARSE_FLAG(recreate_environments_when_repeating); - GTEST_INTERNAL_PARSE_FLAG(shuffle); - GTEST_INTERNAL_PARSE_FLAG(stack_trace_depth); - GTEST_INTERNAL_PARSE_FLAG(stream_result_to); - GTEST_INTERNAL_PARSE_FLAG(throw_on_failure); - return false; -} - -#if GTEST_USE_OWN_FLAGFILE_FLAG_ -static void LoadFlagsFromFile(const std::string& path) { - FILE* flagfile = posix::FOpen(path.c_str(), "r"); - if (!flagfile) { - GTEST_LOG_(FATAL) << "Unable to open file \"" << GTEST_FLAG_GET(flagfile) - << "\""; - } - std::string contents(ReadEntireFile(flagfile)); - posix::FClose(flagfile); - std::vector lines; - SplitString(contents, '\n', &lines); - for (size_t i = 0; i < lines.size(); ++i) { - if (lines[i].empty()) continue; - if (!ParseGoogleTestFlag(lines[i].c_str())) g_help_flag = true; - } -} -#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ - -// Parses the command line for Google Test flags, without initializing -// other parts of Google Test. The type parameter CharType can be -// instantiated to either char or wchar_t. -template -void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { - std::string flagfile_value; - for (int i = 1; i < *argc; i++) { - const std::string arg_string = StreamableToString(argv[i]); - const char* const arg = arg_string.c_str(); - - using internal::ParseFlag; - - bool remove_flag = false; - if (ParseGoogleTestFlag(arg)) { - remove_flag = true; -#if GTEST_USE_OWN_FLAGFILE_FLAG_ - } else if (ParseFlag(arg, "flagfile", &flagfile_value)) { - GTEST_FLAG_SET(flagfile, flagfile_value); - LoadFlagsFromFile(flagfile_value); - remove_flag = true; -#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ - } else if (arg_string == "--help" || HasGoogleTestFlagPrefix(arg)) { - // Both help flag and unrecognized Google Test flags (excluding - // internal ones) trigger help display. - g_help_flag = true; - } - - if (remove_flag) { - // Shift the remainder of the argv list left by one. Note - // that argv has (*argc + 1) elements, the last one always being - // NULL. The following loop moves the trailing NULL element as - // well. - for (int j = i; j != *argc; j++) { - argv[j] = argv[j + 1]; - } - - // Decrements the argument count. - (*argc)--; - - // We also need to decrement the iterator as we just removed - // an element. - i--; - } - } - - if (g_help_flag) { - // We print the help here instead of in RUN_ALL_TESTS(), as the - // latter may not be called at all if the user is using Google - // Test with another testing framework. - PrintColorEncoded(kColorEncodedHelpMessage); - } -} - -// Parses the command line for Google Test flags, without initializing -// other parts of Google Test. -void ParseGoogleTestFlagsOnly(int* argc, char** argv) { -#if GTEST_HAS_ABSL - if (*argc > 0) { - // absl::ParseCommandLine() requires *argc > 0. - auto positional_args = absl::flags_internal::ParseCommandLineImpl( - *argc, argv, absl::flags_internal::ArgvListAction::kRemoveParsedArgs, - absl::flags_internal::UsageFlagsAction::kHandleUsage, - absl::flags_internal::OnUndefinedFlag::kReportUndefined); - // Any command-line positional arguments not part of any command-line flag - // (or arguments to a flag) are copied back out to argv, with the program - // invocation name at position 0, and argc is resized. This includes - // positional arguments after the flag-terminating delimiter '--'. - // See https://abseil.io/docs/cpp/guides/flags. - std::copy(positional_args.begin(), positional_args.end(), argv); - if (static_cast(positional_args.size()) < *argc) { - argv[positional_args.size()] = nullptr; - *argc = static_cast(positional_args.size()); - } - } -#else - ParseGoogleTestFlagsOnlyImpl(argc, argv); -#endif - - // Fix the value of *_NSGetArgc() on macOS, but if and only if - // *_NSGetArgv() == argv - // Only applicable to char** version of argv -#if GTEST_OS_MAC -#ifndef GTEST_OS_IOS - if (*_NSGetArgv() == argv) { - *_NSGetArgc() = *argc; - } -#endif -#endif -} -void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { - ParseGoogleTestFlagsOnlyImpl(argc, argv); -} - -// The internal implementation of InitGoogleTest(). -// -// The type parameter CharType can be instantiated to either char or -// wchar_t. -template -void InitGoogleTestImpl(int* argc, CharType** argv) { - // We don't want to run the initialization code twice. - if (GTestIsInitialized()) return; - - if (*argc <= 0) return; - - g_argvs.clear(); - for (int i = 0; i != *argc; i++) { - g_argvs.push_back(StreamableToString(argv[i])); - } - -#if GTEST_HAS_ABSL - absl::InitializeSymbolizer(g_argvs[0].c_str()); - - // When using the Abseil Flags library, set the program usage message to the - // help message, but remove the color-encoding from the message first. - absl::SetProgramUsageMessage(absl::StrReplaceAll( - kColorEncodedHelpMessage, - {{"@D", ""}, {"@R", ""}, {"@G", ""}, {"@Y", ""}, {"@@", "@"}})); -#endif // GTEST_HAS_ABSL - - ParseGoogleTestFlagsOnly(argc, argv); - GetUnitTestImpl()->PostFlagParsingInit(); -} - -} // namespace internal - -// Initializes Google Test. This must be called before calling -// RUN_ALL_TESTS(). In particular, it parses a command line for the -// flags that Google Test recognizes. Whenever a Google Test flag is -// seen, it is removed from argv, and *argc is decremented. -// -// No value is returned. Instead, the Google Test flag variables are -// updated. -// -// Calling the function for the second time has no user-visible effect. -void InitGoogleTest(int* argc, char** argv) { -#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) - GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv); -#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) - internal::InitGoogleTestImpl(argc, argv); -#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) -} - -// This overloaded version can be used in Windows programs compiled in -// UNICODE mode. -void InitGoogleTest(int* argc, wchar_t** argv) { -#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) - GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv); -#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) - internal::InitGoogleTestImpl(argc, argv); -#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) -} - -// This overloaded version can be used on Arduino/embedded platforms where -// there is no argc/argv. -void InitGoogleTest() { - // Since Arduino doesn't have a command line, fake out the argc/argv arguments - int argc = 1; - const auto arg0 = "dummy"; - char* argv0 = const_cast(arg0); - char** argv = &argv0; - -#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) - GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(&argc, argv); -#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) - internal::InitGoogleTestImpl(&argc, argv); -#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) -} - -#if !defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_) -// Return value of first environment variable that is set and contains -// a non-empty string. If there are none, return the "fallback" string. -// Since we like the temporary directory to have a directory separator suffix, -// add it if not provided in the environment variable value. -static std::string GetTempDirFromEnv( - std::initializer_list environment_variables, - const char* fallback, char separator) { - for (const char* variable_name : environment_variables) { - const char* value = internal::posix::GetEnv(variable_name); - if (value != nullptr && value[0] != '\0') { - if (value[strlen(value) - 1] != separator) { - return std::string(value).append(1, separator); - } - return value; - } - } - return fallback; -} -#endif - -std::string TempDir() { -#if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_) - return GTEST_CUSTOM_TEMPDIR_FUNCTION_(); -#elif GTEST_OS_WINDOWS || GTEST_OS_WINDOWS_MOBILE - return GetTempDirFromEnv({"TEST_TMPDIR", "TEMP"}, "\\temp\\", '\\'); -#elif GTEST_OS_LINUX_ANDROID - return GetTempDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/data/local/tmp/", '/'); -#else - return GetTempDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/tmp/", '/'); -#endif -} - -// Class ScopedTrace - -// Pushes the given source file location and message onto a per-thread -// trace stack maintained by Google Test. -void ScopedTrace::PushTrace(const char* file, int line, std::string message) { - internal::TraceInfo trace; - trace.file = file; - trace.line = line; - trace.message.swap(message); - - UnitTest::GetInstance()->PushGTestTrace(trace); -} - -// Pops the info pushed by the c'tor. -ScopedTrace::~ScopedTrace() GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { - UnitTest::GetInstance()->PopGTestTrace(); -} - -} // namespace testing diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest_main.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest_main.cc deleted file mode 100644 index 44976375..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/googletest/src/src/gtest_main.cc +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include - -#include "gtest/gtest.h" - -#if GTEST_OS_ESP8266 || GTEST_OS_ESP32 -#if GTEST_OS_ESP8266 -extern "C" { -#endif -void setup() { testing::InitGoogleTest(); } - -void loop() { RUN_ALL_TESTS(); } - -#if GTEST_OS_ESP8266 -} -#endif - -#else - -GTEST_API_ int main(int argc, char **argv) { - printf("Running main() from %s\n", __FILE__); - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/AUTHORS.TXT b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/AUTHORS.TXT deleted file mode 100644 index 59b648ca..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/AUTHORS.TXT +++ /dev/null @@ -1,5 +0,0 @@ -# Names should be added to this file like so: -# Name or Organization - -Google Inc. -Elijah Cirioli diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/Android.mk b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/Android.mk deleted file mode 100644 index e6c17df0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/Android.mk +++ /dev/null @@ -1,23 +0,0 @@ -# Ignore this file during non-NDK builds. -ifdef NDK_ROOT -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE:= libwebm -LOCAL_CPPFLAGS:=-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -LOCAL_CPPFLAGS+=-D__STDC_LIMIT_MACROS -std=c++11 -LOCAL_C_INCLUDES:= $(LOCAL_PATH) -LOCAL_EXPORT_C_INCLUDES:= $(LOCAL_PATH) - -LOCAL_SRC_FILES:= common/file_util.cc \ - common/hdr_util.cc \ - mkvparser/mkvparser.cc \ - mkvparser/mkvreader.cc \ - mkvmuxer/mkvmuxer.cc \ - mkvmuxer/mkvmuxerutil.cc \ - mkvmuxer/mkvwriter.cc -LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := $(LOCAL_PATH)/LICENSE.TXT $(LOCAL_PATH)/PATENTS.TXT -include $(BUILD_STATIC_LIBRARY) -endif # NDK_ROOT diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/LICENSE.TXT b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/LICENSE.TXT deleted file mode 100644 index 7a6f9954..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/LICENSE.TXT +++ /dev/null @@ -1,30 +0,0 @@ -Copyright (c) 2010, Google Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * Neither the name of Google nor the names of its contributors may - be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/PATENTS.TXT b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/PATENTS.TXT deleted file mode 100644 index caedf607..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/PATENTS.TXT +++ /dev/null @@ -1,23 +0,0 @@ -Additional IP Rights Grant (Patents) ------------------------------------- - -"These implementations" means the copyrightable works that implement the WebM -codecs distributed by Google as part of the WebM Project. - -Google hereby grants to you a perpetual, worldwide, non-exclusive, no-charge, -royalty-free, irrevocable (except as stated in this section) patent license to -make, have made, use, offer to sell, sell, import, transfer, and otherwise -run, modify and propagate the contents of these implementations of WebM, where -such license applies only to those patent claims, both currently owned by -Google and acquired in the future, licensable by Google that are necessarily -infringed by these implementations of WebM. This grant does not include claims -that would be infringed only as a consequence of further modification of these -implementations. If you or your agent or exclusive licensee institute or order -or agree to the institution of patent litigation or any other patent -enforcement activity against any entity (including a cross-claim or -counterclaim in a lawsuit) alleging that any of these implementations of WebM -or any code incorporated within any of these implementations of WebM -constitute direct or contributory patent infringement, or inducement of -patent infringement, then any patent rights granted to you under this License -for these implementations of WebM shall terminate as of the date such -litigation is filed. diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/README.libvpx b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/README.libvpx deleted file mode 100644 index 6e434875..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/README.libvpx +++ /dev/null @@ -1,20 +0,0 @@ -URL: https://chromium.googlesource.com/webm/libwebm -Version: 3b630045052e1e4d563207ab9e3be8d137c26067 -License: BSD -License File: LICENSE.TXT - -Description: -libwebm is used to handle WebM container I/O. - -Local Changes: -Only keep: - - Android.mk - - AUTHORS.TXT - - common/ - file_util.cc/h - hdr_util.cc/h - webmids.h - - LICENSE.TXT - - mkvmuxer/ - - mkvparser/ - - PATENTS.TXT diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/common/file_util.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/common/file_util.cc deleted file mode 100644 index 6eb6428b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/common/file_util.cc +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2016 The WebM project authors. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -#include "common/file_util.h" - -#include -#ifndef _MSC_VER -#include // close() -#endif - -#include -#include -#include -#include -#include -#include - -namespace libwebm { - -std::string GetTempFileName() { -#if !defined _MSC_VER && !defined __MINGW32__ - std::string temp_file_name_template_str = - std::string(std::getenv("TEST_TMPDIR") ? std::getenv("TEST_TMPDIR") - : ".") + - "/libwebm_temp.XXXXXX"; - char* temp_file_name_template = - new char[temp_file_name_template_str.length() + 1]; - memset(temp_file_name_template, 0, temp_file_name_template_str.length() + 1); - temp_file_name_template_str.copy(temp_file_name_template, - temp_file_name_template_str.length(), 0); - int fd = mkstemp(temp_file_name_template); - std::string temp_file_name = - (fd != -1) ? std::string(temp_file_name_template) : std::string(); - delete[] temp_file_name_template; - if (fd != -1) { - close(fd); - } - return temp_file_name; -#else - char tmp_file_name[_MAX_PATH]; -#if defined _MSC_VER || defined MINGW_HAS_SECURE_API - errno_t err = tmpnam_s(tmp_file_name); -#else - char* fname_pointer = tmpnam(tmp_file_name); - int err = (fname_pointer == &tmp_file_name[0]) ? 0 : -1; -#endif - if (err == 0) { - return std::string(tmp_file_name); - } - return std::string(); -#endif -} - -uint64_t GetFileSize(const std::string& file_name) { - uint64_t file_size = 0; -#ifndef _MSC_VER - struct stat st; - st.st_size = 0; - if (stat(file_name.c_str(), &st) == 0) { -#else - struct _stat st; - st.st_size = 0; - if (_stat(file_name.c_str(), &st) == 0) { -#endif - file_size = st.st_size; - } - return file_size; -} - -bool GetFileContents(const std::string& file_name, std::string* contents) { - std::ifstream file(file_name.c_str()); - *contents = std::string(static_cast(GetFileSize(file_name)), 0); - if (file.good() && contents->size()) { - file.read(&(*contents)[0], contents->size()); - } - return !file.fail(); -} - -TempFileDeleter::TempFileDeleter() { file_name_ = GetTempFileName(); } - -TempFileDeleter::~TempFileDeleter() { - std::ifstream file(file_name_.c_str()); - if (file.good()) { - file.close(); - std::remove(file_name_.c_str()); - } -} - -} // namespace libwebm diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/common/file_util.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/common/file_util.h deleted file mode 100644 index a8737346..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/common/file_util.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2016 The WebM project authors. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -#ifndef LIBWEBM_COMMON_FILE_UTIL_H_ -#define LIBWEBM_COMMON_FILE_UTIL_H_ - -#include - -#include - -#include "mkvmuxer/mkvmuxertypes.h" // LIBWEBM_DISALLOW_COPY_AND_ASSIGN() - -namespace libwebm { - -// Returns a temporary file name. -std::string GetTempFileName(); - -// Returns size of file specified by |file_name|, or 0 upon failure. -uint64_t GetFileSize(const std::string& file_name); - -// Gets the contents file_name as a string. Returns false on error. -bool GetFileContents(const std::string& file_name, std::string* contents); - -// Manages life of temporary file specified at time of construction. Deletes -// file upon destruction. -class TempFileDeleter { - public: - TempFileDeleter(); - explicit TempFileDeleter(std::string file_name) : file_name_(file_name) {} - ~TempFileDeleter(); - const std::string& name() const { return file_name_; } - - private: - std::string file_name_; - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(TempFileDeleter); -}; - -} // namespace libwebm - -#endif // LIBWEBM_COMMON_FILE_UTIL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/common/hdr_util.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/common/hdr_util.cc deleted file mode 100644 index f1320a53..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/common/hdr_util.cc +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright (c) 2016 The WebM project authors. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -#include "hdr_util.h" - -#include -#include -#include - -#include "mkvparser/mkvparser.h" - -namespace libwebm { -const int Vp9CodecFeatures::kValueNotPresent = INT_MAX; - -bool CopyPrimaryChromaticity(const mkvparser::PrimaryChromaticity& parser_pc, - PrimaryChromaticityPtr* muxer_pc) { - muxer_pc->reset(new (std::nothrow) - mkvmuxer::PrimaryChromaticity(parser_pc.x, parser_pc.y)); - if (!muxer_pc->get()) - return false; - return true; -} - -bool MasteringMetadataValuePresent(double value) { - return value != mkvparser::MasteringMetadata::kValueNotPresent; -} - -bool CopyMasteringMetadata(const mkvparser::MasteringMetadata& parser_mm, - mkvmuxer::MasteringMetadata* muxer_mm) { - if (MasteringMetadataValuePresent(parser_mm.luminance_max)) - muxer_mm->set_luminance_max(parser_mm.luminance_max); - if (MasteringMetadataValuePresent(parser_mm.luminance_min)) - muxer_mm->set_luminance_min(parser_mm.luminance_min); - - PrimaryChromaticityPtr r_ptr(nullptr); - PrimaryChromaticityPtr g_ptr(nullptr); - PrimaryChromaticityPtr b_ptr(nullptr); - PrimaryChromaticityPtr wp_ptr(nullptr); - - if (parser_mm.r) { - if (!CopyPrimaryChromaticity(*parser_mm.r, &r_ptr)) - return false; - } - if (parser_mm.g) { - if (!CopyPrimaryChromaticity(*parser_mm.g, &g_ptr)) - return false; - } - if (parser_mm.b) { - if (!CopyPrimaryChromaticity(*parser_mm.b, &b_ptr)) - return false; - } - if (parser_mm.white_point) { - if (!CopyPrimaryChromaticity(*parser_mm.white_point, &wp_ptr)) - return false; - } - - if (!muxer_mm->SetChromaticity(r_ptr.get(), g_ptr.get(), b_ptr.get(), - wp_ptr.get())) { - return false; - } - - return true; -} - -bool ColourValuePresent(long long value) { - return value != mkvparser::Colour::kValueNotPresent; -} - -bool CopyColour(const mkvparser::Colour& parser_colour, - mkvmuxer::Colour* muxer_colour) { - if (!muxer_colour) - return false; - - if (ColourValuePresent(parser_colour.matrix_coefficients)) - muxer_colour->set_matrix_coefficients(parser_colour.matrix_coefficients); - if (ColourValuePresent(parser_colour.bits_per_channel)) - muxer_colour->set_bits_per_channel(parser_colour.bits_per_channel); - if (ColourValuePresent(parser_colour.chroma_subsampling_horz)) { - muxer_colour->set_chroma_subsampling_horz( - parser_colour.chroma_subsampling_horz); - } - if (ColourValuePresent(parser_colour.chroma_subsampling_vert)) { - muxer_colour->set_chroma_subsampling_vert( - parser_colour.chroma_subsampling_vert); - } - if (ColourValuePresent(parser_colour.cb_subsampling_horz)) - muxer_colour->set_cb_subsampling_horz(parser_colour.cb_subsampling_horz); - if (ColourValuePresent(parser_colour.cb_subsampling_vert)) - muxer_colour->set_cb_subsampling_vert(parser_colour.cb_subsampling_vert); - if (ColourValuePresent(parser_colour.chroma_siting_horz)) - muxer_colour->set_chroma_siting_horz(parser_colour.chroma_siting_horz); - if (ColourValuePresent(parser_colour.chroma_siting_vert)) - muxer_colour->set_chroma_siting_vert(parser_colour.chroma_siting_vert); - if (ColourValuePresent(parser_colour.range)) - muxer_colour->set_range(parser_colour.range); - if (ColourValuePresent(parser_colour.transfer_characteristics)) { - muxer_colour->set_transfer_characteristics( - parser_colour.transfer_characteristics); - } - if (ColourValuePresent(parser_colour.primaries)) - muxer_colour->set_primaries(parser_colour.primaries); - if (ColourValuePresent(parser_colour.max_cll)) - muxer_colour->set_max_cll(parser_colour.max_cll); - if (ColourValuePresent(parser_colour.max_fall)) - muxer_colour->set_max_fall(parser_colour.max_fall); - - if (parser_colour.mastering_metadata) { - mkvmuxer::MasteringMetadata muxer_mm; - if (!CopyMasteringMetadata(*parser_colour.mastering_metadata, &muxer_mm)) - return false; - if (!muxer_colour->SetMasteringMetadata(muxer_mm)) - return false; - } - return true; -} - -// Format of VPx private data: -// -// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | ID Byte | Length | | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | -// | | -// : Bytes 1..Length of Codec Feature : -// | | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// -// ID Byte Format -// ID byte is an unsigned byte. -// 0 1 2 3 4 5 6 7 -// +-+-+-+-+-+-+-+-+ -// |X| ID | -// +-+-+-+-+-+-+-+-+ -// -// The X bit is reserved. -// -// See the following link for more information: -// http://www.webmproject.org/vp9/profiles/ -bool ParseVpxCodecPrivate(const uint8_t* private_data, int32_t length, - Vp9CodecFeatures* features) { - const int kVpxCodecPrivateMinLength = 3; - if (!private_data || !features || length < kVpxCodecPrivateMinLength) - return false; - - const uint8_t kVp9ProfileId = 1; - const uint8_t kVp9LevelId = 2; - const uint8_t kVp9BitDepthId = 3; - const uint8_t kVp9ChromaSubsamplingId = 4; - const int kVpxFeatureLength = 1; - int offset = 0; - - // Set features to not set. - features->profile = Vp9CodecFeatures::kValueNotPresent; - features->level = Vp9CodecFeatures::kValueNotPresent; - features->bit_depth = Vp9CodecFeatures::kValueNotPresent; - features->chroma_subsampling = Vp9CodecFeatures::kValueNotPresent; - do { - const uint8_t id_byte = private_data[offset++]; - const uint8_t length_byte = private_data[offset++]; - if (length_byte != kVpxFeatureLength) - return false; - if (id_byte == kVp9ProfileId) { - const int priv_profile = static_cast(private_data[offset++]); - if (priv_profile < 0 || priv_profile > 3) - return false; - if (features->profile != Vp9CodecFeatures::kValueNotPresent && - features->profile != priv_profile) { - return false; - } - features->profile = priv_profile; - } else if (id_byte == kVp9LevelId) { - const int priv_level = static_cast(private_data[offset++]); - - const int kNumLevels = 14; - const int levels[kNumLevels] = {10, 11, 20, 21, 30, 31, 40, - 41, 50, 51, 52, 60, 61, 62}; - - for (int i = 0; i < kNumLevels; ++i) { - if (priv_level == levels[i]) { - if (features->level != Vp9CodecFeatures::kValueNotPresent && - features->level != priv_level) { - return false; - } - features->level = priv_level; - break; - } - } - if (features->level == Vp9CodecFeatures::kValueNotPresent) - return false; - } else if (id_byte == kVp9BitDepthId) { - const int priv_profile = static_cast(private_data[offset++]); - if (priv_profile != 8 && priv_profile != 10 && priv_profile != 12) - return false; - if (features->bit_depth != Vp9CodecFeatures::kValueNotPresent && - features->bit_depth != priv_profile) { - return false; - } - features->bit_depth = priv_profile; - } else if (id_byte == kVp9ChromaSubsamplingId) { - const int priv_profile = static_cast(private_data[offset++]); - if (priv_profile != 0 && priv_profile != 1 && priv_profile != 2 && - priv_profile != 3) - return false; - if (features->chroma_subsampling != Vp9CodecFeatures::kValueNotPresent && - features->chroma_subsampling != priv_profile) { - return false; - } - features->chroma_subsampling = priv_profile; - } else { - // Invalid ID. - return false; - } - } while (offset + kVpxCodecPrivateMinLength <= length); - - return true; -} -} // namespace libwebm diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/common/hdr_util.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/common/hdr_util.h deleted file mode 100644 index 78e2eeb7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/common/hdr_util.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) 2016 The WebM project authors. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -#ifndef LIBWEBM_COMMON_HDR_UTIL_H_ -#define LIBWEBM_COMMON_HDR_UTIL_H_ - -#include - -#include - -#include "mkvmuxer/mkvmuxer.h" - -namespace mkvparser { -struct Colour; -struct MasteringMetadata; -struct PrimaryChromaticity; -} // namespace mkvparser - -namespace libwebm { -// Utility types and functions for working with the Colour element and its -// children. Copiers return true upon success. Presence functions return true -// when the specified element is present. - -// TODO(tomfinegan): These should be moved to libwebm_utils once c++11 is -// required by libwebm. - -// Features of the VP9 codec that may be set in the CodecPrivate of a VP9 video -// stream. A value of kValueNotPresent represents that the value was not set in -// the CodecPrivate. -struct Vp9CodecFeatures { - static const int kValueNotPresent; - - Vp9CodecFeatures() - : profile(kValueNotPresent), - level(kValueNotPresent), - bit_depth(kValueNotPresent), - chroma_subsampling(kValueNotPresent) {} - ~Vp9CodecFeatures() {} - - int profile; - int level; - int bit_depth; - int chroma_subsampling; -}; - -typedef std::unique_ptr PrimaryChromaticityPtr; - -bool CopyPrimaryChromaticity(const mkvparser::PrimaryChromaticity& parser_pc, - PrimaryChromaticityPtr* muxer_pc); - -bool MasteringMetadataValuePresent(double value); - -bool CopyMasteringMetadata(const mkvparser::MasteringMetadata& parser_mm, - mkvmuxer::MasteringMetadata* muxer_mm); - -bool ColourValuePresent(long long value); - -bool CopyColour(const mkvparser::Colour& parser_colour, - mkvmuxer::Colour* muxer_colour); - -// Returns true if |features| is set to one or more valid values. -bool ParseVpxCodecPrivate(const uint8_t* private_data, int32_t length, - Vp9CodecFeatures* features); - -} // namespace libwebm - -#endif // LIBWEBM_COMMON_HDR_UTIL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/common/webmids.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/common/webmids.h deleted file mode 100644 index fc0c2081..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/common/webmids.h +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (c) 2012 The WebM project authors. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. - -#ifndef COMMON_WEBMIDS_H_ -#define COMMON_WEBMIDS_H_ - -namespace libwebm { - -enum MkvId { - kMkvEBML = 0x1A45DFA3, - kMkvEBMLVersion = 0x4286, - kMkvEBMLReadVersion = 0x42F7, - kMkvEBMLMaxIDLength = 0x42F2, - kMkvEBMLMaxSizeLength = 0x42F3, - kMkvDocType = 0x4282, - kMkvDocTypeVersion = 0x4287, - kMkvDocTypeReadVersion = 0x4285, - kMkvVoid = 0xEC, - kMkvSignatureSlot = 0x1B538667, - kMkvSignatureAlgo = 0x7E8A, - kMkvSignatureHash = 0x7E9A, - kMkvSignaturePublicKey = 0x7EA5, - kMkvSignature = 0x7EB5, - kMkvSignatureElements = 0x7E5B, - kMkvSignatureElementList = 0x7E7B, - kMkvSignedElement = 0x6532, - // segment - kMkvSegment = 0x18538067, - // Meta Seek Information - kMkvSeekHead = 0x114D9B74, - kMkvSeek = 0x4DBB, - kMkvSeekID = 0x53AB, - kMkvSeekPosition = 0x53AC, - // Segment Information - kMkvInfo = 0x1549A966, - kMkvTimecodeScale = 0x2AD7B1, - kMkvDuration = 0x4489, - kMkvDateUTC = 0x4461, - kMkvTitle = 0x7BA9, - kMkvMuxingApp = 0x4D80, - kMkvWritingApp = 0x5741, - // Cluster - kMkvCluster = 0x1F43B675, - kMkvTimecode = 0xE7, - kMkvPrevSize = 0xAB, - kMkvBlockGroup = 0xA0, - kMkvBlock = 0xA1, - kMkvBlockDuration = 0x9B, - kMkvReferenceBlock = 0xFB, - kMkvLaceNumber = 0xCC, - kMkvSimpleBlock = 0xA3, - kMkvBlockAdditions = 0x75A1, - kMkvBlockMore = 0xA6, - kMkvBlockAddID = 0xEE, - kMkvBlockAdditional = 0xA5, - kMkvDiscardPadding = 0x75A2, - // Track - kMkvTracks = 0x1654AE6B, - kMkvTrackEntry = 0xAE, - kMkvTrackNumber = 0xD7, - kMkvTrackUID = 0x73C5, - kMkvTrackType = 0x83, - kMkvFlagEnabled = 0xB9, - kMkvFlagDefault = 0x88, - kMkvFlagForced = 0x55AA, - kMkvFlagLacing = 0x9C, - kMkvDefaultDuration = 0x23E383, - kMkvMaxBlockAdditionID = 0x55EE, - kMkvName = 0x536E, - kMkvLanguage = 0x22B59C, - kMkvCodecID = 0x86, - kMkvCodecPrivate = 0x63A2, - kMkvCodecName = 0x258688, - kMkvCodecDelay = 0x56AA, - kMkvSeekPreRoll = 0x56BB, - // video - kMkvVideo = 0xE0, - kMkvFlagInterlaced = 0x9A, - kMkvStereoMode = 0x53B8, - kMkvAlphaMode = 0x53C0, - kMkvPixelWidth = 0xB0, - kMkvPixelHeight = 0xBA, - kMkvPixelCropBottom = 0x54AA, - kMkvPixelCropTop = 0x54BB, - kMkvPixelCropLeft = 0x54CC, - kMkvPixelCropRight = 0x54DD, - kMkvDisplayWidth = 0x54B0, - kMkvDisplayHeight = 0x54BA, - kMkvDisplayUnit = 0x54B2, - kMkvAspectRatioType = 0x54B3, - kMkvColourSpace = 0x2EB524, - kMkvFrameRate = 0x2383E3, - // end video - // colour - kMkvColour = 0x55B0, - kMkvMatrixCoefficients = 0x55B1, - kMkvBitsPerChannel = 0x55B2, - kMkvChromaSubsamplingHorz = 0x55B3, - kMkvChromaSubsamplingVert = 0x55B4, - kMkvCbSubsamplingHorz = 0x55B5, - kMkvCbSubsamplingVert = 0x55B6, - kMkvChromaSitingHorz = 0x55B7, - kMkvChromaSitingVert = 0x55B8, - kMkvRange = 0x55B9, - kMkvTransferCharacteristics = 0x55BA, - kMkvPrimaries = 0x55BB, - kMkvMaxCLL = 0x55BC, - kMkvMaxFALL = 0x55BD, - // mastering metadata - kMkvMasteringMetadata = 0x55D0, - kMkvPrimaryRChromaticityX = 0x55D1, - kMkvPrimaryRChromaticityY = 0x55D2, - kMkvPrimaryGChromaticityX = 0x55D3, - kMkvPrimaryGChromaticityY = 0x55D4, - kMkvPrimaryBChromaticityX = 0x55D5, - kMkvPrimaryBChromaticityY = 0x55D6, - kMkvWhitePointChromaticityX = 0x55D7, - kMkvWhitePointChromaticityY = 0x55D8, - kMkvLuminanceMax = 0x55D9, - kMkvLuminanceMin = 0x55DA, - // end mastering metadata - // end colour - // projection - kMkvProjection = 0x7670, - kMkvProjectionType = 0x7671, - kMkvProjectionPrivate = 0x7672, - kMkvProjectionPoseYaw = 0x7673, - kMkvProjectionPosePitch = 0x7674, - kMkvProjectionPoseRoll = 0x7675, - // end projection - // audio - kMkvAudio = 0xE1, - kMkvSamplingFrequency = 0xB5, - kMkvOutputSamplingFrequency = 0x78B5, - kMkvChannels = 0x9F, - kMkvBitDepth = 0x6264, - // end audio - // ContentEncodings - kMkvContentEncodings = 0x6D80, - kMkvContentEncoding = 0x6240, - kMkvContentEncodingOrder = 0x5031, - kMkvContentEncodingScope = 0x5032, - kMkvContentEncodingType = 0x5033, - kMkvContentCompression = 0x5034, - kMkvContentCompAlgo = 0x4254, - kMkvContentCompSettings = 0x4255, - kMkvContentEncryption = 0x5035, - kMkvContentEncAlgo = 0x47E1, - kMkvContentEncKeyID = 0x47E2, - kMkvContentSignature = 0x47E3, - kMkvContentSigKeyID = 0x47E4, - kMkvContentSigAlgo = 0x47E5, - kMkvContentSigHashAlgo = 0x47E6, - kMkvContentEncAESSettings = 0x47E7, - kMkvAESSettingsCipherMode = 0x47E8, - kMkvAESSettingsCipherInitData = 0x47E9, - // end ContentEncodings - // Cueing Data - kMkvCues = 0x1C53BB6B, - kMkvCuePoint = 0xBB, - kMkvCueTime = 0xB3, - kMkvCueTrackPositions = 0xB7, - kMkvCueTrack = 0xF7, - kMkvCueClusterPosition = 0xF1, - kMkvCueBlockNumber = 0x5378, - // Chapters - kMkvChapters = 0x1043A770, - kMkvEditionEntry = 0x45B9, - kMkvChapterAtom = 0xB6, - kMkvChapterUID = 0x73C4, - kMkvChapterStringUID = 0x5654, - kMkvChapterTimeStart = 0x91, - kMkvChapterTimeEnd = 0x92, - kMkvChapterDisplay = 0x80, - kMkvChapString = 0x85, - kMkvChapLanguage = 0x437C, - kMkvChapCountry = 0x437E, - // Tags - kMkvTags = 0x1254C367, - kMkvTag = 0x7373, - kMkvSimpleTag = 0x67C8, - kMkvTagName = 0x45A3, - kMkvTagString = 0x4487 -}; - -} // namespace libwebm - -#endif // COMMON_WEBMIDS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvmuxer.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvmuxer.cc deleted file mode 100644 index 21e51be4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvmuxer.cc +++ /dev/null @@ -1,4204 +0,0 @@ -// Copyright (c) 2012 The WebM project authors. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. - -#include "mkvmuxer/mkvmuxer.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "common/webmids.h" -#include "mkvmuxer/mkvmuxerutil.h" -#include "mkvmuxer/mkvwriter.h" -#include "mkvparser/mkvparser.h" - -namespace mkvmuxer { - -const float PrimaryChromaticity::kChromaticityMin = 0.0f; -const float PrimaryChromaticity::kChromaticityMax = 1.0f; -const float MasteringMetadata::kMinLuminance = 0.0f; -const float MasteringMetadata::kMinLuminanceMax = 999.99f; -const float MasteringMetadata::kMaxLuminanceMax = 9999.99f; -const float MasteringMetadata::kValueNotPresent = FLT_MAX; -const uint64_t Colour::kValueNotPresent = UINT64_MAX; - -namespace { - -const char kDocTypeWebm[] = "webm"; -const char kDocTypeMatroska[] = "matroska"; - -// Deallocate the string designated by |dst|, and then copy the |src| -// string to |dst|. The caller owns both the |src| string and the -// |dst| copy (hence the caller is responsible for eventually -// deallocating the strings, either directly, or indirectly via -// StrCpy). Returns true if the source string was successfully copied -// to the destination. -bool StrCpy(const char* src, char** dst_ptr) { - if (dst_ptr == NULL) - return false; - - char*& dst = *dst_ptr; - - delete[] dst; - dst = NULL; - - if (src == NULL) - return true; - - const size_t size = strlen(src) + 1; - - dst = new (std::nothrow) char[size]; // NOLINT - if (dst == NULL) - return false; - - memcpy(dst, src, size - 1); - dst[size - 1] = '\0'; - return true; -} - -typedef std::unique_ptr PrimaryChromaticityPtr; -bool CopyChromaticity(const PrimaryChromaticity* src, - PrimaryChromaticityPtr* dst) { - if (!dst) - return false; - - dst->reset(new (std::nothrow) PrimaryChromaticity(src->x(), src->y())); - if (!dst->get()) - return false; - - return true; -} - -} // namespace - -/////////////////////////////////////////////////////////////// -// -// IMkvWriter Class - -IMkvWriter::IMkvWriter() {} - -IMkvWriter::~IMkvWriter() {} - -bool WriteEbmlHeader(IMkvWriter* writer, uint64_t doc_type_version, - const char* const doc_type) { - // Level 0 - uint64_t size = - EbmlElementSize(libwebm::kMkvEBMLVersion, static_cast(1)); - size += EbmlElementSize(libwebm::kMkvEBMLReadVersion, static_cast(1)); - size += EbmlElementSize(libwebm::kMkvEBMLMaxIDLength, static_cast(4)); - size += - EbmlElementSize(libwebm::kMkvEBMLMaxSizeLength, static_cast(8)); - size += EbmlElementSize(libwebm::kMkvDocType, doc_type); - size += EbmlElementSize(libwebm::kMkvDocTypeVersion, - static_cast(doc_type_version)); - size += - EbmlElementSize(libwebm::kMkvDocTypeReadVersion, static_cast(2)); - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvEBML, size)) - return false; - if (!WriteEbmlElement(writer, libwebm::kMkvEBMLVersion, - static_cast(1))) { - return false; - } - if (!WriteEbmlElement(writer, libwebm::kMkvEBMLReadVersion, - static_cast(1))) { - return false; - } - if (!WriteEbmlElement(writer, libwebm::kMkvEBMLMaxIDLength, - static_cast(4))) { - return false; - } - if (!WriteEbmlElement(writer, libwebm::kMkvEBMLMaxSizeLength, - static_cast(8))) { - return false; - } - if (!WriteEbmlElement(writer, libwebm::kMkvDocType, doc_type)) - return false; - if (!WriteEbmlElement(writer, libwebm::kMkvDocTypeVersion, - static_cast(doc_type_version))) { - return false; - } - if (!WriteEbmlElement(writer, libwebm::kMkvDocTypeReadVersion, - static_cast(2))) { - return false; - } - - return true; -} - -bool WriteEbmlHeader(IMkvWriter* writer, uint64_t doc_type_version) { - return WriteEbmlHeader(writer, doc_type_version, kDocTypeWebm); -} - -bool WriteEbmlHeader(IMkvWriter* writer) { - return WriteEbmlHeader(writer, mkvmuxer::Segment::kDefaultDocTypeVersion); -} - -bool ChunkedCopy(mkvparser::IMkvReader* source, mkvmuxer::IMkvWriter* dst, - int64_t start, int64_t size) { - // TODO(vigneshv): Check if this is a reasonable value. - const uint32_t kBufSize = 2048; - uint8_t* buf = new uint8_t[kBufSize]; - int64_t offset = start; - while (size > 0) { - const int64_t read_len = (size > kBufSize) ? kBufSize : size; - if (source->Read(offset, static_cast(read_len), buf)) - return false; - dst->Write(buf, static_cast(read_len)); - offset += read_len; - size -= read_len; - } - delete[] buf; - return true; -} - -/////////////////////////////////////////////////////////////// -// -// Frame Class - -Frame::Frame() - : add_id_(0), - additional_(NULL), - additional_length_(0), - duration_(0), - duration_set_(false), - frame_(NULL), - is_key_(false), - length_(0), - track_number_(0), - timestamp_(0), - discard_padding_(0), - reference_block_timestamp_(0), - reference_block_timestamp_set_(false) {} - -Frame::~Frame() { - delete[] frame_; - delete[] additional_; -} - -bool Frame::CopyFrom(const Frame& frame) { - delete[] frame_; - frame_ = NULL; - length_ = 0; - if (frame.length() > 0 && frame.frame() != NULL && - !Init(frame.frame(), frame.length())) { - return false; - } - add_id_ = 0; - delete[] additional_; - additional_ = NULL; - additional_length_ = 0; - if (frame.additional_length() > 0 && frame.additional() != NULL && - !AddAdditionalData(frame.additional(), frame.additional_length(), - frame.add_id())) { - return false; - } - duration_ = frame.duration(); - duration_set_ = frame.duration_set(); - is_key_ = frame.is_key(); - track_number_ = frame.track_number(); - timestamp_ = frame.timestamp(); - discard_padding_ = frame.discard_padding(); - reference_block_timestamp_ = frame.reference_block_timestamp(); - reference_block_timestamp_set_ = frame.reference_block_timestamp_set(); - return true; -} - -bool Frame::Init(const uint8_t* frame, uint64_t length) { - uint8_t* const data = - new (std::nothrow) uint8_t[static_cast(length)]; // NOLINT - if (!data) - return false; - - delete[] frame_; - frame_ = data; - length_ = length; - - memcpy(frame_, frame, static_cast(length_)); - return true; -} - -bool Frame::AddAdditionalData(const uint8_t* additional, uint64_t length, - uint64_t add_id) { - uint8_t* const data = - new (std::nothrow) uint8_t[static_cast(length)]; // NOLINT - if (!data) - return false; - - delete[] additional_; - additional_ = data; - additional_length_ = length; - add_id_ = add_id; - - memcpy(additional_, additional, static_cast(additional_length_)); - return true; -} - -bool Frame::IsValid() const { - if (length_ == 0 || !frame_) { - return false; - } - if ((additional_length_ != 0 && !additional_) || - (additional_ != NULL && additional_length_ == 0)) { - return false; - } - if (track_number_ == 0 || track_number_ > kMaxTrackNumber) { - return false; - } - if (!CanBeSimpleBlock() && !is_key_ && !reference_block_timestamp_set_) { - return false; - } - return true; -} - -bool Frame::CanBeSimpleBlock() const { - return additional_ == NULL && discard_padding_ == 0 && duration_ == 0; -} - -void Frame::set_duration(uint64_t duration) { - duration_ = duration; - duration_set_ = true; -} - -void Frame::set_reference_block_timestamp(int64_t reference_block_timestamp) { - reference_block_timestamp_ = reference_block_timestamp; - reference_block_timestamp_set_ = true; -} - -/////////////////////////////////////////////////////////////// -// -// CuePoint Class - -CuePoint::CuePoint() - : time_(0), - track_(0), - cluster_pos_(0), - block_number_(1), - output_block_number_(true) {} - -CuePoint::~CuePoint() {} - -bool CuePoint::Write(IMkvWriter* writer) const { - if (!writer || track_ < 1 || cluster_pos_ < 1) - return false; - - uint64_t size = EbmlElementSize(libwebm::kMkvCueClusterPosition, - static_cast(cluster_pos_)); - size += EbmlElementSize(libwebm::kMkvCueTrack, static_cast(track_)); - if (output_block_number_ && block_number_ > 1) - size += EbmlElementSize(libwebm::kMkvCueBlockNumber, - static_cast(block_number_)); - const uint64_t track_pos_size = - EbmlMasterElementSize(libwebm::kMkvCueTrackPositions, size) + size; - const uint64_t payload_size = - EbmlElementSize(libwebm::kMkvCueTime, static_cast(time_)) + - track_pos_size; - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvCuePoint, payload_size)) - return false; - - const int64_t payload_position = writer->Position(); - if (payload_position < 0) - return false; - - if (!WriteEbmlElement(writer, libwebm::kMkvCueTime, - static_cast(time_))) { - return false; - } - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvCueTrackPositions, size)) - return false; - if (!WriteEbmlElement(writer, libwebm::kMkvCueTrack, - static_cast(track_))) { - return false; - } - if (!WriteEbmlElement(writer, libwebm::kMkvCueClusterPosition, - static_cast(cluster_pos_))) { - return false; - } - if (output_block_number_ && block_number_ > 1) { - if (!WriteEbmlElement(writer, libwebm::kMkvCueBlockNumber, - static_cast(block_number_))) { - return false; - } - } - - const int64_t stop_position = writer->Position(); - if (stop_position < 0) - return false; - - if (stop_position - payload_position != static_cast(payload_size)) - return false; - - return true; -} - -uint64_t CuePoint::PayloadSize() const { - uint64_t size = EbmlElementSize(libwebm::kMkvCueClusterPosition, - static_cast(cluster_pos_)); - size += EbmlElementSize(libwebm::kMkvCueTrack, static_cast(track_)); - if (output_block_number_ && block_number_ > 1) - size += EbmlElementSize(libwebm::kMkvCueBlockNumber, - static_cast(block_number_)); - const uint64_t track_pos_size = - EbmlMasterElementSize(libwebm::kMkvCueTrackPositions, size) + size; - const uint64_t payload_size = - EbmlElementSize(libwebm::kMkvCueTime, static_cast(time_)) + - track_pos_size; - - return payload_size; -} - -uint64_t CuePoint::Size() const { - const uint64_t payload_size = PayloadSize(); - return EbmlMasterElementSize(libwebm::kMkvCuePoint, payload_size) + - payload_size; -} - -/////////////////////////////////////////////////////////////// -// -// Cues Class - -Cues::Cues() - : cue_entries_capacity_(0), - cue_entries_size_(0), - cue_entries_(NULL), - output_block_number_(true) {} - -Cues::~Cues() { - if (cue_entries_) { - for (int32_t i = 0; i < cue_entries_size_; ++i) { - CuePoint* const cue = cue_entries_[i]; - delete cue; - } - delete[] cue_entries_; - } -} - -bool Cues::AddCue(CuePoint* cue) { - if (!cue) - return false; - - if ((cue_entries_size_ + 1) > cue_entries_capacity_) { - // Add more CuePoints. - const int32_t new_capacity = - (!cue_entries_capacity_) ? 2 : cue_entries_capacity_ * 2; - - if (new_capacity < 1) - return false; - - CuePoint** const cues = - new (std::nothrow) CuePoint*[new_capacity]; // NOLINT - if (!cues) - return false; - - for (int32_t i = 0; i < cue_entries_size_; ++i) { - cues[i] = cue_entries_[i]; - } - - delete[] cue_entries_; - - cue_entries_ = cues; - cue_entries_capacity_ = new_capacity; - } - - cue->set_output_block_number(output_block_number_); - cue_entries_[cue_entries_size_++] = cue; - return true; -} - -CuePoint* Cues::GetCueByIndex(int32_t index) const { - if (cue_entries_ == NULL) - return NULL; - - if (index >= cue_entries_size_) - return NULL; - - return cue_entries_[index]; -} - -uint64_t Cues::Size() { - uint64_t size = 0; - for (int32_t i = 0; i < cue_entries_size_; ++i) - size += GetCueByIndex(i)->Size(); - size += EbmlMasterElementSize(libwebm::kMkvCues, size); - return size; -} - -bool Cues::Write(IMkvWriter* writer) const { - if (!writer) - return false; - - uint64_t size = 0; - for (int32_t i = 0; i < cue_entries_size_; ++i) { - const CuePoint* const cue = GetCueByIndex(i); - - if (!cue) - return false; - - size += cue->Size(); - } - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvCues, size)) - return false; - - const int64_t payload_position = writer->Position(); - if (payload_position < 0) - return false; - - for (int32_t i = 0; i < cue_entries_size_; ++i) { - const CuePoint* const cue = GetCueByIndex(i); - - if (!cue->Write(writer)) - return false; - } - - const int64_t stop_position = writer->Position(); - if (stop_position < 0) - return false; - - if (stop_position - payload_position != static_cast(size)) - return false; - - return true; -} - -/////////////////////////////////////////////////////////////// -// -// ContentEncAESSettings Class - -ContentEncAESSettings::ContentEncAESSettings() : cipher_mode_(kCTR) {} - -uint64_t ContentEncAESSettings::Size() const { - const uint64_t payload = PayloadSize(); - const uint64_t size = - EbmlMasterElementSize(libwebm::kMkvContentEncAESSettings, payload) + - payload; - return size; -} - -bool ContentEncAESSettings::Write(IMkvWriter* writer) const { - const uint64_t payload = PayloadSize(); - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvContentEncAESSettings, - payload)) - return false; - - const int64_t payload_position = writer->Position(); - if (payload_position < 0) - return false; - - if (!WriteEbmlElement(writer, libwebm::kMkvAESSettingsCipherMode, - static_cast(cipher_mode_))) { - return false; - } - - const int64_t stop_position = writer->Position(); - if (stop_position < 0 || - stop_position - payload_position != static_cast(payload)) - return false; - - return true; -} - -uint64_t ContentEncAESSettings::PayloadSize() const { - uint64_t size = EbmlElementSize(libwebm::kMkvAESSettingsCipherMode, - static_cast(cipher_mode_)); - return size; -} - -/////////////////////////////////////////////////////////////// -// -// ContentEncoding Class - -ContentEncoding::ContentEncoding() - : enc_algo_(5), - enc_key_id_(NULL), - encoding_order_(0), - encoding_scope_(1), - encoding_type_(1), - enc_key_id_length_(0) {} - -ContentEncoding::~ContentEncoding() { delete[] enc_key_id_; } - -bool ContentEncoding::SetEncryptionID(const uint8_t* id, uint64_t length) { - if (!id || length < 1) - return false; - - delete[] enc_key_id_; - - enc_key_id_ = - new (std::nothrow) uint8_t[static_cast(length)]; // NOLINT - if (!enc_key_id_) - return false; - - memcpy(enc_key_id_, id, static_cast(length)); - enc_key_id_length_ = length; - - return true; -} - -uint64_t ContentEncoding::Size() const { - const uint64_t encryption_size = EncryptionSize(); - const uint64_t encoding_size = EncodingSize(0, encryption_size); - const uint64_t encodings_size = - EbmlMasterElementSize(libwebm::kMkvContentEncoding, encoding_size) + - encoding_size; - - return encodings_size; -} - -bool ContentEncoding::Write(IMkvWriter* writer) const { - const uint64_t encryption_size = EncryptionSize(); - const uint64_t encoding_size = EncodingSize(0, encryption_size); - const uint64_t size = - EbmlMasterElementSize(libwebm::kMkvContentEncoding, encoding_size) + - encoding_size; - - const int64_t payload_position = writer->Position(); - if (payload_position < 0) - return false; - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvContentEncoding, - encoding_size)) - return false; - if (!WriteEbmlElement(writer, libwebm::kMkvContentEncodingOrder, - static_cast(encoding_order_))) - return false; - if (!WriteEbmlElement(writer, libwebm::kMkvContentEncodingScope, - static_cast(encoding_scope_))) - return false; - if (!WriteEbmlElement(writer, libwebm::kMkvContentEncodingType, - static_cast(encoding_type_))) - return false; - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvContentEncryption, - encryption_size)) - return false; - if (!WriteEbmlElement(writer, libwebm::kMkvContentEncAlgo, - static_cast(enc_algo_))) { - return false; - } - if (!WriteEbmlElement(writer, libwebm::kMkvContentEncKeyID, enc_key_id_, - enc_key_id_length_)) - return false; - - if (!enc_aes_settings_.Write(writer)) - return false; - - const int64_t stop_position = writer->Position(); - if (stop_position < 0 || - stop_position - payload_position != static_cast(size)) - return false; - - return true; -} - -uint64_t ContentEncoding::EncodingSize(uint64_t compression_size, - uint64_t encryption_size) const { - // TODO(fgalligan): Add support for compression settings. - if (compression_size != 0) - return 0; - - uint64_t encoding_size = 0; - - if (encryption_size > 0) { - encoding_size += - EbmlMasterElementSize(libwebm::kMkvContentEncryption, encryption_size) + - encryption_size; - } - encoding_size += EbmlElementSize(libwebm::kMkvContentEncodingType, - static_cast(encoding_type_)); - encoding_size += EbmlElementSize(libwebm::kMkvContentEncodingScope, - static_cast(encoding_scope_)); - encoding_size += EbmlElementSize(libwebm::kMkvContentEncodingOrder, - static_cast(encoding_order_)); - - return encoding_size; -} - -uint64_t ContentEncoding::EncryptionSize() const { - const uint64_t aes_size = enc_aes_settings_.Size(); - - uint64_t encryption_size = EbmlElementSize(libwebm::kMkvContentEncKeyID, - enc_key_id_, enc_key_id_length_); - encryption_size += EbmlElementSize(libwebm::kMkvContentEncAlgo, - static_cast(enc_algo_)); - - return encryption_size + aes_size; -} - -/////////////////////////////////////////////////////////////// -// -// Track Class - -Track::Track(unsigned int* seed) - : codec_id_(NULL), - codec_private_(NULL), - language_(NULL), - max_block_additional_id_(0), - name_(NULL), - number_(0), - type_(0), - uid_(MakeUID(seed)), - codec_delay_(0), - seek_pre_roll_(0), - default_duration_(0), - codec_private_length_(0), - content_encoding_entries_(NULL), - content_encoding_entries_size_(0) {} - -Track::~Track() { - delete[] codec_id_; - delete[] codec_private_; - delete[] language_; - delete[] name_; - - if (content_encoding_entries_) { - for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) { - ContentEncoding* const encoding = content_encoding_entries_[i]; - delete encoding; - } - delete[] content_encoding_entries_; - } -} - -bool Track::AddContentEncoding() { - const uint32_t count = content_encoding_entries_size_ + 1; - - ContentEncoding** const content_encoding_entries = - new (std::nothrow) ContentEncoding*[count]; // NOLINT - if (!content_encoding_entries) - return false; - - ContentEncoding* const content_encoding = - new (std::nothrow) ContentEncoding(); // NOLINT - if (!content_encoding) { - delete[] content_encoding_entries; - return false; - } - - for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) { - content_encoding_entries[i] = content_encoding_entries_[i]; - } - - delete[] content_encoding_entries_; - - content_encoding_entries_ = content_encoding_entries; - content_encoding_entries_[content_encoding_entries_size_] = content_encoding; - content_encoding_entries_size_ = count; - return true; -} - -ContentEncoding* Track::GetContentEncodingByIndex(uint32_t index) const { - if (content_encoding_entries_ == NULL) - return NULL; - - if (index >= content_encoding_entries_size_) - return NULL; - - return content_encoding_entries_[index]; -} - -uint64_t Track::PayloadSize() const { - uint64_t size = - EbmlElementSize(libwebm::kMkvTrackNumber, static_cast(number_)); - size += EbmlElementSize(libwebm::kMkvTrackUID, static_cast(uid_)); - size += EbmlElementSize(libwebm::kMkvTrackType, static_cast(type_)); - if (codec_id_) - size += EbmlElementSize(libwebm::kMkvCodecID, codec_id_); - if (codec_private_) - size += EbmlElementSize(libwebm::kMkvCodecPrivate, codec_private_, - codec_private_length_); - if (language_) - size += EbmlElementSize(libwebm::kMkvLanguage, language_); - if (name_) - size += EbmlElementSize(libwebm::kMkvName, name_); - if (max_block_additional_id_) { - size += EbmlElementSize(libwebm::kMkvMaxBlockAdditionID, - static_cast(max_block_additional_id_)); - } - if (codec_delay_) { - size += EbmlElementSize(libwebm::kMkvCodecDelay, - static_cast(codec_delay_)); - } - if (seek_pre_roll_) { - size += EbmlElementSize(libwebm::kMkvSeekPreRoll, - static_cast(seek_pre_roll_)); - } - if (default_duration_) { - size += EbmlElementSize(libwebm::kMkvDefaultDuration, - static_cast(default_duration_)); - } - - if (content_encoding_entries_size_ > 0) { - uint64_t content_encodings_size = 0; - for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) { - ContentEncoding* const encoding = content_encoding_entries_[i]; - content_encodings_size += encoding->Size(); - } - - size += EbmlMasterElementSize(libwebm::kMkvContentEncodings, - content_encodings_size) + - content_encodings_size; - } - - return size; -} - -uint64_t Track::Size() const { - uint64_t size = PayloadSize(); - size += EbmlMasterElementSize(libwebm::kMkvTrackEntry, size); - return size; -} - -bool Track::Write(IMkvWriter* writer) const { - if (!writer) - return false; - - // mandatory elements without a default value. - if (!type_ || !codec_id_) - return false; - - // AV1 tracks require a CodecPrivate. See - // https://github.com/ietf-wg-cellar/matroska-specification/blob/HEAD/codec/av1.md - // TODO(tomfinegan): Update the above link to the AV1 Matroska mappings to - // point to a stable version once it is finalized, or our own WebM mappings - // page on webmproject.org should we decide to release them. - if (!strcmp(codec_id_, Tracks::kAv1CodecId) && !codec_private_) - return false; - - // |size| may be bigger than what is written out in this function because - // derived classes may write out more data in the Track element. - const uint64_t payload_size = PayloadSize(); - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvTrackEntry, payload_size)) - return false; - - uint64_t size = - EbmlElementSize(libwebm::kMkvTrackNumber, static_cast(number_)); - size += EbmlElementSize(libwebm::kMkvTrackUID, static_cast(uid_)); - size += EbmlElementSize(libwebm::kMkvTrackType, static_cast(type_)); - if (codec_id_) - size += EbmlElementSize(libwebm::kMkvCodecID, codec_id_); - if (codec_private_) - size += EbmlElementSize(libwebm::kMkvCodecPrivate, codec_private_, - static_cast(codec_private_length_)); - if (language_) - size += EbmlElementSize(libwebm::kMkvLanguage, language_); - if (name_) - size += EbmlElementSize(libwebm::kMkvName, name_); - if (max_block_additional_id_) - size += EbmlElementSize(libwebm::kMkvMaxBlockAdditionID, - static_cast(max_block_additional_id_)); - if (codec_delay_) - size += EbmlElementSize(libwebm::kMkvCodecDelay, - static_cast(codec_delay_)); - if (seek_pre_roll_) - size += EbmlElementSize(libwebm::kMkvSeekPreRoll, - static_cast(seek_pre_roll_)); - if (default_duration_) - size += EbmlElementSize(libwebm::kMkvDefaultDuration, - static_cast(default_duration_)); - - const int64_t payload_position = writer->Position(); - if (payload_position < 0) - return false; - - if (!WriteEbmlElement(writer, libwebm::kMkvTrackNumber, - static_cast(number_))) - return false; - if (!WriteEbmlElement(writer, libwebm::kMkvTrackUID, - static_cast(uid_))) - return false; - if (!WriteEbmlElement(writer, libwebm::kMkvTrackType, - static_cast(type_))) - return false; - if (max_block_additional_id_) { - if (!WriteEbmlElement(writer, libwebm::kMkvMaxBlockAdditionID, - static_cast(max_block_additional_id_))) { - return false; - } - } - if (codec_delay_) { - if (!WriteEbmlElement(writer, libwebm::kMkvCodecDelay, - static_cast(codec_delay_))) - return false; - } - if (seek_pre_roll_) { - if (!WriteEbmlElement(writer, libwebm::kMkvSeekPreRoll, - static_cast(seek_pre_roll_))) - return false; - } - if (default_duration_) { - if (!WriteEbmlElement(writer, libwebm::kMkvDefaultDuration, - static_cast(default_duration_))) - return false; - } - if (codec_id_) { - if (!WriteEbmlElement(writer, libwebm::kMkvCodecID, codec_id_)) - return false; - } - if (codec_private_) { - if (!WriteEbmlElement(writer, libwebm::kMkvCodecPrivate, codec_private_, - static_cast(codec_private_length_))) - return false; - } - if (language_) { - if (!WriteEbmlElement(writer, libwebm::kMkvLanguage, language_)) - return false; - } - if (name_) { - if (!WriteEbmlElement(writer, libwebm::kMkvName, name_)) - return false; - } - - int64_t stop_position = writer->Position(); - if (stop_position < 0 || - stop_position - payload_position != static_cast(size)) - return false; - - if (content_encoding_entries_size_ > 0) { - uint64_t content_encodings_size = 0; - for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) { - ContentEncoding* const encoding = content_encoding_entries_[i]; - content_encodings_size += encoding->Size(); - } - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvContentEncodings, - content_encodings_size)) - return false; - - for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) { - ContentEncoding* const encoding = content_encoding_entries_[i]; - if (!encoding->Write(writer)) - return false; - } - } - - stop_position = writer->Position(); - if (stop_position < 0) - return false; - return true; -} - -bool Track::SetCodecPrivate(const uint8_t* codec_private, uint64_t length) { - if (!codec_private || length < 1) - return false; - - delete[] codec_private_; - - codec_private_ = - new (std::nothrow) uint8_t[static_cast(length)]; // NOLINT - if (!codec_private_) - return false; - - memcpy(codec_private_, codec_private, static_cast(length)); - codec_private_length_ = length; - - return true; -} - -void Track::set_codec_id(const char* codec_id) { - if (codec_id) { - delete[] codec_id_; - - const size_t length = strlen(codec_id) + 1; - codec_id_ = new (std::nothrow) char[length]; // NOLINT - if (codec_id_) { - memcpy(codec_id_, codec_id, length - 1); - codec_id_[length - 1] = '\0'; - } - } -} - -// TODO(fgalligan): Vet the language parameter. -void Track::set_language(const char* language) { - if (language) { - delete[] language_; - - const size_t length = strlen(language) + 1; - language_ = new (std::nothrow) char[length]; // NOLINT - if (language_) { - memcpy(language_, language, length - 1); - language_[length - 1] = '\0'; - } - } -} - -void Track::set_name(const char* name) { - if (name) { - delete[] name_; - - const size_t length = strlen(name) + 1; - name_ = new (std::nothrow) char[length]; // NOLINT - if (name_) { - memcpy(name_, name, length - 1); - name_[length - 1] = '\0'; - } - } -} - -/////////////////////////////////////////////////////////////// -// -// Colour and its child elements - -uint64_t PrimaryChromaticity::PrimaryChromaticitySize( - libwebm::MkvId x_id, libwebm::MkvId y_id) const { - return EbmlElementSize(x_id, x_) + EbmlElementSize(y_id, y_); -} - -bool PrimaryChromaticity::Write(IMkvWriter* writer, libwebm::MkvId x_id, - libwebm::MkvId y_id) const { - if (!Valid()) { - return false; - } - return WriteEbmlElement(writer, x_id, x_) && - WriteEbmlElement(writer, y_id, y_); -} - -bool PrimaryChromaticity::Valid() const { - return (x_ >= kChromaticityMin && x_ <= kChromaticityMax && - y_ >= kChromaticityMin && y_ <= kChromaticityMax); -} - -uint64_t MasteringMetadata::MasteringMetadataSize() const { - uint64_t size = PayloadSize(); - - if (size > 0) - size += EbmlMasterElementSize(libwebm::kMkvMasteringMetadata, size); - - return size; -} - -bool MasteringMetadata::Valid() const { - if (luminance_min_ != kValueNotPresent) { - if (luminance_min_ < kMinLuminance || luminance_min_ > kMinLuminanceMax || - luminance_min_ > luminance_max_) { - return false; - } - } - if (luminance_max_ != kValueNotPresent) { - if (luminance_max_ < kMinLuminance || luminance_max_ > kMaxLuminanceMax || - luminance_max_ < luminance_min_) { - return false; - } - } - if (r_ && !r_->Valid()) - return false; - if (g_ && !g_->Valid()) - return false; - if (b_ && !b_->Valid()) - return false; - if (white_point_ && !white_point_->Valid()) - return false; - - return true; -} - -bool MasteringMetadata::Write(IMkvWriter* writer) const { - const uint64_t size = PayloadSize(); - - // Don't write an empty element. - if (size == 0) - return true; - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvMasteringMetadata, size)) - return false; - if (luminance_max_ != kValueNotPresent && - !WriteEbmlElement(writer, libwebm::kMkvLuminanceMax, luminance_max_)) { - return false; - } - if (luminance_min_ != kValueNotPresent && - !WriteEbmlElement(writer, libwebm::kMkvLuminanceMin, luminance_min_)) { - return false; - } - if (r_ && !r_->Write(writer, libwebm::kMkvPrimaryRChromaticityX, - libwebm::kMkvPrimaryRChromaticityY)) { - return false; - } - if (g_ && !g_->Write(writer, libwebm::kMkvPrimaryGChromaticityX, - libwebm::kMkvPrimaryGChromaticityY)) { - return false; - } - if (b_ && !b_->Write(writer, libwebm::kMkvPrimaryBChromaticityX, - libwebm::kMkvPrimaryBChromaticityY)) { - return false; - } - if (white_point_ && - !white_point_->Write(writer, libwebm::kMkvWhitePointChromaticityX, - libwebm::kMkvWhitePointChromaticityY)) { - return false; - } - - return true; -} - -bool MasteringMetadata::SetChromaticity( - const PrimaryChromaticity* r, const PrimaryChromaticity* g, - const PrimaryChromaticity* b, const PrimaryChromaticity* white_point) { - PrimaryChromaticityPtr r_ptr(nullptr); - if (r) { - if (!CopyChromaticity(r, &r_ptr)) - return false; - } - PrimaryChromaticityPtr g_ptr(nullptr); - if (g) { - if (!CopyChromaticity(g, &g_ptr)) - return false; - } - PrimaryChromaticityPtr b_ptr(nullptr); - if (b) { - if (!CopyChromaticity(b, &b_ptr)) - return false; - } - PrimaryChromaticityPtr wp_ptr(nullptr); - if (white_point) { - if (!CopyChromaticity(white_point, &wp_ptr)) - return false; - } - - r_ = r_ptr.release(); - g_ = g_ptr.release(); - b_ = b_ptr.release(); - white_point_ = wp_ptr.release(); - return true; -} - -uint64_t MasteringMetadata::PayloadSize() const { - uint64_t size = 0; - - if (luminance_max_ != kValueNotPresent) - size += EbmlElementSize(libwebm::kMkvLuminanceMax, luminance_max_); - if (luminance_min_ != kValueNotPresent) - size += EbmlElementSize(libwebm::kMkvLuminanceMin, luminance_min_); - - if (r_) { - size += r_->PrimaryChromaticitySize(libwebm::kMkvPrimaryRChromaticityX, - libwebm::kMkvPrimaryRChromaticityY); - } - if (g_) { - size += g_->PrimaryChromaticitySize(libwebm::kMkvPrimaryGChromaticityX, - libwebm::kMkvPrimaryGChromaticityY); - } - if (b_) { - size += b_->PrimaryChromaticitySize(libwebm::kMkvPrimaryBChromaticityX, - libwebm::kMkvPrimaryBChromaticityY); - } - if (white_point_) { - size += white_point_->PrimaryChromaticitySize( - libwebm::kMkvWhitePointChromaticityX, - libwebm::kMkvWhitePointChromaticityY); - } - - return size; -} - -uint64_t Colour::ColourSize() const { - uint64_t size = PayloadSize(); - - if (size > 0) - size += EbmlMasterElementSize(libwebm::kMkvColour, size); - - return size; -} - -bool Colour::Valid() const { - if (mastering_metadata_ && !mastering_metadata_->Valid()) - return false; - if (matrix_coefficients_ != kValueNotPresent && - !IsMatrixCoefficientsValueValid(matrix_coefficients_)) { - return false; - } - if (chroma_siting_horz_ != kValueNotPresent && - !IsChromaSitingHorzValueValid(chroma_siting_horz_)) { - return false; - } - if (chroma_siting_vert_ != kValueNotPresent && - !IsChromaSitingVertValueValid(chroma_siting_vert_)) { - return false; - } - if (range_ != kValueNotPresent && !IsColourRangeValueValid(range_)) - return false; - if (transfer_characteristics_ != kValueNotPresent && - !IsTransferCharacteristicsValueValid(transfer_characteristics_)) { - return false; - } - if (primaries_ != kValueNotPresent && !IsPrimariesValueValid(primaries_)) - return false; - - return true; -} - -bool Colour::Write(IMkvWriter* writer) const { - const uint64_t size = PayloadSize(); - - // Don't write an empty element. - if (size == 0) - return true; - - // Don't write an invalid element. - if (!Valid()) - return false; - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvColour, size)) - return false; - - if (matrix_coefficients_ != kValueNotPresent && - !WriteEbmlElement(writer, libwebm::kMkvMatrixCoefficients, - static_cast(matrix_coefficients_))) { - return false; - } - if (bits_per_channel_ != kValueNotPresent && - !WriteEbmlElement(writer, libwebm::kMkvBitsPerChannel, - static_cast(bits_per_channel_))) { - return false; - } - if (chroma_subsampling_horz_ != kValueNotPresent && - !WriteEbmlElement(writer, libwebm::kMkvChromaSubsamplingHorz, - static_cast(chroma_subsampling_horz_))) { - return false; - } - if (chroma_subsampling_vert_ != kValueNotPresent && - !WriteEbmlElement(writer, libwebm::kMkvChromaSubsamplingVert, - static_cast(chroma_subsampling_vert_))) { - return false; - } - - if (cb_subsampling_horz_ != kValueNotPresent && - !WriteEbmlElement(writer, libwebm::kMkvCbSubsamplingHorz, - static_cast(cb_subsampling_horz_))) { - return false; - } - if (cb_subsampling_vert_ != kValueNotPresent && - !WriteEbmlElement(writer, libwebm::kMkvCbSubsamplingVert, - static_cast(cb_subsampling_vert_))) { - return false; - } - if (chroma_siting_horz_ != kValueNotPresent && - !WriteEbmlElement(writer, libwebm::kMkvChromaSitingHorz, - static_cast(chroma_siting_horz_))) { - return false; - } - if (chroma_siting_vert_ != kValueNotPresent && - !WriteEbmlElement(writer, libwebm::kMkvChromaSitingVert, - static_cast(chroma_siting_vert_))) { - return false; - } - if (range_ != kValueNotPresent && - !WriteEbmlElement(writer, libwebm::kMkvRange, - static_cast(range_))) { - return false; - } - if (transfer_characteristics_ != kValueNotPresent && - !WriteEbmlElement(writer, libwebm::kMkvTransferCharacteristics, - static_cast(transfer_characteristics_))) { - return false; - } - if (primaries_ != kValueNotPresent && - !WriteEbmlElement(writer, libwebm::kMkvPrimaries, - static_cast(primaries_))) { - return false; - } - if (max_cll_ != kValueNotPresent && - !WriteEbmlElement(writer, libwebm::kMkvMaxCLL, - static_cast(max_cll_))) { - return false; - } - if (max_fall_ != kValueNotPresent && - !WriteEbmlElement(writer, libwebm::kMkvMaxFALL, - static_cast(max_fall_))) { - return false; - } - - if (mastering_metadata_ && !mastering_metadata_->Write(writer)) - return false; - - return true; -} - -bool Colour::SetMasteringMetadata(const MasteringMetadata& mastering_metadata) { - std::unique_ptr mm_ptr(new MasteringMetadata()); - if (!mm_ptr.get()) - return false; - - mm_ptr->set_luminance_max(mastering_metadata.luminance_max()); - mm_ptr->set_luminance_min(mastering_metadata.luminance_min()); - - if (!mm_ptr->SetChromaticity(mastering_metadata.r(), mastering_metadata.g(), - mastering_metadata.b(), - mastering_metadata.white_point())) { - return false; - } - - delete mastering_metadata_; - mastering_metadata_ = mm_ptr.release(); - return true; -} - -uint64_t Colour::PayloadSize() const { - uint64_t size = 0; - - if (matrix_coefficients_ != kValueNotPresent) { - size += EbmlElementSize(libwebm::kMkvMatrixCoefficients, - static_cast(matrix_coefficients_)); - } - if (bits_per_channel_ != kValueNotPresent) { - size += EbmlElementSize(libwebm::kMkvBitsPerChannel, - static_cast(bits_per_channel_)); - } - if (chroma_subsampling_horz_ != kValueNotPresent) { - size += EbmlElementSize(libwebm::kMkvChromaSubsamplingHorz, - static_cast(chroma_subsampling_horz_)); - } - if (chroma_subsampling_vert_ != kValueNotPresent) { - size += EbmlElementSize(libwebm::kMkvChromaSubsamplingVert, - static_cast(chroma_subsampling_vert_)); - } - if (cb_subsampling_horz_ != kValueNotPresent) { - size += EbmlElementSize(libwebm::kMkvCbSubsamplingHorz, - static_cast(cb_subsampling_horz_)); - } - if (cb_subsampling_vert_ != kValueNotPresent) { - size += EbmlElementSize(libwebm::kMkvCbSubsamplingVert, - static_cast(cb_subsampling_vert_)); - } - if (chroma_siting_horz_ != kValueNotPresent) { - size += EbmlElementSize(libwebm::kMkvChromaSitingHorz, - static_cast(chroma_siting_horz_)); - } - if (chroma_siting_vert_ != kValueNotPresent) { - size += EbmlElementSize(libwebm::kMkvChromaSitingVert, - static_cast(chroma_siting_vert_)); - } - if (range_ != kValueNotPresent) { - size += EbmlElementSize(libwebm::kMkvRange, static_cast(range_)); - } - if (transfer_characteristics_ != kValueNotPresent) { - size += EbmlElementSize(libwebm::kMkvTransferCharacteristics, - static_cast(transfer_characteristics_)); - } - if (primaries_ != kValueNotPresent) { - size += EbmlElementSize(libwebm::kMkvPrimaries, - static_cast(primaries_)); - } - if (max_cll_ != kValueNotPresent) { - size += EbmlElementSize(libwebm::kMkvMaxCLL, static_cast(max_cll_)); - } - if (max_fall_ != kValueNotPresent) { - size += - EbmlElementSize(libwebm::kMkvMaxFALL, static_cast(max_fall_)); - } - - if (mastering_metadata_) - size += mastering_metadata_->MasteringMetadataSize(); - - return size; -} - -/////////////////////////////////////////////////////////////// -// -// Projection element - -uint64_t Projection::ProjectionSize() const { - uint64_t size = PayloadSize(); - - if (size > 0) - size += EbmlMasterElementSize(libwebm::kMkvProjection, size); - - return size; -} - -bool Projection::Write(IMkvWriter* writer) const { - const uint64_t size = PayloadSize(); - - // Don't write an empty element. - if (size == 0) - return true; - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvProjection, size)) - return false; - - if (!WriteEbmlElement(writer, libwebm::kMkvProjectionType, - static_cast(type_))) { - return false; - } - - if (private_data_length_ > 0 && private_data_ != NULL && - !WriteEbmlElement(writer, libwebm::kMkvProjectionPrivate, private_data_, - private_data_length_)) { - return false; - } - - if (!WriteEbmlElement(writer, libwebm::kMkvProjectionPoseYaw, pose_yaw_)) - return false; - - if (!WriteEbmlElement(writer, libwebm::kMkvProjectionPosePitch, - pose_pitch_)) { - return false; - } - - if (!WriteEbmlElement(writer, libwebm::kMkvProjectionPoseRoll, pose_roll_)) { - return false; - } - - return true; -} - -bool Projection::SetProjectionPrivate(const uint8_t* data, - uint64_t data_length) { - if (data == NULL || data_length == 0) { - return false; - } - - if (data_length != static_cast(data_length)) { - return false; - } - - uint8_t* new_private_data = - new (std::nothrow) uint8_t[static_cast(data_length)]; - if (new_private_data == NULL) { - return false; - } - - delete[] private_data_; - private_data_ = new_private_data; - private_data_length_ = data_length; - memcpy(private_data_, data, static_cast(data_length)); - - return true; -} - -uint64_t Projection::PayloadSize() const { - uint64_t size = - EbmlElementSize(libwebm::kMkvProjection, static_cast(type_)); - - if (private_data_length_ > 0 && private_data_ != NULL) { - size += EbmlElementSize(libwebm::kMkvProjectionPrivate, private_data_, - private_data_length_); - } - - size += EbmlElementSize(libwebm::kMkvProjectionPoseYaw, pose_yaw_); - size += EbmlElementSize(libwebm::kMkvProjectionPosePitch, pose_pitch_); - size += EbmlElementSize(libwebm::kMkvProjectionPoseRoll, pose_roll_); - - return size; -} - -/////////////////////////////////////////////////////////////// -// -// VideoTrack Class - -VideoTrack::VideoTrack(unsigned int* seed) - : Track(seed), - display_height_(0), - display_width_(0), - pixel_height_(0), - pixel_width_(0), - crop_left_(0), - crop_right_(0), - crop_top_(0), - crop_bottom_(0), - frame_rate_(0.0), - height_(0), - stereo_mode_(0), - alpha_mode_(0), - width_(0), - colour_space_(NULL), - colour_(NULL), - projection_(NULL) {} - -VideoTrack::~VideoTrack() { - delete colour_; - delete projection_; -} - -bool VideoTrack::SetStereoMode(uint64_t stereo_mode) { - if (stereo_mode != kMono && stereo_mode != kSideBySideLeftIsFirst && - stereo_mode != kTopBottomRightIsFirst && - stereo_mode != kTopBottomLeftIsFirst && - stereo_mode != kSideBySideRightIsFirst) - return false; - - stereo_mode_ = stereo_mode; - return true; -} - -bool VideoTrack::SetAlphaMode(uint64_t alpha_mode) { - if (alpha_mode != kNoAlpha && alpha_mode != kAlpha) - return false; - - alpha_mode_ = alpha_mode; - return true; -} - -uint64_t VideoTrack::PayloadSize() const { - const uint64_t parent_size = Track::PayloadSize(); - - uint64_t size = VideoPayloadSize(); - size += EbmlMasterElementSize(libwebm::kMkvVideo, size); - - return parent_size + size; -} - -bool VideoTrack::Write(IMkvWriter* writer) const { - if (!Track::Write(writer)) - return false; - - const uint64_t size = VideoPayloadSize(); - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvVideo, size)) - return false; - - const int64_t payload_position = writer->Position(); - if (payload_position < 0) - return false; - - if (!WriteEbmlElement( - writer, libwebm::kMkvPixelWidth, - static_cast((pixel_width_ > 0) ? pixel_width_ : width_))) - return false; - if (!WriteEbmlElement( - writer, libwebm::kMkvPixelHeight, - static_cast((pixel_height_ > 0) ? pixel_height_ : height_))) - return false; - if (display_width_ > 0) { - if (!WriteEbmlElement(writer, libwebm::kMkvDisplayWidth, - static_cast(display_width_))) - return false; - } - if (display_height_ > 0) { - if (!WriteEbmlElement(writer, libwebm::kMkvDisplayHeight, - static_cast(display_height_))) - return false; - } - if (crop_left_ > 0) { - if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropLeft, - static_cast(crop_left_))) - return false; - } - if (crop_right_ > 0) { - if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropRight, - static_cast(crop_right_))) - return false; - } - if (crop_top_ > 0) { - if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropTop, - static_cast(crop_top_))) - return false; - } - if (crop_bottom_ > 0) { - if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropBottom, - static_cast(crop_bottom_))) - return false; - } - if (stereo_mode_ > kMono) { - if (!WriteEbmlElement(writer, libwebm::kMkvStereoMode, - static_cast(stereo_mode_))) - return false; - } - if (alpha_mode_ > kNoAlpha) { - if (!WriteEbmlElement(writer, libwebm::kMkvAlphaMode, - static_cast(alpha_mode_))) - return false; - } - if (colour_space_) { - if (!WriteEbmlElement(writer, libwebm::kMkvColourSpace, colour_space_)) - return false; - } - if (frame_rate_ > 0.0) { - if (!WriteEbmlElement(writer, libwebm::kMkvFrameRate, - static_cast(frame_rate_))) { - return false; - } - } - if (colour_) { - if (!colour_->Write(writer)) - return false; - } - if (projection_) { - if (!projection_->Write(writer)) - return false; - } - - const int64_t stop_position = writer->Position(); - if (stop_position < 0 || - stop_position - payload_position != static_cast(size)) { - return false; - } - - return true; -} - -void VideoTrack::set_colour_space(const char* colour_space) { - if (colour_space) { - delete[] colour_space_; - - const size_t length = strlen(colour_space) + 1; - colour_space_ = new (std::nothrow) char[length]; // NOLINT - if (colour_space_) { - memcpy(colour_space_, colour_space, length - 1); - colour_space_[length - 1] = '\0'; - } - } -} - -bool VideoTrack::SetColour(const Colour& colour) { - std::unique_ptr colour_ptr(new Colour()); - if (!colour_ptr.get()) - return false; - - if (colour.mastering_metadata()) { - if (!colour_ptr->SetMasteringMetadata(*colour.mastering_metadata())) - return false; - } - - colour_ptr->set_matrix_coefficients(colour.matrix_coefficients()); - colour_ptr->set_bits_per_channel(colour.bits_per_channel()); - colour_ptr->set_chroma_subsampling_horz(colour.chroma_subsampling_horz()); - colour_ptr->set_chroma_subsampling_vert(colour.chroma_subsampling_vert()); - colour_ptr->set_cb_subsampling_horz(colour.cb_subsampling_horz()); - colour_ptr->set_cb_subsampling_vert(colour.cb_subsampling_vert()); - colour_ptr->set_chroma_siting_horz(colour.chroma_siting_horz()); - colour_ptr->set_chroma_siting_vert(colour.chroma_siting_vert()); - colour_ptr->set_range(colour.range()); - colour_ptr->set_transfer_characteristics(colour.transfer_characteristics()); - colour_ptr->set_primaries(colour.primaries()); - colour_ptr->set_max_cll(colour.max_cll()); - colour_ptr->set_max_fall(colour.max_fall()); - delete colour_; - colour_ = colour_ptr.release(); - return true; -} - -bool VideoTrack::SetProjection(const Projection& projection) { - std::unique_ptr projection_ptr(new Projection()); - if (!projection_ptr.get()) - return false; - - if (projection.private_data()) { - if (!projection_ptr->SetProjectionPrivate( - projection.private_data(), projection.private_data_length())) { - return false; - } - } - - projection_ptr->set_type(projection.type()); - projection_ptr->set_pose_yaw(projection.pose_yaw()); - projection_ptr->set_pose_pitch(projection.pose_pitch()); - projection_ptr->set_pose_roll(projection.pose_roll()); - delete projection_; - projection_ = projection_ptr.release(); - return true; -} - -uint64_t VideoTrack::VideoPayloadSize() const { - uint64_t size = EbmlElementSize( - libwebm::kMkvPixelWidth, - static_cast((pixel_width_ > 0) ? pixel_width_ : width_)); - size += EbmlElementSize( - libwebm::kMkvPixelHeight, - static_cast((pixel_height_ > 0) ? pixel_height_ : height_)); - if (display_width_ > 0) - size += EbmlElementSize(libwebm::kMkvDisplayWidth, - static_cast(display_width_)); - if (display_height_ > 0) - size += EbmlElementSize(libwebm::kMkvDisplayHeight, - static_cast(display_height_)); - if (crop_left_ > 0) - size += EbmlElementSize(libwebm::kMkvPixelCropLeft, - static_cast(crop_left_)); - if (crop_right_ > 0) - size += EbmlElementSize(libwebm::kMkvPixelCropRight, - static_cast(crop_right_)); - if (crop_top_ > 0) - size += EbmlElementSize(libwebm::kMkvPixelCropTop, - static_cast(crop_top_)); - if (crop_bottom_ > 0) - size += EbmlElementSize(libwebm::kMkvPixelCropBottom, - static_cast(crop_bottom_)); - if (stereo_mode_ > kMono) - size += EbmlElementSize(libwebm::kMkvStereoMode, - static_cast(stereo_mode_)); - if (alpha_mode_ > kNoAlpha) - size += EbmlElementSize(libwebm::kMkvAlphaMode, - static_cast(alpha_mode_)); - if (frame_rate_ > 0.0) - size += EbmlElementSize(libwebm::kMkvFrameRate, - static_cast(frame_rate_)); - if (colour_space_) - size += EbmlElementSize(libwebm::kMkvColourSpace, colour_space_); - if (colour_) - size += colour_->ColourSize(); - if (projection_) - size += projection_->ProjectionSize(); - - return size; -} - -/////////////////////////////////////////////////////////////// -// -// AudioTrack Class - -AudioTrack::AudioTrack(unsigned int* seed) - : Track(seed), bit_depth_(0), channels_(1), sample_rate_(0.0) {} - -AudioTrack::~AudioTrack() {} - -uint64_t AudioTrack::PayloadSize() const { - const uint64_t parent_size = Track::PayloadSize(); - - uint64_t size = EbmlElementSize(libwebm::kMkvSamplingFrequency, - static_cast(sample_rate_)); - size += - EbmlElementSize(libwebm::kMkvChannels, static_cast(channels_)); - if (bit_depth_ > 0) - size += - EbmlElementSize(libwebm::kMkvBitDepth, static_cast(bit_depth_)); - size += EbmlMasterElementSize(libwebm::kMkvAudio, size); - - return parent_size + size; -} - -bool AudioTrack::Write(IMkvWriter* writer) const { - if (!Track::Write(writer)) - return false; - - // Calculate AudioSettings size. - uint64_t size = EbmlElementSize(libwebm::kMkvSamplingFrequency, - static_cast(sample_rate_)); - size += - EbmlElementSize(libwebm::kMkvChannels, static_cast(channels_)); - if (bit_depth_ > 0) - size += - EbmlElementSize(libwebm::kMkvBitDepth, static_cast(bit_depth_)); - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvAudio, size)) - return false; - - const int64_t payload_position = writer->Position(); - if (payload_position < 0) - return false; - - if (!WriteEbmlElement(writer, libwebm::kMkvSamplingFrequency, - static_cast(sample_rate_))) - return false; - if (!WriteEbmlElement(writer, libwebm::kMkvChannels, - static_cast(channels_))) - return false; - if (bit_depth_ > 0) - if (!WriteEbmlElement(writer, libwebm::kMkvBitDepth, - static_cast(bit_depth_))) - return false; - - const int64_t stop_position = writer->Position(); - if (stop_position < 0 || - stop_position - payload_position != static_cast(size)) - return false; - - return true; -} - -/////////////////////////////////////////////////////////////// -// -// Tracks Class - -const char Tracks::kOpusCodecId[] = "A_OPUS"; -const char Tracks::kVorbisCodecId[] = "A_VORBIS"; -const char Tracks::kAv1CodecId[] = "V_AV1"; -const char Tracks::kVp8CodecId[] = "V_VP8"; -const char Tracks::kVp9CodecId[] = "V_VP9"; -const char Tracks::kWebVttCaptionsId[] = "D_WEBVTT/CAPTIONS"; -const char Tracks::kWebVttDescriptionsId[] = "D_WEBVTT/DESCRIPTIONS"; -const char Tracks::kWebVttMetadataId[] = "D_WEBVTT/METADATA"; -const char Tracks::kWebVttSubtitlesId[] = "D_WEBVTT/SUBTITLES"; - -Tracks::Tracks() - : track_entries_(NULL), track_entries_size_(0), wrote_tracks_(false) {} - -Tracks::~Tracks() { - if (track_entries_) { - for (uint32_t i = 0; i < track_entries_size_; ++i) { - Track* const track = track_entries_[i]; - delete track; - } - delete[] track_entries_; - } -} - -bool Tracks::AddTrack(Track* track, int32_t number) { - if (number < 0 || wrote_tracks_) - return false; - - // This muxer only supports track numbers in the range [1, 126], in - // order to be able (to use Matroska integer representation) to - // serialize the block header (of which the track number is a part) - // for a frame using exactly 4 bytes. - - if (number > 0x7E) - return false; - - uint32_t track_num = number; - - if (track_num > 0) { - // Check to make sure a track does not already have |track_num|. - for (uint32_t i = 0; i < track_entries_size_; ++i) { - if (track_entries_[i]->number() == track_num) - return false; - } - } - - const uint32_t count = track_entries_size_ + 1; - - Track** const track_entries = new (std::nothrow) Track*[count]; // NOLINT - if (!track_entries) - return false; - - for (uint32_t i = 0; i < track_entries_size_; ++i) { - track_entries[i] = track_entries_[i]; - } - - delete[] track_entries_; - - // Find the lowest availible track number > 0. - if (track_num == 0) { - track_num = count; - - // Check to make sure a track does not already have |track_num|. - bool exit = false; - do { - exit = true; - for (uint32_t i = 0; i < track_entries_size_; ++i) { - if (track_entries[i]->number() == track_num) { - track_num++; - exit = false; - break; - } - } - } while (!exit); - } - track->set_number(track_num); - - track_entries_ = track_entries; - track_entries_[track_entries_size_] = track; - track_entries_size_ = count; - return true; -} - -const Track* Tracks::GetTrackByIndex(uint32_t index) const { - if (track_entries_ == NULL) - return NULL; - - if (index >= track_entries_size_) - return NULL; - - return track_entries_[index]; -} - -Track* Tracks::GetTrackByNumber(uint64_t track_number) const { - const int32_t count = track_entries_size(); - for (int32_t i = 0; i < count; ++i) { - if (track_entries_[i]->number() == track_number) - return track_entries_[i]; - } - - return NULL; -} - -bool Tracks::TrackIsAudio(uint64_t track_number) const { - const Track* const track = GetTrackByNumber(track_number); - - if (track->type() == kAudio) - return true; - - return false; -} - -bool Tracks::TrackIsVideo(uint64_t track_number) const { - const Track* const track = GetTrackByNumber(track_number); - - if (track->type() == kVideo) - return true; - - return false; -} - -bool Tracks::Write(IMkvWriter* writer) const { - uint64_t size = 0; - const int32_t count = track_entries_size(); - for (int32_t i = 0; i < count; ++i) { - const Track* const track = GetTrackByIndex(i); - - if (!track) - return false; - - size += track->Size(); - } - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvTracks, size)) - return false; - - const int64_t payload_position = writer->Position(); - if (payload_position < 0) - return false; - - for (int32_t i = 0; i < count; ++i) { - const Track* const track = GetTrackByIndex(i); - if (!track->Write(writer)) - return false; - } - - const int64_t stop_position = writer->Position(); - if (stop_position < 0 || - stop_position - payload_position != static_cast(size)) - return false; - - wrote_tracks_ = true; - return true; -} - -/////////////////////////////////////////////////////////////// -// -// Chapter Class - -bool Chapter::set_id(const char* id) { return StrCpy(id, &id_); } - -void Chapter::set_time(const Segment& segment, uint64_t start_ns, - uint64_t end_ns) { - const SegmentInfo* const info = segment.GetSegmentInfo(); - const uint64_t timecode_scale = info->timecode_scale(); - start_timecode_ = start_ns / timecode_scale; - end_timecode_ = end_ns / timecode_scale; -} - -bool Chapter::add_string(const char* title, const char* language, - const char* country) { - if (!ExpandDisplaysArray()) - return false; - - Display& d = displays_[displays_count_++]; - d.Init(); - - if (!d.set_title(title)) - return false; - - if (!d.set_language(language)) - return false; - - if (!d.set_country(country)) - return false; - - return true; -} - -Chapter::Chapter() { - // This ctor only constructs the object. Proper initialization is - // done in Init() (called in Chapters::AddChapter()). The only - // reason we bother implementing this ctor is because we had to - // declare it as private (along with the dtor), in order to prevent - // clients from creating Chapter instances (a privelege we grant - // only to the Chapters class). Doing no initialization here also - // means that creating arrays of chapter objects is more efficient, - // because we only initialize each new chapter object as it becomes - // active on the array. -} - -Chapter::~Chapter() {} - -void Chapter::Init(unsigned int* seed) { - id_ = NULL; - start_timecode_ = 0; - end_timecode_ = 0; - displays_ = NULL; - displays_size_ = 0; - displays_count_ = 0; - uid_ = MakeUID(seed); -} - -void Chapter::ShallowCopy(Chapter* dst) const { - dst->id_ = id_; - dst->start_timecode_ = start_timecode_; - dst->end_timecode_ = end_timecode_; - dst->uid_ = uid_; - dst->displays_ = displays_; - dst->displays_size_ = displays_size_; - dst->displays_count_ = displays_count_; -} - -void Chapter::Clear() { - StrCpy(NULL, &id_); - - while (displays_count_ > 0) { - Display& d = displays_[--displays_count_]; - d.Clear(); - } - - delete[] displays_; - displays_ = NULL; - - displays_size_ = 0; -} - -bool Chapter::ExpandDisplaysArray() { - if (displays_size_ > displays_count_) - return true; // nothing to do yet - - const int size = (displays_size_ == 0) ? 1 : 2 * displays_size_; - - Display* const displays = new (std::nothrow) Display[size]; // NOLINT - if (displays == NULL) - return false; - - for (int idx = 0; idx < displays_count_; ++idx) { - displays[idx] = displays_[idx]; // shallow copy - } - - delete[] displays_; - - displays_ = displays; - displays_size_ = size; - - return true; -} - -uint64_t Chapter::WriteAtom(IMkvWriter* writer) const { - uint64_t payload_size = - EbmlElementSize(libwebm::kMkvChapterStringUID, id_) + - EbmlElementSize(libwebm::kMkvChapterUID, static_cast(uid_)) + - EbmlElementSize(libwebm::kMkvChapterTimeStart, - static_cast(start_timecode_)) + - EbmlElementSize(libwebm::kMkvChapterTimeEnd, - static_cast(end_timecode_)); - - for (int idx = 0; idx < displays_count_; ++idx) { - const Display& d = displays_[idx]; - payload_size += d.WriteDisplay(NULL); - } - - const uint64_t atom_size = - EbmlMasterElementSize(libwebm::kMkvChapterAtom, payload_size) + - payload_size; - - if (writer == NULL) - return atom_size; - - const int64_t start = writer->Position(); - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvChapterAtom, payload_size)) - return 0; - - if (!WriteEbmlElement(writer, libwebm::kMkvChapterStringUID, id_)) - return 0; - - if (!WriteEbmlElement(writer, libwebm::kMkvChapterUID, - static_cast(uid_))) - return 0; - - if (!WriteEbmlElement(writer, libwebm::kMkvChapterTimeStart, - static_cast(start_timecode_))) - return 0; - - if (!WriteEbmlElement(writer, libwebm::kMkvChapterTimeEnd, - static_cast(end_timecode_))) - return 0; - - for (int idx = 0; idx < displays_count_; ++idx) { - const Display& d = displays_[idx]; - - if (!d.WriteDisplay(writer)) - return 0; - } - - const int64_t stop = writer->Position(); - - if (stop >= start && uint64_t(stop - start) != atom_size) - return 0; - - return atom_size; -} - -void Chapter::Display::Init() { - title_ = NULL; - language_ = NULL; - country_ = NULL; -} - -void Chapter::Display::Clear() { - StrCpy(NULL, &title_); - StrCpy(NULL, &language_); - StrCpy(NULL, &country_); -} - -bool Chapter::Display::set_title(const char* title) { - return StrCpy(title, &title_); -} - -bool Chapter::Display::set_language(const char* language) { - return StrCpy(language, &language_); -} - -bool Chapter::Display::set_country(const char* country) { - return StrCpy(country, &country_); -} - -uint64_t Chapter::Display::WriteDisplay(IMkvWriter* writer) const { - uint64_t payload_size = EbmlElementSize(libwebm::kMkvChapString, title_); - - if (language_) - payload_size += EbmlElementSize(libwebm::kMkvChapLanguage, language_); - - if (country_) - payload_size += EbmlElementSize(libwebm::kMkvChapCountry, country_); - - const uint64_t display_size = - EbmlMasterElementSize(libwebm::kMkvChapterDisplay, payload_size) + - payload_size; - - if (writer == NULL) - return display_size; - - const int64_t start = writer->Position(); - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvChapterDisplay, - payload_size)) - return 0; - - if (!WriteEbmlElement(writer, libwebm::kMkvChapString, title_)) - return 0; - - if (language_) { - if (!WriteEbmlElement(writer, libwebm::kMkvChapLanguage, language_)) - return 0; - } - - if (country_) { - if (!WriteEbmlElement(writer, libwebm::kMkvChapCountry, country_)) - return 0; - } - - const int64_t stop = writer->Position(); - - if (stop >= start && uint64_t(stop - start) != display_size) - return 0; - - return display_size; -} - -/////////////////////////////////////////////////////////////// -// -// Chapters Class - -Chapters::Chapters() : chapters_size_(0), chapters_count_(0), chapters_(NULL) {} - -Chapters::~Chapters() { - while (chapters_count_ > 0) { - Chapter& chapter = chapters_[--chapters_count_]; - chapter.Clear(); - } - - delete[] chapters_; - chapters_ = NULL; -} - -int Chapters::Count() const { return chapters_count_; } - -Chapter* Chapters::AddChapter(unsigned int* seed) { - if (!ExpandChaptersArray()) - return NULL; - - Chapter& chapter = chapters_[chapters_count_++]; - chapter.Init(seed); - - return &chapter; -} - -bool Chapters::Write(IMkvWriter* writer) const { - if (writer == NULL) - return false; - - const uint64_t payload_size = WriteEdition(NULL); // return size only - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvChapters, payload_size)) - return false; - - const int64_t start = writer->Position(); - - if (WriteEdition(writer) == 0) // error - return false; - - const int64_t stop = writer->Position(); - - if (stop >= start && uint64_t(stop - start) != payload_size) - return false; - - return true; -} - -bool Chapters::ExpandChaptersArray() { - if (chapters_size_ > chapters_count_) - return true; // nothing to do yet - - const int size = (chapters_size_ == 0) ? 1 : 2 * chapters_size_; - - Chapter* const chapters = new (std::nothrow) Chapter[size]; // NOLINT - if (chapters == NULL) - return false; - - for (int idx = 0; idx < chapters_count_; ++idx) { - const Chapter& src = chapters_[idx]; - Chapter* const dst = chapters + idx; - src.ShallowCopy(dst); - } - - delete[] chapters_; - - chapters_ = chapters; - chapters_size_ = size; - - return true; -} - -uint64_t Chapters::WriteEdition(IMkvWriter* writer) const { - uint64_t payload_size = 0; - - for (int idx = 0; idx < chapters_count_; ++idx) { - const Chapter& chapter = chapters_[idx]; - payload_size += chapter.WriteAtom(NULL); - } - - const uint64_t edition_size = - EbmlMasterElementSize(libwebm::kMkvEditionEntry, payload_size) + - payload_size; - - if (writer == NULL) // return size only - return edition_size; - - const int64_t start = writer->Position(); - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvEditionEntry, payload_size)) - return 0; // error - - for (int idx = 0; idx < chapters_count_; ++idx) { - const Chapter& chapter = chapters_[idx]; - - const uint64_t chapter_size = chapter.WriteAtom(writer); - if (chapter_size == 0) // error - return 0; - } - - const int64_t stop = writer->Position(); - - if (stop >= start && uint64_t(stop - start) != edition_size) - return 0; - - return edition_size; -} - -// Tag Class - -bool Tag::add_simple_tag(const char* tag_name, const char* tag_string) { - if (!ExpandSimpleTagsArray()) - return false; - - SimpleTag& st = simple_tags_[simple_tags_count_++]; - st.Init(); - - if (!st.set_tag_name(tag_name)) - return false; - - if (!st.set_tag_string(tag_string)) - return false; - - return true; -} - -Tag::Tag() { - simple_tags_ = NULL; - simple_tags_size_ = 0; - simple_tags_count_ = 0; -} - -Tag::~Tag() {} - -void Tag::ShallowCopy(Tag* dst) const { - dst->simple_tags_ = simple_tags_; - dst->simple_tags_size_ = simple_tags_size_; - dst->simple_tags_count_ = simple_tags_count_; -} - -void Tag::Clear() { - while (simple_tags_count_ > 0) { - SimpleTag& st = simple_tags_[--simple_tags_count_]; - st.Clear(); - } - - delete[] simple_tags_; - simple_tags_ = NULL; - - simple_tags_size_ = 0; -} - -bool Tag::ExpandSimpleTagsArray() { - if (simple_tags_size_ > simple_tags_count_) - return true; // nothing to do yet - - const int size = (simple_tags_size_ == 0) ? 1 : 2 * simple_tags_size_; - - SimpleTag* const simple_tags = new (std::nothrow) SimpleTag[size]; // NOLINT - if (simple_tags == NULL) - return false; - - for (int idx = 0; idx < simple_tags_count_; ++idx) { - simple_tags[idx] = simple_tags_[idx]; // shallow copy - } - - delete[] simple_tags_; - - simple_tags_ = simple_tags; - simple_tags_size_ = size; - - return true; -} - -uint64_t Tag::Write(IMkvWriter* writer) const { - uint64_t payload_size = 0; - - for (int idx = 0; idx < simple_tags_count_; ++idx) { - const SimpleTag& st = simple_tags_[idx]; - payload_size += st.Write(NULL); - } - - const uint64_t tag_size = - EbmlMasterElementSize(libwebm::kMkvTag, payload_size) + payload_size; - - if (writer == NULL) - return tag_size; - - const int64_t start = writer->Position(); - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvTag, payload_size)) - return 0; - - for (int idx = 0; idx < simple_tags_count_; ++idx) { - const SimpleTag& st = simple_tags_[idx]; - - if (!st.Write(writer)) - return 0; - } - - const int64_t stop = writer->Position(); - - if (stop >= start && uint64_t(stop - start) != tag_size) - return 0; - - return tag_size; -} - -// Tag::SimpleTag - -void Tag::SimpleTag::Init() { - tag_name_ = NULL; - tag_string_ = NULL; -} - -void Tag::SimpleTag::Clear() { - StrCpy(NULL, &tag_name_); - StrCpy(NULL, &tag_string_); -} - -bool Tag::SimpleTag::set_tag_name(const char* tag_name) { - return StrCpy(tag_name, &tag_name_); -} - -bool Tag::SimpleTag::set_tag_string(const char* tag_string) { - return StrCpy(tag_string, &tag_string_); -} - -uint64_t Tag::SimpleTag::Write(IMkvWriter* writer) const { - uint64_t payload_size = EbmlElementSize(libwebm::kMkvTagName, tag_name_); - - payload_size += EbmlElementSize(libwebm::kMkvTagString, tag_string_); - - const uint64_t simple_tag_size = - EbmlMasterElementSize(libwebm::kMkvSimpleTag, payload_size) + - payload_size; - - if (writer == NULL) - return simple_tag_size; - - const int64_t start = writer->Position(); - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvSimpleTag, payload_size)) - return 0; - - if (!WriteEbmlElement(writer, libwebm::kMkvTagName, tag_name_)) - return 0; - - if (!WriteEbmlElement(writer, libwebm::kMkvTagString, tag_string_)) - return 0; - - const int64_t stop = writer->Position(); - - if (stop >= start && uint64_t(stop - start) != simple_tag_size) - return 0; - - return simple_tag_size; -} - -// Tags Class - -Tags::Tags() : tags_size_(0), tags_count_(0), tags_(NULL) {} - -Tags::~Tags() { - while (tags_count_ > 0) { - Tag& tag = tags_[--tags_count_]; - tag.Clear(); - } - - delete[] tags_; - tags_ = NULL; -} - -int Tags::Count() const { return tags_count_; } - -Tag* Tags::AddTag() { - if (!ExpandTagsArray()) - return NULL; - - Tag& tag = tags_[tags_count_++]; - - return &tag; -} - -bool Tags::Write(IMkvWriter* writer) const { - if (writer == NULL) - return false; - - uint64_t payload_size = 0; - - for (int idx = 0; idx < tags_count_; ++idx) { - const Tag& tag = tags_[idx]; - payload_size += tag.Write(NULL); - } - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvTags, payload_size)) - return false; - - const int64_t start = writer->Position(); - - for (int idx = 0; idx < tags_count_; ++idx) { - const Tag& tag = tags_[idx]; - - const uint64_t tag_size = tag.Write(writer); - if (tag_size == 0) // error - return 0; - } - - const int64_t stop = writer->Position(); - - if (stop >= start && uint64_t(stop - start) != payload_size) - return false; - - return true; -} - -bool Tags::ExpandTagsArray() { - if (tags_size_ > tags_count_) - return true; // nothing to do yet - - const int size = (tags_size_ == 0) ? 1 : 2 * tags_size_; - - Tag* const tags = new (std::nothrow) Tag[size]; // NOLINT - if (tags == NULL) - return false; - - for (int idx = 0; idx < tags_count_; ++idx) { - const Tag& src = tags_[idx]; - Tag* const dst = tags + idx; - src.ShallowCopy(dst); - } - - delete[] tags_; - - tags_ = tags; - tags_size_ = size; - - return true; -} - -/////////////////////////////////////////////////////////////// -// -// Cluster class - -Cluster::Cluster(uint64_t timecode, int64_t cues_pos, uint64_t timecode_scale, - bool write_last_frame_with_duration, bool fixed_size_timecode) - : blocks_added_(0), - finalized_(false), - fixed_size_timecode_(fixed_size_timecode), - header_written_(false), - payload_size_(0), - position_for_cues_(cues_pos), - size_position_(-1), - timecode_(timecode), - timecode_scale_(timecode_scale), - write_last_frame_with_duration_(write_last_frame_with_duration), - writer_(NULL) {} - -Cluster::~Cluster() { - // Delete any stored frames that are left behind. This will happen if the - // Cluster was not Finalized for whatever reason. - while (!stored_frames_.empty()) { - while (!stored_frames_.begin()->second.empty()) { - delete stored_frames_.begin()->second.front(); - stored_frames_.begin()->second.pop_front(); - } - stored_frames_.erase(stored_frames_.begin()->first); - } -} - -bool Cluster::Init(IMkvWriter* ptr_writer) { - if (!ptr_writer) { - return false; - } - writer_ = ptr_writer; - return true; -} - -bool Cluster::AddFrame(const Frame* const frame) { - return QueueOrWriteFrame(frame); -} - -bool Cluster::AddFrame(const uint8_t* data, uint64_t length, - uint64_t track_number, uint64_t abs_timecode, - bool is_key) { - Frame frame; - if (!frame.Init(data, length)) - return false; - frame.set_track_number(track_number); - frame.set_timestamp(abs_timecode); - frame.set_is_key(is_key); - return QueueOrWriteFrame(&frame); -} - -bool Cluster::AddFrameWithAdditional(const uint8_t* data, uint64_t length, - const uint8_t* additional, - uint64_t additional_length, - uint64_t add_id, uint64_t track_number, - uint64_t abs_timecode, bool is_key) { - if (!additional || additional_length == 0) { - return false; - } - Frame frame; - if (!frame.Init(data, length) || - !frame.AddAdditionalData(additional, additional_length, add_id)) { - return false; - } - frame.set_track_number(track_number); - frame.set_timestamp(abs_timecode); - frame.set_is_key(is_key); - return QueueOrWriteFrame(&frame); -} - -bool Cluster::AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length, - int64_t discard_padding, - uint64_t track_number, - uint64_t abs_timecode, bool is_key) { - Frame frame; - if (!frame.Init(data, length)) - return false; - frame.set_discard_padding(discard_padding); - frame.set_track_number(track_number); - frame.set_timestamp(abs_timecode); - frame.set_is_key(is_key); - return QueueOrWriteFrame(&frame); -} - -bool Cluster::AddMetadata(const uint8_t* data, uint64_t length, - uint64_t track_number, uint64_t abs_timecode, - uint64_t duration_timecode) { - Frame frame; - if (!frame.Init(data, length)) - return false; - frame.set_track_number(track_number); - frame.set_timestamp(abs_timecode); - frame.set_duration(duration_timecode); - frame.set_is_key(true); // All metadata blocks are keyframes. - return QueueOrWriteFrame(&frame); -} - -void Cluster::AddPayloadSize(uint64_t size) { payload_size_ += size; } - -bool Cluster::Finalize() { - return !write_last_frame_with_duration_ && Finalize(false, 0); -} - -bool Cluster::Finalize(bool set_last_frame_duration, uint64_t duration) { - if (!writer_ || finalized_) - return false; - - if (write_last_frame_with_duration_) { - // Write out held back Frames. This essentially performs a k-way merge - // across all tracks in the increasing order of timestamps. - while (!stored_frames_.empty()) { - Frame* frame = stored_frames_.begin()->second.front(); - - // Get the next frame to write (frame with least timestamp across all - // tracks). - for (FrameMapIterator frames_iterator = ++stored_frames_.begin(); - frames_iterator != stored_frames_.end(); ++frames_iterator) { - if (frames_iterator->second.front()->timestamp() < frame->timestamp()) { - frame = frames_iterator->second.front(); - } - } - - // Set the duration if it's the last frame for the track. - if (set_last_frame_duration && - stored_frames_[frame->track_number()].size() == 1 && - !frame->duration_set()) { - frame->set_duration(duration - frame->timestamp()); - if (!frame->is_key() && !frame->reference_block_timestamp_set()) { - frame->set_reference_block_timestamp( - last_block_timestamp_[frame->track_number()]); - } - } - - // Write the frame and remove it from |stored_frames_|. - const bool wrote_frame = DoWriteFrame(frame); - stored_frames_[frame->track_number()].pop_front(); - if (stored_frames_[frame->track_number()].empty()) { - stored_frames_.erase(frame->track_number()); - } - delete frame; - if (!wrote_frame) - return false; - } - } - - if (size_position_ == -1) - return false; - - if (writer_->Seekable()) { - const int64_t pos = writer_->Position(); - - if (writer_->Position(size_position_)) - return false; - - if (WriteUIntSize(writer_, payload_size(), 8)) - return false; - - if (writer_->Position(pos)) - return false; - } - - finalized_ = true; - - return true; -} - -uint64_t Cluster::Size() const { - const uint64_t element_size = - EbmlMasterElementSize(libwebm::kMkvCluster, 0xFFFFFFFFFFFFFFFFULL) + - payload_size_; - return element_size; -} - -bool Cluster::PreWriteBlock() { - if (finalized_) - return false; - - if (!header_written_) { - if (!WriteClusterHeader()) - return false; - } - - return true; -} - -void Cluster::PostWriteBlock(uint64_t element_size) { - AddPayloadSize(element_size); - ++blocks_added_; -} - -int64_t Cluster::GetRelativeTimecode(int64_t abs_timecode) const { - const int64_t cluster_timecode = this->Cluster::timecode(); - const int64_t rel_timecode = - static_cast(abs_timecode) - cluster_timecode; - - if (rel_timecode < 0 || rel_timecode > kMaxBlockTimecode) - return -1; - - return rel_timecode; -} - -bool Cluster::DoWriteFrame(const Frame* const frame) { - if (!frame || !frame->IsValid()) - return false; - - if (!PreWriteBlock()) - return false; - - const uint64_t element_size = WriteFrame(writer_, frame, this); - if (element_size == 0) - return false; - - PostWriteBlock(element_size); - last_block_timestamp_[frame->track_number()] = frame->timestamp(); - return true; -} - -bool Cluster::QueueOrWriteFrame(const Frame* const frame) { - if (!frame || !frame->IsValid()) - return false; - - // If |write_last_frame_with_duration_| is not set, then write the frame right - // away. - if (!write_last_frame_with_duration_) { - return DoWriteFrame(frame); - } - - // Queue the current frame. - uint64_t track_number = frame->track_number(); - Frame* const frame_to_store = new Frame(); - frame_to_store->CopyFrom(*frame); - stored_frames_[track_number].push_back(frame_to_store); - - // Iterate through all queued frames in the current track except the last one - // and write it if it is okay to do so (i.e.) no other track has an held back - // frame with timestamp <= the timestamp of the frame in question. - std::vector::iterator> frames_to_erase; - for (std::list::iterator - current_track_iterator = stored_frames_[track_number].begin(), - end = --stored_frames_[track_number].end(); - current_track_iterator != end; ++current_track_iterator) { - const Frame* const frame_to_write = *current_track_iterator; - bool okay_to_write = true; - for (FrameMapIterator track_iterator = stored_frames_.begin(); - track_iterator != stored_frames_.end(); ++track_iterator) { - if (track_iterator->first == track_number) { - continue; - } - if (track_iterator->second.front()->timestamp() < - frame_to_write->timestamp()) { - okay_to_write = false; - break; - } - } - if (okay_to_write) { - const bool wrote_frame = DoWriteFrame(frame_to_write); - delete frame_to_write; - if (!wrote_frame) - return false; - frames_to_erase.push_back(current_track_iterator); - } else { - break; - } - } - for (std::vector::iterator>::iterator iterator = - frames_to_erase.begin(); - iterator != frames_to_erase.end(); ++iterator) { - stored_frames_[track_number].erase(*iterator); - } - return true; -} - -bool Cluster::WriteClusterHeader() { - if (finalized_) - return false; - - if (WriteID(writer_, libwebm::kMkvCluster)) - return false; - - // Save for later. - size_position_ = writer_->Position(); - - // Write "unknown" (EBML coded -1) as cluster size value. We need to write 8 - // bytes because we do not know how big our cluster will be. - if (SerializeInt(writer_, kEbmlUnknownValue, 8)) - return false; - - if (!WriteEbmlElement(writer_, libwebm::kMkvTimecode, timecode(), - fixed_size_timecode_ ? 8 : 0)) { - return false; - } - AddPayloadSize(EbmlElementSize(libwebm::kMkvTimecode, timecode(), - fixed_size_timecode_ ? 8 : 0)); - header_written_ = true; - - return true; -} - -/////////////////////////////////////////////////////////////// -// -// SeekHead Class - -SeekHead::SeekHead() : start_pos_(0ULL) { - for (int32_t i = 0; i < kSeekEntryCount; ++i) { - seek_entry_id_[i] = 0; - seek_entry_pos_[i] = 0; - } -} - -SeekHead::~SeekHead() {} - -bool SeekHead::Finalize(IMkvWriter* writer) const { - if (writer->Seekable()) { - if (start_pos_ == -1) - return false; - - uint64_t payload_size = 0; - uint64_t entry_size[kSeekEntryCount]; - - for (int32_t i = 0; i < kSeekEntryCount; ++i) { - if (seek_entry_id_[i] != 0) { - entry_size[i] = EbmlElementSize(libwebm::kMkvSeekID, - static_cast(seek_entry_id_[i])); - entry_size[i] += EbmlElementSize( - libwebm::kMkvSeekPosition, static_cast(seek_entry_pos_[i])); - - payload_size += - EbmlMasterElementSize(libwebm::kMkvSeek, entry_size[i]) + - entry_size[i]; - } - } - - // No SeekHead elements - if (payload_size == 0) - return true; - - const int64_t pos = writer->Position(); - if (writer->Position(start_pos_)) - return false; - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvSeekHead, payload_size)) - return false; - - for (int32_t i = 0; i < kSeekEntryCount; ++i) { - if (seek_entry_id_[i] != 0) { - if (!WriteEbmlMasterElement(writer, libwebm::kMkvSeek, entry_size[i])) - return false; - - if (!WriteEbmlElement(writer, libwebm::kMkvSeekID, - static_cast(seek_entry_id_[i]))) - return false; - - if (!WriteEbmlElement(writer, libwebm::kMkvSeekPosition, - static_cast(seek_entry_pos_[i]))) - return false; - } - } - - const uint64_t total_entry_size = kSeekEntryCount * MaxEntrySize(); - const uint64_t total_size = - EbmlMasterElementSize(libwebm::kMkvSeekHead, total_entry_size) + - total_entry_size; - const int64_t size_left = total_size - (writer->Position() - start_pos_); - - const uint64_t bytes_written = WriteVoidElement(writer, size_left); - if (!bytes_written) - return false; - - if (writer->Position(pos)) - return false; - } - - return true; -} - -bool SeekHead::Write(IMkvWriter* writer) { - const uint64_t entry_size = kSeekEntryCount * MaxEntrySize(); - const uint64_t size = - EbmlMasterElementSize(libwebm::kMkvSeekHead, entry_size); - - start_pos_ = writer->Position(); - - const uint64_t bytes_written = WriteVoidElement(writer, size + entry_size); - if (!bytes_written) - return false; - - return true; -} - -bool SeekHead::AddSeekEntry(uint32_t id, uint64_t pos) { - for (int32_t i = 0; i < kSeekEntryCount; ++i) { - if (seek_entry_id_[i] == 0) { - seek_entry_id_[i] = id; - seek_entry_pos_[i] = pos; - return true; - } - } - return false; -} - -uint32_t SeekHead::GetId(int index) const { - if (index < 0 || index >= kSeekEntryCount) - return UINT32_MAX; - return seek_entry_id_[index]; -} - -uint64_t SeekHead::GetPosition(int index) const { - if (index < 0 || index >= kSeekEntryCount) - return UINT64_MAX; - return seek_entry_pos_[index]; -} - -bool SeekHead::SetSeekEntry(int index, uint32_t id, uint64_t position) { - if (index < 0 || index >= kSeekEntryCount) - return false; - seek_entry_id_[index] = id; - seek_entry_pos_[index] = position; - return true; -} - -uint64_t SeekHead::MaxEntrySize() const { - const uint64_t max_entry_payload_size = - EbmlElementSize(libwebm::kMkvSeekID, - static_cast(UINT64_C(0xffffffff))) + - EbmlElementSize(libwebm::kMkvSeekPosition, - static_cast(UINT64_C(0xffffffffffffffff))); - const uint64_t max_entry_size = - EbmlMasterElementSize(libwebm::kMkvSeek, max_entry_payload_size) + - max_entry_payload_size; - - return max_entry_size; -} - -/////////////////////////////////////////////////////////////// -// -// SegmentInfo Class - -SegmentInfo::SegmentInfo() - : duration_(-1.0), - muxing_app_(NULL), - timecode_scale_(1000000ULL), - writing_app_(NULL), - date_utc_(INT64_MIN), - duration_pos_(-1) {} - -SegmentInfo::~SegmentInfo() { - delete[] muxing_app_; - delete[] writing_app_; -} - -bool SegmentInfo::Init() { - int32_t major; - int32_t minor; - int32_t build; - int32_t revision; - GetVersion(&major, &minor, &build, &revision); - char temp[256]; -#ifdef _MSC_VER - sprintf_s(temp, sizeof(temp) / sizeof(temp[0]), "libwebm-%d.%d.%d.%d", major, - minor, build, revision); -#else - snprintf(temp, sizeof(temp) / sizeof(temp[0]), "libwebm-%d.%d.%d.%d", major, - minor, build, revision); -#endif - - const size_t app_len = strlen(temp) + 1; - - delete[] muxing_app_; - - muxing_app_ = new (std::nothrow) char[app_len]; // NOLINT - if (!muxing_app_) - return false; - - memcpy(muxing_app_, temp, app_len - 1); - muxing_app_[app_len - 1] = '\0'; - - set_writing_app(temp); - if (!writing_app_) - return false; - return true; -} - -bool SegmentInfo::Finalize(IMkvWriter* writer) const { - if (!writer) - return false; - - if (duration_ > 0.0) { - if (writer->Seekable()) { - if (duration_pos_ == -1) - return false; - - const int64_t pos = writer->Position(); - - if (writer->Position(duration_pos_)) - return false; - - if (!WriteEbmlElement(writer, libwebm::kMkvDuration, - static_cast(duration_))) - return false; - - if (writer->Position(pos)) - return false; - } - } - - return true; -} - -bool SegmentInfo::Write(IMkvWriter* writer) { - if (!writer || !muxing_app_ || !writing_app_) - return false; - - uint64_t size = EbmlElementSize(libwebm::kMkvTimecodeScale, - static_cast(timecode_scale_)); - if (duration_ > 0.0) - size += - EbmlElementSize(libwebm::kMkvDuration, static_cast(duration_)); - if (date_utc_ != INT64_MIN) - size += EbmlDateElementSize(libwebm::kMkvDateUTC); - size += EbmlElementSize(libwebm::kMkvMuxingApp, muxing_app_); - size += EbmlElementSize(libwebm::kMkvWritingApp, writing_app_); - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvInfo, size)) - return false; - - const int64_t payload_position = writer->Position(); - if (payload_position < 0) - return false; - - if (!WriteEbmlElement(writer, libwebm::kMkvTimecodeScale, - static_cast(timecode_scale_))) - return false; - - if (duration_ > 0.0) { - // Save for later - duration_pos_ = writer->Position(); - - if (!WriteEbmlElement(writer, libwebm::kMkvDuration, - static_cast(duration_))) - return false; - } - - if (date_utc_ != INT64_MIN) - WriteEbmlDateElement(writer, libwebm::kMkvDateUTC, date_utc_); - - if (!WriteEbmlElement(writer, libwebm::kMkvMuxingApp, muxing_app_)) - return false; - if (!WriteEbmlElement(writer, libwebm::kMkvWritingApp, writing_app_)) - return false; - - const int64_t stop_position = writer->Position(); - if (stop_position < 0 || - stop_position - payload_position != static_cast(size)) - return false; - - return true; -} - -void SegmentInfo::set_muxing_app(const char* app) { - if (app) { - const size_t length = strlen(app) + 1; - char* temp_str = new (std::nothrow) char[length]; // NOLINT - if (!temp_str) - return; - - memcpy(temp_str, app, length - 1); - temp_str[length - 1] = '\0'; - - delete[] muxing_app_; - muxing_app_ = temp_str; - } -} - -void SegmentInfo::set_writing_app(const char* app) { - if (app) { - const size_t length = strlen(app) + 1; - char* temp_str = new (std::nothrow) char[length]; // NOLINT - if (!temp_str) - return; - - memcpy(temp_str, app, length - 1); - temp_str[length - 1] = '\0'; - - delete[] writing_app_; - writing_app_ = temp_str; - } -} - -/////////////////////////////////////////////////////////////// -// -// Segment Class - -Segment::Segment() - : chunk_count_(0), - chunk_name_(NULL), - chunk_writer_cluster_(NULL), - chunk_writer_cues_(NULL), - chunk_writer_header_(NULL), - chunking_(false), - chunking_base_name_(NULL), - cluster_list_(NULL), - cluster_list_capacity_(0), - cluster_list_size_(0), - cues_position_(kAfterClusters), - cues_track_(0), - force_new_cluster_(false), - frames_(NULL), - frames_capacity_(0), - frames_size_(0), - has_video_(false), - header_written_(false), - last_block_duration_(0), - last_timestamp_(0), - max_cluster_duration_(kDefaultMaxClusterDuration), - max_cluster_size_(0), - mode_(kFile), - new_cuepoint_(false), - output_cues_(true), - accurate_cluster_duration_(false), - fixed_size_cluster_timecode_(false), - estimate_file_duration_(false), - ebml_header_size_(0), - payload_pos_(0), - size_position_(0), - doc_type_version_(kDefaultDocTypeVersion), - doc_type_version_written_(0), - duration_(0.0), - writer_cluster_(NULL), - writer_cues_(NULL), - writer_header_(NULL) { - const time_t curr_time = time(NULL); - seed_ = static_cast(curr_time); -#ifdef _WIN32 - srand(seed_); -#endif -} - -Segment::~Segment() { - if (cluster_list_) { - for (int32_t i = 0; i < cluster_list_size_; ++i) { - Cluster* const cluster = cluster_list_[i]; - delete cluster; - } - delete[] cluster_list_; - } - - if (frames_) { - for (int32_t i = 0; i < frames_size_; ++i) { - Frame* const frame = frames_[i]; - delete frame; - } - delete[] frames_; - } - - delete[] chunk_name_; - delete[] chunking_base_name_; - - if (chunk_writer_cluster_) { - chunk_writer_cluster_->Close(); - delete chunk_writer_cluster_; - } - if (chunk_writer_cues_) { - chunk_writer_cues_->Close(); - delete chunk_writer_cues_; - } - if (chunk_writer_header_) { - chunk_writer_header_->Close(); - delete chunk_writer_header_; - } -} - -void Segment::MoveCuesBeforeClustersHelper(uint64_t diff, int32_t index, - uint64_t* cues_size) { - CuePoint* const cue_point = cues_.GetCueByIndex(index); - if (cue_point == NULL) - return; - const uint64_t old_cue_point_size = cue_point->Size(); - const uint64_t cluster_pos = cue_point->cluster_pos() + diff; - cue_point->set_cluster_pos(cluster_pos); // update the new cluster position - // New size of the cue is computed as follows - // Let a = current sum of size of all CuePoints - // Let b = Increase in Cue Point's size due to this iteration - // Let c = Increase in size of Cues Element's length due to this iteration - // (This is computed as CodedSize(a + b) - CodedSize(a)) - // Let d = b + c. Now d is the |diff| passed to the next recursive call. - // Let e = a + b. Now e is the |cues_size| passed to the next recursive - // call. - const uint64_t cue_point_size_diff = cue_point->Size() - old_cue_point_size; - const uint64_t cue_size_diff = - GetCodedUIntSize(*cues_size + cue_point_size_diff) - - GetCodedUIntSize(*cues_size); - *cues_size += cue_point_size_diff; - diff = cue_size_diff + cue_point_size_diff; - if (diff > 0) { - for (int32_t i = 0; i < cues_.cue_entries_size(); ++i) { - MoveCuesBeforeClustersHelper(diff, i, cues_size); - } - } -} - -void Segment::MoveCuesBeforeClusters() { - const uint64_t current_cue_size = cues_.Size(); - uint64_t cue_size = 0; - for (int32_t i = 0; i < cues_.cue_entries_size(); ++i) - cue_size += cues_.GetCueByIndex(i)->Size(); - for (int32_t i = 0; i < cues_.cue_entries_size(); ++i) - MoveCuesBeforeClustersHelper(current_cue_size, i, &cue_size); - - // Adjust the Seek Entry to reflect the change in position - // of Cluster and Cues - int32_t cluster_index = 0; - int32_t cues_index = 0; - for (int32_t i = 0; i < SeekHead::kSeekEntryCount; ++i) { - if (seek_head_.GetId(i) == libwebm::kMkvCluster) - cluster_index = i; - if (seek_head_.GetId(i) == libwebm::kMkvCues) - cues_index = i; - } - seek_head_.SetSeekEntry(cues_index, libwebm::kMkvCues, - seek_head_.GetPosition(cluster_index)); - seek_head_.SetSeekEntry(cluster_index, libwebm::kMkvCluster, - cues_.Size() + seek_head_.GetPosition(cues_index)); -} - -bool Segment::Init(IMkvWriter* ptr_writer) { - if (!ptr_writer) { - return false; - } - writer_cluster_ = ptr_writer; - writer_cues_ = ptr_writer; - writer_header_ = ptr_writer; - memset(&track_frames_written_, 0, - sizeof(track_frames_written_[0]) * kMaxTrackNumber); - memset(&last_track_timestamp_, 0, - sizeof(last_track_timestamp_[0]) * kMaxTrackNumber); - return segment_info_.Init(); -} - -bool Segment::CopyAndMoveCuesBeforeClusters(mkvparser::IMkvReader* reader, - IMkvWriter* writer) { - if (!writer->Seekable() || chunking_) - return false; - const int64_t cluster_offset = - cluster_list_[0]->size_position() - GetUIntSize(libwebm::kMkvCluster); - - // Copy the headers. - if (!ChunkedCopy(reader, writer, 0, cluster_offset)) - return false; - - // Recompute cue positions and seek entries. - MoveCuesBeforeClusters(); - - // Write cues and seek entries. - // TODO(vigneshv): As of now, it's safe to call seek_head_.Finalize() for the - // second time with a different writer object. But the name Finalize() doesn't - // indicate something we want to call more than once. So consider renaming it - // to write() or some such. - if (!cues_.Write(writer) || !seek_head_.Finalize(writer)) - return false; - - // Copy the Clusters. - if (!ChunkedCopy(reader, writer, cluster_offset, - cluster_end_offset_ - cluster_offset)) - return false; - - // Update the Segment size in case the Cues size has changed. - const int64_t pos = writer->Position(); - const int64_t segment_size = writer->Position() - payload_pos_; - if (writer->Position(size_position_) || - WriteUIntSize(writer, segment_size, 8) || writer->Position(pos)) - return false; - return true; -} - -bool Segment::Finalize() { - if (WriteFramesAll() < 0) - return false; - - // In kLive mode, call Cluster::Finalize only if |accurate_cluster_duration_| - // is set. In all other modes, always call Cluster::Finalize. - if ((mode_ == kLive ? accurate_cluster_duration_ : true) && - cluster_list_size_ > 0) { - // Update last cluster's size - Cluster* const old_cluster = cluster_list_[cluster_list_size_ - 1]; - - // For the last frame of the last Cluster, we don't write it as a BlockGroup - // with Duration unless the frame itself has duration set explicitly. - if (!old_cluster || !old_cluster->Finalize(false, 0)) - return false; - } - - if (mode_ == kFile) { - if (chunking_ && chunk_writer_cluster_) { - chunk_writer_cluster_->Close(); - chunk_count_++; - } - - double duration = - (static_cast(last_timestamp_) + last_block_duration_) / - segment_info_.timecode_scale(); - if (duration_ > 0.0) { - duration = duration_; - } else { - if (last_block_duration_ == 0 && estimate_file_duration_) { - const int num_tracks = static_cast(tracks_.track_entries_size()); - for (int i = 0; i < num_tracks; ++i) { - if (track_frames_written_[i] < 2) - continue; - - // Estimate the duration for the last block of a Track. - const double nano_per_frame = - static_cast(last_track_timestamp_[i]) / - (track_frames_written_[i] - 1); - const double track_duration = - (last_track_timestamp_[i] + nano_per_frame) / - segment_info_.timecode_scale(); - if (track_duration > duration) - duration = track_duration; - } - } - } - segment_info_.set_duration(duration); - if (!segment_info_.Finalize(writer_header_)) - return false; - - if (output_cues_) - if (!seek_head_.AddSeekEntry(libwebm::kMkvCues, MaxOffset())) - return false; - - if (chunking_) { - if (!chunk_writer_cues_) - return false; - - char* name = NULL; - if (!UpdateChunkName("cues", &name)) - return false; - - const bool cues_open = chunk_writer_cues_->Open(name); - delete[] name; - if (!cues_open) - return false; - } - - cluster_end_offset_ = writer_cluster_->Position(); - - // Write the seek headers and cues - if (output_cues_) - if (!cues_.Write(writer_cues_)) - return false; - - if (!seek_head_.Finalize(writer_header_)) - return false; - - if (writer_header_->Seekable()) { - if (size_position_ == -1) - return false; - - const int64_t segment_size = MaxOffset(); - if (segment_size < 1) - return false; - - const int64_t pos = writer_header_->Position(); - UpdateDocTypeVersion(); - if (doc_type_version_ != doc_type_version_written_) { - if (writer_header_->Position(0)) - return false; - - const char* const doc_type = - DocTypeIsWebm() ? kDocTypeWebm : kDocTypeMatroska; - if (!WriteEbmlHeader(writer_header_, doc_type_version_, doc_type)) - return false; - if (writer_header_->Position() != ebml_header_size_) - return false; - - doc_type_version_written_ = doc_type_version_; - } - - if (writer_header_->Position(size_position_)) - return false; - - if (WriteUIntSize(writer_header_, segment_size, 8)) - return false; - - if (writer_header_->Position(pos)) - return false; - } - - if (chunking_) { - // Do not close any writers until the segment size has been written, - // otherwise the size may be off. - if (!chunk_writer_cues_ || !chunk_writer_header_) - return false; - - chunk_writer_cues_->Close(); - chunk_writer_header_->Close(); - } - } - - return true; -} - -Track* Segment::AddTrack(int32_t number) { - Track* const track = new (std::nothrow) Track(&seed_); // NOLINT - - if (!track) - return NULL; - - if (!tracks_.AddTrack(track, number)) { - delete track; - return NULL; - } - - return track; -} - -Chapter* Segment::AddChapter() { return chapters_.AddChapter(&seed_); } - -Tag* Segment::AddTag() { return tags_.AddTag(); } - -uint64_t Segment::AddVideoTrack(int32_t width, int32_t height, int32_t number) { - VideoTrack* const track = new (std::nothrow) VideoTrack(&seed_); // NOLINT - if (!track) - return 0; - - track->set_type(Tracks::kVideo); - track->set_codec_id(Tracks::kVp8CodecId); - track->set_width(width); - track->set_height(height); - - if (!tracks_.AddTrack(track, number)) { - delete track; - return 0; - } - has_video_ = true; - - return track->number(); -} - -bool Segment::AddCuePoint(uint64_t timestamp, uint64_t track) { - if (cluster_list_size_ < 1) - return false; - - const Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; - if (!cluster) - return false; - - CuePoint* const cue = new (std::nothrow) CuePoint(); // NOLINT - if (!cue) - return false; - - cue->set_time(timestamp / segment_info_.timecode_scale()); - cue->set_block_number(cluster->blocks_added()); - cue->set_cluster_pos(cluster->position_for_cues()); - cue->set_track(track); - if (!cues_.AddCue(cue)) { - delete cue; - return false; - } - - new_cuepoint_ = false; - return true; -} - -uint64_t Segment::AddAudioTrack(int32_t sample_rate, int32_t channels, - int32_t number) { - AudioTrack* const track = new (std::nothrow) AudioTrack(&seed_); // NOLINT - if (!track) - return 0; - - track->set_type(Tracks::kAudio); - track->set_codec_id(Tracks::kVorbisCodecId); - track->set_sample_rate(sample_rate); - track->set_channels(channels); - - if (!tracks_.AddTrack(track, number)) { - delete track; - return 0; - } - - return track->number(); -} - -bool Segment::AddFrame(const uint8_t* data, uint64_t length, - uint64_t track_number, uint64_t timestamp, bool is_key) { - if (!data) - return false; - - Frame frame; - if (!frame.Init(data, length)) - return false; - frame.set_track_number(track_number); - frame.set_timestamp(timestamp); - frame.set_is_key(is_key); - return AddGenericFrame(&frame); -} - -bool Segment::AddFrameWithAdditional(const uint8_t* data, uint64_t length, - const uint8_t* additional, - uint64_t additional_length, - uint64_t add_id, uint64_t track_number, - uint64_t timestamp, bool is_key) { - if (!data || !additional) - return false; - - Frame frame; - if (!frame.Init(data, length) || - !frame.AddAdditionalData(additional, additional_length, add_id)) { - return false; - } - frame.set_track_number(track_number); - frame.set_timestamp(timestamp); - frame.set_is_key(is_key); - return AddGenericFrame(&frame); -} - -bool Segment::AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length, - int64_t discard_padding, - uint64_t track_number, - uint64_t timestamp, bool is_key) { - if (!data) - return false; - - Frame frame; - if (!frame.Init(data, length)) - return false; - frame.set_discard_padding(discard_padding); - frame.set_track_number(track_number); - frame.set_timestamp(timestamp); - frame.set_is_key(is_key); - return AddGenericFrame(&frame); -} - -bool Segment::AddMetadata(const uint8_t* data, uint64_t length, - uint64_t track_number, uint64_t timestamp_ns, - uint64_t duration_ns) { - if (!data) - return false; - - Frame frame; - if (!frame.Init(data, length)) - return false; - frame.set_track_number(track_number); - frame.set_timestamp(timestamp_ns); - frame.set_duration(duration_ns); - frame.set_is_key(true); // All metadata blocks are keyframes. - return AddGenericFrame(&frame); -} - -bool Segment::AddGenericFrame(const Frame* frame) { - if (!frame) - return false; - - if (!CheckHeaderInfo()) - return false; - - // Check for non-monotonically increasing timestamps. - if (frame->timestamp() < last_timestamp_) - return false; - - // Check if the track number is valid. - if (!tracks_.GetTrackByNumber(frame->track_number())) - return false; - - if (frame->discard_padding() != 0) - doc_type_version_ = 4; - - if (cluster_list_size_ > 0) { - const uint64_t timecode_scale = segment_info_.timecode_scale(); - const uint64_t frame_timecode = frame->timestamp() / timecode_scale; - - const Cluster* const last_cluster = cluster_list_[cluster_list_size_ - 1]; - const uint64_t last_cluster_timecode = last_cluster->timecode(); - - const uint64_t rel_timecode = frame_timecode - last_cluster_timecode; - if (rel_timecode > kMaxBlockTimecode) { - force_new_cluster_ = true; - } - } - - // If the segment has a video track hold onto audio frames to make sure the - // audio that is associated with the start time of a video key-frame is - // muxed into the same cluster. - if (has_video_ && tracks_.TrackIsAudio(frame->track_number()) && - !force_new_cluster_) { - Frame* const new_frame = new (std::nothrow) Frame(); - if (!new_frame || !new_frame->CopyFrom(*frame)) { - delete new_frame; - return false; - } - if (!QueueFrame(new_frame)) { - delete new_frame; - return false; - } - track_frames_written_[frame->track_number() - 1]++; - return true; - } - - if (!DoNewClusterProcessing(frame->track_number(), frame->timestamp(), - frame->is_key())) { - return false; - } - - if (cluster_list_size_ < 1) - return false; - - Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; - if (!cluster) - return false; - - // If the Frame is not a SimpleBlock, then set the reference_block_timestamp - // if it is not set already. - bool frame_created = false; - if (!frame->CanBeSimpleBlock() && !frame->is_key() && - !frame->reference_block_timestamp_set()) { - Frame* const new_frame = new (std::nothrow) Frame(); - if (!new_frame || !new_frame->CopyFrom(*frame)) { - delete new_frame; - return false; - } - new_frame->set_reference_block_timestamp( - last_track_timestamp_[frame->track_number() - 1]); - frame = new_frame; - frame_created = true; - } - - if (!cluster->AddFrame(frame)) - return false; - - if (new_cuepoint_ && cues_track_ == frame->track_number()) { - if (!AddCuePoint(frame->timestamp(), cues_track_)) - return false; - } - - last_timestamp_ = frame->timestamp(); - last_track_timestamp_[frame->track_number() - 1] = frame->timestamp(); - last_block_duration_ = frame->duration(); - track_frames_written_[frame->track_number() - 1]++; - - if (frame_created) - delete frame; - return true; -} - -void Segment::OutputCues(bool output_cues) { output_cues_ = output_cues; } - -void Segment::AccurateClusterDuration(bool accurate_cluster_duration) { - accurate_cluster_duration_ = accurate_cluster_duration; -} - -void Segment::UseFixedSizeClusterTimecode(bool fixed_size_cluster_timecode) { - fixed_size_cluster_timecode_ = fixed_size_cluster_timecode; -} - -bool Segment::SetChunking(bool chunking, const char* filename) { - if (chunk_count_ > 0) - return false; - - if (chunking) { - if (!filename) - return false; - - // Check if we are being set to what is already set. - if (chunking_ && !strcmp(filename, chunking_base_name_)) - return true; - - const size_t filename_length = strlen(filename); - char* const temp = new (std::nothrow) char[filename_length + 1]; // NOLINT - if (!temp) - return false; - - memcpy(temp, filename, filename_length); - temp[filename_length] = '\0'; - - delete[] chunking_base_name_; - chunking_base_name_ = temp; - // From this point, strlen(chunking_base_name_) == filename_length - - if (!UpdateChunkName("chk", &chunk_name_)) - return false; - - if (!chunk_writer_cluster_) { - chunk_writer_cluster_ = new (std::nothrow) MkvWriter(); // NOLINT - if (!chunk_writer_cluster_) - return false; - } - - if (!chunk_writer_cues_) { - chunk_writer_cues_ = new (std::nothrow) MkvWriter(); // NOLINT - if (!chunk_writer_cues_) - return false; - } - - if (!chunk_writer_header_) { - chunk_writer_header_ = new (std::nothrow) MkvWriter(); // NOLINT - if (!chunk_writer_header_) - return false; - } - - if (!chunk_writer_cluster_->Open(chunk_name_)) - return false; - - const size_t hdr_length = strlen(".hdr"); - const size_t header_length = filename_length + hdr_length + 1; - char* const header = new (std::nothrow) char[header_length]; // NOLINT - if (!header) - return false; - - memcpy(header, chunking_base_name_, filename_length); - memcpy(&header[filename_length], ".hdr", hdr_length); - header[filename_length + hdr_length] = '\0'; - - if (!chunk_writer_header_->Open(header)) { - delete[] header; - return false; - } - - writer_cluster_ = chunk_writer_cluster_; - writer_cues_ = chunk_writer_cues_; - writer_header_ = chunk_writer_header_; - - delete[] header; - } - - chunking_ = chunking; - - return true; -} - -bool Segment::CuesTrack(uint64_t track_number) { - const Track* const track = GetTrackByNumber(track_number); - if (!track) - return false; - - cues_track_ = track_number; - return true; -} - -void Segment::ForceNewClusterOnNextFrame() { force_new_cluster_ = true; } - -Track* Segment::GetTrackByNumber(uint64_t track_number) const { - return tracks_.GetTrackByNumber(track_number); -} - -bool Segment::WriteSegmentHeader() { - UpdateDocTypeVersion(); - - const char* const doc_type = - DocTypeIsWebm() ? kDocTypeWebm : kDocTypeMatroska; - if (!WriteEbmlHeader(writer_header_, doc_type_version_, doc_type)) - return false; - doc_type_version_written_ = doc_type_version_; - ebml_header_size_ = static_cast(writer_header_->Position()); - - // Write "unknown" (-1) as segment size value. If mode is kFile, Segment - // will write over duration when the file is finalized. - if (WriteID(writer_header_, libwebm::kMkvSegment)) - return false; - - // Save for later. - size_position_ = writer_header_->Position(); - - // Write "unknown" (EBML coded -1) as segment size value. We need to write 8 - // bytes because if we are going to overwrite the segment size later we do - // not know how big our segment will be. - if (SerializeInt(writer_header_, kEbmlUnknownValue, 8)) - return false; - - payload_pos_ = writer_header_->Position(); - - if (mode_ == kFile && writer_header_->Seekable()) { - // Set the duration > 0.0 so SegmentInfo will write out the duration. When - // the muxer is done writing we will set the correct duration and have - // SegmentInfo upadte it. - segment_info_.set_duration(1.0); - - if (!seek_head_.Write(writer_header_)) - return false; - } - - if (!seek_head_.AddSeekEntry(libwebm::kMkvInfo, MaxOffset())) - return false; - if (!segment_info_.Write(writer_header_)) - return false; - - if (!seek_head_.AddSeekEntry(libwebm::kMkvTracks, MaxOffset())) - return false; - if (!tracks_.Write(writer_header_)) - return false; - - if (chapters_.Count() > 0) { - if (!seek_head_.AddSeekEntry(libwebm::kMkvChapters, MaxOffset())) - return false; - if (!chapters_.Write(writer_header_)) - return false; - } - - if (tags_.Count() > 0) { - if (!seek_head_.AddSeekEntry(libwebm::kMkvTags, MaxOffset())) - return false; - if (!tags_.Write(writer_header_)) - return false; - } - - if (chunking_ && (mode_ == kLive || !writer_header_->Seekable())) { - if (!chunk_writer_header_) - return false; - - chunk_writer_header_->Close(); - } - - header_written_ = true; - - return true; -} - -// Here we are testing whether to create a new cluster, given a frame -// having time frame_timestamp_ns. -// -int Segment::TestFrame(uint64_t track_number, uint64_t frame_timestamp_ns, - bool is_key) const { - if (force_new_cluster_) - return 1; - - // If no clusters have been created yet, then create a new cluster - // and write this frame immediately, in the new cluster. This path - // should only be followed once, the first time we attempt to write - // a frame. - - if (cluster_list_size_ <= 0) - return 1; - - // There exists at least one cluster. We must compare the frame to - // the last cluster, in order to determine whether the frame is - // written to the existing cluster, or that a new cluster should be - // created. - - const uint64_t timecode_scale = segment_info_.timecode_scale(); - const uint64_t frame_timecode = frame_timestamp_ns / timecode_scale; - - const Cluster* const last_cluster = cluster_list_[cluster_list_size_ - 1]; - const uint64_t last_cluster_timecode = last_cluster->timecode(); - - // For completeness we test for the case when the frame's timecode - // is less than the cluster's timecode. Although in principle that - // is allowed, this muxer doesn't actually write clusters like that, - // so this indicates a bug somewhere in our algorithm. - - if (frame_timecode < last_cluster_timecode) // should never happen - return -1; - - // If the frame has a timestamp significantly larger than the last - // cluster (in Matroska, cluster-relative timestamps are serialized - // using a 16-bit signed integer), then we cannot write this frame - // to that cluster, and so we must create a new cluster. - - const int64_t delta_timecode = frame_timecode - last_cluster_timecode; - - if (delta_timecode > kMaxBlockTimecode) - return 2; - - // We decide to create a new cluster when we have a video keyframe. - // This will flush queued (audio) frames, and write the keyframe - // immediately, in the newly-created cluster. - - if (is_key && tracks_.TrackIsVideo(track_number)) - return 1; - - // Create a new cluster if we have accumulated too many frames - // already, where "too many" is defined as "the total time of frames - // in the cluster exceeds a threshold". - - const uint64_t delta_ns = delta_timecode * timecode_scale; - - if (max_cluster_duration_ > 0 && delta_ns >= max_cluster_duration_) - return 1; - - // This is similar to the case above, with the difference that a new - // cluster is created when the size of the current cluster exceeds a - // threshold. - - const uint64_t cluster_size = last_cluster->payload_size(); - - if (max_cluster_size_ > 0 && cluster_size >= max_cluster_size_) - return 1; - - // There's no need to create a new cluster, so emit this frame now. - - return 0; -} - -bool Segment::MakeNewCluster(uint64_t frame_timestamp_ns) { - const int32_t new_size = cluster_list_size_ + 1; - - if (new_size > cluster_list_capacity_) { - // Add more clusters. - const int32_t new_capacity = - (cluster_list_capacity_ <= 0) ? 1 : cluster_list_capacity_ * 2; - Cluster** const clusters = - new (std::nothrow) Cluster*[new_capacity]; // NOLINT - if (!clusters) - return false; - - for (int32_t i = 0; i < cluster_list_size_; ++i) { - clusters[i] = cluster_list_[i]; - } - - delete[] cluster_list_; - - cluster_list_ = clusters; - cluster_list_capacity_ = new_capacity; - } - - if (!WriteFramesLessThan(frame_timestamp_ns)) - return false; - - if (cluster_list_size_ > 0) { - // Update old cluster's size - Cluster* const old_cluster = cluster_list_[cluster_list_size_ - 1]; - - if (!old_cluster || !old_cluster->Finalize(true, frame_timestamp_ns)) - return false; - } - - if (output_cues_) - new_cuepoint_ = true; - - if (chunking_ && cluster_list_size_ > 0) { - chunk_writer_cluster_->Close(); - chunk_count_++; - - if (!UpdateChunkName("chk", &chunk_name_)) - return false; - if (!chunk_writer_cluster_->Open(chunk_name_)) - return false; - } - - const uint64_t timecode_scale = segment_info_.timecode_scale(); - const uint64_t frame_timecode = frame_timestamp_ns / timecode_scale; - - uint64_t cluster_timecode = frame_timecode; - - if (frames_size_ > 0) { - const Frame* const f = frames_[0]; // earliest queued frame - const uint64_t ns = f->timestamp(); - const uint64_t tc = ns / timecode_scale; - - if (tc < cluster_timecode) - cluster_timecode = tc; - } - - Cluster*& cluster = cluster_list_[cluster_list_size_]; - const int64_t offset = MaxOffset(); - cluster = new (std::nothrow) - Cluster(cluster_timecode, offset, segment_info_.timecode_scale(), - accurate_cluster_duration_, fixed_size_cluster_timecode_); - if (!cluster) - return false; - - if (!cluster->Init(writer_cluster_)) - return false; - - cluster_list_size_ = new_size; - return true; -} - -bool Segment::DoNewClusterProcessing(uint64_t track_number, - uint64_t frame_timestamp_ns, bool is_key) { - for (;;) { - // Based on the characteristics of the current frame and current - // cluster, decide whether to create a new cluster. - const int result = TestFrame(track_number, frame_timestamp_ns, is_key); - if (result < 0) // error - return false; - - // Always set force_new_cluster_ to false after TestFrame. - force_new_cluster_ = false; - - // A non-zero result means create a new cluster. - if (result > 0 && !MakeNewCluster(frame_timestamp_ns)) - return false; - - // Write queued (audio) frames. - const int frame_count = WriteFramesAll(); - if (frame_count < 0) // error - return false; - - // Write the current frame to the current cluster (if TestFrame - // returns 0) or to a newly created cluster (TestFrame returns 1). - if (result <= 1) - return true; - - // TestFrame returned 2, which means there was a large time - // difference between the cluster and the frame itself. Do the - // test again, comparing the frame to the new cluster. - } -} - -bool Segment::CheckHeaderInfo() { - if (!header_written_) { - if (!WriteSegmentHeader()) - return false; - - if (!seek_head_.AddSeekEntry(libwebm::kMkvCluster, MaxOffset())) - return false; - - if (output_cues_ && cues_track_ == 0) { - // Check for a video track - for (uint32_t i = 0; i < tracks_.track_entries_size(); ++i) { - const Track* const track = tracks_.GetTrackByIndex(i); - if (!track) - return false; - - if (tracks_.TrackIsVideo(track->number())) { - cues_track_ = track->number(); - break; - } - } - - // Set first track found - if (cues_track_ == 0) { - const Track* const track = tracks_.GetTrackByIndex(0); - if (!track) - return false; - - cues_track_ = track->number(); - } - } - } - return true; -} - -void Segment::UpdateDocTypeVersion() { - for (uint32_t index = 0; index < tracks_.track_entries_size(); ++index) { - const Track* track = tracks_.GetTrackByIndex(index); - if (track == NULL) - break; - if ((track->codec_delay() || track->seek_pre_roll()) && - doc_type_version_ < 4) { - doc_type_version_ = 4; - break; - } - } -} - -bool Segment::UpdateChunkName(const char* ext, char** name) const { - if (!name || !ext) - return false; - - char ext_chk[64]; -#ifdef _MSC_VER - sprintf_s(ext_chk, sizeof(ext_chk), "_%06d.%s", chunk_count_, ext); -#else - snprintf(ext_chk, sizeof(ext_chk), "_%06d.%s", chunk_count_, ext); -#endif - - const size_t chunking_base_name_length = strlen(chunking_base_name_); - const size_t ext_chk_length = strlen(ext_chk); - const size_t length = chunking_base_name_length + ext_chk_length + 1; - char* const str = new (std::nothrow) char[length]; // NOLINT - if (!str) - return false; - - memcpy(str, chunking_base_name_, chunking_base_name_length); - memcpy(&str[chunking_base_name_length], ext_chk, ext_chk_length); - str[chunking_base_name_length + ext_chk_length] = '\0'; - - delete[] * name; - *name = str; - - return true; -} - -int64_t Segment::MaxOffset() { - if (!writer_header_) - return -1; - - int64_t offset = writer_header_->Position() - payload_pos_; - - if (chunking_) { - for (int32_t i = 0; i < cluster_list_size_; ++i) { - Cluster* const cluster = cluster_list_[i]; - offset += cluster->Size(); - } - - if (writer_cues_) - offset += writer_cues_->Position(); - } - - return offset; -} - -bool Segment::QueueFrame(Frame* frame) { - const int32_t new_size = frames_size_ + 1; - - if (new_size > frames_capacity_) { - // Add more frames. - const int32_t new_capacity = (!frames_capacity_) ? 2 : frames_capacity_ * 2; - - if (new_capacity < 1) - return false; - - Frame** const frames = new (std::nothrow) Frame*[new_capacity]; // NOLINT - if (!frames) - return false; - - for (int32_t i = 0; i < frames_size_; ++i) { - frames[i] = frames_[i]; - } - - delete[] frames_; - frames_ = frames; - frames_capacity_ = new_capacity; - } - - frames_[frames_size_++] = frame; - - return true; -} - -int Segment::WriteFramesAll() { - if (frames_ == NULL) - return 0; - - if (cluster_list_size_ < 1) - return -1; - - Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; - - if (!cluster) - return -1; - - for (int32_t i = 0; i < frames_size_; ++i) { - Frame*& frame = frames_[i]; - // TODO(jzern/vigneshv): using Segment::AddGenericFrame here would limit the - // places where |doc_type_version_| needs to be updated. - if (frame->discard_padding() != 0) - doc_type_version_ = 4; - if (!cluster->AddFrame(frame)) { - delete frame; - continue; - } - - if (new_cuepoint_ && cues_track_ == frame->track_number()) { - if (!AddCuePoint(frame->timestamp(), cues_track_)) { - delete frame; - continue; - } - } - - if (frame->timestamp() > last_timestamp_) { - last_timestamp_ = frame->timestamp(); - last_track_timestamp_[frame->track_number() - 1] = frame->timestamp(); - } - - delete frame; - frame = NULL; - } - - const int result = frames_size_; - frames_size_ = 0; - - return result; -} - -bool Segment::WriteFramesLessThan(uint64_t timestamp) { - // Check |cluster_list_size_| to see if this is the first cluster. If it is - // the first cluster the audio frames that are less than the first video - // timesatmp will be written in a later step. - if (frames_size_ > 0 && cluster_list_size_ > 0) { - if (!frames_) - return false; - - Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; - if (!cluster) - return false; - - int32_t shift_left = 0; - - // TODO(fgalligan): Change this to use the durations of frames instead of - // the next frame's start time if the duration is accurate. - for (int32_t i = 1; i < frames_size_; ++i) { - const Frame* const frame_curr = frames_[i]; - - if (frame_curr->timestamp() > timestamp) - break; - - const Frame* const frame_prev = frames_[i - 1]; - if (frame_prev->discard_padding() != 0) - doc_type_version_ = 4; - if (!cluster->AddFrame(frame_prev)) { - delete frame_prev; - continue; - } - - if (new_cuepoint_ && cues_track_ == frame_prev->track_number()) { - if (!AddCuePoint(frame_prev->timestamp(), cues_track_)) { - delete frame_prev; - continue; - } - } - - ++shift_left; - if (frame_prev->timestamp() > last_timestamp_) { - last_timestamp_ = frame_prev->timestamp(); - last_track_timestamp_[frame_prev->track_number() - 1] = - frame_prev->timestamp(); - } - - delete frame_prev; - } - - if (shift_left > 0) { - if (shift_left >= frames_size_) - return false; - - const int32_t new_frames_size = frames_size_ - shift_left; - for (int32_t i = 0; i < new_frames_size; ++i) { - frames_[i] = frames_[i + shift_left]; - } - - frames_size_ = new_frames_size; - } - } - - return true; -} - -bool Segment::DocTypeIsWebm() const { - const int kNumCodecIds = 9; - - // TODO(vigneshv): Tweak .clang-format. - const char* kWebmCodecIds[kNumCodecIds] = { - Tracks::kOpusCodecId, Tracks::kVorbisCodecId, - Tracks::kAv1CodecId, Tracks::kVp8CodecId, - Tracks::kVp9CodecId, Tracks::kWebVttCaptionsId, - Tracks::kWebVttDescriptionsId, Tracks::kWebVttMetadataId, - Tracks::kWebVttSubtitlesId}; - - const int num_tracks = static_cast(tracks_.track_entries_size()); - for (int track_index = 0; track_index < num_tracks; ++track_index) { - const Track* const track = tracks_.GetTrackByIndex(track_index); - const std::string codec_id = track->codec_id(); - - bool id_is_webm = false; - for (int id_index = 0; id_index < kNumCodecIds; ++id_index) { - if (codec_id == kWebmCodecIds[id_index]) { - id_is_webm = true; - break; - } - } - - if (!id_is_webm) - return false; - } - - return true; -} - -} // namespace mkvmuxer diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvmuxer.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvmuxer.h deleted file mode 100644 index 2c4bb9e9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvmuxer.h +++ /dev/null @@ -1,1924 +0,0 @@ -// Copyright (c) 2012 The WebM project authors. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. - -#ifndef MKVMUXER_MKVMUXER_H_ -#define MKVMUXER_MKVMUXER_H_ - -#include - -#include -#include -#include - -#include "common/webmids.h" -#include "mkvmuxer/mkvmuxertypes.h" - -// For a description of the WebM elements see -// http://www.webmproject.org/code/specs/container/. - -namespace mkvparser { -class IMkvReader; -} // namespace mkvparser - -namespace mkvmuxer { - -class MkvWriter; -class Segment; - -const uint64_t kMaxTrackNumber = 126; - -/////////////////////////////////////////////////////////////// -// Interface used by the mkvmuxer to write out the Mkv data. -class IMkvWriter { - public: - // Writes out |len| bytes of |buf|. Returns 0 on success. - virtual int32 Write(const void* buf, uint32 len) = 0; - - // Returns the offset of the output position from the beginning of the - // output. - virtual int64 Position() const = 0; - - // Set the current File position. Returns 0 on success. - virtual int32 Position(int64 position) = 0; - - // Returns true if the writer is seekable. - virtual bool Seekable() const = 0; - - // Element start notification. Called whenever an element identifier is about - // to be written to the stream. |element_id| is the element identifier, and - // |position| is the location in the WebM stream where the first octet of the - // element identifier will be written. - // Note: the |MkvId| enumeration in webmids.hpp defines element values. - virtual void ElementStartNotify(uint64 element_id, int64 position) = 0; - - protected: - IMkvWriter(); - virtual ~IMkvWriter(); - - private: - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(IMkvWriter); -}; - -// Writes out the EBML header for a WebM file, but allows caller to specify -// DocType. This function must be called before any other libwebm writing -// functions are called. -bool WriteEbmlHeader(IMkvWriter* writer, uint64_t doc_type_version, - const char* const doc_type); - -// Writes out the EBML header for a WebM file. This function must be called -// before any other libwebm writing functions are called. -bool WriteEbmlHeader(IMkvWriter* writer, uint64_t doc_type_version); - -// Deprecated. Writes out EBML header with doc_type_version as -// kDefaultDocTypeVersion. Exists for backward compatibility. -bool WriteEbmlHeader(IMkvWriter* writer); - -// Copies in Chunk from source to destination between the given byte positions -bool ChunkedCopy(mkvparser::IMkvReader* source, IMkvWriter* dst, int64_t start, - int64_t size); - -/////////////////////////////////////////////////////////////// -// Class to hold data the will be written to a block. -class Frame { - public: - Frame(); - ~Frame(); - - // Sets this frame's contents based on |frame|. Returns true on success. On - // failure, this frame's existing contents may be lost. - bool CopyFrom(const Frame& frame); - - // Copies |frame| data into |frame_|. Returns true on success. - bool Init(const uint8_t* frame, uint64_t length); - - // Copies |additional| data into |additional_|. Returns true on success. - bool AddAdditionalData(const uint8_t* additional, uint64_t length, - uint64_t add_id); - - // Returns true if the frame has valid parameters. - bool IsValid() const; - - // Returns true if the frame can be written as a SimpleBlock based on current - // parameters. - bool CanBeSimpleBlock() const; - - uint64_t add_id() const { return add_id_; } - const uint8_t* additional() const { return additional_; } - uint64_t additional_length() const { return additional_length_; } - void set_duration(uint64_t duration); - uint64_t duration() const { return duration_; } - bool duration_set() const { return duration_set_; } - const uint8_t* frame() const { return frame_; } - void set_is_key(bool key) { is_key_ = key; } - bool is_key() const { return is_key_; } - uint64_t length() const { return length_; } - void set_track_number(uint64_t track_number) { track_number_ = track_number; } - uint64_t track_number() const { return track_number_; } - void set_timestamp(uint64_t timestamp) { timestamp_ = timestamp; } - uint64_t timestamp() const { return timestamp_; } - void set_discard_padding(int64_t discard_padding) { - discard_padding_ = discard_padding; - } - int64_t discard_padding() const { return discard_padding_; } - void set_reference_block_timestamp(int64_t reference_block_timestamp); - int64_t reference_block_timestamp() const { - return reference_block_timestamp_; - } - bool reference_block_timestamp_set() const { - return reference_block_timestamp_set_; - } - - private: - // Id of the Additional data. - uint64_t add_id_; - - // Pointer to additional data. Owned by this class. - uint8_t* additional_; - - // Length of the additional data. - uint64_t additional_length_; - - // Duration of the frame in nanoseconds. - uint64_t duration_; - - // Flag indicating that |duration_| has been set. Setting duration causes the - // frame to be written out as a Block with BlockDuration instead of as a - // SimpleBlock. - bool duration_set_; - - // Pointer to the data. Owned by this class. - uint8_t* frame_; - - // Flag telling if the data should set the key flag of a block. - bool is_key_; - - // Length of the data. - uint64_t length_; - - // Mkv track number the data is associated with. - uint64_t track_number_; - - // Timestamp of the data in nanoseconds. - uint64_t timestamp_; - - // Discard padding for the frame. - int64_t discard_padding_; - - // Reference block timestamp. - int64_t reference_block_timestamp_; - - // Flag indicating if |reference_block_timestamp_| has been set. - bool reference_block_timestamp_set_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Frame); -}; - -/////////////////////////////////////////////////////////////// -// Class to hold one cue point in a Cues element. -class CuePoint { - public: - CuePoint(); - ~CuePoint(); - - // Returns the size in bytes for the entire CuePoint element. - uint64_t Size() const; - - // Output the CuePoint element to the writer. Returns true on success. - bool Write(IMkvWriter* writer) const; - - void set_time(uint64_t time) { time_ = time; } - uint64_t time() const { return time_; } - void set_track(uint64_t track) { track_ = track; } - uint64_t track() const { return track_; } - void set_cluster_pos(uint64_t cluster_pos) { cluster_pos_ = cluster_pos; } - uint64_t cluster_pos() const { return cluster_pos_; } - void set_block_number(uint64_t block_number) { block_number_ = block_number; } - uint64_t block_number() const { return block_number_; } - void set_output_block_number(bool output_block_number) { - output_block_number_ = output_block_number; - } - bool output_block_number() const { return output_block_number_; } - - private: - // Returns the size in bytes for the payload of the CuePoint element. - uint64_t PayloadSize() const; - - // Absolute timecode according to the segment time base. - uint64_t time_; - - // The Track element associated with the CuePoint. - uint64_t track_; - - // The position of the Cluster containing the Block. - uint64_t cluster_pos_; - - // Number of the Block within the Cluster, starting from 1. - uint64_t block_number_; - - // If true the muxer will write out the block number for the cue if the - // block number is different than the default of 1. Default is set to true. - bool output_block_number_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(CuePoint); -}; - -/////////////////////////////////////////////////////////////// -// Cues element. -class Cues { - public: - Cues(); - ~Cues(); - - // Adds a cue point to the Cues element. Returns true on success. - bool AddCue(CuePoint* cue); - - // Returns the cue point by index. Returns NULL if there is no cue point - // match. - CuePoint* GetCueByIndex(int32_t index) const; - - // Returns the total size of the Cues element - uint64_t Size(); - - // Output the Cues element to the writer. Returns true on success. - bool Write(IMkvWriter* writer) const; - - int32_t cue_entries_size() const { return cue_entries_size_; } - void set_output_block_number(bool output_block_number) { - output_block_number_ = output_block_number; - } - bool output_block_number() const { return output_block_number_; } - - private: - // Number of allocated elements in |cue_entries_|. - int32_t cue_entries_capacity_; - - // Number of CuePoints in |cue_entries_|. - int32_t cue_entries_size_; - - // CuePoint list. - CuePoint** cue_entries_; - - // If true the muxer will write out the block number for the cue if the - // block number is different than the default of 1. Default is set to true. - bool output_block_number_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Cues); -}; - -/////////////////////////////////////////////////////////////// -// ContentEncAESSettings element -class ContentEncAESSettings { - public: - enum { kCTR = 1 }; - - ContentEncAESSettings(); - ~ContentEncAESSettings() {} - - // Returns the size in bytes for the ContentEncAESSettings element. - uint64_t Size() const; - - // Writes out the ContentEncAESSettings element to |writer|. Returns true on - // success. - bool Write(IMkvWriter* writer) const; - - uint64_t cipher_mode() const { return cipher_mode_; } - - private: - // Returns the size in bytes for the payload of the ContentEncAESSettings - // element. - uint64_t PayloadSize() const; - - // Sub elements - uint64_t cipher_mode_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncAESSettings); -}; - -/////////////////////////////////////////////////////////////// -// ContentEncoding element -// Elements used to describe if the track data has been encrypted or -// compressed with zlib or header stripping. -// Currently only whole frames can be encrypted with AES. This dictates that -// ContentEncodingOrder will be 0, ContentEncodingScope will be 1, -// ContentEncodingType will be 1, and ContentEncAlgo will be 5. -class ContentEncoding { - public: - ContentEncoding(); - ~ContentEncoding(); - - // Sets the content encryption id. Copies |length| bytes from |id| to - // |enc_key_id_|. Returns true on success. - bool SetEncryptionID(const uint8_t* id, uint64_t length); - - // Returns the size in bytes for the ContentEncoding element. - uint64_t Size() const; - - // Writes out the ContentEncoding element to |writer|. Returns true on - // success. - bool Write(IMkvWriter* writer) const; - - uint64_t enc_algo() const { return enc_algo_; } - uint64_t encoding_order() const { return encoding_order_; } - uint64_t encoding_scope() const { return encoding_scope_; } - uint64_t encoding_type() const { return encoding_type_; } - ContentEncAESSettings* enc_aes_settings() { return &enc_aes_settings_; } - - private: - // Returns the size in bytes for the encoding elements. - uint64_t EncodingSize(uint64_t compression_size, - uint64_t encryption_size) const; - - // Returns the size in bytes for the encryption elements. - uint64_t EncryptionSize() const; - - // Track element names - uint64_t enc_algo_; - uint8_t* enc_key_id_; - uint64_t encoding_order_; - uint64_t encoding_scope_; - uint64_t encoding_type_; - - // ContentEncAESSettings element. - ContentEncAESSettings enc_aes_settings_; - - // Size of the ContentEncKeyID data in bytes. - uint64_t enc_key_id_length_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding); -}; - -/////////////////////////////////////////////////////////////// -// Colour element. -class PrimaryChromaticity { - public: - static const float kChromaticityMin; - static const float kChromaticityMax; - - PrimaryChromaticity(float x_val, float y_val) : x_(x_val), y_(y_val) {} - PrimaryChromaticity() : x_(0), y_(0) {} - ~PrimaryChromaticity() {} - - // Returns sum of |x_id| and |y_id| element id sizes and payload sizes. - uint64_t PrimaryChromaticitySize(libwebm::MkvId x_id, - libwebm::MkvId y_id) const; - bool Valid() const; - bool Write(IMkvWriter* writer, libwebm::MkvId x_id, - libwebm::MkvId y_id) const; - - float x() const { return x_; } - void set_x(float new_x) { x_ = new_x; } - float y() const { return y_; } - void set_y(float new_y) { y_ = new_y; } - - private: - float x_; - float y_; -}; - -class MasteringMetadata { - public: - static const float kValueNotPresent; - static const float kMinLuminance; - static const float kMinLuminanceMax; - static const float kMaxLuminanceMax; - - MasteringMetadata() - : luminance_max_(kValueNotPresent), - luminance_min_(kValueNotPresent), - r_(NULL), - g_(NULL), - b_(NULL), - white_point_(NULL) {} - ~MasteringMetadata() { - delete r_; - delete g_; - delete b_; - delete white_point_; - } - - // Returns total size of the MasteringMetadata element. - uint64_t MasteringMetadataSize() const; - bool Valid() const; - bool Write(IMkvWriter* writer) const; - - // Copies non-null chromaticity. - bool SetChromaticity(const PrimaryChromaticity* r, - const PrimaryChromaticity* g, - const PrimaryChromaticity* b, - const PrimaryChromaticity* white_point); - const PrimaryChromaticity* r() const { return r_; } - const PrimaryChromaticity* g() const { return g_; } - const PrimaryChromaticity* b() const { return b_; } - const PrimaryChromaticity* white_point() const { return white_point_; } - - float luminance_max() const { return luminance_max_; } - void set_luminance_max(float luminance_max) { - luminance_max_ = luminance_max; - } - float luminance_min() const { return luminance_min_; } - void set_luminance_min(float luminance_min) { - luminance_min_ = luminance_min; - } - - private: - // Returns size of MasteringMetadata child elements. - uint64_t PayloadSize() const; - - float luminance_max_; - float luminance_min_; - PrimaryChromaticity* r_; - PrimaryChromaticity* g_; - PrimaryChromaticity* b_; - PrimaryChromaticity* white_point_; -}; - -class Colour { - public: - enum MatrixCoefficients { - kGbr = 0, - kBt709 = 1, - kUnspecifiedMc = 2, - kReserved = 3, - kFcc = 4, - kBt470bg = 5, - kSmpte170MMc = 6, - kSmpte240MMc = 7, - kYcocg = 8, - kBt2020NonConstantLuminance = 9, - kBt2020ConstantLuminance = 10, - }; - enum ChromaSitingHorz { - kUnspecifiedCsh = 0, - kLeftCollocated = 1, - kHalfCsh = 2, - }; - enum ChromaSitingVert { - kUnspecifiedCsv = 0, - kTopCollocated = 1, - kHalfCsv = 2, - }; - enum Range { - kUnspecifiedCr = 0, - kBroadcastRange = 1, - kFullRange = 2, - kMcTcDefined = 3, // Defined by MatrixCoefficients/TransferCharacteristics. - }; - enum TransferCharacteristics { - kIturBt709Tc = 1, - kUnspecifiedTc = 2, - kReservedTc = 3, - kGamma22Curve = 4, - kGamma28Curve = 5, - kSmpte170MTc = 6, - kSmpte240MTc = 7, - kLinear = 8, - kLog = 9, - kLogSqrt = 10, - kIec6196624 = 11, - kIturBt1361ExtendedColourGamut = 12, - kIec6196621 = 13, - kIturBt202010bit = 14, - kIturBt202012bit = 15, - kSmpteSt2084 = 16, - kSmpteSt4281Tc = 17, - kAribStdB67Hlg = 18, - }; - enum Primaries { - kReservedP0 = 0, - kIturBt709P = 1, - kUnspecifiedP = 2, - kReservedP3 = 3, - kIturBt470M = 4, - kIturBt470Bg = 5, - kSmpte170MP = 6, - kSmpte240MP = 7, - kFilm = 8, - kIturBt2020 = 9, - kSmpteSt4281P = 10, - kJedecP22Phosphors = 22, - }; - static const uint64_t kValueNotPresent; - Colour() - : matrix_coefficients_(kValueNotPresent), - bits_per_channel_(kValueNotPresent), - chroma_subsampling_horz_(kValueNotPresent), - chroma_subsampling_vert_(kValueNotPresent), - cb_subsampling_horz_(kValueNotPresent), - cb_subsampling_vert_(kValueNotPresent), - chroma_siting_horz_(kValueNotPresent), - chroma_siting_vert_(kValueNotPresent), - range_(kValueNotPresent), - transfer_characteristics_(kValueNotPresent), - primaries_(kValueNotPresent), - max_cll_(kValueNotPresent), - max_fall_(kValueNotPresent), - mastering_metadata_(NULL) {} - ~Colour() { delete mastering_metadata_; } - - // Returns total size of the Colour element. - uint64_t ColourSize() const; - bool Valid() const; - bool Write(IMkvWriter* writer) const; - - // Deep copies |mastering_metadata|. - bool SetMasteringMetadata(const MasteringMetadata& mastering_metadata); - - const MasteringMetadata* mastering_metadata() const { - return mastering_metadata_; - } - - uint64_t matrix_coefficients() const { return matrix_coefficients_; } - void set_matrix_coefficients(uint64_t matrix_coefficients) { - matrix_coefficients_ = matrix_coefficients; - } - uint64_t bits_per_channel() const { return bits_per_channel_; } - void set_bits_per_channel(uint64_t bits_per_channel) { - bits_per_channel_ = bits_per_channel; - } - uint64_t chroma_subsampling_horz() const { return chroma_subsampling_horz_; } - void set_chroma_subsampling_horz(uint64_t chroma_subsampling_horz) { - chroma_subsampling_horz_ = chroma_subsampling_horz; - } - uint64_t chroma_subsampling_vert() const { return chroma_subsampling_vert_; } - void set_chroma_subsampling_vert(uint64_t chroma_subsampling_vert) { - chroma_subsampling_vert_ = chroma_subsampling_vert; - } - uint64_t cb_subsampling_horz() const { return cb_subsampling_horz_; } - void set_cb_subsampling_horz(uint64_t cb_subsampling_horz) { - cb_subsampling_horz_ = cb_subsampling_horz; - } - uint64_t cb_subsampling_vert() const { return cb_subsampling_vert_; } - void set_cb_subsampling_vert(uint64_t cb_subsampling_vert) { - cb_subsampling_vert_ = cb_subsampling_vert; - } - uint64_t chroma_siting_horz() const { return chroma_siting_horz_; } - void set_chroma_siting_horz(uint64_t chroma_siting_horz) { - chroma_siting_horz_ = chroma_siting_horz; - } - uint64_t chroma_siting_vert() const { return chroma_siting_vert_; } - void set_chroma_siting_vert(uint64_t chroma_siting_vert) { - chroma_siting_vert_ = chroma_siting_vert; - } - uint64_t range() const { return range_; } - void set_range(uint64_t range) { range_ = range; } - uint64_t transfer_characteristics() const { - return transfer_characteristics_; - } - void set_transfer_characteristics(uint64_t transfer_characteristics) { - transfer_characteristics_ = transfer_characteristics; - } - uint64_t primaries() const { return primaries_; } - void set_primaries(uint64_t primaries) { primaries_ = primaries; } - uint64_t max_cll() const { return max_cll_; } - void set_max_cll(uint64_t max_cll) { max_cll_ = max_cll; } - uint64_t max_fall() const { return max_fall_; } - void set_max_fall(uint64_t max_fall) { max_fall_ = max_fall; } - - private: - // Returns size of Colour child elements. - uint64_t PayloadSize() const; - - uint64_t matrix_coefficients_; - uint64_t bits_per_channel_; - uint64_t chroma_subsampling_horz_; - uint64_t chroma_subsampling_vert_; - uint64_t cb_subsampling_horz_; - uint64_t cb_subsampling_vert_; - uint64_t chroma_siting_horz_; - uint64_t chroma_siting_vert_; - uint64_t range_; - uint64_t transfer_characteristics_; - uint64_t primaries_; - uint64_t max_cll_; - uint64_t max_fall_; - - MasteringMetadata* mastering_metadata_; -}; - -/////////////////////////////////////////////////////////////// -// Projection element. -class Projection { - public: - enum ProjectionType { - kTypeNotPresent = -1, - kRectangular = 0, - kEquirectangular = 1, - kCubeMap = 2, - kMesh = 3, - }; - static const uint64_t kValueNotPresent; - Projection() - : type_(kRectangular), - pose_yaw_(0.0), - pose_pitch_(0.0), - pose_roll_(0.0), - private_data_(NULL), - private_data_length_(0) {} - ~Projection() { delete[] private_data_; } - - uint64_t ProjectionSize() const; - bool Write(IMkvWriter* writer) const; - - bool SetProjectionPrivate(const uint8_t* private_data, - uint64_t private_data_length); - - ProjectionType type() const { return type_; } - void set_type(ProjectionType type) { type_ = type; } - float pose_yaw() const { return pose_yaw_; } - void set_pose_yaw(float pose_yaw) { pose_yaw_ = pose_yaw; } - float pose_pitch() const { return pose_pitch_; } - void set_pose_pitch(float pose_pitch) { pose_pitch_ = pose_pitch; } - float pose_roll() const { return pose_roll_; } - void set_pose_roll(float pose_roll) { pose_roll_ = pose_roll; } - uint8_t* private_data() const { return private_data_; } - uint64_t private_data_length() const { return private_data_length_; } - - private: - // Returns size of VideoProjection child elements. - uint64_t PayloadSize() const; - - ProjectionType type_; - float pose_yaw_; - float pose_pitch_; - float pose_roll_; - uint8_t* private_data_; - uint64_t private_data_length_; -}; - -/////////////////////////////////////////////////////////////// -// Track element. -class Track { - public: - // The |seed| parameter is used to synthesize a UID for the track. - explicit Track(unsigned int* seed); - virtual ~Track(); - - // Adds a ContentEncoding element to the Track. Returns true on success. - virtual bool AddContentEncoding(); - - // Returns the ContentEncoding by index. Returns NULL if there is no - // ContentEncoding match. - ContentEncoding* GetContentEncodingByIndex(uint32_t index) const; - - // Returns the size in bytes for the payload of the Track element. - virtual uint64_t PayloadSize() const; - - // Returns the size in bytes of the Track element. - virtual uint64_t Size() const; - - // Output the Track element to the writer. Returns true on success. - virtual bool Write(IMkvWriter* writer) const; - - // Sets the CodecPrivate element of the Track element. Copies |length| - // bytes from |codec_private| to |codec_private_|. Returns true on success. - bool SetCodecPrivate(const uint8_t* codec_private, uint64_t length); - - void set_codec_id(const char* codec_id); - const char* codec_id() const { return codec_id_; } - const uint8_t* codec_private() const { return codec_private_; } - void set_language(const char* language); - const char* language() const { return language_; } - void set_max_block_additional_id(uint64_t max_block_additional_id) { - max_block_additional_id_ = max_block_additional_id; - } - uint64_t max_block_additional_id() const { return max_block_additional_id_; } - void set_name(const char* name); - const char* name() const { return name_; } - void set_number(uint64_t number) { number_ = number; } - uint64_t number() const { return number_; } - void set_type(uint64_t type) { type_ = type; } - uint64_t type() const { return type_; } - void set_uid(uint64_t uid) { uid_ = uid; } - uint64_t uid() const { return uid_; } - void set_codec_delay(uint64_t codec_delay) { codec_delay_ = codec_delay; } - uint64_t codec_delay() const { return codec_delay_; } - void set_seek_pre_roll(uint64_t seek_pre_roll) { - seek_pre_roll_ = seek_pre_roll; - } - uint64_t seek_pre_roll() const { return seek_pre_roll_; } - void set_default_duration(uint64_t default_duration) { - default_duration_ = default_duration; - } - uint64_t default_duration() const { return default_duration_; } - - uint64_t codec_private_length() const { return codec_private_length_; } - uint32_t content_encoding_entries_size() const { - return content_encoding_entries_size_; - } - - private: - // Track element names. - char* codec_id_; - uint8_t* codec_private_; - char* language_; - uint64_t max_block_additional_id_; - char* name_; - uint64_t number_; - uint64_t type_; - uint64_t uid_; - uint64_t codec_delay_; - uint64_t seek_pre_roll_; - uint64_t default_duration_; - - // Size of the CodecPrivate data in bytes. - uint64_t codec_private_length_; - - // ContentEncoding element list. - ContentEncoding** content_encoding_entries_; - - // Number of ContentEncoding elements added. - uint32_t content_encoding_entries_size_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Track); -}; - -/////////////////////////////////////////////////////////////// -// Track that has video specific elements. -class VideoTrack : public Track { - public: - // Supported modes for stereo 3D. - enum StereoMode { - kMono = 0, - kSideBySideLeftIsFirst = 1, - kTopBottomRightIsFirst = 2, - kTopBottomLeftIsFirst = 3, - kSideBySideRightIsFirst = 11 - }; - - enum AlphaMode { kNoAlpha = 0, kAlpha = 1 }; - - // The |seed| parameter is used to synthesize a UID for the track. - explicit VideoTrack(unsigned int* seed); - virtual ~VideoTrack(); - - // Returns the size in bytes for the payload of the Track element plus the - // video specific elements. - virtual uint64_t PayloadSize() const; - - // Output the VideoTrack element to the writer. Returns true on success. - virtual bool Write(IMkvWriter* writer) const; - - // Sets the video's stereo mode. Returns true on success. - bool SetStereoMode(uint64_t stereo_mode); - - // Sets the video's alpha mode. Returns true on success. - bool SetAlphaMode(uint64_t alpha_mode); - - void set_display_height(uint64_t height) { display_height_ = height; } - uint64_t display_height() const { return display_height_; } - void set_display_width(uint64_t width) { display_width_ = width; } - uint64_t display_width() const { return display_width_; } - void set_pixel_height(uint64_t height) { pixel_height_ = height; } - uint64_t pixel_height() const { return pixel_height_; } - void set_pixel_width(uint64_t width) { pixel_width_ = width; } - uint64_t pixel_width() const { return pixel_width_; } - - void set_crop_left(uint64_t crop_left) { crop_left_ = crop_left; } - uint64_t crop_left() const { return crop_left_; } - void set_crop_right(uint64_t crop_right) { crop_right_ = crop_right; } - uint64_t crop_right() const { return crop_right_; } - void set_crop_top(uint64_t crop_top) { crop_top_ = crop_top; } - uint64_t crop_top() const { return crop_top_; } - void set_crop_bottom(uint64_t crop_bottom) { crop_bottom_ = crop_bottom; } - uint64_t crop_bottom() const { return crop_bottom_; } - - void set_frame_rate(double frame_rate) { frame_rate_ = frame_rate; } - double frame_rate() const { return frame_rate_; } - void set_height(uint64_t height) { height_ = height; } - uint64_t height() const { return height_; } - uint64_t stereo_mode() { return stereo_mode_; } - uint64_t alpha_mode() { return alpha_mode_; } - void set_width(uint64_t width) { width_ = width; } - uint64_t width() const { return width_; } - void set_colour_space(const char* colour_space); - const char* colour_space() const { return colour_space_; } - - Colour* colour() { return colour_; } - - // Deep copies |colour|. - bool SetColour(const Colour& colour); - - Projection* projection() { return projection_; } - - // Deep copies |projection|. - bool SetProjection(const Projection& projection); - - private: - // Returns the size in bytes of the Video element. - uint64_t VideoPayloadSize() const; - - // Video track element names. - uint64_t display_height_; - uint64_t display_width_; - uint64_t pixel_height_; - uint64_t pixel_width_; - uint64_t crop_left_; - uint64_t crop_right_; - uint64_t crop_top_; - uint64_t crop_bottom_; - double frame_rate_; - uint64_t height_; - uint64_t stereo_mode_; - uint64_t alpha_mode_; - uint64_t width_; - char* colour_space_; - - Colour* colour_; - Projection* projection_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(VideoTrack); -}; - -/////////////////////////////////////////////////////////////// -// Track that has audio specific elements. -class AudioTrack : public Track { - public: - // The |seed| parameter is used to synthesize a UID for the track. - explicit AudioTrack(unsigned int* seed); - virtual ~AudioTrack(); - - // Returns the size in bytes for the payload of the Track element plus the - // audio specific elements. - virtual uint64_t PayloadSize() const; - - // Output the AudioTrack element to the writer. Returns true on success. - virtual bool Write(IMkvWriter* writer) const; - - void set_bit_depth(uint64_t bit_depth) { bit_depth_ = bit_depth; } - uint64_t bit_depth() const { return bit_depth_; } - void set_channels(uint64_t channels) { channels_ = channels; } - uint64_t channels() const { return channels_; } - void set_sample_rate(double sample_rate) { sample_rate_ = sample_rate; } - double sample_rate() const { return sample_rate_; } - - private: - // Audio track element names. - uint64_t bit_depth_; - uint64_t channels_; - double sample_rate_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(AudioTrack); -}; - -/////////////////////////////////////////////////////////////// -// Tracks element -class Tracks { - public: - // Audio and video type defined by the Matroska specs. - enum { kVideo = 0x1, kAudio = 0x2 }; - - static const char kOpusCodecId[]; - static const char kVorbisCodecId[]; - static const char kAv1CodecId[]; - static const char kVp8CodecId[]; - static const char kVp9CodecId[]; - static const char kWebVttCaptionsId[]; - static const char kWebVttDescriptionsId[]; - static const char kWebVttMetadataId[]; - static const char kWebVttSubtitlesId[]; - - Tracks(); - ~Tracks(); - - // Adds a Track element to the Tracks object. |track| will be owned and - // deleted by the Tracks object. Returns true on success. |number| is the - // number to use for the track. |number| must be >= 0. If |number| == 0 - // then the muxer will decide on the track number. - bool AddTrack(Track* track, int32_t number); - - // Returns the track by index. Returns NULL if there is no track match. - const Track* GetTrackByIndex(uint32_t idx) const; - - // Search the Tracks and return the track that matches |tn|. Returns NULL - // if there is no track match. - Track* GetTrackByNumber(uint64_t track_number) const; - - // Returns true if the track number is an audio track. - bool TrackIsAudio(uint64_t track_number) const; - - // Returns true if the track number is a video track. - bool TrackIsVideo(uint64_t track_number) const; - - // Output the Tracks element to the writer. Returns true on success. - bool Write(IMkvWriter* writer) const; - - uint32_t track_entries_size() const { return track_entries_size_; } - - private: - // Track element list. - Track** track_entries_; - - // Number of Track elements added. - uint32_t track_entries_size_; - - // Whether or not Tracks element has already been written via IMkvWriter. - mutable bool wrote_tracks_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tracks); -}; - -/////////////////////////////////////////////////////////////// -// Chapter element -// -class Chapter { - public: - // Set the identifier for this chapter. (This corresponds to the - // Cue Identifier line in WebVTT.) - // TODO(matthewjheaney): the actual serialization of this item in - // MKV is pending. - bool set_id(const char* id); - - // Converts the nanosecond start and stop times of this chapter to - // their corresponding timecode values, and stores them that way. - void set_time(const Segment& segment, uint64_t start_time_ns, - uint64_t end_time_ns); - - // Sets the uid for this chapter. Primarily used to enable - // deterministic output from the muxer. - void set_uid(const uint64_t uid) { uid_ = uid; } - - // Add a title string to this chapter, per the semantics described - // here: - // http://www.matroska.org/technical/specs/index.html - // - // The title ("chapter string") is a UTF-8 string. - // - // The language has ISO 639-2 representation, described here: - // http://www.loc.gov/standards/iso639-2/englangn.html - // http://www.loc.gov/standards/iso639-2/php/English_list.php - // If you specify NULL as the language value, this implies - // English ("eng"). - // - // The country value corresponds to the codes listed here: - // http://www.iana.org/domains/root/db/ - // - // The function returns false if the string could not be allocated. - bool add_string(const char* title, const char* language, const char* country); - - private: - friend class Chapters; - - // For storage of chapter titles that differ by language. - class Display { - public: - // Establish representation invariant for new Display object. - void Init(); - - // Reclaim resources, in anticipation of destruction. - void Clear(); - - // Copies the title to the |title_| member. Returns false on - // error. - bool set_title(const char* title); - - // Copies the language to the |language_| member. Returns false - // on error. - bool set_language(const char* language); - - // Copies the country to the |country_| member. Returns false on - // error. - bool set_country(const char* country); - - // If |writer| is non-NULL, serialize the Display sub-element of - // the Atom into the stream. Returns the Display element size on - // success, 0 if error. - uint64_t WriteDisplay(IMkvWriter* writer) const; - - private: - char* title_; - char* language_; - char* country_; - }; - - Chapter(); - ~Chapter(); - - // Establish the representation invariant for a newly-created - // Chapter object. The |seed| parameter is used to create the UID - // for this chapter atom. - void Init(unsigned int* seed); - - // Copies this Chapter object to a different one. This is used when - // expanding a plain array of Chapter objects (see Chapters). - void ShallowCopy(Chapter* dst) const; - - // Reclaim resources used by this Chapter object, pending its - // destruction. - void Clear(); - - // If there is no storage remaining on the |displays_| array for a - // new display object, creates a new, longer array and copies the - // existing Display objects to the new array. Returns false if the - // array cannot be expanded. - bool ExpandDisplaysArray(); - - // If |writer| is non-NULL, serialize the Atom sub-element into the - // stream. Returns the total size of the element on success, 0 if - // error. - uint64_t WriteAtom(IMkvWriter* writer) const; - - // The string identifier for this chapter (corresponds to WebVTT cue - // identifier). - char* id_; - - // Start timecode of the chapter. - uint64_t start_timecode_; - - // Stop timecode of the chapter. - uint64_t end_timecode_; - - // The binary identifier for this chapter. - uint64_t uid_; - - // The Atom element can contain multiple Display sub-elements, as - // the same logical title can be rendered in different languages. - Display* displays_; - - // The physical length (total size) of the |displays_| array. - int displays_size_; - - // The logical length (number of active elements) on the |displays_| - // array. - int displays_count_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapter); -}; - -/////////////////////////////////////////////////////////////// -// Chapters element -// -class Chapters { - public: - Chapters(); - ~Chapters(); - - Chapter* AddChapter(unsigned int* seed); - - // Returns the number of chapters that have been added. - int Count() const; - - // Output the Chapters element to the writer. Returns true on success. - bool Write(IMkvWriter* writer) const; - - private: - // Expands the chapters_ array if there is not enough space to contain - // another chapter object. Returns true on success. - bool ExpandChaptersArray(); - - // If |writer| is non-NULL, serialize the Edition sub-element of the - // Chapters element into the stream. Returns the Edition element - // size on success, 0 if error. - uint64_t WriteEdition(IMkvWriter* writer) const; - - // Total length of the chapters_ array. - int chapters_size_; - - // Number of active chapters on the chapters_ array. - int chapters_count_; - - // Array for storage of chapter objects. - Chapter* chapters_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapters); -}; - -/////////////////////////////////////////////////////////////// -// Tag element -// -class Tag { - public: - bool add_simple_tag(const char* tag_name, const char* tag_string); - - private: - // Tags calls Clear and the destructor of Tag - friend class Tags; - - // For storage of simple tags - class SimpleTag { - public: - // Establish representation invariant for new SimpleTag object. - void Init(); - - // Reclaim resources, in anticipation of destruction. - void Clear(); - - // Copies the title to the |tag_name_| member. Returns false on - // error. - bool set_tag_name(const char* tag_name); - - // Copies the language to the |tag_string_| member. Returns false - // on error. - bool set_tag_string(const char* tag_string); - - // If |writer| is non-NULL, serialize the SimpleTag sub-element of - // the Atom into the stream. Returns the SimpleTag element size on - // success, 0 if error. - uint64_t Write(IMkvWriter* writer) const; - - private: - char* tag_name_; - char* tag_string_; - }; - - Tag(); - ~Tag(); - - // Copies this Tag object to a different one. This is used when - // expanding a plain array of Tag objects (see Tags). - void ShallowCopy(Tag* dst) const; - - // Reclaim resources used by this Tag object, pending its - // destruction. - void Clear(); - - // If there is no storage remaining on the |simple_tags_| array for a - // new display object, creates a new, longer array and copies the - // existing SimpleTag objects to the new array. Returns false if the - // array cannot be expanded. - bool ExpandSimpleTagsArray(); - - // If |writer| is non-NULL, serialize the Tag sub-element into the - // stream. Returns the total size of the element on success, 0 if - // error. - uint64_t Write(IMkvWriter* writer) const; - - // The Atom element can contain multiple SimpleTag sub-elements - SimpleTag* simple_tags_; - - // The physical length (total size) of the |simple_tags_| array. - int simple_tags_size_; - - // The logical length (number of active elements) on the |simple_tags_| - // array. - int simple_tags_count_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tag); -}; - -/////////////////////////////////////////////////////////////// -// Tags element -// -class Tags { - public: - Tags(); - ~Tags(); - - Tag* AddTag(); - - // Returns the number of tags that have been added. - int Count() const; - - // Output the Tags element to the writer. Returns true on success. - bool Write(IMkvWriter* writer) const; - - private: - // Expands the tags_ array if there is not enough space to contain - // another tag object. Returns true on success. - bool ExpandTagsArray(); - - // Total length of the tags_ array. - int tags_size_; - - // Number of active tags on the tags_ array. - int tags_count_; - - // Array for storage of tag objects. - Tag* tags_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tags); -}; - -/////////////////////////////////////////////////////////////// -// Cluster element -// -// Notes: -// |Init| must be called before any other method in this class. -class Cluster { - public: - // |timecode| is the absolute timecode of the cluster. |cues_pos| is the - // position for the cluster within the segment that should be written in - // the cues element. |timecode_scale| is the timecode scale of the segment. - Cluster(uint64_t timecode, int64_t cues_pos, uint64_t timecode_scale, - bool write_last_frame_with_duration = false, - bool fixed_size_timecode = false); - ~Cluster(); - - bool Init(IMkvWriter* ptr_writer); - - // Adds a frame to be output in the file. The frame is written out through - // |writer_| if successful. Returns true on success. - bool AddFrame(const Frame* frame); - - // Adds a frame to be output in the file. The frame is written out through - // |writer_| if successful. Returns true on success. - // Inputs: - // data: Pointer to the data - // length: Length of the data - // track_number: Track to add the data to. Value returned by Add track - // functions. The range of allowed values is [1, 126]. - // timecode: Absolute (not relative to cluster) timestamp of the - // frame, expressed in timecode units. - // is_key: Flag telling whether or not this frame is a key frame. - bool AddFrame(const uint8_t* data, uint64_t length, uint64_t track_number, - uint64_t timecode, // timecode units (absolute) - bool is_key); - - // Adds a frame to be output in the file. The frame is written out through - // |writer_| if successful. Returns true on success. - // Inputs: - // data: Pointer to the data - // length: Length of the data - // additional: Pointer to the additional data - // additional_length: Length of the additional data - // add_id: Value of BlockAddID element - // track_number: Track to add the data to. Value returned by Add track - // functions. The range of allowed values is [1, 126]. - // abs_timecode: Absolute (not relative to cluster) timestamp of the - // frame, expressed in timecode units. - // is_key: Flag telling whether or not this frame is a key frame. - bool AddFrameWithAdditional(const uint8_t* data, uint64_t length, - const uint8_t* additional, - uint64_t additional_length, uint64_t add_id, - uint64_t track_number, uint64_t abs_timecode, - bool is_key); - - // Adds a frame to be output in the file. The frame is written out through - // |writer_| if successful. Returns true on success. - // Inputs: - // data: Pointer to the data. - // length: Length of the data. - // discard_padding: DiscardPadding element value. - // track_number: Track to add the data to. Value returned by Add track - // functions. The range of allowed values is [1, 126]. - // abs_timecode: Absolute (not relative to cluster) timestamp of the - // frame, expressed in timecode units. - // is_key: Flag telling whether or not this frame is a key frame. - bool AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length, - int64_t discard_padding, - uint64_t track_number, uint64_t abs_timecode, - bool is_key); - - // Writes a frame of metadata to the output medium; returns true on - // success. - // Inputs: - // data: Pointer to the data - // length: Length of the data - // track_number: Track to add the data to. Value returned by Add track - // functions. The range of allowed values is [1, 126]. - // timecode: Absolute (not relative to cluster) timestamp of the - // metadata frame, expressed in timecode units. - // duration: Duration of metadata frame, in timecode units. - // - // The metadata frame is written as a block group, with a duration - // sub-element but no reference time sub-elements (indicating that - // it is considered a keyframe, per Matroska semantics). - bool AddMetadata(const uint8_t* data, uint64_t length, uint64_t track_number, - uint64_t timecode, uint64_t duration); - - // Increments the size of the cluster's data in bytes. - void AddPayloadSize(uint64_t size); - - // Closes the cluster so no more data can be written to it. Will update the - // cluster's size if |writer_| is seekable. Returns true on success. This - // variant of Finalize() fails when |write_last_frame_with_duration_| is set - // to true. - bool Finalize(); - - // Closes the cluster so no more data can be written to it. Will update the - // cluster's size if |writer_| is seekable. Returns true on success. - // Inputs: - // set_last_frame_duration: Boolean indicating whether or not the duration - // of the last frame should be set. If set to - // false, the |duration| value is ignored and - // |write_last_frame_with_duration_| will not be - // honored. - // duration: Duration of the Cluster in timecode scale. - bool Finalize(bool set_last_frame_duration, uint64_t duration); - - // Returns the size in bytes for the entire Cluster element. - uint64_t Size() const; - - // Given |abs_timecode|, calculates timecode relative to most recent timecode. - // Returns -1 on failure, or a relative timecode. - int64_t GetRelativeTimecode(int64_t abs_timecode) const; - - int64_t size_position() const { return size_position_; } - int32_t blocks_added() const { return blocks_added_; } - uint64_t payload_size() const { return payload_size_; } - int64_t position_for_cues() const { return position_for_cues_; } - uint64_t timecode() const { return timecode_; } - uint64_t timecode_scale() const { return timecode_scale_; } - void set_write_last_frame_with_duration(bool write_last_frame_with_duration) { - write_last_frame_with_duration_ = write_last_frame_with_duration; - } - bool write_last_frame_with_duration() const { - return write_last_frame_with_duration_; - } - - private: - // Iterator type for the |stored_frames_| map. - typedef std::map >::iterator FrameMapIterator; - - // Utility method that confirms that blocks can still be added, and that the - // cluster header has been written. Used by |DoWriteFrame*|. Returns true - // when successful. - bool PreWriteBlock(); - - // Utility method used by the |DoWriteFrame*| methods that handles the book - // keeping required after each block is written. - void PostWriteBlock(uint64_t element_size); - - // Does some verification and calls WriteFrame. - bool DoWriteFrame(const Frame* const frame); - - // Either holds back the given frame, or writes it out depending on whether or - // not |write_last_frame_with_duration_| is set. - bool QueueOrWriteFrame(const Frame* const frame); - - // Outputs the Cluster header to |writer_|. Returns true on success. - bool WriteClusterHeader(); - - // Number of blocks added to the cluster. - int32_t blocks_added_; - - // Flag telling if the cluster has been closed. - bool finalized_; - - // Flag indicating whether the cluster's timecode will always be written out - // using 8 bytes. - bool fixed_size_timecode_; - - // Flag telling if the cluster's header has been written. - bool header_written_; - - // The size of the cluster elements in bytes. - uint64_t payload_size_; - - // The file position used for cue points. - const int64_t position_for_cues_; - - // The file position of the cluster's size element. - int64_t size_position_; - - // The absolute timecode of the cluster. - const uint64_t timecode_; - - // The timecode scale of the Segment containing the cluster. - const uint64_t timecode_scale_; - - // Flag indicating whether the last frame of the cluster should be written as - // a Block with Duration. If set to true, then it will result in holding back - // of frames and the parameterized version of Finalize() must be called to - // finish writing the Cluster. - bool write_last_frame_with_duration_; - - // Map used to hold back frames, if required. Track number is the key. - std::map > stored_frames_; - - // Map from track number to the timestamp of the last block written for that - // track. - std::map last_block_timestamp_; - - // Pointer to the writer object. Not owned by this class. - IMkvWriter* writer_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Cluster); -}; - -/////////////////////////////////////////////////////////////// -// SeekHead element -class SeekHead { - public: - SeekHead(); - ~SeekHead(); - - // TODO(fgalligan): Change this to reserve a certain size. Then check how - // big the seek entry to be added is as not every seek entry will be the - // maximum size it could be. - // Adds a seek entry to be written out when the element is finalized. |id| - // must be the coded mkv element id. |pos| is the file position of the - // element. Returns true on success. - bool AddSeekEntry(uint32_t id, uint64_t pos); - - // Writes out SeekHead and SeekEntry elements. Returns true on success. - bool Finalize(IMkvWriter* writer) const; - - // Returns the id of the Seek Entry at the given index. Returns -1 if index is - // out of range. - uint32_t GetId(int index) const; - - // Returns the position of the Seek Entry at the given index. Returns -1 if - // index is out of range. - uint64_t GetPosition(int index) const; - - // Sets the Seek Entry id and position at given index. - // Returns true on success. - bool SetSeekEntry(int index, uint32_t id, uint64_t position); - - // Reserves space by writing out a Void element which will be updated with - // a SeekHead element later. Returns true on success. - bool Write(IMkvWriter* writer); - - // We are going to put a cap on the number of Seek Entries. - constexpr static int32_t kSeekEntryCount = 5; - - private: - // Returns the maximum size in bytes of one seek entry. - uint64_t MaxEntrySize() const; - - // Seek entry id element list. - uint32_t seek_entry_id_[kSeekEntryCount]; - - // Seek entry pos element list. - uint64_t seek_entry_pos_[kSeekEntryCount]; - - // The file position of SeekHead element. - int64_t start_pos_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SeekHead); -}; - -/////////////////////////////////////////////////////////////// -// Segment Information element -class SegmentInfo { - public: - SegmentInfo(); - ~SegmentInfo(); - - // Will update the duration if |duration_| is > 0.0. Returns true on success. - bool Finalize(IMkvWriter* writer) const; - - // Sets |muxing_app_| and |writing_app_|. - bool Init(); - - // Output the Segment Information element to the writer. Returns true on - // success. - bool Write(IMkvWriter* writer); - - void set_duration(double duration) { duration_ = duration; } - double duration() const { return duration_; } - void set_muxing_app(const char* app); - const char* muxing_app() const { return muxing_app_; } - void set_timecode_scale(uint64_t scale) { timecode_scale_ = scale; } - uint64_t timecode_scale() const { return timecode_scale_; } - void set_writing_app(const char* app); - const char* writing_app() const { return writing_app_; } - void set_date_utc(int64_t date_utc) { date_utc_ = date_utc; } - int64_t date_utc() const { return date_utc_; } - - private: - // Segment Information element names. - // Initially set to -1 to signify that a duration has not been set and should - // not be written out. - double duration_; - // Set to libwebm-%d.%d.%d.%d, major, minor, build, revision. - char* muxing_app_; - uint64_t timecode_scale_; - // Initially set to libwebm-%d.%d.%d.%d, major, minor, build, revision. - char* writing_app_; - // INT64_MIN when DateUTC is not set. - int64_t date_utc_; - - // The file position of the duration element. - int64_t duration_pos_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SegmentInfo); -}; - -/////////////////////////////////////////////////////////////// -// This class represents the main segment in a WebM file. Currently only -// supports one Segment element. -// -// Notes: -// |Init| must be called before any other method in this class. -class Segment { - public: - enum Mode { kLive = 0x1, kFile = 0x2 }; - - enum CuesPosition { - kAfterClusters = 0x0, // Position Cues after Clusters - Default - kBeforeClusters = 0x1 // Position Cues before Clusters - }; - - static constexpr uint32_t kDefaultDocTypeVersion = 4; - static constexpr uint64_t kDefaultMaxClusterDuration = 30000000000ULL; - - Segment(); - ~Segment(); - - // Initializes |SegmentInfo| and returns result. Always returns false when - // |ptr_writer| is NULL. - bool Init(IMkvWriter* ptr_writer); - - // Adds a generic track to the segment. Returns the newly-allocated - // track object (which is owned by the segment) on success, NULL on - // error. |number| is the number to use for the track. |number| - // must be >= 0. If |number| == 0 then the muxer will decide on the - // track number. - Track* AddTrack(int32_t number); - - // Adds a Vorbis audio track to the segment. Returns the number of the track - // on success, 0 on error. |number| is the number to use for the audio track. - // |number| must be >= 0. If |number| == 0 then the muxer will decide on - // the track number. - uint64_t AddAudioTrack(int32_t sample_rate, int32_t channels, int32_t number); - - // Adds an empty chapter to the chapters of this segment. Returns - // non-NULL on success. After adding the chapter, the caller should - // populate its fields via the Chapter member functions. - Chapter* AddChapter(); - - // Adds an empty tag to the tags of this segment. Returns - // non-NULL on success. After adding the tag, the caller should - // populate its fields via the Tag member functions. - Tag* AddTag(); - - // Adds a cue point to the Cues element. |timestamp| is the time in - // nanoseconds of the cue's time. |track| is the Track of the Cue. This - // function must be called after AddFrame to calculate the correct - // BlockNumber for the CuePoint. Returns true on success. - bool AddCuePoint(uint64_t timestamp, uint64_t track); - - // Adds a frame to be output in the file. Returns true on success. - // Inputs: - // data: Pointer to the data - // length: Length of the data - // track_number: Track to add the data to. Value returned by Add track - // functions. - // timestamp: Timestamp of the frame in nanoseconds from 0. - // is_key: Flag telling whether or not this frame is a key frame. - bool AddFrame(const uint8_t* data, uint64_t length, uint64_t track_number, - uint64_t timestamp_ns, bool is_key); - - // Writes a frame of metadata to the output medium; returns true on - // success. - // Inputs: - // data: Pointer to the data - // length: Length of the data - // track_number: Track to add the data to. Value returned by Add track - // functions. - // timecode: Absolute timestamp of the metadata frame, expressed - // in nanosecond units. - // duration: Duration of metadata frame, in nanosecond units. - // - // The metadata frame is written as a block group, with a duration - // sub-element but no reference time sub-elements (indicating that - // it is considered a keyframe, per Matroska semantics). - bool AddMetadata(const uint8_t* data, uint64_t length, uint64_t track_number, - uint64_t timestamp_ns, uint64_t duration_ns); - - // Writes a frame with additional data to the output medium; returns true on - // success. - // Inputs: - // data: Pointer to the data. - // length: Length of the data. - // additional: Pointer to additional data. - // additional_length: Length of additional data. - // add_id: Additional ID which identifies the type of additional data. - // track_number: Track to add the data to. Value returned by Add track - // functions. - // timestamp: Absolute timestamp of the frame, expressed in nanosecond - // units. - // is_key: Flag telling whether or not this frame is a key frame. - bool AddFrameWithAdditional(const uint8_t* data, uint64_t length, - const uint8_t* additional, - uint64_t additional_length, uint64_t add_id, - uint64_t track_number, uint64_t timestamp, - bool is_key); - - // Writes a frame with DiscardPadding to the output medium; returns true on - // success. - // Inputs: - // data: Pointer to the data. - // length: Length of the data. - // discard_padding: DiscardPadding element value. - // track_number: Track to add the data to. Value returned by Add track - // functions. - // timestamp: Absolute timestamp of the frame, expressed in nanosecond - // units. - // is_key: Flag telling whether or not this frame is a key frame. - bool AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length, - int64_t discard_padding, - uint64_t track_number, uint64_t timestamp, - bool is_key); - - // Writes a Frame to the output medium. Chooses the correct way of writing - // the frame (Block vs SimpleBlock) based on the parameters passed. - // Inputs: - // frame: frame object - bool AddGenericFrame(const Frame* frame); - - // Adds a VP8 video track to the segment. Returns the number of the track on - // success, 0 on error. |number| is the number to use for the video track. - // |number| must be >= 0. If |number| == 0 then the muxer will decide on - // the track number. - uint64_t AddVideoTrack(int32_t width, int32_t height, int32_t number); - - // This function must be called after Finalize() if you need a copy of the - // output with Cues written before the Clusters. It will return false if the - // writer is not seekable of if chunking is set to true. - // Input parameters: - // reader - an IMkvReader object created with the same underlying file of the - // current writer object. Make sure to close the existing writer - // object before creating this so that all the data is properly - // flushed and available for reading. - // writer - an IMkvWriter object pointing to a *different* file than the one - // pointed by the current writer object. This file will contain the - // Cues element before the Clusters. - bool CopyAndMoveCuesBeforeClusters(mkvparser::IMkvReader* reader, - IMkvWriter* writer); - - // Sets which track to use for the Cues element. Must have added the track - // before calling this function. Returns true on success. |track_number| is - // returned by the Add track functions. - bool CuesTrack(uint64_t track_number); - - // This will force the muxer to create a new Cluster when the next frame is - // added. - void ForceNewClusterOnNextFrame(); - - // Writes out any frames that have not been written out. Finalizes the last - // cluster. May update the size and duration of the segment. May output the - // Cues element. May finalize the SeekHead element. Returns true on success. - bool Finalize(); - - // Returns the Cues object. - Cues* GetCues() { return &cues_; } - - // Returns the Segment Information object. - const SegmentInfo* GetSegmentInfo() const { return &segment_info_; } - SegmentInfo* GetSegmentInfo() { return &segment_info_; } - - // Search the Tracks and return the track that matches |track_number|. - // Returns NULL if there is no track match. - Track* GetTrackByNumber(uint64_t track_number) const; - - // Toggles whether to output a cues element. - void OutputCues(bool output_cues); - - // Toggles whether to write the last frame in each Cluster with Duration. - void AccurateClusterDuration(bool accurate_cluster_duration); - - // Toggles whether to write the Cluster Timecode using exactly 8 bytes. - void UseFixedSizeClusterTimecode(bool fixed_size_cluster_timecode); - - // Sets if the muxer will output files in chunks or not. |chunking| is a - // flag telling whether or not to turn on chunking. |filename| is the base - // filename for the chunk files. The header chunk file will be named - // |filename|.hdr and the data chunks will be named - // |filename|_XXXXXX.chk. Chunking implies that the muxer will be writing - // to files so the muxer will use the default MkvWriter class to control - // what data is written to what files. Returns true on success. - // TODO: Should we change the IMkvWriter Interface to add Open and Close? - // That will force the interface to be dependent on files. - bool SetChunking(bool chunking, const char* filename); - - bool chunking() const { return chunking_; } - uint64_t cues_track() const { return cues_track_; } - void set_max_cluster_duration(uint64_t max_cluster_duration) { - max_cluster_duration_ = max_cluster_duration; - } - uint64_t max_cluster_duration() const { return max_cluster_duration_; } - void set_max_cluster_size(uint64_t max_cluster_size) { - max_cluster_size_ = max_cluster_size; - } - uint64_t max_cluster_size() const { return max_cluster_size_; } - void set_mode(Mode mode) { mode_ = mode; } - Mode mode() const { return mode_; } - CuesPosition cues_position() const { return cues_position_; } - bool output_cues() const { return output_cues_; } - void set_estimate_file_duration(bool estimate_duration) { - estimate_file_duration_ = estimate_duration; - } - bool estimate_file_duration() const { return estimate_file_duration_; } - const SegmentInfo* segment_info() const { return &segment_info_; } - void set_duration(double duration) { duration_ = duration; } - double duration() const { return duration_; } - - // Returns true when codec IDs are valid for WebM. - bool DocTypeIsWebm() const; - - private: - // Checks if header information has been output and initialized. If not it - // will output the Segment element and initialize the SeekHead elment and - // Cues elements. - bool CheckHeaderInfo(); - - // Sets |doc_type_version_| based on the current element requirements. - void UpdateDocTypeVersion(); - - // Sets |name| according to how many chunks have been written. |ext| is the - // file extension. |name| must be deleted by the calling app. Returns true - // on success. - bool UpdateChunkName(const char* ext, char** name) const; - - // Returns the maximum offset within the segment's payload. When chunking - // this function is needed to determine offsets of elements within the - // chunked files. Returns -1 on error. - int64_t MaxOffset(); - - // Adds the frame to our frame array. - bool QueueFrame(Frame* frame); - - // Output all frames that are queued. Returns -1 on error, otherwise - // it returns the number of frames written. - int WriteFramesAll(); - - // Output all frames that are queued that have an end time that is less - // then |timestamp|. Returns true on success and if there are no frames - // queued. - bool WriteFramesLessThan(uint64_t timestamp); - - // Outputs the segment header, Segment Information element, SeekHead element, - // and Tracks element to |writer_|. - bool WriteSegmentHeader(); - - // Given a frame with the specified timestamp (nanosecond units) and - // keyframe status, determine whether a new cluster should be - // created, before writing enqueued frames and the frame itself. The - // function returns one of the following values: - // -1 = error: an out-of-order frame was detected - // 0 = do not create a new cluster, and write frame to the existing cluster - // 1 = create a new cluster, and write frame to that new cluster - // 2 = create a new cluster, and re-run test - int TestFrame(uint64_t track_num, uint64_t timestamp_ns, bool key) const; - - // Create a new cluster, using the earlier of the first enqueued - // frame, or the indicated time. Returns true on success. - bool MakeNewCluster(uint64_t timestamp_ns); - - // Checks whether a new cluster needs to be created, and if so - // creates a new cluster. Returns false if creation of a new cluster - // was necessary but creation was not successful. - bool DoNewClusterProcessing(uint64_t track_num, uint64_t timestamp_ns, - bool key); - - // Adjusts Cue Point values (to place Cues before Clusters) so that they - // reflect the correct offsets. - void MoveCuesBeforeClusters(); - - // This function recursively computes the correct cluster offsets (this is - // done to move the Cues before Clusters). It recursively updates the change - // in size (which indicates a change in cluster offset) until no sizes change. - // Parameters: - // diff - indicates the difference in size of the Cues element that needs to - // accounted for. - // index - index in the list of Cues which is currently being adjusted. - // cue_size - sum of size of all the CuePoint elements. - void MoveCuesBeforeClustersHelper(uint64_t diff, int index, - uint64_t* cue_size); - - // Seeds the random number generator used to make UIDs. - unsigned int seed_; - - // WebM elements - Cues cues_; - SeekHead seek_head_; - SegmentInfo segment_info_; - Tracks tracks_; - Chapters chapters_; - Tags tags_; - - // Number of chunks written. - int chunk_count_; - - // Current chunk filename. - char* chunk_name_; - - // Default MkvWriter object created by this class used for writing clusters - // out in separate files. - MkvWriter* chunk_writer_cluster_; - - // Default MkvWriter object created by this class used for writing Cues - // element out to a file. - MkvWriter* chunk_writer_cues_; - - // Default MkvWriter object created by this class used for writing the - // Matroska header out to a file. - MkvWriter* chunk_writer_header_; - - // Flag telling whether or not the muxer is chunking output to multiple - // files. - bool chunking_; - - // Base filename for the chunked files. - char* chunking_base_name_; - - // File position offset where the Clusters end. - int64_t cluster_end_offset_; - - // List of clusters. - Cluster** cluster_list_; - - // Number of cluster pointers allocated in the cluster list. - int32_t cluster_list_capacity_; - - // Number of clusters in the cluster list. - int32_t cluster_list_size_; - - // Indicates whether Cues should be written before or after Clusters - CuesPosition cues_position_; - - // Track number that is associated with the cues element for this segment. - uint64_t cues_track_; - - // Tells the muxer to force a new cluster on the next Block. - bool force_new_cluster_; - - // List of stored audio frames. These variables are used to store frames so - // the muxer can follow the guideline "Audio blocks that contain the video - // key frame's timecode should be in the same cluster as the video key frame - // block." - Frame** frames_; - - // Number of frame pointers allocated in the frame list. - int32_t frames_capacity_; - - // Number of frames in the frame list. - int32_t frames_size_; - - // Flag telling if a video track has been added to the segment. - bool has_video_; - - // Flag telling if the segment's header has been written. - bool header_written_; - - // Duration of the last block in nanoseconds. - uint64_t last_block_duration_; - - // Last timestamp in nanoseconds added to a cluster. - uint64_t last_timestamp_; - - // Last timestamp in nanoseconds by track number added to a cluster. - uint64_t last_track_timestamp_[kMaxTrackNumber]; - - // Number of frames written per track. - uint64_t track_frames_written_[kMaxTrackNumber]; - - // Maximum time in nanoseconds for a cluster duration. This variable is a - // guideline and some clusters may have a longer duration. Default is 30 - // seconds. - uint64_t max_cluster_duration_; - - // Maximum size in bytes for a cluster. This variable is a guideline and - // some clusters may have a larger size. Default is 0 which signifies that - // the muxer will decide the size. - uint64_t max_cluster_size_; - - // The mode that segment is in. If set to |kLive| the writer must not - // seek backwards. - Mode mode_; - - // Flag telling the muxer that a new cue point should be added. - bool new_cuepoint_; - - // TODO(fgalligan): Should we add support for more than one Cues element? - // Flag whether or not the muxer should output a Cues element. - bool output_cues_; - - // Flag whether or not the last frame in each Cluster will have a Duration - // element in it. - bool accurate_cluster_duration_; - - // Flag whether or not to write the Cluster Timecode using exactly 8 bytes. - bool fixed_size_cluster_timecode_; - - // Flag whether or not to estimate the file duration. - bool estimate_file_duration_; - - // The size of the EBML header, used to validate the header if - // WriteEbmlHeader() is called more than once. - int32_t ebml_header_size_; - - // The file position of the segment's payload. - int64_t payload_pos_; - - // The file position of the element's size. - int64_t size_position_; - - // Current DocTypeVersion (|doc_type_version_|) and that written in - // WriteSegmentHeader(). - // WriteEbmlHeader() will be called from Finalize() if |doc_type_version_| - // differs from |doc_type_version_written_|. - uint32_t doc_type_version_; - uint32_t doc_type_version_written_; - - // If |duration_| is > 0, then explicitly set the duration of the segment. - double duration_; - - // Pointer to the writer objects. Not owned by this class. - IMkvWriter* writer_cluster_; - IMkvWriter* writer_cues_; - IMkvWriter* writer_header_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Segment); -}; - -} // namespace mkvmuxer - -#endif // MKVMUXER_MKVMUXER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvmuxertypes.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvmuxertypes.h deleted file mode 100644 index e5db1216..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvmuxertypes.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2012 The WebM project authors. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. - -#ifndef MKVMUXER_MKVMUXERTYPES_H_ -#define MKVMUXER_MKVMUXERTYPES_H_ - -namespace mkvmuxer { -typedef unsigned char uint8; -typedef short int16; -typedef int int32; -typedef unsigned int uint32; -typedef long long int64; -typedef unsigned long long uint64; -} // namespace mkvmuxer - -// Copied from Chromium basictypes.h -// A macro to disallow the copy constructor and operator= functions -// This should be used in the private: declarations for a class -#define LIBWEBM_DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) - -#endif // MKVMUXER_MKVMUXERTYPES_HPP_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvmuxerutil.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvmuxerutil.cc deleted file mode 100644 index d1e835cd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvmuxerutil.cc +++ /dev/null @@ -1,737 +0,0 @@ -// Copyright (c) 2012 The WebM project authors. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. - -#include "mkvmuxer/mkvmuxerutil.h" - -#ifdef __ANDROID__ -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include "common/webmids.h" -#include "mkvmuxer/mkvmuxer.h" -#include "mkvmuxer/mkvwriter.h" - -namespace mkvmuxer { - -namespace { - -// Date elements are always 8 octets in size. -const int kDateElementSize = 8; - -uint64 WriteBlock(IMkvWriter* writer, const Frame* const frame, int64 timecode, - uint64 timecode_scale) { - uint64 block_additional_elem_size = 0; - uint64 block_addid_elem_size = 0; - uint64 block_more_payload_size = 0; - uint64 block_more_elem_size = 0; - uint64 block_additions_payload_size = 0; - uint64 block_additions_elem_size = 0; - if (frame->additional()) { - block_additional_elem_size = - EbmlElementSize(libwebm::kMkvBlockAdditional, frame->additional(), - frame->additional_length()); - block_addid_elem_size = EbmlElementSize( - libwebm::kMkvBlockAddID, static_cast(frame->add_id())); - - block_more_payload_size = - block_addid_elem_size + block_additional_elem_size; - block_more_elem_size = - EbmlMasterElementSize(libwebm::kMkvBlockMore, block_more_payload_size) + - block_more_payload_size; - block_additions_payload_size = block_more_elem_size; - block_additions_elem_size = - EbmlMasterElementSize(libwebm::kMkvBlockAdditions, - block_additions_payload_size) + - block_additions_payload_size; - } - - uint64 discard_padding_elem_size = 0; - if (frame->discard_padding() != 0) { - discard_padding_elem_size = - EbmlElementSize(libwebm::kMkvDiscardPadding, - static_cast(frame->discard_padding())); - } - - const uint64 reference_block_timestamp = - frame->reference_block_timestamp() / timecode_scale; - uint64 reference_block_elem_size = 0; - if (!frame->is_key()) { - reference_block_elem_size = - EbmlElementSize(libwebm::kMkvReferenceBlock, reference_block_timestamp); - } - - const uint64 duration = frame->duration() / timecode_scale; - uint64 block_duration_elem_size = 0; - if (duration > 0) - block_duration_elem_size = - EbmlElementSize(libwebm::kMkvBlockDuration, duration); - - const uint64 block_payload_size = 4 + frame->length(); - const uint64 block_elem_size = - EbmlMasterElementSize(libwebm::kMkvBlock, block_payload_size) + - block_payload_size; - - const uint64 block_group_payload_size = - block_elem_size + block_additions_elem_size + block_duration_elem_size + - discard_padding_elem_size + reference_block_elem_size; - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvBlockGroup, - block_group_payload_size)) { - return 0; - } - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvBlock, block_payload_size)) - return 0; - - if (WriteUInt(writer, frame->track_number())) - return 0; - - if (SerializeInt(writer, timecode, 2)) - return 0; - - // For a Block, flags is always 0. - if (SerializeInt(writer, 0, 1)) - return 0; - - if (writer->Write(frame->frame(), static_cast(frame->length()))) - return 0; - - if (frame->additional()) { - if (!WriteEbmlMasterElement(writer, libwebm::kMkvBlockAdditions, - block_additions_payload_size)) { - return 0; - } - - if (!WriteEbmlMasterElement(writer, libwebm::kMkvBlockMore, - block_more_payload_size)) - return 0; - - if (!WriteEbmlElement(writer, libwebm::kMkvBlockAddID, - static_cast(frame->add_id()))) - return 0; - - if (!WriteEbmlElement(writer, libwebm::kMkvBlockAdditional, - frame->additional(), frame->additional_length())) { - return 0; - } - } - - if (frame->discard_padding() != 0 && - !WriteEbmlElement(writer, libwebm::kMkvDiscardPadding, - static_cast(frame->discard_padding()))) { - return false; - } - - if (!frame->is_key() && !WriteEbmlElement(writer, libwebm::kMkvReferenceBlock, - reference_block_timestamp)) { - return false; - } - - if (duration > 0 && - !WriteEbmlElement(writer, libwebm::kMkvBlockDuration, duration)) { - return false; - } - return EbmlMasterElementSize(libwebm::kMkvBlockGroup, - block_group_payload_size) + - block_group_payload_size; -} - -uint64 WriteSimpleBlock(IMkvWriter* writer, const Frame* const frame, - int64 timecode) { - if (WriteID(writer, libwebm::kMkvSimpleBlock)) - return 0; - - const int32 size = static_cast(frame->length()) + 4; - if (WriteUInt(writer, size)) - return 0; - - if (WriteUInt(writer, static_cast(frame->track_number()))) - return 0; - - if (SerializeInt(writer, timecode, 2)) - return 0; - - uint64 flags = 0; - if (frame->is_key()) - flags |= 0x80; - - if (SerializeInt(writer, flags, 1)) - return 0; - - if (writer->Write(frame->frame(), static_cast(frame->length()))) - return 0; - - return GetUIntSize(libwebm::kMkvSimpleBlock) + GetCodedUIntSize(size) + 4 + - frame->length(); -} - -} // namespace - -int32 GetCodedUIntSize(uint64 value) { - if (value < 0x000000000000007FULL) - return 1; - else if (value < 0x0000000000003FFFULL) - return 2; - else if (value < 0x00000000001FFFFFULL) - return 3; - else if (value < 0x000000000FFFFFFFULL) - return 4; - else if (value < 0x00000007FFFFFFFFULL) - return 5; - else if (value < 0x000003FFFFFFFFFFULL) - return 6; - else if (value < 0x0001FFFFFFFFFFFFULL) - return 7; - return 8; -} - -int32 GetUIntSize(uint64 value) { - if (value < 0x0000000000000100ULL) - return 1; - else if (value < 0x0000000000010000ULL) - return 2; - else if (value < 0x0000000001000000ULL) - return 3; - else if (value < 0x0000000100000000ULL) - return 4; - else if (value < 0x0000010000000000ULL) - return 5; - else if (value < 0x0001000000000000ULL) - return 6; - else if (value < 0x0100000000000000ULL) - return 7; - return 8; -} - -int32 GetIntSize(int64 value) { - // Doubling the requested value ensures positive values with their high bit - // set are written with 0-padding to avoid flipping the signedness. - const uint64 v = (value < 0) ? value ^ -1LL : value; - return GetUIntSize(2 * v); -} - -uint64 EbmlMasterElementSize(uint64 type, uint64 value) { - // Size of EBML ID - int32 ebml_size = GetUIntSize(type); - - // Datasize - ebml_size += GetCodedUIntSize(value); - - return ebml_size; -} - -uint64 EbmlElementSize(uint64 type, int64 value) { - // Size of EBML ID - int32 ebml_size = GetUIntSize(type); - - // Datasize - ebml_size += GetIntSize(value); - - // Size of Datasize - ebml_size++; - - return ebml_size; -} - -uint64 EbmlElementSize(uint64 type, uint64 value) { - return EbmlElementSize(type, value, 0); -} - -uint64 EbmlElementSize(uint64 type, uint64 value, uint64 fixed_size) { - // Size of EBML ID - uint64 ebml_size = GetUIntSize(type); - - // Datasize - ebml_size += (fixed_size > 0) ? fixed_size : GetUIntSize(value); - - // Size of Datasize - ebml_size++; - - return ebml_size; -} - -uint64 EbmlElementSize(uint64 type, float /* value */) { - // Size of EBML ID - uint64 ebml_size = GetUIntSize(type); - - // Datasize - ebml_size += sizeof(float); - - // Size of Datasize - ebml_size++; - - return ebml_size; -} - -uint64 EbmlElementSize(uint64 type, const char* value) { - if (!value) - return 0; - - // Size of EBML ID - uint64 ebml_size = GetUIntSize(type); - - // Datasize - ebml_size += strlen(value); - - // Size of Datasize - ebml_size += GetCodedUIntSize(strlen(value)); - - return ebml_size; -} - -uint64 EbmlElementSize(uint64 type, const uint8* value, uint64 size) { - if (!value) - return 0; - - // Size of EBML ID - uint64 ebml_size = GetUIntSize(type); - - // Datasize - ebml_size += size; - - // Size of Datasize - ebml_size += GetCodedUIntSize(size); - - return ebml_size; -} - -uint64 EbmlDateElementSize(uint64 type) { - // Size of EBML ID - uint64 ebml_size = GetUIntSize(type); - - // Datasize - ebml_size += kDateElementSize; - - // Size of Datasize - ebml_size++; - - return ebml_size; -} - -int32 SerializeInt(IMkvWriter* writer, int64 value, int32 size) { - if (!writer || size < 1 || size > 8) - return -1; - - for (int32 i = 1; i <= size; ++i) { - const int32 byte_count = size - i; - const int32 bit_count = byte_count * 8; - - const int64 bb = value >> bit_count; - const uint8 b = static_cast(bb); - - const int32 status = writer->Write(&b, 1); - - if (status < 0) - return status; - } - - return 0; -} - -int32 SerializeFloat(IMkvWriter* writer, float f) { - if (!writer) - return -1; - - assert(sizeof(uint32) == sizeof(float)); - // This union is merely used to avoid a reinterpret_cast from float& to - // uint32& which will result in violation of strict aliasing. - union U32 { - uint32 u32; - float f; - } value; - value.f = f; - - for (int32 i = 1; i <= 4; ++i) { - const int32 byte_count = 4 - i; - const int32 bit_count = byte_count * 8; - - const uint8 byte = static_cast(value.u32 >> bit_count); - - const int32 status = writer->Write(&byte, 1); - - if (status < 0) - return status; - } - - return 0; -} - -int32 WriteUInt(IMkvWriter* writer, uint64 value) { - if (!writer) - return -1; - - int32 size = GetCodedUIntSize(value); - - return WriteUIntSize(writer, value, size); -} - -int32 WriteUIntSize(IMkvWriter* writer, uint64 value, int32 size) { - if (!writer || size < 0 || size > 8) - return -1; - - if (size > 0) { - const uint64 bit = 1LL << (size * 7); - - if (value > (bit - 2)) - return -1; - - value |= bit; - } else { - size = 1; - int64 bit; - - for (;;) { - bit = 1LL << (size * 7); - const uint64 max = bit - 2; - - if (value <= max) - break; - - ++size; - } - - if (size > 8) - return false; - - value |= bit; - } - - return SerializeInt(writer, value, size); -} - -int32 WriteID(IMkvWriter* writer, uint64 type) { - if (!writer) - return -1; - - writer->ElementStartNotify(type, writer->Position()); - - const int32 size = GetUIntSize(type); - - return SerializeInt(writer, type, size); -} - -bool WriteEbmlMasterElement(IMkvWriter* writer, uint64 type, uint64 size) { - if (!writer) - return false; - - if (WriteID(writer, type)) - return false; - - if (WriteUInt(writer, size)) - return false; - - return true; -} - -bool WriteEbmlElement(IMkvWriter* writer, uint64 type, uint64 value) { - return WriteEbmlElement(writer, type, value, 0); -} - -bool WriteEbmlElement(IMkvWriter* writer, uint64 type, uint64 value, - uint64 fixed_size) { - if (!writer) - return false; - - if (WriteID(writer, type)) - return false; - - uint64 size = GetUIntSize(value); - if (fixed_size > 0) { - if (size > fixed_size) - return false; - size = fixed_size; - } - if (WriteUInt(writer, size)) - return false; - - if (SerializeInt(writer, value, static_cast(size))) - return false; - - return true; -} - -bool WriteEbmlElement(IMkvWriter* writer, uint64 type, int64 value) { - if (!writer) - return false; - - if (WriteID(writer, type)) - return 0; - - const uint64 size = GetIntSize(value); - if (WriteUInt(writer, size)) - return false; - - if (SerializeInt(writer, value, static_cast(size))) - return false; - - return true; -} - -bool WriteEbmlElement(IMkvWriter* writer, uint64 type, float value) { - if (!writer) - return false; - - if (WriteID(writer, type)) - return false; - - if (WriteUInt(writer, 4)) - return false; - - if (SerializeFloat(writer, value)) - return false; - - return true; -} - -bool WriteEbmlElement(IMkvWriter* writer, uint64 type, const char* value) { - if (!writer || !value) - return false; - - if (WriteID(writer, type)) - return false; - - const uint64 length = strlen(value); - if (WriteUInt(writer, length)) - return false; - - if (writer->Write(value, static_cast(length))) - return false; - - return true; -} - -bool WriteEbmlElement(IMkvWriter* writer, uint64 type, const uint8* value, - uint64 size) { - if (!writer || !value || size < 1) - return false; - - if (WriteID(writer, type)) - return false; - - if (WriteUInt(writer, size)) - return false; - - if (writer->Write(value, static_cast(size))) - return false; - - return true; -} - -bool WriteEbmlDateElement(IMkvWriter* writer, uint64 type, int64 value) { - if (!writer) - return false; - - if (WriteID(writer, type)) - return false; - - if (WriteUInt(writer, kDateElementSize)) - return false; - - if (SerializeInt(writer, value, kDateElementSize)) - return false; - - return true; -} - -uint64 WriteFrame(IMkvWriter* writer, const Frame* const frame, - Cluster* cluster) { - if (!writer || !frame || !frame->IsValid() || !cluster || - !cluster->timecode_scale()) - return 0; - - // Technically the timecode for a block can be less than the - // timecode for the cluster itself (remember that block timecode - // is a signed, 16-bit integer). However, as a simplification we - // only permit non-negative cluster-relative timecodes for blocks. - const int64 relative_timecode = cluster->GetRelativeTimecode( - frame->timestamp() / cluster->timecode_scale()); - if (relative_timecode < 0 || relative_timecode > kMaxBlockTimecode) - return 0; - - return frame->CanBeSimpleBlock() - ? WriteSimpleBlock(writer, frame, relative_timecode) - : WriteBlock(writer, frame, relative_timecode, - cluster->timecode_scale()); -} - -uint64 WriteVoidElement(IMkvWriter* writer, uint64 size) { - if (!writer) - return false; - - // Subtract one for the void ID and the coded size. - uint64 void_entry_size = size - 1 - GetCodedUIntSize(size - 1); - uint64 void_size = EbmlMasterElementSize(libwebm::kMkvVoid, void_entry_size) + - void_entry_size; - - if (void_size != size) - return 0; - - const int64 payload_position = writer->Position(); - if (payload_position < 0) - return 0; - - if (WriteID(writer, libwebm::kMkvVoid)) - return 0; - - if (WriteUInt(writer, void_entry_size)) - return 0; - - const uint8 value = 0; - for (int32 i = 0; i < static_cast(void_entry_size); ++i) { - if (writer->Write(&value, 1)) - return 0; - } - - const int64 stop_position = writer->Position(); - if (stop_position < 0 || - stop_position - payload_position != static_cast(void_size)) - return 0; - - return void_size; -} - -void GetVersion(int32* major, int32* minor, int32* build, int32* revision) { - *major = 0; - *minor = 3; - *build = 3; - *revision = 0; -} - -uint64 MakeUID(unsigned int* seed) { - uint64 uid = 0; - - for (int i = 0; i < 7; ++i) { // avoid problems with 8-byte values - uid <<= 8; - -// TODO(fgalligan): Move random number generation to platform specific code. -#ifdef _WIN32 - (void)seed; - const int32 nn = rand(); -#elif defined(__ANDROID__) - (void)seed; - int32 temp_num = 1; - int fd = open("/dev/urandom", O_RDONLY); - if (fd != -1) { - read(fd, &temp_num, sizeof(temp_num)); - close(fd); - } - const int32 nn = temp_num; -#else - const int32 nn = rand_r(seed); -#endif - const int32 n = 0xFF & (nn >> 4); // throw away low-order bits - - uid |= n; - } - - return uid; -} - -bool IsMatrixCoefficientsValueValid(uint64_t value) { - switch (value) { - case mkvmuxer::Colour::kGbr: - case mkvmuxer::Colour::kBt709: - case mkvmuxer::Colour::kUnspecifiedMc: - case mkvmuxer::Colour::kReserved: - case mkvmuxer::Colour::kFcc: - case mkvmuxer::Colour::kBt470bg: - case mkvmuxer::Colour::kSmpte170MMc: - case mkvmuxer::Colour::kSmpte240MMc: - case mkvmuxer::Colour::kYcocg: - case mkvmuxer::Colour::kBt2020NonConstantLuminance: - case mkvmuxer::Colour::kBt2020ConstantLuminance: - return true; - } - return false; -} - -bool IsChromaSitingHorzValueValid(uint64_t value) { - switch (value) { - case mkvmuxer::Colour::kUnspecifiedCsh: - case mkvmuxer::Colour::kLeftCollocated: - case mkvmuxer::Colour::kHalfCsh: - return true; - } - return false; -} - -bool IsChromaSitingVertValueValid(uint64_t value) { - switch (value) { - case mkvmuxer::Colour::kUnspecifiedCsv: - case mkvmuxer::Colour::kTopCollocated: - case mkvmuxer::Colour::kHalfCsv: - return true; - } - return false; -} - -bool IsColourRangeValueValid(uint64_t value) { - switch (value) { - case mkvmuxer::Colour::kUnspecifiedCr: - case mkvmuxer::Colour::kBroadcastRange: - case mkvmuxer::Colour::kFullRange: - case mkvmuxer::Colour::kMcTcDefined: - return true; - } - return false; -} - -bool IsTransferCharacteristicsValueValid(uint64_t value) { - switch (value) { - case mkvmuxer::Colour::kIturBt709Tc: - case mkvmuxer::Colour::kUnspecifiedTc: - case mkvmuxer::Colour::kReservedTc: - case mkvmuxer::Colour::kGamma22Curve: - case mkvmuxer::Colour::kGamma28Curve: - case mkvmuxer::Colour::kSmpte170MTc: - case mkvmuxer::Colour::kSmpte240MTc: - case mkvmuxer::Colour::kLinear: - case mkvmuxer::Colour::kLog: - case mkvmuxer::Colour::kLogSqrt: - case mkvmuxer::Colour::kIec6196624: - case mkvmuxer::Colour::kIturBt1361ExtendedColourGamut: - case mkvmuxer::Colour::kIec6196621: - case mkvmuxer::Colour::kIturBt202010bit: - case mkvmuxer::Colour::kIturBt202012bit: - case mkvmuxer::Colour::kSmpteSt2084: - case mkvmuxer::Colour::kSmpteSt4281Tc: - case mkvmuxer::Colour::kAribStdB67Hlg: - return true; - } - return false; -} - -bool IsPrimariesValueValid(uint64_t value) { - switch (value) { - case mkvmuxer::Colour::kReservedP0: - case mkvmuxer::Colour::kIturBt709P: - case mkvmuxer::Colour::kUnspecifiedP: - case mkvmuxer::Colour::kReservedP3: - case mkvmuxer::Colour::kIturBt470M: - case mkvmuxer::Colour::kIturBt470Bg: - case mkvmuxer::Colour::kSmpte170MP: - case mkvmuxer::Colour::kSmpte240MP: - case mkvmuxer::Colour::kFilm: - case mkvmuxer::Colour::kIturBt2020: - case mkvmuxer::Colour::kSmpteSt4281P: - case mkvmuxer::Colour::kJedecP22Phosphors: - return true; - } - return false; -} - -} // namespace mkvmuxer diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvmuxerutil.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvmuxerutil.h deleted file mode 100644 index 85fc2a20..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvmuxerutil.h +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) 2012 The WebM project authors. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -#ifndef MKVMUXER_MKVMUXERUTIL_H_ -#define MKVMUXER_MKVMUXERUTIL_H_ - -#include - -#include "mkvmuxertypes.h" - -namespace mkvmuxer { -class Cluster; -class Frame; -class IMkvWriter; - -// TODO(tomfinegan): mkvmuxer:: integer types continue to be used here because -// changing them causes pain for downstream projects. It would be nice if a -// solution that allows removal of the mkvmuxer:: integer types while avoiding -// pain for downstream users of libwebm. Considering that mkvmuxerutil.{cc,h} -// are really, for the great majority of cases, EBML size calculation and writer -// functions, perhaps a more EBML focused utility would be the way to go as a -// first step. - -const uint64 kEbmlUnknownValue = 0x01FFFFFFFFFFFFFFULL; -const int64 kMaxBlockTimecode = 0x07FFFLL; - -// Writes out |value| in Big Endian order. Returns 0 on success. -int32 SerializeInt(IMkvWriter* writer, int64 value, int32 size); - -// Writes out |f| in Big Endian order. Returns 0 on success. -int32 SerializeFloat(IMkvWriter* writer, float f); - -// Returns the size in bytes of the element. -int32 GetUIntSize(uint64 value); -int32 GetIntSize(int64 value); -int32 GetCodedUIntSize(uint64 value); -uint64 EbmlMasterElementSize(uint64 type, uint64 value); -uint64 EbmlElementSize(uint64 type, int64 value); -uint64 EbmlElementSize(uint64 type, uint64 value); -uint64 EbmlElementSize(uint64 type, float value); -uint64 EbmlElementSize(uint64 type, const char* value); -uint64 EbmlElementSize(uint64 type, const uint8* value, uint64 size); -uint64 EbmlDateElementSize(uint64 type); - -// Returns the size in bytes of the element assuming that the element was -// written using |fixed_size| bytes. If |fixed_size| is set to zero, then it -// computes the necessary number of bytes based on |value|. -uint64 EbmlElementSize(uint64 type, uint64 value, uint64 fixed_size); - -// Creates an EBML coded number from |value| and writes it out. The size of -// the coded number is determined by the value of |value|. |value| must not -// be in a coded form. Returns 0 on success. -int32 WriteUInt(IMkvWriter* writer, uint64 value); - -// Creates an EBML coded number from |value| and writes it out. The size of -// the coded number is determined by the value of |size|. |value| must not -// be in a coded form. Returns 0 on success. -int32 WriteUIntSize(IMkvWriter* writer, uint64 value, int32 size); - -// Output an Mkv master element. Returns true if the element was written. -bool WriteEbmlMasterElement(IMkvWriter* writer, uint64 value, uint64 size); - -// Outputs an Mkv ID, calls |IMkvWriter::ElementStartNotify|, and passes the -// ID to |SerializeInt|. Returns 0 on success. -int32 WriteID(IMkvWriter* writer, uint64 type); - -// Output an Mkv non-master element. Returns true if the element was written. -bool WriteEbmlElement(IMkvWriter* writer, uint64 type, uint64 value); -bool WriteEbmlElement(IMkvWriter* writer, uint64 type, int64 value); -bool WriteEbmlElement(IMkvWriter* writer, uint64 type, float value); -bool WriteEbmlElement(IMkvWriter* writer, uint64 type, const char* value); -bool WriteEbmlElement(IMkvWriter* writer, uint64 type, const uint8* value, - uint64 size); -bool WriteEbmlDateElement(IMkvWriter* writer, uint64 type, int64 value); - -// Output an Mkv non-master element using fixed size. The element will be -// written out using exactly |fixed_size| bytes. If |fixed_size| is set to zero -// then it computes the necessary number of bytes based on |value|. Returns true -// if the element was written. -bool WriteEbmlElement(IMkvWriter* writer, uint64 type, uint64 value, - uint64 fixed_size); - -// Output a Mkv Frame. It decides the correct element to write (Block vs -// SimpleBlock) based on the parameters of the Frame. -uint64 WriteFrame(IMkvWriter* writer, const Frame* const frame, - Cluster* cluster); - -// Output a void element. |size| must be the entire size in bytes that will be -// void. The function will calculate the size of the void header and subtract -// it from |size|. -uint64 WriteVoidElement(IMkvWriter* writer, uint64 size); - -// Returns the version number of the muxer in |major|, |minor|, |build|, -// and |revision|. -void GetVersion(int32* major, int32* minor, int32* build, int32* revision); - -// Returns a random number to be used for UID, using |seed| to seed -// the random-number generator (see POSIX rand_r() for semantics). -uint64 MakeUID(unsigned int* seed); - -// Colour field validation helpers. All return true when |value| is valid. -bool IsMatrixCoefficientsValueValid(uint64_t value); -bool IsChromaSitingHorzValueValid(uint64_t value); -bool IsChromaSitingVertValueValid(uint64_t value); -bool IsColourRangeValueValid(uint64_t value); -bool IsTransferCharacteristicsValueValid(uint64_t value); -bool IsPrimariesValueValid(uint64_t value); - -} // namespace mkvmuxer - -#endif // MKVMUXER_MKVMUXERUTIL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvwriter.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvwriter.cc deleted file mode 100644 index 9b714a5e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvwriter.cc +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2012 The WebM project authors. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. - -#include "mkvmuxer/mkvwriter.h" - -#include - -#ifdef _MSC_VER -#include // for _SH_DENYWR -#endif - -namespace mkvmuxer { - -MkvWriter::MkvWriter() : file_(NULL), writer_owns_file_(true) {} - -MkvWriter::MkvWriter(FILE* fp) : file_(fp), writer_owns_file_(false) {} - -MkvWriter::~MkvWriter() { Close(); } - -int32 MkvWriter::Write(const void* buffer, uint32 length) { - if (!file_) - return -1; - - if (length == 0) - return 0; - - if (buffer == NULL) - return -1; - - const size_t bytes_written = fwrite(buffer, 1, length, file_); - - return (bytes_written == length) ? 0 : -1; -} - -bool MkvWriter::Open(const char* filename) { - if (filename == NULL) - return false; - - if (file_) - return false; - -#ifdef _MSC_VER - file_ = _fsopen(filename, "wb", _SH_DENYWR); -#else - file_ = fopen(filename, "wb"); -#endif - if (file_ == NULL) - return false; - return true; -} - -void MkvWriter::Close() { - if (file_ && writer_owns_file_) { - fclose(file_); - } - file_ = NULL; -} - -int64 MkvWriter::Position() const { - if (!file_) - return 0; - -#ifdef _MSC_VER - return _ftelli64(file_); -#else - return ftell(file_); -#endif -} - -int32 MkvWriter::Position(int64 position) { - if (!file_) - return -1; - -#ifdef _MSC_VER - return _fseeki64(file_, position, SEEK_SET); -#elif defined(_WIN32) - return fseeko64(file_, static_cast(position), SEEK_SET); -#elif !(defined(__ANDROID__) && __ANDROID_API__ < 24 && !defined(__LP64__) && \ - defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64) - // POSIX.1 has fseeko and ftello. fseeko and ftello are not available before - // Android API level 24. See - // https://android.googlesource.com/platform/bionic/+/main/docs/32-bit-abi.md - return fseeko(file_, static_cast(position), SEEK_SET); -#else - return fseek(file_, static_cast(position), SEEK_SET); -#endif -} - -bool MkvWriter::Seekable() const { return true; } - -void MkvWriter::ElementStartNotify(uint64, int64) {} - -} // namespace mkvmuxer diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvwriter.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvwriter.h deleted file mode 100644 index 4227c637..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvmuxer/mkvwriter.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2012 The WebM project authors. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. - -#ifndef MKVMUXER_MKVWRITER_H_ -#define MKVMUXER_MKVWRITER_H_ - -#include - -#include "mkvmuxer/mkvmuxer.h" -#include "mkvmuxer/mkvmuxertypes.h" - -namespace mkvmuxer { - -// Default implementation of the IMkvWriter interface on Windows. -class MkvWriter : public IMkvWriter { - public: - MkvWriter(); - explicit MkvWriter(FILE* fp); - virtual ~MkvWriter(); - - // IMkvWriter interface - virtual int64 Position() const; - virtual int32 Position(int64 position); - virtual bool Seekable() const; - virtual int32 Write(const void* buffer, uint32 length); - virtual void ElementStartNotify(uint64 element_id, int64 position); - - // Creates and opens a file for writing. |filename| is the name of the file - // to open. This function will overwrite the contents of |filename|. Returns - // true on success. - bool Open(const char* filename); - - // Closes an opened file. - void Close(); - - private: - // File handle to output file. - FILE* file_; - bool writer_owns_file_; - - LIBWEBM_DISALLOW_COPY_AND_ASSIGN(MkvWriter); -}; - -} // namespace mkvmuxer - -#endif // MKVMUXER_MKVWRITER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvparser/mkvparser.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvparser/mkvparser.cc deleted file mode 100644 index 042a0c56..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvparser/mkvparser.cc +++ /dev/null @@ -1,8104 +0,0 @@ -// Copyright (c) 2012 The WebM project authors. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -#include "mkvparser/mkvparser.h" - -#if defined(_MSC_VER) && _MSC_VER < 1800 -#include // _isnan() / _finite() -#define MSC_COMPAT -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "common/webmids.h" - -namespace mkvparser { -const long long kStringElementSizeLimit = 20 * 1000 * 1000; -const float MasteringMetadata::kValueNotPresent = FLT_MAX; -const long long Colour::kValueNotPresent = LLONG_MAX; -const float Projection::kValueNotPresent = FLT_MAX; - -#ifdef MSC_COMPAT -inline bool isnan(double val) { return !!_isnan(val); } -inline bool isinf(double val) { return !_finite(val); } -#else -inline bool isnan(double val) { return std::isnan(val); } -inline bool isinf(double val) { return std::isinf(val); } -#endif // MSC_COMPAT - -template -Type* SafeArrayAlloc(unsigned long long num_elements, - unsigned long long element_size) { - if (num_elements == 0 || element_size == 0) - return NULL; - - const size_t kMaxAllocSize = 0x80000000; // 2GiB - const unsigned long long num_bytes = num_elements * element_size; - if (element_size > (kMaxAllocSize / num_elements)) - return NULL; - if (num_bytes != static_cast(num_bytes)) - return NULL; - - return new (std::nothrow) Type[static_cast(num_bytes)]; -} - -void GetVersion(int& major, int& minor, int& build, int& revision) { - major = 1; - minor = 1; - build = 3; - revision = 0; -} - -long long ReadUInt(IMkvReader* pReader, long long pos, long& len) { - if (!pReader || pos < 0) - return E_FILE_FORMAT_INVALID; - - len = 1; - unsigned char b; - int status = pReader->Read(pos, 1, &b); - - if (status < 0) // error or underflow - return status; - - if (status > 0) // interpreted as "underflow" - return E_BUFFER_NOT_FULL; - - if (b == 0) // we can't handle u-int values larger than 8 bytes - return E_FILE_FORMAT_INVALID; - - unsigned char m = 0x80; - - while (!(b & m)) { - m >>= 1; - ++len; - } - - long long result = b & (~m); - ++pos; - - for (int i = 1; i < len; ++i) { - status = pReader->Read(pos, 1, &b); - - if (status < 0) { - len = 1; - return status; - } - - if (status > 0) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - result <<= 8; - result |= b; - - ++pos; - } - - return result; -} - -// Reads an EBML ID and returns it. -// An ID must at least 1 byte long, cannot exceed 4, and its value must be -// greater than 0. -// See known EBML values and EBMLMaxIDLength: -// http://www.matroska.org/technical/specs/index.html -// Returns the ID, or a value less than 0 to report an error while reading the -// ID. -long long ReadID(IMkvReader* pReader, long long pos, long& len) { - if (pReader == NULL || pos < 0) - return E_FILE_FORMAT_INVALID; - - // Read the first byte. The length in bytes of the ID is determined by - // finding the first set bit in the first byte of the ID. - unsigned char temp_byte = 0; - int read_status = pReader->Read(pos, 1, &temp_byte); - - if (read_status < 0) - return E_FILE_FORMAT_INVALID; - else if (read_status > 0) // No data to read. - return E_BUFFER_NOT_FULL; - - if (temp_byte == 0) // ID length > 8 bytes; invalid file. - return E_FILE_FORMAT_INVALID; - - int bit_pos = 0; - const int kMaxIdLengthInBytes = 4; - const int kCheckByte = 0x80; - - // Find the first bit that's set. - bool found_bit = false; - for (; bit_pos < kMaxIdLengthInBytes; ++bit_pos) { - if ((kCheckByte >> bit_pos) & temp_byte) { - found_bit = true; - break; - } - } - - if (!found_bit) { - // The value is too large to be a valid ID. - return E_FILE_FORMAT_INVALID; - } - - // Read the remaining bytes of the ID (if any). - const int id_length = bit_pos + 1; - long long ebml_id = temp_byte; - for (int i = 1; i < id_length; ++i) { - ebml_id <<= 8; - read_status = pReader->Read(pos + i, 1, &temp_byte); - - if (read_status < 0) - return E_FILE_FORMAT_INVALID; - else if (read_status > 0) - return E_BUFFER_NOT_FULL; - - ebml_id |= temp_byte; - } - - len = id_length; - return ebml_id; -} - -long long GetUIntLength(IMkvReader* pReader, long long pos, long& len) { - if (!pReader || pos < 0) - return E_FILE_FORMAT_INVALID; - - long long total, available; - - int status = pReader->Length(&total, &available); - if (status < 0 || (total >= 0 && available > total)) - return E_FILE_FORMAT_INVALID; - - len = 1; - - if (pos >= available) - return pos; // too few bytes available - - unsigned char b; - - status = pReader->Read(pos, 1, &b); - - if (status != 0) - return status; - - if (b == 0) // we can't handle u-int values larger than 8 bytes - return E_FILE_FORMAT_INVALID; - - unsigned char m = 0x80; - - while (!(b & m)) { - m >>= 1; - ++len; - } - - return 0; // success -} - -// TODO(vigneshv): This function assumes that unsigned values never have their -// high bit set. -long long UnserializeUInt(IMkvReader* pReader, long long pos, long long size) { - if (!pReader || pos < 0 || (size <= 0) || (size > 8)) - return E_FILE_FORMAT_INVALID; - - long long result = 0; - - for (long long i = 0; i < size; ++i) { - unsigned char b; - - const long status = pReader->Read(pos, 1, &b); - - if (status < 0) - return status; - - result <<= 8; - result |= b; - - ++pos; - } - - return result; -} - -long UnserializeFloat(IMkvReader* pReader, long long pos, long long size_, - double& result) { - if (!pReader || pos < 0 || ((size_ != 4) && (size_ != 8))) - return E_FILE_FORMAT_INVALID; - - const long size = static_cast(size_); - - unsigned char buf[8]; - - const int status = pReader->Read(pos, size, buf); - - if (status < 0) // error - return status; - - if (size == 4) { - union { - float f; - uint32_t ff; - static_assert(sizeof(float) == sizeof(uint32_t), ""); - }; - - ff = 0; - - for (int i = 0;;) { - ff |= buf[i]; - - if (++i >= 4) - break; - - ff <<= 8; - } - - result = f; - } else { - union { - double d; - uint64_t dd; - static_assert(sizeof(double) == sizeof(uint64_t), ""); - }; - - dd = 0; - - for (int i = 0;;) { - dd |= buf[i]; - - if (++i >= 8) - break; - - dd <<= 8; - } - - result = d; - } - - if (mkvparser::isinf(result) || mkvparser::isnan(result)) - return E_FILE_FORMAT_INVALID; - - return 0; -} - -long UnserializeInt(IMkvReader* pReader, long long pos, long long size, - long long& result_ref) { - if (!pReader || pos < 0 || size < 1 || size > 8) - return E_FILE_FORMAT_INVALID; - - signed char first_byte = 0; - const long status = pReader->Read(pos, 1, (unsigned char*)&first_byte); - - if (status < 0) - return status; - - unsigned long long result = static_cast(first_byte); - ++pos; - - for (long i = 1; i < size; ++i) { - unsigned char b; - - const long status = pReader->Read(pos, 1, &b); - - if (status < 0) - return status; - - result <<= 8; - result |= b; - - ++pos; - } - - result_ref = static_cast(result); - return 0; -} - -long UnserializeString(IMkvReader* pReader, long long pos, long long size, - char*& str) { - delete[] str; - str = NULL; - - if (size >= LONG_MAX || size < 0 || size > kStringElementSizeLimit) - return E_FILE_FORMAT_INVALID; - - // +1 for '\0' terminator - const long required_size = static_cast(size) + 1; - - str = SafeArrayAlloc(1, required_size); - if (str == NULL) - return E_FILE_FORMAT_INVALID; - - unsigned char* const buf = reinterpret_cast(str); - - const long status = pReader->Read(pos, static_cast(size), buf); - - if (status) { - delete[] str; - str = NULL; - - return status; - } - - str[required_size - 1] = '\0'; - return 0; -} - -long ParseElementHeader(IMkvReader* pReader, long long& pos, long long stop, - long long& id, long long& size) { - if (stop >= 0 && pos >= stop) - return E_FILE_FORMAT_INVALID; - - long len; - - id = ReadID(pReader, pos, len); - - if (id < 0) - return E_FILE_FORMAT_INVALID; - - pos += len; // consume id - - if (stop >= 0 && pos >= stop) - return E_FILE_FORMAT_INVALID; - - size = ReadUInt(pReader, pos, len); - - if (size < 0 || len < 1 || len > 8) { - // Invalid: Negative payload size, negative or 0 length integer, or integer - // larger than 64 bits (libwebm cannot handle them). - return E_FILE_FORMAT_INVALID; - } - - // Avoid rolling over pos when very close to LLONG_MAX. - const unsigned long long rollover_check = - static_cast(pos) + len; - if (rollover_check > LLONG_MAX) - return E_FILE_FORMAT_INVALID; - - pos += len; // consume length of size - - // pos now designates payload - - if (stop >= 0 && pos > stop) - return E_FILE_FORMAT_INVALID; - - return 0; // success -} - -bool Match(IMkvReader* pReader, long long& pos, unsigned long expected_id, - long long& val) { - if (!pReader || pos < 0) - return false; - - long long total = 0; - long long available = 0; - - const long status = pReader->Length(&total, &available); - if (status < 0 || (total >= 0 && available > total)) - return false; - - long len = 0; - - const long long id = ReadID(pReader, pos, len); - if (id < 0 || (available - pos) > len) - return false; - - if (static_cast(id) != expected_id) - return false; - - pos += len; // consume id - - const long long size = ReadUInt(pReader, pos, len); - if (size < 0 || size > 8 || len < 1 || len > 8 || (available - pos) > len) - return false; - - pos += len; // consume length of size of payload - - val = UnserializeUInt(pReader, pos, size); - if (val < 0) - return false; - - pos += size; // consume size of payload - - return true; -} - -bool Match(IMkvReader* pReader, long long& pos, unsigned long expected_id, - unsigned char*& buf, size_t& buflen) { - if (!pReader || pos < 0) - return false; - - long long total = 0; - long long available = 0; - - long status = pReader->Length(&total, &available); - if (status < 0 || (total >= 0 && available > total)) - return false; - - long len = 0; - const long long id = ReadID(pReader, pos, len); - if (id < 0 || (available - pos) > len) - return false; - - if (static_cast(id) != expected_id) - return false; - - pos += len; // consume id - - const long long size = ReadUInt(pReader, pos, len); - if (size < 0 || len <= 0 || len > 8 || (available - pos) > len) - return false; - - unsigned long long rollover_check = - static_cast(pos) + len; - if (rollover_check > LLONG_MAX) - return false; - - pos += len; // consume length of size of payload - - rollover_check = static_cast(pos) + size; - if (rollover_check > LLONG_MAX) - return false; - - if ((pos + size) > available) - return false; - - if (size >= LONG_MAX) - return false; - - const long buflen_ = static_cast(size); - - buf = SafeArrayAlloc(1, buflen_); - if (!buf) - return false; - - status = pReader->Read(pos, buflen_, buf); - if (status != 0) - return false; - - buflen = buflen_; - - pos += size; // consume size of payload - return true; -} - -EBMLHeader::EBMLHeader() : m_docType(NULL) { Init(); } - -EBMLHeader::~EBMLHeader() { delete[] m_docType; } - -void EBMLHeader::Init() { - m_version = 1; - m_readVersion = 1; - m_maxIdLength = 4; - m_maxSizeLength = 8; - - if (m_docType) { - delete[] m_docType; - m_docType = NULL; - } - - m_docTypeVersion = 1; - m_docTypeReadVersion = 1; -} - -long long EBMLHeader::Parse(IMkvReader* pReader, long long& pos) { - if (!pReader) - return E_FILE_FORMAT_INVALID; - - long long total, available; - - long status = pReader->Length(&total, &available); - - if (status < 0) // error - return status; - - pos = 0; - - // Scan until we find what looks like the first byte of the EBML header. - const long long kMaxScanBytes = (available >= 1024) ? 1024 : available; - const unsigned char kEbmlByte0 = 0x1A; - unsigned char scan_byte = 0; - - while (pos < kMaxScanBytes) { - status = pReader->Read(pos, 1, &scan_byte); - - if (status < 0) // error - return status; - else if (status > 0) - return E_BUFFER_NOT_FULL; - - if (scan_byte == kEbmlByte0) - break; - - ++pos; - } - - long len = 0; - const long long ebml_id = ReadID(pReader, pos, len); - - if (ebml_id == E_BUFFER_NOT_FULL) - return E_BUFFER_NOT_FULL; - - if (len != 4 || ebml_id != libwebm::kMkvEBML) - return E_FILE_FORMAT_INVALID; - - // Move read pos forward to the EBML header size field. - pos += 4; - - // Read length of size field. - long long result = GetUIntLength(pReader, pos, len); - - if (result < 0) // error - return E_FILE_FORMAT_INVALID; - else if (result > 0) // need more data - return E_BUFFER_NOT_FULL; - - if (len < 1 || len > 8) - return E_FILE_FORMAT_INVALID; - - if ((total >= 0) && ((total - pos) < len)) - return E_FILE_FORMAT_INVALID; - - if ((available - pos) < len) - return pos + len; // try again later - - // Read the EBML header size. - result = ReadUInt(pReader, pos, len); - - if (result < 0) // error - return result; - - pos += len; // consume size field - - // pos now designates start of payload - - if ((total >= 0) && ((total - pos) < result)) - return E_FILE_FORMAT_INVALID; - - if ((available - pos) < result) - return pos + result; - - const long long end = pos + result; - - Init(); - - while (pos < end) { - long long id, size; - - status = ParseElementHeader(pReader, pos, end, id, size); - - if (status < 0) // error - return status; - - if (size == 0) - return E_FILE_FORMAT_INVALID; - - if (id == libwebm::kMkvEBMLVersion) { - m_version = UnserializeUInt(pReader, pos, size); - - if (m_version <= 0) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvEBMLReadVersion) { - m_readVersion = UnserializeUInt(pReader, pos, size); - - if (m_readVersion <= 0) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvEBMLMaxIDLength) { - m_maxIdLength = UnserializeUInt(pReader, pos, size); - - if (m_maxIdLength <= 0) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvEBMLMaxSizeLength) { - m_maxSizeLength = UnserializeUInt(pReader, pos, size); - - if (m_maxSizeLength <= 0) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvDocType) { - if (m_docType) - return E_FILE_FORMAT_INVALID; - - status = UnserializeString(pReader, pos, size, m_docType); - - if (status) // error - return status; - } else if (id == libwebm::kMkvDocTypeVersion) { - m_docTypeVersion = UnserializeUInt(pReader, pos, size); - - if (m_docTypeVersion <= 0) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvDocTypeReadVersion) { - m_docTypeReadVersion = UnserializeUInt(pReader, pos, size); - - if (m_docTypeReadVersion <= 0) - return E_FILE_FORMAT_INVALID; - } - - pos += size; - } - - if (pos != end) - return E_FILE_FORMAT_INVALID; - - // Make sure DocType, DocTypeReadVersion, and DocTypeVersion are valid. - if (m_docType == NULL || m_docTypeReadVersion <= 0 || m_docTypeVersion <= 0) - return E_FILE_FORMAT_INVALID; - - // Make sure EBMLMaxIDLength and EBMLMaxSizeLength are valid. - if (m_maxIdLength <= 0 || m_maxIdLength > 4 || m_maxSizeLength <= 0 || - m_maxSizeLength > 8) - return E_FILE_FORMAT_INVALID; - - return 0; -} - -Segment::Segment(IMkvReader* pReader, long long elem_start, - // long long elem_size, - long long start, long long size) - : m_pReader(pReader), - m_element_start(elem_start), - // m_element_size(elem_size), - m_start(start), - m_size(size), - m_pos(start), - m_pUnknownSize(0), - m_pSeekHead(NULL), - m_pInfo(NULL), - m_pTracks(NULL), - m_pCues(NULL), - m_pChapters(NULL), - m_pTags(NULL), - m_clusters(NULL), - m_clusterCount(0), - m_clusterPreloadCount(0), - m_clusterSize(0) {} - -Segment::~Segment() { - const long count = m_clusterCount + m_clusterPreloadCount; - - Cluster** i = m_clusters; - Cluster** j = m_clusters + count; - - while (i != j) { - Cluster* const p = *i++; - delete p; - } - - delete[] m_clusters; - - delete m_pTracks; - delete m_pInfo; - delete m_pCues; - delete m_pChapters; - delete m_pTags; - delete m_pSeekHead; -} - -long long Segment::CreateInstance(IMkvReader* pReader, long long pos, - Segment*& pSegment) { - if (pReader == NULL || pos < 0) - return E_PARSE_FAILED; - - pSegment = NULL; - - long long total, available; - - const long status = pReader->Length(&total, &available); - - if (status < 0) // error - return status; - - if (available < 0) - return -1; - - if ((total >= 0) && (available > total)) - return -1; - - // I would assume that in practice this loop would execute - // exactly once, but we allow for other elements (e.g. Void) - // to immediately follow the EBML header. This is fine for - // the source filter case (since the entire file is available), - // but in the splitter case over a network we should probably - // just give up early. We could for example decide only to - // execute this loop a maximum of, say, 10 times. - // TODO: - // There is an implied "give up early" by only parsing up - // to the available limit. We do do that, but only if the - // total file size is unknown. We could decide to always - // use what's available as our limit (irrespective of whether - // we happen to know the total file length). This would have - // as its sense "parse this much of the file before giving up", - // which a slightly different sense from "try to parse up to - // 10 EMBL elements before giving up". - - for (;;) { - if ((total >= 0) && (pos >= total)) - return E_FILE_FORMAT_INVALID; - - // Read ID - long len; - long long result = GetUIntLength(pReader, pos, len); - - if (result) // error, or too few available bytes - return result; - - if ((total >= 0) && ((pos + len) > total)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > available) - return pos + len; - - const long long idpos = pos; - const long long id = ReadID(pReader, pos, len); - - if (id < 0) - return E_FILE_FORMAT_INVALID; - - pos += len; // consume ID - - // Read Size - - result = GetUIntLength(pReader, pos, len); - - if (result) // error, or too few available bytes - return result; - - if ((total >= 0) && ((pos + len) > total)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > available) - return pos + len; - - long long size = ReadUInt(pReader, pos, len); - - if (size < 0) // error - return size; - - pos += len; // consume length of size of element - - // Pos now points to start of payload - - // Handle "unknown size" for live streaming of webm files. - const long long unknown_size = (1LL << (7 * len)) - 1; - - if (id == libwebm::kMkvSegment) { - if (size == unknown_size) - size = -1; - - else if (total < 0) - size = -1; - - else if ((pos + size) > total) - size = -1; - - pSegment = new (std::nothrow) Segment(pReader, idpos, pos, size); - if (pSegment == NULL) - return E_PARSE_FAILED; - - return 0; // success - } - - if (size == unknown_size) - return E_FILE_FORMAT_INVALID; - - if ((total >= 0) && ((pos + size) > total)) - return E_FILE_FORMAT_INVALID; - - if ((pos + size) > available) - return pos + size; - - pos += size; // consume payload - } -} - -long long Segment::ParseHeaders() { - // Outermost (level 0) segment object has been constructed, - // and pos designates start of payload. We need to find the - // inner (level 1) elements. - long long total, available; - - const int status = m_pReader->Length(&total, &available); - - if (status < 0) // error - return status; - - if (total > 0 && available > total) - return E_FILE_FORMAT_INVALID; - - const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; - - if ((segment_stop >= 0 && total >= 0 && segment_stop > total) || - (segment_stop >= 0 && m_pos > segment_stop)) { - return E_FILE_FORMAT_INVALID; - } - - for (;;) { - if ((total >= 0) && (m_pos >= total)) - break; - - if ((segment_stop >= 0) && (m_pos >= segment_stop)) - break; - - long long pos = m_pos; - const long long element_start = pos; - - // Avoid rolling over pos when very close to LLONG_MAX. - unsigned long long rollover_check = pos + 1ULL; - if (rollover_check > LLONG_MAX) - return E_FILE_FORMAT_INVALID; - - if ((pos + 1) > available) - return (pos + 1); - - long len; - long long result = GetUIntLength(m_pReader, pos, len); - - if (result < 0) // error - return result; - - if (result > 0) { - // MkvReader doesn't have enough data to satisfy this read attempt. - return (pos + 1); - } - - if ((segment_stop >= 0) && ((pos + len) > segment_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > available) - return pos + len; - - const long long idpos = pos; - const long long id = ReadID(m_pReader, idpos, len); - - if (id < 0) - return E_FILE_FORMAT_INVALID; - - if (id == libwebm::kMkvCluster) - break; - - pos += len; // consume ID - - if ((pos + 1) > available) - return (pos + 1); - - // Read Size - result = GetUIntLength(m_pReader, pos, len); - - if (result < 0) // error - return result; - - if (result > 0) { - // MkvReader doesn't have enough data to satisfy this read attempt. - return (pos + 1); - } - - if ((segment_stop >= 0) && ((pos + len) > segment_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > available) - return pos + len; - - const long long size = ReadUInt(m_pReader, pos, len); - - if (size < 0 || len < 1 || len > 8) { - // TODO(tomfinegan): ReadUInt should return an error when len is < 1 or - // len > 8 is true instead of checking this _everywhere_. - return size; - } - - pos += len; // consume length of size of element - - // Avoid rolling over pos when very close to LLONG_MAX. - rollover_check = static_cast(pos) + size; - if (rollover_check > LLONG_MAX) - return E_FILE_FORMAT_INVALID; - - const long long element_size = size + pos - element_start; - - // Pos now points to start of payload - - if ((segment_stop >= 0) && ((pos + size) > segment_stop)) - return E_FILE_FORMAT_INVALID; - - // We read EBML elements either in total or nothing at all. - - if ((pos + size) > available) - return pos + size; - - if (id == libwebm::kMkvInfo) { - if (m_pInfo) - return E_FILE_FORMAT_INVALID; - - m_pInfo = new (std::nothrow) - SegmentInfo(this, pos, size, element_start, element_size); - - if (m_pInfo == NULL) - return -1; - - const long status = m_pInfo->Parse(); - - if (status) - return status; - } else if (id == libwebm::kMkvTracks) { - if (m_pTracks) - return E_FILE_FORMAT_INVALID; - - m_pTracks = new (std::nothrow) - Tracks(this, pos, size, element_start, element_size); - - if (m_pTracks == NULL) - return -1; - - const long status = m_pTracks->Parse(); - - if (status) - return status; - } else if (id == libwebm::kMkvCues) { - if (m_pCues == NULL) { - m_pCues = new (std::nothrow) - Cues(this, pos, size, element_start, element_size); - - if (m_pCues == NULL) - return -1; - } - } else if (id == libwebm::kMkvSeekHead) { - if (m_pSeekHead == NULL) { - m_pSeekHead = new (std::nothrow) - SeekHead(this, pos, size, element_start, element_size); - - if (m_pSeekHead == NULL) - return -1; - - const long status = m_pSeekHead->Parse(); - - if (status) - return status; - } - } else if (id == libwebm::kMkvChapters) { - if (m_pChapters == NULL) { - m_pChapters = new (std::nothrow) - Chapters(this, pos, size, element_start, element_size); - - if (m_pChapters == NULL) - return -1; - - const long status = m_pChapters->Parse(); - - if (status) - return status; - } - } else if (id == libwebm::kMkvTags) { - if (m_pTags == NULL) { - m_pTags = new (std::nothrow) - Tags(this, pos, size, element_start, element_size); - - if (m_pTags == NULL) - return -1; - - const long status = m_pTags->Parse(); - - if (status) - return status; - } - } - - m_pos = pos + size; // consume payload - } - - if (segment_stop >= 0 && m_pos > segment_stop) - return E_FILE_FORMAT_INVALID; - - if (m_pInfo == NULL) // TODO: liberalize this behavior - return E_FILE_FORMAT_INVALID; - - if (m_pTracks == NULL) - return E_FILE_FORMAT_INVALID; - - return 0; // success -} - -long Segment::LoadCluster(long long& pos, long& len) { - for (;;) { - const long result = DoLoadCluster(pos, len); - - if (result <= 1) - return result; - } -} - -long Segment::DoLoadCluster(long long& pos, long& len) { - if (m_pos < 0) - return DoLoadClusterUnknownSize(pos, len); - - long long total, avail; - - long status = m_pReader->Length(&total, &avail); - - if (status < 0) // error - return status; - - if (total >= 0 && avail > total) - return E_FILE_FORMAT_INVALID; - - const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; - - long long cluster_off = -1; // offset relative to start of segment - long long cluster_size = -1; // size of cluster payload - - for (;;) { - if ((total >= 0) && (m_pos >= total)) - return 1; // no more clusters - - if ((segment_stop >= 0) && (m_pos >= segment_stop)) - return 1; // no more clusters - - pos = m_pos; - - // Read ID - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - long long result = GetUIntLength(m_pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) - return E_BUFFER_NOT_FULL; - - if ((segment_stop >= 0) && ((pos + len) > segment_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long idpos = pos; - const long long id = ReadID(m_pReader, idpos, len); - - if (id < 0) - return E_FILE_FORMAT_INVALID; - - pos += len; // consume ID - - // Read Size - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - result = GetUIntLength(m_pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) - return E_BUFFER_NOT_FULL; - - if ((segment_stop >= 0) && ((pos + len) > segment_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long size = ReadUInt(m_pReader, pos, len); - - if (size < 0) // error - return static_cast(size); - - pos += len; // consume length of size of element - - // pos now points to start of payload - - if (size == 0) { - // Missing element payload: move on. - m_pos = pos; - continue; - } - - const long long unknown_size = (1LL << (7 * len)) - 1; - - if ((segment_stop >= 0) && (size != unknown_size) && - ((pos + size) > segment_stop)) { - return E_FILE_FORMAT_INVALID; - } - - if (id == libwebm::kMkvCues) { - if (size == unknown_size) { - // Cues element of unknown size: Not supported. - return E_FILE_FORMAT_INVALID; - } - - if (m_pCues == NULL) { - const long long element_size = (pos - idpos) + size; - - m_pCues = new (std::nothrow) Cues(this, pos, size, idpos, element_size); - if (m_pCues == NULL) - return -1; - } - - m_pos = pos + size; // consume payload - continue; - } - - if (id != libwebm::kMkvCluster) { - // Besides the Segment, Libwebm allows only cluster elements of unknown - // size. Fail the parse upon encountering a non-cluster element reporting - // unknown size. - if (size == unknown_size) - return E_FILE_FORMAT_INVALID; - - m_pos = pos + size; // consume payload - continue; - } - - // We have a cluster. - - cluster_off = idpos - m_start; // relative pos - - if (size != unknown_size) - cluster_size = size; - - break; - } - - if (cluster_off < 0) { - // No cluster, die. - return E_FILE_FORMAT_INVALID; - } - - long long pos_; - long len_; - - status = Cluster::HasBlockEntries(this, cluster_off, pos_, len_); - - if (status < 0) { // error, or underflow - pos = pos_; - len = len_; - - return status; - } - - // status == 0 means "no block entries found" - // status > 0 means "found at least one block entry" - - // TODO: - // The issue here is that the segment increments its own - // pos ptr past the most recent cluster parsed, and then - // starts from there to parse the next cluster. If we - // don't know the size of the current cluster, then we - // must either parse its payload (as we do below), looking - // for the cluster (or cues) ID to terminate the parse. - // This isn't really what we want: rather, we really need - // a way to create the curr cluster object immediately. - // The pity is that cluster::parse can determine its own - // boundary, and we largely duplicate that same logic here. - // - // Maybe we need to get rid of our look-ahead preloading - // in source::parse??? - // - // As we're parsing the blocks in the curr cluster - //(in cluster::parse), we should have some way to signal - // to the segment that we have determined the boundary, - // so it can adjust its own segment::m_pos member. - // - // The problem is that we're asserting in asyncreadinit, - // because we adjust the pos down to the curr seek pos, - // and the resulting adjusted len is > 2GB. I'm suspicious - // that this is even correct, but even if it is, we can't - // be loading that much data in the cache anyway. - - const long idx = m_clusterCount; - - if (m_clusterPreloadCount > 0) { - if (idx >= m_clusterSize) - return E_FILE_FORMAT_INVALID; - - Cluster* const pCluster = m_clusters[idx]; - if (pCluster == NULL || pCluster->m_index >= 0) - return E_FILE_FORMAT_INVALID; - - const long long off = pCluster->GetPosition(); - if (off < 0) - return E_FILE_FORMAT_INVALID; - - if (off == cluster_off) { // preloaded already - if (status == 0) // no entries found - return E_FILE_FORMAT_INVALID; - - if (cluster_size >= 0) - pos += cluster_size; - else { - const long long element_size = pCluster->GetElementSize(); - - if (element_size <= 0) - return E_FILE_FORMAT_INVALID; // TODO: handle this case - - pos = pCluster->m_element_start + element_size; - } - - pCluster->m_index = idx; // move from preloaded to loaded - ++m_clusterCount; - --m_clusterPreloadCount; - - m_pos = pos; // consume payload - if (segment_stop >= 0 && m_pos > segment_stop) - return E_FILE_FORMAT_INVALID; - - return 0; // success - } - } - - if (status == 0) { // no entries found - if (cluster_size >= 0) - pos += cluster_size; - - if ((total >= 0) && (pos >= total)) { - m_pos = total; - return 1; // no more clusters - } - - if ((segment_stop >= 0) && (pos >= segment_stop)) { - m_pos = segment_stop; - return 1; // no more clusters - } - - m_pos = pos; - return 2; // try again - } - - // status > 0 means we have an entry - - Cluster* const pCluster = Cluster::Create(this, idx, cluster_off); - if (pCluster == NULL) - return -1; - - if (!AppendCluster(pCluster)) { - delete pCluster; - return -1; - } - - if (cluster_size >= 0) { - pos += cluster_size; - - m_pos = pos; - - if (segment_stop > 0 && m_pos > segment_stop) - return E_FILE_FORMAT_INVALID; - - return 0; - } - - m_pUnknownSize = pCluster; - m_pos = -pos; - - return 0; // partial success, since we have a new cluster - - // status == 0 means "no block entries found" - // pos designates start of payload - // m_pos has NOT been adjusted yet (in case we need to come back here) -} - -long Segment::DoLoadClusterUnknownSize(long long& pos, long& len) { - if (m_pos >= 0 || m_pUnknownSize == NULL) - return E_PARSE_FAILED; - - const long status = m_pUnknownSize->Parse(pos, len); - - if (status < 0) // error or underflow - return status; - - if (status == 0) // parsed a block - return 2; // continue parsing - - const long long start = m_pUnknownSize->m_element_start; - const long long size = m_pUnknownSize->GetElementSize(); - - if (size < 0) - return E_FILE_FORMAT_INVALID; - - pos = start + size; - m_pos = pos; - - m_pUnknownSize = 0; - - return 2; // continue parsing -} - -bool Segment::AppendCluster(Cluster* pCluster) { - if (pCluster == NULL || pCluster->m_index < 0) - return false; - - const long count = m_clusterCount + m_clusterPreloadCount; - - long& size = m_clusterSize; - const long idx = pCluster->m_index; - - if (size < count || idx != m_clusterCount) - return false; - - if (count >= size) { - const long n = (size <= 0) ? 2048 : 2 * size; - - Cluster** const qq = new (std::nothrow) Cluster*[n]; - if (qq == NULL) - return false; - - Cluster** q = qq; - Cluster** p = m_clusters; - Cluster** const pp = p + count; - - while (p != pp) - *q++ = *p++; - - delete[] m_clusters; - - m_clusters = qq; - size = n; - } - - if (m_clusterPreloadCount > 0) { - Cluster** const p = m_clusters + m_clusterCount; - if (*p == NULL || (*p)->m_index >= 0) - return false; - - Cluster** q = p + m_clusterPreloadCount; - if (q >= (m_clusters + size)) - return false; - - for (;;) { - Cluster** const qq = q - 1; - if ((*qq)->m_index >= 0) - return false; - - *q = *qq; - q = qq; - - if (q == p) - break; - } - } - - m_clusters[idx] = pCluster; - ++m_clusterCount; - return true; -} - -bool Segment::PreloadCluster(Cluster* pCluster, ptrdiff_t idx) { - if (pCluster == NULL || pCluster->m_index >= 0 || idx < m_clusterCount) - return false; - - const long count = m_clusterCount + m_clusterPreloadCount; - - long& size = m_clusterSize; - if (size < count) - return false; - - if (count >= size) { - const long n = (size <= 0) ? 2048 : 2 * size; - - Cluster** const qq = new (std::nothrow) Cluster*[n]; - if (qq == NULL) - return false; - Cluster** q = qq; - - Cluster** p = m_clusters; - Cluster** const pp = p + count; - - while (p != pp) - *q++ = *p++; - - delete[] m_clusters; - - m_clusters = qq; - size = n; - } - - if (m_clusters == NULL) - return false; - - Cluster** const p = m_clusters + idx; - - Cluster** q = m_clusters + count; - if (q < p || q >= (m_clusters + size)) - return false; - - while (q > p) { - Cluster** const qq = q - 1; - - if ((*qq)->m_index >= 0) - return false; - - *q = *qq; - q = qq; - } - - m_clusters[idx] = pCluster; - ++m_clusterPreloadCount; - return true; -} - -long Segment::Load() { - if (m_clusters != NULL || m_clusterSize != 0 || m_clusterCount != 0) - return E_PARSE_FAILED; - - // Outermost (level 0) segment object has been constructed, - // and pos designates start of payload. We need to find the - // inner (level 1) elements. - - const long long header_status = ParseHeaders(); - - if (header_status < 0) // error - return static_cast(header_status); - - if (header_status > 0) // underflow - return E_BUFFER_NOT_FULL; - - if (m_pInfo == NULL || m_pTracks == NULL) - return E_FILE_FORMAT_INVALID; - - for (;;) { - const long status = LoadCluster(); - - if (status < 0) // error - return status; - - if (status >= 1) // no more clusters - return 0; - } -} - -SeekHead::Entry::Entry() : id(0), pos(0), element_start(0), element_size(0) {} - -SeekHead::SeekHead(Segment* pSegment, long long start, long long size_, - long long element_start, long long element_size) - : m_pSegment(pSegment), - m_start(start), - m_size(size_), - m_element_start(element_start), - m_element_size(element_size), - m_entries(0), - m_entry_count(0), - m_void_elements(0), - m_void_element_count(0) {} - -SeekHead::~SeekHead() { - delete[] m_entries; - delete[] m_void_elements; -} - -long SeekHead::Parse() { - IMkvReader* const pReader = m_pSegment->m_pReader; - - long long pos = m_start; - const long long stop = m_start + m_size; - - // first count the seek head entries - - long long entry_count = 0; - long long void_element_count = 0; - - while (pos < stop) { - long long id, size; - - const long status = ParseElementHeader(pReader, pos, stop, id, size); - - if (status < 0) // error - return status; - - if (id == libwebm::kMkvSeek) { - ++entry_count; - if (entry_count > INT_MAX) - return E_PARSE_FAILED; - } else if (id == libwebm::kMkvVoid) { - ++void_element_count; - if (void_element_count > INT_MAX) - return E_PARSE_FAILED; - } - - pos += size; // consume payload - - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - - if (entry_count > 0) { - m_entries = new (std::nothrow) Entry[static_cast(entry_count)]; - - if (m_entries == NULL) - return -1; - } - - if (void_element_count > 0) { - m_void_elements = - new (std::nothrow) VoidElement[static_cast(void_element_count)]; - - if (m_void_elements == NULL) - return -1; - } - - // now parse the entries and void elements - - Entry* pEntry = m_entries; - VoidElement* pVoidElement = m_void_elements; - - pos = m_start; - - while (pos < stop) { - const long long idpos = pos; - - long long id, size; - - const long status = ParseElementHeader(pReader, pos, stop, id, size); - - if (status < 0) // error - return status; - - if (id == libwebm::kMkvSeek && entry_count > 0) { - if (ParseEntry(pReader, pos, size, pEntry)) { - Entry& e = *pEntry++; - - e.element_start = idpos; - e.element_size = (pos + size) - idpos; - } - } else if (id == libwebm::kMkvVoid && void_element_count > 0) { - VoidElement& e = *pVoidElement++; - - e.element_start = idpos; - e.element_size = (pos + size) - idpos; - } - - pos += size; // consume payload - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - - ptrdiff_t count_ = ptrdiff_t(pEntry - m_entries); - assert(count_ >= 0); - assert(static_cast(count_) <= entry_count); - - m_entry_count = static_cast(count_); - - count_ = ptrdiff_t(pVoidElement - m_void_elements); - assert(count_ >= 0); - assert(static_cast(count_) <= void_element_count); - - m_void_element_count = static_cast(count_); - - return 0; -} - -int SeekHead::GetCount() const { return m_entry_count; } - -const SeekHead::Entry* SeekHead::GetEntry(int idx) const { - if (idx < 0) - return 0; - - if (idx >= m_entry_count) - return 0; - - return m_entries + idx; -} - -int SeekHead::GetVoidElementCount() const { return m_void_element_count; } - -const SeekHead::VoidElement* SeekHead::GetVoidElement(int idx) const { - if (idx < 0) - return 0; - - if (idx >= m_void_element_count) - return 0; - - return m_void_elements + idx; -} - -long Segment::ParseCues(long long off, long long& pos, long& len) { - if (m_pCues) - return 0; // success - - if (off < 0) - return -1; - - long long total, avail; - - const int status = m_pReader->Length(&total, &avail); - - if (status < 0) // error - return status; - - assert((total < 0) || (avail <= total)); - - pos = m_start + off; - - if ((total < 0) || (pos >= total)) - return 1; // don't bother parsing cues - - const long long element_start = pos; - const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - long long result = GetUIntLength(m_pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) // underflow (weird) - { - len = 1; - return E_BUFFER_NOT_FULL; - } - - if ((segment_stop >= 0) && ((pos + len) > segment_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long idpos = pos; - - const long long id = ReadID(m_pReader, idpos, len); - - if (id != libwebm::kMkvCues) - return E_FILE_FORMAT_INVALID; - - pos += len; // consume ID - assert((segment_stop < 0) || (pos <= segment_stop)); - - // Read Size - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - result = GetUIntLength(m_pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) // underflow (weird) - { - len = 1; - return E_BUFFER_NOT_FULL; - } - - if ((segment_stop >= 0) && ((pos + len) > segment_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long size = ReadUInt(m_pReader, pos, len); - - if (size < 0) // error - return static_cast(size); - - if (size == 0) // weird, although technically not illegal - return 1; // done - - pos += len; // consume length of size of element - assert((segment_stop < 0) || (pos <= segment_stop)); - - // Pos now points to start of payload - - const long long element_stop = pos + size; - - if ((segment_stop >= 0) && (element_stop > segment_stop)) - return E_FILE_FORMAT_INVALID; - - if ((total >= 0) && (element_stop > total)) - return 1; // don't bother parsing anymore - - len = static_cast(size); - - if (element_stop > avail) - return E_BUFFER_NOT_FULL; - - const long long element_size = element_stop - element_start; - - m_pCues = - new (std::nothrow) Cues(this, pos, size, element_start, element_size); - if (m_pCues == NULL) - return -1; - - return 0; // success -} - -bool SeekHead::ParseEntry(IMkvReader* pReader, long long start, long long size_, - Entry* pEntry) { - if (size_ <= 0) - return false; - - long long pos = start; - const long long stop = start + size_; - - long len; - - // parse the container for the level-1 element ID - - const long long seekIdId = ReadID(pReader, pos, len); - if (seekIdId < 0) - return false; - - if (seekIdId != libwebm::kMkvSeekID) - return false; - - if ((pos + len) > stop) - return false; - - pos += len; // consume SeekID id - - const long long seekIdSize = ReadUInt(pReader, pos, len); - - if (seekIdSize <= 0) - return false; - - if ((pos + len) > stop) - return false; - - pos += len; // consume size of field - - if ((pos + seekIdSize) > stop) - return false; - - pEntry->id = ReadID(pReader, pos, len); // payload - - if (pEntry->id <= 0) - return false; - - if (len != seekIdSize) - return false; - - pos += seekIdSize; // consume SeekID payload - - const long long seekPosId = ReadID(pReader, pos, len); - - if (seekPosId != libwebm::kMkvSeekPosition) - return false; - - if ((pos + len) > stop) - return false; - - pos += len; // consume id - - const long long seekPosSize = ReadUInt(pReader, pos, len); - - if (seekPosSize <= 0) - return false; - - if ((pos + len) > stop) - return false; - - pos += len; // consume size - - if ((pos + seekPosSize) > stop) - return false; - - pEntry->pos = UnserializeUInt(pReader, pos, seekPosSize); - - if (pEntry->pos < 0) - return false; - - pos += seekPosSize; // consume payload - - if (pos != stop) - return false; - - return true; -} - -Cues::Cues(Segment* pSegment, long long start_, long long size_, - long long element_start, long long element_size) - : m_pSegment(pSegment), - m_start(start_), - m_size(size_), - m_element_start(element_start), - m_element_size(element_size), - m_cue_points(NULL), - m_count(0), - m_preload_count(0), - m_pos(start_) {} - -Cues::~Cues() { - const long n = m_count + m_preload_count; - - CuePoint** p = m_cue_points; - CuePoint** const q = p + n; - - while (p != q) { - CuePoint* const pCP = *p++; - assert(pCP); - - delete pCP; - } - - delete[] m_cue_points; -} - -long Cues::GetCount() const { - if (m_cue_points == NULL) - return -1; - - return m_count; // TODO: really ignore preload count? -} - -bool Cues::DoneParsing() const { - const long long stop = m_start + m_size; - return (m_pos >= stop); -} - -bool Cues::Init() const { - if (m_cue_points) - return true; - - if (m_count != 0 || m_preload_count != 0) - return false; - - IMkvReader* const pReader = m_pSegment->m_pReader; - - const long long stop = m_start + m_size; - long long pos = m_start; - - long cue_points_size = 0; - - while (pos < stop) { - const long long idpos = pos; - - long len; - - const long long id = ReadID(pReader, pos, len); - if (id < 0 || (pos + len) > stop) { - return false; - } - - pos += len; // consume ID - - const long long size = ReadUInt(pReader, pos, len); - if (size < 0 || (pos + len > stop)) { - return false; - } - - pos += len; // consume Size field - if (pos + size > stop) { - return false; - } - - if (id == libwebm::kMkvCuePoint) { - if (!PreloadCuePoint(cue_points_size, idpos)) - return false; - } - - pos += size; // skip payload - } - return true; -} - -bool Cues::PreloadCuePoint(long& cue_points_size, long long pos) const { - if (m_count != 0) - return false; - - if (m_preload_count >= cue_points_size) { - const long n = (cue_points_size <= 0) ? 2048 : 2 * cue_points_size; - - CuePoint** const qq = new (std::nothrow) CuePoint*[n]; - if (qq == NULL) - return false; - - CuePoint** q = qq; // beginning of target - - CuePoint** p = m_cue_points; // beginning of source - CuePoint** const pp = p + m_preload_count; // end of source - - while (p != pp) - *q++ = *p++; - - delete[] m_cue_points; - - m_cue_points = qq; - cue_points_size = n; - } - - CuePoint* const pCP = new (std::nothrow) CuePoint(m_preload_count, pos); - if (pCP == NULL) - return false; - - m_cue_points[m_preload_count++] = pCP; - return true; -} - -bool Cues::LoadCuePoint() const { - const long long stop = m_start + m_size; - - if (m_pos >= stop) - return false; // nothing else to do - - if (!Init()) { - m_pos = stop; - return false; - } - - IMkvReader* const pReader = m_pSegment->m_pReader; - - while (m_pos < stop) { - const long long idpos = m_pos; - - long len; - - const long long id = ReadID(pReader, m_pos, len); - if (id < 0 || (m_pos + len) > stop) - return false; - - m_pos += len; // consume ID - - const long long size = ReadUInt(pReader, m_pos, len); - if (size < 0 || (m_pos + len) > stop) - return false; - - m_pos += len; // consume Size field - if ((m_pos + size) > stop) - return false; - - if (id != libwebm::kMkvCuePoint) { - m_pos += size; // consume payload - if (m_pos > stop) - return false; - - continue; - } - - if (m_preload_count < 1) - return false; - - CuePoint* const pCP = m_cue_points[m_count]; - if (!pCP || (pCP->GetTimeCode() < 0 && (-pCP->GetTimeCode() != idpos))) - return false; - - if (!pCP->Load(pReader)) { - m_pos = stop; - return false; - } - ++m_count; - --m_preload_count; - - m_pos += size; // consume payload - if (m_pos > stop) - return false; - - return true; // yes, we loaded a cue point - } - - return false; // no, we did not load a cue point -} - -bool Cues::Find(long long time_ns, const Track* pTrack, const CuePoint*& pCP, - const CuePoint::TrackPosition*& pTP) const { - if (time_ns < 0 || pTrack == NULL || m_cue_points == NULL || m_count == 0) - return false; - - CuePoint** const ii = m_cue_points; - CuePoint** i = ii; - - CuePoint** const jj = ii + m_count; - CuePoint** j = jj; - - pCP = *i; - if (pCP == NULL) - return false; - - if (time_ns <= pCP->GetTime(m_pSegment)) { - pTP = pCP->Find(pTrack); - return (pTP != NULL); - } - - while (i < j) { - // INVARIANT: - //[ii, i) <= time_ns - //[i, j) ? - //[j, jj) > time_ns - - CuePoint** const k = i + (j - i) / 2; - if (k >= jj) - return false; - - CuePoint* const pCP = *k; - if (pCP == NULL) - return false; - - const long long t = pCP->GetTime(m_pSegment); - - if (t <= time_ns) - i = k + 1; - else - j = k; - - if (i > j) - return false; - } - - if (i != j || i > jj || i <= ii) - return false; - - pCP = *--i; - - if (pCP == NULL || pCP->GetTime(m_pSegment) > time_ns) - return false; - - // TODO: here and elsewhere, it's probably not correct to search - // for the cue point with this time, and then search for a matching - // track. In principle, the matching track could be on some earlier - // cue point, and with our current algorithm, we'd miss it. To make - // this bullet-proof, we'd need to create a secondary structure, - // with a list of cue points that apply to a track, and then search - // that track-based structure for a matching cue point. - - pTP = pCP->Find(pTrack); - return (pTP != NULL); -} - -const CuePoint* Cues::GetFirst() const { - if (m_cue_points == NULL || m_count == 0) - return NULL; - - CuePoint* const* const pp = m_cue_points; - if (pp == NULL) - return NULL; - - CuePoint* const pCP = pp[0]; - if (pCP == NULL || pCP->GetTimeCode() < 0) - return NULL; - - return pCP; -} - -const CuePoint* Cues::GetLast() const { - if (m_cue_points == NULL || m_count <= 0) - return NULL; - - const long index = m_count - 1; - - CuePoint* const* const pp = m_cue_points; - if (pp == NULL) - return NULL; - - CuePoint* const pCP = pp[index]; - if (pCP == NULL || pCP->GetTimeCode() < 0) - return NULL; - - return pCP; -} - -const CuePoint* Cues::GetNext(const CuePoint* pCurr) const { - if (pCurr == NULL || pCurr->GetTimeCode() < 0 || m_cue_points == NULL || - m_count < 1) { - return NULL; - } - - long index = pCurr->m_index; - if (index >= m_count) - return NULL; - - CuePoint* const* const pp = m_cue_points; - if (pp == NULL || pp[index] != pCurr) - return NULL; - - ++index; - - if (index >= m_count) - return NULL; - - CuePoint* const pNext = pp[index]; - - if (pNext == NULL || pNext->GetTimeCode() < 0) - return NULL; - - return pNext; -} - -const BlockEntry* Cues::GetBlock(const CuePoint* pCP, - const CuePoint::TrackPosition* pTP) const { - if (pCP == NULL || pTP == NULL) - return NULL; - - return m_pSegment->GetBlock(*pCP, *pTP); -} - -const BlockEntry* Segment::GetBlock(const CuePoint& cp, - const CuePoint::TrackPosition& tp) { - Cluster** const ii = m_clusters; - Cluster** i = ii; - - const long count = m_clusterCount + m_clusterPreloadCount; - - Cluster** const jj = ii + count; - Cluster** j = jj; - - while (i < j) { - // INVARIANT: - //[ii, i) < pTP->m_pos - //[i, j) ? - //[j, jj) > pTP->m_pos - - Cluster** const k = i + (j - i) / 2; - assert(k < jj); - - Cluster* const pCluster = *k; - assert(pCluster); - - // const long long pos_ = pCluster->m_pos; - // assert(pos_); - // const long long pos = pos_ * ((pos_ < 0) ? -1 : 1); - - const long long pos = pCluster->GetPosition(); - assert(pos >= 0); - - if (pos < tp.m_pos) - i = k + 1; - else if (pos > tp.m_pos) - j = k; - else - return pCluster->GetEntry(cp, tp); - } - - assert(i == j); - // assert(Cluster::HasBlockEntries(this, tp.m_pos)); - - Cluster* const pCluster = Cluster::Create(this, -1, tp.m_pos); //, -1); - if (pCluster == NULL) - return NULL; - - const ptrdiff_t idx = i - m_clusters; - - if (!PreloadCluster(pCluster, idx)) { - delete pCluster; - return NULL; - } - assert(m_clusters); - assert(m_clusterPreloadCount > 0); - assert(m_clusters[idx] == pCluster); - - return pCluster->GetEntry(cp, tp); -} - -const Cluster* Segment::FindOrPreloadCluster(long long requested_pos) { - if (requested_pos < 0) - return 0; - - Cluster** const ii = m_clusters; - Cluster** i = ii; - - const long count = m_clusterCount + m_clusterPreloadCount; - - Cluster** const jj = ii + count; - Cluster** j = jj; - - while (i < j) { - // INVARIANT: - //[ii, i) < pTP->m_pos - //[i, j) ? - //[j, jj) > pTP->m_pos - - Cluster** const k = i + (j - i) / 2; - assert(k < jj); - - Cluster* const pCluster = *k; - assert(pCluster); - - // const long long pos_ = pCluster->m_pos; - // assert(pos_); - // const long long pos = pos_ * ((pos_ < 0) ? -1 : 1); - - const long long pos = pCluster->GetPosition(); - assert(pos >= 0); - - if (pos < requested_pos) - i = k + 1; - else if (pos > requested_pos) - j = k; - else - return pCluster; - } - - assert(i == j); - // assert(Cluster::HasBlockEntries(this, tp.m_pos)); - - Cluster* const pCluster = Cluster::Create(this, -1, requested_pos); - if (pCluster == NULL) - return NULL; - - const ptrdiff_t idx = i - m_clusters; - - if (!PreloadCluster(pCluster, idx)) { - delete pCluster; - return NULL; - } - assert(m_clusters); - assert(m_clusterPreloadCount > 0); - assert(m_clusters[idx] == pCluster); - - return pCluster; -} - -CuePoint::CuePoint(long idx, long long pos) - : m_element_start(0), - m_element_size(0), - m_index(idx), - m_timecode(-1 * pos), - m_track_positions(NULL), - m_track_positions_count(0) { - assert(pos > 0); -} - -CuePoint::~CuePoint() { delete[] m_track_positions; } - -bool CuePoint::Load(IMkvReader* pReader) { - // odbgstream os; - // os << "CuePoint::Load(begin): timecode=" << m_timecode << endl; - - if (m_timecode >= 0) // already loaded - return true; - - assert(m_track_positions == NULL); - assert(m_track_positions_count == 0); - - long long pos_ = -m_timecode; - const long long element_start = pos_; - - long long stop; - - { - long len; - - const long long id = ReadID(pReader, pos_, len); - if (id != libwebm::kMkvCuePoint) - return false; - - pos_ += len; // consume ID - - const long long size = ReadUInt(pReader, pos_, len); - assert(size >= 0); - - pos_ += len; // consume Size field - // pos_ now points to start of payload - - stop = pos_ + size; - } - - const long long element_size = stop - element_start; - - long long pos = pos_; - - // First count number of track positions - unsigned long long track_positions_count = 0; - while (pos < stop) { - long len; - - const long long id = ReadID(pReader, pos, len); - if ((id < 0) || (pos + len > stop)) { - return false; - } - - pos += len; // consume ID - - const long long size = ReadUInt(pReader, pos, len); - if ((size < 0) || (pos + len > stop)) { - return false; - } - - pos += len; // consume Size field - if ((pos + size) > stop) { - return false; - } - - if (id == libwebm::kMkvCueTime) - m_timecode = UnserializeUInt(pReader, pos, size); - - else if (id == libwebm::kMkvCueTrackPositions) { - ++track_positions_count; - if (track_positions_count > UINT_MAX) - return E_PARSE_FAILED; - } - - pos += size; // consume payload - } - - m_track_positions_count = static_cast(track_positions_count); - - if (m_timecode < 0 || m_track_positions_count <= 0) { - return false; - } - - // os << "CuePoint::Load(cont'd): idpos=" << idpos - // << " timecode=" << m_timecode - // << endl; - - m_track_positions = new (std::nothrow) TrackPosition[m_track_positions_count]; - if (m_track_positions == NULL) - return false; - - // Now parse track positions - - TrackPosition* p = m_track_positions; - pos = pos_; - - while (pos < stop) { - long len; - - const long long id = ReadID(pReader, pos, len); - if (id < 0 || (pos + len) > stop) - return false; - - pos += len; // consume ID - - const long long size = ReadUInt(pReader, pos, len); - assert(size >= 0); - assert((pos + len) <= stop); - - pos += len; // consume Size field - assert((pos + size) <= stop); - - if (id == libwebm::kMkvCueTrackPositions) { - TrackPosition& tp = *p++; - if (!tp.Parse(pReader, pos, size)) { - return false; - } - } - - pos += size; // consume payload - if (pos > stop) - return false; - } - - assert(size_t(p - m_track_positions) == m_track_positions_count); - - m_element_start = element_start; - m_element_size = element_size; - - return true; -} - -bool CuePoint::TrackPosition::Parse(IMkvReader* pReader, long long start_, - long long size_) { - const long long stop = start_ + size_; - long long pos = start_; - - m_track = -1; - m_pos = -1; - m_block = 1; // default - - while (pos < stop) { - long len; - - const long long id = ReadID(pReader, pos, len); - if ((id < 0) || ((pos + len) > stop)) { - return false; - } - - pos += len; // consume ID - - const long long size = ReadUInt(pReader, pos, len); - if ((size < 0) || ((pos + len) > stop)) { - return false; - } - - pos += len; // consume Size field - if ((pos + size) > stop) { - return false; - } - - if (id == libwebm::kMkvCueTrack) - m_track = UnserializeUInt(pReader, pos, size); - else if (id == libwebm::kMkvCueClusterPosition) - m_pos = UnserializeUInt(pReader, pos, size); - else if (id == libwebm::kMkvCueBlockNumber) - m_block = UnserializeUInt(pReader, pos, size); - - pos += size; // consume payload - } - - if ((m_pos < 0) || (m_track <= 0) || (m_block < 0) || (m_block > LONG_MAX)) { - return false; - } - - return true; -} - -const CuePoint::TrackPosition* CuePoint::Find(const Track* pTrack) const { - if (pTrack == NULL) { - return NULL; - } - - const long long n = pTrack->GetNumber(); - - const TrackPosition* i = m_track_positions; - const TrackPosition* const j = i + m_track_positions_count; - - while (i != j) { - const TrackPosition& p = *i++; - - if (p.m_track == n) - return &p; - } - - return NULL; // no matching track number found -} - -long long CuePoint::GetTimeCode() const { return m_timecode; } - -long long CuePoint::GetTime(const Segment* pSegment) const { - assert(pSegment); - assert(m_timecode >= 0); - - const SegmentInfo* const pInfo = pSegment->GetInfo(); - assert(pInfo); - - const long long scale = pInfo->GetTimeCodeScale(); - assert(scale >= 1); - - const long long time = scale * m_timecode; - - return time; -} - -bool Segment::DoneParsing() const { - if (m_size < 0) { - long long total, avail; - - const int status = m_pReader->Length(&total, &avail); - - if (status < 0) // error - return true; // must assume done - - if (total < 0) - return false; // assume live stream - - return (m_pos >= total); - } - - const long long stop = m_start + m_size; - - return (m_pos >= stop); -} - -const Cluster* Segment::GetFirst() const { - if ((m_clusters == NULL) || (m_clusterCount <= 0)) - return &m_eos; - - Cluster* const pCluster = m_clusters[0]; - assert(pCluster); - - return pCluster; -} - -const Cluster* Segment::GetLast() const { - if ((m_clusters == NULL) || (m_clusterCount <= 0)) - return &m_eos; - - const long idx = m_clusterCount - 1; - - Cluster* const pCluster = m_clusters[idx]; - assert(pCluster); - - return pCluster; -} - -unsigned long Segment::GetCount() const { return m_clusterCount; } - -const Cluster* Segment::GetNext(const Cluster* pCurr) { - assert(pCurr); - assert(pCurr != &m_eos); - assert(m_clusters); - - long idx = pCurr->m_index; - - if (idx >= 0) { - assert(m_clusterCount > 0); - assert(idx < m_clusterCount); - assert(pCurr == m_clusters[idx]); - - ++idx; - - if (idx >= m_clusterCount) - return &m_eos; // caller will LoadCluster as desired - - Cluster* const pNext = m_clusters[idx]; - assert(pNext); - assert(pNext->m_index >= 0); - assert(pNext->m_index == idx); - - return pNext; - } - - assert(m_clusterPreloadCount > 0); - - long long pos = pCurr->m_element_start; - - assert(m_size >= 0); // TODO - const long long stop = m_start + m_size; // end of segment - - { - long len; - - long long result = GetUIntLength(m_pReader, pos, len); - assert(result == 0); - assert((pos + len) <= stop); // TODO - if (result != 0) - return NULL; - - const long long id = ReadID(m_pReader, pos, len); - if (id != libwebm::kMkvCluster) - return NULL; - - pos += len; // consume ID - - // Read Size - result = GetUIntLength(m_pReader, pos, len); - assert(result == 0); // TODO - assert((pos + len) <= stop); // TODO - - const long long size = ReadUInt(m_pReader, pos, len); - assert(size > 0); // TODO - // assert((pCurr->m_size <= 0) || (pCurr->m_size == size)); - - pos += len; // consume length of size of element - assert((pos + size) <= stop); // TODO - - // Pos now points to start of payload - - pos += size; // consume payload - } - - long long off_next = 0; - - while (pos < stop) { - long len; - - long long result = GetUIntLength(m_pReader, pos, len); - assert(result == 0); - assert((pos + len) <= stop); // TODO - if (result != 0) - return NULL; - - const long long idpos = pos; // pos of next (potential) cluster - - const long long id = ReadID(m_pReader, idpos, len); - if (id < 0) - return NULL; - - pos += len; // consume ID - - // Read Size - result = GetUIntLength(m_pReader, pos, len); - assert(result == 0); // TODO - assert((pos + len) <= stop); // TODO - - const long long size = ReadUInt(m_pReader, pos, len); - assert(size >= 0); // TODO - - pos += len; // consume length of size of element - assert((pos + size) <= stop); // TODO - - // Pos now points to start of payload - - if (size == 0) // weird - continue; - - if (id == libwebm::kMkvCluster) { - const long long off_next_ = idpos - m_start; - - long long pos_; - long len_; - - const long status = Cluster::HasBlockEntries(this, off_next_, pos_, len_); - - assert(status >= 0); - - if (status > 0) { - off_next = off_next_; - break; - } - } - - pos += size; // consume payload - } - - if (off_next <= 0) - return 0; - - Cluster** const ii = m_clusters + m_clusterCount; - Cluster** i = ii; - - Cluster** const jj = ii + m_clusterPreloadCount; - Cluster** j = jj; - - while (i < j) { - // INVARIANT: - //[0, i) < pos_next - //[i, j) ? - //[j, jj) > pos_next - - Cluster** const k = i + (j - i) / 2; - assert(k < jj); - - Cluster* const pNext = *k; - assert(pNext); - assert(pNext->m_index < 0); - - // const long long pos_ = pNext->m_pos; - // assert(pos_); - // pos = pos_ * ((pos_ < 0) ? -1 : 1); - - pos = pNext->GetPosition(); - - if (pos < off_next) - i = k + 1; - else if (pos > off_next) - j = k; - else - return pNext; - } - - assert(i == j); - - Cluster* const pNext = Cluster::Create(this, -1, off_next); - if (pNext == NULL) - return NULL; - - const ptrdiff_t idx_next = i - m_clusters; // insertion position - - if (!PreloadCluster(pNext, idx_next)) { - delete pNext; - return NULL; - } - assert(m_clusters); - assert(idx_next < m_clusterSize); - assert(m_clusters[idx_next] == pNext); - - return pNext; -} - -long Segment::ParseNext(const Cluster* pCurr, const Cluster*& pResult, - long long& pos, long& len) { - assert(pCurr); - assert(!pCurr->EOS()); - assert(m_clusters); - - pResult = 0; - - if (pCurr->m_index >= 0) { // loaded (not merely preloaded) - assert(m_clusters[pCurr->m_index] == pCurr); - - const long next_idx = pCurr->m_index + 1; - - if (next_idx < m_clusterCount) { - pResult = m_clusters[next_idx]; - return 0; // success - } - - // curr cluster is last among loaded - - const long result = LoadCluster(pos, len); - - if (result < 0) // error or underflow - return result; - - if (result > 0) // no more clusters - { - // pResult = &m_eos; - return 1; - } - - pResult = GetLast(); - return 0; // success - } - - assert(m_pos > 0); - - long long total, avail; - - long status = m_pReader->Length(&total, &avail); - - if (status < 0) // error - return status; - - assert((total < 0) || (avail <= total)); - - const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; - - // interrogate curr cluster - - pos = pCurr->m_element_start; - - if (pCurr->m_element_size >= 0) - pos += pCurr->m_element_size; - else { - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - long long result = GetUIntLength(m_pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) // weird - return E_BUFFER_NOT_FULL; - - if ((segment_stop >= 0) && ((pos + len) > segment_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long id = ReadUInt(m_pReader, pos, len); - - if (id != libwebm::kMkvCluster) - return -1; - - pos += len; // consume ID - - // Read Size - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - result = GetUIntLength(m_pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) // weird - return E_BUFFER_NOT_FULL; - - if ((segment_stop >= 0) && ((pos + len) > segment_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long size = ReadUInt(m_pReader, pos, len); - - if (size < 0) // error - return static_cast(size); - - pos += len; // consume size field - - const long long unknown_size = (1LL << (7 * len)) - 1; - - if (size == unknown_size) // TODO: should never happen - return E_FILE_FORMAT_INVALID; // TODO: resolve this - - // assert((pCurr->m_size <= 0) || (pCurr->m_size == size)); - - if ((segment_stop >= 0) && ((pos + size) > segment_stop)) - return E_FILE_FORMAT_INVALID; - - // Pos now points to start of payload - - pos += size; // consume payload (that is, the current cluster) - if (segment_stop >= 0 && pos > segment_stop) - return E_FILE_FORMAT_INVALID; - - // By consuming the payload, we are assuming that the curr - // cluster isn't interesting. That is, we don't bother checking - // whether the payload of the curr cluster is less than what - // happens to be available (obtained via IMkvReader::Length). - // Presumably the caller has already dispensed with the current - // cluster, and really does want the next cluster. - } - - // pos now points to just beyond the last fully-loaded cluster - - for (;;) { - const long status = DoParseNext(pResult, pos, len); - - if (status <= 1) - return status; - } -} - -long Segment::DoParseNext(const Cluster*& pResult, long long& pos, long& len) { - long long total, avail; - - long status = m_pReader->Length(&total, &avail); - - if (status < 0) // error - return status; - - assert((total < 0) || (avail <= total)); - - const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; - - // Parse next cluster. This is strictly a parsing activity. - // Creation of a new cluster object happens later, after the - // parsing is done. - - long long off_next = 0; - long long cluster_size = -1; - - for (;;) { - if ((total >= 0) && (pos >= total)) - return 1; // EOF - - if ((segment_stop >= 0) && (pos >= segment_stop)) - return 1; // EOF - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - long long result = GetUIntLength(m_pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) // weird - return E_BUFFER_NOT_FULL; - - if ((segment_stop >= 0) && ((pos + len) > segment_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long idpos = pos; // absolute - const long long idoff = pos - m_start; // relative - - const long long id = ReadID(m_pReader, idpos, len); // absolute - - if (id < 0) // error - return static_cast(id); - - if (id == 0) // weird - return -1; // generic error - - pos += len; // consume ID - - // Read Size - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - result = GetUIntLength(m_pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) // weird - return E_BUFFER_NOT_FULL; - - if ((segment_stop >= 0) && ((pos + len) > segment_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long size = ReadUInt(m_pReader, pos, len); - - if (size < 0) // error - return static_cast(size); - - pos += len; // consume length of size of element - - // Pos now points to start of payload - - if (size == 0) // weird - continue; - - const long long unknown_size = (1LL << (7 * len)) - 1; - - if ((segment_stop >= 0) && (size != unknown_size) && - ((pos + size) > segment_stop)) { - return E_FILE_FORMAT_INVALID; - } - - if (id == libwebm::kMkvCues) { - if (size == unknown_size) - return E_FILE_FORMAT_INVALID; - - const long long element_stop = pos + size; - - if ((segment_stop >= 0) && (element_stop > segment_stop)) - return E_FILE_FORMAT_INVALID; - - const long long element_start = idpos; - const long long element_size = element_stop - element_start; - - if (m_pCues == NULL) { - m_pCues = new (std::nothrow) - Cues(this, pos, size, element_start, element_size); - if (m_pCues == NULL) - return false; - } - - pos += size; // consume payload - if (segment_stop >= 0 && pos > segment_stop) - return E_FILE_FORMAT_INVALID; - - continue; - } - - if (id != libwebm::kMkvCluster) { // not a Cluster ID - if (size == unknown_size) - return E_FILE_FORMAT_INVALID; - - pos += size; // consume payload - if (segment_stop >= 0 && pos > segment_stop) - return E_FILE_FORMAT_INVALID; - - continue; - } - - // We have a cluster. - off_next = idoff; - - if (size != unknown_size) - cluster_size = size; - - break; - } - - assert(off_next > 0); // have cluster - - // We have parsed the next cluster. - // We have not created a cluster object yet. What we need - // to do now is determine whether it has already be preloaded - //(in which case, an object for this cluster has already been - // created), and if not, create a new cluster object. - - Cluster** const ii = m_clusters + m_clusterCount; - Cluster** i = ii; - - Cluster** const jj = ii + m_clusterPreloadCount; - Cluster** j = jj; - - while (i < j) { - // INVARIANT: - //[0, i) < pos_next - //[i, j) ? - //[j, jj) > pos_next - - Cluster** const k = i + (j - i) / 2; - assert(k < jj); - - const Cluster* const pNext = *k; - assert(pNext); - assert(pNext->m_index < 0); - - pos = pNext->GetPosition(); - assert(pos >= 0); - - if (pos < off_next) - i = k + 1; - else if (pos > off_next) - j = k; - else { - pResult = pNext; - return 0; // success - } - } - - assert(i == j); - - long long pos_; - long len_; - - status = Cluster::HasBlockEntries(this, off_next, pos_, len_); - - if (status < 0) { // error or underflow - pos = pos_; - len = len_; - - return status; - } - - if (status > 0) { // means "found at least one block entry" - Cluster* const pNext = Cluster::Create(this, - -1, // preloaded - off_next); - if (pNext == NULL) - return -1; - - const ptrdiff_t idx_next = i - m_clusters; // insertion position - - if (!PreloadCluster(pNext, idx_next)) { - delete pNext; - return -1; - } - assert(m_clusters); - assert(idx_next < m_clusterSize); - assert(m_clusters[idx_next] == pNext); - - pResult = pNext; - return 0; // success - } - - // status == 0 means "no block entries found" - - if (cluster_size < 0) { // unknown size - const long long payload_pos = pos; // absolute pos of cluster payload - - for (;;) { // determine cluster size - if ((total >= 0) && (pos >= total)) - break; - - if ((segment_stop >= 0) && (pos >= segment_stop)) - break; // no more clusters - - // Read ID - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - long long result = GetUIntLength(m_pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) // weird - return E_BUFFER_NOT_FULL; - - if ((segment_stop >= 0) && ((pos + len) > segment_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long idpos = pos; - const long long id = ReadID(m_pReader, idpos, len); - - if (id < 0) // error (or underflow) - return static_cast(id); - - // This is the distinguished set of ID's we use to determine - // that we have exhausted the sub-element's inside the cluster - // whose ID we parsed earlier. - - if (id == libwebm::kMkvCluster || id == libwebm::kMkvCues) - break; - - pos += len; // consume ID (of sub-element) - - // Read Size - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - result = GetUIntLength(m_pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) // weird - return E_BUFFER_NOT_FULL; - - if ((segment_stop >= 0) && ((pos + len) > segment_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long size = ReadUInt(m_pReader, pos, len); - - if (size < 0) // error - return static_cast(size); - - pos += len; // consume size field of element - - // pos now points to start of sub-element's payload - - if (size == 0) // weird - continue; - - const long long unknown_size = (1LL << (7 * len)) - 1; - - if (size == unknown_size) - return E_FILE_FORMAT_INVALID; // not allowed for sub-elements - - if ((segment_stop >= 0) && ((pos + size) > segment_stop)) // weird - return E_FILE_FORMAT_INVALID; - - pos += size; // consume payload of sub-element - if (segment_stop >= 0 && pos > segment_stop) - return E_FILE_FORMAT_INVALID; - } // determine cluster size - - cluster_size = pos - payload_pos; - assert(cluster_size >= 0); // TODO: handle cluster_size = 0 - - pos = payload_pos; // reset and re-parse original cluster - } - - pos += cluster_size; // consume payload - if (segment_stop >= 0 && pos > segment_stop) - return E_FILE_FORMAT_INVALID; - - return 2; // try to find a cluster that follows next -} - -const Cluster* Segment::FindCluster(long long time_ns) const { - if ((m_clusters == NULL) || (m_clusterCount <= 0)) - return &m_eos; - - { - Cluster* const pCluster = m_clusters[0]; - assert(pCluster); - assert(pCluster->m_index == 0); - - if (time_ns <= pCluster->GetTime()) - return pCluster; - } - - // Binary search of cluster array - - long i = 0; - long j = m_clusterCount; - - while (i < j) { - // INVARIANT: - //[0, i) <= time_ns - //[i, j) ? - //[j, m_clusterCount) > time_ns - - const long k = i + (j - i) / 2; - assert(k < m_clusterCount); - - Cluster* const pCluster = m_clusters[k]; - assert(pCluster); - assert(pCluster->m_index == k); - - const long long t = pCluster->GetTime(); - - if (t <= time_ns) - i = k + 1; - else - j = k; - - assert(i <= j); - } - - assert(i == j); - assert(i > 0); - assert(i <= m_clusterCount); - - const long k = i - 1; - - Cluster* const pCluster = m_clusters[k]; - assert(pCluster); - assert(pCluster->m_index == k); - assert(pCluster->GetTime() <= time_ns); - - return pCluster; -} - -const Tracks* Segment::GetTracks() const { return m_pTracks; } -const SegmentInfo* Segment::GetInfo() const { return m_pInfo; } -const Cues* Segment::GetCues() const { return m_pCues; } -const Chapters* Segment::GetChapters() const { return m_pChapters; } -const Tags* Segment::GetTags() const { return m_pTags; } -const SeekHead* Segment::GetSeekHead() const { return m_pSeekHead; } - -long long Segment::GetDuration() const { - assert(m_pInfo); - return m_pInfo->GetDuration(); -} - -Chapters::Chapters(Segment* pSegment, long long payload_start, - long long payload_size, long long element_start, - long long element_size) - : m_pSegment(pSegment), - m_start(payload_start), - m_size(payload_size), - m_element_start(element_start), - m_element_size(element_size), - m_editions(NULL), - m_editions_size(0), - m_editions_count(0) {} - -Chapters::~Chapters() { - while (m_editions_count > 0) { - Edition& e = m_editions[--m_editions_count]; - e.Clear(); - } - delete[] m_editions; -} - -long Chapters::Parse() { - IMkvReader* const pReader = m_pSegment->m_pReader; - - long long pos = m_start; // payload start - const long long stop = pos + m_size; // payload stop - - while (pos < stop) { - long long id, size; - - long status = ParseElementHeader(pReader, pos, stop, id, size); - - if (status < 0) // error - return status; - - if (size == 0) // weird - continue; - - if (id == libwebm::kMkvEditionEntry) { - status = ParseEdition(pos, size); - - if (status < 0) // error - return status; - } - - pos += size; - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - return 0; -} - -int Chapters::GetEditionCount() const { return m_editions_count; } - -const Chapters::Edition* Chapters::GetEdition(int idx) const { - if (idx < 0) - return NULL; - - if (idx >= m_editions_count) - return NULL; - - return m_editions + idx; -} - -bool Chapters::ExpandEditionsArray() { - if (m_editions_size > m_editions_count) - return true; // nothing else to do - - const int size = (m_editions_size == 0) ? 1 : 2 * m_editions_size; - - Edition* const editions = new (std::nothrow) Edition[size]; - - if (editions == NULL) - return false; - - for (int idx = 0; idx < m_editions_count; ++idx) { - m_editions[idx].ShallowCopy(editions[idx]); - } - - delete[] m_editions; - m_editions = editions; - - m_editions_size = size; - return true; -} - -long Chapters::ParseEdition(long long pos, long long size) { - if (!ExpandEditionsArray()) - return -1; - - Edition& e = m_editions[m_editions_count++]; - e.Init(); - - return e.Parse(m_pSegment->m_pReader, pos, size); -} - -Chapters::Edition::Edition() {} - -Chapters::Edition::~Edition() {} - -int Chapters::Edition::GetAtomCount() const { return m_atoms_count; } - -const Chapters::Atom* Chapters::Edition::GetAtom(int index) const { - if (index < 0) - return NULL; - - if (index >= m_atoms_count) - return NULL; - - return m_atoms + index; -} - -void Chapters::Edition::Init() { - m_atoms = NULL; - m_atoms_size = 0; - m_atoms_count = 0; -} - -void Chapters::Edition::ShallowCopy(Edition& rhs) const { - rhs.m_atoms = m_atoms; - rhs.m_atoms_size = m_atoms_size; - rhs.m_atoms_count = m_atoms_count; -} - -void Chapters::Edition::Clear() { - while (m_atoms_count > 0) { - Atom& a = m_atoms[--m_atoms_count]; - a.Clear(); - } - - delete[] m_atoms; - m_atoms = NULL; - - m_atoms_size = 0; -} - -long Chapters::Edition::Parse(IMkvReader* pReader, long long pos, - long long size) { - const long long stop = pos + size; - - while (pos < stop) { - long long id, size; - - long status = ParseElementHeader(pReader, pos, stop, id, size); - - if (status < 0) // error - return status; - - if (size == 0) - continue; - - if (id == libwebm::kMkvChapterAtom) { - status = ParseAtom(pReader, pos, size); - - if (status < 0) // error - return status; - } - - pos += size; - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - return 0; -} - -long Chapters::Edition::ParseAtom(IMkvReader* pReader, long long pos, - long long size) { - if (!ExpandAtomsArray()) - return -1; - - Atom& a = m_atoms[m_atoms_count++]; - a.Init(); - - return a.Parse(pReader, pos, size); -} - -bool Chapters::Edition::ExpandAtomsArray() { - if (m_atoms_size > m_atoms_count) - return true; // nothing else to do - - const int size = (m_atoms_size == 0) ? 1 : 2 * m_atoms_size; - - Atom* const atoms = new (std::nothrow) Atom[size]; - - if (atoms == NULL) - return false; - - for (int idx = 0; idx < m_atoms_count; ++idx) { - m_atoms[idx].ShallowCopy(atoms[idx]); - } - - delete[] m_atoms; - m_atoms = atoms; - - m_atoms_size = size; - return true; -} - -Chapters::Atom::Atom() {} - -Chapters::Atom::~Atom() {} - -unsigned long long Chapters::Atom::GetUID() const { return m_uid; } - -const char* Chapters::Atom::GetStringUID() const { return m_string_uid; } - -long long Chapters::Atom::GetStartTimecode() const { return m_start_timecode; } - -long long Chapters::Atom::GetStopTimecode() const { return m_stop_timecode; } - -long long Chapters::Atom::GetStartTime(const Chapters* pChapters) const { - return GetTime(pChapters, m_start_timecode); -} - -long long Chapters::Atom::GetStopTime(const Chapters* pChapters) const { - return GetTime(pChapters, m_stop_timecode); -} - -int Chapters::Atom::GetDisplayCount() const { return m_displays_count; } - -const Chapters::Display* Chapters::Atom::GetDisplay(int index) const { - if (index < 0) - return NULL; - - if (index >= m_displays_count) - return NULL; - - return m_displays + index; -} - -void Chapters::Atom::Init() { - m_string_uid = NULL; - m_uid = 0; - m_start_timecode = -1; - m_stop_timecode = -1; - - m_displays = NULL; - m_displays_size = 0; - m_displays_count = 0; -} - -void Chapters::Atom::ShallowCopy(Atom& rhs) const { - rhs.m_string_uid = m_string_uid; - rhs.m_uid = m_uid; - rhs.m_start_timecode = m_start_timecode; - rhs.m_stop_timecode = m_stop_timecode; - - rhs.m_displays = m_displays; - rhs.m_displays_size = m_displays_size; - rhs.m_displays_count = m_displays_count; -} - -void Chapters::Atom::Clear() { - delete[] m_string_uid; - m_string_uid = NULL; - - while (m_displays_count > 0) { - Display& d = m_displays[--m_displays_count]; - d.Clear(); - } - - delete[] m_displays; - m_displays = NULL; - - m_displays_size = 0; -} - -long Chapters::Atom::Parse(IMkvReader* pReader, long long pos, long long size) { - const long long stop = pos + size; - - while (pos < stop) { - long long id, size; - - long status = ParseElementHeader(pReader, pos, stop, id, size); - - if (status < 0) // error - return status; - - if (size == 0) // 0 length payload, skip. - continue; - - if (id == libwebm::kMkvChapterDisplay) { - status = ParseDisplay(pReader, pos, size); - - if (status < 0) // error - return status; - } else if (id == libwebm::kMkvChapterStringUID) { - status = UnserializeString(pReader, pos, size, m_string_uid); - - if (status < 0) // error - return status; - } else if (id == libwebm::kMkvChapterUID) { - long long val; - status = UnserializeInt(pReader, pos, size, val); - - if (status < 0) // error - return status; - - m_uid = static_cast(val); - } else if (id == libwebm::kMkvChapterTimeStart) { - const long long val = UnserializeUInt(pReader, pos, size); - - if (val < 0) // error - return static_cast(val); - - m_start_timecode = val; - } else if (id == libwebm::kMkvChapterTimeEnd) { - const long long val = UnserializeUInt(pReader, pos, size); - - if (val < 0) // error - return static_cast(val); - - m_stop_timecode = val; - } - - pos += size; - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - return 0; -} - -long long Chapters::Atom::GetTime(const Chapters* pChapters, - long long timecode) { - if (pChapters == NULL) - return -1; - - Segment* const pSegment = pChapters->m_pSegment; - - if (pSegment == NULL) // weird - return -1; - - const SegmentInfo* const pInfo = pSegment->GetInfo(); - - if (pInfo == NULL) - return -1; - - const long long timecode_scale = pInfo->GetTimeCodeScale(); - - if (timecode_scale < 1) // weird - return -1; - - if (timecode < 0) - return -1; - - const long long result = timecode_scale * timecode; - - return result; -} - -long Chapters::Atom::ParseDisplay(IMkvReader* pReader, long long pos, - long long size) { - if (!ExpandDisplaysArray()) - return -1; - - Display& d = m_displays[m_displays_count++]; - d.Init(); - - return d.Parse(pReader, pos, size); -} - -bool Chapters::Atom::ExpandDisplaysArray() { - if (m_displays_size > m_displays_count) - return true; // nothing else to do - - const int size = (m_displays_size == 0) ? 1 : 2 * m_displays_size; - - Display* const displays = new (std::nothrow) Display[size]; - - if (displays == NULL) - return false; - - for (int idx = 0; idx < m_displays_count; ++idx) { - m_displays[idx].ShallowCopy(displays[idx]); - } - - delete[] m_displays; - m_displays = displays; - - m_displays_size = size; - return true; -} - -Chapters::Display::Display() {} - -Chapters::Display::~Display() {} - -const char* Chapters::Display::GetString() const { return m_string; } - -const char* Chapters::Display::GetLanguage() const { return m_language; } - -const char* Chapters::Display::GetCountry() const { return m_country; } - -void Chapters::Display::Init() { - m_string = NULL; - m_language = NULL; - m_country = NULL; -} - -void Chapters::Display::ShallowCopy(Display& rhs) const { - rhs.m_string = m_string; - rhs.m_language = m_language; - rhs.m_country = m_country; -} - -void Chapters::Display::Clear() { - delete[] m_string; - m_string = NULL; - - delete[] m_language; - m_language = NULL; - - delete[] m_country; - m_country = NULL; -} - -long Chapters::Display::Parse(IMkvReader* pReader, long long pos, - long long size) { - const long long stop = pos + size; - - while (pos < stop) { - long long id, size; - - long status = ParseElementHeader(pReader, pos, stop, id, size); - - if (status < 0) // error - return status; - - if (size == 0) // No payload. - continue; - - if (id == libwebm::kMkvChapString) { - status = UnserializeString(pReader, pos, size, m_string); - - if (status) - return status; - } else if (id == libwebm::kMkvChapLanguage) { - status = UnserializeString(pReader, pos, size, m_language); - - if (status) - return status; - } else if (id == libwebm::kMkvChapCountry) { - status = UnserializeString(pReader, pos, size, m_country); - - if (status) - return status; - } - - pos += size; - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - return 0; -} - -Tags::Tags(Segment* pSegment, long long payload_start, long long payload_size, - long long element_start, long long element_size) - : m_pSegment(pSegment), - m_start(payload_start), - m_size(payload_size), - m_element_start(element_start), - m_element_size(element_size), - m_tags(NULL), - m_tags_size(0), - m_tags_count(0) {} - -Tags::~Tags() { - while (m_tags_count > 0) { - Tag& t = m_tags[--m_tags_count]; - t.Clear(); - } - delete[] m_tags; -} - -long Tags::Parse() { - IMkvReader* const pReader = m_pSegment->m_pReader; - - long long pos = m_start; // payload start - const long long stop = pos + m_size; // payload stop - - while (pos < stop) { - long long id, size; - - long status = ParseElementHeader(pReader, pos, stop, id, size); - - if (status < 0) - return status; - - if (size == 0) // 0 length tag, read another - continue; - - if (id == libwebm::kMkvTag) { - status = ParseTag(pos, size); - - if (status < 0) - return status; - } - - pos += size; - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - - return 0; -} - -int Tags::GetTagCount() const { return m_tags_count; } - -const Tags::Tag* Tags::GetTag(int idx) const { - if (idx < 0) - return NULL; - - if (idx >= m_tags_count) - return NULL; - - return m_tags + idx; -} - -bool Tags::ExpandTagsArray() { - if (m_tags_size > m_tags_count) - return true; // nothing else to do - - const int size = (m_tags_size == 0) ? 1 : 2 * m_tags_size; - - Tag* const tags = new (std::nothrow) Tag[size]; - - if (tags == NULL) - return false; - - for (int idx = 0; idx < m_tags_count; ++idx) { - m_tags[idx].ShallowCopy(tags[idx]); - } - - delete[] m_tags; - m_tags = tags; - - m_tags_size = size; - return true; -} - -long Tags::ParseTag(long long pos, long long size) { - if (!ExpandTagsArray()) - return -1; - - Tag& t = m_tags[m_tags_count++]; - t.Init(); - - return t.Parse(m_pSegment->m_pReader, pos, size); -} - -Tags::Tag::Tag() {} - -Tags::Tag::~Tag() {} - -int Tags::Tag::GetSimpleTagCount() const { return m_simple_tags_count; } - -const Tags::SimpleTag* Tags::Tag::GetSimpleTag(int index) const { - if (index < 0) - return NULL; - - if (index >= m_simple_tags_count) - return NULL; - - return m_simple_tags + index; -} - -void Tags::Tag::Init() { - m_simple_tags = NULL; - m_simple_tags_size = 0; - m_simple_tags_count = 0; -} - -void Tags::Tag::ShallowCopy(Tag& rhs) const { - rhs.m_simple_tags = m_simple_tags; - rhs.m_simple_tags_size = m_simple_tags_size; - rhs.m_simple_tags_count = m_simple_tags_count; -} - -void Tags::Tag::Clear() { - while (m_simple_tags_count > 0) { - SimpleTag& d = m_simple_tags[--m_simple_tags_count]; - d.Clear(); - } - - delete[] m_simple_tags; - m_simple_tags = NULL; - - m_simple_tags_size = 0; -} - -long Tags::Tag::Parse(IMkvReader* pReader, long long pos, long long size) { - const long long stop = pos + size; - - while (pos < stop) { - long long id, size; - - long status = ParseElementHeader(pReader, pos, stop, id, size); - - if (status < 0) - return status; - - if (size == 0) // 0 length tag, read another - continue; - - if (id == libwebm::kMkvSimpleTag) { - status = ParseSimpleTag(pReader, pos, size); - - if (status < 0) - return status; - } - - pos += size; - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - return 0; -} - -long Tags::Tag::ParseSimpleTag(IMkvReader* pReader, long long pos, - long long size) { - if (!ExpandSimpleTagsArray()) - return -1; - - SimpleTag& st = m_simple_tags[m_simple_tags_count++]; - st.Init(); - - return st.Parse(pReader, pos, size); -} - -bool Tags::Tag::ExpandSimpleTagsArray() { - if (m_simple_tags_size > m_simple_tags_count) - return true; // nothing else to do - - const int size = (m_simple_tags_size == 0) ? 1 : 2 * m_simple_tags_size; - - SimpleTag* const displays = new (std::nothrow) SimpleTag[size]; - - if (displays == NULL) - return false; - - for (int idx = 0; idx < m_simple_tags_count; ++idx) { - m_simple_tags[idx].ShallowCopy(displays[idx]); - } - - delete[] m_simple_tags; - m_simple_tags = displays; - - m_simple_tags_size = size; - return true; -} - -Tags::SimpleTag::SimpleTag() {} - -Tags::SimpleTag::~SimpleTag() {} - -const char* Tags::SimpleTag::GetTagName() const { return m_tag_name; } - -const char* Tags::SimpleTag::GetTagString() const { return m_tag_string; } - -void Tags::SimpleTag::Init() { - m_tag_name = NULL; - m_tag_string = NULL; -} - -void Tags::SimpleTag::ShallowCopy(SimpleTag& rhs) const { - rhs.m_tag_name = m_tag_name; - rhs.m_tag_string = m_tag_string; -} - -void Tags::SimpleTag::Clear() { - delete[] m_tag_name; - m_tag_name = NULL; - - delete[] m_tag_string; - m_tag_string = NULL; -} - -long Tags::SimpleTag::Parse(IMkvReader* pReader, long long pos, - long long size) { - const long long stop = pos + size; - - while (pos < stop) { - long long id, size; - - long status = ParseElementHeader(pReader, pos, stop, id, size); - - if (status < 0) // error - return status; - - if (size == 0) // weird - continue; - - if (id == libwebm::kMkvTagName) { - status = UnserializeString(pReader, pos, size, m_tag_name); - - if (status) - return status; - } else if (id == libwebm::kMkvTagString) { - status = UnserializeString(pReader, pos, size, m_tag_string); - - if (status) - return status; - } - - pos += size; - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - return 0; -} - -SegmentInfo::SegmentInfo(Segment* pSegment, long long start, long long size_, - long long element_start, long long element_size) - : m_pSegment(pSegment), - m_start(start), - m_size(size_), - m_element_start(element_start), - m_element_size(element_size), - m_pMuxingAppAsUTF8(NULL), - m_pWritingAppAsUTF8(NULL), - m_pTitleAsUTF8(NULL) {} - -SegmentInfo::~SegmentInfo() { - delete[] m_pMuxingAppAsUTF8; - m_pMuxingAppAsUTF8 = NULL; - - delete[] m_pWritingAppAsUTF8; - m_pWritingAppAsUTF8 = NULL; - - delete[] m_pTitleAsUTF8; - m_pTitleAsUTF8 = NULL; -} - -long SegmentInfo::Parse() { - assert(m_pMuxingAppAsUTF8 == NULL); - assert(m_pWritingAppAsUTF8 == NULL); - assert(m_pTitleAsUTF8 == NULL); - - IMkvReader* const pReader = m_pSegment->m_pReader; - - long long pos = m_start; - const long long stop = m_start + m_size; - - m_timecodeScale = 1000000; - m_duration = -1; - - while (pos < stop) { - long long id, size; - - const long status = ParseElementHeader(pReader, pos, stop, id, size); - - if (status < 0) // error - return status; - - if (id == libwebm::kMkvTimecodeScale) { - m_timecodeScale = UnserializeUInt(pReader, pos, size); - - if (m_timecodeScale <= 0) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvDuration) { - const long status = UnserializeFloat(pReader, pos, size, m_duration); - - if (status < 0) - return status; - - if (m_duration < 0) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvMuxingApp) { - const long status = - UnserializeString(pReader, pos, size, m_pMuxingAppAsUTF8); - - if (status) - return status; - } else if (id == libwebm::kMkvWritingApp) { - const long status = - UnserializeString(pReader, pos, size, m_pWritingAppAsUTF8); - - if (status) - return status; - } else if (id == libwebm::kMkvTitle) { - const long status = UnserializeString(pReader, pos, size, m_pTitleAsUTF8); - - if (status) - return status; - } - - pos += size; - - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - const double rollover_check = m_duration * m_timecodeScale; - if (rollover_check > static_cast(LLONG_MAX)) - return E_FILE_FORMAT_INVALID; - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - - return 0; -} - -long long SegmentInfo::GetTimeCodeScale() const { return m_timecodeScale; } - -long long SegmentInfo::GetDuration() const { - if (m_duration < 0) - return -1; - - assert(m_timecodeScale >= 1); - - const double dd = double(m_duration) * double(m_timecodeScale); - const long long d = static_cast(dd); - - return d; -} - -const char* SegmentInfo::GetMuxingAppAsUTF8() const { - return m_pMuxingAppAsUTF8; -} - -const char* SegmentInfo::GetWritingAppAsUTF8() const { - return m_pWritingAppAsUTF8; -} - -const char* SegmentInfo::GetTitleAsUTF8() const { return m_pTitleAsUTF8; } - -/////////////////////////////////////////////////////////////// -// ContentEncoding element -ContentEncoding::ContentCompression::ContentCompression() - : algo(0), settings(NULL), settings_len(0) {} - -ContentEncoding::ContentCompression::~ContentCompression() { - delete[] settings; -} - -ContentEncoding::ContentEncryption::ContentEncryption() - : algo(0), - key_id(NULL), - key_id_len(0), - signature(NULL), - signature_len(0), - sig_key_id(NULL), - sig_key_id_len(0), - sig_algo(0), - sig_hash_algo(0) {} - -ContentEncoding::ContentEncryption::~ContentEncryption() { - delete[] key_id; - delete[] signature; - delete[] sig_key_id; -} - -ContentEncoding::ContentEncoding() - : compression_entries_(NULL), - compression_entries_end_(NULL), - encryption_entries_(NULL), - encryption_entries_end_(NULL), - encoding_order_(0), - encoding_scope_(1), - encoding_type_(0) {} - -ContentEncoding::~ContentEncoding() { - ContentCompression** comp_i = compression_entries_; - ContentCompression** const comp_j = compression_entries_end_; - - while (comp_i != comp_j) { - ContentCompression* const comp = *comp_i++; - delete comp; - } - - delete[] compression_entries_; - - ContentEncryption** enc_i = encryption_entries_; - ContentEncryption** const enc_j = encryption_entries_end_; - - while (enc_i != enc_j) { - ContentEncryption* const enc = *enc_i++; - delete enc; - } - - delete[] encryption_entries_; -} - -const ContentEncoding::ContentCompression* -ContentEncoding::GetCompressionByIndex(unsigned long idx) const { - const ptrdiff_t count = compression_entries_end_ - compression_entries_; - assert(count >= 0); - - if (idx >= static_cast(count)) - return NULL; - - return compression_entries_[idx]; -} - -unsigned long ContentEncoding::GetCompressionCount() const { - const ptrdiff_t count = compression_entries_end_ - compression_entries_; - assert(count >= 0); - - return static_cast(count); -} - -const ContentEncoding::ContentEncryption* ContentEncoding::GetEncryptionByIndex( - unsigned long idx) const { - const ptrdiff_t count = encryption_entries_end_ - encryption_entries_; - assert(count >= 0); - - if (idx >= static_cast(count)) - return NULL; - - return encryption_entries_[idx]; -} - -unsigned long ContentEncoding::GetEncryptionCount() const { - const ptrdiff_t count = encryption_entries_end_ - encryption_entries_; - assert(count >= 0); - - return static_cast(count); -} - -long ContentEncoding::ParseContentEncAESSettingsEntry( - long long start, long long size, IMkvReader* pReader, - ContentEncAESSettings* aes) { - assert(pReader); - assert(aes); - - long long pos = start; - const long long stop = start + size; - - while (pos < stop) { - long long id, size; - const long status = ParseElementHeader(pReader, pos, stop, id, size); - if (status < 0) // error - return status; - - if (id == libwebm::kMkvAESSettingsCipherMode) { - aes->cipher_mode = UnserializeUInt(pReader, pos, size); - if (aes->cipher_mode != 1) - return E_FILE_FORMAT_INVALID; - } - - pos += size; // consume payload - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - return 0; -} - -long ContentEncoding::ParseContentEncodingEntry(long long start, long long size, - IMkvReader* pReader) { - assert(pReader); - - long long pos = start; - const long long stop = start + size; - - // Count ContentCompression and ContentEncryption elements. - long long compression_count = 0; - long long encryption_count = 0; - - while (pos < stop) { - long long id, size; - const long status = ParseElementHeader(pReader, pos, stop, id, size); - if (status < 0) // error - return status; - - if (id == libwebm::kMkvContentCompression) { - ++compression_count; - if (compression_count > INT_MAX) - return E_PARSE_FAILED; - } - - if (id == libwebm::kMkvContentEncryption) { - ++encryption_count; - if (encryption_count > INT_MAX) - return E_PARSE_FAILED; - } - - pos += size; // consume payload - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - if (compression_count <= 0 && encryption_count <= 0) - return -1; - - if (compression_count > 0) { - compression_entries_ = new (std::nothrow) - ContentCompression*[static_cast(compression_count)]; - if (!compression_entries_) - return -1; - compression_entries_end_ = compression_entries_; - } - - if (encryption_count > 0) { - encryption_entries_ = new (std::nothrow) - ContentEncryption*[static_cast(encryption_count)]; - if (!encryption_entries_) { - delete[] compression_entries_; - compression_entries_ = NULL; - return -1; - } - encryption_entries_end_ = encryption_entries_; - } - - pos = start; - while (pos < stop) { - long long id, size; - long status = ParseElementHeader(pReader, pos, stop, id, size); - if (status < 0) // error - return status; - - if (id == libwebm::kMkvContentEncodingOrder) { - encoding_order_ = UnserializeUInt(pReader, pos, size); - } else if (id == libwebm::kMkvContentEncodingScope) { - encoding_scope_ = UnserializeUInt(pReader, pos, size); - if (encoding_scope_ < 1) - return -1; - } else if (id == libwebm::kMkvContentEncodingType) { - encoding_type_ = UnserializeUInt(pReader, pos, size); - } else if (id == libwebm::kMkvContentCompression) { - ContentCompression* const compression = - new (std::nothrow) ContentCompression(); - if (!compression) - return -1; - - status = ParseCompressionEntry(pos, size, pReader, compression); - if (status) { - delete compression; - return status; - } - assert(compression_count > 0); - *compression_entries_end_++ = compression; - } else if (id == libwebm::kMkvContentEncryption) { - ContentEncryption* const encryption = - new (std::nothrow) ContentEncryption(); - if (!encryption) - return -1; - - status = ParseEncryptionEntry(pos, size, pReader, encryption); - if (status) { - delete encryption; - return status; - } - assert(encryption_count > 0); - *encryption_entries_end_++ = encryption; - } - - pos += size; // consume payload - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - return 0; -} - -long ContentEncoding::ParseCompressionEntry(long long start, long long size, - IMkvReader* pReader, - ContentCompression* compression) { - assert(pReader); - assert(compression); - - long long pos = start; - const long long stop = start + size; - - bool valid = false; - - while (pos < stop) { - long long id, size; - const long status = ParseElementHeader(pReader, pos, stop, id, size); - if (status < 0) // error - return status; - - if (id == libwebm::kMkvContentCompAlgo) { - long long algo = UnserializeUInt(pReader, pos, size); - if (algo < 0) - return E_FILE_FORMAT_INVALID; - compression->algo = algo; - valid = true; - } else if (id == libwebm::kMkvContentCompSettings) { - if (size <= 0) - return E_FILE_FORMAT_INVALID; - - const size_t buflen = static_cast(size); - unsigned char* buf = SafeArrayAlloc(1, buflen); - if (buf == NULL) - return -1; - - const int read_status = - pReader->Read(pos, static_cast(buflen), buf); - if (read_status) { - delete[] buf; - return status; - } - - // There should be only one settings element per content compression. - if (compression->settings != NULL) { - delete[] buf; - return E_FILE_FORMAT_INVALID; - } - - compression->settings = buf; - compression->settings_len = buflen; - } - - pos += size; // consume payload - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - // ContentCompAlgo is mandatory - if (!valid) - return E_FILE_FORMAT_INVALID; - - return 0; -} - -long ContentEncoding::ParseEncryptionEntry(long long start, long long size, - IMkvReader* pReader, - ContentEncryption* encryption) { - assert(pReader); - assert(encryption); - - long long pos = start; - const long long stop = start + size; - - while (pos < stop) { - long long id, size; - const long status = ParseElementHeader(pReader, pos, stop, id, size); - if (status < 0) // error - return status; - - if (id == libwebm::kMkvContentEncAlgo) { - encryption->algo = UnserializeUInt(pReader, pos, size); - if (encryption->algo != 5) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvContentEncKeyID) { - delete[] encryption->key_id; - encryption->key_id = NULL; - encryption->key_id_len = 0; - - if (size <= 0) - return E_FILE_FORMAT_INVALID; - - const size_t buflen = static_cast(size); - unsigned char* buf = SafeArrayAlloc(1, buflen); - if (buf == NULL) - return -1; - - const int read_status = - pReader->Read(pos, static_cast(buflen), buf); - if (read_status) { - delete[] buf; - return status; - } - - encryption->key_id = buf; - encryption->key_id_len = buflen; - } else if (id == libwebm::kMkvContentSignature) { - delete[] encryption->signature; - encryption->signature = NULL; - encryption->signature_len = 0; - - if (size <= 0) - return E_FILE_FORMAT_INVALID; - - const size_t buflen = static_cast(size); - unsigned char* buf = SafeArrayAlloc(1, buflen); - if (buf == NULL) - return -1; - - const int read_status = - pReader->Read(pos, static_cast(buflen), buf); - if (read_status) { - delete[] buf; - return status; - } - - encryption->signature = buf; - encryption->signature_len = buflen; - } else if (id == libwebm::kMkvContentSigKeyID) { - delete[] encryption->sig_key_id; - encryption->sig_key_id = NULL; - encryption->sig_key_id_len = 0; - - if (size <= 0) - return E_FILE_FORMAT_INVALID; - - const size_t buflen = static_cast(size); - unsigned char* buf = SafeArrayAlloc(1, buflen); - if (buf == NULL) - return -1; - - const int read_status = - pReader->Read(pos, static_cast(buflen), buf); - if (read_status) { - delete[] buf; - return status; - } - - encryption->sig_key_id = buf; - encryption->sig_key_id_len = buflen; - } else if (id == libwebm::kMkvContentSigAlgo) { - encryption->sig_algo = UnserializeUInt(pReader, pos, size); - } else if (id == libwebm::kMkvContentSigHashAlgo) { - encryption->sig_hash_algo = UnserializeUInt(pReader, pos, size); - } else if (id == libwebm::kMkvContentEncAESSettings) { - const long status = ParseContentEncAESSettingsEntry( - pos, size, pReader, &encryption->aes_settings); - if (status) - return status; - } - - pos += size; // consume payload - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - return 0; -} - -Track::Track(Segment* pSegment, long long element_start, long long element_size) - : m_pSegment(pSegment), - m_element_start(element_start), - m_element_size(element_size), - content_encoding_entries_(NULL), - content_encoding_entries_end_(NULL) {} - -Track::~Track() { - Info& info = const_cast(m_info); - info.Clear(); - - ContentEncoding** i = content_encoding_entries_; - ContentEncoding** const j = content_encoding_entries_end_; - - while (i != j) { - ContentEncoding* const encoding = *i++; - delete encoding; - } - - delete[] content_encoding_entries_; -} - -long Track::Create(Segment* pSegment, const Info& info, long long element_start, - long long element_size, Track*& pResult) { - if (pResult) - return -1; - - Track* const pTrack = - new (std::nothrow) Track(pSegment, element_start, element_size); - - if (pTrack == NULL) - return -1; // generic error - - const int status = info.Copy(pTrack->m_info); - - if (status) { // error - delete pTrack; - return status; - } - - pResult = pTrack; - return 0; // success -} - -Track::Info::Info() - : uid(0), - defaultDuration(0), - codecDelay(0), - seekPreRoll(0), - nameAsUTF8(NULL), - language(NULL), - codecId(NULL), - codecNameAsUTF8(NULL), - codecPrivate(NULL), - codecPrivateSize(0), - lacing(false) {} - -Track::Info::~Info() { Clear(); } - -void Track::Info::Clear() { - delete[] nameAsUTF8; - nameAsUTF8 = NULL; - - delete[] language; - language = NULL; - - delete[] codecId; - codecId = NULL; - - delete[] codecPrivate; - codecPrivate = NULL; - codecPrivateSize = 0; - - delete[] codecNameAsUTF8; - codecNameAsUTF8 = NULL; -} - -int Track::Info::CopyStr(char* Info::*str, Info& dst_) const { - if (str == static_cast(NULL)) - return -1; - - char*& dst = dst_.*str; - - if (dst) // should be NULL already - return -1; - - const char* const src = this->*str; - - if (src == NULL) - return 0; - - const size_t len = strlen(src); - - dst = SafeArrayAlloc(1, len + 1); - - if (dst == NULL) - return -1; - - memcpy(dst, src, len); - dst[len] = '\0'; - - return 0; -} - -int Track::Info::Copy(Info& dst) const { - if (&dst == this) - return 0; - - dst.type = type; - dst.number = number; - dst.defaultDuration = defaultDuration; - dst.codecDelay = codecDelay; - dst.seekPreRoll = seekPreRoll; - dst.uid = uid; - dst.lacing = lacing; - dst.settings = settings; - - // We now copy the string member variables from src to dst. - // This involves memory allocation so in principle the operation - // can fail (indeed, that's why we have Info::Copy), so we must - // report this to the caller. An error return from this function - // therefore implies that the copy was only partially successful. - - if (int status = CopyStr(&Info::nameAsUTF8, dst)) - return status; - - if (int status = CopyStr(&Info::language, dst)) - return status; - - if (int status = CopyStr(&Info::codecId, dst)) - return status; - - if (int status = CopyStr(&Info::codecNameAsUTF8, dst)) - return status; - - if (codecPrivateSize > 0) { - if (codecPrivate == NULL) - return -1; - - if (dst.codecPrivate) - return -1; - - if (dst.codecPrivateSize != 0) - return -1; - - dst.codecPrivate = SafeArrayAlloc(1, codecPrivateSize); - - if (dst.codecPrivate == NULL) - return -1; - - memcpy(dst.codecPrivate, codecPrivate, codecPrivateSize); - dst.codecPrivateSize = codecPrivateSize; - } - - return 0; -} - -const BlockEntry* Track::GetEOS() const { return &m_eos; } - -long Track::GetType() const { return m_info.type; } - -long Track::GetNumber() const { return m_info.number; } - -unsigned long long Track::GetUid() const { return m_info.uid; } - -const char* Track::GetNameAsUTF8() const { return m_info.nameAsUTF8; } - -const char* Track::GetLanguage() const { return m_info.language; } - -const char* Track::GetCodecNameAsUTF8() const { return m_info.codecNameAsUTF8; } - -const char* Track::GetCodecId() const { return m_info.codecId; } - -const unsigned char* Track::GetCodecPrivate(size_t& size) const { - size = m_info.codecPrivateSize; - return m_info.codecPrivate; -} - -bool Track::GetLacing() const { return m_info.lacing; } - -unsigned long long Track::GetDefaultDuration() const { - return m_info.defaultDuration; -} - -unsigned long long Track::GetCodecDelay() const { return m_info.codecDelay; } - -unsigned long long Track::GetSeekPreRoll() const { return m_info.seekPreRoll; } - -long Track::GetFirst(const BlockEntry*& pBlockEntry) const { - const Cluster* pCluster = m_pSegment->GetFirst(); - - for (int i = 0;;) { - if (pCluster == NULL) { - pBlockEntry = GetEOS(); - return 1; - } - - if (pCluster->EOS()) { - if (m_pSegment->DoneParsing()) { - pBlockEntry = GetEOS(); - return 1; - } - - pBlockEntry = 0; - return E_BUFFER_NOT_FULL; - } - - long status = pCluster->GetFirst(pBlockEntry); - - if (status < 0) // error - return status; - - if (pBlockEntry == 0) { // empty cluster - pCluster = m_pSegment->GetNext(pCluster); - continue; - } - - for (;;) { - const Block* const pBlock = pBlockEntry->GetBlock(); - assert(pBlock); - - const long long tn = pBlock->GetTrackNumber(); - - if ((tn == m_info.number) && VetEntry(pBlockEntry)) - return 0; - - const BlockEntry* pNextEntry; - - status = pCluster->GetNext(pBlockEntry, pNextEntry); - - if (status < 0) // error - return status; - - if (pNextEntry == 0) - break; - - pBlockEntry = pNextEntry; - } - - ++i; - - if (i >= 100) - break; - - pCluster = m_pSegment->GetNext(pCluster); - } - - // NOTE: if we get here, it means that we didn't find a block with - // a matching track number. We interpret that as an error (which - // might be too conservative). - - pBlockEntry = GetEOS(); // so we can return a non-NULL value - return 1; -} - -long Track::GetNext(const BlockEntry* pCurrEntry, - const BlockEntry*& pNextEntry) const { - assert(pCurrEntry); - assert(!pCurrEntry->EOS()); //? - - const Block* const pCurrBlock = pCurrEntry->GetBlock(); - assert(pCurrBlock && pCurrBlock->GetTrackNumber() == m_info.number); - if (!pCurrBlock || pCurrBlock->GetTrackNumber() != m_info.number) - return -1; - - const Cluster* pCluster = pCurrEntry->GetCluster(); - assert(pCluster); - assert(!pCluster->EOS()); - - long status = pCluster->GetNext(pCurrEntry, pNextEntry); - - if (status < 0) // error - return status; - - for (int i = 0;;) { - while (pNextEntry) { - const Block* const pNextBlock = pNextEntry->GetBlock(); - assert(pNextBlock); - - if (pNextBlock->GetTrackNumber() == m_info.number) - return 0; - - pCurrEntry = pNextEntry; - - status = pCluster->GetNext(pCurrEntry, pNextEntry); - - if (status < 0) // error - return status; - } - - pCluster = m_pSegment->GetNext(pCluster); - - if (pCluster == NULL) { - pNextEntry = GetEOS(); - return 1; - } - - if (pCluster->EOS()) { - if (m_pSegment->DoneParsing()) { - pNextEntry = GetEOS(); - return 1; - } - - // TODO: there is a potential O(n^2) problem here: we tell the - // caller to (pre)load another cluster, which he does, but then he - // calls GetNext again, which repeats the same search. This is - // a pathological case, since the only way it can happen is if - // there exists a long sequence of clusters none of which contain a - // block from this track. One way around this problem is for the - // caller to be smarter when he loads another cluster: don't call - // us back until you have a cluster that contains a block from this - // track. (Of course, that's not cheap either, since our caller - // would have to scan the each cluster as it's loaded, so that - // would just push back the problem.) - - pNextEntry = NULL; - return E_BUFFER_NOT_FULL; - } - - status = pCluster->GetFirst(pNextEntry); - - if (status < 0) // error - return status; - - if (pNextEntry == NULL) // empty cluster - continue; - - ++i; - - if (i >= 100) - break; - } - - // NOTE: if we get here, it means that we didn't find a block with - // a matching track number after lots of searching, so we give - // up trying. - - pNextEntry = GetEOS(); // so we can return a non-NULL value - return 1; -} - -bool Track::VetEntry(const BlockEntry* pBlockEntry) const { - assert(pBlockEntry); - const Block* const pBlock = pBlockEntry->GetBlock(); - assert(pBlock); - assert(pBlock->GetTrackNumber() == m_info.number); - if (!pBlock || pBlock->GetTrackNumber() != m_info.number) - return false; - - // This function is used during a seek to determine whether the - // frame is a valid seek target. This default function simply - // returns true, which means all frames are valid seek targets. - // It gets overridden by the VideoTrack class, because only video - // keyframes can be used as seek target. - - return true; -} - -long Track::Seek(long long time_ns, const BlockEntry*& pResult) const { - const long status = GetFirst(pResult); - - if (status < 0) // buffer underflow, etc - return status; - - assert(pResult); - - if (pResult->EOS()) - return 0; - - const Cluster* pCluster = pResult->GetCluster(); - assert(pCluster); - assert(pCluster->GetIndex() >= 0); - - if (time_ns <= pResult->GetBlock()->GetTime(pCluster)) - return 0; - - Cluster** const clusters = m_pSegment->m_clusters; - assert(clusters); - - const long count = m_pSegment->GetCount(); // loaded only, not preloaded - assert(count > 0); - - Cluster** const i = clusters + pCluster->GetIndex(); - assert(i); - assert(*i == pCluster); - assert(pCluster->GetTime() <= time_ns); - - Cluster** const j = clusters + count; - - Cluster** lo = i; - Cluster** hi = j; - - while (lo < hi) { - // INVARIANT: - //[i, lo) <= time_ns - //[lo, hi) ? - //[hi, j) > time_ns - - Cluster** const mid = lo + (hi - lo) / 2; - assert(mid < hi); - - pCluster = *mid; - assert(pCluster); - assert(pCluster->GetIndex() >= 0); - assert(pCluster->GetIndex() == long(mid - m_pSegment->m_clusters)); - - const long long t = pCluster->GetTime(); - - if (t <= time_ns) - lo = mid + 1; - else - hi = mid; - - assert(lo <= hi); - } - - assert(lo == hi); - assert(lo > i); - assert(lo <= j); - - while (lo > i) { - pCluster = *--lo; - assert(pCluster); - assert(pCluster->GetTime() <= time_ns); - - pResult = pCluster->GetEntry(this); - - if ((pResult != 0) && !pResult->EOS()) - return 0; - - // landed on empty cluster (no entries) - } - - pResult = GetEOS(); // weird - return 0; -} - -const ContentEncoding* Track::GetContentEncodingByIndex( - unsigned long idx) const { - const ptrdiff_t count = - content_encoding_entries_end_ - content_encoding_entries_; - assert(count >= 0); - - if (idx >= static_cast(count)) - return NULL; - - return content_encoding_entries_[idx]; -} - -unsigned long Track::GetContentEncodingCount() const { - const ptrdiff_t count = - content_encoding_entries_end_ - content_encoding_entries_; - assert(count >= 0); - - return static_cast(count); -} - -long Track::ParseContentEncodingsEntry(long long start, long long size) { - IMkvReader* const pReader = m_pSegment->m_pReader; - assert(pReader); - - long long pos = start; - const long long stop = start + size; - - // Count ContentEncoding elements. - long long count = 0; - while (pos < stop) { - long long id, size; - const long status = ParseElementHeader(pReader, pos, stop, id, size); - if (status < 0) // error - return status; - - // pos now designates start of element - if (id == libwebm::kMkvContentEncoding) { - ++count; - if (count > INT_MAX) - return E_PARSE_FAILED; - } - - pos += size; // consume payload - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - if (count <= 0) - return -1; - - content_encoding_entries_ = - new (std::nothrow) ContentEncoding*[static_cast(count)]; - if (!content_encoding_entries_) - return -1; - - content_encoding_entries_end_ = content_encoding_entries_; - - pos = start; - while (pos < stop) { - long long id, size; - long status = ParseElementHeader(pReader, pos, stop, id, size); - if (status < 0) // error - return status; - - // pos now designates start of element - if (id == libwebm::kMkvContentEncoding) { - ContentEncoding* const content_encoding = - new (std::nothrow) ContentEncoding(); - if (!content_encoding) - return -1; - - status = content_encoding->ParseContentEncodingEntry(pos, size, pReader); - if (status) { - delete content_encoding; - return status; - } - - *content_encoding_entries_end_++ = content_encoding; - } - - pos += size; // consume payload - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - - return 0; -} - -Track::EOSBlock::EOSBlock() : BlockEntry(NULL, LONG_MIN) {} - -BlockEntry::Kind Track::EOSBlock::GetKind() const { return kBlockEOS; } - -const Block* Track::EOSBlock::GetBlock() const { return NULL; } - -bool PrimaryChromaticity::Parse(IMkvReader* reader, long long read_pos, - long long value_size, bool is_x, - PrimaryChromaticity** chromaticity) { - if (!reader) - return false; - - if (!*chromaticity) - *chromaticity = new PrimaryChromaticity(); - - if (!*chromaticity) - return false; - - PrimaryChromaticity* pc = *chromaticity; - float* value = is_x ? &pc->x : &pc->y; - - double parser_value = 0; - const long long parse_status = - UnserializeFloat(reader, read_pos, value_size, parser_value); - - // Valid range is [0, 1]. Make sure the double is representable as a float - // before casting. - if (parse_status < 0 || parser_value < 0.0 || parser_value > 1.0 || - (parser_value > 0.0 && parser_value < FLT_MIN)) - return false; - - *value = static_cast(parser_value); - - return true; -} - -bool MasteringMetadata::Parse(IMkvReader* reader, long long mm_start, - long long mm_size, MasteringMetadata** mm) { - if (!reader || *mm) - return false; - - std::unique_ptr mm_ptr(new MasteringMetadata()); - if (!mm_ptr.get()) - return false; - - const long long mm_end = mm_start + mm_size; - long long read_pos = mm_start; - - while (read_pos < mm_end) { - long long child_id = 0; - long long child_size = 0; - - const long long status = - ParseElementHeader(reader, read_pos, mm_end, child_id, child_size); - if (status < 0) - return false; - - if (child_id == libwebm::kMkvLuminanceMax) { - double value = 0; - const long long value_parse_status = - UnserializeFloat(reader, read_pos, child_size, value); - if (value < -FLT_MAX || value > FLT_MAX || - (value > 0.0 && value < FLT_MIN)) { - return false; - } - mm_ptr->luminance_max = static_cast(value); - if (value_parse_status < 0 || mm_ptr->luminance_max < 0.0 || - mm_ptr->luminance_max > 9999.99) { - return false; - } - } else if (child_id == libwebm::kMkvLuminanceMin) { - double value = 0; - const long long value_parse_status = - UnserializeFloat(reader, read_pos, child_size, value); - if (value < -FLT_MAX || value > FLT_MAX || - (value > 0.0 && value < FLT_MIN)) { - return false; - } - mm_ptr->luminance_min = static_cast(value); - if (value_parse_status < 0 || mm_ptr->luminance_min < 0.0 || - mm_ptr->luminance_min > 999.9999) { - return false; - } - } else { - bool is_x = false; - PrimaryChromaticity** chromaticity; - switch (child_id) { - case libwebm::kMkvPrimaryRChromaticityX: - case libwebm::kMkvPrimaryRChromaticityY: - is_x = child_id == libwebm::kMkvPrimaryRChromaticityX; - chromaticity = &mm_ptr->r; - break; - case libwebm::kMkvPrimaryGChromaticityX: - case libwebm::kMkvPrimaryGChromaticityY: - is_x = child_id == libwebm::kMkvPrimaryGChromaticityX; - chromaticity = &mm_ptr->g; - break; - case libwebm::kMkvPrimaryBChromaticityX: - case libwebm::kMkvPrimaryBChromaticityY: - is_x = child_id == libwebm::kMkvPrimaryBChromaticityX; - chromaticity = &mm_ptr->b; - break; - case libwebm::kMkvWhitePointChromaticityX: - case libwebm::kMkvWhitePointChromaticityY: - is_x = child_id == libwebm::kMkvWhitePointChromaticityX; - chromaticity = &mm_ptr->white_point; - break; - default: - return false; - } - const bool value_parse_status = PrimaryChromaticity::Parse( - reader, read_pos, child_size, is_x, chromaticity); - if (!value_parse_status) - return false; - } - - read_pos += child_size; - if (read_pos > mm_end) - return false; - } - - *mm = mm_ptr.release(); - return true; -} - -bool Colour::Parse(IMkvReader* reader, long long colour_start, - long long colour_size, Colour** colour) { - if (!reader || *colour) - return false; - - std::unique_ptr colour_ptr(new Colour()); - if (!colour_ptr.get()) - return false; - - const long long colour_end = colour_start + colour_size; - long long read_pos = colour_start; - - while (read_pos < colour_end) { - long long child_id = 0; - long long child_size = 0; - - const long status = - ParseElementHeader(reader, read_pos, colour_end, child_id, child_size); - if (status < 0) - return false; - - if (child_id == libwebm::kMkvMatrixCoefficients) { - colour_ptr->matrix_coefficients = - UnserializeUInt(reader, read_pos, child_size); - if (colour_ptr->matrix_coefficients < 0) - return false; - } else if (child_id == libwebm::kMkvBitsPerChannel) { - colour_ptr->bits_per_channel = - UnserializeUInt(reader, read_pos, child_size); - if (colour_ptr->bits_per_channel < 0) - return false; - } else if (child_id == libwebm::kMkvChromaSubsamplingHorz) { - colour_ptr->chroma_subsampling_horz = - UnserializeUInt(reader, read_pos, child_size); - if (colour_ptr->chroma_subsampling_horz < 0) - return false; - } else if (child_id == libwebm::kMkvChromaSubsamplingVert) { - colour_ptr->chroma_subsampling_vert = - UnserializeUInt(reader, read_pos, child_size); - if (colour_ptr->chroma_subsampling_vert < 0) - return false; - } else if (child_id == libwebm::kMkvCbSubsamplingHorz) { - colour_ptr->cb_subsampling_horz = - UnserializeUInt(reader, read_pos, child_size); - if (colour_ptr->cb_subsampling_horz < 0) - return false; - } else if (child_id == libwebm::kMkvCbSubsamplingVert) { - colour_ptr->cb_subsampling_vert = - UnserializeUInt(reader, read_pos, child_size); - if (colour_ptr->cb_subsampling_vert < 0) - return false; - } else if (child_id == libwebm::kMkvChromaSitingHorz) { - colour_ptr->chroma_siting_horz = - UnserializeUInt(reader, read_pos, child_size); - if (colour_ptr->chroma_siting_horz < 0) - return false; - } else if (child_id == libwebm::kMkvChromaSitingVert) { - colour_ptr->chroma_siting_vert = - UnserializeUInt(reader, read_pos, child_size); - if (colour_ptr->chroma_siting_vert < 0) - return false; - } else if (child_id == libwebm::kMkvRange) { - colour_ptr->range = UnserializeUInt(reader, read_pos, child_size); - if (colour_ptr->range < 0) - return false; - } else if (child_id == libwebm::kMkvTransferCharacteristics) { - colour_ptr->transfer_characteristics = - UnserializeUInt(reader, read_pos, child_size); - if (colour_ptr->transfer_characteristics < 0) - return false; - } else if (child_id == libwebm::kMkvPrimaries) { - colour_ptr->primaries = UnserializeUInt(reader, read_pos, child_size); - if (colour_ptr->primaries < 0) - return false; - } else if (child_id == libwebm::kMkvMaxCLL) { - colour_ptr->max_cll = UnserializeUInt(reader, read_pos, child_size); - if (colour_ptr->max_cll < 0) - return false; - } else if (child_id == libwebm::kMkvMaxFALL) { - colour_ptr->max_fall = UnserializeUInt(reader, read_pos, child_size); - if (colour_ptr->max_fall < 0) - return false; - } else if (child_id == libwebm::kMkvMasteringMetadata) { - if (!MasteringMetadata::Parse(reader, read_pos, child_size, - &colour_ptr->mastering_metadata)) - return false; - } else { - return false; - } - - read_pos += child_size; - if (read_pos > colour_end) - return false; - } - *colour = colour_ptr.release(); - return true; -} - -bool Projection::Parse(IMkvReader* reader, long long start, long long size, - Projection** projection) { - if (!reader || *projection) - return false; - - std::unique_ptr projection_ptr(new Projection()); - if (!projection_ptr.get()) - return false; - - const long long end = start + size; - long long read_pos = start; - - while (read_pos < end) { - long long child_id = 0; - long long child_size = 0; - - const long long status = - ParseElementHeader(reader, read_pos, end, child_id, child_size); - if (status < 0) - return false; - - if (child_id == libwebm::kMkvProjectionType) { - long long projection_type = kTypeNotPresent; - projection_type = UnserializeUInt(reader, read_pos, child_size); - if (projection_type < 0) - return false; - - projection_ptr->type = static_cast(projection_type); - } else if (child_id == libwebm::kMkvProjectionPrivate) { - if (projection_ptr->private_data != NULL) - return false; - unsigned char* data = SafeArrayAlloc(1, child_size); - - if (data == NULL) - return false; - - const int status = - reader->Read(read_pos, static_cast(child_size), data); - - if (status) { - delete[] data; - return false; - } - - projection_ptr->private_data = data; - projection_ptr->private_data_length = static_cast(child_size); - } else { - double value = 0; - const long long value_parse_status = - UnserializeFloat(reader, read_pos, child_size, value); - // Make sure value is representable as a float before casting. - if (value_parse_status < 0 || value < -FLT_MAX || value > FLT_MAX || - (value > 0.0 && value < FLT_MIN)) { - return false; - } - - switch (child_id) { - case libwebm::kMkvProjectionPoseYaw: - projection_ptr->pose_yaw = static_cast(value); - break; - case libwebm::kMkvProjectionPosePitch: - projection_ptr->pose_pitch = static_cast(value); - break; - case libwebm::kMkvProjectionPoseRoll: - projection_ptr->pose_roll = static_cast(value); - break; - default: - return false; - } - } - - read_pos += child_size; - if (read_pos > end) - return false; - } - - *projection = projection_ptr.release(); - return true; -} - -VideoTrack::VideoTrack(Segment* pSegment, long long element_start, - long long element_size) - : Track(pSegment, element_start, element_size), - m_colour_space(NULL), - m_colour(NULL), - m_projection(NULL) {} - -VideoTrack::~VideoTrack() { - delete[] m_colour_space; - delete m_colour; - delete m_projection; -} - -long VideoTrack::Parse(Segment* pSegment, const Info& info, - long long element_start, long long element_size, - VideoTrack*& pResult) { - if (pResult) - return -1; - - if (info.type != Track::kVideo) - return -1; - - long long width = 0; - long long height = 0; - long long display_width = 0; - long long display_height = 0; - long long display_unit = 0; - long long stereo_mode = 0; - - double rate = 0.0; - std::unique_ptr colour_space_ptr; - - IMkvReader* const pReader = pSegment->m_pReader; - - const Settings& s = info.settings; - assert(s.start >= 0); - assert(s.size >= 0); - - long long pos = s.start; - assert(pos >= 0); - - const long long stop = pos + s.size; - - std::unique_ptr colour_ptr; - std::unique_ptr projection_ptr; - - while (pos < stop) { - long long id, size; - - const long status = ParseElementHeader(pReader, pos, stop, id, size); - - if (status < 0) // error - return status; - - if (id == libwebm::kMkvPixelWidth) { - width = UnserializeUInt(pReader, pos, size); - - if (width <= 0) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvPixelHeight) { - height = UnserializeUInt(pReader, pos, size); - - if (height <= 0) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvDisplayWidth) { - display_width = UnserializeUInt(pReader, pos, size); - - if (display_width <= 0) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvDisplayHeight) { - display_height = UnserializeUInt(pReader, pos, size); - - if (display_height <= 0) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvDisplayUnit) { - display_unit = UnserializeUInt(pReader, pos, size); - - if (display_unit < 0) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvStereoMode) { - stereo_mode = UnserializeUInt(pReader, pos, size); - - if (stereo_mode < 0) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvFrameRate) { - const long status = UnserializeFloat(pReader, pos, size, rate); - - if (status < 0) - return status; - - if (rate <= 0) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvColour) { - Colour* colour = NULL; - if (!Colour::Parse(pReader, pos, size, &colour)) { - return E_FILE_FORMAT_INVALID; - } else { - colour_ptr.reset(colour); - } - } else if (id == libwebm::kMkvProjection) { - Projection* projection = NULL; - if (!Projection::Parse(pReader, pos, size, &projection)) { - return E_FILE_FORMAT_INVALID; - } else { - projection_ptr.reset(projection); - } - } else if (id == libwebm::kMkvColourSpace) { - char* colour_space = NULL; - const long status = UnserializeString(pReader, pos, size, colour_space); - if (status < 0) - return status; - colour_space_ptr.reset(colour_space); - } - - pos += size; // consume payload - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - - VideoTrack* const pTrack = - new (std::nothrow) VideoTrack(pSegment, element_start, element_size); - - if (pTrack == NULL) - return -1; // generic error - - const int status = info.Copy(pTrack->m_info); - - if (status) { // error - delete pTrack; - return status; - } - - pTrack->m_width = width; - pTrack->m_height = height; - pTrack->m_display_width = display_width; - pTrack->m_display_height = display_height; - pTrack->m_display_unit = display_unit; - pTrack->m_stereo_mode = stereo_mode; - pTrack->m_rate = rate; - pTrack->m_colour = colour_ptr.release(); - pTrack->m_colour_space = colour_space_ptr.release(); - pTrack->m_projection = projection_ptr.release(); - - pResult = pTrack; - return 0; // success -} - -bool VideoTrack::VetEntry(const BlockEntry* pBlockEntry) const { - return Track::VetEntry(pBlockEntry) && pBlockEntry->GetBlock()->IsKey(); -} - -long VideoTrack::Seek(long long time_ns, const BlockEntry*& pResult) const { - const long status = GetFirst(pResult); - - if (status < 0) // buffer underflow, etc - return status; - - assert(pResult); - - if (pResult->EOS()) - return 0; - - const Cluster* pCluster = pResult->GetCluster(); - assert(pCluster); - assert(pCluster->GetIndex() >= 0); - - if (time_ns <= pResult->GetBlock()->GetTime(pCluster)) - return 0; - - Cluster** const clusters = m_pSegment->m_clusters; - assert(clusters); - - const long count = m_pSegment->GetCount(); // loaded only, not pre-loaded - assert(count > 0); - - Cluster** const i = clusters + pCluster->GetIndex(); - assert(i); - assert(*i == pCluster); - assert(pCluster->GetTime() <= time_ns); - - Cluster** const j = clusters + count; - - Cluster** lo = i; - Cluster** hi = j; - - while (lo < hi) { - // INVARIANT: - //[i, lo) <= time_ns - //[lo, hi) ? - //[hi, j) > time_ns - - Cluster** const mid = lo + (hi - lo) / 2; - assert(mid < hi); - - pCluster = *mid; - assert(pCluster); - assert(pCluster->GetIndex() >= 0); - assert(pCluster->GetIndex() == long(mid - m_pSegment->m_clusters)); - - const long long t = pCluster->GetTime(); - - if (t <= time_ns) - lo = mid + 1; - else - hi = mid; - - assert(lo <= hi); - } - - assert(lo == hi); - assert(lo > i); - assert(lo <= j); - - pCluster = *--lo; - assert(pCluster); - assert(pCluster->GetTime() <= time_ns); - - pResult = pCluster->GetEntry(this, time_ns); - - if ((pResult != 0) && !pResult->EOS()) // found a keyframe - return 0; - - while (lo != i) { - pCluster = *--lo; - assert(pCluster); - assert(pCluster->GetTime() <= time_ns); - - pResult = pCluster->GetEntry(this, time_ns); - - if ((pResult != 0) && !pResult->EOS()) - return 0; - } - - // weird: we're on the first cluster, but no keyframe found - // should never happen but we must return something anyway - - pResult = GetEOS(); - return 0; -} - -Colour* VideoTrack::GetColour() const { return m_colour; } - -Projection* VideoTrack::GetProjection() const { return m_projection; } - -long long VideoTrack::GetWidth() const { return m_width; } - -long long VideoTrack::GetHeight() const { return m_height; } - -long long VideoTrack::GetDisplayWidth() const { - return m_display_width > 0 ? m_display_width : GetWidth(); -} - -long long VideoTrack::GetDisplayHeight() const { - return m_display_height > 0 ? m_display_height : GetHeight(); -} - -long long VideoTrack::GetDisplayUnit() const { return m_display_unit; } - -long long VideoTrack::GetStereoMode() const { return m_stereo_mode; } - -double VideoTrack::GetFrameRate() const { return m_rate; } - -AudioTrack::AudioTrack(Segment* pSegment, long long element_start, - long long element_size) - : Track(pSegment, element_start, element_size) {} - -long AudioTrack::Parse(Segment* pSegment, const Info& info, - long long element_start, long long element_size, - AudioTrack*& pResult) { - if (pResult) - return -1; - - if (info.type != Track::kAudio) - return -1; - - IMkvReader* const pReader = pSegment->m_pReader; - - const Settings& s = info.settings; - assert(s.start >= 0); - assert(s.size >= 0); - - long long pos = s.start; - assert(pos >= 0); - - const long long stop = pos + s.size; - - double rate = 8000.0; // MKV default - long long channels = 1; - long long bit_depth = 0; - - while (pos < stop) { - long long id, size; - - long status = ParseElementHeader(pReader, pos, stop, id, size); - - if (status < 0) // error - return status; - - if (id == libwebm::kMkvSamplingFrequency) { - status = UnserializeFloat(pReader, pos, size, rate); - - if (status < 0) - return status; - - if (rate <= 0) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvChannels) { - channels = UnserializeUInt(pReader, pos, size); - - if (channels <= 0) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvBitDepth) { - bit_depth = UnserializeUInt(pReader, pos, size); - - if (bit_depth <= 0) - return E_FILE_FORMAT_INVALID; - } - - pos += size; // consume payload - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - - AudioTrack* const pTrack = - new (std::nothrow) AudioTrack(pSegment, element_start, element_size); - - if (pTrack == NULL) - return -1; // generic error - - const int status = info.Copy(pTrack->m_info); - - if (status) { - delete pTrack; - return status; - } - - pTrack->m_rate = rate; - pTrack->m_channels = channels; - pTrack->m_bitDepth = bit_depth; - - pResult = pTrack; - return 0; // success -} - -double AudioTrack::GetSamplingRate() const { return m_rate; } - -long long AudioTrack::GetChannels() const { return m_channels; } - -long long AudioTrack::GetBitDepth() const { return m_bitDepth; } - -Tracks::Tracks(Segment* pSegment, long long start, long long size_, - long long element_start, long long element_size) - : m_pSegment(pSegment), - m_start(start), - m_size(size_), - m_element_start(element_start), - m_element_size(element_size), - m_trackEntries(NULL), - m_trackEntriesEnd(NULL) {} - -long Tracks::Parse() { - assert(m_trackEntries == NULL); - assert(m_trackEntriesEnd == NULL); - - const long long stop = m_start + m_size; - IMkvReader* const pReader = m_pSegment->m_pReader; - - long long count = 0; - long long pos = m_start; - - while (pos < stop) { - long long id, size; - - const long status = ParseElementHeader(pReader, pos, stop, id, size); - - if (status < 0) // error - return status; - - if (size == 0) // weird - continue; - - if (id == libwebm::kMkvTrackEntry) { - ++count; - if (count > INT_MAX) - return E_PARSE_FAILED; - } - - pos += size; // consume payload - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - - if (count <= 0) - return 0; // success - - m_trackEntries = new (std::nothrow) Track*[static_cast(count)]; - - if (m_trackEntries == NULL) - return -1; - - m_trackEntriesEnd = m_trackEntries; - - pos = m_start; - - while (pos < stop) { - const long long element_start = pos; - - long long id, payload_size; - - const long status = - ParseElementHeader(pReader, pos, stop, id, payload_size); - - if (status < 0) // error - return status; - - if (payload_size == 0) // weird - continue; - - const long long payload_stop = pos + payload_size; - assert(payload_stop <= stop); // checked in ParseElement - - const long long element_size = payload_stop - element_start; - - if (id == libwebm::kMkvTrackEntry) { - Track*& pTrack = *m_trackEntriesEnd; - pTrack = NULL; - - const long status = ParseTrackEntry(pos, payload_size, element_start, - element_size, pTrack); - if (status) - return status; - - if (pTrack) - ++m_trackEntriesEnd; - } - - pos = payload_stop; - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - - return 0; // success -} - -unsigned long Tracks::GetTracksCount() const { - const ptrdiff_t result = m_trackEntriesEnd - m_trackEntries; - assert(result >= 0); - - return static_cast(result); -} - -long Tracks::ParseTrackEntry(long long track_start, long long track_size, - long long element_start, long long element_size, - Track*& pResult) const { - if (pResult) - return -1; - - IMkvReader* const pReader = m_pSegment->m_pReader; - - long long pos = track_start; - const long long track_stop = track_start + track_size; - - Track::Info info; - - info.type = 0; - info.number = 0; - info.uid = 0; - info.defaultDuration = 0; - - Track::Settings v; - v.start = -1; - v.size = -1; - - Track::Settings a; - a.start = -1; - a.size = -1; - - Track::Settings e; // content_encodings_settings; - e.start = -1; - e.size = -1; - - long long lacing = 1; // default is true - - while (pos < track_stop) { - long long id, size; - - const long status = ParseElementHeader(pReader, pos, track_stop, id, size); - - if (status < 0) // error - return status; - - if (size < 0) - return E_FILE_FORMAT_INVALID; - - const long long start = pos; - - if (id == libwebm::kMkvVideo) { - v.start = start; - v.size = size; - } else if (id == libwebm::kMkvAudio) { - a.start = start; - a.size = size; - } else if (id == libwebm::kMkvContentEncodings) { - e.start = start; - e.size = size; - } else if (id == libwebm::kMkvTrackUID) { - if (size > 8) - return E_FILE_FORMAT_INVALID; - - info.uid = 0; - - long long pos_ = start; - const long long pos_end = start + size; - - while (pos_ != pos_end) { - unsigned char b; - - const int status = pReader->Read(pos_, 1, &b); - - if (status) - return status; - - info.uid <<= 8; - info.uid |= b; - - ++pos_; - } - } else if (id == libwebm::kMkvTrackNumber) { - const long long num = UnserializeUInt(pReader, pos, size); - - if ((num <= 0) || (num > 127)) - return E_FILE_FORMAT_INVALID; - - info.number = static_cast(num); - } else if (id == libwebm::kMkvTrackType) { - const long long type = UnserializeUInt(pReader, pos, size); - - if ((type <= 0) || (type > 254)) - return E_FILE_FORMAT_INVALID; - - info.type = static_cast(type); - } else if (id == libwebm::kMkvName) { - const long status = - UnserializeString(pReader, pos, size, info.nameAsUTF8); - - if (status) - return status; - } else if (id == libwebm::kMkvLanguage) { - const long status = UnserializeString(pReader, pos, size, info.language); - - if (status) - return status; - } else if (id == libwebm::kMkvDefaultDuration) { - const long long duration = UnserializeUInt(pReader, pos, size); - - if (duration < 0) - return E_FILE_FORMAT_INVALID; - - info.defaultDuration = static_cast(duration); - } else if (id == libwebm::kMkvCodecID) { - const long status = UnserializeString(pReader, pos, size, info.codecId); - - if (status) - return status; - } else if (id == libwebm::kMkvFlagLacing) { - lacing = UnserializeUInt(pReader, pos, size); - - if ((lacing < 0) || (lacing > 1)) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvCodecPrivate) { - delete[] info.codecPrivate; - info.codecPrivate = NULL; - info.codecPrivateSize = 0; - - const size_t buflen = static_cast(size); - - if (buflen) { - unsigned char* buf = SafeArrayAlloc(1, buflen); - - if (buf == NULL) - return -1; - - const int status = pReader->Read(pos, static_cast(buflen), buf); - - if (status) { - delete[] buf; - return status; - } - - info.codecPrivate = buf; - info.codecPrivateSize = buflen; - } - } else if (id == libwebm::kMkvCodecName) { - const long status = - UnserializeString(pReader, pos, size, info.codecNameAsUTF8); - - if (status) - return status; - } else if (id == libwebm::kMkvCodecDelay) { - info.codecDelay = UnserializeUInt(pReader, pos, size); - } else if (id == libwebm::kMkvSeekPreRoll) { - info.seekPreRoll = UnserializeUInt(pReader, pos, size); - } - - pos += size; // consume payload - if (pos > track_stop) - return E_FILE_FORMAT_INVALID; - } - - if (pos != track_stop) - return E_FILE_FORMAT_INVALID; - - if (info.number <= 0) // not specified - return E_FILE_FORMAT_INVALID; - - if (GetTrackByNumber(info.number)) - return E_FILE_FORMAT_INVALID; - - if (info.type <= 0) // not specified - return E_FILE_FORMAT_INVALID; - - info.lacing = (lacing > 0) ? true : false; - - if (info.type == Track::kVideo) { - if (v.start < 0) - return E_FILE_FORMAT_INVALID; - - if (a.start >= 0) - return E_FILE_FORMAT_INVALID; - - info.settings = v; - - VideoTrack* pTrack = NULL; - - const long status = VideoTrack::Parse(m_pSegment, info, element_start, - element_size, pTrack); - - if (status) - return status; - - pResult = pTrack; - assert(pResult); - - if (e.start >= 0) - pResult->ParseContentEncodingsEntry(e.start, e.size); - } else if (info.type == Track::kAudio) { - if (a.start < 0) - return E_FILE_FORMAT_INVALID; - - if (v.start >= 0) - return E_FILE_FORMAT_INVALID; - - info.settings = a; - - AudioTrack* pTrack = NULL; - - const long status = AudioTrack::Parse(m_pSegment, info, element_start, - element_size, pTrack); - - if (status) - return status; - - pResult = pTrack; - assert(pResult); - - if (e.start >= 0) - pResult->ParseContentEncodingsEntry(e.start, e.size); - } else { - // neither video nor audio - probably metadata or subtitles - - if (a.start >= 0) - return E_FILE_FORMAT_INVALID; - - if (v.start >= 0) - return E_FILE_FORMAT_INVALID; - - if (info.type == Track::kMetadata && e.start >= 0) - return E_FILE_FORMAT_INVALID; - - info.settings.start = -1; - info.settings.size = 0; - - Track* pTrack = NULL; - - const long status = - Track::Create(m_pSegment, info, element_start, element_size, pTrack); - - if (status) - return status; - - pResult = pTrack; - assert(pResult); - } - - return 0; // success -} - -Tracks::~Tracks() { - Track** i = m_trackEntries; - Track** const j = m_trackEntriesEnd; - - while (i != j) { - Track* const pTrack = *i++; - delete pTrack; - } - - delete[] m_trackEntries; -} - -const Track* Tracks::GetTrackByNumber(long tn) const { - if (tn < 0) - return NULL; - - Track** i = m_trackEntries; - Track** const j = m_trackEntriesEnd; - - while (i != j) { - Track* const pTrack = *i++; - - if (pTrack == NULL) - continue; - - if (tn == pTrack->GetNumber()) - return pTrack; - } - - return NULL; // not found -} - -const Track* Tracks::GetTrackByIndex(unsigned long idx) const { - const ptrdiff_t count = m_trackEntriesEnd - m_trackEntries; - - if (idx >= static_cast(count)) - return NULL; - - return m_trackEntries[idx]; -} - -long Cluster::Load(long long& pos, long& len) const { - if (m_pSegment == NULL) - return E_PARSE_FAILED; - - if (m_timecode >= 0) // at least partially loaded - return 0; - - if (m_pos != m_element_start || m_element_size >= 0) - return E_PARSE_FAILED; - - IMkvReader* const pReader = m_pSegment->m_pReader; - long long total, avail; - const int status = pReader->Length(&total, &avail); - - if (status < 0) // error - return status; - - if (total >= 0 && (avail > total || m_pos > total)) - return E_FILE_FORMAT_INVALID; - - pos = m_pos; - - long long cluster_size = -1; - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - long long result = GetUIntLength(pReader, pos, len); - - if (result < 0) // error or underflow - return static_cast(result); - - if (result > 0) - return E_BUFFER_NOT_FULL; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long id_ = ReadID(pReader, pos, len); - - if (id_ < 0) // error - return static_cast(id_); - - if (id_ != libwebm::kMkvCluster) - return E_FILE_FORMAT_INVALID; - - pos += len; // consume id - - // read cluster size - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - result = GetUIntLength(pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) - return E_BUFFER_NOT_FULL; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long size = ReadUInt(pReader, pos, len); - - if (size < 0) // error - return static_cast(cluster_size); - - if (size == 0) - return E_FILE_FORMAT_INVALID; - - pos += len; // consume length of size of element - - const long long unknown_size = (1LL << (7 * len)) - 1; - - if (size != unknown_size) - cluster_size = size; - - // pos points to start of payload - long long timecode = -1; - long long new_pos = -1; - bool bBlock = false; - - long long cluster_stop = (cluster_size < 0) ? -1 : pos + cluster_size; - - for (;;) { - if ((cluster_stop >= 0) && (pos >= cluster_stop)) - break; - - // Parse ID - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - long long result = GetUIntLength(pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) - return E_BUFFER_NOT_FULL; - - if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long id = ReadID(pReader, pos, len); - - if (id < 0) // error - return static_cast(id); - - if (id == 0) - return E_FILE_FORMAT_INVALID; - - // This is the distinguished set of ID's we use to determine - // that we have exhausted the sub-element's inside the cluster - // whose ID we parsed earlier. - - if (id == libwebm::kMkvCluster) - break; - - if (id == libwebm::kMkvCues) - break; - - pos += len; // consume ID field - - // Parse Size - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - result = GetUIntLength(pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) - return E_BUFFER_NOT_FULL; - - if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long size = ReadUInt(pReader, pos, len); - - if (size < 0) // error - return static_cast(size); - - const long long unknown_size = (1LL << (7 * len)) - 1; - - if (size == unknown_size) - return E_FILE_FORMAT_INVALID; - - pos += len; // consume size field - - if ((cluster_stop >= 0) && (pos > cluster_stop)) - return E_FILE_FORMAT_INVALID; - - // pos now points to start of payload - - if (size == 0) - continue; - - if ((cluster_stop >= 0) && ((pos + size) > cluster_stop)) - return E_FILE_FORMAT_INVALID; - - if (id == libwebm::kMkvTimecode) { - len = static_cast(size); - - if ((pos + size) > avail) - return E_BUFFER_NOT_FULL; - - timecode = UnserializeUInt(pReader, pos, size); - - if (timecode < 0) // error (or underflow) - return static_cast(timecode); - - new_pos = pos + size; - - if (bBlock) - break; - } else if (id == libwebm::kMkvBlockGroup) { - bBlock = true; - break; - } else if (id == libwebm::kMkvSimpleBlock) { - bBlock = true; - break; - } - - pos += size; // consume payload - if (cluster_stop >= 0 && pos > cluster_stop) - return E_FILE_FORMAT_INVALID; - } - - if (cluster_stop >= 0 && pos > cluster_stop) - return E_FILE_FORMAT_INVALID; - - if (timecode < 0) // no timecode found - return E_FILE_FORMAT_INVALID; - - if (!bBlock) - return E_FILE_FORMAT_INVALID; - - m_pos = new_pos; // designates position just beyond timecode payload - m_timecode = timecode; // m_timecode >= 0 means we're partially loaded - - if (cluster_size >= 0) - m_element_size = cluster_stop - m_element_start; - - return 0; -} - -long Cluster::Parse(long long& pos, long& len) const { - long status = Load(pos, len); - - if (status < 0) - return status; - - if (m_pos < m_element_start || m_timecode < 0) - return E_PARSE_FAILED; - - const long long cluster_stop = - (m_element_size < 0) ? -1 : m_element_start + m_element_size; - - if ((cluster_stop >= 0) && (m_pos >= cluster_stop)) - return 1; // nothing else to do - - IMkvReader* const pReader = m_pSegment->m_pReader; - - long long total, avail; - - status = pReader->Length(&total, &avail); - - if (status < 0) // error - return status; - - if (total >= 0 && avail > total) - return E_FILE_FORMAT_INVALID; - - pos = m_pos; - - for (;;) { - if ((cluster_stop >= 0) && (pos >= cluster_stop)) - break; - - if ((total >= 0) && (pos >= total)) { - if (m_element_size < 0) - m_element_size = pos - m_element_start; - - break; - } - - // Parse ID - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - long long result = GetUIntLength(pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) - return E_BUFFER_NOT_FULL; - - if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long id = ReadID(pReader, pos, len); - - if (id < 0) - return E_FILE_FORMAT_INVALID; - - // This is the distinguished set of ID's we use to determine - // that we have exhausted the sub-element's inside the cluster - // whose ID we parsed earlier. - - if ((id == libwebm::kMkvCluster) || (id == libwebm::kMkvCues)) { - if (m_element_size < 0) - m_element_size = pos - m_element_start; - - break; - } - - pos += len; // consume ID field - - // Parse Size - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - result = GetUIntLength(pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) - return E_BUFFER_NOT_FULL; - - if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long size = ReadUInt(pReader, pos, len); - - if (size < 0) // error - return static_cast(size); - - const long long unknown_size = (1LL << (7 * len)) - 1; - - if (size == unknown_size) - return E_FILE_FORMAT_INVALID; - - pos += len; // consume size field - - if ((cluster_stop >= 0) && (pos > cluster_stop)) - return E_FILE_FORMAT_INVALID; - - // pos now points to start of payload - - if (size == 0) - continue; - - // const long long block_start = pos; - const long long block_stop = pos + size; - - if (cluster_stop >= 0) { - if (block_stop > cluster_stop) { - if (id == libwebm::kMkvBlockGroup || id == libwebm::kMkvSimpleBlock) { - return E_FILE_FORMAT_INVALID; - } - - pos = cluster_stop; - break; - } - } else if ((total >= 0) && (block_stop > total)) { - m_element_size = total - m_element_start; - pos = total; - break; - } else if (block_stop > avail) { - len = static_cast(size); - return E_BUFFER_NOT_FULL; - } - - Cluster* const this_ = const_cast(this); - - if (id == libwebm::kMkvBlockGroup) - return this_->ParseBlockGroup(size, pos, len); - - if (id == libwebm::kMkvSimpleBlock) - return this_->ParseSimpleBlock(size, pos, len); - - pos += size; // consume payload - if (cluster_stop >= 0 && pos > cluster_stop) - return E_FILE_FORMAT_INVALID; - } - - if (m_element_size < 1) - return E_FILE_FORMAT_INVALID; - - m_pos = pos; - if (cluster_stop >= 0 && m_pos > cluster_stop) - return E_FILE_FORMAT_INVALID; - - if (m_entries_count > 0) { - const long idx = m_entries_count - 1; - - const BlockEntry* const pLast = m_entries[idx]; - if (pLast == NULL) - return E_PARSE_FAILED; - - const Block* const pBlock = pLast->GetBlock(); - if (pBlock == NULL) - return E_PARSE_FAILED; - - const long long start = pBlock->m_start; - - if ((total >= 0) && (start > total)) - return E_PARSE_FAILED; // defend against trucated stream - - const long long size = pBlock->m_size; - - const long long stop = start + size; - if (cluster_stop >= 0 && stop > cluster_stop) - return E_FILE_FORMAT_INVALID; - - if ((total >= 0) && (stop > total)) - return E_PARSE_FAILED; // defend against trucated stream - } - - return 1; // no more entries -} - -long Cluster::ParseSimpleBlock(long long block_size, long long& pos, - long& len) { - const long long block_start = pos; - const long long block_stop = pos + block_size; - - IMkvReader* const pReader = m_pSegment->m_pReader; - - long long total, avail; - - long status = pReader->Length(&total, &avail); - - if (status < 0) // error - return status; - - assert((total < 0) || (avail <= total)); - - // parse track number - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - long long result = GetUIntLength(pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) // weird - return E_BUFFER_NOT_FULL; - - if ((pos + len) > block_stop) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long track = ReadUInt(pReader, pos, len); - - if (track < 0) // error - return static_cast(track); - - if (track == 0) - return E_FILE_FORMAT_INVALID; - - pos += len; // consume track number - - if ((pos + 2) > block_stop) - return E_FILE_FORMAT_INVALID; - - if ((pos + 2) > avail) { - len = 2; - return E_BUFFER_NOT_FULL; - } - - pos += 2; // consume timecode - - if ((pos + 1) > block_stop) - return E_FILE_FORMAT_INVALID; - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - unsigned char flags; - - status = pReader->Read(pos, 1, &flags); - - if (status < 0) { // error or underflow - len = 1; - return status; - } - - ++pos; // consume flags byte - assert(pos <= avail); - - if (pos >= block_stop) - return E_FILE_FORMAT_INVALID; - - const int lacing = int(flags & 0x06) >> 1; - - if ((lacing != 0) && (block_stop > avail)) { - len = static_cast(block_stop - pos); - return E_BUFFER_NOT_FULL; - } - - status = CreateBlock(libwebm::kMkvSimpleBlock, block_start, block_size, - 0); // DiscardPadding - - if (status != 0) - return status; - - m_pos = block_stop; - - return 0; // success -} - -long Cluster::ParseBlockGroup(long long payload_size, long long& pos, - long& len) { - const long long payload_start = pos; - const long long payload_stop = pos + payload_size; - - IMkvReader* const pReader = m_pSegment->m_pReader; - - long long total, avail; - - long status = pReader->Length(&total, &avail); - - if (status < 0) // error - return status; - - assert((total < 0) || (avail <= total)); - - if ((total >= 0) && (payload_stop > total)) - return E_FILE_FORMAT_INVALID; - - if (payload_stop > avail) { - len = static_cast(payload_size); - return E_BUFFER_NOT_FULL; - } - - long long discard_padding = 0; - - while (pos < payload_stop) { - // parse sub-block element ID - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - long long result = GetUIntLength(pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) // weird - return E_BUFFER_NOT_FULL; - - if ((pos + len) > payload_stop) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long id = ReadID(pReader, pos, len); - - if (id < 0) // error - return static_cast(id); - - if (id == 0) // not a valid ID - return E_FILE_FORMAT_INVALID; - - pos += len; // consume ID field - - // Parse Size - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - result = GetUIntLength(pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) // weird - return E_BUFFER_NOT_FULL; - - if ((pos + len) > payload_stop) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long size = ReadUInt(pReader, pos, len); - - if (size < 0) // error - return static_cast(size); - - pos += len; // consume size field - - // pos now points to start of sub-block group payload - - if (pos > payload_stop) - return E_FILE_FORMAT_INVALID; - - if (size == 0) // weird - continue; - - const long long unknown_size = (1LL << (7 * len)) - 1; - - if (size == unknown_size) - return E_FILE_FORMAT_INVALID; - - if (id == libwebm::kMkvDiscardPadding) { - status = UnserializeInt(pReader, pos, size, discard_padding); - - if (status < 0) // error - return status; - } - - if (id != libwebm::kMkvBlock) { - pos += size; // consume sub-part of block group - - if (pos > payload_stop) - return E_FILE_FORMAT_INVALID; - - continue; - } - - const long long block_stop = pos + size; - - if (block_stop > payload_stop) - return E_FILE_FORMAT_INVALID; - - // parse track number - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - result = GetUIntLength(pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) // weird - return E_BUFFER_NOT_FULL; - - if ((pos + len) > block_stop) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long track = ReadUInt(pReader, pos, len); - - if (track < 0) // error - return static_cast(track); - - if (track == 0) - return E_FILE_FORMAT_INVALID; - - pos += len; // consume track number - - if ((pos + 2) > block_stop) - return E_FILE_FORMAT_INVALID; - - if ((pos + 2) > avail) { - len = 2; - return E_BUFFER_NOT_FULL; - } - - pos += 2; // consume timecode - - if ((pos + 1) > block_stop) - return E_FILE_FORMAT_INVALID; - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - unsigned char flags; - - status = pReader->Read(pos, 1, &flags); - - if (status < 0) { // error or underflow - len = 1; - return status; - } - - ++pos; // consume flags byte - assert(pos <= avail); - - if (pos >= block_stop) - return E_FILE_FORMAT_INVALID; - - const int lacing = int(flags & 0x06) >> 1; - - if ((lacing != 0) && (block_stop > avail)) { - len = static_cast(block_stop - pos); - return E_BUFFER_NOT_FULL; - } - - pos = block_stop; // consume block-part of block group - if (pos > payload_stop) - return E_FILE_FORMAT_INVALID; - } - - if (pos != payload_stop) - return E_FILE_FORMAT_INVALID; - - status = CreateBlock(libwebm::kMkvBlockGroup, payload_start, payload_size, - discard_padding); - if (status != 0) - return status; - - m_pos = payload_stop; - - return 0; // success -} - -long Cluster::GetEntry(long index, const mkvparser::BlockEntry*& pEntry) const { - assert(m_pos >= m_element_start); - - pEntry = NULL; - - if (index < 0) - return -1; // generic error - - if (m_entries_count < 0) - return E_BUFFER_NOT_FULL; - - assert(m_entries); - assert(m_entries_size > 0); - assert(m_entries_count <= m_entries_size); - - if (index < m_entries_count) { - pEntry = m_entries[index]; - assert(pEntry); - - return 1; // found entry - } - - if (m_element_size < 0) // we don't know cluster end yet - return E_BUFFER_NOT_FULL; // underflow - - const long long element_stop = m_element_start + m_element_size; - - if (m_pos >= element_stop) - return 0; // nothing left to parse - - return E_BUFFER_NOT_FULL; // underflow, since more remains to be parsed -} - -Cluster* Cluster::Create(Segment* pSegment, long idx, long long off) { - if (!pSegment || off < 0) - return NULL; - - const long long element_start = pSegment->m_start + off; - - Cluster* const pCluster = - new (std::nothrow) Cluster(pSegment, idx, element_start); - - return pCluster; -} - -Cluster::Cluster() - : m_pSegment(NULL), - m_element_start(0), - m_index(0), - m_pos(0), - m_element_size(0), - m_timecode(0), - m_entries(NULL), - m_entries_size(0), - m_entries_count(0) // means "no entries" -{} - -Cluster::Cluster(Segment* pSegment, long idx, long long element_start - /* long long element_size */) - : m_pSegment(pSegment), - m_element_start(element_start), - m_index(idx), - m_pos(element_start), - m_element_size(-1 /* element_size */), - m_timecode(-1), - m_entries(NULL), - m_entries_size(0), - m_entries_count(-1) // means "has not been parsed yet" -{} - -Cluster::~Cluster() { - if (m_entries_count <= 0) { - delete[] m_entries; - return; - } - - BlockEntry** i = m_entries; - BlockEntry** const j = m_entries + m_entries_count; - - while (i != j) { - BlockEntry* p = *i++; - assert(p); - - delete p; - } - - delete[] m_entries; -} - -bool Cluster::EOS() const { return (m_pSegment == NULL); } - -long Cluster::GetIndex() const { return m_index; } - -long long Cluster::GetPosition() const { - const long long pos = m_element_start - m_pSegment->m_start; - assert(pos >= 0); - - return pos; -} - -long long Cluster::GetElementSize() const { return m_element_size; } - -long Cluster::HasBlockEntries( - const Segment* pSegment, - long long off, // relative to start of segment payload - long long& pos, long& len) { - assert(pSegment); - assert(off >= 0); // relative to segment - - IMkvReader* const pReader = pSegment->m_pReader; - - long long total, avail; - - long status = pReader->Length(&total, &avail); - - if (status < 0) // error - return status; - - assert((total < 0) || (avail <= total)); - - pos = pSegment->m_start + off; // absolute - - if ((total >= 0) && (pos >= total)) - return 0; // we don't even have a complete cluster - - const long long segment_stop = - (pSegment->m_size < 0) ? -1 : pSegment->m_start + pSegment->m_size; - - long long cluster_stop = -1; // interpreted later to mean "unknown size" - - { - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - long long result = GetUIntLength(pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) // need more data - return E_BUFFER_NOT_FULL; - - if ((segment_stop >= 0) && ((pos + len) > segment_stop)) - return E_FILE_FORMAT_INVALID; - - if ((total >= 0) && ((pos + len) > total)) - return 0; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long id = ReadID(pReader, pos, len); - - if (id < 0) // error - return static_cast(id); - - if (id != libwebm::kMkvCluster) - return E_PARSE_FAILED; - - pos += len; // consume Cluster ID field - - // read size field - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - result = GetUIntLength(pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) // weird - return E_BUFFER_NOT_FULL; - - if ((segment_stop >= 0) && ((pos + len) > segment_stop)) - return E_FILE_FORMAT_INVALID; - - if ((total >= 0) && ((pos + len) > total)) - return 0; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long size = ReadUInt(pReader, pos, len); - - if (size < 0) // error - return static_cast(size); - - if (size == 0) - return 0; // cluster does not have entries - - pos += len; // consume size field - - // pos now points to start of payload - - const long long unknown_size = (1LL << (7 * len)) - 1; - - if (size != unknown_size) { - cluster_stop = pos + size; - assert(cluster_stop >= 0); - - if ((segment_stop >= 0) && (cluster_stop > segment_stop)) - return E_FILE_FORMAT_INVALID; - - if ((total >= 0) && (cluster_stop > total)) - // return E_FILE_FORMAT_INVALID; //too conservative - return 0; // cluster does not have any entries - } - } - - for (;;) { - if ((cluster_stop >= 0) && (pos >= cluster_stop)) - return 0; // no entries detected - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - long long result = GetUIntLength(pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) // need more data - return E_BUFFER_NOT_FULL; - - if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long id = ReadID(pReader, pos, len); - - if (id < 0) // error - return static_cast(id); - - // This is the distinguished set of ID's we use to determine - // that we have exhausted the sub-element's inside the cluster - // whose ID we parsed earlier. - - if (id == libwebm::kMkvCluster) - return 0; // no entries found - - if (id == libwebm::kMkvCues) - return 0; // no entries found - - pos += len; // consume id field - - if ((cluster_stop >= 0) && (pos >= cluster_stop)) - return E_FILE_FORMAT_INVALID; - - // read size field - - if ((pos + 1) > avail) { - len = 1; - return E_BUFFER_NOT_FULL; - } - - result = GetUIntLength(pReader, pos, len); - - if (result < 0) // error - return static_cast(result); - - if (result > 0) // underflow - return E_BUFFER_NOT_FULL; - - if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > avail) - return E_BUFFER_NOT_FULL; - - const long long size = ReadUInt(pReader, pos, len); - - if (size < 0) // error - return static_cast(size); - - pos += len; // consume size field - - // pos now points to start of payload - - if ((cluster_stop >= 0) && (pos > cluster_stop)) - return E_FILE_FORMAT_INVALID; - - if (size == 0) // weird - continue; - - const long long unknown_size = (1LL << (7 * len)) - 1; - - if (size == unknown_size) - return E_FILE_FORMAT_INVALID; // not supported inside cluster - - if ((cluster_stop >= 0) && ((pos + size) > cluster_stop)) - return E_FILE_FORMAT_INVALID; - - if (id == libwebm::kMkvBlockGroup) - return 1; // have at least one entry - - if (id == libwebm::kMkvSimpleBlock) - return 1; // have at least one entry - - pos += size; // consume payload - if (cluster_stop >= 0 && pos > cluster_stop) - return E_FILE_FORMAT_INVALID; - } -} - -long long Cluster::GetTimeCode() const { - long long pos; - long len; - - const long status = Load(pos, len); - - if (status < 0) // error - return status; - - return m_timecode; -} - -long long Cluster::GetTime() const { - const long long tc = GetTimeCode(); - - if (tc < 0) - return tc; - - const SegmentInfo* const pInfo = m_pSegment->GetInfo(); - assert(pInfo); - - const long long scale = pInfo->GetTimeCodeScale(); - assert(scale >= 1); - - const long long t = m_timecode * scale; - - return t; -} - -long long Cluster::GetFirstTime() const { - const BlockEntry* pEntry; - - const long status = GetFirst(pEntry); - - if (status < 0) // error - return status; - - if (pEntry == NULL) // empty cluster - return GetTime(); - - const Block* const pBlock = pEntry->GetBlock(); - assert(pBlock); - - return pBlock->GetTime(this); -} - -long long Cluster::GetLastTime() const { - const BlockEntry* pEntry; - - const long status = GetLast(pEntry); - - if (status < 0) // error - return status; - - if (pEntry == NULL) // empty cluster - return GetTime(); - - const Block* const pBlock = pEntry->GetBlock(); - assert(pBlock); - - return pBlock->GetTime(this); -} - -long Cluster::CreateBlock(long long id, - long long pos, // absolute pos of payload - long long size, long long discard_padding) { - if (id != libwebm::kMkvBlockGroup && id != libwebm::kMkvSimpleBlock) - return E_PARSE_FAILED; - - if (m_entries_count < 0) { // haven't parsed anything yet - assert(m_entries == NULL); - assert(m_entries_size == 0); - - m_entries_size = 1024; - m_entries = new (std::nothrow) BlockEntry*[m_entries_size]; - if (m_entries == NULL) - return -1; - - m_entries_count = 0; - } else { - assert(m_entries); - assert(m_entries_size > 0); - assert(m_entries_count <= m_entries_size); - - if (m_entries_count >= m_entries_size) { - const long entries_size = 2 * m_entries_size; - - BlockEntry** const entries = new (std::nothrow) BlockEntry*[entries_size]; - if (entries == NULL) - return -1; - - BlockEntry** src = m_entries; - BlockEntry** const src_end = src + m_entries_count; - - BlockEntry** dst = entries; - - while (src != src_end) - *dst++ = *src++; - - delete[] m_entries; - - m_entries = entries; - m_entries_size = entries_size; - } - } - - if (id == libwebm::kMkvBlockGroup) - return CreateBlockGroup(pos, size, discard_padding); - else - return CreateSimpleBlock(pos, size); -} - -long Cluster::CreateBlockGroup(long long start_offset, long long size, - long long discard_padding) { - assert(m_entries); - assert(m_entries_size > 0); - assert(m_entries_count >= 0); - assert(m_entries_count < m_entries_size); - - IMkvReader* const pReader = m_pSegment->m_pReader; - - long long pos = start_offset; - const long long stop = start_offset + size; - - // For WebM files, there is a bias towards previous reference times - //(in order to support alt-ref frames, which refer back to the previous - // keyframe). Normally a 0 value is not possible, but here we tenatively - // allow 0 as the value of a reference frame, with the interpretation - // that this is a "previous" reference time. - - long long prev = 1; // nonce - long long next = 0; // nonce - long long duration = -1; // really, this is unsigned - - long long bpos = -1; - long long bsize = -1; - - while (pos < stop) { - long len; - const long long id = ReadID(pReader, pos, len); - if (id < 0 || (pos + len) > stop) - return E_FILE_FORMAT_INVALID; - - pos += len; // consume ID - - const long long size = ReadUInt(pReader, pos, len); - assert(size >= 0); // TODO - assert((pos + len) <= stop); - - pos += len; // consume size - - if (id == libwebm::kMkvBlock) { - if (bpos < 0) { // Block ID - bpos = pos; - bsize = size; - } - } else if (id == libwebm::kMkvBlockDuration) { - if (size > 8) - return E_FILE_FORMAT_INVALID; - - duration = UnserializeUInt(pReader, pos, size); - - if (duration < 0) - return E_FILE_FORMAT_INVALID; - } else if (id == libwebm::kMkvReferenceBlock) { - if (size > 8 || size <= 0) - return E_FILE_FORMAT_INVALID; - const long size_ = static_cast(size); - - long long time; - - long status = UnserializeInt(pReader, pos, size_, time); - assert(status == 0); - if (status != 0) - return -1; - - if (time <= 0) // see note above - prev = time; - else - next = time; - } - - pos += size; // consume payload - if (pos > stop) - return E_FILE_FORMAT_INVALID; - } - if (bpos < 0) - return E_FILE_FORMAT_INVALID; - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - assert(bsize >= 0); - - const long idx = m_entries_count; - - BlockEntry** const ppEntry = m_entries + idx; - BlockEntry*& pEntry = *ppEntry; - - pEntry = new (std::nothrow) - BlockGroup(this, idx, bpos, bsize, prev, next, duration, discard_padding); - - if (pEntry == NULL) - return -1; // generic error - - BlockGroup* const p = static_cast(pEntry); - - const long status = p->Parse(); - - if (status == 0) { // success - ++m_entries_count; - return 0; - } - - delete pEntry; - pEntry = 0; - - return status; -} - -long Cluster::CreateSimpleBlock(long long st, long long sz) { - assert(m_entries); - assert(m_entries_size > 0); - assert(m_entries_count >= 0); - assert(m_entries_count < m_entries_size); - - const long idx = m_entries_count; - - BlockEntry** const ppEntry = m_entries + idx; - BlockEntry*& pEntry = *ppEntry; - - pEntry = new (std::nothrow) SimpleBlock(this, idx, st, sz); - - if (pEntry == NULL) - return -1; // generic error - - SimpleBlock* const p = static_cast(pEntry); - - const long status = p->Parse(); - - if (status == 0) { - ++m_entries_count; - return 0; - } - - delete pEntry; - pEntry = 0; - - return status; -} - -long Cluster::GetFirst(const BlockEntry*& pFirst) const { - if (m_entries_count <= 0) { - long long pos; - long len; - - const long status = Parse(pos, len); - - if (status < 0) { // error - pFirst = NULL; - return status; - } - - if (m_entries_count <= 0) { // empty cluster - pFirst = NULL; - return 0; - } - } - - assert(m_entries); - - pFirst = m_entries[0]; - assert(pFirst); - - return 0; // success -} - -long Cluster::GetLast(const BlockEntry*& pLast) const { - for (;;) { - long long pos; - long len; - - const long status = Parse(pos, len); - - if (status < 0) { // error - pLast = NULL; - return status; - } - - if (status > 0) // no new block - break; - } - - if (m_entries_count <= 0) { - pLast = NULL; - return 0; - } - - assert(m_entries); - - const long idx = m_entries_count - 1; - - pLast = m_entries[idx]; - assert(pLast); - - return 0; -} - -long Cluster::GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const { - assert(pCurr); - assert(m_entries); - assert(m_entries_count > 0); - - size_t idx = pCurr->GetIndex(); - assert(idx < size_t(m_entries_count)); - assert(m_entries[idx] == pCurr); - - ++idx; - - if (idx >= size_t(m_entries_count)) { - long long pos; - long len; - - const long status = Parse(pos, len); - - if (status < 0) { // error - pNext = NULL; - return status; - } - - if (status > 0) { - pNext = NULL; - return 0; - } - - assert(m_entries); - assert(m_entries_count > 0); - assert(idx < size_t(m_entries_count)); - } - - pNext = m_entries[idx]; - assert(pNext); - - return 0; -} - -long Cluster::GetEntryCount() const { return m_entries_count; } - -const BlockEntry* Cluster::GetEntry(const Track* pTrack, - long long time_ns) const { - assert(pTrack); - - if (m_pSegment == NULL) // this is the special EOS cluster - return pTrack->GetEOS(); - - const BlockEntry* pResult = pTrack->GetEOS(); - - long index = 0; - - for (;;) { - if (index >= m_entries_count) { - long long pos; - long len; - - const long status = Parse(pos, len); - assert(status >= 0); - - if (status > 0) // completely parsed, and no more entries - return pResult; - - if (status < 0) // should never happen - return 0; - - assert(m_entries); - assert(index < m_entries_count); - } - - const BlockEntry* const pEntry = m_entries[index]; - assert(pEntry); - assert(!pEntry->EOS()); - - const Block* const pBlock = pEntry->GetBlock(); - assert(pBlock); - - if (pBlock->GetTrackNumber() != pTrack->GetNumber()) { - ++index; - continue; - } - - if (pTrack->VetEntry(pEntry)) { - if (time_ns < 0) // just want first candidate block - return pEntry; - - const long long ns = pBlock->GetTime(this); - - if (ns > time_ns) - return pResult; - - pResult = pEntry; // have a candidate - } else if (time_ns >= 0) { - const long long ns = pBlock->GetTime(this); - - if (ns > time_ns) - return pResult; - } - - ++index; - } -} - -const BlockEntry* Cluster::GetEntry(const CuePoint& cp, - const CuePoint::TrackPosition& tp) const { - assert(m_pSegment); - const long long tc = cp.GetTimeCode(); - - if (tp.m_block > 0) { - const long block = static_cast(tp.m_block); - const long index = block - 1; - - while (index >= m_entries_count) { - long long pos; - long len; - - const long status = Parse(pos, len); - - if (status < 0) // TODO: can this happen? - return NULL; - - if (status > 0) // nothing remains to be parsed - return NULL; - } - - const BlockEntry* const pEntry = m_entries[index]; - assert(pEntry); - assert(!pEntry->EOS()); - - const Block* const pBlock = pEntry->GetBlock(); - assert(pBlock); - - if ((pBlock->GetTrackNumber() == tp.m_track) && - (pBlock->GetTimeCode(this) == tc)) { - return pEntry; - } - } - - long index = 0; - - for (;;) { - if (index >= m_entries_count) { - long long pos; - long len; - - const long status = Parse(pos, len); - - if (status < 0) // TODO: can this happen? - return NULL; - - if (status > 0) // nothing remains to be parsed - return NULL; - - assert(m_entries); - assert(index < m_entries_count); - } - - const BlockEntry* const pEntry = m_entries[index]; - assert(pEntry); - assert(!pEntry->EOS()); - - const Block* const pBlock = pEntry->GetBlock(); - assert(pBlock); - - if (pBlock->GetTrackNumber() != tp.m_track) { - ++index; - continue; - } - - const long long tc_ = pBlock->GetTimeCode(this); - - if (tc_ < tc) { - ++index; - continue; - } - - if (tc_ > tc) - return NULL; - - const Tracks* const pTracks = m_pSegment->GetTracks(); - assert(pTracks); - - const long tn = static_cast(tp.m_track); - const Track* const pTrack = pTracks->GetTrackByNumber(tn); - - if (pTrack == NULL) - return NULL; - - const long long type = pTrack->GetType(); - - if (type == 2) // audio - return pEntry; - - if (type != 1) // not video - return NULL; - - if (!pBlock->IsKey()) - return NULL; - - return pEntry; - } -} - -BlockEntry::BlockEntry(Cluster* p, long idx) : m_pCluster(p), m_index(idx) {} -BlockEntry::~BlockEntry() {} -const Cluster* BlockEntry::GetCluster() const { return m_pCluster; } -long BlockEntry::GetIndex() const { return m_index; } - -SimpleBlock::SimpleBlock(Cluster* pCluster, long idx, long long start, - long long size) - : BlockEntry(pCluster, idx), m_block(start, size, 0) {} - -long SimpleBlock::Parse() { return m_block.Parse(m_pCluster); } -BlockEntry::Kind SimpleBlock::GetKind() const { return kBlockSimple; } -const Block* SimpleBlock::GetBlock() const { return &m_block; } - -BlockGroup::BlockGroup(Cluster* pCluster, long idx, long long block_start, - long long block_size, long long prev, long long next, - long long duration, long long discard_padding) - : BlockEntry(pCluster, idx), - m_block(block_start, block_size, discard_padding), - m_prev(prev), - m_next(next), - m_duration(duration) {} - -long BlockGroup::Parse() { - const long status = m_block.Parse(m_pCluster); - - if (status) - return status; - - m_block.SetKey((m_prev > 0) && (m_next <= 0)); - - return 0; -} - -BlockEntry::Kind BlockGroup::GetKind() const { return kBlockGroup; } -const Block* BlockGroup::GetBlock() const { return &m_block; } -long long BlockGroup::GetPrevTimeCode() const { return m_prev; } -long long BlockGroup::GetNextTimeCode() const { return m_next; } -long long BlockGroup::GetDurationTimeCode() const { return m_duration; } - -Block::Block(long long start, long long size_, long long discard_padding) - : m_start(start), - m_size(size_), - m_track(0), - m_timecode(-1), - m_flags(0), - m_frames(NULL), - m_frame_count(-1), - m_discard_padding(discard_padding) {} - -Block::~Block() { delete[] m_frames; } - -long Block::Parse(const Cluster* pCluster) { - if (pCluster == NULL) - return -1; - - if (pCluster->m_pSegment == NULL) - return -1; - - assert(m_start >= 0); - assert(m_size >= 0); - assert(m_track <= 0); - assert(m_frames == NULL); - assert(m_frame_count <= 0); - - long long pos = m_start; - const long long stop = m_start + m_size; - - long len; - - IMkvReader* const pReader = pCluster->m_pSegment->m_pReader; - - m_track = ReadUInt(pReader, pos, len); - - if (m_track <= 0) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > stop) - return E_FILE_FORMAT_INVALID; - - pos += len; // consume track number - - if ((stop - pos) < 2) - return E_FILE_FORMAT_INVALID; - - long status; - long long value; - - status = UnserializeInt(pReader, pos, 2, value); - - if (status) - return E_FILE_FORMAT_INVALID; - - if (value < SHRT_MIN) - return E_FILE_FORMAT_INVALID; - - if (value > SHRT_MAX) - return E_FILE_FORMAT_INVALID; - - m_timecode = static_cast(value); - - pos += 2; - - if ((stop - pos) <= 0) - return E_FILE_FORMAT_INVALID; - - status = pReader->Read(pos, 1, &m_flags); - - if (status) - return E_FILE_FORMAT_INVALID; - - const int lacing = int(m_flags & 0x06) >> 1; - - ++pos; // consume flags byte - - if (lacing == 0) { // no lacing - if (pos > stop) - return E_FILE_FORMAT_INVALID; - - m_frame_count = 1; - m_frames = new (std::nothrow) Frame[m_frame_count]; - if (m_frames == NULL) - return -1; - - Frame& f = m_frames[0]; - f.pos = pos; - - const long long frame_size = stop - pos; - - if (frame_size > LONG_MAX || frame_size <= 0) - return E_FILE_FORMAT_INVALID; - - f.len = static_cast(frame_size); - - return 0; // success - } - - if (pos >= stop) - return E_FILE_FORMAT_INVALID; - - unsigned char biased_count; - - status = pReader->Read(pos, 1, &biased_count); - - if (status) - return E_FILE_FORMAT_INVALID; - - ++pos; // consume frame count - if (pos > stop) - return E_FILE_FORMAT_INVALID; - - m_frame_count = int(biased_count) + 1; - - m_frames = new (std::nothrow) Frame[m_frame_count]; - if (m_frames == NULL) - return -1; - - if (!m_frames) - return E_FILE_FORMAT_INVALID; - - if (lacing == 1) { // Xiph - Frame* pf = m_frames; - Frame* const pf_end = pf + m_frame_count; - - long long size = 0; - int frame_count = m_frame_count; - - while (frame_count > 1) { - long frame_size = 0; - - for (;;) { - unsigned char val; - - if (pos >= stop) - return E_FILE_FORMAT_INVALID; - - status = pReader->Read(pos, 1, &val); - - if (status) - return E_FILE_FORMAT_INVALID; - - ++pos; // consume xiph size byte - - frame_size += val; - - if (val < 255) - break; - } - - Frame& f = *pf++; - assert(pf < pf_end); - if (pf >= pf_end) - return E_FILE_FORMAT_INVALID; - - f.pos = 0; // patch later - - if (frame_size <= 0) - return E_FILE_FORMAT_INVALID; - - f.len = frame_size; - size += frame_size; // contribution of this frame - - --frame_count; - } - - if (pf >= pf_end || pos > stop) - return E_FILE_FORMAT_INVALID; - - { - Frame& f = *pf++; - - if (pf != pf_end) - return E_FILE_FORMAT_INVALID; - - f.pos = 0; // patch later - - const long long total_size = stop - pos; - - if (total_size < size) - return E_FILE_FORMAT_INVALID; - - const long long frame_size = total_size - size; - - if (frame_size > LONG_MAX || frame_size <= 0) - return E_FILE_FORMAT_INVALID; - - f.len = static_cast(frame_size); - } - - pf = m_frames; - while (pf != pf_end) { - Frame& f = *pf++; - assert((pos + f.len) <= stop); - - if ((pos + f.len) > stop) - return E_FILE_FORMAT_INVALID; - - f.pos = pos; - pos += f.len; - } - - assert(pos == stop); - if (pos != stop) - return E_FILE_FORMAT_INVALID; - - } else if (lacing == 2) { // fixed-size lacing - if (pos >= stop) - return E_FILE_FORMAT_INVALID; - - const long long total_size = stop - pos; - - if ((total_size % m_frame_count) != 0) - return E_FILE_FORMAT_INVALID; - - const long long frame_size = total_size / m_frame_count; - - if (frame_size > LONG_MAX || frame_size <= 0) - return E_FILE_FORMAT_INVALID; - - Frame* pf = m_frames; - Frame* const pf_end = pf + m_frame_count; - - while (pf != pf_end) { - assert((pos + frame_size) <= stop); - if ((pos + frame_size) > stop) - return E_FILE_FORMAT_INVALID; - - Frame& f = *pf++; - - f.pos = pos; - f.len = static_cast(frame_size); - - pos += frame_size; - } - - assert(pos == stop); - if (pos != stop) - return E_FILE_FORMAT_INVALID; - - } else { - assert(lacing == 3); // EBML lacing - - if (pos >= stop) - return E_FILE_FORMAT_INVALID; - - long long size = 0; - int frame_count = m_frame_count; - - long long frame_size = ReadUInt(pReader, pos, len); - - if (frame_size <= 0) - return E_FILE_FORMAT_INVALID; - - if (frame_size > LONG_MAX) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > stop) - return E_FILE_FORMAT_INVALID; - - pos += len; // consume length of size of first frame - - if ((pos + frame_size) > stop) - return E_FILE_FORMAT_INVALID; - - Frame* pf = m_frames; - Frame* const pf_end = pf + m_frame_count; - - { - Frame& curr = *pf; - - curr.pos = 0; // patch later - - curr.len = static_cast(frame_size); - size += curr.len; // contribution of this frame - } - - --frame_count; - - while (frame_count > 1) { - if (pos >= stop) - return E_FILE_FORMAT_INVALID; - - assert(pf < pf_end); - if (pf >= pf_end) - return E_FILE_FORMAT_INVALID; - - const Frame& prev = *pf++; - assert(prev.len == frame_size); - if (prev.len != frame_size) - return E_FILE_FORMAT_INVALID; - - assert(pf < pf_end); - if (pf >= pf_end) - return E_FILE_FORMAT_INVALID; - - Frame& curr = *pf; - - curr.pos = 0; // patch later - - const long long delta_size_ = ReadUInt(pReader, pos, len); - - if (delta_size_ < 0) - return E_FILE_FORMAT_INVALID; - - if ((pos + len) > stop) - return E_FILE_FORMAT_INVALID; - - pos += len; // consume length of (delta) size - if (pos > stop) - return E_FILE_FORMAT_INVALID; - - const long exp = 7 * len - 1; - const long long bias = (1LL << exp) - 1LL; - const long long delta_size = delta_size_ - bias; - - frame_size += delta_size; - - if (frame_size <= 0) - return E_FILE_FORMAT_INVALID; - - if (frame_size > LONG_MAX) - return E_FILE_FORMAT_INVALID; - - curr.len = static_cast(frame_size); - // Check if size + curr.len could overflow. - if (size > LLONG_MAX - curr.len) { - return E_FILE_FORMAT_INVALID; - } - size += curr.len; // contribution of this frame - - --frame_count; - } - - // parse last frame - if (frame_count > 0) { - if (pos > stop || pf >= pf_end) - return E_FILE_FORMAT_INVALID; - - const Frame& prev = *pf++; - assert(prev.len == frame_size); - if (prev.len != frame_size) - return E_FILE_FORMAT_INVALID; - - if (pf >= pf_end) - return E_FILE_FORMAT_INVALID; - - Frame& curr = *pf++; - if (pf != pf_end) - return E_FILE_FORMAT_INVALID; - - curr.pos = 0; // patch later - - const long long total_size = stop - pos; - - if (total_size < size) - return E_FILE_FORMAT_INVALID; - - frame_size = total_size - size; - - if (frame_size > LONG_MAX || frame_size <= 0) - return E_FILE_FORMAT_INVALID; - - curr.len = static_cast(frame_size); - } - - pf = m_frames; - while (pf != pf_end) { - Frame& f = *pf++; - if ((pos + f.len) > stop) - return E_FILE_FORMAT_INVALID; - - f.pos = pos; - pos += f.len; - } - - if (pos != stop) - return E_FILE_FORMAT_INVALID; - } - - return 0; // success -} - -long long Block::GetTimeCode(const Cluster* pCluster) const { - if (pCluster == 0) - return m_timecode; - - const long long tc0 = pCluster->GetTimeCode(); - assert(tc0 >= 0); - - // Check if tc0 + m_timecode would overflow. - if (tc0 < 0 || LLONG_MAX - tc0 < m_timecode) { - return -1; - } - - const long long tc = tc0 + m_timecode; - - return tc; // unscaled timecode units -} - -long long Block::GetTime(const Cluster* pCluster) const { - assert(pCluster); - - const long long tc = GetTimeCode(pCluster); - - const Segment* const pSegment = pCluster->m_pSegment; - const SegmentInfo* const pInfo = pSegment->GetInfo(); - assert(pInfo); - - const long long scale = pInfo->GetTimeCodeScale(); - assert(scale >= 1); - - // Check if tc * scale could overflow. - if (tc != 0 && scale > LLONG_MAX / tc) { - return -1; - } - const long long ns = tc * scale; - - return ns; -} - -long long Block::GetTrackNumber() const { return m_track; } - -bool Block::IsKey() const { - return ((m_flags & static_cast(1 << 7)) != 0); -} - -void Block::SetKey(bool bKey) { - if (bKey) - m_flags |= static_cast(1 << 7); - else - m_flags &= 0x7F; -} - -bool Block::IsInvisible() const { return bool(int(m_flags & 0x08) != 0); } - -Block::Lacing Block::GetLacing() const { - const int value = int(m_flags & 0x06) >> 1; - return static_cast(value); -} - -int Block::GetFrameCount() const { return m_frame_count; } - -const Block::Frame& Block::GetFrame(int idx) const { - assert(idx >= 0); - assert(idx < m_frame_count); - - const Frame& f = m_frames[idx]; - assert(f.pos > 0); - assert(f.len > 0); - - return f; -} - -long Block::Frame::Read(IMkvReader* pReader, unsigned char* buf) const { - assert(pReader); - assert(buf); - - const long status = pReader->Read(pos, len, buf); - return status; -} - -long long Block::GetDiscardPadding() const { return m_discard_padding; } - -} // namespace mkvparser diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvparser/mkvparser.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvparser/mkvparser.h deleted file mode 100644 index 848d01f0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvparser/mkvparser.h +++ /dev/null @@ -1,1147 +0,0 @@ -// Copyright (c) 2012 The WebM project authors. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -#ifndef MKVPARSER_MKVPARSER_H_ -#define MKVPARSER_MKVPARSER_H_ - -#include - -namespace mkvparser { - -const int E_PARSE_FAILED = -1; -const int E_FILE_FORMAT_INVALID = -2; -const int E_BUFFER_NOT_FULL = -3; - -class IMkvReader { - public: - virtual int Read(long long pos, long len, unsigned char* buf) = 0; - virtual int Length(long long* total, long long* available) = 0; - - protected: - virtual ~IMkvReader() {} -}; - -template -Type* SafeArrayAlloc(unsigned long long num_elements, - unsigned long long element_size); -long long GetUIntLength(IMkvReader*, long long, long&); -long long ReadUInt(IMkvReader*, long long, long&); -long long ReadID(IMkvReader* pReader, long long pos, long& len); -long long UnserializeUInt(IMkvReader*, long long pos, long long size); - -long UnserializeFloat(IMkvReader*, long long pos, long long size, double&); -long UnserializeInt(IMkvReader*, long long pos, long long size, - long long& result); - -long UnserializeString(IMkvReader*, long long pos, long long size, char*& str); - -long ParseElementHeader(IMkvReader* pReader, - long long& pos, // consume id and size fields - long long stop, // if you know size of element's parent - long long& id, long long& size); - -bool Match(IMkvReader*, long long&, unsigned long, long long&); -bool Match(IMkvReader*, long long&, unsigned long, unsigned char*&, size_t&); - -void GetVersion(int& major, int& minor, int& build, int& revision); - -struct EBMLHeader { - EBMLHeader(); - ~EBMLHeader(); - long long m_version; - long long m_readVersion; - long long m_maxIdLength; - long long m_maxSizeLength; - char* m_docType; - long long m_docTypeVersion; - long long m_docTypeReadVersion; - - long long Parse(IMkvReader*, long long&); - void Init(); -}; - -class Segment; -class Track; -class Cluster; - -class Block { - Block(const Block&); - Block& operator=(const Block&); - - public: - const long long m_start; - const long long m_size; - - Block(long long start, long long size, long long discard_padding); - ~Block(); - - long Parse(const Cluster*); - - long long GetTrackNumber() const; - long long GetTimeCode(const Cluster*) const; // absolute, but not scaled - long long GetTime(const Cluster*) const; // absolute, and scaled (ns) - bool IsKey() const; - void SetKey(bool); - bool IsInvisible() const; - - enum Lacing { kLacingNone, kLacingXiph, kLacingFixed, kLacingEbml }; - Lacing GetLacing() const; - - int GetFrameCount() const; // to index frames: [0, count) - - struct Frame { - long long pos; // absolute offset - long len; - - long Read(IMkvReader*, unsigned char*) const; - }; - - const Frame& GetFrame(int frame_index) const; - - long long GetDiscardPadding() const; - - private: - long long m_track; // Track::Number() - short m_timecode; // relative to cluster - unsigned char m_flags; - - Frame* m_frames; - int m_frame_count; - - protected: - const long long m_discard_padding; -}; - -class BlockEntry { - BlockEntry(const BlockEntry&); - BlockEntry& operator=(const BlockEntry&); - - protected: - BlockEntry(Cluster*, long index); - - public: - virtual ~BlockEntry(); - - bool EOS() const { return (GetKind() == kBlockEOS); } - const Cluster* GetCluster() const; - long GetIndex() const; - virtual const Block* GetBlock() const = 0; - - enum Kind { kBlockEOS, kBlockSimple, kBlockGroup }; - virtual Kind GetKind() const = 0; - - protected: - Cluster* const m_pCluster; - const long m_index; -}; - -class SimpleBlock : public BlockEntry { - SimpleBlock(const SimpleBlock&); - SimpleBlock& operator=(const SimpleBlock&); - - public: - SimpleBlock(Cluster*, long index, long long start, long long size); - long Parse(); - - Kind GetKind() const; - const Block* GetBlock() const; - - protected: - Block m_block; -}; - -class BlockGroup : public BlockEntry { - BlockGroup(const BlockGroup&); - BlockGroup& operator=(const BlockGroup&); - - public: - BlockGroup(Cluster*, long index, - long long block_start, // absolute pos of block's payload - long long block_size, // size of block's payload - long long prev, long long next, long long duration, - long long discard_padding); - - long Parse(); - - Kind GetKind() const; - const Block* GetBlock() const; - - long long GetPrevTimeCode() const; // relative to block's time - long long GetNextTimeCode() const; // as above - long long GetDurationTimeCode() const; - - private: - Block m_block; - const long long m_prev; - const long long m_next; - const long long m_duration; -}; - -/////////////////////////////////////////////////////////////// -// ContentEncoding element -// Elements used to describe if the track data has been encrypted or -// compressed with zlib or header stripping. -class ContentEncoding { - public: - enum { kCTR = 1 }; - - ContentEncoding(); - ~ContentEncoding(); - - // ContentCompression element names - struct ContentCompression { - ContentCompression(); - ~ContentCompression(); - - unsigned long long algo; - unsigned char* settings; - long long settings_len; - }; - - // ContentEncAESSettings element names - struct ContentEncAESSettings { - ContentEncAESSettings() : cipher_mode(kCTR) {} - ~ContentEncAESSettings() {} - - unsigned long long cipher_mode; - }; - - // ContentEncryption element names - struct ContentEncryption { - ContentEncryption(); - ~ContentEncryption(); - - unsigned long long algo; - unsigned char* key_id; - long long key_id_len; - unsigned char* signature; - long long signature_len; - unsigned char* sig_key_id; - long long sig_key_id_len; - unsigned long long sig_algo; - unsigned long long sig_hash_algo; - - ContentEncAESSettings aes_settings; - }; - - // Returns ContentCompression represented by |idx|. Returns NULL if |idx| - // is out of bounds. - const ContentCompression* GetCompressionByIndex(unsigned long idx) const; - - // Returns number of ContentCompression elements in this ContentEncoding - // element. - unsigned long GetCompressionCount() const; - - // Parses the ContentCompression element from |pReader|. |start| is the - // starting offset of the ContentCompression payload. |size| is the size in - // bytes of the ContentCompression payload. |compression| is where the parsed - // values will be stored. - long ParseCompressionEntry(long long start, long long size, - IMkvReader* pReader, - ContentCompression* compression); - - // Returns ContentEncryption represented by |idx|. Returns NULL if |idx| - // is out of bounds. - const ContentEncryption* GetEncryptionByIndex(unsigned long idx) const; - - // Returns number of ContentEncryption elements in this ContentEncoding - // element. - unsigned long GetEncryptionCount() const; - - // Parses the ContentEncAESSettings element from |pReader|. |start| is the - // starting offset of the ContentEncAESSettings payload. |size| is the - // size in bytes of the ContentEncAESSettings payload. |encryption| is - // where the parsed values will be stored. - long ParseContentEncAESSettingsEntry(long long start, long long size, - IMkvReader* pReader, - ContentEncAESSettings* aes); - - // Parses the ContentEncoding element from |pReader|. |start| is the - // starting offset of the ContentEncoding payload. |size| is the size in - // bytes of the ContentEncoding payload. Returns true on success. - long ParseContentEncodingEntry(long long start, long long size, - IMkvReader* pReader); - - // Parses the ContentEncryption element from |pReader|. |start| is the - // starting offset of the ContentEncryption payload. |size| is the size in - // bytes of the ContentEncryption payload. |encryption| is where the parsed - // values will be stored. - long ParseEncryptionEntry(long long start, long long size, - IMkvReader* pReader, ContentEncryption* encryption); - - unsigned long long encoding_order() const { return encoding_order_; } - unsigned long long encoding_scope() const { return encoding_scope_; } - unsigned long long encoding_type() const { return encoding_type_; } - - private: - // Member variables for list of ContentCompression elements. - ContentCompression** compression_entries_; - ContentCompression** compression_entries_end_; - - // Member variables for list of ContentEncryption elements. - ContentEncryption** encryption_entries_; - ContentEncryption** encryption_entries_end_; - - // ContentEncoding element names - unsigned long long encoding_order_; - unsigned long long encoding_scope_; - unsigned long long encoding_type_; - - // LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding); - ContentEncoding(const ContentEncoding&); - ContentEncoding& operator=(const ContentEncoding&); -}; - -class Track { - Track(const Track&); - Track& operator=(const Track&); - - public: - class Info; - static long Create(Segment*, const Info&, long long element_start, - long long element_size, Track*&); - - enum Type { kVideo = 1, kAudio = 2, kSubtitle = 0x11, kMetadata = 0x21 }; - - Segment* const m_pSegment; - const long long m_element_start; - const long long m_element_size; - virtual ~Track(); - - long GetType() const; - long GetNumber() const; - unsigned long long GetUid() const; - const char* GetNameAsUTF8() const; - const char* GetLanguage() const; - const char* GetCodecNameAsUTF8() const; - const char* GetCodecId() const; - const unsigned char* GetCodecPrivate(size_t&) const; - bool GetLacing() const; - unsigned long long GetDefaultDuration() const; - unsigned long long GetCodecDelay() const; - unsigned long long GetSeekPreRoll() const; - - const BlockEntry* GetEOS() const; - - struct Settings { - long long start; - long long size; - }; - - class Info { - public: - Info(); - ~Info(); - int Copy(Info&) const; - void Clear(); - long type; - long number; - unsigned long long uid; - unsigned long long defaultDuration; - unsigned long long codecDelay; - unsigned long long seekPreRoll; - char* nameAsUTF8; - char* language; - char* codecId; - char* codecNameAsUTF8; - unsigned char* codecPrivate; - size_t codecPrivateSize; - bool lacing; - Settings settings; - - private: - Info(const Info&); - Info& operator=(const Info&); - int CopyStr(char* Info::*str, Info&) const; - }; - - long GetFirst(const BlockEntry*&) const; - long GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const; - virtual bool VetEntry(const BlockEntry*) const; - virtual long Seek(long long time_ns, const BlockEntry*&) const; - - const ContentEncoding* GetContentEncodingByIndex(unsigned long idx) const; - unsigned long GetContentEncodingCount() const; - - long ParseContentEncodingsEntry(long long start, long long size); - - protected: - Track(Segment*, long long element_start, long long element_size); - - Info m_info; - - class EOSBlock : public BlockEntry { - public: - EOSBlock(); - - Kind GetKind() const; - const Block* GetBlock() const; - }; - - EOSBlock m_eos; - - private: - ContentEncoding** content_encoding_entries_; - ContentEncoding** content_encoding_entries_end_; -}; - -struct PrimaryChromaticity { - PrimaryChromaticity() : x(0), y(0) {} - ~PrimaryChromaticity() {} - static bool Parse(IMkvReader* reader, long long read_pos, - long long value_size, bool is_x, - PrimaryChromaticity** chromaticity); - float x; - float y; -}; - -struct MasteringMetadata { - static const float kValueNotPresent; - - MasteringMetadata() - : r(NULL), - g(NULL), - b(NULL), - white_point(NULL), - luminance_max(kValueNotPresent), - luminance_min(kValueNotPresent) {} - ~MasteringMetadata() { - delete r; - delete g; - delete b; - delete white_point; - } - - static bool Parse(IMkvReader* reader, long long element_start, - long long element_size, - MasteringMetadata** mastering_metadata); - - PrimaryChromaticity* r; - PrimaryChromaticity* g; - PrimaryChromaticity* b; - PrimaryChromaticity* white_point; - float luminance_max; - float luminance_min; -}; - -struct Colour { - static const long long kValueNotPresent; - - // Unless otherwise noted all values assigned upon construction are the - // equivalent of unspecified/default. - Colour() - : matrix_coefficients(kValueNotPresent), - bits_per_channel(kValueNotPresent), - chroma_subsampling_horz(kValueNotPresent), - chroma_subsampling_vert(kValueNotPresent), - cb_subsampling_horz(kValueNotPresent), - cb_subsampling_vert(kValueNotPresent), - chroma_siting_horz(kValueNotPresent), - chroma_siting_vert(kValueNotPresent), - range(kValueNotPresent), - transfer_characteristics(kValueNotPresent), - primaries(kValueNotPresent), - max_cll(kValueNotPresent), - max_fall(kValueNotPresent), - mastering_metadata(NULL) {} - ~Colour() { - delete mastering_metadata; - mastering_metadata = NULL; - } - - static bool Parse(IMkvReader* reader, long long element_start, - long long element_size, Colour** colour); - - long long matrix_coefficients; - long long bits_per_channel; - long long chroma_subsampling_horz; - long long chroma_subsampling_vert; - long long cb_subsampling_horz; - long long cb_subsampling_vert; - long long chroma_siting_horz; - long long chroma_siting_vert; - long long range; - long long transfer_characteristics; - long long primaries; - long long max_cll; - long long max_fall; - - MasteringMetadata* mastering_metadata; -}; - -struct Projection { - enum ProjectionType { - kTypeNotPresent = -1, - kRectangular = 0, - kEquirectangular = 1, - kCubeMap = 2, - kMesh = 3, - }; - static const float kValueNotPresent; - Projection() - : type(kTypeNotPresent), - private_data(NULL), - private_data_length(0), - pose_yaw(kValueNotPresent), - pose_pitch(kValueNotPresent), - pose_roll(kValueNotPresent) {} - ~Projection() { delete[] private_data; } - static bool Parse(IMkvReader* reader, long long element_start, - long long element_size, Projection** projection); - - ProjectionType type; - unsigned char* private_data; - size_t private_data_length; - float pose_yaw; - float pose_pitch; - float pose_roll; -}; - -class VideoTrack : public Track { - VideoTrack(const VideoTrack&); - VideoTrack& operator=(const VideoTrack&); - - VideoTrack(Segment*, long long element_start, long long element_size); - - public: - virtual ~VideoTrack(); - static long Parse(Segment*, const Info&, long long element_start, - long long element_size, VideoTrack*&); - - long long GetWidth() const; - long long GetHeight() const; - long long GetDisplayWidth() const; - long long GetDisplayHeight() const; - long long GetDisplayUnit() const; - long long GetStereoMode() const; - double GetFrameRate() const; - - bool VetEntry(const BlockEntry*) const; - long Seek(long long time_ns, const BlockEntry*&) const; - - Colour* GetColour() const; - - Projection* GetProjection() const; - - const char* GetColourSpace() const { return m_colour_space; } - - private: - long long m_width; - long long m_height; - long long m_display_width; - long long m_display_height; - long long m_display_unit; - long long m_stereo_mode; - char* m_colour_space; - double m_rate; - - Colour* m_colour; - Projection* m_projection; -}; - -class AudioTrack : public Track { - AudioTrack(const AudioTrack&); - AudioTrack& operator=(const AudioTrack&); - - AudioTrack(Segment*, long long element_start, long long element_size); - - public: - static long Parse(Segment*, const Info&, long long element_start, - long long element_size, AudioTrack*&); - - double GetSamplingRate() const; - long long GetChannels() const; - long long GetBitDepth() const; - - private: - double m_rate; - long long m_channels; - long long m_bitDepth; -}; - -class Tracks { - Tracks(const Tracks&); - Tracks& operator=(const Tracks&); - - public: - Segment* const m_pSegment; - const long long m_start; - const long long m_size; - const long long m_element_start; - const long long m_element_size; - - Tracks(Segment*, long long start, long long size, long long element_start, - long long element_size); - - ~Tracks(); - - long Parse(); - - unsigned long GetTracksCount() const; - - const Track* GetTrackByNumber(long tn) const; - const Track* GetTrackByIndex(unsigned long idx) const; - - private: - Track** m_trackEntries; - Track** m_trackEntriesEnd; - - long ParseTrackEntry(long long payload_start, long long payload_size, - long long element_start, long long element_size, - Track*&) const; -}; - -class Chapters { - Chapters(const Chapters&); - Chapters& operator=(const Chapters&); - - public: - Segment* const m_pSegment; - const long long m_start; - const long long m_size; - const long long m_element_start; - const long long m_element_size; - - Chapters(Segment*, long long payload_start, long long payload_size, - long long element_start, long long element_size); - - ~Chapters(); - - long Parse(); - - class Atom; - class Edition; - - class Display { - friend class Atom; - Display(); - Display(const Display&); - ~Display(); - Display& operator=(const Display&); - - public: - const char* GetString() const; - const char* GetLanguage() const; - const char* GetCountry() const; - - private: - void Init(); - void ShallowCopy(Display&) const; - void Clear(); - long Parse(IMkvReader*, long long pos, long long size); - - char* m_string; - char* m_language; - char* m_country; - }; - - class Atom { - friend class Edition; - Atom(); - Atom(const Atom&); - ~Atom(); - Atom& operator=(const Atom&); - - public: - unsigned long long GetUID() const; - const char* GetStringUID() const; - - long long GetStartTimecode() const; - long long GetStopTimecode() const; - - long long GetStartTime(const Chapters*) const; - long long GetStopTime(const Chapters*) const; - - int GetDisplayCount() const; - const Display* GetDisplay(int index) const; - - private: - void Init(); - void ShallowCopy(Atom&) const; - void Clear(); - long Parse(IMkvReader*, long long pos, long long size); - static long long GetTime(const Chapters*, long long timecode); - - long ParseDisplay(IMkvReader*, long long pos, long long size); - bool ExpandDisplaysArray(); - - char* m_string_uid; - unsigned long long m_uid; - long long m_start_timecode; - long long m_stop_timecode; - - Display* m_displays; - int m_displays_size; - int m_displays_count; - }; - - class Edition { - friend class Chapters; - Edition(); - Edition(const Edition&); - ~Edition(); - Edition& operator=(const Edition&); - - public: - int GetAtomCount() const; - const Atom* GetAtom(int index) const; - - private: - void Init(); - void ShallowCopy(Edition&) const; - void Clear(); - long Parse(IMkvReader*, long long pos, long long size); - - long ParseAtom(IMkvReader*, long long pos, long long size); - bool ExpandAtomsArray(); - - Atom* m_atoms; - int m_atoms_size; - int m_atoms_count; - }; - - int GetEditionCount() const; - const Edition* GetEdition(int index) const; - - private: - long ParseEdition(long long pos, long long size); - bool ExpandEditionsArray(); - - Edition* m_editions; - int m_editions_size; - int m_editions_count; -}; - -class Tags { - Tags(const Tags&); - Tags& operator=(const Tags&); - - public: - Segment* const m_pSegment; - const long long m_start; - const long long m_size; - const long long m_element_start; - const long long m_element_size; - - Tags(Segment*, long long payload_start, long long payload_size, - long long element_start, long long element_size); - - ~Tags(); - - long Parse(); - - class Tag; - class SimpleTag; - - class SimpleTag { - friend class Tag; - SimpleTag(); - SimpleTag(const SimpleTag&); - ~SimpleTag(); - SimpleTag& operator=(const SimpleTag&); - - public: - const char* GetTagName() const; - const char* GetTagString() const; - - private: - void Init(); - void ShallowCopy(SimpleTag&) const; - void Clear(); - long Parse(IMkvReader*, long long pos, long long size); - - char* m_tag_name; - char* m_tag_string; - }; - - class Tag { - friend class Tags; - Tag(); - Tag(const Tag&); - ~Tag(); - Tag& operator=(const Tag&); - - public: - int GetSimpleTagCount() const; - const SimpleTag* GetSimpleTag(int index) const; - - private: - void Init(); - void ShallowCopy(Tag&) const; - void Clear(); - long Parse(IMkvReader*, long long pos, long long size); - - long ParseSimpleTag(IMkvReader*, long long pos, long long size); - bool ExpandSimpleTagsArray(); - - SimpleTag* m_simple_tags; - int m_simple_tags_size; - int m_simple_tags_count; - }; - - int GetTagCount() const; - const Tag* GetTag(int index) const; - - private: - long ParseTag(long long pos, long long size); - bool ExpandTagsArray(); - - Tag* m_tags; - int m_tags_size; - int m_tags_count; -}; - -class SegmentInfo { - SegmentInfo(const SegmentInfo&); - SegmentInfo& operator=(const SegmentInfo&); - - public: - Segment* const m_pSegment; - const long long m_start; - const long long m_size; - const long long m_element_start; - const long long m_element_size; - - SegmentInfo(Segment*, long long start, long long size, - long long element_start, long long element_size); - - ~SegmentInfo(); - - long Parse(); - - long long GetTimeCodeScale() const; - long long GetDuration() const; // scaled - const char* GetMuxingAppAsUTF8() const; - const char* GetWritingAppAsUTF8() const; - const char* GetTitleAsUTF8() const; - - private: - long long m_timecodeScale; - double m_duration; - char* m_pMuxingAppAsUTF8; - char* m_pWritingAppAsUTF8; - char* m_pTitleAsUTF8; -}; - -class SeekHead { - SeekHead(const SeekHead&); - SeekHead& operator=(const SeekHead&); - - public: - Segment* const m_pSegment; - const long long m_start; - const long long m_size; - const long long m_element_start; - const long long m_element_size; - - SeekHead(Segment*, long long start, long long size, long long element_start, - long long element_size); - - ~SeekHead(); - - long Parse(); - - struct Entry { - Entry(); - - // the SeekHead entry payload - long long id; - long long pos; - - // absolute pos of SeekEntry ID - long long element_start; - - // SeekEntry ID size + size size + payload - long long element_size; - }; - - int GetCount() const; - const Entry* GetEntry(int idx) const; - - struct VoidElement { - // absolute pos of Void ID - long long element_start; - - // ID size + size size + payload size - long long element_size; - }; - - int GetVoidElementCount() const; - const VoidElement* GetVoidElement(int idx) const; - - private: - Entry* m_entries; - int m_entry_count; - - VoidElement* m_void_elements; - int m_void_element_count; - - static bool ParseEntry(IMkvReader*, - long long pos, // payload - long long size, Entry*); -}; - -class Cues; -class CuePoint { - friend class Cues; - - CuePoint(long, long long); - ~CuePoint(); - - CuePoint(const CuePoint&); - CuePoint& operator=(const CuePoint&); - - public: - long long m_element_start; - long long m_element_size; - - bool Load(IMkvReader*); - - long long GetTimeCode() const; // absolute but unscaled - long long GetTime(const Segment*) const; // absolute and scaled (ns units) - - struct TrackPosition { - long long m_track; - long long m_pos; // of cluster - long long m_block; - // codec_state //defaults to 0 - // reference = clusters containing req'd referenced blocks - // reftime = timecode of the referenced block - - bool Parse(IMkvReader*, long long, long long); - }; - - const TrackPosition* Find(const Track*) const; - - private: - const long m_index; - long long m_timecode; - TrackPosition* m_track_positions; - size_t m_track_positions_count; -}; - -class Cues { - friend class Segment; - - Cues(Segment*, long long start, long long size, long long element_start, - long long element_size); - ~Cues(); - - Cues(const Cues&); - Cues& operator=(const Cues&); - - public: - Segment* const m_pSegment; - const long long m_start; - const long long m_size; - const long long m_element_start; - const long long m_element_size; - - bool Find( // lower bound of time_ns - long long time_ns, const Track*, const CuePoint*&, - const CuePoint::TrackPosition*&) const; - - const CuePoint* GetFirst() const; - const CuePoint* GetLast() const; - const CuePoint* GetNext(const CuePoint*) const; - - const BlockEntry* GetBlock(const CuePoint*, - const CuePoint::TrackPosition*) const; - - bool LoadCuePoint() const; - long GetCount() const; // loaded only - // long GetTotal() const; //loaded + preloaded - bool DoneParsing() const; - - private: - bool Init() const; - bool PreloadCuePoint(long&, long long) const; - - mutable CuePoint** m_cue_points; - mutable long m_count; - mutable long m_preload_count; - mutable long long m_pos; -}; - -class Cluster { - friend class Segment; - - Cluster(const Cluster&); - Cluster& operator=(const Cluster&); - - public: - Segment* const m_pSegment; - - public: - static Cluster* Create(Segment*, - long index, // index in segment - long long off); // offset relative to segment - // long long element_size); - - Cluster(); // EndOfStream - ~Cluster(); - - bool EOS() const; - - long long GetTimeCode() const; // absolute, but not scaled - long long GetTime() const; // absolute, and scaled (nanosecond units) - long long GetFirstTime() const; // time (ns) of first (earliest) block - long long GetLastTime() const; // time (ns) of last (latest) block - - long GetFirst(const BlockEntry*&) const; - long GetLast(const BlockEntry*&) const; - long GetNext(const BlockEntry* curr, const BlockEntry*& next) const; - - const BlockEntry* GetEntry(const Track*, long long ns = -1) const; - const BlockEntry* GetEntry(const CuePoint&, - const CuePoint::TrackPosition&) const; - // const BlockEntry* GetMaxKey(const VideoTrack*) const; - - // static bool HasBlockEntries(const Segment*, long long); - - static long HasBlockEntries(const Segment*, long long idoff, long long& pos, - long& size); - - long GetEntryCount() const; - - long Load(long long& pos, long& size) const; - - long Parse(long long& pos, long& size) const; - long GetEntry(long index, const mkvparser::BlockEntry*&) const; - - protected: - Cluster(Segment*, long index, long long element_start); - // long long element_size); - - public: - const long long m_element_start; - long long GetPosition() const; // offset relative to segment - - long GetIndex() const; - long long GetElementSize() const; - // long long GetPayloadSize() const; - - // long long Unparsed() const; - - private: - long m_index; - mutable long long m_pos; - // mutable long long m_size; - mutable long long m_element_size; - mutable long long m_timecode; - mutable BlockEntry** m_entries; - mutable long m_entries_size; - mutable long m_entries_count; - - long ParseSimpleBlock(long long, long long&, long&); - long ParseBlockGroup(long long, long long&, long&); - - long CreateBlock(long long id, long long pos, long long size, - long long discard_padding); - long CreateBlockGroup(long long start_offset, long long size, - long long discard_padding); - long CreateSimpleBlock(long long, long long); -}; - -class Segment { - friend class Cues; - friend class Track; - friend class VideoTrack; - - Segment(const Segment&); - Segment& operator=(const Segment&); - - private: - Segment(IMkvReader*, long long elem_start, - // long long elem_size, - long long pos, long long size); - - public: - IMkvReader* const m_pReader; - const long long m_element_start; - // const long long m_element_size; - const long long m_start; // posn of segment payload - const long long m_size; // size of segment payload - Cluster m_eos; // TODO: make private? - - static long long CreateInstance(IMkvReader*, long long, Segment*&); - ~Segment(); - - long Load(); // loads headers and all clusters - - // for incremental loading - // long long Unparsed() const; - bool DoneParsing() const; - long long ParseHeaders(); // stops when first cluster is found - // long FindNextCluster(long long& pos, long& size) const; - long LoadCluster(long long& pos, long& size); // load one cluster - long LoadCluster(); - - long ParseNext(const Cluster* pCurr, const Cluster*& pNext, long long& pos, - long& size); - - const SeekHead* GetSeekHead() const; - const Tracks* GetTracks() const; - const SegmentInfo* GetInfo() const; - const Cues* GetCues() const; - const Chapters* GetChapters() const; - const Tags* GetTags() const; - - long long GetDuration() const; - - unsigned long GetCount() const; - const Cluster* GetFirst() const; - const Cluster* GetLast() const; - const Cluster* GetNext(const Cluster*); - - const Cluster* FindCluster(long long time_nanoseconds) const; - // const BlockEntry* Seek(long long time_nanoseconds, const Track*) const; - - const Cluster* FindOrPreloadCluster(long long pos); - - long ParseCues(long long cues_off, // offset relative to start of segment - long long& parse_pos, long& parse_len); - - private: - long long m_pos; // absolute file posn; what has been consumed so far - Cluster* m_pUnknownSize; - - SeekHead* m_pSeekHead; - SegmentInfo* m_pInfo; - Tracks* m_pTracks; - Cues* m_pCues; - Chapters* m_pChapters; - Tags* m_pTags; - Cluster** m_clusters; - long m_clusterCount; // number of entries for which m_index >= 0 - long m_clusterPreloadCount; // number of entries for which m_index < 0 - long m_clusterSize; // array size - - long DoLoadCluster(long long&, long&); - long DoLoadClusterUnknownSize(long long&, long&); - long DoParseNext(const Cluster*&, long long&, long&); - - bool AppendCluster(Cluster*); - bool PreloadCluster(Cluster*, ptrdiff_t); - - // void ParseSeekHead(long long pos, long long size); - // void ParseSeekEntry(long long pos, long long size); - // void ParseCues(long long); - - const BlockEntry* GetBlock(const CuePoint&, const CuePoint::TrackPosition&); -}; - -} // namespace mkvparser - -inline long mkvparser::Segment::LoadCluster() { - long long pos; - long size; - - return LoadCluster(pos, size); -} - -#endif // MKVPARSER_MKVPARSER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvparser/mkvreader.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvparser/mkvreader.cc deleted file mode 100644 index 46726040..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvparser/mkvreader.cc +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) 2010 The WebM project authors. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -#include "mkvparser/mkvreader.h" - -#include - -#include - -namespace mkvparser { - -MkvReader::MkvReader() : m_file(NULL), reader_owns_file_(true) {} - -MkvReader::MkvReader(FILE* fp) : m_file(fp), reader_owns_file_(false) { - GetFileSize(); -} - -MkvReader::~MkvReader() { - if (reader_owns_file_) - Close(); - m_file = NULL; -} - -int MkvReader::Open(const char* fileName) { - if (fileName == NULL) - return -1; - - if (m_file) - return -1; - -#ifdef _MSC_VER - const errno_t e = fopen_s(&m_file, fileName, "rb"); - - if (e) - return -1; // error -#else - m_file = fopen(fileName, "rb"); - - if (m_file == NULL) - return -1; -#endif - return !GetFileSize(); -} - -bool MkvReader::GetFileSize() { - if (m_file == NULL) - return false; -#ifdef _MSC_VER - int status = _fseeki64(m_file, 0L, SEEK_END); - - if (status) - return false; // error - - m_length = _ftelli64(m_file); -#else - fseek(m_file, 0L, SEEK_END); - m_length = ftell(m_file); -#endif - assert(m_length >= 0); - - if (m_length < 0) - return false; - -#ifdef _MSC_VER - status = _fseeki64(m_file, 0L, SEEK_SET); - - if (status) - return false; // error -#else - fseek(m_file, 0L, SEEK_SET); -#endif - - return true; -} - -void MkvReader::Close() { - if (m_file != NULL) { - fclose(m_file); - m_file = NULL; - } -} - -int MkvReader::Length(long long* total, long long* available) { - if (m_file == NULL) - return -1; - - if (total) - *total = m_length; - - if (available) - *available = m_length; - - return 0; -} - -int MkvReader::Read(long long offset, long len, unsigned char* buffer) { - if (m_file == NULL) - return -1; - - if (offset < 0) - return -1; - - if (len < 0) - return -1; - - if (len == 0) - return 0; - - if (offset >= m_length) - return -1; - -#ifdef _MSC_VER - const int status = _fseeki64(m_file, offset, SEEK_SET); - - if (status) - return -1; // error -#elif defined(_WIN32) - fseeko64(m_file, static_cast(offset), SEEK_SET); -#elif !(defined(__ANDROID__) && __ANDROID_API__ < 24 && !defined(__LP64__) && \ - defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64) - // POSIX.1 has fseeko and ftello. fseeko and ftello are not available before - // Android API level 24. See - // https://android.googlesource.com/platform/bionic/+/main/docs/32-bit-abi.md - fseeko(m_file, static_cast(offset), SEEK_SET); -#else - fseek(m_file, static_cast(offset), SEEK_SET); -#endif - - const size_t size = fread(buffer, 1, len, m_file); - - if (size < size_t(len)) - return -1; // error - - return 0; // success -} - -} // namespace mkvparser diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvparser/mkvreader.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvparser/mkvreader.h deleted file mode 100644 index 9831ecf6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libwebm/mkvparser/mkvreader.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2010 The WebM project authors. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -#ifndef MKVPARSER_MKVREADER_H_ -#define MKVPARSER_MKVREADER_H_ - -#include - -#include "mkvparser/mkvparser.h" - -namespace mkvparser { - -class MkvReader : public IMkvReader { - public: - MkvReader(); - explicit MkvReader(FILE* fp); - virtual ~MkvReader(); - - int Open(const char*); - void Close(); - - virtual int Read(long long position, long length, unsigned char* buffer); - virtual int Length(long long* total, long long* available); - - private: - MkvReader(const MkvReader&); - MkvReader& operator=(const MkvReader&); - - // Determines the size of the file. This is called either by the constructor - // or by the Open function depending on file ownership. Returns true on - // success. - bool GetFileSize(); - - long long m_length; - FILE* m_file; - bool reader_owns_file_; -}; - -} // namespace mkvparser - -#endif // MKVPARSER_MKVREADER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/LICENSE b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/LICENSE deleted file mode 100644 index c911747a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -Copyright 2011 The LibYuv Project Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * Neither the name of Google nor the names of its contributors may - be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/README.libvpx b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/README.libvpx deleted file mode 100644 index 9519dc4b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/README.libvpx +++ /dev/null @@ -1,23 +0,0 @@ -Name: libyuv -URL: https://chromium.googlesource.com/libyuv/libyuv -Version: a37e7bfece9e0676ae90a1700b0ec85b0f4f22a1 -License: BSD -License File: LICENSE - -Description: -libyuv is an open source project that includes YUV conversion and scaling -functionality. - -The optimized scaler in libyuv is used in the multiple resolution encoder -example which down-samples the original input video (f.g. 1280x720) a number of -times in order to encode multiple resolution bit streams. - -Local Modifications: -Disable ARGBToRGB24Row_AVX512VBMI due to build failure on Mac. -rm libyuv/include/libyuv.h libyuv/include/libyuv/compare_row.h -mv libyuv/include tmp/ -mv libyuv/source tmp/ -mv libyuv/LICENSE tmp/ -rm -rf libyuv - -mv tmp/* third_party/libyuv/ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/basic_types.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/basic_types.h deleted file mode 100644 index 01d9dfc7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/basic_types.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_BASIC_TYPES_H_ -#define INCLUDE_LIBYUV_BASIC_TYPES_H_ - -#include // For size_t and NULL - -#if !defined(INT_TYPES_DEFINED) && !defined(GG_LONGLONG) -#define INT_TYPES_DEFINED - -#if defined(_MSC_VER) && (_MSC_VER < 1600) -#include // for uintptr_t on x86 -typedef unsigned __int64 uint64_t; -typedef __int64 int64_t; -typedef unsigned int uint32_t; -typedef int int32_t; -typedef unsigned short uint16_t; -typedef short int16_t; -typedef unsigned char uint8_t; -typedef signed char int8_t; -#else -#include // for uintptr_t and C99 types -#endif // defined(_MSC_VER) && (_MSC_VER < 1600) -typedef uint64_t uint64; -typedef int64_t int64; -typedef uint32_t uint32; -typedef int32_t int32; -typedef uint16_t uint16; -typedef int16_t int16; -typedef uint8_t uint8; -typedef int8_t int8; -#endif // INT_TYPES_DEFINED - -#if !defined(LIBYUV_API) -#if defined(_WIN32) || defined(__CYGWIN__) -#if defined(LIBYUV_BUILDING_SHARED_LIBRARY) -#define LIBYUV_API __declspec(dllexport) -#elif defined(LIBYUV_USING_SHARED_LIBRARY) -#define LIBYUV_API __declspec(dllimport) -#else -#define LIBYUV_API -#endif // LIBYUV_BUILDING_SHARED_LIBRARY -#elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__APPLE__) && \ - (defined(LIBYUV_BUILDING_SHARED_LIBRARY) || \ - defined(LIBYUV_USING_SHARED_LIBRARY)) -#define LIBYUV_API __attribute__((visibility("default"))) -#else -#define LIBYUV_API -#endif // __GNUC__ -#endif // LIBYUV_API - -// TODO(fbarchard): Remove bool macros. -#define LIBYUV_BOOL int -#define LIBYUV_FALSE 0 -#define LIBYUV_TRUE 1 - -#endif // INCLUDE_LIBYUV_BASIC_TYPES_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/compare.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/compare.h deleted file mode 100644 index 3353ad71..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/compare.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_COMPARE_H_ -#define INCLUDE_LIBYUV_COMPARE_H_ - -#include "libyuv/basic_types.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// Compute a hash for specified memory. Seed of 5381 recommended. -LIBYUV_API -uint32_t HashDjb2(const uint8_t* src, uint64_t count, uint32_t seed); - -// Hamming Distance -LIBYUV_API -uint64_t ComputeHammingDistance(const uint8_t* src_a, - const uint8_t* src_b, - int count); - -// Scan an opaque argb image and return fourcc based on alpha offset. -// Returns FOURCC_ARGB, FOURCC_BGRA, or 0 if unknown. -LIBYUV_API -uint32_t ARGBDetect(const uint8_t* argb, - int stride_argb, - int width, - int height); - -// Sum Square Error - used to compute Mean Square Error or PSNR. -LIBYUV_API -uint64_t ComputeSumSquareError(const uint8_t* src_a, - const uint8_t* src_b, - int count); - -LIBYUV_API -uint64_t ComputeSumSquareErrorPlane(const uint8_t* src_a, - int stride_a, - const uint8_t* src_b, - int stride_b, - int width, - int height); - -static const int kMaxPsnr = 128; - -LIBYUV_API -double SumSquareErrorToPsnr(uint64_t sse, uint64_t count); - -LIBYUV_API -double CalcFramePsnr(const uint8_t* src_a, - int stride_a, - const uint8_t* src_b, - int stride_b, - int width, - int height); - -LIBYUV_API -double I420Psnr(const uint8_t* src_y_a, - int stride_y_a, - const uint8_t* src_u_a, - int stride_u_a, - const uint8_t* src_v_a, - int stride_v_a, - const uint8_t* src_y_b, - int stride_y_b, - const uint8_t* src_u_b, - int stride_u_b, - const uint8_t* src_v_b, - int stride_v_b, - int width, - int height); - -LIBYUV_API -double CalcFrameSsim(const uint8_t* src_a, - int stride_a, - const uint8_t* src_b, - int stride_b, - int width, - int height); - -LIBYUV_API -double I420Ssim(const uint8_t* src_y_a, - int stride_y_a, - const uint8_t* src_u_a, - int stride_u_a, - const uint8_t* src_v_a, - int stride_v_a, - const uint8_t* src_y_b, - int stride_y_b, - const uint8_t* src_u_b, - int stride_u_b, - const uint8_t* src_v_b, - int stride_v_b, - int width, - int height); - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // INCLUDE_LIBYUV_COMPARE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/convert.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/convert.h deleted file mode 100644 index d12ef24f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/convert.h +++ /dev/null @@ -1,406 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_CONVERT_H_ -#define INCLUDE_LIBYUV_CONVERT_H_ - -#include "libyuv/basic_types.h" - -#include "libyuv/rotate.h" // For enum RotationMode. - -// TODO(fbarchard): fix WebRTC source to include following libyuv headers: -#include "libyuv/convert_argb.h" // For WebRTC I420ToARGB. b/620 -#include "libyuv/convert_from.h" // For WebRTC ConvertFromI420. b/620 -#include "libyuv/planar_functions.h" // For WebRTC I420Rect, CopyPlane. b/618 - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// Convert I444 to I420. -LIBYUV_API -int I444ToI420(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Convert I422 to I420. -LIBYUV_API -int I422ToI420(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Copy I420 to I420. -#define I420ToI420 I420Copy -LIBYUV_API -int I420Copy(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Copy I010 to I010 -#define I010ToI010 I010Copy -#define H010ToH010 I010Copy -LIBYUV_API -int I010Copy(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint16_t* dst_y, - int dst_stride_y, - uint16_t* dst_u, - int dst_stride_u, - uint16_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Convert 10 bit YUV to 8 bit -#define H010ToH420 I010ToI420 -LIBYUV_API -int I010ToI420(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Convert I400 (grey) to I420. -LIBYUV_API -int I400ToI420(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -#define J400ToJ420 I400ToI420 - -// Convert NV12 to I420. -LIBYUV_API -int NV12ToI420(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Convert NV21 to I420. -LIBYUV_API -int NV21ToI420(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_vu, - int src_stride_vu, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Convert YUY2 to I420. -LIBYUV_API -int YUY2ToI420(const uint8_t* src_yuy2, - int src_stride_yuy2, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Convert UYVY to I420. -LIBYUV_API -int UYVYToI420(const uint8_t* src_uyvy, - int src_stride_uyvy, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Convert M420 to I420. -LIBYUV_API -int M420ToI420(const uint8_t* src_m420, - int src_stride_m420, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Convert Android420 to I420. -LIBYUV_API -int Android420ToI420(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - int src_pixel_stride_uv, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// ARGB little endian (bgra in memory) to I420. -LIBYUV_API -int ARGBToI420(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// BGRA little endian (argb in memory) to I420. -LIBYUV_API -int BGRAToI420(const uint8_t* src_bgra, - int src_stride_bgra, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// ABGR little endian (rgba in memory) to I420. -LIBYUV_API -int ABGRToI420(const uint8_t* src_abgr, - int src_stride_abgr, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// RGBA little endian (abgr in memory) to I420. -LIBYUV_API -int RGBAToI420(const uint8_t* src_rgba, - int src_stride_rgba, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// RGB little endian (bgr in memory) to I420. -LIBYUV_API -int RGB24ToI420(const uint8_t* src_rgb24, - int src_stride_rgb24, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// RGB big endian (rgb in memory) to I420. -LIBYUV_API -int RAWToI420(const uint8_t* src_raw, - int src_stride_raw, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// RGB16 (RGBP fourcc) little endian to I420. -LIBYUV_API -int RGB565ToI420(const uint8_t* src_rgb565, - int src_stride_rgb565, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// RGB15 (RGBO fourcc) little endian to I420. -LIBYUV_API -int ARGB1555ToI420(const uint8_t* src_argb1555, - int src_stride_argb1555, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// RGB12 (R444 fourcc) little endian to I420. -LIBYUV_API -int ARGB4444ToI420(const uint8_t* src_argb4444, - int src_stride_argb4444, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -#ifdef HAVE_JPEG -// src_width/height provided by capture. -// dst_width/height for clipping determine final size. -LIBYUV_API -int MJPGToI420(const uint8_t* sample, - size_t sample_size, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int src_width, - int src_height, - int dst_width, - int dst_height); - -// Query size of MJPG in pixels. -LIBYUV_API -int MJPGSize(const uint8_t* sample, - size_t sample_size, - int* width, - int* height); -#endif - -// Convert camera sample to I420 with cropping, rotation and vertical flip. -// "src_size" is needed to parse MJPG. -// "dst_stride_y" number of bytes in a row of the dst_y plane. -// Normally this would be the same as dst_width, with recommended alignment -// to 16 bytes for better efficiency. -// If rotation of 90 or 270 is used, stride is affected. The caller should -// allocate the I420 buffer according to rotation. -// "dst_stride_u" number of bytes in a row of the dst_u plane. -// Normally this would be the same as (dst_width + 1) / 2, with -// recommended alignment to 16 bytes for better efficiency. -// If rotation of 90 or 270 is used, stride is affected. -// "crop_x" and "crop_y" are starting position for cropping. -// To center, crop_x = (src_width - dst_width) / 2 -// crop_y = (src_height - dst_height) / 2 -// "src_width" / "src_height" is size of src_frame in pixels. -// "src_height" can be negative indicating a vertically flipped image source. -// "crop_width" / "crop_height" is the size to crop the src to. -// Must be less than or equal to src_width/src_height -// Cropping parameters are pre-rotation. -// "rotation" can be 0, 90, 180 or 270. -// "fourcc" is a fourcc. ie 'I420', 'YUY2' -// Returns 0 for successful; -1 for invalid parameter. Non-zero for failure. -LIBYUV_API -int ConvertToI420(const uint8_t* sample, - size_t sample_size, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int crop_x, - int crop_y, - int src_width, - int src_height, - int crop_width, - int crop_height, - enum RotationMode rotation, - uint32_t fourcc); - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // INCLUDE_LIBYUV_CONVERT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/convert_argb.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/convert_argb.h deleted file mode 100644 index ab772b6c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/convert_argb.h +++ /dev/null @@ -1,687 +0,0 @@ -/* - * Copyright 2012 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_CONVERT_ARGB_H_ -#define INCLUDE_LIBYUV_CONVERT_ARGB_H_ - -#include "libyuv/basic_types.h" - -#include "libyuv/rotate.h" // For enum RotationMode. - -// TODO(fbarchard): This set of functions should exactly match convert.h -// TODO(fbarchard): Add tests. Create random content of right size and convert -// with C vs Opt and or to I420 and compare. -// TODO(fbarchard): Some of these functions lack parameter setting. - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// Alias. -#define ARGBToARGB ARGBCopy - -// Copy ARGB to ARGB. -LIBYUV_API -int ARGBCopy(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert I420 to ARGB. -LIBYUV_API -int I420ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Duplicate prototype for function in convert_from.h for remoting. -LIBYUV_API -int I420ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height); - -// Convert I010 to ARGB. -LIBYUV_API -int I010ToARGB(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert I010 to ARGB. -LIBYUV_API -int I010ToARGB(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert I010 to ABGR. -LIBYUV_API -int I010ToABGR(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height); - -// Convert H010 to ARGB. -LIBYUV_API -int H010ToARGB(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert H010 to ABGR. -LIBYUV_API -int H010ToABGR(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height); - -// Convert I422 to ARGB. -LIBYUV_API -int I422ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert I444 to ARGB. -LIBYUV_API -int I444ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert J444 to ARGB. -LIBYUV_API -int J444ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert I444 to ABGR. -LIBYUV_API -int I444ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height); - -// Convert I420 with Alpha to preattenuated ARGB. -LIBYUV_API -int I420AlphaToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - const uint8_t* src_a, - int src_stride_a, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height, - int attenuate); - -// Convert I420 with Alpha to preattenuated ABGR. -LIBYUV_API -int I420AlphaToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - const uint8_t* src_a, - int src_stride_a, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height, - int attenuate); - -// Convert I400 (grey) to ARGB. Reverse of ARGBToI400. -LIBYUV_API -int I400ToARGB(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert J400 (jpeg grey) to ARGB. -LIBYUV_API -int J400ToARGB(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Alias. -#define YToARGB I400ToARGB - -// Convert NV12 to ARGB. -LIBYUV_API -int NV12ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert NV21 to ARGB. -LIBYUV_API -int NV21ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_vu, - int src_stride_vu, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert NV12 to ABGR. -int NV12ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height); - -// Convert NV21 to ABGR. -LIBYUV_API -int NV21ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_vu, - int src_stride_vu, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height); - -// Convert NV12 to RGB24. -LIBYUV_API -int NV12ToRGB24(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height); - -// Convert NV21 to RGB24. -LIBYUV_API -int NV21ToRGB24(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_vu, - int src_stride_vu, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height); - -// Convert M420 to ARGB. -LIBYUV_API -int M420ToARGB(const uint8_t* src_m420, - int src_stride_m420, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert YUY2 to ARGB. -LIBYUV_API -int YUY2ToARGB(const uint8_t* src_yuy2, - int src_stride_yuy2, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert UYVY to ARGB. -LIBYUV_API -int UYVYToARGB(const uint8_t* src_uyvy, - int src_stride_uyvy, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert J420 to ARGB. -LIBYUV_API -int J420ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert J422 to ARGB. -LIBYUV_API -int J422ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert J420 to ABGR. -LIBYUV_API -int J420ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height); - -// Convert J422 to ABGR. -LIBYUV_API -int J422ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height); - -// Convert H420 to ARGB. -LIBYUV_API -int H420ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert H422 to ARGB. -LIBYUV_API -int H422ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert H420 to ABGR. -LIBYUV_API -int H420ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height); - -// Convert H422 to ABGR. -LIBYUV_API -int H422ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height); - -// Convert H010 to ARGB. -LIBYUV_API -int H010ToARGB(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert I010 to AR30. -LIBYUV_API -int I010ToAR30(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_ar30, - int dst_stride_ar30, - int width, - int height); - -// Convert H010 to AR30. -LIBYUV_API -int H010ToAR30(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_ar30, - int dst_stride_ar30, - int width, - int height); - -// Convert I010 to AB30. -LIBYUV_API -int I010ToAB30(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_ab30, - int dst_stride_ab30, - int width, - int height); - -// Convert H010 to AB30. -LIBYUV_API -int H010ToAB30(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_ab30, - int dst_stride_ab30, - int width, - int height); - -// BGRA little endian (argb in memory) to ARGB. -LIBYUV_API -int BGRAToARGB(const uint8_t* src_bgra, - int src_stride_bgra, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// ABGR little endian (rgba in memory) to ARGB. -LIBYUV_API -int ABGRToARGB(const uint8_t* src_abgr, - int src_stride_abgr, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// RGBA little endian (abgr in memory) to ARGB. -LIBYUV_API -int RGBAToARGB(const uint8_t* src_rgba, - int src_stride_rgba, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Deprecated function name. -#define BG24ToARGB RGB24ToARGB - -// RGB little endian (bgr in memory) to ARGB. -LIBYUV_API -int RGB24ToARGB(const uint8_t* src_rgb24, - int src_stride_rgb24, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// RGB big endian (rgb in memory) to ARGB. -LIBYUV_API -int RAWToARGB(const uint8_t* src_raw, - int src_stride_raw, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// RGB16 (RGBP fourcc) little endian to ARGB. -LIBYUV_API -int RGB565ToARGB(const uint8_t* src_rgb565, - int src_stride_rgb565, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// RGB15 (RGBO fourcc) little endian to ARGB. -LIBYUV_API -int ARGB1555ToARGB(const uint8_t* src_argb1555, - int src_stride_argb1555, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// RGB12 (R444 fourcc) little endian to ARGB. -LIBYUV_API -int ARGB4444ToARGB(const uint8_t* src_argb4444, - int src_stride_argb4444, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Aliases -#define AB30ToARGB AR30ToABGR -#define AB30ToABGR AR30ToARGB -#define AB30ToAR30 AR30ToAB30 - -// Convert AR30 To ARGB. -LIBYUV_API -int AR30ToARGB(const uint8_t* src_ar30, - int src_stride_ar30, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert AR30 To ABGR. -LIBYUV_API -int AR30ToABGR(const uint8_t* src_ar30, - int src_stride_ar30, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height); - -// Convert AR30 To AB30. -LIBYUV_API -int AR30ToAB30(const uint8_t* src_ar30, - int src_stride_ar30, - uint8_t* dst_ab30, - int dst_stride_ab30, - int width, - int height); - -#ifdef HAVE_JPEG -// src_width/height provided by capture -// dst_width/height for clipping determine final size. -LIBYUV_API -int MJPGToARGB(const uint8_t* sample, - size_t sample_size, - uint8_t* dst_argb, - int dst_stride_argb, - int src_width, - int src_height, - int dst_width, - int dst_height); -#endif - -// Convert Android420 to ARGB. -LIBYUV_API -int Android420ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - int src_pixel_stride_uv, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert Android420 to ABGR. -LIBYUV_API -int Android420ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - int src_pixel_stride_uv, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height); - -// Convert camera sample to ARGB with cropping, rotation and vertical flip. -// "sample_size" is needed to parse MJPG. -// "dst_stride_argb" number of bytes in a row of the dst_argb plane. -// Normally this would be the same as dst_width, with recommended alignment -// to 16 bytes for better efficiency. -// If rotation of 90 or 270 is used, stride is affected. The caller should -// allocate the I420 buffer according to rotation. -// "dst_stride_u" number of bytes in a row of the dst_u plane. -// Normally this would be the same as (dst_width + 1) / 2, with -// recommended alignment to 16 bytes for better efficiency. -// If rotation of 90 or 270 is used, stride is affected. -// "crop_x" and "crop_y" are starting position for cropping. -// To center, crop_x = (src_width - dst_width) / 2 -// crop_y = (src_height - dst_height) / 2 -// "src_width" / "src_height" is size of src_frame in pixels. -// "src_height" can be negative indicating a vertically flipped image source. -// "crop_width" / "crop_height" is the size to crop the src to. -// Must be less than or equal to src_width/src_height -// Cropping parameters are pre-rotation. -// "rotation" can be 0, 90, 180 or 270. -// "fourcc" is a fourcc. ie 'I420', 'YUY2' -// Returns 0 for successful; -1 for invalid parameter. Non-zero for failure. -LIBYUV_API -int ConvertToARGB(const uint8_t* sample, - size_t sample_size, - uint8_t* dst_argb, - int dst_stride_argb, - int crop_x, - int crop_y, - int src_width, - int src_height, - int crop_width, - int crop_height, - enum RotationMode rotation, - uint32_t fourcc); - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // INCLUDE_LIBYUV_CONVERT_ARGB_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/convert_from.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/convert_from.h deleted file mode 100644 index 5cd8a4bf..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/convert_from.h +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_CONVERT_FROM_H_ -#define INCLUDE_LIBYUV_CONVERT_FROM_H_ - -#include "libyuv/basic_types.h" -#include "libyuv/rotate.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// See Also convert.h for conversions from formats to I420. - -// Convert 8 bit YUV to 10 bit. -#define H420ToH010 I420ToI010 -int I420ToI010(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint16_t* dst_y, - int dst_stride_y, - uint16_t* dst_u, - int dst_stride_u, - uint16_t* dst_v, - int dst_stride_v, - int width, - int height); - -LIBYUV_API -int I420ToI422(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -LIBYUV_API -int I420ToI444(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Copy to I400. Source can be I420, I422, I444, I400, NV12 or NV21. -LIBYUV_API -int I400Copy(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height); - -LIBYUV_API -int I420ToNV12(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_uv, - int dst_stride_uv, - int width, - int height); - -LIBYUV_API -int I420ToNV21(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_vu, - int dst_stride_vu, - int width, - int height); - -LIBYUV_API -int I420ToYUY2(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_yuy2, - int dst_stride_yuy2, - int width, - int height); - -LIBYUV_API -int I420ToUYVY(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_uyvy, - int dst_stride_uyvy, - int width, - int height); - -LIBYUV_API -int I420ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -LIBYUV_API -int I420ToBGRA(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_bgra, - int dst_stride_bgra, - int width, - int height); - -LIBYUV_API -int I420ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height); - -LIBYUV_API -int I420ToRGBA(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgba, - int dst_stride_rgba, - int width, - int height); - -LIBYUV_API -int I420ToRGB24(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height); - -LIBYUV_API -int I420ToRAW(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_raw, - int dst_stride_raw, - int width, - int height); - -LIBYUV_API -int H420ToRGB24(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height); - -LIBYUV_API -int H420ToRAW(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_raw, - int dst_stride_raw, - int width, - int height); - -LIBYUV_API -int I420ToRGB565(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - int width, - int height); - -LIBYUV_API -int I422ToRGB565(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - int width, - int height); - -// Convert I420 To RGB565 with 4x4 dither matrix (16 bytes). -// Values in dither matrix from 0 to 7 recommended. -// The order of the dither matrix is first byte is upper left. - -LIBYUV_API -int I420ToRGB565Dither(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - const uint8_t* dither4x4, - int width, - int height); - -LIBYUV_API -int I420ToARGB1555(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb1555, - int dst_stride_argb1555, - int width, - int height); - -LIBYUV_API -int I420ToARGB4444(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb4444, - int dst_stride_argb4444, - int width, - int height); - -// Convert I420 to AR30. -LIBYUV_API -int I420ToAR30(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_ar30, - int dst_stride_ar30, - int width, - int height); - -// Convert H420 to AR30. -LIBYUV_API -int H420ToAR30(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_ar30, - int dst_stride_ar30, - int width, - int height); - -// Convert I420 to specified format. -// "dst_sample_stride" is bytes in a row for the destination. Pass 0 if the -// buffer has contiguous rows. Can be negative. A multiple of 16 is optimal. -LIBYUV_API -int ConvertFromI420(const uint8_t* y, - int y_stride, - const uint8_t* u, - int u_stride, - const uint8_t* v, - int v_stride, - uint8_t* dst_sample, - int dst_sample_stride, - int width, - int height, - uint32_t fourcc); - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // INCLUDE_LIBYUV_CONVERT_FROM_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/convert_from_argb.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/convert_from_argb.h deleted file mode 100644 index 05c815a0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/convert_from_argb.h +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright 2012 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_ -#define INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_ - -#include "libyuv/basic_types.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// Copy ARGB to ARGB. -#define ARGBToARGB ARGBCopy -LIBYUV_API -int ARGBCopy(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert ARGB To BGRA. -LIBYUV_API -int ARGBToBGRA(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_bgra, - int dst_stride_bgra, - int width, - int height); - -// Convert ARGB To ABGR. -LIBYUV_API -int ARGBToABGR(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height); - -// Convert ARGB To RGBA. -LIBYUV_API -int ARGBToRGBA(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_rgba, - int dst_stride_rgba, - int width, - int height); - -// Aliases -#define ARGBToAB30 ABGRToAR30 -#define ABGRToAB30 ARGBToAR30 - -// Convert ABGR To AR30. -LIBYUV_API -int ABGRToAR30(const uint8_t* src_abgr, - int src_stride_abgr, - uint8_t* dst_ar30, - int dst_stride_ar30, - int width, - int height); - -// Convert ARGB To AR30. -LIBYUV_API -int ARGBToAR30(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_ar30, - int dst_stride_ar30, - int width, - int height); - -// Convert ARGB To RGB24. -LIBYUV_API -int ARGBToRGB24(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height); - -// Convert ARGB To RAW. -LIBYUV_API -int ARGBToRAW(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_raw, - int dst_stride_raw, - int width, - int height); - -// Convert ARGB To RGB565. -LIBYUV_API -int ARGBToRGB565(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - int width, - int height); - -// Convert ARGB To RGB565 with 4x4 dither matrix (16 bytes). -// Values in dither matrix from 0 to 7 recommended. -// The order of the dither matrix is first byte is upper left. -// TODO(fbarchard): Consider pointer to 2d array for dither4x4. -// const uint8_t(*dither)[4][4]; -LIBYUV_API -int ARGBToRGB565Dither(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - const uint8_t* dither4x4, - int width, - int height); - -// Convert ARGB To ARGB1555. -LIBYUV_API -int ARGBToARGB1555(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb1555, - int dst_stride_argb1555, - int width, - int height); - -// Convert ARGB To ARGB4444. -LIBYUV_API -int ARGBToARGB4444(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb4444, - int dst_stride_argb4444, - int width, - int height); - -// Convert ARGB To I444. -LIBYUV_API -int ARGBToI444(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Convert ARGB To I422. -LIBYUV_API -int ARGBToI422(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Convert ARGB To I420. (also in convert.h) -LIBYUV_API -int ARGBToI420(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Convert ARGB to J420. (JPeg full range I420). -LIBYUV_API -int ARGBToJ420(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_yj, - int dst_stride_yj, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Convert ARGB to J422. -LIBYUV_API -int ARGBToJ422(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_yj, - int dst_stride_yj, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Convert ARGB to J400. (JPeg full range). -LIBYUV_API -int ARGBToJ400(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_yj, - int dst_stride_yj, - int width, - int height); - -// Convert ARGB to I400. -LIBYUV_API -int ARGBToI400(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height); - -// Convert ARGB to G. (Reverse of J400toARGB, which replicates G back to ARGB) -LIBYUV_API -int ARGBToG(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_g, - int dst_stride_g, - int width, - int height); - -// Convert ARGB To NV12. -LIBYUV_API -int ARGBToNV12(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_uv, - int dst_stride_uv, - int width, - int height); - -// Convert ARGB To NV21. -LIBYUV_API -int ARGBToNV21(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_vu, - int dst_stride_vu, - int width, - int height); - -// Convert ARGB To NV21. -LIBYUV_API -int ARGBToNV21(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_vu, - int dst_stride_vu, - int width, - int height); - -// Convert ARGB To YUY2. -LIBYUV_API -int ARGBToYUY2(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_yuy2, - int dst_stride_yuy2, - int width, - int height); - -// Convert ARGB To UYVY. -LIBYUV_API -int ARGBToUYVY(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_uyvy, - int dst_stride_uyvy, - int width, - int height); - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/cpu_id.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/cpu_id.h deleted file mode 100644 index 0229cb5e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/cpu_id.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_CPU_ID_H_ -#define INCLUDE_LIBYUV_CPU_ID_H_ - -#include "libyuv/basic_types.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// Internal flag to indicate cpuid requires initialization. -static const int kCpuInitialized = 0x1; - -// These flags are only valid on ARM processors. -static const int kCpuHasARM = 0x2; -static const int kCpuHasNEON = 0x4; -// 0x8 reserved for future ARM flag. - -// These flags are only valid on x86 processors. -static const int kCpuHasX86 = 0x10; -static const int kCpuHasSSE2 = 0x20; -static const int kCpuHasSSSE3 = 0x40; -static const int kCpuHasSSE41 = 0x80; -static const int kCpuHasSSE42 = 0x100; // unused at this time. -static const int kCpuHasAVX = 0x200; -static const int kCpuHasAVX2 = 0x400; -static const int kCpuHasERMS = 0x800; -static const int kCpuHasFMA3 = 0x1000; -static const int kCpuHasF16C = 0x2000; -static const int kCpuHasGFNI = 0x4000; -static const int kCpuHasAVX512BW = 0x8000; -static const int kCpuHasAVX512VL = 0x10000; -static const int kCpuHasAVX512VBMI = 0x20000; -static const int kCpuHasAVX512VBMI2 = 0x40000; -static const int kCpuHasAVX512VBITALG = 0x80000; -static const int kCpuHasAVX512VPOPCNTDQ = 0x100000; - -// These flags are only valid on MIPS processors. -static const int kCpuHasMIPS = 0x200000; -static const int kCpuHasMSA = 0x400000; - -// Optional init function. TestCpuFlag does an auto-init. -// Returns cpu_info flags. -LIBYUV_API -int InitCpuFlags(void); - -// Detect CPU has SSE2 etc. -// Test_flag parameter should be one of kCpuHas constants above. -// Returns non-zero if instruction set is detected -static __inline int TestCpuFlag(int test_flag) { - LIBYUV_API extern int cpu_info_; -#ifdef __ATOMIC_RELAXED - int cpu_info = __atomic_load_n(&cpu_info_, __ATOMIC_RELAXED); -#else - int cpu_info = cpu_info_; -#endif - return (!cpu_info ? InitCpuFlags() : cpu_info) & test_flag; -} - -// Internal function for parsing /proc/cpuinfo. -LIBYUV_API -int ArmCpuCaps(const char* cpuinfo_name); - -// For testing, allow CPU flags to be disabled. -// ie MaskCpuFlags(~kCpuHasSSSE3) to disable SSSE3. -// MaskCpuFlags(-1) to enable all cpu specific optimizations. -// MaskCpuFlags(1) to disable all cpu specific optimizations. -// MaskCpuFlags(0) to reset state so next call will auto init. -// Returns cpu_info flags. -LIBYUV_API -int MaskCpuFlags(int enable_flags); - -// Sets the CPU flags to |cpu_flags|, bypassing the detection code. |cpu_flags| -// should be a valid combination of the kCpuHas constants above and include -// kCpuInitialized. Use this method when running in a sandboxed process where -// the detection code might fail (as it might access /proc/cpuinfo). In such -// cases the cpu_info can be obtained from a non sandboxed process by calling -// InitCpuFlags() and passed to the sandboxed process (via command line -// parameters, IPC...) which can then call this method to initialize the CPU -// flags. -// Notes: -// - when specifying 0 for |cpu_flags|, the auto initialization is enabled -// again. -// - enabling CPU features that are not supported by the CPU will result in -// undefined behavior. -// TODO(fbarchard): consider writing a helper function that translates from -// other library CPU info to libyuv CPU info and add a .md doc that explains -// CPU detection. -static __inline void SetCpuFlags(int cpu_flags) { - LIBYUV_API extern int cpu_info_; -#ifdef __ATOMIC_RELAXED - __atomic_store_n(&cpu_info_, cpu_flags, __ATOMIC_RELAXED); -#else - cpu_info_ = cpu_flags; -#endif -} - -// Low level cpuid for X86. Returns zeros on other CPUs. -// eax is the info type that you want. -// ecx is typically the cpu number, and should normally be zero. -LIBYUV_API -void CpuId(int info_eax, int info_ecx, int* cpu_info); - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // INCLUDE_LIBYUV_CPU_ID_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/macros_msa.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/macros_msa.h deleted file mode 100644 index bba0e8ae..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/macros_msa.h +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2016 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_MACROS_MSA_H_ -#define INCLUDE_LIBYUV_MACROS_MSA_H_ - -#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) -#include -#include - -#if (__mips_isa_rev >= 6) -#define LW(psrc) \ - ({ \ - const uint8_t* psrc_lw_m = (const uint8_t*)(psrc); \ - uint32_t val_m; \ - asm volatile("lw %[val_m], %[psrc_lw_m] \n" \ - : [val_m] "=r"(val_m) \ - : [psrc_lw_m] "m"(*psrc_lw_m)); \ - val_m; \ - }) - -#if (__mips == 64) -#define LD(psrc) \ - ({ \ - const uint8_t* psrc_ld_m = (const uint8_t*)(psrc); \ - uint64_t val_m = 0; \ - asm volatile("ld %[val_m], %[psrc_ld_m] \n" \ - : [val_m] "=r"(val_m) \ - : [psrc_ld_m] "m"(*psrc_ld_m)); \ - val_m; \ - }) -#else // !(__mips == 64) -#define LD(psrc) \ - ({ \ - const uint8_t* psrc_ld_m = (const uint8_t*)(psrc); \ - uint32_t val0_m, val1_m; \ - uint64_t val_m = 0; \ - val0_m = LW(psrc_ld_m); \ - val1_m = LW(psrc_ld_m + 4); \ - val_m = (uint64_t)(val1_m); /* NOLINT */ \ - val_m = (uint64_t)((val_m << 32) & 0xFFFFFFFF00000000); /* NOLINT */ \ - val_m = (uint64_t)(val_m | (uint64_t)val0_m); /* NOLINT */ \ - val_m; \ - }) -#endif // (__mips == 64) - -#define SW(val, pdst) \ - ({ \ - uint8_t* pdst_sw_m = (uint8_t*)(pdst); /* NOLINT */ \ - uint32_t val_m = (val); \ - asm volatile("sw %[val_m], %[pdst_sw_m] \n" \ - : [pdst_sw_m] "=m"(*pdst_sw_m) \ - : [val_m] "r"(val_m)); \ - }) - -#if (__mips == 64) -#define SD(val, pdst) \ - ({ \ - uint8_t* pdst_sd_m = (uint8_t*)(pdst); /* NOLINT */ \ - uint64_t val_m = (val); \ - asm volatile("sd %[val_m], %[pdst_sd_m] \n" \ - : [pdst_sd_m] "=m"(*pdst_sd_m) \ - : [val_m] "r"(val_m)); \ - }) -#else // !(__mips == 64) -#define SD(val, pdst) \ - ({ \ - uint8_t* pdst_sd_m = (uint8_t*)(pdst); /* NOLINT */ \ - uint32_t val0_m, val1_m; \ - val0_m = (uint32_t)((val)&0x00000000FFFFFFFF); \ - val1_m = (uint32_t)(((val) >> 32) & 0x00000000FFFFFFFF); \ - SW(val0_m, pdst_sd_m); \ - SW(val1_m, pdst_sd_m + 4); \ - }) -#endif // !(__mips == 64) -#else // !(__mips_isa_rev >= 6) -#define LW(psrc) \ - ({ \ - const uint8_t* psrc_lw_m = (const uint8_t*)(psrc); \ - uint32_t val_m; \ - asm volatile("ulw %[val_m], %[psrc_lw_m] \n" \ - : [val_m] "=r"(val_m) \ - : [psrc_lw_m] "m"(*psrc_lw_m)); \ - val_m; \ - }) - -#if (__mips == 64) -#define LD(psrc) \ - ({ \ - const uint8_t* psrc_ld_m = (const uint8_t*)(psrc); \ - uint64_t val_m = 0; \ - asm volatile("uld %[val_m], %[psrc_ld_m] \n" \ - : [val_m] "=r"(val_m) \ - : [psrc_ld_m] "m"(*psrc_ld_m)); \ - val_m; \ - }) -#else // !(__mips == 64) -#define LD(psrc) \ - ({ \ - const uint8_t* psrc_ld_m = (const uint8_t*)(psrc); \ - uint32_t val0_m, val1_m; \ - uint64_t val_m = 0; \ - val0_m = LW(psrc_ld_m); \ - val1_m = LW(psrc_ld_m + 4); \ - val_m = (uint64_t)(val1_m); /* NOLINT */ \ - val_m = (uint64_t)((val_m << 32) & 0xFFFFFFFF00000000); /* NOLINT */ \ - val_m = (uint64_t)(val_m | (uint64_t)val0_m); /* NOLINT */ \ - val_m; \ - }) -#endif // (__mips == 64) - -#define SW(val, pdst) \ - ({ \ - uint8_t* pdst_sw_m = (uint8_t*)(pdst); /* NOLINT */ \ - uint32_t val_m = (val); \ - asm volatile("usw %[val_m], %[pdst_sw_m] \n" \ - : [pdst_sw_m] "=m"(*pdst_sw_m) \ - : [val_m] "r"(val_m)); \ - }) - -#define SD(val, pdst) \ - ({ \ - uint8_t* pdst_sd_m = (uint8_t*)(pdst); /* NOLINT */ \ - uint32_t val0_m, val1_m; \ - val0_m = (uint32_t)((val)&0x00000000FFFFFFFF); \ - val1_m = (uint32_t)(((val) >> 32) & 0x00000000FFFFFFFF); \ - SW(val0_m, pdst_sd_m); \ - SW(val1_m, pdst_sd_m + 4); \ - }) -#endif // (__mips_isa_rev >= 6) - -// TODO(fbarchard): Consider removing __VAR_ARGS versions. -#define LD_B(RTYPE, psrc) *((RTYPE*)(psrc)) /* NOLINT */ -#define LD_UB(...) LD_B(const v16u8, __VA_ARGS__) - -#define ST_B(RTYPE, in, pdst) *((RTYPE*)(pdst)) = (in) /* NOLINT */ -#define ST_UB(...) ST_B(v16u8, __VA_ARGS__) - -#define ST_H(RTYPE, in, pdst) *((RTYPE*)(pdst)) = (in) /* NOLINT */ -#define ST_UH(...) ST_H(v8u16, __VA_ARGS__) - -/* Description : Load two vectors with 16 'byte' sized elements - Arguments : Inputs - psrc, stride - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Load 16 byte elements in 'out0' from (psrc) - Load 16 byte elements in 'out1' from (psrc + stride) -*/ -#define LD_B2(RTYPE, psrc, stride, out0, out1) \ - { \ - out0 = LD_B(RTYPE, (psrc)); \ - out1 = LD_B(RTYPE, (psrc) + stride); \ - } -#define LD_UB2(...) LD_B2(const v16u8, __VA_ARGS__) - -#define LD_B4(RTYPE, psrc, stride, out0, out1, out2, out3) \ - { \ - LD_B2(RTYPE, (psrc), stride, out0, out1); \ - LD_B2(RTYPE, (psrc) + 2 * stride, stride, out2, out3); \ - } -#define LD_UB4(...) LD_B4(const v16u8, __VA_ARGS__) - -/* Description : Store two vectors with stride each having 16 'byte' sized - elements - Arguments : Inputs - in0, in1, pdst, stride - Details : Store 16 byte elements from 'in0' to (pdst) - Store 16 byte elements from 'in1' to (pdst + stride) -*/ -#define ST_B2(RTYPE, in0, in1, pdst, stride) \ - { \ - ST_B(RTYPE, in0, (pdst)); \ - ST_B(RTYPE, in1, (pdst) + stride); \ - } -#define ST_UB2(...) ST_B2(v16u8, __VA_ARGS__) - -#define ST_B4(RTYPE, in0, in1, in2, in3, pdst, stride) \ - { \ - ST_B2(RTYPE, in0, in1, (pdst), stride); \ - ST_B2(RTYPE, in2, in3, (pdst) + 2 * stride, stride); \ - } -#define ST_UB4(...) ST_B4(v16u8, __VA_ARGS__) - -/* Description : Store vectors of 8 halfword elements with stride - Arguments : Inputs - in0, in1, pdst, stride - Details : Store 8 halfword elements from 'in0' to (pdst) - Store 8 halfword elements from 'in1' to (pdst + stride) -*/ -#define ST_H2(RTYPE, in0, in1, pdst, stride) \ - { \ - ST_H(RTYPE, in0, (pdst)); \ - ST_H(RTYPE, in1, (pdst) + stride); \ - } -#define ST_UH2(...) ST_H2(v8u16, __VA_ARGS__) - -// TODO(fbarchard): Consider using __msa_vshf_b and __msa_ilvr_b directly. -/* Description : Shuffle byte vector elements as per mask vector - Arguments : Inputs - in0, in1, in2, in3, mask0, mask1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Byte elements from 'in0' & 'in1' are copied selectively to - 'out0' as per control vector 'mask0' -*/ -#define VSHF_B2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_vshf_b((v16i8)mask0, (v16i8)in1, (v16i8)in0); \ - out1 = (RTYPE)__msa_vshf_b((v16i8)mask1, (v16i8)in3, (v16i8)in2); \ - } -#define VSHF_B2_UB(...) VSHF_B2(v16u8, __VA_ARGS__) - -/* Description : Interleave both left and right half of input vectors - Arguments : Inputs - in0, in1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Right half of byte elements from 'in0' and 'in1' are - interleaved and written to 'out0' -*/ -#define ILVRL_B2(RTYPE, in0, in1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvr_b((v16i8)in0, (v16i8)in1); \ - out1 = (RTYPE)__msa_ilvl_b((v16i8)in0, (v16i8)in1); \ - } -#define ILVRL_B2_UB(...) ILVRL_B2(v16u8, __VA_ARGS__) - -#endif /* !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) */ - -#endif // INCLUDE_LIBYUV_MACROS_MSA_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/mjpeg_decoder.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/mjpeg_decoder.h deleted file mode 100644 index 275f8d4c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/mjpeg_decoder.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright 2012 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_MJPEG_DECODER_H_ -#define INCLUDE_LIBYUV_MJPEG_DECODER_H_ - -#include "libyuv/basic_types.h" - -#ifdef __cplusplus -// NOTE: For a simplified public API use convert.h MJPGToI420(). - -struct jpeg_common_struct; -struct jpeg_decompress_struct; -struct jpeg_source_mgr; - -namespace libyuv { - -#ifdef __cplusplus -extern "C" { -#endif - -LIBYUV_BOOL ValidateJpeg(const uint8_t* sample, size_t sample_size); - -#ifdef __cplusplus -} // extern "C" -#endif - -static const uint32_t kUnknownDataSize = 0xFFFFFFFF; - -enum JpegSubsamplingType { - kJpegYuv420, - kJpegYuv422, - kJpegYuv444, - kJpegYuv400, - kJpegUnknown -}; - -struct Buffer { - const uint8_t* data; - int len; -}; - -struct BufferVector { - Buffer* buffers; - int len; - int pos; -}; - -struct SetJmpErrorMgr; - -// MJPEG ("Motion JPEG") is a pseudo-standard video codec where the frames are -// simply independent JPEG images with a fixed huffman table (which is omitted). -// It is rarely used in video transmission, but is common as a camera capture -// format, especially in Logitech devices. This class implements a decoder for -// MJPEG frames. -// -// See http://tools.ietf.org/html/rfc2435 -class LIBYUV_API MJpegDecoder { - public: - typedef void (*CallbackFunction)(void* opaque, - const uint8_t* const* data, - const int* strides, - int rows); - - static const int kColorSpaceUnknown; - static const int kColorSpaceGrayscale; - static const int kColorSpaceRgb; - static const int kColorSpaceYCbCr; - static const int kColorSpaceCMYK; - static const int kColorSpaceYCCK; - - MJpegDecoder(); - ~MJpegDecoder(); - - // Loads a new frame, reads its headers, and determines the uncompressed - // image format. - // Returns LIBYUV_TRUE if image looks valid and format is supported. - // If return value is LIBYUV_TRUE, then the values for all the following - // getters are populated. - // src_len is the size of the compressed mjpeg frame in bytes. - LIBYUV_BOOL LoadFrame(const uint8_t* src, size_t src_len); - - // Returns width of the last loaded frame in pixels. - int GetWidth(); - - // Returns height of the last loaded frame in pixels. - int GetHeight(); - - // Returns format of the last loaded frame. The return value is one of the - // kColorSpace* constants. - int GetColorSpace(); - - // Number of color components in the color space. - int GetNumComponents(); - - // Sample factors of the n-th component. - int GetHorizSampFactor(int component); - - int GetVertSampFactor(int component); - - int GetHorizSubSampFactor(int component); - - int GetVertSubSampFactor(int component); - - // Public for testability. - int GetImageScanlinesPerImcuRow(); - - // Public for testability. - int GetComponentScanlinesPerImcuRow(int component); - - // Width of a component in bytes. - int GetComponentWidth(int component); - - // Height of a component. - int GetComponentHeight(int component); - - // Width of a component in bytes with padding for DCTSIZE. Public for testing. - int GetComponentStride(int component); - - // Size of a component in bytes. - int GetComponentSize(int component); - - // Call this after LoadFrame() if you decide you don't want to decode it - // after all. - LIBYUV_BOOL UnloadFrame(); - - // Decodes the entire image into a one-buffer-per-color-component format. - // dst_width must match exactly. dst_height must be <= to image height; if - // less, the image is cropped. "planes" must have size equal to at least - // GetNumComponents() and they must point to non-overlapping buffers of size - // at least GetComponentSize(i). The pointers in planes are incremented - // to point to after the end of the written data. - // TODO(fbarchard): Add dst_x, dst_y to allow specific rect to be decoded. - LIBYUV_BOOL DecodeToBuffers(uint8_t** planes, int dst_width, int dst_height); - - // Decodes the entire image and passes the data via repeated calls to a - // callback function. Each call will get the data for a whole number of - // image scanlines. - // TODO(fbarchard): Add dst_x, dst_y to allow specific rect to be decoded. - LIBYUV_BOOL DecodeToCallback(CallbackFunction fn, - void* opaque, - int dst_width, - int dst_height); - - // The helper function which recognizes the jpeg sub-sampling type. - static JpegSubsamplingType JpegSubsamplingTypeHelper( - int* subsample_x, - int* subsample_y, - int number_of_components); - - private: - void AllocOutputBuffers(int num_outbufs); - void DestroyOutputBuffers(); - - LIBYUV_BOOL StartDecode(); - LIBYUV_BOOL FinishDecode(); - - void SetScanlinePointers(uint8_t** data); - LIBYUV_BOOL DecodeImcuRow(); - - int GetComponentScanlinePadding(int component); - - // A buffer holding the input data for a frame. - Buffer buf_; - BufferVector buf_vec_; - - jpeg_decompress_struct* decompress_struct_; - jpeg_source_mgr* source_mgr_; - SetJmpErrorMgr* error_mgr_; - - // LIBYUV_TRUE iff at least one component has scanline padding. (i.e., - // GetComponentScanlinePadding() != 0.) - LIBYUV_BOOL has_scanline_padding_; - - // Temporaries used to point to scanline outputs. - int num_outbufs_; // Outermost size of all arrays below. - uint8_t*** scanlines_; - int* scanlines_sizes_; - // Temporary buffer used for decoding when we can't decode directly to the - // output buffers. Large enough for just one iMCU row. - uint8_t** databuf_; - int* databuf_strides_; -}; - -} // namespace libyuv - -#endif // __cplusplus -#endif // INCLUDE_LIBYUV_MJPEG_DECODER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/planar_functions.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/planar_functions.h deleted file mode 100644 index 91137bab..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/planar_functions.h +++ /dev/null @@ -1,847 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_ -#define INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_ - -#include "libyuv/basic_types.h" - -// TODO(fbarchard): Remove the following headers includes. -#include "libyuv/convert.h" -#include "libyuv/convert_argb.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// TODO(fbarchard): Move cpu macros to row.h -#if defined(__pnacl__) || defined(__CLR_VER) || \ - (defined(__native_client__) && defined(__x86_64__)) || \ - (defined(__i386__) && !defined(__SSE__) && !defined(__clang__)) -#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__)) -#define HAS_ARGBAFFINEROW_SSE2 -#endif - -// Copy a plane of data. -LIBYUV_API -void CopyPlane(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height); - -LIBYUV_API -void CopyPlane_16(const uint16_t* src_y, - int src_stride_y, - uint16_t* dst_y, - int dst_stride_y, - int width, - int height); - -LIBYUV_API -void Convert16To8Plane(const uint16_t* src_y, - int src_stride_y, - uint8_t* dst_y, - int dst_stride_y, - int scale, // 16384 for 10 bits - int width, - int height); - -LIBYUV_API -void Convert8To16Plane(const uint8_t* src_y, - int src_stride_y, - uint16_t* dst_y, - int dst_stride_y, - int scale, // 1024 for 10 bits - int width, - int height); - -// Set a plane of data to a 32 bit value. -LIBYUV_API -void SetPlane(uint8_t* dst_y, - int dst_stride_y, - int width, - int height, - uint32_t value); - -// Split interleaved UV plane into separate U and V planes. -LIBYUV_API -void SplitUVPlane(const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Merge separate U and V planes into one interleaved UV plane. -LIBYUV_API -void MergeUVPlane(const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_uv, - int dst_stride_uv, - int width, - int height); - -// Split interleaved RGB plane into separate R, G and B planes. -LIBYUV_API -void SplitRGBPlane(const uint8_t* src_rgb, - int src_stride_rgb, - uint8_t* dst_r, - int dst_stride_r, - uint8_t* dst_g, - int dst_stride_g, - uint8_t* dst_b, - int dst_stride_b, - int width, - int height); - -// Merge separate R, G and B planes into one interleaved RGB plane. -LIBYUV_API -void MergeRGBPlane(const uint8_t* src_r, - int src_stride_r, - const uint8_t* src_g, - int src_stride_g, - const uint8_t* src_b, - int src_stride_b, - uint8_t* dst_rgb, - int dst_stride_rgb, - int width, - int height); - -// Copy I400. Supports inverting. -LIBYUV_API -int I400ToI400(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height); - -#define J400ToJ400 I400ToI400 - -// Copy I422 to I422. -#define I422ToI422 I422Copy -LIBYUV_API -int I422Copy(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Copy I444 to I444. -#define I444ToI444 I444Copy -LIBYUV_API -int I444Copy(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Convert YUY2 to I422. -LIBYUV_API -int YUY2ToI422(const uint8_t* src_yuy2, - int src_stride_yuy2, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Convert UYVY to I422. -LIBYUV_API -int UYVYToI422(const uint8_t* src_uyvy, - int src_stride_uyvy, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -LIBYUV_API -int YUY2ToNV12(const uint8_t* src_yuy2, - int src_stride_yuy2, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_uv, - int dst_stride_uv, - int width, - int height); - -LIBYUV_API -int UYVYToNV12(const uint8_t* src_uyvy, - int src_stride_uyvy, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_uv, - int dst_stride_uv, - int width, - int height); - -LIBYUV_API -int YUY2ToY(const uint8_t* src_yuy2, - int src_stride_yuy2, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height); - -// Convert I420 to I400. (calls CopyPlane ignoring u/v). -LIBYUV_API -int I420ToI400(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height); - -// Alias -#define J420ToJ400 I420ToI400 -#define I420ToI420Mirror I420Mirror - -// I420 mirror. -LIBYUV_API -int I420Mirror(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Alias -#define I400ToI400Mirror I400Mirror - -// I400 mirror. A single plane is mirrored horizontally. -// Pass negative height to achieve 180 degree rotation. -LIBYUV_API -int I400Mirror(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height); - -// Alias -#define ARGBToARGBMirror ARGBMirror - -// ARGB mirror. -LIBYUV_API -int ARGBMirror(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert NV12 to RGB565. -LIBYUV_API -int NV12ToRGB565(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - int width, - int height); - -// I422ToARGB is in convert_argb.h -// Convert I422 to BGRA. -LIBYUV_API -int I422ToBGRA(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_bgra, - int dst_stride_bgra, - int width, - int height); - -// Convert I422 to ABGR. -LIBYUV_API -int I422ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height); - -// Convert I422 to RGBA. -LIBYUV_API -int I422ToRGBA(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgba, - int dst_stride_rgba, - int width, - int height); - -// Alias -#define RGB24ToRAW RAWToRGB24 - -LIBYUV_API -int RAWToRGB24(const uint8_t* src_raw, - int src_stride_raw, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height); - -// Draw a rectangle into I420. -LIBYUV_API -int I420Rect(uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int x, - int y, - int width, - int height, - int value_y, - int value_u, - int value_v); - -// Draw a rectangle into ARGB. -LIBYUV_API -int ARGBRect(uint8_t* dst_argb, - int dst_stride_argb, - int dst_x, - int dst_y, - int width, - int height, - uint32_t value); - -// Convert ARGB to gray scale ARGB. -LIBYUV_API -int ARGBGrayTo(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Make a rectangle of ARGB gray scale. -LIBYUV_API -int ARGBGray(uint8_t* dst_argb, - int dst_stride_argb, - int dst_x, - int dst_y, - int width, - int height); - -// Make a rectangle of ARGB Sepia tone. -LIBYUV_API -int ARGBSepia(uint8_t* dst_argb, - int dst_stride_argb, - int dst_x, - int dst_y, - int width, - int height); - -// Apply a matrix rotation to each ARGB pixel. -// matrix_argb is 4 signed ARGB values. -128 to 127 representing -2 to 2. -// The first 4 coefficients apply to B, G, R, A and produce B of the output. -// The next 4 coefficients apply to B, G, R, A and produce G of the output. -// The next 4 coefficients apply to B, G, R, A and produce R of the output. -// The last 4 coefficients apply to B, G, R, A and produce A of the output. -LIBYUV_API -int ARGBColorMatrix(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - const int8_t* matrix_argb, - int width, - int height); - -// Deprecated. Use ARGBColorMatrix instead. -// Apply a matrix rotation to each ARGB pixel. -// matrix_argb is 3 signed ARGB values. -128 to 127 representing -1 to 1. -// The first 4 coefficients apply to B, G, R, A and produce B of the output. -// The next 4 coefficients apply to B, G, R, A and produce G of the output. -// The last 4 coefficients apply to B, G, R, A and produce R of the output. -LIBYUV_API -int RGBColorMatrix(uint8_t* dst_argb, - int dst_stride_argb, - const int8_t* matrix_rgb, - int dst_x, - int dst_y, - int width, - int height); - -// Apply a color table each ARGB pixel. -// Table contains 256 ARGB values. -LIBYUV_API -int ARGBColorTable(uint8_t* dst_argb, - int dst_stride_argb, - const uint8_t* table_argb, - int dst_x, - int dst_y, - int width, - int height); - -// Apply a color table each ARGB pixel but preserve destination alpha. -// Table contains 256 ARGB values. -LIBYUV_API -int RGBColorTable(uint8_t* dst_argb, - int dst_stride_argb, - const uint8_t* table_argb, - int dst_x, - int dst_y, - int width, - int height); - -// Apply a luma/color table each ARGB pixel but preserve destination alpha. -// Table contains 32768 values indexed by [Y][C] where 7 it 7 bit luma from -// RGB (YJ style) and C is an 8 bit color component (R, G or B). -LIBYUV_API -int ARGBLumaColorTable(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - const uint8_t* luma, - int width, - int height); - -// Apply a 3 term polynomial to ARGB values. -// poly points to a 4x4 matrix. The first row is constants. The 2nd row is -// coefficients for b, g, r and a. The 3rd row is coefficients for b squared, -// g squared, r squared and a squared. The 4rd row is coefficients for b to -// the 3, g to the 3, r to the 3 and a to the 3. The values are summed and -// result clamped to 0 to 255. -// A polynomial approximation can be dirived using software such as 'R'. - -LIBYUV_API -int ARGBPolynomial(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - const float* poly, - int width, - int height); - -// Convert plane of 16 bit shorts to half floats. -// Source values are multiplied by scale before storing as half float. -LIBYUV_API -int HalfFloatPlane(const uint16_t* src_y, - int src_stride_y, - uint16_t* dst_y, - int dst_stride_y, - float scale, - int width, - int height); - -// Convert a buffer of bytes to floats, scale the values and store as floats. -LIBYUV_API -int ByteToFloat(const uint8_t* src_y, float* dst_y, float scale, int width); - -// Quantize a rectangle of ARGB. Alpha unaffected. -// scale is a 16 bit fractional fixed point scaler between 0 and 65535. -// interval_size should be a value between 1 and 255. -// interval_offset should be a value between 0 and 255. -LIBYUV_API -int ARGBQuantize(uint8_t* dst_argb, - int dst_stride_argb, - int scale, - int interval_size, - int interval_offset, - int dst_x, - int dst_y, - int width, - int height); - -// Copy ARGB to ARGB. -LIBYUV_API -int ARGBCopy(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Copy Alpha channel of ARGB to alpha of ARGB. -LIBYUV_API -int ARGBCopyAlpha(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Extract the alpha channel from ARGB. -LIBYUV_API -int ARGBExtractAlpha(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_a, - int dst_stride_a, - int width, - int height); - -// Copy Y channel to Alpha of ARGB. -LIBYUV_API -int ARGBCopyYToAlpha(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -typedef void (*ARGBBlendRow)(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); - -// Get function to Alpha Blend ARGB pixels and store to destination. -LIBYUV_API -ARGBBlendRow GetARGBBlend(); - -// Alpha Blend ARGB images and store to destination. -// Source is pre-multiplied by alpha using ARGBAttenuate. -// Alpha of destination is set to 255. -LIBYUV_API -int ARGBBlend(const uint8_t* src_argb0, - int src_stride_argb0, - const uint8_t* src_argb1, - int src_stride_argb1, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Alpha Blend plane and store to destination. -// Source is not pre-multiplied by alpha. -LIBYUV_API -int BlendPlane(const uint8_t* src_y0, - int src_stride_y0, - const uint8_t* src_y1, - int src_stride_y1, - const uint8_t* alpha, - int alpha_stride, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height); - -// Alpha Blend YUV images and store to destination. -// Source is not pre-multiplied by alpha. -// Alpha is full width x height and subsampled to half size to apply to UV. -LIBYUV_API -int I420Blend(const uint8_t* src_y0, - int src_stride_y0, - const uint8_t* src_u0, - int src_stride_u0, - const uint8_t* src_v0, - int src_stride_v0, - const uint8_t* src_y1, - int src_stride_y1, - const uint8_t* src_u1, - int src_stride_u1, - const uint8_t* src_v1, - int src_stride_v1, - const uint8_t* alpha, - int alpha_stride, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height); - -// Multiply ARGB image by ARGB image. Shifted down by 8. Saturates to 255. -LIBYUV_API -int ARGBMultiply(const uint8_t* src_argb0, - int src_stride_argb0, - const uint8_t* src_argb1, - int src_stride_argb1, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Add ARGB image with ARGB image. Saturates to 255. -LIBYUV_API -int ARGBAdd(const uint8_t* src_argb0, - int src_stride_argb0, - const uint8_t* src_argb1, - int src_stride_argb1, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Subtract ARGB image (argb1) from ARGB image (argb0). Saturates to 0. -LIBYUV_API -int ARGBSubtract(const uint8_t* src_argb0, - int src_stride_argb0, - const uint8_t* src_argb1, - int src_stride_argb1, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert I422 to YUY2. -LIBYUV_API -int I422ToYUY2(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_yuy2, - int dst_stride_yuy2, - int width, - int height); - -// Convert I422 to UYVY. -LIBYUV_API -int I422ToUYVY(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_uyvy, - int dst_stride_uyvy, - int width, - int height); - -// Convert unattentuated ARGB to preattenuated ARGB. -LIBYUV_API -int ARGBAttenuate(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Convert preattentuated ARGB to unattenuated ARGB. -LIBYUV_API -int ARGBUnattenuate(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// 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. -LIBYUV_API -int ARGBComputeCumulativeSum(const uint8_t* src_argb, - int src_stride_argb, - int32_t* dst_cumsum, - int dst_stride32_cumsum, - int width, - int height); - -// Blur ARGB image. -// dst_cumsum table of width * (height + 1) * 16 bytes aligned to -// 16 byte boundary. -// dst_stride32_cumsum is number of ints in a row (width * 4). -// radius is number of pixels around the center. e.g. 1 = 3x3. 2=5x5. -// Blur is optimized for radius of 5 (11x11) or less. -LIBYUV_API -int ARGBBlur(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int32_t* dst_cumsum, - int dst_stride32_cumsum, - int width, - int height, - int radius); - -// Multiply ARGB image by ARGB value. -LIBYUV_API -int ARGBShade(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height, - uint32_t value); - -// Interpolate between two images using specified amount of interpolation -// (0 to 255) and store to destination. -// 'interpolation' is specified as 8 bit fraction where 0 means 100% src0 -// and 255 means 1% src0 and 99% src1. -LIBYUV_API -int InterpolatePlane(const uint8_t* src0, - int src_stride0, - const uint8_t* src1, - int src_stride1, - uint8_t* dst, - int dst_stride, - int width, - int height, - int interpolation); - -// Interpolate between two ARGB images using specified amount of interpolation -// Internally calls InterpolatePlane with width * 4 (bpp). -LIBYUV_API -int ARGBInterpolate(const uint8_t* src_argb0, - int src_stride_argb0, - const uint8_t* src_argb1, - int src_stride_argb1, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height, - int interpolation); - -// Interpolate between two YUV images using specified amount of interpolation -// Internally calls InterpolatePlane on each plane where the U and V planes -// are half width and half height. -LIBYUV_API -int I420Interpolate(const uint8_t* src0_y, - int src0_stride_y, - const uint8_t* src0_u, - int src0_stride_u, - const uint8_t* src0_v, - int src0_stride_v, - const uint8_t* src1_y, - int src1_stride_y, - const uint8_t* src1_u, - int src1_stride_u, - const uint8_t* src1_v, - int src1_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height, - int interpolation); - -// Row function for copying pixels from a source with a slope to a row -// of destination. Useful for scaling, rotation, mirror, texture mapping. -LIBYUV_API -void ARGBAffineRow_C(const uint8_t* src_argb, - int src_argb_stride, - uint8_t* dst_argb, - const float* uv_dudv, - int width); -// TODO(fbarchard): Move ARGBAffineRow_SSE2 to row.h -LIBYUV_API -void ARGBAffineRow_SSE2(const uint8_t* src_argb, - int src_argb_stride, - uint8_t* dst_argb, - const float* uv_dudv, - int width); - -// Shuffle ARGB channel order. e.g. BGRA to ARGB. -// shuffler is 16 bytes and must be aligned. -LIBYUV_API -int ARGBShuffle(const uint8_t* src_bgra, - int src_stride_bgra, - uint8_t* dst_argb, - int dst_stride_argb, - const uint8_t* shuffler, - int width, - int height); - -// Sobel ARGB effect with planar output. -LIBYUV_API -int ARGBSobelToPlane(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height); - -// Sobel ARGB effect. -LIBYUV_API -int ARGBSobel(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -// Sobel ARGB effect w/ Sobel X, Sobel, Sobel Y in ARGB. -LIBYUV_API -int ARGBSobelXY(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height); - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/rotate.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/rotate.h deleted file mode 100644 index 76b692be..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/rotate.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_ROTATE_H_ -#define INCLUDE_LIBYUV_ROTATE_H_ - -#include "libyuv/basic_types.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// Supported rotation. -typedef enum RotationMode { - kRotate0 = 0, // No rotation. - kRotate90 = 90, // Rotate 90 degrees clockwise. - kRotate180 = 180, // Rotate 180 degrees. - kRotate270 = 270, // Rotate 270 degrees clockwise. - - // Deprecated. - kRotateNone = 0, - kRotateClockwise = 90, - kRotateCounterClockwise = 270, -} RotationModeEnum; - -// Rotate I420 frame. -LIBYUV_API -int I420Rotate(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height, - enum RotationMode mode); - -// Rotate NV12 input and store in I420. -LIBYUV_API -int NV12ToI420Rotate(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height, - enum RotationMode mode); - -// Rotate a plane by 0, 90, 180, or 270. -LIBYUV_API -int RotatePlane(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width, - int height, - enum RotationMode mode); - -// Rotate planes by 90, 180, 270. Deprecated. -LIBYUV_API -void RotatePlane90(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width, - int height); - -LIBYUV_API -void RotatePlane180(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width, - int height); - -LIBYUV_API -void RotatePlane270(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width, - int height); - -LIBYUV_API -void RotateUV90(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width, - int height); - -// Rotations for when U and V are interleaved. -// These functions take one input pointer and -// split the data into two buffers while -// rotating them. Deprecated. -LIBYUV_API -void RotateUV180(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width, - int height); - -LIBYUV_API -void RotateUV270(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width, - int height); - -// The 90 and 270 functions are based on transposes. -// Doing a transpose with reversing the read/write -// order will result in a rotation by +- 90 degrees. -// Deprecated. -LIBYUV_API -void TransposePlane(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width, - int height); - -LIBYUV_API -void TransposeUV(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width, - int height); - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // INCLUDE_LIBYUV_ROTATE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/rotate_argb.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/rotate_argb.h deleted file mode 100644 index 20432949..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/rotate_argb.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2012 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_ROTATE_ARGB_H_ -#define INCLUDE_LIBYUV_ROTATE_ARGB_H_ - -#include "libyuv/basic_types.h" -#include "libyuv/rotate.h" // For RotationMode. - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// Rotate ARGB frame -LIBYUV_API -int ARGBRotate(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int src_width, - int src_height, - enum RotationMode mode); - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // INCLUDE_LIBYUV_ROTATE_ARGB_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/rotate_row.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/rotate_row.h deleted file mode 100644 index 5edc0fcf..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/rotate_row.h +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2013 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_ROTATE_ROW_H_ -#define INCLUDE_LIBYUV_ROTATE_ROW_H_ - -#include "libyuv/basic_types.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -#if defined(__pnacl__) || defined(__CLR_VER) || \ - (defined(__native_client__) && defined(__x86_64__)) || \ - (defined(__i386__) && !defined(__SSE__) && !defined(__clang__)) -#define LIBYUV_DISABLE_X86 -#endif -#if defined(__native_client__) -#define LIBYUV_DISABLE_NEON -#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) && defined(_MSC_VER) -#define HAS_TRANSPOSEWX8_SSSE3 -#define HAS_TRANSPOSEUVWX8_SSE2 -#endif - -// The following are available for GCC 32 or 64 bit: -#if !defined(LIBYUV_DISABLE_X86) && (defined(__i386__) || defined(__x86_64__)) -#define HAS_TRANSPOSEWX8_SSSE3 -#endif - -// The following are available for 64 bit GCC: -#if !defined(LIBYUV_DISABLE_X86) && defined(__x86_64__) -#define HAS_TRANSPOSEWX8_FAST_SSSE3 -#define HAS_TRANSPOSEUVWX8_SSE2 -#endif - -#if !defined(LIBYUV_DISABLE_NEON) && \ - (defined(__ARM_NEON__) || defined(LIBYUV_NEON) || defined(__aarch64__)) -#define HAS_TRANSPOSEWX8_NEON -#define HAS_TRANSPOSEUVWX8_NEON -#endif - -#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) -#define HAS_TRANSPOSEWX16_MSA -#define HAS_TRANSPOSEUVWX16_MSA -#endif - -void TransposeWxH_C(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width, - int height); - -void TransposeWx8_C(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width); -void TransposeWx16_C(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width); -void TransposeWx8_NEON(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width); -void TransposeWx8_SSSE3(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width); -void TransposeWx8_Fast_SSSE3(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width); -void TransposeWx16_MSA(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width); - -void TransposeWx8_Any_NEON(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width); -void TransposeWx8_Any_SSSE3(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width); -void TransposeWx8_Fast_Any_SSSE3(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width); -void TransposeWx16_Any_MSA(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width); - -void TransposeUVWxH_C(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width, - int height); - -void TransposeUVWx8_C(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width); -void TransposeUVWx16_C(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width); -void TransposeUVWx8_SSE2(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width); -void TransposeUVWx8_NEON(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width); -void TransposeUVWx16_MSA(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width); - -void TransposeUVWx8_Any_SSE2(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width); -void TransposeUVWx8_Any_NEON(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width); -void TransposeUVWx16_Any_MSA(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width); - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // INCLUDE_LIBYUV_ROTATE_ROW_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/row.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/row.h deleted file mode 100644 index 65ef448b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/row.h +++ /dev/null @@ -1,3471 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_ROW_H_ -#define INCLUDE_LIBYUV_ROW_H_ - -#include // For malloc. - -#include "libyuv/basic_types.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -#if defined(__pnacl__) || defined(__CLR_VER) || \ - (defined(__native_client__) && defined(__x86_64__)) || \ - (defined(__i386__) && !defined(__SSE__) && !defined(__clang__)) -#define LIBYUV_DISABLE_X86 -#endif -#if defined(__native_client__) -#define LIBYUV_DISABLE_NEON -#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 -// clang >= 3.5.0 required for Arm64. -#if defined(__clang__) && defined(__aarch64__) && !defined(LIBYUV_DISABLE_NEON) -#if (__clang_major__ < 3) || (__clang_major__ == 3 && (__clang_minor__ < 5)) -#define LIBYUV_DISABLE_NEON -#endif // clang >= 3.5 -#endif // __clang__ - -// GCC >= 4.7.0 required for AVX2. -#if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) -#if (__GNUC__ > 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 7)) -#define GCC_HAS_AVX2 1 -#endif // GNUC >= 4.7 -#endif // __GNUC__ - -// clang >= 3.4.0 required for AVX2. -#if defined(__clang__) && (defined(__x86_64__) || defined(__i386__)) -#if (__clang_major__ > 3) || (__clang_major__ == 3 && (__clang_minor__ >= 4)) -#define CLANG_HAS_AVX2 1 -#endif // clang >= 3.4 -#endif // __clang__ - -// clang >= 6.0.0 required for AVX512. -// TODO(fbarchard): fix xcode 9 ios b/789. -#if 0 // Build fails in libvpx on Mac -#if defined(__clang__) && (defined(__x86_64__) || defined(__i386__)) -#if (__clang_major__ >= 7) && !defined(__APPLE_EMBEDDED_SIMULATOR__) -#define CLANG_HAS_AVX512 1 -#endif // clang >= 7 -#endif // __clang__ -#endif // 0 - -// Visual C 2012 required for AVX2. -#if defined(_M_IX86) && !defined(__clang__) && defined(_MSC_VER) && \ - _MSC_VER >= 1700 -#define VISUALC_HAS_AVX2 1 -#endif // VisualStudio >= 2012 - -// The following are available on all x86 platforms: -#if !defined(LIBYUV_DISABLE_X86) && \ - (defined(_M_IX86) || defined(__x86_64__) || defined(__i386__)) -// Conversions: -#define HAS_ABGRTOUVROW_SSSE3 -#define HAS_ABGRTOYROW_SSSE3 -#define HAS_ARGB1555TOARGBROW_SSE2 -#define HAS_ARGB4444TOARGBROW_SSE2 -#define HAS_ARGBEXTRACTALPHAROW_SSE2 -#define HAS_ARGBSETROW_X86 -#define HAS_ARGBSHUFFLEROW_SSSE3 -#define HAS_ARGBTOARGB1555ROW_SSE2 -#define HAS_ARGBTOARGB4444ROW_SSE2 -#define HAS_ARGBTORAWROW_SSSE3 -#define HAS_ARGBTORGB24ROW_SSSE3 -#define HAS_ARGBTORGB565DITHERROW_SSE2 -#define HAS_ARGBTORGB565ROW_SSE2 -#define HAS_ARGBTOUV444ROW_SSSE3 -#define HAS_ARGBTOUVJROW_SSSE3 -#define HAS_ARGBTOUVROW_SSSE3 -#define HAS_ARGBTOYJROW_SSSE3 -#define HAS_ARGBTOYROW_SSSE3 -#define HAS_BGRATOUVROW_SSSE3 -#define HAS_BGRATOYROW_SSSE3 -#define HAS_COPYROW_ERMS -#define HAS_COPYROW_SSE2 -#define HAS_H422TOARGBROW_SSSE3 -#define HAS_HALFFLOATROW_SSE2 -#define HAS_I400TOARGBROW_SSE2 -#define HAS_I422TOARGB1555ROW_SSSE3 -#define HAS_I422TOARGB4444ROW_SSSE3 -#define HAS_I422TOARGBROW_SSSE3 -#define HAS_I422TORGB24ROW_SSSE3 -#define HAS_I422TORGB565ROW_SSSE3 -#define HAS_I422TORGBAROW_SSSE3 -#define HAS_I422TOUYVYROW_SSE2 -#define HAS_I422TOYUY2ROW_SSE2 -#define HAS_I444TOARGBROW_SSSE3 -#define HAS_J400TOARGBROW_SSE2 -#define HAS_J422TOARGBROW_SSSE3 -#define HAS_MERGEUVROW_SSE2 -#define HAS_MIRRORROW_SSSE3 -#define HAS_MIRRORUVROW_SSSE3 -#define HAS_NV12TOARGBROW_SSSE3 -#define HAS_NV12TORGB24ROW_SSSE3 -#define HAS_NV12TORGB565ROW_SSSE3 -#define HAS_NV21TOARGBROW_SSSE3 -#define HAS_NV21TORGB24ROW_SSSE3 -#define HAS_RAWTOARGBROW_SSSE3 -#define HAS_RAWTORGB24ROW_SSSE3 -#define HAS_RAWTOYROW_SSSE3 -#define HAS_RGB24TOARGBROW_SSSE3 -#define HAS_RGB24TOYROW_SSSE3 -#define HAS_RGB565TOARGBROW_SSE2 -#define HAS_RGBATOUVROW_SSSE3 -#define HAS_RGBATOYROW_SSSE3 -#define HAS_SETROW_ERMS -#define HAS_SETROW_X86 -#define HAS_SPLITUVROW_SSE2 -#define HAS_UYVYTOARGBROW_SSSE3 -#define HAS_UYVYTOUV422ROW_SSE2 -#define HAS_UYVYTOUVROW_SSE2 -#define HAS_UYVYTOYROW_SSE2 -#define HAS_YUY2TOARGBROW_SSSE3 -#define HAS_YUY2TOUV422ROW_SSE2 -#define HAS_YUY2TOUVROW_SSE2 -#define HAS_YUY2TOYROW_SSE2 - -// Effects: -#define HAS_ARGBADDROW_SSE2 -#define HAS_ARGBAFFINEROW_SSE2 -#define HAS_ARGBATTENUATEROW_SSSE3 -#define HAS_ARGBBLENDROW_SSSE3 -#define HAS_ARGBCOLORMATRIXROW_SSSE3 -#define HAS_ARGBCOLORTABLEROW_X86 -#define HAS_ARGBCOPYALPHAROW_SSE2 -#define HAS_ARGBCOPYYTOALPHAROW_SSE2 -#define HAS_ARGBGRAYROW_SSSE3 -#define HAS_ARGBLUMACOLORTABLEROW_SSSE3 -#define HAS_ARGBMIRRORROW_SSE2 -#define HAS_ARGBMULTIPLYROW_SSE2 -#define HAS_ARGBPOLYNOMIALROW_SSE2 -#define HAS_ARGBQUANTIZEROW_SSE2 -#define HAS_ARGBSEPIAROW_SSSE3 -#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 -#define HAS_RGBCOLORTABLEROW_X86 -#define HAS_SOBELROW_SSE2 -#define HAS_SOBELTOPLANEROW_SSE2 -#define HAS_SOBELXROW_SSE2 -#define HAS_SOBELXYROW_SSE2 -#define HAS_SOBELYROW_SSE2 - -// The following functions fail on gcc/clang 32 bit with fpic and framepointer. -// caveat: clangcl uses row_win.cc which works. -#if defined(__x86_64__) || !defined(__pic__) || defined(__clang__) || \ - defined(_MSC_VER) -// 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 -// require VS2012, clang 3.4 or gcc 4.7. -#if !defined(LIBYUV_DISABLE_X86) && \ - (defined(VISUALC_HAS_AVX2) || defined(CLANG_HAS_AVX2) || \ - defined(GCC_HAS_AVX2)) -#define HAS_ARGBCOPYALPHAROW_AVX2 -#define HAS_ARGBCOPYYTOALPHAROW_AVX2 -#define HAS_ARGBEXTRACTALPHAROW_AVX2 -#define HAS_ARGBMIRRORROW_AVX2 -#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 -#define HAS_COPYROW_AVX -#define HAS_H422TOARGBROW_AVX2 -#define HAS_HALFFLOATROW_AVX2 -// #define HAS_HALFFLOATROW_F16C // Enable to test halffloat cast -#define HAS_I400TOARGBROW_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_NV12TORGB24ROW_AVX2 -#define HAS_NV12TORGB565ROW_AVX2 -#define HAS_NV21TOARGBROW_AVX2 -#define HAS_NV21TORGB24ROW_AVX2 -#define HAS_SPLITUVROW_AVX2 -#define HAS_UYVYTOARGBROW_AVX2 -#define HAS_UYVYTOUV422ROW_AVX2 -#define HAS_UYVYTOUVROW_AVX2 -#define HAS_UYVYTOYROW_AVX2 -#define HAS_YUY2TOARGBROW_AVX2 -#define HAS_YUY2TOUV422ROW_AVX2 -#define HAS_YUY2TOUVROW_AVX2 -#define HAS_YUY2TOYROW_AVX2 - -// Effects: -#define HAS_ARGBADDROW_AVX2 -#define HAS_ARGBATTENUATEROW_AVX2 -#define HAS_ARGBMULTIPLYROW_AVX2 -#define HAS_ARGBSUBTRACTROW_AVX2 -#define HAS_ARGBUNATTENUATEROW_AVX2 -#define HAS_BLENDPLANEROW_AVX2 - -#if defined(__x86_64__) || !defined(__pic__) || defined(__clang__) || \ - defined(_MSC_VER) -// TODO(fbarchard): fix build error on android_full_debug=1 -// https://code.google.com/p/libyuv/issues/detail?id=517 -#define HAS_I422ALPHATOARGBROW_AVX2 -#endif -#endif - -// The following are available for AVX2 Visual C and clangcl 32 bit: -// TODO(fbarchard): Port to gcc. -#if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) && \ - (defined(VISUALC_HAS_AVX2) || defined(CLANG_HAS_AVX2)) -#define HAS_ARGB1555TOARGBROW_AVX2 -#define HAS_ARGB4444TOARGBROW_AVX2 -#define HAS_ARGBTOARGB1555ROW_AVX2 -#define HAS_ARGBTOARGB4444ROW_AVX2 -#define HAS_ARGBTORGB565ROW_AVX2 -#define HAS_J400TOARGBROW_AVX2 -#define HAS_RGB565TOARGBROW_AVX2 -#endif - -// The following are also available on x64 Visual C. -#if !defined(LIBYUV_DISABLE_X86) && defined(_MSC_VER) && defined(_M_X64) && \ - (!defined(__clang__) || defined(__SSSE3__)) -#define HAS_I422ALPHATOARGBROW_SSSE3 -#define HAS_I422TOARGBROW_SSSE3 -#endif - -// The following are available for gcc/clang x86 platforms: -// TODO(fbarchard): Port to Visual C -#if !defined(LIBYUV_DISABLE_X86) && \ - (defined(__x86_64__) || (defined(__i386__) && !defined(_MSC_VER))) -#define HAS_ABGRTOAR30ROW_SSSE3 -#define HAS_ARGBTOAR30ROW_SSSE3 -#define HAS_CONVERT16TO8ROW_SSSE3 -#define HAS_CONVERT8TO16ROW_SSE2 -// I210 is for H010. 2 = 422. I for 601 vs H for 709. -#define HAS_I210TOAR30ROW_SSSE3 -#define HAS_I210TOARGBROW_SSSE3 -#define HAS_I422TOAR30ROW_SSSE3 -#define HAS_MERGERGBROW_SSSE3 -#define HAS_SPLITRGBROW_SSSE3 -#endif - -// The following are available for AVX2 gcc/clang x86 platforms: -// TODO(fbarchard): Port to Visual C -#if !defined(LIBYUV_DISABLE_X86) && \ - (defined(__x86_64__) || (defined(__i386__) && !defined(_MSC_VER))) && \ - (defined(CLANG_HAS_AVX2) || defined(GCC_HAS_AVX2)) -#define HAS_ABGRTOAR30ROW_AVX2 -#define HAS_ARGBTOAR30ROW_AVX2 -#define HAS_ARGBTORAWROW_AVX2 -#define HAS_ARGBTORGB24ROW_AVX2 -#define HAS_CONVERT16TO8ROW_AVX2 -#define HAS_CONVERT8TO16ROW_AVX2 -#define HAS_I210TOAR30ROW_AVX2 -#define HAS_I210TOARGBROW_AVX2 -#define HAS_I422TOAR30ROW_AVX2 -#define HAS_I422TOUYVYROW_AVX2 -#define HAS_I422TOYUY2ROW_AVX2 -#define HAS_MERGEUVROW_16_AVX2 -#define HAS_MULTIPLYROW_16_AVX2 -#endif - -// The following are available for AVX512 clang x86 platforms: -// TODO(fbarchard): Port to GCC and Visual C -// TODO(fbarchard): re-enable HAS_ARGBTORGB24ROW_AVX512VBMI. Issue libyuv:789 -#if !defined(LIBYUV_DISABLE_X86) && \ - (defined(__x86_64__) || (defined(__i386__) && !defined(_MSC_VER))) && \ - (defined(CLANG_HAS_AVX512)) -#define HAS_ARGBTORGB24ROW_AVX512VBMI -#endif - -// The following are available on Neon platforms: -#if !defined(LIBYUV_DISABLE_NEON) && \ - (defined(__aarch64__) || defined(__ARM_NEON__) || defined(LIBYUV_NEON)) -#define HAS_ABGRTOUVROW_NEON -#define HAS_ABGRTOYROW_NEON -#define HAS_ARGB1555TOARGBROW_NEON -#define HAS_ARGB1555TOUVROW_NEON -#define HAS_ARGB1555TOYROW_NEON -#define HAS_ARGB4444TOARGBROW_NEON -#define HAS_ARGB4444TOUVROW_NEON -#define HAS_ARGB4444TOYROW_NEON -#define HAS_ARGBEXTRACTALPHAROW_NEON -#define HAS_ARGBSETROW_NEON -#define HAS_ARGBTOARGB1555ROW_NEON -#define HAS_ARGBTOARGB4444ROW_NEON -#define HAS_ARGBTORAWROW_NEON -#define HAS_ARGBTORGB24ROW_NEON -#define HAS_ARGBTORGB565DITHERROW_NEON -#define HAS_ARGBTORGB565ROW_NEON -#define HAS_ARGBTOUV444ROW_NEON -#define HAS_ARGBTOUVJROW_NEON -#define HAS_ARGBTOUVROW_NEON -#define HAS_ARGBTOYJROW_NEON -#define HAS_ARGBTOYROW_NEON -#define HAS_BGRATOUVROW_NEON -#define HAS_BGRATOYROW_NEON -#define HAS_BYTETOFLOATROW_NEON -#define HAS_COPYROW_NEON -#define HAS_HALFFLOATROW_NEON -#define HAS_I400TOARGBROW_NEON -#define HAS_I422ALPHATOARGBROW_NEON -#define HAS_I422TOARGB1555ROW_NEON -#define HAS_I422TOARGB4444ROW_NEON -#define HAS_I422TOARGBROW_NEON -#define HAS_I422TORGB24ROW_NEON -#define HAS_I422TORGB565ROW_NEON -#define HAS_I422TORGBAROW_NEON -#define HAS_I422TOUYVYROW_NEON -#define HAS_I422TOYUY2ROW_NEON -#define HAS_I444TOARGBROW_NEON -#define HAS_J400TOARGBROW_NEON -#define HAS_MERGEUVROW_NEON -#define HAS_MIRRORROW_NEON -#define HAS_MIRRORUVROW_NEON -#define HAS_NV12TOARGBROW_NEON -#define HAS_NV12TORGB24ROW_NEON -#define HAS_NV12TORGB565ROW_NEON -#define HAS_NV21TOARGBROW_NEON -#define HAS_NV21TORGB24ROW_NEON -#define HAS_RAWTOARGBROW_NEON -#define HAS_RAWTORGB24ROW_NEON -#define HAS_RAWTOUVROW_NEON -#define HAS_RAWTOYROW_NEON -#define HAS_RGB24TOARGBROW_NEON -#define HAS_RGB24TOUVROW_NEON -#define HAS_RGB24TOYROW_NEON -#define HAS_RGB565TOARGBROW_NEON -#define HAS_RGB565TOUVROW_NEON -#define HAS_RGB565TOYROW_NEON -#define HAS_RGBATOUVROW_NEON -#define HAS_RGBATOYROW_NEON -#define HAS_SETROW_NEON -#define HAS_SPLITRGBROW_NEON -#define HAS_SPLITUVROW_NEON -#define HAS_UYVYTOARGBROW_NEON -#define HAS_UYVYTOUV422ROW_NEON -#define HAS_UYVYTOUVROW_NEON -#define HAS_UYVYTOYROW_NEON -#define HAS_YUY2TOARGBROW_NEON -#define HAS_YUY2TOUV422ROW_NEON -#define HAS_YUY2TOUVROW_NEON -#define HAS_YUY2TOYROW_NEON - -// Effects: -#define HAS_ARGBADDROW_NEON -#define HAS_ARGBATTENUATEROW_NEON -#define HAS_ARGBBLENDROW_NEON -#define HAS_ARGBCOLORMATRIXROW_NEON -#define HAS_ARGBGRAYROW_NEON -#define HAS_ARGBMIRRORROW_NEON -#define HAS_ARGBMULTIPLYROW_NEON -#define HAS_ARGBQUANTIZEROW_NEON -#define HAS_ARGBSEPIAROW_NEON -#define HAS_ARGBSHADEROW_NEON -#define HAS_ARGBSHUFFLEROW_NEON -#define HAS_ARGBSUBTRACTROW_NEON -#define HAS_INTERPOLATEROW_NEON -#define HAS_SOBELROW_NEON -#define HAS_SOBELTOPLANEROW_NEON -#define HAS_SOBELXROW_NEON -#define HAS_SOBELXYROW_NEON -#define HAS_SOBELYROW_NEON -#endif - -// The following are available on AArch64 platforms: -#if !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) -#define HAS_SCALESUMSAMPLES_NEON -#endif -#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) -#define HAS_ABGRTOUVROW_MSA -#define HAS_ABGRTOYROW_MSA -#define HAS_ARGB1555TOARGBROW_MSA -#define HAS_ARGB1555TOUVROW_MSA -#define HAS_ARGB1555TOYROW_MSA -#define HAS_ARGB4444TOARGBROW_MSA -#define HAS_ARGBADDROW_MSA -#define HAS_ARGBATTENUATEROW_MSA -#define HAS_ARGBBLENDROW_MSA -#define HAS_ARGBCOLORMATRIXROW_MSA -#define HAS_ARGBEXTRACTALPHAROW_MSA -#define HAS_ARGBGRAYROW_MSA -#define HAS_ARGBMIRRORROW_MSA -#define HAS_ARGBMULTIPLYROW_MSA -#define HAS_ARGBQUANTIZEROW_MSA -#define HAS_ARGBSEPIAROW_MSA -#define HAS_ARGBSETROW_MSA -#define HAS_ARGBSHADEROW_MSA -#define HAS_ARGBSHUFFLEROW_MSA -#define HAS_ARGBSUBTRACTROW_MSA -#define HAS_ARGBTOARGB1555ROW_MSA -#define HAS_ARGBTOARGB4444ROW_MSA -#define HAS_ARGBTORAWROW_MSA -#define HAS_ARGBTORGB24ROW_MSA -#define HAS_ARGBTORGB565DITHERROW_MSA -#define HAS_ARGBTORGB565ROW_MSA -#define HAS_ARGBTOUV444ROW_MSA -#define HAS_ARGBTOUVJROW_MSA -#define HAS_ARGBTOUVROW_MSA -#define HAS_ARGBTOYJROW_MSA -#define HAS_ARGBTOYROW_MSA -#define HAS_BGRATOUVROW_MSA -#define HAS_BGRATOYROW_MSA -#define HAS_HALFFLOATROW_MSA -#define HAS_I400TOARGBROW_MSA -#define HAS_I422ALPHATOARGBROW_MSA -#define HAS_I422TOARGBROW_MSA -#define HAS_I422TORGB24ROW_MSA -#define HAS_I422TORGBAROW_MSA -#define HAS_I422TOUYVYROW_MSA -#define HAS_I422TOYUY2ROW_MSA -#define HAS_I444TOARGBROW_MSA -#define HAS_INTERPOLATEROW_MSA -#define HAS_J400TOARGBROW_MSA -#define HAS_MERGEUVROW_MSA -#define HAS_MIRRORROW_MSA -#define HAS_MIRRORUVROW_MSA -#define HAS_NV12TOARGBROW_MSA -#define HAS_NV12TORGB565ROW_MSA -#define HAS_NV21TOARGBROW_MSA -#define HAS_RAWTOARGBROW_MSA -#define HAS_RAWTORGB24ROW_MSA -#define HAS_RAWTOUVROW_MSA -#define HAS_RAWTOYROW_MSA -#define HAS_RGB24TOARGBROW_MSA -#define HAS_RGB24TOUVROW_MSA -#define HAS_RGB24TOYROW_MSA -#define HAS_RGB565TOARGBROW_MSA -#define HAS_RGB565TOUVROW_MSA -#define HAS_RGB565TOYROW_MSA -#define HAS_RGBATOUVROW_MSA -#define HAS_RGBATOYROW_MSA -#define HAS_SETROW_MSA -#define HAS_SOBELROW_MSA -#define HAS_SOBELTOPLANEROW_MSA -#define HAS_SOBELXROW_MSA -#define HAS_SOBELXYROW_MSA -#define HAS_SOBELYROW_MSA -#define HAS_SPLITUVROW_MSA -#define HAS_UYVYTOARGBROW_MSA -#define HAS_UYVYTOUVROW_MSA -#define HAS_UYVYTOYROW_MSA -#define HAS_YUY2TOARGBROW_MSA -#define HAS_YUY2TOUV422ROW_MSA -#define HAS_YUY2TOUVROW_MSA -#define HAS_YUY2TOYROW_MSA -#endif - -#if defined(_MSC_VER) && !defined(__CLR_VER) && !defined(__clang__) -#if defined(VISUALC_HAS_AVX2) -#define SIMD_ALIGNED(var) __declspec(align(32)) var -#else -#define SIMD_ALIGNED(var) __declspec(align(16)) var -#endif -typedef __declspec(align(16)) int16_t vec16[8]; -typedef __declspec(align(16)) int32_t vec32[4]; -typedef __declspec(align(16)) int8_t vec8[16]; -typedef __declspec(align(16)) uint16_t uvec16[8]; -typedef __declspec(align(16)) uint32_t uvec32[4]; -typedef __declspec(align(16)) uint8_t uvec8[16]; -typedef __declspec(align(32)) int16_t lvec16[16]; -typedef __declspec(align(32)) int32_t lvec32[8]; -typedef __declspec(align(32)) int8_t lvec8[32]; -typedef __declspec(align(32)) uint16_t ulvec16[16]; -typedef __declspec(align(32)) uint32_t ulvec32[8]; -typedef __declspec(align(32)) uint8_t ulvec8[32]; -#elif !defined(__pnacl__) && (defined(__GNUC__) || defined(__clang__)) -// Caveat GCC 4.2 to 4.7 have a known issue using vectors with const. -#if defined(CLANG_HAS_AVX2) || defined(GCC_HAS_AVX2) -#define SIMD_ALIGNED(var) var __attribute__((aligned(32))) -#else -#define SIMD_ALIGNED(var) var __attribute__((aligned(16))) -#endif -typedef int16_t __attribute__((vector_size(16))) vec16; -typedef int32_t __attribute__((vector_size(16))) vec32; -typedef int8_t __attribute__((vector_size(16))) vec8; -typedef uint16_t __attribute__((vector_size(16))) uvec16; -typedef uint32_t __attribute__((vector_size(16))) uvec32; -typedef uint8_t __attribute__((vector_size(16))) uvec8; -typedef int16_t __attribute__((vector_size(32))) lvec16; -typedef int32_t __attribute__((vector_size(32))) lvec32; -typedef int8_t __attribute__((vector_size(32))) lvec8; -typedef uint16_t __attribute__((vector_size(32))) ulvec16; -typedef uint32_t __attribute__((vector_size(32))) ulvec32; -typedef uint8_t __attribute__((vector_size(32))) ulvec8; -#else -#define SIMD_ALIGNED(var) var -typedef int16_t vec16[8]; -typedef int32_t vec32[4]; -typedef int8_t vec8[16]; -typedef uint16_t uvec16[8]; -typedef uint32_t uvec32[4]; -typedef uint8_t uvec8[16]; -typedef int16_t lvec16[16]; -typedef int32_t lvec32[8]; -typedef int8_t lvec8[32]; -typedef uint16_t ulvec16[16]; -typedef uint32_t ulvec32[8]; -typedef uint8_t ulvec8[32]; -#endif - -#if defined(__aarch64__) -// This struct is for Arm64 color conversion. -struct YuvConstants { - uvec16 kUVToRB; - uvec16 kUVToRB2; - uvec16 kUVToG; - uvec16 kUVToG2; - vec16 kUVBiasBGR; - vec32 kYToRgb; -}; -#elif defined(__arm__) -// This struct is for ArmV7 color conversion. -struct YuvConstants { - uvec8 kUVToRB; - uvec8 kUVToG; - vec16 kUVBiasBGR; - vec32 kYToRgb; -}; -#else -// This struct is for Intel color conversion. -struct YuvConstants { - int8_t kUVToB[32]; - int8_t kUVToG[32]; - int8_t kUVToR[32]; - int16_t kUVBiasB[16]; - int16_t kUVBiasG[16]; - int16_t kUVBiasR[16]; - int16_t kYToRgb[16]; -}; - -// Offsets into YuvConstants structure -#define KUVTOB 0 -#define KUVTOG 32 -#define KUVTOR 64 -#define KUVBIASB 96 -#define KUVBIASG 128 -#define KUVBIASR 160 -#define KYTORGB 192 -#endif - -// Conversion matrix for YUV to RGB -extern const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants); // BT.601 -extern const struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants); // JPeg -extern const struct YuvConstants SIMD_ALIGNED(kYuvH709Constants); // BT.709 - -// Conversion matrix for YVU to BGR -extern const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants); // BT.601 -extern const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants); // JPeg -extern const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants); // BT.709 - -#define IS_ALIGNED(p, a) (!((uintptr_t)(p) & ((a)-1))) - -#define align_buffer_64(var, size) \ - uint8_t* var##_mem = (uint8_t*)(malloc((size) + 63)); /* NOLINT */ \ - uint8_t* var = (uint8_t*)(((intptr_t)(var##_mem) + 63) & ~63) /* NOLINT */ - -#define free_aligned_buffer_64(var) \ - free(var##_mem); \ - var = 0 - -#if defined(__APPLE__) || defined(__x86_64__) || defined(__llvm__) -#define OMITFP -#else -#define OMITFP __attribute__((optimize("omit-frame-pointer"))) -#endif - -// NaCL macros for GCC x86 and x64. -#if defined(__native_client__) -#define LABELALIGN ".p2align 5\n" -#else -#define LABELALIGN -#endif - -// Intel Code Analizer markers. Insert IACA_START IACA_END around code to be -// measured and then run with iaca -64 libyuv_unittest. -// IACA_ASM_START amd IACA_ASM_END are equivalents that can be used within -// inline assembly blocks. -// example of iaca: -// ~/iaca-lin64/bin/iaca.sh -64 -analysis LATENCY out/Release/libyuv_unittest - -#if defined(__x86_64__) || defined(__i386__) - -#define IACA_ASM_START \ - ".byte 0x0F, 0x0B\n" \ - " movl $111, %%ebx\n" \ - ".byte 0x64, 0x67, 0x90\n" - -#define IACA_ASM_END \ - " movl $222, %%ebx\n" \ - ".byte 0x64, 0x67, 0x90\n" \ - ".byte 0x0F, 0x0B\n" - -#define IACA_SSC_MARK(MARK_ID) \ - __asm__ __volatile__("\n\t movl $" #MARK_ID \ - ", %%ebx" \ - "\n\t .byte 0x64, 0x67, 0x90" \ - : \ - : \ - : "memory"); - -#define IACA_UD_BYTES __asm__ __volatile__("\n\t .byte 0x0F, 0x0B"); - -#else /* Visual C */ -#define IACA_UD_BYTES \ - { __asm _emit 0x0F __asm _emit 0x0B } - -#define IACA_SSC_MARK(x) \ - { __asm mov ebx, x __asm _emit 0x64 __asm _emit 0x67 __asm _emit 0x90 } - -#define IACA_VC64_START __writegsbyte(111, 111); -#define IACA_VC64_END __writegsbyte(222, 222); -#endif - -#define IACA_START \ - { \ - IACA_UD_BYTES \ - IACA_SSC_MARK(111) \ - } -#define IACA_END \ - { \ - IACA_SSC_MARK(222) \ - IACA_UD_BYTES \ - } - -void I444ToARGBRow_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGBRow_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I422AlphaToARGBRow_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - const uint8_t* src_a, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGBRow_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGBARow_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgba, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB24Row_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB565Row_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB1555Row_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb1555, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB4444Row_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb4444, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToARGBRow_NEON(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToRGB565Row_NEON(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width); -void NV21ToARGBRow_NEON(const uint8_t* src_y, - const uint8_t* src_vu, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToRGB24Row_NEON(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width); -void NV21ToRGB24Row_NEON(const uint8_t* src_y, - const uint8_t* src_vu, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width); -void YUY2ToARGBRow_NEON(const uint8_t* src_yuy2, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void UYVYToARGBRow_NEON(const uint8_t* src_uyvy, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I444ToARGBRow_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); - -void I422ToARGBRow_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGBARow_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I422AlphaToARGBRow_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - const uint8_t* src_a, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB24Row_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB565Row_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB4444Row_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb4444, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB1555Row_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb1555, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToARGBRow_MSA(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToRGB565Row_MSA(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width); -void NV21ToARGBRow_MSA(const uint8_t* src_y, - const uint8_t* src_vu, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void YUY2ToARGBRow_MSA(const uint8_t* src_yuy2, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void UYVYToARGBRow_MSA(const uint8_t* src_uyvy, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); - -void ARGBToYRow_AVX2(const uint8_t* src_argb, uint8_t* dst_y, int width); -void ARGBToYRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void ARGBToYRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_y, int width); -void ARGBToYJRow_AVX2(const uint8_t* src_argb, uint8_t* dst_y, int width); -void ARGBToYJRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void ARGBToYJRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_y, int width); -void BGRAToYRow_SSSE3(const uint8_t* src_bgra, uint8_t* dst_y, int width); -void ABGRToYRow_SSSE3(const uint8_t* src_abgr, uint8_t* dst_y, int width); -void RGBAToYRow_SSSE3(const uint8_t* src_rgba, uint8_t* dst_y, int width); -void RGB24ToYRow_SSSE3(const uint8_t* src_rgb24, uint8_t* dst_y, int width); -void RAWToYRow_SSSE3(const uint8_t* src_raw, uint8_t* dst_y, int width); -void ARGBToYRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width); -void ARGBToYJRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width); -void ARGBToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); -void ARGBToYJRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); -void ARGBToUV444Row_NEON(const uint8_t* src_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVRow_NEON(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUV444Row_MSA(const uint8_t* src_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVRow_MSA(const uint8_t* src_argb0, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVJRow_NEON(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void BGRAToUVRow_NEON(const uint8_t* src_bgra, - int src_stride_bgra, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ABGRToUVRow_NEON(const uint8_t* src_abgr, - int src_stride_abgr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RGBAToUVRow_NEON(const uint8_t* src_rgba, - int src_stride_rgba, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RGB24ToUVRow_NEON(const uint8_t* src_rgb24, - int src_stride_rgb24, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RAWToUVRow_NEON(const uint8_t* src_raw, - int src_stride_raw, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RGB565ToUVRow_NEON(const uint8_t* src_rgb565, - int src_stride_rgb565, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGB1555ToUVRow_NEON(const uint8_t* src_argb1555, - int src_stride_argb1555, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGB4444ToUVRow_NEON(const uint8_t* src_argb4444, - int src_stride_argb4444, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVJRow_MSA(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void BGRAToUVRow_MSA(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ABGRToUVRow_MSA(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RGBAToUVRow_MSA(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RGB24ToUVRow_MSA(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RAWToUVRow_MSA(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RGB565ToUVRow_MSA(const uint8_t* src_rgb565, - int src_stride_rgb565, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGB1555ToUVRow_MSA(const uint8_t* src_argb1555, - int src_stride_argb1555, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void BGRAToYRow_NEON(const uint8_t* src_bgra, uint8_t* dst_y, int width); -void ABGRToYRow_NEON(const uint8_t* src_abgr, uint8_t* dst_y, int width); -void RGBAToYRow_NEON(const uint8_t* src_rgba, uint8_t* dst_y, int width); -void RGB24ToYRow_NEON(const uint8_t* src_rgb24, uint8_t* dst_y, int width); -void RAWToYRow_NEON(const uint8_t* src_raw, uint8_t* dst_y, int width); -void RGB565ToYRow_NEON(const uint8_t* src_rgb565, uint8_t* dst_y, int width); -void ARGB1555ToYRow_NEON(const uint8_t* src_argb1555, - uint8_t* dst_y, - int width); -void ARGB4444ToYRow_NEON(const uint8_t* src_argb4444, - uint8_t* dst_y, - int width); -void BGRAToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); -void ABGRToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); -void RGBAToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); -void RGB24ToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); -void RAWToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); -void RGB565ToYRow_MSA(const uint8_t* src_rgb565, uint8_t* dst_y, int width); -void ARGB1555ToYRow_MSA(const uint8_t* src_argb1555, uint8_t* dst_y, int width); -void ARGBToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width); -void ARGBToYJRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width); -void BGRAToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width); -void ABGRToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width); -void RGBAToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width); -void RGB24ToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width); -void RAWToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width); -void RGB565ToYRow_C(const uint8_t* src_rgb565, uint8_t* dst_y, int width); -void ARGB1555ToYRow_C(const uint8_t* src_argb1555, uint8_t* dst_y, int width); -void ARGB4444ToYRow_C(const uint8_t* src_argb4444, uint8_t* dst_y, int width); -void ARGBToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void ARGBToYJRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void BGRAToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void ABGRToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void RGBAToYRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void RGB24ToYRow_Any_SSSE3(const uint8_t* src_rgb24, uint8_t* dst_y, int width); -void RAWToYRow_Any_SSSE3(const uint8_t* src_raw, uint8_t* dst_y, int width); -void ARGBToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void ARGBToYJRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void BGRAToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void ABGRToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void RGBAToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void RGB24ToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void RAWToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void RGB565ToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void ARGB1555ToYRow_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGB4444ToYRow_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void BGRAToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void ABGRToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void RGBAToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void ARGBToYJRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void ARGBToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void RGB24ToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void RAWToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void RGB565ToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void ARGB1555ToYRow_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); - -void ARGBToUVRow_AVX2(const uint8_t* src_argb0, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVJRow_AVX2(const uint8_t* src_argb0, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVRow_SSSE3(const uint8_t* src_argb0, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVJRow_SSSE3(const uint8_t* src_argb0, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void BGRAToUVRow_SSSE3(const uint8_t* src_bgra0, - int src_stride_bgra, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ABGRToUVRow_SSSE3(const uint8_t* src_abgr0, - int src_stride_abgr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RGBAToUVRow_SSSE3(const uint8_t* src_rgba0, - int src_stride_rgba, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVRow_Any_AVX2(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVJRow_Any_AVX2(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVRow_Any_SSSE3(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVJRow_Any_SSSE3(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void BGRAToUVRow_Any_SSSE3(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ABGRToUVRow_Any_SSSE3(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RGBAToUVRow_Any_SSSE3(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUV444Row_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVRow_Any_NEON(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUV444Row_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVRow_Any_MSA(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVJRow_Any_NEON(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void BGRAToUVRow_Any_NEON(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ABGRToUVRow_Any_NEON(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RGBAToUVRow_Any_NEON(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RGB24ToUVRow_Any_NEON(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RAWToUVRow_Any_NEON(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RGB565ToUVRow_Any_NEON(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGB1555ToUVRow_Any_NEON(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGB4444ToUVRow_Any_NEON(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVJRow_Any_MSA(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void BGRAToUVRow_Any_MSA(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ABGRToUVRow_Any_MSA(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RGBAToUVRow_Any_MSA(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RGB24ToUVRow_Any_MSA(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RAWToUVRow_Any_MSA(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RGB565ToUVRow_Any_MSA(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGB1555ToUVRow_Any_MSA(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVRow_C(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVJRow_C(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVRow_C(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUVJRow_C(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void BGRAToUVRow_C(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ABGRToUVRow_C(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RGBAToUVRow_C(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RGB24ToUVRow_C(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RAWToUVRow_C(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void RGB565ToUVRow_C(const uint8_t* src_rgb565, - int src_stride_rgb565, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGB1555ToUVRow_C(const uint8_t* src_argb1555, - int src_stride_argb1555, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGB4444ToUVRow_C(const uint8_t* src_argb4444, - int src_stride_argb4444, - uint8_t* dst_u, - uint8_t* dst_v, - int width); - -void ARGBToUV444Row_SSSE3(const uint8_t* src_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void ARGBToUV444Row_Any_SSSE3(const uint8_t* src_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); - -void ARGBToUV444Row_C(const uint8_t* src_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width); - -void MirrorRow_AVX2(const uint8_t* src, uint8_t* dst, int width); -void MirrorRow_SSSE3(const uint8_t* src, uint8_t* dst, int width); -void MirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width); -void MirrorRow_MSA(const uint8_t* src, uint8_t* dst, int width); -void MirrorRow_C(const uint8_t* src, uint8_t* dst, int width); -void MirrorRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void MirrorRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void MirrorRow_Any_SSE2(const uint8_t* src, uint8_t* dst, int width); -void MirrorRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void MirrorRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); - -void MirrorUVRow_SSSE3(const uint8_t* src, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void MirrorUVRow_NEON(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void MirrorUVRow_MSA(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void MirrorUVRow_C(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width); - -void ARGBMirrorRow_AVX2(const uint8_t* src, uint8_t* dst, int width); -void ARGBMirrorRow_SSE2(const uint8_t* src, uint8_t* dst, int width); -void ARGBMirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width); -void ARGBMirrorRow_MSA(const uint8_t* src, uint8_t* dst, int width); -void ARGBMirrorRow_C(const uint8_t* src, uint8_t* dst, int width); -void ARGBMirrorRow_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBMirrorRow_Any_SSE2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBMirrorRow_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBMirrorRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); - -void SplitUVRow_C(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void SplitUVRow_SSE2(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void SplitUVRow_AVX2(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void SplitUVRow_NEON(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void SplitUVRow_MSA(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void SplitUVRow_Any_SSE2(const uint8_t* src_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void SplitUVRow_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void SplitUVRow_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void SplitUVRow_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); - -void MergeUVRow_C(const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uv, - int width); -void MergeUVRow_SSE2(const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uv, - int width); -void MergeUVRow_AVX2(const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uv, - int width); -void MergeUVRow_NEON(const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uv, - int width); -void MergeUVRow_MSA(const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uv, - int width); -void MergeUVRow_Any_SSE2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void MergeUVRow_Any_AVX2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void MergeUVRow_Any_NEON(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void MergeUVRow_Any_MSA(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); - -void SplitRGBRow_C(const uint8_t* src_rgb, - uint8_t* dst_r, - uint8_t* dst_g, - uint8_t* dst_b, - int width); -void SplitRGBRow_SSSE3(const uint8_t* src_rgb, - uint8_t* dst_r, - uint8_t* dst_g, - uint8_t* dst_b, - int width); -void SplitRGBRow_NEON(const uint8_t* src_rgb, - uint8_t* dst_r, - uint8_t* dst_g, - uint8_t* dst_b, - int width); -void SplitRGBRow_Any_SSSE3(const uint8_t* src_ptr, - uint8_t* dst_r, - uint8_t* dst_g, - uint8_t* dst_b, - int width); -void SplitRGBRow_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_r, - uint8_t* dst_g, - uint8_t* dst_b, - int width); - -void MergeRGBRow_C(const uint8_t* src_r, - const uint8_t* src_g, - const uint8_t* src_b, - uint8_t* dst_rgb, - int width); -void MergeRGBRow_SSSE3(const uint8_t* src_r, - const uint8_t* src_g, - const uint8_t* src_b, - uint8_t* dst_rgb, - int width); -void MergeRGBRow_NEON(const uint8_t* src_r, - const uint8_t* src_g, - const uint8_t* src_b, - uint8_t* dst_rgb, - int width); -void MergeRGBRow_Any_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - int width); -void MergeRGBRow_Any_NEON(const uint8_t* src_r, - const uint8_t* src_g, - const uint8_t* src_b, - uint8_t* dst_rgb, - int width); - -void MergeUVRow_16_C(const uint16_t* src_u, - const uint16_t* src_v, - uint16_t* dst_uv, - int scale, /* 64 for 10 bit */ - int width); -void MergeUVRow_16_AVX2(const uint16_t* src_u, - const uint16_t* src_v, - uint16_t* dst_uv, - int scale, - int width); - -void MultiplyRow_16_AVX2(const uint16_t* src_y, - uint16_t* dst_y, - int scale, - int width); -void MultiplyRow_16_C(const uint16_t* src_y, - uint16_t* dst_y, - int scale, - int width); - -void Convert8To16Row_C(const uint8_t* src_y, - uint16_t* dst_y, - int scale, - int width); -void Convert8To16Row_SSE2(const uint8_t* src_y, - uint16_t* dst_y, - int scale, - int width); -void Convert8To16Row_AVX2(const uint8_t* src_y, - uint16_t* dst_y, - int scale, - int width); -void Convert8To16Row_Any_SSE2(const uint8_t* src_ptr, - uint16_t* dst_ptr, - int scale, - int width); -void Convert8To16Row_Any_AVX2(const uint8_t* src_ptr, - uint16_t* dst_ptr, - int scale, - int width); - -void Convert16To8Row_C(const uint16_t* src_y, - uint8_t* dst_y, - int scale, - int width); -void Convert16To8Row_SSSE3(const uint16_t* src_y, - uint8_t* dst_y, - int scale, - int width); -void Convert16To8Row_AVX2(const uint16_t* src_y, - uint8_t* dst_y, - int scale, - int width); -void Convert16To8Row_Any_SSSE3(const uint16_t* src_ptr, - uint8_t* dst_ptr, - int scale, - int width); -void Convert16To8Row_Any_AVX2(const uint16_t* src_ptr, - uint8_t* dst_ptr, - int scale, - int width); - -void CopyRow_SSE2(const uint8_t* src, uint8_t* dst, int width); -void CopyRow_AVX(const uint8_t* src, uint8_t* dst, int width); -void CopyRow_ERMS(const uint8_t* src, uint8_t* dst, int width); -void CopyRow_NEON(const uint8_t* src, uint8_t* dst, int width); -void CopyRow_MIPS(const uint8_t* src, uint8_t* dst, int count); -void CopyRow_C(const uint8_t* src, uint8_t* dst, int count); -void CopyRow_Any_SSE2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void CopyRow_Any_AVX(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void CopyRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); - -void CopyRow_16_C(const uint16_t* src, uint16_t* dst, int count); - -void ARGBCopyAlphaRow_C(const uint8_t* src, uint8_t* dst, int width); -void ARGBCopyAlphaRow_SSE2(const uint8_t* src, uint8_t* dst, int width); -void ARGBCopyAlphaRow_AVX2(const uint8_t* src, uint8_t* dst, int width); -void ARGBCopyAlphaRow_Any_SSE2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBCopyAlphaRow_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); - -void ARGBExtractAlphaRow_C(const uint8_t* src_argb, uint8_t* dst_a, int width); -void ARGBExtractAlphaRow_SSE2(const uint8_t* src_argb, - uint8_t* dst_a, - int width); -void ARGBExtractAlphaRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_a, - int width); -void ARGBExtractAlphaRow_NEON(const uint8_t* src_argb, - uint8_t* dst_a, - int width); -void ARGBExtractAlphaRow_MSA(const uint8_t* src_argb, - uint8_t* dst_a, - int width); -void ARGBExtractAlphaRow_Any_SSE2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBExtractAlphaRow_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBExtractAlphaRow_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBExtractAlphaRow_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); - -void ARGBCopyYToAlphaRow_C(const uint8_t* src, uint8_t* dst, int width); -void ARGBCopyYToAlphaRow_SSE2(const uint8_t* src, uint8_t* dst, int width); -void ARGBCopyYToAlphaRow_AVX2(const uint8_t* src, uint8_t* dst, int width); -void ARGBCopyYToAlphaRow_Any_SSE2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBCopyYToAlphaRow_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); - -void SetRow_C(uint8_t* dst, uint8_t v8, int width); -void SetRow_MSA(uint8_t* dst, uint8_t v8, int width); -void SetRow_X86(uint8_t* dst, uint8_t v8, int width); -void SetRow_ERMS(uint8_t* dst, uint8_t v8, int width); -void SetRow_NEON(uint8_t* dst, uint8_t v8, int width); -void SetRow_Any_X86(uint8_t* dst_ptr, uint8_t v32, int width); -void SetRow_Any_NEON(uint8_t* dst_ptr, uint8_t v32, int width); - -void ARGBSetRow_C(uint8_t* dst_argb, uint32_t v32, int width); -void ARGBSetRow_X86(uint8_t* dst_argb, uint32_t v32, int width); -void ARGBSetRow_NEON(uint8_t* dst, uint32_t v32, int width); -void ARGBSetRow_Any_NEON(uint8_t* dst_ptr, uint32_t v32, int width); -void ARGBSetRow_MSA(uint8_t* dst_argb, uint32_t v32, int width); -void ARGBSetRow_Any_MSA(uint8_t* dst_ptr, uint32_t v32, int width); - -// ARGBShufflers for BGRAToARGB etc. -void ARGBShuffleRow_C(const uint8_t* src_argb, - uint8_t* dst_argb, - const uint8_t* shuffler, - int width); -void ARGBShuffleRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_argb, - const uint8_t* shuffler, - int width); -void ARGBShuffleRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_argb, - const uint8_t* shuffler, - int width); -void ARGBShuffleRow_NEON(const uint8_t* src_argb, - uint8_t* dst_argb, - const uint8_t* shuffler, - int width); -void ARGBShuffleRow_MSA(const uint8_t* src_argb, - uint8_t* dst_argb, - const uint8_t* shuffler, - int width); -void ARGBShuffleRow_Any_SSSE3(const uint8_t* src_ptr, - uint8_t* dst_ptr, - const uint8_t* param, - int width); -void ARGBShuffleRow_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - const uint8_t* param, - int width); -void ARGBShuffleRow_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - const uint8_t* param, - int width); -void ARGBShuffleRow_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_ptr, - const uint8_t* param, - int width); - -void RGB24ToARGBRow_SSSE3(const uint8_t* src_rgb24, - uint8_t* dst_argb, - int width); -void RAWToARGBRow_SSSE3(const uint8_t* src_raw, uint8_t* dst_argb, int width); -void RAWToRGB24Row_SSSE3(const uint8_t* src_raw, uint8_t* dst_rgb24, int width); -void RGB565ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width); -void ARGB1555ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width); -void ARGB4444ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width); -void RGB565ToARGBRow_AVX2(const uint8_t* src_rgb565, - uint8_t* dst_argb, - int width); -void ARGB1555ToARGBRow_AVX2(const uint8_t* src_argb1555, - uint8_t* dst_argb, - int width); -void ARGB4444ToARGBRow_AVX2(const uint8_t* src_argb4444, - uint8_t* dst_argb, - int width); - -void RGB24ToARGBRow_NEON(const uint8_t* src_rgb24, - uint8_t* dst_argb, - int width); -void RGB24ToARGBRow_MSA(const uint8_t* src_rgb24, uint8_t* dst_argb, int width); -void RAWToARGBRow_NEON(const uint8_t* src_raw, uint8_t* dst_argb, int width); -void RAWToARGBRow_MSA(const uint8_t* src_raw, uint8_t* dst_argb, int width); -void RAWToRGB24Row_NEON(const uint8_t* src_raw, uint8_t* dst_rgb24, int width); -void RAWToRGB24Row_MSA(const uint8_t* src_raw, uint8_t* dst_rgb24, int width); -void RGB565ToARGBRow_NEON(const uint8_t* src_rgb565, - uint8_t* dst_argb, - int width); -void RGB565ToARGBRow_MSA(const uint8_t* src_rgb565, - uint8_t* dst_argb, - int width); -void ARGB1555ToARGBRow_NEON(const uint8_t* src_argb1555, - uint8_t* dst_argb, - int width); -void ARGB1555ToARGBRow_MSA(const uint8_t* src_argb1555, - uint8_t* dst_argb, - int width); -void ARGB4444ToARGBRow_NEON(const uint8_t* src_argb4444, - uint8_t* dst_argb, - int width); -void ARGB4444ToARGBRow_MSA(const uint8_t* src_argb4444, - uint8_t* dst_argb, - int width); -void RGB24ToARGBRow_C(const uint8_t* src_rgb24, uint8_t* dst_argb, int width); -void RAWToARGBRow_C(const uint8_t* src_raw, uint8_t* dst_argb, int width); -void RAWToRGB24Row_C(const uint8_t* src_raw, uint8_t* dst_rgb24, int width); -void RGB565ToARGBRow_C(const uint8_t* src_rgb565, uint8_t* dst_argb, int width); -void ARGB1555ToARGBRow_C(const uint8_t* src_argb1555, - uint8_t* dst_argb, - int width); -void ARGB4444ToARGBRow_C(const uint8_t* src_argb4444, - uint8_t* dst_argb, - int width); -void AR30ToARGBRow_C(const uint8_t* src_ar30, uint8_t* dst_argb, int width); -void AR30ToABGRRow_C(const uint8_t* src_ar30, uint8_t* dst_abgr, int width); -void ARGBToAR30Row_C(const uint8_t* src_argb, uint8_t* dst_ar30, int width); -void AR30ToAB30Row_C(const uint8_t* src_ar30, uint8_t* dst_ab30, int width); - -void RGB24ToARGBRow_Any_SSSE3(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void RAWToARGBRow_Any_SSSE3(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void RAWToRGB24Row_Any_SSSE3(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); - -void RGB565ToARGBRow_Any_SSE2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGB1555ToARGBRow_Any_SSE2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGB4444ToARGBRow_Any_SSE2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void RGB565ToARGBRow_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGB1555ToARGBRow_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGB4444ToARGBRow_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); - -void RGB24ToARGBRow_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void RGB24ToARGBRow_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void RAWToARGBRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void RAWToARGBRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void RAWToRGB24Row_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void RAWToRGB24Row_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void RGB565ToARGBRow_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void RGB565ToARGBRow_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGB1555ToARGBRow_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGB1555ToARGBRow_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGB4444ToARGBRow_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); - -void ARGB4444ToARGBRow_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); - -void ARGBToRGB24Row_SSSE3(const uint8_t* src, uint8_t* dst, int width); -void ARGBToRAWRow_SSSE3(const uint8_t* src, uint8_t* dst, int width); -void ARGBToRGB565Row_SSE2(const uint8_t* src, uint8_t* dst, int width); -void ARGBToARGB1555Row_SSE2(const uint8_t* src, uint8_t* dst, int width); -void ARGBToARGB4444Row_SSE2(const uint8_t* src, uint8_t* dst, int width); -void ABGRToAR30Row_SSSE3(const uint8_t* src, uint8_t* dst, int width); -void ARGBToAR30Row_SSSE3(const uint8_t* src, uint8_t* dst, int width); - -void ARGBToRAWRow_AVX2(const uint8_t* src, uint8_t* dst, int width); -void ARGBToRGB24Row_AVX2(const uint8_t* src, uint8_t* dst, int width); - -void ARGBToRGB24Row_AVX512VBMI(const uint8_t* src, uint8_t* dst, int width); - -void ARGBToRGB565DitherRow_C(const uint8_t* src_argb, - uint8_t* dst_rgb, - const uint32_t dither4, - int width); -void ARGBToRGB565DitherRow_SSE2(const uint8_t* src, - uint8_t* dst, - const uint32_t dither4, - int width); -void ARGBToRGB565DitherRow_AVX2(const uint8_t* src, - uint8_t* dst, - const uint32_t dither4, - int width); - -void ARGBToRGB565Row_AVX2(const uint8_t* src_argb, uint8_t* dst_rgb, int width); -void ARGBToARGB1555Row_AVX2(const uint8_t* src_argb, - uint8_t* dst_rgb, - int width); -void ARGBToARGB4444Row_AVX2(const uint8_t* src_argb, - uint8_t* dst_rgb, - int width); -void ABGRToAR30Row_AVX2(const uint8_t* src, uint8_t* dst, int width); -void ARGBToAR30Row_AVX2(const uint8_t* src, uint8_t* dst, int width); - -void ARGBToRGB24Row_NEON(const uint8_t* src_argb, - uint8_t* dst_rgb24, - int width); -void ARGBToRAWRow_NEON(const uint8_t* src_argb, uint8_t* dst_raw, int width); -void ARGBToRGB565Row_NEON(const uint8_t* src_argb, - uint8_t* dst_rgb565, - int width); -void ARGBToARGB1555Row_NEON(const uint8_t* src_argb, - uint8_t* dst_argb1555, - int width); -void ARGBToARGB4444Row_NEON(const uint8_t* src_argb, - uint8_t* dst_argb4444, - int width); -void ARGBToRGB565DitherRow_NEON(const uint8_t* src_argb, - uint8_t* dst_rgb, - const uint32_t dither4, - int width); -void ARGBToRGB24Row_MSA(const uint8_t* src_argb, uint8_t* dst_rgb, int width); -void ARGBToRAWRow_MSA(const uint8_t* src_argb, uint8_t* dst_rgb, int width); -void ARGBToRGB565Row_MSA(const uint8_t* src_argb, uint8_t* dst_rgb, int width); -void ARGBToARGB1555Row_MSA(const uint8_t* src_argb, - uint8_t* dst_rgb, - int width); -void ARGBToARGB4444Row_MSA(const uint8_t* src_argb, - uint8_t* dst_rgb, - int width); -void ARGBToRGB565DitherRow_MSA(const uint8_t* src_argb, - uint8_t* dst_rgb, - const uint32_t dither4, - int width); - -void ARGBToRGBARow_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width); -void ARGBToRGB24Row_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width); -void ARGBToRAWRow_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width); -void ARGBToRGB565Row_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width); -void ARGBToARGB1555Row_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width); -void ARGBToARGB4444Row_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width); -void ABGRToAR30Row_C(const uint8_t* src_abgr, uint8_t* dst_ar30, int width); -void ARGBToAR30Row_C(const uint8_t* src_argb, uint8_t* dst_ar30, int width); - -void J400ToARGBRow_SSE2(const uint8_t* src_y, uint8_t* dst_argb, int width); -void J400ToARGBRow_AVX2(const uint8_t* src_y, uint8_t* dst_argb, int width); -void J400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width); -void J400ToARGBRow_MSA(const uint8_t* src_y, uint8_t* dst_argb, int width); -void J400ToARGBRow_C(const uint8_t* src_y, uint8_t* dst_argb, int width); -void J400ToARGBRow_Any_SSE2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void J400ToARGBRow_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void J400ToARGBRow_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void J400ToARGBRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); - -void I444ToARGBRow_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGBRow_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width); -void I422ToAR30Row_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width); -void I210ToAR30Row_C(const uint16_t* src_y, - const uint16_t* src_u, - const uint16_t* src_v, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width); -void I210ToARGBRow_C(const uint16_t* src_y, - const uint16_t* src_u, - const uint16_t* src_v, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width); -void I422AlphaToARGBRow_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - const uint8_t* src_a, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToARGBRow_C(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToRGB565Row_C(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width); -void NV21ToARGBRow_C(const uint8_t* src_y, - const uint8_t* src_vu, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToRGB24Row_C(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width); -void NV21ToRGB24Row_C(const uint8_t* src_y, - const uint8_t* src_vu, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width); -void YUY2ToARGBRow_C(const uint8_t* src_yuy2, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width); -void UYVYToARGBRow_C(const uint8_t* src_uyvy, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGBARow_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB24Row_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB4444Row_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb4444, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB1555Row_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb1555, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB565Row_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGBRow_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGBARow_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I444ToARGBRow_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I444ToARGBRow_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I444ToARGBRow_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I444ToARGBRow_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGBRow_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); - -void I422ToAR30Row_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ar30, - const struct YuvConstants* yuvconstants, - int width); -void I210ToAR30Row_SSSE3(const uint16_t* y_buf, - const uint16_t* u_buf, - const uint16_t* v_buf, - uint8_t* dst_ar30, - const struct YuvConstants* yuvconstants, - int width); -void I210ToARGBRow_SSSE3(const uint16_t* y_buf, - const uint16_t* u_buf, - const uint16_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I422ToAR30Row_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ar30, - const struct YuvConstants* yuvconstants, - int width); -void I210ToARGBRow_AVX2(const uint16_t* y_buf, - const uint16_t* u_buf, - const uint16_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I210ToAR30Row_AVX2(const uint16_t* y_buf, - const uint16_t* u_buf, - const uint16_t* v_buf, - uint8_t* dst_ar30, - const struct YuvConstants* yuvconstants, - int width); -void I422AlphaToARGBRow_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - const uint8_t* a_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I422AlphaToARGBRow_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - const uint8_t* a_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToARGBRow_SSSE3(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToARGBRow_AVX2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToRGB24Row_SSSE3(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width); -void NV21ToRGB24Row_SSSE3(const uint8_t* src_y, - const uint8_t* src_vu, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToRGB565Row_SSSE3(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToRGB24Row_AVX2(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width); -void NV21ToRGB24Row_AVX2(const uint8_t* src_y, - const uint8_t* src_vu, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToRGB565Row_AVX2(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width); -void NV21ToARGBRow_SSSE3(const uint8_t* y_buf, - const uint8_t* vu_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void NV21ToARGBRow_AVX2(const uint8_t* y_buf, - const uint8_t* vu_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void YUY2ToARGBRow_SSSE3(const uint8_t* yuy2_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void UYVYToARGBRow_SSSE3(const uint8_t* uyvy_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void YUY2ToARGBRow_AVX2(const uint8_t* yuy2_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void UYVYToARGBRow_AVX2(const uint8_t* uyvy_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGBARow_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_rgba, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB4444Row_SSSE3(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb4444, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB4444Row_AVX2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb4444, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB1555Row_SSSE3(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb1555, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB1555Row_AVX2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb1555, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB565Row_SSSE3(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB565Row_AVX2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB24Row_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB24Row_AVX2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGBRow_Any_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGBARow_Any_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I444ToARGBRow_Any_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I444ToARGBRow_Any_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGBRow_Any_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToAR30Row_Any_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I210ToAR30Row_Any_SSSE3(const uint16_t* y_buf, - const uint16_t* u_buf, - const uint16_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I210ToARGBRow_Any_SSSE3(const uint16_t* y_buf, - const uint16_t* u_buf, - const uint16_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToAR30Row_Any_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I210ToARGBRow_Any_AVX2(const uint16_t* y_buf, - const uint16_t* u_buf, - const uint16_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I210ToAR30Row_Any_AVX2(const uint16_t* y_buf, - const uint16_t* u_buf, - const uint16_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422AlphaToARGBRow_Any_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - const uint8_t* a_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422AlphaToARGBRow_Any_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - const uint8_t* a_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToARGBRow_Any_SSSE3(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToARGBRow_Any_AVX2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV21ToARGBRow_Any_SSSE3(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV21ToARGBRow_Any_AVX2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToRGB24Row_Any_SSSE3(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV21ToRGB24Row_Any_SSSE3(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToRGB24Row_Any_AVX2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV21ToRGB24Row_Any_AVX2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToRGB565Row_Any_SSSE3(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToRGB565Row_Any_AVX2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void YUY2ToARGBRow_Any_SSSE3(const uint8_t* src_ptr, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void UYVYToARGBRow_Any_SSSE3(const uint8_t* src_ptr, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void YUY2ToARGBRow_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void UYVYToARGBRow_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGBARow_Any_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB4444Row_Any_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB4444Row_Any_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB1555Row_Any_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB1555Row_Any_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB565Row_Any_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB565Row_Any_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB24Row_Any_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB24Row_Any_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); - -void I400ToARGBRow_C(const uint8_t* src_y, uint8_t* rgb_buf, int width); -void I400ToARGBRow_SSE2(const uint8_t* y_buf, uint8_t* dst_argb, int width); -void I400ToARGBRow_AVX2(const uint8_t* y_buf, uint8_t* dst_argb, int width); -void I400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width); -void I400ToARGBRow_MSA(const uint8_t* src_y, uint8_t* dst_argb, int width); -void I400ToARGBRow_Any_SSE2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void I400ToARGBRow_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void I400ToARGBRow_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void I400ToARGBRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); - -// ARGB preattenuated alpha blend. -void ARGBBlendRow_SSSE3(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBBlendRow_NEON(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBBlendRow_MSA(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBBlendRow_C(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); - -// Unattenuated planar alpha blend. -void BlendPlaneRow_SSSE3(const uint8_t* src0, - const uint8_t* src1, - const uint8_t* alpha, - uint8_t* dst, - int width); -void BlendPlaneRow_Any_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - int width); -void BlendPlaneRow_AVX2(const uint8_t* src0, - const uint8_t* src1, - const uint8_t* alpha, - uint8_t* dst, - int width); -void BlendPlaneRow_Any_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - int width); -void BlendPlaneRow_C(const uint8_t* src0, - const uint8_t* src1, - const uint8_t* alpha, - uint8_t* dst, - int width); - -// ARGB multiply images. Same API as Blend, but these require -// pointer and width alignment for SSE2. -void ARGBMultiplyRow_C(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBMultiplyRow_SSE2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBMultiplyRow_Any_SSE2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void ARGBMultiplyRow_AVX2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBMultiplyRow_Any_AVX2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void ARGBMultiplyRow_NEON(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBMultiplyRow_Any_NEON(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void ARGBMultiplyRow_MSA(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBMultiplyRow_Any_MSA(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); - -// ARGB add images. -void ARGBAddRow_C(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBAddRow_SSE2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBAddRow_Any_SSE2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void ARGBAddRow_AVX2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBAddRow_Any_AVX2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void ARGBAddRow_NEON(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBAddRow_Any_NEON(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void ARGBAddRow_MSA(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBAddRow_Any_MSA(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); - -// ARGB subtract images. Same API as Blend, but these require -// pointer and width alignment for SSE2. -void ARGBSubtractRow_C(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBSubtractRow_SSE2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBSubtractRow_Any_SSE2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void ARGBSubtractRow_AVX2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBSubtractRow_Any_AVX2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void ARGBSubtractRow_NEON(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBSubtractRow_Any_NEON(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void ARGBSubtractRow_MSA(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width); -void ARGBSubtractRow_Any_MSA(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); - -void ARGBToRGB24Row_Any_SSSE3(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToRAWRow_Any_SSSE3(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToRGB565Row_Any_SSE2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToARGB1555Row_Any_SSE2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToARGB4444Row_Any_SSE2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ABGRToAR30Row_Any_SSSE3(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToAR30Row_Any_SSSE3(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToRAWRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void ARGBToRGB24Row_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToRGB24Row_Any_AVX512VBMI(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToRGB565DitherRow_Any_SSE2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - const uint32_t param, - int width); -void ARGBToRGB565DitherRow_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - const uint32_t param, - int width); - -void ARGBToRGB565Row_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToARGB1555Row_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToARGB4444Row_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ABGRToAR30Row_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToAR30Row_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); - -void ARGBToRGB24Row_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToRAWRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void ARGBToRGB565Row_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToARGB1555Row_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToARGB4444Row_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToRGB565DitherRow_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - const uint32_t param, - int width); -void ARGBToRGB24Row_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToRAWRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void ARGBToRGB565Row_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToARGB1555Row_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToARGB4444Row_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBToRGB565DitherRow_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_ptr, - const uint32_t param, - int width); - -void I444ToARGBRow_Any_NEON(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGBRow_Any_NEON(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422AlphaToARGBRow_Any_NEON(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - const uint8_t* a_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGBARow_Any_NEON(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB24Row_Any_NEON(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB4444Row_Any_NEON(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB1555Row_Any_NEON(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB565Row_Any_NEON(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToARGBRow_Any_NEON(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV21ToARGBRow_Any_NEON(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToRGB24Row_Any_NEON(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV21ToRGB24Row_Any_NEON(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToRGB565Row_Any_NEON(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void YUY2ToARGBRow_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void UYVYToARGBRow_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I444ToARGBRow_Any_MSA(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGBRow_Any_MSA(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGBARow_Any_MSA(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422AlphaToARGBRow_Any_MSA(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - const uint8_t* a_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB24Row_Any_MSA(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToRGB565Row_Any_MSA(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB4444Row_Any_MSA(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void I422ToARGB1555Row_Any_MSA(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToARGBRow_Any_MSA(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV12ToRGB565Row_Any_MSA(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void NV21ToARGBRow_Any_MSA(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void YUY2ToARGBRow_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); -void UYVYToARGBRow_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_ptr, - const struct YuvConstants* yuvconstants, - int width); - -void YUY2ToYRow_AVX2(const uint8_t* src_yuy2, uint8_t* dst_y, int width); -void YUY2ToUVRow_AVX2(const uint8_t* src_yuy2, - int stride_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void YUY2ToUV422Row_AVX2(const uint8_t* src_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void YUY2ToYRow_SSE2(const uint8_t* src_yuy2, uint8_t* dst_y, int width); -void YUY2ToUVRow_SSE2(const uint8_t* src_yuy2, - int stride_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void YUY2ToUV422Row_SSE2(const uint8_t* src_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void YUY2ToYRow_NEON(const uint8_t* src_yuy2, uint8_t* dst_y, int width); -void YUY2ToUVRow_NEON(const uint8_t* src_yuy2, - int stride_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void YUY2ToUV422Row_NEON(const uint8_t* src_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void YUY2ToYRow_MSA(const uint8_t* src_yuy2, uint8_t* dst_y, int width); -void YUY2ToUVRow_MSA(const uint8_t* src_yuy2, - int src_stride_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void YUY2ToUV422Row_MSA(const uint8_t* src_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void YUY2ToYRow_C(const uint8_t* src_yuy2, uint8_t* dst_y, int width); -void YUY2ToUVRow_C(const uint8_t* src_yuy2, - int src_stride_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void YUY2ToUV422Row_C(const uint8_t* src_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void YUY2ToYRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void YUY2ToUVRow_Any_AVX2(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void YUY2ToUV422Row_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void YUY2ToYRow_Any_SSE2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void YUY2ToUVRow_Any_SSE2(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void YUY2ToUV422Row_Any_SSE2(const uint8_t* src_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void YUY2ToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void YUY2ToUVRow_Any_NEON(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void YUY2ToUV422Row_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void YUY2ToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void YUY2ToUVRow_Any_MSA(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void YUY2ToUV422Row_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToYRow_AVX2(const uint8_t* src_uyvy, uint8_t* dst_y, int width); -void UYVYToUVRow_AVX2(const uint8_t* src_uyvy, - int stride_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToUV422Row_AVX2(const uint8_t* src_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToYRow_SSE2(const uint8_t* src_uyvy, uint8_t* dst_y, int width); -void UYVYToUVRow_SSE2(const uint8_t* src_uyvy, - int stride_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToUV422Row_SSE2(const uint8_t* src_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToYRow_AVX2(const uint8_t* src_uyvy, uint8_t* dst_y, int width); -void UYVYToUVRow_AVX2(const uint8_t* src_uyvy, - int stride_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToUV422Row_AVX2(const uint8_t* src_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToYRow_NEON(const uint8_t* src_uyvy, uint8_t* dst_y, int width); -void UYVYToUVRow_NEON(const uint8_t* src_uyvy, - int stride_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToUV422Row_NEON(const uint8_t* src_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToYRow_MSA(const uint8_t* src_uyvy, uint8_t* dst_y, int width); -void UYVYToUVRow_MSA(const uint8_t* src_uyvy, - int src_stride_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToUV422Row_MSA(const uint8_t* src_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width); - -void UYVYToYRow_C(const uint8_t* src_uyvy, uint8_t* dst_y, int width); -void UYVYToUVRow_C(const uint8_t* src_uyvy, - int src_stride_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToUV422Row_C(const uint8_t* src_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToYRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void UYVYToUVRow_Any_AVX2(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToUV422Row_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToYRow_Any_SSE2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void UYVYToUVRow_Any_SSE2(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToUV422Row_Any_SSE2(const uint8_t* src_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToYRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void UYVYToUVRow_Any_NEON(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToUV422Row_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); -void UYVYToUVRow_Any_MSA(const uint8_t* src_ptr, - int src_stride_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); -void UYVYToUV422Row_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_u, - uint8_t* dst_v, - int width); - -void I422ToYUY2Row_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_frame, - int width); -void I422ToUYVYRow_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_frame, - int width); -void I422ToYUY2Row_SSE2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_yuy2, - int width); -void I422ToUYVYRow_SSE2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uyvy, - int width); -void I422ToYUY2Row_Any_SSE2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - int width); -void I422ToUYVYRow_Any_SSE2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - int width); -void I422ToYUY2Row_AVX2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_yuy2, - int width); -void I422ToUYVYRow_AVX2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uyvy, - int width); -void I422ToYUY2Row_Any_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - int width); -void I422ToUYVYRow_Any_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - int width); -void I422ToYUY2Row_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_yuy2, - int width); -void I422ToUYVYRow_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uyvy, - int width); -void I422ToYUY2Row_Any_NEON(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - int width); -void I422ToUYVYRow_Any_NEON(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - int width); -void I422ToYUY2Row_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_yuy2, - int width); -void I422ToUYVYRow_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uyvy, - int width); -void I422ToYUY2Row_Any_MSA(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - int width); -void I422ToUYVYRow_Any_MSA(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ptr, - int width); - -// Effects related row functions. -void ARGBAttenuateRow_C(const uint8_t* src_argb, uint8_t* dst_argb, int width); -void ARGBAttenuateRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_argb, - int width); -void ARGBAttenuateRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_argb, - int width); -void ARGBAttenuateRow_NEON(const uint8_t* src_argb, - uint8_t* dst_argb, - int width); -void ARGBAttenuateRow_MSA(const uint8_t* src_argb, - uint8_t* dst_argb, - int width); -void ARGBAttenuateRow_Any_SSSE3(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBAttenuateRow_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBAttenuateRow_Any_NEON(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBAttenuateRow_Any_MSA(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); - -// Inverse table for unattenuate, shared by C and SSE2. -extern const uint32_t fixed_invtbl8[256]; -void ARGBUnattenuateRow_C(const uint8_t* src_argb, - uint8_t* dst_argb, - int width); -void ARGBUnattenuateRow_SSE2(const uint8_t* src_argb, - uint8_t* dst_argb, - int width); -void ARGBUnattenuateRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_argb, - int width); -void ARGBUnattenuateRow_Any_SSE2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); -void ARGBUnattenuateRow_Any_AVX2(const uint8_t* src_ptr, - uint8_t* dst_ptr, - int width); - -void ARGBGrayRow_C(const uint8_t* src_argb, uint8_t* dst_argb, int width); -void ARGBGrayRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_argb, int width); -void ARGBGrayRow_NEON(const uint8_t* src_argb, uint8_t* dst_argb, int width); -void ARGBGrayRow_MSA(const uint8_t* src_argb, uint8_t* dst_argb, int width); - -void ARGBSepiaRow_C(uint8_t* dst_argb, int width); -void ARGBSepiaRow_SSSE3(uint8_t* dst_argb, int width); -void ARGBSepiaRow_NEON(uint8_t* dst_argb, int width); -void ARGBSepiaRow_MSA(uint8_t* dst_argb, int width); - -void ARGBColorMatrixRow_C(const uint8_t* src_argb, - uint8_t* dst_argb, - const int8_t* matrix_argb, - int width); -void ARGBColorMatrixRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_argb, - const int8_t* matrix_argb, - int width); -void ARGBColorMatrixRow_NEON(const uint8_t* src_argb, - uint8_t* dst_argb, - const int8_t* matrix_argb, - int width); -void ARGBColorMatrixRow_MSA(const uint8_t* src_argb, - uint8_t* dst_argb, - const int8_t* matrix_argb, - int width); - -void ARGBColorTableRow_C(uint8_t* dst_argb, - const uint8_t* table_argb, - int width); -void ARGBColorTableRow_X86(uint8_t* dst_argb, - const uint8_t* table_argb, - int width); - -void RGBColorTableRow_C(uint8_t* dst_argb, - const uint8_t* table_argb, - int width); -void RGBColorTableRow_X86(uint8_t* dst_argb, - const uint8_t* table_argb, - int width); - -void ARGBQuantizeRow_C(uint8_t* dst_argb, - int scale, - int interval_size, - int interval_offset, - int width); -void ARGBQuantizeRow_SSE2(uint8_t* dst_argb, - int scale, - int interval_size, - int interval_offset, - int width); -void ARGBQuantizeRow_NEON(uint8_t* dst_argb, - int scale, - int interval_size, - int interval_offset, - int width); -void ARGBQuantizeRow_MSA(uint8_t* dst_argb, - int scale, - int interval_size, - int interval_offset, - int width); - -void ARGBShadeRow_C(const uint8_t* src_argb, - uint8_t* dst_argb, - int width, - uint32_t value); -void ARGBShadeRow_SSE2(const uint8_t* src_argb, - uint8_t* dst_argb, - int width, - uint32_t value); -void ARGBShadeRow_NEON(const uint8_t* src_argb, - uint8_t* dst_argb, - int width, - uint32_t value); -void ARGBShadeRow_MSA(const uint8_t* src_argb, - uint8_t* dst_argb, - int width, - uint32_t value); - -// Used for blur. -void CumulativeSumToAverageRow_SSE2(const int32_t* topleft, - const int32_t* botleft, - int width, - int area, - uint8_t* dst, - int count); -void ComputeCumulativeSumRow_SSE2(const uint8_t* row, - int32_t* cumsum, - const int32_t* previous_cumsum, - int width); - -void CumulativeSumToAverageRow_C(const int32_t* tl, - const int32_t* bl, - int w, - int area, - uint8_t* dst, - int count); -void ComputeCumulativeSumRow_C(const uint8_t* row, - int32_t* cumsum, - const int32_t* previous_cumsum, - int width); - -LIBYUV_API -void ARGBAffineRow_C(const uint8_t* src_argb, - int src_argb_stride, - uint8_t* dst_argb, - const float* uv_dudv, - int width); -LIBYUV_API -void ARGBAffineRow_SSE2(const uint8_t* src_argb, - int src_argb_stride, - uint8_t* dst_argb, - const float* src_dudv, - int width); - -// Used for I420Scale, ARGBScale, and ARGBInterpolate. -void InterpolateRow_C(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride, - int width, - int source_y_fraction); -void InterpolateRow_SSSE3(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride, - int dst_width, - int source_y_fraction); -void InterpolateRow_AVX2(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride, - int dst_width, - int source_y_fraction); -void InterpolateRow_NEON(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride, - int dst_width, - int source_y_fraction); -void InterpolateRow_MSA(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride, - int width, - int source_y_fraction); -void InterpolateRow_Any_NEON(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride_ptr, - int width, - int source_y_fraction); -void InterpolateRow_Any_SSSE3(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride_ptr, - int width, - int source_y_fraction); -void InterpolateRow_Any_AVX2(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride_ptr, - int width, - int source_y_fraction); -void InterpolateRow_Any_MSA(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride_ptr, - int width, - int source_y_fraction); - -void InterpolateRow_16_C(uint16_t* dst_ptr, - const uint16_t* src_ptr, - ptrdiff_t src_stride, - int width, - int source_y_fraction); - -// Sobel images. -void SobelXRow_C(const uint8_t* src_y0, - const uint8_t* src_y1, - const uint8_t* src_y2, - uint8_t* dst_sobelx, - int width); -void SobelXRow_SSE2(const uint8_t* src_y0, - const uint8_t* src_y1, - const uint8_t* src_y2, - uint8_t* dst_sobelx, - int width); -void SobelXRow_NEON(const uint8_t* src_y0, - const uint8_t* src_y1, - const uint8_t* src_y2, - uint8_t* dst_sobelx, - int width); -void SobelXRow_MSA(const uint8_t* src_y0, - const uint8_t* src_y1, - const uint8_t* src_y2, - uint8_t* dst_sobelx, - int width); -void SobelYRow_C(const uint8_t* src_y0, - const uint8_t* src_y1, - uint8_t* dst_sobely, - int width); -void SobelYRow_SSE2(const uint8_t* src_y0, - const uint8_t* src_y1, - uint8_t* dst_sobely, - int width); -void SobelYRow_NEON(const uint8_t* src_y0, - const uint8_t* src_y1, - uint8_t* dst_sobely, - int width); -void SobelYRow_MSA(const uint8_t* src_y0, - const uint8_t* src_y1, - uint8_t* dst_sobely, - int width); -void SobelRow_C(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width); -void SobelRow_SSE2(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width); -void SobelRow_NEON(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width); -void SobelRow_MSA(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width); -void SobelToPlaneRow_C(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_y, - int width); -void SobelToPlaneRow_SSE2(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_y, - int width); -void SobelToPlaneRow_NEON(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_y, - int width); -void SobelToPlaneRow_MSA(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_y, - int width); -void SobelXYRow_C(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width); -void SobelXYRow_SSE2(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width); -void SobelXYRow_NEON(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width); -void SobelXYRow_MSA(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width); -void SobelRow_Any_SSE2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void SobelRow_Any_NEON(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void SobelRow_Any_MSA(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void SobelToPlaneRow_Any_SSE2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void SobelToPlaneRow_Any_NEON(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void SobelToPlaneRow_Any_MSA(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void SobelXYRow_Any_SSE2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void SobelXYRow_Any_NEON(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); -void SobelXYRow_Any_MSA(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_ptr, - int width); - -void ARGBPolynomialRow_C(const uint8_t* src_argb, - uint8_t* dst_argb, - const float* poly, - int width); -void ARGBPolynomialRow_SSE2(const uint8_t* src_argb, - uint8_t* dst_argb, - const float* poly, - int width); -void ARGBPolynomialRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_argb, - const float* poly, - int width); - -// Scale and convert to half float. -void HalfFloatRow_C(const uint16_t* src, uint16_t* dst, float scale, int width); -void HalfFloatRow_SSE2(const uint16_t* src, - uint16_t* dst, - float scale, - int width); -void HalfFloatRow_Any_SSE2(const uint16_t* src_ptr, - uint16_t* dst_ptr, - float param, - int width); -void HalfFloatRow_AVX2(const uint16_t* src, - uint16_t* dst, - float scale, - int width); -void HalfFloatRow_Any_AVX2(const uint16_t* src_ptr, - uint16_t* dst_ptr, - float param, - int width); -void HalfFloatRow_F16C(const uint16_t* src, - uint16_t* dst, - float scale, - int width); -void HalfFloatRow_Any_F16C(const uint16_t* src, - uint16_t* dst, - float scale, - int width); -void HalfFloat1Row_F16C(const uint16_t* src, - uint16_t* dst, - float scale, - int width); -void HalfFloat1Row_Any_F16C(const uint16_t* src, - uint16_t* dst, - float scale, - int width); -void HalfFloatRow_NEON(const uint16_t* src, - uint16_t* dst, - float scale, - int width); -void HalfFloatRow_Any_NEON(const uint16_t* src_ptr, - uint16_t* dst_ptr, - float param, - int width); -void HalfFloat1Row_NEON(const uint16_t* src, - uint16_t* dst, - float scale, - int width); -void HalfFloat1Row_Any_NEON(const uint16_t* src_ptr, - uint16_t* dst_ptr, - float param, - int width); -void HalfFloatRow_MSA(const uint16_t* src, - uint16_t* dst, - float scale, - int width); -void HalfFloatRow_Any_MSA(const uint16_t* src_ptr, - uint16_t* dst_ptr, - float param, - int width); -void ByteToFloatRow_C(const uint8_t* src, float* dst, float scale, int width); -void ByteToFloatRow_NEON(const uint8_t* src, - float* dst, - float scale, - int width); -void ByteToFloatRow_Any_NEON(const uint8_t* src_ptr, - float* dst_ptr, - float param, - int width); - -void ARGBLumaColorTableRow_C(const uint8_t* src_argb, - uint8_t* dst_argb, - int width, - const uint8_t* luma, - uint32_t lumacoeff); -void ARGBLumaColorTableRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_argb, - int width, - const uint8_t* luma, - uint32_t lumacoeff); - -float ScaleMaxSamples_C(const float* src, float* dst, float scale, int width); -float ScaleMaxSamples_NEON(const float* src, - float* dst, - float scale, - int width); -float ScaleSumSamples_C(const float* src, float* dst, float scale, int width); -float ScaleSumSamples_NEON(const float* src, - float* dst, - float scale, - int width); -void ScaleSamples_C(const float* src, float* dst, float scale, int width); -void ScaleSamples_NEON(const float* src, float* dst, float scale, int width); - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // INCLUDE_LIBYUV_ROW_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/scale.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/scale.h deleted file mode 100644 index b937d348..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/scale.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_SCALE_H_ -#define INCLUDE_LIBYUV_SCALE_H_ - -#include "libyuv/basic_types.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// Supported filtering. -typedef enum FilterMode { - kFilterNone = 0, // Point sample; Fastest. - kFilterLinear = 1, // Filter horizontally only. - kFilterBilinear = 2, // Faster than box, but lower quality scaling down. - kFilterBox = 3 // Highest quality. -} FilterModeEnum; - -// Scale a YUV plane. -LIBYUV_API -void ScalePlane(const uint8_t* src, - int src_stride, - int src_width, - int src_height, - uint8_t* dst, - int dst_stride, - int dst_width, - int dst_height, - enum FilterMode filtering); - -LIBYUV_API -void ScalePlane_16(const uint16_t* src, - int src_stride, - int src_width, - int src_height, - uint16_t* dst, - int dst_stride, - int dst_width, - int dst_height, - enum FilterMode filtering); - -// Scales a YUV 4:2:0 image from the src width and height to the -// dst width and height. -// If filtering is kFilterNone, a simple nearest-neighbor algorithm is -// used. This produces basic (blocky) quality at the fastest speed. -// If filtering is kFilterBilinear, interpolation is used to produce a better -// quality image, at the expense of speed. -// If filtering is kFilterBox, averaging is used to produce ever better -// quality image, at further expense of speed. -// Returns 0 if successful. - -LIBYUV_API -int I420Scale(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - int src_width, - int src_height, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int dst_width, - int dst_height, - enum FilterMode filtering); - -LIBYUV_API -int I420Scale_16(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - int src_width, - int src_height, - uint16_t* dst_y, - int dst_stride_y, - uint16_t* dst_u, - int dst_stride_u, - uint16_t* dst_v, - int dst_stride_v, - int dst_width, - int dst_height, - enum FilterMode filtering); - -#ifdef __cplusplus -// Legacy API. Deprecated. -LIBYUV_API -int Scale(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - int src_stride_y, - int src_stride_u, - int src_stride_v, - int src_width, - int src_height, - uint8_t* dst_y, - uint8_t* dst_u, - uint8_t* dst_v, - int dst_stride_y, - int dst_stride_u, - int dst_stride_v, - int dst_width, - int dst_height, - LIBYUV_BOOL interpolate); - -// For testing, allow disabling of specialized scalers. -LIBYUV_API -void SetUseReferenceImpl(LIBYUV_BOOL use); -#endif // __cplusplus - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // INCLUDE_LIBYUV_SCALE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/scale_argb.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/scale_argb.h deleted file mode 100644 index 7641f18e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/scale_argb.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2012 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_SCALE_ARGB_H_ -#define INCLUDE_LIBYUV_SCALE_ARGB_H_ - -#include "libyuv/basic_types.h" -#include "libyuv/scale.h" // For FilterMode - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -LIBYUV_API -int ARGBScale(const uint8_t* src_argb, - int src_stride_argb, - int src_width, - int src_height, - uint8_t* dst_argb, - int dst_stride_argb, - int dst_width, - int dst_height, - enum FilterMode filtering); - -// Clipped scale takes destination rectangle coordinates for clip values. -LIBYUV_API -int ARGBScaleClip(const uint8_t* src_argb, - int src_stride_argb, - int src_width, - int src_height, - uint8_t* dst_argb, - int dst_stride_argb, - int dst_width, - int dst_height, - int clip_x, - int clip_y, - int clip_width, - int clip_height, - enum FilterMode filtering); - -// Scale with YUV conversion to ARGB and clipping. -LIBYUV_API -int YUVToARGBScaleClip(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint32_t src_fourcc, - int src_width, - int src_height, - uint8_t* dst_argb, - int dst_stride_argb, - uint32_t dst_fourcc, - int dst_width, - int dst_height, - int clip_x, - int clip_y, - int clip_width, - int clip_height, - enum FilterMode filtering); - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // INCLUDE_LIBYUV_SCALE_ARGB_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/scale_row.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/scale_row.h deleted file mode 100644 index 7194ba09..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/scale_row.h +++ /dev/null @@ -1,944 +0,0 @@ -/* - * Copyright 2013 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_SCALE_ROW_H_ -#define INCLUDE_LIBYUV_SCALE_ROW_H_ - -#include "libyuv/basic_types.h" -#include "libyuv/scale.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -#if defined(__pnacl__) || defined(__CLR_VER) || \ - (defined(__native_client__) && defined(__x86_64__)) || \ - (defined(__i386__) && !defined(__SSE__) && !defined(__clang__)) -#define LIBYUV_DISABLE_X86 -#endif -#if defined(__native_client__) -#define LIBYUV_DISABLE_NEON -#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__)) -#if (__GNUC__ > 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 7)) -#define GCC_HAS_AVX2 1 -#endif // GNUC >= 4.7 -#endif // __GNUC__ - -// clang >= 3.4.0 required for AVX2. -#if defined(__clang__) && (defined(__x86_64__) || defined(__i386__)) -#if (__clang_major__ > 3) || (__clang_major__ == 3 && (__clang_minor__ >= 4)) -#define CLANG_HAS_AVX2 1 -#endif // clang >= 3.4 -#endif // __clang__ - -// Visual C 2012 required for AVX2. -#if defined(_M_IX86) && !defined(__clang__) && defined(_MSC_VER) && \ - _MSC_VER >= 1700 -#define VISUALC_HAS_AVX2 1 -#endif // VisualStudio >= 2012 - -// The following are available on all x86 platforms: -#if !defined(LIBYUV_DISABLE_X86) && \ - (defined(_M_IX86) || defined(__x86_64__) || defined(__i386__)) -#define HAS_FIXEDDIV1_X86 -#define HAS_FIXEDDIV_X86 -#define HAS_SCALEARGBCOLS_SSE2 -#define HAS_SCALEARGBCOLSUP2_SSE2 -#define HAS_SCALEARGBFILTERCOLS_SSSE3 -#define HAS_SCALEARGBROWDOWN2_SSE2 -#define HAS_SCALEARGBROWDOWNEVEN_SSE2 -#define HAS_SCALECOLSUP2_SSE2 -#define HAS_SCALEFILTERCOLS_SSSE3 -#define HAS_SCALEROWDOWN2_SSSE3 -#define HAS_SCALEROWDOWN34_SSSE3 -#define HAS_SCALEROWDOWN38_SSSE3 -#define HAS_SCALEROWDOWN4_SSSE3 -#define HAS_SCALEADDROW_SSE2 -#endif - -// The following are available on all x86 platforms, but -// require VS2012, clang 3.4 or gcc 4.7. -// The code supports NaCL but requires a new compiler and validator. -#if !defined(LIBYUV_DISABLE_X86) && \ - (defined(VISUALC_HAS_AVX2) || defined(CLANG_HAS_AVX2) || \ - defined(GCC_HAS_AVX2)) -#define HAS_SCALEADDROW_AVX2 -#define HAS_SCALEROWDOWN2_AVX2 -#define HAS_SCALEROWDOWN4_AVX2 -#endif - -// The following are available on Neon platforms: -#if !defined(LIBYUV_DISABLE_NEON) && \ - (defined(__ARM_NEON__) || defined(LIBYUV_NEON) || defined(__aarch64__)) -#define HAS_SCALEARGBCOLS_NEON -#define HAS_SCALEARGBROWDOWN2_NEON -#define HAS_SCALEARGBROWDOWNEVEN_NEON -#define HAS_SCALEFILTERCOLS_NEON -#define HAS_SCALEROWDOWN2_NEON -#define HAS_SCALEROWDOWN34_NEON -#define HAS_SCALEROWDOWN38_NEON -#define HAS_SCALEROWDOWN4_NEON -#define HAS_SCALEARGBFILTERCOLS_NEON -#endif - -#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) -#define HAS_SCALEADDROW_MSA -#define HAS_SCALEARGBCOLS_MSA -#define HAS_SCALEARGBFILTERCOLS_MSA -#define HAS_SCALEARGBROWDOWN2_MSA -#define HAS_SCALEARGBROWDOWNEVEN_MSA -#define HAS_SCALEFILTERCOLS_MSA -#define HAS_SCALEROWDOWN2_MSA -#define HAS_SCALEROWDOWN34_MSA -#define HAS_SCALEROWDOWN38_MSA -#define HAS_SCALEROWDOWN4_MSA -#endif - -// Scale ARGB vertically with bilinear interpolation. -void ScalePlaneVertical(int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_argb, - uint8_t* dst_argb, - int x, - int y, - int dy, - int bpp, - enum FilterMode filtering); - -void ScalePlaneVertical_16(int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint16_t* src_argb, - uint16_t* dst_argb, - int x, - int y, - int dy, - int wpp, - enum FilterMode filtering); - -// Simplify the filtering based on scale factors. -enum FilterMode ScaleFilterReduce(int src_width, - int src_height, - int dst_width, - int dst_height, - enum FilterMode filtering); - -// Divide num by div and return as 16.16 fixed point result. -int FixedDiv_C(int num, int div); -int FixedDiv_X86(int num, int div); -// Divide num - 1 by div - 1 and return as 16.16 fixed point result. -int FixedDiv1_C(int num, int div); -int FixedDiv1_X86(int num, int div); -#ifdef HAS_FIXEDDIV_X86 -#define FixedDiv FixedDiv_X86 -#define FixedDiv1 FixedDiv1_X86 -#else -#define FixedDiv FixedDiv_C -#define FixedDiv1 FixedDiv1_C -#endif - -// Compute slope values for stepping. -void ScaleSlope(int src_width, - int src_height, - int dst_width, - int dst_height, - enum FilterMode filtering, - int* x, - int* y, - int* dx, - int* dy); - -void ScaleRowDown2_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleRowDown2_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst, - int dst_width); -void ScaleRowDown2Linear_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleRowDown2Linear_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst, - int dst_width); -void ScaleRowDown2Box_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleRowDown2Box_Odd_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleRowDown2Box_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst, - int dst_width); -void ScaleRowDown4_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleRowDown4_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst, - int dst_width); -void ScaleRowDown4Box_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleRowDown4Box_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst, - int dst_width); -void ScaleRowDown34_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleRowDown34_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst, - int dst_width); -void ScaleRowDown34_0_Box_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* d, - int dst_width); -void ScaleRowDown34_0_Box_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* d, - int dst_width); -void ScaleRowDown34_1_Box_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* d, - int dst_width); -void ScaleRowDown34_1_Box_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* d, - int dst_width); -void ScaleCols_C(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx); -void ScaleCols_16_C(uint16_t* dst_ptr, - const uint16_t* src_ptr, - int dst_width, - int x, - int dx); -void ScaleColsUp2_C(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int, - int); -void ScaleColsUp2_16_C(uint16_t* dst_ptr, - const uint16_t* src_ptr, - int dst_width, - int, - int); -void ScaleFilterCols_C(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx); -void ScaleFilterCols_16_C(uint16_t* dst_ptr, - const uint16_t* src_ptr, - int dst_width, - int x, - int dx); -void ScaleFilterCols64_C(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x32, - int dx); -void ScaleFilterCols64_16_C(uint16_t* dst_ptr, - const uint16_t* src_ptr, - int dst_width, - int x32, - int dx); -void ScaleRowDown38_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleRowDown38_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst, - int dst_width); -void ScaleRowDown38_3_Box_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown38_3_Box_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst_ptr, - int dst_width); -void ScaleRowDown38_2_Box_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown38_2_Box_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst_ptr, - int dst_width); -void ScaleAddRow_C(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width); -void ScaleAddRow_16_C(const uint16_t* src_ptr, - uint32_t* dst_ptr, - int src_width); -void ScaleARGBRowDown2_C(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBRowDown2Linear_C(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBRowDown2Box_C(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBRowDownEven_C(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBRowDownEvenBox_C(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBCols_C(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx); -void ScaleARGBCols64_C(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x32, - int dx); -void ScaleARGBColsUp2_C(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int, - int); -void ScaleARGBFilterCols_C(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx); -void ScaleARGBFilterCols64_C(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x32, - int dx); - -// Specialized scalers for x86. -void ScaleRowDown2_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2Linear_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2Linear_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2Box_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown4_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown4Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown4_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown4Box_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); - -void ScaleRowDown34_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown34_1_Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown34_0_Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown38_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown38_3_Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown38_2_Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2_Any_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2Linear_Any_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2Box_Any_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2Box_Odd_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2_Any_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2Linear_Any_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2Box_Any_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2Box_Odd_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown4_Any_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown4Box_Any_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown4_Any_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown4Box_Any_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); - -void ScaleRowDown34_Any_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown34_1_Box_Any_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown34_0_Box_Any_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown38_Any_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown38_3_Box_Any_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown38_2_Box_Any_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); - -void ScaleAddRow_SSE2(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width); -void ScaleAddRow_AVX2(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width); -void ScaleAddRow_Any_SSE2(const uint8_t* src_ptr, - uint16_t* dst_ptr, - int src_width); -void ScaleAddRow_Any_AVX2(const uint8_t* src_ptr, - uint16_t* dst_ptr, - int src_width); - -void ScaleFilterCols_SSSE3(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx); -void ScaleColsUp2_SSE2(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx); - -// ARGB Column functions -void ScaleARGBCols_SSE2(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx); -void ScaleARGBFilterCols_SSSE3(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx); -void ScaleARGBColsUp2_SSE2(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx); -void ScaleARGBFilterCols_NEON(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx); -void ScaleARGBCols_NEON(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx); -void ScaleARGBFilterCols_Any_NEON(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx); -void ScaleARGBCols_Any_NEON(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx); -void ScaleARGBFilterCols_MSA(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx); -void ScaleARGBCols_MSA(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx); -void ScaleARGBFilterCols_Any_MSA(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx); -void ScaleARGBCols_Any_MSA(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx); - -// ARGB Row functions -void ScaleARGBRowDown2_SSE2(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBRowDown2Linear_SSE2(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBRowDown2Box_SSE2(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBRowDown2_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleARGBRowDown2Linear_NEON(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBRowDown2Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleARGBRowDown2_MSA(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBRowDown2Linear_MSA(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBRowDown2Box_MSA(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBRowDown2_Any_SSE2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleARGBRowDown2Linear_Any_SSE2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleARGBRowDown2Box_Any_SSE2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleARGBRowDown2_Any_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleARGBRowDown2Linear_Any_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleARGBRowDown2Box_Any_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleARGBRowDown2_Any_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleARGBRowDown2Linear_Any_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleARGBRowDown2Box_Any_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); - -void ScaleARGBRowDownEven_SSE2(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBRowDownEvenBox_SSE2(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBRowDownEven_NEON(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBRowDownEvenBox_NEON(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBRowDownEven_MSA(const uint8_t* src_argb, - ptrdiff_t src_stride, - int32_t src_stepx, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBRowDownEvenBox_MSA(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width); -void ScaleARGBRowDownEven_Any_SSE2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_ptr, - int dst_width); -void ScaleARGBRowDownEvenBox_Any_SSE2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_ptr, - int dst_width); -void ScaleARGBRowDownEven_Any_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_ptr, - int dst_width); -void ScaleARGBRowDownEvenBox_Any_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_ptr, - int dst_width); -void ScaleARGBRowDownEven_Any_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - int32_t src_stepx, - uint8_t* dst_ptr, - int dst_width); -void ScaleARGBRowDownEvenBox_Any_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_ptr, - int dst_width); - -// ScaleRowDown2Box also used by planar functions -// NEON downscalers with interpolation. - -// Note - not static due to reuse in convert for 444 to 420. -void ScaleRowDown2_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleRowDown2Linear_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleRowDown2Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); - -void ScaleRowDown4_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown4Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); - -// Down scale from 4 to 3 pixels. Use the neon multilane read/write -// to load up the every 4th pixel into a 4 different registers. -// Point samples 32 pixels to 24 pixels. -void ScaleRowDown34_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown34_0_Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown34_1_Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); - -// 32 -> 12 -void ScaleRowDown38_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -// 32x3 -> 12x1 -void ScaleRowDown38_3_Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -// 32x2 -> 12x1 -void ScaleRowDown38_2_Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); - -void ScaleRowDown2_Any_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2Linear_Any_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2Box_Any_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2Box_Odd_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown4_Any_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown4Box_Any_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown34_Any_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown34_0_Box_Any_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown34_1_Box_Any_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -// 32 -> 12 -void ScaleRowDown38_Any_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -// 32x3 -> 12x1 -void ScaleRowDown38_3_Box_Any_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -// 32x2 -> 12x1 -void ScaleRowDown38_2_Box_Any_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); - -void ScaleAddRow_NEON(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width); -void ScaleAddRow_Any_NEON(const uint8_t* src_ptr, - uint16_t* dst_ptr, - int src_width); - -void ScaleFilterCols_NEON(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx); - -void ScaleFilterCols_Any_NEON(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx); - -void ScaleRowDown2_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleRowDown2Linear_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleRowDown2Box_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleRowDown4_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleRowDown4Box_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleRowDown38_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleRowDown38_2_Box_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown38_3_Box_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleAddRow_MSA(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width); -void ScaleFilterCols_MSA(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx); -void ScaleRowDown34_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width); -void ScaleRowDown34_0_Box_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* d, - int dst_width); -void ScaleRowDown34_1_Box_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* d, - int dst_width); - -void ScaleRowDown2_Any_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2Linear_Any_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown2Box_Any_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown4_Any_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown4Box_Any_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown38_Any_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown38_2_Box_Any_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown38_3_Box_Any_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleAddRow_Any_MSA(const uint8_t* src_ptr, - uint16_t* dst_ptr, - int src_width); -void ScaleFilterCols_Any_MSA(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx); -void ScaleRowDown34_Any_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown34_0_Box_Any_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); -void ScaleRowDown34_1_Box_Any_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width); - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // INCLUDE_LIBYUV_SCALE_ROW_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/version.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/version.h deleted file mode 100644 index 7022785d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/version.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2012 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef INCLUDE_LIBYUV_VERSION_H_ -#define INCLUDE_LIBYUV_VERSION_H_ - -#define LIBYUV_VERSION 1711 - -#endif // INCLUDE_LIBYUV_VERSION_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/video_common.h b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/video_common.h deleted file mode 100644 index bcef378b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/include/libyuv/video_common.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Common definitions for video, including fourcc and VideoFormat. - -#ifndef INCLUDE_LIBYUV_VIDEO_COMMON_H_ -#define INCLUDE_LIBYUV_VIDEO_COMMON_H_ - -#include "libyuv/basic_types.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -////////////////////////////////////////////////////////////////////////////// -// Definition of FourCC codes -////////////////////////////////////////////////////////////////////////////// - -// Convert four characters to a FourCC code. -// Needs to be a macro otherwise the OS X compiler complains when the kFormat* -// constants are used in a switch. -#ifdef __cplusplus -#define FOURCC(a, b, c, d) \ - ((static_cast(a)) | (static_cast(b) << 8) | \ - (static_cast(c) << 16) | (static_cast(d) << 24)) -#else -#define FOURCC(a, b, c, d) \ - (((uint32_t)(a)) | ((uint32_t)(b) << 8) | /* NOLINT */ \ - ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) /* NOLINT */ -#endif - -// Some pages discussing FourCC codes: -// http://www.fourcc.org/yuv.php -// http://v4l2spec.bytesex.org/spec/book1.htm -// http://developer.apple.com/quicktime/icefloe/dispatch020.html -// http://msdn.microsoft.com/library/windows/desktop/dd206750.aspx#nv12 -// http://people.xiph.org/~xiphmont/containers/nut/nut4cc.txt - -// FourCC codes grouped according to implementation efficiency. -// Primary formats should convert in 1 efficient step. -// Secondary formats are converted in 2 steps. -// Auxilliary formats call primary converters. -enum FourCC { - // 9 Primary YUV formats: 5 planar, 2 biplanar, 2 packed. - FOURCC_I420 = FOURCC('I', '4', '2', '0'), - FOURCC_I422 = FOURCC('I', '4', '2', '2'), - FOURCC_I444 = FOURCC('I', '4', '4', '4'), - FOURCC_I400 = FOURCC('I', '4', '0', '0'), - FOURCC_NV21 = FOURCC('N', 'V', '2', '1'), - FOURCC_NV12 = FOURCC('N', 'V', '1', '2'), - FOURCC_YUY2 = FOURCC('Y', 'U', 'Y', '2'), - FOURCC_UYVY = FOURCC('U', 'Y', 'V', 'Y'), - FOURCC_H010 = FOURCC('H', '0', '1', '0'), // unofficial fourcc. 10 bit lsb - - // 1 Secondary YUV format: row biplanar. - FOURCC_M420 = FOURCC('M', '4', '2', '0'), - - // 11 Primary RGB formats: 4 32 bpp, 2 24 bpp, 3 16 bpp, 1 10 bpc - FOURCC_ARGB = FOURCC('A', 'R', 'G', 'B'), - FOURCC_BGRA = FOURCC('B', 'G', 'R', 'A'), - FOURCC_ABGR = FOURCC('A', 'B', 'G', 'R'), - FOURCC_AR30 = FOURCC('A', 'R', '3', '0'), // 10 bit per channel. 2101010. - FOURCC_AB30 = FOURCC('A', 'B', '3', '0'), // ABGR version of 10 bit - FOURCC_24BG = FOURCC('2', '4', 'B', 'G'), - FOURCC_RAW = FOURCC('r', 'a', 'w', ' '), - FOURCC_RGBA = FOURCC('R', 'G', 'B', 'A'), - FOURCC_RGBP = FOURCC('R', 'G', 'B', 'P'), // rgb565 LE. - FOURCC_RGBO = FOURCC('R', 'G', 'B', 'O'), // argb1555 LE. - FOURCC_R444 = FOURCC('R', '4', '4', '4'), // argb4444 LE. - - // 1 Primary Compressed YUV format. - FOURCC_MJPG = FOURCC('M', 'J', 'P', 'G'), - - // 7 Auxiliary YUV variations: 3 with U and V planes are swapped, 1 Alias. - FOURCC_YV12 = FOURCC('Y', 'V', '1', '2'), - FOURCC_YV16 = FOURCC('Y', 'V', '1', '6'), - FOURCC_YV24 = FOURCC('Y', 'V', '2', '4'), - FOURCC_YU12 = FOURCC('Y', 'U', '1', '2'), // Linux version of I420. - FOURCC_J420 = FOURCC('J', '4', '2', '0'), - FOURCC_J400 = FOURCC('J', '4', '0', '0'), // unofficial fourcc - FOURCC_H420 = FOURCC('H', '4', '2', '0'), // unofficial fourcc - - // 14 Auxiliary aliases. CanonicalFourCC() maps these to canonical fourcc. - FOURCC_IYUV = FOURCC('I', 'Y', 'U', 'V'), // Alias for I420. - FOURCC_YU16 = FOURCC('Y', 'U', '1', '6'), // Alias for I422. - FOURCC_YU24 = FOURCC('Y', 'U', '2', '4'), // Alias for I444. - FOURCC_YUYV = FOURCC('Y', 'U', 'Y', 'V'), // Alias for YUY2. - FOURCC_YUVS = FOURCC('y', 'u', 'v', 's'), // Alias for YUY2 on Mac. - FOURCC_HDYC = FOURCC('H', 'D', 'Y', 'C'), // Alias for UYVY. - FOURCC_2VUY = FOURCC('2', 'v', 'u', 'y'), // Alias for UYVY on Mac. - FOURCC_JPEG = FOURCC('J', 'P', 'E', 'G'), // Alias for MJPG. - FOURCC_DMB1 = FOURCC('d', 'm', 'b', '1'), // Alias for MJPG on Mac. - FOURCC_BA81 = FOURCC('B', 'A', '8', '1'), // Alias for BGGR. - FOURCC_RGB3 = FOURCC('R', 'G', 'B', '3'), // Alias for RAW. - FOURCC_BGR3 = FOURCC('B', 'G', 'R', '3'), // Alias for 24BG. - FOURCC_CM32 = FOURCC(0, 0, 0, 32), // Alias for BGRA kCMPixelFormat_32ARGB - FOURCC_CM24 = FOURCC(0, 0, 0, 24), // Alias for RAW kCMPixelFormat_24RGB - FOURCC_L555 = FOURCC('L', '5', '5', '5'), // Alias for RGBO. - FOURCC_L565 = FOURCC('L', '5', '6', '5'), // Alias for RGBP. - FOURCC_5551 = FOURCC('5', '5', '5', '1'), // Alias for RGBO. - - // deprecated formats. Not supported, but defined for backward compatibility. - FOURCC_I411 = FOURCC('I', '4', '1', '1'), - FOURCC_Q420 = FOURCC('Q', '4', '2', '0'), - FOURCC_RGGB = FOURCC('R', 'G', 'G', 'B'), - FOURCC_BGGR = FOURCC('B', 'G', 'G', 'R'), - FOURCC_GRBG = FOURCC('G', 'R', 'B', 'G'), - FOURCC_GBRG = FOURCC('G', 'B', 'R', 'G'), - FOURCC_H264 = FOURCC('H', '2', '6', '4'), - - // Match any fourcc. - FOURCC_ANY = -1, -}; - -enum FourCCBpp { - // Canonical fourcc codes used in our code. - FOURCC_BPP_I420 = 12, - FOURCC_BPP_I422 = 16, - FOURCC_BPP_I444 = 24, - FOURCC_BPP_I411 = 12, - FOURCC_BPP_I400 = 8, - FOURCC_BPP_NV21 = 12, - FOURCC_BPP_NV12 = 12, - FOURCC_BPP_YUY2 = 16, - FOURCC_BPP_UYVY = 16, - FOURCC_BPP_M420 = 12, - FOURCC_BPP_Q420 = 12, - FOURCC_BPP_ARGB = 32, - FOURCC_BPP_BGRA = 32, - FOURCC_BPP_ABGR = 32, - FOURCC_BPP_RGBA = 32, - FOURCC_BPP_AR30 = 32, - FOURCC_BPP_AB30 = 32, - FOURCC_BPP_24BG = 24, - FOURCC_BPP_RAW = 24, - FOURCC_BPP_RGBP = 16, - FOURCC_BPP_RGBO = 16, - FOURCC_BPP_R444 = 16, - FOURCC_BPP_RGGB = 8, - FOURCC_BPP_BGGR = 8, - FOURCC_BPP_GRBG = 8, - FOURCC_BPP_GBRG = 8, - FOURCC_BPP_YV12 = 12, - FOURCC_BPP_YV16 = 16, - FOURCC_BPP_YV24 = 24, - FOURCC_BPP_YU12 = 12, - FOURCC_BPP_J420 = 12, - FOURCC_BPP_J400 = 8, - FOURCC_BPP_H420 = 12, - FOURCC_BPP_H010 = 24, - FOURCC_BPP_MJPG = 0, // 0 means unknown. - FOURCC_BPP_H264 = 0, - FOURCC_BPP_IYUV = 12, - FOURCC_BPP_YU16 = 16, - FOURCC_BPP_YU24 = 24, - FOURCC_BPP_YUYV = 16, - FOURCC_BPP_YUVS = 16, - FOURCC_BPP_HDYC = 16, - FOURCC_BPP_2VUY = 16, - FOURCC_BPP_JPEG = 1, - FOURCC_BPP_DMB1 = 1, - FOURCC_BPP_BA81 = 8, - FOURCC_BPP_RGB3 = 24, - FOURCC_BPP_BGR3 = 24, - FOURCC_BPP_CM32 = 32, - FOURCC_BPP_CM24 = 24, - - // Match any fourcc. - FOURCC_BPP_ANY = 0, // 0 means unknown. -}; - -// Converts fourcc aliases into canonical ones. -LIBYUV_API uint32_t CanonicalFourCC(uint32_t fourcc); - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // INCLUDE_LIBYUV_VIDEO_COMMON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare.cc deleted file mode 100644 index 50e3abd0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare.cc +++ /dev/null @@ -1,429 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/compare.h" - -#include -#include -#ifdef _OPENMP -#include -#endif - -#include "libyuv/basic_types.h" -#include "libyuv/compare_row.h" -#include "libyuv/cpu_id.h" -#include "libyuv/row.h" -#include "libyuv/video_common.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// hash seed of 5381 recommended. -LIBYUV_API -uint32_t HashDjb2(const uint8_t* src, uint64_t count, uint32_t seed) { - const int kBlockSize = 1 << 15; // 32768; - int remainder; - uint32_t (*HashDjb2_SSE)(const uint8_t* src, int count, uint32_t seed) = - HashDjb2_C; -#if defined(HAS_HASHDJB2_SSE41) - if (TestCpuFlag(kCpuHasSSE41)) { - HashDjb2_SSE = HashDjb2_SSE41; - } -#endif -#if defined(HAS_HASHDJB2_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - HashDjb2_SSE = HashDjb2_AVX2; - } -#endif - - while (count >= (uint64_t)(kBlockSize)) { - seed = HashDjb2_SSE(src, kBlockSize, seed); - src += kBlockSize; - count -= kBlockSize; - } - remainder = (int)count & ~15; - if (remainder) { - seed = HashDjb2_SSE(src, remainder, seed); - src += remainder; - count -= remainder; - } - remainder = (int)count & 15; - if (remainder) { - seed = HashDjb2_C(src, remainder, seed); - } - return seed; -} - -static uint32_t ARGBDetectRow_C(const uint8_t* argb, int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - if (argb[0] != 255) { // First byte is not Alpha of 255, so not ARGB. - return FOURCC_BGRA; - } - if (argb[3] != 255) { // 4th byte is not Alpha of 255, so not BGRA. - return FOURCC_ARGB; - } - if (argb[4] != 255) { // Second pixel first byte is not Alpha of 255. - return FOURCC_BGRA; - } - if (argb[7] != 255) { // Second pixel 4th byte is not Alpha of 255. - return FOURCC_ARGB; - } - argb += 8; - } - if (width & 1) { - if (argb[0] != 255) { // First byte is not Alpha of 255, so not ARGB. - return FOURCC_BGRA; - } - if (argb[3] != 255) { // 4th byte is not Alpha of 255, so not BGRA. - return FOURCC_ARGB; - } - } - return 0; -} - -// Scan an opaque argb image and return fourcc based on alpha offset. -// Returns FOURCC_ARGB, FOURCC_BGRA, or 0 if unknown. -LIBYUV_API -uint32_t ARGBDetect(const uint8_t* argb, - int stride_argb, - int width, - int height) { - uint32_t fourcc = 0; - int h; - - // Coalesce rows. - if (stride_argb == width * 4) { - width *= height; - height = 1; - stride_argb = 0; - } - for (h = 0; h < height && fourcc == 0; ++h) { - fourcc = ARGBDetectRow_C(argb, width); - argb += stride_argb; - } - return fourcc; -} - -// NEON version accumulates in 16 bit shorts which overflow at 65536 bytes. -// So actual maximum is 1 less loop, which is 64436 - 32 bytes. - -LIBYUV_API -uint64_t ComputeHammingDistance(const uint8_t* src_a, - const uint8_t* src_b, - int count) { - const int kBlockSize = 1 << 15; // 32768; - const int kSimdSize = 64; - // SIMD for multiple of 64, and C for remainder - int remainder = count & (kBlockSize - 1) & ~(kSimdSize - 1); - uint64_t diff = 0; - int i; - uint32_t (*HammingDistance)(const uint8_t* src_a, const uint8_t* src_b, - int count) = HammingDistance_C; -#if defined(HAS_HAMMINGDISTANCE_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - HammingDistance = HammingDistance_NEON; - } -#endif -#if defined(HAS_HAMMINGDISTANCE_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - HammingDistance = HammingDistance_SSSE3; - } -#endif -#if defined(HAS_HAMMINGDISTANCE_SSE42) - if (TestCpuFlag(kCpuHasSSE42)) { - HammingDistance = HammingDistance_SSE42; - } -#endif -#if defined(HAS_HAMMINGDISTANCE_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - HammingDistance = HammingDistance_AVX2; - } -#endif -#if defined(HAS_HAMMINGDISTANCE_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - HammingDistance = HammingDistance_MSA; - } -#endif -#ifdef _OPENMP -#pragma omp parallel for reduction(+ : diff) -#endif - for (i = 0; i < (count - (kBlockSize - 1)); i += kBlockSize) { - diff += HammingDistance(src_a + i, src_b + i, kBlockSize); - } - src_a += count & ~(kBlockSize - 1); - src_b += count & ~(kBlockSize - 1); - if (remainder) { - diff += HammingDistance(src_a, src_b, remainder); - src_a += remainder; - src_b += remainder; - } - remainder = count & (kSimdSize - 1); - if (remainder) { - diff += HammingDistance_C(src_a, src_b, remainder); - } - return diff; -} - -// TODO(fbarchard): Refactor into row function. -LIBYUV_API -uint64_t ComputeSumSquareError(const uint8_t* src_a, - const uint8_t* src_b, - int count) { - // SumSquareError returns values 0 to 65535 for each squared difference. - // Up to 65536 of those can be summed and remain within a uint32_t. - // After each block of 65536 pixels, accumulate into a uint64_t. - const int kBlockSize = 65536; - int remainder = count & (kBlockSize - 1) & ~31; - uint64_t sse = 0; - int i; - uint32_t (*SumSquareError)(const uint8_t* src_a, const uint8_t* src_b, - int count) = SumSquareError_C; -#if defined(HAS_SUMSQUAREERROR_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - SumSquareError = SumSquareError_NEON; - } -#endif -#if defined(HAS_SUMSQUAREERROR_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - // Note only used for multiples of 16 so count is not checked. - SumSquareError = SumSquareError_SSE2; - } -#endif -#if defined(HAS_SUMSQUAREERROR_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - // Note only used for multiples of 32 so count is not checked. - SumSquareError = SumSquareError_AVX2; - } -#endif -#if defined(HAS_SUMSQUAREERROR_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SumSquareError = SumSquareError_MSA; - } -#endif -#ifdef _OPENMP -#pragma omp parallel for reduction(+ : sse) -#endif - for (i = 0; i < (count - (kBlockSize - 1)); i += kBlockSize) { - sse += SumSquareError(src_a + i, src_b + i, kBlockSize); - } - src_a += count & ~(kBlockSize - 1); - src_b += count & ~(kBlockSize - 1); - if (remainder) { - sse += SumSquareError(src_a, src_b, remainder); - src_a += remainder; - src_b += remainder; - } - remainder = count & 31; - if (remainder) { - sse += SumSquareError_C(src_a, src_b, remainder); - } - return sse; -} - -LIBYUV_API -uint64_t ComputeSumSquareErrorPlane(const uint8_t* src_a, - int stride_a, - const uint8_t* src_b, - int stride_b, - int width, - int height) { - uint64_t sse = 0; - int h; - // Coalesce rows. - if (stride_a == width && stride_b == width) { - width *= height; - height = 1; - stride_a = stride_b = 0; - } - for (h = 0; h < height; ++h) { - sse += ComputeSumSquareError(src_a, src_b, width); - src_a += stride_a; - src_b += stride_b; - } - return sse; -} - -LIBYUV_API -double SumSquareErrorToPsnr(uint64_t sse, uint64_t count) { - double psnr; - if (sse > 0) { - double mse = (double)count / (double)sse; - psnr = 10.0 * log10(255.0 * 255.0 * mse); - } else { - psnr = kMaxPsnr; // Limit to prevent divide by 0 - } - - if (psnr > kMaxPsnr) { - psnr = kMaxPsnr; - } - - return psnr; -} - -LIBYUV_API -double CalcFramePsnr(const uint8_t* src_a, - int stride_a, - const uint8_t* src_b, - int stride_b, - int width, - int height) { - const uint64_t samples = (uint64_t)width * (uint64_t)height; - const uint64_t sse = ComputeSumSquareErrorPlane(src_a, stride_a, src_b, - stride_b, width, height); - return SumSquareErrorToPsnr(sse, samples); -} - -LIBYUV_API -double I420Psnr(const uint8_t* src_y_a, - int stride_y_a, - const uint8_t* src_u_a, - int stride_u_a, - const uint8_t* src_v_a, - int stride_v_a, - const uint8_t* src_y_b, - int stride_y_b, - const uint8_t* src_u_b, - int stride_u_b, - const uint8_t* src_v_b, - int stride_v_b, - int width, - int height) { - const uint64_t sse_y = ComputeSumSquareErrorPlane( - src_y_a, stride_y_a, src_y_b, stride_y_b, width, height); - const int width_uv = (width + 1) >> 1; - const int height_uv = (height + 1) >> 1; - const uint64_t sse_u = ComputeSumSquareErrorPlane( - src_u_a, stride_u_a, src_u_b, stride_u_b, width_uv, height_uv); - const uint64_t sse_v = ComputeSumSquareErrorPlane( - src_v_a, stride_v_a, src_v_b, stride_v_b, width_uv, height_uv); - const uint64_t samples = (uint64_t)width * (uint64_t)height + - 2 * ((uint64_t)width_uv * (uint64_t)height_uv); - const uint64_t sse = sse_y + sse_u + sse_v; - return SumSquareErrorToPsnr(sse, samples); -} - -static const int64_t cc1 = 26634; // (64^2*(.01*255)^2 -static const int64_t cc2 = 239708; // (64^2*(.03*255)^2 - -static double Ssim8x8_C(const uint8_t* src_a, - int stride_a, - const uint8_t* src_b, - int stride_b) { - int64_t sum_a = 0; - int64_t sum_b = 0; - int64_t sum_sq_a = 0; - int64_t sum_sq_b = 0; - int64_t sum_axb = 0; - - int i; - for (i = 0; i < 8; ++i) { - int j; - for (j = 0; j < 8; ++j) { - sum_a += src_a[j]; - sum_b += src_b[j]; - sum_sq_a += src_a[j] * src_a[j]; - sum_sq_b += src_b[j] * src_b[j]; - sum_axb += src_a[j] * src_b[j]; - } - - src_a += stride_a; - src_b += stride_b; - } - - { - const int64_t count = 64; - // scale the constants by number of pixels - const int64_t c1 = (cc1 * count * count) >> 12; - const int64_t c2 = (cc2 * count * count) >> 12; - - const int64_t sum_a_x_sum_b = sum_a * sum_b; - - const int64_t ssim_n = (2 * sum_a_x_sum_b + c1) * - (2 * count * sum_axb - 2 * sum_a_x_sum_b + c2); - - const int64_t sum_a_sq = sum_a * sum_a; - const int64_t sum_b_sq = sum_b * sum_b; - - const int64_t ssim_d = - (sum_a_sq + sum_b_sq + c1) * - (count * sum_sq_a - sum_a_sq + count * sum_sq_b - sum_b_sq + c2); - - if (ssim_d == 0.0) { - return DBL_MAX; - } - return ssim_n * 1.0 / ssim_d; - } -} - -// We are using a 8x8 moving window with starting location of each 8x8 window -// on the 4x4 pixel grid. Such arrangement allows the windows to overlap -// block boundaries to penalize blocking artifacts. -LIBYUV_API -double CalcFrameSsim(const uint8_t* src_a, - int stride_a, - const uint8_t* src_b, - int stride_b, - int width, - int height) { - int samples = 0; - double ssim_total = 0; - double (*Ssim8x8)(const uint8_t* src_a, int stride_a, const uint8_t* src_b, - int stride_b) = Ssim8x8_C; - - // sample point start with each 4x4 location - int i; - for (i = 0; i < height - 8; i += 4) { - int j; - for (j = 0; j < width - 8; j += 4) { - ssim_total += Ssim8x8(src_a + j, stride_a, src_b + j, stride_b); - samples++; - } - - src_a += stride_a * 4; - src_b += stride_b * 4; - } - - ssim_total /= samples; - return ssim_total; -} - -LIBYUV_API -double I420Ssim(const uint8_t* src_y_a, - int stride_y_a, - const uint8_t* src_u_a, - int stride_u_a, - const uint8_t* src_v_a, - int stride_v_a, - const uint8_t* src_y_b, - int stride_y_b, - const uint8_t* src_u_b, - int stride_u_b, - const uint8_t* src_v_b, - int stride_v_b, - int width, - int height) { - const double ssim_y = - CalcFrameSsim(src_y_a, stride_y_a, src_y_b, stride_y_b, width, height); - const int width_uv = (width + 1) >> 1; - const int height_uv = (height + 1) >> 1; - const double ssim_u = CalcFrameSsim(src_u_a, stride_u_a, src_u_b, stride_u_b, - width_uv, height_uv); - const double ssim_v = CalcFrameSsim(src_v_a, stride_v_a, src_v_b, stride_v_b, - width_uv, height_uv); - return ssim_y * 0.8 + 0.1 * (ssim_u + ssim_v); -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_common.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_common.cc deleted file mode 100644 index d4b170ad..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_common.cc +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2012 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/basic_types.h" - -#include "libyuv/compare_row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -#if ORIGINAL_OPT -uint32_t HammingDistance_C1(const uint8_t* src_a, - const uint8_t* src_b, - int count) { - uint32_t diff = 0u; - - int i; - for (i = 0; i < count; ++i) { - int x = src_a[i] ^ src_b[i]; - if (x & 1) - ++diff; - if (x & 2) - ++diff; - if (x & 4) - ++diff; - if (x & 8) - ++diff; - if (x & 16) - ++diff; - if (x & 32) - ++diff; - if (x & 64) - ++diff; - if (x & 128) - ++diff; - } - return diff; -} -#endif - -// Hakmem method for hamming distance. -uint32_t HammingDistance_C(const uint8_t* src_a, - const uint8_t* src_b, - int count) { - uint32_t diff = 0u; - - int i; - for (i = 0; i < count - 3; i += 4) { - uint32_t x = *((const uint32_t*)src_a) ^ *((const uint32_t*)src_b); - uint32_t u = x - ((x >> 1) & 0x55555555); - u = ((u >> 2) & 0x33333333) + (u & 0x33333333); - diff += ((((u + (u >> 4)) & 0x0f0f0f0f) * 0x01010101) >> 24); - src_a += 4; - src_b += 4; - } - - for (; i < count; ++i) { - uint32_t x = *src_a ^ *src_b; - uint32_t u = x - ((x >> 1) & 0x55); - u = ((u >> 2) & 0x33) + (u & 0x33); - diff += (u + (u >> 4)) & 0x0f; - src_a += 1; - src_b += 1; - } - - return diff; -} - -uint32_t SumSquareError_C(const uint8_t* src_a, - const uint8_t* src_b, - int count) { - uint32_t sse = 0u; - int i; - for (i = 0; i < count; ++i) { - int diff = src_a[i] - src_b[i]; - sse += (uint32_t)(diff * diff); - } - return sse; -} - -// hash seed of 5381 recommended. -// Internal C version of HashDjb2 with int sized count for efficiency. -uint32_t HashDjb2_C(const uint8_t* src, int count, uint32_t seed) { - uint32_t hash = seed; - int i; - for (i = 0; i < count; ++i) { - hash += (hash << 5) + src[i]; - } - return hash; -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_gcc.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_gcc.cc deleted file mode 100644 index 676527c1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_gcc.cc +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Copyright 2012 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/basic_types.h" - -#include "libyuv/compare_row.h" -#include "libyuv/row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// This module is for GCC x86 and x64. -#if !defined(LIBYUV_DISABLE_X86) && \ - (defined(__x86_64__) || (defined(__i386__) && !defined(_MSC_VER))) - -#if defined(__x86_64__) -uint32_t HammingDistance_SSE42(const uint8_t* src_a, - const uint8_t* src_b, - int count) { - uint64_t diff = 0u; - - asm volatile( - "xor %3,%3 \n" - "xor %%r8,%%r8 \n" - "xor %%r9,%%r9 \n" - "xor %%r10,%%r10 \n" - - // Process 32 bytes per loop. - LABELALIGN - "1: \n" - "mov (%0),%%rcx \n" - "mov 0x8(%0),%%rdx \n" - "xor (%1),%%rcx \n" - "xor 0x8(%1),%%rdx \n" - "popcnt %%rcx,%%rcx \n" - "popcnt %%rdx,%%rdx \n" - "mov 0x10(%0),%%rsi \n" - "mov 0x18(%0),%%rdi \n" - "xor 0x10(%1),%%rsi \n" - "xor 0x18(%1),%%rdi \n" - "popcnt %%rsi,%%rsi \n" - "popcnt %%rdi,%%rdi \n" - "add $0x20,%0 \n" - "add $0x20,%1 \n" - "add %%rcx,%3 \n" - "add %%rdx,%%r8 \n" - "add %%rsi,%%r9 \n" - "add %%rdi,%%r10 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - - "add %%r8, %3 \n" - "add %%r9, %3 \n" - "add %%r10, %3 \n" - : "+r"(src_a), // %0 - "+r"(src_b), // %1 - "+r"(count), // %2 - "=r"(diff) // %3 - : - : "memory", "cc", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10"); - - return static_cast(diff); -} -#else -uint32_t HammingDistance_SSE42(const uint8_t* src_a, - const uint8_t* src_b, - int count) { - uint32_t diff = 0u; - - asm volatile( - // Process 16 bytes per loop. - LABELALIGN - "1: \n" - "mov (%0),%%ecx \n" - "mov 0x4(%0),%%edx \n" - "xor (%1),%%ecx \n" - "xor 0x4(%1),%%edx \n" - "popcnt %%ecx,%%ecx \n" - "add %%ecx,%3 \n" - "popcnt %%edx,%%edx \n" - "add %%edx,%3 \n" - "mov 0x8(%0),%%ecx \n" - "mov 0xc(%0),%%edx \n" - "xor 0x8(%1),%%ecx \n" - "xor 0xc(%1),%%edx \n" - "popcnt %%ecx,%%ecx \n" - "add %%ecx,%3 \n" - "popcnt %%edx,%%edx \n" - "add %%edx,%3 \n" - "add $0x10,%0 \n" - "add $0x10,%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src_a), // %0 - "+r"(src_b), // %1 - "+r"(count), // %2 - "+r"(diff) // %3 - : - : "memory", "cc", "ecx", "edx"); - - return diff; -} -#endif - -static const vec8 kNibbleMask = {15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15}; -static const vec8 kBitCount = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; - -uint32_t HammingDistance_SSSE3(const uint8_t* src_a, - const uint8_t* src_b, - int count) { - uint32_t diff = 0u; - - asm volatile( - "movdqa %4,%%xmm2 \n" - "movdqa %5,%%xmm3 \n" - "pxor %%xmm0,%%xmm0 \n" - "pxor %%xmm1,%%xmm1 \n" - "sub %0,%1 \n" - - LABELALIGN - "1: \n" - "movdqa (%0),%%xmm4 \n" - "movdqa 0x10(%0), %%xmm5 \n" - "pxor (%0,%1), %%xmm4 \n" - "movdqa %%xmm4,%%xmm6 \n" - "pand %%xmm2,%%xmm6 \n" - "psrlw $0x4,%%xmm4 \n" - "movdqa %%xmm3,%%xmm7 \n" - "pshufb %%xmm6,%%xmm7 \n" - "pand %%xmm2,%%xmm4 \n" - "movdqa %%xmm3,%%xmm6 \n" - "pshufb %%xmm4,%%xmm6 \n" - "paddb %%xmm7,%%xmm6 \n" - "pxor 0x10(%0,%1),%%xmm5 \n" - "add $0x20,%0 \n" - "movdqa %%xmm5,%%xmm4 \n" - "pand %%xmm2,%%xmm5 \n" - "psrlw $0x4,%%xmm4 \n" - "movdqa %%xmm3,%%xmm7 \n" - "pshufb %%xmm5,%%xmm7 \n" - "pand %%xmm2,%%xmm4 \n" - "movdqa %%xmm3,%%xmm5 \n" - "pshufb %%xmm4,%%xmm5 \n" - "paddb %%xmm7,%%xmm5 \n" - "paddb %%xmm5,%%xmm6 \n" - "psadbw %%xmm1,%%xmm6 \n" - "paddd %%xmm6,%%xmm0 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - - "pshufd $0xaa,%%xmm0,%%xmm1 \n" - "paddd %%xmm1,%%xmm0 \n" - "movd %%xmm0, %3 \n" - : "+r"(src_a), // %0 - "+r"(src_b), // %1 - "+r"(count), // %2 - "=r"(diff) // %3 - : "m"(kNibbleMask), // %4 - "m"(kBitCount) // %5 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); - - return diff; -} - -#ifdef HAS_HAMMINGDISTANCE_AVX2 -uint32_t HammingDistance_AVX2(const uint8_t* src_a, - const uint8_t* src_b, - int count) { - uint32_t diff = 0u; - - asm volatile( - "vbroadcastf128 %4,%%ymm2 \n" - "vbroadcastf128 %5,%%ymm3 \n" - "vpxor %%ymm0,%%ymm0,%%ymm0 \n" - "vpxor %%ymm1,%%ymm1,%%ymm1 \n" - "sub %0,%1 \n" - - LABELALIGN - "1: \n" - "vmovdqa (%0),%%ymm4 \n" - "vmovdqa 0x20(%0), %%ymm5 \n" - "vpxor (%0,%1), %%ymm4, %%ymm4 \n" - "vpand %%ymm2,%%ymm4,%%ymm6 \n" - "vpsrlw $0x4,%%ymm4,%%ymm4 \n" - "vpshufb %%ymm6,%%ymm3,%%ymm6 \n" - "vpand %%ymm2,%%ymm4,%%ymm4 \n" - "vpshufb %%ymm4,%%ymm3,%%ymm4 \n" - "vpaddb %%ymm4,%%ymm6,%%ymm6 \n" - "vpxor 0x20(%0,%1),%%ymm5,%%ymm4 \n" - "add $0x40,%0 \n" - "vpand %%ymm2,%%ymm4,%%ymm5 \n" - "vpsrlw $0x4,%%ymm4,%%ymm4 \n" - "vpshufb %%ymm5,%%ymm3,%%ymm5 \n" - "vpand %%ymm2,%%ymm4,%%ymm4 \n" - "vpshufb %%ymm4,%%ymm3,%%ymm4 \n" - "vpaddb %%ymm5,%%ymm4,%%ymm4 \n" - "vpaddb %%ymm6,%%ymm4,%%ymm4 \n" - "vpsadbw %%ymm1,%%ymm4,%%ymm4 \n" - "vpaddd %%ymm0,%%ymm4,%%ymm0 \n" - "sub $0x40,%2 \n" - "jg 1b \n" - - "vpermq $0xb1,%%ymm0,%%ymm1 \n" - "vpaddd %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xaa,%%ymm0,%%ymm1 \n" - "vpaddd %%ymm1,%%ymm0,%%ymm0 \n" - "vmovd %%xmm0, %3 \n" - "vzeroupper \n" - : "+r"(src_a), // %0 - "+r"(src_b), // %1 - "+r"(count), // %2 - "=r"(diff) // %3 - : "m"(kNibbleMask), // %4 - "m"(kBitCount) // %5 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); - - return diff; -} -#endif // HAS_HAMMINGDISTANCE_AVX2 - -uint32_t SumSquareError_SSE2(const uint8_t* src_a, - const uint8_t* src_b, - int count) { - uint32_t sse; - asm volatile( - "pxor %%xmm0,%%xmm0 \n" - "pxor %%xmm5,%%xmm5 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm1 \n" - "lea 0x10(%0),%0 \n" - "movdqu (%1),%%xmm2 \n" - "lea 0x10(%1),%1 \n" - "movdqa %%xmm1,%%xmm3 \n" - "psubusb %%xmm2,%%xmm1 \n" - "psubusb %%xmm3,%%xmm2 \n" - "por %%xmm2,%%xmm1 \n" - "movdqa %%xmm1,%%xmm2 \n" - "punpcklbw %%xmm5,%%xmm1 \n" - "punpckhbw %%xmm5,%%xmm2 \n" - "pmaddwd %%xmm1,%%xmm1 \n" - "pmaddwd %%xmm2,%%xmm2 \n" - "paddd %%xmm1,%%xmm0 \n" - "paddd %%xmm2,%%xmm0 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - - "pshufd $0xee,%%xmm0,%%xmm1 \n" - "paddd %%xmm1,%%xmm0 \n" - "pshufd $0x1,%%xmm0,%%xmm1 \n" - "paddd %%xmm1,%%xmm0 \n" - "movd %%xmm0,%3 \n" - - : "+r"(src_a), // %0 - "+r"(src_b), // %1 - "+r"(count), // %2 - "=g"(sse) // %3 - ::"memory", - "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); - return sse; -} - -static const uvec32 kHash16x33 = {0x92d9e201, 0, 0, 0}; // 33 ^ 16 -static const uvec32 kHashMul0 = { - 0x0c3525e1, // 33 ^ 15 - 0xa3476dc1, // 33 ^ 14 - 0x3b4039a1, // 33 ^ 13 - 0x4f5f0981, // 33 ^ 12 -}; -static const uvec32 kHashMul1 = { - 0x30f35d61, // 33 ^ 11 - 0x855cb541, // 33 ^ 10 - 0x040a9121, // 33 ^ 9 - 0x747c7101, // 33 ^ 8 -}; -static const uvec32 kHashMul2 = { - 0xec41d4e1, // 33 ^ 7 - 0x4cfa3cc1, // 33 ^ 6 - 0x025528a1, // 33 ^ 5 - 0x00121881, // 33 ^ 4 -}; -static const uvec32 kHashMul3 = { - 0x00008c61, // 33 ^ 3 - 0x00000441, // 33 ^ 2 - 0x00000021, // 33 ^ 1 - 0x00000001, // 33 ^ 0 -}; - -uint32_t HashDjb2_SSE41(const uint8_t* src, int count, uint32_t seed) { - uint32_t hash; - asm volatile( - "movd %2,%%xmm0 \n" - "pxor %%xmm7,%%xmm7 \n" - "movdqa %4,%%xmm6 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm1 \n" - "lea 0x10(%0),%0 \n" - "pmulld %%xmm6,%%xmm0 \n" - "movdqa %5,%%xmm5 \n" - "movdqa %%xmm1,%%xmm2 \n" - "punpcklbw %%xmm7,%%xmm2 \n" - "movdqa %%xmm2,%%xmm3 \n" - "punpcklwd %%xmm7,%%xmm3 \n" - "pmulld %%xmm5,%%xmm3 \n" - "movdqa %6,%%xmm5 \n" - "movdqa %%xmm2,%%xmm4 \n" - "punpckhwd %%xmm7,%%xmm4 \n" - "pmulld %%xmm5,%%xmm4 \n" - "movdqa %7,%%xmm5 \n" - "punpckhbw %%xmm7,%%xmm1 \n" - "movdqa %%xmm1,%%xmm2 \n" - "punpcklwd %%xmm7,%%xmm2 \n" - "pmulld %%xmm5,%%xmm2 \n" - "movdqa %8,%%xmm5 \n" - "punpckhwd %%xmm7,%%xmm1 \n" - "pmulld %%xmm5,%%xmm1 \n" - "paddd %%xmm4,%%xmm3 \n" - "paddd %%xmm2,%%xmm1 \n" - "paddd %%xmm3,%%xmm1 \n" - "pshufd $0xe,%%xmm1,%%xmm2 \n" - "paddd %%xmm2,%%xmm1 \n" - "pshufd $0x1,%%xmm1,%%xmm2 \n" - "paddd %%xmm2,%%xmm1 \n" - "paddd %%xmm1,%%xmm0 \n" - "sub $0x10,%1 \n" - "jg 1b \n" - "movd %%xmm0,%3 \n" - : "+r"(src), // %0 - "+r"(count), // %1 - "+rm"(seed), // %2 - "=g"(hash) // %3 - : "m"(kHash16x33), // %4 - "m"(kHashMul0), // %5 - "m"(kHashMul1), // %6 - "m"(kHashMul2), // %7 - "m"(kHashMul3) // %8 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); - return hash; -} -#endif // defined(__x86_64__) || (defined(__i386__) && !defined(__pic__))) - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_msa.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_msa.cc deleted file mode 100644 index 0b807d37..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_msa.cc +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2017 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/basic_types.h" - -#include "libyuv/compare_row.h" -#include "libyuv/row.h" - -// This module is for GCC MSA -#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) -#include "libyuv/macros_msa.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -uint32_t HammingDistance_MSA(const uint8_t* src_a, - const uint8_t* src_b, - int count) { - uint32_t diff = 0u; - int i; - v16u8 src0, src1, src2, src3; - v2i64 vec0 = {0}, vec1 = {0}; - - for (i = 0; i < count; i += 32) { - src0 = (v16u8)__msa_ld_b((v16i8*)src_a, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)src_a, 16); - src2 = (v16u8)__msa_ld_b((v16i8*)src_b, 0); - src3 = (v16u8)__msa_ld_b((v16i8*)src_b, 16); - src0 ^= src2; - src1 ^= src3; - vec0 += __msa_pcnt_d((v2i64)src0); - vec1 += __msa_pcnt_d((v2i64)src1); - src_a += 32; - src_b += 32; - } - - vec0 += vec1; - diff = (uint32_t)__msa_copy_u_w((v4i32)vec0, 0); - diff += (uint32_t)__msa_copy_u_w((v4i32)vec0, 2); - return diff; -} - -uint32_t SumSquareError_MSA(const uint8_t* src_a, - const uint8_t* src_b, - int count) { - uint32_t sse = 0u; - int i; - v16u8 src0, src1, src2, src3; - v8i16 vec0, vec1, vec2, vec3; - v4i32 reg0 = {0}, reg1 = {0}, reg2 = {0}, reg3 = {0}; - v2i64 tmp0; - - for (i = 0; i < count; i += 32) { - src0 = (v16u8)__msa_ld_b((v16i8*)src_a, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)src_a, 16); - src2 = (v16u8)__msa_ld_b((v16i8*)src_b, 0); - src3 = (v16u8)__msa_ld_b((v16i8*)src_b, 16); - vec0 = (v8i16)__msa_ilvr_b((v16i8)src2, (v16i8)src0); - vec1 = (v8i16)__msa_ilvl_b((v16i8)src2, (v16i8)src0); - vec2 = (v8i16)__msa_ilvr_b((v16i8)src3, (v16i8)src1); - vec3 = (v8i16)__msa_ilvl_b((v16i8)src3, (v16i8)src1); - vec0 = __msa_hsub_u_h((v16u8)vec0, (v16u8)vec0); - vec1 = __msa_hsub_u_h((v16u8)vec1, (v16u8)vec1); - vec2 = __msa_hsub_u_h((v16u8)vec2, (v16u8)vec2); - vec3 = __msa_hsub_u_h((v16u8)vec3, (v16u8)vec3); - reg0 = __msa_dpadd_s_w(reg0, vec0, vec0); - reg1 = __msa_dpadd_s_w(reg1, vec1, vec1); - reg2 = __msa_dpadd_s_w(reg2, vec2, vec2); - reg3 = __msa_dpadd_s_w(reg3, vec3, vec3); - src_a += 32; - src_b += 32; - } - - reg0 += reg1; - reg2 += reg3; - reg0 += reg2; - tmp0 = __msa_hadd_s_d(reg0, reg0); - sse = (uint32_t)__msa_copy_u_w((v4i32)tmp0, 0); - sse += (uint32_t)__msa_copy_u_w((v4i32)tmp0, 2); - return sse; -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_neon.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_neon.cc deleted file mode 100644 index 2a2181e0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_neon.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2012 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/basic_types.h" - -#include "libyuv/compare_row.h" -#include "libyuv/row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -#if !defined(LIBYUV_DISABLE_NEON) && defined(__ARM_NEON__) && \ - !defined(__aarch64__) - -// 256 bits at a time -// uses short accumulator which restricts count to 131 KB -uint32_t HammingDistance_NEON(const uint8_t* src_a, - const uint8_t* src_b, - int count) { - uint32_t diff; - - asm volatile( - "vmov.u16 q4, #0 \n" // accumulator - - "1: \n" - "vld1.8 {q0, q1}, [%0]! \n" - "vld1.8 {q2, q3}, [%1]! \n" - "veor.32 q0, q0, q2 \n" - "veor.32 q1, q1, q3 \n" - "vcnt.i8 q0, q0 \n" - "vcnt.i8 q1, q1 \n" - "subs %2, %2, #32 \n" - "vadd.u8 q0, q0, q1 \n" // 16 byte counts - "vpadal.u8 q4, q0 \n" // 8 shorts - "bgt 1b \n" - - "vpaddl.u16 q0, q4 \n" // 4 ints - "vpadd.u32 d0, d0, d1 \n" - "vpadd.u32 d0, d0, d0 \n" - "vmov.32 %3, d0[0] \n" - - : "+r"(src_a), "+r"(src_b), "+r"(count), "=r"(diff) - : - : "cc", "q0", "q1", "q2", "q3", "q4"); - return diff; -} - -uint32_t SumSquareError_NEON(const uint8_t* src_a, - const uint8_t* src_b, - int count) { - uint32_t sse; - asm volatile( - "vmov.u8 q8, #0 \n" - "vmov.u8 q10, #0 \n" - "vmov.u8 q9, #0 \n" - "vmov.u8 q11, #0 \n" - - "1: \n" - "vld1.8 {q0}, [%0]! \n" - "vld1.8 {q1}, [%1]! \n" - "subs %2, %2, #16 \n" - "vsubl.u8 q2, d0, d2 \n" - "vsubl.u8 q3, d1, d3 \n" - "vmlal.s16 q8, d4, d4 \n" - "vmlal.s16 q9, d6, d6 \n" - "vmlal.s16 q10, d5, d5 \n" - "vmlal.s16 q11, d7, d7 \n" - "bgt 1b \n" - - "vadd.u32 q8, q8, q9 \n" - "vadd.u32 q10, q10, q11 \n" - "vadd.u32 q11, q8, q10 \n" - "vpaddl.u32 q1, q11 \n" - "vadd.u64 d0, d2, d3 \n" - "vmov.32 %3, d0[0] \n" - : "+r"(src_a), "+r"(src_b), "+r"(count), "=r"(sse) - : - : "memory", "cc", "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11"); - return sse; -} - -#endif // defined(__ARM_NEON__) && !defined(__aarch64__) - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_neon64.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_neon64.cc deleted file mode 100644 index 6e8f672a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_neon64.cc +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2012 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/basic_types.h" - -#include "libyuv/compare_row.h" -#include "libyuv/row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -#if !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) - -// 256 bits at a time -// uses short accumulator which restricts count to 131 KB -uint32_t HammingDistance_NEON(const uint8_t* src_a, - const uint8_t* src_b, - int count) { - uint32_t diff; - asm volatile( - "movi v4.8h, #0 \n" - - "1: \n" - "ld1 {v0.16b, v1.16b}, [%0], #32 \n" - "ld1 {v2.16b, v3.16b}, [%1], #32 \n" - "eor v0.16b, v0.16b, v2.16b \n" - "eor v1.16b, v1.16b, v3.16b \n" - "cnt v0.16b, v0.16b \n" - "cnt v1.16b, v1.16b \n" - "subs %w2, %w2, #32 \n" - "add v0.16b, v0.16b, v1.16b \n" - "uadalp v4.8h, v0.16b \n" - "b.gt 1b \n" - - "uaddlv s4, v4.8h \n" - "fmov %w3, s4 \n" - : "+r"(src_a), "+r"(src_b), "+r"(count), "=r"(diff) - : - : "cc", "v0", "v1", "v2", "v3", "v4"); - return diff; -} - -uint32_t SumSquareError_NEON(const uint8_t* src_a, - const uint8_t* src_b, - int count) { - uint32_t sse; - asm volatile( - "eor v16.16b, v16.16b, v16.16b \n" - "eor v18.16b, v18.16b, v18.16b \n" - "eor v17.16b, v17.16b, v17.16b \n" - "eor v19.16b, v19.16b, v19.16b \n" - - "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" - "ld1 {v1.16b}, [%1], #16 \n" - "subs %w2, %w2, #16 \n" - "usubl v2.8h, v0.8b, v1.8b \n" - "usubl2 v3.8h, v0.16b, v1.16b \n" - "smlal v16.4s, v2.4h, v2.4h \n" - "smlal v17.4s, v3.4h, v3.4h \n" - "smlal2 v18.4s, v2.8h, v2.8h \n" - "smlal2 v19.4s, v3.8h, v3.8h \n" - "b.gt 1b \n" - - "add v16.4s, v16.4s, v17.4s \n" - "add v18.4s, v18.4s, v19.4s \n" - "add v19.4s, v16.4s, v18.4s \n" - "addv s0, v19.4s \n" - "fmov %w3, s0 \n" - : "+r"(src_a), "+r"(src_b), "+r"(count), "=r"(sse) - : - : "cc", "v0", "v1", "v2", "v3", "v16", "v17", "v18", "v19"); - return sse; -} - -#endif // !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_win.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_win.cc deleted file mode 100644 index d57d3d9d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/compare_win.cc +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2012 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/basic_types.h" - -#include "libyuv/compare_row.h" -#include "libyuv/row.h" - -#if defined(_MSC_VER) -#include // For __popcnt -#endif - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// This module is for 32 bit Visual C x86 and clangcl -#if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) - -uint32_t HammingDistance_SSE42(const uint8_t* src_a, - const uint8_t* src_b, - int count) { - uint32_t diff = 0u; - - int i; - for (i = 0; i < count - 3; i += 4) { - uint32_t x = *((uint32_t*)src_a) ^ *((uint32_t*)src_b); // NOLINT - src_a += 4; - src_b += 4; - diff += __popcnt(x); - } - return diff; -} - -__declspec(naked) uint32_t - SumSquareError_SSE2(const uint8_t* src_a, const uint8_t* src_b, int count) { - __asm { - mov eax, [esp + 4] // src_a - mov edx, [esp + 8] // src_b - mov ecx, [esp + 12] // count - pxor xmm0, xmm0 - pxor xmm5, xmm5 - - wloop: - movdqu xmm1, [eax] - lea eax, [eax + 16] - movdqu xmm2, [edx] - lea edx, [edx + 16] - movdqa xmm3, xmm1 // abs trick - psubusb xmm1, xmm2 - psubusb xmm2, xmm3 - por xmm1, xmm2 - movdqa xmm2, xmm1 - punpcklbw xmm1, xmm5 - punpckhbw xmm2, xmm5 - pmaddwd xmm1, xmm1 - pmaddwd xmm2, xmm2 - paddd xmm0, xmm1 - paddd xmm0, xmm2 - sub ecx, 16 - jg wloop - - pshufd xmm1, xmm0, 0xee - paddd xmm0, xmm1 - pshufd xmm1, xmm0, 0x01 - paddd xmm0, xmm1 - movd eax, xmm0 - ret - } -} - -// Visual C 2012 required for AVX2. -#if _MSC_VER >= 1700 -// C4752: found Intel(R) Advanced Vector Extensions; consider using /arch:AVX. -#pragma warning(disable : 4752) -__declspec(naked) uint32_t - SumSquareError_AVX2(const uint8_t* src_a, const uint8_t* src_b, int count) { - __asm { - mov eax, [esp + 4] // src_a - mov edx, [esp + 8] // src_b - mov ecx, [esp + 12] // count - vpxor ymm0, ymm0, ymm0 // sum - vpxor ymm5, ymm5, ymm5 // constant 0 for unpck - sub edx, eax - - wloop: - vmovdqu ymm1, [eax] - vmovdqu ymm2, [eax + edx] - lea eax, [eax + 32] - vpsubusb ymm3, ymm1, ymm2 // abs difference trick - vpsubusb ymm2, ymm2, ymm1 - vpor ymm1, ymm2, ymm3 - vpunpcklbw ymm2, ymm1, ymm5 // u16. mutates order. - vpunpckhbw ymm1, ymm1, ymm5 - vpmaddwd ymm2, ymm2, ymm2 // square + hadd to u32. - vpmaddwd ymm1, ymm1, ymm1 - vpaddd ymm0, ymm0, ymm1 - vpaddd ymm0, ymm0, ymm2 - sub ecx, 32 - jg wloop - - vpshufd ymm1, ymm0, 0xee // 3, 2 + 1, 0 both lanes. - vpaddd ymm0, ymm0, ymm1 - vpshufd ymm1, ymm0, 0x01 // 1 + 0 both lanes. - vpaddd ymm0, ymm0, ymm1 - vpermq ymm1, ymm0, 0x02 // high + low lane. - vpaddd ymm0, ymm0, ymm1 - vmovd eax, xmm0 - vzeroupper - ret - } -} -#endif // _MSC_VER >= 1700 - -uvec32 kHash16x33 = {0x92d9e201, 0, 0, 0}; // 33 ^ 16 -uvec32 kHashMul0 = { - 0x0c3525e1, // 33 ^ 15 - 0xa3476dc1, // 33 ^ 14 - 0x3b4039a1, // 33 ^ 13 - 0x4f5f0981, // 33 ^ 12 -}; -uvec32 kHashMul1 = { - 0x30f35d61, // 33 ^ 11 - 0x855cb541, // 33 ^ 10 - 0x040a9121, // 33 ^ 9 - 0x747c7101, // 33 ^ 8 -}; -uvec32 kHashMul2 = { - 0xec41d4e1, // 33 ^ 7 - 0x4cfa3cc1, // 33 ^ 6 - 0x025528a1, // 33 ^ 5 - 0x00121881, // 33 ^ 4 -}; -uvec32 kHashMul3 = { - 0x00008c61, // 33 ^ 3 - 0x00000441, // 33 ^ 2 - 0x00000021, // 33 ^ 1 - 0x00000001, // 33 ^ 0 -}; - -__declspec(naked) uint32_t - HashDjb2_SSE41(const uint8_t* src, int count, uint32_t seed) { - __asm { - mov eax, [esp + 4] // src - mov ecx, [esp + 8] // count - movd xmm0, [esp + 12] // seed - - pxor xmm7, xmm7 // constant 0 for unpck - movdqa xmm6, xmmword ptr kHash16x33 - - wloop: - movdqu xmm1, [eax] // src[0-15] - lea eax, [eax + 16] - pmulld xmm0, xmm6 // hash *= 33 ^ 16 - movdqa xmm5, xmmword ptr kHashMul0 - movdqa xmm2, xmm1 - punpcklbw xmm2, xmm7 // src[0-7] - movdqa xmm3, xmm2 - punpcklwd xmm3, xmm7 // src[0-3] - pmulld xmm3, xmm5 - movdqa xmm5, xmmword ptr kHashMul1 - movdqa xmm4, xmm2 - punpckhwd xmm4, xmm7 // src[4-7] - pmulld xmm4, xmm5 - movdqa xmm5, xmmword ptr kHashMul2 - punpckhbw xmm1, xmm7 // src[8-15] - movdqa xmm2, xmm1 - punpcklwd xmm2, xmm7 // src[8-11] - pmulld xmm2, xmm5 - movdqa xmm5, xmmword ptr kHashMul3 - punpckhwd xmm1, xmm7 // src[12-15] - pmulld xmm1, xmm5 - paddd xmm3, xmm4 // add 16 results - paddd xmm1, xmm2 - paddd xmm1, xmm3 - - pshufd xmm2, xmm1, 0x0e // upper 2 dwords - paddd xmm1, xmm2 - pshufd xmm2, xmm1, 0x01 - paddd xmm1, xmm2 - paddd xmm0, xmm1 - sub ecx, 16 - jg wloop - - movd eax, xmm0 // return hash - ret - } -} - -// Visual C 2012 required for AVX2. -#if _MSC_VER >= 1700 -__declspec(naked) uint32_t - HashDjb2_AVX2(const uint8_t* src, int count, uint32_t seed) { - __asm { - mov eax, [esp + 4] // src - mov ecx, [esp + 8] // count - vmovd xmm0, [esp + 12] // seed - - wloop: - vpmovzxbd xmm3, [eax] // src[0-3] - vpmulld xmm0, xmm0, xmmword ptr kHash16x33 // hash *= 33 ^ 16 - vpmovzxbd xmm4, [eax + 4] // src[4-7] - vpmulld xmm3, xmm3, xmmword ptr kHashMul0 - vpmovzxbd xmm2, [eax + 8] // src[8-11] - vpmulld xmm4, xmm4, xmmword ptr kHashMul1 - vpmovzxbd xmm1, [eax + 12] // src[12-15] - vpmulld xmm2, xmm2, xmmword ptr kHashMul2 - lea eax, [eax + 16] - vpmulld xmm1, xmm1, xmmword ptr kHashMul3 - vpaddd xmm3, xmm3, xmm4 // add 16 results - vpaddd xmm1, xmm1, xmm2 - vpaddd xmm1, xmm1, xmm3 - vpshufd xmm2, xmm1, 0x0e // upper 2 dwords - vpaddd xmm1, xmm1,xmm2 - vpshufd xmm2, xmm1, 0x01 - vpaddd xmm1, xmm1, xmm2 - vpaddd xmm0, xmm0, xmm1 - sub ecx, 16 - jg wloop - - vmovd eax, xmm0 // return hash - vzeroupper - ret - } -} -#endif // _MSC_VER >= 1700 - -#endif // !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert.cc deleted file mode 100644 index 375cc732..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert.cc +++ /dev/null @@ -1,1740 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/convert.h" - -#include "libyuv/basic_types.h" -#include "libyuv/cpu_id.h" -#include "libyuv/planar_functions.h" -#include "libyuv/rotate.h" -#include "libyuv/row.h" -#include "libyuv/scale.h" // For ScalePlane() - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -#define SUBSAMPLE(v, a, s) (v < 0) ? (-((-v + a) >> s)) : ((v + a) >> s) -static __inline int Abs(int v) { - return v >= 0 ? v : -v; -} - -// Any I4xx To I420 format with mirroring. -static int I4xxToI420(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int src_y_width, - int src_y_height, - int src_uv_width, - int src_uv_height) { - const int dst_y_width = Abs(src_y_width); - const int dst_y_height = Abs(src_y_height); - const int dst_uv_width = SUBSAMPLE(dst_y_width, 1, 1); - const int dst_uv_height = SUBSAMPLE(dst_y_height, 1, 1); - if (src_uv_width == 0 || src_uv_height == 0) { - return -1; - } - if (dst_y) { - ScalePlane(src_y, src_stride_y, src_y_width, src_y_height, dst_y, - dst_stride_y, dst_y_width, dst_y_height, kFilterBilinear); - } - ScalePlane(src_u, src_stride_u, src_uv_width, src_uv_height, dst_u, - dst_stride_u, dst_uv_width, dst_uv_height, kFilterBilinear); - ScalePlane(src_v, src_stride_v, src_uv_width, src_uv_height, dst_v, - dst_stride_v, dst_uv_width, dst_uv_height, kFilterBilinear); - return 0; -} - -// Copy I420 with optional flipping. -// TODO(fbarchard): Use Scale plane which supports mirroring, but ensure -// is does row coalescing. -LIBYUV_API -int I420Copy(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - if (!src_u || !src_v || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - halfheight = (height + 1) >> 1; - src_y = src_y + (height - 1) * src_stride_y; - src_u = src_u + (halfheight - 1) * src_stride_u; - src_v = src_v + (halfheight - 1) * src_stride_v; - src_stride_y = -src_stride_y; - src_stride_u = -src_stride_u; - src_stride_v = -src_stride_v; - } - - if (dst_y) { - CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - } - // Copy UV planes. - CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, halfheight); - CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, halfheight); - return 0; -} - -// Copy I010 with optional flipping. -LIBYUV_API -int I010Copy(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint16_t* dst_y, - int dst_stride_y, - uint16_t* dst_u, - int dst_stride_u, - uint16_t* dst_v, - int dst_stride_v, - int width, - int height) { - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - if (!src_u || !src_v || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - halfheight = (height + 1) >> 1; - src_y = src_y + (height - 1) * src_stride_y; - src_u = src_u + (halfheight - 1) * src_stride_u; - src_v = src_v + (halfheight - 1) * src_stride_v; - src_stride_y = -src_stride_y; - src_stride_u = -src_stride_u; - src_stride_v = -src_stride_v; - } - - if (dst_y) { - CopyPlane_16(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - } - // Copy UV planes. - CopyPlane_16(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, halfheight); - CopyPlane_16(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, halfheight); - return 0; -} - -// Convert 10 bit YUV to 8 bit. -LIBYUV_API -int I010ToI420(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - if (!src_u || !src_v || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - halfheight = (height + 1) >> 1; - src_y = src_y + (height - 1) * src_stride_y; - src_u = src_u + (halfheight - 1) * src_stride_u; - src_v = src_v + (halfheight - 1) * src_stride_v; - src_stride_y = -src_stride_y; - src_stride_u = -src_stride_u; - src_stride_v = -src_stride_v; - } - - // Convert Y plane. - Convert16To8Plane(src_y, src_stride_y, dst_y, dst_stride_y, 16384, width, - height); - // Convert UV planes. - Convert16To8Plane(src_u, src_stride_u, dst_u, dst_stride_u, 16384, halfwidth, - halfheight); - Convert16To8Plane(src_v, src_stride_v, dst_v, dst_stride_v, 16384, halfwidth, - halfheight); - return 0; -} - -// 422 chroma is 1/2 width, 1x height -// 420 chroma is 1/2 width, 1/2 height -LIBYUV_API -int I422ToI420(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - const int src_uv_width = SUBSAMPLE(width, 1, 1); - return I4xxToI420(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u, - dst_v, dst_stride_v, width, height, src_uv_width, height); -} - -// 444 chroma is 1x width, 1x height -// 420 chroma is 1/2 width, 1/2 height -LIBYUV_API -int I444ToI420(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - return I4xxToI420(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u, - dst_v, dst_stride_v, width, height, width, height); -} - -// I400 is greyscale typically used in MJPG -LIBYUV_API -int I400ToI420(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - if (!dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - halfheight = (height + 1) >> 1; - src_y = src_y + (height - 1) * src_stride_y; - src_stride_y = -src_stride_y; - } - if (dst_y) { - CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - } - SetPlane(dst_u, dst_stride_u, halfwidth, halfheight, 128); - SetPlane(dst_v, dst_stride_v, halfwidth, halfheight, 128); - return 0; -} - -static void CopyPlane2(const uint8_t* src, - int src_stride_0, - int src_stride_1, - uint8_t* dst, - int dst_stride, - int width, - int height) { - int y; - void (*CopyRow)(const uint8_t* src, uint8_t* dst, int width) = CopyRow_C; -#if defined(HAS_COPYROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - CopyRow = IS_ALIGNED(width, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2; - } -#endif -#if defined(HAS_COPYROW_AVX) - if (TestCpuFlag(kCpuHasAVX)) { - CopyRow = IS_ALIGNED(width, 64) ? CopyRow_AVX : CopyRow_Any_AVX; - } -#endif -#if defined(HAS_COPYROW_ERMS) - if (TestCpuFlag(kCpuHasERMS)) { - CopyRow = CopyRow_ERMS; - } -#endif -#if defined(HAS_COPYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - CopyRow = IS_ALIGNED(width, 32) ? CopyRow_NEON : CopyRow_Any_NEON; - } -#endif - - // Copy plane - for (y = 0; y < height - 1; y += 2) { - CopyRow(src, dst, width); - CopyRow(src + src_stride_0, dst + dst_stride, width); - src += src_stride_0 + src_stride_1; - dst += dst_stride * 2; - } - if (height & 1) { - CopyRow(src, dst, width); - } -} - -// Support converting from FOURCC_M420 -// Useful for bandwidth constrained transports like USB 1.0 and 2.0 and for -// easy conversion to I420. -// M420 format description: -// M420 is row biplanar 420: 2 rows of Y and 1 row of UV. -// Chroma is half width / half height. (420) -// src_stride_m420 is row planar. Normally this will be the width in pixels. -// The UV plane is half width, but 2 values, so src_stride_m420 applies to -// this as well as the two Y planes. -static int X420ToI420(const uint8_t* src_y, - int src_stride_y0, - int src_stride_y1, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - if (!src_uv || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - halfheight = (height + 1) >> 1; - if (dst_y) { - dst_y = dst_y + (height - 1) * dst_stride_y; - } - dst_u = dst_u + (halfheight - 1) * dst_stride_u; - dst_v = dst_v + (halfheight - 1) * dst_stride_v; - dst_stride_y = -dst_stride_y; - dst_stride_u = -dst_stride_u; - dst_stride_v = -dst_stride_v; - } - // Coalesce rows. - if (src_stride_y0 == width && src_stride_y1 == width && - dst_stride_y == width) { - width *= height; - height = 1; - src_stride_y0 = src_stride_y1 = dst_stride_y = 0; - } - // Coalesce rows. - if (src_stride_uv == halfwidth * 2 && dst_stride_u == halfwidth && - dst_stride_v == halfwidth) { - halfwidth *= halfheight; - halfheight = 1; - src_stride_uv = dst_stride_u = dst_stride_v = 0; - } - - if (dst_y) { - if (src_stride_y0 == src_stride_y1) { - CopyPlane(src_y, src_stride_y0, dst_y, dst_stride_y, width, height); - } else { - CopyPlane2(src_y, src_stride_y0, src_stride_y1, dst_y, dst_stride_y, - width, height); - } - } - - // Split UV plane - NV12 / NV21 - SplitUVPlane(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v, dst_stride_v, - halfwidth, halfheight); - - return 0; -} - -// Convert NV12 to I420. -LIBYUV_API -int NV12ToI420(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - return X420ToI420(src_y, src_stride_y, src_stride_y, src_uv, src_stride_uv, - dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, - dst_stride_v, width, height); -} - -// Convert NV21 to I420. Same as NV12 but u and v pointers swapped. -LIBYUV_API -int NV21ToI420(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_vu, - int src_stride_vu, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - return X420ToI420(src_y, src_stride_y, src_stride_y, src_vu, src_stride_vu, - dst_y, dst_stride_y, dst_v, dst_stride_v, dst_u, - dst_stride_u, width, height); -} - -// Convert M420 to I420. -LIBYUV_API -int M420ToI420(const uint8_t* src_m420, - int src_stride_m420, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - return X420ToI420(src_m420, src_stride_m420, src_stride_m420 * 2, - src_m420 + src_stride_m420 * 2, src_stride_m420 * 3, dst_y, - dst_stride_y, dst_u, dst_stride_u, dst_v, dst_stride_v, - width, height); -} - -// Convert YUY2 to I420. -LIBYUV_API -int YUY2ToI420(const uint8_t* src_yuy2, - int src_stride_yuy2, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; - void (*YUY2ToUVRow)(const uint8_t* src_yuy2, int src_stride_yuy2, - uint8_t* dst_u, uint8_t* dst_v, int width) = - YUY2ToUVRow_C; - void (*YUY2ToYRow)(const uint8_t* src_yuy2, uint8_t* dst_y, int width) = - YUY2ToYRow_C; - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2; - src_stride_yuy2 = -src_stride_yuy2; - } -#if defined(HAS_YUY2TOYROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - YUY2ToUVRow = YUY2ToUVRow_Any_SSE2; - YUY2ToYRow = YUY2ToYRow_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - YUY2ToUVRow = YUY2ToUVRow_SSE2; - YUY2ToYRow = YUY2ToYRow_SSE2; - } - } -#endif -#if defined(HAS_YUY2TOYROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - YUY2ToUVRow = YUY2ToUVRow_Any_AVX2; - YUY2ToYRow = YUY2ToYRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - YUY2ToUVRow = YUY2ToUVRow_AVX2; - YUY2ToYRow = YUY2ToYRow_AVX2; - } - } -#endif -#if defined(HAS_YUY2TOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - YUY2ToYRow = YUY2ToYRow_Any_NEON; - YUY2ToUVRow = YUY2ToUVRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - YUY2ToYRow = YUY2ToYRow_NEON; - YUY2ToUVRow = YUY2ToUVRow_NEON; - } - } -#endif -#if defined(HAS_YUY2TOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - YUY2ToYRow = YUY2ToYRow_Any_MSA; - YUY2ToUVRow = YUY2ToUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - YUY2ToYRow = YUY2ToYRow_MSA; - YUY2ToUVRow = YUY2ToUVRow_MSA; - } - } -#endif - - for (y = 0; y < height - 1; y += 2) { - YUY2ToUVRow(src_yuy2, src_stride_yuy2, dst_u, dst_v, width); - YUY2ToYRow(src_yuy2, dst_y, width); - YUY2ToYRow(src_yuy2 + src_stride_yuy2, dst_y + dst_stride_y, width); - src_yuy2 += src_stride_yuy2 * 2; - dst_y += dst_stride_y * 2; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - if (height & 1) { - YUY2ToUVRow(src_yuy2, 0, dst_u, dst_v, width); - YUY2ToYRow(src_yuy2, dst_y, width); - } - return 0; -} - -// Convert UYVY to I420. -LIBYUV_API -int UYVYToI420(const uint8_t* src_uyvy, - int src_stride_uyvy, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; - void (*UYVYToUVRow)(const uint8_t* src_uyvy, int src_stride_uyvy, - uint8_t* dst_u, uint8_t* dst_v, int width) = - UYVYToUVRow_C; - void (*UYVYToYRow)(const uint8_t* src_uyvy, uint8_t* dst_y, int width) = - UYVYToYRow_C; - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy; - src_stride_uyvy = -src_stride_uyvy; - } -#if defined(HAS_UYVYTOYROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - UYVYToUVRow = UYVYToUVRow_Any_SSE2; - UYVYToYRow = UYVYToYRow_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - UYVYToUVRow = UYVYToUVRow_SSE2; - UYVYToYRow = UYVYToYRow_SSE2; - } - } -#endif -#if defined(HAS_UYVYTOYROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - UYVYToUVRow = UYVYToUVRow_Any_AVX2; - UYVYToYRow = UYVYToYRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - UYVYToUVRow = UYVYToUVRow_AVX2; - UYVYToYRow = UYVYToYRow_AVX2; - } - } -#endif -#if defined(HAS_UYVYTOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - UYVYToYRow = UYVYToYRow_Any_NEON; - UYVYToUVRow = UYVYToUVRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - UYVYToYRow = UYVYToYRow_NEON; - UYVYToUVRow = UYVYToUVRow_NEON; - } - } -#endif -#if defined(HAS_UYVYTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - UYVYToYRow = UYVYToYRow_Any_MSA; - UYVYToUVRow = UYVYToUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - UYVYToYRow = UYVYToYRow_MSA; - UYVYToUVRow = UYVYToUVRow_MSA; - } - } -#endif - - for (y = 0; y < height - 1; y += 2) { - UYVYToUVRow(src_uyvy, src_stride_uyvy, dst_u, dst_v, width); - UYVYToYRow(src_uyvy, dst_y, width); - UYVYToYRow(src_uyvy + src_stride_uyvy, dst_y + dst_stride_y, width); - src_uyvy += src_stride_uyvy * 2; - dst_y += dst_stride_y * 2; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - if (height & 1) { - UYVYToUVRow(src_uyvy, 0, dst_u, dst_v, width); - UYVYToYRow(src_uyvy, dst_y, width); - } - return 0; -} - -// Convert ARGB to I420. -LIBYUV_API -int ARGBToI420(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; - void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, - uint8_t* dst_u, uint8_t* dst_v, int width) = - ARGBToUVRow_C; - void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = - ARGBToYRow_C; - 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; - src_stride_argb = -src_stride_argb; - } -#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) && 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; - } - } -#endif -#if defined(HAS_ARGBTOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToYRow = ARGBToYRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToYRow = ARGBToYRow_NEON; - } - } -#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_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVRow = ARGBToUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVRow = ARGBToUVRow_MSA; - } - } -#endif - - for (y = 0; y < height - 1; y += 2) { - ARGBToUVRow(src_argb, src_stride_argb, dst_u, dst_v, width); - ARGBToYRow(src_argb, dst_y, width); - ARGBToYRow(src_argb + src_stride_argb, dst_y + dst_stride_y, width); - src_argb += src_stride_argb * 2; - dst_y += dst_stride_y * 2; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - if (height & 1) { - ARGBToUVRow(src_argb, 0, dst_u, dst_v, width); - ARGBToYRow(src_argb, dst_y, width); - } - return 0; -} - -// Convert BGRA to I420. -LIBYUV_API -int BGRAToI420(const uint8_t* src_bgra, - int src_stride_bgra, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; - void (*BGRAToUVRow)(const uint8_t* src_bgra0, int src_stride_bgra, - uint8_t* dst_u, uint8_t* dst_v, int width) = - BGRAToUVRow_C; - void (*BGRAToYRow)(const uint8_t* src_bgra, uint8_t* dst_y, int width) = - BGRAToYRow_C; - if (!src_bgra || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_bgra = src_bgra + (height - 1) * src_stride_bgra; - src_stride_bgra = -src_stride_bgra; - } -#if defined(HAS_BGRATOYROW_SSSE3) && defined(HAS_BGRATOUVROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - BGRAToUVRow = BGRAToUVRow_Any_SSSE3; - BGRAToYRow = BGRAToYRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - BGRAToUVRow = BGRAToUVRow_SSSE3; - BGRAToYRow = BGRAToYRow_SSSE3; - } - } -#endif -#if defined(HAS_BGRATOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - BGRAToYRow = BGRAToYRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - BGRAToYRow = BGRAToYRow_NEON; - } - } -#endif -#if defined(HAS_BGRATOUVROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - BGRAToUVRow = BGRAToUVRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - BGRAToUVRow = BGRAToUVRow_NEON; - } - } -#endif -#if defined(HAS_BGRATOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - BGRAToYRow = BGRAToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - BGRAToYRow = BGRAToYRow_MSA; - } - } -#endif -#if defined(HAS_BGRATOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - BGRAToUVRow = BGRAToUVRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - BGRAToUVRow = BGRAToUVRow_MSA; - } - } -#endif - - for (y = 0; y < height - 1; y += 2) { - BGRAToUVRow(src_bgra, src_stride_bgra, dst_u, dst_v, width); - BGRAToYRow(src_bgra, dst_y, width); - BGRAToYRow(src_bgra + src_stride_bgra, dst_y + dst_stride_y, width); - src_bgra += src_stride_bgra * 2; - dst_y += dst_stride_y * 2; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - if (height & 1) { - BGRAToUVRow(src_bgra, 0, dst_u, dst_v, width); - BGRAToYRow(src_bgra, dst_y, width); - } - return 0; -} - -// Convert ABGR to I420. -LIBYUV_API -int ABGRToI420(const uint8_t* src_abgr, - int src_stride_abgr, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; - void (*ABGRToUVRow)(const uint8_t* src_abgr0, int src_stride_abgr, - uint8_t* dst_u, uint8_t* dst_v, int width) = - ABGRToUVRow_C; - void (*ABGRToYRow)(const uint8_t* src_abgr, uint8_t* dst_y, int width) = - ABGRToYRow_C; - if (!src_abgr || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_abgr = src_abgr + (height - 1) * src_stride_abgr; - src_stride_abgr = -src_stride_abgr; - } -#if defined(HAS_ABGRTOYROW_SSSE3) && defined(HAS_ABGRTOUVROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - ABGRToUVRow = ABGRToUVRow_Any_SSSE3; - ABGRToYRow = ABGRToYRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - ABGRToUVRow = ABGRToUVRow_SSSE3; - ABGRToYRow = ABGRToYRow_SSSE3; - } - } -#endif -#if defined(HAS_ABGRTOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ABGRToYRow = ABGRToYRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ABGRToYRow = ABGRToYRow_NEON; - } - } -#endif -#if defined(HAS_ABGRTOUVROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ABGRToUVRow = ABGRToUVRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - ABGRToUVRow = ABGRToUVRow_NEON; - } - } -#endif -#if defined(HAS_ABGRTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ABGRToYRow = ABGRToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ABGRToYRow = ABGRToYRow_MSA; - } - } -#endif -#if defined(HAS_ABGRTOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ABGRToUVRow = ABGRToUVRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ABGRToUVRow = ABGRToUVRow_MSA; - } - } -#endif - - for (y = 0; y < height - 1; y += 2) { - ABGRToUVRow(src_abgr, src_stride_abgr, dst_u, dst_v, width); - ABGRToYRow(src_abgr, dst_y, width); - ABGRToYRow(src_abgr + src_stride_abgr, dst_y + dst_stride_y, width); - src_abgr += src_stride_abgr * 2; - dst_y += dst_stride_y * 2; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - if (height & 1) { - ABGRToUVRow(src_abgr, 0, dst_u, dst_v, width); - ABGRToYRow(src_abgr, dst_y, width); - } - return 0; -} - -// Convert RGBA to I420. -LIBYUV_API -int RGBAToI420(const uint8_t* src_rgba, - int src_stride_rgba, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; - void (*RGBAToUVRow)(const uint8_t* src_rgba0, int src_stride_rgba, - uint8_t* dst_u, uint8_t* dst_v, int width) = - RGBAToUVRow_C; - void (*RGBAToYRow)(const uint8_t* src_rgba, uint8_t* dst_y, int width) = - RGBAToYRow_C; - if (!src_rgba || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_rgba = src_rgba + (height - 1) * src_stride_rgba; - src_stride_rgba = -src_stride_rgba; - } -#if defined(HAS_RGBATOYROW_SSSE3) && defined(HAS_RGBATOUVROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - RGBAToUVRow = RGBAToUVRow_Any_SSSE3; - RGBAToYRow = RGBAToYRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - RGBAToUVRow = RGBAToUVRow_SSSE3; - RGBAToYRow = RGBAToYRow_SSSE3; - } - } -#endif -#if defined(HAS_RGBATOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - RGBAToYRow = RGBAToYRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - RGBAToYRow = RGBAToYRow_NEON; - } - } -#endif -#if defined(HAS_RGBATOUVROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - RGBAToUVRow = RGBAToUVRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - RGBAToUVRow = RGBAToUVRow_NEON; - } - } -#endif -#if defined(HAS_RGBATOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RGBAToYRow = RGBAToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RGBAToYRow = RGBAToYRow_MSA; - } - } -#endif -#if defined(HAS_RGBATOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RGBAToUVRow = RGBAToUVRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RGBAToUVRow = RGBAToUVRow_MSA; - } - } -#endif - - for (y = 0; y < height - 1; y += 2) { - RGBAToUVRow(src_rgba, src_stride_rgba, dst_u, dst_v, width); - RGBAToYRow(src_rgba, dst_y, width); - RGBAToYRow(src_rgba + src_stride_rgba, dst_y + dst_stride_y, width); - src_rgba += src_stride_rgba * 2; - dst_y += dst_stride_y * 2; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - if (height & 1) { - RGBAToUVRow(src_rgba, 0, dst_u, dst_v, width); - RGBAToYRow(src_rgba, dst_y, width); - } - return 0; -} - -// Convert RGB24 to I420. -LIBYUV_API -int RGB24ToI420(const uint8_t* src_rgb24, - int src_stride_rgb24, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; -#if (defined(HAS_RGB24TOYROW_NEON) || defined(HAS_RGB24TOYROW_MSA)) - void (*RGB24ToUVRow)(const uint8_t* src_rgb24, int src_stride_rgb24, - uint8_t* dst_u, uint8_t* dst_v, int width) = - RGB24ToUVRow_C; - void (*RGB24ToYRow)(const uint8_t* src_rgb24, uint8_t* dst_y, int width) = - RGB24ToYRow_C; -#else - void (*RGB24ToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, int width) = - RGB24ToARGBRow_C; - void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, - uint8_t* dst_u, uint8_t* dst_v, int width) = - ARGBToUVRow_C; - void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = - ARGBToYRow_C; -#endif - if (!src_rgb24 || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_rgb24 = src_rgb24 + (height - 1) * src_stride_rgb24; - src_stride_rgb24 = -src_stride_rgb24; - } - -// Neon version does direct RGB24 to YUV. -#if defined(HAS_RGB24TOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - RGB24ToUVRow = RGB24ToUVRow_Any_NEON; - RGB24ToYRow = RGB24ToYRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - RGB24ToYRow = RGB24ToYRow_NEON; - if (IS_ALIGNED(width, 16)) { - RGB24ToUVRow = RGB24ToUVRow_NEON; - } - } - } -#elif defined(HAS_RGB24TOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RGB24ToUVRow = RGB24ToUVRow_Any_MSA; - RGB24ToYRow = RGB24ToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RGB24ToYRow = RGB24ToYRow_MSA; - RGB24ToUVRow = RGB24ToUVRow_MSA; - } - } -// Other platforms do intermediate conversion from RGB24 to ARGB. -#else -#if defined(HAS_RGB24TOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - RGB24ToARGBRow = RGB24ToARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - RGB24ToARGBRow = RGB24ToARGBRow_SSSE3; - } - } -#endif -#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) && 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; - } - } -#endif -#endif - - { -#if !(defined(HAS_RGB24TOYROW_NEON) || defined(HAS_RGB24TOYROW_MSA)) - // Allocate 2 rows of ARGB. - const int kRowSize = (width * 4 + 31) & ~31; - align_buffer_64(row, kRowSize * 2); -#endif - - for (y = 0; y < height - 1; y += 2) { -#if (defined(HAS_RGB24TOYROW_NEON) || defined(HAS_RGB24TOYROW_MSA)) - RGB24ToUVRow(src_rgb24, src_stride_rgb24, dst_u, dst_v, width); - RGB24ToYRow(src_rgb24, dst_y, width); - RGB24ToYRow(src_rgb24 + src_stride_rgb24, dst_y + dst_stride_y, width); -#else - RGB24ToARGBRow(src_rgb24, row, width); - RGB24ToARGBRow(src_rgb24 + src_stride_rgb24, row + kRowSize, width); - ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); - ARGBToYRow(row, dst_y, width); - ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); -#endif - src_rgb24 += src_stride_rgb24 * 2; - dst_y += dst_stride_y * 2; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - if (height & 1) { -#if (defined(HAS_RGB24TOYROW_NEON) || defined(HAS_RGB24TOYROW_MSA)) - RGB24ToUVRow(src_rgb24, 0, dst_u, dst_v, width); - RGB24ToYRow(src_rgb24, dst_y, width); -#else - RGB24ToARGBRow(src_rgb24, row, width); - ARGBToUVRow(row, 0, dst_u, dst_v, width); - ARGBToYRow(row, dst_y, width); -#endif - } -#if !(defined(HAS_RGB24TOYROW_NEON) || defined(HAS_RGB24TOYROW_MSA)) - free_aligned_buffer_64(row); -#endif - } - return 0; -} - -// Convert RAW to I420. -LIBYUV_API -int RAWToI420(const uint8_t* src_raw, - int src_stride_raw, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; -#if (defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA)) - void (*RAWToUVRow)(const uint8_t* src_raw, int src_stride_raw, uint8_t* dst_u, - uint8_t* dst_v, int width) = RAWToUVRow_C; - void (*RAWToYRow)(const uint8_t* src_raw, uint8_t* dst_y, int width) = - RAWToYRow_C; -#else - void (*RAWToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, int width) = - RAWToARGBRow_C; - void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, - uint8_t* dst_u, uint8_t* dst_v, int width) = - ARGBToUVRow_C; - void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = - ARGBToYRow_C; -#endif - if (!src_raw || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_raw = src_raw + (height - 1) * src_stride_raw; - src_stride_raw = -src_stride_raw; - } - -// Neon version does direct RAW to YUV. -#if defined(HAS_RAWTOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - RAWToUVRow = RAWToUVRow_Any_NEON; - RAWToYRow = RAWToYRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - RAWToYRow = RAWToYRow_NEON; - if (IS_ALIGNED(width, 16)) { - RAWToUVRow = RAWToUVRow_NEON; - } - } - } -#elif defined(HAS_RAWTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RAWToUVRow = RAWToUVRow_Any_MSA; - RAWToYRow = RAWToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RAWToYRow = RAWToYRow_MSA; - RAWToUVRow = RAWToUVRow_MSA; - } - } -// Other platforms do intermediate conversion from RAW to ARGB. -#else -#if defined(HAS_RAWTOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - RAWToARGBRow = RAWToARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - RAWToARGBRow = RAWToARGBRow_SSSE3; - } - } -#endif -#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) && 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; - } - } -#endif -#endif - - { -#if !(defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA)) - // Allocate 2 rows of ARGB. - const int kRowSize = (width * 4 + 31) & ~31; - align_buffer_64(row, kRowSize * 2); -#endif - - for (y = 0; y < height - 1; y += 2) { -#if (defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA)) - RAWToUVRow(src_raw, src_stride_raw, dst_u, dst_v, width); - RAWToYRow(src_raw, dst_y, width); - RAWToYRow(src_raw + src_stride_raw, dst_y + dst_stride_y, width); -#else - RAWToARGBRow(src_raw, row, width); - RAWToARGBRow(src_raw + src_stride_raw, row + kRowSize, width); - ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); - ARGBToYRow(row, dst_y, width); - ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); -#endif - src_raw += src_stride_raw * 2; - dst_y += dst_stride_y * 2; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - if (height & 1) { -#if (defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA)) - RAWToUVRow(src_raw, 0, dst_u, dst_v, width); - RAWToYRow(src_raw, dst_y, width); -#else - RAWToARGBRow(src_raw, row, width); - ARGBToUVRow(row, 0, dst_u, dst_v, width); - ARGBToYRow(row, dst_y, width); -#endif - } -#if !(defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA)) - free_aligned_buffer_64(row); -#endif - } - return 0; -} - -// Convert RGB565 to I420. -LIBYUV_API -int RGB565ToI420(const uint8_t* src_rgb565, - int src_stride_rgb565, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; -#if (defined(HAS_RGB565TOYROW_NEON) || defined(HAS_RGB565TOYROW_MSA)) - void (*RGB565ToUVRow)(const uint8_t* src_rgb565, int src_stride_rgb565, - uint8_t* dst_u, uint8_t* dst_v, int width) = - RGB565ToUVRow_C; - void (*RGB565ToYRow)(const uint8_t* src_rgb565, uint8_t* dst_y, int width) = - RGB565ToYRow_C; -#else - void (*RGB565ToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, - int width) = RGB565ToARGBRow_C; - void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, - uint8_t* dst_u, uint8_t* dst_v, int width) = - ARGBToUVRow_C; - void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = - ARGBToYRow_C; -#endif - if (!src_rgb565 || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_rgb565 = src_rgb565 + (height - 1) * src_stride_rgb565; - src_stride_rgb565 = -src_stride_rgb565; - } - -// Neon version does direct RGB565 to YUV. -#if defined(HAS_RGB565TOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - RGB565ToUVRow = RGB565ToUVRow_Any_NEON; - RGB565ToYRow = RGB565ToYRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - RGB565ToYRow = RGB565ToYRow_NEON; - if (IS_ALIGNED(width, 16)) { - RGB565ToUVRow = RGB565ToUVRow_NEON; - } - } - } -#elif defined(HAS_RGB565TOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RGB565ToUVRow = RGB565ToUVRow_Any_MSA; - RGB565ToYRow = RGB565ToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RGB565ToYRow = RGB565ToYRow_MSA; - RGB565ToUVRow = RGB565ToUVRow_MSA; - } - } -// Other platforms do intermediate conversion from RGB565 to ARGB. -#else -#if defined(HAS_RGB565TOARGBROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - RGB565ToARGBRow = RGB565ToARGBRow_Any_SSE2; - if (IS_ALIGNED(width, 8)) { - RGB565ToARGBRow = RGB565ToARGBRow_SSE2; - } - } -#endif -#if defined(HAS_RGB565TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - RGB565ToARGBRow = RGB565ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - RGB565ToARGBRow = RGB565ToARGBRow_AVX2; - } - } -#endif -#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) && 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; - } - } -#endif -#endif - { -#if !(defined(HAS_RGB565TOYROW_NEON) || defined(HAS_RGB565TOYROW_MSA)) - // Allocate 2 rows of ARGB. - const int kRowSize = (width * 4 + 31) & ~31; - align_buffer_64(row, kRowSize * 2); -#endif - for (y = 0; y < height - 1; y += 2) { -#if (defined(HAS_RGB565TOYROW_NEON) || defined(HAS_RGB565TOYROW_MSA)) - RGB565ToUVRow(src_rgb565, src_stride_rgb565, dst_u, dst_v, width); - RGB565ToYRow(src_rgb565, dst_y, width); - RGB565ToYRow(src_rgb565 + src_stride_rgb565, dst_y + dst_stride_y, width); -#else - RGB565ToARGBRow(src_rgb565, row, width); - RGB565ToARGBRow(src_rgb565 + src_stride_rgb565, row + kRowSize, width); - ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); - ARGBToYRow(row, dst_y, width); - ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); -#endif - src_rgb565 += src_stride_rgb565 * 2; - dst_y += dst_stride_y * 2; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - if (height & 1) { -#if (defined(HAS_RGB565TOYROW_NEON) || defined(HAS_RGB565TOYROW_MSA)) - RGB565ToUVRow(src_rgb565, 0, dst_u, dst_v, width); - RGB565ToYRow(src_rgb565, dst_y, width); -#else - RGB565ToARGBRow(src_rgb565, row, width); - ARGBToUVRow(row, 0, dst_u, dst_v, width); - ARGBToYRow(row, dst_y, width); -#endif - } -#if !(defined(HAS_RGB565TOYROW_NEON) || defined(HAS_RGB565TOYROW_MSA)) - free_aligned_buffer_64(row); -#endif - } - return 0; -} - -// Convert ARGB1555 to I420. -LIBYUV_API -int ARGB1555ToI420(const uint8_t* src_argb1555, - int src_stride_argb1555, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; -#if (defined(HAS_ARGB1555TOYROW_NEON) || defined(HAS_ARGB1555TOYROW_MSA)) - void (*ARGB1555ToUVRow)(const uint8_t* src_argb1555, int src_stride_argb1555, - uint8_t* dst_u, uint8_t* dst_v, int width) = - ARGB1555ToUVRow_C; - void (*ARGB1555ToYRow)(const uint8_t* src_argb1555, uint8_t* dst_y, - int width) = ARGB1555ToYRow_C; -#else - void (*ARGB1555ToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, - int width) = ARGB1555ToARGBRow_C; - void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, - uint8_t* dst_u, uint8_t* dst_v, int width) = - ARGBToUVRow_C; - void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = - ARGBToYRow_C; -#endif - if (!src_argb1555 || !dst_y || !dst_u || !dst_v || width <= 0 || - height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_argb1555 = src_argb1555 + (height - 1) * src_stride_argb1555; - src_stride_argb1555 = -src_stride_argb1555; - } - -// Neon version does direct ARGB1555 to YUV. -#if defined(HAS_ARGB1555TOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGB1555ToUVRow = ARGB1555ToUVRow_Any_NEON; - ARGB1555ToYRow = ARGB1555ToYRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGB1555ToYRow = ARGB1555ToYRow_NEON; - if (IS_ALIGNED(width, 16)) { - ARGB1555ToUVRow = ARGB1555ToUVRow_NEON; - } - } - } -#elif defined(HAS_ARGB1555TOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGB1555ToUVRow = ARGB1555ToUVRow_Any_MSA; - ARGB1555ToYRow = ARGB1555ToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGB1555ToYRow = ARGB1555ToYRow_MSA; - ARGB1555ToUVRow = ARGB1555ToUVRow_MSA; - } - } -// Other platforms do intermediate conversion from ARGB1555 to ARGB. -#else -#if defined(HAS_ARGB1555TOARGBROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_SSE2; - if (IS_ALIGNED(width, 8)) { - ARGB1555ToARGBRow = ARGB1555ToARGBRow_SSE2; - } - } -#endif -#if defined(HAS_ARGB1555TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - ARGB1555ToARGBRow = ARGB1555ToARGBRow_AVX2; - } - } -#endif -#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) && 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; - } - } -#endif -#endif - { -#if !(defined(HAS_ARGB1555TOYROW_NEON) || defined(HAS_ARGB1555TOYROW_MSA)) - // Allocate 2 rows of ARGB. - const int kRowSize = (width * 4 + 31) & ~31; - align_buffer_64(row, kRowSize * 2); -#endif - - for (y = 0; y < height - 1; y += 2) { -#if (defined(HAS_ARGB1555TOYROW_NEON) || defined(HAS_ARGB1555TOYROW_MSA)) - ARGB1555ToUVRow(src_argb1555, src_stride_argb1555, dst_u, dst_v, width); - ARGB1555ToYRow(src_argb1555, dst_y, width); - ARGB1555ToYRow(src_argb1555 + src_stride_argb1555, dst_y + dst_stride_y, - width); -#else - ARGB1555ToARGBRow(src_argb1555, row, width); - ARGB1555ToARGBRow(src_argb1555 + src_stride_argb1555, row + kRowSize, - width); - ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); - ARGBToYRow(row, dst_y, width); - ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); -#endif - src_argb1555 += src_stride_argb1555 * 2; - dst_y += dst_stride_y * 2; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - if (height & 1) { -#if (defined(HAS_ARGB1555TOYROW_NEON) || defined(HAS_ARGB1555TOYROW_MSA)) - ARGB1555ToUVRow(src_argb1555, 0, dst_u, dst_v, width); - ARGB1555ToYRow(src_argb1555, dst_y, width); -#else - ARGB1555ToARGBRow(src_argb1555, row, width); - ARGBToUVRow(row, 0, dst_u, dst_v, width); - ARGBToYRow(row, dst_y, width); -#endif - } -#if !(defined(HAS_ARGB1555TOYROW_NEON) || defined(HAS_ARGB1555TOYROW_MSA)) - free_aligned_buffer_64(row); -#endif - } - return 0; -} - -// Convert ARGB4444 to I420. -LIBYUV_API -int ARGB4444ToI420(const uint8_t* src_argb4444, - int src_stride_argb4444, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; -#if defined(HAS_ARGB4444TOYROW_NEON) - void (*ARGB4444ToUVRow)(const uint8_t* src_argb4444, int src_stride_argb4444, - uint8_t* dst_u, uint8_t* dst_v, int width) = - ARGB4444ToUVRow_C; - void (*ARGB4444ToYRow)(const uint8_t* src_argb4444, uint8_t* dst_y, - int width) = ARGB4444ToYRow_C; -#else - void (*ARGB4444ToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, - int width) = ARGB4444ToARGBRow_C; - void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, - uint8_t* dst_u, uint8_t* dst_v, int width) = - ARGBToUVRow_C; - void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = - ARGBToYRow_C; -#endif - if (!src_argb4444 || !dst_y || !dst_u || !dst_v || width <= 0 || - height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_argb4444 = src_argb4444 + (height - 1) * src_stride_argb4444; - src_stride_argb4444 = -src_stride_argb4444; - } - -// Neon version does direct ARGB4444 to YUV. -#if defined(HAS_ARGB4444TOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGB4444ToUVRow = ARGB4444ToUVRow_Any_NEON; - ARGB4444ToYRow = ARGB4444ToYRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGB4444ToYRow = ARGB4444ToYRow_NEON; - if (IS_ALIGNED(width, 16)) { - ARGB4444ToUVRow = ARGB4444ToUVRow_NEON; - } - } - } -// Other platforms do intermediate conversion from ARGB4444 to ARGB. -#else -#if defined(HAS_ARGB4444TOARGBROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_SSE2; - if (IS_ALIGNED(width, 8)) { - ARGB4444ToARGBRow = ARGB4444ToARGBRow_SSE2; - } - } -#endif -#if defined(HAS_ARGB4444TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - ARGB4444ToARGBRow = ARGB4444ToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_ARGB4444TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGB4444ToARGBRow = ARGB4444ToARGBRow_MSA; - } - } -#endif -#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) && 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; - } - } -#endif -#if defined(HAS_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVRow = ARGBToUVRow_Any_MSA; - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVRow = ARGBToUVRow_MSA; - } - } - } -#endif -#endif - - { -#if !defined(HAS_ARGB4444TOYROW_NEON) - // Allocate 2 rows of ARGB. - const int kRowSize = (width * 4 + 31) & ~31; - align_buffer_64(row, kRowSize * 2); -#endif - - for (y = 0; y < height - 1; y += 2) { -#if defined(HAS_ARGB4444TOYROW_NEON) - ARGB4444ToUVRow(src_argb4444, src_stride_argb4444, dst_u, dst_v, width); - ARGB4444ToYRow(src_argb4444, dst_y, width); - ARGB4444ToYRow(src_argb4444 + src_stride_argb4444, dst_y + dst_stride_y, - width); -#else - ARGB4444ToARGBRow(src_argb4444, row, width); - ARGB4444ToARGBRow(src_argb4444 + src_stride_argb4444, row + kRowSize, - width); - ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); - ARGBToYRow(row, dst_y, width); - ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); -#endif - src_argb4444 += src_stride_argb4444 * 2; - dst_y += dst_stride_y * 2; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - if (height & 1) { -#if defined(HAS_ARGB4444TOYROW_NEON) - ARGB4444ToUVRow(src_argb4444, 0, dst_u, dst_v, width); - ARGB4444ToYRow(src_argb4444, dst_y, width); -#else - ARGB4444ToARGBRow(src_argb4444, row, width); - ARGBToUVRow(row, 0, dst_u, dst_v, width); - ARGBToYRow(row, dst_y, width); -#endif - } -#if !defined(HAS_ARGB4444TOYROW_NEON) - free_aligned_buffer_64(row); -#endif - } - return 0; -} - -static void SplitPixels(const uint8_t* src_u, - int src_pixel_stride_uv, - uint8_t* dst_u, - int width) { - int i; - for (i = 0; i < width; ++i) { - *dst_u = *src_u; - ++dst_u; - src_u += src_pixel_stride_uv; - } -} - -// Convert Android420 to I420. -LIBYUV_API -int Android420ToI420(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - int src_pixel_stride_uv, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; - const ptrdiff_t vu_off = src_v - src_u; - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - if (!src_u || !src_v || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - halfheight = (height + 1) >> 1; - src_y = src_y + (height - 1) * src_stride_y; - src_u = src_u + (halfheight - 1) * src_stride_u; - src_v = src_v + (halfheight - 1) * src_stride_v; - src_stride_y = -src_stride_y; - src_stride_u = -src_stride_u; - src_stride_v = -src_stride_v; - } - - if (dst_y) { - CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - } - - // Copy UV planes as is - I420 - if (src_pixel_stride_uv == 1) { - CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, halfheight); - CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, halfheight); - return 0; - // Split UV planes - NV21 - } - if (src_pixel_stride_uv == 2 && vu_off == -1 && - src_stride_u == src_stride_v) { - SplitUVPlane(src_v, src_stride_v, dst_v, dst_stride_v, dst_u, dst_stride_u, - halfwidth, halfheight); - return 0; - // Split UV planes - NV12 - } - if (src_pixel_stride_uv == 2 && vu_off == 1 && src_stride_u == src_stride_v) { - SplitUVPlane(src_u, src_stride_u, dst_u, dst_stride_u, dst_v, dst_stride_v, - halfwidth, halfheight); - return 0; - } - - for (y = 0; y < halfheight; ++y) { - SplitPixels(src_u, src_pixel_stride_uv, dst_u, halfwidth); - SplitPixels(src_v, src_pixel_stride_uv, dst_v, halfwidth); - src_u += src_stride_u; - src_v += src_stride_v; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - return 0; -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_argb.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_argb.cc deleted file mode 100644 index f2fe474f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_argb.cc +++ /dev/null @@ -1,2231 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/convert_argb.h" - -#include "libyuv/cpu_id.h" -#ifdef HAVE_JPEG -#include "libyuv/mjpeg_decoder.h" -#endif -#include "libyuv/planar_functions.h" // For CopyPlane and ARGBShuffle. -#include "libyuv/rotate_argb.h" -#include "libyuv/row.h" -#include "libyuv/video_common.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// Copy ARGB with optional flipping -LIBYUV_API -int ARGBCopy(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - if (!src_argb || !dst_argb || 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; - src_stride_argb = -src_stride_argb; - } - - CopyPlane(src_argb, src_stride_argb, dst_argb, dst_stride_argb, width * 4, - height); - return 0; -} - -// Convert I420 to ARGB with matrix -static int I420ToARGBMatrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*I422ToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I422ToARGBRow_C; - if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb = dst_argb + (height - 1) * dst_stride_argb; - dst_stride_argb = -dst_stride_argb; - } -#if defined(HAS_I422TOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToARGBRow = I422ToARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToARGBRow = I422ToARGBRow_SSSE3; - } - } -#endif -#if defined(HAS_I422TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToARGBRow = I422ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToARGBRow = I422ToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_I422TOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToARGBRow = I422ToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToARGBRow = I422ToARGBRow_NEON; - } - } -#endif -#if defined(HAS_I422TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToARGBRow = I422ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToARGBRow = I422ToARGBRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToARGBRow(src_y, src_u, src_v, dst_argb, yuvconstants, width); - dst_argb += dst_stride_argb; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - return 0; -} - -// Convert I420 to ARGB. -LIBYUV_API -int I420ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return I420ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_argb, dst_stride_argb, - &kYuvI601Constants, width, height); -} - -// Convert I420 to ABGR. -LIBYUV_API -int I420ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - return I420ToARGBMatrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_abgr, dst_stride_abgr, - &kYvuI601Constants, // Use Yvu matrix - width, height); -} - -// Convert J420 to ARGB. -LIBYUV_API -int J420ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return I420ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_argb, dst_stride_argb, - &kYuvJPEGConstants, width, height); -} - -// Convert J420 to ABGR. -LIBYUV_API -int J420ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - return I420ToARGBMatrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_abgr, dst_stride_abgr, - &kYvuJPEGConstants, // Use Yvu matrix - width, height); -} - -// Convert H420 to ARGB. -LIBYUV_API -int H420ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return I420ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_argb, dst_stride_argb, - &kYuvH709Constants, width, height); -} - -// Convert H420 to ABGR. -LIBYUV_API -int H420ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - return I420ToARGBMatrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_abgr, dst_stride_abgr, - &kYvuH709Constants, // Use Yvu matrix - width, height); -} - -// Convert I422 to ARGB with matrix -static int I422ToARGBMatrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*I422ToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I422ToARGBRow_C; - if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb = dst_argb + (height - 1) * dst_stride_argb; - dst_stride_argb = -dst_stride_argb; - } - // Coalesce rows. - if (src_stride_y == width && src_stride_u * 2 == width && - src_stride_v * 2 == width && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0; - } -#if defined(HAS_I422TOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToARGBRow = I422ToARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToARGBRow = I422ToARGBRow_SSSE3; - } - } -#endif -#if defined(HAS_I422TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToARGBRow = I422ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToARGBRow = I422ToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_I422TOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToARGBRow = I422ToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToARGBRow = I422ToARGBRow_NEON; - } - } -#endif -#if defined(HAS_I422TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToARGBRow = I422ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToARGBRow = I422ToARGBRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToARGBRow(src_y, src_u, src_v, dst_argb, yuvconstants, width); - dst_argb += dst_stride_argb; - src_y += src_stride_y; - src_u += src_stride_u; - src_v += src_stride_v; - } - return 0; -} - -// Convert I422 to ARGB. -LIBYUV_API -int I422ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return I422ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_argb, dst_stride_argb, - &kYuvI601Constants, width, height); -} - -// Convert I422 to ABGR. -LIBYUV_API -int I422ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - return I422ToARGBMatrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_abgr, dst_stride_abgr, - &kYvuI601Constants, // Use Yvu matrix - width, height); -} - -// Convert J422 to ARGB. -LIBYUV_API -int J422ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return I422ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_argb, dst_stride_argb, - &kYuvJPEGConstants, width, height); -} - -// Convert J422 to ABGR. -LIBYUV_API -int J422ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - return I422ToARGBMatrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_abgr, dst_stride_abgr, - &kYvuJPEGConstants, // Use Yvu matrix - width, height); -} - -// Convert H422 to ARGB. -LIBYUV_API -int H422ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return I422ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_argb, dst_stride_argb, - &kYuvH709Constants, width, height); -} - -// Convert H422 to ABGR. -LIBYUV_API -int H422ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - return I422ToARGBMatrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_abgr, dst_stride_abgr, - &kYvuH709Constants, // Use Yvu matrix - width, height); -} - -// Convert 10 bit YUV to ARGB with matrix -// TODO(fbarchard): Consider passing scale multiplier to I210ToARGB to -// multiply 10 bit yuv into high bits to allow any number of bits. -static int I010ToAR30Matrix(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_ar30, - int dst_stride_ar30, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*I210ToAR30Row)(const uint16_t* y_buf, const uint16_t* u_buf, - const uint16_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I210ToAR30Row_C; - if (!src_y || !src_u || !src_v || !dst_ar30 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_ar30 = dst_ar30 + (height - 1) * dst_stride_ar30; - dst_stride_ar30 = -dst_stride_ar30; - } -#if defined(HAS_I210TOAR30ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I210ToAR30Row = I210ToAR30Row_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I210ToAR30Row = I210ToAR30Row_SSSE3; - } - } -#endif -#if defined(HAS_I210TOAR30ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I210ToAR30Row = I210ToAR30Row_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I210ToAR30Row = I210ToAR30Row_AVX2; - } - } -#endif - for (y = 0; y < height; ++y) { - I210ToAR30Row(src_y, src_u, src_v, dst_ar30, yuvconstants, width); - dst_ar30 += dst_stride_ar30; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - return 0; -} - -// Convert I010 to AR30. -LIBYUV_API -int I010ToAR30(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_ar30, - int dst_stride_ar30, - int width, - int height) { - return I010ToAR30Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_ar30, dst_stride_ar30, - &kYuvI601Constants, width, height); -} - -// Convert H010 to AR30. -LIBYUV_API -int H010ToAR30(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_ar30, - int dst_stride_ar30, - int width, - int height) { - return I010ToAR30Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_ar30, dst_stride_ar30, - &kYuvH709Constants, width, height); -} - -// Convert I010 to AB30. -LIBYUV_API -int I010ToAB30(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_ab30, - int dst_stride_ab30, - int width, - int height) { - return I010ToAR30Matrix(src_y, src_stride_y, src_v, src_stride_v, src_u, - src_stride_u, dst_ab30, dst_stride_ab30, - &kYvuI601Constants, width, height); -} - -// Convert H010 to AB30. -LIBYUV_API -int H010ToAB30(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_ab30, - int dst_stride_ab30, - int width, - int height) { - return I010ToAR30Matrix(src_y, src_stride_y, src_v, src_stride_v, src_u, - src_stride_u, dst_ab30, dst_stride_ab30, - &kYvuH709Constants, width, height); -} - -// Convert 10 bit YUV to ARGB with matrix -static int I010ToARGBMatrix(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*I210ToARGBRow)(const uint16_t* y_buf, const uint16_t* u_buf, - const uint16_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I210ToARGBRow_C; - if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb = dst_argb + (height - 1) * dst_stride_argb; - dst_stride_argb = -dst_stride_argb; - } -#if defined(HAS_I210TOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I210ToARGBRow = I210ToARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I210ToARGBRow = I210ToARGBRow_SSSE3; - } - } -#endif -#if defined(HAS_I210TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I210ToARGBRow = I210ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I210ToARGBRow = I210ToARGBRow_AVX2; - } - } -#endif - for (y = 0; y < height; ++y) { - I210ToARGBRow(src_y, src_u, src_v, dst_argb, yuvconstants, width); - dst_argb += dst_stride_argb; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - return 0; -} - -// Convert I010 to ARGB. -LIBYUV_API -int I010ToARGB(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return I010ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_argb, dst_stride_argb, - &kYuvI601Constants, width, height); -} - -// Convert I010 to ABGR. -LIBYUV_API -int I010ToABGR(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - return I010ToARGBMatrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_abgr, dst_stride_abgr, - &kYvuI601Constants, // Use Yvu matrix - width, height); -} - -// Convert H010 to ARGB. -LIBYUV_API -int H010ToARGB(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return I010ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_argb, dst_stride_argb, - &kYuvH709Constants, width, height); -} - -// Convert H010 to ABGR. -LIBYUV_API -int H010ToABGR(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - return I010ToARGBMatrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_abgr, dst_stride_abgr, - &kYvuH709Constants, // Use Yvu matrix - width, height); -} - -// Convert I444 to ARGB with matrix -static int I444ToARGBMatrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*I444ToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I444ToARGBRow_C; - if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb = dst_argb + (height - 1) * dst_stride_argb; - dst_stride_argb = -dst_stride_argb; - } - // Coalesce rows. - if (src_stride_y == width && src_stride_u == width && src_stride_v == width && - dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0; - } -#if defined(HAS_I444TOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I444ToARGBRow = I444ToARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I444ToARGBRow = I444ToARGBRow_SSSE3; - } - } -#endif -#if defined(HAS_I444TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I444ToARGBRow = I444ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I444ToARGBRow = I444ToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_I444TOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I444ToARGBRow = I444ToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I444ToARGBRow = I444ToARGBRow_NEON; - } - } -#endif -#if defined(HAS_I444TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I444ToARGBRow = I444ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I444ToARGBRow = I444ToARGBRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - I444ToARGBRow(src_y, src_u, src_v, dst_argb, yuvconstants, width); - dst_argb += dst_stride_argb; - src_y += src_stride_y; - src_u += src_stride_u; - src_v += src_stride_v; - } - return 0; -} - -// Convert I444 to ARGB. -LIBYUV_API -int I444ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return I444ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_argb, dst_stride_argb, - &kYuvI601Constants, width, height); -} - -// Convert I444 to ABGR. -LIBYUV_API -int I444ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - return I444ToARGBMatrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_abgr, dst_stride_abgr, - &kYvuI601Constants, // Use Yvu matrix - width, height); -} - -// Convert J444 to ARGB. -LIBYUV_API -int J444ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return I444ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_argb, dst_stride_argb, - &kYuvJPEGConstants, width, height); -} - -// Convert I420 with Alpha to preattenuated ARGB. -static int I420AlphaToARGBMatrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - const uint8_t* src_a, - int src_stride_a, - uint8_t* dst_argb, - int dst_stride_argb, - const struct YuvConstants* yuvconstants, - int width, - int height, - int attenuate) { - int y; - void (*I422AlphaToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, const uint8_t* a_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) = I422AlphaToARGBRow_C; - void (*ARGBAttenuateRow)(const uint8_t* src_argb, uint8_t* dst_argb, - int width) = ARGBAttenuateRow_C; - if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb = dst_argb + (height - 1) * dst_stride_argb; - dst_stride_argb = -dst_stride_argb; - } -#if defined(HAS_I422ALPHATOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422AlphaToARGBRow = I422AlphaToARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422AlphaToARGBRow = I422AlphaToARGBRow_SSSE3; - } - } -#endif -#if defined(HAS_I422ALPHATOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422AlphaToARGBRow = I422AlphaToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422AlphaToARGBRow = I422AlphaToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_I422ALPHATOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422AlphaToARGBRow = I422AlphaToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422AlphaToARGBRow = I422AlphaToARGBRow_NEON; - } - } -#endif -#if defined(HAS_I422ALPHATOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422AlphaToARGBRow = I422AlphaToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422AlphaToARGBRow = I422AlphaToARGBRow_MSA; - } - } -#endif -#if defined(HAS_ARGBATTENUATEROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - ARGBAttenuateRow = ARGBAttenuateRow_Any_SSSE3; - if (IS_ALIGNED(width, 4)) { - ARGBAttenuateRow = ARGBAttenuateRow_SSSE3; - } - } -#endif -#if defined(HAS_ARGBATTENUATEROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBAttenuateRow = ARGBAttenuateRow_Any_AVX2; - if (IS_ALIGNED(width, 8)) { - ARGBAttenuateRow = ARGBAttenuateRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBATTENUATEROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBAttenuateRow = ARGBAttenuateRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBAttenuateRow = ARGBAttenuateRow_NEON; - } - } -#endif -#if defined(HAS_ARGBATTENUATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBAttenuateRow = ARGBAttenuateRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBAttenuateRow = ARGBAttenuateRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422AlphaToARGBRow(src_y, src_u, src_v, src_a, dst_argb, yuvconstants, - width); - if (attenuate) { - ARGBAttenuateRow(dst_argb, dst_argb, width); - } - dst_argb += dst_stride_argb; - src_a += src_stride_a; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - return 0; -} - -// Convert I420 with Alpha to ARGB. -LIBYUV_API -int I420AlphaToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - const uint8_t* src_a, - int src_stride_a, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height, - int attenuate) { - return I420AlphaToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, src_a, src_stride_a, dst_argb, - dst_stride_argb, &kYuvI601Constants, width, - height, attenuate); -} - -// Convert I420 with Alpha to ABGR. -LIBYUV_API -int I420AlphaToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - const uint8_t* src_a, - int src_stride_a, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height, - int attenuate) { - return I420AlphaToARGBMatrix( - src_y, src_stride_y, src_v, src_stride_v, // Swap U and V - src_u, src_stride_u, src_a, src_stride_a, dst_abgr, dst_stride_abgr, - &kYvuI601Constants, // Use Yvu matrix - width, height, attenuate); -} - -// Convert I400 to ARGB. -LIBYUV_API -int I400ToARGB(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*I400ToARGBRow)(const uint8_t* y_buf, uint8_t* rgb_buf, int width) = - I400ToARGBRow_C; - if (!src_y || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb = dst_argb + (height - 1) * dst_stride_argb; - dst_stride_argb = -dst_stride_argb; - } - // Coalesce rows. - if (src_stride_y == width && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_y = dst_stride_argb = 0; - } -#if defined(HAS_I400TOARGBROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - I400ToARGBRow = I400ToARGBRow_Any_SSE2; - if (IS_ALIGNED(width, 8)) { - I400ToARGBRow = I400ToARGBRow_SSE2; - } - } -#endif -#if defined(HAS_I400TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I400ToARGBRow = I400ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I400ToARGBRow = I400ToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_I400TOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I400ToARGBRow = I400ToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I400ToARGBRow = I400ToARGBRow_NEON; - } - } -#endif -#if defined(HAS_I400TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I400ToARGBRow = I400ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - I400ToARGBRow = I400ToARGBRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - I400ToARGBRow(src_y, dst_argb, width); - dst_argb += dst_stride_argb; - src_y += src_stride_y; - } - return 0; -} - -// Convert J400 to ARGB. -LIBYUV_API -int J400ToARGB(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*J400ToARGBRow)(const uint8_t* src_y, uint8_t* dst_argb, int width) = - J400ToARGBRow_C; - if (!src_y || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_y = src_y + (height - 1) * src_stride_y; - src_stride_y = -src_stride_y; - } - // Coalesce rows. - if (src_stride_y == width && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_y = dst_stride_argb = 0; - } -#if defined(HAS_J400TOARGBROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - J400ToARGBRow = J400ToARGBRow_Any_SSE2; - if (IS_ALIGNED(width, 8)) { - J400ToARGBRow = J400ToARGBRow_SSE2; - } - } -#endif -#if defined(HAS_J400TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - J400ToARGBRow = J400ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - J400ToARGBRow = J400ToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_J400TOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - J400ToARGBRow = J400ToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - J400ToARGBRow = J400ToARGBRow_NEON; - } - } -#endif -#if defined(HAS_J400TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - J400ToARGBRow = J400ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - J400ToARGBRow = J400ToARGBRow_MSA; - } - } -#endif - for (y = 0; y < height; ++y) { - J400ToARGBRow(src_y, dst_argb, width); - src_y += src_stride_y; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Shuffle table for converting BGRA to ARGB. -static const uvec8 kShuffleMaskBGRAToARGB = { - 3u, 2u, 1u, 0u, 7u, 6u, 5u, 4u, 11u, 10u, 9u, 8u, 15u, 14u, 13u, 12u}; - -// Shuffle table for converting ABGR to ARGB. -static const uvec8 kShuffleMaskABGRToARGB = { - 2u, 1u, 0u, 3u, 6u, 5u, 4u, 7u, 10u, 9u, 8u, 11u, 14u, 13u, 12u, 15u}; - -// Shuffle table for converting RGBA to ARGB. -static const uvec8 kShuffleMaskRGBAToARGB = { - 1u, 2u, 3u, 0u, 5u, 6u, 7u, 4u, 9u, 10u, 11u, 8u, 13u, 14u, 15u, 12u}; - -// Convert BGRA to ARGB. -LIBYUV_API -int BGRAToARGB(const uint8_t* src_bgra, - int src_stride_bgra, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return ARGBShuffle(src_bgra, src_stride_bgra, dst_argb, dst_stride_argb, - (const uint8_t*)(&kShuffleMaskBGRAToARGB), width, height); -} - -// Convert ARGB to BGRA (same as BGRAToARGB). -LIBYUV_API -int ARGBToBGRA(const uint8_t* src_bgra, - int src_stride_bgra, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return ARGBShuffle(src_bgra, src_stride_bgra, dst_argb, dst_stride_argb, - (const uint8_t*)(&kShuffleMaskBGRAToARGB), width, height); -} - -// Convert ABGR to ARGB. -LIBYUV_API -int ABGRToARGB(const uint8_t* src_abgr, - int src_stride_abgr, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return ARGBShuffle(src_abgr, src_stride_abgr, dst_argb, dst_stride_argb, - (const uint8_t*)(&kShuffleMaskABGRToARGB), width, height); -} - -// Convert ARGB to ABGR to (same as ABGRToARGB). -LIBYUV_API -int ARGBToABGR(const uint8_t* src_abgr, - int src_stride_abgr, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return ARGBShuffle(src_abgr, src_stride_abgr, dst_argb, dst_stride_argb, - (const uint8_t*)(&kShuffleMaskABGRToARGB), width, height); -} - -// Convert RGBA to ARGB. -LIBYUV_API -int RGBAToARGB(const uint8_t* src_rgba, - int src_stride_rgba, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return ARGBShuffle(src_rgba, src_stride_rgba, dst_argb, dst_stride_argb, - (const uint8_t*)(&kShuffleMaskRGBAToARGB), width, height); -} - -// Convert RGB24 to ARGB. -LIBYUV_API -int RGB24ToARGB(const uint8_t* src_rgb24, - int src_stride_rgb24, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*RGB24ToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, int width) = - RGB24ToARGBRow_C; - if (!src_rgb24 || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_rgb24 = src_rgb24 + (height - 1) * src_stride_rgb24; - src_stride_rgb24 = -src_stride_rgb24; - } - // Coalesce rows. - if (src_stride_rgb24 == width * 3 && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_rgb24 = dst_stride_argb = 0; - } -#if defined(HAS_RGB24TOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - RGB24ToARGBRow = RGB24ToARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - RGB24ToARGBRow = RGB24ToARGBRow_SSSE3; - } - } -#endif -#if defined(HAS_RGB24TOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - RGB24ToARGBRow = RGB24ToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - RGB24ToARGBRow = RGB24ToARGBRow_NEON; - } - } -#endif -#if defined(HAS_RGB24TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RGB24ToARGBRow = RGB24ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RGB24ToARGBRow = RGB24ToARGBRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - RGB24ToARGBRow(src_rgb24, dst_argb, width); - src_rgb24 += src_stride_rgb24; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Convert RAW to ARGB. -LIBYUV_API -int RAWToARGB(const uint8_t* src_raw, - int src_stride_raw, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*RAWToARGBRow)(const uint8_t* src_rgb, uint8_t* dst_argb, int width) = - RAWToARGBRow_C; - if (!src_raw || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_raw = src_raw + (height - 1) * src_stride_raw; - src_stride_raw = -src_stride_raw; - } - // Coalesce rows. - if (src_stride_raw == width * 3 && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_raw = dst_stride_argb = 0; - } -#if defined(HAS_RAWTOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - RAWToARGBRow = RAWToARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - RAWToARGBRow = RAWToARGBRow_SSSE3; - } - } -#endif -#if defined(HAS_RAWTOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - RAWToARGBRow = RAWToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - RAWToARGBRow = RAWToARGBRow_NEON; - } - } -#endif -#if defined(HAS_RAWTOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RAWToARGBRow = RAWToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RAWToARGBRow = RAWToARGBRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - RAWToARGBRow(src_raw, dst_argb, width); - src_raw += src_stride_raw; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Convert RGB565 to ARGB. -LIBYUV_API -int RGB565ToARGB(const uint8_t* src_rgb565, - int src_stride_rgb565, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*RGB565ToARGBRow)(const uint8_t* src_rgb565, uint8_t* dst_argb, - int width) = RGB565ToARGBRow_C; - if (!src_rgb565 || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_rgb565 = src_rgb565 + (height - 1) * src_stride_rgb565; - src_stride_rgb565 = -src_stride_rgb565; - } - // Coalesce rows. - if (src_stride_rgb565 == width * 2 && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_rgb565 = dst_stride_argb = 0; - } -#if defined(HAS_RGB565TOARGBROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - RGB565ToARGBRow = RGB565ToARGBRow_Any_SSE2; - if (IS_ALIGNED(width, 8)) { - RGB565ToARGBRow = RGB565ToARGBRow_SSE2; - } - } -#endif -#if defined(HAS_RGB565TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - RGB565ToARGBRow = RGB565ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - RGB565ToARGBRow = RGB565ToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_RGB565TOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - RGB565ToARGBRow = RGB565ToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - RGB565ToARGBRow = RGB565ToARGBRow_NEON; - } - } -#endif -#if defined(HAS_RGB565TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RGB565ToARGBRow = RGB565ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RGB565ToARGBRow = RGB565ToARGBRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - RGB565ToARGBRow(src_rgb565, dst_argb, width); - src_rgb565 += src_stride_rgb565; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Convert ARGB1555 to ARGB. -LIBYUV_API -int ARGB1555ToARGB(const uint8_t* src_argb1555, - int src_stride_argb1555, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*ARGB1555ToARGBRow)(const uint8_t* src_argb1555, uint8_t* dst_argb, - int width) = ARGB1555ToARGBRow_C; - if (!src_argb1555 || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_argb1555 = src_argb1555 + (height - 1) * src_stride_argb1555; - src_stride_argb1555 = -src_stride_argb1555; - } - // Coalesce rows. - if (src_stride_argb1555 == width * 2 && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_argb1555 = dst_stride_argb = 0; - } -#if defined(HAS_ARGB1555TOARGBROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_SSE2; - if (IS_ALIGNED(width, 8)) { - ARGB1555ToARGBRow = ARGB1555ToARGBRow_SSE2; - } - } -#endif -#if defined(HAS_ARGB1555TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - ARGB1555ToARGBRow = ARGB1555ToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_ARGB1555TOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGB1555ToARGBRow = ARGB1555ToARGBRow_NEON; - } - } -#endif -#if defined(HAS_ARGB1555TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGB1555ToARGBRow = ARGB1555ToARGBRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - ARGB1555ToARGBRow(src_argb1555, dst_argb, width); - src_argb1555 += src_stride_argb1555; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Convert ARGB4444 to ARGB. -LIBYUV_API -int ARGB4444ToARGB(const uint8_t* src_argb4444, - int src_stride_argb4444, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*ARGB4444ToARGBRow)(const uint8_t* src_argb4444, uint8_t* dst_argb, - int width) = ARGB4444ToARGBRow_C; - if (!src_argb4444 || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_argb4444 = src_argb4444 + (height - 1) * src_stride_argb4444; - src_stride_argb4444 = -src_stride_argb4444; - } - // Coalesce rows. - if (src_stride_argb4444 == width * 2 && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_argb4444 = dst_stride_argb = 0; - } -#if defined(HAS_ARGB4444TOARGBROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_SSE2; - if (IS_ALIGNED(width, 8)) { - ARGB4444ToARGBRow = ARGB4444ToARGBRow_SSE2; - } - } -#endif -#if defined(HAS_ARGB4444TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - ARGB4444ToARGBRow = ARGB4444ToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_ARGB4444TOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGB4444ToARGBRow = ARGB4444ToARGBRow_NEON; - } - } -#endif -#if defined(HAS_ARGB4444TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGB4444ToARGBRow = ARGB4444ToARGBRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - ARGB4444ToARGBRow(src_argb4444, dst_argb, width); - src_argb4444 += src_stride_argb4444; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Convert AR30 to ARGB. -LIBYUV_API -int AR30ToARGB(const uint8_t* src_ar30, - int src_stride_ar30, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - if (!src_ar30 || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_ar30 = src_ar30 + (height - 1) * src_stride_ar30; - src_stride_ar30 = -src_stride_ar30; - } - // Coalesce rows. - if (src_stride_ar30 == width * 4 && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_ar30 = dst_stride_argb = 0; - } - for (y = 0; y < height; ++y) { - AR30ToARGBRow_C(src_ar30, dst_argb, width); - src_ar30 += src_stride_ar30; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Convert AR30 to ABGR. -LIBYUV_API -int AR30ToABGR(const uint8_t* src_ar30, - int src_stride_ar30, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - int y; - if (!src_ar30 || !dst_abgr || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_ar30 = src_ar30 + (height - 1) * src_stride_ar30; - src_stride_ar30 = -src_stride_ar30; - } - // Coalesce rows. - if (src_stride_ar30 == width * 4 && dst_stride_abgr == width * 4) { - width *= height; - height = 1; - src_stride_ar30 = dst_stride_abgr = 0; - } - for (y = 0; y < height; ++y) { - AR30ToABGRRow_C(src_ar30, dst_abgr, width); - src_ar30 += src_stride_ar30; - dst_abgr += dst_stride_abgr; - } - return 0; -} - -// Convert AR30 to AB30. -LIBYUV_API -int AR30ToAB30(const uint8_t* src_ar30, - int src_stride_ar30, - uint8_t* dst_ab30, - int dst_stride_ab30, - int width, - int height) { - int y; - if (!src_ar30 || !dst_ab30 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_ar30 = src_ar30 + (height - 1) * src_stride_ar30; - src_stride_ar30 = -src_stride_ar30; - } - // Coalesce rows. - if (src_stride_ar30 == width * 4 && dst_stride_ab30 == width * 4) { - width *= height; - height = 1; - src_stride_ar30 = dst_stride_ab30 = 0; - } - for (y = 0; y < height; ++y) { - AR30ToAB30Row_C(src_ar30, dst_ab30, width); - src_ar30 += src_stride_ar30; - dst_ab30 += dst_stride_ab30; - } - return 0; -} - -// Convert NV12 to ARGB with matrix -static int NV12ToARGBMatrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_argb, - int dst_stride_argb, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*NV12ToARGBRow)( - const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = NV12ToARGBRow_C; - if (!src_y || !src_uv || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb = dst_argb + (height - 1) * dst_stride_argb; - dst_stride_argb = -dst_stride_argb; - } -#if defined(HAS_NV12TOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - NV12ToARGBRow = NV12ToARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - NV12ToARGBRow = NV12ToARGBRow_SSSE3; - } - } -#endif -#if defined(HAS_NV12TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - NV12ToARGBRow = NV12ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - NV12ToARGBRow = NV12ToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_NV12TOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - NV12ToARGBRow = NV12ToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - NV12ToARGBRow = NV12ToARGBRow_NEON; - } - } -#endif -#if defined(HAS_NV12TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - NV12ToARGBRow = NV12ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - NV12ToARGBRow = NV12ToARGBRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - NV12ToARGBRow(src_y, src_uv, dst_argb, yuvconstants, width); - dst_argb += dst_stride_argb; - src_y += src_stride_y; - if (y & 1) { - src_uv += src_stride_uv; - } - } - return 0; -} - -// Convert NV21 to ARGB with matrix -static int NV21ToARGBMatrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_vu, - int src_stride_vu, - uint8_t* dst_argb, - int dst_stride_argb, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*NV21ToARGBRow)( - const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = NV21ToARGBRow_C; - if (!src_y || !src_vu || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb = dst_argb + (height - 1) * dst_stride_argb; - dst_stride_argb = -dst_stride_argb; - } -#if defined(HAS_NV21TOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - NV21ToARGBRow = NV21ToARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - NV21ToARGBRow = NV21ToARGBRow_SSSE3; - } - } -#endif -#if defined(HAS_NV21TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - NV21ToARGBRow = NV21ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - NV21ToARGBRow = NV21ToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_NV21TOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - NV21ToARGBRow = NV21ToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - NV21ToARGBRow = NV21ToARGBRow_NEON; - } - } -#endif -#if defined(HAS_NV21TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - NV21ToARGBRow = NV21ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - NV21ToARGBRow = NV21ToARGBRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - NV21ToARGBRow(src_y, src_vu, dst_argb, yuvconstants, width); - dst_argb += dst_stride_argb; - src_y += src_stride_y; - if (y & 1) { - src_vu += src_stride_vu; - } - } - return 0; -} - -// Convert NV12 to ARGB. -LIBYUV_API -int NV12ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return NV12ToARGBMatrix(src_y, src_stride_y, src_uv, src_stride_uv, dst_argb, - dst_stride_argb, &kYuvI601Constants, width, height); -} - -// Convert NV21 to ARGB. -LIBYUV_API -int NV21ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_vu, - int src_stride_vu, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return NV21ToARGBMatrix(src_y, src_stride_y, src_vu, src_stride_vu, dst_argb, - dst_stride_argb, &kYuvI601Constants, width, height); -} - -// Convert NV12 to ABGR. -// To output ABGR instead of ARGB swap the UV and use a mirrrored yuc matrix. -// To swap the UV use NV12 instead of NV21.LIBYUV_API -int NV12ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - return NV21ToARGBMatrix(src_y, src_stride_y, src_uv, src_stride_uv, dst_abgr, - dst_stride_abgr, &kYvuI601Constants, width, height); -} - -// Convert NV21 to ABGR. -LIBYUV_API -int NV21ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_vu, - int src_stride_vu, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - return NV12ToARGBMatrix(src_y, src_stride_y, src_vu, src_stride_vu, dst_abgr, - dst_stride_abgr, &kYvuI601Constants, width, height); -} - -// TODO(fbarchard): Consider SSSE3 2 step conversion. -// Convert NV12 to RGB24 with matrix -static int NV12ToRGB24Matrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*NV12ToRGB24Row)( - const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = NV12ToRGB24Row_C; - if (!src_y || !src_uv || !dst_rgb24 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_rgb24 = dst_rgb24 + (height - 1) * dst_stride_rgb24; - dst_stride_rgb24 = -dst_stride_rgb24; - } -#if defined(HAS_NV12TORGB24ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - NV12ToRGB24Row = NV12ToRGB24Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - NV12ToRGB24Row = NV12ToRGB24Row_NEON; - } - } -#endif -#if defined(HAS_NV12TORGB24ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - NV12ToRGB24Row = NV12ToRGB24Row_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - NV12ToRGB24Row = NV12ToRGB24Row_SSSE3; - } - } -#endif -#if defined(HAS_NV12TORGB24ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - NV12ToRGB24Row = NV12ToRGB24Row_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - NV12ToRGB24Row = NV12ToRGB24Row_AVX2; - } - } -#endif - - for (y = 0; y < height; ++y) { - NV12ToRGB24Row(src_y, src_uv, dst_rgb24, yuvconstants, width); - dst_rgb24 += dst_stride_rgb24; - src_y += src_stride_y; - if (y & 1) { - src_uv += src_stride_uv; - } - } - return 0; -} - -// Convert NV21 to RGB24 with matrix -static int NV21ToRGB24Matrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_vu, - int src_stride_vu, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*NV21ToRGB24Row)( - const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = NV21ToRGB24Row_C; - if (!src_y || !src_vu || !dst_rgb24 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_rgb24 = dst_rgb24 + (height - 1) * dst_stride_rgb24; - dst_stride_rgb24 = -dst_stride_rgb24; - } -#if defined(HAS_NV21TORGB24ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - NV21ToRGB24Row = NV21ToRGB24Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - NV21ToRGB24Row = NV21ToRGB24Row_NEON; - } - } -#endif -#if defined(HAS_NV21TORGB24ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - NV21ToRGB24Row = NV21ToRGB24Row_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - NV21ToRGB24Row = NV21ToRGB24Row_SSSE3; - } - } -#endif -#if defined(HAS_NV21TORGB24ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - NV21ToRGB24Row = NV21ToRGB24Row_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - NV21ToRGB24Row = NV21ToRGB24Row_AVX2; - } - } -#endif - - for (y = 0; y < height; ++y) { - NV21ToRGB24Row(src_y, src_vu, dst_rgb24, yuvconstants, width); - dst_rgb24 += dst_stride_rgb24; - src_y += src_stride_y; - if (y & 1) { - src_vu += src_stride_vu; - } - } - return 0; -} - -// TODO(fbarchard): NV12ToRAW can be implemented by mirrored matrix. -// Convert NV12 to RGB24. -LIBYUV_API -int NV12ToRGB24(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height) { - return NV12ToRGB24Matrix(src_y, src_stride_y, src_uv, src_stride_uv, - dst_rgb24, dst_stride_rgb24, &kYuvI601Constants, - width, height); -} - -// Convert NV21 to RGB24. -LIBYUV_API -int NV21ToRGB24(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_vu, - int src_stride_vu, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height) { - return NV21ToRGB24Matrix(src_y, src_stride_y, src_vu, src_stride_vu, - dst_rgb24, dst_stride_rgb24, &kYuvI601Constants, - width, height); -} - -// Convert M420 to ARGB. -LIBYUV_API -int M420ToARGB(const uint8_t* src_m420, - int src_stride_m420, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*NV12ToARGBRow)( - const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = NV12ToARGBRow_C; - if (!src_m420 || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb = dst_argb + (height - 1) * dst_stride_argb; - dst_stride_argb = -dst_stride_argb; - } -#if defined(HAS_NV12TOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - NV12ToARGBRow = NV12ToARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - NV12ToARGBRow = NV12ToARGBRow_SSSE3; - } - } -#endif -#if defined(HAS_NV12TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - NV12ToARGBRow = NV12ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - NV12ToARGBRow = NV12ToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_NV12TOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - NV12ToARGBRow = NV12ToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - NV12ToARGBRow = NV12ToARGBRow_NEON; - } - } -#endif -#if defined(HAS_NV12TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - NV12ToARGBRow = NV12ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - NV12ToARGBRow = NV12ToARGBRow_MSA; - } - } -#endif - - for (y = 0; y < height - 1; y += 2) { - NV12ToARGBRow(src_m420, src_m420 + src_stride_m420 * 2, dst_argb, - &kYuvI601Constants, width); - NV12ToARGBRow(src_m420 + src_stride_m420, src_m420 + src_stride_m420 * 2, - dst_argb + dst_stride_argb, &kYuvI601Constants, width); - dst_argb += dst_stride_argb * 2; - src_m420 += src_stride_m420 * 3; - } - if (height & 1) { - NV12ToARGBRow(src_m420, src_m420 + src_stride_m420 * 2, dst_argb, - &kYuvI601Constants, width); - } - return 0; -} - -// Convert YUY2 to ARGB. -LIBYUV_API -int YUY2ToARGB(const uint8_t* src_yuy2, - int src_stride_yuy2, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*YUY2ToARGBRow)(const uint8_t* src_yuy2, uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, int width) = - YUY2ToARGBRow_C; - if (!src_yuy2 || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2; - src_stride_yuy2 = -src_stride_yuy2; - } - // Coalesce rows. - if (src_stride_yuy2 == width * 2 && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_yuy2 = dst_stride_argb = 0; - } -#if defined(HAS_YUY2TOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - YUY2ToARGBRow = YUY2ToARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - YUY2ToARGBRow = YUY2ToARGBRow_SSSE3; - } - } -#endif -#if defined(HAS_YUY2TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - YUY2ToARGBRow = YUY2ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - YUY2ToARGBRow = YUY2ToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_YUY2TOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - YUY2ToARGBRow = YUY2ToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - YUY2ToARGBRow = YUY2ToARGBRow_NEON; - } - } -#endif -#if defined(HAS_YUY2TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - YUY2ToARGBRow = YUY2ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - YUY2ToARGBRow = YUY2ToARGBRow_MSA; - } - } -#endif - for (y = 0; y < height; ++y) { - YUY2ToARGBRow(src_yuy2, dst_argb, &kYuvI601Constants, width); - src_yuy2 += src_stride_yuy2; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Convert UYVY to ARGB. -LIBYUV_API -int UYVYToARGB(const uint8_t* src_uyvy, - int src_stride_uyvy, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*UYVYToARGBRow)(const uint8_t* src_uyvy, uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, int width) = - UYVYToARGBRow_C; - if (!src_uyvy || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy; - src_stride_uyvy = -src_stride_uyvy; - } - // Coalesce rows. - if (src_stride_uyvy == width * 2 && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_uyvy = dst_stride_argb = 0; - } -#if defined(HAS_UYVYTOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - UYVYToARGBRow = UYVYToARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - UYVYToARGBRow = UYVYToARGBRow_SSSE3; - } - } -#endif -#if defined(HAS_UYVYTOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - UYVYToARGBRow = UYVYToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - UYVYToARGBRow = UYVYToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_UYVYTOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - UYVYToARGBRow = UYVYToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - UYVYToARGBRow = UYVYToARGBRow_NEON; - } - } -#endif -#if defined(HAS_UYVYTOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - UYVYToARGBRow = UYVYToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - UYVYToARGBRow = UYVYToARGBRow_MSA; - } - } -#endif - for (y = 0; y < height; ++y) { - UYVYToARGBRow(src_uyvy, dst_argb, &kYuvI601Constants, width); - src_uyvy += src_stride_uyvy; - dst_argb += dst_stride_argb; - } - return 0; -} -static void WeavePixels(const uint8_t* src_u, - const uint8_t* src_v, - int src_pixel_stride_uv, - uint8_t* dst_uv, - int width) { - int i; - for (i = 0; i < width; ++i) { - dst_uv[0] = *src_u; - dst_uv[1] = *src_v; - dst_uv += 2; - src_u += src_pixel_stride_uv; - src_v += src_pixel_stride_uv; - } -} - -// Convert Android420 to ARGB. -LIBYUV_API -int Android420ToARGBMatrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - int src_pixel_stride_uv, - uint8_t* dst_argb, - int dst_stride_argb, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - uint8_t* dst_uv; - const ptrdiff_t vu_off = src_v - src_u; - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - if (!src_y || !src_u || !src_v || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - halfheight = (height + 1) >> 1; - dst_argb = dst_argb + (height - 1) * dst_stride_argb; - dst_stride_argb = -dst_stride_argb; - } - - // I420 - if (src_pixel_stride_uv == 1) { - return I420ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_argb, dst_stride_argb, - yuvconstants, width, height); - // NV21 - } - if (src_pixel_stride_uv == 2 && vu_off == -1 && - src_stride_u == src_stride_v) { - return NV21ToARGBMatrix(src_y, src_stride_y, src_v, src_stride_v, dst_argb, - dst_stride_argb, yuvconstants, width, height); - // NV12 - } - if (src_pixel_stride_uv == 2 && vu_off == 1 && src_stride_u == src_stride_v) { - return NV12ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, dst_argb, - dst_stride_argb, yuvconstants, width, height); - } - - // General case fallback creates NV12 - align_buffer_64(plane_uv, halfwidth * 2 * halfheight); - dst_uv = plane_uv; - for (y = 0; y < halfheight; ++y) { - WeavePixels(src_u, src_v, src_pixel_stride_uv, dst_uv, halfwidth); - src_u += src_stride_u; - src_v += src_stride_v; - dst_uv += halfwidth * 2; - } - NV12ToARGBMatrix(src_y, src_stride_y, plane_uv, halfwidth * 2, dst_argb, - dst_stride_argb, yuvconstants, width, height); - free_aligned_buffer_64(plane_uv); - return 0; -} - -// Convert Android420 to ARGB. -LIBYUV_API -int Android420ToARGB(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - int src_pixel_stride_uv, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - return Android420ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, src_pixel_stride_uv, dst_argb, - dst_stride_argb, &kYuvI601Constants, width, - height); -} - -// Convert Android420 to ABGR. -LIBYUV_API -int Android420ToABGR(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - int src_pixel_stride_uv, - uint8_t* dst_abgr, - int dst_stride_abgr, - int width, - int height) { - return Android420ToARGBMatrix(src_y, src_stride_y, src_v, src_stride_v, src_u, - src_stride_u, src_pixel_stride_uv, dst_abgr, - dst_stride_abgr, &kYvuI601Constants, width, - height); -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_from.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_from.cc deleted file mode 100644 index 6fa25323..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_from.cc +++ /dev/null @@ -1,1429 +0,0 @@ -/* - * Copyright 2012 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/convert_from.h" - -#include "libyuv/basic_types.h" -#include "libyuv/convert.h" // For I420Copy -#include "libyuv/cpu_id.h" -#include "libyuv/planar_functions.h" -#include "libyuv/rotate.h" -#include "libyuv/row.h" -#include "libyuv/scale.h" // For ScalePlane() -#include "libyuv/video_common.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -#define SUBSAMPLE(v, a, s) (v < 0) ? (-((-v + a) >> s)) : ((v + a) >> s) -static __inline int Abs(int v) { - return v >= 0 ? v : -v; -} - -// I420 To any I4xx YUV format with mirroring. -static int I420ToI4xx(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int src_y_width, - int src_y_height, - int dst_uv_width, - int dst_uv_height) { - const int dst_y_width = Abs(src_y_width); - const int dst_y_height = Abs(src_y_height); - const int src_uv_width = SUBSAMPLE(src_y_width, 1, 1); - const int src_uv_height = SUBSAMPLE(src_y_height, 1, 1); - if (src_y_width == 0 || src_y_height == 0 || dst_uv_width <= 0 || - dst_uv_height <= 0) { - return -1; - } - if (dst_y) { - ScalePlane(src_y, src_stride_y, src_y_width, src_y_height, dst_y, - dst_stride_y, dst_y_width, dst_y_height, kFilterBilinear); - } - ScalePlane(src_u, src_stride_u, src_uv_width, src_uv_height, dst_u, - dst_stride_u, dst_uv_width, dst_uv_height, kFilterBilinear); - ScalePlane(src_v, src_stride_v, src_uv_width, src_uv_height, dst_v, - dst_stride_v, dst_uv_width, dst_uv_height, kFilterBilinear); - return 0; -} - -// Convert 8 bit YUV to 10 bit. -LIBYUV_API -int I420ToI010(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint16_t* dst_y, - int dst_stride_y, - uint16_t* dst_u, - int dst_stride_u, - uint16_t* dst_v, - int dst_stride_v, - int width, - int height) { - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - if (!src_u || !src_v || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - halfheight = (height + 1) >> 1; - src_y = src_y + (height - 1) * src_stride_y; - src_u = src_u + (halfheight - 1) * src_stride_u; - src_v = src_v + (halfheight - 1) * src_stride_v; - src_stride_y = -src_stride_y; - src_stride_u = -src_stride_u; - src_stride_v = -src_stride_v; - } - - // Convert Y plane. - Convert8To16Plane(src_y, src_stride_y, dst_y, dst_stride_y, 1024, width, - height); - // Convert UV planes. - Convert8To16Plane(src_u, src_stride_u, dst_u, dst_stride_u, 1024, halfwidth, - halfheight); - Convert8To16Plane(src_v, src_stride_v, dst_v, dst_stride_v, 1024, halfwidth, - halfheight); - return 0; -} - -// 420 chroma is 1/2 width, 1/2 height -// 422 chroma is 1/2 width, 1x height -LIBYUV_API -int I420ToI422(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - const int dst_uv_width = (Abs(width) + 1) >> 1; - const int dst_uv_height = Abs(height); - return I420ToI4xx(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u, - dst_v, dst_stride_v, width, height, dst_uv_width, - dst_uv_height); -} - -// 420 chroma is 1/2 width, 1/2 height -// 444 chroma is 1x width, 1x height -LIBYUV_API -int I420ToI444(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - const int dst_uv_width = Abs(width); - const int dst_uv_height = Abs(height); - return I420ToI4xx(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u, - dst_v, dst_stride_v, width, height, dst_uv_width, - dst_uv_height); -} - -// Copy to I400. Source can be I420,422,444,400,NV12,NV21 -LIBYUV_API -int I400Copy(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height) { - if (!src_y || !dst_y || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_y = src_y + (height - 1) * src_stride_y; - src_stride_y = -src_stride_y; - } - CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - return 0; -} - -LIBYUV_API -int I422ToYUY2(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_yuy2, - int dst_stride_yuy2, - int width, - int height) { - int y; - void (*I422ToYUY2Row)(const uint8_t* src_y, const uint8_t* src_u, - const uint8_t* src_v, uint8_t* dst_yuy2, int width) = - I422ToYUY2Row_C; - if (!src_y || !src_u || !src_v || !dst_yuy2 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_yuy2 = dst_yuy2 + (height - 1) * dst_stride_yuy2; - dst_stride_yuy2 = -dst_stride_yuy2; - } - // Coalesce rows. - if (src_stride_y == width && src_stride_u * 2 == width && - src_stride_v * 2 == width && dst_stride_yuy2 == width * 2) { - width *= height; - height = 1; - src_stride_y = src_stride_u = src_stride_v = dst_stride_yuy2 = 0; - } -#if defined(HAS_I422TOYUY2ROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - I422ToYUY2Row = I422ToYUY2Row_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - I422ToYUY2Row = I422ToYUY2Row_SSE2; - } - } -#endif -#if defined(HAS_I422TOYUY2ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToYUY2Row = I422ToYUY2Row_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - I422ToYUY2Row = I422ToYUY2Row_AVX2; - } - } -#endif -#if defined(HAS_I422TOYUY2ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToYUY2Row = I422ToYUY2Row_Any_NEON; - if (IS_ALIGNED(width, 16)) { - I422ToYUY2Row = I422ToYUY2Row_NEON; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToYUY2Row(src_y, src_u, src_v, dst_yuy2, width); - src_y += src_stride_y; - src_u += src_stride_u; - src_v += src_stride_v; - dst_yuy2 += dst_stride_yuy2; - } - return 0; -} - -LIBYUV_API -int I420ToYUY2(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_yuy2, - int dst_stride_yuy2, - int width, - int height) { - int y; - void (*I422ToYUY2Row)(const uint8_t* src_y, const uint8_t* src_u, - const uint8_t* src_v, uint8_t* dst_yuy2, int width) = - I422ToYUY2Row_C; - if (!src_y || !src_u || !src_v || !dst_yuy2 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_yuy2 = dst_yuy2 + (height - 1) * dst_stride_yuy2; - dst_stride_yuy2 = -dst_stride_yuy2; - } -#if defined(HAS_I422TOYUY2ROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - I422ToYUY2Row = I422ToYUY2Row_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - I422ToYUY2Row = I422ToYUY2Row_SSE2; - } - } -#endif -#if defined(HAS_I422TOYUY2ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToYUY2Row = I422ToYUY2Row_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - I422ToYUY2Row = I422ToYUY2Row_AVX2; - } - } -#endif -#if defined(HAS_I422TOYUY2ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToYUY2Row = I422ToYUY2Row_Any_NEON; - if (IS_ALIGNED(width, 16)) { - I422ToYUY2Row = I422ToYUY2Row_NEON; - } - } -#endif -#if defined(HAS_I422TOYUY2ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToYUY2Row = I422ToYUY2Row_Any_MSA; - if (IS_ALIGNED(width, 32)) { - I422ToYUY2Row = I422ToYUY2Row_MSA; - } - } -#endif - - for (y = 0; y < height - 1; y += 2) { - I422ToYUY2Row(src_y, src_u, src_v, dst_yuy2, width); - I422ToYUY2Row(src_y + src_stride_y, src_u, src_v, - dst_yuy2 + dst_stride_yuy2, width); - src_y += src_stride_y * 2; - src_u += src_stride_u; - src_v += src_stride_v; - dst_yuy2 += dst_stride_yuy2 * 2; - } - if (height & 1) { - I422ToYUY2Row(src_y, src_u, src_v, dst_yuy2, width); - } - return 0; -} - -LIBYUV_API -int I422ToUYVY(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_uyvy, - int dst_stride_uyvy, - int width, - int height) { - int y; - void (*I422ToUYVYRow)(const uint8_t* src_y, const uint8_t* src_u, - const uint8_t* src_v, uint8_t* dst_uyvy, int width) = - I422ToUYVYRow_C; - if (!src_y || !src_u || !src_v || !dst_uyvy || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_uyvy = dst_uyvy + (height - 1) * dst_stride_uyvy; - dst_stride_uyvy = -dst_stride_uyvy; - } - // Coalesce rows. - if (src_stride_y == width && src_stride_u * 2 == width && - src_stride_v * 2 == width && dst_stride_uyvy == width * 2) { - width *= height; - height = 1; - src_stride_y = src_stride_u = src_stride_v = dst_stride_uyvy = 0; - } -#if defined(HAS_I422TOUYVYROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - I422ToUYVYRow = I422ToUYVYRow_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - I422ToUYVYRow = I422ToUYVYRow_SSE2; - } - } -#endif -#if defined(HAS_I422TOUYVYROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToUYVYRow = I422ToUYVYRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - I422ToUYVYRow = I422ToUYVYRow_AVX2; - } - } -#endif -#if defined(HAS_I422TOUYVYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToUYVYRow = I422ToUYVYRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - I422ToUYVYRow = I422ToUYVYRow_NEON; - } - } -#endif -#if defined(HAS_I422TOUYVYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToUYVYRow = I422ToUYVYRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - I422ToUYVYRow = I422ToUYVYRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToUYVYRow(src_y, src_u, src_v, dst_uyvy, width); - src_y += src_stride_y; - src_u += src_stride_u; - src_v += src_stride_v; - dst_uyvy += dst_stride_uyvy; - } - return 0; -} - -LIBYUV_API -int I420ToUYVY(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_uyvy, - int dst_stride_uyvy, - int width, - int height) { - int y; - void (*I422ToUYVYRow)(const uint8_t* src_y, const uint8_t* src_u, - const uint8_t* src_v, uint8_t* dst_uyvy, int width) = - I422ToUYVYRow_C; - if (!src_y || !src_u || !src_v || !dst_uyvy || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_uyvy = dst_uyvy + (height - 1) * dst_stride_uyvy; - dst_stride_uyvy = -dst_stride_uyvy; - } -#if defined(HAS_I422TOUYVYROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - I422ToUYVYRow = I422ToUYVYRow_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - I422ToUYVYRow = I422ToUYVYRow_SSE2; - } - } -#endif -#if defined(HAS_I422TOUYVYROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToUYVYRow = I422ToUYVYRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - I422ToUYVYRow = I422ToUYVYRow_AVX2; - } - } -#endif -#if defined(HAS_I422TOUYVYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToUYVYRow = I422ToUYVYRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - I422ToUYVYRow = I422ToUYVYRow_NEON; - } - } -#endif -#if defined(HAS_I422TOUYVYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToUYVYRow = I422ToUYVYRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - I422ToUYVYRow = I422ToUYVYRow_MSA; - } - } -#endif - - for (y = 0; y < height - 1; y += 2) { - I422ToUYVYRow(src_y, src_u, src_v, dst_uyvy, width); - I422ToUYVYRow(src_y + src_stride_y, src_u, src_v, - dst_uyvy + dst_stride_uyvy, width); - src_y += src_stride_y * 2; - src_u += src_stride_u; - src_v += src_stride_v; - dst_uyvy += dst_stride_uyvy * 2; - } - if (height & 1) { - I422ToUYVYRow(src_y, src_u, src_v, dst_uyvy, width); - } - return 0; -} - -// TODO(fbarchard): test negative height for invert. -LIBYUV_API -int I420ToNV12(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_uv, - int dst_stride_uv, - int width, - int height) { - if (!src_y || !src_u || !src_v || !dst_y || !dst_uv || width <= 0 || - height == 0) { - return -1; - } - int halfwidth = (width + 1) / 2; - int halfheight = height > 0 ? (height + 1) / 2 : (height - 1) / 2; - if (dst_y) { - CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - } - MergeUVPlane(src_u, src_stride_u, src_v, src_stride_v, dst_uv, dst_stride_uv, - halfwidth, halfheight); - return 0; -} - -LIBYUV_API -int I420ToNV21(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_vu, - int dst_stride_vu, - int width, - int height) { - return I420ToNV12(src_y, src_stride_y, src_v, src_stride_v, src_u, - src_stride_u, dst_y, dst_stride_y, dst_vu, dst_stride_vu, - width, height); -} - -// Convert I422 to RGBA with matrix -static int I420ToRGBAMatrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgba, - int dst_stride_rgba, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*I422ToRGBARow)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I422ToRGBARow_C; - if (!src_y || !src_u || !src_v || !dst_rgba || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_rgba = dst_rgba + (height - 1) * dst_stride_rgba; - dst_stride_rgba = -dst_stride_rgba; - } -#if defined(HAS_I422TORGBAROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToRGBARow = I422ToRGBARow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToRGBARow = I422ToRGBARow_SSSE3; - } - } -#endif -#if defined(HAS_I422TORGBAROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToRGBARow = I422ToRGBARow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToRGBARow = I422ToRGBARow_AVX2; - } - } -#endif -#if defined(HAS_I422TORGBAROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToRGBARow = I422ToRGBARow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToRGBARow = I422ToRGBARow_NEON; - } - } -#endif -#if defined(HAS_I422TORGBAROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToRGBARow = I422ToRGBARow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToRGBARow = I422ToRGBARow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToRGBARow(src_y, src_u, src_v, dst_rgba, yuvconstants, width); - dst_rgba += dst_stride_rgba; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - return 0; -} - -// Convert I420 to RGBA. -LIBYUV_API -int I420ToRGBA(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgba, - int dst_stride_rgba, - int width, - int height) { - return I420ToRGBAMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_rgba, dst_stride_rgba, - &kYuvI601Constants, width, height); -} - -// Convert I420 to BGRA. -LIBYUV_API -int I420ToBGRA(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_bgra, - int dst_stride_bgra, - int width, - int height) { - return I420ToRGBAMatrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_bgra, dst_stride_bgra, - &kYvuI601Constants, // Use Yvu matrix - width, height); -} - -// Convert I420 to RGB24 with matrix -static int I420ToRGB24Matrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*I422ToRGB24Row)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I422ToRGB24Row_C; - if (!src_y || !src_u || !src_v || !dst_rgb24 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_rgb24 = dst_rgb24 + (height - 1) * dst_stride_rgb24; - dst_stride_rgb24 = -dst_stride_rgb24; - } -#if defined(HAS_I422TORGB24ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToRGB24Row = I422ToRGB24Row_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToRGB24Row = I422ToRGB24Row_SSSE3; - } - } -#endif -#if defined(HAS_I422TORGB24ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToRGB24Row = I422ToRGB24Row_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToRGB24Row = I422ToRGB24Row_AVX2; - } - } -#endif -#if defined(HAS_I422TORGB24ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToRGB24Row = I422ToRGB24Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToRGB24Row = I422ToRGB24Row_NEON; - } - } -#endif -#if defined(HAS_I422TORGB24ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToRGB24Row = I422ToRGB24Row_Any_MSA; - if (IS_ALIGNED(width, 16)) { - I422ToRGB24Row = I422ToRGB24Row_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToRGB24Row(src_y, src_u, src_v, dst_rgb24, yuvconstants, width); - dst_rgb24 += dst_stride_rgb24; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - return 0; -} - -// Convert I420 to RGB24. -LIBYUV_API -int I420ToRGB24(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height) { - return I420ToRGB24Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_rgb24, dst_stride_rgb24, - &kYuvI601Constants, width, height); -} - -// Convert I420 to RAW. -LIBYUV_API -int I420ToRAW(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_raw, - int dst_stride_raw, - int width, - int height) { - return I420ToRGB24Matrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_raw, dst_stride_raw, - &kYvuI601Constants, // Use Yvu matrix - width, height); -} - -// Convert H420 to RGB24. -LIBYUV_API -int H420ToRGB24(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height) { - return I420ToRGB24Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_rgb24, dst_stride_rgb24, - &kYuvH709Constants, width, height); -} - -// Convert H420 to RAW. -LIBYUV_API -int H420ToRAW(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_raw, - int dst_stride_raw, - int width, - int height) { - return I420ToRGB24Matrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_raw, dst_stride_raw, - &kYvuH709Constants, // Use Yvu matrix - width, height); -} - -// Convert I420 to ARGB1555. -LIBYUV_API -int I420ToARGB1555(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb1555, - int dst_stride_argb1555, - int width, - int height) { - int y; - void (*I422ToARGB1555Row)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) = I422ToARGB1555Row_C; - if (!src_y || !src_u || !src_v || !dst_argb1555 || width <= 0 || - height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb1555 = dst_argb1555 + (height - 1) * dst_stride_argb1555; - dst_stride_argb1555 = -dst_stride_argb1555; - } -#if defined(HAS_I422TOARGB1555ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToARGB1555Row = I422ToARGB1555Row_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToARGB1555Row = I422ToARGB1555Row_SSSE3; - } - } -#endif -#if defined(HAS_I422TOARGB1555ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToARGB1555Row = I422ToARGB1555Row_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToARGB1555Row = I422ToARGB1555Row_AVX2; - } - } -#endif -#if defined(HAS_I422TOARGB1555ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToARGB1555Row = I422ToARGB1555Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToARGB1555Row = I422ToARGB1555Row_NEON; - } - } -#endif -#if defined(HAS_I422TOARGB1555ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToARGB1555Row = I422ToARGB1555Row_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToARGB1555Row = I422ToARGB1555Row_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToARGB1555Row(src_y, src_u, src_v, dst_argb1555, &kYuvI601Constants, - width); - dst_argb1555 += dst_stride_argb1555; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - return 0; -} - -// Convert I420 to ARGB4444. -LIBYUV_API -int I420ToARGB4444(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_argb4444, - int dst_stride_argb4444, - int width, - int height) { - int y; - void (*I422ToARGB4444Row)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) = I422ToARGB4444Row_C; - if (!src_y || !src_u || !src_v || !dst_argb4444 || width <= 0 || - height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb4444 = dst_argb4444 + (height - 1) * dst_stride_argb4444; - dst_stride_argb4444 = -dst_stride_argb4444; - } -#if defined(HAS_I422TOARGB4444ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToARGB4444Row = I422ToARGB4444Row_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToARGB4444Row = I422ToARGB4444Row_SSSE3; - } - } -#endif -#if defined(HAS_I422TOARGB4444ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToARGB4444Row = I422ToARGB4444Row_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToARGB4444Row = I422ToARGB4444Row_AVX2; - } - } -#endif -#if defined(HAS_I422TOARGB4444ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToARGB4444Row = I422ToARGB4444Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToARGB4444Row = I422ToARGB4444Row_NEON; - } - } -#endif -#if defined(HAS_I422TOARGB4444ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToARGB4444Row = I422ToARGB4444Row_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToARGB4444Row = I422ToARGB4444Row_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToARGB4444Row(src_y, src_u, src_v, dst_argb4444, &kYuvI601Constants, - width); - dst_argb4444 += dst_stride_argb4444; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - return 0; -} - -// Convert I420 to RGB565. -LIBYUV_API -int I420ToRGB565(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - int width, - int height) { - int y; - void (*I422ToRGB565Row)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I422ToRGB565Row_C; - if (!src_y || !src_u || !src_v || !dst_rgb565 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565; - dst_stride_rgb565 = -dst_stride_rgb565; - } -#if defined(HAS_I422TORGB565ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToRGB565Row = I422ToRGB565Row_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToRGB565Row = I422ToRGB565Row_SSSE3; - } - } -#endif -#if defined(HAS_I422TORGB565ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToRGB565Row = I422ToRGB565Row_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToRGB565Row = I422ToRGB565Row_AVX2; - } - } -#endif -#if defined(HAS_I422TORGB565ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToRGB565Row = I422ToRGB565Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToRGB565Row = I422ToRGB565Row_NEON; - } - } -#endif -#if defined(HAS_I422TORGB565ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToRGB565Row = I422ToRGB565Row_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToRGB565Row = I422ToRGB565Row_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToRGB565Row(src_y, src_u, src_v, dst_rgb565, &kYuvI601Constants, width); - dst_rgb565 += dst_stride_rgb565; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - return 0; -} - -// Convert I422 to RGB565. -LIBYUV_API -int I422ToRGB565(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - int width, - int height) { - int y; - void (*I422ToRGB565Row)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I422ToRGB565Row_C; - if (!src_y || !src_u || !src_v || !dst_rgb565 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565; - dst_stride_rgb565 = -dst_stride_rgb565; - } -#if defined(HAS_I422TORGB565ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToRGB565Row = I422ToRGB565Row_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToRGB565Row = I422ToRGB565Row_SSSE3; - } - } -#endif -#if defined(HAS_I422TORGB565ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToRGB565Row = I422ToRGB565Row_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToRGB565Row = I422ToRGB565Row_AVX2; - } - } -#endif -#if defined(HAS_I422TORGB565ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToRGB565Row = I422ToRGB565Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToRGB565Row = I422ToRGB565Row_NEON; - } - } -#endif -#if defined(HAS_I422TORGB565ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToRGB565Row = I422ToRGB565Row_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToRGB565Row = I422ToRGB565Row_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToRGB565Row(src_y, src_u, src_v, dst_rgb565, &kYuvI601Constants, width); - dst_rgb565 += dst_stride_rgb565; - src_y += src_stride_y; - src_u += src_stride_u; - src_v += src_stride_v; - } - return 0; -} - -// Ordered 8x8 dither for 888 to 565. Values from 0 to 7. -static const uint8_t kDither565_4x4[16] = { - 0, 4, 1, 5, 6, 2, 7, 3, 1, 5, 0, 4, 7, 3, 6, 2, -}; - -// Convert I420 to RGB565 with dithering. -LIBYUV_API -int I420ToRGB565Dither(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - const uint8_t* dither4x4, - int width, - int height) { - int y; - void (*I422ToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I422ToARGBRow_C; - void (*ARGBToRGB565DitherRow)(const uint8_t* src_argb, uint8_t* dst_rgb, - const uint32_t dither4, int width) = - ARGBToRGB565DitherRow_C; - if (!src_y || !src_u || !src_v || !dst_rgb565 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565; - dst_stride_rgb565 = -dst_stride_rgb565; - } - if (!dither4x4) { - dither4x4 = kDither565_4x4; - } -#if defined(HAS_I422TOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToARGBRow = I422ToARGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToARGBRow = I422ToARGBRow_SSSE3; - } - } -#endif -#if defined(HAS_I422TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToARGBRow = I422ToARGBRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToARGBRow = I422ToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_I422TOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToARGBRow = I422ToARGBRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToARGBRow = I422ToARGBRow_NEON; - } - } -#endif -#if defined(HAS_I422TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToARGBRow = I422ToARGBRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToARGBRow = I422ToARGBRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTORGB565DITHERROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_SSE2; - if (IS_ALIGNED(width, 4)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_SSE2; - } - } -#endif -#if defined(HAS_ARGBTORGB565DITHERROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_AVX2; - if (IS_ALIGNED(width, 8)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBTORGB565DITHERROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_NEON; - } - } -#endif -#if defined(HAS_ARGBTORGB565DITHERROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_MSA; - } - } -#endif - { - // Allocate a row of argb. - align_buffer_64(row_argb, width * 4); - for (y = 0; y < height; ++y) { - I422ToARGBRow(src_y, src_u, src_v, row_argb, &kYuvI601Constants, width); - ARGBToRGB565DitherRow(row_argb, dst_rgb565, - *(const uint32_t*)(dither4x4 + ((y & 3) << 2)), - width); - dst_rgb565 += dst_stride_rgb565; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - free_aligned_buffer_64(row_argb); - } - return 0; -} - -// Convert I420 to AR30 with matrix -static int I420ToAR30Matrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_ar30, - int dst_stride_ar30, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*I422ToAR30Row)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I422ToAR30Row_C; - - if (!src_y || !src_u || !src_v || !dst_ar30 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_ar30 = dst_ar30 + (height - 1) * dst_stride_ar30; - dst_stride_ar30 = -dst_stride_ar30; - } - -#if defined(HAS_I422TOAR30ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToAR30Row = I422ToAR30Row_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToAR30Row = I422ToAR30Row_SSSE3; - } - } -#endif -#if defined(HAS_I422TOAR30ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToAR30Row = I422ToAR30Row_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToAR30Row = I422ToAR30Row_AVX2; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToAR30Row(src_y, src_u, src_v, dst_ar30, yuvconstants, width); - dst_ar30 += dst_stride_ar30; - src_y += src_stride_y; - if (y & 1) { - src_u += src_stride_u; - src_v += src_stride_v; - } - } - return 0; -} - -// Convert I420 to AR30. -LIBYUV_API -int I420ToAR30(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_ar30, - int dst_stride_ar30, - int width, - int height) { - return I420ToAR30Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_ar30, dst_stride_ar30, - &kYuvI601Constants, width, height); -} - -// Convert H420 to AR30. -LIBYUV_API -int H420ToAR30(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_ar30, - int dst_stride_ar30, - int width, - int height) { - return I420ToAR30Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_ar30, dst_stride_ar30, - &kYvuH709Constants, width, height); -} - -// Convert I420 to specified format -LIBYUV_API -int ConvertFromI420(const uint8_t* y, - int y_stride, - const uint8_t* u, - int u_stride, - const uint8_t* v, - int v_stride, - uint8_t* dst_sample, - int dst_sample_stride, - int width, - int height, - uint32_t fourcc) { - uint32_t format = CanonicalFourCC(fourcc); - int r = 0; - if (!y || !u || !v || !dst_sample || width <= 0 || height == 0) { - return -1; - } - switch (format) { - // Single plane formats - case FOURCC_YUY2: - r = I420ToYUY2(y, y_stride, u, u_stride, v, v_stride, dst_sample, - dst_sample_stride ? dst_sample_stride : width * 2, width, - height); - break; - case FOURCC_UYVY: - r = I420ToUYVY(y, y_stride, u, u_stride, v, v_stride, dst_sample, - dst_sample_stride ? dst_sample_stride : width * 2, width, - height); - break; - case FOURCC_RGBP: - r = I420ToRGB565(y, y_stride, u, u_stride, v, v_stride, dst_sample, - dst_sample_stride ? dst_sample_stride : width * 2, width, - height); - break; - case FOURCC_RGBO: - r = I420ToARGB1555(y, y_stride, u, u_stride, v, v_stride, dst_sample, - dst_sample_stride ? dst_sample_stride : width * 2, - width, height); - break; - case FOURCC_R444: - r = I420ToARGB4444(y, y_stride, u, u_stride, v, v_stride, dst_sample, - dst_sample_stride ? dst_sample_stride : width * 2, - width, height); - break; - case FOURCC_24BG: - r = I420ToRGB24(y, y_stride, u, u_stride, v, v_stride, dst_sample, - dst_sample_stride ? dst_sample_stride : width * 3, width, - height); - break; - case FOURCC_RAW: - r = I420ToRAW(y, y_stride, u, u_stride, v, v_stride, dst_sample, - dst_sample_stride ? dst_sample_stride : width * 3, width, - height); - break; - case FOURCC_ARGB: - r = I420ToARGB(y, y_stride, u, u_stride, v, v_stride, dst_sample, - dst_sample_stride ? dst_sample_stride : width * 4, width, - height); - break; - case FOURCC_BGRA: - r = I420ToBGRA(y, y_stride, u, u_stride, v, v_stride, dst_sample, - dst_sample_stride ? dst_sample_stride : width * 4, width, - height); - break; - case FOURCC_ABGR: - r = I420ToABGR(y, y_stride, u, u_stride, v, v_stride, dst_sample, - dst_sample_stride ? dst_sample_stride : width * 4, width, - height); - break; - case FOURCC_RGBA: - r = I420ToRGBA(y, y_stride, u, u_stride, v, v_stride, dst_sample, - dst_sample_stride ? dst_sample_stride : width * 4, width, - height); - break; - case FOURCC_AR30: - r = I420ToAR30(y, y_stride, u, u_stride, v, v_stride, dst_sample, - dst_sample_stride ? dst_sample_stride : width * 4, width, - height); - break; - case FOURCC_I400: - r = I400Copy(y, y_stride, dst_sample, - dst_sample_stride ? dst_sample_stride : width, width, - height); - break; - case FOURCC_NV12: { - uint8_t* dst_uv = dst_sample + width * height; - r = I420ToNV12(y, y_stride, u, u_stride, v, v_stride, dst_sample, - dst_sample_stride ? dst_sample_stride : width, dst_uv, - dst_sample_stride ? dst_sample_stride : width, width, - height); - break; - } - case FOURCC_NV21: { - uint8_t* dst_vu = dst_sample + width * height; - r = I420ToNV21(y, y_stride, u, u_stride, v, v_stride, dst_sample, - dst_sample_stride ? dst_sample_stride : width, dst_vu, - dst_sample_stride ? dst_sample_stride : width, width, - height); - break; - } - // TODO(fbarchard): Add M420. - // Triplanar formats - case FOURCC_I420: - case FOURCC_YV12: { - dst_sample_stride = dst_sample_stride ? dst_sample_stride : width; - int halfstride = (dst_sample_stride + 1) / 2; - int halfheight = (height + 1) / 2; - uint8_t* dst_u; - uint8_t* dst_v; - if (format == FOURCC_YV12) { - dst_v = dst_sample + dst_sample_stride * height; - dst_u = dst_v + halfstride * halfheight; - } else { - dst_u = dst_sample + dst_sample_stride * height; - dst_v = dst_u + halfstride * halfheight; - } - r = I420Copy(y, y_stride, u, u_stride, v, v_stride, dst_sample, - dst_sample_stride, dst_u, halfstride, dst_v, halfstride, - width, height); - break; - } - case FOURCC_I422: - case FOURCC_YV16: { - dst_sample_stride = dst_sample_stride ? dst_sample_stride : width; - int halfstride = (dst_sample_stride + 1) / 2; - uint8_t* dst_u; - uint8_t* dst_v; - if (format == FOURCC_YV16) { - dst_v = dst_sample + dst_sample_stride * height; - dst_u = dst_v + halfstride * height; - } else { - dst_u = dst_sample + dst_sample_stride * height; - dst_v = dst_u + halfstride * height; - } - r = I420ToI422(y, y_stride, u, u_stride, v, v_stride, dst_sample, - dst_sample_stride, dst_u, halfstride, dst_v, halfstride, - width, height); - break; - } - case FOURCC_I444: - case FOURCC_YV24: { - dst_sample_stride = dst_sample_stride ? dst_sample_stride : width; - uint8_t* dst_u; - uint8_t* dst_v; - if (format == FOURCC_YV24) { - dst_v = dst_sample + dst_sample_stride * height; - dst_u = dst_v + dst_sample_stride * height; - } else { - dst_u = dst_sample + dst_sample_stride * height; - dst_v = dst_u + dst_sample_stride * height; - } - r = I420ToI444(y, y_stride, u, u_stride, v, v_stride, dst_sample, - dst_sample_stride, dst_u, dst_sample_stride, dst_v, - dst_sample_stride, width, height); - break; - } - // Formats not supported - MJPG, biplanar, some rgb formats. - default: - return -1; // unknown fourcc - return failure code. - } - return r; -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_from_argb.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_from_argb.cc deleted file mode 100644 index c8d91252..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_from_argb.cc +++ /dev/null @@ -1,1617 +0,0 @@ -/* - * Copyright 2012 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/convert_from_argb.h" - -#include "libyuv/basic_types.h" -#include "libyuv/cpu_id.h" -#include "libyuv/planar_functions.h" -#include "libyuv/row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// ARGB little endian (bgra in memory) to I444 -LIBYUV_API -int ARGBToI444(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; - void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = - ARGBToYRow_C; - void (*ARGBToUV444Row)(const uint8_t* src_argb, uint8_t* dst_u, - uint8_t* dst_v, int width) = ARGBToUV444Row_C; - if (!src_argb || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - if (height < 0) { - height = -height; - src_argb = src_argb + (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_y == width && - dst_stride_u == width && dst_stride_v == width) { - width *= height; - height = 1; - src_stride_argb = dst_stride_y = dst_stride_u = dst_stride_v = 0; - } -#if defined(HAS_ARGBTOUV444ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - ARGBToUV444Row = ARGBToUV444Row_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - ARGBToUV444Row = ARGBToUV444Row_SSSE3; - } - } -#endif -#if defined(HAS_ARGBTOUV444ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToUV444Row = ARGBToUV444Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToUV444Row = ARGBToUV444Row_NEON; - } - } -#endif -#if defined(HAS_ARGBTOUV444ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUV444Row = ARGBToUV444Row_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToUV444Row = ARGBToUV444Row_MSA; - } - } -#endif -#if defined(HAS_ARGBTOYROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - ARGBToYRow = ARGBToYRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_SSSE3; - } - } -#endif -#if defined(HAS_ARGBTOYROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBToYRow = ARGBToYRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - ARGBToYRow = ARGBToYRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBTOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToYRow = ARGBToYRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToYRow = ARGBToYRow_NEON; - } - } -#endif -#if defined(HAS_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - ARGBToUV444Row(src_argb, dst_u, dst_v, width); - ARGBToYRow(src_argb, dst_y, width); - src_argb += src_stride_argb; - dst_y += dst_stride_y; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - return 0; -} - -// ARGB little endian (bgra in memory) to I422 -LIBYUV_API -int ARGBToI422(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; - void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, - uint8_t* dst_u, uint8_t* dst_v, int width) = - ARGBToUVRow_C; - void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = - ARGBToYRow_C; - 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; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_y == 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; - } -#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) && 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; - } - } -#endif -#if defined(HAS_ARGBTOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToYRow = ARGBToYRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToYRow = ARGBToYRow_NEON; - } - } -#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_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVRow = ARGBToUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVRow = ARGBToUVRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - 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; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - return 0; -} - -LIBYUV_API -int ARGBToNV12(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_uv, - int dst_stride_uv, - int width, - int height) { - int y; - int halfwidth = (width + 1) >> 1; - void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, - uint8_t* dst_u, uint8_t* dst_v, int width) = - ARGBToUVRow_C; - void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = - ARGBToYRow_C; - void (*MergeUVRow_)(const uint8_t* src_u, const uint8_t* src_v, - uint8_t* dst_uv, int width) = MergeUVRow_C; - if (!src_argb || !dst_y || !dst_uv || 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; - src_stride_argb = -src_stride_argb; - } -#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) && 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; - } - } -#endif -#if defined(HAS_ARGBTOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToYRow = ARGBToYRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToYRow = ARGBToYRow_NEON; - } - } -#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_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVRow = ARGBToUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVRow = ARGBToUVRow_MSA; - } - } -#endif -#if defined(HAS_MERGEUVROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - MergeUVRow_ = MergeUVRow_Any_SSE2; - if (IS_ALIGNED(halfwidth, 16)) { - MergeUVRow_ = MergeUVRow_SSE2; - } - } -#endif -#if defined(HAS_MERGEUVROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - MergeUVRow_ = MergeUVRow_Any_AVX2; - if (IS_ALIGNED(halfwidth, 32)) { - MergeUVRow_ = MergeUVRow_AVX2; - } - } -#endif -#if defined(HAS_MERGEUVROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - MergeUVRow_ = MergeUVRow_Any_NEON; - if (IS_ALIGNED(halfwidth, 16)) { - MergeUVRow_ = MergeUVRow_NEON; - } - } -#endif -#if defined(HAS_MERGEUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - MergeUVRow_ = MergeUVRow_Any_MSA; - if (IS_ALIGNED(halfwidth, 16)) { - MergeUVRow_ = MergeUVRow_MSA; - } - } -#endif - { - // Allocate a rows of uv. - align_buffer_64(row_u, ((halfwidth + 31) & ~31) * 2); - uint8_t* row_v = row_u + ((halfwidth + 31) & ~31); - - for (y = 0; y < height - 1; y += 2) { - ARGBToUVRow(src_argb, src_stride_argb, row_u, row_v, width); - MergeUVRow_(row_u, row_v, dst_uv, halfwidth); - ARGBToYRow(src_argb, dst_y, width); - ARGBToYRow(src_argb + src_stride_argb, dst_y + dst_stride_y, width); - src_argb += src_stride_argb * 2; - dst_y += dst_stride_y * 2; - dst_uv += dst_stride_uv; - } - if (height & 1) { - ARGBToUVRow(src_argb, 0, row_u, row_v, width); - MergeUVRow_(row_u, row_v, dst_uv, halfwidth); - ARGBToYRow(src_argb, dst_y, width); - } - free_aligned_buffer_64(row_u); - } - return 0; -} - -// Same as NV12 but U and V swapped. -LIBYUV_API -int ARGBToNV21(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_vu, - int dst_stride_vu, - int width, - int height) { - int y; - int halfwidth = (width + 1) >> 1; - void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, - uint8_t* dst_u, uint8_t* dst_v, int width) = - ARGBToUVRow_C; - void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = - ARGBToYRow_C; - void (*MergeUVRow_)(const uint8_t* src_u, const uint8_t* src_v, - uint8_t* dst_vu, int width) = MergeUVRow_C; - if (!src_argb || !dst_y || !dst_vu || 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; - src_stride_argb = -src_stride_argb; - } -#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) && 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; - } - } -#endif -#if defined(HAS_ARGBTOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToYRow = ARGBToYRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToYRow = ARGBToYRow_NEON; - } - } -#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_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVRow = ARGBToUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVRow = ARGBToUVRow_MSA; - } - } -#endif -#if defined(HAS_MERGEUVROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - MergeUVRow_ = MergeUVRow_Any_SSE2; - if (IS_ALIGNED(halfwidth, 16)) { - MergeUVRow_ = MergeUVRow_SSE2; - } - } -#endif -#if defined(HAS_MERGEUVROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - MergeUVRow_ = MergeUVRow_Any_AVX2; - if (IS_ALIGNED(halfwidth, 32)) { - MergeUVRow_ = MergeUVRow_AVX2; - } - } -#endif -#if defined(HAS_MERGEUVROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - MergeUVRow_ = MergeUVRow_Any_NEON; - if (IS_ALIGNED(halfwidth, 16)) { - MergeUVRow_ = MergeUVRow_NEON; - } - } -#endif -#if defined(HAS_MERGEUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - MergeUVRow_ = MergeUVRow_Any_MSA; - if (IS_ALIGNED(halfwidth, 16)) { - MergeUVRow_ = MergeUVRow_MSA; - } - } -#endif - { - // Allocate a rows of uv. - align_buffer_64(row_u, ((halfwidth + 31) & ~31) * 2); - uint8_t* row_v = row_u + ((halfwidth + 31) & ~31); - - for (y = 0; y < height - 1; y += 2) { - ARGBToUVRow(src_argb, src_stride_argb, row_u, row_v, width); - MergeUVRow_(row_v, row_u, dst_vu, halfwidth); - ARGBToYRow(src_argb, dst_y, width); - ARGBToYRow(src_argb + src_stride_argb, dst_y + dst_stride_y, width); - src_argb += src_stride_argb * 2; - dst_y += dst_stride_y * 2; - dst_vu += dst_stride_vu; - } - if (height & 1) { - ARGBToUVRow(src_argb, 0, row_u, row_v, width); - MergeUVRow_(row_v, row_u, dst_vu, halfwidth); - ARGBToYRow(src_argb, dst_y, width); - } - free_aligned_buffer_64(row_u); - } - return 0; -} - -// Convert ARGB to YUY2. -LIBYUV_API -int ARGBToYUY2(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_yuy2, - int dst_stride_yuy2, - int width, - int height) { - int y; - void (*ARGBToUVRow)(const uint8_t* src_argb, int src_stride_argb, - uint8_t* dst_u, uint8_t* dst_v, int width) = - ARGBToUVRow_C; - void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = - ARGBToYRow_C; - void (*I422ToYUY2Row)(const uint8_t* src_y, const uint8_t* src_u, - const uint8_t* src_v, uint8_t* dst_yuy2, int width) = - I422ToYUY2Row_C; - - if (!src_argb || !dst_yuy2 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_yuy2 = dst_yuy2 + (height - 1) * dst_stride_yuy2; - dst_stride_yuy2 = -dst_stride_yuy2; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_yuy2 == width * 2) { - width *= height; - height = 1; - src_stride_argb = dst_stride_yuy2 = 0; - } -#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) && 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; - } - } -#endif -#if defined(HAS_ARGBTOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToYRow = ARGBToYRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToYRow = ARGBToYRow_NEON; - } - } -#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_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVRow = ARGBToUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVRow = ARGBToUVRow_MSA; - } - } -#endif -#if defined(HAS_I422TOYUY2ROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - I422ToYUY2Row = I422ToYUY2Row_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - I422ToYUY2Row = I422ToYUY2Row_SSE2; - } - } -#endif -#if defined(HAS_I422TOYUY2ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToYUY2Row = I422ToYUY2Row_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - I422ToYUY2Row = I422ToYUY2Row_AVX2; - } - } -#endif -#if defined(HAS_I422TOYUY2ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToYUY2Row = I422ToYUY2Row_Any_NEON; - if (IS_ALIGNED(width, 16)) { - I422ToYUY2Row = I422ToYUY2Row_NEON; - } - } -#endif -#if defined(HAS_I422TOYUY2ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToYUY2Row = I422ToYUY2Row_Any_MSA; - if (IS_ALIGNED(width, 32)) { - I422ToYUY2Row = I422ToYUY2Row_MSA; - } - } -#endif - - { - // Allocate a rows of yuv. - align_buffer_64(row_y, ((width + 63) & ~63) * 2); - uint8_t* row_u = row_y + ((width + 63) & ~63); - uint8_t* row_v = row_u + ((width + 63) & ~63) / 2; - - for (y = 0; y < height; ++y) { - 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; - dst_yuy2 += dst_stride_yuy2; - } - - free_aligned_buffer_64(row_y); - } - return 0; -} - -// Convert ARGB to UYVY. -LIBYUV_API -int ARGBToUYVY(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_uyvy, - int dst_stride_uyvy, - int width, - int height) { - int y; - void (*ARGBToUVRow)(const uint8_t* src_argb, int src_stride_argb, - uint8_t* dst_u, uint8_t* dst_v, int width) = - ARGBToUVRow_C; - void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = - ARGBToYRow_C; - void (*I422ToUYVYRow)(const uint8_t* src_y, const uint8_t* src_u, - const uint8_t* src_v, uint8_t* dst_uyvy, int width) = - I422ToUYVYRow_C; - - if (!src_argb || !dst_uyvy || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_uyvy = dst_uyvy + (height - 1) * dst_stride_uyvy; - dst_stride_uyvy = -dst_stride_uyvy; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_uyvy == width * 2) { - width *= height; - height = 1; - src_stride_argb = dst_stride_uyvy = 0; - } -#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) && 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; - } - } -#endif -#if defined(HAS_ARGBTOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToYRow = ARGBToYRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToYRow = ARGBToYRow_NEON; - } - } -#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_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVRow = ARGBToUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVRow = ARGBToUVRow_MSA; - } - } -#endif -#if defined(HAS_I422TOUYVYROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - I422ToUYVYRow = I422ToUYVYRow_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - I422ToUYVYRow = I422ToUYVYRow_SSE2; - } - } -#endif -#if defined(HAS_I422TOUYVYROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToUYVYRow = I422ToUYVYRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - I422ToUYVYRow = I422ToUYVYRow_AVX2; - } - } -#endif -#if defined(HAS_I422TOUYVYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToUYVYRow = I422ToUYVYRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - I422ToUYVYRow = I422ToUYVYRow_NEON; - } - } -#endif -#if defined(HAS_I422TOUYVYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToUYVYRow = I422ToUYVYRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - I422ToUYVYRow = I422ToUYVYRow_MSA; - } - } -#endif - - { - // Allocate a rows of yuv. - align_buffer_64(row_y, ((width + 63) & ~63) * 2); - uint8_t* row_u = row_y + ((width + 63) & ~63); - uint8_t* row_v = row_u + ((width + 63) & ~63) / 2; - - for (y = 0; y < height; ++y) { - 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; - dst_uyvy += dst_stride_uyvy; - } - - free_aligned_buffer_64(row_y); - } - return 0; -} - -// Convert ARGB to I400. -LIBYUV_API -int ARGBToI400(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height) { - int y; - void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = - ARGBToYRow_C; - if (!src_argb || !dst_y || width <= 0 || height == 0) { - return -1; - } - if (height < 0) { - height = -height; - src_argb = src_argb + (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_y == width) { - width *= height; - height = 1; - src_stride_argb = dst_stride_y = 0; - } -#if defined(HAS_ARGBTOYROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - ARGBToYRow = ARGBToYRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_SSSE3; - } - } -#endif -#if defined(HAS_ARGBTOYROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBToYRow = ARGBToYRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - ARGBToYRow = ARGBToYRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBTOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToYRow = ARGBToYRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToYRow = ARGBToYRow_NEON; - } - } -#endif -#if defined(HAS_ARGBTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYRow = ARGBToYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYRow = ARGBToYRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - ARGBToYRow(src_argb, dst_y, width); - src_argb += src_stride_argb; - dst_y += dst_stride_y; - } - return 0; -} - -// Shuffle table for converting ARGB to RGBA. -static const uvec8 kShuffleMaskARGBToRGBA = { - 3u, 0u, 1u, 2u, 7u, 4u, 5u, 6u, 11u, 8u, 9u, 10u, 15u, 12u, 13u, 14u}; - -// Convert ARGB to RGBA. -LIBYUV_API -int ARGBToRGBA(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_rgba, - int dst_stride_rgba, - int width, - int height) { - return ARGBShuffle(src_argb, src_stride_argb, dst_rgba, dst_stride_rgba, - (const uint8_t*)(&kShuffleMaskARGBToRGBA), width, height); -} - -// Convert ARGB To RGB24. -LIBYUV_API -int ARGBToRGB24(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height) { - int y; - void (*ARGBToRGB24Row)(const uint8_t* src_argb, uint8_t* dst_rgb, int width) = - ARGBToRGB24Row_C; - if (!src_argb || !dst_rgb24 || width <= 0 || height == 0) { - return -1; - } - if (height < 0) { - height = -height; - src_argb = src_argb + (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_rgb24 == width * 3) { - width *= height; - height = 1; - src_stride_argb = dst_stride_rgb24 = 0; - } -#if defined(HAS_ARGBTORGB24ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - ARGBToRGB24Row = ARGBToRGB24Row_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - ARGBToRGB24Row = ARGBToRGB24Row_SSSE3; - } - } -#endif -#if defined(HAS_ARGBTORGB24ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBToRGB24Row = ARGBToRGB24Row_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - ARGBToRGB24Row = ARGBToRGB24Row_AVX2; - } - } -#endif -#if defined(HAS_ARGBTORGB24ROW_AVX512VBMI) - if (TestCpuFlag(kCpuHasAVX512VBMI)) { - ARGBToRGB24Row = ARGBToRGB24Row_Any_AVX512VBMI; - if (IS_ALIGNED(width, 32)) { - ARGBToRGB24Row = ARGBToRGB24Row_AVX512VBMI; - } - } -#endif -#if defined(HAS_ARGBTORGB24ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToRGB24Row = ARGBToRGB24Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToRGB24Row = ARGBToRGB24Row_NEON; - } - } -#endif -#if defined(HAS_ARGBTORGB24ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToRGB24Row = ARGBToRGB24Row_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToRGB24Row = ARGBToRGB24Row_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - ARGBToRGB24Row(src_argb, dst_rgb24, width); - src_argb += src_stride_argb; - dst_rgb24 += dst_stride_rgb24; - } - return 0; -} - -// Convert ARGB To RAW. -LIBYUV_API -int ARGBToRAW(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_raw, - int dst_stride_raw, - int width, - int height) { - int y; - void (*ARGBToRAWRow)(const uint8_t* src_argb, uint8_t* dst_rgb, int width) = - ARGBToRAWRow_C; - if (!src_argb || !dst_raw || width <= 0 || height == 0) { - return -1; - } - if (height < 0) { - height = -height; - src_argb = src_argb + (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_raw == width * 3) { - width *= height; - height = 1; - src_stride_argb = dst_stride_raw = 0; - } -#if defined(HAS_ARGBTORAWROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - ARGBToRAWRow = ARGBToRAWRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - ARGBToRAWRow = ARGBToRAWRow_SSSE3; - } - } -#endif -#if defined(HAS_ARGBTORAWROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBToRAWRow = ARGBToRAWRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - ARGBToRAWRow = ARGBToRAWRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBTORAWROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToRAWRow = ARGBToRAWRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToRAWRow = ARGBToRAWRow_NEON; - } - } -#endif -#if defined(HAS_ARGBTORAWROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToRAWRow = ARGBToRAWRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToRAWRow = ARGBToRAWRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - ARGBToRAWRow(src_argb, dst_raw, width); - src_argb += src_stride_argb; - dst_raw += dst_stride_raw; - } - return 0; -} - -// Ordered 8x8 dither for 888 to 565. Values from 0 to 7. -static const uint8_t kDither565_4x4[16] = { - 0, 4, 1, 5, 6, 2, 7, 3, 1, 5, 0, 4, 7, 3, 6, 2, -}; - -// Convert ARGB To RGB565 with 4x4 dither matrix (16 bytes). -LIBYUV_API -int ARGBToRGB565Dither(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - const uint8_t* dither4x4, - int width, - int height) { - int y; - void (*ARGBToRGB565DitherRow)(const uint8_t* src_argb, uint8_t* dst_rgb, - const uint32_t dither4, int width) = - ARGBToRGB565DitherRow_C; - if (!src_argb || !dst_rgb565 || width <= 0 || height == 0) { - return -1; - } - if (height < 0) { - height = -height; - src_argb = src_argb + (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - if (!dither4x4) { - dither4x4 = kDither565_4x4; - } -#if defined(HAS_ARGBTORGB565DITHERROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_SSE2; - if (IS_ALIGNED(width, 4)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_SSE2; - } - } -#endif -#if defined(HAS_ARGBTORGB565DITHERROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_AVX2; - if (IS_ALIGNED(width, 8)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBTORGB565DITHERROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_NEON; - } - } -#endif -#if defined(HAS_ARGBTORGB565DITHERROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - ARGBToRGB565DitherRow(src_argb, dst_rgb565, - *(const uint32_t*)(dither4x4 + ((y & 3) << 2)), - width); - src_argb += src_stride_argb; - dst_rgb565 += dst_stride_rgb565; - } - return 0; -} - -// Convert ARGB To RGB565. -// TODO(fbarchard): Consider using dither function low level with zeros. -LIBYUV_API -int ARGBToRGB565(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - int width, - int height) { - int y; - void (*ARGBToRGB565Row)(const uint8_t* src_argb, uint8_t* dst_rgb, - int width) = ARGBToRGB565Row_C; - if (!src_argb || !dst_rgb565 || width <= 0 || height == 0) { - return -1; - } - if (height < 0) { - height = -height; - src_argb = src_argb + (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_rgb565 == width * 2) { - width *= height; - height = 1; - src_stride_argb = dst_stride_rgb565 = 0; - } -#if defined(HAS_ARGBTORGB565ROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGBToRGB565Row = ARGBToRGB565Row_Any_SSE2; - if (IS_ALIGNED(width, 4)) { - ARGBToRGB565Row = ARGBToRGB565Row_SSE2; - } - } -#endif -#if defined(HAS_ARGBTORGB565ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBToRGB565Row = ARGBToRGB565Row_Any_AVX2; - if (IS_ALIGNED(width, 8)) { - ARGBToRGB565Row = ARGBToRGB565Row_AVX2; - } - } -#endif -#if defined(HAS_ARGBTORGB565ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToRGB565Row = ARGBToRGB565Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToRGB565Row = ARGBToRGB565Row_NEON; - } - } -#endif -#if defined(HAS_ARGBTORGB565ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToRGB565Row = ARGBToRGB565Row_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBToRGB565Row = ARGBToRGB565Row_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - ARGBToRGB565Row(src_argb, dst_rgb565, width); - src_argb += src_stride_argb; - dst_rgb565 += dst_stride_rgb565; - } - return 0; -} - -// Convert ARGB To ARGB1555. -LIBYUV_API -int ARGBToARGB1555(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb1555, - int dst_stride_argb1555, - int width, - int height) { - int y; - void (*ARGBToARGB1555Row)(const uint8_t* src_argb, uint8_t* dst_rgb, - int width) = ARGBToARGB1555Row_C; - if (!src_argb || !dst_argb1555 || width <= 0 || height == 0) { - return -1; - } - if (height < 0) { - height = -height; - src_argb = src_argb + (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_argb1555 == width * 2) { - width *= height; - height = 1; - src_stride_argb = dst_stride_argb1555 = 0; - } -#if defined(HAS_ARGBTOARGB1555ROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGBToARGB1555Row = ARGBToARGB1555Row_Any_SSE2; - if (IS_ALIGNED(width, 4)) { - ARGBToARGB1555Row = ARGBToARGB1555Row_SSE2; - } - } -#endif -#if defined(HAS_ARGBTOARGB1555ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBToARGB1555Row = ARGBToARGB1555Row_Any_AVX2; - if (IS_ALIGNED(width, 8)) { - ARGBToARGB1555Row = ARGBToARGB1555Row_AVX2; - } - } -#endif -#if defined(HAS_ARGBTOARGB1555ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToARGB1555Row = ARGBToARGB1555Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToARGB1555Row = ARGBToARGB1555Row_NEON; - } - } -#endif -#if defined(HAS_ARGBTOARGB1555ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToARGB1555Row = ARGBToARGB1555Row_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBToARGB1555Row = ARGBToARGB1555Row_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - ARGBToARGB1555Row(src_argb, dst_argb1555, width); - src_argb += src_stride_argb; - dst_argb1555 += dst_stride_argb1555; - } - return 0; -} - -// Convert ARGB To ARGB4444. -LIBYUV_API -int ARGBToARGB4444(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb4444, - int dst_stride_argb4444, - int width, - int height) { - int y; - void (*ARGBToARGB4444Row)(const uint8_t* src_argb, uint8_t* dst_rgb, - int width) = ARGBToARGB4444Row_C; - if (!src_argb || !dst_argb4444 || width <= 0 || height == 0) { - return -1; - } - if (height < 0) { - height = -height; - src_argb = src_argb + (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_argb4444 == width * 2) { - width *= height; - height = 1; - src_stride_argb = dst_stride_argb4444 = 0; - } -#if defined(HAS_ARGBTOARGB4444ROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGBToARGB4444Row = ARGBToARGB4444Row_Any_SSE2; - if (IS_ALIGNED(width, 4)) { - ARGBToARGB4444Row = ARGBToARGB4444Row_SSE2; - } - } -#endif -#if defined(HAS_ARGBTOARGB4444ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBToARGB4444Row = ARGBToARGB4444Row_Any_AVX2; - if (IS_ALIGNED(width, 8)) { - ARGBToARGB4444Row = ARGBToARGB4444Row_AVX2; - } - } -#endif -#if defined(HAS_ARGBTOARGB4444ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToARGB4444Row = ARGBToARGB4444Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToARGB4444Row = ARGBToARGB4444Row_NEON; - } - } -#endif -#if defined(HAS_ARGBTOARGB4444ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToARGB4444Row = ARGBToARGB4444Row_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBToARGB4444Row = ARGBToARGB4444Row_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - ARGBToARGB4444Row(src_argb, dst_argb4444, width); - src_argb += src_stride_argb; - dst_argb4444 += dst_stride_argb4444; - } - return 0; -} - -// Convert ABGR To AR30. -LIBYUV_API -int ABGRToAR30(const uint8_t* src_abgr, - int src_stride_abgr, - uint8_t* dst_ar30, - int dst_stride_ar30, - int width, - int height) { - int y; - void (*ABGRToAR30Row)(const uint8_t* src_abgr, uint8_t* dst_rgb, int width) = - ABGRToAR30Row_C; - if (!src_abgr || !dst_ar30 || width <= 0 || height == 0) { - return -1; - } - if (height < 0) { - height = -height; - src_abgr = src_abgr + (height - 1) * src_stride_abgr; - src_stride_abgr = -src_stride_abgr; - } - // Coalesce rows. - if (src_stride_abgr == width * 4 && dst_stride_ar30 == width * 4) { - width *= height; - height = 1; - src_stride_abgr = dst_stride_ar30 = 0; - } -#if defined(HAS_ABGRTOAR30ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - ABGRToAR30Row = ABGRToAR30Row_Any_SSSE3; - if (IS_ALIGNED(width, 4)) { - ABGRToAR30Row = ABGRToAR30Row_SSSE3; - } - } -#endif -#if defined(HAS_ABGRTOAR30ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ABGRToAR30Row = ABGRToAR30Row_Any_AVX2; - if (IS_ALIGNED(width, 8)) { - ABGRToAR30Row = ABGRToAR30Row_AVX2; - } - } -#endif - for (y = 0; y < height; ++y) { - ABGRToAR30Row(src_abgr, dst_ar30, width); - src_abgr += src_stride_abgr; - dst_ar30 += dst_stride_ar30; - } - return 0; -} - -// Convert ARGB To AR30. -LIBYUV_API -int ARGBToAR30(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_ar30, - int dst_stride_ar30, - int width, - int height) { - int y; - void (*ARGBToAR30Row)(const uint8_t* src_argb, uint8_t* dst_rgb, int width) = - ARGBToAR30Row_C; - if (!src_argb || !dst_ar30 || width <= 0 || height == 0) { - return -1; - } - if (height < 0) { - height = -height; - src_argb = src_argb + (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_ar30 == width * 4) { - width *= height; - height = 1; - src_stride_argb = dst_stride_ar30 = 0; - } -#if defined(HAS_ARGBTOAR30ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - ARGBToAR30Row = ARGBToAR30Row_Any_SSSE3; - if (IS_ALIGNED(width, 4)) { - ARGBToAR30Row = ARGBToAR30Row_SSSE3; - } - } -#endif -#if defined(HAS_ARGBTOAR30ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBToAR30Row = ARGBToAR30Row_Any_AVX2; - if (IS_ALIGNED(width, 8)) { - ARGBToAR30Row = ARGBToAR30Row_AVX2; - } - } -#endif - for (y = 0; y < height; ++y) { - ARGBToAR30Row(src_argb, dst_ar30, width); - src_argb += src_stride_argb; - dst_ar30 += dst_stride_ar30; - } - return 0; -} - -// Convert ARGB to J420. (JPeg full range I420). -LIBYUV_API -int ARGBToJ420(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_yj, - int dst_stride_yj, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; - void (*ARGBToUVJRow)(const uint8_t* src_argb0, int src_stride_argb, - uint8_t* dst_u, uint8_t* dst_v, int width) = - ARGBToUVJRow_C; - void (*ARGBToYJRow)(const uint8_t* src_argb, uint8_t* dst_yj, int width) = - ARGBToYJRow_C; - 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; - src_stride_argb = -src_stride_argb; - } -#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; - } - } -#endif -#if defined(HAS_ARGBTOYJROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBToYJRow = ARGBToYJRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - ARGBToYJRow = ARGBToYJRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBTOYJROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToYJRow = ARGBToYJRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToYJRow = ARGBToYJRow_NEON; - } - } -#endif -#if defined(HAS_ARGBTOUVJROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToUVJRow = ARGBToUVJRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - ARGBToUVJRow = ARGBToUVJRow_NEON; - } - } -#endif -#if defined(HAS_ARGBTOYJROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYJRow = ARGBToYJRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYJRow = ARGBToYJRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOUVJROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVJRow = ARGBToUVJRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVJRow = ARGBToUVJRow_MSA; - } - } -#endif - - for (y = 0; y < height - 1; y += 2) { - ARGBToUVJRow(src_argb, src_stride_argb, dst_u, dst_v, width); - ARGBToYJRow(src_argb, dst_yj, width); - ARGBToYJRow(src_argb + src_stride_argb, dst_yj + dst_stride_yj, width); - src_argb += src_stride_argb * 2; - dst_yj += dst_stride_yj * 2; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - if (height & 1) { - ARGBToUVJRow(src_argb, 0, dst_u, dst_v, width); - ARGBToYJRow(src_argb, dst_yj, width); - } - return 0; -} - -// Convert ARGB to J422. (JPeg full range I422). -LIBYUV_API -int ARGBToJ422(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_yj, - int dst_stride_yj, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; - void (*ARGBToUVJRow)(const uint8_t* src_argb0, int src_stride_argb, - uint8_t* dst_u, uint8_t* dst_v, int width) = - ARGBToUVJRow_C; - void (*ARGBToYJRow)(const uint8_t* src_argb, uint8_t* dst_yj, int width) = - ARGBToYJRow_C; - 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; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_yj == width && - dst_stride_u * 2 == width && dst_stride_v * 2 == width) { - width *= height; - height = 1; - src_stride_argb = dst_stride_yj = dst_stride_u = dst_stride_v = 0; - } -#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; - } - } -#endif -#if defined(HAS_ARGBTOYJROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBToYJRow = ARGBToYJRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - ARGBToYJRow = ARGBToYJRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBTOYJROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToYJRow = ARGBToYJRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToYJRow = ARGBToYJRow_NEON; - } - } -#endif -#if defined(HAS_ARGBTOUVJROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToUVJRow = ARGBToUVJRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - ARGBToUVJRow = ARGBToUVJRow_NEON; - } - } -#endif -#if defined(HAS_ARGBTOYJROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYJRow = ARGBToYJRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYJRow = ARGBToYJRow_MSA; - } - } -#endif -#if defined(HAS_ARGBTOUVJROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToUVJRow = ARGBToUVJRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - ARGBToUVJRow = ARGBToUVJRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - ARGBToUVJRow(src_argb, 0, dst_u, dst_v, width); - ARGBToYJRow(src_argb, dst_yj, width); - src_argb += src_stride_argb; - dst_yj += dst_stride_yj; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - return 0; -} - -// Convert ARGB to J400. -LIBYUV_API -int ARGBToJ400(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_yj, - int dst_stride_yj, - int width, - int height) { - int y; - void (*ARGBToYJRow)(const uint8_t* src_argb, uint8_t* dst_yj, int width) = - ARGBToYJRow_C; - if (!src_argb || !dst_yj || width <= 0 || height == 0) { - return -1; - } - if (height < 0) { - height = -height; - src_argb = src_argb + (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_yj == width) { - width *= height; - height = 1; - src_stride_argb = dst_stride_yj = 0; - } -#if defined(HAS_ARGBTOYJROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - ARGBToYJRow = ARGBToYJRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - ARGBToYJRow = ARGBToYJRow_SSSE3; - } - } -#endif -#if defined(HAS_ARGBTOYJROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBToYJRow = ARGBToYJRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - ARGBToYJRow = ARGBToYJRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBTOYJROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToYJRow = ARGBToYJRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToYJRow = ARGBToYJRow_NEON; - } - } -#endif -#if defined(HAS_ARGBTOYJROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYJRow = ARGBToYJRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYJRow = ARGBToYJRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - ARGBToYJRow(src_argb, dst_yj, width); - src_argb += src_stride_argb; - dst_yj += dst_stride_yj; - } - return 0; -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_jpeg.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_jpeg.cc deleted file mode 100644 index ae3cc18c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_jpeg.cc +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/convert.h" -#include "libyuv/convert_argb.h" - -#ifdef HAVE_JPEG -#include "libyuv/mjpeg_decoder.h" -#endif - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -#ifdef HAVE_JPEG -struct I420Buffers { - uint8_t* y; - int y_stride; - uint8_t* u; - int u_stride; - uint8_t* v; - int v_stride; - int w; - int h; -}; - -static void JpegCopyI420(void* opaque, - const uint8_t* const* data, - const int* strides, - int rows) { - I420Buffers* dest = (I420Buffers*)(opaque); - I420Copy(data[0], strides[0], data[1], strides[1], data[2], strides[2], - dest->y, dest->y_stride, dest->u, dest->u_stride, dest->v, - dest->v_stride, dest->w, rows); - dest->y += rows * dest->y_stride; - dest->u += ((rows + 1) >> 1) * dest->u_stride; - dest->v += ((rows + 1) >> 1) * dest->v_stride; - dest->h -= rows; -} - -static void JpegI422ToI420(void* opaque, - const uint8_t* const* data, - const int* strides, - int rows) { - I420Buffers* dest = (I420Buffers*)(opaque); - I422ToI420(data[0], strides[0], data[1], strides[1], data[2], strides[2], - dest->y, dest->y_stride, dest->u, dest->u_stride, dest->v, - dest->v_stride, dest->w, rows); - dest->y += rows * dest->y_stride; - dest->u += ((rows + 1) >> 1) * dest->u_stride; - dest->v += ((rows + 1) >> 1) * dest->v_stride; - dest->h -= rows; -} - -static void JpegI444ToI420(void* opaque, - const uint8_t* const* data, - const int* strides, - int rows) { - I420Buffers* dest = (I420Buffers*)(opaque); - I444ToI420(data[0], strides[0], data[1], strides[1], data[2], strides[2], - dest->y, dest->y_stride, dest->u, dest->u_stride, dest->v, - dest->v_stride, dest->w, rows); - dest->y += rows * dest->y_stride; - dest->u += ((rows + 1) >> 1) * dest->u_stride; - dest->v += ((rows + 1) >> 1) * dest->v_stride; - dest->h -= rows; -} - -static void JpegI400ToI420(void* opaque, - const uint8_t* const* data, - const int* strides, - int rows) { - I420Buffers* dest = (I420Buffers*)(opaque); - I400ToI420(data[0], strides[0], dest->y, dest->y_stride, dest->u, - dest->u_stride, dest->v, dest->v_stride, dest->w, rows); - dest->y += rows * dest->y_stride; - dest->u += ((rows + 1) >> 1) * dest->u_stride; - dest->v += ((rows + 1) >> 1) * dest->v_stride; - dest->h -= rows; -} - -// Query size of MJPG in pixels. -LIBYUV_API -int MJPGSize(const uint8_t* sample, - size_t sample_size, - int* width, - int* height) { - MJpegDecoder mjpeg_decoder; - LIBYUV_BOOL ret = mjpeg_decoder.LoadFrame(sample, sample_size); - if (ret) { - *width = mjpeg_decoder.GetWidth(); - *height = mjpeg_decoder.GetHeight(); - } - mjpeg_decoder.UnloadFrame(); - return ret ? 0 : -1; // -1 for runtime failure. -} - -// MJPG (Motion JPeg) to I420 -// TODO(fbarchard): review src_width and src_height requirement. dst_width and -// dst_height may be enough. -LIBYUV_API -int MJPGToI420(const uint8_t* sample, - size_t sample_size, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int src_width, - int src_height, - int dst_width, - int dst_height) { - if (sample_size == kUnknownDataSize) { - // ERROR: MJPEG frame size unknown - return -1; - } - - // TODO(fbarchard): Port MJpeg to C. - MJpegDecoder mjpeg_decoder; - LIBYUV_BOOL ret = mjpeg_decoder.LoadFrame(sample, sample_size); - if (ret && (mjpeg_decoder.GetWidth() != src_width || - mjpeg_decoder.GetHeight() != src_height)) { - // ERROR: MJPEG frame has unexpected dimensions - mjpeg_decoder.UnloadFrame(); - return 1; // runtime failure - } - if (ret) { - I420Buffers bufs = {dst_y, dst_stride_y, dst_u, dst_stride_u, - dst_v, dst_stride_v, dst_width, dst_height}; - // YUV420 - if (mjpeg_decoder.GetColorSpace() == MJpegDecoder::kColorSpaceYCbCr && - mjpeg_decoder.GetNumComponents() == 3 && - mjpeg_decoder.GetVertSampFactor(0) == 2 && - mjpeg_decoder.GetHorizSampFactor(0) == 2 && - mjpeg_decoder.GetVertSampFactor(1) == 1 && - mjpeg_decoder.GetHorizSampFactor(1) == 1 && - mjpeg_decoder.GetVertSampFactor(2) == 1 && - mjpeg_decoder.GetHorizSampFactor(2) == 1) { - ret = mjpeg_decoder.DecodeToCallback(&JpegCopyI420, &bufs, dst_width, - dst_height); - // YUV422 - } else if (mjpeg_decoder.GetColorSpace() == - MJpegDecoder::kColorSpaceYCbCr && - mjpeg_decoder.GetNumComponents() == 3 && - mjpeg_decoder.GetVertSampFactor(0) == 1 && - mjpeg_decoder.GetHorizSampFactor(0) == 2 && - mjpeg_decoder.GetVertSampFactor(1) == 1 && - mjpeg_decoder.GetHorizSampFactor(1) == 1 && - mjpeg_decoder.GetVertSampFactor(2) == 1 && - mjpeg_decoder.GetHorizSampFactor(2) == 1) { - ret = mjpeg_decoder.DecodeToCallback(&JpegI422ToI420, &bufs, dst_width, - dst_height); - // YUV444 - } else if (mjpeg_decoder.GetColorSpace() == - MJpegDecoder::kColorSpaceYCbCr && - mjpeg_decoder.GetNumComponents() == 3 && - mjpeg_decoder.GetVertSampFactor(0) == 1 && - mjpeg_decoder.GetHorizSampFactor(0) == 1 && - mjpeg_decoder.GetVertSampFactor(1) == 1 && - mjpeg_decoder.GetHorizSampFactor(1) == 1 && - mjpeg_decoder.GetVertSampFactor(2) == 1 && - mjpeg_decoder.GetHorizSampFactor(2) == 1) { - ret = mjpeg_decoder.DecodeToCallback(&JpegI444ToI420, &bufs, dst_width, - dst_height); - // YUV400 - } else if (mjpeg_decoder.GetColorSpace() == - MJpegDecoder::kColorSpaceGrayscale && - mjpeg_decoder.GetNumComponents() == 1 && - mjpeg_decoder.GetVertSampFactor(0) == 1 && - mjpeg_decoder.GetHorizSampFactor(0) == 1) { - ret = mjpeg_decoder.DecodeToCallback(&JpegI400ToI420, &bufs, dst_width, - dst_height); - } else { - // TODO(fbarchard): Implement conversion for any other colorspace/sample - // factors that occur in practice. - // ERROR: Unable to convert MJPEG frame because format is not supported - mjpeg_decoder.UnloadFrame(); - return 1; - } - } - return ret ? 0 : 1; -} - -#ifdef HAVE_JPEG -struct ARGBBuffers { - uint8_t* argb; - int argb_stride; - int w; - int h; -}; - -static void JpegI420ToARGB(void* opaque, - const uint8_t* const* data, - const int* strides, - int rows) { - ARGBBuffers* dest = (ARGBBuffers*)(opaque); - I420ToARGB(data[0], strides[0], data[1], strides[1], data[2], strides[2], - dest->argb, dest->argb_stride, dest->w, rows); - dest->argb += rows * dest->argb_stride; - dest->h -= rows; -} - -static void JpegI422ToARGB(void* opaque, - const uint8_t* const* data, - const int* strides, - int rows) { - ARGBBuffers* dest = (ARGBBuffers*)(opaque); - I422ToARGB(data[0], strides[0], data[1], strides[1], data[2], strides[2], - dest->argb, dest->argb_stride, dest->w, rows); - dest->argb += rows * dest->argb_stride; - dest->h -= rows; -} - -static void JpegI444ToARGB(void* opaque, - const uint8_t* const* data, - const int* strides, - int rows) { - ARGBBuffers* dest = (ARGBBuffers*)(opaque); - I444ToARGB(data[0], strides[0], data[1], strides[1], data[2], strides[2], - dest->argb, dest->argb_stride, dest->w, rows); - dest->argb += rows * dest->argb_stride; - dest->h -= rows; -} - -static void JpegI400ToARGB(void* opaque, - const uint8_t* const* data, - const int* strides, - int rows) { - ARGBBuffers* dest = (ARGBBuffers*)(opaque); - I400ToARGB(data[0], strides[0], dest->argb, dest->argb_stride, dest->w, rows); - dest->argb += rows * dest->argb_stride; - dest->h -= rows; -} - -// MJPG (Motion JPeg) to ARGB -// TODO(fbarchard): review src_width and src_height requirement. dst_width and -// dst_height may be enough. -LIBYUV_API -int MJPGToARGB(const uint8_t* sample, - size_t sample_size, - uint8_t* dst_argb, - int dst_stride_argb, - int src_width, - int src_height, - int dst_width, - int dst_height) { - if (sample_size == kUnknownDataSize) { - // ERROR: MJPEG frame size unknown - return -1; - } - - // TODO(fbarchard): Port MJpeg to C. - MJpegDecoder mjpeg_decoder; - LIBYUV_BOOL ret = mjpeg_decoder.LoadFrame(sample, sample_size); - if (ret && (mjpeg_decoder.GetWidth() != src_width || - mjpeg_decoder.GetHeight() != src_height)) { - // ERROR: MJPEG frame has unexpected dimensions - mjpeg_decoder.UnloadFrame(); - return 1; // runtime failure - } - if (ret) { - ARGBBuffers bufs = {dst_argb, dst_stride_argb, dst_width, dst_height}; - // YUV420 - if (mjpeg_decoder.GetColorSpace() == MJpegDecoder::kColorSpaceYCbCr && - mjpeg_decoder.GetNumComponents() == 3 && - mjpeg_decoder.GetVertSampFactor(0) == 2 && - mjpeg_decoder.GetHorizSampFactor(0) == 2 && - mjpeg_decoder.GetVertSampFactor(1) == 1 && - mjpeg_decoder.GetHorizSampFactor(1) == 1 && - mjpeg_decoder.GetVertSampFactor(2) == 1 && - mjpeg_decoder.GetHorizSampFactor(2) == 1) { - ret = mjpeg_decoder.DecodeToCallback(&JpegI420ToARGB, &bufs, dst_width, - dst_height); - // YUV422 - } else if (mjpeg_decoder.GetColorSpace() == - MJpegDecoder::kColorSpaceYCbCr && - mjpeg_decoder.GetNumComponents() == 3 && - mjpeg_decoder.GetVertSampFactor(0) == 1 && - mjpeg_decoder.GetHorizSampFactor(0) == 2 && - mjpeg_decoder.GetVertSampFactor(1) == 1 && - mjpeg_decoder.GetHorizSampFactor(1) == 1 && - mjpeg_decoder.GetVertSampFactor(2) == 1 && - mjpeg_decoder.GetHorizSampFactor(2) == 1) { - ret = mjpeg_decoder.DecodeToCallback(&JpegI422ToARGB, &bufs, dst_width, - dst_height); - // YUV444 - } else if (mjpeg_decoder.GetColorSpace() == - MJpegDecoder::kColorSpaceYCbCr && - mjpeg_decoder.GetNumComponents() == 3 && - mjpeg_decoder.GetVertSampFactor(0) == 1 && - mjpeg_decoder.GetHorizSampFactor(0) == 1 && - mjpeg_decoder.GetVertSampFactor(1) == 1 && - mjpeg_decoder.GetHorizSampFactor(1) == 1 && - mjpeg_decoder.GetVertSampFactor(2) == 1 && - mjpeg_decoder.GetHorizSampFactor(2) == 1) { - ret = mjpeg_decoder.DecodeToCallback(&JpegI444ToARGB, &bufs, dst_width, - dst_height); - // YUV400 - } else if (mjpeg_decoder.GetColorSpace() == - MJpegDecoder::kColorSpaceGrayscale && - mjpeg_decoder.GetNumComponents() == 1 && - mjpeg_decoder.GetVertSampFactor(0) == 1 && - mjpeg_decoder.GetHorizSampFactor(0) == 1) { - ret = mjpeg_decoder.DecodeToCallback(&JpegI400ToARGB, &bufs, dst_width, - dst_height); - } else { - // TODO(fbarchard): Implement conversion for any other colorspace/sample - // factors that occur in practice. - // ERROR: Unable to convert MJPEG frame because format is not supported - mjpeg_decoder.UnloadFrame(); - return 1; - } - } - return ret ? 0 : 1; -} -#endif - -#endif - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_to_argb.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_to_argb.cc deleted file mode 100644 index 67484522..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_to_argb.cc +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/convert_argb.h" - -#include "libyuv/cpu_id.h" -#ifdef HAVE_JPEG -#include "libyuv/mjpeg_decoder.h" -#endif -#include "libyuv/rotate_argb.h" -#include "libyuv/row.h" -#include "libyuv/video_common.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// 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. -// With MJPEG it is the compressed size of the frame. - -// TODO(fbarchard): Add the following: -// H010ToARGB -// H420ToARGB -// H422ToARGB -// I010ToARGB -// J400ToARGB -// J422ToARGB -// J444ToARGB - -LIBYUV_API -int ConvertToARGB(const uint8_t* sample, - size_t sample_size, - uint8_t* dst_argb, - int dst_stride_argb, - int crop_x, - int crop_y, - int src_width, - int src_height, - int crop_width, - int crop_height, - enum RotationMode rotation, - uint32_t fourcc) { - uint32_t format = CanonicalFourCC(fourcc); - int aligned_src_width = (src_width + 1) & ~1; - const uint8_t* src; - const uint8_t* src_uv; - int abs_src_height = (src_height < 0) ? -src_height : src_height; - int inv_crop_height = (crop_height < 0) ? -crop_height : crop_height; - int r = 0; - - // One pass rotation is available for some formats. For the rest, convert - // to ARGB (with optional vertical flipping) into a temporary ARGB buffer, - // and then rotate the ARGB to the final destination buffer. - // For in-place conversion, if destination dst_argb is same as source sample, - // also enable temporary buffer. - LIBYUV_BOOL need_buf = - (rotation && format != FOURCC_ARGB) || dst_argb == sample; - uint8_t* dest_argb = dst_argb; - int dest_dst_stride_argb = dst_stride_argb; - uint8_t* rotate_buffer = NULL; - int abs_crop_height = (crop_height < 0) ? -crop_height : crop_height; - - if (dst_argb == NULL || sample == NULL || src_width <= 0 || crop_width <= 0 || - src_height == 0 || crop_height == 0) { - return -1; - } - if (src_height < 0) { - inv_crop_height = -inv_crop_height; - } - - if (need_buf) { - int argb_size = crop_width * 4 * abs_crop_height; - rotate_buffer = (uint8_t*)malloc(argb_size); /* NOLINT */ - if (!rotate_buffer) { - return 1; // Out of memory runtime error. - } - dst_argb = rotate_buffer; - dst_stride_argb = crop_width * 4; - } - - switch (format) { - // Single plane formats - case FOURCC_YUY2: - src = sample + (aligned_src_width * crop_y + crop_x) * 2; - r = YUY2ToARGB(src, aligned_src_width * 2, dst_argb, dst_stride_argb, - crop_width, inv_crop_height); - break; - case FOURCC_UYVY: - src = sample + (aligned_src_width * crop_y + crop_x) * 2; - r = UYVYToARGB(src, aligned_src_width * 2, dst_argb, dst_stride_argb, - crop_width, inv_crop_height); - break; - case FOURCC_24BG: - src = sample + (src_width * crop_y + crop_x) * 3; - r = RGB24ToARGB(src, src_width * 3, dst_argb, dst_stride_argb, crop_width, - inv_crop_height); - break; - case FOURCC_RAW: - src = sample + (src_width * crop_y + crop_x) * 3; - r = RAWToARGB(src, src_width * 3, dst_argb, dst_stride_argb, crop_width, - inv_crop_height); - break; - case FOURCC_ARGB: - if (!need_buf && !rotation) { - src = sample + (src_width * crop_y + crop_x) * 4; - r = ARGBToARGB(src, src_width * 4, dst_argb, dst_stride_argb, - crop_width, inv_crop_height); - } - break; - case FOURCC_BGRA: - src = sample + (src_width * crop_y + crop_x) * 4; - r = BGRAToARGB(src, src_width * 4, dst_argb, dst_stride_argb, crop_width, - inv_crop_height); - break; - case FOURCC_ABGR: - src = sample + (src_width * crop_y + crop_x) * 4; - r = ABGRToARGB(src, src_width * 4, dst_argb, dst_stride_argb, crop_width, - inv_crop_height); - break; - case FOURCC_RGBA: - src = sample + (src_width * crop_y + crop_x) * 4; - r = RGBAToARGB(src, src_width * 4, dst_argb, dst_stride_argb, crop_width, - inv_crop_height); - break; - case FOURCC_AR30: - src = sample + (src_width * crop_y + crop_x) * 4; - r = AR30ToARGB(src, src_width * 4, dst_argb, dst_stride_argb, crop_width, - inv_crop_height); - break; - case FOURCC_AB30: - src = sample + (src_width * crop_y + crop_x) * 4; - r = AB30ToARGB(src, src_width * 4, dst_argb, dst_stride_argb, crop_width, - inv_crop_height); - break; - case FOURCC_RGBP: - src = sample + (src_width * crop_y + crop_x) * 2; - r = RGB565ToARGB(src, src_width * 2, dst_argb, dst_stride_argb, - crop_width, inv_crop_height); - break; - case FOURCC_RGBO: - src = sample + (src_width * crop_y + crop_x) * 2; - r = ARGB1555ToARGB(src, src_width * 2, dst_argb, dst_stride_argb, - crop_width, inv_crop_height); - break; - case FOURCC_R444: - src = sample + (src_width * crop_y + crop_x) * 2; - r = ARGB4444ToARGB(src, src_width * 2, dst_argb, dst_stride_argb, - crop_width, inv_crop_height); - break; - case FOURCC_I400: - src = sample + src_width * crop_y + crop_x; - r = I400ToARGB(src, src_width, dst_argb, dst_stride_argb, crop_width, - inv_crop_height); - break; - - // Biplanar formats - case FOURCC_NV12: - src = sample + (src_width * crop_y + crop_x); - src_uv = sample + aligned_src_width * (abs_src_height + crop_y / 2) + crop_x; - r = NV12ToARGB(src, src_width, src_uv, aligned_src_width, dst_argb, - dst_stride_argb, crop_width, inv_crop_height); - break; - case FOURCC_NV21: - src = sample + (src_width * crop_y + crop_x); - src_uv = sample + aligned_src_width * (abs_src_height + crop_y / 2) + crop_x; - // Call NV12 but with u and v parameters swapped. - r = NV21ToARGB(src, src_width, src_uv, aligned_src_width, dst_argb, - dst_stride_argb, crop_width, inv_crop_height); - break; - case FOURCC_M420: - src = sample + (src_width * crop_y) * 12 / 8 + crop_x; - r = M420ToARGB(src, src_width, dst_argb, dst_stride_argb, crop_width, - inv_crop_height); - break; - - // Triplanar formats - case FOURCC_I420: - case FOURCC_YV12: { - const uint8_t* src_y = sample + (src_width * crop_y + crop_x); - const uint8_t* src_u; - const uint8_t* src_v; - int halfwidth = (src_width + 1) / 2; - int halfheight = (abs_src_height + 1) / 2; - if (format == FOURCC_YV12) { - src_v = sample + src_width * abs_src_height + - (halfwidth * crop_y + crop_x) / 2; - src_u = sample + src_width * abs_src_height + - halfwidth * (halfheight + crop_y / 2) + crop_x / 2; - } else { - src_u = sample + src_width * abs_src_height + - (halfwidth * crop_y + crop_x) / 2; - src_v = sample + src_width * abs_src_height + - halfwidth * (halfheight + crop_y / 2) + crop_x / 2; - } - r = I420ToARGB(src_y, src_width, src_u, halfwidth, src_v, halfwidth, - dst_argb, dst_stride_argb, crop_width, inv_crop_height); - break; - } - - case FOURCC_J420: { - const uint8_t* src_y = sample + (src_width * crop_y + crop_x); - const uint8_t* src_u; - const uint8_t* src_v; - int halfwidth = (src_width + 1) / 2; - int halfheight = (abs_src_height + 1) / 2; - src_u = sample + src_width * abs_src_height + - (halfwidth * crop_y + crop_x) / 2; - src_v = sample + src_width * abs_src_height + - halfwidth * (halfheight + crop_y / 2) + crop_x / 2; - r = J420ToARGB(src_y, src_width, src_u, halfwidth, src_v, halfwidth, - dst_argb, dst_stride_argb, crop_width, inv_crop_height); - break; - } - - case FOURCC_I422: - case FOURCC_YV16: { - const uint8_t* src_y = sample + src_width * crop_y + crop_x; - const uint8_t* src_u; - const uint8_t* src_v; - int halfwidth = (src_width + 1) / 2; - if (format == FOURCC_YV16) { - src_v = sample + src_width * abs_src_height + halfwidth * crop_y + - crop_x / 2; - src_u = sample + src_width * abs_src_height + - halfwidth * (abs_src_height + crop_y) + crop_x / 2; - } else { - src_u = sample + src_width * abs_src_height + halfwidth * crop_y + - crop_x / 2; - src_v = sample + src_width * abs_src_height + - halfwidth * (abs_src_height + crop_y) + crop_x / 2; - } - r = I422ToARGB(src_y, src_width, src_u, halfwidth, src_v, halfwidth, - dst_argb, dst_stride_argb, crop_width, inv_crop_height); - break; - } - case FOURCC_I444: - case FOURCC_YV24: { - const uint8_t* src_y = sample + src_width * crop_y + crop_x; - const uint8_t* src_u; - const uint8_t* src_v; - if (format == FOURCC_YV24) { - src_v = sample + src_width * (abs_src_height + crop_y) + crop_x; - src_u = sample + src_width * (abs_src_height * 2 + crop_y) + crop_x; - } else { - src_u = sample + src_width * (abs_src_height + crop_y) + crop_x; - src_v = sample + src_width * (abs_src_height * 2 + crop_y) + crop_x; - } - r = I444ToARGB(src_y, src_width, src_u, src_width, src_v, src_width, - dst_argb, dst_stride_argb, crop_width, inv_crop_height); - break; - } -#ifdef HAVE_JPEG - case FOURCC_MJPG: - r = MJPGToARGB(sample, sample_size, dst_argb, dst_stride_argb, src_width, - abs_src_height, crop_width, inv_crop_height); - break; -#endif - default: - r = -1; // unknown fourcc - return failure code. - } - - if (need_buf) { - if (!r) { - r = ARGBRotate(dst_argb, dst_stride_argb, dest_argb, dest_dst_stride_argb, - crop_width, abs_crop_height, rotation); - } - free(rotate_buffer); - } else if (rotation) { - src = sample + (src_width * crop_y + crop_x) * 4; - r = ARGBRotate(src, src_width * 4, dst_argb, dst_stride_argb, crop_width, - inv_crop_height, rotation); - } - - return r; -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_to_i420.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_to_i420.cc deleted file mode 100644 index df08309f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/convert_to_i420.cc +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "libyuv/convert.h" - -#include "libyuv/video_common.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// Convert camera sample to I420 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. -// With MJPEG it is the compressed size of the frame. -LIBYUV_API -int ConvertToI420(const uint8_t* sample, - size_t sample_size, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int crop_x, - int crop_y, - int src_width, - int src_height, - int crop_width, - int crop_height, - enum RotationMode rotation, - uint32_t fourcc) { - uint32_t format = CanonicalFourCC(fourcc); - int aligned_src_width = (src_width + 1) & ~1; - const uint8_t* src; - const uint8_t* src_uv; - const int abs_src_height = (src_height < 0) ? -src_height : src_height; - // TODO(nisse): Why allow crop_height < 0? - const int abs_crop_height = (crop_height < 0) ? -crop_height : crop_height; - int r = 0; - LIBYUV_BOOL need_buf = - (rotation && format != FOURCC_I420 && format != FOURCC_NV12 && - format != FOURCC_NV21 && format != FOURCC_YV12) || - dst_y == sample; - uint8_t* tmp_y = dst_y; - uint8_t* tmp_u = dst_u; - uint8_t* tmp_v = dst_v; - int tmp_y_stride = dst_stride_y; - int tmp_u_stride = dst_stride_u; - int tmp_v_stride = dst_stride_v; - uint8_t* rotate_buffer = NULL; - const int inv_crop_height = - (src_height < 0) ? -abs_crop_height : abs_crop_height; - - if (!dst_y || !dst_u || !dst_v || !sample || src_width <= 0 || - crop_width <= 0 || src_height == 0 || crop_height == 0) { - return -1; - } - - // One pass rotation is available for some formats. For the rest, convert - // to I420 (with optional vertical flipping) into a temporary I420 buffer, - // and then rotate the I420 to the final destination buffer. - // For in-place conversion, if destination dst_y is same as source sample, - // also enable temporary buffer. - if (need_buf) { - int y_size = crop_width * abs_crop_height; - int uv_size = ((crop_width + 1) / 2) * ((abs_crop_height + 1) / 2); - rotate_buffer = (uint8_t*)malloc(y_size + uv_size * 2); /* NOLINT */ - if (!rotate_buffer) { - return 1; // Out of memory runtime error. - } - dst_y = rotate_buffer; - dst_u = dst_y + y_size; - dst_v = dst_u + uv_size; - dst_stride_y = crop_width; - dst_stride_u = dst_stride_v = ((crop_width + 1) / 2); - } - - switch (format) { - // Single plane formats - case FOURCC_YUY2: - src = sample + (aligned_src_width * crop_y + crop_x) * 2; - r = YUY2ToI420(src, aligned_src_width * 2, dst_y, dst_stride_y, dst_u, - dst_stride_u, dst_v, dst_stride_v, crop_width, - inv_crop_height); - break; - case FOURCC_UYVY: - src = sample + (aligned_src_width * crop_y + crop_x) * 2; - r = UYVYToI420(src, aligned_src_width * 2, dst_y, dst_stride_y, dst_u, - dst_stride_u, dst_v, dst_stride_v, crop_width, - inv_crop_height); - break; - case FOURCC_RGBP: - src = sample + (src_width * crop_y + crop_x) * 2; - r = RGB565ToI420(src, src_width * 2, dst_y, dst_stride_y, dst_u, - dst_stride_u, dst_v, dst_stride_v, crop_width, - inv_crop_height); - break; - case FOURCC_RGBO: - src = sample + (src_width * crop_y + crop_x) * 2; - r = ARGB1555ToI420(src, src_width * 2, dst_y, dst_stride_y, dst_u, - dst_stride_u, dst_v, dst_stride_v, crop_width, - inv_crop_height); - break; - case FOURCC_R444: - src = sample + (src_width * crop_y + crop_x) * 2; - r = ARGB4444ToI420(src, src_width * 2, dst_y, dst_stride_y, dst_u, - dst_stride_u, dst_v, dst_stride_v, crop_width, - inv_crop_height); - break; - case FOURCC_24BG: - src = sample + (src_width * crop_y + crop_x) * 3; - r = RGB24ToI420(src, src_width * 3, dst_y, dst_stride_y, dst_u, - dst_stride_u, dst_v, dst_stride_v, crop_width, - inv_crop_height); - break; - case FOURCC_RAW: - src = sample + (src_width * crop_y + crop_x) * 3; - r = RAWToI420(src, src_width * 3, dst_y, dst_stride_y, dst_u, - dst_stride_u, dst_v, dst_stride_v, crop_width, - inv_crop_height); - break; - case FOURCC_ARGB: - src = sample + (src_width * crop_y + crop_x) * 4; - r = ARGBToI420(src, src_width * 4, dst_y, dst_stride_y, dst_u, - dst_stride_u, dst_v, dst_stride_v, crop_width, - inv_crop_height); - break; - case FOURCC_BGRA: - src = sample + (src_width * crop_y + crop_x) * 4; - r = BGRAToI420(src, src_width * 4, dst_y, dst_stride_y, dst_u, - dst_stride_u, dst_v, dst_stride_v, crop_width, - inv_crop_height); - break; - case FOURCC_ABGR: - src = sample + (src_width * crop_y + crop_x) * 4; - r = ABGRToI420(src, src_width * 4, dst_y, dst_stride_y, dst_u, - dst_stride_u, dst_v, dst_stride_v, crop_width, - inv_crop_height); - break; - case FOURCC_RGBA: - src = sample + (src_width * crop_y + crop_x) * 4; - r = RGBAToI420(src, src_width * 4, dst_y, dst_stride_y, dst_u, - dst_stride_u, dst_v, dst_stride_v, crop_width, - inv_crop_height); - break; - // TODO(fbarchard): Add AR30 and AB30 - case FOURCC_I400: - src = sample + src_width * crop_y + crop_x; - r = I400ToI420(src, src_width, dst_y, dst_stride_y, dst_u, dst_stride_u, - dst_v, dst_stride_v, crop_width, inv_crop_height); - break; - // Biplanar formats - case FOURCC_NV12: - src = sample + (src_width * crop_y + crop_x); - src_uv = sample + (src_width * abs_src_height) + - ((crop_y / 2) * aligned_src_width) + ((crop_x / 2) * 2); - r = NV12ToI420Rotate(src, src_width, src_uv, aligned_src_width, dst_y, - dst_stride_y, dst_u, dst_stride_u, dst_v, - dst_stride_v, crop_width, inv_crop_height, rotation); - break; - case FOURCC_NV21: - src = sample + (src_width * crop_y + crop_x); - src_uv = sample + (src_width * abs_src_height) + - ((crop_y / 2) * aligned_src_width) + ((crop_x / 2) * 2); - // Call NV12 but with dst_u and dst_v parameters swapped. - r = NV12ToI420Rotate(src, src_width, src_uv, aligned_src_width, dst_y, - dst_stride_y, dst_v, dst_stride_v, dst_u, - dst_stride_u, crop_width, inv_crop_height, rotation); - break; - case FOURCC_M420: - src = sample + (src_width * crop_y) * 12 / 8 + crop_x; - r = M420ToI420(src, src_width, dst_y, dst_stride_y, dst_u, dst_stride_u, - dst_v, dst_stride_v, crop_width, inv_crop_height); - break; - // Triplanar formats - case FOURCC_I420: - case FOURCC_YV12: { - const uint8_t* src_y = sample + (src_width * crop_y + crop_x); - const uint8_t* src_u; - const uint8_t* src_v; - int halfwidth = (src_width + 1) / 2; - int halfheight = (abs_src_height + 1) / 2; - if (format == FOURCC_YV12) { - src_v = sample + src_width * abs_src_height + - (halfwidth * crop_y + crop_x) / 2; - src_u = sample + src_width * abs_src_height + - halfwidth * (halfheight + crop_y / 2) + crop_x / 2; - } else { - src_u = sample + src_width * abs_src_height + - (halfwidth * crop_y + crop_x) / 2; - src_v = sample + src_width * abs_src_height + - halfwidth * (halfheight + crop_y / 2) + crop_x / 2; - } - r = I420Rotate(src_y, src_width, src_u, halfwidth, src_v, halfwidth, - dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, - dst_stride_v, crop_width, inv_crop_height, rotation); - break; - } - case FOURCC_I422: - case FOURCC_YV16: { - const uint8_t* src_y = sample + src_width * crop_y + crop_x; - const uint8_t* src_u; - const uint8_t* src_v; - int halfwidth = (src_width + 1) / 2; - if (format == FOURCC_YV16) { - src_v = sample + src_width * abs_src_height + halfwidth * crop_y + - crop_x / 2; - src_u = sample + src_width * abs_src_height + - halfwidth * (abs_src_height + crop_y) + crop_x / 2; - } else { - src_u = sample + src_width * abs_src_height + halfwidth * crop_y + - crop_x / 2; - src_v = sample + src_width * abs_src_height + - halfwidth * (abs_src_height + crop_y) + crop_x / 2; - } - r = I422ToI420(src_y, src_width, src_u, halfwidth, src_v, halfwidth, - dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, - dst_stride_v, crop_width, inv_crop_height); - break; - } - case FOURCC_I444: - case FOURCC_YV24: { - const uint8_t* src_y = sample + src_width * crop_y + crop_x; - const uint8_t* src_u; - const uint8_t* src_v; - if (format == FOURCC_YV24) { - src_v = sample + src_width * (abs_src_height + crop_y) + crop_x; - src_u = sample + src_width * (abs_src_height * 2 + crop_y) + crop_x; - } else { - src_u = sample + src_width * (abs_src_height + crop_y) + crop_x; - src_v = sample + src_width * (abs_src_height * 2 + crop_y) + crop_x; - } - r = I444ToI420(src_y, src_width, src_u, src_width, src_v, src_width, - dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, - dst_stride_v, crop_width, inv_crop_height); - break; - } -#ifdef HAVE_JPEG - case FOURCC_MJPG: - r = MJPGToI420(sample, sample_size, dst_y, dst_stride_y, dst_u, - dst_stride_u, dst_v, dst_stride_v, src_width, - abs_src_height, crop_width, inv_crop_height); - break; -#endif - default: - r = -1; // unknown fourcc - return failure code. - } - - if (need_buf) { - if (!r) { - r = I420Rotate(dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, - dst_stride_v, tmp_y, tmp_y_stride, tmp_u, tmp_u_stride, - tmp_v, tmp_v_stride, crop_width, abs_crop_height, - rotation); - } - free(rotate_buffer); - } - - return r; -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/cpu_id.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/cpu_id.cc deleted file mode 100644 index 31e24b67..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/cpu_id.cc +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/cpu_id.h" - -#if defined(_MSC_VER) -#include // For __cpuidex() -#endif -#if !defined(__pnacl__) && !defined(__CLR_VER) && \ - !defined(__native_client__) && (defined(_M_IX86) || defined(_M_X64)) && \ - defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 160040219) -#include // For _xgetbv() -#endif - -// For ArmCpuCaps() but unittested on all platforms -#include -#include - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// For functions that use the stack and have runtime checks for overflow, -// use SAFEBUFFERS to avoid additional check. -#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 160040219) && \ - !defined(__clang__) -#define SAFEBUFFERS __declspec(safebuffers) -#else -#define SAFEBUFFERS -#endif - -// cpu_info_ variable for SIMD instruction sets detected. -LIBYUV_API int cpu_info_ = 0; - -// TODO(fbarchard): Consider using int for cpuid so casting is not needed. -// Low level cpuid for X86. -#if (defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \ - defined(__x86_64__)) && \ - !defined(__pnacl__) && !defined(__CLR_VER) -LIBYUV_API -void CpuId(int info_eax, int info_ecx, int* cpu_info) { -#if defined(_MSC_VER) -// Visual C version uses intrinsic or inline x86 assembly. -#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 160040219) - __cpuidex(cpu_info, info_eax, info_ecx); -#elif defined(_M_IX86) - __asm { - mov eax, info_eax - mov ecx, info_ecx - mov edi, cpu_info - cpuid - mov [edi], eax - mov [edi + 4], ebx - mov [edi + 8], ecx - mov [edi + 12], edx - } -#else // Visual C but not x86 - if (info_ecx == 0) { - __cpuid(cpu_info, info_eax); - } else { - cpu_info[3] = cpu_info[2] = cpu_info[1] = cpu_info[0] = 0u; - } -#endif -// GCC version uses inline x86 assembly. -#else // defined(_MSC_VER) - int info_ebx, info_edx; - asm volatile( -#if defined(__i386__) && defined(__PIC__) - // Preserve ebx for fpic 32 bit. - "mov %%ebx, %%edi \n" - "cpuid \n" - "xchg %%edi, %%ebx \n" - : "=D"(info_ebx), -#else - "cpuid \n" - : "=b"(info_ebx), -#endif // defined( __i386__) && defined(__PIC__) - "+a"(info_eax), "+c"(info_ecx), "=d"(info_edx)); - cpu_info[0] = info_eax; - cpu_info[1] = info_ebx; - cpu_info[2] = info_ecx; - cpu_info[3] = info_edx; -#endif // defined(_MSC_VER) -} -#else // (defined(_M_IX86) || defined(_M_X64) ... -LIBYUV_API -void CpuId(int eax, int ecx, int* cpu_info) { - (void)eax; - (void)ecx; - cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0; -} -#endif - -// For VS2010 and earlier emit can be used: -// _asm _emit 0x0f _asm _emit 0x01 _asm _emit 0xd0 // For VS2010 and earlier. -// __asm { -// xor ecx, ecx // xcr 0 -// xgetbv -// mov xcr0, eax -// } -// For VS2013 and earlier 32 bit, the _xgetbv(0) optimizer produces bad code. -// https://code.google.com/p/libyuv/issues/detail?id=529 -#if defined(_M_IX86) && (_MSC_VER < 1900) -#pragma optimize("g", off) -#endif -#if (defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \ - defined(__x86_64__)) && \ - !defined(__pnacl__) && !defined(__CLR_VER) && !defined(__native_client__) -// X86 CPUs have xgetbv to detect OS saves high parts of ymm registers. -int GetXCR0() { - int xcr0 = 0; -#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 160040219) - xcr0 = (int)_xgetbv(0); // VS2010 SP1 required. NOLINT -#elif defined(__i386__) || defined(__x86_64__) - asm(".byte 0x0f, 0x01, 0xd0" : "=a"(xcr0) : "c"(0) : "%edx"); -#endif // defined(__i386__) || defined(__x86_64__) - return xcr0; -} -#else -// xgetbv unavailable to query for OSSave support. Return 0. -#define GetXCR0() 0 -#endif // defined(_M_IX86) || defined(_M_X64) .. -// Return optimization to previous setting. -#if defined(_M_IX86) && (_MSC_VER < 1900) -#pragma optimize("g", on) -#endif - -// based on libvpx arm_cpudetect.c -// For Arm, but public to allow testing on any CPU -LIBYUV_API SAFEBUFFERS int ArmCpuCaps(const char* cpuinfo_name) { - char cpuinfo_line[512]; - FILE* f = fopen(cpuinfo_name, "r"); - if (!f) { - // Assume Neon if /proc/cpuinfo is unavailable. - // This will occur for Chrome sandbox for Pepper or Render process. - return kCpuHasNEON; - } - while (fgets(cpuinfo_line, sizeof(cpuinfo_line) - 1, f)) { - if (memcmp(cpuinfo_line, "Features", 8) == 0) { - char* p = strstr(cpuinfo_line, " neon"); - if (p && (p[5] == ' ' || p[5] == '\n')) { - fclose(f); - return kCpuHasNEON; - } - // aarch64 uses asimd for Neon. - p = strstr(cpuinfo_line, " asimd"); - if (p) { - fclose(f); - return kCpuHasNEON; - } - } - } - fclose(f); - return 0; -} - -// TODO(fbarchard): Consider read_msa_ir(). -// TODO(fbarchard): Add unittest. -LIBYUV_API SAFEBUFFERS int MipsCpuCaps(const char* cpuinfo_name, - const char ase[]) { - char cpuinfo_line[512]; - FILE* f = fopen(cpuinfo_name, "r"); - if (!f) { - // ase enabled if /proc/cpuinfo is unavailable. - if (strcmp(ase, " msa") == 0) { - return kCpuHasMSA; - } - return 0; - } - while (fgets(cpuinfo_line, sizeof(cpuinfo_line) - 1, f)) { - if (memcmp(cpuinfo_line, "ASEs implemented", 16) == 0) { - char* p = strstr(cpuinfo_line, ase); - if (p) { - fclose(f); - if (strcmp(ase, " msa") == 0) { - return kCpuHasMSA; - } - return 0; - } - } - } - fclose(f); - return 0; -} - -static SAFEBUFFERS int GetCpuFlags(void) { - int cpu_info = 0; -#if !defined(__pnacl__) && !defined(__CLR_VER) && \ - (defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || \ - defined(_M_IX86)) - int cpu_info0[4] = {0, 0, 0, 0}; - int cpu_info1[4] = {0, 0, 0, 0}; - int cpu_info7[4] = {0, 0, 0, 0}; - CpuId(0, 0, cpu_info0); - CpuId(1, 0, cpu_info1); - if (cpu_info0[0] >= 7) { - CpuId(7, 0, cpu_info7); - } - cpu_info = kCpuHasX86 | ((cpu_info1[3] & 0x04000000) ? kCpuHasSSE2 : 0) | - ((cpu_info1[2] & 0x00000200) ? kCpuHasSSSE3 : 0) | - ((cpu_info1[2] & 0x00080000) ? kCpuHasSSE41 : 0) | - ((cpu_info1[2] & 0x00100000) ? kCpuHasSSE42 : 0) | - ((cpu_info7[1] & 0x00000200) ? kCpuHasERMS : 0); - - // AVX requires OS saves YMM registers. - if (((cpu_info1[2] & 0x1c000000) == 0x1c000000) && // AVX and OSXSave - ((GetXCR0() & 6) == 6)) { // Test OS saves YMM registers - cpu_info |= kCpuHasAVX | ((cpu_info7[1] & 0x00000020) ? kCpuHasAVX2 : 0) | - ((cpu_info1[2] & 0x00001000) ? kCpuHasFMA3 : 0) | - ((cpu_info1[2] & 0x20000000) ? kCpuHasF16C : 0); - - // Detect AVX512bw - if ((GetXCR0() & 0xe0) == 0xe0) { - cpu_info |= (cpu_info7[1] & 0x40000000) ? kCpuHasAVX512BW : 0; - cpu_info |= (cpu_info7[1] & 0x80000000) ? kCpuHasAVX512VL : 0; - cpu_info |= (cpu_info7[2] & 0x00000002) ? kCpuHasAVX512VBMI : 0; - cpu_info |= (cpu_info7[2] & 0x00000040) ? kCpuHasAVX512VBMI2 : 0; - cpu_info |= (cpu_info7[2] & 0x00001000) ? kCpuHasAVX512VBITALG : 0; - cpu_info |= (cpu_info7[2] & 0x00004000) ? kCpuHasAVX512VPOPCNTDQ : 0; - cpu_info |= (cpu_info7[2] & 0x00000100) ? kCpuHasGFNI : 0; - } - } -#endif -#if defined(__mips__) && defined(__linux__) -#if defined(__mips_msa) - cpu_info = MipsCpuCaps("/proc/cpuinfo", " msa"); -#endif - cpu_info |= kCpuHasMIPS; -#endif -#if defined(__arm__) || defined(__aarch64__) -// gcc -mfpu=neon defines __ARM_NEON__ -// __ARM_NEON__ generates code that requires Neon. NaCL also requires Neon. -// For Linux, /proc/cpuinfo can be tested but without that assume Neon. -#if defined(__ARM_NEON__) || defined(__native_client__) || !defined(__linux__) - cpu_info = kCpuHasNEON; -// For aarch64(arm64), /proc/cpuinfo's feature is not complete, e.g. no neon -// flag in it. -// So for aarch64, neon enabling is hard coded here. -#endif -#if defined(__aarch64__) - cpu_info = kCpuHasNEON; -#else - // Linux arm parse text file for neon detect. - cpu_info = ArmCpuCaps("/proc/cpuinfo"); -#endif - cpu_info |= kCpuHasARM; -#endif // __arm__ - cpu_info |= kCpuInitialized; - return cpu_info; -} - -// Note that use of this function is not thread safe. -LIBYUV_API -int MaskCpuFlags(int enable_flags) { - int cpu_info = GetCpuFlags() & enable_flags; - SetCpuFlags(cpu_info); - return cpu_info; -} - -LIBYUV_API -int InitCpuFlags(void) { - return MaskCpuFlags(-1); -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/mjpeg_decoder.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/mjpeg_decoder.cc deleted file mode 100644 index eaf25301..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/mjpeg_decoder.cc +++ /dev/null @@ -1,573 +0,0 @@ -/* - * Copyright 2012 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/mjpeg_decoder.h" - -#ifdef HAVE_JPEG -#include - -#if !defined(__pnacl__) && !defined(__CLR_VER) && \ - !defined(COVERAGE_ENABLED) && !defined(TARGET_IPHONE_SIMULATOR) -// Must be included before jpeglib. -#include -#define HAVE_SETJMP - -#if defined(_MSC_VER) -// disable warning 4324: structure was padded due to __declspec(align()) -#pragma warning(disable : 4324) -#endif - -#endif -struct FILE; // For jpeglib.h. - -// C++ build requires extern C for jpeg internals. -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#ifdef __cplusplus -} // extern "C" -#endif - -#include "libyuv/planar_functions.h" // For CopyPlane(). - -namespace libyuv { - -#ifdef HAVE_SETJMP -struct SetJmpErrorMgr { - jpeg_error_mgr base; // Must be at the top - jmp_buf setjmp_buffer; -}; -#endif - -const int MJpegDecoder::kColorSpaceUnknown = JCS_UNKNOWN; -const int MJpegDecoder::kColorSpaceGrayscale = JCS_GRAYSCALE; -const int MJpegDecoder::kColorSpaceRgb = JCS_RGB; -const int MJpegDecoder::kColorSpaceYCbCr = JCS_YCbCr; -const int MJpegDecoder::kColorSpaceCMYK = JCS_CMYK; -const int MJpegDecoder::kColorSpaceYCCK = JCS_YCCK; - -// Methods that are passed to jpeglib. -boolean fill_input_buffer(jpeg_decompress_struct* cinfo); -void init_source(jpeg_decompress_struct* cinfo); -void skip_input_data(jpeg_decompress_struct* cinfo, long num_bytes); // NOLINT -void term_source(jpeg_decompress_struct* cinfo); -void ErrorHandler(jpeg_common_struct* cinfo); -void OutputHandler(jpeg_common_struct* cinfo); - -MJpegDecoder::MJpegDecoder() - : has_scanline_padding_(LIBYUV_FALSE), - num_outbufs_(0), - scanlines_(NULL), - scanlines_sizes_(NULL), - databuf_(NULL), - databuf_strides_(NULL) { - decompress_struct_ = new jpeg_decompress_struct; - source_mgr_ = new jpeg_source_mgr; -#ifdef HAVE_SETJMP - error_mgr_ = new SetJmpErrorMgr; - decompress_struct_->err = jpeg_std_error(&error_mgr_->base); - // Override standard exit()-based error handler. - error_mgr_->base.error_exit = &ErrorHandler; - error_mgr_->base.output_message = &OutputHandler; -#endif - decompress_struct_->client_data = NULL; - source_mgr_->init_source = &init_source; - source_mgr_->fill_input_buffer = &fill_input_buffer; - source_mgr_->skip_input_data = &skip_input_data; - source_mgr_->resync_to_restart = &jpeg_resync_to_restart; - source_mgr_->term_source = &term_source; - jpeg_create_decompress(decompress_struct_); - decompress_struct_->src = source_mgr_; - buf_vec_.buffers = &buf_; - buf_vec_.len = 1; -} - -MJpegDecoder::~MJpegDecoder() { - jpeg_destroy_decompress(decompress_struct_); - delete decompress_struct_; - delete source_mgr_; -#ifdef HAVE_SETJMP - delete error_mgr_; -#endif - DestroyOutputBuffers(); -} - -LIBYUV_BOOL MJpegDecoder::LoadFrame(const uint8_t* src, size_t src_len) { - if (!ValidateJpeg(src, src_len)) { - return LIBYUV_FALSE; - } - - buf_.data = src; - buf_.len = static_cast(src_len); - buf_vec_.pos = 0; - decompress_struct_->client_data = &buf_vec_; -#ifdef HAVE_SETJMP - if (setjmp(error_mgr_->setjmp_buffer)) { - // We called jpeg_read_header, it experienced an error, and we called - // longjmp() and rewound the stack to here. Return error. - return LIBYUV_FALSE; - } -#endif - if (jpeg_read_header(decompress_struct_, TRUE) != JPEG_HEADER_OK) { - // ERROR: Bad MJPEG header - return LIBYUV_FALSE; - } - AllocOutputBuffers(GetNumComponents()); - for (int i = 0; i < num_outbufs_; ++i) { - int scanlines_size = GetComponentScanlinesPerImcuRow(i); - if (scanlines_sizes_[i] != scanlines_size) { - if (scanlines_[i]) { - delete scanlines_[i]; - } - scanlines_[i] = new uint8_t*[scanlines_size]; - scanlines_sizes_[i] = scanlines_size; - } - - // We allocate padding for the final scanline to pad it up to DCTSIZE bytes - // to avoid memory errors, since jpeglib only reads full MCUs blocks. For - // the preceding scanlines, the padding is not needed/wanted because the - // following addresses will already be valid (they are the initial bytes of - // the next scanline) and will be overwritten when jpeglib writes out that - // next scanline. - int databuf_stride = GetComponentStride(i); - int databuf_size = scanlines_size * databuf_stride; - if (databuf_strides_[i] != databuf_stride) { - if (databuf_[i]) { - delete databuf_[i]; - } - databuf_[i] = new uint8_t[databuf_size]; - databuf_strides_[i] = databuf_stride; - } - - if (GetComponentStride(i) != GetComponentWidth(i)) { - has_scanline_padding_ = LIBYUV_TRUE; - } - } - return LIBYUV_TRUE; -} - -static int DivideAndRoundUp(int numerator, int denominator) { - return (numerator + denominator - 1) / denominator; -} - -static int DivideAndRoundDown(int numerator, int denominator) { - return numerator / denominator; -} - -// Returns width of the last loaded frame. -int MJpegDecoder::GetWidth() { - return decompress_struct_->image_width; -} - -// Returns height of the last loaded frame. -int MJpegDecoder::GetHeight() { - return decompress_struct_->image_height; -} - -// Returns format of the last loaded frame. The return value is one of the -// kColorSpace* constants. -int MJpegDecoder::GetColorSpace() { - return decompress_struct_->jpeg_color_space; -} - -// Number of color components in the color space. -int MJpegDecoder::GetNumComponents() { - return decompress_struct_->num_components; -} - -// Sample factors of the n-th component. -int MJpegDecoder::GetHorizSampFactor(int component) { - return decompress_struct_->comp_info[component].h_samp_factor; -} - -int MJpegDecoder::GetVertSampFactor(int component) { - return decompress_struct_->comp_info[component].v_samp_factor; -} - -int MJpegDecoder::GetHorizSubSampFactor(int component) { - return decompress_struct_->max_h_samp_factor / GetHorizSampFactor(component); -} - -int MJpegDecoder::GetVertSubSampFactor(int component) { - return decompress_struct_->max_v_samp_factor / GetVertSampFactor(component); -} - -int MJpegDecoder::GetImageScanlinesPerImcuRow() { - return decompress_struct_->max_v_samp_factor * DCTSIZE; -} - -int MJpegDecoder::GetComponentScanlinesPerImcuRow(int component) { - int vs = GetVertSubSampFactor(component); - return DivideAndRoundUp(GetImageScanlinesPerImcuRow(), vs); -} - -int MJpegDecoder::GetComponentWidth(int component) { - int hs = GetHorizSubSampFactor(component); - return DivideAndRoundUp(GetWidth(), hs); -} - -int MJpegDecoder::GetComponentHeight(int component) { - int vs = GetVertSubSampFactor(component); - return DivideAndRoundUp(GetHeight(), vs); -} - -// Get width in bytes padded out to a multiple of DCTSIZE -int MJpegDecoder::GetComponentStride(int component) { - return (GetComponentWidth(component) + DCTSIZE - 1) & ~(DCTSIZE - 1); -} - -int MJpegDecoder::GetComponentSize(int component) { - return GetComponentWidth(component) * GetComponentHeight(component); -} - -LIBYUV_BOOL MJpegDecoder::UnloadFrame() { -#ifdef HAVE_SETJMP - if (setjmp(error_mgr_->setjmp_buffer)) { - // We called jpeg_abort_decompress, it experienced an error, and we called - // longjmp() and rewound the stack to here. Return error. - return LIBYUV_FALSE; - } -#endif - jpeg_abort_decompress(decompress_struct_); - return LIBYUV_TRUE; -} - -// TODO(fbarchard): Allow rectangle to be specified: x, y, width, height. -LIBYUV_BOOL MJpegDecoder::DecodeToBuffers(uint8_t** planes, - int dst_width, - int dst_height) { - if (dst_width != GetWidth() || dst_height > GetHeight()) { - // ERROR: Bad dimensions - return LIBYUV_FALSE; - } -#ifdef HAVE_SETJMP - if (setjmp(error_mgr_->setjmp_buffer)) { - // We called into jpeglib, it experienced an error sometime during this - // function call, and we called longjmp() and rewound the stack to here. - // Return error. - return LIBYUV_FALSE; - } -#endif - if (!StartDecode()) { - return LIBYUV_FALSE; - } - SetScanlinePointers(databuf_); - int lines_left = dst_height; - // Compute amount of lines to skip to implement vertical crop. - // TODO(fbarchard): Ensure skip is a multiple of maximum component - // subsample. ie 2 - int skip = (GetHeight() - dst_height) / 2; - if (skip > 0) { - // There is no API to skip lines in the output data, so we read them - // into the temp buffer. - while (skip >= GetImageScanlinesPerImcuRow()) { - if (!DecodeImcuRow()) { - FinishDecode(); - return LIBYUV_FALSE; - } - skip -= GetImageScanlinesPerImcuRow(); - } - if (skip > 0) { - // Have a partial iMCU row left over to skip. Must read it and then - // copy the parts we want into the destination. - if (!DecodeImcuRow()) { - FinishDecode(); - return LIBYUV_FALSE; - } - for (int i = 0; i < num_outbufs_; ++i) { - // TODO(fbarchard): Compute skip to avoid this - assert(skip % GetVertSubSampFactor(i) == 0); - int rows_to_skip = DivideAndRoundDown(skip, GetVertSubSampFactor(i)); - int scanlines_to_copy = - GetComponentScanlinesPerImcuRow(i) - rows_to_skip; - int data_to_skip = rows_to_skip * GetComponentStride(i); - CopyPlane(databuf_[i] + data_to_skip, GetComponentStride(i), planes[i], - GetComponentWidth(i), GetComponentWidth(i), - scanlines_to_copy); - planes[i] += scanlines_to_copy * GetComponentWidth(i); - } - lines_left -= (GetImageScanlinesPerImcuRow() - skip); - } - } - - // Read full MCUs but cropped horizontally - for (; lines_left > GetImageScanlinesPerImcuRow(); - lines_left -= GetImageScanlinesPerImcuRow()) { - if (!DecodeImcuRow()) { - FinishDecode(); - return LIBYUV_FALSE; - } - for (int i = 0; i < num_outbufs_; ++i) { - int scanlines_to_copy = GetComponentScanlinesPerImcuRow(i); - CopyPlane(databuf_[i], GetComponentStride(i), planes[i], - GetComponentWidth(i), GetComponentWidth(i), scanlines_to_copy); - planes[i] += scanlines_to_copy * GetComponentWidth(i); - } - } - - if (lines_left > 0) { - // Have a partial iMCU row left over to decode. - if (!DecodeImcuRow()) { - FinishDecode(); - return LIBYUV_FALSE; - } - for (int i = 0; i < num_outbufs_; ++i) { - int scanlines_to_copy = - DivideAndRoundUp(lines_left, GetVertSubSampFactor(i)); - CopyPlane(databuf_[i], GetComponentStride(i), planes[i], - GetComponentWidth(i), GetComponentWidth(i), scanlines_to_copy); - planes[i] += scanlines_to_copy * GetComponentWidth(i); - } - } - return FinishDecode(); -} - -LIBYUV_BOOL MJpegDecoder::DecodeToCallback(CallbackFunction fn, - void* opaque, - int dst_width, - int dst_height) { - if (dst_width != GetWidth() || dst_height > GetHeight()) { - // ERROR: Bad dimensions - return LIBYUV_FALSE; - } -#ifdef HAVE_SETJMP - if (setjmp(error_mgr_->setjmp_buffer)) { - // We called into jpeglib, it experienced an error sometime during this - // function call, and we called longjmp() and rewound the stack to here. - // Return error. - return LIBYUV_FALSE; - } -#endif - if (!StartDecode()) { - return LIBYUV_FALSE; - } - SetScanlinePointers(databuf_); - int lines_left = dst_height; - // TODO(fbarchard): Compute amount of lines to skip to implement vertical crop - int skip = (GetHeight() - dst_height) / 2; - if (skip > 0) { - while (skip >= GetImageScanlinesPerImcuRow()) { - if (!DecodeImcuRow()) { - FinishDecode(); - return LIBYUV_FALSE; - } - skip -= GetImageScanlinesPerImcuRow(); - } - if (skip > 0) { - // Have a partial iMCU row left over to skip. - if (!DecodeImcuRow()) { - FinishDecode(); - return LIBYUV_FALSE; - } - for (int i = 0; i < num_outbufs_; ++i) { - // TODO(fbarchard): Compute skip to avoid this - assert(skip % GetVertSubSampFactor(i) == 0); - int rows_to_skip = DivideAndRoundDown(skip, GetVertSubSampFactor(i)); - int data_to_skip = rows_to_skip * GetComponentStride(i); - // Change our own data buffer pointers so we can pass them to the - // callback. - databuf_[i] += data_to_skip; - } - int scanlines_to_copy = GetImageScanlinesPerImcuRow() - skip; - (*fn)(opaque, databuf_, databuf_strides_, scanlines_to_copy); - // Now change them back. - for (int i = 0; i < num_outbufs_; ++i) { - int rows_to_skip = DivideAndRoundDown(skip, GetVertSubSampFactor(i)); - int data_to_skip = rows_to_skip * GetComponentStride(i); - databuf_[i] -= data_to_skip; - } - lines_left -= scanlines_to_copy; - } - } - // Read full MCUs until we get to the crop point. - for (; lines_left >= GetImageScanlinesPerImcuRow(); - lines_left -= GetImageScanlinesPerImcuRow()) { - if (!DecodeImcuRow()) { - FinishDecode(); - return LIBYUV_FALSE; - } - (*fn)(opaque, databuf_, databuf_strides_, GetImageScanlinesPerImcuRow()); - } - if (lines_left > 0) { - // Have a partial iMCU row left over to decode. - if (!DecodeImcuRow()) { - FinishDecode(); - return LIBYUV_FALSE; - } - (*fn)(opaque, databuf_, databuf_strides_, lines_left); - } - return FinishDecode(); -} - -void init_source(j_decompress_ptr cinfo) { - fill_input_buffer(cinfo); -} - -boolean fill_input_buffer(j_decompress_ptr cinfo) { - BufferVector* buf_vec = reinterpret_cast(cinfo->client_data); - if (buf_vec->pos >= buf_vec->len) { - assert(0 && "No more data"); - // ERROR: No more data - return FALSE; - } - cinfo->src->next_input_byte = buf_vec->buffers[buf_vec->pos].data; - cinfo->src->bytes_in_buffer = buf_vec->buffers[buf_vec->pos].len; - ++buf_vec->pos; - return TRUE; -} - -void skip_input_data(j_decompress_ptr cinfo, long num_bytes) { // NOLINT - cinfo->src->next_input_byte += num_bytes; -} - -void term_source(j_decompress_ptr cinfo) { - (void)cinfo; // Nothing to do. -} - -#ifdef HAVE_SETJMP -void ErrorHandler(j_common_ptr cinfo) { -// This is called when a jpeglib command experiences an error. Unfortunately -// jpeglib's error handling model is not very flexible, because it expects the -// error handler to not return--i.e., it wants the program to terminate. To -// recover from errors we use setjmp() as shown in their example. setjmp() is -// C's implementation for the "call with current continuation" functionality -// seen in some functional programming languages. -// A formatted message can be output, but is unsafe for release. -#ifdef DEBUG - char buf[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message)(cinfo, buf); -// ERROR: Error in jpeglib: buf -#endif - - SetJmpErrorMgr* mgr = reinterpret_cast(cinfo->err); - // This rewinds the call stack to the point of the corresponding setjmp() - // and causes it to return (for a second time) with value 1. - longjmp(mgr->setjmp_buffer, 1); -} - -// Suppress fprintf warnings. -void OutputHandler(j_common_ptr cinfo) { - (void)cinfo; -} - -#endif // HAVE_SETJMP - -void MJpegDecoder::AllocOutputBuffers(int num_outbufs) { - if (num_outbufs != num_outbufs_) { - // We could perhaps optimize this case to resize the output buffers without - // necessarily having to delete and recreate each one, but it's not worth - // it. - DestroyOutputBuffers(); - - scanlines_ = new uint8_t**[num_outbufs]; - scanlines_sizes_ = new int[num_outbufs]; - databuf_ = new uint8_t*[num_outbufs]; - databuf_strides_ = new int[num_outbufs]; - - for (int i = 0; i < num_outbufs; ++i) { - scanlines_[i] = NULL; - scanlines_sizes_[i] = 0; - databuf_[i] = NULL; - databuf_strides_[i] = 0; - } - - num_outbufs_ = num_outbufs; - } -} - -void MJpegDecoder::DestroyOutputBuffers() { - for (int i = 0; i < num_outbufs_; ++i) { - delete[] scanlines_[i]; - delete[] databuf_[i]; - } - delete[] scanlines_; - delete[] databuf_; - delete[] scanlines_sizes_; - delete[] databuf_strides_; - scanlines_ = NULL; - databuf_ = NULL; - scanlines_sizes_ = NULL; - databuf_strides_ = NULL; - num_outbufs_ = 0; -} - -// JDCT_IFAST and do_block_smoothing improve performance substantially. -LIBYUV_BOOL MJpegDecoder::StartDecode() { - decompress_struct_->raw_data_out = TRUE; - decompress_struct_->dct_method = JDCT_IFAST; // JDCT_ISLOW is default - decompress_struct_->dither_mode = JDITHER_NONE; - // Not applicable to 'raw': - decompress_struct_->do_fancy_upsampling = (boolean)(LIBYUV_FALSE); - // Only for buffered mode: - decompress_struct_->enable_2pass_quant = (boolean)(LIBYUV_FALSE); - // Blocky but fast: - decompress_struct_->do_block_smoothing = (boolean)(LIBYUV_FALSE); - - if (!jpeg_start_decompress(decompress_struct_)) { - // ERROR: Couldn't start JPEG decompressor"; - return LIBYUV_FALSE; - } - return LIBYUV_TRUE; -} - -LIBYUV_BOOL MJpegDecoder::FinishDecode() { - // jpeglib considers it an error if we finish without decoding the whole - // image, so we call "abort" rather than "finish". - jpeg_abort_decompress(decompress_struct_); - return LIBYUV_TRUE; -} - -void MJpegDecoder::SetScanlinePointers(uint8_t** data) { - for (int i = 0; i < num_outbufs_; ++i) { - uint8_t* data_i = data[i]; - for (int j = 0; j < scanlines_sizes_[i]; ++j) { - scanlines_[i][j] = data_i; - data_i += GetComponentStride(i); - } - } -} - -inline LIBYUV_BOOL MJpegDecoder::DecodeImcuRow() { - return (unsigned int)(GetImageScanlinesPerImcuRow()) == - jpeg_read_raw_data(decompress_struct_, scanlines_, - GetImageScanlinesPerImcuRow()); -} - -// The helper function which recognizes the jpeg sub-sampling type. -JpegSubsamplingType MJpegDecoder::JpegSubsamplingTypeHelper( - int* subsample_x, - int* subsample_y, - int number_of_components) { - if (number_of_components == 3) { // Color images. - if (subsample_x[0] == 1 && subsample_y[0] == 1 && subsample_x[1] == 2 && - subsample_y[1] == 2 && subsample_x[2] == 2 && subsample_y[2] == 2) { - return kJpegYuv420; - } - if (subsample_x[0] == 1 && subsample_y[0] == 1 && subsample_x[1] == 2 && - subsample_y[1] == 1 && subsample_x[2] == 2 && subsample_y[2] == 1) { - return kJpegYuv422; - } - if (subsample_x[0] == 1 && subsample_y[0] == 1 && subsample_x[1] == 1 && - subsample_y[1] == 1 && subsample_x[2] == 1 && subsample_y[2] == 1) { - return kJpegYuv444; - } - } else if (number_of_components == 1) { // Grey-scale images. - if (subsample_x[0] == 1 && subsample_y[0] == 1) { - return kJpegYuv400; - } - } - return kJpegUnknown; -} - -} // namespace libyuv -#endif // HAVE_JPEG diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/mjpeg_validate.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/mjpeg_validate.cc deleted file mode 100644 index 80c2cc0c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/mjpeg_validate.cc +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2012 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/mjpeg_decoder.h" - -#include // For memchr. - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// Helper function to scan for EOI marker (0xff 0xd9). -static LIBYUV_BOOL ScanEOI(const uint8_t* sample, size_t sample_size) { - if (sample_size >= 2) { - const uint8_t* end = sample + sample_size - 1; - const uint8_t* it = sample; - while (it < end) { - // TODO(fbarchard): scan for 0xd9 instead. - it = (const uint8_t*)(memchr(it, 0xff, end - it)); - if (it == NULL) { - break; - } - if (it[1] == 0xd9) { - return LIBYUV_TRUE; // Success: Valid jpeg. - } - ++it; // Skip over current 0xff. - } - } - // ERROR: Invalid jpeg end code not found. Size sample_size - return LIBYUV_FALSE; -} - -// Helper function to validate the jpeg appears intact. -LIBYUV_BOOL ValidateJpeg(const uint8_t* sample, size_t sample_size) { - // Maximum size that ValidateJpeg will consider valid. - const size_t kMaxJpegSize = 0x7fffffffull; - const size_t kBackSearchSize = 1024; - if (sample_size < 64 || sample_size > kMaxJpegSize || !sample) { - // ERROR: Invalid jpeg size: sample_size - return LIBYUV_FALSE; - } - if (sample[0] != 0xff || sample[1] != 0xd8) { // SOI marker - // ERROR: Invalid jpeg initial start code - return LIBYUV_FALSE; - } - - // Look for the End Of Image (EOI) marker near the end of the buffer. - if (sample_size > kBackSearchSize) { - if (ScanEOI(sample + sample_size - kBackSearchSize, kBackSearchSize)) { - return LIBYUV_TRUE; // Success: Valid jpeg. - } - // Reduce search size for forward search. - sample_size = sample_size - kBackSearchSize + 1; - } - // Step over SOI marker and scan for EOI. - return ScanEOI(sample + 2, sample_size - 2); -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/planar_functions.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/planar_functions.cc deleted file mode 100644 index 5eae3f76..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/planar_functions.cc +++ /dev/null @@ -1,3587 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/planar_functions.h" - -#include // for memset() - -#include "libyuv/cpu_id.h" -#ifdef HAVE_JPEG -#include "libyuv/mjpeg_decoder.h" -#endif -#include "libyuv/row.h" -#include "libyuv/scale_row.h" // for ScaleRowDown2 - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// Copy a plane of data -LIBYUV_API -void CopyPlane(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height) { - int y; - void (*CopyRow)(const uint8_t* src, uint8_t* dst, int width) = CopyRow_C; - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_y = dst_y + (height - 1) * dst_stride_y; - dst_stride_y = -dst_stride_y; - } - // Coalesce rows. - if (src_stride_y == width && dst_stride_y == width) { - width *= height; - height = 1; - src_stride_y = dst_stride_y = 0; - } - // Nothing to do. - if (src_y == dst_y && src_stride_y == dst_stride_y) { - return; - } - -#if defined(HAS_COPYROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - CopyRow = IS_ALIGNED(width, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2; - } -#endif -#if defined(HAS_COPYROW_AVX) - if (TestCpuFlag(kCpuHasAVX)) { - CopyRow = IS_ALIGNED(width, 64) ? CopyRow_AVX : CopyRow_Any_AVX; - } -#endif -#if defined(HAS_COPYROW_ERMS) - if (TestCpuFlag(kCpuHasERMS)) { - CopyRow = CopyRow_ERMS; - } -#endif -#if defined(HAS_COPYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - CopyRow = IS_ALIGNED(width, 32) ? CopyRow_NEON : CopyRow_Any_NEON; - } -#endif - - // Copy plane - for (y = 0; y < height; ++y) { - CopyRow(src_y, dst_y, width); - src_y += src_stride_y; - dst_y += dst_stride_y; - } -} - -// TODO(fbarchard): Consider support for negative height. -// TODO(fbarchard): Consider stride measured in bytes. -LIBYUV_API -void CopyPlane_16(const uint16_t* src_y, - int src_stride_y, - uint16_t* dst_y, - int dst_stride_y, - int width, - int height) { - int y; - void (*CopyRow)(const uint16_t* src, uint16_t* dst, int width) = CopyRow_16_C; - // Coalesce rows. - if (src_stride_y == width && dst_stride_y == width) { - width *= height; - height = 1; - src_stride_y = dst_stride_y = 0; - } -#if defined(HAS_COPYROW_16_SSE2) - if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 32)) { - CopyRow = CopyRow_16_SSE2; - } -#endif -#if defined(HAS_COPYROW_16_ERMS) - if (TestCpuFlag(kCpuHasERMS)) { - CopyRow = CopyRow_16_ERMS; - } -#endif -#if defined(HAS_COPYROW_16_NEON) - if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 32)) { - CopyRow = CopyRow_16_NEON; - } -#endif - - // Copy plane - for (y = 0; y < height; ++y) { - CopyRow(src_y, dst_y, width); - src_y += src_stride_y; - dst_y += dst_stride_y; - } -} - -// Convert a plane of 16 bit data to 8 bit -LIBYUV_API -void Convert16To8Plane(const uint16_t* src_y, - int src_stride_y, - uint8_t* dst_y, - int dst_stride_y, - int scale, // 16384 for 10 bits - int width, - int height) { - int y; - void (*Convert16To8Row)(const uint16_t* src_y, uint8_t* dst_y, int scale, - int width) = Convert16To8Row_C; - - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_y = dst_y + (height - 1) * dst_stride_y; - dst_stride_y = -dst_stride_y; - } - // Coalesce rows. - if (src_stride_y == width && dst_stride_y == width) { - width *= height; - height = 1; - src_stride_y = dst_stride_y = 0; - } -#if defined(HAS_CONVERT16TO8ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - Convert16To8Row = Convert16To8Row_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - Convert16To8Row = Convert16To8Row_SSSE3; - } - } -#endif -#if defined(HAS_CONVERT16TO8ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - Convert16To8Row = Convert16To8Row_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - Convert16To8Row = Convert16To8Row_AVX2; - } - } -#endif - - // Convert plane - for (y = 0; y < height; ++y) { - Convert16To8Row(src_y, dst_y, scale, width); - src_y += src_stride_y; - dst_y += dst_stride_y; - } -} - -// Convert a plane of 8 bit data to 16 bit -LIBYUV_API -void Convert8To16Plane(const uint8_t* src_y, - int src_stride_y, - uint16_t* dst_y, - int dst_stride_y, - int scale, // 16384 for 10 bits - int width, - int height) { - int y; - void (*Convert8To16Row)(const uint8_t* src_y, uint16_t* dst_y, int scale, - int width) = Convert8To16Row_C; - - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_y = dst_y + (height - 1) * dst_stride_y; - dst_stride_y = -dst_stride_y; - } - // Coalesce rows. - if (src_stride_y == width && dst_stride_y == width) { - width *= height; - height = 1; - src_stride_y = dst_stride_y = 0; - } -#if defined(HAS_CONVERT8TO16ROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - Convert8To16Row = Convert8To16Row_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - Convert8To16Row = Convert8To16Row_SSE2; - } - } -#endif -#if defined(HAS_CONVERT8TO16ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - Convert8To16Row = Convert8To16Row_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - Convert8To16Row = Convert8To16Row_AVX2; - } - } -#endif - - // Convert plane - for (y = 0; y < height; ++y) { - Convert8To16Row(src_y, dst_y, scale, width); - src_y += src_stride_y; - dst_y += dst_stride_y; - } -} - -// Copy I422. -LIBYUV_API -int I422Copy(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int halfwidth = (width + 1) >> 1; - if (!src_u || !src_v || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_y = src_y + (height - 1) * src_stride_y; - src_u = src_u + (height - 1) * src_stride_u; - src_v = src_v + (height - 1) * src_stride_v; - src_stride_y = -src_stride_y; - src_stride_u = -src_stride_u; - src_stride_v = -src_stride_v; - } - - if (dst_y) { - CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - } - CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, height); - CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, height); - return 0; -} - -// Copy I444. -LIBYUV_API -int I444Copy(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - if (!src_u || !src_v || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_y = src_y + (height - 1) * src_stride_y; - src_u = src_u + (height - 1) * src_stride_u; - src_v = src_v + (height - 1) * src_stride_v; - src_stride_y = -src_stride_y; - src_stride_u = -src_stride_u; - src_stride_v = -src_stride_v; - } - - if (dst_y) { - CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - } - CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, width, height); - CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, width, height); - return 0; -} - -// Copy I400. -LIBYUV_API -int I400ToI400(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height) { - if (!src_y || !dst_y || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_y = src_y + (height - 1) * src_stride_y; - src_stride_y = -src_stride_y; - } - CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - return 0; -} - -// Convert I420 to I400. -LIBYUV_API -int I420ToI400(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height) { - (void)src_u; - (void)src_stride_u; - (void)src_v; - (void)src_stride_v; - if (!src_y || !dst_y || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_y = src_y + (height - 1) * src_stride_y; - src_stride_y = -src_stride_y; - } - - CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - return 0; -} - -// Support function for NV12 etc UV channels. -// Width and height are plane sizes (typically half pixel width). -LIBYUV_API -void SplitUVPlane(const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; - void (*SplitUVRow)(const uint8_t* src_uv, uint8_t* dst_u, uint8_t* dst_v, - int width) = SplitUVRow_C; - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_u = dst_u + (height - 1) * dst_stride_u; - dst_v = dst_v + (height - 1) * dst_stride_v; - dst_stride_u = -dst_stride_u; - dst_stride_v = -dst_stride_v; - } - // Coalesce rows. - if (src_stride_uv == width * 2 && dst_stride_u == width && - dst_stride_v == width) { - width *= height; - height = 1; - src_stride_uv = dst_stride_u = dst_stride_v = 0; - } -#if defined(HAS_SPLITUVROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - SplitUVRow = SplitUVRow_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - SplitUVRow = SplitUVRow_SSE2; - } - } -#endif -#if defined(HAS_SPLITUVROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - SplitUVRow = SplitUVRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - SplitUVRow = SplitUVRow_AVX2; - } - } -#endif -#if defined(HAS_SPLITUVROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - SplitUVRow = SplitUVRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - SplitUVRow = SplitUVRow_NEON; - } - } -#endif -#if defined(HAS_SPLITUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SplitUVRow = SplitUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - SplitUVRow = SplitUVRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - // Copy a row of UV. - SplitUVRow(src_uv, dst_u, dst_v, width); - dst_u += dst_stride_u; - dst_v += dst_stride_v; - src_uv += src_stride_uv; - } -} - -LIBYUV_API -void MergeUVPlane(const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_uv, - int dst_stride_uv, - int width, - int height) { - int y; - void (*MergeUVRow)(const uint8_t* src_u, const uint8_t* src_v, - uint8_t* dst_uv, int width) = MergeUVRow_C; - // Coalesce rows. - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_uv = dst_uv + (height - 1) * dst_stride_uv; - dst_stride_uv = -dst_stride_uv; - } - // Coalesce rows. - if (src_stride_u == width && src_stride_v == width && - dst_stride_uv == width * 2) { - width *= height; - height = 1; - src_stride_u = src_stride_v = dst_stride_uv = 0; - } -#if defined(HAS_MERGEUVROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - MergeUVRow = MergeUVRow_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - MergeUVRow = MergeUVRow_SSE2; - } - } -#endif -#if defined(HAS_MERGEUVROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - MergeUVRow = MergeUVRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - MergeUVRow = MergeUVRow_AVX2; - } - } -#endif -#if defined(HAS_MERGEUVROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - MergeUVRow = MergeUVRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - MergeUVRow = MergeUVRow_NEON; - } - } -#endif -#if defined(HAS_MERGEUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - MergeUVRow = MergeUVRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - MergeUVRow = MergeUVRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - // Merge a row of U and V into a row of UV. - MergeUVRow(src_u, src_v, dst_uv, width); - src_u += src_stride_u; - src_v += src_stride_v; - dst_uv += dst_stride_uv; - } -} - -// Support function for NV12 etc RGB channels. -// Width and height are plane sizes (typically half pixel width). -LIBYUV_API -void SplitRGBPlane(const uint8_t* src_rgb, - int src_stride_rgb, - uint8_t* dst_r, - int dst_stride_r, - uint8_t* dst_g, - int dst_stride_g, - uint8_t* dst_b, - int dst_stride_b, - int width, - int height) { - int y; - void (*SplitRGBRow)(const uint8_t* src_rgb, uint8_t* dst_r, uint8_t* dst_g, - uint8_t* dst_b, int width) = SplitRGBRow_C; - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_r = dst_r + (height - 1) * dst_stride_r; - dst_g = dst_g + (height - 1) * dst_stride_g; - dst_b = dst_b + (height - 1) * dst_stride_b; - dst_stride_r = -dst_stride_r; - dst_stride_g = -dst_stride_g; - dst_stride_b = -dst_stride_b; - } - // Coalesce rows. - if (src_stride_rgb == width * 3 && dst_stride_r == width && - dst_stride_g == width && dst_stride_b == width) { - width *= height; - height = 1; - src_stride_rgb = dst_stride_r = dst_stride_g = dst_stride_b = 0; - } -#if defined(HAS_SPLITRGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - SplitRGBRow = SplitRGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - SplitRGBRow = SplitRGBRow_SSSE3; - } - } -#endif -#if defined(HAS_SPLITRGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - SplitRGBRow = SplitRGBRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - SplitRGBRow = SplitRGBRow_NEON; - } - } -#endif - - for (y = 0; y < height; ++y) { - // Copy a row of RGB. - SplitRGBRow(src_rgb, dst_r, dst_g, dst_b, width); - dst_r += dst_stride_r; - dst_g += dst_stride_g; - dst_b += dst_stride_b; - src_rgb += src_stride_rgb; - } -} - -LIBYUV_API -void MergeRGBPlane(const uint8_t* src_r, - int src_stride_r, - const uint8_t* src_g, - int src_stride_g, - const uint8_t* src_b, - int src_stride_b, - uint8_t* dst_rgb, - int dst_stride_rgb, - int width, - int height) { - int y; - void (*MergeRGBRow)(const uint8_t* src_r, const uint8_t* src_g, - const uint8_t* src_b, uint8_t* dst_rgb, int width) = - MergeRGBRow_C; - // Coalesce rows. - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_rgb = dst_rgb + (height - 1) * dst_stride_rgb; - dst_stride_rgb = -dst_stride_rgb; - } - // Coalesce rows. - if (src_stride_r == width && src_stride_g == width && src_stride_b == width && - dst_stride_rgb == width * 3) { - width *= height; - height = 1; - src_stride_r = src_stride_g = src_stride_b = dst_stride_rgb = 0; - } -#if defined(HAS_MERGERGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - MergeRGBRow = MergeRGBRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - MergeRGBRow = MergeRGBRow_SSSE3; - } - } -#endif -#if defined(HAS_MERGERGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - MergeRGBRow = MergeRGBRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - MergeRGBRow = MergeRGBRow_NEON; - } - } -#endif - - for (y = 0; y < height; ++y) { - // Merge a row of U and V into a row of RGB. - MergeRGBRow(src_r, src_g, src_b, dst_rgb, width); - src_r += src_stride_r; - src_g += src_stride_g; - src_b += src_stride_b; - dst_rgb += dst_stride_rgb; - } -} - -// Mirror a plane of data. -void MirrorPlane(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height) { - int y; - void (*MirrorRow)(const uint8_t* src, uint8_t* dst, int width) = MirrorRow_C; - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_y = src_y + (height - 1) * src_stride_y; - src_stride_y = -src_stride_y; - } -#if defined(HAS_MIRRORROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - MirrorRow = MirrorRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - MirrorRow = MirrorRow_NEON; - } - } -#endif -#if defined(HAS_MIRRORROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - MirrorRow = MirrorRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - MirrorRow = MirrorRow_SSSE3; - } - } -#endif -#if defined(HAS_MIRRORROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - MirrorRow = MirrorRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - MirrorRow = MirrorRow_AVX2; - } - } -#endif -#if defined(HAS_MIRRORROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - MirrorRow = MirrorRow_Any_MSA; - if (IS_ALIGNED(width, 64)) { - MirrorRow = MirrorRow_MSA; - } - } -#endif - - // Mirror plane - for (y = 0; y < height; ++y) { - MirrorRow(src_y, dst_y, width); - src_y += src_stride_y; - dst_y += dst_stride_y; - } -} - -// Convert YUY2 to I422. -LIBYUV_API -int YUY2ToI422(const uint8_t* src_yuy2, - int src_stride_yuy2, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; - void (*YUY2ToUV422Row)(const uint8_t* src_yuy2, uint8_t* dst_u, - uint8_t* dst_v, int width) = YUY2ToUV422Row_C; - void (*YUY2ToYRow)(const uint8_t* src_yuy2, uint8_t* dst_y, int width) = - YUY2ToYRow_C; - if (!src_yuy2 || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2; - src_stride_yuy2 = -src_stride_yuy2; - } - // Coalesce rows. - if (src_stride_yuy2 == width * 2 && dst_stride_y == width && - dst_stride_u * 2 == width && dst_stride_v * 2 == width && - width * height <= 32768) { - width *= height; - height = 1; - src_stride_yuy2 = dst_stride_y = dst_stride_u = dst_stride_v = 0; - } -#if defined(HAS_YUY2TOYROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - YUY2ToUV422Row = YUY2ToUV422Row_Any_SSE2; - YUY2ToYRow = YUY2ToYRow_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - YUY2ToUV422Row = YUY2ToUV422Row_SSE2; - YUY2ToYRow = YUY2ToYRow_SSE2; - } - } -#endif -#if defined(HAS_YUY2TOYROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - YUY2ToUV422Row = YUY2ToUV422Row_Any_AVX2; - YUY2ToYRow = YUY2ToYRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - YUY2ToUV422Row = YUY2ToUV422Row_AVX2; - YUY2ToYRow = YUY2ToYRow_AVX2; - } - } -#endif -#if defined(HAS_YUY2TOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - YUY2ToYRow = YUY2ToYRow_Any_NEON; - YUY2ToUV422Row = YUY2ToUV422Row_Any_NEON; - if (IS_ALIGNED(width, 16)) { - YUY2ToYRow = YUY2ToYRow_NEON; - YUY2ToUV422Row = YUY2ToUV422Row_NEON; - } - } -#endif -#if defined(HAS_YUY2TOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - YUY2ToYRow = YUY2ToYRow_Any_MSA; - YUY2ToUV422Row = YUY2ToUV422Row_Any_MSA; - if (IS_ALIGNED(width, 32)) { - YUY2ToYRow = YUY2ToYRow_MSA; - YUY2ToUV422Row = YUY2ToUV422Row_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - YUY2ToUV422Row(src_yuy2, dst_u, dst_v, width); - YUY2ToYRow(src_yuy2, dst_y, width); - src_yuy2 += src_stride_yuy2; - dst_y += dst_stride_y; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - return 0; -} - -// Convert UYVY to I422. -LIBYUV_API -int UYVYToI422(const uint8_t* src_uyvy, - int src_stride_uyvy, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; - void (*UYVYToUV422Row)(const uint8_t* src_uyvy, uint8_t* dst_u, - uint8_t* dst_v, int width) = UYVYToUV422Row_C; - void (*UYVYToYRow)(const uint8_t* src_uyvy, uint8_t* dst_y, int width) = - UYVYToYRow_C; - if (!src_uyvy || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy; - src_stride_uyvy = -src_stride_uyvy; - } - // Coalesce rows. - if (src_stride_uyvy == width * 2 && dst_stride_y == width && - dst_stride_u * 2 == width && dst_stride_v * 2 == width && - width * height <= 32768) { - width *= height; - height = 1; - src_stride_uyvy = dst_stride_y = dst_stride_u = dst_stride_v = 0; - } -#if defined(HAS_UYVYTOYROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - UYVYToUV422Row = UYVYToUV422Row_Any_SSE2; - UYVYToYRow = UYVYToYRow_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - UYVYToUV422Row = UYVYToUV422Row_SSE2; - UYVYToYRow = UYVYToYRow_SSE2; - } - } -#endif -#if defined(HAS_UYVYTOYROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - UYVYToUV422Row = UYVYToUV422Row_Any_AVX2; - UYVYToYRow = UYVYToYRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - UYVYToUV422Row = UYVYToUV422Row_AVX2; - UYVYToYRow = UYVYToYRow_AVX2; - } - } -#endif -#if defined(HAS_UYVYTOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - UYVYToYRow = UYVYToYRow_Any_NEON; - UYVYToUV422Row = UYVYToUV422Row_Any_NEON; - if (IS_ALIGNED(width, 16)) { - UYVYToYRow = UYVYToYRow_NEON; - UYVYToUV422Row = UYVYToUV422Row_NEON; - } - } -#endif -#if defined(HAS_UYVYTOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - UYVYToYRow = UYVYToYRow_Any_MSA; - UYVYToUV422Row = UYVYToUV422Row_Any_MSA; - if (IS_ALIGNED(width, 32)) { - UYVYToYRow = UYVYToYRow_MSA; - UYVYToUV422Row = UYVYToUV422Row_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - UYVYToUV422Row(src_uyvy, dst_u, dst_v, width); - UYVYToYRow(src_uyvy, dst_y, width); - src_uyvy += src_stride_uyvy; - dst_y += dst_stride_y; - dst_u += dst_stride_u; - dst_v += dst_stride_v; - } - return 0; -} - -// Convert YUY2 to Y. -LIBYUV_API -int YUY2ToY(const uint8_t* src_yuy2, - int src_stride_yuy2, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height) { - int y; - void (*YUY2ToYRow)(const uint8_t* src_yuy2, uint8_t* dst_y, int width) = - YUY2ToYRow_C; - if (!src_yuy2 || !dst_y || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2; - src_stride_yuy2 = -src_stride_yuy2; - } - // Coalesce rows. - if (src_stride_yuy2 == width * 2 && dst_stride_y == width) { - width *= height; - height = 1; - src_stride_yuy2 = dst_stride_y = 0; - } -#if defined(HAS_YUY2TOYROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - YUY2ToYRow = YUY2ToYRow_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - YUY2ToYRow = YUY2ToYRow_SSE2; - } - } -#endif -#if defined(HAS_YUY2TOYROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - YUY2ToYRow = YUY2ToYRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - YUY2ToYRow = YUY2ToYRow_AVX2; - } - } -#endif -#if defined(HAS_YUY2TOYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - YUY2ToYRow = YUY2ToYRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - YUY2ToYRow = YUY2ToYRow_NEON; - } - } -#endif -#if defined(HAS_YUY2TOYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - YUY2ToYRow = YUY2ToYRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - YUY2ToYRow = YUY2ToYRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - YUY2ToYRow(src_yuy2, dst_y, width); - src_yuy2 += src_stride_yuy2; - dst_y += dst_stride_y; - } - return 0; -} - -// Mirror I400 with optional flipping -LIBYUV_API -int I400Mirror(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height) { - if (!src_y || !dst_y || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_y = src_y + (height - 1) * src_stride_y; - src_stride_y = -src_stride_y; - } - - MirrorPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - return 0; -} - -// Mirror I420 with optional flipping -LIBYUV_API -int I420Mirror(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - if (!src_y || !src_u || !src_v || !dst_y || !dst_u || !dst_v || width <= 0 || - height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - halfheight = (height + 1) >> 1; - src_y = src_y + (height - 1) * src_stride_y; - src_u = src_u + (halfheight - 1) * src_stride_u; - src_v = src_v + (halfheight - 1) * src_stride_v; - src_stride_y = -src_stride_y; - src_stride_u = -src_stride_u; - src_stride_v = -src_stride_v; - } - - if (dst_y) { - MirrorPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - } - MirrorPlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, halfheight); - MirrorPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, halfheight); - return 0; -} - -// ARGB mirror. -LIBYUV_API -int ARGBMirror(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*ARGBMirrorRow)(const uint8_t* src, uint8_t* dst, int width) = - ARGBMirrorRow_C; - if (!src_argb || !dst_argb || 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; - src_stride_argb = -src_stride_argb; - } -#if defined(HAS_ARGBMIRRORROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBMirrorRow = ARGBMirrorRow_Any_NEON; - if (IS_ALIGNED(width, 4)) { - ARGBMirrorRow = ARGBMirrorRow_NEON; - } - } -#endif -#if defined(HAS_ARGBMIRRORROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGBMirrorRow = ARGBMirrorRow_Any_SSE2; - if (IS_ALIGNED(width, 4)) { - ARGBMirrorRow = ARGBMirrorRow_SSE2; - } - } -#endif -#if defined(HAS_ARGBMIRRORROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBMirrorRow = ARGBMirrorRow_Any_AVX2; - if (IS_ALIGNED(width, 8)) { - ARGBMirrorRow = ARGBMirrorRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBMIRRORROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBMirrorRow = ARGBMirrorRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBMirrorRow = ARGBMirrorRow_MSA; - } - } -#endif - - // Mirror plane - for (y = 0; y < height; ++y) { - ARGBMirrorRow(src_argb, dst_argb, width); - src_argb += src_stride_argb; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Get a blender that optimized for the CPU and pixel count. -// As there are 6 blenders to choose from, the caller should try to use -// the same blend function for all pixels if possible. -LIBYUV_API -ARGBBlendRow GetARGBBlend() { - void (*ARGBBlendRow)(const uint8_t* src_argb, const uint8_t* src_argb1, - uint8_t* dst_argb, int width) = ARGBBlendRow_C; -#if defined(HAS_ARGBBLENDROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - ARGBBlendRow = ARGBBlendRow_SSSE3; - return ARGBBlendRow; - } -#endif -#if defined(HAS_ARGBBLENDROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBBlendRow = ARGBBlendRow_NEON; - } -#endif -#if defined(HAS_ARGBBLENDROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBBlendRow = ARGBBlendRow_MSA; - } -#endif - return ARGBBlendRow; -} - -// Alpha Blend 2 ARGB images and store to destination. -LIBYUV_API -int ARGBBlend(const uint8_t* src_argb0, - int src_stride_argb0, - const uint8_t* src_argb1, - int src_stride_argb1, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*ARGBBlendRow)(const uint8_t* src_argb, const uint8_t* src_argb1, - uint8_t* dst_argb, int width) = GetARGBBlend(); - if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb = dst_argb + (height - 1) * dst_stride_argb; - dst_stride_argb = -dst_stride_argb; - } - // Coalesce rows. - if (src_stride_argb0 == width * 4 && src_stride_argb1 == width * 4 && - dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0; - } - - for (y = 0; y < height; ++y) { - ARGBBlendRow(src_argb0, src_argb1, dst_argb, width); - src_argb0 += src_stride_argb0; - src_argb1 += src_stride_argb1; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Alpha Blend plane and store to destination. -LIBYUV_API -int BlendPlane(const uint8_t* src_y0, - int src_stride_y0, - const uint8_t* src_y1, - int src_stride_y1, - const uint8_t* alpha, - int alpha_stride, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height) { - int y; - void (*BlendPlaneRow)(const uint8_t* src0, const uint8_t* src1, - const uint8_t* alpha, uint8_t* dst, int width) = - BlendPlaneRow_C; - if (!src_y0 || !src_y1 || !alpha || !dst_y || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_y = dst_y + (height - 1) * dst_stride_y; - dst_stride_y = -dst_stride_y; - } - - // Coalesce rows for Y plane. - if (src_stride_y0 == width && src_stride_y1 == width && - alpha_stride == width && dst_stride_y == width) { - width *= height; - height = 1; - src_stride_y0 = src_stride_y1 = alpha_stride = dst_stride_y = 0; - } - -#if defined(HAS_BLENDPLANEROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - BlendPlaneRow = BlendPlaneRow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - BlendPlaneRow = BlendPlaneRow_SSSE3; - } - } -#endif -#if defined(HAS_BLENDPLANEROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - BlendPlaneRow = BlendPlaneRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - BlendPlaneRow = BlendPlaneRow_AVX2; - } - } -#endif - - for (y = 0; y < height; ++y) { - BlendPlaneRow(src_y0, src_y1, alpha, dst_y, width); - src_y0 += src_stride_y0; - src_y1 += src_stride_y1; - alpha += alpha_stride; - dst_y += dst_stride_y; - } - return 0; -} - -#define MAXTWIDTH 2048 -// Alpha Blend YUV images and store to destination. -LIBYUV_API -int I420Blend(const uint8_t* src_y0, - int src_stride_y0, - const uint8_t* src_u0, - int src_stride_u0, - const uint8_t* src_v0, - int src_stride_v0, - const uint8_t* src_y1, - int src_stride_y1, - const uint8_t* src_u1, - int src_stride_u1, - const uint8_t* src_v1, - int src_stride_v1, - const uint8_t* alpha, - int alpha_stride, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height) { - int y; - // Half width/height for UV. - int halfwidth = (width + 1) >> 1; - void (*BlendPlaneRow)(const uint8_t* src0, const uint8_t* src1, - const uint8_t* alpha, uint8_t* dst, int width) = - BlendPlaneRow_C; - void (*ScaleRowDown2)(const uint8_t* src_ptr, ptrdiff_t src_stride, - uint8_t* dst_ptr, int dst_width) = ScaleRowDown2Box_C; - if (!src_y0 || !src_u0 || !src_v0 || !src_y1 || !src_u1 || !src_v1 || - !alpha || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_y = dst_y + (height - 1) * dst_stride_y; - dst_stride_y = -dst_stride_y; - } - - // Blend Y plane. - BlendPlane(src_y0, src_stride_y0, src_y1, src_stride_y1, alpha, alpha_stride, - dst_y, dst_stride_y, width, height); - -#if defined(HAS_BLENDPLANEROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - BlendPlaneRow = BlendPlaneRow_Any_SSSE3; - if (IS_ALIGNED(halfwidth, 8)) { - BlendPlaneRow = BlendPlaneRow_SSSE3; - } - } -#endif -#if defined(HAS_BLENDPLANEROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - 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_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_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_Odd_AVX2; - if (IS_ALIGNED(width, 2)) { - ScaleRowDown2 = ScaleRowDown2Box_Any_AVX2; - if (IS_ALIGNED(halfwidth, 32)) { - ScaleRowDown2 = ScaleRowDown2Box_AVX2; - } - } - } -#endif - - // Row buffer for intermediate alpha pixels. - align_buffer_64(halfalpha, halfwidth); - for (y = 0; y < height; y += 2) { - // last row of odd height image use 1 row of alpha instead of 2. - if (y == (height - 1)) { - alpha_stride = 0; - } - // Subsample 2 rows of UV to half width and half height. - ScaleRowDown2(alpha, alpha_stride, halfalpha, halfwidth); - alpha += alpha_stride * 2; - BlendPlaneRow(src_u0, src_u1, halfalpha, dst_u, halfwidth); - BlendPlaneRow(src_v0, src_v1, halfalpha, dst_v, halfwidth); - src_u0 += src_stride_u0; - src_u1 += src_stride_u1; - dst_u += dst_stride_u; - src_v0 += src_stride_v0; - src_v1 += src_stride_v1; - dst_v += dst_stride_v; - } - free_aligned_buffer_64(halfalpha); - return 0; -} - -// Multiply 2 ARGB images and store to destination. -LIBYUV_API -int ARGBMultiply(const uint8_t* src_argb0, - int src_stride_argb0, - const uint8_t* src_argb1, - int src_stride_argb1, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*ARGBMultiplyRow)(const uint8_t* src0, const uint8_t* src1, - uint8_t* dst, int width) = ARGBMultiplyRow_C; - if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb = dst_argb + (height - 1) * dst_stride_argb; - dst_stride_argb = -dst_stride_argb; - } - // Coalesce rows. - if (src_stride_argb0 == width * 4 && src_stride_argb1 == width * 4 && - dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0; - } -#if defined(HAS_ARGBMULTIPLYROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGBMultiplyRow = ARGBMultiplyRow_Any_SSE2; - if (IS_ALIGNED(width, 4)) { - ARGBMultiplyRow = ARGBMultiplyRow_SSE2; - } - } -#endif -#if defined(HAS_ARGBMULTIPLYROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBMultiplyRow = ARGBMultiplyRow_Any_AVX2; - if (IS_ALIGNED(width, 8)) { - ARGBMultiplyRow = ARGBMultiplyRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBMULTIPLYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBMultiplyRow = ARGBMultiplyRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBMultiplyRow = ARGBMultiplyRow_NEON; - } - } -#endif -#if defined(HAS_ARGBMULTIPLYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBMultiplyRow = ARGBMultiplyRow_Any_MSA; - if (IS_ALIGNED(width, 4)) { - ARGBMultiplyRow = ARGBMultiplyRow_MSA; - } - } -#endif - - // Multiply plane - for (y = 0; y < height; ++y) { - ARGBMultiplyRow(src_argb0, src_argb1, dst_argb, width); - src_argb0 += src_stride_argb0; - src_argb1 += src_stride_argb1; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Add 2 ARGB images and store to destination. -LIBYUV_API -int ARGBAdd(const uint8_t* src_argb0, - int src_stride_argb0, - const uint8_t* src_argb1, - int src_stride_argb1, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*ARGBAddRow)(const uint8_t* src0, const uint8_t* src1, uint8_t* dst, - int width) = ARGBAddRow_C; - if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb = dst_argb + (height - 1) * dst_stride_argb; - dst_stride_argb = -dst_stride_argb; - } - // Coalesce rows. - if (src_stride_argb0 == width * 4 && src_stride_argb1 == width * 4 && - dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0; - } -#if defined(HAS_ARGBADDROW_SSE2) && (defined(_MSC_VER) && !defined(__clang__)) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGBAddRow = ARGBAddRow_SSE2; - } -#endif -#if defined(HAS_ARGBADDROW_SSE2) && !(defined(_MSC_VER) && !defined(__clang__)) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGBAddRow = ARGBAddRow_Any_SSE2; - if (IS_ALIGNED(width, 4)) { - ARGBAddRow = ARGBAddRow_SSE2; - } - } -#endif -#if defined(HAS_ARGBADDROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBAddRow = ARGBAddRow_Any_AVX2; - if (IS_ALIGNED(width, 8)) { - ARGBAddRow = ARGBAddRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBADDROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBAddRow = ARGBAddRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBAddRow = ARGBAddRow_NEON; - } - } -#endif -#if defined(HAS_ARGBADDROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBAddRow = ARGBAddRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBAddRow = ARGBAddRow_MSA; - } - } -#endif - - // Add plane - for (y = 0; y < height; ++y) { - ARGBAddRow(src_argb0, src_argb1, dst_argb, width); - src_argb0 += src_stride_argb0; - src_argb1 += src_stride_argb1; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Subtract 2 ARGB images and store to destination. -LIBYUV_API -int ARGBSubtract(const uint8_t* src_argb0, - int src_stride_argb0, - const uint8_t* src_argb1, - int src_stride_argb1, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*ARGBSubtractRow)(const uint8_t* src0, const uint8_t* src1, - uint8_t* dst, int width) = ARGBSubtractRow_C; - if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_argb = dst_argb + (height - 1) * dst_stride_argb; - dst_stride_argb = -dst_stride_argb; - } - // Coalesce rows. - if (src_stride_argb0 == width * 4 && src_stride_argb1 == width * 4 && - dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0; - } -#if defined(HAS_ARGBSUBTRACTROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGBSubtractRow = ARGBSubtractRow_Any_SSE2; - if (IS_ALIGNED(width, 4)) { - ARGBSubtractRow = ARGBSubtractRow_SSE2; - } - } -#endif -#if defined(HAS_ARGBSUBTRACTROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBSubtractRow = ARGBSubtractRow_Any_AVX2; - if (IS_ALIGNED(width, 8)) { - ARGBSubtractRow = ARGBSubtractRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBSUBTRACTROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBSubtractRow = ARGBSubtractRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBSubtractRow = ARGBSubtractRow_NEON; - } - } -#endif -#if defined(HAS_ARGBSUBTRACTROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBSubtractRow = ARGBSubtractRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBSubtractRow = ARGBSubtractRow_MSA; - } - } -#endif - - // Subtract plane - for (y = 0; y < height; ++y) { - ARGBSubtractRow(src_argb0, src_argb1, dst_argb, width); - src_argb0 += src_stride_argb0; - src_argb1 += src_stride_argb1; - dst_argb += dst_stride_argb; - } - return 0; -} -// Convert I422 to RGBA with matrix -static int I422ToRGBAMatrix(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgba, - int dst_stride_rgba, - const struct YuvConstants* yuvconstants, - int width, - int height) { - int y; - void (*I422ToRGBARow)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = - I422ToRGBARow_C; - if (!src_y || !src_u || !src_v || !dst_rgba || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_rgba = dst_rgba + (height - 1) * dst_stride_rgba; - dst_stride_rgba = -dst_stride_rgba; - } -#if defined(HAS_I422TORGBAROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToRGBARow = I422ToRGBARow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - I422ToRGBARow = I422ToRGBARow_SSSE3; - } - } -#endif -#if defined(HAS_I422TORGBAROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToRGBARow = I422ToRGBARow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - I422ToRGBARow = I422ToRGBARow_AVX2; - } - } -#endif -#if defined(HAS_I422TORGBAROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToRGBARow = I422ToRGBARow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - I422ToRGBARow = I422ToRGBARow_NEON; - } - } -#endif -#if defined(HAS_I422TORGBAROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToRGBARow = I422ToRGBARow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - I422ToRGBARow = I422ToRGBARow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - I422ToRGBARow(src_y, src_u, src_v, dst_rgba, yuvconstants, width); - dst_rgba += dst_stride_rgba; - src_y += src_stride_y; - src_u += src_stride_u; - src_v += src_stride_v; - } - return 0; -} - -// Convert I422 to RGBA. -LIBYUV_API -int I422ToRGBA(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_rgba, - int dst_stride_rgba, - int width, - int height) { - return I422ToRGBAMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_rgba, dst_stride_rgba, - &kYuvI601Constants, width, height); -} - -// Convert I422 to BGRA. -LIBYUV_API -int I422ToBGRA(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_bgra, - int dst_stride_bgra, - int width, - int height) { - return I422ToRGBAMatrix(src_y, src_stride_y, src_v, - src_stride_v, // Swap U and V - src_u, src_stride_u, dst_bgra, dst_stride_bgra, - &kYvuI601Constants, // Use Yvu matrix - width, height); -} - -// Convert NV12 to RGB565. -LIBYUV_API -int NV12ToRGB565(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_rgb565, - int dst_stride_rgb565, - int width, - int height) { - int y; - void (*NV12ToRGB565Row)( - const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, int width) = NV12ToRGB565Row_C; - if (!src_y || !src_uv || !dst_rgb565 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565; - dst_stride_rgb565 = -dst_stride_rgb565; - } -#if defined(HAS_NV12TORGB565ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - NV12ToRGB565Row = NV12ToRGB565Row_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - NV12ToRGB565Row = NV12ToRGB565Row_SSSE3; - } - } -#endif -#if defined(HAS_NV12TORGB565ROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - NV12ToRGB565Row = NV12ToRGB565Row_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - NV12ToRGB565Row = NV12ToRGB565Row_AVX2; - } - } -#endif -#if defined(HAS_NV12TORGB565ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - NV12ToRGB565Row = NV12ToRGB565Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - NV12ToRGB565Row = NV12ToRGB565Row_NEON; - } - } -#endif -#if defined(HAS_NV12TORGB565ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - NV12ToRGB565Row = NV12ToRGB565Row_Any_MSA; - if (IS_ALIGNED(width, 8)) { - NV12ToRGB565Row = NV12ToRGB565Row_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - NV12ToRGB565Row(src_y, src_uv, dst_rgb565, &kYuvI601Constants, width); - dst_rgb565 += dst_stride_rgb565; - src_y += src_stride_y; - if (y & 1) { - src_uv += src_stride_uv; - } - } - return 0; -} - -// Convert RAW to RGB24. -LIBYUV_API -int RAWToRGB24(const uint8_t* src_raw, - int src_stride_raw, - uint8_t* dst_rgb24, - int dst_stride_rgb24, - int width, - int height) { - int y; - void (*RAWToRGB24Row)(const uint8_t* src_rgb, uint8_t* dst_rgb24, int width) = - RAWToRGB24Row_C; - if (!src_raw || !dst_rgb24 || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_raw = src_raw + (height - 1) * src_stride_raw; - src_stride_raw = -src_stride_raw; - } - // Coalesce rows. - if (src_stride_raw == width * 3 && dst_stride_rgb24 == width * 3) { - width *= height; - height = 1; - src_stride_raw = dst_stride_rgb24 = 0; - } -#if defined(HAS_RAWTORGB24ROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - RAWToRGB24Row = RAWToRGB24Row_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - RAWToRGB24Row = RAWToRGB24Row_SSSE3; - } - } -#endif -#if defined(HAS_RAWTORGB24ROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - RAWToRGB24Row = RAWToRGB24Row_Any_NEON; - if (IS_ALIGNED(width, 8)) { - RAWToRGB24Row = RAWToRGB24Row_NEON; - } - } -#endif -#if defined(HAS_RAWTORGB24ROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - RAWToRGB24Row = RAWToRGB24Row_Any_MSA; - if (IS_ALIGNED(width, 16)) { - RAWToRGB24Row = RAWToRGB24Row_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - RAWToRGB24Row(src_raw, dst_rgb24, width); - src_raw += src_stride_raw; - dst_rgb24 += dst_stride_rgb24; - } - return 0; -} - -LIBYUV_API -void SetPlane(uint8_t* dst_y, - int dst_stride_y, - int width, - int height, - uint32_t value) { - int y; - void (*SetRow)(uint8_t * dst, uint8_t value, int width) = SetRow_C; - if (height < 0) { - height = -height; - dst_y = dst_y + (height - 1) * dst_stride_y; - dst_stride_y = -dst_stride_y; - } - // Coalesce rows. - if (dst_stride_y == width) { - width *= height; - height = 1; - dst_stride_y = 0; - } -#if defined(HAS_SETROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - SetRow = SetRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - SetRow = SetRow_NEON; - } - } -#endif -#if defined(HAS_SETROW_X86) - if (TestCpuFlag(kCpuHasX86)) { - SetRow = SetRow_Any_X86; - if (IS_ALIGNED(width, 4)) { - SetRow = SetRow_X86; - } - } -#endif -#if defined(HAS_SETROW_ERMS) - if (TestCpuFlag(kCpuHasERMS)) { - SetRow = SetRow_ERMS; - } -#endif -#if defined(HAS_SETROW_MSA) - if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 16)) { - SetRow = SetRow_MSA; - } -#endif - - // Set plane - for (y = 0; y < height; ++y) { - SetRow(dst_y, value, width); - dst_y += dst_stride_y; - } -} - -// Draw a rectangle into I420 -LIBYUV_API -int I420Rect(uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int x, - int y, - int width, - int height, - int value_y, - int value_u, - int value_v) { - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - uint8_t* start_y = dst_y + y * dst_stride_y + x; - uint8_t* start_u = dst_u + (y / 2) * dst_stride_u + (x / 2); - uint8_t* start_v = dst_v + (y / 2) * dst_stride_v + (x / 2); - if (!dst_y || !dst_u || !dst_v || width <= 0 || height == 0 || x < 0 || - y < 0 || value_y < 0 || value_y > 255 || value_u < 0 || value_u > 255 || - value_v < 0 || value_v > 255) { - return -1; - } - - SetPlane(start_y, dst_stride_y, width, height, value_y); - SetPlane(start_u, dst_stride_u, halfwidth, halfheight, value_u); - SetPlane(start_v, dst_stride_v, halfwidth, halfheight, value_v); - return 0; -} - -// Draw a rectangle into ARGB -LIBYUV_API -int ARGBRect(uint8_t* dst_argb, - int dst_stride_argb, - int dst_x, - int dst_y, - int width, - int height, - uint32_t value) { - int y; - void (*ARGBSetRow)(uint8_t * dst_argb, uint32_t value, int width) = - ARGBSetRow_C; - if (!dst_argb || width <= 0 || height == 0 || dst_x < 0 || dst_y < 0) { - return -1; - } - if (height < 0) { - height = -height; - dst_argb = dst_argb + (height - 1) * dst_stride_argb; - dst_stride_argb = -dst_stride_argb; - } - dst_argb += dst_y * dst_stride_argb + dst_x * 4; - // Coalesce rows. - if (dst_stride_argb == width * 4) { - width *= height; - height = 1; - dst_stride_argb = 0; - } - -#if defined(HAS_ARGBSETROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBSetRow = ARGBSetRow_Any_NEON; - if (IS_ALIGNED(width, 4)) { - ARGBSetRow = ARGBSetRow_NEON; - } - } -#endif -#if defined(HAS_ARGBSETROW_X86) - if (TestCpuFlag(kCpuHasX86)) { - ARGBSetRow = ARGBSetRow_X86; - } -#endif -#if defined(HAS_ARGBSETROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBSetRow = ARGBSetRow_Any_MSA; - if (IS_ALIGNED(width, 4)) { - ARGBSetRow = ARGBSetRow_MSA; - } - } -#endif - - // Set plane - for (y = 0; y < height; ++y) { - ARGBSetRow(dst_argb, value, width); - dst_argb += dst_stride_argb; - } - return 0; -} - -// Convert unattentuated ARGB to preattenuated ARGB. -// An unattenutated ARGB alpha blend uses the formula -// p = a * f + (1 - a) * b -// where -// p is output pixel -// f is foreground pixel -// b is background pixel -// a is alpha value from foreground pixel -// An preattenutated ARGB alpha blend uses the formula -// p = f + (1 - a) * b -// where -// f is foreground pixel premultiplied by alpha - -LIBYUV_API -int ARGBAttenuate(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*ARGBAttenuateRow)(const uint8_t* src_argb, uint8_t* dst_argb, - int width) = ARGBAttenuateRow_C; - if (!src_argb || !dst_argb || width <= 0 || height == 0) { - return -1; - } - if (height < 0) { - height = -height; - src_argb = src_argb + (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_argb = dst_stride_argb = 0; - } -#if defined(HAS_ARGBATTENUATEROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - ARGBAttenuateRow = ARGBAttenuateRow_Any_SSSE3; - if (IS_ALIGNED(width, 4)) { - ARGBAttenuateRow = ARGBAttenuateRow_SSSE3; - } - } -#endif -#if defined(HAS_ARGBATTENUATEROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBAttenuateRow = ARGBAttenuateRow_Any_AVX2; - if (IS_ALIGNED(width, 8)) { - ARGBAttenuateRow = ARGBAttenuateRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBATTENUATEROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBAttenuateRow = ARGBAttenuateRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBAttenuateRow = ARGBAttenuateRow_NEON; - } - } -#endif -#if defined(HAS_ARGBATTENUATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBAttenuateRow = ARGBAttenuateRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBAttenuateRow = ARGBAttenuateRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - ARGBAttenuateRow(src_argb, dst_argb, width); - src_argb += src_stride_argb; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Convert preattentuated ARGB to unattenuated ARGB. -LIBYUV_API -int ARGBUnattenuate(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*ARGBUnattenuateRow)(const uint8_t* src_argb, uint8_t* dst_argb, - int width) = ARGBUnattenuateRow_C; - if (!src_argb || !dst_argb || width <= 0 || height == 0) { - return -1; - } - if (height < 0) { - height = -height; - src_argb = src_argb + (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_argb = dst_stride_argb = 0; - } -#if defined(HAS_ARGBUNATTENUATEROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGBUnattenuateRow = ARGBUnattenuateRow_Any_SSE2; - if (IS_ALIGNED(width, 4)) { - ARGBUnattenuateRow = ARGBUnattenuateRow_SSE2; - } - } -#endif -#if defined(HAS_ARGBUNATTENUATEROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBUnattenuateRow = ARGBUnattenuateRow_Any_AVX2; - if (IS_ALIGNED(width, 8)) { - ARGBUnattenuateRow = ARGBUnattenuateRow_AVX2; - } - } -#endif - // TODO(fbarchard): Neon version. - - for (y = 0; y < height; ++y) { - ARGBUnattenuateRow(src_argb, dst_argb, width); - src_argb += src_stride_argb; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Convert ARGB to Grayed ARGB. -LIBYUV_API -int ARGBGrayTo(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*ARGBGrayRow)(const uint8_t* src_argb, uint8_t* dst_argb, int width) = - ARGBGrayRow_C; - if (!src_argb || !dst_argb || width <= 0 || height == 0) { - return -1; - } - if (height < 0) { - height = -height; - src_argb = src_argb + (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_argb = dst_stride_argb = 0; - } -#if defined(HAS_ARGBGRAYROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 8)) { - ARGBGrayRow = ARGBGrayRow_SSSE3; - } -#endif -#if defined(HAS_ARGBGRAYROW_NEON) - if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { - ARGBGrayRow = ARGBGrayRow_NEON; - } -#endif -#if defined(HAS_ARGBGRAYROW_MSA) - if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 8)) { - ARGBGrayRow = ARGBGrayRow_MSA; - } -#endif - - for (y = 0; y < height; ++y) { - ARGBGrayRow(src_argb, dst_argb, width); - src_argb += src_stride_argb; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Make a rectangle of ARGB gray scale. -LIBYUV_API -int ARGBGray(uint8_t* dst_argb, - int dst_stride_argb, - int dst_x, - int dst_y, - int width, - int height) { - int y; - void (*ARGBGrayRow)(const uint8_t* src_argb, uint8_t* dst_argb, int width) = - ARGBGrayRow_C; - uint8_t* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; - if (!dst_argb || width <= 0 || height <= 0 || dst_x < 0 || dst_y < 0) { - return -1; - } - // Coalesce rows. - if (dst_stride_argb == width * 4) { - width *= height; - height = 1; - dst_stride_argb = 0; - } -#if defined(HAS_ARGBGRAYROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 8)) { - ARGBGrayRow = ARGBGrayRow_SSSE3; - } -#endif -#if defined(HAS_ARGBGRAYROW_NEON) - if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { - ARGBGrayRow = ARGBGrayRow_NEON; - } -#endif -#if defined(HAS_ARGBGRAYROW_MSA) - if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 8)) { - ARGBGrayRow = ARGBGrayRow_MSA; - } -#endif - - for (y = 0; y < height; ++y) { - ARGBGrayRow(dst, dst, width); - dst += dst_stride_argb; - } - return 0; -} - -// Make a rectangle of ARGB Sepia tone. -LIBYUV_API -int ARGBSepia(uint8_t* dst_argb, - int dst_stride_argb, - int dst_x, - int dst_y, - int width, - int height) { - int y; - void (*ARGBSepiaRow)(uint8_t * dst_argb, int width) = ARGBSepiaRow_C; - uint8_t* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; - if (!dst_argb || width <= 0 || height <= 0 || dst_x < 0 || dst_y < 0) { - return -1; - } - // Coalesce rows. - if (dst_stride_argb == width * 4) { - width *= height; - height = 1; - dst_stride_argb = 0; - } -#if defined(HAS_ARGBSEPIAROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 8)) { - ARGBSepiaRow = ARGBSepiaRow_SSSE3; - } -#endif -#if defined(HAS_ARGBSEPIAROW_NEON) - if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { - ARGBSepiaRow = ARGBSepiaRow_NEON; - } -#endif -#if defined(HAS_ARGBSEPIAROW_MSA) - if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 8)) { - ARGBSepiaRow = ARGBSepiaRow_MSA; - } -#endif - - for (y = 0; y < height; ++y) { - ARGBSepiaRow(dst, width); - dst += dst_stride_argb; - } - return 0; -} - -// Apply a 4x4 matrix to each ARGB pixel. -// Note: Normally for shading, but can be used to swizzle or invert. -LIBYUV_API -int ARGBColorMatrix(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - const int8_t* matrix_argb, - int width, - int height) { - int y; - void (*ARGBColorMatrixRow)(const uint8_t* src_argb, uint8_t* dst_argb, - const int8_t* matrix_argb, int width) = - ARGBColorMatrixRow_C; - if (!src_argb || !dst_argb || !matrix_argb || width <= 0 || height == 0) { - return -1; - } - if (height < 0) { - height = -height; - src_argb = src_argb + (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_argb = dst_stride_argb = 0; - } -#if defined(HAS_ARGBCOLORMATRIXROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 8)) { - ARGBColorMatrixRow = ARGBColorMatrixRow_SSSE3; - } -#endif -#if defined(HAS_ARGBCOLORMATRIXROW_NEON) - if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { - ARGBColorMatrixRow = ARGBColorMatrixRow_NEON; - } -#endif -#if defined(HAS_ARGBCOLORMATRIXROW_MSA) - if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 8)) { - ARGBColorMatrixRow = ARGBColorMatrixRow_MSA; - } -#endif - for (y = 0; y < height; ++y) { - ARGBColorMatrixRow(src_argb, dst_argb, matrix_argb, width); - src_argb += src_stride_argb; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Apply a 4x3 matrix to each ARGB pixel. -// Deprecated. -LIBYUV_API -int RGBColorMatrix(uint8_t* dst_argb, - int dst_stride_argb, - const int8_t* matrix_rgb, - int dst_x, - int dst_y, - int width, - int height) { - SIMD_ALIGNED(int8_t matrix_argb[16]); - uint8_t* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; - if (!dst_argb || !matrix_rgb || width <= 0 || height <= 0 || dst_x < 0 || - dst_y < 0) { - return -1; - } - - // Convert 4x3 7 bit matrix to 4x4 6 bit matrix. - matrix_argb[0] = matrix_rgb[0] / 2; - matrix_argb[1] = matrix_rgb[1] / 2; - matrix_argb[2] = matrix_rgb[2] / 2; - matrix_argb[3] = matrix_rgb[3] / 2; - matrix_argb[4] = matrix_rgb[4] / 2; - matrix_argb[5] = matrix_rgb[5] / 2; - matrix_argb[6] = matrix_rgb[6] / 2; - matrix_argb[7] = matrix_rgb[7] / 2; - matrix_argb[8] = matrix_rgb[8] / 2; - matrix_argb[9] = matrix_rgb[9] / 2; - matrix_argb[10] = matrix_rgb[10] / 2; - matrix_argb[11] = matrix_rgb[11] / 2; - matrix_argb[14] = matrix_argb[13] = matrix_argb[12] = 0; - matrix_argb[15] = 64; // 1.0 - - return ARGBColorMatrix((const uint8_t*)(dst), dst_stride_argb, dst, - dst_stride_argb, &matrix_argb[0], width, height); -} - -// Apply a color table each ARGB pixel. -// Table contains 256 ARGB values. -LIBYUV_API -int ARGBColorTable(uint8_t* dst_argb, - int dst_stride_argb, - const uint8_t* table_argb, - int dst_x, - int dst_y, - int width, - int height) { - int y; - void (*ARGBColorTableRow)(uint8_t * dst_argb, const uint8_t* table_argb, - int width) = ARGBColorTableRow_C; - uint8_t* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; - if (!dst_argb || !table_argb || width <= 0 || height <= 0 || dst_x < 0 || - dst_y < 0) { - return -1; - } - // Coalesce rows. - if (dst_stride_argb == width * 4) { - width *= height; - height = 1; - dst_stride_argb = 0; - } -#if defined(HAS_ARGBCOLORTABLEROW_X86) - if (TestCpuFlag(kCpuHasX86)) { - ARGBColorTableRow = ARGBColorTableRow_X86; - } -#endif - for (y = 0; y < height; ++y) { - ARGBColorTableRow(dst, table_argb, width); - dst += dst_stride_argb; - } - return 0; -} - -// Apply a color table each ARGB pixel but preserve destination alpha. -// Table contains 256 ARGB values. -LIBYUV_API -int RGBColorTable(uint8_t* dst_argb, - int dst_stride_argb, - const uint8_t* table_argb, - int dst_x, - int dst_y, - int width, - int height) { - int y; - void (*RGBColorTableRow)(uint8_t * dst_argb, const uint8_t* table_argb, - int width) = RGBColorTableRow_C; - uint8_t* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; - if (!dst_argb || !table_argb || width <= 0 || height <= 0 || dst_x < 0 || - dst_y < 0) { - return -1; - } - // Coalesce rows. - if (dst_stride_argb == width * 4) { - width *= height; - height = 1; - dst_stride_argb = 0; - } -#if defined(HAS_RGBCOLORTABLEROW_X86) - if (TestCpuFlag(kCpuHasX86)) { - RGBColorTableRow = RGBColorTableRow_X86; - } -#endif - for (y = 0; y < height; ++y) { - RGBColorTableRow(dst, table_argb, width); - dst += dst_stride_argb; - } - return 0; -} - -// ARGBQuantize is used to posterize art. -// e.g. rgb / qvalue * qvalue + qvalue / 2 -// But the low levels implement efficiently with 3 parameters, and could be -// used for other high level operations. -// dst_argb[0] = (b * scale >> 16) * interval_size + interval_offset; -// where scale is 1 / interval_size as a fixed point value. -// The divide is replaces with a multiply by reciprocal fixed point multiply. -// Caveat - although SSE2 saturates, the C function does not and should be used -// with care if doing anything but quantization. -LIBYUV_API -int ARGBQuantize(uint8_t* dst_argb, - int dst_stride_argb, - int scale, - int interval_size, - int interval_offset, - int dst_x, - int dst_y, - int width, - int height) { - int y; - void (*ARGBQuantizeRow)(uint8_t * dst_argb, int scale, int interval_size, - int interval_offset, int width) = ARGBQuantizeRow_C; - uint8_t* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; - if (!dst_argb || width <= 0 || height <= 0 || dst_x < 0 || dst_y < 0 || - interval_size < 1 || interval_size > 255) { - return -1; - } - // Coalesce rows. - if (dst_stride_argb == width * 4) { - width *= height; - height = 1; - dst_stride_argb = 0; - } -#if defined(HAS_ARGBQUANTIZEROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 4)) { - ARGBQuantizeRow = ARGBQuantizeRow_SSE2; - } -#endif -#if defined(HAS_ARGBQUANTIZEROW_NEON) - if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { - ARGBQuantizeRow = ARGBQuantizeRow_NEON; - } -#endif -#if defined(HAS_ARGBQUANTIZEROW_MSA) - if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 8)) { - ARGBQuantizeRow = ARGBQuantizeRow_MSA; - } -#endif - for (y = 0; y < height; ++y) { - ARGBQuantizeRow(dst, scale, interval_size, interval_offset, width); - dst += dst_stride_argb; - } - return 0; -} - -// 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. -LIBYUV_API -int ARGBComputeCumulativeSum(const uint8_t* src_argb, - int src_stride_argb, - int32_t* dst_cumsum, - int dst_stride32_cumsum, - int width, - int height) { - int y; - void (*ComputeCumulativeSumRow)(const uint8_t* row, int32_t* cumsum, - const int32_t* previous_cumsum, int width) = - ComputeCumulativeSumRow_C; - int32_t* previous_cumsum = dst_cumsum; - if (!dst_cumsum || !src_argb || width <= 0 || height <= 0) { - return -1; - } -#if defined(HAS_CUMULATIVESUMTOAVERAGEROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ComputeCumulativeSumRow = ComputeCumulativeSumRow_SSE2; - } -#endif - memset(dst_cumsum, 0, width * sizeof(dst_cumsum[0]) * 4); // 4 int per pixel. - for (y = 0; y < height; ++y) { - ComputeCumulativeSumRow(src_argb, dst_cumsum, previous_cumsum, width); - previous_cumsum = dst_cumsum; - dst_cumsum += dst_stride32_cumsum; - src_argb += src_stride_argb; - } - return 0; -} - -// Blur ARGB image. -// Caller should allocate CumulativeSum table of width * height * 16 bytes -// aligned to 16 byte boundary. height can be radius * 2 + 2 to save memory -// as the buffer is treated as circular. -LIBYUV_API -int ARGBBlur(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int32_t* dst_cumsum, - int dst_stride32_cumsum, - int width, - int height, - int radius) { - int y; - void (*ComputeCumulativeSumRow)(const uint8_t* row, int32_t* cumsum, - const int32_t* previous_cumsum, int width) = - ComputeCumulativeSumRow_C; - void (*CumulativeSumToAverageRow)( - const int32_t* topleft, const int32_t* botleft, int width, int area, - uint8_t* dst, int count) = CumulativeSumToAverageRow_C; - int32_t* cumsum_bot_row; - int32_t* max_cumsum_bot_row; - int32_t* cumsum_top_row; - - if (!src_argb || !dst_argb || width <= 0 || height == 0) { - return -1; - } - if (height < 0) { - height = -height; - src_argb = src_argb + (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - if (radius > height) { - radius = height; - } - if (radius > (width / 2 - 1)) { - radius = width / 2 - 1; - } - if (radius <= 0) { - return -1; - } -#if defined(HAS_CUMULATIVESUMTOAVERAGEROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ComputeCumulativeSumRow = ComputeCumulativeSumRow_SSE2; - CumulativeSumToAverageRow = CumulativeSumToAverageRow_SSE2; - } -#endif - // Compute enough CumulativeSum for first row to be blurred. After this - // one row of CumulativeSum is updated at a time. - ARGBComputeCumulativeSum(src_argb, src_stride_argb, dst_cumsum, - dst_stride32_cumsum, width, radius); - - src_argb = src_argb + radius * src_stride_argb; - cumsum_bot_row = &dst_cumsum[(radius - 1) * dst_stride32_cumsum]; - - max_cumsum_bot_row = &dst_cumsum[(radius * 2 + 2) * dst_stride32_cumsum]; - cumsum_top_row = &dst_cumsum[0]; - - for (y = 0; y < height; ++y) { - int top_y = ((y - radius - 1) >= 0) ? (y - radius - 1) : 0; - int bot_y = ((y + radius) < height) ? (y + radius) : (height - 1); - int area = radius * (bot_y - top_y); - int boxwidth = radius * 4; - int x; - int n; - - // Increment cumsum_top_row pointer with circular buffer wrap around. - if (top_y) { - cumsum_top_row += dst_stride32_cumsum; - if (cumsum_top_row >= max_cumsum_bot_row) { - cumsum_top_row = dst_cumsum; - } - } - // Increment cumsum_bot_row pointer with circular buffer wrap around and - // then fill in a row of CumulativeSum. - if ((y + radius) < height) { - const int32_t* prev_cumsum_bot_row = cumsum_bot_row; - cumsum_bot_row += dst_stride32_cumsum; - if (cumsum_bot_row >= max_cumsum_bot_row) { - cumsum_bot_row = dst_cumsum; - } - ComputeCumulativeSumRow(src_argb, cumsum_bot_row, prev_cumsum_bot_row, - width); - src_argb += src_stride_argb; - } - - // Left clipped. - for (x = 0; x < radius + 1; ++x) { - CumulativeSumToAverageRow(cumsum_top_row, cumsum_bot_row, boxwidth, area, - &dst_argb[x * 4], 1); - area += (bot_y - top_y); - boxwidth += 4; - } - - // Middle unclipped. - n = (width - 1) - radius - x + 1; - CumulativeSumToAverageRow(cumsum_top_row, cumsum_bot_row, boxwidth, area, - &dst_argb[x * 4], n); - - // Right clipped. - for (x += n; x <= width - 1; ++x) { - area -= (bot_y - top_y); - boxwidth -= 4; - CumulativeSumToAverageRow(cumsum_top_row + (x - radius - 1) * 4, - cumsum_bot_row + (x - radius - 1) * 4, boxwidth, - area, &dst_argb[x * 4], 1); - } - dst_argb += dst_stride_argb; - } - return 0; -} - -// Multiply ARGB image by a specified ARGB value. -LIBYUV_API -int ARGBShade(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height, - uint32_t value) { - int y; - void (*ARGBShadeRow)(const uint8_t* src_argb, uint8_t* dst_argb, int width, - uint32_t value) = ARGBShadeRow_C; - if (!src_argb || !dst_argb || width <= 0 || height == 0 || value == 0u) { - return -1; - } - if (height < 0) { - height = -height; - src_argb = src_argb + (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_argb = dst_stride_argb = 0; - } -#if defined(HAS_ARGBSHADEROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 4)) { - ARGBShadeRow = ARGBShadeRow_SSE2; - } -#endif -#if defined(HAS_ARGBSHADEROW_NEON) - if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { - ARGBShadeRow = ARGBShadeRow_NEON; - } -#endif -#if defined(HAS_ARGBSHADEROW_MSA) - if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 4)) { - ARGBShadeRow = ARGBShadeRow_MSA; - } -#endif - - for (y = 0; y < height; ++y) { - ARGBShadeRow(src_argb, dst_argb, width, value); - src_argb += src_stride_argb; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Interpolate 2 planes by specified amount (0 to 255). -LIBYUV_API -int InterpolatePlane(const uint8_t* src0, - int src_stride0, - const uint8_t* src1, - int src_stride1, - uint8_t* dst, - int dst_stride, - int width, - int height, - int interpolation) { - int y; - void (*InterpolateRow)(uint8_t * dst_ptr, const uint8_t* src_ptr, - ptrdiff_t src_stride, int dst_width, - int source_y_fraction) = InterpolateRow_C; - if (!src0 || !src1 || !dst || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - dst = dst + (height - 1) * dst_stride; - dst_stride = -dst_stride; - } - // Coalesce rows. - if (src_stride0 == width && src_stride1 == width && dst_stride == width) { - width *= height; - height = 1; - src_stride0 = src_stride1 = dst_stride = 0; - } -#if defined(HAS_INTERPOLATEROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - InterpolateRow = InterpolateRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - InterpolateRow = InterpolateRow_SSSE3; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - InterpolateRow = InterpolateRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - InterpolateRow = InterpolateRow_AVX2; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - InterpolateRow = InterpolateRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - InterpolateRow = InterpolateRow_NEON; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - InterpolateRow = InterpolateRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - InterpolateRow = InterpolateRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - InterpolateRow(dst, src0, src1 - src0, width, interpolation); - src0 += src_stride0; - src1 += src_stride1; - dst += dst_stride; - } - return 0; -} - -// Interpolate 2 ARGB images by specified amount (0 to 255). -LIBYUV_API -int ARGBInterpolate(const uint8_t* src_argb0, - int src_stride_argb0, - const uint8_t* src_argb1, - int src_stride_argb1, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height, - int interpolation) { - return InterpolatePlane(src_argb0, src_stride_argb0, src_argb1, - src_stride_argb1, dst_argb, dst_stride_argb, - width * 4, height, interpolation); -} - -// Interpolate 2 YUV images by specified amount (0 to 255). -LIBYUV_API -int I420Interpolate(const uint8_t* src0_y, - int src0_stride_y, - const uint8_t* src0_u, - int src0_stride_u, - const uint8_t* src0_v, - int src0_stride_v, - const uint8_t* src1_y, - int src1_stride_y, - const uint8_t* src1_u, - int src1_stride_u, - const uint8_t* src1_v, - int src1_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height, - int interpolation) { - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - if (!src0_y || !src0_u || !src0_v || !src1_y || !src1_u || !src1_v || - !dst_y || !dst_u || !dst_v || width <= 0 || height == 0) { - return -1; - } - InterpolatePlane(src0_y, src0_stride_y, src1_y, src1_stride_y, dst_y, - dst_stride_y, width, height, interpolation); - InterpolatePlane(src0_u, src0_stride_u, src1_u, src1_stride_u, dst_u, - dst_stride_u, halfwidth, halfheight, interpolation); - InterpolatePlane(src0_v, src0_stride_v, src1_v, src1_stride_v, dst_v, - dst_stride_v, halfwidth, halfheight, interpolation); - return 0; -} - -// Shuffle ARGB channel order. e.g. BGRA to ARGB. -LIBYUV_API -int ARGBShuffle(const uint8_t* src_bgra, - int src_stride_bgra, - uint8_t* dst_argb, - int dst_stride_argb, - const uint8_t* shuffler, - int width, - int height) { - int y; - void (*ARGBShuffleRow)(const uint8_t* src_bgra, uint8_t* dst_argb, - const uint8_t* shuffler, int width) = ARGBShuffleRow_C; - if (!src_bgra || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_bgra = src_bgra + (height - 1) * src_stride_bgra; - src_stride_bgra = -src_stride_bgra; - } - // Coalesce rows. - if (src_stride_bgra == width * 4 && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_bgra = dst_stride_argb = 0; - } -#if defined(HAS_ARGBSHUFFLEROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - ARGBShuffleRow = ARGBShuffleRow_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - ARGBShuffleRow = ARGBShuffleRow_SSSE3; - } - } -#endif -#if defined(HAS_ARGBSHUFFLEROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBShuffleRow = ARGBShuffleRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - ARGBShuffleRow = ARGBShuffleRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBSHUFFLEROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBShuffleRow = ARGBShuffleRow_Any_NEON; - if (IS_ALIGNED(width, 4)) { - ARGBShuffleRow = ARGBShuffleRow_NEON; - } - } -#endif -#if defined(HAS_ARGBSHUFFLEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBShuffleRow = ARGBShuffleRow_Any_MSA; - if (IS_ALIGNED(width, 8)) { - ARGBShuffleRow = ARGBShuffleRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - ARGBShuffleRow(src_bgra, dst_argb, shuffler, width); - src_bgra += src_stride_bgra; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Sobel ARGB effect. -static int ARGBSobelize(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height, - void (*SobelRow)(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst, - int width)) { - int y; - void (*ARGBToYJRow)(const uint8_t* src_argb, uint8_t* dst_g, int width) = - ARGBToYJRow_C; - void (*SobelYRow)(const uint8_t* src_y0, const uint8_t* src_y1, - uint8_t* dst_sobely, int width) = SobelYRow_C; - void (*SobelXRow)(const uint8_t* src_y0, const uint8_t* src_y1, - const uint8_t* src_y2, uint8_t* dst_sobely, int width) = - SobelXRow_C; - const int kEdge = 16; // Extra pixels at start of row for extrude/align. - if (!src_argb || !dst_argb || 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; - src_stride_argb = -src_stride_argb; - } - -#if defined(HAS_ARGBTOYJROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - ARGBToYJRow = ARGBToYJRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - ARGBToYJRow = ARGBToYJRow_SSSE3; - } - } -#endif -#if defined(HAS_ARGBTOYJROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBToYJRow = ARGBToYJRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - ARGBToYJRow = ARGBToYJRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBTOYJROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBToYJRow = ARGBToYJRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ARGBToYJRow = ARGBToYJRow_NEON; - } - } -#endif -#if defined(HAS_ARGBTOYJROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBToYJRow = ARGBToYJRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBToYJRow = ARGBToYJRow_MSA; - } - } -#endif - -#if defined(HAS_SOBELYROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - SobelYRow = SobelYRow_SSE2; - } -#endif -#if defined(HAS_SOBELYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - SobelYRow = SobelYRow_NEON; - } -#endif -#if defined(HAS_SOBELYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SobelYRow = SobelYRow_MSA; - } -#endif -#if defined(HAS_SOBELXROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - SobelXRow = SobelXRow_SSE2; - } -#endif -#if defined(HAS_SOBELXROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - SobelXRow = SobelXRow_NEON; - } -#endif -#if defined(HAS_SOBELXROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SobelXRow = SobelXRow_MSA; - } -#endif - { - // 3 rows with edges before/after. - const int kRowSize = (width + kEdge + 31) & ~31; - align_buffer_64(rows, kRowSize * 2 + (kEdge + kRowSize * 3 + kEdge)); - uint8_t* row_sobelx = rows; - uint8_t* row_sobely = rows + kRowSize; - uint8_t* row_y = rows + kRowSize * 2; - - // Convert first row. - uint8_t* row_y0 = row_y + kEdge; - uint8_t* row_y1 = row_y0 + kRowSize; - uint8_t* row_y2 = row_y1 + kRowSize; - ARGBToYJRow(src_argb, row_y0, width); - row_y0[-1] = row_y0[0]; - memset(row_y0 + width, row_y0[width - 1], 16); // Extrude 16 for valgrind. - ARGBToYJRow(src_argb, row_y1, width); - row_y1[-1] = row_y1[0]; - memset(row_y1 + width, row_y1[width - 1], 16); - memset(row_y2 + width, 0, 16); - - for (y = 0; y < height; ++y) { - // Convert next row of ARGB to G. - if (y < (height - 1)) { - src_argb += src_stride_argb; - } - ARGBToYJRow(src_argb, row_y2, width); - row_y2[-1] = row_y2[0]; - row_y2[width] = row_y2[width - 1]; - - SobelXRow(row_y0 - 1, row_y1 - 1, row_y2 - 1, row_sobelx, width); - SobelYRow(row_y0 - 1, row_y2 - 1, row_sobely, width); - SobelRow(row_sobelx, row_sobely, dst_argb, width); - - // Cycle thru circular queue of 3 row_y buffers. - { - uint8_t* row_yt = row_y0; - row_y0 = row_y1; - row_y1 = row_y2; - row_y2 = row_yt; - } - - dst_argb += dst_stride_argb; - } - free_aligned_buffer_64(rows); - } - return 0; -} - -// Sobel ARGB effect. -LIBYUV_API -int ARGBSobel(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - void (*SobelRow)(const uint8_t* src_sobelx, const uint8_t* src_sobely, - uint8_t* dst_argb, int width) = SobelRow_C; -#if defined(HAS_SOBELROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - SobelRow = SobelRow_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - SobelRow = SobelRow_SSE2; - } - } -#endif -#if defined(HAS_SOBELROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - SobelRow = SobelRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - SobelRow = SobelRow_NEON; - } - } -#endif -#if defined(HAS_SOBELROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SobelRow = SobelRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - SobelRow = SobelRow_MSA; - } - } -#endif - return ARGBSobelize(src_argb, src_stride_argb, dst_argb, dst_stride_argb, - width, height, SobelRow); -} - -// Sobel ARGB effect with planar output. -LIBYUV_API -int ARGBSobelToPlane(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_y, - int dst_stride_y, - int width, - int height) { - void (*SobelToPlaneRow)(const uint8_t* src_sobelx, const uint8_t* src_sobely, - uint8_t* dst_, int width) = SobelToPlaneRow_C; -#if defined(HAS_SOBELTOPLANEROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - SobelToPlaneRow = SobelToPlaneRow_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - SobelToPlaneRow = SobelToPlaneRow_SSE2; - } - } -#endif -#if defined(HAS_SOBELTOPLANEROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - SobelToPlaneRow = SobelToPlaneRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - SobelToPlaneRow = SobelToPlaneRow_NEON; - } - } -#endif -#if defined(HAS_SOBELTOPLANEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SobelToPlaneRow = SobelToPlaneRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - SobelToPlaneRow = SobelToPlaneRow_MSA; - } - } -#endif - return ARGBSobelize(src_argb, src_stride_argb, dst_y, dst_stride_y, width, - height, SobelToPlaneRow); -} - -// SobelXY ARGB effect. -// Similar to Sobel, but also stores Sobel X in R and Sobel Y in B. G = Sobel. -LIBYUV_API -int ARGBSobelXY(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - void (*SobelXYRow)(const uint8_t* src_sobelx, const uint8_t* src_sobely, - uint8_t* dst_argb, int width) = SobelXYRow_C; -#if defined(HAS_SOBELXYROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - SobelXYRow = SobelXYRow_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - SobelXYRow = SobelXYRow_SSE2; - } - } -#endif -#if defined(HAS_SOBELXYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - SobelXYRow = SobelXYRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - SobelXYRow = SobelXYRow_NEON; - } - } -#endif -#if defined(HAS_SOBELXYROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SobelXYRow = SobelXYRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - SobelXYRow = SobelXYRow_MSA; - } - } -#endif - return ARGBSobelize(src_argb, src_stride_argb, dst_argb, dst_stride_argb, - width, height, SobelXYRow); -} - -// Apply a 4x4 polynomial to each ARGB pixel. -LIBYUV_API -int ARGBPolynomial(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - const float* poly, - int width, - int height) { - int y; - void (*ARGBPolynomialRow)(const uint8_t* src_argb, uint8_t* dst_argb, - const float* poly, int width) = ARGBPolynomialRow_C; - if (!src_argb || !dst_argb || !poly || 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; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_argb = dst_stride_argb = 0; - } -#if defined(HAS_ARGBPOLYNOMIALROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 2)) { - ARGBPolynomialRow = ARGBPolynomialRow_SSE2; - } -#endif -#if defined(HAS_ARGBPOLYNOMIALROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2) && TestCpuFlag(kCpuHasFMA3) && - IS_ALIGNED(width, 2)) { - ARGBPolynomialRow = ARGBPolynomialRow_AVX2; - } -#endif - - for (y = 0; y < height; ++y) { - ARGBPolynomialRow(src_argb, dst_argb, poly, width); - src_argb += src_stride_argb; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Convert plane of 16 bit shorts to half floats. -// Source values are multiplied by scale before storing as half float. -LIBYUV_API -int HalfFloatPlane(const uint16_t* src_y, - int src_stride_y, - uint16_t* dst_y, - int dst_stride_y, - float scale, - int width, - int height) { - int y; - void (*HalfFloatRow)(const uint16_t* src, uint16_t* dst, float scale, - int width) = HalfFloatRow_C; - if (!src_y || !dst_y || width <= 0 || height == 0) { - return -1; - } - src_stride_y >>= 1; - dst_stride_y >>= 1; - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_y = src_y + (height - 1) * src_stride_y; - src_stride_y = -src_stride_y; - } - // Coalesce rows. - if (src_stride_y == width && dst_stride_y == width) { - width *= height; - height = 1; - src_stride_y = dst_stride_y = 0; - } -#if defined(HAS_HALFFLOATROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - HalfFloatRow = HalfFloatRow_Any_SSE2; - if (IS_ALIGNED(width, 8)) { - HalfFloatRow = HalfFloatRow_SSE2; - } - } -#endif -#if defined(HAS_HALFFLOATROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - HalfFloatRow = HalfFloatRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - HalfFloatRow = HalfFloatRow_AVX2; - } - } -#endif -#if defined(HAS_HALFFLOATROW_F16C) - if (TestCpuFlag(kCpuHasAVX2) && TestCpuFlag(kCpuHasF16C)) { - HalfFloatRow = - (scale == 1.0f) ? HalfFloat1Row_Any_F16C : HalfFloatRow_Any_F16C; - if (IS_ALIGNED(width, 16)) { - HalfFloatRow = (scale == 1.0f) ? HalfFloat1Row_F16C : HalfFloatRow_F16C; - } - } -#endif -#if defined(HAS_HALFFLOATROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - HalfFloatRow = - (scale == 1.0f) ? HalfFloat1Row_Any_NEON : HalfFloatRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - HalfFloatRow = (scale == 1.0f) ? HalfFloat1Row_NEON : HalfFloatRow_NEON; - } - } -#endif -#if defined(HAS_HALFFLOATROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - HalfFloatRow = HalfFloatRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - HalfFloatRow = HalfFloatRow_MSA; - } - } -#endif - - for (y = 0; y < height; ++y) { - HalfFloatRow(src_y, dst_y, scale, width); - src_y += src_stride_y; - dst_y += dst_stride_y; - } - return 0; -} - -// Convert a buffer of bytes to floats, scale the values and store as floats. -LIBYUV_API -int ByteToFloat(const uint8_t* src_y, float* dst_y, float scale, int width) { - void (*ByteToFloatRow)(const uint8_t* src, float* dst, float scale, - int width) = ByteToFloatRow_C; - if (!src_y || !dst_y || width <= 0) { - return -1; - } -#if defined(HAS_BYTETOFLOATROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ByteToFloatRow = ByteToFloatRow_Any_NEON; - if (IS_ALIGNED(width, 8)) { - ByteToFloatRow = ByteToFloatRow_NEON; - } - } -#endif - - ByteToFloatRow(src_y, dst_y, scale, width); - return 0; -} - -// Apply a lumacolortable to each ARGB pixel. -LIBYUV_API -int ARGBLumaColorTable(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - const uint8_t* luma, - int width, - int height) { - int y; - void (*ARGBLumaColorTableRow)( - const uint8_t* src_argb, uint8_t* dst_argb, int width, - const uint8_t* luma, const uint32_t lumacoeff) = ARGBLumaColorTableRow_C; - if (!src_argb || !dst_argb || !luma || 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; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_argb = dst_stride_argb = 0; - } -#if defined(HAS_ARGBLUMACOLORTABLEROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 4)) { - ARGBLumaColorTableRow = ARGBLumaColorTableRow_SSSE3; - } -#endif - - for (y = 0; y < height; ++y) { - ARGBLumaColorTableRow(src_argb, dst_argb, width, luma, 0x00264b0f); - src_argb += src_stride_argb; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Copy Alpha from one ARGB image to another. -LIBYUV_API -int ARGBCopyAlpha(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*ARGBCopyAlphaRow)(const uint8_t* src_argb, uint8_t* dst_argb, - int width) = ARGBCopyAlphaRow_C; - if (!src_argb || !dst_argb || 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; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_argb = dst_stride_argb = 0; - } -#if defined(HAS_ARGBCOPYALPHAROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGBCopyAlphaRow = ARGBCopyAlphaRow_Any_SSE2; - if (IS_ALIGNED(width, 8)) { - ARGBCopyAlphaRow = ARGBCopyAlphaRow_SSE2; - } - } -#endif -#if defined(HAS_ARGBCOPYALPHAROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBCopyAlphaRow = ARGBCopyAlphaRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - ARGBCopyAlphaRow = ARGBCopyAlphaRow_AVX2; - } - } -#endif - - for (y = 0; y < height; ++y) { - ARGBCopyAlphaRow(src_argb, dst_argb, width); - src_argb += src_stride_argb; - dst_argb += dst_stride_argb; - } - return 0; -} - -// Extract just the alpha channel from ARGB. -LIBYUV_API -int ARGBExtractAlpha(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_a, - int dst_stride_a, - int width, - int height) { - if (!src_argb || !dst_a || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_argb += (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - // Coalesce rows. - if (src_stride_argb == width * 4 && dst_stride_a == width) { - width *= height; - height = 1; - src_stride_argb = dst_stride_a = 0; - } - void (*ARGBExtractAlphaRow)(const uint8_t* src_argb, uint8_t* dst_a, - int width) = ARGBExtractAlphaRow_C; -#if defined(HAS_ARGBEXTRACTALPHAROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGBExtractAlphaRow = IS_ALIGNED(width, 8) ? ARGBExtractAlphaRow_SSE2 - : ARGBExtractAlphaRow_Any_SSE2; - } -#endif -#if defined(HAS_ARGBEXTRACTALPHAROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBExtractAlphaRow = IS_ALIGNED(width, 32) ? ARGBExtractAlphaRow_AVX2 - : ARGBExtractAlphaRow_Any_AVX2; - } -#endif -#if defined(HAS_ARGBEXTRACTALPHAROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBExtractAlphaRow = IS_ALIGNED(width, 16) ? ARGBExtractAlphaRow_NEON - : ARGBExtractAlphaRow_Any_NEON; - } -#endif -#if defined(HAS_ARGBEXTRACTALPHAROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBExtractAlphaRow = IS_ALIGNED(width, 16) ? ARGBExtractAlphaRow_MSA - : ARGBExtractAlphaRow_Any_MSA; - } -#endif - - for (int y = 0; y < height; ++y) { - ARGBExtractAlphaRow(src_argb, dst_a, width); - src_argb += src_stride_argb; - dst_a += dst_stride_a; - } - return 0; -} - -// Copy a planar Y channel to the alpha channel of a destination ARGB image. -LIBYUV_API -int ARGBCopyYToAlpha(const uint8_t* src_y, - int src_stride_y, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int y; - void (*ARGBCopyYToAlphaRow)(const uint8_t* src_y, uint8_t* dst_argb, - int width) = ARGBCopyYToAlphaRow_C; - if (!src_y || !dst_argb || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_y = src_y + (height - 1) * src_stride_y; - src_stride_y = -src_stride_y; - } - // Coalesce rows. - if (src_stride_y == width && dst_stride_argb == width * 4) { - width *= height; - height = 1; - src_stride_y = dst_stride_argb = 0; - } -#if defined(HAS_ARGBCOPYYTOALPHAROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGBCopyYToAlphaRow = ARGBCopyYToAlphaRow_Any_SSE2; - if (IS_ALIGNED(width, 8)) { - ARGBCopyYToAlphaRow = ARGBCopyYToAlphaRow_SSE2; - } - } -#endif -#if defined(HAS_ARGBCOPYYTOALPHAROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBCopyYToAlphaRow = ARGBCopyYToAlphaRow_Any_AVX2; - if (IS_ALIGNED(width, 16)) { - ARGBCopyYToAlphaRow = ARGBCopyYToAlphaRow_AVX2; - } - } -#endif - - for (y = 0; y < height; ++y) { - ARGBCopyYToAlphaRow(src_y, dst_argb, width); - src_y += src_stride_y; - dst_argb += dst_stride_argb; - } - 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_t* src_yuy2, - int src_stride_yuy2, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_uv, - int dst_stride_uv, - int width, - int height) { - int y; - int halfwidth = (width + 1) >> 1; - void (*SplitUVRow)(const uint8_t* src_uv, uint8_t* dst_u, uint8_t* dst_v, - int width) = SplitUVRow_C; - void (*InterpolateRow)(uint8_t * dst_ptr, const uint8_t* src_ptr, - ptrdiff_t src_stride, int dst_width, - int source_y_fraction) = InterpolateRow_C; - if (!src_yuy2 || !dst_y || !dst_uv || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2; - src_stride_yuy2 = -src_stride_yuy2; - } -#if defined(HAS_SPLITUVROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - SplitUVRow = SplitUVRow_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - SplitUVRow = SplitUVRow_SSE2; - } - } -#endif -#if defined(HAS_SPLITUVROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - SplitUVRow = SplitUVRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - SplitUVRow = SplitUVRow_AVX2; - } - } -#endif -#if defined(HAS_SPLITUVROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - SplitUVRow = SplitUVRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - SplitUVRow = SplitUVRow_NEON; - } - } -#endif -#if defined(HAS_SPLITUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SplitUVRow = SplitUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - SplitUVRow = SplitUVRow_MSA; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - InterpolateRow = InterpolateRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - InterpolateRow = InterpolateRow_SSSE3; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - InterpolateRow = InterpolateRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - InterpolateRow = InterpolateRow_AVX2; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - InterpolateRow = InterpolateRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - InterpolateRow = InterpolateRow_NEON; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - InterpolateRow = InterpolateRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - InterpolateRow = InterpolateRow_MSA; - } - } -#endif - - { - int awidth = halfwidth * 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, 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, rows, dst_uv, awidth); - memcpy(dst_y, rows, width); - } - free_aligned_buffer_64(rows); - } - return 0; -} - -LIBYUV_API -int UYVYToNV12(const uint8_t* src_uyvy, - int src_stride_uyvy, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_uv, - int dst_stride_uv, - int width, - int height) { - int y; - int halfwidth = (width + 1) >> 1; - void (*SplitUVRow)(const uint8_t* src_uv, uint8_t* dst_u, uint8_t* dst_v, - int width) = SplitUVRow_C; - void (*InterpolateRow)(uint8_t * dst_ptr, const uint8_t* src_ptr, - ptrdiff_t src_stride, int dst_width, - int source_y_fraction) = InterpolateRow_C; - if (!src_uyvy || !dst_y || !dst_uv || width <= 0 || height == 0) { - return -1; - } - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy; - src_stride_uyvy = -src_stride_uyvy; - } -#if defined(HAS_SPLITUVROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - SplitUVRow = SplitUVRow_Any_SSE2; - if (IS_ALIGNED(width, 16)) { - SplitUVRow = SplitUVRow_SSE2; - } - } -#endif -#if defined(HAS_SPLITUVROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - SplitUVRow = SplitUVRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - SplitUVRow = SplitUVRow_AVX2; - } - } -#endif -#if defined(HAS_SPLITUVROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - SplitUVRow = SplitUVRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - SplitUVRow = SplitUVRow_NEON; - } - } -#endif -#if defined(HAS_SPLITUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - SplitUVRow = SplitUVRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - SplitUVRow = SplitUVRow_MSA; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - InterpolateRow = InterpolateRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - InterpolateRow = InterpolateRow_SSSE3; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - InterpolateRow = InterpolateRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - InterpolateRow = InterpolateRow_AVX2; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - InterpolateRow = InterpolateRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - InterpolateRow = InterpolateRow_NEON; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - InterpolateRow = InterpolateRow_Any_MSA; - if (IS_ALIGNED(width, 32)) { - InterpolateRow = InterpolateRow_MSA; - } - } -#endif - - { - int awidth = halfwidth * 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 + 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, rows, awidth); - memcpy(dst_y, rows, width); - } - free_aligned_buffer_64(rows); - } - return 0; -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate.cc deleted file mode 100644 index f2bed85b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate.cc +++ /dev/null @@ -1,514 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/rotate.h" - -#include "libyuv/convert.h" -#include "libyuv/cpu_id.h" -#include "libyuv/planar_functions.h" -#include "libyuv/rotate_row.h" -#include "libyuv/row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -LIBYUV_API -void TransposePlane(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width, - int height) { - int i = height; -#if defined(HAS_TRANSPOSEWX16_MSA) - void (*TransposeWx16)(const uint8_t* src, int src_stride, uint8_t* dst, - int dst_stride, int width) = TransposeWx16_C; -#else - void (*TransposeWx8)(const uint8_t* src, int src_stride, uint8_t* dst, - int dst_stride, int width) = TransposeWx8_C; -#endif -#if defined(HAS_TRANSPOSEWX8_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - TransposeWx8 = TransposeWx8_NEON; - } -#endif -#if defined(HAS_TRANSPOSEWX8_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - TransposeWx8 = TransposeWx8_Any_SSSE3; - if (IS_ALIGNED(width, 8)) { - TransposeWx8 = TransposeWx8_SSSE3; - } - } -#endif -#if defined(HAS_TRANSPOSEWX8_FAST_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - TransposeWx8 = TransposeWx8_Fast_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - TransposeWx8 = TransposeWx8_Fast_SSSE3; - } - } -#endif -#if defined(HAS_TRANSPOSEWX16_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - TransposeWx16 = TransposeWx16_Any_MSA; - if (IS_ALIGNED(width, 16)) { - TransposeWx16 = TransposeWx16_MSA; - } - } -#endif - -#if defined(HAS_TRANSPOSEWX16_MSA) - // Work across the source in 16x16 tiles - while (i >= 16) { - TransposeWx16(src, src_stride, dst, dst_stride, width); - src += 16 * src_stride; // Go down 16 rows. - dst += 16; // Move over 16 columns. - i -= 16; - } -#else - // Work across the source in 8x8 tiles - while (i >= 8) { - TransposeWx8(src, src_stride, dst, dst_stride, width); - src += 8 * src_stride; // Go down 8 rows. - dst += 8; // Move over 8 columns. - i -= 8; - } -#endif - - if (i > 0) { - TransposeWxH_C(src, src_stride, dst, dst_stride, width, i); - } -} - -LIBYUV_API -void RotatePlane90(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width, - int height) { - // Rotate by 90 is a transpose with the source read - // from bottom to top. So set the source pointer to the end - // of the buffer and flip the sign of the source stride. - src += src_stride * (height - 1); - src_stride = -src_stride; - TransposePlane(src, src_stride, dst, dst_stride, width, height); -} - -LIBYUV_API -void RotatePlane270(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width, - int height) { - // Rotate by 270 is a transpose with the destination written - // from bottom to top. So set the destination pointer to the end - // of the buffer and flip the sign of the destination stride. - dst += dst_stride * (width - 1); - dst_stride = -dst_stride; - TransposePlane(src, src_stride, dst, dst_stride, width, height); -} - -LIBYUV_API -void RotatePlane180(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width, - int height) { - // Swap first and last row and mirror the content. Uses a temporary row. - align_buffer_64(row, width); - const uint8_t* src_bot = src + src_stride * (height - 1); - uint8_t* dst_bot = dst + dst_stride * (height - 1); - int half_height = (height + 1) >> 1; - int y; - void (*MirrorRow)(const uint8_t* src, uint8_t* dst, int width) = MirrorRow_C; - void (*CopyRow)(const uint8_t* src, uint8_t* dst, int width) = CopyRow_C; -#if defined(HAS_MIRRORROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - MirrorRow = MirrorRow_Any_NEON; - if (IS_ALIGNED(width, 16)) { - MirrorRow = MirrorRow_NEON; - } - } -#endif -#if defined(HAS_MIRRORROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - MirrorRow = MirrorRow_Any_SSSE3; - if (IS_ALIGNED(width, 16)) { - MirrorRow = MirrorRow_SSSE3; - } - } -#endif -#if defined(HAS_MIRRORROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - MirrorRow = MirrorRow_Any_AVX2; - if (IS_ALIGNED(width, 32)) { - MirrorRow = MirrorRow_AVX2; - } - } -#endif -#if defined(HAS_MIRRORROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - MirrorRow = MirrorRow_Any_MSA; - if (IS_ALIGNED(width, 64)) { - MirrorRow = MirrorRow_MSA; - } - } -#endif -#if defined(HAS_COPYROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - CopyRow = IS_ALIGNED(width, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2; - } -#endif -#if defined(HAS_COPYROW_AVX) - if (TestCpuFlag(kCpuHasAVX)) { - CopyRow = IS_ALIGNED(width, 64) ? CopyRow_AVX : CopyRow_Any_AVX; - } -#endif -#if defined(HAS_COPYROW_ERMS) - if (TestCpuFlag(kCpuHasERMS)) { - CopyRow = CopyRow_ERMS; - } -#endif -#if defined(HAS_COPYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - CopyRow = IS_ALIGNED(width, 32) ? CopyRow_NEON : CopyRow_Any_NEON; - } -#endif - - // Odd height will harmlessly mirror the middle row twice. - for (y = 0; y < half_height; ++y) { - MirrorRow(src, row, width); // Mirror first row into a buffer - src += src_stride; - MirrorRow(src_bot, dst, width); // Mirror last row into first row - dst += dst_stride; - CopyRow(row, dst_bot, width); // Copy first mirrored row into last - src_bot -= src_stride; - dst_bot -= dst_stride; - } - free_aligned_buffer_64(row); -} - -LIBYUV_API -void TransposeUV(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width, - int height) { - int i = height; -#if defined(HAS_TRANSPOSEUVWX16_MSA) - void (*TransposeUVWx16)(const uint8_t* src, int src_stride, uint8_t* dst_a, - int dst_stride_a, uint8_t* dst_b, int dst_stride_b, - int width) = TransposeUVWx16_C; -#else - void (*TransposeUVWx8)(const uint8_t* src, int src_stride, uint8_t* dst_a, - int dst_stride_a, uint8_t* dst_b, int dst_stride_b, - int width) = TransposeUVWx8_C; -#endif -#if defined(HAS_TRANSPOSEUVWX8_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - TransposeUVWx8 = TransposeUVWx8_NEON; - } -#endif -#if defined(HAS_TRANSPOSEUVWX8_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - TransposeUVWx8 = TransposeUVWx8_Any_SSE2; - if (IS_ALIGNED(width, 8)) { - TransposeUVWx8 = TransposeUVWx8_SSE2; - } - } -#endif -#if defined(HAS_TRANSPOSEUVWX16_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - TransposeUVWx16 = TransposeUVWx16_Any_MSA; - if (IS_ALIGNED(width, 8)) { - TransposeUVWx16 = TransposeUVWx16_MSA; - } - } -#endif - -#if defined(HAS_TRANSPOSEUVWX16_MSA) - // Work through the source in 8x8 tiles. - while (i >= 16) { - TransposeUVWx16(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b, - width); - src += 16 * src_stride; // Go down 16 rows. - dst_a += 16; // Move over 8 columns. - dst_b += 16; // Move over 8 columns. - i -= 16; - } -#else - // Work through the source in 8x8 tiles. - while (i >= 8) { - TransposeUVWx8(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b, - width); - src += 8 * src_stride; // Go down 8 rows. - dst_a += 8; // Move over 8 columns. - dst_b += 8; // Move over 8 columns. - i -= 8; - } -#endif - - if (i > 0) { - TransposeUVWxH_C(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b, - width, i); - } -} - -LIBYUV_API -void RotateUV90(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width, - int height) { - src += src_stride * (height - 1); - src_stride = -src_stride; - - TransposeUV(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b, width, - height); -} - -LIBYUV_API -void RotateUV270(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width, - int height) { - dst_a += dst_stride_a * (width - 1); - dst_b += dst_stride_b * (width - 1); - dst_stride_a = -dst_stride_a; - dst_stride_b = -dst_stride_b; - - TransposeUV(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b, width, - height); -} - -// Rotate 180 is a horizontal and vertical flip. -LIBYUV_API -void RotateUV180(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width, - int height) { - int i; - void (*MirrorUVRow)(const uint8_t* src, uint8_t* dst_u, uint8_t* dst_v, - int width) = MirrorUVRow_C; -#if defined(HAS_MIRRORUVROW_NEON) - if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { - MirrorUVRow = MirrorUVRow_NEON; - } -#endif -#if defined(HAS_MIRRORUVROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 16)) { - MirrorUVRow = MirrorUVRow_SSSE3; - } -#endif -#if defined(HAS_MIRRORUVROW_MSA) - if (TestCpuFlag(kCpuHasMSA) && IS_ALIGNED(width, 32)) { - MirrorUVRow = MirrorUVRow_MSA; - } -#endif - - dst_a += dst_stride_a * (height - 1); - dst_b += dst_stride_b * (height - 1); - - for (i = 0; i < height; ++i) { - MirrorUVRow(src, dst_a, dst_b, width); - src += src_stride; - dst_a -= dst_stride_a; - dst_b -= dst_stride_b; - } -} - -LIBYUV_API -int RotatePlane(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width, - int height, - enum RotationMode mode) { - if (!src || width <= 0 || height == 0 || !dst) { - return -1; - } - - // Negative height means invert the image. - if (height < 0) { - height = -height; - src = src + (height - 1) * src_stride; - src_stride = -src_stride; - } - - switch (mode) { - case kRotate0: - // copy frame - CopyPlane(src, src_stride, dst, dst_stride, width, height); - return 0; - case kRotate90: - RotatePlane90(src, src_stride, dst, dst_stride, width, height); - return 0; - case kRotate270: - RotatePlane270(src, src_stride, dst, dst_stride, width, height); - return 0; - case kRotate180: - RotatePlane180(src, src_stride, dst, dst_stride, width, height); - return 0; - default: - break; - } - return -1; -} - -LIBYUV_API -int I420Rotate(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height, - enum RotationMode mode) { - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - if (!src_y || !src_u || !src_v || width <= 0 || height == 0 || !dst_y || - !dst_u || !dst_v) { - return -1; - } - - // Negative height means invert the image. - if (height < 0) { - height = -height; - halfheight = (height + 1) >> 1; - src_y = src_y + (height - 1) * src_stride_y; - src_u = src_u + (halfheight - 1) * src_stride_u; - src_v = src_v + (halfheight - 1) * src_stride_v; - src_stride_y = -src_stride_y; - src_stride_u = -src_stride_u; - src_stride_v = -src_stride_v; - } - - switch (mode) { - case kRotate0: - // copy frame - return I420Copy(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u, - dst_v, dst_stride_v, width, height); - case kRotate90: - RotatePlane90(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - RotatePlane90(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, - halfheight); - RotatePlane90(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, - halfheight); - return 0; - case kRotate270: - RotatePlane270(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - RotatePlane270(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, - halfheight); - RotatePlane270(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, - halfheight); - return 0; - case kRotate180: - RotatePlane180(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - RotatePlane180(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, - halfheight); - RotatePlane180(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, - halfheight); - return 0; - default: - break; - } - return -1; -} - -LIBYUV_API -int NV12ToI420Rotate(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_uv, - int src_stride_uv, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int width, - int height, - enum RotationMode mode) { - int halfwidth = (width + 1) >> 1; - int halfheight = (height + 1) >> 1; - if (!src_y || !src_uv || width <= 0 || height == 0 || !dst_y || !dst_u || - !dst_v) { - return -1; - } - - // Negative height means invert the image. - if (height < 0) { - height = -height; - halfheight = (height + 1) >> 1; - src_y = src_y + (height - 1) * src_stride_y; - src_uv = src_uv + (halfheight - 1) * src_stride_uv; - src_stride_y = -src_stride_y; - src_stride_uv = -src_stride_uv; - } - - switch (mode) { - case kRotate0: - // copy frame - return NV12ToI420(src_y, src_stride_y, src_uv, src_stride_uv, dst_y, - dst_stride_y, dst_u, dst_stride_u, dst_v, dst_stride_v, - width, height); - case kRotate90: - RotatePlane90(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - RotateUV90(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v, - dst_stride_v, halfwidth, halfheight); - return 0; - case kRotate270: - RotatePlane270(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - RotateUV270(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v, - dst_stride_v, halfwidth, halfheight); - return 0; - case kRotate180: - RotatePlane180(src_y, src_stride_y, dst_y, dst_stride_y, width, height); - RotateUV180(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v, - dst_stride_v, halfwidth, halfheight); - return 0; - default: - break; - } - return -1; -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_any.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_any.cc deleted file mode 100644 index c2752e62..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_any.cc +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2015 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/rotate.h" -#include "libyuv/rotate_row.h" - -#include "libyuv/basic_types.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -#define TANY(NAMEANY, TPOS_SIMD, MASK) \ - void NAMEANY(const uint8_t* src, int src_stride, uint8_t* dst, \ - int dst_stride, int width) { \ - int r = width & MASK; \ - int n = width - r; \ - if (n > 0) { \ - TPOS_SIMD(src, src_stride, dst, dst_stride, n); \ - } \ - TransposeWx8_C(src + n, src_stride, dst + n * dst_stride, dst_stride, r); \ - } - -#ifdef HAS_TRANSPOSEWX8_NEON -TANY(TransposeWx8_Any_NEON, TransposeWx8_NEON, 7) -#endif -#ifdef HAS_TRANSPOSEWX8_SSSE3 -TANY(TransposeWx8_Any_SSSE3, TransposeWx8_SSSE3, 7) -#endif -#ifdef HAS_TRANSPOSEWX8_FAST_SSSE3 -TANY(TransposeWx8_Fast_Any_SSSE3, TransposeWx8_Fast_SSSE3, 15) -#endif -#ifdef HAS_TRANSPOSEWX16_MSA -TANY(TransposeWx16_Any_MSA, TransposeWx16_MSA, 15) -#endif -#undef TANY - -#define TUVANY(NAMEANY, TPOS_SIMD, MASK) \ - void NAMEANY(const uint8_t* src, int src_stride, uint8_t* dst_a, \ - int dst_stride_a, uint8_t* dst_b, int dst_stride_b, \ - int width) { \ - int r = width & MASK; \ - int n = width - r; \ - if (n > 0) { \ - TPOS_SIMD(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b, n); \ - } \ - TransposeUVWx8_C(src + n * 2, src_stride, dst_a + n * dst_stride_a, \ - dst_stride_a, dst_b + n * dst_stride_b, dst_stride_b, r); \ - } - -#ifdef HAS_TRANSPOSEUVWX8_NEON -TUVANY(TransposeUVWx8_Any_NEON, TransposeUVWx8_NEON, 7) -#endif -#ifdef HAS_TRANSPOSEUVWX8_SSE2 -TUVANY(TransposeUVWx8_Any_SSE2, TransposeUVWx8_SSE2, 7) -#endif -#ifdef HAS_TRANSPOSEUVWX16_MSA -TUVANY(TransposeUVWx16_Any_MSA, TransposeUVWx16_MSA, 7) -#endif -#undef TUVANY - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_argb.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_argb.cc deleted file mode 100644 index 5a6e0537..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_argb.cc +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright 2012 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/rotate.h" - -#include "libyuv/convert.h" -#include "libyuv/cpu_id.h" -#include "libyuv/planar_functions.h" -#include "libyuv/row.h" -#include "libyuv/scale_row.h" /* for ScaleARGBRowDownEven_ */ - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -static void ARGBTranspose(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - int i; - int src_pixel_step = src_stride_argb >> 2; - void (*ScaleARGBRowDownEven)( - const uint8_t* src_argb, ptrdiff_t src_stride_argb, int src_step, - uint8_t* dst_argb, int dst_width) = ScaleARGBRowDownEven_C; -#if defined(HAS_SCALEARGBROWDOWNEVEN_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ScaleARGBRowDownEven = ScaleARGBRowDownEven_Any_SSE2; - if (IS_ALIGNED(height, 4)) { // Width of dest. - ScaleARGBRowDownEven = ScaleARGBRowDownEven_SSE2; - } - } -#endif -#if defined(HAS_SCALEARGBROWDOWNEVEN_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ScaleARGBRowDownEven = ScaleARGBRowDownEven_Any_NEON; - if (IS_ALIGNED(height, 4)) { // Width of dest. - ScaleARGBRowDownEven = ScaleARGBRowDownEven_NEON; - } - } -#endif -#if defined(HAS_SCALEARGBROWDOWNEVEN_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ScaleARGBRowDownEven = ScaleARGBRowDownEven_Any_MSA; - if (IS_ALIGNED(height, 4)) { // Width of dest. - ScaleARGBRowDownEven = ScaleARGBRowDownEven_MSA; - } - } -#endif - - for (i = 0; i < width; ++i) { // column of source to row of dest. - ScaleARGBRowDownEven(src_argb, 0, src_pixel_step, dst_argb, height); - dst_argb += dst_stride_argb; - src_argb += 4; - } -} - -void ARGBRotate90(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - // Rotate by 90 is a ARGBTranspose with the source read - // from bottom to top. So set the source pointer to the end - // of the buffer and flip the sign of the source stride. - src_argb += src_stride_argb * (height - 1); - src_stride_argb = -src_stride_argb; - ARGBTranspose(src_argb, src_stride_argb, dst_argb, dst_stride_argb, width, - height); -} - -void ARGBRotate270(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - // Rotate by 270 is a ARGBTranspose with the destination written - // from bottom to top. So set the destination pointer to the end - // of the buffer and flip the sign of the destination stride. - dst_argb += dst_stride_argb * (width - 1); - dst_stride_argb = -dst_stride_argb; - ARGBTranspose(src_argb, src_stride_argb, dst_argb, dst_stride_argb, width, - height); -} - -void ARGBRotate180(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height) { - // Swap first and last row and mirror the content. Uses a temporary row. - align_buffer_64(row, width * 4); - const uint8_t* src_bot = src_argb + src_stride_argb * (height - 1); - uint8_t* dst_bot = dst_argb + dst_stride_argb * (height - 1); - int half_height = (height + 1) >> 1; - int y; - void (*ARGBMirrorRow)(const uint8_t* src_argb, uint8_t* dst_argb, int width) = - ARGBMirrorRow_C; - void (*CopyRow)(const uint8_t* src_argb, uint8_t* dst_argb, int width) = - CopyRow_C; -#if defined(HAS_ARGBMIRRORROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ARGBMirrorRow = ARGBMirrorRow_Any_NEON; - if (IS_ALIGNED(width, 4)) { - ARGBMirrorRow = ARGBMirrorRow_NEON; - } - } -#endif -#if defined(HAS_ARGBMIRRORROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ARGBMirrorRow = ARGBMirrorRow_Any_SSE2; - if (IS_ALIGNED(width, 4)) { - ARGBMirrorRow = ARGBMirrorRow_SSE2; - } - } -#endif -#if defined(HAS_ARGBMIRRORROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ARGBMirrorRow = ARGBMirrorRow_Any_AVX2; - if (IS_ALIGNED(width, 8)) { - ARGBMirrorRow = ARGBMirrorRow_AVX2; - } - } -#endif -#if defined(HAS_ARGBMIRRORROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ARGBMirrorRow = ARGBMirrorRow_Any_MSA; - if (IS_ALIGNED(width, 16)) { - ARGBMirrorRow = ARGBMirrorRow_MSA; - } - } -#endif -#if defined(HAS_COPYROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - CopyRow = IS_ALIGNED(width * 4, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2; - } -#endif -#if defined(HAS_COPYROW_AVX) - if (TestCpuFlag(kCpuHasAVX)) { - CopyRow = IS_ALIGNED(width * 4, 64) ? CopyRow_AVX : CopyRow_Any_AVX; - } -#endif -#if defined(HAS_COPYROW_ERMS) - if (TestCpuFlag(kCpuHasERMS)) { - CopyRow = CopyRow_ERMS; - } -#endif -#if defined(HAS_COPYROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - CopyRow = IS_ALIGNED(width * 4, 32) ? CopyRow_NEON : CopyRow_Any_NEON; - } -#endif - - // Odd height will harmlessly mirror the middle row twice. - for (y = 0; y < half_height; ++y) { - ARGBMirrorRow(src_argb, row, width); // Mirror first row into a buffer - ARGBMirrorRow(src_bot, dst_argb, width); // Mirror last row into first row - CopyRow(row, dst_bot, width * 4); // Copy first mirrored row into last - src_argb += src_stride_argb; - dst_argb += dst_stride_argb; - src_bot -= src_stride_argb; - dst_bot -= dst_stride_argb; - } - free_aligned_buffer_64(row); -} - -LIBYUV_API -int ARGBRotate(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_argb, - int dst_stride_argb, - int width, - int height, - enum RotationMode mode) { - if (!src_argb || width <= 0 || height == 0 || !dst_argb) { - return -1; - } - - // Negative height means invert the image. - if (height < 0) { - height = -height; - src_argb = src_argb + (height - 1) * src_stride_argb; - src_stride_argb = -src_stride_argb; - } - - switch (mode) { - case kRotate0: - // copy frame - return ARGBCopy(src_argb, src_stride_argb, dst_argb, dst_stride_argb, - width, height); - case kRotate90: - ARGBRotate90(src_argb, src_stride_argb, dst_argb, dst_stride_argb, width, - height); - return 0; - case kRotate270: - ARGBRotate270(src_argb, src_stride_argb, dst_argb, dst_stride_argb, width, - height); - return 0; - case kRotate180: - ARGBRotate180(src_argb, src_stride_argb, dst_argb, dst_stride_argb, width, - height); - return 0; - default: - break; - } - return -1; -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_common.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_common.cc deleted file mode 100644 index ff212ade..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_common.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/rotate_row.h" -#include "libyuv/row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -void TransposeWx8_C(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width) { - int i; - for (i = 0; i < width; ++i) { - dst[0] = src[0 * src_stride]; - dst[1] = src[1 * src_stride]; - dst[2] = src[2 * src_stride]; - dst[3] = src[3 * src_stride]; - dst[4] = src[4 * src_stride]; - dst[5] = src[5 * src_stride]; - dst[6] = src[6 * src_stride]; - dst[7] = src[7 * src_stride]; - ++src; - dst += dst_stride; - } -} - -void TransposeUVWx8_C(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width) { - int i; - for (i = 0; i < width; ++i) { - dst_a[0] = src[0 * src_stride + 0]; - dst_b[0] = src[0 * src_stride + 1]; - dst_a[1] = src[1 * src_stride + 0]; - dst_b[1] = src[1 * src_stride + 1]; - dst_a[2] = src[2 * src_stride + 0]; - dst_b[2] = src[2 * src_stride + 1]; - dst_a[3] = src[3 * src_stride + 0]; - dst_b[3] = src[3 * src_stride + 1]; - dst_a[4] = src[4 * src_stride + 0]; - dst_b[4] = src[4 * src_stride + 1]; - dst_a[5] = src[5 * src_stride + 0]; - dst_b[5] = src[5 * src_stride + 1]; - dst_a[6] = src[6 * src_stride + 0]; - dst_b[6] = src[6 * src_stride + 1]; - dst_a[7] = src[7 * src_stride + 0]; - dst_b[7] = src[7 * src_stride + 1]; - src += 2; - dst_a += dst_stride_a; - dst_b += dst_stride_b; - } -} - -void TransposeWxH_C(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width, - int height) { - int i; - for (i = 0; i < width; ++i) { - int j; - for (j = 0; j < height; ++j) { - dst[i * dst_stride + j] = src[j * src_stride + i]; - } - } -} - -void TransposeUVWxH_C(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width, - int height) { - int i; - for (i = 0; i < width * 2; i += 2) { - int j; - for (j = 0; j < height; ++j) { - dst_a[j + ((i >> 1) * dst_stride_a)] = src[i + (j * src_stride)]; - dst_b[j + ((i >> 1) * dst_stride_b)] = src[i + (j * src_stride) + 1]; - } - } -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_gcc.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_gcc.cc deleted file mode 100644 index 04e19e29..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_gcc.cc +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright 2015 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/rotate_row.h" -#include "libyuv/row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// This module is for GCC x86 and x64. -#if !defined(LIBYUV_DISABLE_X86) && \ - (defined(__x86_64__) || (defined(__i386__) && !defined(_MSC_VER))) - -// Transpose 8x8. 32 or 64 bit, but not NaCL for 64 bit. -#if defined(HAS_TRANSPOSEWX8_SSSE3) -void TransposeWx8_SSSE3(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width) { - asm volatile( - // Read in the data from the source pointer. - // First round of bit swap. - LABELALIGN - "1: \n" - "movq (%0),%%xmm0 \n" - "movq (%0,%3),%%xmm1 \n" - "lea (%0,%3,2),%0 \n" - "punpcklbw %%xmm1,%%xmm0 \n" - "movq (%0),%%xmm2 \n" - "movdqa %%xmm0,%%xmm1 \n" - "palignr $0x8,%%xmm1,%%xmm1 \n" - "movq (%0,%3),%%xmm3 \n" - "lea (%0,%3,2),%0 \n" - "punpcklbw %%xmm3,%%xmm2 \n" - "movdqa %%xmm2,%%xmm3 \n" - "movq (%0),%%xmm4 \n" - "palignr $0x8,%%xmm3,%%xmm3 \n" - "movq (%0,%3),%%xmm5 \n" - "lea (%0,%3,2),%0 \n" - "punpcklbw %%xmm5,%%xmm4 \n" - "movdqa %%xmm4,%%xmm5 \n" - "movq (%0),%%xmm6 \n" - "palignr $0x8,%%xmm5,%%xmm5 \n" - "movq (%0,%3),%%xmm7 \n" - "lea (%0,%3,2),%0 \n" - "punpcklbw %%xmm7,%%xmm6 \n" - "neg %3 \n" - "movdqa %%xmm6,%%xmm7 \n" - "lea 0x8(%0,%3,8),%0 \n" - "palignr $0x8,%%xmm7,%%xmm7 \n" - "neg %3 \n" - // Second round of bit swap. - "punpcklwd %%xmm2,%%xmm0 \n" - "punpcklwd %%xmm3,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "movdqa %%xmm1,%%xmm3 \n" - "palignr $0x8,%%xmm2,%%xmm2 \n" - "palignr $0x8,%%xmm3,%%xmm3 \n" - "punpcklwd %%xmm6,%%xmm4 \n" - "punpcklwd %%xmm7,%%xmm5 \n" - "movdqa %%xmm4,%%xmm6 \n" - "movdqa %%xmm5,%%xmm7 \n" - "palignr $0x8,%%xmm6,%%xmm6 \n" - "palignr $0x8,%%xmm7,%%xmm7 \n" - // Third round of bit swap. - // Write to the destination pointer. - "punpckldq %%xmm4,%%xmm0 \n" - "movq %%xmm0,(%1) \n" - "movdqa %%xmm0,%%xmm4 \n" - "palignr $0x8,%%xmm4,%%xmm4 \n" - "movq %%xmm4,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "punpckldq %%xmm6,%%xmm2 \n" - "movdqa %%xmm2,%%xmm6 \n" - "movq %%xmm2,(%1) \n" - "palignr $0x8,%%xmm6,%%xmm6 \n" - "punpckldq %%xmm5,%%xmm1 \n" - "movq %%xmm6,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "movdqa %%xmm1,%%xmm5 \n" - "movq %%xmm1,(%1) \n" - "palignr $0x8,%%xmm5,%%xmm5 \n" - "movq %%xmm5,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "punpckldq %%xmm7,%%xmm3 \n" - "movq %%xmm3,(%1) \n" - "movdqa %%xmm3,%%xmm7 \n" - "palignr $0x8,%%xmm7,%%xmm7 \n" - "sub $0x8,%2 \n" - "movq %%xmm7,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "r"((intptr_t)(src_stride)), // %3 - "r"((intptr_t)(dst_stride)) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} -#endif // defined(HAS_TRANSPOSEWX8_SSSE3) - -// Transpose 16x8. 64 bit -#if defined(HAS_TRANSPOSEWX8_FAST_SSSE3) -void TransposeWx8_Fast_SSSE3(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width) { - asm volatile( - // Read in the data from the source pointer. - // First round of bit swap. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu (%0,%3),%%xmm1 \n" - "lea (%0,%3,2),%0 \n" - "movdqa %%xmm0,%%xmm8 \n" - "punpcklbw %%xmm1,%%xmm0 \n" - "punpckhbw %%xmm1,%%xmm8 \n" - "movdqu (%0),%%xmm2 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm8,%%xmm9 \n" - "palignr $0x8,%%xmm1,%%xmm1 \n" - "palignr $0x8,%%xmm9,%%xmm9 \n" - "movdqu (%0,%3),%%xmm3 \n" - "lea (%0,%3,2),%0 \n" - "movdqa %%xmm2,%%xmm10 \n" - "punpcklbw %%xmm3,%%xmm2 \n" - "punpckhbw %%xmm3,%%xmm10 \n" - "movdqa %%xmm2,%%xmm3 \n" - "movdqa %%xmm10,%%xmm11 \n" - "movdqu (%0),%%xmm4 \n" - "palignr $0x8,%%xmm3,%%xmm3 \n" - "palignr $0x8,%%xmm11,%%xmm11 \n" - "movdqu (%0,%3),%%xmm5 \n" - "lea (%0,%3,2),%0 \n" - "movdqa %%xmm4,%%xmm12 \n" - "punpcklbw %%xmm5,%%xmm4 \n" - "punpckhbw %%xmm5,%%xmm12 \n" - "movdqa %%xmm4,%%xmm5 \n" - "movdqa %%xmm12,%%xmm13 \n" - "movdqu (%0),%%xmm6 \n" - "palignr $0x8,%%xmm5,%%xmm5 \n" - "palignr $0x8,%%xmm13,%%xmm13 \n" - "movdqu (%0,%3),%%xmm7 \n" - "lea (%0,%3,2),%0 \n" - "movdqa %%xmm6,%%xmm14 \n" - "punpcklbw %%xmm7,%%xmm6 \n" - "punpckhbw %%xmm7,%%xmm14 \n" - "neg %3 \n" - "movdqa %%xmm6,%%xmm7 \n" - "movdqa %%xmm14,%%xmm15 \n" - "lea 0x10(%0,%3,8),%0 \n" - "palignr $0x8,%%xmm7,%%xmm7 \n" - "palignr $0x8,%%xmm15,%%xmm15 \n" - "neg %3 \n" - // Second round of bit swap. - "punpcklwd %%xmm2,%%xmm0 \n" - "punpcklwd %%xmm3,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "movdqa %%xmm1,%%xmm3 \n" - "palignr $0x8,%%xmm2,%%xmm2 \n" - "palignr $0x8,%%xmm3,%%xmm3 \n" - "punpcklwd %%xmm6,%%xmm4 \n" - "punpcklwd %%xmm7,%%xmm5 \n" - "movdqa %%xmm4,%%xmm6 \n" - "movdqa %%xmm5,%%xmm7 \n" - "palignr $0x8,%%xmm6,%%xmm6 \n" - "palignr $0x8,%%xmm7,%%xmm7 \n" - "punpcklwd %%xmm10,%%xmm8 \n" - "punpcklwd %%xmm11,%%xmm9 \n" - "movdqa %%xmm8,%%xmm10 \n" - "movdqa %%xmm9,%%xmm11 \n" - "palignr $0x8,%%xmm10,%%xmm10 \n" - "palignr $0x8,%%xmm11,%%xmm11 \n" - "punpcklwd %%xmm14,%%xmm12 \n" - "punpcklwd %%xmm15,%%xmm13 \n" - "movdqa %%xmm12,%%xmm14 \n" - "movdqa %%xmm13,%%xmm15 \n" - "palignr $0x8,%%xmm14,%%xmm14 \n" - "palignr $0x8,%%xmm15,%%xmm15 \n" - // Third round of bit swap. - // Write to the destination pointer. - "punpckldq %%xmm4,%%xmm0 \n" - "movq %%xmm0,(%1) \n" - "movdqa %%xmm0,%%xmm4 \n" - "palignr $0x8,%%xmm4,%%xmm4 \n" - "movq %%xmm4,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "punpckldq %%xmm6,%%xmm2 \n" - "movdqa %%xmm2,%%xmm6 \n" - "movq %%xmm2,(%1) \n" - "palignr $0x8,%%xmm6,%%xmm6 \n" - "punpckldq %%xmm5,%%xmm1 \n" - "movq %%xmm6,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "movdqa %%xmm1,%%xmm5 \n" - "movq %%xmm1,(%1) \n" - "palignr $0x8,%%xmm5,%%xmm5 \n" - "movq %%xmm5,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "punpckldq %%xmm7,%%xmm3 \n" - "movq %%xmm3,(%1) \n" - "movdqa %%xmm3,%%xmm7 \n" - "palignr $0x8,%%xmm7,%%xmm7 \n" - "movq %%xmm7,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "punpckldq %%xmm12,%%xmm8 \n" - "movq %%xmm8,(%1) \n" - "movdqa %%xmm8,%%xmm12 \n" - "palignr $0x8,%%xmm12,%%xmm12 \n" - "movq %%xmm12,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "punpckldq %%xmm14,%%xmm10 \n" - "movdqa %%xmm10,%%xmm14 \n" - "movq %%xmm10,(%1) \n" - "palignr $0x8,%%xmm14,%%xmm14 \n" - "punpckldq %%xmm13,%%xmm9 \n" - "movq %%xmm14,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "movdqa %%xmm9,%%xmm13 \n" - "movq %%xmm9,(%1) \n" - "palignr $0x8,%%xmm13,%%xmm13 \n" - "movq %%xmm13,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "punpckldq %%xmm15,%%xmm11 \n" - "movq %%xmm11,(%1) \n" - "movdqa %%xmm11,%%xmm15 \n" - "palignr $0x8,%%xmm15,%%xmm15 \n" - "sub $0x10,%2 \n" - "movq %%xmm15,(%1,%4) \n" - "lea (%1,%4,2),%1 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "r"((intptr_t)(src_stride)), // %3 - "r"((intptr_t)(dst_stride)) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", - "xmm15"); -} -#endif // defined(HAS_TRANSPOSEWX8_FAST_SSSE3) - -// Transpose UV 8x8. 64 bit. -#if defined(HAS_TRANSPOSEUVWX8_SSE2) -void TransposeUVWx8_SSE2(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width) { - asm volatile( - // Read in the data from the source pointer. - // First round of bit swap. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu (%0,%4),%%xmm1 \n" - "lea (%0,%4,2),%0 \n" - "movdqa %%xmm0,%%xmm8 \n" - "punpcklbw %%xmm1,%%xmm0 \n" - "punpckhbw %%xmm1,%%xmm8 \n" - "movdqa %%xmm8,%%xmm1 \n" - "movdqu (%0),%%xmm2 \n" - "movdqu (%0,%4),%%xmm3 \n" - "lea (%0,%4,2),%0 \n" - "movdqa %%xmm2,%%xmm8 \n" - "punpcklbw %%xmm3,%%xmm2 \n" - "punpckhbw %%xmm3,%%xmm8 \n" - "movdqa %%xmm8,%%xmm3 \n" - "movdqu (%0),%%xmm4 \n" - "movdqu (%0,%4),%%xmm5 \n" - "lea (%0,%4,2),%0 \n" - "movdqa %%xmm4,%%xmm8 \n" - "punpcklbw %%xmm5,%%xmm4 \n" - "punpckhbw %%xmm5,%%xmm8 \n" - "movdqa %%xmm8,%%xmm5 \n" - "movdqu (%0),%%xmm6 \n" - "movdqu (%0,%4),%%xmm7 \n" - "lea (%0,%4,2),%0 \n" - "movdqa %%xmm6,%%xmm8 \n" - "punpcklbw %%xmm7,%%xmm6 \n" - "neg %4 \n" - "lea 0x10(%0,%4,8),%0 \n" - "punpckhbw %%xmm7,%%xmm8 \n" - "movdqa %%xmm8,%%xmm7 \n" - "neg %4 \n" - // Second round of bit swap. - "movdqa %%xmm0,%%xmm8 \n" - "movdqa %%xmm1,%%xmm9 \n" - "punpckhwd %%xmm2,%%xmm8 \n" - "punpckhwd %%xmm3,%%xmm9 \n" - "punpcklwd %%xmm2,%%xmm0 \n" - "punpcklwd %%xmm3,%%xmm1 \n" - "movdqa %%xmm8,%%xmm2 \n" - "movdqa %%xmm9,%%xmm3 \n" - "movdqa %%xmm4,%%xmm8 \n" - "movdqa %%xmm5,%%xmm9 \n" - "punpckhwd %%xmm6,%%xmm8 \n" - "punpckhwd %%xmm7,%%xmm9 \n" - "punpcklwd %%xmm6,%%xmm4 \n" - "punpcklwd %%xmm7,%%xmm5 \n" - "movdqa %%xmm8,%%xmm6 \n" - "movdqa %%xmm9,%%xmm7 \n" - // Third round of bit swap. - // Write to the destination pointer. - "movdqa %%xmm0,%%xmm8 \n" - "punpckldq %%xmm4,%%xmm0 \n" - "movlpd %%xmm0,(%1) \n" // Write back U channel - "movhpd %%xmm0,(%2) \n" // Write back V channel - "punpckhdq %%xmm4,%%xmm8 \n" - "movlpd %%xmm8,(%1,%5) \n" - "lea (%1,%5,2),%1 \n" - "movhpd %%xmm8,(%2,%6) \n" - "lea (%2,%6,2),%2 \n" - "movdqa %%xmm2,%%xmm8 \n" - "punpckldq %%xmm6,%%xmm2 \n" - "movlpd %%xmm2,(%1) \n" - "movhpd %%xmm2,(%2) \n" - "punpckhdq %%xmm6,%%xmm8 \n" - "movlpd %%xmm8,(%1,%5) \n" - "lea (%1,%5,2),%1 \n" - "movhpd %%xmm8,(%2,%6) \n" - "lea (%2,%6,2),%2 \n" - "movdqa %%xmm1,%%xmm8 \n" - "punpckldq %%xmm5,%%xmm1 \n" - "movlpd %%xmm1,(%1) \n" - "movhpd %%xmm1,(%2) \n" - "punpckhdq %%xmm5,%%xmm8 \n" - "movlpd %%xmm8,(%1,%5) \n" - "lea (%1,%5,2),%1 \n" - "movhpd %%xmm8,(%2,%6) \n" - "lea (%2,%6,2),%2 \n" - "movdqa %%xmm3,%%xmm8 \n" - "punpckldq %%xmm7,%%xmm3 \n" - "movlpd %%xmm3,(%1) \n" - "movhpd %%xmm3,(%2) \n" - "punpckhdq %%xmm7,%%xmm8 \n" - "sub $0x8,%3 \n" - "movlpd %%xmm8,(%1,%5) \n" - "lea (%1,%5,2),%1 \n" - "movhpd %%xmm8,(%2,%6) \n" - "lea (%2,%6,2),%2 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst_a), // %1 - "+r"(dst_b), // %2 - "+r"(width) // %3 - : "r"((intptr_t)(src_stride)), // %4 - "r"((intptr_t)(dst_stride_a)), // %5 - "r"((intptr_t)(dst_stride_b)) // %6 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7", "xmm8", "xmm9"); -} -#endif // defined(HAS_TRANSPOSEUVWX8_SSE2) -#endif // defined(__x86_64__) || defined(__i386__) - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_msa.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_msa.cc deleted file mode 100644 index 99bdca65..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_msa.cc +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2016 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/rotate_row.h" - -// This module is for GCC MSA -#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) -#include "libyuv/macros_msa.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -#define ILVRL_B(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - out0 = (v16u8)__msa_ilvr_b((v16i8)in1, (v16i8)in0); \ - out1 = (v16u8)__msa_ilvl_b((v16i8)in1, (v16i8)in0); \ - out2 = (v16u8)__msa_ilvr_b((v16i8)in3, (v16i8)in2); \ - out3 = (v16u8)__msa_ilvl_b((v16i8)in3, (v16i8)in2); \ - } - -#define ILVRL_H(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - out0 = (v16u8)__msa_ilvr_h((v8i16)in1, (v8i16)in0); \ - out1 = (v16u8)__msa_ilvl_h((v8i16)in1, (v8i16)in0); \ - out2 = (v16u8)__msa_ilvr_h((v8i16)in3, (v8i16)in2); \ - out3 = (v16u8)__msa_ilvl_h((v8i16)in3, (v8i16)in2); \ - } - -#define ILVRL_W(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - out0 = (v16u8)__msa_ilvr_w((v4i32)in1, (v4i32)in0); \ - out1 = (v16u8)__msa_ilvl_w((v4i32)in1, (v4i32)in0); \ - out2 = (v16u8)__msa_ilvr_w((v4i32)in3, (v4i32)in2); \ - out3 = (v16u8)__msa_ilvl_w((v4i32)in3, (v4i32)in2); \ - } - -#define ILVRL_D(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - out0 = (v16u8)__msa_ilvr_d((v2i64)in1, (v2i64)in0); \ - out1 = (v16u8)__msa_ilvl_d((v2i64)in1, (v2i64)in0); \ - out2 = (v16u8)__msa_ilvr_d((v2i64)in3, (v2i64)in2); \ - out3 = (v16u8)__msa_ilvl_d((v2i64)in3, (v2i64)in2); \ - } - -void TransposeWx16_C(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width) { - TransposeWx8_C(src, src_stride, dst, dst_stride, width); - TransposeWx8_C((src + 8 * src_stride), src_stride, (dst + 8), dst_stride, - width); -} - -void TransposeUVWx16_C(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width) { - TransposeUVWx8_C(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b, - width); - TransposeUVWx8_C((src + 8 * src_stride), src_stride, (dst_a + 8), - dst_stride_a, (dst_b + 8), dst_stride_b, width); -} - -void TransposeWx16_MSA(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width) { - int x; - const uint8_t* s; - v16u8 src0, src1, src2, src3, dst0, dst1, dst2, dst3, vec0, vec1, vec2, vec3; - v16u8 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; - v16u8 res0, res1, res2, res3, res4, res5, res6, res7, res8, res9; - - for (x = 0; x < width; x += 16) { - s = src; - src0 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src1 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src2 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src3 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - ILVRL_B(src0, src1, src2, src3, vec0, vec1, vec2, vec3); - ILVRL_H(vec0, vec2, vec1, vec3, reg0, reg1, reg2, reg3); - src0 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src1 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src2 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src3 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - ILVRL_B(src0, src1, src2, src3, vec0, vec1, vec2, vec3); - ILVRL_H(vec0, vec2, vec1, vec3, reg4, reg5, reg6, reg7); - ILVRL_W(reg0, reg4, reg1, reg5, res0, res1, res2, res3); - ILVRL_W(reg2, reg6, reg3, reg7, res4, res5, res6, res7); - src0 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src1 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src2 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src3 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - ILVRL_B(src0, src1, src2, src3, vec0, vec1, vec2, vec3); - ILVRL_H(vec0, vec2, vec1, vec3, reg0, reg1, reg2, reg3); - src0 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src1 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src2 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src3 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - ILVRL_B(src0, src1, src2, src3, vec0, vec1, vec2, vec3); - ILVRL_H(vec0, vec2, vec1, vec3, reg4, reg5, reg6, reg7); - res8 = (v16u8)__msa_ilvr_w((v4i32)reg4, (v4i32)reg0); - res9 = (v16u8)__msa_ilvl_w((v4i32)reg4, (v4i32)reg0); - ILVRL_D(res0, res8, res1, res9, dst0, dst1, dst2, dst3); - ST_UB4(dst0, dst1, dst2, dst3, dst, dst_stride); - dst += dst_stride * 4; - res8 = (v16u8)__msa_ilvr_w((v4i32)reg5, (v4i32)reg1); - res9 = (v16u8)__msa_ilvl_w((v4i32)reg5, (v4i32)reg1); - ILVRL_D(res2, res8, res3, res9, dst0, dst1, dst2, dst3); - ST_UB4(dst0, dst1, dst2, dst3, dst, dst_stride); - dst += dst_stride * 4; - res8 = (v16u8)__msa_ilvr_w((v4i32)reg6, (v4i32)reg2); - res9 = (v16u8)__msa_ilvl_w((v4i32)reg6, (v4i32)reg2); - ILVRL_D(res4, res8, res5, res9, dst0, dst1, dst2, dst3); - ST_UB4(dst0, dst1, dst2, dst3, dst, dst_stride); - dst += dst_stride * 4; - res8 = (v16u8)__msa_ilvr_w((v4i32)reg7, (v4i32)reg3); - res9 = (v16u8)__msa_ilvl_w((v4i32)reg7, (v4i32)reg3); - ILVRL_D(res6, res8, res7, res9, dst0, dst1, dst2, dst3); - ST_UB4(dst0, dst1, dst2, dst3, dst, dst_stride); - src += 16; - dst += dst_stride * 4; - } -} - -void TransposeUVWx16_MSA(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width) { - int x; - const uint8_t* s; - v16u8 src0, src1, src2, src3, dst0, dst1, dst2, dst3, vec0, vec1, vec2, vec3; - v16u8 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; - v16u8 res0, res1, res2, res3, res4, res5, res6, res7, res8, res9; - - for (x = 0; x < width; x += 8) { - s = src; - src0 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src1 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src2 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src3 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - ILVRL_B(src0, src1, src2, src3, vec0, vec1, vec2, vec3); - ILVRL_H(vec0, vec2, vec1, vec3, reg0, reg1, reg2, reg3); - src0 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src1 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src2 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src3 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - ILVRL_B(src0, src1, src2, src3, vec0, vec1, vec2, vec3); - ILVRL_H(vec0, vec2, vec1, vec3, reg4, reg5, reg6, reg7); - ILVRL_W(reg0, reg4, reg1, reg5, res0, res1, res2, res3); - ILVRL_W(reg2, reg6, reg3, reg7, res4, res5, res6, res7); - src0 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src1 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src2 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src3 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - ILVRL_B(src0, src1, src2, src3, vec0, vec1, vec2, vec3); - ILVRL_H(vec0, vec2, vec1, vec3, reg0, reg1, reg2, reg3); - src0 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src1 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src2 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - src3 = (v16u8)__msa_ld_b((v16i8*)s, 0); - s += src_stride; - ILVRL_B(src0, src1, src2, src3, vec0, vec1, vec2, vec3); - ILVRL_H(vec0, vec2, vec1, vec3, reg4, reg5, reg6, reg7); - res8 = (v16u8)__msa_ilvr_w((v4i32)reg4, (v4i32)reg0); - res9 = (v16u8)__msa_ilvl_w((v4i32)reg4, (v4i32)reg0); - ILVRL_D(res0, res8, res1, res9, dst0, dst1, dst2, dst3); - ST_UB2(dst0, dst2, dst_a, dst_stride_a); - ST_UB2(dst1, dst3, dst_b, dst_stride_b); - dst_a += dst_stride_a * 2; - dst_b += dst_stride_b * 2; - res8 = (v16u8)__msa_ilvr_w((v4i32)reg5, (v4i32)reg1); - res9 = (v16u8)__msa_ilvl_w((v4i32)reg5, (v4i32)reg1); - ILVRL_D(res2, res8, res3, res9, dst0, dst1, dst2, dst3); - ST_UB2(dst0, dst2, dst_a, dst_stride_a); - ST_UB2(dst1, dst3, dst_b, dst_stride_b); - dst_a += dst_stride_a * 2; - dst_b += dst_stride_b * 2; - res8 = (v16u8)__msa_ilvr_w((v4i32)reg6, (v4i32)reg2); - res9 = (v16u8)__msa_ilvl_w((v4i32)reg6, (v4i32)reg2); - ILVRL_D(res4, res8, res5, res9, dst0, dst1, dst2, dst3); - ST_UB2(dst0, dst2, dst_a, dst_stride_a); - ST_UB2(dst1, dst3, dst_b, dst_stride_b); - dst_a += dst_stride_a * 2; - dst_b += dst_stride_b * 2; - res8 = (v16u8)__msa_ilvr_w((v4i32)reg7, (v4i32)reg3); - res9 = (v16u8)__msa_ilvl_w((v4i32)reg7, (v4i32)reg3); - ILVRL_D(res6, res8, res7, res9, dst0, dst1, dst2, dst3); - ST_UB2(dst0, dst2, dst_a, dst_stride_a); - ST_UB2(dst1, dst3, dst_b, dst_stride_b); - src += 16; - dst_a += dst_stride_a * 2; - dst_b += dst_stride_b * 2; - } -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_neon.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_neon.cc deleted file mode 100644 index fdc0dd47..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_neon.cc +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/rotate_row.h" -#include "libyuv/row.h" - -#include "libyuv/basic_types.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -#if !defined(LIBYUV_DISABLE_NEON) && defined(__ARM_NEON__) && \ - !defined(__aarch64__) - -static const uvec8 kVTbl4x4Transpose = {0, 4, 8, 12, 1, 5, 9, 13, - 2, 6, 10, 14, 3, 7, 11, 15}; - -void TransposeWx8_NEON(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width) { - const uint8_t* src_temp; - asm volatile( - // loops are on blocks of 8. loop will stop when - // counter gets to or below 0. starting the counter - // at w-8 allow for this - "sub %5, #8 \n" - - // handle 8x8 blocks. this should be the majority of the plane - "1: \n" - "mov %0, %1 \n" - - "vld1.8 {d0}, [%0], %2 \n" - "vld1.8 {d1}, [%0], %2 \n" - "vld1.8 {d2}, [%0], %2 \n" - "vld1.8 {d3}, [%0], %2 \n" - "vld1.8 {d4}, [%0], %2 \n" - "vld1.8 {d5}, [%0], %2 \n" - "vld1.8 {d6}, [%0], %2 \n" - "vld1.8 {d7}, [%0] \n" - - "vtrn.8 d1, d0 \n" - "vtrn.8 d3, d2 \n" - "vtrn.8 d5, d4 \n" - "vtrn.8 d7, d6 \n" - - "vtrn.16 d1, d3 \n" - "vtrn.16 d0, d2 \n" - "vtrn.16 d5, d7 \n" - "vtrn.16 d4, d6 \n" - - "vtrn.32 d1, d5 \n" - "vtrn.32 d0, d4 \n" - "vtrn.32 d3, d7 \n" - "vtrn.32 d2, d6 \n" - - "vrev16.8 q0, q0 \n" - "vrev16.8 q1, q1 \n" - "vrev16.8 q2, q2 \n" - "vrev16.8 q3, q3 \n" - - "mov %0, %3 \n" - - "vst1.8 {d1}, [%0], %4 \n" - "vst1.8 {d0}, [%0], %4 \n" - "vst1.8 {d3}, [%0], %4 \n" - "vst1.8 {d2}, [%0], %4 \n" - "vst1.8 {d5}, [%0], %4 \n" - "vst1.8 {d4}, [%0], %4 \n" - "vst1.8 {d7}, [%0], %4 \n" - "vst1.8 {d6}, [%0] \n" - - "add %1, #8 \n" // src += 8 - "add %3, %3, %4, lsl #3 \n" // dst += 8 * dst_stride - "subs %5, #8 \n" // w -= 8 - "bge 1b \n" - - // add 8 back to counter. if the result is 0 there are - // no residuals. - "adds %5, #8 \n" - "beq 4f \n" - - // some residual, so between 1 and 7 lines left to transpose - "cmp %5, #2 \n" - "blt 3f \n" - - "cmp %5, #4 \n" - "blt 2f \n" - - // 4x8 block - "mov %0, %1 \n" - "vld1.32 {d0[0]}, [%0], %2 \n" - "vld1.32 {d0[1]}, [%0], %2 \n" - "vld1.32 {d1[0]}, [%0], %2 \n" - "vld1.32 {d1[1]}, [%0], %2 \n" - "vld1.32 {d2[0]}, [%0], %2 \n" - "vld1.32 {d2[1]}, [%0], %2 \n" - "vld1.32 {d3[0]}, [%0], %2 \n" - "vld1.32 {d3[1]}, [%0] \n" - - "mov %0, %3 \n" - - "vld1.8 {q3}, [%6] \n" - - "vtbl.8 d4, {d0, d1}, d6 \n" - "vtbl.8 d5, {d0, d1}, d7 \n" - "vtbl.8 d0, {d2, d3}, d6 \n" - "vtbl.8 d1, {d2, d3}, d7 \n" - - // TODO(frkoenig): Rework shuffle above to - // write out with 4 instead of 8 writes. - "vst1.32 {d4[0]}, [%0], %4 \n" - "vst1.32 {d4[1]}, [%0], %4 \n" - "vst1.32 {d5[0]}, [%0], %4 \n" - "vst1.32 {d5[1]}, [%0] \n" - - "add %0, %3, #4 \n" - "vst1.32 {d0[0]}, [%0], %4 \n" - "vst1.32 {d0[1]}, [%0], %4 \n" - "vst1.32 {d1[0]}, [%0], %4 \n" - "vst1.32 {d1[1]}, [%0] \n" - - "add %1, #4 \n" // src += 4 - "add %3, %3, %4, lsl #2 \n" // dst += 4 * dst_stride - "subs %5, #4 \n" // w -= 4 - "beq 4f \n" - - // some residual, check to see if it includes a 2x8 block, - // or less - "cmp %5, #2 \n" - "blt 3f \n" - - // 2x8 block - "2: \n" - "mov %0, %1 \n" - "vld1.16 {d0[0]}, [%0], %2 \n" - "vld1.16 {d1[0]}, [%0], %2 \n" - "vld1.16 {d0[1]}, [%0], %2 \n" - "vld1.16 {d1[1]}, [%0], %2 \n" - "vld1.16 {d0[2]}, [%0], %2 \n" - "vld1.16 {d1[2]}, [%0], %2 \n" - "vld1.16 {d0[3]}, [%0], %2 \n" - "vld1.16 {d1[3]}, [%0] \n" - - "vtrn.8 d0, d1 \n" - - "mov %0, %3 \n" - - "vst1.64 {d0}, [%0], %4 \n" - "vst1.64 {d1}, [%0] \n" - - "add %1, #2 \n" // src += 2 - "add %3, %3, %4, lsl #1 \n" // dst += 2 * dst_stride - "subs %5, #2 \n" // w -= 2 - "beq 4f \n" - - // 1x8 block - "3: \n" - "vld1.8 {d0[0]}, [%1], %2 \n" - "vld1.8 {d0[1]}, [%1], %2 \n" - "vld1.8 {d0[2]}, [%1], %2 \n" - "vld1.8 {d0[3]}, [%1], %2 \n" - "vld1.8 {d0[4]}, [%1], %2 \n" - "vld1.8 {d0[5]}, [%1], %2 \n" - "vld1.8 {d0[6]}, [%1], %2 \n" - "vld1.8 {d0[7]}, [%1] \n" - - "vst1.64 {d0}, [%3] \n" - - "4: \n" - - : "=&r"(src_temp), // %0 - "+r"(src), // %1 - "+r"(src_stride), // %2 - "+r"(dst), // %3 - "+r"(dst_stride), // %4 - "+r"(width) // %5 - : "r"(&kVTbl4x4Transpose) // %6 - : "memory", "cc", "q0", "q1", "q2", "q3"); -} - -static const uvec8 kVTbl4x4TransposeDi = {0, 8, 1, 9, 2, 10, 3, 11, - 4, 12, 5, 13, 6, 14, 7, 15}; - -void TransposeUVWx8_NEON(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width) { - const uint8_t* src_temp; - asm volatile( - // loops are on blocks of 8. loop will stop when - // counter gets to or below 0. starting the counter - // at w-8 allow for this - "sub %7, #8 \n" - - // handle 8x8 blocks. this should be the majority of the plane - "1: \n" - "mov %0, %1 \n" - - "vld2.8 {d0, d1}, [%0], %2 \n" - "vld2.8 {d2, d3}, [%0], %2 \n" - "vld2.8 {d4, d5}, [%0], %2 \n" - "vld2.8 {d6, d7}, [%0], %2 \n" - "vld2.8 {d16, d17}, [%0], %2 \n" - "vld2.8 {d18, d19}, [%0], %2 \n" - "vld2.8 {d20, d21}, [%0], %2 \n" - "vld2.8 {d22, d23}, [%0] \n" - - "vtrn.8 q1, q0 \n" - "vtrn.8 q3, q2 \n" - "vtrn.8 q9, q8 \n" - "vtrn.8 q11, q10 \n" - - "vtrn.16 q1, q3 \n" - "vtrn.16 q0, q2 \n" - "vtrn.16 q9, q11 \n" - "vtrn.16 q8, q10 \n" - - "vtrn.32 q1, q9 \n" - "vtrn.32 q0, q8 \n" - "vtrn.32 q3, q11 \n" - "vtrn.32 q2, q10 \n" - - "vrev16.8 q0, q0 \n" - "vrev16.8 q1, q1 \n" - "vrev16.8 q2, q2 \n" - "vrev16.8 q3, q3 \n" - "vrev16.8 q8, q8 \n" - "vrev16.8 q9, q9 \n" - "vrev16.8 q10, q10 \n" - "vrev16.8 q11, q11 \n" - - "mov %0, %3 \n" - - "vst1.8 {d2}, [%0], %4 \n" - "vst1.8 {d0}, [%0], %4 \n" - "vst1.8 {d6}, [%0], %4 \n" - "vst1.8 {d4}, [%0], %4 \n" - "vst1.8 {d18}, [%0], %4 \n" - "vst1.8 {d16}, [%0], %4 \n" - "vst1.8 {d22}, [%0], %4 \n" - "vst1.8 {d20}, [%0] \n" - - "mov %0, %5 \n" - - "vst1.8 {d3}, [%0], %6 \n" - "vst1.8 {d1}, [%0], %6 \n" - "vst1.8 {d7}, [%0], %6 \n" - "vst1.8 {d5}, [%0], %6 \n" - "vst1.8 {d19}, [%0], %6 \n" - "vst1.8 {d17}, [%0], %6 \n" - "vst1.8 {d23}, [%0], %6 \n" - "vst1.8 {d21}, [%0] \n" - - "add %1, #8*2 \n" // src += 8*2 - "add %3, %3, %4, lsl #3 \n" // dst_a += 8 * dst_stride_a - "add %5, %5, %6, lsl #3 \n" // dst_b += 8 * dst_stride_b - "subs %7, #8 \n" // w -= 8 - "bge 1b \n" - - // add 8 back to counter. if the result is 0 there are - // no residuals. - "adds %7, #8 \n" - "beq 4f \n" - - // some residual, so between 1 and 7 lines left to transpose - "cmp %7, #2 \n" - "blt 3f \n" - - "cmp %7, #4 \n" - "blt 2f \n" - - // TODO(frkoenig): Clean this up - // 4x8 block - "mov %0, %1 \n" - "vld1.64 {d0}, [%0], %2 \n" - "vld1.64 {d1}, [%0], %2 \n" - "vld1.64 {d2}, [%0], %2 \n" - "vld1.64 {d3}, [%0], %2 \n" - "vld1.64 {d4}, [%0], %2 \n" - "vld1.64 {d5}, [%0], %2 \n" - "vld1.64 {d6}, [%0], %2 \n" - "vld1.64 {d7}, [%0] \n" - - "vld1.8 {q15}, [%8] \n" - - "vtrn.8 q0, q1 \n" - "vtrn.8 q2, q3 \n" - - "vtbl.8 d16, {d0, d1}, d30 \n" - "vtbl.8 d17, {d0, d1}, d31 \n" - "vtbl.8 d18, {d2, d3}, d30 \n" - "vtbl.8 d19, {d2, d3}, d31 \n" - "vtbl.8 d20, {d4, d5}, d30 \n" - "vtbl.8 d21, {d4, d5}, d31 \n" - "vtbl.8 d22, {d6, d7}, d30 \n" - "vtbl.8 d23, {d6, d7}, d31 \n" - - "mov %0, %3 \n" - - "vst1.32 {d16[0]}, [%0], %4 \n" - "vst1.32 {d16[1]}, [%0], %4 \n" - "vst1.32 {d17[0]}, [%0], %4 \n" - "vst1.32 {d17[1]}, [%0], %4 \n" - - "add %0, %3, #4 \n" - "vst1.32 {d20[0]}, [%0], %4 \n" - "vst1.32 {d20[1]}, [%0], %4 \n" - "vst1.32 {d21[0]}, [%0], %4 \n" - "vst1.32 {d21[1]}, [%0] \n" - - "mov %0, %5 \n" - - "vst1.32 {d18[0]}, [%0], %6 \n" - "vst1.32 {d18[1]}, [%0], %6 \n" - "vst1.32 {d19[0]}, [%0], %6 \n" - "vst1.32 {d19[1]}, [%0], %6 \n" - - "add %0, %5, #4 \n" - "vst1.32 {d22[0]}, [%0], %6 \n" - "vst1.32 {d22[1]}, [%0], %6 \n" - "vst1.32 {d23[0]}, [%0], %6 \n" - "vst1.32 {d23[1]}, [%0] \n" - - "add %1, #4*2 \n" // src += 4 * 2 - "add %3, %3, %4, lsl #2 \n" // dst_a += 4 * - // dst_stride_a - "add %5, %5, %6, lsl #2 \n" // dst_b += 4 * - // dst_stride_b - "subs %7, #4 \n" // w -= 4 - "beq 4f \n" - - // some residual, check to see if it includes a 2x8 block, - // or less - "cmp %7, #2 \n" - "blt 3f \n" - - // 2x8 block - "2: \n" - "mov %0, %1 \n" - "vld2.16 {d0[0], d2[0]}, [%0], %2 \n" - "vld2.16 {d1[0], d3[0]}, [%0], %2 \n" - "vld2.16 {d0[1], d2[1]}, [%0], %2 \n" - "vld2.16 {d1[1], d3[1]}, [%0], %2 \n" - "vld2.16 {d0[2], d2[2]}, [%0], %2 \n" - "vld2.16 {d1[2], d3[2]}, [%0], %2 \n" - "vld2.16 {d0[3], d2[3]}, [%0], %2 \n" - "vld2.16 {d1[3], d3[3]}, [%0] \n" - - "vtrn.8 d0, d1 \n" - "vtrn.8 d2, d3 \n" - - "mov %0, %3 \n" - - "vst1.64 {d0}, [%0], %4 \n" - "vst1.64 {d2}, [%0] \n" - - "mov %0, %5 \n" - - "vst1.64 {d1}, [%0], %6 \n" - "vst1.64 {d3}, [%0] \n" - - "add %1, #2*2 \n" // src += 2 * 2 - "add %3, %3, %4, lsl #1 \n" // dst_a += 2 * - // dst_stride_a - "add %5, %5, %6, lsl #1 \n" // dst_b += 2 * - // dst_stride_b - "subs %7, #2 \n" // w -= 2 - "beq 4f \n" - - // 1x8 block - "3: \n" - "vld2.8 {d0[0], d1[0]}, [%1], %2 \n" - "vld2.8 {d0[1], d1[1]}, [%1], %2 \n" - "vld2.8 {d0[2], d1[2]}, [%1], %2 \n" - "vld2.8 {d0[3], d1[3]}, [%1], %2 \n" - "vld2.8 {d0[4], d1[4]}, [%1], %2 \n" - "vld2.8 {d0[5], d1[5]}, [%1], %2 \n" - "vld2.8 {d0[6], d1[6]}, [%1], %2 \n" - "vld2.8 {d0[7], d1[7]}, [%1] \n" - - "vst1.64 {d0}, [%3] \n" - "vst1.64 {d1}, [%5] \n" - - "4: \n" - - : "=&r"(src_temp), // %0 - "+r"(src), // %1 - "+r"(src_stride), // %2 - "+r"(dst_a), // %3 - "+r"(dst_stride_a), // %4 - "+r"(dst_b), // %5 - "+r"(dst_stride_b), // %6 - "+r"(width) // %7 - : "r"(&kVTbl4x4TransposeDi) // %8 - : "memory", "cc", "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11"); -} -#endif // defined(__ARM_NEON__) && !defined(__aarch64__) - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_neon64.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_neon64.cc deleted file mode 100644 index f469baac..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_neon64.cc +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright 2014 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/rotate_row.h" -#include "libyuv/row.h" - -#include "libyuv/basic_types.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// This module is for GCC Neon armv8 64 bit. -#if !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) - -static const uvec8 kVTbl4x4Transpose = {0, 4, 8, 12, 1, 5, 9, 13, - 2, 6, 10, 14, 3, 7, 11, 15}; - -void TransposeWx8_NEON(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width) { - const uint8_t* src_temp; - asm volatile( - // loops are on blocks of 8. loop will stop when - // counter gets to or below 0. starting the counter - // at w-8 allow for this - "sub %w3, %w3, #8 \n" - - // handle 8x8 blocks. this should be the majority of the plane - "1: \n" - "mov %0, %1 \n" - - "ld1 {v0.8b}, [%0], %5 \n" - "ld1 {v1.8b}, [%0], %5 \n" - "ld1 {v2.8b}, [%0], %5 \n" - "ld1 {v3.8b}, [%0], %5 \n" - "ld1 {v4.8b}, [%0], %5 \n" - "ld1 {v5.8b}, [%0], %5 \n" - "ld1 {v6.8b}, [%0], %5 \n" - "ld1 {v7.8b}, [%0] \n" - - "trn2 v16.8b, v0.8b, v1.8b \n" - "trn1 v17.8b, v0.8b, v1.8b \n" - "trn2 v18.8b, v2.8b, v3.8b \n" - "trn1 v19.8b, v2.8b, v3.8b \n" - "trn2 v20.8b, v4.8b, v5.8b \n" - "trn1 v21.8b, v4.8b, v5.8b \n" - "trn2 v22.8b, v6.8b, v7.8b \n" - "trn1 v23.8b, v6.8b, v7.8b \n" - - "trn2 v3.4h, v17.4h, v19.4h \n" - "trn1 v1.4h, v17.4h, v19.4h \n" - "trn2 v2.4h, v16.4h, v18.4h \n" - "trn1 v0.4h, v16.4h, v18.4h \n" - "trn2 v7.4h, v21.4h, v23.4h \n" - "trn1 v5.4h, v21.4h, v23.4h \n" - "trn2 v6.4h, v20.4h, v22.4h \n" - "trn1 v4.4h, v20.4h, v22.4h \n" - - "trn2 v21.2s, v1.2s, v5.2s \n" - "trn1 v17.2s, v1.2s, v5.2s \n" - "trn2 v20.2s, v0.2s, v4.2s \n" - "trn1 v16.2s, v0.2s, v4.2s \n" - "trn2 v23.2s, v3.2s, v7.2s \n" - "trn1 v19.2s, v3.2s, v7.2s \n" - "trn2 v22.2s, v2.2s, v6.2s \n" - "trn1 v18.2s, v2.2s, v6.2s \n" - - "mov %0, %2 \n" - - "st1 {v17.8b}, [%0], %6 \n" - "st1 {v16.8b}, [%0], %6 \n" - "st1 {v19.8b}, [%0], %6 \n" - "st1 {v18.8b}, [%0], %6 \n" - "st1 {v21.8b}, [%0], %6 \n" - "st1 {v20.8b}, [%0], %6 \n" - "st1 {v23.8b}, [%0], %6 \n" - "st1 {v22.8b}, [%0] \n" - - "add %1, %1, #8 \n" // src += 8 - "add %2, %2, %6, lsl #3 \n" // dst += 8 * dst_stride - "subs %w3, %w3, #8 \n" // w -= 8 - "b.ge 1b \n" - - // add 8 back to counter. if the result is 0 there are - // no residuals. - "adds %w3, %w3, #8 \n" - "b.eq 4f \n" - - // some residual, so between 1 and 7 lines left to transpose - "cmp %w3, #2 \n" - "b.lt 3f \n" - - "cmp %w3, #4 \n" - "b.lt 2f \n" - - // 4x8 block - "mov %0, %1 \n" - "ld1 {v0.s}[0], [%0], %5 \n" - "ld1 {v0.s}[1], [%0], %5 \n" - "ld1 {v0.s}[2], [%0], %5 \n" - "ld1 {v0.s}[3], [%0], %5 \n" - "ld1 {v1.s}[0], [%0], %5 \n" - "ld1 {v1.s}[1], [%0], %5 \n" - "ld1 {v1.s}[2], [%0], %5 \n" - "ld1 {v1.s}[3], [%0] \n" - - "mov %0, %2 \n" - - "ld1 {v2.16b}, [%4] \n" - - "tbl v3.16b, {v0.16b}, v2.16b \n" - "tbl v0.16b, {v1.16b}, v2.16b \n" - - // TODO(frkoenig): Rework shuffle above to - // write out with 4 instead of 8 writes. - "st1 {v3.s}[0], [%0], %6 \n" - "st1 {v3.s}[1], [%0], %6 \n" - "st1 {v3.s}[2], [%0], %6 \n" - "st1 {v3.s}[3], [%0] \n" - - "add %0, %2, #4 \n" - "st1 {v0.s}[0], [%0], %6 \n" - "st1 {v0.s}[1], [%0], %6 \n" - "st1 {v0.s}[2], [%0], %6 \n" - "st1 {v0.s}[3], [%0] \n" - - "add %1, %1, #4 \n" // src += 4 - "add %2, %2, %6, lsl #2 \n" // dst += 4 * dst_stride - "subs %w3, %w3, #4 \n" // w -= 4 - "b.eq 4f \n" - - // some residual, check to see if it includes a 2x8 block, - // or less - "cmp %w3, #2 \n" - "b.lt 3f \n" - - // 2x8 block - "2: \n" - "mov %0, %1 \n" - "ld1 {v0.h}[0], [%0], %5 \n" - "ld1 {v1.h}[0], [%0], %5 \n" - "ld1 {v0.h}[1], [%0], %5 \n" - "ld1 {v1.h}[1], [%0], %5 \n" - "ld1 {v0.h}[2], [%0], %5 \n" - "ld1 {v1.h}[2], [%0], %5 \n" - "ld1 {v0.h}[3], [%0], %5 \n" - "ld1 {v1.h}[3], [%0] \n" - - "trn2 v2.8b, v0.8b, v1.8b \n" - "trn1 v3.8b, v0.8b, v1.8b \n" - - "mov %0, %2 \n" - - "st1 {v3.8b}, [%0], %6 \n" - "st1 {v2.8b}, [%0] \n" - - "add %1, %1, #2 \n" // src += 2 - "add %2, %2, %6, lsl #1 \n" // dst += 2 * dst_stride - "subs %w3, %w3, #2 \n" // w -= 2 - "b.eq 4f \n" - - // 1x8 block - "3: \n" - "ld1 {v0.b}[0], [%1], %5 \n" - "ld1 {v0.b}[1], [%1], %5 \n" - "ld1 {v0.b}[2], [%1], %5 \n" - "ld1 {v0.b}[3], [%1], %5 \n" - "ld1 {v0.b}[4], [%1], %5 \n" - "ld1 {v0.b}[5], [%1], %5 \n" - "ld1 {v0.b}[6], [%1], %5 \n" - "ld1 {v0.b}[7], [%1] \n" - - "st1 {v0.8b}, [%2] \n" - - "4: \n" - - : "=&r"(src_temp), // %0 - "+r"(src), // %1 - "+r"(dst), // %2 - "+r"(width) // %3 - : "r"(&kVTbl4x4Transpose), // %4 - "r"(static_cast(src_stride)), // %5 - "r"(static_cast(dst_stride)) // %6 - : "memory", "cc", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", - "v17", "v18", "v19", "v20", "v21", "v22", "v23"); -} - -static const uint8_t kVTbl4x4TransposeDi[32] = { - 0, 16, 32, 48, 2, 18, 34, 50, 4, 20, 36, 52, 6, 22, 38, 54, - 1, 17, 33, 49, 3, 19, 35, 51, 5, 21, 37, 53, 7, 23, 39, 55}; - -void TransposeUVWx8_NEON(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int width) { - const uint8_t* src_temp; - asm volatile( - // loops are on blocks of 8. loop will stop when - // counter gets to or below 0. starting the counter - // at w-8 allow for this - "sub %w4, %w4, #8 \n" - - // handle 8x8 blocks. this should be the majority of the plane - "1: \n" - "mov %0, %1 \n" - - "ld1 {v0.16b}, [%0], %5 \n" - "ld1 {v1.16b}, [%0], %5 \n" - "ld1 {v2.16b}, [%0], %5 \n" - "ld1 {v3.16b}, [%0], %5 \n" - "ld1 {v4.16b}, [%0], %5 \n" - "ld1 {v5.16b}, [%0], %5 \n" - "ld1 {v6.16b}, [%0], %5 \n" - "ld1 {v7.16b}, [%0] \n" - - "trn1 v16.16b, v0.16b, v1.16b \n" - "trn2 v17.16b, v0.16b, v1.16b \n" - "trn1 v18.16b, v2.16b, v3.16b \n" - "trn2 v19.16b, v2.16b, v3.16b \n" - "trn1 v20.16b, v4.16b, v5.16b \n" - "trn2 v21.16b, v4.16b, v5.16b \n" - "trn1 v22.16b, v6.16b, v7.16b \n" - "trn2 v23.16b, v6.16b, v7.16b \n" - - "trn1 v0.8h, v16.8h, v18.8h \n" - "trn2 v1.8h, v16.8h, v18.8h \n" - "trn1 v2.8h, v20.8h, v22.8h \n" - "trn2 v3.8h, v20.8h, v22.8h \n" - "trn1 v4.8h, v17.8h, v19.8h \n" - "trn2 v5.8h, v17.8h, v19.8h \n" - "trn1 v6.8h, v21.8h, v23.8h \n" - "trn2 v7.8h, v21.8h, v23.8h \n" - - "trn1 v16.4s, v0.4s, v2.4s \n" - "trn2 v17.4s, v0.4s, v2.4s \n" - "trn1 v18.4s, v1.4s, v3.4s \n" - "trn2 v19.4s, v1.4s, v3.4s \n" - "trn1 v20.4s, v4.4s, v6.4s \n" - "trn2 v21.4s, v4.4s, v6.4s \n" - "trn1 v22.4s, v5.4s, v7.4s \n" - "trn2 v23.4s, v5.4s, v7.4s \n" - - "mov %0, %2 \n" - - "st1 {v16.d}[0], [%0], %6 \n" - "st1 {v18.d}[0], [%0], %6 \n" - "st1 {v17.d}[0], [%0], %6 \n" - "st1 {v19.d}[0], [%0], %6 \n" - "st1 {v16.d}[1], [%0], %6 \n" - "st1 {v18.d}[1], [%0], %6 \n" - "st1 {v17.d}[1], [%0], %6 \n" - "st1 {v19.d}[1], [%0] \n" - - "mov %0, %3 \n" - - "st1 {v20.d}[0], [%0], %7 \n" - "st1 {v22.d}[0], [%0], %7 \n" - "st1 {v21.d}[0], [%0], %7 \n" - "st1 {v23.d}[0], [%0], %7 \n" - "st1 {v20.d}[1], [%0], %7 \n" - "st1 {v22.d}[1], [%0], %7 \n" - "st1 {v21.d}[1], [%0], %7 \n" - "st1 {v23.d}[1], [%0] \n" - - "add %1, %1, #16 \n" // src += 8*2 - "add %2, %2, %6, lsl #3 \n" // dst_a += 8 * - // dst_stride_a - "add %3, %3, %7, lsl #3 \n" // dst_b += 8 * - // dst_stride_b - "subs %w4, %w4, #8 \n" // w -= 8 - "b.ge 1b \n" - - // add 8 back to counter. if the result is 0 there are - // no residuals. - "adds %w4, %w4, #8 \n" - "b.eq 4f \n" - - // some residual, so between 1 and 7 lines left to transpose - "cmp %w4, #2 \n" - "b.lt 3f \n" - - "cmp %w4, #4 \n" - "b.lt 2f \n" - - // TODO(frkoenig): Clean this up - // 4x8 block - "mov %0, %1 \n" - "ld1 {v0.8b}, [%0], %5 \n" - "ld1 {v1.8b}, [%0], %5 \n" - "ld1 {v2.8b}, [%0], %5 \n" - "ld1 {v3.8b}, [%0], %5 \n" - "ld1 {v4.8b}, [%0], %5 \n" - "ld1 {v5.8b}, [%0], %5 \n" - "ld1 {v6.8b}, [%0], %5 \n" - "ld1 {v7.8b}, [%0] \n" - - "ld1 {v30.16b}, [%8], #16 \n" - "ld1 {v31.16b}, [%8] \n" - - "tbl v16.16b, {v0.16b, v1.16b, v2.16b, v3.16b}, v30.16b \n" - "tbl v17.16b, {v0.16b, v1.16b, v2.16b, v3.16b}, v31.16b \n" - "tbl v18.16b, {v4.16b, v5.16b, v6.16b, v7.16b}, v30.16b \n" - "tbl v19.16b, {v4.16b, v5.16b, v6.16b, v7.16b}, v31.16b \n" - - "mov %0, %2 \n" - - "st1 {v16.s}[0], [%0], %6 \n" - "st1 {v16.s}[1], [%0], %6 \n" - "st1 {v16.s}[2], [%0], %6 \n" - "st1 {v16.s}[3], [%0], %6 \n" - - "add %0, %2, #4 \n" - "st1 {v18.s}[0], [%0], %6 \n" - "st1 {v18.s}[1], [%0], %6 \n" - "st1 {v18.s}[2], [%0], %6 \n" - "st1 {v18.s}[3], [%0] \n" - - "mov %0, %3 \n" - - "st1 {v17.s}[0], [%0], %7 \n" - "st1 {v17.s}[1], [%0], %7 \n" - "st1 {v17.s}[2], [%0], %7 \n" - "st1 {v17.s}[3], [%0], %7 \n" - - "add %0, %3, #4 \n" - "st1 {v19.s}[0], [%0], %7 \n" - "st1 {v19.s}[1], [%0], %7 \n" - "st1 {v19.s}[2], [%0], %7 \n" - "st1 {v19.s}[3], [%0] \n" - - "add %1, %1, #8 \n" // src += 4 * 2 - "add %2, %2, %6, lsl #2 \n" // dst_a += 4 * - // dst_stride_a - "add %3, %3, %7, lsl #2 \n" // dst_b += 4 * - // dst_stride_b - "subs %w4, %w4, #4 \n" // w -= 4 - "b.eq 4f \n" - - // some residual, check to see if it includes a 2x8 block, - // or less - "cmp %w4, #2 \n" - "b.lt 3f \n" - - // 2x8 block - "2: \n" - "mov %0, %1 \n" - "ld2 {v0.h, v1.h}[0], [%0], %5 \n" - "ld2 {v2.h, v3.h}[0], [%0], %5 \n" - "ld2 {v0.h, v1.h}[1], [%0], %5 \n" - "ld2 {v2.h, v3.h}[1], [%0], %5 \n" - "ld2 {v0.h, v1.h}[2], [%0], %5 \n" - "ld2 {v2.h, v3.h}[2], [%0], %5 \n" - "ld2 {v0.h, v1.h}[3], [%0], %5 \n" - "ld2 {v2.h, v3.h}[3], [%0] \n" - - "trn1 v4.8b, v0.8b, v2.8b \n" - "trn2 v5.8b, v0.8b, v2.8b \n" - "trn1 v6.8b, v1.8b, v3.8b \n" - "trn2 v7.8b, v1.8b, v3.8b \n" - - "mov %0, %2 \n" - - "st1 {v4.d}[0], [%0], %6 \n" - "st1 {v6.d}[0], [%0] \n" - - "mov %0, %3 \n" - - "st1 {v5.d}[0], [%0], %7 \n" - "st1 {v7.d}[0], [%0] \n" - - "add %1, %1, #4 \n" // src += 2 * 2 - "add %2, %2, %6, lsl #1 \n" // dst_a += 2 * - // dst_stride_a - "add %3, %3, %7, lsl #1 \n" // dst_b += 2 * - // dst_stride_b - "subs %w4, %w4, #2 \n" // w -= 2 - "b.eq 4f \n" - - // 1x8 block - "3: \n" - "ld2 {v0.b, v1.b}[0], [%1], %5 \n" - "ld2 {v0.b, v1.b}[1], [%1], %5 \n" - "ld2 {v0.b, v1.b}[2], [%1], %5 \n" - "ld2 {v0.b, v1.b}[3], [%1], %5 \n" - "ld2 {v0.b, v1.b}[4], [%1], %5 \n" - "ld2 {v0.b, v1.b}[5], [%1], %5 \n" - "ld2 {v0.b, v1.b}[6], [%1], %5 \n" - "ld2 {v0.b, v1.b}[7], [%1] \n" - - "st1 {v0.d}[0], [%2] \n" - "st1 {v1.d}[0], [%3] \n" - - "4: \n" - - : "=&r"(src_temp), // %0 - "+r"(src), // %1 - "+r"(dst_a), // %2 - "+r"(dst_b), // %3 - "+r"(width) // %4 - : "r"(static_cast(src_stride)), // %5 - "r"(static_cast(dst_stride_a)), // %6 - "r"(static_cast(dst_stride_b)), // %7 - "r"(&kVTbl4x4TransposeDi) // %8 - : "memory", "cc", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", - "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v30", "v31"); -} -#endif // !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_win.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_win.cc deleted file mode 100644 index e887dd52..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/rotate_win.cc +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright 2013 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/rotate_row.h" -#include "libyuv/row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// This module is for 32 bit Visual C x86 and clangcl -#if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) - -__declspec(naked) void TransposeWx8_SSSE3(const uint8_t* src, - int src_stride, - uint8_t* dst, - int dst_stride, - int width) { - __asm { - push edi - push esi - push ebp - mov eax, [esp + 12 + 4] // src - mov edi, [esp + 12 + 8] // src_stride - mov edx, [esp + 12 + 12] // dst - mov esi, [esp + 12 + 16] // dst_stride - mov ecx, [esp + 12 + 20] // width - - // Read in the data from the source pointer. - // First round of bit swap. - align 4 - convertloop: - movq xmm0, qword ptr [eax] - lea ebp, [eax + 8] - movq xmm1, qword ptr [eax + edi] - lea eax, [eax + 2 * edi] - punpcklbw xmm0, xmm1 - movq xmm2, qword ptr [eax] - movdqa xmm1, xmm0 - palignr xmm1, xmm1, 8 - movq xmm3, qword ptr [eax + edi] - lea eax, [eax + 2 * edi] - punpcklbw xmm2, xmm3 - movdqa xmm3, xmm2 - movq xmm4, qword ptr [eax] - palignr xmm3, xmm3, 8 - movq xmm5, qword ptr [eax + edi] - punpcklbw xmm4, xmm5 - lea eax, [eax + 2 * edi] - movdqa xmm5, xmm4 - movq xmm6, qword ptr [eax] - palignr xmm5, xmm5, 8 - movq xmm7, qword ptr [eax + edi] - punpcklbw xmm6, xmm7 - mov eax, ebp - movdqa xmm7, xmm6 - palignr xmm7, xmm7, 8 - // Second round of bit swap. - punpcklwd xmm0, xmm2 - punpcklwd xmm1, xmm3 - movdqa xmm2, xmm0 - movdqa xmm3, xmm1 - palignr xmm2, xmm2, 8 - palignr xmm3, xmm3, 8 - punpcklwd xmm4, xmm6 - punpcklwd xmm5, xmm7 - movdqa xmm6, xmm4 - movdqa xmm7, xmm5 - palignr xmm6, xmm6, 8 - palignr xmm7, xmm7, 8 - // Third round of bit swap. - // Write to the destination pointer. - punpckldq xmm0, xmm4 - movq qword ptr [edx], xmm0 - movdqa xmm4, xmm0 - palignr xmm4, xmm4, 8 - movq qword ptr [edx + esi], xmm4 - lea edx, [edx + 2 * esi] - punpckldq xmm2, xmm6 - movdqa xmm6, xmm2 - palignr xmm6, xmm6, 8 - movq qword ptr [edx], xmm2 - punpckldq xmm1, xmm5 - movq qword ptr [edx + esi], xmm6 - lea edx, [edx + 2 * esi] - movdqa xmm5, xmm1 - movq qword ptr [edx], xmm1 - palignr xmm5, xmm5, 8 - punpckldq xmm3, xmm7 - movq qword ptr [edx + esi], xmm5 - lea edx, [edx + 2 * esi] - movq qword ptr [edx], xmm3 - movdqa xmm7, xmm3 - palignr xmm7, xmm7, 8 - sub ecx, 8 - movq qword ptr [edx + esi], xmm7 - lea edx, [edx + 2 * esi] - jg convertloop - - pop ebp - pop esi - pop edi - ret - } -} - -__declspec(naked) void TransposeUVWx8_SSE2(const uint8_t* src, - int src_stride, - uint8_t* dst_a, - int dst_stride_a, - uint8_t* dst_b, - int dst_stride_b, - int w) { - __asm { - push ebx - push esi - push edi - push ebp - mov eax, [esp + 16 + 4] // src - mov edi, [esp + 16 + 8] // src_stride - mov edx, [esp + 16 + 12] // dst_a - mov esi, [esp + 16 + 16] // dst_stride_a - mov ebx, [esp + 16 + 20] // dst_b - mov ebp, [esp + 16 + 24] // dst_stride_b - mov ecx, esp - sub esp, 4 + 16 - and esp, ~15 - mov [esp + 16], ecx - mov ecx, [ecx + 16 + 28] // w - - align 4 - // Read in the data from the source pointer. - // First round of bit swap. - convertloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + edi] - lea eax, [eax + 2 * edi] - movdqa xmm7, xmm0 // use xmm7 as temp register. - punpcklbw xmm0, xmm1 - punpckhbw xmm7, xmm1 - movdqa xmm1, xmm7 - movdqu xmm2, [eax] - movdqu xmm3, [eax + edi] - lea eax, [eax + 2 * edi] - movdqa xmm7, xmm2 - punpcklbw xmm2, xmm3 - punpckhbw xmm7, xmm3 - movdqa xmm3, xmm7 - movdqu xmm4, [eax] - movdqu xmm5, [eax + edi] - lea eax, [eax + 2 * edi] - movdqa xmm7, xmm4 - punpcklbw xmm4, xmm5 - punpckhbw xmm7, xmm5 - movdqa xmm5, xmm7 - movdqu xmm6, [eax] - movdqu xmm7, [eax + edi] - lea eax, [eax + 2 * edi] - movdqu [esp], xmm5 // backup xmm5 - neg edi - movdqa xmm5, xmm6 // use xmm5 as temp register. - punpcklbw xmm6, xmm7 - punpckhbw xmm5, xmm7 - movdqa xmm7, xmm5 - lea eax, [eax + 8 * edi + 16] - neg edi - // Second round of bit swap. - movdqa xmm5, xmm0 - punpcklwd xmm0, xmm2 - punpckhwd xmm5, xmm2 - movdqa xmm2, xmm5 - movdqa xmm5, xmm1 - punpcklwd xmm1, xmm3 - punpckhwd xmm5, xmm3 - movdqa xmm3, xmm5 - movdqa xmm5, xmm4 - punpcklwd xmm4, xmm6 - punpckhwd xmm5, xmm6 - movdqa xmm6, xmm5 - movdqu xmm5, [esp] // restore xmm5 - movdqu [esp], xmm6 // backup xmm6 - movdqa xmm6, xmm5 // use xmm6 as temp register. - punpcklwd xmm5, xmm7 - punpckhwd xmm6, xmm7 - movdqa xmm7, xmm6 - - // Third round of bit swap. - // Write to the destination pointer. - movdqa xmm6, xmm0 - punpckldq xmm0, xmm4 - punpckhdq xmm6, xmm4 - movdqa xmm4, xmm6 - movdqu xmm6, [esp] // restore xmm6 - movlpd qword ptr [edx], xmm0 - movhpd qword ptr [ebx], xmm0 - movlpd qword ptr [edx + esi], xmm4 - lea edx, [edx + 2 * esi] - movhpd qword ptr [ebx + ebp], xmm4 - lea ebx, [ebx + 2 * ebp] - movdqa xmm0, xmm2 // use xmm0 as the temp register. - punpckldq xmm2, xmm6 - movlpd qword ptr [edx], xmm2 - movhpd qword ptr [ebx], xmm2 - punpckhdq xmm0, xmm6 - movlpd qword ptr [edx + esi], xmm0 - lea edx, [edx + 2 * esi] - movhpd qword ptr [ebx + ebp], xmm0 - lea ebx, [ebx + 2 * ebp] - movdqa xmm0, xmm1 // use xmm0 as the temp register. - punpckldq xmm1, xmm5 - movlpd qword ptr [edx], xmm1 - movhpd qword ptr [ebx], xmm1 - punpckhdq xmm0, xmm5 - movlpd qword ptr [edx + esi], xmm0 - lea edx, [edx + 2 * esi] - movhpd qword ptr [ebx + ebp], xmm0 - lea ebx, [ebx + 2 * ebp] - movdqa xmm0, xmm3 // use xmm0 as the temp register. - punpckldq xmm3, xmm7 - movlpd qword ptr [edx], xmm3 - movhpd qword ptr [ebx], xmm3 - punpckhdq xmm0, xmm7 - sub ecx, 8 - movlpd qword ptr [edx + esi], xmm0 - lea edx, [edx + 2 * esi] - movhpd qword ptr [ebx + ebp], xmm0 - lea ebx, [ebx + 2 * ebp] - jg convertloop - - mov esp, [esp + 16] - pop ebp - pop edi - pop esi - pop ebx - ret - } -} - -#endif // !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_any.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_any.cc deleted file mode 100644 index e91560c4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_any.cc +++ /dev/null @@ -1,1211 +0,0 @@ -/* - * Copyright 2012 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/row.h" - -#include // For memset. - -#include "libyuv/basic_types.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// memset for temp is meant to clear the source buffer (not dest) so that -// SIMD that reads full multiple of 16 bytes will not trigger msan errors. -// memset is not needed for production, as the garbage values are processed but -// not used, although there may be edge cases for subsampling. -// The size of the buffer is based on the largest read, which can be inferred -// by the source type (e.g. ARGB) and the mask (last parameter), or by examining -// the source code for how much the source pointers are advanced. - -// Subsampled source needs to be increase by 1 of not even. -#define SS(width, shift) (((width) + (1 << (shift)) - 1) >> (shift)) - -// Any 4 planes to 1 with yuvconstants -#define ANY41C(NAMEANY, ANY_SIMD, UVSHIFT, DUVSHIFT, BPP, MASK) \ - void NAMEANY(const uint8_t* y_buf, const uint8_t* u_buf, \ - const uint8_t* v_buf, const uint8_t* a_buf, uint8_t* dst_ptr, \ - const struct YuvConstants* yuvconstants, int width) { \ - SIMD_ALIGNED(uint8_t temp[64 * 5]); \ - memset(temp, 0, 64 * 4); /* for msan */ \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(y_buf, u_buf, v_buf, a_buf, dst_ptr, yuvconstants, n); \ - } \ - memcpy(temp, y_buf + n, r); \ - memcpy(temp + 64, u_buf + (n >> UVSHIFT), SS(r, UVSHIFT)); \ - memcpy(temp + 128, v_buf + (n >> UVSHIFT), SS(r, UVSHIFT)); \ - memcpy(temp + 192, a_buf + n, r); \ - ANY_SIMD(temp, temp + 64, temp + 128, temp + 192, temp + 256, \ - yuvconstants, MASK + 1); \ - memcpy(dst_ptr + (n >> DUVSHIFT) * BPP, temp + 256, \ - SS(r, DUVSHIFT) * BPP); \ - } - -#ifdef HAS_I422ALPHATOARGBROW_SSSE3 -ANY41C(I422AlphaToARGBRow_Any_SSSE3, I422AlphaToARGBRow_SSSE3, 1, 0, 4, 7) -#endif -#ifdef HAS_I422ALPHATOARGBROW_AVX2 -ANY41C(I422AlphaToARGBRow_Any_AVX2, I422AlphaToARGBRow_AVX2, 1, 0, 4, 15) -#endif -#ifdef HAS_I422ALPHATOARGBROW_NEON -ANY41C(I422AlphaToARGBRow_Any_NEON, I422AlphaToARGBRow_NEON, 1, 0, 4, 7) -#endif -#ifdef HAS_I422ALPHATOARGBROW_MSA -ANY41C(I422AlphaToARGBRow_Any_MSA, I422AlphaToARGBRow_MSA, 1, 0, 4, 7) -#endif -#undef ANY41C - -// Any 3 planes to 1. -#define ANY31(NAMEANY, ANY_SIMD, UVSHIFT, DUVSHIFT, BPP, MASK) \ - void NAMEANY(const uint8_t* y_buf, const uint8_t* u_buf, \ - const uint8_t* v_buf, uint8_t* dst_ptr, int width) { \ - SIMD_ALIGNED(uint8_t temp[64 * 4]); \ - memset(temp, 0, 64 * 3); /* for YUY2 and msan */ \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(y_buf, u_buf, v_buf, dst_ptr, n); \ - } \ - memcpy(temp, y_buf + n, r); \ - memcpy(temp + 64, u_buf + (n >> UVSHIFT), SS(r, UVSHIFT)); \ - memcpy(temp + 128, v_buf + (n >> UVSHIFT), SS(r, UVSHIFT)); \ - ANY_SIMD(temp, temp + 64, temp + 128, temp + 192, MASK + 1); \ - memcpy(dst_ptr + (n >> DUVSHIFT) * BPP, temp + 192, \ - SS(r, DUVSHIFT) * BPP); \ - } - -// Merge functions. -#ifdef HAS_MERGERGBROW_SSSE3 -ANY31(MergeRGBRow_Any_SSSE3, MergeRGBRow_SSSE3, 0, 0, 3, 15) -#endif -#ifdef HAS_MERGERGBROW_NEON -ANY31(MergeRGBRow_Any_NEON, MergeRGBRow_NEON, 0, 0, 3, 15) -#endif -#ifdef HAS_I422TOYUY2ROW_SSE2 -ANY31(I422ToYUY2Row_Any_SSE2, I422ToYUY2Row_SSE2, 1, 1, 4, 15) -ANY31(I422ToUYVYRow_Any_SSE2, I422ToUYVYRow_SSE2, 1, 1, 4, 15) -#endif -#ifdef HAS_I422TOYUY2ROW_AVX2 -ANY31(I422ToYUY2Row_Any_AVX2, I422ToYUY2Row_AVX2, 1, 1, 4, 31) -ANY31(I422ToUYVYRow_Any_AVX2, I422ToUYVYRow_AVX2, 1, 1, 4, 31) -#endif -#ifdef HAS_I422TOYUY2ROW_NEON -ANY31(I422ToYUY2Row_Any_NEON, I422ToYUY2Row_NEON, 1, 1, 4, 15) -#endif -#ifdef HAS_I422TOYUY2ROW_MSA -ANY31(I422ToYUY2Row_Any_MSA, I422ToYUY2Row_MSA, 1, 1, 4, 31) -#endif -#ifdef HAS_I422TOUYVYROW_NEON -ANY31(I422ToUYVYRow_Any_NEON, I422ToUYVYRow_NEON, 1, 1, 4, 15) -#endif -#ifdef HAS_I422TOUYVYROW_MSA -ANY31(I422ToUYVYRow_Any_MSA, I422ToUYVYRow_MSA, 1, 1, 4, 31) -#endif -#ifdef HAS_BLENDPLANEROW_AVX2 -ANY31(BlendPlaneRow_Any_AVX2, BlendPlaneRow_AVX2, 0, 0, 1, 31) -#endif -#ifdef HAS_BLENDPLANEROW_SSSE3 -ANY31(BlendPlaneRow_Any_SSSE3, BlendPlaneRow_SSSE3, 0, 0, 1, 7) -#endif -#undef ANY31 - -// Note that odd width replication includes 444 due to implementation -// on arm that subsamples 444 to 422 internally. -// Any 3 planes to 1 with yuvconstants -#define ANY31C(NAMEANY, ANY_SIMD, UVSHIFT, DUVSHIFT, BPP, MASK) \ - void NAMEANY(const uint8_t* y_buf, const uint8_t* u_buf, \ - const uint8_t* v_buf, uint8_t* dst_ptr, \ - const struct YuvConstants* yuvconstants, int width) { \ - SIMD_ALIGNED(uint8_t temp[128 * 4]); \ - memset(temp, 0, 128 * 3); /* for YUY2 and msan */ \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(y_buf, u_buf, v_buf, dst_ptr, yuvconstants, n); \ - } \ - memcpy(temp, y_buf + n, r); \ - memcpy(temp + 128, u_buf + (n >> UVSHIFT), SS(r, UVSHIFT)); \ - memcpy(temp + 256, v_buf + (n >> UVSHIFT), SS(r, UVSHIFT)); \ - if (width & 1) { \ - temp[128 + SS(r, UVSHIFT)] = temp[128 + SS(r, UVSHIFT) - 1]; \ - temp[256 + SS(r, UVSHIFT)] = temp[256 + SS(r, UVSHIFT) - 1]; \ - } \ - ANY_SIMD(temp, temp + 128, temp + 256, temp + 384, yuvconstants, \ - MASK + 1); \ - memcpy(dst_ptr + (n >> DUVSHIFT) * BPP, temp + 384, \ - SS(r, DUVSHIFT) * BPP); \ - } - -#ifdef HAS_I422TOARGBROW_SSSE3 -ANY31C(I422ToARGBRow_Any_SSSE3, I422ToARGBRow_SSSE3, 1, 0, 4, 7) -#endif -#ifdef HAS_I422TOAR30ROW_SSSE3 -ANY31C(I422ToAR30Row_Any_SSSE3, I422ToAR30Row_SSSE3, 1, 0, 4, 7) -#endif -#ifdef HAS_I422TOAR30ROW_AVX2 -ANY31C(I422ToAR30Row_Any_AVX2, I422ToAR30Row_AVX2, 1, 0, 4, 15) -#endif -#ifdef HAS_I444TOARGBROW_SSSE3 -ANY31C(I444ToARGBRow_Any_SSSE3, I444ToARGBRow_SSSE3, 0, 0, 4, 7) -ANY31C(I422ToRGBARow_Any_SSSE3, I422ToRGBARow_SSSE3, 1, 0, 4, 7) -ANY31C(I422ToARGB4444Row_Any_SSSE3, I422ToARGB4444Row_SSSE3, 1, 0, 2, 7) -ANY31C(I422ToARGB1555Row_Any_SSSE3, I422ToARGB1555Row_SSSE3, 1, 0, 2, 7) -ANY31C(I422ToRGB565Row_Any_SSSE3, I422ToRGB565Row_SSSE3, 1, 0, 2, 7) -ANY31C(I422ToRGB24Row_Any_SSSE3, I422ToRGB24Row_SSSE3, 1, 0, 3, 15) -#endif // HAS_I444TOARGBROW_SSSE3 -#ifdef HAS_I422TORGB24ROW_AVX2 -ANY31C(I422ToRGB24Row_Any_AVX2, I422ToRGB24Row_AVX2, 1, 0, 3, 31) -#endif -#ifdef HAS_I422TOARGBROW_AVX2 -ANY31C(I422ToARGBRow_Any_AVX2, I422ToARGBRow_AVX2, 1, 0, 4, 15) -#endif -#ifdef HAS_I422TORGBAROW_AVX2 -ANY31C(I422ToRGBARow_Any_AVX2, I422ToRGBARow_AVX2, 1, 0, 4, 15) -#endif -#ifdef HAS_I444TOARGBROW_AVX2 -ANY31C(I444ToARGBRow_Any_AVX2, I444ToARGBRow_AVX2, 0, 0, 4, 15) -#endif -#ifdef HAS_I422TOARGB4444ROW_AVX2 -ANY31C(I422ToARGB4444Row_Any_AVX2, I422ToARGB4444Row_AVX2, 1, 0, 2, 15) -#endif -#ifdef HAS_I422TOARGB1555ROW_AVX2 -ANY31C(I422ToARGB1555Row_Any_AVX2, I422ToARGB1555Row_AVX2, 1, 0, 2, 15) -#endif -#ifdef HAS_I422TORGB565ROW_AVX2 -ANY31C(I422ToRGB565Row_Any_AVX2, I422ToRGB565Row_AVX2, 1, 0, 2, 15) -#endif -#ifdef HAS_I422TOARGBROW_NEON -ANY31C(I444ToARGBRow_Any_NEON, I444ToARGBRow_NEON, 0, 0, 4, 7) -ANY31C(I422ToARGBRow_Any_NEON, I422ToARGBRow_NEON, 1, 0, 4, 7) -ANY31C(I422ToRGBARow_Any_NEON, I422ToRGBARow_NEON, 1, 0, 4, 7) -ANY31C(I422ToRGB24Row_Any_NEON, I422ToRGB24Row_NEON, 1, 0, 3, 7) -ANY31C(I422ToARGB4444Row_Any_NEON, I422ToARGB4444Row_NEON, 1, 0, 2, 7) -ANY31C(I422ToARGB1555Row_Any_NEON, I422ToARGB1555Row_NEON, 1, 0, 2, 7) -ANY31C(I422ToRGB565Row_Any_NEON, I422ToRGB565Row_NEON, 1, 0, 2, 7) -#endif -#ifdef HAS_I422TOARGBROW_MSA -ANY31C(I444ToARGBRow_Any_MSA, I444ToARGBRow_MSA, 0, 0, 4, 7) -ANY31C(I422ToARGBRow_Any_MSA, I422ToARGBRow_MSA, 1, 0, 4, 7) -ANY31C(I422ToRGBARow_Any_MSA, I422ToRGBARow_MSA, 1, 0, 4, 7) -ANY31C(I422ToRGB24Row_Any_MSA, I422ToRGB24Row_MSA, 1, 0, 3, 15) -ANY31C(I422ToARGB4444Row_Any_MSA, I422ToARGB4444Row_MSA, 1, 0, 2, 7) -ANY31C(I422ToARGB1555Row_Any_MSA, I422ToARGB1555Row_MSA, 1, 0, 2, 7) -ANY31C(I422ToRGB565Row_Any_MSA, I422ToRGB565Row_MSA, 1, 0, 2, 7) -#endif -#undef ANY31C - -// Any 3 planes of 16 bit to 1 with yuvconstants -// TODO(fbarchard): consider sharing this code with ANY31C -#define ANY31CT(NAMEANY, ANY_SIMD, UVSHIFT, DUVSHIFT, T, SBPP, BPP, MASK) \ - void NAMEANY(const T* y_buf, const T* u_buf, const T* v_buf, \ - uint8_t* dst_ptr, const struct YuvConstants* yuvconstants, \ - int width) { \ - SIMD_ALIGNED(T temp[16 * 3]); \ - SIMD_ALIGNED(uint8_t out[64]); \ - memset(temp, 0, 16 * 3 * SBPP); /* for YUY2 and msan */ \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(y_buf, u_buf, v_buf, dst_ptr, yuvconstants, n); \ - } \ - memcpy(temp, y_buf + n, r * SBPP); \ - memcpy(temp + 16, u_buf + (n >> UVSHIFT), SS(r, UVSHIFT) * SBPP); \ - memcpy(temp + 32, v_buf + (n >> UVSHIFT), SS(r, UVSHIFT) * SBPP); \ - ANY_SIMD(temp, temp + 16, temp + 32, out, yuvconstants, MASK + 1); \ - memcpy(dst_ptr + (n >> DUVSHIFT) * BPP, out, SS(r, DUVSHIFT) * BPP); \ - } - -#ifdef HAS_I210TOAR30ROW_SSSE3 -ANY31CT(I210ToAR30Row_Any_SSSE3, I210ToAR30Row_SSSE3, 1, 0, uint16_t, 2, 4, 7) -#endif -#ifdef HAS_I210TOARGBROW_SSSE3 -ANY31CT(I210ToARGBRow_Any_SSSE3, I210ToARGBRow_SSSE3, 1, 0, uint16_t, 2, 4, 7) -#endif -#ifdef HAS_I210TOARGBROW_AVX2 -ANY31CT(I210ToARGBRow_Any_AVX2, I210ToARGBRow_AVX2, 1, 0, uint16_t, 2, 4, 15) -#endif -#ifdef HAS_I210TOAR30ROW_AVX2 -ANY31CT(I210ToAR30Row_Any_AVX2, I210ToAR30Row_AVX2, 1, 0, uint16_t, 2, 4, 15) -#endif -#undef ANY31CT - -// Any 2 planes to 1. -#define ANY21(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, SBPP2, BPP, MASK) \ - void NAMEANY(const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* dst_ptr, \ - int width) { \ - SIMD_ALIGNED(uint8_t temp[64 * 3]); \ - memset(temp, 0, 64 * 2); /* for msan */ \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(y_buf, uv_buf, dst_ptr, n); \ - } \ - memcpy(temp, y_buf + n * SBPP, r * SBPP); \ - memcpy(temp + 64, uv_buf + (n >> UVSHIFT) * SBPP2, \ - SS(r, UVSHIFT) * SBPP2); \ - ANY_SIMD(temp, temp + 64, temp + 128, MASK + 1); \ - memcpy(dst_ptr + n * BPP, temp + 128, r * BPP); \ - } - -// Merge functions. -#ifdef HAS_MERGEUVROW_SSE2 -ANY21(MergeUVRow_Any_SSE2, MergeUVRow_SSE2, 0, 1, 1, 2, 15) -#endif -#ifdef HAS_MERGEUVROW_AVX2 -ANY21(MergeUVRow_Any_AVX2, MergeUVRow_AVX2, 0, 1, 1, 2, 31) -#endif -#ifdef HAS_MERGEUVROW_NEON -ANY21(MergeUVRow_Any_NEON, MergeUVRow_NEON, 0, 1, 1, 2, 15) -#endif -#ifdef HAS_MERGEUVROW_MSA -ANY21(MergeUVRow_Any_MSA, MergeUVRow_MSA, 0, 1, 1, 2, 15) -#endif - -// Math functions. -#ifdef HAS_ARGBMULTIPLYROW_SSE2 -ANY21(ARGBMultiplyRow_Any_SSE2, ARGBMultiplyRow_SSE2, 0, 4, 4, 4, 3) -#endif -#ifdef HAS_ARGBADDROW_SSE2 -ANY21(ARGBAddRow_Any_SSE2, ARGBAddRow_SSE2, 0, 4, 4, 4, 3) -#endif -#ifdef HAS_ARGBSUBTRACTROW_SSE2 -ANY21(ARGBSubtractRow_Any_SSE2, ARGBSubtractRow_SSE2, 0, 4, 4, 4, 3) -#endif -#ifdef HAS_ARGBMULTIPLYROW_AVX2 -ANY21(ARGBMultiplyRow_Any_AVX2, ARGBMultiplyRow_AVX2, 0, 4, 4, 4, 7) -#endif -#ifdef HAS_ARGBADDROW_AVX2 -ANY21(ARGBAddRow_Any_AVX2, ARGBAddRow_AVX2, 0, 4, 4, 4, 7) -#endif -#ifdef HAS_ARGBSUBTRACTROW_AVX2 -ANY21(ARGBSubtractRow_Any_AVX2, ARGBSubtractRow_AVX2, 0, 4, 4, 4, 7) -#endif -#ifdef HAS_ARGBMULTIPLYROW_NEON -ANY21(ARGBMultiplyRow_Any_NEON, ARGBMultiplyRow_NEON, 0, 4, 4, 4, 7) -#endif -#ifdef HAS_ARGBADDROW_NEON -ANY21(ARGBAddRow_Any_NEON, ARGBAddRow_NEON, 0, 4, 4, 4, 7) -#endif -#ifdef HAS_ARGBSUBTRACTROW_NEON -ANY21(ARGBSubtractRow_Any_NEON, ARGBSubtractRow_NEON, 0, 4, 4, 4, 7) -#endif -#ifdef HAS_ARGBMULTIPLYROW_MSA -ANY21(ARGBMultiplyRow_Any_MSA, ARGBMultiplyRow_MSA, 0, 4, 4, 4, 3) -#endif -#ifdef HAS_ARGBADDROW_MSA -ANY21(ARGBAddRow_Any_MSA, ARGBAddRow_MSA, 0, 4, 4, 4, 7) -#endif -#ifdef HAS_ARGBSUBTRACTROW_MSA -ANY21(ARGBSubtractRow_Any_MSA, ARGBSubtractRow_MSA, 0, 4, 4, 4, 7) -#endif -#ifdef HAS_SOBELROW_SSE2 -ANY21(SobelRow_Any_SSE2, SobelRow_SSE2, 0, 1, 1, 4, 15) -#endif -#ifdef HAS_SOBELROW_NEON -ANY21(SobelRow_Any_NEON, SobelRow_NEON, 0, 1, 1, 4, 7) -#endif -#ifdef HAS_SOBELROW_MSA -ANY21(SobelRow_Any_MSA, SobelRow_MSA, 0, 1, 1, 4, 15) -#endif -#ifdef HAS_SOBELTOPLANEROW_SSE2 -ANY21(SobelToPlaneRow_Any_SSE2, SobelToPlaneRow_SSE2, 0, 1, 1, 1, 15) -#endif -#ifdef HAS_SOBELTOPLANEROW_NEON -ANY21(SobelToPlaneRow_Any_NEON, SobelToPlaneRow_NEON, 0, 1, 1, 1, 15) -#endif -#ifdef HAS_SOBELTOPLANEROW_MSA -ANY21(SobelToPlaneRow_Any_MSA, SobelToPlaneRow_MSA, 0, 1, 1, 1, 31) -#endif -#ifdef HAS_SOBELXYROW_SSE2 -ANY21(SobelXYRow_Any_SSE2, SobelXYRow_SSE2, 0, 1, 1, 4, 15) -#endif -#ifdef HAS_SOBELXYROW_NEON -ANY21(SobelXYRow_Any_NEON, SobelXYRow_NEON, 0, 1, 1, 4, 7) -#endif -#ifdef HAS_SOBELXYROW_MSA -ANY21(SobelXYRow_Any_MSA, SobelXYRow_MSA, 0, 1, 1, 4, 15) -#endif -#undef ANY21 - -// Any 2 planes to 1 with yuvconstants -#define ANY21C(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, SBPP2, BPP, MASK) \ - void NAMEANY(const uint8_t* y_buf, const uint8_t* uv_buf, uint8_t* dst_ptr, \ - const struct YuvConstants* yuvconstants, int width) { \ - SIMD_ALIGNED(uint8_t temp[128 * 3]); \ - memset(temp, 0, 128 * 2); /* for msan */ \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(y_buf, uv_buf, dst_ptr, yuvconstants, n); \ - } \ - memcpy(temp, y_buf + n * SBPP, r * SBPP); \ - memcpy(temp + 128, uv_buf + (n >> UVSHIFT) * SBPP2, \ - SS(r, UVSHIFT) * SBPP2); \ - ANY_SIMD(temp, temp + 128, temp + 256, yuvconstants, MASK + 1); \ - memcpy(dst_ptr + n * BPP, temp + 256, r * BPP); \ - } - -// Biplanar to RGB. -#ifdef HAS_NV12TOARGBROW_SSSE3 -ANY21C(NV12ToARGBRow_Any_SSSE3, NV12ToARGBRow_SSSE3, 1, 1, 2, 4, 7) -#endif -#ifdef HAS_NV12TOARGBROW_AVX2 -ANY21C(NV12ToARGBRow_Any_AVX2, NV12ToARGBRow_AVX2, 1, 1, 2, 4, 15) -#endif -#ifdef HAS_NV12TOARGBROW_NEON -ANY21C(NV12ToARGBRow_Any_NEON, NV12ToARGBRow_NEON, 1, 1, 2, 4, 7) -#endif -#ifdef HAS_NV12TOARGBROW_MSA -ANY21C(NV12ToARGBRow_Any_MSA, NV12ToARGBRow_MSA, 1, 1, 2, 4, 7) -#endif -#ifdef HAS_NV21TOARGBROW_SSSE3 -ANY21C(NV21ToARGBRow_Any_SSSE3, NV21ToARGBRow_SSSE3, 1, 1, 2, 4, 7) -#endif -#ifdef HAS_NV21TOARGBROW_AVX2 -ANY21C(NV21ToARGBRow_Any_AVX2, NV21ToARGBRow_AVX2, 1, 1, 2, 4, 15) -#endif -#ifdef HAS_NV21TOARGBROW_NEON -ANY21C(NV21ToARGBRow_Any_NEON, NV21ToARGBRow_NEON, 1, 1, 2, 4, 7) -#endif -#ifdef HAS_NV21TOARGBROW_MSA -ANY21C(NV21ToARGBRow_Any_MSA, NV21ToARGBRow_MSA, 1, 1, 2, 4, 7) -#endif -#ifdef HAS_NV12TORGB24ROW_NEON -ANY21C(NV12ToRGB24Row_Any_NEON, NV12ToRGB24Row_NEON, 1, 1, 2, 3, 7) -#endif -#ifdef HAS_NV21TORGB24ROW_NEON -ANY21C(NV21ToRGB24Row_Any_NEON, NV21ToRGB24Row_NEON, 1, 1, 2, 3, 7) -#endif -#ifdef HAS_NV12TORGB24ROW_SSSE3 -ANY21C(NV12ToRGB24Row_Any_SSSE3, NV12ToRGB24Row_SSSE3, 1, 1, 2, 3, 15) -#endif -#ifdef HAS_NV21TORGB24ROW_SSSE3 -ANY21C(NV21ToRGB24Row_Any_SSSE3, NV21ToRGB24Row_SSSE3, 1, 1, 2, 3, 15) -#endif -#ifdef HAS_NV12TORGB24ROW_AVX2 -ANY21C(NV12ToRGB24Row_Any_AVX2, NV12ToRGB24Row_AVX2, 1, 1, 2, 3, 31) -#endif -#ifdef HAS_NV21TORGB24ROW_AVX2 -ANY21C(NV21ToRGB24Row_Any_AVX2, NV21ToRGB24Row_AVX2, 1, 1, 2, 3, 31) -#endif -#ifdef HAS_NV12TORGB565ROW_SSSE3 -ANY21C(NV12ToRGB565Row_Any_SSSE3, NV12ToRGB565Row_SSSE3, 1, 1, 2, 2, 7) -#endif -#ifdef HAS_NV12TORGB565ROW_AVX2 -ANY21C(NV12ToRGB565Row_Any_AVX2, NV12ToRGB565Row_AVX2, 1, 1, 2, 2, 15) -#endif -#ifdef HAS_NV12TORGB565ROW_NEON -ANY21C(NV12ToRGB565Row_Any_NEON, NV12ToRGB565Row_NEON, 1, 1, 2, 2, 7) -#endif -#ifdef HAS_NV12TORGB565ROW_MSA -ANY21C(NV12ToRGB565Row_Any_MSA, NV12ToRGB565Row_MSA, 1, 1, 2, 2, 7) -#endif -#undef ANY21C - -// Any 1 to 1. -#define ANY11(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, BPP, MASK) \ - void NAMEANY(const uint8_t* src_ptr, uint8_t* dst_ptr, int width) { \ - SIMD_ALIGNED(uint8_t temp[128 * 2]); \ - memset(temp, 0, 128); /* for YUY2 and msan */ \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(src_ptr, dst_ptr, n); \ - } \ - memcpy(temp, src_ptr + (n >> UVSHIFT) * SBPP, SS(r, UVSHIFT) * SBPP); \ - ANY_SIMD(temp, temp + 128, MASK + 1); \ - memcpy(dst_ptr + n * BPP, temp + 128, r * BPP); \ - } - -#ifdef HAS_COPYROW_AVX -ANY11(CopyRow_Any_AVX, CopyRow_AVX, 0, 1, 1, 63) -#endif -#ifdef HAS_COPYROW_SSE2 -ANY11(CopyRow_Any_SSE2, CopyRow_SSE2, 0, 1, 1, 31) -#endif -#ifdef HAS_COPYROW_NEON -ANY11(CopyRow_Any_NEON, CopyRow_NEON, 0, 1, 1, 31) -#endif -#if defined(HAS_ARGBTORGB24ROW_SSSE3) -ANY11(ARGBToRGB24Row_Any_SSSE3, ARGBToRGB24Row_SSSE3, 0, 4, 3, 15) -ANY11(ARGBToRAWRow_Any_SSSE3, ARGBToRAWRow_SSSE3, 0, 4, 3, 15) -ANY11(ARGBToRGB565Row_Any_SSE2, ARGBToRGB565Row_SSE2, 0, 4, 2, 3) -ANY11(ARGBToARGB1555Row_Any_SSE2, ARGBToARGB1555Row_SSE2, 0, 4, 2, 3) -ANY11(ARGBToARGB4444Row_Any_SSE2, ARGBToARGB4444Row_SSE2, 0, 4, 2, 3) -#endif -#if defined(HAS_ARGBTORGB24ROW_AVX2) -ANY11(ARGBToRGB24Row_Any_AVX2, ARGBToRGB24Row_AVX2, 0, 4, 3, 31) -#endif -#if defined(HAS_ARGBTORGB24ROW_AVX512VBMI) -ANY11(ARGBToRGB24Row_Any_AVX512VBMI, ARGBToRGB24Row_AVX512VBMI, 0, 4, 3, 31) -#endif -#if defined(HAS_ARGBTORAWROW_AVX2) -ANY11(ARGBToRAWRow_Any_AVX2, ARGBToRAWRow_AVX2, 0, 4, 3, 31) -#endif -#if defined(HAS_ARGBTORGB565ROW_AVX2) -ANY11(ARGBToRGB565Row_Any_AVX2, ARGBToRGB565Row_AVX2, 0, 4, 2, 7) -#endif -#if defined(HAS_ARGBTOARGB4444ROW_AVX2) -ANY11(ARGBToARGB1555Row_Any_AVX2, ARGBToARGB1555Row_AVX2, 0, 4, 2, 7) -ANY11(ARGBToARGB4444Row_Any_AVX2, ARGBToARGB4444Row_AVX2, 0, 4, 2, 7) -#endif -#if defined(HAS_ABGRTOAR30ROW_SSSE3) -ANY11(ABGRToAR30Row_Any_SSSE3, ABGRToAR30Row_SSSE3, 0, 4, 4, 3) -#endif -#if defined(HAS_ARGBTOAR30ROW_SSSE3) -ANY11(ARGBToAR30Row_Any_SSSE3, ARGBToAR30Row_SSSE3, 0, 4, 4, 3) -#endif -#if defined(HAS_ABGRTOAR30ROW_AVX2) -ANY11(ABGRToAR30Row_Any_AVX2, ABGRToAR30Row_AVX2, 0, 4, 4, 7) -#endif -#if defined(HAS_ARGBTOAR30ROW_AVX2) -ANY11(ARGBToAR30Row_Any_AVX2, ARGBToAR30Row_AVX2, 0, 4, 4, 7) -#endif -#if defined(HAS_J400TOARGBROW_SSE2) -ANY11(J400ToARGBRow_Any_SSE2, J400ToARGBRow_SSE2, 0, 1, 4, 7) -#endif -#if defined(HAS_J400TOARGBROW_AVX2) -ANY11(J400ToARGBRow_Any_AVX2, J400ToARGBRow_AVX2, 0, 1, 4, 15) -#endif -#if defined(HAS_I400TOARGBROW_SSE2) -ANY11(I400ToARGBRow_Any_SSE2, I400ToARGBRow_SSE2, 0, 1, 4, 7) -#endif -#if defined(HAS_I400TOARGBROW_AVX2) -ANY11(I400ToARGBRow_Any_AVX2, I400ToARGBRow_AVX2, 0, 1, 4, 15) -#endif -#if defined(HAS_RGB24TOARGBROW_SSSE3) -ANY11(RGB24ToARGBRow_Any_SSSE3, RGB24ToARGBRow_SSSE3, 0, 3, 4, 15) -ANY11(RAWToARGBRow_Any_SSSE3, RAWToARGBRow_SSSE3, 0, 3, 4, 15) -ANY11(RGB565ToARGBRow_Any_SSE2, RGB565ToARGBRow_SSE2, 0, 2, 4, 7) -ANY11(ARGB1555ToARGBRow_Any_SSE2, ARGB1555ToARGBRow_SSE2, 0, 2, 4, 7) -ANY11(ARGB4444ToARGBRow_Any_SSE2, ARGB4444ToARGBRow_SSE2, 0, 2, 4, 7) -#endif -#if defined(HAS_RAWTORGB24ROW_SSSE3) -ANY11(RAWToRGB24Row_Any_SSSE3, RAWToRGB24Row_SSSE3, 0, 3, 3, 7) -#endif -#if defined(HAS_RGB565TOARGBROW_AVX2) -ANY11(RGB565ToARGBRow_Any_AVX2, RGB565ToARGBRow_AVX2, 0, 2, 4, 15) -#endif -#if defined(HAS_ARGB1555TOARGBROW_AVX2) -ANY11(ARGB1555ToARGBRow_Any_AVX2, ARGB1555ToARGBRow_AVX2, 0, 2, 4, 15) -#endif -#if defined(HAS_ARGB4444TOARGBROW_AVX2) -ANY11(ARGB4444ToARGBRow_Any_AVX2, ARGB4444ToARGBRow_AVX2, 0, 2, 4, 15) -#endif -#if defined(HAS_ARGBTORGB24ROW_NEON) -ANY11(ARGBToRGB24Row_Any_NEON, ARGBToRGB24Row_NEON, 0, 4, 3, 7) -ANY11(ARGBToRAWRow_Any_NEON, ARGBToRAWRow_NEON, 0, 4, 3, 7) -ANY11(ARGBToRGB565Row_Any_NEON, ARGBToRGB565Row_NEON, 0, 4, 2, 7) -ANY11(ARGBToARGB1555Row_Any_NEON, ARGBToARGB1555Row_NEON, 0, 4, 2, 7) -ANY11(ARGBToARGB4444Row_Any_NEON, ARGBToARGB4444Row_NEON, 0, 4, 2, 7) -ANY11(J400ToARGBRow_Any_NEON, J400ToARGBRow_NEON, 0, 1, 4, 7) -ANY11(I400ToARGBRow_Any_NEON, I400ToARGBRow_NEON, 0, 1, 4, 7) -#endif -#if defined(HAS_ARGBTORGB24ROW_MSA) -ANY11(ARGBToRGB24Row_Any_MSA, ARGBToRGB24Row_MSA, 0, 4, 3, 15) -ANY11(ARGBToRAWRow_Any_MSA, ARGBToRAWRow_MSA, 0, 4, 3, 15) -ANY11(ARGBToRGB565Row_Any_MSA, ARGBToRGB565Row_MSA, 0, 4, 2, 7) -ANY11(ARGBToARGB1555Row_Any_MSA, ARGBToARGB1555Row_MSA, 0, 4, 2, 7) -ANY11(ARGBToARGB4444Row_Any_MSA, ARGBToARGB4444Row_MSA, 0, 4, 2, 7) -ANY11(J400ToARGBRow_Any_MSA, J400ToARGBRow_MSA, 0, 1, 4, 15) -ANY11(I400ToARGBRow_Any_MSA, I400ToARGBRow_MSA, 0, 1, 4, 15) -#endif -#if defined(HAS_RAWTORGB24ROW_NEON) -ANY11(RAWToRGB24Row_Any_NEON, RAWToRGB24Row_NEON, 0, 3, 3, 7) -#endif -#if defined(HAS_RAWTORGB24ROW_MSA) -ANY11(RAWToRGB24Row_Any_MSA, RAWToRGB24Row_MSA, 0, 3, 3, 15) -#endif -#ifdef HAS_ARGBTOYROW_AVX2 -ANY11(ARGBToYRow_Any_AVX2, ARGBToYRow_AVX2, 0, 4, 1, 31) -#endif -#ifdef HAS_ARGBTOYJROW_AVX2 -ANY11(ARGBToYJRow_Any_AVX2, ARGBToYJRow_AVX2, 0, 4, 1, 31) -#endif -#ifdef HAS_UYVYTOYROW_AVX2 -ANY11(UYVYToYRow_Any_AVX2, UYVYToYRow_AVX2, 0, 2, 1, 31) -#endif -#ifdef HAS_YUY2TOYROW_AVX2 -ANY11(YUY2ToYRow_Any_AVX2, YUY2ToYRow_AVX2, 1, 4, 1, 31) -#endif -#ifdef HAS_ARGBTOYROW_SSSE3 -ANY11(ARGBToYRow_Any_SSSE3, ARGBToYRow_SSSE3, 0, 4, 1, 15) -#endif -#ifdef HAS_BGRATOYROW_SSSE3 -ANY11(BGRAToYRow_Any_SSSE3, BGRAToYRow_SSSE3, 0, 4, 1, 15) -ANY11(ABGRToYRow_Any_SSSE3, ABGRToYRow_SSSE3, 0, 4, 1, 15) -ANY11(RGBAToYRow_Any_SSSE3, RGBAToYRow_SSSE3, 0, 4, 1, 15) -ANY11(YUY2ToYRow_Any_SSE2, YUY2ToYRow_SSE2, 1, 4, 1, 15) -ANY11(UYVYToYRow_Any_SSE2, UYVYToYRow_SSE2, 1, 4, 1, 15) -#endif -#ifdef HAS_ARGBTOYJROW_SSSE3 -ANY11(ARGBToYJRow_Any_SSSE3, ARGBToYJRow_SSSE3, 0, 4, 1, 15) -#endif -#ifdef HAS_ARGBTOYROW_NEON -ANY11(ARGBToYRow_Any_NEON, ARGBToYRow_NEON, 0, 4, 1, 7) -#endif -#ifdef HAS_ARGBTOYROW_MSA -ANY11(ARGBToYRow_Any_MSA, ARGBToYRow_MSA, 0, 4, 1, 15) -#endif -#ifdef HAS_ARGBTOYJROW_NEON -ANY11(ARGBToYJRow_Any_NEON, ARGBToYJRow_NEON, 0, 4, 1, 7) -#endif -#ifdef HAS_ARGBTOYJROW_MSA -ANY11(ARGBToYJRow_Any_MSA, ARGBToYJRow_MSA, 0, 4, 1, 15) -#endif -#ifdef HAS_BGRATOYROW_NEON -ANY11(BGRAToYRow_Any_NEON, BGRAToYRow_NEON, 0, 4, 1, 7) -#endif -#ifdef HAS_BGRATOYROW_MSA -ANY11(BGRAToYRow_Any_MSA, BGRAToYRow_MSA, 0, 4, 1, 15) -#endif -#ifdef HAS_ABGRTOYROW_NEON -ANY11(ABGRToYRow_Any_NEON, ABGRToYRow_NEON, 0, 4, 1, 7) -#endif -#ifdef HAS_ABGRTOYROW_MSA -ANY11(ABGRToYRow_Any_MSA, ABGRToYRow_MSA, 0, 4, 1, 7) -#endif -#ifdef HAS_RGBATOYROW_NEON -ANY11(RGBAToYRow_Any_NEON, RGBAToYRow_NEON, 0, 4, 1, 7) -#endif -#ifdef HAS_RGBATOYROW_MSA -ANY11(RGBAToYRow_Any_MSA, RGBAToYRow_MSA, 0, 4, 1, 15) -#endif -#ifdef HAS_RGB24TOYROW_NEON -ANY11(RGB24ToYRow_Any_NEON, RGB24ToYRow_NEON, 0, 3, 1, 7) -#endif -#ifdef HAS_RGB24TOYROW_MSA -ANY11(RGB24ToYRow_Any_MSA, RGB24ToYRow_MSA, 0, 3, 1, 15) -#endif -#ifdef HAS_RAWTOYROW_NEON -ANY11(RAWToYRow_Any_NEON, RAWToYRow_NEON, 0, 3, 1, 7) -#endif -#ifdef HAS_RAWTOYROW_MSA -ANY11(RAWToYRow_Any_MSA, RAWToYRow_MSA, 0, 3, 1, 15) -#endif -#ifdef HAS_RGB565TOYROW_NEON -ANY11(RGB565ToYRow_Any_NEON, RGB565ToYRow_NEON, 0, 2, 1, 7) -#endif -#ifdef HAS_RGB565TOYROW_MSA -ANY11(RGB565ToYRow_Any_MSA, RGB565ToYRow_MSA, 0, 2, 1, 15) -#endif -#ifdef HAS_ARGB1555TOYROW_NEON -ANY11(ARGB1555ToYRow_Any_NEON, ARGB1555ToYRow_NEON, 0, 2, 1, 7) -#endif -#ifdef HAS_ARGB1555TOYROW_MSA -ANY11(ARGB1555ToYRow_Any_MSA, ARGB1555ToYRow_MSA, 0, 2, 1, 15) -#endif -#ifdef HAS_ARGB4444TOYROW_NEON -ANY11(ARGB4444ToYRow_Any_NEON, ARGB4444ToYRow_NEON, 0, 2, 1, 7) -#endif -#ifdef HAS_YUY2TOYROW_NEON -ANY11(YUY2ToYRow_Any_NEON, YUY2ToYRow_NEON, 1, 4, 1, 15) -#endif -#ifdef HAS_UYVYTOYROW_NEON -ANY11(UYVYToYRow_Any_NEON, UYVYToYRow_NEON, 1, 4, 1, 15) -#endif -#ifdef HAS_YUY2TOYROW_MSA -ANY11(YUY2ToYRow_Any_MSA, YUY2ToYRow_MSA, 1, 4, 1, 31) -#endif -#ifdef HAS_UYVYTOYROW_MSA -ANY11(UYVYToYRow_Any_MSA, UYVYToYRow_MSA, 1, 4, 1, 31) -#endif -#ifdef HAS_RGB24TOARGBROW_NEON -ANY11(RGB24ToARGBRow_Any_NEON, RGB24ToARGBRow_NEON, 0, 3, 4, 7) -#endif -#ifdef HAS_RGB24TOARGBROW_MSA -ANY11(RGB24ToARGBRow_Any_MSA, RGB24ToARGBRow_MSA, 0, 3, 4, 15) -#endif -#ifdef HAS_RAWTOARGBROW_NEON -ANY11(RAWToARGBRow_Any_NEON, RAWToARGBRow_NEON, 0, 3, 4, 7) -#endif -#ifdef HAS_RAWTOARGBROW_MSA -ANY11(RAWToARGBRow_Any_MSA, RAWToARGBRow_MSA, 0, 3, 4, 15) -#endif -#ifdef HAS_RGB565TOARGBROW_NEON -ANY11(RGB565ToARGBRow_Any_NEON, RGB565ToARGBRow_NEON, 0, 2, 4, 7) -#endif -#ifdef HAS_RGB565TOARGBROW_MSA -ANY11(RGB565ToARGBRow_Any_MSA, RGB565ToARGBRow_MSA, 0, 2, 4, 15) -#endif -#ifdef HAS_ARGB1555TOARGBROW_NEON -ANY11(ARGB1555ToARGBRow_Any_NEON, ARGB1555ToARGBRow_NEON, 0, 2, 4, 7) -#endif -#ifdef HAS_ARGB1555TOARGBROW_MSA -ANY11(ARGB1555ToARGBRow_Any_MSA, ARGB1555ToARGBRow_MSA, 0, 2, 4, 15) -#endif -#ifdef HAS_ARGB4444TOARGBROW_NEON -ANY11(ARGB4444ToARGBRow_Any_NEON, ARGB4444ToARGBRow_NEON, 0, 2, 4, 7) -#endif -#ifdef HAS_ARGB4444TOARGBROW_MSA -ANY11(ARGB4444ToARGBRow_Any_MSA, ARGB4444ToARGBRow_MSA, 0, 2, 4, 15) -#endif -#ifdef HAS_ARGBATTENUATEROW_SSSE3 -ANY11(ARGBAttenuateRow_Any_SSSE3, ARGBAttenuateRow_SSSE3, 0, 4, 4, 3) -#endif -#ifdef HAS_ARGBUNATTENUATEROW_SSE2 -ANY11(ARGBUnattenuateRow_Any_SSE2, ARGBUnattenuateRow_SSE2, 0, 4, 4, 3) -#endif -#ifdef HAS_ARGBATTENUATEROW_AVX2 -ANY11(ARGBAttenuateRow_Any_AVX2, ARGBAttenuateRow_AVX2, 0, 4, 4, 7) -#endif -#ifdef HAS_ARGBUNATTENUATEROW_AVX2 -ANY11(ARGBUnattenuateRow_Any_AVX2, ARGBUnattenuateRow_AVX2, 0, 4, 4, 7) -#endif -#ifdef HAS_ARGBATTENUATEROW_NEON -ANY11(ARGBAttenuateRow_Any_NEON, ARGBAttenuateRow_NEON, 0, 4, 4, 7) -#endif -#ifdef HAS_ARGBATTENUATEROW_MSA -ANY11(ARGBAttenuateRow_Any_MSA, ARGBAttenuateRow_MSA, 0, 4, 4, 7) -#endif -#ifdef HAS_ARGBEXTRACTALPHAROW_SSE2 -ANY11(ARGBExtractAlphaRow_Any_SSE2, ARGBExtractAlphaRow_SSE2, 0, 4, 1, 7) -#endif -#ifdef HAS_ARGBEXTRACTALPHAROW_AVX2 -ANY11(ARGBExtractAlphaRow_Any_AVX2, ARGBExtractAlphaRow_AVX2, 0, 4, 1, 31) -#endif -#ifdef HAS_ARGBEXTRACTALPHAROW_NEON -ANY11(ARGBExtractAlphaRow_Any_NEON, ARGBExtractAlphaRow_NEON, 0, 4, 1, 15) -#endif -#ifdef HAS_ARGBEXTRACTALPHAROW_MSA -ANY11(ARGBExtractAlphaRow_Any_MSA, ARGBExtractAlphaRow_MSA, 0, 4, 1, 15) -#endif -#undef ANY11 - -// Any 1 to 1 blended. Destination is read, modify, write. -#define ANY11B(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, BPP, MASK) \ - void NAMEANY(const uint8_t* src_ptr, uint8_t* dst_ptr, int width) { \ - SIMD_ALIGNED(uint8_t temp[64 * 2]); \ - memset(temp, 0, 64 * 2); /* for msan */ \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(src_ptr, dst_ptr, n); \ - } \ - memcpy(temp, src_ptr + (n >> UVSHIFT) * SBPP, SS(r, UVSHIFT) * SBPP); \ - memcpy(temp + 64, dst_ptr + n * BPP, r * BPP); \ - ANY_SIMD(temp, temp + 64, MASK + 1); \ - memcpy(dst_ptr + n * BPP, temp + 64, r * BPP); \ - } - -#ifdef HAS_ARGBCOPYALPHAROW_AVX2 -ANY11B(ARGBCopyAlphaRow_Any_AVX2, ARGBCopyAlphaRow_AVX2, 0, 4, 4, 15) -#endif -#ifdef HAS_ARGBCOPYALPHAROW_SSE2 -ANY11B(ARGBCopyAlphaRow_Any_SSE2, ARGBCopyAlphaRow_SSE2, 0, 4, 4, 7) -#endif -#ifdef HAS_ARGBCOPYYTOALPHAROW_AVX2 -ANY11B(ARGBCopyYToAlphaRow_Any_AVX2, ARGBCopyYToAlphaRow_AVX2, 0, 1, 4, 15) -#endif -#ifdef HAS_ARGBCOPYYTOALPHAROW_SSE2 -ANY11B(ARGBCopyYToAlphaRow_Any_SSE2, ARGBCopyYToAlphaRow_SSE2, 0, 1, 4, 7) -#endif -#undef ANY11B - -// Any 1 to 1 with parameter. -#define ANY11P(NAMEANY, ANY_SIMD, T, SBPP, BPP, MASK) \ - void NAMEANY(const uint8_t* src_ptr, uint8_t* dst_ptr, T param, int width) { \ - SIMD_ALIGNED(uint8_t temp[64 * 2]); \ - memset(temp, 0, 64); /* for msan */ \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(src_ptr, dst_ptr, param, n); \ - } \ - memcpy(temp, src_ptr + n * SBPP, r * SBPP); \ - ANY_SIMD(temp, temp + 64, param, MASK + 1); \ - memcpy(dst_ptr + n * BPP, temp + 64, r * BPP); \ - } - -#if defined(HAS_ARGBTORGB565DITHERROW_SSE2) -ANY11P(ARGBToRGB565DitherRow_Any_SSE2, - ARGBToRGB565DitherRow_SSE2, - const uint32_t, - 4, - 2, - 3) -#endif -#if defined(HAS_ARGBTORGB565DITHERROW_AVX2) -ANY11P(ARGBToRGB565DitherRow_Any_AVX2, - ARGBToRGB565DitherRow_AVX2, - const uint32_t, - 4, - 2, - 7) -#endif -#if defined(HAS_ARGBTORGB565DITHERROW_NEON) -ANY11P(ARGBToRGB565DitherRow_Any_NEON, - ARGBToRGB565DitherRow_NEON, - const uint32_t, - 4, - 2, - 7) -#endif -#if defined(HAS_ARGBTORGB565DITHERROW_MSA) -ANY11P(ARGBToRGB565DitherRow_Any_MSA, - ARGBToRGB565DitherRow_MSA, - const uint32_t, - 4, - 2, - 7) -#endif -#ifdef HAS_ARGBSHUFFLEROW_SSSE3 -ANY11P(ARGBShuffleRow_Any_SSSE3, ARGBShuffleRow_SSSE3, const uint8_t*, 4, 4, 7) -#endif -#ifdef HAS_ARGBSHUFFLEROW_AVX2 -ANY11P(ARGBShuffleRow_Any_AVX2, ARGBShuffleRow_AVX2, const uint8_t*, 4, 4, 15) -#endif -#ifdef HAS_ARGBSHUFFLEROW_NEON -ANY11P(ARGBShuffleRow_Any_NEON, ARGBShuffleRow_NEON, const uint8_t*, 4, 4, 3) -#endif -#ifdef HAS_ARGBSHUFFLEROW_MSA -ANY11P(ARGBShuffleRow_Any_MSA, ARGBShuffleRow_MSA, const uint8_t*, 4, 4, 7) -#endif -#undef ANY11P - -// Any 1 to 1 with parameter and shorts. BPP measures in shorts. -#define ANY11C(NAMEANY, ANY_SIMD, SBPP, BPP, STYPE, DTYPE, MASK) \ - void NAMEANY(const STYPE* src_ptr, DTYPE* dst_ptr, int scale, int width) { \ - SIMD_ALIGNED(STYPE temp[32]); \ - SIMD_ALIGNED(DTYPE out[32]); \ - memset(temp, 0, 32 * SBPP); /* for msan */ \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(src_ptr, dst_ptr, scale, n); \ - } \ - memcpy(temp, src_ptr + n, r * SBPP); \ - ANY_SIMD(temp, out, scale, MASK + 1); \ - memcpy(dst_ptr + n, out, r * BPP); \ - } - -#ifdef HAS_CONVERT16TO8ROW_SSSE3 -ANY11C(Convert16To8Row_Any_SSSE3, - Convert16To8Row_SSSE3, - 2, - 1, - uint16_t, - uint8_t, - 15) -#endif -#ifdef HAS_CONVERT16TO8ROW_AVX2 -ANY11C(Convert16To8Row_Any_AVX2, - Convert16To8Row_AVX2, - 2, - 1, - uint16_t, - uint8_t, - 31) -#endif -#ifdef HAS_CONVERT8TO16ROW_SSE2 -ANY11C(Convert8To16Row_Any_SSE2, - Convert8To16Row_SSE2, - 1, - 2, - uint8_t, - uint16_t, - 15) -#endif -#ifdef HAS_CONVERT8TO16ROW_AVX2 -ANY11C(Convert8To16Row_Any_AVX2, - Convert8To16Row_AVX2, - 1, - 2, - uint8_t, - uint16_t, - 31) -#endif -#undef ANY11C - -// Any 1 to 1 with parameter and shorts to byte. BPP measures in shorts. -#define ANY11P16(NAMEANY, ANY_SIMD, ST, T, SBPP, BPP, MASK) \ - void NAMEANY(const ST* src_ptr, T* dst_ptr, float param, int width) { \ - SIMD_ALIGNED(ST temp[32]); \ - SIMD_ALIGNED(T out[32]); \ - memset(temp, 0, SBPP * 32); /* for msan */ \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(src_ptr, dst_ptr, param, n); \ - } \ - memcpy(temp, src_ptr + n, r * SBPP); \ - ANY_SIMD(temp, out, param, MASK + 1); \ - memcpy(dst_ptr + n, out, r * BPP); \ - } - -#ifdef HAS_HALFFLOATROW_SSE2 -ANY11P16(HalfFloatRow_Any_SSE2, HalfFloatRow_SSE2, uint16_t, uint16_t, 2, 2, 7) -#endif -#ifdef HAS_HALFFLOATROW_AVX2 -ANY11P16(HalfFloatRow_Any_AVX2, HalfFloatRow_AVX2, uint16_t, uint16_t, 2, 2, 15) -#endif -#ifdef HAS_HALFFLOATROW_F16C -ANY11P16(HalfFloatRow_Any_F16C, HalfFloatRow_F16C, uint16_t, uint16_t, 2, 2, 15) -ANY11P16(HalfFloat1Row_Any_F16C, - HalfFloat1Row_F16C, - uint16_t, - uint16_t, - 2, - 2, - 15) -#endif -#ifdef HAS_HALFFLOATROW_NEON -ANY11P16(HalfFloatRow_Any_NEON, HalfFloatRow_NEON, uint16_t, uint16_t, 2, 2, 7) -ANY11P16(HalfFloat1Row_Any_NEON, - HalfFloat1Row_NEON, - uint16_t, - uint16_t, - 2, - 2, - 7) -#endif -#ifdef HAS_HALFFLOATROW_MSA -ANY11P16(HalfFloatRow_Any_MSA, HalfFloatRow_MSA, uint16_t, uint16_t, 2, 2, 31) -#endif -#ifdef HAS_BYTETOFLOATROW_NEON -ANY11P16(ByteToFloatRow_Any_NEON, ByteToFloatRow_NEON, uint8_t, float, 1, 3, 7) -#endif -#undef ANY11P16 - -// Any 1 to 1 with yuvconstants -#define ANY11C(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, BPP, MASK) \ - void NAMEANY(const uint8_t* src_ptr, uint8_t* dst_ptr, \ - const struct YuvConstants* yuvconstants, int width) { \ - SIMD_ALIGNED(uint8_t temp[128 * 2]); \ - memset(temp, 0, 128); /* for YUY2 and msan */ \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(src_ptr, dst_ptr, yuvconstants, n); \ - } \ - memcpy(temp, src_ptr + (n >> UVSHIFT) * SBPP, SS(r, UVSHIFT) * SBPP); \ - ANY_SIMD(temp, temp + 128, yuvconstants, MASK + 1); \ - memcpy(dst_ptr + n * BPP, temp + 128, r * BPP); \ - } -#if defined(HAS_YUY2TOARGBROW_SSSE3) -ANY11C(YUY2ToARGBRow_Any_SSSE3, YUY2ToARGBRow_SSSE3, 1, 4, 4, 15) -ANY11C(UYVYToARGBRow_Any_SSSE3, UYVYToARGBRow_SSSE3, 1, 4, 4, 15) -#endif -#if defined(HAS_YUY2TOARGBROW_AVX2) -ANY11C(YUY2ToARGBRow_Any_AVX2, YUY2ToARGBRow_AVX2, 1, 4, 4, 31) -ANY11C(UYVYToARGBRow_Any_AVX2, UYVYToARGBRow_AVX2, 1, 4, 4, 31) -#endif -#if defined(HAS_YUY2TOARGBROW_NEON) -ANY11C(YUY2ToARGBRow_Any_NEON, YUY2ToARGBRow_NEON, 1, 4, 4, 7) -ANY11C(UYVYToARGBRow_Any_NEON, UYVYToARGBRow_NEON, 1, 4, 4, 7) -#endif -#if defined(HAS_YUY2TOARGBROW_MSA) -ANY11C(YUY2ToARGBRow_Any_MSA, YUY2ToARGBRow_MSA, 1, 4, 4, 7) -ANY11C(UYVYToARGBRow_Any_MSA, UYVYToARGBRow_MSA, 1, 4, 4, 7) -#endif -#undef ANY11C - -// Any 1 to 1 interpolate. Takes 2 rows of source via stride. -#define ANY11T(NAMEANY, ANY_SIMD, SBPP, BPP, MASK) \ - void NAMEANY(uint8_t* dst_ptr, const uint8_t* src_ptr, \ - ptrdiff_t src_stride_ptr, int width, int source_y_fraction) { \ - SIMD_ALIGNED(uint8_t temp[64 * 3]); \ - memset(temp, 0, 64 * 2); /* for msan */ \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(dst_ptr, src_ptr, src_stride_ptr, n, source_y_fraction); \ - } \ - memcpy(temp, src_ptr + n * SBPP, r * SBPP); \ - memcpy(temp + 64, src_ptr + src_stride_ptr + n * SBPP, r * SBPP); \ - ANY_SIMD(temp + 128, temp, 64, MASK + 1, source_y_fraction); \ - memcpy(dst_ptr + n * BPP, temp + 128, r * BPP); \ - } - -#ifdef HAS_INTERPOLATEROW_AVX2 -ANY11T(InterpolateRow_Any_AVX2, InterpolateRow_AVX2, 1, 1, 31) -#endif -#ifdef HAS_INTERPOLATEROW_SSSE3 -ANY11T(InterpolateRow_Any_SSSE3, InterpolateRow_SSSE3, 1, 1, 15) -#endif -#ifdef HAS_INTERPOLATEROW_NEON -ANY11T(InterpolateRow_Any_NEON, InterpolateRow_NEON, 1, 1, 15) -#endif -#ifdef HAS_INTERPOLATEROW_MSA -ANY11T(InterpolateRow_Any_MSA, InterpolateRow_MSA, 1, 1, 31) -#endif -#undef ANY11T - -// Any 1 to 1 mirror. -#define ANY11M(NAMEANY, ANY_SIMD, BPP, MASK) \ - void NAMEANY(const uint8_t* src_ptr, uint8_t* dst_ptr, int width) { \ - SIMD_ALIGNED(uint8_t temp[64 * 2]); \ - memset(temp, 0, 64); /* for msan */ \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(src_ptr + r * BPP, dst_ptr, n); \ - } \ - memcpy(temp, src_ptr, r* BPP); \ - ANY_SIMD(temp, temp + 64, MASK + 1); \ - memcpy(dst_ptr + n * BPP, temp + 64 + (MASK + 1 - r) * BPP, r * BPP); \ - } - -#ifdef HAS_MIRRORROW_AVX2 -ANY11M(MirrorRow_Any_AVX2, MirrorRow_AVX2, 1, 31) -#endif -#ifdef HAS_MIRRORROW_SSSE3 -ANY11M(MirrorRow_Any_SSSE3, MirrorRow_SSSE3, 1, 15) -#endif -#ifdef HAS_MIRRORROW_NEON -ANY11M(MirrorRow_Any_NEON, MirrorRow_NEON, 1, 15) -#endif -#ifdef HAS_MIRRORROW_MSA -ANY11M(MirrorRow_Any_MSA, MirrorRow_MSA, 1, 63) -#endif -#ifdef HAS_ARGBMIRRORROW_AVX2 -ANY11M(ARGBMirrorRow_Any_AVX2, ARGBMirrorRow_AVX2, 4, 7) -#endif -#ifdef HAS_ARGBMIRRORROW_SSE2 -ANY11M(ARGBMirrorRow_Any_SSE2, ARGBMirrorRow_SSE2, 4, 3) -#endif -#ifdef HAS_ARGBMIRRORROW_NEON -ANY11M(ARGBMirrorRow_Any_NEON, ARGBMirrorRow_NEON, 4, 3) -#endif -#ifdef HAS_ARGBMIRRORROW_MSA -ANY11M(ARGBMirrorRow_Any_MSA, ARGBMirrorRow_MSA, 4, 15) -#endif -#undef ANY11M - -// Any 1 plane. (memset) -#define ANY1(NAMEANY, ANY_SIMD, T, BPP, MASK) \ - void NAMEANY(uint8_t* dst_ptr, T v32, int width) { \ - SIMD_ALIGNED(uint8_t temp[64]); \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(dst_ptr, v32, n); \ - } \ - ANY_SIMD(temp, v32, MASK + 1); \ - memcpy(dst_ptr + n * BPP, temp, r * BPP); \ - } - -#ifdef HAS_SETROW_X86 -ANY1(SetRow_Any_X86, SetRow_X86, uint8_t, 1, 3) -#endif -#ifdef HAS_SETROW_NEON -ANY1(SetRow_Any_NEON, SetRow_NEON, uint8_t, 1, 15) -#endif -#ifdef HAS_ARGBSETROW_NEON -ANY1(ARGBSetRow_Any_NEON, ARGBSetRow_NEON, uint32_t, 4, 3) -#endif -#ifdef HAS_ARGBSETROW_MSA -ANY1(ARGBSetRow_Any_MSA, ARGBSetRow_MSA, uint32_t, 4, 3) -#endif -#undef ANY1 - -// Any 1 to 2. Outputs UV planes. -#define ANY12(NAMEANY, ANY_SIMD, UVSHIFT, BPP, DUVSHIFT, MASK) \ - void NAMEANY(const uint8_t* src_ptr, uint8_t* dst_u, uint8_t* dst_v, \ - int width) { \ - SIMD_ALIGNED(uint8_t temp[128 * 3]); \ - memset(temp, 0, 128); /* for msan */ \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(src_ptr, dst_u, dst_v, n); \ - } \ - memcpy(temp, src_ptr + (n >> UVSHIFT) * BPP, SS(r, UVSHIFT) * BPP); \ - ANY_SIMD(temp, temp + 128, temp + 256, MASK + 1); \ - memcpy(dst_u + (n >> DUVSHIFT), temp + 128, SS(r, DUVSHIFT)); \ - memcpy(dst_v + (n >> DUVSHIFT), temp + 256, SS(r, DUVSHIFT)); \ - } - -#ifdef HAS_SPLITUVROW_SSE2 -ANY12(SplitUVRow_Any_SSE2, SplitUVRow_SSE2, 0, 2, 0, 15) -#endif -#ifdef HAS_SPLITUVROW_AVX2 -ANY12(SplitUVRow_Any_AVX2, SplitUVRow_AVX2, 0, 2, 0, 31) -#endif -#ifdef HAS_SPLITUVROW_NEON -ANY12(SplitUVRow_Any_NEON, SplitUVRow_NEON, 0, 2, 0, 15) -#endif -#ifdef HAS_SPLITUVROW_MSA -ANY12(SplitUVRow_Any_MSA, SplitUVRow_MSA, 0, 2, 0, 31) -#endif -#ifdef HAS_ARGBTOUV444ROW_SSSE3 -ANY12(ARGBToUV444Row_Any_SSSE3, ARGBToUV444Row_SSSE3, 0, 4, 0, 15) -#endif -#ifdef HAS_YUY2TOUV422ROW_AVX2 -ANY12(YUY2ToUV422Row_Any_AVX2, YUY2ToUV422Row_AVX2, 1, 4, 1, 31) -ANY12(UYVYToUV422Row_Any_AVX2, UYVYToUV422Row_AVX2, 1, 4, 1, 31) -#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(YUY2ToUV422Row_Any_NEON, YUY2ToUV422Row_NEON, 1, 4, 1, 15) -ANY12(UYVYToUV422Row_Any_NEON, UYVYToUV422Row_NEON, 1, 4, 1, 15) -#endif -#ifdef HAS_YUY2TOUV422ROW_MSA -ANY12(ARGBToUV444Row_Any_MSA, ARGBToUV444Row_MSA, 0, 4, 0, 15) -ANY12(YUY2ToUV422Row_Any_MSA, YUY2ToUV422Row_MSA, 1, 4, 1, 31) -ANY12(UYVYToUV422Row_Any_MSA, UYVYToUV422Row_MSA, 1, 4, 1, 31) -#endif -#undef ANY12 - -// Any 1 to 3. Outputs RGB planes. -#define ANY13(NAMEANY, ANY_SIMD, BPP, MASK) \ - void NAMEANY(const uint8_t* src_ptr, uint8_t* dst_r, uint8_t* dst_g, \ - uint8_t* dst_b, int width) { \ - SIMD_ALIGNED(uint8_t temp[16 * 6]); \ - memset(temp, 0, 16 * 3); /* for msan */ \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(src_ptr, dst_r, dst_g, dst_b, n); \ - } \ - memcpy(temp, src_ptr + n * BPP, r * BPP); \ - ANY_SIMD(temp, temp + 16 * 3, temp + 16 * 4, temp + 16 * 5, MASK + 1); \ - memcpy(dst_r + n, temp + 16 * 3, r); \ - memcpy(dst_g + n, temp + 16 * 4, r); \ - memcpy(dst_b + n, temp + 16 * 5, r); \ - } - -#ifdef HAS_SPLITRGBROW_SSSE3 -ANY13(SplitRGBRow_Any_SSSE3, SplitRGBRow_SSSE3, 3, 15) -#endif -#ifdef HAS_SPLITRGBROW_NEON -ANY13(SplitRGBRow_Any_NEON, SplitRGBRow_NEON, 3, 15) -#endif - -// Any 1 to 2 with source stride (2 rows of source). Outputs UV planes. -// 128 byte row allows for 32 avx ARGB pixels. -#define ANY12S(NAMEANY, ANY_SIMD, UVSHIFT, BPP, MASK) \ - void NAMEANY(const uint8_t* src_ptr, int src_stride_ptr, uint8_t* dst_u, \ - uint8_t* dst_v, int width) { \ - SIMD_ALIGNED(uint8_t temp[128 * 4]); \ - memset(temp, 0, 128 * 2); /* for msan */ \ - int r = width & MASK; \ - int n = width & ~MASK; \ - if (n > 0) { \ - ANY_SIMD(src_ptr, src_stride_ptr, dst_u, dst_v, n); \ - } \ - memcpy(temp, src_ptr + (n >> UVSHIFT) * BPP, SS(r, UVSHIFT) * BPP); \ - memcpy(temp + 128, src_ptr + src_stride_ptr + (n >> UVSHIFT) * BPP, \ - SS(r, UVSHIFT) * BPP); \ - if ((width & 1) && UVSHIFT == 0) { /* repeat last pixel for subsample */ \ - memcpy(temp + SS(r, UVSHIFT) * BPP, temp + SS(r, UVSHIFT) * BPP - BPP, \ - BPP); \ - memcpy(temp + 128 + SS(r, UVSHIFT) * BPP, \ - temp + 128 + SS(r, UVSHIFT) * BPP - BPP, BPP); \ - } \ - ANY_SIMD(temp, 128, temp + 256, temp + 384, MASK + 1); \ - memcpy(dst_u + (n >> 1), temp + 256, SS(r, 1)); \ - memcpy(dst_v + (n >> 1), temp + 384, SS(r, 1)); \ - } - -#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) -ANY12S(BGRAToUVRow_Any_SSSE3, BGRAToUVRow_SSSE3, 0, 4, 15) -ANY12S(ABGRToUVRow_Any_SSSE3, ABGRToUVRow_SSSE3, 0, 4, 15) -ANY12S(RGBAToUVRow_Any_SSSE3, RGBAToUVRow_SSSE3, 0, 4, 15) -#endif -#ifdef HAS_YUY2TOUVROW_AVX2 -ANY12S(YUY2ToUVRow_Any_AVX2, YUY2ToUVRow_AVX2, 1, 4, 31) -ANY12S(UYVYToUVRow_Any_AVX2, UYVYToUVRow_AVX2, 1, 4, 31) -#endif -#ifdef HAS_YUY2TOUVROW_SSE2 -ANY12S(YUY2ToUVRow_Any_SSE2, YUY2ToUVRow_SSE2, 1, 4, 15) -ANY12S(UYVYToUVRow_Any_SSE2, UYVYToUVRow_SSE2, 1, 4, 15) -#endif -#ifdef HAS_ARGBTOUVROW_NEON -ANY12S(ARGBToUVRow_Any_NEON, ARGBToUVRow_NEON, 0, 4, 15) -#endif -#ifdef HAS_ARGBTOUVROW_MSA -ANY12S(ARGBToUVRow_Any_MSA, ARGBToUVRow_MSA, 0, 4, 31) -#endif -#ifdef HAS_ARGBTOUVJROW_NEON -ANY12S(ARGBToUVJRow_Any_NEON, ARGBToUVJRow_NEON, 0, 4, 15) -#endif -#ifdef HAS_ARGBTOUVJROW_MSA -ANY12S(ARGBToUVJRow_Any_MSA, ARGBToUVJRow_MSA, 0, 4, 31) -#endif -#ifdef HAS_BGRATOUVROW_NEON -ANY12S(BGRAToUVRow_Any_NEON, BGRAToUVRow_NEON, 0, 4, 15) -#endif -#ifdef HAS_BGRATOUVROW_MSA -ANY12S(BGRAToUVRow_Any_MSA, BGRAToUVRow_MSA, 0, 4, 31) -#endif -#ifdef HAS_ABGRTOUVROW_NEON -ANY12S(ABGRToUVRow_Any_NEON, ABGRToUVRow_NEON, 0, 4, 15) -#endif -#ifdef HAS_ABGRTOUVROW_MSA -ANY12S(ABGRToUVRow_Any_MSA, ABGRToUVRow_MSA, 0, 4, 31) -#endif -#ifdef HAS_RGBATOUVROW_NEON -ANY12S(RGBAToUVRow_Any_NEON, RGBAToUVRow_NEON, 0, 4, 15) -#endif -#ifdef HAS_RGBATOUVROW_MSA -ANY12S(RGBAToUVRow_Any_MSA, RGBAToUVRow_MSA, 0, 4, 31) -#endif -#ifdef HAS_RGB24TOUVROW_NEON -ANY12S(RGB24ToUVRow_Any_NEON, RGB24ToUVRow_NEON, 0, 3, 15) -#endif -#ifdef HAS_RGB24TOUVROW_MSA -ANY12S(RGB24ToUVRow_Any_MSA, RGB24ToUVRow_MSA, 0, 3, 15) -#endif -#ifdef HAS_RAWTOUVROW_NEON -ANY12S(RAWToUVRow_Any_NEON, RAWToUVRow_NEON, 0, 3, 15) -#endif -#ifdef HAS_RAWTOUVROW_MSA -ANY12S(RAWToUVRow_Any_MSA, RAWToUVRow_MSA, 0, 3, 15) -#endif -#ifdef HAS_RGB565TOUVROW_NEON -ANY12S(RGB565ToUVRow_Any_NEON, RGB565ToUVRow_NEON, 0, 2, 15) -#endif -#ifdef HAS_RGB565TOUVROW_MSA -ANY12S(RGB565ToUVRow_Any_MSA, RGB565ToUVRow_MSA, 0, 2, 15) -#endif -#ifdef HAS_ARGB1555TOUVROW_NEON -ANY12S(ARGB1555ToUVRow_Any_NEON, ARGB1555ToUVRow_NEON, 0, 2, 15) -#endif -#ifdef HAS_ARGB1555TOUVROW_MSA -ANY12S(ARGB1555ToUVRow_Any_MSA, ARGB1555ToUVRow_MSA, 0, 2, 15) -#endif -#ifdef HAS_ARGB4444TOUVROW_NEON -ANY12S(ARGB4444ToUVRow_Any_NEON, ARGB4444ToUVRow_NEON, 0, 2, 15) -#endif -#ifdef HAS_YUY2TOUVROW_NEON -ANY12S(YUY2ToUVRow_Any_NEON, YUY2ToUVRow_NEON, 1, 4, 15) -#endif -#ifdef HAS_UYVYTOUVROW_NEON -ANY12S(UYVYToUVRow_Any_NEON, UYVYToUVRow_NEON, 1, 4, 15) -#endif -#ifdef HAS_YUY2TOUVROW_MSA -ANY12S(YUY2ToUVRow_Any_MSA, YUY2ToUVRow_MSA, 1, 4, 31) -#endif -#ifdef HAS_UYVYTOUVROW_MSA -ANY12S(UYVYToUVRow_Any_MSA, UYVYToUVRow_MSA, 1, 4, 31) -#endif -#undef ANY12S - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_common.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_common.cc deleted file mode 100644 index 2bbc5adb..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_common.cc +++ /dev/null @@ -1,3237 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/row.h" - -#include -#include // For memcpy and memset. - -#include "libyuv/basic_types.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// llvm x86 is poor at ternary operator, so use branchless min/max. - -#define USE_BRANCHLESS 1 -#if USE_BRANCHLESS -static __inline int32_t clamp0(int32_t v) { - return ((-(v) >> 31) & (v)); -} - -static __inline int32_t clamp255(int32_t v) { - return (((255 - (v)) >> 31) | (v)) & 255; -} - -static __inline int32_t clamp1023(int32_t v) { - return (((1023 - (v)) >> 31) | (v)) & 1023; -} - -static __inline uint32_t Abs(int32_t v) { - int m = v >> 31; - return (v + m) ^ m; -} -#else // USE_BRANCHLESS -static __inline int32_t clamp0(int32_t v) { - return (v < 0) ? 0 : v; -} - -static __inline int32_t clamp255(int32_t v) { - return (v > 255) ? 255 : v; -} - -static __inline int32_t clamp1023(int32_t v) { - return (v > 1023) ? 1023 : v; -} - -static __inline uint32_t Abs(int32_t v) { - return (v < 0) ? -v : v; -} -#endif // USE_BRANCHLESS -static __inline uint32_t Clamp(int32_t val) { - int v = clamp0(val); - return (uint32_t)(clamp255(v)); -} - -static __inline uint32_t Clamp10(int32_t val) { - int v = clamp0(val); - return (uint32_t)(clamp1023(v)); -} - -// Little Endian -#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || \ - defined(_M_IX86) || defined(__arm__) || defined(_M_ARM) || \ - (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) -#define WRITEWORD(p, v) *(uint32_t*)(p) = v -#else -static inline void WRITEWORD(uint8_t* p, uint32_t v) { - p[0] = (uint8_t)(v & 255); - p[1] = (uint8_t)((v >> 8) & 255); - p[2] = (uint8_t)((v >> 16) & 255); - p[3] = (uint8_t)((v >> 24) & 255); -} -#endif - -void RGB24ToARGBRow_C(const uint8_t* src_rgb24, uint8_t* dst_argb, int width) { - int x; - for (x = 0; x < width; ++x) { - uint8_t b = src_rgb24[0]; - uint8_t g = src_rgb24[1]; - uint8_t r = src_rgb24[2]; - dst_argb[0] = b; - dst_argb[1] = g; - dst_argb[2] = r; - dst_argb[3] = 255u; - dst_argb += 4; - src_rgb24 += 3; - } -} - -void RAWToARGBRow_C(const uint8_t* src_raw, uint8_t* dst_argb, int width) { - int x; - for (x = 0; x < width; ++x) { - uint8_t r = src_raw[0]; - uint8_t g = src_raw[1]; - uint8_t b = src_raw[2]; - dst_argb[0] = b; - dst_argb[1] = g; - dst_argb[2] = r; - dst_argb[3] = 255u; - dst_argb += 4; - src_raw += 3; - } -} - -void RAWToRGB24Row_C(const uint8_t* src_raw, uint8_t* dst_rgb24, int width) { - int x; - for (x = 0; x < width; ++x) { - uint8_t r = src_raw[0]; - uint8_t g = src_raw[1]; - uint8_t b = src_raw[2]; - dst_rgb24[0] = b; - dst_rgb24[1] = g; - dst_rgb24[2] = r; - dst_rgb24 += 3; - src_raw += 3; - } -} - -void RGB565ToARGBRow_C(const uint8_t* src_rgb565, - uint8_t* dst_argb, - int width) { - int x; - for (x = 0; x < width; ++x) { - uint8_t b = src_rgb565[0] & 0x1f; - uint8_t g = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3); - uint8_t r = src_rgb565[1] >> 3; - dst_argb[0] = (b << 3) | (b >> 2); - dst_argb[1] = (g << 2) | (g >> 4); - dst_argb[2] = (r << 3) | (r >> 2); - dst_argb[3] = 255u; - dst_argb += 4; - src_rgb565 += 2; - } -} - -void ARGB1555ToARGBRow_C(const uint8_t* src_argb1555, - uint8_t* dst_argb, - int width) { - int x; - for (x = 0; x < width; ++x) { - uint8_t b = src_argb1555[0] & 0x1f; - uint8_t g = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3); - uint8_t r = (src_argb1555[1] & 0x7c) >> 2; - uint8_t a = src_argb1555[1] >> 7; - dst_argb[0] = (b << 3) | (b >> 2); - dst_argb[1] = (g << 3) | (g >> 2); - dst_argb[2] = (r << 3) | (r >> 2); - dst_argb[3] = -a; - dst_argb += 4; - src_argb1555 += 2; - } -} - -void ARGB4444ToARGBRow_C(const uint8_t* src_argb4444, - uint8_t* dst_argb, - int width) { - int x; - for (x = 0; x < width; ++x) { - uint8_t b = src_argb4444[0] & 0x0f; - uint8_t g = src_argb4444[0] >> 4; - uint8_t r = src_argb4444[1] & 0x0f; - uint8_t a = src_argb4444[1] >> 4; - dst_argb[0] = (b << 4) | b; - dst_argb[1] = (g << 4) | g; - dst_argb[2] = (r << 4) | r; - dst_argb[3] = (a << 4) | a; - dst_argb += 4; - src_argb4444 += 2; - } -} - -void AR30ToARGBRow_C(const uint8_t* src_ar30, uint8_t* dst_argb, int width) { - int x; - for (x = 0; x < width; ++x) { - uint32_t ar30 = *(const uint32_t*)src_ar30; - uint32_t b = (ar30 >> 2) & 0xff; - uint32_t g = (ar30 >> 12) & 0xff; - uint32_t r = (ar30 >> 22) & 0xff; - uint32_t a = (ar30 >> 30) * 0x55; // Replicate 2 bits to 8 bits. - *(uint32_t*)(dst_argb) = b | (g << 8) | (r << 16) | (a << 24); - dst_argb += 4; - src_ar30 += 4; - } -} - -void AR30ToABGRRow_C(const uint8_t* src_ar30, uint8_t* dst_abgr, int width) { - int x; - for (x = 0; x < width; ++x) { - uint32_t ar30 = *(const uint32_t*)src_ar30; - uint32_t b = (ar30 >> 2) & 0xff; - uint32_t g = (ar30 >> 12) & 0xff; - uint32_t r = (ar30 >> 22) & 0xff; - uint32_t a = (ar30 >> 30) * 0x55; // Replicate 2 bits to 8 bits. - *(uint32_t*)(dst_abgr) = r | (g << 8) | (b << 16) | (a << 24); - dst_abgr += 4; - src_ar30 += 4; - } -} - -void AR30ToAB30Row_C(const uint8_t* src_ar30, uint8_t* dst_ab30, int width) { - int x; - for (x = 0; x < width; ++x) { - uint32_t ar30 = *(const uint32_t*)src_ar30; - uint32_t b = ar30 & 0x3ff; - uint32_t ga = ar30 & 0xc00ffc00; - uint32_t r = (ar30 >> 20) & 0x3ff; - *(uint32_t*)(dst_ab30) = r | ga | (b << 20); - dst_ab30 += 4; - src_ar30 += 4; - } -} - -void ARGBToRGB24Row_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { - int x; - for (x = 0; x < width; ++x) { - uint8_t b = src_argb[0]; - uint8_t g = src_argb[1]; - uint8_t r = src_argb[2]; - dst_rgb[0] = b; - dst_rgb[1] = g; - dst_rgb[2] = r; - dst_rgb += 3; - src_argb += 4; - } -} - -void ARGBToRAWRow_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { - int x; - for (x = 0; x < width; ++x) { - uint8_t b = src_argb[0]; - uint8_t g = src_argb[1]; - uint8_t r = src_argb[2]; - dst_rgb[0] = r; - dst_rgb[1] = g; - dst_rgb[2] = b; - dst_rgb += 3; - src_argb += 4; - } -} - -void ARGBToRGB565Row_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - uint8_t b0 = src_argb[0] >> 3; - uint8_t g0 = src_argb[1] >> 2; - uint8_t r0 = src_argb[2] >> 3; - uint8_t b1 = src_argb[4] >> 3; - uint8_t g1 = src_argb[5] >> 2; - uint8_t r1 = src_argb[6] >> 3; - WRITEWORD(dst_rgb, b0 | (g0 << 5) | (r0 << 11) | (b1 << 16) | (g1 << 21) | - (r1 << 27)); - dst_rgb += 4; - src_argb += 8; - } - if (width & 1) { - uint8_t b0 = src_argb[0] >> 3; - uint8_t g0 = src_argb[1] >> 2; - uint8_t r0 = src_argb[2] >> 3; - *(uint16_t*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 11); - } -} - -// dither4 is a row of 4 values from 4x4 dither matrix. -// The 4x4 matrix contains values to increase RGB. When converting to -// fewer bits (565) this provides an ordered dither. -// The order in the 4x4 matrix in first byte is upper left. -// The 4 values are passed as an int, then referenced as an array, so -// endian will not affect order of the original matrix. But the dither4 -// will containing the first pixel in the lower byte for little endian -// or the upper byte for big endian. -void ARGBToRGB565DitherRow_C(const uint8_t* src_argb, - uint8_t* dst_rgb, - const uint32_t dither4, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - int dither0 = ((const unsigned char*)(&dither4))[x & 3]; - int dither1 = ((const unsigned char*)(&dither4))[(x + 1) & 3]; - uint8_t b0 = clamp255(src_argb[0] + dither0) >> 3; - uint8_t g0 = clamp255(src_argb[1] + dither0) >> 2; - uint8_t r0 = clamp255(src_argb[2] + dither0) >> 3; - uint8_t b1 = clamp255(src_argb[4] + dither1) >> 3; - uint8_t g1 = clamp255(src_argb[5] + dither1) >> 2; - uint8_t r1 = clamp255(src_argb[6] + dither1) >> 3; - WRITEWORD(dst_rgb, b0 | (g0 << 5) | (r0 << 11) | (b1 << 16) | (g1 << 21) | - (r1 << 27)); - dst_rgb += 4; - src_argb += 8; - } - if (width & 1) { - int dither0 = ((const unsigned char*)(&dither4))[(width - 1) & 3]; - uint8_t b0 = clamp255(src_argb[0] + dither0) >> 3; - uint8_t g0 = clamp255(src_argb[1] + dither0) >> 2; - uint8_t r0 = clamp255(src_argb[2] + dither0) >> 3; - *(uint16_t*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 11); - } -} - -void ARGBToARGB1555Row_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - uint8_t b0 = src_argb[0] >> 3; - uint8_t g0 = src_argb[1] >> 3; - uint8_t r0 = src_argb[2] >> 3; - uint8_t a0 = src_argb[3] >> 7; - uint8_t b1 = src_argb[4] >> 3; - uint8_t g1 = src_argb[5] >> 3; - uint8_t r1 = src_argb[6] >> 3; - uint8_t a1 = src_argb[7] >> 7; - *(uint32_t*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 10) | (a0 << 15) | - (b1 << 16) | (g1 << 21) | (r1 << 26) | (a1 << 31); - dst_rgb += 4; - src_argb += 8; - } - if (width & 1) { - uint8_t b0 = src_argb[0] >> 3; - uint8_t g0 = src_argb[1] >> 3; - uint8_t r0 = src_argb[2] >> 3; - uint8_t a0 = src_argb[3] >> 7; - *(uint16_t*)(dst_rgb) = b0 | (g0 << 5) | (r0 << 10) | (a0 << 15); - } -} - -void ARGBToARGB4444Row_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - uint8_t b0 = src_argb[0] >> 4; - uint8_t g0 = src_argb[1] >> 4; - uint8_t r0 = src_argb[2] >> 4; - uint8_t a0 = src_argb[3] >> 4; - uint8_t b1 = src_argb[4] >> 4; - uint8_t g1 = src_argb[5] >> 4; - uint8_t r1 = src_argb[6] >> 4; - uint8_t a1 = src_argb[7] >> 4; - *(uint32_t*)(dst_rgb) = b0 | (g0 << 4) | (r0 << 8) | (a0 << 12) | - (b1 << 16) | (g1 << 20) | (r1 << 24) | (a1 << 28); - dst_rgb += 4; - src_argb += 8; - } - if (width & 1) { - uint8_t b0 = src_argb[0] >> 4; - uint8_t g0 = src_argb[1] >> 4; - uint8_t r0 = src_argb[2] >> 4; - uint8_t a0 = src_argb[3] >> 4; - *(uint16_t*)(dst_rgb) = b0 | (g0 << 4) | (r0 << 8) | (a0 << 12); - } -} - -void ABGRToAR30Row_C(const uint8_t* src_abgr, uint8_t* dst_ar30, int width) { - int x; - for (x = 0; x < width; ++x) { - uint32_t b0 = (src_abgr[0] >> 6) | ((uint32_t)(src_abgr[0]) << 2); - uint32_t g0 = (src_abgr[1] >> 6) | ((uint32_t)(src_abgr[1]) << 2); - uint32_t r0 = (src_abgr[2] >> 6) | ((uint32_t)(src_abgr[2]) << 2); - uint32_t a0 = (src_abgr[3] >> 6); - *(uint32_t*)(dst_ar30) = r0 | (g0 << 10) | (b0 << 20) | (a0 << 30); - dst_ar30 += 4; - src_abgr += 4; - } -} - -void ARGBToAR30Row_C(const uint8_t* src_argb, uint8_t* dst_ar30, int width) { - int x; - for (x = 0; x < width; ++x) { - uint32_t b0 = (src_argb[0] >> 6) | ((uint32_t)(src_argb[0]) << 2); - uint32_t g0 = (src_argb[1] >> 6) | ((uint32_t)(src_argb[1]) << 2); - uint32_t r0 = (src_argb[2] >> 6) | ((uint32_t)(src_argb[2]) << 2); - uint32_t a0 = (src_argb[3] >> 6); - *(uint32_t*)(dst_ar30) = b0 | (g0 << 10) | (r0 << 20) | (a0 << 30); - dst_ar30 += 4; - src_argb += 4; - } -} - -static __inline int RGBToY(uint8_t r, uint8_t g, uint8_t b) { - return (66 * r + 129 * g + 25 * b + 0x1080) >> 8; -} - -static __inline int RGBToU(uint8_t r, uint8_t g, uint8_t b) { - return (112 * b - 74 * g - 38 * r + 0x8080) >> 8; -} -static __inline int RGBToV(uint8_t r, uint8_t g, uint8_t b) { - return (112 * r - 94 * g - 18 * b + 0x8080) >> 8; -} - -// ARGBToY_C and ARGBToUV_C -#define MAKEROWY(NAME, R, G, B, BPP) \ - void NAME##ToYRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width) { \ - int x; \ - for (x = 0; x < width; ++x) { \ - dst_y[0] = RGBToY(src_argb0[R], src_argb0[G], src_argb0[B]); \ - src_argb0 += BPP; \ - dst_y += 1; \ - } \ - } \ - void NAME##ToUVRow_C(const uint8_t* src_rgb0, int src_stride_rgb, \ - uint8_t* dst_u, uint8_t* dst_v, int width) { \ - const uint8_t* src_rgb1 = src_rgb0 + src_stride_rgb; \ - int x; \ - for (x = 0; x < width - 1; x += 2) { \ - uint8_t ab = (src_rgb0[B] + src_rgb0[B + BPP] + src_rgb1[B] + \ - src_rgb1[B + BPP]) >> \ - 2; \ - uint8_t ag = (src_rgb0[G] + src_rgb0[G + BPP] + src_rgb1[G] + \ - src_rgb1[G + BPP]) >> \ - 2; \ - uint8_t ar = (src_rgb0[R] + src_rgb0[R + BPP] + src_rgb1[R] + \ - src_rgb1[R + BPP]) >> \ - 2; \ - dst_u[0] = RGBToU(ar, ag, ab); \ - dst_v[0] = RGBToV(ar, ag, ab); \ - src_rgb0 += BPP * 2; \ - src_rgb1 += BPP * 2; \ - dst_u += 1; \ - dst_v += 1; \ - } \ - if (width & 1) { \ - uint8_t ab = (src_rgb0[B] + src_rgb1[B]) >> 1; \ - uint8_t ag = (src_rgb0[G] + src_rgb1[G]) >> 1; \ - uint8_t ar = (src_rgb0[R] + src_rgb1[R]) >> 1; \ - dst_u[0] = RGBToU(ar, ag, ab); \ - dst_v[0] = RGBToV(ar, ag, ab); \ - } \ - } - -MAKEROWY(ARGB, 2, 1, 0, 4) -MAKEROWY(BGRA, 1, 2, 3, 4) -MAKEROWY(ABGR, 0, 1, 2, 4) -MAKEROWY(RGBA, 3, 2, 1, 4) -MAKEROWY(RGB24, 2, 1, 0, 3) -MAKEROWY(RAW, 0, 1, 2, 3) -#undef MAKEROWY - -// JPeg uses a variation on BT.601-1 full range -// y = 0.29900 * r + 0.58700 * g + 0.11400 * b -// u = -0.16874 * r - 0.33126 * g + 0.50000 * b + center -// v = 0.50000 * r - 0.41869 * g - 0.08131 * b + center -// BT.601 Mpeg range uses: -// b 0.1016 * 255 = 25.908 = 25 -// g 0.5078 * 255 = 129.489 = 129 -// r 0.2578 * 255 = 65.739 = 66 -// JPeg 8 bit Y (not used): -// b 0.11400 * 256 = 29.184 = 29 -// g 0.58700 * 256 = 150.272 = 150 -// r 0.29900 * 256 = 76.544 = 77 -// JPeg 7 bit Y: -// b 0.11400 * 128 = 14.592 = 15 -// g 0.58700 * 128 = 75.136 = 75 -// r 0.29900 * 128 = 38.272 = 38 -// JPeg 8 bit U: -// b 0.50000 * 255 = 127.5 = 127 -// g -0.33126 * 255 = -84.4713 = -84 -// r -0.16874 * 255 = -43.0287 = -43 -// JPeg 8 bit V: -// b -0.08131 * 255 = -20.73405 = -20 -// g -0.41869 * 255 = -106.76595 = -107 -// r 0.50000 * 255 = 127.5 = 127 - -static __inline int RGBToYJ(uint8_t r, uint8_t g, uint8_t b) { - return (38 * r + 75 * g + 15 * b + 64) >> 7; -} - -static __inline int RGBToUJ(uint8_t r, uint8_t g, uint8_t b) { - return (127 * b - 84 * g - 43 * r + 0x8080) >> 8; -} -static __inline int RGBToVJ(uint8_t r, uint8_t g, uint8_t b) { - return (127 * r - 107 * g - 20 * b + 0x8080) >> 8; -} - -#define AVGB(a, b) (((a) + (b) + 1) >> 1) - -// ARGBToYJ_C and ARGBToUVJ_C -#define MAKEROWYJ(NAME, R, G, B, BPP) \ - void NAME##ToYJRow_C(const uint8_t* src_argb0, uint8_t* dst_y, int width) { \ - int x; \ - for (x = 0; x < width; ++x) { \ - dst_y[0] = RGBToYJ(src_argb0[R], src_argb0[G], src_argb0[B]); \ - src_argb0 += BPP; \ - dst_y += 1; \ - } \ - } \ - void NAME##ToUVJRow_C(const uint8_t* src_rgb0, int src_stride_rgb, \ - uint8_t* dst_u, uint8_t* dst_v, int width) { \ - const uint8_t* src_rgb1 = src_rgb0 + src_stride_rgb; \ - int x; \ - for (x = 0; x < width - 1; x += 2) { \ - uint8_t ab = AVGB(AVGB(src_rgb0[B], src_rgb1[B]), \ - AVGB(src_rgb0[B + BPP], src_rgb1[B + BPP])); \ - uint8_t ag = AVGB(AVGB(src_rgb0[G], src_rgb1[G]), \ - AVGB(src_rgb0[G + BPP], src_rgb1[G + BPP])); \ - uint8_t ar = AVGB(AVGB(src_rgb0[R], src_rgb1[R]), \ - AVGB(src_rgb0[R + BPP], src_rgb1[R + BPP])); \ - dst_u[0] = RGBToUJ(ar, ag, ab); \ - dst_v[0] = RGBToVJ(ar, ag, ab); \ - src_rgb0 += BPP * 2; \ - src_rgb1 += BPP * 2; \ - dst_u += 1; \ - dst_v += 1; \ - } \ - if (width & 1) { \ - uint8_t ab = AVGB(src_rgb0[B], src_rgb1[B]); \ - uint8_t ag = AVGB(src_rgb0[G], src_rgb1[G]); \ - uint8_t ar = AVGB(src_rgb0[R], src_rgb1[R]); \ - dst_u[0] = RGBToUJ(ar, ag, ab); \ - dst_v[0] = RGBToVJ(ar, ag, ab); \ - } \ - } - -MAKEROWYJ(ARGB, 2, 1, 0, 4) -#undef MAKEROWYJ - -void RGB565ToYRow_C(const uint8_t* src_rgb565, uint8_t* dst_y, int width) { - int x; - for (x = 0; x < width; ++x) { - uint8_t b = src_rgb565[0] & 0x1f; - uint8_t g = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3); - uint8_t r = src_rgb565[1] >> 3; - b = (b << 3) | (b >> 2); - g = (g << 2) | (g >> 4); - r = (r << 3) | (r >> 2); - dst_y[0] = RGBToY(r, g, b); - src_rgb565 += 2; - dst_y += 1; - } -} - -void ARGB1555ToYRow_C(const uint8_t* src_argb1555, uint8_t* dst_y, int width) { - int x; - for (x = 0; x < width; ++x) { - uint8_t b = src_argb1555[0] & 0x1f; - uint8_t g = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3); - uint8_t r = (src_argb1555[1] & 0x7c) >> 2; - b = (b << 3) | (b >> 2); - g = (g << 3) | (g >> 2); - r = (r << 3) | (r >> 2); - dst_y[0] = RGBToY(r, g, b); - src_argb1555 += 2; - dst_y += 1; - } -} - -void ARGB4444ToYRow_C(const uint8_t* src_argb4444, uint8_t* dst_y, int width) { - int x; - for (x = 0; x < width; ++x) { - uint8_t b = src_argb4444[0] & 0x0f; - uint8_t g = src_argb4444[0] >> 4; - uint8_t r = src_argb4444[1] & 0x0f; - b = (b << 4) | b; - g = (g << 4) | g; - r = (r << 4) | r; - dst_y[0] = RGBToY(r, g, b); - src_argb4444 += 2; - dst_y += 1; - } -} - -void RGB565ToUVRow_C(const uint8_t* src_rgb565, - int src_stride_rgb565, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - const uint8_t* next_rgb565 = src_rgb565 + src_stride_rgb565; - int x; - for (x = 0; x < width - 1; x += 2) { - uint8_t b0 = src_rgb565[0] & 0x1f; - uint8_t g0 = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3); - uint8_t r0 = src_rgb565[1] >> 3; - uint8_t b1 = src_rgb565[2] & 0x1f; - uint8_t g1 = (src_rgb565[2] >> 5) | ((src_rgb565[3] & 0x07) << 3); - uint8_t r1 = src_rgb565[3] >> 3; - uint8_t b2 = next_rgb565[0] & 0x1f; - uint8_t g2 = (next_rgb565[0] >> 5) | ((next_rgb565[1] & 0x07) << 3); - uint8_t r2 = next_rgb565[1] >> 3; - uint8_t b3 = next_rgb565[2] & 0x1f; - uint8_t g3 = (next_rgb565[2] >> 5) | ((next_rgb565[3] & 0x07) << 3); - uint8_t r3 = next_rgb565[3] >> 3; - uint8_t b = (b0 + b1 + b2 + b3); // 565 * 4 = 787. - uint8_t g = (g0 + g1 + g2 + g3); - uint8_t r = (r0 + r1 + r2 + r3); - b = (b << 1) | (b >> 6); // 787 -> 888. - r = (r << 1) | (r >> 6); - dst_u[0] = RGBToU(r, g, b); - dst_v[0] = RGBToV(r, g, b); - src_rgb565 += 4; - next_rgb565 += 4; - dst_u += 1; - dst_v += 1; - } - if (width & 1) { - uint8_t b0 = src_rgb565[0] & 0x1f; - uint8_t g0 = (src_rgb565[0] >> 5) | ((src_rgb565[1] & 0x07) << 3); - uint8_t r0 = src_rgb565[1] >> 3; - uint8_t b2 = next_rgb565[0] & 0x1f; - uint8_t g2 = (next_rgb565[0] >> 5) | ((next_rgb565[1] & 0x07) << 3); - uint8_t r2 = next_rgb565[1] >> 3; - uint8_t b = (b0 + b2); // 565 * 2 = 676. - uint8_t g = (g0 + g2); - uint8_t r = (r0 + r2); - b = (b << 2) | (b >> 4); // 676 -> 888 - g = (g << 1) | (g >> 6); - r = (r << 2) | (r >> 4); - dst_u[0] = RGBToU(r, g, b); - dst_v[0] = RGBToV(r, g, b); - } -} - -void ARGB1555ToUVRow_C(const uint8_t* src_argb1555, - int src_stride_argb1555, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - const uint8_t* next_argb1555 = src_argb1555 + src_stride_argb1555; - int x; - for (x = 0; x < width - 1; x += 2) { - uint8_t b0 = src_argb1555[0] & 0x1f; - uint8_t g0 = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3); - uint8_t r0 = (src_argb1555[1] & 0x7c) >> 2; - uint8_t b1 = src_argb1555[2] & 0x1f; - uint8_t g1 = (src_argb1555[2] >> 5) | ((src_argb1555[3] & 0x03) << 3); - uint8_t r1 = (src_argb1555[3] & 0x7c) >> 2; - uint8_t b2 = next_argb1555[0] & 0x1f; - uint8_t g2 = (next_argb1555[0] >> 5) | ((next_argb1555[1] & 0x03) << 3); - uint8_t r2 = (next_argb1555[1] & 0x7c) >> 2; - uint8_t b3 = next_argb1555[2] & 0x1f; - uint8_t g3 = (next_argb1555[2] >> 5) | ((next_argb1555[3] & 0x03) << 3); - uint8_t r3 = (next_argb1555[3] & 0x7c) >> 2; - uint8_t b = (b0 + b1 + b2 + b3); // 555 * 4 = 777. - uint8_t g = (g0 + g1 + g2 + g3); - uint8_t r = (r0 + r1 + r2 + r3); - b = (b << 1) | (b >> 6); // 777 -> 888. - g = (g << 1) | (g >> 6); - r = (r << 1) | (r >> 6); - dst_u[0] = RGBToU(r, g, b); - dst_v[0] = RGBToV(r, g, b); - src_argb1555 += 4; - next_argb1555 += 4; - dst_u += 1; - dst_v += 1; - } - if (width & 1) { - uint8_t b0 = src_argb1555[0] & 0x1f; - uint8_t g0 = (src_argb1555[0] >> 5) | ((src_argb1555[1] & 0x03) << 3); - uint8_t r0 = (src_argb1555[1] & 0x7c) >> 2; - uint8_t b2 = next_argb1555[0] & 0x1f; - uint8_t g2 = (next_argb1555[0] >> 5) | ((next_argb1555[1] & 0x03) << 3); - uint8_t r2 = next_argb1555[1] >> 3; - uint8_t b = (b0 + b2); // 555 * 2 = 666. - uint8_t g = (g0 + g2); - uint8_t r = (r0 + r2); - b = (b << 2) | (b >> 4); // 666 -> 888. - g = (g << 2) | (g >> 4); - r = (r << 2) | (r >> 4); - dst_u[0] = RGBToU(r, g, b); - dst_v[0] = RGBToV(r, g, b); - } -} - -void ARGB4444ToUVRow_C(const uint8_t* src_argb4444, - int src_stride_argb4444, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - const uint8_t* next_argb4444 = src_argb4444 + src_stride_argb4444; - int x; - for (x = 0; x < width - 1; x += 2) { - uint8_t b0 = src_argb4444[0] & 0x0f; - uint8_t g0 = src_argb4444[0] >> 4; - uint8_t r0 = src_argb4444[1] & 0x0f; - uint8_t b1 = src_argb4444[2] & 0x0f; - uint8_t g1 = src_argb4444[2] >> 4; - uint8_t r1 = src_argb4444[3] & 0x0f; - uint8_t b2 = next_argb4444[0] & 0x0f; - uint8_t g2 = next_argb4444[0] >> 4; - uint8_t r2 = next_argb4444[1] & 0x0f; - uint8_t b3 = next_argb4444[2] & 0x0f; - uint8_t g3 = next_argb4444[2] >> 4; - uint8_t r3 = next_argb4444[3] & 0x0f; - uint8_t b = (b0 + b1 + b2 + b3); // 444 * 4 = 666. - uint8_t g = (g0 + g1 + g2 + g3); - uint8_t r = (r0 + r1 + r2 + r3); - b = (b << 2) | (b >> 4); // 666 -> 888. - g = (g << 2) | (g >> 4); - r = (r << 2) | (r >> 4); - dst_u[0] = RGBToU(r, g, b); - dst_v[0] = RGBToV(r, g, b); - src_argb4444 += 4; - next_argb4444 += 4; - dst_u += 1; - dst_v += 1; - } - if (width & 1) { - uint8_t b0 = src_argb4444[0] & 0x0f; - uint8_t g0 = src_argb4444[0] >> 4; - uint8_t r0 = src_argb4444[1] & 0x0f; - uint8_t b2 = next_argb4444[0] & 0x0f; - uint8_t g2 = next_argb4444[0] >> 4; - uint8_t r2 = next_argb4444[1] & 0x0f; - uint8_t b = (b0 + b2); // 444 * 2 = 555. - uint8_t g = (g0 + g2); - uint8_t r = (r0 + r2); - b = (b << 3) | (b >> 2); // 555 -> 888. - g = (g << 3) | (g >> 2); - r = (r << 3) | (r >> 2); - dst_u[0] = RGBToU(r, g, b); - dst_v[0] = RGBToV(r, g, b); - } -} - -void ARGBToUV444Row_C(const uint8_t* src_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - int x; - for (x = 0; x < width; ++x) { - uint8_t ab = src_argb[0]; - uint8_t ag = src_argb[1]; - uint8_t ar = src_argb[2]; - dst_u[0] = RGBToU(ar, ag, ab); - dst_v[0] = RGBToV(ar, ag, ab); - src_argb += 4; - dst_u += 1; - dst_v += 1; - } -} - -void ARGBGrayRow_C(const uint8_t* src_argb, uint8_t* dst_argb, int width) { - int x; - for (x = 0; x < width; ++x) { - uint8_t y = RGBToYJ(src_argb[2], src_argb[1], src_argb[0]); - dst_argb[2] = dst_argb[1] = dst_argb[0] = y; - dst_argb[3] = src_argb[3]; - dst_argb += 4; - src_argb += 4; - } -} - -// Convert a row of image to Sepia tone. -void ARGBSepiaRow_C(uint8_t* dst_argb, int width) { - int x; - for (x = 0; x < width; ++x) { - int b = dst_argb[0]; - int g = dst_argb[1]; - int r = dst_argb[2]; - int sb = (b * 17 + g * 68 + r * 35) >> 7; - int sg = (b * 22 + g * 88 + r * 45) >> 7; - int sr = (b * 24 + g * 98 + r * 50) >> 7; - // b does not over flow. a is preserved from original. - dst_argb[0] = sb; - dst_argb[1] = clamp255(sg); - dst_argb[2] = clamp255(sr); - dst_argb += 4; - } -} - -// Apply color matrix to a row of image. Matrix is signed. -// TODO(fbarchard): Consider adding rounding (+32). -void ARGBColorMatrixRow_C(const uint8_t* src_argb, - uint8_t* dst_argb, - const int8_t* matrix_argb, - int width) { - int x; - for (x = 0; x < width; ++x) { - int b = src_argb[0]; - int g = src_argb[1]; - int r = src_argb[2]; - int a = src_argb[3]; - int sb = (b * matrix_argb[0] + g * matrix_argb[1] + r * matrix_argb[2] + - a * matrix_argb[3]) >> - 6; - int sg = (b * matrix_argb[4] + g * matrix_argb[5] + r * matrix_argb[6] + - a * matrix_argb[7]) >> - 6; - int sr = (b * matrix_argb[8] + g * matrix_argb[9] + r * matrix_argb[10] + - a * matrix_argb[11]) >> - 6; - int sa = (b * matrix_argb[12] + g * matrix_argb[13] + r * matrix_argb[14] + - a * matrix_argb[15]) >> - 6; - dst_argb[0] = Clamp(sb); - dst_argb[1] = Clamp(sg); - dst_argb[2] = Clamp(sr); - dst_argb[3] = Clamp(sa); - src_argb += 4; - dst_argb += 4; - } -} - -// Apply color table to a row of image. -void ARGBColorTableRow_C(uint8_t* dst_argb, - const uint8_t* table_argb, - int width) { - int x; - for (x = 0; x < width; ++x) { - int b = dst_argb[0]; - int g = dst_argb[1]; - int r = dst_argb[2]; - int a = dst_argb[3]; - dst_argb[0] = table_argb[b * 4 + 0]; - dst_argb[1] = table_argb[g * 4 + 1]; - dst_argb[2] = table_argb[r * 4 + 2]; - dst_argb[3] = table_argb[a * 4 + 3]; - dst_argb += 4; - } -} - -// Apply color table to a row of image. -void RGBColorTableRow_C(uint8_t* dst_argb, - const uint8_t* table_argb, - int width) { - int x; - for (x = 0; x < width; ++x) { - int b = dst_argb[0]; - int g = dst_argb[1]; - int r = dst_argb[2]; - dst_argb[0] = table_argb[b * 4 + 0]; - dst_argb[1] = table_argb[g * 4 + 1]; - dst_argb[2] = table_argb[r * 4 + 2]; - dst_argb += 4; - } -} - -void ARGBQuantizeRow_C(uint8_t* dst_argb, - int scale, - int interval_size, - int interval_offset, - int width) { - int x; - for (x = 0; x < width; ++x) { - int b = dst_argb[0]; - int g = dst_argb[1]; - int r = dst_argb[2]; - dst_argb[0] = (b * scale >> 16) * interval_size + interval_offset; - dst_argb[1] = (g * scale >> 16) * interval_size + interval_offset; - dst_argb[2] = (r * scale >> 16) * interval_size + interval_offset; - dst_argb += 4; - } -} - -#define REPEAT8(v) (v) | ((v) << 8) -#define SHADE(f, v) v* f >> 24 - -void ARGBShadeRow_C(const uint8_t* src_argb, - uint8_t* dst_argb, - int width, - uint32_t value) { - const uint32_t b_scale = REPEAT8(value & 0xff); - const uint32_t g_scale = REPEAT8((value >> 8) & 0xff); - const uint32_t r_scale = REPEAT8((value >> 16) & 0xff); - const uint32_t a_scale = REPEAT8(value >> 24); - - int i; - for (i = 0; i < width; ++i) { - const uint32_t b = REPEAT8(src_argb[0]); - const uint32_t g = REPEAT8(src_argb[1]); - const uint32_t r = REPEAT8(src_argb[2]); - const uint32_t a = REPEAT8(src_argb[3]); - dst_argb[0] = SHADE(b, b_scale); - dst_argb[1] = SHADE(g, g_scale); - dst_argb[2] = SHADE(r, r_scale); - dst_argb[3] = SHADE(a, a_scale); - src_argb += 4; - dst_argb += 4; - } -} -#undef REPEAT8 -#undef SHADE - -#define REPEAT8(v) (v) | ((v) << 8) -#define SHADE(f, v) v* f >> 16 - -void ARGBMultiplyRow_C(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - int i; - for (i = 0; i < width; ++i) { - const uint32_t b = REPEAT8(src_argb0[0]); - const uint32_t g = REPEAT8(src_argb0[1]); - const uint32_t r = REPEAT8(src_argb0[2]); - const uint32_t a = REPEAT8(src_argb0[3]); - const uint32_t b_scale = src_argb1[0]; - const uint32_t g_scale = src_argb1[1]; - const uint32_t r_scale = src_argb1[2]; - const uint32_t a_scale = src_argb1[3]; - dst_argb[0] = SHADE(b, b_scale); - dst_argb[1] = SHADE(g, g_scale); - dst_argb[2] = SHADE(r, r_scale); - dst_argb[3] = SHADE(a, a_scale); - src_argb0 += 4; - src_argb1 += 4; - dst_argb += 4; - } -} -#undef REPEAT8 -#undef SHADE - -#define SHADE(f, v) clamp255(v + f) - -void ARGBAddRow_C(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - int i; - for (i = 0; i < width; ++i) { - const int b = src_argb0[0]; - const int g = src_argb0[1]; - const int r = src_argb0[2]; - const int a = src_argb0[3]; - const int b_add = src_argb1[0]; - const int g_add = src_argb1[1]; - const int r_add = src_argb1[2]; - const int a_add = src_argb1[3]; - dst_argb[0] = SHADE(b, b_add); - dst_argb[1] = SHADE(g, g_add); - dst_argb[2] = SHADE(r, r_add); - dst_argb[3] = SHADE(a, a_add); - src_argb0 += 4; - src_argb1 += 4; - dst_argb += 4; - } -} -#undef SHADE - -#define SHADE(f, v) clamp0(f - v) - -void ARGBSubtractRow_C(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - int i; - for (i = 0; i < width; ++i) { - const int b = src_argb0[0]; - const int g = src_argb0[1]; - const int r = src_argb0[2]; - const int a = src_argb0[3]; - const int b_sub = src_argb1[0]; - const int g_sub = src_argb1[1]; - const int r_sub = src_argb1[2]; - const int a_sub = src_argb1[3]; - dst_argb[0] = SHADE(b, b_sub); - dst_argb[1] = SHADE(g, g_sub); - dst_argb[2] = SHADE(r, r_sub); - dst_argb[3] = SHADE(a, a_sub); - src_argb0 += 4; - src_argb1 += 4; - dst_argb += 4; - } -} -#undef SHADE - -// Sobel functions which mimics SSSE3. -void SobelXRow_C(const uint8_t* src_y0, - const uint8_t* src_y1, - const uint8_t* src_y2, - uint8_t* dst_sobelx, - int width) { - int i; - for (i = 0; i < width; ++i) { - int a = src_y0[i]; - int b = src_y1[i]; - int c = src_y2[i]; - int a_sub = src_y0[i + 2]; - int b_sub = src_y1[i + 2]; - int c_sub = src_y2[i + 2]; - int a_diff = a - a_sub; - int b_diff = b - b_sub; - int c_diff = c - c_sub; - int sobel = Abs(a_diff + b_diff * 2 + c_diff); - dst_sobelx[i] = (uint8_t)(clamp255(sobel)); - } -} - -void SobelYRow_C(const uint8_t* src_y0, - const uint8_t* src_y1, - uint8_t* dst_sobely, - int width) { - int i; - for (i = 0; i < width; ++i) { - int a = src_y0[i + 0]; - int b = src_y0[i + 1]; - int c = src_y0[i + 2]; - int a_sub = src_y1[i + 0]; - int b_sub = src_y1[i + 1]; - int c_sub = src_y1[i + 2]; - int a_diff = a - a_sub; - int b_diff = b - b_sub; - int c_diff = c - c_sub; - int sobel = Abs(a_diff + b_diff * 2 + c_diff); - dst_sobely[i] = (uint8_t)(clamp255(sobel)); - } -} - -void SobelRow_C(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width) { - int i; - for (i = 0; i < width; ++i) { - int r = src_sobelx[i]; - int b = src_sobely[i]; - int s = clamp255(r + b); - dst_argb[0] = (uint8_t)(s); - dst_argb[1] = (uint8_t)(s); - dst_argb[2] = (uint8_t)(s); - dst_argb[3] = (uint8_t)(255u); - dst_argb += 4; - } -} - -void SobelToPlaneRow_C(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_y, - int width) { - int i; - for (i = 0; i < width; ++i) { - int r = src_sobelx[i]; - int b = src_sobely[i]; - int s = clamp255(r + b); - dst_y[i] = (uint8_t)(s); - } -} - -void SobelXYRow_C(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width) { - int i; - for (i = 0; i < width; ++i) { - int r = src_sobelx[i]; - int b = src_sobely[i]; - int g = clamp255(r + b); - dst_argb[0] = (uint8_t)(b); - dst_argb[1] = (uint8_t)(g); - dst_argb[2] = (uint8_t)(r); - dst_argb[3] = (uint8_t)(255u); - dst_argb += 4; - } -} - -void J400ToARGBRow_C(const uint8_t* src_y, uint8_t* dst_argb, int width) { - // Copy a Y to RGB. - int x; - for (x = 0; x < width; ++x) { - uint8_t y = src_y[0]; - dst_argb[2] = dst_argb[1] = dst_argb[0] = y; - dst_argb[3] = 255u; - dst_argb += 4; - ++src_y; - } -} - -// TODO(fbarchard): Unify these structures to be platform independent. -// TODO(fbarchard): Generate SIMD structures from float matrix. - -// BT.601 YUV to RGB reference -// R = (Y - 16) * 1.164 - V * -1.596 -// G = (Y - 16) * 1.164 - U * 0.391 - V * 0.813 -// B = (Y - 16) * 1.164 - U * -2.018 - -// Y contribution to R,G,B. Scale and bias. -#define YG 18997 /* round(1.164 * 64 * 256 * 256 / 257) */ -#define YGB -1160 /* 1.164 * 64 * -16 + 64 / 2 */ - -// U and V contributions to R,G,B. -#define UB -128 /* max(-128, round(-2.018 * 64)) */ -#define UG 25 /* round(0.391 * 64) */ -#define VG 52 /* round(0.813 * 64) */ -#define VR -102 /* round(-1.596 * 64) */ - -// Bias values to subtract 16 from Y and 128 from U and V. -#define BB (UB * 128 + YGB) -#define BG (UG * 128 + VG * 128 + YGB) -#define BR (VR * 128 + YGB) - -#if defined(__aarch64__) // 64 bit arm -const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants) = { - {-UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR}, - {-UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR}, - {UG, VG, UG, VG, UG, VG, UG, VG}, - {UG, VG, UG, VG, UG, VG, UG, VG}, - {BB, BG, BR, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; -const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants) = { - {-VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB}, - {-VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB}, - {VG, UG, VG, UG, VG, UG, VG, UG}, - {VG, UG, VG, UG, VG, UG, VG, UG}, - {BR, BG, BB, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; -#elif defined(__arm__) // 32 bit arm -const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants) = { - {-UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0}, - {UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0}, - {BB, BG, BR, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; -const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants) = { - {-VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0}, - {VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0}, - {BR, BG, BB, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; -#else -const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants) = { - {UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, - UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0}, - {UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, - UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG}, - {0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, - 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR}, - {BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB}, - {BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG}, - {BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR}, - {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}}; -const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants) = { - {VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, - VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0}, - {VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, - VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG}, - {0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, - 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB}, - {BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR}, - {BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG}, - {BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB}, - {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}}; -#endif - -#undef BB -#undef BG -#undef BR -#undef YGB -#undef UB -#undef UG -#undef VG -#undef VR -#undef YG - -// JPEG YUV to RGB reference -// * R = Y - V * -1.40200 -// * G = Y - U * 0.34414 - V * 0.71414 -// * B = Y - U * -1.77200 - -// Y contribution to R,G,B. Scale and bias. -#define YG 16320 /* round(1.000 * 64 * 256 * 256 / 257) */ -#define YGB 32 /* 64 / 2 */ - -// U and V contributions to R,G,B. -#define UB -113 /* round(-1.77200 * 64) */ -#define UG 22 /* round(0.34414 * 64) */ -#define VG 46 /* round(0.71414 * 64) */ -#define VR -90 /* round(-1.40200 * 64) */ - -// Bias values to round, and subtract 128 from U and V. -#define BB (UB * 128 + YGB) -#define BG (UG * 128 + VG * 128 + YGB) -#define BR (VR * 128 + YGB) - -#if defined(__aarch64__) -const struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = { - {-UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR}, - {-UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR}, - {UG, VG, UG, VG, UG, VG, UG, VG}, - {UG, VG, UG, VG, UG, VG, UG, VG}, - {BB, BG, BR, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; -const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = { - {-VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB}, - {-VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB}, - {VG, UG, VG, UG, VG, UG, VG, UG}, - {VG, UG, VG, UG, VG, UG, VG, UG}, - {BR, BG, BB, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; -#elif defined(__arm__) -const struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = { - {-UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0}, - {UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0}, - {BB, BG, BR, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; -const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = { - {-VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0}, - {VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0}, - {BR, BG, BB, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; -#else -const struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = { - {UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, - UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0}, - {UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, - UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG}, - {0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, - 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR}, - {BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB}, - {BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG}, - {BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR}, - {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}}; -const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = { - {VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, - VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0}, - {VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, - VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG}, - {0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, - 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB}, - {BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR}, - {BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG}, - {BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB}, - {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}}; -#endif - -#undef BB -#undef BG -#undef BR -#undef YGB -#undef UB -#undef UG -#undef VG -#undef VR -#undef YG - -// BT.709 YUV to RGB reference -// R = (Y - 16) * 1.164 - V * -1.793 -// G = (Y - 16) * 1.164 - U * 0.213 - V * 0.533 -// B = (Y - 16) * 1.164 - U * -2.112 -// See also http://www.equasys.de/colorconversion.html - -// Y contribution to R,G,B. Scale and bias. -#define YG 18997 /* round(1.164 * 64 * 256 * 256 / 257) */ -#define YGB -1160 /* 1.164 * 64 * -16 + 64 / 2 */ - -// TODO(fbarchard): Find way to express 2.112 instead of 2.0. -// U and V contributions to R,G,B. -#define UB -128 /* max(-128, round(-2.112 * 64)) */ -#define UG 14 /* round(0.213 * 64) */ -#define VG 34 /* round(0.533 * 64) */ -#define VR -115 /* round(-1.793 * 64) */ - -// Bias values to round, and subtract 128 from U and V. -#define BB (UB * 128 + YGB) -#define BG (UG * 128 + VG * 128 + YGB) -#define BR (VR * 128 + YGB) - -#if defined(__aarch64__) -const struct YuvConstants SIMD_ALIGNED(kYuvH709Constants) = { - {-UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR}, - {-UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR}, - {UG, VG, UG, VG, UG, VG, UG, VG}, - {UG, VG, UG, VG, UG, VG, UG, VG}, - {BB, BG, BR, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; -const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = { - {-VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB}, - {-VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB}, - {VG, UG, VG, UG, VG, UG, VG, UG}, - {VG, UG, VG, UG, VG, UG, VG, UG}, - {BR, BG, BB, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; -#elif defined(__arm__) -const struct YuvConstants SIMD_ALIGNED(kYuvH709Constants) = { - {-UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0}, - {UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0}, - {BB, BG, BR, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; -const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = { - {-VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0}, - {VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0}, - {BR, BG, BB, 0, 0, 0, 0, 0}, - {0x0101 * YG, 0, 0, 0}}; -#else -const struct YuvConstants SIMD_ALIGNED(kYuvH709Constants) = { - {UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, - UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0}, - {UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, - UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG}, - {0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, - 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR}, - {BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB}, - {BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG}, - {BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR}, - {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}}; -const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = { - {VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, - VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0}, - {VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, - VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG}, - {0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, - 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB}, - {BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR}, - {BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG}, - {BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB}, - {YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG}}; -#endif - -#undef BB -#undef BG -#undef BR -#undef YGB -#undef UB -#undef UG -#undef VG -#undef VR -#undef YG - -// C reference code that mimics the YUV assembly. -// Reads 8 bit YUV and leaves result as 16 bit. - -static __inline void YuvPixel(uint8_t y, - uint8_t u, - uint8_t v, - uint8_t* b, - uint8_t* g, - uint8_t* r, - const struct YuvConstants* yuvconstants) { -#if defined(__aarch64__) - int ub = -yuvconstants->kUVToRB[0]; - int ug = yuvconstants->kUVToG[0]; - int vg = yuvconstants->kUVToG[1]; - int vr = -yuvconstants->kUVToRB[1]; - int bb = yuvconstants->kUVBiasBGR[0]; - int bg = yuvconstants->kUVBiasBGR[1]; - int br = yuvconstants->kUVBiasBGR[2]; - int yg = yuvconstants->kYToRgb[0] / 0x0101; -#elif defined(__arm__) - int ub = -yuvconstants->kUVToRB[0]; - int ug = yuvconstants->kUVToG[0]; - int vg = yuvconstants->kUVToG[4]; - int vr = -yuvconstants->kUVToRB[4]; - int bb = yuvconstants->kUVBiasBGR[0]; - int bg = yuvconstants->kUVBiasBGR[1]; - int br = yuvconstants->kUVBiasBGR[2]; - int yg = yuvconstants->kYToRgb[0] / 0x0101; -#else - int ub = yuvconstants->kUVToB[0]; - int ug = yuvconstants->kUVToG[0]; - int vg = yuvconstants->kUVToG[1]; - int vr = yuvconstants->kUVToR[1]; - int bb = yuvconstants->kUVBiasB[0]; - int bg = yuvconstants->kUVBiasG[0]; - int br = yuvconstants->kUVBiasR[0]; - int yg = yuvconstants->kYToRgb[0]; -#endif - - uint32_t y1 = (uint32_t)(y * 0x0101 * yg) >> 16; - *b = Clamp((int32_t)(-(u * ub) + y1 + bb) >> 6); - *g = Clamp((int32_t)(-(u * ug + v * vg) + y1 + bg) >> 6); - *r = Clamp((int32_t)(-(v * vr) + y1 + br) >> 6); -} - -// Reads 8 bit YUV and leaves result as 16 bit. -static __inline void YuvPixel8_16(uint8_t y, - uint8_t u, - uint8_t v, - int* b, - int* g, - int* r, - const struct YuvConstants* yuvconstants) { -#if defined(__aarch64__) - int ub = -yuvconstants->kUVToRB[0]; - int ug = yuvconstants->kUVToG[0]; - int vg = yuvconstants->kUVToG[1]; - int vr = -yuvconstants->kUVToRB[1]; - int bb = yuvconstants->kUVBiasBGR[0]; - int bg = yuvconstants->kUVBiasBGR[1]; - int br = yuvconstants->kUVBiasBGR[2]; - int yg = yuvconstants->kYToRgb[0] / 0x0101; -#elif defined(__arm__) - int ub = -yuvconstants->kUVToRB[0]; - int ug = yuvconstants->kUVToG[0]; - int vg = yuvconstants->kUVToG[4]; - int vr = -yuvconstants->kUVToRB[4]; - int bb = yuvconstants->kUVBiasBGR[0]; - int bg = yuvconstants->kUVBiasBGR[1]; - int br = yuvconstants->kUVBiasBGR[2]; - int yg = yuvconstants->kYToRgb[0] / 0x0101; -#else - int ub = yuvconstants->kUVToB[0]; - int ug = yuvconstants->kUVToG[0]; - int vg = yuvconstants->kUVToG[1]; - int vr = yuvconstants->kUVToR[1]; - int bb = yuvconstants->kUVBiasB[0]; - int bg = yuvconstants->kUVBiasG[0]; - int br = yuvconstants->kUVBiasR[0]; - int yg = yuvconstants->kYToRgb[0]; -#endif - - uint32_t y1 = (uint32_t)(y * 0x0101 * yg) >> 16; - *b = (int)(-(u * ub) + y1 + bb); - *g = (int)(-(u * ug + v * vg) + y1 + bg); - *r = (int)(-(v * vr) + y1 + br); -} - -// C reference code that mimics the YUV 16 bit assembly. -// Reads 10 bit YUV and leaves result as 16 bit. -static __inline void YuvPixel16(int16_t y, - int16_t u, - int16_t v, - int* b, - int* g, - int* r, - const struct YuvConstants* yuvconstants) { -#if defined(__aarch64__) - int ub = -yuvconstants->kUVToRB[0]; - int ug = yuvconstants->kUVToG[0]; - int vg = yuvconstants->kUVToG[1]; - int vr = -yuvconstants->kUVToRB[1]; - int bb = yuvconstants->kUVBiasBGR[0]; - int bg = yuvconstants->kUVBiasBGR[1]; - int br = yuvconstants->kUVBiasBGR[2]; - int yg = yuvconstants->kYToRgb[0] / 0x0101; -#elif defined(__arm__) - int ub = -yuvconstants->kUVToRB[0]; - int ug = yuvconstants->kUVToG[0]; - int vg = yuvconstants->kUVToG[4]; - int vr = -yuvconstants->kUVToRB[4]; - int bb = yuvconstants->kUVBiasBGR[0]; - int bg = yuvconstants->kUVBiasBGR[1]; - int br = yuvconstants->kUVBiasBGR[2]; - int yg = yuvconstants->kYToRgb[0] / 0x0101; -#else - int ub = yuvconstants->kUVToB[0]; - int ug = yuvconstants->kUVToG[0]; - int vg = yuvconstants->kUVToG[1]; - int vr = yuvconstants->kUVToR[1]; - int bb = yuvconstants->kUVBiasB[0]; - int bg = yuvconstants->kUVBiasG[0]; - int br = yuvconstants->kUVBiasR[0]; - int yg = yuvconstants->kYToRgb[0]; -#endif - - uint32_t y1 = (uint32_t)((y << 6) * yg) >> 16; - u = clamp255(u >> 2); - v = clamp255(v >> 2); - *b = (int)(-(u * ub) + y1 + bb); - *g = (int)(-(u * ug + v * vg) + y1 + bg); - *r = (int)(-(v * vr) + y1 + br); -} - -// C reference code that mimics the YUV 10 bit assembly. -// Reads 10 bit YUV and clamps down to 8 bit RGB. -static __inline void YuvPixel10(uint16_t y, - uint16_t u, - uint16_t v, - uint8_t* b, - uint8_t* g, - uint8_t* r, - const struct YuvConstants* yuvconstants) { - int b16; - int g16; - int r16; - YuvPixel16(y, u, v, &b16, &g16, &r16, yuvconstants); - *b = Clamp(b16 >> 6); - *g = Clamp(g16 >> 6); - *r = Clamp(r16 >> 6); -} - -// Y contribution to R,G,B. Scale and bias. -#define YG 18997 /* round(1.164 * 64 * 256 * 256 / 257) */ -#define YGB -1160 /* 1.164 * 64 * -16 + 64 / 2 */ - -// C reference code that mimics the YUV assembly. -static __inline void YPixel(uint8_t y, uint8_t* b, uint8_t* g, uint8_t* r) { - uint32_t y1 = (uint32_t)(y * 0x0101 * YG) >> 16; - *b = Clamp((int32_t)(y1 + YGB) >> 6); - *g = Clamp((int32_t)(y1 + YGB) >> 6); - *r = Clamp((int32_t)(y1 + YGB) >> 6); -} - -#undef YG -#undef YGB - -#if !defined(LIBYUV_DISABLE_NEON) && \ - (defined(__ARM_NEON__) || defined(__aarch64__) || defined(LIBYUV_NEON)) -// C mimic assembly. -// TODO(fbarchard): Remove subsampling from Neon. -void I444ToARGBRow_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - uint8_t u = (src_u[0] + src_u[1] + 1) >> 1; - uint8_t v = (src_v[0] + src_v[1] + 1) >> 1; - YuvPixel(src_y[0], u, v, rgb_buf + 0, rgb_buf + 1, rgb_buf + 2, - yuvconstants); - rgb_buf[3] = 255; - YuvPixel(src_y[1], u, v, rgb_buf + 4, rgb_buf + 5, rgb_buf + 6, - yuvconstants); - rgb_buf[7] = 255; - src_y += 2; - src_u += 2; - src_v += 2; - rgb_buf += 8; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel(src_y[0], src_u[0], src_v[0], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - rgb_buf[3] = 255; - } -} -#else -void I444ToARGBRow_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) { - int x; - for (x = 0; x < width; ++x) { - YuvPixel(src_y[0], src_u[0], src_v[0], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - rgb_buf[3] = 255; - src_y += 1; - src_u += 1; - src_v += 1; - rgb_buf += 4; // Advance 1 pixel. - } -} -#endif - -// Also used for 420 -void I422ToARGBRow_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - YuvPixel(src_y[0], src_u[0], src_v[0], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - rgb_buf[3] = 255; - YuvPixel(src_y[1], src_u[0], src_v[0], rgb_buf + 4, rgb_buf + 5, - rgb_buf + 6, yuvconstants); - rgb_buf[7] = 255; - src_y += 2; - src_u += 1; - src_v += 1; - rgb_buf += 8; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel(src_y[0], src_u[0], src_v[0], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - rgb_buf[3] = 255; - } -} - -// 10 bit YUV to ARGB -void I210ToARGBRow_C(const uint16_t* src_y, - const uint16_t* src_u, - const uint16_t* src_v, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - YuvPixel10(src_y[0], src_u[0], src_v[0], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - rgb_buf[3] = 255; - YuvPixel10(src_y[1], src_u[0], src_v[0], rgb_buf + 4, rgb_buf + 5, - rgb_buf + 6, yuvconstants); - rgb_buf[7] = 255; - src_y += 2; - src_u += 1; - src_v += 1; - rgb_buf += 8; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel10(src_y[0], src_u[0], src_v[0], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - rgb_buf[3] = 255; - } -} - -static void StoreAR30(uint8_t* rgb_buf, int b, int g, int r) { - uint32_t ar30; - b = b >> 4; // convert 10.6 to 10 bit. - g = g >> 4; - r = r >> 4; - b = Clamp10(b); - g = Clamp10(g); - r = Clamp10(r); - ar30 = b | ((uint32_t)g << 10) | ((uint32_t)r << 20) | 0xc0000000; - (*(uint32_t*)rgb_buf) = ar30; -} - -// 10 bit YUV to 10 bit AR30 -void I210ToAR30Row_C(const uint16_t* src_y, - const uint16_t* src_u, - const uint16_t* src_v, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) { - int x; - int b; - int g; - int r; - for (x = 0; x < width - 1; x += 2) { - YuvPixel16(src_y[0], src_u[0], src_v[0], &b, &g, &r, yuvconstants); - StoreAR30(rgb_buf, b, g, r); - YuvPixel16(src_y[1], src_u[0], src_v[0], &b, &g, &r, yuvconstants); - StoreAR30(rgb_buf + 4, b, g, r); - src_y += 2; - src_u += 1; - src_v += 1; - rgb_buf += 8; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel16(src_y[0], src_u[0], src_v[0], &b, &g, &r, yuvconstants); - StoreAR30(rgb_buf, b, g, r); - } -} - -// 8 bit YUV to 10 bit AR30 -// Uses same code as 10 bit YUV bit shifts the 8 bit values up to 10 bits. -void I422ToAR30Row_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) { - int x; - int b; - int g; - int r; - for (x = 0; x < width - 1; x += 2) { - YuvPixel8_16(src_y[0], src_u[0], src_v[0], &b, &g, &r, yuvconstants); - StoreAR30(rgb_buf, b, g, r); - YuvPixel8_16(src_y[1], src_u[0], src_v[0], &b, &g, &r, yuvconstants); - StoreAR30(rgb_buf + 4, b, g, r); - src_y += 2; - src_u += 1; - src_v += 1; - rgb_buf += 8; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel8_16(src_y[0], src_u[0], src_v[0], &b, &g, &r, yuvconstants); - StoreAR30(rgb_buf, b, g, r); - } -} - -void I422AlphaToARGBRow_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - const uint8_t* src_a, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - YuvPixel(src_y[0], src_u[0], src_v[0], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - rgb_buf[3] = src_a[0]; - YuvPixel(src_y[1], src_u[0], src_v[0], rgb_buf + 4, rgb_buf + 5, - rgb_buf + 6, yuvconstants); - rgb_buf[7] = src_a[1]; - src_y += 2; - src_u += 1; - src_v += 1; - src_a += 2; - rgb_buf += 8; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel(src_y[0], src_u[0], src_v[0], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - rgb_buf[3] = src_a[0]; - } -} - -void I422ToRGB24Row_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - YuvPixel(src_y[0], src_u[0], src_v[0], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - YuvPixel(src_y[1], src_u[0], src_v[0], rgb_buf + 3, rgb_buf + 4, - rgb_buf + 5, yuvconstants); - src_y += 2; - src_u += 1; - src_v += 1; - rgb_buf += 6; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel(src_y[0], src_u[0], src_v[0], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - } -} - -void I422ToARGB4444Row_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb4444, - const struct YuvConstants* yuvconstants, - int width) { - uint8_t b0; - uint8_t g0; - uint8_t r0; - uint8_t b1; - uint8_t g1; - uint8_t r1; - int x; - for (x = 0; x < width - 1; x += 2) { - YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0, yuvconstants); - YuvPixel(src_y[1], src_u[0], src_v[0], &b1, &g1, &r1, yuvconstants); - b0 = b0 >> 4; - g0 = g0 >> 4; - r0 = r0 >> 4; - b1 = b1 >> 4; - g1 = g1 >> 4; - r1 = r1 >> 4; - *(uint32_t*)(dst_argb4444) = b0 | (g0 << 4) | (r0 << 8) | (b1 << 16) | - (g1 << 20) | (r1 << 24) | 0xf000f000; - src_y += 2; - src_u += 1; - src_v += 1; - dst_argb4444 += 4; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0, yuvconstants); - b0 = b0 >> 4; - g0 = g0 >> 4; - r0 = r0 >> 4; - *(uint16_t*)(dst_argb4444) = b0 | (g0 << 4) | (r0 << 8) | 0xf000; - } -} - -void I422ToARGB1555Row_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb1555, - const struct YuvConstants* yuvconstants, - int width) { - uint8_t b0; - uint8_t g0; - uint8_t r0; - uint8_t b1; - uint8_t g1; - uint8_t r1; - int x; - for (x = 0; x < width - 1; x += 2) { - YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0, yuvconstants); - YuvPixel(src_y[1], src_u[0], src_v[0], &b1, &g1, &r1, yuvconstants); - b0 = b0 >> 3; - g0 = g0 >> 3; - r0 = r0 >> 3; - b1 = b1 >> 3; - g1 = g1 >> 3; - r1 = r1 >> 3; - *(uint32_t*)(dst_argb1555) = b0 | (g0 << 5) | (r0 << 10) | (b1 << 16) | - (g1 << 21) | (r1 << 26) | 0x80008000; - src_y += 2; - src_u += 1; - src_v += 1; - dst_argb1555 += 4; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0, yuvconstants); - b0 = b0 >> 3; - g0 = g0 >> 3; - r0 = r0 >> 3; - *(uint16_t*)(dst_argb1555) = b0 | (g0 << 5) | (r0 << 10) | 0x8000; - } -} - -void I422ToRGB565Row_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width) { - uint8_t b0; - uint8_t g0; - uint8_t r0; - uint8_t b1; - uint8_t g1; - uint8_t r1; - int x; - for (x = 0; x < width - 1; x += 2) { - YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0, yuvconstants); - YuvPixel(src_y[1], src_u[0], src_v[0], &b1, &g1, &r1, yuvconstants); - b0 = b0 >> 3; - g0 = g0 >> 2; - r0 = r0 >> 3; - b1 = b1 >> 3; - g1 = g1 >> 2; - r1 = r1 >> 3; - *(uint32_t*)(dst_rgb565) = - b0 | (g0 << 5) | (r0 << 11) | (b1 << 16) | (g1 << 21) | (r1 << 27); - src_y += 2; - src_u += 1; - src_v += 1; - dst_rgb565 += 4; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel(src_y[0], src_u[0], src_v[0], &b0, &g0, &r0, yuvconstants); - b0 = b0 >> 3; - g0 = g0 >> 2; - r0 = r0 >> 3; - *(uint16_t*)(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11); - } -} - -void NV12ToARGBRow_C(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - YuvPixel(src_y[0], src_uv[0], src_uv[1], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - rgb_buf[3] = 255; - YuvPixel(src_y[1], src_uv[0], src_uv[1], rgb_buf + 4, rgb_buf + 5, - rgb_buf + 6, yuvconstants); - rgb_buf[7] = 255; - src_y += 2; - src_uv += 2; - rgb_buf += 8; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel(src_y[0], src_uv[0], src_uv[1], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - rgb_buf[3] = 255; - } -} - -void NV21ToARGBRow_C(const uint8_t* src_y, - const uint8_t* src_vu, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - YuvPixel(src_y[0], src_vu[1], src_vu[0], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - rgb_buf[3] = 255; - YuvPixel(src_y[1], src_vu[1], src_vu[0], rgb_buf + 4, rgb_buf + 5, - rgb_buf + 6, yuvconstants); - rgb_buf[7] = 255; - src_y += 2; - src_vu += 2; - rgb_buf += 8; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel(src_y[0], src_vu[1], src_vu[0], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - rgb_buf[3] = 255; - } -} - -void NV12ToRGB24Row_C(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - YuvPixel(src_y[0], src_uv[0], src_uv[1], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - YuvPixel(src_y[1], src_uv[0], src_uv[1], rgb_buf + 3, rgb_buf + 4, - rgb_buf + 5, yuvconstants); - src_y += 2; - src_uv += 2; - rgb_buf += 6; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel(src_y[0], src_uv[0], src_uv[1], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - } -} - -void NV21ToRGB24Row_C(const uint8_t* src_y, - const uint8_t* src_vu, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - YuvPixel(src_y[0], src_vu[1], src_vu[0], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - YuvPixel(src_y[1], src_vu[1], src_vu[0], rgb_buf + 3, rgb_buf + 4, - rgb_buf + 5, yuvconstants); - src_y += 2; - src_vu += 2; - rgb_buf += 6; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel(src_y[0], src_vu[1], src_vu[0], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - } -} - -void NV12ToRGB565Row_C(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width) { - uint8_t b0; - uint8_t g0; - uint8_t r0; - uint8_t b1; - uint8_t g1; - uint8_t r1; - int x; - for (x = 0; x < width - 1; x += 2) { - YuvPixel(src_y[0], src_uv[0], src_uv[1], &b0, &g0, &r0, yuvconstants); - YuvPixel(src_y[1], src_uv[0], src_uv[1], &b1, &g1, &r1, yuvconstants); - b0 = b0 >> 3; - g0 = g0 >> 2; - r0 = r0 >> 3; - b1 = b1 >> 3; - g1 = g1 >> 2; - r1 = r1 >> 3; - *(uint32_t*)(dst_rgb565) = - b0 | (g0 << 5) | (r0 << 11) | (b1 << 16) | (g1 << 21) | (r1 << 27); - src_y += 2; - src_uv += 2; - dst_rgb565 += 4; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel(src_y[0], src_uv[0], src_uv[1], &b0, &g0, &r0, yuvconstants); - b0 = b0 >> 3; - g0 = g0 >> 2; - r0 = r0 >> 3; - *(uint16_t*)(dst_rgb565) = b0 | (g0 << 5) | (r0 << 11); - } -} - -void YUY2ToARGBRow_C(const uint8_t* src_yuy2, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - YuvPixel(src_yuy2[0], src_yuy2[1], src_yuy2[3], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - rgb_buf[3] = 255; - YuvPixel(src_yuy2[2], src_yuy2[1], src_yuy2[3], rgb_buf + 4, rgb_buf + 5, - rgb_buf + 6, yuvconstants); - rgb_buf[7] = 255; - src_yuy2 += 4; - rgb_buf += 8; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel(src_yuy2[0], src_yuy2[1], src_yuy2[3], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - rgb_buf[3] = 255; - } -} - -void UYVYToARGBRow_C(const uint8_t* src_uyvy, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - YuvPixel(src_uyvy[1], src_uyvy[0], src_uyvy[2], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - rgb_buf[3] = 255; - YuvPixel(src_uyvy[3], src_uyvy[0], src_uyvy[2], rgb_buf + 4, rgb_buf + 5, - rgb_buf + 6, yuvconstants); - rgb_buf[7] = 255; - src_uyvy += 4; - rgb_buf += 8; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel(src_uyvy[1], src_uyvy[0], src_uyvy[2], rgb_buf + 0, rgb_buf + 1, - rgb_buf + 2, yuvconstants); - rgb_buf[3] = 255; - } -} - -void I422ToRGBARow_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* rgb_buf, - const struct YuvConstants* yuvconstants, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - YuvPixel(src_y[0], src_u[0], src_v[0], rgb_buf + 1, rgb_buf + 2, - rgb_buf + 3, yuvconstants); - rgb_buf[0] = 255; - YuvPixel(src_y[1], src_u[0], src_v[0], rgb_buf + 5, rgb_buf + 6, - rgb_buf + 7, yuvconstants); - rgb_buf[4] = 255; - src_y += 2; - src_u += 1; - src_v += 1; - rgb_buf += 8; // Advance 2 pixels. - } - if (width & 1) { - YuvPixel(src_y[0], src_u[0], src_v[0], rgb_buf + 1, rgb_buf + 2, - rgb_buf + 3, yuvconstants); - rgb_buf[0] = 255; - } -} - -void I400ToARGBRow_C(const uint8_t* src_y, uint8_t* rgb_buf, int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - YPixel(src_y[0], rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); - rgb_buf[3] = 255; - YPixel(src_y[1], rgb_buf + 4, rgb_buf + 5, rgb_buf + 6); - rgb_buf[7] = 255; - src_y += 2; - rgb_buf += 8; // Advance 2 pixels. - } - if (width & 1) { - YPixel(src_y[0], rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); - rgb_buf[3] = 255; - } -} - -void MirrorRow_C(const uint8_t* src, uint8_t* dst, int width) { - int x; - src += width - 1; - for (x = 0; x < width - 1; x += 2) { - dst[x] = src[0]; - dst[x + 1] = src[-1]; - src -= 2; - } - if (width & 1) { - dst[width - 1] = src[0]; - } -} - -void MirrorUVRow_C(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - int x; - src_uv += (width - 1) << 1; - for (x = 0; x < width - 1; x += 2) { - dst_u[x] = src_uv[0]; - dst_u[x + 1] = src_uv[-2]; - dst_v[x] = src_uv[1]; - dst_v[x + 1] = src_uv[-2 + 1]; - src_uv -= 4; - } - if (width & 1) { - dst_u[width - 1] = src_uv[0]; - dst_v[width - 1] = src_uv[1]; - } -} - -void ARGBMirrorRow_C(const uint8_t* src, uint8_t* dst, int width) { - int x; - const uint32_t* src32 = (const uint32_t*)(src); - uint32_t* dst32 = (uint32_t*)(dst); - src32 += width - 1; - for (x = 0; x < width - 1; x += 2) { - dst32[x] = src32[0]; - dst32[x + 1] = src32[-1]; - src32 -= 2; - } - if (width & 1) { - dst32[width - 1] = src32[0]; - } -} - -void SplitUVRow_C(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - dst_u[x] = src_uv[0]; - dst_u[x + 1] = src_uv[2]; - dst_v[x] = src_uv[1]; - dst_v[x + 1] = src_uv[3]; - src_uv += 4; - } - if (width & 1) { - dst_u[width - 1] = src_uv[0]; - dst_v[width - 1] = src_uv[1]; - } -} - -void MergeUVRow_C(const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uv, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - dst_uv[0] = src_u[x]; - dst_uv[1] = src_v[x]; - dst_uv[2] = src_u[x + 1]; - dst_uv[3] = src_v[x + 1]; - dst_uv += 4; - } - if (width & 1) { - dst_uv[0] = src_u[width - 1]; - dst_uv[1] = src_v[width - 1]; - } -} - -void SplitRGBRow_C(const uint8_t* src_rgb, - uint8_t* dst_r, - uint8_t* dst_g, - uint8_t* dst_b, - int width) { - int x; - for (x = 0; x < width; ++x) { - dst_r[x] = src_rgb[0]; - dst_g[x] = src_rgb[1]; - dst_b[x] = src_rgb[2]; - src_rgb += 3; - } -} - -void MergeRGBRow_C(const uint8_t* src_r, - const uint8_t* src_g, - const uint8_t* src_b, - uint8_t* dst_rgb, - int width) { - int x; - for (x = 0; x < width; ++x) { - dst_rgb[0] = src_r[x]; - dst_rgb[1] = src_g[x]; - dst_rgb[2] = src_b[x]; - dst_rgb += 3; - } -} - -// Use scale to convert lsb formats to msb, depending how many bits there are: -// 128 = 9 bits -// 64 = 10 bits -// 16 = 12 bits -// 1 = 16 bits -void MergeUVRow_16_C(const uint16_t* src_u, - const uint16_t* src_v, - uint16_t* dst_uv, - int scale, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - dst_uv[0] = src_u[x] * scale; - dst_uv[1] = src_v[x] * scale; - dst_uv[2] = src_u[x + 1] * scale; - dst_uv[3] = src_v[x + 1] * scale; - dst_uv += 4; - } - if (width & 1) { - dst_uv[0] = src_u[width - 1] * scale; - dst_uv[1] = src_v[width - 1] * scale; - } -} - -void MultiplyRow_16_C(const uint16_t* src_y, - uint16_t* dst_y, - int scale, - int width) { - int x; - for (x = 0; x < width; ++x) { - dst_y[x] = src_y[x] * scale; - } -} - -// Use scale to convert lsb formats to msb, depending how many bits there are: -// 32768 = 9 bits -// 16384 = 10 bits -// 4096 = 12 bits -// 256 = 16 bits -void Convert16To8Row_C(const uint16_t* src_y, - uint8_t* dst_y, - int scale, - int width) { - int x; - for (x = 0; x < width; ++x) { - dst_y[x] = clamp255((src_y[x] * scale) >> 16); - } -} - -// Use scale to convert lsb formats to msb, depending how many bits there are: -// 1024 = 10 bits -void Convert8To16Row_C(const uint8_t* src_y, - uint16_t* dst_y, - int scale, - int width) { - int x; - scale *= 0x0101; // replicates the byte. - for (x = 0; x < width; ++x) { - dst_y[x] = (src_y[x] * scale) >> 16; - } -} - -void CopyRow_C(const uint8_t* src, uint8_t* dst, int count) { - memcpy(dst, src, count); -} - -void CopyRow_16_C(const uint16_t* src, uint16_t* dst, int count) { - memcpy(dst, src, count * 2); -} - -void SetRow_C(uint8_t* dst, uint8_t v8, int width) { - memset(dst, v8, width); -} - -void ARGBSetRow_C(uint8_t* dst_argb, uint32_t v32, int width) { - uint32_t* d = (uint32_t*)(dst_argb); - int x; - for (x = 0; x < width; ++x) { - d[x] = v32; - } -} - -// Filter 2 rows of YUY2 UV's (422) into U and V (420). -void YUY2ToUVRow_C(const uint8_t* src_yuy2, - int src_stride_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - // Output a row of UV values, filtering 2 rows of YUY2. - int x; - for (x = 0; x < width; x += 2) { - dst_u[0] = (src_yuy2[1] + src_yuy2[src_stride_yuy2 + 1] + 1) >> 1; - dst_v[0] = (src_yuy2[3] + src_yuy2[src_stride_yuy2 + 3] + 1) >> 1; - src_yuy2 += 4; - dst_u += 1; - dst_v += 1; - } -} - -// Copy row of YUY2 UV's (422) into U and V (422). -void YUY2ToUV422Row_C(const uint8_t* src_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - // Output a row of UV values. - int x; - for (x = 0; x < width; x += 2) { - dst_u[0] = src_yuy2[1]; - dst_v[0] = src_yuy2[3]; - src_yuy2 += 4; - dst_u += 1; - dst_v += 1; - } -} - -// Copy row of YUY2 Y's (422) into Y (420/422). -void YUY2ToYRow_C(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { - // Output a row of Y values. - int x; - for (x = 0; x < width - 1; x += 2) { - dst_y[x] = src_yuy2[0]; - dst_y[x + 1] = src_yuy2[2]; - src_yuy2 += 4; - } - if (width & 1) { - dst_y[width - 1] = src_yuy2[0]; - } -} - -// Filter 2 rows of UYVY UV's (422) into U and V (420). -void UYVYToUVRow_C(const uint8_t* src_uyvy, - int src_stride_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - // Output a row of UV values. - int x; - for (x = 0; x < width; x += 2) { - dst_u[0] = (src_uyvy[0] + src_uyvy[src_stride_uyvy + 0] + 1) >> 1; - dst_v[0] = (src_uyvy[2] + src_uyvy[src_stride_uyvy + 2] + 1) >> 1; - src_uyvy += 4; - dst_u += 1; - dst_v += 1; - } -} - -// Copy row of UYVY UV's (422) into U and V (422). -void UYVYToUV422Row_C(const uint8_t* src_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - // Output a row of UV values. - int x; - for (x = 0; x < width; x += 2) { - dst_u[0] = src_uyvy[0]; - dst_v[0] = src_uyvy[2]; - src_uyvy += 4; - dst_u += 1; - dst_v += 1; - } -} - -// Copy row of UYVY Y's (422) into Y (420/422). -void UYVYToYRow_C(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { - // Output a row of Y values. - int x; - for (x = 0; x < width - 1; x += 2) { - dst_y[x] = src_uyvy[1]; - dst_y[x + 1] = src_uyvy[3]; - src_uyvy += 4; - } - if (width & 1) { - dst_y[width - 1] = src_uyvy[1]; - } -} - -#define BLEND(f, b, a) (((256 - a) * b) >> 8) + f - -// Blend src_argb0 over src_argb1 and store to dst_argb. -// dst_argb may be src_argb0 or src_argb1. -// This code mimics the SSSE3 version for better testability. -void ARGBBlendRow_C(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - uint32_t fb = src_argb0[0]; - uint32_t fg = src_argb0[1]; - uint32_t fr = src_argb0[2]; - uint32_t a = src_argb0[3]; - uint32_t bb = src_argb1[0]; - uint32_t bg = src_argb1[1]; - uint32_t br = src_argb1[2]; - dst_argb[0] = BLEND(fb, bb, a); - dst_argb[1] = BLEND(fg, bg, a); - dst_argb[2] = BLEND(fr, br, a); - dst_argb[3] = 255u; - - fb = src_argb0[4 + 0]; - fg = src_argb0[4 + 1]; - fr = src_argb0[4 + 2]; - a = src_argb0[4 + 3]; - bb = src_argb1[4 + 0]; - bg = src_argb1[4 + 1]; - br = src_argb1[4 + 2]; - dst_argb[4 + 0] = BLEND(fb, bb, a); - dst_argb[4 + 1] = BLEND(fg, bg, a); - dst_argb[4 + 2] = BLEND(fr, br, a); - dst_argb[4 + 3] = 255u; - src_argb0 += 8; - src_argb1 += 8; - dst_argb += 8; - } - - if (width & 1) { - uint32_t fb = src_argb0[0]; - uint32_t fg = src_argb0[1]; - uint32_t fr = src_argb0[2]; - uint32_t a = src_argb0[3]; - uint32_t bb = src_argb1[0]; - uint32_t bg = src_argb1[1]; - uint32_t br = src_argb1[2]; - dst_argb[0] = BLEND(fb, bb, a); - dst_argb[1] = BLEND(fg, bg, a); - dst_argb[2] = BLEND(fr, br, a); - dst_argb[3] = 255u; - } -} -#undef BLEND - -#define UBLEND(f, b, a) (((a)*f) + ((255 - a) * b) + 255) >> 8 -void BlendPlaneRow_C(const uint8_t* src0, - const uint8_t* src1, - const uint8_t* alpha, - uint8_t* dst, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - dst[0] = UBLEND(src0[0], src1[0], alpha[0]); - dst[1] = UBLEND(src0[1], src1[1], alpha[1]); - src0 += 2; - src1 += 2; - alpha += 2; - dst += 2; - } - if (width & 1) { - dst[0] = UBLEND(src0[0], src1[0], alpha[0]); - } -} -#undef UBLEND - -#define ATTENUATE(f, a) (a | (a << 8)) * (f | (f << 8)) >> 24 - -// Multiply source RGB by alpha and store to destination. -// This code mimics the SSSE3 version for better testability. -void ARGBAttenuateRow_C(const uint8_t* src_argb, uint8_t* dst_argb, int width) { - int i; - for (i = 0; i < width - 1; i += 2) { - uint32_t b = src_argb[0]; - uint32_t g = src_argb[1]; - uint32_t r = src_argb[2]; - uint32_t a = src_argb[3]; - dst_argb[0] = ATTENUATE(b, a); - dst_argb[1] = ATTENUATE(g, a); - dst_argb[2] = ATTENUATE(r, a); - dst_argb[3] = a; - b = src_argb[4]; - g = src_argb[5]; - r = src_argb[6]; - a = src_argb[7]; - dst_argb[4] = ATTENUATE(b, a); - dst_argb[5] = ATTENUATE(g, a); - dst_argb[6] = ATTENUATE(r, a); - dst_argb[7] = a; - src_argb += 8; - dst_argb += 8; - } - - if (width & 1) { - const uint32_t b = src_argb[0]; - const uint32_t g = src_argb[1]; - const uint32_t r = src_argb[2]; - const uint32_t a = src_argb[3]; - dst_argb[0] = ATTENUATE(b, a); - dst_argb[1] = ATTENUATE(g, a); - dst_argb[2] = ATTENUATE(r, a); - dst_argb[3] = a; - } -} -#undef ATTENUATE - -// Divide source RGB by alpha and store to destination. -// b = (b * 255 + (a / 2)) / a; -// g = (g * 255 + (a / 2)) / a; -// r = (r * 255 + (a / 2)) / a; -// Reciprocal method is off by 1 on some values. ie 125 -// 8.8 fixed point inverse table with 1.0 in upper short and 1 / a in lower. -#define T(a) 0x01000000 + (0x10000 / a) -const uint32_t fixed_invtbl8[256] = { - 0x01000000, 0x0100ffff, T(0x02), T(0x03), T(0x04), T(0x05), T(0x06), - T(0x07), T(0x08), T(0x09), T(0x0a), T(0x0b), T(0x0c), T(0x0d), - T(0x0e), T(0x0f), T(0x10), T(0x11), T(0x12), T(0x13), T(0x14), - T(0x15), T(0x16), T(0x17), T(0x18), T(0x19), T(0x1a), T(0x1b), - T(0x1c), T(0x1d), T(0x1e), T(0x1f), T(0x20), T(0x21), T(0x22), - T(0x23), T(0x24), T(0x25), T(0x26), T(0x27), T(0x28), T(0x29), - T(0x2a), T(0x2b), T(0x2c), T(0x2d), T(0x2e), T(0x2f), T(0x30), - T(0x31), T(0x32), T(0x33), T(0x34), T(0x35), T(0x36), T(0x37), - T(0x38), T(0x39), T(0x3a), T(0x3b), T(0x3c), T(0x3d), T(0x3e), - T(0x3f), T(0x40), T(0x41), T(0x42), T(0x43), T(0x44), T(0x45), - T(0x46), T(0x47), T(0x48), T(0x49), T(0x4a), T(0x4b), T(0x4c), - T(0x4d), T(0x4e), T(0x4f), T(0x50), T(0x51), T(0x52), T(0x53), - T(0x54), T(0x55), T(0x56), T(0x57), T(0x58), T(0x59), T(0x5a), - T(0x5b), T(0x5c), T(0x5d), T(0x5e), T(0x5f), T(0x60), T(0x61), - T(0x62), T(0x63), T(0x64), T(0x65), T(0x66), T(0x67), T(0x68), - T(0x69), T(0x6a), T(0x6b), T(0x6c), T(0x6d), T(0x6e), T(0x6f), - T(0x70), T(0x71), T(0x72), T(0x73), T(0x74), T(0x75), T(0x76), - T(0x77), T(0x78), T(0x79), T(0x7a), T(0x7b), T(0x7c), T(0x7d), - T(0x7e), T(0x7f), T(0x80), T(0x81), T(0x82), T(0x83), T(0x84), - T(0x85), T(0x86), T(0x87), T(0x88), T(0x89), T(0x8a), T(0x8b), - T(0x8c), T(0x8d), T(0x8e), T(0x8f), T(0x90), T(0x91), T(0x92), - T(0x93), T(0x94), T(0x95), T(0x96), T(0x97), T(0x98), T(0x99), - T(0x9a), T(0x9b), T(0x9c), T(0x9d), T(0x9e), T(0x9f), T(0xa0), - T(0xa1), T(0xa2), T(0xa3), T(0xa4), T(0xa5), T(0xa6), T(0xa7), - T(0xa8), T(0xa9), T(0xaa), T(0xab), T(0xac), T(0xad), T(0xae), - T(0xaf), T(0xb0), T(0xb1), T(0xb2), T(0xb3), T(0xb4), T(0xb5), - T(0xb6), T(0xb7), T(0xb8), T(0xb9), T(0xba), T(0xbb), T(0xbc), - T(0xbd), T(0xbe), T(0xbf), T(0xc0), T(0xc1), T(0xc2), T(0xc3), - T(0xc4), T(0xc5), T(0xc6), T(0xc7), T(0xc8), T(0xc9), T(0xca), - T(0xcb), T(0xcc), T(0xcd), T(0xce), T(0xcf), T(0xd0), T(0xd1), - T(0xd2), T(0xd3), T(0xd4), T(0xd5), T(0xd6), T(0xd7), T(0xd8), - T(0xd9), T(0xda), T(0xdb), T(0xdc), T(0xdd), T(0xde), T(0xdf), - T(0xe0), T(0xe1), T(0xe2), T(0xe3), T(0xe4), T(0xe5), T(0xe6), - T(0xe7), T(0xe8), T(0xe9), T(0xea), T(0xeb), T(0xec), T(0xed), - T(0xee), T(0xef), T(0xf0), T(0xf1), T(0xf2), T(0xf3), T(0xf4), - T(0xf5), T(0xf6), T(0xf7), T(0xf8), T(0xf9), T(0xfa), T(0xfb), - T(0xfc), T(0xfd), T(0xfe), 0x01000100}; -#undef T - -void ARGBUnattenuateRow_C(const uint8_t* src_argb, - uint8_t* dst_argb, - int width) { - int i; - for (i = 0; i < width; ++i) { - uint32_t b = src_argb[0]; - uint32_t g = src_argb[1]; - uint32_t r = src_argb[2]; - const uint32_t a = src_argb[3]; - const uint32_t ia = fixed_invtbl8[a] & 0xffff; // 8.8 fixed point - b = (b * ia) >> 8; - g = (g * ia) >> 8; - r = (r * ia) >> 8; - // Clamping should not be necessary but is free in assembly. - dst_argb[0] = clamp255(b); - dst_argb[1] = clamp255(g); - dst_argb[2] = clamp255(r); - dst_argb[3] = a; - src_argb += 4; - dst_argb += 4; - } -} - -void ComputeCumulativeSumRow_C(const uint8_t* row, - int32_t* cumsum, - const int32_t* previous_cumsum, - int width) { - int32_t row_sum[4] = {0, 0, 0, 0}; - int x; - for (x = 0; x < width; ++x) { - row_sum[0] += row[x * 4 + 0]; - row_sum[1] += row[x * 4 + 1]; - row_sum[2] += row[x * 4 + 2]; - row_sum[3] += row[x * 4 + 3]; - cumsum[x * 4 + 0] = row_sum[0] + previous_cumsum[x * 4 + 0]; - cumsum[x * 4 + 1] = row_sum[1] + previous_cumsum[x * 4 + 1]; - cumsum[x * 4 + 2] = row_sum[2] + previous_cumsum[x * 4 + 2]; - cumsum[x * 4 + 3] = row_sum[3] + previous_cumsum[x * 4 + 3]; - } -} - -void CumulativeSumToAverageRow_C(const int32_t* tl, - const int32_t* bl, - int w, - int area, - uint8_t* dst, - int count) { - float ooa = 1.0f / area; - int i; - for (i = 0; i < count; ++i) { - dst[0] = (uint8_t)((bl[w + 0] + tl[0] - bl[0] - tl[w + 0]) * ooa); - dst[1] = (uint8_t)((bl[w + 1] + tl[1] - bl[1] - tl[w + 1]) * ooa); - dst[2] = (uint8_t)((bl[w + 2] + tl[2] - bl[2] - tl[w + 2]) * ooa); - dst[3] = (uint8_t)((bl[w + 3] + tl[3] - bl[3] - tl[w + 3]) * ooa); - dst += 4; - tl += 4; - bl += 4; - } -} - -// Copy pixels from rotated source to destination row with a slope. -LIBYUV_API -void ARGBAffineRow_C(const uint8_t* src_argb, - int src_argb_stride, - uint8_t* dst_argb, - const float* uv_dudv, - int width) { - int i; - // Render a row of pixels from source into a buffer. - float uv[2]; - uv[0] = uv_dudv[0]; - uv[1] = uv_dudv[1]; - for (i = 0; i < width; ++i) { - int x = (int)(uv[0]); - int y = (int)(uv[1]); - *(uint32_t*)(dst_argb) = - *(const uint32_t*)(src_argb + y * src_argb_stride + x * 4); - dst_argb += 4; - uv[0] += uv_dudv[2]; - uv[1] += uv_dudv[3]; - } -} - -// Blend 2 rows into 1. -static void HalfRow_C(const uint8_t* src_uv, - ptrdiff_t src_uv_stride, - uint8_t* dst_uv, - int width) { - int x; - for (x = 0; x < width; ++x) { - dst_uv[x] = (src_uv[x] + src_uv[src_uv_stride + x] + 1) >> 1; - } -} - -static void HalfRow_16_C(const uint16_t* src_uv, - ptrdiff_t src_uv_stride, - uint16_t* dst_uv, - int width) { - int x; - for (x = 0; x < width; ++x) { - dst_uv[x] = (src_uv[x] + src_uv[src_uv_stride + x] + 1) >> 1; - } -} - -// C version 2x2 -> 2x1. -void InterpolateRow_C(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride, - int width, - int source_y_fraction) { - int y1_fraction = source_y_fraction; - int y0_fraction = 256 - y1_fraction; - const uint8_t* src_ptr1 = src_ptr + src_stride; - int x; - if (y1_fraction == 0) { - memcpy(dst_ptr, src_ptr, width); - return; - } - if (y1_fraction == 128) { - HalfRow_C(src_ptr, src_stride, dst_ptr, width); - return; - } - for (x = 0; x < width - 1; x += 2) { - dst_ptr[0] = - (src_ptr[0] * y0_fraction + src_ptr1[0] * y1_fraction + 128) >> 8; - dst_ptr[1] = - (src_ptr[1] * y0_fraction + src_ptr1[1] * y1_fraction + 128) >> 8; - src_ptr += 2; - src_ptr1 += 2; - dst_ptr += 2; - } - if (width & 1) { - dst_ptr[0] = - (src_ptr[0] * y0_fraction + src_ptr1[0] * y1_fraction + 128) >> 8; - } -} - -void InterpolateRow_16_C(uint16_t* dst_ptr, - const uint16_t* src_ptr, - ptrdiff_t src_stride, - int width, - int source_y_fraction) { - int y1_fraction = source_y_fraction; - int y0_fraction = 256 - y1_fraction; - const uint16_t* src_ptr1 = src_ptr + src_stride; - int x; - if (source_y_fraction == 0) { - memcpy(dst_ptr, src_ptr, width * 2); - return; - } - if (source_y_fraction == 128) { - HalfRow_16_C(src_ptr, src_stride, dst_ptr, width); - return; - } - for (x = 0; x < width - 1; x += 2) { - dst_ptr[0] = (src_ptr[0] * y0_fraction + src_ptr1[0] * y1_fraction) >> 8; - dst_ptr[1] = (src_ptr[1] * y0_fraction + src_ptr1[1] * y1_fraction) >> 8; - src_ptr += 2; - src_ptr1 += 2; - dst_ptr += 2; - } - if (width & 1) { - dst_ptr[0] = (src_ptr[0] * y0_fraction + src_ptr1[0] * y1_fraction) >> 8; - } -} - -// Use first 4 shuffler values to reorder ARGB channels. -void ARGBShuffleRow_C(const uint8_t* src_argb, - uint8_t* dst_argb, - const uint8_t* shuffler, - int width) { - int index0 = shuffler[0]; - int index1 = shuffler[1]; - int index2 = shuffler[2]; - int index3 = shuffler[3]; - // Shuffle a row of ARGB. - int x; - for (x = 0; x < width; ++x) { - // To support in-place conversion. - uint8_t b = src_argb[index0]; - uint8_t g = src_argb[index1]; - uint8_t r = src_argb[index2]; - uint8_t a = src_argb[index3]; - dst_argb[0] = b; - dst_argb[1] = g; - dst_argb[2] = r; - dst_argb[3] = a; - src_argb += 4; - dst_argb += 4; - } -} - -void I422ToYUY2Row_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_frame, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - dst_frame[0] = src_y[0]; - dst_frame[1] = src_u[0]; - dst_frame[2] = src_y[1]; - dst_frame[3] = src_v[0]; - dst_frame += 4; - src_y += 2; - src_u += 1; - src_v += 1; - } - if (width & 1) { - dst_frame[0] = src_y[0]; - dst_frame[1] = src_u[0]; - dst_frame[2] = 0; - dst_frame[3] = src_v[0]; - } -} - -void I422ToUYVYRow_C(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_frame, - int width) { - int x; - for (x = 0; x < width - 1; x += 2) { - dst_frame[0] = src_u[0]; - dst_frame[1] = src_y[0]; - dst_frame[2] = src_v[0]; - dst_frame[3] = src_y[1]; - dst_frame += 4; - src_y += 2; - src_u += 1; - src_v += 1; - } - if (width & 1) { - dst_frame[0] = src_u[0]; - dst_frame[1] = src_y[0]; - dst_frame[2] = src_v[0]; - dst_frame[3] = 0; - } -} - -void ARGBPolynomialRow_C(const uint8_t* src_argb, - uint8_t* dst_argb, - const float* poly, - int width) { - int i; - for (i = 0; i < width; ++i) { - float b = (float)(src_argb[0]); - float g = (float)(src_argb[1]); - float r = (float)(src_argb[2]); - float a = (float)(src_argb[3]); - float b2 = b * b; - float g2 = g * g; - float r2 = r * r; - float a2 = a * a; - float db = poly[0] + poly[4] * b; - float dg = poly[1] + poly[5] * g; - float dr = poly[2] + poly[6] * r; - float da = poly[3] + poly[7] * a; - float b3 = b2 * b; - float g3 = g2 * g; - float r3 = r2 * r; - float a3 = a2 * a; - db += poly[8] * b2; - dg += poly[9] * g2; - dr += poly[10] * r2; - da += poly[11] * a2; - db += poly[12] * b3; - dg += poly[13] * g3; - dr += poly[14] * r3; - da += poly[15] * a3; - - dst_argb[0] = Clamp((int32_t)(db)); - dst_argb[1] = Clamp((int32_t)(dg)); - dst_argb[2] = Clamp((int32_t)(dr)); - dst_argb[3] = Clamp((int32_t)(da)); - src_argb += 4; - dst_argb += 4; - } -} - -// Samples assumed to be unsigned in low 9, 10 or 12 bits. Scale factor -// adjust the source integer range to the half float range desired. - -// This magic constant is 2^-112. Multiplying by this -// is the same as subtracting 112 from the exponent, which -// is the difference in exponent bias between 32-bit and -// 16-bit floats. Once we've done this subtraction, we can -// simply extract the low bits of the exponent and the high -// bits of the mantissa from our float and we're done. - -// Work around GCC 7 punning warning -Wstrict-aliasing -#if defined(__GNUC__) -typedef uint32_t __attribute__((__may_alias__)) uint32_alias_t; -#else -typedef uint32_t uint32_alias_t; -#endif - -void HalfFloatRow_C(const uint16_t* src, - uint16_t* dst, - float scale, - int width) { - int i; - float mult = 1.9259299444e-34f * scale; - for (i = 0; i < width; ++i) { - float value = src[i] * mult; - dst[i] = (uint16_t)((*(const uint32_alias_t*)&value) >> 13); - } -} - -void ByteToFloatRow_C(const uint8_t* src, float* dst, float scale, int width) { - int i; - for (i = 0; i < width; ++i) { - float value = src[i] * scale; - dst[i] = value; - } -} - -void ARGBLumaColorTableRow_C(const uint8_t* src_argb, - uint8_t* dst_argb, - int width, - const uint8_t* luma, - uint32_t lumacoeff) { - uint32_t bc = lumacoeff & 0xff; - uint32_t gc = (lumacoeff >> 8) & 0xff; - uint32_t rc = (lumacoeff >> 16) & 0xff; - - int i; - for (i = 0; i < width - 1; i += 2) { - // Luminance in rows, color values in columns. - const uint8_t* luma0 = - ((src_argb[0] * bc + src_argb[1] * gc + src_argb[2] * rc) & 0x7F00u) + - luma; - const uint8_t* luma1; - dst_argb[0] = luma0[src_argb[0]]; - dst_argb[1] = luma0[src_argb[1]]; - dst_argb[2] = luma0[src_argb[2]]; - dst_argb[3] = src_argb[3]; - luma1 = - ((src_argb[4] * bc + src_argb[5] * gc + src_argb[6] * rc) & 0x7F00u) + - luma; - dst_argb[4] = luma1[src_argb[4]]; - dst_argb[5] = luma1[src_argb[5]]; - dst_argb[6] = luma1[src_argb[6]]; - dst_argb[7] = src_argb[7]; - src_argb += 8; - dst_argb += 8; - } - if (width & 1) { - // Luminance in rows, color values in columns. - const uint8_t* luma0 = - ((src_argb[0] * bc + src_argb[1] * gc + src_argb[2] * rc) & 0x7F00u) + - luma; - dst_argb[0] = luma0[src_argb[0]]; - dst_argb[1] = luma0[src_argb[1]]; - dst_argb[2] = luma0[src_argb[2]]; - dst_argb[3] = src_argb[3]; - } -} - -void ARGBCopyAlphaRow_C(const uint8_t* src, uint8_t* dst, int width) { - int i; - for (i = 0; i < width - 1; i += 2) { - dst[3] = src[3]; - dst[7] = src[7]; - dst += 8; - src += 8; - } - if (width & 1) { - dst[3] = src[3]; - } -} - -void ARGBExtractAlphaRow_C(const uint8_t* src_argb, uint8_t* dst_a, int width) { - int i; - for (i = 0; i < width - 1; i += 2) { - dst_a[0] = src_argb[3]; - dst_a[1] = src_argb[7]; - dst_a += 2; - src_argb += 8; - } - if (width & 1) { - dst_a[0] = src_argb[3]; - } -} - -void ARGBCopyYToAlphaRow_C(const uint8_t* src, uint8_t* dst, int width) { - int i; - for (i = 0; i < width - 1; i += 2) { - dst[3] = src[0]; - dst[7] = src[1]; - dst += 8; - src += 2; - } - if (width & 1) { - dst[3] = src[0]; - } -} - -// Maximum temporary width for wrappers to process at a time, in pixels. -#define MAXTWIDTH 2048 - -#if !(defined(_MSC_VER) && defined(_M_IX86)) && \ - defined(HAS_I422TORGB565ROW_SSSE3) -// row_win.cc has asm version, but GCC uses 2 step wrapper. -void I422ToRGB565Row_SSSE3(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width) { - SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); - while (width > 0) { - int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; - I422ToARGBRow_SSSE3(src_y, src_u, src_v, row, yuvconstants, twidth); - ARGBToRGB565Row_SSE2(row, dst_rgb565, twidth); - src_y += twidth; - src_u += twidth / 2; - src_v += twidth / 2; - dst_rgb565 += twidth * 2; - width -= twidth; - } -} -#endif - -#if defined(HAS_I422TOARGB1555ROW_SSSE3) -void I422ToARGB1555Row_SSSE3(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb1555, - const struct YuvConstants* yuvconstants, - int width) { - // Row buffer for intermediate ARGB pixels. - SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); - while (width > 0) { - int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; - I422ToARGBRow_SSSE3(src_y, src_u, src_v, row, yuvconstants, twidth); - ARGBToARGB1555Row_SSE2(row, dst_argb1555, twidth); - src_y += twidth; - src_u += twidth / 2; - src_v += twidth / 2; - dst_argb1555 += twidth * 2; - width -= twidth; - } -} -#endif - -#if defined(HAS_I422TOARGB4444ROW_SSSE3) -void I422ToARGB4444Row_SSSE3(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb4444, - const struct YuvConstants* yuvconstants, - int width) { - // Row buffer for intermediate ARGB pixels. - SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); - while (width > 0) { - int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; - I422ToARGBRow_SSSE3(src_y, src_u, src_v, row, yuvconstants, twidth); - ARGBToARGB4444Row_SSE2(row, dst_argb4444, twidth); - src_y += twidth; - src_u += twidth / 2; - src_v += twidth / 2; - dst_argb4444 += twidth * 2; - width -= twidth; - } -} -#endif - -#if defined(HAS_NV12TORGB565ROW_SSSE3) -void NV12ToRGB565Row_SSSE3(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width) { - // Row buffer for intermediate ARGB pixels. - SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); - while (width > 0) { - int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; - NV12ToARGBRow_SSSE3(src_y, src_uv, row, yuvconstants, twidth); - ARGBToRGB565Row_SSE2(row, dst_rgb565, twidth); - src_y += twidth; - src_uv += twidth; - dst_rgb565 += twidth * 2; - width -= twidth; - } -} -#endif - -#if defined(HAS_NV12TORGB24ROW_SSSE3) -void NV12ToRGB24Row_SSSE3(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width) { - // Row buffer for intermediate ARGB pixels. - SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); - while (width > 0) { - int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; - NV12ToARGBRow_SSSE3(src_y, src_uv, row, yuvconstants, twidth); - ARGBToRGB24Row_SSSE3(row, dst_rgb24, twidth); - src_y += twidth; - src_uv += twidth; - dst_rgb24 += twidth * 3; - width -= twidth; - } -} -#endif - -#if defined(HAS_NV21TORGB24ROW_SSSE3) -void NV21ToRGB24Row_SSSE3(const uint8_t* src_y, - const uint8_t* src_vu, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width) { - // Row buffer for intermediate ARGB pixels. - SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); - while (width > 0) { - int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; - NV21ToARGBRow_SSSE3(src_y, src_vu, row, yuvconstants, twidth); - ARGBToRGB24Row_SSSE3(row, dst_rgb24, twidth); - src_y += twidth; - src_vu += twidth; - dst_rgb24 += twidth * 3; - width -= twidth; - } -} -#endif - -#if defined(HAS_NV12TORGB24ROW_AVX2) -void NV12ToRGB24Row_AVX2(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width) { - // Row buffer for intermediate ARGB pixels. - SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); - while (width > 0) { - int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; - NV12ToARGBRow_AVX2(src_y, src_uv, row, yuvconstants, twidth); -#if defined(HAS_ARGBTORGB24ROW_AVX2) - ARGBToRGB24Row_AVX2(row, dst_rgb24, twidth); -#else - ARGBToRGB24Row_SSSE3(row, dst_rgb24, twidth); -#endif - src_y += twidth; - src_uv += twidth; - dst_rgb24 += twidth * 3; - width -= twidth; - } -} -#endif - -#if defined(HAS_NV21TORGB24ROW_AVX2) -void NV21ToRGB24Row_AVX2(const uint8_t* src_y, - const uint8_t* src_vu, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width) { - // Row buffer for intermediate ARGB pixels. - SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); - while (width > 0) { - int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; - NV21ToARGBRow_AVX2(src_y, src_vu, row, yuvconstants, twidth); -#if defined(HAS_ARGBTORGB24ROW_AVX2) - ARGBToRGB24Row_AVX2(row, dst_rgb24, twidth); -#else - ARGBToRGB24Row_SSSE3(row, dst_rgb24, twidth); -#endif - src_y += twidth; - src_vu += twidth; - dst_rgb24 += twidth * 3; - width -= twidth; - } -} -#endif - -#if defined(HAS_I422TORGB565ROW_AVX2) -void I422ToRGB565Row_AVX2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width) { - SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); - 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; - dst_rgb565 += twidth * 2; - width -= twidth; - } -} -#endif - -#if defined(HAS_I422TOARGB1555ROW_AVX2) -void I422ToARGB1555Row_AVX2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb1555, - const struct YuvConstants* yuvconstants, - int width) { - // Row buffer for intermediate ARGB pixels. - SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); - 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; - dst_argb1555 += twidth * 2; - width -= twidth; - } -} -#endif - -#if defined(HAS_I422TOARGB4444ROW_AVX2) -void I422ToARGB4444Row_AVX2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb4444, - const struct YuvConstants* yuvconstants, - int width) { - // Row buffer for intermediate ARGB pixels. - SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); - 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; - dst_argb4444 += twidth * 2; - width -= twidth; - } -} -#endif - -#if defined(HAS_I422TORGB24ROW_AVX2) -void I422ToRGB24Row_AVX2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width) { - // Row buffer for intermediate ARGB pixels. - SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); - while (width > 0) { - int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; - I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth); -#if defined(HAS_ARGBTORGB24ROW_AVX2) - ARGBToRGB24Row_AVX2(row, dst_rgb24, twidth); -#else - ARGBToRGB24Row_SSSE3(row, dst_rgb24, twidth); -#endif - src_y += twidth; - src_u += twidth / 2; - src_v += twidth / 2; - dst_rgb24 += twidth * 3; - width -= twidth; - } -} -#endif - -#if defined(HAS_NV12TORGB565ROW_AVX2) -void NV12ToRGB565Row_AVX2(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width) { - // Row buffer for intermediate ARGB pixels. - SIMD_ALIGNED(uint8_t row[MAXTWIDTH * 4]); - 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; - width -= twidth; - } -} -#endif - -float ScaleSumSamples_C(const float* src, float* dst, float scale, int width) { - float fsum = 0.f; - int i; -#if defined(__clang__) -#pragma clang loop vectorize_width(4) -#endif - for (i = 0; i < width; ++i) { - float v = *src++; - fsum += v * v; - *dst++ = v * scale; - } - return fsum; -} - -float ScaleMaxSamples_C(const float* src, float* dst, float scale, int width) { - float fmax = 0.f; - int i; - for (i = 0; i < width; ++i) { - float v = *src++; - float vs = v * scale; - fmax = (v > fmax) ? v : fmax; - *dst++ = vs; - } - return fmax; -} - -void ScaleSamples_C(const float* src, float* dst, float scale, int width) { - int i; - for (i = 0; i < width; ++i) { - *dst++ = *src++ * scale; - } -} - -void GaussRow_C(const uint32_t* src, uint16_t* dst, int width) { - int i; - for (i = 0; i < width; ++i) { - *dst++ = - (src[0] + src[1] * 4 + src[2] * 6 + src[3] * 4 + src[4] + 128) >> 8; - ++src; - } -} - -// filter 5 rows with 1, 4, 6, 4, 1 coefficients to produce 1 row. -void GaussCol_C(const uint16_t* src0, - const uint16_t* src1, - const uint16_t* src2, - const uint16_t* src3, - const uint16_t* src4, - uint32_t* dst, - int width) { - int i; - for (i = 0; i < width; ++i) { - *dst++ = *src0++ + *src1++ * 4 + *src2++ * 6 + *src3++ * 4 + *src4++; - } -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_gcc.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_gcc.cc deleted file mode 100644 index 8d3cb81c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_gcc.cc +++ /dev/null @@ -1,6677 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// This module is for GCC x86 and x64. -#if !defined(LIBYUV_DISABLE_X86) && \ - (defined(__x86_64__) || (defined(__i386__) && !defined(_MSC_VER))) - -#if defined(HAS_ARGBTOYROW_SSSE3) || defined(HAS_ARGBGRAYROW_SSSE3) - -// Constants for ARGB -static const vec8 kARGBToY = {13, 65, 33, 0, 13, 65, 33, 0, - 13, 65, 33, 0, 13, 65, 33, 0}; - -// JPeg full range. -static const vec8 kARGBToYJ = {15, 75, 38, 0, 15, 75, 38, 0, - 15, 75, 38, 0, 15, 75, 38, 0}; -#endif // defined(HAS_ARGBTOYROW_SSSE3) || defined(HAS_ARGBGRAYROW_SSSE3) - -#if defined(HAS_ARGBTOYROW_SSSE3) || defined(HAS_I422TOARGBROW_SSSE3) - -static const vec8 kARGBToU = {112, -74, -38, 0, 112, -74, -38, 0, - 112, -74, -38, 0, 112, -74, -38, 0}; - -static const vec8 kARGBToUJ = {127, -84, -43, 0, 127, -84, -43, 0, - 127, -84, -43, 0, 127, -84, -43, 0}; - -static const vec8 kARGBToV = {-18, -94, 112, 0, -18, -94, 112, 0, - -18, -94, 112, 0, -18, -94, 112, 0}; - -static const vec8 kARGBToVJ = {-20, -107, 127, 0, -20, -107, 127, 0, - -20, -107, 127, 0, -20, -107, 127, 0}; - -// Constants for BGRA -static const vec8 kBGRAToY = {0, 33, 65, 13, 0, 33, 65, 13, - 0, 33, 65, 13, 0, 33, 65, 13}; - -static const vec8 kBGRAToU = {0, -38, -74, 112, 0, -38, -74, 112, - 0, -38, -74, 112, 0, -38, -74, 112}; - -static const vec8 kBGRAToV = {0, 112, -94, -18, 0, 112, -94, -18, - 0, 112, -94, -18, 0, 112, -94, -18}; - -// Constants for ABGR -static const vec8 kABGRToY = {33, 65, 13, 0, 33, 65, 13, 0, - 33, 65, 13, 0, 33, 65, 13, 0}; - -static const vec8 kABGRToU = {-38, -74, 112, 0, -38, -74, 112, 0, - -38, -74, 112, 0, -38, -74, 112, 0}; - -static const vec8 kABGRToV = {112, -94, -18, 0, 112, -94, -18, 0, - 112, -94, -18, 0, 112, -94, -18, 0}; - -// Constants for RGBA. -static const vec8 kRGBAToY = {0, 13, 65, 33, 0, 13, 65, 33, - 0, 13, 65, 33, 0, 13, 65, 33}; - -static const vec8 kRGBAToU = {0, 112, -74, -38, 0, 112, -74, -38, - 0, 112, -74, -38, 0, 112, -74, -38}; - -static const vec8 kRGBAToV = {0, -18, -94, 112, 0, -18, -94, 112, - 0, -18, -94, 112, 0, -18, -94, 112}; - -static const uvec8 kAddY16 = {16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u, - 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u}; - -// 7 bit fixed point 0.5. -static const vec16 kAddYJ64 = {64, 64, 64, 64, 64, 64, 64, 64}; - -static const uvec8 kAddUV128 = {128u, 128u, 128u, 128u, 128u, 128u, 128u, 128u, - 128u, 128u, 128u, 128u, 128u, 128u, 128u, 128u}; - -static const uvec16 kAddUVJ128 = {0x8080u, 0x8080u, 0x8080u, 0x8080u, - 0x8080u, 0x8080u, 0x8080u, 0x8080u}; -#endif // defined(HAS_ARGBTOYROW_SSSE3) || defined(HAS_I422TOARGBROW_SSSE3) - -#ifdef HAS_RGB24TOARGBROW_SSSE3 - -// Shuffle table for converting RGB24 to ARGB. -static const uvec8 kShuffleMaskRGB24ToARGB = { - 0u, 1u, 2u, 12u, 3u, 4u, 5u, 13u, 6u, 7u, 8u, 14u, 9u, 10u, 11u, 15u}; - -// Shuffle table for converting RAW to ARGB. -static const uvec8 kShuffleMaskRAWToARGB = {2u, 1u, 0u, 12u, 5u, 4u, 3u, 13u, - 8u, 7u, 6u, 14u, 11u, 10u, 9u, 15u}; - -// Shuffle table for converting RAW to RGB24. First 8. -static const uvec8 kShuffleMaskRAWToRGB24_0 = { - 2u, 1u, 0u, 5u, 4u, 3u, 8u, 7u, - 128u, 128u, 128u, 128u, 128u, 128u, 128u, 128u}; - -// Shuffle table for converting RAW to RGB24. Middle 8. -static const uvec8 kShuffleMaskRAWToRGB24_1 = { - 2u, 7u, 6u, 5u, 10u, 9u, 8u, 13u, - 128u, 128u, 128u, 128u, 128u, 128u, 128u, 128u}; - -// Shuffle table for converting RAW to RGB24. Last 8. -static const uvec8 kShuffleMaskRAWToRGB24_2 = { - 8u, 7u, 12u, 11u, 10u, 15u, 14u, 13u, - 128u, 128u, 128u, 128u, 128u, 128u, 128u, 128u}; - -// Shuffle table for converting ARGB to RGB24. -static const uvec8 kShuffleMaskARGBToRGB24 = { - 0u, 1u, 2u, 4u, 5u, 6u, 8u, 9u, 10u, 12u, 13u, 14u, 128u, 128u, 128u, 128u}; - -// Shuffle table for converting ARGB to RAW. -static const uvec8 kShuffleMaskARGBToRAW = { - 2u, 1u, 0u, 6u, 5u, 4u, 10u, 9u, 8u, 14u, 13u, 12u, 128u, 128u, 128u, 128u}; - -// Shuffle table for converting ARGBToRGB24 for I422ToRGB24. First 8 + next 4 -static const uvec8 kShuffleMaskARGBToRGB24_0 = { - 0u, 1u, 2u, 4u, 5u, 6u, 8u, 9u, 128u, 128u, 128u, 128u, 10u, 12u, 13u, 14u}; - -// YUY2 shuf 16 Y to 32 Y. -static const lvec8 kShuffleYUY2Y = {0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, - 10, 12, 12, 14, 14, 0, 0, 2, 2, 4, 4, - 6, 6, 8, 8, 10, 10, 12, 12, 14, 14}; - -// YUY2 shuf 8 UV to 16 UV. -static const lvec8 kShuffleYUY2UV = {1, 3, 1, 3, 5, 7, 5, 7, 9, 11, 9, - 11, 13, 15, 13, 15, 1, 3, 1, 3, 5, 7, - 5, 7, 9, 11, 9, 11, 13, 15, 13, 15}; - -// UYVY shuf 16 Y to 32 Y. -static const lvec8 kShuffleUYVYY = {1, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11, - 11, 13, 13, 15, 15, 1, 1, 3, 3, 5, 5, - 7, 7, 9, 9, 11, 11, 13, 13, 15, 15}; - -// UYVY shuf 8 UV to 16 UV. -static const lvec8 kShuffleUYVYUV = {0, 2, 0, 2, 4, 6, 4, 6, 8, 10, 8, - 10, 12, 14, 12, 14, 0, 2, 0, 2, 4, 6, - 4, 6, 8, 10, 8, 10, 12, 14, 12, 14}; - -// NV21 shuf 8 VU to 16 UV. -static const lvec8 kShuffleNV21 = { - 1, 0, 1, 0, 3, 2, 3, 2, 5, 4, 5, 4, 7, 6, 7, 6, - 1, 0, 1, 0, 3, 2, 3, 2, 5, 4, 5, 4, 7, 6, 7, 6, -}; -#endif // HAS_RGB24TOARGBROW_SSSE3 - -#ifdef HAS_J400TOARGBROW_SSE2 -void J400ToARGBRow_SSE2(const uint8_t* src_y, uint8_t* dst_argb, int width) { - asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "pslld $0x18,%%xmm5 \n" - - LABELALIGN - "1: \n" - "movq (%0),%%xmm0 \n" - "lea 0x8(%0),%0 \n" - "punpcklbw %%xmm0,%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklwd %%xmm0,%%xmm0 \n" - "punpckhwd %%xmm1,%%xmm1 \n" - "por %%xmm5,%%xmm0 \n" - "por %%xmm5,%%xmm1 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu %%xmm1,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - : "+r"(src_y), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - ::"memory", - "cc", "xmm0", "xmm1", "xmm5"); -} -#endif // HAS_J400TOARGBROW_SSE2 - -#ifdef HAS_RGB24TOARGBROW_SSSE3 -void RGB24ToARGBRow_SSSE3(const uint8_t* src_rgb24, - uint8_t* dst_argb, - int width) { - asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" // 0xff000000 - "pslld $0x18,%%xmm5 \n" - "movdqa %3,%%xmm4 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm3 \n" - "lea 0x30(%0),%0 \n" - "movdqa %%xmm3,%%xmm2 \n" - "palignr $0x8,%%xmm1,%%xmm2 \n" - "pshufb %%xmm4,%%xmm2 \n" - "por %%xmm5,%%xmm2 \n" - "palignr $0xc,%%xmm0,%%xmm1 \n" - "pshufb %%xmm4,%%xmm0 \n" - "movdqu %%xmm2,0x20(%1) \n" - "por %%xmm5,%%xmm0 \n" - "pshufb %%xmm4,%%xmm1 \n" - "movdqu %%xmm0,(%1) \n" - "por %%xmm5,%%xmm1 \n" - "palignr $0x4,%%xmm3,%%xmm3 \n" - "pshufb %%xmm4,%%xmm3 \n" - "movdqu %%xmm1,0x10(%1) \n" - "por %%xmm5,%%xmm3 \n" - "movdqu %%xmm3,0x30(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src_rgb24), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : "m"(kShuffleMaskRGB24ToARGB) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} - -void RAWToARGBRow_SSSE3(const uint8_t* src_raw, uint8_t* dst_argb, int width) { - asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" // 0xff000000 - "pslld $0x18,%%xmm5 \n" - "movdqa %3,%%xmm4 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm3 \n" - "lea 0x30(%0),%0 \n" - "movdqa %%xmm3,%%xmm2 \n" - "palignr $0x8,%%xmm1,%%xmm2 \n" - "pshufb %%xmm4,%%xmm2 \n" - "por %%xmm5,%%xmm2 \n" - "palignr $0xc,%%xmm0,%%xmm1 \n" - "pshufb %%xmm4,%%xmm0 \n" - "movdqu %%xmm2,0x20(%1) \n" - "por %%xmm5,%%xmm0 \n" - "pshufb %%xmm4,%%xmm1 \n" - "movdqu %%xmm0,(%1) \n" - "por %%xmm5,%%xmm1 \n" - "palignr $0x4,%%xmm3,%%xmm3 \n" - "pshufb %%xmm4,%%xmm3 \n" - "movdqu %%xmm1,0x10(%1) \n" - "por %%xmm5,%%xmm3 \n" - "movdqu %%xmm3,0x30(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src_raw), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : "m"(kShuffleMaskRAWToARGB) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} - -void RAWToRGB24Row_SSSE3(const uint8_t* src_raw, - uint8_t* dst_rgb24, - int width) { - asm volatile( - "movdqa %3,%%xmm3 \n" - "movdqa %4,%%xmm4 \n" - "movdqa %5,%%xmm5 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x4(%0),%%xmm1 \n" - "movdqu 0x8(%0),%%xmm2 \n" - "lea 0x18(%0),%0 \n" - "pshufb %%xmm3,%%xmm0 \n" - "pshufb %%xmm4,%%xmm1 \n" - "pshufb %%xmm5,%%xmm2 \n" - "movq %%xmm0,(%1) \n" - "movq %%xmm1,0x8(%1) \n" - "movq %%xmm2,0x10(%1) \n" - "lea 0x18(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - : "+r"(src_raw), // %0 - "+r"(dst_rgb24), // %1 - "+r"(width) // %2 - : "m"(kShuffleMaskRAWToRGB24_0), // %3 - "m"(kShuffleMaskRAWToRGB24_1), // %4 - "m"(kShuffleMaskRAWToRGB24_2) // %5 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} - -void RGB565ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "mov $0x1080108,%%eax \n" - "movd %%eax,%%xmm5 \n" - "pshufd $0x0,%%xmm5,%%xmm5 \n" - "mov $0x20802080,%%eax \n" - "movd %%eax,%%xmm6 \n" - "pshufd $0x0,%%xmm6,%%xmm6 \n" - "pcmpeqb %%xmm3,%%xmm3 \n" - "psllw $0xb,%%xmm3 \n" - "pcmpeqb %%xmm4,%%xmm4 \n" - "psllw $0xa,%%xmm4 \n" - "psrlw $0x5,%%xmm4 \n" - "pcmpeqb %%xmm7,%%xmm7 \n" - "psllw $0x8,%%xmm7 \n" - "sub %0,%1 \n" - "sub %0,%1 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "pand %%xmm3,%%xmm1 \n" - "psllw $0xb,%%xmm2 \n" - "pmulhuw %%xmm5,%%xmm1 \n" - "pmulhuw %%xmm5,%%xmm2 \n" - "psllw $0x8,%%xmm1 \n" - "por %%xmm2,%%xmm1 \n" - "pand %%xmm4,%%xmm0 \n" - "pmulhuw %%xmm6,%%xmm0 \n" - "por %%xmm7,%%xmm0 \n" - "movdqa %%xmm1,%%xmm2 \n" - "punpcklbw %%xmm0,%%xmm1 \n" - "punpckhbw %%xmm0,%%xmm2 \n" - "movdqu %%xmm1,0x00(%1,%0,2) \n" - "movdqu %%xmm2,0x10(%1,%0,2) \n" - "lea 0x10(%0),%0 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : - : "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", - "xmm6", "xmm7"); -} - -void ARGB1555ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "mov $0x1080108,%%eax \n" - "movd %%eax,%%xmm5 \n" - "pshufd $0x0,%%xmm5,%%xmm5 \n" - "mov $0x42004200,%%eax \n" - "movd %%eax,%%xmm6 \n" - "pshufd $0x0,%%xmm6,%%xmm6 \n" - "pcmpeqb %%xmm3,%%xmm3 \n" - "psllw $0xb,%%xmm3 \n" - "movdqa %%xmm3,%%xmm4 \n" - "psrlw $0x6,%%xmm4 \n" - "pcmpeqb %%xmm7,%%xmm7 \n" - "psllw $0x8,%%xmm7 \n" - "sub %0,%1 \n" - "sub %0,%1 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "psllw $0x1,%%xmm1 \n" - "psllw $0xb,%%xmm2 \n" - "pand %%xmm3,%%xmm1 \n" - "pmulhuw %%xmm5,%%xmm2 \n" - "pmulhuw %%xmm5,%%xmm1 \n" - "psllw $0x8,%%xmm1 \n" - "por %%xmm2,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "pand %%xmm4,%%xmm0 \n" - "psraw $0x8,%%xmm2 \n" - "pmulhuw %%xmm6,%%xmm0 \n" - "pand %%xmm7,%%xmm2 \n" - "por %%xmm2,%%xmm0 \n" - "movdqa %%xmm1,%%xmm2 \n" - "punpcklbw %%xmm0,%%xmm1 \n" - "punpckhbw %%xmm0,%%xmm2 \n" - "movdqu %%xmm1,0x00(%1,%0,2) \n" - "movdqu %%xmm2,0x10(%1,%0,2) \n" - "lea 0x10(%0),%0 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : - : "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", - "xmm6", "xmm7"); -} - -void ARGB4444ToARGBRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "mov $0xf0f0f0f,%%eax \n" - "movd %%eax,%%xmm4 \n" - "pshufd $0x0,%%xmm4,%%xmm4 \n" - "movdqa %%xmm4,%%xmm5 \n" - "pslld $0x4,%%xmm5 \n" - "sub %0,%1 \n" - "sub %0,%1 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqa %%xmm0,%%xmm2 \n" - "pand %%xmm4,%%xmm0 \n" - "pand %%xmm5,%%xmm2 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm2,%%xmm3 \n" - "psllw $0x4,%%xmm1 \n" - "psrlw $0x4,%%xmm3 \n" - "por %%xmm1,%%xmm0 \n" - "por %%xmm3,%%xmm2 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklbw %%xmm2,%%xmm0 \n" - "punpckhbw %%xmm2,%%xmm1 \n" - "movdqu %%xmm0,0x00(%1,%0,2) \n" - "movdqu %%xmm1,0x10(%1,%0,2) \n" - "lea 0x10(%0),%0 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : - : "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} - -void ARGBToRGB24Row_SSSE3(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - - "movdqa %3,%%xmm6 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x30(%0),%%xmm3 \n" - "lea 0x40(%0),%0 \n" - "pshufb %%xmm6,%%xmm0 \n" - "pshufb %%xmm6,%%xmm1 \n" - "pshufb %%xmm6,%%xmm2 \n" - "pshufb %%xmm6,%%xmm3 \n" - "movdqa %%xmm1,%%xmm4 \n" - "psrldq $0x4,%%xmm1 \n" - "pslldq $0xc,%%xmm4 \n" - "movdqa %%xmm2,%%xmm5 \n" - "por %%xmm4,%%xmm0 \n" - "pslldq $0x8,%%xmm5 \n" - "movdqu %%xmm0,(%1) \n" - "por %%xmm5,%%xmm1 \n" - "psrldq $0x8,%%xmm2 \n" - "pslldq $0x4,%%xmm3 \n" - "por %%xmm3,%%xmm2 \n" - "movdqu %%xmm1,0x10(%1) \n" - "movdqu %%xmm2,0x20(%1) \n" - "lea 0x30(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "m"(kShuffleMaskARGBToRGB24) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); -} - -void ARGBToRAWRow_SSSE3(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - - "movdqa %3,%%xmm6 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x30(%0),%%xmm3 \n" - "lea 0x40(%0),%0 \n" - "pshufb %%xmm6,%%xmm0 \n" - "pshufb %%xmm6,%%xmm1 \n" - "pshufb %%xmm6,%%xmm2 \n" - "pshufb %%xmm6,%%xmm3 \n" - "movdqa %%xmm1,%%xmm4 \n" - "psrldq $0x4,%%xmm1 \n" - "pslldq $0xc,%%xmm4 \n" - "movdqa %%xmm2,%%xmm5 \n" - "por %%xmm4,%%xmm0 \n" - "pslldq $0x8,%%xmm5 \n" - "movdqu %%xmm0,(%1) \n" - "por %%xmm5,%%xmm1 \n" - "psrldq $0x8,%%xmm2 \n" - "pslldq $0x4,%%xmm3 \n" - "por %%xmm3,%%xmm2 \n" - "movdqu %%xmm1,0x10(%1) \n" - "movdqu %%xmm2,0x20(%1) \n" - "lea 0x30(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "m"(kShuffleMaskARGBToRAW) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); -} - -#ifdef HAS_ARGBTORGB24ROW_AVX2 -// vpermd for 12+12 to 24 -static const lvec32 kPermdRGB24_AVX = {0, 1, 2, 4, 5, 6, 3, 7}; - -void ARGBToRGB24Row_AVX2(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "vbroadcastf128 %3,%%ymm6 \n" - "vmovdqa %4,%%ymm7 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vmovdqu 0x40(%0),%%ymm2 \n" - "vmovdqu 0x60(%0),%%ymm3 \n" - "lea 0x80(%0),%0 \n" - "vpshufb %%ymm6,%%ymm0,%%ymm0 \n" // xxx0yyy0 - "vpshufb %%ymm6,%%ymm1,%%ymm1 \n" - "vpshufb %%ymm6,%%ymm2,%%ymm2 \n" - "vpshufb %%ymm6,%%ymm3,%%ymm3 \n" - "vpermd %%ymm0,%%ymm7,%%ymm0 \n" // pack to 24 bytes - "vpermd %%ymm1,%%ymm7,%%ymm1 \n" - "vpermd %%ymm2,%%ymm7,%%ymm2 \n" - "vpermd %%ymm3,%%ymm7,%%ymm3 \n" - "vpermq $0x3f,%%ymm1,%%ymm4 \n" // combine 24 + 8 - "vpor %%ymm4,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "vpermq $0xf9,%%ymm1,%%ymm1 \n" // combine 16 + 16 - "vpermq $0x4f,%%ymm2,%%ymm4 \n" - "vpor %%ymm4,%%ymm1,%%ymm1 \n" - "vmovdqu %%ymm1,0x20(%1) \n" - "vpermq $0xfe,%%ymm2,%%ymm2 \n" // combine 8 + 24 - "vpermq $0x93,%%ymm3,%%ymm3 \n" - "vpor %%ymm3,%%ymm2,%%ymm2 \n" - "vmovdqu %%ymm2,0x40(%1) \n" - "lea 0x60(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "m"(kShuffleMaskARGBToRGB24), // %3 - "m"(kPermdRGB24_AVX) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} -#endif - -#ifdef HAS_ARGBTORGB24ROW_AVX512VBMI -// Shuffle table for converting ARGBToRGB24 -static const ulvec8 kPermARGBToRGB24_0 = { - 0u, 1u, 2u, 4u, 5u, 6u, 8u, 9u, 10u, 12u, 13u, - 14u, 16u, 17u, 18u, 20u, 21u, 22u, 24u, 25u, 26u, 28u, - 29u, 30u, 32u, 33u, 34u, 36u, 37u, 38u, 40u, 41u}; -static const ulvec8 kPermARGBToRGB24_1 = { - 10u, 12u, 13u, 14u, 16u, 17u, 18u, 20u, 21u, 22u, 24u, - 25u, 26u, 28u, 29u, 30u, 32u, 33u, 34u, 36u, 37u, 38u, - 40u, 41u, 42u, 44u, 45u, 46u, 48u, 49u, 50u, 52u}; -static const ulvec8 kPermARGBToRGB24_2 = { - 21u, 22u, 24u, 25u, 26u, 28u, 29u, 30u, 32u, 33u, 34u, - 36u, 37u, 38u, 40u, 41u, 42u, 44u, 45u, 46u, 48u, 49u, - 50u, 52u, 53u, 54u, 56u, 57u, 58u, 60u, 61u, 62u}; - -void ARGBToRGB24Row_AVX512VBMI(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "vmovdqa %3,%%ymm5 \n" - "vmovdqa %4,%%ymm6 \n" - "vmovdqa %5,%%ymm7 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vmovdqu 0x40(%0),%%ymm2 \n" - "vmovdqu 0x60(%0),%%ymm3 \n" - "lea 0x80(%0),%0 \n" - "vpermt2b %%ymm1,%%ymm5,%%ymm0 \n" - "vpermt2b %%ymm2,%%ymm6,%%ymm1 \n" - "vpermt2b %%ymm3,%%ymm7,%%ymm2 \n" - "vmovdqu %%ymm0,(%1) \n" - "vmovdqu %%ymm1,0x20(%1) \n" - "vmovdqu %%ymm2,0x40(%1) \n" - "lea 0x60(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "m"(kPermARGBToRGB24_0), // %3 - "m"(kPermARGBToRGB24_1), // %4 - "m"(kPermARGBToRGB24_2) // %5 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5", "xmm6", "xmm7"); -} -#endif - -#ifdef HAS_ARGBTORAWROW_AVX2 -void ARGBToRAWRow_AVX2(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "vbroadcastf128 %3,%%ymm6 \n" - "vmovdqa %4,%%ymm7 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vmovdqu 0x40(%0),%%ymm2 \n" - "vmovdqu 0x60(%0),%%ymm3 \n" - "lea 0x80(%0),%0 \n" - "vpshufb %%ymm6,%%ymm0,%%ymm0 \n" // xxx0yyy0 - "vpshufb %%ymm6,%%ymm1,%%ymm1 \n" - "vpshufb %%ymm6,%%ymm2,%%ymm2 \n" - "vpshufb %%ymm6,%%ymm3,%%ymm3 \n" - "vpermd %%ymm0,%%ymm7,%%ymm0 \n" // pack to 24 bytes - "vpermd %%ymm1,%%ymm7,%%ymm1 \n" - "vpermd %%ymm2,%%ymm7,%%ymm2 \n" - "vpermd %%ymm3,%%ymm7,%%ymm3 \n" - "vpermq $0x3f,%%ymm1,%%ymm4 \n" // combine 24 + 8 - "vpor %%ymm4,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "vpermq $0xf9,%%ymm1,%%ymm1 \n" // combine 16 + 16 - "vpermq $0x4f,%%ymm2,%%ymm4 \n" - "vpor %%ymm4,%%ymm1,%%ymm1 \n" - "vmovdqu %%ymm1,0x20(%1) \n" - "vpermq $0xfe,%%ymm2,%%ymm2 \n" // combine 8 + 24 - "vpermq $0x93,%%ymm3,%%ymm3 \n" - "vpor %%ymm3,%%ymm2,%%ymm2 \n" - "vmovdqu %%ymm2,0x40(%1) \n" - "lea 0x60(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "m"(kShuffleMaskARGBToRAW), // %3 - "m"(kPermdRGB24_AVX) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} -#endif - -void ARGBToRGB565Row_SSE2(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "pcmpeqb %%xmm3,%%xmm3 \n" - "psrld $0x1b,%%xmm3 \n" - "pcmpeqb %%xmm4,%%xmm4 \n" - "psrld $0x1a,%%xmm4 \n" - "pslld $0x5,%%xmm4 \n" - "pcmpeqb %%xmm5,%%xmm5 \n" - "pslld $0xb,%%xmm5 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "pslld $0x8,%%xmm0 \n" - "psrld $0x3,%%xmm1 \n" - "psrld $0x5,%%xmm2 \n" - "psrad $0x10,%%xmm0 \n" - "pand %%xmm3,%%xmm1 \n" - "pand %%xmm4,%%xmm2 \n" - "pand %%xmm5,%%xmm0 \n" - "por %%xmm2,%%xmm1 \n" - "por %%xmm1,%%xmm0 \n" - "packssdw %%xmm0,%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "movq %%xmm0,(%1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - ::"memory", - "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} - -void ARGBToRGB565DitherRow_SSE2(const uint8_t* src, - uint8_t* dst, - const uint32_t dither4, - int width) { - asm volatile( - "movd %3,%%xmm6 \n" - "punpcklbw %%xmm6,%%xmm6 \n" - "movdqa %%xmm6,%%xmm7 \n" - "punpcklwd %%xmm6,%%xmm6 \n" - "punpckhwd %%xmm7,%%xmm7 \n" - "pcmpeqb %%xmm3,%%xmm3 \n" - "psrld $0x1b,%%xmm3 \n" - "pcmpeqb %%xmm4,%%xmm4 \n" - "psrld $0x1a,%%xmm4 \n" - "pslld $0x5,%%xmm4 \n" - "pcmpeqb %%xmm5,%%xmm5 \n" - "pslld $0xb,%%xmm5 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "paddusb %%xmm6,%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "pslld $0x8,%%xmm0 \n" - "psrld $0x3,%%xmm1 \n" - "psrld $0x5,%%xmm2 \n" - "psrad $0x10,%%xmm0 \n" - "pand %%xmm3,%%xmm1 \n" - "pand %%xmm4,%%xmm2 \n" - "pand %%xmm5,%%xmm0 \n" - "por %%xmm2,%%xmm1 \n" - "por %%xmm1,%%xmm0 \n" - "packssdw %%xmm0,%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "movq %%xmm0,(%1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "m"(dither4) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} - -#ifdef HAS_ARGBTORGB565DITHERROW_AVX2 -void ARGBToRGB565DitherRow_AVX2(const uint8_t* src, - uint8_t* dst, - const uint32_t dither4, - int width) { - asm volatile( - "vbroadcastss %3,%%xmm6 \n" - "vpunpcklbw %%xmm6,%%xmm6,%%xmm6 \n" - "vpermq $0xd8,%%ymm6,%%ymm6 \n" - "vpunpcklwd %%ymm6,%%ymm6,%%ymm6 \n" - "vpcmpeqb %%ymm3,%%ymm3,%%ymm3 \n" - "vpsrld $0x1b,%%ymm3,%%ymm3 \n" - "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" - "vpsrld $0x1a,%%ymm4,%%ymm4 \n" - "vpslld $0x5,%%ymm4,%%ymm4 \n" - "vpslld $0xb,%%ymm3,%%ymm5 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vpaddusb %%ymm6,%%ymm0,%%ymm0 \n" - "vpsrld $0x5,%%ymm0,%%ymm2 \n" - "vpsrld $0x3,%%ymm0,%%ymm1 \n" - "vpsrld $0x8,%%ymm0,%%ymm0 \n" - "vpand %%ymm4,%%ymm2,%%ymm2 \n" - "vpand %%ymm3,%%ymm1,%%ymm1 \n" - "vpand %%ymm5,%%ymm0,%%ymm0 \n" - "vpor %%ymm2,%%ymm1,%%ymm1 \n" - "vpor %%ymm1,%%ymm0,%%ymm0 \n" - "vpackusdw %%ymm0,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "lea 0x20(%0),%0 \n" - "vmovdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "m"(dither4) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} -#endif // HAS_ARGBTORGB565DITHERROW_AVX2 - -void ARGBToARGB1555Row_SSE2(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "pcmpeqb %%xmm4,%%xmm4 \n" - "psrld $0x1b,%%xmm4 \n" - "movdqa %%xmm4,%%xmm5 \n" - "pslld $0x5,%%xmm5 \n" - "movdqa %%xmm4,%%xmm6 \n" - "pslld $0xa,%%xmm6 \n" - "pcmpeqb %%xmm7,%%xmm7 \n" - "pslld $0xf,%%xmm7 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "movdqa %%xmm0,%%xmm3 \n" - "psrad $0x10,%%xmm0 \n" - "psrld $0x3,%%xmm1 \n" - "psrld $0x6,%%xmm2 \n" - "psrld $0x9,%%xmm3 \n" - "pand %%xmm7,%%xmm0 \n" - "pand %%xmm4,%%xmm1 \n" - "pand %%xmm5,%%xmm2 \n" - "pand %%xmm6,%%xmm3 \n" - "por %%xmm1,%%xmm0 \n" - "por %%xmm3,%%xmm2 \n" - "por %%xmm2,%%xmm0 \n" - "packssdw %%xmm0,%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "movq %%xmm0,(%1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - ::"memory", - "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"); -} - -void ARGBToARGB4444Row_SSE2(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "pcmpeqb %%xmm4,%%xmm4 \n" - "psllw $0xc,%%xmm4 \n" - "movdqa %%xmm4,%%xmm3 \n" - "psrlw $0x8,%%xmm3 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "pand %%xmm3,%%xmm0 \n" - "pand %%xmm4,%%xmm1 \n" - "psrlq $0x4,%%xmm0 \n" - "psrlq $0x8,%%xmm1 \n" - "por %%xmm1,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "movq %%xmm0,(%1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - ::"memory", - "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4"); -} -#endif // HAS_RGB24TOARGBROW_SSSE3 - -/* - -ARGBToAR30Row: - -Red Blue -With the 8 bit value in the upper bits of a short, vpmulhuw by (1024+4) will -produce a 10 bit value in the low 10 bits of each 16 bit value. This is whats -wanted for the blue channel. The red needs to be shifted 4 left, so multiply by -(1024+4)*16 for red. - -Alpha Green -Alpha and Green are already in the high bits so vpand can zero out the other -bits, keeping just 2 upper bits of alpha and 8 bit green. The same multiplier -could be used for Green - (1024+4) putting the 10 bit green in the lsb. Alpha -would be a simple multiplier to shift it into position. It wants a gap of 10 -above the green. Green is 10 bits, so there are 6 bits in the low short. 4 -more are needed, so a multiplier of 4 gets the 2 bits into the upper 16 bits, -and then a shift of 4 is a multiply of 16, so (4*16) = 64. Then shift the -result left 10 to position the A and G channels. -*/ - -// Shuffle table for converting RAW to RGB24. Last 8. -static const uvec8 kShuffleRB30 = {128u, 0u, 128u, 2u, 128u, 4u, 128u, 6u, - 128u, 8u, 128u, 10u, 128u, 12u, 128u, 14u}; - -static const uvec8 kShuffleBR30 = {128u, 2u, 128u, 0u, 128u, 6u, 128u, 4u, - 128u, 10u, 128u, 8u, 128u, 14u, 128u, 12u}; - -static const uint32_t kMulRB10 = 1028 * 16 * 65536 + 1028; -static const uint32_t kMaskRB10 = 0x3ff003ff; -static const uint32_t kMaskAG10 = 0xc000ff00; -static const uint32_t kMulAG10 = 64 * 65536 + 1028; - -void ARGBToAR30Row_SSSE3(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "movdqa %3,%%xmm2 \n" // shuffler for RB - "movd %4,%%xmm3 \n" // multipler for RB - "movd %5,%%xmm4 \n" // mask for R10 B10 - "movd %6,%%xmm5 \n" // mask for AG - "movd %7,%%xmm6 \n" // multipler for AG - "pshufd $0x0,%%xmm3,%%xmm3 \n" - "pshufd $0x0,%%xmm4,%%xmm4 \n" - "pshufd $0x0,%%xmm5,%%xmm5 \n" - "pshufd $0x0,%%xmm6,%%xmm6 \n" - "sub %0,%1 \n" - - "1: \n" - "movdqu (%0),%%xmm0 \n" // fetch 4 ARGB pixels - "movdqa %%xmm0,%%xmm1 \n" - "pshufb %%xmm2,%%xmm1 \n" // R0B0 - "pand %%xmm5,%%xmm0 \n" // A0G0 - "pmulhuw %%xmm3,%%xmm1 \n" // X2 R16 X4 B10 - "pmulhuw %%xmm6,%%xmm0 \n" // X10 A2 X10 G10 - "pand %%xmm4,%%xmm1 \n" // X2 R10 X10 B10 - "pslld $10,%%xmm0 \n" // A2 x10 G10 x10 - "por %%xmm1,%%xmm0 \n" // A2 R10 G10 B10 - "movdqu %%xmm0,(%1,%0) \n" // store 4 AR30 pixels - "add $0x10,%0 \n" - "sub $0x4,%2 \n" - "jg 1b \n" - - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "m"(kShuffleRB30), // %3 - "m"(kMulRB10), // %4 - "m"(kMaskRB10), // %5 - "m"(kMaskAG10), // %6 - "m"(kMulAG10) // %7 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); -} - -void ABGRToAR30Row_SSSE3(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "movdqa %3,%%xmm2 \n" // shuffler for RB - "movd %4,%%xmm3 \n" // multipler for RB - "movd %5,%%xmm4 \n" // mask for R10 B10 - "movd %6,%%xmm5 \n" // mask for AG - "movd %7,%%xmm6 \n" // multipler for AG - "pshufd $0x0,%%xmm3,%%xmm3 \n" - "pshufd $0x0,%%xmm4,%%xmm4 \n" - "pshufd $0x0,%%xmm5,%%xmm5 \n" - "pshufd $0x0,%%xmm6,%%xmm6 \n" - "sub %0,%1 \n" - - "1: \n" - "movdqu (%0),%%xmm0 \n" // fetch 4 ABGR pixels - "movdqa %%xmm0,%%xmm1 \n" - "pshufb %%xmm2,%%xmm1 \n" // R0B0 - "pand %%xmm5,%%xmm0 \n" // A0G0 - "pmulhuw %%xmm3,%%xmm1 \n" // X2 R16 X4 B10 - "pmulhuw %%xmm6,%%xmm0 \n" // X10 A2 X10 G10 - "pand %%xmm4,%%xmm1 \n" // X2 R10 X10 B10 - "pslld $10,%%xmm0 \n" // A2 x10 G10 x10 - "por %%xmm1,%%xmm0 \n" // A2 R10 G10 B10 - "movdqu %%xmm0,(%1,%0) \n" // store 4 AR30 pixels - "add $0x10,%0 \n" - "sub $0x4,%2 \n" - "jg 1b \n" - - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "m"(kShuffleBR30), // %3 reversed shuffler - "m"(kMulRB10), // %4 - "m"(kMaskRB10), // %5 - "m"(kMaskAG10), // %6 - "m"(kMulAG10) // %7 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); -} - -#ifdef HAS_ARGBTOAR30ROW_AVX2 -void ARGBToAR30Row_AVX2(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "vbroadcastf128 %3,%%ymm2 \n" // shuffler for RB - "vbroadcastss %4,%%ymm3 \n" // multipler for RB - "vbroadcastss %5,%%ymm4 \n" // mask for R10 B10 - "vbroadcastss %6,%%ymm5 \n" // mask for AG - "vbroadcastss %7,%%ymm6 \n" // multipler for AG - "sub %0,%1 \n" - - "1: \n" - "vmovdqu (%0),%%ymm0 \n" // fetch 8 ARGB pixels - "vpshufb %%ymm2,%%ymm0,%%ymm1 \n" // R0B0 - "vpand %%ymm5,%%ymm0,%%ymm0 \n" // A0G0 - "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" // X2 R16 X4 B10 - "vpmulhuw %%ymm6,%%ymm0,%%ymm0 \n" // X10 A2 X10 G10 - "vpand %%ymm4,%%ymm1,%%ymm1 \n" // X2 R10 X10 B10 - "vpslld $10,%%ymm0,%%ymm0 \n" // A2 x10 G10 x10 - "vpor %%ymm1,%%ymm0,%%ymm0 \n" // A2 R10 G10 B10 - "vmovdqu %%ymm0,(%1,%0) \n" // store 8 AR30 pixels - "add $0x20,%0 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - "vzeroupper \n" - - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "m"(kShuffleRB30), // %3 - "m"(kMulRB10), // %4 - "m"(kMaskRB10), // %5 - "m"(kMaskAG10), // %6 - "m"(kMulAG10) // %7 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); -} -#endif - -#ifdef HAS_ABGRTOAR30ROW_AVX2 -void ABGRToAR30Row_AVX2(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "vbroadcastf128 %3,%%ymm2 \n" // shuffler for RB - "vbroadcastss %4,%%ymm3 \n" // multipler for RB - "vbroadcastss %5,%%ymm4 \n" // mask for R10 B10 - "vbroadcastss %6,%%ymm5 \n" // mask for AG - "vbroadcastss %7,%%ymm6 \n" // multipler for AG - "sub %0,%1 \n" - - "1: \n" - "vmovdqu (%0),%%ymm0 \n" // fetch 8 ABGR pixels - "vpshufb %%ymm2,%%ymm0,%%ymm1 \n" // R0B0 - "vpand %%ymm5,%%ymm0,%%ymm0 \n" // A0G0 - "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" // X2 R16 X4 B10 - "vpmulhuw %%ymm6,%%ymm0,%%ymm0 \n" // X10 A2 X10 G10 - "vpand %%ymm4,%%ymm1,%%ymm1 \n" // X2 R10 X10 B10 - "vpslld $10,%%ymm0,%%ymm0 \n" // A2 x10 G10 x10 - "vpor %%ymm1,%%ymm0,%%ymm0 \n" // A2 R10 G10 B10 - "vmovdqu %%ymm0,(%1,%0) \n" // store 8 AR30 pixels - "add $0x20,%0 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - "vzeroupper \n" - - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "m"(kShuffleBR30), // %3 reversed shuffler - "m"(kMulRB10), // %4 - "m"(kMaskRB10), // %5 - "m"(kMaskAG10), // %6 - "m"(kMulAG10) // %7 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); -} -#endif - -#ifdef HAS_ARGBTOYROW_SSSE3 -// Convert 16 ARGB pixels (64 bytes) to 16 Y values. -void ARGBToYRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_y, int width) { - asm volatile( - "movdqa %3,%%xmm4 \n" - "movdqa %4,%%xmm5 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x30(%0),%%xmm3 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm4,%%xmm3 \n" - "lea 0x40(%0),%0 \n" - "phaddw %%xmm1,%%xmm0 \n" - "phaddw %%xmm3,%%xmm2 \n" - "psrlw $0x7,%%xmm0 \n" - "psrlw $0x7,%%xmm2 \n" - "packuswb %%xmm2,%%xmm0 \n" - "paddb %%xmm5,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : "m"(kARGBToY), // %3 - "m"(kAddY16) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} -#endif // HAS_ARGBTOYROW_SSSE3 - -#ifdef HAS_ARGBTOYJROW_SSSE3 -// Convert 16 ARGB pixels (64 bytes) to 16 YJ values. -// Same as ARGBToYRow but different coefficients, no add 16, but do rounding. -void ARGBToYJRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_y, int width) { - asm volatile( - "movdqa %3,%%xmm4 \n" - "movdqa %4,%%xmm5 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x30(%0),%%xmm3 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm4,%%xmm3 \n" - "lea 0x40(%0),%0 \n" - "phaddw %%xmm1,%%xmm0 \n" - "phaddw %%xmm3,%%xmm2 \n" - "paddw %%xmm5,%%xmm0 \n" - "paddw %%xmm5,%%xmm2 \n" - "psrlw $0x7,%%xmm0 \n" - "psrlw $0x7,%%xmm2 \n" - "packuswb %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : "m"(kARGBToYJ), // %3 - "m"(kAddYJ64) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} -#endif // HAS_ARGBTOYJROW_SSSE3 - -#ifdef HAS_ARGBTOYROW_AVX2 -// vpermd for vphaddw + vpackuswb vpermd. -static const lvec32 kPermdARGBToY_AVX = {0, 4, 1, 5, 2, 6, 3, 7}; - -// Convert 32 ARGB pixels (128 bytes) to 32 Y values. -void ARGBToYRow_AVX2(const uint8_t* src_argb, uint8_t* dst_y, int width) { - asm volatile( - "vbroadcastf128 %3,%%ymm4 \n" - "vbroadcastf128 %4,%%ymm5 \n" - "vmovdqu %5,%%ymm6 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vmovdqu 0x40(%0),%%ymm2 \n" - "vmovdqu 0x60(%0),%%ymm3 \n" - "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" - "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" - "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" - "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" - "lea 0x80(%0),%0 \n" - "vphaddw %%ymm1,%%ymm0,%%ymm0 \n" // mutates. - "vphaddw %%ymm3,%%ymm2,%%ymm2 \n" - "vpsrlw $0x7,%%ymm0,%%ymm0 \n" - "vpsrlw $0x7,%%ymm2,%%ymm2 \n" - "vpackuswb %%ymm2,%%ymm0,%%ymm0 \n" // mutates. - "vpermd %%ymm0,%%ymm6,%%ymm0 \n" // unmutate. - "vpaddb %%ymm5,%%ymm0,%%ymm0 \n" // add 16 for Y - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_argb), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : "m"(kARGBToY), // %3 - "m"(kAddY16), // %4 - "m"(kPermdARGBToY_AVX) // %5 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); -} -#endif // HAS_ARGBTOYROW_AVX2 - -#ifdef HAS_ARGBTOYJROW_AVX2 -// Convert 32 ARGB pixels (128 bytes) to 32 Y values. -void ARGBToYJRow_AVX2(const uint8_t* src_argb, uint8_t* dst_y, int width) { - asm volatile( - "vbroadcastf128 %3,%%ymm4 \n" - "vbroadcastf128 %4,%%ymm5 \n" - "vmovdqu %5,%%ymm6 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vmovdqu 0x40(%0),%%ymm2 \n" - "vmovdqu 0x60(%0),%%ymm3 \n" - "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" - "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" - "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" - "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" - "lea 0x80(%0),%0 \n" - "vphaddw %%ymm1,%%ymm0,%%ymm0 \n" // mutates. - "vphaddw %%ymm3,%%ymm2,%%ymm2 \n" - "vpaddw %%ymm5,%%ymm0,%%ymm0 \n" // Add .5 for rounding. - "vpaddw %%ymm5,%%ymm2,%%ymm2 \n" - "vpsrlw $0x7,%%ymm0,%%ymm0 \n" - "vpsrlw $0x7,%%ymm2,%%ymm2 \n" - "vpackuswb %%ymm2,%%ymm0,%%ymm0 \n" // mutates. - "vpermd %%ymm0,%%ymm6,%%ymm0 \n" // unmutate. - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_argb), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : "m"(kARGBToYJ), // %3 - "m"(kAddYJ64), // %4 - "m"(kPermdARGBToY_AVX) // %5 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); -} -#endif // HAS_ARGBTOYJROW_AVX2 - -#ifdef HAS_ARGBTOUVROW_SSSE3 -void ARGBToUVRow_SSSE3(const uint8_t* src_argb0, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "movdqa %5,%%xmm3 \n" - "movdqa %6,%%xmm4 \n" - "movdqa %7,%%xmm5 \n" - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x10(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x20(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm2 \n" - "movdqu 0x30(%0),%%xmm6 \n" - "movdqu 0x30(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" - - "lea 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,(%1) \n" - "movhps %%xmm0,0x00(%1,%2,1) \n" - "lea 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 - : "r"((intptr_t)(src_stride_argb)), // %4 - "m"(kARGBToV), // %5 - "m"(kARGBToU), // %6 - "m"(kAddUV128) // %7 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm6", "xmm7"); -} -#endif // HAS_ARGBTOUVROW_SSSE3 - -#ifdef HAS_ARGBTOUVROW_AVX2 -// vpshufb for vphaddw + vpackuswb packed to shorts. -static const lvec8 kShufARGBToUV_AVX = { - 0, 1, 8, 9, 2, 3, 10, 11, 4, 5, 12, 13, 6, 7, 14, 15, - 0, 1, 8, 9, 2, 3, 10, 11, 4, 5, 12, 13, 6, 7, 14, 15}; -void ARGBToUVRow_AVX2(const uint8_t* src_argb0, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* 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 (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vmovdqu 0x40(%0),%%ymm2 \n" - "vmovdqu 0x60(%0),%%ymm3 \n" - "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" - "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" - "vpavgb 0x40(%0,%4,1),%%ymm2,%%ymm2 \n" - "vpavgb 0x60(%0,%4,1),%%ymm3,%%ymm3 \n" - "lea 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" - "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" - "vpaddb %%ymm5,%%ymm0,%%ymm0 \n" - - "vextractf128 $0x0,%%ymm0,(%1) \n" - "vextractf128 $0x1,%%ymm0,0x0(%1,%2,1) \n" - "lea 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"(kAddUV128), // %5 - "m"(kARGBToV), // %6 - "m"(kARGBToU), // %7 - "m"(kShufARGBToUV_AVX) // %8 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} -#endif // HAS_ARGBTOUVROW_AVX2 - -#ifdef HAS_ARGBTOUVJROW_AVX2 -void ARGBToUVJRow_AVX2(const uint8_t* src_argb0, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* 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 (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vmovdqu 0x40(%0),%%ymm2 \n" - "vmovdqu 0x60(%0),%%ymm3 \n" - "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" - "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" - "vpavgb 0x40(%0,%4,1),%%ymm2,%%ymm2 \n" - "vpavgb 0x60(%0,%4,1),%%ymm3,%%ymm3 \n" - "lea 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,(%1) \n" - "vextractf128 $0x1,%%ymm0,0x0(%1,%2,1) \n" - "lea 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", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} -#endif // HAS_ARGBTOUVJROW_AVX2 - -#ifdef HAS_ARGBTOUVJROW_SSSE3 -void ARGBToUVJRow_SSSE3(const uint8_t* src_argb0, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "movdqa %5,%%xmm3 \n" - "movdqa %6,%%xmm4 \n" - "movdqa %7,%%xmm5 \n" - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x10(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x20(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm2 \n" - "movdqu 0x30(%0),%%xmm6 \n" - "movdqu 0x30(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" - - "lea 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" - "paddw %%xmm5,%%xmm0 \n" - "paddw %%xmm5,%%xmm1 \n" - "psraw $0x8,%%xmm0 \n" - "psraw $0x8,%%xmm1 \n" - "packsswb %%xmm1,%%xmm0 \n" - "movlps %%xmm0,(%1) \n" - "movhps %%xmm0,0x00(%1,%2,1) \n" - "lea 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 - : "r"((intptr_t)(src_stride_argb)), // %4 - "m"(kARGBToVJ), // %5 - "m"(kARGBToUJ), // %6 - "m"(kAddUVJ128) // %7 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm6", "xmm7"); -} -#endif // HAS_ARGBTOUVJROW_SSSE3 - -#ifdef HAS_ARGBTOUV444ROW_SSSE3 -void ARGBToUV444Row_SSSE3(const uint8_t* src_argb, - uint8_t* dst_u, - uint8_t* 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 (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x30(%0),%%xmm6 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm4,%%xmm6 \n" - "phaddw %%xmm1,%%xmm0 \n" - "phaddw %%xmm6,%%xmm2 \n" - "psraw $0x8,%%xmm0 \n" - "psraw $0x8,%%xmm2 \n" - "packsswb %%xmm2,%%xmm0 \n" - "paddb %%xmm5,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x30(%0),%%xmm6 \n" - "pmaddubsw %%xmm3,%%xmm0 \n" - "pmaddubsw %%xmm3,%%xmm1 \n" - "pmaddubsw %%xmm3,%%xmm2 \n" - "pmaddubsw %%xmm3,%%xmm6 \n" - "phaddw %%xmm1,%%xmm0 \n" - "phaddw %%xmm6,%%xmm2 \n" - "psraw $0x8,%%xmm0 \n" - "psraw $0x8,%%xmm2 \n" - "packsswb %%xmm2,%%xmm0 \n" - "paddb %%xmm5,%%xmm0 \n" - "lea 0x40(%0),%0 \n" - "movdqu %%xmm0,0x00(%1,%2,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+rm"(width) // %3 - : "m"(kARGBToV), // %4 - "m"(kARGBToU), // %5 - "m"(kAddUV128) // %6 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm6"); -} -#endif // HAS_ARGBTOUV444ROW_SSSE3 - -void BGRAToYRow_SSSE3(const uint8_t* src_bgra, uint8_t* dst_y, int width) { - asm volatile( - "movdqa %4,%%xmm5 \n" - "movdqa %3,%%xmm4 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x30(%0),%%xmm3 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm4,%%xmm3 \n" - "lea 0x40(%0),%0 \n" - "phaddw %%xmm1,%%xmm0 \n" - "phaddw %%xmm3,%%xmm2 \n" - "psrlw $0x7,%%xmm0 \n" - "psrlw $0x7,%%xmm2 \n" - "packuswb %%xmm2,%%xmm0 \n" - "paddb %%xmm5,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src_bgra), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : "m"(kBGRAToY), // %3 - "m"(kAddY16) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} - -void BGRAToUVRow_SSSE3(const uint8_t* src_bgra0, - int src_stride_bgra, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "movdqa %5,%%xmm3 \n" - "movdqa %6,%%xmm4 \n" - "movdqa %7,%%xmm5 \n" - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x10(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x20(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm2 \n" - "movdqu 0x30(%0),%%xmm6 \n" - "movdqu 0x30(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" - - "lea 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,(%1) \n" - "movhps %%xmm0,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" - : "+r"(src_bgra0), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+rm"(width) // %3 - : "r"((intptr_t)(src_stride_bgra)), // %4 - "m"(kBGRAToV), // %5 - "m"(kBGRAToU), // %6 - "m"(kAddUV128) // %7 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm6", "xmm7"); -} - -void ABGRToYRow_SSSE3(const uint8_t* src_abgr, uint8_t* dst_y, int width) { - asm volatile( - "movdqa %4,%%xmm5 \n" - "movdqa %3,%%xmm4 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x30(%0),%%xmm3 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm4,%%xmm3 \n" - "lea 0x40(%0),%0 \n" - "phaddw %%xmm1,%%xmm0 \n" - "phaddw %%xmm3,%%xmm2 \n" - "psrlw $0x7,%%xmm0 \n" - "psrlw $0x7,%%xmm2 \n" - "packuswb %%xmm2,%%xmm0 \n" - "paddb %%xmm5,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src_abgr), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : "m"(kABGRToY), // %3 - "m"(kAddY16) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} - -void RGBAToYRow_SSSE3(const uint8_t* src_rgba, uint8_t* dst_y, int width) { - asm volatile( - "movdqa %4,%%xmm5 \n" - "movdqa %3,%%xmm4 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x30(%0),%%xmm3 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm4,%%xmm3 \n" - "lea 0x40(%0),%0 \n" - "phaddw %%xmm1,%%xmm0 \n" - "phaddw %%xmm3,%%xmm2 \n" - "psrlw $0x7,%%xmm0 \n" - "psrlw $0x7,%%xmm2 \n" - "packuswb %%xmm2,%%xmm0 \n" - "paddb %%xmm5,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src_rgba), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : "m"(kRGBAToY), // %3 - "m"(kAddY16) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} - -void ABGRToUVRow_SSSE3(const uint8_t* src_abgr0, - int src_stride_abgr, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "movdqa %5,%%xmm3 \n" - "movdqa %6,%%xmm4 \n" - "movdqa %7,%%xmm5 \n" - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x10(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x20(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm2 \n" - "movdqu 0x30(%0),%%xmm6 \n" - "movdqu 0x30(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" - - "lea 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,(%1) \n" - "movhps %%xmm0,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" - : "+r"(src_abgr0), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+rm"(width) // %3 - : "r"((intptr_t)(src_stride_abgr)), // %4 - "m"(kABGRToV), // %5 - "m"(kABGRToU), // %6 - "m"(kAddUV128) // %7 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm6", "xmm7"); -} - -void RGBAToUVRow_SSSE3(const uint8_t* src_rgba0, - int src_stride_rgba, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "movdqa %5,%%xmm3 \n" - "movdqa %6,%%xmm4 \n" - "movdqa %7,%%xmm5 \n" - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x10(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x20(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm2 \n" - "movdqu 0x30(%0),%%xmm6 \n" - "movdqu 0x30(%0,%4,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" - - "lea 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,(%1) \n" - "movhps %%xmm0,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" - : "+r"(src_rgba0), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+rm"(width) // %3 - : "r"((intptr_t)(src_stride_rgba)), // %4 - "m"(kRGBAToV), // %5 - "m"(kRGBAToU), // %6 - "m"(kAddUV128) // %7 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm6", "xmm7"); -} - -#if defined(HAS_I422TOARGBROW_SSSE3) || defined(HAS_I422TOARGBROW_AVX2) - -// Read 8 UV from 444 -#define READYUV444 \ - "movq (%[u_buf]),%%xmm0 \n" \ - "movq 0x00(%[u_buf],%[v_buf],1),%%xmm1 \n" \ - "lea 0x8(%[u_buf]),%[u_buf] \n" \ - "punpcklbw %%xmm1,%%xmm0 \n" \ - "movq (%[y_buf]),%%xmm4 \n" \ - "punpcklbw %%xmm4,%%xmm4 \n" \ - "lea 0x8(%[y_buf]),%[y_buf] \n" - -// Read 4 UV from 422, upsample to 8 UV -#define READYUV422 \ - "movd (%[u_buf]),%%xmm0 \n" \ - "movd 0x00(%[u_buf],%[v_buf],1),%%xmm1 \n" \ - "lea 0x4(%[u_buf]),%[u_buf] \n" \ - "punpcklbw %%xmm1,%%xmm0 \n" \ - "punpcklwd %%xmm0,%%xmm0 \n" \ - "movq (%[y_buf]),%%xmm4 \n" \ - "punpcklbw %%xmm4,%%xmm4 \n" \ - "lea 0x8(%[y_buf]),%[y_buf] \n" - -// Read 4 UV from 422 10 bit, upsample to 8 UV -// TODO(fbarchard): Consider shufb to replace pack/unpack -// TODO(fbarchard): Consider pmulhuw to replace psraw -// TODO(fbarchard): Consider pmullw to replace psllw and allow different bits. -#define READYUV210 \ - "movq (%[u_buf]),%%xmm0 \n" \ - "movq 0x00(%[u_buf],%[v_buf],1),%%xmm1 \n" \ - "lea 0x8(%[u_buf]),%[u_buf] \n" \ - "punpcklwd %%xmm1,%%xmm0 \n" \ - "psraw $0x2,%%xmm0 \n" \ - "packuswb %%xmm0,%%xmm0 \n" \ - "punpcklwd %%xmm0,%%xmm0 \n" \ - "movdqu (%[y_buf]),%%xmm4 \n" \ - "psllw $0x6,%%xmm4 \n" \ - "lea 0x10(%[y_buf]),%[y_buf] \n" - -// Read 4 UV from 422, upsample to 8 UV. With 8 Alpha. -#define READYUVA422 \ - "movd (%[u_buf]),%%xmm0 \n" \ - "movd 0x00(%[u_buf],%[v_buf],1),%%xmm1 \n" \ - "lea 0x4(%[u_buf]),%[u_buf] \n" \ - "punpcklbw %%xmm1,%%xmm0 \n" \ - "punpcklwd %%xmm0,%%xmm0 \n" \ - "movq (%[y_buf]),%%xmm4 \n" \ - "punpcklbw %%xmm4,%%xmm4 \n" \ - "lea 0x8(%[y_buf]),%[y_buf] \n" \ - "movq (%[a_buf]),%%xmm5 \n" \ - "lea 0x8(%[a_buf]),%[a_buf] \n" - -// Read 4 UV from NV12, upsample to 8 UV -#define READNV12 \ - "movq (%[uv_buf]),%%xmm0 \n" \ - "lea 0x8(%[uv_buf]),%[uv_buf] \n" \ - "punpcklwd %%xmm0,%%xmm0 \n" \ - "movq (%[y_buf]),%%xmm4 \n" \ - "punpcklbw %%xmm4,%%xmm4 \n" \ - "lea 0x8(%[y_buf]),%[y_buf] \n" - -// Read 4 VU from NV21, upsample to 8 UV -#define READNV21 \ - "movq (%[vu_buf]),%%xmm0 \n" \ - "lea 0x8(%[vu_buf]),%[vu_buf] \n" \ - "pshufb %[kShuffleNV21], %%xmm0 \n" \ - "movq (%[y_buf]),%%xmm4 \n" \ - "punpcklbw %%xmm4,%%xmm4 \n" \ - "lea 0x8(%[y_buf]),%[y_buf] \n" - -// Read 4 YUY2 with 8 Y and update 4 UV to 8 UV. -#define READYUY2 \ - "movdqu (%[yuy2_buf]),%%xmm4 \n" \ - "pshufb %[kShuffleYUY2Y], %%xmm4 \n" \ - "movdqu (%[yuy2_buf]),%%xmm0 \n" \ - "pshufb %[kShuffleYUY2UV], %%xmm0 \n" \ - "lea 0x10(%[yuy2_buf]),%[yuy2_buf] \n" - -// Read 4 UYVY with 8 Y and update 4 UV to 8 UV. -#define READUYVY \ - "movdqu (%[uyvy_buf]),%%xmm4 \n" \ - "pshufb %[kShuffleUYVYY], %%xmm4 \n" \ - "movdqu (%[uyvy_buf]),%%xmm0 \n" \ - "pshufb %[kShuffleUYVYUV], %%xmm0 \n" \ - "lea 0x10(%[uyvy_buf]),%[uyvy_buf] \n" - -#if defined(__x86_64__) -#define YUVTORGB_SETUP(yuvconstants) \ - "movdqa (%[yuvconstants]),%%xmm8 \n" \ - "movdqa 32(%[yuvconstants]),%%xmm9 \n" \ - "movdqa 64(%[yuvconstants]),%%xmm10 \n" \ - "movdqa 96(%[yuvconstants]),%%xmm11 \n" \ - "movdqa 128(%[yuvconstants]),%%xmm12 \n" \ - "movdqa 160(%[yuvconstants]),%%xmm13 \n" \ - "movdqa 192(%[yuvconstants]),%%xmm14 \n" -// Convert 8 pixels: 8 UV and 8 Y -#define YUVTORGB16(yuvconstants) \ - "movdqa %%xmm0,%%xmm1 \n" \ - "movdqa %%xmm0,%%xmm2 \n" \ - "movdqa %%xmm0,%%xmm3 \n" \ - "movdqa %%xmm11,%%xmm0 \n" \ - "pmaddubsw %%xmm8,%%xmm1 \n" \ - "psubw %%xmm1,%%xmm0 \n" \ - "movdqa %%xmm12,%%xmm1 \n" \ - "pmaddubsw %%xmm9,%%xmm2 \n" \ - "psubw %%xmm2,%%xmm1 \n" \ - "movdqa %%xmm13,%%xmm2 \n" \ - "pmaddubsw %%xmm10,%%xmm3 \n" \ - "psubw %%xmm3,%%xmm2 \n" \ - "pmulhuw %%xmm14,%%xmm4 \n" \ - "paddsw %%xmm4,%%xmm0 \n" \ - "paddsw %%xmm4,%%xmm1 \n" \ - "paddsw %%xmm4,%%xmm2 \n" -#define YUVTORGB_REGS \ - "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", - -#else -#define YUVTORGB_SETUP(yuvconstants) -// Convert 8 pixels: 8 UV and 8 Y -#define YUVTORGB16(yuvconstants) \ - "movdqa %%xmm0,%%xmm1 \n" \ - "movdqa %%xmm0,%%xmm2 \n" \ - "movdqa %%xmm0,%%xmm3 \n" \ - "movdqa 96(%[yuvconstants]),%%xmm0 \n" \ - "pmaddubsw (%[yuvconstants]),%%xmm1 \n" \ - "psubw %%xmm1,%%xmm0 \n" \ - "movdqa 128(%[yuvconstants]),%%xmm1 \n" \ - "pmaddubsw 32(%[yuvconstants]),%%xmm2 \n" \ - "psubw %%xmm2,%%xmm1 \n" \ - "movdqa 160(%[yuvconstants]),%%xmm2 \n" \ - "pmaddubsw 64(%[yuvconstants]),%%xmm3 \n" \ - "psubw %%xmm3,%%xmm2 \n" \ - "pmulhuw 192(%[yuvconstants]),%%xmm4 \n" \ - "paddsw %%xmm4,%%xmm0 \n" \ - "paddsw %%xmm4,%%xmm1 \n" \ - "paddsw %%xmm4,%%xmm2 \n" -#define YUVTORGB_REGS -#endif - -#define YUVTORGB(yuvconstants) \ - YUVTORGB16(yuvconstants) \ - "psraw $0x6,%%xmm0 \n" \ - "psraw $0x6,%%xmm1 \n" \ - "psraw $0x6,%%xmm2 \n" \ - "packuswb %%xmm0,%%xmm0 \n" \ - "packuswb %%xmm1,%%xmm1 \n" \ - "packuswb %%xmm2,%%xmm2 \n" - -// Store 8 ARGB values. -#define STOREARGB \ - "punpcklbw %%xmm1,%%xmm0 \n" \ - "punpcklbw %%xmm5,%%xmm2 \n" \ - "movdqa %%xmm0,%%xmm1 \n" \ - "punpcklwd %%xmm2,%%xmm0 \n" \ - "punpckhwd %%xmm2,%%xmm1 \n" \ - "movdqu %%xmm0,(%[dst_argb]) \n" \ - "movdqu %%xmm1,0x10(%[dst_argb]) \n" \ - "lea 0x20(%[dst_argb]), %[dst_argb] \n" - -// Store 8 RGBA values. -#define STORERGBA \ - "pcmpeqb %%xmm5,%%xmm5 \n" \ - "punpcklbw %%xmm2,%%xmm1 \n" \ - "punpcklbw %%xmm0,%%xmm5 \n" \ - "movdqa %%xmm5,%%xmm0 \n" \ - "punpcklwd %%xmm1,%%xmm5 \n" \ - "punpckhwd %%xmm1,%%xmm0 \n" \ - "movdqu %%xmm5,(%[dst_rgba]) \n" \ - "movdqu %%xmm0,0x10(%[dst_rgba]) \n" \ - "lea 0x20(%[dst_rgba]),%[dst_rgba] \n" - -// Store 8 AR30 values. -#define STOREAR30 \ - "psraw $0x4,%%xmm0 \n" \ - "psraw $0x4,%%xmm1 \n" \ - "psraw $0x4,%%xmm2 \n" \ - "pminsw %%xmm7,%%xmm0 \n" \ - "pminsw %%xmm7,%%xmm1 \n" \ - "pminsw %%xmm7,%%xmm2 \n" \ - "pmaxsw %%xmm6,%%xmm0 \n" \ - "pmaxsw %%xmm6,%%xmm1 \n" \ - "pmaxsw %%xmm6,%%xmm2 \n" \ - "psllw $0x4,%%xmm2 \n" \ - "movdqa %%xmm0,%%xmm3 \n" \ - "punpcklwd %%xmm2,%%xmm0 \n" \ - "punpckhwd %%xmm2,%%xmm3 \n" \ - "movdqa %%xmm1,%%xmm2 \n" \ - "punpcklwd %%xmm5,%%xmm1 \n" \ - "punpckhwd %%xmm5,%%xmm2 \n" \ - "pslld $0xa,%%xmm1 \n" \ - "pslld $0xa,%%xmm2 \n" \ - "por %%xmm1,%%xmm0 \n" \ - "por %%xmm2,%%xmm3 \n" \ - "movdqu %%xmm0,(%[dst_ar30]) \n" \ - "movdqu %%xmm3,0x10(%[dst_ar30]) \n" \ - "lea 0x20(%[dst_ar30]), %[dst_ar30] \n" - -void OMITFP I444ToARGBRow_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "pcmpeqb %%xmm5,%%xmm5 \n" - - LABELALIGN - "1: \n" - READYUV444 - YUVTORGB(yuvconstants) - STOREARGB - "sub $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] - [dst_argb]"+r"(dst_argb), // %[dst_argb] - [width]"+rm"(width) // %[width] - : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] - : "memory", "cc", YUVTORGB_REGS - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); -} - -void OMITFP I422ToRGB24Row_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP(yuvconstants) - "movdqa %[kShuffleMaskARGBToRGB24_0],%%xmm5 \n" - "movdqa %[kShuffleMaskARGBToRGB24],%%xmm6 \n" - "sub %[u_buf],%[v_buf] \n" - - LABELALIGN - "1: \n" - READYUV422 - YUVTORGB(yuvconstants) - "punpcklbw %%xmm1,%%xmm0 \n" - "punpcklbw %%xmm2,%%xmm2 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklwd %%xmm2,%%xmm0 \n" - "punpckhwd %%xmm2,%%xmm1 \n" - "pshufb %%xmm5,%%xmm0 \n" - "pshufb %%xmm6,%%xmm1 \n" - "palignr $0xc,%%xmm0,%%xmm1 \n" - "movq %%xmm0,(%[dst_rgb24]) \n" - "movdqu %%xmm1,0x8(%[dst_rgb24]) \n" - "lea 0x18(%[dst_rgb24]),%[dst_rgb24] \n" - "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] - [dst_rgb24]"+r"(dst_rgb24), // %[dst_rgb24] -#if defined(__i386__) - [width]"+m"(width) // %[width] -#else - [width]"+rm"(width) // %[width] -#endif - : [yuvconstants]"r"(yuvconstants), // %[yuvconstants] - [kShuffleMaskARGBToRGB24_0]"m"(kShuffleMaskARGBToRGB24_0), - [kShuffleMaskARGBToRGB24]"m"(kShuffleMaskARGBToRGB24) - : "memory", "cc", YUVTORGB_REGS - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6" - ); -} - -void OMITFP I422ToARGBRow_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "pcmpeqb %%xmm5,%%xmm5 \n" - - LABELALIGN - "1: \n" - READYUV422 - YUVTORGB(yuvconstants) - STOREARGB - "sub $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] - [dst_argb]"+r"(dst_argb), // %[dst_argb] - [width]"+rm"(width) // %[width] - : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] - : "memory", "cc", YUVTORGB_REGS - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); -} - -void OMITFP I422ToAR30Row_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ar30, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "pcmpeqb %%xmm5,%%xmm5 \n" // AR30 constants - "psrlw $14,%%xmm5 \n" - "psllw $4,%%xmm5 \n" // 2 alpha bits - "pxor %%xmm6,%%xmm6 \n" - "pcmpeqb %%xmm7,%%xmm7 \n" // 0 for min - "psrlw $6,%%xmm7 \n" // 1023 for max - - LABELALIGN - "1: \n" - READYUV422 - YUVTORGB16(yuvconstants) - STOREAR30 - "sub $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] - [dst_ar30]"+r"(dst_ar30), // %[dst_ar30] - [width]"+rm"(width) // %[width] - : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] - : "memory", "cc", YUVTORGB_REGS - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" - ); -} - -// 10 bit YUV to ARGB -void OMITFP I210ToARGBRow_SSSE3(const uint16_t* y_buf, - const uint16_t* u_buf, - const uint16_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "pcmpeqb %%xmm5,%%xmm5 \n" - - LABELALIGN - "1: \n" - READYUV210 - YUVTORGB(yuvconstants) - STOREARGB - "sub $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] - [dst_argb]"+r"(dst_argb), // %[dst_argb] - [width]"+rm"(width) // %[width] - : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] - : "memory", "cc", YUVTORGB_REGS - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); -} - -// 10 bit YUV to AR30 -void OMITFP I210ToAR30Row_SSSE3(const uint16_t* y_buf, - const uint16_t* u_buf, - const uint16_t* v_buf, - uint8_t* dst_ar30, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "pcmpeqb %%xmm5,%%xmm5 \n" - "psrlw $14,%%xmm5 \n" - "psllw $4,%%xmm5 \n" // 2 alpha bits - "pxor %%xmm6,%%xmm6 \n" - "pcmpeqb %%xmm7,%%xmm7 \n" // 0 for min - "psrlw $6,%%xmm7 \n" // 1023 for max - - LABELALIGN - "1: \n" - READYUV210 - YUVTORGB16(yuvconstants) - STOREAR30 - "sub $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] - [dst_ar30]"+r"(dst_ar30), // %[dst_ar30] - [width]"+rm"(width) // %[width] - : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] - : "memory", "cc", YUVTORGB_REGS - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" - ); -} - -#ifdef HAS_I422ALPHATOARGBROW_SSSE3 -void OMITFP I422AlphaToARGBRow_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - const uint8_t* a_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - // clang-format off - asm volatile ( - YUVTORGB_SETUP(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - - LABELALIGN - "1: \n" - READYUVA422 - YUVTORGB(yuvconstants) - 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] - [a_buf]"+r"(a_buf), // %[a_buf] - [dst_argb]"+r"(dst_argb), // %[dst_argb] -#if defined(__i386__) - [width]"+m"(width) // %[width] -#else - [width]"+rm"(width) // %[width] -#endif - : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] - : "memory", "cc", YUVTORGB_REGS - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); - // clang-format on -} -#endif // HAS_I422ALPHATOARGBROW_SSSE3 - -void OMITFP NV12ToARGBRow_SSSE3(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - // clang-format off - asm volatile ( - YUVTORGB_SETUP(yuvconstants) - "pcmpeqb %%xmm5,%%xmm5 \n" - - LABELALIGN - "1: \n" - READNV12 - YUVTORGB(yuvconstants) - STOREARGB - "sub $0x8,%[width] \n" - "jg 1b \n" - : [y_buf]"+r"(y_buf), // %[y_buf] - [uv_buf]"+r"(uv_buf), // %[uv_buf] - [dst_argb]"+r"(dst_argb), // %[dst_argb] - [width]"+rm"(width) // %[width] - : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] - : "memory", "cc", YUVTORGB_REGS - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); - // clang-format on -} - -void OMITFP NV21ToARGBRow_SSSE3(const uint8_t* y_buf, - const uint8_t* vu_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - // clang-format off - asm volatile ( - YUVTORGB_SETUP(yuvconstants) - "pcmpeqb %%xmm5,%%xmm5 \n" - - LABELALIGN - "1: \n" - READNV21 - YUVTORGB(yuvconstants) - STOREARGB - "sub $0x8,%[width] \n" - "jg 1b \n" - : [y_buf]"+r"(y_buf), // %[y_buf] - [vu_buf]"+r"(vu_buf), // %[vu_buf] - [dst_argb]"+r"(dst_argb), // %[dst_argb] - [width]"+rm"(width) // %[width] - : [yuvconstants]"r"(yuvconstants), // %[yuvconstants] - [kShuffleNV21]"m"(kShuffleNV21) - : "memory", "cc", YUVTORGB_REGS - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); - // clang-format on -} - -void OMITFP YUY2ToARGBRow_SSSE3(const uint8_t* yuy2_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - // clang-format off - asm volatile ( - YUVTORGB_SETUP(yuvconstants) - "pcmpeqb %%xmm5,%%xmm5 \n" - - LABELALIGN - "1: \n" - READYUY2 - YUVTORGB(yuvconstants) - STOREARGB - "sub $0x8,%[width] \n" - "jg 1b \n" - : [yuy2_buf]"+r"(yuy2_buf), // %[yuy2_buf] - [dst_argb]"+r"(dst_argb), // %[dst_argb] - [width]"+rm"(width) // %[width] - : [yuvconstants]"r"(yuvconstants), // %[yuvconstants] - [kShuffleYUY2Y]"m"(kShuffleYUY2Y), - [kShuffleYUY2UV]"m"(kShuffleYUY2UV) - : "memory", "cc", YUVTORGB_REGS - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); - // clang-format on -} - -void OMITFP UYVYToARGBRow_SSSE3(const uint8_t* uyvy_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - // clang-format off - asm volatile ( - YUVTORGB_SETUP(yuvconstants) - "pcmpeqb %%xmm5,%%xmm5 \n" - - LABELALIGN - "1: \n" - READUYVY - YUVTORGB(yuvconstants) - STOREARGB - "sub $0x8,%[width] \n" - "jg 1b \n" - : [uyvy_buf]"+r"(uyvy_buf), // %[uyvy_buf] - [dst_argb]"+r"(dst_argb), // %[dst_argb] - [width]"+rm"(width) // %[width] - : [yuvconstants]"r"(yuvconstants), // %[yuvconstants] - [kShuffleUYVYY]"m"(kShuffleUYVYY), - [kShuffleUYVYUV]"m"(kShuffleUYVYUV) - : "memory", "cc", YUVTORGB_REGS - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); - // clang-format on -} - -void OMITFP I422ToRGBARow_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_rgba, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "pcmpeqb %%xmm5,%%xmm5 \n" - - LABELALIGN - "1: \n" - READYUV422 - YUVTORGB(yuvconstants) - STORERGBA - "sub $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] - [dst_rgba]"+r"(dst_rgba), // %[dst_rgba] - [width]"+rm"(width) // %[width] - : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] - : "memory", "cc", YUVTORGB_REGS - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); -} - -#endif // HAS_I422TOARGBROW_SSSE3 - -// Read 16 UV from 444 -#define READYUV444_AVX2 \ - "vmovdqu (%[u_buf]),%%xmm0 \n" \ - "vmovdqu 0x00(%[u_buf],%[v_buf],1),%%xmm1 \n" \ - "lea 0x10(%[u_buf]),%[u_buf] \n" \ - "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ - "vpermq $0xd8,%%ymm1,%%ymm1 \n" \ - "vpunpcklbw %%ymm1,%%ymm0,%%ymm0 \n" \ - "vmovdqu (%[y_buf]),%%xmm4 \n" \ - "vpermq $0xd8,%%ymm4,%%ymm4 \n" \ - "vpunpcklbw %%ymm4,%%ymm4,%%ymm4 \n" \ - "lea 0x10(%[y_buf]),%[y_buf] \n" - -// Read 8 UV from 422, upsample to 16 UV. -#define READYUV422_AVX2 \ - "vmovq (%[u_buf]),%%xmm0 \n" \ - "vmovq 0x00(%[u_buf],%[v_buf],1),%%xmm1 \n" \ - "lea 0x8(%[u_buf]),%[u_buf] \n" \ - "vpunpcklbw %%ymm1,%%ymm0,%%ymm0 \n" \ - "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ - "vpunpcklwd %%ymm0,%%ymm0,%%ymm0 \n" \ - "vmovdqu (%[y_buf]),%%xmm4 \n" \ - "vpermq $0xd8,%%ymm4,%%ymm4 \n" \ - "vpunpcklbw %%ymm4,%%ymm4,%%ymm4 \n" \ - "lea 0x10(%[y_buf]),%[y_buf] \n" - -// Read 8 UV from 210 10 bit, upsample to 16 UV -// TODO(fbarchard): Consider vshufb to replace pack/unpack -// TODO(fbarchard): Consider vunpcklpd to combine the 2 registers into 1. -#define READYUV210_AVX2 \ - "vmovdqu (%[u_buf]),%%xmm0 \n" \ - "vmovdqu 0x00(%[u_buf],%[v_buf],1),%%xmm1 \n" \ - "lea 0x10(%[u_buf]),%[u_buf] \n" \ - "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ - "vpermq $0xd8,%%ymm1,%%ymm1 \n" \ - "vpunpcklwd %%ymm1,%%ymm0,%%ymm0 \n" \ - "vpsraw $0x2,%%ymm0,%%ymm0 \n" \ - "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" \ - "vpunpcklwd %%ymm0,%%ymm0,%%ymm0 \n" \ - "vmovdqu (%[y_buf]),%%ymm4 \n" \ - "vpsllw $0x6,%%ymm4,%%ymm4 \n" \ - "lea 0x20(%[y_buf]),%[y_buf] \n" - -// Read 8 UV from 422, upsample to 16 UV. With 16 Alpha. -#define READYUVA422_AVX2 \ - "vmovq (%[u_buf]),%%xmm0 \n" \ - "vmovq 0x00(%[u_buf],%[v_buf],1),%%xmm1 \n" \ - "lea 0x8(%[u_buf]),%[u_buf] \n" \ - "vpunpcklbw %%ymm1,%%ymm0,%%ymm0 \n" \ - "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ - "vpunpcklwd %%ymm0,%%ymm0,%%ymm0 \n" \ - "vmovdqu (%[y_buf]),%%xmm4 \n" \ - "vpermq $0xd8,%%ymm4,%%ymm4 \n" \ - "vpunpcklbw %%ymm4,%%ymm4,%%ymm4 \n" \ - "lea 0x10(%[y_buf]),%[y_buf] \n" \ - "vmovdqu (%[a_buf]),%%xmm5 \n" \ - "vpermq $0xd8,%%ymm5,%%ymm5 \n" \ - "lea 0x10(%[a_buf]),%[a_buf] \n" - -// Read 8 UV from NV12, upsample to 16 UV. -#define READNV12_AVX2 \ - "vmovdqu (%[uv_buf]),%%xmm0 \n" \ - "lea 0x10(%[uv_buf]),%[uv_buf] \n" \ - "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ - "vpunpcklwd %%ymm0,%%ymm0,%%ymm0 \n" \ - "vmovdqu (%[y_buf]),%%xmm4 \n" \ - "vpermq $0xd8,%%ymm4,%%ymm4 \n" \ - "vpunpcklbw %%ymm4,%%ymm4,%%ymm4 \n" \ - "lea 0x10(%[y_buf]),%[y_buf] \n" - -// Read 8 VU from NV21, upsample to 16 UV. -#define READNV21_AVX2 \ - "vmovdqu (%[vu_buf]),%%xmm0 \n" \ - "lea 0x10(%[vu_buf]),%[vu_buf] \n" \ - "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ - "vpshufb %[kShuffleNV21], %%ymm0, %%ymm0 \n" \ - "vmovdqu (%[y_buf]),%%xmm4 \n" \ - "vpermq $0xd8,%%ymm4,%%ymm4 \n" \ - "vpunpcklbw %%ymm4,%%ymm4,%%ymm4 \n" \ - "lea 0x10(%[y_buf]),%[y_buf] \n" - -// Read 8 YUY2 with 16 Y and upsample 8 UV to 16 UV. -#define READYUY2_AVX2 \ - "vmovdqu (%[yuy2_buf]),%%ymm4 \n" \ - "vpshufb %[kShuffleYUY2Y], %%ymm4, %%ymm4 \n" \ - "vmovdqu (%[yuy2_buf]),%%ymm0 \n" \ - "vpshufb %[kShuffleYUY2UV], %%ymm0, %%ymm0 \n" \ - "lea 0x20(%[yuy2_buf]),%[yuy2_buf] \n" - -// Read 8 UYVY with 16 Y and upsample 8 UV to 16 UV. -#define READUYVY_AVX2 \ - "vmovdqu (%[uyvy_buf]),%%ymm4 \n" \ - "vpshufb %[kShuffleUYVYY], %%ymm4, %%ymm4 \n" \ - "vmovdqu (%[uyvy_buf]),%%ymm0 \n" \ - "vpshufb %[kShuffleUYVYUV], %%ymm0, %%ymm0 \n" \ - "lea 0x20(%[uyvy_buf]),%[uyvy_buf] \n" - -#if defined(__x86_64__) -#define YUVTORGB_SETUP_AVX2(yuvconstants) \ - "vmovdqa (%[yuvconstants]),%%ymm8 \n" \ - "vmovdqa 32(%[yuvconstants]),%%ymm9 \n" \ - "vmovdqa 64(%[yuvconstants]),%%ymm10 \n" \ - "vmovdqa 96(%[yuvconstants]),%%ymm11 \n" \ - "vmovdqa 128(%[yuvconstants]),%%ymm12 \n" \ - "vmovdqa 160(%[yuvconstants]),%%ymm13 \n" \ - "vmovdqa 192(%[yuvconstants]),%%ymm14 \n" - -#define YUVTORGB16_AVX2(yuvconstants) \ - "vpmaddubsw %%ymm10,%%ymm0,%%ymm2 \n" \ - "vpmaddubsw %%ymm9,%%ymm0,%%ymm1 \n" \ - "vpmaddubsw %%ymm8,%%ymm0,%%ymm0 \n" \ - "vpsubw %%ymm2,%%ymm13,%%ymm2 \n" \ - "vpsubw %%ymm1,%%ymm12,%%ymm1 \n" \ - "vpsubw %%ymm0,%%ymm11,%%ymm0 \n" \ - "vpmulhuw %%ymm14,%%ymm4,%%ymm4 \n" \ - "vpaddsw %%ymm4,%%ymm0,%%ymm0 \n" \ - "vpaddsw %%ymm4,%%ymm1,%%ymm1 \n" \ - "vpaddsw %%ymm4,%%ymm2,%%ymm2 \n" - -#define YUVTORGB_REGS_AVX2 \ - "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", - -#else // Convert 16 pixels: 16 UV and 16 Y. - -#define YUVTORGB_SETUP_AVX2(yuvconstants) -#define YUVTORGB16_AVX2(yuvconstants) \ - "vpmaddubsw 64(%[yuvconstants]),%%ymm0,%%ymm2 \n" \ - "vpmaddubsw 32(%[yuvconstants]),%%ymm0,%%ymm1 \n" \ - "vpmaddubsw (%[yuvconstants]),%%ymm0,%%ymm0 \n" \ - "vmovdqu 160(%[yuvconstants]),%%ymm3 \n" \ - "vpsubw %%ymm2,%%ymm3,%%ymm2 \n" \ - "vmovdqu 128(%[yuvconstants]),%%ymm3 \n" \ - "vpsubw %%ymm1,%%ymm3,%%ymm1 \n" \ - "vmovdqu 96(%[yuvconstants]),%%ymm3 \n" \ - "vpsubw %%ymm0,%%ymm3,%%ymm0 \n" \ - "vpmulhuw 192(%[yuvconstants]),%%ymm4,%%ymm4 \n" \ - "vpaddsw %%ymm4,%%ymm0,%%ymm0 \n" \ - "vpaddsw %%ymm4,%%ymm1,%%ymm1 \n" \ - "vpaddsw %%ymm4,%%ymm2,%%ymm2 \n" -#define YUVTORGB_REGS_AVX2 -#endif - -#define YUVTORGB_AVX2(yuvconstants) \ - YUVTORGB16_AVX2(yuvconstants) \ - "vpsraw $0x6,%%ymm0,%%ymm0 \n" \ - "vpsraw $0x6,%%ymm1,%%ymm1 \n" \ - "vpsraw $0x6,%%ymm2,%%ymm2 \n" \ - "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" \ - "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" \ - "vpackuswb %%ymm2,%%ymm2,%%ymm2 \n" - -// Store 16 ARGB values. -#define STOREARGB_AVX2 \ - "vpunpcklbw %%ymm1,%%ymm0,%%ymm0 \n" \ - "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ - "vpunpcklbw %%ymm5,%%ymm2,%%ymm2 \n" \ - "vpermq $0xd8,%%ymm2,%%ymm2 \n" \ - "vpunpcklwd %%ymm2,%%ymm0,%%ymm1 \n" \ - "vpunpckhwd %%ymm2,%%ymm0,%%ymm0 \n" \ - "vmovdqu %%ymm1,(%[dst_argb]) \n" \ - "vmovdqu %%ymm0,0x20(%[dst_argb]) \n" \ - "lea 0x40(%[dst_argb]), %[dst_argb] \n" - -// Store 16 AR30 values. -#define STOREAR30_AVX2 \ - "vpsraw $0x4,%%ymm0,%%ymm0 \n" \ - "vpsraw $0x4,%%ymm1,%%ymm1 \n" \ - "vpsraw $0x4,%%ymm2,%%ymm2 \n" \ - "vpminsw %%ymm7,%%ymm0,%%ymm0 \n" \ - "vpminsw %%ymm7,%%ymm1,%%ymm1 \n" \ - "vpminsw %%ymm7,%%ymm2,%%ymm2 \n" \ - "vpmaxsw %%ymm6,%%ymm0,%%ymm0 \n" \ - "vpmaxsw %%ymm6,%%ymm1,%%ymm1 \n" \ - "vpmaxsw %%ymm6,%%ymm2,%%ymm2 \n" \ - "vpsllw $0x4,%%ymm2,%%ymm2 \n" \ - "vpermq $0xd8,%%ymm0,%%ymm0 \n" \ - "vpermq $0xd8,%%ymm1,%%ymm1 \n" \ - "vpermq $0xd8,%%ymm2,%%ymm2 \n" \ - "vpunpckhwd %%ymm2,%%ymm0,%%ymm3 \n" \ - "vpunpcklwd %%ymm2,%%ymm0,%%ymm0 \n" \ - "vpunpckhwd %%ymm5,%%ymm1,%%ymm2 \n" \ - "vpunpcklwd %%ymm5,%%ymm1,%%ymm1 \n" \ - "vpslld $0xa,%%ymm1,%%ymm1 \n" \ - "vpslld $0xa,%%ymm2,%%ymm2 \n" \ - "vpor %%ymm1,%%ymm0,%%ymm0 \n" \ - "vpor %%ymm2,%%ymm3,%%ymm3 \n" \ - "vmovdqu %%ymm0,(%[dst_ar30]) \n" \ - "vmovdqu %%ymm3,0x20(%[dst_ar30]) \n" \ - "lea 0x40(%[dst_ar30]), %[dst_ar30] \n" - -#ifdef HAS_I444TOARGBROW_AVX2 -// 16 pixels -// 16 UV values with 16 Y producing 16 ARGB (64 bytes). -void OMITFP I444ToARGBRow_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* 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" - READYUV444_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", YUVTORGB_REGS_AVX2 - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); -} -#endif // HAS_I444TOARGBROW_AVX2 - -#if defined(HAS_I422TOARGBROW_AVX2) -// 16 pixels -// 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 ARGB (64 bytes). -void OMITFP I422ToARGBRow_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* 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" - READYUV422_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", YUVTORGB_REGS_AVX2 - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); -} -#endif // HAS_I422TOARGBROW_AVX2 - -#if defined(HAS_I422TOAR30ROW_AVX2) -// 16 pixels -// 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 AR30 (64 bytes). -void OMITFP I422ToAR30Row_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_ar30, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP_AVX2(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" // AR30 constants - "vpsrlw $14,%%ymm5,%%ymm5 \n" - "vpsllw $4,%%ymm5,%%ymm5 \n" // 2 alpha bits - "vpxor %%ymm6,%%ymm6,%%ymm6 \n" // 0 for min - "vpcmpeqb %%ymm7,%%ymm7,%%ymm7 \n" // 1023 for max - "vpsrlw $6,%%ymm7,%%ymm7 \n" - - LABELALIGN - "1: \n" - READYUV422_AVX2 - YUVTORGB16_AVX2(yuvconstants) - STOREAR30_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_ar30]"+r"(dst_ar30), // %[dst_ar30] - [width]"+rm"(width) // %[width] - : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] - : "memory", "cc", YUVTORGB_REGS_AVX2 - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" - ); -} -#endif // HAS_I422TOAR30ROW_AVX2 - -#if defined(HAS_I210TOARGBROW_AVX2) -// 16 pixels -// 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 ARGB (64 bytes). -void OMITFP I210ToARGBRow_AVX2(const uint16_t* y_buf, - const uint16_t* u_buf, - const uint16_t* v_buf, - uint8_t* 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" - READYUV210_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", YUVTORGB_REGS_AVX2 - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); -} -#endif // HAS_I210TOARGBROW_AVX2 - -#if defined(HAS_I210TOAR30ROW_AVX2) -// 16 pixels -// 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 AR30 (64 bytes). -void OMITFP I210ToAR30Row_AVX2(const uint16_t* y_buf, - const uint16_t* u_buf, - const uint16_t* v_buf, - uint8_t* dst_ar30, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP_AVX2(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" // AR30 constants - "vpsrlw $14,%%ymm5,%%ymm5 \n" - "vpsllw $4,%%ymm5,%%ymm5 \n" // 2 alpha bits - "vpxor %%ymm6,%%ymm6,%%ymm6 \n" // 0 for min - "vpcmpeqb %%ymm7,%%ymm7,%%ymm7 \n" // 1023 for max - "vpsrlw $6,%%ymm7,%%ymm7 \n" - - LABELALIGN - "1: \n" - READYUV210_AVX2 - YUVTORGB16_AVX2(yuvconstants) - STOREAR30_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_ar30]"+r"(dst_ar30), // %[dst_ar30] - [width]"+rm"(width) // %[width] - : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] - : "memory", "cc", YUVTORGB_REGS_AVX2 - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); -} -#endif // HAS_I210TOAR30ROW_AVX2 - -#if defined(HAS_I422ALPHATOARGBROW_AVX2) -// 16 pixels -// 8 UV values upsampled to 16 UV, mixed with 16 Y and 16 A producing 16 ARGB. -void OMITFP I422AlphaToARGBRow_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - const uint8_t* a_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - // clang-format off - asm volatile ( - YUVTORGB_SETUP_AVX2(yuvconstants) - "sub %[u_buf],%[v_buf] \n" - - LABELALIGN - "1: \n" - READYUVA422_AVX2 - YUVTORGB_AVX2(yuvconstants) - STOREARGB_AVX2 - "subl $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] - [a_buf]"+r"(a_buf), // %[a_buf] - [dst_argb]"+r"(dst_argb), // %[dst_argb] -#if defined(__i386__) - [width]"+m"(width) // %[width] -#else - [width]"+rm"(width) // %[width] -#endif - : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] - : "memory", "cc", YUVTORGB_REGS_AVX2 - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); - // clang-format on -} -#endif // HAS_I422ALPHATOARGBROW_AVX2 - -#if defined(HAS_I422TORGBAROW_AVX2) -// 16 pixels -// 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 RGBA (64 bytes). -void OMITFP I422ToRGBARow_AVX2(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* 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" - READYUV422_AVX2 - YUVTORGB_AVX2(yuvconstants) - - // Step 3: Weave into RGBA - "vpunpcklbw %%ymm2,%%ymm1,%%ymm1 \n" - "vpermq $0xd8,%%ymm1,%%ymm1 \n" - "vpunpcklbw %%ymm0,%%ymm5,%%ymm2 \n" - "vpermq $0xd8,%%ymm2,%%ymm2 \n" - "vpunpcklwd %%ymm1,%%ymm2,%%ymm0 \n" - "vpunpckhwd %%ymm1,%%ymm2,%%ymm1 \n" - "vmovdqu %%ymm0,(%[dst_argb]) \n" - "vmovdqu %%ymm1,0x20(%[dst_argb]) \n" - "lea 0x40(%[dst_argb]),%[dst_argb] \n" - "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", YUVTORGB_REGS_AVX2 - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); -} -#endif // HAS_I422TORGBAROW_AVX2 - -#if defined(HAS_NV12TOARGBROW_AVX2) -// 16 pixels. -// 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 ARGB (64 bytes). -void OMITFP NV12ToARGBRow_AVX2(const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - // clang-format off - asm volatile ( - YUVTORGB_SETUP_AVX2(yuvconstants) - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - - LABELALIGN - "1: \n" - READNV12_AVX2 - YUVTORGB_AVX2(yuvconstants) - STOREARGB_AVX2 - "sub $0x10,%[width] \n" - "jg 1b \n" - "vzeroupper \n" - : [y_buf]"+r"(y_buf), // %[y_buf] - [uv_buf]"+r"(uv_buf), // %[uv_buf] - [dst_argb]"+r"(dst_argb), // %[dst_argb] - [width]"+rm"(width) // %[width] - : [yuvconstants]"r"(yuvconstants) // %[yuvconstants] - : "memory", "cc", YUVTORGB_REGS_AVX2 - "xmm0", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); - // clang-format on -} -#endif // HAS_NV12TOARGBROW_AVX2 - -#if defined(HAS_NV21TOARGBROW_AVX2) -// 16 pixels. -// 8 VU values upsampled to 16 UV, mixed with 16 Y producing 16 ARGB (64 bytes). -void OMITFP NV21ToARGBRow_AVX2(const uint8_t* y_buf, - const uint8_t* vu_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - // clang-format off - asm volatile ( - YUVTORGB_SETUP_AVX2(yuvconstants) - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - - LABELALIGN - "1: \n" - READNV21_AVX2 - YUVTORGB_AVX2(yuvconstants) - STOREARGB_AVX2 - "sub $0x10,%[width] \n" - "jg 1b \n" - "vzeroupper \n" - : [y_buf]"+r"(y_buf), // %[y_buf] - [vu_buf]"+r"(vu_buf), // %[vu_buf] - [dst_argb]"+r"(dst_argb), // %[dst_argb] - [width]"+rm"(width) // %[width] - : [yuvconstants]"r"(yuvconstants), // %[yuvconstants] - [kShuffleNV21]"m"(kShuffleNV21) - : "memory", "cc", YUVTORGB_REGS_AVX2 - "xmm0", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); - // clang-format on -} -#endif // HAS_NV21TOARGBROW_AVX2 - -#if defined(HAS_YUY2TOARGBROW_AVX2) -// 16 pixels. -// 8 YUY2 values with 16 Y and 8 UV producing 16 ARGB (64 bytes). -void OMITFP YUY2ToARGBRow_AVX2(const uint8_t* yuy2_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - // clang-format off - asm volatile ( - YUVTORGB_SETUP_AVX2(yuvconstants) - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - - LABELALIGN - "1: \n" - READYUY2_AVX2 - YUVTORGB_AVX2(yuvconstants) - STOREARGB_AVX2 - "sub $0x10,%[width] \n" - "jg 1b \n" - "vzeroupper \n" - : [yuy2_buf]"+r"(yuy2_buf), // %[yuy2_buf] - [dst_argb]"+r"(dst_argb), // %[dst_argb] - [width]"+rm"(width) // %[width] - : [yuvconstants]"r"(yuvconstants), // %[yuvconstants] - [kShuffleYUY2Y]"m"(kShuffleYUY2Y), - [kShuffleYUY2UV]"m"(kShuffleYUY2UV) - : "memory", "cc", YUVTORGB_REGS_AVX2 - "xmm0", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); - // clang-format on -} -#endif // HAS_YUY2TOARGBROW_AVX2 - -#if defined(HAS_UYVYTOARGBROW_AVX2) -// 16 pixels. -// 8 UYVY values with 16 Y and 8 UV producing 16 ARGB (64 bytes). -void OMITFP UYVYToARGBRow_AVX2(const uint8_t* uyvy_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - // clang-format off - asm volatile ( - YUVTORGB_SETUP_AVX2(yuvconstants) - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - - LABELALIGN - "1: \n" - READUYVY_AVX2 - YUVTORGB_AVX2(yuvconstants) - STOREARGB_AVX2 - "sub $0x10,%[width] \n" - "jg 1b \n" - "vzeroupper \n" - : [uyvy_buf]"+r"(uyvy_buf), // %[uyvy_buf] - [dst_argb]"+r"(dst_argb), // %[dst_argb] - [width]"+rm"(width) // %[width] - : [yuvconstants]"r"(yuvconstants), // %[yuvconstants] - [kShuffleUYVYY]"m"(kShuffleUYVYY), - [kShuffleUYVYUV]"m"(kShuffleUYVYUV) - : "memory", "cc", YUVTORGB_REGS_AVX2 - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" - ); - // clang-format on -} -#endif // HAS_UYVYTOARGBROW_AVX2 - -#ifdef HAS_I400TOARGBROW_SSE2 -void I400ToARGBRow_SSE2(const uint8_t* y_buf, uint8_t* dst_argb, int width) { - asm volatile( - "mov $0x4a354a35,%%eax \n" // 4a35 = 18997 = 1.164 - "movd %%eax,%%xmm2 \n" - "pshufd $0x0,%%xmm2,%%xmm2 \n" - "mov $0x04880488,%%eax \n" // 0488 = 1160 = 1.164 * - // 16 - "movd %%eax,%%xmm3 \n" - "pshufd $0x0,%%xmm3,%%xmm3 \n" - "pcmpeqb %%xmm4,%%xmm4 \n" - "pslld $0x18,%%xmm4 \n" - - LABELALIGN - "1: \n" - // Step 1: Scale Y contribution to 8 G values. G = (y - 16) * 1.164 - "movq (%0),%%xmm0 \n" - "lea 0x8(%0),%0 \n" - "punpcklbw %%xmm0,%%xmm0 \n" - "pmulhuw %%xmm2,%%xmm0 \n" - "psubusw %%xmm3,%%xmm0 \n" - "psrlw $6, %%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - - // Step 2: Weave into ARGB - "punpcklbw %%xmm0,%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklwd %%xmm0,%%xmm0 \n" - "punpckhwd %%xmm1,%%xmm1 \n" - "por %%xmm4,%%xmm0 \n" - "por %%xmm4,%%xmm1 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu %%xmm1,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - - "sub $0x8,%2 \n" - "jg 1b \n" - : "+r"(y_buf), // %0 - "+r"(dst_argb), // %1 - "+rm"(width) // %2 - : - : "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4"); -} -#endif // HAS_I400TOARGBROW_SSE2 - -#ifdef HAS_I400TOARGBROW_AVX2 -// 16 pixels of Y converted to 16 pixels of ARGB (64 bytes). -// note: vpunpcklbw mutates and vpackuswb unmutates. -void I400ToARGBRow_AVX2(const uint8_t* y_buf, uint8_t* dst_argb, int width) { - asm volatile( - "mov $0x4a354a35,%%eax \n" // 0488 = 1160 = 1.164 * - // 16 - "vmovd %%eax,%%xmm2 \n" - "vbroadcastss %%xmm2,%%ymm2 \n" - "mov $0x4880488,%%eax \n" // 4a35 = 18997 = 1.164 - "vmovd %%eax,%%xmm3 \n" - "vbroadcastss %%xmm3,%%ymm3 \n" - "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" - "vpslld $0x18,%%ymm4,%%ymm4 \n" - - LABELALIGN - "1: \n" - // Step 1: Scale Y contribution to 16 G values. G = (y - 16) * 1.164 - "vmovdqu (%0),%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpunpcklbw %%ymm0,%%ymm0,%%ymm0 \n" - "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" - "vpsubusw %%ymm3,%%ymm0,%%ymm0 \n" - "vpsrlw $0x6,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" - "vpunpcklbw %%ymm0,%%ymm0,%%ymm1 \n" - "vpermq $0xd8,%%ymm1,%%ymm1 \n" - "vpunpcklwd %%ymm1,%%ymm1,%%ymm0 \n" - "vpunpckhwd %%ymm1,%%ymm1,%%ymm1 \n" - "vpor %%ymm4,%%ymm0,%%ymm0 \n" - "vpor %%ymm4,%%ymm1,%%ymm1 \n" - "vmovdqu %%ymm0,(%1) \n" - "vmovdqu %%ymm1,0x20(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(y_buf), // %0 - "+r"(dst_argb), // %1 - "+rm"(width) // %2 - : - : "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4"); -} -#endif // HAS_I400TOARGBROW_AVX2 - -#ifdef HAS_MIRRORROW_SSSE3 -// Shuffle table for reversing the bytes. -static const uvec8 kShuffleMirror = {15u, 14u, 13u, 12u, 11u, 10u, 9u, 8u, - 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u}; - -void MirrorRow_SSSE3(const uint8_t* src, uint8_t* dst, int width) { - intptr_t temp_width = (intptr_t)(width); - asm volatile( - - "movdqa %3,%%xmm5 \n" - - LABELALIGN - "1: \n" - "movdqu -0x10(%0,%2,1),%%xmm0 \n" - "pshufb %%xmm5,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(temp_width) // %2 - : "m"(kShuffleMirror) // %3 - : "memory", "cc", "xmm0", "xmm5"); -} -#endif // HAS_MIRRORROW_SSSE3 - -#ifdef HAS_MIRRORROW_AVX2 -void MirrorRow_AVX2(const uint8_t* src, uint8_t* dst, int width) { - intptr_t temp_width = (intptr_t)(width); - asm volatile( - - "vbroadcastf128 %3,%%ymm5 \n" - - LABELALIGN - "1: \n" - "vmovdqu -0x20(%0,%2,1),%%ymm0 \n" - "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" - "vpermq $0x4e,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(temp_width) // %2 - : "m"(kShuffleMirror) // %3 - : "memory", "cc", "xmm0", "xmm5"); -} -#endif // HAS_MIRRORROW_AVX2 - -#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}; -void MirrorUVRow_SSSE3(const uint8_t* src, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - intptr_t temp_width = (intptr_t)(width); - asm volatile( - "movdqa %4,%%xmm1 \n" - "lea -0x10(%0,%3,2),%0 \n" - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "lea -0x10(%0),%0 \n" - "pshufb %%xmm1,%%xmm0 \n" - "movlpd %%xmm0,(%1) \n" - "movhpd %%xmm0,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $8,%3 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(temp_width) // %3 - : "m"(kShuffleMirrorUV) // %4 - : "memory", "cc", "xmm0", "xmm1"); -} -#endif // HAS_MIRRORUVROW_SSSE3 - -#ifdef HAS_ARGBMIRRORROW_SSE2 - -void ARGBMirrorRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { - intptr_t temp_width = (intptr_t)(width); - asm volatile( - - "lea -0x10(%0,%2,4),%0 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "pshufd $0x1b,%%xmm0,%%xmm0 \n" - "lea -0x10(%0),%0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(temp_width) // %2 - : - : "memory", "cc", "xmm0"); -} -#endif // HAS_ARGBMIRRORROW_SSE2 - -#ifdef HAS_ARGBMIRRORROW_AVX2 -// Shuffle table for reversing the bytes. -static const ulvec32 kARGBShuffleMirror_AVX2 = {7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u}; -void ARGBMirrorRow_AVX2(const uint8_t* src, uint8_t* dst, int width) { - intptr_t temp_width = (intptr_t)(width); - asm volatile( - - "vmovdqu %3,%%ymm5 \n" - - LABELALIGN - "1: \n" - "vpermd -0x20(%0,%2,4),%%ymm5,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(temp_width) // %2 - : "m"(kARGBShuffleMirror_AVX2) // %3 - : "memory", "cc", "xmm0", "xmm5"); -} -#endif // HAS_ARGBMIRRORROW_AVX2 - -#ifdef HAS_SPLITUVROW_AVX2 -void SplitUVRow_AVX2(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpsrlw $0x8,%%ymm5,%%ymm5 \n" - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpsrlw $0x8,%%ymm0,%%ymm2 \n" - "vpsrlw $0x8,%%ymm1,%%ymm3 \n" - "vpand %%ymm5,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm3,%%ymm2,%%ymm2 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm2,%%ymm2 \n" - "vmovdqu %%ymm0,(%1) \n" - "vmovdqu %%ymm2,0x00(%1,%2,1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%3 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_uv), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); -} -#endif // HAS_SPLITUVROW_AVX2 - -#ifdef HAS_SPLITUVROW_SSE2 -void SplitUVRow_SSE2(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "psrlw $0x8,%%xmm5 \n" - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "movdqa %%xmm0,%%xmm2 \n" - "movdqa %%xmm1,%%xmm3 \n" - "pand %%xmm5,%%xmm0 \n" - "pand %%xmm5,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "psrlw $0x8,%%xmm2 \n" - "psrlw $0x8,%%xmm3 \n" - "packuswb %%xmm3,%%xmm2 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu %%xmm2,0x00(%1,%2,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" - : "+r"(src_uv), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); -} -#endif // HAS_SPLITUVROW_SSE2 - -#ifdef HAS_MERGEUVROW_AVX2 -void MergeUVRow_AVX2(const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uv, - int width) { - asm volatile( - - "sub %0,%1 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x00(%0,%1,1),%%ymm1 \n" - "lea 0x20(%0),%0 \n" - "vpunpcklbw %%ymm1,%%ymm0,%%ymm2 \n" - "vpunpckhbw %%ymm1,%%ymm0,%%ymm0 \n" - "vextractf128 $0x0,%%ymm2,(%2) \n" - "vextractf128 $0x0,%%ymm0,0x10(%2) \n" - "vextractf128 $0x1,%%ymm2,0x20(%2) \n" - "vextractf128 $0x1,%%ymm0,0x30(%2) \n" - "lea 0x40(%2),%2 \n" - "sub $0x20,%3 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_u), // %0 - "+r"(src_v), // %1 - "+r"(dst_uv), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2"); -} -#endif // HAS_MERGEUVROW_AVX2 - -#ifdef HAS_MERGEUVROW_SSE2 -void MergeUVRow_SSE2(const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uv, - int width) { - asm volatile( - - "sub %0,%1 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%1,1),%%xmm1 \n" - "lea 0x10(%0),%0 \n" - "movdqa %%xmm0,%%xmm2 \n" - "punpcklbw %%xmm1,%%xmm0 \n" - "punpckhbw %%xmm1,%%xmm2 \n" - "movdqu %%xmm0,(%2) \n" - "movdqu %%xmm2,0x10(%2) \n" - "lea 0x20(%2),%2 \n" - "sub $0x10,%3 \n" - "jg 1b \n" - : "+r"(src_u), // %0 - "+r"(src_v), // %1 - "+r"(dst_uv), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2"); -} -#endif // HAS_MERGEUVROW_SSE2 - -// Use scale to convert lsb formats to msb, depending how many bits there are: -// 128 = 9 bits -// 64 = 10 bits -// 16 = 12 bits -// 1 = 16 bits -#ifdef HAS_MERGEUVROW_16_AVX2 -void MergeUVRow_16_AVX2(const uint16_t* src_u, - const uint16_t* src_v, - uint16_t* dst_uv, - int scale, - int width) { - // clang-format off - asm volatile ( - "vmovd %4,%%xmm3 \n" - "vpunpcklwd %%xmm3,%%xmm3,%%xmm3 \n" - "vbroadcastss %%xmm3,%%ymm3 \n" - "sub %0,%1 \n" - - // 16 pixels per loop. - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu (%0,%1,1),%%ymm1 \n" - "add $0x20,%0 \n" - - "vpmullw %%ymm3,%%ymm0,%%ymm0 \n" - "vpmullw %%ymm3,%%ymm1,%%ymm1 \n" - "vpunpcklwd %%ymm1,%%ymm0,%%ymm2 \n" // mutates - "vpunpckhwd %%ymm1,%%ymm0,%%ymm0 \n" - "vextractf128 $0x0,%%ymm2,(%2) \n" - "vextractf128 $0x0,%%ymm0,0x10(%2) \n" - "vextractf128 $0x1,%%ymm2,0x20(%2) \n" - "vextractf128 $0x1,%%ymm0,0x30(%2) \n" - "add $0x40,%2 \n" - "sub $0x10,%3 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_u), // %0 - "+r"(src_v), // %1 - "+r"(dst_uv), // %2 - "+r"(width) // %3 - : "r"(scale) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3"); - // clang-format on -} -#endif // HAS_MERGEUVROW_AVX2 - -// Use scale to convert lsb formats to msb, depending how many bits there are: -// 128 = 9 bits -// 64 = 10 bits -// 16 = 12 bits -// 1 = 16 bits -#ifdef HAS_MULTIPLYROW_16_AVX2 -void MultiplyRow_16_AVX2(const uint16_t* src_y, - uint16_t* dst_y, - int scale, - int width) { - // clang-format off - asm volatile ( - "vmovd %3,%%xmm3 \n" - "vpunpcklwd %%xmm3,%%xmm3,%%xmm3 \n" - "vbroadcastss %%xmm3,%%ymm3 \n" - "sub %0,%1 \n" - - // 16 pixels per loop. - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vpmullw %%ymm3,%%ymm0,%%ymm0 \n" - "vpmullw %%ymm3,%%ymm1,%%ymm1 \n" - "vmovdqu %%ymm0,(%0,%1) \n" - "vmovdqu %%ymm1,0x20(%0,%1) \n" - "add $0x40,%0 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_y), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : "r"(scale) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm3"); - // clang-format on -} -#endif // HAS_MULTIPLYROW_16_AVX2 - -// Use scale to convert lsb formats to msb, depending how many bits there are: -// 32768 = 9 bits -// 16384 = 10 bits -// 4096 = 12 bits -// 256 = 16 bits -void Convert16To8Row_SSSE3(const uint16_t* src_y, - uint8_t* dst_y, - int scale, - int width) { - // clang-format off - asm volatile ( - "movd %3,%%xmm2 \n" - "punpcklwd %%xmm2,%%xmm2 \n" - "pshufd $0x0,%%xmm2,%%xmm2 \n" - - // 32 pixels per loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "add $0x20,%0 \n" - "pmulhuw %%xmm2,%%xmm0 \n" - "pmulhuw %%xmm2,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "add $0x10,%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src_y), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : "r"(scale) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2"); - // clang-format on -} - -#ifdef HAS_CONVERT16TO8ROW_AVX2 -void Convert16To8Row_AVX2(const uint16_t* src_y, - uint8_t* dst_y, - int scale, - int width) { - // clang-format off - asm volatile ( - "vmovd %3,%%xmm2 \n" - "vpunpcklwd %%xmm2,%%xmm2,%%xmm2 \n" - "vbroadcastss %%xmm2,%%ymm2 \n" - - // 32 pixels per loop. - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "add $0x40,%0 \n" - "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" - "vpmulhuw %%ymm2,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" // mutates - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "add $0x20,%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_y), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : "r"(scale) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2"); - // clang-format on -} -#endif // HAS_CONVERT16TO8ROW_AVX2 - -// Use scale to convert to lsb formats depending how many bits there are: -// 512 = 9 bits -// 1024 = 10 bits -// 4096 = 12 bits -// TODO(fbarchard): reduce to SSE2 -void Convert8To16Row_SSE2(const uint8_t* src_y, - uint16_t* dst_y, - int scale, - int width) { - // clang-format off - asm volatile ( - "movd %3,%%xmm2 \n" - "punpcklwd %%xmm2,%%xmm2 \n" - "pshufd $0x0,%%xmm2,%%xmm2 \n" - - // 32 pixels per loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklbw %%xmm0,%%xmm0 \n" - "punpckhbw %%xmm1,%%xmm1 \n" - "add $0x10,%0 \n" - "pmulhuw %%xmm2,%%xmm0 \n" - "pmulhuw %%xmm2,%%xmm1 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu %%xmm1,0x10(%1) \n" - "add $0x20,%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src_y), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : "r"(scale) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2"); - // clang-format on -} - -#ifdef HAS_CONVERT8TO16ROW_AVX2 -void Convert8To16Row_AVX2(const uint8_t* src_y, - uint16_t* dst_y, - int scale, - int width) { - // clang-format off - asm volatile ( - "vmovd %3,%%xmm2 \n" - "vpunpcklwd %%xmm2,%%xmm2,%%xmm2 \n" - "vbroadcastss %%xmm2,%%ymm2 \n" - - // 32 pixels per loop. - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "add $0x20,%0 \n" - "vpunpckhbw %%ymm0,%%ymm0,%%ymm1 \n" - "vpunpcklbw %%ymm0,%%ymm0,%%ymm0 \n" - "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" - "vpmulhuw %%ymm2,%%ymm1,%%ymm1 \n" - "vmovdqu %%ymm0,(%1) \n" - "vmovdqu %%ymm1,0x20(%1) \n" - "add $0x40,%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_y), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : "r"(scale) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2"); - // clang-format on -} -#endif // HAS_CONVERT8TO16ROW_AVX2 - -#ifdef HAS_SPLITRGBROW_SSSE3 - -// Shuffle table for converting RGB to Planar. -static const uvec8 kShuffleMaskRGBToR0 = {0u, 3u, 6u, 9u, 12u, 15u, - 128u, 128u, 128u, 128u, 128u, 128u, - 128u, 128u, 128u, 128u}; -static const uvec8 kShuffleMaskRGBToR1 = {128u, 128u, 128u, 128u, 128u, 128u, - 2u, 5u, 8u, 11u, 14u, 128u, - 128u, 128u, 128u, 128u}; -static const uvec8 kShuffleMaskRGBToR2 = {128u, 128u, 128u, 128u, 128u, 128u, - 128u, 128u, 128u, 128u, 128u, 1u, - 4u, 7u, 10u, 13u}; - -static const uvec8 kShuffleMaskRGBToG0 = {1u, 4u, 7u, 10u, 13u, 128u, - 128u, 128u, 128u, 128u, 128u, 128u, - 128u, 128u, 128u, 128u}; -static const uvec8 kShuffleMaskRGBToG1 = {128u, 128u, 128u, 128u, 128u, 0u, - 3u, 6u, 9u, 12u, 15u, 128u, - 128u, 128u, 128u, 128u}; -static const uvec8 kShuffleMaskRGBToG2 = {128u, 128u, 128u, 128u, 128u, 128u, - 128u, 128u, 128u, 128u, 128u, 2u, - 5u, 8u, 11u, 14u}; - -static const uvec8 kShuffleMaskRGBToB0 = {2u, 5u, 8u, 11u, 14u, 128u, - 128u, 128u, 128u, 128u, 128u, 128u, - 128u, 128u, 128u, 128u}; -static const uvec8 kShuffleMaskRGBToB1 = {128u, 128u, 128u, 128u, 128u, 1u, - 4u, 7u, 10u, 13u, 128u, 128u, - 128u, 128u, 128u, 128u}; -static const uvec8 kShuffleMaskRGBToB2 = {128u, 128u, 128u, 128u, 128u, 128u, - 128u, 128u, 128u, 128u, 0u, 3u, - 6u, 9u, 12u, 15u}; - -void SplitRGBRow_SSSE3(const uint8_t* src_rgb, - uint8_t* dst_r, - uint8_t* dst_g, - uint8_t* dst_b, - int width) { - asm volatile( - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "pshufb %5, %%xmm0 \n" - "pshufb %6, %%xmm1 \n" - "pshufb %7, %%xmm2 \n" - "por %%xmm1,%%xmm0 \n" - "por %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "pshufb %8, %%xmm0 \n" - "pshufb %9, %%xmm1 \n" - "pshufb %10, %%xmm2 \n" - "por %%xmm1,%%xmm0 \n" - "por %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "pshufb %11, %%xmm0 \n" - "pshufb %12, %%xmm1 \n" - "pshufb %13, %%xmm2 \n" - "por %%xmm1,%%xmm0 \n" - "por %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%3) \n" - "lea 0x10(%3),%3 \n" - "lea 0x30(%0),%0 \n" - "sub $0x10,%4 \n" - "jg 1b \n" - : "+r"(src_rgb), // %0 - "+r"(dst_r), // %1 - "+r"(dst_g), // %2 - "+r"(dst_b), // %3 - "+r"(width) // %4 - : "m"(kShuffleMaskRGBToR0), // %5 - "m"(kShuffleMaskRGBToR1), // %6 - "m"(kShuffleMaskRGBToR2), // %7 - "m"(kShuffleMaskRGBToG0), // %8 - "m"(kShuffleMaskRGBToG1), // %9 - "m"(kShuffleMaskRGBToG2), // %10 - "m"(kShuffleMaskRGBToB0), // %11 - "m"(kShuffleMaskRGBToB1), // %12 - "m"(kShuffleMaskRGBToB2) // %13 - : "memory", "cc", "xmm0", "xmm1", "xmm2"); -} -#endif // HAS_SPLITRGBROW_SSSE3 - -#ifdef HAS_MERGERGBROW_SSSE3 - -// Shuffle table for converting RGB to Planar. -static const uvec8 kShuffleMaskRToRGB0 = {0u, 128u, 128u, 1u, 128u, 128u, - 2u, 128u, 128u, 3u, 128u, 128u, - 4u, 128u, 128u, 5u}; -static const uvec8 kShuffleMaskGToRGB0 = {128u, 0u, 128u, 128u, 1u, 128u, - 128u, 2u, 128u, 128u, 3u, 128u, - 128u, 4u, 128u, 128u}; -static const uvec8 kShuffleMaskBToRGB0 = {128u, 128u, 0u, 128u, 128u, 1u, - 128u, 128u, 2u, 128u, 128u, 3u, - 128u, 128u, 4u, 128u}; - -static const uvec8 kShuffleMaskGToRGB1 = {5u, 128u, 128u, 6u, 128u, 128u, - 7u, 128u, 128u, 8u, 128u, 128u, - 9u, 128u, 128u, 10u}; -static const uvec8 kShuffleMaskBToRGB1 = {128u, 5u, 128u, 128u, 6u, 128u, - 128u, 7u, 128u, 128u, 8u, 128u, - 128u, 9u, 128u, 128u}; -static const uvec8 kShuffleMaskRToRGB1 = {128u, 128u, 6u, 128u, 128u, 7u, - 128u, 128u, 8u, 128u, 128u, 9u, - 128u, 128u, 10u, 128u}; - -static const uvec8 kShuffleMaskBToRGB2 = {10u, 128u, 128u, 11u, 128u, 128u, - 12u, 128u, 128u, 13u, 128u, 128u, - 14u, 128u, 128u, 15u}; -static const uvec8 kShuffleMaskRToRGB2 = {128u, 11u, 128u, 128u, 12u, 128u, - 128u, 13u, 128u, 128u, 14u, 128u, - 128u, 15u, 128u, 128u}; -static const uvec8 kShuffleMaskGToRGB2 = {128u, 128u, 11u, 128u, 128u, 12u, - 128u, 128u, 13u, 128u, 128u, 14u, - 128u, 128u, 15u, 128u}; - -void MergeRGBRow_SSSE3(const uint8_t* src_r, - const uint8_t* src_g, - const uint8_t* src_b, - uint8_t* dst_rgb, - int width) { - asm volatile( - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu (%1),%%xmm1 \n" - "movdqu (%2),%%xmm2 \n" - "pshufb %5, %%xmm0 \n" - "pshufb %6, %%xmm1 \n" - "pshufb %7, %%xmm2 \n" - "por %%xmm1,%%xmm0 \n" - "por %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%3) \n" - - "movdqu (%0),%%xmm0 \n" - "movdqu (%1),%%xmm1 \n" - "movdqu (%2),%%xmm2 \n" - "pshufb %8, %%xmm0 \n" - "pshufb %9, %%xmm1 \n" - "pshufb %10, %%xmm2 \n" - "por %%xmm1,%%xmm0 \n" - "por %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,16(%3) \n" - - "movdqu (%0),%%xmm0 \n" - "movdqu (%1),%%xmm1 \n" - "movdqu (%2),%%xmm2 \n" - "pshufb %11, %%xmm0 \n" - "pshufb %12, %%xmm1 \n" - "pshufb %13, %%xmm2 \n" - "por %%xmm1,%%xmm0 \n" - "por %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,32(%3) \n" - - "lea 0x10(%0),%0 \n" - "lea 0x10(%1),%1 \n" - "lea 0x10(%2),%2 \n" - "lea 0x30(%3),%3 \n" - "sub $0x10,%4 \n" - "jg 1b \n" - : "+r"(src_r), // %0 - "+r"(src_g), // %1 - "+r"(src_b), // %2 - "+r"(dst_rgb), // %3 - "+r"(width) // %4 - : "m"(kShuffleMaskRToRGB0), // %5 - "m"(kShuffleMaskGToRGB0), // %6 - "m"(kShuffleMaskBToRGB0), // %7 - "m"(kShuffleMaskRToRGB1), // %8 - "m"(kShuffleMaskGToRGB1), // %9 - "m"(kShuffleMaskBToRGB1), // %10 - "m"(kShuffleMaskRToRGB2), // %11 - "m"(kShuffleMaskGToRGB2), // %12 - "m"(kShuffleMaskBToRGB2) // %13 - : "memory", "cc", "xmm0", "xmm1", "xmm2"); -} -#endif // HAS_MERGERGBROW_SSSE3 - -#ifdef HAS_COPYROW_SSE2 -void CopyRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "test $0xf,%0 \n" - "jne 2f \n" - "test $0xf,%1 \n" - "jne 2f \n" - - LABELALIGN - "1: \n" - "movdqa (%0),%%xmm0 \n" - "movdqa 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "movdqa %%xmm0,(%1) \n" - "movdqa %%xmm1,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "jmp 9f \n" - - LABELALIGN - "2: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu %%xmm1,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 2b \n" - - LABELALIGN "9: \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : - : "memory", "cc", "xmm0", "xmm1"); -} -#endif // HAS_COPYROW_SSE2 - -#ifdef HAS_COPYROW_AVX -void CopyRow_AVX(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vmovdqu %%ymm0,(%1) \n" - "vmovdqu %%ymm1,0x20(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x40,%2 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : - : "memory", "cc", "xmm0", "xmm1"); -} -#endif // HAS_COPYROW_AVX - -#ifdef HAS_COPYROW_ERMS -// Multiple of 1. -void CopyRow_ERMS(const uint8_t* src, uint8_t* dst, int width) { - size_t width_tmp = (size_t)(width); - asm volatile( - - "rep movsb \n" - : "+S"(src), // %0 - "+D"(dst), // %1 - "+c"(width_tmp) // %2 - : - : "memory", "cc"); -} -#endif // HAS_COPYROW_ERMS - -#ifdef HAS_ARGBCOPYALPHAROW_SSE2 -// width in pixels -void ARGBCopyAlphaRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "pcmpeqb %%xmm0,%%xmm0 \n" - "pslld $0x18,%%xmm0 \n" - "pcmpeqb %%xmm1,%%xmm1 \n" - "psrld $0x8,%%xmm1 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm2 \n" - "movdqu 0x10(%0),%%xmm3 \n" - "lea 0x20(%0),%0 \n" - "movdqu (%1),%%xmm4 \n" - "movdqu 0x10(%1),%%xmm5 \n" - "pand %%xmm0,%%xmm2 \n" - "pand %%xmm0,%%xmm3 \n" - "pand %%xmm1,%%xmm4 \n" - "pand %%xmm1,%%xmm5 \n" - "por %%xmm4,%%xmm2 \n" - "por %%xmm5,%%xmm3 \n" - "movdqu %%xmm2,(%1) \n" - "movdqu %%xmm3,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} -#endif // HAS_ARGBCOPYALPHAROW_SSE2 - -#ifdef HAS_ARGBCOPYALPHAROW_AVX2 -// width in pixels -void ARGBCopyAlphaRow_AVX2(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "vpcmpeqb %%ymm0,%%ymm0,%%ymm0 \n" - "vpsrld $0x8,%%ymm0,%%ymm0 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm1 \n" - "vmovdqu 0x20(%0),%%ymm2 \n" - "lea 0x40(%0),%0 \n" - "vpblendvb %%ymm0,(%1),%%ymm1,%%ymm1 \n" - "vpblendvb %%ymm0,0x20(%1),%%ymm2,%%ymm2 \n" - "vmovdqu %%ymm1,(%1) \n" - "vmovdqu %%ymm2,0x20(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2"); -} -#endif // HAS_ARGBCOPYALPHAROW_AVX2 - -#ifdef HAS_ARGBEXTRACTALPHAROW_SSE2 -// width in pixels -void ARGBExtractAlphaRow_SSE2(const uint8_t* src_argb, - uint8_t* dst_a, - int width) { - asm volatile( - - LABELALIGN - "1: \n" - "movdqu (%0), %%xmm0 \n" - "movdqu 0x10(%0), %%xmm1 \n" - "lea 0x20(%0), %0 \n" - "psrld $0x18, %%xmm0 \n" - "psrld $0x18, %%xmm1 \n" - "packssdw %%xmm1, %%xmm0 \n" - "packuswb %%xmm0, %%xmm0 \n" - "movq %%xmm0,(%1) \n" - "lea 0x8(%1), %1 \n" - "sub $0x8, %2 \n" - "jg 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_a), // %1 - "+rm"(width) // %2 - : - : "memory", "cc", "xmm0", "xmm1"); -} -#endif // HAS_ARGBEXTRACTALPHAROW_SSE2 - -#ifdef HAS_ARGBEXTRACTALPHAROW_AVX2 -static const uvec8 kShuffleAlphaShort_AVX2 = { - 3u, 128u, 128u, 128u, 7u, 128u, 128u, 128u, - 11u, 128u, 128u, 128u, 15u, 128u, 128u, 128u}; - -void ARGBExtractAlphaRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_a, - int width) { - asm volatile( - "vmovdqa %3,%%ymm4 \n" - "vbroadcastf128 %4,%%ymm5 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0), %%ymm0 \n" - "vmovdqu 0x20(%0), %%ymm1 \n" - "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" // vpsrld $0x18, %%ymm0 - "vpshufb %%ymm5,%%ymm1,%%ymm1 \n" - "vmovdqu 0x40(%0), %%ymm2 \n" - "vmovdqu 0x60(%0), %%ymm3 \n" - "lea 0x80(%0), %0 \n" - "vpackssdw %%ymm1, %%ymm0, %%ymm0 \n" // mutates - "vpshufb %%ymm5,%%ymm2,%%ymm2 \n" - "vpshufb %%ymm5,%%ymm3,%%ymm3 \n" - "vpackssdw %%ymm3, %%ymm2, %%ymm2 \n" // mutates - "vpackuswb %%ymm2,%%ymm0,%%ymm0 \n" // mutates. - "vpermd %%ymm0,%%ymm4,%%ymm0 \n" // unmutate. - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20, %2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_argb), // %0 - "+r"(dst_a), // %1 - "+rm"(width) // %2 - : "m"(kPermdARGBToY_AVX), // %3 - "m"(kShuffleAlphaShort_AVX2) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} -#endif // HAS_ARGBEXTRACTALPHAROW_AVX2 - -#ifdef HAS_ARGBCOPYYTOALPHAROW_SSE2 -// width in pixels -void ARGBCopyYToAlphaRow_SSE2(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "pcmpeqb %%xmm0,%%xmm0 \n" - "pslld $0x18,%%xmm0 \n" - "pcmpeqb %%xmm1,%%xmm1 \n" - "psrld $0x8,%%xmm1 \n" - - LABELALIGN - "1: \n" - "movq (%0),%%xmm2 \n" - "lea 0x8(%0),%0 \n" - "punpcklbw %%xmm2,%%xmm2 \n" - "punpckhwd %%xmm2,%%xmm3 \n" - "punpcklwd %%xmm2,%%xmm2 \n" - "movdqu (%1),%%xmm4 \n" - "movdqu 0x10(%1),%%xmm5 \n" - "pand %%xmm0,%%xmm2 \n" - "pand %%xmm0,%%xmm3 \n" - "pand %%xmm1,%%xmm4 \n" - "pand %%xmm1,%%xmm5 \n" - "por %%xmm4,%%xmm2 \n" - "por %%xmm5,%%xmm3 \n" - "movdqu %%xmm2,(%1) \n" - "movdqu %%xmm3,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} -#endif // HAS_ARGBCOPYYTOALPHAROW_SSE2 - -#ifdef HAS_ARGBCOPYYTOALPHAROW_AVX2 -// width in pixels -void ARGBCopyYToAlphaRow_AVX2(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "vpcmpeqb %%ymm0,%%ymm0,%%ymm0 \n" - "vpsrld $0x8,%%ymm0,%%ymm0 \n" - - LABELALIGN - "1: \n" - "vpmovzxbd (%0),%%ymm1 \n" - "vpmovzxbd 0x8(%0),%%ymm2 \n" - "lea 0x10(%0),%0 \n" - "vpslld $0x18,%%ymm1,%%ymm1 \n" - "vpslld $0x18,%%ymm2,%%ymm2 \n" - "vpblendvb %%ymm0,(%1),%%ymm1,%%ymm1 \n" - "vpblendvb %%ymm0,0x20(%1),%%ymm2,%%ymm2 \n" - "vmovdqu %%ymm1,(%1) \n" - "vmovdqu %%ymm2,0x20(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2"); -} -#endif // HAS_ARGBCOPYYTOALPHAROW_AVX2 - -#ifdef HAS_SETROW_X86 -void SetRow_X86(uint8_t* dst, uint8_t v8, int width) { - size_t width_tmp = (size_t)(width >> 2); - const uint32_t v32 = v8 * 0x01010101u; // Duplicate byte to all bytes. - asm volatile( - - "rep stosl \n" - : "+D"(dst), // %0 - "+c"(width_tmp) // %1 - : "a"(v32) // %2 - : "memory", "cc"); -} - -void SetRow_ERMS(uint8_t* dst, uint8_t v8, int width) { - size_t width_tmp = (size_t)(width); - asm volatile( - - "rep stosb \n" - : "+D"(dst), // %0 - "+c"(width_tmp) // %1 - : "a"(v8) // %2 - : "memory", "cc"); -} - -void ARGBSetRow_X86(uint8_t* dst_argb, uint32_t v32, int width) { - size_t width_tmp = (size_t)(width); - asm volatile( - - "rep stosl \n" - : "+D"(dst_argb), // %0 - "+c"(width_tmp) // %1 - : "a"(v32) // %2 - : "memory", "cc"); -} -#endif // HAS_SETROW_X86 - -#ifdef HAS_YUY2TOYROW_SSE2 -void YUY2ToYRow_SSE2(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { - asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "psrlw $0x8,%%xmm5 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "pand %%xmm5,%%xmm0 \n" - "pand %%xmm5,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src_yuy2), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "memory", "cc", "xmm0", "xmm1", "xmm5"); -} - -void YUY2ToUVRow_SSE2(const uint8_t* src_yuy2, - int stride_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "psrlw $0x8,%%xmm5 \n" - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x00(%0,%4,1),%%xmm2 \n" - "movdqu 0x10(%0,%4,1),%%xmm3 \n" - "lea 0x20(%0),%0 \n" - "pavgb %%xmm2,%%xmm0 \n" - "pavgb %%xmm3,%%xmm1 \n" - "psrlw $0x8,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "pand %%xmm5,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm1 \n" - "movq %%xmm0,(%1) \n" - "movq %%xmm1,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" - : "+r"(src_yuy2), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 - : "r"((intptr_t)(stride_yuy2)) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); -} - -void YUY2ToUV422Row_SSE2(const uint8_t* src_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "psrlw $0x8,%%xmm5 \n" - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "psrlw $0x8,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "pand %%xmm5,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm1 \n" - "movq %%xmm0,(%1) \n" - "movq %%xmm1,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" - : "+r"(src_yuy2), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0", "xmm1", "xmm5"); -} - -void UYVYToYRow_SSE2(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { - asm volatile( - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "psrlw $0x8,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src_uyvy), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "memory", "cc", "xmm0", "xmm1"); -} - -void UYVYToUVRow_SSE2(const uint8_t* src_uyvy, - int stride_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "psrlw $0x8,%%xmm5 \n" - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x00(%0,%4,1),%%xmm2 \n" - "movdqu 0x10(%0,%4,1),%%xmm3 \n" - "lea 0x20(%0),%0 \n" - "pavgb %%xmm2,%%xmm0 \n" - "pavgb %%xmm3,%%xmm1 \n" - "pand %%xmm5,%%xmm0 \n" - "pand %%xmm5,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "pand %%xmm5,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm1 \n" - "movq %%xmm0,(%1) \n" - "movq %%xmm1,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" - : "+r"(src_uyvy), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 - : "r"((intptr_t)(stride_uyvy)) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); -} - -void UYVYToUV422Row_SSE2(const uint8_t* src_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "psrlw $0x8,%%xmm5 \n" - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "pand %%xmm5,%%xmm0 \n" - "pand %%xmm5,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "pand %%xmm5,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm1 \n" - "movq %%xmm0,(%1) \n" - "movq %%xmm1,0x00(%1,%2,1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x10,%3 \n" - "jg 1b \n" - : "+r"(src_uyvy), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0", "xmm1", "xmm5"); -} -#endif // HAS_YUY2TOYROW_SSE2 - -#ifdef HAS_YUY2TOYROW_AVX2 -void YUY2ToYRow_AVX2(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { - asm volatile( - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpsrlw $0x8,%%ymm5,%%ymm5 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpand %%ymm5,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_yuy2), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "memory", "cc", "xmm0", "xmm1", "xmm5"); -} - -void YUY2ToUVRow_AVX2(const uint8_t* src_yuy2, - int stride_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpsrlw $0x8,%%ymm5,%%ymm5 \n" - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" - "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpsrlw $0x8,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm0,%%ymm1 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm1,%%ymm1 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vextractf128 $0x0,%%ymm1,(%1) \n" - "vextractf128 $0x0,%%ymm0,0x00(%1,%2,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x20,%3 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_yuy2), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 - : "r"((intptr_t)(stride_yuy2)) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm5"); -} - -void YUY2ToUV422Row_AVX2(const uint8_t* src_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpsrlw $0x8,%%ymm5,%%ymm5 \n" - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpsrlw $0x8,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm0,%%ymm1 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm1,%%ymm1 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vextractf128 $0x0,%%ymm1,(%1) \n" - "vextractf128 $0x0,%%ymm0,0x00(%1,%2,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x20,%3 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_yuy2), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0", "xmm1", "xmm5"); -} - -void UYVYToYRow_AVX2(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { - asm volatile( - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpsrlw $0x8,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_uyvy), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "memory", "cc", "xmm0", "xmm1", "xmm5"); -} -void UYVYToUVRow_AVX2(const uint8_t* src_uyvy, - int stride_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpsrlw $0x8,%%ymm5,%%ymm5 \n" - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vpavgb 0x00(%0,%4,1),%%ymm0,%%ymm0 \n" - "vpavgb 0x20(%0,%4,1),%%ymm1,%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpand %%ymm5,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm0,%%ymm1 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm1,%%ymm1 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vextractf128 $0x0,%%ymm1,(%1) \n" - "vextractf128 $0x0,%%ymm0,0x00(%1,%2,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x20,%3 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_uyvy), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 - : "r"((intptr_t)(stride_uyvy)) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm5"); -} - -void UYVYToUV422Row_AVX2(const uint8_t* src_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpsrlw $0x8,%%ymm5,%%ymm5 \n" - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpand %%ymm5,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm0,%%ymm1 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm1,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm1,%%ymm1 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vextractf128 $0x0,%%ymm1,(%1) \n" - "vextractf128 $0x0,%%ymm0,0x00(%1,%2,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x20,%3 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_uyvy), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0", "xmm1", "xmm5"); -} -#endif // HAS_YUY2TOYROW_AVX2 - -#ifdef HAS_ARGBBLENDROW_SSSE3 -// Shuffle table for isolating alpha. -static const uvec8 kShuffleAlpha = {3u, 0x80, 3u, 0x80, 7u, 0x80, 7u, 0x80, - 11u, 0x80, 11u, 0x80, 15u, 0x80, 15u, 0x80}; - -// Blend 8 pixels at a time -void ARGBBlendRow_SSSE3(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - asm volatile( - "pcmpeqb %%xmm7,%%xmm7 \n" - "psrlw $0xf,%%xmm7 \n" - "pcmpeqb %%xmm6,%%xmm6 \n" - "psrlw $0x8,%%xmm6 \n" - "pcmpeqb %%xmm5,%%xmm5 \n" - "psllw $0x8,%%xmm5 \n" - "pcmpeqb %%xmm4,%%xmm4 \n" - "pslld $0x18,%%xmm4 \n" - "sub $0x4,%3 \n" - "jl 49f \n" - - // 4 pixel loop. - LABELALIGN - "40: \n" - "movdqu (%0),%%xmm3 \n" - "lea 0x10(%0),%0 \n" - "movdqa %%xmm3,%%xmm0 \n" - "pxor %%xmm4,%%xmm3 \n" - "movdqu (%1),%%xmm2 \n" - "pshufb %4,%%xmm3 \n" - "pand %%xmm6,%%xmm2 \n" - "paddw %%xmm7,%%xmm3 \n" - "pmullw %%xmm3,%%xmm2 \n" - "movdqu (%1),%%xmm1 \n" - "lea 0x10(%1),%1 \n" - "psrlw $0x8,%%xmm1 \n" - "por %%xmm4,%%xmm0 \n" - "pmullw %%xmm3,%%xmm1 \n" - "psrlw $0x8,%%xmm2 \n" - "paddusb %%xmm2,%%xmm0 \n" - "pand %%xmm5,%%xmm1 \n" - "paddusb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%3 \n" - "jge 40b \n" - - "49: \n" - "add $0x3,%3 \n" - "jl 99f \n" - - // 1 pixel loop. - "91: \n" - "movd (%0),%%xmm3 \n" - "lea 0x4(%0),%0 \n" - "movdqa %%xmm3,%%xmm0 \n" - "pxor %%xmm4,%%xmm3 \n" - "movd (%1),%%xmm2 \n" - "pshufb %4,%%xmm3 \n" - "pand %%xmm6,%%xmm2 \n" - "paddw %%xmm7,%%xmm3 \n" - "pmullw %%xmm3,%%xmm2 \n" - "movd (%1),%%xmm1 \n" - "lea 0x4(%1),%1 \n" - "psrlw $0x8,%%xmm1 \n" - "por %%xmm4,%%xmm0 \n" - "pmullw %%xmm3,%%xmm1 \n" - "psrlw $0x8,%%xmm2 \n" - "paddusb %%xmm2,%%xmm0 \n" - "pand %%xmm5,%%xmm1 \n" - "paddusb %%xmm1,%%xmm0 \n" - "movd %%xmm0,(%2) \n" - "lea 0x4(%2),%2 \n" - "sub $0x1,%3 \n" - "jge 91b \n" - "99: \n" - : "+r"(src_argb0), // %0 - "+r"(src_argb1), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : "m"(kShuffleAlpha) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} -#endif // HAS_ARGBBLENDROW_SSSE3 - -#ifdef HAS_BLENDPLANEROW_SSSE3 -// Blend 8 pixels at a time. -// unsigned version of math -// =((A2*C2)+(B2*(255-C2))+255)/256 -// signed version of math -// =(((A2-128)*C2)+((B2-128)*(255-C2))+32768+127)/256 -void BlendPlaneRow_SSSE3(const uint8_t* src0, - const uint8_t* src1, - const uint8_t* alpha, - uint8_t* dst, - int width) { - asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "psllw $0x8,%%xmm5 \n" - "mov $0x80808080,%%eax \n" - "movd %%eax,%%xmm6 \n" - "pshufd $0x0,%%xmm6,%%xmm6 \n" - "mov $0x807f807f,%%eax \n" - "movd %%eax,%%xmm7 \n" - "pshufd $0x0,%%xmm7,%%xmm7 \n" - "sub %2,%0 \n" - "sub %2,%1 \n" - "sub %2,%3 \n" - - // 8 pixel loop. - LABELALIGN - "1: \n" - "movq (%2),%%xmm0 \n" - "punpcklbw %%xmm0,%%xmm0 \n" - "pxor %%xmm5,%%xmm0 \n" - "movq (%0,%2,1),%%xmm1 \n" - "movq (%1,%2,1),%%xmm2 \n" - "punpcklbw %%xmm2,%%xmm1 \n" - "psubb %%xmm6,%%xmm1 \n" - "pmaddubsw %%xmm1,%%xmm0 \n" - "paddw %%xmm7,%%xmm0 \n" - "psrlw $0x8,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movq %%xmm0,(%3,%2,1) \n" - "lea 0x8(%2),%2 \n" - "sub $0x8,%4 \n" - "jg 1b \n" - : "+r"(src0), // %0 - "+r"(src1), // %1 - "+r"(alpha), // %2 - "+r"(dst), // %3 - "+rm"(width) // %4 - ::"memory", - "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm5", "xmm6", "xmm7"); -} -#endif // HAS_BLENDPLANEROW_SSSE3 - -#ifdef HAS_BLENDPLANEROW_AVX2 -// Blend 32 pixels at a time. -// unsigned version of math -// =((A2*C2)+(B2*(255-C2))+255)/256 -// signed version of math -// =(((A2-128)*C2)+((B2-128)*(255-C2))+32768+127)/256 -void BlendPlaneRow_AVX2(const uint8_t* src0, - const uint8_t* src1, - const uint8_t* alpha, - uint8_t* dst, - int width) { - asm volatile( - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpsllw $0x8,%%ymm5,%%ymm5 \n" - "mov $0x80808080,%%eax \n" - "vmovd %%eax,%%xmm6 \n" - "vbroadcastss %%xmm6,%%ymm6 \n" - "mov $0x807f807f,%%eax \n" - "vmovd %%eax,%%xmm7 \n" - "vbroadcastss %%xmm7,%%ymm7 \n" - "sub %2,%0 \n" - "sub %2,%1 \n" - "sub %2,%3 \n" - - // 32 pixel loop. - LABELALIGN - "1: \n" - "vmovdqu (%2),%%ymm0 \n" - "vpunpckhbw %%ymm0,%%ymm0,%%ymm3 \n" - "vpunpcklbw %%ymm0,%%ymm0,%%ymm0 \n" - "vpxor %%ymm5,%%ymm3,%%ymm3 \n" - "vpxor %%ymm5,%%ymm0,%%ymm0 \n" - "vmovdqu (%0,%2,1),%%ymm1 \n" - "vmovdqu (%1,%2,1),%%ymm2 \n" - "vpunpckhbw %%ymm2,%%ymm1,%%ymm4 \n" - "vpunpcklbw %%ymm2,%%ymm1,%%ymm1 \n" - "vpsubb %%ymm6,%%ymm4,%%ymm4 \n" - "vpsubb %%ymm6,%%ymm1,%%ymm1 \n" - "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" - "vpmaddubsw %%ymm1,%%ymm0,%%ymm0 \n" - "vpaddw %%ymm7,%%ymm3,%%ymm3 \n" - "vpaddw %%ymm7,%%ymm0,%%ymm0 \n" - "vpsrlw $0x8,%%ymm3,%%ymm3 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm3,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%3,%2,1) \n" - "lea 0x20(%2),%2 \n" - "sub $0x20,%4 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src0), // %0 - "+r"(src1), // %1 - "+r"(alpha), // %2 - "+r"(dst), // %3 - "+rm"(width) // %4 - ::"memory", - "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} -#endif // HAS_BLENDPLANEROW_AVX2 - -#ifdef HAS_ARGBATTENUATEROW_SSSE3 -// Shuffle table duplicating alpha -static const uvec8 kShuffleAlpha0 = {3u, 3u, 3u, 3u, 3u, 3u, 128u, 128u, - 7u, 7u, 7u, 7u, 7u, 7u, 128u, 128u}; -static const uvec8 kShuffleAlpha1 = {11u, 11u, 11u, 11u, 11u, 11u, 128u, 128u, - 15u, 15u, 15u, 15u, 15u, 15u, 128u, 128u}; -// Attenuate 4 pixels at a time. -void ARGBAttenuateRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_argb, - int width) { - asm volatile( - "pcmpeqb %%xmm3,%%xmm3 \n" - "pslld $0x18,%%xmm3 \n" - "movdqa %3,%%xmm4 \n" - "movdqa %4,%%xmm5 \n" - - // 4 pixel loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "pshufb %%xmm4,%%xmm0 \n" - "movdqu (%0),%%xmm1 \n" - "punpcklbw %%xmm1,%%xmm1 \n" - "pmulhuw %%xmm1,%%xmm0 \n" - "movdqu (%0),%%xmm1 \n" - "pshufb %%xmm5,%%xmm1 \n" - "movdqu (%0),%%xmm2 \n" - "punpckhbw %%xmm2,%%xmm2 \n" - "pmulhuw %%xmm2,%%xmm1 \n" - "movdqu (%0),%%xmm2 \n" - "lea 0x10(%0),%0 \n" - "pand %%xmm3,%%xmm2 \n" - "psrlw $0x8,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "por %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : "m"(kShuffleAlpha0), // %3 - "m"(kShuffleAlpha1) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} -#endif // HAS_ARGBATTENUATEROW_SSSE3 - -#ifdef HAS_ARGBATTENUATEROW_AVX2 -// Shuffle table duplicating alpha. -static const uvec8 kShuffleAlpha_AVX2 = {6u, 7u, 6u, 7u, 6u, 7u, - 128u, 128u, 14u, 15u, 14u, 15u, - 14u, 15u, 128u, 128u}; -// Attenuate 8 pixels at a time. -void ARGBAttenuateRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_argb, - int width) { - asm volatile( - "vbroadcastf128 %3,%%ymm4 \n" - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpslld $0x18,%%ymm5,%%ymm5 \n" - "sub %0,%1 \n" - - // 8 pixel loop. - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm6 \n" - "vpunpcklbw %%ymm6,%%ymm6,%%ymm0 \n" - "vpunpckhbw %%ymm6,%%ymm6,%%ymm1 \n" - "vpshufb %%ymm4,%%ymm0,%%ymm2 \n" - "vpshufb %%ymm4,%%ymm1,%%ymm3 \n" - "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" - "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" - "vpand %%ymm5,%%ymm6,%%ymm6 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpsrlw $0x8,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpor %%ymm6,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,0x00(%0,%1,1) \n" - "lea 0x20(%0),%0 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : "m"(kShuffleAlpha_AVX2) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); -} -#endif // HAS_ARGBATTENUATEROW_AVX2 - -#ifdef HAS_ARGBUNATTENUATEROW_SSE2 -// Unattenuate 4 pixels at a time. -void ARGBUnattenuateRow_SSE2(const uint8_t* src_argb, - uint8_t* dst_argb, - int width) { - uintptr_t alpha; - asm volatile( - // 4 pixel loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movzb 0x03(%0),%3 \n" - "punpcklbw %%xmm0,%%xmm0 \n" - "movd 0x00(%4,%3,4),%%xmm2 \n" - "movzb 0x07(%0),%3 \n" - "movd 0x00(%4,%3,4),%%xmm3 \n" - "pshuflw $0x40,%%xmm2,%%xmm2 \n" - "pshuflw $0x40,%%xmm3,%%xmm3 \n" - "movlhps %%xmm3,%%xmm2 \n" - "pmulhuw %%xmm2,%%xmm0 \n" - "movdqu (%0),%%xmm1 \n" - "movzb 0x0b(%0),%3 \n" - "punpckhbw %%xmm1,%%xmm1 \n" - "movd 0x00(%4,%3,4),%%xmm2 \n" - "movzb 0x0f(%0),%3 \n" - "movd 0x00(%4,%3,4),%%xmm3 \n" - "pshuflw $0x40,%%xmm2,%%xmm2 \n" - "pshuflw $0x40,%%xmm3,%%xmm3 \n" - "movlhps %%xmm3,%%xmm2 \n" - "pmulhuw %%xmm2,%%xmm1 \n" - "lea 0x10(%0),%0 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 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"(fixed_invtbl8) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} -#endif // HAS_ARGBUNATTENUATEROW_SSE2 - -#ifdef HAS_ARGBUNATTENUATEROW_AVX2 -// Shuffle table duplicating alpha. -static const uvec8 kUnattenShuffleAlpha_AVX2 = { - 0u, 1u, 0u, 1u, 0u, 1u, 6u, 7u, 8u, 9u, 8u, 9u, 8u, 9u, 14u, 15u}; -// Unattenuate 8 pixels at a time. -void ARGBUnattenuateRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_argb, - int width) { - uintptr_t alpha; - asm volatile( - "sub %0,%1 \n" - "vbroadcastf128 %5,%%ymm5 \n" - - // 8 pixel loop. - LABELALIGN - "1: \n" - // replace VPGATHER - "movzb 0x03(%0),%3 \n" - "vmovd 0x00(%4,%3,4),%%xmm0 \n" - "movzb 0x07(%0),%3 \n" - "vmovd 0x00(%4,%3,4),%%xmm1 \n" - "movzb 0x0b(%0),%3 \n" - "vpunpckldq %%xmm1,%%xmm0,%%xmm6 \n" - "vmovd 0x00(%4,%3,4),%%xmm2 \n" - "movzb 0x0f(%0),%3 \n" - "vmovd 0x00(%4,%3,4),%%xmm3 \n" - "movzb 0x13(%0),%3 \n" - "vpunpckldq %%xmm3,%%xmm2,%%xmm7 \n" - "vmovd 0x00(%4,%3,4),%%xmm0 \n" - "movzb 0x17(%0),%3 \n" - "vmovd 0x00(%4,%3,4),%%xmm1 \n" - "movzb 0x1b(%0),%3 \n" - "vpunpckldq %%xmm1,%%xmm0,%%xmm0 \n" - "vmovd 0x00(%4,%3,4),%%xmm2 \n" - "movzb 0x1f(%0),%3 \n" - "vmovd 0x00(%4,%3,4),%%xmm3 \n" - "vpunpckldq %%xmm3,%%xmm2,%%xmm2 \n" - "vpunpcklqdq %%xmm7,%%xmm6,%%xmm3 \n" - "vpunpcklqdq %%xmm2,%%xmm0,%%xmm0 \n" - "vinserti128 $0x1,%%xmm0,%%ymm3,%%ymm3 \n" - // end of VPGATHER - - "vmovdqu (%0),%%ymm6 \n" - "vpunpcklbw %%ymm6,%%ymm6,%%ymm0 \n" - "vpunpckhbw %%ymm6,%%ymm6,%%ymm1 \n" - "vpunpcklwd %%ymm3,%%ymm3,%%ymm2 \n" - "vpunpckhwd %%ymm3,%%ymm3,%%ymm3 \n" - "vpshufb %%ymm5,%%ymm2,%%ymm2 \n" - "vpshufb %%ymm5,%%ymm3,%%ymm3 \n" - "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" - "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,0x00(%0,%1,1) \n" - "lea 0x20(%0),%0 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width), // %2 - "=&r"(alpha) // %3 - : "r"(fixed_invtbl8), // %4 - "m"(kUnattenShuffleAlpha_AVX2) // %5 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} -#endif // HAS_ARGBUNATTENUATEROW_AVX2 - -#ifdef HAS_ARGBGRAYROW_SSSE3 -// Convert 8 ARGB pixels (64 bytes) to 8 Gray ARGB pixels -void ARGBGrayRow_SSSE3(const uint8_t* src_argb, uint8_t* dst_argb, int width) { - asm volatile( - "movdqa %3,%%xmm4 \n" - "movdqa %4,%%xmm5 \n" - - // 8 pixel loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "phaddw %%xmm1,%%xmm0 \n" - "paddw %%xmm5,%%xmm0 \n" - "psrlw $0x7,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movdqu (%0),%%xmm2 \n" - "movdqu 0x10(%0),%%xmm3 \n" - "lea 0x20(%0),%0 \n" - "psrld $0x18,%%xmm2 \n" - "psrld $0x18,%%xmm3 \n" - "packuswb %%xmm3,%%xmm2 \n" - "packuswb %%xmm2,%%xmm2 \n" - "movdqa %%xmm0,%%xmm3 \n" - "punpcklbw %%xmm0,%%xmm0 \n" - "punpcklbw %%xmm2,%%xmm3 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklwd %%xmm3,%%xmm0 \n" - "punpckhwd %%xmm3,%%xmm1 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu %%xmm1,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : "m"(kARGBToYJ), // %3 - "m"(kAddYJ64) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} -#endif // HAS_ARGBGRAYROW_SSSE3 - -#ifdef HAS_ARGBSEPIAROW_SSSE3 -// b = (r * 35 + g * 68 + b * 17) >> 7 -// g = (r * 45 + g * 88 + b * 22) >> 7 -// r = (r * 50 + g * 98 + b * 24) >> 7 -// Constant for ARGB color to sepia tone -static const vec8 kARGBToSepiaB = {17, 68, 35, 0, 17, 68, 35, 0, - 17, 68, 35, 0, 17, 68, 35, 0}; - -static const vec8 kARGBToSepiaG = {22, 88, 45, 0, 22, 88, 45, 0, - 22, 88, 45, 0, 22, 88, 45, 0}; - -static const vec8 kARGBToSepiaR = {24, 98, 50, 0, 24, 98, 50, 0, - 24, 98, 50, 0, 24, 98, 50, 0}; - -// Convert 8 ARGB pixels (32 bytes) to 8 Sepia ARGB pixels. -void ARGBSepiaRow_SSSE3(uint8_t* dst_argb, int width) { - asm volatile( - "movdqa %2,%%xmm2 \n" - "movdqa %3,%%xmm3 \n" - "movdqa %4,%%xmm4 \n" - - // 8 pixel loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm6 \n" - "pmaddubsw %%xmm2,%%xmm0 \n" - "pmaddubsw %%xmm2,%%xmm6 \n" - "phaddw %%xmm6,%%xmm0 \n" - "psrlw $0x7,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movdqu (%0),%%xmm5 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "pmaddubsw %%xmm3,%%xmm5 \n" - "pmaddubsw %%xmm3,%%xmm1 \n" - "phaddw %%xmm1,%%xmm5 \n" - "psrlw $0x7,%%xmm5 \n" - "packuswb %%xmm5,%%xmm5 \n" - "punpcklbw %%xmm5,%%xmm0 \n" - "movdqu (%0),%%xmm5 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "pmaddubsw %%xmm4,%%xmm5 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "phaddw %%xmm1,%%xmm5 \n" - "psrlw $0x7,%%xmm5 \n" - "packuswb %%xmm5,%%xmm5 \n" - "movdqu (%0),%%xmm6 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "psrld $0x18,%%xmm6 \n" - "psrld $0x18,%%xmm1 \n" - "packuswb %%xmm1,%%xmm6 \n" - "packuswb %%xmm6,%%xmm6 \n" - "punpcklbw %%xmm6,%%xmm5 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklwd %%xmm5,%%xmm0 \n" - "punpckhwd %%xmm5,%%xmm1 \n" - "movdqu %%xmm0,(%0) \n" - "movdqu %%xmm1,0x10(%0) \n" - "lea 0x20(%0),%0 \n" - "sub $0x8,%1 \n" - "jg 1b \n" - : "+r"(dst_argb), // %0 - "+r"(width) // %1 - : "m"(kARGBToSepiaB), // %2 - "m"(kARGBToSepiaG), // %3 - "m"(kARGBToSepiaR) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); -} -#endif // HAS_ARGBSEPIAROW_SSSE3 - -#ifdef HAS_ARGBCOLORMATRIXROW_SSSE3 -// Tranform 8 ARGB pixels (32 bytes) with color matrix. -// Same as Sepia except matrix is provided. -void ARGBColorMatrixRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_argb, - const int8_t* matrix_argb, - int width) { - asm volatile( - "movdqu (%3),%%xmm5 \n" - "pshufd $0x00,%%xmm5,%%xmm2 \n" - "pshufd $0x55,%%xmm5,%%xmm3 \n" - "pshufd $0xaa,%%xmm5,%%xmm4 \n" - "pshufd $0xff,%%xmm5,%%xmm5 \n" - - // 8 pixel loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm7 \n" - "pmaddubsw %%xmm2,%%xmm0 \n" - "pmaddubsw %%xmm2,%%xmm7 \n" - "movdqu (%0),%%xmm6 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "pmaddubsw %%xmm3,%%xmm6 \n" - "pmaddubsw %%xmm3,%%xmm1 \n" - "phaddsw %%xmm7,%%xmm0 \n" - "phaddsw %%xmm1,%%xmm6 \n" - "psraw $0x6,%%xmm0 \n" - "psraw $0x6,%%xmm6 \n" - "packuswb %%xmm0,%%xmm0 \n" - "packuswb %%xmm6,%%xmm6 \n" - "punpcklbw %%xmm6,%%xmm0 \n" - "movdqu (%0),%%xmm1 \n" - "movdqu 0x10(%0),%%xmm7 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "pmaddubsw %%xmm4,%%xmm7 \n" - "phaddsw %%xmm7,%%xmm1 \n" - "movdqu (%0),%%xmm6 \n" - "movdqu 0x10(%0),%%xmm7 \n" - "pmaddubsw %%xmm5,%%xmm6 \n" - "pmaddubsw %%xmm5,%%xmm7 \n" - "phaddsw %%xmm7,%%xmm6 \n" - "psraw $0x6,%%xmm1 \n" - "psraw $0x6,%%xmm6 \n" - "packuswb %%xmm1,%%xmm1 \n" - "packuswb %%xmm6,%%xmm6 \n" - "punpcklbw %%xmm6,%%xmm1 \n" - "movdqa %%xmm0,%%xmm6 \n" - "punpcklwd %%xmm1,%%xmm0 \n" - "punpckhwd %%xmm1,%%xmm6 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu %%xmm6,0x10(%1) \n" - "lea 0x20(%0),%0 \n" - "lea 0x20(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : "r"(matrix_argb) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} -#endif // HAS_ARGBCOLORMATRIXROW_SSSE3 - -#ifdef HAS_ARGBQUANTIZEROW_SSE2 -// Quantize 4 ARGB pixels (16 bytes). -void ARGBQuantizeRow_SSE2(uint8_t* dst_argb, - int scale, - int interval_size, - int interval_offset, - int width) { - asm volatile( - "movd %2,%%xmm2 \n" - "movd %3,%%xmm3 \n" - "movd %4,%%xmm4 \n" - "pshuflw $0x40,%%xmm2,%%xmm2 \n" - "pshufd $0x44,%%xmm2,%%xmm2 \n" - "pshuflw $0x40,%%xmm3,%%xmm3 \n" - "pshufd $0x44,%%xmm3,%%xmm3 \n" - "pshuflw $0x40,%%xmm4,%%xmm4 \n" - "pshufd $0x44,%%xmm4,%%xmm4 \n" - "pxor %%xmm5,%%xmm5 \n" - "pcmpeqb %%xmm6,%%xmm6 \n" - "pslld $0x18,%%xmm6 \n" - - // 4 pixel loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "punpcklbw %%xmm5,%%xmm0 \n" - "pmulhuw %%xmm2,%%xmm0 \n" - "movdqu (%0),%%xmm1 \n" - "punpckhbw %%xmm5,%%xmm1 \n" - "pmulhuw %%xmm2,%%xmm1 \n" - "pmullw %%xmm3,%%xmm0 \n" - "movdqu (%0),%%xmm7 \n" - "pmullw %%xmm3,%%xmm1 \n" - "pand %%xmm6,%%xmm7 \n" - "paddw %%xmm4,%%xmm0 \n" - "paddw %%xmm4,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "por %%xmm7,%%xmm0 \n" - "movdqu %%xmm0,(%0) \n" - "lea 0x10(%0),%0 \n" - "sub $0x4,%1 \n" - "jg 1b \n" - : "+r"(dst_argb), // %0 - "+r"(width) // %1 - : "r"(scale), // %2 - "r"(interval_size), // %3 - "r"(interval_offset) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} -#endif // HAS_ARGBQUANTIZEROW_SSE2 - -#ifdef HAS_ARGBSHADEROW_SSE2 -// Shade 4 pixels at a time by specified value. -void ARGBShadeRow_SSE2(const uint8_t* src_argb, - uint8_t* dst_argb, - int width, - uint32_t value) { - asm volatile( - "movd %3,%%xmm2 \n" - "punpcklbw %%xmm2,%%xmm2 \n" - "punpcklqdq %%xmm2,%%xmm2 \n" - - // 4 pixel loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklbw %%xmm0,%%xmm0 \n" - "punpckhbw %%xmm1,%%xmm1 \n" - "pmulhuw %%xmm2,%%xmm0 \n" - "pmulhuw %%xmm2,%%xmm1 \n" - "psrlw $0x8,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : "r"(value) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2"); -} -#endif // HAS_ARGBSHADEROW_SSE2 - -#ifdef HAS_ARGBMULTIPLYROW_SSE2 -// Multiply 2 rows of ARGB pixels together, 4 pixels at a time. -void ARGBMultiplyRow_SSE2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - asm volatile( - - "pxor %%xmm5,%%xmm5 \n" - - // 4 pixel loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "movdqu (%1),%%xmm2 \n" - "lea 0x10(%1),%1 \n" - "movdqu %%xmm0,%%xmm1 \n" - "movdqu %%xmm2,%%xmm3 \n" - "punpcklbw %%xmm0,%%xmm0 \n" - "punpckhbw %%xmm1,%%xmm1 \n" - "punpcklbw %%xmm5,%%xmm2 \n" - "punpckhbw %%xmm5,%%xmm3 \n" - "pmulhuw %%xmm2,%%xmm0 \n" - "pmulhuw %%xmm3,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%3 \n" - "jg 1b \n" - : "+r"(src_argb0), // %0 - "+r"(src_argb1), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); -} -#endif // HAS_ARGBMULTIPLYROW_SSE2 - -#ifdef HAS_ARGBMULTIPLYROW_AVX2 -// Multiply 2 rows of ARGB pixels together, 8 pixels at a time. -void ARGBMultiplyRow_AVX2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - asm volatile( - - "vpxor %%ymm5,%%ymm5,%%ymm5 \n" - - // 4 pixel loop. - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm1 \n" - "lea 0x20(%0),%0 \n" - "vmovdqu (%1),%%ymm3 \n" - "lea 0x20(%1),%1 \n" - "vpunpcklbw %%ymm1,%%ymm1,%%ymm0 \n" - "vpunpckhbw %%ymm1,%%ymm1,%%ymm1 \n" - "vpunpcklbw %%ymm5,%%ymm3,%%ymm2 \n" - "vpunpckhbw %%ymm5,%%ymm3,%%ymm3 \n" - "vpmulhuw %%ymm2,%%ymm0,%%ymm0 \n" - "vpmulhuw %%ymm3,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%2) \n" - "lea 0x20(%2),%2 \n" - "sub $0x8,%3 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_argb0), // %0 - "+r"(src_argb1), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "memory", "cc" -#if defined(__AVX2__) - , - "xmm0", "xmm1", "xmm2", "xmm3", "xmm5" -#endif - ); -} -#endif // HAS_ARGBMULTIPLYROW_AVX2 - -#ifdef HAS_ARGBADDROW_SSE2 -// Add 2 rows of ARGB pixels together, 4 pixels at a time. -void ARGBAddRow_SSE2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - asm volatile( - // 4 pixel loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "movdqu (%1),%%xmm1 \n" - "lea 0x10(%1),%1 \n" - "paddusb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%3 \n" - "jg 1b \n" - : "+r"(src_argb0), // %0 - "+r"(src_argb1), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0", "xmm1"); -} -#endif // HAS_ARGBADDROW_SSE2 - -#ifdef HAS_ARGBADDROW_AVX2 -// Add 2 rows of ARGB pixels together, 4 pixels at a time. -void ARGBAddRow_AVX2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - asm volatile( - // 4 pixel loop. - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "lea 0x20(%0),%0 \n" - "vpaddusb (%1),%%ymm0,%%ymm0 \n" - "lea 0x20(%1),%1 \n" - "vmovdqu %%ymm0,(%2) \n" - "lea 0x20(%2),%2 \n" - "sub $0x8,%3 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_argb0), // %0 - "+r"(src_argb1), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0"); -} -#endif // HAS_ARGBADDROW_AVX2 - -#ifdef HAS_ARGBSUBTRACTROW_SSE2 -// Subtract 2 rows of ARGB pixels, 4 pixels at a time. -void ARGBSubtractRow_SSE2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - asm volatile( - // 4 pixel loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "movdqu (%1),%%xmm1 \n" - "lea 0x10(%1),%1 \n" - "psubusb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%3 \n" - "jg 1b \n" - : "+r"(src_argb0), // %0 - "+r"(src_argb1), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0", "xmm1"); -} -#endif // HAS_ARGBSUBTRACTROW_SSE2 - -#ifdef HAS_ARGBSUBTRACTROW_AVX2 -// Subtract 2 rows of ARGB pixels, 8 pixels at a time. -void ARGBSubtractRow_AVX2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - asm volatile( - // 4 pixel loop. - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "lea 0x20(%0),%0 \n" - "vpsubusb (%1),%%ymm0,%%ymm0 \n" - "lea 0x20(%1),%1 \n" - "vmovdqu %%ymm0,(%2) \n" - "lea 0x20(%2),%2 \n" - "sub $0x8,%3 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_argb0), // %0 - "+r"(src_argb1), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0"); -} -#endif // HAS_ARGBSUBTRACTROW_AVX2 - -#ifdef HAS_SOBELXROW_SSE2 -// SobelX as a matrix is -// -1 0 1 -// -2 0 2 -// -1 0 1 -void SobelXRow_SSE2(const uint8_t* src_y0, - const uint8_t* src_y1, - const uint8_t* src_y2, - uint8_t* dst_sobelx, - int width) { - asm volatile( - "sub %0,%1 \n" - "sub %0,%2 \n" - "sub %0,%3 \n" - "pxor %%xmm5,%%xmm5 \n" - - // 8 pixel loop. - LABELALIGN - "1: \n" - "movq (%0),%%xmm0 \n" - "movq 0x2(%0),%%xmm1 \n" - "punpcklbw %%xmm5,%%xmm0 \n" - "punpcklbw %%xmm5,%%xmm1 \n" - "psubw %%xmm1,%%xmm0 \n" - "movq 0x00(%0,%1,1),%%xmm1 \n" - "movq 0x02(%0,%1,1),%%xmm2 \n" - "punpcklbw %%xmm5,%%xmm1 \n" - "punpcklbw %%xmm5,%%xmm2 \n" - "psubw %%xmm2,%%xmm1 \n" - "movq 0x00(%0,%2,1),%%xmm2 \n" - "movq 0x02(%0,%2,1),%%xmm3 \n" - "punpcklbw %%xmm5,%%xmm2 \n" - "punpcklbw %%xmm5,%%xmm3 \n" - "psubw %%xmm3,%%xmm2 \n" - "paddw %%xmm2,%%xmm0 \n" - "paddw %%xmm1,%%xmm0 \n" - "paddw %%xmm1,%%xmm0 \n" - "pxor %%xmm1,%%xmm1 \n" - "psubw %%xmm0,%%xmm1 \n" - "pmaxsw %%xmm1,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movq %%xmm0,0x00(%0,%3,1) \n" - "lea 0x8(%0),%0 \n" - "sub $0x8,%4 \n" - "jg 1b \n" - : "+r"(src_y0), // %0 - "+r"(src_y1), // %1 - "+r"(src_y2), // %2 - "+r"(dst_sobelx), // %3 - "+r"(width) // %4 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); -} -#endif // HAS_SOBELXROW_SSE2 - -#ifdef HAS_SOBELYROW_SSE2 -// SobelY as a matrix is -// -1 -2 -1 -// 0 0 0 -// 1 2 1 -void SobelYRow_SSE2(const uint8_t* src_y0, - const uint8_t* src_y1, - uint8_t* dst_sobely, - int width) { - asm volatile( - "sub %0,%1 \n" - "sub %0,%2 \n" - "pxor %%xmm5,%%xmm5 \n" - - // 8 pixel loop. - LABELALIGN - "1: \n" - "movq (%0),%%xmm0 \n" - "movq 0x00(%0,%1,1),%%xmm1 \n" - "punpcklbw %%xmm5,%%xmm0 \n" - "punpcklbw %%xmm5,%%xmm1 \n" - "psubw %%xmm1,%%xmm0 \n" - "movq 0x1(%0),%%xmm1 \n" - "movq 0x01(%0,%1,1),%%xmm2 \n" - "punpcklbw %%xmm5,%%xmm1 \n" - "punpcklbw %%xmm5,%%xmm2 \n" - "psubw %%xmm2,%%xmm1 \n" - "movq 0x2(%0),%%xmm2 \n" - "movq 0x02(%0,%1,1),%%xmm3 \n" - "punpcklbw %%xmm5,%%xmm2 \n" - "punpcklbw %%xmm5,%%xmm3 \n" - "psubw %%xmm3,%%xmm2 \n" - "paddw %%xmm2,%%xmm0 \n" - "paddw %%xmm1,%%xmm0 \n" - "paddw %%xmm1,%%xmm0 \n" - "pxor %%xmm1,%%xmm1 \n" - "psubw %%xmm0,%%xmm1 \n" - "pmaxsw %%xmm1,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movq %%xmm0,0x00(%0,%2,1) \n" - "lea 0x8(%0),%0 \n" - "sub $0x8,%3 \n" - "jg 1b \n" - : "+r"(src_y0), // %0 - "+r"(src_y1), // %1 - "+r"(dst_sobely), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); -} -#endif // HAS_SOBELYROW_SSE2 - -#ifdef HAS_SOBELROW_SSE2 -// Adds Sobel X and Sobel Y and stores Sobel into ARGB. -// A = 255 -// R = Sobel -// G = Sobel -// B = Sobel -void SobelRow_SSE2(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width) { - asm volatile( - "sub %0,%1 \n" - "pcmpeqb %%xmm5,%%xmm5 \n" - "pslld $0x18,%%xmm5 \n" - - // 8 pixel loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%1,1),%%xmm1 \n" - "lea 0x10(%0),%0 \n" - "paddusb %%xmm1,%%xmm0 \n" - "movdqa %%xmm0,%%xmm2 \n" - "punpcklbw %%xmm0,%%xmm2 \n" - "punpckhbw %%xmm0,%%xmm0 \n" - "movdqa %%xmm2,%%xmm1 \n" - "punpcklwd %%xmm2,%%xmm1 \n" - "punpckhwd %%xmm2,%%xmm2 \n" - "por %%xmm5,%%xmm1 \n" - "por %%xmm5,%%xmm2 \n" - "movdqa %%xmm0,%%xmm3 \n" - "punpcklwd %%xmm0,%%xmm3 \n" - "punpckhwd %%xmm0,%%xmm0 \n" - "por %%xmm5,%%xmm3 \n" - "por %%xmm5,%%xmm0 \n" - "movdqu %%xmm1,(%2) \n" - "movdqu %%xmm2,0x10(%2) \n" - "movdqu %%xmm3,0x20(%2) \n" - "movdqu %%xmm0,0x30(%2) \n" - "lea 0x40(%2),%2 \n" - "sub $0x10,%3 \n" - "jg 1b \n" - : "+r"(src_sobelx), // %0 - "+r"(src_sobely), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); -} -#endif // HAS_SOBELROW_SSE2 - -#ifdef HAS_SOBELTOPLANEROW_SSE2 -// Adds Sobel X and Sobel Y and stores Sobel into a plane. -void SobelToPlaneRow_SSE2(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_y, - int width) { - asm volatile( - "sub %0,%1 \n" - "pcmpeqb %%xmm5,%%xmm5 \n" - "pslld $0x18,%%xmm5 \n" - - // 8 pixel loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%1,1),%%xmm1 \n" - "lea 0x10(%0),%0 \n" - "paddusb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x10,%3 \n" - "jg 1b \n" - : "+r"(src_sobelx), // %0 - "+r"(src_sobely), // %1 - "+r"(dst_y), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0", "xmm1"); -} -#endif // HAS_SOBELTOPLANEROW_SSE2 - -#ifdef HAS_SOBELXYROW_SSE2 -// Mixes Sobel X, Sobel Y and Sobel into ARGB. -// A = 255 -// R = Sobel X -// G = Sobel -// B = Sobel Y -void SobelXYRow_SSE2(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width) { - asm volatile( - "sub %0,%1 \n" - "pcmpeqb %%xmm5,%%xmm5 \n" - - // 8 pixel loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%1,1),%%xmm1 \n" - "lea 0x10(%0),%0 \n" - "movdqa %%xmm0,%%xmm2 \n" - "paddusb %%xmm1,%%xmm2 \n" - "movdqa %%xmm0,%%xmm3 \n" - "punpcklbw %%xmm5,%%xmm3 \n" - "punpckhbw %%xmm5,%%xmm0 \n" - "movdqa %%xmm1,%%xmm4 \n" - "punpcklbw %%xmm2,%%xmm4 \n" - "punpckhbw %%xmm2,%%xmm1 \n" - "movdqa %%xmm4,%%xmm6 \n" - "punpcklwd %%xmm3,%%xmm6 \n" - "punpckhwd %%xmm3,%%xmm4 \n" - "movdqa %%xmm1,%%xmm7 \n" - "punpcklwd %%xmm0,%%xmm7 \n" - "punpckhwd %%xmm0,%%xmm1 \n" - "movdqu %%xmm6,(%2) \n" - "movdqu %%xmm4,0x10(%2) \n" - "movdqu %%xmm7,0x20(%2) \n" - "movdqu %%xmm1,0x30(%2) \n" - "lea 0x40(%2),%2 \n" - "sub $0x10,%3 \n" - "jg 1b \n" - : "+r"(src_sobelx), // %0 - "+r"(src_sobely), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} -#endif // HAS_SOBELXYROW_SSE2 - -#ifdef HAS_COMPUTECUMULATIVESUMROW_SSE2 -// Creates a table of cumulative sums where each value is a sum of all values -// above and to the left of the value, inclusive of the value. -void ComputeCumulativeSumRow_SSE2(const uint8_t* row, - int32_t* cumsum, - const int32_t* previous_cumsum, - int width) { - asm volatile( - "pxor %%xmm0,%%xmm0 \n" - "pxor %%xmm1,%%xmm1 \n" - "sub $0x4,%3 \n" - "jl 49f \n" - "test $0xf,%1 \n" - "jne 49f \n" - - // 4 pixel loop. - LABELALIGN - "40: \n" - "movdqu (%0),%%xmm2 \n" - "lea 0x10(%0),%0 \n" - "movdqa %%xmm2,%%xmm4 \n" - "punpcklbw %%xmm1,%%xmm2 \n" - "movdqa %%xmm2,%%xmm3 \n" - "punpcklwd %%xmm1,%%xmm2 \n" - "punpckhwd %%xmm1,%%xmm3 \n" - "punpckhbw %%xmm1,%%xmm4 \n" - "movdqa %%xmm4,%%xmm5 \n" - "punpcklwd %%xmm1,%%xmm4 \n" - "punpckhwd %%xmm1,%%xmm5 \n" - "paddd %%xmm2,%%xmm0 \n" - "movdqu (%2),%%xmm2 \n" - "paddd %%xmm0,%%xmm2 \n" - "paddd %%xmm3,%%xmm0 \n" - "movdqu 0x10(%2),%%xmm3 \n" - "paddd %%xmm0,%%xmm3 \n" - "paddd %%xmm4,%%xmm0 \n" - "movdqu 0x20(%2),%%xmm4 \n" - "paddd %%xmm0,%%xmm4 \n" - "paddd %%xmm5,%%xmm0 \n" - "movdqu 0x30(%2),%%xmm5 \n" - "lea 0x40(%2),%2 \n" - "paddd %%xmm0,%%xmm5 \n" - "movdqu %%xmm2,(%1) \n" - "movdqu %%xmm3,0x10(%1) \n" - "movdqu %%xmm4,0x20(%1) \n" - "movdqu %%xmm5,0x30(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x4,%3 \n" - "jge 40b \n" - - "49: \n" - "add $0x3,%3 \n" - "jl 19f \n" - - // 1 pixel loop. - LABELALIGN - "10: \n" - "movd (%0),%%xmm2 \n" - "lea 0x4(%0),%0 \n" - "punpcklbw %%xmm1,%%xmm2 \n" - "punpcklwd %%xmm1,%%xmm2 \n" - "paddd %%xmm2,%%xmm0 \n" - "movdqu (%2),%%xmm2 \n" - "lea 0x10(%2),%2 \n" - "paddd %%xmm0,%%xmm2 \n" - "movdqu %%xmm2,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x1,%3 \n" - "jge 10b \n" - - "19: \n" - : "+r"(row), // %0 - "+r"(cumsum), // %1 - "+r"(previous_cumsum), // %2 - "+r"(width) // %3 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} -#endif // HAS_COMPUTECUMULATIVESUMROW_SSE2 - -#ifdef HAS_CUMULATIVESUMTOAVERAGEROW_SSE2 -void CumulativeSumToAverageRow_SSE2(const int32_t* topleft, - const int32_t* botleft, - int width, - int area, - uint8_t* dst, - int count) { - asm volatile( - "movd %5,%%xmm5 \n" - "cvtdq2ps %%xmm5,%%xmm5 \n" - "rcpss %%xmm5,%%xmm4 \n" - "pshufd $0x0,%%xmm4,%%xmm4 \n" - "sub $0x4,%3 \n" - "jl 49f \n" - "cmpl $0x80,%5 \n" - "ja 40f \n" - - "pshufd $0x0,%%xmm5,%%xmm5 \n" - "pcmpeqb %%xmm6,%%xmm6 \n" - "psrld $0x10,%%xmm6 \n" - "cvtdq2ps %%xmm6,%%xmm6 \n" - "addps %%xmm6,%%xmm5 \n" - "mulps %%xmm4,%%xmm5 \n" - "cvtps2dq %%xmm5,%%xmm5 \n" - "packssdw %%xmm5,%%xmm5 \n" - - // 4 pixel small loop. - LABELALIGN - "4: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x30(%0),%%xmm3 \n" - "psubd 0x00(%0,%4,4),%%xmm0 \n" - "psubd 0x10(%0,%4,4),%%xmm1 \n" - "psubd 0x20(%0,%4,4),%%xmm2 \n" - "psubd 0x30(%0,%4,4),%%xmm3 \n" - "lea 0x40(%0),%0 \n" - "psubd (%1),%%xmm0 \n" - "psubd 0x10(%1),%%xmm1 \n" - "psubd 0x20(%1),%%xmm2 \n" - "psubd 0x30(%1),%%xmm3 \n" - "paddd 0x00(%1,%4,4),%%xmm0 \n" - "paddd 0x10(%1,%4,4),%%xmm1 \n" - "paddd 0x20(%1,%4,4),%%xmm2 \n" - "paddd 0x30(%1,%4,4),%%xmm3 \n" - "lea 0x40(%1),%1 \n" - "packssdw %%xmm1,%%xmm0 \n" - "packssdw %%xmm3,%%xmm2 \n" - "pmulhuw %%xmm5,%%xmm0 \n" - "pmulhuw %%xmm5,%%xmm2 \n" - "packuswb %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%3 \n" - "jge 4b \n" - "jmp 49f \n" - - // 4 pixel loop - LABELALIGN - "40: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x20(%0),%%xmm2 \n" - "movdqu 0x30(%0),%%xmm3 \n" - "psubd 0x00(%0,%4,4),%%xmm0 \n" - "psubd 0x10(%0,%4,4),%%xmm1 \n" - "psubd 0x20(%0,%4,4),%%xmm2 \n" - "psubd 0x30(%0,%4,4),%%xmm3 \n" - "lea 0x40(%0),%0 \n" - "psubd (%1),%%xmm0 \n" - "psubd 0x10(%1),%%xmm1 \n" - "psubd 0x20(%1),%%xmm2 \n" - "psubd 0x30(%1),%%xmm3 \n" - "paddd 0x00(%1,%4,4),%%xmm0 \n" - "paddd 0x10(%1,%4,4),%%xmm1 \n" - "paddd 0x20(%1,%4,4),%%xmm2 \n" - "paddd 0x30(%1,%4,4),%%xmm3 \n" - "lea 0x40(%1),%1 \n" - "cvtdq2ps %%xmm0,%%xmm0 \n" - "cvtdq2ps %%xmm1,%%xmm1 \n" - "mulps %%xmm4,%%xmm0 \n" - "mulps %%xmm4,%%xmm1 \n" - "cvtdq2ps %%xmm2,%%xmm2 \n" - "cvtdq2ps %%xmm3,%%xmm3 \n" - "mulps %%xmm4,%%xmm2 \n" - "mulps %%xmm4,%%xmm3 \n" - "cvtps2dq %%xmm0,%%xmm0 \n" - "cvtps2dq %%xmm1,%%xmm1 \n" - "cvtps2dq %%xmm2,%%xmm2 \n" - "cvtps2dq %%xmm3,%%xmm3 \n" - "packssdw %%xmm1,%%xmm0 \n" - "packssdw %%xmm3,%%xmm2 \n" - "packuswb %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%3 \n" - "jge 40b \n" - - "49: \n" - "add $0x3,%3 \n" - "jl 19f \n" - - // 1 pixel loop - LABELALIGN - "10: \n" - "movdqu (%0),%%xmm0 \n" - "psubd 0x00(%0,%4,4),%%xmm0 \n" - "lea 0x10(%0),%0 \n" - "psubd (%1),%%xmm0 \n" - "paddd 0x00(%1,%4,4),%%xmm0 \n" - "lea 0x10(%1),%1 \n" - "cvtdq2ps %%xmm0,%%xmm0 \n" - "mulps %%xmm4,%%xmm0 \n" - "cvtps2dq %%xmm0,%%xmm0 \n" - "packssdw %%xmm0,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movd %%xmm0,(%2) \n" - "lea 0x4(%2),%2 \n" - "sub $0x1,%3 \n" - "jge 10b \n" - "19: \n" - : "+r"(topleft), // %0 - "+r"(botleft), // %1 - "+r"(dst), // %2 - "+rm"(count) // %3 - : "r"((intptr_t)(width)), // %4 - "rm"(area) // %5 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); -} -#endif // HAS_CUMULATIVESUMTOAVERAGEROW_SSE2 - -#ifdef HAS_ARGBAFFINEROW_SSE2 -// Copy ARGB pixels from source image with slope to a row of destination. -LIBYUV_API -void ARGBAffineRow_SSE2(const uint8_t* src_argb, - int src_argb_stride, - uint8_t* dst_argb, - const float* src_dudv, - int width) { - intptr_t src_argb_stride_temp = src_argb_stride; - intptr_t temp; - asm volatile( - "movq (%3),%%xmm2 \n" - "movq 0x08(%3),%%xmm7 \n" - "shl $0x10,%1 \n" - "add $0x4,%1 \n" - "movd %1,%%xmm5 \n" - "sub $0x4,%4 \n" - "jl 49f \n" - - "pshufd $0x44,%%xmm7,%%xmm7 \n" - "pshufd $0x0,%%xmm5,%%xmm5 \n" - "movdqa %%xmm2,%%xmm0 \n" - "addps %%xmm7,%%xmm0 \n" - "movlhps %%xmm0,%%xmm2 \n" - "movdqa %%xmm7,%%xmm4 \n" - "addps %%xmm4,%%xmm4 \n" - "movdqa %%xmm2,%%xmm3 \n" - "addps %%xmm4,%%xmm3 \n" - "addps %%xmm4,%%xmm4 \n" - - // 4 pixel loop - LABELALIGN - "40: \n" - "cvttps2dq %%xmm2,%%xmm0 \n" // x,y float->int first 2 - "cvttps2dq %%xmm3,%%xmm1 \n" // x,y float->int next 2 - "packssdw %%xmm1,%%xmm0 \n" // x, y as 8 shorts - "pmaddwd %%xmm5,%%xmm0 \n" // off = x*4 + y*stride - "movd %%xmm0,%k1 \n" - "pshufd $0x39,%%xmm0,%%xmm0 \n" - "movd %%xmm0,%k5 \n" - "pshufd $0x39,%%xmm0,%%xmm0 \n" - "movd 0x00(%0,%1,1),%%xmm1 \n" - "movd 0x00(%0,%5,1),%%xmm6 \n" - "punpckldq %%xmm6,%%xmm1 \n" - "addps %%xmm4,%%xmm2 \n" - "movq %%xmm1,(%2) \n" - "movd %%xmm0,%k1 \n" - "pshufd $0x39,%%xmm0,%%xmm0 \n" - "movd %%xmm0,%k5 \n" - "movd 0x00(%0,%1,1),%%xmm0 \n" - "movd 0x00(%0,%5,1),%%xmm6 \n" - "punpckldq %%xmm6,%%xmm0 \n" - "addps %%xmm4,%%xmm3 \n" - "movq %%xmm0,0x08(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%4 \n" - "jge 40b \n" - - "49: \n" - "add $0x3,%4 \n" - "jl 19f \n" - - // 1 pixel loop - LABELALIGN - "10: \n" - "cvttps2dq %%xmm2,%%xmm0 \n" - "packssdw %%xmm0,%%xmm0 \n" - "pmaddwd %%xmm5,%%xmm0 \n" - "addps %%xmm7,%%xmm2 \n" - "movd %%xmm0,%k1 \n" - "movd 0x00(%0,%1,1),%%xmm0 \n" - "movd %%xmm0,(%2) \n" - "lea 0x04(%2),%2 \n" - "sub $0x1,%4 \n" - "jge 10b \n" - "19: \n" - : "+r"(src_argb), // %0 - "+r"(src_argb_stride_temp), // %1 - "+r"(dst_argb), // %2 - "+r"(src_dudv), // %3 - "+rm"(width), // %4 - "=&r"(temp) // %5 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} -#endif // HAS_ARGBAFFINEROW_SSE2 - -#ifdef HAS_INTERPOLATEROW_SSSE3 -// Bilinear filter 16x2 -> 16x1 -void InterpolateRow_SSSE3(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride, - int dst_width, - int source_y_fraction) { - asm volatile( - "sub %1,%0 \n" - "cmp $0x0,%3 \n" - "je 100f \n" - "cmp $0x80,%3 \n" - "je 50f \n" - - "movd %3,%%xmm0 \n" - "neg %3 \n" - "add $0x100,%3 \n" - "movd %3,%%xmm5 \n" - "punpcklbw %%xmm0,%%xmm5 \n" - "punpcklwd %%xmm5,%%xmm5 \n" - "pshufd $0x0,%%xmm5,%%xmm5 \n" - "mov $0x80808080,%%eax \n" - "movd %%eax,%%xmm4 \n" - "pshufd $0x0,%%xmm4,%%xmm4 \n" - - // General purpose row blend. - LABELALIGN - "1: \n" - "movdqu (%1),%%xmm0 \n" - "movdqu 0x00(%1,%4,1),%%xmm2 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklbw %%xmm2,%%xmm0 \n" - "punpckhbw %%xmm2,%%xmm1 \n" - "psubb %%xmm4,%%xmm0 \n" - "psubb %%xmm4,%%xmm1 \n" - "movdqa %%xmm5,%%xmm2 \n" - "movdqa %%xmm5,%%xmm3 \n" - "pmaddubsw %%xmm0,%%xmm2 \n" - "pmaddubsw %%xmm1,%%xmm3 \n" - "paddw %%xmm4,%%xmm2 \n" - "paddw %%xmm4,%%xmm3 \n" - "psrlw $0x8,%%xmm2 \n" - "psrlw $0x8,%%xmm3 \n" - "packuswb %%xmm3,%%xmm2 \n" - "movdqu %%xmm2,0x00(%1,%0,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - "jmp 99f \n" - - // Blend 50 / 50. - LABELALIGN - "50: \n" - "movdqu (%1),%%xmm0 \n" - "movdqu 0x00(%1,%4,1),%%xmm1 \n" - "pavgb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,0x00(%1,%0,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 50b \n" - "jmp 99f \n" - - // Blend 100 / 0 - Copy row unchanged. - LABELALIGN - "100: \n" - "movdqu (%1),%%xmm0 \n" - "movdqu %%xmm0,0x00(%1,%0,1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 100b \n" - - "99: \n" - : "+r"(dst_ptr), // %0 - "+r"(src_ptr), // %1 - "+rm"(dst_width), // %2 - "+r"(source_y_fraction) // %3 - : "r"((intptr_t)(src_stride)) // %4 - : "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} -#endif // HAS_INTERPOLATEROW_SSSE3 - -#ifdef HAS_INTERPOLATEROW_AVX2 -// Bilinear filter 32x2 -> 32x1 -void InterpolateRow_AVX2(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride, - int dst_width, - int source_y_fraction) { - asm volatile( - "cmp $0x0,%3 \n" - "je 100f \n" - "sub %1,%0 \n" - "cmp $0x80,%3 \n" - "je 50f \n" - - "vmovd %3,%%xmm0 \n" - "neg %3 \n" - "add $0x100,%3 \n" - "vmovd %3,%%xmm5 \n" - "vpunpcklbw %%xmm0,%%xmm5,%%xmm5 \n" - "vpunpcklwd %%xmm5,%%xmm5,%%xmm5 \n" - "vbroadcastss %%xmm5,%%ymm5 \n" - "mov $0x80808080,%%eax \n" - "vmovd %%eax,%%xmm4 \n" - "vbroadcastss %%xmm4,%%ymm4 \n" - - // General purpose row blend. - LABELALIGN - "1: \n" - "vmovdqu (%1),%%ymm0 \n" - "vmovdqu 0x00(%1,%4,1),%%ymm2 \n" - "vpunpckhbw %%ymm2,%%ymm0,%%ymm1 \n" - "vpunpcklbw %%ymm2,%%ymm0,%%ymm0 \n" - "vpsubb %%ymm4,%%ymm1,%%ymm1 \n" - "vpsubb %%ymm4,%%ymm0,%%ymm0 \n" - "vpmaddubsw %%ymm1,%%ymm5,%%ymm1 \n" - "vpmaddubsw %%ymm0,%%ymm5,%%ymm0 \n" - "vpaddw %%ymm4,%%ymm1,%%ymm1 \n" - "vpaddw %%ymm4,%%ymm0,%%ymm0 \n" - "vpsrlw $0x8,%%ymm1,%%ymm1 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,0x00(%1,%0,1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "jmp 99f \n" - - // Blend 50 / 50. - LABELALIGN - "50: \n" - "vmovdqu (%1),%%ymm0 \n" - "vpavgb 0x00(%1,%4,1),%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,0x00(%1,%0,1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 50b \n" - "jmp 99f \n" - - // Blend 100 / 0 - Copy row unchanged. - LABELALIGN - "100: \n" - "rep movsb \n" - "jmp 999f \n" - - "99: \n" - "vzeroupper \n" - "999: \n" - : "+D"(dst_ptr), // %0 - "+S"(src_ptr), // %1 - "+cm"(dst_width), // %2 - "+r"(source_y_fraction) // %3 - : "r"((intptr_t)(src_stride)) // %4 - : "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm4", "xmm5"); -} -#endif // HAS_INTERPOLATEROW_AVX2 - -#ifdef HAS_ARGBSHUFFLEROW_SSSE3 -// For BGRAToARGB, ABGRToARGB, RGBAToARGB, and ARGBToRGBA. -void ARGBShuffleRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_argb, - const uint8_t* shuffler, - int width) { - asm volatile( - - "movdqu (%3),%%xmm5 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "pshufb %%xmm5,%%xmm0 \n" - "pshufb %%xmm5,%%xmm1 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu %%xmm1,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : "r"(shuffler) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm5"); -} -#endif // HAS_ARGBSHUFFLEROW_SSSE3 - -#ifdef HAS_ARGBSHUFFLEROW_AVX2 -// For BGRAToARGB, ABGRToARGB, RGBAToARGB, and ARGBToRGBA. -void ARGBShuffleRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_argb, - const uint8_t* shuffler, - int width) { - asm volatile( - - "vbroadcastf128 (%3),%%ymm5 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpshufb %%ymm5,%%ymm0,%%ymm0 \n" - "vpshufb %%ymm5,%%ymm1,%%ymm1 \n" - "vmovdqu %%ymm0,(%1) \n" - "vmovdqu %%ymm1,0x20(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : "r"(shuffler) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm5"); -} -#endif // HAS_ARGBSHUFFLEROW_AVX2 - -#ifdef HAS_I422TOYUY2ROW_SSE2 -void I422ToYUY2Row_SSE2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_yuy2, - int width) { - asm volatile( - - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "movq (%1),%%xmm2 \n" - "movq 0x00(%1,%2,1),%%xmm1 \n" - "add $0x8,%1 \n" - "punpcklbw %%xmm1,%%xmm2 \n" - "movdqu (%0),%%xmm0 \n" - "add $0x10,%0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklbw %%xmm2,%%xmm0 \n" - "punpckhbw %%xmm2,%%xmm1 \n" - "movdqu %%xmm0,(%3) \n" - "movdqu %%xmm1,0x10(%3) \n" - "lea 0x20(%3),%3 \n" - "sub $0x10,%4 \n" - "jg 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_yuy2), // %3 - "+rm"(width) // %4 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2"); -} -#endif // HAS_I422TOYUY2ROW_SSE2 - -#ifdef HAS_I422TOUYVYROW_SSE2 -void I422ToUYVYRow_SSE2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uyvy, - int width) { - asm volatile( - - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "movq (%1),%%xmm2 \n" - "movq 0x00(%1,%2,1),%%xmm1 \n" - "add $0x8,%1 \n" - "punpcklbw %%xmm1,%%xmm2 \n" - "movdqu (%0),%%xmm0 \n" - "movdqa %%xmm2,%%xmm1 \n" - "add $0x10,%0 \n" - "punpcklbw %%xmm0,%%xmm1 \n" - "punpckhbw %%xmm0,%%xmm2 \n" - "movdqu %%xmm1,(%3) \n" - "movdqu %%xmm2,0x10(%3) \n" - "lea 0x20(%3),%3 \n" - "sub $0x10,%4 \n" - "jg 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_uyvy), // %3 - "+rm"(width) // %4 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2"); -} -#endif // HAS_I422TOUYVYROW_SSE2 - -#ifdef HAS_I422TOYUY2ROW_AVX2 -void I422ToYUY2Row_AVX2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_yuy2, - int width) { - asm volatile( - - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "vpmovzxbw (%1),%%ymm1 \n" - "vpmovzxbw 0x00(%1,%2,1),%%ymm2 \n" - "add $0x10,%1 \n" - "vpsllw $0x8,%%ymm2,%%ymm2 \n" - "vpor %%ymm1,%%ymm2,%%ymm2 \n" - "vmovdqu (%0),%%ymm0 \n" - "add $0x20,%0 \n" - "vpunpcklbw %%ymm2,%%ymm0,%%ymm1 \n" - "vpunpckhbw %%ymm2,%%ymm0,%%ymm2 \n" - "vextractf128 $0x0,%%ymm1,(%3) \n" - "vextractf128 $0x0,%%ymm2,0x10(%3) \n" - "vextractf128 $0x1,%%ymm1,0x20(%3) \n" - "vextractf128 $0x1,%%ymm2,0x30(%3) \n" - "lea 0x40(%3),%3 \n" - "sub $0x20,%4 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_yuy2), // %3 - "+rm"(width) // %4 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2"); -} -#endif // HAS_I422TOYUY2ROW_AVX2 - -#ifdef HAS_I422TOUYVYROW_AVX2 -void I422ToUYVYRow_AVX2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uyvy, - int width) { - asm volatile( - - "sub %1,%2 \n" - - LABELALIGN - "1: \n" - "vpmovzxbw (%1),%%ymm1 \n" - "vpmovzxbw 0x00(%1,%2,1),%%ymm2 \n" - "add $0x10,%1 \n" - "vpsllw $0x8,%%ymm2,%%ymm2 \n" - "vpor %%ymm1,%%ymm2,%%ymm2 \n" - "vmovdqu (%0),%%ymm0 \n" - "add $0x20,%0 \n" - "vpunpcklbw %%ymm0,%%ymm2,%%ymm1 \n" - "vpunpckhbw %%ymm0,%%ymm2,%%ymm2 \n" - "vextractf128 $0x0,%%ymm1,(%3) \n" - "vextractf128 $0x0,%%ymm2,0x10(%3) \n" - "vextractf128 $0x1,%%ymm1,0x20(%3) \n" - "vextractf128 $0x1,%%ymm2,0x30(%3) \n" - "lea 0x40(%3),%3 \n" - "sub $0x20,%4 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_uyvy), // %3 - "+rm"(width) // %4 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2"); -} -#endif // HAS_I422TOUYVYROW_AVX2 - -#ifdef HAS_ARGBPOLYNOMIALROW_SSE2 -void ARGBPolynomialRow_SSE2(const uint8_t* src_argb, - uint8_t* dst_argb, - const float* poly, - int width) { - asm volatile( - - "pxor %%xmm3,%%xmm3 \n" - - // 2 pixel loop. - LABELALIGN - "1: \n" - "movq (%0),%%xmm0 \n" - "lea 0x8(%0),%0 \n" - "punpcklbw %%xmm3,%%xmm0 \n" - "movdqa %%xmm0,%%xmm4 \n" - "punpcklwd %%xmm3,%%xmm0 \n" - "punpckhwd %%xmm3,%%xmm4 \n" - "cvtdq2ps %%xmm0,%%xmm0 \n" - "cvtdq2ps %%xmm4,%%xmm4 \n" - "movdqa %%xmm0,%%xmm1 \n" - "movdqa %%xmm4,%%xmm5 \n" - "mulps 0x10(%3),%%xmm0 \n" - "mulps 0x10(%3),%%xmm4 \n" - "addps (%3),%%xmm0 \n" - "addps (%3),%%xmm4 \n" - "movdqa %%xmm1,%%xmm2 \n" - "movdqa %%xmm5,%%xmm6 \n" - "mulps %%xmm1,%%xmm2 \n" - "mulps %%xmm5,%%xmm6 \n" - "mulps %%xmm2,%%xmm1 \n" - "mulps %%xmm6,%%xmm5 \n" - "mulps 0x20(%3),%%xmm2 \n" - "mulps 0x20(%3),%%xmm6 \n" - "mulps 0x30(%3),%%xmm1 \n" - "mulps 0x30(%3),%%xmm5 \n" - "addps %%xmm2,%%xmm0 \n" - "addps %%xmm6,%%xmm4 \n" - "addps %%xmm1,%%xmm0 \n" - "addps %%xmm5,%%xmm4 \n" - "cvttps2dq %%xmm0,%%xmm0 \n" - "cvttps2dq %%xmm4,%%xmm4 \n" - "packuswb %%xmm4,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movq %%xmm0,(%1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x2,%2 \n" - "jg 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : "r"(poly) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); -} -#endif // HAS_ARGBPOLYNOMIALROW_SSE2 - -#ifdef HAS_ARGBPOLYNOMIALROW_AVX2 -void ARGBPolynomialRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_argb, - const float* poly, - int width) { - asm volatile( - "vbroadcastf128 (%3),%%ymm4 \n" - "vbroadcastf128 0x10(%3),%%ymm5 \n" - "vbroadcastf128 0x20(%3),%%ymm6 \n" - "vbroadcastf128 0x30(%3),%%ymm7 \n" - - // 2 pixel loop. - LABELALIGN - "1: \n" - "vpmovzxbd (%0),%%ymm0 \n" // 2 ARGB pixels - "lea 0x8(%0),%0 \n" - "vcvtdq2ps %%ymm0,%%ymm0 \n" // X 8 floats - "vmulps %%ymm0,%%ymm0,%%ymm2 \n" // X * X - "vmulps %%ymm7,%%ymm0,%%ymm3 \n" // C3 * X - "vfmadd132ps %%ymm5,%%ymm4,%%ymm0 \n" // result = C0 + C1 * X - "vfmadd231ps %%ymm6,%%ymm2,%%ymm0 \n" // result += C2 * X * X - "vfmadd231ps %%ymm3,%%ymm2,%%ymm0 \n" // result += C3 * X * X * - // X - "vcvttps2dq %%ymm0,%%ymm0 \n" - "vpackusdw %%ymm0,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpackuswb %%xmm0,%%xmm0,%%xmm0 \n" - "vmovq %%xmm0,(%1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x2,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : "r"(poly) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} -#endif // HAS_ARGBPOLYNOMIALROW_AVX2 - -#ifdef HAS_HALFFLOATROW_SSE2 -static float kScaleBias = 1.9259299444e-34f; -void HalfFloatRow_SSE2(const uint16_t* src, - uint16_t* dst, - float scale, - int width) { - scale *= kScaleBias; - asm volatile( - "movd %3,%%xmm4 \n" - "pshufd $0x0,%%xmm4,%%xmm4 \n" - "pxor %%xmm5,%%xmm5 \n" - "sub %0,%1 \n" - - // 16 pixel loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm2 \n" // 8 shorts - "add $0x10,%0 \n" - "movdqa %%xmm2,%%xmm3 \n" - "punpcklwd %%xmm5,%%xmm2 \n" // 8 ints in xmm2/1 - "cvtdq2ps %%xmm2,%%xmm2 \n" // 8 floats - "punpckhwd %%xmm5,%%xmm3 \n" - "cvtdq2ps %%xmm3,%%xmm3 \n" - "mulps %%xmm4,%%xmm2 \n" - "mulps %%xmm4,%%xmm3 \n" - "psrld $0xd,%%xmm2 \n" - "psrld $0xd,%%xmm3 \n" - "packssdw %%xmm3,%%xmm2 \n" - "movdqu %%xmm2,-0x10(%0,%1,1) \n" - "sub $0x8,%2 \n" - "jg 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "m"(scale) // %3 - : "memory", "cc", "xmm2", "xmm3", "xmm4", "xmm5"); -} -#endif // HAS_HALFFLOATROW_SSE2 - -#ifdef HAS_HALFFLOATROW_AVX2 -void HalfFloatRow_AVX2(const uint16_t* src, - uint16_t* dst, - float scale, - int width) { - scale *= kScaleBias; - asm volatile( - "vbroadcastss %3, %%ymm4 \n" - "vpxor %%ymm5,%%ymm5,%%ymm5 \n" - "sub %0,%1 \n" - - // 16 pixel loop. - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm2 \n" // 16 shorts - "add $0x20,%0 \n" - "vpunpckhwd %%ymm5,%%ymm2,%%ymm3 \n" // mutates - "vpunpcklwd %%ymm5,%%ymm2,%%ymm2 \n" - "vcvtdq2ps %%ymm3,%%ymm3 \n" - "vcvtdq2ps %%ymm2,%%ymm2 \n" - "vmulps %%ymm3,%%ymm4,%%ymm3 \n" - "vmulps %%ymm2,%%ymm4,%%ymm2 \n" - "vpsrld $0xd,%%ymm3,%%ymm3 \n" - "vpsrld $0xd,%%ymm2,%%ymm2 \n" - "vpackssdw %%ymm3, %%ymm2, %%ymm2 \n" // unmutates - "vmovdqu %%ymm2,-0x20(%0,%1,1) \n" - "sub $0x10,%2 \n" - "jg 1b \n" - - "vzeroupper \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 -#if defined(__x86_64__) - : "x"(scale) // %3 -#else - : "m"(scale) // %3 -#endif - : "memory", "cc", "xmm2", "xmm3", "xmm4", "xmm5"); -} -#endif // HAS_HALFFLOATROW_AVX2 - -#ifdef HAS_HALFFLOATROW_F16C -void HalfFloatRow_F16C(const uint16_t* src, - uint16_t* dst, - float scale, - int width) { - asm volatile( - "vbroadcastss %3, %%ymm4 \n" - "sub %0,%1 \n" - - // 16 pixel loop. - LABELALIGN - "1: \n" - "vpmovzxwd (%0),%%ymm2 \n" // 16 shorts -> 16 ints - "vpmovzxwd 0x10(%0),%%ymm3 \n" - "vcvtdq2ps %%ymm2,%%ymm2 \n" - "vcvtdq2ps %%ymm3,%%ymm3 \n" - "vmulps %%ymm2,%%ymm4,%%ymm2 \n" - "vmulps %%ymm3,%%ymm4,%%ymm3 \n" - "vcvtps2ph $3, %%ymm2, %%xmm2 \n" - "vcvtps2ph $3, %%ymm3, %%xmm3 \n" - "vmovdqu %%xmm2,0x00(%0,%1,1) \n" - "vmovdqu %%xmm3,0x10(%0,%1,1) \n" - "add $0x20,%0 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 -#if defined(__x86_64__) - : "x"(scale) // %3 -#else - : "m"(scale) // %3 -#endif - : "memory", "cc", "xmm2", "xmm3", "xmm4"); -} -#endif // HAS_HALFFLOATROW_F16C - -#ifdef HAS_HALFFLOATROW_F16C -void HalfFloat1Row_F16C(const uint16_t* src, uint16_t* dst, float, int width) { - asm volatile( - "sub %0,%1 \n" - // 16 pixel loop. - LABELALIGN - "1: \n" - "vpmovzxwd (%0),%%ymm2 \n" // 16 shorts -> 16 ints - "vpmovzxwd 0x10(%0),%%ymm3 \n" - "vcvtdq2ps %%ymm2,%%ymm2 \n" - "vcvtdq2ps %%ymm3,%%ymm3 \n" - "vcvtps2ph $3, %%ymm2, %%xmm2 \n" - "vcvtps2ph $3, %%ymm3, %%xmm3 \n" - "vmovdqu %%xmm2,0x00(%0,%1,1) \n" - "vmovdqu %%xmm3,0x10(%0,%1,1) \n" - "add $0x20,%0 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : - : "memory", "cc", "xmm2", "xmm3"); -} -#endif // HAS_HALFFLOATROW_F16C - -#ifdef HAS_ARGBCOLORTABLEROW_X86 -// Tranform ARGB pixels with color table. -void ARGBColorTableRow_X86(uint8_t* dst_argb, - const uint8_t* table_argb, - int width) { - uintptr_t pixel_temp; - asm volatile( - // 1 pixel loop. - LABELALIGN - "1: \n" - "movzb (%0),%1 \n" - "lea 0x4(%0),%0 \n" - "movzb 0x00(%3,%1,4),%1 \n" - "mov %b1,-0x4(%0) \n" - "movzb -0x3(%0),%1 \n" - "movzb 0x01(%3,%1,4),%1 \n" - "mov %b1,-0x3(%0) \n" - "movzb -0x2(%0),%1 \n" - "movzb 0x02(%3,%1,4),%1 \n" - "mov %b1,-0x2(%0) \n" - "movzb -0x1(%0),%1 \n" - "movzb 0x03(%3,%1,4),%1 \n" - "mov %b1,-0x1(%0) \n" - "dec %2 \n" - "jg 1b \n" - : "+r"(dst_argb), // %0 - "=&d"(pixel_temp), // %1 - "+r"(width) // %2 - : "r"(table_argb) // %3 - : "memory", "cc"); -} -#endif // HAS_ARGBCOLORTABLEROW_X86 - -#ifdef HAS_RGBCOLORTABLEROW_X86 -// Tranform RGB pixels with color table. -void RGBColorTableRow_X86(uint8_t* dst_argb, - const uint8_t* table_argb, - int width) { - uintptr_t pixel_temp; - asm volatile( - // 1 pixel loop. - LABELALIGN - "1: \n" - "movzb (%0),%1 \n" - "lea 0x4(%0),%0 \n" - "movzb 0x00(%3,%1,4),%1 \n" - "mov %b1,-0x4(%0) \n" - "movzb -0x3(%0),%1 \n" - "movzb 0x01(%3,%1,4),%1 \n" - "mov %b1,-0x3(%0) \n" - "movzb -0x2(%0),%1 \n" - "movzb 0x02(%3,%1,4),%1 \n" - "mov %b1,-0x2(%0) \n" - "dec %2 \n" - "jg 1b \n" - : "+r"(dst_argb), // %0 - "=&d"(pixel_temp), // %1 - "+r"(width) // %2 - : "r"(table_argb) // %3 - : "memory", "cc"); -} -#endif // HAS_RGBCOLORTABLEROW_X86 - -#ifdef HAS_ARGBLUMACOLORTABLEROW_SSSE3 -// Tranform RGB pixels with luma table. -void ARGBLumaColorTableRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_argb, - int width, - const uint8_t* luma, - uint32_t lumacoeff) { - uintptr_t pixel_temp; - uintptr_t table_temp; - asm volatile( - "movd %6,%%xmm3 \n" - "pshufd $0x0,%%xmm3,%%xmm3 \n" - "pcmpeqb %%xmm4,%%xmm4 \n" - "psllw $0x8,%%xmm4 \n" - "pxor %%xmm5,%%xmm5 \n" - - // 4 pixel loop. - LABELALIGN - "1: \n" - "movdqu (%2),%%xmm0 \n" - "pmaddubsw %%xmm3,%%xmm0 \n" - "phaddw %%xmm0,%%xmm0 \n" - "pand %%xmm4,%%xmm0 \n" - "punpcklwd %%xmm5,%%xmm0 \n" - "movd %%xmm0,%k1 \n" // 32 bit offset - "add %5,%1 \n" - "pshufd $0x39,%%xmm0,%%xmm0 \n" - - "movzb (%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,(%3) \n" - "movzb 0x1(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0x1(%3) \n" - "movzb 0x2(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0x2(%3) \n" - "movzb 0x3(%2),%0 \n" - "mov %b0,0x3(%3) \n" - - "movd %%xmm0,%k1 \n" // 32 bit offset - "add %5,%1 \n" - "pshufd $0x39,%%xmm0,%%xmm0 \n" - - "movzb 0x4(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0x4(%3) \n" - "movzb 0x5(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0x5(%3) \n" - "movzb 0x6(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0x6(%3) \n" - "movzb 0x7(%2),%0 \n" - "mov %b0,0x7(%3) \n" - - "movd %%xmm0,%k1 \n" // 32 bit offset - "add %5,%1 \n" - "pshufd $0x39,%%xmm0,%%xmm0 \n" - - "movzb 0x8(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0x8(%3) \n" - "movzb 0x9(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0x9(%3) \n" - "movzb 0xa(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0xa(%3) \n" - "movzb 0xb(%2),%0 \n" - "mov %b0,0xb(%3) \n" - - "movd %%xmm0,%k1 \n" // 32 bit offset - "add %5,%1 \n" - - "movzb 0xc(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0xc(%3) \n" - "movzb 0xd(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0xd(%3) \n" - "movzb 0xe(%2),%0 \n" - "movzb 0x00(%1,%0,1),%0 \n" - "mov %b0,0xe(%3) \n" - "movzb 0xf(%2),%0 \n" - "mov %b0,0xf(%3) \n" - "lea 0x10(%2),%2 \n" - "lea 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 - : "memory", "cc", "xmm0", "xmm3", "xmm4", "xmm5"); -} -#endif // HAS_ARGBLUMACOLORTABLEROW_SSSE3 - -#endif // defined(__x86_64__) || defined(__i386__) - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_msa.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_msa.cc deleted file mode 100644 index 4fb2631f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_msa.cc +++ /dev/null @@ -1,3512 +0,0 @@ -/* - * Copyright 2016 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "libyuv/row.h" - -// This module is for GCC MSA -#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) -#include "libyuv/macros_msa.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -#define ALPHA_VAL (-1) - -// Fill YUV -> RGB conversion constants into vectors -#define YUVTORGB_SETUP(yuvconst, ub, vr, ug, vg, bb, bg, br, yg) \ - { \ - ub = __msa_fill_w(yuvconst->kUVToB[0]); \ - vr = __msa_fill_w(yuvconst->kUVToR[1]); \ - ug = __msa_fill_w(yuvconst->kUVToG[0]); \ - vg = __msa_fill_w(yuvconst->kUVToG[1]); \ - bb = __msa_fill_w(yuvconst->kUVBiasB[0]); \ - bg = __msa_fill_w(yuvconst->kUVBiasG[0]); \ - br = __msa_fill_w(yuvconst->kUVBiasR[0]); \ - yg = __msa_fill_w(yuvconst->kYToRgb[0]); \ - } - -// Load YUV 422 pixel data -#define READYUV422(psrc_y, psrc_u, psrc_v, out_y, out_u, out_v) \ - { \ - uint64_t y_m; \ - uint32_t u_m, v_m; \ - v4i32 zero_m = {0}; \ - y_m = LD(psrc_y); \ - u_m = LW(psrc_u); \ - v_m = LW(psrc_v); \ - out_y = (v16u8)__msa_insert_d((v2i64)zero_m, 0, (int64_t)y_m); \ - out_u = (v16u8)__msa_insert_w(zero_m, 0, (int32_t)u_m); \ - out_v = (v16u8)__msa_insert_w(zero_m, 0, (int32_t)v_m); \ - } - -// Clip input vector elements between 0 to 255 -#define CLIP_0TO255(in0, in1, in2, in3, in4, in5) \ - { \ - v4i32 max_m = __msa_ldi_w(0xFF); \ - \ - in0 = __msa_maxi_s_w(in0, 0); \ - in1 = __msa_maxi_s_w(in1, 0); \ - in2 = __msa_maxi_s_w(in2, 0); \ - in3 = __msa_maxi_s_w(in3, 0); \ - in4 = __msa_maxi_s_w(in4, 0); \ - in5 = __msa_maxi_s_w(in5, 0); \ - in0 = __msa_min_s_w(max_m, in0); \ - in1 = __msa_min_s_w(max_m, in1); \ - in2 = __msa_min_s_w(max_m, in2); \ - in3 = __msa_min_s_w(max_m, in3); \ - in4 = __msa_min_s_w(max_m, in4); \ - in5 = __msa_min_s_w(max_m, in5); \ - } - -// Convert 8 pixels of YUV 420 to RGB. -#define YUVTORGB(in_y, in_uv, ubvr, ugvg, bb, bg, br, yg, out_b, out_g, out_r) \ - { \ - v8i16 vec0_m, vec1_m; \ - v4i32 reg0_m, reg1_m, reg2_m, reg3_m, reg4_m; \ - v4i32 reg5_m, reg6_m, reg7_m; \ - v16i8 zero_m = {0}; \ - \ - vec0_m = (v8i16)__msa_ilvr_b((v16i8)in_y, (v16i8)in_y); \ - vec1_m = (v8i16)__msa_ilvr_b((v16i8)zero_m, (v16i8)in_uv); \ - reg0_m = (v4i32)__msa_ilvr_h((v8i16)zero_m, (v8i16)vec0_m); \ - reg1_m = (v4i32)__msa_ilvl_h((v8i16)zero_m, (v8i16)vec0_m); \ - reg2_m = (v4i32)__msa_ilvr_h((v8i16)zero_m, (v8i16)vec1_m); \ - reg3_m = (v4i32)__msa_ilvl_h((v8i16)zero_m, (v8i16)vec1_m); \ - reg0_m *= yg; \ - reg1_m *= yg; \ - reg2_m *= ubvr; \ - reg3_m *= ubvr; \ - reg0_m = __msa_srai_w(reg0_m, 16); \ - reg1_m = __msa_srai_w(reg1_m, 16); \ - reg4_m = __msa_dotp_s_w((v8i16)vec1_m, (v8i16)ugvg); \ - reg5_m = __msa_ilvev_w(reg2_m, reg2_m); \ - reg6_m = __msa_ilvev_w(reg3_m, reg3_m); \ - reg7_m = __msa_ilvr_w(reg4_m, reg4_m); \ - reg2_m = __msa_ilvod_w(reg2_m, reg2_m); \ - reg3_m = __msa_ilvod_w(reg3_m, reg3_m); \ - reg4_m = __msa_ilvl_w(reg4_m, reg4_m); \ - reg5_m = reg0_m - reg5_m; \ - reg6_m = reg1_m - reg6_m; \ - reg2_m = reg0_m - reg2_m; \ - reg3_m = reg1_m - reg3_m; \ - reg7_m = reg0_m - reg7_m; \ - reg4_m = reg1_m - reg4_m; \ - reg5_m += bb; \ - reg6_m += bb; \ - reg7_m += bg; \ - reg4_m += bg; \ - reg2_m += br; \ - reg3_m += br; \ - reg5_m = __msa_srai_w(reg5_m, 6); \ - reg6_m = __msa_srai_w(reg6_m, 6); \ - reg7_m = __msa_srai_w(reg7_m, 6); \ - reg4_m = __msa_srai_w(reg4_m, 6); \ - reg2_m = __msa_srai_w(reg2_m, 6); \ - reg3_m = __msa_srai_w(reg3_m, 6); \ - CLIP_0TO255(reg5_m, reg6_m, reg7_m, reg4_m, reg2_m, reg3_m); \ - out_b = __msa_pckev_h((v8i16)reg6_m, (v8i16)reg5_m); \ - out_g = __msa_pckev_h((v8i16)reg4_m, (v8i16)reg7_m); \ - out_r = __msa_pckev_h((v8i16)reg3_m, (v8i16)reg2_m); \ - } - -// Pack and Store 8 ARGB values. -#define STOREARGB(in0, in1, in2, in3, pdst_argb) \ - { \ - v8i16 vec0_m, vec1_m; \ - v16u8 dst0_m, dst1_m; \ - vec0_m = (v8i16)__msa_ilvev_b((v16i8)in1, (v16i8)in0); \ - vec1_m = (v8i16)__msa_ilvev_b((v16i8)in3, (v16i8)in2); \ - dst0_m = (v16u8)__msa_ilvr_h(vec1_m, vec0_m); \ - dst1_m = (v16u8)__msa_ilvl_h(vec1_m, vec0_m); \ - ST_UB2(dst0_m, dst1_m, pdst_argb, 16); \ - } - -// Takes ARGB input and calculates Y. -#define ARGBTOY(argb0, argb1, argb2, argb3, const0, const1, const2, shift, \ - y_out) \ - { \ - v16u8 vec0_m, vec1_m, vec2_m, vec3_m; \ - v8u16 reg0_m, reg1_m; \ - \ - vec0_m = (v16u8)__msa_pckev_h((v8i16)argb1, (v8i16)argb0); \ - vec1_m = (v16u8)__msa_pckev_h((v8i16)argb3, (v8i16)argb2); \ - vec2_m = (v16u8)__msa_pckod_h((v8i16)argb1, (v8i16)argb0); \ - vec3_m = (v16u8)__msa_pckod_h((v8i16)argb3, (v8i16)argb2); \ - reg0_m = __msa_dotp_u_h(vec0_m, const0); \ - reg1_m = __msa_dotp_u_h(vec1_m, const0); \ - reg0_m = __msa_dpadd_u_h(reg0_m, vec2_m, const1); \ - reg1_m = __msa_dpadd_u_h(reg1_m, vec3_m, const1); \ - reg0_m += const2; \ - reg1_m += const2; \ - reg0_m = (v8u16)__msa_srai_h((v8i16)reg0_m, shift); \ - reg1_m = (v8u16)__msa_srai_h((v8i16)reg1_m, shift); \ - y_out = (v16u8)__msa_pckev_b((v16i8)reg1_m, (v16i8)reg0_m); \ - } - -// Loads current and next row of ARGB input and averages it to calculate U and V -#define READ_ARGB(s_ptr, t_ptr, argb0, argb1, argb2, argb3) \ - { \ - v16u8 src0_m, src1_m, src2_m, src3_m, src4_m, src5_m, src6_m, src7_m; \ - v16u8 vec0_m, vec1_m, vec2_m, vec3_m, vec4_m, vec5_m, vec6_m, vec7_m; \ - v16u8 vec8_m, vec9_m; \ - v8u16 reg0_m, reg1_m, reg2_m, reg3_m, reg4_m, reg5_m, reg6_m, reg7_m; \ - v8u16 reg8_m, reg9_m; \ - \ - src0_m = (v16u8)__msa_ld_b((v16i8*)s, 0); \ - src1_m = (v16u8)__msa_ld_b((v16i8*)s, 16); \ - src2_m = (v16u8)__msa_ld_b((v16i8*)s, 32); \ - src3_m = (v16u8)__msa_ld_b((v16i8*)s, 48); \ - src4_m = (v16u8)__msa_ld_b((v16i8*)t, 0); \ - src5_m = (v16u8)__msa_ld_b((v16i8*)t, 16); \ - src6_m = (v16u8)__msa_ld_b((v16i8*)t, 32); \ - src7_m = (v16u8)__msa_ld_b((v16i8*)t, 48); \ - vec0_m = (v16u8)__msa_ilvr_b((v16i8)src0_m, (v16i8)src4_m); \ - vec1_m = (v16u8)__msa_ilvr_b((v16i8)src1_m, (v16i8)src5_m); \ - vec2_m = (v16u8)__msa_ilvr_b((v16i8)src2_m, (v16i8)src6_m); \ - vec3_m = (v16u8)__msa_ilvr_b((v16i8)src3_m, (v16i8)src7_m); \ - vec4_m = (v16u8)__msa_ilvl_b((v16i8)src0_m, (v16i8)src4_m); \ - vec5_m = (v16u8)__msa_ilvl_b((v16i8)src1_m, (v16i8)src5_m); \ - vec6_m = (v16u8)__msa_ilvl_b((v16i8)src2_m, (v16i8)src6_m); \ - vec7_m = (v16u8)__msa_ilvl_b((v16i8)src3_m, (v16i8)src7_m); \ - reg0_m = __msa_hadd_u_h(vec0_m, vec0_m); \ - reg1_m = __msa_hadd_u_h(vec1_m, vec1_m); \ - reg2_m = __msa_hadd_u_h(vec2_m, vec2_m); \ - reg3_m = __msa_hadd_u_h(vec3_m, vec3_m); \ - reg4_m = __msa_hadd_u_h(vec4_m, vec4_m); \ - reg5_m = __msa_hadd_u_h(vec5_m, vec5_m); \ - reg6_m = __msa_hadd_u_h(vec6_m, vec6_m); \ - reg7_m = __msa_hadd_u_h(vec7_m, vec7_m); \ - reg8_m = (v8u16)__msa_pckev_d((v2i64)reg4_m, (v2i64)reg0_m); \ - reg9_m = (v8u16)__msa_pckev_d((v2i64)reg5_m, (v2i64)reg1_m); \ - reg8_m += (v8u16)__msa_pckod_d((v2i64)reg4_m, (v2i64)reg0_m); \ - reg9_m += (v8u16)__msa_pckod_d((v2i64)reg5_m, (v2i64)reg1_m); \ - reg0_m = (v8u16)__msa_pckev_d((v2i64)reg6_m, (v2i64)reg2_m); \ - reg1_m = (v8u16)__msa_pckev_d((v2i64)reg7_m, (v2i64)reg3_m); \ - reg0_m += (v8u16)__msa_pckod_d((v2i64)reg6_m, (v2i64)reg2_m); \ - reg1_m += (v8u16)__msa_pckod_d((v2i64)reg7_m, (v2i64)reg3_m); \ - reg8_m = (v8u16)__msa_srai_h((v8i16)reg8_m, 2); \ - reg9_m = (v8u16)__msa_srai_h((v8i16)reg9_m, 2); \ - reg0_m = (v8u16)__msa_srai_h((v8i16)reg0_m, 2); \ - reg1_m = (v8u16)__msa_srai_h((v8i16)reg1_m, 2); \ - argb0 = (v16u8)__msa_pckev_b((v16i8)reg9_m, (v16i8)reg8_m); \ - argb1 = (v16u8)__msa_pckev_b((v16i8)reg1_m, (v16i8)reg0_m); \ - src0_m = (v16u8)__msa_ld_b((v16i8*)s, 64); \ - src1_m = (v16u8)__msa_ld_b((v16i8*)s, 80); \ - src2_m = (v16u8)__msa_ld_b((v16i8*)s, 96); \ - src3_m = (v16u8)__msa_ld_b((v16i8*)s, 112); \ - src4_m = (v16u8)__msa_ld_b((v16i8*)t, 64); \ - src5_m = (v16u8)__msa_ld_b((v16i8*)t, 80); \ - src6_m = (v16u8)__msa_ld_b((v16i8*)t, 96); \ - src7_m = (v16u8)__msa_ld_b((v16i8*)t, 112); \ - vec2_m = (v16u8)__msa_ilvr_b((v16i8)src0_m, (v16i8)src4_m); \ - vec3_m = (v16u8)__msa_ilvr_b((v16i8)src1_m, (v16i8)src5_m); \ - vec4_m = (v16u8)__msa_ilvr_b((v16i8)src2_m, (v16i8)src6_m); \ - vec5_m = (v16u8)__msa_ilvr_b((v16i8)src3_m, (v16i8)src7_m); \ - vec6_m = (v16u8)__msa_ilvl_b((v16i8)src0_m, (v16i8)src4_m); \ - vec7_m = (v16u8)__msa_ilvl_b((v16i8)src1_m, (v16i8)src5_m); \ - vec8_m = (v16u8)__msa_ilvl_b((v16i8)src2_m, (v16i8)src6_m); \ - vec9_m = (v16u8)__msa_ilvl_b((v16i8)src3_m, (v16i8)src7_m); \ - reg0_m = __msa_hadd_u_h(vec2_m, vec2_m); \ - reg1_m = __msa_hadd_u_h(vec3_m, vec3_m); \ - reg2_m = __msa_hadd_u_h(vec4_m, vec4_m); \ - reg3_m = __msa_hadd_u_h(vec5_m, vec5_m); \ - reg4_m = __msa_hadd_u_h(vec6_m, vec6_m); \ - reg5_m = __msa_hadd_u_h(vec7_m, vec7_m); \ - reg6_m = __msa_hadd_u_h(vec8_m, vec8_m); \ - reg7_m = __msa_hadd_u_h(vec9_m, vec9_m); \ - reg8_m = (v8u16)__msa_pckev_d((v2i64)reg4_m, (v2i64)reg0_m); \ - reg9_m = (v8u16)__msa_pckev_d((v2i64)reg5_m, (v2i64)reg1_m); \ - reg8_m += (v8u16)__msa_pckod_d((v2i64)reg4_m, (v2i64)reg0_m); \ - reg9_m += (v8u16)__msa_pckod_d((v2i64)reg5_m, (v2i64)reg1_m); \ - reg0_m = (v8u16)__msa_pckev_d((v2i64)reg6_m, (v2i64)reg2_m); \ - reg1_m = (v8u16)__msa_pckev_d((v2i64)reg7_m, (v2i64)reg3_m); \ - reg0_m += (v8u16)__msa_pckod_d((v2i64)reg6_m, (v2i64)reg2_m); \ - reg1_m += (v8u16)__msa_pckod_d((v2i64)reg7_m, (v2i64)reg3_m); \ - reg8_m = (v8u16)__msa_srai_h((v8i16)reg8_m, 2); \ - reg9_m = (v8u16)__msa_srai_h((v8i16)reg9_m, 2); \ - reg0_m = (v8u16)__msa_srai_h((v8i16)reg0_m, 2); \ - reg1_m = (v8u16)__msa_srai_h((v8i16)reg1_m, 2); \ - argb2 = (v16u8)__msa_pckev_b((v16i8)reg9_m, (v16i8)reg8_m); \ - argb3 = (v16u8)__msa_pckev_b((v16i8)reg1_m, (v16i8)reg0_m); \ - } - -// Takes ARGB input and calculates U and V. -#define ARGBTOUV(argb0, argb1, argb2, argb3, const0, const1, const2, const3, \ - shf0, shf1, shf2, shf3, v_out, u_out) \ - { \ - v16u8 vec0_m, vec1_m, vec2_m, vec3_m, vec4_m, vec5_m, vec6_m, vec7_m; \ - v8u16 reg0_m, reg1_m, reg2_m, reg3_m; \ - \ - vec0_m = (v16u8)__msa_vshf_b(shf0, (v16i8)argb1, (v16i8)argb0); \ - vec1_m = (v16u8)__msa_vshf_b(shf0, (v16i8)argb3, (v16i8)argb2); \ - vec2_m = (v16u8)__msa_vshf_b(shf1, (v16i8)argb1, (v16i8)argb0); \ - vec3_m = (v16u8)__msa_vshf_b(shf1, (v16i8)argb3, (v16i8)argb2); \ - vec4_m = (v16u8)__msa_vshf_b(shf2, (v16i8)argb1, (v16i8)argb0); \ - vec5_m = (v16u8)__msa_vshf_b(shf2, (v16i8)argb3, (v16i8)argb2); \ - vec6_m = (v16u8)__msa_vshf_b(shf3, (v16i8)argb1, (v16i8)argb0); \ - vec7_m = (v16u8)__msa_vshf_b(shf3, (v16i8)argb3, (v16i8)argb2); \ - reg0_m = __msa_dotp_u_h(vec0_m, const1); \ - reg1_m = __msa_dotp_u_h(vec1_m, const1); \ - reg2_m = __msa_dotp_u_h(vec4_m, const1); \ - reg3_m = __msa_dotp_u_h(vec5_m, const1); \ - reg0_m += const3; \ - reg1_m += const3; \ - reg2_m += const3; \ - reg3_m += const3; \ - reg0_m -= __msa_dotp_u_h(vec2_m, const0); \ - reg1_m -= __msa_dotp_u_h(vec3_m, const0); \ - reg2_m -= __msa_dotp_u_h(vec6_m, const2); \ - reg3_m -= __msa_dotp_u_h(vec7_m, const2); \ - v_out = (v16u8)__msa_pckod_b((v16i8)reg1_m, (v16i8)reg0_m); \ - u_out = (v16u8)__msa_pckod_b((v16i8)reg3_m, (v16i8)reg2_m); \ - } - -// Load I444 pixel data -#define READI444(psrc_y, psrc_u, psrc_v, out_y, out_u, out_v) \ - { \ - uint64_t y_m, u_m, v_m; \ - v2i64 zero_m = {0}; \ - y_m = LD(psrc_y); \ - u_m = LD(psrc_u); \ - v_m = LD(psrc_v); \ - out_y = (v16u8)__msa_insert_d(zero_m, 0, (int64_t)y_m); \ - out_u = (v16u8)__msa_insert_d(zero_m, 0, (int64_t)u_m); \ - out_v = (v16u8)__msa_insert_d(zero_m, 0, (int64_t)v_m); \ - } - -void MirrorRow_MSA(const uint8_t* src, uint8_t* dst, int width) { - int x; - v16u8 src0, src1, src2, src3; - v16u8 dst0, dst1, dst2, dst3; - v16i8 shuffler = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; - src += width - 64; - - for (x = 0; x < width; x += 64) { - LD_UB4(src, 16, src3, src2, src1, src0); - VSHF_B2_UB(src3, src3, src2, src2, shuffler, shuffler, dst3, dst2); - VSHF_B2_UB(src1, src1, src0, src0, shuffler, shuffler, dst1, dst0); - ST_UB4(dst0, dst1, dst2, dst3, dst, 16); - dst += 64; - src -= 64; - } -} - -void ARGBMirrorRow_MSA(const uint8_t* src, uint8_t* dst, int width) { - int x; - v16u8 src0, src1, src2, src3; - v16u8 dst0, dst1, dst2, dst3; - v16i8 shuffler = {12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3}; - src += width * 4 - 64; - - for (x = 0; x < width; x += 16) { - LD_UB4(src, 16, src3, src2, src1, src0); - VSHF_B2_UB(src3, src3, src2, src2, shuffler, shuffler, dst3, dst2); - VSHF_B2_UB(src1, src1, src0, src0, shuffler, shuffler, dst1, dst0); - ST_UB4(dst0, dst1, dst2, dst3, dst, 16); - dst += 64; - src -= 64; - } -} - -void I422ToYUY2Row_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_yuy2, - int width) { - int x; - v16u8 src_u0, src_v0, src_y0, src_y1, vec_uv0, vec_uv1; - v16u8 dst_yuy2_0, dst_yuy2_1, dst_yuy2_2, dst_yuy2_3; - - for (x = 0; x < width; x += 32) { - src_u0 = LD_UB(src_u); - src_v0 = LD_UB(src_v); - LD_UB2(src_y, 16, src_y0, src_y1); - ILVRL_B2_UB(src_v0, src_u0, vec_uv0, vec_uv1); - ILVRL_B2_UB(vec_uv0, src_y0, dst_yuy2_0, dst_yuy2_1); - ILVRL_B2_UB(vec_uv1, src_y1, dst_yuy2_2, dst_yuy2_3); - ST_UB4(dst_yuy2_0, dst_yuy2_1, dst_yuy2_2, dst_yuy2_3, dst_yuy2, 16); - src_u += 16; - src_v += 16; - src_y += 32; - dst_yuy2 += 64; - } -} - -void I422ToUYVYRow_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uyvy, - int width) { - int x; - v16u8 src_u0, src_v0, src_y0, src_y1, vec_uv0, vec_uv1; - v16u8 dst_uyvy0, dst_uyvy1, dst_uyvy2, dst_uyvy3; - - for (x = 0; x < width; x += 32) { - src_u0 = LD_UB(src_u); - src_v0 = LD_UB(src_v); - LD_UB2(src_y, 16, src_y0, src_y1); - ILVRL_B2_UB(src_v0, src_u0, vec_uv0, vec_uv1); - ILVRL_B2_UB(src_y0, vec_uv0, dst_uyvy0, dst_uyvy1); - ILVRL_B2_UB(src_y1, vec_uv1, dst_uyvy2, dst_uyvy3); - ST_UB4(dst_uyvy0, dst_uyvy1, dst_uyvy2, dst_uyvy3, dst_uyvy, 16); - src_u += 16; - src_v += 16; - src_y += 32; - dst_uyvy += 64; - } -} - -void I422ToARGBRow_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - int x; - v16u8 src0, src1, src2; - v8i16 vec0, vec1, vec2; - v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; - v4i32 vec_ubvr, vec_ugvg; - v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); - - YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, - vec_br, vec_yg); - vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); - vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); - - for (x = 0; x < width; x += 8) { - READYUV422(src_y, src_u, src_v, src0, src1, src2); - src1 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src1); - YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, - vec0, vec1, vec2); - STOREARGB(vec0, vec1, vec2, alpha, dst_argb); - src_y += 8; - src_u += 4; - src_v += 4; - dst_argb += 32; - } -} - -void I422ToRGBARow_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - int x; - v16u8 src0, src1, src2; - v8i16 vec0, vec1, vec2; - v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; - v4i32 vec_ubvr, vec_ugvg; - v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); - - YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, - vec_br, vec_yg); - vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); - vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); - - for (x = 0; x < width; x += 8) { - READYUV422(src_y, src_u, src_v, src0, src1, src2); - src1 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src1); - YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, - vec0, vec1, vec2); - STOREARGB(alpha, vec0, vec1, vec2, dst_argb); - src_y += 8; - src_u += 4; - src_v += 4; - dst_argb += 32; - } -} - -void I422AlphaToARGBRow_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - const uint8_t* src_a, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - int x; - int64_t data_a; - v16u8 src0, src1, src2, src3; - v8i16 vec0, vec1, vec2; - v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; - v4i32 vec_ubvr, vec_ugvg; - v4i32 zero = {0}; - - YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, - vec_br, vec_yg); - vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); - vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); - - for (x = 0; x < width; x += 8) { - data_a = LD(src_a); - READYUV422(src_y, src_u, src_v, src0, src1, src2); - src1 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src1); - src3 = (v16u8)__msa_insert_d((v2i64)zero, 0, data_a); - YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, - vec0, vec1, vec2); - src3 = (v16u8)__msa_ilvr_b((v16i8)src3, (v16i8)src3); - STOREARGB(vec0, vec1, vec2, src3, dst_argb); - src_y += 8; - src_u += 4; - src_v += 4; - src_a += 8; - dst_argb += 32; - } -} - -void I422ToRGB24Row_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int32_t width) { - int x; - int64_t data_u, data_v; - v16u8 src0, src1, src2, src3, src4, dst0, dst1, dst2; - v8i16 vec0, vec1, vec2, vec3, vec4, vec5; - v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; - v4i32 vec_ubvr, vec_ugvg; - v16u8 reg0, reg1, reg2, reg3; - v2i64 zero = {0}; - v16i8 shuffler0 = {0, 1, 16, 2, 3, 17, 4, 5, 18, 6, 7, 19, 8, 9, 20, 10}; - v16i8 shuffler1 = {0, 21, 1, 2, 22, 3, 4, 23, 5, 6, 24, 7, 8, 25, 9, 10}; - v16i8 shuffler2 = {26, 6, 7, 27, 8, 9, 28, 10, - 11, 29, 12, 13, 30, 14, 15, 31}; - - YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, - vec_br, vec_yg); - vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); - vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((v16u8*)src_y, 0); - data_u = LD(src_u); - data_v = LD(src_v); - src1 = (v16u8)__msa_insert_d(zero, 0, data_u); - src2 = (v16u8)__msa_insert_d(zero, 0, data_v); - src1 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src1); - src3 = (v16u8)__msa_sldi_b((v16i8)src0, (v16i8)src0, 8); - src4 = (v16u8)__msa_sldi_b((v16i8)src1, (v16i8)src1, 8); - YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, - vec0, vec1, vec2); - YUVTORGB(src3, src4, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, - vec3, vec4, vec5); - reg0 = (v16u8)__msa_ilvev_b((v16i8)vec1, (v16i8)vec0); - reg2 = (v16u8)__msa_ilvev_b((v16i8)vec4, (v16i8)vec3); - reg3 = (v16u8)__msa_pckev_b((v16i8)vec5, (v16i8)vec2); - reg1 = (v16u8)__msa_sldi_b((v16i8)reg2, (v16i8)reg0, 11); - dst0 = (v16u8)__msa_vshf_b(shuffler0, (v16i8)reg3, (v16i8)reg0); - dst1 = (v16u8)__msa_vshf_b(shuffler1, (v16i8)reg3, (v16i8)reg1); - dst2 = (v16u8)__msa_vshf_b(shuffler2, (v16i8)reg3, (v16i8)reg2); - ST_UB2(dst0, dst1, dst_argb, 16); - ST_UB(dst2, (dst_argb + 32)); - src_y += 16; - src_u += 8; - src_v += 8; - dst_argb += 48; - } -} - -// TODO(fbarchard): Consider AND instead of shift to isolate 5 upper bits of R. -void I422ToRGB565Row_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width) { - int x; - v16u8 src0, src1, src2, dst0; - v8i16 vec0, vec1, vec2; - v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; - v4i32 vec_ubvr, vec_ugvg; - - YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, - vec_br, vec_yg); - vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); - vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); - - for (x = 0; x < width; x += 8) { - READYUV422(src_y, src_u, src_v, src0, src1, src2); - src1 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src1); - YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, - vec0, vec2, vec1); - vec0 = __msa_srai_h(vec0, 3); - vec1 = __msa_srai_h(vec1, 3); - vec2 = __msa_srai_h(vec2, 2); - vec1 = __msa_slli_h(vec1, 11); - vec2 = __msa_slli_h(vec2, 5); - vec0 |= vec1; - dst0 = (v16u8)(vec2 | vec0); - ST_UB(dst0, dst_rgb565); - src_y += 8; - src_u += 4; - src_v += 4; - dst_rgb565 += 16; - } -} - -// TODO(fbarchard): Consider AND instead of shift to isolate 4 upper bits of G. -void I422ToARGB4444Row_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb4444, - const struct YuvConstants* yuvconstants, - int width) { - int x; - v16u8 src0, src1, src2, dst0; - v8i16 vec0, vec1, vec2; - v8u16 reg0, reg1, reg2; - v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; - v4i32 vec_ubvr, vec_ugvg; - v8u16 const_0xF000 = (v8u16)__msa_fill_h(0xF000); - - YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, - vec_br, vec_yg); - vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); - vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); - - for (x = 0; x < width; x += 8) { - READYUV422(src_y, src_u, src_v, src0, src1, src2); - src1 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src1); - YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, - vec0, vec1, vec2); - reg0 = (v8u16)__msa_srai_h(vec0, 4); - reg1 = (v8u16)__msa_srai_h(vec1, 4); - reg2 = (v8u16)__msa_srai_h(vec2, 4); - reg1 = (v8u16)__msa_slli_h((v8i16)reg1, 4); - reg2 = (v8u16)__msa_slli_h((v8i16)reg2, 8); - reg1 |= const_0xF000; - reg0 |= reg2; - dst0 = (v16u8)(reg1 | reg0); - ST_UB(dst0, dst_argb4444); - src_y += 8; - src_u += 4; - src_v += 4; - dst_argb4444 += 16; - } -} - -void I422ToARGB1555Row_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb1555, - const struct YuvConstants* yuvconstants, - int width) { - int x; - v16u8 src0, src1, src2, dst0; - v8i16 vec0, vec1, vec2; - v8u16 reg0, reg1, reg2; - v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; - v4i32 vec_ubvr, vec_ugvg; - v8u16 const_0x8000 = (v8u16)__msa_fill_h(0x8000); - - YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, - vec_br, vec_yg); - vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); - vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); - - for (x = 0; x < width; x += 8) { - READYUV422(src_y, src_u, src_v, src0, src1, src2); - src1 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src1); - YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, - vec0, vec1, vec2); - reg0 = (v8u16)__msa_srai_h(vec0, 3); - reg1 = (v8u16)__msa_srai_h(vec1, 3); - reg2 = (v8u16)__msa_srai_h(vec2, 3); - reg1 = (v8u16)__msa_slli_h((v8i16)reg1, 5); - reg2 = (v8u16)__msa_slli_h((v8i16)reg2, 10); - reg1 |= const_0x8000; - reg0 |= reg2; - dst0 = (v16u8)(reg1 | reg0); - ST_UB(dst0, dst_argb1555); - src_y += 8; - src_u += 4; - src_v += 4; - dst_argb1555 += 16; - } -} - -void YUY2ToYRow_MSA(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { - int x; - v16u8 src0, src1, src2, src3, dst0, dst1; - - for (x = 0; x < width; x += 32) { - LD_UB4(src_yuy2, 16, src0, src1, src2, src3); - dst0 = (v16u8)__msa_pckev_b((v16i8)src1, (v16i8)src0); - dst1 = (v16u8)__msa_pckev_b((v16i8)src3, (v16i8)src2); - ST_UB2(dst0, dst1, dst_y, 16); - src_yuy2 += 64; - dst_y += 32; - } -} - -void YUY2ToUVRow_MSA(const uint8_t* src_yuy2, - int src_stride_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - const uint8_t* src_yuy2_next = src_yuy2 + src_stride_yuy2; - int x; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v16u8 vec0, vec1, dst0, dst1; - - for (x = 0; x < width; x += 32) { - LD_UB4(src_yuy2, 16, src0, src1, src2, src3); - LD_UB4(src_yuy2_next, 16, src4, src5, src6, src7); - src0 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0); - src1 = (v16u8)__msa_pckod_b((v16i8)src3, (v16i8)src2); - src2 = (v16u8)__msa_pckod_b((v16i8)src5, (v16i8)src4); - src3 = (v16u8)__msa_pckod_b((v16i8)src7, (v16i8)src6); - vec0 = __msa_aver_u_b(src0, src2); - vec1 = __msa_aver_u_b(src1, src3); - dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - dst1 = (v16u8)__msa_pckod_b((v16i8)vec1, (v16i8)vec0); - ST_UB(dst0, dst_u); - ST_UB(dst1, dst_v); - src_yuy2 += 64; - src_yuy2_next += 64; - dst_u += 16; - dst_v += 16; - } -} - -void YUY2ToUV422Row_MSA(const uint8_t* src_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - int x; - v16u8 src0, src1, src2, src3, dst0, dst1; - - for (x = 0; x < width; x += 32) { - LD_UB4(src_yuy2, 16, src0, src1, src2, src3); - src0 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0); - src1 = (v16u8)__msa_pckod_b((v16i8)src3, (v16i8)src2); - dst0 = (v16u8)__msa_pckev_b((v16i8)src1, (v16i8)src0); - dst1 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0); - ST_UB(dst0, dst_u); - ST_UB(dst1, dst_v); - src_yuy2 += 64; - dst_u += 16; - dst_v += 16; - } -} - -void UYVYToYRow_MSA(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { - int x; - v16u8 src0, src1, src2, src3, dst0, dst1; - - for (x = 0; x < width; x += 32) { - LD_UB4(src_uyvy, 16, src0, src1, src2, src3); - dst0 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0); - dst1 = (v16u8)__msa_pckod_b((v16i8)src3, (v16i8)src2); - ST_UB2(dst0, dst1, dst_y, 16); - src_uyvy += 64; - dst_y += 32; - } -} - -void UYVYToUVRow_MSA(const uint8_t* src_uyvy, - int src_stride_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - const uint8_t* src_uyvy_next = src_uyvy + src_stride_uyvy; - int x; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v16u8 vec0, vec1, dst0, dst1; - - for (x = 0; x < width; x += 32) { - LD_UB4(src_uyvy, 16, src0, src1, src2, src3); - LD_UB4(src_uyvy_next, 16, src4, src5, src6, src7); - src0 = (v16u8)__msa_pckev_b((v16i8)src1, (v16i8)src0); - src1 = (v16u8)__msa_pckev_b((v16i8)src3, (v16i8)src2); - src2 = (v16u8)__msa_pckev_b((v16i8)src5, (v16i8)src4); - src3 = (v16u8)__msa_pckev_b((v16i8)src7, (v16i8)src6); - vec0 = __msa_aver_u_b(src0, src2); - vec1 = __msa_aver_u_b(src1, src3); - dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - dst1 = (v16u8)__msa_pckod_b((v16i8)vec1, (v16i8)vec0); - ST_UB(dst0, dst_u); - ST_UB(dst1, dst_v); - src_uyvy += 64; - src_uyvy_next += 64; - dst_u += 16; - dst_v += 16; - } -} - -void UYVYToUV422Row_MSA(const uint8_t* src_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - int x; - v16u8 src0, src1, src2, src3, dst0, dst1; - - for (x = 0; x < width; x += 32) { - LD_UB4(src_uyvy, 16, src0, src1, src2, src3); - src0 = (v16u8)__msa_pckev_b((v16i8)src1, (v16i8)src0); - src1 = (v16u8)__msa_pckev_b((v16i8)src3, (v16i8)src2); - dst0 = (v16u8)__msa_pckev_b((v16i8)src1, (v16i8)src0); - dst1 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0); - ST_UB(dst0, dst_u); - ST_UB(dst1, dst_v); - src_uyvy += 64; - dst_u += 16; - dst_v += 16; - } -} - -void ARGBToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width) { - int x; - v16u8 src0, src1, src2, src3, vec0, vec1, vec2, vec3, dst0; - v8u16 reg0, reg1, reg2, reg3, reg4, reg5; - v16i8 zero = {0}; - v8u16 const_0x19 = (v8u16)__msa_ldi_h(0x19); - v8u16 const_0x81 = (v8u16)__msa_ldi_h(0x81); - v8u16 const_0x42 = (v8u16)__msa_ldi_h(0x42); - v8u16 const_0x1080 = (v8u16)__msa_fill_h(0x1080); - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((v16u8*)src_argb0, 0); - src1 = (v16u8)__msa_ld_b((v16u8*)src_argb0, 16); - src2 = (v16u8)__msa_ld_b((v16u8*)src_argb0, 32); - src3 = (v16u8)__msa_ld_b((v16u8*)src_argb0, 48); - vec0 = (v16u8)__msa_pckev_b((v16i8)src1, (v16i8)src0); - vec1 = (v16u8)__msa_pckev_b((v16i8)src3, (v16i8)src2); - vec2 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0); - vec3 = (v16u8)__msa_pckod_b((v16i8)src3, (v16i8)src2); - reg0 = (v8u16)__msa_ilvev_b(zero, (v16i8)vec0); - reg1 = (v8u16)__msa_ilvev_b(zero, (v16i8)vec1); - reg2 = (v8u16)__msa_ilvev_b(zero, (v16i8)vec2); - reg3 = (v8u16)__msa_ilvev_b(zero, (v16i8)vec3); - reg4 = (v8u16)__msa_ilvod_b(zero, (v16i8)vec0); - reg5 = (v8u16)__msa_ilvod_b(zero, (v16i8)vec1); - reg0 *= const_0x19; - reg1 *= const_0x19; - reg2 *= const_0x81; - reg3 *= const_0x81; - reg4 *= const_0x42; - reg5 *= const_0x42; - reg0 += reg2; - reg1 += reg3; - reg0 += reg4; - reg1 += reg5; - reg0 += const_0x1080; - reg1 += const_0x1080; - reg0 = (v8u16)__msa_srai_h((v8i16)reg0, 8); - reg1 = (v8u16)__msa_srai_h((v8i16)reg1, 8); - dst0 = (v16u8)__msa_pckev_b((v16i8)reg1, (v16i8)reg0); - ST_UB(dst0, dst_y); - src_argb0 += 64; - dst_y += 16; - } -} - -void ARGBToUVRow_MSA(const uint8_t* src_argb0, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - int x; - const uint8_t* src_argb0_next = src_argb0 + src_stride_argb; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9; - v8u16 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9; - v16u8 dst0, dst1; - v8u16 const_0x70 = (v8u16)__msa_ldi_h(0x70); - v8u16 const_0x4A = (v8u16)__msa_ldi_h(0x4A); - v8u16 const_0x26 = (v8u16)__msa_ldi_h(0x26); - v8u16 const_0x5E = (v8u16)__msa_ldi_h(0x5E); - v8u16 const_0x12 = (v8u16)__msa_ldi_h(0x12); - v8u16 const_0x8080 = (v8u16)__msa_fill_h(0x8080); - - for (x = 0; x < width; x += 32) { - src0 = (v16u8)__msa_ld_b((v16u8*)src_argb0, 0); - src1 = (v16u8)__msa_ld_b((v16u8*)src_argb0, 16); - src2 = (v16u8)__msa_ld_b((v16u8*)src_argb0, 32); - src3 = (v16u8)__msa_ld_b((v16u8*)src_argb0, 48); - src4 = (v16u8)__msa_ld_b((v16u8*)src_argb0, 64); - src5 = (v16u8)__msa_ld_b((v16u8*)src_argb0, 80); - src6 = (v16u8)__msa_ld_b((v16u8*)src_argb0, 96); - src7 = (v16u8)__msa_ld_b((v16u8*)src_argb0, 112); - vec0 = (v16u8)__msa_pckev_b((v16i8)src1, (v16i8)src0); - vec1 = (v16u8)__msa_pckev_b((v16i8)src3, (v16i8)src2); - vec2 = (v16u8)__msa_pckev_b((v16i8)src5, (v16i8)src4); - vec3 = (v16u8)__msa_pckev_b((v16i8)src7, (v16i8)src6); - vec4 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0); - vec5 = (v16u8)__msa_pckod_b((v16i8)src3, (v16i8)src2); - vec6 = (v16u8)__msa_pckod_b((v16i8)src5, (v16i8)src4); - vec7 = (v16u8)__msa_pckod_b((v16i8)src7, (v16i8)src6); - vec8 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - vec9 = (v16u8)__msa_pckev_b((v16i8)vec3, (v16i8)vec2); - vec4 = (v16u8)__msa_pckev_b((v16i8)vec5, (v16i8)vec4); - vec5 = (v16u8)__msa_pckev_b((v16i8)vec7, (v16i8)vec6); - vec0 = (v16u8)__msa_pckod_b((v16i8)vec1, (v16i8)vec0); - vec1 = (v16u8)__msa_pckod_b((v16i8)vec3, (v16i8)vec2); - reg0 = __msa_hadd_u_h(vec8, vec8); - reg1 = __msa_hadd_u_h(vec9, vec9); - reg2 = __msa_hadd_u_h(vec4, vec4); - reg3 = __msa_hadd_u_h(vec5, vec5); - reg4 = __msa_hadd_u_h(vec0, vec0); - reg5 = __msa_hadd_u_h(vec1, vec1); - src0 = (v16u8)__msa_ld_b((v16u8*)src_argb0_next, 0); - src1 = (v16u8)__msa_ld_b((v16u8*)src_argb0_next, 16); - src2 = (v16u8)__msa_ld_b((v16u8*)src_argb0_next, 32); - src3 = (v16u8)__msa_ld_b((v16u8*)src_argb0_next, 48); - src4 = (v16u8)__msa_ld_b((v16u8*)src_argb0_next, 64); - src5 = (v16u8)__msa_ld_b((v16u8*)src_argb0_next, 80); - src6 = (v16u8)__msa_ld_b((v16u8*)src_argb0_next, 96); - src7 = (v16u8)__msa_ld_b((v16u8*)src_argb0_next, 112); - vec0 = (v16u8)__msa_pckev_b((v16i8)src1, (v16i8)src0); - vec1 = (v16u8)__msa_pckev_b((v16i8)src3, (v16i8)src2); - vec2 = (v16u8)__msa_pckev_b((v16i8)src5, (v16i8)src4); - vec3 = (v16u8)__msa_pckev_b((v16i8)src7, (v16i8)src6); - vec4 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0); - vec5 = (v16u8)__msa_pckod_b((v16i8)src3, (v16i8)src2); - vec6 = (v16u8)__msa_pckod_b((v16i8)src5, (v16i8)src4); - vec7 = (v16u8)__msa_pckod_b((v16i8)src7, (v16i8)src6); - vec8 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - vec9 = (v16u8)__msa_pckev_b((v16i8)vec3, (v16i8)vec2); - vec4 = (v16u8)__msa_pckev_b((v16i8)vec5, (v16i8)vec4); - vec5 = (v16u8)__msa_pckev_b((v16i8)vec7, (v16i8)vec6); - vec0 = (v16u8)__msa_pckod_b((v16i8)vec1, (v16i8)vec0); - vec1 = (v16u8)__msa_pckod_b((v16i8)vec3, (v16i8)vec2); - reg0 += __msa_hadd_u_h(vec8, vec8); - reg1 += __msa_hadd_u_h(vec9, vec9); - reg2 += __msa_hadd_u_h(vec4, vec4); - reg3 += __msa_hadd_u_h(vec5, vec5); - reg4 += __msa_hadd_u_h(vec0, vec0); - reg5 += __msa_hadd_u_h(vec1, vec1); - reg0 = (v8u16)__msa_srai_h((v8i16)reg0, 2); - reg1 = (v8u16)__msa_srai_h((v8i16)reg1, 2); - reg2 = (v8u16)__msa_srai_h((v8i16)reg2, 2); - reg3 = (v8u16)__msa_srai_h((v8i16)reg3, 2); - reg4 = (v8u16)__msa_srai_h((v8i16)reg4, 2); - reg5 = (v8u16)__msa_srai_h((v8i16)reg5, 2); - reg6 = reg0 * const_0x70; - reg7 = reg1 * const_0x70; - reg8 = reg2 * const_0x4A; - reg9 = reg3 * const_0x4A; - reg6 += const_0x8080; - reg7 += const_0x8080; - reg8 += reg4 * const_0x26; - reg9 += reg5 * const_0x26; - reg0 *= const_0x12; - reg1 *= const_0x12; - reg2 *= const_0x5E; - reg3 *= const_0x5E; - reg4 *= const_0x70; - reg5 *= const_0x70; - reg2 += reg0; - reg3 += reg1; - reg4 += const_0x8080; - reg5 += const_0x8080; - reg6 -= reg8; - reg7 -= reg9; - reg4 -= reg2; - reg5 -= reg3; - reg6 = (v8u16)__msa_srai_h((v8i16)reg6, 8); - reg7 = (v8u16)__msa_srai_h((v8i16)reg7, 8); - reg4 = (v8u16)__msa_srai_h((v8i16)reg4, 8); - reg5 = (v8u16)__msa_srai_h((v8i16)reg5, 8); - dst0 = (v16u8)__msa_pckev_b((v16i8)reg7, (v16i8)reg6); - dst1 = (v16u8)__msa_pckev_b((v16i8)reg5, (v16i8)reg4); - ST_UB(dst0, dst_u); - ST_UB(dst1, dst_v); - src_argb0 += 128; - src_argb0_next += 128; - dst_u += 16; - dst_v += 16; - } -} - -void ARGBToRGB24Row_MSA(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { - int x; - v16u8 src0, src1, src2, src3, dst0, dst1, dst2; - v16i8 shuffler0 = {0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 18, 20}; - v16i8 shuffler1 = {5, 6, 8, 9, 10, 12, 13, 14, - 16, 17, 18, 20, 21, 22, 24, 25}; - v16i8 shuffler2 = {10, 12, 13, 14, 16, 17, 18, 20, - 21, 22, 24, 25, 26, 28, 29, 30}; - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 32); - src3 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 48); - dst0 = (v16u8)__msa_vshf_b(shuffler0, (v16i8)src1, (v16i8)src0); - dst1 = (v16u8)__msa_vshf_b(shuffler1, (v16i8)src2, (v16i8)src1); - dst2 = (v16u8)__msa_vshf_b(shuffler2, (v16i8)src3, (v16i8)src2); - ST_UB2(dst0, dst1, dst_rgb, 16); - ST_UB(dst2, (dst_rgb + 32)); - src_argb += 64; - dst_rgb += 48; - } -} - -void ARGBToRAWRow_MSA(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { - int x; - v16u8 src0, src1, src2, src3, dst0, dst1, dst2; - v16i8 shuffler0 = {2, 1, 0, 6, 5, 4, 10, 9, 8, 14, 13, 12, 18, 17, 16, 22}; - v16i8 shuffler1 = {5, 4, 10, 9, 8, 14, 13, 12, - 18, 17, 16, 22, 21, 20, 26, 25}; - v16i8 shuffler2 = {8, 14, 13, 12, 18, 17, 16, 22, - 21, 20, 26, 25, 24, 30, 29, 28}; - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 32); - src3 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 48); - dst0 = (v16u8)__msa_vshf_b(shuffler0, (v16i8)src1, (v16i8)src0); - dst1 = (v16u8)__msa_vshf_b(shuffler1, (v16i8)src2, (v16i8)src1); - dst2 = (v16u8)__msa_vshf_b(shuffler2, (v16i8)src3, (v16i8)src2); - ST_UB2(dst0, dst1, dst_rgb, 16); - ST_UB(dst2, (dst_rgb + 32)); - src_argb += 64; - dst_rgb += 48; - } -} - -void ARGBToRGB565Row_MSA(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { - int x; - v16u8 src0, src1, dst0; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v16i8 zero = {0}; - - for (x = 0; x < width; x += 8) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 16); - vec0 = (v16u8)__msa_srai_b((v16i8)src0, 3); - vec1 = (v16u8)__msa_slli_b((v16i8)src0, 3); - vec2 = (v16u8)__msa_srai_b((v16i8)src0, 5); - vec4 = (v16u8)__msa_srai_b((v16i8)src1, 3); - vec5 = (v16u8)__msa_slli_b((v16i8)src1, 3); - vec6 = (v16u8)__msa_srai_b((v16i8)src1, 5); - vec1 = (v16u8)__msa_sldi_b(zero, (v16i8)vec1, 1); - vec2 = (v16u8)__msa_sldi_b(zero, (v16i8)vec2, 1); - vec5 = (v16u8)__msa_sldi_b(zero, (v16i8)vec5, 1); - vec6 = (v16u8)__msa_sldi_b(zero, (v16i8)vec6, 1); - vec3 = (v16u8)__msa_sldi_b(zero, (v16i8)src0, 2); - vec7 = (v16u8)__msa_sldi_b(zero, (v16i8)src1, 2); - vec0 = __msa_binsli_b(vec0, vec1, 2); - vec1 = __msa_binsli_b(vec2, vec3, 4); - vec4 = __msa_binsli_b(vec4, vec5, 2); - vec5 = __msa_binsli_b(vec6, vec7, 4); - vec0 = (v16u8)__msa_ilvev_b((v16i8)vec1, (v16i8)vec0); - vec4 = (v16u8)__msa_ilvev_b((v16i8)vec5, (v16i8)vec4); - dst0 = (v16u8)__msa_pckev_h((v8i16)vec4, (v8i16)vec0); - ST_UB(dst0, dst_rgb); - src_argb += 32; - dst_rgb += 16; - } -} - -void ARGBToARGB1555Row_MSA(const uint8_t* src_argb, - uint8_t* dst_rgb, - int width) { - int x; - v16u8 src0, src1, dst0; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9; - v16i8 zero = {0}; - - for (x = 0; x < width; x += 8) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 16); - vec0 = (v16u8)__msa_srai_b((v16i8)src0, 3); - vec1 = (v16u8)__msa_slli_b((v16i8)src0, 2); - vec2 = (v16u8)__msa_srai_b((v16i8)vec0, 3); - vec1 = (v16u8)__msa_sldi_b(zero, (v16i8)vec1, 1); - vec2 = (v16u8)__msa_sldi_b(zero, (v16i8)vec2, 1); - vec3 = (v16u8)__msa_srai_b((v16i8)src0, 1); - vec5 = (v16u8)__msa_srai_b((v16i8)src1, 3); - vec6 = (v16u8)__msa_slli_b((v16i8)src1, 2); - vec7 = (v16u8)__msa_srai_b((v16i8)vec5, 3); - vec6 = (v16u8)__msa_sldi_b(zero, (v16i8)vec6, 1); - vec7 = (v16u8)__msa_sldi_b(zero, (v16i8)vec7, 1); - vec8 = (v16u8)__msa_srai_b((v16i8)src1, 1); - vec3 = (v16u8)__msa_sldi_b(zero, (v16i8)vec3, 2); - vec8 = (v16u8)__msa_sldi_b(zero, (v16i8)vec8, 2); - vec4 = (v16u8)__msa_sldi_b(zero, (v16i8)src0, 3); - vec9 = (v16u8)__msa_sldi_b(zero, (v16i8)src1, 3); - vec0 = __msa_binsli_b(vec0, vec1, 2); - vec5 = __msa_binsli_b(vec5, vec6, 2); - vec1 = __msa_binsli_b(vec2, vec3, 5); - vec6 = __msa_binsli_b(vec7, vec8, 5); - vec1 = __msa_binsli_b(vec1, vec4, 0); - vec6 = __msa_binsli_b(vec6, vec9, 0); - vec0 = (v16u8)__msa_ilvev_b((v16i8)vec1, (v16i8)vec0); - vec1 = (v16u8)__msa_ilvev_b((v16i8)vec6, (v16i8)vec5); - dst0 = (v16u8)__msa_pckev_h((v8i16)vec1, (v8i16)vec0); - ST_UB(dst0, dst_rgb); - src_argb += 32; - dst_rgb += 16; - } -} - -void ARGBToARGB4444Row_MSA(const uint8_t* src_argb, - uint8_t* dst_rgb, - int width) { - int x; - v16u8 src0, src1; - v16u8 vec0, vec1; - v16u8 dst0; - v16i8 zero = {0}; - - for (x = 0; x < width; x += 8) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 16); - vec0 = (v16u8)__msa_srai_b((v16i8)src0, 4); - vec1 = (v16u8)__msa_srai_b((v16i8)src1, 4); - src0 = (v16u8)__msa_sldi_b(zero, (v16i8)src0, 1); - src1 = (v16u8)__msa_sldi_b(zero, (v16i8)src1, 1); - vec0 = __msa_binsli_b(vec0, src0, 3); - vec1 = __msa_binsli_b(vec1, src1, 3); - dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - ST_UB(dst0, dst_rgb); - src_argb += 32; - dst_rgb += 16; - } -} - -void ARGBToUV444Row_MSA(const uint8_t* src_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int32_t width) { - int32_t x; - v16u8 src0, src1, src2, src3, reg0, reg1, reg2, reg3, dst0, dst1; - v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8u16 vec8, vec9, vec10, vec11; - v8u16 const_112 = (v8u16)__msa_ldi_h(112); - v8u16 const_74 = (v8u16)__msa_ldi_h(74); - v8u16 const_38 = (v8u16)__msa_ldi_h(38); - v8u16 const_94 = (v8u16)__msa_ldi_h(94); - v8u16 const_18 = (v8u16)__msa_ldi_h(18); - v8u16 const_32896 = (v8u16)__msa_fill_h(32896); - v16i8 zero = {0}; - - for (x = width; x > 0; x -= 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 32); - src3 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 48); - reg0 = (v16u8)__msa_pckev_b((v16i8)src1, (v16i8)src0); - reg1 = (v16u8)__msa_pckev_b((v16i8)src3, (v16i8)src2); - reg2 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0); - reg3 = (v16u8)__msa_pckod_b((v16i8)src3, (v16i8)src2); - src0 = (v16u8)__msa_pckev_b((v16i8)reg1, (v16i8)reg0); - src1 = (v16u8)__msa_pckev_b((v16i8)reg3, (v16i8)reg2); - src2 = (v16u8)__msa_pckod_b((v16i8)reg1, (v16i8)reg0); - vec0 = (v8u16)__msa_ilvr_b(zero, (v16i8)src0); - vec1 = (v8u16)__msa_ilvl_b(zero, (v16i8)src0); - vec2 = (v8u16)__msa_ilvr_b(zero, (v16i8)src1); - vec3 = (v8u16)__msa_ilvl_b(zero, (v16i8)src1); - vec4 = (v8u16)__msa_ilvr_b(zero, (v16i8)src2); - vec5 = (v8u16)__msa_ilvl_b(zero, (v16i8)src2); - vec10 = vec0 * const_18; - vec11 = vec1 * const_18; - vec8 = vec2 * const_94; - vec9 = vec3 * const_94; - vec6 = vec4 * const_112; - vec7 = vec5 * const_112; - vec0 *= const_112; - vec1 *= const_112; - vec2 *= const_74; - vec3 *= const_74; - vec4 *= const_38; - vec5 *= const_38; - vec8 += vec10; - vec9 += vec11; - vec6 += const_32896; - vec7 += const_32896; - vec0 += const_32896; - vec1 += const_32896; - vec2 += vec4; - vec3 += vec5; - vec0 -= vec2; - vec1 -= vec3; - vec6 -= vec8; - vec7 -= vec9; - vec0 = (v8u16)__msa_srai_h((v8i16)vec0, 8); - vec1 = (v8u16)__msa_srai_h((v8i16)vec1, 8); - vec6 = (v8u16)__msa_srai_h((v8i16)vec6, 8); - vec7 = (v8u16)__msa_srai_h((v8i16)vec7, 8); - dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - dst1 = (v16u8)__msa_pckev_b((v16i8)vec7, (v16i8)vec6); - ST_UB(dst0, dst_u); - ST_UB(dst1, dst_v); - src_argb += 64; - dst_u += 16; - dst_v += 16; - } -} - -void ARGBMultiplyRow_MSA(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - int x; - v16u8 src0, src1, dst0; - v8u16 vec0, vec1, vec2, vec3; - v4u32 reg0, reg1, reg2, reg3; - v8i16 zero = {0}; - - for (x = 0; x < width; x += 4) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb1, 0); - vec0 = (v8u16)__msa_ilvr_b((v16i8)src0, (v16i8)src0); - vec1 = (v8u16)__msa_ilvl_b((v16i8)src0, (v16i8)src0); - vec2 = (v8u16)__msa_ilvr_b((v16i8)zero, (v16i8)src1); - vec3 = (v8u16)__msa_ilvl_b((v16i8)zero, (v16i8)src1); - reg0 = (v4u32)__msa_ilvr_h(zero, (v8i16)vec0); - reg1 = (v4u32)__msa_ilvl_h(zero, (v8i16)vec0); - reg2 = (v4u32)__msa_ilvr_h(zero, (v8i16)vec1); - reg3 = (v4u32)__msa_ilvl_h(zero, (v8i16)vec1); - reg0 *= (v4u32)__msa_ilvr_h(zero, (v8i16)vec2); - reg1 *= (v4u32)__msa_ilvl_h(zero, (v8i16)vec2); - reg2 *= (v4u32)__msa_ilvr_h(zero, (v8i16)vec3); - reg3 *= (v4u32)__msa_ilvl_h(zero, (v8i16)vec3); - reg0 = (v4u32)__msa_srai_w((v4i32)reg0, 16); - reg1 = (v4u32)__msa_srai_w((v4i32)reg1, 16); - reg2 = (v4u32)__msa_srai_w((v4i32)reg2, 16); - reg3 = (v4u32)__msa_srai_w((v4i32)reg3, 16); - vec0 = (v8u16)__msa_pckev_h((v8i16)reg1, (v8i16)reg0); - vec1 = (v8u16)__msa_pckev_h((v8i16)reg3, (v8i16)reg2); - dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - ST_UB(dst0, dst_argb); - src_argb0 += 16; - src_argb1 += 16; - dst_argb += 16; - } -} - -void ARGBAddRow_MSA(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - int x; - v16u8 src0, src1, src2, src3, dst0, dst1; - - for (x = 0; x < width; x += 8) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_argb1, 0); - src3 = (v16u8)__msa_ld_b((const v16i8*)src_argb1, 16); - dst0 = __msa_adds_u_b(src0, src2); - dst1 = __msa_adds_u_b(src1, src3); - ST_UB2(dst0, dst1, dst_argb, 16); - src_argb0 += 32; - src_argb1 += 32; - dst_argb += 32; - } -} - -void ARGBSubtractRow_MSA(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - int x; - v16u8 src0, src1, src2, src3, dst0, dst1; - - for (x = 0; x < width; x += 8) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_argb1, 0); - src3 = (v16u8)__msa_ld_b((const v16i8*)src_argb1, 16); - dst0 = __msa_subs_u_b(src0, src2); - dst1 = __msa_subs_u_b(src1, src3); - ST_UB2(dst0, dst1, dst_argb, 16); - src_argb0 += 32; - src_argb1 += 32; - dst_argb += 32; - } -} - -void ARGBAttenuateRow_MSA(const uint8_t* src_argb, - uint8_t* dst_argb, - int width) { - int x; - v16u8 src0, src1, dst0, dst1; - v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9; - v4u32 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; - v8i16 zero = {0}; - v16u8 mask = {0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255}; - - for (x = 0; x < width; x += 8) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 16); - vec0 = (v8u16)__msa_ilvr_b((v16i8)src0, (v16i8)src0); - vec1 = (v8u16)__msa_ilvl_b((v16i8)src0, (v16i8)src0); - vec2 = (v8u16)__msa_ilvr_b((v16i8)src1, (v16i8)src1); - vec3 = (v8u16)__msa_ilvl_b((v16i8)src1, (v16i8)src1); - vec4 = (v8u16)__msa_fill_h(vec0[3]); - vec5 = (v8u16)__msa_fill_h(vec0[7]); - vec6 = (v8u16)__msa_fill_h(vec1[3]); - vec7 = (v8u16)__msa_fill_h(vec1[7]); - vec4 = (v8u16)__msa_pckev_d((v2i64)vec5, (v2i64)vec4); - vec5 = (v8u16)__msa_pckev_d((v2i64)vec7, (v2i64)vec6); - vec6 = (v8u16)__msa_fill_h(vec2[3]); - vec7 = (v8u16)__msa_fill_h(vec2[7]); - vec8 = (v8u16)__msa_fill_h(vec3[3]); - vec9 = (v8u16)__msa_fill_h(vec3[7]); - vec6 = (v8u16)__msa_pckev_d((v2i64)vec7, (v2i64)vec6); - vec7 = (v8u16)__msa_pckev_d((v2i64)vec9, (v2i64)vec8); - reg0 = (v4u32)__msa_ilvr_h(zero, (v8i16)vec4); - reg1 = (v4u32)__msa_ilvl_h(zero, (v8i16)vec4); - reg2 = (v4u32)__msa_ilvr_h(zero, (v8i16)vec5); - reg3 = (v4u32)__msa_ilvl_h(zero, (v8i16)vec5); - reg4 = (v4u32)__msa_ilvr_h(zero, (v8i16)vec6); - reg5 = (v4u32)__msa_ilvl_h(zero, (v8i16)vec6); - reg6 = (v4u32)__msa_ilvr_h(zero, (v8i16)vec7); - reg7 = (v4u32)__msa_ilvl_h(zero, (v8i16)vec7); - reg0 *= (v4u32)__msa_ilvr_h(zero, (v8i16)vec0); - reg1 *= (v4u32)__msa_ilvl_h(zero, (v8i16)vec0); - reg2 *= (v4u32)__msa_ilvr_h(zero, (v8i16)vec1); - reg3 *= (v4u32)__msa_ilvl_h(zero, (v8i16)vec1); - reg4 *= (v4u32)__msa_ilvr_h(zero, (v8i16)vec2); - reg5 *= (v4u32)__msa_ilvl_h(zero, (v8i16)vec2); - reg6 *= (v4u32)__msa_ilvr_h(zero, (v8i16)vec3); - reg7 *= (v4u32)__msa_ilvl_h(zero, (v8i16)vec3); - reg0 = (v4u32)__msa_srai_w((v4i32)reg0, 24); - reg1 = (v4u32)__msa_srai_w((v4i32)reg1, 24); - reg2 = (v4u32)__msa_srai_w((v4i32)reg2, 24); - reg3 = (v4u32)__msa_srai_w((v4i32)reg3, 24); - reg4 = (v4u32)__msa_srai_w((v4i32)reg4, 24); - reg5 = (v4u32)__msa_srai_w((v4i32)reg5, 24); - reg6 = (v4u32)__msa_srai_w((v4i32)reg6, 24); - reg7 = (v4u32)__msa_srai_w((v4i32)reg7, 24); - vec0 = (v8u16)__msa_pckev_h((v8i16)reg1, (v8i16)reg0); - vec1 = (v8u16)__msa_pckev_h((v8i16)reg3, (v8i16)reg2); - vec2 = (v8u16)__msa_pckev_h((v8i16)reg5, (v8i16)reg4); - vec3 = (v8u16)__msa_pckev_h((v8i16)reg7, (v8i16)reg6); - dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - dst1 = (v16u8)__msa_pckev_b((v16i8)vec3, (v16i8)vec2); - dst0 = __msa_bmnz_v(dst0, src0, mask); - dst1 = __msa_bmnz_v(dst1, src1, mask); - ST_UB2(dst0, dst1, dst_argb, 16); - src_argb += 32; - dst_argb += 32; - } -} - -void ARGBToRGB565DitherRow_MSA(const uint8_t* src_argb, - uint8_t* dst_rgb, - uint32_t dither4, - int width) { - int x; - v16u8 src0, src1, dst0, vec0, vec1; - v8i16 vec_d0; - v8i16 reg0, reg1, reg2; - v16i8 zero = {0}; - v8i16 max = __msa_ldi_h(0xFF); - - vec_d0 = (v8i16)__msa_fill_w(dither4); - vec_d0 = (v8i16)__msa_ilvr_b(zero, (v16i8)vec_d0); - - for (x = 0; x < width; x += 8) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 16); - vec0 = (v16u8)__msa_pckev_b((v16i8)src1, (v16i8)src0); - vec1 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0); - reg0 = (v8i16)__msa_ilvev_b(zero, (v16i8)vec0); - reg1 = (v8i16)__msa_ilvev_b(zero, (v16i8)vec1); - reg2 = (v8i16)__msa_ilvod_b(zero, (v16i8)vec0); - reg0 += vec_d0; - reg1 += vec_d0; - reg2 += vec_d0; - reg0 = __msa_maxi_s_h((v8i16)reg0, 0); - reg1 = __msa_maxi_s_h((v8i16)reg1, 0); - reg2 = __msa_maxi_s_h((v8i16)reg2, 0); - reg0 = __msa_min_s_h((v8i16)max, (v8i16)reg0); - reg1 = __msa_min_s_h((v8i16)max, (v8i16)reg1); - reg2 = __msa_min_s_h((v8i16)max, (v8i16)reg2); - reg0 = __msa_srai_h(reg0, 3); - reg2 = __msa_srai_h(reg2, 3); - reg1 = __msa_srai_h(reg1, 2); - reg2 = __msa_slli_h(reg2, 11); - reg1 = __msa_slli_h(reg1, 5); - reg0 |= reg1; - dst0 = (v16u8)(reg0 | reg2); - ST_UB(dst0, dst_rgb); - src_argb += 32; - dst_rgb += 16; - } -} - -void ARGBShuffleRow_MSA(const uint8_t* src_argb, - uint8_t* dst_argb, - const uint8_t* shuffler, - int width) { - int x; - v16u8 src0, src1, dst0, dst1; - v16i8 vec0; - v16i8 shuffler_vec = {0, 0, 0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, 12, 12, 12}; - int32_t val = LW((int32_t*)shuffler); - - vec0 = (v16i8)__msa_fill_w(val); - shuffler_vec += vec0; - - for (x = 0; x < width; x += 8) { - src0 = (v16u8)__msa_ld_b((const v16u8*)src_argb, 0); - src1 = (v16u8)__msa_ld_b((const v16u8*)src_argb, 16); - dst0 = (v16u8)__msa_vshf_b(shuffler_vec, (v16i8)src0, (v16i8)src0); - dst1 = (v16u8)__msa_vshf_b(shuffler_vec, (v16i8)src1, (v16i8)src1); - ST_UB2(dst0, dst1, dst_argb, 16); - src_argb += 32; - dst_argb += 32; - } -} - -void ARGBShadeRow_MSA(const uint8_t* src_argb, - uint8_t* dst_argb, - int width, - uint32_t value) { - int x; - v16u8 src0, dst0; - v8u16 vec0, vec1; - v4u32 reg0, reg1, reg2, reg3, rgba_scale; - v8i16 zero = {0}; - - rgba_scale[0] = value; - rgba_scale = (v4u32)__msa_ilvr_b((v16i8)rgba_scale, (v16i8)rgba_scale); - rgba_scale = (v4u32)__msa_ilvr_h(zero, (v8i16)rgba_scale); - - for (x = 0; x < width; x += 4) { - src0 = (v16u8)__msa_ld_b((const v16u8*)src_argb, 0); - vec0 = (v8u16)__msa_ilvr_b((v16i8)src0, (v16i8)src0); - vec1 = (v8u16)__msa_ilvl_b((v16i8)src0, (v16i8)src0); - reg0 = (v4u32)__msa_ilvr_h(zero, (v8i16)vec0); - reg1 = (v4u32)__msa_ilvl_h(zero, (v8i16)vec0); - reg2 = (v4u32)__msa_ilvr_h(zero, (v8i16)vec1); - reg3 = (v4u32)__msa_ilvl_h(zero, (v8i16)vec1); - reg0 *= rgba_scale; - reg1 *= rgba_scale; - reg2 *= rgba_scale; - reg3 *= rgba_scale; - reg0 = (v4u32)__msa_srai_w((v4i32)reg0, 24); - reg1 = (v4u32)__msa_srai_w((v4i32)reg1, 24); - reg2 = (v4u32)__msa_srai_w((v4i32)reg2, 24); - reg3 = (v4u32)__msa_srai_w((v4i32)reg3, 24); - vec0 = (v8u16)__msa_pckev_h((v8i16)reg1, (v8i16)reg0); - vec1 = (v8u16)__msa_pckev_h((v8i16)reg3, (v8i16)reg2); - dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - ST_UB(dst0, dst_argb); - src_argb += 16; - dst_argb += 16; - } -} - -void ARGBGrayRow_MSA(const uint8_t* src_argb, uint8_t* dst_argb, int width) { - int x; - v16u8 src0, src1, vec0, vec1, dst0, dst1; - v8u16 reg0; - v16u8 const_0x26 = (v16u8)__msa_ldi_h(0x26); - v16u8 const_0x4B0F = (v16u8)__msa_fill_h(0x4B0F); - - for (x = 0; x < width; x += 8) { - src0 = (v16u8)__msa_ld_b((const v16u8*)src_argb, 0); - src1 = (v16u8)__msa_ld_b((const v16u8*)src_argb, 16); - vec0 = (v16u8)__msa_pckev_h((v8i16)src1, (v8i16)src0); - vec1 = (v16u8)__msa_pckod_h((v8i16)src1, (v8i16)src0); - reg0 = __msa_dotp_u_h(vec0, const_0x4B0F); - reg0 = __msa_dpadd_u_h(reg0, vec1, const_0x26); - reg0 = (v8u16)__msa_srari_h((v8i16)reg0, 7); - vec0 = (v16u8)__msa_ilvev_b((v16i8)reg0, (v16i8)reg0); - vec1 = (v16u8)__msa_ilvod_b((v16i8)vec1, (v16i8)vec0); - dst0 = (v16u8)__msa_ilvr_b((v16i8)vec1, (v16i8)vec0); - dst1 = (v16u8)__msa_ilvl_b((v16i8)vec1, (v16i8)vec0); - ST_UB2(dst0, dst1, dst_argb, 16); - src_argb += 32; - dst_argb += 32; - } -} - -void ARGBSepiaRow_MSA(uint8_t* dst_argb, int width) { - int x; - v16u8 src0, src1, dst0, dst1, vec0, vec1, vec2, vec3, vec4, vec5; - v8u16 reg0, reg1, reg2; - v16u8 const_0x4411 = (v16u8)__msa_fill_h(0x4411); - v16u8 const_0x23 = (v16u8)__msa_ldi_h(0x23); - v16u8 const_0x5816 = (v16u8)__msa_fill_h(0x5816); - v16u8 const_0x2D = (v16u8)__msa_ldi_h(0x2D); - v16u8 const_0x6218 = (v16u8)__msa_fill_h(0x6218); - v16u8 const_0x32 = (v16u8)__msa_ldi_h(0x32); - v8u16 const_0xFF = (v8u16)__msa_ldi_h(0xFF); - - for (x = 0; x < width; x += 8) { - src0 = (v16u8)__msa_ld_b((v16u8*)dst_argb, 0); - src1 = (v16u8)__msa_ld_b((v16u8*)dst_argb, 16); - vec0 = (v16u8)__msa_pckev_h((v8i16)src1, (v8i16)src0); - vec1 = (v16u8)__msa_pckod_h((v8i16)src1, (v8i16)src0); - vec3 = (v16u8)__msa_pckod_b((v16i8)vec1, (v16i8)vec1); - reg0 = (v8u16)__msa_dotp_u_h(vec0, const_0x4411); - reg1 = (v8u16)__msa_dotp_u_h(vec0, const_0x5816); - reg2 = (v8u16)__msa_dotp_u_h(vec0, const_0x6218); - reg0 = (v8u16)__msa_dpadd_u_h(reg0, vec1, const_0x23); - reg1 = (v8u16)__msa_dpadd_u_h(reg1, vec1, const_0x2D); - reg2 = (v8u16)__msa_dpadd_u_h(reg2, vec1, const_0x32); - reg0 = (v8u16)__msa_srai_h((v8i16)reg0, 7); - reg1 = (v8u16)__msa_srai_h((v8i16)reg1, 7); - reg2 = (v8u16)__msa_srai_h((v8i16)reg2, 7); - reg1 = (v8u16)__msa_min_u_h((v8u16)reg1, const_0xFF); - reg2 = (v8u16)__msa_min_u_h((v8u16)reg2, const_0xFF); - vec0 = (v16u8)__msa_pckev_b((v16i8)reg0, (v16i8)reg0); - vec1 = (v16u8)__msa_pckev_b((v16i8)reg1, (v16i8)reg1); - vec2 = (v16u8)__msa_pckev_b((v16i8)reg2, (v16i8)reg2); - vec4 = (v16u8)__msa_ilvr_b((v16i8)vec2, (v16i8)vec0); - vec5 = (v16u8)__msa_ilvr_b((v16i8)vec3, (v16i8)vec1); - dst0 = (v16u8)__msa_ilvr_b((v16i8)vec5, (v16i8)vec4); - dst1 = (v16u8)__msa_ilvl_b((v16i8)vec5, (v16i8)vec4); - ST_UB2(dst0, dst1, dst_argb, 16); - dst_argb += 32; - } -} - -void ARGB4444ToARGBRow_MSA(const uint8_t* src_argb4444, - uint8_t* dst_argb, - int width) { - int x; - v16u8 src0, src1; - v8u16 vec0, vec1, vec2, vec3; - v16u8 dst0, dst1, dst2, dst3; - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16u8*)src_argb4444, 0); - src1 = (v16u8)__msa_ld_b((const v16u8*)src_argb4444, 16); - vec0 = (v8u16)__msa_andi_b(src0, 0x0F); - vec1 = (v8u16)__msa_andi_b(src1, 0x0F); - vec2 = (v8u16)__msa_andi_b(src0, 0xF0); - vec3 = (v8u16)__msa_andi_b(src1, 0xF0); - vec0 |= (v8u16)__msa_slli_b((v16i8)vec0, 4); - vec1 |= (v8u16)__msa_slli_b((v16i8)vec1, 4); - vec2 |= (v8u16)__msa_srli_b((v16i8)vec2, 4); - vec3 |= (v8u16)__msa_srli_b((v16i8)vec3, 4); - dst0 = (v16u8)__msa_ilvr_b((v16i8)vec2, (v16i8)vec0); - dst1 = (v16u8)__msa_ilvl_b((v16i8)vec2, (v16i8)vec0); - dst2 = (v16u8)__msa_ilvr_b((v16i8)vec3, (v16i8)vec1); - dst3 = (v16u8)__msa_ilvl_b((v16i8)vec3, (v16i8)vec1); - ST_UB4(dst0, dst1, dst2, dst3, dst_argb, 16); - src_argb4444 += 32; - dst_argb += 64; - } -} - -void ARGB1555ToARGBRow_MSA(const uint8_t* src_argb1555, - uint8_t* dst_argb, - int width) { - int x; - v8u16 src0, src1; - v8u16 vec0, vec1, vec2, vec3, vec4, vec5; - v16u8 reg0, reg1, reg2, reg3, reg4, reg5, reg6; - v16u8 dst0, dst1, dst2, dst3; - v8u16 const_0x1F = (v8u16)__msa_ldi_h(0x1F); - - for (x = 0; x < width; x += 16) { - src0 = (v8u16)__msa_ld_h((const v8u16*)src_argb1555, 0); - src1 = (v8u16)__msa_ld_h((const v8u16*)src_argb1555, 16); - vec0 = src0 & const_0x1F; - vec1 = src1 & const_0x1F; - src0 = (v8u16)__msa_srli_h((v8i16)src0, 5); - src1 = (v8u16)__msa_srli_h((v8i16)src1, 5); - vec2 = src0 & const_0x1F; - vec3 = src1 & const_0x1F; - src0 = (v8u16)__msa_srli_h((v8i16)src0, 5); - src1 = (v8u16)__msa_srli_h((v8i16)src1, 5); - vec4 = src0 & const_0x1F; - vec5 = src1 & const_0x1F; - src0 = (v8u16)__msa_srli_h((v8i16)src0, 5); - src1 = (v8u16)__msa_srli_h((v8i16)src1, 5); - reg0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - reg1 = (v16u8)__msa_pckev_b((v16i8)vec3, (v16i8)vec2); - reg2 = (v16u8)__msa_pckev_b((v16i8)vec5, (v16i8)vec4); - reg3 = (v16u8)__msa_pckev_b((v16i8)src1, (v16i8)src0); - reg4 = (v16u8)__msa_slli_b((v16i8)reg0, 3); - reg5 = (v16u8)__msa_slli_b((v16i8)reg1, 3); - reg6 = (v16u8)__msa_slli_b((v16i8)reg2, 3); - reg4 |= (v16u8)__msa_srai_b((v16i8)reg0, 2); - reg5 |= (v16u8)__msa_srai_b((v16i8)reg1, 2); - reg6 |= (v16u8)__msa_srai_b((v16i8)reg2, 2); - reg3 = -reg3; - reg0 = (v16u8)__msa_ilvr_b((v16i8)reg6, (v16i8)reg4); - reg1 = (v16u8)__msa_ilvl_b((v16i8)reg6, (v16i8)reg4); - reg2 = (v16u8)__msa_ilvr_b((v16i8)reg3, (v16i8)reg5); - reg3 = (v16u8)__msa_ilvl_b((v16i8)reg3, (v16i8)reg5); - dst0 = (v16u8)__msa_ilvr_b((v16i8)reg2, (v16i8)reg0); - dst1 = (v16u8)__msa_ilvl_b((v16i8)reg2, (v16i8)reg0); - dst2 = (v16u8)__msa_ilvr_b((v16i8)reg3, (v16i8)reg1); - dst3 = (v16u8)__msa_ilvl_b((v16i8)reg3, (v16i8)reg1); - ST_UB4(dst0, dst1, dst2, dst3, dst_argb, 16); - src_argb1555 += 32; - dst_argb += 64; - } -} - -void RGB565ToARGBRow_MSA(const uint8_t* src_rgb565, - uint8_t* dst_argb, - int width) { - int x; - v8u16 src0, src1, vec0, vec1, vec2, vec3, vec4, vec5; - v8u16 reg0, reg1, reg2, reg3, reg4, reg5; - v16u8 res0, res1, res2, res3, dst0, dst1, dst2, dst3; - v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); - v8u16 const_0x1F = (v8u16)__msa_ldi_h(0x1F); - v8u16 const_0x7E0 = (v8u16)__msa_fill_h(0x7E0); - v8u16 const_0xF800 = (v8u16)__msa_fill_h(0xF800); - - for (x = 0; x < width; x += 16) { - src0 = (v8u16)__msa_ld_h((const v8u16*)src_rgb565, 0); - src1 = (v8u16)__msa_ld_h((const v8u16*)src_rgb565, 16); - vec0 = src0 & const_0x1F; - vec1 = src0 & const_0x7E0; - vec2 = src0 & const_0xF800; - vec3 = src1 & const_0x1F; - vec4 = src1 & const_0x7E0; - vec5 = src1 & const_0xF800; - reg0 = (v8u16)__msa_slli_h((v8i16)vec0, 3); - reg1 = (v8u16)__msa_srli_h((v8i16)vec1, 3); - reg2 = (v8u16)__msa_srli_h((v8i16)vec2, 8); - reg3 = (v8u16)__msa_slli_h((v8i16)vec3, 3); - reg4 = (v8u16)__msa_srli_h((v8i16)vec4, 3); - reg5 = (v8u16)__msa_srli_h((v8i16)vec5, 8); - reg0 |= (v8u16)__msa_srli_h((v8i16)vec0, 2); - reg1 |= (v8u16)__msa_srli_h((v8i16)vec1, 9); - reg2 |= (v8u16)__msa_srli_h((v8i16)vec2, 13); - reg3 |= (v8u16)__msa_srli_h((v8i16)vec3, 2); - reg4 |= (v8u16)__msa_srli_h((v8i16)vec4, 9); - reg5 |= (v8u16)__msa_srli_h((v8i16)vec5, 13); - res0 = (v16u8)__msa_ilvev_b((v16i8)reg2, (v16i8)reg0); - res1 = (v16u8)__msa_ilvev_b((v16i8)alpha, (v16i8)reg1); - res2 = (v16u8)__msa_ilvev_b((v16i8)reg5, (v16i8)reg3); - res3 = (v16u8)__msa_ilvev_b((v16i8)alpha, (v16i8)reg4); - dst0 = (v16u8)__msa_ilvr_b((v16i8)res1, (v16i8)res0); - dst1 = (v16u8)__msa_ilvl_b((v16i8)res1, (v16i8)res0); - dst2 = (v16u8)__msa_ilvr_b((v16i8)res3, (v16i8)res2); - dst3 = (v16u8)__msa_ilvl_b((v16i8)res3, (v16i8)res2); - ST_UB4(dst0, dst1, dst2, dst3, dst_argb, 16); - src_rgb565 += 32; - dst_argb += 64; - } -} - -void RGB24ToARGBRow_MSA(const uint8_t* src_rgb24, - uint8_t* dst_argb, - int width) { - int x; - v16u8 src0, src1, src2; - v16u8 vec0, vec1, vec2; - v16u8 dst0, dst1, dst2, dst3; - v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); - v16i8 shuffler = {0, 1, 2, 16, 3, 4, 5, 17, 6, 7, 8, 18, 9, 10, 11, 19}; - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_rgb24, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_rgb24, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_rgb24, 32); - vec0 = (v16u8)__msa_sldi_b((v16i8)src1, (v16i8)src0, 12); - vec1 = (v16u8)__msa_sldi_b((v16i8)src2, (v16i8)src1, 8); - vec2 = (v16u8)__msa_sldi_b((v16i8)src2, (v16i8)src2, 4); - dst0 = (v16u8)__msa_vshf_b(shuffler, (v16i8)alpha, (v16i8)src0); - dst1 = (v16u8)__msa_vshf_b(shuffler, (v16i8)alpha, (v16i8)vec0); - dst2 = (v16u8)__msa_vshf_b(shuffler, (v16i8)alpha, (v16i8)vec1); - dst3 = (v16u8)__msa_vshf_b(shuffler, (v16i8)alpha, (v16i8)vec2); - ST_UB4(dst0, dst1, dst2, dst3, dst_argb, 16); - src_rgb24 += 48; - dst_argb += 64; - } -} - -void RAWToARGBRow_MSA(const uint8_t* src_raw, uint8_t* dst_argb, int width) { - int x; - v16u8 src0, src1, src2; - v16u8 vec0, vec1, vec2; - v16u8 dst0, dst1, dst2, dst3; - v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); - v16i8 mask = {2, 1, 0, 16, 5, 4, 3, 17, 8, 7, 6, 18, 11, 10, 9, 19}; - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_raw, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_raw, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_raw, 32); - vec0 = (v16u8)__msa_sldi_b((v16i8)src1, (v16i8)src0, 12); - vec1 = (v16u8)__msa_sldi_b((v16i8)src2, (v16i8)src1, 8); - vec2 = (v16u8)__msa_sldi_b((v16i8)src2, (v16i8)src2, 4); - dst0 = (v16u8)__msa_vshf_b(mask, (v16i8)alpha, (v16i8)src0); - dst1 = (v16u8)__msa_vshf_b(mask, (v16i8)alpha, (v16i8)vec0); - dst2 = (v16u8)__msa_vshf_b(mask, (v16i8)alpha, (v16i8)vec1); - dst3 = (v16u8)__msa_vshf_b(mask, (v16i8)alpha, (v16i8)vec2); - ST_UB4(dst0, dst1, dst2, dst3, dst_argb, 16); - src_raw += 48; - dst_argb += 64; - } -} - -void ARGB1555ToYRow_MSA(const uint8_t* src_argb1555, - uint8_t* dst_y, - int width) { - int x; - v8u16 src0, src1, vec0, vec1, vec2, vec3, vec4, vec5; - v8u16 reg0, reg1, reg2, reg3, reg4, reg5; - v16u8 dst0; - v8u16 const_0x19 = (v8u16)__msa_ldi_h(0x19); - v8u16 const_0x81 = (v8u16)__msa_ldi_h(0x81); - v8u16 const_0x42 = (v8u16)__msa_ldi_h(0x42); - v8u16 const_0x1F = (v8u16)__msa_ldi_h(0x1F); - v8u16 const_0x1080 = (v8u16)__msa_fill_h(0x1080); - - for (x = 0; x < width; x += 16) { - src0 = (v8u16)__msa_ld_b((const v8i16*)src_argb1555, 0); - src1 = (v8u16)__msa_ld_b((const v8i16*)src_argb1555, 16); - vec0 = src0 & const_0x1F; - vec1 = src1 & const_0x1F; - src0 = (v8u16)__msa_srai_h((v8i16)src0, 5); - src1 = (v8u16)__msa_srai_h((v8i16)src1, 5); - vec2 = src0 & const_0x1F; - vec3 = src1 & const_0x1F; - src0 = (v8u16)__msa_srai_h((v8i16)src0, 5); - src1 = (v8u16)__msa_srai_h((v8i16)src1, 5); - vec4 = src0 & const_0x1F; - vec5 = src1 & const_0x1F; - reg0 = (v8u16)__msa_slli_h((v8i16)vec0, 3); - reg1 = (v8u16)__msa_slli_h((v8i16)vec1, 3); - reg0 |= (v8u16)__msa_srai_h((v8i16)vec0, 2); - reg1 |= (v8u16)__msa_srai_h((v8i16)vec1, 2); - reg2 = (v8u16)__msa_slli_h((v8i16)vec2, 3); - reg3 = (v8u16)__msa_slli_h((v8i16)vec3, 3); - reg2 |= (v8u16)__msa_srai_h((v8i16)vec2, 2); - reg3 |= (v8u16)__msa_srai_h((v8i16)vec3, 2); - reg4 = (v8u16)__msa_slli_h((v8i16)vec4, 3); - reg5 = (v8u16)__msa_slli_h((v8i16)vec5, 3); - reg4 |= (v8u16)__msa_srai_h((v8i16)vec4, 2); - reg5 |= (v8u16)__msa_srai_h((v8i16)vec5, 2); - reg0 *= const_0x19; - reg1 *= const_0x19; - reg2 *= const_0x81; - reg3 *= const_0x81; - reg4 *= const_0x42; - reg5 *= const_0x42; - reg0 += reg2; - reg1 += reg3; - reg0 += reg4; - reg1 += reg5; - reg0 += const_0x1080; - reg1 += const_0x1080; - reg0 = (v8u16)__msa_srai_h((v8i16)reg0, 8); - reg1 = (v8u16)__msa_srai_h((v8i16)reg1, 8); - dst0 = (v16u8)__msa_pckev_b((v16i8)reg1, (v16i8)reg0); - ST_UB(dst0, dst_y); - src_argb1555 += 32; - dst_y += 16; - } -} - -void RGB565ToYRow_MSA(const uint8_t* src_rgb565, uint8_t* dst_y, int width) { - int x; - v8u16 src0, src1, vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8u16 reg0, reg1, reg2, reg3, reg4, reg5; - v4u32 res0, res1, res2, res3; - v16u8 dst0; - v4u32 const_0x810019 = (v4u32)__msa_fill_w(0x810019); - v4u32 const_0x010042 = (v4u32)__msa_fill_w(0x010042); - v8i16 const_0x1080 = __msa_fill_h(0x1080); - v8u16 const_0x1F = (v8u16)__msa_ldi_h(0x1F); - v8u16 const_0x7E0 = (v8u16)__msa_fill_h(0x7E0); - v8u16 const_0xF800 = (v8u16)__msa_fill_h(0xF800); - - for (x = 0; x < width; x += 16) { - src0 = (v8u16)__msa_ld_b((const v8i16*)src_rgb565, 0); - src1 = (v8u16)__msa_ld_b((const v8i16*)src_rgb565, 16); - vec0 = src0 & const_0x1F; - vec1 = src0 & const_0x7E0; - vec2 = src0 & const_0xF800; - vec3 = src1 & const_0x1F; - vec4 = src1 & const_0x7E0; - vec5 = src1 & const_0xF800; - reg0 = (v8u16)__msa_slli_h((v8i16)vec0, 3); - reg1 = (v8u16)__msa_srli_h((v8i16)vec1, 3); - reg2 = (v8u16)__msa_srli_h((v8i16)vec2, 8); - reg3 = (v8u16)__msa_slli_h((v8i16)vec3, 3); - reg4 = (v8u16)__msa_srli_h((v8i16)vec4, 3); - reg5 = (v8u16)__msa_srli_h((v8i16)vec5, 8); - reg0 |= (v8u16)__msa_srli_h((v8i16)vec0, 2); - reg1 |= (v8u16)__msa_srli_h((v8i16)vec1, 9); - reg2 |= (v8u16)__msa_srli_h((v8i16)vec2, 13); - reg3 |= (v8u16)__msa_srli_h((v8i16)vec3, 2); - reg4 |= (v8u16)__msa_srli_h((v8i16)vec4, 9); - reg5 |= (v8u16)__msa_srli_h((v8i16)vec5, 13); - vec0 = (v8u16)__msa_ilvr_h((v8i16)reg1, (v8i16)reg0); - vec1 = (v8u16)__msa_ilvl_h((v8i16)reg1, (v8i16)reg0); - vec2 = (v8u16)__msa_ilvr_h((v8i16)reg4, (v8i16)reg3); - vec3 = (v8u16)__msa_ilvl_h((v8i16)reg4, (v8i16)reg3); - vec4 = (v8u16)__msa_ilvr_h(const_0x1080, (v8i16)reg2); - vec5 = (v8u16)__msa_ilvl_h(const_0x1080, (v8i16)reg2); - vec6 = (v8u16)__msa_ilvr_h(const_0x1080, (v8i16)reg5); - vec7 = (v8u16)__msa_ilvl_h(const_0x1080, (v8i16)reg5); - res0 = __msa_dotp_u_w(vec0, (v8u16)const_0x810019); - res1 = __msa_dotp_u_w(vec1, (v8u16)const_0x810019); - res2 = __msa_dotp_u_w(vec2, (v8u16)const_0x810019); - res3 = __msa_dotp_u_w(vec3, (v8u16)const_0x810019); - res0 = __msa_dpadd_u_w(res0, vec4, (v8u16)const_0x010042); - res1 = __msa_dpadd_u_w(res1, vec5, (v8u16)const_0x010042); - res2 = __msa_dpadd_u_w(res2, vec6, (v8u16)const_0x010042); - res3 = __msa_dpadd_u_w(res3, vec7, (v8u16)const_0x010042); - res0 = (v4u32)__msa_srai_w((v4i32)res0, 8); - res1 = (v4u32)__msa_srai_w((v4i32)res1, 8); - res2 = (v4u32)__msa_srai_w((v4i32)res2, 8); - res3 = (v4u32)__msa_srai_w((v4i32)res3, 8); - vec0 = (v8u16)__msa_pckev_h((v8i16)res1, (v8i16)res0); - vec1 = (v8u16)__msa_pckev_h((v8i16)res3, (v8i16)res2); - dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - ST_UB(dst0, dst_y); - src_rgb565 += 32; - dst_y += 16; - } -} - -void RGB24ToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width) { - int x; - v16u8 src0, src1, src2, reg0, reg1, reg2, reg3, dst0; - v8u16 vec0, vec1, vec2, vec3; - v8u16 const_0x8119 = (v8u16)__msa_fill_h(0x8119); - v8u16 const_0x42 = (v8u16)__msa_fill_h(0x42); - v8u16 const_0x1080 = (v8u16)__msa_fill_h(0x1080); - v16i8 mask0 = {0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12}; - v16i8 mask1 = {12, 13, 14, 15, 15, 16, 17, 18, - 18, 19, 20, 21, 21, 22, 23, 24}; - v16i8 mask2 = {8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20}; - v16i8 mask3 = {4, 5, 6, 7, 7, 8, 9, 10, 10, 11, 12, 13, 13, 14, 15, 16}; - v16i8 zero = {0}; - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 32); - reg0 = (v16u8)__msa_vshf_b(mask0, zero, (v16i8)src0); - reg1 = (v16u8)__msa_vshf_b(mask1, (v16i8)src1, (v16i8)src0); - reg2 = (v16u8)__msa_vshf_b(mask2, (v16i8)src2, (v16i8)src1); - reg3 = (v16u8)__msa_vshf_b(mask3, zero, (v16i8)src2); - vec0 = (v8u16)__msa_pckev_h((v8i16)reg1, (v8i16)reg0); - vec1 = (v8u16)__msa_pckev_h((v8i16)reg3, (v8i16)reg2); - vec2 = (v8u16)__msa_pckod_h((v8i16)reg1, (v8i16)reg0); - vec3 = (v8u16)__msa_pckod_h((v8i16)reg3, (v8i16)reg2); - vec0 = __msa_dotp_u_h((v16u8)vec0, (v16u8)const_0x8119); - vec1 = __msa_dotp_u_h((v16u8)vec1, (v16u8)const_0x8119); - vec0 = __msa_dpadd_u_h(vec0, (v16u8)vec2, (v16u8)const_0x42); - vec1 = __msa_dpadd_u_h(vec1, (v16u8)vec3, (v16u8)const_0x42); - vec0 += const_0x1080; - vec1 += const_0x1080; - vec0 = (v8u16)__msa_srai_h((v8i16)vec0, 8); - vec1 = (v8u16)__msa_srai_h((v8i16)vec1, 8); - dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - ST_UB(dst0, dst_y); - src_argb0 += 48; - dst_y += 16; - } -} - -void RAWToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width) { - int x; - v16u8 src0, src1, src2, reg0, reg1, reg2, reg3, dst0; - v8u16 vec0, vec1, vec2, vec3; - v8u16 const_0x8142 = (v8u16)__msa_fill_h(0x8142); - v8u16 const_0x19 = (v8u16)__msa_fill_h(0x19); - v8u16 const_0x1080 = (v8u16)__msa_fill_h(0x1080); - v16i8 mask0 = {0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12}; - v16i8 mask1 = {12, 13, 14, 15, 15, 16, 17, 18, - 18, 19, 20, 21, 21, 22, 23, 24}; - v16i8 mask2 = {8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20}; - v16i8 mask3 = {4, 5, 6, 7, 7, 8, 9, 10, 10, 11, 12, 13, 13, 14, 15, 16}; - v16i8 zero = {0}; - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 32); - reg0 = (v16u8)__msa_vshf_b(mask0, zero, (v16i8)src0); - reg1 = (v16u8)__msa_vshf_b(mask1, (v16i8)src1, (v16i8)src0); - reg2 = (v16u8)__msa_vshf_b(mask2, (v16i8)src2, (v16i8)src1); - reg3 = (v16u8)__msa_vshf_b(mask3, zero, (v16i8)src2); - vec0 = (v8u16)__msa_pckev_h((v8i16)reg1, (v8i16)reg0); - vec1 = (v8u16)__msa_pckev_h((v8i16)reg3, (v8i16)reg2); - vec2 = (v8u16)__msa_pckod_h((v8i16)reg1, (v8i16)reg0); - vec3 = (v8u16)__msa_pckod_h((v8i16)reg3, (v8i16)reg2); - vec0 = __msa_dotp_u_h((v16u8)vec0, (v16u8)const_0x8142); - vec1 = __msa_dotp_u_h((v16u8)vec1, (v16u8)const_0x8142); - vec0 = __msa_dpadd_u_h(vec0, (v16u8)vec2, (v16u8)const_0x19); - vec1 = __msa_dpadd_u_h(vec1, (v16u8)vec3, (v16u8)const_0x19); - vec0 += const_0x1080; - vec1 += const_0x1080; - vec0 = (v8u16)__msa_srai_h((v8i16)vec0, 8); - vec1 = (v8u16)__msa_srai_h((v8i16)vec1, 8); - dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - ST_UB(dst0, dst_y); - src_argb0 += 48; - dst_y += 16; - } -} - -void ARGB1555ToUVRow_MSA(const uint8_t* src_argb1555, - int src_stride_argb1555, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - int x; - const uint16_t* s = (const uint16_t*)src_argb1555; - const uint16_t* t = (const uint16_t*)(src_argb1555 + src_stride_argb1555); - int64_t res0, res1; - v8u16 src0, src1, src2, src3, reg0, reg1, reg2, reg3; - v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6; - v16u8 dst0; - v8u16 const_0x70 = (v8u16)__msa_ldi_h(0x70); - v8u16 const_0x4A = (v8u16)__msa_ldi_h(0x4A); - v8u16 const_0x26 = (v8u16)__msa_ldi_h(0x26); - v8u16 const_0x5E = (v8u16)__msa_ldi_h(0x5E); - v8u16 const_0x12 = (v8u16)__msa_ldi_h(0x12); - v8u16 const_0x8080 = (v8u16)__msa_fill_h(0x8080); - v8u16 const_0x1F = (v8u16)__msa_ldi_h(0x1F); - - for (x = 0; x < width; x += 16) { - src0 = (v8u16)__msa_ld_b((v8i16*)s, 0); - src1 = (v8u16)__msa_ld_b((v8i16*)s, 16); - src2 = (v8u16)__msa_ld_b((v8i16*)t, 0); - src3 = (v8u16)__msa_ld_b((v8i16*)t, 16); - vec0 = src0 & const_0x1F; - vec1 = src1 & const_0x1F; - vec0 += src2 & const_0x1F; - vec1 += src3 & const_0x1F; - vec0 = (v8u16)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - src0 = (v8u16)__msa_srai_h((v8i16)src0, 5); - src1 = (v8u16)__msa_srai_h((v8i16)src1, 5); - src2 = (v8u16)__msa_srai_h((v8i16)src2, 5); - src3 = (v8u16)__msa_srai_h((v8i16)src3, 5); - vec2 = src0 & const_0x1F; - vec3 = src1 & const_0x1F; - vec2 += src2 & const_0x1F; - vec3 += src3 & const_0x1F; - vec2 = (v8u16)__msa_pckev_b((v16i8)vec3, (v16i8)vec2); - src0 = (v8u16)__msa_srai_h((v8i16)src0, 5); - src1 = (v8u16)__msa_srai_h((v8i16)src1, 5); - src2 = (v8u16)__msa_srai_h((v8i16)src2, 5); - src3 = (v8u16)__msa_srai_h((v8i16)src3, 5); - vec4 = src0 & const_0x1F; - vec5 = src1 & const_0x1F; - vec4 += src2 & const_0x1F; - vec5 += src3 & const_0x1F; - vec4 = (v8u16)__msa_pckev_b((v16i8)vec5, (v16i8)vec4); - vec0 = __msa_hadd_u_h((v16u8)vec0, (v16u8)vec0); - vec2 = __msa_hadd_u_h((v16u8)vec2, (v16u8)vec2); - vec4 = __msa_hadd_u_h((v16u8)vec4, (v16u8)vec4); - vec6 = (v8u16)__msa_slli_h((v8i16)vec0, 1); - vec6 |= (v8u16)__msa_srai_h((v8i16)vec0, 6); - vec0 = (v8u16)__msa_slli_h((v8i16)vec2, 1); - vec0 |= (v8u16)__msa_srai_h((v8i16)vec2, 6); - vec2 = (v8u16)__msa_slli_h((v8i16)vec4, 1); - vec2 |= (v8u16)__msa_srai_h((v8i16)vec4, 6); - reg0 = vec6 * const_0x70; - reg1 = vec0 * const_0x4A; - reg2 = vec2 * const_0x70; - reg3 = vec0 * const_0x5E; - reg0 += const_0x8080; - reg1 += vec2 * const_0x26; - reg2 += const_0x8080; - reg3 += vec6 * const_0x12; - reg0 -= reg1; - reg2 -= reg3; - reg0 = (v8u16)__msa_srai_h((v8i16)reg0, 8); - reg2 = (v8u16)__msa_srai_h((v8i16)reg2, 8); - dst0 = (v16u8)__msa_pckev_b((v16i8)reg2, (v16i8)reg0); - res0 = __msa_copy_u_d((v2i64)dst0, 0); - res1 = __msa_copy_u_d((v2i64)dst0, 1); - SD(res0, dst_u); - SD(res1, dst_v); - s += 16; - t += 16; - dst_u += 8; - dst_v += 8; - } -} - -void RGB565ToUVRow_MSA(const uint8_t* src_rgb565, - int src_stride_rgb565, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - int x; - const uint16_t* s = (const uint16_t*)src_rgb565; - const uint16_t* t = (const uint16_t*)(src_rgb565 + src_stride_rgb565); - int64_t res0, res1; - v8u16 src0, src1, src2, src3, reg0, reg1, reg2, reg3; - v8u16 vec0, vec1, vec2, vec3, vec4, vec5; - v16u8 dst0; - v8u16 const_0x70 = (v8u16)__msa_ldi_h(0x70); - v8u16 const_0x4A = (v8u16)__msa_ldi_h(0x4A); - v8u16 const_0x26 = (v8u16)__msa_ldi_h(0x26); - v8u16 const_0x5E = (v8u16)__msa_ldi_h(0x5E); - v8u16 const_0x12 = (v8u16)__msa_ldi_h(0x12); - v8u16 const_32896 = (v8u16)__msa_fill_h(0x8080); - v8u16 const_0x1F = (v8u16)__msa_ldi_h(0x1F); - v8u16 const_0x3F = (v8u16)__msa_fill_h(0x3F); - - for (x = 0; x < width; x += 16) { - src0 = (v8u16)__msa_ld_b((v8i16*)s, 0); - src1 = (v8u16)__msa_ld_b((v8i16*)s, 16); - src2 = (v8u16)__msa_ld_b((v8i16*)t, 0); - src3 = (v8u16)__msa_ld_b((v8i16*)t, 16); - vec0 = src0 & const_0x1F; - vec1 = src1 & const_0x1F; - vec0 += src2 & const_0x1F; - vec1 += src3 & const_0x1F; - vec0 = (v8u16)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - src0 = (v8u16)__msa_srai_h((v8i16)src0, 5); - src1 = (v8u16)__msa_srai_h((v8i16)src1, 5); - src2 = (v8u16)__msa_srai_h((v8i16)src2, 5); - src3 = (v8u16)__msa_srai_h((v8i16)src3, 5); - vec2 = src0 & const_0x3F; - vec3 = src1 & const_0x3F; - vec2 += src2 & const_0x3F; - vec3 += src3 & const_0x3F; - vec1 = (v8u16)__msa_pckev_b((v16i8)vec3, (v16i8)vec2); - src0 = (v8u16)__msa_srai_h((v8i16)src0, 6); - src1 = (v8u16)__msa_srai_h((v8i16)src1, 6); - src2 = (v8u16)__msa_srai_h((v8i16)src2, 6); - src3 = (v8u16)__msa_srai_h((v8i16)src3, 6); - vec4 = src0 & const_0x1F; - vec5 = src1 & const_0x1F; - vec4 += src2 & const_0x1F; - vec5 += src3 & const_0x1F; - vec2 = (v8u16)__msa_pckev_b((v16i8)vec5, (v16i8)vec4); - vec0 = __msa_hadd_u_h((v16u8)vec0, (v16u8)vec0); - vec1 = __msa_hadd_u_h((v16u8)vec1, (v16u8)vec1); - vec2 = __msa_hadd_u_h((v16u8)vec2, (v16u8)vec2); - vec3 = (v8u16)__msa_slli_h((v8i16)vec0, 1); - vec3 |= (v8u16)__msa_srai_h((v8i16)vec0, 6); - vec4 = (v8u16)__msa_slli_h((v8i16)vec2, 1); - vec4 |= (v8u16)__msa_srai_h((v8i16)vec2, 6); - reg0 = vec3 * const_0x70; - reg1 = vec1 * const_0x4A; - reg2 = vec4 * const_0x70; - reg3 = vec1 * const_0x5E; - reg0 += const_32896; - reg1 += vec4 * const_0x26; - reg2 += const_32896; - reg3 += vec3 * const_0x12; - reg0 -= reg1; - reg2 -= reg3; - reg0 = (v8u16)__msa_srai_h((v8i16)reg0, 8); - reg2 = (v8u16)__msa_srai_h((v8i16)reg2, 8); - dst0 = (v16u8)__msa_pckev_b((v16i8)reg2, (v16i8)reg0); - res0 = __msa_copy_u_d((v2i64)dst0, 0); - res1 = __msa_copy_u_d((v2i64)dst0, 1); - SD(res0, dst_u); - SD(res1, dst_v); - s += 16; - t += 16; - dst_u += 8; - dst_v += 8; - } -} - -void RGB24ToUVRow_MSA(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - int x; - const uint8_t* s = src_rgb0; - const uint8_t* t = src_rgb0 + src_stride_rgb; - int64_t res0, res1; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v16u8 inp0, inp1, inp2, inp3, inp4, inp5; - v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8i16 reg0, reg1, reg2, reg3; - v16u8 dst0; - v8u16 const_0x70 = (v8u16)__msa_fill_h(0x70); - v8u16 const_0x4A = (v8u16)__msa_fill_h(0x4A); - v8u16 const_0x26 = (v8u16)__msa_fill_h(0x26); - v8u16 const_0x5E = (v8u16)__msa_fill_h(0x5E); - v8u16 const_0x12 = (v8u16)__msa_fill_h(0x12); - v8u16 const_0x8080 = (v8u16)__msa_fill_h(0x8080); - v16i8 mask = {0, 1, 2, 16, 3, 4, 5, 17, 6, 7, 8, 18, 9, 10, 11, 19}; - v16i8 zero = {0}; - - for (x = 0; x < width; x += 16) { - inp0 = (v16u8)__msa_ld_b((const v16i8*)s, 0); - inp1 = (v16u8)__msa_ld_b((const v16i8*)s, 16); - inp2 = (v16u8)__msa_ld_b((const v16i8*)s, 32); - inp3 = (v16u8)__msa_ld_b((const v16i8*)t, 0); - inp4 = (v16u8)__msa_ld_b((const v16i8*)t, 16); - inp5 = (v16u8)__msa_ld_b((const v16i8*)t, 32); - src1 = (v16u8)__msa_sldi_b((v16i8)inp1, (v16i8)inp0, 12); - src5 = (v16u8)__msa_sldi_b((v16i8)inp4, (v16i8)inp3, 12); - src2 = (v16u8)__msa_sldi_b((v16i8)inp2, (v16i8)inp1, 8); - src6 = (v16u8)__msa_sldi_b((v16i8)inp5, (v16i8)inp4, 8); - src3 = (v16u8)__msa_sldi_b((v16i8)inp2, (v16i8)inp2, 4); - src7 = (v16u8)__msa_sldi_b((v16i8)inp5, (v16i8)inp5, 4); - src0 = (v16u8)__msa_vshf_b(mask, (v16i8)zero, (v16i8)inp0); - src1 = (v16u8)__msa_vshf_b(mask, (v16i8)zero, (v16i8)src1); - src2 = (v16u8)__msa_vshf_b(mask, (v16i8)zero, (v16i8)src2); - src3 = (v16u8)__msa_vshf_b(mask, (v16i8)zero, (v16i8)src3); - src4 = (v16u8)__msa_vshf_b(mask, (v16i8)zero, (v16i8)inp3); - src5 = (v16u8)__msa_vshf_b(mask, (v16i8)zero, (v16i8)src5); - src6 = (v16u8)__msa_vshf_b(mask, (v16i8)zero, (v16i8)src6); - src7 = (v16u8)__msa_vshf_b(mask, (v16i8)zero, (v16i8)src7); - vec0 = (v8u16)__msa_ilvr_b((v16i8)src4, (v16i8)src0); - vec1 = (v8u16)__msa_ilvl_b((v16i8)src4, (v16i8)src0); - vec2 = (v8u16)__msa_ilvr_b((v16i8)src5, (v16i8)src1); - vec3 = (v8u16)__msa_ilvl_b((v16i8)src5, (v16i8)src1); - vec4 = (v8u16)__msa_ilvr_b((v16i8)src6, (v16i8)src2); - vec5 = (v8u16)__msa_ilvl_b((v16i8)src6, (v16i8)src2); - vec6 = (v8u16)__msa_ilvr_b((v16i8)src7, (v16i8)src3); - vec7 = (v8u16)__msa_ilvl_b((v16i8)src7, (v16i8)src3); - vec0 = (v8u16)__msa_hadd_u_h((v16u8)vec0, (v16u8)vec0); - vec1 = (v8u16)__msa_hadd_u_h((v16u8)vec1, (v16u8)vec1); - vec2 = (v8u16)__msa_hadd_u_h((v16u8)vec2, (v16u8)vec2); - vec3 = (v8u16)__msa_hadd_u_h((v16u8)vec3, (v16u8)vec3); - vec4 = (v8u16)__msa_hadd_u_h((v16u8)vec4, (v16u8)vec4); - vec5 = (v8u16)__msa_hadd_u_h((v16u8)vec5, (v16u8)vec5); - vec6 = (v8u16)__msa_hadd_u_h((v16u8)vec6, (v16u8)vec6); - vec7 = (v8u16)__msa_hadd_u_h((v16u8)vec7, (v16u8)vec7); - reg0 = (v8i16)__msa_pckev_d((v2i64)vec1, (v2i64)vec0); - reg1 = (v8i16)__msa_pckev_d((v2i64)vec3, (v2i64)vec2); - reg2 = (v8i16)__msa_pckev_d((v2i64)vec5, (v2i64)vec4); - reg3 = (v8i16)__msa_pckev_d((v2i64)vec7, (v2i64)vec6); - reg0 += (v8i16)__msa_pckod_d((v2i64)vec1, (v2i64)vec0); - reg1 += (v8i16)__msa_pckod_d((v2i64)vec3, (v2i64)vec2); - reg2 += (v8i16)__msa_pckod_d((v2i64)vec5, (v2i64)vec4); - reg3 += (v8i16)__msa_pckod_d((v2i64)vec7, (v2i64)vec6); - reg0 = __msa_srai_h((v8i16)reg0, 2); - reg1 = __msa_srai_h((v8i16)reg1, 2); - reg2 = __msa_srai_h((v8i16)reg2, 2); - reg3 = __msa_srai_h((v8i16)reg3, 2); - vec4 = (v8u16)__msa_pckev_h(reg1, reg0); - vec5 = (v8u16)__msa_pckev_h(reg3, reg2); - vec6 = (v8u16)__msa_pckod_h(reg1, reg0); - vec7 = (v8u16)__msa_pckod_h(reg3, reg2); - vec0 = (v8u16)__msa_pckev_h((v8i16)vec5, (v8i16)vec4); - vec1 = (v8u16)__msa_pckev_h((v8i16)vec7, (v8i16)vec6); - vec2 = (v8u16)__msa_pckod_h((v8i16)vec5, (v8i16)vec4); - vec3 = vec0 * const_0x70; - vec4 = vec1 * const_0x4A; - vec5 = vec2 * const_0x26; - vec2 *= const_0x70; - vec1 *= const_0x5E; - vec0 *= const_0x12; - reg0 = __msa_subv_h((v8i16)vec3, (v8i16)vec4); - reg1 = __msa_subv_h((v8i16)const_0x8080, (v8i16)vec5); - reg2 = __msa_subv_h((v8i16)vec2, (v8i16)vec1); - reg3 = __msa_subv_h((v8i16)const_0x8080, (v8i16)vec0); - reg0 += reg1; - reg2 += reg3; - reg0 = __msa_srai_h(reg0, 8); - reg2 = __msa_srai_h(reg2, 8); - dst0 = (v16u8)__msa_pckev_b((v16i8)reg2, (v16i8)reg0); - res0 = __msa_copy_u_d((v2i64)dst0, 0); - res1 = __msa_copy_u_d((v2i64)dst0, 1); - SD(res0, dst_u); - SD(res1, dst_v); - t += 48; - s += 48; - dst_u += 8; - dst_v += 8; - } -} - -void RAWToUVRow_MSA(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - int x; - const uint8_t* s = src_rgb0; - const uint8_t* t = src_rgb0 + src_stride_rgb; - int64_t res0, res1; - v16u8 inp0, inp1, inp2, inp3, inp4, inp5; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8i16 reg0, reg1, reg2, reg3; - v16u8 dst0; - v8u16 const_0x70 = (v8u16)__msa_fill_h(0x70); - v8u16 const_0x4A = (v8u16)__msa_fill_h(0x4A); - v8u16 const_0x26 = (v8u16)__msa_fill_h(0x26); - v8u16 const_0x5E = (v8u16)__msa_fill_h(0x5E); - v8u16 const_0x12 = (v8u16)__msa_fill_h(0x12); - v8u16 const_0x8080 = (v8u16)__msa_fill_h(0x8080); - v16i8 mask = {0, 1, 2, 16, 3, 4, 5, 17, 6, 7, 8, 18, 9, 10, 11, 19}; - v16i8 zero = {0}; - - for (x = 0; x < width; x += 16) { - inp0 = (v16u8)__msa_ld_b((const v16i8*)s, 0); - inp1 = (v16u8)__msa_ld_b((const v16i8*)s, 16); - inp2 = (v16u8)__msa_ld_b((const v16i8*)s, 32); - inp3 = (v16u8)__msa_ld_b((const v16i8*)t, 0); - inp4 = (v16u8)__msa_ld_b((const v16i8*)t, 16); - inp5 = (v16u8)__msa_ld_b((const v16i8*)t, 32); - src1 = (v16u8)__msa_sldi_b((v16i8)inp1, (v16i8)inp0, 12); - src5 = (v16u8)__msa_sldi_b((v16i8)inp4, (v16i8)inp3, 12); - src2 = (v16u8)__msa_sldi_b((v16i8)inp2, (v16i8)inp1, 8); - src6 = (v16u8)__msa_sldi_b((v16i8)inp5, (v16i8)inp4, 8); - src3 = (v16u8)__msa_sldi_b((v16i8)inp2, (v16i8)inp2, 4); - src7 = (v16u8)__msa_sldi_b((v16i8)inp5, (v16i8)inp5, 4); - src0 = (v16u8)__msa_vshf_b(mask, (v16i8)zero, (v16i8)inp0); - src1 = (v16u8)__msa_vshf_b(mask, (v16i8)zero, (v16i8)src1); - src2 = (v16u8)__msa_vshf_b(mask, (v16i8)zero, (v16i8)src2); - src3 = (v16u8)__msa_vshf_b(mask, (v16i8)zero, (v16i8)src3); - src4 = (v16u8)__msa_vshf_b(mask, (v16i8)zero, (v16i8)inp3); - src5 = (v16u8)__msa_vshf_b(mask, (v16i8)zero, (v16i8)src5); - src6 = (v16u8)__msa_vshf_b(mask, (v16i8)zero, (v16i8)src6); - src7 = (v16u8)__msa_vshf_b(mask, (v16i8)zero, (v16i8)src7); - vec0 = (v8u16)__msa_ilvr_b((v16i8)src4, (v16i8)src0); - vec1 = (v8u16)__msa_ilvl_b((v16i8)src4, (v16i8)src0); - vec2 = (v8u16)__msa_ilvr_b((v16i8)src5, (v16i8)src1); - vec3 = (v8u16)__msa_ilvl_b((v16i8)src5, (v16i8)src1); - vec4 = (v8u16)__msa_ilvr_b((v16i8)src6, (v16i8)src2); - vec5 = (v8u16)__msa_ilvl_b((v16i8)src6, (v16i8)src2); - vec6 = (v8u16)__msa_ilvr_b((v16i8)src7, (v16i8)src3); - vec7 = (v8u16)__msa_ilvl_b((v16i8)src7, (v16i8)src3); - vec0 = (v8u16)__msa_hadd_u_h((v16u8)vec0, (v16u8)vec0); - vec1 = (v8u16)__msa_hadd_u_h((v16u8)vec1, (v16u8)vec1); - vec2 = (v8u16)__msa_hadd_u_h((v16u8)vec2, (v16u8)vec2); - vec3 = (v8u16)__msa_hadd_u_h((v16u8)vec3, (v16u8)vec3); - vec4 = (v8u16)__msa_hadd_u_h((v16u8)vec4, (v16u8)vec4); - vec5 = (v8u16)__msa_hadd_u_h((v16u8)vec5, (v16u8)vec5); - vec6 = (v8u16)__msa_hadd_u_h((v16u8)vec6, (v16u8)vec6); - vec7 = (v8u16)__msa_hadd_u_h((v16u8)vec7, (v16u8)vec7); - reg0 = (v8i16)__msa_pckev_d((v2i64)vec1, (v2i64)vec0); - reg1 = (v8i16)__msa_pckev_d((v2i64)vec3, (v2i64)vec2); - reg2 = (v8i16)__msa_pckev_d((v2i64)vec5, (v2i64)vec4); - reg3 = (v8i16)__msa_pckev_d((v2i64)vec7, (v2i64)vec6); - reg0 += (v8i16)__msa_pckod_d((v2i64)vec1, (v2i64)vec0); - reg1 += (v8i16)__msa_pckod_d((v2i64)vec3, (v2i64)vec2); - reg2 += (v8i16)__msa_pckod_d((v2i64)vec5, (v2i64)vec4); - reg3 += (v8i16)__msa_pckod_d((v2i64)vec7, (v2i64)vec6); - reg0 = __msa_srai_h(reg0, 2); - reg1 = __msa_srai_h(reg1, 2); - reg2 = __msa_srai_h(reg2, 2); - reg3 = __msa_srai_h(reg3, 2); - vec4 = (v8u16)__msa_pckev_h((v8i16)reg1, (v8i16)reg0); - vec5 = (v8u16)__msa_pckev_h((v8i16)reg3, (v8i16)reg2); - vec6 = (v8u16)__msa_pckod_h((v8i16)reg1, (v8i16)reg0); - vec7 = (v8u16)__msa_pckod_h((v8i16)reg3, (v8i16)reg2); - vec0 = (v8u16)__msa_pckod_h((v8i16)vec5, (v8i16)vec4); - vec1 = (v8u16)__msa_pckev_h((v8i16)vec7, (v8i16)vec6); - vec2 = (v8u16)__msa_pckev_h((v8i16)vec5, (v8i16)vec4); - vec3 = vec0 * const_0x70; - vec4 = vec1 * const_0x4A; - vec5 = vec2 * const_0x26; - vec2 *= const_0x70; - vec1 *= const_0x5E; - vec0 *= const_0x12; - reg0 = __msa_subv_h((v8i16)vec3, (v8i16)vec4); - reg1 = __msa_subv_h((v8i16)const_0x8080, (v8i16)vec5); - reg2 = __msa_subv_h((v8i16)vec2, (v8i16)vec1); - reg3 = __msa_subv_h((v8i16)const_0x8080, (v8i16)vec0); - reg0 += reg1; - reg2 += reg3; - reg0 = __msa_srai_h(reg0, 8); - reg2 = __msa_srai_h(reg2, 8); - dst0 = (v16u8)__msa_pckev_b((v16i8)reg2, (v16i8)reg0); - res0 = __msa_copy_u_d((v2i64)dst0, 0); - res1 = __msa_copy_u_d((v2i64)dst0, 1); - SD(res0, dst_u); - SD(res1, dst_v); - t += 48; - s += 48; - dst_u += 8; - dst_v += 8; - } -} - -void NV12ToARGBRow_MSA(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - int x; - uint64_t val0, val1; - v16u8 src0, src1, res0, res1, dst0, dst1; - v8i16 vec0, vec1, vec2; - v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; - v4i32 vec_ubvr, vec_ugvg; - v16u8 zero = {0}; - v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); - - YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, - vec_br, vec_yg); - vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); - vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); - - for (x = 0; x < width; x += 8) { - val0 = LD(src_y); - val1 = LD(src_uv); - src0 = (v16u8)__msa_insert_d((v2i64)zero, 0, val0); - src1 = (v16u8)__msa_insert_d((v2i64)zero, 0, val1); - YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, - vec0, vec1, vec2); - res0 = (v16u8)__msa_ilvev_b((v16i8)vec2, (v16i8)vec0); - res1 = (v16u8)__msa_ilvev_b((v16i8)alpha, (v16i8)vec1); - dst0 = (v16u8)__msa_ilvr_b((v16i8)res1, (v16i8)res0); - dst1 = (v16u8)__msa_ilvl_b((v16i8)res1, (v16i8)res0); - ST_UB2(dst0, dst1, dst_argb, 16); - src_y += 8; - src_uv += 8; - dst_argb += 32; - } -} - -void NV12ToRGB565Row_MSA(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width) { - int x; - uint64_t val0, val1; - v16u8 src0, src1, dst0; - v8i16 vec0, vec1, vec2; - v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; - v4i32 vec_ubvr, vec_ugvg; - v16u8 zero = {0}; - - YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, - vec_br, vec_yg); - vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); - vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); - - for (x = 0; x < width; x += 8) { - val0 = LD(src_y); - val1 = LD(src_uv); - src0 = (v16u8)__msa_insert_d((v2i64)zero, 0, val0); - src1 = (v16u8)__msa_insert_d((v2i64)zero, 0, val1); - YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, - vec0, vec1, vec2); - vec0 = vec0 >> 3; - vec1 = (vec1 >> 2) << 5; - vec2 = (vec2 >> 3) << 11; - dst0 = (v16u8)(vec0 | vec1 | vec2); - ST_UB(dst0, dst_rgb565); - src_y += 8; - src_uv += 8; - dst_rgb565 += 16; - } -} - -void NV21ToARGBRow_MSA(const uint8_t* src_y, - const uint8_t* src_vu, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - int x; - uint64_t val0, val1; - v16u8 src0, src1, res0, res1, dst0, dst1; - v8i16 vec0, vec1, vec2; - v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; - v4i32 vec_ubvr, vec_ugvg; - v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); - v16u8 zero = {0}; - v16i8 shuffler = {1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14}; - - YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, - vec_br, vec_yg); - vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); - vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); - - for (x = 0; x < width; x += 8) { - val0 = LD(src_y); - val1 = LD(src_vu); - src0 = (v16u8)__msa_insert_d((v2i64)zero, 0, val0); - src1 = (v16u8)__msa_insert_d((v2i64)zero, 0, val1); - src1 = (v16u8)__msa_vshf_b(shuffler, (v16i8)src1, (v16i8)src1); - YUVTORGB(src0, src1, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, - vec0, vec1, vec2); - res0 = (v16u8)__msa_ilvev_b((v16i8)vec2, (v16i8)vec0); - res1 = (v16u8)__msa_ilvev_b((v16i8)alpha, (v16i8)vec1); - dst0 = (v16u8)__msa_ilvr_b((v16i8)res1, (v16i8)res0); - dst1 = (v16u8)__msa_ilvl_b((v16i8)res1, (v16i8)res0); - ST_UB2(dst0, dst1, dst_argb, 16); - src_y += 8; - src_vu += 8; - dst_argb += 32; - } -} - -void SobelRow_MSA(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width) { - int x; - v16u8 src0, src1, vec0, dst0, dst1, dst2, dst3; - v16i8 mask0 = {0, 0, 0, 16, 1, 1, 1, 16, 2, 2, 2, 16, 3, 3, 3, 16}; - v16i8 const_0x4 = __msa_ldi_b(0x4); - v16i8 mask1 = mask0 + const_0x4; - v16i8 mask2 = mask1 + const_0x4; - v16i8 mask3 = mask2 + const_0x4; - v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_sobelx, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_sobely, 0); - vec0 = __msa_adds_u_b(src0, src1); - dst0 = (v16u8)__msa_vshf_b(mask0, (v16i8)alpha, (v16i8)vec0); - dst1 = (v16u8)__msa_vshf_b(mask1, (v16i8)alpha, (v16i8)vec0); - dst2 = (v16u8)__msa_vshf_b(mask2, (v16i8)alpha, (v16i8)vec0); - dst3 = (v16u8)__msa_vshf_b(mask3, (v16i8)alpha, (v16i8)vec0); - ST_UB4(dst0, dst1, dst2, dst3, dst_argb, 16); - src_sobelx += 16; - src_sobely += 16; - dst_argb += 64; - } -} - -void SobelToPlaneRow_MSA(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_y, - int width) { - int x; - v16u8 src0, src1, src2, src3, dst0, dst1; - - for (x = 0; x < width; x += 32) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_sobelx, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_sobelx, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_sobely, 0); - src3 = (v16u8)__msa_ld_b((const v16i8*)src_sobely, 16); - dst0 = __msa_adds_u_b(src0, src2); - dst1 = __msa_adds_u_b(src1, src3); - ST_UB2(dst0, dst1, dst_y, 16); - src_sobelx += 32; - src_sobely += 32; - dst_y += 32; - } -} - -void SobelXYRow_MSA(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width) { - int x; - v16u8 src0, src1, vec0, vec1, vec2; - v16u8 reg0, reg1, dst0, dst1, dst2, dst3; - v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_sobelx, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_sobely, 0); - vec0 = __msa_adds_u_b(src0, src1); - vec1 = (v16u8)__msa_ilvr_b((v16i8)src0, (v16i8)src1); - vec2 = (v16u8)__msa_ilvl_b((v16i8)src0, (v16i8)src1); - reg0 = (v16u8)__msa_ilvr_b((v16i8)alpha, (v16i8)vec0); - reg1 = (v16u8)__msa_ilvl_b((v16i8)alpha, (v16i8)vec0); - dst0 = (v16u8)__msa_ilvr_b((v16i8)reg0, (v16i8)vec1); - dst1 = (v16u8)__msa_ilvl_b((v16i8)reg0, (v16i8)vec1); - dst2 = (v16u8)__msa_ilvr_b((v16i8)reg1, (v16i8)vec2); - dst3 = (v16u8)__msa_ilvl_b((v16i8)reg1, (v16i8)vec2); - ST_UB4(dst0, dst1, dst2, dst3, dst_argb, 16); - src_sobelx += 16; - src_sobely += 16; - dst_argb += 64; - } -} - -void ARGBToYJRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width) { - int x; - v16u8 src0, src1, src2, src3, dst0; - v16u8 const_0x4B0F = (v16u8)__msa_fill_h(0x4B0F); - v16u8 const_0x26 = (v16u8)__msa_fill_h(0x26); - v8u16 const_0x40 = (v8u16)__msa_fill_h(0x40); - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 32); - src3 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 48); - ARGBTOY(src0, src1, src2, src3, const_0x4B0F, const_0x26, const_0x40, 7, - dst0); - ST_UB(dst0, dst_y); - src_argb0 += 64; - dst_y += 16; - } -} - -void BGRAToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width) { - int x; - v16u8 src0, src1, src2, src3, dst0; - v16u8 const_0x4200 = (v16u8)__msa_fill_h(0x4200); - v16u8 const_0x1981 = (v16u8)__msa_fill_h(0x1981); - v8u16 const_0x1080 = (v8u16)__msa_fill_h(0x1080); - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 32); - src3 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 48); - ARGBTOY(src0, src1, src2, src3, const_0x4200, const_0x1981, const_0x1080, 8, - dst0); - ST_UB(dst0, dst_y); - src_argb0 += 64; - dst_y += 16; - } -} - -void ABGRToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width) { - int x; - v16u8 src0, src1, src2, src3, dst0; - v16u8 const_0x8142 = (v16u8)__msa_fill_h(0x8142); - v16u8 const_0x19 = (v16u8)__msa_fill_h(0x19); - v8u16 const_0x1080 = (v8u16)__msa_fill_h(0x1080); - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 32); - src3 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 48); - ARGBTOY(src0, src1, src2, src3, const_0x8142, const_0x19, const_0x1080, 8, - dst0); - ST_UB(dst0, dst_y); - src_argb0 += 64; - dst_y += 16; - } -} - -void RGBAToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width) { - int x; - v16u8 src0, src1, src2, src3, dst0; - v16u8 const_0x1900 = (v16u8)__msa_fill_h(0x1900); - v16u8 const_0x4281 = (v16u8)__msa_fill_h(0x4281); - v8u16 const_0x1080 = (v8u16)__msa_fill_h(0x1080); - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 32); - src3 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 48); - ARGBTOY(src0, src1, src2, src3, const_0x1900, const_0x4281, const_0x1080, 8, - dst0); - ST_UB(dst0, dst_y); - src_argb0 += 64; - dst_y += 16; - } -} - -void ARGBToUVJRow_MSA(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - int x; - const uint8_t* s = src_rgb0; - const uint8_t* t = src_rgb0 + src_stride_rgb; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v16u8 vec0, vec1, vec2, vec3; - v16u8 dst0, dst1; - v16i8 shuffler0 = {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29}; - v16i8 shuffler1 = {2, 3, 6, 7, 10, 11, 14, 15, - 18, 19, 22, 23, 26, 27, 30, 31}; - v16i8 shuffler2 = {0, 3, 4, 7, 8, 11, 12, 15, 16, 19, 20, 23, 24, 27, 28, 31}; - v16i8 shuffler3 = {1, 2, 5, 6, 9, 10, 13, 14, 17, 18, 21, 22, 25, 26, 29, 30}; - v16u8 const_0x7F = (v16u8)__msa_fill_h(0x7F); - v16u8 const_0x6B14 = (v16u8)__msa_fill_h(0x6B14); - v16u8 const_0x2B54 = (v16u8)__msa_fill_h(0x2B54); - v8u16 const_0x8080 = (v8u16)__msa_fill_h(0x8080); - - for (x = 0; x < width; x += 32) { - src0 = (v16u8)__msa_ld_b((const v16i8*)s, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)s, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)s, 32); - src3 = (v16u8)__msa_ld_b((const v16i8*)s, 48); - src4 = (v16u8)__msa_ld_b((const v16i8*)t, 0); - src5 = (v16u8)__msa_ld_b((const v16i8*)t, 16); - src6 = (v16u8)__msa_ld_b((const v16i8*)t, 32); - src7 = (v16u8)__msa_ld_b((const v16i8*)t, 48); - src0 = __msa_aver_u_b(src0, src4); - src1 = __msa_aver_u_b(src1, src5); - src2 = __msa_aver_u_b(src2, src6); - src3 = __msa_aver_u_b(src3, src7); - src4 = (v16u8)__msa_pckev_w((v4i32)src1, (v4i32)src0); - src5 = (v16u8)__msa_pckev_w((v4i32)src3, (v4i32)src2); - src6 = (v16u8)__msa_pckod_w((v4i32)src1, (v4i32)src0); - src7 = (v16u8)__msa_pckod_w((v4i32)src3, (v4i32)src2); - vec0 = __msa_aver_u_b(src4, src6); - vec1 = __msa_aver_u_b(src5, src7); - src0 = (v16u8)__msa_ld_b((v16i8*)s, 64); - src1 = (v16u8)__msa_ld_b((v16i8*)s, 80); - src2 = (v16u8)__msa_ld_b((v16i8*)s, 96); - src3 = (v16u8)__msa_ld_b((v16i8*)s, 112); - src4 = (v16u8)__msa_ld_b((v16i8*)t, 64); - src5 = (v16u8)__msa_ld_b((v16i8*)t, 80); - src6 = (v16u8)__msa_ld_b((v16i8*)t, 96); - src7 = (v16u8)__msa_ld_b((v16i8*)t, 112); - src0 = __msa_aver_u_b(src0, src4); - src1 = __msa_aver_u_b(src1, src5); - src2 = __msa_aver_u_b(src2, src6); - src3 = __msa_aver_u_b(src3, src7); - src4 = (v16u8)__msa_pckev_w((v4i32)src1, (v4i32)src0); - src5 = (v16u8)__msa_pckev_w((v4i32)src3, (v4i32)src2); - src6 = (v16u8)__msa_pckod_w((v4i32)src1, (v4i32)src0); - src7 = (v16u8)__msa_pckod_w((v4i32)src3, (v4i32)src2); - vec2 = __msa_aver_u_b(src4, src6); - vec3 = __msa_aver_u_b(src5, src7); - ARGBTOUV(vec0, vec1, vec2, vec3, const_0x6B14, const_0x7F, const_0x2B54, - const_0x8080, shuffler1, shuffler0, shuffler2, shuffler3, dst0, - dst1); - ST_UB(dst0, dst_v); - ST_UB(dst1, dst_u); - s += 128; - t += 128; - dst_v += 16; - dst_u += 16; - } -} - -void BGRAToUVRow_MSA(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - int x; - const uint8_t* s = src_rgb0; - const uint8_t* t = src_rgb0 + src_stride_rgb; - v16u8 dst0, dst1, vec0, vec1, vec2, vec3; - v16i8 shuffler0 = {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29}; - v16i8 shuffler1 = {2, 3, 6, 7, 10, 11, 14, 15, - 18, 19, 22, 23, 26, 27, 30, 31}; - v16i8 shuffler2 = {0, 3, 4, 7, 8, 11, 12, 15, 16, 19, 20, 23, 24, 27, 28, 31}; - v16i8 shuffler3 = {2, 1, 6, 5, 10, 9, 14, 13, 18, 17, 22, 21, 26, 25, 30, 29}; - v16u8 const_0x125E = (v16u8)__msa_fill_h(0x125E); - v16u8 const_0x7000 = (v16u8)__msa_fill_h(0x7000); - v16u8 const_0x264A = (v16u8)__msa_fill_h(0x264A); - v8u16 const_0x8080 = (v8u16)__msa_fill_h(0x8080); - - for (x = 0; x < width; x += 32) { - READ_ARGB(s, t, vec0, vec1, vec2, vec3); - ARGBTOUV(vec0, vec1, vec2, vec3, const_0x125E, const_0x7000, const_0x264A, - const_0x8080, shuffler0, shuffler1, shuffler2, shuffler3, dst0, - dst1); - ST_UB(dst0, dst_v); - ST_UB(dst1, dst_u); - s += 128; - t += 128; - dst_v += 16; - dst_u += 16; - } -} - -void ABGRToUVRow_MSA(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - int x; - const uint8_t* s = src_rgb0; - const uint8_t* t = src_rgb0 + src_stride_rgb; - v16u8 src0, src1, src2, src3; - v16u8 dst0, dst1; - v16i8 shuffler0 = {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29}; - v16i8 shuffler1 = {2, 3, 6, 7, 10, 11, 14, 15, - 18, 19, 22, 23, 26, 27, 30, 31}; - v16i8 shuffler2 = {0, 3, 4, 7, 8, 11, 12, 15, 16, 19, 20, 23, 24, 27, 28, 31}; - v16i8 shuffler3 = {1, 2, 5, 6, 9, 10, 13, 14, 17, 18, 21, 22, 25, 26, 29, 30}; - v16u8 const_0x4A26 = (v16u8)__msa_fill_h(0x4A26); - v16u8 const_0x0070 = (v16u8)__msa_fill_h(0x0070); - v16u8 const_0x125E = (v16u8)__msa_fill_h(0x125E); - v8u16 const_0x8080 = (v8u16)__msa_fill_h(0x8080); - - for (x = 0; x < width; x += 32) { - READ_ARGB(s, t, src0, src1, src2, src3); - ARGBTOUV(src0, src1, src2, src3, const_0x4A26, const_0x0070, const_0x125E, - const_0x8080, shuffler1, shuffler0, shuffler2, shuffler3, dst0, - dst1); - ST_UB(dst0, dst_u); - ST_UB(dst1, dst_v); - s += 128; - t += 128; - dst_u += 16; - dst_v += 16; - } -} - -void RGBAToUVRow_MSA(const uint8_t* src_rgb0, - int src_stride_rgb, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - int x; - const uint8_t* s = src_rgb0; - const uint8_t* t = src_rgb0 + src_stride_rgb; - v16u8 dst0, dst1, vec0, vec1, vec2, vec3; - v16i8 shuffler0 = {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29}; - v16i8 shuffler1 = {2, 3, 6, 7, 10, 11, 14, 15, - 18, 19, 22, 23, 26, 27, 30, 31}; - v16i8 shuffler2 = {0, 3, 4, 7, 8, 11, 12, 15, 16, 19, 20, 23, 24, 27, 28, 31}; - v16i8 shuffler3 = {2, 1, 6, 5, 10, 9, 14, 13, 18, 17, 22, 21, 26, 25, 30, 29}; - v16u8 const_0x125E = (v16u8)__msa_fill_h(0x264A); - v16u8 const_0x7000 = (v16u8)__msa_fill_h(0x7000); - v16u8 const_0x264A = (v16u8)__msa_fill_h(0x125E); - v8u16 const_0x8080 = (v8u16)__msa_fill_h(0x8080); - - for (x = 0; x < width; x += 32) { - READ_ARGB(s, t, vec0, vec1, vec2, vec3); - ARGBTOUV(vec0, vec1, vec2, vec3, const_0x125E, const_0x7000, const_0x264A, - const_0x8080, shuffler0, shuffler1, shuffler2, shuffler3, dst0, - dst1); - ST_UB(dst0, dst_u); - ST_UB(dst1, dst_v); - s += 128; - t += 128; - dst_u += 16; - dst_v += 16; - } -} - -void I444ToARGBRow_MSA(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - int x; - v16u8 src0, src1, src2, dst0, dst1; - v8u16 vec0, vec1, vec2; - v4i32 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9; - v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; - v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); - v8i16 zero = {0}; - - YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, - vec_br, vec_yg); - - for (x = 0; x < width; x += 8) { - READI444(src_y, src_u, src_v, src0, src1, src2); - vec0 = (v8u16)__msa_ilvr_b((v16i8)src0, (v16i8)src0); - reg0 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec0); - reg1 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec0); - reg0 *= vec_yg; - reg1 *= vec_yg; - reg0 = __msa_srai_w(reg0, 16); - reg1 = __msa_srai_w(reg1, 16); - reg4 = reg0 + vec_br; - reg5 = reg1 + vec_br; - reg2 = reg0 + vec_bg; - reg3 = reg1 + vec_bg; - reg0 += vec_bb; - reg1 += vec_bb; - vec0 = (v8u16)__msa_ilvr_b((v16i8)zero, (v16i8)src1); - vec1 = (v8u16)__msa_ilvr_b((v16i8)zero, (v16i8)src2); - reg6 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec0); - reg7 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec0); - reg8 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec1); - reg9 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec1); - reg0 -= reg6 * vec_ub; - reg1 -= reg7 * vec_ub; - reg2 -= reg6 * vec_ug; - reg3 -= reg7 * vec_ug; - reg4 -= reg8 * vec_vr; - reg5 -= reg9 * vec_vr; - reg2 -= reg8 * vec_vg; - reg3 -= reg9 * vec_vg; - reg0 = __msa_srai_w(reg0, 6); - reg1 = __msa_srai_w(reg1, 6); - reg2 = __msa_srai_w(reg2, 6); - reg3 = __msa_srai_w(reg3, 6); - reg4 = __msa_srai_w(reg4, 6); - reg5 = __msa_srai_w(reg5, 6); - CLIP_0TO255(reg0, reg1, reg2, reg3, reg4, reg5); - vec0 = (v8u16)__msa_pckev_h((v8i16)reg1, (v8i16)reg0); - vec1 = (v8u16)__msa_pckev_h((v8i16)reg3, (v8i16)reg2); - vec2 = (v8u16)__msa_pckev_h((v8i16)reg5, (v8i16)reg4); - vec0 = (v8u16)__msa_ilvev_b((v16i8)vec1, (v16i8)vec0); - vec1 = (v8u16)__msa_ilvev_b((v16i8)alpha, (v16i8)vec2); - dst0 = (v16u8)__msa_ilvr_h((v8i16)vec1, (v8i16)vec0); - dst1 = (v16u8)__msa_ilvl_h((v8i16)vec1, (v8i16)vec0); - ST_UB2(dst0, dst1, dst_argb, 16); - src_y += 8; - src_u += 8; - src_v += 8; - dst_argb += 32; - } -} - -void I400ToARGBRow_MSA(const uint8_t* src_y, uint8_t* dst_argb, int width) { - int x; - v16u8 src0, res0, res1, res2, res3, res4, dst0, dst1, dst2, dst3; - v8i16 vec0, vec1; - v4i32 reg0, reg1, reg2, reg3; - v4i32 vec_yg = __msa_fill_w(0x4A35); - v8i16 vec_ygb = __msa_fill_h(0xFB78); - v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); - v8i16 max = __msa_ldi_h(0xFF); - v8i16 zero = {0}; - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_y, 0); - vec0 = (v8i16)__msa_ilvr_b((v16i8)src0, (v16i8)src0); - vec1 = (v8i16)__msa_ilvl_b((v16i8)src0, (v16i8)src0); - reg0 = (v4i32)__msa_ilvr_h(zero, vec0); - reg1 = (v4i32)__msa_ilvl_h(zero, vec0); - reg2 = (v4i32)__msa_ilvr_h(zero, vec1); - reg3 = (v4i32)__msa_ilvl_h(zero, vec1); - reg0 *= vec_yg; - reg1 *= vec_yg; - reg2 *= vec_yg; - reg3 *= vec_yg; - reg0 = __msa_srai_w(reg0, 16); - reg1 = __msa_srai_w(reg1, 16); - reg2 = __msa_srai_w(reg2, 16); - reg3 = __msa_srai_w(reg3, 16); - vec0 = (v8i16)__msa_pckev_h((v8i16)reg1, (v8i16)reg0); - vec1 = (v8i16)__msa_pckev_h((v8i16)reg3, (v8i16)reg2); - vec0 += vec_ygb; - vec1 += vec_ygb; - vec0 = __msa_srai_h(vec0, 6); - vec1 = __msa_srai_h(vec1, 6); - vec0 = __msa_maxi_s_h(vec0, 0); - vec1 = __msa_maxi_s_h(vec1, 0); - vec0 = __msa_min_s_h(max, vec0); - vec1 = __msa_min_s_h(max, vec1); - res0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - res1 = (v16u8)__msa_ilvr_b((v16i8)res0, (v16i8)res0); - res2 = (v16u8)__msa_ilvl_b((v16i8)res0, (v16i8)res0); - res3 = (v16u8)__msa_ilvr_b((v16i8)alpha, (v16i8)res0); - res4 = (v16u8)__msa_ilvl_b((v16i8)alpha, (v16i8)res0); - dst0 = (v16u8)__msa_ilvr_b((v16i8)res3, (v16i8)res1); - dst1 = (v16u8)__msa_ilvl_b((v16i8)res3, (v16i8)res1); - dst2 = (v16u8)__msa_ilvr_b((v16i8)res4, (v16i8)res2); - dst3 = (v16u8)__msa_ilvl_b((v16i8)res4, (v16i8)res2); - ST_UB4(dst0, dst1, dst2, dst3, dst_argb, 16); - src_y += 16; - dst_argb += 64; - } -} - -void J400ToARGBRow_MSA(const uint8_t* src_y, uint8_t* dst_argb, int width) { - int x; - v16u8 src0, vec0, vec1, vec2, vec3, dst0, dst1, dst2, dst3; - v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_y, 0); - vec0 = (v16u8)__msa_ilvr_b((v16i8)src0, (v16i8)src0); - vec1 = (v16u8)__msa_ilvl_b((v16i8)src0, (v16i8)src0); - vec2 = (v16u8)__msa_ilvr_b((v16i8)alpha, (v16i8)src0); - vec3 = (v16u8)__msa_ilvl_b((v16i8)alpha, (v16i8)src0); - dst0 = (v16u8)__msa_ilvr_b((v16i8)vec2, (v16i8)vec0); - dst1 = (v16u8)__msa_ilvl_b((v16i8)vec2, (v16i8)vec0); - dst2 = (v16u8)__msa_ilvr_b((v16i8)vec3, (v16i8)vec1); - dst3 = (v16u8)__msa_ilvl_b((v16i8)vec3, (v16i8)vec1); - ST_UB4(dst0, dst1, dst2, dst3, dst_argb, 16); - src_y += 16; - dst_argb += 64; - } -} - -void YUY2ToARGBRow_MSA(const uint8_t* src_yuy2, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - int x; - v16u8 src0, src1, src2; - v8i16 vec0, vec1, vec2; - v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; - v4i32 vec_ubvr, vec_ugvg; - v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); - - YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, - vec_br, vec_yg); - vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); - vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); - - for (x = 0; x < width; x += 8) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_yuy2, 0); - src1 = (v16u8)__msa_pckev_b((v16i8)src0, (v16i8)src0); - src2 = (v16u8)__msa_pckod_b((v16i8)src0, (v16i8)src0); - YUVTORGB(src1, src2, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, - vec0, vec1, vec2); - STOREARGB(vec0, vec1, vec2, alpha, dst_argb); - src_yuy2 += 16; - dst_argb += 32; - } -} - -void UYVYToARGBRow_MSA(const uint8_t* src_uyvy, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - int x; - v16u8 src0, src1, src2; - v8i16 vec0, vec1, vec2; - v4i32 vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, vec_br, vec_yg; - v4i32 vec_ubvr, vec_ugvg; - v16u8 alpha = (v16u8)__msa_ldi_b(ALPHA_VAL); - - YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_bb, vec_bg, - vec_br, vec_yg); - vec_ubvr = __msa_ilvr_w(vec_vr, vec_ub); - vec_ugvg = (v4i32)__msa_ilvev_h((v8i16)vec_vg, (v8i16)vec_ug); - - for (x = 0; x < width; x += 8) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_uyvy, 0); - src1 = (v16u8)__msa_pckod_b((v16i8)src0, (v16i8)src0); - src2 = (v16u8)__msa_pckev_b((v16i8)src0, (v16i8)src0); - YUVTORGB(src1, src2, vec_ubvr, vec_ugvg, vec_bb, vec_bg, vec_br, vec_yg, - vec0, vec1, vec2); - STOREARGB(vec0, vec1, vec2, alpha, dst_argb); - src_uyvy += 16; - dst_argb += 32; - } -} - -void InterpolateRow_MSA(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride, - int width, - int32_t source_y_fraction) { - int32_t y1_fraction = source_y_fraction; - int32_t y0_fraction = 256 - y1_fraction; - uint16_t y_fractions; - const uint8_t* s = src_ptr; - const uint8_t* t = src_ptr + src_stride; - int x; - v16u8 src0, src1, src2, src3, dst0, dst1; - v8u16 vec0, vec1, vec2, vec3, y_frac; - - if (0 == y1_fraction) { - memcpy(dst_ptr, src_ptr, width); - return; - } - - if (128 == y1_fraction) { - for (x = 0; x < width; x += 32) { - src0 = (v16u8)__msa_ld_b((const v16i8*)s, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)s, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)t, 0); - src3 = (v16u8)__msa_ld_b((const v16i8*)t, 16); - dst0 = __msa_aver_u_b(src0, src2); - dst1 = __msa_aver_u_b(src1, src3); - ST_UB2(dst0, dst1, dst_ptr, 16); - s += 32; - t += 32; - dst_ptr += 32; - } - return; - } - - y_fractions = (uint16_t)(y0_fraction + (y1_fraction << 8)); - y_frac = (v8u16)__msa_fill_h(y_fractions); - - for (x = 0; x < width; x += 32) { - src0 = (v16u8)__msa_ld_b((const v16i8*)s, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)s, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)t, 0); - src3 = (v16u8)__msa_ld_b((const v16i8*)t, 16); - vec0 = (v8u16)__msa_ilvr_b((v16i8)src2, (v16i8)src0); - vec1 = (v8u16)__msa_ilvl_b((v16i8)src2, (v16i8)src0); - vec2 = (v8u16)__msa_ilvr_b((v16i8)src3, (v16i8)src1); - vec3 = (v8u16)__msa_ilvl_b((v16i8)src3, (v16i8)src1); - vec0 = (v8u16)__msa_dotp_u_h((v16u8)vec0, (v16u8)y_frac); - vec1 = (v8u16)__msa_dotp_u_h((v16u8)vec1, (v16u8)y_frac); - vec2 = (v8u16)__msa_dotp_u_h((v16u8)vec2, (v16u8)y_frac); - vec3 = (v8u16)__msa_dotp_u_h((v16u8)vec3, (v16u8)y_frac); - vec0 = (v8u16)__msa_srari_h((v8i16)vec0, 8); - vec1 = (v8u16)__msa_srari_h((v8i16)vec1, 8); - vec2 = (v8u16)__msa_srari_h((v8i16)vec2, 8); - vec3 = (v8u16)__msa_srari_h((v8i16)vec3, 8); - dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - dst1 = (v16u8)__msa_pckev_b((v16i8)vec3, (v16i8)vec2); - ST_UB2(dst0, dst1, dst_ptr, 16); - s += 32; - t += 32; - dst_ptr += 32; - } -} - -void ARGBSetRow_MSA(uint8_t* dst_argb, uint32_t v32, int width) { - int x; - v4i32 dst0 = __builtin_msa_fill_w(v32); - - for (x = 0; x < width; x += 4) { - ST_UB(dst0, dst_argb); - dst_argb += 16; - } -} - -void RAWToRGB24Row_MSA(const uint8_t* src_raw, uint8_t* dst_rgb24, int width) { - int x; - v16u8 src0, src1, src2, src3, src4, dst0, dst1, dst2; - v16i8 shuffler0 = {2, 1, 0, 5, 4, 3, 8, 7, 6, 11, 10, 9, 14, 13, 12, 17}; - v16i8 shuffler1 = {8, 7, 12, 11, 10, 15, 14, 13, - 18, 17, 16, 21, 20, 19, 24, 23}; - v16i8 shuffler2 = {14, 19, 18, 17, 22, 21, 20, 25, - 24, 23, 28, 27, 26, 31, 30, 29}; - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_raw, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_raw, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_raw, 32); - src3 = (v16u8)__msa_sldi_b((v16i8)src1, (v16i8)src0, 8); - src4 = (v16u8)__msa_sldi_b((v16i8)src2, (v16i8)src1, 8); - dst0 = (v16u8)__msa_vshf_b(shuffler0, (v16i8)src1, (v16i8)src0); - dst1 = (v16u8)__msa_vshf_b(shuffler1, (v16i8)src4, (v16i8)src3); - dst2 = (v16u8)__msa_vshf_b(shuffler2, (v16i8)src2, (v16i8)src1); - ST_UB2(dst0, dst1, dst_rgb24, 16); - ST_UB(dst2, (dst_rgb24 + 32)); - src_raw += 48; - dst_rgb24 += 48; - } -} - -void MergeUVRow_MSA(const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uv, - int width) { - int x; - v16u8 src0, src1, dst0, dst1; - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_u, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_v, 0); - dst0 = (v16u8)__msa_ilvr_b((v16i8)src1, (v16i8)src0); - dst1 = (v16u8)__msa_ilvl_b((v16i8)src1, (v16i8)src0); - ST_UB2(dst0, dst1, dst_uv, 16); - src_u += 16; - src_v += 16; - dst_uv += 32; - } -} - -void ARGBExtractAlphaRow_MSA(const uint8_t* src_argb, - uint8_t* dst_a, - int width) { - int i; - v16u8 src0, src1, src2, src3, vec0, vec1, dst0; - - for (i = 0; i < width; i += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 32); - src3 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 48); - vec0 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0); - vec1 = (v16u8)__msa_pckod_b((v16i8)src3, (v16i8)src2); - dst0 = (v16u8)__msa_pckod_b((v16i8)vec1, (v16i8)vec0); - ST_UB(dst0, dst_a); - src_argb += 64; - dst_a += 16; - } -} - -void ARGBBlendRow_MSA(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - int x; - v16u8 src0, src1, src2, src3, dst0, dst1; - v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8u16 vec8, vec9, vec10, vec11, vec12, vec13; - v8u16 const_256 = (v8u16)__msa_ldi_h(256); - v16u8 const_255 = (v16u8)__msa_ldi_b(255); - v16u8 mask = {0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255}; - v16i8 zero = {0}; - - for (x = 0; x < width; x += 8) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb0, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_argb1, 0); - src3 = (v16u8)__msa_ld_b((const v16i8*)src_argb1, 16); - vec0 = (v8u16)__msa_ilvr_b(zero, (v16i8)src0); - vec1 = (v8u16)__msa_ilvl_b(zero, (v16i8)src0); - vec2 = (v8u16)__msa_ilvr_b(zero, (v16i8)src1); - vec3 = (v8u16)__msa_ilvl_b(zero, (v16i8)src1); - vec4 = (v8u16)__msa_ilvr_b(zero, (v16i8)src2); - vec5 = (v8u16)__msa_ilvl_b(zero, (v16i8)src2); - vec6 = (v8u16)__msa_ilvr_b(zero, (v16i8)src3); - vec7 = (v8u16)__msa_ilvl_b(zero, (v16i8)src3); - vec8 = (v8u16)__msa_fill_h(vec0[3]); - vec9 = (v8u16)__msa_fill_h(vec0[7]); - vec10 = (v8u16)__msa_fill_h(vec1[3]); - vec11 = (v8u16)__msa_fill_h(vec1[7]); - vec8 = (v8u16)__msa_pckev_d((v2i64)vec9, (v2i64)vec8); - vec9 = (v8u16)__msa_pckev_d((v2i64)vec11, (v2i64)vec10); - vec10 = (v8u16)__msa_fill_h(vec2[3]); - vec11 = (v8u16)__msa_fill_h(vec2[7]); - vec12 = (v8u16)__msa_fill_h(vec3[3]); - vec13 = (v8u16)__msa_fill_h(vec3[7]); - vec10 = (v8u16)__msa_pckev_d((v2i64)vec11, (v2i64)vec10); - vec11 = (v8u16)__msa_pckev_d((v2i64)vec13, (v2i64)vec12); - vec8 = const_256 - vec8; - vec9 = const_256 - vec9; - vec10 = const_256 - vec10; - vec11 = const_256 - vec11; - vec8 *= vec4; - vec9 *= vec5; - vec10 *= vec6; - vec11 *= vec7; - vec8 = (v8u16)__msa_srai_h((v8i16)vec8, 8); - vec9 = (v8u16)__msa_srai_h((v8i16)vec9, 8); - vec10 = (v8u16)__msa_srai_h((v8i16)vec10, 8); - vec11 = (v8u16)__msa_srai_h((v8i16)vec11, 8); - vec0 += vec8; - vec1 += vec9; - vec2 += vec10; - vec3 += vec11; - dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - dst1 = (v16u8)__msa_pckev_b((v16i8)vec3, (v16i8)vec2); - dst0 = __msa_bmnz_v(dst0, const_255, mask); - dst1 = __msa_bmnz_v(dst1, const_255, mask); - ST_UB2(dst0, dst1, dst_argb, 16); - src_argb0 += 32; - src_argb1 += 32; - dst_argb += 32; - } -} - -void ARGBQuantizeRow_MSA(uint8_t* dst_argb, - int scale, - int interval_size, - int interval_offset, - int width) { - int x; - v16u8 src0, src1, src2, src3, dst0, dst1, dst2, dst3; - v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v4i32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - v4i32 tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15; - v4i32 vec_scale = __msa_fill_w(scale); - v16u8 vec_int_sz = (v16u8)__msa_fill_b(interval_size); - v16u8 vec_int_ofst = (v16u8)__msa_fill_b(interval_offset); - v16i8 mask = {0, 1, 2, 19, 4, 5, 6, 23, 8, 9, 10, 27, 12, 13, 14, 31}; - v16i8 zero = {0}; - - for (x = 0; x < width; x += 8) { - src0 = (v16u8)__msa_ld_b((v16i8*)dst_argb, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)dst_argb, 16); - src2 = (v16u8)__msa_ld_b((v16i8*)dst_argb, 32); - src3 = (v16u8)__msa_ld_b((v16i8*)dst_argb, 48); - vec0 = (v8i16)__msa_ilvr_b(zero, (v16i8)src0); - vec1 = (v8i16)__msa_ilvl_b(zero, (v16i8)src0); - vec2 = (v8i16)__msa_ilvr_b(zero, (v16i8)src1); - vec3 = (v8i16)__msa_ilvl_b(zero, (v16i8)src1); - vec4 = (v8i16)__msa_ilvr_b(zero, (v16i8)src2); - vec5 = (v8i16)__msa_ilvl_b(zero, (v16i8)src2); - vec6 = (v8i16)__msa_ilvr_b(zero, (v16i8)src3); - vec7 = (v8i16)__msa_ilvl_b(zero, (v16i8)src3); - tmp0 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec0); - tmp1 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec0); - tmp2 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec1); - tmp3 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec1); - tmp4 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec2); - tmp5 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec2); - tmp6 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec3); - tmp7 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec3); - tmp8 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec4); - tmp9 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec4); - tmp10 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec5); - tmp11 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec5); - tmp12 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec6); - tmp13 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec6); - tmp14 = (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)vec7); - tmp15 = (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)vec7); - tmp0 *= vec_scale; - tmp1 *= vec_scale; - tmp2 *= vec_scale; - tmp3 *= vec_scale; - tmp4 *= vec_scale; - tmp5 *= vec_scale; - tmp6 *= vec_scale; - tmp7 *= vec_scale; - tmp8 *= vec_scale; - tmp9 *= vec_scale; - tmp10 *= vec_scale; - tmp11 *= vec_scale; - tmp12 *= vec_scale; - tmp13 *= vec_scale; - tmp14 *= vec_scale; - tmp15 *= vec_scale; - tmp0 >>= 16; - tmp1 >>= 16; - tmp2 >>= 16; - tmp3 >>= 16; - tmp4 >>= 16; - tmp5 >>= 16; - tmp6 >>= 16; - tmp7 >>= 16; - tmp8 >>= 16; - tmp9 >>= 16; - tmp10 >>= 16; - tmp11 >>= 16; - tmp12 >>= 16; - tmp13 >>= 16; - tmp14 >>= 16; - tmp15 >>= 16; - vec0 = (v8i16)__msa_pckev_h((v8i16)tmp1, (v8i16)tmp0); - vec1 = (v8i16)__msa_pckev_h((v8i16)tmp3, (v8i16)tmp2); - vec2 = (v8i16)__msa_pckev_h((v8i16)tmp5, (v8i16)tmp4); - vec3 = (v8i16)__msa_pckev_h((v8i16)tmp7, (v8i16)tmp6); - vec4 = (v8i16)__msa_pckev_h((v8i16)tmp9, (v8i16)tmp8); - vec5 = (v8i16)__msa_pckev_h((v8i16)tmp11, (v8i16)tmp10); - vec6 = (v8i16)__msa_pckev_h((v8i16)tmp13, (v8i16)tmp12); - vec7 = (v8i16)__msa_pckev_h((v8i16)tmp15, (v8i16)tmp14); - dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - dst1 = (v16u8)__msa_pckev_b((v16i8)vec3, (v16i8)vec2); - dst2 = (v16u8)__msa_pckev_b((v16i8)vec5, (v16i8)vec4); - dst3 = (v16u8)__msa_pckev_b((v16i8)vec7, (v16i8)vec6); - dst0 *= vec_int_sz; - dst1 *= vec_int_sz; - dst2 *= vec_int_sz; - dst3 *= vec_int_sz; - dst0 += vec_int_ofst; - dst1 += vec_int_ofst; - dst2 += vec_int_ofst; - dst3 += vec_int_ofst; - dst0 = (v16u8)__msa_vshf_b(mask, (v16i8)src0, (v16i8)dst0); - dst1 = (v16u8)__msa_vshf_b(mask, (v16i8)src1, (v16i8)dst1); - dst2 = (v16u8)__msa_vshf_b(mask, (v16i8)src2, (v16i8)dst2); - dst3 = (v16u8)__msa_vshf_b(mask, (v16i8)src3, (v16i8)dst3); - ST_UB4(dst0, dst1, dst2, dst3, dst_argb, 16); - dst_argb += 64; - } -} - -void ARGBColorMatrixRow_MSA(const uint8_t* src_argb, - uint8_t* dst_argb, - const int8_t* matrix_argb, - int width) { - int32_t x; - v16i8 src0; - v16u8 src1, src2, dst0, dst1; - v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9; - v8i16 vec10, vec11, vec12, vec13, vec14, vec15, vec16, vec17; - v4i32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - v4i32 tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15; - v16i8 zero = {0}; - v8i16 max = __msa_ldi_h(255); - - src0 = __msa_ld_b((v16i8*)matrix_argb, 0); - vec0 = (v8i16)__msa_ilvr_b(zero, src0); - vec1 = (v8i16)__msa_ilvl_b(zero, src0); - - for (x = 0; x < width; x += 8) { - src1 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 0); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_argb, 16); - vec2 = (v8i16)__msa_ilvr_b(zero, (v16i8)src1); - vec3 = (v8i16)__msa_ilvl_b(zero, (v16i8)src1); - vec4 = (v8i16)__msa_ilvr_b(zero, (v16i8)src2); - vec5 = (v8i16)__msa_ilvl_b(zero, (v16i8)src2); - vec6 = (v8i16)__msa_pckod_d((v2i64)vec2, (v2i64)vec2); - vec7 = (v8i16)__msa_pckod_d((v2i64)vec3, (v2i64)vec3); - vec8 = (v8i16)__msa_pckod_d((v2i64)vec4, (v2i64)vec4); - vec9 = (v8i16)__msa_pckod_d((v2i64)vec5, (v2i64)vec5); - vec2 = (v8i16)__msa_pckev_d((v2i64)vec2, (v2i64)vec2); - vec3 = (v8i16)__msa_pckev_d((v2i64)vec3, (v2i64)vec3); - vec4 = (v8i16)__msa_pckev_d((v2i64)vec4, (v2i64)vec4); - vec5 = (v8i16)__msa_pckev_d((v2i64)vec5, (v2i64)vec5); - vec10 = vec2 * vec0; - vec11 = vec2 * vec1; - vec12 = vec6 * vec0; - vec13 = vec6 * vec1; - tmp0 = __msa_hadd_s_w(vec10, vec10); - tmp1 = __msa_hadd_s_w(vec11, vec11); - tmp2 = __msa_hadd_s_w(vec12, vec12); - tmp3 = __msa_hadd_s_w(vec13, vec13); - vec14 = vec3 * vec0; - vec15 = vec3 * vec1; - vec16 = vec7 * vec0; - vec17 = vec7 * vec1; - tmp4 = __msa_hadd_s_w(vec14, vec14); - tmp5 = __msa_hadd_s_w(vec15, vec15); - tmp6 = __msa_hadd_s_w(vec16, vec16); - tmp7 = __msa_hadd_s_w(vec17, vec17); - vec10 = __msa_pckev_h((v8i16)tmp1, (v8i16)tmp0); - vec11 = __msa_pckev_h((v8i16)tmp3, (v8i16)tmp2); - vec12 = __msa_pckev_h((v8i16)tmp5, (v8i16)tmp4); - vec13 = __msa_pckev_h((v8i16)tmp7, (v8i16)tmp6); - tmp0 = __msa_hadd_s_w(vec10, vec10); - tmp1 = __msa_hadd_s_w(vec11, vec11); - tmp2 = __msa_hadd_s_w(vec12, vec12); - tmp3 = __msa_hadd_s_w(vec13, vec13); - tmp0 = __msa_srai_w(tmp0, 6); - tmp1 = __msa_srai_w(tmp1, 6); - tmp2 = __msa_srai_w(tmp2, 6); - tmp3 = __msa_srai_w(tmp3, 6); - vec2 = vec4 * vec0; - vec6 = vec4 * vec1; - vec3 = vec8 * vec0; - vec7 = vec8 * vec1; - tmp8 = __msa_hadd_s_w(vec2, vec2); - tmp9 = __msa_hadd_s_w(vec6, vec6); - tmp10 = __msa_hadd_s_w(vec3, vec3); - tmp11 = __msa_hadd_s_w(vec7, vec7); - vec4 = vec5 * vec0; - vec8 = vec5 * vec1; - vec5 = vec9 * vec0; - vec9 = vec9 * vec1; - tmp12 = __msa_hadd_s_w(vec4, vec4); - tmp13 = __msa_hadd_s_w(vec8, vec8); - tmp14 = __msa_hadd_s_w(vec5, vec5); - tmp15 = __msa_hadd_s_w(vec9, vec9); - vec14 = __msa_pckev_h((v8i16)tmp9, (v8i16)tmp8); - vec15 = __msa_pckev_h((v8i16)tmp11, (v8i16)tmp10); - vec16 = __msa_pckev_h((v8i16)tmp13, (v8i16)tmp12); - vec17 = __msa_pckev_h((v8i16)tmp15, (v8i16)tmp14); - tmp4 = __msa_hadd_s_w(vec14, vec14); - tmp5 = __msa_hadd_s_w(vec15, vec15); - tmp6 = __msa_hadd_s_w(vec16, vec16); - tmp7 = __msa_hadd_s_w(vec17, vec17); - tmp4 = __msa_srai_w(tmp4, 6); - tmp5 = __msa_srai_w(tmp5, 6); - tmp6 = __msa_srai_w(tmp6, 6); - tmp7 = __msa_srai_w(tmp7, 6); - vec10 = __msa_pckev_h((v8i16)tmp1, (v8i16)tmp0); - vec11 = __msa_pckev_h((v8i16)tmp3, (v8i16)tmp2); - vec12 = __msa_pckev_h((v8i16)tmp5, (v8i16)tmp4); - vec13 = __msa_pckev_h((v8i16)tmp7, (v8i16)tmp6); - vec10 = __msa_maxi_s_h(vec10, 0); - vec11 = __msa_maxi_s_h(vec11, 0); - vec12 = __msa_maxi_s_h(vec12, 0); - vec13 = __msa_maxi_s_h(vec13, 0); - vec10 = __msa_min_s_h(vec10, max); - vec11 = __msa_min_s_h(vec11, max); - vec12 = __msa_min_s_h(vec12, max); - vec13 = __msa_min_s_h(vec13, max); - dst0 = (v16u8)__msa_pckev_b((v16i8)vec11, (v16i8)vec10); - dst1 = (v16u8)__msa_pckev_b((v16i8)vec13, (v16i8)vec12); - ST_UB2(dst0, dst1, dst_argb, 16); - src_argb += 32; - dst_argb += 32; - } -} - -void SplitUVRow_MSA(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - int x; - v16u8 src0, src1, src2, src3, dst0, dst1, dst2, dst3; - - for (x = 0; x < width; x += 32) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_uv, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_uv, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_uv, 32); - src3 = (v16u8)__msa_ld_b((const v16i8*)src_uv, 48); - dst0 = (v16u8)__msa_pckev_b((v16i8)src1, (v16i8)src0); - dst1 = (v16u8)__msa_pckev_b((v16i8)src3, (v16i8)src2); - dst2 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0); - dst3 = (v16u8)__msa_pckod_b((v16i8)src3, (v16i8)src2); - ST_UB2(dst0, dst1, dst_u, 16); - ST_UB2(dst2, dst3, dst_v, 16); - src_uv += 64; - dst_u += 32; - dst_v += 32; - } -} - -void SetRow_MSA(uint8_t* dst, uint8_t v8, int width) { - int x; - v16u8 dst0 = (v16u8)__msa_fill_b(v8); - - for (x = 0; x < width; x += 16) { - ST_UB(dst0, dst); - dst += 16; - } -} - -void MirrorUVRow_MSA(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - int x; - v16u8 src0, src1, src2, src3; - v16u8 dst0, dst1, dst2, dst3; - v16i8 mask0 = {30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0}; - v16i8 mask1 = {31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1}; - - src_uv += (2 * width); - - for (x = 0; x < width; x += 32) { - src_uv -= 64; - src2 = (v16u8)__msa_ld_b((const v16i8*)src_uv, 0); - src3 = (v16u8)__msa_ld_b((const v16i8*)src_uv, 16); - src0 = (v16u8)__msa_ld_b((const v16i8*)src_uv, 32); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_uv, 48); - dst0 = (v16u8)__msa_vshf_b(mask1, (v16i8)src1, (v16i8)src0); - dst1 = (v16u8)__msa_vshf_b(mask1, (v16i8)src3, (v16i8)src2); - dst2 = (v16u8)__msa_vshf_b(mask0, (v16i8)src1, (v16i8)src0); - dst3 = (v16u8)__msa_vshf_b(mask0, (v16i8)src3, (v16i8)src2); - ST_UB2(dst0, dst1, dst_v, 16); - ST_UB2(dst2, dst3, dst_u, 16); - dst_u += 32; - dst_v += 32; - } -} - -void SobelXRow_MSA(const uint8_t* src_y0, - const uint8_t* src_y1, - const uint8_t* src_y2, - uint8_t* dst_sobelx, - int32_t width) { - int x; - v16u8 src0, src1, src2, src3, src4, src5, dst0; - v8i16 vec0, vec1, vec2, vec3, vec4, vec5; - v16i8 mask0 = {0, 2, 1, 3, 2, 4, 3, 5, 4, 6, 5, 7, 6, 8, 7, 9}; - v16i8 tmp = __msa_ldi_b(8); - v16i8 mask1 = mask0 + tmp; - v8i16 zero = {0}; - v8i16 max = __msa_ldi_h(255); - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_y0, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_y0, 16); - src2 = (v16u8)__msa_ld_b((const v16i8*)src_y1, 0); - src3 = (v16u8)__msa_ld_b((const v16i8*)src_y1, 16); - src4 = (v16u8)__msa_ld_b((const v16i8*)src_y2, 0); - src5 = (v16u8)__msa_ld_b((const v16i8*)src_y2, 16); - vec0 = (v8i16)__msa_vshf_b(mask0, (v16i8)src1, (v16i8)src0); - vec1 = (v8i16)__msa_vshf_b(mask1, (v16i8)src1, (v16i8)src0); - vec2 = (v8i16)__msa_vshf_b(mask0, (v16i8)src3, (v16i8)src2); - vec3 = (v8i16)__msa_vshf_b(mask1, (v16i8)src3, (v16i8)src2); - vec4 = (v8i16)__msa_vshf_b(mask0, (v16i8)src5, (v16i8)src4); - vec5 = (v8i16)__msa_vshf_b(mask1, (v16i8)src5, (v16i8)src4); - vec0 = (v8i16)__msa_hsub_u_h((v16u8)vec0, (v16u8)vec0); - vec1 = (v8i16)__msa_hsub_u_h((v16u8)vec1, (v16u8)vec1); - vec2 = (v8i16)__msa_hsub_u_h((v16u8)vec2, (v16u8)vec2); - vec3 = (v8i16)__msa_hsub_u_h((v16u8)vec3, (v16u8)vec3); - vec4 = (v8i16)__msa_hsub_u_h((v16u8)vec4, (v16u8)vec4); - vec5 = (v8i16)__msa_hsub_u_h((v16u8)vec5, (v16u8)vec5); - vec0 += vec2; - vec1 += vec3; - vec4 += vec2; - vec5 += vec3; - vec0 += vec4; - vec1 += vec5; - vec0 = __msa_add_a_h(zero, vec0); - vec1 = __msa_add_a_h(zero, vec1); - vec0 = __msa_maxi_s_h(vec0, 0); - vec1 = __msa_maxi_s_h(vec1, 0); - vec0 = __msa_min_s_h(max, vec0); - vec1 = __msa_min_s_h(max, vec1); - dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - ST_UB(dst0, dst_sobelx); - src_y0 += 16; - src_y1 += 16; - src_y2 += 16; - dst_sobelx += 16; - } -} - -void SobelYRow_MSA(const uint8_t* src_y0, - const uint8_t* src_y1, - uint8_t* dst_sobely, - int32_t width) { - int x; - v16u8 src0, src1, dst0; - v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6; - v8i16 zero = {0}; - v8i16 max = __msa_ldi_h(255); - - for (x = 0; x < width; x += 16) { - src0 = (v16u8)__msa_ld_b((const v16i8*)src_y0, 0); - src1 = (v16u8)__msa_ld_b((const v16i8*)src_y1, 0); - vec0 = (v8i16)__msa_ilvr_b((v16i8)zero, (v16i8)src0); - vec1 = (v8i16)__msa_ilvl_b((v16i8)zero, (v16i8)src0); - vec2 = (v8i16)__msa_ilvr_b((v16i8)zero, (v16i8)src1); - vec3 = (v8i16)__msa_ilvl_b((v16i8)zero, (v16i8)src1); - vec0 -= vec2; - vec1 -= vec3; - vec6[0] = src_y0[16] - src_y1[16]; - vec6[1] = src_y0[17] - src_y1[17]; - vec2 = (v8i16)__msa_sldi_b((v16i8)vec1, (v16i8)vec0, 2); - vec3 = (v8i16)__msa_sldi_b((v16i8)vec6, (v16i8)vec1, 2); - vec4 = (v8i16)__msa_sldi_b((v16i8)vec1, (v16i8)vec0, 4); - vec5 = (v8i16)__msa_sldi_b((v16i8)vec6, (v16i8)vec1, 4); - vec0 += vec2; - vec1 += vec3; - vec4 += vec2; - vec5 += vec3; - vec0 += vec4; - vec1 += vec5; - vec0 = __msa_add_a_h(zero, vec0); - vec1 = __msa_add_a_h(zero, vec1); - vec0 = __msa_maxi_s_h(vec0, 0); - vec1 = __msa_maxi_s_h(vec1, 0); - vec0 = __msa_min_s_h(max, vec0); - vec1 = __msa_min_s_h(max, vec1); - dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - ST_UB(dst0, dst_sobely); - src_y0 += 16; - src_y1 += 16; - dst_sobely += 16; - } -} - -void HalfFloatRow_MSA(const uint16_t* src, - uint16_t* dst, - float scale, - int width) { - int i; - v8u16 src0, src1, src2, src3, dst0, dst1, dst2, dst3; - v4u32 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v4f32 fvec0, fvec1, fvec2, fvec3, fvec4, fvec5, fvec6, fvec7; - v4f32 mult_vec; - v8i16 zero = {0}; - mult_vec[0] = 1.9259299444e-34f * scale; - mult_vec = (v4f32)__msa_splati_w((v4i32)mult_vec, 0); - - for (i = 0; i < width; i += 32) { - src0 = (v8u16)__msa_ld_h((v8i16*)src, 0); - src1 = (v8u16)__msa_ld_h((v8i16*)src, 16); - src2 = (v8u16)__msa_ld_h((v8i16*)src, 32); - src3 = (v8u16)__msa_ld_h((v8i16*)src, 48); - vec0 = (v4u32)__msa_ilvr_h(zero, (v8i16)src0); - vec1 = (v4u32)__msa_ilvl_h(zero, (v8i16)src0); - vec2 = (v4u32)__msa_ilvr_h(zero, (v8i16)src1); - vec3 = (v4u32)__msa_ilvl_h(zero, (v8i16)src1); - vec4 = (v4u32)__msa_ilvr_h(zero, (v8i16)src2); - vec5 = (v4u32)__msa_ilvl_h(zero, (v8i16)src2); - vec6 = (v4u32)__msa_ilvr_h(zero, (v8i16)src3); - vec7 = (v4u32)__msa_ilvl_h(zero, (v8i16)src3); - fvec0 = __msa_ffint_u_w(vec0); - fvec1 = __msa_ffint_u_w(vec1); - fvec2 = __msa_ffint_u_w(vec2); - fvec3 = __msa_ffint_u_w(vec3); - fvec4 = __msa_ffint_u_w(vec4); - fvec5 = __msa_ffint_u_w(vec5); - fvec6 = __msa_ffint_u_w(vec6); - fvec7 = __msa_ffint_u_w(vec7); - fvec0 *= mult_vec; - fvec1 *= mult_vec; - fvec2 *= mult_vec; - fvec3 *= mult_vec; - fvec4 *= mult_vec; - fvec5 *= mult_vec; - fvec6 *= mult_vec; - fvec7 *= mult_vec; - vec0 = ((v4u32)fvec0) >> 13; - vec1 = ((v4u32)fvec1) >> 13; - vec2 = ((v4u32)fvec2) >> 13; - vec3 = ((v4u32)fvec3) >> 13; - vec4 = ((v4u32)fvec4) >> 13; - vec5 = ((v4u32)fvec5) >> 13; - vec6 = ((v4u32)fvec6) >> 13; - vec7 = ((v4u32)fvec7) >> 13; - dst0 = (v8u16)__msa_pckev_h((v8i16)vec1, (v8i16)vec0); - dst1 = (v8u16)__msa_pckev_h((v8i16)vec3, (v8i16)vec2); - dst2 = (v8u16)__msa_pckev_h((v8i16)vec5, (v8i16)vec4); - dst3 = (v8u16)__msa_pckev_h((v8i16)vec7, (v8i16)vec6); - ST_UH2(dst0, dst1, dst, 8); - ST_UH2(dst2, dst3, dst + 16, 8); - src += 32; - dst += 32; - } -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_neon.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_neon.cc deleted file mode 100644 index ff87e74c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_neon.cc +++ /dev/null @@ -1,2693 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/row.h" - -#include - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// This module is for GCC Neon -#if !defined(LIBYUV_DISABLE_NEON) && defined(__ARM_NEON__) && \ - !defined(__aarch64__) - -// Read 8 Y, 4 U and 4 V from 422 -#define READYUV422 \ - "vld1.8 {d0}, [%0]! \n" \ - "vld1.32 {d2[0]}, [%1]! \n" \ - "vld1.32 {d2[1]}, [%2]! \n" - -// Read 8 Y, 8 U and 8 V from 444 -#define READYUV444 \ - "vld1.8 {d0}, [%0]! \n" \ - "vld1.8 {d2}, [%1]! \n" \ - "vld1.8 {d3}, [%2]! \n" \ - "vpaddl.u8 q1, q1 \n" \ - "vrshrn.u16 d2, q1, #1 \n" - -// Read 8 Y, and set 4 U and 4 V to 128 -#define READYUV400 \ - "vld1.8 {d0}, [%0]! \n" \ - "vmov.u8 d2, #128 \n" - -// Read 8 Y and 4 UV from NV12 -#define READNV12 \ - "vld1.8 {d0}, [%0]! \n" \ - "vld1.8 {d2}, [%1]! \n" \ - "vmov.u8 d3, d2 \n" /* split odd/even uv apart */ \ - "vuzp.u8 d2, d3 \n" \ - "vtrn.u32 d2, d3 \n" - -// Read 8 Y and 4 VU from NV21 -#define READNV21 \ - "vld1.8 {d0}, [%0]! \n" \ - "vld1.8 {d2}, [%1]! \n" \ - "vmov.u8 d3, d2 \n" /* split odd/even uv apart */ \ - "vuzp.u8 d3, d2 \n" \ - "vtrn.u32 d2, d3 \n" - -// Read 8 YUY2 -#define READYUY2 \ - "vld2.8 {d0, d2}, [%0]! \n" \ - "vmov.u8 d3, d2 \n" \ - "vuzp.u8 d2, d3 \n" \ - "vtrn.u32 d2, d3 \n" - -// Read 8 UYVY -#define READUYVY \ - "vld2.8 {d2, d3}, [%0]! \n" \ - "vmov.u8 d0, d3 \n" \ - "vmov.u8 d3, d2 \n" \ - "vuzp.u8 d2, d3 \n" \ - "vtrn.u32 d2, d3 \n" - -#define YUVTORGB_SETUP \ - "vld1.8 {d24}, [%[kUVToRB]] \n" \ - "vld1.8 {d25}, [%[kUVToG]] \n" \ - "vld1.16 {d26[], d27[]}, [%[kUVBiasBGR]]! \n" \ - "vld1.16 {d8[], d9[]}, [%[kUVBiasBGR]]! \n" \ - "vld1.16 {d28[], d29[]}, [%[kUVBiasBGR]] \n" \ - "vld1.32 {d30[], d31[]}, [%[kYToRgb]] \n" - -#define YUVTORGB \ - "vmull.u8 q8, d2, d24 \n" /* u/v B/R component */ \ - "vmull.u8 q9, d2, d25 \n" /* u/v G component */ \ - "vmovl.u8 q0, d0 \n" /* Y */ \ - "vmovl.s16 q10, d1 \n" \ - "vmovl.s16 q0, d0 \n" \ - "vmul.s32 q10, q10, q15 \n" \ - "vmul.s32 q0, q0, q15 \n" \ - "vqshrun.s32 d0, q0, #16 \n" \ - "vqshrun.s32 d1, q10, #16 \n" /* Y */ \ - "vadd.s16 d18, d19 \n" \ - "vshll.u16 q1, d16, #16 \n" /* Replicate u * UB */ \ - "vshll.u16 q10, d17, #16 \n" /* Replicate v * VR */ \ - "vshll.u16 q3, d18, #16 \n" /* Replicate (v*VG + u*UG)*/ \ - "vaddw.u16 q1, q1, d16 \n" \ - "vaddw.u16 q10, q10, d17 \n" \ - "vaddw.u16 q3, q3, d18 \n" \ - "vqadd.s16 q8, q0, q13 \n" /* B */ \ - "vqadd.s16 q9, q0, q14 \n" /* R */ \ - "vqadd.s16 q0, q0, q4 \n" /* G */ \ - "vqadd.s16 q8, q8, q1 \n" /* B */ \ - "vqadd.s16 q9, q9, q10 \n" /* R */ \ - "vqsub.s16 q0, q0, q3 \n" /* G */ \ - "vqshrun.s16 d20, q8, #6 \n" /* B */ \ - "vqshrun.s16 d22, q9, #6 \n" /* R */ \ - "vqshrun.s16 d21, q0, #6 \n" /* G */ - -void I444ToARGBRow_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile( - YUVTORGB_SETUP - "vmov.u8 d23, #255 \n" - "1: \n" READYUV444 YUVTORGB - "subs %4, %4, #8 \n" - "vst4.8 {d20, d21, d22, d23}, [%3]! \n" - "bgt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_argb), // %3 - "+r"(width) // %4 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", - "q12", "q13", "q14", "q15"); -} - -void I422ToARGBRow_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile( - YUVTORGB_SETUP - "vmov.u8 d23, #255 \n" - "1: \n" READYUV422 YUVTORGB - "subs %4, %4, #8 \n" - "vst4.8 {d20, d21, d22, d23}, [%3]! \n" - "bgt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_argb), // %3 - "+r"(width) // %4 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", - "q12", "q13", "q14", "q15"); -} - -void I422AlphaToARGBRow_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - const uint8_t* src_a, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile( - YUVTORGB_SETUP - "1: \n" READYUV422 YUVTORGB - "subs %5, %5, #8 \n" - "vld1.8 {d23}, [%3]! \n" - "vst4.8 {d20, d21, d22, d23}, [%4]! \n" - "bgt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(src_a), // %3 - "+r"(dst_argb), // %4 - "+r"(width) // %5 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", - "q12", "q13", "q14", "q15"); -} - -void I422ToRGBARow_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgba, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile( - YUVTORGB_SETUP - "1: \n" READYUV422 YUVTORGB - "subs %4, %4, #8 \n" - "vmov.u8 d19, #255 \n" // YUVTORGB modified d19 - "vst4.8 {d19, d20, d21, d22}, [%3]! \n" - "bgt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_rgba), // %3 - "+r"(width) // %4 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", - "q12", "q13", "q14", "q15"); -} - -void I422ToRGB24Row_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile( - YUVTORGB_SETUP - "1: \n" READYUV422 YUVTORGB - "subs %4, %4, #8 \n" - "vst3.8 {d20, d21, d22}, [%3]! \n" - "bgt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_rgb24), // %3 - "+r"(width) // %4 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", - "q12", "q13", "q14", "q15"); -} - -#define ARGBTORGB565 \ - "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_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile( - YUVTORGB_SETUP - "1: \n" READYUV422 YUVTORGB - "subs %4, %4, #8 \n" ARGBTORGB565 - "vst1.8 {q0}, [%3]! \n" // store 8 pixels RGB565. - "bgt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_rgb565), // %3 - "+r"(width) // %4 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", - "q12", "q13", "q14", "q15"); -} - -#define ARGBTOARGB1555 \ - "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_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb1555, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile( - YUVTORGB_SETUP - "1: \n" READYUV422 YUVTORGB - "subs %4, %4, #8 \n" - "vmov.u8 d23, #255 \n" ARGBTOARGB1555 - "vst1.8 {q0}, [%3]! \n" // store 8 pixels - "bgt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_argb1555), // %3 - "+r"(width) // %4 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", - "q12", "q13", "q14", "q15"); -} - -#define ARGBTOARGB4444 \ - "vshr.u8 d20, d20, #4 \n" /* B */ \ - "vbic.32 d21, d21, d4 \n" /* G */ \ - "vshr.u8 d22, d22, #4 \n" /* R */ \ - "vbic.32 d23, d23, d4 \n" /* A */ \ - "vorr d0, d20, d21 \n" /* BG */ \ - "vorr d1, d22, d23 \n" /* RA */ \ - "vzip.u8 d0, d1 \n" /* BGRA */ - -void I422ToARGB4444Row_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb4444, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile( - YUVTORGB_SETUP - "vmov.u8 d4, #0x0f \n" // vbic bits to clear - "1: \n" - - READYUV422 YUVTORGB - "subs %4, %4, #8 \n" - "vmov.u8 d23, #255 \n" ARGBTOARGB4444 - "vst1.8 {q0}, [%3]! \n" // store 8 pixels - "bgt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_argb4444), // %3 - "+r"(width) // %4 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", - "q12", "q13", "q14", "q15"); -} - -void I400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width) { - asm volatile( - YUVTORGB_SETUP - "vmov.u8 d23, #255 \n" - "1: \n" READYUV400 YUVTORGB - "subs %2, %2, #8 \n" - "vst4.8 {d20, d21, d22, d23}, [%1]! \n" - "bgt 1b \n" - : "+r"(src_y), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : [kUVToRB] "r"(&kYuvI601Constants.kUVToRB), - [kUVToG] "r"(&kYuvI601Constants.kUVToG), - [kUVBiasBGR] "r"(&kYuvI601Constants.kUVBiasBGR), - [kYToRgb] "r"(&kYuvI601Constants.kYToRgb) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", - "q12", "q13", "q14", "q15"); -} - -void J400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width) { - asm volatile( - "vmov.u8 d23, #255 \n" - "1: \n" - "vld1.8 {d20}, [%0]! \n" - "vmov d21, d20 \n" - "vmov d22, d20 \n" - "subs %2, %2, #8 \n" - "vst4.8 {d20, d21, d22, d23}, [%1]! \n" - "bgt 1b \n" - : "+r"(src_y), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "d20", "d21", "d22", "d23"); -} - -void NV12ToARGBRow_NEON(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile(YUVTORGB_SETUP - "vmov.u8 d23, #255 \n" - "1: \n" READNV12 YUVTORGB - "subs %3, %3, #8 \n" - "vst4.8 {d20, d21, d22, d23}, [%2]! \n" - "bgt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_uv), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", - "q10", "q11", "q12", "q13", "q14", "q15"); -} - -void NV21ToARGBRow_NEON(const uint8_t* src_y, - const uint8_t* src_vu, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile(YUVTORGB_SETUP - "vmov.u8 d23, #255 \n" - "1: \n" READNV21 YUVTORGB - "subs %3, %3, #8 \n" - "vst4.8 {d20, d21, d22, d23}, [%2]! \n" - "bgt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_vu), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", - "q10", "q11", "q12", "q13", "q14", "q15"); -} - -void NV12ToRGB24Row_NEON(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile( - - YUVTORGB_SETUP - - "1: \n" - - READNV12 YUVTORGB - "subs %3, %3, #8 \n" - "vst3.8 {d20, d21, d22}, [%2]! \n" - "bgt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_uv), // %1 - "+r"(dst_rgb24), // %2 - "+r"(width) // %3 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", - "q12", "q13", "q14", "q15"); -} - -void NV21ToRGB24Row_NEON(const uint8_t* src_y, - const uint8_t* src_vu, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile( - - YUVTORGB_SETUP - - "1: \n" - - READNV21 YUVTORGB - "subs %3, %3, #8 \n" - "vst3.8 {d20, d21, d22}, [%2]! \n" - "bgt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_vu), // %1 - "+r"(dst_rgb24), // %2 - "+r"(width) // %3 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", - "q12", "q13", "q14", "q15"); -} - -void NV12ToRGB565Row_NEON(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile( - YUVTORGB_SETUP - "1: \n" READNV12 YUVTORGB - "subs %3, %3, #8 \n" ARGBTORGB565 - "vst1.8 {q0}, [%2]! \n" // store 8 pixels RGB565. - "bgt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_uv), // %1 - "+r"(dst_rgb565), // %2 - "+r"(width) // %3 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", - "q12", "q13", "q14", "q15"); -} - -void YUY2ToARGBRow_NEON(const uint8_t* src_yuy2, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile(YUVTORGB_SETUP - "vmov.u8 d23, #255 \n" - "1: \n" READYUY2 YUVTORGB - "subs %2, %2, #8 \n" - "vst4.8 {d20, d21, d22, d23}, [%1]! \n" - "bgt 1b \n" - : "+r"(src_yuy2), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", - "q10", "q11", "q12", "q13", "q14", "q15"); -} - -void UYVYToARGBRow_NEON(const uint8_t* src_uyvy, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile(YUVTORGB_SETUP - "vmov.u8 d23, #255 \n" - "1: \n" READUYVY YUVTORGB - "subs %2, %2, #8 \n" - "vst4.8 {d20, d21, d22, d23}, [%1]! \n" - "bgt 1b \n" - : "+r"(src_uyvy), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q8", "q9", - "q10", "q11", "q12", "q13", "q14", "q15"); -} - -// Reads 16 pairs of UV and write even values to dst_u and odd to dst_v. -void SplitUVRow_NEON(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "1: \n" - "vld2.8 {q0, q1}, [%0]! \n" // load 16 pairs of UV - "subs %3, %3, #16 \n" // 16 processed per loop - "vst1.8 {q0}, [%1]! \n" // store U - "vst1.8 {q1}, [%2]! \n" // store V - "bgt 1b \n" - : "+r"(src_uv), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 // Output registers - : // Input registers - : "cc", "memory", "q0", "q1" // Clobber List - ); -} - -// Reads 16 U's and V's and writes out 16 pairs of UV. -void MergeUVRow_NEON(const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uv, - int width) { - asm volatile( - "1: \n" - "vld1.8 {q0}, [%0]! \n" // load U - "vld1.8 {q1}, [%1]! \n" // load V - "subs %3, %3, #16 \n" // 16 processed per loop - "vst2.8 {q0, q1}, [%2]! \n" // store 16 pairs of UV - "bgt 1b \n" - : "+r"(src_u), // %0 - "+r"(src_v), // %1 - "+r"(dst_uv), // %2 - "+r"(width) // %3 // Output registers - : // Input registers - : "cc", "memory", "q0", "q1" // Clobber List - ); -} - -// Reads 16 packed RGB and write to planar dst_r, dst_g, dst_b. -void SplitRGBRow_NEON(const uint8_t* src_rgb, - uint8_t* dst_r, - uint8_t* dst_g, - uint8_t* dst_b, - int width) { - asm volatile( - "1: \n" - "vld3.8 {d0, d2, d4}, [%0]! \n" // load 8 RGB - "vld3.8 {d1, d3, d5}, [%0]! \n" // next 8 RGB - "subs %4, %4, #16 \n" // 16 processed per loop - "vst1.8 {q0}, [%1]! \n" // store R - "vst1.8 {q1}, [%2]! \n" // store G - "vst1.8 {q2}, [%3]! \n" // store B - "bgt 1b \n" - : "+r"(src_rgb), // %0 - "+r"(dst_r), // %1 - "+r"(dst_g), // %2 - "+r"(dst_b), // %3 - "+r"(width) // %4 - : // Input registers - : "cc", "memory", "d0", "d1", "d2" // Clobber List - ); -} - -// Reads 16 planar R's, G's and B's and writes out 16 packed RGB at a time -void MergeRGBRow_NEON(const uint8_t* src_r, - const uint8_t* src_g, - const uint8_t* src_b, - uint8_t* dst_rgb, - int width) { - asm volatile( - "1: \n" - "vld1.8 {q0}, [%0]! \n" // load R - "vld1.8 {q1}, [%1]! \n" // load G - "vld1.8 {q2}, [%2]! \n" // load B - "subs %4, %4, #16 \n" // 16 processed per loop - "vst3.8 {d0, d2, d4}, [%3]! \n" // store 8 RGB - "vst3.8 {d1, d3, d5}, [%3]! \n" // next 8 RGB - "bgt 1b \n" - : "+r"(src_r), // %0 - "+r"(src_g), // %1 - "+r"(src_b), // %2 - "+r"(dst_rgb), // %3 - "+r"(width) // %4 - : // Input registers - : "cc", "memory", "q0", "q1", "q2" // Clobber List - ); -} - -// Copy multiple of 32. vld4.8 allow unaligned and is fastest on a15. -void CopyRow_NEON(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "1: \n" - "vld1.8 {d0, d1, d2, d3}, [%0]! \n" // load 32 - "subs %2, %2, #32 \n" // 32 processed per loop - "vst1.8 {d0, d1, d2, d3}, [%1]! \n" // store 32 - "bgt 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 // Output registers - : // Input registers - : "cc", "memory", "q0", "q1" // Clobber List - ); -} - -// SetRow writes 'width' bytes using an 8 bit value repeated. -void SetRow_NEON(uint8_t* dst, uint8_t v8, int width) { - asm volatile( - "vdup.8 q0, %2 \n" // duplicate 16 bytes - "1: \n" - "subs %1, %1, #16 \n" // 16 bytes per loop - "vst1.8 {q0}, [%0]! \n" // store - "bgt 1b \n" - : "+r"(dst), // %0 - "+r"(width) // %1 - : "r"(v8) // %2 - : "cc", "memory", "q0"); -} - -// ARGBSetRow writes 'width' pixels using an 32 bit value repeated. -void ARGBSetRow_NEON(uint8_t* dst, uint32_t v32, int width) { - asm volatile( - "vdup.u32 q0, %2 \n" // duplicate 4 ints - "1: \n" - "subs %1, %1, #4 \n" // 4 pixels per loop - "vst1.8 {q0}, [%0]! \n" // store - "bgt 1b \n" - : "+r"(dst), // %0 - "+r"(width) // %1 - : "r"(v32) // %2 - : "cc", "memory", "q0"); -} - -void MirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - // Start at end of source row. - "mov r3, #-16 \n" - "add %0, %0, %2 \n" - "sub %0, #16 \n" - - "1: \n" - "vld1.8 {q0}, [%0], r3 \n" // src -= 16 - "subs %2, #16 \n" // 16 pixels per loop. - "vrev64.8 q0, q0 \n" - "vst1.8 {d1}, [%1]! \n" // dst += 16 - "vst1.8 {d0}, [%1]! \n" - "bgt 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "r3", "q0"); -} - -void MirrorUVRow_NEON(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - // Start at end of source row. - "mov r12, #-16 \n" - "add %0, %0, %3, lsl #1 \n" - "sub %0, #16 \n" - - "1: \n" - "vld2.8 {d0, d1}, [%0], r12 \n" // src -= 16 - "subs %3, #8 \n" // 8 pixels per loop. - "vrev64.8 q0, q0 \n" - "vst1.8 {d0}, [%1]! \n" // dst += 8 - "vst1.8 {d1}, [%2]! \n" - "bgt 1b \n" - : "+r"(src_uv), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "r12", "q0"); -} - -void ARGBMirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - // Start at end of source row. - "mov r3, #-16 \n" - "add %0, %0, %2, lsl #2 \n" - "sub %0, #16 \n" - - "1: \n" - "vld1.8 {q0}, [%0], r3 \n" // src -= 16 - "subs %2, #4 \n" // 4 pixels per loop. - "vrev64.32 q0, q0 \n" - "vst1.8 {d1}, [%1]! \n" // dst += 16 - "vst1.8 {d0}, [%1]! \n" - "bgt 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "r3", "q0"); -} - -void RGB24ToARGBRow_NEON(const uint8_t* src_rgb24, - uint8_t* dst_argb, - int width) { - asm volatile( - "vmov.u8 d4, #255 \n" // Alpha - "1: \n" - "vld3.8 {d1, d2, d3}, [%0]! \n" // load 8 pixels of RGB24. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vst4.8 {d1, d2, d3, d4}, [%1]! \n" // store 8 pixels of ARGB. - "bgt 1b \n" - : "+r"(src_rgb24), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "d1", "d2", "d3", "d4" // Clobber List - ); -} - -void RAWToARGBRow_NEON(const uint8_t* src_raw, uint8_t* dst_argb, int width) { - asm volatile( - "vmov.u8 d4, #255 \n" // Alpha - "1: \n" - "vld3.8 {d1, d2, d3}, [%0]! \n" // load 8 pixels of RAW. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vswp.u8 d1, d3 \n" // swap R, B - "vst4.8 {d1, d2, d3, d4}, [%1]! \n" // store 8 pixels of ARGB. - "bgt 1b \n" - : "+r"(src_raw), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "d1", "d2", "d3", "d4" // Clobber List - ); -} - -void RAWToRGB24Row_NEON(const uint8_t* src_raw, uint8_t* dst_rgb24, int width) { - asm volatile( - "1: \n" - "vld3.8 {d1, d2, d3}, [%0]! \n" // load 8 pixels of RAW. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vswp.u8 d1, d3 \n" // swap R, B - "vst3.8 {d1, d2, d3}, [%1]! \n" // store 8 pixels of - // RGB24. - "bgt 1b \n" - : "+r"(src_raw), // %0 - "+r"(dst_rgb24), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "d1", "d2", "d3" // Clobber List - ); -} - -#define RGB565TOARGB \ - "vshrn.u16 d6, q0, #5 \n" /* G xxGGGGGG */ \ - "vuzp.u8 d0, d1 \n" /* d0 xxxBBBBB RRRRRxxx */ \ - "vshl.u8 d6, d6, #2 \n" /* G GGGGGG00 upper 6 */ \ - "vshr.u8 d1, d1, #3 \n" /* R 000RRRRR lower 5 */ \ - "vshl.u8 q0, q0, #3 \n" /* B,R BBBBB000 upper 5 */ \ - "vshr.u8 q2, q0, #5 \n" /* B,R 00000BBB lower 3 */ \ - "vorr.u8 d0, d0, d4 \n" /* B */ \ - "vshr.u8 d4, d6, #6 \n" /* G 000000GG lower 2 */ \ - "vorr.u8 d2, d1, d5 \n" /* R */ \ - "vorr.u8 d1, d4, d6 \n" /* G */ - -void RGB565ToARGBRow_NEON(const uint8_t* src_rgb565, - uint8_t* dst_argb, - int width) { - asm volatile( - "vmov.u8 d3, #255 \n" // Alpha - "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 8 RGB565 pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. - RGB565TOARGB - "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 8 pixels of ARGB. - "bgt 1b \n" - : "+r"(src_rgb565), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "q0", "q1", "q2", "q3" // Clobber List - ); -} - -#define ARGB1555TOARGB \ - "vshrn.u16 d7, q0, #8 \n" /* A Arrrrrxx */ \ - "vshr.u8 d6, d7, #2 \n" /* R xxxRRRRR */ \ - "vshrn.u16 d5, q0, #5 \n" /* G xxxGGGGG */ \ - "vmovn.u16 d4, q0 \n" /* B xxxBBBBB */ \ - "vshr.u8 d7, d7, #7 \n" /* A 0000000A */ \ - "vneg.s8 d7, d7 \n" /* A AAAAAAAA upper 8 */ \ - "vshl.u8 d6, d6, #3 \n" /* R RRRRR000 upper 5 */ \ - "vshr.u8 q1, q3, #5 \n" /* R,A 00000RRR lower 3 */ \ - "vshl.u8 q0, q2, #3 \n" /* B,G BBBBB000 upper 5 */ \ - "vshr.u8 q2, q0, #5 \n" /* B,G 00000BBB lower 3 */ \ - "vorr.u8 q1, q1, q3 \n" /* R,A */ \ - "vorr.u8 q0, q0, q2 \n" /* B,G */ - -// RGB555TOARGB is same as ARGB1555TOARGB but ignores alpha. -#define RGB555TOARGB \ - "vshrn.u16 d6, q0, #5 \n" /* G xxxGGGGG */ \ - "vuzp.u8 d0, d1 \n" /* d0 xxxBBBBB xRRRRRxx */ \ - "vshl.u8 d6, d6, #3 \n" /* G GGGGG000 upper 5 */ \ - "vshr.u8 d1, d1, #2 \n" /* R 00xRRRRR lower 5 */ \ - "vshl.u8 q0, q0, #3 \n" /* B,R BBBBB000 upper 5 */ \ - "vshr.u8 q2, q0, #5 \n" /* B,R 00000BBB lower 3 */ \ - "vorr.u8 d0, d0, d4 \n" /* B */ \ - "vshr.u8 d4, d6, #5 \n" /* G 00000GGG lower 3 */ \ - "vorr.u8 d2, d1, d5 \n" /* R */ \ - "vorr.u8 d1, d4, d6 \n" /* G */ - -void ARGB1555ToARGBRow_NEON(const uint8_t* src_argb1555, - uint8_t* dst_argb, - int width) { - asm volatile( - "vmov.u8 d3, #255 \n" // Alpha - "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 8 ARGB1555 pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. - ARGB1555TOARGB - "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 8 pixels of ARGB. - "bgt 1b \n" - : "+r"(src_argb1555), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "q0", "q1", "q2", "q3" // Clobber List - ); -} - -#define ARGB4444TOARGB \ - "vuzp.u8 d0, d1 \n" /* d0 BG, d1 RA */ \ - "vshl.u8 q2, q0, #4 \n" /* B,R BBBB0000 */ \ - "vshr.u8 q1, q0, #4 \n" /* G,A 0000GGGG */ \ - "vshr.u8 q0, q2, #4 \n" /* B,R 0000BBBB */ \ - "vorr.u8 q0, q0, q2 \n" /* B,R BBBBBBBB */ \ - "vshl.u8 q2, q1, #4 \n" /* G,A GGGG0000 */ \ - "vorr.u8 q1, q1, q2 \n" /* G,A GGGGGGGG */ \ - "vswp.u8 d1, d2 \n" /* B,R,G,A -> B,G,R,A */ - -void ARGB4444ToARGBRow_NEON(const uint8_t* src_argb4444, - uint8_t* dst_argb, - int width) { - asm volatile( - "vmov.u8 d3, #255 \n" // Alpha - "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 8 ARGB4444 pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. - ARGB4444TOARGB - "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 8 pixels of ARGB. - "bgt 1b \n" - : "+r"(src_argb4444), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "q0", "q1", "q2" // Clobber List - ); -} - -void ARGBToRGB24Row_NEON(const uint8_t* src_argb, - uint8_t* dst_rgb24, - int width) { - asm volatile( - "1: \n" - "vld4.8 {d1, d2, d3, d4}, [%0]! \n" // load 8 pixels of ARGB. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vst3.8 {d1, d2, d3}, [%1]! \n" // store 8 pixels of - // RGB24. - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_rgb24), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "d1", "d2", "d3", "d4" // Clobber List - ); -} - -void ARGBToRAWRow_NEON(const uint8_t* src_argb, uint8_t* dst_raw, int width) { - asm volatile( - "1: \n" - "vld4.8 {d1, d2, d3, d4}, [%0]! \n" // load 8 pixels of ARGB. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vswp.u8 d1, d3 \n" // swap R, B - "vst3.8 {d1, d2, d3}, [%1]! \n" // store 8 pixels of RAW. - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_raw), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "d1", "d2", "d3", "d4" // Clobber List - ); -} - -void YUY2ToYRow_NEON(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { - asm volatile( - "1: \n" - "vld2.8 {q0, q1}, [%0]! \n" // load 16 pixels of YUY2. - "subs %2, %2, #16 \n" // 16 processed per loop. - "vst1.8 {q0}, [%1]! \n" // store 16 pixels of Y. - "bgt 1b \n" - : "+r"(src_yuy2), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "q0", "q1" // Clobber List - ); -} - -void UYVYToYRow_NEON(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { - asm volatile( - "1: \n" - "vld2.8 {q0, q1}, [%0]! \n" // load 16 pixels of UYVY. - "subs %2, %2, #16 \n" // 16 processed per loop. - "vst1.8 {q1}, [%1]! \n" // store 16 pixels of Y. - "bgt 1b \n" - : "+r"(src_uyvy), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "q0", "q1" // Clobber List - ); -} - -void YUY2ToUV422Row_NEON(const uint8_t* src_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 16 pixels of YUY2. - "subs %3, %3, #16 \n" // 16 pixels = 8 UVs. - "vst1.8 {d1}, [%1]! \n" // store 8 U. - "vst1.8 {d3}, [%2]! \n" // store 8 V. - "bgt 1b \n" - : "+r"(src_yuy2), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "d0", "d1", "d2", "d3" // Clobber List - ); -} - -void UYVYToUV422Row_NEON(const uint8_t* src_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 16 pixels of UYVY. - "subs %3, %3, #16 \n" // 16 pixels = 8 UVs. - "vst1.8 {d0}, [%1]! \n" // store 8 U. - "vst1.8 {d2}, [%2]! \n" // store 8 V. - "bgt 1b \n" - : "+r"(src_uyvy), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "d0", "d1", "d2", "d3" // Clobber List - ); -} - -void YUY2ToUVRow_NEON(const uint8_t* src_yuy2, - int stride_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "add %1, %0, %1 \n" // stride + src_yuy2 - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 16 pixels of YUY2. - "subs %4, %4, #16 \n" // 16 pixels = 8 UVs. - "vld4.8 {d4, d5, d6, d7}, [%1]! \n" // load next row YUY2. - "vrhadd.u8 d1, d1, d5 \n" // average rows of U - "vrhadd.u8 d3, d3, d7 \n" // average rows of V - "vst1.8 {d1}, [%2]! \n" // store 8 U. - "vst1.8 {d3}, [%3]! \n" // store 8 V. - "bgt 1b \n" - : "+r"(src_yuy2), // %0 - "+r"(stride_yuy2), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "d0", "d1", "d2", "d3", "d4", "d5", "d6", - "d7" // Clobber List - ); -} - -void UYVYToUVRow_NEON(const uint8_t* src_uyvy, - int stride_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "add %1, %0, %1 \n" // stride + src_uyvy - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 16 pixels of UYVY. - "subs %4, %4, #16 \n" // 16 pixels = 8 UVs. - "vld4.8 {d4, d5, d6, d7}, [%1]! \n" // load next row UYVY. - "vrhadd.u8 d0, d0, d4 \n" // average rows of U - "vrhadd.u8 d2, d2, d6 \n" // average rows of V - "vst1.8 {d0}, [%2]! \n" // store 8 U. - "vst1.8 {d2}, [%3]! \n" // store 8 V. - "bgt 1b \n" - : "+r"(src_uyvy), // %0 - "+r"(stride_uyvy), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "d0", "d1", "d2", "d3", "d4", "d5", "d6", - "d7" // Clobber List - ); -} - -// For BGRAToARGB, ABGRToARGB, RGBAToARGB, and ARGBToRGBA. -void ARGBShuffleRow_NEON(const uint8_t* src_argb, - uint8_t* dst_argb, - const uint8_t* shuffler, - int width) { - asm volatile( - "vld1.8 {q2}, [%3] \n" // shuffler - "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 4 pixels. - "subs %2, %2, #4 \n" // 4 processed per loop - "vtbl.8 d2, {d0, d1}, d4 \n" // look up 2 first pixels - "vtbl.8 d3, {d0, d1}, d5 \n" // look up 2 next pixels - "vst1.8 {q1}, [%1]! \n" // store 4. - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : "r"(shuffler) // %3 - : "cc", "memory", "q0", "q1", "q2" // Clobber List - ); -} - -void I422ToYUY2Row_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_yuy2, - int width) { - asm volatile( - "1: \n" - "vld2.8 {d0, d2}, [%0]! \n" // load 16 Ys - "vld1.8 {d1}, [%1]! \n" // load 8 Us - "vld1.8 {d3}, [%2]! \n" // load 8 Vs - "subs %4, %4, #16 \n" // 16 pixels - "vst4.8 {d0, d1, d2, d3}, [%3]! \n" // Store 8 YUY2/16 pixels. - "bgt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_yuy2), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "d0", "d1", "d2", "d3"); -} - -void I422ToUYVYRow_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uyvy, - int width) { - asm volatile( - "1: \n" - "vld2.8 {d1, d3}, [%0]! \n" // load 16 Ys - "vld1.8 {d0}, [%1]! \n" // load 8 Us - "vld1.8 {d2}, [%2]! \n" // load 8 Vs - "subs %4, %4, #16 \n" // 16 pixels - "vst4.8 {d0, d1, d2, d3}, [%3]! \n" // Store 8 UYVY/16 pixels. - "bgt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_uyvy), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "d0", "d1", "d2", "d3"); -} - -void ARGBToRGB565Row_NEON(const uint8_t* src_argb, - uint8_t* dst_rgb565, - int width) { - asm volatile( - "1: \n" - "vld4.8 {d20, d21, d22, d23}, [%0]! \n" // load 8 pixels of ARGB. - "subs %2, %2, #8 \n" // 8 processed per loop. - ARGBTORGB565 - "vst1.8 {q0}, [%1]! \n" // store 8 pixels RGB565. - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_rgb565), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "q0", "q8", "q9", "q10", "q11"); -} - -void ARGBToRGB565DitherRow_NEON(const uint8_t* src_argb, - uint8_t* dst_rgb, - const uint32_t dither4, - int width) { - asm volatile( - "vdup.32 d2, %2 \n" // dither4 - "1: \n" - "vld4.8 {d20, d21, d22, d23}, [%1]! \n" // load 8 pixels of ARGB. - "subs %3, %3, #8 \n" // 8 processed per loop. - "vqadd.u8 d20, d20, d2 \n" - "vqadd.u8 d21, d21, d2 \n" - "vqadd.u8 d22, d22, d2 \n" // add for dither - ARGBTORGB565 - "vst1.8 {q0}, [%0]! \n" // store 8 RGB565. - "bgt 1b \n" - : "+r"(dst_rgb) // %0 - : "r"(src_argb), // %1 - "r"(dither4), // %2 - "r"(width) // %3 - : "cc", "memory", "q0", "q1", "q8", "q9", "q10", "q11"); -} - -void ARGBToARGB1555Row_NEON(const uint8_t* src_argb, - uint8_t* dst_argb1555, - int width) { - asm volatile( - "1: \n" - "vld4.8 {d20, d21, d22, d23}, [%0]! \n" // load 8 pixels of ARGB. - "subs %2, %2, #8 \n" // 8 processed per loop. - ARGBTOARGB1555 - "vst1.8 {q0}, [%1]! \n" // store 8 ARGB1555. - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb1555), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "q0", "q8", "q9", "q10", "q11"); -} - -void ARGBToARGB4444Row_NEON(const uint8_t* src_argb, - uint8_t* dst_argb4444, - int width) { - asm volatile( - "vmov.u8 d4, #0x0f \n" // bits to clear with - // vbic. - "1: \n" - "vld4.8 {d20, d21, d22, d23}, [%0]! \n" // load 8 pixels of ARGB. - "subs %2, %2, #8 \n" // 8 processed per loop. - ARGBTOARGB4444 - "vst1.8 {q0}, [%1]! \n" // store 8 ARGB4444. - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb4444), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "q0", "q8", "q9", "q10", "q11"); -} - -void ARGBToYRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width) { - asm volatile( - "vmov.u8 d24, #13 \n" // B * 0.1016 coefficient - "vmov.u8 d25, #65 \n" // G * 0.5078 coefficient - "vmov.u8 d26, #33 \n" // R * 0.2578 coefficient - "vmov.u8 d27, #16 \n" // Add 16 constant - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q2, d0, d24 \n" // B - "vmlal.u8 q2, d1, d25 \n" // G - "vmlal.u8 q2, d2, d26 \n" // R - "vqrshrun.s16 d0, q2, #7 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d27 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "q0", "q1", "q2", "q12", "q13"); -} - -void ARGBExtractAlphaRow_NEON(const uint8_t* src_argb, - uint8_t* dst_a, - int width) { - asm volatile( - "1: \n" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels - "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB pixels - "subs %2, %2, #16 \n" // 16 processed per loop - "vst1.8 {q3}, [%1]! \n" // store 16 A's. - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_a), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "q0", "q1", "q2", "q3" // Clobber List - ); -} - -void ARGBToYJRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width) { - asm volatile( - "vmov.u8 d24, #15 \n" // B * 0.11400 coefficient - "vmov.u8 d25, #75 \n" // G * 0.58700 coefficient - "vmov.u8 d26, #38 \n" // R * 0.29900 coefficient - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q2, d0, d24 \n" // B - "vmlal.u8 q2, d1, d25 \n" // G - "vmlal.u8 q2, d2, d26 \n" // R - "vqrshrun.s16 d0, q2, #7 \n" // 15 bit to 8 bit Y - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "q0", "q1", "q2", "q12", "q13"); -} - -// 8x1 pixels. -void ARGBToUV444Row_NEON(const uint8_t* src_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "vmov.u8 d24, #112 \n" // UB / VR 0.875 - // coefficient - "vmov.u8 d25, #74 \n" // UG -0.5781 coefficient - "vmov.u8 d26, #38 \n" // UR -0.2969 coefficient - "vmov.u8 d27, #18 \n" // VB -0.1406 coefficient - "vmov.u8 d28, #94 \n" // VG -0.7344 coefficient - "vmov.u16 q15, #0x8080 \n" // 128.5 - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. - "subs %3, %3, #8 \n" // 8 processed per loop. - "vmull.u8 q2, d0, d24 \n" // B - "vmlsl.u8 q2, d1, d25 \n" // G - "vmlsl.u8 q2, d2, d26 \n" // R - "vadd.u16 q2, q2, q15 \n" // +128 -> unsigned - - "vmull.u8 q3, d2, d24 \n" // R - "vmlsl.u8 q3, d1, d28 \n" // G - "vmlsl.u8 q3, d0, d27 \n" // B - "vadd.u16 q3, q3, q15 \n" // +128 -> unsigned - - "vqshrn.u16 d0, q2, #8 \n" // 16 bit to 8 bit U - "vqshrn.u16 d1, q3, #8 \n" // 16 bit to 8 bit V - - "vst1.8 {d0}, [%1]! \n" // store 8 pixels U. - "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", "q4", "q12", "q13", "q14", - "q15"); -} - -// clang-format off -// 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. -#define RGBTOUV(QB, QG, QR) \ - "vmul.s16 q8, " #QB ", q10 \n" /* B */ \ - "vmls.s16 q8, " #QG ", q11 \n" /* G */ \ - "vmls.s16 q8, " #QR ", q12 \n" /* R */ \ - "vadd.u16 q8, q8, q15 \n" /* +128 -> unsigned */ \ - "vmul.s16 q9, " #QR ", q10 \n" /* R */ \ - "vmls.s16 q9, " #QG ", q14 \n" /* G */ \ - "vmls.s16 q9, " #QB ", 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 */ -// clang-format on - -// TODO(fbarchard): Consider vhadd vertical, then vpaddl horizontal, avoid shr. -void ARGBToUVRow_NEON(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile ( - "add %1, %0, %1 \n" // src_stride + src_argb - "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" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. - "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. - "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more ARGB pixels. - "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 ARGB pixels. - "vpadal.u8 q0, q4 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. - "vpadal.u8 q2, q6 \n" // R 16 bytes -> 8 shorts. - - "vrshr.u16 q0, q0, #1 \n" // 2x average - "vrshr.u16 q1, q1, #1 \n" - "vrshr.u16 q2, q2, #1 \n" - - "subs %4, %4, #16 \n" // 32 processed per loop. - RGBTOUV(q0, q1, q2) - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(src_stride_argb), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15" - ); -} - -// TODO(fbarchard): Subsample match C code. -void ARGBToUVJRow_NEON(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile ( - "add %1, %0, %1 \n" // src_stride + src_argb - "vmov.s16 q10, #127 / 2 \n" // UB / VR 0.500 coefficient - "vmov.s16 q11, #84 / 2 \n" // UG -0.33126 coefficient - "vmov.s16 q12, #43 / 2 \n" // UR -0.16874 coefficient - "vmov.s16 q13, #20 / 2 \n" // VB -0.08131 coefficient - "vmov.s16 q14, #107 / 2 \n" // VG -0.41869 coefficient - "vmov.u16 q15, #0x8080 \n" // 128.5 - "1: \n" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. - "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. - "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more ARGB pixels. - "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 ARGB pixels. - "vpadal.u8 q0, q4 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. - "vpadal.u8 q2, q6 \n" // R 16 bytes -> 8 shorts. - - "vrshr.u16 q0, q0, #1 \n" // 2x average - "vrshr.u16 q1, q1, #1 \n" - "vrshr.u16 q2, q2, #1 \n" - - "subs %4, %4, #16 \n" // 32 processed per loop. - RGBTOUV(q0, q1, q2) - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(src_stride_argb), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15" - ); -} - -void BGRAToUVRow_NEON(const uint8_t* src_bgra, - int src_stride_bgra, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile ( - "add %1, %0, %1 \n" // src_stride + src_bgra - "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" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 BGRA pixels. - "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 BGRA pixels. - "vpaddl.u8 q3, q3 \n" // B 16 bytes -> 8 shorts. - "vpaddl.u8 q2, q2 \n" // G 16 bytes -> 8 shorts. - "vpaddl.u8 q1, q1 \n" // R 16 bytes -> 8 shorts. - "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more BGRA pixels. - "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 BGRA pixels. - "vpadal.u8 q3, q7 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q2, q6 \n" // G 16 bytes -> 8 shorts. - "vpadal.u8 q1, q5 \n" // R 16 bytes -> 8 shorts. - - "vrshr.u16 q1, q1, #1 \n" // 2x average - "vrshr.u16 q2, q2, #1 \n" - "vrshr.u16 q3, q3, #1 \n" - - "subs %4, %4, #16 \n" // 32 processed per loop. - RGBTOUV(q3, q2, q1) - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" - : "+r"(src_bgra), // %0 - "+r"(src_stride_bgra), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15" - ); -} - -void ABGRToUVRow_NEON(const uint8_t* src_abgr, - int src_stride_abgr, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile ( - "add %1, %0, %1 \n" // src_stride + src_abgr - "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" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ABGR pixels. - "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ABGR pixels. - "vpaddl.u8 q2, q2 \n" // B 16 bytes -> 8 shorts. - "vpaddl.u8 q1, q1 \n" // G 16 bytes -> 8 shorts. - "vpaddl.u8 q0, q0 \n" // R 16 bytes -> 8 shorts. - "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more ABGR pixels. - "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 ABGR pixels. - "vpadal.u8 q2, q6 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. - "vpadal.u8 q0, q4 \n" // R 16 bytes -> 8 shorts. - - "vrshr.u16 q0, q0, #1 \n" // 2x average - "vrshr.u16 q1, q1, #1 \n" - "vrshr.u16 q2, q2, #1 \n" - - "subs %4, %4, #16 \n" // 32 processed per loop. - RGBTOUV(q2, q1, q0) - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" - : "+r"(src_abgr), // %0 - "+r"(src_stride_abgr), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15" - ); -} - -void RGBAToUVRow_NEON(const uint8_t* src_rgba, - int src_stride_rgba, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile ( - "add %1, %0, %1 \n" // src_stride + src_rgba - "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" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 RGBA pixels. - "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 RGBA pixels. - "vpaddl.u8 q0, q1 \n" // B 16 bytes -> 8 shorts. - "vpaddl.u8 q1, q2 \n" // G 16 bytes -> 8 shorts. - "vpaddl.u8 q2, q3 \n" // R 16 bytes -> 8 shorts. - "vld4.8 {d8, d10, d12, d14}, [%1]! \n" // load 8 more RGBA pixels. - "vld4.8 {d9, d11, d13, d15}, [%1]! \n" // load last 8 RGBA pixels. - "vpadal.u8 q0, q5 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q1, q6 \n" // G 16 bytes -> 8 shorts. - "vpadal.u8 q2, q7 \n" // R 16 bytes -> 8 shorts. - - "vrshr.u16 q0, q0, #1 \n" // 2x average - "vrshr.u16 q1, q1, #1 \n" - "vrshr.u16 q2, q2, #1 \n" - - "subs %4, %4, #16 \n" // 32 processed per loop. - RGBTOUV(q0, q1, q2) - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" - : "+r"(src_rgba), // %0 - "+r"(src_stride_rgba), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15" - ); -} - -void RGB24ToUVRow_NEON(const uint8_t* src_rgb24, - int src_stride_rgb24, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile ( - "add %1, %0, %1 \n" // src_stride + src_rgb24 - "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" - "vld3.8 {d0, d2, d4}, [%0]! \n" // load 8 RGB24 pixels. - "vld3.8 {d1, d3, d5}, [%0]! \n" // load next 8 RGB24 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. - "vld3.8 {d8, d10, d12}, [%1]! \n" // load 8 more RGB24 pixels. - "vld3.8 {d9, d11, d13}, [%1]! \n" // load last 8 RGB24 pixels. - "vpadal.u8 q0, q4 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. - "vpadal.u8 q2, q6 \n" // R 16 bytes -> 8 shorts. - - "vrshr.u16 q0, q0, #1 \n" // 2x average - "vrshr.u16 q1, q1, #1 \n" - "vrshr.u16 q2, q2, #1 \n" - - "subs %4, %4, #16 \n" // 32 processed per loop. - RGBTOUV(q0, q1, q2) - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" - : "+r"(src_rgb24), // %0 - "+r"(src_stride_rgb24), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15" - ); -} - -void RAWToUVRow_NEON(const uint8_t* src_raw, - int src_stride_raw, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile ( - "add %1, %0, %1 \n" // src_stride + src_raw - "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" - "vld3.8 {d0, d2, d4}, [%0]! \n" // load 8 RAW pixels. - "vld3.8 {d1, d3, d5}, [%0]! \n" // load next 8 RAW pixels. - "vpaddl.u8 q2, q2 \n" // B 16 bytes -> 8 shorts. - "vpaddl.u8 q1, q1 \n" // G 16 bytes -> 8 shorts. - "vpaddl.u8 q0, q0 \n" // R 16 bytes -> 8 shorts. - "vld3.8 {d8, d10, d12}, [%1]! \n" // load 8 more RAW pixels. - "vld3.8 {d9, d11, d13}, [%1]! \n" // load last 8 RAW pixels. - "vpadal.u8 q2, q6 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q1, q5 \n" // G 16 bytes -> 8 shorts. - "vpadal.u8 q0, q4 \n" // R 16 bytes -> 8 shorts. - - "vrshr.u16 q0, q0, #1 \n" // 2x average - "vrshr.u16 q1, q1, #1 \n" - "vrshr.u16 q2, q2, #1 \n" - - "subs %4, %4, #16 \n" // 32 processed per loop. - RGBTOUV(q2, q1, q0) - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" - : "+r"(src_raw), // %0 - "+r"(src_stride_raw), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", - "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15" - ); -} - -// 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. -void RGB565ToUVRow_NEON(const uint8_t* src_rgb565, - int src_stride_rgb565, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "add %1, %0, %1 \n" // src_stride + src_argb - "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" - "vld1.8 {q0}, [%0]! \n" // load 8 RGB565 pixels. - RGB565TOARGB - "vpaddl.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. - "vpaddl.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. - "vpaddl.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. - "vld1.8 {q0}, [%0]! \n" // next 8 RGB565 pixels. - RGB565TOARGB - "vpaddl.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. - "vpaddl.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. - "vpaddl.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. - - "vld1.8 {q0}, [%1]! \n" // load 8 RGB565 pixels. - RGB565TOARGB - "vpadal.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. - "vpadal.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. - "vpadal.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. - "vld1.8 {q0}, [%1]! \n" // next 8 RGB565 pixels. - RGB565TOARGB - "vpadal.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. - "vpadal.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. - "vpadal.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. - - "vrshr.u16 q4, q4, #1 \n" // 2x average - "vrshr.u16 q5, q5, #1 \n" - "vrshr.u16 q6, q6, #1 \n" - - "subs %4, %4, #16 \n" // 16 processed per loop. - "vmul.s16 q8, q4, q10 \n" // B - "vmls.s16 q8, q5, q11 \n" // G - "vmls.s16 q8, q6, q12 \n" // R - "vadd.u16 q8, q8, q15 \n" // +128 -> unsigned - "vmul.s16 q9, q6, q10 \n" // R - "vmls.s16 q9, q5, q14 \n" // G - "vmls.s16 q9, q4, 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 - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" - : "+r"(src_rgb565), // %0 - "+r"(src_stride_rgb565), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", - "q9", "q10", "q11", "q12", "q13", "q14", "q15"); -} - -// 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. -void ARGB1555ToUVRow_NEON(const uint8_t* src_argb1555, - int src_stride_argb1555, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "add %1, %0, %1 \n" // src_stride + src_argb - "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" - "vld1.8 {q0}, [%0]! \n" // load 8 ARGB1555 pixels. - RGB555TOARGB - "vpaddl.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. - "vpaddl.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. - "vpaddl.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. - "vld1.8 {q0}, [%0]! \n" // next 8 ARGB1555 pixels. - RGB555TOARGB - "vpaddl.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. - "vpaddl.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. - "vpaddl.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. - - "vld1.8 {q0}, [%1]! \n" // load 8 ARGB1555 pixels. - RGB555TOARGB - "vpadal.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. - "vpadal.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. - "vpadal.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. - "vld1.8 {q0}, [%1]! \n" // next 8 ARGB1555 pixels. - RGB555TOARGB - "vpadal.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. - "vpadal.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. - "vpadal.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. - - "vrshr.u16 q4, q4, #1 \n" // 2x average - "vrshr.u16 q5, q5, #1 \n" - "vrshr.u16 q6, q6, #1 \n" - - "subs %4, %4, #16 \n" // 16 processed per loop. - "vmul.s16 q8, q4, q10 \n" // B - "vmls.s16 q8, q5, q11 \n" // G - "vmls.s16 q8, q6, q12 \n" // R - "vadd.u16 q8, q8, q15 \n" // +128 -> unsigned - "vmul.s16 q9, q6, q10 \n" // R - "vmls.s16 q9, q5, q14 \n" // G - "vmls.s16 q9, q4, 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 - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" - : "+r"(src_argb1555), // %0 - "+r"(src_stride_argb1555), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", - "q9", "q10", "q11", "q12", "q13", "q14", "q15"); -} - -// 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. -void ARGB4444ToUVRow_NEON(const uint8_t* src_argb4444, - int src_stride_argb4444, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "add %1, %0, %1 \n" // src_stride + src_argb - "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" - "vld1.8 {q0}, [%0]! \n" // load 8 ARGB4444 pixels. - ARGB4444TOARGB - "vpaddl.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. - "vpaddl.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. - "vpaddl.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. - "vld1.8 {q0}, [%0]! \n" // next 8 ARGB4444 pixels. - ARGB4444TOARGB - "vpaddl.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. - "vpaddl.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. - "vpaddl.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. - - "vld1.8 {q0}, [%1]! \n" // load 8 ARGB4444 pixels. - ARGB4444TOARGB - "vpadal.u8 d8, d0 \n" // B 8 bytes -> 4 shorts. - "vpadal.u8 d10, d1 \n" // G 8 bytes -> 4 shorts. - "vpadal.u8 d12, d2 \n" // R 8 bytes -> 4 shorts. - "vld1.8 {q0}, [%1]! \n" // next 8 ARGB4444 pixels. - ARGB4444TOARGB - "vpadal.u8 d9, d0 \n" // B 8 bytes -> 4 shorts. - "vpadal.u8 d11, d1 \n" // G 8 bytes -> 4 shorts. - "vpadal.u8 d13, d2 \n" // R 8 bytes -> 4 shorts. - - "vrshr.u16 q4, q4, #1 \n" // 2x average - "vrshr.u16 q5, q5, #1 \n" - "vrshr.u16 q6, q6, #1 \n" - - "subs %4, %4, #16 \n" // 16 processed per loop. - "vmul.s16 q8, q4, q10 \n" // B - "vmls.s16 q8, q5, q11 \n" // G - "vmls.s16 q8, q6, q12 \n" // R - "vadd.u16 q8, q8, q15 \n" // +128 -> unsigned - "vmul.s16 q9, q6, q10 \n" // R - "vmls.s16 q9, q5, q14 \n" // G - "vmls.s16 q9, q4, 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 - "vst1.8 {d0}, [%2]! \n" // store 8 pixels U. - "vst1.8 {d1}, [%3]! \n" // store 8 pixels V. - "bgt 1b \n" - : "+r"(src_argb4444), // %0 - "+r"(src_stride_argb4444), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", - "q9", "q10", "q11", "q12", "q13", "q14", "q15"); -} - -void RGB565ToYRow_NEON(const uint8_t* src_rgb565, uint8_t* dst_y, int width) { - asm volatile( - "vmov.u8 d24, #13 \n" // B * 0.1016 coefficient - "vmov.u8 d25, #65 \n" // G * 0.5078 coefficient - "vmov.u8 d26, #33 \n" // R * 0.2578 coefficient - "vmov.u8 d27, #16 \n" // Add 16 constant - "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 8 RGB565 pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. - RGB565TOARGB - "vmull.u8 q2, d0, d24 \n" // B - "vmlal.u8 q2, d1, d25 \n" // G - "vmlal.u8 q2, d2, d26 \n" // R - "vqrshrun.s16 d0, q2, #7 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d27 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" - : "+r"(src_rgb565), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q12", "q13"); -} - -void ARGB1555ToYRow_NEON(const uint8_t* src_argb1555, - uint8_t* dst_y, - int width) { - asm volatile( - "vmov.u8 d24, #13 \n" // B * 0.1016 coefficient - "vmov.u8 d25, #65 \n" // G * 0.5078 coefficient - "vmov.u8 d26, #33 \n" // R * 0.2578 coefficient - "vmov.u8 d27, #16 \n" // Add 16 constant - "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 8 ARGB1555 pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. - ARGB1555TOARGB - "vmull.u8 q2, d0, d24 \n" // B - "vmlal.u8 q2, d1, d25 \n" // G - "vmlal.u8 q2, d2, d26 \n" // R - "vqrshrun.s16 d0, q2, #7 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d27 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" - : "+r"(src_argb1555), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q12", "q13"); -} - -void ARGB4444ToYRow_NEON(const uint8_t* src_argb4444, - uint8_t* dst_y, - int width) { - asm volatile( - "vmov.u8 d24, #13 \n" // B * 0.1016 coefficient - "vmov.u8 d25, #65 \n" // G * 0.5078 coefficient - "vmov.u8 d26, #33 \n" // R * 0.2578 coefficient - "vmov.u8 d27, #16 \n" // Add 16 constant - "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 8 ARGB4444 pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. - ARGB4444TOARGB - "vmull.u8 q2, d0, d24 \n" // B - "vmlal.u8 q2, d1, d25 \n" // G - "vmlal.u8 q2, d2, d26 \n" // R - "vqrshrun.s16 d0, q2, #7 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d27 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" - : "+r"(src_argb4444), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q12", "q13"); -} - -void BGRAToYRow_NEON(const uint8_t* src_bgra, uint8_t* dst_y, int width) { - asm volatile( - "vmov.u8 d4, #33 \n" // R * 0.2578 coefficient - "vmov.u8 d5, #65 \n" // G * 0.5078 coefficient - "vmov.u8 d6, #13 \n" // B * 0.1016 coefficient - "vmov.u8 d7, #16 \n" // Add 16 constant - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 pixels of BGRA. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q8, d1, d4 \n" // R - "vmlal.u8 q8, d2, d5 \n" // G - "vmlal.u8 q8, d3, d6 \n" // B - "vqrshrun.s16 d0, q8, #7 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d7 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" - : "+r"(src_bgra), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "q8"); -} - -void ABGRToYRow_NEON(const uint8_t* src_abgr, uint8_t* dst_y, int width) { - asm volatile( - "vmov.u8 d4, #33 \n" // R * 0.2578 coefficient - "vmov.u8 d5, #65 \n" // G * 0.5078 coefficient - "vmov.u8 d6, #13 \n" // B * 0.1016 coefficient - "vmov.u8 d7, #16 \n" // Add 16 constant - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 pixels of ABGR. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q8, d0, d4 \n" // R - "vmlal.u8 q8, d1, d5 \n" // G - "vmlal.u8 q8, d2, d6 \n" // B - "vqrshrun.s16 d0, q8, #7 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d7 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" - : "+r"(src_abgr), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "q8"); -} - -void RGBAToYRow_NEON(const uint8_t* src_rgba, uint8_t* dst_y, int width) { - asm volatile( - "vmov.u8 d4, #13 \n" // B * 0.1016 coefficient - "vmov.u8 d5, #65 \n" // G * 0.5078 coefficient - "vmov.u8 d6, #33 \n" // R * 0.2578 coefficient - "vmov.u8 d7, #16 \n" // Add 16 constant - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 pixels of RGBA. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q8, d1, d4 \n" // B - "vmlal.u8 q8, d2, d5 \n" // G - "vmlal.u8 q8, d3, d6 \n" // R - "vqrshrun.s16 d0, q8, #7 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d7 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" - : "+r"(src_rgba), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "q8"); -} - -void RGB24ToYRow_NEON(const uint8_t* src_rgb24, uint8_t* dst_y, int width) { - asm volatile( - "vmov.u8 d4, #13 \n" // B * 0.1016 coefficient - "vmov.u8 d5, #65 \n" // G * 0.5078 coefficient - "vmov.u8 d6, #33 \n" // R * 0.2578 coefficient - "vmov.u8 d7, #16 \n" // Add 16 constant - "1: \n" - "vld3.8 {d0, d1, d2}, [%0]! \n" // load 8 pixels of RGB24. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q8, d0, d4 \n" // B - "vmlal.u8 q8, d1, d5 \n" // G - "vmlal.u8 q8, d2, d6 \n" // R - "vqrshrun.s16 d0, q8, #7 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d7 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" - : "+r"(src_rgb24), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "q8"); -} - -void RAWToYRow_NEON(const uint8_t* src_raw, uint8_t* dst_y, int width) { - asm volatile( - "vmov.u8 d4, #33 \n" // R * 0.2578 coefficient - "vmov.u8 d5, #65 \n" // G * 0.5078 coefficient - "vmov.u8 d6, #13 \n" // B * 0.1016 coefficient - "vmov.u8 d7, #16 \n" // Add 16 constant - "1: \n" - "vld3.8 {d0, d1, d2}, [%0]! \n" // load 8 pixels of RAW. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q8, d0, d4 \n" // B - "vmlal.u8 q8, d1, d5 \n" // G - "vmlal.u8 q8, d2, d6 \n" // R - "vqrshrun.s16 d0, q8, #7 \n" // 16 bit to 8 bit Y - "vqadd.u8 d0, d7 \n" - "vst1.8 {d0}, [%1]! \n" // store 8 pixels Y. - "bgt 1b \n" - : "+r"(src_raw), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "q8"); -} - -// Bilinear filter 16x2 -> 16x1 -void InterpolateRow_NEON(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride, - int dst_width, - int source_y_fraction) { - int y1_fraction = source_y_fraction; - asm volatile( - "cmp %4, #0 \n" - "beq 100f \n" - "add %2, %1 \n" - "cmp %4, #128 \n" - "beq 50f \n" - - "vdup.8 d5, %4 \n" - "rsb %4, #256 \n" - "vdup.8 d4, %4 \n" - // General purpose row blend. - "1: \n" - "vld1.8 {q0}, [%1]! \n" - "vld1.8 {q1}, [%2]! \n" - "subs %3, %3, #16 \n" - "vmull.u8 q13, d0, d4 \n" - "vmull.u8 q14, d1, d4 \n" - "vmlal.u8 q13, d2, d5 \n" - "vmlal.u8 q14, d3, d5 \n" - "vrshrn.u16 d0, q13, #8 \n" - "vrshrn.u16 d1, q14, #8 \n" - "vst1.8 {q0}, [%0]! \n" - "bgt 1b \n" - "b 99f \n" - - // Blend 50 / 50. - "50: \n" - "vld1.8 {q0}, [%1]! \n" - "vld1.8 {q1}, [%2]! \n" - "subs %3, %3, #16 \n" - "vrhadd.u8 q0, q1 \n" - "vst1.8 {q0}, [%0]! \n" - "bgt 50b \n" - "b 99f \n" - - // Blend 100 / 0 - Copy row unchanged. - "100: \n" - "vld1.8 {q0}, [%1]! \n" - "subs %3, %3, #16 \n" - "vst1.8 {q0}, [%0]! \n" - "bgt 100b \n" - - "99: \n" - : "+r"(dst_ptr), // %0 - "+r"(src_ptr), // %1 - "+r"(src_stride), // %2 - "+r"(dst_width), // %3 - "+r"(y1_fraction) // %4 - : - : "cc", "memory", "q0", "q1", "d4", "d5", "q13", "q14"); -} - -// dr * (256 - sa) / 256 + sr = dr - dr * sa / 256 + sr -void ARGBBlendRow_NEON(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - asm volatile( - "subs %3, #8 \n" - "blt 89f \n" - // Blend 8 pixels. - "8: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 pixels of ARGB0. - "vld4.8 {d4, d5, d6, d7}, [%1]! \n" // load 8 pixels of ARGB1. - "subs %3, %3, #8 \n" // 8 processed per loop. - "vmull.u8 q10, d4, d3 \n" // db * a - "vmull.u8 q11, d5, d3 \n" // dg * a - "vmull.u8 q12, d6, d3 \n" // dr * a - "vqrshrn.u16 d20, q10, #8 \n" // db >>= 8 - "vqrshrn.u16 d21, q11, #8 \n" // dg >>= 8 - "vqrshrn.u16 d22, q12, #8 \n" // dr >>= 8 - "vqsub.u8 q2, q2, q10 \n" // dbg - dbg * a / 256 - "vqsub.u8 d6, d6, d22 \n" // dr - dr * a / 256 - "vqadd.u8 q0, q0, q2 \n" // + sbg - "vqadd.u8 d2, d2, d6 \n" // + sr - "vmov.u8 d3, #255 \n" // a = 255 - "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 pixels of ARGB. - "bge 8b \n" - - "89: \n" - "adds %3, #8-1 \n" - "blt 99f \n" - - // Blend 1 pixels. - "1: \n" - "vld4.8 {d0[0],d1[0],d2[0],d3[0]}, [%0]! \n" // load 1 pixel ARGB0. - "vld4.8 {d4[0],d5[0],d6[0],d7[0]}, [%1]! \n" // load 1 pixel ARGB1. - "subs %3, %3, #1 \n" // 1 processed per loop. - "vmull.u8 q10, d4, d3 \n" // db * a - "vmull.u8 q11, d5, d3 \n" // dg * a - "vmull.u8 q12, d6, d3 \n" // dr * a - "vqrshrn.u16 d20, q10, #8 \n" // db >>= 8 - "vqrshrn.u16 d21, q11, #8 \n" // dg >>= 8 - "vqrshrn.u16 d22, q12, #8 \n" // dr >>= 8 - "vqsub.u8 q2, q2, q10 \n" // dbg - dbg * a / 256 - "vqsub.u8 d6, d6, d22 \n" // dr - dr * a / 256 - "vqadd.u8 q0, q0, q2 \n" // + sbg - "vqadd.u8 d2, d2, d6 \n" // + sr - "vmov.u8 d3, #255 \n" // a = 255 - "vst4.8 {d0[0],d1[0],d2[0],d3[0]}, [%2]! \n" // store 1 pixel. - "bge 1b \n" - - "99: \n" - - : "+r"(src_argb0), // %0 - "+r"(src_argb1), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q10", "q11", "q12"); -} - -// Attenuate 8 pixels at a time. -void ARGBAttenuateRow_NEON(const uint8_t* src_argb, - uint8_t* dst_argb, - int width) { - asm volatile( - // Attenuate 8 pixels. - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 pixels of ARGB. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q10, d0, d3 \n" // b * a - "vmull.u8 q11, d1, d3 \n" // g * a - "vmull.u8 q12, d2, d3 \n" // r * a - "vqrshrn.u16 d0, q10, #8 \n" // b >>= 8 - "vqrshrn.u16 d1, q11, #8 \n" // g >>= 8 - "vqrshrn.u16 d2, q12, #8 \n" // r >>= 8 - "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 8 pixels of ARGB. - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "q0", "q1", "q10", "q11", "q12"); -} - -// Quantize 8 ARGB pixels (32 bytes). -// dst = (dst * scale >> 16) * interval_size + interval_offset; -void ARGBQuantizeRow_NEON(uint8_t* dst_argb, - int scale, - int interval_size, - int interval_offset, - int width) { - asm volatile( - "vdup.u16 q8, %2 \n" - "vshr.u16 q8, q8, #1 \n" // scale >>= 1 - "vdup.u16 q9, %3 \n" // interval multiply. - "vdup.u16 q10, %4 \n" // interval add - - // 8 pixel loop. - "1: \n" - "vld4.8 {d0, d2, d4, d6}, [%0] \n" // load 8 pixels of ARGB. - "subs %1, %1, #8 \n" // 8 processed per loop. - "vmovl.u8 q0, d0 \n" // b (0 .. 255) - "vmovl.u8 q1, d2 \n" - "vmovl.u8 q2, d4 \n" - "vqdmulh.s16 q0, q0, q8 \n" // b * scale - "vqdmulh.s16 q1, q1, q8 \n" // g - "vqdmulh.s16 q2, q2, q8 \n" // r - "vmul.u16 q0, q0, q9 \n" // b * interval_size - "vmul.u16 q1, q1, q9 \n" // g - "vmul.u16 q2, q2, q9 \n" // r - "vadd.u16 q0, q0, q10 \n" // b + interval_offset - "vadd.u16 q1, q1, q10 \n" // g - "vadd.u16 q2, q2, q10 \n" // r - "vqmovn.u16 d0, q0 \n" - "vqmovn.u16 d2, q1 \n" - "vqmovn.u16 d4, q2 \n" - "vst4.8 {d0, d2, d4, d6}, [%0]! \n" // store 8 pixels of ARGB. - "bgt 1b \n" - : "+r"(dst_argb), // %0 - "+r"(width) // %1 - : "r"(scale), // %2 - "r"(interval_size), // %3 - "r"(interval_offset) // %4 - : "cc", "memory", "q0", "q1", "q2", "q3", "q8", "q9", "q10"); -} - -// Shade 8 pixels at a time by specified value. -// NOTE vqrdmulh.s16 q10, q10, d0[0] must use a scaler register from 0 to 8. -// Rounding in vqrdmulh does +1 to high if high bit of low s16 is set. -void ARGBShadeRow_NEON(const uint8_t* src_argb, - uint8_t* dst_argb, - int width, - uint32_t value) { - asm volatile( - "vdup.u32 q0, %3 \n" // duplicate scale value. - "vzip.u8 d0, d1 \n" // d0 aarrggbb. - "vshr.u16 q0, q0, #1 \n" // scale / 2. - - // 8 pixel loop. - "1: \n" - "vld4.8 {d20, d22, d24, d26}, [%0]! \n" // load 8 pixels of ARGB. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmovl.u8 q10, d20 \n" // b (0 .. 255) - "vmovl.u8 q11, d22 \n" - "vmovl.u8 q12, d24 \n" - "vmovl.u8 q13, d26 \n" - "vqrdmulh.s16 q10, q10, d0[0] \n" // b * scale * 2 - "vqrdmulh.s16 q11, q11, d0[1] \n" // g - "vqrdmulh.s16 q12, q12, d0[2] \n" // r - "vqrdmulh.s16 q13, q13, d0[3] \n" // a - "vqmovn.u16 d20, q10 \n" - "vqmovn.u16 d22, q11 \n" - "vqmovn.u16 d24, q12 \n" - "vqmovn.u16 d26, q13 \n" - "vst4.8 {d20, d22, d24, d26}, [%1]! \n" // store 8 pixels of ARGB. - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : "r"(value) // %3 - : "cc", "memory", "q0", "q10", "q11", "q12", "q13"); -} - -// Convert 8 ARGB pixels (64 bytes) to 8 Gray ARGB pixels -// Similar to ARGBToYJ but stores ARGB. -// C code is (15 * b + 75 * g + 38 * r + 64) >> 7; -void ARGBGrayRow_NEON(const uint8_t* src_argb, uint8_t* dst_argb, int width) { - asm volatile( - "vmov.u8 d24, #15 \n" // B * 0.11400 coefficient - "vmov.u8 d25, #75 \n" // G * 0.58700 coefficient - "vmov.u8 d26, #38 \n" // R * 0.29900 coefficient - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmull.u8 q2, d0, d24 \n" // B - "vmlal.u8 q2, d1, d25 \n" // G - "vmlal.u8 q2, d2, d26 \n" // R - "vqrshrun.s16 d0, q2, #7 \n" // 15 bit to 8 bit B - "vmov d1, d0 \n" // G - "vmov d2, d0 \n" // R - "vst4.8 {d0, d1, d2, d3}, [%1]! \n" // store 8 ARGB pixels. - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "q0", "q1", "q2", "q12", "q13"); -} - -// Convert 8 ARGB pixels (32 bytes) to 8 Sepia ARGB pixels. -// b = (r * 35 + g * 68 + b * 17) >> 7 -// g = (r * 45 + g * 88 + b * 22) >> 7 -// r = (r * 50 + g * 98 + b * 24) >> 7 -void ARGBSepiaRow_NEON(uint8_t* dst_argb, int width) { - asm volatile( - "vmov.u8 d20, #17 \n" // BB coefficient - "vmov.u8 d21, #68 \n" // BG coefficient - "vmov.u8 d22, #35 \n" // BR coefficient - "vmov.u8 d24, #22 \n" // GB coefficient - "vmov.u8 d25, #88 \n" // GG coefficient - "vmov.u8 d26, #45 \n" // GR coefficient - "vmov.u8 d28, #24 \n" // BB coefficient - "vmov.u8 d29, #98 \n" // BG coefficient - "vmov.u8 d30, #50 \n" // BR coefficient - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0] \n" // load 8 ARGB pixels. - "subs %1, %1, #8 \n" // 8 processed per loop. - "vmull.u8 q2, d0, d20 \n" // B to Sepia B - "vmlal.u8 q2, d1, d21 \n" // G - "vmlal.u8 q2, d2, d22 \n" // R - "vmull.u8 q3, d0, d24 \n" // B to Sepia G - "vmlal.u8 q3, d1, d25 \n" // G - "vmlal.u8 q3, d2, d26 \n" // R - "vmull.u8 q8, d0, d28 \n" // B to Sepia R - "vmlal.u8 q8, d1, d29 \n" // G - "vmlal.u8 q8, d2, d30 \n" // R - "vqshrn.u16 d0, q2, #7 \n" // 16 bit to 8 bit B - "vqshrn.u16 d1, q3, #7 \n" // 16 bit to 8 bit G - "vqshrn.u16 d2, q8, #7 \n" // 16 bit to 8 bit R - "vst4.8 {d0, d1, d2, d3}, [%0]! \n" // store 8 ARGB pixels. - "bgt 1b \n" - : "+r"(dst_argb), // %0 - "+r"(width) // %1 - : - : "cc", "memory", "q0", "q1", "q2", "q3", "q10", "q11", "q12", "q13", - "q14", "q15"); -} - -// Tranform 8 ARGB pixels (32 bytes) with color matrix. -// TODO(fbarchard): Was same as Sepia except matrix is provided. This function -// needs to saturate. Consider doing a non-saturating version. -void ARGBColorMatrixRow_NEON(const uint8_t* src_argb, - uint8_t* dst_argb, - const int8_t* matrix_argb, - int width) { - asm volatile( - "vld1.8 {q2}, [%3] \n" // load 3 ARGB vectors. - "vmovl.s8 q0, d4 \n" // B,G coefficients s16. - "vmovl.s8 q1, d5 \n" // R,A coefficients s16. - - "1: \n" - "vld4.8 {d16, d18, d20, d22}, [%0]! \n" // load 8 ARGB pixels. - "subs %2, %2, #8 \n" // 8 processed per loop. - "vmovl.u8 q8, d16 \n" // b (0 .. 255) 16 bit - "vmovl.u8 q9, d18 \n" // g - "vmovl.u8 q10, d20 \n" // r - "vmovl.u8 q11, d22 \n" // a - "vmul.s16 q12, q8, d0[0] \n" // B = B * Matrix B - "vmul.s16 q13, q8, d1[0] \n" // G = B * Matrix G - "vmul.s16 q14, q8, d2[0] \n" // R = B * Matrix R - "vmul.s16 q15, q8, d3[0] \n" // A = B * Matrix A - "vmul.s16 q4, q9, d0[1] \n" // B += G * Matrix B - "vmul.s16 q5, q9, d1[1] \n" // G += G * Matrix G - "vmul.s16 q6, q9, d2[1] \n" // R += G * Matrix R - "vmul.s16 q7, q9, d3[1] \n" // A += G * Matrix A - "vqadd.s16 q12, q12, q4 \n" // Accumulate B - "vqadd.s16 q13, q13, q5 \n" // Accumulate G - "vqadd.s16 q14, q14, q6 \n" // Accumulate R - "vqadd.s16 q15, q15, q7 \n" // Accumulate A - "vmul.s16 q4, q10, d0[2] \n" // B += R * Matrix B - "vmul.s16 q5, q10, d1[2] \n" // G += R * Matrix G - "vmul.s16 q6, q10, d2[2] \n" // R += R * Matrix R - "vmul.s16 q7, q10, d3[2] \n" // A += R * Matrix A - "vqadd.s16 q12, q12, q4 \n" // Accumulate B - "vqadd.s16 q13, q13, q5 \n" // Accumulate G - "vqadd.s16 q14, q14, q6 \n" // Accumulate R - "vqadd.s16 q15, q15, q7 \n" // Accumulate A - "vmul.s16 q4, q11, d0[3] \n" // B += A * Matrix B - "vmul.s16 q5, q11, d1[3] \n" // G += A * Matrix G - "vmul.s16 q6, q11, d2[3] \n" // R += A * Matrix R - "vmul.s16 q7, q11, d3[3] \n" // A += A * Matrix A - "vqadd.s16 q12, q12, q4 \n" // Accumulate B - "vqadd.s16 q13, q13, q5 \n" // Accumulate G - "vqadd.s16 q14, q14, q6 \n" // Accumulate R - "vqadd.s16 q15, q15, q7 \n" // Accumulate A - "vqshrun.s16 d16, q12, #6 \n" // 16 bit to 8 bit B - "vqshrun.s16 d18, q13, #6 \n" // 16 bit to 8 bit G - "vqshrun.s16 d20, q14, #6 \n" // 16 bit to 8 bit R - "vqshrun.s16 d22, q15, #6 \n" // 16 bit to 8 bit A - "vst4.8 {d16, d18, d20, d22}, [%1]! \n" // store 8 ARGB pixels. - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : "r"(matrix_argb) // %3 - : "cc", "memory", "q0", "q1", "q2", "q4", "q5", "q6", "q7", "q8", "q9", - "q10", "q11", "q12", "q13", "q14", "q15"); -} - -// Multiply 2 rows of ARGB pixels together, 8 pixels at a time. -void ARGBMultiplyRow_NEON(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - asm volatile( - // 8 pixel loop. - "1: \n" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. - "vld4.8 {d1, d3, d5, d7}, [%1]! \n" // load 8 more ARGB - "subs %3, %3, #8 \n" // 8 processed per loop. - "vmull.u8 q0, d0, d1 \n" // multiply B - "vmull.u8 q1, d2, d3 \n" // multiply G - "vmull.u8 q2, d4, d5 \n" // multiply R - "vmull.u8 q3, d6, d7 \n" // multiply A - "vrshrn.u16 d0, q0, #8 \n" // 16 bit to 8 bit B - "vrshrn.u16 d1, q1, #8 \n" // 16 bit to 8 bit G - "vrshrn.u16 d2, q2, #8 \n" // 16 bit to 8 bit R - "vrshrn.u16 d3, q3, #8 \n" // 16 bit to 8 bit A - "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 ARGB pixels. - "bgt 1b \n" - : "+r"(src_argb0), // %0 - "+r"(src_argb1), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "q0", "q1", "q2", "q3"); -} - -// Add 2 rows of ARGB pixels together, 8 pixels at a time. -void ARGBAddRow_NEON(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - asm volatile( - // 8 pixel loop. - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. - "vld4.8 {d4, d5, d6, d7}, [%1]! \n" // load 8 more ARGB - "subs %3, %3, #8 \n" // 8 processed per loop. - "vqadd.u8 q0, q0, q2 \n" // add B, G - "vqadd.u8 q1, q1, q3 \n" // add R, A - "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 ARGB pixels. - "bgt 1b \n" - : "+r"(src_argb0), // %0 - "+r"(src_argb1), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "q0", "q1", "q2", "q3"); -} - -// Subtract 2 rows of ARGB pixels, 8 pixels at a time. -void ARGBSubtractRow_NEON(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - asm volatile( - // 8 pixel loop. - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // load 8 ARGB pixels. - "vld4.8 {d4, d5, d6, d7}, [%1]! \n" // load 8 more ARGB - "subs %3, %3, #8 \n" // 8 processed per loop. - "vqsub.u8 q0, q0, q2 \n" // subtract B, G - "vqsub.u8 q1, q1, q3 \n" // subtract R, A - "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 ARGB pixels. - "bgt 1b \n" - : "+r"(src_argb0), // %0 - "+r"(src_argb1), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "q0", "q1", "q2", "q3"); -} - -// Adds Sobel X and Sobel Y and stores Sobel into ARGB. -// A = 255 -// R = Sobel -// G = Sobel -// B = Sobel -void SobelRow_NEON(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width) { - asm volatile( - "vmov.u8 d3, #255 \n" // alpha - // 8 pixel loop. - "1: \n" - "vld1.8 {d0}, [%0]! \n" // load 8 sobelx. - "vld1.8 {d1}, [%1]! \n" // load 8 sobely. - "subs %3, %3, #8 \n" // 8 processed per loop. - "vqadd.u8 d0, d0, d1 \n" // add - "vmov.u8 d1, d0 \n" - "vmov.u8 d2, d0 \n" - "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 ARGB pixels. - "bgt 1b \n" - : "+r"(src_sobelx), // %0 - "+r"(src_sobely), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "q0", "q1"); -} - -// Adds Sobel X and Sobel Y and stores Sobel into plane. -void SobelToPlaneRow_NEON(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_y, - int width) { - asm volatile( - // 16 pixel loop. - "1: \n" - "vld1.8 {q0}, [%0]! \n" // load 16 sobelx. - "vld1.8 {q1}, [%1]! \n" // load 16 sobely. - "subs %3, %3, #16 \n" // 16 processed per loop. - "vqadd.u8 q0, q0, q1 \n" // add - "vst1.8 {q0}, [%2]! \n" // store 16 pixels. - "bgt 1b \n" - : "+r"(src_sobelx), // %0 - "+r"(src_sobely), // %1 - "+r"(dst_y), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "q0", "q1"); -} - -// Mixes Sobel X, Sobel Y and Sobel into ARGB. -// A = 255 -// R = Sobel X -// G = Sobel -// B = Sobel Y -void SobelXYRow_NEON(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width) { - asm volatile( - "vmov.u8 d3, #255 \n" // alpha - // 8 pixel loop. - "1: \n" - "vld1.8 {d2}, [%0]! \n" // load 8 sobelx. - "vld1.8 {d0}, [%1]! \n" // load 8 sobely. - "subs %3, %3, #8 \n" // 8 processed per loop. - "vqadd.u8 d1, d0, d2 \n" // add - "vst4.8 {d0, d1, d2, d3}, [%2]! \n" // store 8 ARGB pixels. - "bgt 1b \n" - : "+r"(src_sobelx), // %0 - "+r"(src_sobely), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "q0", "q1"); -} - -// SobelX as a matrix is -// -1 0 1 -// -2 0 2 -// -1 0 1 -void SobelXRow_NEON(const uint8_t* src_y0, - const uint8_t* src_y1, - const uint8_t* src_y2, - uint8_t* dst_sobelx, - int width) { - asm volatile( - "1: \n" - "vld1.8 {d0}, [%0],%5 \n" // top - "vld1.8 {d1}, [%0],%6 \n" - "vsubl.u8 q0, d0, d1 \n" - "vld1.8 {d2}, [%1],%5 \n" // center * 2 - "vld1.8 {d3}, [%1],%6 \n" - "vsubl.u8 q1, d2, d3 \n" - "vadd.s16 q0, q0, q1 \n" - "vadd.s16 q0, q0, q1 \n" - "vld1.8 {d2}, [%2],%5 \n" // bottom - "vld1.8 {d3}, [%2],%6 \n" - "subs %4, %4, #8 \n" // 8 pixels - "vsubl.u8 q1, d2, d3 \n" - "vadd.s16 q0, q0, q1 \n" - "vabs.s16 q0, q0 \n" - "vqmovn.u16 d0, q0 \n" - "vst1.8 {d0}, [%3]! \n" // store 8 sobelx - "bgt 1b \n" - : "+r"(src_y0), // %0 - "+r"(src_y1), // %1 - "+r"(src_y2), // %2 - "+r"(dst_sobelx), // %3 - "+r"(width) // %4 - : "r"(2), // %5 - "r"(6) // %6 - : "cc", "memory", "q0", "q1" // Clobber List - ); -} - -// SobelY as a matrix is -// -1 -2 -1 -// 0 0 0 -// 1 2 1 -void SobelYRow_NEON(const uint8_t* src_y0, - const uint8_t* src_y1, - uint8_t* dst_sobely, - int width) { - asm volatile( - "1: \n" - "vld1.8 {d0}, [%0],%4 \n" // left - "vld1.8 {d1}, [%1],%4 \n" - "vsubl.u8 q0, d0, d1 \n" - "vld1.8 {d2}, [%0],%4 \n" // center * 2 - "vld1.8 {d3}, [%1],%4 \n" - "vsubl.u8 q1, d2, d3 \n" - "vadd.s16 q0, q0, q1 \n" - "vadd.s16 q0, q0, q1 \n" - "vld1.8 {d2}, [%0],%5 \n" // right - "vld1.8 {d3}, [%1],%5 \n" - "subs %3, %3, #8 \n" // 8 pixels - "vsubl.u8 q1, d2, d3 \n" - "vadd.s16 q0, q0, q1 \n" - "vabs.s16 q0, q0 \n" - "vqmovn.u16 d0, q0 \n" - "vst1.8 {d0}, [%2]! \n" // store 8 sobely - "bgt 1b \n" - : "+r"(src_y0), // %0 - "+r"(src_y1), // %1 - "+r"(dst_sobely), // %2 - "+r"(width) // %3 - : "r"(1), // %4 - "r"(6) // %5 - : "cc", "memory", "q0", "q1" // Clobber List - ); -} - -// %y passes a float as a scalar vector for vector * scalar multiply. -// the regoster must be d0 to d15 and indexed with [0] or [1] to access -// the float in the first or second float of the d-reg - -void HalfFloat1Row_NEON(const uint16_t* src, - uint16_t* dst, - float /*unused*/, - int width) { - asm volatile( - - "1: \n" - "vld1.8 {q1}, [%0]! \n" // load 8 shorts - "subs %2, %2, #8 \n" // 8 pixels per loop - "vmovl.u16 q2, d2 \n" // 8 int's - "vmovl.u16 q3, d3 \n" - "vcvt.f32.u32 q2, q2 \n" // 8 floats - "vcvt.f32.u32 q3, q3 \n" - "vmul.f32 q2, q2, %y3 \n" // adjust exponent - "vmul.f32 q3, q3, %y3 \n" - "vqshrn.u32 d2, q2, #13 \n" // isolate halffloat - "vqshrn.u32 d3, q3, #13 \n" - "vst1.8 {q1}, [%1]! \n" - "bgt 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "w"(1.9259299444e-34f) // %3 - : "cc", "memory", "q1", "q2", "q3"); -} - -void HalfFloatRow_NEON(const uint16_t* src, - uint16_t* dst, - float scale, - int width) { - asm volatile( - - "1: \n" - "vld1.8 {q1}, [%0]! \n" // load 8 shorts - "subs %2, %2, #8 \n" // 8 pixels per loop - "vmovl.u16 q2, d2 \n" // 8 int's - "vmovl.u16 q3, d3 \n" - "vcvt.f32.u32 q2, q2 \n" // 8 floats - "vcvt.f32.u32 q3, q3 \n" - "vmul.f32 q2, q2, %y3 \n" // adjust exponent - "vmul.f32 q3, q3, %y3 \n" - "vqshrn.u32 d2, q2, #13 \n" // isolate halffloat - "vqshrn.u32 d3, q3, #13 \n" - "vst1.8 {q1}, [%1]! \n" - "bgt 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "w"(scale * 1.9259299444e-34f) // %3 - : "cc", "memory", "q1", "q2", "q3"); -} - -void ByteToFloatRow_NEON(const uint8_t* src, - float* dst, - float scale, - int width) { - asm volatile( - - "1: \n" - "vld1.8 {d2}, [%0]! \n" // load 8 bytes - "subs %2, %2, #8 \n" // 8 pixels per loop - "vmovl.u8 q1, d2 \n" // 8 shorts - "vmovl.u16 q2, d2 \n" // 8 ints - "vmovl.u16 q3, d3 \n" - "vcvt.f32.u32 q2, q2 \n" // 8 floats - "vcvt.f32.u32 q3, q3 \n" - "vmul.f32 q2, q2, %y3 \n" // scale - "vmul.f32 q3, q3, %y3 \n" - "vst1.8 {q2, q3}, [%1]! \n" // store 8 floats - "bgt 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "w"(scale) // %3 - : "cc", "memory", "q1", "q2", "q3"); -} - -#endif // !defined(LIBYUV_DISABLE_NEON) && defined(__ARM_NEON__).. - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_neon64.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_neon64.cc deleted file mode 100644 index 24b4520b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_neon64.cc +++ /dev/null @@ -1,2884 +0,0 @@ -/* - * Copyright 2014 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// This module is for GCC Neon armv8 64 bit. -#if !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) - -// Read 8 Y, 4 U and 4 V from 422 -#define READYUV422 \ - "ld1 {v0.8b}, [%0], #8 \n" \ - "ld1 {v1.s}[0], [%1], #4 \n" \ - "ld1 {v1.s}[1], [%2], #4 \n" - -// Read 8 Y, 8 U and 8 V from 444 -#define READYUV444 \ - "ld1 {v0.8b}, [%0], #8 \n" \ - "ld1 {v1.d}[0], [%1], #8 \n" \ - "ld1 {v1.d}[1], [%2], #8 \n" \ - "uaddlp v1.8h, v1.16b \n" \ - "rshrn v1.8b, v1.8h, #1 \n" - -// Read 8 Y, and set 4 U and 4 V to 128 -#define READYUV400 \ - "ld1 {v0.8b}, [%0], #8 \n" \ - "movi v1.8b , #128 \n" - -// Read 8 Y and 4 UV from NV12 -#define READNV12 \ - "ld1 {v0.8b}, [%0], #8 \n" \ - "ld1 {v2.8b}, [%1], #8 \n" \ - "uzp1 v1.8b, v2.8b, v2.8b \n" \ - "uzp2 v3.8b, v2.8b, v2.8b \n" \ - "ins v1.s[1], v3.s[0] \n" - -// Read 8 Y and 4 VU from NV21 -#define READNV21 \ - "ld1 {v0.8b}, [%0], #8 \n" \ - "ld1 {v2.8b}, [%1], #8 \n" \ - "uzp1 v3.8b, v2.8b, v2.8b \n" \ - "uzp2 v1.8b, v2.8b, v2.8b \n" \ - "ins v1.s[1], v3.s[0] \n" - -// Read 8 YUY2 -#define READYUY2 \ - "ld2 {v0.8b, v1.8b}, [%0], #16 \n" \ - "uzp2 v3.8b, v1.8b, v1.8b \n" \ - "uzp1 v1.8b, v1.8b, v1.8b \n" \ - "ins v1.s[1], v3.s[0] \n" - -// Read 8 UYVY -#define READUYVY \ - "ld2 {v2.8b, v3.8b}, [%0], #16 \n" \ - "orr v0.8b, v3.8b, v3.8b \n" \ - "uzp1 v1.8b, v2.8b, v2.8b \n" \ - "uzp2 v3.8b, v2.8b, v2.8b \n" \ - "ins v1.s[1], v3.s[0] \n" - -#define YUVTORGB_SETUP \ - "ld1r {v24.8h}, [%[kUVBiasBGR]], #2 \n" \ - "ld1r {v25.8h}, [%[kUVBiasBGR]], #2 \n" \ - "ld1r {v26.8h}, [%[kUVBiasBGR]] \n" \ - "ld1r {v31.4s}, [%[kYToRgb]] \n" \ - "ld2 {v27.8h, v28.8h}, [%[kUVToRB]] \n" \ - "ld2 {v29.8h, v30.8h}, [%[kUVToG]] \n" - -#define YUVTORGB(vR, vG, vB) \ - "uxtl v0.8h, v0.8b \n" /* Extract Y */ \ - "shll v2.8h, v1.8b, #8 \n" /* Replicate UV */ \ - "ushll2 v3.4s, v0.8h, #0 \n" /* Y */ \ - "ushll v0.4s, v0.4h, #0 \n" \ - "mul v3.4s, v3.4s, v31.4s \n" \ - "mul v0.4s, v0.4s, v31.4s \n" \ - "sqshrun v0.4h, v0.4s, #16 \n" \ - "sqshrun2 v0.8h, v3.4s, #16 \n" /* Y */ \ - "uaddw v1.8h, v2.8h, v1.8b \n" /* Replicate UV */ \ - "mov v2.d[0], v1.d[1] \n" /* Extract V */ \ - "uxtl v2.8h, v2.8b \n" \ - "uxtl v1.8h, v1.8b \n" /* Extract U */ \ - "mul v3.8h, v1.8h, v27.8h \n" \ - "mul v5.8h, v1.8h, v29.8h \n" \ - "mul v6.8h, v2.8h, v30.8h \n" \ - "mul v7.8h, v2.8h, v28.8h \n" \ - "sqadd v6.8h, v6.8h, v5.8h \n" \ - "sqadd " #vB \ - ".8h, v24.8h, v0.8h \n" /* B */ \ - "sqadd " #vG \ - ".8h, v25.8h, v0.8h \n" /* G */ \ - "sqadd " #vR \ - ".8h, v26.8h, v0.8h \n" /* R */ \ - "sqadd " #vB ".8h, " #vB \ - ".8h, v3.8h \n" /* B */ \ - "sqsub " #vG ".8h, " #vG \ - ".8h, v6.8h \n" /* G */ \ - "sqadd " #vR ".8h, " #vR \ - ".8h, v7.8h \n" /* R */ \ - "sqshrun " #vB ".8b, " #vB \ - ".8h, #6 \n" /* B */ \ - "sqshrun " #vG ".8b, " #vG \ - ".8h, #6 \n" /* G */ \ - "sqshrun " #vR ".8b, " #vR ".8h, #6 \n" /* R */ - -void I444ToARGBRow_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP - "movi v23.8b, #255 \n" /* A */ - "1: \n" - READYUV444 - YUVTORGB(v22, v21, v20) - "subs %w4, %w4, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%3], #32 \n" - "b.gt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_argb), // %3 - "+r"(width) // %4 - : [kUVToRB]"r"(&yuvconstants->kUVToRB), - [kUVToG]"r"(&yuvconstants->kUVToG), - [kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR), - [kYToRgb]"r"(&yuvconstants->kYToRgb) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", - "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" - ); -} - -void I422ToARGBRow_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP - "movi v23.8b, #255 \n" /* A */ - "1: \n" - READYUV422 - YUVTORGB(v22, v21, v20) - "subs %w4, %w4, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%3], #32 \n" - "b.gt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_argb), // %3 - "+r"(width) // %4 - : [kUVToRB]"r"(&yuvconstants->kUVToRB), - [kUVToG]"r"(&yuvconstants->kUVToG), - [kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR), - [kYToRgb]"r"(&yuvconstants->kYToRgb) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", - "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" - ); -} - -void I422AlphaToARGBRow_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - const uint8_t* src_a, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP - "1: \n" - READYUV422 - YUVTORGB(v22, v21, v20) - "ld1 {v23.8b}, [%3], #8 \n" - "subs %w5, %w5, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%4], #32 \n" - "b.gt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(src_a), // %3 - "+r"(dst_argb), // %4 - "+r"(width) // %5 - : [kUVToRB]"r"(&yuvconstants->kUVToRB), - [kUVToG]"r"(&yuvconstants->kUVToG), - [kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR), - [kYToRgb]"r"(&yuvconstants->kYToRgb) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", - "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" - ); -} - -void I422ToRGBARow_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgba, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP - "movi v20.8b, #255 \n" /* A */ - "1: \n" - READYUV422 - YUVTORGB(v23, v22, v21) - "subs %w4, %w4, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%3], #32 \n" - "b.gt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_rgba), // %3 - "+r"(width) // %4 - : [kUVToRB]"r"(&yuvconstants->kUVToRB), - [kUVToG]"r"(&yuvconstants->kUVToG), - [kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR), - [kYToRgb]"r"(&yuvconstants->kYToRgb) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", - "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" - ); -} - -void I422ToRGB24Row_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP - "1: \n" - READYUV422 - YUVTORGB(v22, v21, v20) - "subs %w4, %w4, #8 \n" - "st3 {v20.8b,v21.8b,v22.8b}, [%3], #24 \n" - "b.gt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_rgb24), // %3 - "+r"(width) // %4 - : [kUVToRB]"r"(&yuvconstants->kUVToRB), - [kUVToG]"r"(&yuvconstants->kUVToG), - [kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR), - [kYToRgb]"r"(&yuvconstants->kYToRgb) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", - "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" - ); -} - -#define ARGBTORGB565 \ - "shll v0.8h, v22.8b, #8 \n" /* R */ \ - "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 */ - -void I422ToRGB565Row_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile( - YUVTORGB_SETUP - "1: \n" READYUV422 YUVTORGB( - v22, v21, - v20) "subs %w4, %w4, #8 \n" ARGBTORGB565 - "st1 {v0.8h}, [%3], #16 \n" // store 8 pixels - // RGB565. - "b.gt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_rgb565), // %3 - "+r"(width) // %4 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", - "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"); -} - -#define ARGBTOARGB1555 \ - "shll v0.8h, v23.8b, #8 \n" /* A */ \ - "shll v22.8h, v22.8b, #8 \n" /* R */ \ - "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 */ - -void I422ToARGB1555Row_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb1555, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile( - YUVTORGB_SETUP - "movi v23.8b, #255 \n" - "1: \n" READYUV422 YUVTORGB( - v22, v21, - v20) "subs %w4, %w4, #8 \n" ARGBTOARGB1555 - "st1 {v0.8h}, [%3], #16 \n" // store 8 pixels - // RGB565. - "b.gt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_argb1555), // %3 - "+r"(width) // %4 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", - "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"); -} - -#define ARGBTOARGB4444 \ - /* Input v20.8b<=B, v21.8b<=G, v22.8b<=R, v23.8b<=A, v4.8b<=0x0f */ \ - "ushr v20.8b, v20.8b, #4 \n" /* B */ \ - "bic v21.8b, v21.8b, v4.8b \n" /* G */ \ - "ushr v22.8b, v22.8b, #4 \n" /* R */ \ - "bic v23.8b, v23.8b, v4.8b \n" /* A */ \ - "orr v0.8b, v20.8b, v21.8b \n" /* BG */ \ - "orr v1.8b, v22.8b, v23.8b \n" /* RA */ \ - "zip1 v0.16b, v0.16b, v1.16b \n" /* BGRA */ - -void I422ToARGB4444Row_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb4444, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP - "movi v4.16b, #0x0f \n" // bits to clear with vbic. - "1: \n" - READYUV422 - YUVTORGB(v22, v21, v20) - "subs %w4, %w4, #8 \n" - "movi v23.8b, #255 \n" - ARGBTOARGB4444 - "st1 {v0.8h}, [%3], #16 \n" // store 8 pixels ARGB4444. - "b.gt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_argb4444), // %3 - "+r"(width) // %4 - : [kUVToRB]"r"(&yuvconstants->kUVToRB), - [kUVToG]"r"(&yuvconstants->kUVToG), - [kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR), - [kYToRgb]"r"(&yuvconstants->kYToRgb) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", - "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" - ); -} - -void I400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width) { - asm volatile ( - YUVTORGB_SETUP - "movi v23.8b, #255 \n" - "1: \n" - READYUV400 - YUVTORGB(v22, v21, v20) - "subs %w2, %w2, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%1], #32 \n" - "b.gt 1b \n" - : "+r"(src_y), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : [kUVToRB]"r"(&kYuvI601Constants.kUVToRB), - [kUVToG]"r"(&kYuvI601Constants.kUVToG), - [kUVBiasBGR]"r"(&kYuvI601Constants.kUVBiasBGR), - [kYToRgb]"r"(&kYuvI601Constants.kYToRgb) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", - "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" - ); -} - -void J400ToARGBRow_NEON(const uint8_t* src_y, uint8_t* dst_argb, int width) { - asm volatile( - "movi v23.8b, #255 \n" - "1: \n" - "ld1 {v20.8b}, [%0], #8 \n" - "orr v21.8b, v20.8b, v20.8b \n" - "orr v22.8b, v20.8b, v20.8b \n" - "subs %w2, %w2, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%1], #32 \n" - "b.gt 1b \n" - : "+r"(src_y), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v20", "v21", "v22", "v23"); -} - -void NV12ToARGBRow_NEON(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP - "movi v23.8b, #255 \n" - "1: \n" - READNV12 - YUVTORGB(v22, v21, v20) - "subs %w3, %w3, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%2], #32 \n" - "b.gt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_uv), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : [kUVToRB]"r"(&yuvconstants->kUVToRB), - [kUVToG]"r"(&yuvconstants->kUVToG), - [kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR), - [kYToRgb]"r"(&yuvconstants->kYToRgb) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", - "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" - ); -} - -void NV21ToARGBRow_NEON(const uint8_t* src_y, - const uint8_t* src_vu, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP - "movi v23.8b, #255 \n" - "1: \n" - READNV21 - YUVTORGB(v22, v21, v20) - "subs %w3, %w3, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%2], #32 \n" - "b.gt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_vu), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : [kUVToRB]"r"(&yuvconstants->kUVToRB), - [kUVToG]"r"(&yuvconstants->kUVToG), - [kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR), - [kYToRgb]"r"(&yuvconstants->kYToRgb) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", - "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" - ); -} - -void NV12ToRGB24Row_NEON(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP - "1: \n" - READNV12 - YUVTORGB(v22, v21, v20) - "subs %w3, %w3, #8 \n" - "st3 {v20.8b,v21.8b,v22.8b}, [%2], #24 \n" - "b.gt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_uv), // %1 - "+r"(dst_rgb24), // %2 - "+r"(width) // %3 - : [kUVToRB]"r"(&yuvconstants->kUVToRB), - [kUVToG]"r"(&yuvconstants->kUVToG), - [kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR), - [kYToRgb]"r"(&yuvconstants->kYToRgb) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", - "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" - ); -} - -void NV21ToRGB24Row_NEON(const uint8_t* src_y, - const uint8_t* src_vu, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP - "1: \n" - READNV21 - YUVTORGB(v22, v21, v20) - "subs %w3, %w3, #8 \n" - "st3 {v20.8b,v21.8b,v22.8b}, [%2], #24 \n" - "b.gt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_vu), // %1 - "+r"(dst_rgb24), // %2 - "+r"(width) // %3 - : [kUVToRB]"r"(&yuvconstants->kUVToRB), - [kUVToG]"r"(&yuvconstants->kUVToG), - [kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR), - [kYToRgb]"r"(&yuvconstants->kYToRgb) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", - "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" - ); -} - -void NV12ToRGB565Row_NEON(const uint8_t* src_y, - const uint8_t* src_uv, - uint8_t* dst_rgb565, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile( - YUVTORGB_SETUP - "1: \n" READNV12 YUVTORGB( - v22, v21, - v20) "subs %w3, %w3, #8 \n" ARGBTORGB565 - "st1 {v0.8h}, [%2], 16 \n" // store 8 pixels - // RGB565. - "b.gt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_uv), // %1 - "+r"(dst_rgb565), // %2 - "+r"(width) // %3 - : [kUVToRB] "r"(&yuvconstants->kUVToRB), - [kUVToG] "r"(&yuvconstants->kUVToG), - [kUVBiasBGR] "r"(&yuvconstants->kUVBiasBGR), - [kYToRgb] "r"(&yuvconstants->kYToRgb) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", - "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"); -} - -void YUY2ToARGBRow_NEON(const uint8_t* src_yuy2, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP - "movi v23.8b, #255 \n" - "1: \n" - READYUY2 - YUVTORGB(v22, v21, v20) - "subs %w2, %w2, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%1], #32 \n" - "b.gt 1b \n" - : "+r"(src_yuy2), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : [kUVToRB]"r"(&yuvconstants->kUVToRB), - [kUVToG]"r"(&yuvconstants->kUVToG), - [kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR), - [kYToRgb]"r"(&yuvconstants->kYToRgb) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", - "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" - ); -} - -void UYVYToARGBRow_NEON(const uint8_t* src_uyvy, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - asm volatile ( - YUVTORGB_SETUP - "movi v23.8b, #255 \n" - "1: \n" - READUYVY - YUVTORGB(v22, v21, v20) - "subs %w2, %w2, #8 \n" - "st4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%1], 32 \n" - "b.gt 1b \n" - : "+r"(src_uyvy), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : [kUVToRB]"r"(&yuvconstants->kUVToRB), - [kUVToG]"r"(&yuvconstants->kUVToG), - [kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR), - [kYToRgb]"r"(&yuvconstants->kYToRgb) - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", - "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" - ); -} - -// Reads 16 pairs of UV and write even values to dst_u and odd to dst_v. -void SplitUVRow_NEON(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "1: \n" - "ld2 {v0.16b,v1.16b}, [%0], #32 \n" // load 16 pairs of UV - "subs %w3, %w3, #16 \n" // 16 processed per loop - "st1 {v0.16b}, [%1], #16 \n" // store U - "st1 {v1.16b}, [%2], #16 \n" // store V - "b.gt 1b \n" - : "+r"(src_uv), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 // Output registers - : // Input registers - : "cc", "memory", "v0", "v1" // Clobber List - ); -} - -// Reads 16 U's and V's and writes out 16 pairs of UV. -void MergeUVRow_NEON(const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uv, - int width) { - asm volatile( - "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load U - "ld1 {v1.16b}, [%1], #16 \n" // load V - "subs %w3, %w3, #16 \n" // 16 processed per loop - "st2 {v0.16b,v1.16b}, [%2], #32 \n" // store 16 pairs of UV - "b.gt 1b \n" - : "+r"(src_u), // %0 - "+r"(src_v), // %1 - "+r"(dst_uv), // %2 - "+r"(width) // %3 // Output registers - : // Input registers - : "cc", "memory", "v0", "v1" // Clobber List - ); -} - -// Reads 16 packed RGB and write to planar dst_r, dst_g, dst_b. -void SplitRGBRow_NEON(const uint8_t* src_rgb, - uint8_t* dst_r, - uint8_t* dst_g, - uint8_t* dst_b, - int width) { - asm volatile( - "1: \n" - "ld3 {v0.16b,v1.16b,v2.16b}, [%0], #48 \n" // load 16 RGB - "subs %w4, %w4, #16 \n" // 16 processed per loop - "st1 {v0.16b}, [%1], #16 \n" // store R - "st1 {v1.16b}, [%2], #16 \n" // store G - "st1 {v2.16b}, [%3], #16 \n" // store B - "b.gt 1b \n" - : "+r"(src_rgb), // %0 - "+r"(dst_r), // %1 - "+r"(dst_g), // %2 - "+r"(dst_b), // %3 - "+r"(width) // %4 - : // Input registers - : "cc", "memory", "v0", "v1", "v2" // Clobber List - ); -} - -// Reads 16 planar R's, G's and B's and writes out 16 packed RGB at a time -void MergeRGBRow_NEON(const uint8_t* src_r, - const uint8_t* src_g, - const uint8_t* src_b, - uint8_t* dst_rgb, - int width) { - asm volatile( - "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load R - "ld1 {v1.16b}, [%1], #16 \n" // load G - "ld1 {v2.16b}, [%2], #16 \n" // load B - "subs %w4, %w4, #16 \n" // 16 processed per loop - "st3 {v0.16b,v1.16b,v2.16b}, [%3], #48 \n" // store 16 RGB - "b.gt 1b \n" - : "+r"(src_r), // %0 - "+r"(src_g), // %1 - "+r"(src_b), // %2 - "+r"(dst_rgb), // %3 - "+r"(width) // %4 - : // Input registers - : "cc", "memory", "v0", "v1", "v2" // Clobber List - ); -} - -// Copy multiple of 32. -void CopyRow_NEON(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - "1: \n" - "ldp q0, q1, [%0], #32 \n" - "subs %w2, %w2, #32 \n" // 32 processed per loop - "stp q0, q1, [%1], #32 \n" - "b.gt 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 // Output registers - : // Input registers - : "cc", "memory", "v0", "v1" // Clobber List - ); -} - -// SetRow writes 'width' bytes using an 8 bit value repeated. -void SetRow_NEON(uint8_t* dst, uint8_t v8, int width) { - asm volatile( - "dup v0.16b, %w2 \n" // duplicate 16 bytes - "1: \n" - "subs %w1, %w1, #16 \n" // 16 bytes per loop - "st1 {v0.16b}, [%0], #16 \n" // store - "b.gt 1b \n" - : "+r"(dst), // %0 - "+r"(width) // %1 - : "r"(v8) // %2 - : "cc", "memory", "v0"); -} - -void ARGBSetRow_NEON(uint8_t* dst, uint32_t v32, int width) { - asm volatile( - "dup v0.4s, %w2 \n" // duplicate 4 ints - "1: \n" - "subs %w1, %w1, #4 \n" // 4 ints per loop - "st1 {v0.16b}, [%0], #16 \n" // store - "b.gt 1b \n" - : "+r"(dst), // %0 - "+r"(width) // %1 - : "r"(v32) // %2 - : "cc", "memory", "v0"); -} - -void MirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - // Start at end of source row. - "add %0, %0, %w2, sxtw \n" - "sub %0, %0, #16 \n" - "1: \n" - "ld1 {v0.16b}, [%0], %3 \n" // src -= 16 - "subs %w2, %w2, #16 \n" // 16 pixels per loop. - "rev64 v0.16b, v0.16b \n" - "st1 {v0.D}[1], [%1], #8 \n" // dst += 16 - "st1 {v0.D}[0], [%1], #8 \n" - "b.gt 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "r"((ptrdiff_t)-16) // %3 - : "cc", "memory", "v0"); -} - -void MirrorUVRow_NEON(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - // Start at end of source row. - "add %0, %0, %w3, sxtw #1 \n" - "sub %0, %0, #16 \n" - "1: \n" - "ld2 {v0.8b, v1.8b}, [%0], %4 \n" // src -= 16 - "subs %w3, %w3, #8 \n" // 8 pixels per loop. - "rev64 v0.8b, v0.8b \n" - "rev64 v1.8b, v1.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // dst += 8 - "st1 {v1.8b}, [%2], #8 \n" - "b.gt 1b \n" - : "+r"(src_uv), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 - : "r"((ptrdiff_t)-16) // %4 - : "cc", "memory", "v0", "v1"); -} - -void ARGBMirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width) { - asm volatile( - // Start at end of source row. - "add %0, %0, %w2, sxtw #2 \n" - "sub %0, %0, #16 \n" - "1: \n" - "ld1 {v0.16b}, [%0], %3 \n" // src -= 16 - "subs %w2, %w2, #4 \n" // 4 pixels per loop. - "rev64 v0.4s, v0.4s \n" - "st1 {v0.D}[1], [%1], #8 \n" // dst += 16 - "st1 {v0.D}[0], [%1], #8 \n" - "b.gt 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "r"((ptrdiff_t)-16) // %3 - : "cc", "memory", "v0"); -} - -void RGB24ToARGBRow_NEON(const uint8_t* src_rgb24, - uint8_t* dst_argb, - int width) { - asm volatile( - "movi v4.8b, #255 \n" // Alpha - "1: \n" - "ld3 {v1.8b,v2.8b,v3.8b}, [%0], #24 \n" // load 8 pixels of RGB24. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "st4 {v1.8b,v2.8b,v3.8b,v4.8b}, [%1], #32 \n" // store 8 ARGB - "b.gt 1b \n" - : "+r"(src_rgb24), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v1", "v2", "v3", "v4" // Clobber List - ); -} - -void RAWToARGBRow_NEON(const uint8_t* src_raw, uint8_t* dst_argb, int width) { - asm volatile( - "movi v5.8b, #255 \n" // Alpha - "1: \n" - "ld3 {v0.8b,v1.8b,v2.8b}, [%0], #24 \n" // read r g b - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "orr v3.8b, v1.8b, v1.8b \n" // move g - "orr v4.8b, v0.8b, v0.8b \n" // move r - "st4 {v2.8b,v3.8b,v4.8b,v5.8b}, [%1], #32 \n" // store b g r a - "b.gt 1b \n" - : "+r"(src_raw), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5" // Clobber List - ); -} - -void RAWToRGB24Row_NEON(const uint8_t* src_raw, uint8_t* dst_rgb24, int width) { - asm volatile( - "1: \n" - "ld3 {v0.8b,v1.8b,v2.8b}, [%0], #24 \n" // read r g b - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "orr v3.8b, v1.8b, v1.8b \n" // move g - "orr v4.8b, v0.8b, v0.8b \n" // move r - "st3 {v2.8b,v3.8b,v4.8b}, [%1], #24 \n" // store b g r - "b.gt 1b \n" - : "+r"(src_raw), // %0 - "+r"(dst_rgb24), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4" // Clobber List - ); -} - -#define RGB565TOARGB \ - "shrn v6.8b, v0.8h, #5 \n" /* G xxGGGGGG */ \ - "shl v6.8b, v6.8b, #2 \n" /* G GGGGGG00 upper 6 */ \ - "ushr v4.8b, v6.8b, #6 \n" /* G 000000GG lower 2 */ \ - "orr v1.8b, v4.8b, v6.8b \n" /* G */ \ - "xtn v2.8b, v0.8h \n" /* B xxxBBBBB */ \ - "ushr v0.8h, v0.8h, #11 \n" /* R 000RRRRR */ \ - "xtn2 v2.16b,v0.8h \n" /* R in upper part */ \ - "shl v2.16b, v2.16b, #3 \n" /* R,B BBBBB000 upper 5 */ \ - "ushr v0.16b, v2.16b, #5 \n" /* R,B 00000BBB lower 3 */ \ - "orr v0.16b, v0.16b, v2.16b \n" /* R,B */ \ - "dup v2.2D, v0.D[1] \n" /* R */ - -void RGB565ToARGBRow_NEON(const uint8_t* src_rgb565, - uint8_t* dst_argb, - int width) { - asm volatile( - "movi v3.8b, #255 \n" // Alpha - "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 RGB565 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - RGB565TOARGB - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n" // store 8 ARGB - "b.gt 1b \n" - : "+r"(src_rgb565), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v6" // Clobber List - ); -} - -#define ARGB1555TOARGB \ - "ushr v2.8h, v0.8h, #10 \n" /* R xxxRRRRR */ \ - "shl v2.8h, v2.8h, #3 \n" /* R RRRRR000 upper 5 */ \ - "xtn v3.8b, v2.8h \n" /* RRRRR000 AAAAAAAA */ \ - \ - "sshr v2.8h, v0.8h, #15 \n" /* A AAAAAAAA */ \ - "xtn2 v3.16b, v2.8h \n" \ - \ - "xtn v2.8b, v0.8h \n" /* B xxxBBBBB */ \ - "shrn2 v2.16b,v0.8h, #5 \n" /* G xxxGGGGG */ \ - \ - "ushr v1.16b, v3.16b, #5 \n" /* R,A 00000RRR lower 3 */ \ - "shl v0.16b, v2.16b, #3 \n" /* B,G BBBBB000 upper 5 */ \ - "ushr v2.16b, v0.16b, #5 \n" /* B,G 00000BBB lower 3 */ \ - \ - "orr v0.16b, v0.16b, v2.16b \n" /* B,G */ \ - "orr v2.16b, v1.16b, v3.16b \n" /* R,A */ \ - "dup v1.2D, v0.D[1] \n" \ - "dup v3.2D, v2.D[1] \n" - -// RGB555TOARGB is same as ARGB1555TOARGB but ignores alpha. -#define RGB555TOARGB \ - "ushr v2.8h, v0.8h, #10 \n" /* R xxxRRRRR */ \ - "shl v2.8h, v2.8h, #3 \n" /* R RRRRR000 upper 5 */ \ - "xtn v3.8b, v2.8h \n" /* RRRRR000 */ \ - \ - "xtn v2.8b, v0.8h \n" /* B xxxBBBBB */ \ - "shrn2 v2.16b,v0.8h, #5 \n" /* G xxxGGGGG */ \ - \ - "ushr v1.16b, v3.16b, #5 \n" /* R 00000RRR lower 3 */ \ - "shl v0.16b, v2.16b, #3 \n" /* B,G BBBBB000 upper 5 */ \ - "ushr v2.16b, v0.16b, #5 \n" /* B,G 00000BBB lower 3 */ \ - \ - "orr v0.16b, v0.16b, v2.16b \n" /* B,G */ \ - "orr v2.16b, v1.16b, v3.16b \n" /* R */ \ - "dup v1.2D, v0.D[1] \n" /* G */ - -void ARGB1555ToARGBRow_NEON(const uint8_t* src_argb1555, - uint8_t* dst_argb, - int width) { - asm volatile( - "movi v3.8b, #255 \n" // Alpha - "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB1555 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - ARGB1555TOARGB - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n" // store 8 ARGB - // pixels - "b.gt 1b \n" - : "+r"(src_argb1555), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List - ); -} - -#define ARGB4444TOARGB \ - "shrn v1.8b, v0.8h, #8 \n" /* v1(l) AR */ \ - "xtn2 v1.16b, v0.8h \n" /* v1(h) GB */ \ - "shl v2.16b, v1.16b, #4 \n" /* B,R BBBB0000 */ \ - "ushr v3.16b, v1.16b, #4 \n" /* G,A 0000GGGG */ \ - "ushr v0.16b, v2.16b, #4 \n" /* B,R 0000BBBB */ \ - "shl v1.16b, v3.16b, #4 \n" /* G,A GGGG0000 */ \ - "orr v2.16b, v0.16b, v2.16b \n" /* B,R BBBBBBBB */ \ - "orr v3.16b, v1.16b, v3.16b \n" /* G,A GGGGGGGG */ \ - "dup v0.2D, v2.D[1] \n" \ - "dup v1.2D, v3.D[1] \n" - -void ARGB4444ToARGBRow_NEON(const uint8_t* src_argb4444, - uint8_t* dst_argb, - int width) { - asm volatile( - "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB4444 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - ARGB4444TOARGB - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n" // store 8 ARGB - // pixels - "b.gt 1b \n" - : "+r"(src_argb4444), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4" // Clobber List - ); -} - -void ARGBToRGB24Row_NEON(const uint8_t* src_argb, - uint8_t* dst_rgb24, - int width) { - asm volatile( - "1: \n" - "ld4 {v1.8b,v2.8b,v3.8b,v4.8b}, [%0], #32 \n" // load 8 ARGB - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "st3 {v1.8b,v2.8b,v3.8b}, [%1], #24 \n" // store 8 pixels of - // RGB24. - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_rgb24), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v1", "v2", "v3", "v4" // Clobber List - ); -} - -void ARGBToRAWRow_NEON(const uint8_t* src_argb, uint8_t* dst_raw, int width) { - asm volatile( - "1: \n" - "ld4 {v1.8b,v2.8b,v3.8b,v4.8b}, [%0], #32 \n" // load b g r a - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "orr v4.8b, v2.8b, v2.8b \n" // mov g - "orr v5.8b, v1.8b, v1.8b \n" // mov b - "st3 {v3.8b,v4.8b,v5.8b}, [%1], #24 \n" // store r g b - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_raw), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v1", "v2", "v3", "v4", "v5" // Clobber List - ); -} - -void YUY2ToYRow_NEON(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { - asm volatile( - "1: \n" - "ld2 {v0.16b,v1.16b}, [%0], #32 \n" // load 16 pixels of YUY2. - "subs %w2, %w2, #16 \n" // 16 processed per loop. - "st1 {v0.16b}, [%1], #16 \n" // store 16 pixels of Y. - "b.gt 1b \n" - : "+r"(src_yuy2), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1" // Clobber List - ); -} - -void UYVYToYRow_NEON(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { - asm volatile( - "1: \n" - "ld2 {v0.16b,v1.16b}, [%0], #32 \n" // load 16 pixels of UYVY. - "subs %w2, %w2, #16 \n" // 16 processed per loop. - "st1 {v1.16b}, [%1], #16 \n" // store 16 pixels of Y. - "b.gt 1b \n" - : "+r"(src_uyvy), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1" // Clobber List - ); -} - -void YUY2ToUV422Row_NEON(const uint8_t* src_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 16 YUY2 - "subs %w3, %w3, #16 \n" // 16 pixels = 8 UVs. - "st1 {v1.8b}, [%1], #8 \n" // store 8 U. - "st1 {v3.8b}, [%2], #8 \n" // store 8 V. - "b.gt 1b \n" - : "+r"(src_yuy2), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List - ); -} - -void UYVYToUV422Row_NEON(const uint8_t* src_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 16 UYVY - "subs %w3, %w3, #16 \n" // 16 pixels = 8 UVs. - "st1 {v0.8b}, [%1], #8 \n" // store 8 U. - "st1 {v2.8b}, [%2], #8 \n" // store 8 V. - "b.gt 1b \n" - : "+r"(src_uyvy), // %0 - "+r"(dst_u), // %1 - "+r"(dst_v), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List - ); -} - -void YUY2ToUVRow_NEON(const uint8_t* src_yuy2, - int stride_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - const uint8_t* src_yuy2b = src_yuy2 + stride_yuy2; - asm volatile( - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 16 pixels - "subs %w4, %w4, #16 \n" // 16 pixels = 8 UVs. - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load next row - "urhadd v1.8b, v1.8b, v5.8b \n" // average rows of U - "urhadd v3.8b, v3.8b, v7.8b \n" // average rows of V - "st1 {v1.8b}, [%2], #8 \n" // store 8 U. - "st1 {v3.8b}, [%3], #8 \n" // store 8 V. - "b.gt 1b \n" - : "+r"(src_yuy2), // %0 - "+r"(src_yuy2b), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", - "v7" // Clobber List - ); -} - -void UYVYToUVRow_NEON(const uint8_t* src_uyvy, - int stride_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - const uint8_t* src_uyvyb = src_uyvy + stride_uyvy; - asm volatile( - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 16 pixels - "subs %w4, %w4, #16 \n" // 16 pixels = 8 UVs. - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load next row - "urhadd v0.8b, v0.8b, v4.8b \n" // average rows of U - "urhadd v2.8b, v2.8b, v6.8b \n" // average rows of V - "st1 {v0.8b}, [%2], #8 \n" // store 8 U. - "st1 {v2.8b}, [%3], #8 \n" // store 8 V. - "b.gt 1b \n" - : "+r"(src_uyvy), // %0 - "+r"(src_uyvyb), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", - "v7" // Clobber List - ); -} - -// For BGRAToARGB, ABGRToARGB, RGBAToARGB, and ARGBToRGBA. -void ARGBShuffleRow_NEON(const uint8_t* src_argb, - uint8_t* dst_argb, - const uint8_t* shuffler, - int width) { - asm volatile( - "ld1 {v2.16b}, [%3] \n" // shuffler - "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 4 pixels. - "subs %w2, %w2, #4 \n" // 4 processed per loop - "tbl v1.16b, {v0.16b}, v2.16b \n" // look up 4 pixels - "st1 {v1.16b}, [%1], #16 \n" // store 4. - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : "r"(shuffler) // %3 - : "cc", "memory", "v0", "v1", "v2" // Clobber List - ); -} - -void I422ToYUY2Row_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_yuy2, - int width) { - asm volatile( - "1: \n" - "ld2 {v0.8b, v1.8b}, [%0], #16 \n" // load 16 Ys - "orr v2.8b, v1.8b, v1.8b \n" - "ld1 {v1.8b}, [%1], #8 \n" // load 8 Us - "ld1 {v3.8b}, [%2], #8 \n" // load 8 Vs - "subs %w4, %w4, #16 \n" // 16 pixels - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%3], #32 \n" // Store 16 pixels. - "b.gt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_yuy2), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "v0", "v1", "v2", "v3"); -} - -void I422ToUYVYRow_NEON(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uyvy, - int width) { - asm volatile( - "1: \n" - "ld2 {v1.8b,v2.8b}, [%0], #16 \n" // load 16 Ys - "orr v3.8b, v2.8b, v2.8b \n" - "ld1 {v0.8b}, [%1], #8 \n" // load 8 Us - "ld1 {v2.8b}, [%2], #8 \n" // load 8 Vs - "subs %w4, %w4, #16 \n" // 16 pixels - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%3], #32 \n" // Store 16 pixels. - "b.gt 1b \n" - : "+r"(src_y), // %0 - "+r"(src_u), // %1 - "+r"(src_v), // %2 - "+r"(dst_uyvy), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "v0", "v1", "v2", "v3"); -} - -void ARGBToRGB565Row_NEON(const uint8_t* src_argb, - uint8_t* dst_rgb565, - int width) { - asm volatile( - "1: \n" - "ld4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%0], #32 \n" // load 8 pixels - "subs %w2, %w2, #8 \n" // 8 processed per loop. - ARGBTORGB565 - "st1 {v0.16b}, [%1], #16 \n" // store 8 pixels RGB565. - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_rgb565), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v20", "v21", "v22", "v23"); -} - -void ARGBToRGB565DitherRow_NEON(const uint8_t* src_argb, - uint8_t* dst_rgb, - const uint32_t dither4, - int width) { - asm volatile( - "dup v1.4s, %w2 \n" // dither4 - "1: \n" - "ld4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%1], #32 \n" // load 8 pixels - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "uqadd v20.8b, v20.8b, v1.8b \n" - "uqadd v21.8b, v21.8b, v1.8b \n" - "uqadd v22.8b, v22.8b, v1.8b \n" ARGBTORGB565 - "st1 {v0.16b}, [%0], #16 \n" // store 8 pixels RGB565. - "b.gt 1b \n" - : "+r"(dst_rgb) // %0 - : "r"(src_argb), // %1 - "r"(dither4), // %2 - "r"(width) // %3 - : "cc", "memory", "v0", "v1", "v20", "v21", "v22", "v23"); -} - -void ARGBToARGB1555Row_NEON(const uint8_t* src_argb, - uint8_t* dst_argb1555, - int width) { - asm volatile( - "1: \n" - "ld4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%0], #32 \n" // load 8 pixels - "subs %w2, %w2, #8 \n" // 8 processed per loop. - ARGBTOARGB1555 - "st1 {v0.16b}, [%1], #16 \n" // store 8 pixels - // ARGB1555. - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb1555), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v20", "v21", "v22", "v23"); -} - -void ARGBToARGB4444Row_NEON(const uint8_t* src_argb, - uint8_t* dst_argb4444, - int width) { - asm volatile( - "movi v4.16b, #0x0f \n" // bits to clear with - // vbic. - "1: \n" - "ld4 {v20.8b,v21.8b,v22.8b,v23.8b}, [%0], #32 \n" // load 8 pixels - "subs %w2, %w2, #8 \n" // 8 processed per loop. - ARGBTOARGB4444 - "st1 {v0.16b}, [%1], #16 \n" // store 8 pixels - // ARGB4444. - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb4444), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v4", "v20", "v21", "v22", "v23"); -} - -void ARGBToYRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width) { - asm volatile( - "movi v4.8b, #13 \n" // B * 0.1016 coefficient - "movi v5.8b, #65 \n" // G * 0.5078 coefficient - "movi v6.8b, #33 \n" // R * 0.2578 coefficient - "movi v7.8b, #16 \n" // Add 16 constant - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v3.8h, v0.8b, v4.8b \n" // B - "umlal v3.8h, v1.8b, v5.8b \n" // G - "umlal v3.8h, v2.8b, v6.8b \n" // R - "sqrshrun v0.8b, v3.8h, #7 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v7.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"); -} - -void ARGBExtractAlphaRow_NEON(const uint8_t* src_argb, - uint8_t* dst_a, - int width) { - asm volatile( - "1: \n" - "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load row 16 - // pixels - "subs %w2, %w2, #16 \n" // 16 processed per loop - "st1 {v3.16b}, [%1], #16 \n" // store 16 A's. - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_a), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List - ); -} - -void ARGBToYJRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width) { - asm volatile( - "movi v4.8b, #15 \n" // B * 0.11400 coefficient - "movi v5.8b, #75 \n" // G * 0.58700 coefficient - "movi v6.8b, #38 \n" // R * 0.29900 coefficient - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v3.8h, v0.8b, v4.8b \n" // B - "umlal v3.8h, v1.8b, v5.8b \n" // G - "umlal v3.8h, v2.8b, v6.8b \n" // R - "sqrshrun v0.8b, v3.8h, #7 \n" // 15 bit to 8 bit Y - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6"); -} - -// 8x1 pixels. -void ARGBToUV444Row_NEON(const uint8_t* src_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - asm volatile( - "movi v24.8b, #112 \n" // UB / VR 0.875 - // coefficient - "movi v25.8b, #74 \n" // UG -0.5781 coefficient - "movi v26.8b, #38 \n" // UR -0.2969 coefficient - "movi v27.8b, #18 \n" // VB -0.1406 coefficient - "movi v28.8b, #94 \n" // VG -0.7344 coefficient - "movi v29.16b,#0x80 \n" // 128.5 - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB - // pixels. - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "umull v4.8h, v0.8b, v24.8b \n" // B - "umlsl v4.8h, v1.8b, v25.8b \n" // G - "umlsl v4.8h, v2.8b, v26.8b \n" // R - "add v4.8h, v4.8h, v29.8h \n" // +128 -> unsigned - - "umull v3.8h, v2.8b, v24.8b \n" // R - "umlsl v3.8h, v1.8b, v28.8b \n" // G - "umlsl v3.8h, v0.8b, v27.8b \n" // B - "add v3.8h, v3.8h, v29.8h \n" // +128 -> unsigned - - "uqshrn v0.8b, v4.8h, #8 \n" // 16 bit to 8 bit U - "uqshrn v1.8b, v3.8h, #8 \n" // 16 bit to 8 bit V - - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels U. - "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", "v24", "v25", "v26", - "v27", "v28", "v29"); -} - -#define RGBTOUV_SETUP_REG \ - "movi v20.8h, #56, lsl #0 \n" /* UB/VR coefficient (0.875) / 2 */ \ - "movi v21.8h, #37, lsl #0 \n" /* UG coefficient (-0.5781) / 2 */ \ - "movi v22.8h, #19, lsl #0 \n" /* UR coefficient (-0.2969) / 2 */ \ - "movi v23.8h, #9, lsl #0 \n" /* VB coefficient (-0.1406) / 2 */ \ - "movi v24.8h, #47, lsl #0 \n" /* VG coefficient (-0.7344) / 2 */ \ - "movi v25.16b, #0x80 \n" /* 128.5 (0x8080 in 16-bit) */ - -// 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. -// clang-format off -#define RGBTOUV(QB, QG, QR) \ - "mul v3.8h, " #QB ",v20.8h \n" /* B */ \ - "mul v4.8h, " #QR ",v20.8h \n" /* R */ \ - "mls v3.8h, " #QG ",v21.8h \n" /* G */ \ - "mls v4.8h, " #QG ",v24.8h \n" /* G */ \ - "mls v3.8h, " #QR ",v22.8h \n" /* R */ \ - "mls v4.8h, " #QB ",v23.8h \n" /* B */ \ - "add v3.8h, v3.8h, v25.8h \n" /* +128 -> unsigned */ \ - "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 */ -// clang-format on - -// TODO(fbarchard): Consider vhadd vertical, then vpaddl horizontal, avoid shr. -// TODO(fbarchard): consider ptrdiff_t for all strides. - -void ARGBToUVRow_NEON(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - const uint8_t* src_argb_1 = src_argb + src_stride_argb; - asm volatile ( - RGBTOUV_SETUP_REG - "1: \n" - "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. - - "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load next 16 - "uadalp v0.8h, v4.16b \n" // B 16 bytes -> 8 shorts. - "uadalp v1.8h, v5.16b \n" // G 16 bytes -> 8 shorts. - "uadalp v2.8h, v6.16b \n" // R 16 bytes -> 8 shorts. - - "urshr v0.8h, v0.8h, #1 \n" // 2x average - "urshr v1.8h, v1.8h, #1 \n" - "urshr v2.8h, v2.8h, #1 \n" - - "subs %w4, %w4, #16 \n" // 32 processed per loop. - RGBTOUV(v0.8h, v1.8h, v2.8h) - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(src_argb_1), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", - "v20", "v21", "v22", "v23", "v24", "v25" - ); -} - -// TODO(fbarchard): Subsample match C code. -void ARGBToUVJRow_NEON(const uint8_t* src_argb, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - const uint8_t* src_argb_1 = src_argb + src_stride_argb; - asm volatile ( - "movi v20.8h, #63, lsl #0 \n" // UB/VR coeff (0.500) / 2 - "movi v21.8h, #42, lsl #0 \n" // UG coeff (-0.33126) / 2 - "movi v22.8h, #21, lsl #0 \n" // UR coeff (-0.16874) / 2 - "movi v23.8h, #10, lsl #0 \n" // VB coeff (-0.08131) / 2 - "movi v24.8h, #53, lsl #0 \n" // VG coeff (-0.41869) / 2 - "movi v25.16b, #0x80 \n" // 128.5 (0x8080 in 16-bit) - "1: \n" - "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. - "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load next 16 - "uadalp v0.8h, v4.16b \n" // B 16 bytes -> 8 shorts. - "uadalp v1.8h, v5.16b \n" // G 16 bytes -> 8 shorts. - "uadalp v2.8h, v6.16b \n" // R 16 bytes -> 8 shorts. - - "urshr v0.8h, v0.8h, #1 \n" // 2x average - "urshr v1.8h, v1.8h, #1 \n" - "urshr v2.8h, v2.8h, #1 \n" - - "subs %w4, %w4, #16 \n" // 32 processed per loop. - RGBTOUV(v0.8h, v1.8h, v2.8h) - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(src_argb_1), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", - "v20", "v21", "v22", "v23", "v24", "v25" - ); -} - -void BGRAToUVRow_NEON(const uint8_t* src_bgra, - int src_stride_bgra, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - const uint8_t* src_bgra_1 = src_bgra + src_stride_bgra; - asm volatile ( - RGBTOUV_SETUP_REG - "1: \n" - "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 pixels. - "uaddlp v0.8h, v3.16b \n" // B 16 bytes -> 8 shorts. - "uaddlp v3.8h, v2.16b \n" // G 16 bytes -> 8 shorts. - "uaddlp v2.8h, v1.16b \n" // R 16 bytes -> 8 shorts. - "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load 16 more - "uadalp v0.8h, v7.16b \n" // B 16 bytes -> 8 shorts. - "uadalp v3.8h, v6.16b \n" // G 16 bytes -> 8 shorts. - "uadalp v2.8h, v5.16b \n" // R 16 bytes -> 8 shorts. - - "urshr v0.8h, v0.8h, #1 \n" // 2x average - "urshr v1.8h, v3.8h, #1 \n" - "urshr v2.8h, v2.8h, #1 \n" - - "subs %w4, %w4, #16 \n" // 32 processed per loop. - RGBTOUV(v0.8h, v1.8h, v2.8h) - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" - : "+r"(src_bgra), // %0 - "+r"(src_bgra_1), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", - "v20", "v21", "v22", "v23", "v24", "v25" - ); -} - -void ABGRToUVRow_NEON(const uint8_t* src_abgr, - int src_stride_abgr, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - const uint8_t* src_abgr_1 = src_abgr + src_stride_abgr; - asm volatile ( - RGBTOUV_SETUP_REG - "1: \n" - "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 pixels. - "uaddlp v3.8h, v2.16b \n" // B 16 bytes -> 8 shorts. - "uaddlp v2.8h, v1.16b \n" // G 16 bytes -> 8 shorts. - "uaddlp v1.8h, v0.16b \n" // R 16 bytes -> 8 shorts. - "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load 16 more. - "uadalp v3.8h, v6.16b \n" // B 16 bytes -> 8 shorts. - "uadalp v2.8h, v5.16b \n" // G 16 bytes -> 8 shorts. - "uadalp v1.8h, v4.16b \n" // R 16 bytes -> 8 shorts. - - "urshr v0.8h, v3.8h, #1 \n" // 2x average - "urshr v2.8h, v2.8h, #1 \n" - "urshr v1.8h, v1.8h, #1 \n" - - "subs %w4, %w4, #16 \n" // 32 processed per loop. - RGBTOUV(v0.8h, v2.8h, v1.8h) - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" - : "+r"(src_abgr), // %0 - "+r"(src_abgr_1), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", - "v20", "v21", "v22", "v23", "v24", "v25" - ); -} - -void RGBAToUVRow_NEON(const uint8_t* src_rgba, - int src_stride_rgba, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - const uint8_t* src_rgba_1 = src_rgba + src_stride_rgba; - asm volatile ( - RGBTOUV_SETUP_REG - "1: \n" - "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 16 pixels. - "uaddlp v0.8h, v1.16b \n" // B 16 bytes -> 8 shorts. - "uaddlp v1.8h, v2.16b \n" // G 16 bytes -> 8 shorts. - "uaddlp v2.8h, v3.16b \n" // R 16 bytes -> 8 shorts. - "ld4 {v4.16b,v5.16b,v6.16b,v7.16b}, [%1], #64 \n" // load 16 more. - "uadalp v0.8h, v5.16b \n" // B 16 bytes -> 8 shorts. - "uadalp v1.8h, v6.16b \n" // G 16 bytes -> 8 shorts. - "uadalp v2.8h, v7.16b \n" // R 16 bytes -> 8 shorts. - - "urshr v0.8h, v0.8h, #1 \n" // 2x average - "urshr v1.8h, v1.8h, #1 \n" - "urshr v2.8h, v2.8h, #1 \n" - - "subs %w4, %w4, #16 \n" // 32 processed per loop. - RGBTOUV(v0.8h, v1.8h, v2.8h) - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" - : "+r"(src_rgba), // %0 - "+r"(src_rgba_1), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", - "v20", "v21", "v22", "v23", "v24", "v25" - ); -} - -void RGB24ToUVRow_NEON(const uint8_t* src_rgb24, - int src_stride_rgb24, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - const uint8_t* src_rgb24_1 = src_rgb24 + src_stride_rgb24; - asm volatile ( - RGBTOUV_SETUP_REG - "1: \n" - "ld3 {v0.16b,v1.16b,v2.16b}, [%0], #48 \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. - "ld3 {v4.16b,v5.16b,v6.16b}, [%1], #48 \n" // load 16 more. - "uadalp v0.8h, v4.16b \n" // B 16 bytes -> 8 shorts. - "uadalp v1.8h, v5.16b \n" // G 16 bytes -> 8 shorts. - "uadalp v2.8h, v6.16b \n" // R 16 bytes -> 8 shorts. - - "urshr v0.8h, v0.8h, #1 \n" // 2x average - "urshr v1.8h, v1.8h, #1 \n" - "urshr v2.8h, v2.8h, #1 \n" - - "subs %w4, %w4, #16 \n" // 32 processed per loop. - RGBTOUV(v0.8h, v1.8h, v2.8h) - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" - : "+r"(src_rgb24), // %0 - "+r"(src_rgb24_1), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", - "v20", "v21", "v22", "v23", "v24", "v25" - ); -} - -void RAWToUVRow_NEON(const uint8_t* src_raw, - int src_stride_raw, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - const uint8_t* src_raw_1 = src_raw + src_stride_raw; - asm volatile ( - RGBTOUV_SETUP_REG - "1: \n" - "ld3 {v0.16b,v1.16b,v2.16b}, [%0], #48 \n" // load 8 RAW pixels. - "uaddlp v2.8h, v2.16b \n" // B 16 bytes -> 8 shorts. - "uaddlp v1.8h, v1.16b \n" // G 16 bytes -> 8 shorts. - "uaddlp v0.8h, v0.16b \n" // R 16 bytes -> 8 shorts. - "ld3 {v4.16b,v5.16b,v6.16b}, [%1], #48 \n" // load 8 more RAW pixels - "uadalp v2.8h, v6.16b \n" // B 16 bytes -> 8 shorts. - "uadalp v1.8h, v5.16b \n" // G 16 bytes -> 8 shorts. - "uadalp v0.8h, v4.16b \n" // R 16 bytes -> 8 shorts. - - "urshr v2.8h, v2.8h, #1 \n" // 2x average - "urshr v1.8h, v1.8h, #1 \n" - "urshr v0.8h, v0.8h, #1 \n" - - "subs %w4, %w4, #16 \n" // 32 processed per loop. - RGBTOUV(v2.8h, v1.8h, v0.8h) - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" - : "+r"(src_raw), // %0 - "+r"(src_raw_1), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", - "v20", "v21", "v22", "v23", "v24", "v25" - ); -} - -// 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. -void RGB565ToUVRow_NEON(const uint8_t* src_rgb565, - int src_stride_rgb565, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - const uint8_t* src_rgb565_1 = src_rgb565 + src_stride_rgb565; - asm volatile( - "movi v22.8h, #56, lsl #0 \n" // UB / VR coeff (0.875) / - // 2 - "movi v23.8h, #37, lsl #0 \n" // UG coeff (-0.5781) / 2 - "movi v24.8h, #19, lsl #0 \n" // UR coeff (-0.2969) / 2 - "movi v25.8h, #9 , lsl #0 \n" // VB coeff (-0.1406) / 2 - "movi v26.8h, #47, lsl #0 \n" // VG coeff (-0.7344) / 2 - "movi v27.16b, #0x80 \n" // 128.5 0x8080 in 16bit - "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 RGB565 pixels. - RGB565TOARGB - "uaddlp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uaddlp v18.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uaddlp v20.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ld1 {v0.16b}, [%0], #16 \n" // next 8 RGB565 pixels. - RGB565TOARGB - "uaddlp v17.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uaddlp v19.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uaddlp v21.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - - "ld1 {v0.16b}, [%1], #16 \n" // load 8 RGB565 pixels. - RGB565TOARGB - "uadalp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uadalp v18.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uadalp v20.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ld1 {v0.16b}, [%1], #16 \n" // next 8 RGB565 pixels. - RGB565TOARGB - "uadalp v17.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uadalp v19.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uadalp v21.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - - "ins v16.D[1], v17.D[0] \n" - "ins v18.D[1], v19.D[0] \n" - "ins v20.D[1], v21.D[0] \n" - - "urshr v4.8h, v16.8h, #1 \n" // 2x average - "urshr v5.8h, v18.8h, #1 \n" - "urshr v6.8h, v20.8h, #1 \n" - - "subs %w4, %w4, #16 \n" // 16 processed per loop. - "mul v16.8h, v4.8h, v22.8h \n" // B - "mls v16.8h, v5.8h, v23.8h \n" // G - "mls v16.8h, v6.8h, v24.8h \n" // R - "add v16.8h, v16.8h, v27.8h \n" // +128 -> unsigned - "mul v17.8h, v6.8h, v22.8h \n" // R - "mls v17.8h, v5.8h, v26.8h \n" // G - "mls v17.8h, v4.8h, v25.8h \n" // B - "add v17.8h, v17.8h, v27.8h \n" // +128 -> unsigned - "uqshrn v0.8b, v16.8h, #8 \n" // 16 bit to 8 bit U - "uqshrn v1.8b, v17.8h, #8 \n" // 16 bit to 8 bit V - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" - : "+r"(src_rgb565), // %0 - "+r"(src_rgb565_1), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", - "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", - "v27"); -} - -// 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. -void ARGB1555ToUVRow_NEON(const uint8_t* src_argb1555, - int src_stride_argb1555, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - const uint8_t* src_argb1555_1 = src_argb1555 + src_stride_argb1555; - asm volatile( - RGBTOUV_SETUP_REG - "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB1555 pixels. - RGB555TOARGB - "uaddlp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uaddlp v17.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uaddlp v18.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ld1 {v0.16b}, [%0], #16 \n" // next 8 ARGB1555 pixels. - RGB555TOARGB - "uaddlp v26.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uaddlp v27.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uaddlp v28.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - - "ld1 {v0.16b}, [%1], #16 \n" // load 8 ARGB1555 pixels. - RGB555TOARGB - "uadalp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uadalp v17.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uadalp v18.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ld1 {v0.16b}, [%1], #16 \n" // next 8 ARGB1555 pixels. - RGB555TOARGB - "uadalp v26.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uadalp v27.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uadalp v28.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - - "ins v16.D[1], v26.D[0] \n" - "ins v17.D[1], v27.D[0] \n" - "ins v18.D[1], v28.D[0] \n" - - "urshr v4.8h, v16.8h, #1 \n" // 2x average - "urshr v5.8h, v17.8h, #1 \n" - "urshr v6.8h, v18.8h, #1 \n" - - "subs %w4, %w4, #16 \n" // 16 processed per loop. - "mul v2.8h, v4.8h, v20.8h \n" // B - "mls v2.8h, v5.8h, v21.8h \n" // G - "mls v2.8h, v6.8h, v22.8h \n" // R - "add v2.8h, v2.8h, v25.8h \n" // +128 -> unsigned - "mul v3.8h, v6.8h, v20.8h \n" // R - "mls v3.8h, v5.8h, v24.8h \n" // G - "mls v3.8h, v4.8h, v23.8h \n" // B - "add v3.8h, v3.8h, v25.8h \n" // +128 -> unsigned - "uqshrn v0.8b, v2.8h, #8 \n" // 16 bit to 8 bit U - "uqshrn v1.8b, v3.8h, #8 \n" // 16 bit to 8 bit V - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" - : "+r"(src_argb1555), // %0 - "+r"(src_argb1555_1), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v16", "v17", - "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", - "v28"); -} - -// 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. -void ARGB4444ToUVRow_NEON(const uint8_t* src_argb4444, - int src_stride_argb4444, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - const uint8_t* src_argb4444_1 = src_argb4444 + src_stride_argb4444; - asm volatile( - RGBTOUV_SETUP_REG - "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB4444 pixels. - ARGB4444TOARGB - "uaddlp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uaddlp v17.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uaddlp v18.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ld1 {v0.16b}, [%0], #16 \n" // next 8 ARGB4444 pixels. - ARGB4444TOARGB - "uaddlp v26.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uaddlp v27.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uaddlp v28.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - - "ld1 {v0.16b}, [%1], #16 \n" // load 8 ARGB4444 pixels. - ARGB4444TOARGB - "uadalp v16.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uadalp v17.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uadalp v18.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - "ld1 {v0.16b}, [%1], #16 \n" // next 8 ARGB4444 pixels. - ARGB4444TOARGB - "uadalp v26.4h, v0.8b \n" // B 8 bytes -> 4 shorts. - "uadalp v27.4h, v1.8b \n" // G 8 bytes -> 4 shorts. - "uadalp v28.4h, v2.8b \n" // R 8 bytes -> 4 shorts. - - "ins v16.D[1], v26.D[0] \n" - "ins v17.D[1], v27.D[0] \n" - "ins v18.D[1], v28.D[0] \n" - - "urshr v4.8h, v16.8h, #1 \n" // 2x average - "urshr v5.8h, v17.8h, #1 \n" - "urshr v6.8h, v18.8h, #1 \n" - - "subs %w4, %w4, #16 \n" // 16 processed per loop. - "mul v2.8h, v4.8h, v20.8h \n" // B - "mls v2.8h, v5.8h, v21.8h \n" // G - "mls v2.8h, v6.8h, v22.8h \n" // R - "add v2.8h, v2.8h, v25.8h \n" // +128 -> unsigned - "mul v3.8h, v6.8h, v20.8h \n" // R - "mls v3.8h, v5.8h, v24.8h \n" // G - "mls v3.8h, v4.8h, v23.8h \n" // B - "add v3.8h, v3.8h, v25.8h \n" // +128 -> unsigned - "uqshrn v0.8b, v2.8h, #8 \n" // 16 bit to 8 bit U - "uqshrn v1.8b, v3.8h, #8 \n" // 16 bit to 8 bit V - "st1 {v0.8b}, [%2], #8 \n" // store 8 pixels U. - "st1 {v1.8b}, [%3], #8 \n" // store 8 pixels V. - "b.gt 1b \n" - : "+r"(src_argb4444), // %0 - "+r"(src_argb4444_1), // %1 - "+r"(dst_u), // %2 - "+r"(dst_v), // %3 - "+r"(width) // %4 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v16", "v17", - "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", - "v28" - - ); -} - -void RGB565ToYRow_NEON(const uint8_t* src_rgb565, uint8_t* dst_y, int width) { - asm volatile( - "movi v24.8b, #13 \n" // B * 0.1016 coefficient - "movi v25.8b, #65 \n" // G * 0.5078 coefficient - "movi v26.8b, #33 \n" // R * 0.2578 coefficient - "movi v27.8b, #16 \n" // Add 16 constant - "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 RGB565 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - RGB565TOARGB - "umull v3.8h, v0.8b, v24.8b \n" // B - "umlal v3.8h, v1.8b, v25.8b \n" // G - "umlal v3.8h, v2.8b, v26.8b \n" // R - "sqrshrun v0.8b, v3.8h, #7 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v27.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" - : "+r"(src_rgb565), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v6", "v24", "v25", "v26", - "v27"); -} - -void ARGB1555ToYRow_NEON(const uint8_t* src_argb1555, - uint8_t* dst_y, - int width) { - asm volatile( - "movi v4.8b, #13 \n" // B * 0.1016 coefficient - "movi v5.8b, #65 \n" // G * 0.5078 coefficient - "movi v6.8b, #33 \n" // R * 0.2578 coefficient - "movi v7.8b, #16 \n" // Add 16 constant - "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB1555 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - ARGB1555TOARGB - "umull v3.8h, v0.8b, v4.8b \n" // B - "umlal v3.8h, v1.8b, v5.8b \n" // G - "umlal v3.8h, v2.8b, v6.8b \n" // R - "sqrshrun v0.8b, v3.8h, #7 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v7.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" - : "+r"(src_argb1555), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"); -} - -void ARGB4444ToYRow_NEON(const uint8_t* src_argb4444, - uint8_t* dst_y, - int width) { - asm volatile( - "movi v24.8b, #13 \n" // B * 0.1016 coefficient - "movi v25.8b, #65 \n" // G * 0.5078 coefficient - "movi v26.8b, #33 \n" // R * 0.2578 coefficient - "movi v27.8b, #16 \n" // Add 16 constant - "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 8 ARGB4444 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - ARGB4444TOARGB - "umull v3.8h, v0.8b, v24.8b \n" // B - "umlal v3.8h, v1.8b, v25.8b \n" // G - "umlal v3.8h, v2.8b, v26.8b \n" // R - "sqrshrun v0.8b, v3.8h, #7 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v27.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" - : "+r"(src_argb4444), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v24", "v25", "v26", "v27"); -} - -void BGRAToYRow_NEON(const uint8_t* src_bgra, uint8_t* dst_y, int width) { - asm volatile( - "movi v4.8b, #33 \n" // R * 0.2578 coefficient - "movi v5.8b, #65 \n" // G * 0.5078 coefficient - "movi v6.8b, #13 \n" // B * 0.1016 coefficient - "movi v7.8b, #16 \n" // Add 16 constant - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v16.8h, v1.8b, v4.8b \n" // R - "umlal v16.8h, v2.8b, v5.8b \n" // G - "umlal v16.8h, v3.8b, v6.8b \n" // B - "sqrshrun v0.8b, v16.8h, #7 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v7.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" - : "+r"(src_bgra), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"); -} - -void ABGRToYRow_NEON(const uint8_t* src_abgr, uint8_t* dst_y, int width) { - asm volatile( - "movi v4.8b, #33 \n" // R * 0.2578 coefficient - "movi v5.8b, #65 \n" // G * 0.5078 coefficient - "movi v6.8b, #13 \n" // B * 0.1016 coefficient - "movi v7.8b, #16 \n" // Add 16 constant - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v16.8h, v0.8b, v4.8b \n" // R - "umlal v16.8h, v1.8b, v5.8b \n" // G - "umlal v16.8h, v2.8b, v6.8b \n" // B - "sqrshrun v0.8b, v16.8h, #7 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v7.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" - : "+r"(src_abgr), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"); -} - -void RGBAToYRow_NEON(const uint8_t* src_rgba, uint8_t* dst_y, int width) { - asm volatile( - "movi v4.8b, #13 \n" // B * 0.1016 coefficient - "movi v5.8b, #65 \n" // G * 0.5078 coefficient - "movi v6.8b, #33 \n" // R * 0.2578 coefficient - "movi v7.8b, #16 \n" // Add 16 constant - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v16.8h, v1.8b, v4.8b \n" // B - "umlal v16.8h, v2.8b, v5.8b \n" // G - "umlal v16.8h, v3.8b, v6.8b \n" // R - "sqrshrun v0.8b, v16.8h, #7 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v7.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" - : "+r"(src_rgba), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"); -} - -void RGB24ToYRow_NEON(const uint8_t* src_rgb24, uint8_t* dst_y, int width) { - asm volatile( - "movi v4.8b, #13 \n" // B * 0.1016 coefficient - "movi v5.8b, #65 \n" // G * 0.5078 coefficient - "movi v6.8b, #33 \n" // R * 0.2578 coefficient - "movi v7.8b, #16 \n" // Add 16 constant - "1: \n" - "ld3 {v0.8b,v1.8b,v2.8b}, [%0], #24 \n" // load 8 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v16.8h, v0.8b, v4.8b \n" // B - "umlal v16.8h, v1.8b, v5.8b \n" // G - "umlal v16.8h, v2.8b, v6.8b \n" // R - "sqrshrun v0.8b, v16.8h, #7 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v7.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" - : "+r"(src_rgb24), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"); -} - -void RAWToYRow_NEON(const uint8_t* src_raw, uint8_t* dst_y, int width) { - asm volatile( - "movi v4.8b, #33 \n" // R * 0.2578 coefficient - "movi v5.8b, #65 \n" // G * 0.5078 coefficient - "movi v6.8b, #13 \n" // B * 0.1016 coefficient - "movi v7.8b, #16 \n" // Add 16 constant - "1: \n" - "ld3 {v0.8b,v1.8b,v2.8b}, [%0], #24 \n" // load 8 pixels. - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v16.8h, v0.8b, v4.8b \n" // B - "umlal v16.8h, v1.8b, v5.8b \n" // G - "umlal v16.8h, v2.8b, v6.8b \n" // R - "sqrshrun v0.8b, v16.8h, #7 \n" // 16 bit to 8 bit Y - "uqadd v0.8b, v0.8b, v7.8b \n" - "st1 {v0.8b}, [%1], #8 \n" // store 8 pixels Y. - "b.gt 1b \n" - : "+r"(src_raw), // %0 - "+r"(dst_y), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"); -} - -// Bilinear filter 16x2 -> 16x1 -void InterpolateRow_NEON(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride, - int dst_width, - int source_y_fraction) { - int y1_fraction = source_y_fraction; - int y0_fraction = 256 - y1_fraction; - const uint8_t* src_ptr1 = src_ptr + src_stride; - asm volatile( - "cmp %w4, #0 \n" - "b.eq 100f \n" - "cmp %w4, #128 \n" - "b.eq 50f \n" - - "dup v5.16b, %w4 \n" - "dup v4.16b, %w5 \n" - // General purpose row blend. - "1: \n" - "ld1 {v0.16b}, [%1], #16 \n" - "ld1 {v1.16b}, [%2], #16 \n" - "subs %w3, %w3, #16 \n" - "umull v2.8h, v0.8b, v4.8b \n" - "umull2 v3.8h, v0.16b, v4.16b \n" - "umlal v2.8h, v1.8b, v5.8b \n" - "umlal2 v3.8h, v1.16b, v5.16b \n" - "rshrn v0.8b, v2.8h, #8 \n" - "rshrn2 v0.16b, v3.8h, #8 \n" - "st1 {v0.16b}, [%0], #16 \n" - "b.gt 1b \n" - "b 99f \n" - - // Blend 50 / 50. - "50: \n" - "ld1 {v0.16b}, [%1], #16 \n" - "ld1 {v1.16b}, [%2], #16 \n" - "subs %w3, %w3, #16 \n" - "urhadd v0.16b, v0.16b, v1.16b \n" - "st1 {v0.16b}, [%0], #16 \n" - "b.gt 50b \n" - "b 99f \n" - - // Blend 100 / 0 - Copy row unchanged. - "100: \n" - "ld1 {v0.16b}, [%1], #16 \n" - "subs %w3, %w3, #16 \n" - "st1 {v0.16b}, [%0], #16 \n" - "b.gt 100b \n" - - "99: \n" - : "+r"(dst_ptr), // %0 - "+r"(src_ptr), // %1 - "+r"(src_ptr1), // %2 - "+r"(dst_width), // %3 - "+r"(y1_fraction), // %4 - "+r"(y0_fraction) // %5 - : - : "cc", "memory", "v0", "v1", "v3", "v4", "v5"); -} - -// dr * (256 - sa) / 256 + sr = dr - dr * sa / 256 + sr -void ARGBBlendRow_NEON(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - asm volatile( - "subs %w3, %w3, #8 \n" - "b.lt 89f \n" - // Blend 8 pixels. - "8: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB0 - // pixels - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load 8 ARGB1 - // pixels - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "umull v16.8h, v4.8b, v3.8b \n" // db * a - "umull v17.8h, v5.8b, v3.8b \n" // dg * a - "umull v18.8h, v6.8b, v3.8b \n" // dr * a - "uqrshrn v16.8b, v16.8h, #8 \n" // db >>= 8 - "uqrshrn v17.8b, v17.8h, #8 \n" // dg >>= 8 - "uqrshrn v18.8b, v18.8h, #8 \n" // dr >>= 8 - "uqsub v4.8b, v4.8b, v16.8b \n" // db - (db * a / 256) - "uqsub v5.8b, v5.8b, v17.8b \n" // dg - (dg * a / 256) - "uqsub v6.8b, v6.8b, v18.8b \n" // dr - (dr * a / 256) - "uqadd v0.8b, v0.8b, v4.8b \n" // + sb - "uqadd v1.8b, v1.8b, v5.8b \n" // + sg - "uqadd v2.8b, v2.8b, v6.8b \n" // + sr - "movi v3.8b, #255 \n" // a = 255 - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB - // pixels - "b.ge 8b \n" - - "89: \n" - "adds %w3, %w3, #8-1 \n" - "b.lt 99f \n" - - // Blend 1 pixels. - "1: \n" - "ld4 {v0.b,v1.b,v2.b,v3.b}[0], [%0], #4 \n" // load 1 pixel ARGB0. - "ld4 {v4.b,v5.b,v6.b,v7.b}[0], [%1], #4 \n" // load 1 pixel ARGB1. - "subs %w3, %w3, #1 \n" // 1 processed per loop. - "umull v16.8h, v4.8b, v3.8b \n" // db * a - "umull v17.8h, v5.8b, v3.8b \n" // dg * a - "umull v18.8h, v6.8b, v3.8b \n" // dr * a - "uqrshrn v16.8b, v16.8h, #8 \n" // db >>= 8 - "uqrshrn v17.8b, v17.8h, #8 \n" // dg >>= 8 - "uqrshrn v18.8b, v18.8h, #8 \n" // dr >>= 8 - "uqsub v4.8b, v4.8b, v16.8b \n" // db - (db * a / 256) - "uqsub v5.8b, v5.8b, v17.8b \n" // dg - (dg * a / 256) - "uqsub v6.8b, v6.8b, v18.8b \n" // dr - (dr * a / 256) - "uqadd v0.8b, v0.8b, v4.8b \n" // + sb - "uqadd v1.8b, v1.8b, v5.8b \n" // + sg - "uqadd v2.8b, v2.8b, v6.8b \n" // + sr - "movi v3.8b, #255 \n" // a = 255 - "st4 {v0.b,v1.b,v2.b,v3.b}[0], [%2], #4 \n" // store 1 pixel. - "b.ge 1b \n" - - "99: \n" - - : "+r"(src_argb0), // %0 - "+r"(src_argb1), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", - "v17", "v18"); -} - -// Attenuate 8 pixels at a time. -void ARGBAttenuateRow_NEON(const uint8_t* src_argb, - uint8_t* dst_argb, - int width) { - asm volatile( - // Attenuate 8 pixels. - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v4.8h, v0.8b, v3.8b \n" // b * a - "umull v5.8h, v1.8b, v3.8b \n" // g * a - "umull v6.8h, v2.8b, v3.8b \n" // r * a - "uqrshrn v0.8b, v4.8h, #8 \n" // b >>= 8 - "uqrshrn v1.8b, v5.8h, #8 \n" // g >>= 8 - "uqrshrn v2.8b, v6.8h, #8 \n" // r >>= 8 - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n" // store 8 ARGB - // pixels - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6"); -} - -// Quantize 8 ARGB pixels (32 bytes). -// dst = (dst * scale >> 16) * interval_size + interval_offset; -void ARGBQuantizeRow_NEON(uint8_t* dst_argb, - int scale, - int interval_size, - int interval_offset, - int width) { - asm volatile( - "dup v4.8h, %w2 \n" - "ushr v4.8h, v4.8h, #1 \n" // scale >>= 1 - "dup v5.8h, %w3 \n" // interval multiply. - "dup v6.8h, %w4 \n" // interval add - - // 8 pixel loop. - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0] \n" // load 8 ARGB. - "subs %w1, %w1, #8 \n" // 8 processed per loop. - "uxtl v0.8h, v0.8b \n" // b (0 .. 255) - "uxtl v1.8h, v1.8b \n" - "uxtl v2.8h, v2.8b \n" - "sqdmulh v0.8h, v0.8h, v4.8h \n" // b * scale - "sqdmulh v1.8h, v1.8h, v4.8h \n" // g - "sqdmulh v2.8h, v2.8h, v4.8h \n" // r - "mul v0.8h, v0.8h, v5.8h \n" // b * interval_size - "mul v1.8h, v1.8h, v5.8h \n" // g - "mul v2.8h, v2.8h, v5.8h \n" // r - "add v0.8h, v0.8h, v6.8h \n" // b + interval_offset - "add v1.8h, v1.8h, v6.8h \n" // g - "add v2.8h, v2.8h, v6.8h \n" // r - "uqxtn v0.8b, v0.8h \n" - "uqxtn v1.8b, v1.8h \n" - "uqxtn v2.8b, v2.8h \n" - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // store 8 ARGB - "b.gt 1b \n" - : "+r"(dst_argb), // %0 - "+r"(width) // %1 - : "r"(scale), // %2 - "r"(interval_size), // %3 - "r"(interval_offset) // %4 - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6"); -} - -// Shade 8 pixels at a time by specified value. -// NOTE vqrdmulh.s16 q10, q10, d0[0] must use a scaler register from 0 to 8. -// Rounding in vqrdmulh does +1 to high if high bit of low s16 is set. -void ARGBShadeRow_NEON(const uint8_t* src_argb, - uint8_t* dst_argb, - int width, - uint32_t value) { - asm volatile( - "dup v0.4s, %w3 \n" // duplicate scale value. - "zip1 v0.8b, v0.8b, v0.8b \n" // v0.8b aarrggbb. - "ushr v0.8h, v0.8h, #1 \n" // scale / 2. - - // 8 pixel loop. - "1: \n" - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%0], #32 \n" // load 8 ARGB - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "uxtl v4.8h, v4.8b \n" // b (0 .. 255) - "uxtl v5.8h, v5.8b \n" - "uxtl v6.8h, v6.8b \n" - "uxtl v7.8h, v7.8b \n" - "sqrdmulh v4.8h, v4.8h, v0.h[0] \n" // b * scale * 2 - "sqrdmulh v5.8h, v5.8h, v0.h[1] \n" // g - "sqrdmulh v6.8h, v6.8h, v0.h[2] \n" // r - "sqrdmulh v7.8h, v7.8h, v0.h[3] \n" // a - "uqxtn v4.8b, v4.8h \n" - "uqxtn v5.8b, v5.8h \n" - "uqxtn v6.8b, v6.8h \n" - "uqxtn v7.8b, v7.8h \n" - "st4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // store 8 ARGB - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : "r"(value) // %3 - : "cc", "memory", "v0", "v4", "v5", "v6", "v7"); -} - -// Convert 8 ARGB pixels (64 bytes) to 8 Gray ARGB pixels -// Similar to ARGBToYJ but stores ARGB. -// C code is (15 * b + 75 * g + 38 * r + 64) >> 7; -void ARGBGrayRow_NEON(const uint8_t* src_argb, uint8_t* dst_argb, int width) { - asm volatile( - "movi v24.8b, #15 \n" // B * 0.11400 coefficient - "movi v25.8b, #75 \n" // G * 0.58700 coefficient - "movi v26.8b, #38 \n" // R * 0.29900 coefficient - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "umull v4.8h, v0.8b, v24.8b \n" // B - "umlal v4.8h, v1.8b, v25.8b \n" // G - "umlal v4.8h, v2.8b, v26.8b \n" // R - "sqrshrun v0.8b, v4.8h, #7 \n" // 15 bit to 8 bit B - "orr v1.8b, v0.8b, v0.8b \n" // G - "orr v2.8b, v0.8b, v0.8b \n" // R - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%1], #32 \n" // store 8 pixels. - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v24", "v25", "v26"); -} - -// Convert 8 ARGB pixels (32 bytes) to 8 Sepia ARGB pixels. -// b = (r * 35 + g * 68 + b * 17) >> 7 -// g = (r * 45 + g * 88 + b * 22) >> 7 -// r = (r * 50 + g * 98 + b * 24) >> 7 - -void ARGBSepiaRow_NEON(uint8_t* dst_argb, int width) { - asm volatile( - "movi v20.8b, #17 \n" // BB coefficient - "movi v21.8b, #68 \n" // BG coefficient - "movi v22.8b, #35 \n" // BR coefficient - "movi v24.8b, #22 \n" // GB coefficient - "movi v25.8b, #88 \n" // GG coefficient - "movi v26.8b, #45 \n" // GR coefficient - "movi v28.8b, #24 \n" // BB coefficient - "movi v29.8b, #98 \n" // BG coefficient - "movi v30.8b, #50 \n" // BR coefficient - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0] \n" // load 8 ARGB pixels. - "subs %w1, %w1, #8 \n" // 8 processed per loop. - "umull v4.8h, v0.8b, v20.8b \n" // B to Sepia B - "umlal v4.8h, v1.8b, v21.8b \n" // G - "umlal v4.8h, v2.8b, v22.8b \n" // R - "umull v5.8h, v0.8b, v24.8b \n" // B to Sepia G - "umlal v5.8h, v1.8b, v25.8b \n" // G - "umlal v5.8h, v2.8b, v26.8b \n" // R - "umull v6.8h, v0.8b, v28.8b \n" // B to Sepia R - "umlal v6.8h, v1.8b, v29.8b \n" // G - "umlal v6.8h, v2.8b, v30.8b \n" // R - "uqshrn v0.8b, v4.8h, #7 \n" // 16 bit to 8 bit B - "uqshrn v1.8b, v5.8h, #7 \n" // 16 bit to 8 bit G - "uqshrn v2.8b, v6.8h, #7 \n" // 16 bit to 8 bit R - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // store 8 pixels. - "b.gt 1b \n" - : "+r"(dst_argb), // %0 - "+r"(width) // %1 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", - "v21", "v22", "v24", "v25", "v26", "v28", "v29", "v30"); -} - -// Tranform 8 ARGB pixels (32 bytes) with color matrix. -// TODO(fbarchard): Was same as Sepia except matrix is provided. This function -// needs to saturate. Consider doing a non-saturating version. -void ARGBColorMatrixRow_NEON(const uint8_t* src_argb, - uint8_t* dst_argb, - const int8_t* matrix_argb, - int width) { - asm volatile( - "ld1 {v2.16b}, [%3] \n" // load 3 ARGB vectors. - "sxtl v0.8h, v2.8b \n" // B,G coefficients s16. - "sxtl2 v1.8h, v2.16b \n" // R,A coefficients s16. - - "1: \n" - "ld4 {v16.8b,v17.8b,v18.8b,v19.8b}, [%0], #32 \n" // load 8 ARGB - "subs %w2, %w2, #8 \n" // 8 processed per loop. - "uxtl v16.8h, v16.8b \n" // b (0 .. 255) 16 bit - "uxtl v17.8h, v17.8b \n" // g - "uxtl v18.8h, v18.8b \n" // r - "uxtl v19.8h, v19.8b \n" // a - "mul v22.8h, v16.8h, v0.h[0] \n" // B = B * Matrix B - "mul v23.8h, v16.8h, v0.h[4] \n" // G = B * Matrix G - "mul v24.8h, v16.8h, v1.h[0] \n" // R = B * Matrix R - "mul v25.8h, v16.8h, v1.h[4] \n" // A = B * Matrix A - "mul v4.8h, v17.8h, v0.h[1] \n" // B += G * Matrix B - "mul v5.8h, v17.8h, v0.h[5] \n" // G += G * Matrix G - "mul v6.8h, v17.8h, v1.h[1] \n" // R += G * Matrix R - "mul v7.8h, v17.8h, v1.h[5] \n" // A += G * Matrix A - "sqadd v22.8h, v22.8h, v4.8h \n" // Accumulate B - "sqadd v23.8h, v23.8h, v5.8h \n" // Accumulate G - "sqadd v24.8h, v24.8h, v6.8h \n" // Accumulate R - "sqadd v25.8h, v25.8h, v7.8h \n" // Accumulate A - "mul v4.8h, v18.8h, v0.h[2] \n" // B += R * Matrix B - "mul v5.8h, v18.8h, v0.h[6] \n" // G += R * Matrix G - "mul v6.8h, v18.8h, v1.h[2] \n" // R += R * Matrix R - "mul v7.8h, v18.8h, v1.h[6] \n" // A += R * Matrix A - "sqadd v22.8h, v22.8h, v4.8h \n" // Accumulate B - "sqadd v23.8h, v23.8h, v5.8h \n" // Accumulate G - "sqadd v24.8h, v24.8h, v6.8h \n" // Accumulate R - "sqadd v25.8h, v25.8h, v7.8h \n" // Accumulate A - "mul v4.8h, v19.8h, v0.h[3] \n" // B += A * Matrix B - "mul v5.8h, v19.8h, v0.h[7] \n" // G += A * Matrix G - "mul v6.8h, v19.8h, v1.h[3] \n" // R += A * Matrix R - "mul v7.8h, v19.8h, v1.h[7] \n" // A += A * Matrix A - "sqadd v22.8h, v22.8h, v4.8h \n" // Accumulate B - "sqadd v23.8h, v23.8h, v5.8h \n" // Accumulate G - "sqadd v24.8h, v24.8h, v6.8h \n" // Accumulate R - "sqadd v25.8h, v25.8h, v7.8h \n" // Accumulate A - "sqshrun v16.8b, v22.8h, #6 \n" // 16 bit to 8 bit B - "sqshrun v17.8b, v23.8h, #6 \n" // 16 bit to 8 bit G - "sqshrun v18.8b, v24.8h, #6 \n" // 16 bit to 8 bit R - "sqshrun v19.8b, v25.8h, #6 \n" // 16 bit to 8 bit A - "st4 {v16.8b,v17.8b,v18.8b,v19.8b}, [%1], #32 \n" // store 8 ARGB - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(width) // %2 - : "r"(matrix_argb) // %3 - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", - "v17", "v18", "v19", "v22", "v23", "v24", "v25"); -} - -// TODO(fbarchard): fix vqshrun in ARGBMultiplyRow_NEON and reenable. -// Multiply 2 rows of ARGB pixels together, 8 pixels at a time. -void ARGBMultiplyRow_NEON(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - asm volatile( - // 8 pixel loop. - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load 8 more - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "umull v0.8h, v0.8b, v4.8b \n" // multiply B - "umull v1.8h, v1.8b, v5.8b \n" // multiply G - "umull v2.8h, v2.8b, v6.8b \n" // multiply R - "umull v3.8h, v3.8b, v7.8b \n" // multiply A - "rshrn v0.8b, v0.8h, #8 \n" // 16 bit to 8 bit B - "rshrn v1.8b, v1.8h, #8 \n" // 16 bit to 8 bit G - "rshrn v2.8b, v2.8h, #8 \n" // 16 bit to 8 bit R - "rshrn v3.8b, v3.8h, #8 \n" // 16 bit to 8 bit A - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB - "b.gt 1b \n" - : "+r"(src_argb0), // %0 - "+r"(src_argb1), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"); -} - -// Add 2 rows of ARGB pixels together, 8 pixels at a time. -void ARGBAddRow_NEON(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - asm volatile( - // 8 pixel loop. - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load 8 more - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "uqadd v0.8b, v0.8b, v4.8b \n" - "uqadd v1.8b, v1.8b, v5.8b \n" - "uqadd v2.8b, v2.8b, v6.8b \n" - "uqadd v3.8b, v3.8b, v7.8b \n" - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB - "b.gt 1b \n" - : "+r"(src_argb0), // %0 - "+r"(src_argb1), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"); -} - -// Subtract 2 rows of ARGB pixels, 8 pixels at a time. -void ARGBSubtractRow_NEON(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - asm volatile( - // 8 pixel loop. - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // load 8 ARGB - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%1], #32 \n" // load 8 more - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "uqsub v0.8b, v0.8b, v4.8b \n" - "uqsub v1.8b, v1.8b, v5.8b \n" - "uqsub v2.8b, v2.8b, v6.8b \n" - "uqsub v3.8b, v3.8b, v7.8b \n" - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB - "b.gt 1b \n" - : "+r"(src_argb0), // %0 - "+r"(src_argb1), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"); -} - -// Adds Sobel X and Sobel Y and stores Sobel into ARGB. -// A = 255 -// R = Sobel -// G = Sobel -// B = Sobel -void SobelRow_NEON(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width) { - asm volatile( - "movi v3.8b, #255 \n" // alpha - // 8 pixel loop. - "1: \n" - "ld1 {v0.8b}, [%0], #8 \n" // load 8 sobelx. - "ld1 {v1.8b}, [%1], #8 \n" // load 8 sobely. - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "uqadd v0.8b, v0.8b, v1.8b \n" // add - "orr v1.8b, v0.8b, v0.8b \n" - "orr v2.8b, v0.8b, v0.8b \n" - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB - "b.gt 1b \n" - : "+r"(src_sobelx), // %0 - "+r"(src_sobely), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "v0", "v1", "v2", "v3"); -} - -// Adds Sobel X and Sobel Y and stores Sobel into plane. -void SobelToPlaneRow_NEON(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_y, - int width) { - asm volatile( - // 16 pixel loop. - "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load 16 sobelx. - "ld1 {v1.16b}, [%1], #16 \n" // load 16 sobely. - "subs %w3, %w3, #16 \n" // 16 processed per loop. - "uqadd v0.16b, v0.16b, v1.16b \n" // add - "st1 {v0.16b}, [%2], #16 \n" // store 16 pixels. - "b.gt 1b \n" - : "+r"(src_sobelx), // %0 - "+r"(src_sobely), // %1 - "+r"(dst_y), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "v0", "v1"); -} - -// Mixes Sobel X, Sobel Y and Sobel into ARGB. -// A = 255 -// R = Sobel X -// G = Sobel -// B = Sobel Y -void SobelXYRow_NEON(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width) { - asm volatile( - "movi v3.8b, #255 \n" // alpha - // 8 pixel loop. - "1: \n" - "ld1 {v2.8b}, [%0], #8 \n" // load 8 sobelx. - "ld1 {v0.8b}, [%1], #8 \n" // load 8 sobely. - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "uqadd v1.8b, v0.8b, v2.8b \n" // add - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" // store 8 ARGB - "b.gt 1b \n" - : "+r"(src_sobelx), // %0 - "+r"(src_sobely), // %1 - "+r"(dst_argb), // %2 - "+r"(width) // %3 - : - : "cc", "memory", "v0", "v1", "v2", "v3"); -} - -// SobelX as a matrix is -// -1 0 1 -// -2 0 2 -// -1 0 1 -void SobelXRow_NEON(const uint8_t* src_y0, - const uint8_t* src_y1, - const uint8_t* src_y2, - uint8_t* dst_sobelx, - int width) { - asm volatile( - "1: \n" - "ld1 {v0.8b}, [%0],%5 \n" // top - "ld1 {v1.8b}, [%0],%6 \n" - "usubl v0.8h, v0.8b, v1.8b \n" - "ld1 {v2.8b}, [%1],%5 \n" // center * 2 - "ld1 {v3.8b}, [%1],%6 \n" - "usubl v1.8h, v2.8b, v3.8b \n" - "add v0.8h, v0.8h, v1.8h \n" - "add v0.8h, v0.8h, v1.8h \n" - "ld1 {v2.8b}, [%2],%5 \n" // bottom - "ld1 {v3.8b}, [%2],%6 \n" - "subs %w4, %w4, #8 \n" // 8 pixels - "usubl v1.8h, v2.8b, v3.8b \n" - "add v0.8h, v0.8h, v1.8h \n" - "abs v0.8h, v0.8h \n" - "uqxtn v0.8b, v0.8h \n" - "st1 {v0.8b}, [%3], #8 \n" // store 8 sobelx - "b.gt 1b \n" - : "+r"(src_y0), // %0 - "+r"(src_y1), // %1 - "+r"(src_y2), // %2 - "+r"(dst_sobelx), // %3 - "+r"(width) // %4 - : "r"(2LL), // %5 - "r"(6LL) // %6 - : "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List - ); -} - -// SobelY as a matrix is -// -1 -2 -1 -// 0 0 0 -// 1 2 1 -void SobelYRow_NEON(const uint8_t* src_y0, - const uint8_t* src_y1, - uint8_t* dst_sobely, - int width) { - asm volatile( - "1: \n" - "ld1 {v0.8b}, [%0],%4 \n" // left - "ld1 {v1.8b}, [%1],%4 \n" - "usubl v0.8h, v0.8b, v1.8b \n" - "ld1 {v2.8b}, [%0],%4 \n" // center * 2 - "ld1 {v3.8b}, [%1],%4 \n" - "usubl v1.8h, v2.8b, v3.8b \n" - "add v0.8h, v0.8h, v1.8h \n" - "add v0.8h, v0.8h, v1.8h \n" - "ld1 {v2.8b}, [%0],%5 \n" // right - "ld1 {v3.8b}, [%1],%5 \n" - "subs %w3, %w3, #8 \n" // 8 pixels - "usubl v1.8h, v2.8b, v3.8b \n" - "add v0.8h, v0.8h, v1.8h \n" - "abs v0.8h, v0.8h \n" - "uqxtn v0.8b, v0.8h \n" - "st1 {v0.8b}, [%2], #8 \n" // store 8 sobely - "b.gt 1b \n" - : "+r"(src_y0), // %0 - "+r"(src_y1), // %1 - "+r"(dst_sobely), // %2 - "+r"(width) // %3 - : "r"(1LL), // %4 - "r"(6LL) // %5 - : "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List - ); -} - -// Caveat - rounds float to half float whereas scaling version truncates. -void HalfFloat1Row_NEON(const uint16_t* src, - uint16_t* dst, - float /*unused*/, - int width) { - asm volatile( - "1: \n" - "ld1 {v1.16b}, [%0], #16 \n" // load 8 shorts - "subs %w2, %w2, #8 \n" // 8 pixels per loop - "uxtl v2.4s, v1.4h \n" // 8 int's - "uxtl2 v3.4s, v1.8h \n" - "scvtf v2.4s, v2.4s \n" // 8 floats - "scvtf v3.4s, v3.4s \n" - "fcvtn v1.4h, v2.4s \n" // 8 half floats - "fcvtn2 v1.8h, v3.4s \n" - "st1 {v1.16b}, [%1], #16 \n" // store 8 shorts - "b.gt 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : - : "cc", "memory", "v1", "v2", "v3"); -} - -void HalfFloatRow_NEON(const uint16_t* src, - uint16_t* dst, - float scale, - int width) { - asm volatile( - "1: \n" - "ld1 {v1.16b}, [%0], #16 \n" // load 8 shorts - "subs %w2, %w2, #8 \n" // 8 pixels per loop - "uxtl v2.4s, v1.4h \n" // 8 int's - "uxtl2 v3.4s, v1.8h \n" - "scvtf v2.4s, v2.4s \n" // 8 floats - "scvtf v3.4s, v3.4s \n" - "fmul v2.4s, v2.4s, %3.s[0] \n" // adjust exponent - "fmul v3.4s, v3.4s, %3.s[0] \n" - "uqshrn v1.4h, v2.4s, #13 \n" // isolate halffloat - "uqshrn2 v1.8h, v3.4s, #13 \n" - "st1 {v1.16b}, [%1], #16 \n" // store 8 shorts - "b.gt 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "w"(scale * 1.9259299444e-34f) // %3 - : "cc", "memory", "v1", "v2", "v3"); -} - -void ByteToFloatRow_NEON(const uint8_t* src, - float* dst, - float scale, - int width) { - asm volatile( - "1: \n" - "ld1 {v1.8b}, [%0], #8 \n" // load 8 bytes - "subs %w2, %w2, #8 \n" // 8 pixels per loop - "uxtl v1.8h, v1.8b \n" // 8 shorts - "uxtl v2.4s, v1.4h \n" // 8 ints - "uxtl2 v3.4s, v1.8h \n" - "scvtf v2.4s, v2.4s \n" // 8 floats - "scvtf v3.4s, v3.4s \n" - "fmul v2.4s, v2.4s, %3.s[0] \n" // scale - "fmul v3.4s, v3.4s, %3.s[0] \n" - "st1 {v2.16b, v3.16b}, [%1], #32 \n" // store 8 floats - "b.gt 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "w"(scale) // %3 - : "cc", "memory", "v1", "v2", "v3"); -} - -float ScaleMaxSamples_NEON(const float* src, - float* dst, - float scale, - int width) { - float fmax; - asm volatile( - "movi v5.4s, #0 \n" // max - "movi v6.4s, #0 \n" - - "1: \n" - "ld1 {v1.4s, v2.4s}, [%0], #32 \n" // load 8 samples - "subs %w2, %w2, #8 \n" // 8 processed per loop - "fmul v3.4s, v1.4s, %4.s[0] \n" // scale - "fmul v4.4s, v2.4s, %4.s[0] \n" // scale - "fmax v5.4s, v5.4s, v1.4s \n" // max - "fmax v6.4s, v6.4s, v2.4s \n" - "st1 {v3.4s, v4.4s}, [%1], #32 \n" // store 8 samples - "b.gt 1b \n" - "fmax v5.4s, v5.4s, v6.4s \n" // max - "fmaxv %s3, v5.4s \n" // signed max acculator - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width), // %2 - "=w"(fmax) // %3 - : "w"(scale) // %4 - : "cc", "memory", "v1", "v2", "v3", "v4", "v5", "v6"); - return fmax; -} - -float ScaleSumSamples_NEON(const float* src, - float* dst, - float scale, - int width) { - float fsum; - asm volatile( - "movi v5.4s, #0 \n" // max - "movi v6.4s, #0 \n" // max - - "1: \n" - "ld1 {v1.4s, v2.4s}, [%0], #32 \n" // load 8 samples - "subs %w2, %w2, #8 \n" // 8 processed per loop - "fmul v3.4s, v1.4s, %4.s[0] \n" // scale - "fmul v4.4s, v2.4s, %4.s[0] \n" - "fmla v5.4s, v1.4s, v1.4s \n" // sum of squares - "fmla v6.4s, v2.4s, v2.4s \n" - "st1 {v3.4s, v4.4s}, [%1], #32 \n" // store 8 samples - "b.gt 1b \n" - "faddp v5.4s, v5.4s, v6.4s \n" - "faddp v5.4s, v5.4s, v5.4s \n" - "faddp %3.4s, v5.4s, v5.4s \n" // sum - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width), // %2 - "=w"(fsum) // %3 - : "w"(scale) // %4 - : "cc", "memory", "v1", "v2", "v3", "v4", "v5", "v6"); - return fsum; -} - -void ScaleSamples_NEON(const float* src, float* dst, float scale, int width) { - asm volatile( - "1: \n" - "ld1 {v1.4s, v2.4s}, [%0], #32 \n" // load 8 samples - "subs %w2, %w2, #8 \n" // 8 processed per loop - "fmul v1.4s, v1.4s, %3.s[0] \n" // scale - "fmul v2.4s, v2.4s, %3.s[0] \n" // scale - "st1 {v1.4s, v2.4s}, [%1], #32 \n" // store 8 samples - "b.gt 1b \n" - : "+r"(src), // %0 - "+r"(dst), // %1 - "+r"(width) // %2 - : "w"(scale) // %3 - : "cc", "memory", "v1", "v2"); -} - -// filter 5 rows with 1, 4, 6, 4, 1 coefficients to produce 1 row. -void GaussCol_NEON(const uint16_t* src0, - const uint16_t* src1, - const uint16_t* src2, - const uint16_t* src3, - const uint16_t* src4, - uint32_t* dst, - int width) { - asm volatile( - "movi v6.8h, #4 \n" // constant 4 - "movi v7.8h, #6 \n" // constant 6 - - "1: \n" - "ld1 {v1.8h}, [%0], #16 \n" // load 8 samples, 5 rows - "ld1 {v2.8h}, [%4], #16 \n" - "uaddl v0.4s, v1.4h, v2.4h \n" // * 1 - "uaddl2 v1.4s, v1.8h, v2.8h \n" // * 1 - "ld1 {v2.8h}, [%1], #16 \n" - "umlal v0.4s, v2.4h, v6.4h \n" // * 4 - "umlal2 v1.4s, v2.8h, v6.8h \n" // * 4 - "ld1 {v2.8h}, [%2], #16 \n" - "umlal v0.4s, v2.4h, v7.4h \n" // * 6 - "umlal2 v1.4s, v2.8h, v7.8h \n" // * 6 - "ld1 {v2.8h}, [%3], #16 \n" - "umlal v0.4s, v2.4h, v6.4h \n" // * 4 - "umlal2 v1.4s, v2.8h, v6.8h \n" // * 4 - "subs %w6, %w6, #8 \n" // 8 processed per loop - "st1 {v0.4s,v1.4s}, [%5], #32 \n" // store 8 samples - "b.gt 1b \n" - : "+r"(src0), // %0 - "+r"(src1), // %1 - "+r"(src2), // %2 - "+r"(src3), // %3 - "+r"(src4), // %4 - "+r"(dst), // %5 - "+r"(width) // %6 - : - : "cc", "memory", "v0", "v1", "v2", "v6", "v7"); -} - -// filter 5 rows with 1, 4, 6, 4, 1 coefficients to produce 1 row. -void GaussRow_NEON(const uint32_t* src, uint16_t* dst, int width) { - const uint32_t* src1 = src + 1; - const uint32_t* src2 = src + 2; - const uint32_t* src3 = src + 3; - asm volatile( - "movi v6.4s, #4 \n" // constant 4 - "movi v7.4s, #6 \n" // constant 6 - - "1: \n" - "ld1 {v0.4s,v1.4s,v2.4s}, [%0], %6 \n" // load 12 source samples - "add v0.4s, v0.4s, v1.4s \n" // * 1 - "add v1.4s, v1.4s, v2.4s \n" // * 1 - "ld1 {v2.4s,v3.4s}, [%2], #32 \n" - "mla v0.4s, v2.4s, v7.4s \n" // * 6 - "mla v1.4s, v3.4s, v7.4s \n" // * 6 - "ld1 {v2.4s,v3.4s}, [%1], #32 \n" - "ld1 {v4.4s,v5.4s}, [%3], #32 \n" - "add v2.4s, v2.4s, v4.4s \n" // add rows for * 4 - "add v3.4s, v3.4s, v5.4s \n" - "mla v0.4s, v2.4s, v6.4s \n" // * 4 - "mla v1.4s, v3.4s, v6.4s \n" // * 4 - "subs %w5, %w5, #8 \n" // 8 processed per loop - "uqrshrn v0.4h, v0.4s, #8 \n" // round and pack - "uqrshrn2 v0.8h, v1.4s, #8 \n" - "st1 {v0.8h}, [%4], #16 \n" // store 8 samples - "b.gt 1b \n" - : "+r"(src), // %0 - "+r"(src1), // %1 - "+r"(src2), // %2 - "+r"(src3), // %3 - "+r"(dst), // %4 - "+r"(width) // %5 - : "r"(32LL) // %6 - : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"); -} - -#endif // !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_win.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_win.cc deleted file mode 100644 index 5500d7f5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/row_win.cc +++ /dev/null @@ -1,6234 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/row.h" - -// This module is for Visual C 32/64 bit and clangcl 32 bit -#if !defined(LIBYUV_DISABLE_X86) && defined(_MSC_VER) && \ - (defined(_M_IX86) || (defined(_M_X64) && !defined(__clang__))) - -#if defined(_M_X64) -#include -#include // For _mm_maddubs_epi16 -#endif - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// 64 bit -#if defined(_M_X64) - -// Read 4 UV from 422, upsample to 8 UV. -#define READYUV422 \ - xmm0 = _mm_cvtsi32_si128(*(uint32_t*)u_buf); \ - xmm1 = _mm_cvtsi32_si128(*(uint32_t*)(u_buf + offset)); \ - xmm0 = _mm_unpacklo_epi8(xmm0, xmm1); \ - xmm0 = _mm_unpacklo_epi16(xmm0, xmm0); \ - u_buf += 4; \ - xmm4 = _mm_loadl_epi64((__m128i*)y_buf); \ - xmm4 = _mm_unpacklo_epi8(xmm4, xmm4); \ - y_buf += 8; - -// Read 4 UV from 422, upsample to 8 UV. With 8 Alpha. -#define READYUVA422 \ - xmm0 = _mm_cvtsi32_si128(*(uint32_t*)u_buf); \ - xmm1 = _mm_cvtsi32_si128(*(uint32_t*)(u_buf + offset)); \ - xmm0 = _mm_unpacklo_epi8(xmm0, xmm1); \ - xmm0 = _mm_unpacklo_epi16(xmm0, xmm0); \ - u_buf += 4; \ - xmm4 = _mm_loadl_epi64((__m128i*)y_buf); \ - xmm4 = _mm_unpacklo_epi8(xmm4, xmm4); \ - y_buf += 8; \ - xmm5 = _mm_loadl_epi64((__m128i*)a_buf); \ - a_buf += 8; - -// Convert 8 pixels: 8 UV and 8 Y. -#define YUVTORGB(yuvconstants) \ - xmm1 = _mm_loadu_si128(&xmm0); \ - xmm2 = _mm_loadu_si128(&xmm0); \ - xmm0 = _mm_maddubs_epi16(xmm0, *(__m128i*)yuvconstants->kUVToB); \ - xmm1 = _mm_maddubs_epi16(xmm1, *(__m128i*)yuvconstants->kUVToG); \ - xmm2 = _mm_maddubs_epi16(xmm2, *(__m128i*)yuvconstants->kUVToR); \ - xmm0 = _mm_sub_epi16(*(__m128i*)yuvconstants->kUVBiasB, xmm0); \ - xmm1 = _mm_sub_epi16(*(__m128i*)yuvconstants->kUVBiasG, xmm1); \ - xmm2 = _mm_sub_epi16(*(__m128i*)yuvconstants->kUVBiasR, xmm2); \ - xmm4 = _mm_mulhi_epu16(xmm4, *(__m128i*)yuvconstants->kYToRgb); \ - xmm0 = _mm_adds_epi16(xmm0, xmm4); \ - xmm1 = _mm_adds_epi16(xmm1, xmm4); \ - xmm2 = _mm_adds_epi16(xmm2, xmm4); \ - xmm0 = _mm_srai_epi16(xmm0, 6); \ - xmm1 = _mm_srai_epi16(xmm1, 6); \ - xmm2 = _mm_srai_epi16(xmm2, 6); \ - xmm0 = _mm_packus_epi16(xmm0, xmm0); \ - xmm1 = _mm_packus_epi16(xmm1, xmm1); \ - xmm2 = _mm_packus_epi16(xmm2, xmm2); - -// Store 8 ARGB values. -#define STOREARGB \ - xmm0 = _mm_unpacklo_epi8(xmm0, xmm1); \ - xmm2 = _mm_unpacklo_epi8(xmm2, xmm5); \ - xmm1 = _mm_loadu_si128(&xmm0); \ - xmm0 = _mm_unpacklo_epi16(xmm0, xmm2); \ - xmm1 = _mm_unpackhi_epi16(xmm1, xmm2); \ - _mm_storeu_si128((__m128i*)dst_argb, xmm0); \ - _mm_storeu_si128((__m128i*)(dst_argb + 16), xmm1); \ - dst_argb += 32; - -#if defined(HAS_I422TOARGBROW_SSSE3) -void I422ToARGBRow_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - __m128i xmm0, xmm1, xmm2, xmm4; - const __m128i xmm5 = _mm_set1_epi8(-1); - const ptrdiff_t offset = (uint8_t*)v_buf - (uint8_t*)u_buf; - while (width > 0) { - READYUV422 - YUVTORGB(yuvconstants) - STOREARGB - width -= 8; - } -} -#endif - -#if defined(HAS_I422ALPHATOARGBROW_SSSE3) -void I422AlphaToARGBRow_SSSE3(const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - const uint8_t* a_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - __m128i xmm0, xmm1, xmm2, xmm4, xmm5; - const ptrdiff_t offset = (uint8_t*)v_buf - (uint8_t*)u_buf; - while (width > 0) { - READYUVA422 - YUVTORGB(yuvconstants) - STOREARGB - width -= 8; - } -} -#endif - -// 32 bit -#else // defined(_M_X64) -#ifdef HAS_ARGBTOYROW_SSSE3 - -// Constants for ARGB. -static const vec8 kARGBToY = {13, 65, 33, 0, 13, 65, 33, 0, - 13, 65, 33, 0, 13, 65, 33, 0}; - -// JPeg full range. -static const vec8 kARGBToYJ = {15, 75, 38, 0, 15, 75, 38, 0, - 15, 75, 38, 0, 15, 75, 38, 0}; - -static const vec8 kARGBToU = {112, -74, -38, 0, 112, -74, -38, 0, - 112, -74, -38, 0, 112, -74, -38, 0}; - -static const vec8 kARGBToUJ = {127, -84, -43, 0, 127, -84, -43, 0, - 127, -84, -43, 0, 127, -84, -43, 0}; - -static const vec8 kARGBToV = { - -18, -94, 112, 0, -18, -94, 112, 0, -18, -94, 112, 0, -18, -94, 112, 0, -}; - -static const vec8 kARGBToVJ = {-20, -107, 127, 0, -20, -107, 127, 0, - -20, -107, 127, 0, -20, -107, 127, 0}; - -// vpshufb for vphaddw + vpackuswb packed to shorts. -static const lvec8 kShufARGBToUV_AVX = { - 0, 1, 8, 9, 2, 3, 10, 11, 4, 5, 12, 13, 6, 7, 14, 15, - 0, 1, 8, 9, 2, 3, 10, 11, 4, 5, 12, 13, 6, 7, 14, 15}; - -// Constants for BGRA. -static const vec8 kBGRAToY = {0, 33, 65, 13, 0, 33, 65, 13, - 0, 33, 65, 13, 0, 33, 65, 13}; - -static const vec8 kBGRAToU = {0, -38, -74, 112, 0, -38, -74, 112, - 0, -38, -74, 112, 0, -38, -74, 112}; - -static const vec8 kBGRAToV = {0, 112, -94, -18, 0, 112, -94, -18, - 0, 112, -94, -18, 0, 112, -94, -18}; - -// Constants for ABGR. -static const vec8 kABGRToY = {33, 65, 13, 0, 33, 65, 13, 0, - 33, 65, 13, 0, 33, 65, 13, 0}; - -static const vec8 kABGRToU = {-38, -74, 112, 0, -38, -74, 112, 0, - -38, -74, 112, 0, -38, -74, 112, 0}; - -static const vec8 kABGRToV = {112, -94, -18, 0, 112, -94, -18, 0, - 112, -94, -18, 0, 112, -94, -18, 0}; - -// Constants for RGBA. -static const vec8 kRGBAToY = {0, 13, 65, 33, 0, 13, 65, 33, - 0, 13, 65, 33, 0, 13, 65, 33}; - -static const vec8 kRGBAToU = {0, 112, -74, -38, 0, 112, -74, -38, - 0, 112, -74, -38, 0, 112, -74, -38}; - -static const vec8 kRGBAToV = {0, -18, -94, 112, 0, -18, -94, 112, - 0, -18, -94, 112, 0, -18, -94, 112}; - -static const uvec8 kAddY16 = {16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u, - 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u}; - -// 7 bit fixed point 0.5. -static const vec16 kAddYJ64 = {64, 64, 64, 64, 64, 64, 64, 64}; - -static const uvec8 kAddUV128 = {128u, 128u, 128u, 128u, 128u, 128u, 128u, 128u, - 128u, 128u, 128u, 128u, 128u, 128u, 128u, 128u}; - -static const uvec16 kAddUVJ128 = {0x8080u, 0x8080u, 0x8080u, 0x8080u, - 0x8080u, 0x8080u, 0x8080u, 0x8080u}; - -// Shuffle table for converting RGB24 to ARGB. -static const uvec8 kShuffleMaskRGB24ToARGB = { - 0u, 1u, 2u, 12u, 3u, 4u, 5u, 13u, 6u, 7u, 8u, 14u, 9u, 10u, 11u, 15u}; - -// Shuffle table for converting RAW to ARGB. -static const uvec8 kShuffleMaskRAWToARGB = {2u, 1u, 0u, 12u, 5u, 4u, 3u, 13u, - 8u, 7u, 6u, 14u, 11u, 10u, 9u, 15u}; - -// Shuffle table for converting RAW to RGB24. First 8. -static const uvec8 kShuffleMaskRAWToRGB24_0 = { - 2u, 1u, 0u, 5u, 4u, 3u, 8u, 7u, - 128u, 128u, 128u, 128u, 128u, 128u, 128u, 128u}; - -// Shuffle table for converting RAW to RGB24. Middle 8. -static const uvec8 kShuffleMaskRAWToRGB24_1 = { - 2u, 7u, 6u, 5u, 10u, 9u, 8u, 13u, - 128u, 128u, 128u, 128u, 128u, 128u, 128u, 128u}; - -// Shuffle table for converting RAW to RGB24. Last 8. -static const uvec8 kShuffleMaskRAWToRGB24_2 = { - 8u, 7u, 12u, 11u, 10u, 15u, 14u, 13u, - 128u, 128u, 128u, 128u, 128u, 128u, 128u, 128u}; - -// Shuffle table for converting ARGB to RGB24. -static const uvec8 kShuffleMaskARGBToRGB24 = { - 0u, 1u, 2u, 4u, 5u, 6u, 8u, 9u, 10u, 12u, 13u, 14u, 128u, 128u, 128u, 128u}; - -// Shuffle table for converting ARGB to RAW. -static const uvec8 kShuffleMaskARGBToRAW = { - 2u, 1u, 0u, 6u, 5u, 4u, 10u, 9u, 8u, 14u, 13u, 12u, 128u, 128u, 128u, 128u}; - -// Shuffle table for converting ARGBToRGB24 for I422ToRGB24. First 8 + next 4 -static const uvec8 kShuffleMaskARGBToRGB24_0 = { - 0u, 1u, 2u, 4u, 5u, 6u, 8u, 9u, 128u, 128u, 128u, 128u, 10u, 12u, 13u, 14u}; - -// YUY2 shuf 16 Y to 32 Y. -static const lvec8 kShuffleYUY2Y = {0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, - 10, 12, 12, 14, 14, 0, 0, 2, 2, 4, 4, - 6, 6, 8, 8, 10, 10, 12, 12, 14, 14}; - -// YUY2 shuf 8 UV to 16 UV. -static const lvec8 kShuffleYUY2UV = {1, 3, 1, 3, 5, 7, 5, 7, 9, 11, 9, - 11, 13, 15, 13, 15, 1, 3, 1, 3, 5, 7, - 5, 7, 9, 11, 9, 11, 13, 15, 13, 15}; - -// UYVY shuf 16 Y to 32 Y. -static const lvec8 kShuffleUYVYY = {1, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11, - 11, 13, 13, 15, 15, 1, 1, 3, 3, 5, 5, - 7, 7, 9, 9, 11, 11, 13, 13, 15, 15}; - -// UYVY shuf 8 UV to 16 UV. -static const lvec8 kShuffleUYVYUV = {0, 2, 0, 2, 4, 6, 4, 6, 8, 10, 8, - 10, 12, 14, 12, 14, 0, 2, 0, 2, 4, 6, - 4, 6, 8, 10, 8, 10, 12, 14, 12, 14}; - -// NV21 shuf 8 VU to 16 UV. -static const lvec8 kShuffleNV21 = { - 1, 0, 1, 0, 3, 2, 3, 2, 5, 4, 5, 4, 7, 6, 7, 6, - 1, 0, 1, 0, 3, 2, 3, 2, 5, 4, 5, 4, 7, 6, 7, 6, -}; - -// Duplicates gray value 3 times and fills in alpha opaque. -__declspec(naked) void J400ToARGBRow_SSE2(const uint8_t* src_y, - uint8_t* dst_argb, - int width) { - __asm { - mov eax, [esp + 4] // src_y - mov edx, [esp + 8] // dst_argb - mov ecx, [esp + 12] // width - pcmpeqb xmm5, xmm5 // generate mask 0xff000000 - pslld xmm5, 24 - - convertloop: - movq xmm0, qword ptr [eax] - lea eax, [eax + 8] - punpcklbw xmm0, xmm0 - movdqa xmm1, xmm0 - punpcklwd xmm0, xmm0 - punpckhwd xmm1, xmm1 - por xmm0, xmm5 - por xmm1, xmm5 - movdqu [edx], xmm0 - movdqu [edx + 16], xmm1 - lea edx, [edx + 32] - sub ecx, 8 - jg convertloop - ret - } -} - -#ifdef HAS_J400TOARGBROW_AVX2 -// Duplicates gray value 3 times and fills in alpha opaque. -__declspec(naked) void J400ToARGBRow_AVX2(const uint8_t* src_y, - uint8_t* dst_argb, - int width) { - __asm { - mov eax, [esp + 4] // src_y - mov edx, [esp + 8] // dst_argb - mov ecx, [esp + 12] // width - vpcmpeqb ymm5, ymm5, ymm5 // generate mask 0xff000000 - vpslld ymm5, ymm5, 24 - - convertloop: - vmovdqu xmm0, [eax] - lea eax, [eax + 16] - vpermq ymm0, ymm0, 0xd8 - vpunpcklbw ymm0, ymm0, ymm0 - vpermq ymm0, ymm0, 0xd8 - vpunpckhwd ymm1, ymm0, ymm0 - vpunpcklwd ymm0, ymm0, ymm0 - vpor ymm0, ymm0, ymm5 - vpor ymm1, ymm1, ymm5 - vmovdqu [edx], ymm0 - vmovdqu [edx + 32], ymm1 - lea edx, [edx + 64] - sub ecx, 16 - jg convertloop - vzeroupper - ret - } -} -#endif // HAS_J400TOARGBROW_AVX2 - -__declspec(naked) void RGB24ToARGBRow_SSSE3(const uint8_t* src_rgb24, - uint8_t* dst_argb, - int width) { - __asm { - mov eax, [esp + 4] // src_rgb24 - mov edx, [esp + 8] // dst_argb - mov ecx, [esp + 12] // width - pcmpeqb xmm5, xmm5 // generate mask 0xff000000 - pslld xmm5, 24 - movdqa xmm4, xmmword ptr kShuffleMaskRGB24ToARGB - - convertloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - movdqu xmm3, [eax + 32] - lea eax, [eax + 48] - movdqa xmm2, xmm3 - palignr xmm2, xmm1, 8 // xmm2 = { xmm3[0:3] xmm1[8:15]} - pshufb xmm2, xmm4 - por xmm2, xmm5 - palignr xmm1, xmm0, 12 // xmm1 = { xmm3[0:7] xmm0[12:15]} - pshufb xmm0, xmm4 - movdqu [edx + 32], xmm2 - por xmm0, xmm5 - pshufb xmm1, xmm4 - movdqu [edx], xmm0 - por xmm1, xmm5 - palignr xmm3, xmm3, 4 // xmm3 = { xmm3[4:15]} - pshufb xmm3, xmm4 - movdqu [edx + 16], xmm1 - por xmm3, xmm5 - movdqu [edx + 48], xmm3 - lea edx, [edx + 64] - sub ecx, 16 - jg convertloop - ret - } -} - -__declspec(naked) void RAWToARGBRow_SSSE3(const uint8_t* src_raw, - uint8_t* dst_argb, - int width) { - __asm { - mov eax, [esp + 4] // src_raw - mov edx, [esp + 8] // dst_argb - mov ecx, [esp + 12] // width - pcmpeqb xmm5, xmm5 // generate mask 0xff000000 - pslld xmm5, 24 - movdqa xmm4, xmmword ptr kShuffleMaskRAWToARGB - - convertloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - movdqu xmm3, [eax + 32] - lea eax, [eax + 48] - movdqa xmm2, xmm3 - palignr xmm2, xmm1, 8 // xmm2 = { xmm3[0:3] xmm1[8:15]} - pshufb xmm2, xmm4 - por xmm2, xmm5 - palignr xmm1, xmm0, 12 // xmm1 = { xmm3[0:7] xmm0[12:15]} - pshufb xmm0, xmm4 - movdqu [edx + 32], xmm2 - por xmm0, xmm5 - pshufb xmm1, xmm4 - movdqu [edx], xmm0 - por xmm1, xmm5 - palignr xmm3, xmm3, 4 // xmm3 = { xmm3[4:15]} - pshufb xmm3, xmm4 - movdqu [edx + 16], xmm1 - por xmm3, xmm5 - movdqu [edx + 48], xmm3 - lea edx, [edx + 64] - sub ecx, 16 - jg convertloop - ret - } -} - -__declspec(naked) void RAWToRGB24Row_SSSE3(const uint8_t* src_raw, - uint8_t* dst_rgb24, - int width) { - __asm { - mov eax, [esp + 4] // src_raw - mov edx, [esp + 8] // dst_rgb24 - mov ecx, [esp + 12] // width - movdqa xmm3, xmmword ptr kShuffleMaskRAWToRGB24_0 - movdqa xmm4, xmmword ptr kShuffleMaskRAWToRGB24_1 - movdqa xmm5, xmmword ptr kShuffleMaskRAWToRGB24_2 - - convertloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 4] - movdqu xmm2, [eax + 8] - lea eax, [eax + 24] - pshufb xmm0, xmm3 - pshufb xmm1, xmm4 - pshufb xmm2, xmm5 - movq qword ptr [edx], xmm0 - movq qword ptr [edx + 8], xmm1 - movq qword ptr [edx + 16], xmm2 - lea edx, [edx + 24] - sub ecx, 8 - jg convertloop - ret - } -} - -// pmul method to replicate bits. -// Math to replicate bits: -// (v << 8) | (v << 3) -// v * 256 + v * 8 -// v * (256 + 8) -// G shift of 5 is incorporated, so shift is 5 + 8 and 5 + 3 -// 20 instructions. -__declspec(naked) void RGB565ToARGBRow_SSE2(const uint8_t* src_rgb565, - uint8_t* dst_argb, - int width) { - __asm { - mov eax, 0x01080108 // generate multiplier to repeat 5 bits - movd xmm5, eax - pshufd xmm5, xmm5, 0 - mov eax, 0x20802080 // multiplier shift by 5 and then repeat 6 bits - movd xmm6, eax - pshufd xmm6, xmm6, 0 - pcmpeqb xmm3, xmm3 // generate mask 0xf800f800 for Red - psllw xmm3, 11 - pcmpeqb xmm4, xmm4 // generate mask 0x07e007e0 for Green - psllw xmm4, 10 - psrlw xmm4, 5 - pcmpeqb xmm7, xmm7 // generate mask 0xff00ff00 for Alpha - psllw xmm7, 8 - - mov eax, [esp + 4] // src_rgb565 - mov edx, [esp + 8] // dst_argb - mov ecx, [esp + 12] // width - sub edx, eax - sub edx, eax - - convertloop: - movdqu xmm0, [eax] // fetch 8 pixels of bgr565 - movdqa xmm1, xmm0 - movdqa xmm2, xmm0 - pand xmm1, xmm3 // R in upper 5 bits - psllw xmm2, 11 // B in upper 5 bits - pmulhuw xmm1, xmm5 // * (256 + 8) - pmulhuw xmm2, xmm5 // * (256 + 8) - psllw xmm1, 8 - por xmm1, xmm2 // RB - pand xmm0, xmm4 // G in middle 6 bits - pmulhuw xmm0, xmm6 // << 5 * (256 + 4) - por xmm0, xmm7 // AG - movdqa xmm2, xmm1 - punpcklbw xmm1, xmm0 - punpckhbw xmm2, xmm0 - movdqu [eax * 2 + edx], xmm1 // store 4 pixels of ARGB - movdqu [eax * 2 + edx + 16], xmm2 // store next 4 pixels of ARGB - lea eax, [eax + 16] - sub ecx, 8 - jg convertloop - ret - } -} - -#ifdef HAS_RGB565TOARGBROW_AVX2 -// pmul method to replicate bits. -// Math to replicate bits: -// (v << 8) | (v << 3) -// v * 256 + v * 8 -// v * (256 + 8) -// G shift of 5 is incorporated, so shift is 5 + 8 and 5 + 3 -__declspec(naked) void RGB565ToARGBRow_AVX2(const uint8_t* src_rgb565, - uint8_t* dst_argb, - int width) { - __asm { - mov eax, 0x01080108 // generate multiplier to repeat 5 bits - vmovd xmm5, eax - vbroadcastss ymm5, xmm5 - mov eax, 0x20802080 // multiplier shift by 5 and then repeat 6 bits - vmovd xmm6, eax - vbroadcastss ymm6, xmm6 - vpcmpeqb ymm3, ymm3, ymm3 // generate mask 0xf800f800 for Red - vpsllw ymm3, ymm3, 11 - vpcmpeqb ymm4, ymm4, ymm4 // generate mask 0x07e007e0 for Green - vpsllw ymm4, ymm4, 10 - vpsrlw ymm4, ymm4, 5 - vpcmpeqb ymm7, ymm7, ymm7 // generate mask 0xff00ff00 for Alpha - vpsllw ymm7, ymm7, 8 - - mov eax, [esp + 4] // src_rgb565 - mov edx, [esp + 8] // dst_argb - mov ecx, [esp + 12] // width - sub edx, eax - sub edx, eax - - convertloop: - vmovdqu ymm0, [eax] // fetch 16 pixels of bgr565 - vpand ymm1, ymm0, ymm3 // R in upper 5 bits - vpsllw ymm2, ymm0, 11 // B in upper 5 bits - vpmulhuw ymm1, ymm1, ymm5 // * (256 + 8) - vpmulhuw ymm2, ymm2, ymm5 // * (256 + 8) - vpsllw ymm1, ymm1, 8 - vpor ymm1, ymm1, ymm2 // RB - vpand ymm0, ymm0, ymm4 // G in middle 6 bits - vpmulhuw ymm0, ymm0, ymm6 // << 5 * (256 + 4) - vpor ymm0, ymm0, ymm7 // AG - vpermq ymm0, ymm0, 0xd8 // mutate for unpack - vpermq ymm1, ymm1, 0xd8 - vpunpckhbw ymm2, ymm1, ymm0 - vpunpcklbw ymm1, ymm1, ymm0 - vmovdqu [eax * 2 + edx], ymm1 // store 4 pixels of ARGB - vmovdqu [eax * 2 + edx + 32], ymm2 // store next 4 pixels of ARGB - lea eax, [eax + 32] - sub ecx, 16 - jg convertloop - vzeroupper - ret - } -} -#endif // HAS_RGB565TOARGBROW_AVX2 - -#ifdef HAS_ARGB1555TOARGBROW_AVX2 -__declspec(naked) void ARGB1555ToARGBRow_AVX2(const uint8_t* src_argb1555, - uint8_t* dst_argb, - int width) { - __asm { - mov eax, 0x01080108 // generate multiplier to repeat 5 bits - vmovd xmm5, eax - vbroadcastss ymm5, xmm5 - mov eax, 0x42004200 // multiplier shift by 6 and then repeat 5 bits - vmovd xmm6, eax - vbroadcastss ymm6, xmm6 - vpcmpeqb ymm3, ymm3, ymm3 // generate mask 0xf800f800 for Red - vpsllw ymm3, ymm3, 11 - vpsrlw ymm4, ymm3, 6 // generate mask 0x03e003e0 for Green - vpcmpeqb ymm7, ymm7, ymm7 // generate mask 0xff00ff00 for Alpha - vpsllw ymm7, ymm7, 8 - - mov eax, [esp + 4] // src_argb1555 - mov edx, [esp + 8] // dst_argb - mov ecx, [esp + 12] // width - sub edx, eax - sub edx, eax - - convertloop: - vmovdqu ymm0, [eax] // fetch 16 pixels of 1555 - vpsllw ymm1, ymm0, 1 // R in upper 5 bits - vpsllw ymm2, ymm0, 11 // B in upper 5 bits - vpand ymm1, ymm1, ymm3 - vpmulhuw ymm2, ymm2, ymm5 // * (256 + 8) - vpmulhuw ymm1, ymm1, ymm5 // * (256 + 8) - vpsllw ymm1, ymm1, 8 - vpor ymm1, ymm1, ymm2 // RB - vpsraw ymm2, ymm0, 8 // A - vpand ymm0, ymm0, ymm4 // G in middle 5 bits - vpmulhuw ymm0, ymm0, ymm6 // << 6 * (256 + 8) - vpand ymm2, ymm2, ymm7 - vpor ymm0, ymm0, ymm2 // AG - vpermq ymm0, ymm0, 0xd8 // mutate for unpack - vpermq ymm1, ymm1, 0xd8 - vpunpckhbw ymm2, ymm1, ymm0 - vpunpcklbw ymm1, ymm1, ymm0 - vmovdqu [eax * 2 + edx], ymm1 // store 8 pixels of ARGB - vmovdqu [eax * 2 + edx + 32], ymm2 // store next 8 pixels of ARGB - lea eax, [eax + 32] - sub ecx, 16 - jg convertloop - vzeroupper - ret - } -} -#endif // HAS_ARGB1555TOARGBROW_AVX2 - -#ifdef HAS_ARGB4444TOARGBROW_AVX2 -__declspec(naked) void ARGB4444ToARGBRow_AVX2(const uint8_t* src_argb4444, - uint8_t* dst_argb, - int width) { - __asm { - mov eax, 0x0f0f0f0f // generate mask 0x0f0f0f0f - vmovd xmm4, eax - vbroadcastss ymm4, xmm4 - vpslld ymm5, ymm4, 4 // 0xf0f0f0f0 for high nibbles - mov eax, [esp + 4] // src_argb4444 - mov edx, [esp + 8] // dst_argb - mov ecx, [esp + 12] // width - sub edx, eax - sub edx, eax - - convertloop: - vmovdqu ymm0, [eax] // fetch 16 pixels of bgra4444 - vpand ymm2, ymm0, ymm5 // mask high nibbles - vpand ymm0, ymm0, ymm4 // mask low nibbles - vpsrlw ymm3, ymm2, 4 - vpsllw ymm1, ymm0, 4 - vpor ymm2, ymm2, ymm3 - vpor ymm0, ymm0, ymm1 - vpermq ymm0, ymm0, 0xd8 // mutate for unpack - vpermq ymm2, ymm2, 0xd8 - vpunpckhbw ymm1, ymm0, ymm2 - vpunpcklbw ymm0, ymm0, ymm2 - vmovdqu [eax * 2 + edx], ymm0 // store 8 pixels of ARGB - vmovdqu [eax * 2 + edx + 32], ymm1 // store next 8 pixels of ARGB - lea eax, [eax + 32] - sub ecx, 16 - jg convertloop - vzeroupper - ret - } -} -#endif // HAS_ARGB4444TOARGBROW_AVX2 - -// 24 instructions -__declspec(naked) void ARGB1555ToARGBRow_SSE2(const uint8_t* src_argb1555, - uint8_t* dst_argb, - int width) { - __asm { - mov eax, 0x01080108 // generate multiplier to repeat 5 bits - movd xmm5, eax - pshufd xmm5, xmm5, 0 - mov eax, 0x42004200 // multiplier shift by 6 and then repeat 5 bits - movd xmm6, eax - pshufd xmm6, xmm6, 0 - pcmpeqb xmm3, xmm3 // generate mask 0xf800f800 for Red - psllw xmm3, 11 - movdqa xmm4, xmm3 // generate mask 0x03e003e0 for Green - psrlw xmm4, 6 - pcmpeqb xmm7, xmm7 // generate mask 0xff00ff00 for Alpha - psllw xmm7, 8 - - mov eax, [esp + 4] // src_argb1555 - mov edx, [esp + 8] // dst_argb - mov ecx, [esp + 12] // width - sub edx, eax - sub edx, eax - - convertloop: - movdqu xmm0, [eax] // fetch 8 pixels of 1555 - movdqa xmm1, xmm0 - movdqa xmm2, xmm0 - psllw xmm1, 1 // R in upper 5 bits - psllw xmm2, 11 // B in upper 5 bits - pand xmm1, xmm3 - pmulhuw xmm2, xmm5 // * (256 + 8) - pmulhuw xmm1, xmm5 // * (256 + 8) - psllw xmm1, 8 - por xmm1, xmm2 // RB - movdqa xmm2, xmm0 - pand xmm0, xmm4 // G in middle 5 bits - psraw xmm2, 8 // A - pmulhuw xmm0, xmm6 // << 6 * (256 + 8) - pand xmm2, xmm7 - por xmm0, xmm2 // AG - movdqa xmm2, xmm1 - punpcklbw xmm1, xmm0 - punpckhbw xmm2, xmm0 - movdqu [eax * 2 + edx], xmm1 // store 4 pixels of ARGB - movdqu [eax * 2 + edx + 16], xmm2 // store next 4 pixels of ARGB - lea eax, [eax + 16] - sub ecx, 8 - jg convertloop - ret - } -} - -// 18 instructions. -__declspec(naked) void ARGB4444ToARGBRow_SSE2(const uint8_t* src_argb4444, - uint8_t* dst_argb, - int width) { - __asm { - mov eax, 0x0f0f0f0f // generate mask 0x0f0f0f0f - movd xmm4, eax - pshufd xmm4, xmm4, 0 - movdqa xmm5, xmm4 // 0xf0f0f0f0 for high nibbles - pslld xmm5, 4 - mov eax, [esp + 4] // src_argb4444 - mov edx, [esp + 8] // dst_argb - mov ecx, [esp + 12] // width - sub edx, eax - sub edx, eax - - convertloop: - movdqu xmm0, [eax] // fetch 8 pixels of bgra4444 - movdqa xmm2, xmm0 - pand xmm0, xmm4 // mask low nibbles - pand xmm2, xmm5 // mask high nibbles - movdqa xmm1, xmm0 - movdqa xmm3, xmm2 - psllw xmm1, 4 - psrlw xmm3, 4 - por xmm0, xmm1 - por xmm2, xmm3 - movdqa xmm1, xmm0 - punpcklbw xmm0, xmm2 - punpckhbw xmm1, xmm2 - movdqu [eax * 2 + edx], xmm0 // store 4 pixels of ARGB - movdqu [eax * 2 + edx + 16], xmm1 // store next 4 pixels of ARGB - lea eax, [eax + 16] - sub ecx, 8 - jg convertloop - ret - } -} - -__declspec(naked) void ARGBToRGB24Row_SSSE3(const uint8_t* src_argb, - uint8_t* dst_rgb, - int width) { - __asm { - mov eax, [esp + 4] // src_argb - mov edx, [esp + 8] // dst_rgb - mov ecx, [esp + 12] // width - movdqa xmm6, xmmword ptr kShuffleMaskARGBToRGB24 - - convertloop: - movdqu xmm0, [eax] // fetch 16 pixels of argb - movdqu xmm1, [eax + 16] - movdqu xmm2, [eax + 32] - movdqu xmm3, [eax + 48] - lea eax, [eax + 64] - pshufb xmm0, xmm6 // pack 16 bytes of ARGB to 12 bytes of RGB - pshufb xmm1, xmm6 - pshufb xmm2, xmm6 - pshufb xmm3, xmm6 - movdqa xmm4, xmm1 // 4 bytes from 1 for 0 - psrldq xmm1, 4 // 8 bytes from 1 - pslldq xmm4, 12 // 4 bytes from 1 for 0 - movdqa xmm5, xmm2 // 8 bytes from 2 for 1 - por xmm0, xmm4 // 4 bytes from 1 for 0 - pslldq xmm5, 8 // 8 bytes from 2 for 1 - movdqu [edx], xmm0 // store 0 - por xmm1, xmm5 // 8 bytes from 2 for 1 - psrldq xmm2, 8 // 4 bytes from 2 - pslldq xmm3, 4 // 12 bytes from 3 for 2 - por xmm2, xmm3 // 12 bytes from 3 for 2 - movdqu [edx + 16], xmm1 // store 1 - movdqu [edx + 32], xmm2 // store 2 - lea edx, [edx + 48] - sub ecx, 16 - jg convertloop - ret - } -} - -__declspec(naked) void ARGBToRAWRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_rgb, - int width) { - __asm { - mov eax, [esp + 4] // src_argb - mov edx, [esp + 8] // dst_rgb - mov ecx, [esp + 12] // width - movdqa xmm6, xmmword ptr kShuffleMaskARGBToRAW - - convertloop: - movdqu xmm0, [eax] // fetch 16 pixels of argb - movdqu xmm1, [eax + 16] - movdqu xmm2, [eax + 32] - movdqu xmm3, [eax + 48] - lea eax, [eax + 64] - pshufb xmm0, xmm6 // pack 16 bytes of ARGB to 12 bytes of RGB - pshufb xmm1, xmm6 - pshufb xmm2, xmm6 - pshufb xmm3, xmm6 - movdqa xmm4, xmm1 // 4 bytes from 1 for 0 - psrldq xmm1, 4 // 8 bytes from 1 - pslldq xmm4, 12 // 4 bytes from 1 for 0 - movdqa xmm5, xmm2 // 8 bytes from 2 for 1 - por xmm0, xmm4 // 4 bytes from 1 for 0 - pslldq xmm5, 8 // 8 bytes from 2 for 1 - movdqu [edx], xmm0 // store 0 - por xmm1, xmm5 // 8 bytes from 2 for 1 - psrldq xmm2, 8 // 4 bytes from 2 - pslldq xmm3, 4 // 12 bytes from 3 for 2 - por xmm2, xmm3 // 12 bytes from 3 for 2 - movdqu [edx + 16], xmm1 // store 1 - movdqu [edx + 32], xmm2 // store 2 - lea edx, [edx + 48] - sub ecx, 16 - jg convertloop - ret - } -} - -__declspec(naked) void ARGBToRGB565Row_SSE2(const uint8_t* src_argb, - uint8_t* dst_rgb, - int width) { - __asm { - mov eax, [esp + 4] // src_argb - mov edx, [esp + 8] // dst_rgb - mov ecx, [esp + 12] // width - pcmpeqb xmm3, xmm3 // generate mask 0x0000001f - psrld xmm3, 27 - pcmpeqb xmm4, xmm4 // generate mask 0x000007e0 - psrld xmm4, 26 - pslld xmm4, 5 - pcmpeqb xmm5, xmm5 // generate mask 0xfffff800 - pslld xmm5, 11 - - convertloop: - movdqu xmm0, [eax] // fetch 4 pixels of argb - movdqa xmm1, xmm0 // B - movdqa xmm2, xmm0 // G - pslld xmm0, 8 // R - psrld xmm1, 3 // B - psrld xmm2, 5 // G - psrad xmm0, 16 // R - pand xmm1, xmm3 // B - pand xmm2, xmm4 // G - pand xmm0, xmm5 // R - por xmm1, xmm2 // BG - por xmm0, xmm1 // BGR - packssdw xmm0, xmm0 - lea eax, [eax + 16] - movq qword ptr [edx], xmm0 // store 4 pixels of RGB565 - lea edx, [edx + 8] - sub ecx, 4 - jg convertloop - ret - } -} - -__declspec(naked) void ARGBToRGB565DitherRow_SSE2(const uint8_t* src_argb, - uint8_t* dst_rgb, - const uint32_t dither4, - int width) { - __asm { - - mov eax, [esp + 4] // src_argb - mov edx, [esp + 8] // dst_rgb - movd xmm6, [esp + 12] // dither4 - mov ecx, [esp + 16] // width - punpcklbw xmm6, xmm6 // make dither 16 bytes - movdqa xmm7, xmm6 - punpcklwd xmm6, xmm6 - punpckhwd xmm7, xmm7 - pcmpeqb xmm3, xmm3 // generate mask 0x0000001f - psrld xmm3, 27 - pcmpeqb xmm4, xmm4 // generate mask 0x000007e0 - psrld xmm4, 26 - pslld xmm4, 5 - pcmpeqb xmm5, xmm5 // generate mask 0xfffff800 - pslld xmm5, 11 - - convertloop: - movdqu xmm0, [eax] // fetch 4 pixels of argb - paddusb xmm0, xmm6 // add dither - movdqa xmm1, xmm0 // B - movdqa xmm2, xmm0 // G - pslld xmm0, 8 // R - psrld xmm1, 3 // B - psrld xmm2, 5 // G - psrad xmm0, 16 // R - pand xmm1, xmm3 // B - pand xmm2, xmm4 // G - pand xmm0, xmm5 // R - por xmm1, xmm2 // BG - por xmm0, xmm1 // BGR - packssdw xmm0, xmm0 - lea eax, [eax + 16] - movq qword ptr [edx], xmm0 // store 4 pixels of RGB565 - lea edx, [edx + 8] - sub ecx, 4 - jg convertloop - ret - } -} - -#ifdef HAS_ARGBTORGB565DITHERROW_AVX2 -__declspec(naked) void ARGBToRGB565DitherRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_rgb, - const uint32_t dither4, - int width) { - __asm { - mov eax, [esp + 4] // src_argb - mov edx, [esp + 8] // dst_rgb - vbroadcastss xmm6, [esp + 12] // dither4 - mov ecx, [esp + 16] // width - vpunpcklbw xmm6, xmm6, xmm6 // make dither 32 bytes - vpermq ymm6, ymm6, 0xd8 - vpunpcklwd ymm6, ymm6, ymm6 - vpcmpeqb ymm3, ymm3, ymm3 // generate mask 0x0000001f - vpsrld ymm3, ymm3, 27 - vpcmpeqb ymm4, ymm4, ymm4 // generate mask 0x000007e0 - vpsrld ymm4, ymm4, 26 - vpslld ymm4, ymm4, 5 - vpslld ymm5, ymm3, 11 // generate mask 0x0000f800 - - convertloop: - vmovdqu ymm0, [eax] // fetch 8 pixels of argb - vpaddusb ymm0, ymm0, ymm6 // add dither - vpsrld ymm2, ymm0, 5 // G - vpsrld ymm1, ymm0, 3 // B - vpsrld ymm0, ymm0, 8 // R - vpand ymm2, ymm2, ymm4 // G - vpand ymm1, ymm1, ymm3 // B - vpand ymm0, ymm0, ymm5 // R - vpor ymm1, ymm1, ymm2 // BG - vpor ymm0, ymm0, ymm1 // BGR - vpackusdw ymm0, ymm0, ymm0 - vpermq ymm0, ymm0, 0xd8 - lea eax, [eax + 32] - vmovdqu [edx], xmm0 // store 8 pixels of RGB565 - lea edx, [edx + 16] - sub ecx, 8 - jg convertloop - vzeroupper - ret - } -} -#endif // HAS_ARGBTORGB565DITHERROW_AVX2 - -// TODO(fbarchard): Improve sign extension/packing. -__declspec(naked) void ARGBToARGB1555Row_SSE2(const uint8_t* src_argb, - uint8_t* dst_rgb, - int width) { - __asm { - mov eax, [esp + 4] // src_argb - mov edx, [esp + 8] // dst_rgb - mov ecx, [esp + 12] // width - pcmpeqb xmm4, xmm4 // generate mask 0x0000001f - psrld xmm4, 27 - movdqa xmm5, xmm4 // generate mask 0x000003e0 - pslld xmm5, 5 - movdqa xmm6, xmm4 // generate mask 0x00007c00 - pslld xmm6, 10 - pcmpeqb xmm7, xmm7 // generate mask 0xffff8000 - pslld xmm7, 15 - - convertloop: - movdqu xmm0, [eax] // fetch 4 pixels of argb - movdqa xmm1, xmm0 // B - movdqa xmm2, xmm0 // G - movdqa xmm3, xmm0 // R - psrad xmm0, 16 // A - psrld xmm1, 3 // B - psrld xmm2, 6 // G - psrld xmm3, 9 // R - pand xmm0, xmm7 // A - pand xmm1, xmm4 // B - pand xmm2, xmm5 // G - pand xmm3, xmm6 // R - por xmm0, xmm1 // BA - por xmm2, xmm3 // GR - por xmm0, xmm2 // BGRA - packssdw xmm0, xmm0 - lea eax, [eax + 16] - movq qword ptr [edx], xmm0 // store 4 pixels of ARGB1555 - lea edx, [edx + 8] - sub ecx, 4 - jg convertloop - ret - } -} - -__declspec(naked) void ARGBToARGB4444Row_SSE2(const uint8_t* src_argb, - uint8_t* dst_rgb, - int width) { - __asm { - mov eax, [esp + 4] // src_argb - mov edx, [esp + 8] // dst_rgb - mov ecx, [esp + 12] // width - pcmpeqb xmm4, xmm4 // generate mask 0xf000f000 - psllw xmm4, 12 - movdqa xmm3, xmm4 // generate mask 0x00f000f0 - psrlw xmm3, 8 - - convertloop: - movdqu xmm0, [eax] // fetch 4 pixels of argb - movdqa xmm1, xmm0 - pand xmm0, xmm3 // low nibble - pand xmm1, xmm4 // high nibble - psrld xmm0, 4 - psrld xmm1, 8 - por xmm0, xmm1 - packuswb xmm0, xmm0 - lea eax, [eax + 16] - movq qword ptr [edx], xmm0 // store 4 pixels of ARGB4444 - lea edx, [edx + 8] - sub ecx, 4 - jg convertloop - ret - } -} - -#ifdef HAS_ARGBTORGB565ROW_AVX2 -__declspec(naked) void ARGBToRGB565Row_AVX2(const uint8_t* src_argb, - uint8_t* dst_rgb, - int width) { - __asm { - mov eax, [esp + 4] // src_argb - mov edx, [esp + 8] // dst_rgb - mov ecx, [esp + 12] // width - vpcmpeqb ymm3, ymm3, ymm3 // generate mask 0x0000001f - vpsrld ymm3, ymm3, 27 - vpcmpeqb ymm4, ymm4, ymm4 // generate mask 0x000007e0 - vpsrld ymm4, ymm4, 26 - vpslld ymm4, ymm4, 5 - vpslld ymm5, ymm3, 11 // generate mask 0x0000f800 - - convertloop: - vmovdqu ymm0, [eax] // fetch 8 pixels of argb - vpsrld ymm2, ymm0, 5 // G - vpsrld ymm1, ymm0, 3 // B - vpsrld ymm0, ymm0, 8 // R - vpand ymm2, ymm2, ymm4 // G - vpand ymm1, ymm1, ymm3 // B - vpand ymm0, ymm0, ymm5 // R - vpor ymm1, ymm1, ymm2 // BG - vpor ymm0, ymm0, ymm1 // BGR - vpackusdw ymm0, ymm0, ymm0 - vpermq ymm0, ymm0, 0xd8 - lea eax, [eax + 32] - vmovdqu [edx], xmm0 // store 8 pixels of RGB565 - lea edx, [edx + 16] - sub ecx, 8 - jg convertloop - vzeroupper - ret - } -} -#endif // HAS_ARGBTORGB565ROW_AVX2 - -#ifdef HAS_ARGBTOARGB1555ROW_AVX2 -__declspec(naked) void ARGBToARGB1555Row_AVX2(const uint8_t* src_argb, - uint8_t* dst_rgb, - int width) { - __asm { - mov eax, [esp + 4] // src_argb - mov edx, [esp + 8] // dst_rgb - mov ecx, [esp + 12] // width - vpcmpeqb ymm4, ymm4, ymm4 - vpsrld ymm4, ymm4, 27 // generate mask 0x0000001f - vpslld ymm5, ymm4, 5 // generate mask 0x000003e0 - vpslld ymm6, ymm4, 10 // generate mask 0x00007c00 - vpcmpeqb ymm7, ymm7, ymm7 // generate mask 0xffff8000 - vpslld ymm7, ymm7, 15 - - convertloop: - vmovdqu ymm0, [eax] // fetch 8 pixels of argb - vpsrld ymm3, ymm0, 9 // R - vpsrld ymm2, ymm0, 6 // G - vpsrld ymm1, ymm0, 3 // B - vpsrad ymm0, ymm0, 16 // A - vpand ymm3, ymm3, ymm6 // R - vpand ymm2, ymm2, ymm5 // G - vpand ymm1, ymm1, ymm4 // B - vpand ymm0, ymm0, ymm7 // A - vpor ymm0, ymm0, ymm1 // BA - vpor ymm2, ymm2, ymm3 // GR - vpor ymm0, ymm0, ymm2 // BGRA - vpackssdw ymm0, ymm0, ymm0 - vpermq ymm0, ymm0, 0xd8 - lea eax, [eax + 32] - vmovdqu [edx], xmm0 // store 8 pixels of ARGB1555 - lea edx, [edx + 16] - sub ecx, 8 - jg convertloop - vzeroupper - ret - } -} -#endif // HAS_ARGBTOARGB1555ROW_AVX2 - -#ifdef HAS_ARGBTOARGB4444ROW_AVX2 -__declspec(naked) void ARGBToARGB4444Row_AVX2(const uint8_t* src_argb, - uint8_t* dst_rgb, - int width) { - __asm { - mov eax, [esp + 4] // src_argb - mov edx, [esp + 8] // dst_rgb - mov ecx, [esp + 12] // width - vpcmpeqb ymm4, ymm4, ymm4 // generate mask 0xf000f000 - vpsllw ymm4, ymm4, 12 - vpsrlw ymm3, ymm4, 8 // generate mask 0x00f000f0 - - convertloop: - vmovdqu ymm0, [eax] // fetch 8 pixels of argb - vpand ymm1, ymm0, ymm4 // high nibble - vpand ymm0, ymm0, ymm3 // low nibble - vpsrld ymm1, ymm1, 8 - vpsrld ymm0, ymm0, 4 - vpor ymm0, ymm0, ymm1 - vpackuswb ymm0, ymm0, ymm0 - vpermq ymm0, ymm0, 0xd8 - lea eax, [eax + 32] - vmovdqu [edx], xmm0 // store 8 pixels of ARGB4444 - lea edx, [edx + 16] - sub ecx, 8 - jg convertloop - vzeroupper - ret - } -} -#endif // HAS_ARGBTOARGB4444ROW_AVX2 - -// Convert 16 ARGB pixels (64 bytes) to 16 Y values. -__declspec(naked) void ARGBToYRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_y, - int width) { - __asm { - mov eax, [esp + 4] /* src_argb */ - mov edx, [esp + 8] /* dst_y */ - mov ecx, [esp + 12] /* width */ - movdqa xmm4, xmmword ptr kARGBToY - movdqa xmm5, xmmword ptr kAddY16 - - convertloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - movdqu xmm2, [eax + 32] - movdqu xmm3, [eax + 48] - pmaddubsw xmm0, xmm4 - pmaddubsw xmm1, xmm4 - pmaddubsw xmm2, xmm4 - pmaddubsw xmm3, xmm4 - lea eax, [eax + 64] - phaddw xmm0, xmm1 - phaddw xmm2, xmm3 - psrlw xmm0, 7 - psrlw xmm2, 7 - packuswb xmm0, xmm2 - paddb xmm0, xmm5 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 16 - jg convertloop - ret - } -} - -// Convert 16 ARGB pixels (64 bytes) to 16 YJ values. -// Same as ARGBToYRow but different coefficients, no add 16, but do rounding. -__declspec(naked) void ARGBToYJRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_y, - int width) { - __asm { - mov eax, [esp + 4] /* src_argb */ - mov edx, [esp + 8] /* dst_y */ - mov ecx, [esp + 12] /* width */ - movdqa xmm4, xmmword ptr kARGBToYJ - movdqa xmm5, xmmword ptr kAddYJ64 - - convertloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - movdqu xmm2, [eax + 32] - movdqu xmm3, [eax + 48] - pmaddubsw xmm0, xmm4 - pmaddubsw xmm1, xmm4 - pmaddubsw xmm2, xmm4 - pmaddubsw xmm3, xmm4 - lea eax, [eax + 64] - phaddw xmm0, xmm1 - phaddw xmm2, xmm3 - paddw xmm0, xmm5 // Add .5 for rounding. - paddw xmm2, xmm5 - psrlw xmm0, 7 - psrlw xmm2, 7 - packuswb xmm0, xmm2 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 16 - jg convertloop - ret - } -} - -#ifdef HAS_ARGBTOYROW_AVX2 -// vpermd for vphaddw + vpackuswb vpermd. -static const lvec32 kPermdARGBToY_AVX = {0, 4, 1, 5, 2, 6, 3, 7}; - -// Convert 32 ARGB pixels (128 bytes) to 32 Y values. -__declspec(naked) void ARGBToYRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_y, - int width) { - __asm { - mov eax, [esp + 4] /* src_argb */ - mov edx, [esp + 8] /* dst_y */ - mov ecx, [esp + 12] /* width */ - vbroadcastf128 ymm4, xmmword ptr kARGBToY - vbroadcastf128 ymm5, xmmword ptr kAddY16 - vmovdqu ymm6, ymmword ptr kPermdARGBToY_AVX - - convertloop: - vmovdqu ymm0, [eax] - vmovdqu ymm1, [eax + 32] - vmovdqu ymm2, [eax + 64] - vmovdqu ymm3, [eax + 96] - vpmaddubsw ymm0, ymm0, ymm4 - vpmaddubsw ymm1, ymm1, ymm4 - vpmaddubsw ymm2, ymm2, ymm4 - vpmaddubsw ymm3, ymm3, ymm4 - lea eax, [eax + 128] - vphaddw ymm0, ymm0, ymm1 // mutates. - vphaddw ymm2, ymm2, ymm3 - vpsrlw ymm0, ymm0, 7 - vpsrlw ymm2, ymm2, 7 - vpackuswb ymm0, ymm0, ymm2 // mutates. - vpermd ymm0, ymm6, ymm0 // For vphaddw + vpackuswb mutation. - vpaddb ymm0, ymm0, ymm5 // add 16 for Y - vmovdqu [edx], ymm0 - lea edx, [edx + 32] - sub ecx, 32 - jg convertloop - vzeroupper - ret - } -} -#endif // HAS_ARGBTOYROW_AVX2 - -#ifdef HAS_ARGBTOYJROW_AVX2 -// Convert 32 ARGB pixels (128 bytes) to 32 Y values. -__declspec(naked) void ARGBToYJRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_y, - int width) { - __asm { - mov eax, [esp + 4] /* src_argb */ - mov edx, [esp + 8] /* dst_y */ - mov ecx, [esp + 12] /* width */ - vbroadcastf128 ymm4, xmmword ptr kARGBToYJ - vbroadcastf128 ymm5, xmmword ptr kAddYJ64 - vmovdqu ymm6, ymmword ptr kPermdARGBToY_AVX - - convertloop: - vmovdqu ymm0, [eax] - vmovdqu ymm1, [eax + 32] - vmovdqu ymm2, [eax + 64] - vmovdqu ymm3, [eax + 96] - vpmaddubsw ymm0, ymm0, ymm4 - vpmaddubsw ymm1, ymm1, ymm4 - vpmaddubsw ymm2, ymm2, ymm4 - vpmaddubsw ymm3, ymm3, ymm4 - lea eax, [eax + 128] - vphaddw ymm0, ymm0, ymm1 // mutates. - vphaddw ymm2, ymm2, ymm3 - vpaddw ymm0, ymm0, ymm5 // Add .5 for rounding. - vpaddw ymm2, ymm2, ymm5 - vpsrlw ymm0, ymm0, 7 - vpsrlw ymm2, ymm2, 7 - vpackuswb ymm0, ymm0, ymm2 // mutates. - vpermd ymm0, ymm6, ymm0 // For vphaddw + vpackuswb mutation. - vmovdqu [edx], ymm0 - lea edx, [edx + 32] - sub ecx, 32 - jg convertloop - - vzeroupper - ret - } -} -#endif // HAS_ARGBTOYJROW_AVX2 - -__declspec(naked) void BGRAToYRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_y, - int width) { - __asm { - mov eax, [esp + 4] /* src_argb */ - mov edx, [esp + 8] /* dst_y */ - mov ecx, [esp + 12] /* width */ - movdqa xmm4, xmmword ptr kBGRAToY - movdqa xmm5, xmmword ptr kAddY16 - - convertloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - movdqu xmm2, [eax + 32] - movdqu xmm3, [eax + 48] - pmaddubsw xmm0, xmm4 - pmaddubsw xmm1, xmm4 - pmaddubsw xmm2, xmm4 - pmaddubsw xmm3, xmm4 - lea eax, [eax + 64] - phaddw xmm0, xmm1 - phaddw xmm2, xmm3 - psrlw xmm0, 7 - psrlw xmm2, 7 - packuswb xmm0, xmm2 - paddb xmm0, xmm5 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 16 - jg convertloop - ret - } -} - -__declspec(naked) void ABGRToYRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_y, - int width) { - __asm { - mov eax, [esp + 4] /* src_argb */ - mov edx, [esp + 8] /* dst_y */ - mov ecx, [esp + 12] /* width */ - movdqa xmm4, xmmword ptr kABGRToY - movdqa xmm5, xmmword ptr kAddY16 - - convertloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - movdqu xmm2, [eax + 32] - movdqu xmm3, [eax + 48] - pmaddubsw xmm0, xmm4 - pmaddubsw xmm1, xmm4 - pmaddubsw xmm2, xmm4 - pmaddubsw xmm3, xmm4 - lea eax, [eax + 64] - phaddw xmm0, xmm1 - phaddw xmm2, xmm3 - psrlw xmm0, 7 - psrlw xmm2, 7 - packuswb xmm0, xmm2 - paddb xmm0, xmm5 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 16 - jg convertloop - ret - } -} - -__declspec(naked) void RGBAToYRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_y, - int width) { - __asm { - mov eax, [esp + 4] /* src_argb */ - mov edx, [esp + 8] /* dst_y */ - mov ecx, [esp + 12] /* width */ - movdqa xmm4, xmmword ptr kRGBAToY - movdqa xmm5, xmmword ptr kAddY16 - - convertloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - movdqu xmm2, [eax + 32] - movdqu xmm3, [eax + 48] - pmaddubsw xmm0, xmm4 - pmaddubsw xmm1, xmm4 - pmaddubsw xmm2, xmm4 - pmaddubsw xmm3, xmm4 - lea eax, [eax + 64] - phaddw xmm0, xmm1 - phaddw xmm2, xmm3 - psrlw xmm0, 7 - psrlw xmm2, 7 - packuswb xmm0, xmm2 - paddb xmm0, xmm5 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 16 - jg convertloop - ret - } -} - -__declspec(naked) void ARGBToUVRow_SSSE3(const uint8_t* src_argb0, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* 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 - 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 xmm4, [eax + esi] - pavgb xmm0, xmm4 - movdqu xmm1, [eax + 16] - movdqu xmm4, [eax + esi + 16] - pavgb xmm1, xmm4 - movdqu xmm2, [eax + 32] - movdqu xmm4, [eax + esi + 32] - pavgb xmm2, xmm4 - movdqu xmm3, [eax + 48] - movdqu xmm4, [eax + esi + 48] - pavgb xmm3, xmm4 - - 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 - pop esi - ret - } -} - -__declspec(naked) void ARGBToUVJRow_SSSE3(const uint8_t* src_argb0, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* 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 - movdqa xmm5, xmmword ptr kAddUVJ128 - movdqa xmm6, xmmword ptr kARGBToVJ - movdqa xmm7, xmmword ptr kARGBToUJ - sub edi, edx // stride from u to v - - convertloop: - /* step 1 - subsample 16x2 argb pixels to 8x1 */ - movdqu xmm0, [eax] - movdqu xmm4, [eax + esi] - pavgb xmm0, xmm4 - movdqu xmm1, [eax + 16] - movdqu xmm4, [eax + esi + 16] - pavgb xmm1, xmm4 - movdqu xmm2, [eax + 32] - movdqu xmm4, [eax + esi + 32] - pavgb xmm2, xmm4 - movdqu xmm3, [eax + 48] - movdqu xmm4, [eax + esi + 48] - pavgb xmm3, xmm4 - - 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 - paddw xmm0, xmm5 // +.5 rounding -> unsigned - paddw xmm1, xmm5 - psraw xmm0, 8 - psraw xmm1, 8 - packsswb xmm0, xmm1 - - // 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 - pop esi - ret - } -} - -#ifdef HAS_ARGBTOUVROW_AVX2 -__declspec(naked) void ARGBToUVRow_AVX2(const uint8_t* src_argb0, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* 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 - 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 - vpaddb ymm0, ymm0, ymm5 // -> unsigned - - // 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_ARGBTOUVROW_AVX2 - -#ifdef HAS_ARGBTOUVJROW_AVX2 -__declspec(naked) void ARGBToUVJRow_AVX2(const uint8_t* src_argb0, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* 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_t* src_argb0, - uint8_t* dst_u, - uint8_t* 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: - /* convert to U and V */ - movdqu xmm0, [eax] // U - movdqu xmm1, [eax + 16] - movdqu xmm2, [eax + 32] - movdqu xmm3, [eax + 48] - pmaddubsw xmm0, xmm7 - pmaddubsw xmm1, xmm7 - pmaddubsw xmm2, xmm7 - pmaddubsw xmm3, xmm7 - phaddw xmm0, xmm1 - phaddw xmm2, xmm3 - psraw xmm0, 8 - psraw xmm2, 8 - packsswb xmm0, xmm2 - paddb xmm0, xmm5 - movdqu [edx], xmm0 - - movdqu xmm0, [eax] // V - movdqu xmm1, [eax + 16] - movdqu xmm2, [eax + 32] - movdqu xmm3, [eax + 48] - pmaddubsw xmm0, xmm6 - pmaddubsw xmm1, xmm6 - pmaddubsw xmm2, xmm6 - pmaddubsw xmm3, xmm6 - phaddw xmm0, xmm1 - phaddw xmm2, xmm3 - psraw xmm0, 8 - psraw xmm2, 8 - packsswb xmm0, xmm2 - paddb xmm0, xmm5 - lea eax, [eax + 64] - movdqu [edx + edi], xmm0 - lea edx, [edx + 16] - sub ecx, 16 - jg convertloop - - pop edi - ret - } -} - -__declspec(naked) void BGRAToUVRow_SSSE3(const uint8_t* src_argb0, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* 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 - movdqa xmm5, xmmword ptr kAddUV128 - movdqa xmm6, xmmword ptr kBGRAToV - movdqa xmm7, xmmword ptr kBGRAToU - sub edi, edx // stride from u to v - - convertloop: - /* step 1 - subsample 16x2 argb pixels to 8x1 */ - movdqu xmm0, [eax] - movdqu xmm4, [eax + esi] - pavgb xmm0, xmm4 - movdqu xmm1, [eax + 16] - movdqu xmm4, [eax + esi + 16] - pavgb xmm1, xmm4 - movdqu xmm2, [eax + 32] - movdqu xmm4, [eax + esi + 32] - pavgb xmm2, xmm4 - movdqu xmm3, [eax + 48] - movdqu xmm4, [eax + esi + 48] - pavgb xmm3, xmm4 - - 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 - pop esi - ret - } -} - -__declspec(naked) void ABGRToUVRow_SSSE3(const uint8_t* src_argb0, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* 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 - movdqa xmm5, xmmword ptr kAddUV128 - movdqa xmm6, xmmword ptr kABGRToV - movdqa xmm7, xmmword ptr kABGRToU - sub edi, edx // stride from u to v - - convertloop: - /* step 1 - subsample 16x2 argb pixels to 8x1 */ - movdqu xmm0, [eax] - movdqu xmm4, [eax + esi] - pavgb xmm0, xmm4 - movdqu xmm1, [eax + 16] - movdqu xmm4, [eax + esi + 16] - pavgb xmm1, xmm4 - movdqu xmm2, [eax + 32] - movdqu xmm4, [eax + esi + 32] - pavgb xmm2, xmm4 - movdqu xmm3, [eax + 48] - movdqu xmm4, [eax + esi + 48] - pavgb xmm3, xmm4 - - 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 - pop esi - ret - } -} - -__declspec(naked) void RGBAToUVRow_SSSE3(const uint8_t* src_argb0, - int src_stride_argb, - uint8_t* dst_u, - uint8_t* 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 - movdqa xmm5, xmmword ptr kAddUV128 - movdqa xmm6, xmmword ptr kRGBAToV - movdqa xmm7, xmmword ptr kRGBAToU - sub edi, edx // stride from u to v - - convertloop: - /* step 1 - subsample 16x2 argb pixels to 8x1 */ - movdqu xmm0, [eax] - movdqu xmm4, [eax + esi] - pavgb xmm0, xmm4 - movdqu xmm1, [eax + 16] - movdqu xmm4, [eax + esi + 16] - pavgb xmm1, xmm4 - movdqu xmm2, [eax + 32] - movdqu xmm4, [eax + esi + 32] - pavgb xmm2, xmm4 - movdqu xmm3, [eax + 48] - movdqu xmm4, [eax + esi + 48] - pavgb xmm3, xmm4 - - 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 - pop esi - ret - } -} -#endif // HAS_ARGBTOYROW_SSSE3 - -// Read 16 UV from 444 -#define READYUV444_AVX2 \ - __asm { \ - __asm vmovdqu xmm0, [esi] /* U */ \ - __asm vmovdqu xmm1, [esi + edi] /* V */ \ - __asm lea esi, [esi + 16] \ - __asm vpermq ymm0, ymm0, 0xd8 \ - __asm vpermq ymm1, ymm1, 0xd8 \ - __asm vpunpcklbw ymm0, ymm0, ymm1 /* UV */ \ - __asm vmovdqu xmm4, [eax] /* Y */ \ - __asm vpermq ymm4, ymm4, 0xd8 \ - __asm vpunpcklbw ymm4, ymm4, ymm4 \ - __asm lea eax, [eax + 16]} - -// Read 8 UV from 422, upsample to 16 UV. -#define READYUV422_AVX2 \ - __asm { \ - __asm vmovq xmm0, qword ptr [esi] /* U */ \ - __asm vmovq xmm1, qword ptr [esi + edi] /* V */ \ - __asm lea esi, [esi + 8] \ - __asm vpunpcklbw ymm0, ymm0, ymm1 /* UV */ \ - __asm vpermq ymm0, ymm0, 0xd8 \ - __asm vpunpcklwd ymm0, ymm0, ymm0 /* UVUV (upsample) */ \ - __asm vmovdqu xmm4, [eax] /* Y */ \ - __asm vpermq ymm4, ymm4, 0xd8 \ - __asm vpunpcklbw ymm4, ymm4, ymm4 \ - __asm lea eax, [eax + 16]} - -// Read 8 UV from 422, upsample to 16 UV. With 16 Alpha. -#define READYUVA422_AVX2 \ - __asm { \ - __asm vmovq xmm0, qword ptr [esi] /* U */ \ - __asm vmovq xmm1, qword ptr [esi + edi] /* V */ \ - __asm lea esi, [esi + 8] \ - __asm vpunpcklbw ymm0, ymm0, ymm1 /* UV */ \ - __asm vpermq ymm0, ymm0, 0xd8 \ - __asm vpunpcklwd ymm0, ymm0, ymm0 /* UVUV (upsample) */ \ - __asm vmovdqu xmm4, [eax] /* Y */ \ - __asm vpermq ymm4, ymm4, 0xd8 \ - __asm vpunpcklbw ymm4, ymm4, ymm4 \ - __asm lea eax, [eax + 16] \ - __asm vmovdqu xmm5, [ebp] /* A */ \ - __asm vpermq ymm5, ymm5, 0xd8 \ - __asm lea ebp, [ebp + 16]} - -// Read 8 UV from NV12, upsample to 16 UV. -#define READNV12_AVX2 \ - __asm { \ - __asm vmovdqu xmm0, [esi] /* UV */ \ - __asm lea esi, [esi + 16] \ - __asm vpermq ymm0, ymm0, 0xd8 \ - __asm vpunpcklwd ymm0, ymm0, ymm0 /* UVUV (upsample) */ \ - __asm vmovdqu xmm4, [eax] /* Y */ \ - __asm vpermq ymm4, ymm4, 0xd8 \ - __asm vpunpcklbw ymm4, ymm4, ymm4 \ - __asm lea eax, [eax + 16]} - -// Read 8 UV from NV21, upsample to 16 UV. -#define READNV21_AVX2 \ - __asm { \ - __asm vmovdqu xmm0, [esi] /* UV */ \ - __asm lea esi, [esi + 16] \ - __asm vpermq ymm0, ymm0, 0xd8 \ - __asm vpshufb ymm0, ymm0, ymmword ptr kShuffleNV21 \ - __asm vmovdqu xmm4, [eax] /* Y */ \ - __asm vpermq ymm4, ymm4, 0xd8 \ - __asm vpunpcklbw ymm4, ymm4, ymm4 \ - __asm lea eax, [eax + 16]} - -// Read 8 YUY2 with 16 Y and upsample 8 UV to 16 UV. -#define READYUY2_AVX2 \ - __asm { \ - __asm vmovdqu ymm4, [eax] /* YUY2 */ \ - __asm vpshufb ymm4, ymm4, ymmword ptr kShuffleYUY2Y \ - __asm vmovdqu ymm0, [eax] /* UV */ \ - __asm vpshufb ymm0, ymm0, ymmword ptr kShuffleYUY2UV \ - __asm lea eax, [eax + 32]} - -// Read 8 UYVY with 16 Y and upsample 8 UV to 16 UV. -#define READUYVY_AVX2 \ - __asm { \ - __asm vmovdqu ymm4, [eax] /* UYVY */ \ - __asm vpshufb ymm4, ymm4, ymmword ptr kShuffleUYVYY \ - __asm vmovdqu ymm0, [eax] /* UV */ \ - __asm vpshufb ymm0, ymm0, ymmword ptr kShuffleUYVYUV \ - __asm lea eax, [eax + 32]} - -// Convert 16 pixels: 16 UV and 16 Y. -#define YUVTORGB_AVX2(YuvConstants) \ - __asm { \ - __asm vpmaddubsw ymm2, ymm0, ymmword ptr [YuvConstants + KUVTOR] /* R UV */\ - __asm vpmaddubsw ymm1, ymm0, ymmword ptr [YuvConstants + KUVTOG] /* G UV */\ - __asm vpmaddubsw ymm0, ymm0, ymmword ptr [YuvConstants + KUVTOB] /* B UV */\ - __asm vmovdqu ymm3, ymmword ptr [YuvConstants + KUVBIASR] \ - __asm vpsubw ymm2, ymm3, ymm2 \ - __asm vmovdqu ymm3, ymmword ptr [YuvConstants + KUVBIASG] \ - __asm vpsubw ymm1, ymm3, ymm1 \ - __asm vmovdqu ymm3, ymmword ptr [YuvConstants + KUVBIASB] \ - __asm vpsubw ymm0, ymm3, ymm0 /* Step 2: Find Y contribution to 16 R,G,B values */ \ - __asm vpmulhuw ymm4, ymm4, ymmword ptr [YuvConstants + KYTORGB] \ - __asm vpaddsw ymm0, ymm0, ymm4 /* B += Y */ \ - __asm vpaddsw ymm1, ymm1, ymm4 /* G += Y */ \ - __asm vpaddsw ymm2, ymm2, ymm4 /* R += Y */ \ - __asm vpsraw ymm0, ymm0, 6 \ - __asm vpsraw ymm1, ymm1, 6 \ - __asm vpsraw ymm2, ymm2, 6 \ - __asm vpackuswb ymm0, ymm0, ymm0 /* B */ \ - __asm vpackuswb ymm1, ymm1, ymm1 /* G */ \ - __asm vpackuswb ymm2, ymm2, ymm2 /* R */ \ - } - -// Store 16 ARGB values. -#define STOREARGB_AVX2 \ - __asm { \ - __asm vpunpcklbw ymm0, ymm0, ymm1 /* BG */ \ - __asm vpermq ymm0, ymm0, 0xd8 \ - __asm vpunpcklbw ymm2, ymm2, ymm5 /* RA */ \ - __asm vpermq ymm2, ymm2, 0xd8 \ - __asm vpunpcklwd ymm1, ymm0, ymm2 /* BGRA first 8 pixels */ \ - __asm vpunpckhwd ymm0, ymm0, ymm2 /* BGRA next 8 pixels */ \ - __asm vmovdqu 0[edx], ymm1 \ - __asm vmovdqu 32[edx], ymm0 \ - __asm lea edx, [edx + 64]} - -// Store 16 RGBA values. -#define STORERGBA_AVX2 \ - __asm { \ - __asm vpunpcklbw ymm1, ymm1, ymm2 /* GR */ \ - __asm vpermq ymm1, ymm1, 0xd8 \ - __asm vpunpcklbw ymm2, ymm5, ymm0 /* AB */ \ - __asm vpermq ymm2, ymm2, 0xd8 \ - __asm vpunpcklwd ymm0, ymm2, ymm1 /* ABGR first 8 pixels */ \ - __asm vpunpckhwd ymm1, ymm2, ymm1 /* ABGR next 8 pixels */ \ - __asm vmovdqu [edx], ymm0 \ - __asm vmovdqu [edx + 32], ymm1 \ - __asm lea edx, [edx + 64]} - -#ifdef HAS_I422TOARGBROW_AVX2 -// 16 pixels -// 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 ARGB (64 bytes). -__declspec(naked) void I422ToARGBRow_AVX2( - const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push esi - push edi - push ebx - mov eax, [esp + 12 + 4] // Y - mov esi, [esp + 12 + 8] // U - mov edi, [esp + 12 + 12] // V - mov edx, [esp + 12 + 16] // argb - mov ebx, [esp + 12 + 20] // yuvconstants - mov ecx, [esp + 12 + 24] // width - sub edi, esi - vpcmpeqb ymm5, ymm5, ymm5 // generate 0xffffffffffffffff for alpha - - convertloop: - READYUV422_AVX2 - YUVTORGB_AVX2(ebx) - STOREARGB_AVX2 - - sub ecx, 16 - jg convertloop - - pop ebx - pop edi - pop esi - vzeroupper - ret - } -} -#endif // HAS_I422TOARGBROW_AVX2 - -#ifdef HAS_I422ALPHATOARGBROW_AVX2 -// 16 pixels -// 8 UV values upsampled to 16 UV, mixed with 16 Y and 16 A producing 16 ARGB. -__declspec(naked) void I422AlphaToARGBRow_AVX2( - const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - const uint8_t* a_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push esi - push edi - push ebx - push ebp - mov eax, [esp + 16 + 4] // Y - mov esi, [esp + 16 + 8] // U - mov edi, [esp + 16 + 12] // V - mov ebp, [esp + 16 + 16] // A - mov edx, [esp + 16 + 20] // argb - mov ebx, [esp + 16 + 24] // yuvconstants - mov ecx, [esp + 16 + 28] // width - sub edi, esi - - convertloop: - READYUVA422_AVX2 - YUVTORGB_AVX2(ebx) - STOREARGB_AVX2 - - sub ecx, 16 - jg convertloop - - pop ebp - pop ebx - pop edi - pop esi - vzeroupper - ret - } -} -#endif // HAS_I422ALPHATOARGBROW_AVX2 - -#ifdef HAS_I444TOARGBROW_AVX2 -// 16 pixels -// 16 UV values with 16 Y producing 16 ARGB (64 bytes). -__declspec(naked) void I444ToARGBRow_AVX2( - const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push esi - push edi - push ebx - mov eax, [esp + 12 + 4] // Y - mov esi, [esp + 12 + 8] // U - mov edi, [esp + 12 + 12] // V - mov edx, [esp + 12 + 16] // argb - mov ebx, [esp + 12 + 20] // yuvconstants - mov ecx, [esp + 12 + 24] // width - sub edi, esi - vpcmpeqb ymm5, ymm5, ymm5 // generate 0xffffffffffffffff for alpha - convertloop: - READYUV444_AVX2 - YUVTORGB_AVX2(ebx) - STOREARGB_AVX2 - - sub ecx, 16 - jg convertloop - - pop ebx - pop edi - pop esi - vzeroupper - ret - } -} -#endif // HAS_I444TOARGBROW_AVX2 - -#ifdef HAS_NV12TOARGBROW_AVX2 -// 16 pixels. -// 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 ARGB (64 bytes). -__declspec(naked) void NV12ToARGBRow_AVX2( - const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push esi - push ebx - mov eax, [esp + 8 + 4] // Y - mov esi, [esp + 8 + 8] // UV - mov edx, [esp + 8 + 12] // argb - mov ebx, [esp + 8 + 16] // yuvconstants - mov ecx, [esp + 8 + 20] // width - vpcmpeqb ymm5, ymm5, ymm5 // generate 0xffffffffffffffff for alpha - - convertloop: - READNV12_AVX2 - YUVTORGB_AVX2(ebx) - STOREARGB_AVX2 - - sub ecx, 16 - jg convertloop - - pop ebx - pop esi - vzeroupper - ret - } -} -#endif // HAS_NV12TOARGBROW_AVX2 - -#ifdef HAS_NV21TOARGBROW_AVX2 -// 16 pixels. -// 8 VU values upsampled to 16 UV, mixed with 16 Y producing 16 ARGB (64 bytes). -__declspec(naked) void NV21ToARGBRow_AVX2( - const uint8_t* y_buf, - const uint8_t* vu_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push esi - push ebx - mov eax, [esp + 8 + 4] // Y - mov esi, [esp + 8 + 8] // VU - mov edx, [esp + 8 + 12] // argb - mov ebx, [esp + 8 + 16] // yuvconstants - mov ecx, [esp + 8 + 20] // width - vpcmpeqb ymm5, ymm5, ymm5 // generate 0xffffffffffffffff for alpha - - convertloop: - READNV21_AVX2 - YUVTORGB_AVX2(ebx) - STOREARGB_AVX2 - - sub ecx, 16 - jg convertloop - - pop ebx - pop esi - vzeroupper - ret - } -} -#endif // HAS_NV21TOARGBROW_AVX2 - -#ifdef HAS_YUY2TOARGBROW_AVX2 -// 16 pixels. -// 8 YUY2 values with 16 Y and 8 UV producing 16 ARGB (64 bytes). -__declspec(naked) void YUY2ToARGBRow_AVX2( - const uint8_t* src_yuy2, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push ebx - mov eax, [esp + 4 + 4] // yuy2 - mov edx, [esp + 4 + 8] // argb - mov ebx, [esp + 4 + 12] // yuvconstants - mov ecx, [esp + 4 + 16] // width - vpcmpeqb ymm5, ymm5, ymm5 // generate 0xffffffffffffffff for alpha - - convertloop: - READYUY2_AVX2 - YUVTORGB_AVX2(ebx) - STOREARGB_AVX2 - - sub ecx, 16 - jg convertloop - - pop ebx - vzeroupper - ret - } -} -#endif // HAS_YUY2TOARGBROW_AVX2 - -#ifdef HAS_UYVYTOARGBROW_AVX2 -// 16 pixels. -// 8 UYVY values with 16 Y and 8 UV producing 16 ARGB (64 bytes). -__declspec(naked) void UYVYToARGBRow_AVX2( - const uint8_t* src_uyvy, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push ebx - mov eax, [esp + 4 + 4] // uyvy - mov edx, [esp + 4 + 8] // argb - mov ebx, [esp + 4 + 12] // yuvconstants - mov ecx, [esp + 4 + 16] // width - vpcmpeqb ymm5, ymm5, ymm5 // generate 0xffffffffffffffff for alpha - - convertloop: - READUYVY_AVX2 - YUVTORGB_AVX2(ebx) - STOREARGB_AVX2 - - sub ecx, 16 - jg convertloop - - pop ebx - vzeroupper - ret - } -} -#endif // HAS_UYVYTOARGBROW_AVX2 - -#ifdef HAS_I422TORGBAROW_AVX2 -// 16 pixels -// 8 UV values upsampled to 16 UV, mixed with 16 Y producing 16 RGBA (64 bytes). -__declspec(naked) void I422ToRGBARow_AVX2( - const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push esi - push edi - push ebx - mov eax, [esp + 12 + 4] // Y - mov esi, [esp + 12 + 8] // U - mov edi, [esp + 12 + 12] // V - mov edx, [esp + 12 + 16] // abgr - mov ebx, [esp + 12 + 20] // yuvconstants - mov ecx, [esp + 12 + 24] // width - sub edi, esi - vpcmpeqb ymm5, ymm5, ymm5 // generate 0xffffffffffffffff for alpha - - convertloop: - READYUV422_AVX2 - YUVTORGB_AVX2(ebx) - STORERGBA_AVX2 - - sub ecx, 16 - jg convertloop - - pop ebx - pop edi - pop esi - vzeroupper - ret - } -} -#endif // HAS_I422TORGBAROW_AVX2 - -#if defined(HAS_I422TOARGBROW_SSSE3) -// TODO(fbarchard): Read that does half size on Y and treats 420 as 444. -// Allows a conversion with half size scaling. - -// Read 8 UV from 444. -#define READYUV444 \ - __asm { \ - __asm movq xmm0, qword ptr [esi] /* U */ \ - __asm movq xmm1, qword ptr [esi + edi] /* V */ \ - __asm lea esi, [esi + 8] \ - __asm punpcklbw xmm0, xmm1 /* UV */ \ - __asm movq xmm4, qword ptr [eax] \ - __asm punpcklbw xmm4, xmm4 \ - __asm lea eax, [eax + 8]} - -// Read 4 UV from 422, upsample to 8 UV. -#define READYUV422 \ - __asm { \ - __asm movd xmm0, [esi] /* U */ \ - __asm movd xmm1, [esi + edi] /* V */ \ - __asm lea esi, [esi + 4] \ - __asm punpcklbw xmm0, xmm1 /* UV */ \ - __asm punpcklwd xmm0, xmm0 /* UVUV (upsample) */ \ - __asm movq xmm4, qword ptr [eax] \ - __asm punpcklbw xmm4, xmm4 \ - __asm lea eax, [eax + 8]} - -// Read 4 UV from 422, upsample to 8 UV. With 8 Alpha. -#define READYUVA422 \ - __asm { \ - __asm movd xmm0, [esi] /* U */ \ - __asm movd xmm1, [esi + edi] /* V */ \ - __asm lea esi, [esi + 4] \ - __asm punpcklbw xmm0, xmm1 /* UV */ \ - __asm punpcklwd xmm0, xmm0 /* UVUV (upsample) */ \ - __asm movq xmm4, qword ptr [eax] /* Y */ \ - __asm punpcklbw xmm4, xmm4 \ - __asm lea eax, [eax + 8] \ - __asm movq xmm5, qword ptr [ebp] /* A */ \ - __asm lea ebp, [ebp + 8]} - -// Read 4 UV from NV12, upsample to 8 UV. -#define READNV12 \ - __asm { \ - __asm movq xmm0, qword ptr [esi] /* UV */ \ - __asm lea esi, [esi + 8] \ - __asm punpcklwd xmm0, xmm0 /* UVUV (upsample) */ \ - __asm movq xmm4, qword ptr [eax] \ - __asm punpcklbw xmm4, xmm4 \ - __asm lea eax, [eax + 8]} - -// Read 4 VU from NV21, upsample to 8 UV. -#define READNV21 \ - __asm { \ - __asm movq xmm0, qword ptr [esi] /* UV */ \ - __asm lea esi, [esi + 8] \ - __asm pshufb xmm0, xmmword ptr kShuffleNV21 \ - __asm movq xmm4, qword ptr [eax] \ - __asm punpcklbw xmm4, xmm4 \ - __asm lea eax, [eax + 8]} - -// Read 4 YUY2 with 8 Y and upsample 4 UV to 8 UV. -#define READYUY2 \ - __asm { \ - __asm movdqu xmm4, [eax] /* YUY2 */ \ - __asm pshufb xmm4, xmmword ptr kShuffleYUY2Y \ - __asm movdqu xmm0, [eax] /* UV */ \ - __asm pshufb xmm0, xmmword ptr kShuffleYUY2UV \ - __asm lea eax, [eax + 16]} - -// Read 4 UYVY with 8 Y and upsample 4 UV to 8 UV. -#define READUYVY \ - __asm { \ - __asm movdqu xmm4, [eax] /* UYVY */ \ - __asm pshufb xmm4, xmmword ptr kShuffleUYVYY \ - __asm movdqu xmm0, [eax] /* UV */ \ - __asm pshufb xmm0, xmmword ptr kShuffleUYVYUV \ - __asm lea eax, [eax + 16]} - -// Convert 8 pixels: 8 UV and 8 Y. -#define YUVTORGB(YuvConstants) \ - __asm { \ - __asm movdqa xmm1, xmm0 \ - __asm movdqa xmm2, xmm0 \ - __asm movdqa xmm3, xmm0 \ - __asm movdqa xmm0, xmmword ptr [YuvConstants + KUVBIASB] \ - __asm pmaddubsw xmm1, xmmword ptr [YuvConstants + KUVTOB] \ - __asm psubw xmm0, xmm1 \ - __asm movdqa xmm1, xmmword ptr [YuvConstants + KUVBIASG] \ - __asm pmaddubsw xmm2, xmmword ptr [YuvConstants + KUVTOG] \ - __asm psubw xmm1, xmm2 \ - __asm movdqa xmm2, xmmword ptr [YuvConstants + KUVBIASR] \ - __asm pmaddubsw xmm3, xmmword ptr [YuvConstants + KUVTOR] \ - __asm psubw xmm2, xmm3 \ - __asm pmulhuw xmm4, xmmword ptr [YuvConstants + KYTORGB] \ - __asm paddsw xmm0, xmm4 /* B += Y */ \ - __asm paddsw xmm1, xmm4 /* G += Y */ \ - __asm paddsw xmm2, xmm4 /* R += Y */ \ - __asm psraw xmm0, 6 \ - __asm psraw xmm1, 6 \ - __asm psraw xmm2, 6 \ - __asm packuswb xmm0, xmm0 /* B */ \ - __asm packuswb xmm1, xmm1 /* G */ \ - __asm packuswb xmm2, xmm2 /* R */ \ - } - -// Store 8 ARGB values. -#define STOREARGB \ - __asm { \ - __asm punpcklbw xmm0, xmm1 /* BG */ \ - __asm punpcklbw xmm2, xmm5 /* RA */ \ - __asm movdqa xmm1, xmm0 \ - __asm punpcklwd xmm0, xmm2 /* BGRA first 4 pixels */ \ - __asm punpckhwd xmm1, xmm2 /* BGRA next 4 pixels */ \ - __asm movdqu 0[edx], xmm0 \ - __asm movdqu 16[edx], xmm1 \ - __asm lea edx, [edx + 32]} - -// Store 8 BGRA values. -#define STOREBGRA \ - __asm { \ - __asm pcmpeqb xmm5, xmm5 /* generate 0xffffffff for alpha */ \ - __asm punpcklbw xmm1, xmm0 /* GB */ \ - __asm punpcklbw xmm5, xmm2 /* AR */ \ - __asm movdqa xmm0, xmm5 \ - __asm punpcklwd xmm5, xmm1 /* BGRA first 4 pixels */ \ - __asm punpckhwd xmm0, xmm1 /* BGRA next 4 pixels */ \ - __asm movdqu 0[edx], xmm5 \ - __asm movdqu 16[edx], xmm0 \ - __asm lea edx, [edx + 32]} - -// Store 8 RGBA values. -#define STORERGBA \ - __asm { \ - __asm pcmpeqb xmm5, xmm5 /* generate 0xffffffff for alpha */ \ - __asm punpcklbw xmm1, xmm2 /* GR */ \ - __asm punpcklbw xmm5, xmm0 /* AB */ \ - __asm movdqa xmm0, xmm5 \ - __asm punpcklwd xmm5, xmm1 /* RGBA first 4 pixels */ \ - __asm punpckhwd xmm0, xmm1 /* RGBA next 4 pixels */ \ - __asm movdqu 0[edx], xmm5 \ - __asm movdqu 16[edx], xmm0 \ - __asm lea edx, [edx + 32]} - -// Store 8 RGB24 values. -#define STORERGB24 \ - __asm {/* Weave into RRGB */ \ - __asm punpcklbw xmm0, xmm1 /* BG */ \ - __asm punpcklbw xmm2, xmm2 /* RR */ \ - __asm movdqa xmm1, xmm0 \ - __asm punpcklwd xmm0, xmm2 /* BGRR first 4 pixels */ \ - __asm punpckhwd xmm1, xmm2 /* BGRR next 4 pixels */ /* RRGB -> RGB24 */ \ - __asm pshufb xmm0, xmm5 /* Pack first 8 and last 4 bytes. */ \ - __asm pshufb xmm1, xmm6 /* Pack first 12 bytes. */ \ - __asm palignr xmm1, xmm0, 12 /* last 4 bytes of xmm0 + 12 xmm1 */ \ - __asm movq qword ptr 0[edx], xmm0 /* First 8 bytes */ \ - __asm movdqu 8[edx], xmm1 /* Last 16 bytes */ \ - __asm lea edx, [edx + 24]} - -// Store 8 RGB565 values. -#define STORERGB565 \ - __asm {/* Weave into RRGB */ \ - __asm punpcklbw xmm0, xmm1 /* BG */ \ - __asm punpcklbw xmm2, xmm2 /* RR */ \ - __asm movdqa xmm1, xmm0 \ - __asm punpcklwd xmm0, xmm2 /* BGRR first 4 pixels */ \ - __asm punpckhwd xmm1, xmm2 /* BGRR next 4 pixels */ /* RRGB -> RGB565 */ \ - __asm movdqa xmm3, xmm0 /* B first 4 pixels of argb */ \ - __asm movdqa xmm2, xmm0 /* G */ \ - __asm pslld xmm0, 8 /* R */ \ - __asm psrld xmm3, 3 /* B */ \ - __asm psrld xmm2, 5 /* G */ \ - __asm psrad xmm0, 16 /* R */ \ - __asm pand xmm3, xmm5 /* B */ \ - __asm pand xmm2, xmm6 /* G */ \ - __asm pand xmm0, xmm7 /* R */ \ - __asm por xmm3, xmm2 /* BG */ \ - __asm por xmm0, xmm3 /* BGR */ \ - __asm movdqa xmm3, xmm1 /* B next 4 pixels of argb */ \ - __asm movdqa xmm2, xmm1 /* G */ \ - __asm pslld xmm1, 8 /* R */ \ - __asm psrld xmm3, 3 /* B */ \ - __asm psrld xmm2, 5 /* G */ \ - __asm psrad xmm1, 16 /* R */ \ - __asm pand xmm3, xmm5 /* B */ \ - __asm pand xmm2, xmm6 /* G */ \ - __asm pand xmm1, xmm7 /* R */ \ - __asm por xmm3, xmm2 /* BG */ \ - __asm por xmm1, xmm3 /* BGR */ \ - __asm packssdw xmm0, xmm1 \ - __asm movdqu 0[edx], xmm0 /* store 8 pixels of RGB565 */ \ - __asm lea edx, [edx + 16]} - -// 8 pixels. -// 8 UV values, mixed with 8 Y producing 8 ARGB (32 bytes). -__declspec(naked) void I444ToARGBRow_SSSE3( - const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push esi - push edi - push ebx - mov eax, [esp + 12 + 4] // Y - mov esi, [esp + 12 + 8] // U - mov edi, [esp + 12 + 12] // V - mov edx, [esp + 12 + 16] // argb - mov ebx, [esp + 12 + 20] // yuvconstants - mov ecx, [esp + 12 + 24] // width - sub edi, esi - pcmpeqb xmm5, xmm5 // generate 0xffffffff for alpha - - convertloop: - READYUV444 - YUVTORGB(ebx) - STOREARGB - - sub ecx, 8 - jg convertloop - - pop ebx - pop edi - pop esi - ret - } -} - -// 8 pixels. -// 4 UV values upsampled to 8 UV, mixed with 8 Y producing 8 RGB24 (24 bytes). -__declspec(naked) void I422ToRGB24Row_SSSE3( - const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_rgb24, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push esi - push edi - push ebx - mov eax, [esp + 12 + 4] // Y - mov esi, [esp + 12 + 8] // U - mov edi, [esp + 12 + 12] // V - mov edx, [esp + 12 + 16] // argb - mov ebx, [esp + 12 + 20] // yuvconstants - mov ecx, [esp + 12 + 24] // width - sub edi, esi - movdqa xmm5, xmmword ptr kShuffleMaskARGBToRGB24_0 - movdqa xmm6, xmmword ptr kShuffleMaskARGBToRGB24 - - convertloop: - READYUV422 - YUVTORGB(ebx) - STORERGB24 - - sub ecx, 8 - jg convertloop - - pop ebx - pop edi - pop esi - ret - } -} - -// 8 pixels -// 4 UV values upsampled to 8 UV, mixed with 8 Y producing 8 RGB565 (16 bytes). -__declspec(naked) void I422ToRGB565Row_SSSE3( - const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* rgb565_buf, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push esi - push edi - push ebx - mov eax, [esp + 12 + 4] // Y - mov esi, [esp + 12 + 8] // U - mov edi, [esp + 12 + 12] // V - mov edx, [esp + 12 + 16] // argb - mov ebx, [esp + 12 + 20] // yuvconstants - mov ecx, [esp + 12 + 24] // width - sub edi, esi - pcmpeqb xmm5, xmm5 // generate mask 0x0000001f - psrld xmm5, 27 - pcmpeqb xmm6, xmm6 // generate mask 0x000007e0 - psrld xmm6, 26 - pslld xmm6, 5 - pcmpeqb xmm7, xmm7 // generate mask 0xfffff800 - pslld xmm7, 11 - - convertloop: - READYUV422 - YUVTORGB(ebx) - STORERGB565 - - sub ecx, 8 - jg convertloop - - pop ebx - pop edi - pop esi - ret - } -} - -// 8 pixels. -// 4 UV values upsampled to 8 UV, mixed with 8 Y producing 8 ARGB (32 bytes). -__declspec(naked) void I422ToARGBRow_SSSE3( - const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push esi - push edi - push ebx - mov eax, [esp + 12 + 4] // Y - mov esi, [esp + 12 + 8] // U - mov edi, [esp + 12 + 12] // V - mov edx, [esp + 12 + 16] // argb - mov ebx, [esp + 12 + 20] // yuvconstants - mov ecx, [esp + 12 + 24] // width - sub edi, esi - pcmpeqb xmm5, xmm5 // generate 0xffffffff for alpha - - convertloop: - READYUV422 - YUVTORGB(ebx) - STOREARGB - - sub ecx, 8 - jg convertloop - - pop ebx - pop edi - pop esi - ret - } -} - -// 8 pixels. -// 4 UV values upsampled to 8 UV, mixed with 8 Y and 8 A producing 8 ARGB. -__declspec(naked) void I422AlphaToARGBRow_SSSE3( - const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - const uint8_t* a_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push esi - push edi - push ebx - push ebp - mov eax, [esp + 16 + 4] // Y - mov esi, [esp + 16 + 8] // U - mov edi, [esp + 16 + 12] // V - mov ebp, [esp + 16 + 16] // A - mov edx, [esp + 16 + 20] // argb - mov ebx, [esp + 16 + 24] // yuvconstants - mov ecx, [esp + 16 + 28] // width - sub edi, esi - - convertloop: - READYUVA422 - YUVTORGB(ebx) - STOREARGB - - sub ecx, 8 - jg convertloop - - pop ebp - pop ebx - pop edi - pop esi - ret - } -} - -// 8 pixels. -// 4 UV values upsampled to 8 UV, mixed with 8 Y producing 8 ARGB (32 bytes). -__declspec(naked) void NV12ToARGBRow_SSSE3( - const uint8_t* y_buf, - const uint8_t* uv_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push esi - push ebx - mov eax, [esp + 8 + 4] // Y - mov esi, [esp + 8 + 8] // UV - mov edx, [esp + 8 + 12] // argb - mov ebx, [esp + 8 + 16] // yuvconstants - mov ecx, [esp + 8 + 20] // width - pcmpeqb xmm5, xmm5 // generate 0xffffffff for alpha - - convertloop: - READNV12 - YUVTORGB(ebx) - STOREARGB - - sub ecx, 8 - jg convertloop - - pop ebx - pop esi - ret - } -} - -// 8 pixels. -// 4 UV values upsampled to 8 UV, mixed with 8 Y producing 8 ARGB (32 bytes). -__declspec(naked) void NV21ToARGBRow_SSSE3( - const uint8_t* y_buf, - const uint8_t* vu_buf, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push esi - push ebx - mov eax, [esp + 8 + 4] // Y - mov esi, [esp + 8 + 8] // VU - mov edx, [esp + 8 + 12] // argb - mov ebx, [esp + 8 + 16] // yuvconstants - mov ecx, [esp + 8 + 20] // width - pcmpeqb xmm5, xmm5 // generate 0xffffffff for alpha - - convertloop: - READNV21 - YUVTORGB(ebx) - STOREARGB - - sub ecx, 8 - jg convertloop - - pop ebx - pop esi - ret - } -} - -// 8 pixels. -// 4 YUY2 values with 8 Y and 4 UV producing 8 ARGB (32 bytes). -__declspec(naked) void YUY2ToARGBRow_SSSE3( - const uint8_t* src_yuy2, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push ebx - mov eax, [esp + 4 + 4] // yuy2 - mov edx, [esp + 4 + 8] // argb - mov ebx, [esp + 4 + 12] // yuvconstants - mov ecx, [esp + 4 + 16] // width - pcmpeqb xmm5, xmm5 // generate 0xffffffff for alpha - - convertloop: - READYUY2 - YUVTORGB(ebx) - STOREARGB - - sub ecx, 8 - jg convertloop - - pop ebx - ret - } -} - -// 8 pixels. -// 4 UYVY values with 8 Y and 4 UV producing 8 ARGB (32 bytes). -__declspec(naked) void UYVYToARGBRow_SSSE3( - const uint8_t* src_uyvy, - uint8_t* dst_argb, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push ebx - mov eax, [esp + 4 + 4] // uyvy - mov edx, [esp + 4 + 8] // argb - mov ebx, [esp + 4 + 12] // yuvconstants - mov ecx, [esp + 4 + 16] // width - pcmpeqb xmm5, xmm5 // generate 0xffffffff for alpha - - convertloop: - READUYVY - YUVTORGB(ebx) - STOREARGB - - sub ecx, 8 - jg convertloop - - pop ebx - ret - } -} - -__declspec(naked) void I422ToRGBARow_SSSE3( - const uint8_t* y_buf, - const uint8_t* u_buf, - const uint8_t* v_buf, - uint8_t* dst_rgba, - const struct YuvConstants* yuvconstants, - int width) { - __asm { - push esi - push edi - push ebx - mov eax, [esp + 12 + 4] // Y - mov esi, [esp + 12 + 8] // U - mov edi, [esp + 12 + 12] // V - mov edx, [esp + 12 + 16] // argb - mov ebx, [esp + 12 + 20] // yuvconstants - mov ecx, [esp + 12 + 24] // width - sub edi, esi - - convertloop: - READYUV422 - YUVTORGB(ebx) - STORERGBA - - sub ecx, 8 - jg convertloop - - pop ebx - pop edi - pop esi - ret - } -} -#endif // HAS_I422TOARGBROW_SSSE3 - -#ifdef HAS_I400TOARGBROW_SSE2 -// 8 pixels of Y converted to 8 pixels of ARGB (32 bytes). -__declspec(naked) void I400ToARGBRow_SSE2(const uint8_t* y_buf, - uint8_t* rgb_buf, - int width) { - __asm { - mov eax, 0x4a354a35 // 4a35 = 18997 = round(1.164 * 64 * 256) - movd xmm2, eax - pshufd xmm2, xmm2,0 - mov eax, 0x04880488 // 0488 = 1160 = round(1.164 * 64 * 16) - movd xmm3, eax - pshufd xmm3, xmm3, 0 - pcmpeqb xmm4, xmm4 // generate mask 0xff000000 - pslld xmm4, 24 - - mov eax, [esp + 4] // Y - mov edx, [esp + 8] // rgb - mov ecx, [esp + 12] // width - - convertloop: - // Step 1: Scale Y contribution to 8 G values. G = (y - 16) * 1.164 - movq xmm0, qword ptr [eax] - lea eax, [eax + 8] - punpcklbw xmm0, xmm0 // Y.Y - pmulhuw xmm0, xmm2 - psubusw xmm0, xmm3 - psrlw xmm0, 6 - packuswb xmm0, xmm0 // G - - // Step 2: Weave into ARGB - punpcklbw xmm0, xmm0 // GG - movdqa xmm1, xmm0 - punpcklwd xmm0, xmm0 // BGRA first 4 pixels - punpckhwd xmm1, xmm1 // BGRA next 4 pixels - por xmm0, xmm4 - por xmm1, xmm4 - movdqu [edx], xmm0 - movdqu [edx + 16], xmm1 - lea edx, [edx + 32] - sub ecx, 8 - jg convertloop - ret - } -} -#endif // HAS_I400TOARGBROW_SSE2 - -#ifdef HAS_I400TOARGBROW_AVX2 -// 16 pixels of Y converted to 16 pixels of ARGB (64 bytes). -// note: vpunpcklbw mutates and vpackuswb unmutates. -__declspec(naked) void I400ToARGBRow_AVX2(const uint8_t* y_buf, - uint8_t* rgb_buf, - int width) { - __asm { - mov eax, 0x4a354a35 // 4a35 = 18997 = round(1.164 * 64 * 256) - vmovd xmm2, eax - vbroadcastss ymm2, xmm2 - mov eax, 0x04880488 // 0488 = 1160 = round(1.164 * 64 * 16) - vmovd xmm3, eax - vbroadcastss ymm3, xmm3 - vpcmpeqb ymm4, ymm4, ymm4 // generate mask 0xff000000 - vpslld ymm4, ymm4, 24 - - mov eax, [esp + 4] // Y - mov edx, [esp + 8] // rgb - mov ecx, [esp + 12] // width - - convertloop: - // Step 1: Scale Y contriportbution to 16 G values. G = (y - 16) * 1.164 - vmovdqu xmm0, [eax] - lea eax, [eax + 16] - vpermq ymm0, ymm0, 0xd8 // vpunpcklbw mutates - vpunpcklbw ymm0, ymm0, ymm0 // Y.Y - vpmulhuw ymm0, ymm0, ymm2 - vpsubusw ymm0, ymm0, ymm3 - vpsrlw ymm0, ymm0, 6 - vpackuswb ymm0, ymm0, ymm0 // G. still mutated: 3120 - - // TODO(fbarchard): Weave alpha with unpack. - // Step 2: Weave into ARGB - vpunpcklbw ymm1, ymm0, ymm0 // GG - mutates - vpermq ymm1, ymm1, 0xd8 - vpunpcklwd ymm0, ymm1, ymm1 // GGGG first 8 pixels - vpunpckhwd ymm1, ymm1, ymm1 // GGGG next 8 pixels - vpor ymm0, ymm0, ymm4 - vpor ymm1, ymm1, ymm4 - vmovdqu [edx], ymm0 - vmovdqu [edx + 32], ymm1 - lea edx, [edx + 64] - sub ecx, 16 - jg convertloop - vzeroupper - ret - } -} -#endif // HAS_I400TOARGBROW_AVX2 - -#ifdef HAS_MIRRORROW_SSSE3 -// Shuffle table for reversing the bytes. -static const uvec8 kShuffleMirror = {15u, 14u, 13u, 12u, 11u, 10u, 9u, 8u, - 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u}; - -// TODO(fbarchard): Replace lea with -16 offset. -__declspec(naked) void MirrorRow_SSSE3(const uint8_t* src, - uint8_t* dst, - int width) { - __asm { - mov eax, [esp + 4] // src - mov edx, [esp + 8] // dst - mov ecx, [esp + 12] // width - movdqa xmm5, xmmword ptr kShuffleMirror - - convertloop: - movdqu xmm0, [eax - 16 + ecx] - pshufb xmm0, xmm5 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 16 - jg convertloop - ret - } -} -#endif // HAS_MIRRORROW_SSSE3 - -#ifdef HAS_MIRRORROW_AVX2 -__declspec(naked) void MirrorRow_AVX2(const uint8_t* src, - uint8_t* dst, - int width) { - __asm { - mov eax, [esp + 4] // src - mov edx, [esp + 8] // dst - mov ecx, [esp + 12] // width - vbroadcastf128 ymm5, xmmword ptr kShuffleMirror - - convertloop: - vmovdqu ymm0, [eax - 32 + ecx] - vpshufb ymm0, ymm0, ymm5 - vpermq ymm0, ymm0, 0x4e // swap high and low halfs - vmovdqu [edx], ymm0 - lea edx, [edx + 32] - sub ecx, 32 - jg convertloop - vzeroupper - ret - } -} -#endif // HAS_MIRRORROW_AVX2 - -#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}; - -__declspec(naked) void MirrorUVRow_SSSE3(const uint8_t* src, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - __asm { - push edi - mov eax, [esp + 4 + 4] // src - mov edx, [esp + 4 + 8] // dst_u - mov edi, [esp + 4 + 12] // dst_v - mov ecx, [esp + 4 + 16] // width - movdqa xmm1, xmmword ptr kShuffleMirrorUV - lea eax, [eax + ecx * 2 - 16] - sub edi, edx - - convertloop: - movdqu xmm0, [eax] - lea eax, [eax - 16] - pshufb xmm0, xmm1 - movlpd qword ptr [edx], xmm0 - movhpd qword ptr [edx + edi], xmm0 - lea edx, [edx + 8] - sub ecx, 8 - jg convertloop - - pop edi - ret - } -} -#endif // HAS_MIRRORUVROW_SSSE3 - -#ifdef HAS_ARGBMIRRORROW_SSE2 -__declspec(naked) void ARGBMirrorRow_SSE2(const uint8_t* src, - uint8_t* dst, - int width) { - __asm { - mov eax, [esp + 4] // src - mov edx, [esp + 8] // dst - mov ecx, [esp + 12] // width - lea eax, [eax - 16 + ecx * 4] // last 4 pixels. - - convertloop: - movdqu xmm0, [eax] - lea eax, [eax - 16] - pshufd xmm0, xmm0, 0x1b - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 4 - jg convertloop - ret - } -} -#endif // HAS_ARGBMIRRORROW_SSE2 - -#ifdef HAS_ARGBMIRRORROW_AVX2 -// Shuffle table for reversing the bytes. -static const ulvec32 kARGBShuffleMirror_AVX2 = {7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u}; - -__declspec(naked) void ARGBMirrorRow_AVX2(const uint8_t* src, - uint8_t* dst, - int width) { - __asm { - mov eax, [esp + 4] // src - mov edx, [esp + 8] // dst - mov ecx, [esp + 12] // width - vmovdqu ymm5, ymmword ptr kARGBShuffleMirror_AVX2 - - convertloop: - vpermd ymm0, ymm5, [eax - 32 + ecx * 4] // permute dword order - vmovdqu [edx], ymm0 - lea edx, [edx + 32] - sub ecx, 8 - jg convertloop - vzeroupper - ret - } -} -#endif // HAS_ARGBMIRRORROW_AVX2 - -#ifdef HAS_SPLITUVROW_SSE2 -__declspec(naked) void SplitUVRow_SSE2(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - __asm { - push edi - mov eax, [esp + 4 + 4] // src_uv - mov edx, [esp + 4 + 8] // dst_u - mov edi, [esp + 4 + 12] // dst_v - mov ecx, [esp + 4 + 16] // width - pcmpeqb xmm5, xmm5 // generate mask 0x00ff00ff - psrlw xmm5, 8 - sub edi, edx - - convertloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - lea eax, [eax + 32] - movdqa xmm2, xmm0 - movdqa xmm3, xmm1 - pand xmm0, xmm5 // even bytes - pand xmm1, xmm5 - packuswb xmm0, xmm1 - psrlw xmm2, 8 // odd bytes - psrlw xmm3, 8 - packuswb xmm2, xmm3 - movdqu [edx], xmm0 - movdqu [edx + edi], xmm2 - lea edx, [edx + 16] - sub ecx, 16 - jg convertloop - - pop edi - ret - } -} - -#endif // HAS_SPLITUVROW_SSE2 - -#ifdef HAS_SPLITUVROW_AVX2 -__declspec(naked) void SplitUVRow_AVX2(const uint8_t* src_uv, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - __asm { - push edi - mov eax, [esp + 4 + 4] // src_uv - mov edx, [esp + 4 + 8] // dst_u - mov edi, [esp + 4 + 12] // dst_v - mov ecx, [esp + 4 + 16] // width - vpcmpeqb ymm5, ymm5, ymm5 // generate mask 0x00ff00ff - vpsrlw ymm5, ymm5, 8 - sub edi, edx - - convertloop: - vmovdqu ymm0, [eax] - vmovdqu ymm1, [eax + 32] - lea eax, [eax + 64] - vpsrlw ymm2, ymm0, 8 // odd bytes - vpsrlw ymm3, ymm1, 8 - vpand ymm0, ymm0, ymm5 // even bytes - vpand ymm1, ymm1, ymm5 - vpackuswb ymm0, ymm0, ymm1 - vpackuswb ymm2, ymm2, ymm3 - vpermq ymm0, ymm0, 0xd8 - vpermq ymm2, ymm2, 0xd8 - vmovdqu [edx], ymm0 - vmovdqu [edx + edi], ymm2 - lea edx, [edx + 32] - sub ecx, 32 - jg convertloop - - pop edi - vzeroupper - ret - } -} -#endif // HAS_SPLITUVROW_AVX2 - -#ifdef HAS_MERGEUVROW_SSE2 -__declspec(naked) void MergeUVRow_SSE2(const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uv, - int width) { - __asm { - push edi - mov eax, [esp + 4 + 4] // src_u - mov edx, [esp + 4 + 8] // src_v - mov edi, [esp + 4 + 12] // dst_uv - mov ecx, [esp + 4 + 16] // width - sub edx, eax - - convertloop: - movdqu xmm0, [eax] // read 16 U's - movdqu xmm1, [eax + edx] // and 16 V's - lea eax, [eax + 16] - movdqa xmm2, xmm0 - punpcklbw xmm0, xmm1 // first 8 UV pairs - punpckhbw xmm2, xmm1 // next 8 UV pairs - movdqu [edi], xmm0 - movdqu [edi + 16], xmm2 - lea edi, [edi + 32] - sub ecx, 16 - jg convertloop - - pop edi - ret - } -} -#endif // HAS_MERGEUVROW_SSE2 - -#ifdef HAS_MERGEUVROW_AVX2 -__declspec(naked) void MergeUVRow_AVX2(const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_uv, - int width) { - __asm { - push edi - mov eax, [esp + 4 + 4] // src_u - mov edx, [esp + 4 + 8] // src_v - mov edi, [esp + 4 + 12] // dst_uv - mov ecx, [esp + 4 + 16] // width - sub edx, eax - - convertloop: - vmovdqu ymm0, [eax] // read 32 U's - vmovdqu ymm1, [eax + edx] // and 32 V's - lea eax, [eax + 32] - vpunpcklbw ymm2, ymm0, ymm1 // low 16 UV pairs. mutated qqword 0,2 - vpunpckhbw ymm0, ymm0, ymm1 // high 16 UV pairs. mutated qqword 1,3 - vextractf128 [edi], ymm2, 0 // bytes 0..15 - vextractf128 [edi + 16], ymm0, 0 // bytes 16..31 - vextractf128 [edi + 32], ymm2, 1 // bytes 32..47 - vextractf128 [edi + 48], ymm0, 1 // bytes 47..63 - lea edi, [edi + 64] - sub ecx, 32 - jg convertloop - - pop edi - vzeroupper - ret - } -} -#endif // HAS_MERGEUVROW_AVX2 - -#ifdef HAS_COPYROW_SSE2 -// CopyRow copys 'width' bytes using a 16 byte load/store, 32 bytes at time. -__declspec(naked) void CopyRow_SSE2(const uint8_t* src, - uint8_t* dst, - int width) { - __asm { - mov eax, [esp + 4] // src - mov edx, [esp + 8] // dst - mov ecx, [esp + 12] // width - test eax, 15 - jne convertloopu - test edx, 15 - jne convertloopu - - convertloopa: - movdqa xmm0, [eax] - movdqa xmm1, [eax + 16] - lea eax, [eax + 32] - movdqa [edx], xmm0 - movdqa [edx + 16], xmm1 - lea edx, [edx + 32] - sub ecx, 32 - jg convertloopa - ret - - convertloopu: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - lea eax, [eax + 32] - movdqu [edx], xmm0 - movdqu [edx + 16], xmm1 - lea edx, [edx + 32] - sub ecx, 32 - jg convertloopu - ret - } -} -#endif // HAS_COPYROW_SSE2 - -#ifdef HAS_COPYROW_AVX -// CopyRow copys 'width' bytes using a 32 byte load/store, 64 bytes at time. -__declspec(naked) void CopyRow_AVX(const uint8_t* src, - uint8_t* dst, - int width) { - __asm { - mov eax, [esp + 4] // src - mov edx, [esp + 8] // dst - mov ecx, [esp + 12] // width - - convertloop: - vmovdqu ymm0, [eax] - vmovdqu ymm1, [eax + 32] - lea eax, [eax + 64] - vmovdqu [edx], ymm0 - vmovdqu [edx + 32], ymm1 - lea edx, [edx + 64] - sub ecx, 64 - jg convertloop - - vzeroupper - ret - } -} -#endif // HAS_COPYROW_AVX - -// Multiple of 1. -__declspec(naked) void CopyRow_ERMS(const uint8_t* src, - uint8_t* dst, - int width) { - __asm { - mov eax, esi - mov edx, edi - mov esi, [esp + 4] // src - mov edi, [esp + 8] // dst - mov ecx, [esp + 12] // width - rep movsb - mov edi, edx - mov esi, eax - ret - } -} - -#ifdef HAS_ARGBCOPYALPHAROW_SSE2 -// width in pixels -__declspec(naked) void ARGBCopyAlphaRow_SSE2(const uint8_t* src, - uint8_t* dst, - int width) { - __asm { - mov eax, [esp + 4] // src - mov edx, [esp + 8] // dst - mov ecx, [esp + 12] // width - pcmpeqb xmm0, xmm0 // generate mask 0xff000000 - pslld xmm0, 24 - pcmpeqb xmm1, xmm1 // generate mask 0x00ffffff - psrld xmm1, 8 - - convertloop: - movdqu xmm2, [eax] - movdqu xmm3, [eax + 16] - lea eax, [eax + 32] - movdqu xmm4, [edx] - movdqu xmm5, [edx + 16] - pand xmm2, xmm0 - pand xmm3, xmm0 - pand xmm4, xmm1 - pand xmm5, xmm1 - por xmm2, xmm4 - por xmm3, xmm5 - movdqu [edx], xmm2 - movdqu [edx + 16], xmm3 - lea edx, [edx + 32] - sub ecx, 8 - jg convertloop - - ret - } -} -#endif // HAS_ARGBCOPYALPHAROW_SSE2 - -#ifdef HAS_ARGBCOPYALPHAROW_AVX2 -// width in pixels -__declspec(naked) void ARGBCopyAlphaRow_AVX2(const uint8_t* src, - uint8_t* dst, - int width) { - __asm { - mov eax, [esp + 4] // src - mov edx, [esp + 8] // dst - mov ecx, [esp + 12] // width - vpcmpeqb ymm0, ymm0, ymm0 - vpsrld ymm0, ymm0, 8 // generate mask 0x00ffffff - - convertloop: - vmovdqu ymm1, [eax] - vmovdqu ymm2, [eax + 32] - lea eax, [eax + 64] - vpblendvb ymm1, ymm1, [edx], ymm0 - vpblendvb ymm2, ymm2, [edx + 32], ymm0 - vmovdqu [edx], ymm1 - vmovdqu [edx + 32], ymm2 - lea edx, [edx + 64] - sub ecx, 16 - jg convertloop - - vzeroupper - ret - } -} -#endif // HAS_ARGBCOPYALPHAROW_AVX2 - -#ifdef HAS_ARGBEXTRACTALPHAROW_SSE2 -// width in pixels -__declspec(naked) void ARGBExtractAlphaRow_SSE2(const uint8_t* src_argb, - uint8_t* dst_a, - int width) { - __asm { - mov eax, [esp + 4] // src_argb - mov edx, [esp + 8] // dst_a - mov ecx, [esp + 12] // width - - extractloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - lea eax, [eax + 32] - psrld xmm0, 24 - psrld xmm1, 24 - packssdw xmm0, xmm1 - packuswb xmm0, xmm0 - movq qword ptr [edx], xmm0 - lea edx, [edx + 8] - sub ecx, 8 - jg extractloop - - ret - } -} -#endif // HAS_ARGBEXTRACTALPHAROW_SSE2 - -#ifdef HAS_ARGBEXTRACTALPHAROW_AVX2 -// width in pixels -__declspec(naked) void ARGBExtractAlphaRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_a, - int width) { - __asm { - mov eax, [esp + 4] // src_argb - mov edx, [esp + 8] // dst_a - mov ecx, [esp + 12] // width - vmovdqa ymm4, ymmword ptr kPermdARGBToY_AVX - - extractloop: - vmovdqu ymm0, [eax] - vmovdqu ymm1, [eax + 32] - vpsrld ymm0, ymm0, 24 - vpsrld ymm1, ymm1, 24 - vmovdqu ymm2, [eax + 64] - vmovdqu ymm3, [eax + 96] - lea eax, [eax + 128] - vpackssdw ymm0, ymm0, ymm1 // mutates - vpsrld ymm2, ymm2, 24 - vpsrld ymm3, ymm3, 24 - vpackssdw ymm2, ymm2, ymm3 // mutates - vpackuswb ymm0, ymm0, ymm2 // mutates - vpermd ymm0, ymm4, ymm0 // unmutate - vmovdqu [edx], ymm0 - lea edx, [edx + 32] - sub ecx, 32 - jg extractloop - - vzeroupper - ret - } -} -#endif // HAS_ARGBEXTRACTALPHAROW_AVX2 - -#ifdef HAS_ARGBCOPYYTOALPHAROW_SSE2 -// width in pixels -__declspec(naked) void ARGBCopyYToAlphaRow_SSE2(const uint8_t* src, - uint8_t* dst, - int width) { - __asm { - mov eax, [esp + 4] // src - mov edx, [esp + 8] // dst - mov ecx, [esp + 12] // width - pcmpeqb xmm0, xmm0 // generate mask 0xff000000 - pslld xmm0, 24 - pcmpeqb xmm1, xmm1 // generate mask 0x00ffffff - psrld xmm1, 8 - - convertloop: - movq xmm2, qword ptr [eax] // 8 Y's - lea eax, [eax + 8] - punpcklbw xmm2, xmm2 - punpckhwd xmm3, xmm2 - punpcklwd xmm2, xmm2 - movdqu xmm4, [edx] - movdqu xmm5, [edx + 16] - pand xmm2, xmm0 - pand xmm3, xmm0 - pand xmm4, xmm1 - pand xmm5, xmm1 - por xmm2, xmm4 - por xmm3, xmm5 - movdqu [edx], xmm2 - movdqu [edx + 16], xmm3 - lea edx, [edx + 32] - sub ecx, 8 - jg convertloop - - ret - } -} -#endif // HAS_ARGBCOPYYTOALPHAROW_SSE2 - -#ifdef HAS_ARGBCOPYYTOALPHAROW_AVX2 -// width in pixels -__declspec(naked) void ARGBCopyYToAlphaRow_AVX2(const uint8_t* src, - uint8_t* dst, - int width) { - __asm { - mov eax, [esp + 4] // src - mov edx, [esp + 8] // dst - mov ecx, [esp + 12] // width - vpcmpeqb ymm0, ymm0, ymm0 - vpsrld ymm0, ymm0, 8 // generate mask 0x00ffffff - - convertloop: - vpmovzxbd ymm1, qword ptr [eax] - vpmovzxbd ymm2, qword ptr [eax + 8] - lea eax, [eax + 16] - vpslld ymm1, ymm1, 24 - vpslld ymm2, ymm2, 24 - vpblendvb ymm1, ymm1, [edx], ymm0 - vpblendvb ymm2, ymm2, [edx + 32], ymm0 - vmovdqu [edx], ymm1 - vmovdqu [edx + 32], ymm2 - lea edx, [edx + 64] - sub ecx, 16 - jg convertloop - - vzeroupper - ret - } -} -#endif // HAS_ARGBCOPYYTOALPHAROW_AVX2 - -#ifdef HAS_SETROW_X86 -// Write 'width' bytes using an 8 bit value repeated. -// width should be multiple of 4. -__declspec(naked) void SetRow_X86(uint8_t* dst, uint8_t v8, int width) { - __asm { - movzx eax, byte ptr [esp + 8] // v8 - mov edx, 0x01010101 // Duplicate byte to all bytes. - mul edx // overwrites edx with upper part of result. - mov edx, edi - mov edi, [esp + 4] // dst - mov ecx, [esp + 12] // width - shr ecx, 2 - rep stosd - mov edi, edx - ret - } -} - -// Write 'width' bytes using an 8 bit value repeated. -__declspec(naked) void SetRow_ERMS(uint8_t* dst, uint8_t v8, int width) { - __asm { - mov edx, edi - mov edi, [esp + 4] // dst - mov eax, [esp + 8] // v8 - mov ecx, [esp + 12] // width - rep stosb - mov edi, edx - ret - } -} - -// Write 'width' 32 bit values. -__declspec(naked) void ARGBSetRow_X86(uint8_t* dst_argb, - uint32_t v32, - int width) { - __asm { - mov edx, edi - mov edi, [esp + 4] // dst - mov eax, [esp + 8] // v32 - mov ecx, [esp + 12] // width - rep stosd - mov edi, edx - ret - } -} -#endif // HAS_SETROW_X86 - -#ifdef HAS_YUY2TOYROW_AVX2 -__declspec(naked) void YUY2ToYRow_AVX2(const uint8_t* src_yuy2, - uint8_t* dst_y, - int width) { - __asm { - mov eax, [esp + 4] // src_yuy2 - mov edx, [esp + 8] // dst_y - mov ecx, [esp + 12] // width - vpcmpeqb ymm5, ymm5, ymm5 // generate mask 0x00ff00ff - vpsrlw ymm5, ymm5, 8 - - convertloop: - vmovdqu ymm0, [eax] - vmovdqu ymm1, [eax + 32] - lea eax, [eax + 64] - vpand ymm0, ymm0, ymm5 // even bytes are Y - vpand ymm1, ymm1, ymm5 - vpackuswb ymm0, ymm0, ymm1 // mutates. - vpermq ymm0, ymm0, 0xd8 - vmovdqu [edx], ymm0 - lea edx, [edx + 32] - sub ecx, 32 - jg convertloop - vzeroupper - ret - } -} - -__declspec(naked) void YUY2ToUVRow_AVX2(const uint8_t* src_yuy2, - int stride_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - __asm { - push esi - push edi - mov eax, [esp + 8 + 4] // src_yuy2 - mov esi, [esp + 8 + 8] // stride_yuy2 - mov edx, [esp + 8 + 12] // dst_u - mov edi, [esp + 8 + 16] // dst_v - mov ecx, [esp + 8 + 20] // width - vpcmpeqb ymm5, ymm5, ymm5 // generate mask 0x00ff00ff - vpsrlw ymm5, ymm5, 8 - sub edi, edx - - convertloop: - vmovdqu ymm0, [eax] - vmovdqu ymm1, [eax + 32] - vpavgb ymm0, ymm0, [eax + esi] - vpavgb ymm1, ymm1, [eax + esi + 32] - lea eax, [eax + 64] - vpsrlw ymm0, ymm0, 8 // YUYV -> UVUV - vpsrlw ymm1, ymm1, 8 - vpackuswb ymm0, ymm0, ymm1 // mutates. - vpermq ymm0, ymm0, 0xd8 - vpand ymm1, ymm0, ymm5 // U - vpsrlw ymm0, ymm0, 8 // V - vpackuswb ymm1, ymm1, ymm1 // mutates. - vpackuswb ymm0, ymm0, ymm0 // mutates. - vpermq ymm1, ymm1, 0xd8 - vpermq ymm0, ymm0, 0xd8 - vextractf128 [edx], ymm1, 0 // U - vextractf128 [edx + edi], ymm0, 0 // V - lea edx, [edx + 16] - sub ecx, 32 - jg convertloop - - pop edi - pop esi - vzeroupper - ret - } -} - -__declspec(naked) void YUY2ToUV422Row_AVX2(const uint8_t* src_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - __asm { - push edi - mov eax, [esp + 4 + 4] // src_yuy2 - mov edx, [esp + 4 + 8] // dst_u - mov edi, [esp + 4 + 12] // dst_v - mov ecx, [esp + 4 + 16] // width - vpcmpeqb ymm5, ymm5, ymm5 // generate mask 0x00ff00ff - vpsrlw ymm5, ymm5, 8 - sub edi, edx - - convertloop: - vmovdqu ymm0, [eax] - vmovdqu ymm1, [eax + 32] - lea eax, [eax + 64] - vpsrlw ymm0, ymm0, 8 // YUYV -> UVUV - vpsrlw ymm1, ymm1, 8 - vpackuswb ymm0, ymm0, ymm1 // mutates. - vpermq ymm0, ymm0, 0xd8 - vpand ymm1, ymm0, ymm5 // U - vpsrlw ymm0, ymm0, 8 // V - vpackuswb ymm1, ymm1, ymm1 // mutates. - vpackuswb ymm0, ymm0, ymm0 // mutates. - vpermq ymm1, ymm1, 0xd8 - vpermq ymm0, ymm0, 0xd8 - vextractf128 [edx], ymm1, 0 // U - vextractf128 [edx + edi], ymm0, 0 // V - lea edx, [edx + 16] - sub ecx, 32 - jg convertloop - - pop edi - vzeroupper - ret - } -} - -__declspec(naked) void UYVYToYRow_AVX2(const uint8_t* src_uyvy, - uint8_t* dst_y, - int width) { - __asm { - mov eax, [esp + 4] // src_uyvy - mov edx, [esp + 8] // dst_y - mov ecx, [esp + 12] // width - - convertloop: - vmovdqu ymm0, [eax] - vmovdqu ymm1, [eax + 32] - lea eax, [eax + 64] - vpsrlw ymm0, ymm0, 8 // odd bytes are Y - vpsrlw ymm1, ymm1, 8 - vpackuswb ymm0, ymm0, ymm1 // mutates. - vpermq ymm0, ymm0, 0xd8 - vmovdqu [edx], ymm0 - lea edx, [edx + 32] - sub ecx, 32 - jg convertloop - vzeroupper - ret - } -} - -__declspec(naked) void UYVYToUVRow_AVX2(const uint8_t* src_uyvy, - int stride_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - __asm { - push esi - push edi - mov eax, [esp + 8 + 4] // src_yuy2 - mov esi, [esp + 8 + 8] // stride_yuy2 - mov edx, [esp + 8 + 12] // dst_u - mov edi, [esp + 8 + 16] // dst_v - mov ecx, [esp + 8 + 20] // width - vpcmpeqb ymm5, ymm5, ymm5 // generate mask 0x00ff00ff - vpsrlw ymm5, ymm5, 8 - sub edi, edx - - convertloop: - vmovdqu ymm0, [eax] - vmovdqu ymm1, [eax + 32] - vpavgb ymm0, ymm0, [eax + esi] - vpavgb ymm1, ymm1, [eax + esi + 32] - lea eax, [eax + 64] - vpand ymm0, ymm0, ymm5 // UYVY -> UVUV - vpand ymm1, ymm1, ymm5 - vpackuswb ymm0, ymm0, ymm1 // mutates. - vpermq ymm0, ymm0, 0xd8 - vpand ymm1, ymm0, ymm5 // U - vpsrlw ymm0, ymm0, 8 // V - vpackuswb ymm1, ymm1, ymm1 // mutates. - vpackuswb ymm0, ymm0, ymm0 // mutates. - vpermq ymm1, ymm1, 0xd8 - vpermq ymm0, ymm0, 0xd8 - vextractf128 [edx], ymm1, 0 // U - vextractf128 [edx + edi], ymm0, 0 // V - lea edx, [edx + 16] - sub ecx, 32 - jg convertloop - - pop edi - pop esi - vzeroupper - ret - } -} - -__declspec(naked) void UYVYToUV422Row_AVX2(const uint8_t* src_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - __asm { - push edi - mov eax, [esp + 4 + 4] // src_yuy2 - mov edx, [esp + 4 + 8] // dst_u - mov edi, [esp + 4 + 12] // dst_v - mov ecx, [esp + 4 + 16] // width - vpcmpeqb ymm5, ymm5, ymm5 // generate mask 0x00ff00ff - vpsrlw ymm5, ymm5, 8 - sub edi, edx - - convertloop: - vmovdqu ymm0, [eax] - vmovdqu ymm1, [eax + 32] - lea eax, [eax + 64] - vpand ymm0, ymm0, ymm5 // UYVY -> UVUV - vpand ymm1, ymm1, ymm5 - vpackuswb ymm0, ymm0, ymm1 // mutates. - vpermq ymm0, ymm0, 0xd8 - vpand ymm1, ymm0, ymm5 // U - vpsrlw ymm0, ymm0, 8 // V - vpackuswb ymm1, ymm1, ymm1 // mutates. - vpackuswb ymm0, ymm0, ymm0 // mutates. - vpermq ymm1, ymm1, 0xd8 - vpermq ymm0, ymm0, 0xd8 - vextractf128 [edx], ymm1, 0 // U - vextractf128 [edx + edi], ymm0, 0 // V - lea edx, [edx + 16] - sub ecx, 32 - jg convertloop - - pop edi - vzeroupper - ret - } -} -#endif // HAS_YUY2TOYROW_AVX2 - -#ifdef HAS_YUY2TOYROW_SSE2 -__declspec(naked) void YUY2ToYRow_SSE2(const uint8_t* src_yuy2, - uint8_t* dst_y, - int width) { - __asm { - mov eax, [esp + 4] // src_yuy2 - mov edx, [esp + 8] // dst_y - mov ecx, [esp + 12] // width - pcmpeqb xmm5, xmm5 // generate mask 0x00ff00ff - psrlw xmm5, 8 - - convertloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - lea eax, [eax + 32] - pand xmm0, xmm5 // even bytes are Y - pand xmm1, xmm5 - packuswb xmm0, xmm1 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 16 - jg convertloop - ret - } -} - -__declspec(naked) void YUY2ToUVRow_SSE2(const uint8_t* src_yuy2, - int stride_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - __asm { - push esi - push edi - mov eax, [esp + 8 + 4] // src_yuy2 - mov esi, [esp + 8 + 8] // stride_yuy2 - mov edx, [esp + 8 + 12] // dst_u - mov edi, [esp + 8 + 16] // dst_v - mov ecx, [esp + 8 + 20] // width - pcmpeqb xmm5, xmm5 // generate mask 0x00ff00ff - psrlw xmm5, 8 - sub edi, edx - - convertloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - movdqu xmm2, [eax + esi] - movdqu xmm3, [eax + esi + 16] - lea eax, [eax + 32] - pavgb xmm0, xmm2 - pavgb xmm1, xmm3 - psrlw xmm0, 8 // YUYV -> UVUV - psrlw xmm1, 8 - packuswb xmm0, xmm1 - movdqa xmm1, xmm0 - pand xmm0, xmm5 // U - packuswb xmm0, xmm0 - psrlw xmm1, 8 // V - packuswb xmm1, xmm1 - movq qword ptr [edx], xmm0 - movq qword ptr [edx + edi], xmm1 - lea edx, [edx + 8] - sub ecx, 16 - jg convertloop - - pop edi - pop esi - ret - } -} - -__declspec(naked) void YUY2ToUV422Row_SSE2(const uint8_t* src_yuy2, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - __asm { - push edi - mov eax, [esp + 4 + 4] // src_yuy2 - mov edx, [esp + 4 + 8] // dst_u - mov edi, [esp + 4 + 12] // dst_v - mov ecx, [esp + 4 + 16] // width - pcmpeqb xmm5, xmm5 // generate mask 0x00ff00ff - psrlw xmm5, 8 - sub edi, edx - - convertloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - lea eax, [eax + 32] - psrlw xmm0, 8 // YUYV -> UVUV - psrlw xmm1, 8 - packuswb xmm0, xmm1 - movdqa xmm1, xmm0 - pand xmm0, xmm5 // U - packuswb xmm0, xmm0 - psrlw xmm1, 8 // V - packuswb xmm1, xmm1 - movq qword ptr [edx], xmm0 - movq qword ptr [edx + edi], xmm1 - lea edx, [edx + 8] - sub ecx, 16 - jg convertloop - - pop edi - ret - } -} - -__declspec(naked) void UYVYToYRow_SSE2(const uint8_t* src_uyvy, - uint8_t* dst_y, - int width) { - __asm { - mov eax, [esp + 4] // src_uyvy - mov edx, [esp + 8] // dst_y - mov ecx, [esp + 12] // width - - convertloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - lea eax, [eax + 32] - psrlw xmm0, 8 // odd bytes are Y - psrlw xmm1, 8 - packuswb xmm0, xmm1 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 16 - jg convertloop - ret - } -} - -__declspec(naked) void UYVYToUVRow_SSE2(const uint8_t* src_uyvy, - int stride_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - __asm { - push esi - push edi - mov eax, [esp + 8 + 4] // src_yuy2 - mov esi, [esp + 8 + 8] // stride_yuy2 - mov edx, [esp + 8 + 12] // dst_u - mov edi, [esp + 8 + 16] // dst_v - mov ecx, [esp + 8 + 20] // width - pcmpeqb xmm5, xmm5 // generate mask 0x00ff00ff - psrlw xmm5, 8 - sub edi, edx - - convertloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - movdqu xmm2, [eax + esi] - movdqu xmm3, [eax + esi + 16] - lea eax, [eax + 32] - pavgb xmm0, xmm2 - pavgb xmm1, xmm3 - pand xmm0, xmm5 // UYVY -> UVUV - pand xmm1, xmm5 - packuswb xmm0, xmm1 - movdqa xmm1, xmm0 - pand xmm0, xmm5 // U - packuswb xmm0, xmm0 - psrlw xmm1, 8 // V - packuswb xmm1, xmm1 - movq qword ptr [edx], xmm0 - movq qword ptr [edx + edi], xmm1 - lea edx, [edx + 8] - sub ecx, 16 - jg convertloop - - pop edi - pop esi - ret - } -} - -__declspec(naked) void UYVYToUV422Row_SSE2(const uint8_t* src_uyvy, - uint8_t* dst_u, - uint8_t* dst_v, - int width) { - __asm { - push edi - mov eax, [esp + 4 + 4] // src_yuy2 - mov edx, [esp + 4 + 8] // dst_u - mov edi, [esp + 4 + 12] // dst_v - mov ecx, [esp + 4 + 16] // width - pcmpeqb xmm5, xmm5 // generate mask 0x00ff00ff - psrlw xmm5, 8 - sub edi, edx - - convertloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - lea eax, [eax + 32] - pand xmm0, xmm5 // UYVY -> UVUV - pand xmm1, xmm5 - packuswb xmm0, xmm1 - movdqa xmm1, xmm0 - pand xmm0, xmm5 // U - packuswb xmm0, xmm0 - psrlw xmm1, 8 // V - packuswb xmm1, xmm1 - movq qword ptr [edx], xmm0 - movq qword ptr [edx + edi], xmm1 - lea edx, [edx + 8] - sub ecx, 16 - jg convertloop - - pop edi - ret - } -} -#endif // HAS_YUY2TOYROW_SSE2 - -#ifdef HAS_BLENDPLANEROW_SSSE3 -// Blend 8 pixels at a time. -// unsigned version of math -// =((A2*C2)+(B2*(255-C2))+255)/256 -// signed version of math -// =(((A2-128)*C2)+((B2-128)*(255-C2))+32768+127)/256 -__declspec(naked) void BlendPlaneRow_SSSE3(const uint8_t* src0, - const uint8_t* src1, - const uint8_t* alpha, - uint8_t* dst, - int width) { - __asm { - push esi - push edi - pcmpeqb xmm5, xmm5 // generate mask 0xff00ff00 - psllw xmm5, 8 - mov eax, 0x80808080 // 128 for biasing image to signed. - movd xmm6, eax - pshufd xmm6, xmm6, 0x00 - - mov eax, 0x807f807f // 32768 + 127 for unbias and round. - movd xmm7, eax - pshufd xmm7, xmm7, 0x00 - mov eax, [esp + 8 + 4] // src0 - mov edx, [esp + 8 + 8] // src1 - mov esi, [esp + 8 + 12] // alpha - mov edi, [esp + 8 + 16] // dst - mov ecx, [esp + 8 + 20] // width - sub eax, esi - sub edx, esi - sub edi, esi - - // 8 pixel loop. - convertloop8: - movq xmm0, qword ptr [esi] // alpha - punpcklbw xmm0, xmm0 - pxor xmm0, xmm5 // a, 255-a - movq xmm1, qword ptr [eax + esi] // src0 - movq xmm2, qword ptr [edx + esi] // src1 - punpcklbw xmm1, xmm2 - psubb xmm1, xmm6 // bias src0/1 - 128 - pmaddubsw xmm0, xmm1 - paddw xmm0, xmm7 // unbias result - 32768 and round. - psrlw xmm0, 8 - packuswb xmm0, xmm0 - movq qword ptr [edi + esi], xmm0 - lea esi, [esi + 8] - sub ecx, 8 - jg convertloop8 - - pop edi - pop esi - ret - } -} -#endif // HAS_BLENDPLANEROW_SSSE3 - -#ifdef HAS_BLENDPLANEROW_AVX2 -// Blend 32 pixels at a time. -// unsigned version of math -// =((A2*C2)+(B2*(255-C2))+255)/256 -// signed version of math -// =(((A2-128)*C2)+((B2-128)*(255-C2))+32768+127)/256 -__declspec(naked) void BlendPlaneRow_AVX2(const uint8_t* src0, - const uint8_t* src1, - const uint8_t* alpha, - uint8_t* dst, - int width) { - __asm { - push esi - push edi - vpcmpeqb ymm5, ymm5, ymm5 // generate mask 0xff00ff00 - vpsllw ymm5, ymm5, 8 - mov eax, 0x80808080 // 128 for biasing image to signed. - vmovd xmm6, eax - vbroadcastss ymm6, xmm6 - mov eax, 0x807f807f // 32768 + 127 for unbias and round. - vmovd xmm7, eax - vbroadcastss ymm7, xmm7 - mov eax, [esp + 8 + 4] // src0 - mov edx, [esp + 8 + 8] // src1 - mov esi, [esp + 8 + 12] // alpha - mov edi, [esp + 8 + 16] // dst - mov ecx, [esp + 8 + 20] // width - sub eax, esi - sub edx, esi - sub edi, esi - - // 32 pixel loop. - convertloop32: - vmovdqu ymm0, [esi] // alpha - vpunpckhbw ymm3, ymm0, ymm0 // 8..15, 24..31 - vpunpcklbw ymm0, ymm0, ymm0 // 0..7, 16..23 - vpxor ymm3, ymm3, ymm5 // a, 255-a - vpxor ymm0, ymm0, ymm5 // a, 255-a - vmovdqu ymm1, [eax + esi] // src0 - vmovdqu ymm2, [edx + esi] // src1 - vpunpckhbw ymm4, ymm1, ymm2 - vpunpcklbw ymm1, ymm1, ymm2 - vpsubb ymm4, ymm4, ymm6 // bias src0/1 - 128 - vpsubb ymm1, ymm1, ymm6 // bias src0/1 - 128 - vpmaddubsw ymm3, ymm3, ymm4 - vpmaddubsw ymm0, ymm0, ymm1 - vpaddw ymm3, ymm3, ymm7 // unbias result - 32768 and round. - vpaddw ymm0, ymm0, ymm7 // unbias result - 32768 and round. - vpsrlw ymm3, ymm3, 8 - vpsrlw ymm0, ymm0, 8 - vpackuswb ymm0, ymm0, ymm3 - vmovdqu [edi + esi], ymm0 - lea esi, [esi + 32] - sub ecx, 32 - jg convertloop32 - - pop edi - pop esi - vzeroupper - ret - } -} -#endif // HAS_BLENDPLANEROW_AVX2 - -#ifdef HAS_ARGBBLENDROW_SSSE3 -// Shuffle table for isolating alpha. -static const uvec8 kShuffleAlpha = {3u, 0x80, 3u, 0x80, 7u, 0x80, 7u, 0x80, - 11u, 0x80, 11u, 0x80, 15u, 0x80, 15u, 0x80}; - -// Blend 8 pixels at a time. -__declspec(naked) void ARGBBlendRow_SSSE3(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_argb0 - mov esi, [esp + 4 + 8] // src_argb1 - mov edx, [esp + 4 + 12] // dst_argb - mov ecx, [esp + 4 + 16] // width - pcmpeqb xmm7, xmm7 // generate constant 0x0001 - psrlw xmm7, 15 - pcmpeqb xmm6, xmm6 // generate mask 0x00ff00ff - psrlw xmm6, 8 - pcmpeqb xmm5, xmm5 // generate mask 0xff00ff00 - psllw xmm5, 8 - pcmpeqb xmm4, xmm4 // generate mask 0xff000000 - pslld xmm4, 24 - sub ecx, 4 - jl convertloop4b // less than 4 pixels? - - // 4 pixel loop. - convertloop4: - movdqu xmm3, [eax] // src argb - lea eax, [eax + 16] - movdqa xmm0, xmm3 // src argb - pxor xmm3, xmm4 // ~alpha - movdqu xmm2, [esi] // _r_b - pshufb xmm3, xmmword ptr kShuffleAlpha // alpha - pand xmm2, xmm6 // _r_b - paddw xmm3, xmm7 // 256 - alpha - pmullw xmm2, xmm3 // _r_b * alpha - movdqu xmm1, [esi] // _a_g - lea esi, [esi + 16] - psrlw xmm1, 8 // _a_g - por xmm0, xmm4 // set alpha to 255 - pmullw xmm1, xmm3 // _a_g * alpha - psrlw xmm2, 8 // _r_b convert to 8 bits again - paddusb xmm0, xmm2 // + src argb - pand xmm1, xmm5 // a_g_ convert to 8 bits again - paddusb xmm0, xmm1 // + src argb - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 4 - jge convertloop4 - - convertloop4b: - add ecx, 4 - 1 - jl convertloop1b - - // 1 pixel loop. - convertloop1: - movd xmm3, [eax] // src argb - lea eax, [eax + 4] - movdqa xmm0, xmm3 // src argb - pxor xmm3, xmm4 // ~alpha - movd xmm2, [esi] // _r_b - pshufb xmm3, xmmword ptr kShuffleAlpha // alpha - pand xmm2, xmm6 // _r_b - paddw xmm3, xmm7 // 256 - alpha - pmullw xmm2, xmm3 // _r_b * alpha - movd xmm1, [esi] // _a_g - lea esi, [esi + 4] - psrlw xmm1, 8 // _a_g - por xmm0, xmm4 // set alpha to 255 - pmullw xmm1, xmm3 // _a_g * alpha - psrlw xmm2, 8 // _r_b convert to 8 bits again - paddusb xmm0, xmm2 // + src argb - pand xmm1, xmm5 // a_g_ convert to 8 bits again - paddusb xmm0, xmm1 // + src argb - movd [edx], xmm0 - lea edx, [edx + 4] - sub ecx, 1 - jge convertloop1 - - convertloop1b: - pop esi - ret - } -} -#endif // HAS_ARGBBLENDROW_SSSE3 - -#ifdef HAS_ARGBATTENUATEROW_SSSE3 -// Shuffle table duplicating alpha. -static const uvec8 kShuffleAlpha0 = { - 3u, 3u, 3u, 3u, 3u, 3u, 128u, 128u, 7u, 7u, 7u, 7u, 7u, 7u, 128u, 128u, -}; -static const uvec8 kShuffleAlpha1 = { - 11u, 11u, 11u, 11u, 11u, 11u, 128u, 128u, - 15u, 15u, 15u, 15u, 15u, 15u, 128u, 128u, -}; -__declspec(naked) void ARGBAttenuateRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_argb, - int width) { - __asm { - mov eax, [esp + 4] // src_argb0 - mov edx, [esp + 8] // dst_argb - mov ecx, [esp + 12] // width - pcmpeqb xmm3, xmm3 // generate mask 0xff000000 - pslld xmm3, 24 - movdqa xmm4, xmmword ptr kShuffleAlpha0 - movdqa xmm5, xmmword ptr kShuffleAlpha1 - - convertloop: - movdqu xmm0, [eax] // read 4 pixels - pshufb xmm0, xmm4 // isolate first 2 alphas - movdqu xmm1, [eax] // read 4 pixels - punpcklbw xmm1, xmm1 // first 2 pixel rgbs - pmulhuw xmm0, xmm1 // rgb * a - movdqu xmm1, [eax] // read 4 pixels - pshufb xmm1, xmm5 // isolate next 2 alphas - movdqu xmm2, [eax] // read 4 pixels - punpckhbw xmm2, xmm2 // next 2 pixel rgbs - pmulhuw xmm1, xmm2 // rgb * a - movdqu xmm2, [eax] // mask original alpha - lea eax, [eax + 16] - pand xmm2, xmm3 - psrlw xmm0, 8 - psrlw xmm1, 8 - packuswb xmm0, xmm1 - por xmm0, xmm2 // copy original alpha - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 4 - jg convertloop - - ret - } -} -#endif // HAS_ARGBATTENUATEROW_SSSE3 - -#ifdef HAS_ARGBATTENUATEROW_AVX2 -// Shuffle table duplicating alpha. -static const uvec8 kShuffleAlpha_AVX2 = {6u, 7u, 6u, 7u, 6u, 7u, - 128u, 128u, 14u, 15u, 14u, 15u, - 14u, 15u, 128u, 128u}; -__declspec(naked) void ARGBAttenuateRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_argb, - int width) { - __asm { - mov eax, [esp + 4] // src_argb0 - mov edx, [esp + 8] // dst_argb - mov ecx, [esp + 12] // width - sub edx, eax - vbroadcastf128 ymm4, xmmword ptr kShuffleAlpha_AVX2 - vpcmpeqb ymm5, ymm5, ymm5 // generate mask 0xff000000 - vpslld ymm5, ymm5, 24 - - convertloop: - vmovdqu ymm6, [eax] // read 8 pixels. - vpunpcklbw ymm0, ymm6, ymm6 // low 4 pixels. mutated. - vpunpckhbw ymm1, ymm6, ymm6 // high 4 pixels. mutated. - vpshufb ymm2, ymm0, ymm4 // low 4 alphas - vpshufb ymm3, ymm1, ymm4 // high 4 alphas - vpmulhuw ymm0, ymm0, ymm2 // rgb * a - vpmulhuw ymm1, ymm1, ymm3 // rgb * a - vpand ymm6, ymm6, ymm5 // isolate alpha - vpsrlw ymm0, ymm0, 8 - vpsrlw ymm1, ymm1, 8 - vpackuswb ymm0, ymm0, ymm1 // unmutated. - vpor ymm0, ymm0, ymm6 // copy original alpha - vmovdqu [eax + edx], ymm0 - lea eax, [eax + 32] - sub ecx, 8 - jg convertloop - - vzeroupper - ret - } -} -#endif // HAS_ARGBATTENUATEROW_AVX2 - -#ifdef HAS_ARGBUNATTENUATEROW_SSE2 -// Unattenuate 4 pixels at a time. -__declspec(naked) void ARGBUnattenuateRow_SSE2(const uint8_t* src_argb, - uint8_t* dst_argb, - int width) { - __asm { - push ebx - push esi - push edi - mov eax, [esp + 12 + 4] // src_argb - mov edx, [esp + 12 + 8] // dst_argb - mov ecx, [esp + 12 + 12] // width - lea ebx, fixed_invtbl8 - - convertloop: - movdqu xmm0, [eax] // read 4 pixels - movzx esi, byte ptr [eax + 3] // first alpha - movzx edi, byte ptr [eax + 7] // second alpha - punpcklbw xmm0, xmm0 // first 2 - movd xmm2, dword ptr [ebx + esi * 4] - movd xmm3, dword ptr [ebx + edi * 4] - pshuflw xmm2, xmm2, 040h // first 4 inv_alpha words. 1, a, a, a - pshuflw xmm3, xmm3, 040h // next 4 inv_alpha words - movlhps xmm2, xmm3 - pmulhuw xmm0, xmm2 // rgb * a - - movdqu xmm1, [eax] // read 4 pixels - movzx esi, byte ptr [eax + 11] // third alpha - movzx edi, byte ptr [eax + 15] // forth alpha - punpckhbw xmm1, xmm1 // next 2 - movd xmm2, dword ptr [ebx + esi * 4] - movd xmm3, dword ptr [ebx + edi * 4] - pshuflw xmm2, xmm2, 040h // first 4 inv_alpha words - pshuflw xmm3, xmm3, 040h // next 4 inv_alpha words - movlhps xmm2, xmm3 - pmulhuw xmm1, xmm2 // rgb * a - lea eax, [eax + 16] - packuswb xmm0, xmm1 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 4 - jg convertloop - - pop edi - pop esi - pop ebx - ret - } -} -#endif // HAS_ARGBUNATTENUATEROW_SSE2 - -#ifdef HAS_ARGBUNATTENUATEROW_AVX2 -// Shuffle table duplicating alpha. -static const uvec8 kUnattenShuffleAlpha_AVX2 = { - 0u, 1u, 0u, 1u, 0u, 1u, 6u, 7u, 8u, 9u, 8u, 9u, 8u, 9u, 14u, 15u}; -// TODO(fbarchard): Enable USE_GATHER for future hardware if faster. -// USE_GATHER is not on by default, due to being a slow instruction. -#ifdef USE_GATHER -__declspec(naked) void ARGBUnattenuateRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_argb, - int width) { - __asm { - mov eax, [esp + 4] // src_argb0 - mov edx, [esp + 8] // dst_argb - mov ecx, [esp + 12] // width - sub edx, eax - vbroadcastf128 ymm4, xmmword ptr kUnattenShuffleAlpha_AVX2 - - convertloop: - vmovdqu ymm6, [eax] // read 8 pixels. - vpcmpeqb ymm5, ymm5, ymm5 // generate mask 0xffffffff for gather. - vpsrld ymm2, ymm6, 24 // alpha in low 8 bits. - vpunpcklbw ymm0, ymm6, ymm6 // low 4 pixels. mutated. - vpunpckhbw ymm1, ymm6, ymm6 // high 4 pixels. mutated. - vpgatherdd ymm3, [ymm2 * 4 + fixed_invtbl8], ymm5 // ymm5 cleared. 1, a - vpunpcklwd ymm2, ymm3, ymm3 // low 4 inverted alphas. mutated. 1, 1, a, a - vpunpckhwd ymm3, ymm3, ymm3 // high 4 inverted alphas. mutated. - vpshufb ymm2, ymm2, ymm4 // replicate low 4 alphas. 1, a, a, a - vpshufb ymm3, ymm3, ymm4 // replicate high 4 alphas - vpmulhuw ymm0, ymm0, ymm2 // rgb * ia - vpmulhuw ymm1, ymm1, ymm3 // rgb * ia - vpackuswb ymm0, ymm0, ymm1 // unmutated. - vmovdqu [eax + edx], ymm0 - lea eax, [eax + 32] - sub ecx, 8 - jg convertloop - - vzeroupper - ret - } -} -#else // USE_GATHER -__declspec(naked) void ARGBUnattenuateRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_argb, - int width) { - __asm { - - push ebx - push esi - push edi - mov eax, [esp + 12 + 4] // src_argb - mov edx, [esp + 12 + 8] // dst_argb - mov ecx, [esp + 12 + 12] // width - sub edx, eax - lea ebx, fixed_invtbl8 - vbroadcastf128 ymm5, xmmword ptr kUnattenShuffleAlpha_AVX2 - - convertloop: - // replace VPGATHER - movzx esi, byte ptr [eax + 3] // alpha0 - movzx edi, byte ptr [eax + 7] // alpha1 - vmovd xmm0, dword ptr [ebx + esi * 4] // [1,a0] - vmovd xmm1, dword ptr [ebx + edi * 4] // [1,a1] - movzx esi, byte ptr [eax + 11] // alpha2 - movzx edi, byte ptr [eax + 15] // alpha3 - vpunpckldq xmm6, xmm0, xmm1 // [1,a1,1,a0] - vmovd xmm2, dword ptr [ebx + esi * 4] // [1,a2] - vmovd xmm3, dword ptr [ebx + edi * 4] // [1,a3] - movzx esi, byte ptr [eax + 19] // alpha4 - movzx edi, byte ptr [eax + 23] // alpha5 - vpunpckldq xmm7, xmm2, xmm3 // [1,a3,1,a2] - vmovd xmm0, dword ptr [ebx + esi * 4] // [1,a4] - vmovd xmm1, dword ptr [ebx + edi * 4] // [1,a5] - movzx esi, byte ptr [eax + 27] // alpha6 - movzx edi, byte ptr [eax + 31] // alpha7 - vpunpckldq xmm0, xmm0, xmm1 // [1,a5,1,a4] - vmovd xmm2, dword ptr [ebx + esi * 4] // [1,a6] - vmovd xmm3, dword ptr [ebx + edi * 4] // [1,a7] - vpunpckldq xmm2, xmm2, xmm3 // [1,a7,1,a6] - vpunpcklqdq xmm3, xmm6, xmm7 // [1,a3,1,a2,1,a1,1,a0] - vpunpcklqdq xmm0, xmm0, xmm2 // [1,a7,1,a6,1,a5,1,a4] - vinserti128 ymm3, ymm3, xmm0, 1 // [1,a7,1,a6,1,a5,1,a4,1,a3,1,a2,1,a1,1,a0] - // end of VPGATHER - - vmovdqu ymm6, [eax] // read 8 pixels. - vpunpcklbw ymm0, ymm6, ymm6 // low 4 pixels. mutated. - vpunpckhbw ymm1, ymm6, ymm6 // high 4 pixels. mutated. - vpunpcklwd ymm2, ymm3, ymm3 // low 4 inverted alphas. mutated. 1, 1, a, a - vpunpckhwd ymm3, ymm3, ymm3 // high 4 inverted alphas. mutated. - vpshufb ymm2, ymm2, ymm5 // replicate low 4 alphas. 1, a, a, a - vpshufb ymm3, ymm3, ymm5 // replicate high 4 alphas - vpmulhuw ymm0, ymm0, ymm2 // rgb * ia - vpmulhuw ymm1, ymm1, ymm3 // rgb * ia - vpackuswb ymm0, ymm0, ymm1 // unmutated. - vmovdqu [eax + edx], ymm0 - lea eax, [eax + 32] - sub ecx, 8 - jg convertloop - - pop edi - pop esi - pop ebx - vzeroupper - ret - } -} -#endif // USE_GATHER -#endif // HAS_ARGBATTENUATEROW_AVX2 - -#ifdef HAS_ARGBGRAYROW_SSSE3 -// Convert 8 ARGB pixels (64 bytes) to 8 Gray ARGB pixels. -__declspec(naked) void ARGBGrayRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_argb, - int width) { - __asm { - mov eax, [esp + 4] /* src_argb */ - mov edx, [esp + 8] /* dst_argb */ - mov ecx, [esp + 12] /* width */ - movdqa xmm4, xmmword ptr kARGBToYJ - movdqa xmm5, xmmword ptr kAddYJ64 - - convertloop: - movdqu xmm0, [eax] // G - movdqu xmm1, [eax + 16] - pmaddubsw xmm0, xmm4 - pmaddubsw xmm1, xmm4 - phaddw xmm0, xmm1 - paddw xmm0, xmm5 // Add .5 for rounding. - psrlw xmm0, 7 - packuswb xmm0, xmm0 // 8 G bytes - movdqu xmm2, [eax] // A - movdqu xmm3, [eax + 16] - lea eax, [eax + 32] - psrld xmm2, 24 - psrld xmm3, 24 - packuswb xmm2, xmm3 - packuswb xmm2, xmm2 // 8 A bytes - movdqa xmm3, xmm0 // Weave into GG, GA, then GGGA - punpcklbw xmm0, xmm0 // 8 GG words - punpcklbw xmm3, xmm2 // 8 GA words - movdqa xmm1, xmm0 - punpcklwd xmm0, xmm3 // GGGA first 4 - punpckhwd xmm1, xmm3 // GGGA next 4 - movdqu [edx], xmm0 - movdqu [edx + 16], xmm1 - lea edx, [edx + 32] - sub ecx, 8 - jg convertloop - ret - } -} -#endif // HAS_ARGBGRAYROW_SSSE3 - -#ifdef HAS_ARGBSEPIAROW_SSSE3 -// b = (r * 35 + g * 68 + b * 17) >> 7 -// g = (r * 45 + g * 88 + b * 22) >> 7 -// r = (r * 50 + g * 98 + b * 24) >> 7 -// Constant for ARGB color to sepia tone. -static const vec8 kARGBToSepiaB = {17, 68, 35, 0, 17, 68, 35, 0, - 17, 68, 35, 0, 17, 68, 35, 0}; - -static const vec8 kARGBToSepiaG = {22, 88, 45, 0, 22, 88, 45, 0, - 22, 88, 45, 0, 22, 88, 45, 0}; - -static const vec8 kARGBToSepiaR = {24, 98, 50, 0, 24, 98, 50, 0, - 24, 98, 50, 0, 24, 98, 50, 0}; - -// Convert 8 ARGB pixels (32 bytes) to 8 Sepia ARGB pixels. -__declspec(naked) void ARGBSepiaRow_SSSE3(uint8_t* dst_argb, int width) { - __asm { - mov eax, [esp + 4] /* dst_argb */ - mov ecx, [esp + 8] /* width */ - movdqa xmm2, xmmword ptr kARGBToSepiaB - movdqa xmm3, xmmword ptr kARGBToSepiaG - movdqa xmm4, xmmword ptr kARGBToSepiaR - - convertloop: - movdqu xmm0, [eax] // B - movdqu xmm6, [eax + 16] - pmaddubsw xmm0, xmm2 - pmaddubsw xmm6, xmm2 - phaddw xmm0, xmm6 - psrlw xmm0, 7 - packuswb xmm0, xmm0 // 8 B values - movdqu xmm5, [eax] // G - movdqu xmm1, [eax + 16] - pmaddubsw xmm5, xmm3 - pmaddubsw xmm1, xmm3 - phaddw xmm5, xmm1 - psrlw xmm5, 7 - packuswb xmm5, xmm5 // 8 G values - punpcklbw xmm0, xmm5 // 8 BG values - movdqu xmm5, [eax] // R - movdqu xmm1, [eax + 16] - pmaddubsw xmm5, xmm4 - pmaddubsw xmm1, xmm4 - phaddw xmm5, xmm1 - psrlw xmm5, 7 - packuswb xmm5, xmm5 // 8 R values - movdqu xmm6, [eax] // A - movdqu xmm1, [eax + 16] - psrld xmm6, 24 - psrld xmm1, 24 - packuswb xmm6, xmm1 - packuswb xmm6, xmm6 // 8 A values - punpcklbw xmm5, xmm6 // 8 RA values - movdqa xmm1, xmm0 // Weave BG, RA together - punpcklwd xmm0, xmm5 // BGRA first 4 - punpckhwd xmm1, xmm5 // BGRA next 4 - movdqu [eax], xmm0 - movdqu [eax + 16], xmm1 - lea eax, [eax + 32] - sub ecx, 8 - jg convertloop - ret - } -} -#endif // HAS_ARGBSEPIAROW_SSSE3 - -#ifdef HAS_ARGBCOLORMATRIXROW_SSSE3 -// Tranform 8 ARGB pixels (32 bytes) with color matrix. -// Same as Sepia except matrix is provided. -// TODO(fbarchard): packuswbs only use half of the reg. To make RGBA, combine R -// and B into a high and low, then G/A, unpackl/hbw and then unpckl/hwd. -__declspec(naked) void ARGBColorMatrixRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_argb, - const int8_t* matrix_argb, - int width) { - __asm { - mov eax, [esp + 4] /* src_argb */ - mov edx, [esp + 8] /* dst_argb */ - mov ecx, [esp + 12] /* matrix_argb */ - movdqu xmm5, [ecx] - pshufd xmm2, xmm5, 0x00 - pshufd xmm3, xmm5, 0x55 - pshufd xmm4, xmm5, 0xaa - pshufd xmm5, xmm5, 0xff - mov ecx, [esp + 16] /* width */ - - convertloop: - movdqu xmm0, [eax] // B - movdqu xmm7, [eax + 16] - pmaddubsw xmm0, xmm2 - pmaddubsw xmm7, xmm2 - movdqu xmm6, [eax] // G - movdqu xmm1, [eax + 16] - pmaddubsw xmm6, xmm3 - pmaddubsw xmm1, xmm3 - phaddsw xmm0, xmm7 // B - phaddsw xmm6, xmm1 // G - psraw xmm0, 6 // B - psraw xmm6, 6 // G - packuswb xmm0, xmm0 // 8 B values - packuswb xmm6, xmm6 // 8 G values - punpcklbw xmm0, xmm6 // 8 BG values - movdqu xmm1, [eax] // R - movdqu xmm7, [eax + 16] - pmaddubsw xmm1, xmm4 - pmaddubsw xmm7, xmm4 - phaddsw xmm1, xmm7 // R - movdqu xmm6, [eax] // A - movdqu xmm7, [eax + 16] - pmaddubsw xmm6, xmm5 - pmaddubsw xmm7, xmm5 - phaddsw xmm6, xmm7 // A - psraw xmm1, 6 // R - psraw xmm6, 6 // A - packuswb xmm1, xmm1 // 8 R values - packuswb xmm6, xmm6 // 8 A values - punpcklbw xmm1, xmm6 // 8 RA values - movdqa xmm6, xmm0 // Weave BG, RA together - punpcklwd xmm0, xmm1 // BGRA first 4 - punpckhwd xmm6, xmm1 // BGRA next 4 - movdqu [edx], xmm0 - movdqu [edx + 16], xmm6 - lea eax, [eax + 32] - lea edx, [edx + 32] - sub ecx, 8 - jg convertloop - ret - } -} -#endif // HAS_ARGBCOLORMATRIXROW_SSSE3 - -#ifdef HAS_ARGBQUANTIZEROW_SSE2 -// Quantize 4 ARGB pixels (16 bytes). -__declspec(naked) void ARGBQuantizeRow_SSE2(uint8_t* dst_argb, - int scale, - int interval_size, - int interval_offset, - int width) { - __asm { - mov eax, [esp + 4] /* dst_argb */ - movd xmm2, [esp + 8] /* scale */ - movd xmm3, [esp + 12] /* interval_size */ - movd xmm4, [esp + 16] /* interval_offset */ - mov ecx, [esp + 20] /* width */ - pshuflw xmm2, xmm2, 040h - pshufd xmm2, xmm2, 044h - pshuflw xmm3, xmm3, 040h - pshufd xmm3, xmm3, 044h - pshuflw xmm4, xmm4, 040h - pshufd xmm4, xmm4, 044h - pxor xmm5, xmm5 // constant 0 - pcmpeqb xmm6, xmm6 // generate mask 0xff000000 - pslld xmm6, 24 - - convertloop: - movdqu xmm0, [eax] // read 4 pixels - punpcklbw xmm0, xmm5 // first 2 pixels - pmulhuw xmm0, xmm2 // pixel * scale >> 16 - movdqu xmm1, [eax] // read 4 pixels - punpckhbw xmm1, xmm5 // next 2 pixels - pmulhuw xmm1, xmm2 - pmullw xmm0, xmm3 // * interval_size - movdqu xmm7, [eax] // read 4 pixels - pmullw xmm1, xmm3 - pand xmm7, xmm6 // mask alpha - paddw xmm0, xmm4 // + interval_size / 2 - paddw xmm1, xmm4 - packuswb xmm0, xmm1 - por xmm0, xmm7 - movdqu [eax], xmm0 - lea eax, [eax + 16] - sub ecx, 4 - jg convertloop - ret - } -} -#endif // HAS_ARGBQUANTIZEROW_SSE2 - -#ifdef HAS_ARGBSHADEROW_SSE2 -// Shade 4 pixels at a time by specified value. -__declspec(naked) void ARGBShadeRow_SSE2(const uint8_t* src_argb, - uint8_t* dst_argb, - int width, - uint32_t value) { - __asm { - mov eax, [esp + 4] // src_argb - mov edx, [esp + 8] // dst_argb - mov ecx, [esp + 12] // width - movd xmm2, [esp + 16] // value - punpcklbw xmm2, xmm2 - punpcklqdq xmm2, xmm2 - - convertloop: - movdqu xmm0, [eax] // read 4 pixels - lea eax, [eax + 16] - movdqa xmm1, xmm0 - punpcklbw xmm0, xmm0 // first 2 - punpckhbw xmm1, xmm1 // next 2 - pmulhuw xmm0, xmm2 // argb * value - pmulhuw xmm1, xmm2 // argb * value - psrlw xmm0, 8 - psrlw xmm1, 8 - packuswb xmm0, xmm1 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 4 - jg convertloop - - ret - } -} -#endif // HAS_ARGBSHADEROW_SSE2 - -#ifdef HAS_ARGBMULTIPLYROW_SSE2 -// Multiply 2 rows of ARGB pixels together, 4 pixels at a time. -__declspec(naked) void ARGBMultiplyRow_SSE2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_argb0 - mov esi, [esp + 4 + 8] // src_argb1 - mov edx, [esp + 4 + 12] // dst_argb - mov ecx, [esp + 4 + 16] // width - pxor xmm5, xmm5 // constant 0 - - convertloop: - movdqu xmm0, [eax] // read 4 pixels from src_argb0 - movdqu xmm2, [esi] // read 4 pixels from src_argb1 - movdqu xmm1, xmm0 - movdqu xmm3, xmm2 - punpcklbw xmm0, xmm0 // first 2 - punpckhbw xmm1, xmm1 // next 2 - punpcklbw xmm2, xmm5 // first 2 - punpckhbw xmm3, xmm5 // next 2 - pmulhuw xmm0, xmm2 // src_argb0 * src_argb1 first 2 - pmulhuw xmm1, xmm3 // src_argb0 * src_argb1 next 2 - lea eax, [eax + 16] - lea esi, [esi + 16] - packuswb xmm0, xmm1 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 4 - jg convertloop - - pop esi - ret - } -} -#endif // HAS_ARGBMULTIPLYROW_SSE2 - -#ifdef HAS_ARGBADDROW_SSE2 -// Add 2 rows of ARGB pixels together, 4 pixels at a time. -// TODO(fbarchard): Port this to posix, neon and other math functions. -__declspec(naked) void ARGBAddRow_SSE2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_argb0 - mov esi, [esp + 4 + 8] // src_argb1 - mov edx, [esp + 4 + 12] // dst_argb - mov ecx, [esp + 4 + 16] // width - - sub ecx, 4 - jl convertloop49 - - convertloop4: - movdqu xmm0, [eax] // read 4 pixels from src_argb0 - lea eax, [eax + 16] - movdqu xmm1, [esi] // read 4 pixels from src_argb1 - lea esi, [esi + 16] - paddusb xmm0, xmm1 // src_argb0 + src_argb1 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 4 - jge convertloop4 - - convertloop49: - add ecx, 4 - 1 - jl convertloop19 - - convertloop1: - movd xmm0, [eax] // read 1 pixels from src_argb0 - lea eax, [eax + 4] - movd xmm1, [esi] // read 1 pixels from src_argb1 - lea esi, [esi + 4] - paddusb xmm0, xmm1 // src_argb0 + src_argb1 - movd [edx], xmm0 - lea edx, [edx + 4] - sub ecx, 1 - jge convertloop1 - - convertloop19: - pop esi - ret - } -} -#endif // HAS_ARGBADDROW_SSE2 - -#ifdef HAS_ARGBSUBTRACTROW_SSE2 -// Subtract 2 rows of ARGB pixels together, 4 pixels at a time. -__declspec(naked) void ARGBSubtractRow_SSE2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_argb0 - mov esi, [esp + 4 + 8] // src_argb1 - mov edx, [esp + 4 + 12] // dst_argb - mov ecx, [esp + 4 + 16] // width - - convertloop: - movdqu xmm0, [eax] // read 4 pixels from src_argb0 - lea eax, [eax + 16] - movdqu xmm1, [esi] // read 4 pixels from src_argb1 - lea esi, [esi + 16] - psubusb xmm0, xmm1 // src_argb0 - src_argb1 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 4 - jg convertloop - - pop esi - ret - } -} -#endif // HAS_ARGBSUBTRACTROW_SSE2 - -#ifdef HAS_ARGBMULTIPLYROW_AVX2 -// Multiply 2 rows of ARGB pixels together, 8 pixels at a time. -__declspec(naked) void ARGBMultiplyRow_AVX2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_argb0 - mov esi, [esp + 4 + 8] // src_argb1 - mov edx, [esp + 4 + 12] // dst_argb - mov ecx, [esp + 4 + 16] // width - vpxor ymm5, ymm5, ymm5 // constant 0 - - convertloop: - vmovdqu ymm1, [eax] // read 8 pixels from src_argb0 - lea eax, [eax + 32] - vmovdqu ymm3, [esi] // read 8 pixels from src_argb1 - lea esi, [esi + 32] - vpunpcklbw ymm0, ymm1, ymm1 // low 4 - vpunpckhbw ymm1, ymm1, ymm1 // high 4 - vpunpcklbw ymm2, ymm3, ymm5 // low 4 - vpunpckhbw ymm3, ymm3, ymm5 // high 4 - vpmulhuw ymm0, ymm0, ymm2 // src_argb0 * src_argb1 low 4 - vpmulhuw ymm1, ymm1, ymm3 // src_argb0 * src_argb1 high 4 - vpackuswb ymm0, ymm0, ymm1 - vmovdqu [edx], ymm0 - lea edx, [edx + 32] - sub ecx, 8 - jg convertloop - - pop esi - vzeroupper - ret - } -} -#endif // HAS_ARGBMULTIPLYROW_AVX2 - -#ifdef HAS_ARGBADDROW_AVX2 -// Add 2 rows of ARGB pixels together, 8 pixels at a time. -__declspec(naked) void ARGBAddRow_AVX2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_argb0 - mov esi, [esp + 4 + 8] // src_argb1 - mov edx, [esp + 4 + 12] // dst_argb - mov ecx, [esp + 4 + 16] // width - - convertloop: - vmovdqu ymm0, [eax] // read 8 pixels from src_argb0 - lea eax, [eax + 32] - vpaddusb ymm0, ymm0, [esi] // add 8 pixels from src_argb1 - lea esi, [esi + 32] - vmovdqu [edx], ymm0 - lea edx, [edx + 32] - sub ecx, 8 - jg convertloop - - pop esi - vzeroupper - ret - } -} -#endif // HAS_ARGBADDROW_AVX2 - -#ifdef HAS_ARGBSUBTRACTROW_AVX2 -// Subtract 2 rows of ARGB pixels together, 8 pixels at a time. -__declspec(naked) void ARGBSubtractRow_AVX2(const uint8_t* src_argb0, - const uint8_t* src_argb1, - uint8_t* dst_argb, - int width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_argb0 - mov esi, [esp + 4 + 8] // src_argb1 - mov edx, [esp + 4 + 12] // dst_argb - mov ecx, [esp + 4 + 16] // width - - convertloop: - vmovdqu ymm0, [eax] // read 8 pixels from src_argb0 - lea eax, [eax + 32] - vpsubusb ymm0, ymm0, [esi] // src_argb0 - src_argb1 - lea esi, [esi + 32] - vmovdqu [edx], ymm0 - lea edx, [edx + 32] - sub ecx, 8 - jg convertloop - - pop esi - vzeroupper - ret - } -} -#endif // HAS_ARGBSUBTRACTROW_AVX2 - -#ifdef HAS_SOBELXROW_SSE2 -// SobelX as a matrix is -// -1 0 1 -// -2 0 2 -// -1 0 1 -__declspec(naked) void SobelXRow_SSE2(const uint8_t* src_y0, - const uint8_t* src_y1, - const uint8_t* src_y2, - uint8_t* dst_sobelx, - int width) { - __asm { - push esi - push edi - mov eax, [esp + 8 + 4] // src_y0 - mov esi, [esp + 8 + 8] // src_y1 - mov edi, [esp + 8 + 12] // src_y2 - mov edx, [esp + 8 + 16] // dst_sobelx - mov ecx, [esp + 8 + 20] // width - sub esi, eax - sub edi, eax - sub edx, eax - pxor xmm5, xmm5 // constant 0 - - convertloop: - movq xmm0, qword ptr [eax] // read 8 pixels from src_y0[0] - movq xmm1, qword ptr [eax + 2] // read 8 pixels from src_y0[2] - punpcklbw xmm0, xmm5 - punpcklbw xmm1, xmm5 - psubw xmm0, xmm1 - movq xmm1, qword ptr [eax + esi] // read 8 pixels from src_y1[0] - movq xmm2, qword ptr [eax + esi + 2] // read 8 pixels from src_y1[2] - punpcklbw xmm1, xmm5 - punpcklbw xmm2, xmm5 - psubw xmm1, xmm2 - movq xmm2, qword ptr [eax + edi] // read 8 pixels from src_y2[0] - movq xmm3, qword ptr [eax + edi + 2] // read 8 pixels from src_y2[2] - punpcklbw xmm2, xmm5 - punpcklbw xmm3, xmm5 - psubw xmm2, xmm3 - paddw xmm0, xmm2 - paddw xmm0, xmm1 - paddw xmm0, xmm1 - pxor xmm1, xmm1 // abs = max(xmm0, -xmm0). SSSE3 could use pabsw - psubw xmm1, xmm0 - pmaxsw xmm0, xmm1 - packuswb xmm0, xmm0 - movq qword ptr [eax + edx], xmm0 - lea eax, [eax + 8] - sub ecx, 8 - jg convertloop - - pop edi - pop esi - ret - } -} -#endif // HAS_SOBELXROW_SSE2 - -#ifdef HAS_SOBELYROW_SSE2 -// SobelY as a matrix is -// -1 -2 -1 -// 0 0 0 -// 1 2 1 -__declspec(naked) void SobelYRow_SSE2(const uint8_t* src_y0, - const uint8_t* src_y1, - uint8_t* dst_sobely, - int width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_y0 - mov esi, [esp + 4 + 8] // src_y1 - mov edx, [esp + 4 + 12] // dst_sobely - mov ecx, [esp + 4 + 16] // width - sub esi, eax - sub edx, eax - pxor xmm5, xmm5 // constant 0 - - convertloop: - movq xmm0, qword ptr [eax] // read 8 pixels from src_y0[0] - movq xmm1, qword ptr [eax + esi] // read 8 pixels from src_y1[0] - punpcklbw xmm0, xmm5 - punpcklbw xmm1, xmm5 - psubw xmm0, xmm1 - movq xmm1, qword ptr [eax + 1] // read 8 pixels from src_y0[1] - movq xmm2, qword ptr [eax + esi + 1] // read 8 pixels from src_y1[1] - punpcklbw xmm1, xmm5 - punpcklbw xmm2, xmm5 - psubw xmm1, xmm2 - movq xmm2, qword ptr [eax + 2] // read 8 pixels from src_y0[2] - movq xmm3, qword ptr [eax + esi + 2] // read 8 pixels from src_y1[2] - punpcklbw xmm2, xmm5 - punpcklbw xmm3, xmm5 - psubw xmm2, xmm3 - paddw xmm0, xmm2 - paddw xmm0, xmm1 - paddw xmm0, xmm1 - pxor xmm1, xmm1 // abs = max(xmm0, -xmm0). SSSE3 could use pabsw - psubw xmm1, xmm0 - pmaxsw xmm0, xmm1 - packuswb xmm0, xmm0 - movq qword ptr [eax + edx], xmm0 - lea eax, [eax + 8] - sub ecx, 8 - jg convertloop - - pop esi - ret - } -} -#endif // HAS_SOBELYROW_SSE2 - -#ifdef HAS_SOBELROW_SSE2 -// Adds Sobel X and Sobel Y and stores Sobel into ARGB. -// A = 255 -// R = Sobel -// G = Sobel -// B = Sobel -__declspec(naked) void SobelRow_SSE2(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_sobelx - mov esi, [esp + 4 + 8] // src_sobely - mov edx, [esp + 4 + 12] // dst_argb - mov ecx, [esp + 4 + 16] // width - sub esi, eax - pcmpeqb xmm5, xmm5 // alpha 255 - pslld xmm5, 24 // 0xff000000 - - convertloop: - movdqu xmm0, [eax] // read 16 pixels src_sobelx - movdqu xmm1, [eax + esi] // read 16 pixels src_sobely - lea eax, [eax + 16] - paddusb xmm0, xmm1 // sobel = sobelx + sobely - movdqa xmm2, xmm0 // GG - punpcklbw xmm2, xmm0 // First 8 - punpckhbw xmm0, xmm0 // Next 8 - movdqa xmm1, xmm2 // GGGG - punpcklwd xmm1, xmm2 // First 4 - punpckhwd xmm2, xmm2 // Next 4 - por xmm1, xmm5 // GGGA - por xmm2, xmm5 - movdqa xmm3, xmm0 // GGGG - punpcklwd xmm3, xmm0 // Next 4 - punpckhwd xmm0, xmm0 // Last 4 - por xmm3, xmm5 // GGGA - por xmm0, xmm5 - movdqu [edx], xmm1 - movdqu [edx + 16], xmm2 - movdqu [edx + 32], xmm3 - movdqu [edx + 48], xmm0 - lea edx, [edx + 64] - sub ecx, 16 - jg convertloop - - pop esi - ret - } -} -#endif // HAS_SOBELROW_SSE2 - -#ifdef HAS_SOBELTOPLANEROW_SSE2 -// Adds Sobel X and Sobel Y and stores Sobel into a plane. -__declspec(naked) void SobelToPlaneRow_SSE2(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_y, - int width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_sobelx - mov esi, [esp + 4 + 8] // src_sobely - mov edx, [esp + 4 + 12] // dst_argb - mov ecx, [esp + 4 + 16] // width - sub esi, eax - - convertloop: - movdqu xmm0, [eax] // read 16 pixels src_sobelx - movdqu xmm1, [eax + esi] // read 16 pixels src_sobely - lea eax, [eax + 16] - paddusb xmm0, xmm1 // sobel = sobelx + sobely - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 16 - jg convertloop - - pop esi - ret - } -} -#endif // HAS_SOBELTOPLANEROW_SSE2 - -#ifdef HAS_SOBELXYROW_SSE2 -// Mixes Sobel X, Sobel Y and Sobel into ARGB. -// A = 255 -// R = Sobel X -// G = Sobel -// B = Sobel Y -__declspec(naked) void SobelXYRow_SSE2(const uint8_t* src_sobelx, - const uint8_t* src_sobely, - uint8_t* dst_argb, - int width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_sobelx - mov esi, [esp + 4 + 8] // src_sobely - mov edx, [esp + 4 + 12] // dst_argb - mov ecx, [esp + 4 + 16] // width - sub esi, eax - pcmpeqb xmm5, xmm5 // alpha 255 - - convertloop: - movdqu xmm0, [eax] // read 16 pixels src_sobelx - movdqu xmm1, [eax + esi] // read 16 pixels src_sobely - lea eax, [eax + 16] - movdqa xmm2, xmm0 - paddusb xmm2, xmm1 // sobel = sobelx + sobely - movdqa xmm3, xmm0 // XA - punpcklbw xmm3, xmm5 - punpckhbw xmm0, xmm5 - movdqa xmm4, xmm1 // YS - punpcklbw xmm4, xmm2 - punpckhbw xmm1, xmm2 - movdqa xmm6, xmm4 // YSXA - punpcklwd xmm6, xmm3 // First 4 - punpckhwd xmm4, xmm3 // Next 4 - movdqa xmm7, xmm1 // YSXA - punpcklwd xmm7, xmm0 // Next 4 - punpckhwd xmm1, xmm0 // Last 4 - movdqu [edx], xmm6 - movdqu [edx + 16], xmm4 - movdqu [edx + 32], xmm7 - movdqu [edx + 48], xmm1 - lea edx, [edx + 64] - sub ecx, 16 - jg convertloop - - pop esi - ret - } -} -#endif // HAS_SOBELXYROW_SSE2 - -#ifdef HAS_CUMULATIVESUMTOAVERAGEROW_SSE2 -// Consider float CumulativeSum. -// Consider calling CumulativeSum one row at time as needed. -// Consider circular CumulativeSum buffer of radius * 2 + 1 height. -// Convert cumulative sum for an area to an average for 1 pixel. -// topleft is pointer to top left of CumulativeSum buffer for area. -// botleft is pointer to bottom left of CumulativeSum buffer. -// width is offset from left to right of area in CumulativeSum buffer measured -// in number of ints. -// area is the number of pixels in the area being averaged. -// dst points to pixel to store result to. -// count is number of averaged pixels to produce. -// Does 4 pixels at a time. -// This function requires alignment on accumulation buffer pointers. -void CumulativeSumToAverageRow_SSE2(const int32_t* topleft, - const int32_t* botleft, - int width, - int area, - uint8_t* dst, - int count) { - __asm { - mov eax, topleft // eax topleft - mov esi, botleft // esi botleft - mov edx, width - movd xmm5, area - mov edi, dst - mov ecx, count - cvtdq2ps xmm5, xmm5 - rcpss xmm4, xmm5 // 1.0f / area - pshufd xmm4, xmm4, 0 - sub ecx, 4 - jl l4b - - cmp area, 128 // 128 pixels will not overflow 15 bits. - ja l4 - - pshufd xmm5, xmm5, 0 // area - pcmpeqb xmm6, xmm6 // constant of 65536.0 - 1 = 65535.0 - psrld xmm6, 16 - cvtdq2ps xmm6, xmm6 - addps xmm5, xmm6 // (65536.0 + area - 1) - mulps xmm5, xmm4 // (65536.0 + area - 1) * 1 / area - cvtps2dq xmm5, xmm5 // 0.16 fixed point - packssdw xmm5, xmm5 // 16 bit shorts - - // 4 pixel loop small blocks. - s4: - // top left - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - movdqu xmm2, [eax + 32] - movdqu xmm3, [eax + 48] - - // - top right - psubd xmm0, [eax + edx * 4] - psubd xmm1, [eax + edx * 4 + 16] - psubd xmm2, [eax + edx * 4 + 32] - psubd xmm3, [eax + edx * 4 + 48] - lea eax, [eax + 64] - - // - bottom left - psubd xmm0, [esi] - psubd xmm1, [esi + 16] - psubd xmm2, [esi + 32] - psubd xmm3, [esi + 48] - - // + bottom right - paddd xmm0, [esi + edx * 4] - paddd xmm1, [esi + edx * 4 + 16] - paddd xmm2, [esi + edx * 4 + 32] - paddd xmm3, [esi + edx * 4 + 48] - lea esi, [esi + 64] - - packssdw xmm0, xmm1 // pack 4 pixels into 2 registers - packssdw xmm2, xmm3 - - pmulhuw xmm0, xmm5 - pmulhuw xmm2, xmm5 - - packuswb xmm0, xmm2 - movdqu [edi], xmm0 - lea edi, [edi + 16] - sub ecx, 4 - jge s4 - - jmp l4b - - // 4 pixel loop - l4: - // top left - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - movdqu xmm2, [eax + 32] - movdqu xmm3, [eax + 48] - - // - top right - psubd xmm0, [eax + edx * 4] - psubd xmm1, [eax + edx * 4 + 16] - psubd xmm2, [eax + edx * 4 + 32] - psubd xmm3, [eax + edx * 4 + 48] - lea eax, [eax + 64] - - // - bottom left - psubd xmm0, [esi] - psubd xmm1, [esi + 16] - psubd xmm2, [esi + 32] - psubd xmm3, [esi + 48] - - // + bottom right - paddd xmm0, [esi + edx * 4] - paddd xmm1, [esi + edx * 4 + 16] - paddd xmm2, [esi + edx * 4 + 32] - paddd xmm3, [esi + edx * 4 + 48] - lea esi, [esi + 64] - - cvtdq2ps xmm0, xmm0 // Average = Sum * 1 / Area - cvtdq2ps xmm1, xmm1 - mulps xmm0, xmm4 - mulps xmm1, xmm4 - cvtdq2ps xmm2, xmm2 - cvtdq2ps xmm3, xmm3 - mulps xmm2, xmm4 - mulps xmm3, xmm4 - cvtps2dq xmm0, xmm0 - cvtps2dq xmm1, xmm1 - cvtps2dq xmm2, xmm2 - cvtps2dq xmm3, xmm3 - packssdw xmm0, xmm1 - packssdw xmm2, xmm3 - packuswb xmm0, xmm2 - movdqu [edi], xmm0 - lea edi, [edi + 16] - sub ecx, 4 - jge l4 - - l4b: - add ecx, 4 - 1 - jl l1b - - // 1 pixel loop - l1: - movdqu xmm0, [eax] - psubd xmm0, [eax + edx * 4] - lea eax, [eax + 16] - psubd xmm0, [esi] - paddd xmm0, [esi + edx * 4] - lea esi, [esi + 16] - cvtdq2ps xmm0, xmm0 - mulps xmm0, xmm4 - cvtps2dq xmm0, xmm0 - packssdw xmm0, xmm0 - packuswb xmm0, xmm0 - movd dword ptr [edi], xmm0 - lea edi, [edi + 4] - sub ecx, 1 - jge l1 - l1b: - } -} -#endif // HAS_CUMULATIVESUMTOAVERAGEROW_SSE2 - -#ifdef HAS_COMPUTECUMULATIVESUMROW_SSE2 -// Creates a table of cumulative sums where each value is a sum of all values -// above and to the left of the value. -void ComputeCumulativeSumRow_SSE2(const uint8_t* row, - int32_t* cumsum, - const int32_t* previous_cumsum, - int width) { - __asm { - mov eax, row - mov edx, cumsum - mov esi, previous_cumsum - mov ecx, width - pxor xmm0, xmm0 - pxor xmm1, xmm1 - - sub ecx, 4 - jl l4b - test edx, 15 - jne l4b - - // 4 pixel loop - l4: - movdqu xmm2, [eax] // 4 argb pixels 16 bytes. - lea eax, [eax + 16] - movdqa xmm4, xmm2 - - punpcklbw xmm2, xmm1 - movdqa xmm3, xmm2 - punpcklwd xmm2, xmm1 - punpckhwd xmm3, xmm1 - - punpckhbw xmm4, xmm1 - movdqa xmm5, xmm4 - punpcklwd xmm4, xmm1 - punpckhwd xmm5, xmm1 - - paddd xmm0, xmm2 - movdqu xmm2, [esi] // previous row above. - paddd xmm2, xmm0 - - paddd xmm0, xmm3 - movdqu xmm3, [esi + 16] - paddd xmm3, xmm0 - - paddd xmm0, xmm4 - movdqu xmm4, [esi + 32] - paddd xmm4, xmm0 - - paddd xmm0, xmm5 - movdqu xmm5, [esi + 48] - lea esi, [esi + 64] - paddd xmm5, xmm0 - - movdqu [edx], xmm2 - movdqu [edx + 16], xmm3 - movdqu [edx + 32], xmm4 - movdqu [edx + 48], xmm5 - - lea edx, [edx + 64] - sub ecx, 4 - jge l4 - - l4b: - add ecx, 4 - 1 - jl l1b - - // 1 pixel loop - l1: - movd xmm2, dword ptr [eax] // 1 argb pixel 4 bytes. - lea eax, [eax + 4] - punpcklbw xmm2, xmm1 - punpcklwd xmm2, xmm1 - paddd xmm0, xmm2 - movdqu xmm2, [esi] - lea esi, [esi + 16] - paddd xmm2, xmm0 - movdqu [edx], xmm2 - lea edx, [edx + 16] - sub ecx, 1 - jge l1 - - l1b: - } -} -#endif // HAS_COMPUTECUMULATIVESUMROW_SSE2 - -#ifdef HAS_ARGBAFFINEROW_SSE2 -// Copy ARGB pixels from source image with slope to a row of destination. -__declspec(naked) LIBYUV_API void ARGBAffineRow_SSE2(const uint8_t* src_argb, - int src_argb_stride, - uint8_t* dst_argb, - const float* uv_dudv, - int width) { - __asm { - push esi - push edi - mov eax, [esp + 12] // src_argb - mov esi, [esp + 16] // stride - mov edx, [esp + 20] // dst_argb - mov ecx, [esp + 24] // pointer to uv_dudv - movq xmm2, qword ptr [ecx] // uv - movq xmm7, qword ptr [ecx + 8] // dudv - mov ecx, [esp + 28] // width - shl esi, 16 // 4, stride - add esi, 4 - movd xmm5, esi - sub ecx, 4 - jl l4b - - // setup for 4 pixel loop - pshufd xmm7, xmm7, 0x44 // dup dudv - pshufd xmm5, xmm5, 0 // dup 4, stride - movdqa xmm0, xmm2 // x0, y0, x1, y1 - addps xmm0, xmm7 - movlhps xmm2, xmm0 - movdqa xmm4, xmm7 - addps xmm4, xmm4 // dudv *= 2 - movdqa xmm3, xmm2 // x2, y2, x3, y3 - addps xmm3, xmm4 - addps xmm4, xmm4 // dudv *= 4 - - // 4 pixel loop - l4: - cvttps2dq xmm0, xmm2 // x, y float to int first 2 - cvttps2dq xmm1, xmm3 // x, y float to int next 2 - packssdw xmm0, xmm1 // x, y as 8 shorts - pmaddwd xmm0, xmm5 // offsets = x * 4 + y * stride. - movd esi, xmm0 - pshufd xmm0, xmm0, 0x39 // shift right - movd edi, xmm0 - pshufd xmm0, xmm0, 0x39 // shift right - movd xmm1, [eax + esi] // read pixel 0 - movd xmm6, [eax + edi] // read pixel 1 - punpckldq xmm1, xmm6 // combine pixel 0 and 1 - addps xmm2, xmm4 // x, y += dx, dy first 2 - movq qword ptr [edx], xmm1 - movd esi, xmm0 - pshufd xmm0, xmm0, 0x39 // shift right - movd edi, xmm0 - movd xmm6, [eax + esi] // read pixel 2 - movd xmm0, [eax + edi] // read pixel 3 - punpckldq xmm6, xmm0 // combine pixel 2 and 3 - addps xmm3, xmm4 // x, y += dx, dy next 2 - movq qword ptr 8[edx], xmm6 - lea edx, [edx + 16] - sub ecx, 4 - jge l4 - - l4b: - add ecx, 4 - 1 - jl l1b - - // 1 pixel loop - l1: - cvttps2dq xmm0, xmm2 // x, y float to int - packssdw xmm0, xmm0 // x, y as shorts - pmaddwd xmm0, xmm5 // offset = x * 4 + y * stride - addps xmm2, xmm7 // x, y += dx, dy - movd esi, xmm0 - movd xmm0, [eax + esi] // copy a pixel - movd [edx], xmm0 - lea edx, [edx + 4] - sub ecx, 1 - jge l1 - l1b: - pop edi - pop esi - ret - } -} -#endif // HAS_ARGBAFFINEROW_SSE2 - -#ifdef HAS_INTERPOLATEROW_AVX2 -// Bilinear filter 32x2 -> 32x1 -__declspec(naked) void InterpolateRow_AVX2(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride, - int dst_width, - int source_y_fraction) { - __asm { - push esi - push edi - mov edi, [esp + 8 + 4] // dst_ptr - mov esi, [esp + 8 + 8] // src_ptr - mov edx, [esp + 8 + 12] // src_stride - mov ecx, [esp + 8 + 16] // dst_width - mov eax, [esp + 8 + 20] // source_y_fraction (0..255) - // Dispatch to specialized filters if applicable. - cmp eax, 0 - je xloop100 // 0 / 256. Blend 100 / 0. - sub edi, esi - cmp eax, 128 - je xloop50 // 128 /256 is 0.50. Blend 50 / 50. - - vmovd xmm0, eax // high fraction 0..255 - neg eax - add eax, 256 - vmovd xmm5, eax // low fraction 256..1 - vpunpcklbw xmm5, xmm5, xmm0 - vpunpcklwd xmm5, xmm5, xmm5 - vbroadcastss ymm5, xmm5 - - mov eax, 0x80808080 // 128b for bias and rounding. - vmovd xmm4, eax - vbroadcastss ymm4, xmm4 - - xloop: - vmovdqu ymm0, [esi] - vmovdqu ymm2, [esi + edx] - vpunpckhbw ymm1, ymm0, ymm2 // mutates - vpunpcklbw ymm0, ymm0, ymm2 - vpsubb ymm1, ymm1, ymm4 // bias to signed image - vpsubb ymm0, ymm0, ymm4 - vpmaddubsw ymm1, ymm5, ymm1 - vpmaddubsw ymm0, ymm5, ymm0 - vpaddw ymm1, ymm1, ymm4 // unbias and round - vpaddw ymm0, ymm0, ymm4 - vpsrlw ymm1, ymm1, 8 - vpsrlw ymm0, ymm0, 8 - vpackuswb ymm0, ymm0, ymm1 // unmutates - vmovdqu [esi + edi], ymm0 - lea esi, [esi + 32] - sub ecx, 32 - jg xloop - jmp xloop99 - - // Blend 50 / 50. - xloop50: - vmovdqu ymm0, [esi] - vpavgb ymm0, ymm0, [esi + edx] - vmovdqu [esi + edi], ymm0 - lea esi, [esi + 32] - sub ecx, 32 - jg xloop50 - jmp xloop99 - - // Blend 100 / 0 - Copy row unchanged. - xloop100: - rep movsb - - xloop99: - pop edi - pop esi - vzeroupper - ret - } -} -#endif // HAS_INTERPOLATEROW_AVX2 - -// Bilinear filter 16x2 -> 16x1 -// TODO(fbarchard): Consider allowing 256 using memcpy. -__declspec(naked) void InterpolateRow_SSSE3(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride, - int dst_width, - int source_y_fraction) { - __asm { - push esi - push edi - - mov edi, [esp + 8 + 4] // dst_ptr - mov esi, [esp + 8 + 8] // src_ptr - mov edx, [esp + 8 + 12] // src_stride - mov ecx, [esp + 8 + 16] // dst_width - mov eax, [esp + 8 + 20] // source_y_fraction (0..255) - sub edi, esi - // Dispatch to specialized filters if applicable. - cmp eax, 0 - je xloop100 // 0 /256. Blend 100 / 0. - cmp eax, 128 - je xloop50 // 128 / 256 is 0.50. Blend 50 / 50. - - movd xmm0, eax // high fraction 0..255 - neg eax - add eax, 256 - movd xmm5, eax // low fraction 255..1 - punpcklbw xmm5, xmm0 - punpcklwd xmm5, xmm5 - pshufd xmm5, xmm5, 0 - mov eax, 0x80808080 // 128 for biasing image to signed. - movd xmm4, eax - pshufd xmm4, xmm4, 0x00 - - xloop: - movdqu xmm0, [esi] - movdqu xmm2, [esi + edx] - movdqu xmm1, xmm0 - punpcklbw xmm0, xmm2 - punpckhbw xmm1, xmm2 - psubb xmm0, xmm4 // bias image by -128 - psubb xmm1, xmm4 - movdqa xmm2, xmm5 - movdqa xmm3, xmm5 - pmaddubsw xmm2, xmm0 - pmaddubsw xmm3, xmm1 - paddw xmm2, xmm4 - paddw xmm3, xmm4 - psrlw xmm2, 8 - psrlw xmm3, 8 - packuswb xmm2, xmm3 - movdqu [esi + edi], xmm2 - lea esi, [esi + 16] - sub ecx, 16 - jg xloop - jmp xloop99 - - // Blend 50 / 50. - xloop50: - movdqu xmm0, [esi] - movdqu xmm1, [esi + edx] - pavgb xmm0, xmm1 - movdqu [esi + edi], xmm0 - lea esi, [esi + 16] - sub ecx, 16 - jg xloop50 - jmp xloop99 - - // Blend 100 / 0 - Copy row unchanged. - xloop100: - movdqu xmm0, [esi] - movdqu [esi + edi], xmm0 - lea esi, [esi + 16] - sub ecx, 16 - jg xloop100 - - xloop99: - pop edi - pop esi - ret - } -} - -// For BGRAToARGB, ABGRToARGB, RGBAToARGB, and ARGBToRGBA. -__declspec(naked) void ARGBShuffleRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_argb, - const uint8_t* shuffler, - int width) { - __asm { - mov eax, [esp + 4] // src_argb - mov edx, [esp + 8] // dst_argb - mov ecx, [esp + 12] // shuffler - movdqu xmm5, [ecx] - mov ecx, [esp + 16] // width - - wloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - lea eax, [eax + 32] - pshufb xmm0, xmm5 - pshufb xmm1, xmm5 - movdqu [edx], xmm0 - movdqu [edx + 16], xmm1 - lea edx, [edx + 32] - sub ecx, 8 - jg wloop - ret - } -} - -#ifdef HAS_ARGBSHUFFLEROW_AVX2 -__declspec(naked) void ARGBShuffleRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_argb, - const uint8_t* shuffler, - int width) { - __asm { - mov eax, [esp + 4] // src_argb - mov edx, [esp + 8] // dst_argb - mov ecx, [esp + 12] // shuffler - vbroadcastf128 ymm5, [ecx] // same shuffle in high as low. - mov ecx, [esp + 16] // width - - wloop: - vmovdqu ymm0, [eax] - vmovdqu ymm1, [eax + 32] - lea eax, [eax + 64] - vpshufb ymm0, ymm0, ymm5 - vpshufb ymm1, ymm1, ymm5 - vmovdqu [edx], ymm0 - vmovdqu [edx + 32], ymm1 - lea edx, [edx + 64] - sub ecx, 16 - jg wloop - - vzeroupper - ret - } -} -#endif // HAS_ARGBSHUFFLEROW_AVX2 - -// YUY2 - Macro-pixel = 2 image pixels -// Y0U0Y1V0....Y2U2Y3V2...Y4U4Y5V4.... - -// UYVY - Macro-pixel = 2 image pixels -// U0Y0V0Y1 - -__declspec(naked) void I422ToYUY2Row_SSE2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_frame, - int width) { - __asm { - push esi - push edi - mov eax, [esp + 8 + 4] // src_y - mov esi, [esp + 8 + 8] // src_u - mov edx, [esp + 8 + 12] // src_v - mov edi, [esp + 8 + 16] // dst_frame - mov ecx, [esp + 8 + 20] // width - sub edx, esi - - convertloop: - movq xmm2, qword ptr [esi] // U - movq xmm3, qword ptr [esi + edx] // V - lea esi, [esi + 8] - punpcklbw xmm2, xmm3 // UV - movdqu xmm0, [eax] // Y - lea eax, [eax + 16] - movdqa xmm1, xmm0 - punpcklbw xmm0, xmm2 // YUYV - punpckhbw xmm1, xmm2 - movdqu [edi], xmm0 - movdqu [edi + 16], xmm1 - lea edi, [edi + 32] - sub ecx, 16 - jg convertloop - - pop edi - pop esi - ret - } -} - -__declspec(naked) void I422ToUYVYRow_SSE2(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_frame, - int width) { - __asm { - push esi - push edi - mov eax, [esp + 8 + 4] // src_y - mov esi, [esp + 8 + 8] // src_u - mov edx, [esp + 8 + 12] // src_v - mov edi, [esp + 8 + 16] // dst_frame - mov ecx, [esp + 8 + 20] // width - sub edx, esi - - convertloop: - movq xmm2, qword ptr [esi] // U - movq xmm3, qword ptr [esi + edx] // V - lea esi, [esi + 8] - punpcklbw xmm2, xmm3 // UV - movdqu xmm0, [eax] // Y - movdqa xmm1, xmm2 - lea eax, [eax + 16] - punpcklbw xmm1, xmm0 // UYVY - punpckhbw xmm2, xmm0 - movdqu [edi], xmm1 - movdqu [edi + 16], xmm2 - lea edi, [edi + 32] - sub ecx, 16 - jg convertloop - - pop edi - pop esi - ret - } -} - -#ifdef HAS_ARGBPOLYNOMIALROW_SSE2 -__declspec(naked) void ARGBPolynomialRow_SSE2(const uint8_t* src_argb, - uint8_t* dst_argb, - const float* poly, - int width) { - __asm { - push esi - mov eax, [esp + 4 + 4] /* src_argb */ - mov edx, [esp + 4 + 8] /* dst_argb */ - mov esi, [esp + 4 + 12] /* poly */ - mov ecx, [esp + 4 + 16] /* width */ - pxor xmm3, xmm3 // 0 constant for zero extending bytes to ints. - - // 2 pixel loop. - convertloop: - // pmovzxbd xmm0, dword ptr [eax] // BGRA pixel - // pmovzxbd xmm4, dword ptr [eax + 4] // BGRA pixel - movq xmm0, qword ptr [eax] // BGRABGRA - lea eax, [eax + 8] - punpcklbw xmm0, xmm3 - movdqa xmm4, xmm0 - punpcklwd xmm0, xmm3 // pixel 0 - punpckhwd xmm4, xmm3 // pixel 1 - cvtdq2ps xmm0, xmm0 // 4 floats - cvtdq2ps xmm4, xmm4 - movdqa xmm1, xmm0 // X - movdqa xmm5, xmm4 - mulps xmm0, [esi + 16] // C1 * X - mulps xmm4, [esi + 16] - addps xmm0, [esi] // result = C0 + C1 * X - addps xmm4, [esi] - movdqa xmm2, xmm1 - movdqa xmm6, xmm5 - mulps xmm2, xmm1 // X * X - mulps xmm6, xmm5 - mulps xmm1, xmm2 // X * X * X - mulps xmm5, xmm6 - mulps xmm2, [esi + 32] // C2 * X * X - mulps xmm6, [esi + 32] - mulps xmm1, [esi + 48] // C3 * X * X * X - mulps xmm5, [esi + 48] - addps xmm0, xmm2 // result += C2 * X * X - addps xmm4, xmm6 - addps xmm0, xmm1 // result += C3 * X * X * X - addps xmm4, xmm5 - cvttps2dq xmm0, xmm0 - cvttps2dq xmm4, xmm4 - packuswb xmm0, xmm4 - packuswb xmm0, xmm0 - movq qword ptr [edx], xmm0 - lea edx, [edx + 8] - sub ecx, 2 - jg convertloop - pop esi - ret - } -} -#endif // HAS_ARGBPOLYNOMIALROW_SSE2 - -#ifdef HAS_ARGBPOLYNOMIALROW_AVX2 -__declspec(naked) void ARGBPolynomialRow_AVX2(const uint8_t* src_argb, - uint8_t* dst_argb, - const float* poly, - int width) { - __asm { - mov eax, [esp + 4] /* src_argb */ - mov edx, [esp + 8] /* dst_argb */ - mov ecx, [esp + 12] /* poly */ - vbroadcastf128 ymm4, [ecx] // C0 - vbroadcastf128 ymm5, [ecx + 16] // C1 - vbroadcastf128 ymm6, [ecx + 32] // C2 - vbroadcastf128 ymm7, [ecx + 48] // C3 - mov ecx, [esp + 16] /* width */ - - // 2 pixel loop. - convertloop: - vpmovzxbd ymm0, qword ptr [eax] // 2 BGRA pixels - lea eax, [eax + 8] - vcvtdq2ps ymm0, ymm0 // X 8 floats - vmulps ymm2, ymm0, ymm0 // X * X - vmulps ymm3, ymm0, ymm7 // C3 * X - vfmadd132ps ymm0, ymm4, ymm5 // result = C0 + C1 * X - vfmadd231ps ymm0, ymm2, ymm6 // result += C2 * X * X - vfmadd231ps ymm0, ymm2, ymm3 // result += C3 * X * X * X - vcvttps2dq ymm0, ymm0 - vpackusdw ymm0, ymm0, ymm0 // b0g0r0a0_00000000_b0g0r0a0_00000000 - vpermq ymm0, ymm0, 0xd8 // b0g0r0a0_b0g0r0a0_00000000_00000000 - vpackuswb xmm0, xmm0, xmm0 // bgrabgra_00000000_00000000_00000000 - vmovq qword ptr [edx], xmm0 - lea edx, [edx + 8] - sub ecx, 2 - jg convertloop - vzeroupper - ret - } -} -#endif // HAS_ARGBPOLYNOMIALROW_AVX2 - -#ifdef HAS_HALFFLOATROW_SSE2 -static float kExpBias = 1.9259299444e-34f; -__declspec(naked) void HalfFloatRow_SSE2(const uint16_t* src, - uint16_t* dst, - float scale, - int width) { - __asm { - mov eax, [esp + 4] /* src */ - mov edx, [esp + 8] /* dst */ - movd xmm4, dword ptr [esp + 12] /* scale */ - mov ecx, [esp + 16] /* width */ - mulss xmm4, kExpBias - pshufd xmm4, xmm4, 0 - pxor xmm5, xmm5 - sub edx, eax - - // 8 pixel loop. - convertloop: - movdqu xmm2, xmmword ptr [eax] // 8 shorts - add eax, 16 - movdqa xmm3, xmm2 - punpcklwd xmm2, xmm5 - cvtdq2ps xmm2, xmm2 // convert 8 ints to floats - punpckhwd xmm3, xmm5 - cvtdq2ps xmm3, xmm3 - mulps xmm2, xmm4 - mulps xmm3, xmm4 - psrld xmm2, 13 - psrld xmm3, 13 - packssdw xmm2, xmm3 - movdqu [eax + edx - 16], xmm2 - sub ecx, 8 - jg convertloop - ret - } -} -#endif // HAS_HALFFLOATROW_SSE2 - -#ifdef HAS_HALFFLOATROW_AVX2 -__declspec(naked) void HalfFloatRow_AVX2(const uint16_t* src, - uint16_t* dst, - float scale, - int width) { - __asm { - mov eax, [esp + 4] /* src */ - mov edx, [esp + 8] /* dst */ - movd xmm4, dword ptr [esp + 12] /* scale */ - mov ecx, [esp + 16] /* width */ - - vmulss xmm4, xmm4, kExpBias - vbroadcastss ymm4, xmm4 - vpxor ymm5, ymm5, ymm5 - sub edx, eax - - // 16 pixel loop. - convertloop: - vmovdqu ymm2, [eax] // 16 shorts - add eax, 32 - vpunpckhwd ymm3, ymm2, ymm5 // convert 16 shorts to 16 ints - vpunpcklwd ymm2, ymm2, ymm5 - vcvtdq2ps ymm3, ymm3 // convert 16 ints to floats - vcvtdq2ps ymm2, ymm2 - vmulps ymm3, ymm3, ymm4 // scale to adjust exponent for 5 bit range. - vmulps ymm2, ymm2, ymm4 - vpsrld ymm3, ymm3, 13 // float convert to 8 half floats truncate - vpsrld ymm2, ymm2, 13 - vpackssdw ymm2, ymm2, ymm3 - vmovdqu [eax + edx - 32], ymm2 - sub ecx, 16 - jg convertloop - vzeroupper - ret - } -} -#endif // HAS_HALFFLOATROW_AVX2 - -#ifdef HAS_HALFFLOATROW_F16C -__declspec(naked) void HalfFloatRow_F16C(const uint16_t* src, - uint16_t* dst, - float scale, - int width) { - __asm { - mov eax, [esp + 4] /* src */ - mov edx, [esp + 8] /* dst */ - vbroadcastss ymm4, [esp + 12] /* scale */ - mov ecx, [esp + 16] /* width */ - sub edx, eax - - // 16 pixel loop. - convertloop: - vpmovzxwd ymm2, xmmword ptr [eax] // 8 shorts -> 8 ints - vpmovzxwd ymm3, xmmword ptr [eax + 16] // 8 more shorts - add eax, 32 - vcvtdq2ps ymm2, ymm2 // convert 8 ints to floats - vcvtdq2ps ymm3, ymm3 - vmulps ymm2, ymm2, ymm4 // scale to normalized range 0 to 1 - vmulps ymm3, ymm3, ymm4 - vcvtps2ph xmm2, ymm2, 3 // float convert to 8 half floats truncate - vcvtps2ph xmm3, ymm3, 3 - vmovdqu [eax + edx + 32], xmm2 - vmovdqu [eax + edx + 32 + 16], xmm3 - sub ecx, 16 - jg convertloop - vzeroupper - ret - } -} -#endif // HAS_HALFFLOATROW_F16C - -#ifdef HAS_ARGBCOLORTABLEROW_X86 -// Tranform ARGB pixels with color table. -__declspec(naked) void ARGBColorTableRow_X86(uint8_t* dst_argb, - const uint8_t* table_argb, - int width) { - __asm { - push esi - mov eax, [esp + 4 + 4] /* dst_argb */ - mov esi, [esp + 4 + 8] /* table_argb */ - mov ecx, [esp + 4 + 12] /* width */ - - // 1 pixel loop. - convertloop: - movzx edx, byte ptr [eax] - lea eax, [eax + 4] - movzx edx, byte ptr [esi + edx * 4] - mov byte ptr [eax - 4], dl - movzx edx, byte ptr [eax - 4 + 1] - movzx edx, byte ptr [esi + edx * 4 + 1] - mov byte ptr [eax - 4 + 1], dl - movzx edx, byte ptr [eax - 4 + 2] - movzx edx, byte ptr [esi + edx * 4 + 2] - mov byte ptr [eax - 4 + 2], dl - movzx edx, byte ptr [eax - 4 + 3] - movzx edx, byte ptr [esi + edx * 4 + 3] - mov byte ptr [eax - 4 + 3], dl - dec ecx - jg convertloop - pop esi - ret - } -} -#endif // HAS_ARGBCOLORTABLEROW_X86 - -#ifdef HAS_RGBCOLORTABLEROW_X86 -// Tranform RGB pixels with color table. -__declspec(naked) void RGBColorTableRow_X86(uint8_t* dst_argb, - const uint8_t* table_argb, - int width) { - __asm { - push esi - mov eax, [esp + 4 + 4] /* dst_argb */ - mov esi, [esp + 4 + 8] /* table_argb */ - mov ecx, [esp + 4 + 12] /* width */ - - // 1 pixel loop. - convertloop: - movzx edx, byte ptr [eax] - lea eax, [eax + 4] - movzx edx, byte ptr [esi + edx * 4] - mov byte ptr [eax - 4], dl - movzx edx, byte ptr [eax - 4 + 1] - movzx edx, byte ptr [esi + edx * 4 + 1] - mov byte ptr [eax - 4 + 1], dl - movzx edx, byte ptr [eax - 4 + 2] - movzx edx, byte ptr [esi + edx * 4 + 2] - mov byte ptr [eax - 4 + 2], dl - dec ecx - jg convertloop - - pop esi - ret - } -} -#endif // HAS_RGBCOLORTABLEROW_X86 - -#ifdef HAS_ARGBLUMACOLORTABLEROW_SSSE3 -// Tranform RGB pixels with luma table. -__declspec(naked) void ARGBLumaColorTableRow_SSSE3(const uint8_t* src_argb, - uint8_t* dst_argb, - int width, - const uint8_t* luma, - uint32_t lumacoeff) { - __asm { - push esi - push edi - mov eax, [esp + 8 + 4] /* src_argb */ - mov edi, [esp + 8 + 8] /* dst_argb */ - mov ecx, [esp + 8 + 12] /* width */ - movd xmm2, dword ptr [esp + 8 + 16] // luma table - movd xmm3, dword ptr [esp + 8 + 20] // lumacoeff - pshufd xmm2, xmm2, 0 - pshufd xmm3, xmm3, 0 - pcmpeqb xmm4, xmm4 // generate mask 0xff00ff00 - psllw xmm4, 8 - pxor xmm5, xmm5 - - // 4 pixel loop. - convertloop: - movdqu xmm0, xmmword ptr [eax] // generate luma ptr - pmaddubsw xmm0, xmm3 - phaddw xmm0, xmm0 - pand xmm0, xmm4 // mask out low bits - punpcklwd xmm0, xmm5 - paddd xmm0, xmm2 // add table base - movd esi, xmm0 - pshufd xmm0, xmm0, 0x39 // 00111001 to rotate right 32 - - movzx edx, byte ptr [eax] - movzx edx, byte ptr [esi + edx] - mov byte ptr [edi], dl - movzx edx, byte ptr [eax + 1] - movzx edx, byte ptr [esi + edx] - mov byte ptr [edi + 1], dl - movzx edx, byte ptr [eax + 2] - movzx edx, byte ptr [esi + edx] - mov byte ptr [edi + 2], dl - movzx edx, byte ptr [eax + 3] // copy alpha. - mov byte ptr [edi + 3], dl - - movd esi, xmm0 - pshufd xmm0, xmm0, 0x39 // 00111001 to rotate right 32 - - movzx edx, byte ptr [eax + 4] - movzx edx, byte ptr [esi + edx] - mov byte ptr [edi + 4], dl - movzx edx, byte ptr [eax + 5] - movzx edx, byte ptr [esi + edx] - mov byte ptr [edi + 5], dl - movzx edx, byte ptr [eax + 6] - movzx edx, byte ptr [esi + edx] - mov byte ptr [edi + 6], dl - movzx edx, byte ptr [eax + 7] // copy alpha. - mov byte ptr [edi + 7], dl - - movd esi, xmm0 - pshufd xmm0, xmm0, 0x39 // 00111001 to rotate right 32 - - movzx edx, byte ptr [eax + 8] - movzx edx, byte ptr [esi + edx] - mov byte ptr [edi + 8], dl - movzx edx, byte ptr [eax + 9] - movzx edx, byte ptr [esi + edx] - mov byte ptr [edi + 9], dl - movzx edx, byte ptr [eax + 10] - movzx edx, byte ptr [esi + edx] - mov byte ptr [edi + 10], dl - movzx edx, byte ptr [eax + 11] // copy alpha. - mov byte ptr [edi + 11], dl - - movd esi, xmm0 - - movzx edx, byte ptr [eax + 12] - movzx edx, byte ptr [esi + edx] - mov byte ptr [edi + 12], dl - movzx edx, byte ptr [eax + 13] - movzx edx, byte ptr [esi + edx] - mov byte ptr [edi + 13], dl - movzx edx, byte ptr [eax + 14] - movzx edx, byte ptr [esi + edx] - mov byte ptr [edi + 14], dl - movzx edx, byte ptr [eax + 15] // copy alpha. - mov byte ptr [edi + 15], dl - - lea eax, [eax + 16] - lea edi, [edi + 16] - sub ecx, 4 - jg convertloop - - pop edi - pop esi - ret - } -} -#endif // HAS_ARGBLUMACOLORTABLEROW_SSSE3 - -#endif // defined(_M_X64) - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // !defined(LIBYUV_DISABLE_X86) && (defined(_M_IX86) || defined(_M_X64)) diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale.cc deleted file mode 100644 index 2cfa1c6c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale.cc +++ /dev/null @@ -1,1741 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/scale.h" - -#include -#include - -#include "libyuv/cpu_id.h" -#include "libyuv/planar_functions.h" // For CopyPlane -#include "libyuv/row.h" -#include "libyuv/scale_row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -static __inline int Abs(int v) { - return v >= 0 ? v : -v; -} - -#define SUBSAMPLE(v, a, s) (v < 0) ? (-((-v + a) >> s)) : ((v + a) >> s) - -// Scale plane, 1/2 -// This is an optimized version for scaling down a plane to 1/2 of -// its original size. - -static void ScalePlaneDown2(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_ptr, - uint8_t* dst_ptr, - enum FilterMode filtering) { - int y; - void (*ScaleRowDown2)(const uint8_t* src_ptr, ptrdiff_t src_stride, - uint8_t* dst_ptr, int dst_width) = - filtering == kFilterNone - ? ScaleRowDown2_C - : (filtering == kFilterLinear ? ScaleRowDown2Linear_C - : ScaleRowDown2Box_C); - int row_stride = src_stride << 1; - (void)src_width; - (void)src_height; - if (!filtering) { - src_ptr += src_stride; // Point to odd rows. - src_stride = 0; - } - -#if defined(HAS_SCALEROWDOWN2_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ScaleRowDown2 = - filtering == kFilterNone - ? ScaleRowDown2_Any_NEON - : (filtering == kFilterLinear ? ScaleRowDown2Linear_Any_NEON - : ScaleRowDown2Box_Any_NEON); - if (IS_ALIGNED(dst_width, 16)) { - ScaleRowDown2 = filtering == kFilterNone ? ScaleRowDown2_NEON - : (filtering == kFilterLinear - ? ScaleRowDown2Linear_NEON - : ScaleRowDown2Box_NEON); - } - } -#endif -#if defined(HAS_SCALEROWDOWN2_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - ScaleRowDown2 = - filtering == kFilterNone - ? ScaleRowDown2_Any_SSSE3 - : (filtering == kFilterLinear ? ScaleRowDown2Linear_Any_SSSE3 - : ScaleRowDown2Box_Any_SSSE3); - if (IS_ALIGNED(dst_width, 16)) { - ScaleRowDown2 = - filtering == kFilterNone - ? ScaleRowDown2_SSSE3 - : (filtering == kFilterLinear ? ScaleRowDown2Linear_SSSE3 - : ScaleRowDown2Box_SSSE3); - } - } -#endif -#if defined(HAS_SCALEROWDOWN2_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ScaleRowDown2 = - filtering == kFilterNone - ? ScaleRowDown2_Any_AVX2 - : (filtering == kFilterLinear ? ScaleRowDown2Linear_Any_AVX2 - : ScaleRowDown2Box_Any_AVX2); - if (IS_ALIGNED(dst_width, 32)) { - ScaleRowDown2 = filtering == kFilterNone ? ScaleRowDown2_AVX2 - : (filtering == kFilterLinear - ? ScaleRowDown2Linear_AVX2 - : ScaleRowDown2Box_AVX2); - } - } -#endif -#if defined(HAS_SCALEROWDOWN2_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ScaleRowDown2 = - filtering == kFilterNone - ? ScaleRowDown2_Any_MSA - : (filtering == kFilterLinear ? ScaleRowDown2Linear_Any_MSA - : ScaleRowDown2Box_Any_MSA); - if (IS_ALIGNED(dst_width, 32)) { - ScaleRowDown2 = filtering == kFilterNone ? ScaleRowDown2_MSA - : (filtering == kFilterLinear - ? ScaleRowDown2Linear_MSA - : ScaleRowDown2Box_MSA); - } - } -#endif - - if (filtering == kFilterLinear) { - src_stride = 0; - } - // TODO(fbarchard): Loop through source height to allow odd height. - for (y = 0; y < dst_height; ++y) { - ScaleRowDown2(src_ptr, src_stride, dst_ptr, dst_width); - src_ptr += row_stride; - dst_ptr += dst_stride; - } -} - -static void ScalePlaneDown2_16(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint16_t* src_ptr, - uint16_t* dst_ptr, - enum FilterMode filtering) { - int y; - void (*ScaleRowDown2)(const uint16_t* src_ptr, ptrdiff_t src_stride, - uint16_t* dst_ptr, int dst_width) = - filtering == kFilterNone - ? ScaleRowDown2_16_C - : (filtering == kFilterLinear ? ScaleRowDown2Linear_16_C - : ScaleRowDown2Box_16_C); - int row_stride = src_stride << 1; - (void)src_width; - (void)src_height; - if (!filtering) { - src_ptr += src_stride; // Point to odd rows. - src_stride = 0; - } - -#if defined(HAS_SCALEROWDOWN2_16_NEON) - if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(dst_width, 16)) { - ScaleRowDown2 = - filtering ? ScaleRowDown2Box_16_NEON : ScaleRowDown2_16_NEON; - } -#endif -#if defined(HAS_SCALEROWDOWN2_16_SSE2) - if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 16)) { - ScaleRowDown2 = - filtering == kFilterNone - ? ScaleRowDown2_16_SSE2 - : (filtering == kFilterLinear ? ScaleRowDown2Linear_16_SSE2 - : ScaleRowDown2Box_16_SSE2); - } -#endif - - if (filtering == kFilterLinear) { - src_stride = 0; - } - // TODO(fbarchard): Loop through source height to allow odd height. - for (y = 0; y < dst_height; ++y) { - ScaleRowDown2(src_ptr, src_stride, dst_ptr, dst_width); - src_ptr += row_stride; - dst_ptr += dst_stride; - } -} - -// Scale plane, 1/4 -// This is an optimized version for scaling down a plane to 1/4 of -// its original size. - -static void ScalePlaneDown4(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_ptr, - uint8_t* dst_ptr, - enum FilterMode filtering) { - int y; - void (*ScaleRowDown4)(const uint8_t* src_ptr, ptrdiff_t src_stride, - uint8_t* dst_ptr, int dst_width) = - filtering ? ScaleRowDown4Box_C : ScaleRowDown4_C; - int row_stride = src_stride << 2; - (void)src_width; - (void)src_height; - if (!filtering) { - src_ptr += src_stride * 2; // Point to row 2. - src_stride = 0; - } -#if defined(HAS_SCALEROWDOWN4_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ScaleRowDown4 = - filtering ? ScaleRowDown4Box_Any_NEON : ScaleRowDown4_Any_NEON; - if (IS_ALIGNED(dst_width, 8)) { - ScaleRowDown4 = filtering ? ScaleRowDown4Box_NEON : ScaleRowDown4_NEON; - } - } -#endif -#if defined(HAS_SCALEROWDOWN4_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - ScaleRowDown4 = - filtering ? ScaleRowDown4Box_Any_SSSE3 : ScaleRowDown4_Any_SSSE3; - if (IS_ALIGNED(dst_width, 8)) { - ScaleRowDown4 = filtering ? ScaleRowDown4Box_SSSE3 : ScaleRowDown4_SSSE3; - } - } -#endif -#if defined(HAS_SCALEROWDOWN4_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ScaleRowDown4 = - filtering ? ScaleRowDown4Box_Any_AVX2 : ScaleRowDown4_Any_AVX2; - if (IS_ALIGNED(dst_width, 16)) { - ScaleRowDown4 = filtering ? ScaleRowDown4Box_AVX2 : ScaleRowDown4_AVX2; - } - } -#endif -#if defined(HAS_SCALEROWDOWN4_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ScaleRowDown4 = - filtering ? ScaleRowDown4Box_Any_MSA : ScaleRowDown4_Any_MSA; - if (IS_ALIGNED(dst_width, 16)) { - ScaleRowDown4 = filtering ? ScaleRowDown4Box_MSA : ScaleRowDown4_MSA; - } - } -#endif - - if (filtering == kFilterLinear) { - src_stride = 0; - } - for (y = 0; y < dst_height; ++y) { - ScaleRowDown4(src_ptr, src_stride, dst_ptr, dst_width); - src_ptr += row_stride; - dst_ptr += dst_stride; - } -} - -static void ScalePlaneDown4_16(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint16_t* src_ptr, - uint16_t* dst_ptr, - enum FilterMode filtering) { - int y; - void (*ScaleRowDown4)(const uint16_t* src_ptr, ptrdiff_t src_stride, - uint16_t* dst_ptr, int dst_width) = - filtering ? ScaleRowDown4Box_16_C : ScaleRowDown4_16_C; - int row_stride = src_stride << 2; - (void)src_width; - (void)src_height; - if (!filtering) { - src_ptr += src_stride * 2; // Point to row 2. - src_stride = 0; - } -#if defined(HAS_SCALEROWDOWN4_16_NEON) - if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(dst_width, 8)) { - ScaleRowDown4 = - filtering ? ScaleRowDown4Box_16_NEON : ScaleRowDown4_16_NEON; - } -#endif -#if defined(HAS_SCALEROWDOWN4_16_SSE2) - if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8)) { - ScaleRowDown4 = - filtering ? ScaleRowDown4Box_16_SSE2 : ScaleRowDown4_16_SSE2; - } -#endif - - if (filtering == kFilterLinear) { - src_stride = 0; - } - for (y = 0; y < dst_height; ++y) { - ScaleRowDown4(src_ptr, src_stride, dst_ptr, dst_width); - src_ptr += row_stride; - dst_ptr += dst_stride; - } -} - -// Scale plane down, 3/4 -static void ScalePlaneDown34(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_ptr, - uint8_t* dst_ptr, - enum FilterMode filtering) { - int y; - void (*ScaleRowDown34_0)(const uint8_t* src_ptr, ptrdiff_t src_stride, - uint8_t* dst_ptr, int dst_width); - void (*ScaleRowDown34_1)(const uint8_t* src_ptr, ptrdiff_t src_stride, - uint8_t* dst_ptr, int dst_width); - const int filter_stride = (filtering == kFilterLinear) ? 0 : src_stride; - (void)src_width; - (void)src_height; - assert(dst_width % 3 == 0); - if (!filtering) { - ScaleRowDown34_0 = ScaleRowDown34_C; - ScaleRowDown34_1 = ScaleRowDown34_C; - } else { - ScaleRowDown34_0 = ScaleRowDown34_0_Box_C; - ScaleRowDown34_1 = ScaleRowDown34_1_Box_C; - } -#if defined(HAS_SCALEROWDOWN34_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - if (!filtering) { - ScaleRowDown34_0 = ScaleRowDown34_Any_NEON; - ScaleRowDown34_1 = ScaleRowDown34_Any_NEON; - } else { - ScaleRowDown34_0 = ScaleRowDown34_0_Box_Any_NEON; - ScaleRowDown34_1 = ScaleRowDown34_1_Box_Any_NEON; - } - if (dst_width % 24 == 0) { - if (!filtering) { - ScaleRowDown34_0 = ScaleRowDown34_NEON; - ScaleRowDown34_1 = ScaleRowDown34_NEON; - } else { - ScaleRowDown34_0 = ScaleRowDown34_0_Box_NEON; - ScaleRowDown34_1 = ScaleRowDown34_1_Box_NEON; - } - } - } -#endif -#if defined(HAS_SCALEROWDOWN34_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - if (!filtering) { - ScaleRowDown34_0 = ScaleRowDown34_Any_MSA; - ScaleRowDown34_1 = ScaleRowDown34_Any_MSA; - } else { - ScaleRowDown34_0 = ScaleRowDown34_0_Box_Any_MSA; - ScaleRowDown34_1 = ScaleRowDown34_1_Box_Any_MSA; - } - if (dst_width % 48 == 0) { - if (!filtering) { - ScaleRowDown34_0 = ScaleRowDown34_MSA; - ScaleRowDown34_1 = ScaleRowDown34_MSA; - } else { - ScaleRowDown34_0 = ScaleRowDown34_0_Box_MSA; - ScaleRowDown34_1 = ScaleRowDown34_1_Box_MSA; - } - } - } -#endif -#if defined(HAS_SCALEROWDOWN34_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - if (!filtering) { - ScaleRowDown34_0 = ScaleRowDown34_Any_SSSE3; - ScaleRowDown34_1 = ScaleRowDown34_Any_SSSE3; - } else { - ScaleRowDown34_0 = ScaleRowDown34_0_Box_Any_SSSE3; - ScaleRowDown34_1 = ScaleRowDown34_1_Box_Any_SSSE3; - } - if (dst_width % 24 == 0) { - if (!filtering) { - ScaleRowDown34_0 = ScaleRowDown34_SSSE3; - ScaleRowDown34_1 = ScaleRowDown34_SSSE3; - } else { - ScaleRowDown34_0 = ScaleRowDown34_0_Box_SSSE3; - ScaleRowDown34_1 = ScaleRowDown34_1_Box_SSSE3; - } - } - } -#endif - - for (y = 0; y < dst_height - 2; y += 3) { - ScaleRowDown34_0(src_ptr, filter_stride, dst_ptr, dst_width); - src_ptr += src_stride; - dst_ptr += dst_stride; - ScaleRowDown34_1(src_ptr, filter_stride, dst_ptr, dst_width); - src_ptr += src_stride; - dst_ptr += dst_stride; - ScaleRowDown34_0(src_ptr + src_stride, -filter_stride, dst_ptr, dst_width); - src_ptr += src_stride * 2; - dst_ptr += dst_stride; - } - - // Remainder 1 or 2 rows with last row vertically unfiltered - if ((dst_height % 3) == 2) { - ScaleRowDown34_0(src_ptr, filter_stride, dst_ptr, dst_width); - src_ptr += src_stride; - dst_ptr += dst_stride; - ScaleRowDown34_1(src_ptr, 0, dst_ptr, dst_width); - } else if ((dst_height % 3) == 1) { - ScaleRowDown34_0(src_ptr, 0, dst_ptr, dst_width); - } -} - -static void ScalePlaneDown34_16(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint16_t* src_ptr, - uint16_t* dst_ptr, - enum FilterMode filtering) { - int y; - void (*ScaleRowDown34_0)(const uint16_t* src_ptr, ptrdiff_t src_stride, - uint16_t* dst_ptr, int dst_width); - void (*ScaleRowDown34_1)(const uint16_t* src_ptr, ptrdiff_t src_stride, - uint16_t* dst_ptr, int dst_width); - const int filter_stride = (filtering == kFilterLinear) ? 0 : src_stride; - (void)src_width; - (void)src_height; - assert(dst_width % 3 == 0); - if (!filtering) { - ScaleRowDown34_0 = ScaleRowDown34_16_C; - ScaleRowDown34_1 = ScaleRowDown34_16_C; - } else { - ScaleRowDown34_0 = ScaleRowDown34_0_Box_16_C; - ScaleRowDown34_1 = ScaleRowDown34_1_Box_16_C; - } -#if defined(HAS_SCALEROWDOWN34_16_NEON) - if (TestCpuFlag(kCpuHasNEON) && (dst_width % 24 == 0)) { - if (!filtering) { - ScaleRowDown34_0 = ScaleRowDown34_16_NEON; - ScaleRowDown34_1 = ScaleRowDown34_16_NEON; - } else { - ScaleRowDown34_0 = ScaleRowDown34_0_Box_16_NEON; - ScaleRowDown34_1 = ScaleRowDown34_1_Box_16_NEON; - } - } -#endif -#if defined(HAS_SCALEROWDOWN34_16_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3) && (dst_width % 24 == 0)) { - if (!filtering) { - ScaleRowDown34_0 = ScaleRowDown34_16_SSSE3; - ScaleRowDown34_1 = ScaleRowDown34_16_SSSE3; - } else { - ScaleRowDown34_0 = ScaleRowDown34_0_Box_16_SSSE3; - ScaleRowDown34_1 = ScaleRowDown34_1_Box_16_SSSE3; - } - } -#endif - - for (y = 0; y < dst_height - 2; y += 3) { - ScaleRowDown34_0(src_ptr, filter_stride, dst_ptr, dst_width); - src_ptr += src_stride; - dst_ptr += dst_stride; - ScaleRowDown34_1(src_ptr, filter_stride, dst_ptr, dst_width); - src_ptr += src_stride; - dst_ptr += dst_stride; - ScaleRowDown34_0(src_ptr + src_stride, -filter_stride, dst_ptr, dst_width); - src_ptr += src_stride * 2; - dst_ptr += dst_stride; - } - - // Remainder 1 or 2 rows with last row vertically unfiltered - if ((dst_height % 3) == 2) { - ScaleRowDown34_0(src_ptr, filter_stride, dst_ptr, dst_width); - src_ptr += src_stride; - dst_ptr += dst_stride; - ScaleRowDown34_1(src_ptr, 0, dst_ptr, dst_width); - } else if ((dst_height % 3) == 1) { - ScaleRowDown34_0(src_ptr, 0, dst_ptr, dst_width); - } -} - -// Scale plane, 3/8 -// This is an optimized version for scaling down a plane to 3/8 -// of its original size. -// -// Uses box filter arranges like this -// aaabbbcc -> abc -// aaabbbcc def -// aaabbbcc ghi -// dddeeeff -// dddeeeff -// dddeeeff -// ggghhhii -// ggghhhii -// Boxes are 3x3, 2x3, 3x2 and 2x2 - -static void ScalePlaneDown38(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_ptr, - uint8_t* dst_ptr, - enum FilterMode filtering) { - int y; - void (*ScaleRowDown38_3)(const uint8_t* src_ptr, ptrdiff_t src_stride, - uint8_t* dst_ptr, int dst_width); - void (*ScaleRowDown38_2)(const uint8_t* src_ptr, ptrdiff_t src_stride, - uint8_t* dst_ptr, int dst_width); - const int filter_stride = (filtering == kFilterLinear) ? 0 : src_stride; - assert(dst_width % 3 == 0); - (void)src_width; - (void)src_height; - if (!filtering) { - ScaleRowDown38_3 = ScaleRowDown38_C; - ScaleRowDown38_2 = ScaleRowDown38_C; - } else { - ScaleRowDown38_3 = ScaleRowDown38_3_Box_C; - ScaleRowDown38_2 = ScaleRowDown38_2_Box_C; - } - -#if defined(HAS_SCALEROWDOWN38_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - if (!filtering) { - ScaleRowDown38_3 = ScaleRowDown38_Any_NEON; - ScaleRowDown38_2 = ScaleRowDown38_Any_NEON; - } else { - ScaleRowDown38_3 = ScaleRowDown38_3_Box_Any_NEON; - ScaleRowDown38_2 = ScaleRowDown38_2_Box_Any_NEON; - } - if (dst_width % 12 == 0) { - if (!filtering) { - ScaleRowDown38_3 = ScaleRowDown38_NEON; - ScaleRowDown38_2 = ScaleRowDown38_NEON; - } else { - ScaleRowDown38_3 = ScaleRowDown38_3_Box_NEON; - ScaleRowDown38_2 = ScaleRowDown38_2_Box_NEON; - } - } - } -#endif -#if defined(HAS_SCALEROWDOWN38_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - if (!filtering) { - ScaleRowDown38_3 = ScaleRowDown38_Any_SSSE3; - ScaleRowDown38_2 = ScaleRowDown38_Any_SSSE3; - } else { - ScaleRowDown38_3 = ScaleRowDown38_3_Box_Any_SSSE3; - ScaleRowDown38_2 = ScaleRowDown38_2_Box_Any_SSSE3; - } - if (dst_width % 12 == 0 && !filtering) { - ScaleRowDown38_3 = ScaleRowDown38_SSSE3; - ScaleRowDown38_2 = ScaleRowDown38_SSSE3; - } - if (dst_width % 6 == 0 && filtering) { - ScaleRowDown38_3 = ScaleRowDown38_3_Box_SSSE3; - ScaleRowDown38_2 = ScaleRowDown38_2_Box_SSSE3; - } - } -#endif -#if defined(HAS_SCALEROWDOWN38_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - if (!filtering) { - ScaleRowDown38_3 = ScaleRowDown38_Any_MSA; - ScaleRowDown38_2 = ScaleRowDown38_Any_MSA; - } else { - ScaleRowDown38_3 = ScaleRowDown38_3_Box_Any_MSA; - ScaleRowDown38_2 = ScaleRowDown38_2_Box_Any_MSA; - } - if (dst_width % 12 == 0) { - if (!filtering) { - ScaleRowDown38_3 = ScaleRowDown38_MSA; - ScaleRowDown38_2 = ScaleRowDown38_MSA; - } else { - ScaleRowDown38_3 = ScaleRowDown38_3_Box_MSA; - ScaleRowDown38_2 = ScaleRowDown38_2_Box_MSA; - } - } - } -#endif - - for (y = 0; y < dst_height - 2; y += 3) { - ScaleRowDown38_3(src_ptr, filter_stride, dst_ptr, dst_width); - src_ptr += src_stride * 3; - dst_ptr += dst_stride; - ScaleRowDown38_3(src_ptr, filter_stride, dst_ptr, dst_width); - src_ptr += src_stride * 3; - dst_ptr += dst_stride; - ScaleRowDown38_2(src_ptr, filter_stride, dst_ptr, dst_width); - src_ptr += src_stride * 2; - dst_ptr += dst_stride; - } - - // Remainder 1 or 2 rows with last row vertically unfiltered - if ((dst_height % 3) == 2) { - ScaleRowDown38_3(src_ptr, filter_stride, dst_ptr, dst_width); - src_ptr += src_stride * 3; - dst_ptr += dst_stride; - ScaleRowDown38_3(src_ptr, 0, dst_ptr, dst_width); - } else if ((dst_height % 3) == 1) { - ScaleRowDown38_3(src_ptr, 0, dst_ptr, dst_width); - } -} - -static void ScalePlaneDown38_16(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint16_t* src_ptr, - uint16_t* dst_ptr, - enum FilterMode filtering) { - int y; - void (*ScaleRowDown38_3)(const uint16_t* src_ptr, ptrdiff_t src_stride, - uint16_t* dst_ptr, int dst_width); - void (*ScaleRowDown38_2)(const uint16_t* src_ptr, ptrdiff_t src_stride, - uint16_t* dst_ptr, int dst_width); - const int filter_stride = (filtering == kFilterLinear) ? 0 : src_stride; - (void)src_width; - (void)src_height; - assert(dst_width % 3 == 0); - if (!filtering) { - ScaleRowDown38_3 = ScaleRowDown38_16_C; - ScaleRowDown38_2 = ScaleRowDown38_16_C; - } else { - ScaleRowDown38_3 = ScaleRowDown38_3_Box_16_C; - ScaleRowDown38_2 = ScaleRowDown38_2_Box_16_C; - } -#if defined(HAS_SCALEROWDOWN38_16_NEON) - if (TestCpuFlag(kCpuHasNEON) && (dst_width % 12 == 0)) { - if (!filtering) { - ScaleRowDown38_3 = ScaleRowDown38_16_NEON; - ScaleRowDown38_2 = ScaleRowDown38_16_NEON; - } else { - ScaleRowDown38_3 = ScaleRowDown38_3_Box_16_NEON; - ScaleRowDown38_2 = ScaleRowDown38_2_Box_16_NEON; - } - } -#endif -#if defined(HAS_SCALEROWDOWN38_16_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3) && (dst_width % 24 == 0)) { - if (!filtering) { - ScaleRowDown38_3 = ScaleRowDown38_16_SSSE3; - ScaleRowDown38_2 = ScaleRowDown38_16_SSSE3; - } else { - ScaleRowDown38_3 = ScaleRowDown38_3_Box_16_SSSE3; - ScaleRowDown38_2 = ScaleRowDown38_2_Box_16_SSSE3; - } - } -#endif - - for (y = 0; y < dst_height - 2; y += 3) { - ScaleRowDown38_3(src_ptr, filter_stride, dst_ptr, dst_width); - src_ptr += src_stride * 3; - dst_ptr += dst_stride; - ScaleRowDown38_3(src_ptr, filter_stride, dst_ptr, dst_width); - src_ptr += src_stride * 3; - dst_ptr += dst_stride; - ScaleRowDown38_2(src_ptr, filter_stride, dst_ptr, dst_width); - src_ptr += src_stride * 2; - dst_ptr += dst_stride; - } - - // Remainder 1 or 2 rows with last row vertically unfiltered - if ((dst_height % 3) == 2) { - ScaleRowDown38_3(src_ptr, filter_stride, dst_ptr, dst_width); - src_ptr += src_stride * 3; - dst_ptr += dst_stride; - ScaleRowDown38_3(src_ptr, 0, dst_ptr, dst_width); - } else if ((dst_height % 3) == 1) { - ScaleRowDown38_3(src_ptr, 0, dst_ptr, dst_width); - } -} - -#define MIN1(x) ((x) < 1 ? 1 : (x)) - -static __inline uint32_t SumPixels(int iboxwidth, const uint16_t* src_ptr) { - uint32_t sum = 0u; - int x; - assert(iboxwidth > 0); - for (x = 0; x < iboxwidth; ++x) { - sum += src_ptr[x]; - } - return sum; -} - -static __inline uint32_t SumPixels_16(int iboxwidth, const uint32_t* src_ptr) { - uint32_t sum = 0u; - int x; - assert(iboxwidth > 0); - for (x = 0; x < iboxwidth; ++x) { - sum += src_ptr[x]; - } - return sum; -} - -static void ScaleAddCols2_C(int dst_width, - int boxheight, - int x, - int dx, - const uint16_t* src_ptr, - uint8_t* dst_ptr) { - int i; - int scaletbl[2]; - int minboxwidth = dx >> 16; - int boxwidth; - scaletbl[0] = 65536 / (MIN1(minboxwidth) * boxheight); - scaletbl[1] = 65536 / (MIN1(minboxwidth + 1) * boxheight); - for (i = 0; i < dst_width; ++i) { - int ix = x >> 16; - x += dx; - boxwidth = MIN1((x >> 16) - ix); - *dst_ptr++ = - SumPixels(boxwidth, src_ptr + ix) * scaletbl[boxwidth - minboxwidth] >> - 16; - } -} - -static void ScaleAddCols2_16_C(int dst_width, - int boxheight, - int x, - int dx, - const uint32_t* src_ptr, - uint16_t* dst_ptr) { - int i; - int scaletbl[2]; - int minboxwidth = dx >> 16; - int boxwidth; - scaletbl[0] = 65536 / (MIN1(minboxwidth) * boxheight); - scaletbl[1] = 65536 / (MIN1(minboxwidth + 1) * boxheight); - for (i = 0; i < dst_width; ++i) { - int ix = x >> 16; - x += dx; - boxwidth = MIN1((x >> 16) - ix); - *dst_ptr++ = SumPixels_16(boxwidth, src_ptr + ix) * - scaletbl[boxwidth - minboxwidth] >> - 16; - } -} - -static void ScaleAddCols0_C(int dst_width, - int boxheight, - int x, - int dx, - const uint16_t* src_ptr, - uint8_t* dst_ptr) { - int scaleval = 65536 / boxheight; - int i; - (void)dx; - src_ptr += (x >> 16); - for (i = 0; i < dst_width; ++i) { - *dst_ptr++ = src_ptr[i] * scaleval >> 16; - } -} - -static void ScaleAddCols1_C(int dst_width, - int boxheight, - int x, - int dx, - const uint16_t* src_ptr, - uint8_t* dst_ptr) { - int boxwidth = MIN1(dx >> 16); - int scaleval = 65536 / (boxwidth * boxheight); - int i; - x >>= 16; - for (i = 0; i < dst_width; ++i) { - *dst_ptr++ = SumPixels(boxwidth, src_ptr + x) * scaleval >> 16; - x += boxwidth; - } -} - -static void ScaleAddCols1_16_C(int dst_width, - int boxheight, - int x, - int dx, - const uint32_t* src_ptr, - uint16_t* dst_ptr) { - int boxwidth = MIN1(dx >> 16); - int scaleval = 65536 / (boxwidth * boxheight); - int i; - for (i = 0; i < dst_width; ++i) { - *dst_ptr++ = SumPixels_16(boxwidth, src_ptr + x) * scaleval >> 16; - x += boxwidth; - } -} - -// Scale plane down to any dimensions, with interpolation. -// (boxfilter). -// -// Same method as SimpleScale, which is fixed point, outputting -// one pixel of destination using fixed point (16.16) to step -// through source, sampling a box of pixel with simple -// averaging. -static void ScalePlaneBox(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_ptr, - uint8_t* dst_ptr) { - int j, k; - // Initial source x/y coordinate and step values as 16.16 fixed point. - int x = 0; - int y = 0; - int dx = 0; - int dy = 0; - const int max_y = (src_height << 16); - ScaleSlope(src_width, src_height, dst_width, dst_height, kFilterBox, &x, &y, - &dx, &dy); - src_width = Abs(src_width); - { - // Allocate a row buffer of uint16_t. - align_buffer_64(row16, src_width * 2); - void (*ScaleAddCols)(int dst_width, int boxheight, int x, int dx, - const uint16_t* src_ptr, uint8_t* dst_ptr) = - (dx & 0xffff) ? ScaleAddCols2_C - : ((dx != 0x10000) ? ScaleAddCols1_C : ScaleAddCols0_C); - void (*ScaleAddRow)(const uint8_t* src_ptr, uint16_t* dst_ptr, - int src_width) = ScaleAddRow_C; -#if defined(HAS_SCALEADDROW_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ScaleAddRow = ScaleAddRow_Any_SSE2; - if (IS_ALIGNED(src_width, 16)) { - ScaleAddRow = ScaleAddRow_SSE2; - } - } -#endif -#if defined(HAS_SCALEADDROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - ScaleAddRow = ScaleAddRow_Any_AVX2; - if (IS_ALIGNED(src_width, 32)) { - ScaleAddRow = ScaleAddRow_AVX2; - } - } -#endif -#if defined(HAS_SCALEADDROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ScaleAddRow = ScaleAddRow_Any_NEON; - if (IS_ALIGNED(src_width, 16)) { - ScaleAddRow = ScaleAddRow_NEON; - } - } -#endif -#if defined(HAS_SCALEADDROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ScaleAddRow = ScaleAddRow_Any_MSA; - if (IS_ALIGNED(src_width, 16)) { - ScaleAddRow = ScaleAddRow_MSA; - } - } -#endif - - for (j = 0; j < dst_height; ++j) { - int boxheight; - int iy = y >> 16; - const uint8_t* src = src_ptr + iy * src_stride; - y += dy; - if (y > max_y) { - y = max_y; - } - boxheight = MIN1((y >> 16) - iy); - memset(row16, 0, src_width * 2); - for (k = 0; k < boxheight; ++k) { - ScaleAddRow(src, (uint16_t*)(row16), src_width); - src += src_stride; - } - ScaleAddCols(dst_width, boxheight, x, dx, (uint16_t*)(row16), dst_ptr); - dst_ptr += dst_stride; - } - free_aligned_buffer_64(row16); - } -} - -static void ScalePlaneBox_16(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint16_t* src_ptr, - uint16_t* dst_ptr) { - int j, k; - // Initial source x/y coordinate and step values as 16.16 fixed point. - int x = 0; - int y = 0; - int dx = 0; - int dy = 0; - const int max_y = (src_height << 16); - ScaleSlope(src_width, src_height, dst_width, dst_height, kFilterBox, &x, &y, - &dx, &dy); - src_width = Abs(src_width); - { - // Allocate a row buffer of uint32_t. - align_buffer_64(row32, src_width * 4); - void (*ScaleAddCols)(int dst_width, int boxheight, int x, int dx, - const uint32_t* src_ptr, uint16_t* dst_ptr) = - (dx & 0xffff) ? ScaleAddCols2_16_C : ScaleAddCols1_16_C; - void (*ScaleAddRow)(const uint16_t* src_ptr, uint32_t* dst_ptr, - int src_width) = ScaleAddRow_16_C; - -#if defined(HAS_SCALEADDROW_16_SSE2) - if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(src_width, 16)) { - ScaleAddRow = ScaleAddRow_16_SSE2; - } -#endif - - for (j = 0; j < dst_height; ++j) { - int boxheight; - int iy = y >> 16; - const uint16_t* src = src_ptr + iy * src_stride; - y += dy; - if (y > max_y) { - y = max_y; - } - boxheight = MIN1((y >> 16) - iy); - memset(row32, 0, src_width * 4); - for (k = 0; k < boxheight; ++k) { - ScaleAddRow(src, (uint32_t*)(row32), src_width); - src += src_stride; - } - ScaleAddCols(dst_width, boxheight, x, dx, (uint32_t*)(row32), dst_ptr); - dst_ptr += dst_stride; - } - free_aligned_buffer_64(row32); - } -} - -// Scale plane down with bilinear interpolation. -void ScalePlaneBilinearDown(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_ptr, - uint8_t* dst_ptr, - enum FilterMode filtering) { - // Initial source x/y coordinate and step values as 16.16 fixed point. - int x = 0; - int y = 0; - int dx = 0; - int dy = 0; - // TODO(fbarchard): Consider not allocating row buffer for kFilterLinear. - // Allocate a row buffer. - align_buffer_64(row, src_width); - - const int max_y = (src_height - 1) << 16; - int j; - void (*ScaleFilterCols)(uint8_t * dst_ptr, const uint8_t* src_ptr, - int dst_width, int x, int dx) = - (src_width >= 32768) ? ScaleFilterCols64_C : ScaleFilterCols_C; - void (*InterpolateRow)(uint8_t * dst_ptr, const uint8_t* src_ptr, - ptrdiff_t src_stride, int dst_width, - int source_y_fraction) = InterpolateRow_C; - ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, &x, &y, - &dx, &dy); - src_width = Abs(src_width); - -#if defined(HAS_INTERPOLATEROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - InterpolateRow = InterpolateRow_Any_SSSE3; - if (IS_ALIGNED(src_width, 16)) { - InterpolateRow = InterpolateRow_SSSE3; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - InterpolateRow = InterpolateRow_Any_AVX2; - if (IS_ALIGNED(src_width, 32)) { - InterpolateRow = InterpolateRow_AVX2; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - InterpolateRow = InterpolateRow_Any_NEON; - if (IS_ALIGNED(src_width, 16)) { - InterpolateRow = InterpolateRow_NEON; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - InterpolateRow = InterpolateRow_Any_MSA; - if (IS_ALIGNED(src_width, 32)) { - InterpolateRow = InterpolateRow_MSA; - } - } -#endif - -#if defined(HAS_SCALEFILTERCOLS_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { - ScaleFilterCols = ScaleFilterCols_SSSE3; - } -#endif -#if defined(HAS_SCALEFILTERCOLS_NEON) - if (TestCpuFlag(kCpuHasNEON) && src_width < 32768) { - ScaleFilterCols = ScaleFilterCols_Any_NEON; - if (IS_ALIGNED(dst_width, 8)) { - ScaleFilterCols = ScaleFilterCols_NEON; - } - } -#endif -#if defined(HAS_SCALEFILTERCOLS_MSA) - if (TestCpuFlag(kCpuHasMSA) && src_width < 32768) { - ScaleFilterCols = ScaleFilterCols_Any_MSA; - if (IS_ALIGNED(dst_width, 16)) { - ScaleFilterCols = ScaleFilterCols_MSA; - } - } -#endif - if (y > max_y) { - y = max_y; - } - - for (j = 0; j < dst_height; ++j) { - int yi = y >> 16; - const uint8_t* src = src_ptr + yi * src_stride; - if (filtering == kFilterLinear) { - ScaleFilterCols(dst_ptr, src, dst_width, x, dx); - } else { - int yf = (y >> 8) & 255; - InterpolateRow(row, src, src_stride, src_width, yf); - ScaleFilterCols(dst_ptr, row, dst_width, x, dx); - } - dst_ptr += dst_stride; - y += dy; - if (y > max_y) { - y = max_y; - } - } - free_aligned_buffer_64(row); -} - -void ScalePlaneBilinearDown_16(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint16_t* src_ptr, - uint16_t* dst_ptr, - enum FilterMode filtering) { - // Initial source x/y coordinate and step values as 16.16 fixed point. - int x = 0; - int y = 0; - int dx = 0; - int dy = 0; - // TODO(fbarchard): Consider not allocating row buffer for kFilterLinear. - // Allocate a row buffer. - align_buffer_64(row, src_width * 2); - - const int max_y = (src_height - 1) << 16; - int j; - void (*ScaleFilterCols)(uint16_t * dst_ptr, const uint16_t* src_ptr, - int dst_width, int x, int dx) = - (src_width >= 32768) ? ScaleFilterCols64_16_C : ScaleFilterCols_16_C; - void (*InterpolateRow)(uint16_t * dst_ptr, const uint16_t* src_ptr, - ptrdiff_t src_stride, int dst_width, - int source_y_fraction) = InterpolateRow_16_C; - ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, &x, &y, - &dx, &dy); - src_width = Abs(src_width); - -#if defined(HAS_INTERPOLATEROW_16_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - InterpolateRow = InterpolateRow_Any_16_SSE2; - if (IS_ALIGNED(src_width, 16)) { - InterpolateRow = InterpolateRow_16_SSE2; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_16_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - InterpolateRow = InterpolateRow_Any_16_SSSE3; - if (IS_ALIGNED(src_width, 16)) { - InterpolateRow = InterpolateRow_16_SSSE3; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_16_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - InterpolateRow = InterpolateRow_Any_16_AVX2; - if (IS_ALIGNED(src_width, 32)) { - InterpolateRow = InterpolateRow_16_AVX2; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_16_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - InterpolateRow = InterpolateRow_Any_16_NEON; - if (IS_ALIGNED(src_width, 16)) { - InterpolateRow = InterpolateRow_16_NEON; - } - } -#endif - -#if defined(HAS_SCALEFILTERCOLS_16_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { - ScaleFilterCols = ScaleFilterCols_16_SSSE3; - } -#endif - if (y > max_y) { - y = max_y; - } - - for (j = 0; j < dst_height; ++j) { - int yi = y >> 16; - const uint16_t* src = src_ptr + yi * src_stride; - if (filtering == kFilterLinear) { - ScaleFilterCols(dst_ptr, src, dst_width, x, dx); - } else { - int yf = (y >> 8) & 255; - InterpolateRow((uint16_t*)row, src, src_stride, src_width, yf); - ScaleFilterCols(dst_ptr, (uint16_t*)row, dst_width, x, dx); - } - dst_ptr += dst_stride; - y += dy; - if (y > max_y) { - y = max_y; - } - } - free_aligned_buffer_64(row); -} - -// Scale up down with bilinear interpolation. -void ScalePlaneBilinearUp(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_ptr, - uint8_t* dst_ptr, - enum FilterMode filtering) { - int j; - // Initial source x/y coordinate and step values as 16.16 fixed point. - int x = 0; - int y = 0; - int dx = 0; - int dy = 0; - const int max_y = (src_height - 1) << 16; - void (*InterpolateRow)(uint8_t * dst_ptr, const uint8_t* src_ptr, - ptrdiff_t src_stride, int dst_width, - int source_y_fraction) = InterpolateRow_C; - void (*ScaleFilterCols)(uint8_t * dst_ptr, const uint8_t* src_ptr, - int dst_width, int x, int dx) = - filtering ? ScaleFilterCols_C : ScaleCols_C; - ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, &x, &y, - &dx, &dy); - src_width = Abs(src_width); - -#if defined(HAS_INTERPOLATEROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - InterpolateRow = InterpolateRow_Any_SSSE3; - if (IS_ALIGNED(dst_width, 16)) { - InterpolateRow = InterpolateRow_SSSE3; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - InterpolateRow = InterpolateRow_Any_AVX2; - if (IS_ALIGNED(dst_width, 32)) { - InterpolateRow = InterpolateRow_AVX2; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - InterpolateRow = InterpolateRow_Any_NEON; - if (IS_ALIGNED(dst_width, 16)) { - InterpolateRow = InterpolateRow_NEON; - } - } -#endif - - if (filtering && src_width >= 32768) { - ScaleFilterCols = ScaleFilterCols64_C; - } -#if defined(HAS_SCALEFILTERCOLS_SSSE3) - if (filtering && TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { - ScaleFilterCols = ScaleFilterCols_SSSE3; - } -#endif -#if defined(HAS_SCALEFILTERCOLS_NEON) - if (filtering && TestCpuFlag(kCpuHasNEON) && src_width < 32768) { - ScaleFilterCols = ScaleFilterCols_Any_NEON; - if (IS_ALIGNED(dst_width, 8)) { - ScaleFilterCols = ScaleFilterCols_NEON; - } - } -#endif -#if defined(HAS_SCALEFILTERCOLS_MSA) - if (filtering && TestCpuFlag(kCpuHasMSA) && src_width < 32768) { - ScaleFilterCols = ScaleFilterCols_Any_MSA; - if (IS_ALIGNED(dst_width, 16)) { - ScaleFilterCols = ScaleFilterCols_MSA; - } - } -#endif - if (!filtering && src_width * 2 == dst_width && x < 0x8000) { - ScaleFilterCols = ScaleColsUp2_C; -#if defined(HAS_SCALECOLS_SSE2) - if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8)) { - ScaleFilterCols = ScaleColsUp2_SSE2; - } -#endif - } - - if (y > max_y) { - y = max_y; - } - { - int yi = y >> 16; - const uint8_t* src = src_ptr + yi * src_stride; - - // Allocate 2 row buffers. - const int kRowSize = (dst_width + 31) & ~31; - align_buffer_64(row, kRowSize * 2); - - uint8_t* rowptr = row; - int rowstride = kRowSize; - int lasty = yi; - - ScaleFilterCols(rowptr, src, dst_width, x, dx); - if (src_height > 1) { - src += src_stride; - } - ScaleFilterCols(rowptr + rowstride, src, dst_width, x, dx); - src += src_stride; - - for (j = 0; j < dst_height; ++j) { - yi = y >> 16; - if (yi != lasty) { - if (y > max_y) { - y = max_y; - yi = y >> 16; - src = src_ptr + yi * src_stride; - } - if (yi != lasty) { - ScaleFilterCols(rowptr, src, dst_width, x, dx); - rowptr += rowstride; - rowstride = -rowstride; - lasty = yi; - src += src_stride; - } - } - if (filtering == kFilterLinear) { - InterpolateRow(dst_ptr, rowptr, 0, dst_width, 0); - } else { - int yf = (y >> 8) & 255; - InterpolateRow(dst_ptr, rowptr, rowstride, dst_width, yf); - } - dst_ptr += dst_stride; - y += dy; - } - free_aligned_buffer_64(row); - } -} - -void ScalePlaneBilinearUp_16(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint16_t* src_ptr, - uint16_t* dst_ptr, - enum FilterMode filtering) { - int j; - // Initial source x/y coordinate and step values as 16.16 fixed point. - int x = 0; - int y = 0; - int dx = 0; - int dy = 0; - const int max_y = (src_height - 1) << 16; - void (*InterpolateRow)(uint16_t * dst_ptr, const uint16_t* src_ptr, - ptrdiff_t src_stride, int dst_width, - int source_y_fraction) = InterpolateRow_16_C; - void (*ScaleFilterCols)(uint16_t * dst_ptr, const uint16_t* src_ptr, - int dst_width, int x, int dx) = - filtering ? ScaleFilterCols_16_C : ScaleCols_16_C; - ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, &x, &y, - &dx, &dy); - src_width = Abs(src_width); - -#if defined(HAS_INTERPOLATEROW_16_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - InterpolateRow = InterpolateRow_Any_16_SSE2; - if (IS_ALIGNED(dst_width, 16)) { - InterpolateRow = InterpolateRow_16_SSE2; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_16_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - InterpolateRow = InterpolateRow_Any_16_SSSE3; - if (IS_ALIGNED(dst_width, 16)) { - InterpolateRow = InterpolateRow_16_SSSE3; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_16_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - InterpolateRow = InterpolateRow_Any_16_AVX2; - if (IS_ALIGNED(dst_width, 32)) { - InterpolateRow = InterpolateRow_16_AVX2; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_16_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - InterpolateRow = InterpolateRow_Any_16_NEON; - if (IS_ALIGNED(dst_width, 16)) { - InterpolateRow = InterpolateRow_16_NEON; - } - } -#endif - - if (filtering && src_width >= 32768) { - ScaleFilterCols = ScaleFilterCols64_16_C; - } -#if defined(HAS_SCALEFILTERCOLS_16_SSSE3) - if (filtering && TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { - ScaleFilterCols = ScaleFilterCols_16_SSSE3; - } -#endif - if (!filtering && src_width * 2 == dst_width && x < 0x8000) { - ScaleFilterCols = ScaleColsUp2_16_C; -#if defined(HAS_SCALECOLS_16_SSE2) - if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8)) { - ScaleFilterCols = ScaleColsUp2_16_SSE2; - } -#endif - } - - if (y > max_y) { - y = max_y; - } - { - int yi = y >> 16; - const uint16_t* src = src_ptr + yi * src_stride; - - // Allocate 2 row buffers. - const int kRowSize = (dst_width + 31) & ~31; - align_buffer_64(row, kRowSize * 4); - - uint16_t* rowptr = (uint16_t*)row; - int rowstride = kRowSize; - int lasty = yi; - - ScaleFilterCols(rowptr, src, dst_width, x, dx); - if (src_height > 1) { - src += src_stride; - } - ScaleFilterCols(rowptr + rowstride, src, dst_width, x, dx); - src += src_stride; - - for (j = 0; j < dst_height; ++j) { - yi = y >> 16; - if (yi != lasty) { - if (y > max_y) { - y = max_y; - yi = y >> 16; - src = src_ptr + yi * src_stride; - } - if (yi != lasty) { - ScaleFilterCols(rowptr, src, dst_width, x, dx); - rowptr += rowstride; - rowstride = -rowstride; - lasty = yi; - src += src_stride; - } - } - if (filtering == kFilterLinear) { - InterpolateRow(dst_ptr, rowptr, 0, dst_width, 0); - } else { - int yf = (y >> 8) & 255; - InterpolateRow(dst_ptr, rowptr, rowstride, dst_width, yf); - } - dst_ptr += dst_stride; - y += dy; - } - free_aligned_buffer_64(row); - } -} - -// Scale Plane to/from any dimensions, without interpolation. -// Fixed point math is used for performance: The upper 16 bits -// of x and dx is the integer part of the source position and -// the lower 16 bits are the fixed decimal part. - -static void ScalePlaneSimple(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_ptr, - uint8_t* dst_ptr) { - int i; - void (*ScaleCols)(uint8_t * dst_ptr, const uint8_t* src_ptr, int dst_width, - int x, int dx) = ScaleCols_C; - // Initial source x/y coordinate and step values as 16.16 fixed point. - int x = 0; - int y = 0; - int dx = 0; - int dy = 0; - ScaleSlope(src_width, src_height, dst_width, dst_height, kFilterNone, &x, &y, - &dx, &dy); - src_width = Abs(src_width); - - if (src_width * 2 == dst_width && x < 0x8000) { - ScaleCols = ScaleColsUp2_C; -#if defined(HAS_SCALECOLS_SSE2) - if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8)) { - ScaleCols = ScaleColsUp2_SSE2; - } -#endif - } - - for (i = 0; i < dst_height; ++i) { - ScaleCols(dst_ptr, src_ptr + (y >> 16) * src_stride, dst_width, x, dx); - dst_ptr += dst_stride; - y += dy; - } -} - -static void ScalePlaneSimple_16(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint16_t* src_ptr, - uint16_t* dst_ptr) { - int i; - void (*ScaleCols)(uint16_t * dst_ptr, const uint16_t* src_ptr, int dst_width, - int x, int dx) = ScaleCols_16_C; - // Initial source x/y coordinate and step values as 16.16 fixed point. - int x = 0; - int y = 0; - int dx = 0; - int dy = 0; - ScaleSlope(src_width, src_height, dst_width, dst_height, kFilterNone, &x, &y, - &dx, &dy); - src_width = Abs(src_width); - - if (src_width * 2 == dst_width && x < 0x8000) { - ScaleCols = ScaleColsUp2_16_C; -#if defined(HAS_SCALECOLS_16_SSE2) - if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8)) { - ScaleCols = ScaleColsUp2_16_SSE2; - } -#endif - } - - for (i = 0; i < dst_height; ++i) { - ScaleCols(dst_ptr, src_ptr + (y >> 16) * src_stride, dst_width, x, dx); - dst_ptr += dst_stride; - y += dy; - } -} - -// Scale a plane. -// This function dispatches to a specialized scaler based on scale factor. - -LIBYUV_API -void ScalePlane(const uint8_t* src, - int src_stride, - int src_width, - int src_height, - uint8_t* dst, - int dst_stride, - int dst_width, - int dst_height, - enum FilterMode filtering) { - // Simplify filtering when possible. - filtering = ScaleFilterReduce(src_width, src_height, dst_width, dst_height, - filtering); - - // Negative height means invert the image. - if (src_height < 0) { - src_height = -src_height; - src = src + (src_height - 1) * src_stride; - src_stride = -src_stride; - } - - // Use specialized scales to improve performance for common resolutions. - // For example, all the 1/2 scalings will use ScalePlaneDown2() - if (dst_width == src_width && dst_height == src_height) { - // Straight copy. - CopyPlane(src, src_stride, dst, dst_stride, dst_width, dst_height); - return; - } - if (dst_width == src_width && filtering != kFilterBox) { - int dy = FixedDiv(src_height, dst_height); - // Arbitrary scale vertically, but unscaled horizontally. - ScalePlaneVertical(src_height, dst_width, dst_height, src_stride, - dst_stride, src, dst, 0, 0, dy, 1, filtering); - return; - } - if (dst_width <= Abs(src_width) && dst_height <= src_height) { - // Scale down. - if (4 * dst_width == 3 * src_width && 4 * dst_height == 3 * src_height) { - // optimized, 3/4 - ScalePlaneDown34(src_width, src_height, dst_width, dst_height, src_stride, - dst_stride, src, dst, filtering); - return; - } - if (2 * dst_width == src_width && 2 * dst_height == src_height) { - // optimized, 1/2 - ScalePlaneDown2(src_width, src_height, dst_width, dst_height, src_stride, - dst_stride, src, dst, filtering); - return; - } - // 3/8 rounded up for odd sized chroma height. - if (8 * dst_width == 3 * src_width && 8 * dst_height == 3 * src_height) { - // optimized, 3/8 - ScalePlaneDown38(src_width, src_height, dst_width, dst_height, src_stride, - dst_stride, src, dst, filtering); - return; - } - if (4 * dst_width == src_width && 4 * dst_height == src_height && - (filtering == kFilterBox || filtering == kFilterNone)) { - // optimized, 1/4 - ScalePlaneDown4(src_width, src_height, dst_width, dst_height, src_stride, - dst_stride, src, dst, filtering); - return; - } - } - if (filtering == kFilterBox && dst_height * 2 < src_height) { - ScalePlaneBox(src_width, src_height, dst_width, dst_height, src_stride, - dst_stride, src, dst); - return; - } - if (filtering && dst_height > src_height) { - ScalePlaneBilinearUp(src_width, src_height, dst_width, dst_height, - src_stride, dst_stride, src, dst, filtering); - return; - } - if (filtering) { - ScalePlaneBilinearDown(src_width, src_height, dst_width, dst_height, - src_stride, dst_stride, src, dst, filtering); - return; - } - ScalePlaneSimple(src_width, src_height, dst_width, dst_height, src_stride, - dst_stride, src, dst); -} - -LIBYUV_API -void ScalePlane_16(const uint16_t* src, - int src_stride, - int src_width, - int src_height, - uint16_t* dst, - int dst_stride, - int dst_width, - int dst_height, - enum FilterMode filtering) { - // Simplify filtering when possible. - filtering = ScaleFilterReduce(src_width, src_height, dst_width, dst_height, - filtering); - - // Negative height means invert the image. - if (src_height < 0) { - src_height = -src_height; - src = src + (src_height - 1) * src_stride; - src_stride = -src_stride; - } - - // Use specialized scales to improve performance for common resolutions. - // For example, all the 1/2 scalings will use ScalePlaneDown2() - if (dst_width == src_width && dst_height == src_height) { - // Straight copy. - CopyPlane_16(src, src_stride, dst, dst_stride, dst_width, dst_height); - return; - } - if (dst_width == src_width && filtering != kFilterBox) { - int dy = FixedDiv(src_height, dst_height); - // Arbitrary scale vertically, but unscaled vertically. - ScalePlaneVertical_16(src_height, dst_width, dst_height, src_stride, - dst_stride, src, dst, 0, 0, dy, 1, filtering); - return; - } - if (dst_width <= Abs(src_width) && dst_height <= src_height) { - // Scale down. - if (4 * dst_width == 3 * src_width && 4 * dst_height == 3 * src_height) { - // optimized, 3/4 - ScalePlaneDown34_16(src_width, src_height, dst_width, dst_height, - src_stride, dst_stride, src, dst, filtering); - return; - } - if (2 * dst_width == src_width && 2 * dst_height == src_height) { - // optimized, 1/2 - ScalePlaneDown2_16(src_width, src_height, dst_width, dst_height, - src_stride, dst_stride, src, dst, filtering); - return; - } - // 3/8 rounded up for odd sized chroma height. - if (8 * dst_width == 3 * src_width && 8 * dst_height == 3 * src_height) { - // optimized, 3/8 - ScalePlaneDown38_16(src_width, src_height, dst_width, dst_height, - src_stride, dst_stride, src, dst, filtering); - return; - } - if (4 * dst_width == src_width && 4 * dst_height == src_height && - (filtering == kFilterBox || filtering == kFilterNone)) { - // optimized, 1/4 - ScalePlaneDown4_16(src_width, src_height, dst_width, dst_height, - src_stride, dst_stride, src, dst, filtering); - return; - } - } - if (filtering == kFilterBox && dst_height * 2 < src_height) { - ScalePlaneBox_16(src_width, src_height, dst_width, dst_height, src_stride, - dst_stride, src, dst); - return; - } - if (filtering && dst_height > src_height) { - ScalePlaneBilinearUp_16(src_width, src_height, dst_width, dst_height, - src_stride, dst_stride, src, dst, filtering); - return; - } - if (filtering) { - ScalePlaneBilinearDown_16(src_width, src_height, dst_width, dst_height, - src_stride, dst_stride, src, dst, filtering); - return; - } - ScalePlaneSimple_16(src_width, src_height, dst_width, dst_height, src_stride, - dst_stride, src, dst); -} - -// Scale an I420 image. -// This function in turn calls a scaling function for each plane. - -LIBYUV_API -int I420Scale(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - int src_width, - int src_height, - uint8_t* dst_y, - int dst_stride_y, - uint8_t* dst_u, - int dst_stride_u, - uint8_t* dst_v, - int dst_stride_v, - int dst_width, - int dst_height, - enum FilterMode filtering) { - int src_halfwidth = SUBSAMPLE(src_width, 1, 1); - int src_halfheight = SUBSAMPLE(src_height, 1, 1); - int dst_halfwidth = SUBSAMPLE(dst_width, 1, 1); - int dst_halfheight = SUBSAMPLE(dst_height, 1, 1); - if (!src_y || !src_u || !src_v || src_width == 0 || src_height == 0 || - src_width > 32768 || src_height > 32768 || !dst_y || !dst_u || !dst_v || - dst_width <= 0 || dst_height <= 0) { - return -1; - } - - ScalePlane(src_y, src_stride_y, src_width, src_height, dst_y, dst_stride_y, - dst_width, dst_height, filtering); - ScalePlane(src_u, src_stride_u, src_halfwidth, src_halfheight, dst_u, - dst_stride_u, dst_halfwidth, dst_halfheight, filtering); - ScalePlane(src_v, src_stride_v, src_halfwidth, src_halfheight, dst_v, - dst_stride_v, dst_halfwidth, dst_halfheight, filtering); - return 0; -} - -LIBYUV_API -int I420Scale_16(const uint16_t* src_y, - int src_stride_y, - const uint16_t* src_u, - int src_stride_u, - const uint16_t* src_v, - int src_stride_v, - int src_width, - int src_height, - uint16_t* dst_y, - int dst_stride_y, - uint16_t* dst_u, - int dst_stride_u, - uint16_t* dst_v, - int dst_stride_v, - int dst_width, - int dst_height, - enum FilterMode filtering) { - int src_halfwidth = SUBSAMPLE(src_width, 1, 1); - int src_halfheight = SUBSAMPLE(src_height, 1, 1); - int dst_halfwidth = SUBSAMPLE(dst_width, 1, 1); - int dst_halfheight = SUBSAMPLE(dst_height, 1, 1); - if (!src_y || !src_u || !src_v || src_width == 0 || src_height == 0 || - src_width > 32768 || src_height > 32768 || !dst_y || !dst_u || !dst_v || - dst_width <= 0 || dst_height <= 0) { - return -1; - } - - ScalePlane_16(src_y, src_stride_y, src_width, src_height, dst_y, dst_stride_y, - dst_width, dst_height, filtering); - ScalePlane_16(src_u, src_stride_u, src_halfwidth, src_halfheight, dst_u, - dst_stride_u, dst_halfwidth, dst_halfheight, filtering); - ScalePlane_16(src_v, src_stride_v, src_halfwidth, src_halfheight, dst_v, - dst_stride_v, dst_halfwidth, dst_halfheight, filtering); - return 0; -} - -// Deprecated api -LIBYUV_API -int Scale(const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - int src_stride_y, - int src_stride_u, - int src_stride_v, - int src_width, - int src_height, - uint8_t* dst_y, - uint8_t* dst_u, - uint8_t* dst_v, - int dst_stride_y, - int dst_stride_u, - int dst_stride_v, - int dst_width, - int dst_height, - LIBYUV_BOOL interpolate) { - return I420Scale(src_y, src_stride_y, src_u, src_stride_u, src_v, - src_stride_v, src_width, src_height, dst_y, dst_stride_y, - dst_u, dst_stride_u, dst_v, dst_stride_v, dst_width, - dst_height, interpolate ? kFilterBox : kFilterNone); -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_any.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_any.cc deleted file mode 100644 index 53ad1364..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_any.cc +++ /dev/null @@ -1,464 +0,0 @@ -/* - * Copyright 2015 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/scale.h" -#include "libyuv/scale_row.h" - -#include "libyuv/basic_types.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// Definition for ScaleFilterCols, ScaleARGBCols and ScaleARGBFilterCols -#define CANY(NAMEANY, TERP_SIMD, TERP_C, BPP, MASK) \ - void NAMEANY(uint8_t* dst_ptr, const uint8_t* src_ptr, int dst_width, int x, \ - int dx) { \ - int r = dst_width & MASK; \ - int n = dst_width & ~MASK; \ - if (n > 0) { \ - TERP_SIMD(dst_ptr, src_ptr, n, x, dx); \ - } \ - TERP_C(dst_ptr + n * BPP, src_ptr, r, x + n * dx, dx); \ - } - -#ifdef HAS_SCALEFILTERCOLS_NEON -CANY(ScaleFilterCols_Any_NEON, ScaleFilterCols_NEON, ScaleFilterCols_C, 1, 7) -#endif -#ifdef HAS_SCALEFILTERCOLS_MSA -CANY(ScaleFilterCols_Any_MSA, ScaleFilterCols_MSA, ScaleFilterCols_C, 1, 15) -#endif -#ifdef HAS_SCALEARGBCOLS_NEON -CANY(ScaleARGBCols_Any_NEON, ScaleARGBCols_NEON, ScaleARGBCols_C, 4, 7) -#endif -#ifdef HAS_SCALEARGBCOLS_MSA -CANY(ScaleARGBCols_Any_MSA, ScaleARGBCols_MSA, ScaleARGBCols_C, 4, 3) -#endif -#ifdef HAS_SCALEARGBFILTERCOLS_NEON -CANY(ScaleARGBFilterCols_Any_NEON, - ScaleARGBFilterCols_NEON, - ScaleARGBFilterCols_C, - 4, - 3) -#endif -#ifdef HAS_SCALEARGBFILTERCOLS_MSA -CANY(ScaleARGBFilterCols_Any_MSA, - ScaleARGBFilterCols_MSA, - ScaleARGBFilterCols_C, - 4, - 7) -#endif -#undef CANY - -// Fixed scale down. -// Mask may be non-power of 2, so use MOD -#define SDANY(NAMEANY, SCALEROWDOWN_SIMD, SCALEROWDOWN_C, FACTOR, BPP, MASK) \ - void NAMEANY(const uint8_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst_ptr, \ - int dst_width) { \ - int r = (int)((unsigned int)dst_width % (MASK + 1)); /* NOLINT */ \ - 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); \ - } - -// 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_t* src_ptr, ptrdiff_t src_stride, uint8_t* dst_ptr, \ - int dst_width) { \ - int r = (int)((unsigned int)(dst_width - 1) % (MASK + 1)); /* NOLINT */ \ - int n = (dst_width - 1) - 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 + 1); \ - } - -#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) -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) -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_SCALEROWDOWN2_MSA -SDANY(ScaleRowDown2_Any_MSA, ScaleRowDown2_MSA, ScaleRowDown2_C, 2, 1, 31) -SDANY(ScaleRowDown2Linear_Any_MSA, - ScaleRowDown2Linear_MSA, - ScaleRowDown2Linear_C, - 2, - 1, - 31) -SDANY(ScaleRowDown2Box_Any_MSA, - ScaleRowDown2Box_MSA, - ScaleRowDown2Box_C, - 2, - 1, - 31) -#endif -#ifdef HAS_SCALEROWDOWN4_SSSE3 -SDANY(ScaleRowDown4_Any_SSSE3, ScaleRowDown4_SSSE3, ScaleRowDown4_C, 4, 1, 7) -SDANY(ScaleRowDown4Box_Any_SSSE3, - ScaleRowDown4Box_SSSE3, - ScaleRowDown4Box_C, - 4, - 1, - 7) -#endif -#ifdef HAS_SCALEROWDOWN4_AVX2 -SDANY(ScaleRowDown4_Any_AVX2, ScaleRowDown4_AVX2, ScaleRowDown4_C, 4, 1, 15) -SDANY(ScaleRowDown4Box_Any_AVX2, - ScaleRowDown4Box_AVX2, - ScaleRowDown4Box_C, - 4, - 1, - 15) -#endif -#ifdef HAS_SCALEROWDOWN4_NEON -SDANY(ScaleRowDown4_Any_NEON, ScaleRowDown4_NEON, ScaleRowDown4_C, 4, 1, 7) -SDANY(ScaleRowDown4Box_Any_NEON, - ScaleRowDown4Box_NEON, - ScaleRowDown4Box_C, - 4, - 1, - 7) -#endif -#ifdef HAS_SCALEROWDOWN4_MSA -SDANY(ScaleRowDown4_Any_MSA, ScaleRowDown4_MSA, ScaleRowDown4_C, 4, 1, 15) -SDANY(ScaleRowDown4Box_Any_MSA, - ScaleRowDown4Box_MSA, - ScaleRowDown4Box_C, - 4, - 1, - 15) -#endif -#ifdef HAS_SCALEROWDOWN34_SSSE3 -SDANY(ScaleRowDown34_Any_SSSE3, - ScaleRowDown34_SSSE3, - ScaleRowDown34_C, - 4 / 3, - 1, - 23) -SDANY(ScaleRowDown34_0_Box_Any_SSSE3, - ScaleRowDown34_0_Box_SSSE3, - ScaleRowDown34_0_Box_C, - 4 / 3, - 1, - 23) -SDANY(ScaleRowDown34_1_Box_Any_SSSE3, - ScaleRowDown34_1_Box_SSSE3, - ScaleRowDown34_1_Box_C, - 4 / 3, - 1, - 23) -#endif -#ifdef HAS_SCALEROWDOWN34_NEON -SDANY(ScaleRowDown34_Any_NEON, - ScaleRowDown34_NEON, - ScaleRowDown34_C, - 4 / 3, - 1, - 23) -SDANY(ScaleRowDown34_0_Box_Any_NEON, - ScaleRowDown34_0_Box_NEON, - ScaleRowDown34_0_Box_C, - 4 / 3, - 1, - 23) -SDANY(ScaleRowDown34_1_Box_Any_NEON, - ScaleRowDown34_1_Box_NEON, - ScaleRowDown34_1_Box_C, - 4 / 3, - 1, - 23) -#endif -#ifdef HAS_SCALEROWDOWN34_MSA -SDANY(ScaleRowDown34_Any_MSA, - ScaleRowDown34_MSA, - ScaleRowDown34_C, - 4 / 3, - 1, - 47) -SDANY(ScaleRowDown34_0_Box_Any_MSA, - ScaleRowDown34_0_Box_MSA, - ScaleRowDown34_0_Box_C, - 4 / 3, - 1, - 47) -SDANY(ScaleRowDown34_1_Box_Any_MSA, - ScaleRowDown34_1_Box_MSA, - ScaleRowDown34_1_Box_C, - 4 / 3, - 1, - 47) -#endif -#ifdef HAS_SCALEROWDOWN38_SSSE3 -SDANY(ScaleRowDown38_Any_SSSE3, - ScaleRowDown38_SSSE3, - ScaleRowDown38_C, - 8 / 3, - 1, - 11) -SDANY(ScaleRowDown38_3_Box_Any_SSSE3, - ScaleRowDown38_3_Box_SSSE3, - ScaleRowDown38_3_Box_C, - 8 / 3, - 1, - 5) -SDANY(ScaleRowDown38_2_Box_Any_SSSE3, - ScaleRowDown38_2_Box_SSSE3, - ScaleRowDown38_2_Box_C, - 8 / 3, - 1, - 5) -#endif -#ifdef HAS_SCALEROWDOWN38_NEON -SDANY(ScaleRowDown38_Any_NEON, - ScaleRowDown38_NEON, - ScaleRowDown38_C, - 8 / 3, - 1, - 11) -SDANY(ScaleRowDown38_3_Box_Any_NEON, - ScaleRowDown38_3_Box_NEON, - ScaleRowDown38_3_Box_C, - 8 / 3, - 1, - 11) -SDANY(ScaleRowDown38_2_Box_Any_NEON, - ScaleRowDown38_2_Box_NEON, - ScaleRowDown38_2_Box_C, - 8 / 3, - 1, - 11) -#endif -#ifdef HAS_SCALEROWDOWN38_MSA -SDANY(ScaleRowDown38_Any_MSA, - ScaleRowDown38_MSA, - ScaleRowDown38_C, - 8 / 3, - 1, - 11) -SDANY(ScaleRowDown38_3_Box_Any_MSA, - ScaleRowDown38_3_Box_MSA, - ScaleRowDown38_3_Box_C, - 8 / 3, - 1, - 11) -SDANY(ScaleRowDown38_2_Box_Any_MSA, - ScaleRowDown38_2_Box_MSA, - ScaleRowDown38_2_Box_C, - 8 / 3, - 1, - 11) -#endif - -#ifdef HAS_SCALEARGBROWDOWN2_SSE2 -SDANY(ScaleARGBRowDown2_Any_SSE2, - ScaleARGBRowDown2_SSE2, - ScaleARGBRowDown2_C, - 2, - 4, - 3) -SDANY(ScaleARGBRowDown2Linear_Any_SSE2, - ScaleARGBRowDown2Linear_SSE2, - ScaleARGBRowDown2Linear_C, - 2, - 4, - 3) -SDANY(ScaleARGBRowDown2Box_Any_SSE2, - ScaleARGBRowDown2Box_SSE2, - ScaleARGBRowDown2Box_C, - 2, - 4, - 3) -#endif -#ifdef HAS_SCALEARGBROWDOWN2_NEON -SDANY(ScaleARGBRowDown2_Any_NEON, - ScaleARGBRowDown2_NEON, - ScaleARGBRowDown2_C, - 2, - 4, - 7) -SDANY(ScaleARGBRowDown2Linear_Any_NEON, - ScaleARGBRowDown2Linear_NEON, - ScaleARGBRowDown2Linear_C, - 2, - 4, - 7) -SDANY(ScaleARGBRowDown2Box_Any_NEON, - ScaleARGBRowDown2Box_NEON, - ScaleARGBRowDown2Box_C, - 2, - 4, - 7) -#endif -#ifdef HAS_SCALEARGBROWDOWN2_MSA -SDANY(ScaleARGBRowDown2_Any_MSA, - ScaleARGBRowDown2_MSA, - ScaleARGBRowDown2_C, - 2, - 4, - 3) -SDANY(ScaleARGBRowDown2Linear_Any_MSA, - ScaleARGBRowDown2Linear_MSA, - ScaleARGBRowDown2Linear_C, - 2, - 4, - 3) -SDANY(ScaleARGBRowDown2Box_Any_MSA, - ScaleARGBRowDown2Box_MSA, - ScaleARGBRowDown2Box_C, - 2, - 4, - 3) -#endif -#undef SDANY - -// Scale down by even scale factor. -#define SDAANY(NAMEANY, SCALEROWDOWN_SIMD, SCALEROWDOWN_C, BPP, MASK) \ - void NAMEANY(const uint8_t* src_ptr, ptrdiff_t src_stride, int src_stepx, \ - uint8_t* dst_ptr, int dst_width) { \ - int r = dst_width & MASK; \ - int n = dst_width & ~MASK; \ - if (n > 0) { \ - SCALEROWDOWN_SIMD(src_ptr, src_stride, src_stepx, dst_ptr, n); \ - } \ - SCALEROWDOWN_C(src_ptr + (n * src_stepx) * BPP, src_stride, src_stepx, \ - dst_ptr + n * BPP, r); \ - } - -#ifdef HAS_SCALEARGBROWDOWNEVEN_SSE2 -SDAANY(ScaleARGBRowDownEven_Any_SSE2, - ScaleARGBRowDownEven_SSE2, - ScaleARGBRowDownEven_C, - 4, - 3) -SDAANY(ScaleARGBRowDownEvenBox_Any_SSE2, - ScaleARGBRowDownEvenBox_SSE2, - ScaleARGBRowDownEvenBox_C, - 4, - 3) -#endif -#ifdef HAS_SCALEARGBROWDOWNEVEN_NEON -SDAANY(ScaleARGBRowDownEven_Any_NEON, - ScaleARGBRowDownEven_NEON, - ScaleARGBRowDownEven_C, - 4, - 3) -SDAANY(ScaleARGBRowDownEvenBox_Any_NEON, - ScaleARGBRowDownEvenBox_NEON, - ScaleARGBRowDownEvenBox_C, - 4, - 3) -#endif -#ifdef HAS_SCALEARGBROWDOWNEVEN_MSA -SDAANY(ScaleARGBRowDownEven_Any_MSA, - ScaleARGBRowDownEven_MSA, - ScaleARGBRowDownEven_C, - 4, - 3) -SDAANY(ScaleARGBRowDownEvenBox_Any_MSA, - ScaleARGBRowDownEvenBox_MSA, - ScaleARGBRowDownEvenBox_C, - 4, - 3) -#endif - -// Add rows box filter scale down. -#define SAANY(NAMEANY, SCALEADDROW_SIMD, SCALEADDROW_C, MASK) \ - void NAMEANY(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width) { \ - int n = src_width & ~MASK; \ - if (n > 0) { \ - SCALEADDROW_SIMD(src_ptr, dst_ptr, n); \ - } \ - SCALEADDROW_C(src_ptr + n, dst_ptr + n, src_width & MASK); \ - } - -#ifdef HAS_SCALEADDROW_SSE2 -SAANY(ScaleAddRow_Any_SSE2, ScaleAddRow_SSE2, ScaleAddRow_C, 15) -#endif -#ifdef HAS_SCALEADDROW_AVX2 -SAANY(ScaleAddRow_Any_AVX2, ScaleAddRow_AVX2, ScaleAddRow_C, 31) -#endif -#ifdef HAS_SCALEADDROW_NEON -SAANY(ScaleAddRow_Any_NEON, ScaleAddRow_NEON, ScaleAddRow_C, 15) -#endif -#ifdef HAS_SCALEADDROW_MSA -SAANY(ScaleAddRow_Any_MSA, ScaleAddRow_MSA, ScaleAddRow_C, 15) -#endif -#undef SAANY - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_argb.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_argb.cc deleted file mode 100644 index 53a22e8b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_argb.cc +++ /dev/null @@ -1,1010 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/scale.h" - -#include -#include - -#include "libyuv/cpu_id.h" -#include "libyuv/planar_functions.h" // For CopyARGB -#include "libyuv/row.h" -#include "libyuv/scale_row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -static __inline int Abs(int v) { - return v >= 0 ? v : -v; -} - -// ScaleARGB ARGB, 1/2 -// This is an optimized version for scaling down a ARGB to 1/2 of -// its original size. -static void ScaleARGBDown2(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_argb, - uint8_t* dst_argb, - int x, - int dx, - int y, - int dy, - enum FilterMode filtering) { - int j; - int row_stride = src_stride * (dy >> 16); - void (*ScaleARGBRowDown2)(const uint8_t* src_argb, ptrdiff_t src_stride, - uint8_t* dst_argb, int dst_width) = - filtering == kFilterNone - ? ScaleARGBRowDown2_C - : (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_C - : ScaleARGBRowDown2Box_C); - (void)src_width; - (void)src_height; - (void)dx; - assert(dx == 65536 * 2); // Test scale factor of 2. - assert((dy & 0x1ffff) == 0); // Test vertical scale is multiple of 2. - // Advance to odd row, even column. - if (filtering == kFilterBilinear) { - src_argb += (y >> 16) * src_stride + (x >> 16) * 4; - } else { - src_argb += (y >> 16) * src_stride + ((x >> 16) - 1) * 4; - } - -#if defined(HAS_SCALEARGBROWDOWN2_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ScaleARGBRowDown2 = - filtering == kFilterNone - ? ScaleARGBRowDown2_Any_SSE2 - : (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_Any_SSE2 - : ScaleARGBRowDown2Box_Any_SSE2); - if (IS_ALIGNED(dst_width, 4)) { - ScaleARGBRowDown2 = - filtering == kFilterNone - ? ScaleARGBRowDown2_SSE2 - : (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_SSE2 - : ScaleARGBRowDown2Box_SSE2); - } - } -#endif -#if defined(HAS_SCALEARGBROWDOWN2_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ScaleARGBRowDown2 = - filtering == kFilterNone - ? ScaleARGBRowDown2_Any_NEON - : (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_Any_NEON - : ScaleARGBRowDown2Box_Any_NEON); - if (IS_ALIGNED(dst_width, 8)) { - ScaleARGBRowDown2 = - filtering == kFilterNone - ? ScaleARGBRowDown2_NEON - : (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_NEON - : ScaleARGBRowDown2Box_NEON); - } - } -#endif -#if defined(HAS_SCALEARGBROWDOWN2_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ScaleARGBRowDown2 = - filtering == kFilterNone - ? ScaleARGBRowDown2_Any_MSA - : (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_Any_MSA - : ScaleARGBRowDown2Box_Any_MSA); - if (IS_ALIGNED(dst_width, 4)) { - ScaleARGBRowDown2 = - filtering == kFilterNone - ? ScaleARGBRowDown2_MSA - : (filtering == kFilterLinear ? ScaleARGBRowDown2Linear_MSA - : ScaleARGBRowDown2Box_MSA); - } - } -#endif - - if (filtering == kFilterLinear) { - src_stride = 0; - } - for (j = 0; j < dst_height; ++j) { - ScaleARGBRowDown2(src_argb, src_stride, dst_argb, dst_width); - src_argb += row_stride; - dst_argb += dst_stride; - } -} - -// ScaleARGB ARGB, 1/4 -// This is an optimized version for scaling down a ARGB to 1/4 of -// its original size. -static void ScaleARGBDown4Box(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_argb, - uint8_t* dst_argb, - int x, - int dx, - int y, - int dy) { - int j; - // Allocate 2 rows of ARGB. - const int kRowSize = (dst_width * 2 * 4 + 31) & ~31; - align_buffer_64(row, kRowSize * 2); - int row_stride = src_stride * (dy >> 16); - void (*ScaleARGBRowDown2)(const uint8_t* src_argb, ptrdiff_t src_stride, - uint8_t* dst_argb, int dst_width) = - ScaleARGBRowDown2Box_C; - // Advance to odd row, even column. - src_argb += (y >> 16) * src_stride + (x >> 16) * 4; - (void)src_width; - (void)src_height; - (void)dx; - assert(dx == 65536 * 4); // Test scale factor of 4. - assert((dy & 0x3ffff) == 0); // Test vertical scale is multiple of 4. -#if defined(HAS_SCALEARGBROWDOWN2_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ScaleARGBRowDown2 = ScaleARGBRowDown2Box_Any_SSE2; - if (IS_ALIGNED(dst_width, 4)) { - ScaleARGBRowDown2 = ScaleARGBRowDown2Box_SSE2; - } - } -#endif -#if defined(HAS_SCALEARGBROWDOWN2_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ScaleARGBRowDown2 = ScaleARGBRowDown2Box_Any_NEON; - if (IS_ALIGNED(dst_width, 8)) { - ScaleARGBRowDown2 = ScaleARGBRowDown2Box_NEON; - } - } -#endif - - for (j = 0; j < dst_height; ++j) { - ScaleARGBRowDown2(src_argb, src_stride, row, dst_width * 2); - ScaleARGBRowDown2(src_argb + src_stride * 2, src_stride, row + kRowSize, - dst_width * 2); - ScaleARGBRowDown2(row, kRowSize, dst_argb, dst_width); - src_argb += row_stride; - dst_argb += dst_stride; - } - free_aligned_buffer_64(row); -} - -// ScaleARGB ARGB Even -// This is an optimized version for scaling down a ARGB to even -// multiple of its original size. -static void ScaleARGBDownEven(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_argb, - uint8_t* dst_argb, - int x, - int dx, - int y, - int dy, - enum FilterMode filtering) { - int j; - int col_step = dx >> 16; - int row_stride = (dy >> 16) * src_stride; - void (*ScaleARGBRowDownEven)(const uint8_t* src_argb, ptrdiff_t src_stride, - int src_step, uint8_t* dst_argb, int dst_width) = - filtering ? ScaleARGBRowDownEvenBox_C : ScaleARGBRowDownEven_C; - (void)src_width; - (void)src_height; - assert(IS_ALIGNED(src_width, 2)); - assert(IS_ALIGNED(src_height, 2)); - src_argb += (y >> 16) * src_stride + (x >> 16) * 4; -#if defined(HAS_SCALEARGBROWDOWNEVEN_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - ScaleARGBRowDownEven = filtering ? ScaleARGBRowDownEvenBox_Any_SSE2 - : ScaleARGBRowDownEven_Any_SSE2; - if (IS_ALIGNED(dst_width, 4)) { - ScaleARGBRowDownEven = - filtering ? ScaleARGBRowDownEvenBox_SSE2 : ScaleARGBRowDownEven_SSE2; - } - } -#endif -#if defined(HAS_SCALEARGBROWDOWNEVEN_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ScaleARGBRowDownEven = filtering ? ScaleARGBRowDownEvenBox_Any_NEON - : ScaleARGBRowDownEven_Any_NEON; - if (IS_ALIGNED(dst_width, 4)) { - ScaleARGBRowDownEven = - filtering ? ScaleARGBRowDownEvenBox_NEON : ScaleARGBRowDownEven_NEON; - } - } -#endif -#if defined(HAS_SCALEARGBROWDOWNEVEN_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ScaleARGBRowDownEven = filtering ? ScaleARGBRowDownEvenBox_Any_MSA - : ScaleARGBRowDownEven_Any_MSA; - if (IS_ALIGNED(dst_width, 4)) { - ScaleARGBRowDownEven = - filtering ? ScaleARGBRowDownEvenBox_MSA : ScaleARGBRowDownEven_MSA; - } - } -#endif - - if (filtering == kFilterLinear) { - src_stride = 0; - } - for (j = 0; j < dst_height; ++j) { - ScaleARGBRowDownEven(src_argb, src_stride, col_step, dst_argb, dst_width); - src_argb += row_stride; - dst_argb += dst_stride; - } -} - -// Scale ARGB down with bilinear interpolation. -static void ScaleARGBBilinearDown(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_argb, - uint8_t* dst_argb, - int x, - int dx, - int y, - int dy, - enum FilterMode filtering) { - int j; - void (*InterpolateRow)(uint8_t * dst_argb, const uint8_t* src_argb, - ptrdiff_t src_stride, int dst_width, - int source_y_fraction) = InterpolateRow_C; - void (*ScaleARGBFilterCols)(uint8_t * dst_argb, const uint8_t* src_argb, - int dst_width, int x, int dx) = - (src_width >= 32768) ? ScaleARGBFilterCols64_C : ScaleARGBFilterCols_C; - int64_t xlast = x + (int64_t)(dst_width - 1) * dx; - int64_t xl = (dx >= 0) ? x : xlast; - int64_t xr = (dx >= 0) ? xlast : x; - int clip_src_width; - xl = (xl >> 16) & ~3; // Left edge aligned. - xr = (xr >> 16) + 1; // Right most pixel used. Bilinear uses 2 pixels. - xr = (xr + 1 + 3) & ~3; // 1 beyond 4 pixel aligned right most pixel. - if (xr > src_width) { - xr = src_width; - } - clip_src_width = (int)(xr - xl) * 4; // Width aligned to 4. - src_argb += xl * 4; - x -= (int)(xl << 16); -#if defined(HAS_INTERPOLATEROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - InterpolateRow = InterpolateRow_Any_SSSE3; - if (IS_ALIGNED(clip_src_width, 16)) { - InterpolateRow = InterpolateRow_SSSE3; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - InterpolateRow = InterpolateRow_Any_AVX2; - if (IS_ALIGNED(clip_src_width, 32)) { - InterpolateRow = InterpolateRow_AVX2; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - InterpolateRow = InterpolateRow_Any_NEON; - if (IS_ALIGNED(clip_src_width, 16)) { - InterpolateRow = InterpolateRow_NEON; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - InterpolateRow = InterpolateRow_Any_MSA; - if (IS_ALIGNED(clip_src_width, 32)) { - InterpolateRow = InterpolateRow_MSA; - } - } -#endif -#if defined(HAS_SCALEARGBFILTERCOLS_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { - ScaleARGBFilterCols = ScaleARGBFilterCols_SSSE3; - } -#endif -#if defined(HAS_SCALEARGBFILTERCOLS_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ScaleARGBFilterCols = ScaleARGBFilterCols_Any_NEON; - if (IS_ALIGNED(dst_width, 4)) { - ScaleARGBFilterCols = ScaleARGBFilterCols_NEON; - } - } -#endif -#if defined(HAS_SCALEARGBFILTERCOLS_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ScaleARGBFilterCols = ScaleARGBFilterCols_Any_MSA; - if (IS_ALIGNED(dst_width, 8)) { - ScaleARGBFilterCols = ScaleARGBFilterCols_MSA; - } - } -#endif - // TODO(fbarchard): Consider not allocating row buffer for kFilterLinear. - // Allocate a row of ARGB. - { - align_buffer_64(row, clip_src_width * 4); - - const int max_y = (src_height - 1) << 16; - if (y > max_y) { - y = max_y; - } - for (j = 0; j < dst_height; ++j) { - int yi = y >> 16; - const uint8_t* src = src_argb + yi * src_stride; - if (filtering == kFilterLinear) { - ScaleARGBFilterCols(dst_argb, src, dst_width, x, dx); - } else { - int yf = (y >> 8) & 255; - InterpolateRow(row, src, src_stride, clip_src_width, yf); - ScaleARGBFilterCols(dst_argb, row, dst_width, x, dx); - } - dst_argb += dst_stride; - y += dy; - if (y > max_y) { - y = max_y; - } - } - free_aligned_buffer_64(row); - } -} - -// Scale ARGB up with bilinear interpolation. -static void ScaleARGBBilinearUp(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_argb, - uint8_t* dst_argb, - int x, - int dx, - int y, - int dy, - enum FilterMode filtering) { - int j; - void (*InterpolateRow)(uint8_t * dst_argb, const uint8_t* src_argb, - ptrdiff_t src_stride, int dst_width, - int source_y_fraction) = InterpolateRow_C; - void (*ScaleARGBFilterCols)(uint8_t * dst_argb, const uint8_t* src_argb, - int dst_width, int x, int dx) = - filtering ? ScaleARGBFilterCols_C : ScaleARGBCols_C; - const int max_y = (src_height - 1) << 16; -#if defined(HAS_INTERPOLATEROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - InterpolateRow = InterpolateRow_Any_SSSE3; - if (IS_ALIGNED(dst_width, 4)) { - InterpolateRow = InterpolateRow_SSSE3; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - InterpolateRow = InterpolateRow_Any_AVX2; - if (IS_ALIGNED(dst_width, 8)) { - InterpolateRow = InterpolateRow_AVX2; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - InterpolateRow = InterpolateRow_Any_NEON; - if (IS_ALIGNED(dst_width, 4)) { - InterpolateRow = InterpolateRow_NEON; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - InterpolateRow = InterpolateRow_Any_MSA; - if (IS_ALIGNED(dst_width, 8)) { - InterpolateRow = InterpolateRow_MSA; - } - } -#endif - if (src_width >= 32768) { - ScaleARGBFilterCols = - filtering ? ScaleARGBFilterCols64_C : ScaleARGBCols64_C; - } -#if defined(HAS_SCALEARGBFILTERCOLS_SSSE3) - if (filtering && TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { - ScaleARGBFilterCols = ScaleARGBFilterCols_SSSE3; - } -#endif -#if defined(HAS_SCALEARGBFILTERCOLS_NEON) - if (filtering && TestCpuFlag(kCpuHasNEON)) { - ScaleARGBFilterCols = ScaleARGBFilterCols_Any_NEON; - if (IS_ALIGNED(dst_width, 4)) { - ScaleARGBFilterCols = ScaleARGBFilterCols_NEON; - } - } -#endif -#if defined(HAS_SCALEARGBFILTERCOLS_MSA) - if (filtering && TestCpuFlag(kCpuHasMSA)) { - ScaleARGBFilterCols = ScaleARGBFilterCols_Any_MSA; - if (IS_ALIGNED(dst_width, 8)) { - ScaleARGBFilterCols = ScaleARGBFilterCols_MSA; - } - } -#endif -#if defined(HAS_SCALEARGBCOLS_SSE2) - if (!filtering && TestCpuFlag(kCpuHasSSE2) && src_width < 32768) { - ScaleARGBFilterCols = ScaleARGBCols_SSE2; - } -#endif -#if defined(HAS_SCALEARGBCOLS_NEON) - if (!filtering && TestCpuFlag(kCpuHasNEON)) { - ScaleARGBFilterCols = ScaleARGBCols_Any_NEON; - if (IS_ALIGNED(dst_width, 8)) { - ScaleARGBFilterCols = ScaleARGBCols_NEON; - } - } -#endif -#if defined(HAS_SCALEARGBCOLS_MSA) - if (!filtering && TestCpuFlag(kCpuHasMSA)) { - ScaleARGBFilterCols = ScaleARGBCols_Any_MSA; - if (IS_ALIGNED(dst_width, 4)) { - ScaleARGBFilterCols = ScaleARGBCols_MSA; - } - } -#endif - if (!filtering && src_width * 2 == dst_width && x < 0x8000) { - ScaleARGBFilterCols = ScaleARGBColsUp2_C; -#if defined(HAS_SCALEARGBCOLSUP2_SSE2) - if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8)) { - ScaleARGBFilterCols = ScaleARGBColsUp2_SSE2; - } -#endif - } - - if (y > max_y) { - y = max_y; - } - - { - int yi = y >> 16; - const uint8_t* src = src_argb + yi * src_stride; - - // Allocate 2 rows of ARGB. - const int kRowSize = (dst_width * 4 + 31) & ~31; - align_buffer_64(row, kRowSize * 2); - - uint8_t* rowptr = row; - int rowstride = kRowSize; - int lasty = yi; - - ScaleARGBFilterCols(rowptr, src, dst_width, x, dx); - if (src_height > 1) { - src += src_stride; - } - ScaleARGBFilterCols(rowptr + rowstride, src, dst_width, x, dx); - src += src_stride; - - for (j = 0; j < dst_height; ++j) { - yi = y >> 16; - if (yi != lasty) { - if (y > max_y) { - y = max_y; - yi = y >> 16; - src = src_argb + yi * src_stride; - } - if (yi != lasty) { - ScaleARGBFilterCols(rowptr, src, dst_width, x, dx); - rowptr += rowstride; - rowstride = -rowstride; - lasty = yi; - src += src_stride; - } - } - if (filtering == kFilterLinear) { - InterpolateRow(dst_argb, rowptr, 0, dst_width * 4, 0); - } else { - int yf = (y >> 8) & 255; - InterpolateRow(dst_argb, rowptr, rowstride, dst_width * 4, yf); - } - dst_argb += dst_stride; - y += dy; - } - free_aligned_buffer_64(row); - } -} - -#ifdef YUVSCALEUP -// Scale YUV to ARGB up with bilinear interpolation. -static void ScaleYUVToARGBBilinearUp(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride_y, - int src_stride_u, - int src_stride_v, - int dst_stride_argb, - const uint8_t* src_y, - const uint8_t* src_u, - const uint8_t* src_v, - uint8_t* dst_argb, - int x, - int dx, - int y, - int dy, - enum FilterMode filtering) { - int j; - void (*I422ToARGBRow)(const uint8_t* y_buf, const uint8_t* u_buf, - const uint8_t* v_buf, uint8_t* rgb_buf, int width) = - I422ToARGBRow_C; -#if defined(HAS_I422TOARGBROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - I422ToARGBRow = I422ToARGBRow_Any_SSSE3; - if (IS_ALIGNED(src_width, 8)) { - I422ToARGBRow = I422ToARGBRow_SSSE3; - } - } -#endif -#if defined(HAS_I422TOARGBROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - I422ToARGBRow = I422ToARGBRow_Any_AVX2; - if (IS_ALIGNED(src_width, 16)) { - I422ToARGBRow = I422ToARGBRow_AVX2; - } - } -#endif -#if defined(HAS_I422TOARGBROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - I422ToARGBRow = I422ToARGBRow_Any_NEON; - if (IS_ALIGNED(src_width, 8)) { - I422ToARGBRow = I422ToARGBRow_NEON; - } - } -#endif -#if defined(HAS_I422TOARGBROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - I422ToARGBRow = I422ToARGBRow_Any_MSA; - if (IS_ALIGNED(src_width, 8)) { - I422ToARGBRow = I422ToARGBRow_MSA; - } - } -#endif - - void (*InterpolateRow)(uint8_t * dst_argb, const uint8_t* src_argb, - ptrdiff_t src_stride, int dst_width, - int source_y_fraction) = InterpolateRow_C; -#if defined(HAS_INTERPOLATEROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - InterpolateRow = InterpolateRow_Any_SSSE3; - if (IS_ALIGNED(dst_width, 4)) { - InterpolateRow = InterpolateRow_SSSE3; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - InterpolateRow = InterpolateRow_Any_AVX2; - if (IS_ALIGNED(dst_width, 8)) { - InterpolateRow = InterpolateRow_AVX2; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - InterpolateRow = InterpolateRow_Any_NEON; - if (IS_ALIGNED(dst_width, 4)) { - InterpolateRow = InterpolateRow_NEON; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - InterpolateRow = InterpolateRow_Any_MSA; - if (IS_ALIGNED(dst_width, 8)) { - InterpolateRow = InterpolateRow_MSA; - } - } -#endif - - void (*ScaleARGBFilterCols)(uint8_t * dst_argb, const uint8_t* src_argb, - int dst_width, int x, int dx) = - filtering ? ScaleARGBFilterCols_C : ScaleARGBCols_C; - if (src_width >= 32768) { - ScaleARGBFilterCols = - filtering ? ScaleARGBFilterCols64_C : ScaleARGBCols64_C; - } -#if defined(HAS_SCALEARGBFILTERCOLS_SSSE3) - if (filtering && TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { - ScaleARGBFilterCols = ScaleARGBFilterCols_SSSE3; - } -#endif -#if defined(HAS_SCALEARGBFILTERCOLS_NEON) - if (filtering && TestCpuFlag(kCpuHasNEON)) { - ScaleARGBFilterCols = ScaleARGBFilterCols_Any_NEON; - if (IS_ALIGNED(dst_width, 4)) { - ScaleARGBFilterCols = ScaleARGBFilterCols_NEON; - } - } -#endif -#if defined(HAS_SCALEARGBFILTERCOLS_MSA) - if (filtering && TestCpuFlag(kCpuHasMSA)) { - ScaleARGBFilterCols = ScaleARGBFilterCols_Any_MSA; - if (IS_ALIGNED(dst_width, 8)) { - ScaleARGBFilterCols = ScaleARGBFilterCols_MSA; - } - } -#endif -#if defined(HAS_SCALEARGBCOLS_SSE2) - if (!filtering && TestCpuFlag(kCpuHasSSE2) && src_width < 32768) { - ScaleARGBFilterCols = ScaleARGBCols_SSE2; - } -#endif -#if defined(HAS_SCALEARGBCOLS_NEON) - if (!filtering && TestCpuFlag(kCpuHasNEON)) { - ScaleARGBFilterCols = ScaleARGBCols_Any_NEON; - if (IS_ALIGNED(dst_width, 8)) { - ScaleARGBFilterCols = ScaleARGBCols_NEON; - } - } -#endif -#if defined(HAS_SCALEARGBCOLS_MSA) - if (!filtering && TestCpuFlag(kCpuHasMSA)) { - ScaleARGBFilterCols = ScaleARGBCols_Any_MSA; - if (IS_ALIGNED(dst_width, 4)) { - ScaleARGBFilterCols = ScaleARGBCols_MSA; - } - } -#endif - if (!filtering && src_width * 2 == dst_width && x < 0x8000) { - ScaleARGBFilterCols = ScaleARGBColsUp2_C; -#if defined(HAS_SCALEARGBCOLSUP2_SSE2) - if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8)) { - ScaleARGBFilterCols = ScaleARGBColsUp2_SSE2; - } -#endif - } - - const int max_y = (src_height - 1) << 16; - if (y > max_y) { - y = max_y; - } - const int kYShift = 1; // Shift Y by 1 to convert Y plane to UV coordinate. - int yi = y >> 16; - int uv_yi = yi >> kYShift; - const uint8_t* src_row_y = src_y + yi * src_stride_y; - const uint8_t* src_row_u = src_u + uv_yi * src_stride_u; - const uint8_t* src_row_v = src_v + uv_yi * src_stride_v; - - // Allocate 2 rows of ARGB. - const int kRowSize = (dst_width * 4 + 31) & ~31; - align_buffer_64(row, kRowSize * 2); - - // Allocate 1 row of ARGB for source conversion. - align_buffer_64(argb_row, src_width * 4); - - uint8_t* rowptr = row; - int rowstride = kRowSize; - int lasty = yi; - - // TODO(fbarchard): Convert first 2 rows of YUV to ARGB. - ScaleARGBFilterCols(rowptr, src_row_y, dst_width, x, dx); - if (src_height > 1) { - src_row_y += src_stride_y; - if (yi & 1) { - src_row_u += src_stride_u; - src_row_v += src_stride_v; - } - } - ScaleARGBFilterCols(rowptr + rowstride, src_row_y, dst_width, x, dx); - if (src_height > 2) { - src_row_y += src_stride_y; - if (!(yi & 1)) { - src_row_u += src_stride_u; - src_row_v += src_stride_v; - } - } - - for (j = 0; j < dst_height; ++j) { - yi = y >> 16; - if (yi != lasty) { - if (y > max_y) { - y = max_y; - yi = y >> 16; - uv_yi = yi >> kYShift; - src_row_y = src_y + yi * src_stride_y; - src_row_u = src_u + uv_yi * src_stride_u; - src_row_v = src_v + uv_yi * src_stride_v; - } - if (yi != lasty) { - // TODO(fbarchard): Convert the clipped region of row. - I422ToARGBRow(src_row_y, src_row_u, src_row_v, argb_row, src_width); - ScaleARGBFilterCols(rowptr, argb_row, dst_width, x, dx); - rowptr += rowstride; - rowstride = -rowstride; - lasty = yi; - src_row_y += src_stride_y; - if (yi & 1) { - src_row_u += src_stride_u; - src_row_v += src_stride_v; - } - } - } - if (filtering == kFilterLinear) { - InterpolateRow(dst_argb, rowptr, 0, dst_width * 4, 0); - } else { - int yf = (y >> 8) & 255; - InterpolateRow(dst_argb, rowptr, rowstride, dst_width * 4, yf); - } - dst_argb += dst_stride_argb; - y += dy; - } - free_aligned_buffer_64(row); - free_aligned_buffer_64(row_argb); -} -#endif - -// Scale ARGB to/from any dimensions, without interpolation. -// Fixed point math is used for performance: The upper 16 bits -// of x and dx is the integer part of the source position and -// the lower 16 bits are the fixed decimal part. - -static void ScaleARGBSimple(int src_width, - int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_argb, - uint8_t* dst_argb, - int x, - int dx, - int y, - int dy) { - int j; - void (*ScaleARGBCols)(uint8_t * dst_argb, const uint8_t* src_argb, - int dst_width, int x, int dx) = - (src_width >= 32768) ? ScaleARGBCols64_C : ScaleARGBCols_C; - (void)src_height; -#if defined(HAS_SCALEARGBCOLS_SSE2) - if (TestCpuFlag(kCpuHasSSE2) && src_width < 32768) { - ScaleARGBCols = ScaleARGBCols_SSE2; - } -#endif -#if defined(HAS_SCALEARGBCOLS_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - ScaleARGBCols = ScaleARGBCols_Any_NEON; - if (IS_ALIGNED(dst_width, 8)) { - ScaleARGBCols = ScaleARGBCols_NEON; - } - } -#endif -#if defined(HAS_SCALEARGBCOLS_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - ScaleARGBCols = ScaleARGBCols_Any_MSA; - if (IS_ALIGNED(dst_width, 4)) { - ScaleARGBCols = ScaleARGBCols_MSA; - } - } -#endif - if (src_width * 2 == dst_width && x < 0x8000) { - ScaleARGBCols = ScaleARGBColsUp2_C; -#if defined(HAS_SCALEARGBCOLSUP2_SSE2) - if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8)) { - ScaleARGBCols = ScaleARGBColsUp2_SSE2; - } -#endif - } - - for (j = 0; j < dst_height; ++j) { - ScaleARGBCols(dst_argb, src_argb + (y >> 16) * src_stride, dst_width, x, - dx); - dst_argb += dst_stride; - y += dy; - } -} - -// ScaleARGB a ARGB. -// This function in turn calls a scaling function -// suitable for handling the desired resolutions. -static void ScaleARGB(const uint8_t* src, - int src_stride, - int src_width, - int src_height, - uint8_t* dst, - int dst_stride, - int dst_width, - int dst_height, - int clip_x, - int clip_y, - int clip_width, - int clip_height, - enum FilterMode filtering) { - // Initial source x/y coordinate and step values as 16.16 fixed point. - int x = 0; - int y = 0; - int dx = 0; - int dy = 0; - // ARGB does not support box filter yet, but allow the user to pass it. - // Simplify filtering when possible. - filtering = ScaleFilterReduce(src_width, src_height, dst_width, dst_height, - filtering); - - // Negative src_height means invert the image. - if (src_height < 0) { - src_height = -src_height; - src = src + (src_height - 1) * src_stride; - src_stride = -src_stride; - } - ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, &x, &y, - &dx, &dy); - src_width = Abs(src_width); - if (clip_x) { - int64_t clipf = (int64_t)(clip_x)*dx; - x += (clipf & 0xffff); - src += (clipf >> 16) * 4; - dst += clip_x * 4; - } - if (clip_y) { - int64_t clipf = (int64_t)(clip_y)*dy; - y += (clipf & 0xffff); - src += (clipf >> 16) * src_stride; - dst += clip_y * dst_stride; - } - - // Special case for integer step values. - if (((dx | dy) & 0xffff) == 0) { - if (!dx || !dy) { // 1 pixel wide and/or tall. - filtering = kFilterNone; - } else { - // Optimized even scale down. ie 2, 4, 6, 8, 10x. - if (!(dx & 0x10000) && !(dy & 0x10000)) { - if (dx == 0x20000) { - // Optimized 1/2 downsample. - ScaleARGBDown2(src_width, src_height, clip_width, clip_height, - src_stride, dst_stride, src, dst, x, dx, y, dy, - filtering); - return; - } - if (dx == 0x40000 && filtering == kFilterBox) { - // Optimized 1/4 box downsample. - ScaleARGBDown4Box(src_width, src_height, clip_width, clip_height, - src_stride, dst_stride, src, dst, x, dx, y, dy); - return; - } - ScaleARGBDownEven(src_width, src_height, clip_width, clip_height, - src_stride, dst_stride, src, dst, x, dx, y, dy, - filtering); - return; - } - // Optimized odd scale down. ie 3, 5, 7, 9x. - if ((dx & 0x10000) && (dy & 0x10000)) { - filtering = kFilterNone; - if (dx == 0x10000 && dy == 0x10000) { - // Straight copy. - ARGBCopy(src + (y >> 16) * src_stride + (x >> 16) * 4, src_stride, - dst, dst_stride, clip_width, clip_height); - return; - } - } - } - } - if (dx == 0x10000 && (x & 0xffff) == 0) { - // Arbitrary scale vertically, but unscaled vertically. - ScalePlaneVertical(src_height, clip_width, clip_height, src_stride, - dst_stride, src, dst, x, y, dy, 4, filtering); - return; - } - if (filtering && dy < 65536) { - ScaleARGBBilinearUp(src_width, src_height, clip_width, clip_height, - src_stride, dst_stride, src, dst, x, dx, y, dy, - filtering); - return; - } - if (filtering) { - ScaleARGBBilinearDown(src_width, src_height, clip_width, clip_height, - src_stride, dst_stride, src, dst, x, dx, y, dy, - filtering); - return; - } - ScaleARGBSimple(src_width, src_height, clip_width, clip_height, src_stride, - dst_stride, src, dst, x, dx, y, dy); -} - -LIBYUV_API -int ARGBScaleClip(const uint8_t* src_argb, - int src_stride_argb, - int src_width, - int src_height, - uint8_t* dst_argb, - int dst_stride_argb, - int dst_width, - int dst_height, - int clip_x, - int clip_y, - int clip_width, - int clip_height, - enum FilterMode filtering) { - if (!src_argb || src_width == 0 || src_height == 0 || !dst_argb || - dst_width <= 0 || dst_height <= 0 || clip_x < 0 || clip_y < 0 || - clip_width > 32768 || clip_height > 32768 || - (clip_x + clip_width) > dst_width || - (clip_y + clip_height) > dst_height) { - return -1; - } - ScaleARGB(src_argb, src_stride_argb, src_width, src_height, dst_argb, - dst_stride_argb, dst_width, dst_height, clip_x, clip_y, clip_width, - clip_height, filtering); - return 0; -} - -// Scale an ARGB image. -LIBYUV_API -int ARGBScale(const uint8_t* src_argb, - int src_stride_argb, - int src_width, - int src_height, - uint8_t* dst_argb, - int dst_stride_argb, - int dst_width, - int dst_height, - enum FilterMode filtering) { - if (!src_argb || src_width == 0 || src_height == 0 || src_width > 32768 || - src_height > 32768 || !dst_argb || dst_width <= 0 || dst_height <= 0) { - return -1; - } - ScaleARGB(src_argb, src_stride_argb, src_width, src_height, dst_argb, - dst_stride_argb, dst_width, dst_height, 0, 0, dst_width, dst_height, - filtering); - return 0; -} - -// Scale with YUV conversion to ARGB and clipping. -LIBYUV_API -int YUVToARGBScaleClip(const uint8_t* src_y, - int src_stride_y, - const uint8_t* src_u, - int src_stride_u, - const uint8_t* src_v, - int src_stride_v, - uint32_t src_fourcc, - int src_width, - int src_height, - uint8_t* dst_argb, - int dst_stride_argb, - uint32_t dst_fourcc, - int dst_width, - int dst_height, - int clip_x, - int clip_y, - int clip_width, - int clip_height, - enum FilterMode filtering) { - uint8_t* argb_buffer = (uint8_t*)malloc(src_width * src_height * 4); - int r; - (void)src_fourcc; // TODO(fbarchard): implement and/or assert. - (void)dst_fourcc; - I420ToARGB(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, - argb_buffer, src_width * 4, src_width, src_height); - - r = ARGBScaleClip(argb_buffer, src_width * 4, src_width, src_height, dst_argb, - dst_stride_argb, dst_width, dst_height, clip_x, clip_y, - clip_width, clip_height, filtering); - free(argb_buffer); - return r; -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_common.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_common.cc deleted file mode 100644 index b28d7da4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_common.cc +++ /dev/null @@ -1,1323 +0,0 @@ -/* - * Copyright 2013 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/scale.h" - -#include -#include - -#include "libyuv/cpu_id.h" -#include "libyuv/planar_functions.h" // For CopyARGB -#include "libyuv/row.h" -#include "libyuv/scale_row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -static __inline int Abs(int v) { - return v >= 0 ? v : -v; -} - -// CPU agnostic row functions -void ScaleRowDown2_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - int x; - (void)src_stride; - for (x = 0; x < dst_width - 1; x += 2) { - dst[0] = src_ptr[1]; - dst[1] = src_ptr[3]; - dst += 2; - src_ptr += 4; - } - if (dst_width & 1) { - dst[0] = src_ptr[1]; - } -} - -void ScaleRowDown2_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst, - int dst_width) { - int x; - (void)src_stride; - for (x = 0; x < dst_width - 1; x += 2) { - dst[0] = src_ptr[1]; - dst[1] = src_ptr[3]; - dst += 2; - src_ptr += 4; - } - if (dst_width & 1) { - dst[0] = src_ptr[1]; - } -} - -void ScaleRowDown2Linear_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - const uint8_t* s = src_ptr; - int x; - (void)src_stride; - for (x = 0; x < dst_width - 1; x += 2) { - dst[0] = (s[0] + s[1] + 1) >> 1; - dst[1] = (s[2] + s[3] + 1) >> 1; - dst += 2; - s += 4; - } - if (dst_width & 1) { - dst[0] = (s[0] + s[1] + 1) >> 1; - } -} - -void ScaleRowDown2Linear_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst, - int dst_width) { - const uint16_t* s = src_ptr; - int x; - (void)src_stride; - for (x = 0; x < dst_width - 1; x += 2) { - dst[0] = (s[0] + s[1] + 1) >> 1; - dst[1] = (s[2] + s[3] + 1) >> 1; - dst += 2; - s += 4; - } - if (dst_width & 1) { - dst[0] = (s[0] + s[1] + 1) >> 1; - } -} - -void ScaleRowDown2Box_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - const uint8_t* s = src_ptr; - const uint8_t* t = src_ptr + src_stride; - int x; - 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; - } -} - -void ScaleRowDown2Box_Odd_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - const uint8_t* s = src_ptr; - const uint8_t* 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_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst, - int dst_width) { - const uint16_t* s = src_ptr; - const uint16_t* t = src_ptr + src_stride; - int x; - 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; - } -} - -void ScaleRowDown4_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - int x; - (void)src_stride; - for (x = 0; x < dst_width - 1; x += 2) { - dst[0] = src_ptr[2]; - dst[1] = src_ptr[6]; - dst += 2; - src_ptr += 8; - } - if (dst_width & 1) { - dst[0] = src_ptr[2]; - } -} - -void ScaleRowDown4_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst, - int dst_width) { - int x; - (void)src_stride; - for (x = 0; x < dst_width - 1; x += 2) { - dst[0] = src_ptr[2]; - dst[1] = src_ptr[6]; - dst += 2; - src_ptr += 8; - } - if (dst_width & 1) { - dst[0] = src_ptr[2]; - } -} - -void ScaleRowDown4Box_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - intptr_t stride = src_stride; - int x; - for (x = 0; x < dst_width - 1; x += 2) { - dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + - src_ptr[stride + 0] + src_ptr[stride + 1] + src_ptr[stride + 2] + - src_ptr[stride + 3] + src_ptr[stride * 2 + 0] + - src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2] + - src_ptr[stride * 2 + 3] + src_ptr[stride * 3 + 0] + - src_ptr[stride * 3 + 1] + src_ptr[stride * 3 + 2] + - src_ptr[stride * 3 + 3] + 8) >> - 4; - dst[1] = (src_ptr[4] + src_ptr[5] + src_ptr[6] + src_ptr[7] + - src_ptr[stride + 4] + src_ptr[stride + 5] + src_ptr[stride + 6] + - src_ptr[stride + 7] + src_ptr[stride * 2 + 4] + - src_ptr[stride * 2 + 5] + src_ptr[stride * 2 + 6] + - src_ptr[stride * 2 + 7] + src_ptr[stride * 3 + 4] + - src_ptr[stride * 3 + 5] + src_ptr[stride * 3 + 6] + - src_ptr[stride * 3 + 7] + 8) >> - 4; - dst += 2; - src_ptr += 8; - } - if (dst_width & 1) { - dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + - src_ptr[stride + 0] + src_ptr[stride + 1] + src_ptr[stride + 2] + - src_ptr[stride + 3] + src_ptr[stride * 2 + 0] + - src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2] + - src_ptr[stride * 2 + 3] + src_ptr[stride * 3 + 0] + - src_ptr[stride * 3 + 1] + src_ptr[stride * 3 + 2] + - src_ptr[stride * 3 + 3] + 8) >> - 4; - } -} - -void ScaleRowDown4Box_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst, - int dst_width) { - intptr_t stride = src_stride; - int x; - for (x = 0; x < dst_width - 1; x += 2) { - dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + - src_ptr[stride + 0] + src_ptr[stride + 1] + src_ptr[stride + 2] + - src_ptr[stride + 3] + src_ptr[stride * 2 + 0] + - src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2] + - src_ptr[stride * 2 + 3] + src_ptr[stride * 3 + 0] + - src_ptr[stride * 3 + 1] + src_ptr[stride * 3 + 2] + - src_ptr[stride * 3 + 3] + 8) >> - 4; - dst[1] = (src_ptr[4] + src_ptr[5] + src_ptr[6] + src_ptr[7] + - src_ptr[stride + 4] + src_ptr[stride + 5] + src_ptr[stride + 6] + - src_ptr[stride + 7] + src_ptr[stride * 2 + 4] + - src_ptr[stride * 2 + 5] + src_ptr[stride * 2 + 6] + - src_ptr[stride * 2 + 7] + src_ptr[stride * 3 + 4] + - src_ptr[stride * 3 + 5] + src_ptr[stride * 3 + 6] + - src_ptr[stride * 3 + 7] + 8) >> - 4; - dst += 2; - src_ptr += 8; - } - if (dst_width & 1) { - dst[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[3] + - src_ptr[stride + 0] + src_ptr[stride + 1] + src_ptr[stride + 2] + - src_ptr[stride + 3] + src_ptr[stride * 2 + 0] + - src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2] + - src_ptr[stride * 2 + 3] + src_ptr[stride * 3 + 0] + - src_ptr[stride * 3 + 1] + src_ptr[stride * 3 + 2] + - src_ptr[stride * 3 + 3] + 8) >> - 4; - } -} - -void ScaleRowDown34_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - int x; - (void)src_stride; - assert((dst_width % 3 == 0) && (dst_width > 0)); - for (x = 0; x < dst_width; x += 3) { - dst[0] = src_ptr[0]; - dst[1] = src_ptr[1]; - dst[2] = src_ptr[3]; - dst += 3; - src_ptr += 4; - } -} - -void ScaleRowDown34_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst, - int dst_width) { - int x; - (void)src_stride; - assert((dst_width % 3 == 0) && (dst_width > 0)); - for (x = 0; x < dst_width; x += 3) { - dst[0] = src_ptr[0]; - dst[1] = src_ptr[1]; - dst[2] = src_ptr[3]; - dst += 3; - src_ptr += 4; - } -} - -// Filter rows 0 and 1 together, 3 : 1 -void ScaleRowDown34_0_Box_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* d, - int dst_width) { - const uint8_t* s = src_ptr; - const uint8_t* t = src_ptr + src_stride; - int x; - assert((dst_width % 3 == 0) && (dst_width > 0)); - for (x = 0; x < dst_width; x += 3) { - uint8_t a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; - uint8_t a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; - uint8_t a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; - uint8_t b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; - uint8_t b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; - uint8_t b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; - d[0] = (a0 * 3 + b0 + 2) >> 2; - d[1] = (a1 * 3 + b1 + 2) >> 2; - d[2] = (a2 * 3 + b2 + 2) >> 2; - d += 3; - s += 4; - t += 4; - } -} - -void ScaleRowDown34_0_Box_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* d, - int dst_width) { - const uint16_t* s = src_ptr; - const uint16_t* t = src_ptr + src_stride; - int x; - assert((dst_width % 3 == 0) && (dst_width > 0)); - for (x = 0; x < dst_width; x += 3) { - uint16_t a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; - uint16_t a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; - uint16_t a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; - uint16_t b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; - uint16_t b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; - uint16_t b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; - d[0] = (a0 * 3 + b0 + 2) >> 2; - d[1] = (a1 * 3 + b1 + 2) >> 2; - d[2] = (a2 * 3 + b2 + 2) >> 2; - d += 3; - s += 4; - t += 4; - } -} - -// Filter rows 1 and 2 together, 1 : 1 -void ScaleRowDown34_1_Box_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* d, - int dst_width) { - const uint8_t* s = src_ptr; - const uint8_t* t = src_ptr + src_stride; - int x; - assert((dst_width % 3 == 0) && (dst_width > 0)); - for (x = 0; x < dst_width; x += 3) { - uint8_t a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; - uint8_t a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; - uint8_t a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; - uint8_t b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; - uint8_t b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; - uint8_t b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; - d[0] = (a0 + b0 + 1) >> 1; - d[1] = (a1 + b1 + 1) >> 1; - d[2] = (a2 + b2 + 1) >> 1; - d += 3; - s += 4; - t += 4; - } -} - -void ScaleRowDown34_1_Box_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* d, - int dst_width) { - const uint16_t* s = src_ptr; - const uint16_t* t = src_ptr + src_stride; - int x; - assert((dst_width % 3 == 0) && (dst_width > 0)); - for (x = 0; x < dst_width; x += 3) { - uint16_t a0 = (s[0] * 3 + s[1] * 1 + 2) >> 2; - uint16_t a1 = (s[1] * 1 + s[2] * 1 + 1) >> 1; - uint16_t a2 = (s[2] * 1 + s[3] * 3 + 2) >> 2; - uint16_t b0 = (t[0] * 3 + t[1] * 1 + 2) >> 2; - uint16_t b1 = (t[1] * 1 + t[2] * 1 + 1) >> 1; - uint16_t b2 = (t[2] * 1 + t[3] * 3 + 2) >> 2; - d[0] = (a0 + b0 + 1) >> 1; - d[1] = (a1 + b1 + 1) >> 1; - d[2] = (a2 + b2 + 1) >> 1; - d += 3; - s += 4; - t += 4; - } -} - -// Scales a single row of pixels using point sampling. -void ScaleCols_C(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx) { - int j; - for (j = 0; j < dst_width - 1; j += 2) { - dst_ptr[0] = src_ptr[x >> 16]; - x += dx; - dst_ptr[1] = src_ptr[x >> 16]; - x += dx; - dst_ptr += 2; - } - if (dst_width & 1) { - dst_ptr[0] = src_ptr[x >> 16]; - } -} - -void ScaleCols_16_C(uint16_t* dst_ptr, - const uint16_t* src_ptr, - int dst_width, - int x, - int dx) { - int j; - for (j = 0; j < dst_width - 1; j += 2) { - dst_ptr[0] = src_ptr[x >> 16]; - x += dx; - dst_ptr[1] = src_ptr[x >> 16]; - x += dx; - dst_ptr += 2; - } - if (dst_width & 1) { - dst_ptr[0] = src_ptr[x >> 16]; - } -} - -// Scales a single row of pixels up by 2x using point sampling. -void ScaleColsUp2_C(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx) { - int j; - (void)x; - (void)dx; - for (j = 0; j < dst_width - 1; j += 2) { - dst_ptr[1] = dst_ptr[0] = src_ptr[0]; - src_ptr += 1; - dst_ptr += 2; - } - if (dst_width & 1) { - dst_ptr[0] = src_ptr[0]; - } -} - -void ScaleColsUp2_16_C(uint16_t* dst_ptr, - const uint16_t* src_ptr, - int dst_width, - int x, - int dx) { - int j; - (void)x; - (void)dx; - for (j = 0; j < dst_width - 1; j += 2) { - dst_ptr[1] = dst_ptr[0] = src_ptr[0]; - src_ptr += 1; - dst_ptr += 2; - } - if (dst_width & 1) { - dst_ptr[0] = src_ptr[0]; - } -} - -// (1-f)a + fb can be replaced with a + f(b-a) -#if defined(__arm__) || defined(__aarch64__) -#define BLENDER(a, b, f) \ - (uint8_t)((int)(a) + ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16)) -#else -// Intel uses 7 bit math with rounding. -#define BLENDER(a, b, f) \ - (uint8_t)((int)(a) + (((int)((f) >> 9) * ((int)(b) - (int)(a)) + 0x40) >> 7)) -#endif - -void ScaleFilterCols_C(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx) { - int j; - for (j = 0; j < dst_width - 1; j += 2) { - int xi = x >> 16; - int a = src_ptr[xi]; - int b = src_ptr[xi + 1]; - dst_ptr[0] = BLENDER(a, b, x & 0xffff); - x += dx; - xi = x >> 16; - a = src_ptr[xi]; - b = src_ptr[xi + 1]; - dst_ptr[1] = BLENDER(a, b, x & 0xffff); - x += dx; - dst_ptr += 2; - } - if (dst_width & 1) { - int xi = x >> 16; - int a = src_ptr[xi]; - int b = src_ptr[xi + 1]; - dst_ptr[0] = BLENDER(a, b, x & 0xffff); - } -} - -void ScaleFilterCols64_C(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x32, - int dx) { - int64_t x = (int64_t)(x32); - int j; - for (j = 0; j < dst_width - 1; j += 2) { - int64_t xi = x >> 16; - int a = src_ptr[xi]; - int b = src_ptr[xi + 1]; - dst_ptr[0] = BLENDER(a, b, x & 0xffff); - x += dx; - xi = x >> 16; - a = src_ptr[xi]; - b = src_ptr[xi + 1]; - dst_ptr[1] = BLENDER(a, b, x & 0xffff); - x += dx; - dst_ptr += 2; - } - if (dst_width & 1) { - int64_t xi = x >> 16; - int a = src_ptr[xi]; - int b = src_ptr[xi + 1]; - dst_ptr[0] = BLENDER(a, b, x & 0xffff); - } -} -#undef BLENDER - -// Same as 8 bit arm blender but return is cast to uint16_t -#define BLENDER(a, b, f) \ - (uint16_t)((int)(a) + ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16)) - -void ScaleFilterCols_16_C(uint16_t* dst_ptr, - const uint16_t* src_ptr, - int dst_width, - int x, - int dx) { - int j; - for (j = 0; j < dst_width - 1; j += 2) { - int xi = x >> 16; - int a = src_ptr[xi]; - int b = src_ptr[xi + 1]; - dst_ptr[0] = BLENDER(a, b, x & 0xffff); - x += dx; - xi = x >> 16; - a = src_ptr[xi]; - b = src_ptr[xi + 1]; - dst_ptr[1] = BLENDER(a, b, x & 0xffff); - x += dx; - dst_ptr += 2; - } - if (dst_width & 1) { - int xi = x >> 16; - int a = src_ptr[xi]; - int b = src_ptr[xi + 1]; - dst_ptr[0] = BLENDER(a, b, x & 0xffff); - } -} - -void ScaleFilterCols64_16_C(uint16_t* dst_ptr, - const uint16_t* src_ptr, - int dst_width, - int x32, - int dx) { - int64_t x = (int64_t)(x32); - int j; - for (j = 0; j < dst_width - 1; j += 2) { - int64_t xi = x >> 16; - int a = src_ptr[xi]; - int b = src_ptr[xi + 1]; - dst_ptr[0] = BLENDER(a, b, x & 0xffff); - x += dx; - xi = x >> 16; - a = src_ptr[xi]; - b = src_ptr[xi + 1]; - dst_ptr[1] = BLENDER(a, b, x & 0xffff); - x += dx; - dst_ptr += 2; - } - if (dst_width & 1) { - int64_t xi = x >> 16; - int a = src_ptr[xi]; - int b = src_ptr[xi + 1]; - dst_ptr[0] = BLENDER(a, b, x & 0xffff); - } -} -#undef BLENDER - -void ScaleRowDown38_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - int x; - (void)src_stride; - assert(dst_width % 3 == 0); - for (x = 0; x < dst_width; x += 3) { - dst[0] = src_ptr[0]; - dst[1] = src_ptr[3]; - dst[2] = src_ptr[6]; - dst += 3; - src_ptr += 8; - } -} - -void ScaleRowDown38_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst, - int dst_width) { - int x; - (void)src_stride; - assert(dst_width % 3 == 0); - for (x = 0; x < dst_width; x += 3) { - dst[0] = src_ptr[0]; - dst[1] = src_ptr[3]; - dst[2] = src_ptr[6]; - dst += 3; - src_ptr += 8; - } -} - -// 8x3 -> 3x1 -void ScaleRowDown38_3_Box_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - intptr_t stride = src_stride; - int i; - assert((dst_width % 3 == 0) && (dst_width > 0)); - for (i = 0; i < dst_width; i += 3) { - dst_ptr[0] = - (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[stride + 0] + - src_ptr[stride + 1] + src_ptr[stride + 2] + src_ptr[stride * 2 + 0] + - src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2]) * - (65536 / 9) >> - 16; - dst_ptr[1] = - (src_ptr[3] + src_ptr[4] + src_ptr[5] + src_ptr[stride + 3] + - src_ptr[stride + 4] + src_ptr[stride + 5] + src_ptr[stride * 2 + 3] + - src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5]) * - (65536 / 9) >> - 16; - dst_ptr[2] = - (src_ptr[6] + src_ptr[7] + src_ptr[stride + 6] + src_ptr[stride + 7] + - src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7]) * - (65536 / 6) >> - 16; - src_ptr += 8; - dst_ptr += 3; - } -} - -void ScaleRowDown38_3_Box_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst_ptr, - int dst_width) { - intptr_t stride = src_stride; - int i; - assert((dst_width % 3 == 0) && (dst_width > 0)); - for (i = 0; i < dst_width; i += 3) { - dst_ptr[0] = - (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[stride + 0] + - src_ptr[stride + 1] + src_ptr[stride + 2] + src_ptr[stride * 2 + 0] + - src_ptr[stride * 2 + 1] + src_ptr[stride * 2 + 2]) * - (65536 / 9) >> - 16; - dst_ptr[1] = - (src_ptr[3] + src_ptr[4] + src_ptr[5] + src_ptr[stride + 3] + - src_ptr[stride + 4] + src_ptr[stride + 5] + src_ptr[stride * 2 + 3] + - src_ptr[stride * 2 + 4] + src_ptr[stride * 2 + 5]) * - (65536 / 9) >> - 16; - dst_ptr[2] = - (src_ptr[6] + src_ptr[7] + src_ptr[stride + 6] + src_ptr[stride + 7] + - src_ptr[stride * 2 + 6] + src_ptr[stride * 2 + 7]) * - (65536 / 6) >> - 16; - src_ptr += 8; - dst_ptr += 3; - } -} - -// 8x2 -> 3x1 -void ScaleRowDown38_2_Box_C(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - intptr_t stride = src_stride; - int i; - assert((dst_width % 3 == 0) && (dst_width > 0)); - for (i = 0; i < dst_width; i += 3) { - dst_ptr[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[stride + 0] + - src_ptr[stride + 1] + src_ptr[stride + 2]) * - (65536 / 6) >> - 16; - dst_ptr[1] = (src_ptr[3] + src_ptr[4] + src_ptr[5] + src_ptr[stride + 3] + - src_ptr[stride + 4] + src_ptr[stride + 5]) * - (65536 / 6) >> - 16; - dst_ptr[2] = - (src_ptr[6] + src_ptr[7] + src_ptr[stride + 6] + src_ptr[stride + 7]) * - (65536 / 4) >> - 16; - src_ptr += 8; - dst_ptr += 3; - } -} - -void ScaleRowDown38_2_Box_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst_ptr, - int dst_width) { - intptr_t stride = src_stride; - int i; - assert((dst_width % 3 == 0) && (dst_width > 0)); - for (i = 0; i < dst_width; i += 3) { - dst_ptr[0] = (src_ptr[0] + src_ptr[1] + src_ptr[2] + src_ptr[stride + 0] + - src_ptr[stride + 1] + src_ptr[stride + 2]) * - (65536 / 6) >> - 16; - dst_ptr[1] = (src_ptr[3] + src_ptr[4] + src_ptr[5] + src_ptr[stride + 3] + - src_ptr[stride + 4] + src_ptr[stride + 5]) * - (65536 / 6) >> - 16; - dst_ptr[2] = - (src_ptr[6] + src_ptr[7] + src_ptr[stride + 6] + src_ptr[stride + 7]) * - (65536 / 4) >> - 16; - src_ptr += 8; - dst_ptr += 3; - } -} - -void ScaleAddRow_C(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width) { - int x; - assert(src_width > 0); - for (x = 0; x < src_width - 1; x += 2) { - dst_ptr[0] += src_ptr[0]; - dst_ptr[1] += src_ptr[1]; - src_ptr += 2; - dst_ptr += 2; - } - if (src_width & 1) { - dst_ptr[0] += src_ptr[0]; - } -} - -void ScaleAddRow_16_C(const uint16_t* src_ptr, - uint32_t* dst_ptr, - int src_width) { - int x; - assert(src_width > 0); - for (x = 0; x < src_width - 1; x += 2) { - dst_ptr[0] += src_ptr[0]; - dst_ptr[1] += src_ptr[1]; - src_ptr += 2; - dst_ptr += 2; - } - if (src_width & 1) { - dst_ptr[0] += src_ptr[0]; - } -} - -void ScaleARGBRowDown2_C(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width) { - const uint32_t* src = (const uint32_t*)(src_argb); - uint32_t* dst = (uint32_t*)(dst_argb); - int x; - (void)src_stride; - for (x = 0; x < dst_width - 1; x += 2) { - dst[0] = src[1]; - dst[1] = src[3]; - src += 4; - dst += 2; - } - if (dst_width & 1) { - dst[0] = src[1]; - } -} - -void ScaleARGBRowDown2Linear_C(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width) { - int x; - (void)src_stride; - for (x = 0; x < dst_width; ++x) { - dst_argb[0] = (src_argb[0] + src_argb[4] + 1) >> 1; - dst_argb[1] = (src_argb[1] + src_argb[5] + 1) >> 1; - dst_argb[2] = (src_argb[2] + src_argb[6] + 1) >> 1; - dst_argb[3] = (src_argb[3] + src_argb[7] + 1) >> 1; - src_argb += 8; - dst_argb += 4; - } -} - -void ScaleARGBRowDown2Box_C(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width) { - int x; - for (x = 0; x < dst_width; ++x) { - dst_argb[0] = (src_argb[0] + src_argb[4] + src_argb[src_stride] + - src_argb[src_stride + 4] + 2) >> - 2; - dst_argb[1] = (src_argb[1] + src_argb[5] + src_argb[src_stride + 1] + - src_argb[src_stride + 5] + 2) >> - 2; - dst_argb[2] = (src_argb[2] + src_argb[6] + src_argb[src_stride + 2] + - src_argb[src_stride + 6] + 2) >> - 2; - dst_argb[3] = (src_argb[3] + src_argb[7] + src_argb[src_stride + 3] + - src_argb[src_stride + 7] + 2) >> - 2; - src_argb += 8; - dst_argb += 4; - } -} - -void ScaleARGBRowDownEven_C(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width) { - const uint32_t* src = (const uint32_t*)(src_argb); - uint32_t* dst = (uint32_t*)(dst_argb); - (void)src_stride; - int x; - for (x = 0; x < dst_width - 1; x += 2) { - dst[0] = src[0]; - dst[1] = src[src_stepx]; - src += src_stepx * 2; - dst += 2; - } - if (dst_width & 1) { - dst[0] = src[0]; - } -} - -void ScaleARGBRowDownEvenBox_C(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width) { - int x; - for (x = 0; x < dst_width; ++x) { - dst_argb[0] = (src_argb[0] + src_argb[4] + src_argb[src_stride] + - src_argb[src_stride + 4] + 2) >> - 2; - dst_argb[1] = (src_argb[1] + src_argb[5] + src_argb[src_stride + 1] + - src_argb[src_stride + 5] + 2) >> - 2; - dst_argb[2] = (src_argb[2] + src_argb[6] + src_argb[src_stride + 2] + - src_argb[src_stride + 6] + 2) >> - 2; - dst_argb[3] = (src_argb[3] + src_argb[7] + src_argb[src_stride + 3] + - src_argb[src_stride + 7] + 2) >> - 2; - src_argb += src_stepx * 4; - dst_argb += 4; - } -} - -// Scales a single row of pixels using point sampling. -void ScaleARGBCols_C(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx) { - const uint32_t* src = (const uint32_t*)(src_argb); - uint32_t* dst = (uint32_t*)(dst_argb); - int j; - for (j = 0; j < dst_width - 1; j += 2) { - dst[0] = src[x >> 16]; - x += dx; - dst[1] = src[x >> 16]; - x += dx; - dst += 2; - } - if (dst_width & 1) { - dst[0] = src[x >> 16]; - } -} - -void ScaleARGBCols64_C(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x32, - int dx) { - int64_t x = (int64_t)(x32); - const uint32_t* src = (const uint32_t*)(src_argb); - uint32_t* dst = (uint32_t*)(dst_argb); - int j; - for (j = 0; j < dst_width - 1; j += 2) { - dst[0] = src[x >> 16]; - x += dx; - dst[1] = src[x >> 16]; - x += dx; - dst += 2; - } - if (dst_width & 1) { - dst[0] = src[x >> 16]; - } -} - -// Scales a single row of pixels up by 2x using point sampling. -void ScaleARGBColsUp2_C(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx) { - const uint32_t* src = (const uint32_t*)(src_argb); - uint32_t* dst = (uint32_t*)(dst_argb); - int j; - (void)x; - (void)dx; - for (j = 0; j < dst_width - 1; j += 2) { - dst[1] = dst[0] = src[0]; - src += 1; - dst += 2; - } - if (dst_width & 1) { - dst[0] = src[0]; - } -} - -// TODO(fbarchard): Replace 0x7f ^ f with 128-f. bug=607. -// Mimics SSSE3 blender -#define BLENDER1(a, b, f) ((a) * (0x7f ^ f) + (b)*f) >> 7 -#define BLENDERC(a, b, f, s) \ - (uint32_t)(BLENDER1(((a) >> s) & 255, ((b) >> s) & 255, f) << s) -#define BLENDER(a, b, f) \ - BLENDERC(a, b, f, 24) | BLENDERC(a, b, f, 16) | BLENDERC(a, b, f, 8) | \ - BLENDERC(a, b, f, 0) - -void ScaleARGBFilterCols_C(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx) { - const uint32_t* src = (const uint32_t*)(src_argb); - uint32_t* dst = (uint32_t*)(dst_argb); - int j; - for (j = 0; j < dst_width - 1; j += 2) { - int xi = x >> 16; - int xf = (x >> 9) & 0x7f; - uint32_t a = src[xi]; - uint32_t b = src[xi + 1]; - dst[0] = BLENDER(a, b, xf); - x += dx; - xi = x >> 16; - xf = (x >> 9) & 0x7f; - a = src[xi]; - b = src[xi + 1]; - dst[1] = BLENDER(a, b, xf); - x += dx; - dst += 2; - } - if (dst_width & 1) { - int xi = x >> 16; - int xf = (x >> 9) & 0x7f; - uint32_t a = src[xi]; - uint32_t b = src[xi + 1]; - dst[0] = BLENDER(a, b, xf); - } -} - -void ScaleARGBFilterCols64_C(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x32, - int dx) { - int64_t x = (int64_t)(x32); - const uint32_t* src = (const uint32_t*)(src_argb); - uint32_t* dst = (uint32_t*)(dst_argb); - int j; - for (j = 0; j < dst_width - 1; j += 2) { - int64_t xi = x >> 16; - int xf = (x >> 9) & 0x7f; - uint32_t a = src[xi]; - uint32_t b = src[xi + 1]; - dst[0] = BLENDER(a, b, xf); - x += dx; - xi = x >> 16; - xf = (x >> 9) & 0x7f; - a = src[xi]; - b = src[xi + 1]; - dst[1] = BLENDER(a, b, xf); - x += dx; - dst += 2; - } - if (dst_width & 1) { - int64_t xi = x >> 16; - int xf = (x >> 9) & 0x7f; - uint32_t a = src[xi]; - uint32_t b = src[xi + 1]; - dst[0] = BLENDER(a, b, xf); - } -} -#undef BLENDER1 -#undef BLENDERC -#undef BLENDER - -// Scale plane vertically with bilinear interpolation. -void ScalePlaneVertical(int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint8_t* src_argb, - uint8_t* dst_argb, - int x, - int y, - int dy, - int bpp, - enum FilterMode filtering) { - // TODO(fbarchard): Allow higher bpp. - int dst_width_bytes = dst_width * bpp; - void (*InterpolateRow)(uint8_t * dst_argb, const uint8_t* src_argb, - ptrdiff_t src_stride, int dst_width, - int source_y_fraction) = InterpolateRow_C; - const int max_y = (src_height > 1) ? ((src_height - 1) << 16) - 1 : 0; - int j; - assert(bpp >= 1 && bpp <= 4); - assert(src_height != 0); - assert(dst_width > 0); - assert(dst_height > 0); - src_argb += (x >> 16) * bpp; -#if defined(HAS_INTERPOLATEROW_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - InterpolateRow = InterpolateRow_Any_SSSE3; - if (IS_ALIGNED(dst_width_bytes, 16)) { - InterpolateRow = InterpolateRow_SSSE3; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - InterpolateRow = InterpolateRow_Any_AVX2; - if (IS_ALIGNED(dst_width_bytes, 32)) { - InterpolateRow = InterpolateRow_AVX2; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - InterpolateRow = InterpolateRow_Any_NEON; - if (IS_ALIGNED(dst_width_bytes, 16)) { - InterpolateRow = InterpolateRow_NEON; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_MSA) - if (TestCpuFlag(kCpuHasMSA)) { - InterpolateRow = InterpolateRow_Any_MSA; - if (IS_ALIGNED(dst_width_bytes, 32)) { - InterpolateRow = InterpolateRow_MSA; - } - } -#endif - for (j = 0; j < dst_height; ++j) { - int yi; - int yf; - if (y > max_y) { - y = max_y; - } - yi = y >> 16; - yf = filtering ? ((y >> 8) & 255) : 0; - InterpolateRow(dst_argb, src_argb + yi * src_stride, src_stride, - dst_width_bytes, yf); - dst_argb += dst_stride; - y += dy; - } -} -void ScalePlaneVertical_16(int src_height, - int dst_width, - int dst_height, - int src_stride, - int dst_stride, - const uint16_t* src_argb, - uint16_t* dst_argb, - int x, - int y, - int dy, - int wpp, - enum FilterMode filtering) { - // TODO(fbarchard): Allow higher wpp. - int dst_width_words = dst_width * wpp; - void (*InterpolateRow)(uint16_t * dst_argb, const uint16_t* src_argb, - ptrdiff_t src_stride, int dst_width, - int source_y_fraction) = InterpolateRow_16_C; - const int max_y = (src_height > 1) ? ((src_height - 1) << 16) - 1 : 0; - int j; - assert(wpp >= 1 && wpp <= 2); - assert(src_height != 0); - assert(dst_width > 0); - assert(dst_height > 0); - src_argb += (x >> 16) * wpp; -#if defined(HAS_INTERPOLATEROW_16_SSE2) - if (TestCpuFlag(kCpuHasSSE2)) { - InterpolateRow = InterpolateRow_Any_16_SSE2; - if (IS_ALIGNED(dst_width_bytes, 16)) { - InterpolateRow = InterpolateRow_16_SSE2; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_16_SSSE3) - if (TestCpuFlag(kCpuHasSSSE3)) { - InterpolateRow = InterpolateRow_Any_16_SSSE3; - if (IS_ALIGNED(dst_width_bytes, 16)) { - InterpolateRow = InterpolateRow_16_SSSE3; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_16_AVX2) - if (TestCpuFlag(kCpuHasAVX2)) { - InterpolateRow = InterpolateRow_Any_16_AVX2; - if (IS_ALIGNED(dst_width_bytes, 32)) { - InterpolateRow = InterpolateRow_16_AVX2; - } - } -#endif -#if defined(HAS_INTERPOLATEROW_16_NEON) - if (TestCpuFlag(kCpuHasNEON)) { - InterpolateRow = InterpolateRow_Any_16_NEON; - if (IS_ALIGNED(dst_width_bytes, 16)) { - InterpolateRow = InterpolateRow_16_NEON; - } - } -#endif - for (j = 0; j < dst_height; ++j) { - int yi; - int yf; - if (y > max_y) { - y = max_y; - } - yi = y >> 16; - yf = filtering ? ((y >> 8) & 255) : 0; - InterpolateRow(dst_argb, src_argb + yi * src_stride, src_stride, - dst_width_words, yf); - dst_argb += dst_stride; - y += dy; - } -} - -// Simplify the filtering based on scale factors. -enum FilterMode ScaleFilterReduce(int src_width, - int src_height, - int dst_width, - int dst_height, - enum FilterMode filtering) { - if (src_width < 0) { - src_width = -src_width; - } - if (src_height < 0) { - src_height = -src_height; - } - if (filtering == kFilterBox) { - // If scaling both axis to 0.5 or larger, switch from Box to Bilinear. - if (dst_width * 2 >= src_width && dst_height * 2 >= src_height) { - filtering = kFilterBilinear; - } - } - if (filtering == kFilterBilinear) { - if (src_height == 1) { - filtering = kFilterLinear; - } - // TODO(fbarchard): Detect any odd scale factor and reduce to Linear. - if (dst_height == src_height || dst_height * 3 == src_height) { - filtering = kFilterLinear; - } - // TODO(fbarchard): Remove 1 pixel wide filter restriction, which is to - // avoid reading 2 pixels horizontally that causes memory exception. - if (src_width == 1) { - filtering = kFilterNone; - } - } - if (filtering == kFilterLinear) { - if (src_width == 1) { - filtering = kFilterNone; - } - // TODO(fbarchard): Detect any odd scale factor and reduce to None. - if (dst_width == src_width || dst_width * 3 == src_width) { - filtering = kFilterNone; - } - } - return filtering; -} - -// Divide num by div and return as 16.16 fixed point result. -int FixedDiv_C(int num, int div) { - return (int)(((int64_t)(num) << 16) / div); -} - -// Divide num by div and return as 16.16 fixed point result. -int FixedDiv1_C(int num, int div) { - return (int)((((int64_t)(num) << 16) - 0x00010001) / (div - 1)); -} - -#define CENTERSTART(dx, s) (dx < 0) ? -((-dx >> 1) + s) : ((dx >> 1) + s) - -// Compute slope values for stepping. -void ScaleSlope(int src_width, - int src_height, - int dst_width, - int dst_height, - enum FilterMode filtering, - int* x, - int* y, - int* dx, - int* dy) { - assert(x != NULL); - assert(y != NULL); - assert(dx != NULL); - assert(dy != NULL); - assert(src_width != 0); - assert(src_height != 0); - assert(dst_width > 0); - assert(dst_height > 0); - // Check for 1 pixel and avoid FixedDiv overflow. - if (dst_width == 1 && src_width >= 32768) { - dst_width = src_width; - } - if (dst_height == 1 && src_height >= 32768) { - dst_height = src_height; - } - if (filtering == kFilterBox) { - // Scale step for point sampling duplicates all pixels equally. - *dx = FixedDiv(Abs(src_width), dst_width); - *dy = FixedDiv(src_height, dst_height); - *x = 0; - *y = 0; - } else if (filtering == kFilterBilinear) { - // Scale step for bilinear sampling renders last pixel once for upsample. - if (dst_width <= Abs(src_width)) { - *dx = FixedDiv(Abs(src_width), dst_width); - *x = CENTERSTART(*dx, -32768); // Subtract 0.5 (32768) to center filter. - } else if (dst_width > 1) { - *dx = FixedDiv1(Abs(src_width), dst_width); - *x = 0; - } - if (dst_height <= src_height) { - *dy = FixedDiv(src_height, dst_height); - *y = CENTERSTART(*dy, -32768); // Subtract 0.5 (32768) to center filter. - } else if (dst_height > 1) { - *dy = FixedDiv1(src_height, dst_height); - *y = 0; - } - } else if (filtering == kFilterLinear) { - // Scale step for bilinear sampling renders last pixel once for upsample. - if (dst_width <= Abs(src_width)) { - *dx = FixedDiv(Abs(src_width), dst_width); - *x = CENTERSTART(*dx, -32768); // Subtract 0.5 (32768) to center filter. - } else if (dst_width > 1) { - *dx = FixedDiv1(Abs(src_width), dst_width); - *x = 0; - } - *dy = FixedDiv(src_height, dst_height); - *y = *dy >> 1; - } else { - // Scale step for point sampling duplicates all pixels equally. - *dx = FixedDiv(Abs(src_width), dst_width); - *dy = FixedDiv(src_height, dst_height); - *x = CENTERSTART(*dx, 0); - *y = CENTERSTART(*dy, 0); - } - // Negative src_width means horizontally mirror. - if (src_width < 0) { - *x += (dst_width - 1) * *dx; - *dx = -*dx; - // src_width = -src_width; // Caller must do this. - } -} -#undef CENTERSTART - -// Read 8x2 upsample with filtering and write 16x1. -// actually reads an extra pixel, so 9x2. -void ScaleRowUp2_16_C(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst, - int dst_width) { - const uint16_t* src2 = src_ptr + src_stride; - - int x; - for (x = 0; x < dst_width - 1; x += 2) { - uint16_t p0 = src_ptr[0]; - uint16_t p1 = src_ptr[1]; - uint16_t p2 = src2[0]; - uint16_t p3 = src2[1]; - dst[0] = (p0 * 9 + p1 * 3 + p2 * 3 + p3 + 8) >> 4; - dst[1] = (p0 * 3 + p1 * 9 + p2 + p3 * 3 + 8) >> 4; - ++src_ptr; - ++src2; - dst += 2; - } - if (dst_width & 1) { - uint16_t p0 = src_ptr[0]; - uint16_t p1 = src_ptr[1]; - uint16_t p2 = src2[0]; - uint16_t p3 = src2[1]; - dst[0] = (p0 * 9 + p1 * 3 + p2 * 3 + p3 + 8) >> 4; - } -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_gcc.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_gcc.cc deleted file mode 100644 index 312236d2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_gcc.cc +++ /dev/null @@ -1,1374 +0,0 @@ -/* - * Copyright 2013 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/row.h" -#include "libyuv/scale_row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// This module is for GCC x86 and x64. -#if !defined(LIBYUV_DISABLE_X86) && \ - (defined(__x86_64__) || (defined(__i386__) && !defined(_MSC_VER))) - -// Offsets for source bytes 0 to 9 -static const uvec8 kShuf0 = {0, 1, 3, 4, 5, 7, 8, 9, - 128, 128, 128, 128, 128, 128, 128, 128}; - -// Offsets for source bytes 11 to 20 with 8 subtracted = 3 to 12. -static const uvec8 kShuf1 = {3, 4, 5, 7, 8, 9, 11, 12, - 128, 128, 128, 128, 128, 128, 128, 128}; - -// Offsets for source bytes 21 to 31 with 16 subtracted = 5 to 31. -static const uvec8 kShuf2 = {5, 7, 8, 9, 11, 12, 13, 15, - 128, 128, 128, 128, 128, 128, 128, 128}; - -// Offsets for source bytes 0 to 10 -static const uvec8 kShuf01 = {0, 1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10}; - -// Offsets for source bytes 10 to 21 with 8 subtracted = 3 to 13. -static const uvec8 kShuf11 = {2, 3, 4, 5, 5, 6, 6, 7, - 8, 9, 9, 10, 10, 11, 12, 13}; - -// Offsets for source bytes 21 to 31 with 16 subtracted = 5 to 31. -static const uvec8 kShuf21 = {5, 6, 6, 7, 8, 9, 9, 10, - 10, 11, 12, 13, 13, 14, 14, 15}; - -// Coefficients for source bytes 0 to 10 -static const uvec8 kMadd01 = {3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2}; - -// Coefficients for source bytes 10 to 21 -static const uvec8 kMadd11 = {1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1}; - -// Coefficients for source bytes 21 to 31 -static const uvec8 kMadd21 = {2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3}; - -// Coefficients for source bytes 21 to 31 -static const vec16 kRound34 = {2, 2, 2, 2, 2, 2, 2, 2}; - -static const uvec8 kShuf38a = {0, 3, 6, 8, 11, 14, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128}; - -static const uvec8 kShuf38b = {128, 128, 128, 128, 128, 128, 0, 3, - 6, 8, 11, 14, 128, 128, 128, 128}; - -// Arrange words 0,3,6 into 0,1,2 -static const uvec8 kShufAc = {0, 1, 6, 7, 12, 13, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128}; - -// Arrange words 0,3,6 into 3,4,5 -static const uvec8 kShufAc3 = {128, 128, 128, 128, 128, 128, 0, 1, - 6, 7, 12, 13, 128, 128, 128, 128}; - -// Scaling values for boxes of 3x3 and 2x3 -static const uvec16 kScaleAc33 = {65536 / 9, 65536 / 9, 65536 / 6, 65536 / 9, - 65536 / 9, 65536 / 6, 0, 0}; - -// Arrange first value for pixels 0,1,2,3,4,5 -static const uvec8 kShufAb0 = {0, 128, 3, 128, 6, 128, 8, 128, - 11, 128, 14, 128, 128, 128, 128, 128}; - -// Arrange second value for pixels 0,1,2,3,4,5 -static const uvec8 kShufAb1 = {1, 128, 4, 128, 7, 128, 9, 128, - 12, 128, 15, 128, 128, 128, 128, 128}; - -// Arrange third value for pixels 0,1,2,3,4,5 -static const uvec8 kShufAb2 = {2, 128, 5, 128, 128, 128, 10, 128, - 13, 128, 128, 128, 128, 128, 128, 128}; - -// Scaling values for boxes of 3x2 and 2x2 -static const uvec16 kScaleAb2 = {65536 / 3, 65536 / 3, 65536 / 2, 65536 / 3, - 65536 / 3, 65536 / 2, 0, 0}; - -// GCC versions of row functions are verbatim conversions from Visual C. -// Generated using gcc disassembly on Visual C object file: -// objdump -D yuvscaler.obj >yuvscaler.txt - -void ScaleRowDown2_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - (void)src_stride; - asm volatile( - // 16 pixel loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "psrlw $0x8,%%xmm0 \n" - "psrlw $0x8,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - ::"memory", - "cc", "xmm0", "xmm1"); -} - -void ScaleRowDown2Linear_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - (void)src_stride; - asm volatile( - "pcmpeqb %%xmm4,%%xmm4 \n" - "psrlw $0xf,%%xmm4 \n" - "packuswb %%xmm4,%%xmm4 \n" - "pxor %%xmm5,%%xmm5 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "pavgw %%xmm5,%%xmm0 \n" - "pavgw %%xmm5,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - ::"memory", - "cc", "xmm0", "xmm1", "xmm4", "xmm5"); -} - -void ScaleRowDown2Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - asm volatile( - "pcmpeqb %%xmm4,%%xmm4 \n" - "psrlw $0xf,%%xmm4 \n" - "packuswb %%xmm4,%%xmm4 \n" - "pxor %%xmm5,%%xmm5 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x00(%0,%3,1),%%xmm2 \n" - "movdqu 0x10(%0,%3,1),%%xmm3 \n" - "lea 0x20(%0),%0 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm4,%%xmm3 \n" - "paddw %%xmm2,%%xmm0 \n" - "paddw %%xmm3,%%xmm1 \n" - "psrlw $0x1,%%xmm0 \n" - "psrlw $0x1,%%xmm1 \n" - "pavgw %%xmm5,%%xmm0 \n" - "pavgw %%xmm5,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - : "r"((intptr_t)(src_stride)) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); -} - -#ifdef HAS_SCALEROWDOWN2_AVX2 -void ScaleRowDown2_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - (void)src_stride; - asm volatile( - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpsrlw $0x8,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - ::"memory", - "cc", "xmm0", "xmm1"); -} - -void ScaleRowDown2Linear_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - (void)src_stride; - asm volatile( - "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" - "vpsrlw $0xf,%%ymm4,%%ymm4 \n" - "vpackuswb %%ymm4,%%ymm4,%%ymm4 \n" - "vpxor %%ymm5,%%ymm5,%%ymm5 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" - "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" - "vpavgw %%ymm5,%%ymm0,%%ymm0 \n" - "vpavgw %%ymm5,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - ::"memory", - "cc", "xmm0", "xmm1", "xmm4", "xmm5"); -} - -void ScaleRowDown2Box_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - asm volatile( - "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" - "vpsrlw $0xf,%%ymm4,%%ymm4 \n" - "vpackuswb %%ymm4,%%ymm4,%%ymm4 \n" - "vpxor %%ymm5,%%ymm5,%%ymm5 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vmovdqu 0x00(%0,%3,1),%%ymm2 \n" - "vmovdqu 0x20(%0,%3,1),%%ymm3 \n" - "lea 0x40(%0),%0 \n" - "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" - "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" - "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" - "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" - "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" - "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" - "vpsrlw $0x1,%%ymm0,%%ymm0 \n" - "vpsrlw $0x1,%%ymm1,%%ymm1 \n" - "vpavgw %%ymm5,%%ymm0,%%ymm0 \n" - "vpavgw %%ymm5,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vmovdqu %%ymm0,(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - : "r"((intptr_t)(src_stride)) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); -} -#endif // HAS_SCALEROWDOWN2_AVX2 - -void ScaleRowDown4_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - (void)src_stride; - asm volatile( - "pcmpeqb %%xmm5,%%xmm5 \n" - "psrld $0x18,%%xmm5 \n" - "pslld $0x10,%%xmm5 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "pand %%xmm5,%%xmm0 \n" - "pand %%xmm5,%%xmm1 \n" - "packuswb %%xmm1,%%xmm0 \n" - "psrlw $0x8,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movq %%xmm0,(%1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - ::"memory", - "cc", "xmm0", "xmm1", "xmm5"); -} - -void ScaleRowDown4Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - intptr_t stridex3; - asm volatile( - "pcmpeqb %%xmm4,%%xmm4 \n" - "psrlw $0xf,%%xmm4 \n" - "movdqa %%xmm4,%%xmm5 \n" - "packuswb %%xmm4,%%xmm4 \n" - "psllw $0x3,%%xmm5 \n" - "lea 0x00(%4,%4,2),%3 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x00(%0,%4,1),%%xmm2 \n" - "movdqu 0x10(%0,%4,1),%%xmm3 \n" - "pmaddubsw %%xmm4,%%xmm0 \n" - "pmaddubsw %%xmm4,%%xmm1 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm4,%%xmm3 \n" - "paddw %%xmm2,%%xmm0 \n" - "paddw %%xmm3,%%xmm1 \n" - "movdqu 0x00(%0,%4,2),%%xmm2 \n" - "movdqu 0x10(%0,%4,2),%%xmm3 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm4,%%xmm3 \n" - "paddw %%xmm2,%%xmm0 \n" - "paddw %%xmm3,%%xmm1 \n" - "movdqu 0x00(%0,%3,1),%%xmm2 \n" - "movdqu 0x10(%0,%3,1),%%xmm3 \n" - "lea 0x20(%0),%0 \n" - "pmaddubsw %%xmm4,%%xmm2 \n" - "pmaddubsw %%xmm4,%%xmm3 \n" - "paddw %%xmm2,%%xmm0 \n" - "paddw %%xmm3,%%xmm1 \n" - "phaddw %%xmm1,%%xmm0 \n" - "paddw %%xmm5,%%xmm0 \n" - "psrlw $0x4,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movq %%xmm0,(%1) \n" - "lea 0x8(%1),%1 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width), // %2 - "=&r"(stridex3) // %3 - : "r"((intptr_t)(src_stride)) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} - -#ifdef HAS_SCALEROWDOWN4_AVX2 -void ScaleRowDown4_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - (void)src_stride; - asm volatile( - "vpcmpeqb %%ymm5,%%ymm5,%%ymm5 \n" - "vpsrld $0x18,%%ymm5,%%ymm5 \n" - "vpslld $0x10,%%ymm5,%%ymm5 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "lea 0x40(%0),%0 \n" - "vpand %%ymm5,%%ymm0,%%ymm0 \n" - "vpand %%ymm5,%%ymm1,%%ymm1 \n" - "vpackuswb %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpsrlw $0x8,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vmovdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - ::"memory", - "cc", "xmm0", "xmm1", "xmm5"); -} - -void ScaleRowDown4Box_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - asm volatile( - "vpcmpeqb %%ymm4,%%ymm4,%%ymm4 \n" - "vpsrlw $0xf,%%ymm4,%%ymm4 \n" - "vpsllw $0x3,%%ymm4,%%ymm5 \n" - "vpackuswb %%ymm4,%%ymm4,%%ymm4 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm0 \n" - "vmovdqu 0x20(%0),%%ymm1 \n" - "vmovdqu 0x00(%0,%3,1),%%ymm2 \n" - "vmovdqu 0x20(%0,%3,1),%%ymm3 \n" - "vpmaddubsw %%ymm4,%%ymm0,%%ymm0 \n" - "vpmaddubsw %%ymm4,%%ymm1,%%ymm1 \n" - "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" - "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" - "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" - "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" - "vmovdqu 0x00(%0,%3,2),%%ymm2 \n" - "vmovdqu 0x20(%0,%3,2),%%ymm3 \n" - "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" - "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" - "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" - "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" - "vmovdqu 0x00(%0,%4,1),%%ymm2 \n" - "vmovdqu 0x20(%0,%4,1),%%ymm3 \n" - "lea 0x40(%0),%0 \n" - "vpmaddubsw %%ymm4,%%ymm2,%%ymm2 \n" - "vpmaddubsw %%ymm4,%%ymm3,%%ymm3 \n" - "vpaddw %%ymm2,%%ymm0,%%ymm0 \n" - "vpaddw %%ymm3,%%ymm1,%%ymm1 \n" - "vphaddw %%ymm1,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vpaddw %%ymm5,%%ymm0,%%ymm0 \n" - "vpsrlw $0x4,%%ymm0,%%ymm0 \n" - "vpackuswb %%ymm0,%%ymm0,%%ymm0 \n" - "vpermq $0xd8,%%ymm0,%%ymm0 \n" - "vmovdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - : "r"((intptr_t)(src_stride)), // %3 - "r"((intptr_t)(src_stride * 3)) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} -#endif // HAS_SCALEROWDOWN4_AVX2 - -void ScaleRowDown34_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - (void)src_stride; - asm volatile( - "movdqa %0,%%xmm3 \n" - "movdqa %1,%%xmm4 \n" - "movdqa %2,%%xmm5 \n" - : - : "m"(kShuf0), // %0 - "m"(kShuf1), // %1 - "m"(kShuf2) // %2 - ); - asm volatile( - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm2 \n" - "lea 0x20(%0),%0 \n" - "movdqa %%xmm2,%%xmm1 \n" - "palignr $0x8,%%xmm0,%%xmm1 \n" - "pshufb %%xmm3,%%xmm0 \n" - "pshufb %%xmm4,%%xmm1 \n" - "pshufb %%xmm5,%%xmm2 \n" - "movq %%xmm0,(%1) \n" - "movq %%xmm1,0x8(%1) \n" - "movq %%xmm2,0x10(%1) \n" - "lea 0x18(%1),%1 \n" - "sub $0x18,%2 \n" - "jg 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - ::"memory", - "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} - -void ScaleRowDown34_1_Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - asm volatile( - "movdqa %0,%%xmm2 \n" // kShuf01 - "movdqa %1,%%xmm3 \n" // kShuf11 - "movdqa %2,%%xmm4 \n" // kShuf21 - : - : "m"(kShuf01), // %0 - "m"(kShuf11), // %1 - "m"(kShuf21) // %2 - ); - asm volatile( - "movdqa %0,%%xmm5 \n" // kMadd01 - "movdqa %1,%%xmm0 \n" // kMadd11 - "movdqa %2,%%xmm1 \n" // kRound34 - : - : "m"(kMadd01), // %0 - "m"(kMadd11), // %1 - "m"(kRound34) // %2 - ); - asm volatile( - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm6 \n" - "movdqu 0x00(%0,%3,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" - "pshufb %%xmm2,%%xmm6 \n" - "pmaddubsw %%xmm5,%%xmm6 \n" - "paddsw %%xmm1,%%xmm6 \n" - "psrlw $0x2,%%xmm6 \n" - "packuswb %%xmm6,%%xmm6 \n" - "movq %%xmm6,(%1) \n" - "movdqu 0x8(%0),%%xmm6 \n" - "movdqu 0x8(%0,%3,1),%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" - "pshufb %%xmm3,%%xmm6 \n" - "pmaddubsw %%xmm0,%%xmm6 \n" - "paddsw %%xmm1,%%xmm6 \n" - "psrlw $0x2,%%xmm6 \n" - "packuswb %%xmm6,%%xmm6 \n" - "movq %%xmm6,0x8(%1) \n" - "movdqu 0x10(%0),%%xmm6 \n" - "movdqu 0x10(%0,%3,1),%%xmm7 \n" - "lea 0x20(%0),%0 \n" - "pavgb %%xmm7,%%xmm6 \n" - "pshufb %%xmm4,%%xmm6 \n" - "pmaddubsw %4,%%xmm6 \n" - "paddsw %%xmm1,%%xmm6 \n" - "psrlw $0x2,%%xmm6 \n" - "packuswb %%xmm6,%%xmm6 \n" - "movq %%xmm6,0x10(%1) \n" - "lea 0x18(%1),%1 \n" - "sub $0x18,%2 \n" - "jg 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - : "r"((intptr_t)(src_stride)), // %3 - "m"(kMadd21) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} - -void ScaleRowDown34_0_Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - asm volatile( - "movdqa %0,%%xmm2 \n" // kShuf01 - "movdqa %1,%%xmm3 \n" // kShuf11 - "movdqa %2,%%xmm4 \n" // kShuf21 - : - : "m"(kShuf01), // %0 - "m"(kShuf11), // %1 - "m"(kShuf21) // %2 - ); - asm volatile( - "movdqa %0,%%xmm5 \n" // kMadd01 - "movdqa %1,%%xmm0 \n" // kMadd11 - "movdqa %2,%%xmm1 \n" // kRound34 - : - : "m"(kMadd01), // %0 - "m"(kMadd11), // %1 - "m"(kRound34) // %2 - ); - - asm volatile( - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm6 \n" - "movdqu 0x00(%0,%3,1),%%xmm7 \n" - "pavgb %%xmm6,%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" - "pshufb %%xmm2,%%xmm6 \n" - "pmaddubsw %%xmm5,%%xmm6 \n" - "paddsw %%xmm1,%%xmm6 \n" - "psrlw $0x2,%%xmm6 \n" - "packuswb %%xmm6,%%xmm6 \n" - "movq %%xmm6,(%1) \n" - "movdqu 0x8(%0),%%xmm6 \n" - "movdqu 0x8(%0,%3,1),%%xmm7 \n" - "pavgb %%xmm6,%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" - "pshufb %%xmm3,%%xmm6 \n" - "pmaddubsw %%xmm0,%%xmm6 \n" - "paddsw %%xmm1,%%xmm6 \n" - "psrlw $0x2,%%xmm6 \n" - "packuswb %%xmm6,%%xmm6 \n" - "movq %%xmm6,0x8(%1) \n" - "movdqu 0x10(%0),%%xmm6 \n" - "movdqu 0x10(%0,%3,1),%%xmm7 \n" - "lea 0x20(%0),%0 \n" - "pavgb %%xmm6,%%xmm7 \n" - "pavgb %%xmm7,%%xmm6 \n" - "pshufb %%xmm4,%%xmm6 \n" - "pmaddubsw %4,%%xmm6 \n" - "paddsw %%xmm1,%%xmm6 \n" - "psrlw $0x2,%%xmm6 \n" - "packuswb %%xmm6,%%xmm6 \n" - "movq %%xmm6,0x10(%1) \n" - "lea 0x18(%1),%1 \n" - "sub $0x18,%2 \n" - "jg 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - : "r"((intptr_t)(src_stride)), // %3 - "m"(kMadd21) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} - -void ScaleRowDown38_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - (void)src_stride; - asm volatile( - "movdqa %3,%%xmm4 \n" - "movdqa %4,%%xmm5 \n" - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "pshufb %%xmm4,%%xmm0 \n" - "pshufb %%xmm5,%%xmm1 \n" - "paddusb %%xmm1,%%xmm0 \n" - "movq %%xmm0,(%1) \n" - "movhlps %%xmm0,%%xmm1 \n" - "movd %%xmm1,0x8(%1) \n" - "lea 0xc(%1),%1 \n" - "sub $0xc,%2 \n" - "jg 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - : "m"(kShuf38a), // %3 - "m"(kShuf38b) // %4 - : "memory", "cc", "xmm0", "xmm1", "xmm4", "xmm5"); -} - -void ScaleRowDown38_2_Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - asm volatile( - "movdqa %0,%%xmm2 \n" - "movdqa %1,%%xmm3 \n" - "movdqa %2,%%xmm4 \n" - "movdqa %3,%%xmm5 \n" - : - : "m"(kShufAb0), // %0 - "m"(kShufAb1), // %1 - "m"(kShufAb2), // %2 - "m"(kScaleAb2) // %3 - ); - asm volatile( - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%3,1),%%xmm1 \n" - "lea 0x10(%0),%0 \n" - "pavgb %%xmm1,%%xmm0 \n" - "movdqa %%xmm0,%%xmm1 \n" - "pshufb %%xmm2,%%xmm1 \n" - "movdqa %%xmm0,%%xmm6 \n" - "pshufb %%xmm3,%%xmm6 \n" - "paddusw %%xmm6,%%xmm1 \n" - "pshufb %%xmm4,%%xmm0 \n" - "paddusw %%xmm0,%%xmm1 \n" - "pmulhuw %%xmm5,%%xmm1 \n" - "packuswb %%xmm1,%%xmm1 \n" - "movd %%xmm1,(%1) \n" - "psrlq $0x10,%%xmm1 \n" - "movd %%xmm1,0x2(%1) \n" - "lea 0x6(%1),%1 \n" - "sub $0x6,%2 \n" - "jg 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - : "r"((intptr_t)(src_stride)) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); -} - -void ScaleRowDown38_3_Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - asm volatile( - "movdqa %0,%%xmm2 \n" - "movdqa %1,%%xmm3 \n" - "movdqa %2,%%xmm4 \n" - "pxor %%xmm5,%%xmm5 \n" - : - : "m"(kShufAc), // %0 - "m"(kShufAc3), // %1 - "m"(kScaleAc33) // %2 - ); - asm volatile( - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x00(%0,%3,1),%%xmm6 \n" - "movhlps %%xmm0,%%xmm1 \n" - "movhlps %%xmm6,%%xmm7 \n" - "punpcklbw %%xmm5,%%xmm0 \n" - "punpcklbw %%xmm5,%%xmm1 \n" - "punpcklbw %%xmm5,%%xmm6 \n" - "punpcklbw %%xmm5,%%xmm7 \n" - "paddusw %%xmm6,%%xmm0 \n" - "paddusw %%xmm7,%%xmm1 \n" - "movdqu 0x00(%0,%3,2),%%xmm6 \n" - "lea 0x10(%0),%0 \n" - "movhlps %%xmm6,%%xmm7 \n" - "punpcklbw %%xmm5,%%xmm6 \n" - "punpcklbw %%xmm5,%%xmm7 \n" - "paddusw %%xmm6,%%xmm0 \n" - "paddusw %%xmm7,%%xmm1 \n" - "movdqa %%xmm0,%%xmm6 \n" - "psrldq $0x2,%%xmm0 \n" - "paddusw %%xmm0,%%xmm6 \n" - "psrldq $0x2,%%xmm0 \n" - "paddusw %%xmm0,%%xmm6 \n" - "pshufb %%xmm2,%%xmm6 \n" - "movdqa %%xmm1,%%xmm7 \n" - "psrldq $0x2,%%xmm1 \n" - "paddusw %%xmm1,%%xmm7 \n" - "psrldq $0x2,%%xmm1 \n" - "paddusw %%xmm1,%%xmm7 \n" - "pshufb %%xmm3,%%xmm7 \n" - "paddusw %%xmm7,%%xmm6 \n" - "pmulhuw %%xmm4,%%xmm6 \n" - "packuswb %%xmm6,%%xmm6 \n" - "movd %%xmm6,(%1) \n" - "psrlq $0x10,%%xmm6 \n" - "movd %%xmm6,0x2(%1) \n" - "lea 0x6(%1),%1 \n" - "sub $0x6,%2 \n" - "jg 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - : "r"((intptr_t)(src_stride)) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} - -// Reads 16xN bytes and produces 16 shorts at a time. -void ScaleAddRow_SSE2(const uint8_t* src_ptr, - uint16_t* dst_ptr, - int src_width) { - asm volatile( - - "pxor %%xmm5,%%xmm5 \n" - - // 16 pixel loop. - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm3 \n" - "lea 0x10(%0),%0 \n" // src_ptr += 16 - "movdqu (%1),%%xmm0 \n" - "movdqu 0x10(%1),%%xmm1 \n" - "movdqa %%xmm3,%%xmm2 \n" - "punpcklbw %%xmm5,%%xmm2 \n" - "punpckhbw %%xmm5,%%xmm3 \n" - "paddusw %%xmm2,%%xmm0 \n" - "paddusw %%xmm3,%%xmm1 \n" - "movdqu %%xmm0,(%1) \n" - "movdqu %%xmm1,0x10(%1) \n" - "lea 0x20(%1),%1 \n" - "sub $0x10,%2 \n" - "jg 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(src_width) // %2 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); -} - -#ifdef HAS_SCALEADDROW_AVX2 -// Reads 32 bytes and accumulates to 32 shorts at a time. -void ScaleAddRow_AVX2(const uint8_t* src_ptr, - uint16_t* dst_ptr, - int src_width) { - asm volatile( - - "vpxor %%ymm5,%%ymm5,%%ymm5 \n" - - LABELALIGN - "1: \n" - "vmovdqu (%0),%%ymm3 \n" - "lea 0x20(%0),%0 \n" // src_ptr += 32 - "vpermq $0xd8,%%ymm3,%%ymm3 \n" - "vpunpcklbw %%ymm5,%%ymm3,%%ymm2 \n" - "vpunpckhbw %%ymm5,%%ymm3,%%ymm3 \n" - "vpaddusw (%1),%%ymm2,%%ymm0 \n" - "vpaddusw 0x20(%1),%%ymm3,%%ymm1 \n" - "vmovdqu %%ymm0,(%1) \n" - "vmovdqu %%ymm1,0x20(%1) \n" - "lea 0x40(%1),%1 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - "vzeroupper \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(src_width) // %2 - : - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm5"); -} -#endif // HAS_SCALEADDROW_AVX2 - -// Constant for making pixels signed to avoid pmaddubsw -// saturation. -static const uvec8 kFsub80 = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}; - -// Constant for making pixels unsigned and adding .5 for rounding. -static const uvec16 kFadd40 = {0x4040, 0x4040, 0x4040, 0x4040, - 0x4040, 0x4040, 0x4040, 0x4040}; - -// Bilinear column filtering. SSSE3 version. -void ScaleFilterCols_SSSE3(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx) { - intptr_t x0, x1, temp_pixel; - asm volatile( - "movd %6,%%xmm2 \n" - "movd %7,%%xmm3 \n" - "movl $0x04040000,%k2 \n" - "movd %k2,%%xmm5 \n" - "pcmpeqb %%xmm6,%%xmm6 \n" - "psrlw $0x9,%%xmm6 \n" // 0x007f007f - "pcmpeqb %%xmm7,%%xmm7 \n" - "psrlw $15,%%xmm7 \n" // 0x00010001 - - "pextrw $0x1,%%xmm2,%k3 \n" - "subl $0x2,%5 \n" - "jl 29f \n" - "movdqa %%xmm2,%%xmm0 \n" - "paddd %%xmm3,%%xmm0 \n" - "punpckldq %%xmm0,%%xmm2 \n" - "punpckldq %%xmm3,%%xmm3 \n" - "paddd %%xmm3,%%xmm3 \n" - "pextrw $0x3,%%xmm2,%k4 \n" - - LABELALIGN - "2: \n" - "movdqa %%xmm2,%%xmm1 \n" - "paddd %%xmm3,%%xmm2 \n" - "movzwl 0x00(%1,%3,1),%k2 \n" - "movd %k2,%%xmm0 \n" - "psrlw $0x9,%%xmm1 \n" - "movzwl 0x00(%1,%4,1),%k2 \n" - "movd %k2,%%xmm4 \n" - "pshufb %%xmm5,%%xmm1 \n" - "punpcklwd %%xmm4,%%xmm0 \n" - "psubb %8,%%xmm0 \n" // make pixels signed. - "pxor %%xmm6,%%xmm1 \n" // 128 - f = (f ^ 127 ) + - // 1 - "paddusb %%xmm7,%%xmm1 \n" - "pmaddubsw %%xmm0,%%xmm1 \n" - "pextrw $0x1,%%xmm2,%k3 \n" - "pextrw $0x3,%%xmm2,%k4 \n" - "paddw %9,%%xmm1 \n" // make pixels unsigned. - "psrlw $0x7,%%xmm1 \n" - "packuswb %%xmm1,%%xmm1 \n" - "movd %%xmm1,%k2 \n" - "mov %w2,(%0) \n" - "lea 0x2(%0),%0 \n" - "subl $0x2,%5 \n" - "jge 2b \n" - - LABELALIGN - "29: \n" - "addl $0x1,%5 \n" - "jl 99f \n" - "movzwl 0x00(%1,%3,1),%k2 \n" - "movd %k2,%%xmm0 \n" - "psrlw $0x9,%%xmm2 \n" - "pshufb %%xmm5,%%xmm2 \n" - "psubb %8,%%xmm0 \n" // make pixels signed. - "pxor %%xmm6,%%xmm2 \n" - "paddusb %%xmm7,%%xmm2 \n" - "pmaddubsw %%xmm0,%%xmm2 \n" - "paddw %9,%%xmm2 \n" // make pixels unsigned. - "psrlw $0x7,%%xmm2 \n" - "packuswb %%xmm2,%%xmm2 \n" - "movd %%xmm2,%k2 \n" - "mov %b2,(%0) \n" - "99: \n" - : "+r"(dst_ptr), // %0 - "+r"(src_ptr), // %1 - "=&a"(temp_pixel), // %2 - "=&r"(x0), // %3 - "=&r"(x1), // %4 -#if defined(__x86_64__) - "+rm"(dst_width) // %5 -#else - "+m"(dst_width) // %5 -#endif - : "rm"(x), // %6 - "rm"(dx), // %7 -#if defined(__x86_64__) - "x"(kFsub80), // %8 - "x"(kFadd40) // %9 -#else - "m"(kFsub80), // %8 - "m"(kFadd40) // %9 -#endif - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", - "xmm7"); -} - -// Reads 4 pixels, duplicates them and writes 8 pixels. -// Alignment requirement: src_argb 16 byte aligned, dst_argb 16 byte aligned. -void ScaleColsUp2_SSE2(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx) { - (void)x; - (void)dx; - asm volatile( - - LABELALIGN - "1: \n" - "movdqu (%1),%%xmm0 \n" - "lea 0x10(%1),%1 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpcklbw %%xmm0,%%xmm0 \n" - "punpckhbw %%xmm1,%%xmm1 \n" - "movdqu %%xmm0,(%0) \n" - "movdqu %%xmm1,0x10(%0) \n" - "lea 0x20(%0),%0 \n" - "sub $0x20,%2 \n" - "jg 1b \n" - - : "+r"(dst_ptr), // %0 - "+r"(src_ptr), // %1 - "+r"(dst_width) // %2 - ::"memory", - "cc", "xmm0", "xmm1"); -} - -void ScaleARGBRowDown2_SSE2(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width) { - (void)src_stride; - asm volatile( - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "shufps $0xdd,%%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(dst_width) // %2 - ::"memory", - "cc", "xmm0", "xmm1"); -} - -void ScaleARGBRowDown2Linear_SSE2(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width) { - (void)src_stride; - asm volatile( - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "lea 0x20(%0),%0 \n" - "movdqa %%xmm0,%%xmm2 \n" - "shufps $0x88,%%xmm1,%%xmm0 \n" - "shufps $0xdd,%%xmm1,%%xmm2 \n" - "pavgb %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(dst_width) // %2 - ::"memory", - "cc", "xmm0", "xmm1"); -} - -void ScaleARGBRowDown2Box_SSE2(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width) { - asm volatile( - - LABELALIGN - "1: \n" - "movdqu (%0),%%xmm0 \n" - "movdqu 0x10(%0),%%xmm1 \n" - "movdqu 0x00(%0,%3,1),%%xmm2 \n" - "movdqu 0x10(%0,%3,1),%%xmm3 \n" - "lea 0x20(%0),%0 \n" - "pavgb %%xmm2,%%xmm0 \n" - "pavgb %%xmm3,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "shufps $0x88,%%xmm1,%%xmm0 \n" - "shufps $0xdd,%%xmm1,%%xmm2 \n" - "pavgb %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%1) \n" - "lea 0x10(%1),%1 \n" - "sub $0x4,%2 \n" - "jg 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(dst_width) // %2 - : "r"((intptr_t)(src_stride)) // %3 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3"); -} - -// Reads 4 pixels at a time. -// Alignment requirement: dst_argb 16 byte aligned. -void ScaleARGBRowDownEven_SSE2(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width) { - intptr_t src_stepx_x4 = (intptr_t)(src_stepx); - intptr_t src_stepx_x12; - (void)src_stride; - asm volatile( - "lea 0x00(,%1,4),%1 \n" - "lea 0x00(%1,%1,2),%4 \n" - - LABELALIGN - "1: \n" - "movd (%0),%%xmm0 \n" - "movd 0x00(%0,%1,1),%%xmm1 \n" - "punpckldq %%xmm1,%%xmm0 \n" - "movd 0x00(%0,%1,2),%%xmm2 \n" - "movd 0x00(%0,%4,1),%%xmm3 \n" - "lea 0x00(%0,%1,4),%0 \n" - "punpckldq %%xmm3,%%xmm2 \n" - "punpcklqdq %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 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 - ::"memory", - "cc", "xmm0", "xmm1", "xmm2", "xmm3"); -} - -// Blends four 2x2 to 4x1. -// Alignment requirement: dst_argb 16 byte aligned. -void ScaleARGBRowDownEvenBox_SSE2(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width) { - intptr_t src_stepx_x4 = (intptr_t)(src_stepx); - intptr_t src_stepx_x12; - intptr_t row1 = (intptr_t)(src_stride); - asm volatile( - "lea 0x00(,%1,4),%1 \n" - "lea 0x00(%1,%1,2),%4 \n" - "lea 0x00(%0,%5,1),%5 \n" - - LABELALIGN - "1: \n" - "movq (%0),%%xmm0 \n" - "movhps 0x00(%0,%1,1),%%xmm0 \n" - "movq 0x00(%0,%1,2),%%xmm1 \n" - "movhps 0x00(%0,%4,1),%%xmm1 \n" - "lea 0x00(%0,%1,4),%0 \n" - "movq (%5),%%xmm2 \n" - "movhps 0x00(%5,%1,1),%%xmm2 \n" - "movq 0x00(%5,%1,2),%%xmm3 \n" - "movhps 0x00(%5,%4,1),%%xmm3 \n" - "lea 0x00(%5,%1,4),%5 \n" - "pavgb %%xmm2,%%xmm0 \n" - "pavgb %%xmm3,%%xmm1 \n" - "movdqa %%xmm0,%%xmm2 \n" - "shufps $0x88,%%xmm1,%%xmm0 \n" - "shufps $0xdd,%%xmm1,%%xmm2 \n" - "pavgb %%xmm2,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 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 - ::"memory", - "cc", "xmm0", "xmm1", "xmm2", "xmm3"); -} - -void ScaleARGBCols_SSE2(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx) { - intptr_t x0, x1; - asm volatile( - "movd %5,%%xmm2 \n" - "movd %6,%%xmm3 \n" - "pshufd $0x0,%%xmm2,%%xmm2 \n" - "pshufd $0x11,%%xmm3,%%xmm0 \n" - "paddd %%xmm0,%%xmm2 \n" - "paddd %%xmm3,%%xmm3 \n" - "pshufd $0x5,%%xmm3,%%xmm0 \n" - "paddd %%xmm0,%%xmm2 \n" - "paddd %%xmm3,%%xmm3 \n" - "pshufd $0x0,%%xmm3,%%xmm3 \n" - "pextrw $0x1,%%xmm2,%k0 \n" - "pextrw $0x3,%%xmm2,%k1 \n" - "cmp $0x0,%4 \n" - "jl 99f \n" - "sub $0x4,%4 \n" - "jl 49f \n" - - LABELALIGN - "40: \n" - "movd 0x00(%3,%0,4),%%xmm0 \n" - "movd 0x00(%3,%1,4),%%xmm1 \n" - "pextrw $0x5,%%xmm2,%k0 \n" - "pextrw $0x7,%%xmm2,%k1 \n" - "paddd %%xmm3,%%xmm2 \n" - "punpckldq %%xmm1,%%xmm0 \n" - "movd 0x00(%3,%0,4),%%xmm1 \n" - "movd 0x00(%3,%1,4),%%xmm4 \n" - "pextrw $0x1,%%xmm2,%k0 \n" - "pextrw $0x3,%%xmm2,%k1 \n" - "punpckldq %%xmm4,%%xmm1 \n" - "punpcklqdq %%xmm1,%%xmm0 \n" - "movdqu %%xmm0,(%2) \n" - "lea 0x10(%2),%2 \n" - "sub $0x4,%4 \n" - "jge 40b \n" - - "49: \n" - "test $0x2,%4 \n" - "je 29f \n" - "movd 0x00(%3,%0,4),%%xmm0 \n" - "movd 0x00(%3,%1,4),%%xmm1 \n" - "pextrw $0x5,%%xmm2,%k0 \n" - "punpckldq %%xmm1,%%xmm0 \n" - "movq %%xmm0,(%2) \n" - "lea 0x8(%2),%2 \n" - "29: \n" - "test $0x1,%4 \n" - "je 99f \n" - "movd 0x00(%3,%0,4),%%xmm0 \n" - "movd %%xmm0,(%2) \n" - "99: \n" - : "=&a"(x0), // %0 - "=&d"(x1), // %1 - "+r"(dst_argb), // %2 - "+r"(src_argb), // %3 - "+r"(dst_width) // %4 - : "rm"(x), // %5 - "rm"(dx) // %6 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4"); -} - -// Reads 4 pixels, duplicates them and writes 8 pixels. -// Alignment requirement: src_argb 16 byte aligned, dst_argb 16 byte aligned. -void ScaleARGBColsUp2_SSE2(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx) { - (void)x; - (void)dx; - asm volatile( - - LABELALIGN - "1: \n" - "movdqu (%1),%%xmm0 \n" - "lea 0x10(%1),%1 \n" - "movdqa %%xmm0,%%xmm1 \n" - "punpckldq %%xmm0,%%xmm0 \n" - "punpckhdq %%xmm1,%%xmm1 \n" - "movdqu %%xmm0,(%0) \n" - "movdqu %%xmm1,0x10(%0) \n" - "lea 0x20(%0),%0 \n" - "sub $0x8,%2 \n" - "jg 1b \n" - - : "+r"(dst_argb), // %0 - "+r"(src_argb), // %1 - "+r"(dst_width) // %2 - ::"memory", - "cc", "xmm0", "xmm1"); -} - -// Shuffle table for arranging 2 pixels into pairs for pmaddubsw -static const uvec8 kShuffleColARGB = { - 0u, 4u, 1u, 5u, 2u, 6u, 3u, 7u, // bbggrraa 1st pixel - 8u, 12u, 9u, 13u, 10u, 14u, 11u, 15u // bbggrraa 2nd pixel -}; - -// Shuffle table for duplicating 2 fractions into 8 bytes each -static const uvec8 kShuffleFractions = { - 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, -}; - -// Bilinear row filtering combines 4x2 -> 4x1. SSSE3 version -void ScaleARGBFilterCols_SSSE3(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx) { - intptr_t x0, x1; - asm volatile( - "movdqa %0,%%xmm4 \n" - "movdqa %1,%%xmm5 \n" - : - : "m"(kShuffleColARGB), // %0 - "m"(kShuffleFractions) // %1 - ); - - asm volatile( - "movd %5,%%xmm2 \n" - "movd %6,%%xmm3 \n" - "pcmpeqb %%xmm6,%%xmm6 \n" - "psrlw $0x9,%%xmm6 \n" - "pextrw $0x1,%%xmm2,%k3 \n" - "sub $0x2,%2 \n" - "jl 29f \n" - "movdqa %%xmm2,%%xmm0 \n" - "paddd %%xmm3,%%xmm0 \n" - "punpckldq %%xmm0,%%xmm2 \n" - "punpckldq %%xmm3,%%xmm3 \n" - "paddd %%xmm3,%%xmm3 \n" - "pextrw $0x3,%%xmm2,%k4 \n" - - LABELALIGN - "2: \n" - "movdqa %%xmm2,%%xmm1 \n" - "paddd %%xmm3,%%xmm2 \n" - "movq 0x00(%1,%3,4),%%xmm0 \n" - "psrlw $0x9,%%xmm1 \n" - "movhps 0x00(%1,%4,4),%%xmm0 \n" - "pshufb %%xmm5,%%xmm1 \n" - "pshufb %%xmm4,%%xmm0 \n" - "pxor %%xmm6,%%xmm1 \n" - "pmaddubsw %%xmm1,%%xmm0 \n" - "psrlw $0x7,%%xmm0 \n" - "pextrw $0x1,%%xmm2,%k3 \n" - "pextrw $0x3,%%xmm2,%k4 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movq %%xmm0,(%0) \n" - "lea 0x8(%0),%0 \n" - "sub $0x2,%2 \n" - "jge 2b \n" - - LABELALIGN - "29: \n" - "add $0x1,%2 \n" - "jl 99f \n" - "psrlw $0x9,%%xmm2 \n" - "movq 0x00(%1,%3,4),%%xmm0 \n" - "pshufb %%xmm5,%%xmm2 \n" - "pshufb %%xmm4,%%xmm0 \n" - "pxor %%xmm6,%%xmm2 \n" - "pmaddubsw %%xmm2,%%xmm0 \n" - "psrlw $0x7,%%xmm0 \n" - "packuswb %%xmm0,%%xmm0 \n" - "movd %%xmm0,(%0) \n" - - LABELALIGN "99: \n" // clang-format error. - - : "+r"(dst_argb), // %0 - "+r"(src_argb), // %1 - "+rm"(dst_width), // %2 - "=&r"(x0), // %3 - "=&r"(x1) // %4 - : "rm"(x), // %5 - "rm"(dx) // %6 - : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"); -} - -// Divide num by div and return as 16.16 fixed point result. -int FixedDiv_X86(int num, int div) { - asm volatile( - "cdq \n" - "shld $0x10,%%eax,%%edx \n" - "shl $0x10,%%eax \n" - "idiv %1 \n" - "mov %0, %%eax \n" - : "+a"(num) // %0 - : "c"(div) // %1 - : "memory", "cc", "edx"); - return num; -} - -// Divide num - 1 by div - 1 and return as 16.16 fixed point result. -int FixedDiv1_X86(int num, int div) { - asm volatile( - "cdq \n" - "shld $0x10,%%eax,%%edx \n" - "shl $0x10,%%eax \n" - "sub $0x10001,%%eax \n" - "sbb $0x0,%%edx \n" - "sub $0x1,%1 \n" - "idiv %1 \n" - "mov %0, %%eax \n" - : "+a"(num) // %0 - : "c"(div) // %1 - : "memory", "cc", "edx"); - return num; -} - -#endif // defined(__x86_64__) || defined(__i386__) - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_msa.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_msa.cc deleted file mode 100644 index 482a521f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_msa.cc +++ /dev/null @@ -1,949 +0,0 @@ -/* - * Copyright 2016 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "libyuv/scale_row.h" - -// This module is for GCC MSA -#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) -#include "libyuv/macros_msa.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -#define LOAD_INDEXED_DATA(srcp, indx0, out0) \ - { \ - out0[0] = srcp[indx0[0]]; \ - out0[1] = srcp[indx0[1]]; \ - out0[2] = srcp[indx0[2]]; \ - out0[3] = srcp[indx0[3]]; \ - } - -void ScaleARGBRowDown2_MSA(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width) { - int x; - v16u8 src0, src1, dst0; - (void)src_stride; - - for (x = 0; x < dst_width; x += 4) { - src0 = (v16u8)__msa_ld_b((v16i8*)src_argb, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)src_argb, 16); - dst0 = (v16u8)__msa_pckod_w((v4i32)src1, (v4i32)src0); - ST_UB(dst0, dst_argb); - src_argb += 32; - dst_argb += 16; - } -} - -void ScaleARGBRowDown2Linear_MSA(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width) { - int x; - v16u8 src0, src1, vec0, vec1, dst0; - (void)src_stride; - - for (x = 0; x < dst_width; x += 4) { - src0 = (v16u8)__msa_ld_b((v16i8*)src_argb, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)src_argb, 16); - vec0 = (v16u8)__msa_pckev_w((v4i32)src1, (v4i32)src0); - vec1 = (v16u8)__msa_pckod_w((v4i32)src1, (v4i32)src0); - dst0 = (v16u8)__msa_aver_u_b((v16u8)vec0, (v16u8)vec1); - ST_UB(dst0, dst_argb); - src_argb += 32; - dst_argb += 16; - } -} - -void ScaleARGBRowDown2Box_MSA(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width) { - int x; - const uint8_t* s = src_argb; - const uint8_t* t = src_argb + src_stride; - v16u8 src0, src1, src2, src3, vec0, vec1, vec2, vec3, dst0; - v8u16 reg0, reg1, reg2, reg3; - v16i8 shuffler = {0, 4, 1, 5, 2, 6, 3, 7, 8, 12, 9, 13, 10, 14, 11, 15}; - - for (x = 0; x < dst_width; x += 4) { - src0 = (v16u8)__msa_ld_b((v16i8*)s, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)s, 16); - src2 = (v16u8)__msa_ld_b((v16i8*)t, 0); - src3 = (v16u8)__msa_ld_b((v16i8*)t, 16); - vec0 = (v16u8)__msa_vshf_b(shuffler, (v16i8)src0, (v16i8)src0); - vec1 = (v16u8)__msa_vshf_b(shuffler, (v16i8)src1, (v16i8)src1); - vec2 = (v16u8)__msa_vshf_b(shuffler, (v16i8)src2, (v16i8)src2); - vec3 = (v16u8)__msa_vshf_b(shuffler, (v16i8)src3, (v16i8)src3); - reg0 = __msa_hadd_u_h(vec0, vec0); - reg1 = __msa_hadd_u_h(vec1, vec1); - reg2 = __msa_hadd_u_h(vec2, vec2); - reg3 = __msa_hadd_u_h(vec3, vec3); - reg0 += reg2; - reg1 += reg3; - reg0 = (v8u16)__msa_srari_h((v8i16)reg0, 2); - reg1 = (v8u16)__msa_srari_h((v8i16)reg1, 2); - dst0 = (v16u8)__msa_pckev_b((v16i8)reg1, (v16i8)reg0); - ST_UB(dst0, dst_argb); - s += 32; - t += 32; - dst_argb += 16; - } -} - -void ScaleARGBRowDownEven_MSA(const uint8_t* src_argb, - ptrdiff_t src_stride, - int32_t src_stepx, - uint8_t* dst_argb, - int dst_width) { - int x; - int32_t stepx = src_stepx * 4; - int32_t data0, data1, data2, data3; - (void)src_stride; - - for (x = 0; x < dst_width; x += 4) { - data0 = LW(src_argb); - data1 = LW(src_argb + stepx); - data2 = LW(src_argb + stepx * 2); - data3 = LW(src_argb + stepx * 3); - SW(data0, dst_argb); - SW(data1, dst_argb + 4); - SW(data2, dst_argb + 8); - SW(data3, dst_argb + 12); - src_argb += stepx * 4; - dst_argb += 16; - } -} - -void ScaleARGBRowDownEvenBox_MSA(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width) { - int x; - const uint8_t* nxt_argb = src_argb + src_stride; - int32_t stepx = src_stepx * 4; - int64_t data0, data1, data2, data3; - v16u8 src0 = {0}, src1 = {0}, src2 = {0}, src3 = {0}; - v16u8 vec0, vec1, vec2, vec3; - v8u16 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; - v16u8 dst0; - - for (x = 0; x < dst_width; x += 4) { - data0 = LD(src_argb); - data1 = LD(src_argb + stepx); - data2 = LD(src_argb + stepx * 2); - data3 = LD(src_argb + stepx * 3); - src0 = (v16u8)__msa_insert_d((v2i64)src0, 0, data0); - src0 = (v16u8)__msa_insert_d((v2i64)src0, 1, data1); - src1 = (v16u8)__msa_insert_d((v2i64)src1, 0, data2); - src1 = (v16u8)__msa_insert_d((v2i64)src1, 1, data3); - data0 = LD(nxt_argb); - data1 = LD(nxt_argb + stepx); - data2 = LD(nxt_argb + stepx * 2); - data3 = LD(nxt_argb + stepx * 3); - src2 = (v16u8)__msa_insert_d((v2i64)src2, 0, data0); - src2 = (v16u8)__msa_insert_d((v2i64)src2, 1, data1); - src3 = (v16u8)__msa_insert_d((v2i64)src3, 0, data2); - src3 = (v16u8)__msa_insert_d((v2i64)src3, 1, data3); - vec0 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src0); - vec1 = (v16u8)__msa_ilvr_b((v16i8)src3, (v16i8)src1); - vec2 = (v16u8)__msa_ilvl_b((v16i8)src2, (v16i8)src0); - vec3 = (v16u8)__msa_ilvl_b((v16i8)src3, (v16i8)src1); - reg0 = __msa_hadd_u_h(vec0, vec0); - reg1 = __msa_hadd_u_h(vec1, vec1); - reg2 = __msa_hadd_u_h(vec2, vec2); - reg3 = __msa_hadd_u_h(vec3, vec3); - reg4 = (v8u16)__msa_pckev_d((v2i64)reg2, (v2i64)reg0); - reg5 = (v8u16)__msa_pckev_d((v2i64)reg3, (v2i64)reg1); - reg6 = (v8u16)__msa_pckod_d((v2i64)reg2, (v2i64)reg0); - reg7 = (v8u16)__msa_pckod_d((v2i64)reg3, (v2i64)reg1); - reg4 += reg6; - reg5 += reg7; - reg4 = (v8u16)__msa_srari_h((v8i16)reg4, 2); - reg5 = (v8u16)__msa_srari_h((v8i16)reg5, 2); - dst0 = (v16u8)__msa_pckev_b((v16i8)reg5, (v16i8)reg4); - ST_UB(dst0, dst_argb); - src_argb += stepx * 4; - nxt_argb += stepx * 4; - dst_argb += 16; - } -} - -void ScaleRowDown2_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - int x; - v16u8 src0, src1, src2, src3, dst0, dst1; - (void)src_stride; - - for (x = 0; x < dst_width; x += 32) { - src0 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 16); - src2 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 32); - src3 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 48); - dst0 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0); - dst1 = (v16u8)__msa_pckod_b((v16i8)src3, (v16i8)src2); - ST_UB2(dst0, dst1, dst, 16); - src_ptr += 64; - dst += 32; - } -} - -void ScaleRowDown2Linear_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - int x; - v16u8 src0, src1, src2, src3, vec0, vec1, vec2, vec3, dst0, dst1; - (void)src_stride; - - for (x = 0; x < dst_width; x += 32) { - src0 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 16); - src2 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 32); - src3 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 48); - vec0 = (v16u8)__msa_pckev_b((v16i8)src1, (v16i8)src0); - vec2 = (v16u8)__msa_pckev_b((v16i8)src3, (v16i8)src2); - vec1 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0); - vec3 = (v16u8)__msa_pckod_b((v16i8)src3, (v16i8)src2); - dst0 = __msa_aver_u_b(vec1, vec0); - dst1 = __msa_aver_u_b(vec3, vec2); - ST_UB2(dst0, dst1, dst, 16); - src_ptr += 64; - dst += 32; - } -} - -void ScaleRowDown2Box_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - int x; - const uint8_t* s = src_ptr; - const uint8_t* t = src_ptr + src_stride; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7, dst0, dst1; - v8u16 vec0, vec1, vec2, vec3; - - for (x = 0; x < dst_width; x += 32) { - src0 = (v16u8)__msa_ld_b((v16i8*)s, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)s, 16); - src2 = (v16u8)__msa_ld_b((v16i8*)s, 32); - src3 = (v16u8)__msa_ld_b((v16i8*)s, 48); - src4 = (v16u8)__msa_ld_b((v16i8*)t, 0); - src5 = (v16u8)__msa_ld_b((v16i8*)t, 16); - src6 = (v16u8)__msa_ld_b((v16i8*)t, 32); - src7 = (v16u8)__msa_ld_b((v16i8*)t, 48); - vec0 = __msa_hadd_u_h(src0, src0); - vec1 = __msa_hadd_u_h(src1, src1); - vec2 = __msa_hadd_u_h(src2, src2); - vec3 = __msa_hadd_u_h(src3, src3); - vec0 += __msa_hadd_u_h(src4, src4); - vec1 += __msa_hadd_u_h(src5, src5); - vec2 += __msa_hadd_u_h(src6, src6); - vec3 += __msa_hadd_u_h(src7, src7); - vec0 = (v8u16)__msa_srari_h((v8i16)vec0, 2); - vec1 = (v8u16)__msa_srari_h((v8i16)vec1, 2); - vec2 = (v8u16)__msa_srari_h((v8i16)vec2, 2); - vec3 = (v8u16)__msa_srari_h((v8i16)vec3, 2); - dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - dst1 = (v16u8)__msa_pckev_b((v16i8)vec3, (v16i8)vec2); - ST_UB2(dst0, dst1, dst, 16); - s += 64; - t += 64; - dst += 32; - } -} - -void ScaleRowDown4_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - int x; - v16u8 src0, src1, src2, src3, vec0, vec1, dst0; - (void)src_stride; - - for (x = 0; x < dst_width; x += 16) { - src0 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 16); - src2 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 32); - src3 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 48); - vec0 = (v16u8)__msa_pckev_b((v16i8)src1, (v16i8)src0); - vec1 = (v16u8)__msa_pckev_b((v16i8)src3, (v16i8)src2); - dst0 = (v16u8)__msa_pckod_b((v16i8)vec1, (v16i8)vec0); - ST_UB(dst0, dst); - src_ptr += 64; - dst += 16; - } -} - -void ScaleRowDown4Box_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - int x; - const uint8_t* s = src_ptr; - const uint8_t* t0 = s + src_stride; - const uint8_t* t1 = s + src_stride * 2; - const uint8_t* t2 = s + src_stride * 3; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7, dst0; - v8u16 vec0, vec1, vec2, vec3; - v4u32 reg0, reg1, reg2, reg3; - - for (x = 0; x < dst_width; x += 16) { - src0 = (v16u8)__msa_ld_b((v16i8*)s, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)s, 16); - src2 = (v16u8)__msa_ld_b((v16i8*)s, 32); - src3 = (v16u8)__msa_ld_b((v16i8*)s, 48); - src4 = (v16u8)__msa_ld_b((v16i8*)t0, 0); - src5 = (v16u8)__msa_ld_b((v16i8*)t0, 16); - src6 = (v16u8)__msa_ld_b((v16i8*)t0, 32); - src7 = (v16u8)__msa_ld_b((v16i8*)t0, 48); - vec0 = __msa_hadd_u_h(src0, src0); - vec1 = __msa_hadd_u_h(src1, src1); - vec2 = __msa_hadd_u_h(src2, src2); - vec3 = __msa_hadd_u_h(src3, src3); - vec0 += __msa_hadd_u_h(src4, src4); - vec1 += __msa_hadd_u_h(src5, src5); - vec2 += __msa_hadd_u_h(src6, src6); - vec3 += __msa_hadd_u_h(src7, src7); - src0 = (v16u8)__msa_ld_b((v16i8*)t1, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)t1, 16); - src2 = (v16u8)__msa_ld_b((v16i8*)t1, 32); - src3 = (v16u8)__msa_ld_b((v16i8*)t1, 48); - src4 = (v16u8)__msa_ld_b((v16i8*)t2, 0); - src5 = (v16u8)__msa_ld_b((v16i8*)t2, 16); - src6 = (v16u8)__msa_ld_b((v16i8*)t2, 32); - src7 = (v16u8)__msa_ld_b((v16i8*)t2, 48); - vec0 += __msa_hadd_u_h(src0, src0); - vec1 += __msa_hadd_u_h(src1, src1); - vec2 += __msa_hadd_u_h(src2, src2); - vec3 += __msa_hadd_u_h(src3, src3); - vec0 += __msa_hadd_u_h(src4, src4); - vec1 += __msa_hadd_u_h(src5, src5); - vec2 += __msa_hadd_u_h(src6, src6); - vec3 += __msa_hadd_u_h(src7, src7); - reg0 = __msa_hadd_u_w(vec0, vec0); - reg1 = __msa_hadd_u_w(vec1, vec1); - reg2 = __msa_hadd_u_w(vec2, vec2); - reg3 = __msa_hadd_u_w(vec3, vec3); - reg0 = (v4u32)__msa_srari_w((v4i32)reg0, 4); - reg1 = (v4u32)__msa_srari_w((v4i32)reg1, 4); - reg2 = (v4u32)__msa_srari_w((v4i32)reg2, 4); - reg3 = (v4u32)__msa_srari_w((v4i32)reg3, 4); - vec0 = (v8u16)__msa_pckev_h((v8i16)reg1, (v8i16)reg0); - vec1 = (v8u16)__msa_pckev_h((v8i16)reg3, (v8i16)reg2); - dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0); - ST_UB(dst0, dst); - s += 64; - t0 += 64; - t1 += 64; - t2 += 64; - dst += 16; - } -} - -void ScaleRowDown38_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - int x, width; - uint64_t dst0; - uint32_t dst1; - v16u8 src0, src1, vec0; - v16i8 mask = {0, 3, 6, 8, 11, 14, 16, 19, 22, 24, 27, 30, 0, 0, 0, 0}; - (void)src_stride; - - assert(dst_width % 3 == 0); - width = dst_width / 3; - - for (x = 0; x < width; x += 4) { - src0 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 16); - vec0 = (v16u8)__msa_vshf_b(mask, (v16i8)src1, (v16i8)src0); - dst0 = __msa_copy_u_d((v2i64)vec0, 0); - dst1 = __msa_copy_u_w((v4i32)vec0, 2); - SD(dst0, dst); - SW(dst1, dst + 8); - src_ptr += 32; - dst += 12; - } -} - -void ScaleRowDown38_2_Box_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - int x, width; - const uint8_t* s = src_ptr; - const uint8_t* t = src_ptr + src_stride; - uint64_t dst0; - uint32_t dst1; - v16u8 src0, src1, src2, src3, out; - v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v4u32 tmp0, tmp1, tmp2, tmp3, tmp4; - v8i16 zero = {0}; - v8i16 mask = {0, 1, 2, 8, 3, 4, 5, 9}; - v16i8 dst_mask = {0, 2, 16, 4, 6, 18, 8, 10, 20, 12, 14, 22, 0, 0, 0, 0}; - v4u32 const_0x2AAA = (v4u32)__msa_fill_w(0x2AAA); - v4u32 const_0x4000 = (v4u32)__msa_fill_w(0x4000); - - assert((dst_width % 3 == 0) && (dst_width > 0)); - width = dst_width / 3; - - for (x = 0; x < width; x += 4) { - src0 = (v16u8)__msa_ld_b((v16i8*)s, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)s, 16); - src2 = (v16u8)__msa_ld_b((v16i8*)t, 0); - src3 = (v16u8)__msa_ld_b((v16i8*)t, 16); - vec0 = (v8u16)__msa_ilvr_b((v16i8)src2, (v16i8)src0); - vec1 = (v8u16)__msa_ilvl_b((v16i8)src2, (v16i8)src0); - vec2 = (v8u16)__msa_ilvr_b((v16i8)src3, (v16i8)src1); - vec3 = (v8u16)__msa_ilvl_b((v16i8)src3, (v16i8)src1); - vec0 = __msa_hadd_u_h((v16u8)vec0, (v16u8)vec0); - vec1 = __msa_hadd_u_h((v16u8)vec1, (v16u8)vec1); - vec2 = __msa_hadd_u_h((v16u8)vec2, (v16u8)vec2); - vec3 = __msa_hadd_u_h((v16u8)vec3, (v16u8)vec3); - vec4 = (v8u16)__msa_vshf_h(mask, zero, (v8i16)vec0); - vec5 = (v8u16)__msa_vshf_h(mask, zero, (v8i16)vec1); - vec6 = (v8u16)__msa_vshf_h(mask, zero, (v8i16)vec2); - vec7 = (v8u16)__msa_vshf_h(mask, zero, (v8i16)vec3); - vec0 = (v8u16)__msa_pckod_w((v4i32)vec1, (v4i32)vec0); - vec1 = (v8u16)__msa_pckod_w((v4i32)vec3, (v4i32)vec2); - vec0 = (v8u16)__msa_pckod_w((v4i32)vec1, (v4i32)vec0); - tmp0 = __msa_hadd_u_w(vec4, vec4); - tmp1 = __msa_hadd_u_w(vec5, vec5); - tmp2 = __msa_hadd_u_w(vec6, vec6); - tmp3 = __msa_hadd_u_w(vec7, vec7); - tmp4 = __msa_hadd_u_w(vec0, vec0); - vec0 = (v8u16)__msa_pckev_h((v8i16)tmp1, (v8i16)tmp0); - vec1 = (v8u16)__msa_pckev_h((v8i16)tmp3, (v8i16)tmp2); - tmp0 = __msa_hadd_u_w(vec0, vec0); - tmp1 = __msa_hadd_u_w(vec1, vec1); - tmp0 *= const_0x2AAA; - tmp1 *= const_0x2AAA; - tmp4 *= const_0x4000; - tmp0 = (v4u32)__msa_srai_w((v4i32)tmp0, 16); - tmp1 = (v4u32)__msa_srai_w((v4i32)tmp1, 16); - tmp4 = (v4u32)__msa_srai_w((v4i32)tmp4, 16); - vec0 = (v8u16)__msa_pckev_h((v8i16)tmp1, (v8i16)tmp0); - vec1 = (v8u16)__msa_pckev_h((v8i16)tmp4, (v8i16)tmp4); - out = (v16u8)__msa_vshf_b(dst_mask, (v16i8)vec1, (v16i8)vec0); - dst0 = __msa_copy_u_d((v2i64)out, 0); - dst1 = __msa_copy_u_w((v4i32)out, 2); - SD(dst0, dst_ptr); - SW(dst1, dst_ptr + 8); - s += 32; - t += 32; - dst_ptr += 12; - } -} - -void ScaleRowDown38_3_Box_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - int x, width; - const uint8_t* s = src_ptr; - const uint8_t* t0 = s + src_stride; - const uint8_t* t1 = s + src_stride * 2; - uint64_t dst0; - uint32_t dst1; - v16u8 src0, src1, src2, src3, src4, src5, out; - v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v4u32 tmp0, tmp1, tmp2, tmp3, tmp4; - v8u16 zero = {0}; - v8i16 mask = {0, 1, 2, 8, 3, 4, 5, 9}; - v16i8 dst_mask = {0, 2, 16, 4, 6, 18, 8, 10, 20, 12, 14, 22, 0, 0, 0, 0}; - v4u32 const_0x1C71 = (v4u32)__msa_fill_w(0x1C71); - v4u32 const_0x2AAA = (v4u32)__msa_fill_w(0x2AAA); - - assert((dst_width % 3 == 0) && (dst_width > 0)); - width = dst_width / 3; - - for (x = 0; x < width; x += 4) { - src0 = (v16u8)__msa_ld_b((v16i8*)s, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)s, 16); - src2 = (v16u8)__msa_ld_b((v16i8*)t0, 0); - src3 = (v16u8)__msa_ld_b((v16i8*)t0, 16); - src4 = (v16u8)__msa_ld_b((v16i8*)t1, 0); - src5 = (v16u8)__msa_ld_b((v16i8*)t1, 16); - vec0 = (v8u16)__msa_ilvr_b((v16i8)src2, (v16i8)src0); - vec1 = (v8u16)__msa_ilvl_b((v16i8)src2, (v16i8)src0); - vec2 = (v8u16)__msa_ilvr_b((v16i8)src3, (v16i8)src1); - vec3 = (v8u16)__msa_ilvl_b((v16i8)src3, (v16i8)src1); - vec4 = (v8u16)__msa_ilvr_b((v16i8)zero, (v16i8)src4); - vec5 = (v8u16)__msa_ilvl_b((v16i8)zero, (v16i8)src4); - vec6 = (v8u16)__msa_ilvr_b((v16i8)zero, (v16i8)src5); - vec7 = (v8u16)__msa_ilvl_b((v16i8)zero, (v16i8)src5); - vec0 = __msa_hadd_u_h((v16u8)vec0, (v16u8)vec0); - vec1 = __msa_hadd_u_h((v16u8)vec1, (v16u8)vec1); - vec2 = __msa_hadd_u_h((v16u8)vec2, (v16u8)vec2); - vec3 = __msa_hadd_u_h((v16u8)vec3, (v16u8)vec3); - vec0 += __msa_hadd_u_h((v16u8)vec4, (v16u8)vec4); - vec1 += __msa_hadd_u_h((v16u8)vec5, (v16u8)vec5); - vec2 += __msa_hadd_u_h((v16u8)vec6, (v16u8)vec6); - vec3 += __msa_hadd_u_h((v16u8)vec7, (v16u8)vec7); - vec4 = (v8u16)__msa_vshf_h(mask, (v8i16)zero, (v8i16)vec0); - vec5 = (v8u16)__msa_vshf_h(mask, (v8i16)zero, (v8i16)vec1); - vec6 = (v8u16)__msa_vshf_h(mask, (v8i16)zero, (v8i16)vec2); - vec7 = (v8u16)__msa_vshf_h(mask, (v8i16)zero, (v8i16)vec3); - vec0 = (v8u16)__msa_pckod_w((v4i32)vec1, (v4i32)vec0); - vec1 = (v8u16)__msa_pckod_w((v4i32)vec3, (v4i32)vec2); - vec0 = (v8u16)__msa_pckod_w((v4i32)vec1, (v4i32)vec0); - tmp0 = __msa_hadd_u_w(vec4, vec4); - tmp1 = __msa_hadd_u_w(vec5, vec5); - tmp2 = __msa_hadd_u_w(vec6, vec6); - tmp3 = __msa_hadd_u_w(vec7, vec7); - tmp4 = __msa_hadd_u_w(vec0, vec0); - vec0 = (v8u16)__msa_pckev_h((v8i16)tmp1, (v8i16)tmp0); - vec1 = (v8u16)__msa_pckev_h((v8i16)tmp3, (v8i16)tmp2); - tmp0 = __msa_hadd_u_w(vec0, vec0); - tmp1 = __msa_hadd_u_w(vec1, vec1); - tmp0 *= const_0x1C71; - tmp1 *= const_0x1C71; - tmp4 *= const_0x2AAA; - tmp0 = (v4u32)__msa_srai_w((v4i32)tmp0, 16); - tmp1 = (v4u32)__msa_srai_w((v4i32)tmp1, 16); - tmp4 = (v4u32)__msa_srai_w((v4i32)tmp4, 16); - vec0 = (v8u16)__msa_pckev_h((v8i16)tmp1, (v8i16)tmp0); - vec1 = (v8u16)__msa_pckev_h((v8i16)tmp4, (v8i16)tmp4); - out = (v16u8)__msa_vshf_b(dst_mask, (v16i8)vec1, (v16i8)vec0); - dst0 = __msa_copy_u_d((v2i64)out, 0); - dst1 = __msa_copy_u_w((v4i32)out, 2); - SD(dst0, dst_ptr); - SW(dst1, dst_ptr + 8); - s += 32; - t0 += 32; - t1 += 32; - dst_ptr += 12; - } -} - -void ScaleAddRow_MSA(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width) { - int x; - v16u8 src0; - v8u16 dst0, dst1; - v16i8 zero = {0}; - - assert(src_width > 0); - - for (x = 0; x < src_width; x += 16) { - src0 = LD_UB(src_ptr); - dst0 = (v8u16)__msa_ld_h((v8i16*)dst_ptr, 0); - dst1 = (v8u16)__msa_ld_h((v8i16*)dst_ptr, 16); - dst0 += (v8u16)__msa_ilvr_b(zero, (v16i8)src0); - dst1 += (v8u16)__msa_ilvl_b(zero, (v16i8)src0); - ST_UH2(dst0, dst1, dst_ptr, 8); - src_ptr += 16; - dst_ptr += 16; - } -} - -void ScaleFilterCols_MSA(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx) { - int j; - v4i32 vec_x = __msa_fill_w(x); - v4i32 vec_dx = __msa_fill_w(dx); - v4i32 vec_const = {0, 1, 2, 3}; - v4i32 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9; - v4i32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - v8u16 reg0, reg1; - v16u8 dst0; - v4i32 const_0xFFFF = __msa_fill_w(0xFFFF); - v4i32 const_0x40 = __msa_fill_w(0x40); - - vec0 = vec_dx * vec_const; - vec1 = vec_dx * 4; - vec_x += vec0; - - for (j = 0; j < dst_width - 1; j += 16) { - vec2 = vec_x >> 16; - vec6 = vec_x & const_0xFFFF; - vec_x += vec1; - vec3 = vec_x >> 16; - vec7 = vec_x & const_0xFFFF; - vec_x += vec1; - vec4 = vec_x >> 16; - vec8 = vec_x & const_0xFFFF; - vec_x += vec1; - vec5 = vec_x >> 16; - vec9 = vec_x & const_0xFFFF; - vec_x += vec1; - vec6 >>= 9; - vec7 >>= 9; - vec8 >>= 9; - vec9 >>= 9; - LOAD_INDEXED_DATA(src_ptr, vec2, tmp0); - LOAD_INDEXED_DATA(src_ptr, vec3, tmp1); - LOAD_INDEXED_DATA(src_ptr, vec4, tmp2); - LOAD_INDEXED_DATA(src_ptr, vec5, tmp3); - vec2 += 1; - vec3 += 1; - vec4 += 1; - vec5 += 1; - LOAD_INDEXED_DATA(src_ptr, vec2, tmp4); - LOAD_INDEXED_DATA(src_ptr, vec3, tmp5); - LOAD_INDEXED_DATA(src_ptr, vec4, tmp6); - LOAD_INDEXED_DATA(src_ptr, vec5, tmp7); - tmp4 -= tmp0; - tmp5 -= tmp1; - tmp6 -= tmp2; - tmp7 -= tmp3; - tmp4 *= vec6; - tmp5 *= vec7; - tmp6 *= vec8; - tmp7 *= vec9; - tmp4 += const_0x40; - tmp5 += const_0x40; - tmp6 += const_0x40; - tmp7 += const_0x40; - tmp4 >>= 7; - tmp5 >>= 7; - tmp6 >>= 7; - tmp7 >>= 7; - tmp0 += tmp4; - tmp1 += tmp5; - tmp2 += tmp6; - tmp3 += tmp7; - reg0 = (v8u16)__msa_pckev_h((v8i16)tmp1, (v8i16)tmp0); - reg1 = (v8u16)__msa_pckev_h((v8i16)tmp3, (v8i16)tmp2); - dst0 = (v16u8)__msa_pckev_b((v16i8)reg1, (v16i8)reg0); - __msa_st_b(dst0, dst_ptr, 0); - dst_ptr += 16; - } -} - -void ScaleARGBCols_MSA(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx) { - const uint32_t* src = (const uint32_t*)(src_argb); - uint32_t* dst = (uint32_t*)(dst_argb); - int j; - v4i32 x_vec = __msa_fill_w(x); - v4i32 dx_vec = __msa_fill_w(dx); - v4i32 const_vec = {0, 1, 2, 3}; - v4i32 vec0, vec1, vec2; - v4i32 dst0; - - vec0 = dx_vec * const_vec; - vec1 = dx_vec * 4; - x_vec += vec0; - - for (j = 0; j < dst_width; j += 4) { - vec2 = x_vec >> 16; - x_vec += vec1; - LOAD_INDEXED_DATA(src, vec2, dst0); - __msa_st_w(dst0, dst, 0); - dst += 4; - } -} - -void ScaleARGBFilterCols_MSA(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx) { - const uint32_t* src = (const uint32_t*)(src_argb); - int j; - v4u32 src0, src1, src2, src3; - v4u32 vec0, vec1, vec2, vec3; - v16u8 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; - v16u8 mult0, mult1, mult2, mult3; - v8u16 tmp0, tmp1, tmp2, tmp3; - v16u8 dst0, dst1; - v4u32 vec_x = (v4u32)__msa_fill_w(x); - v4u32 vec_dx = (v4u32)__msa_fill_w(dx); - v4u32 vec_const = {0, 1, 2, 3}; - v16u8 const_0x7f = (v16u8)__msa_fill_b(0x7f); - - vec0 = vec_dx * vec_const; - vec1 = vec_dx * 4; - vec_x += vec0; - - for (j = 0; j < dst_width - 1; j += 8) { - vec2 = vec_x >> 16; - reg0 = (v16u8)(vec_x >> 9); - vec_x += vec1; - vec3 = vec_x >> 16; - reg1 = (v16u8)(vec_x >> 9); - vec_x += vec1; - reg0 = reg0 & const_0x7f; - reg1 = reg1 & const_0x7f; - reg0 = (v16u8)__msa_shf_b((v16i8)reg0, 0); - reg1 = (v16u8)__msa_shf_b((v16i8)reg1, 0); - reg2 = reg0 ^ const_0x7f; - reg3 = reg1 ^ const_0x7f; - mult0 = (v16u8)__msa_ilvr_b((v16i8)reg0, (v16i8)reg2); - mult1 = (v16u8)__msa_ilvl_b((v16i8)reg0, (v16i8)reg2); - mult2 = (v16u8)__msa_ilvr_b((v16i8)reg1, (v16i8)reg3); - mult3 = (v16u8)__msa_ilvl_b((v16i8)reg1, (v16i8)reg3); - LOAD_INDEXED_DATA(src, vec2, src0); - LOAD_INDEXED_DATA(src, vec3, src1); - vec2 += 1; - vec3 += 1; - LOAD_INDEXED_DATA(src, vec2, src2); - LOAD_INDEXED_DATA(src, vec3, src3); - reg4 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src0); - reg5 = (v16u8)__msa_ilvl_b((v16i8)src2, (v16i8)src0); - reg6 = (v16u8)__msa_ilvr_b((v16i8)src3, (v16i8)src1); - reg7 = (v16u8)__msa_ilvl_b((v16i8)src3, (v16i8)src1); - tmp0 = __msa_dotp_u_h(reg4, mult0); - tmp1 = __msa_dotp_u_h(reg5, mult1); - tmp2 = __msa_dotp_u_h(reg6, mult2); - tmp3 = __msa_dotp_u_h(reg7, mult3); - tmp0 >>= 7; - tmp1 >>= 7; - tmp2 >>= 7; - tmp3 >>= 7; - dst0 = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - dst1 = (v16u8)__msa_pckev_b((v16i8)tmp3, (v16i8)tmp2); - __msa_st_b(dst0, dst_argb, 0); - __msa_st_b(dst1, dst_argb, 16); - dst_argb += 32; - } -} - -void ScaleRowDown34_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - int x; - (void)src_stride; - v16u8 src0, src1, src2, src3; - v16u8 vec0, vec1, vec2; - v16i8 mask0 = {0, 1, 3, 4, 5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19, 20}; - v16i8 mask1 = {5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19, 20, 21, 23, 24, 25}; - v16i8 mask2 = {11, 12, 13, 15, 16, 17, 19, 20, - 21, 23, 24, 25, 27, 28, 29, 31}; - - assert((dst_width % 3 == 0) && (dst_width > 0)); - - for (x = 0; x < dst_width; x += 48) { - src0 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 16); - src2 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 32); - src3 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 48); - vec0 = (v16u8)__msa_vshf_b(mask0, (v16i8)src1, (v16i8)src0); - vec1 = (v16u8)__msa_vshf_b(mask1, (v16i8)src2, (v16i8)src1); - vec2 = (v16u8)__msa_vshf_b(mask2, (v16i8)src3, (v16i8)src2); - __msa_st_b((v16i8)vec0, dst, 0); - __msa_st_b((v16i8)vec1, dst, 16); - __msa_st_b((v16i8)vec2, dst, 32); - src_ptr += 64; - dst += 48; - } -} - -void ScaleRowDown34_0_Box_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* d, - int dst_width) { - const uint8_t* s = src_ptr; - const uint8_t* t = src_ptr + src_stride; - int x; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7, dst0, dst1, dst2; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5; - v16u8 vec6, vec7, vec8, vec9, vec10, vec11; - v8i16 reg0, reg1, reg2, reg3, reg4, reg5; - v8i16 reg6, reg7, reg8, reg9, reg10, reg11; - v16u8 const0 = {3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1}; - v16u8 const1 = {1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1}; - v16u8 const2 = {1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3}; - v16i8 mask0 = {0, 1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10}; - v16i8 mask1 = {10, 11, 12, 13, 13, 14, 14, 15, - 16, 17, 17, 18, 18, 19, 20, 21}; - v16i8 mask2 = {5, 6, 6, 7, 8, 9, 9, 10, 10, 11, 12, 13, 13, 14, 14, 15}; - v8i16 shft0 = {2, 1, 2, 2, 1, 2, 2, 1}; - v8i16 shft1 = {2, 2, 1, 2, 2, 1, 2, 2}; - v8i16 shft2 = {1, 2, 2, 1, 2, 2, 1, 2}; - - assert((dst_width % 3 == 0) && (dst_width > 0)); - - for (x = 0; x < dst_width; x += 48) { - src0 = (v16u8)__msa_ld_b((v16i8*)s, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)s, 16); - src2 = (v16u8)__msa_ld_b((v16i8*)s, 32); - src3 = (v16u8)__msa_ld_b((v16i8*)s, 48); - src4 = (v16u8)__msa_ld_b((v16i8*)t, 0); - src5 = (v16u8)__msa_ld_b((v16i8*)t, 16); - src6 = (v16u8)__msa_ld_b((v16i8*)t, 32); - src7 = (v16u8)__msa_ld_b((v16i8*)t, 48); - vec0 = (v16u8)__msa_vshf_b(mask0, (v16i8)src0, (v16i8)src0); - vec1 = (v16u8)__msa_vshf_b(mask1, (v16i8)src1, (v16i8)src0); - vec2 = (v16u8)__msa_vshf_b(mask2, (v16i8)src1, (v16i8)src1); - vec3 = (v16u8)__msa_vshf_b(mask0, (v16i8)src2, (v16i8)src2); - vec4 = (v16u8)__msa_vshf_b(mask1, (v16i8)src3, (v16i8)src2); - vec5 = (v16u8)__msa_vshf_b(mask2, (v16i8)src3, (v16i8)src3); - vec6 = (v16u8)__msa_vshf_b(mask0, (v16i8)src4, (v16i8)src4); - vec7 = (v16u8)__msa_vshf_b(mask1, (v16i8)src5, (v16i8)src4); - vec8 = (v16u8)__msa_vshf_b(mask2, (v16i8)src5, (v16i8)src5); - vec9 = (v16u8)__msa_vshf_b(mask0, (v16i8)src6, (v16i8)src6); - vec10 = (v16u8)__msa_vshf_b(mask1, (v16i8)src7, (v16i8)src6); - vec11 = (v16u8)__msa_vshf_b(mask2, (v16i8)src7, (v16i8)src7); - reg0 = (v8i16)__msa_dotp_u_h(vec0, const0); - reg1 = (v8i16)__msa_dotp_u_h(vec1, const1); - reg2 = (v8i16)__msa_dotp_u_h(vec2, const2); - reg3 = (v8i16)__msa_dotp_u_h(vec3, const0); - reg4 = (v8i16)__msa_dotp_u_h(vec4, const1); - reg5 = (v8i16)__msa_dotp_u_h(vec5, const2); - reg6 = (v8i16)__msa_dotp_u_h(vec6, const0); - reg7 = (v8i16)__msa_dotp_u_h(vec7, const1); - reg8 = (v8i16)__msa_dotp_u_h(vec8, const2); - reg9 = (v8i16)__msa_dotp_u_h(vec9, const0); - reg10 = (v8i16)__msa_dotp_u_h(vec10, const1); - reg11 = (v8i16)__msa_dotp_u_h(vec11, const2); - reg0 = __msa_srar_h(reg0, shft0); - reg1 = __msa_srar_h(reg1, shft1); - reg2 = __msa_srar_h(reg2, shft2); - reg3 = __msa_srar_h(reg3, shft0); - reg4 = __msa_srar_h(reg4, shft1); - reg5 = __msa_srar_h(reg5, shft2); - reg6 = __msa_srar_h(reg6, shft0); - reg7 = __msa_srar_h(reg7, shft1); - reg8 = __msa_srar_h(reg8, shft2); - reg9 = __msa_srar_h(reg9, shft0); - reg10 = __msa_srar_h(reg10, shft1); - reg11 = __msa_srar_h(reg11, shft2); - reg0 = reg0 * 3 + reg6; - reg1 = reg1 * 3 + reg7; - reg2 = reg2 * 3 + reg8; - reg3 = reg3 * 3 + reg9; - reg4 = reg4 * 3 + reg10; - reg5 = reg5 * 3 + reg11; - reg0 = __msa_srari_h(reg0, 2); - reg1 = __msa_srari_h(reg1, 2); - reg2 = __msa_srari_h(reg2, 2); - reg3 = __msa_srari_h(reg3, 2); - reg4 = __msa_srari_h(reg4, 2); - reg5 = __msa_srari_h(reg5, 2); - dst0 = (v16u8)__msa_pckev_b((v16i8)reg1, (v16i8)reg0); - dst1 = (v16u8)__msa_pckev_b((v16i8)reg3, (v16i8)reg2); - dst2 = (v16u8)__msa_pckev_b((v16i8)reg5, (v16i8)reg4); - __msa_st_b((v16i8)dst0, d, 0); - __msa_st_b((v16i8)dst1, d, 16); - __msa_st_b((v16i8)dst2, d, 32); - s += 64; - t += 64; - d += 48; - } -} - -void ScaleRowDown34_1_Box_MSA(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* d, - int dst_width) { - const uint8_t* s = src_ptr; - const uint8_t* t = src_ptr + src_stride; - int x; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7, dst0, dst1, dst2; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5; - v16u8 vec6, vec7, vec8, vec9, vec10, vec11; - v8i16 reg0, reg1, reg2, reg3, reg4, reg5; - v8i16 reg6, reg7, reg8, reg9, reg10, reg11; - v16u8 const0 = {3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1}; - v16u8 const1 = {1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1}; - v16u8 const2 = {1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3}; - v16i8 mask0 = {0, 1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10}; - v16i8 mask1 = {10, 11, 12, 13, 13, 14, 14, 15, - 16, 17, 17, 18, 18, 19, 20, 21}; - v16i8 mask2 = {5, 6, 6, 7, 8, 9, 9, 10, 10, 11, 12, 13, 13, 14, 14, 15}; - v8i16 shft0 = {2, 1, 2, 2, 1, 2, 2, 1}; - v8i16 shft1 = {2, 2, 1, 2, 2, 1, 2, 2}; - v8i16 shft2 = {1, 2, 2, 1, 2, 2, 1, 2}; - - assert((dst_width % 3 == 0) && (dst_width > 0)); - - for (x = 0; x < dst_width; x += 48) { - src0 = (v16u8)__msa_ld_b((v16i8*)s, 0); - src1 = (v16u8)__msa_ld_b((v16i8*)s, 16); - src2 = (v16u8)__msa_ld_b((v16i8*)s, 32); - src3 = (v16u8)__msa_ld_b((v16i8*)s, 48); - src4 = (v16u8)__msa_ld_b((v16i8*)t, 0); - src5 = (v16u8)__msa_ld_b((v16i8*)t, 16); - src6 = (v16u8)__msa_ld_b((v16i8*)t, 32); - src7 = (v16u8)__msa_ld_b((v16i8*)t, 48); - vec0 = (v16u8)__msa_vshf_b(mask0, (v16i8)src0, (v16i8)src0); - vec1 = (v16u8)__msa_vshf_b(mask1, (v16i8)src1, (v16i8)src0); - vec2 = (v16u8)__msa_vshf_b(mask2, (v16i8)src1, (v16i8)src1); - vec3 = (v16u8)__msa_vshf_b(mask0, (v16i8)src2, (v16i8)src2); - vec4 = (v16u8)__msa_vshf_b(mask1, (v16i8)src3, (v16i8)src2); - vec5 = (v16u8)__msa_vshf_b(mask2, (v16i8)src3, (v16i8)src3); - vec6 = (v16u8)__msa_vshf_b(mask0, (v16i8)src4, (v16i8)src4); - vec7 = (v16u8)__msa_vshf_b(mask1, (v16i8)src5, (v16i8)src4); - vec8 = (v16u8)__msa_vshf_b(mask2, (v16i8)src5, (v16i8)src5); - vec9 = (v16u8)__msa_vshf_b(mask0, (v16i8)src6, (v16i8)src6); - vec10 = (v16u8)__msa_vshf_b(mask1, (v16i8)src7, (v16i8)src6); - vec11 = (v16u8)__msa_vshf_b(mask2, (v16i8)src7, (v16i8)src7); - reg0 = (v8i16)__msa_dotp_u_h(vec0, const0); - reg1 = (v8i16)__msa_dotp_u_h(vec1, const1); - reg2 = (v8i16)__msa_dotp_u_h(vec2, const2); - reg3 = (v8i16)__msa_dotp_u_h(vec3, const0); - reg4 = (v8i16)__msa_dotp_u_h(vec4, const1); - reg5 = (v8i16)__msa_dotp_u_h(vec5, const2); - reg6 = (v8i16)__msa_dotp_u_h(vec6, const0); - reg7 = (v8i16)__msa_dotp_u_h(vec7, const1); - reg8 = (v8i16)__msa_dotp_u_h(vec8, const2); - reg9 = (v8i16)__msa_dotp_u_h(vec9, const0); - reg10 = (v8i16)__msa_dotp_u_h(vec10, const1); - reg11 = (v8i16)__msa_dotp_u_h(vec11, const2); - reg0 = __msa_srar_h(reg0, shft0); - reg1 = __msa_srar_h(reg1, shft1); - reg2 = __msa_srar_h(reg2, shft2); - reg3 = __msa_srar_h(reg3, shft0); - reg4 = __msa_srar_h(reg4, shft1); - reg5 = __msa_srar_h(reg5, shft2); - reg6 = __msa_srar_h(reg6, shft0); - reg7 = __msa_srar_h(reg7, shft1); - reg8 = __msa_srar_h(reg8, shft2); - reg9 = __msa_srar_h(reg9, shft0); - reg10 = __msa_srar_h(reg10, shft1); - reg11 = __msa_srar_h(reg11, shft2); - reg0 += reg6; - reg1 += reg7; - reg2 += reg8; - reg3 += reg9; - reg4 += reg10; - reg5 += reg11; - reg0 = __msa_srari_h(reg0, 1); - reg1 = __msa_srari_h(reg1, 1); - reg2 = __msa_srari_h(reg2, 1); - reg3 = __msa_srari_h(reg3, 1); - reg4 = __msa_srari_h(reg4, 1); - reg5 = __msa_srari_h(reg5, 1); - dst0 = (v16u8)__msa_pckev_b((v16i8)reg1, (v16i8)reg0); - dst1 = (v16u8)__msa_pckev_b((v16i8)reg3, (v16i8)reg2); - dst2 = (v16u8)__msa_pckev_b((v16i8)reg5, (v16i8)reg4); - __msa_st_b((v16i8)dst0, d, 0); - __msa_st_b((v16i8)dst1, d, 16); - __msa_st_b((v16i8)dst2, d, 32); - s += 64; - t += 64; - d += 48; - } -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif - -#endif // !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_neon.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_neon.cc deleted file mode 100644 index 459a2995..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_neon.cc +++ /dev/null @@ -1,970 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// This module is for GCC Neon. -#if !defined(LIBYUV_DISABLE_NEON) && defined(__ARM_NEON__) && \ - !defined(__aarch64__) - -// NEON downscalers with interpolation. -// Provided by Fritz Koenig - -// Read 32x1 throw away even pixels, and write 16x1. -void ScaleRowDown2_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - (void)src_stride; - asm volatile( - "1: \n" - // load even pixels into q0, odd into q1 - "vld2.8 {q0, q1}, [%0]! \n" - "subs %2, %2, #16 \n" // 16 processed per loop - "vst1.8 {q1}, [%1]! \n" // store odd pixels - "bgt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst), // %1 - "+r"(dst_width) // %2 - : - : "q0", "q1" // Clobber List - ); -} - -// Read 32x1 average down and write 16x1. -void ScaleRowDown2Linear_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - (void)src_stride; - asm volatile( - "1: \n" - "vld2.8 {q0, q1}, [%0]! \n" // load 32 pixels - "subs %2, %2, #16 \n" // 16 processed per loop - "vrhadd.u8 q0, q0, q1 \n" // rounding half add - "vst1.8 {q0}, [%1]! \n" - "bgt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst), // %1 - "+r"(dst_width) // %2 - : - : "q0", "q1" // Clobber List - ); -} - -// Read 32x2 average down and write 16x1. -void ScaleRowDown2Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - asm volatile( - // change the stride to row 2 pointer - "add %1, %0 \n" - "1: \n" - "vld1.8 {q0, q1}, [%0]! \n" // load row 1 and post inc - "vld1.8 {q2, q3}, [%1]! \n" // load row 2 and post inc - "subs %3, %3, #16 \n" // 16 processed per loop - "vpaddl.u8 q0, q0 \n" // row 1 add adjacent - "vpaddl.u8 q1, q1 \n" - "vpadal.u8 q0, q2 \n" // row 2 add adjacent + - // row1 - "vpadal.u8 q1, q3 \n" - "vrshrn.u16 d0, q0, #2 \n" // downshift, round and - // pack - "vrshrn.u16 d1, q1, #2 \n" - "vst1.8 {q0}, [%2]! \n" - "bgt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(src_stride), // %1 - "+r"(dst), // %2 - "+r"(dst_width) // %3 - : - : "q0", "q1", "q2", "q3" // Clobber List - ); -} - -void ScaleRowDown4_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - (void)src_stride; - asm volatile( - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // src line 0 - "subs %2, %2, #8 \n" // 8 processed per loop - "vst1.8 {d2}, [%1]! \n" - "bgt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - : - : "q0", "q1", "memory", "cc"); -} - -void ScaleRowDown4Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - const uint8_t* src_ptr1 = src_ptr + src_stride; - const uint8_t* src_ptr2 = src_ptr + src_stride * 2; - const uint8_t* src_ptr3 = src_ptr + src_stride * 3; - asm volatile( - "1: \n" - "vld1.8 {q0}, [%0]! \n" // load up 16x4 - "vld1.8 {q1}, [%3]! \n" - "vld1.8 {q2}, [%4]! \n" - "vld1.8 {q3}, [%5]! \n" - "subs %2, %2, #4 \n" - "vpaddl.u8 q0, q0 \n" - "vpadal.u8 q0, q1 \n" - "vpadal.u8 q0, q2 \n" - "vpadal.u8 q0, q3 \n" - "vpaddl.u16 q0, q0 \n" - "vrshrn.u32 d0, q0, #4 \n" // divide by 16 w/rounding - "vmovn.u16 d0, q0 \n" - "vst1.32 {d0[0]}, [%1]! \n" - "bgt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width), // %2 - "+r"(src_ptr1), // %3 - "+r"(src_ptr2), // %4 - "+r"(src_ptr3) // %5 - : - : "q0", "q1", "q2", "q3", "memory", "cc"); -} - -// Down scale from 4 to 3 pixels. Use the neon multilane read/write -// to load up the every 4th pixel into a 4 different registers. -// Point samples 32 pixels to 24 pixels. -void ScaleRowDown34_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - (void)src_stride; - asm volatile( - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // src line 0 - "subs %2, %2, #24 \n" - "vmov d2, d3 \n" // order d0, d1, d2 - "vst3.8 {d0, d1, d2}, [%1]! \n" - "bgt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - : - : "d0", "d1", "d2", "d3", "memory", "cc"); -} - -void ScaleRowDown34_0_Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - asm volatile( - "vmov.u8 d24, #3 \n" - "add %3, %0 \n" - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // src line 0 - "vld4.8 {d4, d5, d6, d7}, [%3]! \n" // src line 1 - "subs %2, %2, #24 \n" - - // filter src line 0 with src line 1 - // expand chars to shorts to allow for room - // when adding lines together - "vmovl.u8 q8, d4 \n" - "vmovl.u8 q9, d5 \n" - "vmovl.u8 q10, d6 \n" - "vmovl.u8 q11, d7 \n" - - // 3 * line_0 + line_1 - "vmlal.u8 q8, d0, d24 \n" - "vmlal.u8 q9, d1, d24 \n" - "vmlal.u8 q10, d2, d24 \n" - "vmlal.u8 q11, d3, d24 \n" - - // (3 * line_0 + line_1) >> 2 - "vqrshrn.u16 d0, q8, #2 \n" - "vqrshrn.u16 d1, q9, #2 \n" - "vqrshrn.u16 d2, q10, #2 \n" - "vqrshrn.u16 d3, q11, #2 \n" - - // a0 = (src[0] * 3 + s[1] * 1) >> 2 - "vmovl.u8 q8, d1 \n" - "vmlal.u8 q8, d0, d24 \n" - "vqrshrn.u16 d0, q8, #2 \n" - - // a1 = (src[1] * 1 + s[2] * 1) >> 1 - "vrhadd.u8 d1, d1, d2 \n" - - // a2 = (src[2] * 1 + s[3] * 3) >> 2 - "vmovl.u8 q8, d2 \n" - "vmlal.u8 q8, d3, d24 \n" - "vqrshrn.u16 d2, q8, #2 \n" - - "vst3.8 {d0, d1, d2}, [%1]! \n" - - "bgt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width), // %2 - "+r"(src_stride) // %3 - : - : "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11", "d24", "memory", - "cc"); -} - -void ScaleRowDown34_1_Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - asm volatile( - "vmov.u8 d24, #3 \n" - "add %3, %0 \n" - "1: \n" - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" // src line 0 - "vld4.8 {d4, d5, d6, d7}, [%3]! \n" // src line 1 - "subs %2, %2, #24 \n" - // average src line 0 with src line 1 - "vrhadd.u8 q0, q0, q2 \n" - "vrhadd.u8 q1, q1, q3 \n" - - // a0 = (src[0] * 3 + s[1] * 1) >> 2 - "vmovl.u8 q3, d1 \n" - "vmlal.u8 q3, d0, d24 \n" - "vqrshrn.u16 d0, q3, #2 \n" - - // a1 = (src[1] * 1 + s[2] * 1) >> 1 - "vrhadd.u8 d1, d1, d2 \n" - - // a2 = (src[2] * 1 + s[3] * 3) >> 2 - "vmovl.u8 q3, d2 \n" - "vmlal.u8 q3, d3, d24 \n" - "vqrshrn.u16 d2, q3, #2 \n" - - "vst3.8 {d0, d1, d2}, [%1]! \n" - "bgt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width), // %2 - "+r"(src_stride) // %3 - : - : "r4", "q0", "q1", "q2", "q3", "d24", "memory", "cc"); -} - -#define HAS_SCALEROWDOWN38_NEON -static const uvec8 kShuf38 = {0, 3, 6, 8, 11, 14, 16, 19, - 22, 24, 27, 30, 0, 0, 0, 0}; -static const uvec8 kShuf38_2 = {0, 8, 16, 2, 10, 17, 4, 12, - 18, 6, 14, 19, 0, 0, 0, 0}; -static const vec16 kMult38_Div6 = {65536 / 12, 65536 / 12, 65536 / 12, - 65536 / 12, 65536 / 12, 65536 / 12, - 65536 / 12, 65536 / 12}; -static const vec16 kMult38_Div9 = {65536 / 18, 65536 / 18, 65536 / 18, - 65536 / 18, 65536 / 18, 65536 / 18, - 65536 / 18, 65536 / 18}; - -// 32 -> 12 -void ScaleRowDown38_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - (void)src_stride; - asm volatile( - "vld1.8 {q3}, [%3] \n" - "1: \n" - "vld1.8 {d0, d1, d2, d3}, [%0]! \n" - "subs %2, %2, #12 \n" - "vtbl.u8 d4, {d0, d1, d2, d3}, d6 \n" - "vtbl.u8 d5, {d0, d1, d2, d3}, d7 \n" - "vst1.8 {d4}, [%1]! \n" - "vst1.32 {d5[0]}, [%1]! \n" - "bgt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - : "r"(&kShuf38) // %3 - : "d0", "d1", "d2", "d3", "d4", "d5", "memory", "cc"); -} - -// 32x3 -> 12x1 -void OMITFP ScaleRowDown38_3_Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - const uint8_t* src_ptr1 = src_ptr + src_stride * 2; - - asm volatile( - "vld1.16 {q13}, [%5] \n" - "vld1.8 {q14}, [%6] \n" - "vld1.8 {q15}, [%7] \n" - "add %3, %0 \n" - "1: \n" - - // d0 = 00 40 01 41 02 42 03 43 - // d1 = 10 50 11 51 12 52 13 53 - // d2 = 20 60 21 61 22 62 23 63 - // d3 = 30 70 31 71 32 72 33 73 - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" - "vld4.8 {d4, d5, d6, d7}, [%3]! \n" - "vld4.8 {d16, d17, d18, d19}, [%4]! \n" - "subs %2, %2, #12 \n" - - // Shuffle the input data around to get align the data - // so adjacent data can be added. 0,1 - 2,3 - 4,5 - 6,7 - // d0 = 00 10 01 11 02 12 03 13 - // d1 = 40 50 41 51 42 52 43 53 - "vtrn.u8 d0, d1 \n" - "vtrn.u8 d4, d5 \n" - "vtrn.u8 d16, d17 \n" - - // d2 = 20 30 21 31 22 32 23 33 - // d3 = 60 70 61 71 62 72 63 73 - "vtrn.u8 d2, d3 \n" - "vtrn.u8 d6, d7 \n" - "vtrn.u8 d18, d19 \n" - - // d0 = 00+10 01+11 02+12 03+13 - // d2 = 40+50 41+51 42+52 43+53 - "vpaddl.u8 q0, q0 \n" - "vpaddl.u8 q2, q2 \n" - "vpaddl.u8 q8, q8 \n" - - // d3 = 60+70 61+71 62+72 63+73 - "vpaddl.u8 d3, d3 \n" - "vpaddl.u8 d7, d7 \n" - "vpaddl.u8 d19, d19 \n" - - // combine source lines - "vadd.u16 q0, q2 \n" - "vadd.u16 q0, q8 \n" - "vadd.u16 d4, d3, d7 \n" - "vadd.u16 d4, d19 \n" - - // dst_ptr[3] = (s[6 + st * 0] + s[7 + st * 0] - // + s[6 + st * 1] + s[7 + st * 1] - // + s[6 + st * 2] + s[7 + st * 2]) / 6 - "vqrdmulh.s16 q2, q2, q13 \n" - "vmovn.u16 d4, q2 \n" - - // Shuffle 2,3 reg around so that 2 can be added to the - // 0,1 reg and 3 can be added to the 4,5 reg. This - // requires expanding from u8 to u16 as the 0,1 and 4,5 - // registers are already expanded. Then do transposes - // to get aligned. - // q2 = xx 20 xx 30 xx 21 xx 31 xx 22 xx 32 xx 23 xx 33 - "vmovl.u8 q1, d2 \n" - "vmovl.u8 q3, d6 \n" - "vmovl.u8 q9, d18 \n" - - // combine source lines - "vadd.u16 q1, q3 \n" - "vadd.u16 q1, q9 \n" - - // d4 = xx 20 xx 30 xx 22 xx 32 - // d5 = xx 21 xx 31 xx 23 xx 33 - "vtrn.u32 d2, d3 \n" - - // d4 = xx 20 xx 21 xx 22 xx 23 - // d5 = xx 30 xx 31 xx 32 xx 33 - "vtrn.u16 d2, d3 \n" - - // 0+1+2, 3+4+5 - "vadd.u16 q0, q1 \n" - - // Need to divide, but can't downshift as the the value - // isn't a power of 2. So multiply by 65536 / n - // and take the upper 16 bits. - "vqrdmulh.s16 q0, q0, q15 \n" - - // Align for table lookup, vtbl requires registers to - // be adjacent - "vmov.u8 d2, d4 \n" - - "vtbl.u8 d3, {d0, d1, d2}, d28 \n" - "vtbl.u8 d4, {d0, d1, d2}, d29 \n" - - "vst1.8 {d3}, [%1]! \n" - "vst1.32 {d4[0]}, [%1]! \n" - "bgt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width), // %2 - "+r"(src_stride), // %3 - "+r"(src_ptr1) // %4 - : "r"(&kMult38_Div6), // %5 - "r"(&kShuf38_2), // %6 - "r"(&kMult38_Div9) // %7 - : "q0", "q1", "q2", "q3", "q8", "q9", "q13", "q14", "q15", "memory", - "cc"); -} - -// 32x2 -> 12x1 -void ScaleRowDown38_2_Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - asm volatile( - "vld1.16 {q13}, [%4] \n" - "vld1.8 {q14}, [%5] \n" - "add %3, %0 \n" - "1: \n" - - // d0 = 00 40 01 41 02 42 03 43 - // d1 = 10 50 11 51 12 52 13 53 - // d2 = 20 60 21 61 22 62 23 63 - // d3 = 30 70 31 71 32 72 33 73 - "vld4.8 {d0, d1, d2, d3}, [%0]! \n" - "vld4.8 {d4, d5, d6, d7}, [%3]! \n" - "subs %2, %2, #12 \n" - - // Shuffle the input data around to get align the data - // so adjacent data can be added. 0,1 - 2,3 - 4,5 - 6,7 - // d0 = 00 10 01 11 02 12 03 13 - // d1 = 40 50 41 51 42 52 43 53 - "vtrn.u8 d0, d1 \n" - "vtrn.u8 d4, d5 \n" - - // d2 = 20 30 21 31 22 32 23 33 - // d3 = 60 70 61 71 62 72 63 73 - "vtrn.u8 d2, d3 \n" - "vtrn.u8 d6, d7 \n" - - // d0 = 00+10 01+11 02+12 03+13 - // d2 = 40+50 41+51 42+52 43+53 - "vpaddl.u8 q0, q0 \n" - "vpaddl.u8 q2, q2 \n" - - // d3 = 60+70 61+71 62+72 63+73 - "vpaddl.u8 d3, d3 \n" - "vpaddl.u8 d7, d7 \n" - - // combine source lines - "vadd.u16 q0, q2 \n" - "vadd.u16 d4, d3, d7 \n" - - // dst_ptr[3] = (s[6] + s[7] + s[6+st] + s[7+st]) / 4 - "vqrshrn.u16 d4, q2, #2 \n" - - // Shuffle 2,3 reg around so that 2 can be added to the - // 0,1 reg and 3 can be added to the 4,5 reg. This - // requires expanding from u8 to u16 as the 0,1 and 4,5 - // registers are already expanded. Then do transposes - // to get aligned. - // q2 = xx 20 xx 30 xx 21 xx 31 xx 22 xx 32 xx 23 xx 33 - "vmovl.u8 q1, d2 \n" - "vmovl.u8 q3, d6 \n" - - // combine source lines - "vadd.u16 q1, q3 \n" - - // d4 = xx 20 xx 30 xx 22 xx 32 - // d5 = xx 21 xx 31 xx 23 xx 33 - "vtrn.u32 d2, d3 \n" - - // d4 = xx 20 xx 21 xx 22 xx 23 - // d5 = xx 30 xx 31 xx 32 xx 33 - "vtrn.u16 d2, d3 \n" - - // 0+1+2, 3+4+5 - "vadd.u16 q0, q1 \n" - - // Need to divide, but can't downshift as the the value - // isn't a power of 2. So multiply by 65536 / n - // and take the upper 16 bits. - "vqrdmulh.s16 q0, q0, q13 \n" - - // Align for table lookup, vtbl requires registers to - // be adjacent - "vmov.u8 d2, d4 \n" - - "vtbl.u8 d3, {d0, d1, d2}, d28 \n" - "vtbl.u8 d4, {d0, d1, d2}, d29 \n" - - "vst1.8 {d3}, [%1]! \n" - "vst1.32 {d4[0]}, [%1]! \n" - "bgt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width), // %2 - "+r"(src_stride) // %3 - : "r"(&kMult38_Div6), // %4 - "r"(&kShuf38_2) // %5 - : "q0", "q1", "q2", "q3", "q13", "q14", "memory", "cc"); -} - -void ScaleAddRows_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst_ptr, - int src_width, - int src_height) { - const uint8_t* src_tmp; - asm volatile( - "1: \n" - "mov %0, %1 \n" - "mov r12, %5 \n" - "veor q2, q2, q2 \n" - "veor q3, q3, q3 \n" - "2: \n" - // load 16 pixels into q0 - "vld1.8 {q0}, [%0], %3 \n" - "vaddw.u8 q3, q3, d1 \n" - "vaddw.u8 q2, q2, d0 \n" - "subs r12, r12, #1 \n" - "bgt 2b \n" - "vst1.16 {q2, q3}, [%2]! \n" // store pixels - "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 - : - : "memory", "cc", "r12", "q0", "q1", "q2", "q3" // Clobber List - ); -} - -// TODO(Yang Zhang): Investigate less load instructions for -// the x/dx stepping -#define LOAD2_DATA8_LANE(n) \ - "lsr %5, %3, #16 \n" \ - "add %6, %1, %5 \n" \ - "add %3, %3, %4 \n" \ - "vld2.8 {d6[" #n "], d7[" #n "]}, [%6] \n" - -// The NEON version mimics this formula (from row_common.cc): -// #define BLENDER(a, b, f) (uint8_t)((int)(a) + -// ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16)) - -void ScaleFilterCols_NEON(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx) { - int dx_offset[4] = {0, 1, 2, 3}; - int* tmp = dx_offset; - const uint8_t* src_tmp = src_ptr; - asm volatile ( - "vdup.32 q0, %3 \n" // x - "vdup.32 q1, %4 \n" // dx - "vld1.32 {q2}, [%5] \n" // 0 1 2 3 - "vshl.i32 q3, q1, #2 \n" // 4 * dx - "vmul.s32 q1, q1, q2 \n" - // x , x + 1 * dx, x + 2 * dx, x + 3 * dx - "vadd.s32 q1, q1, q0 \n" - // x + 4 * dx, x + 5 * dx, x + 6 * dx, x + 7 * dx - "vadd.s32 q2, q1, q3 \n" - "vshl.i32 q0, q3, #1 \n" // 8 * dx - "1: \n" - LOAD2_DATA8_LANE(0) - LOAD2_DATA8_LANE(1) - LOAD2_DATA8_LANE(2) - LOAD2_DATA8_LANE(3) - LOAD2_DATA8_LANE(4) - LOAD2_DATA8_LANE(5) - LOAD2_DATA8_LANE(6) - LOAD2_DATA8_LANE(7) - "vmov q10, q1 \n" - "vmov q11, q2 \n" - "vuzp.16 q10, q11 \n" - "vmovl.u8 q8, d6 \n" - "vmovl.u8 q9, d7 \n" - "vsubl.s16 q11, d18, d16 \n" - "vsubl.s16 q12, d19, d17 \n" - "vmovl.u16 q13, d20 \n" - "vmovl.u16 q10, d21 \n" - "vmul.s32 q11, q11, q13 \n" - "vmul.s32 q12, q12, q10 \n" - "vrshrn.s32 d18, q11, #16 \n" - "vrshrn.s32 d19, q12, #16 \n" - "vadd.s16 q8, q8, q9 \n" - "vmovn.s16 d6, q8 \n" - - "vst1.8 {d6}, [%0]! \n" // store pixels - "vadd.s32 q1, q1, q0 \n" - "vadd.s32 q2, q2, q0 \n" - "subs %2, %2, #8 \n" // 8 processed per loop - "bgt 1b \n" - : "+r"(dst_ptr), // %0 - "+r"(src_ptr), // %1 - "+r"(dst_width), // %2 - "+r"(x), // %3 - "+r"(dx), // %4 - "+r"(tmp), // %5 - "+r"(src_tmp) // %6 - : - : "memory", "cc", "q0", "q1", "q2", "q3", - "q8", "q9", "q10", "q11", "q12", "q13" - ); -} - -#undef LOAD2_DATA8_LANE - -// 16x2 -> 16x1 -void ScaleFilterRows_NEON(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride, - int dst_width, - int source_y_fraction) { - asm volatile( - "cmp %4, #0 \n" - "beq 100f \n" - "add %2, %1 \n" - "cmp %4, #64 \n" - "beq 75f \n" - "cmp %4, #128 \n" - "beq 50f \n" - "cmp %4, #192 \n" - "beq 25f \n" - - "vdup.8 d5, %4 \n" - "rsb %4, #256 \n" - "vdup.8 d4, %4 \n" - // General purpose row blend. - "1: \n" - "vld1.8 {q0}, [%1]! \n" - "vld1.8 {q1}, [%2]! \n" - "subs %3, %3, #16 \n" - "vmull.u8 q13, d0, d4 \n" - "vmull.u8 q14, d1, d4 \n" - "vmlal.u8 q13, d2, d5 \n" - "vmlal.u8 q14, d3, d5 \n" - "vrshrn.u16 d0, q13, #8 \n" - "vrshrn.u16 d1, q14, #8 \n" - "vst1.8 {q0}, [%0]! \n" - "bgt 1b \n" - "b 99f \n" - - // Blend 25 / 75. - "25: \n" - "vld1.8 {q0}, [%1]! \n" - "vld1.8 {q1}, [%2]! \n" - "subs %3, %3, #16 \n" - "vrhadd.u8 q0, q1 \n" - "vrhadd.u8 q0, q1 \n" - "vst1.8 {q0}, [%0]! \n" - "bgt 25b \n" - "b 99f \n" - - // Blend 50 / 50. - "50: \n" - "vld1.8 {q0}, [%1]! \n" - "vld1.8 {q1}, [%2]! \n" - "subs %3, %3, #16 \n" - "vrhadd.u8 q0, q1 \n" - "vst1.8 {q0}, [%0]! \n" - "bgt 50b \n" - "b 99f \n" - - // Blend 75 / 25. - "75: \n" - "vld1.8 {q1}, [%1]! \n" - "vld1.8 {q0}, [%2]! \n" - "subs %3, %3, #16 \n" - "vrhadd.u8 q0, q1 \n" - "vrhadd.u8 q0, q1 \n" - "vst1.8 {q0}, [%0]! \n" - "bgt 75b \n" - "b 99f \n" - - // Blend 100 / 0 - Copy row unchanged. - "100: \n" - "vld1.8 {q0}, [%1]! \n" - "subs %3, %3, #16 \n" - "vst1.8 {q0}, [%0]! \n" - "bgt 100b \n" - - "99: \n" - "vst1.8 {d1[7]}, [%0] \n" - : "+r"(dst_ptr), // %0 - "+r"(src_ptr), // %1 - "+r"(src_stride), // %2 - "+r"(dst_width), // %3 - "+r"(source_y_fraction) // %4 - : - : "q0", "q1", "d4", "d5", "q13", "q14", "memory", "cc"); -} - -void ScaleARGBRowDown2_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - (void)src_stride; - asm volatile( - "1: \n" - "vld4.32 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. - "vld4.32 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB - "subs %2, %2, #8 \n" // 8 processed per loop - "vmov q2, q1 \n" // load next 8 ARGB - "vst2.32 {q2, q3}, [%1]! \n" // store odd pixels - "bgt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst), // %1 - "+r"(dst_width) // %2 - : - : "memory", "cc", "q0", "q1", "q2", "q3" // Clobber List - ); -} - -// 46: f964 018d vld4.32 {d16,d18,d20,d22}, [r4]! -// 4a: 3e04 subs r6, #4 -// 4c: f964 118d vld4.32 {d17,d19,d21,d23}, [r4]! -// 50: ef64 21f4 vorr q9, q10, q10 -// 54: f942 038d vst2.32 {d16-d19}, [r2]! -// 58: d1f5 bne.n 46 - -void ScaleARGBRowDown2Linear_NEON(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width) { - (void)src_stride; - asm volatile( - "1: \n" - "vld4.32 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. - "vld4.32 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB - "subs %2, %2, #8 \n" // 8 processed per loop - "vrhadd.u8 q0, q0, q1 \n" // rounding half add - "vrhadd.u8 q1, q2, q3 \n" // rounding half add - "vst2.32 {q0, q1}, [%1]! \n" - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(dst_width) // %2 - : - : "memory", "cc", "q0", "q1", "q2", "q3" // Clobber List - ); -} - -void ScaleARGBRowDown2Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - asm volatile( - // change the stride to row 2 pointer - "add %1, %1, %0 \n" - "1: \n" - "vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels. - "vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB - "subs %3, %3, #8 \n" // 8 processed per loop. - "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. - "vpaddl.u8 q3, q3 \n" // A 16 bytes -> 8 shorts. - "vld4.8 {d16, d18, d20, d22}, [%1]! \n" // load 8 more ARGB - "vld4.8 {d17, d19, d21, d23}, [%1]! \n" // load last 8 ARGB - "vpadal.u8 q0, q8 \n" // B 16 bytes -> 8 shorts. - "vpadal.u8 q1, q9 \n" // G 16 bytes -> 8 shorts. - "vpadal.u8 q2, q10 \n" // R 16 bytes -> 8 shorts. - "vpadal.u8 q3, q11 \n" // A 16 bytes -> 8 shorts. - "vrshrn.u16 d0, q0, #2 \n" // round and pack to bytes - "vrshrn.u16 d1, q1, #2 \n" - "vrshrn.u16 d2, q2, #2 \n" - "vrshrn.u16 d3, q3, #2 \n" - "vst4.8 {d0, d1, d2, d3}, [%2]! \n" - "bgt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(src_stride), // %1 - "+r"(dst), // %2 - "+r"(dst_width) // %3 - : - : "memory", "cc", "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11"); -} - -// Reads 4 pixels at a time. -// Alignment requirement: src_argb 4 byte aligned. -void ScaleARGBRowDownEven_NEON(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width) { - (void)src_stride; - asm volatile( - "mov r12, %3, lsl #2 \n" - "1: \n" - "vld1.32 {d0[0]}, [%0], r12 \n" - "vld1.32 {d0[1]}, [%0], r12 \n" - "vld1.32 {d1[0]}, [%0], r12 \n" - "vld1.32 {d1[1]}, [%0], r12 \n" - "subs %2, %2, #4 \n" // 4 pixels per loop. - "vst1.8 {q0}, [%1]! \n" - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(dst_width) // %2 - : "r"(src_stepx) // %3 - : "memory", "cc", "r12", "q0"); -} - -// Reads 4 pixels at a time. -// Alignment requirement: src_argb 4 byte aligned. -void ScaleARGBRowDownEvenBox_NEON(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width) { - asm volatile( - "mov r12, %4, lsl #2 \n" - "add %1, %1, %0 \n" - "1: \n" - "vld1.8 {d0}, [%0], r12 \n" // 4 2x2 blocks -> 2x1 - "vld1.8 {d1}, [%1], r12 \n" - "vld1.8 {d2}, [%0], r12 \n" - "vld1.8 {d3}, [%1], r12 \n" - "vld1.8 {d4}, [%0], r12 \n" - "vld1.8 {d5}, [%1], r12 \n" - "vld1.8 {d6}, [%0], r12 \n" - "vld1.8 {d7}, [%1], r12 \n" - "vaddl.u8 q0, d0, d1 \n" - "vaddl.u8 q1, d2, d3 \n" - "vaddl.u8 q2, d4, d5 \n" - "vaddl.u8 q3, d6, d7 \n" - "vswp.8 d1, d2 \n" // ab_cd -> ac_bd - "vswp.8 d5, d6 \n" // ef_gh -> eg_fh - "vadd.u16 q0, q0, q1 \n" // (a+b)_(c+d) - "vadd.u16 q2, q2, q3 \n" // (e+f)_(g+h) - "vrshrn.u16 d0, q0, #2 \n" // first 2 pixels. - "vrshrn.u16 d1, q2, #2 \n" // next 2 pixels. - "subs %3, %3, #4 \n" // 4 pixels per loop. - "vst1.8 {q0}, [%2]! \n" - "bgt 1b \n" - : "+r"(src_argb), // %0 - "+r"(src_stride), // %1 - "+r"(dst_argb), // %2 - "+r"(dst_width) // %3 - : "r"(src_stepx) // %4 - : "memory", "cc", "r12", "q0", "q1", "q2", "q3"); -} - -// TODO(Yang Zhang): Investigate less load instructions for -// the x/dx stepping -#define LOAD1_DATA32_LANE(dn, n) \ - "lsr %5, %3, #16 \n" \ - "add %6, %1, %5, lsl #2 \n" \ - "add %3, %3, %4 \n" \ - "vld1.32 {" #dn "[" #n "]}, [%6] \n" - -void ScaleARGBCols_NEON(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx) { - int tmp; - const uint8_t* src_tmp = src_argb; - asm volatile( - "1: \n" - // clang-format off - LOAD1_DATA32_LANE(d0, 0) - LOAD1_DATA32_LANE(d0, 1) - LOAD1_DATA32_LANE(d1, 0) - LOAD1_DATA32_LANE(d1, 1) - LOAD1_DATA32_LANE(d2, 0) - LOAD1_DATA32_LANE(d2, 1) - LOAD1_DATA32_LANE(d3, 0) - LOAD1_DATA32_LANE(d3, 1) - // clang-format on - "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 - : - : "memory", "cc", "q0", "q1"); -} - -#undef LOAD1_DATA32_LANE - -// TODO(Yang Zhang): Investigate less load instructions for -// the x/dx stepping -#define LOAD2_DATA32_LANE(dn1, dn2, n) \ - "lsr %5, %3, #16 \n" \ - "add %6, %1, %5, lsl #2 \n" \ - "add %3, %3, %4 \n" \ - "vld2.32 {" #dn1 "[" #n "], " #dn2 "[" #n "]}, [%6] \n" - -void ScaleARGBFilterCols_NEON(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx) { - int dx_offset[4] = {0, 1, 2, 3}; - int* tmp = dx_offset; - const uint8_t* src_tmp = src_argb; - asm volatile ( - "vdup.32 q0, %3 \n" // x - "vdup.32 q1, %4 \n" // dx - "vld1.32 {q2}, [%5] \n" // 0 1 2 3 - "vshl.i32 q9, q1, #2 \n" // 4 * dx - "vmul.s32 q1, q1, q2 \n" - "vmov.i8 q3, #0x7f \n" // 0x7F - "vmov.i16 q15, #0x7f \n" // 0x7F - // x , x + 1 * dx, x + 2 * dx, x + 3 * dx - "vadd.s32 q8, q1, q0 \n" - "1: \n" - // d0, d1: a - // d2, d3: b - LOAD2_DATA32_LANE(d0, d2, 0) - LOAD2_DATA32_LANE(d0, d2, 1) - LOAD2_DATA32_LANE(d1, d3, 0) - LOAD2_DATA32_LANE(d1, d3, 1) - "vshrn.i32 d22, q8, #9 \n" - "vand.16 d22, d22, d30 \n" - "vdup.8 d24, d22[0] \n" - "vdup.8 d25, d22[2] \n" - "vdup.8 d26, d22[4] \n" - "vdup.8 d27, d22[6] \n" - "vext.8 d4, d24, d25, #4 \n" - "vext.8 d5, d26, d27, #4 \n" // f - "veor.8 q10, q2, q3 \n" // 0x7f ^ f - "vmull.u8 q11, d0, d20 \n" - "vmull.u8 q12, d1, d21 \n" - "vmull.u8 q13, d2, d4 \n" - "vmull.u8 q14, d3, d5 \n" - "vadd.i16 q11, q11, q13 \n" - "vadd.i16 q12, q12, q14 \n" - "vshrn.i16 d0, q11, #7 \n" - "vshrn.i16 d1, q12, #7 \n" - - "vst1.32 {d0, d1}, [%0]! \n" // store pixels - "vadd.s32 q8, q8, q9 \n" - "subs %2, %2, #4 \n" // 4 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 - : - : "memory", "cc", "q0", "q1", "q2", "q3", "q8", "q9", - "q10", "q11", "q12", "q13", "q14", "q15" - ); -} - -#undef LOAD2_DATA32_LANE - -#endif // defined(__ARM_NEON__) && !defined(__aarch64__) - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_neon64.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_neon64.cc deleted file mode 100644 index 494a9cfb..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_neon64.cc +++ /dev/null @@ -1,1064 +0,0 @@ -/* - * Copyright 2014 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/row.h" -#include "libyuv/scale.h" -#include "libyuv/scale_row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// This module is for GCC Neon armv8 64 bit. -#if !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) - -// Read 32x1 throw away even pixels, and write 16x1. -void ScaleRowDown2_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - (void)src_stride; - asm volatile( - "1: \n" - // load even pixels into v0, odd into v1 - "ld2 {v0.16b,v1.16b}, [%0], #32 \n" - "subs %w2, %w2, #16 \n" // 16 processed per loop - "st1 {v1.16b}, [%1], #16 \n" // store odd pixels - "b.gt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst), // %1 - "+r"(dst_width) // %2 - : - : "v0", "v1" // Clobber List - ); -} - -// Read 32x1 average down and write 16x1. -void ScaleRowDown2Linear_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - (void)src_stride; - asm volatile( - "1: \n" - // load even pixels into v0, odd into v1 - "ld2 {v0.16b,v1.16b}, [%0], #32 \n" - "subs %w2, %w2, #16 \n" // 16 processed per loop - "urhadd v0.16b, v0.16b, v1.16b \n" // rounding half add - "st1 {v0.16b}, [%1], #16 \n" - "b.gt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst), // %1 - "+r"(dst_width) // %2 - : - : "v0", "v1" // Clobber List - ); -} - -// Read 32x2 average down and write 16x1. -void ScaleRowDown2Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - asm volatile( - // change the stride to row 2 pointer - "add %1, %1, %0 \n" - "1: \n" - "ld1 {v0.16b, v1.16b}, [%0], #32 \n" // load row 1 and post inc - "ld1 {v2.16b, v3.16b}, [%1], #32 \n" // load row 2 and post inc - "subs %w3, %w3, #16 \n" // 16 processed per loop - "uaddlp v0.8h, v0.16b \n" // row 1 add adjacent - "uaddlp v1.8h, v1.16b \n" - "uadalp v0.8h, v2.16b \n" // += row 2 add adjacent - "uadalp v1.8h, v3.16b \n" - "rshrn v0.8b, v0.8h, #2 \n" // round and pack - "rshrn2 v0.16b, v1.8h, #2 \n" - "st1 {v0.16b}, [%2], #16 \n" - "b.gt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(src_stride), // %1 - "+r"(dst), // %2 - "+r"(dst_width) // %3 - : - : "v0", "v1", "v2", "v3" // Clobber List - ); -} - -void ScaleRowDown4_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - (void)src_stride; - asm volatile( - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // src line 0 - "subs %w2, %w2, #8 \n" // 8 processed per loop - "st1 {v2.8b}, [%1], #8 \n" - "b.gt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - : - : "v0", "v1", "v2", "v3", "memory", "cc"); -} - -void ScaleRowDown4Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - const uint8_t* src_ptr1 = src_ptr + src_stride; - const uint8_t* src_ptr2 = src_ptr + src_stride * 2; - const uint8_t* src_ptr3 = src_ptr + src_stride * 3; - asm volatile( - "1: \n" - "ld1 {v0.16b}, [%0], #16 \n" // load up 16x4 - "ld1 {v1.16b}, [%2], #16 \n" - "ld1 {v2.16b}, [%3], #16 \n" - "ld1 {v3.16b}, [%4], #16 \n" - "subs %w5, %w5, #4 \n" - "uaddlp v0.8h, v0.16b \n" - "uadalp v0.8h, v1.16b \n" - "uadalp v0.8h, v2.16b \n" - "uadalp v0.8h, v3.16b \n" - "addp v0.8h, v0.8h, v0.8h \n" - "rshrn v0.8b, v0.8h, #4 \n" // divide by 16 w/rounding - "st1 {v0.s}[0], [%1], #4 \n" - "b.gt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(src_ptr1), // %2 - "+r"(src_ptr2), // %3 - "+r"(src_ptr3), // %4 - "+r"(dst_width) // %5 - : - : "v0", "v1", "v2", "v3", "memory", "cc"); -} - -// Down scale from 4 to 3 pixels. Use the neon multilane read/write -// to load up the every 4th pixel into a 4 different registers. -// Point samples 32 pixels to 24 pixels. -void ScaleRowDown34_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - (void)src_stride; - asm volatile( - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // src line 0 - "subs %w2, %w2, #24 \n" - "orr v2.16b, v3.16b, v3.16b \n" // order v0,v1,v2 - "st3 {v0.8b,v1.8b,v2.8b}, [%1], #24 \n" - "b.gt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - : - : "v0", "v1", "v2", "v3", "memory", "cc"); -} - -void ScaleRowDown34_0_Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - asm volatile( - "movi v20.8b, #3 \n" - "add %3, %3, %0 \n" - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // src line 0 - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%3], #32 \n" // src line 1 - "subs %w2, %w2, #24 \n" - - // filter src line 0 with src line 1 - // expand chars to shorts to allow for room - // when adding lines together - "ushll v16.8h, v4.8b, #0 \n" - "ushll v17.8h, v5.8b, #0 \n" - "ushll v18.8h, v6.8b, #0 \n" - "ushll v19.8h, v7.8b, #0 \n" - - // 3 * line_0 + line_1 - "umlal v16.8h, v0.8b, v20.8b \n" - "umlal v17.8h, v1.8b, v20.8b \n" - "umlal v18.8h, v2.8b, v20.8b \n" - "umlal v19.8h, v3.8b, v20.8b \n" - - // (3 * line_0 + line_1) >> 2 - "uqrshrn v0.8b, v16.8h, #2 \n" - "uqrshrn v1.8b, v17.8h, #2 \n" - "uqrshrn v2.8b, v18.8h, #2 \n" - "uqrshrn v3.8b, v19.8h, #2 \n" - - // a0 = (src[0] * 3 + s[1] * 1) >> 2 - "ushll v16.8h, v1.8b, #0 \n" - "umlal v16.8h, v0.8b, v20.8b \n" - "uqrshrn v0.8b, v16.8h, #2 \n" - - // a1 = (src[1] * 1 + s[2] * 1) >> 1 - "urhadd v1.8b, v1.8b, v2.8b \n" - - // a2 = (src[2] * 1 + s[3] * 3) >> 2 - "ushll v16.8h, v2.8b, #0 \n" - "umlal v16.8h, v3.8b, v20.8b \n" - "uqrshrn v2.8b, v16.8h, #2 \n" - - "st3 {v0.8b,v1.8b,v2.8b}, [%1], #24 \n" - - "b.gt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width), // %2 - "+r"(src_stride) // %3 - : - : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", "v17", "v18", - "v19", "v20", "memory", "cc"); -} - -void ScaleRowDown34_1_Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - asm volatile( - "movi v20.8b, #3 \n" - "add %3, %3, %0 \n" - "1: \n" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" // src line 0 - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%3], #32 \n" // src line 1 - "subs %w2, %w2, #24 \n" - // average src line 0 with src line 1 - "urhadd v0.8b, v0.8b, v4.8b \n" - "urhadd v1.8b, v1.8b, v5.8b \n" - "urhadd v2.8b, v2.8b, v6.8b \n" - "urhadd v3.8b, v3.8b, v7.8b \n" - - // a0 = (src[0] * 3 + s[1] * 1) >> 2 - "ushll v4.8h, v1.8b, #0 \n" - "umlal v4.8h, v0.8b, v20.8b \n" - "uqrshrn v0.8b, v4.8h, #2 \n" - - // a1 = (src[1] * 1 + s[2] * 1) >> 1 - "urhadd v1.8b, v1.8b, v2.8b \n" - - // a2 = (src[2] * 1 + s[3] * 3) >> 2 - "ushll v4.8h, v2.8b, #0 \n" - "umlal v4.8h, v3.8b, v20.8b \n" - "uqrshrn v2.8b, v4.8h, #2 \n" - - "st3 {v0.8b,v1.8b,v2.8b}, [%1], #24 \n" - "b.gt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width), // %2 - "+r"(src_stride) // %3 - : - : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v20", "memory", "cc"); -} - -static const uvec8 kShuf38 = {0, 3, 6, 8, 11, 14, 16, 19, - 22, 24, 27, 30, 0, 0, 0, 0}; -static const uvec8 kShuf38_2 = {0, 16, 32, 2, 18, 33, 4, 20, - 34, 6, 22, 35, 0, 0, 0, 0}; -static const vec16 kMult38_Div6 = {65536 / 12, 65536 / 12, 65536 / 12, - 65536 / 12, 65536 / 12, 65536 / 12, - 65536 / 12, 65536 / 12}; -static const vec16 kMult38_Div9 = {65536 / 18, 65536 / 18, 65536 / 18, - 65536 / 18, 65536 / 18, 65536 / 18, - 65536 / 18, 65536 / 18}; - -// 32 -> 12 -void ScaleRowDown38_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - (void)src_stride; - asm volatile( - "ld1 {v3.16b}, [%3] \n" - "1: \n" - "ld1 {v0.16b,v1.16b}, [%0], #32 \n" - "subs %w2, %w2, #12 \n" - "tbl v2.16b, {v0.16b,v1.16b}, v3.16b \n" - "st1 {v2.8b}, [%1], #8 \n" - "st1 {v2.s}[2], [%1], #4 \n" - "b.gt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(dst_width) // %2 - : "r"(&kShuf38) // %3 - : "v0", "v1", "v2", "v3", "memory", "cc"); -} - -// 32x3 -> 12x1 -void OMITFP ScaleRowDown38_3_Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - const uint8_t* src_ptr1 = src_ptr + src_stride * 2; - ptrdiff_t tmp_src_stride = src_stride; - - asm volatile( - "ld1 {v29.8h}, [%5] \n" - "ld1 {v30.16b}, [%6] \n" - "ld1 {v31.8h}, [%7] \n" - "add %2, %2, %0 \n" - "1: \n" - - // 00 40 01 41 02 42 03 43 - // 10 50 11 51 12 52 13 53 - // 20 60 21 61 22 62 23 63 - // 30 70 31 71 32 72 33 73 - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%2], #32 \n" - "ld4 {v16.8b,v17.8b,v18.8b,v19.8b}, [%3], #32 \n" - "subs %w4, %w4, #12 \n" - - // Shuffle the input data around to get align the data - // so adjacent data can be added. 0,1 - 2,3 - 4,5 - 6,7 - // 00 10 01 11 02 12 03 13 - // 40 50 41 51 42 52 43 53 - "trn1 v20.8b, v0.8b, v1.8b \n" - "trn2 v21.8b, v0.8b, v1.8b \n" - "trn1 v22.8b, v4.8b, v5.8b \n" - "trn2 v23.8b, v4.8b, v5.8b \n" - "trn1 v24.8b, v16.8b, v17.8b \n" - "trn2 v25.8b, v16.8b, v17.8b \n" - - // 20 30 21 31 22 32 23 33 - // 60 70 61 71 62 72 63 73 - "trn1 v0.8b, v2.8b, v3.8b \n" - "trn2 v1.8b, v2.8b, v3.8b \n" - "trn1 v4.8b, v6.8b, v7.8b \n" - "trn2 v5.8b, v6.8b, v7.8b \n" - "trn1 v16.8b, v18.8b, v19.8b \n" - "trn2 v17.8b, v18.8b, v19.8b \n" - - // 00+10 01+11 02+12 03+13 - // 40+50 41+51 42+52 43+53 - "uaddlp v20.4h, v20.8b \n" - "uaddlp v21.4h, v21.8b \n" - "uaddlp v22.4h, v22.8b \n" - "uaddlp v23.4h, v23.8b \n" - "uaddlp v24.4h, v24.8b \n" - "uaddlp v25.4h, v25.8b \n" - - // 60+70 61+71 62+72 63+73 - "uaddlp v1.4h, v1.8b \n" - "uaddlp v5.4h, v5.8b \n" - "uaddlp v17.4h, v17.8b \n" - - // combine source lines - "add v20.4h, v20.4h, v22.4h \n" - "add v21.4h, v21.4h, v23.4h \n" - "add v20.4h, v20.4h, v24.4h \n" - "add v21.4h, v21.4h, v25.4h \n" - "add v2.4h, v1.4h, v5.4h \n" - "add v2.4h, v2.4h, v17.4h \n" - - // dst_ptr[3] = (s[6 + st * 0] + s[7 + st * 0] - // + s[6 + st * 1] + s[7 + st * 1] - // + s[6 + st * 2] + s[7 + st * 2]) / 6 - "sqrdmulh v2.8h, v2.8h, v29.8h \n" - "xtn v2.8b, v2.8h \n" - - // Shuffle 2,3 reg around so that 2 can be added to the - // 0,1 reg and 3 can be added to the 4,5 reg. This - // requires expanding from u8 to u16 as the 0,1 and 4,5 - // registers are already expanded. Then do transposes - // to get aligned. - // xx 20 xx 30 xx 21 xx 31 xx 22 xx 32 xx 23 xx 33 - "ushll v16.8h, v16.8b, #0 \n" - "uaddl v0.8h, v0.8b, v4.8b \n" - - // combine source lines - "add v0.8h, v0.8h, v16.8h \n" - - // xx 20 xx 21 xx 22 xx 23 - // xx 30 xx 31 xx 32 xx 33 - "trn1 v1.8h, v0.8h, v0.8h \n" - "trn2 v4.8h, v0.8h, v0.8h \n" - "xtn v0.4h, v1.4s \n" - "xtn v4.4h, v4.4s \n" - - // 0+1+2, 3+4+5 - "add v20.8h, v20.8h, v0.8h \n" - "add v21.8h, v21.8h, v4.8h \n" - - // Need to divide, but can't downshift as the the value - // isn't a power of 2. So multiply by 65536 / n - // and take the upper 16 bits. - "sqrdmulh v0.8h, v20.8h, v31.8h \n" - "sqrdmulh v1.8h, v21.8h, v31.8h \n" - - // Align for table lookup, vtbl requires registers to be adjacent - "tbl v3.16b, {v0.16b, v1.16b, v2.16b}, v30.16b \n" - - "st1 {v3.8b}, [%1], #8 \n" - "st1 {v3.s}[2], [%1], #4 \n" - "b.gt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(tmp_src_stride), // %2 - "+r"(src_ptr1), // %3 - "+r"(dst_width) // %4 - : "r"(&kMult38_Div6), // %5 - "r"(&kShuf38_2), // %6 - "r"(&kMult38_Div9) // %7 - : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", "v17", "v18", - "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v29", "v30", "v31", - "memory", "cc"); -} - -// 32x2 -> 12x1 -void ScaleRowDown38_2_Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - // TODO(fbarchard): use src_stride directly for clang 3.5+. - ptrdiff_t tmp_src_stride = src_stride; - asm volatile( - "ld1 {v30.8h}, [%4] \n" - "ld1 {v31.16b}, [%5] \n" - "add %2, %2, %0 \n" - "1: \n" - - // 00 40 01 41 02 42 03 43 - // 10 50 11 51 12 52 13 53 - // 20 60 21 61 22 62 23 63 - // 30 70 31 71 32 72 33 73 - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%0], #32 \n" - "ld4 {v4.8b,v5.8b,v6.8b,v7.8b}, [%2], #32 \n" - "subs %w3, %w3, #12 \n" - - // Shuffle the input data around to get align the data - // so adjacent data can be added. 0,1 - 2,3 - 4,5 - 6,7 - // 00 10 01 11 02 12 03 13 - // 40 50 41 51 42 52 43 53 - "trn1 v16.8b, v0.8b, v1.8b \n" - "trn2 v17.8b, v0.8b, v1.8b \n" - "trn1 v18.8b, v4.8b, v5.8b \n" - "trn2 v19.8b, v4.8b, v5.8b \n" - - // 20 30 21 31 22 32 23 33 - // 60 70 61 71 62 72 63 73 - "trn1 v0.8b, v2.8b, v3.8b \n" - "trn2 v1.8b, v2.8b, v3.8b \n" - "trn1 v4.8b, v6.8b, v7.8b \n" - "trn2 v5.8b, v6.8b, v7.8b \n" - - // 00+10 01+11 02+12 03+13 - // 40+50 41+51 42+52 43+53 - "uaddlp v16.4h, v16.8b \n" - "uaddlp v17.4h, v17.8b \n" - "uaddlp v18.4h, v18.8b \n" - "uaddlp v19.4h, v19.8b \n" - - // 60+70 61+71 62+72 63+73 - "uaddlp v1.4h, v1.8b \n" - "uaddlp v5.4h, v5.8b \n" - - // combine source lines - "add v16.4h, v16.4h, v18.4h \n" - "add v17.4h, v17.4h, v19.4h \n" - "add v2.4h, v1.4h, v5.4h \n" - - // dst_ptr[3] = (s[6] + s[7] + s[6+st] + s[7+st]) / 4 - "uqrshrn v2.8b, v2.8h, #2 \n" - - // Shuffle 2,3 reg around so that 2 can be added to the - // 0,1 reg and 3 can be added to the 4,5 reg. This - // requires expanding from u8 to u16 as the 0,1 and 4,5 - // registers are already expanded. Then do transposes - // to get aligned. - // xx 20 xx 30 xx 21 xx 31 xx 22 xx 32 xx 23 xx 33 - - // combine source lines - "uaddl v0.8h, v0.8b, v4.8b \n" - - // xx 20 xx 21 xx 22 xx 23 - // xx 30 xx 31 xx 32 xx 33 - "trn1 v1.8h, v0.8h, v0.8h \n" - "trn2 v4.8h, v0.8h, v0.8h \n" - "xtn v0.4h, v1.4s \n" - "xtn v4.4h, v4.4s \n" - - // 0+1+2, 3+4+5 - "add v16.8h, v16.8h, v0.8h \n" - "add v17.8h, v17.8h, v4.8h \n" - - // Need to divide, but can't downshift as the the value - // isn't a power of 2. So multiply by 65536 / n - // and take the upper 16 bits. - "sqrdmulh v0.8h, v16.8h, v30.8h \n" - "sqrdmulh v1.8h, v17.8h, v30.8h \n" - - // Align for table lookup, vtbl requires registers to - // be adjacent - - "tbl v3.16b, {v0.16b, v1.16b, v2.16b}, v31.16b \n" - - "st1 {v3.8b}, [%1], #8 \n" - "st1 {v3.s}[2], [%1], #4 \n" - "b.gt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst_ptr), // %1 - "+r"(tmp_src_stride), // %2 - "+r"(dst_width) // %3 - : "r"(&kMult38_Div6), // %4 - "r"(&kShuf38_2) // %5 - : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", "v17", "v18", - "v19", "v30", "v31", "memory", "cc"); -} - -void ScaleAddRows_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst_ptr, - int src_width, - int src_height) { - const uint8_t* src_tmp; - asm volatile( - "1: \n" - "mov %0, %1 \n" - "mov w12, %w5 \n" - "eor v2.16b, v2.16b, v2.16b \n" - "eor v3.16b, v3.16b, v3.16b \n" - "2: \n" - // load 16 pixels into q0 - "ld1 {v0.16b}, [%0], %3 \n" - "uaddw2 v3.8h, v3.8h, v0.16b \n" - "uaddw v2.8h, v2.8h, v0.8b \n" - "subs w12, w12, #1 \n" - "b.gt 2b \n" - "st1 {v2.8h, v3.8h}, [%2], #32 \n" // store pixels - "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 - : - : "memory", "cc", "w12", "v0", "v1", "v2", "v3" // Clobber List - ); -} - -// TODO(Yang Zhang): Investigate less load instructions for -// the x/dx stepping -#define LOAD2_DATA8_LANE(n) \ - "lsr %5, %3, #16 \n" \ - "add %6, %1, %5 \n" \ - "add %3, %3, %4 \n" \ - "ld2 {v4.b, v5.b}[" #n "], [%6] \n" - -// The NEON version mimics this formula (from row_common.cc): -// #define BLENDER(a, b, f) (uint8_t)((int)(a) + -// ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16)) - -void ScaleFilterCols_NEON(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx) { - int dx_offset[4] = {0, 1, 2, 3}; - int* tmp = dx_offset; - const uint8_t* src_tmp = src_ptr; - int64_t x64 = (int64_t)x; // NOLINT - int64_t dx64 = (int64_t)dx; // NOLINT - asm volatile ( - "dup v0.4s, %w3 \n" // x - "dup v1.4s, %w4 \n" // dx - "ld1 {v2.4s}, [%5] \n" // 0 1 2 3 - "shl v3.4s, v1.4s, #2 \n" // 4 * dx - "mul v1.4s, v1.4s, v2.4s \n" - // x , x + 1 * dx, x + 2 * dx, x + 3 * dx - "add v1.4s, v1.4s, v0.4s \n" - // x + 4 * dx, x + 5 * dx, x + 6 * dx, x + 7 * dx - "add v2.4s, v1.4s, v3.4s \n" - "shl v0.4s, v3.4s, #1 \n" // 8 * dx - "1: \n" - LOAD2_DATA8_LANE(0) - LOAD2_DATA8_LANE(1) - LOAD2_DATA8_LANE(2) - LOAD2_DATA8_LANE(3) - LOAD2_DATA8_LANE(4) - LOAD2_DATA8_LANE(5) - LOAD2_DATA8_LANE(6) - LOAD2_DATA8_LANE(7) - "mov v6.16b, v1.16b \n" - "mov v7.16b, v2.16b \n" - "uzp1 v6.8h, v6.8h, v7.8h \n" - "ushll v4.8h, v4.8b, #0 \n" - "ushll v5.8h, v5.8b, #0 \n" - "ssubl v16.4s, v5.4h, v4.4h \n" - "ssubl2 v17.4s, v5.8h, v4.8h \n" - "ushll v7.4s, v6.4h, #0 \n" - "ushll2 v6.4s, v6.8h, #0 \n" - "mul v16.4s, v16.4s, v7.4s \n" - "mul v17.4s, v17.4s, v6.4s \n" - "rshrn v6.4h, v16.4s, #16 \n" - "rshrn2 v6.8h, v17.4s, #16 \n" - "add v4.8h, v4.8h, v6.8h \n" - "xtn v4.8b, v4.8h \n" - - "st1 {v4.8b}, [%0], #8 \n" // store pixels - "add v1.4s, v1.4s, v0.4s \n" - "add v2.4s, v2.4s, v0.4s \n" - "subs %w2, %w2, #8 \n" // 8 processed per loop - "b.gt 1b \n" - : "+r"(dst_ptr), // %0 - "+r"(src_ptr), // %1 - "+r"(dst_width), // %2 - "+r"(x64), // %3 - "+r"(dx64), // %4 - "+r"(tmp), // %5 - "+r"(src_tmp) // %6 - : - : "memory", "cc", "v0", "v1", "v2", "v3", - "v4", "v5", "v6", "v7", "v16", "v17" - ); -} - -#undef LOAD2_DATA8_LANE - -// 16x2 -> 16x1 -void ScaleFilterRows_NEON(uint8_t* dst_ptr, - const uint8_t* src_ptr, - ptrdiff_t src_stride, - int dst_width, - int source_y_fraction) { - int y_fraction = 256 - source_y_fraction; - asm volatile( - "cmp %w4, #0 \n" - "b.eq 100f \n" - "add %2, %2, %1 \n" - "cmp %w4, #64 \n" - "b.eq 75f \n" - "cmp %w4, #128 \n" - "b.eq 50f \n" - "cmp %w4, #192 \n" - "b.eq 25f \n" - - "dup v5.8b, %w4 \n" - "dup v4.8b, %w5 \n" - // General purpose row blend. - "1: \n" - "ld1 {v0.16b}, [%1], #16 \n" - "ld1 {v1.16b}, [%2], #16 \n" - "subs %w3, %w3, #16 \n" - "umull v6.8h, v0.8b, v4.8b \n" - "umull2 v7.8h, v0.16b, v4.16b \n" - "umlal v6.8h, v1.8b, v5.8b \n" - "umlal2 v7.8h, v1.16b, v5.16b \n" - "rshrn v0.8b, v6.8h, #8 \n" - "rshrn2 v0.16b, v7.8h, #8 \n" - "st1 {v0.16b}, [%0], #16 \n" - "b.gt 1b \n" - "b 99f \n" - - // Blend 25 / 75. - "25: \n" - "ld1 {v0.16b}, [%1], #16 \n" - "ld1 {v1.16b}, [%2], #16 \n" - "subs %w3, %w3, #16 \n" - "urhadd v0.16b, v0.16b, v1.16b \n" - "urhadd v0.16b, v0.16b, v1.16b \n" - "st1 {v0.16b}, [%0], #16 \n" - "b.gt 25b \n" - "b 99f \n" - - // Blend 50 / 50. - "50: \n" - "ld1 {v0.16b}, [%1], #16 \n" - "ld1 {v1.16b}, [%2], #16 \n" - "subs %w3, %w3, #16 \n" - "urhadd v0.16b, v0.16b, v1.16b \n" - "st1 {v0.16b}, [%0], #16 \n" - "b.gt 50b \n" - "b 99f \n" - - // Blend 75 / 25. - "75: \n" - "ld1 {v1.16b}, [%1], #16 \n" - "ld1 {v0.16b}, [%2], #16 \n" - "subs %w3, %w3, #16 \n" - "urhadd v0.16b, v0.16b, v1.16b \n" - "urhadd v0.16b, v0.16b, v1.16b \n" - "st1 {v0.16b}, [%0], #16 \n" - "b.gt 75b \n" - "b 99f \n" - - // Blend 100 / 0 - Copy row unchanged. - "100: \n" - "ld1 {v0.16b}, [%1], #16 \n" - "subs %w3, %w3, #16 \n" - "st1 {v0.16b}, [%0], #16 \n" - "b.gt 100b \n" - - "99: \n" - "st1 {v0.b}[15], [%0] \n" - : "+r"(dst_ptr), // %0 - "+r"(src_ptr), // %1 - "+r"(src_stride), // %2 - "+r"(dst_width), // %3 - "+r"(source_y_fraction), // %4 - "+r"(y_fraction) // %5 - : - : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "memory", "cc"); -} - -void ScaleARGBRowDown2_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - (void)src_stride; - asm volatile( - "1: \n" - // load 16 ARGB pixels with even pixels into q0/q2, odd into q1/q3 - "ld4 {v0.4s,v1.4s,v2.4s,v3.4s}, [%0], #64 \n" - "subs %w2, %w2, #8 \n" // 8 processed per loop - "mov v2.16b, v3.16b \n" - "st2 {v1.4s,v2.4s}, [%1], #32 \n" // store 8 odd pixels - "b.gt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(dst), // %1 - "+r"(dst_width) // %2 - : - : "memory", "cc", "v0", "v1", "v2", "v3" // Clobber List - ); -} - -void ScaleARGBRowDown2Linear_NEON(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width) { - (void)src_stride; - asm volatile( - "1: \n" - // load 16 ARGB pixels with even pixels into q0/q2, odd into q1/q3 - "ld4 {v0.4s,v1.4s,v2.4s,v3.4s}, [%0], #64 \n" - "subs %w2, %w2, #8 \n" // 8 processed per loop - - "urhadd v0.16b, v0.16b, v1.16b \n" // rounding half add - "urhadd v1.16b, v2.16b, v3.16b \n" - "st2 {v0.4s,v1.4s}, [%1], #32 \n" // store 8 pixels - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(dst_width) // %2 - : - : "memory", "cc", "v0", "v1", "v2", "v3" // Clobber List - ); -} - -void ScaleARGBRowDown2Box_NEON(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst, - int dst_width) { - asm volatile( - // change the stride to row 2 pointer - "add %1, %1, %0 \n" - "1: \n" - "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load 8 ARGB - "subs %w3, %w3, #8 \n" // 8 processed per loop. - "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. - "uaddlp v3.8h, v3.16b \n" // A 16 bytes -> 8 shorts. - "ld4 {v16.16b,v17.16b,v18.16b,v19.16b}, [%1], #64 \n" // load 8 - "uadalp v0.8h, v16.16b \n" // B 16 bytes -> 8 shorts. - "uadalp v1.8h, v17.16b \n" // G 16 bytes -> 8 shorts. - "uadalp v2.8h, v18.16b \n" // R 16 bytes -> 8 shorts. - "uadalp v3.8h, v19.16b \n" // A 16 bytes -> 8 shorts. - "rshrn v0.8b, v0.8h, #2 \n" // round and pack - "rshrn v1.8b, v1.8h, #2 \n" - "rshrn v2.8b, v2.8h, #2 \n" - "rshrn v3.8b, v3.8h, #2 \n" - "st4 {v0.8b,v1.8b,v2.8b,v3.8b}, [%2], #32 \n" - "b.gt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(src_stride), // %1 - "+r"(dst), // %2 - "+r"(dst_width) // %3 - : - : "memory", "cc", "v0", "v1", "v2", "v3", "v16", "v17", "v18", "v19"); -} - -// Reads 4 pixels at a time. -// Alignment requirement: src_argb 4 byte aligned. -void ScaleARGBRowDownEven_NEON(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width) { - (void)src_stride; - asm volatile( - "1: \n" - "ld1 {v0.s}[0], [%0], %3 \n" - "ld1 {v0.s}[1], [%0], %3 \n" - "ld1 {v0.s}[2], [%0], %3 \n" - "ld1 {v0.s}[3], [%0], %3 \n" - "subs %w2, %w2, #4 \n" // 4 pixels per loop. - "st1 {v0.16b}, [%1], #16 \n" - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(dst_argb), // %1 - "+r"(dst_width) // %2 - : "r"((int64_t)(src_stepx * 4)) // %3 - : "memory", "cc", "v0"); -} - -// Reads 4 pixels at a time. -// Alignment requirement: src_argb 4 byte aligned. -// TODO(Yang Zhang): Might be worth another optimization pass in future. -// It could be upgraded to 8 pixels at a time to start with. -void ScaleARGBRowDownEvenBox_NEON(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width) { - asm volatile( - "add %1, %1, %0 \n" - "1: \n" - "ld1 {v0.8b}, [%0], %4 \n" // Read 4 2x2 -> 2x1 - "ld1 {v1.8b}, [%1], %4 \n" - "ld1 {v2.8b}, [%0], %4 \n" - "ld1 {v3.8b}, [%1], %4 \n" - "ld1 {v4.8b}, [%0], %4 \n" - "ld1 {v5.8b}, [%1], %4 \n" - "ld1 {v6.8b}, [%0], %4 \n" - "ld1 {v7.8b}, [%1], %4 \n" - "uaddl v0.8h, v0.8b, v1.8b \n" - "uaddl v2.8h, v2.8b, v3.8b \n" - "uaddl v4.8h, v4.8b, v5.8b \n" - "uaddl v6.8h, v6.8b, v7.8b \n" - "mov v16.d[1], v0.d[1] \n" // ab_cd -> ac_bd - "mov v0.d[1], v2.d[0] \n" - "mov v2.d[0], v16.d[1] \n" - "mov v16.d[1], v4.d[1] \n" // ef_gh -> eg_fh - "mov v4.d[1], v6.d[0] \n" - "mov v6.d[0], v16.d[1] \n" - "add v0.8h, v0.8h, v2.8h \n" // (a+b)_(c+d) - "add v4.8h, v4.8h, v6.8h \n" // (e+f)_(g+h) - "rshrn v0.8b, v0.8h, #2 \n" // first 2 pixels. - "rshrn2 v0.16b, v4.8h, #2 \n" // next 2 pixels. - "subs %w3, %w3, #4 \n" // 4 pixels per loop. - "st1 {v0.16b}, [%2], #16 \n" - "b.gt 1b \n" - : "+r"(src_argb), // %0 - "+r"(src_stride), // %1 - "+r"(dst_argb), // %2 - "+r"(dst_width) // %3 - : "r"((int64_t)(src_stepx * 4)) // %4 - : "memory", "cc", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"); -} - -// TODO(Yang Zhang): Investigate less load instructions for -// the x/dx stepping -#define LOAD1_DATA32_LANE(vn, n) \ - "lsr %5, %3, #16 \n" \ - "add %6, %1, %5, lsl #2 \n" \ - "add %3, %3, %4 \n" \ - "ld1 {" #vn ".s}[" #n "], [%6] \n" - -void ScaleARGBCols_NEON(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx) { - const uint8_t* src_tmp = src_argb; - int64_t x64 = (int64_t)x; // NOLINT - int64_t dx64 = (int64_t)dx; // NOLINT - int64_t tmp64; - asm volatile( - "1: \n" - // clang-format off - LOAD1_DATA32_LANE(v0, 0) - LOAD1_DATA32_LANE(v0, 1) - LOAD1_DATA32_LANE(v0, 2) - LOAD1_DATA32_LANE(v0, 3) - LOAD1_DATA32_LANE(v1, 0) - LOAD1_DATA32_LANE(v1, 1) - LOAD1_DATA32_LANE(v1, 2) - LOAD1_DATA32_LANE(v1, 3) - // clang-format on - "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_width), // %2 - "+r"(x64), // %3 - "+r"(dx64), // %4 - "=&r"(tmp64), // %5 - "+r"(src_tmp) // %6 - : - : "memory", "cc", "v0", "v1"); -} - -#undef LOAD1_DATA32_LANE - -// TODO(Yang Zhang): Investigate less load instructions for -// the x/dx stepping -#define LOAD2_DATA32_LANE(vn1, vn2, n) \ - "lsr %5, %3, #16 \n" \ - "add %6, %1, %5, lsl #2 \n" \ - "add %3, %3, %4 \n" \ - "ld2 {" #vn1 ".s, " #vn2 ".s}[" #n "], [%6] \n" - -void ScaleARGBFilterCols_NEON(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx) { - int dx_offset[4] = {0, 1, 2, 3}; - int* tmp = dx_offset; - const uint8_t* src_tmp = src_argb; - int64_t x64 = (int64_t)x; // NOLINT - int64_t dx64 = (int64_t)dx; // NOLINT - asm volatile ( - "dup v0.4s, %w3 \n" // x - "dup v1.4s, %w4 \n" // dx - "ld1 {v2.4s}, [%5] \n" // 0 1 2 3 - "shl v6.4s, v1.4s, #2 \n" // 4 * dx - "mul v1.4s, v1.4s, v2.4s \n" - "movi v3.16b, #0x7f \n" // 0x7F - "movi v4.8h, #0x7f \n" // 0x7F - // x , x + 1 * dx, x + 2 * dx, x + 3 * dx - "add v5.4s, v1.4s, v0.4s \n" - "1: \n" - // d0, d1: a - // d2, d3: b - LOAD2_DATA32_LANE(v0, v1, 0) - LOAD2_DATA32_LANE(v0, v1, 1) - LOAD2_DATA32_LANE(v0, v1, 2) - LOAD2_DATA32_LANE(v0, v1, 3) - "shrn v2.4h, v5.4s, #9 \n" - "and v2.8b, v2.8b, v4.8b \n" - "dup v16.8b, v2.b[0] \n" - "dup v17.8b, v2.b[2] \n" - "dup v18.8b, v2.b[4] \n" - "dup v19.8b, v2.b[6] \n" - "ext v2.8b, v16.8b, v17.8b, #4 \n" - "ext v17.8b, v18.8b, v19.8b, #4 \n" - "ins v2.d[1], v17.d[0] \n" // f - "eor v7.16b, v2.16b, v3.16b \n" // 0x7f ^ f - "umull v16.8h, v0.8b, v7.8b \n" - "umull2 v17.8h, v0.16b, v7.16b \n" - "umull v18.8h, v1.8b, v2.8b \n" - "umull2 v19.8h, v1.16b, v2.16b \n" - "add v16.8h, v16.8h, v18.8h \n" - "add v17.8h, v17.8h, v19.8h \n" - "shrn v0.8b, v16.8h, #7 \n" - "shrn2 v0.16b, v17.8h, #7 \n" - - "st1 {v0.4s}, [%0], #16 \n" // store pixels - "add v5.4s, v5.4s, v6.4s \n" - "subs %w2, %w2, #4 \n" // 4 processed per loop - "b.gt 1b \n" - : "+r"(dst_argb), // %0 - "+r"(src_argb), // %1 - "+r"(dst_width), // %2 - "+r"(x64), // %3 - "+r"(dx64), // %4 - "+r"(tmp), // %5 - "+r"(src_tmp) // %6 - : - : "memory", "cc", "v0", "v1", "v2", "v3", "v4", "v5", - "v6", "v7", "v16", "v17", "v18", "v19" - ); -} - -#undef LOAD2_DATA32_LANE - -// Read 16x2 average down and write 8x1. -void ScaleRowDown2Box_16_NEON(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst, - int dst_width) { - asm volatile( - // change the stride to row 2 pointer - "add %1, %0, %1, lsl #1 \n" // ptr + stide * 2 - "1: \n" - "ld1 {v0.8h, v1.8h}, [%0], #32 \n" // load row 1 and post inc - "ld1 {v2.8h, v3.8h}, [%1], #32 \n" // load row 2 and post inc - "subs %w3, %w3, #8 \n" // 8 processed per loop - "uaddlp v0.4s, v0.8h \n" // row 1 add adjacent - "uaddlp v1.4s, v1.8h \n" - "uadalp v0.4s, v2.8h \n" // +row 2 add adjacent - "uadalp v1.4s, v3.8h \n" - "rshrn v0.4h, v0.4s, #2 \n" // round and pack - "rshrn2 v0.8h, v1.4s, #2 \n" - "st1 {v0.8h}, [%2], #16 \n" - "b.gt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(src_stride), // %1 - "+r"(dst), // %2 - "+r"(dst_width) // %3 - : - : "v0", "v1", "v2", "v3" // Clobber List - ); -} - -// Read 8x2 upsample with filtering and write 16x1. -// Actually reads an extra pixel, so 9x2. -void ScaleRowUp2_16_NEON(const uint16_t* src_ptr, - ptrdiff_t src_stride, - uint16_t* dst, - int dst_width) { - asm volatile( - "add %1, %0, %1, lsl #1 \n" // ptr + stide * 2 - "movi v0.8h, #9 \n" // constants - "movi v1.4s, #3 \n" - - "1: \n" - "ld1 {v3.8h}, [%0], %4 \n" // TL read first 8 - "ld1 {v4.8h}, [%0], %5 \n" // TR read 8 offset by 1 - "ld1 {v5.8h}, [%1], %4 \n" // BL read 8 from next row - "ld1 {v6.8h}, [%1], %5 \n" // BR offset by 1 - "subs %w3, %w3, #16 \n" // 16 dst pixels per loop - "umull v16.4s, v3.4h, v0.4h \n" - "umull2 v7.4s, v3.8h, v0.8h \n" - "umull v18.4s, v4.4h, v0.4h \n" - "umull2 v17.4s, v4.8h, v0.8h \n" - "uaddw v16.4s, v16.4s, v6.4h \n" - "uaddl2 v19.4s, v6.8h, v3.8h \n" - "uaddl v3.4s, v6.4h, v3.4h \n" - "uaddw2 v6.4s, v7.4s, v6.8h \n" - "uaddl2 v7.4s, v5.8h, v4.8h \n" - "uaddl v4.4s, v5.4h, v4.4h \n" - "uaddw v18.4s, v18.4s, v5.4h \n" - "mla v16.4s, v4.4s, v1.4s \n" - "mla v18.4s, v3.4s, v1.4s \n" - "mla v6.4s, v7.4s, v1.4s \n" - "uaddw2 v4.4s, v17.4s, v5.8h \n" - "uqrshrn v16.4h, v16.4s, #4 \n" - "mla v4.4s, v19.4s, v1.4s \n" - "uqrshrn2 v16.8h, v6.4s, #4 \n" - "uqrshrn v17.4h, v18.4s, #4 \n" - "uqrshrn2 v17.8h, v4.4s, #4 \n" - "st2 {v16.8h-v17.8h}, [%2], #32 \n" - "b.gt 1b \n" - : "+r"(src_ptr), // %0 - "+r"(src_stride), // %1 - "+r"(dst), // %2 - "+r"(dst_width) // %3 - : "r"(2LL), // %4 - "r"(14LL) // %5 - : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", "v17", "v18", - "v19" // Clobber List - ); -} - -#endif // !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_win.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_win.cc deleted file mode 100644 index c5fc86f3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/scale_win.cc +++ /dev/null @@ -1,1391 +0,0 @@ -/* - * Copyright 2013 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/row.h" -#include "libyuv/scale_row.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -// This module is for 32 bit Visual C x86 and clangcl -#if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) - -// Offsets for source bytes 0 to 9 -static const uvec8 kShuf0 = {0, 1, 3, 4, 5, 7, 8, 9, - 128, 128, 128, 128, 128, 128, 128, 128}; - -// Offsets for source bytes 11 to 20 with 8 subtracted = 3 to 12. -static const uvec8 kShuf1 = {3, 4, 5, 7, 8, 9, 11, 12, - 128, 128, 128, 128, 128, 128, 128, 128}; - -// Offsets for source bytes 21 to 31 with 16 subtracted = 5 to 31. -static const uvec8 kShuf2 = {5, 7, 8, 9, 11, 12, 13, 15, - 128, 128, 128, 128, 128, 128, 128, 128}; - -// Offsets for source bytes 0 to 10 -static const uvec8 kShuf01 = {0, 1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10}; - -// Offsets for source bytes 10 to 21 with 8 subtracted = 3 to 13. -static const uvec8 kShuf11 = {2, 3, 4, 5, 5, 6, 6, 7, - 8, 9, 9, 10, 10, 11, 12, 13}; - -// Offsets for source bytes 21 to 31 with 16 subtracted = 5 to 31. -static const uvec8 kShuf21 = {5, 6, 6, 7, 8, 9, 9, 10, - 10, 11, 12, 13, 13, 14, 14, 15}; - -// Coefficients for source bytes 0 to 10 -static const uvec8 kMadd01 = {3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2}; - -// Coefficients for source bytes 10 to 21 -static const uvec8 kMadd11 = {1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1}; - -// Coefficients for source bytes 21 to 31 -static const uvec8 kMadd21 = {2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3}; - -// Coefficients for source bytes 21 to 31 -static const vec16 kRound34 = {2, 2, 2, 2, 2, 2, 2, 2}; - -static const uvec8 kShuf38a = {0, 3, 6, 8, 11, 14, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128}; - -static const uvec8 kShuf38b = {128, 128, 128, 128, 128, 128, 0, 3, - 6, 8, 11, 14, 128, 128, 128, 128}; - -// Arrange words 0,3,6 into 0,1,2 -static const uvec8 kShufAc = {0, 1, 6, 7, 12, 13, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128}; - -// Arrange words 0,3,6 into 3,4,5 -static const uvec8 kShufAc3 = {128, 128, 128, 128, 128, 128, 0, 1, - 6, 7, 12, 13, 128, 128, 128, 128}; - -// Scaling values for boxes of 3x3 and 2x3 -static const uvec16 kScaleAc33 = {65536 / 9, 65536 / 9, 65536 / 6, 65536 / 9, - 65536 / 9, 65536 / 6, 0, 0}; - -// Arrange first value for pixels 0,1,2,3,4,5 -static const uvec8 kShufAb0 = {0, 128, 3, 128, 6, 128, 8, 128, - 11, 128, 14, 128, 128, 128, 128, 128}; - -// Arrange second value for pixels 0,1,2,3,4,5 -static const uvec8 kShufAb1 = {1, 128, 4, 128, 7, 128, 9, 128, - 12, 128, 15, 128, 128, 128, 128, 128}; - -// Arrange third value for pixels 0,1,2,3,4,5 -static const uvec8 kShufAb2 = {2, 128, 5, 128, 128, 128, 10, 128, - 13, 128, 128, 128, 128, 128, 128, 128}; - -// Scaling values for boxes of 3x2 and 2x2 -static const uvec16 kScaleAb2 = {65536 / 3, 65536 / 3, 65536 / 2, 65536 / 3, - 65536 / 3, 65536 / 2, 0, 0}; - -// Reads 32 pixels, throws half away and writes 16 pixels. -__declspec(naked) void ScaleRowDown2_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - __asm { - mov eax, [esp + 4] // src_ptr - // src_stride ignored - mov edx, [esp + 12] // dst_ptr - mov ecx, [esp + 16] // dst_width - - wloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - lea eax, [eax + 32] - psrlw xmm0, 8 // isolate odd pixels. - psrlw xmm1, 8 - packuswb xmm0, xmm1 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 16 - jg wloop - - ret - } -} - -// Blends 32x1 rectangle to 16x1. -__declspec(naked) void ScaleRowDown2Linear_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - __asm { - mov eax, [esp + 4] // src_ptr - // src_stride - mov edx, [esp + 12] // dst_ptr - mov ecx, [esp + 16] // dst_width - - pcmpeqb xmm4, xmm4 // constant 0x0101 - psrlw xmm4, 15 - packuswb xmm4, xmm4 - pxor xmm5, xmm5 // constant 0 - - wloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - lea eax, [eax + 32] - pmaddubsw xmm0, xmm4 // horizontal add - pmaddubsw xmm1, xmm4 - pavgw xmm0, xmm5 // (x + 1) / 2 - pavgw xmm1, xmm5 - packuswb xmm0, xmm1 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 16 - jg wloop - - ret - } -} - -// Blends 32x2 rectangle to 16x1. -__declspec(naked) void ScaleRowDown2Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_ptr - mov esi, [esp + 4 + 8] // src_stride - mov edx, [esp + 4 + 12] // dst_ptr - mov ecx, [esp + 4 + 16] // dst_width - - pcmpeqb xmm4, xmm4 // constant 0x0101 - psrlw xmm4, 15 - packuswb xmm4, xmm4 - pxor xmm5, xmm5 // constant 0 - - wloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - movdqu xmm2, [eax + esi] - movdqu xmm3, [eax + esi + 16] - lea eax, [eax + 32] - pmaddubsw xmm0, xmm4 // horizontal add - pmaddubsw xmm1, xmm4 - pmaddubsw xmm2, xmm4 - pmaddubsw xmm3, xmm4 - paddw xmm0, xmm2 // vertical add - paddw xmm1, xmm3 - psrlw xmm0, 1 - psrlw xmm1, 1 - pavgw xmm0, xmm5 // (x + 1) / 2 - pavgw xmm1, xmm5 - packuswb xmm0, xmm1 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 16 - jg wloop - - pop esi - ret - } -} - -#ifdef HAS_SCALEROWDOWN2_AVX2 -// Reads 64 pixels, throws half away and writes 32 pixels. -__declspec(naked) void ScaleRowDown2_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - __asm { - mov eax, [esp + 4] // src_ptr - // src_stride ignored - mov edx, [esp + 12] // dst_ptr - mov ecx, [esp + 16] // dst_width - - wloop: - vmovdqu ymm0, [eax] - vmovdqu ymm1, [eax + 32] - lea eax, [eax + 64] - vpsrlw ymm0, ymm0, 8 // isolate odd pixels. - vpsrlw ymm1, ymm1, 8 - vpackuswb ymm0, ymm0, ymm1 - vpermq ymm0, ymm0, 0xd8 // unmutate vpackuswb - vmovdqu [edx], ymm0 - lea edx, [edx + 32] - sub ecx, 32 - jg wloop - - vzeroupper - ret - } -} - -// Blends 64x1 rectangle to 32x1. -__declspec(naked) void ScaleRowDown2Linear_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - __asm { - mov eax, [esp + 4] // src_ptr - // src_stride - mov edx, [esp + 12] // dst_ptr - mov ecx, [esp + 16] // dst_width - - vpcmpeqb ymm4, ymm4, ymm4 // '1' constant, 8b - vpsrlw ymm4, ymm4, 15 - vpackuswb ymm4, ymm4, ymm4 - vpxor ymm5, ymm5, ymm5 // constant 0 - - wloop: - vmovdqu ymm0, [eax] - vmovdqu ymm1, [eax + 32] - lea eax, [eax + 64] - vpmaddubsw ymm0, ymm0, ymm4 // horizontal add - vpmaddubsw ymm1, ymm1, ymm4 - vpavgw ymm0, ymm0, ymm5 // (x + 1) / 2 - vpavgw ymm1, ymm1, ymm5 - vpackuswb ymm0, ymm0, ymm1 - vpermq ymm0, ymm0, 0xd8 // unmutate vpackuswb - vmovdqu [edx], ymm0 - lea edx, [edx + 32] - sub ecx, 32 - jg wloop - - vzeroupper - ret - } -} - -// For rounding, average = (sum + 2) / 4 -// becomes average((sum >> 1), 0) -// Blends 64x2 rectangle to 32x1. -__declspec(naked) void ScaleRowDown2Box_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_ptr - mov esi, [esp + 4 + 8] // src_stride - mov edx, [esp + 4 + 12] // dst_ptr - mov ecx, [esp + 4 + 16] // dst_width - - vpcmpeqb ymm4, ymm4, ymm4 // '1' constant, 8b - vpsrlw ymm4, ymm4, 15 - vpackuswb ymm4, ymm4, ymm4 - vpxor ymm5, ymm5, ymm5 // constant 0 - - wloop: - vmovdqu ymm0, [eax] - vmovdqu ymm1, [eax + 32] - vmovdqu ymm2, [eax + esi] - vmovdqu ymm3, [eax + esi + 32] - lea eax, [eax + 64] - vpmaddubsw ymm0, ymm0, ymm4 // horizontal add - vpmaddubsw ymm1, ymm1, ymm4 - vpmaddubsw ymm2, ymm2, ymm4 - vpmaddubsw ymm3, ymm3, ymm4 - vpaddw ymm0, ymm0, ymm2 // vertical add - vpaddw ymm1, ymm1, ymm3 - 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 - vpackuswb ymm0, ymm0, ymm1 - vpermq ymm0, ymm0, 0xd8 // unmutate vpackuswb - vmovdqu [edx], ymm0 - lea edx, [edx + 32] - sub ecx, 32 - jg wloop - - pop esi - vzeroupper - ret - } -} -#endif // HAS_SCALEROWDOWN2_AVX2 - -// Point samples 32 pixels to 8 pixels. -__declspec(naked) void ScaleRowDown4_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - __asm { - mov eax, [esp + 4] // src_ptr - // src_stride ignored - mov edx, [esp + 12] // dst_ptr - mov ecx, [esp + 16] // dst_width - pcmpeqb xmm5, xmm5 // generate mask 0x00ff0000 - psrld xmm5, 24 - pslld xmm5, 16 - - wloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - lea eax, [eax + 32] - pand xmm0, xmm5 - pand xmm1, xmm5 - packuswb xmm0, xmm1 - psrlw xmm0, 8 - packuswb xmm0, xmm0 - movq qword ptr [edx], xmm0 - lea edx, [edx + 8] - sub ecx, 8 - jg wloop - - ret - } -} - -// Blends 32x4 rectangle to 8x1. -__declspec(naked) void ScaleRowDown4Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - __asm { - push esi - push edi - mov eax, [esp + 8 + 4] // src_ptr - mov esi, [esp + 8 + 8] // src_stride - mov edx, [esp + 8 + 12] // dst_ptr - mov ecx, [esp + 8 + 16] // dst_width - lea edi, [esi + esi * 2] // src_stride * 3 - pcmpeqb xmm4, xmm4 // constant 0x0101 - psrlw xmm4, 15 - movdqa xmm5, xmm4 - packuswb xmm4, xmm4 - psllw xmm5, 3 // constant 0x0008 - - wloop: - movdqu xmm0, [eax] // average rows - movdqu xmm1, [eax + 16] - movdqu xmm2, [eax + esi] - movdqu xmm3, [eax + esi + 16] - pmaddubsw xmm0, xmm4 // horizontal add - pmaddubsw xmm1, xmm4 - pmaddubsw xmm2, xmm4 - pmaddubsw xmm3, xmm4 - paddw xmm0, xmm2 // vertical add rows 0, 1 - paddw xmm1, xmm3 - movdqu xmm2, [eax + esi * 2] - movdqu xmm3, [eax + esi * 2 + 16] - pmaddubsw xmm2, xmm4 - pmaddubsw xmm3, xmm4 - paddw xmm0, xmm2 // add row 2 - paddw xmm1, xmm3 - movdqu xmm2, [eax + edi] - movdqu xmm3, [eax + edi + 16] - lea eax, [eax + 32] - pmaddubsw xmm2, xmm4 - pmaddubsw xmm3, xmm4 - paddw xmm0, xmm2 // add row 3 - paddw xmm1, xmm3 - phaddw xmm0, xmm1 - paddw xmm0, xmm5 // + 8 for round - psrlw xmm0, 4 // /16 for average of 4 * 4 - packuswb xmm0, xmm0 - movq qword ptr [edx], xmm0 - lea edx, [edx + 8] - sub ecx, 8 - jg wloop - - pop edi - pop esi - ret - } -} - -#ifdef HAS_SCALEROWDOWN4_AVX2 -// Point samples 64 pixels to 16 pixels. -__declspec(naked) void ScaleRowDown4_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - __asm { - mov eax, [esp + 4] // src_ptr - // src_stride ignored - mov edx, [esp + 12] // dst_ptr - mov ecx, [esp + 16] // dst_width - vpcmpeqb ymm5, ymm5, ymm5 // generate mask 0x00ff0000 - vpsrld ymm5, ymm5, 24 - vpslld ymm5, ymm5, 16 - - wloop: - vmovdqu ymm0, [eax] - vmovdqu ymm1, [eax + 32] - lea eax, [eax + 64] - vpand ymm0, ymm0, ymm5 - vpand ymm1, ymm1, ymm5 - vpackuswb ymm0, ymm0, ymm1 - vpermq ymm0, ymm0, 0xd8 // unmutate vpackuswb - vpsrlw ymm0, ymm0, 8 - vpackuswb ymm0, ymm0, ymm0 - vpermq ymm0, ymm0, 0xd8 // unmutate vpackuswb - vmovdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 16 - jg wloop - - vzeroupper - ret - } -} - -// Blends 64x4 rectangle to 16x1. -__declspec(naked) void ScaleRowDown4Box_AVX2(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - __asm { - push esi - push edi - mov eax, [esp + 8 + 4] // src_ptr - mov esi, [esp + 8 + 8] // src_stride - mov edx, [esp + 8 + 12] // dst_ptr - mov ecx, [esp + 8 + 16] // dst_width - lea edi, [esi + esi * 2] // src_stride * 3 - vpcmpeqb ymm4, ymm4, ymm4 // constant 0x0101 - vpsrlw ymm4, ymm4, 15 - vpsllw ymm5, ymm4, 3 // constant 0x0008 - vpackuswb ymm4, ymm4, ymm4 - - wloop: - vmovdqu ymm0, [eax] // average rows - vmovdqu ymm1, [eax + 32] - vmovdqu ymm2, [eax + esi] - vmovdqu ymm3, [eax + esi + 32] - vpmaddubsw ymm0, ymm0, ymm4 // horizontal add - vpmaddubsw ymm1, ymm1, ymm4 - vpmaddubsw ymm2, ymm2, ymm4 - vpmaddubsw ymm3, ymm3, ymm4 - vpaddw ymm0, ymm0, ymm2 // vertical add rows 0, 1 - vpaddw ymm1, ymm1, ymm3 - vmovdqu ymm2, [eax + esi * 2] - vmovdqu ymm3, [eax + esi * 2 + 32] - vpmaddubsw ymm2, ymm2, ymm4 - vpmaddubsw ymm3, ymm3, ymm4 - vpaddw ymm0, ymm0, ymm2 // add row 2 - vpaddw ymm1, ymm1, ymm3 - vmovdqu ymm2, [eax + edi] - vmovdqu ymm3, [eax + edi + 32] - lea eax, [eax + 64] - vpmaddubsw ymm2, ymm2, ymm4 - vpmaddubsw ymm3, ymm3, ymm4 - vpaddw ymm0, ymm0, ymm2 // add row 3 - vpaddw ymm1, ymm1, ymm3 - vphaddw ymm0, ymm0, ymm1 // mutates - vpermq ymm0, ymm0, 0xd8 // unmutate vphaddw - vpaddw ymm0, ymm0, ymm5 // + 8 for round - vpsrlw ymm0, ymm0, 4 // /32 for average of 4 * 4 - vpackuswb ymm0, ymm0, ymm0 - vpermq ymm0, ymm0, 0xd8 // unmutate vpackuswb - vmovdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 16 - jg wloop - - pop edi - pop esi - vzeroupper - ret - } -} -#endif // HAS_SCALEROWDOWN4_AVX2 - -// Point samples 32 pixels to 24 pixels. -// Produces three 8 byte values. For each 8 bytes, 16 bytes are read. -// Then shuffled to do the scaling. - -__declspec(naked) void ScaleRowDown34_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - __asm { - mov eax, [esp + 4] // src_ptr - // src_stride ignored - mov edx, [esp + 12] // dst_ptr - mov ecx, [esp + 16] // dst_width - movdqa xmm3, xmmword ptr kShuf0 - movdqa xmm4, xmmword ptr kShuf1 - movdqa xmm5, xmmword ptr kShuf2 - - wloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - lea eax, [eax + 32] - movdqa xmm2, xmm1 - palignr xmm1, xmm0, 8 - pshufb xmm0, xmm3 - pshufb xmm1, xmm4 - pshufb xmm2, xmm5 - movq qword ptr [edx], xmm0 - movq qword ptr [edx + 8], xmm1 - movq qword ptr [edx + 16], xmm2 - lea edx, [edx + 24] - sub ecx, 24 - jg wloop - - ret - } -} - -// Blends 32x2 rectangle to 24x1 -// Produces three 8 byte values. For each 8 bytes, 16 bytes are read. -// Then shuffled to do the scaling. - -// Register usage: -// xmm0 src_row 0 -// xmm1 src_row 1 -// xmm2 shuf 0 -// xmm3 shuf 1 -// xmm4 shuf 2 -// xmm5 madd 0 -// xmm6 madd 1 -// xmm7 kRound34 - -// Note that movdqa+palign may be better than movdqu. -__declspec(naked) void ScaleRowDown34_1_Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_ptr - mov esi, [esp + 4 + 8] // src_stride - mov edx, [esp + 4 + 12] // dst_ptr - mov ecx, [esp + 4 + 16] // dst_width - movdqa xmm2, xmmword ptr kShuf01 - movdqa xmm3, xmmword ptr kShuf11 - movdqa xmm4, xmmword ptr kShuf21 - movdqa xmm5, xmmword ptr kMadd01 - movdqa xmm6, xmmword ptr kMadd11 - movdqa xmm7, xmmword ptr kRound34 - - wloop: - movdqu xmm0, [eax] // pixels 0..7 - movdqu xmm1, [eax + esi] - pavgb xmm0, xmm1 - pshufb xmm0, xmm2 - pmaddubsw xmm0, xmm5 - paddsw xmm0, xmm7 - psrlw xmm0, 2 - packuswb xmm0, xmm0 - movq qword ptr [edx], xmm0 - movdqu xmm0, [eax + 8] // pixels 8..15 - movdqu xmm1, [eax + esi + 8] - pavgb xmm0, xmm1 - pshufb xmm0, xmm3 - pmaddubsw xmm0, xmm6 - paddsw xmm0, xmm7 - psrlw xmm0, 2 - packuswb xmm0, xmm0 - movq qword ptr [edx + 8], xmm0 - movdqu xmm0, [eax + 16] // pixels 16..23 - movdqu xmm1, [eax + esi + 16] - lea eax, [eax + 32] - pavgb xmm0, xmm1 - pshufb xmm0, xmm4 - movdqa xmm1, xmmword ptr kMadd21 - pmaddubsw xmm0, xmm1 - paddsw xmm0, xmm7 - psrlw xmm0, 2 - packuswb xmm0, xmm0 - movq qword ptr [edx + 16], xmm0 - lea edx, [edx + 24] - sub ecx, 24 - jg wloop - - pop esi - ret - } -} - -// Note that movdqa+palign may be better than movdqu. -__declspec(naked) void ScaleRowDown34_0_Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_ptr - mov esi, [esp + 4 + 8] // src_stride - mov edx, [esp + 4 + 12] // dst_ptr - mov ecx, [esp + 4 + 16] // dst_width - movdqa xmm2, xmmword ptr kShuf01 - movdqa xmm3, xmmword ptr kShuf11 - movdqa xmm4, xmmword ptr kShuf21 - movdqa xmm5, xmmword ptr kMadd01 - movdqa xmm6, xmmword ptr kMadd11 - movdqa xmm7, xmmword ptr kRound34 - - wloop: - movdqu xmm0, [eax] // pixels 0..7 - movdqu xmm1, [eax + esi] - pavgb xmm1, xmm0 - pavgb xmm0, xmm1 - pshufb xmm0, xmm2 - pmaddubsw xmm0, xmm5 - paddsw xmm0, xmm7 - psrlw xmm0, 2 - packuswb xmm0, xmm0 - movq qword ptr [edx], xmm0 - movdqu xmm0, [eax + 8] // pixels 8..15 - movdqu xmm1, [eax + esi + 8] - pavgb xmm1, xmm0 - pavgb xmm0, xmm1 - pshufb xmm0, xmm3 - pmaddubsw xmm0, xmm6 - paddsw xmm0, xmm7 - psrlw xmm0, 2 - packuswb xmm0, xmm0 - movq qword ptr [edx + 8], xmm0 - movdqu xmm0, [eax + 16] // pixels 16..23 - movdqu xmm1, [eax + esi + 16] - lea eax, [eax + 32] - pavgb xmm1, xmm0 - pavgb xmm0, xmm1 - pshufb xmm0, xmm4 - movdqa xmm1, xmmword ptr kMadd21 - pmaddubsw xmm0, xmm1 - paddsw xmm0, xmm7 - psrlw xmm0, 2 - packuswb xmm0, xmm0 - movq qword ptr [edx + 16], xmm0 - lea edx, [edx+24] - sub ecx, 24 - jg wloop - - pop esi - ret - } -} - -// 3/8 point sampler - -// Scale 32 pixels to 12 -__declspec(naked) void ScaleRowDown38_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - __asm { - mov eax, [esp + 4] // src_ptr - // src_stride ignored - mov edx, [esp + 12] // dst_ptr - mov ecx, [esp + 16] // dst_width - movdqa xmm4, xmmword ptr kShuf38a - movdqa xmm5, xmmword ptr kShuf38b - - xloop: - movdqu xmm0, [eax] // 16 pixels -> 0,1,2,3,4,5 - movdqu xmm1, [eax + 16] // 16 pixels -> 6,7,8,9,10,11 - lea eax, [eax + 32] - pshufb xmm0, xmm4 - pshufb xmm1, xmm5 - paddusb xmm0, xmm1 - - movq qword ptr [edx], xmm0 // write 12 pixels - movhlps xmm1, xmm0 - movd [edx + 8], xmm1 - lea edx, [edx + 12] - sub ecx, 12 - jg xloop - - ret - } -} - -// Scale 16x3 pixels to 6x1 with interpolation -__declspec(naked) void ScaleRowDown38_3_Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_ptr - mov esi, [esp + 4 + 8] // src_stride - mov edx, [esp + 4 + 12] // dst_ptr - mov ecx, [esp + 4 + 16] // dst_width - movdqa xmm2, xmmword ptr kShufAc - movdqa xmm3, xmmword ptr kShufAc3 - movdqa xmm4, xmmword ptr kScaleAc33 - pxor xmm5, xmm5 - - xloop: - movdqu xmm0, [eax] // sum up 3 rows into xmm0/1 - movdqu xmm6, [eax + esi] - movhlps xmm1, xmm0 - movhlps xmm7, xmm6 - punpcklbw xmm0, xmm5 - punpcklbw xmm1, xmm5 - punpcklbw xmm6, xmm5 - punpcklbw xmm7, xmm5 - paddusw xmm0, xmm6 - paddusw xmm1, xmm7 - movdqu xmm6, [eax + esi * 2] - lea eax, [eax + 16] - movhlps xmm7, xmm6 - punpcklbw xmm6, xmm5 - punpcklbw xmm7, xmm5 - paddusw xmm0, xmm6 - paddusw xmm1, xmm7 - - movdqa xmm6, xmm0 // 8 pixels -> 0,1,2 of xmm6 - psrldq xmm0, 2 - paddusw xmm6, xmm0 - psrldq xmm0, 2 - paddusw xmm6, xmm0 - pshufb xmm6, xmm2 - - movdqa xmm7, xmm1 // 8 pixels -> 3,4,5 of xmm6 - psrldq xmm1, 2 - paddusw xmm7, xmm1 - psrldq xmm1, 2 - paddusw xmm7, xmm1 - pshufb xmm7, xmm3 - paddusw xmm6, xmm7 - - pmulhuw xmm6, xmm4 // divide by 9,9,6, 9,9,6 - packuswb xmm6, xmm6 - - movd [edx], xmm6 // write 6 pixels - psrlq xmm6, 16 - movd [edx + 2], xmm6 - lea edx, [edx + 6] - sub ecx, 6 - jg xloop - - pop esi - ret - } -} - -// Scale 16x2 pixels to 6x1 with interpolation -__declspec(naked) void ScaleRowDown38_2_Box_SSSE3(const uint8_t* src_ptr, - ptrdiff_t src_stride, - uint8_t* dst_ptr, - int dst_width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_ptr - mov esi, [esp + 4 + 8] // src_stride - mov edx, [esp + 4 + 12] // dst_ptr - mov ecx, [esp + 4 + 16] // dst_width - movdqa xmm2, xmmword ptr kShufAb0 - movdqa xmm3, xmmword ptr kShufAb1 - movdqa xmm4, xmmword ptr kShufAb2 - movdqa xmm5, xmmword ptr kScaleAb2 - - xloop: - movdqu xmm0, [eax] // average 2 rows into xmm0 - movdqu xmm1, [eax + esi] - lea eax, [eax + 16] - pavgb xmm0, xmm1 - - movdqa xmm1, xmm0 // 16 pixels -> 0,1,2,3,4,5 of xmm1 - pshufb xmm1, xmm2 - movdqa xmm6, xmm0 - pshufb xmm6, xmm3 - paddusw xmm1, xmm6 - pshufb xmm0, xmm4 - paddusw xmm1, xmm0 - - pmulhuw xmm1, xmm5 // divide by 3,3,2, 3,3,2 - packuswb xmm1, xmm1 - - movd [edx], xmm1 // write 6 pixels - psrlq xmm1, 16 - movd [edx + 2], xmm1 - lea edx, [edx + 6] - sub ecx, 6 - jg xloop - - pop esi - ret - } -} - -// Reads 16 bytes and accumulates to 16 shorts at a time. -__declspec(naked) void ScaleAddRow_SSE2(const uint8_t* src_ptr, - uint16_t* dst_ptr, - int src_width) { - __asm { - mov eax, [esp + 4] // src_ptr - mov edx, [esp + 8] // dst_ptr - mov ecx, [esp + 12] // src_width - pxor xmm5, xmm5 - - // sum rows - xloop: - movdqu xmm3, [eax] // read 16 bytes - lea eax, [eax + 16] - movdqu xmm0, [edx] // read 16 words from destination - movdqu xmm1, [edx + 16] - movdqa xmm2, xmm3 - punpcklbw xmm2, xmm5 - punpckhbw xmm3, xmm5 - paddusw xmm0, xmm2 // sum 16 words - paddusw xmm1, xmm3 - movdqu [edx], xmm0 // write 16 words to destination - movdqu [edx + 16], xmm1 - lea edx, [edx + 32] - sub ecx, 16 - jg xloop - ret - } -} - -#ifdef HAS_SCALEADDROW_AVX2 -// Reads 32 bytes and accumulates to 32 shorts at a time. -__declspec(naked) void ScaleAddRow_AVX2(const uint8_t* src_ptr, - uint16_t* dst_ptr, - int src_width) { - __asm { - mov eax, [esp + 4] // src_ptr - mov edx, [esp + 8] // dst_ptr - mov ecx, [esp + 12] // src_width - vpxor ymm5, ymm5, ymm5 - - // sum rows - xloop: - vmovdqu ymm3, [eax] // read 32 bytes - lea eax, [eax + 32] - vpermq ymm3, ymm3, 0xd8 // unmutate for vpunpck - vpunpcklbw ymm2, ymm3, ymm5 - vpunpckhbw ymm3, ymm3, ymm5 - vpaddusw ymm0, ymm2, [edx] // sum 16 words - vpaddusw ymm1, ymm3, [edx + 32] - vmovdqu [edx], ymm0 // write 32 words to destination - vmovdqu [edx + 32], ymm1 - lea edx, [edx + 64] - sub ecx, 32 - jg xloop - - vzeroupper - ret - } -} -#endif // HAS_SCALEADDROW_AVX2 - -// Constant for making pixels signed to avoid pmaddubsw -// saturation. -static const uvec8 kFsub80 = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}; - -// Constant for making pixels unsigned and adding .5 for rounding. -static const uvec16 kFadd40 = {0x4040, 0x4040, 0x4040, 0x4040, - 0x4040, 0x4040, 0x4040, 0x4040}; - -// Bilinear column filtering. SSSE3 version. -__declspec(naked) void ScaleFilterCols_SSSE3(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx) { - __asm { - push ebx - push esi - push edi - mov edi, [esp + 12 + 4] // dst_ptr - mov esi, [esp + 12 + 8] // src_ptr - mov ecx, [esp + 12 + 12] // dst_width - movd xmm2, [esp + 12 + 16] // x - movd xmm3, [esp + 12 + 20] // dx - mov eax, 0x04040000 // shuffle to line up fractions with pixel. - movd xmm5, eax - pcmpeqb xmm6, xmm6 // generate 0x007f for inverting fraction. - psrlw xmm6, 9 - pcmpeqb xmm7, xmm7 // generate 0x0001 - psrlw xmm7, 15 - pextrw eax, xmm2, 1 // get x0 integer. preroll - sub ecx, 2 - jl xloop29 - - movdqa xmm0, xmm2 // x1 = x0 + dx - paddd xmm0, xmm3 - punpckldq xmm2, xmm0 // x0 x1 - punpckldq xmm3, xmm3 // dx dx - paddd xmm3, xmm3 // dx * 2, dx * 2 - pextrw edx, xmm2, 3 // get x1 integer. preroll - - // 2 Pixel loop. - xloop2: - movdqa xmm1, xmm2 // x0, x1 fractions. - paddd xmm2, xmm3 // x += dx - movzx ebx, word ptr [esi + eax] // 2 source x0 pixels - movd xmm0, ebx - psrlw xmm1, 9 // 7 bit fractions. - movzx ebx, word ptr [esi + edx] // 2 source x1 pixels - movd xmm4, ebx - pshufb xmm1, xmm5 // 0011 - punpcklwd xmm0, xmm4 - psubb xmm0, xmmword ptr kFsub80 // make pixels signed. - pxor xmm1, xmm6 // 0..7f and 7f..0 - paddusb xmm1, xmm7 // +1 so 0..7f and 80..1 - pmaddubsw xmm1, xmm0 // 16 bit, 2 pixels. - pextrw eax, xmm2, 1 // get x0 integer. next iteration. - pextrw edx, xmm2, 3 // get x1 integer. next iteration. - paddw xmm1, xmmword ptr kFadd40 // make pixels unsigned and round. - psrlw xmm1, 7 // 8.7 fixed point to low 8 bits. - packuswb xmm1, xmm1 // 8 bits, 2 pixels. - movd ebx, xmm1 - mov [edi], bx - lea edi, [edi + 2] - sub ecx, 2 // 2 pixels - jge xloop2 - - xloop29: - add ecx, 2 - 1 - jl xloop99 - - // 1 pixel remainder - movzx ebx, word ptr [esi + eax] // 2 source x0 pixels - movd xmm0, ebx - psrlw xmm2, 9 // 7 bit fractions. - pshufb xmm2, xmm5 // 0011 - psubb xmm0, xmmword ptr kFsub80 // make pixels signed. - pxor xmm2, xmm6 // 0..7f and 7f..0 - paddusb xmm2, xmm7 // +1 so 0..7f and 80..1 - pmaddubsw xmm2, xmm0 // 16 bit - paddw xmm2, xmmword ptr kFadd40 // make pixels unsigned and round. - psrlw xmm2, 7 // 8.7 fixed point to low 8 bits. - packuswb xmm2, xmm2 // 8 bits - movd ebx, xmm2 - mov [edi], bl - - xloop99: - - pop edi - pop esi - pop ebx - ret - } -} - -// Reads 16 pixels, duplicates them and writes 32 pixels. -__declspec(naked) void ScaleColsUp2_SSE2(uint8_t* dst_ptr, - const uint8_t* src_ptr, - int dst_width, - int x, - int dx) { - __asm { - mov edx, [esp + 4] // dst_ptr - mov eax, [esp + 8] // src_ptr - mov ecx, [esp + 12] // dst_width - - wloop: - movdqu xmm0, [eax] - lea eax, [eax + 16] - movdqa xmm1, xmm0 - punpcklbw xmm0, xmm0 - punpckhbw xmm1, xmm1 - movdqu [edx], xmm0 - movdqu [edx + 16], xmm1 - lea edx, [edx + 32] - sub ecx, 32 - jg wloop - - ret - } -} - -// Reads 8 pixels, throws half away and writes 4 even pixels (0, 2, 4, 6) -__declspec(naked) void ScaleARGBRowDown2_SSE2(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width) { - __asm { - mov eax, [esp + 4] // src_argb - // src_stride ignored - mov edx, [esp + 12] // dst_argb - mov ecx, [esp + 16] // dst_width - - wloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - lea eax, [eax + 32] - shufps xmm0, xmm1, 0xdd - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 4 - jg wloop - - ret - } -} - -// Blends 8x1 rectangle to 4x1. -__declspec(naked) void ScaleARGBRowDown2Linear_SSE2(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width) { - __asm { - mov eax, [esp + 4] // src_argb - // src_stride ignored - mov edx, [esp + 12] // dst_argb - mov ecx, [esp + 16] // dst_width - - wloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - lea eax, [eax + 32] - movdqa xmm2, xmm0 - shufps xmm0, xmm1, 0x88 // even pixels - shufps xmm2, xmm1, 0xdd // odd pixels - pavgb xmm0, xmm2 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 4 - jg wloop - - ret - } -} - -// Blends 8x2 rectangle to 4x1. -__declspec(naked) void ScaleARGBRowDown2Box_SSE2(const uint8_t* src_argb, - ptrdiff_t src_stride, - uint8_t* dst_argb, - int dst_width) { - __asm { - push esi - mov eax, [esp + 4 + 4] // src_argb - mov esi, [esp + 4 + 8] // src_stride - mov edx, [esp + 4 + 12] // dst_argb - mov ecx, [esp + 4 + 16] // dst_width - - wloop: - movdqu xmm0, [eax] - movdqu xmm1, [eax + 16] - movdqu xmm2, [eax + esi] - movdqu xmm3, [eax + esi + 16] - lea eax, [eax + 32] - pavgb xmm0, xmm2 // average rows - pavgb xmm1, xmm3 - movdqa xmm2, xmm0 // average columns (8 to 4 pixels) - shufps xmm0, xmm1, 0x88 // even pixels - shufps xmm2, xmm1, 0xdd // odd pixels - pavgb xmm0, xmm2 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 4 - jg wloop - - pop esi - ret - } -} - -// Reads 4 pixels at a time. -__declspec(naked) void ScaleARGBRowDownEven_SSE2(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width) { - __asm { - push ebx - push edi - mov eax, [esp + 8 + 4] // src_argb - // src_stride ignored - mov ebx, [esp + 8 + 12] // src_stepx - mov edx, [esp + 8 + 16] // dst_argb - mov ecx, [esp + 8 + 20] // dst_width - lea ebx, [ebx * 4] - lea edi, [ebx + ebx * 2] - - wloop: - movd xmm0, [eax] - movd xmm1, [eax + ebx] - punpckldq xmm0, xmm1 - movd xmm2, [eax + ebx * 2] - movd xmm3, [eax + edi] - lea eax, [eax + ebx * 4] - punpckldq xmm2, xmm3 - punpcklqdq xmm0, xmm2 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 4 - jg wloop - - pop edi - pop ebx - ret - } -} - -// Blends four 2x2 to 4x1. -__declspec(naked) void ScaleARGBRowDownEvenBox_SSE2(const uint8_t* src_argb, - ptrdiff_t src_stride, - int src_stepx, - uint8_t* dst_argb, - int dst_width) { - __asm { - push ebx - push esi - push edi - mov eax, [esp + 12 + 4] // src_argb - mov esi, [esp + 12 + 8] // src_stride - mov ebx, [esp + 12 + 12] // src_stepx - mov edx, [esp + 12 + 16] // dst_argb - mov ecx, [esp + 12 + 20] // dst_width - lea esi, [eax + esi] // row1 pointer - lea ebx, [ebx * 4] - lea edi, [ebx + ebx * 2] - - wloop: - movq xmm0, qword ptr [eax] // row0 4 pairs - movhps xmm0, qword ptr [eax + ebx] - movq xmm1, qword ptr [eax + ebx * 2] - movhps xmm1, qword ptr [eax + edi] - lea eax, [eax + ebx * 4] - movq xmm2, qword ptr [esi] // row1 4 pairs - movhps xmm2, qword ptr [esi + ebx] - movq xmm3, qword ptr [esi + ebx * 2] - movhps xmm3, qword ptr [esi + edi] - lea esi, [esi + ebx * 4] - pavgb xmm0, xmm2 // average rows - pavgb xmm1, xmm3 - movdqa xmm2, xmm0 // average columns (8 to 4 pixels) - shufps xmm0, xmm1, 0x88 // even pixels - shufps xmm2, xmm1, 0xdd // odd pixels - pavgb xmm0, xmm2 - movdqu [edx], xmm0 - lea edx, [edx + 16] - sub ecx, 4 - jg wloop - - pop edi - pop esi - pop ebx - ret - } -} - -// Column scaling unfiltered. SSE2 version. -__declspec(naked) void ScaleARGBCols_SSE2(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx) { - __asm { - push edi - push esi - mov edi, [esp + 8 + 4] // dst_argb - mov esi, [esp + 8 + 8] // src_argb - mov ecx, [esp + 8 + 12] // dst_width - movd xmm2, [esp + 8 + 16] // x - movd xmm3, [esp + 8 + 20] // dx - - pshufd xmm2, xmm2, 0 // x0 x0 x0 x0 - pshufd xmm0, xmm3, 0x11 // dx 0 dx 0 - paddd xmm2, xmm0 - paddd xmm3, xmm3 // 0, 0, 0, dx * 2 - pshufd xmm0, xmm3, 0x05 // dx * 2, dx * 2, 0, 0 - paddd xmm2, xmm0 // x3 x2 x1 x0 - paddd xmm3, xmm3 // 0, 0, 0, dx * 4 - pshufd xmm3, xmm3, 0 // dx * 4, dx * 4, dx * 4, dx * 4 - - pextrw eax, xmm2, 1 // get x0 integer. - pextrw edx, xmm2, 3 // get x1 integer. - - cmp ecx, 0 - jle xloop99 - sub ecx, 4 - jl xloop49 - - // 4 Pixel loop. - xloop4: - movd xmm0, [esi + eax * 4] // 1 source x0 pixels - movd xmm1, [esi + edx * 4] // 1 source x1 pixels - pextrw eax, xmm2, 5 // get x2 integer. - pextrw edx, xmm2, 7 // get x3 integer. - paddd xmm2, xmm3 // x += dx - punpckldq xmm0, xmm1 // x0 x1 - - movd xmm1, [esi + eax * 4] // 1 source x2 pixels - movd xmm4, [esi + edx * 4] // 1 source x3 pixels - pextrw eax, xmm2, 1 // get x0 integer. next iteration. - pextrw edx, xmm2, 3 // get x1 integer. next iteration. - punpckldq xmm1, xmm4 // x2 x3 - punpcklqdq xmm0, xmm1 // x0 x1 x2 x3 - movdqu [edi], xmm0 - lea edi, [edi + 16] - sub ecx, 4 // 4 pixels - jge xloop4 - - xloop49: - test ecx, 2 - je xloop29 - - // 2 Pixels. - movd xmm0, [esi + eax * 4] // 1 source x0 pixels - movd xmm1, [esi + edx * 4] // 1 source x1 pixels - pextrw eax, xmm2, 5 // get x2 integer. - punpckldq xmm0, xmm1 // x0 x1 - - movq qword ptr [edi], xmm0 - lea edi, [edi + 8] - - xloop29: - test ecx, 1 - je xloop99 - - // 1 Pixels. - movd xmm0, [esi + eax * 4] // 1 source x2 pixels - movd dword ptr [edi], xmm0 - xloop99: - - pop esi - pop edi - ret - } -} - -// Bilinear row filtering combines 2x1 -> 1x1. SSSE3 version. -// TODO(fbarchard): Port to Neon - -// Shuffle table for arranging 2 pixels into pairs for pmaddubsw -static const uvec8 kShuffleColARGB = { - 0u, 4u, 1u, 5u, 2u, 6u, 3u, 7u, // bbggrraa 1st pixel - 8u, 12u, 9u, 13u, 10u, 14u, 11u, 15u // bbggrraa 2nd pixel -}; - -// Shuffle table for duplicating 2 fractions into 8 bytes each -static const uvec8 kShuffleFractions = { - 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, -}; - -__declspec(naked) void ScaleARGBFilterCols_SSSE3(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx) { - __asm { - push esi - push edi - mov edi, [esp + 8 + 4] // dst_argb - mov esi, [esp + 8 + 8] // src_argb - mov ecx, [esp + 8 + 12] // dst_width - movd xmm2, [esp + 8 + 16] // x - movd xmm3, [esp + 8 + 20] // dx - movdqa xmm4, xmmword ptr kShuffleColARGB - movdqa xmm5, xmmword ptr kShuffleFractions - pcmpeqb xmm6, xmm6 // generate 0x007f for inverting fraction. - psrlw xmm6, 9 - pextrw eax, xmm2, 1 // get x0 integer. preroll - sub ecx, 2 - jl xloop29 - - movdqa xmm0, xmm2 // x1 = x0 + dx - paddd xmm0, xmm3 - punpckldq xmm2, xmm0 // x0 x1 - punpckldq xmm3, xmm3 // dx dx - paddd xmm3, xmm3 // dx * 2, dx * 2 - pextrw edx, xmm2, 3 // get x1 integer. preroll - - // 2 Pixel loop. - xloop2: - movdqa xmm1, xmm2 // x0, x1 fractions. - paddd xmm2, xmm3 // x += dx - movq xmm0, qword ptr [esi + eax * 4] // 2 source x0 pixels - psrlw xmm1, 9 // 7 bit fractions. - movhps xmm0, qword ptr [esi + edx * 4] // 2 source x1 pixels - pshufb xmm1, xmm5 // 0000000011111111 - pshufb xmm0, xmm4 // arrange pixels into pairs - pxor xmm1, xmm6 // 0..7f and 7f..0 - pmaddubsw xmm0, xmm1 // argb_argb 16 bit, 2 pixels. - pextrw eax, xmm2, 1 // get x0 integer. next iteration. - pextrw edx, xmm2, 3 // get x1 integer. next iteration. - psrlw xmm0, 7 // argb 8.7 fixed point to low 8 bits. - packuswb xmm0, xmm0 // argb_argb 8 bits, 2 pixels. - movq qword ptr [edi], xmm0 - lea edi, [edi + 8] - sub ecx, 2 // 2 pixels - jge xloop2 - - xloop29: - - add ecx, 2 - 1 - jl xloop99 - - // 1 pixel remainder - psrlw xmm2, 9 // 7 bit fractions. - movq xmm0, qword ptr [esi + eax * 4] // 2 source x0 pixels - pshufb xmm2, xmm5 // 00000000 - pshufb xmm0, xmm4 // arrange pixels into pairs - pxor xmm2, xmm6 // 0..7f and 7f..0 - pmaddubsw xmm0, xmm2 // argb 16 bit, 1 pixel. - psrlw xmm0, 7 - packuswb xmm0, xmm0 // argb 8 bits, 1 pixel. - movd [edi], xmm0 - - xloop99: - - pop edi - pop esi - ret - } -} - -// Reads 4 pixels, duplicates them and writes 8 pixels. -__declspec(naked) void ScaleARGBColsUp2_SSE2(uint8_t* dst_argb, - const uint8_t* src_argb, - int dst_width, - int x, - int dx) { - __asm { - mov edx, [esp + 4] // dst_argb - mov eax, [esp + 8] // src_argb - mov ecx, [esp + 12] // dst_width - - wloop: - movdqu xmm0, [eax] - lea eax, [eax + 16] - movdqa xmm1, xmm0 - punpckldq xmm0, xmm0 - punpckhdq xmm1, xmm1 - movdqu [edx], xmm0 - movdqu [edx + 16], xmm1 - lea edx, [edx + 32] - sub ecx, 8 - jg wloop - - ret - } -} - -// Divide num by div and return as 16.16 fixed point result. -__declspec(naked) int FixedDiv_X86(int num, int div) { - __asm { - mov eax, [esp + 4] // num - cdq // extend num to 64 bits - shld edx, eax, 16 // 32.16 - shl eax, 16 - idiv dword ptr [esp + 8] - ret - } -} - -// Divide num by div and return as 16.16 fixed point result. -__declspec(naked) int FixedDiv1_X86(int num, int div) { - __asm { - mov eax, [esp + 4] // num - mov ecx, [esp + 8] // denom - cdq // extend num to 64 bits - shld edx, eax, 16 // 32.16 - shl eax, 16 - sub eax, 0x00010001 - sbb edx, 0 - sub ecx, 1 - idiv ecx - ret - } -} -#endif // !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/video_common.cc b/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/video_common.cc deleted file mode 100644 index 92384c05..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/libyuv/source/video_common.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2011 The LibYuv Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "libyuv/video_common.h" - -#ifdef __cplusplus -namespace libyuv { -extern "C" { -#endif - -struct FourCCAliasEntry { - uint32_t alias; - uint32_t canonical; -}; - -#define NUM_ALIASES 18 -static const struct FourCCAliasEntry kFourCCAliases[NUM_ALIASES] = { - {FOURCC_IYUV, FOURCC_I420}, - {FOURCC_YU12, FOURCC_I420}, - {FOURCC_YU16, FOURCC_I422}, - {FOURCC_YU24, FOURCC_I444}, - {FOURCC_YUYV, FOURCC_YUY2}, - {FOURCC_YUVS, FOURCC_YUY2}, // kCMPixelFormat_422YpCbCr8_yuvs - {FOURCC_HDYC, FOURCC_UYVY}, - {FOURCC_2VUY, FOURCC_UYVY}, // kCMPixelFormat_422YpCbCr8 - {FOURCC_JPEG, FOURCC_MJPG}, // Note: JPEG has DHT while MJPG does not. - {FOURCC_DMB1, FOURCC_MJPG}, - {FOURCC_BA81, FOURCC_BGGR}, // deprecated. - {FOURCC_RGB3, FOURCC_RAW}, - {FOURCC_BGR3, FOURCC_24BG}, - {FOURCC_CM32, FOURCC_BGRA}, // kCMPixelFormat_32ARGB - {FOURCC_CM24, FOURCC_RAW}, // kCMPixelFormat_24RGB - {FOURCC_L555, FOURCC_RGBO}, // kCMPixelFormat_16LE555 - {FOURCC_L565, FOURCC_RGBP}, // kCMPixelFormat_16LE565 - {FOURCC_5551, FOURCC_RGBO}, // kCMPixelFormat_16LE5551 -}; -// TODO(fbarchard): Consider mapping kCMPixelFormat_32BGRA to FOURCC_ARGB. -// {FOURCC_BGRA, FOURCC_ARGB}, // kCMPixelFormat_32BGRA - -LIBYUV_API -uint32_t CanonicalFourCC(uint32_t fourcc) { - int i; - for (i = 0; i < NUM_ALIASES; ++i) { - if (kFourCCAliases[i].alias == fourcc) { - return kFourCCAliases[i].canonical; - } - } - // Not an alias, so return it as-is. - return fourcc; -} - -#ifdef __cplusplus -} // extern "C" -} // namespace libyuv -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/x86inc/LICENSE b/presentation/src/main/cpp/third_party/libvpx/third_party/x86inc/LICENSE deleted file mode 100644 index 7d07645a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/x86inc/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -Copyright (C) 2005-2012 x264 project - -Authors: Loren Merritt - Anton Mitrofanov - Jason Garrett-Glaser - Henrik Gramner - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/x86inc/README.libvpx b/presentation/src/main/cpp/third_party/libvpx/third_party/x86inc/README.libvpx deleted file mode 100644 index 195654f7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/x86inc/README.libvpx +++ /dev/null @@ -1,19 +0,0 @@ -URL: https://git.videolan.org/git/x264.git -Version: 3e5aed95cc470f37e2db3e6506a8deb89b527720 -License: ISC -License File: LICENSE - -Description: -x264/libav's framework for x86 assembly. Contains a variety of macros and -defines that help automatically allow assembly to work cross-platform. - -Local Modifications: -Get configuration from vpx_config.asm. -Prefix functions with vpx by default. -Manage name mangling (prefixing with '_') manually because 'PREFIX' does not - exist in libvpx. -Copy PIC 'GLOBAL' macros from x86_abi_support.asm -Use .text instead of .rodata on macho to avoid broken tables in PIC mode. -Use .text with no alignment for aout. -Only use 'hidden' visibility with Chromium. -Prefix ARCH_* with VPX_. diff --git a/presentation/src/main/cpp/third_party/libvpx/third_party/x86inc/x86inc.asm b/presentation/src/main/cpp/third_party/libvpx/third_party/x86inc/x86inc.asm deleted file mode 100644 index 3d55e921..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/third_party/x86inc/x86inc.asm +++ /dev/null @@ -1,1923 +0,0 @@ -;***************************************************************************** -;* x86inc.asm: x264asm abstraction layer -;***************************************************************************** -;* Copyright (C) 2005-2019 x264 project -;* -;* Authors: Loren Merritt -;* Henrik Gramner -;* Anton Mitrofanov -;* Fiona Glaser -;* -;* Permission to use, copy, modify, and/or distribute this software for any -;* purpose with or without fee is hereby granted, provided that the above -;* copyright notice and this permission notice appear in all copies. -;* -;* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -;* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -;* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -;* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -;* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -;* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -;* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -;***************************************************************************** - -; This is a header file for the x264ASM assembly language, which uses -; NASM/YASM syntax combined with a large number of macros to provide easy -; abstraction between different calling conventions (x86_32, win64, linux64). -; It also has various other useful features to simplify writing the kind of -; DSP functions that are most often used in x264. - -; Unlike the rest of x264, this file is available under an ISC license, as it -; has significant usefulness outside of x264 and we want it to be available -; to the largest audience possible. Of course, if you modify it for your own -; purposes to add a new feature, we strongly encourage contributing a patch -; as this feature might be useful for others as well. Send patches or ideas -; to x264-devel@videolan.org . - -%include "vpx_config.asm" - -%ifndef private_prefix - %define private_prefix vpx -%endif - -%ifndef public_prefix - %define public_prefix private_prefix -%endif - -%ifndef STACK_ALIGNMENT - %if VPX_ARCH_X86_64 - %define STACK_ALIGNMENT 16 - %else - %define STACK_ALIGNMENT 4 - %endif -%endif - -%define WIN64 0 -%define UNIX64 0 -%if VPX_ARCH_X86_64 - %ifidn __OUTPUT_FORMAT__,win32 - %define WIN64 1 - %elifidn __OUTPUT_FORMAT__,win64 - %define WIN64 1 - %elifidn __OUTPUT_FORMAT__,x64 - %define WIN64 1 - %else - %define UNIX64 1 - %endif -%endif - -%define FORMAT_ELF 0 -%define FORMAT_MACHO 0 -%ifidn __OUTPUT_FORMAT__,elf - %define FORMAT_ELF 1 -%elifidn __OUTPUT_FORMAT__,elf32 - %define FORMAT_ELF 1 -%elifidn __OUTPUT_FORMAT__,elf64 - %define FORMAT_ELF 1 -%elifidn __OUTPUT_FORMAT__,macho - %define FORMAT_MACHO 1 -%elifidn __OUTPUT_FORMAT__,macho32 - %define FORMAT_MACHO 1 -%elifidn __OUTPUT_FORMAT__,macho64 - %define FORMAT_MACHO 1 -%endif - -; Set PREFIX for libvpx builds. -%if FORMAT_ELF - %undef PREFIX -%elif WIN64 - %undef PREFIX -%else - %define PREFIX -%endif - -%ifdef PREFIX - %define mangle(x) _ %+ x -%else - %define mangle(x) x -%endif - -; In some instances macho32 tables get misaligned when using .rodata. -; When looking at the disassembly it appears that the offset is either -; correct or consistently off by 90. Placing them in the .text section -; works around the issue. It appears to be specific to the way libvpx -; handles the tables. -%macro SECTION_RODATA 0-1 16 - %ifidn __OUTPUT_FORMAT__,win32 - SECTION .rdata align=%1 - %elif WIN64 - SECTION .rdata align=%1 - %elifidn __OUTPUT_FORMAT__,macho32 - SECTION .text align=%1 - fakegot: - %elifidn __OUTPUT_FORMAT__,aout - SECTION .text - %else - SECTION .rodata align=%1 - %endif -%endmacro - -; PIC macros from vpx_ports/x86_abi_support.asm. -%ifidn __OUTPUT_FORMAT__,elf32 -%define ABI_IS_32BIT 1 -%elifidn __OUTPUT_FORMAT__,macho32 -%define ABI_IS_32BIT 1 -%elifidn __OUTPUT_FORMAT__,win32 -%define ABI_IS_32BIT 1 -%elifidn __OUTPUT_FORMAT__,aout -%define ABI_IS_32BIT 1 -%else -%define ABI_IS_32BIT 0 -%endif - -%if ABI_IS_32BIT - %if CONFIG_PIC=1 - %ifidn __OUTPUT_FORMAT__,elf32 - %define GET_GOT_DEFINED 1 - %define WRT_PLT wrt ..plt - %macro GET_GOT 1 - extern _GLOBAL_OFFSET_TABLE_ - push %1 - call %%get_got - %%sub_offset: - jmp %%exitGG - %%get_got: - mov %1, [esp] - add %1, _GLOBAL_OFFSET_TABLE_ + $$ - %%sub_offset wrt ..gotpc - ret - %%exitGG: - %undef GLOBAL - %define GLOBAL(x) x + %1 wrt ..gotoff - %undef RESTORE_GOT - %define RESTORE_GOT pop %1 - %endmacro - %elifidn __OUTPUT_FORMAT__,macho32 - %define GET_GOT_DEFINED 1 - %macro GET_GOT 1 - push %1 - call %%get_got - %%get_got: - pop %1 - %undef GLOBAL - %define GLOBAL(x) x + %1 - %%get_got - %undef RESTORE_GOT - %define RESTORE_GOT pop %1 - %endmacro - %else - %define GET_GOT_DEFINED 0 - %endif - %endif - - %if VPX_ARCH_X86_64 == 0 - %undef PIC - %endif - -%else - %macro GET_GOT 1 - %endmacro - %define GLOBAL(x) rel x - %define WRT_PLT wrt ..plt - - %if WIN64 - %define PIC - %elifidn __OUTPUT_FORMAT__,macho64 - %define PIC - %elif CONFIG_PIC - %define PIC - %endif -%endif - -%ifnmacro GET_GOT - %macro GET_GOT 1 - %endmacro - %define GLOBAL(x) x -%endif -%ifndef RESTORE_GOT - %define RESTORE_GOT -%endif -%ifndef WRT_PLT - %define WRT_PLT -%endif - -%ifdef PIC - default rel -%endif - -%ifndef GET_GOT_DEFINED - %define GET_GOT_DEFINED 0 -%endif -; End PIC macros from vpx_ports/x86_abi_support.asm. - -; libvpx explicitly sets visibilty in shared object builds. Avoid setting -; visibility to hidden as it may break builds that split sources on e.g., -; directory boundaries. -%ifdef CHROMIUM - %define VISIBILITY hidden - %define HAVE_PRIVATE_EXTERN 1 -%else - %define VISIBILITY - %define HAVE_PRIVATE_EXTERN 0 -%endif - -%ifdef __NASM_VER__ - %use smartalign - %if __NASM_VERSION_ID__ < 0x020e0000 ; 2.14 - %define HAVE_PRIVATE_EXTERN 0 - %endif -%endif - -; Macros to eliminate most code duplication between x86_32 and x86_64: -; Currently this works only for leaf functions which load all their arguments -; into registers at the start, and make no other use of the stack. Luckily that -; covers most of x264's asm. - -; PROLOGUE: -; %1 = number of arguments. loads them from stack if needed. -; %2 = number of registers used. pushes callee-saved regs if needed. -; %3 = number of xmm registers used. pushes callee-saved xmm regs if needed. -; %4 = (optional) stack size to be allocated. The stack will be aligned before -; allocating the specified stack size. If the required stack alignment is -; larger than the known stack alignment the stack will be manually aligned -; and an extra register will be allocated to hold the original stack -; pointer (to not invalidate r0m etc.). To prevent the use of an extra -; register as stack pointer, request a negative stack size. -; %4+/%5+ = list of names to define to registers -; PROLOGUE can also be invoked by adding the same options to cglobal - -; e.g. -; cglobal foo, 2,3,7,0x40, dst, src, tmp -; declares a function (foo) that automatically loads two arguments (dst and -; src) into registers, uses one additional register (tmp) plus 7 vector -; registers (m0-m6) and allocates 0x40 bytes of stack space. - -; TODO Some functions can use some args directly from the stack. If they're the -; last args then you can just not declare them, but if they're in the middle -; we need more flexible macro. - -; RET: -; Pops anything that was pushed by PROLOGUE, and returns. - -; REP_RET: -; Use this instead of RET if it's a branch target. - -; registers: -; rN and rNq are the native-size register holding function argument N -; rNd, rNw, rNb are dword, word, and byte size -; rNh is the high 8 bits of the word size -; rNm is the original location of arg N (a register or on the stack), dword -; rNmp is native size - -%macro DECLARE_REG 2-3 - %define r%1q %2 - %define r%1d %2d - %define r%1w %2w - %define r%1b %2b - %define r%1h %2h - %define %2q %2 - %if %0 == 2 - %define r%1m %2d - %define r%1mp %2 - %elif VPX_ARCH_X86_64 ; memory - %define r%1m [rstk + stack_offset + %3] - %define r%1mp qword r %+ %1 %+ m - %else - %define r%1m [rstk + stack_offset + %3] - %define r%1mp dword r %+ %1 %+ m - %endif - %define r%1 %2 -%endmacro - -%macro DECLARE_REG_SIZE 3 - %define r%1q r%1 - %define e%1q r%1 - %define r%1d e%1 - %define e%1d e%1 - %define r%1w %1 - %define e%1w %1 - %define r%1h %3 - %define e%1h %3 - %define r%1b %2 - %define e%1b %2 - %if VPX_ARCH_X86_64 == 0 - %define r%1 e%1 - %endif -%endmacro - -DECLARE_REG_SIZE ax, al, ah -DECLARE_REG_SIZE bx, bl, bh -DECLARE_REG_SIZE cx, cl, ch -DECLARE_REG_SIZE dx, dl, dh -DECLARE_REG_SIZE si, sil, null -DECLARE_REG_SIZE di, dil, null -DECLARE_REG_SIZE bp, bpl, null - -; t# defines for when per-arch register allocation is more complex than just function arguments - -%macro DECLARE_REG_TMP 1-* - %assign %%i 0 - %rep %0 - CAT_XDEFINE t, %%i, r%1 - %assign %%i %%i+1 - %rotate 1 - %endrep -%endmacro - -%macro DECLARE_REG_TMP_SIZE 0-* - %rep %0 - %define t%1q t%1 %+ q - %define t%1d t%1 %+ d - %define t%1w t%1 %+ w - %define t%1h t%1 %+ h - %define t%1b t%1 %+ b - %rotate 1 - %endrep -%endmacro - -DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 - -%if VPX_ARCH_X86_64 - %define gprsize 8 -%else - %define gprsize 4 -%endif - -%macro LEA 2 -%if VPX_ARCH_X86_64 - lea %1, [%2] -%elif PIC - call $+5 ; special-cased to not affect the RSB on most CPU:s - pop %1 - add %1, (%2)-$+1 -%else - mov %1, %2 -%endif -%endmacro - -%macro PUSH 1 - push %1 - %ifidn rstk, rsp - %assign stack_offset stack_offset+gprsize - %endif -%endmacro - -%macro POP 1 - pop %1 - %ifidn rstk, rsp - %assign stack_offset stack_offset-gprsize - %endif -%endmacro - -%macro PUSH_IF_USED 1-* - %rep %0 - %if %1 < regs_used - PUSH r%1 - %endif - %rotate 1 - %endrep -%endmacro - -%macro POP_IF_USED 1-* - %rep %0 - %if %1 < regs_used - pop r%1 - %endif - %rotate 1 - %endrep -%endmacro - -%macro LOAD_IF_USED 1-* - %rep %0 - %if %1 < num_args - mov r%1, r %+ %1 %+ mp - %endif - %rotate 1 - %endrep -%endmacro - -%macro SUB 2 - sub %1, %2 - %ifidn %1, rstk - %assign stack_offset stack_offset+(%2) - %endif -%endmacro - -%macro ADD 2 - add %1, %2 - %ifidn %1, rstk - %assign stack_offset stack_offset-(%2) - %endif -%endmacro - -%macro movifnidn 2 - %ifnidn %1, %2 - mov %1, %2 - %endif -%endmacro - -%if VPX_ARCH_X86_64 == 0 - %define movsxd movifnidn -%endif - -%macro movsxdifnidn 2 - %ifnidn %1, %2 - movsxd %1, %2 - %endif -%endmacro - -%macro ASSERT 1 - %if (%1) == 0 - %error assertion ``%1'' failed - %endif -%endmacro - -%macro DEFINE_ARGS 0-* - %ifdef n_arg_names - %assign %%i 0 - %rep n_arg_names - CAT_UNDEF arg_name %+ %%i, q - CAT_UNDEF arg_name %+ %%i, d - CAT_UNDEF arg_name %+ %%i, w - CAT_UNDEF arg_name %+ %%i, h - CAT_UNDEF arg_name %+ %%i, b - CAT_UNDEF arg_name %+ %%i, m - CAT_UNDEF arg_name %+ %%i, mp - CAT_UNDEF arg_name, %%i - %assign %%i %%i+1 - %endrep - %endif - - %xdefine %%stack_offset stack_offset - %undef stack_offset ; so that the current value of stack_offset doesn't get baked in by xdefine - %assign %%i 0 - %rep %0 - %xdefine %1q r %+ %%i %+ q - %xdefine %1d r %+ %%i %+ d - %xdefine %1w r %+ %%i %+ w - %xdefine %1h r %+ %%i %+ h - %xdefine %1b r %+ %%i %+ b - %xdefine %1m r %+ %%i %+ m - %xdefine %1mp r %+ %%i %+ mp - CAT_XDEFINE arg_name, %%i, %1 - %assign %%i %%i+1 - %rotate 1 - %endrep - %xdefine stack_offset %%stack_offset - %assign n_arg_names %0 -%endmacro - -%define required_stack_alignment ((mmsize + 15) & ~15) -%define vzeroupper_required (mmsize > 16 && (VPX_ARCH_X86_64 == 0 || xmm_regs_used > 16 || notcpuflag(avx512))) -%define high_mm_regs (16*cpuflag(avx512)) - -%macro ALLOC_STACK 1-2 0 ; stack_size, n_xmm_regs (for win64 only) - %ifnum %1 - %if %1 != 0 - %assign %%pad 0 - %assign stack_size %1 - %if stack_size < 0 - %assign stack_size -stack_size - %endif - %if WIN64 - %assign %%pad %%pad + 32 ; shadow space - %if mmsize != 8 - %assign xmm_regs_used %2 - %if xmm_regs_used > 8 - %assign %%pad %%pad + (xmm_regs_used-8)*16 ; callee-saved xmm registers - %endif - %endif - %endif - %if required_stack_alignment <= STACK_ALIGNMENT - ; maintain the current stack alignment - %assign stack_size_padded stack_size + %%pad + ((-%%pad-stack_offset-gprsize) & (STACK_ALIGNMENT-1)) - SUB rsp, stack_size_padded - %else - %assign %%reg_num (regs_used - 1) - %xdefine rstk r %+ %%reg_num - ; align stack, and save original stack location directly above - ; it, i.e. in [rsp+stack_size_padded], so we can restore the - ; stack in a single instruction (i.e. mov rsp, rstk or mov - ; rsp, [rsp+stack_size_padded]) - %if %1 < 0 ; need to store rsp on stack - %xdefine rstkm [rsp + stack_size + %%pad] - %assign %%pad %%pad + gprsize - %else ; can keep rsp in rstk during whole function - %xdefine rstkm rstk - %endif - %assign stack_size_padded stack_size + ((%%pad + required_stack_alignment-1) & ~(required_stack_alignment-1)) - mov rstk, rsp - and rsp, ~(required_stack_alignment-1) - sub rsp, stack_size_padded - movifnidn rstkm, rstk - %endif - WIN64_PUSH_XMM - %endif - %endif -%endmacro - -%macro SETUP_STACK_POINTER 1 - %ifnum %1 - %if %1 != 0 && required_stack_alignment > STACK_ALIGNMENT - %if %1 > 0 - ; Reserve an additional register for storing the original stack pointer, but avoid using - ; eax/rax for this purpose since it can potentially get overwritten as a return value. - %assign regs_used (regs_used + 1) - %if VPX_ARCH_X86_64 && regs_used == 7 - %assign regs_used 8 - %elif VPX_ARCH_X86_64 == 0 && regs_used == 1 - %assign regs_used 2 - %endif - %endif - %if VPX_ARCH_X86_64 && regs_used < 5 + UNIX64 * 3 - ; Ensure that we don't clobber any registers containing arguments. For UNIX64 we also preserve r6 (rax) - ; since it's used as a hidden argument in vararg functions to specify the number of vector registers used. - %assign regs_used 5 + UNIX64 * 3 - %endif - %endif - %endif -%endmacro - -%macro DEFINE_ARGS_INTERNAL 3+ - %ifnum %2 - DEFINE_ARGS %3 - %elif %1 == 4 - DEFINE_ARGS %2 - %elif %1 > 4 - DEFINE_ARGS %2, %3 - %endif -%endmacro - -%if WIN64 ; Windows x64 ;================================================= - -DECLARE_REG 0, rcx -DECLARE_REG 1, rdx -DECLARE_REG 2, R8 -DECLARE_REG 3, R9 -DECLARE_REG 4, R10, 40 -DECLARE_REG 5, R11, 48 -DECLARE_REG 6, rax, 56 -DECLARE_REG 7, rdi, 64 -DECLARE_REG 8, rsi, 72 -DECLARE_REG 9, rbx, 80 -DECLARE_REG 10, rbp, 88 -DECLARE_REG 11, R14, 96 -DECLARE_REG 12, R15, 104 -DECLARE_REG 13, R12, 112 -DECLARE_REG 14, R13, 120 - -%macro PROLOGUE 2-5+ 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... - %assign num_args %1 - %assign regs_used %2 - ASSERT regs_used >= num_args - SETUP_STACK_POINTER %4 - ASSERT regs_used <= 15 - PUSH_IF_USED 7, 8, 9, 10, 11, 12, 13, 14 - ALLOC_STACK %4, %3 - %if mmsize != 8 && stack_size == 0 - WIN64_SPILL_XMM %3 - %endif - LOAD_IF_USED 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 - DEFINE_ARGS_INTERNAL %0, %4, %5 -%endmacro - -%macro WIN64_PUSH_XMM 0 - ; Use the shadow space to store XMM6 and XMM7, the rest needs stack space allocated. - %if xmm_regs_used > 6 + high_mm_regs - movaps [rstk + stack_offset + 8], xmm6 - %endif - %if xmm_regs_used > 7 + high_mm_regs - movaps [rstk + stack_offset + 24], xmm7 - %endif - %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 - %if %%xmm_regs_on_stack > 0 - %assign %%i 8 - %rep %%xmm_regs_on_stack - movaps [rsp + (%%i-8)*16 + stack_size + 32], xmm %+ %%i - %assign %%i %%i+1 - %endrep - %endif -%endmacro - -%macro WIN64_SPILL_XMM 1 - %assign xmm_regs_used %1 - ASSERT xmm_regs_used <= 16 + high_mm_regs - %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 - %if %%xmm_regs_on_stack > 0 - ; Allocate stack space for callee-saved xmm registers plus shadow space and align the stack. - %assign %%pad %%xmm_regs_on_stack*16 + 32 - %assign stack_size_padded %%pad + ((-%%pad-stack_offset-gprsize) & (STACK_ALIGNMENT-1)) - SUB rsp, stack_size_padded - %endif - WIN64_PUSH_XMM -%endmacro - -%macro WIN64_RESTORE_XMM_INTERNAL 0 - %assign %%pad_size 0 - %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 - %if %%xmm_regs_on_stack > 0 - %assign %%i xmm_regs_used - high_mm_regs - %rep %%xmm_regs_on_stack - %assign %%i %%i-1 - movaps xmm %+ %%i, [rsp + (%%i-8)*16 + stack_size + 32] - %endrep - %endif - %if stack_size_padded > 0 - %if stack_size > 0 && required_stack_alignment > STACK_ALIGNMENT - mov rsp, rstkm - %else - add rsp, stack_size_padded - %assign %%pad_size stack_size_padded - %endif - %endif - %if xmm_regs_used > 7 + high_mm_regs - movaps xmm7, [rsp + stack_offset - %%pad_size + 24] - %endif - %if xmm_regs_used > 6 + high_mm_regs - movaps xmm6, [rsp + stack_offset - %%pad_size + 8] - %endif -%endmacro - -%macro WIN64_RESTORE_XMM 0 - WIN64_RESTORE_XMM_INTERNAL - %assign stack_offset (stack_offset-stack_size_padded) - %assign stack_size_padded 0 - %assign xmm_regs_used 0 -%endmacro - -%define has_epilogue regs_used > 7 || stack_size > 0 || vzeroupper_required || xmm_regs_used > 6+high_mm_regs - -%macro RET 0 - WIN64_RESTORE_XMM_INTERNAL - POP_IF_USED 14, 13, 12, 11, 10, 9, 8, 7 - %if vzeroupper_required - vzeroupper - %endif - AUTO_REP_RET -%endmacro - -%elif VPX_ARCH_X86_64 ; *nix x64 ;============================================= - -DECLARE_REG 0, rdi -DECLARE_REG 1, rsi -DECLARE_REG 2, rdx -DECLARE_REG 3, rcx -DECLARE_REG 4, R8 -DECLARE_REG 5, R9 -DECLARE_REG 6, rax, 8 -DECLARE_REG 7, R10, 16 -DECLARE_REG 8, R11, 24 -DECLARE_REG 9, rbx, 32 -DECLARE_REG 10, rbp, 40 -DECLARE_REG 11, R14, 48 -DECLARE_REG 12, R15, 56 -DECLARE_REG 13, R12, 64 -DECLARE_REG 14, R13, 72 - -%macro PROLOGUE 2-5+ 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... - %assign num_args %1 - %assign regs_used %2 - %assign xmm_regs_used %3 - ASSERT regs_used >= num_args - SETUP_STACK_POINTER %4 - ASSERT regs_used <= 15 - PUSH_IF_USED 9, 10, 11, 12, 13, 14 - ALLOC_STACK %4 - LOAD_IF_USED 6, 7, 8, 9, 10, 11, 12, 13, 14 - DEFINE_ARGS_INTERNAL %0, %4, %5 -%endmacro - -%define has_epilogue regs_used > 9 || stack_size > 0 || vzeroupper_required - -%macro RET 0 - %if stack_size_padded > 0 - %if required_stack_alignment > STACK_ALIGNMENT - mov rsp, rstkm - %else - add rsp, stack_size_padded - %endif - %endif - POP_IF_USED 14, 13, 12, 11, 10, 9 - %if vzeroupper_required - vzeroupper - %endif - AUTO_REP_RET -%endmacro - -%else ; X86_32 ;============================================================== - -DECLARE_REG 0, eax, 4 -DECLARE_REG 1, ecx, 8 -DECLARE_REG 2, edx, 12 -DECLARE_REG 3, ebx, 16 -DECLARE_REG 4, esi, 20 -DECLARE_REG 5, edi, 24 -DECLARE_REG 6, ebp, 28 -%define rsp esp - -%macro DECLARE_ARG 1-* - %rep %0 - %define r%1m [rstk + stack_offset + 4*%1 + 4] - %define r%1mp dword r%1m - %rotate 1 - %endrep -%endmacro - -DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14 - -%macro PROLOGUE 2-5+ ; #args, #regs, #xmm_regs, [stack_size,] arg_names... - %assign num_args %1 - %assign regs_used %2 - ASSERT regs_used >= num_args - %if num_args > 7 - %assign num_args 7 - %endif - %if regs_used > 7 - %assign regs_used 7 - %endif - SETUP_STACK_POINTER %4 - ASSERT regs_used <= 7 - PUSH_IF_USED 3, 4, 5, 6 - ALLOC_STACK %4 - LOAD_IF_USED 0, 1, 2, 3, 4, 5, 6 - DEFINE_ARGS_INTERNAL %0, %4, %5 -%endmacro - -%define has_epilogue regs_used > 3 || stack_size > 0 || vzeroupper_required - -%macro RET 0 - %if stack_size_padded > 0 - %if required_stack_alignment > STACK_ALIGNMENT - mov rsp, rstkm - %else - add rsp, stack_size_padded - %endif - %endif - POP_IF_USED 6, 5, 4, 3 - %if vzeroupper_required - vzeroupper - %endif - AUTO_REP_RET -%endmacro - -%endif ;====================================================================== - -%if WIN64 == 0 - %macro WIN64_SPILL_XMM 1 - %endmacro - %macro WIN64_RESTORE_XMM 0 - %endmacro - %macro WIN64_PUSH_XMM 0 - %endmacro -%endif - -; On AMD cpus <=K10, an ordinary ret is slow if it immediately follows either -; a branch or a branch target. So switch to a 2-byte form of ret in that case. -; We can automatically detect "follows a branch", but not a branch target. -; (SSSE3 is a sufficient condition to know that your cpu doesn't have this problem.) -%macro REP_RET 0 - %if has_epilogue || cpuflag(ssse3) - RET - %else - rep ret - %endif - annotate_function_size -%endmacro - -%define last_branch_adr $$ -%macro AUTO_REP_RET 0 - %if notcpuflag(ssse3) - times ((last_branch_adr-$)>>31)+1 rep ; times 1 iff $ == last_branch_adr. - %endif - ret - annotate_function_size -%endmacro - -%macro BRANCH_INSTR 0-* - %rep %0 - %macro %1 1-2 %1 - %2 %1 - %if notcpuflag(ssse3) - %%branch_instr equ $ - %xdefine last_branch_adr %%branch_instr - %endif - %endmacro - %rotate 1 - %endrep -%endmacro - -BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, jna, jnae, jb, jbe, jnb, jnbe, jc, jnc, js, jns, jo, jno, jp, jnp - -%macro TAIL_CALL 1-2 1 ; callee, is_nonadjacent - %if has_epilogue - call %1 - RET - %elif %2 - jmp %1 - %endif - annotate_function_size -%endmacro - -;============================================================================= -; arch-independent part -;============================================================================= - -%assign function_align 16 - -; Begin a function. -; Applies any symbol mangling needed for C linkage, and sets up a define such that -; subsequent uses of the function name automatically refer to the mangled version. -; Appends cpuflags to the function name if cpuflags has been specified. -; The "" empty default parameter is a workaround for nasm, which fails if SUFFIX -; is empty and we call cglobal_internal with just %1 %+ SUFFIX (without %2). -%macro cglobal 1-2+ "" ; name, [PROLOGUE args] - cglobal_internal 1, %1 %+ SUFFIX, %2 -%endmacro -%macro cvisible 1-2+ "" ; name, [PROLOGUE args] - cglobal_internal 0, %1 %+ SUFFIX, %2 -%endmacro -%macro cglobal_internal 2-3+ - annotate_function_size - %ifndef cglobaled_%2 - %if %1 - %xdefine %2 mangle(private_prefix %+ _ %+ %2) - %else - %xdefine %2 mangle(public_prefix %+ _ %+ %2) - %endif - %xdefine %2.skip_prologue %2 %+ .skip_prologue - CAT_XDEFINE cglobaled_, %2, 1 - %endif - %xdefine current_function %2 - %xdefine current_function_section __SECT__ - %if FORMAT_ELF - %if %1 - global %2:function VISIBILITY - %else - global %2:function - %endif - %elif FORMAT_MACHO && HAVE_PRIVATE_EXTERN && %1 - global %2:private_extern - %else - global %2 - %endif - align function_align - %2: - RESET_MM_PERMUTATION ; needed for x86-64, also makes disassembly somewhat nicer - %xdefine rstk rsp ; copy of the original stack pointer, used when greater alignment than the known stack alignment is required - %assign stack_offset 0 ; stack pointer offset relative to the return address - %assign stack_size 0 ; amount of stack space that can be freely used inside a function - %assign stack_size_padded 0 ; total amount of allocated stack space, including space for callee-saved xmm registers on WIN64 and alignment padding - %assign xmm_regs_used 0 ; number of XMM registers requested, used for dealing with callee-saved registers on WIN64 and vzeroupper - %ifnidn %3, "" - PROLOGUE %3 - %endif -%endmacro - -; Create a global symbol from a local label with the correct name mangling and type -%macro cglobal_label 1 - %if FORMAT_ELF - global current_function %+ %1:function VISIBILITY - %elif FORMAT_MACHO && HAVE_PRIVATE_EXTERN - global current_function %+ %1:private_extern - %else - global current_function %+ %1 - %endif - %1: -%endmacro - -%macro cextern 1 - %xdefine %1 mangle(private_prefix %+ _ %+ %1) - CAT_XDEFINE cglobaled_, %1, 1 - extern %1 -%endmacro - -; like cextern, but without the prefix -%macro cextern_naked 1 - %ifdef PREFIX - %xdefine %1 mangle(%1) - %endif - CAT_XDEFINE cglobaled_, %1, 1 - extern %1 -%endmacro - -%macro const 1-2+ - %xdefine %1 mangle(private_prefix %+ _ %+ %1) - %if FORMAT_ELF - global %1:data VISIBILITY - %elif FORMAT_MACHO && HAVE_PRIVATE_EXTERN - global %1:private_extern - %else - global %1 - %endif - %1: %2 -%endmacro - -; This is needed for ELF, otherwise the GNU linker assumes the stack is executable by default. -%if FORMAT_ELF - [SECTION .note.GNU-stack noalloc noexec nowrite progbits] -%endif - -; Tell debuggers how large the function was. -; This may be invoked multiple times per function; we rely on later instances overriding earlier ones. -; This is invoked by RET and similar macros, and also cglobal does it for the previous function, -; but if the last function in a source file doesn't use any of the standard macros for its epilogue, -; then its size might be unspecified. -%macro annotate_function_size 0 - %ifdef __YASM_VER__ - %ifdef current_function - %if FORMAT_ELF - current_function_section - %%ecf equ $ - size current_function %%ecf - current_function - __SECT__ - %endif - %endif - %endif -%endmacro - -; cpuflags - -%assign cpuflags_mmx (1<<0) -%assign cpuflags_mmx2 (1<<1) | cpuflags_mmx -%assign cpuflags_3dnow (1<<2) | cpuflags_mmx -%assign cpuflags_3dnowext (1<<3) | cpuflags_3dnow -%assign cpuflags_sse (1<<4) | cpuflags_mmx2 -%assign cpuflags_sse2 (1<<5) | cpuflags_sse -%assign cpuflags_sse2slow (1<<6) | cpuflags_sse2 -%assign cpuflags_lzcnt (1<<7) | cpuflags_sse2 -%assign cpuflags_sse3 (1<<8) | cpuflags_sse2 -%assign cpuflags_ssse3 (1<<9) | cpuflags_sse3 -%assign cpuflags_sse4 (1<<10)| cpuflags_ssse3 -%assign cpuflags_sse42 (1<<11)| cpuflags_sse4 -%assign cpuflags_aesni (1<<12)| cpuflags_sse42 -%assign cpuflags_gfni (1<<13)| cpuflags_sse42 -%assign cpuflags_avx (1<<14)| cpuflags_sse42 -%assign cpuflags_xop (1<<15)| cpuflags_avx -%assign cpuflags_fma4 (1<<16)| cpuflags_avx -%assign cpuflags_fma3 (1<<17)| cpuflags_avx -%assign cpuflags_bmi1 (1<<18)| cpuflags_avx|cpuflags_lzcnt -%assign cpuflags_bmi2 (1<<19)| cpuflags_bmi1 -%assign cpuflags_avx2 (1<<20)| cpuflags_fma3|cpuflags_bmi2 -%assign cpuflags_avx512 (1<<21)| cpuflags_avx2 ; F, CD, BW, DQ, VL - -%assign cpuflags_cache32 (1<<22) -%assign cpuflags_cache64 (1<<23) -%assign cpuflags_aligned (1<<24) ; not a cpu feature, but a function variant -%assign cpuflags_atom (1<<25) - -; Returns a boolean value expressing whether or not the specified cpuflag is enabled. -%define cpuflag(x) (((((cpuflags & (cpuflags_ %+ x)) ^ (cpuflags_ %+ x)) - 1) >> 31) & 1) -%define notcpuflag(x) (cpuflag(x) ^ 1) - -; Takes an arbitrary number of cpuflags from the above list. -; All subsequent functions (up to the next INIT_CPUFLAGS) is built for the specified cpu. -; You shouldn't need to invoke this macro directly, it's a subroutine for INIT_MMX &co. -%macro INIT_CPUFLAGS 0-* - %xdefine SUFFIX - %undef cpuname - %assign cpuflags 0 - - %if %0 >= 1 - %rep %0 - %ifdef cpuname - %xdefine cpuname cpuname %+ _%1 - %else - %xdefine cpuname %1 - %endif - %assign cpuflags cpuflags | cpuflags_%1 - %rotate 1 - %endrep - %xdefine SUFFIX _ %+ cpuname - - %if cpuflag(avx) - %assign avx_enabled 1 - %endif - %if (mmsize == 16 && notcpuflag(sse2)) || (mmsize == 32 && notcpuflag(avx2)) - %define mova movaps - %define movu movups - %define movnta movntps - %endif - %if cpuflag(aligned) - %define movu mova - %elif cpuflag(sse3) && notcpuflag(ssse3) - %define movu lddqu - %endif - %endif - - %if VPX_ARCH_X86_64 || cpuflag(sse2) - %ifdef __NASM_VER__ - ALIGNMODE p6 - %else - CPU amdnop - %endif - %else - %ifdef __NASM_VER__ - ALIGNMODE nop - %else - CPU basicnop - %endif - %endif -%endmacro - -; Merge mmx, sse*, and avx* -; m# is a simd register of the currently selected size -; xm# is the corresponding xmm register if mmsize >= 16, otherwise the same as m# -; ym# is the corresponding ymm register if mmsize >= 32, otherwise the same as m# -; zm# is the corresponding zmm register if mmsize >= 64, otherwise the same as m# -; (All 4 remain in sync through SWAP.) - -%macro CAT_XDEFINE 3 - %xdefine %1%2 %3 -%endmacro - -%macro CAT_UNDEF 2 - %undef %1%2 -%endmacro - -%macro DEFINE_MMREGS 1 ; mmtype - %assign %%prev_mmregs 0 - %ifdef num_mmregs - %assign %%prev_mmregs num_mmregs - %endif - - %assign num_mmregs 8 - %if VPX_ARCH_X86_64 && mmsize >= 16 - %assign num_mmregs 16 - %if cpuflag(avx512) || mmsize == 64 - %assign num_mmregs 32 - %endif - %endif - - %assign %%i 0 - %rep num_mmregs - CAT_XDEFINE m, %%i, %1 %+ %%i - CAT_XDEFINE nn%1, %%i, %%i - %assign %%i %%i+1 - %endrep - %if %%prev_mmregs > num_mmregs - %rep %%prev_mmregs - num_mmregs - CAT_UNDEF m, %%i - CAT_UNDEF nn %+ mmtype, %%i - %assign %%i %%i+1 - %endrep - %endif - %xdefine mmtype %1 -%endmacro - -; Prefer registers 16-31 over 0-15 to avoid having to use vzeroupper -%macro AVX512_MM_PERMUTATION 0-1 0 ; start_reg - %if VPX_ARCH_X86_64 && cpuflag(avx512) - %assign %%i %1 - %rep 16-%1 - %assign %%i_high %%i+16 - SWAP %%i, %%i_high - %assign %%i %%i+1 - %endrep - %endif -%endmacro - -%macro INIT_MMX 0-1+ - %assign avx_enabled 0 - %define RESET_MM_PERMUTATION INIT_MMX %1 - %define mmsize 8 - %define mova movq - %define movu movq - %define movh movd - %define movnta movntq - INIT_CPUFLAGS %1 - DEFINE_MMREGS mm -%endmacro - -%macro INIT_XMM 0-1+ - %assign avx_enabled 0 - %define RESET_MM_PERMUTATION INIT_XMM %1 - %define mmsize 16 - %define mova movdqa - %define movu movdqu - %define movh movq - %define movnta movntdq - INIT_CPUFLAGS %1 - DEFINE_MMREGS xmm - %if WIN64 - AVX512_MM_PERMUTATION 6 ; Swap callee-saved registers with volatile registers - %endif -%endmacro - -%macro INIT_YMM 0-1+ - %assign avx_enabled 1 - %define RESET_MM_PERMUTATION INIT_YMM %1 - %define mmsize 32 - %define mova movdqa - %define movu movdqu - %undef movh - %define movnta movntdq - INIT_CPUFLAGS %1 - DEFINE_MMREGS ymm - AVX512_MM_PERMUTATION -%endmacro - -%macro INIT_ZMM 0-1+ - %assign avx_enabled 1 - %define RESET_MM_PERMUTATION INIT_ZMM %1 - %define mmsize 64 - %define mova movdqa - %define movu movdqu - %undef movh - %define movnta movntdq - INIT_CPUFLAGS %1 - DEFINE_MMREGS zmm - AVX512_MM_PERMUTATION -%endmacro - -INIT_XMM - -%macro DECLARE_MMCAST 1 - %define mmmm%1 mm%1 - %define mmxmm%1 mm%1 - %define mmymm%1 mm%1 - %define mmzmm%1 mm%1 - %define xmmmm%1 mm%1 - %define xmmxmm%1 xmm%1 - %define xmmymm%1 xmm%1 - %define xmmzmm%1 xmm%1 - %define ymmmm%1 mm%1 - %define ymmxmm%1 xmm%1 - %define ymmymm%1 ymm%1 - %define ymmzmm%1 ymm%1 - %define zmmmm%1 mm%1 - %define zmmxmm%1 xmm%1 - %define zmmymm%1 ymm%1 - %define zmmzmm%1 zmm%1 - %define xm%1 xmm %+ m%1 - %define ym%1 ymm %+ m%1 - %define zm%1 zmm %+ m%1 -%endmacro - -%assign i 0 -%rep 32 - DECLARE_MMCAST i - %assign i i+1 -%endrep - -; I often want to use macros that permute their arguments. e.g. there's no -; efficient way to implement butterfly or transpose or dct without swapping some -; arguments. -; -; I would like to not have to manually keep track of the permutations: -; If I insert a permutation in the middle of a function, it should automatically -; change everything that follows. For more complex macros I may also have multiple -; implementations, e.g. the SSE2 and SSSE3 versions may have different permutations. -; -; Hence these macros. Insert a PERMUTE or some SWAPs at the end of a macro that -; permutes its arguments. It's equivalent to exchanging the contents of the -; registers, except that this way you exchange the register names instead, so it -; doesn't cost any cycles. - -%macro PERMUTE 2-* ; takes a list of pairs to swap - %rep %0/2 - %xdefine %%tmp%2 m%2 - %rotate 2 - %endrep - %rep %0/2 - %xdefine m%1 %%tmp%2 - CAT_XDEFINE nn, m%1, %1 - %rotate 2 - %endrep -%endmacro - -%macro SWAP 2+ ; swaps a single chain (sometimes more concise than pairs) - %ifnum %1 ; SWAP 0, 1, ... - SWAP_INTERNAL_NUM %1, %2 - %else ; SWAP m0, m1, ... - SWAP_INTERNAL_NAME %1, %2 - %endif -%endmacro - -%macro SWAP_INTERNAL_NUM 2-* - %rep %0-1 - %xdefine %%tmp m%1 - %xdefine m%1 m%2 - %xdefine m%2 %%tmp - CAT_XDEFINE nn, m%1, %1 - CAT_XDEFINE nn, m%2, %2 - %rotate 1 - %endrep -%endmacro - -%macro SWAP_INTERNAL_NAME 2-* - %xdefine %%args nn %+ %1 - %rep %0-1 - %xdefine %%args %%args, nn %+ %2 - %rotate 1 - %endrep - SWAP_INTERNAL_NUM %%args -%endmacro - -; If SAVE_MM_PERMUTATION is placed at the end of a function, then any later -; calls to that function will automatically load the permutation, so values can -; be returned in mmregs. -%macro SAVE_MM_PERMUTATION 0-1 - %if %0 - %xdefine %%f %1_m - %else - %xdefine %%f current_function %+ _m - %endif - %assign %%i 0 - %rep num_mmregs - %xdefine %%tmp m %+ %%i - CAT_XDEFINE %%f, %%i, regnumof %+ %%tmp - %assign %%i %%i+1 - %endrep -%endmacro - -%macro LOAD_MM_PERMUTATION 0-1 ; name to load from - %if %0 - %xdefine %%f %1_m - %else - %xdefine %%f current_function %+ _m - %endif - %xdefine %%tmp %%f %+ 0 - %ifnum %%tmp - RESET_MM_PERMUTATION - %assign %%i 0 - %rep num_mmregs - %xdefine %%tmp %%f %+ %%i - CAT_XDEFINE %%m, %%i, m %+ %%tmp - %assign %%i %%i+1 - %endrep - %rep num_mmregs - %assign %%i %%i-1 - CAT_XDEFINE m, %%i, %%m %+ %%i - CAT_XDEFINE nn, m %+ %%i, %%i - %endrep - %endif -%endmacro - -; Append cpuflags to the callee's name iff the appended name is known and the plain name isn't -%macro call 1 - %ifid %1 - call_internal %1 %+ SUFFIX, %1 - %else - call %1 - %endif -%endmacro -%macro call_internal 2 - %xdefine %%i %2 - %ifndef cglobaled_%2 - %ifdef cglobaled_%1 - %xdefine %%i %1 - %endif - %endif - call %%i - LOAD_MM_PERMUTATION %%i -%endmacro - -; Substitutions that reduce instruction size but are functionally equivalent -%macro add 2 - %ifnum %2 - %if %2==128 - sub %1, -128 - %else - add %1, %2 - %endif - %else - add %1, %2 - %endif -%endmacro - -%macro sub 2 - %ifnum %2 - %if %2==128 - add %1, -128 - %else - sub %1, %2 - %endif - %else - sub %1, %2 - %endif -%endmacro - -;============================================================================= -; AVX abstraction layer -;============================================================================= - -%assign i 0 -%rep 32 - %if i < 8 - CAT_XDEFINE sizeofmm, i, 8 - CAT_XDEFINE regnumofmm, i, i - %endif - CAT_XDEFINE sizeofxmm, i, 16 - CAT_XDEFINE sizeofymm, i, 32 - CAT_XDEFINE sizeofzmm, i, 64 - CAT_XDEFINE regnumofxmm, i, i - CAT_XDEFINE regnumofymm, i, i - CAT_XDEFINE regnumofzmm, i, i - %assign i i+1 -%endrep -%undef i - -%macro CHECK_AVX_INSTR_EMU 3-* - %xdefine %%opcode %1 - %xdefine %%dst %2 - %rep %0-2 - %ifidn %%dst, %3 - %error non-avx emulation of ``%%opcode'' is not supported - %endif - %rotate 1 - %endrep -%endmacro - -;%1 == instruction -;%2 == minimal instruction set -;%3 == 1 if float, 0 if int -;%4 == 1 if 4-operand emulation, 0 if 3-operand emulation, 255 otherwise (no emulation) -;%5 == 1 if commutative (i.e. doesn't matter which src arg is which), 0 if not -;%6+: operands -%macro RUN_AVX_INSTR 6-9+ - %ifnum sizeof%7 - %assign __sizeofreg sizeof%7 - %elifnum sizeof%6 - %assign __sizeofreg sizeof%6 - %else - %assign __sizeofreg mmsize - %endif - %assign __emulate_avx 0 - %if avx_enabled && __sizeofreg >= 16 - %xdefine __instr v%1 - %else - %xdefine __instr %1 - %if %0 >= 8+%4 - %assign __emulate_avx 1 - %endif - %endif - %ifnidn %2, fnord - %ifdef cpuname - %if notcpuflag(%2) - %error use of ``%1'' %2 instruction in cpuname function: current_function - %elif %3 == 0 && __sizeofreg == 16 && notcpuflag(sse2) - %error use of ``%1'' sse2 instruction in cpuname function: current_function - %elif %3 == 0 && __sizeofreg == 32 && notcpuflag(avx2) - %error use of ``%1'' avx2 instruction in cpuname function: current_function - %elif __sizeofreg == 16 && notcpuflag(sse) - %error use of ``%1'' sse instruction in cpuname function: current_function - %elif __sizeofreg == 32 && notcpuflag(avx) - %error use of ``%1'' avx instruction in cpuname function: current_function - %elif __sizeofreg == 64 && notcpuflag(avx512) - %error use of ``%1'' avx512 instruction in cpuname function: current_function - %elifidn %1, pextrw ; special case because the base instruction is mmx2, - %ifnid %6 ; but sse4 is required for memory operands - %if notcpuflag(sse4) - %error use of ``%1'' sse4 instruction in cpuname function: current_function - %endif - %endif - %endif - %endif - %endif - - %if __emulate_avx - %xdefine __src1 %7 - %xdefine __src2 %8 - %if %5 && %4 == 0 - %ifnidn %6, %7 - %ifidn %6, %8 - %xdefine __src1 %8 - %xdefine __src2 %7 - %elifnnum sizeof%8 - ; 3-operand AVX instructions with a memory arg can only have it in src2, - ; whereas SSE emulation prefers to have it in src1 (i.e. the mov). - ; So, if the instruction is commutative with a memory arg, swap them. - %xdefine __src1 %8 - %xdefine __src2 %7 - %endif - %endif - %endif - %ifnidn %6, __src1 - %if %0 >= 9 - CHECK_AVX_INSTR_EMU {%1 %6, %7, %8, %9}, %6, __src2, %9 - %else - CHECK_AVX_INSTR_EMU {%1 %6, %7, %8}, %6, __src2 - %endif - %if __sizeofreg == 8 - MOVQ %6, __src1 - %elif %3 - MOVAPS %6, __src1 - %else - MOVDQA %6, __src1 - %endif - %endif - %if %0 >= 9 - %1 %6, __src2, %9 - %else - %1 %6, __src2 - %endif - %elif %0 >= 9 - __instr %6, %7, %8, %9 - %elif %0 == 8 - %if avx_enabled && %5 - %xdefine __src1 %7 - %xdefine __src2 %8 - %ifnum regnumof%7 - %ifnum regnumof%8 - %if regnumof%7 < 8 && regnumof%8 >= 8 && regnumof%8 < 16 && sizeof%8 <= 32 - ; Most VEX-encoded instructions require an additional byte to encode when - ; src2 is a high register (e.g. m8..15). If the instruction is commutative - ; we can swap src1 and src2 when doing so reduces the instruction length. - %xdefine __src1 %8 - %xdefine __src2 %7 - %endif - %endif - %endif - __instr %6, __src1, __src2 - %else - __instr %6, %7, %8 - %endif - %elif %0 == 7 - %if avx_enabled && %5 - %xdefine __src1 %6 - %xdefine __src2 %7 - %ifnum regnumof%6 - %ifnum regnumof%7 - %if regnumof%6 < 8 && regnumof%7 >= 8 && regnumof%7 < 16 && sizeof%7 <= 32 - %xdefine __src1 %7 - %xdefine __src2 %6 - %endif - %endif - %endif - __instr %6, __src1, __src2 - %else - __instr %6, %7 - %endif - %else - __instr %6 - %endif -%endmacro - -;%1 == instruction -;%2 == minimal instruction set -;%3 == 1 if float, 0 if int -;%4 == 1 if 4-operand emulation, 0 if 3-operand emulation, 255 otherwise (no emulation) -;%5 == 1 if commutative (i.e. doesn't matter which src arg is which), 0 if not -%macro AVX_INSTR 1-5 fnord, 0, 255, 0 - %macro %1 1-10 fnord, fnord, fnord, fnord, %1, %2, %3, %4, %5 - %ifidn %2, fnord - RUN_AVX_INSTR %6, %7, %8, %9, %10, %1 - %elifidn %3, fnord - RUN_AVX_INSTR %6, %7, %8, %9, %10, %1, %2 - %elifidn %4, fnord - RUN_AVX_INSTR %6, %7, %8, %9, %10, %1, %2, %3 - %elifidn %5, fnord - RUN_AVX_INSTR %6, %7, %8, %9, %10, %1, %2, %3, %4 - %else - RUN_AVX_INSTR %6, %7, %8, %9, %10, %1, %2, %3, %4, %5 - %endif - %endmacro -%endmacro - -; Instructions with both VEX/EVEX and legacy encodings -; Non-destructive instructions are written without parameters -AVX_INSTR addpd, sse2, 1, 0, 1 -AVX_INSTR addps, sse, 1, 0, 1 -AVX_INSTR addsd, sse2, 1, 0, 0 -AVX_INSTR addss, sse, 1, 0, 0 -AVX_INSTR addsubpd, sse3, 1, 0, 0 -AVX_INSTR addsubps, sse3, 1, 0, 0 -AVX_INSTR aesdec, aesni, 0, 0, 0 -AVX_INSTR aesdeclast, aesni, 0, 0, 0 -AVX_INSTR aesenc, aesni, 0, 0, 0 -AVX_INSTR aesenclast, aesni, 0, 0, 0 -AVX_INSTR aesimc, aesni -AVX_INSTR aeskeygenassist, aesni -AVX_INSTR andnpd, sse2, 1, 0, 0 -AVX_INSTR andnps, sse, 1, 0, 0 -AVX_INSTR andpd, sse2, 1, 0, 1 -AVX_INSTR andps, sse, 1, 0, 1 -AVX_INSTR blendpd, sse4, 1, 1, 0 -AVX_INSTR blendps, sse4, 1, 1, 0 -AVX_INSTR blendvpd, sse4 ; can't be emulated -AVX_INSTR blendvps, sse4 ; can't be emulated -AVX_INSTR cmpeqpd, sse2, 1, 0, 1 -AVX_INSTR cmpeqps, sse, 1, 0, 1 -AVX_INSTR cmpeqsd, sse2, 1, 0, 0 -AVX_INSTR cmpeqss, sse, 1, 0, 0 -AVX_INSTR cmplepd, sse2, 1, 0, 0 -AVX_INSTR cmpleps, sse, 1, 0, 0 -AVX_INSTR cmplesd, sse2, 1, 0, 0 -AVX_INSTR cmpless, sse, 1, 0, 0 -AVX_INSTR cmpltpd, sse2, 1, 0, 0 -AVX_INSTR cmpltps, sse, 1, 0, 0 -AVX_INSTR cmpltsd, sse2, 1, 0, 0 -AVX_INSTR cmpltss, sse, 1, 0, 0 -AVX_INSTR cmpneqpd, sse2, 1, 0, 1 -AVX_INSTR cmpneqps, sse, 1, 0, 1 -AVX_INSTR cmpneqsd, sse2, 1, 0, 0 -AVX_INSTR cmpneqss, sse, 1, 0, 0 -AVX_INSTR cmpnlepd, sse2, 1, 0, 0 -AVX_INSTR cmpnleps, sse, 1, 0, 0 -AVX_INSTR cmpnlesd, sse2, 1, 0, 0 -AVX_INSTR cmpnless, sse, 1, 0, 0 -AVX_INSTR cmpnltpd, sse2, 1, 0, 0 -AVX_INSTR cmpnltps, sse, 1, 0, 0 -AVX_INSTR cmpnltsd, sse2, 1, 0, 0 -AVX_INSTR cmpnltss, sse, 1, 0, 0 -AVX_INSTR cmpordpd, sse2 1, 0, 1 -AVX_INSTR cmpordps, sse 1, 0, 1 -AVX_INSTR cmpordsd, sse2 1, 0, 0 -AVX_INSTR cmpordss, sse 1, 0, 0 -AVX_INSTR cmppd, sse2, 1, 1, 0 -AVX_INSTR cmpps, sse, 1, 1, 0 -AVX_INSTR cmpsd, sse2, 1, 1, 0 -AVX_INSTR cmpss, sse, 1, 1, 0 -AVX_INSTR cmpunordpd, sse2, 1, 0, 1 -AVX_INSTR cmpunordps, sse, 1, 0, 1 -AVX_INSTR cmpunordsd, sse2, 1, 0, 0 -AVX_INSTR cmpunordss, sse, 1, 0, 0 -AVX_INSTR comisd, sse2, 1 -AVX_INSTR comiss, sse, 1 -AVX_INSTR cvtdq2pd, sse2, 1 -AVX_INSTR cvtdq2ps, sse2, 1 -AVX_INSTR cvtpd2dq, sse2, 1 -AVX_INSTR cvtpd2ps, sse2, 1 -AVX_INSTR cvtps2dq, sse2, 1 -AVX_INSTR cvtps2pd, sse2, 1 -AVX_INSTR cvtsd2si, sse2, 1 -AVX_INSTR cvtsd2ss, sse2, 1, 0, 0 -AVX_INSTR cvtsi2sd, sse2, 1, 0, 0 -AVX_INSTR cvtsi2ss, sse, 1, 0, 0 -AVX_INSTR cvtss2sd, sse2, 1, 0, 0 -AVX_INSTR cvtss2si, sse, 1 -AVX_INSTR cvttpd2dq, sse2, 1 -AVX_INSTR cvttps2dq, sse2, 1 -AVX_INSTR cvttsd2si, sse2, 1 -AVX_INSTR cvttss2si, sse, 1 -AVX_INSTR divpd, sse2, 1, 0, 0 -AVX_INSTR divps, sse, 1, 0, 0 -AVX_INSTR divsd, sse2, 1, 0, 0 -AVX_INSTR divss, sse, 1, 0, 0 -AVX_INSTR dppd, sse4, 1, 1, 0 -AVX_INSTR dpps, sse4, 1, 1, 0 -AVX_INSTR extractps, sse4, 1 -AVX_INSTR gf2p8affineinvqb, gfni, 0, 1, 0 -AVX_INSTR gf2p8affineqb, gfni, 0, 1, 0 -AVX_INSTR gf2p8mulb, gfni, 0, 0, 0 -AVX_INSTR haddpd, sse3, 1, 0, 0 -AVX_INSTR haddps, sse3, 1, 0, 0 -AVX_INSTR hsubpd, sse3, 1, 0, 0 -AVX_INSTR hsubps, sse3, 1, 0, 0 -AVX_INSTR insertps, sse4, 1, 1, 0 -AVX_INSTR lddqu, sse3 -AVX_INSTR ldmxcsr, sse, 1 -AVX_INSTR maskmovdqu, sse2 -AVX_INSTR maxpd, sse2, 1, 0, 1 -AVX_INSTR maxps, sse, 1, 0, 1 -AVX_INSTR maxsd, sse2, 1, 0, 0 -AVX_INSTR maxss, sse, 1, 0, 0 -AVX_INSTR minpd, sse2, 1, 0, 1 -AVX_INSTR minps, sse, 1, 0, 1 -AVX_INSTR minsd, sse2, 1, 0, 0 -AVX_INSTR minss, sse, 1, 0, 0 -AVX_INSTR movapd, sse2, 1 -AVX_INSTR movaps, sse, 1 -AVX_INSTR movd, mmx -AVX_INSTR movddup, sse3, 1 -AVX_INSTR movdqa, sse2 -AVX_INSTR movdqu, sse2 -AVX_INSTR movhlps, sse, 1, 0, 0 -AVX_INSTR movhpd, sse2, 1, 0, 0 -AVX_INSTR movhps, sse, 1, 0, 0 -AVX_INSTR movlhps, sse, 1, 0, 0 -AVX_INSTR movlpd, sse2, 1, 0, 0 -AVX_INSTR movlps, sse, 1, 0, 0 -AVX_INSTR movmskpd, sse2, 1 -AVX_INSTR movmskps, sse, 1 -AVX_INSTR movntdq, sse2 -AVX_INSTR movntdqa, sse4 -AVX_INSTR movntpd, sse2, 1 -AVX_INSTR movntps, sse, 1 -AVX_INSTR movq, mmx -AVX_INSTR movsd, sse2, 1, 0, 0 -AVX_INSTR movshdup, sse3, 1 -AVX_INSTR movsldup, sse3, 1 -AVX_INSTR movss, sse, 1, 0, 0 -AVX_INSTR movupd, sse2, 1 -AVX_INSTR movups, sse, 1 -AVX_INSTR mpsadbw, sse4, 0, 1, 0 -AVX_INSTR mulpd, sse2, 1, 0, 1 -AVX_INSTR mulps, sse, 1, 0, 1 -AVX_INSTR mulsd, sse2, 1, 0, 0 -AVX_INSTR mulss, sse, 1, 0, 0 -AVX_INSTR orpd, sse2, 1, 0, 1 -AVX_INSTR orps, sse, 1, 0, 1 -AVX_INSTR pabsb, ssse3 -AVX_INSTR pabsd, ssse3 -AVX_INSTR pabsw, ssse3 -AVX_INSTR packsswb, mmx, 0, 0, 0 -AVX_INSTR packssdw, mmx, 0, 0, 0 -AVX_INSTR packuswb, mmx, 0, 0, 0 -AVX_INSTR packusdw, sse4, 0, 0, 0 -AVX_INSTR paddb, mmx, 0, 0, 1 -AVX_INSTR paddw, mmx, 0, 0, 1 -AVX_INSTR paddd, mmx, 0, 0, 1 -AVX_INSTR paddq, sse2, 0, 0, 1 -AVX_INSTR paddsb, mmx, 0, 0, 1 -AVX_INSTR paddsw, mmx, 0, 0, 1 -AVX_INSTR paddusb, mmx, 0, 0, 1 -AVX_INSTR paddusw, mmx, 0, 0, 1 -AVX_INSTR palignr, ssse3, 0, 1, 0 -AVX_INSTR pand, mmx, 0, 0, 1 -AVX_INSTR pandn, mmx, 0, 0, 0 -AVX_INSTR pavgb, mmx2, 0, 0, 1 -AVX_INSTR pavgw, mmx2, 0, 0, 1 -AVX_INSTR pblendvb, sse4 ; can't be emulated -AVX_INSTR pblendw, sse4, 0, 1, 0 -AVX_INSTR pclmulqdq, fnord, 0, 1, 0 -AVX_INSTR pclmulhqhqdq, fnord, 0, 0, 0 -AVX_INSTR pclmulhqlqdq, fnord, 0, 0, 0 -AVX_INSTR pclmullqhqdq, fnord, 0, 0, 0 -AVX_INSTR pclmullqlqdq, fnord, 0, 0, 0 -AVX_INSTR pcmpestri, sse42 -AVX_INSTR pcmpestrm, sse42 -AVX_INSTR pcmpistri, sse42 -AVX_INSTR pcmpistrm, sse42 -AVX_INSTR pcmpeqb, mmx, 0, 0, 1 -AVX_INSTR pcmpeqw, mmx, 0, 0, 1 -AVX_INSTR pcmpeqd, mmx, 0, 0, 1 -AVX_INSTR pcmpeqq, sse4, 0, 0, 1 -AVX_INSTR pcmpgtb, mmx, 0, 0, 0 -AVX_INSTR pcmpgtw, mmx, 0, 0, 0 -AVX_INSTR pcmpgtd, mmx, 0, 0, 0 -AVX_INSTR pcmpgtq, sse42, 0, 0, 0 -AVX_INSTR pextrb, sse4 -AVX_INSTR pextrd, sse4 -AVX_INSTR pextrq, sse4 -AVX_INSTR pextrw, mmx2 -AVX_INSTR phaddw, ssse3, 0, 0, 0 -AVX_INSTR phaddd, ssse3, 0, 0, 0 -AVX_INSTR phaddsw, ssse3, 0, 0, 0 -AVX_INSTR phminposuw, sse4 -AVX_INSTR phsubw, ssse3, 0, 0, 0 -AVX_INSTR phsubd, ssse3, 0, 0, 0 -AVX_INSTR phsubsw, ssse3, 0, 0, 0 -AVX_INSTR pinsrb, sse4, 0, 1, 0 -AVX_INSTR pinsrd, sse4, 0, 1, 0 -AVX_INSTR pinsrq, sse4, 0, 1, 0 -AVX_INSTR pinsrw, mmx2, 0, 1, 0 -AVX_INSTR pmaddwd, mmx, 0, 0, 1 -AVX_INSTR pmaddubsw, ssse3, 0, 0, 0 -AVX_INSTR pmaxsb, sse4, 0, 0, 1 -AVX_INSTR pmaxsw, mmx2, 0, 0, 1 -AVX_INSTR pmaxsd, sse4, 0, 0, 1 -AVX_INSTR pmaxub, mmx2, 0, 0, 1 -AVX_INSTR pmaxuw, sse4, 0, 0, 1 -AVX_INSTR pmaxud, sse4, 0, 0, 1 -AVX_INSTR pminsb, sse4, 0, 0, 1 -AVX_INSTR pminsw, mmx2, 0, 0, 1 -AVX_INSTR pminsd, sse4, 0, 0, 1 -AVX_INSTR pminub, mmx2, 0, 0, 1 -AVX_INSTR pminuw, sse4, 0, 0, 1 -AVX_INSTR pminud, sse4, 0, 0, 1 -AVX_INSTR pmovmskb, mmx2 -AVX_INSTR pmovsxbw, sse4 -AVX_INSTR pmovsxbd, sse4 -AVX_INSTR pmovsxbq, sse4 -AVX_INSTR pmovsxwd, sse4 -AVX_INSTR pmovsxwq, sse4 -AVX_INSTR pmovsxdq, sse4 -AVX_INSTR pmovzxbw, sse4 -AVX_INSTR pmovzxbd, sse4 -AVX_INSTR pmovzxbq, sse4 -AVX_INSTR pmovzxwd, sse4 -AVX_INSTR pmovzxwq, sse4 -AVX_INSTR pmovzxdq, sse4 -AVX_INSTR pmuldq, sse4, 0, 0, 1 -AVX_INSTR pmulhrsw, ssse3, 0, 0, 1 -AVX_INSTR pmulhuw, mmx2, 0, 0, 1 -AVX_INSTR pmulhw, mmx, 0, 0, 1 -AVX_INSTR pmullw, mmx, 0, 0, 1 -AVX_INSTR pmulld, sse4, 0, 0, 1 -AVX_INSTR pmuludq, sse2, 0, 0, 1 -AVX_INSTR por, mmx, 0, 0, 1 -AVX_INSTR psadbw, mmx2, 0, 0, 1 -AVX_INSTR pshufb, ssse3, 0, 0, 0 -AVX_INSTR pshufd, sse2 -AVX_INSTR pshufhw, sse2 -AVX_INSTR pshuflw, sse2 -AVX_INSTR psignb, ssse3, 0, 0, 0 -AVX_INSTR psignw, ssse3, 0, 0, 0 -AVX_INSTR psignd, ssse3, 0, 0, 0 -AVX_INSTR psllw, mmx, 0, 0, 0 -AVX_INSTR pslld, mmx, 0, 0, 0 -AVX_INSTR psllq, mmx, 0, 0, 0 -AVX_INSTR pslldq, sse2, 0, 0, 0 -AVX_INSTR psraw, mmx, 0, 0, 0 -AVX_INSTR psrad, mmx, 0, 0, 0 -AVX_INSTR psrlw, mmx, 0, 0, 0 -AVX_INSTR psrld, mmx, 0, 0, 0 -AVX_INSTR psrlq, mmx, 0, 0, 0 -AVX_INSTR psrldq, sse2, 0, 0, 0 -AVX_INSTR psubb, mmx, 0, 0, 0 -AVX_INSTR psubw, mmx, 0, 0, 0 -AVX_INSTR psubd, mmx, 0, 0, 0 -AVX_INSTR psubq, sse2, 0, 0, 0 -AVX_INSTR psubsb, mmx, 0, 0, 0 -AVX_INSTR psubsw, mmx, 0, 0, 0 -AVX_INSTR psubusb, mmx, 0, 0, 0 -AVX_INSTR psubusw, mmx, 0, 0, 0 -AVX_INSTR ptest, sse4 -AVX_INSTR punpckhbw, mmx, 0, 0, 0 -AVX_INSTR punpckhwd, mmx, 0, 0, 0 -AVX_INSTR punpckhdq, mmx, 0, 0, 0 -AVX_INSTR punpckhqdq, sse2, 0, 0, 0 -AVX_INSTR punpcklbw, mmx, 0, 0, 0 -AVX_INSTR punpcklwd, mmx, 0, 0, 0 -AVX_INSTR punpckldq, mmx, 0, 0, 0 -AVX_INSTR punpcklqdq, sse2, 0, 0, 0 -AVX_INSTR pxor, mmx, 0, 0, 1 -AVX_INSTR rcpps, sse, 1 -AVX_INSTR rcpss, sse, 1, 0, 0 -AVX_INSTR roundpd, sse4, 1 -AVX_INSTR roundps, sse4, 1 -AVX_INSTR roundsd, sse4, 1, 1, 0 -AVX_INSTR roundss, sse4, 1, 1, 0 -AVX_INSTR rsqrtps, sse, 1 -AVX_INSTR rsqrtss, sse, 1, 0, 0 -AVX_INSTR shufpd, sse2, 1, 1, 0 -AVX_INSTR shufps, sse, 1, 1, 0 -AVX_INSTR sqrtpd, sse2, 1 -AVX_INSTR sqrtps, sse, 1 -AVX_INSTR sqrtsd, sse2, 1, 0, 0 -AVX_INSTR sqrtss, sse, 1, 0, 0 -AVX_INSTR stmxcsr, sse, 1 -AVX_INSTR subpd, sse2, 1, 0, 0 -AVX_INSTR subps, sse, 1, 0, 0 -AVX_INSTR subsd, sse2, 1, 0, 0 -AVX_INSTR subss, sse, 1, 0, 0 -AVX_INSTR ucomisd, sse2, 1 -AVX_INSTR ucomiss, sse, 1 -AVX_INSTR unpckhpd, sse2, 1, 0, 0 -AVX_INSTR unpckhps, sse, 1, 0, 0 -AVX_INSTR unpcklpd, sse2, 1, 0, 0 -AVX_INSTR unpcklps, sse, 1, 0, 0 -AVX_INSTR xorpd, sse2, 1, 0, 1 -AVX_INSTR xorps, sse, 1, 0, 1 - -; 3DNow instructions, for sharing code between AVX, SSE and 3DN -AVX_INSTR pfadd, 3dnow, 1, 0, 1 -AVX_INSTR pfsub, 3dnow, 1, 0, 0 -AVX_INSTR pfmul, 3dnow, 1, 0, 1 - -;%1 == instruction -;%2 == minimal instruction set -%macro GPR_INSTR 2 - %macro %1 2-5 fnord, %1, %2 - %ifdef cpuname - %if notcpuflag(%5) - %error use of ``%4'' %5 instruction in cpuname function: current_function - %endif - %endif - %ifidn %3, fnord - %4 %1, %2 - %else - %4 %1, %2, %3 - %endif - %endmacro -%endmacro - -GPR_INSTR andn, bmi1 -GPR_INSTR bextr, bmi1 -GPR_INSTR blsi, bmi1 -GPR_INSTR blsr, bmi1 -GPR_INSTR blsmsk, bmi1 -GPR_INSTR bzhi, bmi2 -GPR_INSTR mulx, bmi2 -GPR_INSTR pdep, bmi2 -GPR_INSTR pext, bmi2 -GPR_INSTR popcnt, sse42 -GPR_INSTR rorx, bmi2 -GPR_INSTR sarx, bmi2 -GPR_INSTR shlx, bmi2 -GPR_INSTR shrx, bmi2 - -; base-4 constants for shuffles -%assign i 0 -%rep 256 - %assign j ((i>>6)&3)*1000 + ((i>>4)&3)*100 + ((i>>2)&3)*10 + (i&3) - %if j < 10 - CAT_XDEFINE q000, j, i - %elif j < 100 - CAT_XDEFINE q00, j, i - %elif j < 1000 - CAT_XDEFINE q0, j, i - %else - CAT_XDEFINE q, j, i - %endif - %assign i i+1 -%endrep -%undef i -%undef j - -%macro FMA_INSTR 3 - %macro %1 4-7 %1, %2, %3 - %if cpuflag(xop) - v%5 %1, %2, %3, %4 - %elifnidn %1, %4 - %6 %1, %2, %3 - %7 %1, %4 - %else - %error non-xop emulation of ``%5 %1, %2, %3, %4'' is not supported - %endif - %endmacro -%endmacro - -FMA_INSTR pmacsww, pmullw, paddw -FMA_INSTR pmacsdd, pmulld, paddd ; sse4 emulation -FMA_INSTR pmacsdql, pmuldq, paddq ; sse4 emulation -FMA_INSTR pmadcswd, pmaddwd, paddd - -; Macros for consolidating FMA3 and FMA4 using 4-operand (dst, src1, src2, src3) syntax. -; FMA3 is only possible if dst is the same as one of the src registers. -; Either src2 or src3 can be a memory operand. -%macro FMA4_INSTR 2-* - %push fma4_instr - %xdefine %$prefix %1 - %rep %0 - 1 - %macro %$prefix%2 4-6 %$prefix, %2 - %if notcpuflag(fma3) && notcpuflag(fma4) - %error use of ``%5%6'' fma instruction in cpuname function: current_function - %elif cpuflag(fma4) - v%5%6 %1, %2, %3, %4 - %elifidn %1, %2 - ; If %3 or %4 is a memory operand it needs to be encoded as the last operand. - %ifnum sizeof%3 - v%{5}213%6 %2, %3, %4 - %else - v%{5}132%6 %2, %4, %3 - %endif - %elifidn %1, %3 - v%{5}213%6 %3, %2, %4 - %elifidn %1, %4 - v%{5}231%6 %4, %2, %3 - %else - %error fma3 emulation of ``%5%6 %1, %2, %3, %4'' is not supported - %endif - %endmacro - %rotate 1 - %endrep - %pop -%endmacro - -FMA4_INSTR fmadd, pd, ps, sd, ss -FMA4_INSTR fmaddsub, pd, ps -FMA4_INSTR fmsub, pd, ps, sd, ss -FMA4_INSTR fmsubadd, pd, ps -FMA4_INSTR fnmadd, pd, ps, sd, ss -FMA4_INSTR fnmsub, pd, ps, sd, ss - -; Macros for converting VEX instructions to equivalent EVEX ones. -%macro EVEX_INSTR 2-3 0 ; vex, evex, prefer_evex - %macro %1 2-7 fnord, fnord, %1, %2, %3 - %ifidn %3, fnord - %define %%args %1, %2 - %elifidn %4, fnord - %define %%args %1, %2, %3 - %else - %define %%args %1, %2, %3, %4 - %endif - %assign %%evex_required cpuflag(avx512) & %7 - %ifnum regnumof%1 - %if regnumof%1 >= 16 || sizeof%1 > 32 - %assign %%evex_required 1 - %endif - %endif - %ifnum regnumof%2 - %if regnumof%2 >= 16 || sizeof%2 > 32 - %assign %%evex_required 1 - %endif - %endif - %ifnum regnumof%3 - %if regnumof%3 >= 16 || sizeof%3 > 32 - %assign %%evex_required 1 - %endif - %endif - %if %%evex_required - %6 %%args - %else - %5 %%args ; Prefer VEX over EVEX due to shorter instruction length - %endif - %endmacro -%endmacro - -EVEX_INSTR vbroadcastf128, vbroadcastf32x4 -EVEX_INSTR vbroadcasti128, vbroadcasti32x4 -EVEX_INSTR vextractf128, vextractf32x4 -EVEX_INSTR vextracti128, vextracti32x4 -EVEX_INSTR vinsertf128, vinsertf32x4 -EVEX_INSTR vinserti128, vinserti32x4 -EVEX_INSTR vmovdqa, vmovdqa32 -EVEX_INSTR vmovdqu, vmovdqu32 -EVEX_INSTR vpand, vpandd -EVEX_INSTR vpandn, vpandnd -EVEX_INSTR vpor, vpord -EVEX_INSTR vpxor, vpxord -EVEX_INSTR vrcpps, vrcp14ps, 1 ; EVEX versions have higher precision -EVEX_INSTR vrcpss, vrcp14ss, 1 -EVEX_INSTR vrsqrtps, vrsqrt14ps, 1 -EVEX_INSTR vrsqrtss, vrsqrt14ss, 1 diff --git a/presentation/src/main/cpp/third_party/libvpx/tools.mk b/presentation/src/main/cpp/third_party/libvpx/tools.mk deleted file mode 100644 index dd2ebeb3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools.mk +++ /dev/null @@ -1,116 +0,0 @@ -## -## Copyright (c) 2016 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -# List of tools to build. -TOOLS-yes += tiny_ssim.c -tiny_ssim.SRCS += vpx/vpx_integer.h y4minput.c y4minput.h \ - vpx/vpx_codec.h vpx/src/vpx_image.c -tiny_ssim.SRCS += vpx_mem/vpx_mem.c vpx_mem/vpx_mem.h -tiny_ssim.SRCS += vpx_dsp/ssim.h vpx_scale/yv12config.h -tiny_ssim.SRCS += vpx_ports/mem.h vpx_ports/mem.h -tiny_ssim.SRCS += vpx_mem/include/vpx_mem_intrnl.h -tiny_ssim.GUID = 3afa9b05-940b-4d68-b5aa-55157d8ed7b4 -tiny_ssim.DESCRIPTION = Generate SSIM/PSNR from raw .yuv files - -# -# End of specified files. The rest of the build rules should happen -# automagically from here. -# - - -# Expand list of selected tools to build (as specified above) -TOOLS = $(addprefix tools/,$(call enabled,TOOLS)) -ALL_SRCS = $(foreach ex,$(TOOLS),$($(notdir $(ex:.c=)).SRCS)) -CFLAGS += -I../include - -ifneq ($(CONFIG_CODEC_SRCS), yes) - CFLAGS += -I../include/vpx -endif - -# Expand all tools sources into a variable containing all sources -# for that tools (not just them main one specified in TOOLS) -# and add this file to the list (for MSVS workspace generation) -$(foreach ex,$(TOOLS),$(eval $(notdir $(ex:.c=)).SRCS += $(ex) tools.mk)) - - -# Create build/install dependencies for all tools. The common case -# is handled here. The MSVS case is handled below. -NOT_MSVS = $(if $(CONFIG_MSVS),,yes) -DIST-BINS-$(NOT_MSVS) += $(addprefix bin/,$(TOOLS:.c=$(EXE_SFX))) -DIST-SRCS-yes += $(ALL_SRCS) -OBJS-$(NOT_MSVS) += $(call objs,$(ALL_SRCS)) -BINS-$(NOT_MSVS) += $(addprefix $(BUILD_PFX),$(TOOLS:.c=$(EXE_SFX))) - -# Instantiate linker template for all tools. -$(foreach bin,$(BINS-yes),\ - $(eval $(bin):)\ - $(eval $(call linker_template,$(bin),\ - $(call objs,$($(notdir $(bin:$(EXE_SFX)=)).SRCS)) -lm))) - -# The following pairs define a mapping of locations in the distribution -# tree to locations in the source/build trees. -INSTALL_MAPS += src/%.c %.c -INSTALL_MAPS += src/% $(SRC_PATH_BARE)/% -INSTALL_MAPS += bin/% % -INSTALL_MAPS += % % - - -# Build Visual Studio Projects. We use a template here to instantiate -# explicit rules rather than using an implicit rule because we want to -# leverage make's VPATH searching rather than specifying the paths on -# each file in TOOLS. This has the unfortunate side effect that -# touching the source files trigger a rebuild of the project files -# even though there is no real dependency there (the dependency is on -# the makefiles). We may want to revisit this. -define vcproj_template -$(1): $($(1:.$(VCPROJ_SFX)=).SRCS) vpx.$(VCPROJ_SFX) - $(if $(quiet),@echo " [vcproj] $$@") - $(qexec)$$(GEN_VCPROJ)\ - --exe\ - --target=$$(TOOLCHAIN)\ - --name=$$(@:.$(VCPROJ_SFX)=)\ - --ver=$$(CONFIG_VS_VERSION)\ - --proj-guid=$$($$(@:.$(VCPROJ_SFX)=).GUID)\ - --src-path-bare="$(SRC_PATH_BARE)" \ - --as=$$(AS) \ - $$(if $$(CONFIG_STATIC_MSVCRT),--static-crt) \ - --out=$$@ $$(INTERNAL_CFLAGS) $$(CFLAGS) \ - $$(INTERNAL_LDFLAGS) $$(LDFLAGS) $$^ -endef -TOOLS_BASENAME := $(notdir $(TOOLS)) -PROJECTS-$(CONFIG_MSVS) += $(TOOLS_BASENAME:.c=.$(VCPROJ_SFX)) -INSTALL-BINS-$(CONFIG_MSVS) += $(foreach p,$(VS_PLATFORMS),\ - $(addprefix bin/$(p)/,$(TOOLS_BASENAME:.c=.exe))) -$(foreach proj,$(call enabled,PROJECTS),\ - $(eval $(call vcproj_template,$(proj)))) - -# -# Documentation Rules -# -%.dox: %.c - @echo " [DOXY] $@" - @mkdir -p $(dir $@) - @echo "/*!\page tools_$(@F:.dox=) $(@F:.dox=)" > $@ - @echo " \includelineno $(> $@ - @echo "*/" >> $@ - -tools.dox: tools.mk - @echo " [DOXY] $@" - @echo "/*!\page tools Tools" > $@ - @echo " This SDK includes a number of tools/utilities."\ - "The following tools are included: ">>$@ - @$(foreach ex,$(sort $(notdir $(TOOLS:.c=))),\ - echo " - \subpage tools_$(ex) $($(ex).DESCRIPTION)" >> $@;) - @echo "*/" >> $@ - -CLEAN-OBJS += tools.doxy tools.dox $(TOOLS:.c=.dox) -DOCS-yes += tools.doxy tools.dox -tools.doxy: tools.dox $(TOOLS:.c=.dox) - @echo "INPUT += $^" > $@ diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/Anandan.py b/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/Anandan.py deleted file mode 100644 index 5ff9e989..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/Anandan.py +++ /dev/null @@ -1,193 +0,0 @@ -## Copyright (c) 2020 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -# coding: utf-8 -import numpy as np -import numpy.linalg as LA -from scipy.ndimage.filters import gaussian_filter -from scipy.sparse import csc_matrix -from scipy.sparse.linalg import inv -from MotionEST import MotionEST -"""Anandan Model""" - - -class Anandan(MotionEST): - """ - constructor: - cur_f: current frame - ref_f: reference frame - blk_sz: block size - beta: smooth constrain weight - k1,k2,k3: confidence coefficients - max_iter: maximum number of iterations - """ - - def __init__(self, cur_f, ref_f, blk_sz, beta, k1, k2, k3, max_iter=100): - super(Anandan, self).__init__(cur_f, ref_f, blk_sz) - self.levels = int(np.log2(blk_sz)) - self.intensity_hierarchy() - self.c_maxs = [] - self.c_mins = [] - self.e_maxs = [] - self.e_mins = [] - for l in xrange(self.levels + 1): - c_max, c_min, e_max, e_min = self.get_curvature(self.cur_Is[l]) - self.c_maxs.append(c_max) - self.c_mins.append(c_min) - self.e_maxs.append(e_max) - self.e_mins.append(e_min) - self.beta = beta - self.k1, self.k2, self.k3 = k1, k2, k3 - self.max_iter = max_iter - - """ - build intensity hierarchy - """ - - def intensity_hierarchy(self): - level = 0 - self.cur_Is = [] - self.ref_Is = [] - #build each level itensity by using gaussian filters - while level <= self.levels: - cur_I = gaussian_filter(self.cur_yuv[:, :, 0], sigma=(2**level) * 0.56) - ref_I = gaussian_filter(self.ref_yuv[:, :, 0], sigma=(2**level) * 0.56) - self.ref_Is.append(ref_I) - self.cur_Is.append(cur_I) - level += 1 - - """ - get curvature of each block - """ - - def get_curvature(self, I): - c_max = np.zeros((self.num_row, self.num_col)) - c_min = np.zeros((self.num_row, self.num_col)) - e_max = np.zeros((self.num_row, self.num_col, 2)) - e_min = np.zeros((self.num_row, self.num_col, 2)) - for r in xrange(self.num_row): - for c in xrange(self.num_col): - h11, h12, h21, h22 = 0, 0, 0, 0 - for i in xrange(r * self.blk_sz, r * self.blk_sz + self.blk_sz): - for j in xrange(c * self.blk_sz, c * self.blk_sz + self.blk_sz): - if 0 <= i < self.height - 1 and 0 <= j < self.width - 1: - Ix = I[i][j + 1] - I[i][j] - Iy = I[i + 1][j] - I[i][j] - h11 += Iy * Iy - h12 += Ix * Iy - h21 += Ix * Iy - h22 += Ix * Ix - U, S, _ = LA.svd(np.array([[h11, h12], [h21, h22]])) - c_max[r, c], c_min[r, c] = S[0], S[1] - e_max[r, c] = U[:, 0] - e_min[r, c] = U[:, 1] - return c_max, c_min, e_max, e_min - - """ - get ssd of motion vector: - cur_I: current intensity - ref_I: reference intensity - center: current position - mv: motion vector - """ - - def get_ssd(self, cur_I, ref_I, center, mv): - ssd = 0 - for r in xrange(int(center[0]), int(center[0]) + self.blk_sz): - for c in xrange(int(center[1]), int(center[1]) + self.blk_sz): - if 0 <= r < self.height and 0 <= c < self.width: - tr, tc = r + int(mv[0]), c + int(mv[1]) - if 0 <= tr < self.height and 0 <= tc < self.width: - ssd += (ref_I[tr, tc] - cur_I[r, c])**2 - else: - ssd += cur_I[r, c]**2 - return ssd - - """ - get region match of level l - l: current level - last_mvs: matchine results of last level - radius: movenment radius - """ - - def region_match(self, l, last_mvs, radius): - mvs = np.zeros((self.num_row, self.num_col, 2)) - min_ssds = np.zeros((self.num_row, self.num_col)) - for r in xrange(self.num_row): - for c in xrange(self.num_col): - center = np.array([r * self.blk_sz, c * self.blk_sz]) - #use overlap hierarchy policy - init_mvs = [] - if last_mvs is None: - init_mvs = [np.array([0, 0])] - else: - for i, j in {(r, c), (r, c + 1), (r + 1, c), (r + 1, c + 1)}: - if 0 <= i < last_mvs.shape[0] and 0 <= j < last_mvs.shape[1]: - init_mvs.append(last_mvs[i, j]) - #use last matching results as the start position as current level - min_ssd = None - min_mv = None - for init_mv in init_mvs: - for i in xrange(-2, 3): - for j in xrange(-2, 3): - mv = init_mv + np.array([i, j]) * radius - ssd = self.get_ssd(self.cur_Is[l], self.ref_Is[l], center, mv) - if min_ssd is None or ssd < min_ssd: - min_ssd = ssd - min_mv = mv - min_ssds[r, c] = min_ssd - mvs[r, c] = min_mv - return mvs, min_ssds - - """ - smooth motion field based on neighbor constraint - uvs: current estimation - mvs: matching results - min_ssds: minimum ssd of matching results - l: current level - """ - - def smooth(self, uvs, mvs, min_ssds, l): - sm_uvs = np.zeros((self.num_row, self.num_col, 2)) - c_max = self.c_maxs[l] - c_min = self.c_mins[l] - e_max = self.e_maxs[l] - e_min = self.e_mins[l] - for r in xrange(self.num_row): - for c in xrange(self.num_col): - w_max = c_max[r, c] / ( - self.k1 + self.k2 * min_ssds[r, c] + self.k3 * c_max[r, c]) - w_min = c_min[r, c] / ( - self.k1 + self.k2 * min_ssds[r, c] + self.k3 * c_min[r, c]) - w = w_max * w_min / (w_max + w_min + 1e-6) - if w < 0: - w = 0 - avg_uv = np.array([0.0, 0.0]) - for i, j in {(r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1)}: - if 0 <= i < self.num_row and 0 <= j < self.num_col: - avg_uv += 0.25 * uvs[i, j] - sm_uvs[r, c] = (w * w * mvs[r, c] + self.beta * avg_uv) / ( - self.beta + w * w) - return sm_uvs - - """ - motion field estimation - """ - - def motion_field_estimation(self): - last_mvs = None - for l in xrange(self.levels, -1, -1): - mvs, min_ssds = self.region_match(l, last_mvs, 2**l) - uvs = np.zeros(mvs.shape) - for _ in xrange(self.max_iter): - uvs = self.smooth(uvs, mvs, min_ssds, l) - last_mvs = uvs - for r in xrange(self.num_row): - for c in xrange(self.num_col): - self.mf[r, c] = uvs[r, c] diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/Exhaust.py b/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/Exhaust.py deleted file mode 100644 index d763de85..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/Exhaust.py +++ /dev/null @@ -1,259 +0,0 @@ -## Copyright (c) 2020 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -# coding: utf-8 -import numpy as np -import numpy.linalg as LA -from Util import MSE -from MotionEST import MotionEST -"""Exhaust Search:""" - - -class Exhaust(MotionEST): - """ - Constructor: - cur_f: current frame - ref_f: reference frame - blk_sz: block size - wnd_size: search window size - metric: metric to compare the blocks distrotion - """ - - def __init__(self, cur_f, ref_f, blk_size, wnd_size, metric=MSE): - self.name = 'exhaust' - self.wnd_sz = wnd_size - self.metric = metric - super(Exhaust, self).__init__(cur_f, ref_f, blk_size) - - """ - search method: - cur_r: start row - cur_c: start column - """ - - def search(self, cur_r, cur_c): - min_loss = self.block_dist(cur_r, cur_c, [0, 0], self.metric) - cur_x = cur_c * self.blk_sz - cur_y = cur_r * self.blk_sz - ref_x = cur_x - ref_y = cur_y - #search all validate positions and select the one with minimum distortion - for y in xrange(cur_y - self.wnd_sz, cur_y + self.wnd_sz): - for x in xrange(cur_x - self.wnd_sz, cur_x + self.wnd_sz): - if 0 <= x < self.width - self.blk_sz and 0 <= y < self.height - self.blk_sz: - loss = self.block_dist(cur_r, cur_c, [y - cur_y, x - cur_x], - self.metric) - if loss < min_loss: - min_loss = loss - ref_x = x - ref_y = y - return ref_x, ref_y - - def motion_field_estimation(self): - for i in xrange(self.num_row): - for j in xrange(self.num_col): - ref_x, ref_y = self.search(i, j) - self.mf[i, j] = np.array( - [ref_y - i * self.blk_sz, ref_x - j * self.blk_sz]) - - -"""Exhaust with Neighbor Constraint""" - - -class ExhaustNeighbor(MotionEST): - """ - Constructor: - cur_f: current frame - ref_f: reference frame - blk_sz: block size - wnd_size: search window size - beta: neigbor loss weight - metric: metric to compare the blocks distrotion - """ - - def __init__(self, cur_f, ref_f, blk_size, wnd_size, beta, metric=MSE): - self.name = 'exhaust + neighbor' - self.wnd_sz = wnd_size - self.beta = beta - self.metric = metric - super(ExhaustNeighbor, self).__init__(cur_f, ref_f, blk_size) - self.assign = np.zeros((self.num_row, self.num_col), dtype=bool) - - """ - estimate neighbor loss: - cur_r: current row - cur_c: current column - mv: current motion vector - """ - - def neighborLoss(self, cur_r, cur_c, mv): - loss = 0 - #accumulate difference between current block's motion vector with neighbors' - for i, j in {(-1, 0), (1, 0), (0, 1), (0, -1)}: - nb_r = cur_r + i - nb_c = cur_c + j - if 0 <= nb_r < self.num_row and 0 <= nb_c < self.num_col and self.assign[ - nb_r, nb_c]: - loss += LA.norm(mv - self.mf[nb_r, nb_c]) - return loss - - """ - search method: - cur_r: start row - cur_c: start column - """ - - def search(self, cur_r, cur_c): - dist_loss = self.block_dist(cur_r, cur_c, [0, 0], self.metric) - nb_loss = self.neighborLoss(cur_r, cur_c, np.array([0, 0])) - min_loss = dist_loss + self.beta * nb_loss - cur_x = cur_c * self.blk_sz - cur_y = cur_r * self.blk_sz - ref_x = cur_x - ref_y = cur_y - #search all validate positions and select the one with minimum distortion - # as well as weighted neighbor loss - for y in xrange(cur_y - self.wnd_sz, cur_y + self.wnd_sz): - for x in xrange(cur_x - self.wnd_sz, cur_x + self.wnd_sz): - if 0 <= x < self.width - self.blk_sz and 0 <= y < self.height - self.blk_sz: - dist_loss = self.block_dist(cur_r, cur_c, [y - cur_y, x - cur_x], - self.metric) - nb_loss = self.neighborLoss(cur_r, cur_c, [y - cur_y, x - cur_x]) - loss = dist_loss + self.beta * nb_loss - if loss < min_loss: - min_loss = loss - ref_x = x - ref_y = y - return ref_x, ref_y - - def motion_field_estimation(self): - for i in xrange(self.num_row): - for j in xrange(self.num_col): - ref_x, ref_y = self.search(i, j) - self.mf[i, j] = np.array( - [ref_y - i * self.blk_sz, ref_x - j * self.blk_sz]) - self.assign[i, j] = True - - -"""Exhaust with Neighbor Constraint and Feature Score""" - - -class ExhaustNeighborFeatureScore(MotionEST): - """ - Constructor: - cur_f: current frame - ref_f: reference frame - blk_sz: block size - wnd_size: search window size - beta: neigbor loss weight - max_iter: maximum number of iterations - metric: metric to compare the blocks distrotion - """ - - def __init__(self, - cur_f, - ref_f, - blk_size, - wnd_size, - beta=1, - max_iter=100, - metric=MSE): - self.name = 'exhaust + neighbor+feature score' - self.wnd_sz = wnd_size - self.beta = beta - self.metric = metric - self.max_iter = max_iter - super(ExhaustNeighborFeatureScore, self).__init__(cur_f, ref_f, blk_size) - self.fs = self.getFeatureScore() - - """ - get feature score of each block - """ - - def getFeatureScore(self): - fs = np.zeros((self.num_row, self.num_col)) - for r in xrange(self.num_row): - for c in xrange(self.num_col): - IxIx = 0 - IyIy = 0 - IxIy = 0 - #get ssd surface - for x in xrange(self.blk_sz - 1): - for y in xrange(self.blk_sz - 1): - ox = c * self.blk_sz + x - oy = r * self.blk_sz + y - Ix = self.cur_yuv[oy, ox + 1, 0] - self.cur_yuv[oy, ox, 0] - Iy = self.cur_yuv[oy + 1, ox, 0] - self.cur_yuv[oy, ox, 0] - IxIx += Ix * Ix - IyIy += Iy * Iy - IxIy += Ix * Iy - #get maximum and minimum eigenvalues - lambda_max = 0.5 * ((IxIx + IyIy) + np.sqrt(4 * IxIy * IxIy + - (IxIx - IyIy)**2)) - lambda_min = 0.5 * ((IxIx + IyIy) - np.sqrt(4 * IxIy * IxIy + - (IxIx - IyIy)**2)) - fs[r, c] = lambda_max * lambda_min / (1e-6 + lambda_max + lambda_min) - if fs[r, c] < 0: - fs[r, c] = 0 - return fs - - """ - do exhaust search - """ - - def search(self, cur_r, cur_c): - min_loss = self.block_dist(cur_r, cur_c, [0, 0], self.metric) - cur_x = cur_c * self.blk_sz - cur_y = cur_r * self.blk_sz - ref_x = cur_x - ref_y = cur_y - #search all validate positions and select the one with minimum distortion - for y in xrange(cur_y - self.wnd_sz, cur_y + self.wnd_sz): - for x in xrange(cur_x - self.wnd_sz, cur_x + self.wnd_sz): - if 0 <= x < self.width - self.blk_sz and 0 <= y < self.height - self.blk_sz: - loss = self.block_dist(cur_r, cur_c, [y - cur_y, x - cur_x], - self.metric) - if loss < min_loss: - min_loss = loss - ref_x = x - ref_y = y - return ref_x, ref_y - - """ - add smooth constraint - """ - - def smooth(self, uvs, mvs): - sm_uvs = np.zeros(uvs.shape) - for r in xrange(self.num_row): - for c in xrange(self.num_col): - avg_uv = np.array([0.0, 0.0]) - for i, j in {(r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1)}: - if 0 <= i < self.num_row and 0 <= j < self.num_col: - avg_uv += uvs[i, j] / 6.0 - for i, j in {(r - 1, c - 1), (r - 1, c + 1), (r + 1, c - 1), - (r + 1, c + 1)}: - if 0 <= i < self.num_row and 0 <= j < self.num_col: - avg_uv += uvs[i, j] / 12.0 - sm_uvs[r, c] = (self.fs[r, c] * mvs[r, c] + self.beta * avg_uv) / ( - self.beta + self.fs[r, c]) - return sm_uvs - - def motion_field_estimation(self): - #get matching results - mvs = np.zeros(self.mf.shape) - for r in xrange(self.num_row): - for c in xrange(self.num_col): - ref_x, ref_y = self.search(r, c) - mvs[r, c] = np.array([ref_y - r * self.blk_sz, ref_x - c * self.blk_sz]) - #add smoothness constraint - uvs = np.zeros(self.mf.shape) - for _ in xrange(self.max_iter): - uvs = self.smooth(uvs, mvs) - self.mf = uvs diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/GroundTruth.py b/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/GroundTruth.py deleted file mode 100644 index 37305898..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/GroundTruth.py +++ /dev/null @@ -1,48 +0,0 @@ -## Copyright (c) 2020 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -#coding : utf - 8 -import numpy as np -import numpy.linalg as LA -from MotionEST import MotionEST -"""Ground Truth: - - Load in ground truth motion field and mask -""" - - -class GroundTruth(MotionEST): - """constructor: - - cur_f:current - frame ref_f:reference - frame blk_sz:block size - gt_path:ground truth motion field file path - """ - - def __init__(self, cur_f, ref_f, blk_sz, gt_path, mf=None, mask=None): - self.name = 'ground truth' - super(GroundTruth, self).__init__(cur_f, ref_f, blk_sz) - self.mask = np.zeros((self.num_row, self.num_col), dtype=bool) - if gt_path: - with open(gt_path) as gt_file: - lines = gt_file.readlines() - for i in xrange(len(lines)): - info = lines[i].split(';') - for j in xrange(len(info)): - x, y = info[j].split(',') - #-, - stands for nothing - if x == '-' or y == '-': - self.mask[i, -j - 1] = True - continue - #the order of original file is flipped on the x axis - self.mf[i, -j - 1] = np.array([float(y), -float(x)], dtype=int) - else: - self.mf = mf - self.mask = mask diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/HornSchunck.py b/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/HornSchunck.py deleted file mode 100644 index 976bd4a1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/HornSchunck.py +++ /dev/null @@ -1,212 +0,0 @@ -## Copyright (c) 2020 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -# coding: utf-8 -import numpy as np -import numpy.linalg as LA -from scipy.ndimage.filters import gaussian_filter -from scipy.sparse import csc_matrix -from scipy.sparse.linalg import inv -from MotionEST import MotionEST -"""Horn & Schunck Model""" - - -class HornSchunck(MotionEST): - """ - constructor: - cur_f: current frame - ref_f: reference frame - blk_sz: block size - alpha: smooth constrain weight - sigma: gaussian blur parameter - """ - - def __init__(self, cur_f, ref_f, blk_sz, alpha, sigma, max_iter=100): - super(HornSchunck, self).__init__(cur_f, ref_f, blk_sz) - self.cur_I, self.ref_I = self.getIntensity() - #perform gaussian blur to smooth the intensity - self.cur_I = gaussian_filter(self.cur_I, sigma=sigma) - self.ref_I = gaussian_filter(self.ref_I, sigma=sigma) - self.alpha = alpha - self.max_iter = max_iter - self.Ix, self.Iy, self.It = self.intensityDiff() - - """ - Build Frame Intensity - """ - - def getIntensity(self): - cur_I = np.zeros((self.num_row, self.num_col)) - ref_I = np.zeros((self.num_row, self.num_col)) - #use average intensity as block's intensity - for i in xrange(self.num_row): - for j in xrange(self.num_col): - r = i * self.blk_sz - c = j * self.blk_sz - cur_I[i, j] = np.mean(self.cur_yuv[r:r + self.blk_sz, c:c + self.blk_sz, - 0]) - ref_I[i, j] = np.mean(self.ref_yuv[r:r + self.blk_sz, c:c + self.blk_sz, - 0]) - return cur_I, ref_I - - """ - Get First Order Derivative - """ - - def intensityDiff(self): - Ix = np.zeros((self.num_row, self.num_col)) - Iy = np.zeros((self.num_row, self.num_col)) - It = np.zeros((self.num_row, self.num_col)) - sz = self.blk_sz - for i in xrange(self.num_row - 1): - for j in xrange(self.num_col - 1): - """ - Ix: - (i ,j) <--- (i ,j+1) - (i+1,j) <--- (i+1,j+1) - """ - count = 0 - for r, c in {(i, j + 1), (i + 1, j + 1)}: - if 0 <= r < self.num_row and 0 < c < self.num_col: - Ix[i, j] += ( - self.cur_I[r, c] - self.cur_I[r, c - 1] + self.ref_I[r, c] - - self.ref_I[r, c - 1]) - count += 2 - Ix[i, j] /= count - """ - Iy: - (i ,j) (i ,j+1) - ^ ^ - | | - (i+1,j) (i+1,j+1) - """ - count = 0 - for r, c in {(i + 1, j), (i + 1, j + 1)}: - if 0 < r < self.num_row and 0 <= c < self.num_col: - Iy[i, j] += ( - self.cur_I[r, c] - self.cur_I[r - 1, c] + self.ref_I[r, c] - - self.ref_I[r - 1, c]) - count += 2 - Iy[i, j] /= count - count = 0 - #It: - for r in xrange(i, i + 2): - for c in xrange(j, j + 2): - if 0 <= r < self.num_row and 0 <= c < self.num_col: - It[i, j] += (self.ref_I[r, c] - self.cur_I[r, c]) - count += 1 - It[i, j] /= count - return Ix, Iy, It - - """ - Get weighted average of neighbor motion vectors - for evaluation of laplacian - """ - - def averageMV(self): - avg = np.zeros((self.num_row, self.num_col, 2)) - """ - 1/12 --- 1/6 --- 1/12 - | | | - 1/6 --- -1/8 --- 1/6 - | | | - 1/12 --- 1/6 --- 1/12 - """ - for i in xrange(self.num_row): - for j in xrange(self.num_col): - for r, c in {(-1, 0), (1, 0), (0, -1), (0, 1)}: - if 0 <= i + r < self.num_row and 0 <= j + c < self.num_col: - avg[i, j] += self.mf[i + r, j + c] / 6.0 - for r, c in {(-1, -1), (-1, 1), (1, -1), (1, 1)}: - if 0 <= i + r < self.num_row and 0 <= j + c < self.num_col: - avg[i, j] += self.mf[i + r, j + c] / 12.0 - return avg - - def motion_field_estimation(self): - count = 0 - """ - u_{n+1} = ~u_n - Ix(Ix.~u_n+Iy.~v+It)/(IxIx+IyIy+alpha^2) - v_{n+1} = ~v_n - Iy(Ix.~u_n+Iy.~v+It)/(IxIx+IyIy+alpha^2) - """ - denom = self.alpha**2 + np.power(self.Ix, 2) + np.power(self.Iy, 2) - while count < self.max_iter: - avg = self.averageMV() - self.mf[:, :, 1] = avg[:, :, 1] - self.Ix * ( - self.Ix * avg[:, :, 1] + self.Iy * avg[:, :, 0] + self.It) / denom - self.mf[:, :, 0] = avg[:, :, 0] - self.Iy * ( - self.Ix * avg[:, :, 1] + self.Iy * avg[:, :, 0] + self.It) / denom - count += 1 - self.mf *= self.blk_sz - - def motion_field_estimation_mat(self): - row_idx = [] - col_idx = [] - data = [] - - N = 2 * self.num_row * self.num_col - b = np.zeros((N, 1)) - for i in xrange(self.num_row): - for j in xrange(self.num_col): - """(IxIx+alpha^2)u+IxIy.v-alpha^2~u IxIy.u+(IyIy+alpha^2)v-alpha^2~v""" - u_idx = i * 2 * self.num_col + 2 * j - v_idx = u_idx + 1 - b[u_idx, 0] = -self.Ix[i, j] * self.It[i, j] - b[v_idx, 0] = -self.Iy[i, j] * self.It[i, j] - #u: (IxIx+alpha^2)u - row_idx.append(u_idx) - col_idx.append(u_idx) - data.append(self.Ix[i, j] * self.Ix[i, j] + self.alpha**2) - #IxIy.v - row_idx.append(u_idx) - col_idx.append(v_idx) - data.append(self.Ix[i, j] * self.Iy[i, j]) - - #v: IxIy.u - row_idx.append(v_idx) - col_idx.append(u_idx) - data.append(self.Ix[i, j] * self.Iy[i, j]) - #(IyIy+alpha^2)v - row_idx.append(v_idx) - col_idx.append(v_idx) - data.append(self.Iy[i, j] * self.Iy[i, j] + self.alpha**2) - - #-alpha^2~u - #-alpha^2~v - for r, c in {(-1, 0), (1, 0), (0, -1), (0, 1)}: - if 0 <= i + r < self.num_row and 0 <= j + c < self.num_col: - u_nb = (i + r) * 2 * self.num_col + 2 * (j + c) - v_nb = u_nb + 1 - - row_idx.append(u_idx) - col_idx.append(u_nb) - data.append(-1 * self.alpha**2 / 6.0) - - row_idx.append(v_idx) - col_idx.append(v_nb) - data.append(-1 * self.alpha**2 / 6.0) - for r, c in {(-1, -1), (-1, 1), (1, -1), (1, 1)}: - if 0 <= i + r < self.num_row and 0 <= j + c < self.num_col: - u_nb = (i + r) * 2 * self.num_col + 2 * (j + c) - v_nb = u_nb + 1 - - row_idx.append(u_idx) - col_idx.append(u_nb) - data.append(-1 * self.alpha**2 / 12.0) - - row_idx.append(v_idx) - col_idx.append(v_nb) - data.append(-1 * self.alpha**2 / 12.0) - M = csc_matrix((data, (row_idx, col_idx)), shape=(N, N)) - M_inv = inv(M) - uv = M_inv.dot(b) - - for i in xrange(self.num_row): - for j in xrange(self.num_col): - self.mf[i, j, 0] = uv[i * 2 * self.num_col + 2 * j + 1, 0] * self.blk_sz - self.mf[i, j, 1] = uv[i * 2 * self.num_col + 2 * j, 0] * self.blk_sz diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/MotionEST.py b/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/MotionEST.py deleted file mode 100644 index fc393818..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/MotionEST.py +++ /dev/null @@ -1,117 +0,0 @@ -## Copyright (c) 2020 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -#coding : utf - 8 -import numpy as np -import numpy.linalg as LA -import matplotlib.pyplot as plt -from Util import drawMF, MSE -"""The Base Class of Estimators""" - - -class MotionEST(object): - """ - constructor: - cur_f: current frame - ref_f: reference frame - blk_sz: block size - """ - - def __init__(self, cur_f, ref_f, blk_sz): - self.cur_f = cur_f - self.ref_f = ref_f - self.blk_sz = blk_sz - #convert RGB to YUV - self.cur_yuv = np.array(self.cur_f.convert('YCbCr'), dtype=int) - self.ref_yuv = np.array(self.ref_f.convert('YCbCr'), dtype=int) - #frame size - self.width = self.cur_f.size[0] - self.height = self.cur_f.size[1] - #motion field size - self.num_row = self.height // self.blk_sz - self.num_col = self.width // self.blk_sz - #initialize motion field - self.mf = np.zeros((self.num_row, self.num_col, 2)) - - """estimation function Override by child classes""" - - def motion_field_estimation(self): - pass - - """ - distortion of a block: - cur_r: current row - cur_c: current column - mv: motion vector - metric: distortion metric - """ - - def block_dist(self, cur_r, cur_c, mv, metric=MSE): - cur_x = cur_c * self.blk_sz - cur_y = cur_r * self.blk_sz - h = min(self.blk_sz, self.height - cur_y) - w = min(self.blk_sz, self.width - cur_x) - cur_blk = self.cur_yuv[cur_y:cur_y + h, cur_x:cur_x + w, :] - ref_x = int(cur_x + mv[1]) - ref_y = int(cur_y + mv[0]) - if 0 <= ref_x < self.width - w and 0 <= ref_y < self.height - h: - ref_blk = self.ref_yuv[ref_y:ref_y + h, ref_x:ref_x + w, :] - else: - ref_blk = np.zeros((h, w, 3)) - return metric(cur_blk, ref_blk) - - """ - distortion of motion field - """ - - def distortion(self, mask=None, metric=MSE): - loss = 0 - count = 0 - for i in xrange(self.num_row): - for j in xrange(self.num_col): - if mask is not None and mask[i, j]: - continue - loss += self.block_dist(i, j, self.mf[i, j], metric) - count += 1 - return loss / count - - """evaluation compare the difference with ground truth""" - - def motion_field_evaluation(self, ground_truth): - loss = 0 - count = 0 - gt = ground_truth.mf - mask = ground_truth.mask - for i in xrange(self.num_row): - for j in xrange(self.num_col): - if mask is not None and mask[i][j]: - continue - loss += LA.norm(gt[i, j] - self.mf[i, j]) - count += 1 - return loss / count - - """render the motion field""" - - def show(self, ground_truth=None, size=10): - cur_mf = drawMF(self.cur_f, self.blk_sz, self.mf) - if ground_truth is None: - n_row = 1 - else: - gt_mf = drawMF(self.cur_f, self.blk_sz, ground_truth) - n_row = 2 - plt.figure(figsize=(n_row * size, size * self.height / self.width)) - plt.subplot(1, n_row, 1) - plt.imshow(cur_mf) - plt.title('Estimated Motion Field') - if ground_truth is not None: - plt.subplot(1, n_row, 2) - plt.imshow(gt_mf) - plt.title('Ground Truth') - plt.tight_layout() - plt.show() diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/SearchSmooth.py b/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/SearchSmooth.py deleted file mode 100644 index 2dc6771e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/SearchSmooth.py +++ /dev/null @@ -1,221 +0,0 @@ -## Copyright (c) 2020 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -# coding: utf-8 -import numpy as np -import numpy.linalg as LA -from Util import MSE -from MotionEST import MotionEST -"""Search & Smooth Model with Adapt Weights""" - - -class SearchSmoothAdapt(MotionEST): - """ - Constructor: - cur_f: current frame - ref_f: reference frame - blk_sz: block size - wnd_size: search window size - beta: neigbor loss weight - max_iter: maximum number of iterations - metric: metric to compare the blocks distrotion - """ - - def __init__(self, cur_f, ref_f, blk_size, search, max_iter=100): - self.search = search - self.max_iter = max_iter - super(SearchSmoothAdapt, self).__init__(cur_f, ref_f, blk_size) - - """ - get local diffiencial of refernce - """ - - def getRefLocalDiff(self, mvs): - m, n = self.num_row, self.num_col - localDiff = [[] for _ in xrange(m)] - blk_sz = self.blk_sz - for r in xrange(m): - for c in xrange(n): - I_row = 0 - I_col = 0 - #get ssd surface - count = 0 - center = self.cur_yuv[r * blk_sz:(r + 1) * blk_sz, - c * blk_sz:(c + 1) * blk_sz, 0] - ty = np.clip(r * blk_sz + int(mvs[r, c, 0]), 0, self.height - blk_sz) - tx = np.clip(c * blk_sz + int(mvs[r, c, 1]), 0, self.width - blk_sz) - target = self.ref_yuv[ty:ty + blk_sz, tx:tx + blk_sz, 0] - for y, x in {(ty - blk_sz, tx), (ty + blk_sz, tx)}: - if 0 <= y < self.height - blk_sz and 0 <= x < self.width - blk_sz: - nb = self.ref_yuv[y:y + blk_sz, x:x + blk_sz, 0] - I_row += np.sum(np.abs(nb - center)) - np.sum( - np.abs(target - center)) - count += 1 - I_row //= (count * blk_sz * blk_sz) - count = 0 - for y, x in {(ty, tx - blk_sz), (ty, tx + blk_sz)}: - if 0 <= y < self.height - blk_sz and 0 <= x < self.width - blk_sz: - nb = self.ref_yuv[y:y + blk_sz, x:x + blk_sz, 0] - I_col += np.sum(np.abs(nb - center)) - np.sum( - np.abs(target - center)) - count += 1 - I_col //= (count * blk_sz * blk_sz) - localDiff[r].append( - np.array([[I_row * I_row, I_row * I_col], - [I_col * I_row, I_col * I_col]])) - return localDiff - - """ - add smooth constraint - """ - - def smooth(self, uvs, mvs): - sm_uvs = np.zeros(uvs.shape) - blk_sz = self.blk_sz - for r in xrange(self.num_row): - for c in xrange(self.num_col): - nb_uv = np.array([0.0, 0.0]) - for i, j in {(r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1)}: - if 0 <= i < self.num_row and 0 <= j < self.num_col: - nb_uv += uvs[i, j] / 6.0 - else: - nb_uv += uvs[r, c] / 6.0 - for i, j in {(r - 1, c - 1), (r - 1, c + 1), (r + 1, c - 1), - (r + 1, c + 1)}: - if 0 <= i < self.num_row and 0 <= j < self.num_col: - nb_uv += uvs[i, j] / 12.0 - else: - nb_uv += uvs[r, c] / 12.0 - ssd_nb = self.block_dist(r, c, self.blk_sz * nb_uv) - mv = mvs[r, c] - ssd_mv = self.block_dist(r, c, mv) - alpha = (ssd_nb - ssd_mv) / (ssd_mv + 1e-6) - M = alpha * self.localDiff[r][c] - P = M + np.identity(2) - inv_P = LA.inv(P) - sm_uvs[r, c] = np.dot(inv_P, nb_uv) + np.dot( - np.matmul(inv_P, M), mv / blk_sz) - return sm_uvs - - def block_matching(self): - self.search.motion_field_estimation() - - def motion_field_estimation(self): - self.localDiff = self.getRefLocalDiff(self.search.mf) - #get matching results - mvs = self.search.mf - #add smoothness constraint - uvs = mvs / self.blk_sz - for _ in xrange(self.max_iter): - uvs = self.smooth(uvs, mvs) - self.mf = uvs * self.blk_sz - - -"""Search & Smooth Model with Fixed Weights""" - - -class SearchSmoothFix(MotionEST): - """ - Constructor: - cur_f: current frame - ref_f: reference frame - blk_sz: block size - wnd_size: search window size - beta: neigbor loss weight - max_iter: maximum number of iterations - metric: metric to compare the blocks distrotion - """ - - def __init__(self, cur_f, ref_f, blk_size, search, beta, max_iter=100): - self.search = search - self.max_iter = max_iter - self.beta = beta - super(SearchSmoothFix, self).__init__(cur_f, ref_f, blk_size) - - """ - get local diffiencial of refernce - """ - - def getRefLocalDiff(self, mvs): - m, n = self.num_row, self.num_col - localDiff = [[] for _ in xrange(m)] - blk_sz = self.blk_sz - for r in xrange(m): - for c in xrange(n): - I_row = 0 - I_col = 0 - #get ssd surface - count = 0 - center = self.cur_yuv[r * blk_sz:(r + 1) * blk_sz, - c * blk_sz:(c + 1) * blk_sz, 0] - ty = np.clip(r * blk_sz + int(mvs[r, c, 0]), 0, self.height - blk_sz) - tx = np.clip(c * blk_sz + int(mvs[r, c, 1]), 0, self.width - blk_sz) - target = self.ref_yuv[ty:ty + blk_sz, tx:tx + blk_sz, 0] - for y, x in {(ty - blk_sz, tx), (ty + blk_sz, tx)}: - if 0 <= y < self.height - blk_sz and 0 <= x < self.width - blk_sz: - nb = self.ref_yuv[y:y + blk_sz, x:x + blk_sz, 0] - I_row += np.sum(np.abs(nb - center)) - np.sum( - np.abs(target - center)) - count += 1 - I_row //= (count * blk_sz * blk_sz) - count = 0 - for y, x in {(ty, tx - blk_sz), (ty, tx + blk_sz)}: - if 0 <= y < self.height - blk_sz and 0 <= x < self.width - blk_sz: - nb = self.ref_yuv[y:y + blk_sz, x:x + blk_sz, 0] - I_col += np.sum(np.abs(nb - center)) - np.sum( - np.abs(target - center)) - count += 1 - I_col //= (count * blk_sz * blk_sz) - localDiff[r].append( - np.array([[I_row * I_row, I_row * I_col], - [I_col * I_row, I_col * I_col]])) - return localDiff - - """ - add smooth constraint - """ - - def smooth(self, uvs, mvs): - sm_uvs = np.zeros(uvs.shape) - blk_sz = self.blk_sz - for r in xrange(self.num_row): - for c in xrange(self.num_col): - nb_uv = np.array([0.0, 0.0]) - for i, j in {(r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1)}: - if 0 <= i < self.num_row and 0 <= j < self.num_col: - nb_uv += uvs[i, j] / 6.0 - else: - nb_uv += uvs[r, c] / 6.0 - for i, j in {(r - 1, c - 1), (r - 1, c + 1), (r + 1, c - 1), - (r + 1, c + 1)}: - if 0 <= i < self.num_row and 0 <= j < self.num_col: - nb_uv += uvs[i, j] / 12.0 - else: - nb_uv += uvs[r, c] / 12.0 - mv = mvs[r, c] / blk_sz - M = self.localDiff[r][c] - P = M + self.beta * np.identity(2) - inv_P = LA.inv(P) - sm_uvs[r, c] = np.dot(inv_P, self.beta * nb_uv) + np.dot( - np.matmul(inv_P, M), mv) - return sm_uvs - - def block_matching(self): - self.search.motion_field_estimation() - - def motion_field_estimation(self): - #get local structure - self.localDiff = self.getRefLocalDiff(self.search.mf) - #get matching results - mvs = self.search.mf - #add smoothness constraint - uvs = mvs / self.blk_sz - for _ in xrange(self.max_iter): - uvs = self.smooth(uvs, mvs) - self.mf = uvs * self.blk_sz diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/Util.py b/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/Util.py deleted file mode 100644 index c2416163..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/MotionEST/Util.py +++ /dev/null @@ -1,46 +0,0 @@ -## Copyright (c) 2020 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -# coding: utf-8 -import numpy as np -import numpy.linalg as LA -import matplotlib.pyplot as plt -from scipy.ndimage import filters -from PIL import Image, ImageDraw - - -def MSE(blk1, blk2): - return np.mean( - LA.norm( - np.array(blk1, dtype=int) - np.array(blk2, dtype=int), axis=2)) - - -def drawMF(img, blk_sz, mf): - img_rgba = img.convert('RGBA') - mf_layer = Image.new(mode='RGBA', size=img_rgba.size, color=(0, 0, 0, 0)) - draw = ImageDraw.Draw(mf_layer) - width = img_rgba.size[0] - height = img_rgba.size[1] - num_row = height // blk_sz - num_col = width // blk_sz - for i in xrange(num_row): - left = (0, i * blk_sz) - right = (width, i * blk_sz) - draw.line([left, right], fill=(0, 0, 255, 255)) - for j in xrange(num_col): - up = (j * blk_sz, 0) - down = (j * blk_sz, height) - draw.line([up, down], fill=(0, 0, 255, 255)) - for i in xrange(num_row): - for j in xrange(num_col): - center = (j * blk_sz + 0.5 * blk_sz, i * blk_sz + 0.5 * blk_sz) - """mf[i,j][0] is the row shift and mf[i,j][1] is the column shift In PIL coordinates, head[0] is x (column shift) and head[1] is y (row shift).""" - head = (center[0] + mf[i, j][1], center[1] + mf[i, j][0]) - draw.line([center, head], fill=(255, 0, 0, 255)) - return Image.alpha_composite(img_rgba, mf_layer) diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/genY4M/genY4M.py b/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/genY4M/genY4M.py deleted file mode 100644 index 8028102f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/genY4M/genY4M.py +++ /dev/null @@ -1,85 +0,0 @@ -## Copyright (c) 2020 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -import argparse -from os import listdir, path -from PIL import Image -import sys - -parser = argparse.ArgumentParser() -parser.add_argument("--frame_path", default="../data/frame/", type=str) -parser.add_argument("--frame_rate", default="25:1", type=str) -parser.add_argument("--interlacing", default="Ip", type=str) -parser.add_argument("--pix_ratio", default="0:0", type=str) -parser.add_argument("--color_space", default="4:2:0", type=str) -parser.add_argument("--output", default="output.y4m", type=str) - - -def generate(args, frames): - if len(frames) == 0: - return - #sort the frames based on the frame index - frames = sorted(frames, key=lambda x: x[0]) - #convert the frames to YUV form - frames = [f.convert("YCbCr") for _, f in frames] - #write the header - header = "YUV4MPEG2 W%d H%d F%s %s A%s" % (frames[0].width, frames[0].height, - args.frame_rate, args.interlacing, - args.pix_ratio) - cs = args.color_space.split(":") - header += " C%s%s%s\n" % (cs[0], cs[1], cs[2]) - #estimate the sample step based on subsample value - subsamples = [int(c) for c in cs] - r_step = [1, int(subsamples[2] == 0) + 1, int(subsamples[2] == 0) + 1] - c_step = [1, 4 // subsamples[1], 4 // subsamples[1]] - #write in frames - with open(args.output, "wb") as y4m: - y4m.write(header) - for f in frames: - y4m.write("FRAME\n") - px = f.load() - for k in xrange(3): - for i in xrange(0, f.height, r_step[k]): - for j in xrange(0, f.width, c_step[k]): - yuv = px[j, i] - y4m.write(chr(yuv[k])) - - -if __name__ == "__main__": - args = parser.parse_args() - frames = [] - frames_mv = [] - for filename in listdir(args.frame_path): - name, ext = filename.split(".") - if ext == "png": - name_parse = name.split("_") - idx = int(name_parse[-1]) - img = Image.open(path.join(args.frame_path, filename)) - if name_parse[-2] == "mv": - frames_mv.append((idx, img)) - else: - frames.append((idx, img)) - if len(frames) == 0: - print("No frames in directory: " + args.frame_path) - sys.exit() - print("----------------------Y4M Info----------------------") - print("width: %d" % frames[0][1].width) - print("height: %d" % frames[0][1].height) - print("#frame: %d" % len(frames)) - print("frame rate: %s" % args.frame_rate) - print("interlacing: %s" % args.interlacing) - print("pixel ratio: %s" % args.pix_ratio) - print("color space: %s" % args.color_space) - print("----------------------------------------------------") - - print("Generating ...") - generate(args, frames) - if len(frames_mv) != 0: - args.output = args.output.replace(".y4m", "_mv.y4m") - generate(args, frames_mv) diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/BVH.pde b/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/BVH.pde deleted file mode 100644 index 7249ee97..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/BVH.pde +++ /dev/null @@ -1,163 +0,0 @@ -/* - *AABB bounding box - *Bouding Volume Hierarchy - */ -class BoundingBox { - float min_x, min_y, min_z, max_x, max_y, max_z; - PVector center; - BoundingBox() { - min_x = Float.POSITIVE_INFINITY; - min_y = Float.POSITIVE_INFINITY; - min_z = Float.POSITIVE_INFINITY; - max_x = Float.NEGATIVE_INFINITY; - max_y = Float.NEGATIVE_INFINITY; - max_z = Float.NEGATIVE_INFINITY; - center = new PVector(); - } - // build a bounding box for a triangle - void create(Triangle t) { - min_x = min(t.p1.x, min(t.p2.x, t.p3.x)); - max_x = max(t.p1.x, max(t.p2.x, t.p3.x)); - - min_y = min(t.p1.y, min(t.p2.y, t.p3.y)); - max_y = max(t.p1.y, max(t.p2.y, t.p3.y)); - - min_z = min(t.p1.z, min(t.p2.z, t.p3.z)); - max_z = max(t.p1.z, max(t.p2.z, t.p3.z)); - center.x = (max_x + min_x) / 2; - center.y = (max_y + min_y) / 2; - center.z = (max_z + min_z) / 2; - } - // merge two bounding boxes - void add(BoundingBox bbx) { - min_x = min(min_x, bbx.min_x); - min_y = min(min_y, bbx.min_y); - min_z = min(min_z, bbx.min_z); - - max_x = max(max_x, bbx.max_x); - max_y = max(max_y, bbx.max_y); - max_z = max(max_z, bbx.max_z); - center.x = (max_x + min_x) / 2; - center.y = (max_y + min_y) / 2; - center.z = (max_z + min_z) / 2; - } - // get bounding box center axis value - float getCenterAxisValue(int axis) { - if (axis == 1) { - return center.x; - } else if (axis == 2) { - return center.y; - } - // when axis == 3 - return center.z; - } - // check if a ray is intersected with the bounding box - boolean intersect(Ray r) { - float tmin, tmax; - if (r.dir.x >= 0) { - tmin = (min_x - r.ori.x) * (1.0f / r.dir.x); - tmax = (max_x - r.ori.x) * (1.0f / r.dir.x); - } else { - tmin = (max_x - r.ori.x) * (1.0f / r.dir.x); - tmax = (min_x - r.ori.x) * (1.0f / r.dir.x); - } - - float tymin, tymax; - if (r.dir.y >= 0) { - tymin = (min_y - r.ori.y) * (1.0f / r.dir.y); - tymax = (max_y - r.ori.y) * (1.0f / r.dir.y); - } else { - tymin = (max_y - r.ori.y) * (1.0f / r.dir.y); - tymax = (min_y - r.ori.y) * (1.0f / r.dir.y); - } - - if (tmax < tymin || tymax < tmin) { - return false; - } - - tmin = tmin < tymin ? tymin : tmin; - tmax = tmax > tymax ? tymax : tmax; - - float tzmin, tzmax; - if (r.dir.z >= 0) { - tzmin = (min_z - r.ori.z) * (1.0f / r.dir.z); - tzmax = (max_z - r.ori.z) * (1.0f / r.dir.z); - } else { - tzmin = (max_z - r.ori.z) * (1.0f / r.dir.z); - tzmax = (min_z - r.ori.z) * (1.0f / r.dir.z); - } - if (tmax < tzmin || tmin > tzmax) { - return false; - } - return true; - } -} -// Bounding Volume Hierarchy -class BVH { - // Binary Tree - BVH left, right; - BoundingBox overall_bbx; - ArrayList mesh; - BVH(ArrayList mesh) { - this.mesh = mesh; - overall_bbx = new BoundingBox(); - left = null; - right = null; - int mesh_size = this.mesh.size(); - if (mesh_size <= 1) { - return; - } - // random select an axis - int axis = int(random(100)) % 3 + 1; - // build bounding box and save the selected center component - float[] axis_values = new float[mesh_size]; - for (int i = 0; i < mesh_size; i++) { - Triangle t = this.mesh.get(i); - overall_bbx.add(t.bbx); - axis_values[i] = t.bbx.getCenterAxisValue(axis); - } - // find the median value of selected center component as pivot - axis_values = sort(axis_values); - float pivot; - if (mesh_size % 2 == 1) { - pivot = axis_values[mesh_size / 2]; - } else { - pivot = - 0.5f * (axis_values[mesh_size / 2 - 1] + axis_values[mesh_size / 2]); - } - // Build left node and right node by partitioning the mesh based on triangle - // bounding box center component value - ArrayList left_mesh = new ArrayList(); - ArrayList right_mesh = new ArrayList(); - for (int i = 0; i < mesh_size; i++) { - Triangle t = this.mesh.get(i); - if (t.bbx.getCenterAxisValue(axis) < pivot) { - left_mesh.add(t); - } else if (t.bbx.getCenterAxisValue(axis) > pivot) { - right_mesh.add(t); - } else if (left_mesh.size() < right_mesh.size()) { - left_mesh.add(t); - } else { - right_mesh.add(t); - } - } - left = new BVH(left_mesh); - right = new BVH(right_mesh); - } - // check if a ray intersect with current volume - boolean intersect(Ray r, float[] param) { - if (mesh.size() == 0) { - return false; - } - if (mesh.size() == 1) { - Triangle t = mesh.get(0); - return t.intersect(r, param); - } - if (!overall_bbx.intersect(r)) { - return false; - } - boolean left_res = left.intersect(r, param); - boolean right_res = right.intersect(r, param); - return left_res || right_res; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/Camera.pde b/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/Camera.pde deleted file mode 100644 index b39dae3a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/Camera.pde +++ /dev/null @@ -1,138 +0,0 @@ -class Camera { - // camera's field of view - float fov; - // camera's position, look at point and axis - PVector pos, center, axis; - PVector init_pos, init_center, init_axis; - float move_speed; - float rot_speed; - Camera(float fov, PVector pos, PVector center, PVector axis) { - this.fov = fov; - this.pos = pos; - this.center = center; - this.axis = axis; - this.axis.normalize(); - move_speed = 0.001; - rot_speed = 0.01 * PI; - init_pos = pos.copy(); - init_center = center.copy(); - init_axis = axis.copy(); - } - - Camera copy() { - Camera cam = new Camera(fov, pos.copy(), center.copy(), axis.copy()); - return cam; - } - - PVector project(PVector pos) { - PVector proj = MatxVec3(getCameraMat(), PVector.sub(pos, this.pos)); - proj.x = (float)height / 2.0 * proj.x / proj.z / tan(fov / 2.0f); - proj.y = (float)height / 2.0 * proj.y / proj.z / tan(fov / 2.0f); - proj.z = proj.z; - return proj; - } - - float[] getCameraMat() { - float[] mat = new float[9]; - PVector dir = PVector.sub(center, pos); - dir.normalize(); - PVector left = dir.cross(axis); - left.normalize(); - // processing camera system does not follow right hand rule - mat[0] = -left.x; - mat[1] = -left.y; - mat[2] = -left.z; - mat[3] = axis.x; - mat[4] = axis.y; - mat[5] = axis.z; - mat[6] = dir.x; - mat[7] = dir.y; - mat[8] = dir.z; - - return mat; - } - - void run() { - PVector dir, left; - if (mousePressed) { - float angleX = (float)mouseX / width * PI - PI / 2; - float angleY = (float)mouseY / height * PI - PI; - PVector diff = PVector.sub(center, pos); - float radius = diff.mag(); - pos.x = radius * sin(angleY) * sin(angleX) + center.x; - pos.y = radius * cos(angleY) + center.y; - pos.z = radius * sin(angleY) * cos(angleX) + center.z; - dir = PVector.sub(center, pos); - dir.normalize(); - PVector up = new PVector(0, 1, 0); - left = up.cross(dir); - left.normalize(); - axis = dir.cross(left); - axis.normalize(); - } - - if (keyPressed) { - switch (key) { - case 'w': - dir = PVector.sub(center, pos); - dir.normalize(); - pos = PVector.add(pos, PVector.mult(dir, move_speed)); - center = PVector.add(center, PVector.mult(dir, move_speed)); - break; - case 's': - dir = PVector.sub(center, pos); - dir.normalize(); - pos = PVector.sub(pos, PVector.mult(dir, move_speed)); - center = PVector.sub(center, PVector.mult(dir, move_speed)); - break; - case 'a': - dir = PVector.sub(center, pos); - dir.normalize(); - left = axis.cross(dir); - left.normalize(); - pos = PVector.add(pos, PVector.mult(left, move_speed)); - center = PVector.add(center, PVector.mult(left, move_speed)); - break; - case 'd': - dir = PVector.sub(center, pos); - dir.normalize(); - left = axis.cross(dir); - left.normalize(); - pos = PVector.sub(pos, PVector.mult(left, move_speed)); - center = PVector.sub(center, PVector.mult(left, move_speed)); - break; - case 'r': - dir = PVector.sub(center, pos); - dir.normalize(); - float[] mat = getRotationMat3x3(rot_speed, dir.x, dir.y, dir.z); - axis = MatxVec3(mat, axis); - axis.normalize(); - break; - case 'b': - pos = init_pos.copy(); - center = init_center.copy(); - axis = init_axis.copy(); - break; - case '+': move_speed *= 2.0f; break; - case '-': move_speed /= 2.0; break; - case CODED: - if (keyCode == UP) { - pos = PVector.add(pos, PVector.mult(axis, move_speed)); - center = PVector.add(center, PVector.mult(axis, move_speed)); - } else if (keyCode == DOWN) { - pos = PVector.sub(pos, PVector.mult(axis, move_speed)); - center = PVector.sub(center, PVector.mult(axis, move_speed)); - } - } - } - } - void open() { - perspective(fov, float(width) / height, 1e-6, 1e5); - camera(pos.x, pos.y, pos.z, center.x, center.y, center.z, axis.x, axis.y, - axis.z); - } - void close() { - ortho(-width, 0, -height, 0); - camera(0, 0, 0, 0, 0, 1, 0, 1, 0); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/MotionField.pde b/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/MotionField.pde deleted file mode 100644 index a5e04b6a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/MotionField.pde +++ /dev/null @@ -1,102 +0,0 @@ -class MotionField { - int block_size; - ArrayList motion_field; - MotionField(int block_size) { - this.block_size = block_size; - motion_field = new ArrayList(); - } - - void update(Camera last_cam, Camera current_cam, PointCloud point_cloud, - BVH bvh) { - // clear motion field - motion_field = new ArrayList(); - int r_num = height / block_size, c_num = width / block_size; - for (int i = 0; i < r_num * c_num; i++) - motion_field.add(new PVector(0, 0, 0)); - // estimate motion vector of each point in point cloud - for (int i = 0; i < point_cloud.size(); i++) { - PVector p = point_cloud.getPosition(i); - PVector p0 = current_cam.project(p); - PVector p1 = last_cam.project(p); - int row = int((p0.y + height / 2.0f) / block_size); - int col = int((p0.x + width / 2.0f) / block_size); - if (row >= 0 && row < r_num && col >= 0 && col < c_num) { - PVector accu = motion_field.get(row * c_num + col); - accu.x += p1.x - p0.x; - accu.y += p1.y - p0.y; - accu.z += 1; - } - } - // if some blocks do not have point, then use ray tracing to see if they are - // in triangles - for (int i = 0; i < r_num; i++) - for (int j = 0; j < c_num; j++) { - PVector accu = motion_field.get(i * c_num + j); - if (accu.z > 0) { - continue; - } - // use the center of the block to generate view ray - float cx = j * block_size + block_size / 2.0f - width / 2.0f; - float cy = i * block_size + block_size / 2.0f - height / 2.0f; - float cz = 0.5f * height / tan(current_cam.fov / 2.0f); - PVector dir = new PVector(cx, cy, cz); - float[] camMat = current_cam.getCameraMat(); - dir = MatxVec3(transpose3x3(camMat), dir); - dir.normalize(); - Ray r = new Ray(current_cam.pos, dir); - // ray tracing - float[] param = new float[4]; - param[0] = Float.POSITIVE_INFINITY; - if (bvh.intersect(r, param)) { - PVector p = new PVector(param[1], param[2], param[3]); - PVector p0 = current_cam.project(p); - PVector p1 = last_cam.project(p); - accu.x += p1.x - p0.x; - accu.y += p1.y - p0.y; - accu.z += 1; - } - } - // estimate the motion vector of each block - for (int i = 0; i < r_num * c_num; i++) { - PVector mv = motion_field.get(i); - if (mv.z > 0) { - motion_field.set(i, new PVector(mv.x / mv.z, mv.y / mv.z, 0)); - } else // there is nothing in the block, use -1 to mark it. - { - motion_field.set(i, new PVector(0.0, 0.0, -1)); - } - } - } - - void render() { - int r_num = height / block_size, c_num = width / block_size; - for (int i = 0; i < r_num; i++) - for (int j = 0; j < c_num; j++) { - PVector mv = motion_field.get(i * c_num + j); - float ox = j * block_size + 0.5f * block_size; - float oy = i * block_size + 0.5f * block_size; - stroke(255, 0, 0); - line(ox, oy, ox + mv.x, oy + mv.y); - } - } - - void save(String path) { - int r_num = height / block_size; - int c_num = width / block_size; - String[] mvs = new String[r_num]; - for (int i = 0; i < r_num; i++) { - mvs[i] = ""; - for (int j = 0; j < c_num; j++) { - PVector mv = motion_field.get(i * c_num + j); - if (mv.z != -1) { - mvs[i] += str(mv.x) + "," + str(mv.y); - } else // there is nothing - { - mvs[i] += "-,-"; - } - if (j != c_num - 1) mvs[i] += ";"; - } - } - saveStrings(path, mvs); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/PointCloud.pde b/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/PointCloud.pde deleted file mode 100644 index 714a6f3a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/PointCloud.pde +++ /dev/null @@ -1,138 +0,0 @@ -class PointCloud { - ArrayList points; // array to save points - IntList point_colors; // array to save points color - PVector cloud_mass; - float[] depth; - boolean[] real; - PointCloud() { - // initialize - points = new ArrayList(); - point_colors = new IntList(); - cloud_mass = new PVector(0, 0, 0); - depth = new float[width * height]; - real = new boolean[width * height]; - } - - void generate(PImage rgb_img, PImage depth_img, Transform trans) { - if (depth_img.width != width || depth_img.height != height || - rgb_img.width != width || rgb_img.height != height) { - println("rgb and depth file dimension should be same with window size"); - exit(); - } - // clear depth and real - for (int i = 0; i < width * height; i++) { - depth[i] = 0; - real[i] = false; - } - for (int v = 0; v < height; v++) - for (int u = 0; u < width; u++) { - // get depth value (red channel) - color depth_px = depth_img.get(u, v); - depth[v * width + u] = depth_px & 0x0000FFFF; - if (int(depth[v * width + u]) != 0) { - real[v * width + u] = true; - } - point_colors.append(rgb_img.get(u, v)); - } - for (int v = 0; v < height; v++) - for (int u = 0; u < width; u++) { - if (int(depth[v * width + u]) == 0) { - interpolateDepth(v, u); - } - // add transformed pixel as well as pixel color to the list - PVector pos = trans.transform(u, v, int(depth[v * width + u])); - points.add(pos); - // accumulate z value - cloud_mass = PVector.add(cloud_mass, pos); - } - } - void fillInDepthAlongPath(float d, Node node) { - node = node.parent; - while (node != null) { - int i = node.row; - int j = node.col; - if (depth[i * width + j] == 0) { - depth[i * width + j] = d; - } - node = node.parent; - } - } - // interpolate - void interpolateDepth(int row, int col) { - if (row < 0 || row >= height || col < 0 || col >= width || - int(depth[row * width + col]) != 0) { - return; - } - ArrayList queue = new ArrayList(); - queue.add(new Node(row, col, null)); - boolean[] visited = new boolean[width * height]; - for (int i = 0; i < width * height; i++) visited[i] = false; - visited[row * width + col] = true; - // Using BFS to Find the Nearest Neighbor - while (queue.size() > 0) { - // pop - Node node = queue.get(0); - queue.remove(0); - int i = node.row; - int j = node.col; - // if current position have a real depth - if (depth[i * width + j] != 0 && real[i * width + j]) { - fillInDepthAlongPath(depth[i * width + j], node); - break; - } else { - // search unvisited 8 neighbors - for (int r = max(0, i - 1); r < min(height, i + 2); r++) { - for (int c = max(0, j - 1); c < min(width, j + 2); c++) { - if (!visited[r * width + c]) { - visited[r * width + c] = true; - queue.add(new Node(r, c, node)); - } - } - } - } - } - } - // get point cloud size - int size() { return points.size(); } - // get ith position - PVector getPosition(int i) { - if (i >= points.size()) { - println("point position: index " + str(i) + " exceeds"); - exit(); - } - return points.get(i); - } - // get ith color - color getColor(int i) { - if (i >= point_colors.size()) { - println("point color: index " + str(i) + " exceeds"); - exit(); - } - return point_colors.get(i); - } - // get cloud center - PVector getCloudCenter() { - if (points.size() > 0) { - return PVector.div(cloud_mass, points.size()); - } - return new PVector(0, 0, 0); - } - // merge two clouds - void merge(PointCloud point_cloud) { - for (int i = 0; i < point_cloud.size(); i++) { - points.add(point_cloud.getPosition(i)); - point_colors.append(point_cloud.getColor(i)); - } - cloud_mass = PVector.add(cloud_mass, point_cloud.cloud_mass); - } -} - -class Node { - int row, col; - Node parent; - Node(int row, int col, Node parent) { - this.row = row; - this.col = col; - this.parent = parent; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/Ray_Tracing.pde b/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/Ray_Tracing.pde deleted file mode 100644 index ef4be691..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/Ray_Tracing.pde +++ /dev/null @@ -1,61 +0,0 @@ -// Triangle -class Triangle { - // position - PVector p1, p2, p3; - // color - color c1, c2, c3; - BoundingBox bbx; - Triangle(PVector p1, PVector p2, PVector p3, color c1, color c2, color c3) { - this.p1 = p1; - this.p2 = p2; - this.p3 = p3; - this.c1 = c1; - this.c2 = c2; - this.c3 = c3; - bbx = new BoundingBox(); - bbx.create(this); - } - // check to see if a ray intersects with the triangle - boolean intersect(Ray r, float[] param) { - PVector p21 = PVector.sub(p2, p1); - PVector p31 = PVector.sub(p3, p1); - PVector po1 = PVector.sub(r.ori, p1); - - PVector dxp31 = r.dir.cross(p31); - PVector po1xp21 = po1.cross(p21); - float denom = p21.dot(dxp31); - float t = p31.dot(po1xp21) / denom; - float alpha = po1.dot(dxp31) / denom; - float beta = r.dir.dot(po1xp21) / denom; - - boolean res = t > 0 && alpha > 0 && alpha < 1 && beta > 0 && beta < 1 && - alpha + beta < 1; - // depth test - if (res && t < param[0]) { - param[0] = t; - param[1] = alpha * p1.x + beta * p2.x + (1 - alpha - beta) * p3.x; - param[2] = alpha * p1.y + beta * p2.y + (1 - alpha - beta) * p3.y; - param[3] = alpha * p1.z + beta * p2.z + (1 - alpha - beta) * p3.z; - } - return res; - } - void render() { - beginShape(TRIANGLES); - fill(c1); - vertex(p1.x, p1.y, p1.z); - fill(c2); - vertex(p2.x, p2.y, p2.z); - fill(c3); - vertex(p3.x, p3.y, p3.z); - endShape(); - } -} -// Ray -class Ray { - // origin and direction - PVector ori, dir; - Ray(PVector ori, PVector dir) { - this.ori = ori; - this.dir = dir; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/Scene.pde b/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/Scene.pde deleted file mode 100644 index cf79ab71..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/Scene.pde +++ /dev/null @@ -1,59 +0,0 @@ -class Scene { - PointCloud point_cloud; - ArrayList mesh; - BVH bvh; - MotionField motion_field; - Camera last_cam; - Camera current_cam; - int frame_count; - - Scene(Camera camera, PointCloud point_cloud, MotionField motion_field) { - this.point_cloud = point_cloud; - this.motion_field = motion_field; - mesh = new ArrayList(); - for (int v = 0; v < height - 1; v++) - for (int u = 0; u < width - 1; u++) { - PVector p1 = point_cloud.getPosition(v * width + u); - PVector p2 = point_cloud.getPosition(v * width + u + 1); - PVector p3 = point_cloud.getPosition((v + 1) * width + u + 1); - PVector p4 = point_cloud.getPosition((v + 1) * width + u); - color c1 = point_cloud.getColor(v * width + u); - color c2 = point_cloud.getColor(v * width + u + 1); - color c3 = point_cloud.getColor((v + 1) * width + u + 1); - color c4 = point_cloud.getColor((v + 1) * width + u); - mesh.add(new Triangle(p1, p2, p3, c1, c2, c3)); - mesh.add(new Triangle(p3, p4, p1, c3, c4, c1)); - } - bvh = new BVH(mesh); - last_cam = camera.copy(); - current_cam = camera; - frame_count = 0; - } - - void run() { - last_cam = current_cam.copy(); - current_cam.run(); - motion_field.update(last_cam, current_cam, point_cloud, bvh); - frame_count += 1; - } - - void render(boolean show_motion_field) { - // build mesh - current_cam.open(); - noStroke(); - for (int i = 0; i < mesh.size(); i++) { - Triangle t = mesh.get(i); - t.render(); - } - if (show_motion_field) { - current_cam.close(); - motion_field.render(); - } - } - - void save(String path) { saveFrame(path + "_" + str(frame_count) + ".png"); } - - void saveMotionField(String path) { - motion_field.save(path + "_" + str(frame_count) + ".txt"); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/Transform.pde b/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/Transform.pde deleted file mode 100644 index af2204e8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/Transform.pde +++ /dev/null @@ -1,82 +0,0 @@ -class Transform { - float[] inv_rot; // inverse of rotation matrix - PVector inv_mov; // inverse of movement vector - float focal; // the focal distacne of real camera - int w, h; // the width and height of the frame - float normalier; // nomalization factor of depth - Transform(float tx, float ty, float tz, float qx, float qy, float qz, - float qw, float fov, int w, int h, float normalier) { - // currently, we did not use the info of real camera's position and - // quaternion maybe we will use it in the future when combine all frames - float[] rot = quaternion2Mat3x3(qx, qy, qz, qw); - inv_rot = transpose3x3(rot); - inv_mov = new PVector(-tx, -ty, -tz); - this.focal = 0.5f * h / tan(fov / 2.0); - this.w = w; - this.h = h; - this.normalier = normalier; - } - - PVector transform(int i, int j, float d) { - // transfer from camera view to world view - float z = d / normalier; - float x = (i - w / 2.0f) * z / focal; - float y = (j - h / 2.0f) * z / focal; - return new PVector(x, y, z); - } -} - -// get rotation matrix by using rotation axis and angle -float[] getRotationMat3x3(float angle, float ax, float ay, float az) { - float[] mat = new float[9]; - float c = cos(angle); - float s = sin(angle); - mat[0] = c + ax * ax * (1 - c); - mat[1] = ax * ay * (1 - c) - az * s; - mat[2] = ax * az * (1 - c) + ay * s; - mat[3] = ay * ax * (1 - c) + az * s; - mat[4] = c + ay * ay * (1 - c); - mat[5] = ay * az * (1 - c) - ax * s; - mat[6] = az * ax * (1 - c) - ay * s; - mat[7] = az * ay * (1 - c) + ax * s; - mat[8] = c + az * az * (1 - c); - return mat; -} - -// get rotation matrix by using quaternion -float[] quaternion2Mat3x3(float qx, float qy, float qz, float qw) { - float[] mat = new float[9]; - mat[0] = 1 - 2 * qy * qy - 2 * qz * qz; - mat[1] = 2 * qx * qy - 2 * qz * qw; - mat[2] = 2 * qx * qz + 2 * qy * qw; - mat[3] = 2 * qx * qy + 2 * qz * qw; - mat[4] = 1 - 2 * qx * qx - 2 * qz * qz; - mat[5] = 2 * qy * qz - 2 * qx * qw; - mat[6] = 2 * qx * qz - 2 * qy * qw; - mat[7] = 2 * qy * qz + 2 * qx * qw; - mat[8] = 1 - 2 * qx * qx - 2 * qy * qy; - return mat; -} - -// tranpose a 3x3 matrix -float[] transpose3x3(float[] mat) { - float[] Tmat = new float[9]; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) { - Tmat[i * 3 + j] = mat[j * 3 + i]; - } - return Tmat; -} - -// multiply a matrix with vector -PVector MatxVec3(float[] mat, PVector v) { - float[] vec = v.array(); - float[] res = new float[3]; - for (int i = 0; i < 3; i++) { - res[i] = 0.0f; - for (int j = 0; j < 3; j++) { - res[i] += mat[i * 3 + j] * vec[j]; - } - } - return new PVector(res[0], res[1], res[2]); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/Util.pde b/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/Util.pde deleted file mode 100644 index 19d124a0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/Util.pde +++ /dev/null @@ -1,28 +0,0 @@ -// show grids -void showGrids(int block_size) { - ortho(-width, 0, -height, 0); - camera(0, 0, 0, 0, 0, 1, 0, 1, 0); - stroke(0, 0, 255); - for (int i = 0; i < height; i += block_size) { - line(0, i, width, i); - } - for (int i = 0; i < width; i += block_size) { - line(i, 0, i, height); - } -} - -// save the point clould information -void savePointCloud(PointCloud point_cloud, String file_name) { - String[] positions = new String[point_cloud.points.size()]; - String[] colors = new String[point_cloud.points.size()]; - for (int i = 0; i < point_cloud.points.size(); i++) { - PVector point = point_cloud.getPosition(i); - color point_color = point_cloud.getColor(i); - positions[i] = str(point.x) + ' ' + str(point.y) + ' ' + str(point.z); - colors[i] = str(((point_color >> 16) & 0xFF) / 255.0) + ' ' + - str(((point_color >> 8) & 0xFF) / 255.0) + ' ' + - str((point_color & 0xFF) / 255.0); - } - saveStrings(file_name + "_pos.txt", positions); - saveStrings(file_name + "_color.txt", colors); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/sketch_3D_reconstruction.pde b/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/sketch_3D_reconstruction.pde deleted file mode 100644 index 22a49543..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/3D-Reconstruction/sketch_3D_reconstruction/sketch_3D_reconstruction.pde +++ /dev/null @@ -1,74 +0,0 @@ -/*The dataset is from - *Computer Vision Group - *TUM Department of Informatics Technical - *University of Munich - *https://vision.in.tum.de/data/datasets/rgbd-dataset/download#freiburg1_xyz - */ -Scene scene; -void setup() { - size(640, 480, P3D); - // default settings - int frame_no = 0; // frame number - float fov = PI / 3; // field of view - int block_size = 8; // block size - float normalizer = 5000.0f; // normalizer - // initialize - PointCloud point_cloud = new PointCloud(); - // synchronized rgb, depth and ground truth - String head = "../data/"; - String[] rgb_depth_gt = loadStrings(head + "rgb_depth_groundtruth.txt"); - // read in rgb and depth image file paths as well as corresponding camera - // posiiton and quaternion - String[] info = split(rgb_depth_gt[frame_no], ' '); - String rgb_path = head + info[1]; - String depth_path = head + info[3]; - float tx = float(info[7]), ty = float(info[8]), - tz = float(info[9]); // real camera position - float qx = float(info[10]), qy = float(info[11]), qz = float(info[12]), - qw = float(info[13]); // quaternion - - // build transformer - Transform trans = - new Transform(tx, ty, tz, qx, qy, qz, qw, fov, width, height, normalizer); - PImage rgb = loadImage(rgb_path); - PImage depth = loadImage(depth_path); - // generate point cloud - point_cloud.generate(rgb, depth, trans); - // initialize camera - Camera camera = new Camera(fov, new PVector(0, 0, 0), new PVector(0, 0, 1), - new PVector(0, 1, 0)); - // initialize motion field - MotionField motion_field = new MotionField(block_size); - // initialize scene - scene = new Scene(camera, point_cloud, motion_field); -} -boolean inter = false; -void draw() { - background(0); - // run camera dragged mouse to rotate camera - // w: go forward - // s: go backward - // a: go left - // d: go right - // up arrow: go up - // down arrow: go down - //+ increase move speed - //- decrease move speed - // r: rotate the camera - // b: reset to initial position - scene.run(); // true: make interpolation; false: do not make - // interpolation - if (keyPressed && key == 'o') { - inter = true; - } - scene.render( - false); // true: turn on motion field; false: turn off motion field - // save frame with no motion field - scene.save("../data/frame/raw"); - background(0); - scene.render(true); - showGrids(scene.motion_field.block_size); - // save frame with motion field - scene.save("../data/frame/raw_mv"); - scene.saveMotionField("../data/frame/mv"); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/README.pgo.md b/presentation/src/main/cpp/third_party/libvpx/tools/README.pgo.md deleted file mode 100644 index 414743f8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/README.pgo.md +++ /dev/null @@ -1,24 +0,0 @@ -# Using Profile Guided Optimizations to identify compiler optimization failures - -When using Clang, the `-Rpass-missed` flag enables the verbose log of failed -compiler optimizations. However, the extensive log messages can obscure -potential optimization opportunities. - -Use the following steps to generate a more transparent optimization report -using a previously created PGO profile file. The report also includes code -hotness diagnostics: - -```bash -$ ../libvpx/configure --use-profile=perf.profdata \ - --extra-cflags="-fsave-optimization-record -fdiagnostics-show-hotness" -``` - -Convert the generated YAML files into a detailed HTML report using the -[optviewer2](https://github.com/OfekShilon/optview2) tool: - -```bash -$ opt-viewer.py --output-dir=out/ --source-dir=libvpx . -``` - -The HTML report displays each code line's relative hotness, cross-referenced -with the failed compiler optimizations. diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/cpplint.py b/presentation/src/main/cpp/third_party/libvpx/tools/cpplint.py deleted file mode 100644 index e3ebde2f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/cpplint.py +++ /dev/null @@ -1,6244 +0,0 @@ -#!/usr/bin/env python -# -# Copyright (c) 2009 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Does google-lint on c++ files. - -The goal of this script is to identify places in the code that *may* -be in non-compliance with google style. It does not attempt to fix -up these problems -- the point is to educate. It does also not -attempt to find all problems, or to ensure that everything it does -find is legitimately a problem. - -In particular, we can get very confused by /* and // inside strings! -We do a small hack, which is to ignore //'s with "'s after them on the -same line, but it is far from perfect (in either direction). -""" - -import codecs -import copy -import getopt -import math # for log -import os -import re -import sre_compile -import string -import sys -import unicodedata -import sysconfig - -try: - xrange # Python 2 -except NameError: - xrange = range # Python 3 - - -_USAGE = """ -Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...] - [--counting=total|toplevel|detailed] [--root=subdir] - [--linelength=digits] [--headers=x,y,...] - [--quiet] - [file] ... - - The style guidelines this tries to follow are those in - https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml - - Every problem is given a confidence score from 1-5, with 5 meaning we are - certain of the problem, and 1 meaning it could be a legitimate construct. - This will miss some errors, and is not a substitute for a code review. - - To suppress false-positive errors of a certain category, add a - 'NOLINT(category)' comment to the line. NOLINT or NOLINT(*) - suppresses errors of all categories on that line. - - The files passed in will be linted; at least one file must be provided. - Default linted extensions are .cc, .cpp, .cu, .cuh and .h. Change the - extensions with the --extensions flag. - - Flags: - - output=vs7 - By default, the output is formatted to ease emacs parsing. Visual Studio - compatible output (vs7) may also be used. Other formats are unsupported. - - verbose=# - Specify a number 0-5 to restrict errors to certain verbosity levels. - - quiet - Don't print anything if no errors are found. - - filter=-x,+y,... - Specify a comma-separated list of category-filters to apply: only - error messages whose category names pass the filters will be printed. - (Category names are printed with the message and look like - "[whitespace/indent]".) Filters are evaluated left to right. - "-FOO" and "FOO" means "do not print categories that start with FOO". - "+FOO" means "do print categories that start with FOO". - - Examples: --filter=-whitespace,+whitespace/braces - --filter=whitespace,runtime/printf,+runtime/printf_format - --filter=-,+build/include_what_you_use - - To see a list of all the categories used in cpplint, pass no arg: - --filter= - - counting=total|toplevel|detailed - The total number of errors found is always printed. If - 'toplevel' is provided, then the count of errors in each of - the top-level categories like 'build' and 'whitespace' will - also be printed. If 'detailed' is provided, then a count - is provided for each category like 'build/class'. - - root=subdir - The root directory used for deriving header guard CPP variable. - By default, the header guard CPP variable is calculated as the relative - path to the directory that contains .git, .hg, or .svn. When this flag - is specified, the relative path is calculated from the specified - directory. If the specified directory does not exist, this flag is - ignored. - - Examples: - Assuming that top/src/.git exists (and cwd=top/src), the header guard - CPP variables for top/src/chrome/browser/ui/browser.h are: - - No flag => CHROME_BROWSER_UI_BROWSER_H_ - --root=chrome => BROWSER_UI_BROWSER_H_ - --root=chrome/browser => UI_BROWSER_H_ - --root=.. => SRC_CHROME_BROWSER_UI_BROWSER_H_ - - linelength=digits - This is the allowed line length for the project. The default value is - 80 characters. - - Examples: - --linelength=120 - - extensions=extension,extension,... - The allowed file extensions that cpplint will check - - Examples: - --extensions=hpp,cpp - - headers=x,y,... - The header extensions that cpplint will treat as .h in checks. Values are - automatically added to --extensions list. - - Examples: - --headers=hpp,hxx - --headers=hpp - - cpplint.py supports per-directory configurations specified in CPPLINT.cfg - files. CPPLINT.cfg file can contain a number of key=value pairs. - Currently the following options are supported: - - set noparent - filter=+filter1,-filter2,... - exclude_files=regex - linelength=80 - root=subdir - headers=x,y,... - - "set noparent" option prevents cpplint from traversing directory tree - upwards looking for more .cfg files in parent directories. This option - is usually placed in the top-level project directory. - - The "filter" option is similar in function to --filter flag. It specifies - message filters in addition to the |_DEFAULT_FILTERS| and those specified - through --filter command-line flag. - - "exclude_files" allows to specify a regular expression to be matched against - a file name. If the expression matches, the file is skipped and not run - through liner. - - "linelength" allows to specify the allowed line length for the project. - - The "root" option is similar in function to the --root flag (see example - above). Paths are relative to the directory of the CPPLINT.cfg. - - The "headers" option is similar in function to the --headers flag - (see example above). - - CPPLINT.cfg has an effect on files in the same directory and all - sub-directories, unless overridden by a nested configuration file. - - Example file: - filter=-build/include_order,+build/include_alpha - exclude_files=.*\.cc - - The above example disables build/include_order warning and enables - build/include_alpha as well as excludes all .cc from being - processed by linter, in the current directory (where the .cfg - file is located) and all sub-directories. -""" - -# We categorize each error message we print. Here are the categories. -# We want an explicit list so we can list them all in cpplint --filter=. -# If you add a new error message with a new category, add it to the list -# here! cpplint_unittest.py should tell you if you forget to do this. -_ERROR_CATEGORIES = [ - 'build/class', - 'build/c++11', - 'build/c++14', - 'build/c++tr1', - 'build/deprecated', - 'build/endif_comment', - 'build/explicit_make_pair', - 'build/forward_decl', - 'build/header_guard', - 'build/include', - 'build/include_alpha', - 'build/include_order', - 'build/include_what_you_use', - 'build/namespaces', - 'build/printf_format', - 'build/storage_class', - 'legal/copyright', - 'readability/alt_tokens', - 'readability/braces', - 'readability/casting', - 'readability/check', - 'readability/constructors', - 'readability/fn_size', - 'readability/inheritance', - 'readability/multiline_comment', - 'readability/multiline_string', - 'readability/namespace', - 'readability/nolint', - 'readability/nul', - 'readability/strings', - 'readability/todo', - 'readability/utf8', - 'runtime/arrays', - 'runtime/casting', - 'runtime/explicit', - 'runtime/int', - 'runtime/init', - 'runtime/invalid_increment', - 'runtime/member_string_references', - 'runtime/memset', - 'runtime/indentation_namespace', - 'runtime/operator', - 'runtime/printf', - 'runtime/printf_format', - 'runtime/references', - 'runtime/string', - 'runtime/threadsafe_fn', - 'runtime/vlog', - 'whitespace/blank_line', - 'whitespace/braces', - 'whitespace/comma', - 'whitespace/comments', - 'whitespace/empty_conditional_body', - 'whitespace/empty_if_body', - 'whitespace/empty_loop_body', - 'whitespace/end_of_line', - 'whitespace/ending_newline', - 'whitespace/forcolon', - 'whitespace/indent', - 'whitespace/line_length', - 'whitespace/newline', - 'whitespace/operators', - 'whitespace/parens', - 'whitespace/semicolon', - 'whitespace/tab', - 'whitespace/todo', - ] - -# These error categories are no longer enforced by cpplint, but for backwards- -# compatibility they may still appear in NOLINT comments. -_LEGACY_ERROR_CATEGORIES = [ - 'readability/streams', - 'readability/function', - ] - -# The default state of the category filter. This is overridden by the --filter= -# flag. By default all errors are on, so only add here categories that should be -# off by default (i.e., categories that must be enabled by the --filter= flags). -# All entries here should start with a '-' or '+', as in the --filter= flag. -_DEFAULT_FILTERS = ['-build/include_alpha'] - -# The default list of categories suppressed for C (not C++) files. -_DEFAULT_C_SUPPRESSED_CATEGORIES = [ - 'readability/casting', - ] - -# The default list of categories suppressed for Linux Kernel files. -_DEFAULT_KERNEL_SUPPRESSED_CATEGORIES = [ - 'whitespace/tab', - ] - -# We used to check for high-bit characters, but after much discussion we -# decided those were OK, as long as they were in UTF-8 and didn't represent -# hard-coded international strings, which belong in a separate i18n file. - -# C++ headers -_CPP_HEADERS = frozenset([ - # Legacy - 'algobase.h', - 'algo.h', - 'alloc.h', - 'builtinbuf.h', - 'bvector.h', - 'complex.h', - 'defalloc.h', - 'deque.h', - 'editbuf.h', - 'fstream.h', - 'function.h', - 'hash_map', - 'hash_map.h', - 'hash_set', - 'hash_set.h', - 'hashtable.h', - 'heap.h', - 'indstream.h', - 'iomanip.h', - 'iostream.h', - 'istream.h', - 'iterator.h', - 'list.h', - 'map.h', - 'multimap.h', - 'multiset.h', - 'ostream.h', - 'pair.h', - 'parsestream.h', - 'pfstream.h', - 'procbuf.h', - 'pthread_alloc', - 'pthread_alloc.h', - 'rope', - 'rope.h', - 'ropeimpl.h', - 'set.h', - 'slist', - 'slist.h', - 'stack.h', - 'stdiostream.h', - 'stl_alloc.h', - 'stl_relops.h', - 'streambuf.h', - 'stream.h', - 'strfile.h', - 'strstream.h', - 'tempbuf.h', - 'tree.h', - 'type_traits.h', - 'vector.h', - # 17.6.1.2 C++ library headers - 'algorithm', - 'array', - 'atomic', - 'bitset', - 'chrono', - 'codecvt', - 'complex', - 'condition_variable', - 'deque', - 'exception', - 'forward_list', - 'fstream', - 'functional', - 'future', - 'initializer_list', - 'iomanip', - 'ios', - 'iosfwd', - 'iostream', - 'istream', - 'iterator', - 'limits', - 'list', - 'locale', - 'map', - 'memory', - 'mutex', - 'new', - 'numeric', - 'ostream', - 'queue', - 'random', - 'ratio', - 'regex', - 'scoped_allocator', - 'set', - 'sstream', - 'stack', - 'stdexcept', - 'streambuf', - 'string', - 'strstream', - 'system_error', - 'thread', - 'tuple', - 'typeindex', - 'typeinfo', - 'type_traits', - 'unordered_map', - 'unordered_set', - 'utility', - 'valarray', - 'vector', - # 17.6.1.2 C++ headers for C library facilities - 'cassert', - 'ccomplex', - 'cctype', - 'cerrno', - 'cfenv', - 'cfloat', - 'cinttypes', - 'ciso646', - 'climits', - 'clocale', - 'cmath', - 'csetjmp', - 'csignal', - 'cstdalign', - 'cstdarg', - 'cstdbool', - 'cstddef', - 'cstdint', - 'cstdio', - 'cstdlib', - 'cstring', - 'ctgmath', - 'ctime', - 'cuchar', - 'cwchar', - 'cwctype', - ]) - -# Type names -_TYPES = re.compile( - r'^(?:' - # [dcl.type.simple] - r'(char(16_t|32_t)?)|wchar_t|' - r'bool|short|int|long|signed|unsigned|float|double|' - # [support.types] - r'(ptrdiff_t|size_t|max_align_t|nullptr_t)|' - # [cstdint.syn] - r'(u?int(_fast|_least)?(8|16|32|64)_t)|' - r'(u?int(max|ptr)_t)|' - r')$') - - -# These headers are excluded from [build/include] and [build/include_order] -# checks: -# - Anything not following google file name conventions (containing an -# uppercase character, such as Python.h or nsStringAPI.h, for example). -# - Lua headers. -_THIRD_PARTY_HEADERS_PATTERN = re.compile( - r'^(?:[^/]*[A-Z][^/]*\.h|lua\.h|lauxlib\.h|lualib\.h)$') - -# Pattern for matching FileInfo.BaseName() against test file name -_TEST_FILE_SUFFIX = r'(_test|_unittest|_regtest)$' - -# Pattern that matches only complete whitespace, possibly across multiple lines. -_EMPTY_CONDITIONAL_BODY_PATTERN = re.compile(r'^\s*$', re.DOTALL) - -# Assertion macros. These are defined in base/logging.h and -# testing/base/public/gunit.h. -_CHECK_MACROS = [ - 'DCHECK', 'CHECK', - 'EXPECT_TRUE', 'ASSERT_TRUE', - 'EXPECT_FALSE', 'ASSERT_FALSE', - ] - -# Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE -_CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS]) - -for op, replacement in [('==', 'EQ'), ('!=', 'NE'), - ('>=', 'GE'), ('>', 'GT'), - ('<=', 'LE'), ('<', 'LT')]: - _CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement - _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement - _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement - _CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement - -for op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'), - ('>=', 'LT'), ('>', 'LE'), - ('<=', 'GT'), ('<', 'GE')]: - _CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement - _CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement - -# Alternative tokens and their replacements. For full list, see section 2.5 -# Alternative tokens [lex.digraph] in the C++ standard. -# -# Digraphs (such as '%:') are not included here since it's a mess to -# match those on a word boundary. -_ALT_TOKEN_REPLACEMENT = { - 'and': '&&', - 'bitor': '|', - 'or': '||', - 'xor': '^', - 'compl': '~', - 'bitand': '&', - 'and_eq': '&=', - 'or_eq': '|=', - 'xor_eq': '^=', - 'not': '!', - 'not_eq': '!=' - } - -# Compile regular expression that matches all the above keywords. The "[ =()]" -# bit is meant to avoid matching these keywords outside of boolean expressions. -# -# False positives include C-style multi-line comments and multi-line strings -# but those have always been troublesome for cpplint. -_ALT_TOKEN_REPLACEMENT_PATTERN = re.compile( - r'[ =()](' + ('|'.join(_ALT_TOKEN_REPLACEMENT.keys())) + r')(?=[ (]|$)') - - -# These constants define types of headers for use with -# _IncludeState.CheckNextIncludeOrder(). -_C_SYS_HEADER = 1 -_CPP_SYS_HEADER = 2 -_LIKELY_MY_HEADER = 3 -_POSSIBLE_MY_HEADER = 4 -_OTHER_HEADER = 5 - -# These constants define the current inline assembly state -_NO_ASM = 0 # Outside of inline assembly block -_INSIDE_ASM = 1 # Inside inline assembly block -_END_ASM = 2 # Last line of inline assembly block -_BLOCK_ASM = 3 # The whole block is an inline assembly block - -# Match start of assembly blocks -_MATCH_ASM = re.compile(r'^\s*(?:asm|_asm|__asm|__asm__)' - r'(?:\s+(volatile|__volatile__))?' - r'\s*[{(]') - -# Match strings that indicate we're working on a C (not C++) file. -_SEARCH_C_FILE = re.compile(r'\b(?:LINT_C_FILE|' - r'vim?:\s*.*(\s*|:)filetype=c(\s*|:|$))') - -# Match string that indicates we're working on a Linux Kernel file. -_SEARCH_KERNEL_FILE = re.compile(r'\b(?:LINT_KERNEL_FILE)') - -_regexp_compile_cache = {} - -# {str, set(int)}: a map from error categories to sets of linenumbers -# on which those errors are expected and should be suppressed. -_error_suppressions = {} - -# The root directory used for deriving header guard CPP variable. -# This is set by --root flag. -_root = None -_root_debug = False - -# The allowed line length of files. -# This is set by --linelength flag. -_line_length = 80 - -# The allowed extensions for file names -# This is set by --extensions flag. -_valid_extensions = set(['cc', 'h', 'cpp', 'cu', 'cuh']) - -# Treat all headers starting with 'h' equally: .h, .hpp, .hxx etc. -# This is set by --headers flag. -_hpp_headers = set(['h']) - -# {str, bool}: a map from error categories to booleans which indicate if the -# category should be suppressed for every line. -_global_error_suppressions = {} - -def ProcessHppHeadersOption(val): - global _hpp_headers - try: - _hpp_headers = set(val.split(',')) - # Automatically append to extensions list so it does not have to be set 2 times - _valid_extensions.update(_hpp_headers) - except ValueError: - PrintUsage('Header extensions must be comma separated list.') - -def IsHeaderExtension(file_extension): - return file_extension in _hpp_headers - -def ParseNolintSuppressions(filename, raw_line, linenum, error): - """Updates the global list of line error-suppressions. - - Parses any NOLINT comments on the current line, updating the global - error_suppressions store. Reports an error if the NOLINT comment - was malformed. - - Args: - filename: str, the name of the input file. - raw_line: str, the line of input text, with comments. - linenum: int, the number of the current line. - error: function, an error handler. - """ - matched = Search(r'\bNOLINT(NEXTLINE)?\b(\([^)]+\))?', raw_line) - if matched: - if matched.group(1): - suppressed_line = linenum + 1 - else: - suppressed_line = linenum - category = matched.group(2) - if category in (None, '(*)'): # => "suppress all" - _error_suppressions.setdefault(None, set()).add(suppressed_line) - else: - if category.startswith('(') and category.endswith(')'): - category = category[1:-1] - if category in _ERROR_CATEGORIES: - _error_suppressions.setdefault(category, set()).add(suppressed_line) - elif category not in _LEGACY_ERROR_CATEGORIES: - error(filename, linenum, 'readability/nolint', 5, - 'Unknown NOLINT error category: %s' % category) - - -def ProcessGlobalSuppresions(lines): - """Updates the list of global error suppressions. - - Parses any lint directives in the file that have global effect. - - Args: - lines: An array of strings, each representing a line of the file, with the - last element being empty if the file is terminated with a newline. - """ - for line in lines: - if _SEARCH_C_FILE.search(line): - for category in _DEFAULT_C_SUPPRESSED_CATEGORIES: - _global_error_suppressions[category] = True - if _SEARCH_KERNEL_FILE.search(line): - for category in _DEFAULT_KERNEL_SUPPRESSED_CATEGORIES: - _global_error_suppressions[category] = True - - -def ResetNolintSuppressions(): - """Resets the set of NOLINT suppressions to empty.""" - _error_suppressions.clear() - _global_error_suppressions.clear() - - -def IsErrorSuppressedByNolint(category, linenum): - """Returns true if the specified error category is suppressed on this line. - - Consults the global error_suppressions map populated by - ParseNolintSuppressions/ProcessGlobalSuppresions/ResetNolintSuppressions. - - Args: - category: str, the category of the error. - linenum: int, the current line number. - Returns: - bool, True iff the error should be suppressed due to a NOLINT comment or - global suppression. - """ - return (_global_error_suppressions.get(category, False) or - linenum in _error_suppressions.get(category, set()) or - linenum in _error_suppressions.get(None, set())) - - -def Match(pattern, s): - """Matches the string with the pattern, caching the compiled regexp.""" - # The regexp compilation caching is inlined in both Match and Search for - # performance reasons; factoring it out into a separate function turns out - # to be noticeably expensive. - if pattern not in _regexp_compile_cache: - _regexp_compile_cache[pattern] = sre_compile.compile(pattern) - return _regexp_compile_cache[pattern].match(s) - - -def ReplaceAll(pattern, rep, s): - """Replaces instances of pattern in a string with a replacement. - - The compiled regex is kept in a cache shared by Match and Search. - - Args: - pattern: regex pattern - rep: replacement text - s: search string - - Returns: - string with replacements made (or original string if no replacements) - """ - if pattern not in _regexp_compile_cache: - _regexp_compile_cache[pattern] = sre_compile.compile(pattern) - return _regexp_compile_cache[pattern].sub(rep, s) - - -def Search(pattern, s): - """Searches the string for the pattern, caching the compiled regexp.""" - if pattern not in _regexp_compile_cache: - _regexp_compile_cache[pattern] = sre_compile.compile(pattern) - return _regexp_compile_cache[pattern].search(s) - - -def _IsSourceExtension(s): - """File extension (excluding dot) matches a source file extension.""" - return s in ('c', 'cc', 'cpp', 'cxx') - - -class _IncludeState(object): - """Tracks line numbers for includes, and the order in which includes appear. - - include_list contains list of lists of (header, line number) pairs. - It's a lists of lists rather than just one flat list to make it - easier to update across preprocessor boundaries. - - Call CheckNextIncludeOrder() once for each header in the file, passing - in the type constants defined above. Calls in an illegal order will - raise an _IncludeError with an appropriate error message. - - """ - # self._section will move monotonically through this set. If it ever - # needs to move backwards, CheckNextIncludeOrder will raise an error. - _INITIAL_SECTION = 0 - _MY_H_SECTION = 1 - _C_SECTION = 2 - _CPP_SECTION = 3 - _OTHER_H_SECTION = 4 - - _TYPE_NAMES = { - _C_SYS_HEADER: 'C system header', - _CPP_SYS_HEADER: 'C++ system header', - _LIKELY_MY_HEADER: 'header this file implements', - _POSSIBLE_MY_HEADER: 'header this file may implement', - _OTHER_HEADER: 'other header', - } - _SECTION_NAMES = { - _INITIAL_SECTION: "... nothing. (This can't be an error.)", - _MY_H_SECTION: 'a header this file implements', - _C_SECTION: 'C system header', - _CPP_SECTION: 'C++ system header', - _OTHER_H_SECTION: 'other header', - } - - def __init__(self): - self.include_list = [[]] - self.ResetSection('') - - def FindHeader(self, header): - """Check if a header has already been included. - - Args: - header: header to check. - Returns: - Line number of previous occurrence, or -1 if the header has not - been seen before. - """ - for section_list in self.include_list: - for f in section_list: - if f[0] == header: - return f[1] - return -1 - - def ResetSection(self, directive): - """Reset section checking for preprocessor directive. - - Args: - directive: preprocessor directive (e.g. "if", "else"). - """ - # The name of the current section. - self._section = self._INITIAL_SECTION - # The path of last found header. - self._last_header = '' - - # Update list of includes. Note that we never pop from the - # include list. - if directive in ('if', 'ifdef', 'ifndef'): - self.include_list.append([]) - elif directive in ('else', 'elif'): - self.include_list[-1] = [] - - def SetLastHeader(self, header_path): - self._last_header = header_path - - def CanonicalizeAlphabeticalOrder(self, header_path): - """Returns a path canonicalized for alphabetical comparison. - - - replaces "-" with "_" so they both cmp the same. - - removes '-inl' since we don't require them to be after the main header. - - lowercase everything, just in case. - - Args: - header_path: Path to be canonicalized. - - Returns: - Canonicalized path. - """ - return header_path.replace('-inl.h', '.h').replace('-', '_').lower() - - def IsInAlphabeticalOrder(self, clean_lines, linenum, header_path): - """Check if a header is in alphabetical order with the previous header. - - Args: - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - header_path: Canonicalized header to be checked. - - Returns: - Returns true if the header is in alphabetical order. - """ - # If previous section is different from current section, _last_header will - # be reset to empty string, so it's always less than current header. - # - # If previous line was a blank line, assume that the headers are - # intentionally sorted the way they are. - if (self._last_header > header_path and - Match(r'^\s*#\s*include\b', clean_lines.elided[linenum - 1])): - return False - return True - - def CheckNextIncludeOrder(self, header_type): - """Returns a non-empty error message if the next header is out of order. - - This function also updates the internal state to be ready to check - the next include. - - Args: - header_type: One of the _XXX_HEADER constants defined above. - - Returns: - The empty string if the header is in the right order, or an - error message describing what's wrong. - - """ - error_message = ('Found %s after %s' % - (self._TYPE_NAMES[header_type], - self._SECTION_NAMES[self._section])) - - last_section = self._section - - if header_type == _C_SYS_HEADER: - if self._section <= self._C_SECTION: - self._section = self._C_SECTION - else: - self._last_header = '' - return error_message - elif header_type == _CPP_SYS_HEADER: - if self._section <= self._CPP_SECTION: - self._section = self._CPP_SECTION - else: - self._last_header = '' - return error_message - elif header_type == _LIKELY_MY_HEADER: - if self._section <= self._MY_H_SECTION: - self._section = self._MY_H_SECTION - else: - self._section = self._OTHER_H_SECTION - elif header_type == _POSSIBLE_MY_HEADER: - if self._section <= self._MY_H_SECTION: - self._section = self._MY_H_SECTION - else: - # This will always be the fallback because we're not sure - # enough that the header is associated with this file. - self._section = self._OTHER_H_SECTION - else: - assert header_type == _OTHER_HEADER - self._section = self._OTHER_H_SECTION - - if last_section != self._section: - self._last_header = '' - - return '' - - -class _CppLintState(object): - """Maintains module-wide state..""" - - def __init__(self): - self.verbose_level = 1 # global setting. - self.error_count = 0 # global count of reported errors - # filters to apply when emitting error messages - self.filters = _DEFAULT_FILTERS[:] - # backup of filter list. Used to restore the state after each file. - self._filters_backup = self.filters[:] - self.counting = 'total' # In what way are we counting errors? - self.errors_by_category = {} # string to int dict storing error counts - self.quiet = False # Suppress non-error messagess? - - # output format: - # "emacs" - format that emacs can parse (default) - # "vs7" - format that Microsoft Visual Studio 7 can parse - self.output_format = 'emacs' - - def SetOutputFormat(self, output_format): - """Sets the output format for errors.""" - self.output_format = output_format - - def SetQuiet(self, quiet): - """Sets the module's quiet settings, and returns the previous setting.""" - last_quiet = self.quiet - self.quiet = quiet - return last_quiet - - def SetVerboseLevel(self, level): - """Sets the module's verbosity, and returns the previous setting.""" - last_verbose_level = self.verbose_level - self.verbose_level = level - return last_verbose_level - - def SetCountingStyle(self, counting_style): - """Sets the module's counting options.""" - self.counting = counting_style - - def SetFilters(self, filters): - """Sets the error-message filters. - - These filters are applied when deciding whether to emit a given - error message. - - Args: - filters: A string of comma-separated filters (eg "+whitespace/indent"). - Each filter should start with + or -; else we die. - - Raises: - ValueError: The comma-separated filters did not all start with '+' or '-'. - E.g. "-,+whitespace,-whitespace/indent,whitespace/badfilter" - """ - # Default filters always have less priority than the flag ones. - self.filters = _DEFAULT_FILTERS[:] - self.AddFilters(filters) - - def AddFilters(self, filters): - """ Adds more filters to the existing list of error-message filters. """ - for filt in filters.split(','): - clean_filt = filt.strip() - if clean_filt: - self.filters.append(clean_filt) - for filt in self.filters: - if not (filt.startswith('+') or filt.startswith('-')): - raise ValueError('Every filter in --filters must start with + or -' - ' (%s does not)' % filt) - - def BackupFilters(self): - """ Saves the current filter list to backup storage.""" - self._filters_backup = self.filters[:] - - def RestoreFilters(self): - """ Restores filters previously backed up.""" - self.filters = self._filters_backup[:] - - def ResetErrorCounts(self): - """Sets the module's error statistic back to zero.""" - self.error_count = 0 - self.errors_by_category = {} - - def IncrementErrorCount(self, category): - """Bumps the module's error statistic.""" - self.error_count += 1 - if self.counting in ('toplevel', 'detailed'): - if self.counting != 'detailed': - category = category.split('/')[0] - if category not in self.errors_by_category: - self.errors_by_category[category] = 0 - self.errors_by_category[category] += 1 - - def PrintErrorCounts(self): - """Print a summary of errors by category, and the total.""" - for category, count in self.errors_by_category.iteritems(): - sys.stderr.write('Category \'%s\' errors found: %d\n' % - (category, count)) - sys.stdout.write('Total errors found: %d\n' % self.error_count) - -_cpplint_state = _CppLintState() - - -def _OutputFormat(): - """Gets the module's output format.""" - return _cpplint_state.output_format - - -def _SetOutputFormat(output_format): - """Sets the module's output format.""" - _cpplint_state.SetOutputFormat(output_format) - -def _Quiet(): - """Return's the module's quiet setting.""" - return _cpplint_state.quiet - -def _SetQuiet(quiet): - """Set the module's quiet status, and return previous setting.""" - return _cpplint_state.SetQuiet(quiet) - - -def _VerboseLevel(): - """Returns the module's verbosity setting.""" - return _cpplint_state.verbose_level - - -def _SetVerboseLevel(level): - """Sets the module's verbosity, and returns the previous setting.""" - return _cpplint_state.SetVerboseLevel(level) - - -def _SetCountingStyle(level): - """Sets the module's counting options.""" - _cpplint_state.SetCountingStyle(level) - - -def _Filters(): - """Returns the module's list of output filters, as a list.""" - return _cpplint_state.filters - - -def _SetFilters(filters): - """Sets the module's error-message filters. - - These filters are applied when deciding whether to emit a given - error message. - - Args: - filters: A string of comma-separated filters (eg "whitespace/indent"). - Each filter should start with + or -; else we die. - """ - _cpplint_state.SetFilters(filters) - -def _AddFilters(filters): - """Adds more filter overrides. - - Unlike _SetFilters, this function does not reset the current list of filters - available. - - Args: - filters: A string of comma-separated filters (eg "whitespace/indent"). - Each filter should start with + or -; else we die. - """ - _cpplint_state.AddFilters(filters) - -def _BackupFilters(): - """ Saves the current filter list to backup storage.""" - _cpplint_state.BackupFilters() - -def _RestoreFilters(): - """ Restores filters previously backed up.""" - _cpplint_state.RestoreFilters() - -class _FunctionState(object): - """Tracks current function name and the number of lines in its body.""" - - _NORMAL_TRIGGER = 250 # for --v=0, 500 for --v=1, etc. - _TEST_TRIGGER = 400 # about 50% more than _NORMAL_TRIGGER. - - def __init__(self): - self.in_a_function = False - self.lines_in_function = 0 - self.current_function = '' - - def Begin(self, function_name): - """Start analyzing function body. - - Args: - function_name: The name of the function being tracked. - """ - self.in_a_function = True - self.lines_in_function = 0 - self.current_function = function_name - - def Count(self): - """Count line in current function body.""" - if self.in_a_function: - self.lines_in_function += 1 - - def Check(self, error, filename, linenum): - """Report if too many lines in function body. - - Args: - error: The function to call with any errors found. - filename: The name of the current file. - linenum: The number of the line to check. - """ - if not self.in_a_function: - return - - if Match(r'T(EST|est)', self.current_function): - base_trigger = self._TEST_TRIGGER - else: - base_trigger = self._NORMAL_TRIGGER - trigger = base_trigger * 2**_VerboseLevel() - - if self.lines_in_function > trigger: - error_level = int(math.log(self.lines_in_function / base_trigger, 2)) - # 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ... - if error_level > 5: - error_level = 5 - error(filename, linenum, 'readability/fn_size', error_level, - 'Small and focused functions are preferred:' - ' %s has %d non-comment lines' - ' (error triggered by exceeding %d lines).' % ( - self.current_function, self.lines_in_function, trigger)) - - def End(self): - """Stop analyzing function body.""" - self.in_a_function = False - - -class _IncludeError(Exception): - """Indicates a problem with the include order in a file.""" - pass - - -class FileInfo(object): - """Provides utility functions for filenames. - - FileInfo provides easy access to the components of a file's path - relative to the project root. - """ - - def __init__(self, filename): - self._filename = filename - - def FullName(self): - """Make Windows paths like Unix.""" - return os.path.abspath(self._filename).replace('\\', '/') - - def RepositoryName(self): - """FullName after removing the local path to the repository. - - If we have a real absolute path name here we can try to do something smart: - detecting the root of the checkout and truncating /path/to/checkout from - the name so that we get header guards that don't include things like - "C:\Documents and Settings\..." or "/home/username/..." in them and thus - people on different computers who have checked the source out to different - locations won't see bogus errors. - """ - fullname = self.FullName() - - if os.path.exists(fullname): - project_dir = os.path.dirname(fullname) - - if os.path.exists(os.path.join(project_dir, ".svn")): - # If there's a .svn file in the current directory, we recursively look - # up the directory tree for the top of the SVN checkout - root_dir = project_dir - one_up_dir = os.path.dirname(root_dir) - while os.path.exists(os.path.join(one_up_dir, ".svn")): - root_dir = os.path.dirname(root_dir) - one_up_dir = os.path.dirname(one_up_dir) - - prefix = os.path.commonprefix([root_dir, project_dir]) - return fullname[len(prefix) + 1:] - - # Not SVN <= 1.6? Try to find a git, hg, or svn top level directory by - # searching up from the current path. - root_dir = current_dir = os.path.dirname(fullname) - while current_dir != os.path.dirname(current_dir): - if (os.path.exists(os.path.join(current_dir, ".git")) or - os.path.exists(os.path.join(current_dir, ".hg")) or - os.path.exists(os.path.join(current_dir, ".svn"))): - root_dir = current_dir - current_dir = os.path.dirname(current_dir) - - if (os.path.exists(os.path.join(root_dir, ".git")) or - os.path.exists(os.path.join(root_dir, ".hg")) or - os.path.exists(os.path.join(root_dir, ".svn"))): - prefix = os.path.commonprefix([root_dir, project_dir]) - return fullname[len(prefix) + 1:] - - # Don't know what to do; header guard warnings may be wrong... - return fullname - - def Split(self): - """Splits the file into the directory, basename, and extension. - - For 'chrome/browser/browser.cc', Split() would - return ('chrome/browser', 'browser', '.cc') - - Returns: - A tuple of (directory, basename, extension). - """ - - googlename = self.RepositoryName() - project, rest = os.path.split(googlename) - return (project,) + os.path.splitext(rest) - - def BaseName(self): - """File base name - text after the final slash, before the final period.""" - return self.Split()[1] - - def Extension(self): - """File extension - text following the final period.""" - return self.Split()[2] - - def NoExtension(self): - """File has no source file extension.""" - return '/'.join(self.Split()[0:2]) - - def IsSource(self): - """File has a source file extension.""" - return _IsSourceExtension(self.Extension()[1:]) - - -def _ShouldPrintError(category, confidence, linenum): - """If confidence >= verbose, category passes filter and is not suppressed.""" - - # There are three ways we might decide not to print an error message: - # a "NOLINT(category)" comment appears in the source, - # the verbosity level isn't high enough, or the filters filter it out. - if IsErrorSuppressedByNolint(category, linenum): - return False - - if confidence < _cpplint_state.verbose_level: - return False - - is_filtered = False - for one_filter in _Filters(): - if one_filter.startswith('-'): - if category.startswith(one_filter[1:]): - is_filtered = True - elif one_filter.startswith('+'): - if category.startswith(one_filter[1:]): - is_filtered = False - else: - assert False # should have been checked for in SetFilter. - if is_filtered: - return False - - return True - - -def Error(filename, linenum, category, confidence, message): - """Logs the fact we've found a lint error. - - We log where the error was found, and also our confidence in the error, - that is, how certain we are this is a legitimate style regression, and - not a misidentification or a use that's sometimes justified. - - False positives can be suppressed by the use of - "cpplint(category)" comments on the offending line. These are - parsed into _error_suppressions. - - Args: - filename: The name of the file containing the error. - linenum: The number of the line containing the error. - category: A string used to describe the "category" this bug - falls under: "whitespace", say, or "runtime". Categories - may have a hierarchy separated by slashes: "whitespace/indent". - confidence: A number from 1-5 representing a confidence score for - the error, with 5 meaning that we are certain of the problem, - and 1 meaning that it could be a legitimate construct. - message: The error message. - """ - if _ShouldPrintError(category, confidence, linenum): - _cpplint_state.IncrementErrorCount(category) - if _cpplint_state.output_format == 'vs7': - sys.stderr.write('%s(%s): error cpplint: [%s] %s [%d]\n' % ( - filename, linenum, category, message, confidence)) - elif _cpplint_state.output_format == 'eclipse': - sys.stderr.write('%s:%s: warning: %s [%s] [%d]\n' % ( - filename, linenum, message, category, confidence)) - else: - sys.stderr.write('%s:%s: %s [%s] [%d]\n' % ( - filename, linenum, message, category, confidence)) - - -# Matches standard C++ escape sequences per 2.13.2.3 of the C++ standard. -_RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile( - r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)') -# Match a single C style comment on the same line. -_RE_PATTERN_C_COMMENTS = r'/\*(?:[^*]|\*(?!/))*\*/' -# Matches multi-line C style comments. -# This RE is a little bit more complicated than one might expect, because we -# have to take care of space removals tools so we can handle comments inside -# statements better. -# The current rule is: We only clear spaces from both sides when we're at the -# end of the line. Otherwise, we try to remove spaces from the right side, -# if this doesn't work we try on left side but only if there's a non-character -# on the right. -_RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile( - r'(\s*' + _RE_PATTERN_C_COMMENTS + r'\s*$|' + - _RE_PATTERN_C_COMMENTS + r'\s+|' + - r'\s+' + _RE_PATTERN_C_COMMENTS + r'(?=\W)|' + - _RE_PATTERN_C_COMMENTS + r')') - - -def IsCppString(line): - """Does line terminate so, that the next symbol is in string constant. - - This function does not consider single-line nor multi-line comments. - - Args: - line: is a partial line of code starting from the 0..n. - - Returns: - True, if next character appended to 'line' is inside a - string constant. - """ - - line = line.replace(r'\\', 'XX') # after this, \\" does not match to \" - return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1 - - -def CleanseRawStrings(raw_lines): - """Removes C++11 raw strings from lines. - - Before: - static const char kData[] = R"( - multi-line string - )"; - - After: - static const char kData[] = "" - (replaced by blank line) - ""; - - Args: - raw_lines: list of raw lines. - - Returns: - list of lines with C++11 raw strings replaced by empty strings. - """ - - delimiter = None - lines_without_raw_strings = [] - for line in raw_lines: - if delimiter: - # Inside a raw string, look for the end - end = line.find(delimiter) - if end >= 0: - # Found the end of the string, match leading space for this - # line and resume copying the original lines, and also insert - # a "" on the last line. - leading_space = Match(r'^(\s*)\S', line) - line = leading_space.group(1) + '""' + line[end + len(delimiter):] - delimiter = None - else: - # Haven't found the end yet, append a blank line. - line = '""' - - # Look for beginning of a raw string, and replace them with - # empty strings. This is done in a loop to handle multiple raw - # strings on the same line. - while delimiter is None: - # Look for beginning of a raw string. - # See 2.14.15 [lex.string] for syntax. - # - # Once we have matched a raw string, we check the prefix of the - # line to make sure that the line is not part of a single line - # comment. It's done this way because we remove raw strings - # before removing comments as opposed to removing comments - # before removing raw strings. This is because there are some - # cpplint checks that requires the comments to be preserved, but - # we don't want to check comments that are inside raw strings. - matched = Match(r'^(.*?)\b(?:R|u8R|uR|UR|LR)"([^\s\\()]*)\((.*)$', line) - if (matched and - not Match(r'^([^\'"]|\'(\\.|[^\'])*\'|"(\\.|[^"])*")*//', - matched.group(1))): - delimiter = ')' + matched.group(2) + '"' - - end = matched.group(3).find(delimiter) - if end >= 0: - # Raw string ended on same line - line = (matched.group(1) + '""' + - matched.group(3)[end + len(delimiter):]) - delimiter = None - else: - # Start of a multi-line raw string - line = matched.group(1) + '""' - else: - break - - lines_without_raw_strings.append(line) - - # TODO(unknown): if delimiter is not None here, we might want to - # emit a warning for unterminated string. - return lines_without_raw_strings - - -def FindNextMultiLineCommentStart(lines, lineix): - """Find the beginning marker for a multiline comment.""" - while lineix < len(lines): - if lines[lineix].strip().startswith('/*'): - # Only return this marker if the comment goes beyond this line - if lines[lineix].strip().find('*/', 2) < 0: - return lineix - lineix += 1 - return len(lines) - - -def FindNextMultiLineCommentEnd(lines, lineix): - """We are inside a comment, find the end marker.""" - while lineix < len(lines): - if lines[lineix].strip().endswith('*/'): - return lineix - lineix += 1 - return len(lines) - - -def RemoveMultiLineCommentsFromRange(lines, begin, end): - """Clears a range of lines for multi-line comments.""" - # Having // comments makes the lines non-empty, so we will not get - # unnecessary blank line warnings later in the code. - for i in range(begin, end): - lines[i] = '/**/' - - -def RemoveMultiLineComments(filename, lines, error): - """Removes multiline (c-style) comments from lines.""" - lineix = 0 - while lineix < len(lines): - lineix_begin = FindNextMultiLineCommentStart(lines, lineix) - if lineix_begin >= len(lines): - return - lineix_end = FindNextMultiLineCommentEnd(lines, lineix_begin) - if lineix_end >= len(lines): - error(filename, lineix_begin + 1, 'readability/multiline_comment', 5, - 'Could not find end of multi-line comment') - return - RemoveMultiLineCommentsFromRange(lines, lineix_begin, lineix_end + 1) - lineix = lineix_end + 1 - - -def CleanseComments(line): - """Removes //-comments and single-line C-style /* */ comments. - - Args: - line: A line of C++ source. - - Returns: - The line with single-line comments removed. - """ - commentpos = line.find('//') - if commentpos != -1 and not IsCppString(line[:commentpos]): - line = line[:commentpos].rstrip() - # get rid of /* ... */ - return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line) - - -class CleansedLines(object): - """Holds 4 copies of all lines with different preprocessing applied to them. - - 1) elided member contains lines without strings and comments. - 2) lines member contains lines without comments. - 3) raw_lines member contains all the lines without processing. - 4) lines_without_raw_strings member is same as raw_lines, but with C++11 raw - strings removed. - All these members are of , and of the same length. - """ - - def __init__(self, lines): - self.elided = [] - self.lines = [] - self.raw_lines = lines - self.num_lines = len(lines) - self.lines_without_raw_strings = CleanseRawStrings(lines) - for linenum in range(len(self.lines_without_raw_strings)): - self.lines.append(CleanseComments( - self.lines_without_raw_strings[linenum])) - elided = self._CollapseStrings(self.lines_without_raw_strings[linenum]) - self.elided.append(CleanseComments(elided)) - - def NumLines(self): - """Returns the number of lines represented.""" - return self.num_lines - - @staticmethod - def _CollapseStrings(elided): - """Collapses strings and chars on a line to simple "" or '' blocks. - - We nix strings first so we're not fooled by text like '"http://"' - - Args: - elided: The line being processed. - - Returns: - The line with collapsed strings. - """ - if _RE_PATTERN_INCLUDE.match(elided): - return elided - - # Remove escaped characters first to make quote/single quote collapsing - # basic. Things that look like escaped characters shouldn't occur - # outside of strings and chars. - elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided) - - # Replace quoted strings and digit separators. Both single quotes - # and double quotes are processed in the same loop, otherwise - # nested quotes wouldn't work. - collapsed = '' - while True: - # Find the first quote character - match = Match(r'^([^\'"]*)([\'"])(.*)$', elided) - if not match: - collapsed += elided - break - head, quote, tail = match.groups() - - if quote == '"': - # Collapse double quoted strings - second_quote = tail.find('"') - if second_quote >= 0: - collapsed += head + '""' - elided = tail[second_quote + 1:] - else: - # Unmatched double quote, don't bother processing the rest - # of the line since this is probably a multiline string. - collapsed += elided - break - else: - # Found single quote, check nearby text to eliminate digit separators. - # - # There is no special handling for floating point here, because - # the integer/fractional/exponent parts would all be parsed - # correctly as long as there are digits on both sides of the - # separator. So we are fine as long as we don't see something - # like "0.'3" (gcc 4.9.0 will not allow this literal). - if Search(r'\b(?:0[bBxX]?|[1-9])[0-9a-fA-F]*$', head): - match_literal = Match(r'^((?:\'?[0-9a-zA-Z_])*)(.*)$', "'" + tail) - collapsed += head + match_literal.group(1).replace("'", '') - elided = match_literal.group(2) - else: - second_quote = tail.find('\'') - if second_quote >= 0: - collapsed += head + "''" - elided = tail[second_quote + 1:] - else: - # Unmatched single quote - collapsed += elided - break - - return collapsed - - -def FindEndOfExpressionInLine(line, startpos, stack): - """Find the position just after the end of current parenthesized expression. - - Args: - line: a CleansedLines line. - startpos: start searching at this position. - stack: nesting stack at startpos. - - Returns: - On finding matching end: (index just after matching end, None) - On finding an unclosed expression: (-1, None) - Otherwise: (-1, new stack at end of this line) - """ - for i in xrange(startpos, len(line)): - char = line[i] - if char in '([{': - # Found start of parenthesized expression, push to expression stack - stack.append(char) - elif char == '<': - # Found potential start of template argument list - if i > 0 and line[i - 1] == '<': - # Left shift operator - if stack and stack[-1] == '<': - stack.pop() - if not stack: - return (-1, None) - elif i > 0 and Search(r'\boperator\s*$', line[0:i]): - # operator<, don't add to stack - continue - else: - # Tentative start of template argument list - stack.append('<') - elif char in ')]}': - # Found end of parenthesized expression. - # - # If we are currently expecting a matching '>', the pending '<' - # must have been an operator. Remove them from expression stack. - while stack and stack[-1] == '<': - stack.pop() - if not stack: - return (-1, None) - if ((stack[-1] == '(' and char == ')') or - (stack[-1] == '[' and char == ']') or - (stack[-1] == '{' and char == '}')): - stack.pop() - if not stack: - return (i + 1, None) - else: - # Mismatched parentheses - return (-1, None) - elif char == '>': - # Found potential end of template argument list. - - # Ignore "->" and operator functions - if (i > 0 and - (line[i - 1] == '-' or Search(r'\boperator\s*$', line[0:i - 1]))): - continue - - # Pop the stack if there is a matching '<'. Otherwise, ignore - # this '>' since it must be an operator. - if stack: - if stack[-1] == '<': - stack.pop() - if not stack: - return (i + 1, None) - elif char == ';': - # Found something that look like end of statements. If we are currently - # expecting a '>', the matching '<' must have been an operator, since - # template argument list should not contain statements. - while stack and stack[-1] == '<': - stack.pop() - if not stack: - return (-1, None) - - # Did not find end of expression or unbalanced parentheses on this line - return (-1, stack) - - -def CloseExpression(clean_lines, linenum, pos): - """If input points to ( or { or [ or <, finds the position that closes it. - - If lines[linenum][pos] points to a '(' or '{' or '[' or '<', finds the - linenum/pos that correspond to the closing of the expression. - - TODO(unknown): cpplint spends a fair bit of time matching parentheses. - Ideally we would want to index all opening and closing parentheses once - and have CloseExpression be just a simple lookup, but due to preprocessor - tricks, this is not so easy. - - Args: - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - pos: A position on the line. - - Returns: - A tuple (line, linenum, pos) pointer *past* the closing brace, or - (line, len(lines), -1) if we never find a close. Note we ignore - strings and comments when matching; and the line we return is the - 'cleansed' line at linenum. - """ - - line = clean_lines.elided[linenum] - if (line[pos] not in '({[<') or Match(r'<[<=]', line[pos:]): - return (line, clean_lines.NumLines(), -1) - - # Check first line - (end_pos, stack) = FindEndOfExpressionInLine(line, pos, []) - if end_pos > -1: - return (line, linenum, end_pos) - - # Continue scanning forward - while stack and linenum < clean_lines.NumLines() - 1: - linenum += 1 - line = clean_lines.elided[linenum] - (end_pos, stack) = FindEndOfExpressionInLine(line, 0, stack) - if end_pos > -1: - return (line, linenum, end_pos) - - # Did not find end of expression before end of file, give up - return (line, clean_lines.NumLines(), -1) - - -def FindStartOfExpressionInLine(line, endpos, stack): - """Find position at the matching start of current expression. - - This is almost the reverse of FindEndOfExpressionInLine, but note - that the input position and returned position differs by 1. - - Args: - line: a CleansedLines line. - endpos: start searching at this position. - stack: nesting stack at endpos. - - Returns: - On finding matching start: (index at matching start, None) - On finding an unclosed expression: (-1, None) - Otherwise: (-1, new stack at beginning of this line) - """ - i = endpos - while i >= 0: - char = line[i] - if char in ')]}': - # Found end of expression, push to expression stack - stack.append(char) - elif char == '>': - # Found potential end of template argument list. - # - # Ignore it if it's a "->" or ">=" or "operator>" - if (i > 0 and - (line[i - 1] == '-' or - Match(r'\s>=\s', line[i - 1:]) or - Search(r'\boperator\s*$', line[0:i]))): - i -= 1 - else: - stack.append('>') - elif char == '<': - # Found potential start of template argument list - if i > 0 and line[i - 1] == '<': - # Left shift operator - i -= 1 - else: - # If there is a matching '>', we can pop the expression stack. - # Otherwise, ignore this '<' since it must be an operator. - if stack and stack[-1] == '>': - stack.pop() - if not stack: - return (i, None) - elif char in '([{': - # Found start of expression. - # - # If there are any unmatched '>' on the stack, they must be - # operators. Remove those. - while stack and stack[-1] == '>': - stack.pop() - if not stack: - return (-1, None) - if ((char == '(' and stack[-1] == ')') or - (char == '[' and stack[-1] == ']') or - (char == '{' and stack[-1] == '}')): - stack.pop() - if not stack: - return (i, None) - else: - # Mismatched parentheses - return (-1, None) - elif char == ';': - # Found something that look like end of statements. If we are currently - # expecting a '<', the matching '>' must have been an operator, since - # template argument list should not contain statements. - while stack and stack[-1] == '>': - stack.pop() - if not stack: - return (-1, None) - - i -= 1 - - return (-1, stack) - - -def ReverseCloseExpression(clean_lines, linenum, pos): - """If input points to ) or } or ] or >, finds the position that opens it. - - If lines[linenum][pos] points to a ')' or '}' or ']' or '>', finds the - linenum/pos that correspond to the opening of the expression. - - Args: - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - pos: A position on the line. - - Returns: - A tuple (line, linenum, pos) pointer *at* the opening brace, or - (line, 0, -1) if we never find the matching opening brace. Note - we ignore strings and comments when matching; and the line we - return is the 'cleansed' line at linenum. - """ - line = clean_lines.elided[linenum] - if line[pos] not in ')}]>': - return (line, 0, -1) - - # Check last line - (start_pos, stack) = FindStartOfExpressionInLine(line, pos, []) - if start_pos > -1: - return (line, linenum, start_pos) - - # Continue scanning backward - while stack and linenum > 0: - linenum -= 1 - line = clean_lines.elided[linenum] - (start_pos, stack) = FindStartOfExpressionInLine(line, len(line) - 1, stack) - if start_pos > -1: - return (line, linenum, start_pos) - - # Did not find start of expression before beginning of file, give up - return (line, 0, -1) - - -def CheckForCopyright(filename, lines, error): - """Logs an error if no Copyright message appears at the top of the file.""" - - # We'll say it should occur by line 10. Don't forget there's a - # placeholder line at the front. - for line in xrange(1, min(len(lines), 11)): - if re.search(r'Copyright', lines[line], re.I): break - else: # means no copyright line was found - error(filename, 0, 'legal/copyright', 5, - 'No copyright message found. ' - 'You should have a line: "Copyright [year] "') - - -def GetIndentLevel(line): - """Return the number of leading spaces in line. - - Args: - line: A string to check. - - Returns: - An integer count of leading spaces, possibly zero. - """ - indent = Match(r'^( *)\S', line) - if indent: - return len(indent.group(1)) - else: - return 0 - -def PathSplitToList(path): - """Returns the path split into a list by the separator. - - Args: - path: An absolute or relative path (e.g. '/a/b/c/' or '../a') - - Returns: - A list of path components (e.g. ['a', 'b', 'c]). - """ - lst = [] - while True: - (head, tail) = os.path.split(path) - if head == path: # absolute paths end - lst.append(head) - break - if tail == path: # relative paths end - lst.append(tail) - break - - path = head - lst.append(tail) - - lst.reverse() - return lst - -def GetHeaderGuardCPPVariable(filename): - """Returns the CPP variable that should be used as a header guard. - - Args: - filename: The name of a C++ header file. - - Returns: - The CPP variable that should be used as a header guard in the - named file. - - """ - - # Restores original filename in case that cpplint is invoked from Emacs's - # flymake. - filename = re.sub(r'_flymake\.h$', '.h', filename) - filename = re.sub(r'/\.flymake/([^/]*)$', r'/\1', filename) - # Replace 'c++' with 'cpp'. - filename = filename.replace('C++', 'cpp').replace('c++', 'cpp') - - fileinfo = FileInfo(filename) - file_path_from_root = fileinfo.RepositoryName() - - def FixupPathFromRoot(): - if _root_debug: - sys.stderr.write("\n_root fixup, _root = '%s', repository name = '%s'\n" - %(_root, fileinfo.RepositoryName())) - - # Process the file path with the --root flag if it was set. - if not _root: - if _root_debug: - sys.stderr.write("_root unspecified\n") - return file_path_from_root - - def StripListPrefix(lst, prefix): - # f(['x', 'y'], ['w, z']) -> None (not a valid prefix) - if lst[:len(prefix)] != prefix: - return None - # f(['a, 'b', 'c', 'd'], ['a', 'b']) -> ['c', 'd'] - return lst[(len(prefix)):] - - # root behavior: - # --root=subdir , lstrips subdir from the header guard - maybe_path = StripListPrefix(PathSplitToList(file_path_from_root), - PathSplitToList(_root)) - - if _root_debug: - sys.stderr.write(("_root lstrip (maybe_path=%s, file_path_from_root=%s," + - " _root=%s)\n") %(maybe_path, file_path_from_root, _root)) - - if maybe_path: - return os.path.join(*maybe_path) - - # --root=.. , will prepend the outer directory to the header guard - full_path = fileinfo.FullName() - root_abspath = os.path.abspath(_root) - - maybe_path = StripListPrefix(PathSplitToList(full_path), - PathSplitToList(root_abspath)) - - if _root_debug: - sys.stderr.write(("_root prepend (maybe_path=%s, full_path=%s, " + - "root_abspath=%s)\n") %(maybe_path, full_path, root_abspath)) - - if maybe_path: - return os.path.join(*maybe_path) - - if _root_debug: - sys.stderr.write("_root ignore, returning %s\n" %(file_path_from_root)) - - # --root=FAKE_DIR is ignored - return file_path_from_root - - file_path_from_root = FixupPathFromRoot() - return re.sub(r'[^a-zA-Z0-9]', '_', file_path_from_root).upper() + '_' - - -def CheckForHeaderGuard(filename, clean_lines, error): - """Checks that the file contains a header guard. - - Logs an error if no #ifndef header guard is present. For other - headers, checks that the full pathname is used. - - Args: - filename: The name of the C++ header file. - clean_lines: A CleansedLines instance containing the file. - error: The function to call with any errors found. - """ - - # Don't check for header guards if there are error suppression - # comments somewhere in this file. - # - # Because this is silencing a warning for a nonexistent line, we - # only support the very specific NOLINT(build/header_guard) syntax, - # and not the general NOLINT or NOLINT(*) syntax. - raw_lines = clean_lines.lines_without_raw_strings - for i in raw_lines: - if Search(r'//\s*NOLINT\(build/header_guard\)', i): - return - - cppvar = GetHeaderGuardCPPVariable(filename) - - ifndef = '' - ifndef_linenum = 0 - define = '' - endif = '' - endif_linenum = 0 - for linenum, line in enumerate(raw_lines): - linesplit = line.split() - if len(linesplit) >= 2: - # find the first occurrence of #ifndef and #define, save arg - if not ifndef and linesplit[0] == '#ifndef': - # set ifndef to the header guard presented on the #ifndef line. - ifndef = linesplit[1] - ifndef_linenum = linenum - if not define and linesplit[0] == '#define': - define = linesplit[1] - # find the last occurrence of #endif, save entire line - if line.startswith('#endif'): - endif = line - endif_linenum = linenum - - if not ifndef or not define or ifndef != define: - error(filename, 0, 'build/header_guard', 5, - 'No #ifndef header guard found, suggested CPP variable is: %s' % - cppvar) - return - - # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__ - # for backward compatibility. - if ifndef != cppvar: - error_level = 0 - if ifndef != cppvar + '_': - error_level = 5 - - ParseNolintSuppressions(filename, raw_lines[ifndef_linenum], ifndef_linenum, - error) - error(filename, ifndef_linenum, 'build/header_guard', error_level, - '#ifndef header guard has wrong style, please use: %s' % cppvar) - - # Check for "//" comments on endif line. - ParseNolintSuppressions(filename, raw_lines[endif_linenum], endif_linenum, - error) - match = Match(r'#endif\s*//\s*' + cppvar + r'(_)?\b', endif) - if match: - if match.group(1) == '_': - # Issue low severity warning for deprecated double trailing underscore - error(filename, endif_linenum, 'build/header_guard', 0, - '#endif line should be "#endif // %s"' % cppvar) - return - - # Didn't find the corresponding "//" comment. If this file does not - # contain any "//" comments at all, it could be that the compiler - # only wants "/**/" comments, look for those instead. - no_single_line_comments = True - for i in xrange(1, len(raw_lines) - 1): - line = raw_lines[i] - if Match(r'^(?:(?:\'(?:\.|[^\'])*\')|(?:"(?:\.|[^"])*")|[^\'"])*//', line): - no_single_line_comments = False - break - - if no_single_line_comments: - match = Match(r'#endif\s*/\*\s*' + cppvar + r'(_)?\s*\*/', endif) - if match: - if match.group(1) == '_': - # Low severity warning for double trailing underscore - error(filename, endif_linenum, 'build/header_guard', 0, - '#endif line should be "#endif /* %s */"' % cppvar) - return - - # Didn't find anything - error(filename, endif_linenum, 'build/header_guard', 5, - '#endif line should be "#endif // %s"' % cppvar) - - -def CheckHeaderFileIncluded(filename, include_state, error): - """Logs an error if a .cc file does not include its header.""" - - # Do not check test files - fileinfo = FileInfo(filename) - if Search(_TEST_FILE_SUFFIX, fileinfo.BaseName()): - return - - headerfile = filename[0:len(filename) - len(fileinfo.Extension())] + '.h' - if not os.path.exists(headerfile): - return - headername = FileInfo(headerfile).RepositoryName() - first_include = 0 - for section_list in include_state.include_list: - for f in section_list: - if headername in f[0] or f[0] in headername: - return - if not first_include: - first_include = f[1] - - error(filename, first_include, 'build/include', 5, - '%s should include its header file %s' % (fileinfo.RepositoryName(), - headername)) - - -def CheckForBadCharacters(filename, lines, error): - """Logs an error for each line containing bad characters. - - Two kinds of bad characters: - - 1. Unicode replacement characters: These indicate that either the file - contained invalid UTF-8 (likely) or Unicode replacement characters (which - it shouldn't). Note that it's possible for this to throw off line - numbering if the invalid UTF-8 occurred adjacent to a newline. - - 2. NUL bytes. These are problematic for some tools. - - Args: - filename: The name of the current file. - lines: An array of strings, each representing a line of the file. - error: The function to call with any errors found. - """ - for linenum, line in enumerate(lines): - if u'\ufffd' in line: - error(filename, linenum, 'readability/utf8', 5, - 'Line contains invalid UTF-8 (or Unicode replacement character).') - if '\0' in line: - error(filename, linenum, 'readability/nul', 5, 'Line contains NUL byte.') - - -def CheckForNewlineAtEOF(filename, lines, error): - """Logs an error if there is no newline char at the end of the file. - - Args: - filename: The name of the current file. - lines: An array of strings, each representing a line of the file. - error: The function to call with any errors found. - """ - - # The array lines() was created by adding two newlines to the - # original file (go figure), then splitting on \n. - # To verify that the file ends in \n, we just have to make sure the - # last-but-two element of lines() exists and is empty. - if len(lines) < 3 or lines[-2]: - error(filename, len(lines) - 2, 'whitespace/ending_newline', 5, - 'Could not find a newline character at the end of the file.') - - -def CheckForMultilineCommentsAndStrings(filename, clean_lines, linenum, error): - """Logs an error if we see /* ... */ or "..." that extend past one line. - - /* ... */ comments are legit inside macros, for one line. - Otherwise, we prefer // comments, so it's ok to warn about the - other. Likewise, it's ok for strings to extend across multiple - lines, as long as a line continuation character (backslash) - terminates each line. Although not currently prohibited by the C++ - style guide, it's ugly and unnecessary. We don't do well with either - in this lint program, so we warn about both. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - line = clean_lines.elided[linenum] - - # Remove all \\ (escaped backslashes) from the line. They are OK, and the - # second (escaped) slash may trigger later \" detection erroneously. - line = line.replace('\\\\', '') - - if line.count('/*') > line.count('*/'): - error(filename, linenum, 'readability/multiline_comment', 5, - 'Complex multi-line /*...*/-style comment found. ' - 'Lint may give bogus warnings. ' - 'Consider replacing these with //-style comments, ' - 'with #if 0...#endif, ' - 'or with more clearly structured multi-line comments.') - - if (line.count('"') - line.count('\\"')) % 2: - error(filename, linenum, 'readability/multiline_string', 5, - 'Multi-line string ("...") found. This lint script doesn\'t ' - 'do well with such strings, and may give bogus warnings. ' - 'Use C++11 raw strings or concatenation instead.') - - -# (non-threadsafe name, thread-safe alternative, validation pattern) -# -# The validation pattern is used to eliminate false positives such as: -# _rand(); // false positive due to substring match. -# ->rand(); // some member function rand(). -# ACMRandom rand(seed); // some variable named rand. -# ISAACRandom rand(); // another variable named rand. -# -# Basically we require the return value of these functions to be used -# in some expression context on the same line by matching on some -# operator before the function name. This eliminates constructors and -# member function calls. -_UNSAFE_FUNC_PREFIX = r'(?:[-+*/=%^&|(<]\s*|>\s+)' -_THREADING_LIST = ( - ('asctime(', 'asctime_r(', _UNSAFE_FUNC_PREFIX + r'asctime\([^)]+\)'), - ('ctime(', 'ctime_r(', _UNSAFE_FUNC_PREFIX + r'ctime\([^)]+\)'), - ('getgrgid(', 'getgrgid_r(', _UNSAFE_FUNC_PREFIX + r'getgrgid\([^)]+\)'), - ('getgrnam(', 'getgrnam_r(', _UNSAFE_FUNC_PREFIX + r'getgrnam\([^)]+\)'), - ('getlogin(', 'getlogin_r(', _UNSAFE_FUNC_PREFIX + r'getlogin\(\)'), - ('getpwnam(', 'getpwnam_r(', _UNSAFE_FUNC_PREFIX + r'getpwnam\([^)]+\)'), - ('getpwuid(', 'getpwuid_r(', _UNSAFE_FUNC_PREFIX + r'getpwuid\([^)]+\)'), - ('gmtime(', 'gmtime_r(', _UNSAFE_FUNC_PREFIX + r'gmtime\([^)]+\)'), - ('localtime(', 'localtime_r(', _UNSAFE_FUNC_PREFIX + r'localtime\([^)]+\)'), - ('rand(', 'rand_r(', _UNSAFE_FUNC_PREFIX + r'rand\(\)'), - ('strtok(', 'strtok_r(', - _UNSAFE_FUNC_PREFIX + r'strtok\([^)]+\)'), - ('ttyname(', 'ttyname_r(', _UNSAFE_FUNC_PREFIX + r'ttyname\([^)]+\)'), - ) - - -def CheckPosixThreading(filename, clean_lines, linenum, error): - """Checks for calls to thread-unsafe functions. - - Much code has been originally written without consideration of - multi-threading. Also, engineers are relying on their old experience; - they have learned posix before threading extensions were added. These - tests guide the engineers to use thread-safe functions (when using - posix directly). - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - line = clean_lines.elided[linenum] - for single_thread_func, multithread_safe_func, pattern in _THREADING_LIST: - # Additional pattern matching check to confirm that this is the - # function we are looking for - if Search(pattern, line): - error(filename, linenum, 'runtime/threadsafe_fn', 2, - 'Consider using ' + multithread_safe_func + - '...) instead of ' + single_thread_func + - '...) for improved thread safety.') - - -def CheckVlogArguments(filename, clean_lines, linenum, error): - """Checks that VLOG() is only used for defining a logging level. - - For example, VLOG(2) is correct. VLOG(INFO), VLOG(WARNING), VLOG(ERROR), and - VLOG(FATAL) are not. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - line = clean_lines.elided[linenum] - if Search(r'\bVLOG\((INFO|ERROR|WARNING|DFATAL|FATAL)\)', line): - error(filename, linenum, 'runtime/vlog', 5, - 'VLOG() should be used with numeric verbosity level. ' - 'Use LOG() if you want symbolic severity levels.') - -# Matches invalid increment: *count++, which moves pointer instead of -# incrementing a value. -_RE_PATTERN_INVALID_INCREMENT = re.compile( - r'^\s*\*\w+(\+\+|--);') - - -def CheckInvalidIncrement(filename, clean_lines, linenum, error): - """Checks for invalid increment *count++. - - For example following function: - void increment_counter(int* count) { - *count++; - } - is invalid, because it effectively does count++, moving pointer, and should - be replaced with ++*count, (*count)++ or *count += 1. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - line = clean_lines.elided[linenum] - if _RE_PATTERN_INVALID_INCREMENT.match(line): - error(filename, linenum, 'runtime/invalid_increment', 5, - 'Changing pointer instead of value (or unused value of operator*).') - - -def IsMacroDefinition(clean_lines, linenum): - if Search(r'^#define', clean_lines[linenum]): - return True - - if linenum > 0 and Search(r'\\$', clean_lines[linenum - 1]): - return True - - return False - - -def IsForwardClassDeclaration(clean_lines, linenum): - return Match(r'^\s*(\btemplate\b)*.*class\s+\w+;\s*$', clean_lines[linenum]) - - -class _BlockInfo(object): - """Stores information about a generic block of code.""" - - def __init__(self, linenum, seen_open_brace): - self.starting_linenum = linenum - self.seen_open_brace = seen_open_brace - self.open_parentheses = 0 - self.inline_asm = _NO_ASM - self.check_namespace_indentation = False - - def CheckBegin(self, filename, clean_lines, linenum, error): - """Run checks that applies to text up to the opening brace. - - This is mostly for checking the text after the class identifier - and the "{", usually where the base class is specified. For other - blocks, there isn't much to check, so we always pass. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - pass - - def CheckEnd(self, filename, clean_lines, linenum, error): - """Run checks that applies to text after the closing brace. - - This is mostly used for checking end of namespace comments. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - pass - - def IsBlockInfo(self): - """Returns true if this block is a _BlockInfo. - - This is convenient for verifying that an object is an instance of - a _BlockInfo, but not an instance of any of the derived classes. - - Returns: - True for this class, False for derived classes. - """ - return self.__class__ == _BlockInfo - - -class _ExternCInfo(_BlockInfo): - """Stores information about an 'extern "C"' block.""" - - def __init__(self, linenum): - _BlockInfo.__init__(self, linenum, True) - - -class _ClassInfo(_BlockInfo): - """Stores information about a class.""" - - def __init__(self, name, class_or_struct, clean_lines, linenum): - _BlockInfo.__init__(self, linenum, False) - self.name = name - self.is_derived = False - self.check_namespace_indentation = True - if class_or_struct == 'struct': - self.access = 'public' - self.is_struct = True - else: - self.access = 'private' - self.is_struct = False - - # Remember initial indentation level for this class. Using raw_lines here - # instead of elided to account for leading comments. - self.class_indent = GetIndentLevel(clean_lines.raw_lines[linenum]) - - # Try to find the end of the class. This will be confused by things like: - # class A { - # } *x = { ... - # - # But it's still good enough for CheckSectionSpacing. - self.last_line = 0 - depth = 0 - for i in range(linenum, clean_lines.NumLines()): - line = clean_lines.elided[i] - depth += line.count('{') - line.count('}') - if not depth: - self.last_line = i - break - - def CheckBegin(self, filename, clean_lines, linenum, error): - # Look for a bare ':' - if Search('(^|[^:]):($|[^:])', clean_lines.elided[linenum]): - self.is_derived = True - - def CheckEnd(self, filename, clean_lines, linenum, error): - # If there is a DISALLOW macro, it should appear near the end of - # the class. - seen_last_thing_in_class = False - for i in xrange(linenum - 1, self.starting_linenum, -1): - match = Search( - r'\b(DISALLOW_COPY_AND_ASSIGN|DISALLOW_IMPLICIT_CONSTRUCTORS)\(' + - self.name + r'\)', - clean_lines.elided[i]) - if match: - if seen_last_thing_in_class: - error(filename, i, 'readability/constructors', 3, - match.group(1) + ' should be the last thing in the class') - break - - if not Match(r'^\s*$', clean_lines.elided[i]): - seen_last_thing_in_class = True - - # Check that closing brace is aligned with beginning of the class. - # Only do this if the closing brace is indented by only whitespaces. - # This means we will not check single-line class definitions. - indent = Match(r'^( *)\}', clean_lines.elided[linenum]) - if indent and len(indent.group(1)) != self.class_indent: - if self.is_struct: - parent = 'struct ' + self.name - else: - parent = 'class ' + self.name - error(filename, linenum, 'whitespace/indent', 3, - 'Closing brace should be aligned with beginning of %s' % parent) - - -class _NamespaceInfo(_BlockInfo): - """Stores information about a namespace.""" - - def __init__(self, name, linenum): - _BlockInfo.__init__(self, linenum, False) - self.name = name or '' - self.check_namespace_indentation = True - - def CheckEnd(self, filename, clean_lines, linenum, error): - """Check end of namespace comments.""" - line = clean_lines.raw_lines[linenum] - - # Check how many lines is enclosed in this namespace. Don't issue - # warning for missing namespace comments if there aren't enough - # lines. However, do apply checks if there is already an end of - # namespace comment and it's incorrect. - # - # TODO(unknown): We always want to check end of namespace comments - # if a namespace is large, but sometimes we also want to apply the - # check if a short namespace contained nontrivial things (something - # other than forward declarations). There is currently no logic on - # deciding what these nontrivial things are, so this check is - # triggered by namespace size only, which works most of the time. - if (linenum - self.starting_linenum < 10 - and not Match(r'^\s*};*\s*(//|/\*).*\bnamespace\b', line)): - return - - # Look for matching comment at end of namespace. - # - # Note that we accept C style "/* */" comments for terminating - # namespaces, so that code that terminate namespaces inside - # preprocessor macros can be cpplint clean. - # - # We also accept stuff like "// end of namespace ." with the - # period at the end. - # - # Besides these, we don't accept anything else, otherwise we might - # get false negatives when existing comment is a substring of the - # expected namespace. - if self.name: - # Named namespace - if not Match((r'^\s*};*\s*(//|/\*).*\bnamespace\s+' + - re.escape(self.name) + r'[\*/\.\\\s]*$'), - line): - error(filename, linenum, 'readability/namespace', 5, - 'Namespace should be terminated with "// namespace %s"' % - self.name) - else: - # Anonymous namespace - if not Match(r'^\s*};*\s*(//|/\*).*\bnamespace[\*/\.\\\s]*$', line): - # If "// namespace anonymous" or "// anonymous namespace (more text)", - # mention "// anonymous namespace" as an acceptable form - if Match(r'^\s*}.*\b(namespace anonymous|anonymous namespace)\b', line): - error(filename, linenum, 'readability/namespace', 5, - 'Anonymous namespace should be terminated with "// namespace"' - ' or "// anonymous namespace"') - else: - error(filename, linenum, 'readability/namespace', 5, - 'Anonymous namespace should be terminated with "// namespace"') - - -class _PreprocessorInfo(object): - """Stores checkpoints of nesting stacks when #if/#else is seen.""" - - def __init__(self, stack_before_if): - # The entire nesting stack before #if - self.stack_before_if = stack_before_if - - # The entire nesting stack up to #else - self.stack_before_else = [] - - # Whether we have already seen #else or #elif - self.seen_else = False - - -class NestingState(object): - """Holds states related to parsing braces.""" - - def __init__(self): - # Stack for tracking all braces. An object is pushed whenever we - # see a "{", and popped when we see a "}". Only 3 types of - # objects are possible: - # - _ClassInfo: a class or struct. - # - _NamespaceInfo: a namespace. - # - _BlockInfo: some other type of block. - self.stack = [] - - # Top of the previous stack before each Update(). - # - # Because the nesting_stack is updated at the end of each line, we - # had to do some convoluted checks to find out what is the current - # scope at the beginning of the line. This check is simplified by - # saving the previous top of nesting stack. - # - # We could save the full stack, but we only need the top. Copying - # the full nesting stack would slow down cpplint by ~10%. - self.previous_stack_top = [] - - # Stack of _PreprocessorInfo objects. - self.pp_stack = [] - - def SeenOpenBrace(self): - """Check if we have seen the opening brace for the innermost block. - - Returns: - True if we have seen the opening brace, False if the innermost - block is still expecting an opening brace. - """ - return (not self.stack) or self.stack[-1].seen_open_brace - - def InNamespaceBody(self): - """Check if we are currently one level inside a namespace body. - - Returns: - True if top of the stack is a namespace block, False otherwise. - """ - return self.stack and isinstance(self.stack[-1], _NamespaceInfo) - - def InExternC(self): - """Check if we are currently one level inside an 'extern "C"' block. - - Returns: - True if top of the stack is an extern block, False otherwise. - """ - return self.stack and isinstance(self.stack[-1], _ExternCInfo) - - def InClassDeclaration(self): - """Check if we are currently one level inside a class or struct declaration. - - Returns: - True if top of the stack is a class/struct, False otherwise. - """ - return self.stack and isinstance(self.stack[-1], _ClassInfo) - - def InAsmBlock(self): - """Check if we are currently one level inside an inline ASM block. - - Returns: - True if the top of the stack is a block containing inline ASM. - """ - return self.stack and self.stack[-1].inline_asm != _NO_ASM - - def InTemplateArgumentList(self, clean_lines, linenum, pos): - """Check if current position is inside template argument list. - - Args: - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - pos: position just after the suspected template argument. - Returns: - True if (linenum, pos) is inside template arguments. - """ - while linenum < clean_lines.NumLines(): - # Find the earliest character that might indicate a template argument - line = clean_lines.elided[linenum] - match = Match(r'^[^{};=\[\]\.<>]*(.)', line[pos:]) - if not match: - linenum += 1 - pos = 0 - continue - token = match.group(1) - pos += len(match.group(0)) - - # These things do not look like template argument list: - # class Suspect { - # class Suspect x; } - if token in ('{', '}', ';'): return False - - # These things look like template argument list: - # template - # template - # template - # template - if token in ('>', '=', '[', ']', '.'): return True - - # Check if token is an unmatched '<'. - # If not, move on to the next character. - if token != '<': - pos += 1 - if pos >= len(line): - linenum += 1 - pos = 0 - continue - - # We can't be sure if we just find a single '<', and need to - # find the matching '>'. - (_, end_line, end_pos) = CloseExpression(clean_lines, linenum, pos - 1) - if end_pos < 0: - # Not sure if template argument list or syntax error in file - return False - linenum = end_line - pos = end_pos - return False - - def UpdatePreprocessor(self, line): - """Update preprocessor stack. - - We need to handle preprocessors due to classes like this: - #ifdef SWIG - struct ResultDetailsPageElementExtensionPoint { - #else - struct ResultDetailsPageElementExtensionPoint : public Extension { - #endif - - We make the following assumptions (good enough for most files): - - Preprocessor condition evaluates to true from #if up to first - #else/#elif/#endif. - - - Preprocessor condition evaluates to false from #else/#elif up - to #endif. We still perform lint checks on these lines, but - these do not affect nesting stack. - - Args: - line: current line to check. - """ - if Match(r'^\s*#\s*(if|ifdef|ifndef)\b', line): - # Beginning of #if block, save the nesting stack here. The saved - # stack will allow us to restore the parsing state in the #else case. - self.pp_stack.append(_PreprocessorInfo(copy.deepcopy(self.stack))) - elif Match(r'^\s*#\s*(else|elif)\b', line): - # Beginning of #else block - if self.pp_stack: - if not self.pp_stack[-1].seen_else: - # This is the first #else or #elif block. Remember the - # whole nesting stack up to this point. This is what we - # keep after the #endif. - self.pp_stack[-1].seen_else = True - self.pp_stack[-1].stack_before_else = copy.deepcopy(self.stack) - - # Restore the stack to how it was before the #if - self.stack = copy.deepcopy(self.pp_stack[-1].stack_before_if) - else: - # TODO(unknown): unexpected #else, issue warning? - pass - elif Match(r'^\s*#\s*endif\b', line): - # End of #if or #else blocks. - if self.pp_stack: - # If we saw an #else, we will need to restore the nesting - # stack to its former state before the #else, otherwise we - # will just continue from where we left off. - if self.pp_stack[-1].seen_else: - # Here we can just use a shallow copy since we are the last - # reference to it. - self.stack = self.pp_stack[-1].stack_before_else - # Drop the corresponding #if - self.pp_stack.pop() - else: - # TODO(unknown): unexpected #endif, issue warning? - pass - - # TODO(unknown): Update() is too long, but we will refactor later. - def Update(self, filename, clean_lines, linenum, error): - """Update nesting state with current line. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - line = clean_lines.elided[linenum] - - # Remember top of the previous nesting stack. - # - # The stack is always pushed/popped and not modified in place, so - # we can just do a shallow copy instead of copy.deepcopy. Using - # deepcopy would slow down cpplint by ~28%. - if self.stack: - self.previous_stack_top = self.stack[-1] - else: - self.previous_stack_top = None - - # Update pp_stack - self.UpdatePreprocessor(line) - - # Count parentheses. This is to avoid adding struct arguments to - # the nesting stack. - if self.stack: - inner_block = self.stack[-1] - depth_change = line.count('(') - line.count(')') - inner_block.open_parentheses += depth_change - - # Also check if we are starting or ending an inline assembly block. - if inner_block.inline_asm in (_NO_ASM, _END_ASM): - if (depth_change != 0 and - inner_block.open_parentheses == 1 and - _MATCH_ASM.match(line)): - # Enter assembly block - inner_block.inline_asm = _INSIDE_ASM - else: - # Not entering assembly block. If previous line was _END_ASM, - # we will now shift to _NO_ASM state. - inner_block.inline_asm = _NO_ASM - elif (inner_block.inline_asm == _INSIDE_ASM and - inner_block.open_parentheses == 0): - # Exit assembly block - inner_block.inline_asm = _END_ASM - - # Consume namespace declaration at the beginning of the line. Do - # this in a loop so that we catch same line declarations like this: - # namespace proto2 { namespace bridge { class MessageSet; } } - while True: - # Match start of namespace. The "\b\s*" below catches namespace - # declarations even if it weren't followed by a whitespace, this - # is so that we don't confuse our namespace checker. The - # missing spaces will be flagged by CheckSpacing. - namespace_decl_match = Match(r'^\s*namespace\b\s*([:\w]+)?(.*)$', line) - if not namespace_decl_match: - break - - new_namespace = _NamespaceInfo(namespace_decl_match.group(1), linenum) - self.stack.append(new_namespace) - - line = namespace_decl_match.group(2) - if line.find('{') != -1: - new_namespace.seen_open_brace = True - line = line[line.find('{') + 1:] - - # Look for a class declaration in whatever is left of the line - # after parsing namespaces. The regexp accounts for decorated classes - # such as in: - # class LOCKABLE API Object { - # }; - class_decl_match = Match( - r'^(\s*(?:template\s*<[\w\s<>,:]*>\s*)?' - r'(class|struct)\s+(?:[A-Z_]+\s+)*(\w+(?:::\w+)*))' - r'(.*)$', line) - if (class_decl_match and - (not self.stack or self.stack[-1].open_parentheses == 0)): - # We do not want to accept classes that are actually template arguments: - # template , - # template class Ignore3> - # void Function() {}; - # - # To avoid template argument cases, we scan forward and look for - # an unmatched '>'. If we see one, assume we are inside a - # template argument list. - end_declaration = len(class_decl_match.group(1)) - if not self.InTemplateArgumentList(clean_lines, linenum, end_declaration): - self.stack.append(_ClassInfo( - class_decl_match.group(3), class_decl_match.group(2), - clean_lines, linenum)) - line = class_decl_match.group(4) - - # If we have not yet seen the opening brace for the innermost block, - # run checks here. - if not self.SeenOpenBrace(): - self.stack[-1].CheckBegin(filename, clean_lines, linenum, error) - - # Update access control if we are inside a class/struct - if self.stack and isinstance(self.stack[-1], _ClassInfo): - classinfo = self.stack[-1] - access_match = Match( - r'^(.*)\b(public|private|protected|signals)(\s+(?:slots\s*)?)?' - r':(?:[^:]|$)', - line) - if access_match: - classinfo.access = access_match.group(2) - - # Check that access keywords are indented +1 space. Skip this - # check if the keywords are not preceded by whitespaces. - indent = access_match.group(1) - if (len(indent) != classinfo.class_indent + 1 and - Match(r'^\s*$', indent)): - if classinfo.is_struct: - parent = 'struct ' + classinfo.name - else: - parent = 'class ' + classinfo.name - slots = '' - if access_match.group(3): - slots = access_match.group(3) - error(filename, linenum, 'whitespace/indent', 3, - '%s%s: should be indented +1 space inside %s' % ( - access_match.group(2), slots, parent)) - - # Consume braces or semicolons from what's left of the line - while True: - # Match first brace, semicolon, or closed parenthesis. - matched = Match(r'^[^{;)}]*([{;)}])(.*)$', line) - if not matched: - break - - token = matched.group(1) - if token == '{': - # If namespace or class hasn't seen a opening brace yet, mark - # namespace/class head as complete. Push a new block onto the - # stack otherwise. - if not self.SeenOpenBrace(): - self.stack[-1].seen_open_brace = True - elif Match(r'^extern\s*"[^"]*"\s*\{', line): - self.stack.append(_ExternCInfo(linenum)) - else: - self.stack.append(_BlockInfo(linenum, True)) - if _MATCH_ASM.match(line): - self.stack[-1].inline_asm = _BLOCK_ASM - - elif token == ';' or token == ')': - # If we haven't seen an opening brace yet, but we already saw - # a semicolon, this is probably a forward declaration. Pop - # the stack for these. - # - # Similarly, if we haven't seen an opening brace yet, but we - # already saw a closing parenthesis, then these are probably - # function arguments with extra "class" or "struct" keywords. - # Also pop these stack for these. - if not self.SeenOpenBrace(): - self.stack.pop() - else: # token == '}' - # Perform end of block checks and pop the stack. - if self.stack: - self.stack[-1].CheckEnd(filename, clean_lines, linenum, error) - self.stack.pop() - line = matched.group(2) - - def InnermostClass(self): - """Get class info on the top of the stack. - - Returns: - A _ClassInfo object if we are inside a class, or None otherwise. - """ - for i in range(len(self.stack), 0, -1): - classinfo = self.stack[i - 1] - if isinstance(classinfo, _ClassInfo): - return classinfo - return None - - def CheckCompletedBlocks(self, filename, error): - """Checks that all classes and namespaces have been completely parsed. - - Call this when all lines in a file have been processed. - Args: - filename: The name of the current file. - error: The function to call with any errors found. - """ - # Note: This test can result in false positives if #ifdef constructs - # get in the way of brace matching. See the testBuildClass test in - # cpplint_unittest.py for an example of this. - for obj in self.stack: - if isinstance(obj, _ClassInfo): - error(filename, obj.starting_linenum, 'build/class', 5, - 'Failed to find complete declaration of class %s' % - obj.name) - elif isinstance(obj, _NamespaceInfo): - error(filename, obj.starting_linenum, 'build/namespaces', 5, - 'Failed to find complete declaration of namespace %s' % - obj.name) - - -def CheckForNonStandardConstructs(filename, clean_lines, linenum, - nesting_state, error): - r"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2. - - Complain about several constructs which gcc-2 accepts, but which are - not standard C++. Warning about these in lint is one way to ease the - transition to new compilers. - - put storage class first (e.g. "static const" instead of "const static"). - - "%lld" instead of %qd" in printf-type functions. - - "%1$d" is non-standard in printf-type functions. - - "\%" is an undefined character escape sequence. - - text after #endif is not allowed. - - invalid inner-style forward declaration. - - >? and ?= and )\?=?\s*(\w+|[+-]?\d+)(\.\d*)?', - line): - error(filename, linenum, 'build/deprecated', 3, - '>? and ))?' - # r'\s*const\s*' + type_name + '\s*&\s*\w+\s*;' - error(filename, linenum, 'runtime/member_string_references', 2, - 'const string& members are dangerous. It is much better to use ' - 'alternatives, such as pointers or simple constants.') - - # Everything else in this function operates on class declarations. - # Return early if the top of the nesting stack is not a class, or if - # the class head is not completed yet. - classinfo = nesting_state.InnermostClass() - if not classinfo or not classinfo.seen_open_brace: - return - - # The class may have been declared with namespace or classname qualifiers. - # The constructor and destructor will not have those qualifiers. - base_classname = classinfo.name.split('::')[-1] - - # Look for single-argument constructors that aren't marked explicit. - # Technically a valid construct, but against style. - explicit_constructor_match = Match( - r'\s+(?:(?:inline|constexpr)\s+)*(explicit\s+)?' - r'(?:(?:inline|constexpr)\s+)*%s\s*' - r'\(((?:[^()]|\([^()]*\))*)\)' - % re.escape(base_classname), - line) - - if explicit_constructor_match: - is_marked_explicit = explicit_constructor_match.group(1) - - if not explicit_constructor_match.group(2): - constructor_args = [] - else: - constructor_args = explicit_constructor_match.group(2).split(',') - - # collapse arguments so that commas in template parameter lists and function - # argument parameter lists don't split arguments in two - i = 0 - while i < len(constructor_args): - constructor_arg = constructor_args[i] - while (constructor_arg.count('<') > constructor_arg.count('>') or - constructor_arg.count('(') > constructor_arg.count(')')): - constructor_arg += ',' + constructor_args[i + 1] - del constructor_args[i + 1] - constructor_args[i] = constructor_arg - i += 1 - - defaulted_args = [arg for arg in constructor_args if '=' in arg] - noarg_constructor = (not constructor_args or # empty arg list - # 'void' arg specifier - (len(constructor_args) == 1 and - constructor_args[0].strip() == 'void')) - onearg_constructor = ((len(constructor_args) == 1 and # exactly one arg - not noarg_constructor) or - # all but at most one arg defaulted - (len(constructor_args) >= 1 and - not noarg_constructor and - len(defaulted_args) >= len(constructor_args) - 1)) - initializer_list_constructor = bool( - onearg_constructor and - Search(r'\bstd\s*::\s*initializer_list\b', constructor_args[0])) - copy_constructor = bool( - onearg_constructor and - Match(r'(const\s+)?%s(\s*<[^>]*>)?(\s+const)?\s*(?:<\w+>\s*)?&' - % re.escape(base_classname), constructor_args[0].strip())) - - if (not is_marked_explicit and - onearg_constructor and - not initializer_list_constructor and - not copy_constructor): - if defaulted_args: - error(filename, linenum, 'runtime/explicit', 5, - 'Constructors callable with one argument ' - 'should be marked explicit.') - else: - error(filename, linenum, 'runtime/explicit', 5, - 'Single-parameter constructors should be marked explicit.') - elif is_marked_explicit and not onearg_constructor: - if noarg_constructor: - error(filename, linenum, 'runtime/explicit', 5, - 'Zero-parameter constructors should not be marked explicit.') - - -def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error): - """Checks for the correctness of various spacing around function calls. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - line = clean_lines.elided[linenum] - - # Since function calls often occur inside if/for/while/switch - # expressions - which have their own, more liberal conventions - we - # first see if we should be looking inside such an expression for a - # function call, to which we can apply more strict standards. - fncall = line # if there's no control flow construct, look at whole line - for pattern in (r'\bif\s*\((.*)\)\s*{', - r'\bfor\s*\((.*)\)\s*{', - r'\bwhile\s*\((.*)\)\s*[{;]', - r'\bswitch\s*\((.*)\)\s*{'): - match = Search(pattern, line) - if match: - fncall = match.group(1) # look inside the parens for function calls - break - - # Except in if/for/while/switch, there should never be space - # immediately inside parens (eg "f( 3, 4 )"). We make an exception - # for nested parens ( (a+b) + c ). Likewise, there should never be - # a space before a ( when it's a function argument. I assume it's a - # function argument when the char before the whitespace is legal in - # a function name (alnum + _) and we're not starting a macro. Also ignore - # pointers and references to arrays and functions coz they're too tricky: - # we use a very simple way to recognize these: - # " (something)(maybe-something)" or - # " (something)(maybe-something," or - # " (something)[something]" - # Note that we assume the contents of [] to be short enough that - # they'll never need to wrap. - if ( # Ignore control structures. - not Search(r'\b(if|for|while|switch|return|new|delete|catch|sizeof)\b', - fncall) and - # Ignore pointers/references to functions. - not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and - # Ignore pointers/references to arrays. - not Search(r' \([^)]+\)\[[^\]]+\]', fncall)): - if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call - error(filename, linenum, 'whitespace/parens', 4, - 'Extra space after ( in function call') - elif Search(r'\(\s+(?!(\s*\\)|\()', fncall): - error(filename, linenum, 'whitespace/parens', 2, - 'Extra space after (') - if (Search(r'\w\s+\(', fncall) and - not Search(r'_{0,2}asm_{0,2}\s+_{0,2}volatile_{0,2}\s+\(', fncall) and - not Search(r'#\s*define|typedef|using\s+\w+\s*=', fncall) and - not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall) and - not Search(r'\bcase\s+\(', fncall)): - # TODO(unknown): Space after an operator function seem to be a common - # error, silence those for now by restricting them to highest verbosity. - if Search(r'\boperator_*\b', line): - error(filename, linenum, 'whitespace/parens', 0, - 'Extra space before ( in function call') - else: - error(filename, linenum, 'whitespace/parens', 4, - 'Extra space before ( in function call') - # If the ) is followed only by a newline or a { + newline, assume it's - # part of a control statement (if/while/etc), and don't complain - if Search(r'[^)]\s+\)\s*[^{\s]', fncall): - # If the closing parenthesis is preceded by only whitespaces, - # try to give a more descriptive error message. - if Search(r'^\s+\)', fncall): - error(filename, linenum, 'whitespace/parens', 2, - 'Closing ) should be moved to the previous line') - else: - error(filename, linenum, 'whitespace/parens', 2, - 'Extra space before )') - - -def IsBlankLine(line): - """Returns true if the given line is blank. - - We consider a line to be blank if the line is empty or consists of - only white spaces. - - Args: - line: A line of a string. - - Returns: - True, if the given line is blank. - """ - return not line or line.isspace() - - -def CheckForNamespaceIndentation(filename, nesting_state, clean_lines, line, - error): - is_namespace_indent_item = ( - len(nesting_state.stack) > 1 and - nesting_state.stack[-1].check_namespace_indentation and - isinstance(nesting_state.previous_stack_top, _NamespaceInfo) and - nesting_state.previous_stack_top == nesting_state.stack[-2]) - - if ShouldCheckNamespaceIndentation(nesting_state, is_namespace_indent_item, - clean_lines.elided, line): - CheckItemIndentationInNamespace(filename, clean_lines.elided, - line, error) - - -def CheckForFunctionLengths(filename, clean_lines, linenum, - function_state, error): - """Reports for long function bodies. - - For an overview why this is done, see: - https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Functions - - Uses a simplistic algorithm assuming other style guidelines - (especially spacing) are followed. - Only checks unindented functions, so class members are unchecked. - Trivial bodies are unchecked, so constructors with huge initializer lists - may be missed. - Blank/comment lines are not counted so as to avoid encouraging the removal - of vertical space and comments just to get through a lint check. - NOLINT *on the last line of a function* disables this check. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - function_state: Current function name and lines in body so far. - error: The function to call with any errors found. - """ - lines = clean_lines.lines - line = lines[linenum] - joined_line = '' - - starting_func = False - regexp = r'(\w(\w|::|\*|\&|\s)*)\(' # decls * & space::name( ... - match_result = Match(regexp, line) - if match_result: - # If the name is all caps and underscores, figure it's a macro and - # ignore it, unless it's TEST or TEST_F. - function_name = match_result.group(1).split()[-1] - if function_name == 'TEST' or function_name == 'TEST_F' or ( - not Match(r'[A-Z_]+$', function_name)): - starting_func = True - - if starting_func: - body_found = False - for start_linenum in xrange(linenum, clean_lines.NumLines()): - start_line = lines[start_linenum] - joined_line += ' ' + start_line.lstrip() - if Search(r'(;|})', start_line): # Declarations and trivial functions - body_found = True - break # ... ignore - elif Search(r'{', start_line): - body_found = True - function = Search(r'((\w|:)*)\(', line).group(1) - if Match(r'TEST', function): # Handle TEST... macros - parameter_regexp = Search(r'(\(.*\))', joined_line) - if parameter_regexp: # Ignore bad syntax - function += parameter_regexp.group(1) - else: - function += '()' - function_state.Begin(function) - break - if not body_found: - # No body for the function (or evidence of a non-function) was found. - error(filename, linenum, 'readability/fn_size', 5, - 'Lint failed to find start of function body.') - elif Match(r'^\}\s*$', line): # function end - function_state.Check(error, filename, linenum) - function_state.End() - elif not Match(r'^\s*$', line): - function_state.Count() # Count non-blank/non-comment lines. - - -_RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?') - - -def CheckComment(line, filename, linenum, next_line_start, error): - """Checks for common mistakes in comments. - - Args: - line: The line in question. - filename: The name of the current file. - linenum: The number of the line to check. - next_line_start: The first non-whitespace column of the next line. - error: The function to call with any errors found. - """ - commentpos = line.find('//') - if commentpos != -1: - # Check if the // may be in quotes. If so, ignore it - if re.sub(r'\\.', '', line[0:commentpos]).count('"') % 2 == 0: - # Allow one space for new scopes, two spaces otherwise: - if (not (Match(r'^.*{ *//', line) and next_line_start == commentpos) and - ((commentpos >= 1 and - line[commentpos-1] not in string.whitespace) or - (commentpos >= 2 and - line[commentpos-2] not in string.whitespace))): - error(filename, linenum, 'whitespace/comments', 2, - 'At least two spaces is best between code and comments') - - # Checks for common mistakes in TODO comments. - comment = line[commentpos:] - match = _RE_PATTERN_TODO.match(comment) - if match: - # One whitespace is correct; zero whitespace is handled elsewhere. - leading_whitespace = match.group(1) - if len(leading_whitespace) > 1: - error(filename, linenum, 'whitespace/todo', 2, - 'Too many spaces before TODO') - - username = match.group(2) - if not username: - error(filename, linenum, 'readability/todo', 2, - 'Missing username in TODO; it should look like ' - '"// TODO(my_username): Stuff."') - - middle_whitespace = match.group(3) - # Comparisons made explicit for correctness -- pylint: disable=g-explicit-bool-comparison - if middle_whitespace != ' ' and middle_whitespace != '': - error(filename, linenum, 'whitespace/todo', 2, - 'TODO(my_username) should be followed by a space') - - # If the comment contains an alphanumeric character, there - # should be a space somewhere between it and the // unless - # it's a /// or //! Doxygen comment. - if (Match(r'//[^ ]*\w', comment) and - not Match(r'(///|//\!)(\s+|$)', comment)): - error(filename, linenum, 'whitespace/comments', 4, - 'Should have a space between // and comment') - - -def CheckSpacing(filename, clean_lines, linenum, nesting_state, error): - """Checks for the correctness of various spacing issues in the code. - - Things we check for: spaces around operators, spaces after - if/for/while/switch, no spaces around parens in function calls, two - spaces between code and comment, don't start a block with a blank - line, don't end a function with a blank line, don't add a blank line - after public/protected/private, don't have too many blank lines in a row. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - nesting_state: A NestingState instance which maintains information about - the current stack of nested blocks being parsed. - error: The function to call with any errors found. - """ - - # Don't use "elided" lines here, otherwise we can't check commented lines. - # Don't want to use "raw" either, because we don't want to check inside C++11 - # raw strings, - raw = clean_lines.lines_without_raw_strings - line = raw[linenum] - - # Before nixing comments, check if the line is blank for no good - # reason. This includes the first line after a block is opened, and - # blank lines at the end of a function (ie, right before a line like '}' - # - # Skip all the blank line checks if we are immediately inside a - # namespace body. In other words, don't issue blank line warnings - # for this block: - # namespace { - # - # } - # - # A warning about missing end of namespace comments will be issued instead. - # - # Also skip blank line checks for 'extern "C"' blocks, which are formatted - # like namespaces. - if (IsBlankLine(line) and - not nesting_state.InNamespaceBody() and - not nesting_state.InExternC()): - elided = clean_lines.elided - prev_line = elided[linenum - 1] - prevbrace = prev_line.rfind('{') - # TODO(unknown): Don't complain if line before blank line, and line after, - # both start with alnums and are indented the same amount. - # This ignores whitespace at the start of a namespace block - # because those are not usually indented. - if prevbrace != -1 and prev_line[prevbrace:].find('}') == -1: - # OK, we have a blank line at the start of a code block. Before we - # complain, we check if it is an exception to the rule: The previous - # non-empty line has the parameters of a function header that are indented - # 4 spaces (because they did not fit in a 80 column line when placed on - # the same line as the function name). We also check for the case where - # the previous line is indented 6 spaces, which may happen when the - # initializers of a constructor do not fit into a 80 column line. - exception = False - if Match(r' {6}\w', prev_line): # Initializer list? - # We are looking for the opening column of initializer list, which - # should be indented 4 spaces to cause 6 space indentation afterwards. - search_position = linenum-2 - while (search_position >= 0 - and Match(r' {6}\w', elided[search_position])): - search_position -= 1 - exception = (search_position >= 0 - and elided[search_position][:5] == ' :') - else: - # Search for the function arguments or an initializer list. We use a - # simple heuristic here: If the line is indented 4 spaces; and we have a - # closing paren, without the opening paren, followed by an opening brace - # or colon (for initializer lists) we assume that it is the last line of - # a function header. If we have a colon indented 4 spaces, it is an - # initializer list. - exception = (Match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)', - prev_line) - or Match(r' {4}:', prev_line)) - - if not exception: - error(filename, linenum, 'whitespace/blank_line', 2, - 'Redundant blank line at the start of a code block ' - 'should be deleted.') - # Ignore blank lines at the end of a block in a long if-else - # chain, like this: - # if (condition1) { - # // Something followed by a blank line - # - # } else if (condition2) { - # // Something else - # } - if linenum + 1 < clean_lines.NumLines(): - next_line = raw[linenum + 1] - if (next_line - and Match(r'\s*}', next_line) - and next_line.find('} else ') == -1): - error(filename, linenum, 'whitespace/blank_line', 3, - 'Redundant blank line at the end of a code block ' - 'should be deleted.') - - matched = Match(r'\s*(public|protected|private):', prev_line) - if matched: - error(filename, linenum, 'whitespace/blank_line', 3, - 'Do not leave a blank line after "%s:"' % matched.group(1)) - - # Next, check comments - next_line_start = 0 - if linenum + 1 < clean_lines.NumLines(): - next_line = raw[linenum + 1] - next_line_start = len(next_line) - len(next_line.lstrip()) - CheckComment(line, filename, linenum, next_line_start, error) - - # get rid of comments and strings - line = clean_lines.elided[linenum] - - # You shouldn't have spaces before your brackets, except maybe after - # 'delete []', 'return []() {};', or 'auto [abc, ...] = ...;'. - if Search(r'\w\s+\[', line) and not Search(r'(?:auto&?|delete|return)\s+\[', line): - error(filename, linenum, 'whitespace/braces', 5, - 'Extra space before [') - - # In range-based for, we wanted spaces before and after the colon, but - # not around "::" tokens that might appear. - if (Search(r'for *\(.*[^:]:[^: ]', line) or - Search(r'for *\(.*[^: ]:[^:]', line)): - error(filename, linenum, 'whitespace/forcolon', 2, - 'Missing space around colon in range-based for loop') - - -def CheckOperatorSpacing(filename, clean_lines, linenum, error): - """Checks for horizontal spacing around operators. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - line = clean_lines.elided[linenum] - - # Don't try to do spacing checks for operator methods. Do this by - # replacing the troublesome characters with something else, - # preserving column position for all other characters. - # - # The replacement is done repeatedly to avoid false positives from - # operators that call operators. - while True: - match = Match(r'^(.*\boperator\b)(\S+)(\s*\(.*)$', line) - if match: - line = match.group(1) + ('_' * len(match.group(2))) + match.group(3) - else: - break - - # We allow no-spaces around = within an if: "if ( (a=Foo()) == 0 )". - # Otherwise not. Note we only check for non-spaces on *both* sides; - # sometimes people put non-spaces on one side when aligning ='s among - # many lines (not that this is behavior that I approve of...) - if ((Search(r'[\w.]=', line) or - Search(r'=[\w.]', line)) - and not Search(r'\b(if|while|for) ', line) - # Operators taken from [lex.operators] in C++11 standard. - and not Search(r'(>=|<=|==|!=|&=|\^=|\|=|\+=|\*=|\/=|\%=)', line) - and not Search(r'operator=', line)): - error(filename, linenum, 'whitespace/operators', 4, - 'Missing spaces around =') - - # It's ok not to have spaces around binary operators like + - * /, but if - # there's too little whitespace, we get concerned. It's hard to tell, - # though, so we punt on this one for now. TODO. - - # You should always have whitespace around binary operators. - # - # Check <= and >= first to avoid false positives with < and >, then - # check non-include lines for spacing around < and >. - # - # If the operator is followed by a comma, assume it's be used in a - # macro context and don't do any checks. This avoids false - # positives. - # - # Note that && is not included here. This is because there are too - # many false positives due to RValue references. - match = Search(r'[^<>=!\s](==|!=|<=|>=|\|\|)[^<>=!\s,;\)]', line) - if match: - error(filename, linenum, 'whitespace/operators', 3, - 'Missing spaces around %s' % match.group(1)) - elif not Match(r'#.*include', line): - # Look for < that is not surrounded by spaces. This is only - # triggered if both sides are missing spaces, even though - # technically should should flag if at least one side is missing a - # space. This is done to avoid some false positives with shifts. - match = Match(r'^(.*[^\s<])<[^\s=<,]', line) - if match: - (_, _, end_pos) = CloseExpression( - clean_lines, linenum, len(match.group(1))) - if end_pos <= -1: - error(filename, linenum, 'whitespace/operators', 3, - 'Missing spaces around <') - - # Look for > that is not surrounded by spaces. Similar to the - # above, we only trigger if both sides are missing spaces to avoid - # false positives with shifts. - match = Match(r'^(.*[^-\s>])>[^\s=>,]', line) - if match: - (_, _, start_pos) = ReverseCloseExpression( - clean_lines, linenum, len(match.group(1))) - if start_pos <= -1: - error(filename, linenum, 'whitespace/operators', 3, - 'Missing spaces around >') - - # We allow no-spaces around << when used like this: 10<<20, but - # not otherwise (particularly, not when used as streams) - # - # We also allow operators following an opening parenthesis, since - # those tend to be macros that deal with operators. - match = Search(r'(operator|[^\s(<])(?:L|UL|LL|ULL|l|ul|ll|ull)?<<([^\s,=<])', line) - if (match and not (match.group(1).isdigit() and match.group(2).isdigit()) and - not (match.group(1) == 'operator' and match.group(2) == ';')): - error(filename, linenum, 'whitespace/operators', 3, - 'Missing spaces around <<') - - # We allow no-spaces around >> for almost anything. This is because - # C++11 allows ">>" to close nested templates, which accounts for - # most cases when ">>" is not followed by a space. - # - # We still warn on ">>" followed by alpha character, because that is - # likely due to ">>" being used for right shifts, e.g.: - # value >> alpha - # - # When ">>" is used to close templates, the alphanumeric letter that - # follows would be part of an identifier, and there should still be - # a space separating the template type and the identifier. - # type> alpha - match = Search(r'>>[a-zA-Z_]', line) - if match: - error(filename, linenum, 'whitespace/operators', 3, - 'Missing spaces around >>') - - # There shouldn't be space around unary operators - match = Search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line) - if match: - error(filename, linenum, 'whitespace/operators', 4, - 'Extra space for operator %s' % match.group(1)) - - -def CheckParenthesisSpacing(filename, clean_lines, linenum, error): - """Checks for horizontal spacing around parentheses. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - line = clean_lines.elided[linenum] - - # No spaces after an if, while, switch, or for - match = Search(r' (if\(|for\(|while\(|switch\()', line) - if match: - error(filename, linenum, 'whitespace/parens', 5, - 'Missing space before ( in %s' % match.group(1)) - - # For if/for/while/switch, the left and right parens should be - # consistent about how many spaces are inside the parens, and - # there should either be zero or one spaces inside the parens. - # We don't want: "if ( foo)" or "if ( foo )". - # Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed. - match = Search(r'\b(if|for|while|switch)\s*' - r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$', - line) - if match: - if len(match.group(2)) != len(match.group(4)): - if not (match.group(3) == ';' and - len(match.group(2)) == 1 + len(match.group(4)) or - not match.group(2) and Search(r'\bfor\s*\(.*; \)', line)): - error(filename, linenum, 'whitespace/parens', 5, - 'Mismatching spaces inside () in %s' % match.group(1)) - if len(match.group(2)) not in [0, 1]: - error(filename, linenum, 'whitespace/parens', 5, - 'Should have zero or one spaces inside ( and ) in %s' % - match.group(1)) - - -def CheckCommaSpacing(filename, clean_lines, linenum, error): - """Checks for horizontal spacing near commas and semicolons. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - raw = clean_lines.lines_without_raw_strings - line = clean_lines.elided[linenum] - - # You should always have a space after a comma (either as fn arg or operator) - # - # This does not apply when the non-space character following the - # comma is another comma, since the only time when that happens is - # for empty macro arguments. - # - # We run this check in two passes: first pass on elided lines to - # verify that lines contain missing whitespaces, second pass on raw - # lines to confirm that those missing whitespaces are not due to - # elided comments. - if (Search(r',[^,\s]', ReplaceAll(r'\boperator\s*,\s*\(', 'F(', line)) and - Search(r',[^,\s]', raw[linenum])): - error(filename, linenum, 'whitespace/comma', 3, - 'Missing space after ,') - - # You should always have a space after a semicolon - # except for few corner cases - # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more - # space after ; - if Search(r';[^\s};\\)/]', line): - error(filename, linenum, 'whitespace/semicolon', 3, - 'Missing space after ;') - - -def _IsType(clean_lines, nesting_state, expr): - """Check if expression looks like a type name, returns true if so. - - Args: - clean_lines: A CleansedLines instance containing the file. - nesting_state: A NestingState instance which maintains information about - the current stack of nested blocks being parsed. - expr: The expression to check. - Returns: - True, if token looks like a type. - """ - # Keep only the last token in the expression - last_word = Match(r'^.*(\b\S+)$', expr) - if last_word: - token = last_word.group(1) - else: - token = expr - - # Match native types and stdint types - if _TYPES.match(token): - return True - - # Try a bit harder to match templated types. Walk up the nesting - # stack until we find something that resembles a typename - # declaration for what we are looking for. - typename_pattern = (r'\b(?:typename|class|struct)\s+' + re.escape(token) + - r'\b') - block_index = len(nesting_state.stack) - 1 - while block_index >= 0: - if isinstance(nesting_state.stack[block_index], _NamespaceInfo): - return False - - # Found where the opening brace is. We want to scan from this - # line up to the beginning of the function, minus a few lines. - # template - # class C - # : public ... { // start scanning here - last_line = nesting_state.stack[block_index].starting_linenum - - next_block_start = 0 - if block_index > 0: - next_block_start = nesting_state.stack[block_index - 1].starting_linenum - first_line = last_line - while first_line >= next_block_start: - if clean_lines.elided[first_line].find('template') >= 0: - break - first_line -= 1 - if first_line < next_block_start: - # Didn't find any "template" keyword before reaching the next block, - # there are probably no template things to check for this block - block_index -= 1 - continue - - # Look for typename in the specified range - for i in xrange(first_line, last_line + 1, 1): - if Search(typename_pattern, clean_lines.elided[i]): - return True - block_index -= 1 - - return False - - -def CheckBracesSpacing(filename, clean_lines, linenum, nesting_state, error): - """Checks for horizontal spacing near commas. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - nesting_state: A NestingState instance which maintains information about - the current stack of nested blocks being parsed. - error: The function to call with any errors found. - """ - line = clean_lines.elided[linenum] - - # Except after an opening paren, or after another opening brace (in case of - # an initializer list, for instance), you should have spaces before your - # braces when they are delimiting blocks, classes, namespaces etc. - # And since you should never have braces at the beginning of a line, - # this is an easy test. Except that braces used for initialization don't - # follow the same rule; we often don't want spaces before those. - match = Match(r'^(.*[^ ({>]){', line) - - if match: - # Try a bit harder to check for brace initialization. This - # happens in one of the following forms: - # Constructor() : initializer_list_{} { ... } - # Constructor{}.MemberFunction() - # Type variable{}; - # FunctionCall(type{}, ...); - # LastArgument(..., type{}); - # LOG(INFO) << type{} << " ..."; - # map_of_type[{...}] = ...; - # ternary = expr ? new type{} : nullptr; - # OuterTemplate{}> - # - # We check for the character following the closing brace, and - # silence the warning if it's one of those listed above, i.e. - # "{.;,)<>]:". - # - # To account for nested initializer list, we allow any number of - # closing braces up to "{;,)<". We can't simply silence the - # warning on first sight of closing brace, because that would - # cause false negatives for things that are not initializer lists. - # Silence this: But not this: - # Outer{ if (...) { - # Inner{...} if (...){ // Missing space before { - # }; } - # - # There is a false negative with this approach if people inserted - # spurious semicolons, e.g. "if (cond){};", but we will catch the - # spurious semicolon with a separate check. - leading_text = match.group(1) - (endline, endlinenum, endpos) = CloseExpression( - clean_lines, linenum, len(match.group(1))) - trailing_text = '' - if endpos > -1: - trailing_text = endline[endpos:] - for offset in xrange(endlinenum + 1, - min(endlinenum + 3, clean_lines.NumLines() - 1)): - trailing_text += clean_lines.elided[offset] - # We also suppress warnings for `uint64_t{expression}` etc., as the style - # guide recommends brace initialization for integral types to avoid - # overflow/truncation. - if (not Match(r'^[\s}]*[{.;,)<>\]:]', trailing_text) - and not _IsType(clean_lines, nesting_state, leading_text)): - error(filename, linenum, 'whitespace/braces', 5, - 'Missing space before {') - - # Make sure '} else {' has spaces. - if Search(r'}else', line): - error(filename, linenum, 'whitespace/braces', 5, - 'Missing space before else') - - # You shouldn't have a space before a semicolon at the end of the line. - # There's a special case for "for" since the style guide allows space before - # the semicolon there. - if Search(r':\s*;\s*$', line): - error(filename, linenum, 'whitespace/semicolon', 5, - 'Semicolon defining empty statement. Use {} instead.') - elif Search(r'^\s*;\s*$', line): - error(filename, linenum, 'whitespace/semicolon', 5, - 'Line contains only semicolon. If this should be an empty statement, ' - 'use {} instead.') - elif (Search(r'\s+;\s*$', line) and - not Search(r'\bfor\b', line)): - error(filename, linenum, 'whitespace/semicolon', 5, - 'Extra space before last semicolon. If this should be an empty ' - 'statement, use {} instead.') - - -def IsDecltype(clean_lines, linenum, column): - """Check if the token ending on (linenum, column) is decltype(). - - Args: - clean_lines: A CleansedLines instance containing the file. - linenum: the number of the line to check. - column: end column of the token to check. - Returns: - True if this token is decltype() expression, False otherwise. - """ - (text, _, start_col) = ReverseCloseExpression(clean_lines, linenum, column) - if start_col < 0: - return False - if Search(r'\bdecltype\s*$', text[0:start_col]): - return True - return False - - -def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error): - """Checks for additional blank line issues related to sections. - - Currently the only thing checked here is blank line before protected/private. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - class_info: A _ClassInfo objects. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - # Skip checks if the class is small, where small means 25 lines or less. - # 25 lines seems like a good cutoff since that's the usual height of - # terminals, and any class that can't fit in one screen can't really - # be considered "small". - # - # Also skip checks if we are on the first line. This accounts for - # classes that look like - # class Foo { public: ... }; - # - # If we didn't find the end of the class, last_line would be zero, - # and the check will be skipped by the first condition. - if (class_info.last_line - class_info.starting_linenum <= 24 or - linenum <= class_info.starting_linenum): - return - - matched = Match(r'\s*(public|protected|private):', clean_lines.lines[linenum]) - if matched: - # Issue warning if the line before public/protected/private was - # not a blank line, but don't do this if the previous line contains - # "class" or "struct". This can happen two ways: - # - We are at the beginning of the class. - # - We are forward-declaring an inner class that is semantically - # private, but needed to be public for implementation reasons. - # Also ignores cases where the previous line ends with a backslash as can be - # common when defining classes in C macros. - prev_line = clean_lines.lines[linenum - 1] - if (not IsBlankLine(prev_line) and - not Search(r'\b(class|struct)\b', prev_line) and - not Search(r'\\$', prev_line)): - # Try a bit harder to find the beginning of the class. This is to - # account for multi-line base-specifier lists, e.g.: - # class Derived - # : public Base { - end_class_head = class_info.starting_linenum - for i in range(class_info.starting_linenum, linenum): - if Search(r'\{\s*$', clean_lines.lines[i]): - end_class_head = i - break - if end_class_head < linenum - 1: - error(filename, linenum, 'whitespace/blank_line', 3, - '"%s:" should be preceded by a blank line' % matched.group(1)) - - -def GetPreviousNonBlankLine(clean_lines, linenum): - """Return the most recent non-blank line and its line number. - - Args: - clean_lines: A CleansedLines instance containing the file contents. - linenum: The number of the line to check. - - Returns: - A tuple with two elements. The first element is the contents of the last - non-blank line before the current line, or the empty string if this is the - first non-blank line. The second is the line number of that line, or -1 - if this is the first non-blank line. - """ - - prevlinenum = linenum - 1 - while prevlinenum >= 0: - prevline = clean_lines.elided[prevlinenum] - if not IsBlankLine(prevline): # if not a blank line... - return (prevline, prevlinenum) - prevlinenum -= 1 - return ('', -1) - - -def CheckBraces(filename, clean_lines, linenum, error): - """Looks for misplaced braces (e.g. at the end of line). - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - - line = clean_lines.elided[linenum] # get rid of comments and strings - - if Match(r'\s*{\s*$', line): - # We allow an open brace to start a line in the case where someone is using - # braces in a block to explicitly create a new scope, which is commonly used - # to control the lifetime of stack-allocated variables. Braces are also - # used for brace initializers inside function calls. We don't detect this - # perfectly: we just don't complain if the last non-whitespace character on - # the previous non-blank line is ',', ';', ':', '(', '{', or '}', or if the - # previous line starts a preprocessor block. We also allow a brace on the - # following line if it is part of an array initialization and would not fit - # within the 80 character limit of the preceding line. - prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] - if (not Search(r'[,;:}{(]\s*$', prevline) and - not Match(r'\s*#', prevline) and - not (GetLineWidth(prevline) > _line_length - 2 and '[]' in prevline)): - error(filename, linenum, 'whitespace/braces', 4, - '{ should almost always be at the end of the previous line') - - # An else clause should be on the same line as the preceding closing brace. - if Match(r'\s*else\b\s*(?:if\b|\{|$)', line): - prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] - if Match(r'\s*}\s*$', prevline): - error(filename, linenum, 'whitespace/newline', 4, - 'An else should appear on the same line as the preceding }') - - # If braces come on one side of an else, they should be on both. - # However, we have to worry about "else if" that spans multiple lines! - if Search(r'else if\s*\(', line): # could be multi-line if - brace_on_left = bool(Search(r'}\s*else if\s*\(', line)) - # find the ( after the if - pos = line.find('else if') - pos = line.find('(', pos) - if pos > 0: - (endline, _, endpos) = CloseExpression(clean_lines, linenum, pos) - brace_on_right = endline[endpos:].find('{') != -1 - if brace_on_left != brace_on_right: # must be brace after if - error(filename, linenum, 'readability/braces', 5, - 'If an else has a brace on one side, it should have it on both') - elif Search(r'}\s*else[^{]*$', line) or Match(r'[^}]*else\s*{', line): - error(filename, linenum, 'readability/braces', 5, - 'If an else has a brace on one side, it should have it on both') - - # Likewise, an else should never have the else clause on the same line - if Search(r'\belse [^\s{]', line) and not Search(r'\belse if\b', line): - error(filename, linenum, 'whitespace/newline', 4, - 'Else clause should never be on same line as else (use 2 lines)') - - # In the same way, a do/while should never be on one line - if Match(r'\s*do [^\s{]', line): - error(filename, linenum, 'whitespace/newline', 4, - 'do/while clauses should not be on a single line') - - # Check single-line if/else bodies. The style guide says 'curly braces are not - # required for single-line statements'. We additionally allow multi-line, - # single statements, but we reject anything with more than one semicolon in - # it. This means that the first semicolon after the if should be at the end of - # its line, and the line after that should have an indent level equal to or - # lower than the if. We also check for ambiguous if/else nesting without - # braces. - if_else_match = Search(r'\b(if\s*\(|else\b)', line) - if if_else_match and not Match(r'\s*#', line): - if_indent = GetIndentLevel(line) - endline, endlinenum, endpos = line, linenum, if_else_match.end() - if_match = Search(r'\bif\s*\(', line) - if if_match: - # This could be a multiline if condition, so find the end first. - pos = if_match.end() - 1 - (endline, endlinenum, endpos) = CloseExpression(clean_lines, linenum, pos) - # Check for an opening brace, either directly after the if or on the next - # line. If found, this isn't a single-statement conditional. - if (not Match(r'\s*{', endline[endpos:]) - and not (Match(r'\s*$', endline[endpos:]) - and endlinenum < (len(clean_lines.elided) - 1) - and Match(r'\s*{', clean_lines.elided[endlinenum + 1]))): - while (endlinenum < len(clean_lines.elided) - and ';' not in clean_lines.elided[endlinenum][endpos:]): - endlinenum += 1 - endpos = 0 - if endlinenum < len(clean_lines.elided): - endline = clean_lines.elided[endlinenum] - # We allow a mix of whitespace and closing braces (e.g. for one-liner - # methods) and a single \ after the semicolon (for macros) - endpos = endline.find(';') - if not Match(r';[\s}]*(\\?)$', endline[endpos:]): - # Semicolon isn't the last character, there's something trailing. - # Output a warning if the semicolon is not contained inside - # a lambda expression. - if not Match(r'^[^{};]*\[[^\[\]]*\][^{}]*\{[^{}]*\}\s*\)*[;,]\s*$', - endline): - error(filename, linenum, 'readability/braces', 4, - 'If/else bodies with multiple statements require braces') - elif endlinenum < len(clean_lines.elided) - 1: - # Make sure the next line is dedented - next_line = clean_lines.elided[endlinenum + 1] - next_indent = GetIndentLevel(next_line) - # With ambiguous nested if statements, this will error out on the - # if that *doesn't* match the else, regardless of whether it's the - # inner one or outer one. - if (if_match and Match(r'\s*else\b', next_line) - and next_indent != if_indent): - error(filename, linenum, 'readability/braces', 4, - 'Else clause should be indented at the same level as if. ' - 'Ambiguous nested if/else chains require braces.') - elif next_indent > if_indent: - error(filename, linenum, 'readability/braces', 4, - 'If/else bodies with multiple statements require braces') - - -def CheckTrailingSemicolon(filename, clean_lines, linenum, error): - """Looks for redundant trailing semicolon. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - - line = clean_lines.elided[linenum] - - # Block bodies should not be followed by a semicolon. Due to C++11 - # brace initialization, there are more places where semicolons are - # required than not, so we explicitly list the allowed rules rather - # than listing the disallowed ones. These are the places where "};" - # should be replaced by just "}": - # 1. Some flavor of block following closing parenthesis: - # for (;;) {}; - # while (...) {}; - # switch (...) {}; - # Function(...) {}; - # if (...) {}; - # if (...) else if (...) {}; - # - # 2. else block: - # if (...) else {}; - # - # 3. const member function: - # Function(...) const {}; - # - # 4. Block following some statement: - # x = 42; - # {}; - # - # 5. Block at the beginning of a function: - # Function(...) { - # {}; - # } - # - # Note that naively checking for the preceding "{" will also match - # braces inside multi-dimensional arrays, but this is fine since - # that expression will not contain semicolons. - # - # 6. Block following another block: - # while (true) {} - # {}; - # - # 7. End of namespaces: - # namespace {}; - # - # These semicolons seems far more common than other kinds of - # redundant semicolons, possibly due to people converting classes - # to namespaces. For now we do not warn for this case. - # - # Try matching case 1 first. - match = Match(r'^(.*\)\s*)\{', line) - if match: - # Matched closing parenthesis (case 1). Check the token before the - # matching opening parenthesis, and don't warn if it looks like a - # macro. This avoids these false positives: - # - macro that defines a base class - # - multi-line macro that defines a base class - # - macro that defines the whole class-head - # - # But we still issue warnings for macros that we know are safe to - # warn, specifically: - # - TEST, TEST_F, TEST_P, MATCHER, MATCHER_P - # - TYPED_TEST - # - INTERFACE_DEF - # - EXCLUSIVE_LOCKS_REQUIRED, SHARED_LOCKS_REQUIRED, LOCKS_EXCLUDED: - # - # We implement a list of safe macros instead of a list of - # unsafe macros, even though the latter appears less frequently in - # google code and would have been easier to implement. This is because - # the downside for getting the allowed checks wrong means some extra - # semicolons, while the downside for getting disallowed checks wrong - # would result in compile errors. - # - # In addition to macros, we also don't want to warn on - # - Compound literals - # - Lambdas - # - alignas specifier with anonymous structs - # - decltype - closing_brace_pos = match.group(1).rfind(')') - opening_parenthesis = ReverseCloseExpression( - clean_lines, linenum, closing_brace_pos) - if opening_parenthesis[2] > -1: - line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]] - macro = Search(r'\b([A-Z_][A-Z0-9_]*)\s*$', line_prefix) - func = Match(r'^(.*\])\s*$', line_prefix) - if ((macro and - macro.group(1) not in ( - 'TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST', - 'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED', - 'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or - (func and not Search(r'\boperator\s*\[\s*\]', func.group(1))) or - Search(r'\b(?:struct|union)\s+alignas\s*$', line_prefix) or - Search(r'\bdecltype$', line_prefix) or - Search(r'\s+=\s*$', line_prefix)): - match = None - if (match and - opening_parenthesis[1] > 1 and - Search(r'\]\s*$', clean_lines.elided[opening_parenthesis[1] - 1])): - # Multi-line lambda-expression - match = None - - else: - # Try matching cases 2-3. - match = Match(r'^(.*(?:else|\)\s*const)\s*)\{', line) - if not match: - # Try matching cases 4-6. These are always matched on separate lines. - # - # Note that we can't simply concatenate the previous line to the - # current line and do a single match, otherwise we may output - # duplicate warnings for the blank line case: - # if (cond) { - # // blank line - # } - prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] - if prevline and Search(r'[;{}]\s*$', prevline): - match = Match(r'^(\s*)\{', line) - - # Check matching closing brace - if match: - (endline, endlinenum, endpos) = CloseExpression( - clean_lines, linenum, len(match.group(1))) - if endpos > -1 and Match(r'^\s*;', endline[endpos:]): - # Current {} pair is eligible for semicolon check, and we have found - # the redundant semicolon, output warning here. - # - # Note: because we are scanning forward for opening braces, and - # outputting warnings for the matching closing brace, if there are - # nested blocks with trailing semicolons, we will get the error - # messages in reversed order. - - # We need to check the line forward for NOLINT - raw_lines = clean_lines.raw_lines - ParseNolintSuppressions(filename, raw_lines[endlinenum-1], endlinenum-1, - error) - ParseNolintSuppressions(filename, raw_lines[endlinenum], endlinenum, - error) - - error(filename, endlinenum, 'readability/braces', 4, - "You don't need a ; after a }") - - -def CheckEmptyBlockBody(filename, clean_lines, linenum, error): - """Look for empty loop/conditional body with only a single semicolon. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - - # Search for loop keywords at the beginning of the line. Because only - # whitespaces are allowed before the keywords, this will also ignore most - # do-while-loops, since those lines should start with closing brace. - # - # We also check "if" blocks here, since an empty conditional block - # is likely an error. - line = clean_lines.elided[linenum] - matched = Match(r'\s*(for|while|if)\s*\(', line) - if matched: - # Find the end of the conditional expression. - (end_line, end_linenum, end_pos) = CloseExpression( - clean_lines, linenum, line.find('(')) - - # Output warning if what follows the condition expression is a semicolon. - # No warning for all other cases, including whitespace or newline, since we - # have a separate check for semicolons preceded by whitespace. - if end_pos >= 0 and Match(r';', end_line[end_pos:]): - if matched.group(1) == 'if': - error(filename, end_linenum, 'whitespace/empty_conditional_body', 5, - 'Empty conditional bodies should use {}') - else: - error(filename, end_linenum, 'whitespace/empty_loop_body', 5, - 'Empty loop bodies should use {} or continue') - - # Check for if statements that have completely empty bodies (no comments) - # and no else clauses. - if end_pos >= 0 and matched.group(1) == 'if': - # Find the position of the opening { for the if statement. - # Return without logging an error if it has no brackets. - opening_linenum = end_linenum - opening_line_fragment = end_line[end_pos:] - # Loop until EOF or find anything that's not whitespace or opening {. - while not Search(r'^\s*\{', opening_line_fragment): - if Search(r'^(?!\s*$)', opening_line_fragment): - # Conditional has no brackets. - return - opening_linenum += 1 - if opening_linenum == len(clean_lines.elided): - # Couldn't find conditional's opening { or any code before EOF. - return - opening_line_fragment = clean_lines.elided[opening_linenum] - # Set opening_line (opening_line_fragment may not be entire opening line). - opening_line = clean_lines.elided[opening_linenum] - - # Find the position of the closing }. - opening_pos = opening_line_fragment.find('{') - if opening_linenum == end_linenum: - # We need to make opening_pos relative to the start of the entire line. - opening_pos += end_pos - (closing_line, closing_linenum, closing_pos) = CloseExpression( - clean_lines, opening_linenum, opening_pos) - if closing_pos < 0: - return - - # Now construct the body of the conditional. This consists of the portion - # of the opening line after the {, all lines until the closing line, - # and the portion of the closing line before the }. - if (clean_lines.raw_lines[opening_linenum] != - CleanseComments(clean_lines.raw_lines[opening_linenum])): - # Opening line ends with a comment, so conditional isn't empty. - return - if closing_linenum > opening_linenum: - # Opening line after the {. Ignore comments here since we checked above. - body = list(opening_line[opening_pos+1:]) - # All lines until closing line, excluding closing line, with comments. - body.extend(clean_lines.raw_lines[opening_linenum+1:closing_linenum]) - # Closing line before the }. Won't (and can't) have comments. - body.append(clean_lines.elided[closing_linenum][:closing_pos-1]) - body = '\n'.join(body) - else: - # If statement has brackets and fits on a single line. - body = opening_line[opening_pos+1:closing_pos-1] - - # Check if the body is empty - if not _EMPTY_CONDITIONAL_BODY_PATTERN.search(body): - return - # The body is empty. Now make sure there's not an else clause. - current_linenum = closing_linenum - current_line_fragment = closing_line[closing_pos:] - # Loop until EOF or find anything that's not whitespace or else clause. - while Search(r'^\s*$|^(?=\s*else)', current_line_fragment): - if Search(r'^(?=\s*else)', current_line_fragment): - # Found an else clause, so don't log an error. - return - current_linenum += 1 - if current_linenum == len(clean_lines.elided): - break - current_line_fragment = clean_lines.elided[current_linenum] - - # The body is empty and there's no else clause until EOF or other code. - error(filename, end_linenum, 'whitespace/empty_if_body', 4, - ('If statement had no body and no else clause')) - - -def FindCheckMacro(line): - """Find a replaceable CHECK-like macro. - - Args: - line: line to search on. - Returns: - (macro name, start position), or (None, -1) if no replaceable - macro is found. - """ - for macro in _CHECK_MACROS: - i = line.find(macro) - if i >= 0: - # Find opening parenthesis. Do a regular expression match here - # to make sure that we are matching the expected CHECK macro, as - # opposed to some other macro that happens to contain the CHECK - # substring. - matched = Match(r'^(.*\b' + macro + r'\s*)\(', line) - if not matched: - continue - return (macro, len(matched.group(1))) - return (None, -1) - - -def CheckCheck(filename, clean_lines, linenum, error): - """Checks the use of CHECK and EXPECT macros. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - - # Decide the set of replacement macros that should be suggested - lines = clean_lines.elided - (check_macro, start_pos) = FindCheckMacro(lines[linenum]) - if not check_macro: - return - - # Find end of the boolean expression by matching parentheses - (last_line, end_line, end_pos) = CloseExpression( - clean_lines, linenum, start_pos) - if end_pos < 0: - return - - # If the check macro is followed by something other than a - # semicolon, assume users will log their own custom error messages - # and don't suggest any replacements. - if not Match(r'\s*;', last_line[end_pos:]): - return - - if linenum == end_line: - expression = lines[linenum][start_pos + 1:end_pos - 1] - else: - expression = lines[linenum][start_pos + 1:] - for i in xrange(linenum + 1, end_line): - expression += lines[i] - expression += last_line[0:end_pos - 1] - - # Parse expression so that we can take parentheses into account. - # This avoids false positives for inputs like "CHECK((a < 4) == b)", - # which is not replaceable by CHECK_LE. - lhs = '' - rhs = '' - operator = None - while expression: - matched = Match(r'^\s*(<<|<<=|>>|>>=|->\*|->|&&|\|\||' - r'==|!=|>=|>|<=|<|\()(.*)$', expression) - if matched: - token = matched.group(1) - if token == '(': - # Parenthesized operand - expression = matched.group(2) - (end, _) = FindEndOfExpressionInLine(expression, 0, ['(']) - if end < 0: - return # Unmatched parenthesis - lhs += '(' + expression[0:end] - expression = expression[end:] - elif token in ('&&', '||'): - # Logical and/or operators. This means the expression - # contains more than one term, for example: - # CHECK(42 < a && a < b); - # - # These are not replaceable with CHECK_LE, so bail out early. - return - elif token in ('<<', '<<=', '>>', '>>=', '->*', '->'): - # Non-relational operator - lhs += token - expression = matched.group(2) - else: - # Relational operator - operator = token - rhs = matched.group(2) - break - else: - # Unparenthesized operand. Instead of appending to lhs one character - # at a time, we do another regular expression match to consume several - # characters at once if possible. Trivial benchmark shows that this - # is more efficient when the operands are longer than a single - # character, which is generally the case. - matched = Match(r'^([^-=!<>()&|]+)(.*)$', expression) - if not matched: - matched = Match(r'^(\s*\S)(.*)$', expression) - if not matched: - break - lhs += matched.group(1) - expression = matched.group(2) - - # Only apply checks if we got all parts of the boolean expression - if not (lhs and operator and rhs): - return - - # Check that rhs do not contain logical operators. We already know - # that lhs is fine since the loop above parses out && and ||. - if rhs.find('&&') > -1 or rhs.find('||') > -1: - return - - # At least one of the operands must be a constant literal. This is - # to avoid suggesting replacements for unprintable things like - # CHECK(variable != iterator) - # - # The following pattern matches decimal, hex integers, strings, and - # characters (in that order). - lhs = lhs.strip() - rhs = rhs.strip() - match_constant = r'^([-+]?(\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|".*"|\'.*\')$' - if Match(match_constant, lhs) or Match(match_constant, rhs): - # Note: since we know both lhs and rhs, we can provide a more - # descriptive error message like: - # Consider using CHECK_EQ(x, 42) instead of CHECK(x == 42) - # Instead of: - # Consider using CHECK_EQ instead of CHECK(a == b) - # - # We are still keeping the less descriptive message because if lhs - # or rhs gets long, the error message might become unreadable. - error(filename, linenum, 'readability/check', 2, - 'Consider using %s instead of %s(a %s b)' % ( - _CHECK_REPLACEMENT[check_macro][operator], - check_macro, operator)) - - -def CheckAltTokens(filename, clean_lines, linenum, error): - """Check alternative keywords being used in boolean expressions. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - line = clean_lines.elided[linenum] - - # Avoid preprocessor lines - if Match(r'^\s*#', line): - return - - # Last ditch effort to avoid multi-line comments. This will not help - # if the comment started before the current line or ended after the - # current line, but it catches most of the false positives. At least, - # it provides a way to workaround this warning for people who use - # multi-line comments in preprocessor macros. - # - # TODO(unknown): remove this once cpplint has better support for - # multi-line comments. - if line.find('/*') >= 0 or line.find('*/') >= 0: - return - - for match in _ALT_TOKEN_REPLACEMENT_PATTERN.finditer(line): - error(filename, linenum, 'readability/alt_tokens', 2, - 'Use operator %s instead of %s' % ( - _ALT_TOKEN_REPLACEMENT[match.group(1)], match.group(1))) - - -def GetLineWidth(line): - """Determines the width of the line in column positions. - - Args: - line: A string, which may be a Unicode string. - - Returns: - The width of the line in column positions, accounting for Unicode - combining characters and wide characters. - """ - if isinstance(line, unicode): - width = 0 - for uc in unicodedata.normalize('NFC', line): - if unicodedata.east_asian_width(uc) in ('W', 'F'): - width += 2 - elif not unicodedata.combining(uc): - # Issue 337 - # https://mail.python.org/pipermail/python-list/2012-August/628809.html - if (sys.version_info.major, sys.version_info.minor) <= (3, 2): - # https://github.com/python/cpython/blob/2.7/Include/unicodeobject.h#L81 - is_wide_build = sysconfig.get_config_var("Py_UNICODE_SIZE") >= 4 - # https://github.com/python/cpython/blob/2.7/Objects/unicodeobject.c#L564 - is_low_surrogate = 0xDC00 <= ord(uc) <= 0xDFFF - if not is_wide_build and is_low_surrogate: - width -= 1 - - width += 1 - return width - else: - return len(line) - - -def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state, - error): - """Checks rules from the 'C++ style rules' section of cppguide.html. - - Most of these rules are hard to test (naming, comment style), but we - do what we can. In particular we check for 2-space indents, line lengths, - tab usage, spaces inside code, etc. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - file_extension: The extension (without the dot) of the filename. - nesting_state: A NestingState instance which maintains information about - the current stack of nested blocks being parsed. - error: The function to call with any errors found. - """ - - # Don't use "elided" lines here, otherwise we can't check commented lines. - # Don't want to use "raw" either, because we don't want to check inside C++11 - # raw strings, - raw_lines = clean_lines.lines_without_raw_strings - line = raw_lines[linenum] - prev = raw_lines[linenum - 1] if linenum > 0 else '' - - if line.find('\t') != -1: - error(filename, linenum, 'whitespace/tab', 1, - 'Tab found; better to use spaces') - - # One or three blank spaces at the beginning of the line is weird; it's - # hard to reconcile that with 2-space indents. - # NOTE: here are the conditions rob pike used for his tests. Mine aren't - # as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces - # if(RLENGTH > 20) complain = 0; - # if(match($0, " +(error|private|public|protected):")) complain = 0; - # if(match(prev, "&& *$")) complain = 0; - # if(match(prev, "\\|\\| *$")) complain = 0; - # if(match(prev, "[\",=><] *$")) complain = 0; - # if(match($0, " <<")) complain = 0; - # if(match(prev, " +for \\(")) complain = 0; - # if(prevodd && match(prevprev, " +for \\(")) complain = 0; - scope_or_label_pattern = r'\s*\w+\s*:\s*\\?$' - classinfo = nesting_state.InnermostClass() - initial_spaces = 0 - cleansed_line = clean_lines.elided[linenum] - while initial_spaces < len(line) and line[initial_spaces] == ' ': - initial_spaces += 1 - # There are certain situations we allow one space, notably for - # section labels, and also lines containing multi-line raw strings. - # We also don't check for lines that look like continuation lines - # (of lines ending in double quotes, commas, equals, or angle brackets) - # because the rules for how to indent those are non-trivial. - if (not Search(r'[",=><] *$', prev) and - (initial_spaces == 1 or initial_spaces == 3) and - not Match(scope_or_label_pattern, cleansed_line) and - not (clean_lines.raw_lines[linenum] != line and - Match(r'^\s*""', line))): - error(filename, linenum, 'whitespace/indent', 3, - 'Weird number of spaces at line-start. ' - 'Are you using a 2-space indent?') - - if line and line[-1].isspace(): - error(filename, linenum, 'whitespace/end_of_line', 4, - 'Line ends in whitespace. Consider deleting these extra spaces.') - - # Check if the line is a header guard. - is_header_guard = False - if IsHeaderExtension(file_extension): - cppvar = GetHeaderGuardCPPVariable(filename) - if (line.startswith('#ifndef %s' % cppvar) or - line.startswith('#define %s' % cppvar) or - line.startswith('#endif // %s' % cppvar)): - is_header_guard = True - # #include lines and header guards can be long, since there's no clean way to - # split them. - # - # URLs can be long too. It's possible to split these, but it makes them - # harder to cut&paste. - # - # The "$Id:...$" comment may also get very long without it being the - # developers fault. - if (not line.startswith('#include') and not is_header_guard and - not Match(r'^\s*//.*http(s?)://\S*$', line) and - not Match(r'^\s*//\s*[^\s]*$', line) and - not Match(r'^// \$Id:.*#[0-9]+ \$$', line)): - line_width = GetLineWidth(line) - if line_width > _line_length: - error(filename, linenum, 'whitespace/line_length', 2, - 'Lines should be <= %i characters long' % _line_length) - - if (cleansed_line.count(';') > 1 and - # for loops are allowed two ;'s (and may run over two lines). - cleansed_line.find('for') == -1 and - (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or - GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and - # It's ok to have many commands in a switch case that fits in 1 line - not ((cleansed_line.find('case ') != -1 or - cleansed_line.find('default:') != -1) and - cleansed_line.find('break;') != -1)): - error(filename, linenum, 'whitespace/newline', 0, - 'More than one command on the same line') - - # Some more style checks - CheckBraces(filename, clean_lines, linenum, error) - CheckTrailingSemicolon(filename, clean_lines, linenum, error) - CheckEmptyBlockBody(filename, clean_lines, linenum, error) - CheckSpacing(filename, clean_lines, linenum, nesting_state, error) - CheckOperatorSpacing(filename, clean_lines, linenum, error) - CheckParenthesisSpacing(filename, clean_lines, linenum, error) - CheckCommaSpacing(filename, clean_lines, linenum, error) - CheckBracesSpacing(filename, clean_lines, linenum, nesting_state, error) - CheckSpacingForFunctionCall(filename, clean_lines, linenum, error) - CheckCheck(filename, clean_lines, linenum, error) - CheckAltTokens(filename, clean_lines, linenum, error) - classinfo = nesting_state.InnermostClass() - if classinfo: - CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error) - - -_RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$') -# Matches the first component of a filename delimited by -s and _s. That is: -# _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo' -# _RE_FIRST_COMPONENT.match('foo.cc').group(0) == 'foo' -# _RE_FIRST_COMPONENT.match('foo-bar_baz.cc').group(0) == 'foo' -# _RE_FIRST_COMPONENT.match('foo_bar-baz.cc').group(0) == 'foo' -_RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+') - - -def _DropCommonSuffixes(filename): - """Drops common suffixes like _test.cc or -inl.h from filename. - - For example: - >>> _DropCommonSuffixes('foo/foo-inl.h') - 'foo/foo' - >>> _DropCommonSuffixes('foo/bar/foo.cc') - 'foo/bar/foo' - >>> _DropCommonSuffixes('foo/foo_internal.h') - 'foo/foo' - >>> _DropCommonSuffixes('foo/foo_unusualinternal.h') - 'foo/foo_unusualinternal' - - Args: - filename: The input filename. - - Returns: - The filename with the common suffix removed. - """ - for suffix in ('test.cc', 'regtest.cc', 'unittest.cc', - 'inl.h', 'impl.h', 'internal.h'): - if (filename.endswith(suffix) and len(filename) > len(suffix) and - filename[-len(suffix) - 1] in ('-', '_')): - return filename[:-len(suffix) - 1] - return os.path.splitext(filename)[0] - - -def _ClassifyInclude(fileinfo, include, is_system): - """Figures out what kind of header 'include' is. - - Args: - fileinfo: The current file cpplint is running over. A FileInfo instance. - include: The path to a #included file. - is_system: True if the #include used <> rather than "". - - Returns: - One of the _XXX_HEADER constants. - - For example: - >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'stdio.h', True) - _C_SYS_HEADER - >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'string', True) - _CPP_SYS_HEADER - >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.h', False) - _LIKELY_MY_HEADER - >>> _ClassifyInclude(FileInfo('foo/foo_unknown_extension.cc'), - ... 'bar/foo_other_ext.h', False) - _POSSIBLE_MY_HEADER - >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/bar.h', False) - _OTHER_HEADER - """ - # This is a list of all standard c++ header files, except - # those already checked for above. - is_cpp_h = include in _CPP_HEADERS - - if is_system: - if is_cpp_h: - return _CPP_SYS_HEADER - else: - return _C_SYS_HEADER - - # If the target file and the include we're checking share a - # basename when we drop common extensions, and the include - # lives in . , then it's likely to be owned by the target file. - target_dir, target_base = ( - os.path.split(_DropCommonSuffixes(fileinfo.RepositoryName()))) - include_dir, include_base = os.path.split(_DropCommonSuffixes(include)) - if target_base == include_base and ( - include_dir == target_dir or - include_dir == os.path.normpath(target_dir + '/../public')): - return _LIKELY_MY_HEADER - - # If the target and include share some initial basename - # component, it's possible the target is implementing the - # include, so it's allowed to be first, but we'll never - # complain if it's not there. - target_first_component = _RE_FIRST_COMPONENT.match(target_base) - include_first_component = _RE_FIRST_COMPONENT.match(include_base) - if (target_first_component and include_first_component and - target_first_component.group(0) == - include_first_component.group(0)): - return _POSSIBLE_MY_HEADER - - return _OTHER_HEADER - - - -def CheckIncludeLine(filename, clean_lines, linenum, include_state, error): - """Check rules that are applicable to #include lines. - - Strings on #include lines are NOT removed from elided line, to make - certain tasks easier. However, to prevent false positives, checks - applicable to #include lines in CheckLanguage must be put here. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - include_state: An _IncludeState instance in which the headers are inserted. - error: The function to call with any errors found. - """ - fileinfo = FileInfo(filename) - line = clean_lines.lines[linenum] - - # "include" should use the new style "foo/bar.h" instead of just "bar.h" - # Only do this check if the included header follows google naming - # conventions. If not, assume that it's a 3rd party API that - # requires special include conventions. - # - # We also make an exception for Lua headers, which follow google - # naming convention but not the include convention. - match = Match(r'#include\s*"([^/]+\.h)"', line) - if match and not _THIRD_PARTY_HEADERS_PATTERN.match(match.group(1)): - error(filename, linenum, 'build/include', 4, - 'Include the directory when naming .h files') - - # we shouldn't include a file more than once. actually, there are a - # handful of instances where doing so is okay, but in general it's - # not. - match = _RE_PATTERN_INCLUDE.search(line) - if match: - include = match.group(2) - is_system = (match.group(1) == '<') - duplicate_line = include_state.FindHeader(include) - if duplicate_line >= 0: - error(filename, linenum, 'build/include', 4, - '"%s" already included at %s:%s' % - (include, filename, duplicate_line)) - elif (include.endswith('.cc') and - os.path.dirname(fileinfo.RepositoryName()) != os.path.dirname(include)): - error(filename, linenum, 'build/include', 4, - 'Do not include .cc files from other packages') - elif not _THIRD_PARTY_HEADERS_PATTERN.match(include): - include_state.include_list[-1].append((include, linenum)) - - # We want to ensure that headers appear in the right order: - # 1) for foo.cc, foo.h (preferred location) - # 2) c system files - # 3) cpp system files - # 4) for foo.cc, foo.h (deprecated location) - # 5) other google headers - # - # We classify each include statement as one of those 5 types - # using a number of techniques. The include_state object keeps - # track of the highest type seen, and complains if we see a - # lower type after that. - error_message = include_state.CheckNextIncludeOrder( - _ClassifyInclude(fileinfo, include, is_system)) - if error_message: - error(filename, linenum, 'build/include_order', 4, - '%s. Should be: %s.h, c system, c++ system, other.' % - (error_message, fileinfo.BaseName())) - canonical_include = include_state.CanonicalizeAlphabeticalOrder(include) - if not include_state.IsInAlphabeticalOrder( - clean_lines, linenum, canonical_include): - error(filename, linenum, 'build/include_alpha', 4, - 'Include "%s" not in alphabetical order' % include) - include_state.SetLastHeader(canonical_include) - - - -def _GetTextInside(text, start_pattern): - r"""Retrieves all the text between matching open and close parentheses. - - Given a string of lines and a regular expression string, retrieve all the text - following the expression and between opening punctuation symbols like - (, [, or {, and the matching close-punctuation symbol. This properly nested - occurrences of the punctuations, so for the text like - printf(a(), b(c())); - a call to _GetTextInside(text, r'printf\(') will return 'a(), b(c())'. - start_pattern must match string having an open punctuation symbol at the end. - - Args: - text: The lines to extract text. Its comments and strings must be elided. - It can be single line and can span multiple lines. - start_pattern: The regexp string indicating where to start extracting - the text. - Returns: - The extracted text. - None if either the opening string or ending punctuation could not be found. - """ - # TODO(unknown): Audit cpplint.py to see what places could be profitably - # rewritten to use _GetTextInside (and use inferior regexp matching today). - - # Give opening punctuations to get the matching close-punctuations. - matching_punctuation = {'(': ')', '{': '}', '[': ']'} - closing_punctuation = set(matching_punctuation.itervalues()) - - # Find the position to start extracting text. - match = re.search(start_pattern, text, re.M) - if not match: # start_pattern not found in text. - return None - start_position = match.end(0) - - assert start_position > 0, ( - 'start_pattern must ends with an opening punctuation.') - assert text[start_position - 1] in matching_punctuation, ( - 'start_pattern must ends with an opening punctuation.') - # Stack of closing punctuations we expect to have in text after position. - punctuation_stack = [matching_punctuation[text[start_position - 1]]] - position = start_position - while punctuation_stack and position < len(text): - if text[position] == punctuation_stack[-1]: - punctuation_stack.pop() - elif text[position] in closing_punctuation: - # A closing punctuation without matching opening punctuations. - return None - elif text[position] in matching_punctuation: - punctuation_stack.append(matching_punctuation[text[position]]) - position += 1 - if punctuation_stack: - # Opening punctuations left without matching close-punctuations. - return None - # punctuations match. - return text[start_position:position - 1] - - -# Patterns for matching call-by-reference parameters. -# -# Supports nested templates up to 2 levels deep using this messy pattern: -# < (?: < (?: < [^<>]* -# > -# | [^<>] )* -# > -# | [^<>] )* -# > -_RE_PATTERN_IDENT = r'[_a-zA-Z]\w*' # =~ [[:alpha:]][[:alnum:]]* -_RE_PATTERN_TYPE = ( - r'(?:const\s+)?(?:typename\s+|class\s+|struct\s+|union\s+|enum\s+)?' - r'(?:\w|' - r'\s*<(?:<(?:<[^<>]*>|[^<>])*>|[^<>])*>|' - r'::)+') -# A call-by-reference parameter ends with '& identifier'. -_RE_PATTERN_REF_PARAM = re.compile( - r'(' + _RE_PATTERN_TYPE + r'(?:\s*(?:\bconst\b|[*]))*\s*' - r'&\s*' + _RE_PATTERN_IDENT + r')\s*(?:=[^,()]+)?[,)]') -# A call-by-const-reference parameter either ends with 'const& identifier' -# or looks like 'const type& identifier' when 'type' is atomic. -_RE_PATTERN_CONST_REF_PARAM = ( - r'(?:.*\s*\bconst\s*&\s*' + _RE_PATTERN_IDENT + - r'|const\s+' + _RE_PATTERN_TYPE + r'\s*&\s*' + _RE_PATTERN_IDENT + r')') -# Stream types. -_RE_PATTERN_REF_STREAM_PARAM = ( - r'(?:.*stream\s*&\s*' + _RE_PATTERN_IDENT + r')') - - -def CheckLanguage(filename, clean_lines, linenum, file_extension, - include_state, nesting_state, error): - """Checks rules from the 'C++ language rules' section of cppguide.html. - - Some of these rules are hard to test (function overloading, using - uint32 inappropriately), but we do the best we can. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - file_extension: The extension (without the dot) of the filename. - include_state: An _IncludeState instance in which the headers are inserted. - nesting_state: A NestingState instance which maintains information about - the current stack of nested blocks being parsed. - error: The function to call with any errors found. - """ - # If the line is empty or consists of entirely a comment, no need to - # check it. - line = clean_lines.elided[linenum] - if not line: - return - - match = _RE_PATTERN_INCLUDE.search(line) - if match: - CheckIncludeLine(filename, clean_lines, linenum, include_state, error) - return - - # Reset include state across preprocessor directives. This is meant - # to silence warnings for conditional includes. - match = Match(r'^\s*#\s*(if|ifdef|ifndef|elif|else|endif)\b', line) - if match: - include_state.ResetSection(match.group(1)) - - # Make Windows paths like Unix. - fullname = os.path.abspath(filename).replace('\\', '/') - - # Perform other checks now that we are sure that this is not an include line - CheckCasts(filename, clean_lines, linenum, error) - CheckGlobalStatic(filename, clean_lines, linenum, error) - CheckPrintf(filename, clean_lines, linenum, error) - - if IsHeaderExtension(file_extension): - # TODO(unknown): check that 1-arg constructors are explicit. - # How to tell it's a constructor? - # (handled in CheckForNonStandardConstructs for now) - # TODO(unknown): check that classes declare or disable copy/assign - # (level 1 error) - pass - - # Check if people are using the verboten C basic types. The only exception - # we regularly allow is "unsigned short port" for port. - if Search(r'\bshort port\b', line): - if not Search(r'\bunsigned short port\b', line): - error(filename, linenum, 'runtime/int', 4, - 'Use "unsigned short" for ports, not "short"') - else: - match = Search(r'\b(short|long(?! +double)|long long)\b', line) - if match: - error(filename, linenum, 'runtime/int', 4, - 'Use int16/int64/etc, rather than the C type %s' % match.group(1)) - - # Check if some verboten operator overloading is going on - # TODO(unknown): catch out-of-line unary operator&: - # class X {}; - # int operator&(const X& x) { return 42; } // unary operator& - # The trick is it's hard to tell apart from binary operator&: - # class Y { int operator&(const Y& x) { return 23; } }; // binary operator& - if Search(r'\boperator\s*&\s*\(\s*\)', line): - error(filename, linenum, 'runtime/operator', 4, - 'Unary operator& is dangerous. Do not use it.') - - # Check for suspicious usage of "if" like - # } if (a == b) { - if Search(r'\}\s*if\s*\(', line): - error(filename, linenum, 'readability/braces', 4, - 'Did you mean "else if"? If not, start a new line for "if".') - - # Check for potential format string bugs like printf(foo). - # We constrain the pattern not to pick things like DocidForPrintf(foo). - # Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str()) - # TODO(unknown): Catch the following case. Need to change the calling - # convention of the whole function to process multiple line to handle it. - # printf( - # boy_this_is_a_really_long_variable_that_cannot_fit_on_the_prev_line); - printf_args = _GetTextInside(line, r'(?i)\b(string)?printf\s*\(') - if printf_args: - match = Match(r'([\w.\->()]+)$', printf_args) - if match and match.group(1) != '__VA_ARGS__': - function_name = re.search(r'\b((?:string)?printf)\s*\(', - line, re.I).group(1) - error(filename, linenum, 'runtime/printf', 4, - 'Potential format string bug. Do %s("%%s", %s) instead.' - % (function_name, match.group(1))) - - # Check for potential memset bugs like memset(buf, sizeof(buf), 0). - match = Search(r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)', line) - if match and not Match(r"^''|-?[0-9]+|0x[0-9A-Fa-f]$", match.group(2)): - error(filename, linenum, 'runtime/memset', 4, - 'Did you mean "memset(%s, 0, %s)"?' - % (match.group(1), match.group(2))) - - if Search(r'\busing namespace\b', line): - error(filename, linenum, 'build/namespaces', 5, - 'Do not use namespace using-directives. ' - 'Use using-declarations instead.') - - # Detect variable-length arrays. - match = Match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line) - if (match and match.group(2) != 'return' and match.group(2) != 'delete' and - match.group(3).find(']') == -1): - # Split the size using space and arithmetic operators as delimiters. - # If any of the resulting tokens are not compile time constants then - # report the error. - tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', match.group(3)) - is_const = True - skip_next = False - for tok in tokens: - if skip_next: - skip_next = False - continue - - if Search(r'sizeof\(.+\)', tok): continue - if Search(r'arraysize\(\w+\)', tok): continue - - tok = tok.lstrip('(') - tok = tok.rstrip(')') - if not tok: continue - if Match(r'\d+', tok): continue - if Match(r'0[xX][0-9a-fA-F]+', tok): continue - if Match(r'k[A-Z0-9]\w*', tok): continue - if Match(r'(.+::)?k[A-Z0-9]\w*', tok): continue - if Match(r'(.+::)?[A-Z][A-Z0-9_]*', tok): continue - # A catch all for tricky sizeof cases, including 'sizeof expression', - # 'sizeof(*type)', 'sizeof(const type)', 'sizeof(struct StructName)' - # requires skipping the next token because we split on ' ' and '*'. - if tok.startswith('sizeof'): - skip_next = True - continue - is_const = False - break - if not is_const: - error(filename, linenum, 'runtime/arrays', 1, - 'Do not use variable-length arrays. Use an appropriately named ' - "('k' followed by CamelCase) compile-time constant for the size.") - - # Check for use of unnamed namespaces in header files. Registration - # macros are typically OK, so we allow use of "namespace {" on lines - # that end with backslashes. - if (IsHeaderExtension(file_extension) - and Search(r'\bnamespace\s*{', line) - and line[-1] != '\\'): - error(filename, linenum, 'build/namespaces', 4, - 'Do not use unnamed namespaces in header files. See ' - 'https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces' - ' for more information.') - - -def CheckGlobalStatic(filename, clean_lines, linenum, error): - """Check for unsafe global or static objects. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - line = clean_lines.elided[linenum] - - # Match two lines at a time to support multiline declarations - if linenum + 1 < clean_lines.NumLines() and not Search(r'[;({]', line): - line += clean_lines.elided[linenum + 1].strip() - - # Check for people declaring static/global STL strings at the top level. - # This is dangerous because the C++ language does not guarantee that - # globals with constructors are initialized before the first access, and - # also because globals can be destroyed when some threads are still running. - # TODO(unknown): Generalize this to also find static unique_ptr instances. - # TODO(unknown): File bugs for clang-tidy to find these. - match = Match( - r'((?:|static +)(?:|const +))(?::*std::)?string( +const)? +' - r'([a-zA-Z0-9_:]+)\b(.*)', - line) - - # Remove false positives: - # - String pointers (as opposed to values). - # string *pointer - # const string *pointer - # string const *pointer - # string *const pointer - # - # - Functions and template specializations. - # string Function(... - # string Class::Method(... - # - # - Operators. These are matched separately because operator names - # cross non-word boundaries, and trying to match both operators - # and functions at the same time would decrease accuracy of - # matching identifiers. - # string Class::operator*() - if (match and - not Search(r'\bstring\b(\s+const)?\s*[\*\&]\s*(const\s+)?\w', line) and - not Search(r'\boperator\W', line) and - not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)*\s*\(([^"]|$)', match.group(4))): - if Search(r'\bconst\b', line): - error(filename, linenum, 'runtime/string', 4, - 'For a static/global string constant, use a C style string ' - 'instead: "%schar%s %s[]".' % - (match.group(1), match.group(2) or '', match.group(3))) - else: - error(filename, linenum, 'runtime/string', 4, - 'Static/global string variables are not permitted.') - - if (Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line) or - Search(r'\b([A-Za-z0-9_]*_)\(CHECK_NOTNULL\(\1\)\)', line)): - error(filename, linenum, 'runtime/init', 4, - 'You seem to be initializing a member variable with itself.') - - -def CheckPrintf(filename, clean_lines, linenum, error): - """Check for printf related issues. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - line = clean_lines.elided[linenum] - - # When snprintf is used, the second argument shouldn't be a literal. - match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line) - if match and match.group(2) != '0': - # If 2nd arg is zero, snprintf is used to calculate size. - error(filename, linenum, 'runtime/printf', 3, - 'If you can, use sizeof(%s) instead of %s as the 2nd arg ' - 'to snprintf.' % (match.group(1), match.group(2))) - - # Check if some verboten C functions are being used. - if Search(r'\bsprintf\s*\(', line): - error(filename, linenum, 'runtime/printf', 5, - 'Never use sprintf. Use snprintf instead.') - match = Search(r'\b(strcpy|strcat)\s*\(', line) - if match: - error(filename, linenum, 'runtime/printf', 4, - 'Almost always, snprintf is better than %s' % match.group(1)) - - -def IsDerivedFunction(clean_lines, linenum): - """Check if current line contains an inherited function. - - Args: - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - Returns: - True if current line contains a function with "override" - virt-specifier. - """ - # Scan back a few lines for start of current function - for i in xrange(linenum, max(-1, linenum - 10), -1): - match = Match(r'^([^()]*\w+)\(', clean_lines.elided[i]) - if match: - # Look for "override" after the matching closing parenthesis - line, _, closing_paren = CloseExpression( - clean_lines, i, len(match.group(1))) - return (closing_paren >= 0 and - Search(r'\boverride\b', line[closing_paren:])) - return False - - -def IsOutOfLineMethodDefinition(clean_lines, linenum): - """Check if current line contains an out-of-line method definition. - - Args: - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - Returns: - True if current line contains an out-of-line method definition. - """ - # Scan back a few lines for start of current function - for i in xrange(linenum, max(-1, linenum - 10), -1): - if Match(r'^([^()]*\w+)\(', clean_lines.elided[i]): - return Match(r'^[^()]*\w+::\w+\(', clean_lines.elided[i]) is not None - return False - - -def IsInitializerList(clean_lines, linenum): - """Check if current line is inside constructor initializer list. - - Args: - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - Returns: - True if current line appears to be inside constructor initializer - list, False otherwise. - """ - for i in xrange(linenum, 1, -1): - line = clean_lines.elided[i] - if i == linenum: - remove_function_body = Match(r'^(.*)\{\s*$', line) - if remove_function_body: - line = remove_function_body.group(1) - - if Search(r'\s:\s*\w+[({]', line): - # A lone colon tend to indicate the start of a constructor - # initializer list. It could also be a ternary operator, which - # also tend to appear in constructor initializer lists as - # opposed to parameter lists. - return True - if Search(r'\}\s*,\s*$', line): - # A closing brace followed by a comma is probably the end of a - # brace-initialized member in constructor initializer list. - return True - if Search(r'[{};]\s*$', line): - # Found one of the following: - # - A closing brace or semicolon, probably the end of the previous - # function. - # - An opening brace, probably the start of current class or namespace. - # - # Current line is probably not inside an initializer list since - # we saw one of those things without seeing the starting colon. - return False - - # Got to the beginning of the file without seeing the start of - # constructor initializer list. - return False - - -def CheckForNonConstReference(filename, clean_lines, linenum, - nesting_state, error): - """Check for non-const references. - - Separate from CheckLanguage since it scans backwards from current - line, instead of scanning forward. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - nesting_state: A NestingState instance which maintains information about - the current stack of nested blocks being parsed. - error: The function to call with any errors found. - """ - # Do nothing if there is no '&' on current line. - line = clean_lines.elided[linenum] - if '&' not in line: - return - - # If a function is inherited, current function doesn't have much of - # a choice, so any non-const references should not be blamed on - # derived function. - if IsDerivedFunction(clean_lines, linenum): - return - - # Don't warn on out-of-line method definitions, as we would warn on the - # in-line declaration, if it isn't marked with 'override'. - if IsOutOfLineMethodDefinition(clean_lines, linenum): - return - - # Long type names may be broken across multiple lines, usually in one - # of these forms: - # LongType - # ::LongTypeContinued &identifier - # LongType:: - # LongTypeContinued &identifier - # LongType< - # ...>::LongTypeContinued &identifier - # - # If we detected a type split across two lines, join the previous - # line to current line so that we can match const references - # accordingly. - # - # Note that this only scans back one line, since scanning back - # arbitrary number of lines would be expensive. If you have a type - # that spans more than 2 lines, please use a typedef. - if linenum > 1: - previous = None - if Match(r'\s*::(?:[\w<>]|::)+\s*&\s*\S', line): - # previous_line\n + ::current_line - previous = Search(r'\b((?:const\s*)?(?:[\w<>]|::)+[\w<>])\s*$', - clean_lines.elided[linenum - 1]) - elif Match(r'\s*[a-zA-Z_]([\w<>]|::)+\s*&\s*\S', line): - # previous_line::\n + current_line - previous = Search(r'\b((?:const\s*)?(?:[\w<>]|::)+::)\s*$', - clean_lines.elided[linenum - 1]) - if previous: - line = previous.group(1) + line.lstrip() - else: - # Check for templated parameter that is split across multiple lines - endpos = line.rfind('>') - if endpos > -1: - (_, startline, startpos) = ReverseCloseExpression( - clean_lines, linenum, endpos) - if startpos > -1 and startline < linenum: - # Found the matching < on an earlier line, collect all - # pieces up to current line. - line = '' - for i in xrange(startline, linenum + 1): - line += clean_lines.elided[i].strip() - - # Check for non-const references in function parameters. A single '&' may - # found in the following places: - # inside expression: binary & for bitwise AND - # inside expression: unary & for taking the address of something - # inside declarators: reference parameter - # We will exclude the first two cases by checking that we are not inside a - # function body, including one that was just introduced by a trailing '{'. - # TODO(unknown): Doesn't account for 'catch(Exception& e)' [rare]. - if (nesting_state.previous_stack_top and - not (isinstance(nesting_state.previous_stack_top, _ClassInfo) or - isinstance(nesting_state.previous_stack_top, _NamespaceInfo))): - # Not at toplevel, not within a class, and not within a namespace - return - - # Avoid initializer lists. We only need to scan back from the - # current line for something that starts with ':'. - # - # We don't need to check the current line, since the '&' would - # appear inside the second set of parentheses on the current line as - # opposed to the first set. - if linenum > 0: - for i in xrange(linenum - 1, max(0, linenum - 10), -1): - previous_line = clean_lines.elided[i] - if not Search(r'[),]\s*$', previous_line): - break - if Match(r'^\s*:\s+\S', previous_line): - return - - # Avoid preprocessors - if Search(r'\\\s*$', line): - return - - # Avoid constructor initializer lists - if IsInitializerList(clean_lines, linenum): - return - - # We allow non-const references in a few standard places, like functions - # called "swap()" or iostream operators like "<<" or ">>". Do not check - # those function parameters. - # - # We also accept & in static_assert, which looks like a function but - # it's actually a declaration expression. - allowed_functions = (r'(?:[sS]wap(?:<\w:+>)?|' - r'operator\s*[<>][<>]|' - r'static_assert|COMPILE_ASSERT' - r')\s*\(') - if Search(allowed_functions, line): - return - elif not Search(r'\S+\([^)]*$', line): - # Don't see an allowed function on this line. Actually we - # didn't see any function name on this line, so this is likely a - # multi-line parameter list. Try a bit harder to catch this case. - for i in xrange(2): - if (linenum > i and - Search(allowed_functions, clean_lines.elided[linenum - i - 1])): - return - - decls = ReplaceAll(r'{[^}]*}', ' ', line) # exclude function body - for parameter in re.findall(_RE_PATTERN_REF_PARAM, decls): - if (not Match(_RE_PATTERN_CONST_REF_PARAM, parameter) and - not Match(_RE_PATTERN_REF_STREAM_PARAM, parameter)): - error(filename, linenum, 'runtime/references', 2, - 'Is this a non-const reference? ' - 'If so, make const or use a pointer: ' + - ReplaceAll(' *<', '<', parameter)) - - -def CheckCasts(filename, clean_lines, linenum, error): - """Various cast related checks. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - line = clean_lines.elided[linenum] - - # Check to see if they're using an conversion function cast. - # I just try to capture the most common basic types, though there are more. - # Parameterless conversion functions, such as bool(), are allowed as they are - # probably a member operator declaration or default constructor. - match = Search( - r'(\bnew\s+(?:const\s+)?|\S<\s*(?:const\s+)?)?\b' - r'(int|float|double|bool|char|int32|uint32|int64|uint64)' - r'(\([^)].*)', line) - expecting_function = ExpectingFunctionArgs(clean_lines, linenum) - if match and not expecting_function: - matched_type = match.group(2) - - # matched_new_or_template is used to silence two false positives: - # - New operators - # - Template arguments with function types - # - # For template arguments, we match on types immediately following - # an opening bracket without any spaces. This is a fast way to - # silence the common case where the function type is the first - # template argument. False negative with less-than comparison is - # avoided because those operators are usually followed by a space. - # - # function // bracket + no space = false positive - # value < double(42) // bracket + space = true positive - matched_new_or_template = match.group(1) - - # Avoid arrays by looking for brackets that come after the closing - # parenthesis. - if Match(r'\([^()]+\)\s*\[', match.group(3)): - return - - # Other things to ignore: - # - Function pointers - # - Casts to pointer types - # - Placement new - # - Alias declarations - matched_funcptr = match.group(3) - if (matched_new_or_template is None and - not (matched_funcptr and - (Match(r'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\(', - matched_funcptr) or - matched_funcptr.startswith('(*)'))) and - not Match(r'\s*using\s+\S+\s*=\s*' + matched_type, line) and - not Search(r'new\(\S+\)\s*' + matched_type, line)): - error(filename, linenum, 'readability/casting', 4, - 'Using deprecated casting style. ' - 'Use static_cast<%s>(...) instead' % - matched_type) - - if not expecting_function: - CheckCStyleCast(filename, clean_lines, linenum, 'static_cast', - r'\((int|float|double|bool|char|u?int(16|32|64))\)', error) - - # This doesn't catch all cases. Consider (const char * const)"hello". - # - # (char *) "foo" should always be a const_cast (reinterpret_cast won't - # compile). - if CheckCStyleCast(filename, clean_lines, linenum, 'const_cast', - r'\((char\s?\*+\s?)\)\s*"', error): - pass - else: - # Check pointer casts for other than string constants - CheckCStyleCast(filename, clean_lines, linenum, 'reinterpret_cast', - r'\((\w+\s?\*+\s?)\)', error) - - # In addition, we look for people taking the address of a cast. This - # is dangerous -- casts can assign to temporaries, so the pointer doesn't - # point where you think. - # - # Some non-identifier character is required before the '&' for the - # expression to be recognized as a cast. These are casts: - # expression = &static_cast(temporary()); - # function(&(int*)(temporary())); - # - # This is not a cast: - # reference_type&(int* function_param); - match = Search( - r'(?:[^\w]&\(([^)*][^)]*)\)[\w(])|' - r'(?:[^\w]&(static|dynamic|down|reinterpret)_cast\b)', line) - if match: - # Try a better error message when the & is bound to something - # dereferenced by the casted pointer, as opposed to the casted - # pointer itself. - parenthesis_error = False - match = Match(r'^(.*&(?:static|dynamic|down|reinterpret)_cast\b)<', line) - if match: - _, y1, x1 = CloseExpression(clean_lines, linenum, len(match.group(1))) - if x1 >= 0 and clean_lines.elided[y1][x1] == '(': - _, y2, x2 = CloseExpression(clean_lines, y1, x1) - if x2 >= 0: - extended_line = clean_lines.elided[y2][x2:] - if y2 < clean_lines.NumLines() - 1: - extended_line += clean_lines.elided[y2 + 1] - if Match(r'\s*(?:->|\[)', extended_line): - parenthesis_error = True - - if parenthesis_error: - error(filename, linenum, 'readability/casting', 4, - ('Are you taking an address of something dereferenced ' - 'from a cast? Wrapping the dereferenced expression in ' - 'parentheses will make the binding more obvious')) - else: - error(filename, linenum, 'runtime/casting', 4, - ('Are you taking an address of a cast? ' - 'This is dangerous: could be a temp var. ' - 'Take the address before doing the cast, rather than after')) - - -def CheckCStyleCast(filename, clean_lines, linenum, cast_type, pattern, error): - """Checks for a C-style cast by looking for the pattern. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - cast_type: The string for the C++ cast to recommend. This is either - reinterpret_cast, static_cast, or const_cast, depending. - pattern: The regular expression used to find C-style casts. - error: The function to call with any errors found. - - Returns: - True if an error was emitted. - False otherwise. - """ - line = clean_lines.elided[linenum] - match = Search(pattern, line) - if not match: - return False - - # Exclude lines with keywords that tend to look like casts - context = line[0:match.start(1) - 1] - if Match(r'.*\b(?:sizeof|alignof|alignas|[_A-Z][_A-Z0-9]*)\s*$', context): - return False - - # Try expanding current context to see if we one level of - # parentheses inside a macro. - if linenum > 0: - for i in xrange(linenum - 1, max(0, linenum - 5), -1): - context = clean_lines.elided[i] + context - if Match(r'.*\b[_A-Z][_A-Z0-9]*\s*\((?:\([^()]*\)|[^()])*$', context): - return False - - # operator++(int) and operator--(int) - if context.endswith(' operator++') or context.endswith(' operator--'): - return False - - # A single unnamed argument for a function tends to look like old style cast. - # If we see those, don't issue warnings for deprecated casts. - remainder = line[match.end(0):] - if Match(r'^\s*(?:;|const\b|throw\b|final\b|override\b|[=>{),]|->)', - remainder): - return False - - # At this point, all that should be left is actual casts. - error(filename, linenum, 'readability/casting', 4, - 'Using C-style cast. Use %s<%s>(...) instead' % - (cast_type, match.group(1))) - - return True - - -def ExpectingFunctionArgs(clean_lines, linenum): - """Checks whether where function type arguments are expected. - - Args: - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - - Returns: - True if the line at 'linenum' is inside something that expects arguments - of function types. - """ - line = clean_lines.elided[linenum] - return (Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line) or - (linenum >= 2 and - (Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\((?:\S+,)?\s*$', - clean_lines.elided[linenum - 1]) or - Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\(\s*$', - clean_lines.elided[linenum - 2]) or - Search(r'\bstd::m?function\s*\<\s*$', - clean_lines.elided[linenum - 1])))) - - -_HEADERS_CONTAINING_TEMPLATES = ( - ('', ('deque',)), - ('', ('unary_function', 'binary_function', - 'plus', 'minus', 'multiplies', 'divides', 'modulus', - 'negate', - 'equal_to', 'not_equal_to', 'greater', 'less', - 'greater_equal', 'less_equal', - 'logical_and', 'logical_or', 'logical_not', - 'unary_negate', 'not1', 'binary_negate', 'not2', - 'bind1st', 'bind2nd', - 'pointer_to_unary_function', - 'pointer_to_binary_function', - 'ptr_fun', - 'mem_fun_t', 'mem_fun', 'mem_fun1_t', 'mem_fun1_ref_t', - 'mem_fun_ref_t', - 'const_mem_fun_t', 'const_mem_fun1_t', - 'const_mem_fun_ref_t', 'const_mem_fun1_ref_t', - 'mem_fun_ref', - )), - ('', ('numeric_limits',)), - ('', ('list',)), - ('', ('map', 'multimap',)), - ('', ('allocator', 'make_shared', 'make_unique', 'shared_ptr', - 'unique_ptr', 'weak_ptr')), - ('', ('queue', 'priority_queue',)), - ('', ('set', 'multiset',)), - ('', ('stack',)), - ('', ('char_traits', 'basic_string',)), - ('', ('tuple',)), - ('', ('unordered_map', 'unordered_multimap')), - ('', ('unordered_set', 'unordered_multiset')), - ('', ('pair',)), - ('', ('vector',)), - - # gcc extensions. - # Note: std::hash is their hash, ::hash is our hash - ('', ('hash_map', 'hash_multimap',)), - ('', ('hash_set', 'hash_multiset',)), - ('', ('slist',)), - ) - -_HEADERS_MAYBE_TEMPLATES = ( - ('', ('copy', 'max', 'min', 'min_element', 'sort', - 'transform', - )), - ('', ('forward', 'make_pair', 'move', 'swap')), - ) - -_RE_PATTERN_STRING = re.compile(r'\bstring\b') - -_re_pattern_headers_maybe_templates = [] -for _header, _templates in _HEADERS_MAYBE_TEMPLATES: - for _template in _templates: - # Match max(..., ...), max(..., ...), but not foo->max, foo.max or - # type::max(). - _re_pattern_headers_maybe_templates.append( - (re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'), - _template, - _header)) - -# Other scripts may reach in and modify this pattern. -_re_pattern_templates = [] -for _header, _templates in _HEADERS_CONTAINING_TEMPLATES: - for _template in _templates: - _re_pattern_templates.append( - (re.compile(r'(\<|\b)' + _template + r'\s*\<'), - _template + '<>', - _header)) - - -def FilesBelongToSameModule(filename_cc, filename_h): - """Check if these two filenames belong to the same module. - - The concept of a 'module' here is a as follows: - foo.h, foo-inl.h, foo.cc, foo_test.cc and foo_unittest.cc belong to the - same 'module' if they are in the same directory. - some/path/public/xyzzy and some/path/internal/xyzzy are also considered - to belong to the same module here. - - If the filename_cc contains a longer path than the filename_h, for example, - '/absolute/path/to/base/sysinfo.cc', and this file would include - 'base/sysinfo.h', this function also produces the prefix needed to open the - header. This is used by the caller of this function to more robustly open the - header file. We don't have access to the real include paths in this context, - so we need this guesswork here. - - Known bugs: tools/base/bar.cc and base/bar.h belong to the same module - according to this implementation. Because of this, this function gives - some false positives. This should be sufficiently rare in practice. - - Args: - filename_cc: is the path for the .cc file - filename_h: is the path for the header path - - Returns: - Tuple with a bool and a string: - bool: True if filename_cc and filename_h belong to the same module. - string: the additional prefix needed to open the header file. - """ - - fileinfo = FileInfo(filename_cc) - if not fileinfo.IsSource(): - return (False, '') - filename_cc = filename_cc[:-len(fileinfo.Extension())] - matched_test_suffix = Search(_TEST_FILE_SUFFIX, fileinfo.BaseName()) - if matched_test_suffix: - filename_cc = filename_cc[:-len(matched_test_suffix.group(1))] - filename_cc = filename_cc.replace('/public/', '/') - filename_cc = filename_cc.replace('/internal/', '/') - - if not filename_h.endswith('.h'): - return (False, '') - filename_h = filename_h[:-len('.h')] - if filename_h.endswith('-inl'): - filename_h = filename_h[:-len('-inl')] - filename_h = filename_h.replace('/public/', '/') - filename_h = filename_h.replace('/internal/', '/') - - files_belong_to_same_module = filename_cc.endswith(filename_h) - common_path = '' - if files_belong_to_same_module: - common_path = filename_cc[:-len(filename_h)] - return files_belong_to_same_module, common_path - - -def UpdateIncludeState(filename, include_dict, io=codecs): - """Fill up the include_dict with new includes found from the file. - - Args: - filename: the name of the header to read. - include_dict: a dictionary in which the headers are inserted. - io: The io factory to use to read the file. Provided for testability. - - Returns: - True if a header was successfully added. False otherwise. - """ - headerfile = None - try: - headerfile = io.open(filename, 'r', 'utf8', 'replace') - except IOError: - return False - linenum = 0 - for line in headerfile: - linenum += 1 - clean_line = CleanseComments(line) - match = _RE_PATTERN_INCLUDE.search(clean_line) - if match: - include = match.group(2) - include_dict.setdefault(include, linenum) - return True - - -def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error, - io=codecs): - """Reports for missing stl includes. - - This function will output warnings to make sure you are including the headers - necessary for the stl containers and functions that you use. We only give one - reason to include a header. For example, if you use both equal_to<> and - less<> in a .h file, only one (the latter in the file) of these will be - reported as a reason to include the . - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - include_state: An _IncludeState instance. - error: The function to call with any errors found. - io: The IO factory to use to read the header file. Provided for unittest - injection. - """ - required = {} # A map of header name to linenumber and the template entity. - # Example of required: { '': (1219, 'less<>') } - - for linenum in xrange(clean_lines.NumLines()): - line = clean_lines.elided[linenum] - if not line or line[0] == '#': - continue - - # String is special -- it is a non-templatized type in STL. - matched = _RE_PATTERN_STRING.search(line) - if matched: - # Don't warn about strings in non-STL namespaces: - # (We check only the first match per line; good enough.) - prefix = line[:matched.start()] - if prefix.endswith('std::') or not prefix.endswith('::'): - required[''] = (linenum, 'string') - - for pattern, template, header in _re_pattern_headers_maybe_templates: - if pattern.search(line): - required[header] = (linenum, template) - - # The following function is just a speed up, no semantics are changed. - if not '<' in line: # Reduces the cpu time usage by skipping lines. - continue - - for pattern, template, header in _re_pattern_templates: - matched = pattern.search(line) - if matched: - # Don't warn about IWYU in non-STL namespaces: - # (We check only the first match per line; good enough.) - prefix = line[:matched.start()] - if prefix.endswith('std::') or not prefix.endswith('::'): - required[header] = (linenum, template) - - # The policy is that if you #include something in foo.h you don't need to - # include it again in foo.cc. Here, we will look at possible includes. - # Let's flatten the include_state include_list and copy it into a dictionary. - include_dict = dict([item for sublist in include_state.include_list - for item in sublist]) - - # Did we find the header for this file (if any) and successfully load it? - header_found = False - - # Use the absolute path so that matching works properly. - abs_filename = FileInfo(filename).FullName() - - # For Emacs's flymake. - # If cpplint is invoked from Emacs's flymake, a temporary file is generated - # by flymake and that file name might end with '_flymake.cc'. In that case, - # restore original file name here so that the corresponding header file can be - # found. - # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h' - # instead of 'foo_flymake.h' - abs_filename = re.sub(r'_flymake\.cc$', '.cc', abs_filename) - - # include_dict is modified during iteration, so we iterate over a copy of - # the keys. - header_keys = include_dict.keys() - for header in header_keys: - (same_module, common_path) = FilesBelongToSameModule(abs_filename, header) - fullpath = common_path + header - if same_module and UpdateIncludeState(fullpath, include_dict, io): - header_found = True - - # If we can't find the header file for a .cc, assume it's because we don't - # know where to look. In that case we'll give up as we're not sure they - # didn't include it in the .h file. - # TODO(unknown): Do a better job of finding .h files so we are confident that - # not having the .h file means there isn't one. - if filename.endswith('.cc') and not header_found: - return - - # All the lines have been processed, report the errors found. - for required_header_unstripped in required: - template = required[required_header_unstripped][1] - if required_header_unstripped.strip('<>"') not in include_dict: - error(filename, required[required_header_unstripped][0], - 'build/include_what_you_use', 4, - 'Add #include ' + required_header_unstripped + ' for ' + template) - - -_RE_PATTERN_EXPLICIT_MAKEPAIR = re.compile(r'\bmake_pair\s*<') - - -def CheckMakePairUsesDeduction(filename, clean_lines, linenum, error): - """Check that make_pair's template arguments are deduced. - - G++ 4.6 in C++11 mode fails badly if make_pair's template arguments are - specified explicitly, and such use isn't intended in any case. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - line = clean_lines.elided[linenum] - match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line) - if match: - error(filename, linenum, 'build/explicit_make_pair', - 4, # 4 = high confidence - 'For C++11-compatibility, omit template arguments from make_pair' - ' OR use pair directly OR if appropriate, construct a pair directly') - - -def CheckRedundantVirtual(filename, clean_lines, linenum, error): - """Check if line contains a redundant "virtual" function-specifier. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - # Look for "virtual" on current line. - line = clean_lines.elided[linenum] - virtual = Match(r'^(.*)(\bvirtual\b)(.*)$', line) - if not virtual: return - - # Ignore "virtual" keywords that are near access-specifiers. These - # are only used in class base-specifier and do not apply to member - # functions. - if (Search(r'\b(public|protected|private)\s+$', virtual.group(1)) or - Match(r'^\s+(public|protected|private)\b', virtual.group(3))): - return - - # Ignore the "virtual" keyword from virtual base classes. Usually - # there is a column on the same line in these cases (virtual base - # classes are rare in google3 because multiple inheritance is rare). - if Match(r'^.*[^:]:[^:].*$', line): return - - # Look for the next opening parenthesis. This is the start of the - # parameter list (possibly on the next line shortly after virtual). - # TODO(unknown): doesn't work if there are virtual functions with - # decltype() or other things that use parentheses, but csearch suggests - # that this is rare. - end_col = -1 - end_line = -1 - start_col = len(virtual.group(2)) - for start_line in xrange(linenum, min(linenum + 3, clean_lines.NumLines())): - line = clean_lines.elided[start_line][start_col:] - parameter_list = Match(r'^([^(]*)\(', line) - if parameter_list: - # Match parentheses to find the end of the parameter list - (_, end_line, end_col) = CloseExpression( - clean_lines, start_line, start_col + len(parameter_list.group(1))) - break - start_col = 0 - - if end_col < 0: - return # Couldn't find end of parameter list, give up - - # Look for "override" or "final" after the parameter list - # (possibly on the next few lines). - for i in xrange(end_line, min(end_line + 3, clean_lines.NumLines())): - line = clean_lines.elided[i][end_col:] - match = Search(r'\b(override|final)\b', line) - if match: - error(filename, linenum, 'readability/inheritance', 4, - ('"virtual" is redundant since function is ' - 'already declared as "%s"' % match.group(1))) - - # Set end_col to check whole lines after we are done with the - # first line. - end_col = 0 - if Search(r'[^\w]\s*$', line): - break - - -def CheckRedundantOverrideOrFinal(filename, clean_lines, linenum, error): - """Check if line contains a redundant "override" or "final" virt-specifier. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - # Look for closing parenthesis nearby. We need one to confirm where - # the declarator ends and where the virt-specifier starts to avoid - # false positives. - line = clean_lines.elided[linenum] - declarator_end = line.rfind(')') - if declarator_end >= 0: - fragment = line[declarator_end:] - else: - if linenum > 1 and clean_lines.elided[linenum - 1].rfind(')') >= 0: - fragment = line - else: - return - - # Check that at most one of "override" or "final" is present, not both - if Search(r'\boverride\b', fragment) and Search(r'\bfinal\b', fragment): - error(filename, linenum, 'readability/inheritance', 4, - ('"override" is redundant since function is ' - 'already declared as "final"')) - - - - -# Returns true if we are at a new block, and it is directly -# inside of a namespace. -def IsBlockInNameSpace(nesting_state, is_forward_declaration): - """Checks that the new block is directly in a namespace. - - Args: - nesting_state: The _NestingState object that contains info about our state. - is_forward_declaration: If the class is a forward declared class. - Returns: - Whether or not the new block is directly in a namespace. - """ - if is_forward_declaration: - if len(nesting_state.stack) >= 1 and ( - isinstance(nesting_state.stack[-1], _NamespaceInfo)): - return True - else: - return False - - return (len(nesting_state.stack) > 1 and - nesting_state.stack[-1].check_namespace_indentation and - isinstance(nesting_state.stack[-2], _NamespaceInfo)) - - -def ShouldCheckNamespaceIndentation(nesting_state, is_namespace_indent_item, - raw_lines_no_comments, linenum): - """This method determines if we should apply our namespace indentation check. - - Args: - nesting_state: The current nesting state. - is_namespace_indent_item: If we just put a new class on the stack, True. - If the top of the stack is not a class, or we did not recently - add the class, False. - raw_lines_no_comments: The lines without the comments. - linenum: The current line number we are processing. - - Returns: - True if we should apply our namespace indentation check. Currently, it - only works for classes and namespaces inside of a namespace. - """ - - is_forward_declaration = IsForwardClassDeclaration(raw_lines_no_comments, - linenum) - - if not (is_namespace_indent_item or is_forward_declaration): - return False - - # If we are in a macro, we do not want to check the namespace indentation. - if IsMacroDefinition(raw_lines_no_comments, linenum): - return False - - return IsBlockInNameSpace(nesting_state, is_forward_declaration) - - -# Call this method if the line is directly inside of a namespace. -# If the line above is blank (excluding comments) or the start of -# an inner namespace, it cannot be indented. -def CheckItemIndentationInNamespace(filename, raw_lines_no_comments, linenum, - error): - line = raw_lines_no_comments[linenum] - if Match(r'^\s+', line): - error(filename, linenum, 'runtime/indentation_namespace', 4, - 'Do not indent within a namespace') - - -def ProcessLine(filename, file_extension, clean_lines, line, - include_state, function_state, nesting_state, error, - extra_check_functions=[]): - """Processes a single line in the file. - - Args: - filename: Filename of the file that is being processed. - file_extension: The extension (dot not included) of the file. - clean_lines: An array of strings, each representing a line of the file, - with comments stripped. - line: Number of line being processed. - include_state: An _IncludeState instance in which the headers are inserted. - function_state: A _FunctionState instance which counts function lines, etc. - nesting_state: A NestingState instance which maintains information about - the current stack of nested blocks being parsed. - error: A callable to which errors are reported, which takes 4 arguments: - filename, line number, error level, and message - extra_check_functions: An array of additional check functions that will be - run on each source line. Each function takes 4 - arguments: filename, clean_lines, line, error - """ - raw_lines = clean_lines.raw_lines - ParseNolintSuppressions(filename, raw_lines[line], line, error) - nesting_state.Update(filename, clean_lines, line, error) - CheckForNamespaceIndentation(filename, nesting_state, clean_lines, line, - error) - if nesting_state.InAsmBlock(): return - CheckForFunctionLengths(filename, clean_lines, line, function_state, error) - CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error) - CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error) - CheckLanguage(filename, clean_lines, line, file_extension, include_state, - nesting_state, error) - CheckForNonConstReference(filename, clean_lines, line, nesting_state, error) - CheckForNonStandardConstructs(filename, clean_lines, line, - nesting_state, error) - CheckVlogArguments(filename, clean_lines, line, error) - CheckPosixThreading(filename, clean_lines, line, error) - CheckInvalidIncrement(filename, clean_lines, line, error) - CheckMakePairUsesDeduction(filename, clean_lines, line, error) - CheckRedundantVirtual(filename, clean_lines, line, error) - CheckRedundantOverrideOrFinal(filename, clean_lines, line, error) - for check_fn in extra_check_functions: - check_fn(filename, clean_lines, line, error) - -def FlagCxx11Features(filename, clean_lines, linenum, error): - """Flag those c++11 features that we only allow in certain places. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - line = clean_lines.elided[linenum] - - include = Match(r'\s*#\s*include\s+[<"]([^<"]+)[">]', line) - - # Flag unapproved C++ TR1 headers. - if include and include.group(1).startswith('tr1/'): - error(filename, linenum, 'build/c++tr1', 5, - ('C++ TR1 headers such as <%s> are unapproved.') % include.group(1)) - - # Flag unapproved C++11 headers. - if include and include.group(1) in ('cfenv', - 'condition_variable', - 'fenv.h', - 'future', - 'mutex', - 'thread', - 'chrono', - 'ratio', - 'regex', - 'system_error', - ): - error(filename, linenum, 'build/c++11', 5, - ('<%s> is an unapproved C++11 header.') % include.group(1)) - - # The only place where we need to worry about C++11 keywords and library - # features in preprocessor directives is in macro definitions. - if Match(r'\s*#', line) and not Match(r'\s*#\s*define\b', line): return - - # These are classes and free functions. The classes are always - # mentioned as std::*, but we only catch the free functions if - # they're not found by ADL. They're alphabetical by header. - for top_name in ( - # type_traits - 'alignment_of', - 'aligned_union', - ): - if Search(r'\bstd::%s\b' % top_name, line): - error(filename, linenum, 'build/c++11', 5, - ('std::%s is an unapproved C++11 class or function. Send c-style ' - 'an example of where it would make your code more readable, and ' - 'they may let you use it.') % top_name) - - -def FlagCxx14Features(filename, clean_lines, linenum, error): - """Flag those C++14 features that we restrict. - - Args: - filename: The name of the current file. - clean_lines: A CleansedLines instance containing the file. - linenum: The number of the line to check. - error: The function to call with any errors found. - """ - line = clean_lines.elided[linenum] - - include = Match(r'\s*#\s*include\s+[<"]([^<"]+)[">]', line) - - # Flag unapproved C++14 headers. - if include and include.group(1) in ('scoped_allocator', 'shared_mutex'): - error(filename, linenum, 'build/c++14', 5, - ('<%s> is an unapproved C++14 header.') % include.group(1)) - - -def ProcessFileData(filename, file_extension, lines, error, - extra_check_functions=[]): - """Performs lint checks and reports any errors to the given error function. - - Args: - filename: Filename of the file that is being processed. - file_extension: The extension (dot not included) of the file. - lines: An array of strings, each representing a line of the file, with the - last element being empty if the file is terminated with a newline. - error: A callable to which errors are reported, which takes 4 arguments: - filename, line number, error level, and message - extra_check_functions: An array of additional check functions that will be - run on each source line. Each function takes 4 - arguments: filename, clean_lines, line, error - """ - lines = (['// marker so line numbers and indices both start at 1'] + lines + - ['// marker so line numbers end in a known way']) - - include_state = _IncludeState() - function_state = _FunctionState() - nesting_state = NestingState() - - ResetNolintSuppressions() - - CheckForCopyright(filename, lines, error) - ProcessGlobalSuppresions(lines) - RemoveMultiLineComments(filename, lines, error) - clean_lines = CleansedLines(lines) - - if IsHeaderExtension(file_extension): - CheckForHeaderGuard(filename, clean_lines, error) - - for line in xrange(clean_lines.NumLines()): - ProcessLine(filename, file_extension, clean_lines, line, - include_state, function_state, nesting_state, error, - extra_check_functions) - FlagCxx11Features(filename, clean_lines, line, error) - nesting_state.CheckCompletedBlocks(filename, error) - - CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error) - - # Check that the .cc file has included its header if it exists. - if _IsSourceExtension(file_extension): - CheckHeaderFileIncluded(filename, include_state, error) - - # We check here rather than inside ProcessLine so that we see raw - # lines rather than "cleaned" lines. - CheckForBadCharacters(filename, lines, error) - - CheckForNewlineAtEOF(filename, lines, error) - -def ProcessConfigOverrides(filename): - """ Loads the configuration files and processes the config overrides. - - Args: - filename: The name of the file being processed by the linter. - - Returns: - False if the current |filename| should not be processed further. - """ - - abs_filename = os.path.abspath(filename) - cfg_filters = [] - keep_looking = True - while keep_looking: - abs_path, base_name = os.path.split(abs_filename) - if not base_name: - break # Reached the root directory. - - cfg_file = os.path.join(abs_path, "CPPLINT.cfg") - abs_filename = abs_path - if not os.path.isfile(cfg_file): - continue - - try: - with open(cfg_file) as file_handle: - for line in file_handle: - line, _, _ = line.partition('#') # Remove comments. - if not line.strip(): - continue - - name, _, val = line.partition('=') - name = name.strip() - val = val.strip() - if name == 'set noparent': - keep_looking = False - elif name == 'filter': - cfg_filters.append(val) - elif name == 'exclude_files': - # When matching exclude_files pattern, use the base_name of - # the current file name or the directory name we are processing. - # For example, if we are checking for lint errors in /foo/bar/baz.cc - # and we found the .cfg file at /foo/CPPLINT.cfg, then the config - # file's "exclude_files" filter is meant to be checked against "bar" - # and not "baz" nor "bar/baz.cc". - if base_name: - pattern = re.compile(val) - if pattern.match(base_name): - if _cpplint_state.quiet: - # Suppress "Ignoring file" warning when using --quiet. - return False - sys.stderr.write('Ignoring "%s": file excluded by "%s". ' - 'File path component "%s" matches ' - 'pattern "%s"\n' % - (filename, cfg_file, base_name, val)) - return False - elif name == 'linelength': - global _line_length - try: - _line_length = int(val) - except ValueError: - sys.stderr.write('Line length must be numeric.') - elif name == 'root': - global _root - # root directories are specified relative to CPPLINT.cfg dir. - _root = os.path.join(os.path.dirname(cfg_file), val) - elif name == 'headers': - ProcessHppHeadersOption(val) - else: - sys.stderr.write( - 'Invalid configuration option (%s) in file %s\n' % - (name, cfg_file)) - - except IOError: - sys.stderr.write( - "Skipping config file '%s': Can't open for reading\n" % cfg_file) - keep_looking = False - - # Apply all the accumulated filters in reverse order (top-level directory - # config options having the least priority). - for filter in reversed(cfg_filters): - _AddFilters(filter) - - return True - - -def ProcessFile(filename, vlevel, extra_check_functions=[]): - """Does google-lint on a single file. - - Args: - filename: The name of the file to parse. - - vlevel: The level of errors to report. Every error of confidence - >= verbose_level will be reported. 0 is a good default. - - extra_check_functions: An array of additional check functions that will be - run on each source line. Each function takes 4 - arguments: filename, clean_lines, line, error - """ - - _SetVerboseLevel(vlevel) - _BackupFilters() - old_errors = _cpplint_state.error_count - - if not ProcessConfigOverrides(filename): - _RestoreFilters() - return - - lf_lines = [] - crlf_lines = [] - try: - # Support the UNIX convention of using "-" for stdin. Note that - # we are not opening the file with universal newline support - # (which codecs doesn't support anyway), so the resulting lines do - # contain trailing '\r' characters if we are reading a file that - # has CRLF endings. - # If after the split a trailing '\r' is present, it is removed - # below. - if filename == '-': - lines = codecs.StreamReaderWriter(sys.stdin, - codecs.getreader('utf8'), - codecs.getwriter('utf8'), - 'replace').read().split('\n') - else: - lines = codecs.open(filename, 'r', 'utf8', 'replace').read().split('\n') - - # Remove trailing '\r'. - # The -1 accounts for the extra trailing blank line we get from split() - for linenum in range(len(lines) - 1): - if lines[linenum].endswith('\r'): - lines[linenum] = lines[linenum].rstrip('\r') - crlf_lines.append(linenum + 1) - else: - lf_lines.append(linenum + 1) - - except IOError: - sys.stderr.write( - "Skipping input '%s': Can't open for reading\n" % filename) - _RestoreFilters() - return - - # Note, if no dot is found, this will give the entire filename as the ext. - file_extension = filename[filename.rfind('.') + 1:] - - # When reading from stdin, the extension is unknown, so no cpplint tests - # should rely on the extension. - if filename != '-' and file_extension not in _valid_extensions: - sys.stderr.write('Ignoring %s; not a valid file name ' - '(%s)\n' % (filename, ', '.join(_valid_extensions))) - else: - ProcessFileData(filename, file_extension, lines, Error, - extra_check_functions) - - # If end-of-line sequences are a mix of LF and CR-LF, issue - # warnings on the lines with CR. - # - # Don't issue any warnings if all lines are uniformly LF or CR-LF, - # since critique can handle these just fine, and the style guide - # doesn't dictate a particular end of line sequence. - # - # We can't depend on os.linesep to determine what the desired - # end-of-line sequence should be, since that will return the - # server-side end-of-line sequence. - if lf_lines and crlf_lines: - # Warn on every line with CR. An alternative approach might be to - # check whether the file is mostly CRLF or just LF, and warn on the - # minority, we bias toward LF here since most tools prefer LF. - for linenum in crlf_lines: - Error(filename, linenum, 'whitespace/newline', 1, - 'Unexpected \\r (^M) found; better to use only \\n') - - # Suppress printing anything if --quiet was passed unless the error - # count has increased after processing this file. - if not _cpplint_state.quiet or old_errors != _cpplint_state.error_count: - sys.stdout.write('Done processing %s\n' % filename) - _RestoreFilters() - - -def PrintUsage(message): - """Prints a brief usage string and exits, optionally with an error message. - - Args: - message: The optional error message. - """ - sys.stderr.write(_USAGE) - if message: - sys.exit('\nFATAL ERROR: ' + message) - else: - sys.exit(1) - - -def PrintCategories(): - """Prints a list of all the error-categories used by error messages. - - These are the categories used to filter messages via --filter. - """ - sys.stderr.write(''.join(' %s\n' % cat for cat in _ERROR_CATEGORIES)) - sys.exit(0) - - -def ParseArguments(args): - """Parses the command line arguments. - - This may set the output format and verbosity level as side-effects. - - Args: - args: The command line arguments: - - Returns: - The list of filenames to lint. - """ - try: - (opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=', - 'counting=', - 'filter=', - 'root=', - 'linelength=', - 'extensions=', - 'headers=', - 'quiet']) - except getopt.GetoptError: - PrintUsage('Invalid arguments.') - - verbosity = _VerboseLevel() - output_format = _OutputFormat() - filters = '' - quiet = _Quiet() - counting_style = '' - - for (opt, val) in opts: - if opt == '--help': - PrintUsage(None) - elif opt == '--output': - if val not in ('emacs', 'vs7', 'eclipse'): - PrintUsage('The only allowed output formats are emacs, vs7 and eclipse.') - output_format = val - elif opt == '--quiet': - quiet = True - elif opt == '--verbose': - verbosity = int(val) - elif opt == '--filter': - filters = val - if not filters: - PrintCategories() - elif opt == '--counting': - if val not in ('total', 'toplevel', 'detailed'): - PrintUsage('Valid counting options are total, toplevel, and detailed') - counting_style = val - elif opt == '--root': - global _root - _root = val - elif opt == '--linelength': - global _line_length - try: - _line_length = int(val) - except ValueError: - PrintUsage('Line length must be digits.') - elif opt == '--extensions': - global _valid_extensions - try: - _valid_extensions = set(val.split(',')) - except ValueError: - PrintUsage('Extensions must be comma separated list.') - elif opt == '--headers': - ProcessHppHeadersOption(val) - - if not filenames: - PrintUsage('No files were specified.') - - _SetOutputFormat(output_format) - _SetQuiet(quiet) - _SetVerboseLevel(verbosity) - _SetFilters(filters) - _SetCountingStyle(counting_style) - - return filenames - - -def main(): - filenames = ParseArguments(sys.argv[1:]) - - # Change stderr to write with replacement characters so we don't die - # if we try to print something containing non-ASCII characters. - sys.stderr = codecs.StreamReaderWriter(sys.stderr, - codecs.getreader('utf8'), - codecs.getwriter('utf8'), - 'replace') - - _cpplint_state.ResetErrorCounts() - for filename in filenames: - ProcessFile(filename, _cpplint_state.verbose_level) - # If --quiet is passed, suppress printing error count unless there are errors. - if not _cpplint_state.quiet or _cpplint_state.error_count > 0: - _cpplint_state.PrintErrorCounts() - - sys.exit(_cpplint_state.error_count > 0) - - -if __name__ == '__main__': - main() diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/diff.py b/presentation/src/main/cpp/third_party/libvpx/tools/diff.py deleted file mode 100644 index 860a6b05..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/diff.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env python3 -## Copyright (c) 2012 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -"""Classes for representing diff pieces.""" - -__author__ = "jkoleszar@google.com" - -import re - - -class DiffLines(object): - """A container for one half of a diff.""" - - def __init__(self, filename, offset, length): - self.filename = filename - self.offset = offset - self.length = length - self.lines = [] - self.delta_line_nums = [] - - def Append(self, line): - l = len(self.lines) - if line[0] != " ": - self.delta_line_nums.append(self.offset + l) - self.lines.append(line[1:]) - assert l+1 <= self.length - - def Complete(self): - return len(self.lines) == self.length - - def __contains__(self, item): - return item >= self.offset and item <= self.offset + self.length - 1 - - -class DiffHunk(object): - """A container for one diff hunk, consisting of two DiffLines.""" - - def __init__(self, header, file_a, file_b, start_a, len_a, start_b, len_b): - self.header = header - self.left = DiffLines(file_a, start_a, len_a) - self.right = DiffLines(file_b, start_b, len_b) - self.lines = [] - - def Append(self, line): - """Adds a line to the DiffHunk and its DiffLines children.""" - if line[0] == "-": - self.left.Append(line) - elif line[0] == "+": - self.right.Append(line) - elif line[0] == " ": - self.left.Append(line) - self.right.Append(line) - elif line[0] == "\\": - # Ignore newline messages from git diff. - pass - else: - assert False, ("Unrecognized character at start of diff line " - "%r" % line[0]) - self.lines.append(line) - - def Complete(self): - return self.left.Complete() and self.right.Complete() - - def __repr__(self): - return "DiffHunk(%s, %s, len %d)" % ( - self.left.filename, self.right.filename, - max(self.left.length, self.right.length)) - - -def ParseDiffHunks(stream): - """Walk a file-like object, yielding DiffHunks as they're parsed.""" - - file_regex = re.compile(r"(\+\+\+|---) (\S+)") - range_regex = re.compile(r"@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))?") - hunk = None - while True: - line = stream.readline() - if not line: - break - - if hunk is None: - # Parse file names - diff_file = file_regex.match(line) - if diff_file: - if line.startswith("---"): - a_line = line - a = diff_file.group(2) - continue - if line.startswith("+++"): - b_line = line - b = diff_file.group(2) - continue - - # Parse offset/lengths - diffrange = range_regex.match(line) - if diffrange: - if diffrange.group(2): - start_a = int(diffrange.group(1)) - len_a = int(diffrange.group(3)) - else: - start_a = 1 - len_a = int(diffrange.group(1)) - - if diffrange.group(5): - start_b = int(diffrange.group(4)) - len_b = int(diffrange.group(6)) - else: - start_b = 1 - len_b = int(diffrange.group(4)) - - header = [a_line, b_line, line] - hunk = DiffHunk(header, a, b, start_a, len_a, start_b, len_b) - else: - # Add the current line to the hunk - hunk.Append(line) - - # See if the whole hunk has been parsed. If so, yield it and prepare - # for the next hunk. - if hunk.Complete(): - yield hunk - hunk = None - - # Partial hunks are a parse error - assert hunk is None diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/gen_authors.sh b/presentation/src/main/cpp/third_party/libvpx/tools/gen_authors.sh deleted file mode 100644 index f163f663..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/gen_authors.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -# Add organization names manually. - -cat <" | sort | uniq | grep -v corp.google \ - | grep -v noreply) -Google Inc. -The Mozilla Foundation -The Xiph.Org Foundation -EOF diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/intersect-diffs.py b/presentation/src/main/cpp/third_party/libvpx/tools/intersect-diffs.py deleted file mode 100644 index 590e687b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/intersect-diffs.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python3 -## Copyright (c) 2012 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -"""Calculates the "intersection" of two unified diffs. - -Given two diffs, A and B, it finds all hunks in B that had non-context lines -in A and prints them to stdout. This is useful to determine the hunks in B that -are relevant to A. The resulting file can be applied with patch(1) on top of A. -""" - -__author__ = "jkoleszar@google.com" - -import sys - -import diff - - -def FormatDiffHunks(hunks): - """Re-serialize a list of DiffHunks.""" - r = [] - last_header = None - for hunk in hunks: - this_header = hunk.header[0:2] - if last_header != this_header: - r.extend(hunk.header) - last_header = this_header - else: - r.extend(hunk.header[2]) - r.extend(hunk.lines) - r.append("\n") - return "".join(r) - - -def ZipHunks(rhs_hunks, lhs_hunks): - """Join two hunk lists on filename.""" - for rhs_hunk in rhs_hunks: - rhs_file = rhs_hunk.right.filename.split("/")[1:] - - for lhs_hunk in lhs_hunks: - lhs_file = lhs_hunk.left.filename.split("/")[1:] - if lhs_file != rhs_file: - continue - yield (rhs_hunk, lhs_hunk) - - -def main(): - old_hunks = [x for x in diff.ParseDiffHunks(open(sys.argv[1], "r"))] - new_hunks = [x for x in diff.ParseDiffHunks(open(sys.argv[2], "r"))] - out_hunks = [] - - # Join the right hand side of the older diff with the left hand side of the - # newer diff. - for old_hunk, new_hunk in ZipHunks(old_hunks, new_hunks): - if new_hunk in out_hunks: - continue - old_lines = old_hunk.right - new_lines = new_hunk.left - - # Determine if this hunk overlaps any non-context line from the other - for i in old_lines.delta_line_nums: - if i in new_lines: - out_hunks.append(new_hunk) - break - - if out_hunks: - print(FormatDiffHunks(out_hunks)) - sys.exit(1) - -if __name__ == "__main__": - main() diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/lint-hunks.py b/presentation/src/main/cpp/third_party/libvpx/tools/lint-hunks.py deleted file mode 100644 index 0a94afeb..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/lint-hunks.py +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env python3 -## Copyright (c) 2012 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -"""Performs style checking on each diff hunk.""" -import getopt -import os -import io -import subprocess -import sys - -import diff - - -SHORT_OPTIONS = "h" -LONG_OPTIONS = ["help"] - -TOPLEVEL_CMD = ["git", "rev-parse", "--show-toplevel"] -DIFF_CMD = ["git", "diff"] -DIFF_INDEX_CMD = ["git", "diff-index", "-u", "HEAD", "--"] -SHOW_CMD = ["git", "show"] -CPPLINT_FILTERS = ["-readability/casting"] - - -class Usage(Exception): - pass - - -class SubprocessException(Exception): - def __init__(self, args): - msg = "Failed to execute '%s'"%(" ".join(args)) - super(SubprocessException, self).__init__(msg) - - -class Subprocess(subprocess.Popen): - """Adds the notion of an expected returncode to Popen.""" - - def __init__(self, args, expected_returncode=0, **kwargs): - self._args = args - self._expected_returncode = expected_returncode - super(Subprocess, self).__init__(args, **kwargs) - - def communicate(self, *args, **kwargs): - result = super(Subprocess, self).communicate(*args, **kwargs) - if self._expected_returncode is not None: - try: - ok = self.returncode in self._expected_returncode - except TypeError: - ok = self.returncode == self._expected_returncode - if not ok: - raise SubprocessException(self._args) - return result - - -def main(argv=None): - if argv is None: - argv = sys.argv - try: - try: - opts, args = getopt.getopt(argv[1:], SHORT_OPTIONS, LONG_OPTIONS) - except getopt.error as msg: - raise Usage(msg) - - # process options - for o, _ in opts: - if o in ("-h", "--help"): - print(__doc__) - sys.exit(0) - - if args and len(args) > 1: - print(__doc__) - sys.exit(0) - - # Find the fully qualified path to the root of the tree - tl = Subprocess(TOPLEVEL_CMD, stdout=subprocess.PIPE, text=True) - tl = tl.communicate()[0].strip() - - # See if we're working on the index or not. - if args: - diff_cmd = DIFF_CMD + [args[0] + "^!"] - else: - diff_cmd = DIFF_INDEX_CMD - - # Build the command line to execute cpplint - cpplint_cmd = [os.path.join(tl, "tools", "cpplint.py"), - "--filter=" + ",".join(CPPLINT_FILTERS), - "-"] - - # Get a list of all affected lines - file_affected_line_map = {} - p = Subprocess(diff_cmd, stdout=subprocess.PIPE, text=True) - stdout = p.communicate()[0] - for hunk in diff.ParseDiffHunks(io.StringIO(stdout)): - filename = hunk.right.filename[2:] - if filename not in file_affected_line_map: - file_affected_line_map[filename] = set() - file_affected_line_map[filename].update(hunk.right.delta_line_nums) - - # Run each affected file through cpplint - lint_failed = False - for filename, affected_lines in file_affected_line_map.items(): - if filename.split(".")[-1] not in ("c", "h", "cc"): - continue - if filename.startswith("third_party"): - continue - - if args: - # File contents come from git - show_cmd = SHOW_CMD + [args[0] + ":" + filename] - show = Subprocess(show_cmd, stdout=subprocess.PIPE, text=True) - lint = Subprocess(cpplint_cmd, expected_returncode=(0, 1), - stdin=show.stdout, stderr=subprocess.PIPE, - text=True) - lint_out = lint.communicate()[1] - else: - # File contents come from the working tree - lint = Subprocess(cpplint_cmd, expected_returncode=(0, 1), - stdin=subprocess.PIPE, stderr=subprocess.PIPE, - text=True) - stdin = open(os.path.join(tl, filename)).read() - lint_out = lint.communicate(stdin)[1] - - for line in lint_out.split("\n"): - fields = line.split(":") - if fields[0] != "-": - continue - warning_line_num = int(fields[1]) - if warning_line_num in affected_lines: - print("%s:%d:%s"%(filename, warning_line_num, - ":".join(fields[2:]))) - lint_failed = True - - # Set exit code if any relevant lint errors seen - if lint_failed: - return 1 - - except Usage as err: - print(err, file=sys.stderr) - print("for help use --help", file=sys.stderr) - return 2 - -if __name__ == "__main__": - sys.exit(main()) diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/non_greedy_mv/non_greedy_mv.py b/presentation/src/main/cpp/third_party/libvpx/tools/non_greedy_mv/non_greedy_mv.py deleted file mode 100644 index a46b7e76..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/non_greedy_mv/non_greedy_mv.py +++ /dev/null @@ -1,195 +0,0 @@ -## Copyright (c) 2020 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -import sys -import matplotlib.pyplot as plt -from matplotlib.collections import LineCollection -from matplotlib import colors as mcolors -import numpy as np -import math - - -def draw_mv_ls(axis, mv_ls, mode=0): - colors = np.array([(1., 0., 0., 1.)]) - segs = np.array([ - np.array([[ptr[0], ptr[1]], [ptr[0] + ptr[2], ptr[1] + ptr[3]]]) - for ptr in mv_ls - ]) - line_segments = LineCollection( - segs, linewidths=(1.,), colors=colors, linestyle='solid') - axis.add_collection(line_segments) - if mode == 0: - axis.scatter(mv_ls[:, 0], mv_ls[:, 1], s=2, c='b') - else: - axis.scatter( - mv_ls[:, 0] + mv_ls[:, 2], mv_ls[:, 1] + mv_ls[:, 3], s=2, c='b') - - -def draw_pred_block_ls(axis, mv_ls, bs, mode=0): - colors = np.array([(0., 0., 0., 1.)]) - segs = [] - for ptr in mv_ls: - if mode == 0: - x = ptr[0] - y = ptr[1] - else: - x = ptr[0] + ptr[2] - y = ptr[1] + ptr[3] - x_ls = [x, x + bs, x + bs, x, x] - y_ls = [y, y, y + bs, y + bs, y] - - segs.append(np.column_stack([x_ls, y_ls])) - line_segments = LineCollection( - segs, linewidths=(.5,), colors=colors, linestyle='solid') - axis.add_collection(line_segments) - - -def read_frame(fp, no_swap=0): - plane = [None, None, None] - for i in range(3): - line = fp.readline() - word_ls = line.split() - word_ls = [int(item) for item in word_ls] - rows = word_ls[0] - cols = word_ls[1] - - line = fp.readline() - word_ls = line.split() - word_ls = [int(item) for item in word_ls] - - plane[i] = np.array(word_ls).reshape(rows, cols) - if i > 0: - plane[i] = plane[i].repeat(2, axis=0).repeat(2, axis=1) - plane = np.array(plane) - if no_swap == 0: - plane = np.swapaxes(np.swapaxes(plane, 0, 1), 1, 2) - return plane - - -def yuv_to_rgb(yuv): - #mat = np.array([ - # [1.164, 0 , 1.596 ], - # [1.164, -0.391, -0.813], - # [1.164, 2.018 , 0 ] ] - # ) - #c = np.array([[ -16 , -16 , -16 ], - # [ 0 , -128, -128 ], - # [ -128, -128, 0 ]]) - - mat = np.array([[1, 0, 1.4075], [1, -0.3445, -0.7169], [1, 1.7790, 0]]) - c = np.array([[0, 0, 0], [0, -128, -128], [-128, -128, 0]]) - mat_c = np.dot(mat, c) - v = np.array([mat_c[0, 0], mat_c[1, 1], mat_c[2, 2]]) - mat = mat.transpose() - rgb = np.dot(yuv, mat) + v - rgb = rgb.astype(int) - rgb = rgb.clip(0, 255) - return rgb / 255. - - -def read_feature_score(fp, mv_rows, mv_cols): - line = fp.readline() - word_ls = line.split() - feature_score = np.array([math.log(float(v) + 1, 2) for v in word_ls]) - feature_score = feature_score.reshape(mv_rows, mv_cols) - return feature_score - -def read_mv_mode_arr(fp, mv_rows, mv_cols): - line = fp.readline() - word_ls = line.split() - mv_mode_arr = np.array([int(v) for v in word_ls]) - mv_mode_arr = mv_mode_arr.reshape(mv_rows, mv_cols) - return mv_mode_arr - - -def read_frame_dpl_stats(fp): - line = fp.readline() - word_ls = line.split() - frame_idx = int(word_ls[1]) - mi_rows = int(word_ls[3]) - mi_cols = int(word_ls[5]) - bs = int(word_ls[7]) - ref_frame_idx = int(word_ls[9]) - rf_idx = int(word_ls[11]) - gf_frame_offset = int(word_ls[13]) - ref_gf_frame_offset = int(word_ls[15]) - mi_size = bs / 8 - mv_ls = [] - mv_rows = int((math.ceil(mi_rows * 1. / mi_size))) - mv_cols = int((math.ceil(mi_cols * 1. / mi_size))) - for i in range(mv_rows * mv_cols): - line = fp.readline() - word_ls = line.split() - row = int(word_ls[0]) * 8. - col = int(word_ls[1]) * 8. - mv_row = int(word_ls[2]) / 8. - mv_col = int(word_ls[3]) / 8. - mv_ls.append([col, row, mv_col, mv_row]) - mv_ls = np.array(mv_ls) - feature_score = read_feature_score(fp, mv_rows, mv_cols) - mv_mode_arr = read_mv_mode_arr(fp, mv_rows, mv_cols) - img = yuv_to_rgb(read_frame(fp)) - ref = yuv_to_rgb(read_frame(fp)) - return rf_idx, frame_idx, ref_frame_idx, gf_frame_offset, ref_gf_frame_offset, mv_ls, img, ref, bs, feature_score, mv_mode_arr - - -def read_dpl_stats_file(filename, frame_num=0): - fp = open(filename) - line = fp.readline() - width = 0 - height = 0 - data_ls = [] - while (line): - if line[0] == '=': - data_ls.append(read_frame_dpl_stats(fp)) - line = fp.readline() - if frame_num > 0 and len(data_ls) == frame_num: - break - return data_ls - - -if __name__ == '__main__': - filename = sys.argv[1] - data_ls = read_dpl_stats_file(filename, frame_num=5) - for rf_idx, frame_idx, ref_frame_idx, gf_frame_offset, ref_gf_frame_offset, mv_ls, img, ref, bs, feature_score, mv_mode_arr in data_ls: - fig, axes = plt.subplots(2, 2) - - axes[0][0].imshow(img) - draw_mv_ls(axes[0][0], mv_ls) - draw_pred_block_ls(axes[0][0], mv_ls, bs, mode=0) - #axes[0].grid(color='k', linestyle='-') - axes[0][0].set_ylim(img.shape[0], 0) - axes[0][0].set_xlim(0, img.shape[1]) - - if ref is not None: - axes[0][1].imshow(ref) - draw_mv_ls(axes[0][1], mv_ls, mode=1) - draw_pred_block_ls(axes[0][1], mv_ls, bs, mode=1) - #axes[1].grid(color='k', linestyle='-') - axes[0][1].set_ylim(ref.shape[0], 0) - axes[0][1].set_xlim(0, ref.shape[1]) - - axes[1][0].imshow(feature_score) - #feature_score_arr = feature_score.flatten() - #feature_score_max = feature_score_arr.max() - #feature_score_min = feature_score_arr.min() - #step = (feature_score_max - feature_score_min) / 20. - #feature_score_bins = np.arange(feature_score_min, feature_score_max, step) - #axes[1][1].hist(feature_score_arr, bins=feature_score_bins) - im = axes[1][1].imshow(mv_mode_arr) - #axes[1][1].figure.colorbar(im, ax=axes[1][1]) - - print rf_idx, frame_idx, ref_frame_idx, gf_frame_offset, ref_gf_frame_offset, len(mv_ls) - - flatten_mv_mode = mv_mode_arr.flatten() - zero_mv_count = sum(flatten_mv_mode == 0); - new_mv_count = sum(flatten_mv_mode == 1); - ref_mv_count = sum(flatten_mv_mode == 2) + sum(flatten_mv_mode == 3); - print zero_mv_count, new_mv_count, ref_mv_count - plt.show() diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/set_analyzer_env.sh b/presentation/src/main/cpp/third_party/libvpx/tools/set_analyzer_env.sh deleted file mode 100644 index 4d659dba..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/set_analyzer_env.sh +++ /dev/null @@ -1,129 +0,0 @@ -## Copyright (c) 2018 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -## Sourcing this file sets environment variables to simplify setting up -## sanitizer builds and testing. - -sanitizer="${1}" - -case "${sanitizer}" in - address) ;; - cfi) ;; - integer) ;; - memory) ;; - thread) ;; - undefined) ;; - clear) - echo "Clearing environment:" - set -x - unset CC CXX LD AR - unset CFLAGS CXXFLAGS LDFLAGS - unset ASAN_OPTIONS MSAN_OPTIONS TSAN_OPTIONS UBSAN_OPTIONS - set +x - return - ;; - *) - echo "Usage: source set_analyzer_env.sh [|clear]" - echo " Supported sanitizers:" - echo " address cfi integer memory thread undefined" - return 1 - ;; -esac - -if [ ! $(which clang) ]; then - # TODO(johannkoenig): Support gcc analyzers. - echo "ERROR: 'clang' must be in your PATH" - return 1 -fi - -# Warnings. -if [ "${sanitizer}" = "undefined" -o "${sanitizer}" = "integer" ]; then - echo "WARNING: When building the ${sanitizer} sanitizer for 32 bit targets" - echo "you must run:" - echo "export LDFLAGS=\"\${LDFLAGS} --rtlib=compiler-rt -lgcc_s\"" - echo "See http://llvm.org/bugs/show_bug.cgi?id=17693 for details." -fi - -if [ "${sanitizer}" = "undefined" ]; then - major_version=$(clang --version | head -n 1 \ - | grep -o -E "[[:digit:]]\.[[:digit:]]\.[[:digit:]]" | cut -f1 -d.) - if [ ${major_version} -eq 5 ]; then - echo "WARNING: clang v5 has a problem with vp9 x86_64 high bit depth" - echo "configurations. It can take ~40 minutes to compile" - echo "vpx_dsp/x86/fwd_txfm_sse2.c" - echo "clang v4 did not have this issue." - fi -fi - -echo "It is recommended to configure with '--enable-debug' to improve stack" -echo "traces. On mac builds, run 'dysmutil' on the output binaries (vpxenc," -echo "test_libvpx, etc) to link the stack traces to source code lines." - -# Build configuration. -cflags="-fsanitize=${sanitizer}" -ldflags="-fsanitize=${sanitizer}" - -# Useful backtraces. -cflags="${cflags} -fno-omit-frame-pointer" -# Exact backtraces. -cflags="${cflags} -fno-optimize-sibling-calls" - -if [ "${sanitizer}" = "cfi" ]; then - # https://clang.llvm.org/docs/ControlFlowIntegrity.html - cflags="${cflags} -fno-sanitize-trap=cfi -flto -fvisibility=hidden" - ldflags="${ldflags} -fno-sanitize-trap=cfi -flto -fuse-ld=gold" - export AR="llvm-ar" -fi - -set -x -export CC="clang" -export CXX="clang++" -export LD="clang++" - -export CFLAGS="${cflags}" -export CXXFLAGS="${cflags}" -export LDFLAGS="${ldflags}" -set +x - -# Execution configuration. -sanitizer_options="" -sanitizer_options="${sanitizer_options}:handle_segv=1" -sanitizer_options="${sanitizer_options}:handle_abort=1" -sanitizer_options="${sanitizer_options}:handle_sigfpe=1" -sanitizer_options="${sanitizer_options}:fast_unwind_on_fatal=1" -sanitizer_options="${sanitizer_options}:allocator_may_return_null=1" - -case "${sanitizer}" in - address) - sanitizer_options="${sanitizer_options}:detect_stack_use_after_return=1" - sanitizer_options="${sanitizer_options}:max_uar_stack_size_log=17" - set -x - export ASAN_OPTIONS="${sanitizer_options}" - set +x - ;; - cfi) - # No environment settings - ;; - memory) - set -x - export MSAN_OPTIONS="${sanitizer_options}" - set +x - ;; - thread) - # The thread sanitizer uses an entirely independent set of options. - set -x - export TSAN_OPTIONS="halt_on_error=1" - set +x - ;; - undefined|integer) - sanitizer_options="${sanitizer_options}:print_stacktrace=1" - set -x - export UBSAN_OPTIONS="${sanitizer_options}" - set +x - ;; -esac diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/tiny_ssim.c b/presentation/src/main/cpp/third_party/libvpx/tools/tiny_ssim.c deleted file mode 100644 index 8cc4d988..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/tiny_ssim.c +++ /dev/null @@ -1,569 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include -#include -#include "vpx/vpx_codec.h" -#include "vpx/vpx_integer.h" -#include "./y4minput.h" -#include "vpx_dsp/ssim.h" -#include "vpx_ports/mem.h" - -static const int64_t cc1 = 26634; // (64^2*(.01*255)^2 -static const int64_t cc2 = 239708; // (64^2*(.03*255)^2 -static const int64_t cc1_10 = 428658; // (64^2*(.01*1023)^2 -static const int64_t cc2_10 = 3857925; // (64^2*(.03*1023)^2 -static const int64_t cc1_12 = 6868593; // (64^2*(.01*4095)^2 -static const int64_t cc2_12 = 61817334; // (64^2*(.03*4095)^2 - -#if CONFIG_VP9_HIGHBITDEPTH -static uint64_t calc_plane_error16(uint16_t *orig, int orig_stride, - uint16_t *recon, int recon_stride, - unsigned int cols, unsigned int rows) { - unsigned int row, col; - uint64_t total_sse = 0; - int diff; - if (orig == NULL || recon == NULL) { - assert(0); - return 0; - } - - for (row = 0; row < rows; row++) { - for (col = 0; col < cols; col++) { - diff = orig[col] - recon[col]; - total_sse += diff * diff; - } - - orig += orig_stride; - recon += recon_stride; - } - return total_sse; -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static uint64_t calc_plane_error(uint8_t *orig, int orig_stride, uint8_t *recon, - int recon_stride, unsigned int cols, - unsigned int rows) { - unsigned int row, col; - uint64_t total_sse = 0; - int diff; - if (orig == NULL || recon == NULL) { - assert(0); - return 0; - } - - for (row = 0; row < rows; row++) { - for (col = 0; col < cols; col++) { - diff = orig[col] - recon[col]; - total_sse += diff * diff; - } - - orig += orig_stride; - recon += recon_stride; - } - return total_sse; -} - -#define MAX_PSNR 100 -static double mse2psnr(double samples, double peak, double mse) { - double psnr; - - if (mse > 0.0) - psnr = 10.0 * log10(peak * peak * samples / mse); - else - psnr = MAX_PSNR; // Limit to prevent / 0 - - if (psnr > MAX_PSNR) psnr = MAX_PSNR; - - return psnr; -} - -typedef enum { RAW_YUV, Y4M } input_file_type; - -typedef struct input_file { - FILE *file; - input_file_type type; - unsigned char *buf; - y4m_input y4m; - vpx_image_t img; - int w; - int h; - int bit_depth; - int frame_size; -} input_file_t; - -// Open a file and determine if its y4m or raw. If y4m get the header. -static int open_input_file(const char *file_name, input_file_t *input, int w, - int h, int bit_depth) { - char y4m_buf[4]; - input->w = w; - input->h = h; - input->bit_depth = bit_depth; - input->type = RAW_YUV; - input->buf = NULL; - input->file = strcmp(file_name, "-") ? fopen(file_name, "rb") : stdin; - if (input->file == NULL) return -1; - if (fread(y4m_buf, 1, 4, input->file) != 4) return -1; - if (memcmp(y4m_buf, "YUV4", 4) == 0) input->type = Y4M; - switch (input->type) { - case Y4M: - y4m_input_open(&input->y4m, input->file, y4m_buf, 4, 0); - input->w = input->y4m.pic_w; - input->h = input->y4m.pic_h; - input->bit_depth = input->y4m.bit_depth; - // Y4M alloc's its own buf. Init this to avoid problems if we never - // read frames. - memset(&input->img, 0, sizeof(input->img)); - break; - case RAW_YUV: - fseek(input->file, 0, SEEK_SET); - input->w = w; - input->h = h; - // handle odd frame sizes - input->frame_size = w * h + ((w + 1) / 2) * ((h + 1) / 2) * 2; - if (bit_depth > 8) { - input->frame_size *= 2; - } - input->buf = malloc(input->frame_size); - break; - } - return 0; -} - -static void close_input_file(input_file_t *in) { - if (in->file) fclose(in->file); - if (in->type == Y4M) { - vpx_img_free(&in->img); - } else { - free(in->buf); - } -} - -// Returns 1 on success, 0 on failure due to a read error or eof (or format -// error in the case of y4m). -static int read_input_file(input_file_t *in, unsigned char **y, - unsigned char **u, unsigned char **v, int bd) { - size_t r1 = 0; - switch (in->type) { - case Y4M: - r1 = y4m_input_fetch_frame(&in->y4m, in->file, &in->img); - if (r1 == (size_t)-1) return 0; - *y = in->img.planes[0]; - *u = in->img.planes[1]; - *v = in->img.planes[2]; - break; - case RAW_YUV: - if (bd < 9) { - r1 = fread(in->buf, in->frame_size, 1, in->file); - *y = in->buf; - *u = in->buf + in->w * in->h; - *v = *u + ((1 + in->w) / 2) * ((1 + in->h) / 2); - } else { - r1 = fread(in->buf, in->frame_size, 1, in->file); - *y = in->buf; - *u = in->buf + (in->w * in->h) * 2; - *v = *u + 2 * ((1 + in->w) / 2) * ((1 + in->h) / 2); - } - break; - } - - return r1 != 0; -} - -static void ssim_parms_8x8(const uint8_t *s, int sp, const uint8_t *r, int rp, - uint32_t *sum_s, uint32_t *sum_r, uint32_t *sum_sq_s, - uint32_t *sum_sq_r, uint32_t *sum_sxr) { - int i, j; - if (s == NULL || r == NULL || sum_s == NULL || sum_r == NULL || - sum_sq_s == NULL || sum_sq_r == NULL || sum_sxr == NULL) { - assert(0); - return; - } - for (i = 0; i < 8; i++, s += sp, r += rp) { - for (j = 0; j < 8; j++) { - *sum_s += s[j]; - *sum_r += r[j]; - *sum_sq_s += s[j] * s[j]; - *sum_sq_r += r[j] * r[j]; - *sum_sxr += s[j] * r[j]; - } - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -static void highbd_ssim_parms_8x8(const uint16_t *s, int sp, const uint16_t *r, - int rp, uint32_t *sum_s, uint32_t *sum_r, - uint32_t *sum_sq_s, uint32_t *sum_sq_r, - uint32_t *sum_sxr) { - int i, j; - if (s == NULL || r == NULL || sum_s == NULL || sum_r == NULL || - sum_sq_s == NULL || sum_sq_r == NULL || sum_sxr == NULL) { - assert(0); - return; - } - for (i = 0; i < 8; i++, s += sp, r += rp) { - for (j = 0; j < 8; j++) { - *sum_s += s[j]; - *sum_r += r[j]; - *sum_sq_s += s[j] * s[j]; - *sum_sq_r += r[j] * r[j]; - *sum_sxr += s[j] * r[j]; - } - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static double similarity(uint32_t sum_s, uint32_t sum_r, uint32_t sum_sq_s, - uint32_t sum_sq_r, uint32_t sum_sxr, int count, - uint32_t bd) { - double ssim_n, ssim_d; - int64_t c1 = 0, c2 = 0; - if (bd == 8) { - // scale the constants by number of pixels - c1 = (cc1 * count * count) >> 12; - c2 = (cc2 * count * count) >> 12; - } else if (bd == 10) { - c1 = (cc1_10 * count * count) >> 12; - c2 = (cc2_10 * count * count) >> 12; - } else if (bd == 12) { - c1 = (cc1_12 * count * count) >> 12; - c2 = (cc2_12 * count * count) >> 12; - } else { - assert(0); - } - - ssim_n = (2.0 * sum_s * sum_r + c1) * - (2.0 * count * sum_sxr - 2.0 * sum_s * sum_r + c2); - - ssim_d = ((double)sum_s * sum_s + (double)sum_r * sum_r + c1) * - ((double)count * sum_sq_s - (double)sum_s * sum_s + - (double)count * sum_sq_r - (double)sum_r * sum_r + c2); - - return ssim_n / ssim_d; -} - -static double ssim_8x8(const uint8_t *s, int sp, const uint8_t *r, int rp) { - uint32_t sum_s = 0, sum_r = 0, sum_sq_s = 0, sum_sq_r = 0, sum_sxr = 0; - ssim_parms_8x8(s, sp, r, rp, &sum_s, &sum_r, &sum_sq_s, &sum_sq_r, &sum_sxr); - return similarity(sum_s, sum_r, sum_sq_s, sum_sq_r, sum_sxr, 64, 8); -} - -#if CONFIG_VP9_HIGHBITDEPTH -static double highbd_ssim_8x8(const uint16_t *s, int sp, const uint16_t *r, - int rp, uint32_t bd) { - uint32_t sum_s = 0, sum_r = 0, sum_sq_s = 0, sum_sq_r = 0, sum_sxr = 0; - highbd_ssim_parms_8x8(s, sp, r, rp, &sum_s, &sum_r, &sum_sq_s, &sum_sq_r, - &sum_sxr); - return similarity(sum_s, sum_r, sum_sq_s, sum_sq_r, sum_sxr, 64, bd); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -// We are using a 8x8 moving window with starting location of each 8x8 window -// on the 4x4 pixel grid. Such arrangement allows the windows to overlap -// block boundaries to penalize blocking artifacts. -static double ssim2(const uint8_t *img1, const uint8_t *img2, int stride_img1, - int stride_img2, int width, int height) { - int i, j; - int samples = 0; - double ssim_total = 0; - - // sample point start with each 4x4 location - for (i = 0; i <= height - 8; - i += 4, img1 += stride_img1 * 4, img2 += stride_img2 * 4) { - for (j = 0; j <= width - 8; j += 4) { - double v = ssim_8x8(img1 + j, stride_img1, img2 + j, stride_img2); - ssim_total += v; - samples++; - } - } - ssim_total /= samples; - return ssim_total; -} - -#if CONFIG_VP9_HIGHBITDEPTH -static double highbd_ssim2(const uint8_t *img1, const uint8_t *img2, - int stride_img1, int stride_img2, int width, - int height, uint32_t bd) { - int i, j; - int samples = 0; - double ssim_total = 0; - - // sample point start with each 4x4 location - for (i = 0; i <= height - 8; - i += 4, img1 += stride_img1 * 4, img2 += stride_img2 * 4) { - for (j = 0; j <= width - 8; j += 4) { - double v = - highbd_ssim_8x8(CONVERT_TO_SHORTPTR(img1 + j), stride_img1, - CONVERT_TO_SHORTPTR(img2 + j), stride_img2, bd); - ssim_total += v; - samples++; - } - } - ssim_total /= samples; - return ssim_total; -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -int main(int argc, char *argv[]) { - FILE *framestats = NULL; - int bit_depth = 8; - int w = 0, h = 0, tl_skip = 0, tl_skips_remaining = 0; - double ssimavg = 0, ssimyavg = 0, ssimuavg = 0, ssimvavg = 0; - double psnrglb = 0, psnryglb = 0, psnruglb = 0, psnrvglb = 0; - double psnravg = 0, psnryavg = 0, psnruavg = 0, psnrvavg = 0; - double *ssimy = NULL, *ssimu = NULL, *ssimv = NULL; - uint64_t *psnry = NULL, *psnru = NULL, *psnrv = NULL; - size_t i, n_frames = 0, allocated_frames = 0; - int return_value = 0; - input_file_t in[2]; - double peak = 255.0; - - memset(in, 0, sizeof(in)); - - if (argc < 3) { - fprintf(stderr, - "Usage: %s file1.{yuv|y4m} file2.{yuv|y4m}" - " [WxH tl_skip={0,1,3} frame_stats_file bits]\n", - argv[0]); - return 1; - } - - if (argc > 3) { - sscanf(argv[3], "%dx%d", &w, &h); - } - - if (argc > 6) { - sscanf(argv[6], "%d", &bit_depth); - } - - if (open_input_file(argv[1], &in[0], w, h, bit_depth) < 0) { - fprintf(stderr, "File %s can't be opened or parsed!\n", argv[1]); - goto clean_up; - } - - if (w == 0 && h == 0) { - // If a y4m is the first file and w, h is not set grab from first file. - w = in[0].w; - h = in[0].h; - bit_depth = in[0].bit_depth; - } - if (bit_depth == 10) peak = 1023.0; - - if (bit_depth == 12) peak = 4095.0; - - if (open_input_file(argv[2], &in[1], w, h, bit_depth) < 0) { - fprintf(stderr, "File %s can't be opened or parsed!\n", argv[2]); - goto clean_up; - } - - if (in[0].w != in[1].w || in[0].h != in[1].h || in[0].w != w || - in[0].h != h || w == 0 || h == 0) { - fprintf(stderr, - "Failing: Image dimensions don't match or are unspecified!\n"); - return_value = 1; - goto clean_up; - } - - if (in[0].bit_depth != in[1].bit_depth) { - fprintf(stderr, - "Failing: Image bit depths don't match or are unspecified!\n"); - return_value = 1; - goto clean_up; - } - - bit_depth = in[0].bit_depth; - - // Number of frames to skip from file1.yuv for every frame used. Normal - // values 0, 1 and 3 correspond to TL2, TL1 and TL0 respectively for a 3TL - // encoding in mode 10. 7 would be reasonable for comparing TL0 of a 4-layer - // encoding. - if (argc > 4) { - sscanf(argv[4], "%d", &tl_skip); - if (argc > 5) { - framestats = fopen(argv[5], "w"); - if (!framestats) { - fprintf(stderr, "Could not open \"%s\" for writing: %s\n", argv[5], - strerror(errno)); - return_value = 1; - goto clean_up; - } - } - } - - while (1) { - int r1, r2; - unsigned char *y[2], *u[2], *v[2]; - - r1 = read_input_file(&in[0], &y[0], &u[0], &v[0], bit_depth); - if (r1 == 0) { - if (ferror(in[0].file)) { - fprintf(stderr, "Failed to read data from '%s'\n", argv[1]); - return_value = 1; - goto clean_up; - } - break; - } - - // Reading parts of file1.yuv that were not used in temporal layer. - if (tl_skips_remaining > 0) { - --tl_skips_remaining; - continue; - } - // Use frame, but skip |tl_skip| after it. - tl_skips_remaining = tl_skip; - - r2 = read_input_file(&in[1], &y[1], &u[1], &v[1], bit_depth); - if (r2 == 0) { - if (ferror(in[1].file)) { - fprintf(stderr, "Failed to read data from '%s'\n", argv[2]); - return_value = 1; - goto clean_up; - } - break; - } - -#if CONFIG_VP9_HIGHBITDEPTH -#define psnr_and_ssim(ssim, psnr, buf0, buf1, w, h) \ - do { \ - if (bit_depth < 9) { \ - ssim = ssim2(buf0, buf1, w, w, w, h); \ - psnr = calc_plane_error(buf0, w, buf1, w, w, h); \ - } else { \ - ssim = highbd_ssim2(CONVERT_TO_BYTEPTR(buf0), CONVERT_TO_BYTEPTR(buf1), \ - w, w, w, h, bit_depth); \ - psnr = calc_plane_error16(CAST_TO_SHORTPTR(buf0), w, \ - CAST_TO_SHORTPTR(buf1), w, w, h); \ - } \ - } while (0) -#else -#define psnr_and_ssim(ssim, psnr, buf0, buf1, w, h) \ - do { \ - ssim = ssim2(buf0, buf1, w, w, w, h); \ - psnr = calc_plane_error(buf0, w, buf1, w, w, h); \ - } while (0) -#endif // CONFIG_VP9_HIGHBITDEPTH - - if (n_frames == allocated_frames) { - allocated_frames = allocated_frames == 0 ? 1024 : allocated_frames * 2; - ssimy = realloc(ssimy, allocated_frames * sizeof(*ssimy)); - ssimu = realloc(ssimu, allocated_frames * sizeof(*ssimu)); - ssimv = realloc(ssimv, allocated_frames * sizeof(*ssimv)); - psnry = realloc(psnry, allocated_frames * sizeof(*psnry)); - psnru = realloc(psnru, allocated_frames * sizeof(*psnru)); - psnrv = realloc(psnrv, allocated_frames * sizeof(*psnrv)); - if (!(ssimy && ssimu && ssimv && psnry && psnru && psnrv)) { - fprintf(stderr, "Error allocating SSIM/PSNR data.\n"); - exit(EXIT_FAILURE); - } - } - psnr_and_ssim(ssimy[n_frames], psnry[n_frames], y[0], y[1], w, h); - psnr_and_ssim(ssimu[n_frames], psnru[n_frames], u[0], u[1], (w + 1) / 2, - (h + 1) / 2); - psnr_and_ssim(ssimv[n_frames], psnrv[n_frames], v[0], v[1], (w + 1) / 2, - (h + 1) / 2); - - n_frames++; - } - - if (framestats) { - fprintf(framestats, - "ssim,ssim-y,ssim-u,ssim-v,psnr,psnr-y,psnr-u,psnr-v\n"); - } - - for (i = 0; i < n_frames; ++i) { - double frame_ssim; - double frame_psnr, frame_psnry, frame_psnru, frame_psnrv; - - frame_ssim = 0.8 * ssimy[i] + 0.1 * (ssimu[i] + ssimv[i]); - ssimavg += frame_ssim; - ssimyavg += ssimy[i]; - ssimuavg += ssimu[i]; - ssimvavg += ssimv[i]; - - frame_psnr = - mse2psnr(w * h * 6 / 4, peak, (double)psnry[i] + psnru[i] + psnrv[i]); - frame_psnry = mse2psnr(w * h * 4 / 4, peak, (double)psnry[i]); - frame_psnru = mse2psnr(w * h * 1 / 4, peak, (double)psnru[i]); - frame_psnrv = mse2psnr(w * h * 1 / 4, peak, (double)psnrv[i]); - - psnravg += frame_psnr; - psnryavg += frame_psnry; - psnruavg += frame_psnru; - psnrvavg += frame_psnrv; - - psnryglb += psnry[i]; - psnruglb += psnru[i]; - psnrvglb += psnrv[i]; - - if (framestats) { - fprintf(framestats, "%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf\n", frame_ssim, - ssimy[i], ssimu[i], ssimv[i], frame_psnr, frame_psnry, - frame_psnru, frame_psnrv); - } - } - - ssimavg /= n_frames; - ssimyavg /= n_frames; - ssimuavg /= n_frames; - ssimvavg /= n_frames; - - printf("VpxSSIM: %lf\n", 100 * pow(ssimavg, 8.0)); - printf("SSIM: %lf\n", ssimavg); - printf("SSIM-Y: %lf\n", ssimyavg); - printf("SSIM-U: %lf\n", ssimuavg); - printf("SSIM-V: %lf\n", ssimvavg); - puts(""); - - psnravg /= n_frames; - psnryavg /= n_frames; - psnruavg /= n_frames; - psnrvavg /= n_frames; - - printf("AvgPSNR: %lf\n", psnravg); - printf("AvgPSNR-Y: %lf\n", psnryavg); - printf("AvgPSNR-U: %lf\n", psnruavg); - printf("AvgPSNR-V: %lf\n", psnrvavg); - puts(""); - - psnrglb = psnryglb + psnruglb + psnrvglb; - psnrglb = mse2psnr((double)n_frames * w * h * 6 / 4, peak, psnrglb); - psnryglb = mse2psnr((double)n_frames * w * h * 4 / 4, peak, psnryglb); - psnruglb = mse2psnr((double)n_frames * w * h * 1 / 4, peak, psnruglb); - psnrvglb = mse2psnr((double)n_frames * w * h * 1 / 4, peak, psnrvglb); - - printf("GlbPSNR: %lf\n", psnrglb); - printf("GlbPSNR-Y: %lf\n", psnryglb); - printf("GlbPSNR-U: %lf\n", psnruglb); - printf("GlbPSNR-V: %lf\n", psnrvglb); - puts(""); - - printf("Nframes: %d\n", (int)n_frames); - -clean_up: - - close_input_file(&in[0]); - close_input_file(&in[1]); - - if (framestats) fclose(framestats); - - free(ssimy); - free(ssimu); - free(ssimv); - - free(psnry); - free(psnru); - free(psnrv); - - return return_value; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/tools/wrap-commit-msg.py b/presentation/src/main/cpp/third_party/libvpx/tools/wrap-commit-msg.py deleted file mode 100644 index ba3fa587..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools/wrap-commit-msg.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python3 -## Copyright (c) 2012 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## -"""Wraps paragraphs of text, preserving manual formatting - -This is like fold(1), but has the special convention of not modifying lines -that start with whitespace. This allows you to intersperse blocks with -special formatting, like code blocks, with written prose. The prose will -be wordwrapped, and the manual formatting will be preserved. - - * This won't handle the case of a bulleted (or ordered) list specially, so - manual wrapping must be done. - -Occasionally it's useful to put something with explicit formatting that -doesn't look at all like a block of text inline. - - indicator = has_leading_whitespace(line); - if (indicator) - preserve_formatting(line); - -The intent is that this docstring would make it through the transform -and still be legible and presented as it is in the source. If additional -cases are handled, update this doc to describe the effect. -""" - -__author__ = "jkoleszar@google.com" -import textwrap -import sys - -def wrap(text): - if text: - return textwrap.fill(text, break_long_words=False) + '\n' - return "" - - -def main(fileobj): - text = "" - output = "" - while True: - line = fileobj.readline() - if not line: - break - - if line.lstrip() == line: - text += line - else: - output += wrap(text) - text="" - output += line - output += wrap(text) - - # Replace the file or write to stdout. - if fileobj == sys.stdin: - fileobj = sys.stdout - else: - fileobj.seek(0) - fileobj.truncate(0) - fileobj.write(output) - -if __name__ == "__main__": - if len(sys.argv) > 1: - main(open(sys.argv[1], "r+")) - else: - main(sys.stdin) diff --git a/presentation/src/main/cpp/third_party/libvpx/tools_common.c b/presentation/src/main/cpp/third_party/libvpx/tools_common.c deleted file mode 100644 index 5af971f7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools_common.c +++ /dev/null @@ -1,780 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include - -#include "./tools_common.h" - -#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER -#include "vpx/vp8cx.h" -#endif - -#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER -#include "vpx/vp8dx.h" -#endif - -#include "vpx/vpx_codec.h" - -#if defined(_WIN32) -#include -#include -#endif - -#define LOG_ERROR(label) \ - do { \ - const char *l = label; \ - va_list ap; \ - va_start(ap, fmt); \ - if (l) fprintf(stderr, "%s: ", l); \ - vfprintf(stderr, fmt, ap); \ - fprintf(stderr, "\n"); \ - va_end(ap); \ - } while (0) - -#if CONFIG_ENCODERS -/* Swallow warnings about unused results of fread/fwrite */ -static size_t wrap_fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { - return fread(ptr, size, nmemb, stream); -} -#define fread wrap_fread -#endif - -FILE *set_binary_mode(FILE *stream) { - (void)stream; -#if defined(_WIN32) - _setmode(_fileno(stream), _O_BINARY); -#endif - return stream; -} - -void die(const char *fmt, ...) { - LOG_ERROR(NULL); - usage_exit(); -} - -void fatal(const char *fmt, ...) { - LOG_ERROR("Fatal"); - exit(EXIT_FAILURE); -} - -void warn(const char *fmt, ...) { LOG_ERROR("Warning"); } - -void die_codec(vpx_codec_ctx_t *ctx, const char *s) { - const char *detail = vpx_codec_error_detail(ctx); - - fprintf(stderr, "%s: %s\n", s, vpx_codec_error(ctx)); - if (detail) fprintf(stderr, " %s\n", detail); - exit(EXIT_FAILURE); -} - -int read_yuv_frame(struct VpxInputContext *input_ctx, vpx_image_t *yuv_frame) { - FILE *f = input_ctx->file; - struct FileTypeDetectionBuffer *detect = &input_ctx->detect; - int plane = 0; - int shortread = 0; - const int bytespp = (yuv_frame->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1; - - for (plane = 0; plane < 3; ++plane) { - uint8_t *ptr; - int w = vpx_img_plane_width(yuv_frame, plane); - const int h = vpx_img_plane_height(yuv_frame, plane); - int r; - // Assuming that for nv12 we read all chroma data at once - if (yuv_frame->fmt == VPX_IMG_FMT_NV12 && plane > 1) break; - // Fixing NV12 chroma width if it is odd - if (yuv_frame->fmt == VPX_IMG_FMT_NV12 && plane == 1) w = (w + 1) & ~1; - /* Determine the correct plane based on the image format. The for-loop - * always counts in Y,U,V order, but this may not match the order of - * the data on disk. - */ - switch (plane) { - case 1: - ptr = - yuv_frame->planes[yuv_frame->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_V - : VPX_PLANE_U]; - break; - case 2: - ptr = - yuv_frame->planes[yuv_frame->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_U - : VPX_PLANE_V]; - break; - default: ptr = yuv_frame->planes[plane]; - } - - for (r = 0; r < h; ++r) { - size_t needed = w * bytespp; - size_t buf_position = 0; - const size_t left = detect->buf_read - detect->position; - if (left > 0) { - const size_t more = (left < needed) ? left : needed; - memcpy(ptr, detect->buf + detect->position, more); - buf_position = more; - needed -= more; - detect->position += more; - } - if (needed > 0) { - shortread |= (fread(ptr + buf_position, 1, needed, f) < needed); - } - - ptr += yuv_frame->stride[plane]; - } - } - - return shortread; -} - -#if CONFIG_ENCODERS - -static const VpxInterface vpx_encoders[] = { -#if CONFIG_VP8_ENCODER - { "vp8", VP8_FOURCC, &vpx_codec_vp8_cx }, -#endif - -#if CONFIG_VP9_ENCODER - { "vp9", VP9_FOURCC, &vpx_codec_vp9_cx }, -#endif -}; - -int get_vpx_encoder_count(void) { - return sizeof(vpx_encoders) / sizeof(vpx_encoders[0]); -} - -const VpxInterface *get_vpx_encoder_by_index(int i) { return &vpx_encoders[i]; } - -const VpxInterface *get_vpx_encoder_by_name(const char *name) { - int i; - - for (i = 0; i < get_vpx_encoder_count(); ++i) { - const VpxInterface *encoder = get_vpx_encoder_by_index(i); - if (strcmp(encoder->name, name) == 0) return encoder; - } - - return NULL; -} - -#endif // CONFIG_ENCODERS - -#if CONFIG_DECODERS - -static const VpxInterface vpx_decoders[] = { -#if CONFIG_VP8_DECODER - { "vp8", VP8_FOURCC, &vpx_codec_vp8_dx }, -#endif - -#if CONFIG_VP9_DECODER - { "vp9", VP9_FOURCC, &vpx_codec_vp9_dx }, -#endif -}; - -int get_vpx_decoder_count(void) { - return sizeof(vpx_decoders) / sizeof(vpx_decoders[0]); -} - -const VpxInterface *get_vpx_decoder_by_index(int i) { return &vpx_decoders[i]; } - -const VpxInterface *get_vpx_decoder_by_name(const char *name) { - int i; - - for (i = 0; i < get_vpx_decoder_count(); ++i) { - const VpxInterface *const decoder = get_vpx_decoder_by_index(i); - if (strcmp(decoder->name, name) == 0) return decoder; - } - - return NULL; -} - -const VpxInterface *get_vpx_decoder_by_fourcc(uint32_t fourcc) { - int i; - - for (i = 0; i < get_vpx_decoder_count(); ++i) { - const VpxInterface *const decoder = get_vpx_decoder_by_index(i); - if (decoder->fourcc == fourcc) return decoder; - } - - return NULL; -} - -#endif // CONFIG_DECODERS - -int vpx_img_plane_width(const vpx_image_t *img, int plane) { - if (plane > 0 && img->x_chroma_shift > 0) - return (img->d_w + 1) >> img->x_chroma_shift; - else - return img->d_w; -} - -int vpx_img_plane_height(const vpx_image_t *img, int plane) { - if (plane > 0 && img->y_chroma_shift > 0) - return (img->d_h + 1) >> img->y_chroma_shift; - else - return img->d_h; -} - -void vpx_img_write(const vpx_image_t *img, FILE *file) { - int plane; - const int bytespp = (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1; - - for (plane = 0; plane < 3; ++plane) { - const unsigned char *buf = img->planes[plane]; - const int stride = img->stride[plane]; - int w = vpx_img_plane_width(img, plane); - const int h = vpx_img_plane_height(img, plane); - int y; - - // Assuming that for nv12 we write all chroma data at once - if (img->fmt == VPX_IMG_FMT_NV12 && plane > 1) break; - // Fixing NV12 chroma width if it is odd - if (img->fmt == VPX_IMG_FMT_NV12 && plane == 1) w = (w + 1) & ~1; - - for (y = 0; y < h; ++y) { - fwrite(buf, bytespp, w, file); - buf += stride; - } - } -} - -int vpx_img_read(vpx_image_t *img, FILE *file) { - int plane; - const int bytespp = (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1; - - for (plane = 0; plane < 3; ++plane) { - unsigned char *buf = img->planes[plane]; - const int stride = img->stride[plane]; - int w = vpx_img_plane_width(img, plane); - const int h = vpx_img_plane_height(img, plane); - int y; - - // Assuming that for nv12 we read all chroma data at once - if (img->fmt == VPX_IMG_FMT_NV12 && plane > 1) break; - // Fixing NV12 chroma width if it is odd - if (img->fmt == VPX_IMG_FMT_NV12 && plane == 1) w = (w + 1) & ~1; - - for (y = 0; y < h; ++y) { - if (fread(buf, bytespp, w, file) != (size_t)w) return 0; - buf += stride; - } - } - - return 1; -} - -// TODO(dkovalev) change sse_to_psnr signature: double -> int64_t -double sse_to_psnr(double samples, double peak, double sse) { - static const double kMaxPSNR = 100.0; - - if (sse > 0.0) { - const double psnr = 10.0 * log10(samples * peak * peak / sse); - return psnr > kMaxPSNR ? kMaxPSNR : psnr; - } else { - return kMaxPSNR; - } -} - -#if CONFIG_ENCODERS -int read_frame(struct VpxInputContext *input_ctx, vpx_image_t *img) { - FILE *f = input_ctx->file; - y4m_input *y4m = &input_ctx->y4m; - int shortread = 0; - - if (input_ctx->file_type == FILE_TYPE_Y4M) { - if (y4m_input_fetch_frame(y4m, f, img) < 1) return 0; - } else { - shortread = read_yuv_frame(input_ctx, img); - } - - return !shortread; -} - -int file_is_y4m(const char detect[4]) { - if (memcmp(detect, "YUV4", 4) == 0) { - return 1; - } - return 0; -} - -int fourcc_is_ivf(const char detect[4]) { - if (memcmp(detect, "DKIF", 4) == 0) { - return 1; - } - return 0; -} - -void open_input_file(struct VpxInputContext *input) { - /* Parse certain options from the input file, if possible */ - input->file = strcmp(input->filename, "-") ? fopen(input->filename, "rb") - : set_binary_mode(stdin); - - if (!input->file) fatal("Failed to open input file"); - - if (!fseeko(input->file, 0, SEEK_END)) { - /* Input file is seekable. Figure out how long it is, so we can get - * progress info. - */ - input->length = ftello(input->file); - rewind(input->file); - } - - /* Default to 1:1 pixel aspect ratio. */ - input->pixel_aspect_ratio.numerator = 1; - input->pixel_aspect_ratio.denominator = 1; - - /* For RAW input sources, these bytes will applied on the first frame - * in read_frame(). - */ - input->detect.buf_read = fread(input->detect.buf, 1, 4, input->file); - input->detect.position = 0; - - if (input->detect.buf_read == 4 && file_is_y4m(input->detect.buf)) { - if (y4m_input_open(&input->y4m, input->file, input->detect.buf, 4, - input->only_i420) >= 0) { - input->file_type = FILE_TYPE_Y4M; - input->width = input->y4m.pic_w; - input->height = input->y4m.pic_h; - input->pixel_aspect_ratio.numerator = input->y4m.par_n; - input->pixel_aspect_ratio.denominator = input->y4m.par_d; - input->framerate.numerator = input->y4m.fps_n; - input->framerate.denominator = input->y4m.fps_d; - input->fmt = input->y4m.vpx_fmt; - input->bit_depth = input->y4m.bit_depth; - } else { - fatal("Unsupported Y4M stream."); - } - } else if (input->detect.buf_read == 4 && fourcc_is_ivf(input->detect.buf)) { - fatal("IVF is not supported as input."); - } else { - input->file_type = FILE_TYPE_RAW; - } -} - -void close_input_file(struct VpxInputContext *input) { - fclose(input->file); - if (input->file_type == FILE_TYPE_Y4M) y4m_input_close(&input->y4m); -} -#endif - -// TODO(debargha): Consolidate the functions below into a separate file. -#if CONFIG_VP9_HIGHBITDEPTH -static void highbd_img_upshift(vpx_image_t *dst, vpx_image_t *src, - int input_shift) { - // Note the offset is 1 less than half. - const int offset = input_shift > 0 ? (1 << (input_shift - 1)) - 1 : 0; - int plane; - if (dst->d_w != src->d_w || dst->d_h != src->d_h || - dst->x_chroma_shift != src->x_chroma_shift || - dst->y_chroma_shift != src->y_chroma_shift || dst->fmt != src->fmt || - input_shift < 0) { - fatal("Unsupported image conversion"); - } - switch (src->fmt) { - case VPX_IMG_FMT_I42016: - case VPX_IMG_FMT_I42216: - case VPX_IMG_FMT_I44416: - case VPX_IMG_FMT_I44016: break; - default: fatal("Unsupported image conversion"); - } - for (plane = 0; plane < 3; plane++) { - int w = src->d_w; - int h = src->d_h; - int x, y; - if (plane) { - w = (w + src->x_chroma_shift) >> src->x_chroma_shift; - h = (h + src->y_chroma_shift) >> src->y_chroma_shift; - } - for (y = 0; y < h; y++) { - uint16_t *p_src = - (uint16_t *)(src->planes[plane] + y * src->stride[plane]); - uint16_t *p_dst = - (uint16_t *)(dst->planes[plane] + y * dst->stride[plane]); - for (x = 0; x < w; x++) *p_dst++ = (*p_src++ << input_shift) + offset; - } - } -} - -static void lowbd_img_upshift(vpx_image_t *dst, vpx_image_t *src, - int input_shift) { - // Note the offset is 1 less than half. - const int offset = input_shift > 0 ? (1 << (input_shift - 1)) - 1 : 0; - int plane; - if (dst->d_w != src->d_w || dst->d_h != src->d_h || - dst->x_chroma_shift != src->x_chroma_shift || - dst->y_chroma_shift != src->y_chroma_shift || - dst->fmt != src->fmt + VPX_IMG_FMT_HIGHBITDEPTH || input_shift < 0) { - fatal("Unsupported image conversion"); - } - switch (src->fmt) { - case VPX_IMG_FMT_I420: - case VPX_IMG_FMT_I422: - case VPX_IMG_FMT_I444: - case VPX_IMG_FMT_I440: break; - default: fatal("Unsupported image conversion"); - } - for (plane = 0; plane < 3; plane++) { - int w = src->d_w; - int h = src->d_h; - int x, y; - if (plane) { - w = (w + src->x_chroma_shift) >> src->x_chroma_shift; - h = (h + src->y_chroma_shift) >> src->y_chroma_shift; - } - for (y = 0; y < h; y++) { - uint8_t *p_src = src->planes[plane] + y * src->stride[plane]; - uint16_t *p_dst = - (uint16_t *)(dst->planes[plane] + y * dst->stride[plane]); - for (x = 0; x < w; x++) { - *p_dst++ = (*p_src++ << input_shift) + offset; - } - } - } -} - -void vpx_img_upshift(vpx_image_t *dst, vpx_image_t *src, int input_shift) { - if (src->fmt & VPX_IMG_FMT_HIGHBITDEPTH) { - highbd_img_upshift(dst, src, input_shift); - } else { - lowbd_img_upshift(dst, src, input_shift); - } -} - -void vpx_img_truncate_16_to_8(vpx_image_t *dst, vpx_image_t *src) { - int plane; - if (dst->fmt + VPX_IMG_FMT_HIGHBITDEPTH != src->fmt || dst->d_w != src->d_w || - dst->d_h != src->d_h || dst->x_chroma_shift != src->x_chroma_shift || - dst->y_chroma_shift != src->y_chroma_shift) { - fatal("Unsupported image conversion"); - } - switch (dst->fmt) { - case VPX_IMG_FMT_I420: - case VPX_IMG_FMT_I422: - case VPX_IMG_FMT_I444: - case VPX_IMG_FMT_I440: break; - default: fatal("Unsupported image conversion"); - } - for (plane = 0; plane < 3; plane++) { - int w = src->d_w; - int h = src->d_h; - int x, y; - if (plane) { - w = (w + src->x_chroma_shift) >> src->x_chroma_shift; - h = (h + src->y_chroma_shift) >> src->y_chroma_shift; - } - for (y = 0; y < h; y++) { - uint16_t *p_src = - (uint16_t *)(src->planes[plane] + y * src->stride[plane]); - uint8_t *p_dst = dst->planes[plane] + y * dst->stride[plane]; - for (x = 0; x < w; x++) { - *p_dst++ = (uint8_t)(*p_src++); - } - } - } -} - -static void highbd_img_downshift(vpx_image_t *dst, vpx_image_t *src, - int down_shift) { - int plane; - if (dst->d_w != src->d_w || dst->d_h != src->d_h || - dst->x_chroma_shift != src->x_chroma_shift || - dst->y_chroma_shift != src->y_chroma_shift || dst->fmt != src->fmt || - down_shift < 0) { - fatal("Unsupported image conversion"); - } - switch (src->fmt) { - case VPX_IMG_FMT_I42016: - case VPX_IMG_FMT_I42216: - case VPX_IMG_FMT_I44416: - case VPX_IMG_FMT_I44016: break; - default: fatal("Unsupported image conversion"); - } - for (plane = 0; plane < 3; plane++) { - int w = src->d_w; - int h = src->d_h; - int x, y; - if (plane) { - w = (w + src->x_chroma_shift) >> src->x_chroma_shift; - h = (h + src->y_chroma_shift) >> src->y_chroma_shift; - } - for (y = 0; y < h; y++) { - uint16_t *p_src = - (uint16_t *)(src->planes[plane] + y * src->stride[plane]); - uint16_t *p_dst = - (uint16_t *)(dst->planes[plane] + y * dst->stride[plane]); - for (x = 0; x < w; x++) *p_dst++ = *p_src++ >> down_shift; - } - } -} - -static void lowbd_img_downshift(vpx_image_t *dst, vpx_image_t *src, - int down_shift) { - int plane; - if (dst->d_w != src->d_w || dst->d_h != src->d_h || - dst->x_chroma_shift != src->x_chroma_shift || - dst->y_chroma_shift != src->y_chroma_shift || - src->fmt != dst->fmt + VPX_IMG_FMT_HIGHBITDEPTH || down_shift < 0) { - fatal("Unsupported image conversion"); - } - switch (dst->fmt) { - case VPX_IMG_FMT_I420: - case VPX_IMG_FMT_I422: - case VPX_IMG_FMT_I444: - case VPX_IMG_FMT_I440: break; - default: fatal("Unsupported image conversion"); - } - for (plane = 0; plane < 3; plane++) { - int w = src->d_w; - int h = src->d_h; - int x, y; - if (plane) { - w = (w + src->x_chroma_shift) >> src->x_chroma_shift; - h = (h + src->y_chroma_shift) >> src->y_chroma_shift; - } - for (y = 0; y < h; y++) { - uint16_t *p_src = - (uint16_t *)(src->planes[plane] + y * src->stride[plane]); - uint8_t *p_dst = dst->planes[plane] + y * dst->stride[plane]; - for (x = 0; x < w; x++) { - *p_dst++ = *p_src++ >> down_shift; - } - } - } -} - -void vpx_img_downshift(vpx_image_t *dst, vpx_image_t *src, int down_shift) { - if (dst->fmt & VPX_IMG_FMT_HIGHBITDEPTH) { - highbd_img_downshift(dst, src, down_shift); - } else { - lowbd_img_downshift(dst, src, down_shift); - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -int compare_img(const vpx_image_t *const img1, const vpx_image_t *const img2) { - uint32_t l_w = img1->d_w; - uint32_t c_w = (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift; - const uint32_t c_h = - (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift; - uint32_t i; - int match = 1; - - match &= (img1->fmt == img2->fmt); - match &= (img1->d_w == img2->d_w); - match &= (img1->d_h == img2->d_h); -#if CONFIG_VP9_HIGHBITDEPTH - if (img1->fmt & VPX_IMG_FMT_HIGHBITDEPTH) { - l_w *= 2; - c_w *= 2; - } -#endif - - for (i = 0; i < img1->d_h; ++i) - match &= (memcmp(img1->planes[VPX_PLANE_Y] + i * img1->stride[VPX_PLANE_Y], - img2->planes[VPX_PLANE_Y] + i * img2->stride[VPX_PLANE_Y], - l_w) == 0); - - for (i = 0; i < c_h; ++i) - match &= (memcmp(img1->planes[VPX_PLANE_U] + i * img1->stride[VPX_PLANE_U], - img2->planes[VPX_PLANE_U] + i * img2->stride[VPX_PLANE_U], - c_w) == 0); - - for (i = 0; i < c_h; ++i) - match &= (memcmp(img1->planes[VPX_PLANE_V] + i * img1->stride[VPX_PLANE_V], - img2->planes[VPX_PLANE_V] + i * img2->stride[VPX_PLANE_V], - c_w) == 0); - - return match; -} - -#define mmin(a, b) ((a) < (b) ? (a) : (b)) - -#if CONFIG_VP9_HIGHBITDEPTH -void find_mismatch_high(const vpx_image_t *const img1, - const vpx_image_t *const img2, int yloc[4], int uloc[4], - int vloc[4]) { - uint16_t *plane1, *plane2; - uint32_t stride1, stride2; - const uint32_t bsize = 64; - const uint32_t bsizey = bsize >> img1->y_chroma_shift; - const uint32_t bsizex = bsize >> img1->x_chroma_shift; - const uint32_t c_w = - (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift; - const uint32_t c_h = - (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift; - int match = 1; - uint32_t i, j; - yloc[0] = yloc[1] = yloc[2] = yloc[3] = -1; - plane1 = (uint16_t *)img1->planes[VPX_PLANE_Y]; - plane2 = (uint16_t *)img2->planes[VPX_PLANE_Y]; - stride1 = img1->stride[VPX_PLANE_Y] / 2; - stride2 = img2->stride[VPX_PLANE_Y] / 2; - for (i = 0, match = 1; match && i < img1->d_h; i += bsize) { - for (j = 0; match && j < img1->d_w; j += bsize) { - int k, l; - const int si = mmin(i + bsize, img1->d_h) - i; - const int sj = mmin(j + bsize, img1->d_w) - j; - for (k = 0; match && k < si; ++k) { - for (l = 0; match && l < sj; ++l) { - if (*(plane1 + (i + k) * stride1 + j + l) != - *(plane2 + (i + k) * stride2 + j + l)) { - yloc[0] = i + k; - yloc[1] = j + l; - yloc[2] = *(plane1 + (i + k) * stride1 + j + l); - yloc[3] = *(plane2 + (i + k) * stride2 + j + l); - match = 0; - break; - } - } - } - } - } - - uloc[0] = uloc[1] = uloc[2] = uloc[3] = -1; - plane1 = (uint16_t *)img1->planes[VPX_PLANE_U]; - plane2 = (uint16_t *)img2->planes[VPX_PLANE_U]; - stride1 = img1->stride[VPX_PLANE_U] / 2; - stride2 = img2->stride[VPX_PLANE_U] / 2; - for (i = 0, match = 1; match && i < c_h; i += bsizey) { - for (j = 0; match && j < c_w; j += bsizex) { - int k, l; - const int si = mmin(i + bsizey, c_h - i); - const int sj = mmin(j + bsizex, c_w - j); - for (k = 0; match && k < si; ++k) { - for (l = 0; match && l < sj; ++l) { - if (*(plane1 + (i + k) * stride1 + j + l) != - *(plane2 + (i + k) * stride2 + j + l)) { - uloc[0] = i + k; - uloc[1] = j + l; - uloc[2] = *(plane1 + (i + k) * stride1 + j + l); - uloc[3] = *(plane2 + (i + k) * stride2 + j + l); - match = 0; - break; - } - } - } - } - } - - vloc[0] = vloc[1] = vloc[2] = vloc[3] = -1; - plane1 = (uint16_t *)img1->planes[VPX_PLANE_V]; - plane2 = (uint16_t *)img2->planes[VPX_PLANE_V]; - stride1 = img1->stride[VPX_PLANE_V] / 2; - stride2 = img2->stride[VPX_PLANE_V] / 2; - for (i = 0, match = 1; match && i < c_h; i += bsizey) { - for (j = 0; match && j < c_w; j += bsizex) { - int k, l; - const int si = mmin(i + bsizey, c_h - i); - const int sj = mmin(j + bsizex, c_w - j); - for (k = 0; match && k < si; ++k) { - for (l = 0; match && l < sj; ++l) { - if (*(plane1 + (i + k) * stride1 + j + l) != - *(plane2 + (i + k) * stride2 + j + l)) { - vloc[0] = i + k; - vloc[1] = j + l; - vloc[2] = *(plane1 + (i + k) * stride1 + j + l); - vloc[3] = *(plane2 + (i + k) * stride2 + j + l); - match = 0; - break; - } - } - } - } - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -void find_mismatch(const vpx_image_t *const img1, const vpx_image_t *const img2, - int yloc[4], int uloc[4], int vloc[4]) { - const uint32_t bsize = 64; - const uint32_t bsizey = bsize >> img1->y_chroma_shift; - const uint32_t bsizex = bsize >> img1->x_chroma_shift; - const uint32_t c_w = - (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift; - const uint32_t c_h = - (img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift; - int match = 1; - uint32_t i, j; - yloc[0] = yloc[1] = yloc[2] = yloc[3] = -1; - for (i = 0, match = 1; match && i < img1->d_h; i += bsize) { - for (j = 0; match && j < img1->d_w; j += bsize) { - int k, l; - const int si = mmin(i + bsize, img1->d_h) - i; - const int sj = mmin(j + bsize, img1->d_w) - j; - for (k = 0; match && k < si; ++k) { - for (l = 0; match && l < sj; ++l) { - if (*(img1->planes[VPX_PLANE_Y] + - (i + k) * img1->stride[VPX_PLANE_Y] + j + l) != - *(img2->planes[VPX_PLANE_Y] + - (i + k) * img2->stride[VPX_PLANE_Y] + j + l)) { - yloc[0] = i + k; - yloc[1] = j + l; - yloc[2] = *(img1->planes[VPX_PLANE_Y] + - (i + k) * img1->stride[VPX_PLANE_Y] + j + l); - yloc[3] = *(img2->planes[VPX_PLANE_Y] + - (i + k) * img2->stride[VPX_PLANE_Y] + j + l); - match = 0; - break; - } - } - } - } - } - - uloc[0] = uloc[1] = uloc[2] = uloc[3] = -1; - for (i = 0, match = 1; match && i < c_h; i += bsizey) { - for (j = 0; match && j < c_w; j += bsizex) { - int k, l; - const int si = mmin(i + bsizey, c_h - i); - const int sj = mmin(j + bsizex, c_w - j); - for (k = 0; match && k < si; ++k) { - for (l = 0; match && l < sj; ++l) { - if (*(img1->planes[VPX_PLANE_U] + - (i + k) * img1->stride[VPX_PLANE_U] + j + l) != - *(img2->planes[VPX_PLANE_U] + - (i + k) * img2->stride[VPX_PLANE_U] + j + l)) { - uloc[0] = i + k; - uloc[1] = j + l; - uloc[2] = *(img1->planes[VPX_PLANE_U] + - (i + k) * img1->stride[VPX_PLANE_U] + j + l); - uloc[3] = *(img2->planes[VPX_PLANE_U] + - (i + k) * img2->stride[VPX_PLANE_U] + j + l); - match = 0; - break; - } - } - } - } - } - vloc[0] = vloc[1] = vloc[2] = vloc[3] = -1; - for (i = 0, match = 1; match && i < c_h; i += bsizey) { - for (j = 0; match && j < c_w; j += bsizex) { - int k, l; - const int si = mmin(i + bsizey, c_h - i); - const int sj = mmin(j + bsizex, c_w - j); - for (k = 0; match && k < si; ++k) { - for (l = 0; match && l < sj; ++l) { - if (*(img1->planes[VPX_PLANE_V] + - (i + k) * img1->stride[VPX_PLANE_V] + j + l) != - *(img2->planes[VPX_PLANE_V] + - (i + k) * img2->stride[VPX_PLANE_V] + j + l)) { - vloc[0] = i + k; - vloc[1] = j + l; - vloc[2] = *(img1->planes[VPX_PLANE_V] + - (i + k) * img1->stride[VPX_PLANE_V] + j + l); - vloc[3] = *(img2->planes[VPX_PLANE_V] + - (i + k) * img2->stride[VPX_PLANE_V] + j + l); - match = 0; - break; - } - } - } - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/tools_common.h b/presentation/src/main/cpp/third_party/libvpx/tools_common.h deleted file mode 100644 index 81453cc0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/tools_common.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_TOOLS_COMMON_H_ -#define VPX_TOOLS_COMMON_H_ - -#include - -#include "./vpx_config.h" -#include "vpx/vpx_codec.h" -#include "vpx/vpx_image.h" -#include "vpx/vpx_integer.h" - -#if CONFIG_ENCODERS -#include "./y4minput.h" -#endif - -#if defined(_MSC_VER) -/* MSVS uses _f{seek,tell}i64. */ -#define fseeko _fseeki64 -#define ftello _ftelli64 -typedef int64_t FileOffset; -#elif defined(_WIN32) -/* MinGW uses f{seek,tell}o64 for large files. */ -#define fseeko fseeko64 -#define ftello ftello64 -typedef off64_t FileOffset; -#elif CONFIG_OS_SUPPORT && \ - !(defined(__ANDROID__) && __ANDROID_API__ < 24 && !defined(__LP64__) && \ - defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64) -/* POSIX.1 has fseeko and ftello. fseeko and ftello are not available before - * Android API level 24. See - * https://android.googlesource.com/platform/bionic/+/main/docs/32-bit-abi.md */ -#include /* NOLINT */ -typedef off_t FileOffset; -/* Use 32-bit file operations in WebM file format when building ARM - * executables (.axf) with RVCT. */ -#else -#define fseeko fseek -#define ftello ftell -typedef long FileOffset; /* NOLINT */ -#endif /* CONFIG_OS_SUPPORT */ - -#if CONFIG_OS_SUPPORT -#if defined(_MSC_VER) -#include /* NOLINT */ -#define isatty _isatty -#define fileno _fileno -#else -#include /* NOLINT */ -#endif /* _MSC_VER */ -#endif /* CONFIG_OS_SUPPORT */ - -#define LITERALU64(hi, lo) ((((uint64_t)hi) << 32) | lo) - -#ifndef PATH_MAX -#define PATH_MAX 512 -#endif - -#define IVF_FRAME_HDR_SZ (4 + 8) /* 4 byte size + 8 byte timestamp */ -#define IVF_FILE_HDR_SZ 32 - -#define RAW_FRAME_HDR_SZ sizeof(uint32_t) - -#define VP8_FOURCC 0x30385056 -#define VP9_FOURCC 0x30395056 - -enum VideoFileType { - FILE_TYPE_RAW, - FILE_TYPE_IVF, - FILE_TYPE_Y4M, - FILE_TYPE_WEBM -}; - -struct FileTypeDetectionBuffer { - char buf[4]; - size_t buf_read; - size_t position; -}; - -struct VpxRational { - int numerator; - int denominator; -}; - -struct VpxInputContext { - const char *filename; - FILE *file; - int64_t length; - struct FileTypeDetectionBuffer detect; - enum VideoFileType file_type; - uint32_t width; - uint32_t height; - struct VpxRational pixel_aspect_ratio; - vpx_img_fmt_t fmt; - vpx_bit_depth_t bit_depth; - int only_i420; - uint32_t fourcc; - struct VpxRational framerate; -#if CONFIG_ENCODERS - y4m_input y4m; -#endif -}; - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__GNUC__) -#define VPX_NO_RETURN __attribute__((noreturn)) -#elif defined(_MSC_VER) -#define VPX_NO_RETURN __declspec(noreturn) -#else -#define VPX_NO_RETURN -#endif - -// Tells the compiler to perform `printf` format string checking if the -// compiler supports it; see the 'format' attribute in -// . -#define VPX_TOOLS_FORMAT_PRINTF(string_index, first_to_check) -#if defined(__has_attribute) -#if __has_attribute(format) -#undef VPX_TOOLS_FORMAT_PRINTF -#define VPX_TOOLS_FORMAT_PRINTF(string_index, first_to_check) \ - __attribute__((__format__(__printf__, string_index, first_to_check))) -#endif -#endif - -/* Sets a stdio stream into binary mode */ -FILE *set_binary_mode(FILE *stream); - -VPX_NO_RETURN void die(const char *fmt, ...) VPX_TOOLS_FORMAT_PRINTF(1, 2); -VPX_NO_RETURN void fatal(const char *fmt, ...) VPX_TOOLS_FORMAT_PRINTF(1, 2); -void warn(const char *fmt, ...) VPX_TOOLS_FORMAT_PRINTF(1, 2); - -VPX_NO_RETURN void die_codec(vpx_codec_ctx_t *ctx, const char *s); - -/* The tool including this file must define usage_exit() */ -VPX_NO_RETURN void usage_exit(void); - -#undef VPX_NO_RETURN - -int read_yuv_frame(struct VpxInputContext *input_ctx, vpx_image_t *yuv_frame); - -typedef struct VpxInterface { - const char *name; - uint32_t fourcc; - vpx_codec_iface_t *(*codec_interface)(void); -} VpxInterface; - -int get_vpx_encoder_count(void); -const VpxInterface *get_vpx_encoder_by_index(int i); -const VpxInterface *get_vpx_encoder_by_name(const char *name); - -int get_vpx_decoder_count(void); -const VpxInterface *get_vpx_decoder_by_index(int i); -const VpxInterface *get_vpx_decoder_by_name(const char *name); -const VpxInterface *get_vpx_decoder_by_fourcc(uint32_t fourcc); - -int vpx_img_plane_width(const vpx_image_t *img, int plane); -int vpx_img_plane_height(const vpx_image_t *img, int plane); -void vpx_img_write(const vpx_image_t *img, FILE *file); -int vpx_img_read(vpx_image_t *img, FILE *file); - -double sse_to_psnr(double samples, double peak, double mse); - -#if CONFIG_ENCODERS -int read_frame(struct VpxInputContext *input_ctx, vpx_image_t *img); -int file_is_y4m(const char detect[4]); -int fourcc_is_ivf(const char detect[4]); -void open_input_file(struct VpxInputContext *input); -void close_input_file(struct VpxInputContext *input); -#endif - -#if CONFIG_VP9_HIGHBITDEPTH -void vpx_img_upshift(vpx_image_t *dst, vpx_image_t *src, int input_shift); -void vpx_img_downshift(vpx_image_t *dst, vpx_image_t *src, int down_shift); -void vpx_img_truncate_16_to_8(vpx_image_t *dst, vpx_image_t *src); -#endif - -int compare_img(const vpx_image_t *const img1, const vpx_image_t *const img2); -#if CONFIG_VP9_HIGHBITDEPTH -void find_mismatch_high(const vpx_image_t *const img1, - const vpx_image_t *const img2, int yloc[4], int uloc[4], - int vloc[4]); -#endif -void find_mismatch(const vpx_image_t *const img1, const vpx_image_t *const img2, - int yloc[4], int uloc[4], int vloc[4]); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif // VPX_TOOLS_COMMON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/usage.dox b/presentation/src/main/cpp/third_party/libvpx/usage.dox deleted file mode 100644 index 88235202..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/usage.dox +++ /dev/null @@ -1,136 +0,0 @@ -/*!\page usage Usage - - The vpx multi-format codec SDK provides a unified interface amongst its - supported codecs. This abstraction allows applications using this SDK to - easily support multiple video formats with minimal code duplication or - "special casing." This section describes the interface common to all codecs. - For codec-specific details, see the \ref codecs page. - - The following sections are common to all codecs: - - \ref usage_types - - \ref usage_features - - \ref usage_init - - \ref usage_errors - - For more information on decoder and encoder specific usage, see the - following pages: - \if decoder - \li \subpage usage_decode - \endif - \if encoder - \li \subpage usage_encode - \endif - - \section usage_types Important Data Types - There are two important data structures to consider in this interface. - - \subsection usage_ctxs Contexts - A context is a storage area allocated by the calling application that the - codec may write into to store details about a single instance of that codec. - Most of the context is implementation specific, and thus opaque to the - application. The context structure as seen by the application is of fixed - size, and thus can be allocated with automatic storage or dynamically - on the heap. - - Most operations require an initialized codec context. Codec context - instances are codec specific. That is, the codec to be used for the encoded - video must be known at initialization time. See #vpx_codec_ctx_t for further - information. - - \subsection usage_ifaces Interfaces - A codec interface is an opaque structure that controls how function calls - into the generic interface are dispatched to their codec-specific - implementations. Applications \ref MUSTNOT attempt to examine or override - this storage, as it contains internal implementation details likely to - change from release to release. - - Each supported codec will expose an interface structure to the application - as an extern reference to a structure of the incomplete type - #vpx_codec_iface_t. - - \section usage_features Features - Several "features" are defined that are optionally implemented by codec - algorithms. Indeed, the same algorithm may support different features on - different platforms. The purpose of defining these features is that when - they are implemented, they conform to a common interface. The features, or - capabilities, of an algorithm can be queried from it's interface by using - the vpx_codec_get_caps() method. Attempts to invoke features not supported - by an algorithm will generally result in #VPX_CODEC_INCAPABLE. - - \if decoder - Currently defined decoder features include: - - \ref usage_cb - - \ref usage_postproc - \endif - - \section usage_init Initialization - To initialize a codec instance, the address of the codec context - and interface structures are passed to an initialization function. Depending - on the \ref usage_features that the codec supports, the codec could be - initialized in different modes. - - To prevent cases of confusion where the ABI of the library changes, - the ABI is versioned. The ABI version number must be passed at - initialization time to ensure the application is using a header file that - matches the library. The current ABI version number is stored in the - preprocessor macros #VPX_CODEC_ABI_VERSION, #VPX_ENCODER_ABI_VERSION, and - #VPX_DECODER_ABI_VERSION. For convenience, each initialization function has - a wrapper macro that inserts the correct version number. These macros are - named like the initialization methods, but without the _ver suffix. - - - The available initialization methods are: - \if encoder - \li #vpx_codec_enc_init (calls vpx_codec_enc_init_ver()) - \li #vpx_codec_enc_init_multi (calls vpx_codec_enc_init_multi_ver()) - \endif - \if decoder - \li #vpx_codec_dec_init (calls vpx_codec_dec_init_ver()) - \endif - - - \section usage_errors Error Handling - Almost all codec functions return an error status of type #vpx_codec_err_t. - The semantics of how each error condition should be processed is clearly - defined in the definitions of each enumerated value. Error values can be - converted into ASCII strings with the vpx_codec_error() and - vpx_codec_err_to_string() methods. The difference between these two methods is - that vpx_codec_error() returns the error state from an initialized context, - whereas vpx_codec_err_to_string() can be used in cases where an error occurs - outside any context. The enumerated value returned from the last call can be - retrieved from the err member of the decoder context as well. - Finally, more detailed error information may be able to be obtained by using - the vpx_codec_error_detail() method. Not all errors produce detailed error - information. - - In addition to error information, the codec library's build configuration - is available at runtime on some platforms. This information can be returned - by calling vpx_codec_build_config(), and is formatted as a base64 coded string - (comprised of characters in the set [a-z_a-Z0-9+/]). This information is not - useful to an application at runtime, but may be of use to vpx for support. - - - \section usage_deadline Deadline - Both the encoding and decoding functions have a deadline - parameter. This parameter indicates the amount of time, in microseconds - (us), that the application wants the codec to spend processing before - returning. This is a soft deadline -- that is, the semantics of the - requested operation take precedence over meeting the deadline. If, for - example, an application sets a deadline of 1000us, and the - frame takes 2000us to decode, the call to vpx_codec_decode() will return - after 2000us. In this case the deadline is not met, but the semantics of the - function are preserved. If, for the same frame, an application instead sets - a deadline of 5000us, the decoder will see that it has 3000us - remaining in its time slice when decoding completes. It could then choose to - run a set of \ref usage_postproc filters, and perhaps would return after - 4000us (instead of the allocated 5000us). In this case the deadline is met, - and the semantics of the call are preserved, as before. - - The special value 0 is reserved to represent an infinite - deadline. In this case, the codec will perform as much processing as - possible to yield the highest quality frame. - - By convention, the value 1 is used to mean "return as fast as - possible." - -*/ diff --git a/presentation/src/main/cpp/third_party/libvpx/usage_cx.dox b/presentation/src/main/cpp/third_party/libvpx/usage_cx.dox deleted file mode 100644 index b2220cfd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/usage_cx.dox +++ /dev/null @@ -1,15 +0,0 @@ -/*! \page usage_encode Encoding - - The vpx_codec_encode() function is at the core of the encode loop. It - processes raw images passed by the application, producing packets of - compressed data. The deadline parameter controls the amount - of time in microseconds the encoder should spend working on the frame. For - more information on the deadline parameter, see - \ref usage_deadline. - - - \if samples - \ref samples - \endif - -*/ diff --git a/presentation/src/main/cpp/third_party/libvpx/usage_dx.dox b/presentation/src/main/cpp/third_party/libvpx/usage_dx.dox deleted file mode 100644 index 85063f70..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/usage_dx.dox +++ /dev/null @@ -1,64 +0,0 @@ -/*! \page usage_decode Decoding - - The vpx_codec_decode() function is at the core of the decode loop. It - processes packets of compressed data passed by the application, producing - decoded images. The decoder expects packets to comprise exactly one image - frame of data. Packets \ref MUST be passed in decode order. If the - application wishes to associate some data with the frame, the - user_priv member may be set. The deadline - parameter controls the amount of time in microseconds the decoder should - spend working on the frame. This is typically used to support adaptive - \ref usage_postproc based on the amount of free CPU time. For more - information on the deadline parameter, see \ref usage_deadline. - - \if samples - \ref samples - \endif - - - \section usage_cb Callback Based Decoding - There are two methods for the application to access decoded frame data. Some - codecs support asynchronous (callback-based) decoding \ref usage_features - that allow the application to register a callback to be invoked by the - decoder when decoded data becomes available. Decoders are not required to - support this feature, however. Like all \ref usage_features, support can be - determined by calling vpx_codec_get_caps(). Callbacks are available in both - frame-based and slice-based variants. Frame based callbacks conform to the - signature of #vpx_codec_put_frame_cb_fn_t and are invoked once the entire - frame has been decoded. Slice based callbacks conform to the signature of - #vpx_codec_put_slice_cb_fn_t and are invoked after a subsection of the frame - is decoded. For example, a slice callback could be issued for each - macroblock row. However, the number and size of slices to return is - implementation specific. Also, the image data passed in a slice callback is - not necessarily in the same memory segment as the data will be when it is - assembled into a full frame. For this reason, the application \ref MUST - examine the rectangles that describe what data is valid to access and what - data has been updated in this call. For all their additional complexity, - slice based decoding callbacks provide substantial speed gains to the - overall application in some cases, due to improved cache behavior. - - - \section usage_frame_iter Frame Iterator Based Decoding - If the codec does not support callback based decoding, or the application - chooses not to make use of that feature, decoded frames are made available - through the vpx_codec_get_frame() iterator. The application initializes the - iterator storage (of type #vpx_codec_iter_t) to NULL, then calls - vpx_codec_get_frame repeatedly until it returns NULL, indicating that all - images have been returned. This process may result in zero, one, or many - frames that are ready for display, depending on the codec. - - - \section usage_postproc Postprocessing - Postprocessing is a process that is applied after a frame is decoded to - enhance the image's appearance by removing artifacts introduced in the - compression process. It is not required to properly decode the frame, and - is generally done only when there is enough spare CPU time to execute - the required filters. Codecs may support a number of different - postprocessing filters, and the available filters may differ from platform - to platform. Embedded devices often do not have enough CPU to implement - postprocessing in software. The filter selection is generally handled - automatically by the codec, depending on the amount of time remaining before - hitting the user-specified \ref usage_deadline after decoding the frame. - - -*/ diff --git a/presentation/src/main/cpp/third_party/libvpx/video_common.h b/presentation/src/main/cpp/third_party/libvpx/video_common.h deleted file mode 100644 index 77eb9fac..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/video_common.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VIDEO_COMMON_H_ -#define VPX_VIDEO_COMMON_H_ - -#include "./tools_common.h" - -typedef struct { - uint32_t codec_fourcc; - int frame_width; - int frame_height; - struct VpxRational time_base; -} VpxVideoInfo; - -#endif // VPX_VIDEO_COMMON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/video_reader.c b/presentation/src/main/cpp/third_party/libvpx/video_reader.c deleted file mode 100644 index 16822eff..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/video_reader.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./ivfdec.h" -#include "./video_reader.h" - -#include "vpx_ports/mem_ops.h" - -static const char *const kIVFSignature = "DKIF"; - -struct VpxVideoReaderStruct { - VpxVideoInfo info; - FILE *file; - uint8_t *buffer; - size_t buffer_size; - size_t frame_size; -}; - -VpxVideoReader *vpx_video_reader_open(const char *filename) { - char header[32]; - VpxVideoReader *reader = NULL; - FILE *const file = fopen(filename, "rb"); - if (!file) { - fprintf(stderr, "%s can't be opened.\n", filename); // Can't open file - return NULL; - } - - if (fread(header, 1, 32, file) != 32) { - fprintf(stderr, "File header on %s can't be read.\n", - filename); // Can't read file header - return NULL; - } - if (memcmp(kIVFSignature, header, 4) != 0) { - fprintf(stderr, "The IVF signature on %s is wrong.\n", - filename); // Wrong IVF signature - - return NULL; - } - if (mem_get_le16(header + 4) != 0) { - fprintf(stderr, "%s uses the wrong IVF version.\n", - filename); // Wrong IVF version - - return NULL; - } - - reader = calloc(1, sizeof(*reader)); - if (!reader) { - fprintf( - stderr, - "Can't allocate VpxVideoReader\n"); // Can't allocate VpxVideoReader - - return NULL; - } - - reader->file = file; - reader->info.codec_fourcc = mem_get_le32(header + 8); - reader->info.frame_width = mem_get_le16(header + 12); - reader->info.frame_height = mem_get_le16(header + 14); - reader->info.time_base.numerator = mem_get_le32(header + 16); - reader->info.time_base.denominator = mem_get_le32(header + 20); - - return reader; -} - -void vpx_video_reader_close(VpxVideoReader *reader) { - if (reader) { - fclose(reader->file); - free(reader->buffer); - free(reader); - } -} - -int vpx_video_reader_read_frame(VpxVideoReader *reader) { - return !ivf_read_frame(reader->file, &reader->buffer, &reader->frame_size, - &reader->buffer_size); -} - -const uint8_t *vpx_video_reader_get_frame(VpxVideoReader *reader, - size_t *size) { - if (size) *size = reader->frame_size; - - return reader->buffer; -} - -const VpxVideoInfo *vpx_video_reader_get_info(VpxVideoReader *reader) { - return &reader->info; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/video_reader.h b/presentation/src/main/cpp/third_party/libvpx/video_reader.h deleted file mode 100644 index 1f5c8088..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/video_reader.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VIDEO_READER_H_ -#define VPX_VIDEO_READER_H_ - -#include "./video_common.h" - -// The following code is work in progress. It is going to support transparent -// reading of input files. Right now only IVF format is supported for -// simplicity. The main goal the API is to be simple and easy to use in example -// code and in vpxenc/vpxdec later. All low-level details like memory -// buffer management are hidden from API users. -struct VpxVideoReaderStruct; -typedef struct VpxVideoReaderStruct VpxVideoReader; - -#ifdef __cplusplus -extern "C" { -#endif - -// Opens the input file for reading and inspects it to determine file type. -// Returns an opaque VpxVideoReader* upon success, or NULL upon failure. -// Right now only IVF format is supported. -VpxVideoReader *vpx_video_reader_open(const char *filename); - -// Frees all resources associated with VpxVideoReader* returned from -// vpx_video_reader_open() call. -void vpx_video_reader_close(VpxVideoReader *reader); - -// Reads frame from the file and stores it in internal buffer. -int vpx_video_reader_read_frame(VpxVideoReader *reader); - -// Returns the pointer to memory buffer with frame data read by last call to -// vpx_video_reader_read_frame(). -const uint8_t *vpx_video_reader_get_frame(VpxVideoReader *reader, size_t *size); - -// Fills VpxVideoInfo with information from opened video file. -const VpxVideoInfo *vpx_video_reader_get_info(VpxVideoReader *reader); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VIDEO_READER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/video_writer.c b/presentation/src/main/cpp/third_party/libvpx/video_writer.c deleted file mode 100644 index 6e9a848b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/video_writer.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./ivfenc.h" -#include "./video_writer.h" -#include "vpx/vpx_encoder.h" - -struct VpxVideoWriterStruct { - VpxVideoInfo info; - FILE *file; - int frame_count; -}; - -static void write_header(FILE *file, const VpxVideoInfo *info, - int frame_count) { - struct vpx_codec_enc_cfg cfg; - cfg.g_w = info->frame_width; - cfg.g_h = info->frame_height; - cfg.g_timebase.num = info->time_base.numerator; - cfg.g_timebase.den = info->time_base.denominator; - - ivf_write_file_header(file, &cfg, info->codec_fourcc, frame_count); -} - -VpxVideoWriter *vpx_video_writer_open(const char *filename, - VpxContainer container, - const VpxVideoInfo *info) { - if (container == kContainerIVF) { - VpxVideoWriter *writer = NULL; - FILE *const file = fopen(filename, "wb"); - if (!file) { - fprintf(stderr, "%s can't be written to.\n", filename); - return NULL; - } - writer = malloc(sizeof(*writer)); - if (!writer) { - fprintf(stderr, "Can't allocate VpxVideoWriter.\n"); - return NULL; - } - writer->frame_count = 0; - writer->info = *info; - writer->file = file; - - write_header(writer->file, info, 0); - - return writer; - } - fprintf(stderr, "VpxVideoWriter supports only IVF.\n"); - return NULL; -} - -void vpx_video_writer_close(VpxVideoWriter *writer) { - if (writer) { - // Rewriting frame header with real frame count - rewind(writer->file); - write_header(writer->file, &writer->info, writer->frame_count); - - fclose(writer->file); - free(writer); - } -} - -int vpx_video_writer_write_frame(VpxVideoWriter *writer, const uint8_t *buffer, - size_t size, int64_t pts) { - ivf_write_frame_header(writer->file, pts, size); - if (fwrite(buffer, 1, size, writer->file) != size) return 0; - - ++writer->frame_count; - - return 1; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/video_writer.h b/presentation/src/main/cpp/third_party/libvpx/video_writer.h deleted file mode 100644 index b4d242b9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/video_writer.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VIDEO_WRITER_H_ -#define VPX_VIDEO_WRITER_H_ - -#include "./video_common.h" - -typedef enum { kContainerIVF } VpxContainer; - -struct VpxVideoWriterStruct; -typedef struct VpxVideoWriterStruct VpxVideoWriter; - -#ifdef __cplusplus -extern "C" { -#endif - -// Finds and opens writer for specified container format. -// Returns an opaque VpxVideoWriter* upon success, or NULL upon failure. -// Right now only IVF format is supported. -VpxVideoWriter *vpx_video_writer_open(const char *filename, - VpxContainer container, - const VpxVideoInfo *info); - -// Frees all resources associated with VpxVideoWriter* returned from -// vpx_video_writer_open() call. -void vpx_video_writer_close(VpxVideoWriter *writer); - -// Writes frame bytes to the file. -int vpx_video_writer_write_frame(VpxVideoWriter *writer, const uint8_t *buffer, - size_t size, int64_t pts); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VIDEO_WRITER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/alloccommon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/alloccommon.c deleted file mode 100644 index 722b158c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/alloccommon.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "alloccommon.h" -#include "blockd.h" -#include "vpx_mem/vpx_mem.h" -#include "onyxc_int.h" -#include "findnearmv.h" -#include "entropymode.h" -#include "systemdependent.h" - -void vp8_de_alloc_frame_buffers(VP8_COMMON *oci) { - int i; - for (i = 0; i < NUM_YV12_BUFFERS; ++i) { - vp8_yv12_de_alloc_frame_buffer(&oci->yv12_fb[i]); - } - - vp8_yv12_de_alloc_frame_buffer(&oci->temp_scale_frame); -#if CONFIG_POSTPROC - vp8_yv12_de_alloc_frame_buffer(&oci->post_proc_buffer); - if (oci->post_proc_buffer_int_used) { - vp8_yv12_de_alloc_frame_buffer(&oci->post_proc_buffer_int); - } - - vpx_free(oci->pp_limits_buffer); - oci->pp_limits_buffer = NULL; - - vpx_free(oci->postproc_state.generated_noise); - oci->postproc_state.generated_noise = NULL; -#endif - - vpx_free(oci->above_context); - vpx_free(oci->mip); -#if CONFIG_ERROR_CONCEALMENT - vpx_free(oci->prev_mip); - oci->prev_mip = NULL; -#endif - - oci->above_context = NULL; - oci->mip = NULL; -} - -int vp8_alloc_frame_buffers(VP8_COMMON *oci, int width, int height) { - int i; - - vp8_de_alloc_frame_buffers(oci); - - /* our internal buffers are always multiples of 16 */ - if ((width & 0xf) != 0) width += 16 - (width & 0xf); - - if ((height & 0xf) != 0) height += 16 - (height & 0xf); - - for (i = 0; i < NUM_YV12_BUFFERS; ++i) { - oci->fb_idx_ref_cnt[i] = 0; - oci->yv12_fb[i].flags = 0; - if (vp8_yv12_alloc_frame_buffer(&oci->yv12_fb[i], width, height, - VP8BORDERINPIXELS) < 0) { - goto allocation_fail; - } - } - - oci->new_fb_idx = 0; - oci->lst_fb_idx = 1; - oci->gld_fb_idx = 2; - oci->alt_fb_idx = 3; - - oci->fb_idx_ref_cnt[0] = 1; - oci->fb_idx_ref_cnt[1] = 1; - oci->fb_idx_ref_cnt[2] = 1; - oci->fb_idx_ref_cnt[3] = 1; - - if (vp8_yv12_alloc_frame_buffer(&oci->temp_scale_frame, width, 16, - VP8BORDERINPIXELS) < 0) { - goto allocation_fail; - } - - oci->mb_rows = height >> 4; - oci->mb_cols = width >> 4; - oci->MBs = oci->mb_rows * oci->mb_cols; - oci->mode_info_stride = oci->mb_cols + 1; - oci->mip = - vpx_calloc((oci->mb_cols + 1) * (oci->mb_rows + 1), sizeof(MODE_INFO)); - - if (!oci->mip) goto allocation_fail; - - oci->mi = oci->mip + oci->mode_info_stride + 1; - - /* Allocation of previous mode info will be done in vp8_decode_frame() - * as it is a decoder only data */ - - oci->above_context = - vpx_calloc(sizeof(ENTROPY_CONTEXT_PLANES) * oci->mb_cols, 1); - - if (!oci->above_context) goto allocation_fail; - -#if CONFIG_POSTPROC - if (vp8_yv12_alloc_frame_buffer(&oci->post_proc_buffer, width, height, - VP8BORDERINPIXELS) < 0) { - goto allocation_fail; - } - - oci->post_proc_buffer_int_used = 0; - memset(&oci->postproc_state, 0, sizeof(oci->postproc_state)); - memset(oci->post_proc_buffer.buffer_alloc, 128, - oci->post_proc_buffer.frame_size); - - /* Allocate buffer to store post-processing filter coefficients. - * - * Note: Round up mb_cols to support SIMD reads - */ - oci->pp_limits_buffer = vpx_memalign(16, 24 * ((oci->mb_cols + 1) & ~1)); - if (!oci->pp_limits_buffer) goto allocation_fail; -#endif - - return 0; - -allocation_fail: - vp8_de_alloc_frame_buffers(oci); - return 1; -} - -void vp8_setup_version(VP8_COMMON *cm) { - switch (cm->version) { - case 0: - cm->no_lpf = 0; - cm->filter_type = NORMAL_LOOPFILTER; - cm->use_bilinear_mc_filter = 0; - cm->full_pixel = 0; - break; - case 1: - cm->no_lpf = 0; - cm->filter_type = SIMPLE_LOOPFILTER; - cm->use_bilinear_mc_filter = 1; - cm->full_pixel = 0; - break; - case 2: - cm->no_lpf = 1; - cm->filter_type = NORMAL_LOOPFILTER; - cm->use_bilinear_mc_filter = 1; - cm->full_pixel = 0; - break; - case 3: - cm->no_lpf = 1; - cm->filter_type = SIMPLE_LOOPFILTER; - cm->use_bilinear_mc_filter = 1; - cm->full_pixel = 1; - break; - default: - /*4,5,6,7 are reserved for future use*/ - cm->no_lpf = 0; - cm->filter_type = NORMAL_LOOPFILTER; - cm->use_bilinear_mc_filter = 0; - cm->full_pixel = 0; - break; - } -} -void vp8_create_common(VP8_COMMON *oci) { - vp8_machine_specific_config(oci); - - vp8_init_mbmode_probs(oci); - vp8_default_bmode_probs(oci->fc.bmode_prob); - - oci->mb_no_coeff_skip = 1; - oci->no_lpf = 0; - oci->filter_type = NORMAL_LOOPFILTER; - oci->use_bilinear_mc_filter = 0; - oci->full_pixel = 0; - oci->multi_token_partition = ONE_PARTITION; - oci->clamp_type = RECON_CLAMP_REQUIRED; - - /* Initialize reference frame sign bias structure to defaults */ - memset(oci->ref_frame_sign_bias, 0, sizeof(oci->ref_frame_sign_bias)); - - /* Default disable buffer to buffer copying */ - oci->copy_buffer_to_gf = 0; - oci->copy_buffer_to_arf = 0; -} - -void vp8_remove_common(VP8_COMMON *oci) { vp8_de_alloc_frame_buffers(oci); } diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/alloccommon.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/alloccommon.h deleted file mode 100644 index 2d376bba..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/alloccommon.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_ALLOCCOMMON_H_ -#define VPX_VP8_COMMON_ALLOCCOMMON_H_ - -#include "onyxc_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vp8_create_common(VP8_COMMON *oci); -void vp8_remove_common(VP8_COMMON *oci); -void vp8_de_alloc_frame_buffers(VP8_COMMON *oci); -int vp8_alloc_frame_buffers(VP8_COMMON *oci, int width, int height); -void vp8_setup_version(VP8_COMMON *cm); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_ALLOCCOMMON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/loopfilter_arm.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/loopfilter_arm.c deleted file mode 100644 index 48a19720..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/loopfilter_arm.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "./vp8_rtcd.h" -#include "vp8/common/arm/loopfilter_arm.h" -#include "vp8/common/loopfilter.h" -#include "vp8/common/onyxc_int.h" - -/* NEON loopfilter functions */ -/* Horizontal MB filtering */ -void vp8_loop_filter_mbh_neon(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { - unsigned char mblim = *lfi->mblim; - unsigned char lim = *lfi->lim; - unsigned char hev_thr = *lfi->hev_thr; - vp8_mbloop_filter_horizontal_edge_y_neon(y_ptr, y_stride, mblim, lim, - hev_thr); - - if (u_ptr) - vp8_mbloop_filter_horizontal_edge_uv_neon(u_ptr, uv_stride, mblim, lim, - hev_thr, v_ptr); -} - -/* Vertical MB Filtering */ -void vp8_loop_filter_mbv_neon(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { - unsigned char mblim = *lfi->mblim; - unsigned char lim = *lfi->lim; - unsigned char hev_thr = *lfi->hev_thr; - - vp8_mbloop_filter_vertical_edge_y_neon(y_ptr, y_stride, mblim, lim, hev_thr); - - if (u_ptr) - vp8_mbloop_filter_vertical_edge_uv_neon(u_ptr, uv_stride, mblim, lim, - hev_thr, v_ptr); -} - -/* Horizontal B Filtering */ -void vp8_loop_filter_bh_neon(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { - unsigned char blim = *lfi->blim; - unsigned char lim = *lfi->lim; - unsigned char hev_thr = *lfi->hev_thr; - - vp8_loop_filter_horizontal_edge_y_neon(y_ptr + 4 * y_stride, y_stride, blim, - lim, hev_thr); - vp8_loop_filter_horizontal_edge_y_neon(y_ptr + 8 * y_stride, y_stride, blim, - lim, hev_thr); - vp8_loop_filter_horizontal_edge_y_neon(y_ptr + 12 * y_stride, y_stride, blim, - lim, hev_thr); - - if (u_ptr) - vp8_loop_filter_horizontal_edge_uv_neon(u_ptr + 4 * uv_stride, uv_stride, - blim, lim, hev_thr, - v_ptr + 4 * uv_stride); -} - -/* Vertical B Filtering */ -void vp8_loop_filter_bv_neon(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { - unsigned char blim = *lfi->blim; - unsigned char lim = *lfi->lim; - unsigned char hev_thr = *lfi->hev_thr; - - vp8_loop_filter_vertical_edge_y_neon(y_ptr + 4, y_stride, blim, lim, hev_thr); - vp8_loop_filter_vertical_edge_y_neon(y_ptr + 8, y_stride, blim, lim, hev_thr); - vp8_loop_filter_vertical_edge_y_neon(y_ptr + 12, y_stride, blim, lim, - hev_thr); - - if (u_ptr) - vp8_loop_filter_vertical_edge_uv_neon(u_ptr + 4, uv_stride, blim, lim, - hev_thr, v_ptr + 4); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/loopfilter_arm.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/loopfilter_arm.h deleted file mode 100644 index 6cf660d2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/loopfilter_arm.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2019 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_ARM_LOOPFILTER_ARM_H_ -#define VPX_VP8_COMMON_ARM_LOOPFILTER_ARM_H_ - -typedef void loopfilter_y_neon(unsigned char *src, int pitch, - unsigned char blimit, unsigned char limit, - unsigned char thresh); -typedef void loopfilter_uv_neon(unsigned char *u, int pitch, - unsigned char blimit, unsigned char limit, - unsigned char thresh, unsigned char *v); - -loopfilter_y_neon vp8_loop_filter_horizontal_edge_y_neon; -loopfilter_y_neon vp8_loop_filter_vertical_edge_y_neon; -loopfilter_uv_neon vp8_loop_filter_horizontal_edge_uv_neon; -loopfilter_uv_neon vp8_loop_filter_vertical_edge_uv_neon; - -loopfilter_y_neon vp8_mbloop_filter_horizontal_edge_y_neon; -loopfilter_y_neon vp8_mbloop_filter_vertical_edge_y_neon; -loopfilter_uv_neon vp8_mbloop_filter_horizontal_edge_uv_neon; -loopfilter_uv_neon vp8_mbloop_filter_vertical_edge_uv_neon; - -#endif // VPX_VP8_COMMON_ARM_LOOPFILTER_ARM_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/bilinearpredict_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/bilinearpredict_neon.c deleted file mode 100644 index 590956dd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/bilinearpredict_neon.c +++ /dev/null @@ -1,764 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vp8_rtcd.h" -#include "vpx_dsp/arm/mem_neon.h" - -static const uint8_t bifilter4_coeff[8][2] = { { 128, 0 }, { 112, 16 }, - { 96, 32 }, { 80, 48 }, - { 64, 64 }, { 48, 80 }, - { 32, 96 }, { 16, 112 } }; - -static INLINE uint8x8_t load_and_shift(const unsigned char *a) { - return vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(vld1_u8(a)), 32)); -} - -void vp8_bilinear_predict4x4_neon(unsigned char *src_ptr, - int src_pixels_per_line, int xoffset, - int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - uint8x8_t e0, e1, e2; - - if (xoffset == 0) { // skip_1stpass_filter - uint8x8_t a0, a1, a2, a3, a4; - - a0 = load_and_shift(src_ptr); - src_ptr += src_pixels_per_line; - a1 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - a2 = load_and_shift(src_ptr); - src_ptr += src_pixels_per_line; - a3 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - a4 = vld1_u8(src_ptr); - - e0 = vext_u8(a0, a1, 4); - e1 = vext_u8(a2, a3, 4); - e2 = a4; - } else { - uint8x8_t a0, a1, a2, a3, a4, b4; - uint8x16_t a01, a23; - uint8x16_t b01, b23; - uint32x2x2_t c0, c1, c2, c3; - uint16x8_t d0, d1, d2; - const uint8x8_t filter0 = vdup_n_u8(bifilter4_coeff[xoffset][0]); - const uint8x8_t filter1 = vdup_n_u8(bifilter4_coeff[xoffset][1]); - - a0 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - a1 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - a2 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - a3 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - a4 = vld1_u8(src_ptr); - - a01 = vcombine_u8(a0, a1); - a23 = vcombine_u8(a2, a3); - - b01 = vreinterpretq_u8_u64(vshrq_n_u64(vreinterpretq_u64_u8(a01), 8)); - b23 = vreinterpretq_u8_u64(vshrq_n_u64(vreinterpretq_u64_u8(a23), 8)); - b4 = vreinterpret_u8_u64(vshr_n_u64(vreinterpret_u64_u8(a4), 8)); - - c0 = vzip_u32(vreinterpret_u32_u8(vget_low_u8(a01)), - vreinterpret_u32_u8(vget_high_u8(a01))); - c1 = vzip_u32(vreinterpret_u32_u8(vget_low_u8(a23)), - vreinterpret_u32_u8(vget_high_u8(a23))); - c2 = vzip_u32(vreinterpret_u32_u8(vget_low_u8(b01)), - vreinterpret_u32_u8(vget_high_u8(b01))); - c3 = vzip_u32(vreinterpret_u32_u8(vget_low_u8(b23)), - vreinterpret_u32_u8(vget_high_u8(b23))); - - d0 = vmull_u8(vreinterpret_u8_u32(c0.val[0]), filter0); - d1 = vmull_u8(vreinterpret_u8_u32(c1.val[0]), filter0); - d2 = vmull_u8(a4, filter0); - - d0 = vmlal_u8(d0, vreinterpret_u8_u32(c2.val[0]), filter1); - d1 = vmlal_u8(d1, vreinterpret_u8_u32(c3.val[0]), filter1); - d2 = vmlal_u8(d2, b4, filter1); - - e0 = vqrshrn_n_u16(d0, 7); - e1 = vqrshrn_n_u16(d1, 7); - e2 = vqrshrn_n_u16(d2, 7); - } - - // secondpass_filter - if (yoffset == 0) { // skip_2ndpass_filter - store_unaligned_u8q(dst_ptr, dst_pitch, vcombine_u8(e0, e1)); - } else { - uint8x8_t f0, f1; - const uint8x8_t filter0 = vdup_n_u8(bifilter4_coeff[yoffset][0]); - const uint8x8_t filter1 = vdup_n_u8(bifilter4_coeff[yoffset][1]); - - uint16x8_t b0 = vmull_u8(e0, filter0); - uint16x8_t b1 = vmull_u8(e1, filter0); - - const uint8x8_t a0 = vext_u8(e0, e1, 4); - const uint8x8_t a1 = vext_u8(e1, e2, 4); - - b0 = vmlal_u8(b0, a0, filter1); - b1 = vmlal_u8(b1, a1, filter1); - - f0 = vqrshrn_n_u16(b0, 7); - f1 = vqrshrn_n_u16(b1, 7); - - store_unaligned_u8q(dst_ptr, dst_pitch, vcombine_u8(f0, f1)); - } -} - -void vp8_bilinear_predict8x4_neon(unsigned char *src_ptr, - int src_pixels_per_line, int xoffset, - int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - uint8x8_t d0u8, d1u8, d2u8, d3u8, d4u8, d5u8; - uint8x8_t d7u8, d9u8, d11u8, d22u8, d23u8, d24u8, d25u8, d26u8; - uint8x16_t q1u8, q2u8, q3u8, q4u8, q5u8; - uint16x8_t q1u16, q2u16, q3u16, q4u16; - uint16x8_t q6u16, q7u16, q8u16, q9u16, q10u16; - - if (xoffset == 0) { // skip_1stpass_filter - d22u8 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - d23u8 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - d24u8 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - d25u8 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - d26u8 = vld1_u8(src_ptr); - } else { - q1u8 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - q2u8 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - q3u8 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - q4u8 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - q5u8 = vld1q_u8(src_ptr); - - d0u8 = vdup_n_u8(bifilter4_coeff[xoffset][0]); - d1u8 = vdup_n_u8(bifilter4_coeff[xoffset][1]); - - q6u16 = vmull_u8(vget_low_u8(q1u8), d0u8); - q7u16 = vmull_u8(vget_low_u8(q2u8), d0u8); - q8u16 = vmull_u8(vget_low_u8(q3u8), d0u8); - q9u16 = vmull_u8(vget_low_u8(q4u8), d0u8); - q10u16 = vmull_u8(vget_low_u8(q5u8), d0u8); - - d3u8 = vext_u8(vget_low_u8(q1u8), vget_high_u8(q1u8), 1); - d5u8 = vext_u8(vget_low_u8(q2u8), vget_high_u8(q2u8), 1); - d7u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 1); - d9u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 1); - d11u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 1); - - q6u16 = vmlal_u8(q6u16, d3u8, d1u8); - q7u16 = vmlal_u8(q7u16, d5u8, d1u8); - q8u16 = vmlal_u8(q8u16, d7u8, d1u8); - q9u16 = vmlal_u8(q9u16, d9u8, d1u8); - q10u16 = vmlal_u8(q10u16, d11u8, d1u8); - - d22u8 = vqrshrn_n_u16(q6u16, 7); - d23u8 = vqrshrn_n_u16(q7u16, 7); - d24u8 = vqrshrn_n_u16(q8u16, 7); - d25u8 = vqrshrn_n_u16(q9u16, 7); - d26u8 = vqrshrn_n_u16(q10u16, 7); - } - - // secondpass_filter - if (yoffset == 0) { // skip_2ndpass_filter - vst1_u8((uint8_t *)dst_ptr, d22u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d23u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d24u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d25u8); - } else { - d0u8 = vdup_n_u8(bifilter4_coeff[yoffset][0]); - d1u8 = vdup_n_u8(bifilter4_coeff[yoffset][1]); - - q1u16 = vmull_u8(d22u8, d0u8); - q2u16 = vmull_u8(d23u8, d0u8); - q3u16 = vmull_u8(d24u8, d0u8); - q4u16 = vmull_u8(d25u8, d0u8); - - q1u16 = vmlal_u8(q1u16, d23u8, d1u8); - q2u16 = vmlal_u8(q2u16, d24u8, d1u8); - q3u16 = vmlal_u8(q3u16, d25u8, d1u8); - q4u16 = vmlal_u8(q4u16, d26u8, d1u8); - - d2u8 = vqrshrn_n_u16(q1u16, 7); - d3u8 = vqrshrn_n_u16(q2u16, 7); - d4u8 = vqrshrn_n_u16(q3u16, 7); - d5u8 = vqrshrn_n_u16(q4u16, 7); - - vst1_u8((uint8_t *)dst_ptr, d2u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d3u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d4u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d5u8); - } - return; -} - -void vp8_bilinear_predict8x8_neon(unsigned char *src_ptr, - int src_pixels_per_line, int xoffset, - int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - uint8x8_t d0u8, d1u8, d2u8, d3u8, d4u8, d5u8, d6u8, d7u8, d8u8, d9u8, d11u8; - uint8x8_t d22u8, d23u8, d24u8, d25u8, d26u8, d27u8, d28u8, d29u8, d30u8; - uint8x16_t q1u8, q2u8, q3u8, q4u8, q5u8; - uint16x8_t q1u16, q2u16, q3u16, q4u16, q5u16; - uint16x8_t q6u16, q7u16, q8u16, q9u16, q10u16; - - if (xoffset == 0) { // skip_1stpass_filter - d22u8 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - d23u8 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - d24u8 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - d25u8 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - d26u8 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - d27u8 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - d28u8 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - d29u8 = vld1_u8(src_ptr); - src_ptr += src_pixels_per_line; - d30u8 = vld1_u8(src_ptr); - } else { - q1u8 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - q2u8 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - q3u8 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - q4u8 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - - d0u8 = vdup_n_u8(bifilter4_coeff[xoffset][0]); - d1u8 = vdup_n_u8(bifilter4_coeff[xoffset][1]); - - q6u16 = vmull_u8(vget_low_u8(q1u8), d0u8); - q7u16 = vmull_u8(vget_low_u8(q2u8), d0u8); - q8u16 = vmull_u8(vget_low_u8(q3u8), d0u8); - q9u16 = vmull_u8(vget_low_u8(q4u8), d0u8); - - d3u8 = vext_u8(vget_low_u8(q1u8), vget_high_u8(q1u8), 1); - d5u8 = vext_u8(vget_low_u8(q2u8), vget_high_u8(q2u8), 1); - d7u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 1); - d9u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 1); - - q6u16 = vmlal_u8(q6u16, d3u8, d1u8); - q7u16 = vmlal_u8(q7u16, d5u8, d1u8); - q8u16 = vmlal_u8(q8u16, d7u8, d1u8); - q9u16 = vmlal_u8(q9u16, d9u8, d1u8); - - d22u8 = vqrshrn_n_u16(q6u16, 7); - d23u8 = vqrshrn_n_u16(q7u16, 7); - d24u8 = vqrshrn_n_u16(q8u16, 7); - d25u8 = vqrshrn_n_u16(q9u16, 7); - - // first_pass filtering on the rest 5-line data - q1u8 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - q2u8 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - q3u8 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - q4u8 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - q5u8 = vld1q_u8(src_ptr); - - q6u16 = vmull_u8(vget_low_u8(q1u8), d0u8); - q7u16 = vmull_u8(vget_low_u8(q2u8), d0u8); - q8u16 = vmull_u8(vget_low_u8(q3u8), d0u8); - q9u16 = vmull_u8(vget_low_u8(q4u8), d0u8); - q10u16 = vmull_u8(vget_low_u8(q5u8), d0u8); - - d3u8 = vext_u8(vget_low_u8(q1u8), vget_high_u8(q1u8), 1); - d5u8 = vext_u8(vget_low_u8(q2u8), vget_high_u8(q2u8), 1); - d7u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 1); - d9u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 1); - d11u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 1); - - q6u16 = vmlal_u8(q6u16, d3u8, d1u8); - q7u16 = vmlal_u8(q7u16, d5u8, d1u8); - q8u16 = vmlal_u8(q8u16, d7u8, d1u8); - q9u16 = vmlal_u8(q9u16, d9u8, d1u8); - q10u16 = vmlal_u8(q10u16, d11u8, d1u8); - - d26u8 = vqrshrn_n_u16(q6u16, 7); - d27u8 = vqrshrn_n_u16(q7u16, 7); - d28u8 = vqrshrn_n_u16(q8u16, 7); - d29u8 = vqrshrn_n_u16(q9u16, 7); - d30u8 = vqrshrn_n_u16(q10u16, 7); - } - - // secondpass_filter - if (yoffset == 0) { // skip_2ndpass_filter - vst1_u8((uint8_t *)dst_ptr, d22u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d23u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d24u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d25u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d26u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d27u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d28u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d29u8); - } else { - d0u8 = vdup_n_u8(bifilter4_coeff[yoffset][0]); - d1u8 = vdup_n_u8(bifilter4_coeff[yoffset][1]); - - q1u16 = vmull_u8(d22u8, d0u8); - q2u16 = vmull_u8(d23u8, d0u8); - q3u16 = vmull_u8(d24u8, d0u8); - q4u16 = vmull_u8(d25u8, d0u8); - q5u16 = vmull_u8(d26u8, d0u8); - q6u16 = vmull_u8(d27u8, d0u8); - q7u16 = vmull_u8(d28u8, d0u8); - q8u16 = vmull_u8(d29u8, d0u8); - - q1u16 = vmlal_u8(q1u16, d23u8, d1u8); - q2u16 = vmlal_u8(q2u16, d24u8, d1u8); - q3u16 = vmlal_u8(q3u16, d25u8, d1u8); - q4u16 = vmlal_u8(q4u16, d26u8, d1u8); - q5u16 = vmlal_u8(q5u16, d27u8, d1u8); - q6u16 = vmlal_u8(q6u16, d28u8, d1u8); - q7u16 = vmlal_u8(q7u16, d29u8, d1u8); - q8u16 = vmlal_u8(q8u16, d30u8, d1u8); - - d2u8 = vqrshrn_n_u16(q1u16, 7); - d3u8 = vqrshrn_n_u16(q2u16, 7); - d4u8 = vqrshrn_n_u16(q3u16, 7); - d5u8 = vqrshrn_n_u16(q4u16, 7); - d6u8 = vqrshrn_n_u16(q5u16, 7); - d7u8 = vqrshrn_n_u16(q6u16, 7); - d8u8 = vqrshrn_n_u16(q7u16, 7); - d9u8 = vqrshrn_n_u16(q8u16, 7); - - vst1_u8((uint8_t *)dst_ptr, d2u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d3u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d4u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d5u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d6u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d7u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d8u8); - dst_ptr += dst_pitch; - vst1_u8((uint8_t *)dst_ptr, d9u8); - } - return; -} - -void vp8_bilinear_predict16x16_neon(unsigned char *src_ptr, - int src_pixels_per_line, int xoffset, - int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - int i; - unsigned char tmp[272]; - unsigned char *tmpp; - uint8x8_t d0u8, d1u8, d2u8, d3u8, d4u8, d5u8, d6u8, d7u8, d8u8, d9u8; - uint8x8_t d10u8, d11u8, d12u8, d13u8, d14u8, d15u8, d16u8, d17u8, d18u8; - uint8x8_t d19u8, d20u8, d21u8; - uint8x16_t q1u8, q2u8, q3u8, q4u8, q5u8, q6u8, q7u8, q8u8, q9u8, q10u8; - uint8x16_t q11u8, q12u8, q13u8, q14u8, q15u8; - uint16x8_t q1u16, q2u16, q3u16, q4u16, q5u16, q6u16, q7u16, q8u16; - uint16x8_t q9u16, q10u16, q11u16, q12u16, q13u16, q14u16; - - if (xoffset == 0) { // secondpass_bfilter16x16_only - d0u8 = vdup_n_u8(bifilter4_coeff[yoffset][0]); - d1u8 = vdup_n_u8(bifilter4_coeff[yoffset][1]); - - q11u8 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - for (i = 4; i > 0; i--) { - q12u8 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - q13u8 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - q14u8 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - q15u8 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - - q1u16 = vmull_u8(vget_low_u8(q11u8), d0u8); - q2u16 = vmull_u8(vget_high_u8(q11u8), d0u8); - q3u16 = vmull_u8(vget_low_u8(q12u8), d0u8); - q4u16 = vmull_u8(vget_high_u8(q12u8), d0u8); - q5u16 = vmull_u8(vget_low_u8(q13u8), d0u8); - q6u16 = vmull_u8(vget_high_u8(q13u8), d0u8); - q7u16 = vmull_u8(vget_low_u8(q14u8), d0u8); - q8u16 = vmull_u8(vget_high_u8(q14u8), d0u8); - - q1u16 = vmlal_u8(q1u16, vget_low_u8(q12u8), d1u8); - q2u16 = vmlal_u8(q2u16, vget_high_u8(q12u8), d1u8); - q3u16 = vmlal_u8(q3u16, vget_low_u8(q13u8), d1u8); - q4u16 = vmlal_u8(q4u16, vget_high_u8(q13u8), d1u8); - q5u16 = vmlal_u8(q5u16, vget_low_u8(q14u8), d1u8); - q6u16 = vmlal_u8(q6u16, vget_high_u8(q14u8), d1u8); - q7u16 = vmlal_u8(q7u16, vget_low_u8(q15u8), d1u8); - q8u16 = vmlal_u8(q8u16, vget_high_u8(q15u8), d1u8); - - d2u8 = vqrshrn_n_u16(q1u16, 7); - d3u8 = vqrshrn_n_u16(q2u16, 7); - d4u8 = vqrshrn_n_u16(q3u16, 7); - d5u8 = vqrshrn_n_u16(q4u16, 7); - d6u8 = vqrshrn_n_u16(q5u16, 7); - d7u8 = vqrshrn_n_u16(q6u16, 7); - d8u8 = vqrshrn_n_u16(q7u16, 7); - d9u8 = vqrshrn_n_u16(q8u16, 7); - - q1u8 = vcombine_u8(d2u8, d3u8); - q2u8 = vcombine_u8(d4u8, d5u8); - q3u8 = vcombine_u8(d6u8, d7u8); - q4u8 = vcombine_u8(d8u8, d9u8); - - q11u8 = q15u8; - - vst1q_u8((uint8_t *)dst_ptr, q1u8); - dst_ptr += dst_pitch; - vst1q_u8((uint8_t *)dst_ptr, q2u8); - dst_ptr += dst_pitch; - vst1q_u8((uint8_t *)dst_ptr, q3u8); - dst_ptr += dst_pitch; - vst1q_u8((uint8_t *)dst_ptr, q4u8); - dst_ptr += dst_pitch; - } - return; - } - - if (yoffset == 0) { // firstpass_bfilter16x16_only - d0u8 = vdup_n_u8(bifilter4_coeff[xoffset][0]); - d1u8 = vdup_n_u8(bifilter4_coeff[xoffset][1]); - - for (i = 4; i > 0; i--) { - d2u8 = vld1_u8(src_ptr); - d3u8 = vld1_u8(src_ptr + 8); - d4u8 = vld1_u8(src_ptr + 16); - src_ptr += src_pixels_per_line; - d5u8 = vld1_u8(src_ptr); - d6u8 = vld1_u8(src_ptr + 8); - d7u8 = vld1_u8(src_ptr + 16); - src_ptr += src_pixels_per_line; - d8u8 = vld1_u8(src_ptr); - d9u8 = vld1_u8(src_ptr + 8); - d10u8 = vld1_u8(src_ptr + 16); - src_ptr += src_pixels_per_line; - d11u8 = vld1_u8(src_ptr); - d12u8 = vld1_u8(src_ptr + 8); - d13u8 = vld1_u8(src_ptr + 16); - src_ptr += src_pixels_per_line; - - q7u16 = vmull_u8(d2u8, d0u8); - q8u16 = vmull_u8(d3u8, d0u8); - q9u16 = vmull_u8(d5u8, d0u8); - q10u16 = vmull_u8(d6u8, d0u8); - q11u16 = vmull_u8(d8u8, d0u8); - q12u16 = vmull_u8(d9u8, d0u8); - q13u16 = vmull_u8(d11u8, d0u8); - q14u16 = vmull_u8(d12u8, d0u8); - - d2u8 = vext_u8(d2u8, d3u8, 1); - d5u8 = vext_u8(d5u8, d6u8, 1); - d8u8 = vext_u8(d8u8, d9u8, 1); - d11u8 = vext_u8(d11u8, d12u8, 1); - - q7u16 = vmlal_u8(q7u16, d2u8, d1u8); - q9u16 = vmlal_u8(q9u16, d5u8, d1u8); - q11u16 = vmlal_u8(q11u16, d8u8, d1u8); - q13u16 = vmlal_u8(q13u16, d11u8, d1u8); - - d3u8 = vext_u8(d3u8, d4u8, 1); - d6u8 = vext_u8(d6u8, d7u8, 1); - d9u8 = vext_u8(d9u8, d10u8, 1); - d12u8 = vext_u8(d12u8, d13u8, 1); - - q8u16 = vmlal_u8(q8u16, d3u8, d1u8); - q10u16 = vmlal_u8(q10u16, d6u8, d1u8); - q12u16 = vmlal_u8(q12u16, d9u8, d1u8); - q14u16 = vmlal_u8(q14u16, d12u8, d1u8); - - d14u8 = vqrshrn_n_u16(q7u16, 7); - d15u8 = vqrshrn_n_u16(q8u16, 7); - d16u8 = vqrshrn_n_u16(q9u16, 7); - d17u8 = vqrshrn_n_u16(q10u16, 7); - d18u8 = vqrshrn_n_u16(q11u16, 7); - d19u8 = vqrshrn_n_u16(q12u16, 7); - d20u8 = vqrshrn_n_u16(q13u16, 7); - d21u8 = vqrshrn_n_u16(q14u16, 7); - - q7u8 = vcombine_u8(d14u8, d15u8); - q8u8 = vcombine_u8(d16u8, d17u8); - q9u8 = vcombine_u8(d18u8, d19u8); - q10u8 = vcombine_u8(d20u8, d21u8); - - vst1q_u8((uint8_t *)dst_ptr, q7u8); - dst_ptr += dst_pitch; - vst1q_u8((uint8_t *)dst_ptr, q8u8); - dst_ptr += dst_pitch; - vst1q_u8((uint8_t *)dst_ptr, q9u8); - dst_ptr += dst_pitch; - vst1q_u8((uint8_t *)dst_ptr, q10u8); - dst_ptr += dst_pitch; - } - return; - } - - d0u8 = vdup_n_u8(bifilter4_coeff[xoffset][0]); - d1u8 = vdup_n_u8(bifilter4_coeff[xoffset][1]); - - d2u8 = vld1_u8(src_ptr); - d3u8 = vld1_u8(src_ptr + 8); - d4u8 = vld1_u8(src_ptr + 16); - src_ptr += src_pixels_per_line; - d5u8 = vld1_u8(src_ptr); - d6u8 = vld1_u8(src_ptr + 8); - d7u8 = vld1_u8(src_ptr + 16); - src_ptr += src_pixels_per_line; - d8u8 = vld1_u8(src_ptr); - d9u8 = vld1_u8(src_ptr + 8); - d10u8 = vld1_u8(src_ptr + 16); - src_ptr += src_pixels_per_line; - d11u8 = vld1_u8(src_ptr); - d12u8 = vld1_u8(src_ptr + 8); - d13u8 = vld1_u8(src_ptr + 16); - src_ptr += src_pixels_per_line; - - // First Pass: output_height lines x output_width columns (17x16) - tmpp = tmp; - for (i = 3; i > 0; i--) { - q7u16 = vmull_u8(d2u8, d0u8); - q8u16 = vmull_u8(d3u8, d0u8); - q9u16 = vmull_u8(d5u8, d0u8); - q10u16 = vmull_u8(d6u8, d0u8); - q11u16 = vmull_u8(d8u8, d0u8); - q12u16 = vmull_u8(d9u8, d0u8); - q13u16 = vmull_u8(d11u8, d0u8); - q14u16 = vmull_u8(d12u8, d0u8); - - d2u8 = vext_u8(d2u8, d3u8, 1); - d5u8 = vext_u8(d5u8, d6u8, 1); - d8u8 = vext_u8(d8u8, d9u8, 1); - d11u8 = vext_u8(d11u8, d12u8, 1); - - q7u16 = vmlal_u8(q7u16, d2u8, d1u8); - q9u16 = vmlal_u8(q9u16, d5u8, d1u8); - q11u16 = vmlal_u8(q11u16, d8u8, d1u8); - q13u16 = vmlal_u8(q13u16, d11u8, d1u8); - - d3u8 = vext_u8(d3u8, d4u8, 1); - d6u8 = vext_u8(d6u8, d7u8, 1); - d9u8 = vext_u8(d9u8, d10u8, 1); - d12u8 = vext_u8(d12u8, d13u8, 1); - - q8u16 = vmlal_u8(q8u16, d3u8, d1u8); - q10u16 = vmlal_u8(q10u16, d6u8, d1u8); - q12u16 = vmlal_u8(q12u16, d9u8, d1u8); - q14u16 = vmlal_u8(q14u16, d12u8, d1u8); - - d14u8 = vqrshrn_n_u16(q7u16, 7); - d15u8 = vqrshrn_n_u16(q8u16, 7); - d16u8 = vqrshrn_n_u16(q9u16, 7); - d17u8 = vqrshrn_n_u16(q10u16, 7); - d18u8 = vqrshrn_n_u16(q11u16, 7); - d19u8 = vqrshrn_n_u16(q12u16, 7); - d20u8 = vqrshrn_n_u16(q13u16, 7); - d21u8 = vqrshrn_n_u16(q14u16, 7); - - d2u8 = vld1_u8(src_ptr); - d3u8 = vld1_u8(src_ptr + 8); - d4u8 = vld1_u8(src_ptr + 16); - src_ptr += src_pixels_per_line; - d5u8 = vld1_u8(src_ptr); - d6u8 = vld1_u8(src_ptr + 8); - d7u8 = vld1_u8(src_ptr + 16); - src_ptr += src_pixels_per_line; - d8u8 = vld1_u8(src_ptr); - d9u8 = vld1_u8(src_ptr + 8); - d10u8 = vld1_u8(src_ptr + 16); - src_ptr += src_pixels_per_line; - d11u8 = vld1_u8(src_ptr); - d12u8 = vld1_u8(src_ptr + 8); - d13u8 = vld1_u8(src_ptr + 16); - src_ptr += src_pixels_per_line; - - q7u8 = vcombine_u8(d14u8, d15u8); - q8u8 = vcombine_u8(d16u8, d17u8); - q9u8 = vcombine_u8(d18u8, d19u8); - q10u8 = vcombine_u8(d20u8, d21u8); - - vst1q_u8((uint8_t *)tmpp, q7u8); - tmpp += 16; - vst1q_u8((uint8_t *)tmpp, q8u8); - tmpp += 16; - vst1q_u8((uint8_t *)tmpp, q9u8); - tmpp += 16; - vst1q_u8((uint8_t *)tmpp, q10u8); - tmpp += 16; - } - - // First-pass filtering for rest 5 lines - d14u8 = vld1_u8(src_ptr); - d15u8 = vld1_u8(src_ptr + 8); - d16u8 = vld1_u8(src_ptr + 16); - src_ptr += src_pixels_per_line; - - q9u16 = vmull_u8(d2u8, d0u8); - q10u16 = vmull_u8(d3u8, d0u8); - q11u16 = vmull_u8(d5u8, d0u8); - q12u16 = vmull_u8(d6u8, d0u8); - q13u16 = vmull_u8(d8u8, d0u8); - q14u16 = vmull_u8(d9u8, d0u8); - - d2u8 = vext_u8(d2u8, d3u8, 1); - d5u8 = vext_u8(d5u8, d6u8, 1); - d8u8 = vext_u8(d8u8, d9u8, 1); - - q9u16 = vmlal_u8(q9u16, d2u8, d1u8); - q11u16 = vmlal_u8(q11u16, d5u8, d1u8); - q13u16 = vmlal_u8(q13u16, d8u8, d1u8); - - d3u8 = vext_u8(d3u8, d4u8, 1); - d6u8 = vext_u8(d6u8, d7u8, 1); - d9u8 = vext_u8(d9u8, d10u8, 1); - - q10u16 = vmlal_u8(q10u16, d3u8, d1u8); - q12u16 = vmlal_u8(q12u16, d6u8, d1u8); - q14u16 = vmlal_u8(q14u16, d9u8, d1u8); - - q1u16 = vmull_u8(d11u8, d0u8); - q2u16 = vmull_u8(d12u8, d0u8); - q3u16 = vmull_u8(d14u8, d0u8); - q4u16 = vmull_u8(d15u8, d0u8); - - d11u8 = vext_u8(d11u8, d12u8, 1); - d14u8 = vext_u8(d14u8, d15u8, 1); - - q1u16 = vmlal_u8(q1u16, d11u8, d1u8); - q3u16 = vmlal_u8(q3u16, d14u8, d1u8); - - d12u8 = vext_u8(d12u8, d13u8, 1); - d15u8 = vext_u8(d15u8, d16u8, 1); - - q2u16 = vmlal_u8(q2u16, d12u8, d1u8); - q4u16 = vmlal_u8(q4u16, d15u8, d1u8); - - d10u8 = vqrshrn_n_u16(q9u16, 7); - d11u8 = vqrshrn_n_u16(q10u16, 7); - d12u8 = vqrshrn_n_u16(q11u16, 7); - d13u8 = vqrshrn_n_u16(q12u16, 7); - d14u8 = vqrshrn_n_u16(q13u16, 7); - d15u8 = vqrshrn_n_u16(q14u16, 7); - d16u8 = vqrshrn_n_u16(q1u16, 7); - d17u8 = vqrshrn_n_u16(q2u16, 7); - d18u8 = vqrshrn_n_u16(q3u16, 7); - d19u8 = vqrshrn_n_u16(q4u16, 7); - - q5u8 = vcombine_u8(d10u8, d11u8); - q6u8 = vcombine_u8(d12u8, d13u8); - q7u8 = vcombine_u8(d14u8, d15u8); - q8u8 = vcombine_u8(d16u8, d17u8); - q9u8 = vcombine_u8(d18u8, d19u8); - - vst1q_u8((uint8_t *)tmpp, q5u8); - tmpp += 16; - vst1q_u8((uint8_t *)tmpp, q6u8); - tmpp += 16; - vst1q_u8((uint8_t *)tmpp, q7u8); - tmpp += 16; - vst1q_u8((uint8_t *)tmpp, q8u8); - tmpp += 16; - vst1q_u8((uint8_t *)tmpp, q9u8); - - // secondpass_filter - d0u8 = vdup_n_u8(bifilter4_coeff[yoffset][0]); - d1u8 = vdup_n_u8(bifilter4_coeff[yoffset][1]); - - tmpp = tmp; - q11u8 = vld1q_u8(tmpp); - tmpp += 16; - for (i = 4; i > 0; i--) { - q12u8 = vld1q_u8(tmpp); - tmpp += 16; - q13u8 = vld1q_u8(tmpp); - tmpp += 16; - q14u8 = vld1q_u8(tmpp); - tmpp += 16; - q15u8 = vld1q_u8(tmpp); - tmpp += 16; - - q1u16 = vmull_u8(vget_low_u8(q11u8), d0u8); - q2u16 = vmull_u8(vget_high_u8(q11u8), d0u8); - q3u16 = vmull_u8(vget_low_u8(q12u8), d0u8); - q4u16 = vmull_u8(vget_high_u8(q12u8), d0u8); - q5u16 = vmull_u8(vget_low_u8(q13u8), d0u8); - q6u16 = vmull_u8(vget_high_u8(q13u8), d0u8); - q7u16 = vmull_u8(vget_low_u8(q14u8), d0u8); - q8u16 = vmull_u8(vget_high_u8(q14u8), d0u8); - - q1u16 = vmlal_u8(q1u16, vget_low_u8(q12u8), d1u8); - q2u16 = vmlal_u8(q2u16, vget_high_u8(q12u8), d1u8); - q3u16 = vmlal_u8(q3u16, vget_low_u8(q13u8), d1u8); - q4u16 = vmlal_u8(q4u16, vget_high_u8(q13u8), d1u8); - q5u16 = vmlal_u8(q5u16, vget_low_u8(q14u8), d1u8); - q6u16 = vmlal_u8(q6u16, vget_high_u8(q14u8), d1u8); - q7u16 = vmlal_u8(q7u16, vget_low_u8(q15u8), d1u8); - q8u16 = vmlal_u8(q8u16, vget_high_u8(q15u8), d1u8); - - d2u8 = vqrshrn_n_u16(q1u16, 7); - d3u8 = vqrshrn_n_u16(q2u16, 7); - d4u8 = vqrshrn_n_u16(q3u16, 7); - d5u8 = vqrshrn_n_u16(q4u16, 7); - d6u8 = vqrshrn_n_u16(q5u16, 7); - d7u8 = vqrshrn_n_u16(q6u16, 7); - d8u8 = vqrshrn_n_u16(q7u16, 7); - d9u8 = vqrshrn_n_u16(q8u16, 7); - - q1u8 = vcombine_u8(d2u8, d3u8); - q2u8 = vcombine_u8(d4u8, d5u8); - q3u8 = vcombine_u8(d6u8, d7u8); - q4u8 = vcombine_u8(d8u8, d9u8); - - q11u8 = q15u8; - - vst1q_u8((uint8_t *)dst_ptr, q1u8); - dst_ptr += dst_pitch; - vst1q_u8((uint8_t *)dst_ptr, q2u8); - dst_ptr += dst_pitch; - vst1q_u8((uint8_t *)dst_ptr, q3u8); - dst_ptr += dst_pitch; - vst1q_u8((uint8_t *)dst_ptr, q4u8); - dst_ptr += dst_pitch; - } - return; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/copymem_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/copymem_neon.c deleted file mode 100644 index c89b47d6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/copymem_neon.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp8_rtcd.h" - -void vp8_copy_mem8x4_neon(unsigned char *src, int src_stride, - unsigned char *dst, int dst_stride) { - uint8x8_t vtmp; - int r; - - for (r = 0; r < 4; ++r) { - vtmp = vld1_u8(src); - vst1_u8(dst, vtmp); - src += src_stride; - dst += dst_stride; - } -} - -void vp8_copy_mem8x8_neon(unsigned char *src, int src_stride, - unsigned char *dst, int dst_stride) { - uint8x8_t vtmp; - int r; - - for (r = 0; r < 8; ++r) { - vtmp = vld1_u8(src); - vst1_u8(dst, vtmp); - src += src_stride; - dst += dst_stride; - } -} - -void vp8_copy_mem16x16_neon(unsigned char *src, int src_stride, - unsigned char *dst, int dst_stride) { - int r; - uint8x16_t qtmp; - - for (r = 0; r < 16; ++r) { - qtmp = vld1q_u8(src); - vst1q_u8(dst, qtmp); - src += src_stride; - dst += dst_stride; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/dc_only_idct_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/dc_only_idct_add_neon.c deleted file mode 100644 index d12c3a83..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/dc_only_idct_add_neon.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp8_rtcd.h" - -void vp8_dc_only_idct_add_neon(int16_t input_dc, unsigned char *pred_ptr, - int pred_stride, unsigned char *dst_ptr, - int dst_stride) { - int i; - uint16_t a1 = ((input_dc + 4) >> 3); - uint32x2_t d2u32 = vdup_n_u32(0); - uint8x8_t d2u8; - uint16x8_t q1u16; - uint16x8_t qAdd; - - qAdd = vdupq_n_u16(a1); - - for (i = 0; i < 2; ++i) { - d2u32 = vld1_lane_u32((const uint32_t *)pred_ptr, d2u32, 0); - pred_ptr += pred_stride; - d2u32 = vld1_lane_u32((const uint32_t *)pred_ptr, d2u32, 1); - pred_ptr += pred_stride; - - q1u16 = vaddw_u8(qAdd, vreinterpret_u8_u32(d2u32)); - d2u8 = vqmovun_s16(vreinterpretq_s16_u16(q1u16)); - - vst1_lane_u32((uint32_t *)dst_ptr, vreinterpret_u32_u8(d2u8), 0); - dst_ptr += dst_stride; - vst1_lane_u32((uint32_t *)dst_ptr, vreinterpret_u32_u8(d2u8), 1); - dst_ptr += dst_stride; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/dequant_idct_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/dequant_idct_neon.c deleted file mode 100644 index 5445f296..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/dequant_idct_neon.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp8_rtcd.h" - -static const int16_t cospi8sqrt2minus1 = 20091; -// 35468 exceeds INT16_MAX and gets converted to a negative number. Because of -// the way it is used in vqdmulh, where the result is doubled, it can be divided -// by 2 beforehand. This saves compensating for the negative value as well as -// shifting the result. -static const int16_t sinpi8sqrt2 = 35468 >> 1; - -void vp8_dequant_idct_add_neon(int16_t *input, int16_t *dq, unsigned char *dst, - int stride) { - unsigned char *dst0; - int32x2_t d14, d15; - int16x4_t d2, d3, d4, d5, d10, d11, d12, d13; - int16x8_t q1, q2, q3, q4, q5, q6; - int16x8_t qEmpty = vdupq_n_s16(0); - int32x2x2_t d2tmp0, d2tmp1; - int16x4x2_t d2tmp2, d2tmp3; - - d14 = d15 = vdup_n_s32(0); - - // load input - q3 = vld1q_s16(input); - vst1q_s16(input, qEmpty); - input += 8; - q4 = vld1q_s16(input); - vst1q_s16(input, qEmpty); - - // load dq - q5 = vld1q_s16(dq); - dq += 8; - q6 = vld1q_s16(dq); - - // load src from dst - dst0 = dst; - d14 = vld1_lane_s32((const int32_t *)dst0, d14, 0); - dst0 += stride; - d14 = vld1_lane_s32((const int32_t *)dst0, d14, 1); - dst0 += stride; - d15 = vld1_lane_s32((const int32_t *)dst0, d15, 0); - dst0 += stride; - d15 = vld1_lane_s32((const int32_t *)dst0, d15, 1); - - q1 = vreinterpretq_s16_u16( - vmulq_u16(vreinterpretq_u16_s16(q3), vreinterpretq_u16_s16(q5))); - q2 = vreinterpretq_s16_u16( - vmulq_u16(vreinterpretq_u16_s16(q4), vreinterpretq_u16_s16(q6))); - - d12 = vqadd_s16(vget_low_s16(q1), vget_low_s16(q2)); - d13 = vqsub_s16(vget_low_s16(q1), vget_low_s16(q2)); - - q2 = vcombine_s16(vget_high_s16(q1), vget_high_s16(q2)); - - q3 = vqdmulhq_n_s16(q2, sinpi8sqrt2); - q4 = vqdmulhq_n_s16(q2, cospi8sqrt2minus1); - - q4 = vshrq_n_s16(q4, 1); - - q4 = vqaddq_s16(q4, q2); - - d10 = vqsub_s16(vget_low_s16(q3), vget_high_s16(q4)); - d11 = vqadd_s16(vget_high_s16(q3), vget_low_s16(q4)); - - d2 = vqadd_s16(d12, d11); - d3 = vqadd_s16(d13, d10); - d4 = vqsub_s16(d13, d10); - d5 = vqsub_s16(d12, d11); - - d2tmp0 = vtrn_s32(vreinterpret_s32_s16(d2), vreinterpret_s32_s16(d4)); - d2tmp1 = vtrn_s32(vreinterpret_s32_s16(d3), vreinterpret_s32_s16(d5)); - d2tmp2 = vtrn_s16(vreinterpret_s16_s32(d2tmp0.val[0]), - vreinterpret_s16_s32(d2tmp1.val[0])); - d2tmp3 = vtrn_s16(vreinterpret_s16_s32(d2tmp0.val[1]), - vreinterpret_s16_s32(d2tmp1.val[1])); - - // loop 2 - q2 = vcombine_s16(d2tmp2.val[1], d2tmp3.val[1]); - - q3 = vqdmulhq_n_s16(q2, sinpi8sqrt2); - q4 = vqdmulhq_n_s16(q2, cospi8sqrt2minus1); - - d12 = vqadd_s16(d2tmp2.val[0], d2tmp3.val[0]); - d13 = vqsub_s16(d2tmp2.val[0], d2tmp3.val[0]); - - q4 = vshrq_n_s16(q4, 1); - - q4 = vqaddq_s16(q4, q2); - - d10 = vqsub_s16(vget_low_s16(q3), vget_high_s16(q4)); - d11 = vqadd_s16(vget_high_s16(q3), vget_low_s16(q4)); - - d2 = vqadd_s16(d12, d11); - d3 = vqadd_s16(d13, d10); - d4 = vqsub_s16(d13, d10); - d5 = vqsub_s16(d12, d11); - - d2 = vrshr_n_s16(d2, 3); - d3 = vrshr_n_s16(d3, 3); - d4 = vrshr_n_s16(d4, 3); - d5 = vrshr_n_s16(d5, 3); - - d2tmp0 = vtrn_s32(vreinterpret_s32_s16(d2), vreinterpret_s32_s16(d4)); - d2tmp1 = vtrn_s32(vreinterpret_s32_s16(d3), vreinterpret_s32_s16(d5)); - d2tmp2 = vtrn_s16(vreinterpret_s16_s32(d2tmp0.val[0]), - vreinterpret_s16_s32(d2tmp1.val[0])); - d2tmp3 = vtrn_s16(vreinterpret_s16_s32(d2tmp0.val[1]), - vreinterpret_s16_s32(d2tmp1.val[1])); - - q1 = vcombine_s16(d2tmp2.val[0], d2tmp2.val[1]); - q2 = vcombine_s16(d2tmp3.val[0], d2tmp3.val[1]); - - q1 = vreinterpretq_s16_u16( - vaddw_u8(vreinterpretq_u16_s16(q1), vreinterpret_u8_s32(d14))); - q2 = vreinterpretq_s16_u16( - vaddw_u8(vreinterpretq_u16_s16(q2), vreinterpret_u8_s32(d15))); - - d14 = vreinterpret_s32_u8(vqmovun_s16(q1)); - d15 = vreinterpret_s32_u8(vqmovun_s16(q2)); - - dst0 = dst; - vst1_lane_s32((int32_t *)dst0, d14, 0); - dst0 += stride; - vst1_lane_s32((int32_t *)dst0, d14, 1); - dst0 += stride; - vst1_lane_s32((int32_t *)dst0, d15, 0); - dst0 += stride; - vst1_lane_s32((int32_t *)dst0, d15, 1); - return; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/dequantizeb_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/dequantizeb_neon.c deleted file mode 100644 index 791aaea2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/dequantizeb_neon.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp8_rtcd.h" -#include "vp8/common/blockd.h" - -void vp8_dequantize_b_neon(BLOCKD *d, short *DQC) { - int16x8x2_t qQ, qDQC, qDQ; - - qQ = vld2q_s16(d->qcoeff); - qDQC = vld2q_s16(DQC); - - qDQ.val[0] = vmulq_s16(qQ.val[0], qDQC.val[0]); - qDQ.val[1] = vmulq_s16(qQ.val[1], qDQC.val[1]); - - vst2q_s16(d->dqcoeff, qDQ); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/idct_blk_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/idct_blk_neon.c deleted file mode 100644 index 5c26ce67..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/idct_blk_neon.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp8_rtcd.h" - -static void idct_dequant_0_2x_neon(int16_t *q, int16_t dq, unsigned char *dst, - int stride) { - unsigned char *dst0; - int i, a0, a1; - int16x8x2_t q2Add; - int32x2_t d2s32 = vdup_n_s32(0), d4s32 = vdup_n_s32(0); - uint8x8_t d2u8, d4u8; - uint16x8_t q1u16, q2u16; - - a0 = ((q[0] * dq) + 4) >> 3; - a1 = ((q[16] * dq) + 4) >> 3; - q[0] = q[16] = 0; - q2Add.val[0] = vdupq_n_s16((int16_t)a0); - q2Add.val[1] = vdupq_n_s16((int16_t)a1); - - for (i = 0; i < 2; i++, dst += 4) { - dst0 = dst; - d2s32 = vld1_lane_s32((const int32_t *)dst0, d2s32, 0); - dst0 += stride; - d2s32 = vld1_lane_s32((const int32_t *)dst0, d2s32, 1); - dst0 += stride; - d4s32 = vld1_lane_s32((const int32_t *)dst0, d4s32, 0); - dst0 += stride; - d4s32 = vld1_lane_s32((const int32_t *)dst0, d4s32, 1); - - q1u16 = vaddw_u8(vreinterpretq_u16_s16(q2Add.val[i]), - vreinterpret_u8_s32(d2s32)); - q2u16 = vaddw_u8(vreinterpretq_u16_s16(q2Add.val[i]), - vreinterpret_u8_s32(d4s32)); - - d2u8 = vqmovun_s16(vreinterpretq_s16_u16(q1u16)); - d4u8 = vqmovun_s16(vreinterpretq_s16_u16(q2u16)); - - d2s32 = vreinterpret_s32_u8(d2u8); - d4s32 = vreinterpret_s32_u8(d4u8); - - dst0 = dst; - vst1_lane_s32((int32_t *)dst0, d2s32, 0); - dst0 += stride; - vst1_lane_s32((int32_t *)dst0, d2s32, 1); - dst0 += stride; - vst1_lane_s32((int32_t *)dst0, d4s32, 0); - dst0 += stride; - vst1_lane_s32((int32_t *)dst0, d4s32, 1); - } -} - -static const int16_t cospi8sqrt2minus1 = 20091; -static const int16_t sinpi8sqrt2 = 17734; -// because the lowest bit in 0x8a8c is 0, we can pre-shift this - -static void idct_dequant_full_2x_neon(int16_t *q, int16_t *dq, - unsigned char *dst, int stride) { - unsigned char *dst0, *dst1; - int32x2_t d28, d29, d30, d31; - int16x8_t q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11; - int16x8_t qEmpty = vdupq_n_s16(0); - int32x4x2_t q2tmp0, q2tmp1; - int16x8x2_t q2tmp2, q2tmp3; - int16x4_t dLow0, dLow1, dHigh0, dHigh1; - - d28 = d29 = d30 = d31 = vdup_n_s32(0); - - // load dq - q0 = vld1q_s16(dq); - dq += 8; - q1 = vld1q_s16(dq); - - // load q - q2 = vld1q_s16(q); - vst1q_s16(q, qEmpty); - q += 8; - q3 = vld1q_s16(q); - vst1q_s16(q, qEmpty); - q += 8; - q4 = vld1q_s16(q); - vst1q_s16(q, qEmpty); - q += 8; - q5 = vld1q_s16(q); - vst1q_s16(q, qEmpty); - - // load src from dst - dst0 = dst; - dst1 = dst + 4; - d28 = vld1_lane_s32((const int32_t *)dst0, d28, 0); - dst0 += stride; - d28 = vld1_lane_s32((const int32_t *)dst1, d28, 1); - dst1 += stride; - d29 = vld1_lane_s32((const int32_t *)dst0, d29, 0); - dst0 += stride; - d29 = vld1_lane_s32((const int32_t *)dst1, d29, 1); - dst1 += stride; - - d30 = vld1_lane_s32((const int32_t *)dst0, d30, 0); - dst0 += stride; - d30 = vld1_lane_s32((const int32_t *)dst1, d30, 1); - dst1 += stride; - d31 = vld1_lane_s32((const int32_t *)dst0, d31, 0); - d31 = vld1_lane_s32((const int32_t *)dst1, d31, 1); - - q2 = vmulq_s16(q2, q0); - q3 = vmulq_s16(q3, q1); - q4 = vmulq_s16(q4, q0); - q5 = vmulq_s16(q5, q1); - - // vswp - dLow0 = vget_low_s16(q2); - dHigh0 = vget_high_s16(q2); - dLow1 = vget_low_s16(q4); - dHigh1 = vget_high_s16(q4); - q2 = vcombine_s16(dLow0, dLow1); - q4 = vcombine_s16(dHigh0, dHigh1); - - dLow0 = vget_low_s16(q3); - dHigh0 = vget_high_s16(q3); - dLow1 = vget_low_s16(q5); - dHigh1 = vget_high_s16(q5); - q3 = vcombine_s16(dLow0, dLow1); - q5 = vcombine_s16(dHigh0, dHigh1); - - q6 = vqdmulhq_n_s16(q4, sinpi8sqrt2); - q7 = vqdmulhq_n_s16(q5, sinpi8sqrt2); - q8 = vqdmulhq_n_s16(q4, cospi8sqrt2minus1); - q9 = vqdmulhq_n_s16(q5, cospi8sqrt2minus1); - - q10 = vqaddq_s16(q2, q3); - q11 = vqsubq_s16(q2, q3); - - q8 = vshrq_n_s16(q8, 1); - q9 = vshrq_n_s16(q9, 1); - - q4 = vqaddq_s16(q4, q8); - q5 = vqaddq_s16(q5, q9); - - q2 = vqsubq_s16(q6, q5); - q3 = vqaddq_s16(q7, q4); - - q4 = vqaddq_s16(q10, q3); - q5 = vqaddq_s16(q11, q2); - q6 = vqsubq_s16(q11, q2); - q7 = vqsubq_s16(q10, q3); - - q2tmp0 = vtrnq_s32(vreinterpretq_s32_s16(q4), vreinterpretq_s32_s16(q6)); - q2tmp1 = vtrnq_s32(vreinterpretq_s32_s16(q5), vreinterpretq_s32_s16(q7)); - q2tmp2 = vtrnq_s16(vreinterpretq_s16_s32(q2tmp0.val[0]), - vreinterpretq_s16_s32(q2tmp1.val[0])); - q2tmp3 = vtrnq_s16(vreinterpretq_s16_s32(q2tmp0.val[1]), - vreinterpretq_s16_s32(q2tmp1.val[1])); - - // loop 2 - q8 = vqdmulhq_n_s16(q2tmp2.val[1], sinpi8sqrt2); - q9 = vqdmulhq_n_s16(q2tmp3.val[1], sinpi8sqrt2); - q10 = vqdmulhq_n_s16(q2tmp2.val[1], cospi8sqrt2minus1); - q11 = vqdmulhq_n_s16(q2tmp3.val[1], cospi8sqrt2minus1); - - q2 = vqaddq_s16(q2tmp2.val[0], q2tmp3.val[0]); - q3 = vqsubq_s16(q2tmp2.val[0], q2tmp3.val[0]); - - q10 = vshrq_n_s16(q10, 1); - q11 = vshrq_n_s16(q11, 1); - - q10 = vqaddq_s16(q2tmp2.val[1], q10); - q11 = vqaddq_s16(q2tmp3.val[1], q11); - - q8 = vqsubq_s16(q8, q11); - q9 = vqaddq_s16(q9, q10); - - q4 = vqaddq_s16(q2, q9); - q5 = vqaddq_s16(q3, q8); - q6 = vqsubq_s16(q3, q8); - q7 = vqsubq_s16(q2, q9); - - q4 = vrshrq_n_s16(q4, 3); - q5 = vrshrq_n_s16(q5, 3); - q6 = vrshrq_n_s16(q6, 3); - q7 = vrshrq_n_s16(q7, 3); - - q2tmp0 = vtrnq_s32(vreinterpretq_s32_s16(q4), vreinterpretq_s32_s16(q6)); - q2tmp1 = vtrnq_s32(vreinterpretq_s32_s16(q5), vreinterpretq_s32_s16(q7)); - q2tmp2 = vtrnq_s16(vreinterpretq_s16_s32(q2tmp0.val[0]), - vreinterpretq_s16_s32(q2tmp1.val[0])); - q2tmp3 = vtrnq_s16(vreinterpretq_s16_s32(q2tmp0.val[1]), - vreinterpretq_s16_s32(q2tmp1.val[1])); - - q4 = vreinterpretq_s16_u16( - vaddw_u8(vreinterpretq_u16_s16(q2tmp2.val[0]), vreinterpret_u8_s32(d28))); - q5 = vreinterpretq_s16_u16( - vaddw_u8(vreinterpretq_u16_s16(q2tmp2.val[1]), vreinterpret_u8_s32(d29))); - q6 = vreinterpretq_s16_u16( - vaddw_u8(vreinterpretq_u16_s16(q2tmp3.val[0]), vreinterpret_u8_s32(d30))); - q7 = vreinterpretq_s16_u16( - vaddw_u8(vreinterpretq_u16_s16(q2tmp3.val[1]), vreinterpret_u8_s32(d31))); - - d28 = vreinterpret_s32_u8(vqmovun_s16(q4)); - d29 = vreinterpret_s32_u8(vqmovun_s16(q5)); - d30 = vreinterpret_s32_u8(vqmovun_s16(q6)); - d31 = vreinterpret_s32_u8(vqmovun_s16(q7)); - - dst0 = dst; - dst1 = dst + 4; - vst1_lane_s32((int32_t *)dst0, d28, 0); - dst0 += stride; - vst1_lane_s32((int32_t *)dst1, d28, 1); - dst1 += stride; - vst1_lane_s32((int32_t *)dst0, d29, 0); - dst0 += stride; - vst1_lane_s32((int32_t *)dst1, d29, 1); - dst1 += stride; - - vst1_lane_s32((int32_t *)dst0, d30, 0); - dst0 += stride; - vst1_lane_s32((int32_t *)dst1, d30, 1); - dst1 += stride; - vst1_lane_s32((int32_t *)dst0, d31, 0); - vst1_lane_s32((int32_t *)dst1, d31, 1); -} - -void vp8_dequant_idct_add_y_block_neon(short *q, short *dq, unsigned char *dst, - int stride, char *eobs) { - int i; - - for (i = 0; i < 4; ++i) { - if (((short *)(eobs))[0]) { - if (((short *)eobs)[0] & 0xfefe) - idct_dequant_full_2x_neon(q, dq, dst, stride); - else - idct_dequant_0_2x_neon(q, dq[0], dst, stride); - } - - if (((short *)(eobs))[1]) { - if (((short *)eobs)[1] & 0xfefe) - idct_dequant_full_2x_neon(q + 32, dq, dst + 8, stride); - else - idct_dequant_0_2x_neon(q + 32, dq[0], dst + 8, stride); - } - q += 64; - dst += 4 * stride; - eobs += 4; - } -} - -void vp8_dequant_idct_add_uv_block_neon(short *q, short *dq, - unsigned char *dst_u, - unsigned char *dst_v, int stride, - char *eobs) { - if (((short *)(eobs))[0]) { - if (((short *)eobs)[0] & 0xfefe) - idct_dequant_full_2x_neon(q, dq, dst_u, stride); - else - idct_dequant_0_2x_neon(q, dq[0], dst_u, stride); - } - - q += 32; - dst_u += 4 * stride; - - if (((short *)(eobs))[1]) { - if (((short *)eobs)[1] & 0xfefe) - idct_dequant_full_2x_neon(q, dq, dst_u, stride); - else - idct_dequant_0_2x_neon(q, dq[0], dst_u, stride); - } - - q += 32; - - if (((short *)(eobs))[2]) { - if (((short *)eobs)[2] & 0xfefe) - idct_dequant_full_2x_neon(q, dq, dst_v, stride); - else - idct_dequant_0_2x_neon(q, dq[0], dst_v, stride); - } - - q += 32; - dst_v += 4 * stride; - - if (((short *)(eobs))[3]) { - if (((short *)eobs)[3] & 0xfefe) - idct_dequant_full_2x_neon(q, dq, dst_v, stride); - else - idct_dequant_0_2x_neon(q, dq[0], dst_v, stride); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/iwalsh_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/iwalsh_neon.c deleted file mode 100644 index 91600bfc..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/iwalsh_neon.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp8_rtcd.h" - -void vp8_short_inv_walsh4x4_neon(int16_t *input, int16_t *mb_dqcoeff) { - int16x8_t q0s16, q1s16, q2s16, q3s16; - int16x4_t d4s16, d5s16, d6s16, d7s16; - int16x4x2_t v2tmp0, v2tmp1; - int32x2x2_t v2tmp2, v2tmp3; - int16x8_t qAdd3; - - q0s16 = vld1q_s16(input); - q1s16 = vld1q_s16(input + 8); - - // 1st for loop - d4s16 = vadd_s16(vget_low_s16(q0s16), vget_high_s16(q1s16)); - d6s16 = vadd_s16(vget_high_s16(q0s16), vget_low_s16(q1s16)); - d5s16 = vsub_s16(vget_low_s16(q0s16), vget_high_s16(q1s16)); - d7s16 = vsub_s16(vget_high_s16(q0s16), vget_low_s16(q1s16)); - - q2s16 = vcombine_s16(d4s16, d5s16); - q3s16 = vcombine_s16(d6s16, d7s16); - - q0s16 = vaddq_s16(q2s16, q3s16); - q1s16 = vsubq_s16(q2s16, q3s16); - - v2tmp2 = vtrn_s32(vreinterpret_s32_s16(vget_low_s16(q0s16)), - vreinterpret_s32_s16(vget_low_s16(q1s16))); - v2tmp3 = vtrn_s32(vreinterpret_s32_s16(vget_high_s16(q0s16)), - vreinterpret_s32_s16(vget_high_s16(q1s16))); - v2tmp0 = vtrn_s16(vreinterpret_s16_s32(v2tmp2.val[0]), - vreinterpret_s16_s32(v2tmp3.val[0])); - v2tmp1 = vtrn_s16(vreinterpret_s16_s32(v2tmp2.val[1]), - vreinterpret_s16_s32(v2tmp3.val[1])); - - // 2nd for loop - d4s16 = vadd_s16(v2tmp0.val[0], v2tmp1.val[1]); - d6s16 = vadd_s16(v2tmp0.val[1], v2tmp1.val[0]); - d5s16 = vsub_s16(v2tmp0.val[0], v2tmp1.val[1]); - d7s16 = vsub_s16(v2tmp0.val[1], v2tmp1.val[0]); - q2s16 = vcombine_s16(d4s16, d5s16); - q3s16 = vcombine_s16(d6s16, d7s16); - - qAdd3 = vdupq_n_s16(3); - - q0s16 = vaddq_s16(q2s16, q3s16); - q1s16 = vsubq_s16(q2s16, q3s16); - - q0s16 = vaddq_s16(q0s16, qAdd3); - q1s16 = vaddq_s16(q1s16, qAdd3); - - q0s16 = vshrq_n_s16(q0s16, 3); - q1s16 = vshrq_n_s16(q1s16, 3); - - // store - vst1_lane_s16(mb_dqcoeff, vget_low_s16(q0s16), 0); - mb_dqcoeff += 16; - vst1_lane_s16(mb_dqcoeff, vget_high_s16(q0s16), 0); - mb_dqcoeff += 16; - vst1_lane_s16(mb_dqcoeff, vget_low_s16(q1s16), 0); - mb_dqcoeff += 16; - vst1_lane_s16(mb_dqcoeff, vget_high_s16(q1s16), 0); - mb_dqcoeff += 16; - - vst1_lane_s16(mb_dqcoeff, vget_low_s16(q0s16), 1); - mb_dqcoeff += 16; - vst1_lane_s16(mb_dqcoeff, vget_high_s16(q0s16), 1); - mb_dqcoeff += 16; - vst1_lane_s16(mb_dqcoeff, vget_low_s16(q1s16), 1); - mb_dqcoeff += 16; - vst1_lane_s16(mb_dqcoeff, vget_high_s16(q1s16), 1); - mb_dqcoeff += 16; - - vst1_lane_s16(mb_dqcoeff, vget_low_s16(q0s16), 2); - mb_dqcoeff += 16; - vst1_lane_s16(mb_dqcoeff, vget_high_s16(q0s16), 2); - mb_dqcoeff += 16; - vst1_lane_s16(mb_dqcoeff, vget_low_s16(q1s16), 2); - mb_dqcoeff += 16; - vst1_lane_s16(mb_dqcoeff, vget_high_s16(q1s16), 2); - mb_dqcoeff += 16; - - vst1_lane_s16(mb_dqcoeff, vget_low_s16(q0s16), 3); - mb_dqcoeff += 16; - vst1_lane_s16(mb_dqcoeff, vget_high_s16(q0s16), 3); - mb_dqcoeff += 16; - vst1_lane_s16(mb_dqcoeff, vget_low_s16(q1s16), 3); - mb_dqcoeff += 16; - vst1_lane_s16(mb_dqcoeff, vget_high_s16(q1s16), 3); - mb_dqcoeff += 16; - return; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.c deleted file mode 100644 index df983b23..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vp8_rtcd.h" - -static INLINE void vp8_loop_filter_simple_horizontal_edge_neon( - unsigned char *s, int p, const unsigned char *blimit) { - uint8_t *sp; - uint8x16_t qblimit, q0u8; - uint8x16_t q5u8, q6u8, q7u8, q8u8, q9u8, q10u8, q14u8, q15u8; - int16x8_t q2s16, q3s16, q13s16; - int8x8_t d8s8, d9s8; - int8x16_t q2s8, q3s8, q4s8, q10s8, q11s8, q14s8; - - qblimit = vdupq_n_u8(*blimit); - - sp = s - (p << 1); - q5u8 = vld1q_u8(sp); - sp += p; - q6u8 = vld1q_u8(sp); - sp += p; - q7u8 = vld1q_u8(sp); - sp += p; - q8u8 = vld1q_u8(sp); - - q15u8 = vabdq_u8(q6u8, q7u8); - q14u8 = vabdq_u8(q5u8, q8u8); - - q15u8 = vqaddq_u8(q15u8, q15u8); - q14u8 = vshrq_n_u8(q14u8, 1); - q0u8 = vdupq_n_u8(0x80); - q13s16 = vdupq_n_s16(3); - q15u8 = vqaddq_u8(q15u8, q14u8); - - q5u8 = veorq_u8(q5u8, q0u8); - q6u8 = veorq_u8(q6u8, q0u8); - q7u8 = veorq_u8(q7u8, q0u8); - q8u8 = veorq_u8(q8u8, q0u8); - - q15u8 = vcgeq_u8(qblimit, q15u8); - - q2s16 = vsubl_s8(vget_low_s8(vreinterpretq_s8_u8(q7u8)), - vget_low_s8(vreinterpretq_s8_u8(q6u8))); - q3s16 = vsubl_s8(vget_high_s8(vreinterpretq_s8_u8(q7u8)), - vget_high_s8(vreinterpretq_s8_u8(q6u8))); - - q4s8 = vqsubq_s8(vreinterpretq_s8_u8(q5u8), vreinterpretq_s8_u8(q8u8)); - - q2s16 = vmulq_s16(q2s16, q13s16); - q3s16 = vmulq_s16(q3s16, q13s16); - - q10u8 = vdupq_n_u8(3); - q9u8 = vdupq_n_u8(4); - - q2s16 = vaddw_s8(q2s16, vget_low_s8(q4s8)); - q3s16 = vaddw_s8(q3s16, vget_high_s8(q4s8)); - - d8s8 = vqmovn_s16(q2s16); - d9s8 = vqmovn_s16(q3s16); - q4s8 = vcombine_s8(d8s8, d9s8); - - q14s8 = vandq_s8(q4s8, vreinterpretq_s8_u8(q15u8)); - - q2s8 = vqaddq_s8(q14s8, vreinterpretq_s8_u8(q10u8)); - q3s8 = vqaddq_s8(q14s8, vreinterpretq_s8_u8(q9u8)); - q2s8 = vshrq_n_s8(q2s8, 3); - q3s8 = vshrq_n_s8(q3s8, 3); - - q11s8 = vqaddq_s8(vreinterpretq_s8_u8(q6u8), q2s8); - q10s8 = vqsubq_s8(vreinterpretq_s8_u8(q7u8), q3s8); - - q6u8 = veorq_u8(vreinterpretq_u8_s8(q11s8), q0u8); - q7u8 = veorq_u8(vreinterpretq_u8_s8(q10s8), q0u8); - - vst1q_u8(s, q7u8); - s -= p; - vst1q_u8(s, q6u8); - return; -} - -void vp8_loop_filter_bhs_neon(unsigned char *y_ptr, int y_stride, - const unsigned char *blimit) { - y_ptr += y_stride * 4; - vp8_loop_filter_simple_horizontal_edge_neon(y_ptr, y_stride, blimit); - y_ptr += y_stride * 4; - vp8_loop_filter_simple_horizontal_edge_neon(y_ptr, y_stride, blimit); - y_ptr += y_stride * 4; - vp8_loop_filter_simple_horizontal_edge_neon(y_ptr, y_stride, blimit); - return; -} - -void vp8_loop_filter_mbhs_neon(unsigned char *y_ptr, int y_stride, - const unsigned char *blimit) { - vp8_loop_filter_simple_horizontal_edge_neon(y_ptr, y_stride, blimit); - return; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.c deleted file mode 100644 index fbc83ae2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vp8_rtcd.h" -#include "vpx_ports/arm.h" - -#ifdef VPX_INCOMPATIBLE_GCC -static INLINE void write_2x4(unsigned char *dst, int pitch, - const uint8x8x2_t result) { - /* - * uint8x8x2_t result - 00 01 02 03 | 04 05 06 07 - 10 11 12 13 | 14 15 16 17 - --- - * after vtrn_u8 - 00 10 02 12 | 04 14 06 16 - 01 11 03 13 | 05 15 07 17 - */ - const uint8x8x2_t r01_u8 = vtrn_u8(result.val[0], result.val[1]); - const uint16x4_t x_0_4 = vreinterpret_u16_u8(r01_u8.val[0]); - const uint16x4_t x_1_5 = vreinterpret_u16_u8(r01_u8.val[1]); - vst1_lane_u16((uint16_t *)dst, x_0_4, 0); - dst += pitch; - vst1_lane_u16((uint16_t *)dst, x_1_5, 0); - dst += pitch; - vst1_lane_u16((uint16_t *)dst, x_0_4, 1); - dst += pitch; - vst1_lane_u16((uint16_t *)dst, x_1_5, 1); - dst += pitch; - vst1_lane_u16((uint16_t *)dst, x_0_4, 2); - dst += pitch; - vst1_lane_u16((uint16_t *)dst, x_1_5, 2); - dst += pitch; - vst1_lane_u16((uint16_t *)dst, x_0_4, 3); - dst += pitch; - vst1_lane_u16((uint16_t *)dst, x_1_5, 3); -} - -static INLINE void write_2x8(unsigned char *dst, int pitch, - const uint8x8x2_t result, - const uint8x8x2_t result2) { - write_2x4(dst, pitch, result); - dst += pitch * 8; - write_2x4(dst, pitch, result2); -} -#else -static INLINE void write_2x8(unsigned char *dst, int pitch, - const uint8x8x2_t result, - const uint8x8x2_t result2) { - vst2_lane_u8(dst, result, 0); - dst += pitch; - vst2_lane_u8(dst, result, 1); - dst += pitch; - vst2_lane_u8(dst, result, 2); - dst += pitch; - vst2_lane_u8(dst, result, 3); - dst += pitch; - vst2_lane_u8(dst, result, 4); - dst += pitch; - vst2_lane_u8(dst, result, 5); - dst += pitch; - vst2_lane_u8(dst, result, 6); - dst += pitch; - vst2_lane_u8(dst, result, 7); - dst += pitch; - - vst2_lane_u8(dst, result2, 0); - dst += pitch; - vst2_lane_u8(dst, result2, 1); - dst += pitch; - vst2_lane_u8(dst, result2, 2); - dst += pitch; - vst2_lane_u8(dst, result2, 3); - dst += pitch; - vst2_lane_u8(dst, result2, 4); - dst += pitch; - vst2_lane_u8(dst, result2, 5); - dst += pitch; - vst2_lane_u8(dst, result2, 6); - dst += pitch; - vst2_lane_u8(dst, result2, 7); -} -#endif // VPX_INCOMPATIBLE_GCC - -#ifdef VPX_INCOMPATIBLE_GCC -static INLINE uint8x8x4_t read_4x8(unsigned char *src, int pitch) { - uint8x8x4_t x; - const uint8x8_t a = vld1_u8(src); - const uint8x8_t b = vld1_u8(src + pitch * 1); - const uint8x8_t c = vld1_u8(src + pitch * 2); - const uint8x8_t d = vld1_u8(src + pitch * 3); - const uint8x8_t e = vld1_u8(src + pitch * 4); - const uint8x8_t f = vld1_u8(src + pitch * 5); - const uint8x8_t g = vld1_u8(src + pitch * 6); - const uint8x8_t h = vld1_u8(src + pitch * 7); - const uint32x2x2_t r04_u32 = - vtrn_u32(vreinterpret_u32_u8(a), vreinterpret_u32_u8(e)); - const uint32x2x2_t r15_u32 = - vtrn_u32(vreinterpret_u32_u8(b), vreinterpret_u32_u8(f)); - const uint32x2x2_t r26_u32 = - vtrn_u32(vreinterpret_u32_u8(c), vreinterpret_u32_u8(g)); - const uint32x2x2_t r37_u32 = - vtrn_u32(vreinterpret_u32_u8(d), vreinterpret_u32_u8(h)); - const uint16x4x2_t r02_u16 = vtrn_u16(vreinterpret_u16_u32(r04_u32.val[0]), - vreinterpret_u16_u32(r26_u32.val[0])); - const uint16x4x2_t r13_u16 = vtrn_u16(vreinterpret_u16_u32(r15_u32.val[0]), - vreinterpret_u16_u32(r37_u32.val[0])); - const uint8x8x2_t r01_u8 = vtrn_u8(vreinterpret_u8_u16(r02_u16.val[0]), - vreinterpret_u8_u16(r13_u16.val[0])); - const uint8x8x2_t r23_u8 = vtrn_u8(vreinterpret_u8_u16(r02_u16.val[1]), - vreinterpret_u8_u16(r13_u16.val[1])); - /* - * after vtrn_u32 - 00 01 02 03 | 40 41 42 43 - 10 11 12 13 | 50 51 52 53 - 20 21 22 23 | 60 61 62 63 - 30 31 32 33 | 70 71 72 73 - --- - * after vtrn_u16 - 00 01 20 21 | 40 41 60 61 - 02 03 22 23 | 42 43 62 63 - 10 11 30 31 | 50 51 70 71 - 12 13 32 33 | 52 52 72 73 - - 00 01 20 21 | 40 41 60 61 - 10 11 30 31 | 50 51 70 71 - 02 03 22 23 | 42 43 62 63 - 12 13 32 33 | 52 52 72 73 - --- - * after vtrn_u8 - 00 10 20 30 | 40 50 60 70 - 01 11 21 31 | 41 51 61 71 - 02 12 22 32 | 42 52 62 72 - 03 13 23 33 | 43 53 63 73 - */ - x.val[0] = r01_u8.val[0]; - x.val[1] = r01_u8.val[1]; - x.val[2] = r23_u8.val[0]; - x.val[3] = r23_u8.val[1]; - - return x; -} -#else -static INLINE uint8x8x4_t read_4x8(unsigned char *src, int pitch) { - uint8x8x4_t x; - x.val[0] = x.val[1] = x.val[2] = x.val[3] = vdup_n_u8(0); - x = vld4_lane_u8(src, x, 0); - src += pitch; - x = vld4_lane_u8(src, x, 1); - src += pitch; - x = vld4_lane_u8(src, x, 2); - src += pitch; - x = vld4_lane_u8(src, x, 3); - src += pitch; - x = vld4_lane_u8(src, x, 4); - src += pitch; - x = vld4_lane_u8(src, x, 5); - src += pitch; - x = vld4_lane_u8(src, x, 6); - src += pitch; - x = vld4_lane_u8(src, x, 7); - return x; -} -#endif // VPX_INCOMPATIBLE_GCC - -static INLINE void vp8_loop_filter_simple_vertical_edge_neon( - unsigned char *s, int p, const unsigned char *blimit) { - unsigned char *src1; - uint8x16_t qblimit, q0u8; - uint8x16_t q3u8, q4u8, q5u8, q6u8, q7u8, q11u8, q12u8, q14u8, q15u8; - int16x8_t q2s16, q13s16, q11s16; - int8x8_t d28s8, d29s8; - int8x16_t q2s8, q3s8, q10s8, q11s8, q14s8; - uint8x8x4_t d0u8x4; // d6, d7, d8, d9 - uint8x8x4_t d1u8x4; // d10, d11, d12, d13 - uint8x8x2_t d2u8x2; // d12, d13 - uint8x8x2_t d3u8x2; // d14, d15 - - qblimit = vdupq_n_u8(*blimit); - - src1 = s - 2; - d0u8x4 = read_4x8(src1, p); - src1 += p * 8; - d1u8x4 = read_4x8(src1, p); - - q3u8 = vcombine_u8(d0u8x4.val[0], d1u8x4.val[0]); // d6 d10 - q4u8 = vcombine_u8(d0u8x4.val[2], d1u8x4.val[2]); // d8 d12 - q5u8 = vcombine_u8(d0u8x4.val[1], d1u8x4.val[1]); // d7 d11 - q6u8 = vcombine_u8(d0u8x4.val[3], d1u8x4.val[3]); // d9 d13 - - q15u8 = vabdq_u8(q5u8, q4u8); - q14u8 = vabdq_u8(q3u8, q6u8); - - q15u8 = vqaddq_u8(q15u8, q15u8); - q14u8 = vshrq_n_u8(q14u8, 1); - q0u8 = vdupq_n_u8(0x80); - q11s16 = vdupq_n_s16(3); - q15u8 = vqaddq_u8(q15u8, q14u8); - - q3u8 = veorq_u8(q3u8, q0u8); - q4u8 = veorq_u8(q4u8, q0u8); - q5u8 = veorq_u8(q5u8, q0u8); - q6u8 = veorq_u8(q6u8, q0u8); - - q15u8 = vcgeq_u8(qblimit, q15u8); - - q2s16 = vsubl_s8(vget_low_s8(vreinterpretq_s8_u8(q4u8)), - vget_low_s8(vreinterpretq_s8_u8(q5u8))); - q13s16 = vsubl_s8(vget_high_s8(vreinterpretq_s8_u8(q4u8)), - vget_high_s8(vreinterpretq_s8_u8(q5u8))); - - q14s8 = vqsubq_s8(vreinterpretq_s8_u8(q3u8), vreinterpretq_s8_u8(q6u8)); - - q2s16 = vmulq_s16(q2s16, q11s16); - q13s16 = vmulq_s16(q13s16, q11s16); - - q11u8 = vdupq_n_u8(3); - q12u8 = vdupq_n_u8(4); - - q2s16 = vaddw_s8(q2s16, vget_low_s8(q14s8)); - q13s16 = vaddw_s8(q13s16, vget_high_s8(q14s8)); - - d28s8 = vqmovn_s16(q2s16); - d29s8 = vqmovn_s16(q13s16); - q14s8 = vcombine_s8(d28s8, d29s8); - - q14s8 = vandq_s8(q14s8, vreinterpretq_s8_u8(q15u8)); - - q2s8 = vqaddq_s8(q14s8, vreinterpretq_s8_u8(q11u8)); - q3s8 = vqaddq_s8(q14s8, vreinterpretq_s8_u8(q12u8)); - q2s8 = vshrq_n_s8(q2s8, 3); - q14s8 = vshrq_n_s8(q3s8, 3); - - q11s8 = vqaddq_s8(vreinterpretq_s8_u8(q5u8), q2s8); - q10s8 = vqsubq_s8(vreinterpretq_s8_u8(q4u8), q14s8); - - q6u8 = veorq_u8(vreinterpretq_u8_s8(q11s8), q0u8); - q7u8 = veorq_u8(vreinterpretq_u8_s8(q10s8), q0u8); - - d2u8x2.val[0] = vget_low_u8(q6u8); // d12 - d2u8x2.val[1] = vget_low_u8(q7u8); // d14 - d3u8x2.val[0] = vget_high_u8(q6u8); // d13 - d3u8x2.val[1] = vget_high_u8(q7u8); // d15 - - src1 = s - 1; - write_2x8(src1, p, d2u8x2, d3u8x2); -} - -void vp8_loop_filter_bvs_neon(unsigned char *y_ptr, int y_stride, - const unsigned char *blimit) { - y_ptr += 4; - vp8_loop_filter_simple_vertical_edge_neon(y_ptr, y_stride, blimit); - y_ptr += 4; - vp8_loop_filter_simple_vertical_edge_neon(y_ptr, y_stride, blimit); - y_ptr += 4; - vp8_loop_filter_simple_vertical_edge_neon(y_ptr, y_stride, blimit); - return; -} - -void vp8_loop_filter_mbvs_neon(unsigned char *y_ptr, int y_stride, - const unsigned char *blimit) { - vp8_loop_filter_simple_vertical_edge_neon(y_ptr, y_stride, blimit); - return; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/mbloopfilter_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/mbloopfilter_neon.c deleted file mode 100644 index fafaf2d4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/mbloopfilter_neon.c +++ /dev/null @@ -1,613 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "vp8/common/arm/loopfilter_arm.h" - -static INLINE void vp8_mbloop_filter_neon(uint8x16_t qblimit, // mblimit - uint8x16_t qlimit, // limit - uint8x16_t qthresh, // thresh - uint8x16_t q3, // p2 - uint8x16_t q4, // p2 - uint8x16_t q5, // p1 - uint8x16_t q6, // p0 - uint8x16_t q7, // q0 - uint8x16_t q8, // q1 - uint8x16_t q9, // q2 - uint8x16_t q10, // q3 - uint8x16_t *q4r, // p1 - uint8x16_t *q5r, // p1 - uint8x16_t *q6r, // p0 - uint8x16_t *q7r, // q0 - uint8x16_t *q8r, // q1 - uint8x16_t *q9r) { // q1 - uint8x16_t q0u8, q1u8, q11u8, q12u8, q13u8, q14u8, q15u8; - int16x8_t q0s16, q2s16, q11s16, q12s16, q13s16, q14s16, q15s16; - int8x16_t q1s8, q6s8, q7s8, q2s8, q11s8, q13s8; - uint16x8_t q0u16, q11u16, q12u16, q13u16, q14u16, q15u16; - int8x16_t q0s8, q12s8, q14s8, q15s8; - int8x8_t d0, d1, d2, d3, d4, d5, d24, d25, d28, d29; - - q11u8 = vabdq_u8(q3, q4); - q12u8 = vabdq_u8(q4, q5); - q13u8 = vabdq_u8(q5, q6); - q14u8 = vabdq_u8(q8, q7); - q1u8 = vabdq_u8(q9, q8); - q0u8 = vabdq_u8(q10, q9); - - q11u8 = vmaxq_u8(q11u8, q12u8); - q12u8 = vmaxq_u8(q13u8, q14u8); - q1u8 = vmaxq_u8(q1u8, q0u8); - q15u8 = vmaxq_u8(q11u8, q12u8); - - q12u8 = vabdq_u8(q6, q7); - - // vp8_hevmask - q13u8 = vcgtq_u8(q13u8, qthresh); - q14u8 = vcgtq_u8(q14u8, qthresh); - q15u8 = vmaxq_u8(q15u8, q1u8); - - q15u8 = vcgeq_u8(qlimit, q15u8); - - q1u8 = vabdq_u8(q5, q8); - q12u8 = vqaddq_u8(q12u8, q12u8); - - // vp8_filter() function - // convert to signed - q0u8 = vdupq_n_u8(0x80); - q9 = veorq_u8(q9, q0u8); - q8 = veorq_u8(q8, q0u8); - q7 = veorq_u8(q7, q0u8); - q6 = veorq_u8(q6, q0u8); - q5 = veorq_u8(q5, q0u8); - q4 = veorq_u8(q4, q0u8); - - q1u8 = vshrq_n_u8(q1u8, 1); - q12u8 = vqaddq_u8(q12u8, q1u8); - - q14u8 = vorrq_u8(q13u8, q14u8); - q12u8 = vcgeq_u8(qblimit, q12u8); - - q2s16 = vsubl_s8(vget_low_s8(vreinterpretq_s8_u8(q7)), - vget_low_s8(vreinterpretq_s8_u8(q6))); - q13s16 = vsubl_s8(vget_high_s8(vreinterpretq_s8_u8(q7)), - vget_high_s8(vreinterpretq_s8_u8(q6))); - - q1s8 = vqsubq_s8(vreinterpretq_s8_u8(q5), vreinterpretq_s8_u8(q8)); - - q11s16 = vdupq_n_s16(3); - q2s16 = vmulq_s16(q2s16, q11s16); - q13s16 = vmulq_s16(q13s16, q11s16); - - q15u8 = vandq_u8(q15u8, q12u8); - - q2s16 = vaddw_s8(q2s16, vget_low_s8(q1s8)); - q13s16 = vaddw_s8(q13s16, vget_high_s8(q1s8)); - - q12u8 = vdupq_n_u8(3); - q11u8 = vdupq_n_u8(4); - // vp8_filter = clamp(vp8_filter + 3 * ( qs0 - ps0)) - d2 = vqmovn_s16(q2s16); - d3 = vqmovn_s16(q13s16); - q1s8 = vcombine_s8(d2, d3); - q1s8 = vandq_s8(q1s8, vreinterpretq_s8_u8(q15u8)); - q13s8 = vandq_s8(q1s8, vreinterpretq_s8_u8(q14u8)); - - q2s8 = vqaddq_s8(q13s8, vreinterpretq_s8_u8(q11u8)); - q13s8 = vqaddq_s8(q13s8, vreinterpretq_s8_u8(q12u8)); - q2s8 = vshrq_n_s8(q2s8, 3); - q13s8 = vshrq_n_s8(q13s8, 3); - - q7s8 = vqsubq_s8(vreinterpretq_s8_u8(q7), q2s8); - q6s8 = vqaddq_s8(vreinterpretq_s8_u8(q6), q13s8); - - q1s8 = vbicq_s8(q1s8, vreinterpretq_s8_u8(q14u8)); - - q0u16 = q11u16 = q12u16 = q13u16 = q14u16 = q15u16 = vdupq_n_u16(63); - d5 = vdup_n_s8(9); - d4 = vdup_n_s8(18); - - q0s16 = vmlal_s8(vreinterpretq_s16_u16(q0u16), vget_low_s8(q1s8), d5); - q11s16 = vmlal_s8(vreinterpretq_s16_u16(q11u16), vget_high_s8(q1s8), d5); - d5 = vdup_n_s8(27); - q12s16 = vmlal_s8(vreinterpretq_s16_u16(q12u16), vget_low_s8(q1s8), d4); - q13s16 = vmlal_s8(vreinterpretq_s16_u16(q13u16), vget_high_s8(q1s8), d4); - q14s16 = vmlal_s8(vreinterpretq_s16_u16(q14u16), vget_low_s8(q1s8), d5); - q15s16 = vmlal_s8(vreinterpretq_s16_u16(q15u16), vget_high_s8(q1s8), d5); - - d0 = vqshrn_n_s16(q0s16, 7); - d1 = vqshrn_n_s16(q11s16, 7); - d24 = vqshrn_n_s16(q12s16, 7); - d25 = vqshrn_n_s16(q13s16, 7); - d28 = vqshrn_n_s16(q14s16, 7); - d29 = vqshrn_n_s16(q15s16, 7); - - q0s8 = vcombine_s8(d0, d1); - q12s8 = vcombine_s8(d24, d25); - q14s8 = vcombine_s8(d28, d29); - - q11s8 = vqsubq_s8(vreinterpretq_s8_u8(q9), q0s8); - q0s8 = vqaddq_s8(vreinterpretq_s8_u8(q4), q0s8); - q13s8 = vqsubq_s8(vreinterpretq_s8_u8(q8), q12s8); - q12s8 = vqaddq_s8(vreinterpretq_s8_u8(q5), q12s8); - q15s8 = vqsubq_s8((q7s8), q14s8); - q14s8 = vqaddq_s8((q6s8), q14s8); - - q1u8 = vdupq_n_u8(0x80); - *q9r = veorq_u8(vreinterpretq_u8_s8(q11s8), q1u8); - *q8r = veorq_u8(vreinterpretq_u8_s8(q13s8), q1u8); - *q7r = veorq_u8(vreinterpretq_u8_s8(q15s8), q1u8); - *q6r = veorq_u8(vreinterpretq_u8_s8(q14s8), q1u8); - *q5r = veorq_u8(vreinterpretq_u8_s8(q12s8), q1u8); - *q4r = veorq_u8(vreinterpretq_u8_s8(q0s8), q1u8); - return; -} - -void vp8_mbloop_filter_horizontal_edge_y_neon(unsigned char *src, int pitch, - unsigned char blimit, - unsigned char limit, - unsigned char thresh) { - uint8x16_t qblimit, qlimit, qthresh, q3, q4; - uint8x16_t q5, q6, q7, q8, q9, q10; - - qblimit = vdupq_n_u8(blimit); - qlimit = vdupq_n_u8(limit); - qthresh = vdupq_n_u8(thresh); - - src -= (pitch << 2); - - q3 = vld1q_u8(src); - src += pitch; - q4 = vld1q_u8(src); - src += pitch; - q5 = vld1q_u8(src); - src += pitch; - q6 = vld1q_u8(src); - src += pitch; - q7 = vld1q_u8(src); - src += pitch; - q8 = vld1q_u8(src); - src += pitch; - q9 = vld1q_u8(src); - src += pitch; - q10 = vld1q_u8(src); - - vp8_mbloop_filter_neon(qblimit, qlimit, qthresh, q3, q4, q5, q6, q7, q8, q9, - q10, &q4, &q5, &q6, &q7, &q8, &q9); - - src -= (pitch * 6); - vst1q_u8(src, q4); - src += pitch; - vst1q_u8(src, q5); - src += pitch; - vst1q_u8(src, q6); - src += pitch; - vst1q_u8(src, q7); - src += pitch; - vst1q_u8(src, q8); - src += pitch; - vst1q_u8(src, q9); - return; -} - -void vp8_mbloop_filter_horizontal_edge_uv_neon(unsigned char *u, int pitch, - unsigned char blimit, - unsigned char limit, - unsigned char thresh, - unsigned char *v) { - uint8x16_t qblimit, qlimit, qthresh, q3, q4; - uint8x16_t q5, q6, q7, q8, q9, q10; - uint8x8_t d6, d7, d8, d9, d10, d11, d12, d13, d14; - uint8x8_t d15, d16, d17, d18, d19, d20, d21; - - qblimit = vdupq_n_u8(blimit); - qlimit = vdupq_n_u8(limit); - qthresh = vdupq_n_u8(thresh); - - u -= (pitch << 2); - v -= (pitch << 2); - - d6 = vld1_u8(u); - u += pitch; - d7 = vld1_u8(v); - v += pitch; - d8 = vld1_u8(u); - u += pitch; - d9 = vld1_u8(v); - v += pitch; - d10 = vld1_u8(u); - u += pitch; - d11 = vld1_u8(v); - v += pitch; - d12 = vld1_u8(u); - u += pitch; - d13 = vld1_u8(v); - v += pitch; - d14 = vld1_u8(u); - u += pitch; - d15 = vld1_u8(v); - v += pitch; - d16 = vld1_u8(u); - u += pitch; - d17 = vld1_u8(v); - v += pitch; - d18 = vld1_u8(u); - u += pitch; - d19 = vld1_u8(v); - v += pitch; - d20 = vld1_u8(u); - d21 = vld1_u8(v); - - q3 = vcombine_u8(d6, d7); - q4 = vcombine_u8(d8, d9); - q5 = vcombine_u8(d10, d11); - q6 = vcombine_u8(d12, d13); - q7 = vcombine_u8(d14, d15); - q8 = vcombine_u8(d16, d17); - q9 = vcombine_u8(d18, d19); - q10 = vcombine_u8(d20, d21); - - vp8_mbloop_filter_neon(qblimit, qlimit, qthresh, q3, q4, q5, q6, q7, q8, q9, - q10, &q4, &q5, &q6, &q7, &q8, &q9); - - u -= (pitch * 6); - v -= (pitch * 6); - vst1_u8(u, vget_low_u8(q4)); - u += pitch; - vst1_u8(v, vget_high_u8(q4)); - v += pitch; - vst1_u8(u, vget_low_u8(q5)); - u += pitch; - vst1_u8(v, vget_high_u8(q5)); - v += pitch; - vst1_u8(u, vget_low_u8(q6)); - u += pitch; - vst1_u8(v, vget_high_u8(q6)); - v += pitch; - vst1_u8(u, vget_low_u8(q7)); - u += pitch; - vst1_u8(v, vget_high_u8(q7)); - v += pitch; - vst1_u8(u, vget_low_u8(q8)); - u += pitch; - vst1_u8(v, vget_high_u8(q8)); - v += pitch; - vst1_u8(u, vget_low_u8(q9)); - vst1_u8(v, vget_high_u8(q9)); - return; -} - -void vp8_mbloop_filter_vertical_edge_y_neon(unsigned char *src, int pitch, - unsigned char blimit, - unsigned char limit, - unsigned char thresh) { - unsigned char *s1, *s2; - uint8x16_t qblimit, qlimit, qthresh, q3, q4; - uint8x16_t q5, q6, q7, q8, q9, q10; - uint8x8_t d6, d7, d8, d9, d10, d11, d12, d13, d14; - uint8x8_t d15, d16, d17, d18, d19, d20, d21; - uint32x4x2_t q2tmp0, q2tmp1, q2tmp2, q2tmp3; - uint16x8x2_t q2tmp4, q2tmp5, q2tmp6, q2tmp7; - uint8x16x2_t q2tmp8, q2tmp9, q2tmp10, q2tmp11; - - qblimit = vdupq_n_u8(blimit); - qlimit = vdupq_n_u8(limit); - qthresh = vdupq_n_u8(thresh); - - s1 = src - 4; - s2 = s1 + 8 * pitch; - d6 = vld1_u8(s1); - s1 += pitch; - d7 = vld1_u8(s2); - s2 += pitch; - d8 = vld1_u8(s1); - s1 += pitch; - d9 = vld1_u8(s2); - s2 += pitch; - d10 = vld1_u8(s1); - s1 += pitch; - d11 = vld1_u8(s2); - s2 += pitch; - d12 = vld1_u8(s1); - s1 += pitch; - d13 = vld1_u8(s2); - s2 += pitch; - d14 = vld1_u8(s1); - s1 += pitch; - d15 = vld1_u8(s2); - s2 += pitch; - d16 = vld1_u8(s1); - s1 += pitch; - d17 = vld1_u8(s2); - s2 += pitch; - d18 = vld1_u8(s1); - s1 += pitch; - d19 = vld1_u8(s2); - s2 += pitch; - d20 = vld1_u8(s1); - d21 = vld1_u8(s2); - - q3 = vcombine_u8(d6, d7); - q4 = vcombine_u8(d8, d9); - q5 = vcombine_u8(d10, d11); - q6 = vcombine_u8(d12, d13); - q7 = vcombine_u8(d14, d15); - q8 = vcombine_u8(d16, d17); - q9 = vcombine_u8(d18, d19); - q10 = vcombine_u8(d20, d21); - - q2tmp0 = vtrnq_u32(vreinterpretq_u32_u8(q3), vreinterpretq_u32_u8(q7)); - q2tmp1 = vtrnq_u32(vreinterpretq_u32_u8(q4), vreinterpretq_u32_u8(q8)); - q2tmp2 = vtrnq_u32(vreinterpretq_u32_u8(q5), vreinterpretq_u32_u8(q9)); - q2tmp3 = vtrnq_u32(vreinterpretq_u32_u8(q6), vreinterpretq_u32_u8(q10)); - - q2tmp4 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp0.val[0]), - vreinterpretq_u16_u32(q2tmp2.val[0])); - q2tmp5 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp1.val[0]), - vreinterpretq_u16_u32(q2tmp3.val[0])); - q2tmp6 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp0.val[1]), - vreinterpretq_u16_u32(q2tmp2.val[1])); - q2tmp7 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp1.val[1]), - vreinterpretq_u16_u32(q2tmp3.val[1])); - - q2tmp8 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp4.val[0]), - vreinterpretq_u8_u16(q2tmp5.val[0])); - q2tmp9 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp4.val[1]), - vreinterpretq_u8_u16(q2tmp5.val[1])); - q2tmp10 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp6.val[0]), - vreinterpretq_u8_u16(q2tmp7.val[0])); - q2tmp11 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp6.val[1]), - vreinterpretq_u8_u16(q2tmp7.val[1])); - - q3 = q2tmp8.val[0]; - q4 = q2tmp8.val[1]; - q5 = q2tmp9.val[0]; - q6 = q2tmp9.val[1]; - q7 = q2tmp10.val[0]; - q8 = q2tmp10.val[1]; - q9 = q2tmp11.val[0]; - q10 = q2tmp11.val[1]; - - vp8_mbloop_filter_neon(qblimit, qlimit, qthresh, q3, q4, q5, q6, q7, q8, q9, - q10, &q4, &q5, &q6, &q7, &q8, &q9); - - q2tmp0 = vtrnq_u32(vreinterpretq_u32_u8(q3), vreinterpretq_u32_u8(q7)); - q2tmp1 = vtrnq_u32(vreinterpretq_u32_u8(q4), vreinterpretq_u32_u8(q8)); - q2tmp2 = vtrnq_u32(vreinterpretq_u32_u8(q5), vreinterpretq_u32_u8(q9)); - q2tmp3 = vtrnq_u32(vreinterpretq_u32_u8(q6), vreinterpretq_u32_u8(q10)); - - q2tmp4 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp0.val[0]), - vreinterpretq_u16_u32(q2tmp2.val[0])); - q2tmp5 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp1.val[0]), - vreinterpretq_u16_u32(q2tmp3.val[0])); - q2tmp6 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp0.val[1]), - vreinterpretq_u16_u32(q2tmp2.val[1])); - q2tmp7 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp1.val[1]), - vreinterpretq_u16_u32(q2tmp3.val[1])); - - q2tmp8 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp4.val[0]), - vreinterpretq_u8_u16(q2tmp5.val[0])); - q2tmp9 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp4.val[1]), - vreinterpretq_u8_u16(q2tmp5.val[1])); - q2tmp10 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp6.val[0]), - vreinterpretq_u8_u16(q2tmp7.val[0])); - q2tmp11 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp6.val[1]), - vreinterpretq_u8_u16(q2tmp7.val[1])); - - q3 = q2tmp8.val[0]; - q4 = q2tmp8.val[1]; - q5 = q2tmp9.val[0]; - q6 = q2tmp9.val[1]; - q7 = q2tmp10.val[0]; - q8 = q2tmp10.val[1]; - q9 = q2tmp11.val[0]; - q10 = q2tmp11.val[1]; - - s1 -= 7 * pitch; - s2 -= 7 * pitch; - - vst1_u8(s1, vget_low_u8(q3)); - s1 += pitch; - vst1_u8(s2, vget_high_u8(q3)); - s2 += pitch; - vst1_u8(s1, vget_low_u8(q4)); - s1 += pitch; - vst1_u8(s2, vget_high_u8(q4)); - s2 += pitch; - vst1_u8(s1, vget_low_u8(q5)); - s1 += pitch; - vst1_u8(s2, vget_high_u8(q5)); - s2 += pitch; - vst1_u8(s1, vget_low_u8(q6)); - s1 += pitch; - vst1_u8(s2, vget_high_u8(q6)); - s2 += pitch; - vst1_u8(s1, vget_low_u8(q7)); - s1 += pitch; - vst1_u8(s2, vget_high_u8(q7)); - s2 += pitch; - vst1_u8(s1, vget_low_u8(q8)); - s1 += pitch; - vst1_u8(s2, vget_high_u8(q8)); - s2 += pitch; - vst1_u8(s1, vget_low_u8(q9)); - s1 += pitch; - vst1_u8(s2, vget_high_u8(q9)); - s2 += pitch; - vst1_u8(s1, vget_low_u8(q10)); - vst1_u8(s2, vget_high_u8(q10)); - return; -} - -void vp8_mbloop_filter_vertical_edge_uv_neon(unsigned char *u, int pitch, - unsigned char blimit, - unsigned char limit, - unsigned char thresh, - unsigned char *v) { - unsigned char *us, *ud; - unsigned char *vs, *vd; - uint8x16_t qblimit, qlimit, qthresh, q3, q4; - uint8x16_t q5, q6, q7, q8, q9, q10; - uint8x8_t d6, d7, d8, d9, d10, d11, d12, d13, d14; - uint8x8_t d15, d16, d17, d18, d19, d20, d21; - uint32x4x2_t q2tmp0, q2tmp1, q2tmp2, q2tmp3; - uint16x8x2_t q2tmp4, q2tmp5, q2tmp6, q2tmp7; - uint8x16x2_t q2tmp8, q2tmp9, q2tmp10, q2tmp11; - - qblimit = vdupq_n_u8(blimit); - qlimit = vdupq_n_u8(limit); - qthresh = vdupq_n_u8(thresh); - - us = u - 4; - vs = v - 4; - d6 = vld1_u8(us); - us += pitch; - d7 = vld1_u8(vs); - vs += pitch; - d8 = vld1_u8(us); - us += pitch; - d9 = vld1_u8(vs); - vs += pitch; - d10 = vld1_u8(us); - us += pitch; - d11 = vld1_u8(vs); - vs += pitch; - d12 = vld1_u8(us); - us += pitch; - d13 = vld1_u8(vs); - vs += pitch; - d14 = vld1_u8(us); - us += pitch; - d15 = vld1_u8(vs); - vs += pitch; - d16 = vld1_u8(us); - us += pitch; - d17 = vld1_u8(vs); - vs += pitch; - d18 = vld1_u8(us); - us += pitch; - d19 = vld1_u8(vs); - vs += pitch; - d20 = vld1_u8(us); - d21 = vld1_u8(vs); - - q3 = vcombine_u8(d6, d7); - q4 = vcombine_u8(d8, d9); - q5 = vcombine_u8(d10, d11); - q6 = vcombine_u8(d12, d13); - q7 = vcombine_u8(d14, d15); - q8 = vcombine_u8(d16, d17); - q9 = vcombine_u8(d18, d19); - q10 = vcombine_u8(d20, d21); - - q2tmp0 = vtrnq_u32(vreinterpretq_u32_u8(q3), vreinterpretq_u32_u8(q7)); - q2tmp1 = vtrnq_u32(vreinterpretq_u32_u8(q4), vreinterpretq_u32_u8(q8)); - q2tmp2 = vtrnq_u32(vreinterpretq_u32_u8(q5), vreinterpretq_u32_u8(q9)); - q2tmp3 = vtrnq_u32(vreinterpretq_u32_u8(q6), vreinterpretq_u32_u8(q10)); - - q2tmp4 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp0.val[0]), - vreinterpretq_u16_u32(q2tmp2.val[0])); - q2tmp5 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp1.val[0]), - vreinterpretq_u16_u32(q2tmp3.val[0])); - q2tmp6 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp0.val[1]), - vreinterpretq_u16_u32(q2tmp2.val[1])); - q2tmp7 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp1.val[1]), - vreinterpretq_u16_u32(q2tmp3.val[1])); - - q2tmp8 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp4.val[0]), - vreinterpretq_u8_u16(q2tmp5.val[0])); - q2tmp9 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp4.val[1]), - vreinterpretq_u8_u16(q2tmp5.val[1])); - q2tmp10 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp6.val[0]), - vreinterpretq_u8_u16(q2tmp7.val[0])); - q2tmp11 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp6.val[1]), - vreinterpretq_u8_u16(q2tmp7.val[1])); - - q3 = q2tmp8.val[0]; - q4 = q2tmp8.val[1]; - q5 = q2tmp9.val[0]; - q6 = q2tmp9.val[1]; - q7 = q2tmp10.val[0]; - q8 = q2tmp10.val[1]; - q9 = q2tmp11.val[0]; - q10 = q2tmp11.val[1]; - - vp8_mbloop_filter_neon(qblimit, qlimit, qthresh, q3, q4, q5, q6, q7, q8, q9, - q10, &q4, &q5, &q6, &q7, &q8, &q9); - - q2tmp0 = vtrnq_u32(vreinterpretq_u32_u8(q3), vreinterpretq_u32_u8(q7)); - q2tmp1 = vtrnq_u32(vreinterpretq_u32_u8(q4), vreinterpretq_u32_u8(q8)); - q2tmp2 = vtrnq_u32(vreinterpretq_u32_u8(q5), vreinterpretq_u32_u8(q9)); - q2tmp3 = vtrnq_u32(vreinterpretq_u32_u8(q6), vreinterpretq_u32_u8(q10)); - - q2tmp4 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp0.val[0]), - vreinterpretq_u16_u32(q2tmp2.val[0])); - q2tmp5 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp1.val[0]), - vreinterpretq_u16_u32(q2tmp3.val[0])); - q2tmp6 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp0.val[1]), - vreinterpretq_u16_u32(q2tmp2.val[1])); - q2tmp7 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp1.val[1]), - vreinterpretq_u16_u32(q2tmp3.val[1])); - - q2tmp8 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp4.val[0]), - vreinterpretq_u8_u16(q2tmp5.val[0])); - q2tmp9 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp4.val[1]), - vreinterpretq_u8_u16(q2tmp5.val[1])); - q2tmp10 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp6.val[0]), - vreinterpretq_u8_u16(q2tmp7.val[0])); - q2tmp11 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp6.val[1]), - vreinterpretq_u8_u16(q2tmp7.val[1])); - - q3 = q2tmp8.val[0]; - q4 = q2tmp8.val[1]; - q5 = q2tmp9.val[0]; - q6 = q2tmp9.val[1]; - q7 = q2tmp10.val[0]; - q8 = q2tmp10.val[1]; - q9 = q2tmp11.val[0]; - q10 = q2tmp11.val[1]; - - ud = u - 4; - vst1_u8(ud, vget_low_u8(q3)); - ud += pitch; - vst1_u8(ud, vget_low_u8(q4)); - ud += pitch; - vst1_u8(ud, vget_low_u8(q5)); - ud += pitch; - vst1_u8(ud, vget_low_u8(q6)); - ud += pitch; - vst1_u8(ud, vget_low_u8(q7)); - ud += pitch; - vst1_u8(ud, vget_low_u8(q8)); - ud += pitch; - vst1_u8(ud, vget_low_u8(q9)); - ud += pitch; - vst1_u8(ud, vget_low_u8(q10)); - - vd = v - 4; - vst1_u8(vd, vget_high_u8(q3)); - vd += pitch; - vst1_u8(vd, vget_high_u8(q4)); - vd += pitch; - vst1_u8(vd, vget_high_u8(q5)); - vd += pitch; - vst1_u8(vd, vget_high_u8(q6)); - vd += pitch; - vst1_u8(vd, vget_high_u8(q7)); - vd += pitch; - vst1_u8(vd, vget_high_u8(q8)); - vd += pitch; - vst1_u8(vd, vget_high_u8(q9)); - vd += pitch; - vst1_u8(vd, vget_high_u8(q10)); - return; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/shortidct4x4llm_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/shortidct4x4llm_neon.c deleted file mode 100644 index 2724ca23..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/shortidct4x4llm_neon.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp8_rtcd.h" - -static const int16_t cospi8sqrt2minus1 = 20091; -// 35468 exceeds INT16_MAX and gets converted to a negative number. Because of -// the way it is used in vqdmulh, where the result is doubled, it can be divided -// by 2 beforehand. This saves compensating for the negative value as well as -// shifting the result. -static const int16_t sinpi8sqrt2 = 35468 >> 1; - -void vp8_short_idct4x4llm_neon(int16_t *input, unsigned char *pred_ptr, - int pred_stride, unsigned char *dst_ptr, - int dst_stride) { - int i; - uint32x2_t d6u32 = vdup_n_u32(0); - uint8x8_t d1u8; - int16x4_t d2, d3, d4, d5, d10, d11, d12, d13; - uint16x8_t q1u16; - int16x8_t q1s16, q2s16, q3s16, q4s16; - int32x2x2_t v2tmp0, v2tmp1; - int16x4x2_t v2tmp2, v2tmp3; - - d2 = vld1_s16(input); - d3 = vld1_s16(input + 4); - d4 = vld1_s16(input + 8); - d5 = vld1_s16(input + 12); - - // 1st for loop - q1s16 = vcombine_s16(d2, d4); // Swap d3 d4 here - q2s16 = vcombine_s16(d3, d5); - - q3s16 = vqdmulhq_n_s16(q2s16, sinpi8sqrt2); - q4s16 = vqdmulhq_n_s16(q2s16, cospi8sqrt2minus1); - - d12 = vqadd_s16(vget_low_s16(q1s16), vget_high_s16(q1s16)); // a1 - d13 = vqsub_s16(vget_low_s16(q1s16), vget_high_s16(q1s16)); // b1 - - q4s16 = vshrq_n_s16(q4s16, 1); - - q4s16 = vqaddq_s16(q4s16, q2s16); - - d10 = vqsub_s16(vget_low_s16(q3s16), vget_high_s16(q4s16)); // c1 - d11 = vqadd_s16(vget_high_s16(q3s16), vget_low_s16(q4s16)); // d1 - - d2 = vqadd_s16(d12, d11); - d3 = vqadd_s16(d13, d10); - d4 = vqsub_s16(d13, d10); - d5 = vqsub_s16(d12, d11); - - v2tmp0 = vtrn_s32(vreinterpret_s32_s16(d2), vreinterpret_s32_s16(d4)); - v2tmp1 = vtrn_s32(vreinterpret_s32_s16(d3), vreinterpret_s32_s16(d5)); - v2tmp2 = vtrn_s16(vreinterpret_s16_s32(v2tmp0.val[0]), - vreinterpret_s16_s32(v2tmp1.val[0])); - v2tmp3 = vtrn_s16(vreinterpret_s16_s32(v2tmp0.val[1]), - vreinterpret_s16_s32(v2tmp1.val[1])); - - // 2nd for loop - q1s16 = vcombine_s16(v2tmp2.val[0], v2tmp3.val[0]); - q2s16 = vcombine_s16(v2tmp2.val[1], v2tmp3.val[1]); - - q3s16 = vqdmulhq_n_s16(q2s16, sinpi8sqrt2); - q4s16 = vqdmulhq_n_s16(q2s16, cospi8sqrt2minus1); - - d12 = vqadd_s16(vget_low_s16(q1s16), vget_high_s16(q1s16)); // a1 - d13 = vqsub_s16(vget_low_s16(q1s16), vget_high_s16(q1s16)); // b1 - - q4s16 = vshrq_n_s16(q4s16, 1); - - q4s16 = vqaddq_s16(q4s16, q2s16); - - d10 = vqsub_s16(vget_low_s16(q3s16), vget_high_s16(q4s16)); // c1 - d11 = vqadd_s16(vget_high_s16(q3s16), vget_low_s16(q4s16)); // d1 - - d2 = vqadd_s16(d12, d11); - d3 = vqadd_s16(d13, d10); - d4 = vqsub_s16(d13, d10); - d5 = vqsub_s16(d12, d11); - - d2 = vrshr_n_s16(d2, 3); - d3 = vrshr_n_s16(d3, 3); - d4 = vrshr_n_s16(d4, 3); - d5 = vrshr_n_s16(d5, 3); - - v2tmp0 = vtrn_s32(vreinterpret_s32_s16(d2), vreinterpret_s32_s16(d4)); - v2tmp1 = vtrn_s32(vreinterpret_s32_s16(d3), vreinterpret_s32_s16(d5)); - v2tmp2 = vtrn_s16(vreinterpret_s16_s32(v2tmp0.val[0]), - vreinterpret_s16_s32(v2tmp1.val[0])); - v2tmp3 = vtrn_s16(vreinterpret_s16_s32(v2tmp0.val[1]), - vreinterpret_s16_s32(v2tmp1.val[1])); - - q1s16 = vcombine_s16(v2tmp2.val[0], v2tmp2.val[1]); - q2s16 = vcombine_s16(v2tmp3.val[0], v2tmp3.val[1]); - - // dc_only_idct_add - for (i = 0; i < 2; i++, q1s16 = q2s16) { - d6u32 = vld1_lane_u32((const uint32_t *)pred_ptr, d6u32, 0); - pred_ptr += pred_stride; - d6u32 = vld1_lane_u32((const uint32_t *)pred_ptr, d6u32, 1); - pred_ptr += pred_stride; - - q1u16 = vaddw_u8(vreinterpretq_u16_s16(q1s16), vreinterpret_u8_u32(d6u32)); - d1u8 = vqmovun_s16(vreinterpretq_s16_u16(q1u16)); - - vst1_lane_u32((uint32_t *)dst_ptr, vreinterpret_u32_u8(d1u8), 0); - dst_ptr += dst_stride; - vst1_lane_u32((uint32_t *)dst_ptr, vreinterpret_u32_u8(d1u8), 1); - dst_ptr += dst_stride; - } - return; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/sixtappredict_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/sixtappredict_neon.c deleted file mode 100644 index a54e8108..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/sixtappredict_neon.c +++ /dev/null @@ -1,1729 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include "./vpx_config.h" -#include "./vp8_rtcd.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_ports/mem.h" - -static const int8_t vp8_sub_pel_filters[8][8] = { - { 0, 0, -128, 0, 0, 0, 0, 0 }, /* note that 1/8 pel positions are */ - { 0, -6, 123, 12, -1, 0, 0, 0 }, /* just as per alpha -0.5 bicubic */ - { 2, -11, 108, 36, -8, 1, 0, 0 }, /* New 1/4 pel 6 tap filter */ - { 0, -9, 93, 50, -6, 0, 0, 0 }, - { 3, -16, 77, 77, -16, 3, 0, 0 }, /* New 1/2 pel 6 tap filter */ - { 0, -6, 50, 93, -9, 0, 0, 0 }, - { 1, -8, 36, 108, -11, 2, 0, 0 }, /* New 1/4 pel 6 tap filter */ - { 0, -1, 12, 123, -6, 0, 0, 0 }, -}; - -// This table is derived from vp8/common/filter.c:vp8_sub_pel_filters. -// Apply abs() to all the values. Elements 0, 2, 3, and 5 are always positive. -// Elements 1 and 4 are either 0 or negative. The code accounts for this with -// multiply/accumulates which either add or subtract as needed. The other -// functions will be updated to use this table later. -// It is also expanded to 8 elements to allow loading into 64 bit neon -// registers. -static const uint8_t abs_filters[8][8] = { - { 0, 0, 128, 0, 0, 0, 0, 0 }, { 0, 6, 123, 12, 1, 0, 0, 0 }, - { 2, 11, 108, 36, 8, 1, 0, 0 }, { 0, 9, 93, 50, 6, 0, 0, 0 }, - { 3, 16, 77, 77, 16, 3, 0, 0 }, { 0, 6, 50, 93, 9, 0, 0, 0 }, - { 1, 8, 36, 108, 11, 2, 0, 0 }, { 0, 1, 12, 123, 6, 0, 0, 0 }, -}; - -static INLINE uint8x8_t load_and_shift(const unsigned char *a) { - return vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(vld1_u8(a)), 32)); -} - -static INLINE void filter_add_accumulate(const uint8x16_t a, const uint8x16_t b, - const uint8x8_t filter, uint16x8_t *c, - uint16x8_t *d) { - const uint32x2x2_t a_shuf = vzip_u32(vreinterpret_u32_u8(vget_low_u8(a)), - vreinterpret_u32_u8(vget_high_u8(a))); - const uint32x2x2_t b_shuf = vzip_u32(vreinterpret_u32_u8(vget_low_u8(b)), - vreinterpret_u32_u8(vget_high_u8(b))); - *c = vmlal_u8(*c, vreinterpret_u8_u32(a_shuf.val[0]), filter); - *d = vmlal_u8(*d, vreinterpret_u8_u32(b_shuf.val[0]), filter); -} - -static INLINE void filter_sub_accumulate(const uint8x16_t a, const uint8x16_t b, - const uint8x8_t filter, uint16x8_t *c, - uint16x8_t *d) { - const uint32x2x2_t a_shuf = vzip_u32(vreinterpret_u32_u8(vget_low_u8(a)), - vreinterpret_u32_u8(vget_high_u8(a))); - const uint32x2x2_t b_shuf = vzip_u32(vreinterpret_u32_u8(vget_low_u8(b)), - vreinterpret_u32_u8(vget_high_u8(b))); - *c = vmlsl_u8(*c, vreinterpret_u8_u32(a_shuf.val[0]), filter); - *d = vmlsl_u8(*d, vreinterpret_u8_u32(b_shuf.val[0]), filter); -} - -static INLINE void yonly4x4(const unsigned char *src, int src_stride, - int filter_offset, unsigned char *dst, - int dst_stride) { - uint8x8_t a0, a1, a2, a3, a4, a5, a6, a7, a8; - uint8x8_t b0, b1, b2, b3, b4, b5, b6, b7, b8; - uint16x8_t c0, c1, c2, c3; - int16x8_t d0, d1; - uint8x8_t e0, e1; - - const uint8x8_t filter = vld1_u8(abs_filters[filter_offset]); - const uint8x8_t filter0 = vdup_lane_u8(filter, 0); - const uint8x8_t filter1 = vdup_lane_u8(filter, 1); - const uint8x8_t filter2 = vdup_lane_u8(filter, 2); - const uint8x8_t filter3 = vdup_lane_u8(filter, 3); - const uint8x8_t filter4 = vdup_lane_u8(filter, 4); - const uint8x8_t filter5 = vdup_lane_u8(filter, 5); - - src -= src_stride * 2; - // Shift the even rows to allow using 'vext' to combine the vectors. armv8 - // has vcopy_lane which would be interesting. This started as just a - // horrible workaround for clang adding alignment hints to 32bit loads: - // https://llvm.org/bugs/show_bug.cgi?id=24421 - // But it turns out it almost identical to casting the loads. - a0 = load_and_shift(src); - src += src_stride; - a1 = vld1_u8(src); - src += src_stride; - a2 = load_and_shift(src); - src += src_stride; - a3 = vld1_u8(src); - src += src_stride; - a4 = load_and_shift(src); - src += src_stride; - a5 = vld1_u8(src); - src += src_stride; - a6 = load_and_shift(src); - src += src_stride; - a7 = vld1_u8(src); - src += src_stride; - a8 = vld1_u8(src); - - // Combine the rows so we can operate on 8 at a time. - b0 = vext_u8(a0, a1, 4); - b2 = vext_u8(a2, a3, 4); - b4 = vext_u8(a4, a5, 4); - b6 = vext_u8(a6, a7, 4); - b8 = a8; - - // To keep with the 8-at-a-time theme, combine *alternate* rows. This - // allows combining the odd rows with the even. - b1 = vext_u8(b0, b2, 4); - b3 = vext_u8(b2, b4, 4); - b5 = vext_u8(b4, b6, 4); - b7 = vext_u8(b6, b8, 4); - - // Multiply and expand to 16 bits. - c0 = vmull_u8(b0, filter0); - c1 = vmull_u8(b2, filter0); - c2 = vmull_u8(b5, filter5); - c3 = vmull_u8(b7, filter5); - - // Multiply, subtract and accumulate for filters 1 and 4 (the negative - // ones). - c0 = vmlsl_u8(c0, b4, filter4); - c1 = vmlsl_u8(c1, b6, filter4); - c2 = vmlsl_u8(c2, b1, filter1); - c3 = vmlsl_u8(c3, b3, filter1); - - // Add more positive ones. vmlal should really return a signed type. - // It's doing signed math internally, as evidenced by the fact we can do - // subtractions followed by more additions. Ideally we could use - // vqmlal/sl but that instruction doesn't exist. Might be able to - // shoehorn vqdmlal/vqdmlsl in here but it would take some effort. - c0 = vmlal_u8(c0, b2, filter2); - c1 = vmlal_u8(c1, b4, filter2); - c2 = vmlal_u8(c2, b3, filter3); - c3 = vmlal_u8(c3, b5, filter3); - - // Use signed saturation math because vmlsl may have left some negative - // numbers in there. - d0 = vqaddq_s16(vreinterpretq_s16_u16(c2), vreinterpretq_s16_u16(c0)); - d1 = vqaddq_s16(vreinterpretq_s16_u16(c3), vreinterpretq_s16_u16(c1)); - - // Use signed again because numbers like -200 need to be saturated to 0. - e0 = vqrshrun_n_s16(d0, 7); - e1 = vqrshrun_n_s16(d1, 7); - - store_unaligned_u8q(dst, dst_stride, vcombine_u8(e0, e1)); -} - -void vp8_sixtap_predict4x4_neon(unsigned char *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, - unsigned char *dst_ptr, int dst_pitch) { - uint8x16_t s0, s1, s2, s3, s4; - uint64x2_t s01, s23; - // Variables to hold src[] elements for the given filter[] - uint8x8_t s0_f5, s1_f5, s2_f5, s3_f5, s4_f5; - uint8x8_t s4_f1, s4_f2, s4_f3, s4_f4; - uint8x16_t s01_f0, s23_f0; - uint64x2_t s01_f3, s23_f3; - uint32x2x2_t s01_f3_q, s23_f3_q, s01_f5_q, s23_f5_q; - // Accumulator variables. - uint16x8_t d0123, d4567, d89; - uint16x8_t d0123_a, d4567_a, d89_a; - int16x8_t e0123, e4567, e89; - // Second pass intermediates. - uint8x8_t b0, b1, b2, b3, b4, b5, b6, b7, b8; - uint16x8_t c0, c1, c2, c3; - int16x8_t d0, d1; - uint8x8_t e0, e1; - uint8x8_t filter, filter0, filter1, filter2, filter3, filter4, filter5; - - if (xoffset == 0) { // Second pass only. - yonly4x4(src_ptr, src_pixels_per_line, yoffset, dst_ptr, dst_pitch); - return; - } - - if (yoffset == 0) { // First pass only. - src_ptr -= 2; - } else { // Add context for the second pass. 2 extra lines on top. - src_ptr -= 2 + (src_pixels_per_line * 2); - } - - filter = vld1_u8(abs_filters[xoffset]); - filter0 = vdup_lane_u8(filter, 0); - filter1 = vdup_lane_u8(filter, 1); - filter2 = vdup_lane_u8(filter, 2); - filter3 = vdup_lane_u8(filter, 3); - filter4 = vdup_lane_u8(filter, 4); - filter5 = vdup_lane_u8(filter, 5); - - // 2 bytes of context, 4 bytes of src values, 3 bytes of context, 7 bytes of - // garbage. So much effort for that last single bit. - // The low values of each pair are for filter0. - s0 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - s1 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - s2 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - s3 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - - // Shift to extract values for filter[5] - // If src[] is 0, this puts: - // 3 4 5 6 7 8 9 10 in s0_f5 - // Can't use vshr.u64 because it crosses the double word boundary. - s0_f5 = vext_u8(vget_low_u8(s0), vget_high_u8(s0), 5); - s1_f5 = vext_u8(vget_low_u8(s1), vget_high_u8(s1), 5); - s2_f5 = vext_u8(vget_low_u8(s2), vget_high_u8(s2), 5); - s3_f5 = vext_u8(vget_low_u8(s3), vget_high_u8(s3), 5); - - s01_f0 = vcombine_u8(vget_low_u8(s0), vget_low_u8(s1)); - s23_f0 = vcombine_u8(vget_low_u8(s2), vget_low_u8(s3)); - - s01_f5_q = vzip_u32(vreinterpret_u32_u8(s0_f5), vreinterpret_u32_u8(s1_f5)); - s23_f5_q = vzip_u32(vreinterpret_u32_u8(s2_f5), vreinterpret_u32_u8(s3_f5)); - d0123 = vmull_u8(vreinterpret_u8_u32(s01_f5_q.val[0]), filter5); - d4567 = vmull_u8(vreinterpret_u8_u32(s23_f5_q.val[0]), filter5); - - // Keep original src data as 64 bits to simplify shifting and extracting. - s01 = vreinterpretq_u64_u8(s01_f0); - s23 = vreinterpretq_u64_u8(s23_f0); - - // 3 4 5 6 * filter0 - filter_add_accumulate(s01_f0, s23_f0, filter0, &d0123, &d4567); - - // Shift over one to use -1, 0, 1, 2 for filter1 - // -1 0 1 2 * filter1 - filter_sub_accumulate(vreinterpretq_u8_u64(vshrq_n_u64(s01, 8)), - vreinterpretq_u8_u64(vshrq_n_u64(s23, 8)), filter1, - &d0123, &d4567); - - // 2 3 4 5 * filter4 - filter_sub_accumulate(vreinterpretq_u8_u64(vshrq_n_u64(s01, 32)), - vreinterpretq_u8_u64(vshrq_n_u64(s23, 32)), filter4, - &d0123, &d4567); - - // 0 1 2 3 * filter2 - filter_add_accumulate(vreinterpretq_u8_u64(vshrq_n_u64(s01, 16)), - vreinterpretq_u8_u64(vshrq_n_u64(s23, 16)), filter2, - &d0123, &d4567); - - // 1 2 3 4 * filter3 - s01_f3 = vshrq_n_u64(s01, 24); - s23_f3 = vshrq_n_u64(s23, 24); - s01_f3_q = vzip_u32(vreinterpret_u32_u64(vget_low_u64(s01_f3)), - vreinterpret_u32_u64(vget_high_u64(s01_f3))); - s23_f3_q = vzip_u32(vreinterpret_u32_u64(vget_low_u64(s23_f3)), - vreinterpret_u32_u64(vget_high_u64(s23_f3))); - // Accumulate into different registers so it can use saturated addition. - d0123_a = vmull_u8(vreinterpret_u8_u32(s01_f3_q.val[0]), filter3); - d4567_a = vmull_u8(vreinterpret_u8_u32(s23_f3_q.val[0]), filter3); - - e0123 = - vqaddq_s16(vreinterpretq_s16_u16(d0123), vreinterpretq_s16_u16(d0123_a)); - e4567 = - vqaddq_s16(vreinterpretq_s16_u16(d4567), vreinterpretq_s16_u16(d4567_a)); - - // Shift and narrow. - b0 = vqrshrun_n_s16(e0123, 7); - b2 = vqrshrun_n_s16(e4567, 7); - - if (yoffset == 0) { // firstpass_filter4x4_only - store_unaligned_u8q(dst_ptr, dst_pitch, vcombine_u8(b0, b2)); - return; - } - - // Load additional context when doing both filters. - s0 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - s1 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - s2 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - s3 = vld1q_u8(src_ptr); - src_ptr += src_pixels_per_line; - s4 = vld1q_u8(src_ptr); - - s0_f5 = vext_u8(vget_low_u8(s0), vget_high_u8(s0), 5); - s1_f5 = vext_u8(vget_low_u8(s1), vget_high_u8(s1), 5); - s2_f5 = vext_u8(vget_low_u8(s2), vget_high_u8(s2), 5); - s3_f5 = vext_u8(vget_low_u8(s3), vget_high_u8(s3), 5); - s4_f5 = vext_u8(vget_low_u8(s4), vget_high_u8(s4), 5); - - // 3 4 5 6 * filter0 - s01_f0 = vcombine_u8(vget_low_u8(s0), vget_low_u8(s1)); - s23_f0 = vcombine_u8(vget_low_u8(s2), vget_low_u8(s3)); - - s01_f5_q = vzip_u32(vreinterpret_u32_u8(s0_f5), vreinterpret_u32_u8(s1_f5)); - s23_f5_q = vzip_u32(vreinterpret_u32_u8(s2_f5), vreinterpret_u32_u8(s3_f5)); - // But this time instead of 16 pixels to filter, there are 20. So an extra - // run with a doubleword register. - d0123 = vmull_u8(vreinterpret_u8_u32(s01_f5_q.val[0]), filter5); - d4567 = vmull_u8(vreinterpret_u8_u32(s23_f5_q.val[0]), filter5); - d89 = vmull_u8(s4_f5, filter5); - - // Save a copy as u64 for shifting. - s01 = vreinterpretq_u64_u8(s01_f0); - s23 = vreinterpretq_u64_u8(s23_f0); - - filter_add_accumulate(s01_f0, s23_f0, filter0, &d0123, &d4567); - d89 = vmlal_u8(d89, vget_low_u8(s4), filter0); - - filter_sub_accumulate(vreinterpretq_u8_u64(vshrq_n_u64(s01, 8)), - vreinterpretq_u8_u64(vshrq_n_u64(s23, 8)), filter1, - &d0123, &d4567); - s4_f1 = vext_u8(vget_low_u8(s4), vget_high_u8(s4), 1); - d89 = vmlsl_u8(d89, s4_f1, filter1); - - filter_sub_accumulate(vreinterpretq_u8_u64(vshrq_n_u64(s01, 32)), - vreinterpretq_u8_u64(vshrq_n_u64(s23, 32)), filter4, - &d0123, &d4567); - s4_f4 = vext_u8(vget_low_u8(s4), vget_high_u8(s4), 4); - d89 = vmlsl_u8(d89, s4_f4, filter4); - - filter_add_accumulate(vreinterpretq_u8_u64(vshrq_n_u64(s01, 16)), - vreinterpretq_u8_u64(vshrq_n_u64(s23, 16)), filter2, - &d0123, &d4567); - s4_f2 = vext_u8(vget_low_u8(s4), vget_high_u8(s4), 2); - d89 = vmlal_u8(d89, s4_f2, filter2); - - s01_f3 = vshrq_n_u64(s01, 24); - s23_f3 = vshrq_n_u64(s23, 24); - s01_f3_q = vzip_u32(vreinterpret_u32_u64(vget_low_u64(s01_f3)), - vreinterpret_u32_u64(vget_high_u64(s01_f3))); - s23_f3_q = vzip_u32(vreinterpret_u32_u64(vget_low_u64(s23_f3)), - vreinterpret_u32_u64(vget_high_u64(s23_f3))); - s4_f3 = vext_u8(vget_low_u8(s4), vget_high_u8(s4), 3); - d0123_a = vmull_u8(vreinterpret_u8_u32(s01_f3_q.val[0]), filter3); - d4567_a = vmull_u8(vreinterpret_u8_u32(s23_f3_q.val[0]), filter3); - d89_a = vmull_u8(s4_f3, filter3); - - e0123 = - vqaddq_s16(vreinterpretq_s16_u16(d0123), vreinterpretq_s16_u16(d0123_a)); - e4567 = - vqaddq_s16(vreinterpretq_s16_u16(d4567), vreinterpretq_s16_u16(d4567_a)); - e89 = vqaddq_s16(vreinterpretq_s16_u16(d89), vreinterpretq_s16_u16(d89_a)); - - b4 = vqrshrun_n_s16(e0123, 7); - b6 = vqrshrun_n_s16(e4567, 7); - b8 = vqrshrun_n_s16(e89, 7); - - // Second pass: 4x4 - filter = vld1_u8(abs_filters[yoffset]); - filter0 = vdup_lane_u8(filter, 0); - filter1 = vdup_lane_u8(filter, 1); - filter2 = vdup_lane_u8(filter, 2); - filter3 = vdup_lane_u8(filter, 3); - filter4 = vdup_lane_u8(filter, 4); - filter5 = vdup_lane_u8(filter, 5); - - b1 = vext_u8(b0, b2, 4); - b3 = vext_u8(b2, b4, 4); - b5 = vext_u8(b4, b6, 4); - b7 = vext_u8(b6, b8, 4); - - c0 = vmull_u8(b0, filter0); - c1 = vmull_u8(b2, filter0); - c2 = vmull_u8(b5, filter5); - c3 = vmull_u8(b7, filter5); - - c0 = vmlsl_u8(c0, b4, filter4); - c1 = vmlsl_u8(c1, b6, filter4); - c2 = vmlsl_u8(c2, b1, filter1); - c3 = vmlsl_u8(c3, b3, filter1); - - c0 = vmlal_u8(c0, b2, filter2); - c1 = vmlal_u8(c1, b4, filter2); - c2 = vmlal_u8(c2, b3, filter3); - c3 = vmlal_u8(c3, b5, filter3); - - d0 = vqaddq_s16(vreinterpretq_s16_u16(c2), vreinterpretq_s16_u16(c0)); - d1 = vqaddq_s16(vreinterpretq_s16_u16(c3), vreinterpretq_s16_u16(c1)); - - e0 = vqrshrun_n_s16(d0, 7); - e1 = vqrshrun_n_s16(d1, 7); - - store_unaligned_u8q(dst_ptr, dst_pitch, vcombine_u8(e0, e1)); -} - -void vp8_sixtap_predict8x4_neon(unsigned char *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, - unsigned char *dst_ptr, int dst_pitch) { - unsigned char *src; - uint8x8_t d0u8, d1u8, d2u8, d3u8, d4u8, d5u8, d6u8, d7u8, d8u8, d9u8; - uint8x8_t d22u8, d23u8, d24u8, d25u8, d26u8; - uint8x8_t d27u8, d28u8, d29u8, d30u8, d31u8; - int8x8_t dtmps8, d0s8, d1s8, d2s8, d3s8, d4s8, d5s8; - uint16x8_t q3u16, q4u16, q5u16, q6u16, q7u16; - uint16x8_t q8u16, q9u16, q10u16, q11u16, q12u16; - int16x8_t q3s16, q4s16, q5s16, q6s16, q7s16; - int16x8_t q8s16, q9s16, q10s16, q11s16, q12s16; - uint8x16_t q3u8, q4u8, q5u8, q6u8, q7u8; - - if (xoffset == 0) { // secondpass_filter8x4_only - // load second_pass filter - dtmps8 = vld1_s8(vp8_sub_pel_filters[yoffset]); - d0s8 = vdup_lane_s8(dtmps8, 0); - d1s8 = vdup_lane_s8(dtmps8, 1); - d2s8 = vdup_lane_s8(dtmps8, 2); - d3s8 = vdup_lane_s8(dtmps8, 3); - d4s8 = vdup_lane_s8(dtmps8, 4); - d5s8 = vdup_lane_s8(dtmps8, 5); - d0u8 = vreinterpret_u8_s8(vabs_s8(d0s8)); - d1u8 = vreinterpret_u8_s8(vabs_s8(d1s8)); - d2u8 = vreinterpret_u8_s8(vabs_s8(d2s8)); - d3u8 = vreinterpret_u8_s8(vabs_s8(d3s8)); - d4u8 = vreinterpret_u8_s8(vabs_s8(d4s8)); - d5u8 = vreinterpret_u8_s8(vabs_s8(d5s8)); - - // load src data - src = src_ptr - src_pixels_per_line * 2; - d22u8 = vld1_u8(src); - src += src_pixels_per_line; - d23u8 = vld1_u8(src); - src += src_pixels_per_line; - d24u8 = vld1_u8(src); - src += src_pixels_per_line; - d25u8 = vld1_u8(src); - src += src_pixels_per_line; - d26u8 = vld1_u8(src); - src += src_pixels_per_line; - d27u8 = vld1_u8(src); - src += src_pixels_per_line; - d28u8 = vld1_u8(src); - src += src_pixels_per_line; - d29u8 = vld1_u8(src); - src += src_pixels_per_line; - d30u8 = vld1_u8(src); - - q3u16 = vmull_u8(d22u8, d0u8); - q4u16 = vmull_u8(d23u8, d0u8); - q5u16 = vmull_u8(d24u8, d0u8); - q6u16 = vmull_u8(d25u8, d0u8); - - q3u16 = vmlsl_u8(q3u16, d23u8, d1u8); - q4u16 = vmlsl_u8(q4u16, d24u8, d1u8); - q5u16 = vmlsl_u8(q5u16, d25u8, d1u8); - q6u16 = vmlsl_u8(q6u16, d26u8, d1u8); - - q3u16 = vmlsl_u8(q3u16, d26u8, d4u8); - q4u16 = vmlsl_u8(q4u16, d27u8, d4u8); - q5u16 = vmlsl_u8(q5u16, d28u8, d4u8); - q6u16 = vmlsl_u8(q6u16, d29u8, d4u8); - - q3u16 = vmlal_u8(q3u16, d24u8, d2u8); - q4u16 = vmlal_u8(q4u16, d25u8, d2u8); - q5u16 = vmlal_u8(q5u16, d26u8, d2u8); - q6u16 = vmlal_u8(q6u16, d27u8, d2u8); - - q3u16 = vmlal_u8(q3u16, d27u8, d5u8); - q4u16 = vmlal_u8(q4u16, d28u8, d5u8); - q5u16 = vmlal_u8(q5u16, d29u8, d5u8); - q6u16 = vmlal_u8(q6u16, d30u8, d5u8); - - q7u16 = vmull_u8(d25u8, d3u8); - q8u16 = vmull_u8(d26u8, d3u8); - q9u16 = vmull_u8(d27u8, d3u8); - q10u16 = vmull_u8(d28u8, d3u8); - - q3s16 = vreinterpretq_s16_u16(q3u16); - q4s16 = vreinterpretq_s16_u16(q4u16); - q5s16 = vreinterpretq_s16_u16(q5u16); - q6s16 = vreinterpretq_s16_u16(q6u16); - q7s16 = vreinterpretq_s16_u16(q7u16); - q8s16 = vreinterpretq_s16_u16(q8u16); - q9s16 = vreinterpretq_s16_u16(q9u16); - q10s16 = vreinterpretq_s16_u16(q10u16); - - q7s16 = vqaddq_s16(q7s16, q3s16); - q8s16 = vqaddq_s16(q8s16, q4s16); - q9s16 = vqaddq_s16(q9s16, q5s16); - q10s16 = vqaddq_s16(q10s16, q6s16); - - d6u8 = vqrshrun_n_s16(q7s16, 7); - d7u8 = vqrshrun_n_s16(q8s16, 7); - d8u8 = vqrshrun_n_s16(q9s16, 7); - d9u8 = vqrshrun_n_s16(q10s16, 7); - - vst1_u8(dst_ptr, d6u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d7u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d8u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d9u8); - return; - } - - // load first_pass filter - dtmps8 = vld1_s8(vp8_sub_pel_filters[xoffset]); - d0s8 = vdup_lane_s8(dtmps8, 0); - d1s8 = vdup_lane_s8(dtmps8, 1); - d2s8 = vdup_lane_s8(dtmps8, 2); - d3s8 = vdup_lane_s8(dtmps8, 3); - d4s8 = vdup_lane_s8(dtmps8, 4); - d5s8 = vdup_lane_s8(dtmps8, 5); - d0u8 = vreinterpret_u8_s8(vabs_s8(d0s8)); - d1u8 = vreinterpret_u8_s8(vabs_s8(d1s8)); - d2u8 = vreinterpret_u8_s8(vabs_s8(d2s8)); - d3u8 = vreinterpret_u8_s8(vabs_s8(d3s8)); - d4u8 = vreinterpret_u8_s8(vabs_s8(d4s8)); - d5u8 = vreinterpret_u8_s8(vabs_s8(d5s8)); - - // First pass: output_height lines x output_width columns (9x4) - if (yoffset == 0) // firstpass_filter4x4_only - src = src_ptr - 2; - else - src = src_ptr - 2 - (src_pixels_per_line * 2); - q3u8 = vld1q_u8(src); - src += src_pixels_per_line; - q4u8 = vld1q_u8(src); - src += src_pixels_per_line; - q5u8 = vld1q_u8(src); - src += src_pixels_per_line; - q6u8 = vld1q_u8(src); - - q7u16 = vmull_u8(vget_low_u8(q3u8), d0u8); - q8u16 = vmull_u8(vget_low_u8(q4u8), d0u8); - q9u16 = vmull_u8(vget_low_u8(q5u8), d0u8); - q10u16 = vmull_u8(vget_low_u8(q6u8), d0u8); - - d28u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 1); - d29u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 1); - d30u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 1); - d31u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 1); - - q7u16 = vmlsl_u8(q7u16, d28u8, d1u8); - q8u16 = vmlsl_u8(q8u16, d29u8, d1u8); - q9u16 = vmlsl_u8(q9u16, d30u8, d1u8); - q10u16 = vmlsl_u8(q10u16, d31u8, d1u8); - - d28u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 4); - d29u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 4); - d30u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 4); - d31u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 4); - - q7u16 = vmlsl_u8(q7u16, d28u8, d4u8); - q8u16 = vmlsl_u8(q8u16, d29u8, d4u8); - q9u16 = vmlsl_u8(q9u16, d30u8, d4u8); - q10u16 = vmlsl_u8(q10u16, d31u8, d4u8); - - d28u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 2); - d29u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 2); - d30u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 2); - d31u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 2); - - q7u16 = vmlal_u8(q7u16, d28u8, d2u8); - q8u16 = vmlal_u8(q8u16, d29u8, d2u8); - q9u16 = vmlal_u8(q9u16, d30u8, d2u8); - q10u16 = vmlal_u8(q10u16, d31u8, d2u8); - - d28u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 5); - d29u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 5); - d30u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 5); - d31u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 5); - - q7u16 = vmlal_u8(q7u16, d28u8, d5u8); - q8u16 = vmlal_u8(q8u16, d29u8, d5u8); - q9u16 = vmlal_u8(q9u16, d30u8, d5u8); - q10u16 = vmlal_u8(q10u16, d31u8, d5u8); - - d28u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 3); - d29u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 3); - d30u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 3); - d31u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 3); - - q3u16 = vmull_u8(d28u8, d3u8); - q4u16 = vmull_u8(d29u8, d3u8); - q5u16 = vmull_u8(d30u8, d3u8); - q6u16 = vmull_u8(d31u8, d3u8); - - q3s16 = vreinterpretq_s16_u16(q3u16); - q4s16 = vreinterpretq_s16_u16(q4u16); - q5s16 = vreinterpretq_s16_u16(q5u16); - q6s16 = vreinterpretq_s16_u16(q6u16); - q7s16 = vreinterpretq_s16_u16(q7u16); - q8s16 = vreinterpretq_s16_u16(q8u16); - q9s16 = vreinterpretq_s16_u16(q9u16); - q10s16 = vreinterpretq_s16_u16(q10u16); - - q7s16 = vqaddq_s16(q7s16, q3s16); - q8s16 = vqaddq_s16(q8s16, q4s16); - q9s16 = vqaddq_s16(q9s16, q5s16); - q10s16 = vqaddq_s16(q10s16, q6s16); - - d22u8 = vqrshrun_n_s16(q7s16, 7); - d23u8 = vqrshrun_n_s16(q8s16, 7); - d24u8 = vqrshrun_n_s16(q9s16, 7); - d25u8 = vqrshrun_n_s16(q10s16, 7); - - if (yoffset == 0) { // firstpass_filter8x4_only - vst1_u8(dst_ptr, d22u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d23u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d24u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d25u8); - return; - } - - // First Pass on rest 5-line data - src += src_pixels_per_line; - q3u8 = vld1q_u8(src); - src += src_pixels_per_line; - q4u8 = vld1q_u8(src); - src += src_pixels_per_line; - q5u8 = vld1q_u8(src); - src += src_pixels_per_line; - q6u8 = vld1q_u8(src); - src += src_pixels_per_line; - q7u8 = vld1q_u8(src); - - q8u16 = vmull_u8(vget_low_u8(q3u8), d0u8); - q9u16 = vmull_u8(vget_low_u8(q4u8), d0u8); - q10u16 = vmull_u8(vget_low_u8(q5u8), d0u8); - q11u16 = vmull_u8(vget_low_u8(q6u8), d0u8); - q12u16 = vmull_u8(vget_low_u8(q7u8), d0u8); - - d27u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 1); - d28u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 1); - d29u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 1); - d30u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 1); - d31u8 = vext_u8(vget_low_u8(q7u8), vget_high_u8(q7u8), 1); - - q8u16 = vmlsl_u8(q8u16, d27u8, d1u8); - q9u16 = vmlsl_u8(q9u16, d28u8, d1u8); - q10u16 = vmlsl_u8(q10u16, d29u8, d1u8); - q11u16 = vmlsl_u8(q11u16, d30u8, d1u8); - q12u16 = vmlsl_u8(q12u16, d31u8, d1u8); - - d27u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 4); - d28u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 4); - d29u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 4); - d30u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 4); - d31u8 = vext_u8(vget_low_u8(q7u8), vget_high_u8(q7u8), 4); - - q8u16 = vmlsl_u8(q8u16, d27u8, d4u8); - q9u16 = vmlsl_u8(q9u16, d28u8, d4u8); - q10u16 = vmlsl_u8(q10u16, d29u8, d4u8); - q11u16 = vmlsl_u8(q11u16, d30u8, d4u8); - q12u16 = vmlsl_u8(q12u16, d31u8, d4u8); - - d27u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 2); - d28u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 2); - d29u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 2); - d30u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 2); - d31u8 = vext_u8(vget_low_u8(q7u8), vget_high_u8(q7u8), 2); - - q8u16 = vmlal_u8(q8u16, d27u8, d2u8); - q9u16 = vmlal_u8(q9u16, d28u8, d2u8); - q10u16 = vmlal_u8(q10u16, d29u8, d2u8); - q11u16 = vmlal_u8(q11u16, d30u8, d2u8); - q12u16 = vmlal_u8(q12u16, d31u8, d2u8); - - d27u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 5); - d28u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 5); - d29u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 5); - d30u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 5); - d31u8 = vext_u8(vget_low_u8(q7u8), vget_high_u8(q7u8), 5); - - q8u16 = vmlal_u8(q8u16, d27u8, d5u8); - q9u16 = vmlal_u8(q9u16, d28u8, d5u8); - q10u16 = vmlal_u8(q10u16, d29u8, d5u8); - q11u16 = vmlal_u8(q11u16, d30u8, d5u8); - q12u16 = vmlal_u8(q12u16, d31u8, d5u8); - - d27u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 3); - d28u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 3); - d29u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 3); - d30u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 3); - d31u8 = vext_u8(vget_low_u8(q7u8), vget_high_u8(q7u8), 3); - - q3u16 = vmull_u8(d27u8, d3u8); - q4u16 = vmull_u8(d28u8, d3u8); - q5u16 = vmull_u8(d29u8, d3u8); - q6u16 = vmull_u8(d30u8, d3u8); - q7u16 = vmull_u8(d31u8, d3u8); - - q3s16 = vreinterpretq_s16_u16(q3u16); - q4s16 = vreinterpretq_s16_u16(q4u16); - q5s16 = vreinterpretq_s16_u16(q5u16); - q6s16 = vreinterpretq_s16_u16(q6u16); - q7s16 = vreinterpretq_s16_u16(q7u16); - q8s16 = vreinterpretq_s16_u16(q8u16); - q9s16 = vreinterpretq_s16_u16(q9u16); - q10s16 = vreinterpretq_s16_u16(q10u16); - q11s16 = vreinterpretq_s16_u16(q11u16); - q12s16 = vreinterpretq_s16_u16(q12u16); - - q8s16 = vqaddq_s16(q8s16, q3s16); - q9s16 = vqaddq_s16(q9s16, q4s16); - q10s16 = vqaddq_s16(q10s16, q5s16); - q11s16 = vqaddq_s16(q11s16, q6s16); - q12s16 = vqaddq_s16(q12s16, q7s16); - - d26u8 = vqrshrun_n_s16(q8s16, 7); - d27u8 = vqrshrun_n_s16(q9s16, 7); - d28u8 = vqrshrun_n_s16(q10s16, 7); - d29u8 = vqrshrun_n_s16(q11s16, 7); - d30u8 = vqrshrun_n_s16(q12s16, 7); - - // Second pass: 8x4 - dtmps8 = vld1_s8(vp8_sub_pel_filters[yoffset]); - d0s8 = vdup_lane_s8(dtmps8, 0); - d1s8 = vdup_lane_s8(dtmps8, 1); - d2s8 = vdup_lane_s8(dtmps8, 2); - d3s8 = vdup_lane_s8(dtmps8, 3); - d4s8 = vdup_lane_s8(dtmps8, 4); - d5s8 = vdup_lane_s8(dtmps8, 5); - d0u8 = vreinterpret_u8_s8(vabs_s8(d0s8)); - d1u8 = vreinterpret_u8_s8(vabs_s8(d1s8)); - d2u8 = vreinterpret_u8_s8(vabs_s8(d2s8)); - d3u8 = vreinterpret_u8_s8(vabs_s8(d3s8)); - d4u8 = vreinterpret_u8_s8(vabs_s8(d4s8)); - d5u8 = vreinterpret_u8_s8(vabs_s8(d5s8)); - - q3u16 = vmull_u8(d22u8, d0u8); - q4u16 = vmull_u8(d23u8, d0u8); - q5u16 = vmull_u8(d24u8, d0u8); - q6u16 = vmull_u8(d25u8, d0u8); - - q3u16 = vmlsl_u8(q3u16, d23u8, d1u8); - q4u16 = vmlsl_u8(q4u16, d24u8, d1u8); - q5u16 = vmlsl_u8(q5u16, d25u8, d1u8); - q6u16 = vmlsl_u8(q6u16, d26u8, d1u8); - - q3u16 = vmlsl_u8(q3u16, d26u8, d4u8); - q4u16 = vmlsl_u8(q4u16, d27u8, d4u8); - q5u16 = vmlsl_u8(q5u16, d28u8, d4u8); - q6u16 = vmlsl_u8(q6u16, d29u8, d4u8); - - q3u16 = vmlal_u8(q3u16, d24u8, d2u8); - q4u16 = vmlal_u8(q4u16, d25u8, d2u8); - q5u16 = vmlal_u8(q5u16, d26u8, d2u8); - q6u16 = vmlal_u8(q6u16, d27u8, d2u8); - - q3u16 = vmlal_u8(q3u16, d27u8, d5u8); - q4u16 = vmlal_u8(q4u16, d28u8, d5u8); - q5u16 = vmlal_u8(q5u16, d29u8, d5u8); - q6u16 = vmlal_u8(q6u16, d30u8, d5u8); - - q7u16 = vmull_u8(d25u8, d3u8); - q8u16 = vmull_u8(d26u8, d3u8); - q9u16 = vmull_u8(d27u8, d3u8); - q10u16 = vmull_u8(d28u8, d3u8); - - q3s16 = vreinterpretq_s16_u16(q3u16); - q4s16 = vreinterpretq_s16_u16(q4u16); - q5s16 = vreinterpretq_s16_u16(q5u16); - q6s16 = vreinterpretq_s16_u16(q6u16); - q7s16 = vreinterpretq_s16_u16(q7u16); - q8s16 = vreinterpretq_s16_u16(q8u16); - q9s16 = vreinterpretq_s16_u16(q9u16); - q10s16 = vreinterpretq_s16_u16(q10u16); - - q7s16 = vqaddq_s16(q7s16, q3s16); - q8s16 = vqaddq_s16(q8s16, q4s16); - q9s16 = vqaddq_s16(q9s16, q5s16); - q10s16 = vqaddq_s16(q10s16, q6s16); - - d6u8 = vqrshrun_n_s16(q7s16, 7); - d7u8 = vqrshrun_n_s16(q8s16, 7); - d8u8 = vqrshrun_n_s16(q9s16, 7); - d9u8 = vqrshrun_n_s16(q10s16, 7); - - vst1_u8(dst_ptr, d6u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d7u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d8u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d9u8); -} - -void vp8_sixtap_predict8x8_neon(unsigned char *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, - unsigned char *dst_ptr, int dst_pitch) { - unsigned char *src, *tmpp; - unsigned char tmp[64]; - int i; - uint8x8_t d0u8, d1u8, d2u8, d3u8, d4u8, d5u8, d6u8, d7u8, d8u8, d9u8; - uint8x8_t d18u8, d19u8, d20u8, d21u8, d22u8, d23u8, d24u8, d25u8; - uint8x8_t d26u8, d27u8, d28u8, d29u8, d30u8, d31u8; - int8x8_t dtmps8, d0s8, d1s8, d2s8, d3s8, d4s8, d5s8; - uint16x8_t q3u16, q4u16, q5u16, q6u16, q7u16; - uint16x8_t q8u16, q9u16, q10u16, q11u16, q12u16; - int16x8_t q3s16, q4s16, q5s16, q6s16, q7s16; - int16x8_t q8s16, q9s16, q10s16, q11s16, q12s16; - uint8x16_t q3u8, q4u8, q5u8, q6u8, q7u8, q9u8, q10u8, q11u8, q12u8; - - if (xoffset == 0) { // secondpass_filter8x8_only - // load second_pass filter - dtmps8 = vld1_s8(vp8_sub_pel_filters[yoffset]); - d0s8 = vdup_lane_s8(dtmps8, 0); - d1s8 = vdup_lane_s8(dtmps8, 1); - d2s8 = vdup_lane_s8(dtmps8, 2); - d3s8 = vdup_lane_s8(dtmps8, 3); - d4s8 = vdup_lane_s8(dtmps8, 4); - d5s8 = vdup_lane_s8(dtmps8, 5); - d0u8 = vreinterpret_u8_s8(vabs_s8(d0s8)); - d1u8 = vreinterpret_u8_s8(vabs_s8(d1s8)); - d2u8 = vreinterpret_u8_s8(vabs_s8(d2s8)); - d3u8 = vreinterpret_u8_s8(vabs_s8(d3s8)); - d4u8 = vreinterpret_u8_s8(vabs_s8(d4s8)); - d5u8 = vreinterpret_u8_s8(vabs_s8(d5s8)); - - // load src data - src = src_ptr - src_pixels_per_line * 2; - d18u8 = vld1_u8(src); - src += src_pixels_per_line; - d19u8 = vld1_u8(src); - src += src_pixels_per_line; - d20u8 = vld1_u8(src); - src += src_pixels_per_line; - d21u8 = vld1_u8(src); - src += src_pixels_per_line; - d22u8 = vld1_u8(src); - src += src_pixels_per_line; - d23u8 = vld1_u8(src); - src += src_pixels_per_line; - d24u8 = vld1_u8(src); - src += src_pixels_per_line; - d25u8 = vld1_u8(src); - src += src_pixels_per_line; - d26u8 = vld1_u8(src); - src += src_pixels_per_line; - d27u8 = vld1_u8(src); - src += src_pixels_per_line; - d28u8 = vld1_u8(src); - src += src_pixels_per_line; - d29u8 = vld1_u8(src); - src += src_pixels_per_line; - d30u8 = vld1_u8(src); - - for (i = 2; i > 0; i--) { - q3u16 = vmull_u8(d18u8, d0u8); - q4u16 = vmull_u8(d19u8, d0u8); - q5u16 = vmull_u8(d20u8, d0u8); - q6u16 = vmull_u8(d21u8, d0u8); - - q3u16 = vmlsl_u8(q3u16, d19u8, d1u8); - q4u16 = vmlsl_u8(q4u16, d20u8, d1u8); - q5u16 = vmlsl_u8(q5u16, d21u8, d1u8); - q6u16 = vmlsl_u8(q6u16, d22u8, d1u8); - - q3u16 = vmlsl_u8(q3u16, d22u8, d4u8); - q4u16 = vmlsl_u8(q4u16, d23u8, d4u8); - q5u16 = vmlsl_u8(q5u16, d24u8, d4u8); - q6u16 = vmlsl_u8(q6u16, d25u8, d4u8); - - q3u16 = vmlal_u8(q3u16, d20u8, d2u8); - q4u16 = vmlal_u8(q4u16, d21u8, d2u8); - q5u16 = vmlal_u8(q5u16, d22u8, d2u8); - q6u16 = vmlal_u8(q6u16, d23u8, d2u8); - - q3u16 = vmlal_u8(q3u16, d23u8, d5u8); - q4u16 = vmlal_u8(q4u16, d24u8, d5u8); - q5u16 = vmlal_u8(q5u16, d25u8, d5u8); - q6u16 = vmlal_u8(q6u16, d26u8, d5u8); - - q7u16 = vmull_u8(d21u8, d3u8); - q8u16 = vmull_u8(d22u8, d3u8); - q9u16 = vmull_u8(d23u8, d3u8); - q10u16 = vmull_u8(d24u8, d3u8); - - q3s16 = vreinterpretq_s16_u16(q3u16); - q4s16 = vreinterpretq_s16_u16(q4u16); - q5s16 = vreinterpretq_s16_u16(q5u16); - q6s16 = vreinterpretq_s16_u16(q6u16); - q7s16 = vreinterpretq_s16_u16(q7u16); - q8s16 = vreinterpretq_s16_u16(q8u16); - q9s16 = vreinterpretq_s16_u16(q9u16); - q10s16 = vreinterpretq_s16_u16(q10u16); - - q7s16 = vqaddq_s16(q7s16, q3s16); - q8s16 = vqaddq_s16(q8s16, q4s16); - q9s16 = vqaddq_s16(q9s16, q5s16); - q10s16 = vqaddq_s16(q10s16, q6s16); - - d6u8 = vqrshrun_n_s16(q7s16, 7); - d7u8 = vqrshrun_n_s16(q8s16, 7); - d8u8 = vqrshrun_n_s16(q9s16, 7); - d9u8 = vqrshrun_n_s16(q10s16, 7); - - d18u8 = d22u8; - d19u8 = d23u8; - d20u8 = d24u8; - d21u8 = d25u8; - d22u8 = d26u8; - d23u8 = d27u8; - d24u8 = d28u8; - d25u8 = d29u8; - d26u8 = d30u8; - - vst1_u8(dst_ptr, d6u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d7u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d8u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d9u8); - dst_ptr += dst_pitch; - } - return; - } - - // load first_pass filter - dtmps8 = vld1_s8(vp8_sub_pel_filters[xoffset]); - d0s8 = vdup_lane_s8(dtmps8, 0); - d1s8 = vdup_lane_s8(dtmps8, 1); - d2s8 = vdup_lane_s8(dtmps8, 2); - d3s8 = vdup_lane_s8(dtmps8, 3); - d4s8 = vdup_lane_s8(dtmps8, 4); - d5s8 = vdup_lane_s8(dtmps8, 5); - d0u8 = vreinterpret_u8_s8(vabs_s8(d0s8)); - d1u8 = vreinterpret_u8_s8(vabs_s8(d1s8)); - d2u8 = vreinterpret_u8_s8(vabs_s8(d2s8)); - d3u8 = vreinterpret_u8_s8(vabs_s8(d3s8)); - d4u8 = vreinterpret_u8_s8(vabs_s8(d4s8)); - d5u8 = vreinterpret_u8_s8(vabs_s8(d5s8)); - - // First pass: output_height lines x output_width columns (9x4) - if (yoffset == 0) // firstpass_filter4x4_only - src = src_ptr - 2; - else - src = src_ptr - 2 - (src_pixels_per_line * 2); - - tmpp = tmp; - for (i = 2; i > 0; i--) { - q3u8 = vld1q_u8(src); - src += src_pixels_per_line; - q4u8 = vld1q_u8(src); - src += src_pixels_per_line; - q5u8 = vld1q_u8(src); - src += src_pixels_per_line; - q6u8 = vld1q_u8(src); - src += src_pixels_per_line; - - __builtin_prefetch(src); - __builtin_prefetch(src + src_pixels_per_line); - __builtin_prefetch(src + src_pixels_per_line * 2); - - q7u16 = vmull_u8(vget_low_u8(q3u8), d0u8); - q8u16 = vmull_u8(vget_low_u8(q4u8), d0u8); - q9u16 = vmull_u8(vget_low_u8(q5u8), d0u8); - q10u16 = vmull_u8(vget_low_u8(q6u8), d0u8); - - d28u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 1); - d29u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 1); - d30u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 1); - d31u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 1); - - q7u16 = vmlsl_u8(q7u16, d28u8, d1u8); - q8u16 = vmlsl_u8(q8u16, d29u8, d1u8); - q9u16 = vmlsl_u8(q9u16, d30u8, d1u8); - q10u16 = vmlsl_u8(q10u16, d31u8, d1u8); - - d28u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 4); - d29u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 4); - d30u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 4); - d31u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 4); - - q7u16 = vmlsl_u8(q7u16, d28u8, d4u8); - q8u16 = vmlsl_u8(q8u16, d29u8, d4u8); - q9u16 = vmlsl_u8(q9u16, d30u8, d4u8); - q10u16 = vmlsl_u8(q10u16, d31u8, d4u8); - - d28u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 2); - d29u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 2); - d30u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 2); - d31u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 2); - - q7u16 = vmlal_u8(q7u16, d28u8, d2u8); - q8u16 = vmlal_u8(q8u16, d29u8, d2u8); - q9u16 = vmlal_u8(q9u16, d30u8, d2u8); - q10u16 = vmlal_u8(q10u16, d31u8, d2u8); - - d28u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 5); - d29u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 5); - d30u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 5); - d31u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 5); - - q7u16 = vmlal_u8(q7u16, d28u8, d5u8); - q8u16 = vmlal_u8(q8u16, d29u8, d5u8); - q9u16 = vmlal_u8(q9u16, d30u8, d5u8); - q10u16 = vmlal_u8(q10u16, d31u8, d5u8); - - d28u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 3); - d29u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 3); - d30u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 3); - d31u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 3); - - q3u16 = vmull_u8(d28u8, d3u8); - q4u16 = vmull_u8(d29u8, d3u8); - q5u16 = vmull_u8(d30u8, d3u8); - q6u16 = vmull_u8(d31u8, d3u8); - - q3s16 = vreinterpretq_s16_u16(q3u16); - q4s16 = vreinterpretq_s16_u16(q4u16); - q5s16 = vreinterpretq_s16_u16(q5u16); - q6s16 = vreinterpretq_s16_u16(q6u16); - q7s16 = vreinterpretq_s16_u16(q7u16); - q8s16 = vreinterpretq_s16_u16(q8u16); - q9s16 = vreinterpretq_s16_u16(q9u16); - q10s16 = vreinterpretq_s16_u16(q10u16); - - q7s16 = vqaddq_s16(q7s16, q3s16); - q8s16 = vqaddq_s16(q8s16, q4s16); - q9s16 = vqaddq_s16(q9s16, q5s16); - q10s16 = vqaddq_s16(q10s16, q6s16); - - d22u8 = vqrshrun_n_s16(q7s16, 7); - d23u8 = vqrshrun_n_s16(q8s16, 7); - d24u8 = vqrshrun_n_s16(q9s16, 7); - d25u8 = vqrshrun_n_s16(q10s16, 7); - - if (yoffset == 0) { // firstpass_filter8x4_only - vst1_u8(dst_ptr, d22u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d23u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d24u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d25u8); - dst_ptr += dst_pitch; - } else { - vst1_u8(tmpp, d22u8); - tmpp += 8; - vst1_u8(tmpp, d23u8); - tmpp += 8; - vst1_u8(tmpp, d24u8); - tmpp += 8; - vst1_u8(tmpp, d25u8); - tmpp += 8; - } - } - if (yoffset == 0) return; - - // First Pass on rest 5-line data - q3u8 = vld1q_u8(src); - src += src_pixels_per_line; - q4u8 = vld1q_u8(src); - src += src_pixels_per_line; - q5u8 = vld1q_u8(src); - src += src_pixels_per_line; - q6u8 = vld1q_u8(src); - src += src_pixels_per_line; - q7u8 = vld1q_u8(src); - - q8u16 = vmull_u8(vget_low_u8(q3u8), d0u8); - q9u16 = vmull_u8(vget_low_u8(q4u8), d0u8); - q10u16 = vmull_u8(vget_low_u8(q5u8), d0u8); - q11u16 = vmull_u8(vget_low_u8(q6u8), d0u8); - q12u16 = vmull_u8(vget_low_u8(q7u8), d0u8); - - d27u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 1); - d28u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 1); - d29u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 1); - d30u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 1); - d31u8 = vext_u8(vget_low_u8(q7u8), vget_high_u8(q7u8), 1); - - q8u16 = vmlsl_u8(q8u16, d27u8, d1u8); - q9u16 = vmlsl_u8(q9u16, d28u8, d1u8); - q10u16 = vmlsl_u8(q10u16, d29u8, d1u8); - q11u16 = vmlsl_u8(q11u16, d30u8, d1u8); - q12u16 = vmlsl_u8(q12u16, d31u8, d1u8); - - d27u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 4); - d28u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 4); - d29u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 4); - d30u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 4); - d31u8 = vext_u8(vget_low_u8(q7u8), vget_high_u8(q7u8), 4); - - q8u16 = vmlsl_u8(q8u16, d27u8, d4u8); - q9u16 = vmlsl_u8(q9u16, d28u8, d4u8); - q10u16 = vmlsl_u8(q10u16, d29u8, d4u8); - q11u16 = vmlsl_u8(q11u16, d30u8, d4u8); - q12u16 = vmlsl_u8(q12u16, d31u8, d4u8); - - d27u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 2); - d28u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 2); - d29u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 2); - d30u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 2); - d31u8 = vext_u8(vget_low_u8(q7u8), vget_high_u8(q7u8), 2); - - q8u16 = vmlal_u8(q8u16, d27u8, d2u8); - q9u16 = vmlal_u8(q9u16, d28u8, d2u8); - q10u16 = vmlal_u8(q10u16, d29u8, d2u8); - q11u16 = vmlal_u8(q11u16, d30u8, d2u8); - q12u16 = vmlal_u8(q12u16, d31u8, d2u8); - - d27u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 5); - d28u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 5); - d29u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 5); - d30u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 5); - d31u8 = vext_u8(vget_low_u8(q7u8), vget_high_u8(q7u8), 5); - - q8u16 = vmlal_u8(q8u16, d27u8, d5u8); - q9u16 = vmlal_u8(q9u16, d28u8, d5u8); - q10u16 = vmlal_u8(q10u16, d29u8, d5u8); - q11u16 = vmlal_u8(q11u16, d30u8, d5u8); - q12u16 = vmlal_u8(q12u16, d31u8, d5u8); - - d27u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 3); - d28u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 3); - d29u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 3); - d30u8 = vext_u8(vget_low_u8(q6u8), vget_high_u8(q6u8), 3); - d31u8 = vext_u8(vget_low_u8(q7u8), vget_high_u8(q7u8), 3); - - q3u16 = vmull_u8(d27u8, d3u8); - q4u16 = vmull_u8(d28u8, d3u8); - q5u16 = vmull_u8(d29u8, d3u8); - q6u16 = vmull_u8(d30u8, d3u8); - q7u16 = vmull_u8(d31u8, d3u8); - - q3s16 = vreinterpretq_s16_u16(q3u16); - q4s16 = vreinterpretq_s16_u16(q4u16); - q5s16 = vreinterpretq_s16_u16(q5u16); - q6s16 = vreinterpretq_s16_u16(q6u16); - q7s16 = vreinterpretq_s16_u16(q7u16); - q8s16 = vreinterpretq_s16_u16(q8u16); - q9s16 = vreinterpretq_s16_u16(q9u16); - q10s16 = vreinterpretq_s16_u16(q10u16); - q11s16 = vreinterpretq_s16_u16(q11u16); - q12s16 = vreinterpretq_s16_u16(q12u16); - - q8s16 = vqaddq_s16(q8s16, q3s16); - q9s16 = vqaddq_s16(q9s16, q4s16); - q10s16 = vqaddq_s16(q10s16, q5s16); - q11s16 = vqaddq_s16(q11s16, q6s16); - q12s16 = vqaddq_s16(q12s16, q7s16); - - d26u8 = vqrshrun_n_s16(q8s16, 7); - d27u8 = vqrshrun_n_s16(q9s16, 7); - d28u8 = vqrshrun_n_s16(q10s16, 7); - d29u8 = vqrshrun_n_s16(q11s16, 7); - d30u8 = vqrshrun_n_s16(q12s16, 7); - - // Second pass: 8x8 - dtmps8 = vld1_s8(vp8_sub_pel_filters[yoffset]); - d0s8 = vdup_lane_s8(dtmps8, 0); - d1s8 = vdup_lane_s8(dtmps8, 1); - d2s8 = vdup_lane_s8(dtmps8, 2); - d3s8 = vdup_lane_s8(dtmps8, 3); - d4s8 = vdup_lane_s8(dtmps8, 4); - d5s8 = vdup_lane_s8(dtmps8, 5); - d0u8 = vreinterpret_u8_s8(vabs_s8(d0s8)); - d1u8 = vreinterpret_u8_s8(vabs_s8(d1s8)); - d2u8 = vreinterpret_u8_s8(vabs_s8(d2s8)); - d3u8 = vreinterpret_u8_s8(vabs_s8(d3s8)); - d4u8 = vreinterpret_u8_s8(vabs_s8(d4s8)); - d5u8 = vreinterpret_u8_s8(vabs_s8(d5s8)); - - tmpp = tmp; - q9u8 = vld1q_u8(tmpp); - tmpp += 16; - q10u8 = vld1q_u8(tmpp); - tmpp += 16; - q11u8 = vld1q_u8(tmpp); - tmpp += 16; - q12u8 = vld1q_u8(tmpp); - - d18u8 = vget_low_u8(q9u8); - d19u8 = vget_high_u8(q9u8); - d20u8 = vget_low_u8(q10u8); - d21u8 = vget_high_u8(q10u8); - d22u8 = vget_low_u8(q11u8); - d23u8 = vget_high_u8(q11u8); - d24u8 = vget_low_u8(q12u8); - d25u8 = vget_high_u8(q12u8); - - for (i = 2; i > 0; i--) { - q3u16 = vmull_u8(d18u8, d0u8); - q4u16 = vmull_u8(d19u8, d0u8); - q5u16 = vmull_u8(d20u8, d0u8); - q6u16 = vmull_u8(d21u8, d0u8); - - q3u16 = vmlsl_u8(q3u16, d19u8, d1u8); - q4u16 = vmlsl_u8(q4u16, d20u8, d1u8); - q5u16 = vmlsl_u8(q5u16, d21u8, d1u8); - q6u16 = vmlsl_u8(q6u16, d22u8, d1u8); - - q3u16 = vmlsl_u8(q3u16, d22u8, d4u8); - q4u16 = vmlsl_u8(q4u16, d23u8, d4u8); - q5u16 = vmlsl_u8(q5u16, d24u8, d4u8); - q6u16 = vmlsl_u8(q6u16, d25u8, d4u8); - - q3u16 = vmlal_u8(q3u16, d20u8, d2u8); - q4u16 = vmlal_u8(q4u16, d21u8, d2u8); - q5u16 = vmlal_u8(q5u16, d22u8, d2u8); - q6u16 = vmlal_u8(q6u16, d23u8, d2u8); - - q3u16 = vmlal_u8(q3u16, d23u8, d5u8); - q4u16 = vmlal_u8(q4u16, d24u8, d5u8); - q5u16 = vmlal_u8(q5u16, d25u8, d5u8); - q6u16 = vmlal_u8(q6u16, d26u8, d5u8); - - q7u16 = vmull_u8(d21u8, d3u8); - q8u16 = vmull_u8(d22u8, d3u8); - q9u16 = vmull_u8(d23u8, d3u8); - q10u16 = vmull_u8(d24u8, d3u8); - - q3s16 = vreinterpretq_s16_u16(q3u16); - q4s16 = vreinterpretq_s16_u16(q4u16); - q5s16 = vreinterpretq_s16_u16(q5u16); - q6s16 = vreinterpretq_s16_u16(q6u16); - q7s16 = vreinterpretq_s16_u16(q7u16); - q8s16 = vreinterpretq_s16_u16(q8u16); - q9s16 = vreinterpretq_s16_u16(q9u16); - q10s16 = vreinterpretq_s16_u16(q10u16); - - q7s16 = vqaddq_s16(q7s16, q3s16); - q8s16 = vqaddq_s16(q8s16, q4s16); - q9s16 = vqaddq_s16(q9s16, q5s16); - q10s16 = vqaddq_s16(q10s16, q6s16); - - d6u8 = vqrshrun_n_s16(q7s16, 7); - d7u8 = vqrshrun_n_s16(q8s16, 7); - d8u8 = vqrshrun_n_s16(q9s16, 7); - d9u8 = vqrshrun_n_s16(q10s16, 7); - - d18u8 = d22u8; - d19u8 = d23u8; - d20u8 = d24u8; - d21u8 = d25u8; - d22u8 = d26u8; - d23u8 = d27u8; - d24u8 = d28u8; - d25u8 = d29u8; - d26u8 = d30u8; - - vst1_u8(dst_ptr, d6u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d7u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d8u8); - dst_ptr += dst_pitch; - vst1_u8(dst_ptr, d9u8); - dst_ptr += dst_pitch; - } -} - -void vp8_sixtap_predict16x16_neon(unsigned char *src_ptr, - int src_pixels_per_line, int xoffset, - int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - unsigned char *src, *src_tmp, *dst, *tmpp; - unsigned char tmp[336]; - int i, j; - uint8x8_t d0u8, d1u8, d2u8, d3u8, d4u8, d5u8, d6u8, d7u8, d8u8, d9u8; - uint8x8_t d10u8, d11u8, d12u8, d13u8, d14u8, d15u8, d18u8, d19u8; - uint8x8_t d20u8, d21u8, d22u8, d23u8, d24u8, d25u8, d26u8, d27u8; - uint8x8_t d28u8, d29u8, d30u8, d31u8; - int8x8_t dtmps8, d0s8, d1s8, d2s8, d3s8, d4s8, d5s8; - uint8x16_t q3u8, q4u8; - uint16x8_t q3u16, q4u16, q5u16, q6u16, q7u16, q8u16, q9u16, q10u16; - uint16x8_t q11u16, q12u16, q13u16, q15u16; - int16x8_t q3s16, q4s16, q5s16, q6s16, q7s16, q8s16, q9s16, q10s16; - int16x8_t q11s16, q12s16, q13s16, q15s16; - - if (xoffset == 0) { // secondpass_filter8x8_only - // load second_pass filter - dtmps8 = vld1_s8(vp8_sub_pel_filters[yoffset]); - d0s8 = vdup_lane_s8(dtmps8, 0); - d1s8 = vdup_lane_s8(dtmps8, 1); - d2s8 = vdup_lane_s8(dtmps8, 2); - d3s8 = vdup_lane_s8(dtmps8, 3); - d4s8 = vdup_lane_s8(dtmps8, 4); - d5s8 = vdup_lane_s8(dtmps8, 5); - d0u8 = vreinterpret_u8_s8(vabs_s8(d0s8)); - d1u8 = vreinterpret_u8_s8(vabs_s8(d1s8)); - d2u8 = vreinterpret_u8_s8(vabs_s8(d2s8)); - d3u8 = vreinterpret_u8_s8(vabs_s8(d3s8)); - d4u8 = vreinterpret_u8_s8(vabs_s8(d4s8)); - d5u8 = vreinterpret_u8_s8(vabs_s8(d5s8)); - - // load src data - src_tmp = src_ptr - src_pixels_per_line * 2; - for (i = 0; i < 2; ++i) { - src = src_tmp + i * 8; - dst = dst_ptr + i * 8; - d18u8 = vld1_u8(src); - src += src_pixels_per_line; - d19u8 = vld1_u8(src); - src += src_pixels_per_line; - d20u8 = vld1_u8(src); - src += src_pixels_per_line; - d21u8 = vld1_u8(src); - src += src_pixels_per_line; - d22u8 = vld1_u8(src); - src += src_pixels_per_line; - for (j = 0; j < 4; ++j) { - d23u8 = vld1_u8(src); - src += src_pixels_per_line; - d24u8 = vld1_u8(src); - src += src_pixels_per_line; - d25u8 = vld1_u8(src); - src += src_pixels_per_line; - d26u8 = vld1_u8(src); - src += src_pixels_per_line; - - q3u16 = vmull_u8(d18u8, d0u8); - q4u16 = vmull_u8(d19u8, d0u8); - q5u16 = vmull_u8(d20u8, d0u8); - q6u16 = vmull_u8(d21u8, d0u8); - - q3u16 = vmlsl_u8(q3u16, d19u8, d1u8); - q4u16 = vmlsl_u8(q4u16, d20u8, d1u8); - q5u16 = vmlsl_u8(q5u16, d21u8, d1u8); - q6u16 = vmlsl_u8(q6u16, d22u8, d1u8); - - q3u16 = vmlsl_u8(q3u16, d22u8, d4u8); - q4u16 = vmlsl_u8(q4u16, d23u8, d4u8); - q5u16 = vmlsl_u8(q5u16, d24u8, d4u8); - q6u16 = vmlsl_u8(q6u16, d25u8, d4u8); - - q3u16 = vmlal_u8(q3u16, d20u8, d2u8); - q4u16 = vmlal_u8(q4u16, d21u8, d2u8); - q5u16 = vmlal_u8(q5u16, d22u8, d2u8); - q6u16 = vmlal_u8(q6u16, d23u8, d2u8); - - q3u16 = vmlal_u8(q3u16, d23u8, d5u8); - q4u16 = vmlal_u8(q4u16, d24u8, d5u8); - q5u16 = vmlal_u8(q5u16, d25u8, d5u8); - q6u16 = vmlal_u8(q6u16, d26u8, d5u8); - - q7u16 = vmull_u8(d21u8, d3u8); - q8u16 = vmull_u8(d22u8, d3u8); - q9u16 = vmull_u8(d23u8, d3u8); - q10u16 = vmull_u8(d24u8, d3u8); - - q3s16 = vreinterpretq_s16_u16(q3u16); - q4s16 = vreinterpretq_s16_u16(q4u16); - q5s16 = vreinterpretq_s16_u16(q5u16); - q6s16 = vreinterpretq_s16_u16(q6u16); - q7s16 = vreinterpretq_s16_u16(q7u16); - q8s16 = vreinterpretq_s16_u16(q8u16); - q9s16 = vreinterpretq_s16_u16(q9u16); - q10s16 = vreinterpretq_s16_u16(q10u16); - - q7s16 = vqaddq_s16(q7s16, q3s16); - q8s16 = vqaddq_s16(q8s16, q4s16); - q9s16 = vqaddq_s16(q9s16, q5s16); - q10s16 = vqaddq_s16(q10s16, q6s16); - - d6u8 = vqrshrun_n_s16(q7s16, 7); - d7u8 = vqrshrun_n_s16(q8s16, 7); - d8u8 = vqrshrun_n_s16(q9s16, 7); - d9u8 = vqrshrun_n_s16(q10s16, 7); - - d18u8 = d22u8; - d19u8 = d23u8; - d20u8 = d24u8; - d21u8 = d25u8; - d22u8 = d26u8; - - vst1_u8(dst, d6u8); - dst += dst_pitch; - vst1_u8(dst, d7u8); - dst += dst_pitch; - vst1_u8(dst, d8u8); - dst += dst_pitch; - vst1_u8(dst, d9u8); - dst += dst_pitch; - } - } - return; - } - - // load first_pass filter - dtmps8 = vld1_s8(vp8_sub_pel_filters[xoffset]); - d0s8 = vdup_lane_s8(dtmps8, 0); - d1s8 = vdup_lane_s8(dtmps8, 1); - d2s8 = vdup_lane_s8(dtmps8, 2); - d3s8 = vdup_lane_s8(dtmps8, 3); - d4s8 = vdup_lane_s8(dtmps8, 4); - d5s8 = vdup_lane_s8(dtmps8, 5); - d0u8 = vreinterpret_u8_s8(vabs_s8(d0s8)); - d1u8 = vreinterpret_u8_s8(vabs_s8(d1s8)); - d2u8 = vreinterpret_u8_s8(vabs_s8(d2s8)); - d3u8 = vreinterpret_u8_s8(vabs_s8(d3s8)); - d4u8 = vreinterpret_u8_s8(vabs_s8(d4s8)); - d5u8 = vreinterpret_u8_s8(vabs_s8(d5s8)); - - // First pass: output_height lines x output_width columns (9x4) - if (yoffset == 0) { // firstpass_filter4x4_only - src = src_ptr - 2; - dst = dst_ptr; - for (i = 0; i < 8; ++i) { - d6u8 = vld1_u8(src); - d7u8 = vld1_u8(src + 8); - d8u8 = vld1_u8(src + 16); - src += src_pixels_per_line; - d9u8 = vld1_u8(src); - d10u8 = vld1_u8(src + 8); - d11u8 = vld1_u8(src + 16); - src += src_pixels_per_line; - - __builtin_prefetch(src); - __builtin_prefetch(src + src_pixels_per_line); - - q6u16 = vmull_u8(d6u8, d0u8); - q7u16 = vmull_u8(d7u8, d0u8); - q8u16 = vmull_u8(d9u8, d0u8); - q9u16 = vmull_u8(d10u8, d0u8); - - d20u8 = vext_u8(d6u8, d7u8, 1); - d21u8 = vext_u8(d9u8, d10u8, 1); - d22u8 = vext_u8(d7u8, d8u8, 1); - d23u8 = vext_u8(d10u8, d11u8, 1); - d24u8 = vext_u8(d6u8, d7u8, 4); - d25u8 = vext_u8(d9u8, d10u8, 4); - d26u8 = vext_u8(d7u8, d8u8, 4); - d27u8 = vext_u8(d10u8, d11u8, 4); - d28u8 = vext_u8(d6u8, d7u8, 5); - d29u8 = vext_u8(d9u8, d10u8, 5); - - q6u16 = vmlsl_u8(q6u16, d20u8, d1u8); - q8u16 = vmlsl_u8(q8u16, d21u8, d1u8); - q7u16 = vmlsl_u8(q7u16, d22u8, d1u8); - q9u16 = vmlsl_u8(q9u16, d23u8, d1u8); - q6u16 = vmlsl_u8(q6u16, d24u8, d4u8); - q8u16 = vmlsl_u8(q8u16, d25u8, d4u8); - q7u16 = vmlsl_u8(q7u16, d26u8, d4u8); - q9u16 = vmlsl_u8(q9u16, d27u8, d4u8); - q6u16 = vmlal_u8(q6u16, d28u8, d5u8); - q8u16 = vmlal_u8(q8u16, d29u8, d5u8); - - d20u8 = vext_u8(d7u8, d8u8, 5); - d21u8 = vext_u8(d10u8, d11u8, 5); - d22u8 = vext_u8(d6u8, d7u8, 2); - d23u8 = vext_u8(d9u8, d10u8, 2); - d24u8 = vext_u8(d7u8, d8u8, 2); - d25u8 = vext_u8(d10u8, d11u8, 2); - d26u8 = vext_u8(d6u8, d7u8, 3); - d27u8 = vext_u8(d9u8, d10u8, 3); - d28u8 = vext_u8(d7u8, d8u8, 3); - d29u8 = vext_u8(d10u8, d11u8, 3); - - q7u16 = vmlal_u8(q7u16, d20u8, d5u8); - q9u16 = vmlal_u8(q9u16, d21u8, d5u8); - q6u16 = vmlal_u8(q6u16, d22u8, d2u8); - q8u16 = vmlal_u8(q8u16, d23u8, d2u8); - q7u16 = vmlal_u8(q7u16, d24u8, d2u8); - q9u16 = vmlal_u8(q9u16, d25u8, d2u8); - - q10u16 = vmull_u8(d26u8, d3u8); - q11u16 = vmull_u8(d27u8, d3u8); - q12u16 = vmull_u8(d28u8, d3u8); - q15u16 = vmull_u8(d29u8, d3u8); - - q6s16 = vreinterpretq_s16_u16(q6u16); - q7s16 = vreinterpretq_s16_u16(q7u16); - q8s16 = vreinterpretq_s16_u16(q8u16); - q9s16 = vreinterpretq_s16_u16(q9u16); - q10s16 = vreinterpretq_s16_u16(q10u16); - q11s16 = vreinterpretq_s16_u16(q11u16); - q12s16 = vreinterpretq_s16_u16(q12u16); - q15s16 = vreinterpretq_s16_u16(q15u16); - - q6s16 = vqaddq_s16(q6s16, q10s16); - q8s16 = vqaddq_s16(q8s16, q11s16); - q7s16 = vqaddq_s16(q7s16, q12s16); - q9s16 = vqaddq_s16(q9s16, q15s16); - - d6u8 = vqrshrun_n_s16(q6s16, 7); - d7u8 = vqrshrun_n_s16(q7s16, 7); - d8u8 = vqrshrun_n_s16(q8s16, 7); - d9u8 = vqrshrun_n_s16(q9s16, 7); - - q3u8 = vcombine_u8(d6u8, d7u8); - q4u8 = vcombine_u8(d8u8, d9u8); - vst1q_u8(dst, q3u8); - dst += dst_pitch; - vst1q_u8(dst, q4u8); - dst += dst_pitch; - } - return; - } - - src = src_ptr - 2 - src_pixels_per_line * 2; - tmpp = tmp; - for (i = 0; i < 7; ++i) { - d6u8 = vld1_u8(src); - d7u8 = vld1_u8(src + 8); - d8u8 = vld1_u8(src + 16); - src += src_pixels_per_line; - d9u8 = vld1_u8(src); - d10u8 = vld1_u8(src + 8); - d11u8 = vld1_u8(src + 16); - src += src_pixels_per_line; - d12u8 = vld1_u8(src); - d13u8 = vld1_u8(src + 8); - // Only 5 pixels are needed, avoid a potential out of bounds read. - d14u8 = vld1_u8(src + 13); - d14u8 = vext_u8(d14u8, d14u8, 3); - src += src_pixels_per_line; - - __builtin_prefetch(src); - __builtin_prefetch(src + src_pixels_per_line); - __builtin_prefetch(src + src_pixels_per_line * 2); - - q8u16 = vmull_u8(d6u8, d0u8); - q9u16 = vmull_u8(d7u8, d0u8); - q10u16 = vmull_u8(d9u8, d0u8); - q11u16 = vmull_u8(d10u8, d0u8); - q12u16 = vmull_u8(d12u8, d0u8); - q13u16 = vmull_u8(d13u8, d0u8); - - d28u8 = vext_u8(d6u8, d7u8, 1); - d29u8 = vext_u8(d9u8, d10u8, 1); - d30u8 = vext_u8(d12u8, d13u8, 1); - q8u16 = vmlsl_u8(q8u16, d28u8, d1u8); - q10u16 = vmlsl_u8(q10u16, d29u8, d1u8); - q12u16 = vmlsl_u8(q12u16, d30u8, d1u8); - d28u8 = vext_u8(d7u8, d8u8, 1); - d29u8 = vext_u8(d10u8, d11u8, 1); - d30u8 = vext_u8(d13u8, d14u8, 1); - q9u16 = vmlsl_u8(q9u16, d28u8, d1u8); - q11u16 = vmlsl_u8(q11u16, d29u8, d1u8); - q13u16 = vmlsl_u8(q13u16, d30u8, d1u8); - - d28u8 = vext_u8(d6u8, d7u8, 4); - d29u8 = vext_u8(d9u8, d10u8, 4); - d30u8 = vext_u8(d12u8, d13u8, 4); - q8u16 = vmlsl_u8(q8u16, d28u8, d4u8); - q10u16 = vmlsl_u8(q10u16, d29u8, d4u8); - q12u16 = vmlsl_u8(q12u16, d30u8, d4u8); - d28u8 = vext_u8(d7u8, d8u8, 4); - d29u8 = vext_u8(d10u8, d11u8, 4); - d30u8 = vext_u8(d13u8, d14u8, 4); - q9u16 = vmlsl_u8(q9u16, d28u8, d4u8); - q11u16 = vmlsl_u8(q11u16, d29u8, d4u8); - q13u16 = vmlsl_u8(q13u16, d30u8, d4u8); - - d28u8 = vext_u8(d6u8, d7u8, 5); - d29u8 = vext_u8(d9u8, d10u8, 5); - d30u8 = vext_u8(d12u8, d13u8, 5); - q8u16 = vmlal_u8(q8u16, d28u8, d5u8); - q10u16 = vmlal_u8(q10u16, d29u8, d5u8); - q12u16 = vmlal_u8(q12u16, d30u8, d5u8); - d28u8 = vext_u8(d7u8, d8u8, 5); - d29u8 = vext_u8(d10u8, d11u8, 5); - d30u8 = vext_u8(d13u8, d14u8, 5); - q9u16 = vmlal_u8(q9u16, d28u8, d5u8); - q11u16 = vmlal_u8(q11u16, d29u8, d5u8); - q13u16 = vmlal_u8(q13u16, d30u8, d5u8); - - d28u8 = vext_u8(d6u8, d7u8, 2); - d29u8 = vext_u8(d9u8, d10u8, 2); - d30u8 = vext_u8(d12u8, d13u8, 2); - q8u16 = vmlal_u8(q8u16, d28u8, d2u8); - q10u16 = vmlal_u8(q10u16, d29u8, d2u8); - q12u16 = vmlal_u8(q12u16, d30u8, d2u8); - d28u8 = vext_u8(d7u8, d8u8, 2); - d29u8 = vext_u8(d10u8, d11u8, 2); - d30u8 = vext_u8(d13u8, d14u8, 2); - q9u16 = vmlal_u8(q9u16, d28u8, d2u8); - q11u16 = vmlal_u8(q11u16, d29u8, d2u8); - q13u16 = vmlal_u8(q13u16, d30u8, d2u8); - - d28u8 = vext_u8(d6u8, d7u8, 3); - d29u8 = vext_u8(d9u8, d10u8, 3); - d30u8 = vext_u8(d12u8, d13u8, 3); - d15u8 = vext_u8(d7u8, d8u8, 3); - d31u8 = vext_u8(d10u8, d11u8, 3); - d6u8 = vext_u8(d13u8, d14u8, 3); - q4u16 = vmull_u8(d28u8, d3u8); - q5u16 = vmull_u8(d29u8, d3u8); - q6u16 = vmull_u8(d30u8, d3u8); - q4s16 = vreinterpretq_s16_u16(q4u16); - q5s16 = vreinterpretq_s16_u16(q5u16); - q6s16 = vreinterpretq_s16_u16(q6u16); - q8s16 = vreinterpretq_s16_u16(q8u16); - q10s16 = vreinterpretq_s16_u16(q10u16); - q12s16 = vreinterpretq_s16_u16(q12u16); - q8s16 = vqaddq_s16(q8s16, q4s16); - q10s16 = vqaddq_s16(q10s16, q5s16); - q12s16 = vqaddq_s16(q12s16, q6s16); - - q6u16 = vmull_u8(d15u8, d3u8); - q7u16 = vmull_u8(d31u8, d3u8); - q3u16 = vmull_u8(d6u8, d3u8); - q3s16 = vreinterpretq_s16_u16(q3u16); - q6s16 = vreinterpretq_s16_u16(q6u16); - q7s16 = vreinterpretq_s16_u16(q7u16); - q9s16 = vreinterpretq_s16_u16(q9u16); - q11s16 = vreinterpretq_s16_u16(q11u16); - q13s16 = vreinterpretq_s16_u16(q13u16); - q9s16 = vqaddq_s16(q9s16, q6s16); - q11s16 = vqaddq_s16(q11s16, q7s16); - q13s16 = vqaddq_s16(q13s16, q3s16); - - d6u8 = vqrshrun_n_s16(q8s16, 7); - d7u8 = vqrshrun_n_s16(q9s16, 7); - d8u8 = vqrshrun_n_s16(q10s16, 7); - d9u8 = vqrshrun_n_s16(q11s16, 7); - d10u8 = vqrshrun_n_s16(q12s16, 7); - d11u8 = vqrshrun_n_s16(q13s16, 7); - - vst1_u8(tmpp, d6u8); - tmpp += 8; - vst1_u8(tmpp, d7u8); - tmpp += 8; - vst1_u8(tmpp, d8u8); - tmpp += 8; - vst1_u8(tmpp, d9u8); - tmpp += 8; - vst1_u8(tmpp, d10u8); - tmpp += 8; - vst1_u8(tmpp, d11u8); - tmpp += 8; - } - - // Second pass: 16x16 - dtmps8 = vld1_s8(vp8_sub_pel_filters[yoffset]); - d0s8 = vdup_lane_s8(dtmps8, 0); - d1s8 = vdup_lane_s8(dtmps8, 1); - d2s8 = vdup_lane_s8(dtmps8, 2); - d3s8 = vdup_lane_s8(dtmps8, 3); - d4s8 = vdup_lane_s8(dtmps8, 4); - d5s8 = vdup_lane_s8(dtmps8, 5); - d0u8 = vreinterpret_u8_s8(vabs_s8(d0s8)); - d1u8 = vreinterpret_u8_s8(vabs_s8(d1s8)); - d2u8 = vreinterpret_u8_s8(vabs_s8(d2s8)); - d3u8 = vreinterpret_u8_s8(vabs_s8(d3s8)); - d4u8 = vreinterpret_u8_s8(vabs_s8(d4s8)); - d5u8 = vreinterpret_u8_s8(vabs_s8(d5s8)); - - for (i = 0; i < 2; ++i) { - dst = dst_ptr + 8 * i; - tmpp = tmp + 8 * i; - d18u8 = vld1_u8(tmpp); - tmpp += 16; - d19u8 = vld1_u8(tmpp); - tmpp += 16; - d20u8 = vld1_u8(tmpp); - tmpp += 16; - d21u8 = vld1_u8(tmpp); - tmpp += 16; - d22u8 = vld1_u8(tmpp); - tmpp += 16; - for (j = 0; j < 4; ++j) { - d23u8 = vld1_u8(tmpp); - tmpp += 16; - d24u8 = vld1_u8(tmpp); - tmpp += 16; - d25u8 = vld1_u8(tmpp); - tmpp += 16; - d26u8 = vld1_u8(tmpp); - tmpp += 16; - - q3u16 = vmull_u8(d18u8, d0u8); - q4u16 = vmull_u8(d19u8, d0u8); - q5u16 = vmull_u8(d20u8, d0u8); - q6u16 = vmull_u8(d21u8, d0u8); - - q3u16 = vmlsl_u8(q3u16, d19u8, d1u8); - q4u16 = vmlsl_u8(q4u16, d20u8, d1u8); - q5u16 = vmlsl_u8(q5u16, d21u8, d1u8); - q6u16 = vmlsl_u8(q6u16, d22u8, d1u8); - - q3u16 = vmlsl_u8(q3u16, d22u8, d4u8); - q4u16 = vmlsl_u8(q4u16, d23u8, d4u8); - q5u16 = vmlsl_u8(q5u16, d24u8, d4u8); - q6u16 = vmlsl_u8(q6u16, d25u8, d4u8); - - q3u16 = vmlal_u8(q3u16, d20u8, d2u8); - q4u16 = vmlal_u8(q4u16, d21u8, d2u8); - q5u16 = vmlal_u8(q5u16, d22u8, d2u8); - q6u16 = vmlal_u8(q6u16, d23u8, d2u8); - - q3u16 = vmlal_u8(q3u16, d23u8, d5u8); - q4u16 = vmlal_u8(q4u16, d24u8, d5u8); - q5u16 = vmlal_u8(q5u16, d25u8, d5u8); - q6u16 = vmlal_u8(q6u16, d26u8, d5u8); - - q7u16 = vmull_u8(d21u8, d3u8); - q8u16 = vmull_u8(d22u8, d3u8); - q9u16 = vmull_u8(d23u8, d3u8); - q10u16 = vmull_u8(d24u8, d3u8); - - q3s16 = vreinterpretq_s16_u16(q3u16); - q4s16 = vreinterpretq_s16_u16(q4u16); - q5s16 = vreinterpretq_s16_u16(q5u16); - q6s16 = vreinterpretq_s16_u16(q6u16); - q7s16 = vreinterpretq_s16_u16(q7u16); - q8s16 = vreinterpretq_s16_u16(q8u16); - q9s16 = vreinterpretq_s16_u16(q9u16); - q10s16 = vreinterpretq_s16_u16(q10u16); - - q7s16 = vqaddq_s16(q7s16, q3s16); - q8s16 = vqaddq_s16(q8s16, q4s16); - q9s16 = vqaddq_s16(q9s16, q5s16); - q10s16 = vqaddq_s16(q10s16, q6s16); - - d6u8 = vqrshrun_n_s16(q7s16, 7); - d7u8 = vqrshrun_n_s16(q8s16, 7); - d8u8 = vqrshrun_n_s16(q9s16, 7); - d9u8 = vqrshrun_n_s16(q10s16, 7); - - d18u8 = d22u8; - d19u8 = d23u8; - d20u8 = d24u8; - d21u8 = d25u8; - d22u8 = d26u8; - - vst1_u8(dst, d6u8); - dst += dst_pitch; - vst1_u8(dst, d7u8); - dst += dst_pitch; - vst1_u8(dst, d8u8); - dst += dst_pitch; - vst1_u8(dst, d9u8); - dst += dst_pitch; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/vp8_loopfilter_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/vp8_loopfilter_neon.c deleted file mode 100644 index ebc004a0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/arm/neon/vp8_loopfilter_neon.c +++ /dev/null @@ -1,538 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "vp8/common/arm/loopfilter_arm.h" -#include "vpx_ports/arm.h" - -static INLINE void vp8_loop_filter_neon(uint8x16_t qblimit, // flimit - uint8x16_t qlimit, // limit - uint8x16_t qthresh, // thresh - uint8x16_t q3, // p3 - uint8x16_t q4, // p2 - uint8x16_t q5, // p1 - uint8x16_t q6, // p0 - uint8x16_t q7, // q0 - uint8x16_t q8, // q1 - uint8x16_t q9, // q2 - uint8x16_t q10, // q3 - uint8x16_t *q5r, // p1 - uint8x16_t *q6r, // p0 - uint8x16_t *q7r, // q0 - uint8x16_t *q8r) { // q1 - uint8x16_t q0u8, q1u8, q2u8, q11u8, q12u8, q13u8, q14u8, q15u8; - int16x8_t q2s16, q11s16; - uint16x8_t q4u16; - int8x16_t q1s8, q2s8, q10s8, q11s8, q12s8, q13s8; - int8x8_t d2s8, d3s8; - - q11u8 = vabdq_u8(q3, q4); - q12u8 = vabdq_u8(q4, q5); - q13u8 = vabdq_u8(q5, q6); - q14u8 = vabdq_u8(q8, q7); - q3 = vabdq_u8(q9, q8); - q4 = vabdq_u8(q10, q9); - - q11u8 = vmaxq_u8(q11u8, q12u8); - q12u8 = vmaxq_u8(q13u8, q14u8); - q3 = vmaxq_u8(q3, q4); - q15u8 = vmaxq_u8(q11u8, q12u8); - - q9 = vabdq_u8(q6, q7); - - // vp8_hevmask - q13u8 = vcgtq_u8(q13u8, qthresh); - q14u8 = vcgtq_u8(q14u8, qthresh); - q15u8 = vmaxq_u8(q15u8, q3); - - q2u8 = vabdq_u8(q5, q8); - q9 = vqaddq_u8(q9, q9); - - q15u8 = vcgeq_u8(qlimit, q15u8); - - // vp8_filter() function - // convert to signed - q10 = vdupq_n_u8(0x80); - q8 = veorq_u8(q8, q10); - q7 = veorq_u8(q7, q10); - q6 = veorq_u8(q6, q10); - q5 = veorq_u8(q5, q10); - - q2u8 = vshrq_n_u8(q2u8, 1); - q9 = vqaddq_u8(q9, q2u8); - - q10 = vdupq_n_u8(3); - - q2s16 = vsubl_s8(vget_low_s8(vreinterpretq_s8_u8(q7)), - vget_low_s8(vreinterpretq_s8_u8(q6))); - q11s16 = vsubl_s8(vget_high_s8(vreinterpretq_s8_u8(q7)), - vget_high_s8(vreinterpretq_s8_u8(q6))); - - q9 = vcgeq_u8(qblimit, q9); - - q1s8 = vqsubq_s8(vreinterpretq_s8_u8(q5), vreinterpretq_s8_u8(q8)); - - q14u8 = vorrq_u8(q13u8, q14u8); - - q4u16 = vmovl_u8(vget_low_u8(q10)); - q2s16 = vmulq_s16(q2s16, vreinterpretq_s16_u16(q4u16)); - q11s16 = vmulq_s16(q11s16, vreinterpretq_s16_u16(q4u16)); - - q1u8 = vandq_u8(vreinterpretq_u8_s8(q1s8), q14u8); - q15u8 = vandq_u8(q15u8, q9); - - q1s8 = vreinterpretq_s8_u8(q1u8); - q2s16 = vaddw_s8(q2s16, vget_low_s8(q1s8)); - q11s16 = vaddw_s8(q11s16, vget_high_s8(q1s8)); - - q9 = vdupq_n_u8(4); - // vp8_filter = clamp(vp8_filter + 3 * ( qs0 - ps0)) - d2s8 = vqmovn_s16(q2s16); - d3s8 = vqmovn_s16(q11s16); - q1s8 = vcombine_s8(d2s8, d3s8); - q1u8 = vandq_u8(vreinterpretq_u8_s8(q1s8), q15u8); - q1s8 = vreinterpretq_s8_u8(q1u8); - - q2s8 = vqaddq_s8(q1s8, vreinterpretq_s8_u8(q10)); - q1s8 = vqaddq_s8(q1s8, vreinterpretq_s8_u8(q9)); - q2s8 = vshrq_n_s8(q2s8, 3); - q1s8 = vshrq_n_s8(q1s8, 3); - - q11s8 = vqaddq_s8(vreinterpretq_s8_u8(q6), q2s8); - q10s8 = vqsubq_s8(vreinterpretq_s8_u8(q7), q1s8); - - q1s8 = vrshrq_n_s8(q1s8, 1); - q1s8 = vbicq_s8(q1s8, vreinterpretq_s8_u8(q14u8)); - - q13s8 = vqaddq_s8(vreinterpretq_s8_u8(q5), q1s8); - q12s8 = vqsubq_s8(vreinterpretq_s8_u8(q8), q1s8); - - q0u8 = vdupq_n_u8(0x80); - *q8r = veorq_u8(vreinterpretq_u8_s8(q12s8), q0u8); - *q7r = veorq_u8(vreinterpretq_u8_s8(q10s8), q0u8); - *q6r = veorq_u8(vreinterpretq_u8_s8(q11s8), q0u8); - *q5r = veorq_u8(vreinterpretq_u8_s8(q13s8), q0u8); - return; -} - -void vp8_loop_filter_horizontal_edge_y_neon(unsigned char *src, int pitch, - unsigned char blimit, - unsigned char limit, - unsigned char thresh) { - uint8x16_t qblimit, qlimit, qthresh, q3, q4; - uint8x16_t q5, q6, q7, q8, q9, q10; - - qblimit = vdupq_n_u8(blimit); - qlimit = vdupq_n_u8(limit); - qthresh = vdupq_n_u8(thresh); - src -= (pitch << 2); - - q3 = vld1q_u8(src); - src += pitch; - q4 = vld1q_u8(src); - src += pitch; - q5 = vld1q_u8(src); - src += pitch; - q6 = vld1q_u8(src); - src += pitch; - q7 = vld1q_u8(src); - src += pitch; - q8 = vld1q_u8(src); - src += pitch; - q9 = vld1q_u8(src); - src += pitch; - q10 = vld1q_u8(src); - - vp8_loop_filter_neon(qblimit, qlimit, qthresh, q3, q4, q5, q6, q7, q8, q9, - q10, &q5, &q6, &q7, &q8); - - src -= (pitch * 5); - vst1q_u8(src, q5); - src += pitch; - vst1q_u8(src, q6); - src += pitch; - vst1q_u8(src, q7); - src += pitch; - vst1q_u8(src, q8); - return; -} - -void vp8_loop_filter_horizontal_edge_uv_neon(unsigned char *u, int pitch, - unsigned char blimit, - unsigned char limit, - unsigned char thresh, - unsigned char *v) { - uint8x16_t qblimit, qlimit, qthresh, q3, q4; - uint8x16_t q5, q6, q7, q8, q9, q10; - uint8x8_t d6, d7, d8, d9, d10, d11, d12, d13, d14; - uint8x8_t d15, d16, d17, d18, d19, d20, d21; - - qblimit = vdupq_n_u8(blimit); - qlimit = vdupq_n_u8(limit); - qthresh = vdupq_n_u8(thresh); - - u -= (pitch << 2); - v -= (pitch << 2); - - d6 = vld1_u8(u); - u += pitch; - d7 = vld1_u8(v); - v += pitch; - d8 = vld1_u8(u); - u += pitch; - d9 = vld1_u8(v); - v += pitch; - d10 = vld1_u8(u); - u += pitch; - d11 = vld1_u8(v); - v += pitch; - d12 = vld1_u8(u); - u += pitch; - d13 = vld1_u8(v); - v += pitch; - d14 = vld1_u8(u); - u += pitch; - d15 = vld1_u8(v); - v += pitch; - d16 = vld1_u8(u); - u += pitch; - d17 = vld1_u8(v); - v += pitch; - d18 = vld1_u8(u); - u += pitch; - d19 = vld1_u8(v); - v += pitch; - d20 = vld1_u8(u); - d21 = vld1_u8(v); - - q3 = vcombine_u8(d6, d7); - q4 = vcombine_u8(d8, d9); - q5 = vcombine_u8(d10, d11); - q6 = vcombine_u8(d12, d13); - q7 = vcombine_u8(d14, d15); - q8 = vcombine_u8(d16, d17); - q9 = vcombine_u8(d18, d19); - q10 = vcombine_u8(d20, d21); - - vp8_loop_filter_neon(qblimit, qlimit, qthresh, q3, q4, q5, q6, q7, q8, q9, - q10, &q5, &q6, &q7, &q8); - - u -= (pitch * 5); - vst1_u8(u, vget_low_u8(q5)); - u += pitch; - vst1_u8(u, vget_low_u8(q6)); - u += pitch; - vst1_u8(u, vget_low_u8(q7)); - u += pitch; - vst1_u8(u, vget_low_u8(q8)); - - v -= (pitch * 5); - vst1_u8(v, vget_high_u8(q5)); - v += pitch; - vst1_u8(v, vget_high_u8(q6)); - v += pitch; - vst1_u8(v, vget_high_u8(q7)); - v += pitch; - vst1_u8(v, vget_high_u8(q8)); - return; -} - -static INLINE void write_4x8(unsigned char *dst, int pitch, - const uint8x8x4_t result) { -#ifdef VPX_INCOMPATIBLE_GCC - /* - * uint8x8x4_t result - 00 01 02 03 | 04 05 06 07 - 10 11 12 13 | 14 15 16 17 - 20 21 22 23 | 24 25 26 27 - 30 31 32 33 | 34 35 36 37 - --- - * after vtrn_u16 - 00 01 20 21 | 04 05 24 25 - 02 03 22 23 | 06 07 26 27 - 10 11 30 31 | 14 15 34 35 - 12 13 32 33 | 16 17 36 37 - --- - * after vtrn_u8 - 00 10 20 30 | 04 14 24 34 - 01 11 21 31 | 05 15 25 35 - 02 12 22 32 | 06 16 26 36 - 03 13 23 33 | 07 17 27 37 - */ - const uint16x4x2_t r02_u16 = vtrn_u16(vreinterpret_u16_u8(result.val[0]), - vreinterpret_u16_u8(result.val[2])); - const uint16x4x2_t r13_u16 = vtrn_u16(vreinterpret_u16_u8(result.val[1]), - vreinterpret_u16_u8(result.val[3])); - const uint8x8x2_t r01_u8 = vtrn_u8(vreinterpret_u8_u16(r02_u16.val[0]), - vreinterpret_u8_u16(r13_u16.val[0])); - const uint8x8x2_t r23_u8 = vtrn_u8(vreinterpret_u8_u16(r02_u16.val[1]), - vreinterpret_u8_u16(r13_u16.val[1])); - const uint32x2_t x_0_4 = vreinterpret_u32_u8(r01_u8.val[0]); - const uint32x2_t x_1_5 = vreinterpret_u32_u8(r01_u8.val[1]); - const uint32x2_t x_2_6 = vreinterpret_u32_u8(r23_u8.val[0]); - const uint32x2_t x_3_7 = vreinterpret_u32_u8(r23_u8.val[1]); - vst1_lane_u32((uint32_t *)dst, x_0_4, 0); - dst += pitch; - vst1_lane_u32((uint32_t *)dst, x_1_5, 0); - dst += pitch; - vst1_lane_u32((uint32_t *)dst, x_2_6, 0); - dst += pitch; - vst1_lane_u32((uint32_t *)dst, x_3_7, 0); - dst += pitch; - vst1_lane_u32((uint32_t *)dst, x_0_4, 1); - dst += pitch; - vst1_lane_u32((uint32_t *)dst, x_1_5, 1); - dst += pitch; - vst1_lane_u32((uint32_t *)dst, x_2_6, 1); - dst += pitch; - vst1_lane_u32((uint32_t *)dst, x_3_7, 1); -#else - vst4_lane_u8(dst, result, 0); - dst += pitch; - vst4_lane_u8(dst, result, 1); - dst += pitch; - vst4_lane_u8(dst, result, 2); - dst += pitch; - vst4_lane_u8(dst, result, 3); - dst += pitch; - vst4_lane_u8(dst, result, 4); - dst += pitch; - vst4_lane_u8(dst, result, 5); - dst += pitch; - vst4_lane_u8(dst, result, 6); - dst += pitch; - vst4_lane_u8(dst, result, 7); -#endif // VPX_INCOMPATIBLE_GCC -} - -void vp8_loop_filter_vertical_edge_y_neon(unsigned char *src, int pitch, - unsigned char blimit, - unsigned char limit, - unsigned char thresh) { - unsigned char *s, *d; - uint8x16_t qblimit, qlimit, qthresh, q3, q4; - uint8x16_t q5, q6, q7, q8, q9, q10; - uint8x8_t d6, d7, d8, d9, d10, d11, d12, d13, d14; - uint8x8_t d15, d16, d17, d18, d19, d20, d21; - uint32x4x2_t q2tmp0, q2tmp1, q2tmp2, q2tmp3; - uint16x8x2_t q2tmp4, q2tmp5, q2tmp6, q2tmp7; - uint8x16x2_t q2tmp8, q2tmp9, q2tmp10, q2tmp11; - uint8x8x4_t q4ResultH, q4ResultL; - - qblimit = vdupq_n_u8(blimit); - qlimit = vdupq_n_u8(limit); - qthresh = vdupq_n_u8(thresh); - - s = src - 4; - d6 = vld1_u8(s); - s += pitch; - d8 = vld1_u8(s); - s += pitch; - d10 = vld1_u8(s); - s += pitch; - d12 = vld1_u8(s); - s += pitch; - d14 = vld1_u8(s); - s += pitch; - d16 = vld1_u8(s); - s += pitch; - d18 = vld1_u8(s); - s += pitch; - d20 = vld1_u8(s); - s += pitch; - d7 = vld1_u8(s); - s += pitch; - d9 = vld1_u8(s); - s += pitch; - d11 = vld1_u8(s); - s += pitch; - d13 = vld1_u8(s); - s += pitch; - d15 = vld1_u8(s); - s += pitch; - d17 = vld1_u8(s); - s += pitch; - d19 = vld1_u8(s); - s += pitch; - d21 = vld1_u8(s); - - q3 = vcombine_u8(d6, d7); - q4 = vcombine_u8(d8, d9); - q5 = vcombine_u8(d10, d11); - q6 = vcombine_u8(d12, d13); - q7 = vcombine_u8(d14, d15); - q8 = vcombine_u8(d16, d17); - q9 = vcombine_u8(d18, d19); - q10 = vcombine_u8(d20, d21); - - q2tmp0 = vtrnq_u32(vreinterpretq_u32_u8(q3), vreinterpretq_u32_u8(q7)); - q2tmp1 = vtrnq_u32(vreinterpretq_u32_u8(q4), vreinterpretq_u32_u8(q8)); - q2tmp2 = vtrnq_u32(vreinterpretq_u32_u8(q5), vreinterpretq_u32_u8(q9)); - q2tmp3 = vtrnq_u32(vreinterpretq_u32_u8(q6), vreinterpretq_u32_u8(q10)); - - q2tmp4 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp0.val[0]), - vreinterpretq_u16_u32(q2tmp2.val[0])); - q2tmp5 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp1.val[0]), - vreinterpretq_u16_u32(q2tmp3.val[0])); - q2tmp6 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp0.val[1]), - vreinterpretq_u16_u32(q2tmp2.val[1])); - q2tmp7 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp1.val[1]), - vreinterpretq_u16_u32(q2tmp3.val[1])); - - q2tmp8 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp4.val[0]), - vreinterpretq_u8_u16(q2tmp5.val[0])); - q2tmp9 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp4.val[1]), - vreinterpretq_u8_u16(q2tmp5.val[1])); - q2tmp10 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp6.val[0]), - vreinterpretq_u8_u16(q2tmp7.val[0])); - q2tmp11 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp6.val[1]), - vreinterpretq_u8_u16(q2tmp7.val[1])); - - q3 = q2tmp8.val[0]; - q4 = q2tmp8.val[1]; - q5 = q2tmp9.val[0]; - q6 = q2tmp9.val[1]; - q7 = q2tmp10.val[0]; - q8 = q2tmp10.val[1]; - q9 = q2tmp11.val[0]; - q10 = q2tmp11.val[1]; - - vp8_loop_filter_neon(qblimit, qlimit, qthresh, q3, q4, q5, q6, q7, q8, q9, - q10, &q5, &q6, &q7, &q8); - - q4ResultL.val[0] = vget_low_u8(q5); // d10 - q4ResultL.val[1] = vget_low_u8(q6); // d12 - q4ResultL.val[2] = vget_low_u8(q7); // d14 - q4ResultL.val[3] = vget_low_u8(q8); // d16 - q4ResultH.val[0] = vget_high_u8(q5); // d11 - q4ResultH.val[1] = vget_high_u8(q6); // d13 - q4ResultH.val[2] = vget_high_u8(q7); // d15 - q4ResultH.val[3] = vget_high_u8(q8); // d17 - - d = src - 2; - write_4x8(d, pitch, q4ResultL); - d += pitch * 8; - write_4x8(d, pitch, q4ResultH); -} - -void vp8_loop_filter_vertical_edge_uv_neon(unsigned char *u, int pitch, - unsigned char blimit, - unsigned char limit, - unsigned char thresh, - unsigned char *v) { - unsigned char *us, *ud; - unsigned char *vs, *vd; - uint8x16_t qblimit, qlimit, qthresh, q3, q4; - uint8x16_t q5, q6, q7, q8, q9, q10; - uint8x8_t d6, d7, d8, d9, d10, d11, d12, d13, d14; - uint8x8_t d15, d16, d17, d18, d19, d20, d21; - uint32x4x2_t q2tmp0, q2tmp1, q2tmp2, q2tmp3; - uint16x8x2_t q2tmp4, q2tmp5, q2tmp6, q2tmp7; - uint8x16x2_t q2tmp8, q2tmp9, q2tmp10, q2tmp11; - uint8x8x4_t q4ResultH, q4ResultL; - - qblimit = vdupq_n_u8(blimit); - qlimit = vdupq_n_u8(limit); - qthresh = vdupq_n_u8(thresh); - - us = u - 4; - d6 = vld1_u8(us); - us += pitch; - d8 = vld1_u8(us); - us += pitch; - d10 = vld1_u8(us); - us += pitch; - d12 = vld1_u8(us); - us += pitch; - d14 = vld1_u8(us); - us += pitch; - d16 = vld1_u8(us); - us += pitch; - d18 = vld1_u8(us); - us += pitch; - d20 = vld1_u8(us); - - vs = v - 4; - d7 = vld1_u8(vs); - vs += pitch; - d9 = vld1_u8(vs); - vs += pitch; - d11 = vld1_u8(vs); - vs += pitch; - d13 = vld1_u8(vs); - vs += pitch; - d15 = vld1_u8(vs); - vs += pitch; - d17 = vld1_u8(vs); - vs += pitch; - d19 = vld1_u8(vs); - vs += pitch; - d21 = vld1_u8(vs); - - q3 = vcombine_u8(d6, d7); - q4 = vcombine_u8(d8, d9); - q5 = vcombine_u8(d10, d11); - q6 = vcombine_u8(d12, d13); - q7 = vcombine_u8(d14, d15); - q8 = vcombine_u8(d16, d17); - q9 = vcombine_u8(d18, d19); - q10 = vcombine_u8(d20, d21); - - q2tmp0 = vtrnq_u32(vreinterpretq_u32_u8(q3), vreinterpretq_u32_u8(q7)); - q2tmp1 = vtrnq_u32(vreinterpretq_u32_u8(q4), vreinterpretq_u32_u8(q8)); - q2tmp2 = vtrnq_u32(vreinterpretq_u32_u8(q5), vreinterpretq_u32_u8(q9)); - q2tmp3 = vtrnq_u32(vreinterpretq_u32_u8(q6), vreinterpretq_u32_u8(q10)); - - q2tmp4 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp0.val[0]), - vreinterpretq_u16_u32(q2tmp2.val[0])); - q2tmp5 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp1.val[0]), - vreinterpretq_u16_u32(q2tmp3.val[0])); - q2tmp6 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp0.val[1]), - vreinterpretq_u16_u32(q2tmp2.val[1])); - q2tmp7 = vtrnq_u16(vreinterpretq_u16_u32(q2tmp1.val[1]), - vreinterpretq_u16_u32(q2tmp3.val[1])); - - q2tmp8 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp4.val[0]), - vreinterpretq_u8_u16(q2tmp5.val[0])); - q2tmp9 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp4.val[1]), - vreinterpretq_u8_u16(q2tmp5.val[1])); - q2tmp10 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp6.val[0]), - vreinterpretq_u8_u16(q2tmp7.val[0])); - q2tmp11 = vtrnq_u8(vreinterpretq_u8_u16(q2tmp6.val[1]), - vreinterpretq_u8_u16(q2tmp7.val[1])); - - q3 = q2tmp8.val[0]; - q4 = q2tmp8.val[1]; - q5 = q2tmp9.val[0]; - q6 = q2tmp9.val[1]; - q7 = q2tmp10.val[0]; - q8 = q2tmp10.val[1]; - q9 = q2tmp11.val[0]; - q10 = q2tmp11.val[1]; - - vp8_loop_filter_neon(qblimit, qlimit, qthresh, q3, q4, q5, q6, q7, q8, q9, - q10, &q5, &q6, &q7, &q8); - - q4ResultL.val[0] = vget_low_u8(q5); // d10 - q4ResultL.val[1] = vget_low_u8(q6); // d12 - q4ResultL.val[2] = vget_low_u8(q7); // d14 - q4ResultL.val[3] = vget_low_u8(q8); // d16 - ud = u - 2; - write_4x8(ud, pitch, q4ResultL); - - q4ResultH.val[0] = vget_high_u8(q5); // d11 - q4ResultH.val[1] = vget_high_u8(q6); // d13 - q4ResultH.val[2] = vget_high_u8(q7); // d15 - q4ResultH.val[3] = vget_high_u8(q8); // d17 - vd = v - 2; - write_4x8(vd, pitch, q4ResultH); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/blockd.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/blockd.c deleted file mode 100644 index 22905c10..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/blockd.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "blockd.h" -#include "vpx_mem/vpx_mem.h" - -const unsigned char vp8_block2left[25] = { 0, 0, 0, 0, 1, 1, 1, 1, 2, - 2, 2, 2, 3, 3, 3, 3, 4, 4, - 5, 5, 6, 6, 7, 7, 8 }; -const unsigned char vp8_block2above[25] = { 0, 1, 2, 3, 0, 1, 2, 3, 0, - 1, 2, 3, 0, 1, 2, 3, 4, 5, - 4, 5, 6, 7, 6, 7, 8 }; diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/blockd.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/blockd.h deleted file mode 100644 index 8300aad9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/blockd.h +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_BLOCKD_H_ -#define VPX_VP8_COMMON_BLOCKD_H_ - -void vpx_log(const char *format, ...); - -#include "vpx/internal/vpx_codec_internal.h" -#include "vpx_config.h" -#include "vpx_scale/yv12config.h" -#include "mv.h" -#include "treecoder.h" -#include "vpx_ports/mem.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*#define DCPRED 1*/ -#define DCPREDSIMTHRESH 0 -#define DCPREDCNTTHRESH 3 - -#define MB_FEATURE_TREE_PROBS 3 -#define MAX_MB_SEGMENTS 4 - -#define MAX_REF_LF_DELTAS 4 -#define MAX_MODE_LF_DELTAS 4 - -/* Segment Feature Masks */ -#define SEGMENT_DELTADATA 0 -#define SEGMENT_ABSDATA 1 - -typedef struct { - int r, c; -} POS; - -#define PLANE_TYPE_Y_NO_DC 0 -#define PLANE_TYPE_Y2 1 -#define PLANE_TYPE_UV 2 -#define PLANE_TYPE_Y_WITH_DC 3 - -typedef char ENTROPY_CONTEXT; -typedef struct { - ENTROPY_CONTEXT y1[4]; - ENTROPY_CONTEXT u[2]; - ENTROPY_CONTEXT v[2]; - ENTROPY_CONTEXT y2; -} ENTROPY_CONTEXT_PLANES; - -extern const unsigned char vp8_block2left[25]; -extern const unsigned char vp8_block2above[25]; - -#define VP8_COMBINEENTROPYCONTEXTS(Dest, A, B) Dest = (A) + (B) - -typedef enum { KEY_FRAME = 0, INTER_FRAME = 1 } FRAME_TYPE; - -typedef enum { - DC_PRED, /* average of above and left pixels */ - V_PRED, /* vertical prediction */ - H_PRED, /* horizontal prediction */ - TM_PRED, /* Truemotion prediction */ - B_PRED, /* block based prediction, each block has its own prediction mode */ - - NEARESTMV, - NEARMV, - ZEROMV, - NEWMV, - SPLITMV, - - MB_MODE_COUNT -} MB_PREDICTION_MODE; - -/* Macroblock level features */ -typedef enum { - MB_LVL_ALT_Q = 0, /* Use alternate Quantizer .... */ - MB_LVL_ALT_LF = 1, /* Use alternate loop filter value... */ - MB_LVL_MAX = 2 /* Number of MB level features supported */ - -} MB_LVL_FEATURES; - -/* Segment Feature Masks */ -#define SEGMENT_ALTQ 0x01 -#define SEGMENT_ALT_LF 0x02 - -#define VP8_YMODES (B_PRED + 1) -#define VP8_UV_MODES (TM_PRED + 1) - -#define VP8_MVREFS (1 + SPLITMV - NEARESTMV) - -typedef enum { - B_DC_PRED, /* average of above and left pixels */ - B_TM_PRED, - - B_VE_PRED, /* vertical prediction */ - B_HE_PRED, /* horizontal prediction */ - - B_LD_PRED, - B_RD_PRED, - - B_VR_PRED, - B_VL_PRED, - B_HD_PRED, - B_HU_PRED, - - LEFT4X4, - ABOVE4X4, - ZERO4X4, - NEW4X4, - - B_MODE_COUNT -} B_PREDICTION_MODE; - -#define VP8_BINTRAMODES (B_HU_PRED + 1) /* 10 */ -#define VP8_SUBMVREFS (1 + NEW4X4 - LEFT4X4) - -/* For keyframes, intra block modes are predicted by the (already decoded) - modes for the Y blocks to the left and above us; for interframes, there - is a single probability table. */ - -union b_mode_info { - B_PREDICTION_MODE as_mode; - int_mv mv; -}; - -typedef enum { - INTRA_FRAME = 0, - LAST_FRAME = 1, - GOLDEN_FRAME = 2, - ALTREF_FRAME = 3, - MAX_REF_FRAMES = 4 -} MV_REFERENCE_FRAME; - -typedef struct { - uint8_t mode, uv_mode; - uint8_t ref_frame; - uint8_t is_4x4; - int_mv mv; - - uint8_t partitioning; - /* does this mb has coefficients at all, 1=no coefficients, 0=need decode - tokens */ - uint8_t mb_skip_coeff; - uint8_t need_to_clamp_mvs; - /* Which set of segmentation parameters should be used for this MB */ - uint8_t segment_id; -} MB_MODE_INFO; - -typedef struct modeinfo { - MB_MODE_INFO mbmi; - union b_mode_info bmi[16]; -} MODE_INFO; - -#if CONFIG_MULTI_RES_ENCODING -/* The mb-level information needed to be stored for higher-resolution encoder */ -typedef struct { - MB_PREDICTION_MODE mode; - MV_REFERENCE_FRAME ref_frame; - int_mv mv; - int dissim; /* dissimilarity level of the macroblock */ -} LOWER_RES_MB_INFO; - -/* The frame-level information needed to be stored for higher-resolution - * encoder */ -typedef struct { - FRAME_TYPE frame_type; - int is_frame_dropped; - // If frame is dropped due to overshoot after encode_frame. This triggers a - // drop and resets rate control with Q forced to max for following frame. - // The check for this dropping due to overshoot is only done on lowest stream, - // and if set will force drop on all spatial streams for that current frame. - int is_frame_dropped_overshoot_maxqp; - // The frame rate for the lowest resolution. - double low_res_framerate; - /* The frame number of each reference frames */ - unsigned int low_res_ref_frames[MAX_REF_FRAMES]; - // The video frame counter value for the key frame, for lowest resolution. - unsigned int key_frame_counter_value; - // Flags to signal skipped encoding of previous and base layer stream. - unsigned int skip_encoding_prev_stream; - unsigned int skip_encoding_base_stream; - LOWER_RES_MB_INFO *mb_info; -} LOWER_RES_FRAME_INFO; -#endif - -typedef struct blockd { - short *qcoeff; - short *dqcoeff; - unsigned char *predictor; - short *dequant; - - int offset; - char *eob; - - union b_mode_info bmi; -} BLOCKD; - -typedef void (*vp8_subpix_fn_t)(unsigned char *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, - unsigned char *dst_ptr, int dst_pitch); - -typedef struct macroblockd { - DECLARE_ALIGNED(16, unsigned char, predictor[384]); - DECLARE_ALIGNED(16, short, qcoeff[400]); - DECLARE_ALIGNED(16, short, dqcoeff[400]); - DECLARE_ALIGNED(16, char, eobs[25]); - - DECLARE_ALIGNED(16, short, dequant_y1[16]); - DECLARE_ALIGNED(16, short, dequant_y1_dc[16]); - DECLARE_ALIGNED(16, short, dequant_y2[16]); - DECLARE_ALIGNED(16, short, dequant_uv[16]); - - /* 16 Y blocks, 4 U, 4 V, 1 DC 2nd order block, each with 16 entries. */ - BLOCKD block[25]; - int fullpixel_mask; - - YV12_BUFFER_CONFIG pre; /* Filtered copy of previous frame reconstruction */ - YV12_BUFFER_CONFIG dst; - - MODE_INFO *mode_info_context; - int mode_info_stride; - - FRAME_TYPE frame_type; - - int up_available; - int left_available; - - unsigned char *recon_above[3]; - unsigned char *recon_left[3]; - int recon_left_stride[2]; - - /* Y,U,V,Y2 */ - ENTROPY_CONTEXT_PLANES *above_context; - ENTROPY_CONTEXT_PLANES *left_context; - - /* 0 indicates segmentation at MB level is not enabled. Otherwise the - * individual bits indicate which features are active. */ - unsigned char segmentation_enabled; - - /* 0 (do not update) 1 (update) the macroblock segmentation map. */ - unsigned char update_mb_segmentation_map; - - /* 0 (do not update) 1 (update) the macroblock segmentation feature data. */ - unsigned char update_mb_segmentation_data; - - /* 0 (do not update) 1 (update) the macroblock segmentation feature data. */ - unsigned char mb_segment_abs_delta; - - /* Per frame flags that define which MB level features (such as quantizer or - * loop filter level) */ - /* are enabled and when enabled the proabilities used to decode the per MB - * flags in MB_MODE_INFO */ - /* Probability Tree used to code Segment number */ - vp8_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS]; - /* Segment parameters */ - signed char segment_feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; - - /* mode_based Loop filter adjustment */ - unsigned char mode_ref_lf_delta_enabled; - unsigned char mode_ref_lf_delta_update; - - /* Delta values have the range +/- MAX_LOOP_FILTER */ - signed char - last_ref_lf_deltas[MAX_REF_LF_DELTAS]; /* 0 = Intra, Last, GF, ARF */ - signed char ref_lf_deltas[MAX_REF_LF_DELTAS]; /* 0 = Intra, Last, GF, ARF */ - /* 0 = BPRED, ZERO_MV, MV, SPLIT */ - signed char last_mode_lf_deltas[MAX_MODE_LF_DELTAS]; - signed char - mode_lf_deltas[MAX_MODE_LF_DELTAS]; /* 0 = BPRED, ZERO_MV, MV, SPLIT */ - - /* Distance of MB away from frame edges */ - int mb_to_left_edge; - int mb_to_right_edge; - int mb_to_top_edge; - int mb_to_bottom_edge; - - vp8_subpix_fn_t subpixel_predict; - vp8_subpix_fn_t subpixel_predict8x4; - vp8_subpix_fn_t subpixel_predict8x8; - vp8_subpix_fn_t subpixel_predict16x16; - - void *current_bc; - - int corrupted; - - struct vpx_internal_error_info error_info; - -#if VPX_ARCH_X86 || VPX_ARCH_X86_64 - /* This is an intermediate buffer currently used in sub-pixel motion search - * to keep a copy of the reference area. This buffer can be used for other - * purpose. - */ - DECLARE_ALIGNED(32, unsigned char, y_buf[22 * 32]); -#endif -} MACROBLOCKD; - -extern void vp8_build_block_doffsets(MACROBLOCKD *x); -extern void vp8_setup_block_dptrs(MACROBLOCKD *x); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_BLOCKD_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/coefupdateprobs.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/coefupdateprobs.h deleted file mode 100644 index b342096b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/coefupdateprobs.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_COEFUPDATEPROBS_H_ -#define VPX_VP8_COMMON_COEFUPDATEPROBS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Update probabilities for the nodes in the token entropy tree. - Generated file included by entropy.c */ - -const vp8_prob vp8_coef_update_probs - [BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES] = { - { - { - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255 }, - { 250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255 }, - { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - }, - { - { - { 217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255 }, - { 234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255 }, - }, - { - { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - }, - { - { - { 186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255 }, - { 251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255 }, - }, - { - { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - }, - { - { - { 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255 }, - { 248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - { - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - }, - }, - }; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_COEFUPDATEPROBS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/common.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/common.h deleted file mode 100644 index 562569f9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/common.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_COMMON_H_ -#define VPX_VP8_COMMON_COMMON_H_ - -#include - -/* Interface header for common constant data structures and lookup tables */ - -#include "vpx_mem/vpx_mem.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Only need this for fixed-size arrays, for structs just assign. */ - -#define vp8_copy(Dest, Src) \ - do { \ - assert(sizeof(Dest) == sizeof(Src)); \ - memcpy(Dest, Src, sizeof(Src)); \ - } while (0) - -/* Use this for variably-sized arrays. */ - -#define vp8_copy_array(Dest, Src, N) \ - do { \ - assert(sizeof(*(Dest)) == sizeof(*(Src))); \ - memcpy(Dest, Src, (N) * sizeof(*(Src))); \ - } while (0) - -#define vp8_zero(Dest) memset(&(Dest), 0, sizeof(Dest)) - -#define vp8_zero_array(Dest, N) memset(Dest, 0, (N) * sizeof(*(Dest))) - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_COMMON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/context.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/context.c deleted file mode 100644 index 3c624ae6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/context.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "entropy.h" - -/* *** GENERATED FILE: DO NOT EDIT *** */ - -#if 0 -int Contexts[vp8_coef_counter_dimen]; - -const int default_contexts[vp8_coef_counter_dimen] = -{ - { - // Block Type ( 0 ) - { - // Coeff Band ( 0 ) - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - }, - { - // Coeff Band ( 1 ) - {30190, 26544, 225, 24, 4, 0, 0, 0, 0, 0, 0, 4171593,}, - {26846, 25157, 1241, 130, 26, 6, 1, 0, 0, 0, 0, 149987,}, - {10484, 9538, 1006, 160, 36, 18, 0, 0, 0, 0, 0, 15104,}, - }, - { - // Coeff Band ( 2 ) - {25842, 40456, 1126, 83, 11, 2, 0, 0, 0, 0, 0, 0,}, - {9338, 8010, 512, 73, 7, 3, 2, 0, 0, 0, 0, 43294,}, - {1047, 751, 149, 31, 13, 6, 1, 0, 0, 0, 0, 879,}, - }, - { - // Coeff Band ( 3 ) - {26136, 9826, 252, 13, 0, 0, 0, 0, 0, 0, 0, 0,}, - {8134, 5574, 191, 14, 2, 0, 0, 0, 0, 0, 0, 35302,}, - { 605, 677, 116, 9, 1, 0, 0, 0, 0, 0, 0, 611,}, - }, - { - // Coeff Band ( 4 ) - {10263, 15463, 283, 17, 0, 0, 0, 0, 0, 0, 0, 0,}, - {2773, 2191, 128, 9, 2, 2, 0, 0, 0, 0, 0, 10073,}, - { 134, 125, 32, 4, 0, 2, 0, 0, 0, 0, 0, 50,}, - }, - { - // Coeff Band ( 5 ) - {10483, 2663, 23, 1, 0, 0, 0, 0, 0, 0, 0, 0,}, - {2137, 1251, 27, 1, 1, 0, 0, 0, 0, 0, 0, 14362,}, - { 116, 156, 14, 2, 1, 0, 0, 0, 0, 0, 0, 190,}, - }, - { - // Coeff Band ( 6 ) - {40977, 27614, 412, 28, 0, 0, 0, 0, 0, 0, 0, 0,}, - {6113, 5213, 261, 22, 3, 0, 0, 0, 0, 0, 0, 26164,}, - { 382, 312, 50, 14, 2, 0, 0, 0, 0, 0, 0, 345,}, - }, - { - // Coeff Band ( 7 ) - { 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - { 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 319,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,}, - }, - }, - { - // Block Type ( 1 ) - { - // Coeff Band ( 0 ) - {3268, 19382, 1043, 250, 93, 82, 49, 26, 17, 8, 25, 82289,}, - {8758, 32110, 5436, 1832, 827, 668, 420, 153, 24, 0, 3, 52914,}, - {9337, 23725, 8487, 3954, 2107, 1836, 1069, 399, 59, 0, 0, 18620,}, - }, - { - // Coeff Band ( 1 ) - {12419, 8420, 452, 62, 9, 1, 0, 0, 0, 0, 0, 0,}, - {11715, 8705, 693, 92, 15, 7, 2, 0, 0, 0, 0, 53988,}, - {7603, 8585, 2306, 778, 270, 145, 39, 5, 0, 0, 0, 9136,}, - }, - { - // Coeff Band ( 2 ) - {15938, 14335, 1207, 184, 55, 13, 4, 1, 0, 0, 0, 0,}, - {7415, 6829, 1138, 244, 71, 26, 7, 0, 0, 0, 0, 9980,}, - {1580, 1824, 655, 241, 89, 46, 10, 2, 0, 0, 0, 429,}, - }, - { - // Coeff Band ( 3 ) - {19453, 5260, 201, 19, 0, 0, 0, 0, 0, 0, 0, 0,}, - {9173, 3758, 213, 22, 1, 1, 0, 0, 0, 0, 0, 9820,}, - {1689, 1277, 276, 51, 17, 4, 0, 0, 0, 0, 0, 679,}, - }, - { - // Coeff Band ( 4 ) - {12076, 10667, 620, 85, 19, 9, 5, 0, 0, 0, 0, 0,}, - {4665, 3625, 423, 55, 19, 9, 0, 0, 0, 0, 0, 5127,}, - { 415, 440, 143, 34, 20, 7, 2, 0, 0, 0, 0, 101,}, - }, - { - // Coeff Band ( 5 ) - {12183, 4846, 115, 11, 1, 0, 0, 0, 0, 0, 0, 0,}, - {4226, 3149, 177, 21, 2, 0, 0, 0, 0, 0, 0, 7157,}, - { 375, 621, 189, 51, 11, 4, 1, 0, 0, 0, 0, 198,}, - }, - { - // Coeff Band ( 6 ) - {61658, 37743, 1203, 94, 10, 3, 0, 0, 0, 0, 0, 0,}, - {15514, 11563, 903, 111, 14, 5, 0, 0, 0, 0, 0, 25195,}, - { 929, 1077, 291, 78, 14, 7, 1, 0, 0, 0, 0, 507,}, - }, - { - // Coeff Band ( 7 ) - { 0, 990, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0,}, - { 0, 412, 13, 0, 0, 0, 0, 0, 0, 0, 0, 1641,}, - { 0, 18, 7, 1, 0, 0, 0, 0, 0, 0, 0, 30,}, - }, - }, - { - // Block Type ( 2 ) - { - // Coeff Band ( 0 ) - { 953, 24519, 628, 120, 28, 12, 4, 0, 0, 0, 0, 2248798,}, - {1525, 25654, 2647, 617, 239, 143, 42, 5, 0, 0, 0, 66837,}, - {1180, 11011, 3001, 1237, 532, 448, 239, 54, 5, 0, 0, 7122,}, - }, - { - // Coeff Band ( 1 ) - {1356, 2220, 67, 10, 4, 1, 0, 0, 0, 0, 0, 0,}, - {1450, 2544, 102, 18, 4, 3, 0, 0, 0, 0, 0, 57063,}, - {1182, 2110, 470, 130, 41, 21, 0, 0, 0, 0, 0, 6047,}, - }, - { - // Coeff Band ( 2 ) - { 370, 3378, 200, 30, 5, 4, 1, 0, 0, 0, 0, 0,}, - { 293, 1006, 131, 29, 11, 0, 0, 0, 0, 0, 0, 5404,}, - { 114, 387, 98, 23, 4, 8, 1, 0, 0, 0, 0, 236,}, - }, - { - // Coeff Band ( 3 ) - { 579, 194, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - { 395, 213, 5, 1, 0, 0, 0, 0, 0, 0, 0, 4157,}, - { 119, 122, 4, 0, 0, 0, 0, 0, 0, 0, 0, 300,}, - }, - { - // Coeff Band ( 4 ) - { 38, 557, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - { 21, 114, 12, 1, 0, 0, 0, 0, 0, 0, 0, 427,}, - { 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,}, - }, - { - // Coeff Band ( 5 ) - { 52, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - { 18, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 652,}, - { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30,}, - }, - { - // Coeff Band ( 6 ) - { 640, 569, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - { 25, 77, 2, 0, 0, 0, 0, 0, 0, 0, 0, 517,}, - { 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,}, - }, - { - // Coeff Band ( 7 ) - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - }, - }, - { - // Block Type ( 3 ) - { - // Coeff Band ( 0 ) - {2506, 20161, 2707, 767, 261, 178, 107, 30, 14, 3, 0, 100694,}, - {8806, 36478, 8817, 3268, 1280, 850, 401, 114, 42, 0, 0, 58572,}, - {11003, 27214, 11798, 5716, 2482, 2072, 1048, 175, 32, 0, 0, 19284,}, - }, - { - // Coeff Band ( 1 ) - {9738, 11313, 959, 205, 70, 18, 11, 1, 0, 0, 0, 0,}, - {12628, 15085, 1507, 273, 52, 19, 9, 0, 0, 0, 0, 54280,}, - {10701, 15846, 5561, 1926, 813, 570, 249, 36, 0, 0, 0, 6460,}, - }, - { - // Coeff Band ( 2 ) - {6781, 22539, 2784, 634, 182, 123, 20, 4, 0, 0, 0, 0,}, - {6263, 11544, 2649, 790, 259, 168, 27, 5, 0, 0, 0, 20539,}, - {3109, 4075, 2031, 896, 457, 386, 158, 29, 0, 0, 0, 1138,}, - }, - { - // Coeff Band ( 3 ) - {11515, 4079, 465, 73, 5, 14, 2, 0, 0, 0, 0, 0,}, - {9361, 5834, 650, 96, 24, 8, 4, 0, 0, 0, 0, 22181,}, - {4343, 3974, 1360, 415, 132, 96, 14, 1, 0, 0, 0, 1267,}, - }, - { - // Coeff Band ( 4 ) - {4787, 9297, 823, 168, 44, 12, 4, 0, 0, 0, 0, 0,}, - {3619, 4472, 719, 198, 60, 31, 3, 0, 0, 0, 0, 8401,}, - {1157, 1175, 483, 182, 88, 31, 8, 0, 0, 0, 0, 268,}, - }, - { - // Coeff Band ( 5 ) - {8299, 1226, 32, 5, 1, 0, 0, 0, 0, 0, 0, 0,}, - {3502, 1568, 57, 4, 1, 1, 0, 0, 0, 0, 0, 9811,}, - {1055, 1070, 166, 29, 6, 1, 0, 0, 0, 0, 0, 527,}, - }, - { - // Coeff Band ( 6 ) - {27414, 27927, 1989, 347, 69, 26, 0, 0, 0, 0, 0, 0,}, - {5876, 10074, 1574, 341, 91, 24, 4, 0, 0, 0, 0, 21954,}, - {1571, 2171, 778, 324, 124, 65, 16, 0, 0, 0, 0, 979,}, - }, - { - // Coeff Band ( 7 ) - { 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - { 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 459,}, - { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13,}, - }, - }, -}; - -//Update probabilities for the nodes in the token entropy tree. -const vp8_prob tree_update_probs[vp8_coef_tree_dimen] = -{ - { - { - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255, }, - {249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255, }, - {234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255, }, - {250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255, }, - {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - }, - { - { - {217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255, }, - {234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255, }, - }, - { - {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, - {250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - }, - { - { - {186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255, }, - {234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255, }, - {251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255, }, - }, - { - {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - }, - { - { - {248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255, }, - {248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, - {246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, - {252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255, }, - {248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, - {253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, - {252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, - {250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - }, -}; -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/debugmodes.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/debugmodes.c deleted file mode 100644 index 27a97b26..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/debugmodes.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "blockd.h" - -void vp8_print_modes_and_motion_vectors(MODE_INFO *mi, int rows, int cols, - int frame) { - int mb_row; - int mb_col; - int mb_index = 0; - FILE *mvs = fopen("mvs.stt", "a"); - - /* print out the macroblock Y modes */ - mb_index = 0; - fprintf(mvs, "Mb Modes for Frame %d\n", frame); - - for (mb_row = 0; mb_row < rows; ++mb_row) { - for (mb_col = 0; mb_col < cols; ++mb_col) { - fprintf(mvs, "%2d ", mi[mb_index].mbmi.mode); - - mb_index++; - } - - fprintf(mvs, "\n"); - mb_index++; - } - - fprintf(mvs, "\n"); - - mb_index = 0; - fprintf(mvs, "Mb mv ref for Frame %d\n", frame); - - for (mb_row = 0; mb_row < rows; ++mb_row) { - for (mb_col = 0; mb_col < cols; ++mb_col) { - fprintf(mvs, "%2d ", mi[mb_index].mbmi.ref_frame); - - mb_index++; - } - - fprintf(mvs, "\n"); - mb_index++; - } - - fprintf(mvs, "\n"); - - /* print out the macroblock UV modes */ - mb_index = 0; - fprintf(mvs, "UV Modes for Frame %d\n", frame); - - for (mb_row = 0; mb_row < rows; ++mb_row) { - for (mb_col = 0; mb_col < cols; ++mb_col) { - fprintf(mvs, "%2d ", mi[mb_index].mbmi.uv_mode); - - mb_index++; - } - - mb_index++; - fprintf(mvs, "\n"); - } - - fprintf(mvs, "\n"); - - /* print out the block modes */ - fprintf(mvs, "Mbs for Frame %d\n", frame); - { - int b_row; - - for (b_row = 0; b_row < 4 * rows; ++b_row) { - int b_col; - int bindex; - - for (b_col = 0; b_col < 4 * cols; ++b_col) { - mb_index = (b_row >> 2) * (cols + 1) + (b_col >> 2); - bindex = (b_row & 3) * 4 + (b_col & 3); - - if (mi[mb_index].mbmi.mode == B_PRED) - fprintf(mvs, "%2d ", mi[mb_index].bmi[bindex].as_mode); - else - fprintf(mvs, "xx "); - } - - fprintf(mvs, "\n"); - } - } - fprintf(mvs, "\n"); - - /* print out the macroblock mvs */ - mb_index = 0; - fprintf(mvs, "MVs for Frame %d\n", frame); - - for (mb_row = 0; mb_row < rows; ++mb_row) { - for (mb_col = 0; mb_col < cols; ++mb_col) { - fprintf(mvs, "%5d:%-5d", mi[mb_index].mbmi.mv.as_mv.row / 2, - mi[mb_index].mbmi.mv.as_mv.col / 2); - - mb_index++; - } - - mb_index++; - fprintf(mvs, "\n"); - } - - fprintf(mvs, "\n"); - - /* print out the block modes */ - fprintf(mvs, "MVs for Frame %d\n", frame); - { - int b_row; - - for (b_row = 0; b_row < 4 * rows; ++b_row) { - int b_col; - int bindex; - - for (b_col = 0; b_col < 4 * cols; ++b_col) { - mb_index = (b_row >> 2) * (cols + 1) + (b_col >> 2); - bindex = (b_row & 3) * 4 + (b_col & 3); - fprintf(mvs, "%3d:%-3d ", mi[mb_index].bmi[bindex].mv.as_mv.row, - mi[mb_index].bmi[bindex].mv.as_mv.col); - } - - fprintf(mvs, "\n"); - } - } - fprintf(mvs, "\n"); - - fclose(mvs); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/default_coef_probs.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/default_coef_probs.h deleted file mode 100644 index b25e4a45..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/default_coef_probs.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_DEFAULT_COEF_PROBS_H_ -#define VPX_VP8_COMMON_DEFAULT_COEF_PROBS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/*Generated file, included by entropy.c*/ - -static const vp8_prob default_coef_probs - [BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES] = { - { /* Block Type ( 0 ) */ - { /* Coeff Band ( 0 )*/ - { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }, - { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }, - { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } }, - { /* Coeff Band ( 1 )*/ - { 253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128 }, - { 189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128 }, - { 106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128 } }, - { /* Coeff Band ( 2 )*/ - { 1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128 }, - { 181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128 }, - { 78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128 } }, - { /* Coeff Band ( 3 )*/ - { 1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128 }, - { 184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128 }, - { 77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128 } }, - { /* Coeff Band ( 4 )*/ - { 1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128 }, - { 170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128 }, - { 37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128 } }, - { /* Coeff Band ( 5 )*/ - { 1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128 }, - { 207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128 }, - { 102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128 } }, - { /* Coeff Band ( 6 )*/ - { 1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128 }, - { 177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128 }, - { 80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128 } }, - { /* Coeff Band ( 7 )*/ - { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, - { 246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, - { 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } } }, - { /* Block Type ( 1 ) */ - { /* Coeff Band ( 0 )*/ - { 198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62 }, - { 131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1 }, - { 68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128 } }, - { /* Coeff Band ( 1 )*/ - { 1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128 }, - { 184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128 }, - { 81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128 } }, - { /* Coeff Band ( 2 )*/ - { 1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128 }, - { 99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128 }, - { 23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128 } }, - { /* Coeff Band ( 3 )*/ - { 1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128 }, - { 109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128 }, - { 44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128 } }, - { /* Coeff Band ( 4 )*/ - { 1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128 }, - { 94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128 }, - { 22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128 } }, - { /* Coeff Band ( 5 )*/ - { 1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128 }, - { 124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128 }, - { 35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128 } }, - { /* Coeff Band ( 6 )*/ - { 1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128 }, - { 121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128 }, - { 45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128 } }, - { /* Coeff Band ( 7 )*/ - { 1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128 }, - { 203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128 }, - { 137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128 } } }, - { /* Block Type ( 2 ) */ - { /* Coeff Band ( 0 )*/ - { 253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128 }, - { 175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128 }, - { 73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128 } }, - { /* Coeff Band ( 1 )*/ - { 1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128 }, - { 239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128 }, - { 155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128 } }, - { /* Coeff Band ( 2 )*/ - { 1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128 }, - { 201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128 }, - { 69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128 } }, - { /* Coeff Band ( 3 )*/ - { 1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128 }, - { 223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128 }, - { 141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128 } }, - { /* Coeff Band ( 4 )*/ - { 1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128 }, - { 190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128 }, - { 149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 } }, - { /* Coeff Band ( 5 )*/ - { 1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, - { 247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, - { 240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128 } }, - { /* Coeff Band ( 6 )*/ - { 1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128 }, - { 213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128 }, - { 55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128 } }, - { /* Coeff Band ( 7 )*/ - { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }, - { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }, - { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 } } }, - { /* Block Type ( 3 ) */ - { /* Coeff Band ( 0 )*/ - { 202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255 }, - { 126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128 }, - { 61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128 } }, - { /* Coeff Band ( 1 )*/ - { 1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128 }, - { 166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128 }, - { 39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128 } }, - { /* Coeff Band ( 2 )*/ - { 1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128 }, - { 124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128 }, - { 24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128 } }, - { /* Coeff Band ( 3 )*/ - { 1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128 }, - { 149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128 }, - { 28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128 } }, - { /* Coeff Band ( 4 )*/ - { 1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128 }, - { 123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128 }, - { 20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128 } }, - { /* Coeff Band ( 5 )*/ - { 1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128 }, - { 168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128 }, - { 47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128 } }, - { /* Coeff Band ( 6 )*/ - { 1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128 }, - { 141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128 }, - { 42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128 } }, - { /* Coeff Band ( 7 )*/ - { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, - { 244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }, - { 238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128 } } } - }; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_DEFAULT_COEF_PROBS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/dequantize.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/dequantize.c deleted file mode 100644 index 8a56ae68..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/dequantize.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "vp8_rtcd.h" -#include "vp8/common/blockd.h" -#include "vpx_mem/vpx_mem.h" - -void vp8_dequantize_b_c(BLOCKD *d, short *DQC) { - int i; - short *DQ = d->dqcoeff; - short *Q = d->qcoeff; - - for (i = 0; i < 16; ++i) { - DQ[i] = Q[i] * DQC[i]; - } -} - -void vp8_dequant_idct_add_c(short *input, short *dq, unsigned char *dest, - int stride) { - int i; - - for (i = 0; i < 16; ++i) { - input[i] = dq[i] * input[i]; - } - - vp8_short_idct4x4llm_c(input, dest, stride, dest, stride); - - memset(input, 0, 32); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropy.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropy.c deleted file mode 100644 index b9efc0cc..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropy.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "entropy.h" -#include "blockd.h" -#include "onyxc_int.h" -#include "vpx_mem/vpx_mem.h" - -#include "coefupdateprobs.h" - -DECLARE_ALIGNED(16, const unsigned char, vp8_norm[256]) = { - 0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -DECLARE_ALIGNED(16, const unsigned char, - vp8_coef_bands[16]) = { 0, 1, 2, 3, 6, 4, 5, 6, - 6, 6, 6, 6, 6, 6, 6, 7 }; - -DECLARE_ALIGNED(16, const unsigned char, - vp8_prev_token_class[MAX_ENTROPY_TOKENS]) = { - 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0 -}; - -DECLARE_ALIGNED(16, const int, vp8_default_zig_zag1d[16]) = { - 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15, -}; - -DECLARE_ALIGNED(16, const short, - vp8_default_inv_zig_zag[16]) = { 1, 2, 6, 7, 3, 5, 8, 13, - 4, 9, 12, 14, 10, 11, 15, 16 }; - -/* vp8_default_zig_zag_mask generated with: - - void vp8_init_scan_order_mask() - { - int i; - - for (i = 0; i < 16; ++i) - { - vp8_default_zig_zag_mask[vp8_default_zig_zag1d[i]] = 1 << i; - } - - } -*/ -DECLARE_ALIGNED(16, const short, vp8_default_zig_zag_mask[16]) = { - 1, 2, 32, 64, 4, 16, 128, 4096, 8, 256, 2048, 8192, 512, 1024, 16384, -32768 -}; - -const int vp8_mb_feature_data_bits[MB_LVL_MAX] = { 7, 6 }; - -/* Array indices are identical to previously-existing CONTEXT_NODE indices */ -/* corresponding _CONTEXT_NODEs */ -/* clang-format off */ -const vp8_tree_index vp8_coef_tree[22] = { - -DCT_EOB_TOKEN, 2, /* 0 = EOB */ - -ZERO_TOKEN, 4, /* 1 = ZERO */ - -ONE_TOKEN, 6, /* 2 = ONE */ - 8, 12, /* 3 = LOW_VAL */ - -TWO_TOKEN, 10, /* 4 = TWO */ - -THREE_TOKEN, -FOUR_TOKEN, /* 5 = THREE */ - 14, 16, /* 6 = HIGH_LOW */ - -DCT_VAL_CATEGORY1, -DCT_VAL_CATEGORY2, /* 7 = CAT_ONE */ - 18, 20, /* 8 = CAT_THREEFOUR */ - -DCT_VAL_CATEGORY3, -DCT_VAL_CATEGORY4, /* 9 = CAT_THREE */ - -DCT_VAL_CATEGORY5, -DCT_VAL_CATEGORY6 /* 10 = CAT_FIVE */ -}; -/* clang-format on */ - -/* vp8_coef_encodings generated with: - vp8_tokens_from_tree(vp8_coef_encodings, vp8_coef_tree); -*/ -vp8_token vp8_coef_encodings[MAX_ENTROPY_TOKENS] = { - { 2, 2 }, { 6, 3 }, { 28, 5 }, { 58, 6 }, { 59, 6 }, { 60, 6 }, - { 61, 6 }, { 124, 7 }, { 125, 7 }, { 126, 7 }, { 127, 7 }, { 0, 1 } -}; - -/* Trees for extra bits. Probabilities are constant and - do not depend on previously encoded bits */ - -static const vp8_prob Pcat1[] = { 159 }; -static const vp8_prob Pcat2[] = { 165, 145 }; -static const vp8_prob Pcat3[] = { 173, 148, 140 }; -static const vp8_prob Pcat4[] = { 176, 155, 140, 135 }; -static const vp8_prob Pcat5[] = { 180, 157, 141, 134, 130 }; -static const vp8_prob Pcat6[] = { 254, 254, 243, 230, 196, 177, - 153, 140, 133, 130, 129 }; - -/* tree index tables generated with: - - void init_bit_tree(vp8_tree_index *p, int n) { - int i = 0; - - while (++i < n) { - p[0] = p[1] = i << 1; - p += 2; - } - - p[0] = p[1] = 0; - } - - void init_bit_trees(void) { - init_bit_tree(cat1, 1); - init_bit_tree(cat2, 2); - init_bit_tree(cat3, 3); - init_bit_tree(cat4, 4); - init_bit_tree(cat5, 5); - init_bit_tree(cat6, 11); - } -*/ - -static const vp8_tree_index cat1[2] = { 0, 0 }; -static const vp8_tree_index cat2[4] = { 2, 2, 0, 0 }; -static const vp8_tree_index cat3[6] = { 2, 2, 4, 4, 0, 0 }; -static const vp8_tree_index cat4[8] = { 2, 2, 4, 4, 6, 6, 0, 0 }; -static const vp8_tree_index cat5[10] = { 2, 2, 4, 4, 6, 6, 8, 8, 0, 0 }; -static const vp8_tree_index cat6[22] = { 2, 2, 4, 4, 6, 6, 8, 8, - 10, 10, 12, 12, 14, 14, 16, 16, - 18, 18, 20, 20, 0, 0 }; - -const vp8_extra_bit_struct vp8_extra_bits[12] = { - { 0, 0, 0, 0 }, { 0, 0, 0, 1 }, { 0, 0, 0, 2 }, - { 0, 0, 0, 3 }, { 0, 0, 0, 4 }, { cat1, Pcat1, 1, 5 }, - { cat2, Pcat2, 2, 7 }, { cat3, Pcat3, 3, 11 }, { cat4, Pcat4, 4, 19 }, - { cat5, Pcat5, 5, 35 }, { cat6, Pcat6, 11, 67 }, { 0, 0, 0, 0 } -}; - -#include "default_coef_probs.h" - -void vp8_default_coef_probs(VP8_COMMON *pc) { - memcpy(pc->fc.coef_probs, default_coef_probs, sizeof(default_coef_probs)); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropy.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropy.h deleted file mode 100644 index fbdb7bcf..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropy.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_ENTROPY_H_ -#define VPX_VP8_COMMON_ENTROPY_H_ - -#include "treecoder.h" -#include "blockd.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Coefficient token alphabet */ - -#define ZERO_TOKEN 0 /* 0 Extra Bits 0+0 */ -#define ONE_TOKEN 1 /* 1 Extra Bits 0+1 */ -#define TWO_TOKEN 2 /* 2 Extra Bits 0+1 */ -#define THREE_TOKEN 3 /* 3 Extra Bits 0+1 */ -#define FOUR_TOKEN 4 /* 4 Extra Bits 0+1 */ -#define DCT_VAL_CATEGORY1 5 /* 5-6 Extra Bits 1+1 */ -#define DCT_VAL_CATEGORY2 6 /* 7-10 Extra Bits 2+1 */ -#define DCT_VAL_CATEGORY3 7 /* 11-18 Extra Bits 3+1 */ -#define DCT_VAL_CATEGORY4 8 /* 19-34 Extra Bits 4+1 */ -#define DCT_VAL_CATEGORY5 9 /* 35-66 Extra Bits 5+1 */ -#define DCT_VAL_CATEGORY6 10 /* 67+ Extra Bits 11+1 */ -#define DCT_EOB_TOKEN 11 /* EOB Extra Bits 0+0 */ - -#define MAX_ENTROPY_TOKENS 12 -#define ENTROPY_NODES 11 - -extern const vp8_tree_index vp8_coef_tree[]; - -extern const struct vp8_token_struct vp8_coef_encodings[MAX_ENTROPY_TOKENS]; - -typedef struct { - vp8_tree_p tree; - const vp8_prob *prob; - int Len; - int base_val; -} vp8_extra_bit_struct; - -extern const vp8_extra_bit_struct - vp8_extra_bits[12]; /* indexed by token value */ - -#define PROB_UPDATE_BASELINE_COST 7 - -#define MAX_PROB 255 -#define DCT_MAX_VALUE 2048 - -/* Coefficients are predicted via a 3-dimensional probability table. */ - -/* Outside dimension. 0 = Y no DC, 1 = Y2, 2 = UV, 3 = Y with DC */ - -#define BLOCK_TYPES 4 - -/* Middle dimension is a coarsening of the coefficient's - position within the 4x4 DCT. */ - -#define COEF_BANDS 8 -extern DECLARE_ALIGNED(16, const unsigned char, vp8_coef_bands[16]); - -/* Inside dimension is 3-valued measure of nearby complexity, that is, - the extent to which nearby coefficients are nonzero. For the first - coefficient (DC, unless block type is 0), we look at the (already encoded) - blocks above and to the left of the current block. The context index is - then the number (0,1,or 2) of these blocks having nonzero coefficients. - After decoding a coefficient, the measure is roughly the size of the - most recently decoded coefficient (0 for 0, 1 for 1, 2 for >1). - Note that the intuitive meaning of this measure changes as coefficients - are decoded, e.g., prior to the first token, a zero means that my neighbors - are empty while, after the first token, because of the use of end-of-block, - a zero means we just decoded a zero and hence guarantees that a non-zero - coefficient will appear later in this block. However, this shift - in meaning is perfectly OK because our context depends also on the - coefficient band (and since zigzag positions 0, 1, and 2 are in - distinct bands). */ - -/*# define DC_TOKEN_CONTEXTS 3*/ /* 00, 0!0, !0!0 */ -#define PREV_COEF_CONTEXTS 3 - -extern DECLARE_ALIGNED(16, const unsigned char, - vp8_prev_token_class[MAX_ENTROPY_TOKENS]); - -extern const vp8_prob vp8_coef_update_probs[BLOCK_TYPES][COEF_BANDS] - [PREV_COEF_CONTEXTS][ENTROPY_NODES]; - -struct VP8Common; -void vp8_default_coef_probs(struct VP8Common *); - -extern DECLARE_ALIGNED(16, const int, vp8_default_zig_zag1d[16]); -extern DECLARE_ALIGNED(16, const short, vp8_default_inv_zig_zag[16]); -extern DECLARE_ALIGNED(16, const short, vp8_default_zig_zag_mask[16]); -extern const int vp8_mb_feature_data_bits[MB_LVL_MAX]; - -void vp8_coef_tree_initialize(void); -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_ENTROPY_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropymode.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropymode.c deleted file mode 100644 index f61e0c2e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropymode.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#define USE_PREBUILT_TABLES - -#include "entropymode.h" -#include "entropy.h" -#include "vpx_mem/vpx_mem.h" - -#include "vp8_entropymodedata.h" - -int vp8_mv_cont(const int_mv *l, const int_mv *a) { - int lez = (l->as_int == 0); - int aez = (a->as_int == 0); - int lea = (l->as_int == a->as_int); - - if (lea && lez) return SUBMVREF_LEFT_ABOVE_ZED; - - if (lea) return SUBMVREF_LEFT_ABOVE_SAME; - - if (aez) return SUBMVREF_ABOVE_ZED; - - if (lez) return SUBMVREF_LEFT_ZED; - - return SUBMVREF_NORMAL; -} - -static const vp8_prob sub_mv_ref_prob[VP8_SUBMVREFS - 1] = { 180, 162, 25 }; - -const vp8_prob vp8_sub_mv_ref_prob2[SUBMVREF_COUNT][VP8_SUBMVREFS - 1] = { - { 147, 136, 18 }, - { 106, 145, 1 }, - { 179, 121, 1 }, - { 223, 1, 34 }, - { 208, 1, 1 } -}; - -const vp8_mbsplit vp8_mbsplits[VP8_NUMMBSPLITS] = { - { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 }, - { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }, - { 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 2, 2, 3, 3 }, - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } -}; - -const int vp8_mbsplit_count[VP8_NUMMBSPLITS] = { 2, 2, 4, 16 }; - -const vp8_prob vp8_mbsplit_probs[VP8_NUMMBSPLITS - 1] = { 110, 111, 150 }; - -/* Array indices are identical to previously-existing INTRAMODECONTEXTNODES. */ - -const vp8_tree_index vp8_bmode_tree[18] = /* INTRAMODECONTEXTNODE value */ - { - -B_DC_PRED, 2, /* 0 = DC_NODE */ - -B_TM_PRED, 4, /* 1 = TM_NODE */ - -B_VE_PRED, 6, /* 2 = VE_NODE */ - 8, 12, /* 3 = COM_NODE */ - -B_HE_PRED, 10, /* 4 = HE_NODE */ - -B_RD_PRED, -B_VR_PRED, /* 5 = RD_NODE */ - -B_LD_PRED, 14, /* 6 = LD_NODE */ - -B_VL_PRED, 16, /* 7 = VL_NODE */ - -B_HD_PRED, -B_HU_PRED /* 8 = HD_NODE */ - }; - -/* Again, these trees use the same probability indices as their - explicitly-programmed predecessors. */ - -const vp8_tree_index vp8_ymode_tree[8] = { - -DC_PRED, 2, 4, 6, -V_PRED, -H_PRED, -TM_PRED, -B_PRED -}; - -const vp8_tree_index vp8_kf_ymode_tree[8] = { -B_PRED, 2, 4, - 6, -DC_PRED, -V_PRED, - -H_PRED, -TM_PRED }; - -const vp8_tree_index vp8_uv_mode_tree[6] = { -DC_PRED, 2, -V_PRED, - 4, -H_PRED, -TM_PRED }; - -const vp8_tree_index vp8_mbsplit_tree[6] = { -3, 2, -2, 4, -0, -1 }; - -const vp8_tree_index vp8_mv_ref_tree[8] = { -ZEROMV, 2, -NEARESTMV, 4, - -NEARMV, 6, -NEWMV, -SPLITMV }; - -const vp8_tree_index vp8_sub_mv_ref_tree[6] = { -LEFT4X4, 2, -ABOVE4X4, - 4, -ZERO4X4, -NEW4X4 }; - -const vp8_tree_index vp8_small_mvtree[14] = { 2, 8, 4, 6, -0, -1, -2, - -3, 10, 12, -4, -5, -6, -7 }; - -void vp8_init_mbmode_probs(VP8_COMMON *x) { - memcpy(x->fc.ymode_prob, vp8_ymode_prob, sizeof(vp8_ymode_prob)); - memcpy(x->fc.uv_mode_prob, vp8_uv_mode_prob, sizeof(vp8_uv_mode_prob)); - memcpy(x->fc.sub_mv_ref_prob, sub_mv_ref_prob, sizeof(sub_mv_ref_prob)); -} - -void vp8_default_bmode_probs(vp8_prob dest[VP8_BINTRAMODES - 1]) { - memcpy(dest, vp8_bmode_prob, sizeof(vp8_bmode_prob)); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropymode.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropymode.h deleted file mode 100644 index c772cece..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropymode.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_ENTROPYMODE_H_ -#define VPX_VP8_COMMON_ENTROPYMODE_H_ - -#include "onyxc_int.h" -#include "treecoder.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - SUBMVREF_NORMAL, - SUBMVREF_LEFT_ZED, - SUBMVREF_ABOVE_ZED, - SUBMVREF_LEFT_ABOVE_SAME, - SUBMVREF_LEFT_ABOVE_ZED -} sumvfref_t; - -typedef int vp8_mbsplit[16]; - -#define VP8_NUMMBSPLITS 4 - -extern const vp8_mbsplit vp8_mbsplits[VP8_NUMMBSPLITS]; - -extern const int vp8_mbsplit_count[VP8_NUMMBSPLITS]; /* # of subsets */ - -extern const vp8_prob vp8_mbsplit_probs[VP8_NUMMBSPLITS - 1]; - -extern int vp8_mv_cont(const int_mv *l, const int_mv *a); -#define SUBMVREF_COUNT 5 -extern const vp8_prob vp8_sub_mv_ref_prob2[SUBMVREF_COUNT][VP8_SUBMVREFS - 1]; - -extern const unsigned int vp8_kf_default_bmode_counts[VP8_BINTRAMODES] - [VP8_BINTRAMODES] - [VP8_BINTRAMODES]; - -extern const vp8_tree_index vp8_bmode_tree[]; - -extern const vp8_tree_index vp8_ymode_tree[]; -extern const vp8_tree_index vp8_kf_ymode_tree[]; -extern const vp8_tree_index vp8_uv_mode_tree[]; - -extern const vp8_tree_index vp8_mbsplit_tree[]; -extern const vp8_tree_index vp8_mv_ref_tree[]; -extern const vp8_tree_index vp8_sub_mv_ref_tree[]; - -extern const struct vp8_token_struct vp8_bmode_encodings[VP8_BINTRAMODES]; -extern const struct vp8_token_struct vp8_ymode_encodings[VP8_YMODES]; -extern const struct vp8_token_struct vp8_kf_ymode_encodings[VP8_YMODES]; -extern const struct vp8_token_struct vp8_uv_mode_encodings[VP8_UV_MODES]; -extern const struct vp8_token_struct vp8_mbsplit_encodings[VP8_NUMMBSPLITS]; - -/* Inter mode values do not start at zero */ - -extern const struct vp8_token_struct vp8_mv_ref_encoding_array[VP8_MVREFS]; -extern const struct vp8_token_struct - vp8_sub_mv_ref_encoding_array[VP8_SUBMVREFS]; - -extern const vp8_tree_index vp8_small_mvtree[]; - -extern const struct vp8_token_struct vp8_small_mvencodings[8]; - -/* Key frame default mode probs */ -extern const vp8_prob vp8_kf_bmode_prob[VP8_BINTRAMODES][VP8_BINTRAMODES] - [VP8_BINTRAMODES - 1]; -extern const vp8_prob vp8_kf_uv_mode_prob[VP8_UV_MODES - 1]; -extern const vp8_prob vp8_kf_ymode_prob[VP8_YMODES - 1]; - -void vp8_init_mbmode_probs(VP8_COMMON *x); -void vp8_default_bmode_probs(vp8_prob dest[VP8_BINTRAMODES - 1]); -void vp8_kf_default_bmode_probs( - vp8_prob dest[VP8_BINTRAMODES][VP8_BINTRAMODES][VP8_BINTRAMODES - 1]); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_ENTROPYMODE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropymv.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropymv.c deleted file mode 100644 index fb4f0c88..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropymv.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "entropymv.h" - -/* clang-format off */ -const MV_CONTEXT vp8_mv_update_probs[2] = { - { { - 237, - 246, - 253, 253, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 250, 250, 252, 254, 254 - } }, - { { - 231, - 243, - 245, 253, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 251, 251, 254, 254, 254 - } } -}; -/* clang-format on */ - -const MV_CONTEXT vp8_default_mv_context[2] = { - { { - /* row */ - 162, /* is short */ - 128, /* sign */ - 225, 146, 172, 147, 214, 39, 156, /* short tree */ - 128, 129, 132, 75, 145, 178, 206, 239, 254, 254 /* long bits */ - } }, - - { { - /* same for column */ - 164, /* is short */ - 128, /**/ - 204, 170, 119, 235, 140, 230, 228, /**/ - 128, 130, 130, 74, 148, 180, 203, 236, 254, 254 /* long bits */ - - } } -}; diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropymv.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropymv.h deleted file mode 100644 index 40039f5b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/entropymv.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_ENTROPYMV_H_ -#define VPX_VP8_COMMON_ENTROPYMV_H_ - -#include "treecoder.h" - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - mv_max = 1023, /* max absolute value of a MV component */ - MVvals = (2 * mv_max) + 1, /* # possible values "" */ - mvfp_max = 255, /* max absolute value of a full pixel MV component */ - MVfpvals = (2 * mvfp_max) + 1, /* # possible full pixel MV values */ - - mvlong_width = 10, /* Large MVs have 9 bit magnitudes */ - mvnum_short = 8, /* magnitudes 0 through 7 */ - - /* probability offsets for coding each MV component */ - - mvpis_short = 0, /* short (<= 7) vs long (>= 8) */ - MVPsign, /* sign for non-zero */ - MVPshort, /* 8 short values = 7-position tree */ - - MVPbits = MVPshort + mvnum_short - 1, /* mvlong_width long value bits */ - MVPcount = MVPbits + mvlong_width /* (with independent probabilities) */ -}; - -typedef struct mv_context { - vp8_prob prob[MVPcount]; /* often come in row, col pairs */ -} MV_CONTEXT; - -extern const MV_CONTEXT vp8_mv_update_probs[2], vp8_default_mv_context[2]; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_ENTROPYMV_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/extend.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/extend.c deleted file mode 100644 index b52e9fe9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/extend.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "extend.h" -#include "vpx_mem/vpx_mem.h" - -static void copy_and_extend_plane( - unsigned char *s, /* source */ - int sp, /* source pitch */ - unsigned char *d, /* destination */ - int dp, /* destination pitch */ - int h, /* height */ - int w, /* width */ - int et, /* extend top border */ - int el, /* extend left border */ - int eb, /* extend bottom border */ - int er, /* extend right border */ - int interleave_step) { /* step between pixels of the current plane */ - int i, j; - unsigned char *src_ptr1, *src_ptr2; - unsigned char *dest_ptr1, *dest_ptr2; - int linesize; - - if (interleave_step < 1) interleave_step = 1; - - /* copy the left and right most columns out */ - src_ptr1 = s; - src_ptr2 = s + (w - 1) * interleave_step; - dest_ptr1 = d - el; - dest_ptr2 = d + w; - - for (i = 0; i < h; ++i) { - memset(dest_ptr1, src_ptr1[0], el); - if (interleave_step == 1) { - memcpy(dest_ptr1 + el, src_ptr1, w); - } else { - for (j = 0; j < w; j++) { - dest_ptr1[el + j] = src_ptr1[interleave_step * j]; - } - } - memset(dest_ptr2, src_ptr2[0], er); - src_ptr1 += sp; - src_ptr2 += sp; - dest_ptr1 += dp; - dest_ptr2 += dp; - } - - /* Now copy the top and bottom lines into each line of the respective - * borders - */ - src_ptr1 = d - el; - src_ptr2 = d + dp * (h - 1) - el; - dest_ptr1 = d + dp * (-et) - el; - dest_ptr2 = d + dp * (h)-el; - linesize = el + er + w; - - for (i = 0; i < et; ++i) { - memcpy(dest_ptr1, src_ptr1, linesize); - dest_ptr1 += dp; - } - - for (i = 0; i < eb; ++i) { - memcpy(dest_ptr2, src_ptr2, linesize); - dest_ptr2 += dp; - } -} - -void vp8_copy_and_extend_frame(YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst) { - int et = dst->border; - int el = dst->border; - int eb = dst->border + dst->y_height - src->y_height; - int er = dst->border + dst->y_width - src->y_width; - - // detect nv12 colorspace - int chroma_step = src->v_buffer - src->u_buffer == 1 ? 2 : 1; - - copy_and_extend_plane(src->y_buffer, src->y_stride, dst->y_buffer, - dst->y_stride, src->y_height, src->y_width, et, el, eb, - er, 1); - - et = dst->border >> 1; - el = dst->border >> 1; - eb = (dst->border >> 1) + dst->uv_height - src->uv_height; - er = (dst->border >> 1) + dst->uv_width - src->uv_width; - - copy_and_extend_plane(src->u_buffer, src->uv_stride, dst->u_buffer, - dst->uv_stride, src->uv_height, src->uv_width, et, el, - eb, er, chroma_step); - - copy_and_extend_plane(src->v_buffer, src->uv_stride, dst->v_buffer, - dst->uv_stride, src->uv_height, src->uv_width, et, el, - eb, er, chroma_step); -} - -void vp8_copy_and_extend_frame_with_rect(YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst, int srcy, - int srcx, int srch, int srcw) { - int et = dst->border; - int el = dst->border; - int eb = dst->border + dst->y_height - src->y_height; - int er = dst->border + dst->y_width - src->y_width; - int src_y_offset = srcy * src->y_stride + srcx; - int dst_y_offset = srcy * dst->y_stride + srcx; - int src_uv_offset = ((srcy * src->uv_stride) >> 1) + (srcx >> 1); - int dst_uv_offset = ((srcy * dst->uv_stride) >> 1) + (srcx >> 1); - // detect nv12 colorspace - int chroma_step = src->v_buffer - src->u_buffer == 1 ? 2 : 1; - - /* If the side is not touching the bounder then don't extend. */ - if (srcy) et = 0; - if (srcx) el = 0; - if (srcy + srch != src->y_height) eb = 0; - if (srcx + srcw != src->y_width) er = 0; - - copy_and_extend_plane(src->y_buffer + src_y_offset, src->y_stride, - dst->y_buffer + dst_y_offset, dst->y_stride, srch, srcw, - et, el, eb, er, 1); - - et = (et + 1) >> 1; - el = (el + 1) >> 1; - eb = (eb + 1) >> 1; - er = (er + 1) >> 1; - srch = (srch + 1) >> 1; - srcw = (srcw + 1) >> 1; - - copy_and_extend_plane(src->u_buffer + src_uv_offset, src->uv_stride, - dst->u_buffer + dst_uv_offset, dst->uv_stride, srch, - srcw, et, el, eb, er, chroma_step); - - copy_and_extend_plane(src->v_buffer + src_uv_offset, src->uv_stride, - dst->v_buffer + dst_uv_offset, dst->uv_stride, srch, - srcw, et, el, eb, er, chroma_step); -} - -/* note the extension is only for the last row, for intra prediction purpose */ -void vp8_extend_mb_row(YV12_BUFFER_CONFIG *ybf, unsigned char *YPtr, - unsigned char *UPtr, unsigned char *VPtr) { - int i; - - YPtr += ybf->y_stride * 14; - UPtr += ybf->uv_stride * 6; - VPtr += ybf->uv_stride * 6; - - for (i = 0; i < 4; ++i) { - YPtr[i] = YPtr[-1]; - UPtr[i] = UPtr[-1]; - VPtr[i] = VPtr[-1]; - } - - YPtr += ybf->y_stride; - UPtr += ybf->uv_stride; - VPtr += ybf->uv_stride; - - for (i = 0; i < 4; ++i) { - YPtr[i] = YPtr[-1]; - UPtr[i] = UPtr[-1]; - VPtr[i] = VPtr[-1]; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/extend.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/extend.h deleted file mode 100644 index 586a38a4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/extend.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_EXTEND_H_ -#define VPX_VP8_COMMON_EXTEND_H_ - -#include "vpx_scale/yv12config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vp8_extend_mb_row(YV12_BUFFER_CONFIG *ybf, unsigned char *YPtr, - unsigned char *UPtr, unsigned char *VPtr); -void vp8_copy_and_extend_frame(YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst); -void vp8_copy_and_extend_frame_with_rect(YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst, int srcy, - int srcx, int srch, int srcw); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_EXTEND_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/filter.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/filter.c deleted file mode 100644 index 26749833..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/filter.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vp8_rtcd.h" -#include "vp8/common/filter.h" - -DECLARE_ALIGNED(16, const short, vp8_bilinear_filters[8][2]) = { - { 128, 0 }, { 112, 16 }, { 96, 32 }, { 80, 48 }, - { 64, 64 }, { 48, 80 }, { 32, 96 }, { 16, 112 } -}; - -DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters[8][6]) = { - - { 0, 0, 128, 0, 0, - 0 }, /* note that 1/8 pel positions are just as per alpha -0.5 bicubic */ - { 0, -6, 123, 12, -1, 0 }, - { 2, -11, 108, 36, -8, 1 }, /* New 1/4 pel 6 tap filter */ - { 0, -9, 93, 50, -6, 0 }, - { 3, -16, 77, 77, -16, 3 }, /* New 1/2 pel 6 tap filter */ - { 0, -6, 50, 93, -9, 0 }, - { 1, -8, 36, 108, -11, 2 }, /* New 1/4 pel 6 tap filter */ - { 0, -1, 12, 123, -6, 0 }, -}; - -static void filter_block2d_first_pass(unsigned char *src_ptr, int *output_ptr, - unsigned int src_pixels_per_line, - unsigned int pixel_step, - unsigned int output_height, - unsigned int output_width, - const short *vp8_filter) { - unsigned int i, j; - int Temp; - - for (i = 0; i < output_height; ++i) { - for (j = 0; j < output_width; ++j) { - Temp = ((int)src_ptr[-2 * (int)pixel_step] * vp8_filter[0]) + - ((int)src_ptr[-1 * (int)pixel_step] * vp8_filter[1]) + - ((int)src_ptr[0] * vp8_filter[2]) + - ((int)src_ptr[pixel_step] * vp8_filter[3]) + - ((int)src_ptr[2 * pixel_step] * vp8_filter[4]) + - ((int)src_ptr[3 * pixel_step] * vp8_filter[5]) + - (VP8_FILTER_WEIGHT >> 1); /* Rounding */ - - /* Normalize back to 0-255 */ - Temp = Temp >> VP8_FILTER_SHIFT; - - if (Temp < 0) { - Temp = 0; - } else if (Temp > 255) { - Temp = 255; - } - - output_ptr[j] = Temp; - src_ptr++; - } - - /* Next row... */ - src_ptr += src_pixels_per_line - output_width; - output_ptr += output_width; - } -} - -static void filter_block2d_second_pass(int *src_ptr, unsigned char *output_ptr, - int output_pitch, - unsigned int src_pixels_per_line, - unsigned int pixel_step, - unsigned int output_height, - unsigned int output_width, - const short *vp8_filter) { - unsigned int i, j; - int Temp; - - for (i = 0; i < output_height; ++i) { - for (j = 0; j < output_width; ++j) { - /* Apply filter */ - Temp = ((int)src_ptr[-2 * (int)pixel_step] * vp8_filter[0]) + - ((int)src_ptr[-1 * (int)pixel_step] * vp8_filter[1]) + - ((int)src_ptr[0] * vp8_filter[2]) + - ((int)src_ptr[pixel_step] * vp8_filter[3]) + - ((int)src_ptr[2 * pixel_step] * vp8_filter[4]) + - ((int)src_ptr[3 * pixel_step] * vp8_filter[5]) + - (VP8_FILTER_WEIGHT >> 1); /* Rounding */ - - /* Normalize back to 0-255 */ - Temp = Temp >> VP8_FILTER_SHIFT; - - if (Temp < 0) { - Temp = 0; - } else if (Temp > 255) { - Temp = 255; - } - - output_ptr[j] = (unsigned char)Temp; - src_ptr++; - } - - /* Start next row */ - src_ptr += src_pixels_per_line - output_width; - output_ptr += output_pitch; - } -} - -static void filter_block2d(unsigned char *src_ptr, unsigned char *output_ptr, - unsigned int src_pixels_per_line, int output_pitch, - const short *HFilter, const short *VFilter) { - int FData[9 * 4]; /* Temp data buffer used in filtering */ - - /* First filter 1-D horizontally... */ - filter_block2d_first_pass(src_ptr - (2 * src_pixels_per_line), FData, - src_pixels_per_line, 1, 9, 4, HFilter); - - /* then filter verticaly... */ - filter_block2d_second_pass(FData + 8, output_ptr, output_pitch, 4, 4, 4, 4, - VFilter); -} - -void vp8_sixtap_predict4x4_c(unsigned char *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - const short *HFilter; - const short *VFilter; - - HFilter = vp8_sub_pel_filters[xoffset]; /* 6 tap */ - VFilter = vp8_sub_pel_filters[yoffset]; /* 6 tap */ - - filter_block2d(src_ptr, dst_ptr, src_pixels_per_line, dst_pitch, HFilter, - VFilter); -} -void vp8_sixtap_predict8x8_c(unsigned char *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - const short *HFilter; - const short *VFilter; - int FData[13 * 16]; /* Temp data buffer used in filtering */ - - HFilter = vp8_sub_pel_filters[xoffset]; /* 6 tap */ - VFilter = vp8_sub_pel_filters[yoffset]; /* 6 tap */ - - /* First filter 1-D horizontally... */ - filter_block2d_first_pass(src_ptr - (2 * src_pixels_per_line), FData, - src_pixels_per_line, 1, 13, 8, HFilter); - - /* then filter verticaly... */ - filter_block2d_second_pass(FData + 16, dst_ptr, dst_pitch, 8, 8, 8, 8, - VFilter); -} - -void vp8_sixtap_predict8x4_c(unsigned char *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - const short *HFilter; - const short *VFilter; - int FData[13 * 16]; /* Temp data buffer used in filtering */ - - HFilter = vp8_sub_pel_filters[xoffset]; /* 6 tap */ - VFilter = vp8_sub_pel_filters[yoffset]; /* 6 tap */ - - /* First filter 1-D horizontally... */ - filter_block2d_first_pass(src_ptr - (2 * src_pixels_per_line), FData, - src_pixels_per_line, 1, 9, 8, HFilter); - - /* then filter verticaly... */ - filter_block2d_second_pass(FData + 16, dst_ptr, dst_pitch, 8, 8, 4, 8, - VFilter); -} - -void vp8_sixtap_predict16x16_c(unsigned char *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - const short *HFilter; - const short *VFilter; - int FData[21 * 24]; /* Temp data buffer used in filtering */ - - HFilter = vp8_sub_pel_filters[xoffset]; /* 6 tap */ - VFilter = vp8_sub_pel_filters[yoffset]; /* 6 tap */ - - /* First filter 1-D horizontally... */ - filter_block2d_first_pass(src_ptr - (2 * src_pixels_per_line), FData, - src_pixels_per_line, 1, 21, 16, HFilter); - - /* then filter verticaly... */ - filter_block2d_second_pass(FData + 32, dst_ptr, dst_pitch, 16, 16, 16, 16, - VFilter); -} - -/**************************************************************************** - * - * ROUTINE : filter_block2d_bil_first_pass - * - * INPUTS : UINT8 *src_ptr : Pointer to source block. - * UINT32 src_stride : Stride of source block. - * UINT32 height : Block height. - * UINT32 width : Block width. - * INT32 *vp8_filter : Array of 2 bi-linear filter taps. - * - * OUTPUTS : INT32 *dst_ptr : Pointer to filtered block. - * - * RETURNS : void - * - * FUNCTION : Applies a 1-D 2-tap bi-linear filter to the source block - * in the horizontal direction to produce the filtered output - * block. Used to implement first-pass of 2-D separable filter. - * - * SPECIAL NOTES : Produces INT32 output to retain precision for next pass. - * Two filter taps should sum to VP8_FILTER_WEIGHT. - * - ****************************************************************************/ -static void filter_block2d_bil_first_pass( - unsigned char *src_ptr, unsigned short *dst_ptr, unsigned int src_stride, - unsigned int height, unsigned int width, const short *vp8_filter) { - unsigned int i, j; - - for (i = 0; i < height; ++i) { - for (j = 0; j < width; ++j) { - /* Apply bilinear filter */ - dst_ptr[j] = - (((int)src_ptr[0] * vp8_filter[0]) + - ((int)src_ptr[1] * vp8_filter[1]) + (VP8_FILTER_WEIGHT / 2)) >> - VP8_FILTER_SHIFT; - src_ptr++; - } - - /* Next row... */ - src_ptr += src_stride - width; - dst_ptr += width; - } -} - -/**************************************************************************** - * - * ROUTINE : filter_block2d_bil_second_pass - * - * INPUTS : INT32 *src_ptr : Pointer to source block. - * UINT32 dst_pitch : Destination block pitch. - * UINT32 height : Block height. - * UINT32 width : Block width. - * INT32 *vp8_filter : Array of 2 bi-linear filter taps. - * - * OUTPUTS : UINT16 *dst_ptr : Pointer to filtered block. - * - * RETURNS : void - * - * FUNCTION : Applies a 1-D 2-tap bi-linear filter to the source block - * in the vertical direction to produce the filtered output - * block. Used to implement second-pass of 2-D separable - * filter. - * - * SPECIAL NOTES : Requires 32-bit input as produced by - * filter_block2d_bil_first_pass. - * Two filter taps should sum to VP8_FILTER_WEIGHT. - * - ****************************************************************************/ -static void filter_block2d_bil_second_pass(unsigned short *src_ptr, - unsigned char *dst_ptr, - int dst_pitch, unsigned int height, - unsigned int width, - const short *vp8_filter) { - unsigned int i, j; - int Temp; - - for (i = 0; i < height; ++i) { - for (j = 0; j < width; ++j) { - /* Apply filter */ - Temp = ((int)src_ptr[0] * vp8_filter[0]) + - ((int)src_ptr[width] * vp8_filter[1]) + (VP8_FILTER_WEIGHT / 2); - dst_ptr[j] = (unsigned int)(Temp >> VP8_FILTER_SHIFT); - src_ptr++; - } - - /* Next row... */ - dst_ptr += dst_pitch; - } -} - -/**************************************************************************** - * - * ROUTINE : filter_block2d_bil - * - * INPUTS : UINT8 *src_ptr : Pointer to source block. - * UINT32 src_pitch : Stride of source block. - * UINT32 dst_pitch : Stride of destination block. - * INT32 *HFilter : Array of 2 horizontal filter - * taps. - * INT32 *VFilter : Array of 2 vertical filter taps. - * INT32 Width : Block width - * INT32 Height : Block height - * - * OUTPUTS : UINT16 *dst_ptr : Pointer to filtered block. - * - * RETURNS : void - * - * FUNCTION : 2-D filters an input block by applying a 2-tap - * bi-linear filter horizontally followed by a 2-tap - * bi-linear filter vertically on the result. - * - * SPECIAL NOTES : The largest block size can be handled here is 16x16 - * - ****************************************************************************/ -static void filter_block2d_bil(unsigned char *src_ptr, unsigned char *dst_ptr, - unsigned int src_pitch, unsigned int dst_pitch, - const short *HFilter, const short *VFilter, - int Width, int Height) { - unsigned short FData[17 * 16]; /* Temp data buffer used in filtering */ - - /* First filter 1-D horizontally... */ - filter_block2d_bil_first_pass(src_ptr, FData, src_pitch, Height + 1, Width, - HFilter); - - /* then 1-D vertically... */ - filter_block2d_bil_second_pass(FData, dst_ptr, dst_pitch, Height, Width, - VFilter); -} - -void vp8_bilinear_predict4x4_c(unsigned char *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - const short *HFilter; - const short *VFilter; - - // This represents a copy and is not required to be handled by optimizations. - assert((xoffset | yoffset) != 0); - - HFilter = vp8_bilinear_filters[xoffset]; - VFilter = vp8_bilinear_filters[yoffset]; - filter_block2d_bil(src_ptr, dst_ptr, src_pixels_per_line, dst_pitch, HFilter, - VFilter, 4, 4); -} - -void vp8_bilinear_predict8x8_c(unsigned char *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - const short *HFilter; - const short *VFilter; - - assert((xoffset | yoffset) != 0); - - HFilter = vp8_bilinear_filters[xoffset]; - VFilter = vp8_bilinear_filters[yoffset]; - - filter_block2d_bil(src_ptr, dst_ptr, src_pixels_per_line, dst_pitch, HFilter, - VFilter, 8, 8); -} - -void vp8_bilinear_predict8x4_c(unsigned char *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - const short *HFilter; - const short *VFilter; - - assert((xoffset | yoffset) != 0); - - HFilter = vp8_bilinear_filters[xoffset]; - VFilter = vp8_bilinear_filters[yoffset]; - - filter_block2d_bil(src_ptr, dst_ptr, src_pixels_per_line, dst_pitch, HFilter, - VFilter, 8, 4); -} - -void vp8_bilinear_predict16x16_c(unsigned char *src_ptr, - int src_pixels_per_line, int xoffset, - int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - const short *HFilter; - const short *VFilter; - - assert((xoffset | yoffset) != 0); - - HFilter = vp8_bilinear_filters[xoffset]; - VFilter = vp8_bilinear_filters[yoffset]; - - filter_block2d_bil(src_ptr, dst_ptr, src_pixels_per_line, dst_pitch, HFilter, - VFilter, 16, 16); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/filter.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/filter.h deleted file mode 100644 index 6acee22b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/filter.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2011 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_FILTER_H_ -#define VPX_VP8_COMMON_FILTER_H_ - -#include "vpx_ports/mem.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define BLOCK_HEIGHT_WIDTH 4 -#define VP8_FILTER_WEIGHT 128 -#define VP8_FILTER_SHIFT 7 - -extern DECLARE_ALIGNED(16, const short, vp8_bilinear_filters[8][2]); -extern DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters[8][6]); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_FILTER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/findnearmv.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/findnearmv.c deleted file mode 100644 index 3b319236..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/findnearmv.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "findnearmv.h" - -const unsigned char vp8_mbsplit_offset[4][16] = { - { 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 2, 8, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } -}; - -/* Predict motion vectors using those from already-decoded nearby blocks. - Note that we only consider one 4x4 subblock from each candidate 16x16 - macroblock. */ -void vp8_find_near_mvs(MACROBLOCKD *xd, const MODE_INFO *here, int_mv *nearest, - int_mv *nearby, int_mv *best_mv, int near_mv_ref_cnts[4], - int refframe, int *ref_frame_sign_bias) { - const MODE_INFO *above = here - xd->mode_info_stride; - const MODE_INFO *left = here - 1; - const MODE_INFO *aboveleft = above - 1; - int_mv near_mvs[4]; - int_mv *mv = near_mvs; - int *cntx = near_mv_ref_cnts; - enum { CNT_INTRA, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV }; - - /* Zero accumulators */ - mv[0].as_int = mv[1].as_int = mv[2].as_int = 0; - near_mv_ref_cnts[0] = near_mv_ref_cnts[1] = near_mv_ref_cnts[2] = - near_mv_ref_cnts[3] = 0; - - /* Process above */ - if (above->mbmi.ref_frame != INTRA_FRAME) { - if (above->mbmi.mv.as_int) { - (++mv)->as_int = above->mbmi.mv.as_int; - mv_bias(ref_frame_sign_bias[above->mbmi.ref_frame], refframe, mv, - ref_frame_sign_bias); - ++cntx; - } - - *cntx += 2; - } - - /* Process left */ - if (left->mbmi.ref_frame != INTRA_FRAME) { - if (left->mbmi.mv.as_int) { - int_mv this_mv; - - this_mv.as_int = left->mbmi.mv.as_int; - mv_bias(ref_frame_sign_bias[left->mbmi.ref_frame], refframe, &this_mv, - ref_frame_sign_bias); - - if (this_mv.as_int != mv->as_int) { - (++mv)->as_int = this_mv.as_int; - ++cntx; - } - - *cntx += 2; - } else { - near_mv_ref_cnts[CNT_INTRA] += 2; - } - } - - /* Process above left */ - if (aboveleft->mbmi.ref_frame != INTRA_FRAME) { - if (aboveleft->mbmi.mv.as_int) { - int_mv this_mv; - - this_mv.as_int = aboveleft->mbmi.mv.as_int; - mv_bias(ref_frame_sign_bias[aboveleft->mbmi.ref_frame], refframe, - &this_mv, ref_frame_sign_bias); - - if (this_mv.as_int != mv->as_int) { - (++mv)->as_int = this_mv.as_int; - ++cntx; - } - - *cntx += 1; - } else { - near_mv_ref_cnts[CNT_INTRA] += 1; - } - } - - /* If we have three distinct MV's ... */ - if (near_mv_ref_cnts[CNT_SPLITMV]) { - /* See if above-left MV can be merged with NEAREST */ - if (mv->as_int == near_mvs[CNT_NEAREST].as_int) - near_mv_ref_cnts[CNT_NEAREST] += 1; - } - - near_mv_ref_cnts[CNT_SPLITMV] = - ((above->mbmi.mode == SPLITMV) + (left->mbmi.mode == SPLITMV)) * 2 + - (aboveleft->mbmi.mode == SPLITMV); - - /* Swap near and nearest if necessary */ - if (near_mv_ref_cnts[CNT_NEAR] > near_mv_ref_cnts[CNT_NEAREST]) { - int tmp; - tmp = near_mv_ref_cnts[CNT_NEAREST]; - near_mv_ref_cnts[CNT_NEAREST] = near_mv_ref_cnts[CNT_NEAR]; - near_mv_ref_cnts[CNT_NEAR] = tmp; - tmp = (int)near_mvs[CNT_NEAREST].as_int; - near_mvs[CNT_NEAREST].as_int = near_mvs[CNT_NEAR].as_int; - near_mvs[CNT_NEAR].as_int = (uint32_t)tmp; - } - - /* Use near_mvs[0] to store the "best" MV */ - if (near_mv_ref_cnts[CNT_NEAREST] >= near_mv_ref_cnts[CNT_INTRA]) { - near_mvs[CNT_INTRA] = near_mvs[CNT_NEAREST]; - } - - /* Set up return values */ - best_mv->as_int = near_mvs[0].as_int; - nearest->as_int = near_mvs[CNT_NEAREST].as_int; - nearby->as_int = near_mvs[CNT_NEAR].as_int; -} - -static void invert_and_clamp_mvs(int_mv *inv, int_mv *src, MACROBLOCKD *xd) { - inv->as_mv.row = src->as_mv.row * -1; - inv->as_mv.col = src->as_mv.col * -1; - vp8_clamp_mv2(inv, xd); - vp8_clamp_mv2(src, xd); -} - -int vp8_find_near_mvs_bias(MACROBLOCKD *xd, const MODE_INFO *here, - int_mv mode_mv_sb[2][MB_MODE_COUNT], - int_mv best_mv_sb[2], int cnt[4], int refframe, - int *ref_frame_sign_bias) { - int sign_bias = ref_frame_sign_bias[refframe]; - - vp8_find_near_mvs(xd, here, &mode_mv_sb[sign_bias][NEARESTMV], - &mode_mv_sb[sign_bias][NEARMV], &best_mv_sb[sign_bias], cnt, - refframe, ref_frame_sign_bias); - - invert_and_clamp_mvs(&mode_mv_sb[!sign_bias][NEARESTMV], - &mode_mv_sb[sign_bias][NEARESTMV], xd); - invert_and_clamp_mvs(&mode_mv_sb[!sign_bias][NEARMV], - &mode_mv_sb[sign_bias][NEARMV], xd); - invert_and_clamp_mvs(&best_mv_sb[!sign_bias], &best_mv_sb[sign_bias], xd); - - return sign_bias; -} - -vp8_prob *vp8_mv_ref_probs(vp8_prob p[VP8_MVREFS - 1], - const int near_mv_ref_ct[4]) { - p[0] = vp8_mode_contexts[near_mv_ref_ct[0]][0]; - p[1] = vp8_mode_contexts[near_mv_ref_ct[1]][1]; - p[2] = vp8_mode_contexts[near_mv_ref_ct[2]][2]; - p[3] = vp8_mode_contexts[near_mv_ref_ct[3]][3]; - /* p[3] = vp8_mode_contexts[near_mv_ref_ct[1] + near_mv_ref_ct[2] + - near_mv_ref_ct[3]][3]; */ - return p; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/findnearmv.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/findnearmv.h deleted file mode 100644 index d7db9544..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/findnearmv.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_FINDNEARMV_H_ -#define VPX_VP8_COMMON_FINDNEARMV_H_ - -#include "./vpx_config.h" -#include "mv.h" -#include "blockd.h" -#include "modecont.h" -#include "treecoder.h" - -#ifdef __cplusplus -extern "C" { -#endif - -static INLINE void mv_bias(int refmb_ref_frame_sign_bias, int refframe, - int_mv *mvp, const int *ref_frame_sign_bias) { - if (refmb_ref_frame_sign_bias != ref_frame_sign_bias[refframe]) { - mvp->as_mv.row *= -1; - mvp->as_mv.col *= -1; - } -} - -#define LEFT_TOP_MARGIN (16 << 3) -#define RIGHT_BOTTOM_MARGIN (16 << 3) -static INLINE void vp8_clamp_mv2(int_mv *mv, const MACROBLOCKD *xd) { - if (mv->as_mv.col < (xd->mb_to_left_edge - LEFT_TOP_MARGIN)) { - mv->as_mv.col = xd->mb_to_left_edge - LEFT_TOP_MARGIN; - } else if (mv->as_mv.col > xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN) { - mv->as_mv.col = xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN; - } - - if (mv->as_mv.row < (xd->mb_to_top_edge - LEFT_TOP_MARGIN)) { - mv->as_mv.row = xd->mb_to_top_edge - LEFT_TOP_MARGIN; - } else if (mv->as_mv.row > xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN) { - mv->as_mv.row = xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN; - } -} - -static INLINE void vp8_clamp_mv(int_mv *mv, int mb_to_left_edge, - int mb_to_right_edge, int mb_to_top_edge, - int mb_to_bottom_edge) { - mv->as_mv.col = - (mv->as_mv.col < mb_to_left_edge) ? mb_to_left_edge : mv->as_mv.col; - mv->as_mv.col = - (mv->as_mv.col > mb_to_right_edge) ? mb_to_right_edge : mv->as_mv.col; - mv->as_mv.row = - (mv->as_mv.row < mb_to_top_edge) ? mb_to_top_edge : mv->as_mv.row; - mv->as_mv.row = - (mv->as_mv.row > mb_to_bottom_edge) ? mb_to_bottom_edge : mv->as_mv.row; -} -static INLINE unsigned int vp8_check_mv_bounds(int_mv *mv, int mb_to_left_edge, - int mb_to_right_edge, - int mb_to_top_edge, - int mb_to_bottom_edge) { - unsigned int need_to_clamp; - need_to_clamp = (mv->as_mv.col < mb_to_left_edge); - need_to_clamp |= (mv->as_mv.col > mb_to_right_edge); - need_to_clamp |= (mv->as_mv.row < mb_to_top_edge); - need_to_clamp |= (mv->as_mv.row > mb_to_bottom_edge); - return need_to_clamp; -} - -void vp8_find_near_mvs(MACROBLOCKD *xd, const MODE_INFO *here, int_mv *nearest, - int_mv *nearby, int_mv *best_mv, int near_mv_ref_cnts[4], - int refframe, int *ref_frame_sign_bias); - -int vp8_find_near_mvs_bias(MACROBLOCKD *xd, const MODE_INFO *here, - int_mv mode_mv_sb[2][MB_MODE_COUNT], - int_mv best_mv_sb[2], int cnt[4], int refframe, - int *ref_frame_sign_bias); - -vp8_prob *vp8_mv_ref_probs(vp8_prob p[VP8_MVREFS - 1], - const int near_mv_ref_ct[4]); - -extern const unsigned char vp8_mbsplit_offset[4][16]; - -static INLINE uint32_t left_block_mv(const MODE_INFO *cur_mb, int b) { - if (!(b & 3)) { - /* On L edge, get from MB to left of us */ - --cur_mb; - - if (cur_mb->mbmi.mode != SPLITMV) return cur_mb->mbmi.mv.as_int; - b += 4; - } - - return (cur_mb->bmi + b - 1)->mv.as_int; -} - -static INLINE uint32_t above_block_mv(const MODE_INFO *cur_mb, int b, - int mi_stride) { - if (!(b >> 2)) { - /* On top edge, get from MB above us */ - cur_mb -= mi_stride; - - if (cur_mb->mbmi.mode != SPLITMV) return cur_mb->mbmi.mv.as_int; - b += 16; - } - - return (cur_mb->bmi + (b - 4))->mv.as_int; -} -static INLINE B_PREDICTION_MODE left_block_mode(const MODE_INFO *cur_mb, - int b) { - if (!(b & 3)) { - /* On L edge, get from MB to left of us */ - --cur_mb; - switch (cur_mb->mbmi.mode) { - case B_PRED: return (cur_mb->bmi + b + 3)->as_mode; - case DC_PRED: return B_DC_PRED; - case V_PRED: return B_VE_PRED; - case H_PRED: return B_HE_PRED; - case TM_PRED: return B_TM_PRED; - default: return B_DC_PRED; - } - } - - return (cur_mb->bmi + b - 1)->as_mode; -} - -static INLINE B_PREDICTION_MODE above_block_mode(const MODE_INFO *cur_mb, int b, - int mi_stride) { - if (!(b >> 2)) { - /* On top edge, get from MB above us */ - cur_mb -= mi_stride; - - switch (cur_mb->mbmi.mode) { - case B_PRED: return (cur_mb->bmi + b + 12)->as_mode; - case DC_PRED: return B_DC_PRED; - case V_PRED: return B_VE_PRED; - case H_PRED: return B_HE_PRED; - case TM_PRED: return B_TM_PRED; - default: return B_DC_PRED; - } - } - - return (cur_mb->bmi + b - 4)->as_mode; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_FINDNEARMV_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/generic/systemdependent.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/generic/systemdependent.c deleted file mode 100644 index 58c778ab..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/generic/systemdependent.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "vp8_rtcd.h" -#if VPX_ARCH_ARM -#include "vpx_ports/arm.h" -#elif VPX_ARCH_X86 || VPX_ARCH_X86_64 -#include "vpx_ports/x86.h" -#elif VPX_ARCH_PPC -#include "vpx_ports/ppc.h" -#elif VPX_ARCH_MIPS -#include "vpx_ports/mips.h" -#elif VPX_ARCH_LOONGARCH -#include "vpx_ports/loongarch.h" -#endif -#include "vp8/common/onyxc_int.h" -#include "vp8/common/systemdependent.h" - -#if CONFIG_MULTITHREAD -#if HAVE_UNISTD_H -#include -#elif defined(_WIN32) -#include -typedef void(WINAPI *PGNSI)(LPSYSTEM_INFO); -#endif -#endif - -#if CONFIG_MULTITHREAD -static int get_cpu_count(void) { - int core_count = 16; - -#if HAVE_UNISTD_H -#if defined(_SC_NPROCESSORS_ONLN) - core_count = (int)sysconf(_SC_NPROCESSORS_ONLN); -#elif defined(_SC_NPROC_ONLN) - core_count = (int)sysconf(_SC_NPROC_ONLN); -#endif -#elif defined(_WIN32) - { -#if _WIN32_WINNT < 0x0501 -#error _WIN32_WINNT must target Windows XP or newer. -#endif - SYSTEM_INFO sysinfo; - GetNativeSystemInfo(&sysinfo); - core_count = (int)sysinfo.dwNumberOfProcessors; - } -#else -/* other platforms */ -#endif - - return core_count > 0 ? core_count : 1; -} -#endif - -void vp8_machine_specific_config(VP8_COMMON *ctx) { -#if CONFIG_MULTITHREAD - ctx->processor_core_count = get_cpu_count(); -#else - (void)ctx; -#endif /* CONFIG_MULTITHREAD */ -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/header.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/header.h deleted file mode 100644 index e64e2419..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/header.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_HEADER_H_ -#define VPX_VP8_COMMON_HEADER_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* 24 bits total */ -typedef struct { - unsigned int type : 1; - unsigned int version : 3; - unsigned int show_frame : 1; - - /* Allow 2^20 bytes = 8 megabits for first partition */ - - unsigned int first_partition_length_in_bytes : 19; - -#ifdef PACKET_TESTING - unsigned int frame_number; - unsigned int update_gold : 1; - unsigned int uses_gold : 1; - unsigned int update_last : 1; - unsigned int uses_last : 1; -#endif - -} VP8_HEADER; - -#ifdef PACKET_TESTING -#define VP8_HEADER_SIZE 8 -#else -#define VP8_HEADER_SIZE 3 -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_HEADER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/idct_blk.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/idct_blk.c deleted file mode 100644 index ebe1774f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/idct_blk.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "vp8_rtcd.h" -#include "vpx_mem/vpx_mem.h" - -void vp8_dequant_idct_add_y_block_c(short *q, short *dq, unsigned char *dst, - int stride, char *eobs) { - int i, j; - - for (i = 0; i < 4; ++i) { - for (j = 0; j < 4; ++j) { - if (*eobs++ > 1) { - vp8_dequant_idct_add_c(q, dq, dst, stride); - } else { - vp8_dc_only_idct_add_c(q[0] * dq[0], dst, stride, dst, stride); - memset(q, 0, 2 * sizeof(q[0])); - } - - q += 16; - dst += 4; - } - - dst += 4 * stride - 16; - } -} - -void vp8_dequant_idct_add_uv_block_c(short *q, short *dq, unsigned char *dst_u, - unsigned char *dst_v, int stride, - char *eobs) { - int i, j; - - for (i = 0; i < 2; ++i) { - for (j = 0; j < 2; ++j) { - if (*eobs++ > 1) { - vp8_dequant_idct_add_c(q, dq, dst_u, stride); - } else { - vp8_dc_only_idct_add_c(q[0] * dq[0], dst_u, stride, dst_u, stride); - memset(q, 0, 2 * sizeof(q[0])); - } - - q += 16; - dst_u += 4; - } - - dst_u += 4 * stride - 8; - } - - for (i = 0; i < 2; ++i) { - for (j = 0; j < 2; ++j) { - if (*eobs++ > 1) { - vp8_dequant_idct_add_c(q, dq, dst_v, stride); - } else { - vp8_dc_only_idct_add_c(q[0] * dq[0], dst_v, stride, dst_v, stride); - memset(q, 0, 2 * sizeof(q[0])); - } - - q += 16; - dst_v += 4; - } - - dst_v += 4 * stride - 8; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/idctllm.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/idctllm.c deleted file mode 100644 index 2f5adc0b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/idctllm.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" - -/**************************************************************************** - * Notes: - * - * This implementation makes use of 16 bit fixed point verio of two multiply - * constants: - * 1. sqrt(2) * cos (pi/8) - * 2. sqrt(2) * sin (pi/8) - * Becuase the first constant is bigger than 1, to maintain the same 16 bit - * fixed point precision as the second one, we use a trick of - * x * a = x + x*(a-1) - * so - * x * sqrt(2) * cos (pi/8) = x + x * (sqrt(2) *cos(pi/8)-1). - **************************************************************************/ -static const int cospi8sqrt2minus1 = 20091; -static const int sinpi8sqrt2 = 35468; - -void vp8_short_idct4x4llm_c(short *input, unsigned char *pred_ptr, - int pred_stride, unsigned char *dst_ptr, - int dst_stride) { - int i; - int r, c; - int a1, b1, c1, d1; - short output[16]; - short *ip = input; - short *op = output; - int temp1, temp2; - int shortpitch = 4; - - for (i = 0; i < 4; ++i) { - a1 = ip[0] + ip[8]; - b1 = ip[0] - ip[8]; - - temp1 = (ip[4] * sinpi8sqrt2) >> 16; - temp2 = ip[12] + ((ip[12] * cospi8sqrt2minus1) >> 16); - c1 = temp1 - temp2; - - temp1 = ip[4] + ((ip[4] * cospi8sqrt2minus1) >> 16); - temp2 = (ip[12] * sinpi8sqrt2) >> 16; - d1 = temp1 + temp2; - - op[shortpitch * 0] = a1 + d1; - op[shortpitch * 3] = a1 - d1; - - op[shortpitch * 1] = b1 + c1; - op[shortpitch * 2] = b1 - c1; - - ip++; - op++; - } - - ip = output; - op = output; - - for (i = 0; i < 4; ++i) { - a1 = ip[0] + ip[2]; - b1 = ip[0] - ip[2]; - - temp1 = (ip[1] * sinpi8sqrt2) >> 16; - temp2 = ip[3] + ((ip[3] * cospi8sqrt2minus1) >> 16); - c1 = temp1 - temp2; - - temp1 = ip[1] + ((ip[1] * cospi8sqrt2minus1) >> 16); - temp2 = (ip[3] * sinpi8sqrt2) >> 16; - d1 = temp1 + temp2; - - op[0] = (a1 + d1 + 4) >> 3; - op[3] = (a1 - d1 + 4) >> 3; - - op[1] = (b1 + c1 + 4) >> 3; - op[2] = (b1 - c1 + 4) >> 3; - - ip += shortpitch; - op += shortpitch; - } - - ip = output; - for (r = 0; r < 4; ++r) { - for (c = 0; c < 4; ++c) { - int a = ip[c] + pred_ptr[c]; - - if (a < 0) a = 0; - - if (a > 255) a = 255; - - dst_ptr[c] = (unsigned char)a; - } - ip += 4; - dst_ptr += dst_stride; - pred_ptr += pred_stride; - } -} - -void vp8_dc_only_idct_add_c(short input_dc, unsigned char *pred_ptr, - int pred_stride, unsigned char *dst_ptr, - int dst_stride) { - int a1 = ((input_dc + 4) >> 3); - int r, c; - - for (r = 0; r < 4; ++r) { - for (c = 0; c < 4; ++c) { - int a = a1 + pred_ptr[c]; - - if (a < 0) a = 0; - - if (a > 255) a = 255; - - dst_ptr[c] = (unsigned char)a; - } - - dst_ptr += dst_stride; - pred_ptr += pred_stride; - } -} - -void vp8_short_inv_walsh4x4_c(short *input, short *mb_dqcoeff) { - short output[16]; - int i; - int a1, b1, c1, d1; - int a2, b2, c2, d2; - short *ip = input; - short *op = output; - - for (i = 0; i < 4; ++i) { - a1 = ip[0] + ip[12]; - b1 = ip[4] + ip[8]; - c1 = ip[4] - ip[8]; - d1 = ip[0] - ip[12]; - - op[0] = a1 + b1; - op[4] = c1 + d1; - op[8] = a1 - b1; - op[12] = d1 - c1; - ip++; - op++; - } - - ip = output; - op = output; - - for (i = 0; i < 4; ++i) { - a1 = ip[0] + ip[3]; - b1 = ip[1] + ip[2]; - c1 = ip[1] - ip[2]; - d1 = ip[0] - ip[3]; - - a2 = a1 + b1; - b2 = c1 + d1; - c2 = a1 - b1; - d2 = d1 - c1; - - op[0] = (a2 + 3) >> 3; - op[1] = (b2 + 3) >> 3; - op[2] = (c2 + 3) >> 3; - op[3] = (d2 + 3) >> 3; - - ip += 4; - op += 4; - } - - for (i = 0; i < 16; ++i) { - mb_dqcoeff[i * 16] = output[i]; - } -} - -void vp8_short_inv_walsh4x4_1_c(short *input, short *mb_dqcoeff) { - int i; - int a1; - - a1 = ((input[0] + 3) >> 3); - for (i = 0; i < 16; ++i) { - mb_dqcoeff[i * 16] = a1; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/invtrans.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/invtrans.h deleted file mode 100644 index aed7bb06..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/invtrans.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_INVTRANS_H_ -#define VPX_VP8_COMMON_INVTRANS_H_ - -#include "./vpx_config.h" -#include "vp8_rtcd.h" -#include "blockd.h" -#include "onyxc_int.h" - -#if CONFIG_MULTITHREAD -#include "vpx_mem/vpx_mem.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -static void eob_adjust(char *eobs, short *diff) { - /* eob adjust.... the idct can only skip if both the dc and eob are zero */ - int js; - for (js = 0; js < 16; ++js) { - if ((eobs[js] == 0) && (diff[0] != 0)) eobs[js]++; - diff += 16; - } -} - -static INLINE void vp8_inverse_transform_mby(MACROBLOCKD *xd) { - short *DQC = xd->dequant_y1; - - if (xd->mode_info_context->mbmi.mode != SPLITMV) { - /* do 2nd order transform on the dc block */ - if (xd->eobs[24] > 1) { - vp8_short_inv_walsh4x4(&xd->block[24].dqcoeff[0], xd->qcoeff); - } else { - vp8_short_inv_walsh4x4_1(&xd->block[24].dqcoeff[0], xd->qcoeff); - } - eob_adjust(xd->eobs, xd->qcoeff); - - DQC = xd->dequant_y1_dc; - } - vp8_dequant_idct_add_y_block(xd->qcoeff, DQC, xd->dst.y_buffer, - xd->dst.y_stride, xd->eobs); -} -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_INVTRANS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/loongarch/idct_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/loongarch/idct_lsx.c deleted file mode 100644 index eee871ee..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/loongarch/idct_lsx.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vp8/common/blockd.h" -#include "vpx_util/loongson_intrinsics.h" - -static const int32_t cospi8sqrt2minus1 = 20091; -static const int32_t sinpi8sqrt2 = 35468; - -#define TRANSPOSE8X4_SH_SH(in0, in1, in2, in3, out0, out1, out2, out3) \ - do { \ - __m128i tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ - \ - DUP2_ARG2(__lsx_vilvl_h, in1, in0, in3, in2, tmp0_m, tmp1_m); \ - DUP2_ARG2(__lsx_vilvh_h, in1, in0, in3, in2, tmp2_m, tmp3_m); \ - DUP2_ARG2(__lsx_vilvl_w, tmp1_m, tmp0_m, tmp3_m, tmp2_m, out0, out2); \ - DUP2_ARG2(__lsx_vilvh_w, tmp1_m, tmp0_m, tmp3_m, tmp2_m, out1, out3); \ - } while (0) - -#define TRANSPOSE_TWO_4x4_H(in0, in1, in2, in3, out0, out1, out2, out3) \ - do { \ - __m128i s4_m, s5_m, s6_m, s7_m; \ - \ - TRANSPOSE8X4_SH_SH(in0, in1, in2, in3, s4_m, s5_m, s6_m, s7_m); \ - DUP2_ARG2(__lsx_vilvl_d, s6_m, s4_m, s7_m, s5_m, out0, out2); \ - out1 = __lsx_vilvh_d(s6_m, s4_m); \ - out3 = __lsx_vilvh_d(s7_m, s5_m); \ - } while (0) - -#define EXPAND_TO_H_MULTIPLY_SINPI8SQRT2_PCK_TO_W(in0, in1) \ - do { \ - __m128i zero_m = __lsx_vldi(0); \ - __m128i tmp1_m, tmp2_m; \ - __m128i sinpi8_sqrt2_m = __lsx_vreplgr2vr_w(sinpi8sqrt2); \ - \ - tmp1_m = __lsx_vilvl_h(in0, zero_m); \ - tmp2_m = __lsx_vilvh_h(in0, zero_m); \ - tmp1_m = __lsx_vsrai_w(tmp1_m, 16); \ - tmp2_m = __lsx_vsrai_w(tmp2_m, 16); \ - tmp1_m = __lsx_vmul_w(tmp1_m, sinpi8_sqrt2_m); \ - tmp1_m = __lsx_vsrai_w(tmp1_m, 16); \ - tmp2_m = __lsx_vmul_w(tmp2_m, sinpi8_sqrt2_m); \ - tmp2_m = __lsx_vsrai_w(tmp2_m, 16); \ - in1 = __lsx_vpickev_h(tmp2_m, tmp1_m); \ - } while (0) - -#define VP8_IDCT_1D_H(in0, in1, in2, in3, out0, out1, out2, out3) \ - do { \ - __m128i a1_m, b1_m, c1_m, d1_m; \ - __m128i c_tmp1_m, c_tmp2_m; \ - __m128i d_tmp1_m, d_tmp2_m; \ - __m128i const_cospi8sqrt2minus1_m; \ - \ - const_cospi8sqrt2minus1_m = __lsx_vreplgr2vr_h(cospi8sqrt2minus1); \ - a1_m = __lsx_vadd_h(in0, in2); \ - b1_m = __lsx_vsub_h(in0, in2); \ - EXPAND_TO_H_MULTIPLY_SINPI8SQRT2_PCK_TO_W(in1, c_tmp1_m); \ - \ - c_tmp2_m = __lsx_vmuh_h(in3, const_cospi8sqrt2minus1_m); \ - c_tmp2_m = __lsx_vslli_h(c_tmp2_m, 1); \ - c_tmp2_m = __lsx_vsrai_h(c_tmp2_m, 1); \ - c_tmp2_m = __lsx_vadd_h(in3, c_tmp2_m); \ - c1_m = __lsx_vsub_h(c_tmp1_m, c_tmp2_m); \ - \ - d_tmp1_m = __lsx_vmuh_h(in1, const_cospi8sqrt2minus1_m); \ - d_tmp1_m = __lsx_vslli_h(d_tmp1_m, 1); \ - d_tmp1_m = __lsx_vsrai_h(d_tmp1_m, 1); \ - d_tmp1_m = __lsx_vadd_h(in1, d_tmp1_m); \ - EXPAND_TO_H_MULTIPLY_SINPI8SQRT2_PCK_TO_W(in3, d_tmp2_m); \ - d1_m = __lsx_vadd_h(d_tmp1_m, d_tmp2_m); \ - LSX_BUTTERFLY_4_H(a1_m, b1_m, c1_m, d1_m, out0, out1, out2, out3); \ - } while (0) - -#define VP8_IDCT_1D_W(in0, in1, in2, in3, out0, out1, out2, out3) \ - do { \ - __m128i a1_m, b1_m, c1_m, d1_m; \ - __m128i c_tmp1_m, c_tmp2_m, d_tmp1_m, d_tmp2_m; \ - __m128i const_cospi8sqrt2minus1_m, sinpi8_sqrt2_m; \ - \ - const_cospi8sqrt2minus1_m = __lsx_vreplgr2vr_w(cospi8sqrt2minus1); \ - sinpi8_sqrt2_m = __lsx_vreplgr2vr_w(sinpi8sqrt2); \ - a1_m = __lsx_vadd_w(in0, in2); \ - b1_m = __lsx_vsub_w(in0, in2); \ - c_tmp1_m = __lsx_vmul_w(in1, sinpi8_sqrt2_m); \ - c_tmp1_m = __lsx_vsrai_w(c_tmp1_m, 16); \ - c_tmp2_m = __lsx_vmul_w(in3, const_cospi8sqrt2minus1_m); \ - c_tmp2_m = __lsx_vsrai_w(c_tmp2_m, 16); \ - c_tmp2_m = __lsx_vadd_w(in3, c_tmp2_m); \ - c1_m = __lsx_vsub_w(c_tmp1_m, c_tmp2_m); \ - d_tmp1_m = __lsx_vmul_w(in1, const_cospi8sqrt2minus1_m); \ - d_tmp1_m = __lsx_vsrai_w(d_tmp1_m, 16); \ - d_tmp1_m = __lsx_vadd_w(in1, d_tmp1_m); \ - d_tmp2_m = __lsx_vmul_w(in3, sinpi8_sqrt2_m); \ - d_tmp2_m = __lsx_vsrai_w(d_tmp2_m, 16); \ - d1_m = __lsx_vadd_w(d_tmp1_m, d_tmp2_m); \ - LSX_BUTTERFLY_4_W(a1_m, b1_m, c1_m, d1_m, out0, out1, out2, out3); \ - } while (0) - -#define UNPCK_SH_SW(in, out0, out1) \ - do { \ - out0 = __lsx_vsllwil_w_h(in, 0); \ - out1 = __lsx_vexth_w_h(in); \ - } while (0) - -static void idct4x4_addconst_lsx(int16_t in_dc, uint8_t *pred, - int32_t pred_stride, uint8_t *dest, - int32_t dest_stride) { - __m128i vec, res0, res1, res2, res3, dst0, dst1; - __m128i pred0, pred1, pred2, pred3; - __m128i zero = __lsx_vldi(0); - - int32_t pred_stride2 = pred_stride << 1; - int32_t pred_stride3 = pred_stride2 + pred_stride; - - vec = __lsx_vreplgr2vr_h(in_dc); - vec = __lsx_vsrari_h(vec, 3); - pred0 = __lsx_vld(pred, 0); - DUP2_ARG2(__lsx_vldx, pred, pred_stride, pred, pred_stride2, pred1, pred2); - pred3 = __lsx_vldx(pred, pred_stride3); - DUP4_ARG2(__lsx_vilvl_b, zero, pred0, zero, pred1, zero, pred2, zero, pred3, - res0, res1, res2, res3); - DUP4_ARG2(__lsx_vadd_h, res0, vec, res1, vec, res2, vec, res3, vec, res0, - res1, res2, res3); - res0 = __lsx_vclip255_h(res0); - res1 = __lsx_vclip255_h(res1); - res2 = __lsx_vclip255_h(res2); - res3 = __lsx_vclip255_h(res3); - - DUP2_ARG2(__lsx_vpickev_b, res1, res0, res3, res2, dst0, dst1); - dst0 = __lsx_vpickev_w(dst1, dst0); - __lsx_vstelm_w(dst0, dest, 0, 0); - dest += dest_stride; - __lsx_vstelm_w(dst0, dest, 0, 1); - dest += dest_stride; - __lsx_vstelm_w(dst0, dest, 0, 2); - dest += dest_stride; - __lsx_vstelm_w(dst0, dest, 0, 3); -} - -void vp8_dc_only_idct_add_lsx(int16_t input_dc, uint8_t *pred_ptr, - int32_t pred_stride, uint8_t *dst_ptr, - int32_t dst_stride) { - idct4x4_addconst_lsx(input_dc, pred_ptr, pred_stride, dst_ptr, dst_stride); -} - -static void dequant_idct4x4_addblk_2x_lsx(int16_t *input, - int16_t *dequant_input, uint8_t *dest, - int32_t dest_stride) { - __m128i dest0, dest1, dest2, dest3; - __m128i in0, in1, in2, in3, mul0, mul1, mul2, mul3, dequant_in0, dequant_in1; - __m128i hz0, hz1, hz2, hz3, vt0, vt1, vt2, vt3, res0, res1, res2, res3; - __m128i hz0l, hz1l, hz2l, hz3l, hz0r, hz1r, hz2r, hz3r; - __m128i vt0l, vt1l, vt2l, vt3l, vt0r, vt1r, vt2r, vt3r; - __m128i zero = __lsx_vldi(0); - - int32_t dest_stride2 = dest_stride << 1; - int32_t dest_stride3 = dest_stride2 + dest_stride; - - DUP4_ARG2(__lsx_vld, input, 0, input, 16, input, 32, input, 48, in0, in1, in2, - in3); - DUP2_ARG2(__lsx_vld, dequant_input, 0, dequant_input, 16, dequant_in0, - dequant_in1); - - DUP4_ARG2(__lsx_vmul_h, in0, dequant_in0, in1, dequant_in1, in2, dequant_in0, - in3, dequant_in1, mul0, mul1, mul2, mul3); - DUP2_ARG2(__lsx_vpickev_d, mul2, mul0, mul3, mul1, in0, in2); - DUP2_ARG2(__lsx_vpickod_d, mul2, mul0, mul3, mul1, in1, in3); - - VP8_IDCT_1D_H(in0, in1, in2, in3, hz0, hz1, hz2, hz3); - TRANSPOSE_TWO_4x4_H(hz0, hz1, hz2, hz3, hz0, hz1, hz2, hz3); - UNPCK_SH_SW(hz0, hz0r, hz0l); - UNPCK_SH_SW(hz1, hz1r, hz1l); - UNPCK_SH_SW(hz2, hz2r, hz2l); - UNPCK_SH_SW(hz3, hz3r, hz3l); - VP8_IDCT_1D_W(hz0l, hz1l, hz2l, hz3l, vt0l, vt1l, vt2l, vt3l); - DUP4_ARG2(__lsx_vsrari_w, vt0l, 3, vt1l, 3, vt2l, 3, vt3l, 3, vt0l, vt1l, - vt2l, vt3l); - VP8_IDCT_1D_W(hz0r, hz1r, hz2r, hz3r, vt0r, vt1r, vt2r, vt3r); - DUP4_ARG2(__lsx_vsrari_w, vt0r, 3, vt1r, 3, vt2r, 3, vt3r, 3, vt0r, vt1r, - vt2r, vt3r); - DUP4_ARG2(__lsx_vpickev_h, vt0l, vt0r, vt1l, vt1r, vt2l, vt2r, vt3l, vt3r, - vt0, vt1, vt2, vt3); - TRANSPOSE_TWO_4x4_H(vt0, vt1, vt2, vt3, vt0, vt1, vt2, vt3); - dest0 = __lsx_vld(dest, 0); - DUP2_ARG2(__lsx_vldx, dest, dest_stride, dest, dest_stride2, dest1, dest2); - dest3 = __lsx_vldx(dest, dest_stride3); - DUP4_ARG2(__lsx_vilvl_b, zero, dest0, zero, dest1, zero, dest2, zero, dest3, - res0, res1, res2, res3); - DUP4_ARG2(__lsx_vadd_h, res0, vt0, res1, vt1, res2, vt2, res3, vt3, res0, - res1, res2, res3); - - res0 = __lsx_vclip255_h(res0); - res1 = __lsx_vclip255_h(res1); - res2 = __lsx_vclip255_h(res2); - res3 = __lsx_vclip255_h(res3); - DUP2_ARG2(__lsx_vpickev_b, res1, res0, res3, res2, vt0l, vt1l); - - __lsx_vstelm_d(vt0l, dest, 0, 0); - __lsx_vstelm_d(vt0l, dest + dest_stride, 0, 1); - __lsx_vstelm_d(vt1l, dest + dest_stride2, 0, 0); - __lsx_vstelm_d(vt1l, dest + dest_stride3, 0, 1); - - __lsx_vst(zero, input, 0); - __lsx_vst(zero, input, 16); - __lsx_vst(zero, input, 32); - __lsx_vst(zero, input, 48); -} - -static void dequant_idct_addconst_2x_lsx(int16_t *input, int16_t *dequant_input, - uint8_t *dest, int32_t dest_stride) { - __m128i input_dc0, input_dc1, vec, res0, res1, res2, res3; - __m128i dest0, dest1, dest2, dest3; - __m128i zero = __lsx_vldi(0); - int32_t dest_stride2 = dest_stride << 1; - int32_t dest_stride3 = dest_stride2 + dest_stride; - - input_dc0 = __lsx_vreplgr2vr_h(input[0] * dequant_input[0]); - input_dc1 = __lsx_vreplgr2vr_h(input[16] * dequant_input[0]); - DUP2_ARG2(__lsx_vsrari_h, input_dc0, 3, input_dc1, 3, input_dc0, input_dc1); - vec = __lsx_vpickev_d(input_dc1, input_dc0); - input[0] = 0; - input[16] = 0; - dest0 = __lsx_vld(dest, 0); - DUP2_ARG2(__lsx_vldx, dest, dest_stride, dest, dest_stride2, dest1, dest2); - dest3 = __lsx_vldx(dest, dest_stride3); - DUP4_ARG2(__lsx_vilvl_b, zero, dest0, zero, dest1, zero, dest2, zero, dest3, - res0, res1, res2, res3); - DUP4_ARG2(__lsx_vadd_h, res0, vec, res1, vec, res2, vec, res3, vec, res0, - res1, res2, res3); - res0 = __lsx_vclip255_h(res0); - res1 = __lsx_vclip255_h(res1); - res2 = __lsx_vclip255_h(res2); - res3 = __lsx_vclip255_h(res3); - - DUP2_ARG2(__lsx_vpickev_b, res1, res0, res3, res2, res0, res1); - __lsx_vstelm_d(res0, dest, 0, 0); - __lsx_vstelm_d(res0, dest + dest_stride, 0, 1); - __lsx_vstelm_d(res1, dest + dest_stride2, 0, 0); - __lsx_vstelm_d(res1, dest + dest_stride3, 0, 1); -} - -void vp8_dequant_idct_add_y_block_lsx(int16_t *q, int16_t *dq, uint8_t *dst, - int32_t stride, char *eobs) { - int16_t *eobs_h = (int16_t *)eobs; - uint8_t i; - - for (i = 4; i--;) { - if (eobs_h[0]) { - if (eobs_h[0] & 0xfefe) { - dequant_idct4x4_addblk_2x_lsx(q, dq, dst, stride); - } else { - dequant_idct_addconst_2x_lsx(q, dq, dst, stride); - } - } - - q += 32; - - if (eobs_h[1]) { - if (eobs_h[1] & 0xfefe) { - dequant_idct4x4_addblk_2x_lsx(q, dq, dst + 8, stride); - } else { - dequant_idct_addconst_2x_lsx(q, dq, dst + 8, stride); - } - } - - q += 32; - dst += (4 * stride); - eobs_h += 2; - } -} - -void vp8_dequant_idct_add_uv_block_lsx(int16_t *q, int16_t *dq, uint8_t *dst_u, - uint8_t *dst_v, int32_t stride, - char *eobs) { - int16_t *eobs_h = (int16_t *)eobs; - if (eobs_h[0]) { - if (eobs_h[0] & 0xfefe) { - dequant_idct4x4_addblk_2x_lsx(q, dq, dst_u, stride); - } else { - dequant_idct_addconst_2x_lsx(q, dq, dst_u, stride); - } - } - - q += 32; - dst_u += (stride * 4); - - if (eobs_h[1]) { - if (eobs_h[1] & 0xfefe) { - dequant_idct4x4_addblk_2x_lsx(q, dq, dst_u, stride); - } else { - dequant_idct_addconst_2x_lsx(q, dq, dst_u, stride); - } - } - - q += 32; - - if (eobs_h[2]) { - if (eobs_h[2] & 0xfefe) { - dequant_idct4x4_addblk_2x_lsx(q, dq, dst_v, stride); - } else { - dequant_idct_addconst_2x_lsx(q, dq, dst_v, stride); - } - } - q += 32; - dst_v += (stride * 4); - - if (eobs_h[3]) { - if (eobs_h[3] & 0xfefe) { - dequant_idct4x4_addblk_2x_lsx(q, dq, dst_v, stride); - } else { - dequant_idct_addconst_2x_lsx(q, dq, dst_v, stride); - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/loongarch/loopfilter_filters_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/loongarch/loopfilter_filters_lsx.c deleted file mode 100644 index 79c3ea6d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/loongarch/loopfilter_filters_lsx.c +++ /dev/null @@ -1,743 +0,0 @@ -/* - * Copyright (c) 2021 Loongson Technology Corporation Limited - * Contributed by Lu Wang - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vp8/common/loopfilter.h" -#include "vpx_util/loongson_intrinsics.h" - -#define VP8_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev) \ - do { \ - __m128i p1_m, p0_m, q0_m, q1_m, filt, q0_sub_p0, t1, t2; \ - const __m128i cnst4b = __lsx_vldi(4); \ - const __m128i cnst3b = __lsx_vldi(3); \ - \ - p1_m = __lsx_vxori_b(p1, 0x80); \ - p0_m = __lsx_vxori_b(p0, 0x80); \ - q0_m = __lsx_vxori_b(q0, 0x80); \ - q1_m = __lsx_vxori_b(q1, 0x80); \ - \ - filt = __lsx_vssub_b(p1_m, q1_m); \ - filt = __lsx_vand_v(filt, hev); \ - q0_sub_p0 = __lsx_vssub_b(q0_m, p0_m); \ - filt = __lsx_vsadd_b(filt, q0_sub_p0); \ - filt = __lsx_vsadd_b(filt, q0_sub_p0); \ - filt = __lsx_vsadd_b(filt, q0_sub_p0); \ - filt = __lsx_vand_v(filt, mask); \ - t1 = __lsx_vsadd_b(filt, cnst4b); \ - t1 = __lsx_vsra_b(t1, cnst3b); \ - t2 = __lsx_vsadd_b(filt, cnst3b); \ - t2 = __lsx_vsra_b(t2, cnst3b); \ - q0_m = __lsx_vssub_b(q0_m, t1); \ - q0 = __lsx_vxori_b(q0_m, 0x80); \ - p0_m = __lsx_vsadd_b(p0_m, t2); \ - p0 = __lsx_vxori_b(p0_m, 0x80); \ - filt = __lsx_vsrari_b(t1, 1); \ - hev = __lsx_vxori_b(hev, 0xff); \ - filt = __lsx_vand_v(filt, hev); \ - q1_m = __lsx_vssub_b(q1_m, filt); \ - q1 = __lsx_vxori_b(q1_m, 0x80); \ - p1_m = __lsx_vsadd_b(p1_m, filt); \ - p1 = __lsx_vxori_b(p1_m, 0x80); \ - } while (0) - -#define VP8_MBFILTER(p2, p1, p0, q0, q1, q2, mask, hev) \ - do { \ - __m128i p2_m, p1_m, p0_m, q2_m, q1_m, q0_m; \ - __m128i u, filt, t1, t2, filt_sign, q0_sub_p0; \ - __m128i filt_r, filt_l; \ - __m128i temp0, temp1, temp2, temp3; \ - const __m128i cnst4b = __lsx_vldi(4); \ - const __m128i cnst3b = __lsx_vldi(3); \ - const __m128i cnst9h = __lsx_vldi(1033); \ - const __m128i cnst63h = __lsx_vldi(1087); \ - \ - p2_m = __lsx_vxori_b(p2, 0x80); \ - p1_m = __lsx_vxori_b(p1, 0x80); \ - p0_m = __lsx_vxori_b(p0, 0x80); \ - q0_m = __lsx_vxori_b(q0, 0x80); \ - q1_m = __lsx_vxori_b(q1, 0x80); \ - q2_m = __lsx_vxori_b(q2, 0x80); \ - \ - filt = __lsx_vssub_b(p1_m, q1_m); \ - q0_sub_p0 = __lsx_vssub_b(q0_m, p0_m); \ - filt = __lsx_vsadd_b(filt, q0_sub_p0); \ - filt = __lsx_vsadd_b(filt, q0_sub_p0); \ - filt = __lsx_vsadd_b(filt, q0_sub_p0); \ - filt = __lsx_vand_v(filt, mask); \ - \ - t2 = __lsx_vand_v(filt, hev); \ - hev = __lsx_vxori_b(hev, 0xff); \ - filt = __lsx_vand_v(hev, filt); \ - t1 = __lsx_vsadd_b(t2, cnst4b); \ - t1 = __lsx_vsra_b(t1, cnst3b); \ - t2 = __lsx_vsadd_b(t2, cnst3b); \ - t2 = __lsx_vsra_b(t2, cnst3b); \ - q0_m = __lsx_vssub_b(q0_m, t1); \ - p0_m = __lsx_vsadd_b(p0_m, t2); \ - filt_sign = __lsx_vslti_b(filt, 0); \ - filt_r = __lsx_vilvl_b(filt_sign, filt); \ - filt_l = __lsx_vilvh_b(filt_sign, filt); \ - temp0 = __lsx_vmul_h(filt_r, cnst9h); \ - temp1 = __lsx_vadd_h(temp0, cnst63h); \ - temp2 = __lsx_vmul_h(filt_l, cnst9h); \ - temp3 = __lsx_vadd_h(temp2, cnst63h); \ - \ - u = __lsx_vssrani_b_h(temp3, temp1, 7); \ - q2_m = __lsx_vssub_b(q2_m, u); \ - p2_m = __lsx_vsadd_b(p2_m, u); \ - q2 = __lsx_vxori_b(q2_m, 0x80); \ - p2 = __lsx_vxori_b(p2_m, 0x80); \ - \ - temp1 = __lsx_vadd_h(temp1, temp0); \ - temp3 = __lsx_vadd_h(temp3, temp2); \ - \ - u = __lsx_vssrani_b_h(temp3, temp1, 7); \ - q1_m = __lsx_vssub_b(q1_m, u); \ - p1_m = __lsx_vsadd_b(p1_m, u); \ - q1 = __lsx_vxori_b(q1_m, 0x80); \ - p1 = __lsx_vxori_b(p1_m, 0x80); \ - \ - temp1 = __lsx_vadd_h(temp1, temp0); \ - temp3 = __lsx_vadd_h(temp3, temp2); \ - \ - u = __lsx_vssrani_b_h(temp3, temp1, 7); \ - q0_m = __lsx_vssub_b(q0_m, u); \ - p0_m = __lsx_vsadd_b(p0_m, u); \ - q0 = __lsx_vxori_b(q0_m, 0x80); \ - p0 = __lsx_vxori_b(p0_m, 0x80); \ - } while (0) - -#define LPF_MASK_HEV(p3_in, p2_in, p1_in, p0_in, q0_in, q1_in, q2_in, q3_in, \ - limit_in, b_limit_in, thresh_in, hev_out, mask_out, \ - flat_out) \ - do { \ - __m128i p3_asub_p2_m, p2_asub_p1_m, p1_asub_p0_m, q1_asub_q0_m; \ - __m128i p1_asub_q1_m, p0_asub_q0_m, q3_asub_q2_m, q2_asub_q1_m; \ - \ - p3_asub_p2_m = __lsx_vabsd_bu(p3_in, p2_in); \ - p2_asub_p1_m = __lsx_vabsd_bu(p2_in, p1_in); \ - p1_asub_p0_m = __lsx_vabsd_bu(p1_in, p0_in); \ - q1_asub_q0_m = __lsx_vabsd_bu(q1_in, q0_in); \ - q2_asub_q1_m = __lsx_vabsd_bu(q2_in, q1_in); \ - q3_asub_q2_m = __lsx_vabsd_bu(q3_in, q2_in); \ - p0_asub_q0_m = __lsx_vabsd_bu(p0_in, q0_in); \ - p1_asub_q1_m = __lsx_vabsd_bu(p1_in, q1_in); \ - flat_out = __lsx_vmax_bu(p1_asub_p0_m, q1_asub_q0_m); \ - hev_out = __lsx_vslt_bu(thresh_in, flat_out); \ - p0_asub_q0_m = __lsx_vsadd_bu(p0_asub_q0_m, p0_asub_q0_m); \ - p1_asub_q1_m = __lsx_vsrli_b(p1_asub_q1_m, 1); \ - p0_asub_q0_m = __lsx_vsadd_bu(p0_asub_q0_m, p1_asub_q1_m); \ - mask_out = __lsx_vslt_bu(b_limit_in, p0_asub_q0_m); \ - mask_out = __lsx_vmax_bu(flat_out, mask_out); \ - p3_asub_p2_m = __lsx_vmax_bu(p3_asub_p2_m, p2_asub_p1_m); \ - mask_out = __lsx_vmax_bu(p3_asub_p2_m, mask_out); \ - q2_asub_q1_m = __lsx_vmax_bu(q2_asub_q1_m, q3_asub_q2_m); \ - mask_out = __lsx_vmax_bu(q2_asub_q1_m, mask_out); \ - mask_out = __lsx_vslt_bu(limit_in, mask_out); \ - mask_out = __lsx_vxori_b(mask_out, 0xff); \ - } while (0) - -#define VP8_ST6x1_B(in0, in0_idx, in1, in1_idx, pdst, stride) \ - do { \ - __lsx_vstelm_w(in0, pdst, 0, in0_idx); \ - __lsx_vstelm_h(in1, pdst + stride, 0, in1_idx); \ - } while (0) - -static void loop_filter_horizontal_4_dual_lsx(uint8_t *src, int32_t pitch, - const uint8_t *b_limit0_ptr, - const uint8_t *limit0_ptr, - const uint8_t *thresh0_ptr, - const uint8_t *b_limit1_ptr, - const uint8_t *limit1_ptr, - const uint8_t *thresh1_ptr) { - int32_t pitch_x2 = pitch << 1; - int32_t pitch_x3 = pitch_x2 + pitch; - int32_t pitch_x4 = pitch << 2; - - __m128i mask, hev, flat; - __m128i thresh0, b_limit0, limit0, thresh1, b_limit1, limit1; - __m128i p3, p2, p1, p0, q3, q2, q1, q0; - - DUP4_ARG2(__lsx_vldx, src, -pitch_x4, src, -pitch_x3, src, -pitch_x2, src, - -pitch, p3, p2, p1, p0); - q0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, pitch, src, pitch_x2, q1, q2); - q3 = __lsx_vldx(src, pitch_x3); - - thresh0 = __lsx_vldrepl_b(thresh0_ptr, 0); - thresh1 = __lsx_vldrepl_b(thresh1_ptr, 0); - thresh0 = __lsx_vilvl_d(thresh1, thresh0); - - b_limit0 = __lsx_vldrepl_b(b_limit0_ptr, 0); - b_limit1 = __lsx_vldrepl_b(b_limit1_ptr, 0); - b_limit0 = __lsx_vilvl_d(b_limit1, b_limit0); - - limit0 = __lsx_vldrepl_b(limit0_ptr, 0); - limit1 = __lsx_vldrepl_b(limit1_ptr, 0); - limit0 = __lsx_vilvl_d(limit1, limit0); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit0, b_limit0, thresh0, hev, - mask, flat); - VP8_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev); - - __lsx_vstx(p1, src, -pitch_x2); - __lsx_vstx(p0, src, -pitch); - __lsx_vst(q0, src, 0); - __lsx_vstx(q1, src, pitch); -} - -static void loop_filter_vertical_4_dual_lsx(uint8_t *src, int32_t pitch, - const uint8_t *b_limit0_ptr, - const uint8_t *limit0_ptr, - const uint8_t *thresh0_ptr, - const uint8_t *b_limit1_ptr, - const uint8_t *limit1_ptr, - const uint8_t *thresh1_ptr) { - uint8_t *src_tmp0 = src - 4; - int32_t pitch_x2 = pitch << 1; - int32_t pitch_x3 = pitch_x2 + pitch; - int32_t pitch_x4 = pitch << 2; - __m128i mask, hev, flat; - __m128i thresh0, b_limit0, limit0, thresh1, b_limit1, limit1; - __m128i p3, p2, p1, p0, q3, q2, q1, q0; - __m128i row0, row1, row2, row3, row4, row5, row6, row7; - __m128i row8, row9, row10, row11, row12, row13, row14, row15; - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; - - row0 = __lsx_vld(src_tmp0, 0); - DUP2_ARG2(__lsx_vldx, src_tmp0, pitch, src_tmp0, pitch_x2, row1, row2); - row3 = __lsx_vldx(src_tmp0, pitch_x3); - src_tmp0 += pitch_x4; - row4 = __lsx_vld(src_tmp0, 0); - DUP2_ARG2(__lsx_vldx, src_tmp0, pitch, src_tmp0, pitch_x2, row5, row6); - row7 = __lsx_vldx(src_tmp0, pitch_x3); - src_tmp0 += pitch_x4; - - row8 = __lsx_vld(src_tmp0, 0); - DUP2_ARG2(__lsx_vldx, src_tmp0, pitch, src_tmp0, pitch_x2, row9, row10); - row11 = __lsx_vldx(src_tmp0, pitch_x3); - src_tmp0 += pitch_x4; - row12 = __lsx_vld(src_tmp0, 0); - DUP2_ARG2(__lsx_vldx, src_tmp0, pitch, src_tmp0, pitch_x2, row13, row14); - row15 = __lsx_vldx(src_tmp0, pitch_x3); - - LSX_TRANSPOSE16x8_B(row0, row1, row2, row3, row4, row5, row6, row7, row8, - row9, row10, row11, row12, row13, row14, row15, p3, p2, - p1, p0, q0, q1, q2, q3); - - thresh0 = __lsx_vldrepl_b(thresh0_ptr, 0); - thresh1 = __lsx_vldrepl_b(thresh1_ptr, 0); - thresh0 = __lsx_vilvl_d(thresh1, thresh0); - - b_limit0 = __lsx_vldrepl_b(b_limit0_ptr, 0); - b_limit1 = __lsx_vldrepl_b(b_limit1_ptr, 0); - b_limit0 = __lsx_vilvl_d(b_limit1, b_limit0); - - limit0 = __lsx_vldrepl_b(limit0_ptr, 0); - limit1 = __lsx_vldrepl_b(limit1_ptr, 0); - limit0 = __lsx_vilvl_d(limit1, limit0); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit0, b_limit0, thresh0, hev, - mask, flat); - VP8_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev); - - DUP2_ARG2(__lsx_vilvl_b, p0, p1, q1, q0, tmp0, tmp1); - tmp2 = __lsx_vilvl_h(tmp1, tmp0); - tmp3 = __lsx_vilvh_h(tmp1, tmp0); - DUP2_ARG2(__lsx_vilvh_b, p0, p1, q1, q0, tmp0, tmp1); - tmp4 = __lsx_vilvl_h(tmp1, tmp0); - tmp5 = __lsx_vilvh_h(tmp1, tmp0); - - src -= 2; - __lsx_vstelm_w(tmp2, src, 0, 0); - src += pitch; - __lsx_vstelm_w(tmp2, src, 0, 1); - src += pitch; - __lsx_vstelm_w(tmp2, src, 0, 2); - src += pitch; - __lsx_vstelm_w(tmp2, src, 0, 3); - src += pitch; - - __lsx_vstelm_w(tmp3, src, 0, 0); - src += pitch; - __lsx_vstelm_w(tmp3, src, 0, 1); - src += pitch; - __lsx_vstelm_w(tmp3, src, 0, 2); - src += pitch; - __lsx_vstelm_w(tmp3, src, 0, 3); - src += pitch; - - __lsx_vstelm_w(tmp4, src, 0, 0); - src += pitch; - __lsx_vstelm_w(tmp4, src, 0, 1); - src += pitch; - __lsx_vstelm_w(tmp4, src, 0, 2); - src += pitch; - __lsx_vstelm_w(tmp4, src, 0, 3); - src += pitch; - - __lsx_vstelm_w(tmp5, src, 0, 0); - src += pitch; - __lsx_vstelm_w(tmp5, src, 0, 1); - src += pitch; - __lsx_vstelm_w(tmp5, src, 0, 2); - src += pitch; - __lsx_vstelm_w(tmp5, src, 0, 3); -} - -static void loop_filter_horizontal_edge_uv_lsx(uint8_t *src_u, uint8_t *src_v, - int32_t pitch, - const uint8_t b_limit_in, - const uint8_t limit_in, - const uint8_t thresh_in) { - int32_t pitch_x2 = pitch << 1; - int32_t pitch_x3 = pitch_x2 + pitch; - int32_t pitch_x4 = pitch << 2; - - __m128i p3, p2, p1, p0, q3, q2, q1, q0; - __m128i mask, hev, flat, thresh, limit, b_limit; - __m128i p3_u, p2_u, p1_u, p0_u, q3_u, q2_u, q1_u, q0_u; - __m128i p3_v, p2_v, p1_v, p0_v, q3_v, q2_v, q1_v, q0_v; - - thresh = __lsx_vreplgr2vr_b(thresh_in); - limit = __lsx_vreplgr2vr_b(limit_in); - b_limit = __lsx_vreplgr2vr_b(b_limit_in); - - DUP4_ARG2(__lsx_vldx, src_u, -pitch_x4, src_u, -pitch_x3, src_u, -pitch_x2, - src_u, -pitch, p3_u, p2_u, p1_u, p0_u); - q0_u = __lsx_vld(src_u, 0); - DUP2_ARG2(__lsx_vldx, src_u, pitch, src_u, pitch_x2, q1_u, q2_u); - q3_u = __lsx_vldx(src_u, pitch_x3); - - DUP4_ARG2(__lsx_vldx, src_v, -pitch_x4, src_v, -pitch_x3, src_v, -pitch_x2, - src_v, -pitch, p3_v, p2_v, p1_v, p0_v); - q0_v = __lsx_vld(src_v, 0); - DUP2_ARG2(__lsx_vldx, src_v, pitch, src_v, pitch_x2, q1_v, q2_v); - q3_v = __lsx_vldx(src_v, pitch_x3); - - /* right 8 element of p3 are u pixel and - left 8 element of p3 are v pixel */ - DUP4_ARG2(__lsx_vilvl_d, p3_v, p3_u, p2_v, p2_u, p1_v, p1_u, p0_v, p0_u, p3, - p2, p1, p0); - DUP4_ARG2(__lsx_vilvl_d, q0_v, q0_u, q1_v, q1_u, q2_v, q2_u, q3_v, q3_u, q0, - q1, q2, q3); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP8_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev); - - __lsx_vstelm_d(q1, src_u + pitch, 0, 0); - __lsx_vstelm_d(q0, src_u, 0, 0); - __lsx_vstelm_d(p0, src_u - pitch, 0, 0); - __lsx_vstelm_d(p1, src_u - pitch_x2, 0, 0); - - __lsx_vstelm_d(q1, src_v + pitch, 0, 1); - __lsx_vstelm_d(q0, src_v, 0, 1); - __lsx_vstelm_d(p0, src_v - pitch, 0, 1); - __lsx_vstelm_d(p1, src_v - pitch_x2, 0, 1); -} - -static void loop_filter_vertical_edge_uv_lsx(uint8_t *src_u, uint8_t *src_v, - int32_t pitch, - const uint8_t b_limit_in, - const uint8_t limit_in, - const uint8_t thresh_in) { - uint8_t *src_u_tmp, *src_v_tmp; - int32_t pitch_x2 = pitch << 1; - int32_t pitch_x3 = pitch_x2 + pitch; - int32_t pitch_x4 = pitch << 2; - - __m128i p3, p2, p1, p0, q3, q2, q1, q0; - __m128i mask, hev, flat, thresh, limit, b_limit; - __m128i row0, row1, row2, row3, row4, row5, row6, row7, row8; - __m128i row9, row10, row11, row12, row13, row14, row15; - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; - - thresh = __lsx_vreplgr2vr_b(thresh_in); - limit = __lsx_vreplgr2vr_b(limit_in); - b_limit = __lsx_vreplgr2vr_b(b_limit_in); - - src_u_tmp = src_u - 4; - row0 = __lsx_vld(src_u_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_u_tmp, pitch, src_u_tmp, pitch_x2, row1, row2); - row3 = __lsx_vldx(src_u_tmp, pitch_x3); - src_u_tmp += pitch_x4; - row4 = __lsx_vld(src_u_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_u_tmp, pitch, src_u_tmp, pitch_x2, row5, row6); - row7 = __lsx_vldx(src_u_tmp, pitch_x3); - - src_v_tmp = src_v - 4; - row8 = __lsx_vld(src_v_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_v_tmp, pitch, src_v_tmp, pitch_x2, row9, row10); - row11 = __lsx_vldx(src_v_tmp, pitch_x3); - src_v_tmp += pitch_x4; - row12 = __lsx_vld(src_v_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_v_tmp, pitch, src_v_tmp, pitch_x2, row13, row14); - row15 = __lsx_vldx(src_v_tmp, pitch_x3); - - LSX_TRANSPOSE16x8_B(row0, row1, row2, row3, row4, row5, row6, row7, row8, - row9, row10, row11, row12, row13, row14, row15, p3, p2, - p1, p0, q0, q1, q2, q3); - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP8_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev); - - DUP2_ARG2(__lsx_vilvl_b, p0, p1, q1, q0, tmp0, tmp1); - tmp2 = __lsx_vilvl_h(tmp1, tmp0); - tmp3 = __lsx_vilvh_h(tmp1, tmp0); - - tmp0 = __lsx_vilvh_b(p0, p1); - tmp1 = __lsx_vilvh_b(q1, q0); - tmp4 = __lsx_vilvl_h(tmp1, tmp0); - tmp5 = __lsx_vilvh_h(tmp1, tmp0); - - src_u_tmp += 2; - __lsx_vstelm_w(tmp2, src_u_tmp - pitch_x4, 0, 0); - __lsx_vstelm_w(tmp2, src_u_tmp - pitch_x3, 0, 1); - __lsx_vstelm_w(tmp2, src_u_tmp - pitch_x2, 0, 2); - __lsx_vstelm_w(tmp2, src_u_tmp - pitch, 0, 3); - - __lsx_vstelm_w(tmp3, src_u_tmp, 0, 0); - __lsx_vstelm_w(tmp3, src_u_tmp + pitch, 0, 1); - __lsx_vstelm_w(tmp3, src_u_tmp + pitch_x2, 0, 2); - __lsx_vstelm_w(tmp3, src_u_tmp + pitch_x3, 0, 3); - - src_v_tmp += 2; - __lsx_vstelm_w(tmp4, src_v_tmp - pitch_x4, 0, 0); - __lsx_vstelm_w(tmp4, src_v_tmp - pitch_x3, 0, 1); - __lsx_vstelm_w(tmp4, src_v_tmp - pitch_x2, 0, 2); - __lsx_vstelm_w(tmp4, src_v_tmp - pitch, 0, 3); - - __lsx_vstelm_w(tmp5, src_v_tmp, 0, 0); - __lsx_vstelm_w(tmp5, src_v_tmp + pitch, 0, 1); - __lsx_vstelm_w(tmp5, src_v_tmp + pitch_x2, 0, 2); - __lsx_vstelm_w(tmp5, src_v_tmp + pitch_x3, 0, 3); -} - -static inline void mbloop_filter_horizontal_edge_y_lsx( - uint8_t *src, int32_t pitch, const uint8_t b_limit_in, - const uint8_t limit_in, const uint8_t thresh_in) { - uint8_t *temp_src; - int32_t pitch_x2 = pitch << 1; - int32_t pitch_x3 = pitch_x2 + pitch; - int32_t pitch_x4 = pitch << 2; - - __m128i p3, p2, p1, p0, q3, q2, q1, q0; - __m128i mask, hev, flat, thresh, limit, b_limit; - - DUP2_ARG2(__lsx_vldrepl_b, &b_limit_in, 0, &limit_in, 0, b_limit, limit); - thresh = __lsx_vldrepl_b(&thresh_in, 0); - - temp_src = src - pitch_x4; - DUP4_ARG2(__lsx_vldx, temp_src, 0, temp_src, pitch, temp_src, pitch_x2, - temp_src, pitch_x3, p3, p2, p1, p0); - temp_src += pitch_x4; - DUP4_ARG2(__lsx_vldx, temp_src, 0, temp_src, pitch, temp_src, pitch_x2, - temp_src, pitch_x3, q0, q1, q2, q3); - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP8_MBFILTER(p2, p1, p0, q0, q1, q2, mask, hev); - - temp_src = src - pitch_x3; - __lsx_vstx(p2, temp_src, 0); - __lsx_vstx(p1, temp_src, pitch); - __lsx_vstx(p0, temp_src, pitch_x2); - __lsx_vstx(q0, temp_src, pitch_x3); - temp_src += pitch_x4; - __lsx_vstx(q1, temp_src, 0); - __lsx_vstx(q2, temp_src, pitch); -} - -static inline void mbloop_filter_horizontal_edge_uv_lsx( - uint8_t *src_u, uint8_t *src_v, int32_t pitch, const uint8_t b_limit_in, - const uint8_t limit_in, const uint8_t thresh_in) { - uint8_t *temp_src; - int32_t pitch_x2 = pitch << 1; - int32_t pitch_x3 = pitch_x2 + pitch; - int32_t pitch_x4 = pitch << 2; - __m128i p3, p2, p1, p0, q3, q2, q1, q0; - __m128i mask, hev, flat, thresh, limit, b_limit; - __m128i p3_u, p2_u, p1_u, p0_u, q3_u, q2_u, q1_u, q0_u; - __m128i p3_v, p2_v, p1_v, p0_v, q3_v, q2_v, q1_v, q0_v; - - DUP2_ARG2(__lsx_vldrepl_b, &b_limit_in, 0, &limit_in, 0, b_limit, limit); - thresh = __lsx_vldrepl_b(&thresh_in, 0); - - temp_src = src_u - pitch_x4; - DUP4_ARG2(__lsx_vldx, temp_src, 0, temp_src, pitch, temp_src, pitch_x2, - temp_src, pitch_x3, p3_u, p2_u, p1_u, p0_u); - temp_src += pitch_x4; - DUP4_ARG2(__lsx_vldx, temp_src, 0, temp_src, pitch, temp_src, pitch_x2, - temp_src, pitch_x3, q0_u, q1_u, q2_u, q3_u); - temp_src = src_v - pitch_x4; - DUP4_ARG2(__lsx_vldx, temp_src, 0, temp_src, pitch, temp_src, pitch_x2, - temp_src, pitch_x3, p3_v, p2_v, p1_v, p0_v); - temp_src += pitch_x4; - DUP4_ARG2(__lsx_vldx, temp_src, 0, temp_src, pitch, temp_src, pitch_x2, - temp_src, pitch_x3, q0_v, q1_v, q2_v, q3_v); - - DUP4_ARG2(__lsx_vilvl_d, p3_v, p3_u, p2_v, p2_u, p1_v, p1_u, p0_v, p0_u, p3, - p2, p1, p0); - DUP4_ARG2(__lsx_vilvl_d, q0_v, q0_u, q1_v, q1_u, q2_v, q2_u, q3_v, q3_u, q0, - q1, q2, q3); - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP8_MBFILTER(p2, p1, p0, q0, q1, q2, mask, hev); - - src_u -= pitch_x3; - __lsx_vstelm_d(p2, src_u, 0, 0); - __lsx_vstelm_d(p1, src_u + pitch, 0, 0); - __lsx_vstelm_d(p0, src_u + pitch_x2, 0, 0); - __lsx_vstelm_d(q0, src_u + pitch_x3, 0, 0); - src_u += pitch_x4; - __lsx_vstelm_d(q1, src_u, 0, 0); - src_u += pitch; - __lsx_vstelm_d(q2, src_u, 0, 0); - - src_v -= pitch_x3; - __lsx_vstelm_d(p2, src_v, 0, 1); - __lsx_vstelm_d(p1, src_v + pitch, 0, 1); - __lsx_vstelm_d(p0, src_v + pitch_x2, 0, 1); - __lsx_vstelm_d(q0, src_v + pitch_x3, 0, 1); - src_v += pitch_x4; - __lsx_vstelm_d(q1, src_v, 0, 1); - src_v += pitch; - __lsx_vstelm_d(q2, src_v, 0, 1); -} - -static inline void mbloop_filter_vertical_edge_y_lsx(uint8_t *src, - int32_t pitch, - const uint8_t b_limit_in, - const uint8_t limit_in, - const uint8_t thresh_in) { - uint8_t *temp_src; - int32_t pitch_x2 = pitch << 1; - int32_t pitch_x3 = pitch_x2 + pitch; - int32_t pitch_x4 = pitch << 2; - - __m128i p3, p2, p1, p0, q3, q2, q1, q0; - __m128i mask, hev, flat, thresh, limit, b_limit; - __m128i row0, row1, row2, row3, row4, row5, row6, row7, row8; - __m128i row9, row10, row11, row12, row13, row14, row15; - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - - DUP2_ARG2(__lsx_vldrepl_b, &b_limit_in, 0, &limit_in, 0, b_limit, limit); - thresh = __lsx_vldrepl_b(&thresh_in, 0); - temp_src = src - 4; - DUP4_ARG2(__lsx_vldx, temp_src, 0, temp_src, pitch, temp_src, pitch_x2, - temp_src, pitch_x3, row0, row1, row2, row3); - temp_src += pitch_x4; - DUP4_ARG2(__lsx_vldx, temp_src, 0, temp_src, pitch, temp_src, pitch_x2, - temp_src, pitch_x3, row4, row5, row6, row7); - temp_src += pitch_x4; - DUP4_ARG2(__lsx_vldx, temp_src, 0, temp_src, pitch, temp_src, pitch_x2, - temp_src, pitch_x3, row8, row9, row10, row11); - temp_src += pitch_x4; - DUP4_ARG2(__lsx_vldx, temp_src, 0, temp_src, pitch, temp_src, pitch_x2, - temp_src, pitch_x3, row12, row13, row14, row15); - temp_src -= pitch_x4; - LSX_TRANSPOSE16x8_B(row0, row1, row2, row3, row4, row5, row6, row7, row8, - row9, row10, row11, row12, row13, row14, row15, p3, p2, - p1, p0, q0, q1, q2, q3); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP8_MBFILTER(p2, p1, p0, q0, q1, q2, mask, hev); - DUP2_ARG2(__lsx_vilvl_b, p1, p2, q0, p0, tmp0, tmp1); - tmp3 = __lsx_vilvl_h(tmp1, tmp0); - tmp4 = __lsx_vilvh_h(tmp1, tmp0); - DUP2_ARG2(__lsx_vilvh_b, p1, p2, q0, p0, tmp0, tmp1); - tmp6 = __lsx_vilvl_h(tmp1, tmp0); - tmp7 = __lsx_vilvh_h(tmp1, tmp0); - tmp2 = __lsx_vilvl_b(q2, q1); - tmp5 = __lsx_vilvh_b(q2, q1); - - temp_src = src - 3; - VP8_ST6x1_B(tmp3, 0, tmp2, 0, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_B(tmp3, 1, tmp2, 1, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_B(tmp3, 2, tmp2, 2, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_B(tmp3, 3, tmp2, 3, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_B(tmp4, 0, tmp2, 4, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_B(tmp4, 1, tmp2, 5, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_B(tmp4, 2, tmp2, 6, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_B(tmp4, 3, tmp2, 7, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_B(tmp6, 0, tmp5, 0, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_B(tmp6, 1, tmp5, 1, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_B(tmp6, 2, tmp5, 2, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_B(tmp6, 3, tmp5, 3, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_B(tmp7, 0, tmp5, 4, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_B(tmp7, 1, tmp5, 5, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_B(tmp7, 2, tmp5, 6, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_B(tmp7, 3, tmp5, 7, temp_src, 4); -} - -static inline void mbloop_filter_vertical_edge_uv_lsx( - uint8_t *src_u, uint8_t *src_v, int32_t pitch, const uint8_t b_limit_in, - const uint8_t limit_in, const uint8_t thresh_in) { - int32_t pitch_x2 = pitch << 1; - int32_t pitch_x3 = pitch_x2 + pitch; - int32_t pitch_x4 = pitch << 2; - __m128i p3, p2, p1, p0, q3, q2, q1, q0; - __m128i mask, hev, flat, thresh, limit, b_limit; - __m128i row0, row1, row2, row3, row4, row5, row6, row7, row8; - __m128i row9, row10, row11, row12, row13, row14, row15; - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - - DUP2_ARG2(__lsx_vldrepl_b, &b_limit_in, 0, &limit_in, 0, b_limit, limit); - thresh = __lsx_vldrepl_b(&thresh_in, 0); - - src_u -= 4; - DUP4_ARG2(__lsx_vldx, src_u, 0, src_u, pitch, src_u, pitch_x2, src_u, - pitch_x3, row0, row1, row2, row3); - src_u += pitch_x4; - DUP4_ARG2(__lsx_vldx, src_u, 0, src_u, pitch, src_u, pitch_x2, src_u, - pitch_x3, row4, row5, row6, row7); - src_v -= 4; - DUP4_ARG2(__lsx_vldx, src_v, 0, src_v, pitch, src_v, pitch_x2, src_v, - pitch_x3, row8, row9, row10, row11); - src_v += pitch_x4; - DUP4_ARG2(__lsx_vldx, src_v, 0, src_v, pitch, src_v, pitch_x2, src_v, - pitch_x3, row12, row13, row14, row15); - LSX_TRANSPOSE16x8_B(row0, row1, row2, row3, row4, row5, row6, row7, row8, - row9, row10, row11, row12, row13, row14, row15, p3, p2, - p1, p0, q0, q1, q2, q3); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP8_MBFILTER(p2, p1, p0, q0, q1, q2, mask, hev); - - DUP2_ARG2(__lsx_vilvl_b, p1, p2, q0, p0, tmp0, tmp1); - tmp3 = __lsx_vilvl_h(tmp1, tmp0); - tmp4 = __lsx_vilvh_h(tmp1, tmp0); - DUP2_ARG2(__lsx_vilvh_b, p1, p2, q0, p0, tmp0, tmp1); - tmp6 = __lsx_vilvl_h(tmp1, tmp0); - tmp7 = __lsx_vilvh_h(tmp1, tmp0); - tmp2 = __lsx_vilvl_b(q2, q1); - tmp5 = __lsx_vilvh_b(q2, q1); - - src_u += 1 - pitch_x4; - VP8_ST6x1_B(tmp3, 0, tmp2, 0, src_u, 4); - src_u += pitch; - VP8_ST6x1_B(tmp3, 1, tmp2, 1, src_u, 4); - src_u += pitch; - VP8_ST6x1_B(tmp3, 2, tmp2, 2, src_u, 4); - src_u += pitch; - VP8_ST6x1_B(tmp3, 3, tmp2, 3, src_u, 4); - src_u += pitch; - VP8_ST6x1_B(tmp4, 0, tmp2, 4, src_u, 4); - src_u += pitch; - VP8_ST6x1_B(tmp4, 1, tmp2, 5, src_u, 4); - src_u += pitch; - VP8_ST6x1_B(tmp4, 2, tmp2, 6, src_u, 4); - src_u += pitch; - VP8_ST6x1_B(tmp4, 3, tmp2, 7, src_u, 4); - - src_v += 1 - pitch_x4; - VP8_ST6x1_B(tmp6, 0, tmp5, 0, src_v, 4); - src_v += pitch; - VP8_ST6x1_B(tmp6, 1, tmp5, 1, src_v, 4); - src_v += pitch; - VP8_ST6x1_B(tmp6, 2, tmp5, 2, src_v, 4); - src_v += pitch; - VP8_ST6x1_B(tmp6, 3, tmp5, 3, src_v, 4); - src_v += pitch; - VP8_ST6x1_B(tmp7, 0, tmp5, 4, src_v, 4); - src_v += pitch; - VP8_ST6x1_B(tmp7, 1, tmp5, 5, src_v, 4); - src_v += pitch; - VP8_ST6x1_B(tmp7, 2, tmp5, 6, src_v, 4); - src_v += pitch; - VP8_ST6x1_B(tmp7, 3, tmp5, 7, src_v, 4); -} - -void vp8_loop_filter_mbh_lsx(uint8_t *src_y, uint8_t *src_u, uint8_t *src_v, - int32_t pitch_y, int32_t pitch_u_v, - loop_filter_info *lpf_info_ptr) { - mbloop_filter_horizontal_edge_y_lsx(src_y, pitch_y, *lpf_info_ptr->mblim, - *lpf_info_ptr->lim, - *lpf_info_ptr->hev_thr); - if (src_u) { - mbloop_filter_horizontal_edge_uv_lsx( - src_u, src_v, pitch_u_v, *lpf_info_ptr->mblim, *lpf_info_ptr->lim, - *lpf_info_ptr->hev_thr); - } -} - -void vp8_loop_filter_mbv_lsx(uint8_t *src_y, uint8_t *src_u, uint8_t *src_v, - int32_t pitch_y, int32_t pitch_u_v, - loop_filter_info *lpf_info_ptr) { - mbloop_filter_vertical_edge_y_lsx(src_y, pitch_y, *lpf_info_ptr->mblim, - *lpf_info_ptr->lim, *lpf_info_ptr->hev_thr); - if (src_u) { - mbloop_filter_vertical_edge_uv_lsx(src_u, src_v, pitch_u_v, - *lpf_info_ptr->mblim, *lpf_info_ptr->lim, - *lpf_info_ptr->hev_thr); - } -} - -void vp8_loop_filter_bh_lsx(uint8_t *src_y, uint8_t *src_u, uint8_t *src_v, - int32_t pitch_y, int32_t pitch_u_v, - loop_filter_info *lpf_info_ptr) { - loop_filter_horizontal_4_dual_lsx(src_y + 4 * pitch_y, pitch_y, - lpf_info_ptr->blim, lpf_info_ptr->lim, - lpf_info_ptr->hev_thr, lpf_info_ptr->blim, - lpf_info_ptr->lim, lpf_info_ptr->hev_thr); - loop_filter_horizontal_4_dual_lsx(src_y + 8 * pitch_y, pitch_y, - lpf_info_ptr->blim, lpf_info_ptr->lim, - lpf_info_ptr->hev_thr, lpf_info_ptr->blim, - lpf_info_ptr->lim, lpf_info_ptr->hev_thr); - loop_filter_horizontal_4_dual_lsx(src_y + 12 * pitch_y, pitch_y, - lpf_info_ptr->blim, lpf_info_ptr->lim, - lpf_info_ptr->hev_thr, lpf_info_ptr->blim, - lpf_info_ptr->lim, lpf_info_ptr->hev_thr); - if (src_u) { - loop_filter_horizontal_edge_uv_lsx( - src_u + (4 * pitch_u_v), src_v + (4 * pitch_u_v), pitch_u_v, - *lpf_info_ptr->blim, *lpf_info_ptr->lim, *lpf_info_ptr->hev_thr); - } -} - -void vp8_loop_filter_bv_lsx(uint8_t *src_y, uint8_t *src_u, uint8_t *src_v, - int32_t pitch_y, int32_t pitch_u_v, - loop_filter_info *lpf_info_ptr) { - loop_filter_vertical_4_dual_lsx(src_y + 4, pitch_y, lpf_info_ptr->blim, - lpf_info_ptr->lim, lpf_info_ptr->hev_thr, - lpf_info_ptr->blim, lpf_info_ptr->lim, - lpf_info_ptr->hev_thr); - loop_filter_vertical_4_dual_lsx(src_y + 8, pitch_y, lpf_info_ptr->blim, - lpf_info_ptr->lim, lpf_info_ptr->hev_thr, - lpf_info_ptr->blim, lpf_info_ptr->lim, - lpf_info_ptr->hev_thr); - loop_filter_vertical_4_dual_lsx(src_y + 12, pitch_y, lpf_info_ptr->blim, - lpf_info_ptr->lim, lpf_info_ptr->hev_thr, - lpf_info_ptr->blim, lpf_info_ptr->lim, - lpf_info_ptr->hev_thr); - if (src_u) { - loop_filter_vertical_edge_uv_lsx(src_u + 4, src_v + 4, pitch_u_v, - *lpf_info_ptr->blim, *lpf_info_ptr->lim, - *lpf_info_ptr->hev_thr); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/loongarch/sixtap_filter_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/loongarch/sixtap_filter_lsx.c deleted file mode 100644 index 98676334..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/loongarch/sixtap_filter_lsx.c +++ /dev/null @@ -1,1904 +0,0 @@ -/* - * Copyright (c) 2021 Loongson Technology Corporation Limited - * Contributed by Lu Wang - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vp8/common/filter.h" -#include "vpx_ports/mem.h" -#include "vpx_util/loongson_intrinsics.h" - -DECLARE_ALIGNED(16, static const int8_t, vp8_subpel_filters_lsx[7][8]) = { - { 0, -6, 123, 12, -1, 0, 0, 0 }, - { 2, -11, 108, 36, -8, 1, 0, 0 }, /* New 1/4 pel 6 tap filter */ - { 0, -9, 93, 50, -6, 0, 0, 0 }, - { 3, -16, 77, 77, -16, 3, 0, 0 }, /* New 1/2 pel 6 tap filter */ - { 0, -6, 50, 93, -9, 0, 0, 0 }, - { 1, -8, 36, 108, -11, 2, 0, 0 }, /* New 1/4 pel 6 tap filter */ - { 0, -1, 12, 123, -6, 0, 0, 0 }, -}; - -static const uint8_t vp8_mc_filt_mask_arr[16 * 3] = { - /* 8 width cases */ - 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, - /* 4 width cases */ - 0, 1, 1, 2, 2, 3, 3, 4, 16, 17, 17, 18, 18, 19, 19, 20, - /* 4 width cases */ - 8, 9, 9, 10, 10, 11, 11, 12, 24, 25, 25, 26, 26, 27, 27, 28 -}; - -static INLINE __m128i dpadd_h3(__m128i in0, __m128i in1, __m128i in2, - __m128i coeff0, __m128i coeff1, __m128i coeff2) { - __m128i out0_m; - - out0_m = __lsx_vdp2_h_b(in0, coeff0); - out0_m = __lsx_vdp2add_h_b(out0_m, in1, coeff1); - out0_m = __lsx_vdp2add_h_b(out0_m, in2, coeff2); - - return out0_m; -} - -static INLINE __m128i horiz_6tap_filt(__m128i src0, __m128i src1, __m128i mask0, - __m128i mask1, __m128i mask2, - __m128i filt_h0, __m128i filt_h1, - __m128i filt_h2) { - __m128i vec0_m, vec1_m, vec2_m; - __m128i hz_out_m; - - DUP2_ARG3(__lsx_vshuf_b, src1, src0, mask0, src1, src0, mask1, vec0_m, - vec1_m); - vec2_m = __lsx_vshuf_b(src1, src0, mask2); - hz_out_m = dpadd_h3(vec0_m, vec1_m, vec2_m, filt_h0, filt_h1, filt_h2); - hz_out_m = __lsx_vsrari_h(hz_out_m, VP8_FILTER_SHIFT); - hz_out_m = __lsx_vsat_h(hz_out_m, 7); - - return hz_out_m; -} - -static INLINE __m128i filt_4tap_dpadd_h(__m128i vec0, __m128i vec1, - __m128i filt0, __m128i filt1) { - __m128i tmp_m; - - tmp_m = __lsx_vdp2_h_b(vec0, filt0); - tmp_m = __lsx_vdp2add_h_b(tmp_m, vec1, filt1); - - return tmp_m; -} - -static INLINE __m128i horiz_4tap_filt(__m128i src0, __m128i src1, __m128i mask0, - __m128i mask1, __m128i filt_h0, - __m128i filt_h1) { - __m128i vec0_m, vec1_m, hz_out_m; - - DUP2_ARG3(__lsx_vshuf_b, src1, src0, mask0, src1, src0, mask1, vec0_m, - vec1_m); - hz_out_m = filt_4tap_dpadd_h(vec0_m, vec1_m, filt_h0, filt_h1); - hz_out_m = __lsx_vsrari_h(hz_out_m, VP8_FILTER_SHIFT); - hz_out_m = __lsx_vsat_h(hz_out_m, 7); - - return hz_out_m; -} - -#define HORIZ_6TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, \ - mask2, filt0, filt1, filt2, out0, out1) \ - do { \ - __m128i vec0_m, vec1_m, vec2_m, vec3_m, vec4_m, vec5_m; \ - \ - DUP2_ARG3(__lsx_vshuf_b, src1, src0, mask0, src3, src2, mask0, vec0_m, \ - vec1_m); \ - DUP2_ARG2(__lsx_vdp2_h_b, vec0_m, filt0, vec1_m, filt0, out0, out1); \ - DUP2_ARG3(__lsx_vshuf_b, src1, src0, mask1, src3, src2, mask1, vec2_m, \ - vec3_m); \ - DUP2_ARG3(__lsx_vdp2add_h_b, out0, vec2_m, filt1, out1, vec3_m, filt1, \ - out0, out1); \ - DUP2_ARG3(__lsx_vshuf_b, src1, src0, mask2, src3, src2, mask2, vec4_m, \ - vec5_m); \ - DUP2_ARG3(__lsx_vdp2add_h_b, out0, vec4_m, filt2, out1, vec5_m, filt2, \ - out0, out1); \ - } while (0) - -#define HORIZ_6TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, \ - mask2, filt0, filt1, filt2, out0, out1, \ - out2, out3) \ - do { \ - __m128i vec0_m, vec1_m, vec2_m, vec3_m, vec4_m, vec5_m, vec6_m, vec7_m; \ - \ - DUP2_ARG3(__lsx_vshuf_b, src0, src0, mask0, src1, src1, mask0, vec0_m, \ - vec1_m); \ - DUP2_ARG3(__lsx_vshuf_b, src2, src2, mask0, src3, src3, mask0, vec2_m, \ - vec3_m); \ - DUP4_ARG2(__lsx_vdp2_h_b, vec0_m, filt0, vec1_m, filt0, vec2_m, filt0, \ - vec3_m, filt0, out0, out1, out2, out3); \ - DUP2_ARG3(__lsx_vshuf_b, src0, src0, mask1, src1, src1, mask1, vec0_m, \ - vec1_m); \ - DUP2_ARG3(__lsx_vshuf_b, src2, src2, mask1, src3, src3, mask1, vec2_m, \ - vec3_m); \ - DUP2_ARG3(__lsx_vshuf_b, src0, src0, mask2, src1, src1, mask2, vec4_m, \ - vec5_m); \ - DUP2_ARG3(__lsx_vshuf_b, src2, src2, mask2, src3, src3, mask2, vec6_m, \ - vec7_m); \ - DUP4_ARG3(__lsx_vdp2add_h_b, out0, vec0_m, filt1, out1, vec1_m, filt1, \ - out2, vec2_m, filt1, out3, vec3_m, filt1, out0, out1, out2, \ - out3); \ - DUP4_ARG3(__lsx_vdp2add_h_b, out0, vec4_m, filt2, out1, vec5_m, filt2, \ - out2, vec6_m, filt2, out3, vec7_m, filt2, out0, out1, out2, \ - out3); \ - } while (0) - -#define HORIZ_4TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, \ - filt0, filt1, out0, out1) \ - do { \ - __m128i vec0_m, vec1_m, vec2_m, vec3_m; \ - \ - DUP2_ARG3(__lsx_vshuf_b, src1, src0, mask0, src3, src2, mask0, vec0_m, \ - vec1_m); \ - DUP2_ARG2(__lsx_vdp2_h_b, vec0_m, filt0, vec1_m, filt0, out0, out1); \ - DUP2_ARG3(__lsx_vshuf_b, src1, src0, mask1, src3, src2, mask1, vec2_m, \ - vec3_m); \ - DUP2_ARG3(__lsx_vdp2add_h_b, out0, vec2_m, filt1, out1, vec3_m, filt1, \ - out0, out1); \ - } while (0) - -#define HORIZ_4TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, \ - filt0, filt1, out0, out1, out2, out3) \ - do { \ - __m128i vec0_m, vec1_m, vec2_m, vec3_m; \ - \ - DUP2_ARG3(__lsx_vshuf_b, src0, src0, mask0, src1, src1, mask0, vec0_m, \ - vec1_m); \ - DUP2_ARG3(__lsx_vshuf_b, src2, src2, mask0, src3, src3, mask0, vec2_m, \ - vec3_m); \ - DUP4_ARG2(__lsx_vdp2_h_b, vec0_m, filt0, vec1_m, filt0, vec2_m, filt0, \ - vec3_m, filt0, out0, out1, out2, out3); \ - DUP2_ARG3(__lsx_vshuf_b, src0, src0, mask1, src1, src1, mask1, vec0_m, \ - vec1_m); \ - DUP2_ARG3(__lsx_vshuf_b, src2, src2, mask1, src3, src3, mask1, vec2_m, \ - vec3_m); \ - DUP4_ARG3(__lsx_vdp2add_h_b, out0, vec0_m, filt1, out1, vec1_m, filt1, \ - out2, vec2_m, filt1, out3, vec3_m, filt1, out0, out1, out2, \ - out3); \ - } while (0) - -static inline void common_hz_6t_4x4_lsx(uint8_t *RESTRICT src, - int32_t src_stride, - uint8_t *RESTRICT dst, - int32_t dst_stride, - const int8_t *filter) { - __m128i src0, src1, src2, src3, filt0, filt1, filt2; - __m128i mask0, mask1, mask2, out0, out1; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - - mask0 = __lsx_vld(vp8_mc_filt_mask_arr, 16); - src -= 2; - - DUP2_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filt0, filt1); - filt2 = __lsx_vldrepl_h(filter, 4); - - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride_x2, src1, src2); - src3 = __lsx_vldx(src, src_stride_x3); - - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_6TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, filt0, - filt1, filt2, out0, out1); - out0 = __lsx_vssrarni_b_h(out1, out0, VP8_FILTER_SHIFT); - out0 = __lsx_vxori_b(out0, 128); - - __lsx_vstelm_w(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 3); -} - -static void common_hz_6t_4x8_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter) { - __m128i src0, src1, src2, src3, filt0, filt1, filt2; - __m128i mask0, mask1, mask2, out0, out1, out2, out3; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride_x2 << 1; - - mask0 = __lsx_vld(vp8_mc_filt_mask_arr, 16); - src -= 2; - - DUP2_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filt0, filt1); - filt2 = __lsx_vldrepl_h(filter, 4); - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride_x2, src1, src2); - src3 = __lsx_vldx(src, src_stride_x3); - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - src += src_stride_x4; - HORIZ_6TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, filt0, - filt1, filt2, out0, out1); - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride_x2, src1, src2); - src3 = __lsx_vldx(src, src_stride_x3); - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_6TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, filt0, - filt1, filt2, out2, out3); - - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, VP8_FILTER_SHIFT, out3, out2, - VP8_FILTER_SHIFT, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - __lsx_vstelm_w(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 3); - dst += dst_stride; - - __lsx_vstelm_w(out1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(out1, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(out1, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(out1, dst, 0, 3); -} - -static void common_hz_6t_4w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - if (height == 4) { - common_hz_6t_4x4_lsx(src, src_stride, dst, dst_stride, filter); - } else if (height == 8) { - common_hz_6t_4x8_lsx(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_hz_6t_8w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride << 2; - int32_t dst_stride_x2 = dst_stride << 1; - int32_t dst_stride_x3 = dst_stride_x2 + dst_stride; - int32_t dst_stride_x4 = dst_stride << 2; - __m128i src0, src1, src2, src3, filt0, filt1, filt2; - __m128i mask0, mask1, mask2, tmp0, tmp1; - __m128i filt, out0, out1, out2, out3; - - mask0 = __lsx_vld(vp8_mc_filt_mask_arr, 0); - src -= 2; - - filt = __lsx_vld(filter, 0); - DUP2_ARG2(__lsx_vreplvei_h, filt, 0, filt, 1, filt0, filt1); - filt2 = __lsx_vreplvei_h(filt, 2); - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src0, src1, src2, src3); - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - src += src_stride_x4; - HORIZ_6TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, filt0, - filt1, filt2, out0, out1, out2, out3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, VP8_FILTER_SHIFT, out3, out2, - VP8_FILTER_SHIFT, tmp0, tmp1); - DUP2_ARG2(__lsx_vxori_b, tmp0, 128, tmp1, 128, tmp0, tmp1); - __lsx_vstelm_d(tmp0, dst, 0, 0); - __lsx_vstelm_d(tmp0, dst + dst_stride, 0, 1); - __lsx_vstelm_d(tmp1, dst + dst_stride_x2, 0, 0); - __lsx_vstelm_d(tmp1, dst + dst_stride_x3, 0, 1); - dst += dst_stride_x4; - - for (loop_cnt = (height >> 2) - 1; loop_cnt--;) { - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src0, src1, src2, src3); - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - src += src_stride_x4; - HORIZ_6TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - filt0, filt1, filt2, out0, out1, out2, out3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, VP8_FILTER_SHIFT, out3, out2, - VP8_FILTER_SHIFT, tmp0, tmp1); - DUP2_ARG2(__lsx_vxori_b, tmp0, 128, tmp1, 128, tmp0, tmp1); - __lsx_vstelm_d(tmp0, dst, 0, 0); - __lsx_vstelm_d(tmp0, dst + dst_stride, 0, 1); - __lsx_vstelm_d(tmp1, dst + dst_stride_x2, 0, 0); - __lsx_vstelm_d(tmp1, dst + dst_stride_x3, 0, 1); - dst += dst_stride_x4; - } -} - -static void common_hz_6t_16w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride << 2; - int32_t dst_stride_x2 = dst_stride << 1; - int32_t dst_stride_x3 = dst_stride_x2 + dst_stride; - int32_t dst_stride_x4 = dst_stride << 2; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, filt0, filt1, filt2; - __m128i mask0, mask1, mask2, out; - __m128i filt, out0, out1, out2, out3, out4, out5, out6, out7; - - mask0 = __lsx_vld(vp8_mc_filt_mask_arr, 0); - src -= 2; - - filt = __lsx_vld(filter, 0); - DUP2_ARG2(__lsx_vreplvei_h, filt, 0, filt, 1, filt0, filt1); - filt2 = __lsx_vreplvei_h(filt, 2); - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src0, src2, src4, src6); - src += 8; - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src1, src3, src5, src7); - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - DUP4_ARG2(__lsx_vxori_b, src4, 128, src5, 128, src6, 128, src7, 128, src4, - src5, src6, src7); - src += src_stride_x4 - 8; - - HORIZ_6TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - filt0, filt1, filt2, out0, out1, out2, out3); - HORIZ_6TAP_8WID_4VECS_FILT(src4, src5, src6, src7, mask0, mask1, mask2, - filt0, filt1, filt2, out4, out5, out6, out7); - DUP4_ARG2(__lsx_vsrari_h, out0, VP8_FILTER_SHIFT, out1, VP8_FILTER_SHIFT, - out2, VP8_FILTER_SHIFT, out3, VP8_FILTER_SHIFT, out0, out1, out2, - out3); - DUP4_ARG2(__lsx_vsrari_h, out4, VP8_FILTER_SHIFT, out5, VP8_FILTER_SHIFT, - out6, VP8_FILTER_SHIFT, out7, VP8_FILTER_SHIFT, out4, out5, out6, - out7); - DUP4_ARG2(__lsx_vsat_h, out0, 7, out1, 7, out2, 7, out3, 7, out0, out1, - out2, out3); - DUP4_ARG2(__lsx_vsat_h, out4, 7, out5, 7, out6, 7, out7, 7, out4, out5, - out6, out7); - out = __lsx_vpickev_b(out1, out0); - out = __lsx_vxori_b(out, 128); - __lsx_vst(out, dst, 0); - out = __lsx_vpickev_b(out3, out2); - out = __lsx_vxori_b(out, 128); - __lsx_vstx(out, dst, dst_stride); - out = __lsx_vpickev_b(out5, out4); - out = __lsx_vxori_b(out, 128); - __lsx_vstx(out, dst, dst_stride_x2); - out = __lsx_vpickev_b(out7, out6); - out = __lsx_vxori_b(out, 128); - __lsx_vstx(out, dst, dst_stride_x3); - dst += dst_stride_x4; - } -} - -static void common_vt_6t_4w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8; - __m128i src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; - __m128i src87_r, src2110, src4332, src6554, src8776, filt0, filt1, filt2; - __m128i out0, out1; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride << 2; - - DUP2_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filt0, filt1); - filt2 = __lsx_vldrepl_h(filter, 4); - - DUP2_ARG2(__lsx_vldx, src, -src_stride_x2, src, -src_stride, src0, src1); - src2 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride_x2, src3, src4); - src += src_stride_x3; - - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, src3, src2, src4, src3, - src10_r, src21_r, src32_r, src43_r); - DUP2_ARG2(__lsx_vilvl_d, src21_r, src10_r, src43_r, src32_r, src2110, - src4332); - DUP2_ARG2(__lsx_vxori_b, src2110, 128, src4332, 128, src2110, src4332); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - src5 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride_x2, src6, src7); - src8 = __lsx_vldx(src, src_stride_x3); - src += src_stride_x4; - - DUP4_ARG2(__lsx_vilvl_b, src5, src4, src6, src5, src7, src6, src8, src7, - src54_r, src65_r, src76_r, src87_r); - DUP2_ARG2(__lsx_vilvl_d, src65_r, src54_r, src87_r, src76_r, src6554, - src8776); - DUP2_ARG2(__lsx_vxori_b, src6554, 128, src8776, 128, src6554, src8776); - out0 = dpadd_h3(src2110, src4332, src6554, filt0, filt1, filt2); - out1 = dpadd_h3(src4332, src6554, src8776, filt0, filt1, filt2); - - out0 = __lsx_vssrarni_b_h(out1, out0, VP8_FILTER_SHIFT); - out0 = __lsx_vxori_b(out0, 128); - - __lsx_vstelm_w(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 3); - dst += dst_stride; - - src2110 = src6554; - src4332 = src8776; - src4 = src8; - } -} - -static void common_vt_6t_8w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride << 2; - int32_t dst_stride_x2 = dst_stride << 1; - int32_t dst_stride_x3 = dst_stride_x2 + dst_stride; - int32_t dst_stride_x4 = dst_stride << 2; - __m128i src0, src1, src2, src3, src4, src7, src8, src9, src10; - __m128i src10_r, src32_r, src76_r, src98_r, src21_r, src43_r, src87_r; - __m128i src109_r, filt0, filt1, filt2; - __m128i tmp0, tmp1; - __m128i filt, out0_r, out1_r, out2_r, out3_r; - - src -= src_stride_x2; - filt = __lsx_vld(filter, 0); - DUP2_ARG2(__lsx_vreplvei_h, filt, 0, filt, 1, filt0, filt1); - filt2 = __lsx_vreplvei_h(filt, 2); - - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src0, src1, src2, src3); - src += src_stride_x4; - src4 = __lsx_vld(src, 0); - src += src_stride; - - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - src4 = __lsx_vxori_b(src4, 128); - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src3, src2, src2, src1, src4, src3, - src10_r, src32_r, src21_r, src43_r); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src7, src8, src9, src10); - DUP4_ARG2(__lsx_vxori_b, src7, 128, src8, 128, src9, 128, src10, 128, src7, - src8, src9, src10); - src += src_stride_x4; - - DUP4_ARG2(__lsx_vilvl_b, src7, src4, src8, src7, src9, src8, src10, src9, - src76_r, src87_r, src98_r, src109_r); - out0_r = dpadd_h3(src10_r, src32_r, src76_r, filt0, filt1, filt2); - out1_r = dpadd_h3(src21_r, src43_r, src87_r, filt0, filt1, filt2); - out2_r = dpadd_h3(src32_r, src76_r, src98_r, filt0, filt1, filt2); - out3_r = dpadd_h3(src43_r, src87_r, src109_r, filt0, filt1, filt2); - DUP2_ARG3(__lsx_vssrarni_b_h, out1_r, out0_r, VP8_FILTER_SHIFT, out3_r, - out2_r, VP8_FILTER_SHIFT, tmp0, tmp1); - DUP2_ARG2(__lsx_vxori_b, tmp0, 128, tmp1, 128, tmp0, tmp1); - __lsx_vstelm_d(tmp0, dst, 0, 0); - __lsx_vstelm_d(tmp0, dst + dst_stride, 0, 1); - __lsx_vstelm_d(tmp1, dst + dst_stride_x2, 0, 0); - __lsx_vstelm_d(tmp1, dst + dst_stride_x3, 0, 1); - dst += dst_stride_x4; - - src10_r = src76_r; - src32_r = src98_r; - src21_r = src87_r; - src43_r = src109_r; - src4 = src10; - } -} - -static void common_vt_6t_16w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride << 2; - int32_t dst_stride_x2 = dst_stride << 1; - int32_t dst_stride_x3 = dst_stride_x2 + dst_stride; - int32_t dst_stride_x4 = dst_stride << 2; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8; - __m128i src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; - __m128i src87_r, src10_l, src32_l, src54_l, src76_l, src21_l, src43_l; - __m128i src65_l, src87_l, filt0, filt1, filt2; - __m128i tmp0, tmp1, tmp2, tmp3; - __m128i filt, out0_r, out1_r, out2_r, out3_r, out0_l, out1_l, out2_l, out3_l; - - src -= src_stride_x2; - filt = __lsx_vld(filter, 0); - DUP2_ARG2(__lsx_vreplvei_h, filt, 0, filt, 1, filt0, filt1); - filt2 = __lsx_vreplvei_h(filt, 2); - - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src0, src1, src2, src3); - src += src_stride_x4; - src4 = __lsx_vldx(src, 0); - src += src_stride; - - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - src4 = __lsx_vxori_b(src4, 128); - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src3, src2, src4, src3, src2, src1, - src10_r, src32_r, src43_r, src21_r); - DUP4_ARG2(__lsx_vilvh_b, src1, src0, src3, src2, src4, src3, src2, src1, - src10_l, src32_l, src43_l, src21_l); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src5, src6, src7, src8); - src += src_stride_x4; - - DUP4_ARG2(__lsx_vxori_b, src5, 128, src6, 128, src7, 128, src8, 128, src5, - src6, src7, src8); - DUP4_ARG2(__lsx_vilvl_b, src5, src4, src6, src5, src7, src6, src8, src7, - src54_r, src65_r, src76_r, src87_r); - DUP4_ARG2(__lsx_vilvh_b, src5, src4, src6, src5, src7, src6, src8, src7, - src54_l, src65_l, src76_l, src87_l); - out0_r = dpadd_h3(src10_r, src32_r, src54_r, filt0, filt1, filt2); - out1_r = dpadd_h3(src21_r, src43_r, src65_r, filt0, filt1, filt2); - out2_r = dpadd_h3(src32_r, src54_r, src76_r, filt0, filt1, filt2); - out3_r = dpadd_h3(src43_r, src65_r, src87_r, filt0, filt1, filt2); - out0_l = dpadd_h3(src10_l, src32_l, src54_l, filt0, filt1, filt2); - out1_l = dpadd_h3(src21_l, src43_l, src65_l, filt0, filt1, filt2); - out2_l = dpadd_h3(src32_l, src54_l, src76_l, filt0, filt1, filt2); - out3_l = dpadd_h3(src43_l, src65_l, src87_l, filt0, filt1, filt2); - DUP4_ARG3(__lsx_vssrarni_b_h, out0_l, out0_r, VP8_FILTER_SHIFT, out1_l, - out1_r, VP8_FILTER_SHIFT, out2_l, out2_r, VP8_FILTER_SHIFT, - out3_l, out3_r, VP8_FILTER_SHIFT, tmp0, tmp1, tmp2, tmp3); - DUP4_ARG2(__lsx_vxori_b, tmp0, 128, tmp1, 128, tmp2, 128, tmp3, 128, tmp0, - tmp1, tmp2, tmp3); - __lsx_vstx(tmp0, dst, 0); - __lsx_vstx(tmp1, dst, dst_stride); - __lsx_vstx(tmp2, dst, dst_stride_x2); - __lsx_vstx(tmp3, dst, dst_stride_x3); - dst += dst_stride_x4; - - src10_r = src54_r; - src32_r = src76_r; - src21_r = src65_r; - src43_r = src87_r; - src10_l = src54_l; - src32_l = src76_l; - src21_l = src65_l; - src43_l = src87_l; - src4 = src8; - } -} - -static void common_hv_6ht_6vt_4w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, tmp0, tmp1; - __m128i filt_hz0, filt_hz1, filt_hz2, mask0, mask1, mask2; - __m128i hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; - __m128i hz_out7, filt_vt0, filt_vt1, filt_vt2, out0, out1, out2, out3; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - - mask0 = __lsx_vld(vp8_mc_filt_mask_arr, 16); - src -= 2; - - DUP2_ARG2(__lsx_vldrepl_h, filter_horiz, 0, filter_horiz, 2, filt_hz0, - filt_hz1); - filt_hz2 = __lsx_vldrepl_h(filter_horiz, 4); - DUP2_ARG2(__lsx_vldrepl_h, filter_vert, 0, filter_vert, 2, filt_vt0, - filt_vt1); - filt_vt2 = __lsx_vldrepl_h(filter_vert, 4); - - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - - DUP2_ARG2(__lsx_vldx, src, -src_stride_x2, src, -src_stride, src0, src1); - src2 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride_x2, src3, src4); - src += src_stride_x3; - - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - src4 = __lsx_vxori_b(src4, 128); - - hz_out0 = horiz_6tap_filt(src0, src1, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out2 = horiz_6tap_filt(src2, src3, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out1 = __lsx_vshuf_b(hz_out2, hz_out0, shuff); - hz_out3 = horiz_6tap_filt(src3, src4, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - DUP2_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out3, hz_out2, out0, out1); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - src5 = __lsx_vld(src, 0); - src6 = __lsx_vldx(src, src_stride); - src += src_stride_x2; - - DUP2_ARG2(__lsx_vxori_b, src5, 128, src6, 128, src5, src6); - hz_out5 = horiz_6tap_filt(src5, src6, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - hz_out4 = __lsx_vshuf_b(hz_out5, hz_out3, shuff); - - src7 = __lsx_vld(src, 0); - src8 = __lsx_vldx(src, src_stride); - src += src_stride_x2; - - DUP2_ARG2(__lsx_vxori_b, src7, 128, src8, 128, src7, src8); - hz_out7 = horiz_6tap_filt(src7, src8, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - hz_out6 = __lsx_vshuf_b(hz_out7, hz_out5, shuff); - - out2 = __lsx_vpackev_b(hz_out5, hz_out4); - tmp0 = dpadd_h3(out0, out1, out2, filt_vt0, filt_vt1, filt_vt2); - - out3 = __lsx_vpackev_b(hz_out7, hz_out6); - tmp1 = dpadd_h3(out1, out2, out3, filt_vt0, filt_vt1, filt_vt2); - - tmp0 = __lsx_vssrarni_b_h(tmp1, tmp0, 7); - tmp0 = __lsx_vxori_b(tmp0, 128); - __lsx_vstelm_w(tmp0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(tmp0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(tmp0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(tmp0, dst, 0, 3); - dst += dst_stride; - - hz_out3 = hz_out7; - out0 = out2; - out1 = out3; - } -} - -static void common_hv_6ht_6vt_8w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride << 2; - int32_t dst_stride_x2 = dst_stride << 1; - int32_t dst_stride_x3 = dst_stride_x2 + dst_stride; - int32_t dst_stride_x4 = dst_stride << 2; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8; - __m128i filt_hz0, filt_hz1, filt_hz2; - __m128i mask0, mask1, mask2, vec0, vec1; - __m128i filt, filt_vt0, filt_vt1, filt_vt2; - __m128i hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; - __m128i hz_out7, hz_out8, out0, out1, out2, out3, out4, out5, out6, out7; - __m128i tmp0, tmp1, tmp2, tmp3; - - mask0 = __lsx_vld(vp8_mc_filt_mask_arr, 0); - src -= (2 + src_stride_x2); - - filt = __lsx_vld(filter_horiz, 0); - DUP2_ARG2(__lsx_vreplvei_h, filt, 0, filt, 1, filt_hz0, filt_hz1); - filt_hz2 = __lsx_vreplvei_h(filt, 2); - - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src0, src1, src2, src3); - src += src_stride_x4; - src4 = __lsx_vldx(src, 0); - src += src_stride; - - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - src4 = __lsx_vxori_b(src4, 128); - - hz_out0 = horiz_6tap_filt(src0, src0, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out1 = horiz_6tap_filt(src1, src1, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out2 = horiz_6tap_filt(src2, src2, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out3 = horiz_6tap_filt(src3, src3, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out4 = horiz_6tap_filt(src4, src4, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - filt = __lsx_vld(filter_vert, 0); - DUP2_ARG2(__lsx_vreplvei_h, filt, 0, filt, 1, filt_vt0, filt_vt1); - filt_vt2 = __lsx_vreplvei_h(filt, 2); - - DUP4_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out3, hz_out2, hz_out2, - hz_out1, hz_out4, hz_out3, out0, out1, out3, out4); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src5, src6, src7, src8); - src += src_stride_x4; - - DUP4_ARG2(__lsx_vxori_b, src5, 128, src6, 128, src7, 128, src8, 128, src5, - src6, src7, src8); - hz_out5 = horiz_6tap_filt(src5, src5, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - out2 = __lsx_vpackev_b(hz_out5, hz_out4); - tmp0 = dpadd_h3(out0, out1, out2, filt_vt0, filt_vt1, filt_vt2); - - hz_out6 = horiz_6tap_filt(src6, src6, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - out5 = __lsx_vpackev_b(hz_out6, hz_out5); - tmp1 = dpadd_h3(out3, out4, out5, filt_vt0, filt_vt1, filt_vt2); - - hz_out7 = horiz_6tap_filt(src7, src7, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - out7 = __lsx_vpackev_b(hz_out7, hz_out6); - tmp2 = dpadd_h3(out1, out2, out7, filt_vt0, filt_vt1, filt_vt2); - - hz_out8 = horiz_6tap_filt(src8, src8, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - out6 = __lsx_vpackev_b(hz_out8, hz_out7); - tmp3 = dpadd_h3(out4, out5, out6, filt_vt0, filt_vt1, filt_vt2); - - DUP2_ARG3(__lsx_vssrarni_b_h, tmp1, tmp0, VP8_FILTER_SHIFT, tmp3, tmp2, - VP8_FILTER_SHIFT, vec0, vec1); - DUP2_ARG2(__lsx_vxori_b, vec0, 128, vec1, 128, vec0, vec1); - - __lsx_vstelm_d(vec0, dst, 0, 0); - __lsx_vstelm_d(vec0, dst + dst_stride, 0, 1); - __lsx_vstelm_d(vec1, dst + dst_stride_x2, 0, 0); - __lsx_vstelm_d(vec1, dst + dst_stride_x3, 0, 1); - dst += dst_stride_x4; - - hz_out4 = hz_out8; - out0 = out2; - out1 = out7; - out3 = out5; - out4 = out6; - } -} - -static void common_hv_6ht_6vt_16w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - common_hv_6ht_6vt_8w_lsx(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - common_hv_6ht_6vt_8w_lsx(src + 8, src_stride, dst + 8, dst_stride, - filter_horiz, filter_vert, height); -} - -static void common_hz_4t_4x4_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter) { - __m128i src0, src1, src2, src3, filt0, filt1, mask0, mask1; - __m128i out0, out1; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - - mask0 = __lsx_vld(vp8_mc_filt_mask_arr, 16); - src -= 1; - - DUP2_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filt0, filt1); - mask1 = __lsx_vaddi_bu(mask0, 2); - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride_x2, src1, src2); - src3 = __lsx_vldx(src, src_stride_x3); - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_4TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, filt0, filt1, - out0, out1); - - out0 = __lsx_vssrarni_b_h(out1, out0, VP8_FILTER_SHIFT); - out0 = __lsx_vxori_b(out0, 128); - - __lsx_vstelm_w(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 3); -} - -static void common_hz_4t_4x8_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter) { - __m128i src0, src1, src2, src3, filt0, filt1, mask0, mask1; - __m128i out0, out1, out2, out3; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride << 2; - - mask0 = __lsx_vld(vp8_mc_filt_mask_arr, 16); - src -= 1; - - DUP2_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filt0, filt1); - mask1 = __lsx_vaddi_bu(mask0, 2); - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride_x2, src1, src2); - src3 = __lsx_vldx(src, src_stride_x3); - src += src_stride_x4; - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_4TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, filt0, filt1, - out0, out1); - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride_x2, src1, src2); - src3 = __lsx_vldx(src, src_stride_x3); - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_4TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, filt0, filt1, - out2, out3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, VP8_FILTER_SHIFT, out3, out2, - VP8_FILTER_SHIFT, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - __lsx_vstelm_w(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 3); - dst += dst_stride; - - __lsx_vstelm_w(out1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(out1, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(out1, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(out1, dst, 0, 3); -} - -static void common_hz_4t_4w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - if (height == 4) { - common_hz_4t_4x4_lsx(src, src_stride, dst, dst_stride, filter); - } else if (height == 8) { - common_hz_4t_4x8_lsx(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_hz_4t_8w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride << 2; - int32_t dst_stride_x2 = dst_stride << 1; - int32_t dst_stride_x3 = dst_stride_x2 + dst_stride; - int32_t dst_stride_x4 = dst_stride << 2; - __m128i src0, src1, src2, src3, filt0, filt1, mask0, mask1; - __m128i tmp0, tmp1; - __m128i filt, out0, out1, out2, out3; - - mask0 = __lsx_vld(vp8_mc_filt_mask_arr, 0); - src -= 1; - - filt = __lsx_vld(filter, 0); - DUP2_ARG2(__lsx_vreplvei_h, filt, 0, filt, 1, filt0, filt1); - mask1 = __lsx_vaddi_bu(mask0, 2); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src0, src1, src2, src3); - src += src_stride_x4; - - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_4TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, filt0, - filt1, out0, out1, out2, out3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, VP8_FILTER_SHIFT, out3, out2, - VP8_FILTER_SHIFT, tmp0, tmp1); - DUP2_ARG2(__lsx_vxori_b, tmp0, 128, tmp1, 128, tmp0, tmp1); - __lsx_vstelm_d(tmp0, dst, 0, 0); - __lsx_vstelm_d(tmp0, dst + dst_stride, 0, 1); - __lsx_vstelm_d(tmp1, dst + dst_stride_x2, 0, 0); - __lsx_vstelm_d(tmp1, dst + dst_stride_x3, 0, 1); - dst += dst_stride_x4; - } -} - -static void common_hz_4t_16w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride << 2; - int32_t dst_stride_x2 = dst_stride << 1; - int32_t dst_stride_x3 = dst_stride_x2 + dst_stride; - int32_t dst_stride_x4 = dst_stride << 2; - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - __m128i filt0, filt1, mask0, mask1; - __m128i filt, out0, out1, out2, out3, out4, out5, out6, out7; - - mask0 = __lsx_vld(vp8_mc_filt_mask_arr, 0); - src -= 1; - - filt = __lsx_vld(filter, 0); - DUP2_ARG2(__lsx_vreplvei_h, filt, 0, filt, 1, filt0, filt1); - mask1 = __lsx_vaddi_bu(mask0, 2); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src0, src2, src4, src6); - src += 8; - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src1, src3, src5, src7); - src += src_stride_x4 - 8; - - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - DUP4_ARG2(__lsx_vxori_b, src4, 128, src5, 128, src6, 128, src7, 128, src4, - src5, src6, src7); - HORIZ_4TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, filt0, - filt1, out0, out1, out2, out3); - HORIZ_4TAP_8WID_4VECS_FILT(src4, src5, src6, src7, mask0, mask1, filt0, - filt1, out4, out5, out6, out7); - DUP4_ARG3(__lsx_vssrarni_b_h, out1, out0, VP8_FILTER_SHIFT, out3, out2, - VP8_FILTER_SHIFT, out5, out4, VP8_FILTER_SHIFT, out7, out6, - VP8_FILTER_SHIFT, out0, out1, out2, out3); - DUP4_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out2, 128, out3, 128, out0, - out1, out2, out3); - __lsx_vstx(out0, dst, 0); - __lsx_vstx(out1, dst, dst_stride); - __lsx_vstx(out2, dst, dst_stride_x2); - __lsx_vstx(out3, dst, dst_stride_x3); - dst += dst_stride_x4; - } -} - -static void common_vt_4t_4w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - __m128i src0, src1, src2, src3, src4, src5; - __m128i src10_r, src32_r, src54_r, src21_r, src43_r, src65_r; - __m128i src2110, src4332, filt0, filt1, out0, out1; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - - DUP2_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filt0, filt1); - DUP2_ARG2(__lsx_vldx, src, -src_stride, src, src_stride, src0, src2); - src1 = __lsx_vld(src, 0); - src += src_stride_x2; - - DUP2_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, src10_r, src21_r); - - src2110 = __lsx_vilvl_d(src21_r, src10_r); - src2110 = __lsx_vxori_b(src2110, 128); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - src3 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride_x2, src4, src5); - src += src_stride_x3; - DUP2_ARG2(__lsx_vilvl_b, src3, src2, src4, src3, src32_r, src43_r); - src4332 = __lsx_vilvl_d(src43_r, src32_r); - src4332 = __lsx_vxori_b(src4332, 128); - out0 = filt_4tap_dpadd_h(src2110, src4332, filt0, filt1); - - src2 = __lsx_vld(src, 0); - src += src_stride; - DUP2_ARG2(__lsx_vilvl_b, src5, src4, src2, src5, src54_r, src65_r); - src2110 = __lsx_vilvl_d(src65_r, src54_r); - src2110 = __lsx_vxori_b(src2110, 128); - out1 = filt_4tap_dpadd_h(src4332, src2110, filt0, filt1); - out0 = __lsx_vssrarni_b_h(out1, out0, VP8_FILTER_SHIFT); - out0 = __lsx_vxori_b(out0, 128); - - __lsx_vstelm_w(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 3); - dst += dst_stride; - } -} - -static void common_vt_4t_8w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride << 2; - int32_t dst_stride_x2 = dst_stride << 1; - int32_t dst_stride_x3 = dst_stride_x2 + dst_stride; - int32_t dst_stride_x4 = dst_stride << 2; - __m128i src0, src1, src2, src7, src8, src9, src10; - __m128i src10_r, src72_r, src98_r, src21_r, src87_r, src109_r, filt0, filt1; - __m128i tmp0, tmp1; - __m128i filt, out0_r, out1_r, out2_r, out3_r; - - src -= src_stride; - filt = __lsx_vld(filter, 0); - DUP2_ARG2(__lsx_vreplvei_h, filt, 0, filt, 1, filt0, filt1); - - DUP2_ARG2(__lsx_vldx, src, 0, src, src_stride, src0, src1); - src2 = __lsx_vldx(src, src_stride_x2); - src += src_stride_x3; - - DUP2_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src0, src1); - src2 = __lsx_vxori_b(src2, 128); - DUP2_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, src10_r, src21_r); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src7, src8, src9, src10); - src += src_stride_x4; - - DUP4_ARG2(__lsx_vxori_b, src7, 128, src8, 128, src9, 128, src10, 128, src7, - src8, src9, src10); - DUP4_ARG2(__lsx_vilvl_b, src7, src2, src8, src7, src9, src8, src10, src9, - src72_r, src87_r, src98_r, src109_r); - out0_r = filt_4tap_dpadd_h(src10_r, src72_r, filt0, filt1); - out1_r = filt_4tap_dpadd_h(src21_r, src87_r, filt0, filt1); - out2_r = filt_4tap_dpadd_h(src72_r, src98_r, filt0, filt1); - out3_r = filt_4tap_dpadd_h(src87_r, src109_r, filt0, filt1); - DUP2_ARG3(__lsx_vssrarni_b_h, out1_r, out0_r, VP8_FILTER_SHIFT, out3_r, - out2_r, VP8_FILTER_SHIFT, tmp0, tmp1); - DUP2_ARG2(__lsx_vxori_b, tmp0, 128, tmp1, 128, tmp0, tmp1); - __lsx_vstelm_d(tmp0, dst, 0, 0); - __lsx_vstelm_d(tmp0, dst + dst_stride, 0, 1); - __lsx_vstelm_d(tmp1, dst + dst_stride_x2, 0, 0); - __lsx_vstelm_d(tmp1, dst + dst_stride_x3, 0, 1); - dst += dst_stride_x4; - - src10_r = src98_r; - src21_r = src109_r; - src2 = src10; - } -} - -static void common_vt_4t_16w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride << 2; - int32_t dst_stride_x2 = dst_stride << 1; - int32_t dst_stride_x3 = dst_stride_x2 + dst_stride; - int32_t dst_stride_x4 = dst_stride << 2; - __m128i src0, src1, src2, src3, src4, src5, src6; - __m128i src10_r, src32_r, src54_r, src21_r, src43_r, src65_r, src10_l; - __m128i src32_l, src54_l, src21_l, src43_l, src65_l, filt0, filt1; - __m128i tmp0, tmp1, tmp2, tmp3; - __m128i filt, out0_r, out1_r, out2_r, out3_r, out0_l, out1_l, out2_l, out3_l; - - src -= src_stride; - filt = __lsx_vld(filter, 0); - DUP2_ARG2(__lsx_vreplvei_h, filt, 0, filt, 1, filt0, filt1); - - DUP2_ARG2(__lsx_vldx, src, 0, src, src_stride, src0, src1); - src2 = __lsx_vldx(src, src_stride_x2); - src += src_stride_x3; - - DUP2_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src0, src1); - src2 = __lsx_vxori_b(src2, 128); - DUP2_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, src10_r, src21_r); - DUP2_ARG2(__lsx_vilvh_b, src1, src0, src2, src1, src10_l, src21_l); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src3, src4, src5, src6); - src += src_stride_x4; - - DUP4_ARG2(__lsx_vxori_b, src3, 128, src4, 128, src5, 128, src6, 128, src3, - src4, src5, src6); - DUP4_ARG2(__lsx_vilvl_b, src3, src2, src4, src3, src5, src4, src6, src5, - src32_r, src43_r, src54_r, src65_r); - DUP4_ARG2(__lsx_vilvh_b, src3, src2, src4, src3, src5, src4, src6, src5, - src32_l, src43_l, src54_l, src65_l); - out0_r = filt_4tap_dpadd_h(src10_r, src32_r, filt0, filt1); - out1_r = filt_4tap_dpadd_h(src21_r, src43_r, filt0, filt1); - out2_r = filt_4tap_dpadd_h(src32_r, src54_r, filt0, filt1); - out3_r = filt_4tap_dpadd_h(src43_r, src65_r, filt0, filt1); - out0_l = filt_4tap_dpadd_h(src10_l, src32_l, filt0, filt1); - out1_l = filt_4tap_dpadd_h(src21_l, src43_l, filt0, filt1); - out2_l = filt_4tap_dpadd_h(src32_l, src54_l, filt0, filt1); - out3_l = filt_4tap_dpadd_h(src43_l, src65_l, filt0, filt1); - DUP4_ARG3(__lsx_vssrarni_b_h, out0_l, out0_r, VP8_FILTER_SHIFT, out1_l, - out1_r, VP8_FILTER_SHIFT, out2_l, out2_r, VP8_FILTER_SHIFT, - out3_l, out3_r, VP8_FILTER_SHIFT, tmp0, tmp1, tmp2, tmp3); - DUP4_ARG2(__lsx_vxori_b, tmp0, 128, tmp1, 128, tmp2, 128, tmp3, 128, tmp0, - tmp1, tmp2, tmp3); - __lsx_vstx(tmp0, dst, 0); - __lsx_vstx(tmp1, dst, dst_stride); - __lsx_vstx(tmp2, dst, dst_stride_x2); - __lsx_vstx(tmp3, dst, dst_stride_x3); - dst += dst_stride_x4; - - src10_r = src54_r; - src21_r = src65_r; - src10_l = src54_l; - src21_l = src65_l; - src2 = src6; - } -} - -static void common_hv_4ht_4vt_4w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - __m128i src0, src1, src2, src3, src4, src5, src6, filt_hz0, filt_hz1; - __m128i mask0, mask1, filt_vt0, filt_vt1, tmp0, tmp1, vec0, vec1, vec2; - __m128i hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride << 2; - - mask0 = __lsx_vld(vp8_mc_filt_mask_arr, 16); - src -= 1; - - DUP2_ARG2(__lsx_vldrepl_h, filter_horiz, 0, filter_horiz, 2, filt_hz0, - filt_hz1); - mask1 = __lsx_vaddi_bu(mask0, 2); - - src1 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, -src_stride, src, src_stride, src0, src2); - src += src_stride_x2; - - DUP2_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src0, src1); - src2 = __lsx_vxori_b(src2, 128); - hz_out0 = horiz_4tap_filt(src0, src1, mask0, mask1, filt_hz0, filt_hz1); - hz_out1 = horiz_4tap_filt(src1, src2, mask0, mask1, filt_hz0, filt_hz1); - vec0 = __lsx_vpackev_b(hz_out1, hz_out0); - - DUP2_ARG2(__lsx_vldrepl_h, filter_vert, 0, filter_vert, 2, filt_vt0, - filt_vt1); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - src3 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride_x2, src4, src5); - src6 = __lsx_vldx(src, src_stride_x3); - src += src_stride_x4; - - DUP2_ARG2(__lsx_vxori_b, src3, 128, src4, 128, src3, src4); - hz_out3 = horiz_4tap_filt(src3, src4, mask0, mask1, filt_hz0, filt_hz1); - hz_out2 = __lsx_vshuf_b(hz_out3, hz_out1, shuff); - vec1 = __lsx_vpackev_b(hz_out3, hz_out2); - tmp0 = filt_4tap_dpadd_h(vec0, vec1, filt_vt0, filt_vt1); - - DUP2_ARG2(__lsx_vxori_b, src5, 128, src6, 128, src5, src6); - hz_out5 = horiz_4tap_filt(src5, src6, mask0, mask1, filt_hz0, filt_hz1); - hz_out4 = __lsx_vshuf_b(hz_out5, hz_out3, shuff); - vec2 = __lsx_vpackev_b(hz_out5, hz_out4); - tmp1 = filt_4tap_dpadd_h(vec1, vec2, filt_vt0, filt_vt1); - - tmp0 = __lsx_vssrarni_b_h(tmp1, tmp0, 7); - tmp0 = __lsx_vxori_b(tmp0, 128); - __lsx_vstelm_w(tmp0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(tmp0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(tmp0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(tmp0, dst, 0, 3); - dst += dst_stride; - - hz_out1 = hz_out5; - vec0 = vec2; - } -} - -static inline void common_hv_4ht_4vt_8w_lsx( - uint8_t *RESTRICT src, int32_t src_stride, uint8_t *RESTRICT dst, - int32_t dst_stride, const int8_t *filter_horiz, const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride << 2; - int32_t dst_stride_x2 = dst_stride << 1; - int32_t dst_stride_x3 = dst_stride_x2 + dst_stride; - int32_t dst_stride_x4 = dst_stride << 2; - __m128i src0, src1, src2, src3, src4, src5, src6, filt_hz0, filt_hz1; - __m128i mask0, mask1, out0, out1; - __m128i filt, filt_vt0, filt_vt1, tmp0, tmp1, tmp2, tmp3; - __m128i hz_out0, hz_out1, hz_out2, hz_out3; - __m128i vec0, vec1, vec2, vec3, vec4; - - mask0 = __lsx_vld(vp8_mc_filt_mask_arr, 0); - src -= 1 + src_stride; - - filt = __lsx_vld(filter_horiz, 0); - DUP2_ARG2(__lsx_vreplvei_h, filt, 0, filt, 1, filt_hz0, filt_hz1); - mask1 = __lsx_vaddi_bu(mask0, 2); - - DUP2_ARG2(__lsx_vldx, src, 0, src, src_stride, src0, src1); - src2 = __lsx_vldx(src, src_stride_x2); - src += src_stride_x3; - - DUP2_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src0, src1); - src2 = __lsx_vxori_b(src2, 128); - hz_out0 = horiz_4tap_filt(src0, src0, mask0, mask1, filt_hz0, filt_hz1); - hz_out1 = horiz_4tap_filt(src1, src1, mask0, mask1, filt_hz0, filt_hz1); - hz_out2 = horiz_4tap_filt(src2, src2, mask0, mask1, filt_hz0, filt_hz1); - DUP2_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out2, hz_out1, vec0, vec2); - - filt = __lsx_vld(filter_vert, 0); - DUP2_ARG2(__lsx_vreplvei_h, filt, 0, filt, 1, filt_vt0, filt_vt1); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src3, src4, src5, src6); - src += src_stride_x4; - - DUP4_ARG2(__lsx_vxori_b, src3, 128, src4, 128, src5, 128, src6, 128, src3, - src4, src5, src6); - hz_out3 = horiz_4tap_filt(src3, src3, mask0, mask1, filt_hz0, filt_hz1); - vec1 = __lsx_vpackev_b(hz_out3, hz_out2); - tmp0 = filt_4tap_dpadd_h(vec0, vec1, filt_vt0, filt_vt1); - - hz_out0 = horiz_4tap_filt(src4, src4, mask0, mask1, filt_hz0, filt_hz1); - vec3 = __lsx_vpackev_b(hz_out0, hz_out3); - tmp1 = filt_4tap_dpadd_h(vec2, vec3, filt_vt0, filt_vt1); - - hz_out1 = horiz_4tap_filt(src5, src5, mask0, mask1, filt_hz0, filt_hz1); - vec4 = __lsx_vpackev_b(hz_out1, hz_out0); - tmp2 = filt_4tap_dpadd_h(vec1, vec4, filt_vt0, filt_vt1); - - hz_out2 = horiz_4tap_filt(src6, src6, mask0, mask1, filt_hz0, filt_hz1); - DUP2_ARG2(__lsx_vpackev_b, hz_out0, hz_out3, hz_out2, hz_out1, vec0, vec1); - tmp3 = filt_4tap_dpadd_h(vec0, vec1, filt_vt0, filt_vt1); - - DUP2_ARG3(__lsx_vssrarni_b_h, tmp1, tmp0, 7, tmp3, tmp2, 7, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - __lsx_vstelm_d(out0, dst, 0, 0); - __lsx_vstelm_d(out0, dst + dst_stride, 0, 1); - __lsx_vstelm_d(out1, dst + dst_stride_x2, 0, 0); - __lsx_vstelm_d(out1, dst + dst_stride_x3, 0, 1); - dst += dst_stride_x4; - - vec0 = vec4; - vec2 = vec1; - } -} - -static void common_hv_4ht_4vt_16w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - common_hv_4ht_4vt_8w_lsx(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - common_hv_4ht_4vt_8w_lsx(src + 8, src_stride, dst + 8, dst_stride, - filter_horiz, filter_vert, height); -} - -static void common_hv_6ht_4vt_4w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - __m128i src0, src1, src2, src3, src4, src5, src6; - __m128i filt_hz0, filt_hz1, filt_hz2, mask0, mask1, mask2; - __m128i filt_vt0, filt_vt1, tmp0, tmp1, vec0, vec1, vec2; - __m128i hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride << 2; - - mask0 = __lsx_vld(vp8_mc_filt_mask_arr, 16); - src -= 2; - - DUP2_ARG2(__lsx_vldrepl_h, filter_horiz, 0, filter_horiz, 2, filt_hz0, - filt_hz1); - filt_hz2 = __lsx_vldrepl_h(filter_horiz, 4); - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - - src1 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, -src_stride, src, src_stride, src0, src2); - src += src_stride_x2; - - DUP2_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src0, src1); - src2 = __lsx_vxori_b(src2, 128); - - hz_out0 = horiz_6tap_filt(src0, src1, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out1 = horiz_6tap_filt(src1, src2, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - vec0 = __lsx_vpackev_b(hz_out1, hz_out0); - - DUP2_ARG2(__lsx_vldrepl_h, filter_vert, 0, filter_vert, 2, filt_vt0, - filt_vt1); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - src3 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride_x2, src4, src5); - src6 = __lsx_vldx(src, src_stride_x3); - src += src_stride_x4; - DUP4_ARG2(__lsx_vxori_b, src3, 128, src4, 128, src5, 128, src6, 128, src3, - src4, src5, src6); - - hz_out3 = horiz_6tap_filt(src3, src4, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - hz_out2 = __lsx_vshuf_b(hz_out3, hz_out1, shuff); - vec1 = __lsx_vpackev_b(hz_out3, hz_out2); - tmp0 = filt_4tap_dpadd_h(vec0, vec1, filt_vt0, filt_vt1); - - hz_out5 = horiz_6tap_filt(src5, src6, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - hz_out4 = __lsx_vshuf_b(hz_out5, hz_out3, shuff); - vec2 = __lsx_vpackev_b(hz_out5, hz_out4); - tmp1 = filt_4tap_dpadd_h(vec1, vec2, filt_vt0, filt_vt1); - - DUP2_ARG3(__lsx_vssrarni_b_h, tmp0, tmp0, 7, tmp1, tmp1, 7, tmp0, tmp1); - DUP2_ARG2(__lsx_vxori_b, tmp0, 128, tmp1, 128, tmp0, tmp1); - - __lsx_vstelm_w(tmp0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(tmp0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(tmp1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(tmp1, dst, 0, 1); - dst += dst_stride; - - hz_out1 = hz_out5; - vec0 = vec2; - } -} - -static inline void common_hv_6ht_4vt_8w_lsx( - uint8_t *RESTRICT src, int32_t src_stride, uint8_t *RESTRICT dst, - int32_t dst_stride, const int8_t *filter_horiz, const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride << 2; - int32_t dst_stride_x2 = dst_stride << 1; - int32_t dst_stride_x3 = dst_stride_x2 + dst_stride; - int32_t dst_stride_x4 = dst_stride << 2; - - __m128i src0, src1, src2, src3, src4, src5, src6; - __m128i filt_hz0, filt_hz1, filt_hz2, mask0, mask1, mask2; - __m128i filt, filt_vt0, filt_vt1, hz_out0, hz_out1, hz_out2, hz_out3; - __m128i tmp0, tmp1, tmp2, tmp3, vec0, vec1, vec2, vec3; - __m128i out0, out1; - - mask0 = __lsx_vld(vp8_mc_filt_mask_arr, 0); - src -= (2 + src_stride); - - filt = __lsx_vld(filter_horiz, 0); - DUP2_ARG2(__lsx_vreplvei_h, filt, 0, filt, 1, filt_hz0, filt_hz1); - filt_hz2 = __lsx_vreplvei_h(filt, 2); - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - - DUP2_ARG2(__lsx_vldx, src, 0, src, src_stride, src0, src1); - src2 = __lsx_vldx(src, src_stride_x2); - src += src_stride_x3; - - DUP2_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src0, src1); - src2 = __lsx_vxori_b(src2, 128); - hz_out0 = horiz_6tap_filt(src0, src0, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out1 = horiz_6tap_filt(src1, src1, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out2 = horiz_6tap_filt(src2, src2, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - DUP2_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out2, hz_out1, vec0, vec2); - - filt = __lsx_vld(filter_vert, 0); - DUP2_ARG2(__lsx_vreplvei_h, filt, 0, filt, 1, filt_vt0, filt_vt1); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src3, src4, src5, src6); - src += src_stride_x4; - DUP4_ARG2(__lsx_vxori_b, src3, 128, src4, 128, src5, 128, src6, 128, src3, - src4, src5, src6); - - hz_out3 = horiz_6tap_filt(src3, src3, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - vec1 = __lsx_vpackev_b(hz_out3, hz_out2); - tmp0 = filt_4tap_dpadd_h(vec0, vec1, filt_vt0, filt_vt1); - - hz_out0 = horiz_6tap_filt(src4, src4, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - vec3 = __lsx_vpackev_b(hz_out0, hz_out3); - tmp1 = filt_4tap_dpadd_h(vec2, vec3, filt_vt0, filt_vt1); - - hz_out1 = horiz_6tap_filt(src5, src5, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - vec0 = __lsx_vpackev_b(hz_out1, hz_out0); - tmp2 = filt_4tap_dpadd_h(vec1, vec0, filt_vt0, filt_vt1); - - hz_out2 = horiz_6tap_filt(src6, src6, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - DUP2_ARG2(__lsx_vpackev_b, hz_out0, hz_out3, hz_out2, hz_out1, vec1, vec2); - tmp3 = filt_4tap_dpadd_h(vec1, vec2, filt_vt0, filt_vt1); - - DUP2_ARG3(__lsx_vssrarni_b_h, tmp1, tmp0, 7, tmp3, tmp2, 7, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - __lsx_vstelm_d(out0, dst, 0, 0); - __lsx_vstelm_d(out0, dst + dst_stride, 0, 1); - __lsx_vstelm_d(out1, dst + dst_stride_x2, 0, 0); - __lsx_vstelm_d(out1, dst + dst_stride_x3, 0, 1); - dst += dst_stride_x4; - } -} - -static void common_hv_6ht_4vt_16w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - common_hv_6ht_4vt_8w_lsx(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - common_hv_6ht_4vt_8w_lsx(src + 8, src_stride, dst + 8, dst_stride, - filter_horiz, filter_vert, height); -} - -static void common_hv_4ht_6vt_4w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8; - __m128i filt_hz0, filt_hz1, filt_vt0, filt_vt1, filt_vt2, mask0, mask1; - __m128i hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; - __m128i hz_out7, tmp0, tmp1, out0, out1, out2, out3; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride << 2; - - mask0 = __lsx_vld(vp8_mc_filt_mask_arr, 16); - - src -= 1; - - DUP2_ARG2(__lsx_vldrepl_h, filter_horiz, 0, filter_horiz, 2, filt_hz0, - filt_hz1); - mask1 = __lsx_vaddi_bu(mask0, 2); - - DUP4_ARG2(__lsx_vldx, src, -src_stride_x2, src, -src_stride, src, src_stride, - src, src_stride_x2, src0, src1, src3, src4); - src2 = __lsx_vld(src, 0); - src += src_stride_x3; - - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - src4 = __lsx_vxori_b(src4, 128); - hz_out0 = horiz_4tap_filt(src0, src1, mask0, mask1, filt_hz0, filt_hz1); - hz_out2 = horiz_4tap_filt(src2, src3, mask0, mask1, filt_hz0, filt_hz1); - hz_out3 = horiz_4tap_filt(src3, src4, mask0, mask1, filt_hz0, filt_hz1); - hz_out1 = __lsx_vshuf_b(hz_out2, hz_out0, shuff); - DUP2_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out3, hz_out2, out0, out1); - - DUP2_ARG2(__lsx_vldrepl_h, filter_vert, 0, filter_vert, 2, filt_vt0, - filt_vt1); - filt_vt2 = __lsx_vldrepl_h(filter_vert, 4); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - src5 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride_x2, src6, src7); - src8 = __lsx_vldx(src, src_stride_x3); - DUP4_ARG2(__lsx_vxori_b, src5, 128, src6, 128, src7, 128, src8, 128, src5, - src6, src7, src8); - src += src_stride_x4; - - hz_out5 = horiz_4tap_filt(src5, src6, mask0, mask1, filt_hz0, filt_hz1); - hz_out4 = __lsx_vshuf_b(hz_out5, hz_out3, shuff); - out2 = __lsx_vpackev_b(hz_out5, hz_out4); - tmp0 = dpadd_h3(out0, out1, out2, filt_vt0, filt_vt1, filt_vt2); - - hz_out7 = horiz_4tap_filt(src7, src8, mask0, mask1, filt_hz0, filt_hz1); - hz_out6 = __lsx_vshuf_b(hz_out7, hz_out5, shuff); - out3 = __lsx_vpackev_b(hz_out7, hz_out6); - tmp1 = dpadd_h3(out1, out2, out3, filt_vt0, filt_vt1, filt_vt2); - - tmp0 = __lsx_vssrarni_b_h(tmp1, tmp0, 7); - tmp0 = __lsx_vxori_b(tmp0, 128); - __lsx_vstelm_w(tmp0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(tmp0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(tmp0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(tmp0, dst, 0, 3); - dst += dst_stride; - - hz_out3 = hz_out7; - out0 = out2; - out1 = out3; - } -} - -static inline void common_hv_4ht_6vt_8w_lsx( - uint8_t *RESTRICT src, int32_t src_stride, uint8_t *RESTRICT dst, - int32_t dst_stride, const int8_t *filter_horiz, const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - int32_t src_stride_x2 = src_stride << 1; - int32_t src_stride_x3 = src_stride_x2 + src_stride; - int32_t src_stride_x4 = src_stride << 2; - int32_t dst_stride_x2 = dst_stride << 1; - int32_t dst_stride_x3 = dst_stride_x2 + dst_stride; - int32_t dst_stride_x4 = dst_stride << 2; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8; - __m128i filt_hz0, filt_hz1, mask0, mask1; - __m128i filt, filt_vt0, filt_vt1, filt_vt2, tmp0, tmp1, tmp2, tmp3; - __m128i hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; - __m128i hz_out7, hz_out8, out0, out1, out2, out3, out4, out5, out6, out7; - __m128i vec0, vec1; - - mask0 = __lsx_vld(vp8_mc_filt_mask_arr, 0); - src -= 1 + src_stride_x2; - - filt = __lsx_vld(filter_horiz, 0); - DUP2_ARG2(__lsx_vreplvei_h, filt, 0, filt, 1, filt_hz0, filt_hz1); - mask1 = __lsx_vaddi_bu(mask0, 2); - - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src0, src1, src2, src3); - src += src_stride_x4; - src4 = __lsx_vld(src, 0); - src += src_stride; - - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - src4 = __lsx_vxori_b(src4, 128); - hz_out0 = horiz_4tap_filt(src0, src0, mask0, mask1, filt_hz0, filt_hz1); - hz_out1 = horiz_4tap_filt(src1, src1, mask0, mask1, filt_hz0, filt_hz1); - hz_out2 = horiz_4tap_filt(src2, src2, mask0, mask1, filt_hz0, filt_hz1); - hz_out3 = horiz_4tap_filt(src3, src3, mask0, mask1, filt_hz0, filt_hz1); - hz_out4 = horiz_4tap_filt(src4, src4, mask0, mask1, filt_hz0, filt_hz1); - DUP2_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out3, hz_out2, out0, out1); - DUP2_ARG2(__lsx_vpackev_b, hz_out2, hz_out1, hz_out4, hz_out3, out3, out4); - - filt = __lsx_vld(filter_vert, 0); - DUP2_ARG2(__lsx_vreplvei_h, filt, 0, filt, 1, filt_vt0, filt_vt1); - filt_vt2 = __lsx_vreplvei_h(filt, 2); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - DUP4_ARG2(__lsx_vldx, src, 0, src, src_stride, src, src_stride_x2, src, - src_stride_x3, src5, src6, src7, src8); - src += src_stride_x4; - - DUP4_ARG2(__lsx_vxori_b, src5, 128, src6, 128, src7, 128, src8, 128, src5, - src6, src7, src8); - hz_out5 = horiz_4tap_filt(src5, src5, mask0, mask1, filt_hz0, filt_hz1); - out2 = __lsx_vpackev_b(hz_out5, hz_out4); - tmp0 = dpadd_h3(out0, out1, out2, filt_vt0, filt_vt1, filt_vt2); - - hz_out6 = horiz_4tap_filt(src6, src6, mask0, mask1, filt_hz0, filt_hz1); - out5 = __lsx_vpackev_b(hz_out6, hz_out5); - tmp1 = dpadd_h3(out3, out4, out5, filt_vt0, filt_vt1, filt_vt2); - - hz_out7 = horiz_4tap_filt(src7, src7, mask0, mask1, filt_hz0, filt_hz1); - out6 = __lsx_vpackev_b(hz_out7, hz_out6); - tmp2 = dpadd_h3(out1, out2, out6, filt_vt0, filt_vt1, filt_vt2); - - hz_out8 = horiz_4tap_filt(src8, src8, mask0, mask1, filt_hz0, filt_hz1); - out7 = __lsx_vpackev_b(hz_out8, hz_out7); - tmp3 = dpadd_h3(out4, out5, out7, filt_vt0, filt_vt1, filt_vt2); - DUP2_ARG3(__lsx_vssrarni_b_h, tmp1, tmp0, 7, tmp3, tmp2, 7, vec0, vec1); - DUP2_ARG2(__lsx_vxori_b, vec0, 128, vec1, 128, vec0, vec1); - __lsx_vstelm_d(vec0, dst, 0, 0); - __lsx_vstelm_d(vec0, dst + dst_stride, 0, 1); - __lsx_vstelm_d(vec1, dst + dst_stride_x2, 0, 0); - __lsx_vstelm_d(vec1, dst + dst_stride_x3, 0, 1); - dst += dst_stride_x4; - hz_out4 = hz_out8; - out0 = out2; - out1 = out6; - out3 = out5; - out4 = out7; - } -} - -static void common_hv_4ht_6vt_16w_lsx(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - common_hv_4ht_6vt_8w_lsx(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - common_hv_4ht_6vt_8w_lsx(src + 8, src_stride, dst + 8, dst_stride, - filter_horiz, filter_vert, height); -} - -typedef void (*PVp8SixtapPredictFunc1)( - uint8_t *RESTRICT src, int32_t src_stride, uint8_t *RESTRICT dst, - int32_t dst_stride, const int8_t *filter_horiz, const int8_t *filter_vert, - int32_t height); - -typedef void (*PVp8SixtapPredictFunc2)(uint8_t *RESTRICT src, - int32_t src_stride, - uint8_t *RESTRICT dst, - int32_t dst_stride, const int8_t *filter, - int32_t height); - -void vp8_sixtap_predict4x4_lsx(uint8_t *RESTRICT src, int32_t src_stride, - int32_t xoffset, int32_t yoffset, - uint8_t *RESTRICT dst, int32_t dst_stride) { - const int8_t *h_filter = vp8_subpel_filters_lsx[xoffset - 1]; - const int8_t *v_filter = vp8_subpel_filters_lsx[yoffset - 1]; - - static PVp8SixtapPredictFunc1 Predict4x4Funcs1[4] = { - common_hv_6ht_6vt_4w_lsx, - common_hv_6ht_4vt_4w_lsx, - common_hv_4ht_6vt_4w_lsx, - common_hv_4ht_4vt_4w_lsx, - }; - - static PVp8SixtapPredictFunc2 Predict4x4Funcs2[4] = { common_vt_6t_4w_lsx, - common_vt_4t_4w_lsx, - common_hz_6t_4w_lsx, - common_hz_4t_4w_lsx }; - if (yoffset < 8 && xoffset < 8) { - if (yoffset) { - if (xoffset) { - switch (xoffset & 1) { - case 0: - switch (yoffset & 1) { - case 0: - Predict4x4Funcs1[0](src, src_stride, dst, dst_stride, h_filter, - v_filter, 4); - break; - case 1: - Predict4x4Funcs1[1](src, src_stride, dst, dst_stride, h_filter, - v_filter + 1, 4); - break; - } - break; - - case 1: - switch (yoffset & 1) { - case 0: - Predict4x4Funcs1[2](src, src_stride, dst, dst_stride, - h_filter + 1, v_filter, 4); - break; - - case 1: - Predict4x4Funcs1[3](src, src_stride, dst, dst_stride, - h_filter + 1, v_filter + 1, 4); - break; - } - break; - } - } else { - switch (yoffset & 1) { - case 0: - Predict4x4Funcs2[0](src, src_stride, dst, dst_stride, v_filter, 4); - break; - - case 1: - Predict4x4Funcs2[1](src, src_stride, dst, dst_stride, v_filter + 1, - 4); - break; - } - } - } else { - switch (xoffset) { - case 0: { - __m128i tp0; - - tp0 = __lsx_vldrepl_w(src, 0); - src += src_stride; - __lsx_vstelm_w(tp0, dst, 0, 0); - dst += dst_stride; - tp0 = __lsx_vldrepl_w(src, 0); - src += src_stride; - __lsx_vstelm_w(tp0, dst, 0, 0); - dst += dst_stride; - tp0 = __lsx_vldrepl_w(src, 0); - src += src_stride; - __lsx_vstelm_w(tp0, dst, 0, 0); - dst += dst_stride; - tp0 = __lsx_vldrepl_w(src, 0); - __lsx_vstelm_w(tp0, dst, 0, 0); - - break; - } - case 2: - case 4: - case 6: - Predict4x4Funcs2[2](src, src_stride, dst, dst_stride, h_filter, 4); - break; - } - switch (xoffset & 1) { - case 1: - Predict4x4Funcs2[3](src, src_stride, dst, dst_stride, h_filter + 1, - 4); - break; - } - } - } -} - -void vp8_sixtap_predict8x8_lsx(uint8_t *RESTRICT src, int32_t src_stride, - int32_t xoffset, int32_t yoffset, - uint8_t *RESTRICT dst, int32_t dst_stride) { - const int8_t *h_filter = vp8_subpel_filters_lsx[xoffset - 1]; - const int8_t *v_filter = vp8_subpel_filters_lsx[yoffset - 1]; - - static PVp8SixtapPredictFunc1 Predict8x8Funcs1[4] = { - common_hv_6ht_6vt_8w_lsx, - common_hv_6ht_4vt_8w_lsx, - common_hv_4ht_6vt_8w_lsx, - common_hv_4ht_4vt_8w_lsx, - }; - - static PVp8SixtapPredictFunc2 Predict8x8Funcs2[4] = { common_vt_6t_8w_lsx, - common_vt_4t_8w_lsx, - common_hz_6t_8w_lsx, - common_hz_4t_8w_lsx }; - - if (yoffset < 8 && xoffset < 8) { - if (yoffset) { - if (xoffset) { - switch (xoffset & 1) { - case 0: - switch (yoffset & 1) { - case 0: - Predict8x8Funcs1[0](src, src_stride, dst, dst_stride, h_filter, - v_filter, 8); - break; - - case 1: - Predict8x8Funcs1[1](src, src_stride, dst, dst_stride, h_filter, - v_filter + 1, 8); - break; - } - break; - - case 1: - switch (yoffset & 1) { - case 0: - Predict8x8Funcs1[2](src, src_stride, dst, dst_stride, - h_filter + 1, v_filter, 8); - break; - - case 1: - Predict8x8Funcs1[3](src, src_stride, dst, dst_stride, - h_filter + 1, v_filter + 1, 8); - break; - } - break; - } - } else { - switch (yoffset & 1) { - case 0: - Predict8x8Funcs2[0](src, src_stride, dst, dst_stride, v_filter, 8); - break; - - case 1: - Predict8x8Funcs2[1](src, src_stride, dst, dst_stride, v_filter + 1, - 8); - break; - } - } - } else { - switch (xoffset & 1) { - case 1: - Predict8x8Funcs2[3](src, src_stride, dst, dst_stride, h_filter + 1, - 8); - break; - } - switch (xoffset) { - case 0: vp8_copy_mem8x8(src, src_stride, dst, dst_stride); break; - case 2: - case 4: - case 6: - Predict8x8Funcs2[2](src, src_stride, dst, dst_stride, h_filter, 8); - break; - } - } - } -} - -void vp8_sixtap_predict16x16_lsx(uint8_t *RESTRICT src, int32_t src_stride, - int32_t xoffset, int32_t yoffset, - uint8_t *RESTRICT dst, int32_t dst_stride) { - const int8_t *h_filter = vp8_subpel_filters_lsx[xoffset - 1]; - const int8_t *v_filter = vp8_subpel_filters_lsx[yoffset - 1]; - - static PVp8SixtapPredictFunc1 Predict16x16Funcs1[4] = { - common_hv_6ht_6vt_16w_lsx, - common_hv_6ht_4vt_16w_lsx, - common_hv_4ht_6vt_16w_lsx, - common_hv_4ht_4vt_16w_lsx, - }; - - static PVp8SixtapPredictFunc2 Predict16x16Funcs2[4] = { - common_vt_6t_16w_lsx, common_vt_4t_16w_lsx, common_hz_6t_16w_lsx, - common_hz_4t_16w_lsx - }; - - if (yoffset < 8 && xoffset < 8) { - if (yoffset) { - if (xoffset) { - switch (xoffset & 1) { - case 0: - switch (yoffset & 1) { - case 0: - Predict16x16Funcs1[0](src, src_stride, dst, dst_stride, - h_filter, v_filter, 16); - break; - - case 1: - Predict16x16Funcs1[1](src, src_stride, dst, dst_stride, - h_filter, v_filter + 1, 16); - break; - } - break; - - case 1: - switch (yoffset & 1) { - case 0: - Predict16x16Funcs1[2](src, src_stride, dst, dst_stride, - h_filter + 1, v_filter, 16); - break; - - case 1: - Predict16x16Funcs1[3](src, src_stride, dst, dst_stride, - h_filter + 1, v_filter + 1, 16); - break; - } - break; - } - } else { - switch (yoffset & 1) { - case 0: - Predict16x16Funcs2[0](src, src_stride, dst, dst_stride, v_filter, - 16); - break; - - case 1: - Predict16x16Funcs2[1](src, src_stride, dst, dst_stride, - v_filter + 1, 16); - break; - } - } - } else { - switch (xoffset & 1) { - case 1: - Predict16x16Funcs2[3](src, src_stride, dst, dst_stride, h_filter + 1, - 16); - break; - } - switch (xoffset) { - case 0: vp8_copy_mem16x16(src, src_stride, dst, dst_stride); break; - case 2: - case 4: - case 6: - Predict16x16Funcs2[2](src, src_stride, dst, dst_stride, h_filter, 16); - break; - } - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/loopfilter.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/loopfilter.h deleted file mode 100644 index 909e8df5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/loopfilter.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_LOOPFILTER_H_ -#define VPX_VP8_COMMON_LOOPFILTER_H_ - -#include "vpx_ports/mem.h" -#include "vpx_config.h" -#include "vp8_rtcd.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_LOOP_FILTER 63 -/* fraction of total macroblock rows to be used in fast filter level picking */ -/* has to be > 2 */ -#define PARTIAL_FRAME_FRACTION 8 - -typedef enum { NORMAL_LOOPFILTER = 0, SIMPLE_LOOPFILTER = 1 } LOOPFILTERTYPE; - -#if VPX_ARCH_ARM -#define SIMD_WIDTH 1 -#else -#define SIMD_WIDTH 16 -#endif - -/* Need to align this structure so when it is declared and - * passed it can be loaded into vector registers. - */ -typedef struct { - DECLARE_ALIGNED(SIMD_WIDTH, unsigned char, - mblim[MAX_LOOP_FILTER + 1][SIMD_WIDTH]); - DECLARE_ALIGNED(SIMD_WIDTH, unsigned char, - blim[MAX_LOOP_FILTER + 1][SIMD_WIDTH]); - DECLARE_ALIGNED(SIMD_WIDTH, unsigned char, - lim[MAX_LOOP_FILTER + 1][SIMD_WIDTH]); - DECLARE_ALIGNED(SIMD_WIDTH, unsigned char, hev_thr[4][SIMD_WIDTH]); - unsigned char lvl[4][4][4]; - unsigned char hev_thr_lut[2][MAX_LOOP_FILTER + 1]; - unsigned char mode_lf_lut[10]; -} loop_filter_info_n; - -typedef struct loop_filter_info { - const unsigned char *mblim; - const unsigned char *blim; - const unsigned char *lim; - const unsigned char *hev_thr; -} loop_filter_info; - -typedef void loop_filter_uvfunction(unsigned char *u, /* source pointer */ - int p, /* pitch */ - const unsigned char *blimit, - const unsigned char *limit, - const unsigned char *thresh, - unsigned char *v); - -/* assorted loopfilter functions which get used elsewhere */ -struct VP8Common; -struct macroblockd; -struct modeinfo; - -void vp8_loop_filter_init(struct VP8Common *cm); - -void vp8_loop_filter_frame_init(struct VP8Common *cm, struct macroblockd *mbd, - int default_filt_lvl); - -void vp8_loop_filter_frame(struct VP8Common *cm, struct macroblockd *mbd, - int frame_type); - -void vp8_loop_filter_partial_frame(struct VP8Common *cm, - struct macroblockd *mbd, - int default_filt_lvl); - -void vp8_loop_filter_frame_yonly(struct VP8Common *cm, struct macroblockd *mbd, - int default_filt_lvl); - -void vp8_loop_filter_update_sharpness(loop_filter_info_n *lfi, - int sharpness_lvl); - -void vp8_loop_filter_row_normal(struct VP8Common *cm, - struct modeinfo *mode_info_context, int mb_row, - int post_ystride, int post_uvstride, - unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr); - -void vp8_loop_filter_row_simple(struct VP8Common *cm, - struct modeinfo *mode_info_context, int mb_row, - int post_ystride, unsigned char *y_ptr); -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_LOOPFILTER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/loopfilter_filters.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/loopfilter_filters.c deleted file mode 100644 index 61a55d3c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/loopfilter_filters.c +++ /dev/null @@ -1,397 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "loopfilter.h" -#include "onyxc_int.h" - -typedef unsigned char uc; - -static signed char vp8_signed_char_clamp(int t) { - t = (t < -128 ? -128 : t); - t = (t > 127 ? 127 : t); - return (signed char)t; -} - -/* should we apply any filter at all ( 11111111 yes, 00000000 no) */ -static signed char vp8_filter_mask(uc limit, uc blimit, uc p3, uc p2, uc p1, - uc p0, uc q0, uc q1, uc q2, uc q3) { - signed char mask = 0; - mask |= (abs(p3 - p2) > limit); - mask |= (abs(p2 - p1) > limit); - mask |= (abs(p1 - p0) > limit); - mask |= (abs(q1 - q0) > limit); - mask |= (abs(q2 - q1) > limit); - mask |= (abs(q3 - q2) > limit); - mask |= (abs(p0 - q0) * 2 + abs(p1 - q1) / 2 > blimit); - return mask - 1; -} - -/* is there high variance internal edge ( 11111111 yes, 00000000 no) */ -static signed char vp8_hevmask(uc thresh, uc p1, uc p0, uc q0, uc q1) { - signed char hev = 0; - hev |= (abs(p1 - p0) > thresh) * -1; - hev |= (abs(q1 - q0) > thresh) * -1; - return hev; -} - -static void vp8_filter(signed char mask, uc hev, uc *op1, uc *op0, uc *oq0, - uc *oq1) { - signed char ps0, qs0; - signed char ps1, qs1; - signed char filter_value, Filter1, Filter2; - signed char u; - - ps1 = (signed char)*op1 ^ 0x80; - ps0 = (signed char)*op0 ^ 0x80; - qs0 = (signed char)*oq0 ^ 0x80; - qs1 = (signed char)*oq1 ^ 0x80; - - /* add outer taps if we have high edge variance */ - filter_value = vp8_signed_char_clamp(ps1 - qs1); - filter_value &= hev; - - /* inner taps */ - filter_value = vp8_signed_char_clamp(filter_value + 3 * (qs0 - ps0)); - filter_value &= mask; - - /* save bottom 3 bits so that we round one side +4 and the other +3 - * if it equals 4 we'll set it to adjust by -1 to account for the fact - * we'd round it by 3 the other way - */ - Filter1 = vp8_signed_char_clamp(filter_value + 4); - Filter2 = vp8_signed_char_clamp(filter_value + 3); - Filter1 >>= 3; - Filter2 >>= 3; - u = vp8_signed_char_clamp(qs0 - Filter1); - *oq0 = u ^ 0x80; - u = vp8_signed_char_clamp(ps0 + Filter2); - *op0 = u ^ 0x80; - filter_value = Filter1; - - /* outer tap adjustments */ - filter_value += 1; - filter_value >>= 1; - filter_value &= ~hev; - - u = vp8_signed_char_clamp(qs1 - filter_value); - *oq1 = u ^ 0x80; - u = vp8_signed_char_clamp(ps1 + filter_value); - *op1 = u ^ 0x80; -} - -static void loop_filter_horizontal_edge_c(unsigned char *s, int p, /* pitch */ - const unsigned char *blimit, - const unsigned char *limit, - const unsigned char *thresh, - int count) { - int hev = 0; /* high edge variance */ - signed char mask = 0; - int i = 0; - - /* loop filter designed to work using chars so that we can make maximum use - * of 8 bit simd instructions. - */ - do { - mask = vp8_filter_mask(limit[0], blimit[0], s[-4 * p], s[-3 * p], s[-2 * p], - s[-1 * p], s[0 * p], s[1 * p], s[2 * p], s[3 * p]); - - hev = vp8_hevmask(thresh[0], s[-2 * p], s[-1 * p], s[0 * p], s[1 * p]); - - vp8_filter(mask, hev, s - 2 * p, s - 1 * p, s, s + 1 * p); - - ++s; - } while (++i < count * 8); -} - -static void loop_filter_vertical_edge_c(unsigned char *s, int p, - const unsigned char *blimit, - const unsigned char *limit, - const unsigned char *thresh, - int count) { - int hev = 0; /* high edge variance */ - signed char mask = 0; - int i = 0; - - /* loop filter designed to work using chars so that we can make maximum use - * of 8 bit simd instructions. - */ - do { - mask = vp8_filter_mask(limit[0], blimit[0], s[-4], s[-3], s[-2], s[-1], - s[0], s[1], s[2], s[3]); - - hev = vp8_hevmask(thresh[0], s[-2], s[-1], s[0], s[1]); - - vp8_filter(mask, hev, s - 2, s - 1, s, s + 1); - - s += p; - } while (++i < count * 8); -} - -static void vp8_mbfilter(signed char mask, uc hev, uc *op2, uc *op1, uc *op0, - uc *oq0, uc *oq1, uc *oq2) { - signed char s, u; - signed char filter_value, Filter1, Filter2; - signed char ps2 = (signed char)*op2 ^ 0x80; - signed char ps1 = (signed char)*op1 ^ 0x80; - signed char ps0 = (signed char)*op0 ^ 0x80; - signed char qs0 = (signed char)*oq0 ^ 0x80; - signed char qs1 = (signed char)*oq1 ^ 0x80; - signed char qs2 = (signed char)*oq2 ^ 0x80; - - /* add outer taps if we have high edge variance */ - filter_value = vp8_signed_char_clamp(ps1 - qs1); - filter_value = vp8_signed_char_clamp(filter_value + 3 * (qs0 - ps0)); - filter_value &= mask; - - Filter2 = filter_value; - Filter2 &= hev; - - /* save bottom 3 bits so that we round one side +4 and the other +3 */ - Filter1 = vp8_signed_char_clamp(Filter2 + 4); - Filter2 = vp8_signed_char_clamp(Filter2 + 3); - Filter1 >>= 3; - Filter2 >>= 3; - qs0 = vp8_signed_char_clamp(qs0 - Filter1); - ps0 = vp8_signed_char_clamp(ps0 + Filter2); - - /* only apply wider filter if not high edge variance */ - filter_value &= ~hev; - Filter2 = filter_value; - - /* roughly 3/7th difference across boundary */ - u = vp8_signed_char_clamp((63 + Filter2 * 27) >> 7); - s = vp8_signed_char_clamp(qs0 - u); - *oq0 = s ^ 0x80; - s = vp8_signed_char_clamp(ps0 + u); - *op0 = s ^ 0x80; - - /* roughly 2/7th difference across boundary */ - u = vp8_signed_char_clamp((63 + Filter2 * 18) >> 7); - s = vp8_signed_char_clamp(qs1 - u); - *oq1 = s ^ 0x80; - s = vp8_signed_char_clamp(ps1 + u); - *op1 = s ^ 0x80; - - /* roughly 1/7th difference across boundary */ - u = vp8_signed_char_clamp((63 + Filter2 * 9) >> 7); - s = vp8_signed_char_clamp(qs2 - u); - *oq2 = s ^ 0x80; - s = vp8_signed_char_clamp(ps2 + u); - *op2 = s ^ 0x80; -} - -static void mbloop_filter_horizontal_edge_c(unsigned char *s, int p, - const unsigned char *blimit, - const unsigned char *limit, - const unsigned char *thresh, - int count) { - signed char hev = 0; /* high edge variance */ - signed char mask = 0; - int i = 0; - - /* loop filter designed to work using chars so that we can make maximum use - * of 8 bit simd instructions. - */ - do { - mask = vp8_filter_mask(limit[0], blimit[0], s[-4 * p], s[-3 * p], s[-2 * p], - s[-1 * p], s[0 * p], s[1 * p], s[2 * p], s[3 * p]); - - hev = vp8_hevmask(thresh[0], s[-2 * p], s[-1 * p], s[0 * p], s[1 * p]); - - vp8_mbfilter(mask, hev, s - 3 * p, s - 2 * p, s - 1 * p, s, s + 1 * p, - s + 2 * p); - - ++s; - } while (++i < count * 8); -} - -static void mbloop_filter_vertical_edge_c(unsigned char *s, int p, - const unsigned char *blimit, - const unsigned char *limit, - const unsigned char *thresh, - int count) { - signed char hev = 0; /* high edge variance */ - signed char mask = 0; - int i = 0; - - do { - mask = vp8_filter_mask(limit[0], blimit[0], s[-4], s[-3], s[-2], s[-1], - s[0], s[1], s[2], s[3]); - - hev = vp8_hevmask(thresh[0], s[-2], s[-1], s[0], s[1]); - - vp8_mbfilter(mask, hev, s - 3, s - 2, s - 1, s, s + 1, s + 2); - - s += p; - } while (++i < count * 8); -} - -/* should we apply any filter at all ( 11111111 yes, 00000000 no) */ -static signed char vp8_simple_filter_mask(uc blimit, uc p1, uc p0, uc q0, - uc q1) { - /* Why does this cause problems for win32? - * error C2143: syntax error : missing ';' before 'type' - * (void) limit; - */ - signed char mask = (abs(p0 - q0) * 2 + abs(p1 - q1) / 2 <= blimit) * -1; - return mask; -} - -static void vp8_simple_filter(signed char mask, uc *op1, uc *op0, uc *oq0, - uc *oq1) { - signed char filter_value, Filter1, Filter2; - signed char p1 = (signed char)*op1 ^ 0x80; - signed char p0 = (signed char)*op0 ^ 0x80; - signed char q0 = (signed char)*oq0 ^ 0x80; - signed char q1 = (signed char)*oq1 ^ 0x80; - signed char u; - - filter_value = vp8_signed_char_clamp(p1 - q1); - filter_value = vp8_signed_char_clamp(filter_value + 3 * (q0 - p0)); - filter_value &= mask; - - /* save bottom 3 bits so that we round one side +4 and the other +3 */ - Filter1 = vp8_signed_char_clamp(filter_value + 4); - Filter1 >>= 3; - u = vp8_signed_char_clamp(q0 - Filter1); - *oq0 = u ^ 0x80; - - Filter2 = vp8_signed_char_clamp(filter_value + 3); - Filter2 >>= 3; - u = vp8_signed_char_clamp(p0 + Filter2); - *op0 = u ^ 0x80; -} - -void vp8_loop_filter_simple_horizontal_edge_c(unsigned char *y_ptr, - int y_stride, - const unsigned char *blimit) { - signed char mask = 0; - int i = 0; - - do { - mask = vp8_simple_filter_mask(blimit[0], y_ptr[-2 * y_stride], - y_ptr[-1 * y_stride], y_ptr[0 * y_stride], - y_ptr[1 * y_stride]); - vp8_simple_filter(mask, y_ptr - 2 * y_stride, y_ptr - 1 * y_stride, y_ptr, - y_ptr + 1 * y_stride); - ++y_ptr; - } while (++i < 16); -} - -void vp8_loop_filter_simple_vertical_edge_c(unsigned char *y_ptr, int y_stride, - const unsigned char *blimit) { - signed char mask = 0; - int i = 0; - - do { - mask = vp8_simple_filter_mask(blimit[0], y_ptr[-2], y_ptr[-1], y_ptr[0], - y_ptr[1]); - vp8_simple_filter(mask, y_ptr - 2, y_ptr - 1, y_ptr, y_ptr + 1); - y_ptr += y_stride; - } while (++i < 16); -} - -/* Horizontal MB filtering */ -void vp8_loop_filter_mbh_c(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { - mbloop_filter_horizontal_edge_c(y_ptr, y_stride, lfi->mblim, lfi->lim, - lfi->hev_thr, 2); - - if (u_ptr) { - mbloop_filter_horizontal_edge_c(u_ptr, uv_stride, lfi->mblim, lfi->lim, - lfi->hev_thr, 1); - } - - if (v_ptr) { - mbloop_filter_horizontal_edge_c(v_ptr, uv_stride, lfi->mblim, lfi->lim, - lfi->hev_thr, 1); - } -} - -/* Vertical MB Filtering */ -void vp8_loop_filter_mbv_c(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { - mbloop_filter_vertical_edge_c(y_ptr, y_stride, lfi->mblim, lfi->lim, - lfi->hev_thr, 2); - - if (u_ptr) { - mbloop_filter_vertical_edge_c(u_ptr, uv_stride, lfi->mblim, lfi->lim, - lfi->hev_thr, 1); - } - - if (v_ptr) { - mbloop_filter_vertical_edge_c(v_ptr, uv_stride, lfi->mblim, lfi->lim, - lfi->hev_thr, 1); - } -} - -/* Horizontal B Filtering */ -void vp8_loop_filter_bh_c(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { - loop_filter_horizontal_edge_c(y_ptr + 4 * y_stride, y_stride, lfi->blim, - lfi->lim, lfi->hev_thr, 2); - loop_filter_horizontal_edge_c(y_ptr + 8 * y_stride, y_stride, lfi->blim, - lfi->lim, lfi->hev_thr, 2); - loop_filter_horizontal_edge_c(y_ptr + 12 * y_stride, y_stride, lfi->blim, - lfi->lim, lfi->hev_thr, 2); - - if (u_ptr) { - loop_filter_horizontal_edge_c(u_ptr + 4 * uv_stride, uv_stride, lfi->blim, - lfi->lim, lfi->hev_thr, 1); - } - - if (v_ptr) { - loop_filter_horizontal_edge_c(v_ptr + 4 * uv_stride, uv_stride, lfi->blim, - lfi->lim, lfi->hev_thr, 1); - } -} - -void vp8_loop_filter_bhs_c(unsigned char *y_ptr, int y_stride, - const unsigned char *blimit) { - vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 4 * y_stride, y_stride, - blimit); - vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 8 * y_stride, y_stride, - blimit); - vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 12 * y_stride, y_stride, - blimit); -} - -/* Vertical B Filtering */ -void vp8_loop_filter_bv_c(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { - loop_filter_vertical_edge_c(y_ptr + 4, y_stride, lfi->blim, lfi->lim, - lfi->hev_thr, 2); - loop_filter_vertical_edge_c(y_ptr + 8, y_stride, lfi->blim, lfi->lim, - lfi->hev_thr, 2); - loop_filter_vertical_edge_c(y_ptr + 12, y_stride, lfi->blim, lfi->lim, - lfi->hev_thr, 2); - - if (u_ptr) { - loop_filter_vertical_edge_c(u_ptr + 4, uv_stride, lfi->blim, lfi->lim, - lfi->hev_thr, 1); - } - - if (v_ptr) { - loop_filter_vertical_edge_c(v_ptr + 4, uv_stride, lfi->blim, lfi->lim, - lfi->hev_thr, 1); - } -} - -void vp8_loop_filter_bvs_c(unsigned char *y_ptr, int y_stride, - const unsigned char *blimit) { - vp8_loop_filter_simple_vertical_edge_c(y_ptr + 4, y_stride, blimit); - vp8_loop_filter_simple_vertical_edge_c(y_ptr + 8, y_stride, blimit); - vp8_loop_filter_simple_vertical_edge_c(y_ptr + 12, y_stride, blimit); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mbpitch.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mbpitch.c deleted file mode 100644 index 188b57f3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mbpitch.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "blockd.h" - -void vp8_setup_block_dptrs(MACROBLOCKD *x) { - int r, c; - - for (r = 0; r < 4; ++r) { - for (c = 0; c < 4; ++c) { - x->block[r * 4 + c].predictor = x->predictor + r * 4 * 16 + c * 4; - } - } - - for (r = 0; r < 2; ++r) { - for (c = 0; c < 2; ++c) { - x->block[16 + r * 2 + c].predictor = - x->predictor + 256 + r * 4 * 8 + c * 4; - } - } - - for (r = 0; r < 2; ++r) { - for (c = 0; c < 2; ++c) { - x->block[20 + r * 2 + c].predictor = - x->predictor + 320 + r * 4 * 8 + c * 4; - } - } - - for (r = 0; r < 25; ++r) { - x->block[r].qcoeff = x->qcoeff + r * 16; - x->block[r].dqcoeff = x->dqcoeff + r * 16; - x->block[r].eob = x->eobs + r; - } -} - -void vp8_build_block_doffsets(MACROBLOCKD *x) { - int block; - - for (block = 0; block < 16; ++block) /* y blocks */ - { - x->block[block].offset = - (block >> 2) * 4 * x->dst.y_stride + (block & 3) * 4; - } - - for (block = 16; block < 20; ++block) /* U and V blocks */ - { - x->block[block + 4].offset = x->block[block].offset = - ((block - 16) >> 1) * 4 * x->dst.uv_stride + (block & 1) * 4; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mfqe.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mfqe.c deleted file mode 100644 index 1fe7363f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mfqe.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* MFQE: Multiframe Quality Enhancement - * In rate limited situations keyframes may cause significant visual artifacts - * commonly referred to as "popping." This file implements a postproccesing - * algorithm which blends data from the preceeding frame when there is no - * motion and the q from the previous frame is lower which indicates that it is - * higher quality. - */ - -#include "./vp8_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "vp8/common/common.h" -#include "vp8/common/postproc.h" -#include "vpx_dsp/variance.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_scale/yv12config.h" - -#include -#include - -static void filter_by_weight(unsigned char *src, int src_stride, - unsigned char *dst, int dst_stride, int block_size, - int src_weight) { - int dst_weight = (1 << MFQE_PRECISION) - src_weight; - int rounding_bit = 1 << (MFQE_PRECISION - 1); - int r, c; - - for (r = 0; r < block_size; ++r) { - for (c = 0; c < block_size; ++c) { - dst[c] = (src[c] * src_weight + dst[c] * dst_weight + rounding_bit) >> - MFQE_PRECISION; - } - src += src_stride; - dst += dst_stride; - } -} - -void vp8_filter_by_weight16x16_c(unsigned char *src, int src_stride, - unsigned char *dst, int dst_stride, - int src_weight) { - filter_by_weight(src, src_stride, dst, dst_stride, 16, src_weight); -} - -void vp8_filter_by_weight8x8_c(unsigned char *src, int src_stride, - unsigned char *dst, int dst_stride, - int src_weight) { - filter_by_weight(src, src_stride, dst, dst_stride, 8, src_weight); -} - -void vp8_filter_by_weight4x4_c(unsigned char *src, int src_stride, - unsigned char *dst, int dst_stride, - int src_weight) { - filter_by_weight(src, src_stride, dst, dst_stride, 4, src_weight); -} - -static void apply_ifactor(unsigned char *y_src, int y_src_stride, - unsigned char *y_dst, int y_dst_stride, - unsigned char *u_src, unsigned char *v_src, - int uv_src_stride, unsigned char *u_dst, - unsigned char *v_dst, int uv_dst_stride, - int block_size, int src_weight) { - if (block_size == 16) { - vp8_filter_by_weight16x16(y_src, y_src_stride, y_dst, y_dst_stride, - src_weight); - vp8_filter_by_weight8x8(u_src, uv_src_stride, u_dst, uv_dst_stride, - src_weight); - vp8_filter_by_weight8x8(v_src, uv_src_stride, v_dst, uv_dst_stride, - src_weight); - } else { - vp8_filter_by_weight8x8(y_src, y_src_stride, y_dst, y_dst_stride, - src_weight); - vp8_filter_by_weight4x4(u_src, uv_src_stride, u_dst, uv_dst_stride, - src_weight); - vp8_filter_by_weight4x4(v_src, uv_src_stride, v_dst, uv_dst_stride, - src_weight); - } -} - -static unsigned int int_sqrt(unsigned int x) { - unsigned int y = x; - unsigned int guess; - int p = 1; - while (y >>= 1) p++; - p >>= 1; - - guess = 0; - while (p >= 0) { - guess |= (1 << p); - if (x < guess * guess) guess -= (1 << p); - p--; - } - /* choose between guess or guess+1 */ - return guess + (guess * guess + guess + 1 <= x); -} - -#define USE_SSD -static void multiframe_quality_enhance_block( - int blksize, /* Currently only values supported are 16, 8 */ - int qcurr, int qprev, unsigned char *y, unsigned char *u, unsigned char *v, - int y_stride, int uv_stride, unsigned char *yd, unsigned char *ud, - unsigned char *vd, int yd_stride, int uvd_stride) { - static const unsigned char VP8_ZEROS[16] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 }; - int uvblksize = blksize >> 1; - int qdiff = qcurr - qprev; - - int i; - unsigned char *up; - unsigned char *udp; - unsigned char *vp; - unsigned char *vdp; - - unsigned int act, actd, sad, usad, vsad, sse, thr, thrsq, actrisk; - - if (blksize == 16) { - actd = (vpx_variance16x16(yd, yd_stride, VP8_ZEROS, 0, &sse) + 128) >> 8; - act = (vpx_variance16x16(y, y_stride, VP8_ZEROS, 0, &sse) + 128) >> 8; -#ifdef USE_SSD - vpx_variance16x16(y, y_stride, yd, yd_stride, &sse); - sad = (sse + 128) >> 8; - vpx_variance8x8(u, uv_stride, ud, uvd_stride, &sse); - usad = (sse + 32) >> 6; - vpx_variance8x8(v, uv_stride, vd, uvd_stride, &sse); - vsad = (sse + 32) >> 6; -#else - sad = (vpx_sad16x16(y, y_stride, yd, yd_stride) + 128) >> 8; - usad = (vpx_sad8x8(u, uv_stride, ud, uvd_stride) + 32) >> 6; - vsad = (vpx_sad8x8(v, uv_stride, vd, uvd_stride) + 32) >> 6; -#endif - } else { - actd = (vpx_variance8x8(yd, yd_stride, VP8_ZEROS, 0, &sse) + 32) >> 6; - act = (vpx_variance8x8(y, y_stride, VP8_ZEROS, 0, &sse) + 32) >> 6; -#ifdef USE_SSD - vpx_variance8x8(y, y_stride, yd, yd_stride, &sse); - sad = (sse + 32) >> 6; - vpx_variance4x4(u, uv_stride, ud, uvd_stride, &sse); - usad = (sse + 8) >> 4; - vpx_variance4x4(v, uv_stride, vd, uvd_stride, &sse); - vsad = (sse + 8) >> 4; -#else - sad = (vpx_sad8x8(y, y_stride, yd, yd_stride) + 32) >> 6; - usad = (vpx_sad4x4(u, uv_stride, ud, uvd_stride) + 8) >> 4; - vsad = (vpx_sad4x4(v, uv_stride, vd, uvd_stride) + 8) >> 4; -#endif - } - - actrisk = (actd > act * 5); - - /* thr = qdiff/16 + log2(act) + log4(qprev) */ - thr = (qdiff >> 4); - while (actd >>= 1) thr++; - while (qprev >>= 2) thr++; - -#ifdef USE_SSD - thrsq = thr * thr; - if (sad < thrsq && - /* additional checks for color mismatch and excessive addition of - * high-frequencies */ - 4 * usad < thrsq && 4 * vsad < thrsq && !actrisk) -#else - if (sad < thr && - /* additional checks for color mismatch and excessive addition of - * high-frequencies */ - 2 * usad < thr && 2 * vsad < thr && !actrisk) -#endif - { - int ifactor; -#ifdef USE_SSD - /* TODO: optimize this later to not need sqr root */ - sad = int_sqrt(sad); -#endif - ifactor = (sad << MFQE_PRECISION) / thr; - ifactor >>= (qdiff >> 5); - - if (ifactor) { - apply_ifactor(y, y_stride, yd, yd_stride, u, v, uv_stride, ud, vd, - uvd_stride, blksize, ifactor); - } - } else { /* else implicitly copy from previous frame */ - if (blksize == 16) { - vp8_copy_mem16x16(y, y_stride, yd, yd_stride); - vp8_copy_mem8x8(u, uv_stride, ud, uvd_stride); - vp8_copy_mem8x8(v, uv_stride, vd, uvd_stride); - } else { - vp8_copy_mem8x8(y, y_stride, yd, yd_stride); - for (up = u, udp = ud, i = 0; i < uvblksize; - ++i, up += uv_stride, udp += uvd_stride) { - memcpy(udp, up, uvblksize); - } - for (vp = v, vdp = vd, i = 0; i < uvblksize; - ++i, vp += uv_stride, vdp += uvd_stride) { - memcpy(vdp, vp, uvblksize); - } - } - } -} - -static int qualify_inter_mb(const MODE_INFO *mode_info_context, int *map) { - if (mode_info_context->mbmi.mb_skip_coeff) { - map[0] = map[1] = map[2] = map[3] = 1; - } else if (mode_info_context->mbmi.mode == SPLITMV) { - static int ndx[4][4] = { - { 0, 1, 4, 5 }, { 2, 3, 6, 7 }, { 8, 9, 12, 13 }, { 10, 11, 14, 15 } - }; - int i, j; - vp8_zero(*map); - for (i = 0; i < 4; ++i) { - map[i] = 1; - for (j = 0; j < 4 && map[j]; ++j) { - map[i] &= (mode_info_context->bmi[ndx[i][j]].mv.as_mv.row <= 2 && - mode_info_context->bmi[ndx[i][j]].mv.as_mv.col <= 2); - } - } - } else { - map[0] = map[1] = map[2] = map[3] = - (mode_info_context->mbmi.mode > B_PRED && - abs(mode_info_context->mbmi.mv.as_mv.row) <= 2 && - abs(mode_info_context->mbmi.mv.as_mv.col) <= 2); - } - return (map[0] + map[1] + map[2] + map[3]); -} - -void vp8_multiframe_quality_enhance(VP8_COMMON *cm) { - YV12_BUFFER_CONFIG *show = cm->frame_to_show; - YV12_BUFFER_CONFIG *dest = &cm->post_proc_buffer; - - FRAME_TYPE frame_type = cm->frame_type; - /* Point at base of Mb MODE_INFO list has motion vectors etc */ - const MODE_INFO *mode_info_context = cm->mi; - int mb_row; - int mb_col; - int totmap, map[4]; - int qcurr = cm->base_qindex; - int qprev = cm->postproc_state.last_base_qindex; - - unsigned char *y_ptr, *u_ptr, *v_ptr; - unsigned char *yd_ptr, *ud_ptr, *vd_ptr; - - /* Set up the buffer pointers */ - y_ptr = show->y_buffer; - u_ptr = show->u_buffer; - v_ptr = show->v_buffer; - yd_ptr = dest->y_buffer; - ud_ptr = dest->u_buffer; - vd_ptr = dest->v_buffer; - - /* postprocess each macro block */ - for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) { - for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) { - /* if motion is high there will likely be no benefit */ - if (frame_type == INTER_FRAME) { - totmap = qualify_inter_mb(mode_info_context, map); - } else { - totmap = (frame_type == KEY_FRAME ? 4 : 0); - } - if (totmap) { - if (totmap < 4) { - int i, j; - for (i = 0; i < 2; ++i) { - for (j = 0; j < 2; ++j) { - if (map[i * 2 + j]) { - multiframe_quality_enhance_block( - 8, qcurr, qprev, y_ptr + 8 * (i * show->y_stride + j), - u_ptr + 4 * (i * show->uv_stride + j), - v_ptr + 4 * (i * show->uv_stride + j), show->y_stride, - show->uv_stride, yd_ptr + 8 * (i * dest->y_stride + j), - ud_ptr + 4 * (i * dest->uv_stride + j), - vd_ptr + 4 * (i * dest->uv_stride + j), dest->y_stride, - dest->uv_stride); - } else { - /* copy a 8x8 block */ - int k; - unsigned char *up = u_ptr + 4 * (i * show->uv_stride + j); - unsigned char *udp = ud_ptr + 4 * (i * dest->uv_stride + j); - unsigned char *vp = v_ptr + 4 * (i * show->uv_stride + j); - unsigned char *vdp = vd_ptr + 4 * (i * dest->uv_stride + j); - vp8_copy_mem8x8( - y_ptr + 8 * (i * show->y_stride + j), show->y_stride, - yd_ptr + 8 * (i * dest->y_stride + j), dest->y_stride); - for (k = 0; k < 4; ++k, up += show->uv_stride, - udp += dest->uv_stride, vp += show->uv_stride, - vdp += dest->uv_stride) { - memcpy(udp, up, 4); - memcpy(vdp, vp, 4); - } - } - } - } - } else { /* totmap = 4 */ - multiframe_quality_enhance_block( - 16, qcurr, qprev, y_ptr, u_ptr, v_ptr, show->y_stride, - show->uv_stride, yd_ptr, ud_ptr, vd_ptr, dest->y_stride, - dest->uv_stride); - } - } else { - vp8_copy_mem16x16(y_ptr, show->y_stride, yd_ptr, dest->y_stride); - vp8_copy_mem8x8(u_ptr, show->uv_stride, ud_ptr, dest->uv_stride); - vp8_copy_mem8x8(v_ptr, show->uv_stride, vd_ptr, dest->uv_stride); - } - y_ptr += 16; - u_ptr += 8; - v_ptr += 8; - yd_ptr += 16; - ud_ptr += 8; - vd_ptr += 8; - mode_info_context++; /* step to next MB */ - } - - y_ptr += show->y_stride * 16 - 16 * cm->mb_cols; - u_ptr += show->uv_stride * 8 - 8 * cm->mb_cols; - v_ptr += show->uv_stride * 8 - 8 * cm->mb_cols; - yd_ptr += dest->y_stride * 16 - 16 * cm->mb_cols; - ud_ptr += dest->uv_stride * 8 - 8 * cm->mb_cols; - vd_ptr += dest->uv_stride * 8 - 8 * cm->mb_cols; - - mode_info_context++; /* Skip border mb */ - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/dequantize_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/dequantize_dspr2.c deleted file mode 100644 index 1cfd1461..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/dequantize_dspr2.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "vp8_rtcd.h" -#include "vpx_mem/vpx_mem.h" - -#if HAVE_DSPR2 -void vp8_dequant_idct_add_dspr2(short *input, short *dq, unsigned char *dest, - int stride) { - int i; - - for (i = 0; i < 16; ++i) { - input[i] = dq[i] * input[i]; - } - - vp8_short_idct4x4llm_dspr2(input, dest, stride, dest, stride); - - memset(input, 0, 32); -} - -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/filter_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/filter_dspr2.c deleted file mode 100644 index b9da5208..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/filter_dspr2.c +++ /dev/null @@ -1,2767 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "vp8_rtcd.h" -#include "vpx_ports/mem.h" - -#if HAVE_DSPR2 -#define CROP_WIDTH 256 -unsigned char ff_cropTbl[256 + 2 * CROP_WIDTH]; - -static const unsigned short sub_pel_filterss[8][3] = { - { 0, 0, 0 }, - { 0, 0x0601, 0x7b0c }, - { 0x0201, 0x0b08, 0x6c24 }, - { 0, 0x0906, 0x5d32 }, - { 0x0303, 0x1010, 0x4d4d }, - { 0, 0x0609, 0x325d }, - { 0x0102, 0x080b, 0x246c }, - { 0, 0x0106, 0x0c7b }, -}; - -static const int sub_pel_filters_int[8][3] = { - { 0, 0, 0 }, - { 0x0000fffa, 0x007b000c, 0xffff0000 }, - { 0x0002fff5, 0x006c0024, 0xfff80001 }, - { 0x0000fff7, 0x005d0032, 0xfffa0000 }, - { 0x0003fff0, 0x004d004d, 0xfff00003 }, - { 0x0000fffa, 0x0032005d, 0xfff70000 }, - { 0x0001fff8, 0x0024006c, 0xfff50002 }, - { 0x0000ffff, 0x000c007b, 0xfffa0000 }, -}; - -static const int sub_pel_filters_inv[8][3] = { - { 0, 0, 0 }, - { 0xfffa0000, 0x000c007b, 0x0000ffff }, - { 0xfff50002, 0x0024006c, 0x0001fff8 }, - { 0xfff70000, 0x0032005d, 0x0000fffa }, - { 0xfff00003, 0x004d004d, 0x0003fff0 }, - { 0xfffa0000, 0x005d0032, 0x0000fff7 }, - { 0xfff80001, 0x006c0024, 0x0002fff5 }, - { 0xffff0000, 0x007b000c, 0x0000fffa }, -}; - -/* clang-format off */ -static const int sub_pel_filters_int_tap_4[8][2] = { - { 0, 0}, - { 0xfffa007b, 0x000cffff}, - { 0, 0}, - { 0xfff7005d, 0x0032fffa}, - { 0, 0}, - { 0xfffa0032, 0x005dfff7}, - { 0, 0}, - { 0xffff000c, 0x007bfffa}, -}; - - -static const int sub_pel_filters_inv_tap_4[8][2] = { - { 0, 0}, - { 0x007bfffa, 0xffff000c}, - { 0, 0}, - { 0x005dfff7, 0xfffa0032}, - { 0, 0}, - { 0x0032fffa, 0xfff7005d}, - { 0, 0}, - { 0x000cffff, 0xfffa007b}, -}; -/* clang-format on */ - -inline void prefetch_load(unsigned char *src) { - __asm__ __volatile__("pref 0, 0(%[src]) \n\t" : : [src] "r"(src)); -} - -inline void prefetch_store(unsigned char *dst) { - __asm__ __volatile__("pref 1, 0(%[dst]) \n\t" : : [dst] "r"(dst)); -} - -void dsputil_static_init(void) { - int i; - - for (i = 0; i < 256; ++i) ff_cropTbl[i + CROP_WIDTH] = i; - - for (i = 0; i < CROP_WIDTH; ++i) { - ff_cropTbl[i] = 0; - ff_cropTbl[i + CROP_WIDTH + 256] = 255; - } -} - -void vp8_filter_block2d_first_pass_4(unsigned char *RESTRICT src_ptr, - unsigned char *RESTRICT dst_ptr, - unsigned int src_pixels_per_line, - unsigned int output_height, int xoffset, - int pitch) { - unsigned int i; - int Temp1, Temp2, Temp3, Temp4; - - unsigned int vector4a = 64; - int vector1b, vector2b, vector3b; - unsigned int tp1, tp2, tn1, tn2; - unsigned int p1, p2, p3; - unsigned int n1, n2, n3; - unsigned char *cm = ff_cropTbl + CROP_WIDTH; - - vector3b = sub_pel_filters_inv[xoffset][2]; - - /* if (xoffset == 0) we don't need any filtering */ - if (vector3b == 0) { - for (i = 0; i < output_height; ++i) { - /* prefetch src_ptr data to cache memory */ - prefetch_load(src_ptr + src_pixels_per_line); - dst_ptr[0] = src_ptr[0]; - dst_ptr[1] = src_ptr[1]; - dst_ptr[2] = src_ptr[2]; - dst_ptr[3] = src_ptr[3]; - - /* next row... */ - src_ptr += src_pixels_per_line; - dst_ptr += 4; - } - } else { - if (vector3b > 65536) { - /* 6 tap filter */ - - vector1b = sub_pel_filters_inv[xoffset][0]; - vector2b = sub_pel_filters_inv[xoffset][1]; - - /* prefetch src_ptr data to cache memory */ - prefetch_load(src_ptr + src_pixels_per_line); - - for (i = output_height; i--;) { - /* apply filter with vectors pairs */ - __asm__ __volatile__( - "ulw %[tp1], -2(%[src_ptr]) \n\t" - "ulw %[tp2], 2(%[src_ptr]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[p1], %[tp1] \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "preceu.ph.qbr %[p3], %[tp2] \n\t" - "dpa.w.ph $ac3, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p3], %[vector3b] \n\t" - - /* even 2. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbl %[p1], %[tp2] \n\t" - "balign %[tp2], %[tp1], 3 \n\t" - "extp %[Temp1], $ac3, 9 \n\t" - "dpa.w.ph $ac2, %[p2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p3], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector3b] \n\t" - - /* odd 1. pixel */ - "ulw %[tn2], 3(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[n1], %[tp2] \n\t" - "preceu.ph.qbl %[n2], %[tp2] \n\t" - "preceu.ph.qbr %[n3], %[tn2] \n\t" - "extp %[Temp3], $ac2, 9 \n\t" - "dpa.w.ph $ac3, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[n3], %[vector3b] \n\t" - - /* even 2. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbl %[n1], %[tn2] \n\t" - "extp %[Temp2], $ac3, 9 \n\t" - "dpa.w.ph $ac2, %[n2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[n3], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[n1], %[vector3b] \n\t" - "extp %[Temp4], $ac2, 9 \n\t" - - /* clamp */ - "lbux %[tp1], %[Temp1](%[cm]) \n\t" - "lbux %[tn1], %[Temp2](%[cm]) \n\t" - "lbux %[tp2], %[Temp3](%[cm]) \n\t" - "lbux %[n2], %[Temp4](%[cm]) \n\t" - - /* store bytes */ - "sb %[tp1], 0(%[dst_ptr]) \n\t" - "sb %[tn1], 1(%[dst_ptr]) \n\t" - "sb %[tp2], 2(%[dst_ptr]) \n\t" - "sb %[n2], 3(%[dst_ptr]) \n\t" - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tn1] "=&r"(tn1), - [tn2] "=&r"(tn2), [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), - [n1] "=&r"(n1), [n2] "=&r"(n2), [n3] "=&r"(n3), - [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [Temp4] "=&r"(Temp4) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector4a] "r"(vector4a), [cm] "r"(cm), [dst_ptr] "r"(dst_ptr), - [vector3b] "r"(vector3b), [src_ptr] "r"(src_ptr)); - - /* Next row... */ - src_ptr += src_pixels_per_line; - dst_ptr += pitch; - } - } else { - /* 4 tap filter */ - - vector1b = sub_pel_filters_inv_tap_4[xoffset][0]; - vector2b = sub_pel_filters_inv_tap_4[xoffset][1]; - - for (i = output_height; i--;) { - /* apply filter with vectors pairs */ - __asm__ __volatile__( - "ulw %[tp1], -1(%[src_ptr]) \n\t" - "ulw %[tp2], 3(%[src_ptr]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[p1], %[tp1] \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "preceu.ph.qbr %[p3], %[tp2] \n\t" - "dpa.w.ph $ac3, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p2], %[vector2b] \n\t" - - /* even 2. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "dpa.w.ph $ac2, %[p2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p3], %[vector2b] \n\t" - "extp %[Temp1], $ac3, 9 \n\t" - - /* odd 1. pixel */ - "srl %[tn1], %[tp2], 8 \n\t" - "balign %[tp2], %[tp1], 3 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[n1], %[tp2] \n\t" - "preceu.ph.qbl %[n2], %[tp2] \n\t" - "preceu.ph.qbr %[n3], %[tn1] \n\t" - "extp %[Temp3], $ac2, 9 \n\t" - "dpa.w.ph $ac3, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector2b] \n\t" - - /* odd 2. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "extp %[Temp2], $ac3, 9 \n\t" - "dpa.w.ph $ac2, %[n2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[n3], %[vector2b] \n\t" - "extp %[Temp4], $ac2, 9 \n\t" - - /* clamp and store results */ - "lbux %[tp1], %[Temp1](%[cm]) \n\t" - "lbux %[tn1], %[Temp2](%[cm]) \n\t" - "lbux %[tp2], %[Temp3](%[cm]) \n\t" - "sb %[tp1], 0(%[dst_ptr]) \n\t" - "sb %[tn1], 1(%[dst_ptr]) \n\t" - "lbux %[n2], %[Temp4](%[cm]) \n\t" - "sb %[tp2], 2(%[dst_ptr]) \n\t" - "sb %[n2], 3(%[dst_ptr]) \n\t" - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tn1] "=&r"(tn1), - [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), [n1] "=&r"(n1), - [n2] "=&r"(n2), [n3] "=&r"(n3), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), [Temp4] "=&r"(Temp4) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector4a] "r"(vector4a), [cm] "r"(cm), [dst_ptr] "r"(dst_ptr), - [src_ptr] "r"(src_ptr)); - /* Next row... */ - src_ptr += src_pixels_per_line; - dst_ptr += pitch; - } - } - } -} - -void vp8_filter_block2d_first_pass_8_all(unsigned char *RESTRICT src_ptr, - unsigned char *RESTRICT dst_ptr, - unsigned int src_pixels_per_line, - unsigned int output_height, - int xoffset, int pitch) { - unsigned int i; - int Temp1, Temp2, Temp3, Temp4; - - unsigned int vector4a = 64; - unsigned int vector1b, vector2b, vector3b; - unsigned int tp1, tp2, tn1, tn2; - unsigned int p1, p2, p3, p4; - unsigned int n1, n2, n3, n4; - - unsigned char *cm = ff_cropTbl + CROP_WIDTH; - - /* if (xoffset == 0) we don't need any filtering */ - if (xoffset == 0) { - for (i = 0; i < output_height; ++i) { - /* prefetch src_ptr data to cache memory */ - prefetch_load(src_ptr + src_pixels_per_line); - - dst_ptr[0] = src_ptr[0]; - dst_ptr[1] = src_ptr[1]; - dst_ptr[2] = src_ptr[2]; - dst_ptr[3] = src_ptr[3]; - dst_ptr[4] = src_ptr[4]; - dst_ptr[5] = src_ptr[5]; - dst_ptr[6] = src_ptr[6]; - dst_ptr[7] = src_ptr[7]; - - /* next row... */ - src_ptr += src_pixels_per_line; - dst_ptr += 8; - } - } else { - vector3b = sub_pel_filters_inv[xoffset][2]; - - if (vector3b > 65536) { - /* 6 tap filter */ - - vector1b = sub_pel_filters_inv[xoffset][0]; - vector2b = sub_pel_filters_inv[xoffset][1]; - - for (i = output_height; i--;) { - /* prefetch src_ptr data to cache memory */ - prefetch_load(src_ptr + src_pixels_per_line); - - /* apply filter with vectors pairs */ - __asm__ __volatile__( - "ulw %[tp1], -2(%[src_ptr]) \n\t" - "ulw %[tp2], 2(%[src_ptr]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[p1], %[tp1] \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "preceu.ph.qbr %[p3], %[tp2] \n\t" - "dpa.w.ph $ac3, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p3], %[vector3b] \n\t" - - /* even 2. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbl %[p1], %[tp2] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p3], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector3b] \n\t" - - "balign %[tp2], %[tp1], 3 \n\t" - "extp %[Temp1], $ac3, 9 \n\t" - "ulw %[tn2], 3(%[src_ptr]) \n\t" - - /* odd 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[n1], %[tp2] \n\t" - "preceu.ph.qbl %[n2], %[tp2] \n\t" - "preceu.ph.qbr %[n3], %[tn2] \n\t" - "extp %[Temp3], $ac2, 9 \n\t" - "dpa.w.ph $ac3, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[n3], %[vector3b] \n\t" - - /* odd 2. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbl %[n1], %[tn2] \n\t" - "dpa.w.ph $ac2, %[n2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[n3], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[n1], %[vector3b] \n\t" - "ulw %[tp1], 6(%[src_ptr]) \n\t" - "extp %[Temp2], $ac3, 9 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[p2], %[tp1] \n\t" - "extp %[Temp4], $ac2, 9 \n\t" - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tn2] "=&r"(tn2), - [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), [n1] "=&r"(n1), - [n2] "=&r"(n2), [n3] "=&r"(n3), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), [Temp4] "=r"(Temp4) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector4a] "r"(vector4a), [vector3b] "r"(vector3b), - [src_ptr] "r"(src_ptr)); - - /* clamp and store results */ - dst_ptr[0] = cm[Temp1]; - dst_ptr[1] = cm[Temp2]; - dst_ptr[2] = cm[Temp3]; - dst_ptr[3] = cm[Temp4]; - - /* next 4 pixels */ - __asm__ __volatile__( - /* even 3. pixel */ - "dpa.w.ph $ac3, %[p3], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p1], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p2], %[vector3b] \n\t" - - /* even 4. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbl %[p4], %[tp1] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[p4], %[vector3b] \n\t" - - "ulw %[tn1], 7(%[src_ptr]) \n\t" - "extp %[Temp1], $ac3, 9 \n\t" - - /* odd 3. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[n2], %[tn1] \n\t" - "dpa.w.ph $ac3, %[n3], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[n1], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector3b] \n\t" - "extp %[Temp3], $ac2, 9 \n\t" - - /* odd 4. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbl %[n4], %[tn1] \n\t" - "dpa.w.ph $ac2, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[n2], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[n4], %[vector3b] \n\t" - "extp %[Temp2], $ac3, 9 \n\t" - "extp %[Temp4], $ac2, 9 \n\t" - - : [tn1] "=&r"(tn1), [n2] "=&r"(n2), [p4] "=&r"(p4), [n4] "=&r"(n4), - [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [Temp4] "=r"(Temp4) - : [tp1] "r"(tp1), [vector1b] "r"(vector1b), [p2] "r"(p2), - [vector2b] "r"(vector2b), [n1] "r"(n1), [p1] "r"(p1), - [vector4a] "r"(vector4a), [vector3b] "r"(vector3b), [p3] "r"(p3), - [n3] "r"(n3), [src_ptr] "r"(src_ptr)); - - /* clamp and store results */ - dst_ptr[4] = cm[Temp1]; - dst_ptr[5] = cm[Temp2]; - dst_ptr[6] = cm[Temp3]; - dst_ptr[7] = cm[Temp4]; - - src_ptr += src_pixels_per_line; - dst_ptr += pitch; - } - } else { - /* 4 tap filter */ - - vector1b = sub_pel_filters_inv_tap_4[xoffset][0]; - vector2b = sub_pel_filters_inv_tap_4[xoffset][1]; - - for (i = output_height; i--;) { - /* prefetch src_ptr data to cache memory */ - prefetch_load(src_ptr + src_pixels_per_line); - - /* apply filter with vectors pairs */ - __asm__ __volatile__( - "ulw %[tp1], -1(%[src_ptr]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[p1], %[tp1] \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "dpa.w.ph $ac3, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p2], %[vector2b] \n\t" - - "ulw %[tp2], 3(%[src_ptr]) \n\t" - - /* even 2. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbr %[p3], %[tp2] \n\t" - "preceu.ph.qbl %[p4], %[tp2] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p3], %[vector2b] \n\t" - "extp %[Temp1], $ac3, 9 \n\t" - - "balign %[tp2], %[tp1], 3 \n\t" - - /* odd 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[n1], %[tp2] \n\t" - "preceu.ph.qbl %[n2], %[tp2] \n\t" - "dpa.w.ph $ac3, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector2b] \n\t" - "extp %[Temp3], $ac2, 9 \n\t" - - "ulw %[tn2], 4(%[src_ptr]) \n\t" - - /* odd 2. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbr %[n3], %[tn2] \n\t" - "preceu.ph.qbl %[n4], %[tn2] \n\t" - "dpa.w.ph $ac2, %[n2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[n3], %[vector2b] \n\t" - "ulw %[tp1], 7(%[src_ptr]) \n\t" - "extp %[Temp2], $ac3, 9 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "extp %[Temp4], $ac2, 9 \n\t" - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tn2] "=&r"(tn2), - [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), [p4] "=&r"(p4), - [n1] "=&r"(n1), [n2] "=&r"(n2), [n3] "=&r"(n3), [n4] "=&r"(n4), - [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [Temp4] "=r"(Temp4) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector4a] "r"(vector4a), [src_ptr] "r"(src_ptr)); - - /* clamp and store results */ - dst_ptr[0] = cm[Temp1]; - dst_ptr[1] = cm[Temp2]; - dst_ptr[2] = cm[Temp3]; - dst_ptr[3] = cm[Temp4]; - - /* next 4 pixels */ - __asm__ __volatile__( - /* even 3. pixel */ - "dpa.w.ph $ac3, %[p3], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p4], %[vector2b] \n\t" - - /* even 4. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbr %[p2], %[tp1] \n\t" - "dpa.w.ph $ac2, %[p4], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector2b] \n\t" - "extp %[Temp1], $ac3, 9 \n\t" - - /* odd 3. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "dpa.w.ph $ac3, %[n3], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[n4], %[vector2b] \n\t" - "ulw %[tn1], 8(%[src_ptr]) \n\t" - "extp %[Temp3], $ac2, 9 \n\t" - - /* odd 4. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbr %[n2], %[tn1] \n\t" - "dpa.w.ph $ac2, %[n4], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[n2], %[vector2b] \n\t" - "extp %[Temp2], $ac3, 9 \n\t" - "extp %[Temp4], $ac2, 9 \n\t" - - : [tn1] "=&r"(tn1), [p2] "=&r"(p2), [n2] "=&r"(n2), - [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [Temp4] "=r"(Temp4) - : [tp1] "r"(tp1), [p3] "r"(p3), [p4] "r"(p4), - [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector4a] "r"(vector4a), [src_ptr] "r"(src_ptr), [n3] "r"(n3), - [n4] "r"(n4)); - - /* clamp and store results */ - dst_ptr[4] = cm[Temp1]; - dst_ptr[5] = cm[Temp2]; - dst_ptr[6] = cm[Temp3]; - dst_ptr[7] = cm[Temp4]; - - /* next row... */ - src_ptr += src_pixels_per_line; - dst_ptr += pitch; - } - } - } -} - -void vp8_filter_block2d_first_pass16_6tap(unsigned char *RESTRICT src_ptr, - unsigned char *RESTRICT dst_ptr, - unsigned int src_pixels_per_line, - unsigned int output_height, - int xoffset, int pitch) { - unsigned int i; - int Temp1, Temp2, Temp3, Temp4; - - unsigned int vector4a; - unsigned int vector1b, vector2b, vector3b; - unsigned int tp1, tp2, tn1, tn2; - unsigned int p1, p2, p3, p4; - unsigned int n1, n2, n3, n4; - unsigned char *cm = ff_cropTbl + CROP_WIDTH; - - vector1b = sub_pel_filters_inv[xoffset][0]; - vector2b = sub_pel_filters_inv[xoffset][1]; - vector3b = sub_pel_filters_inv[xoffset][2]; - vector4a = 64; - - for (i = output_height; i--;) { - /* prefetch src_ptr data to cache memory */ - prefetch_load(src_ptr + src_pixels_per_line); - - /* apply filter with vectors pairs */ - __asm__ __volatile__( - "ulw %[tp1], -2(%[src_ptr]) \n\t" - "ulw %[tp2], 2(%[src_ptr]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[p1], %[tp1] \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "preceu.ph.qbr %[p3], %[tp2] \n\t" - "dpa.w.ph $ac3, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p3], %[vector3b] \n\t" - - /* even 2. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbl %[p1], %[tp2] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p3], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector3b] \n\t" - - "balign %[tp2], %[tp1], 3 \n\t" - "ulw %[tn2], 3(%[src_ptr]) \n\t" - "extp %[Temp1], $ac3, 9 \n\t" - - /* odd 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[n1], %[tp2] \n\t" - "preceu.ph.qbl %[n2], %[tp2] \n\t" - "preceu.ph.qbr %[n3], %[tn2] \n\t" - "extp %[Temp3], $ac2, 9 \n\t" - "dpa.w.ph $ac3, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[n3], %[vector3b] \n\t" - - /* odd 2. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbl %[n1], %[tn2] \n\t" - "dpa.w.ph $ac2, %[n2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[n3], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[n1], %[vector3b] \n\t" - "ulw %[tp1], 6(%[src_ptr]) \n\t" - "extp %[Temp2], $ac3, 9 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[p2], %[tp1] \n\t" - "extp %[Temp4], $ac2, 9 \n\t" - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tn2] "=&r"(tn2), [p1] "=&r"(p1), - [p2] "=&r"(p2), [p3] "=&r"(p3), [n1] "=&r"(n1), [n2] "=&r"(n2), - [n3] "=&r"(n3), [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), - [Temp3] "=&r"(Temp3), [Temp4] "=r"(Temp4) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector4a] "r"(vector4a), [vector3b] "r"(vector3b), - [src_ptr] "r"(src_ptr)); - - /* clamp and store results */ - dst_ptr[0] = cm[Temp1]; - dst_ptr[1] = cm[Temp2]; - dst_ptr[2] = cm[Temp3]; - dst_ptr[3] = cm[Temp4]; - - /* next 4 pixels */ - __asm__ __volatile__( - /* even 3. pixel */ - "dpa.w.ph $ac3, %[p3], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p1], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p2], %[vector3b] \n\t" - - /* even 4. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbl %[p4], %[tp1] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[p4], %[vector3b] \n\t" - "ulw %[tn1], 7(%[src_ptr]) \n\t" - "extp %[Temp1], $ac3, 9 \n\t" - - /* odd 3. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[n2], %[tn1] \n\t" - "dpa.w.ph $ac3, %[n3], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[n1], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector3b] \n\t" - "extp %[Temp3], $ac2, 9 \n\t" - - /* odd 4. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbl %[n4], %[tn1] \n\t" - "dpa.w.ph $ac2, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[n2], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[n4], %[vector3b] \n\t" - "ulw %[tp2], 10(%[src_ptr]) \n\t" - "extp %[Temp2], $ac3, 9 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[p1], %[tp2] \n\t" - "extp %[Temp4], $ac2, 9 \n\t" - - : [tn1] "=&r"(tn1), [tp2] "=&r"(tp2), [n2] "=&r"(n2), [p4] "=&r"(p4), - [n4] "=&r"(n4), [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), - [Temp3] "=&r"(Temp3), [Temp4] "=r"(Temp4), [p1] "+r"(p1) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), [tp1] "r"(tp1), - [n1] "r"(n1), [vector4a] "r"(vector4a), [p2] "r"(p2), - [vector3b] "r"(vector3b), [p3] "r"(p3), [n3] "r"(n3), - [src_ptr] "r"(src_ptr)); - - /* clamp and store results */ - dst_ptr[4] = cm[Temp1]; - dst_ptr[5] = cm[Temp2]; - dst_ptr[6] = cm[Temp3]; - dst_ptr[7] = cm[Temp4]; - - /* next 4 pixels */ - __asm__ __volatile__( - /* even 5. pixel */ - "dpa.w.ph $ac3, %[p2], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p4], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p1], %[vector3b] \n\t" - - /* even 6. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbl %[p3], %[tp2] \n\t" - "dpa.w.ph $ac2, %[p4], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[p3], %[vector3b] \n\t" - - "ulw %[tn1], 11(%[src_ptr]) \n\t" - "extp %[Temp1], $ac3, 9 \n\t" - - /* odd 5. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[n1], %[tn1] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[n4], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[n1], %[vector3b] \n\t" - "extp %[Temp3], $ac2, 9 \n\t" - - /* odd 6. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbl %[n3], %[tn1] \n\t" - "dpa.w.ph $ac2, %[n4], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[n1], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[n3], %[vector3b] \n\t" - "ulw %[tp1], 14(%[src_ptr]) \n\t" - "extp %[Temp2], $ac3, 9 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[p4], %[tp1] \n\t" - "extp %[Temp4], $ac2, 9 \n\t" - - : [tn1] "=&r"(tn1), [tp1] "=&r"(tp1), [n1] "=&r"(n1), [p3] "=&r"(p3), - [n3] "=&r"(n3), [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), - [Temp3] "=&r"(Temp3), [Temp4] "=r"(Temp4), [p4] "+r"(p4) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), [tp2] "r"(tp2), - [p2] "r"(p2), [n2] "r"(n2), [n4] "r"(n4), [p1] "r"(p1), - [src_ptr] "r"(src_ptr), [vector4a] "r"(vector4a), - [vector3b] "r"(vector3b)); - - /* clamp and store results */ - dst_ptr[8] = cm[Temp1]; - dst_ptr[9] = cm[Temp2]; - dst_ptr[10] = cm[Temp3]; - dst_ptr[11] = cm[Temp4]; - - /* next 4 pixels */ - __asm__ __volatile__( - /* even 7. pixel */ - "dpa.w.ph $ac3, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p3], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p4], %[vector3b] \n\t" - - /* even 8. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "dpa.w.ph $ac2, %[p3], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p4], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector3b] \n\t" - "ulw %[tn1], 15(%[src_ptr]) \n\t" - "extp %[Temp1], $ac3, 9 \n\t" - - /* odd 7. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "preceu.ph.qbr %[n4], %[tn1] \n\t" - "dpa.w.ph $ac3, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[n3], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[n4], %[vector3b] \n\t" - "extp %[Temp3], $ac2, 9 \n\t" - - /* odd 8. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "preceu.ph.qbl %[n2], %[tn1] \n\t" - "dpa.w.ph $ac2, %[n3], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[n4], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[n2], %[vector3b] \n\t" - "extp %[Temp2], $ac3, 9 \n\t" - "extp %[Temp4], $ac2, 9 \n\t" - - /* clamp and store results */ - "lbux %[tp1], %[Temp1](%[cm]) \n\t" - "lbux %[tn1], %[Temp2](%[cm]) \n\t" - "lbux %[p2], %[Temp3](%[cm]) \n\t" - "sb %[tp1], 12(%[dst_ptr]) \n\t" - "sb %[tn1], 13(%[dst_ptr]) \n\t" - "lbux %[n2], %[Temp4](%[cm]) \n\t" - "sb %[p2], 14(%[dst_ptr]) \n\t" - "sb %[n2], 15(%[dst_ptr]) \n\t" - - : [tn1] "=&r"(tn1), [p2] "=&r"(p2), [n2] "=&r"(n2), [n4] "=&r"(n4), - [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [Temp4] "=r"(Temp4), [tp1] "+r"(tp1) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), [p4] "r"(p4), - [n1] "r"(n1), [p1] "r"(p1), [vector4a] "r"(vector4a), - [vector3b] "r"(vector3b), [p3] "r"(p3), [n3] "r"(n3), - [src_ptr] "r"(src_ptr), [cm] "r"(cm), [dst_ptr] "r"(dst_ptr)); - - src_ptr += src_pixels_per_line; - dst_ptr += pitch; - } -} - -void vp8_filter_block2d_first_pass16_0(unsigned char *RESTRICT src_ptr, - unsigned char *RESTRICT output_ptr, - unsigned int src_pixels_per_line) { - int Temp1, Temp2, Temp3, Temp4; - int i; - - /* prefetch src_ptr data to cache memory */ - prefetch_store(output_ptr + 32); - - /* copy memory from src buffer to dst buffer */ - for (i = 0; i < 7; ++i) { - __asm__ __volatile__( - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "ulw %[Temp3], 8(%[src_ptr]) \n\t" - "ulw %[Temp4], 12(%[src_ptr]) \n\t" - "sw %[Temp1], 0(%[output_ptr]) \n\t" - "sw %[Temp2], 4(%[output_ptr]) \n\t" - "sw %[Temp3], 8(%[output_ptr]) \n\t" - "sw %[Temp4], 12(%[output_ptr]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - : [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [Temp4] "=&r"(Temp4), [src_ptr] "+r"(src_ptr) - : [src_pixels_per_line] "r"(src_pixels_per_line), [output_ptr] "r"( - output_ptr)); - - __asm__ __volatile__( - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "ulw %[Temp3], 8(%[src_ptr]) \n\t" - "ulw %[Temp4], 12(%[src_ptr]) \n\t" - "sw %[Temp1], 16(%[output_ptr]) \n\t" - "sw %[Temp2], 20(%[output_ptr]) \n\t" - "sw %[Temp3], 24(%[output_ptr]) \n\t" - "sw %[Temp4], 28(%[output_ptr]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - : [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [Temp4] "=&r"(Temp4), [src_ptr] "+r"(src_ptr) - : [src_pixels_per_line] "r"(src_pixels_per_line), [output_ptr] "r"( - output_ptr)); - - __asm__ __volatile__( - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "ulw %[Temp3], 8(%[src_ptr]) \n\t" - "ulw %[Temp4], 12(%[src_ptr]) \n\t" - "sw %[Temp1], 32(%[output_ptr]) \n\t" - "sw %[Temp2], 36(%[output_ptr]) \n\t" - "sw %[Temp3], 40(%[output_ptr]) \n\t" - "sw %[Temp4], 44(%[output_ptr]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - : [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [Temp4] "=&r"(Temp4), [src_ptr] "+r"(src_ptr) - : [src_pixels_per_line] "r"(src_pixels_per_line), [output_ptr] "r"( - output_ptr)); - - output_ptr += 48; - } -} - -void vp8_filter_block2d_first_pass16_4tap( - unsigned char *RESTRICT src_ptr, unsigned char *RESTRICT output_ptr, - unsigned int src_pixels_per_line, unsigned int output_width, - unsigned int output_height, int xoffset, int yoffset, - unsigned char *RESTRICT dst_ptr, int pitch) { - unsigned int i, j; - int Temp1, Temp2, Temp3, Temp4; - - unsigned int vector4a; - int vector1b, vector2b; - unsigned int tp1, tp2, tp3, tn1; - unsigned int p1, p2, p3; - unsigned int n1, n2, n3; - unsigned char *cm = ff_cropTbl + CROP_WIDTH; - - vector4a = 64; - - vector1b = sub_pel_filters_inv_tap_4[xoffset][0]; - vector2b = sub_pel_filters_inv_tap_4[xoffset][1]; - - /* if (yoffset == 0) don't need temp buffer, data will be stored in dst_ptr */ - if (yoffset == 0) { - output_height -= 5; - src_ptr += (src_pixels_per_line + src_pixels_per_line); - - for (i = output_height; i--;) { - __asm__ __volatile__("ulw %[tp3], -1(%[src_ptr]) \n\t" - : [tp3] "=&r"(tp3) - : [src_ptr] "r"(src_ptr)); - - /* processing 4 adjacent pixels */ - for (j = 0; j < 16; j += 4) { - /* apply filter with vectors pairs */ - __asm__ __volatile__( - "ulw %[tp2], 3(%[src_ptr]) " - "\n\t" - "move %[tp1], %[tp3] " - "\n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 " - "\n\t" - "mthi $0, $ac3 " - "\n\t" - "move %[tp3], %[tp2] " - "\n\t" - "preceu.ph.qbr %[p1], %[tp1] " - "\n\t" - "preceu.ph.qbl %[p2], %[tp1] " - "\n\t" - "preceu.ph.qbr %[p3], %[tp2] " - "\n\t" - "dpa.w.ph $ac3, %[p1], %[vector1b] " - "\n\t" - "dpa.w.ph $ac3, %[p2], %[vector2b] " - "\n\t" - - /* even 2. pixel */ - "mtlo %[vector4a], $ac2 " - "\n\t" - "mthi $0, $ac2 " - "\n\t" - "dpa.w.ph $ac2, %[p2], %[vector1b] " - "\n\t" - "dpa.w.ph $ac2, %[p3], %[vector2b] " - "\n\t" - "extr.w %[Temp1], $ac3, 7 " - "\n\t" - - /* odd 1. pixel */ - "ulw %[tn1], 4(%[src_ptr]) " - "\n\t" - "balign %[tp2], %[tp1], 3 " - "\n\t" - "mtlo %[vector4a], $ac3 " - "\n\t" - "mthi $0, $ac3 " - "\n\t" - "preceu.ph.qbr %[n1], %[tp2] " - "\n\t" - "preceu.ph.qbl %[n2], %[tp2] " - "\n\t" - "preceu.ph.qbr %[n3], %[tn1] " - "\n\t" - "extr.w %[Temp3], $ac2, 7 " - "\n\t" - "dpa.w.ph $ac3, %[n1], %[vector1b] " - "\n\t" - "dpa.w.ph $ac3, %[n2], %[vector2b] " - "\n\t" - - /* odd 2. pixel */ - "mtlo %[vector4a], $ac2 " - "\n\t" - "mthi $0, $ac2 " - "\n\t" - "extr.w %[Temp2], $ac3, 7 " - "\n\t" - "dpa.w.ph $ac2, %[n2], %[vector1b] " - "\n\t" - "dpa.w.ph $ac2, %[n3], %[vector2b] " - "\n\t" - "extr.w %[Temp4], $ac2, 7 " - "\n\t" - - /* clamp and store results */ - "lbux %[tp1], %[Temp1](%[cm]) " - "\n\t" - "lbux %[tn1], %[Temp2](%[cm]) " - "\n\t" - "lbux %[tp2], %[Temp3](%[cm]) " - "\n\t" - "sb %[tp1], 0(%[dst_ptr]) " - "\n\t" - "sb %[tn1], 1(%[dst_ptr]) " - "\n\t" - "lbux %[n2], %[Temp4](%[cm]) " - "\n\t" - "sb %[tp2], 2(%[dst_ptr]) " - "\n\t" - "sb %[n2], 3(%[dst_ptr]) " - "\n\t" - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tp3] "=&r"(tp3), - [tn1] "=&r"(tn1), [p1] "=&r"(p1), [p2] "=&r"(p2), [n1] "=&r"(n1), - [n2] "=&r"(n2), [n3] "=&r"(n3), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [p3] "=&r"(p3), [Temp3] "=&r"(Temp3), - [Temp4] "=&r"(Temp4) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector4a] "r"(vector4a), [cm] "r"(cm), [dst_ptr] "r"(dst_ptr), - [src_ptr] "r"(src_ptr)); - - src_ptr += 4; - } - - /* Next row... */ - src_ptr += src_pixels_per_line - 16; - dst_ptr += pitch; - } - } else { - for (i = output_height; i--;) { - /* processing 4 adjacent pixels */ - for (j = 0; j < 16; j += 4) { - /* apply filter with vectors pairs */ - __asm__ __volatile__( - "ulw %[tp1], -1(%[src_ptr]) " - "\n\t" - "ulw %[tp2], 3(%[src_ptr]) " - "\n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 " - "\n\t" - "mthi $0, $ac3 " - "\n\t" - "preceu.ph.qbr %[p1], %[tp1] " - "\n\t" - "preceu.ph.qbl %[p2], %[tp1] " - "\n\t" - "preceu.ph.qbr %[p3], %[tp2] " - "\n\t" - "dpa.w.ph $ac3, %[p1], %[vector1b] " - "\n\t" - "dpa.w.ph $ac3, %[p2], %[vector2b] " - "\n\t" - - /* even 2. pixel */ - "mtlo %[vector4a], $ac2 " - "\n\t" - "mthi $0, $ac2 " - "\n\t" - "dpa.w.ph $ac2, %[p2], %[vector1b] " - "\n\t" - "dpa.w.ph $ac2, %[p3], %[vector2b] " - "\n\t" - "extr.w %[Temp1], $ac3, 7 " - "\n\t" - - /* odd 1. pixel */ - "ulw %[tn1], 4(%[src_ptr]) " - "\n\t" - "balign %[tp2], %[tp1], 3 " - "\n\t" - "mtlo %[vector4a], $ac3 " - "\n\t" - "mthi $0, $ac3 " - "\n\t" - "preceu.ph.qbr %[n1], %[tp2] " - "\n\t" - "preceu.ph.qbl %[n2], %[tp2] " - "\n\t" - "preceu.ph.qbr %[n3], %[tn1] " - "\n\t" - "extr.w %[Temp3], $ac2, 7 " - "\n\t" - "dpa.w.ph $ac3, %[n1], %[vector1b] " - "\n\t" - "dpa.w.ph $ac3, %[n2], %[vector2b] " - "\n\t" - - /* odd 2. pixel */ - "mtlo %[vector4a], $ac2 " - "\n\t" - "mthi $0, $ac2 " - "\n\t" - "extr.w %[Temp2], $ac3, 7 " - "\n\t" - "dpa.w.ph $ac2, %[n2], %[vector1b] " - "\n\t" - "dpa.w.ph $ac2, %[n3], %[vector2b] " - "\n\t" - "extr.w %[Temp4], $ac2, 7 " - "\n\t" - - /* clamp and store results */ - "lbux %[tp1], %[Temp1](%[cm]) " - "\n\t" - "lbux %[tn1], %[Temp2](%[cm]) " - "\n\t" - "lbux %[tp2], %[Temp3](%[cm]) " - "\n\t" - "sb %[tp1], 0(%[output_ptr]) " - "\n\t" - "sb %[tn1], 1(%[output_ptr]) " - "\n\t" - "lbux %[n2], %[Temp4](%[cm]) " - "\n\t" - "sb %[tp2], 2(%[output_ptr]) " - "\n\t" - "sb %[n2], 3(%[output_ptr]) " - "\n\t" - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tn1] "=&r"(tn1), - [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), [n1] "=&r"(n1), - [n2] "=&r"(n2), [n3] "=&r"(n3), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), [Temp4] "=&r"(Temp4) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector4a] "r"(vector4a), [cm] "r"(cm), - [output_ptr] "r"(output_ptr), [src_ptr] "r"(src_ptr)); - - src_ptr += 4; - } - - /* next row... */ - src_ptr += src_pixels_per_line; - output_ptr += output_width; - } - } -} - -void vp8_filter_block2d_second_pass4(unsigned char *RESTRICT src_ptr, - unsigned char *RESTRICT output_ptr, - int output_pitch, int yoffset) { - unsigned int i; - - int Temp1, Temp2, Temp3, Temp4; - unsigned int vector1b, vector2b, vector3b, vector4a; - - unsigned char src_ptr_l2; - unsigned char src_ptr_l1; - unsigned char src_ptr_0; - unsigned char src_ptr_r1; - unsigned char src_ptr_r2; - unsigned char src_ptr_r3; - - unsigned char *cm = ff_cropTbl + CROP_WIDTH; - - vector4a = 64; - - /* load filter coefficients */ - vector1b = sub_pel_filterss[yoffset][0]; - vector2b = sub_pel_filterss[yoffset][2]; - vector3b = sub_pel_filterss[yoffset][1]; - - if (vector1b) { - /* 6 tap filter */ - - for (i = 2; i--;) { - /* prefetch src_ptr data to cache memory */ - prefetch_load(src_ptr); - - /* do not allow compiler to reorder instructions */ - __asm__ __volatile__( - ".set noreorder \n\t" - : - :); - - /* apply filter with vectors pairs */ - __asm__ __volatile__( - "lbu %[src_ptr_l2], -8(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -4(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 0(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 4(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 8(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 12(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac2 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac2, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac2, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac2, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -7(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -3(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 1(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 5(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 9(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 13(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "extp %[Temp1], $ac2, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac3, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac3, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac3, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -6(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -2(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 2(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 6(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 10(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 14(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac0 \n\t" - "extp %[Temp2], $ac3, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac0, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac0, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac0, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -5(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -1(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 3(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 7(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 11(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 15(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "extp %[Temp3], $ac0, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac1, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac1, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac1, %[src_ptr_l1], %[vector3b] \n\t" - "extp %[Temp4], $ac1, 9 \n\t" - - : [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [Temp4] "=r"(Temp4), [src_ptr_l1] "=&r"(src_ptr_l1), - [src_ptr_0] "=&r"(src_ptr_0), [src_ptr_r1] "=&r"(src_ptr_r1), - [src_ptr_r2] "=&r"(src_ptr_r2), [src_ptr_l2] "=&r"(src_ptr_l2), - [src_ptr_r3] "=&r"(src_ptr_r3) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector3b] "r"(vector3b), [vector4a] "r"(vector4a), - [src_ptr] "r"(src_ptr)); - - /* clamp and store results */ - output_ptr[0] = cm[Temp1]; - output_ptr[1] = cm[Temp2]; - output_ptr[2] = cm[Temp3]; - output_ptr[3] = cm[Temp4]; - - output_ptr += output_pitch; - - /* apply filter with vectors pairs */ - __asm__ __volatile__( - "lbu %[src_ptr_l2], -4(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], 0(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 4(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 8(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 12(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 16(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac2, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac2, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac2, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -3(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], 1(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 5(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 9(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 13(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 17(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "extp %[Temp1], $ac2, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac3, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac3, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac3, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -2(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], 2(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 6(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 10(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 14(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 18(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac0 \n\t" - "extp %[Temp2], $ac3, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac0, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac0, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac0, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -1(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], 3(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 7(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 11(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 15(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 19(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "extp %[Temp3], $ac0, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac1, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac1, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac1, %[src_ptr_l1], %[vector3b] \n\t" - "extp %[Temp4], $ac1, 9 \n\t" - - : [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [Temp4] "=r"(Temp4), [src_ptr_l1] "=&r"(src_ptr_l1), - [src_ptr_0] "=&r"(src_ptr_0), [src_ptr_r1] "=&r"(src_ptr_r1), - [src_ptr_r2] "=&r"(src_ptr_r2), [src_ptr_l2] "=&r"(src_ptr_l2), - [src_ptr_r3] "=&r"(src_ptr_r3) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector3b] "r"(vector3b), [vector4a] "r"(vector4a), - [src_ptr] "r"(src_ptr)); - - /* clamp and store results */ - output_ptr[0] = cm[Temp1]; - output_ptr[1] = cm[Temp2]; - output_ptr[2] = cm[Temp3]; - output_ptr[3] = cm[Temp4]; - - src_ptr += 8; - output_ptr += output_pitch; - } - } else { - /* 4 tap filter */ - - /* prefetch src_ptr data to cache memory */ - prefetch_load(src_ptr); - - for (i = 2; i--;) { - /* do not allow compiler to reorder instructions */ - __asm__ __volatile__( - ".set noreorder \n\t" - : - :); - - /* apply filter with vectors pairs */ - __asm__ __volatile__( - "lbu %[src_ptr_l1], -4(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 0(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 4(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 8(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac2, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac2, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l1], -3(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 1(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 5(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 9(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "extp %[Temp1], $ac2, 9 \n\t" - - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac3, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac3, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l1], -2(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 2(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 6(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 10(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac0 \n\t" - "extp %[Temp2], $ac3, 9 \n\t" - - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac0, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac0, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l1], -1(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 3(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 7(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 11(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "extp %[Temp3], $ac0, 9 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac1, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac1, %[src_ptr_l1], %[vector3b] \n\t" - "extp %[Temp4], $ac1, 9 \n\t" - - : [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [Temp4] "=r"(Temp4), [src_ptr_l1] "=&r"(src_ptr_l1), - [src_ptr_0] "=&r"(src_ptr_0), [src_ptr_r1] "=&r"(src_ptr_r1), - [src_ptr_r2] "=&r"(src_ptr_r2) - : [vector2b] "r"(vector2b), [vector3b] "r"(vector3b), - [vector4a] "r"(vector4a), [src_ptr] "r"(src_ptr)); - - /* clamp and store results */ - output_ptr[0] = cm[Temp1]; - output_ptr[1] = cm[Temp2]; - output_ptr[2] = cm[Temp3]; - output_ptr[3] = cm[Temp4]; - - output_ptr += output_pitch; - - /* apply filter with vectors pairs */ - __asm__ __volatile__( - "lbu %[src_ptr_l1], 0(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 4(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 8(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 12(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac2, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac2, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l1], 1(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 5(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 9(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 13(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "extp %[Temp1], $ac2, 9 \n\t" - - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac3, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac3, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l1], 2(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 6(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 10(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 14(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac0 \n\t" - "extp %[Temp2], $ac3, 9 \n\t" - - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac0, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac0, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l1], 3(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 7(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 11(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 15(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "extp %[Temp3], $ac0, 9 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac1, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac1, %[src_ptr_l1], %[vector3b] \n\t" - "extp %[Temp4], $ac1, 9 \n\t" - - : [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [Temp4] "=r"(Temp4), [src_ptr_l1] "=&r"(src_ptr_l1), - [src_ptr_0] "=&r"(src_ptr_0), [src_ptr_r1] "=&r"(src_ptr_r1), - [src_ptr_r2] "=&r"(src_ptr_r2) - : [vector2b] "r"(vector2b), [vector3b] "r"(vector3b), - [vector4a] "r"(vector4a), [src_ptr] "r"(src_ptr)); - - /* clamp and store results */ - output_ptr[0] = cm[Temp1]; - output_ptr[1] = cm[Temp2]; - output_ptr[2] = cm[Temp3]; - output_ptr[3] = cm[Temp4]; - - src_ptr += 8; - output_ptr += output_pitch; - } - } -} - -void vp8_filter_block2d_second_pass_8(unsigned char *RESTRICT src_ptr, - unsigned char *RESTRICT output_ptr, - int output_pitch, - unsigned int output_height, - unsigned int output_width, - unsigned int yoffset) { - unsigned int i; - - int Temp1, Temp2, Temp3, Temp4, Temp5, Temp6, Temp7, Temp8; - unsigned int vector1b, vector2b, vector3b, vector4a; - - unsigned char src_ptr_l2; - unsigned char src_ptr_l1; - unsigned char src_ptr_0; - unsigned char src_ptr_r1; - unsigned char src_ptr_r2; - unsigned char src_ptr_r3; - unsigned char *cm = ff_cropTbl + CROP_WIDTH; - (void)output_width; - - vector4a = 64; - - vector1b = sub_pel_filterss[yoffset][0]; - vector2b = sub_pel_filterss[yoffset][2]; - vector3b = sub_pel_filterss[yoffset][1]; - - if (vector1b) { - /* 6 tap filter */ - - /* prefetch src_ptr data to cache memory */ - prefetch_load(src_ptr); - - for (i = output_height; i--;) { - /* apply filter with vectors pairs */ - __asm__ __volatile__( - "lbu %[src_ptr_l2], -16(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -8(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 0(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 8(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 16(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 24(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac2 \n\t" - - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "dpau.h.qbr $ac2, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac2, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac2, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -15(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -7(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 1(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 9(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 17(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 25(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "extp %[Temp1], $ac2, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac3, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac3, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac3, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -14(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -6(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 2(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 10(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 18(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 26(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac0 \n\t" - "extp %[Temp2], $ac3, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac0, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac0, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac0, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -13(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -5(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 3(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 11(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 19(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 27(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "extp %[Temp3], $ac0, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac1, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac1, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac1, %[src_ptr_l1], %[vector3b] \n\t" - - : [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [src_ptr_l1] "=&r"(src_ptr_l1), [src_ptr_0] "=&r"(src_ptr_0), - [src_ptr_r1] "=&r"(src_ptr_r1), [src_ptr_r2] "=&r"(src_ptr_r2), - [src_ptr_l2] "=&r"(src_ptr_l2), [src_ptr_r3] "=&r"(src_ptr_r3) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector3b] "r"(vector3b), [vector4a] "r"(vector4a), - [src_ptr] "r"(src_ptr)); - - /* apply filter with vectors pairs */ - __asm__ __volatile__( - "lbu %[src_ptr_l2], -12(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -4(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 4(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 12(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 20(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 28(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac2 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac2, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac2, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac2, %[src_ptr_l1], %[vector3b] \n\t" - "extp %[Temp4], $ac1, 9 \n\t" - - "lbu %[src_ptr_l2], -11(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -3(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 5(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 13(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 21(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 29(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "extp %[Temp5], $ac2, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac3, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac3, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac3, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -10(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -2(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 6(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 14(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 22(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 30(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac0 \n\t" - "extp %[Temp6], $ac3, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac0, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac0, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac0, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -9(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -1(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 7(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 15(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 23(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 31(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "extp %[Temp7], $ac0, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac1, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac1, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac1, %[src_ptr_l1], %[vector3b] \n\t" - "extp %[Temp8], $ac1, 9 \n\t" - - : [Temp4] "=&r"(Temp4), [Temp5] "=&r"(Temp5), [Temp6] "=&r"(Temp6), - [Temp7] "=&r"(Temp7), [Temp8] "=r"(Temp8), - [src_ptr_l1] "=&r"(src_ptr_l1), [src_ptr_0] "=&r"(src_ptr_0), - [src_ptr_r1] "=&r"(src_ptr_r1), [src_ptr_r2] "=&r"(src_ptr_r2), - [src_ptr_l2] "=&r"(src_ptr_l2), [src_ptr_r3] "=&r"(src_ptr_r3) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector3b] "r"(vector3b), [vector4a] "r"(vector4a), - [src_ptr] "r"(src_ptr)); - - /* clamp and store results */ - output_ptr[0] = cm[Temp1]; - output_ptr[1] = cm[Temp2]; - output_ptr[2] = cm[Temp3]; - output_ptr[3] = cm[Temp4]; - output_ptr[4] = cm[Temp5]; - output_ptr[5] = cm[Temp6]; - output_ptr[6] = cm[Temp7]; - output_ptr[7] = cm[Temp8]; - - src_ptr += 8; - output_ptr += output_pitch; - } - } else { - /* 4 tap filter */ - - /* prefetch src_ptr data to cache memory */ - prefetch_load(src_ptr); - - for (i = output_height; i--;) { - __asm__ __volatile__( - "lbu %[src_ptr_l1], -8(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 0(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 8(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 16(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac2, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac2, %[src_ptr_l1], %[vector3b] \n\t" - - : [src_ptr_l1] "=&r"(src_ptr_l1), [src_ptr_0] "=&r"(src_ptr_0), - [src_ptr_r1] "=&r"(src_ptr_r1), [src_ptr_r2] "=&r"(src_ptr_r2) - : [vector2b] "r"(vector2b), [vector3b] "r"(vector3b), - [vector4a] "r"(vector4a), [src_ptr] "r"(src_ptr)); - - __asm__ __volatile__( - "lbu %[src_ptr_l1], -7(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 1(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 9(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 17(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac3, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac3, %[src_ptr_l1], %[vector3b] \n\t" - "extp %[Temp1], $ac2, 9 \n\t" - - : [Temp1] "=r"(Temp1), [src_ptr_l1] "=&r"(src_ptr_l1), - [src_ptr_0] "=&r"(src_ptr_0), [src_ptr_r1] "=&r"(src_ptr_r1), - [src_ptr_r2] "=&r"(src_ptr_r2) - : [vector2b] "r"(vector2b), [vector3b] "r"(vector3b), - [vector4a] "r"(vector4a), [src_ptr] "r"(src_ptr)); - - src_ptr_l1 = src_ptr[-6]; - src_ptr_0 = src_ptr[2]; - src_ptr_r1 = src_ptr[10]; - src_ptr_r2 = src_ptr[18]; - - __asm__ __volatile__( - "mtlo %[vector4a], $ac0 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac0, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac0, %[src_ptr_l1], %[vector3b] \n\t" - "extp %[Temp2], $ac3, 9 \n\t" - - : [Temp2] "=r"(Temp2) - : [vector2b] "r"(vector2b), [vector3b] "r"(vector3b), - [src_ptr_l1] "r"(src_ptr_l1), [src_ptr_0] "r"(src_ptr_0), - [src_ptr_r1] "r"(src_ptr_r1), [src_ptr_r2] "r"(src_ptr_r2), - [vector4a] "r"(vector4a)); - - src_ptr_l1 = src_ptr[-5]; - src_ptr_0 = src_ptr[3]; - src_ptr_r1 = src_ptr[11]; - src_ptr_r2 = src_ptr[19]; - - __asm__ __volatile__( - "mtlo %[vector4a], $ac1 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac1, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac1, %[src_ptr_l1], %[vector3b] \n\t" - "extp %[Temp3], $ac0, 9 \n\t" - - : [Temp3] "=r"(Temp3) - : [vector2b] "r"(vector2b), [vector3b] "r"(vector3b), - [src_ptr_l1] "r"(src_ptr_l1), [src_ptr_0] "r"(src_ptr_0), - [src_ptr_r1] "r"(src_ptr_r1), [src_ptr_r2] "r"(src_ptr_r2), - [vector4a] "r"(vector4a)); - - src_ptr_l1 = src_ptr[-4]; - src_ptr_0 = src_ptr[4]; - src_ptr_r1 = src_ptr[12]; - src_ptr_r2 = src_ptr[20]; - - __asm__ __volatile__( - "mtlo %[vector4a], $ac2 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac2, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac2, %[src_ptr_l1], %[vector3b] \n\t" - "extp %[Temp4], $ac1, 9 \n\t" - - : [Temp4] "=r"(Temp4) - : [vector2b] "r"(vector2b), [vector3b] "r"(vector3b), - [src_ptr_l1] "r"(src_ptr_l1), [src_ptr_0] "r"(src_ptr_0), - [src_ptr_r1] "r"(src_ptr_r1), [src_ptr_r2] "r"(src_ptr_r2), - [vector4a] "r"(vector4a)); - - src_ptr_l1 = src_ptr[-3]; - src_ptr_0 = src_ptr[5]; - src_ptr_r1 = src_ptr[13]; - src_ptr_r2 = src_ptr[21]; - - __asm__ __volatile__( - "mtlo %[vector4a], $ac3 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac3, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac3, %[src_ptr_l1], %[vector3b] \n\t" - "extp %[Temp5], $ac2, 9 \n\t" - - : [Temp5] "=&r"(Temp5) - : [vector2b] "r"(vector2b), [vector3b] "r"(vector3b), - [src_ptr_l1] "r"(src_ptr_l1), [src_ptr_0] "r"(src_ptr_0), - [src_ptr_r1] "r"(src_ptr_r1), [src_ptr_r2] "r"(src_ptr_r2), - [vector4a] "r"(vector4a)); - - src_ptr_l1 = src_ptr[-2]; - src_ptr_0 = src_ptr[6]; - src_ptr_r1 = src_ptr[14]; - src_ptr_r2 = src_ptr[22]; - - __asm__ __volatile__( - "mtlo %[vector4a], $ac0 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac0, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac0, %[src_ptr_l1], %[vector3b] \n\t" - "extp %[Temp6], $ac3, 9 \n\t" - - : [Temp6] "=r"(Temp6) - : [vector2b] "r"(vector2b), [vector3b] "r"(vector3b), - [src_ptr_l1] "r"(src_ptr_l1), [src_ptr_0] "r"(src_ptr_0), - [src_ptr_r1] "r"(src_ptr_r1), [src_ptr_r2] "r"(src_ptr_r2), - [vector4a] "r"(vector4a)); - - src_ptr_l1 = src_ptr[-1]; - src_ptr_0 = src_ptr[7]; - src_ptr_r1 = src_ptr[15]; - src_ptr_r2 = src_ptr[23]; - - __asm__ __volatile__( - "mtlo %[vector4a], $ac1 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac1, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac1, %[src_ptr_l1], %[vector3b] \n\t" - "extp %[Temp7], $ac0, 9 \n\t" - "extp %[Temp8], $ac1, 9 \n\t" - - : [Temp7] "=&r"(Temp7), [Temp8] "=r"(Temp8) - : [vector2b] "r"(vector2b), [vector3b] "r"(vector3b), - [src_ptr_l1] "r"(src_ptr_l1), [src_ptr_0] "r"(src_ptr_0), - [src_ptr_r1] "r"(src_ptr_r1), [src_ptr_r2] "r"(src_ptr_r2), - [vector4a] "r"(vector4a)); - - /* clamp and store results */ - output_ptr[0] = cm[Temp1]; - output_ptr[1] = cm[Temp2]; - output_ptr[2] = cm[Temp3]; - output_ptr[3] = cm[Temp4]; - output_ptr[4] = cm[Temp5]; - output_ptr[5] = cm[Temp6]; - output_ptr[6] = cm[Temp7]; - output_ptr[7] = cm[Temp8]; - - src_ptr += 8; - output_ptr += output_pitch; - } - } -} - -void vp8_filter_block2d_second_pass161(unsigned char *RESTRICT src_ptr, - unsigned char *RESTRICT output_ptr, - int output_pitch, - const unsigned short *vp8_filter) { - unsigned int i, j; - - int Temp1, Temp2, Temp3, Temp4, Temp5, Temp6, Temp7, Temp8; - unsigned int vector4a; - unsigned int vector1b, vector2b, vector3b; - - unsigned char src_ptr_l2; - unsigned char src_ptr_l1; - unsigned char src_ptr_0; - unsigned char src_ptr_r1; - unsigned char src_ptr_r2; - unsigned char src_ptr_r3; - unsigned char *cm = ff_cropTbl + CROP_WIDTH; - - vector4a = 64; - - vector1b = vp8_filter[0]; - vector2b = vp8_filter[2]; - vector3b = vp8_filter[1]; - - if (vector1b == 0) { - /* 4 tap filter */ - - /* prefetch src_ptr data to cache memory */ - prefetch_load(src_ptr + 16); - - for (i = 16; i--;) { - /* unrolling for loop */ - for (j = 0; j < 16; j += 8) { - /* apply filter with vectors pairs */ - __asm__ __volatile__( - "lbu %[src_ptr_l1], -16(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_0], 0(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_r1], 16(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_r2], 32(%[src_ptr]) " - "\n\t" - "mtlo %[vector4a], $ac2 " - "\n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 " - "\n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 " - "\n\t" - "dpau.h.qbr $ac2, %[src_ptr_0], %[vector2b] " - "\n\t" - "dpsu.h.qbr $ac2, %[src_ptr_l1], %[vector3b] " - "\n\t" - - "lbu %[src_ptr_l1], -15(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_0], 1(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_r1], 17(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_r2], 33(%[src_ptr]) " - "\n\t" - "mtlo %[vector4a], $ac3 " - "\n\t" - "extp %[Temp1], $ac2, 9 " - "\n\t" - - "append %[src_ptr_0], %[src_ptr_r1], 8 " - "\n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 " - "\n\t" - "dpau.h.qbr $ac3, %[src_ptr_0], %[vector2b] " - "\n\t" - "dpsu.h.qbr $ac3, %[src_ptr_l1], %[vector3b] " - "\n\t" - - "lbu %[src_ptr_l1], -14(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_0], 2(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_r1], 18(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_r2], 34(%[src_ptr]) " - "\n\t" - "mtlo %[vector4a], $ac1 " - "\n\t" - "extp %[Temp2], $ac3, 9 " - "\n\t" - - "append %[src_ptr_0], %[src_ptr_r1], 8 " - "\n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 " - "\n\t" - "dpau.h.qbr $ac1, %[src_ptr_0], %[vector2b] " - "\n\t" - "dpsu.h.qbr $ac1, %[src_ptr_l1], %[vector3b] " - "\n\t" - - "lbu %[src_ptr_l1], -13(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_0], 3(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_r1], 19(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_r2], 35(%[src_ptr]) " - "\n\t" - "mtlo %[vector4a], $ac3 " - "\n\t" - "extp %[Temp3], $ac1, 9 " - "\n\t" - - "append %[src_ptr_0], %[src_ptr_r1], 8 " - "\n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 " - "\n\t" - "dpau.h.qbr $ac3, %[src_ptr_0], %[vector2b] " - "\n\t" - "dpsu.h.qbr $ac3, %[src_ptr_l1], %[vector3b] " - "\n\t" - - "lbu %[src_ptr_l1], -12(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_0], 4(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_r1], 20(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_r2], 36(%[src_ptr]) " - "\n\t" - "mtlo %[vector4a], $ac2 " - "\n\t" - "extp %[Temp4], $ac3, 9 " - "\n\t" - - "append %[src_ptr_0], %[src_ptr_r1], 8 " - "\n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 " - "\n\t" - "dpau.h.qbr $ac2, %[src_ptr_0], %[vector2b] " - "\n\t" - "dpsu.h.qbr $ac2, %[src_ptr_l1], %[vector3b] " - "\n\t" - - "lbu %[src_ptr_l1], -11(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_0], 5(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_r1], 21(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_r2], 37(%[src_ptr]) " - "\n\t" - "mtlo %[vector4a], $ac3 " - "\n\t" - "extp %[Temp5], $ac2, 9 " - "\n\t" - - "append %[src_ptr_0], %[src_ptr_r1], 8 " - "\n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 " - "\n\t" - "dpau.h.qbr $ac3, %[src_ptr_0], %[vector2b] " - "\n\t" - "dpsu.h.qbr $ac3, %[src_ptr_l1], %[vector3b] " - "\n\t" - - "lbu %[src_ptr_l1], -10(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_0], 6(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_r1], 22(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_r2], 38(%[src_ptr]) " - "\n\t" - "mtlo %[vector4a], $ac1 " - "\n\t" - "extp %[Temp6], $ac3, 9 " - "\n\t" - - "append %[src_ptr_0], %[src_ptr_r1], 8 " - "\n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 " - "\n\t" - "dpau.h.qbr $ac1, %[src_ptr_0], %[vector2b] " - "\n\t" - "dpsu.h.qbr $ac1, %[src_ptr_l1], %[vector3b] " - "\n\t" - - "lbu %[src_ptr_l1], -9(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_0], 7(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_r1], 23(%[src_ptr]) " - "\n\t" - "lbu %[src_ptr_r2], 39(%[src_ptr]) " - "\n\t" - "mtlo %[vector4a], $ac3 " - "\n\t" - "extp %[Temp7], $ac1, 9 " - "\n\t" - - "append %[src_ptr_0], %[src_ptr_r1], 8 " - "\n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 " - "\n\t" - "dpau.h.qbr $ac3, %[src_ptr_0], %[vector2b] " - "\n\t" - "dpsu.h.qbr $ac3, %[src_ptr_l1], %[vector3b] " - "\n\t" - "extp %[Temp8], $ac3, 9 " - "\n\t" - - : [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [Temp4] "=&r"(Temp4), [Temp5] "=&r"(Temp5), [Temp6] "=&r"(Temp6), - [Temp7] "=&r"(Temp7), [Temp8] "=r"(Temp8), - [src_ptr_l1] "=&r"(src_ptr_l1), [src_ptr_0] "=&r"(src_ptr_0), - [src_ptr_r1] "=&r"(src_ptr_r1), [src_ptr_r2] "=&r"(src_ptr_r2) - : [vector2b] "r"(vector2b), [vector3b] "r"(vector3b), - [vector4a] "r"(vector4a), [src_ptr] "r"(src_ptr)); - - /* clamp and store results */ - output_ptr[j] = cm[Temp1]; - output_ptr[j + 1] = cm[Temp2]; - output_ptr[j + 2] = cm[Temp3]; - output_ptr[j + 3] = cm[Temp4]; - output_ptr[j + 4] = cm[Temp5]; - output_ptr[j + 5] = cm[Temp6]; - output_ptr[j + 6] = cm[Temp7]; - output_ptr[j + 7] = cm[Temp8]; - - src_ptr += 8; - } - - output_ptr += output_pitch; - } - } else { - /* 4 tap filter */ - - /* prefetch src_ptr data to cache memory */ - prefetch_load(src_ptr + 16); - - /* unroll for loop */ - for (i = 16; i--;) { - /* apply filter with vectors pairs */ - __asm__ __volatile__( - "lbu %[src_ptr_l2], -32(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -16(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 0(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 16(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 32(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 48(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac2 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac2, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac2, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac2, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -31(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -15(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 1(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 17(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 33(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 49(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac0 \n\t" - "extp %[Temp1], $ac2, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac0, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac0, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac0, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -30(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -14(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 2(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 18(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 34(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 50(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "extp %[Temp2], $ac0, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac1, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac1, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac1, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -29(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -13(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 3(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 19(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 35(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 51(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "extp %[Temp3], $ac1, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac3, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac3, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac3, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -28(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -12(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 4(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 20(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 36(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 52(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "extp %[Temp4], $ac3, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac2, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac2, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac2, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -27(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -11(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 5(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 21(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 37(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 53(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac0 \n\t" - "extp %[Temp5], $ac2, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac0, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac0, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac0, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -26(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -10(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 6(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 22(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 38(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 54(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "extp %[Temp6], $ac0, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac1, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac1, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac1, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -25(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -9(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 7(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 23(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 39(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 55(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "extp %[Temp7], $ac1, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac3, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac3, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac3, %[src_ptr_l1], %[vector3b] \n\t" - "extp %[Temp8], $ac3, 9 \n\t" - - : [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [Temp4] "=&r"(Temp4), [Temp5] "=&r"(Temp5), [Temp6] "=&r"(Temp6), - [Temp7] "=&r"(Temp7), [Temp8] "=r"(Temp8), - [src_ptr_l1] "=&r"(src_ptr_l1), [src_ptr_0] "=&r"(src_ptr_0), - [src_ptr_r1] "=&r"(src_ptr_r1), [src_ptr_r2] "=&r"(src_ptr_r2), - [src_ptr_l2] "=&r"(src_ptr_l2), [src_ptr_r3] "=&r"(src_ptr_r3) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector3b] "r"(vector3b), [vector4a] "r"(vector4a), - [src_ptr] "r"(src_ptr)); - - /* clamp and store results */ - output_ptr[0] = cm[Temp1]; - output_ptr[1] = cm[Temp2]; - output_ptr[2] = cm[Temp3]; - output_ptr[3] = cm[Temp4]; - output_ptr[4] = cm[Temp5]; - output_ptr[5] = cm[Temp6]; - output_ptr[6] = cm[Temp7]; - output_ptr[7] = cm[Temp8]; - - /* apply filter with vectors pairs */ - __asm__ __volatile__( - "lbu %[src_ptr_l2], -24(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -8(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 8(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 24(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 40(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 56(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac2 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac2, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac2, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac2, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -23(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -7(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 9(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 25(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 41(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 57(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac0 \n\t" - "extp %[Temp1], $ac2, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac0, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac0, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac0, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -22(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -6(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 10(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 26(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 42(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 58(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "extp %[Temp2], $ac0, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac1, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac1, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac1, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -21(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -5(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 11(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 27(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 43(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 59(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "extp %[Temp3], $ac1, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac3, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac3, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac3, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -20(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -4(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 12(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 28(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 44(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 60(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "extp %[Temp4], $ac3, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac2, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac2, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac2, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -19(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -3(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 13(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 29(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 45(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 61(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac0 \n\t" - "extp %[Temp5], $ac2, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac0, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac0, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac0, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -18(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -2(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 14(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 30(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 46(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 62(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "extp %[Temp6], $ac0, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac1, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac1, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac1, %[src_ptr_l1], %[vector3b] \n\t" - - "lbu %[src_ptr_l2], -17(%[src_ptr]) \n\t" - "lbu %[src_ptr_l1], -1(%[src_ptr]) \n\t" - "lbu %[src_ptr_0], 15(%[src_ptr]) \n\t" - "lbu %[src_ptr_r1], 31(%[src_ptr]) \n\t" - "lbu %[src_ptr_r2], 47(%[src_ptr]) \n\t" - "lbu %[src_ptr_r3], 63(%[src_ptr]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "extp %[Temp7], $ac1, 9 \n\t" - - "append %[src_ptr_l2], %[src_ptr_r3], 8 \n\t" - "append %[src_ptr_0], %[src_ptr_r1], 8 \n\t" - "append %[src_ptr_l1], %[src_ptr_r2], 8 \n\t" - "dpau.h.qbr $ac3, %[src_ptr_l2], %[vector1b] \n\t" - "dpau.h.qbr $ac3, %[src_ptr_0], %[vector2b] \n\t" - "dpsu.h.qbr $ac3, %[src_ptr_l1], %[vector3b] \n\t" - "extp %[Temp8], $ac3, 9 \n\t" - - : [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [Temp4] "=&r"(Temp4), [Temp5] "=&r"(Temp5), [Temp6] "=&r"(Temp6), - [Temp7] "=&r"(Temp7), [Temp8] "=r"(Temp8), - [src_ptr_l1] "=&r"(src_ptr_l1), [src_ptr_0] "=&r"(src_ptr_0), - [src_ptr_r1] "=&r"(src_ptr_r1), [src_ptr_r2] "=&r"(src_ptr_r2), - [src_ptr_l2] "=&r"(src_ptr_l2), [src_ptr_r3] "=&r"(src_ptr_r3) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector3b] "r"(vector3b), [vector4a] "r"(vector4a), - [src_ptr] "r"(src_ptr)); - - src_ptr += 16; - output_ptr[8] = cm[Temp1]; - output_ptr[9] = cm[Temp2]; - output_ptr[10] = cm[Temp3]; - output_ptr[11] = cm[Temp4]; - output_ptr[12] = cm[Temp5]; - output_ptr[13] = cm[Temp6]; - output_ptr[14] = cm[Temp7]; - output_ptr[15] = cm[Temp8]; - - output_ptr += output_pitch; - } - } -} - -void vp8_sixtap_predict4x4_dspr2(unsigned char *RESTRICT src_ptr, - int src_pixels_per_line, int xoffset, - int yoffset, unsigned char *RESTRICT dst_ptr, - int dst_pitch) { - unsigned char FData[9 * 4]; /* Temp data bufffer used in filtering */ - unsigned int pos = 16; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - if (yoffset) { - /* First filter 1-D horizontally... */ - vp8_filter_block2d_first_pass_4(src_ptr - (2 * src_pixels_per_line), FData, - src_pixels_per_line, 9, xoffset, 4); - /* then filter verticaly... */ - vp8_filter_block2d_second_pass4(FData + 8, dst_ptr, dst_pitch, yoffset); - } else - /* if (yoffsset == 0) vp8_filter_block2d_first_pass save data to dst_ptr */ - vp8_filter_block2d_first_pass_4(src_ptr, dst_ptr, src_pixels_per_line, 4, - xoffset, dst_pitch); -} - -void vp8_sixtap_predict8x8_dspr2(unsigned char *RESTRICT src_ptr, - int src_pixels_per_line, int xoffset, - int yoffset, unsigned char *RESTRICT dst_ptr, - int dst_pitch) { - unsigned char FData[13 * 8]; /* Temp data bufffer used in filtering */ - unsigned int pos, Temp1, Temp2; - - pos = 16; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - if (yoffset) { - src_ptr = src_ptr - (2 * src_pixels_per_line); - - if (xoffset) /* filter 1-D horizontally... */ - vp8_filter_block2d_first_pass_8_all(src_ptr, FData, src_pixels_per_line, - 13, xoffset, 8); - - else { - /* prefetch src_ptr data to cache memory */ - prefetch_load(src_ptr + 2 * src_pixels_per_line); - - __asm__ __volatile__( - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 0(%[FData]) \n\t" - "sw %[Temp2], 4(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 8(%[FData]) \n\t" - "sw %[Temp2], 12(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 16(%[FData]) \n\t" - "sw %[Temp2], 20(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 24(%[FData]) \n\t" - "sw %[Temp2], 28(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 32(%[FData]) \n\t" - "sw %[Temp2], 36(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 40(%[FData]) \n\t" - "sw %[Temp2], 44(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 48(%[FData]) \n\t" - "sw %[Temp2], 52(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 56(%[FData]) \n\t" - "sw %[Temp2], 60(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 64(%[FData]) \n\t" - "sw %[Temp2], 68(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 72(%[FData]) \n\t" - "sw %[Temp2], 76(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 80(%[FData]) \n\t" - "sw %[Temp2], 84(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 88(%[FData]) \n\t" - "sw %[Temp2], 92(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 96(%[FData]) \n\t" - "sw %[Temp2], 100(%[FData]) \n\t" - - : [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2) - : [FData] "r"(FData), [src_ptr] "r"(src_ptr), - [src_pixels_per_line] "r"(src_pixels_per_line)); - } - - /* filter verticaly... */ - vp8_filter_block2d_second_pass_8(FData + 16, dst_ptr, dst_pitch, 8, 8, - yoffset); - } - - /* if (yoffsset == 0) vp8_filter_block2d_first_pass save data to dst_ptr */ - else { - if (xoffset) - vp8_filter_block2d_first_pass_8_all(src_ptr, dst_ptr, src_pixels_per_line, - 8, xoffset, dst_pitch); - - else { - /* copy from src buffer to dst buffer */ - __asm__ __volatile__( - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 0(%[dst_ptr]) \n\t" - "sw %[Temp2], 4(%[dst_ptr]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 8(%[dst_ptr]) \n\t" - "sw %[Temp2], 12(%[dst_ptr]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 16(%[dst_ptr]) \n\t" - "sw %[Temp2], 20(%[dst_ptr]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 24(%[dst_ptr]) \n\t" - "sw %[Temp2], 28(%[dst_ptr]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 32(%[dst_ptr]) \n\t" - "sw %[Temp2], 36(%[dst_ptr]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 40(%[dst_ptr]) \n\t" - "sw %[Temp2], 44(%[dst_ptr]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 48(%[dst_ptr]) \n\t" - "sw %[Temp2], 52(%[dst_ptr]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 56(%[dst_ptr]) \n\t" - "sw %[Temp2], 60(%[dst_ptr]) \n\t" - - : [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2) - : [dst_ptr] "r"(dst_ptr), [src_ptr] "r"(src_ptr), - [src_pixels_per_line] "r"(src_pixels_per_line)); - } - } -} - -void vp8_sixtap_predict8x4_dspr2(unsigned char *RESTRICT src_ptr, - int src_pixels_per_line, int xoffset, - int yoffset, unsigned char *RESTRICT dst_ptr, - int dst_pitch) { - unsigned char FData[9 * 8]; /* Temp data bufffer used in filtering */ - unsigned int pos, Temp1, Temp2; - - pos = 16; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - if (yoffset) { - src_ptr = src_ptr - (2 * src_pixels_per_line); - - if (xoffset) /* filter 1-D horizontally... */ - vp8_filter_block2d_first_pass_8_all(src_ptr, FData, src_pixels_per_line, - 9, xoffset, 8); - - else { - /* prefetch src_ptr data to cache memory */ - prefetch_load(src_ptr + 2 * src_pixels_per_line); - - __asm__ __volatile__( - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 0(%[FData]) \n\t" - "sw %[Temp2], 4(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 8(%[FData]) \n\t" - "sw %[Temp2], 12(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 16(%[FData]) \n\t" - "sw %[Temp2], 20(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 24(%[FData]) \n\t" - "sw %[Temp2], 28(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 32(%[FData]) \n\t" - "sw %[Temp2], 36(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 40(%[FData]) \n\t" - "sw %[Temp2], 44(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 48(%[FData]) \n\t" - "sw %[Temp2], 52(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 56(%[FData]) \n\t" - "sw %[Temp2], 60(%[FData]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 64(%[FData]) \n\t" - "sw %[Temp2], 68(%[FData]) \n\t" - - : [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2) - : [FData] "r"(FData), [src_ptr] "r"(src_ptr), - [src_pixels_per_line] "r"(src_pixels_per_line)); - } - - /* filter verticaly... */ - vp8_filter_block2d_second_pass_8(FData + 16, dst_ptr, dst_pitch, 4, 8, - yoffset); - } - - /* if (yoffsset == 0) vp8_filter_block2d_first_pass save data to dst_ptr */ - else { - if (xoffset) - vp8_filter_block2d_first_pass_8_all(src_ptr, dst_ptr, src_pixels_per_line, - 4, xoffset, dst_pitch); - - else { - /* copy from src buffer to dst buffer */ - __asm__ __volatile__( - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 0(%[dst_ptr]) \n\t" - "sw %[Temp2], 4(%[dst_ptr]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 8(%[dst_ptr]) \n\t" - "sw %[Temp2], 12(%[dst_ptr]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 16(%[dst_ptr]) \n\t" - "sw %[Temp2], 20(%[dst_ptr]) \n\t" - "addu %[src_ptr], %[src_ptr], %[src_pixels_per_line] \n\t" - - "ulw %[Temp1], 0(%[src_ptr]) \n\t" - "ulw %[Temp2], 4(%[src_ptr]) \n\t" - "sw %[Temp1], 24(%[dst_ptr]) \n\t" - "sw %[Temp2], 28(%[dst_ptr]) \n\t" - - : [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2) - : [dst_ptr] "r"(dst_ptr), [src_ptr] "r"(src_ptr), - [src_pixels_per_line] "r"(src_pixels_per_line)); - } - } -} - -void vp8_sixtap_predict16x16_dspr2(unsigned char *RESTRICT src_ptr, - int src_pixels_per_line, int xoffset, - int yoffset, unsigned char *RESTRICT dst_ptr, - int dst_pitch) { - const unsigned short *VFilter; - unsigned char FData[21 * 16]; /* Temp data bufffer used in filtering */ - unsigned int pos; - - VFilter = sub_pel_filterss[yoffset]; - - pos = 16; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - if (yoffset) { - src_ptr = src_ptr - (2 * src_pixels_per_line); - - switch (xoffset) { - /* filter 1-D horizontally... */ - case 2: - case 4: - case 6: - /* 6 tap filter */ - vp8_filter_block2d_first_pass16_6tap( - src_ptr, FData, src_pixels_per_line, 21, xoffset, 16); - break; - - case 0: - /* only copy buffer */ - vp8_filter_block2d_first_pass16_0(src_ptr, FData, src_pixels_per_line); - break; - - case 1: - case 3: - case 5: - case 7: - /* 4 tap filter */ - vp8_filter_block2d_first_pass16_4tap( - src_ptr, FData, src_pixels_per_line, 16, 21, xoffset, yoffset, - dst_ptr, dst_pitch); - break; - } - - /* filter verticaly... */ - vp8_filter_block2d_second_pass161(FData + 32, dst_ptr, dst_pitch, VFilter); - } else { - /* if (yoffsset == 0) vp8_filter_block2d_first_pass save data to dst_ptr */ - switch (xoffset) { - case 2: - case 4: - case 6: - /* 6 tap filter */ - vp8_filter_block2d_first_pass16_6tap( - src_ptr, dst_ptr, src_pixels_per_line, 16, xoffset, dst_pitch); - break; - - case 1: - case 3: - case 5: - case 7: - /* 4 tap filter */ - vp8_filter_block2d_first_pass16_4tap( - src_ptr, dst_ptr, src_pixels_per_line, 16, 21, xoffset, yoffset, - dst_ptr, dst_pitch); - break; - } - } -} - -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/idct_blk_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/idct_blk_dspr2.c deleted file mode 100644 index eae852d5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/idct_blk_dspr2.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "vp8_rtcd.h" - -#if HAVE_DSPR2 - -void vp8_dequant_idct_add_y_block_dspr2(short *q, short *dq, unsigned char *dst, - int stride, char *eobs) { - int i, j; - - for (i = 0; i < 4; ++i) { - for (j = 0; j < 4; ++j) { - if (*eobs++ > 1) - vp8_dequant_idct_add_dspr2(q, dq, dst, stride); - else { - vp8_dc_only_idct_add_dspr2(q[0] * dq[0], dst, stride, dst, stride); - ((int *)q)[0] = 0; - } - - q += 16; - dst += 4; - } - - dst += 4 * stride - 16; - } -} - -void vp8_dequant_idct_add_uv_block_dspr2(short *q, short *dq, - unsigned char *dst_u, - unsigned char *dst_v, int stride, - char *eobs) { - int i, j; - - for (i = 0; i < 2; ++i) { - for (j = 0; j < 2; ++j) { - if (*eobs++ > 1) - vp8_dequant_idct_add_dspr2(q, dq, dst_u, stride); - else { - vp8_dc_only_idct_add_dspr2(q[0] * dq[0], dst_u, stride, dst_u, stride); - ((int *)q)[0] = 0; - } - - q += 16; - dst_u += 4; - } - - dst_u += 4 * stride - 8; - } - - for (i = 0; i < 2; ++i) { - for (j = 0; j < 2; ++j) { - if (*eobs++ > 1) - vp8_dequant_idct_add_dspr2(q, dq, dst_v, stride); - else { - vp8_dc_only_idct_add_dspr2(q[0] * dq[0], dst_v, stride, dst_v, stride); - ((int *)q)[0] = 0; - } - - q += 16; - dst_v += 4; - } - - dst_v += 4 * stride - 8; - } -} - -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/idctllm_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/idctllm_dspr2.c deleted file mode 100644 index 9163ffad..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/idctllm_dspr2.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp8_rtcd.h" - -#if HAVE_DSPR2 -#define CROP_WIDTH 256 - -/****************************************************************************** - * Notes: - * - * This implementation makes use of 16 bit fixed point version of two multiply - * constants: - * 1. sqrt(2) * cos (pi/8) - * 2. sqrt(2) * sin (pi/8) - * Since the first constant is bigger than 1, to maintain the same 16 bit - * fixed point precision as the second one, we use a trick of - * x * a = x + x*(a-1) - * so - * x * sqrt(2) * cos (pi/8) = x + x * (sqrt(2) *cos(pi/8)-1). - ****************************************************************************/ -extern unsigned char ff_cropTbl[256 + 2 * CROP_WIDTH]; -static const int cospi8sqrt2minus1 = 20091; -static const int sinpi8sqrt2 = 35468; - -inline void prefetch_load_short(short *src) { - __asm__ __volatile__("pref 0, 0(%[src]) \n\t" : : [src] "r"(src)); -} - -void vp8_short_idct4x4llm_dspr2(short *input, unsigned char *pred_ptr, - int pred_stride, unsigned char *dst_ptr, - int dst_stride) { - int r, c; - int a1, b1, c1, d1; - short output[16]; - short *ip = input; - short *op = output; - int temp1, temp2; - int shortpitch = 4; - - int c2, d2; - int temp3, temp4; - unsigned char *cm = ff_cropTbl + CROP_WIDTH; - - /* prepare data for load */ - prefetch_load_short(ip + 8); - - /* first loop is unrolled */ - a1 = ip[0] + ip[8]; - b1 = ip[0] - ip[8]; - - temp1 = (ip[4] * sinpi8sqrt2) >> 16; - temp2 = ip[12] + ((ip[12] * cospi8sqrt2minus1) >> 16); - c1 = temp1 - temp2; - - temp1 = ip[4] + ((ip[4] * cospi8sqrt2minus1) >> 16); - temp2 = (ip[12] * sinpi8sqrt2) >> 16; - d1 = temp1 + temp2; - - temp3 = (ip[5] * sinpi8sqrt2) >> 16; - temp4 = ip[13] + ((ip[13] * cospi8sqrt2minus1) >> 16); - c2 = temp3 - temp4; - - temp3 = ip[5] + ((ip[5] * cospi8sqrt2minus1) >> 16); - temp4 = (ip[13] * sinpi8sqrt2) >> 16; - d2 = temp3 + temp4; - - op[0] = a1 + d1; - op[12] = a1 - d1; - op[4] = b1 + c1; - op[8] = b1 - c1; - - a1 = ip[1] + ip[9]; - b1 = ip[1] - ip[9]; - - op[1] = a1 + d2; - op[13] = a1 - d2; - op[5] = b1 + c2; - op[9] = b1 - c2; - - a1 = ip[2] + ip[10]; - b1 = ip[2] - ip[10]; - - temp1 = (ip[6] * sinpi8sqrt2) >> 16; - temp2 = ip[14] + ((ip[14] * cospi8sqrt2minus1) >> 16); - c1 = temp1 - temp2; - - temp1 = ip[6] + ((ip[6] * cospi8sqrt2minus1) >> 16); - temp2 = (ip[14] * sinpi8sqrt2) >> 16; - d1 = temp1 + temp2; - - temp3 = (ip[7] * sinpi8sqrt2) >> 16; - temp4 = ip[15] + ((ip[15] * cospi8sqrt2minus1) >> 16); - c2 = temp3 - temp4; - - temp3 = ip[7] + ((ip[7] * cospi8sqrt2minus1) >> 16); - temp4 = (ip[15] * sinpi8sqrt2) >> 16; - d2 = temp3 + temp4; - - op[2] = a1 + d1; - op[14] = a1 - d1; - op[6] = b1 + c1; - op[10] = b1 - c1; - - a1 = ip[3] + ip[11]; - b1 = ip[3] - ip[11]; - - op[3] = a1 + d2; - op[15] = a1 - d2; - op[7] = b1 + c2; - op[11] = b1 - c2; - - ip = output; - - /* prepare data for load */ - prefetch_load_short(ip + shortpitch); - - /* second loop is unrolled */ - a1 = ip[0] + ip[2]; - b1 = ip[0] - ip[2]; - - temp1 = (ip[1] * sinpi8sqrt2) >> 16; - temp2 = ip[3] + ((ip[3] * cospi8sqrt2minus1) >> 16); - c1 = temp1 - temp2; - - temp1 = ip[1] + ((ip[1] * cospi8sqrt2minus1) >> 16); - temp2 = (ip[3] * sinpi8sqrt2) >> 16; - d1 = temp1 + temp2; - - temp3 = (ip[5] * sinpi8sqrt2) >> 16; - temp4 = ip[7] + ((ip[7] * cospi8sqrt2minus1) >> 16); - c2 = temp3 - temp4; - - temp3 = ip[5] + ((ip[5] * cospi8sqrt2minus1) >> 16); - temp4 = (ip[7] * sinpi8sqrt2) >> 16; - d2 = temp3 + temp4; - - op[0] = (a1 + d1 + 4) >> 3; - op[3] = (a1 - d1 + 4) >> 3; - op[1] = (b1 + c1 + 4) >> 3; - op[2] = (b1 - c1 + 4) >> 3; - - a1 = ip[4] + ip[6]; - b1 = ip[4] - ip[6]; - - op[4] = (a1 + d2 + 4) >> 3; - op[7] = (a1 - d2 + 4) >> 3; - op[5] = (b1 + c2 + 4) >> 3; - op[6] = (b1 - c2 + 4) >> 3; - - a1 = ip[8] + ip[10]; - b1 = ip[8] - ip[10]; - - temp1 = (ip[9] * sinpi8sqrt2) >> 16; - temp2 = ip[11] + ((ip[11] * cospi8sqrt2minus1) >> 16); - c1 = temp1 - temp2; - - temp1 = ip[9] + ((ip[9] * cospi8sqrt2minus1) >> 16); - temp2 = (ip[11] * sinpi8sqrt2) >> 16; - d1 = temp1 + temp2; - - temp3 = (ip[13] * sinpi8sqrt2) >> 16; - temp4 = ip[15] + ((ip[15] * cospi8sqrt2minus1) >> 16); - c2 = temp3 - temp4; - - temp3 = ip[13] + ((ip[13] * cospi8sqrt2minus1) >> 16); - temp4 = (ip[15] * sinpi8sqrt2) >> 16; - d2 = temp3 + temp4; - - op[8] = (a1 + d1 + 4) >> 3; - op[11] = (a1 - d1 + 4) >> 3; - op[9] = (b1 + c1 + 4) >> 3; - op[10] = (b1 - c1 + 4) >> 3; - - a1 = ip[12] + ip[14]; - b1 = ip[12] - ip[14]; - - op[12] = (a1 + d2 + 4) >> 3; - op[15] = (a1 - d2 + 4) >> 3; - op[13] = (b1 + c2 + 4) >> 3; - op[14] = (b1 - c2 + 4) >> 3; - - ip = output; - - for (r = 0; r < 4; ++r) { - for (c = 0; c < 4; ++c) { - short a = ip[c] + pred_ptr[c]; - dst_ptr[c] = cm[a]; - } - - ip += 4; - dst_ptr += dst_stride; - pred_ptr += pred_stride; - } -} - -void vp8_dc_only_idct_add_dspr2(short input_dc, unsigned char *pred_ptr, - int pred_stride, unsigned char *dst_ptr, - int dst_stride) { - int a1; - int i, absa1; - int t2, vector_a1, vector_a; - - /* a1 = ((input_dc + 4) >> 3); */ - __asm__ __volatile__( - "addi %[a1], %[input_dc], 4 \n\t" - "sra %[a1], %[a1], 3 \n\t" - : [a1] "=r"(a1) - : [input_dc] "r"(input_dc)); - - if (a1 < 0) { - /* use quad-byte - * input and output memory are four byte aligned - */ - __asm__ __volatile__( - "abs %[absa1], %[a1] \n\t" - "replv.qb %[vector_a1], %[absa1] \n\t" - : [absa1] "=r"(absa1), [vector_a1] "=r"(vector_a1) - : [a1] "r"(a1)); - - /* use (a1 - predptr[c]) instead a1 + predptr[c] */ - for (i = 4; i--;) { - __asm__ __volatile__( - "lw %[t2], 0(%[pred_ptr]) \n\t" - "add %[pred_ptr], %[pred_ptr], %[pred_stride] \n\t" - "subu_s.qb %[vector_a], %[t2], %[vector_a1] \n\t" - "sw %[vector_a], 0(%[dst_ptr]) \n\t" - "add %[dst_ptr], %[dst_ptr], %[dst_stride] \n\t" - : [t2] "=&r"(t2), [vector_a] "=&r"(vector_a), - [dst_ptr] "+&r"(dst_ptr), [pred_ptr] "+&r"(pred_ptr) - : [dst_stride] "r"(dst_stride), [pred_stride] "r"(pred_stride), - [vector_a1] "r"(vector_a1)); - } - } else { - /* use quad-byte - * input and output memory are four byte aligned - */ - __asm__ __volatile__("replv.qb %[vector_a1], %[a1] \n\t" - : [vector_a1] "=r"(vector_a1) - : [a1] "r"(a1)); - - for (i = 4; i--;) { - __asm__ __volatile__( - "lw %[t2], 0(%[pred_ptr]) \n\t" - "add %[pred_ptr], %[pred_ptr], %[pred_stride] \n\t" - "addu_s.qb %[vector_a], %[vector_a1], %[t2] \n\t" - "sw %[vector_a], 0(%[dst_ptr]) \n\t" - "add %[dst_ptr], %[dst_ptr], %[dst_stride] \n\t" - : [t2] "=&r"(t2), [vector_a] "=&r"(vector_a), - [dst_ptr] "+&r"(dst_ptr), [pred_ptr] "+&r"(pred_ptr) - : [dst_stride] "r"(dst_stride), [pred_stride] "r"(pred_stride), - [vector_a1] "r"(vector_a1)); - } - } -} - -void vp8_short_inv_walsh4x4_dspr2(short *input, short *mb_dqcoeff) { - short output[16]; - int i; - int a1, b1, c1, d1; - int a2, b2, c2, d2; - short *ip = input; - short *op = output; - - prefetch_load_short(ip); - - for (i = 4; i--;) { - a1 = ip[0] + ip[12]; - b1 = ip[4] + ip[8]; - c1 = ip[4] - ip[8]; - d1 = ip[0] - ip[12]; - - op[0] = a1 + b1; - op[4] = c1 + d1; - op[8] = a1 - b1; - op[12] = d1 - c1; - - ip++; - op++; - } - - ip = output; - op = output; - - prefetch_load_short(ip); - - for (i = 4; i--;) { - a1 = ip[0] + ip[3] + 3; - b1 = ip[1] + ip[2]; - c1 = ip[1] - ip[2]; - d1 = ip[0] - ip[3] + 3; - - a2 = a1 + b1; - b2 = d1 + c1; - c2 = a1 - b1; - d2 = d1 - c1; - - op[0] = a2 >> 3; - op[1] = b2 >> 3; - op[2] = c2 >> 3; - op[3] = d2 >> 3; - - ip += 4; - op += 4; - } - - for (i = 0; i < 16; ++i) { - mb_dqcoeff[i * 16] = output[i]; - } -} - -void vp8_short_inv_walsh4x4_1_dspr2(short *input, short *mb_dqcoeff) { - int a1; - - a1 = ((input[0] + 3) >> 3); - - __asm__ __volatile__( - "sh %[a1], 0(%[mb_dqcoeff]) \n\t" - "sh %[a1], 32(%[mb_dqcoeff]) \n\t" - "sh %[a1], 64(%[mb_dqcoeff]) \n\t" - "sh %[a1], 96(%[mb_dqcoeff]) \n\t" - "sh %[a1], 128(%[mb_dqcoeff]) \n\t" - "sh %[a1], 160(%[mb_dqcoeff]) \n\t" - "sh %[a1], 192(%[mb_dqcoeff]) \n\t" - "sh %[a1], 224(%[mb_dqcoeff]) \n\t" - "sh %[a1], 256(%[mb_dqcoeff]) \n\t" - "sh %[a1], 288(%[mb_dqcoeff]) \n\t" - "sh %[a1], 320(%[mb_dqcoeff]) \n\t" - "sh %[a1], 352(%[mb_dqcoeff]) \n\t" - "sh %[a1], 384(%[mb_dqcoeff]) \n\t" - "sh %[a1], 416(%[mb_dqcoeff]) \n\t" - "sh %[a1], 448(%[mb_dqcoeff]) \n\t" - "sh %[a1], 480(%[mb_dqcoeff]) \n\t" - - : - : [a1] "r"(a1), [mb_dqcoeff] "r"(mb_dqcoeff)); -} - -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/reconinter_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/reconinter_dspr2.c deleted file mode 100644 index e44ae292..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/reconinter_dspr2.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "vp8_rtcd.h" -#include "vpx/vpx_integer.h" - -#if HAVE_DSPR2 -inline void prefetch_load_int(unsigned char *src) { - __asm__ __volatile__("pref 0, 0(%[src]) \n\t" : : [src] "r"(src)); -} - -__inline void vp8_copy_mem16x16_dspr2(unsigned char *RESTRICT src, - int src_stride, - unsigned char *RESTRICT dst, - int dst_stride) { - int r; - unsigned int a0, a1, a2, a3; - - for (r = 16; r--;) { - /* load src data in cache memory */ - prefetch_load_int(src + src_stride); - - /* use unaligned memory load and store */ - __asm__ __volatile__( - "ulw %[a0], 0(%[src]) \n\t" - "ulw %[a1], 4(%[src]) \n\t" - "ulw %[a2], 8(%[src]) \n\t" - "ulw %[a3], 12(%[src]) \n\t" - "sw %[a0], 0(%[dst]) \n\t" - "sw %[a1], 4(%[dst]) \n\t" - "sw %[a2], 8(%[dst]) \n\t" - "sw %[a3], 12(%[dst]) \n\t" - : [a0] "=&r"(a0), [a1] "=&r"(a1), [a2] "=&r"(a2), [a3] "=&r"(a3) - : [src] "r"(src), [dst] "r"(dst)); - - src += src_stride; - dst += dst_stride; - } -} - -__inline void vp8_copy_mem8x8_dspr2(unsigned char *RESTRICT src, int src_stride, - unsigned char *RESTRICT dst, - int dst_stride) { - int r; - unsigned int a0, a1; - - /* load src data in cache memory */ - prefetch_load_int(src + src_stride); - - for (r = 8; r--;) { - /* use unaligned memory load and store */ - __asm__ __volatile__( - "ulw %[a0], 0(%[src]) \n\t" - "ulw %[a1], 4(%[src]) \n\t" - "sw %[a0], 0(%[dst]) \n\t" - "sw %[a1], 4(%[dst]) \n\t" - : [a0] "=&r"(a0), [a1] "=&r"(a1) - : [src] "r"(src), [dst] "r"(dst)); - - src += src_stride; - dst += dst_stride; - } -} - -__inline void vp8_copy_mem8x4_dspr2(unsigned char *RESTRICT src, int src_stride, - unsigned char *RESTRICT dst, - int dst_stride) { - int r; - unsigned int a0, a1; - - /* load src data in cache memory */ - prefetch_load_int(src + src_stride); - - for (r = 4; r--;) { - /* use unaligned memory load and store */ - __asm__ __volatile__( - "ulw %[a0], 0(%[src]) \n\t" - "ulw %[a1], 4(%[src]) \n\t" - "sw %[a0], 0(%[dst]) \n\t" - "sw %[a1], 4(%[dst]) \n\t" - : [a0] "=&r"(a0), [a1] "=&r"(a1) - : [src] "r"(src), [dst] "r"(dst)); - - src += src_stride; - dst += dst_stride; - } -} - -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/vp8_loopfilter_filters_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/vp8_loopfilter_filters_dspr2.c deleted file mode 100644 index 21446fb4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/dspr2/vp8_loopfilter_filters_dspr2.c +++ /dev/null @@ -1,2401 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "vp8_rtcd.h" -#include "vp8/common/onyxc_int.h" - -#if HAVE_DSPR2 -typedef unsigned char uc; - -/* prefetch data for load */ -inline void prefetch_load_lf(unsigned char *src) { - __asm__ __volatile__("pref 0, 0(%[src]) \n\t" : : [src] "r"(src)); -} - -/* prefetch data for store */ -inline void prefetch_store_lf(unsigned char *dst) { - __asm__ __volatile__("pref 1, 0(%[dst]) \n\t" : : [dst] "r"(dst)); -} - -/* processing 4 pixels at the same time - * compute hev and mask in the same function - */ -static __inline void vp8_filter_mask_vec_mips( - uint32_t limit, uint32_t flimit, uint32_t p1, uint32_t p0, uint32_t p3, - uint32_t p2, uint32_t q0, uint32_t q1, uint32_t q2, uint32_t q3, - uint32_t thresh, uint32_t *hev, uint32_t *mask) { - uint32_t c, r, r3, r_k; - uint32_t s1, s2, s3; - uint32_t ones = 0xFFFFFFFF; - uint32_t hev1; - - __asm__ __volatile__( - /* mask |= (abs(p3 - p2) > limit) */ - "subu_s.qb %[c], %[p3], %[p2] \n\t" - "subu_s.qb %[r_k], %[p2], %[p3] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], $0, %[c] \n\t" - - /* mask |= (abs(p2 - p1) > limit) */ - "subu_s.qb %[c], %[p2], %[p1] \n\t" - "subu_s.qb %[r_k], %[p1], %[p2] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], %[r], %[c] \n\t" - - /* mask |= (abs(p1 - p0) > limit) - * hev |= (abs(p1 - p0) > thresh) - */ - "subu_s.qb %[c], %[p1], %[p0] \n\t" - "subu_s.qb %[r_k], %[p0], %[p1] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[thresh], %[r_k] \n\t" - "or %[r3], $0, %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], %[r], %[c] \n\t" - - /* mask |= (abs(q1 - q0) > limit) - * hev |= (abs(q1 - q0) > thresh) - */ - "subu_s.qb %[c], %[q1], %[q0] \n\t" - "subu_s.qb %[r_k], %[q0], %[q1] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[thresh], %[r_k] \n\t" - "or %[r3], %[r3], %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], %[r], %[c] \n\t" - - /* mask |= (abs(q2 - q1) > limit) */ - "subu_s.qb %[c], %[q2], %[q1] \n\t" - "subu_s.qb %[r_k], %[q1], %[q2] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], %[r], %[c] \n\t" - "sll %[r3], %[r3], 24 \n\t" - - /* mask |= (abs(q3 - q2) > limit) */ - "subu_s.qb %[c], %[q3], %[q2] \n\t" - "subu_s.qb %[r_k], %[q2], %[q3] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], %[r], %[c] \n\t" - - : [c] "=&r"(c), [r_k] "=&r"(r_k), [r] "=&r"(r), [r3] "=&r"(r3) - : [limit] "r"(limit), [p3] "r"(p3), [p2] "r"(p2), [p1] "r"(p1), - [p0] "r"(p0), [q1] "r"(q1), [q0] "r"(q0), [q2] "r"(q2), [q3] "r"(q3), - [thresh] "r"(thresh)); - - __asm__ __volatile__( - /* abs(p0 - q0) */ - "subu_s.qb %[c], %[p0], %[q0] \n\t" - "subu_s.qb %[r_k], %[q0], %[p0] \n\t" - "wrdsp %[r3] \n\t" - "or %[s1], %[r_k], %[c] \n\t" - - /* abs(p1 - q1) */ - "subu_s.qb %[c], %[p1], %[q1] \n\t" - "addu_s.qb %[s3], %[s1], %[s1] \n\t" - "pick.qb %[hev1], %[ones], $0 \n\t" - "subu_s.qb %[r_k], %[q1], %[p1] \n\t" - "or %[s2], %[r_k], %[c] \n\t" - - /* abs(p0 - q0) * 2 + abs(p1 - q1) / 2 > flimit * 2 + limit */ - "shrl.qb %[s2], %[s2], 1 \n\t" - "addu_s.qb %[s1], %[s2], %[s3] \n\t" - "cmpgu.lt.qb %[c], %[flimit], %[s1] \n\t" - "or %[r], %[r], %[c] \n\t" - "sll %[r], %[r], 24 \n\t" - - "wrdsp %[r] \n\t" - "pick.qb %[s2], $0, %[ones] \n\t" - - : [c] "=&r"(c), [r_k] "=&r"(r_k), [s1] "=&r"(s1), [hev1] "=&r"(hev1), - [s2] "=&r"(s2), [r] "+r"(r), [s3] "=&r"(s3) - : [p0] "r"(p0), [q0] "r"(q0), [p1] "r"(p1), [r3] "r"(r3), [q1] "r"(q1), - [ones] "r"(ones), [flimit] "r"(flimit)); - - *hev = hev1; - *mask = s2; -} - -/* inputs & outputs are quad-byte vectors */ -static __inline void vp8_filter_mips(uint32_t mask, uint32_t hev, uint32_t *ps1, - uint32_t *ps0, uint32_t *qs0, - uint32_t *qs1) { - int32_t vp8_filter_l, vp8_filter_r; - int32_t Filter1_l, Filter1_r, Filter2_l, Filter2_r; - int32_t subr_r, subr_l; - uint32_t t1, t2, HWM, t3; - uint32_t hev_l, hev_r, mask_l, mask_r, invhev_l, invhev_r; - - int32_t vps1, vps0, vqs0, vqs1; - int32_t vps1_l, vps1_r, vps0_l, vps0_r, vqs0_l, vqs0_r, vqs1_l, vqs1_r; - uint32_t N128; - - N128 = 0x80808080; - t1 = 0x03000300; - t2 = 0x04000400; - t3 = 0x01000100; - HWM = 0xFF00FF00; - - vps0 = (*ps0) ^ N128; - vps1 = (*ps1) ^ N128; - vqs0 = (*qs0) ^ N128; - vqs1 = (*qs1) ^ N128; - - /* use halfword pairs instead quad-bytes because of accuracy */ - vps0_l = vps0 & HWM; - vps0_r = vps0 << 8; - vps0_r = vps0_r & HWM; - - vps1_l = vps1 & HWM; - vps1_r = vps1 << 8; - vps1_r = vps1_r & HWM; - - vqs0_l = vqs0 & HWM; - vqs0_r = vqs0 << 8; - vqs0_r = vqs0_r & HWM; - - vqs1_l = vqs1 & HWM; - vqs1_r = vqs1 << 8; - vqs1_r = vqs1_r & HWM; - - mask_l = mask & HWM; - mask_r = mask << 8; - mask_r = mask_r & HWM; - - hev_l = hev & HWM; - hev_r = hev << 8; - hev_r = hev_r & HWM; - - __asm__ __volatile__( - /* vp8_filter = vp8_signed_char_clamp(ps1 - qs1); */ - "subq_s.ph %[vp8_filter_l], %[vps1_l], %[vqs1_l] \n\t" - "subq_s.ph %[vp8_filter_r], %[vps1_r], %[vqs1_r] \n\t" - - /* qs0 - ps0 */ - "subq_s.ph %[subr_l], %[vqs0_l], %[vps0_l] \n\t" - "subq_s.ph %[subr_r], %[vqs0_r], %[vps0_r] \n\t" - - /* vp8_filter &= hev; */ - "and %[vp8_filter_l], %[vp8_filter_l], %[hev_l] \n\t" - "and %[vp8_filter_r], %[vp8_filter_r], %[hev_r] \n\t" - - /* vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * (qs0 - ps0)); */ - "addq_s.ph %[vp8_filter_l], %[vp8_filter_l], %[subr_l] \n\t" - "addq_s.ph %[vp8_filter_r], %[vp8_filter_r], %[subr_r] \n\t" - "xor %[invhev_l], %[hev_l], %[HWM] \n\t" - "addq_s.ph %[vp8_filter_l], %[vp8_filter_l], %[subr_l] \n\t" - "addq_s.ph %[vp8_filter_r], %[vp8_filter_r], %[subr_r] \n\t" - "xor %[invhev_r], %[hev_r], %[HWM] \n\t" - "addq_s.ph %[vp8_filter_l], %[vp8_filter_l], %[subr_l] \n\t" - "addq_s.ph %[vp8_filter_r], %[vp8_filter_r], %[subr_r] \n\t" - - /* vp8_filter &= mask; */ - "and %[vp8_filter_l], %[vp8_filter_l], %[mask_l] \n\t" - "and %[vp8_filter_r], %[vp8_filter_r], %[mask_r] \n\t" - - : [vp8_filter_l] "=&r"(vp8_filter_l), [vp8_filter_r] "=&r"(vp8_filter_r), - [subr_l] "=&r"(subr_l), [subr_r] "=&r"(subr_r), - [invhev_l] "=&r"(invhev_l), [invhev_r] "=&r"(invhev_r) - - : [vps0_l] "r"(vps0_l), [vps0_r] "r"(vps0_r), [vps1_l] "r"(vps1_l), - [vps1_r] "r"(vps1_r), [vqs0_l] "r"(vqs0_l), [vqs0_r] "r"(vqs0_r), - [vqs1_l] "r"(vqs1_l), [vqs1_r] "r"(vqs1_r), [mask_l] "r"(mask_l), - [mask_r] "r"(mask_r), [hev_l] "r"(hev_l), [hev_r] "r"(hev_r), - [HWM] "r"(HWM)); - - /* save bottom 3 bits so that we round one side +4 and the other +3 */ - __asm__ __volatile__( - /* Filter2 = vp8_signed_char_clamp(vp8_filter + 3) >>= 3; */ - "addq_s.ph %[Filter1_l], %[vp8_filter_l], %[t2] \n\t" - "addq_s.ph %[Filter1_r], %[vp8_filter_r], %[t2] \n\t" - - /* Filter1 = vp8_signed_char_clamp(vp8_filter + 4) >>= 3; */ - "addq_s.ph %[Filter2_l], %[vp8_filter_l], %[t1] \n\t" - "addq_s.ph %[Filter2_r], %[vp8_filter_r], %[t1] \n\t" - "shra.ph %[Filter1_r], %[Filter1_r], 3 \n\t" - "shra.ph %[Filter1_l], %[Filter1_l], 3 \n\t" - - "shra.ph %[Filter2_l], %[Filter2_l], 3 \n\t" - "shra.ph %[Filter2_r], %[Filter2_r], 3 \n\t" - - "and %[Filter1_l], %[Filter1_l], %[HWM] \n\t" - "and %[Filter1_r], %[Filter1_r], %[HWM] \n\t" - - /* vps0 = vp8_signed_char_clamp(ps0 + Filter2); */ - "addq_s.ph %[vps0_l], %[vps0_l], %[Filter2_l] \n\t" - "addq_s.ph %[vps0_r], %[vps0_r], %[Filter2_r] \n\t" - - /* vqs0 = vp8_signed_char_clamp(qs0 - Filter1); */ - "subq_s.ph %[vqs0_l], %[vqs0_l], %[Filter1_l] \n\t" - "subq_s.ph %[vqs0_r], %[vqs0_r], %[Filter1_r] \n\t" - - : [Filter1_l] "=&r"(Filter1_l), [Filter1_r] "=&r"(Filter1_r), - [Filter2_l] "=&r"(Filter2_l), [Filter2_r] "=&r"(Filter2_r), - [vps0_l] "+r"(vps0_l), [vps0_r] "+r"(vps0_r), [vqs0_l] "+r"(vqs0_l), - [vqs0_r] "+r"(vqs0_r) - - : [t1] "r"(t1), [t2] "r"(t2), [vp8_filter_l] "r"(vp8_filter_l), - [vp8_filter_r] "r"(vp8_filter_r), [HWM] "r"(HWM)); - - __asm__ __volatile__( - /* (vp8_filter += 1) >>= 1 */ - "addqh.ph %[Filter1_l], %[Filter1_l], %[t3] \n\t" - "addqh.ph %[Filter1_r], %[Filter1_r], %[t3] \n\t" - - /* vp8_filter &= ~hev; */ - "and %[Filter1_l], %[Filter1_l], %[invhev_l] \n\t" - "and %[Filter1_r], %[Filter1_r], %[invhev_r] \n\t" - - /* vps1 = vp8_signed_char_clamp(ps1 + vp8_filter); */ - "addq_s.ph %[vps1_l], %[vps1_l], %[Filter1_l] \n\t" - "addq_s.ph %[vps1_r], %[vps1_r], %[Filter1_r] \n\t" - - /* vqs1 = vp8_signed_char_clamp(qs1 - vp8_filter); */ - "subq_s.ph %[vqs1_l], %[vqs1_l], %[Filter1_l] \n\t" - "subq_s.ph %[vqs1_r], %[vqs1_r], %[Filter1_r] \n\t" - - : [Filter1_l] "+r"(Filter1_l), [Filter1_r] "+r"(Filter1_r), - [vps1_l] "+r"(vps1_l), [vps1_r] "+r"(vps1_r), [vqs1_l] "+r"(vqs1_l), - [vqs1_r] "+r"(vqs1_r) - - : [t3] "r"(t3), [invhev_l] "r"(invhev_l), [invhev_r] "r"(invhev_r)); - - /* Create quad-bytes from halfword pairs */ - vqs0_l = vqs0_l & HWM; - vqs1_l = vqs1_l & HWM; - vps0_l = vps0_l & HWM; - vps1_l = vps1_l & HWM; - - __asm__ __volatile__( - "shrl.ph %[vqs0_r], %[vqs0_r], 8 \n\t" - "shrl.ph %[vps0_r], %[vps0_r], 8 \n\t" - "shrl.ph %[vqs1_r], %[vqs1_r], 8 \n\t" - "shrl.ph %[vps1_r], %[vps1_r], 8 \n\t" - - : [vps1_r] "+r"(vps1_r), [vqs1_r] "+r"(vqs1_r), [vps0_r] "+r"(vps0_r), - [vqs0_r] "+r"(vqs0_r) - :); - - vqs0 = vqs0_l | vqs0_r; - vqs1 = vqs1_l | vqs1_r; - vps0 = vps0_l | vps0_r; - vps1 = vps1_l | vps1_r; - - *ps0 = vps0 ^ N128; - *ps1 = vps1 ^ N128; - *qs0 = vqs0 ^ N128; - *qs1 = vqs1 ^ N128; -} - -void vp8_loop_filter_horizontal_edge_mips(unsigned char *s, int p, - unsigned int flimit, - unsigned int limit, - unsigned int thresh, int count) { - uint32_t mask; - uint32_t hev; - uint32_t pm1, p0, p1, p2, p3, p4, p5, p6; - unsigned char *sm1, *s0, *s1, *s2, *s3, *s4, *s5, *s6; - (void)count; - - mask = 0; - hev = 0; - p1 = 0; - p2 = 0; - p3 = 0; - p4 = 0; - - /* prefetch data for store */ - prefetch_store_lf(s); - - /* loop filter designed to work using chars so that we can make maximum use - * of 8 bit simd instructions. - */ - - sm1 = s - (p << 2); - s0 = s - p - p - p; - s1 = s - p - p; - s2 = s - p; - s3 = s; - s4 = s + p; - s5 = s + p + p; - s6 = s + p + p + p; - - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p1 = *((uint32_t *)(s1)); - p2 = *((uint32_t *)(s2)); - p3 = *((uint32_t *)(s3)); - p4 = *((uint32_t *)(s4)); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - pm1 = *((uint32_t *)(sm1)); - p0 = *((uint32_t *)(s0)); - p5 = *((uint32_t *)(s5)); - p6 = *((uint32_t *)(s6)); - - vp8_filter_mask_vec_mips(limit, flimit, p1, p2, pm1, p0, p3, p4, p5, p6, - thresh, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - vp8_filter_mips(mask, hev, &p1, &p2, &p3, &p4); - - /* unpack processed 4x4 neighborhood */ - *((uint32_t *)s1) = p1; - *((uint32_t *)s2) = p2; - *((uint32_t *)s3) = p3; - *((uint32_t *)s4) = p4; - } - } - - sm1 += 4; - s0 += 4; - s1 += 4; - s2 += 4; - s3 += 4; - s4 += 4; - s5 += 4; - s6 += 4; - - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p1 = *((uint32_t *)(s1)); - p2 = *((uint32_t *)(s2)); - p3 = *((uint32_t *)(s3)); - p4 = *((uint32_t *)(s4)); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - pm1 = *((uint32_t *)(sm1)); - p0 = *((uint32_t *)(s0)); - p5 = *((uint32_t *)(s5)); - p6 = *((uint32_t *)(s6)); - - vp8_filter_mask_vec_mips(limit, flimit, p1, p2, pm1, p0, p3, p4, p5, p6, - thresh, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - vp8_filter_mips(mask, hev, &p1, &p2, &p3, &p4); - - /* unpack processed 4x4 neighborhood */ - *((uint32_t *)s1) = p1; - *((uint32_t *)s2) = p2; - *((uint32_t *)s3) = p3; - *((uint32_t *)s4) = p4; - } - } - - sm1 += 4; - s0 += 4; - s1 += 4; - s2 += 4; - s3 += 4; - s4 += 4; - s5 += 4; - s6 += 4; - - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p1 = *((uint32_t *)(s1)); - p2 = *((uint32_t *)(s2)); - p3 = *((uint32_t *)(s3)); - p4 = *((uint32_t *)(s4)); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - pm1 = *((uint32_t *)(sm1)); - p0 = *((uint32_t *)(s0)); - p5 = *((uint32_t *)(s5)); - p6 = *((uint32_t *)(s6)); - - vp8_filter_mask_vec_mips(limit, flimit, p1, p2, pm1, p0, p3, p4, p5, p6, - thresh, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - vp8_filter_mips(mask, hev, &p1, &p2, &p3, &p4); - - /* unpack processed 4x4 neighborhood */ - *((uint32_t *)s1) = p1; - *((uint32_t *)s2) = p2; - *((uint32_t *)s3) = p3; - *((uint32_t *)s4) = p4; - } - } - - sm1 += 4; - s0 += 4; - s1 += 4; - s2 += 4; - s3 += 4; - s4 += 4; - s5 += 4; - s6 += 4; - - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p1 = *((uint32_t *)(s1)); - p2 = *((uint32_t *)(s2)); - p3 = *((uint32_t *)(s3)); - p4 = *((uint32_t *)(s4)); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - pm1 = *((uint32_t *)(sm1)); - p0 = *((uint32_t *)(s0)); - p5 = *((uint32_t *)(s5)); - p6 = *((uint32_t *)(s6)); - - vp8_filter_mask_vec_mips(limit, flimit, p1, p2, pm1, p0, p3, p4, p5, p6, - thresh, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - vp8_filter_mips(mask, hev, &p1, &p2, &p3, &p4); - - /* unpack processed 4x4 neighborhood */ - *((uint32_t *)s1) = p1; - *((uint32_t *)s2) = p2; - *((uint32_t *)s3) = p3; - *((uint32_t *)s4) = p4; - } - } -} - -void vp8_loop_filter_uvhorizontal_edge_mips(unsigned char *s, int p, - unsigned int flimit, - unsigned int limit, - unsigned int thresh, int count) { - uint32_t mask; - uint32_t hev; - uint32_t pm1, p0, p1, p2, p3, p4, p5, p6; - unsigned char *sm1, *s0, *s1, *s2, *s3, *s4, *s5, *s6; - (void)count; - - mask = 0; - hev = 0; - p1 = 0; - p2 = 0; - p3 = 0; - p4 = 0; - - /* loop filter designed to work using chars so that we can make maximum use - * of 8 bit simd instructions. - */ - - sm1 = s - (p << 2); - s0 = s - p - p - p; - s1 = s - p - p; - s2 = s - p; - s3 = s; - s4 = s + p; - s5 = s + p + p; - s6 = s + p + p + p; - - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p1 = *((uint32_t *)(s1)); - p2 = *((uint32_t *)(s2)); - p3 = *((uint32_t *)(s3)); - p4 = *((uint32_t *)(s4)); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - pm1 = *((uint32_t *)(sm1)); - p0 = *((uint32_t *)(s0)); - p5 = *((uint32_t *)(s5)); - p6 = *((uint32_t *)(s6)); - - vp8_filter_mask_vec_mips(limit, flimit, p1, p2, pm1, p0, p3, p4, p5, p6, - thresh, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - vp8_filter_mips(mask, hev, &p1, &p2, &p3, &p4); - - /* unpack processed 4x4 neighborhood */ - *((uint32_t *)s1) = p1; - *((uint32_t *)s2) = p2; - *((uint32_t *)s3) = p3; - *((uint32_t *)s4) = p4; - } - } - - sm1 += 4; - s0 += 4; - s1 += 4; - s2 += 4; - s3 += 4; - s4 += 4; - s5 += 4; - s6 += 4; - - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p1 = *((uint32_t *)(s1)); - p2 = *((uint32_t *)(s2)); - p3 = *((uint32_t *)(s3)); - p4 = *((uint32_t *)(s4)); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - pm1 = *((uint32_t *)(sm1)); - p0 = *((uint32_t *)(s0)); - p5 = *((uint32_t *)(s5)); - p6 = *((uint32_t *)(s6)); - - vp8_filter_mask_vec_mips(limit, flimit, p1, p2, pm1, p0, p3, p4, p5, p6, - thresh, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - vp8_filter_mips(mask, hev, &p1, &p2, &p3, &p4); - - /* unpack processed 4x4 neighborhood */ - *((uint32_t *)s1) = p1; - *((uint32_t *)s2) = p2; - *((uint32_t *)s3) = p3; - *((uint32_t *)s4) = p4; - } - } -} - -void vp8_loop_filter_vertical_edge_mips(unsigned char *s, int p, - const unsigned int flimit, - const unsigned int limit, - const unsigned int thresh, int count) { - int i; - uint32_t mask, hev; - uint32_t pm1, p0, p1, p2, p3, p4, p5, p6; - unsigned char *s1, *s2, *s3, *s4; - uint32_t prim1, prim2, sec3, sec4, prim3, prim4; - - hev = 0; - mask = 0; - i = 0; - pm1 = 0; - p0 = 0; - p1 = 0; - p2 = 0; - p3 = 0; - p4 = 0; - p5 = 0; - p6 = 0; - - /* loop filter designed to work using chars so that we can make maximum use - * of 8 bit simd instructions. - */ - - /* apply filter on 4 pixesl at the same time */ - do { - /* prefetch data for store */ - prefetch_store_lf(s + p); - - s1 = s; - s2 = s + p; - s3 = s2 + p; - s4 = s3 + p; - s = s4 + p; - - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p2 = *((uint32_t *)(s1 - 4)); - p6 = *((uint32_t *)(s1)); - p1 = *((uint32_t *)(s2 - 4)); - p5 = *((uint32_t *)(s2)); - p0 = *((uint32_t *)(s3 - 4)); - p4 = *((uint32_t *)(s3)); - pm1 = *((uint32_t *)(s4 - 4)); - p3 = *((uint32_t *)(s4)); - - /* transpose pm1, p0, p1, p2 */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p2], %[p1] \n\t" - "precr.qb.ph %[prim2], %[p2], %[p1] \n\t" - "precrq.qb.ph %[prim3], %[p0], %[pm1] \n\t" - "precr.qb.ph %[prim4], %[p0], %[pm1] \n\t" - - "precrq.qb.ph %[p1], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[pm1], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p2], %[p1], %[sec3] \n\t" - "precrq.ph.w %[p0], %[pm1], %[sec4] \n\t" - "append %[p1], %[sec3], 16 \n\t" - "append %[pm1], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p2] "+r"(p2), [p1] "+r"(p1), [p0] "+r"(p0), - [pm1] "+r"(pm1), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* transpose p3, p4, p5, p6 */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p6], %[p5] \n\t" - "precr.qb.ph %[prim2], %[p6], %[p5] \n\t" - "precrq.qb.ph %[prim3], %[p4], %[p3] \n\t" - "precr.qb.ph %[prim4], %[p4], %[p3] \n\t" - - "precrq.qb.ph %[p5], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[p3], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p6], %[p5], %[sec3] \n\t" - "precrq.ph.w %[p4], %[p3], %[sec4] \n\t" - "append %[p5], %[sec3], 16 \n\t" - "append %[p3], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p6] "+r"(p6), [p5] "+r"(p5), [p4] "+r"(p4), - [p3] "+r"(p3), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - vp8_filter_mask_vec_mips(limit, flimit, p1, p2, pm1, p0, p3, p4, p5, p6, - thresh, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - vp8_filter_mips(mask, hev, &p1, &p2, &p3, &p4); - - /* unpack processed 4x4 neighborhood - * don't use transpose on output data - * because memory isn't aligned - */ - __asm__ __volatile__( - "sb %[p4], 1(%[s4]) \n\t" - "sb %[p3], 0(%[s4]) \n\t" - "sb %[p2], -1(%[s4]) \n\t" - "sb %[p1], -2(%[s4]) \n\t" - : - : [p4] "r"(p4), [p3] "r"(p3), [s4] "r"(s4), [p2] "r"(p2), - [p1] "r"(p1)); - - __asm__ __volatile__( - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - : [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), [p1] "+r"(p1) - :); - - __asm__ __volatile__( - "sb %[p4], 1(%[s3]) \n\t" - "sb %[p3], 0(%[s3]) \n\t" - "sb %[p2], -1(%[s3]) \n\t" - "sb %[p1], -2(%[s3]) \n\t" - : [p1] "+r"(p1) - : [p4] "r"(p4), [p3] "r"(p3), [s3] "r"(s3), [p2] "r"(p2)); - - __asm__ __volatile__( - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - : [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), [p1] "+r"(p1) - :); - - __asm__ __volatile__( - "sb %[p4], 1(%[s2]) \n\t" - "sb %[p3], 0(%[s2]) \n\t" - "sb %[p2], -1(%[s2]) \n\t" - "sb %[p1], -2(%[s2]) \n\t" - : - : [p4] "r"(p4), [p3] "r"(p3), [s2] "r"(s2), [p2] "r"(p2), - [p1] "r"(p1)); - - __asm__ __volatile__( - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - : [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), [p1] "+r"(p1) - :); - - __asm__ __volatile__( - "sb %[p4], 1(%[s1]) \n\t" - "sb %[p3], 0(%[s1]) \n\t" - "sb %[p2], -1(%[s1]) \n\t" - "sb %[p1], -2(%[s1]) \n\t" - : - : [p4] "r"(p4), [p3] "r"(p3), [s1] "r"(s1), [p2] "r"(p2), - [p1] "r"(p1)); - } - } - - s1 = s; - s2 = s + p; - s3 = s2 + p; - s4 = s3 + p; - s = s4 + p; - - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p2 = *((uint32_t *)(s1 - 4)); - p6 = *((uint32_t *)(s1)); - p1 = *((uint32_t *)(s2 - 4)); - p5 = *((uint32_t *)(s2)); - p0 = *((uint32_t *)(s3 - 4)); - p4 = *((uint32_t *)(s3)); - pm1 = *((uint32_t *)(s4 - 4)); - p3 = *((uint32_t *)(s4)); - - /* transpose pm1, p0, p1, p2 */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p2], %[p1] \n\t" - "precr.qb.ph %[prim2], %[p2], %[p1] \n\t" - "precrq.qb.ph %[prim3], %[p0], %[pm1] \n\t" - "precr.qb.ph %[prim4], %[p0], %[pm1] \n\t" - - "precrq.qb.ph %[p1], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[pm1], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p2], %[p1], %[sec3] \n\t" - "precrq.ph.w %[p0], %[pm1], %[sec4] \n\t" - "append %[p1], %[sec3], 16 \n\t" - "append %[pm1], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p2] "+r"(p2), [p1] "+r"(p1), [p0] "+r"(p0), - [pm1] "+r"(pm1), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* transpose p3, p4, p5, p6 */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p6], %[p5] \n\t" - "precr.qb.ph %[prim2], %[p6], %[p5] \n\t" - "precrq.qb.ph %[prim3], %[p4], %[p3] \n\t" - "precr.qb.ph %[prim4], %[p4], %[p3] \n\t" - - "precrq.qb.ph %[p5], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[p3], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p6], %[p5], %[sec3] \n\t" - "precrq.ph.w %[p4], %[p3], %[sec4] \n\t" - "append %[p5], %[sec3], 16 \n\t" - "append %[p3], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p6] "+r"(p6), [p5] "+r"(p5), [p4] "+r"(p4), - [p3] "+r"(p3), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - vp8_filter_mask_vec_mips(limit, flimit, p1, p2, pm1, p0, p3, p4, p5, p6, - thresh, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - vp8_filter_mips(mask, hev, &p1, &p2, &p3, &p4); - - /* unpack processed 4x4 neighborhood - * don't use transpose on output data - * because memory isn't aligned - */ - __asm__ __volatile__( - "sb %[p4], 1(%[s4]) \n\t" - "sb %[p3], 0(%[s4]) \n\t" - "sb %[p2], -1(%[s4]) \n\t" - "sb %[p1], -2(%[s4]) \n\t" - : - : [p4] "r"(p4), [p3] "r"(p3), [s4] "r"(s4), [p2] "r"(p2), - [p1] "r"(p1)); - - __asm__ __volatile__( - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - : [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), [p1] "+r"(p1) - :); - - __asm__ __volatile__( - "sb %[p4], 1(%[s3]) \n\t" - "sb %[p3], 0(%[s3]) \n\t" - "sb %[p2], -1(%[s3]) \n\t" - "sb %[p1], -2(%[s3]) \n\t" - : [p1] "+r"(p1) - : [p4] "r"(p4), [p3] "r"(p3), [s3] "r"(s3), [p2] "r"(p2)); - - __asm__ __volatile__( - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - : [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), [p1] "+r"(p1) - :); - - __asm__ __volatile__( - "sb %[p4], 1(%[s2]) \n\t" - "sb %[p3], 0(%[s2]) \n\t" - "sb %[p2], -1(%[s2]) \n\t" - "sb %[p1], -2(%[s2]) \n\t" - : - : [p4] "r"(p4), [p3] "r"(p3), [s2] "r"(s2), [p2] "r"(p2), - [p1] "r"(p1)); - - __asm__ __volatile__( - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - : [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), [p1] "+r"(p1) - :); - - __asm__ __volatile__( - "sb %[p4], 1(%[s1]) \n\t" - "sb %[p3], 0(%[s1]) \n\t" - "sb %[p2], -1(%[s1]) \n\t" - "sb %[p1], -2(%[s1]) \n\t" - : - : [p4] "r"(p4), [p3] "r"(p3), [s1] "r"(s1), [p2] "r"(p2), - [p1] "r"(p1)); - } - } - - i += 8; - } - - while (i < count); -} - -void vp8_loop_filter_uvvertical_edge_mips(unsigned char *s, int p, - unsigned int flimit, - unsigned int limit, - unsigned int thresh, int count) { - uint32_t mask, hev; - uint32_t pm1, p0, p1, p2, p3, p4, p5, p6; - unsigned char *s1, *s2, *s3, *s4; - uint32_t prim1, prim2, sec3, sec4, prim3, prim4; - (void)count; - - /* loop filter designed to work using chars so that we can make maximum use - * of 8 bit simd instructions. - */ - - /* apply filter on 4 pixesl at the same time */ - - s1 = s; - s2 = s + p; - s3 = s2 + p; - s4 = s3 + p; - - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p2 = *((uint32_t *)(s1 - 4)); - p6 = *((uint32_t *)(s1)); - p1 = *((uint32_t *)(s2 - 4)); - p5 = *((uint32_t *)(s2)); - p0 = *((uint32_t *)(s3 - 4)); - p4 = *((uint32_t *)(s3)); - pm1 = *((uint32_t *)(s4 - 4)); - p3 = *((uint32_t *)(s4)); - - /* transpose pm1, p0, p1, p2 */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p2], %[p1] \n\t" - "precr.qb.ph %[prim2], %[p2], %[p1] \n\t" - "precrq.qb.ph %[prim3], %[p0], %[pm1] \n\t" - "precr.qb.ph %[prim4], %[p0], %[pm1] \n\t" - - "precrq.qb.ph %[p1], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[pm1], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p2], %[p1], %[sec3] \n\t" - "precrq.ph.w %[p0], %[pm1], %[sec4] \n\t" - "append %[p1], %[sec3], 16 \n\t" - "append %[pm1], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p2] "+r"(p2), [p1] "+r"(p1), [p0] "+r"(p0), - [pm1] "+r"(pm1), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* transpose p3, p4, p5, p6 */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p6], %[p5] \n\t" - "precr.qb.ph %[prim2], %[p6], %[p5] \n\t" - "precrq.qb.ph %[prim3], %[p4], %[p3] \n\t" - "precr.qb.ph %[prim4], %[p4], %[p3] \n\t" - - "precrq.qb.ph %[p5], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[p3], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p6], %[p5], %[sec3] \n\t" - "precrq.ph.w %[p4], %[p3], %[sec4] \n\t" - "append %[p5], %[sec3], 16 \n\t" - "append %[p3], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p6] "+r"(p6), [p5] "+r"(p5), [p4] "+r"(p4), - [p3] "+r"(p3), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - vp8_filter_mask_vec_mips(limit, flimit, p1, p2, pm1, p0, p3, p4, p5, p6, - thresh, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - vp8_filter_mips(mask, hev, &p1, &p2, &p3, &p4); - - /* unpack processed 4x4 neighborhood - * don't use transpose on output data - * because memory isn't aligned - */ - __asm__ __volatile__( - "sb %[p4], 1(%[s4]) \n\t" - "sb %[p3], 0(%[s4]) \n\t" - "sb %[p2], -1(%[s4]) \n\t" - "sb %[p1], -2(%[s4]) \n\t" - : - : - [p4] "r"(p4), [p3] "r"(p3), [s4] "r"(s4), [p2] "r"(p2), [p1] "r"(p1)); - - __asm__ __volatile__( - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - : [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), [p1] "+r"(p1) - :); - - __asm__ __volatile__( - "sb %[p4], 1(%[s3]) \n\t" - "sb %[p3], 0(%[s3]) \n\t" - "sb %[p2], -1(%[s3]) \n\t" - "sb %[p1], -2(%[s3]) \n\t" - : [p1] "+r"(p1) - : [p4] "r"(p4), [p3] "r"(p3), [s3] "r"(s3), [p2] "r"(p2)); - - __asm__ __volatile__( - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - : [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), [p1] "+r"(p1) - :); - - __asm__ __volatile__( - "sb %[p4], 1(%[s2]) \n\t" - "sb %[p3], 0(%[s2]) \n\t" - "sb %[p2], -1(%[s2]) \n\t" - "sb %[p1], -2(%[s2]) \n\t" - : - : - [p4] "r"(p4), [p3] "r"(p3), [s2] "r"(s2), [p2] "r"(p2), [p1] "r"(p1)); - - __asm__ __volatile__( - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - : [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), [p1] "+r"(p1) - :); - - __asm__ __volatile__( - "sb %[p4], 1(%[s1]) \n\t" - "sb %[p3], 0(%[s1]) \n\t" - "sb %[p2], -1(%[s1]) \n\t" - "sb %[p1], -2(%[s1]) \n\t" - : - : - [p4] "r"(p4), [p3] "r"(p3), [s1] "r"(s1), [p2] "r"(p2), [p1] "r"(p1)); - } - } - - s1 = s4 + p; - s2 = s1 + p; - s3 = s2 + p; - s4 = s3 + p; - - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p2 = *((uint32_t *)(s1 - 4)); - p6 = *((uint32_t *)(s1)); - p1 = *((uint32_t *)(s2 - 4)); - p5 = *((uint32_t *)(s2)); - p0 = *((uint32_t *)(s3 - 4)); - p4 = *((uint32_t *)(s3)); - pm1 = *((uint32_t *)(s4 - 4)); - p3 = *((uint32_t *)(s4)); - - /* transpose pm1, p0, p1, p2 */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p2], %[p1] \n\t" - "precr.qb.ph %[prim2], %[p2], %[p1] \n\t" - "precrq.qb.ph %[prim3], %[p0], %[pm1] \n\t" - "precr.qb.ph %[prim4], %[p0], %[pm1] \n\t" - - "precrq.qb.ph %[p1], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[pm1], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p2], %[p1], %[sec3] \n\t" - "precrq.ph.w %[p0], %[pm1], %[sec4] \n\t" - "append %[p1], %[sec3], 16 \n\t" - "append %[pm1], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p2] "+r"(p2), [p1] "+r"(p1), [p0] "+r"(p0), - [pm1] "+r"(pm1), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* transpose p3, p4, p5, p6 */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p6], %[p5] \n\t" - "precr.qb.ph %[prim2], %[p6], %[p5] \n\t" - "precrq.qb.ph %[prim3], %[p4], %[p3] \n\t" - "precr.qb.ph %[prim4], %[p4], %[p3] \n\t" - - "precrq.qb.ph %[p5], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[p3], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p6], %[p5], %[sec3] \n\t" - "precrq.ph.w %[p4], %[p3], %[sec4] \n\t" - "append %[p5], %[sec3], 16 \n\t" - "append %[p3], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p6] "+r"(p6), [p5] "+r"(p5), [p4] "+r"(p4), - [p3] "+r"(p3), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - vp8_filter_mask_vec_mips(limit, flimit, p1, p2, pm1, p0, p3, p4, p5, p6, - thresh, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - vp8_filter_mips(mask, hev, &p1, &p2, &p3, &p4); - - /* unpack processed 4x4 neighborhood - * don't use transpose on output data - * because memory isn't aligned - */ - __asm__ __volatile__( - "sb %[p4], 1(%[s4]) \n\t" - "sb %[p3], 0(%[s4]) \n\t" - "sb %[p2], -1(%[s4]) \n\t" - "sb %[p1], -2(%[s4]) \n\t" - : - : - [p4] "r"(p4), [p3] "r"(p3), [s4] "r"(s4), [p2] "r"(p2), [p1] "r"(p1)); - - __asm__ __volatile__( - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - : [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), [p1] "+r"(p1) - :); - - __asm__ __volatile__( - "sb %[p4], 1(%[s3]) \n\t" - "sb %[p3], 0(%[s3]) \n\t" - "sb %[p2], -1(%[s3]) \n\t" - "sb %[p1], -2(%[s3]) \n\t" - : [p1] "+r"(p1) - : [p4] "r"(p4), [p3] "r"(p3), [s3] "r"(s3), [p2] "r"(p2)); - - __asm__ __volatile__( - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - : [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), [p1] "+r"(p1) - :); - - __asm__ __volatile__( - "sb %[p4], 1(%[s2]) \n\t" - "sb %[p3], 0(%[s2]) \n\t" - "sb %[p2], -1(%[s2]) \n\t" - "sb %[p1], -2(%[s2]) \n\t" - : - : - [p4] "r"(p4), [p3] "r"(p3), [s2] "r"(s2), [p2] "r"(p2), [p1] "r"(p1)); - - __asm__ __volatile__( - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - : [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), [p1] "+r"(p1) - :); - - __asm__ __volatile__( - "sb %[p4], 1(%[s1]) \n\t" - "sb %[p3], 0(%[s1]) \n\t" - "sb %[p2], -1(%[s1]) \n\t" - "sb %[p1], -2(%[s1]) \n\t" - : - : - [p4] "r"(p4), [p3] "r"(p3), [s1] "r"(s1), [p2] "r"(p2), [p1] "r"(p1)); - } - } -} - -/* inputs & outputs are quad-byte vectors */ -static __inline void vp8_mbfilter_mips(uint32_t mask, uint32_t hev, - uint32_t *ps2, uint32_t *ps1, - uint32_t *ps0, uint32_t *qs0, - uint32_t *qs1, uint32_t *qs2) { - int32_t vps2, vps1, vps0, vqs0, vqs1, vqs2; - int32_t vps2_l, vps1_l, vps0_l, vqs0_l, vqs1_l, vqs2_l; - int32_t vps2_r, vps1_r, vps0_r, vqs0_r, vqs1_r, vqs2_r; - uint32_t HWM, vp8_filter_l, vp8_filter_r, mask_l, mask_r, hev_l, hev_r, - subr_r, subr_l; - uint32_t Filter2_l, Filter2_r, t1, t2, Filter1_l, Filter1_r, invhev_l, - invhev_r; - uint32_t N128, R63; - uint32_t u1_l, u1_r, u2_l, u2_r, u3_l, u3_r; - - R63 = 0x003F003F; - HWM = 0xFF00FF00; - N128 = 0x80808080; - t1 = 0x03000300; - t2 = 0x04000400; - - vps0 = (*ps0) ^ N128; - vps1 = (*ps1) ^ N128; - vps2 = (*ps2) ^ N128; - vqs0 = (*qs0) ^ N128; - vqs1 = (*qs1) ^ N128; - vqs2 = (*qs2) ^ N128; - - /* use halfword pairs instead quad-bytes because of accuracy */ - vps0_l = vps0 & HWM; - vps0_r = vps0 << 8; - vps0_r = vps0_r & HWM; - - vqs0_l = vqs0 & HWM; - vqs0_r = vqs0 << 8; - vqs0_r = vqs0_r & HWM; - - vps1_l = vps1 & HWM; - vps1_r = vps1 << 8; - vps1_r = vps1_r & HWM; - - vqs1_l = vqs1 & HWM; - vqs1_r = vqs1 << 8; - vqs1_r = vqs1_r & HWM; - - vqs2_l = vqs2 & HWM; - vqs2_r = vqs2 << 8; - vqs2_r = vqs2_r & HWM; - - __asm__ __volatile__( - /* qs0 - ps0 */ - "subq_s.ph %[subr_l], %[vqs0_l], %[vps0_l] \n\t" - "subq_s.ph %[subr_r], %[vqs0_r], %[vps0_r] \n\t" - - /* vp8_filter = vp8_signed_char_clamp(ps1 - qs1); */ - "subq_s.ph %[vp8_filter_l], %[vps1_l], %[vqs1_l] \n\t" - "subq_s.ph %[vp8_filter_r], %[vps1_r], %[vqs1_r] \n\t" - - : [vp8_filter_l] "=&r"(vp8_filter_l), [vp8_filter_r] "=r"(vp8_filter_r), - [subr_l] "=&r"(subr_l), [subr_r] "=&r"(subr_r) - : [vps0_l] "r"(vps0_l), [vps0_r] "r"(vps0_r), [vps1_l] "r"(vps1_l), - [vps1_r] "r"(vps1_r), [vqs0_l] "r"(vqs0_l), [vqs0_r] "r"(vqs0_r), - [vqs1_l] "r"(vqs1_l), [vqs1_r] "r"(vqs1_r)); - - vps2_l = vps2 & HWM; - vps2_r = vps2 << 8; - vps2_r = vps2_r & HWM; - - /* add outer taps if we have high edge variance */ - __asm__ __volatile__( - /* vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * (qs0 - ps0)); */ - "addq_s.ph %[vp8_filter_l], %[vp8_filter_l], %[subr_l] \n\t" - "addq_s.ph %[vp8_filter_r], %[vp8_filter_r], %[subr_r] \n\t" - "and %[mask_l], %[HWM], %[mask] \n\t" - "sll %[mask_r], %[mask], 8 \n\t" - "and %[mask_r], %[HWM], %[mask_r] \n\t" - "addq_s.ph %[vp8_filter_l], %[vp8_filter_l], %[subr_l] \n\t" - "addq_s.ph %[vp8_filter_r], %[vp8_filter_r], %[subr_r] \n\t" - "and %[hev_l], %[HWM], %[hev] \n\t" - "sll %[hev_r], %[hev], 8 \n\t" - "and %[hev_r], %[HWM], %[hev_r] \n\t" - "addq_s.ph %[vp8_filter_l], %[vp8_filter_l], %[subr_l] \n\t" - "addq_s.ph %[vp8_filter_r], %[vp8_filter_r], %[subr_r] \n\t" - - /* vp8_filter &= mask; */ - "and %[vp8_filter_l], %[vp8_filter_l], %[mask_l] \n\t" - "and %[vp8_filter_r], %[vp8_filter_r], %[mask_r] \n\t" - - /* Filter2 = vp8_filter & hev; */ - "and %[Filter2_l], %[vp8_filter_l], %[hev_l] \n\t" - "and %[Filter2_r], %[vp8_filter_r], %[hev_r] \n\t" - - : [vp8_filter_l] "+r"(vp8_filter_l), [vp8_filter_r] "+r"(vp8_filter_r), - [hev_l] "=&r"(hev_l), [hev_r] "=&r"(hev_r), [mask_l] "=&r"(mask_l), - [mask_r] "=&r"(mask_r), [Filter2_l] "=&r"(Filter2_l), - [Filter2_r] "=&r"(Filter2_r) - : [subr_l] "r"(subr_l), [subr_r] "r"(subr_r), [HWM] "r"(HWM), - [hev] "r"(hev), [mask] "r"(mask)); - - /* save bottom 3 bits so that we round one side +4 and the other +3 */ - __asm__ __volatile__( - /* Filter1 = vp8_signed_char_clamp(Filter2 + 4) >>= 3; */ - "addq_s.ph %[Filter1_l], %[Filter2_l], %[t2] \n\t" - "xor %[invhev_l], %[hev_l], %[HWM] \n\t" - "addq_s.ph %[Filter1_r], %[Filter2_r], %[t2] \n\t" - - /* Filter2 = vp8_signed_char_clamp(Filter2 + 3) >>= 3; */ - "addq_s.ph %[Filter2_l], %[Filter2_l], %[t1] \n\t" - "addq_s.ph %[Filter2_r], %[Filter2_r], %[t1] \n\t" - - "shra.ph %[Filter1_l], %[Filter1_l], 3 \n\t" - "shra.ph %[Filter1_r], %[Filter1_r], 3 \n\t" - - "shra.ph %[Filter2_l], %[Filter2_l], 3 \n\t" - "shra.ph %[Filter2_r], %[Filter2_r], 3 \n\t" - "and %[Filter1_l], %[Filter1_l], %[HWM] \n\t" - "and %[Filter1_r], %[Filter1_r], %[HWM] \n\t" - "xor %[invhev_r], %[hev_r], %[HWM] \n\t" - - /* qs0 = vp8_signed_char_clamp(qs0 - Filter1); */ - "subq_s.ph %[vqs0_l], %[vqs0_l], %[Filter1_l] \n\t" - "subq_s.ph %[vqs0_r], %[vqs0_r], %[Filter1_r] \n\t" - - /* ps0 = vp8_signed_char_clamp(ps0 + Filter2); */ - "addq_s.ph %[vps0_l], %[vps0_l], %[Filter2_l] \n\t" - "addq_s.ph %[vps0_r], %[vps0_r], %[Filter2_r] \n\t" - - : [invhev_l] "=&r"(invhev_l), [invhev_r] "=&r"(invhev_r), - [Filter1_l] "=&r"(Filter1_l), [Filter1_r] "=&r"(Filter1_r), - [Filter2_l] "+r"(Filter2_l), [Filter2_r] "+r"(Filter2_r), - [vps0_l] "+r"(vps0_l), [vps0_r] "+r"(vps0_r), [vqs0_l] "+r"(vqs0_l), - [vqs0_r] "+r"(vqs0_r) - : [t1] "r"(t1), [t2] "r"(t2), [HWM] "r"(HWM), [hev_l] "r"(hev_l), - [hev_r] "r"(hev_r)); - - /* only apply wider filter if not high edge variance */ - __asm__ __volatile__( - /* vp8_filter &= ~hev; */ - "and %[Filter2_l], %[vp8_filter_l], %[invhev_l] \n\t" - "and %[Filter2_r], %[vp8_filter_r], %[invhev_r] \n\t" - - "shra.ph %[Filter2_l], %[Filter2_l], 8 \n\t" - "shra.ph %[Filter2_r], %[Filter2_r], 8 \n\t" - - : [Filter2_l] "=&r"(Filter2_l), [Filter2_r] "=&r"(Filter2_r) - : [vp8_filter_l] "r"(vp8_filter_l), [vp8_filter_r] "r"(vp8_filter_r), - [invhev_l] "r"(invhev_l), [invhev_r] "r"(invhev_r)); - - /* roughly 3/7th difference across boundary */ - __asm__ __volatile__( - "shll.ph %[u3_l], %[Filter2_l], 3 \n\t" - "shll.ph %[u3_r], %[Filter2_r], 3 \n\t" - - "addq.ph %[u3_l], %[u3_l], %[Filter2_l] \n\t" - "addq.ph %[u3_r], %[u3_r], %[Filter2_r] \n\t" - - "shll.ph %[u2_l], %[u3_l], 1 \n\t" - "shll.ph %[u2_r], %[u3_r], 1 \n\t" - - "addq.ph %[u1_l], %[u3_l], %[u2_l] \n\t" - "addq.ph %[u1_r], %[u3_r], %[u2_r] \n\t" - - "addq.ph %[u2_l], %[u2_l], %[R63] \n\t" - "addq.ph %[u2_r], %[u2_r], %[R63] \n\t" - - "addq.ph %[u3_l], %[u3_l], %[R63] \n\t" - "addq.ph %[u3_r], %[u3_r], %[R63] \n\t" - - /* vp8_signed_char_clamp((63 + Filter2 * 27) >> 7) - * vp8_signed_char_clamp((63 + Filter2 * 18) >> 7) - */ - "addq.ph %[u1_l], %[u1_l], %[R63] \n\t" - "addq.ph %[u1_r], %[u1_r], %[R63] \n\t" - "shra.ph %[u1_l], %[u1_l], 7 \n\t" - "shra.ph %[u1_r], %[u1_r], 7 \n\t" - "shra.ph %[u2_l], %[u2_l], 7 \n\t" - "shra.ph %[u2_r], %[u2_r], 7 \n\t" - "shll.ph %[u1_l], %[u1_l], 8 \n\t" - "shll.ph %[u1_r], %[u1_r], 8 \n\t" - "shll.ph %[u2_l], %[u2_l], 8 \n\t" - "shll.ph %[u2_r], %[u2_r], 8 \n\t" - - /* vqs0 = vp8_signed_char_clamp(qs0 - u); */ - "subq_s.ph %[vqs0_l], %[vqs0_l], %[u1_l] \n\t" - "subq_s.ph %[vqs0_r], %[vqs0_r], %[u1_r] \n\t" - - /* vps0 = vp8_signed_char_clamp(ps0 + u); */ - "addq_s.ph %[vps0_l], %[vps0_l], %[u1_l] \n\t" - "addq_s.ph %[vps0_r], %[vps0_r], %[u1_r] \n\t" - - : [u1_l] "=&r"(u1_l), [u1_r] "=&r"(u1_r), [u2_l] "=&r"(u2_l), - [u2_r] "=&r"(u2_r), [u3_l] "=&r"(u3_l), [u3_r] "=&r"(u3_r), - [vps0_l] "+r"(vps0_l), [vps0_r] "+r"(vps0_r), [vqs0_l] "+r"(vqs0_l), - [vqs0_r] "+r"(vqs0_r) - : [R63] "r"(R63), [Filter2_l] "r"(Filter2_l), [Filter2_r] "r"(Filter2_r)); - - __asm__ __volatile__( - /* vqs1 = vp8_signed_char_clamp(qs1 - u); */ - "subq_s.ph %[vqs1_l], %[vqs1_l], %[u2_l] \n\t" - "addq_s.ph %[vps1_l], %[vps1_l], %[u2_l] \n\t" - - /* vps1 = vp8_signed_char_clamp(ps1 + u); */ - "addq_s.ph %[vps1_r], %[vps1_r], %[u2_r] \n\t" - "subq_s.ph %[vqs1_r], %[vqs1_r], %[u2_r] \n\t" - - : [vps1_l] "+r"(vps1_l), [vps1_r] "+r"(vps1_r), [vqs1_l] "+r"(vqs1_l), - [vqs1_r] "+r"(vqs1_r) - : [u2_l] "r"(u2_l), [u2_r] "r"(u2_r)); - - /* roughly 1/7th difference across boundary */ - __asm__ __volatile__( - /* u = vp8_signed_char_clamp((63 + Filter2 * 9) >> 7); */ - "shra.ph %[u3_l], %[u3_l], 7 \n\t" - "shra.ph %[u3_r], %[u3_r], 7 \n\t" - "shll.ph %[u3_l], %[u3_l], 8 \n\t" - "shll.ph %[u3_r], %[u3_r], 8 \n\t" - - /* vqs2 = vp8_signed_char_clamp(qs2 - u); */ - "subq_s.ph %[vqs2_l], %[vqs2_l], %[u3_l] \n\t" - "subq_s.ph %[vqs2_r], %[vqs2_r], %[u3_r] \n\t" - - /* vps2 = vp8_signed_char_clamp(ps2 + u); */ - "addq_s.ph %[vps2_l], %[vps2_l], %[u3_l] \n\t" - "addq_s.ph %[vps2_r], %[vps2_r], %[u3_r] \n\t" - - : [u3_l] "+r"(u3_l), [u3_r] "+r"(u3_r), [vps2_l] "+r"(vps2_l), - [vps2_r] "+r"(vps2_r), [vqs2_l] "+r"(vqs2_l), [vqs2_r] "+r"(vqs2_r) - :); - - /* Create quad-bytes from halfword pairs */ - __asm__ __volatile__( - "and %[vqs0_l], %[vqs0_l], %[HWM] \n\t" - "shrl.ph %[vqs0_r], %[vqs0_r], 8 \n\t" - - "and %[vps0_l], %[vps0_l], %[HWM] \n\t" - "shrl.ph %[vps0_r], %[vps0_r], 8 \n\t" - - "and %[vqs1_l], %[vqs1_l], %[HWM] \n\t" - "shrl.ph %[vqs1_r], %[vqs1_r], 8 \n\t" - - "and %[vps1_l], %[vps1_l], %[HWM] \n\t" - "shrl.ph %[vps1_r], %[vps1_r], 8 \n\t" - - "and %[vqs2_l], %[vqs2_l], %[HWM] \n\t" - "shrl.ph %[vqs2_r], %[vqs2_r], 8 \n\t" - - "and %[vps2_l], %[vps2_l], %[HWM] \n\t" - "shrl.ph %[vps2_r], %[vps2_r], 8 \n\t" - - "or %[vqs0_r], %[vqs0_l], %[vqs0_r] \n\t" - "or %[vps0_r], %[vps0_l], %[vps0_r] \n\t" - "or %[vqs1_r], %[vqs1_l], %[vqs1_r] \n\t" - "or %[vps1_r], %[vps1_l], %[vps1_r] \n\t" - "or %[vqs2_r], %[vqs2_l], %[vqs2_r] \n\t" - "or %[vps2_r], %[vps2_l], %[vps2_r] \n\t" - - : [vps1_l] "+r"(vps1_l), [vps1_r] "+r"(vps1_r), [vqs1_l] "+r"(vqs1_l), - [vqs1_r] "+r"(vqs1_r), [vps0_l] "+r"(vps0_l), [vps0_r] "+r"(vps0_r), - [vqs0_l] "+r"(vqs0_l), [vqs0_r] "+r"(vqs0_r), [vqs2_l] "+r"(vqs2_l), - [vqs2_r] "+r"(vqs2_r), [vps2_r] "+r"(vps2_r), [vps2_l] "+r"(vps2_l) - : [HWM] "r"(HWM)); - - *ps0 = vps0_r ^ N128; - *ps1 = vps1_r ^ N128; - *ps2 = vps2_r ^ N128; - *qs0 = vqs0_r ^ N128; - *qs1 = vqs1_r ^ N128; - *qs2 = vqs2_r ^ N128; -} - -void vp8_mbloop_filter_horizontal_edge_mips(unsigned char *s, int p, - unsigned int flimit, - unsigned int limit, - unsigned int thresh, int count) { - int i; - uint32_t mask, hev; - uint32_t pm1, p0, p1, p2, p3, p4, p5, p6; - unsigned char *sm1, *s0, *s1, *s2, *s3, *s4, *s5, *s6; - - mask = 0; - hev = 0; - i = 0; - p1 = 0; - p2 = 0; - p3 = 0; - p4 = 0; - - /* loop filter designed to work using chars so that we can make maximum use - * of 8 bit simd instructions. - */ - - sm1 = s - (p << 2); - s0 = s - p - p - p; - s1 = s - p - p; - s2 = s - p; - s3 = s; - s4 = s + p; - s5 = s + p + p; - s6 = s + p + p + p; - - /* prefetch data for load */ - prefetch_load_lf(s + p); - - /* apply filter on 4 pixesl at the same time */ - do { - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p1 = *((uint32_t *)(s1)); - p2 = *((uint32_t *)(s2)); - p3 = *((uint32_t *)(s3)); - p4 = *((uint32_t *)(s4)); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - pm1 = *((uint32_t *)(sm1)); - p0 = *((uint32_t *)(s0)); - p5 = *((uint32_t *)(s5)); - p6 = *((uint32_t *)(s6)); - - vp8_filter_mask_vec_mips(limit, flimit, p1, p2, pm1, p0, p3, p4, p5, p6, - thresh, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - vp8_mbfilter_mips(mask, hev, &p0, &p1, &p2, &p3, &p4, &p5); - - /* unpack processed 4x4 neighborhood - * memory is 4 byte aligned - */ - *((uint32_t *)s0) = p0; - *((uint32_t *)s1) = p1; - *((uint32_t *)s2) = p2; - *((uint32_t *)s3) = p3; - *((uint32_t *)s4) = p4; - *((uint32_t *)s5) = p5; - } - } - - sm1 += 4; - s0 += 4; - s1 += 4; - s2 += 4; - s3 += 4; - s4 += 4; - s5 += 4; - s6 += 4; - - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p1 = *((uint32_t *)(s1)); - p2 = *((uint32_t *)(s2)); - p3 = *((uint32_t *)(s3)); - p4 = *((uint32_t *)(s4)); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - pm1 = *((uint32_t *)(sm1)); - p0 = *((uint32_t *)(s0)); - p5 = *((uint32_t *)(s5)); - p6 = *((uint32_t *)(s6)); - - vp8_filter_mask_vec_mips(limit, flimit, p1, p2, pm1, p0, p3, p4, p5, p6, - thresh, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - vp8_mbfilter_mips(mask, hev, &p0, &p1, &p2, &p3, &p4, &p5); - - /* unpack processed 4x4 neighborhood - * memory is 4 byte aligned - */ - *((uint32_t *)s0) = p0; - *((uint32_t *)s1) = p1; - *((uint32_t *)s2) = p2; - *((uint32_t *)s3) = p3; - *((uint32_t *)s4) = p4; - *((uint32_t *)s5) = p5; - } - } - - sm1 += 4; - s0 += 4; - s1 += 4; - s2 += 4; - s3 += 4; - s4 += 4; - s5 += 4; - s6 += 4; - - i += 8; - } - - while (i < count); -} - -void vp8_mbloop_filter_uvhorizontal_edge_mips(unsigned char *s, int p, - unsigned int flimit, - unsigned int limit, - unsigned int thresh, int count) { - uint32_t mask, hev; - uint32_t pm1, p0, p1, p2, p3, p4, p5, p6; - unsigned char *sm1, *s0, *s1, *s2, *s3, *s4, *s5, *s6; - (void)count; - - mask = 0; - hev = 0; - p1 = 0; - p2 = 0; - p3 = 0; - p4 = 0; - - /* loop filter designed to work using chars so that we can make maximum use - * of 8 bit simd instructions. - */ - - sm1 = s - (p << 2); - s0 = s - p - p - p; - s1 = s - p - p; - s2 = s - p; - s3 = s; - s4 = s + p; - s5 = s + p + p; - s6 = s + p + p + p; - - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p1 = *((uint32_t *)(s1)); - p2 = *((uint32_t *)(s2)); - p3 = *((uint32_t *)(s3)); - p4 = *((uint32_t *)(s4)); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - pm1 = *((uint32_t *)(sm1)); - p0 = *((uint32_t *)(s0)); - p5 = *((uint32_t *)(s5)); - p6 = *((uint32_t *)(s6)); - - /* if mask == 0 do filtering is not needed */ - vp8_filter_mask_vec_mips(limit, flimit, p1, p2, pm1, p0, p3, p4, p5, p6, - thresh, &hev, &mask); - - if (mask) { - /* filtering */ - vp8_mbfilter_mips(mask, hev, &p0, &p1, &p2, &p3, &p4, &p5); - - /* unpack processed 4x4 neighborhood - * memory is 4 byte aligned - */ - *((uint32_t *)s0) = p0; - *((uint32_t *)s1) = p1; - *((uint32_t *)s2) = p2; - *((uint32_t *)s3) = p3; - *((uint32_t *)s4) = p4; - *((uint32_t *)s5) = p5; - } - } - - sm1 += 4; - s0 += 4; - s1 += 4; - s2 += 4; - s3 += 4; - s4 += 4; - s5 += 4; - s6 += 4; - - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p1 = *((uint32_t *)(s1)); - p2 = *((uint32_t *)(s2)); - p3 = *((uint32_t *)(s3)); - p4 = *((uint32_t *)(s4)); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - pm1 = *((uint32_t *)(sm1)); - p0 = *((uint32_t *)(s0)); - p5 = *((uint32_t *)(s5)); - p6 = *((uint32_t *)(s6)); - - vp8_filter_mask_vec_mips(limit, flimit, p1, p2, pm1, p0, p3, p4, p5, p6, - thresh, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - vp8_mbfilter_mips(mask, hev, &p0, &p1, &p2, &p3, &p4, &p5); - - /* unpack processed 4x4 neighborhood - * memory is 4 byte aligned - */ - *((uint32_t *)s0) = p0; - *((uint32_t *)s1) = p1; - *((uint32_t *)s2) = p2; - *((uint32_t *)s3) = p3; - *((uint32_t *)s4) = p4; - *((uint32_t *)s5) = p5; - } - } -} - -void vp8_mbloop_filter_vertical_edge_mips(unsigned char *s, int p, - unsigned int flimit, - unsigned int limit, - unsigned int thresh, int count) { - int i; - uint32_t mask, hev; - uint32_t pm1, p0, p1, p2, p3, p4, p5, p6; - unsigned char *s1, *s2, *s3, *s4; - uint32_t prim1, prim2, sec3, sec4, prim3, prim4; - - mask = 0; - hev = 0; - i = 0; - pm1 = 0; - p0 = 0; - p1 = 0; - p2 = 0; - p3 = 0; - p4 = 0; - p5 = 0; - p6 = 0; - - /* loop filter designed to work using chars so that we can make maximum use - * of 8 bit simd instructions. - */ - - /* apply filter on 4 pixesl at the same time */ - do { - s1 = s; - s2 = s + p; - s3 = s2 + p; - s4 = s3 + p; - s = s4 + p; - - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p2 = *((uint32_t *)(s1 - 4)); - p6 = *((uint32_t *)(s1)); - p1 = *((uint32_t *)(s2 - 4)); - p5 = *((uint32_t *)(s2)); - p0 = *((uint32_t *)(s3 - 4)); - p4 = *((uint32_t *)(s3)); - pm1 = *((uint32_t *)(s4 - 4)); - p3 = *((uint32_t *)(s4)); - - /* transpose pm1, p0, p1, p2 */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p2], %[p1] \n\t" - "precr.qb.ph %[prim2], %[p2], %[p1] \n\t" - "precrq.qb.ph %[prim3], %[p0], %[pm1] \n\t" - "precr.qb.ph %[prim4], %[p0], %[pm1] \n\t" - - "precrq.qb.ph %[p1], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[pm1], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p2], %[p1], %[sec3] \n\t" - "precrq.ph.w %[p0], %[pm1], %[sec4] \n\t" - "append %[p1], %[sec3], 16 \n\t" - "append %[pm1], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p2] "+r"(p2), [p1] "+r"(p1), [p0] "+r"(p0), - [pm1] "+r"(pm1), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* transpose p3, p4, p5, p6 */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p6], %[p5] \n\t" - "precr.qb.ph %[prim2], %[p6], %[p5] \n\t" - "precrq.qb.ph %[prim3], %[p4], %[p3] \n\t" - "precr.qb.ph %[prim4], %[p4], %[p3] \n\t" - - "precrq.qb.ph %[p5], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[p3], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p6], %[p5], %[sec3] \n\t" - "precrq.ph.w %[p4], %[p3], %[sec4] \n\t" - "append %[p5], %[sec3], 16 \n\t" - "append %[p3], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p6] "+r"(p6), [p5] "+r"(p5), [p4] "+r"(p4), - [p3] "+r"(p3), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - vp8_filter_mask_vec_mips(limit, flimit, p1, p2, pm1, p0, p3, p4, p5, p6, - thresh, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - vp8_mbfilter_mips(mask, hev, &p0, &p1, &p2, &p3, &p4, &p5); - - /* don't use transpose on output data - * because memory isn't aligned - */ - __asm__ __volatile__( - "sb %[p5], 2(%[s4]) \n\t" - "sb %[p4], 1(%[s4]) \n\t" - "sb %[p3], 0(%[s4]) \n\t" - "sb %[p2], -1(%[s4]) \n\t" - "sb %[p1], -2(%[s4]) \n\t" - "sb %[p0], -3(%[s4]) \n\t" - : - : [p5] "r"(p5), [p4] "r"(p4), [p3] "r"(p3), [s4] "r"(s4), - [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0)); - - __asm__ __volatile__( - "srl %[p5], %[p5], 8 \n\t" - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - "srl %[p0], %[p0], 8 \n\t" - : [p5] "+r"(p5), [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), - [p1] "+r"(p1), [p0] "+r"(p0) - :); - - __asm__ __volatile__( - "sb %[p5], 2(%[s3]) \n\t" - "sb %[p4], 1(%[s3]) \n\t" - "sb %[p3], 0(%[s3]) \n\t" - "sb %[p2], -1(%[s3]) \n\t" - "sb %[p1], -2(%[s3]) \n\t" - "sb %[p0], -3(%[s3]) \n\t" - : - : [p5] "r"(p5), [p4] "r"(p4), [p3] "r"(p3), [s3] "r"(s3), - [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0)); - - __asm__ __volatile__( - "srl %[p5], %[p5], 8 \n\t" - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - "srl %[p0], %[p0], 8 \n\t" - : [p5] "+r"(p5), [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), - [p1] "+r"(p1), [p0] "+r"(p0) - :); - - __asm__ __volatile__( - "sb %[p5], 2(%[s2]) \n\t" - "sb %[p4], 1(%[s2]) \n\t" - "sb %[p3], 0(%[s2]) \n\t" - "sb %[p2], -1(%[s2]) \n\t" - "sb %[p1], -2(%[s2]) \n\t" - "sb %[p0], -3(%[s2]) \n\t" - : - : [p5] "r"(p5), [p4] "r"(p4), [p3] "r"(p3), [s2] "r"(s2), - [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0)); - - __asm__ __volatile__( - "srl %[p5], %[p5], 8 \n\t" - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - "srl %[p0], %[p0], 8 \n\t" - : [p5] "+r"(p5), [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), - [p1] "+r"(p1), [p0] "+r"(p0) - :); - - __asm__ __volatile__( - "sb %[p5], 2(%[s1]) \n\t" - "sb %[p4], 1(%[s1]) \n\t" - "sb %[p3], 0(%[s1]) \n\t" - "sb %[p2], -1(%[s1]) \n\t" - "sb %[p1], -2(%[s1]) \n\t" - "sb %[p0], -3(%[s1]) \n\t" - : - : [p5] "r"(p5), [p4] "r"(p4), [p3] "r"(p3), [s1] "r"(s1), - [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0)); - } - } - - i += 4; - } - - while (i < count); -} - -void vp8_mbloop_filter_uvvertical_edge_mips(unsigned char *s, int p, - unsigned int flimit, - unsigned int limit, - unsigned int thresh, int count) { - uint32_t mask, hev; - uint32_t pm1, p0, p1, p2, p3, p4, p5, p6; - unsigned char *s1, *s2, *s3, *s4; - uint32_t prim1, prim2, sec3, sec4, prim3, prim4; - (void)count; - - mask = 0; - hev = 0; - pm1 = 0; - p0 = 0; - p1 = 0; - p2 = 0; - p3 = 0; - p4 = 0; - p5 = 0; - p6 = 0; - - /* loop filter designed to work using chars so that we can make maximum use - * of 8 bit simd instructions. - */ - - /* apply filter on 4 pixesl at the same time */ - - s1 = s; - s2 = s + p; - s3 = s2 + p; - s4 = s3 + p; - - /* prefetch data for load */ - prefetch_load_lf(s + 2 * p); - - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p2 = *((uint32_t *)(s1 - 4)); - p6 = *((uint32_t *)(s1)); - p1 = *((uint32_t *)(s2 - 4)); - p5 = *((uint32_t *)(s2)); - p0 = *((uint32_t *)(s3 - 4)); - p4 = *((uint32_t *)(s3)); - pm1 = *((uint32_t *)(s4 - 4)); - p3 = *((uint32_t *)(s4)); - - /* transpose pm1, p0, p1, p2 */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p2], %[p1] \n\t" - "precr.qb.ph %[prim2], %[p2], %[p1] \n\t" - "precrq.qb.ph %[prim3], %[p0], %[pm1] \n\t" - "precr.qb.ph %[prim4], %[p0], %[pm1] \n\t" - - "precrq.qb.ph %[p1], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[pm1], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p2], %[p1], %[sec3] \n\t" - "precrq.ph.w %[p0], %[pm1], %[sec4] \n\t" - "append %[p1], %[sec3], 16 \n\t" - "append %[pm1], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p2] "+r"(p2), [p1] "+r"(p1), [p0] "+r"(p0), - [pm1] "+r"(pm1), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* transpose p3, p4, p5, p6 */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p6], %[p5] \n\t" - "precr.qb.ph %[prim2], %[p6], %[p5] \n\t" - "precrq.qb.ph %[prim3], %[p4], %[p3] \n\t" - "precr.qb.ph %[prim4], %[p4], %[p3] \n\t" - - "precrq.qb.ph %[p5], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[p3], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p6], %[p5], %[sec3] \n\t" - "precrq.ph.w %[p4], %[p3], %[sec4] \n\t" - "append %[p5], %[sec3], 16 \n\t" - "append %[p3], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p6] "+r"(p6), [p5] "+r"(p5), [p4] "+r"(p4), - [p3] "+r"(p3), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - vp8_filter_mask_vec_mips(limit, flimit, p1, p2, pm1, p0, p3, p4, p5, p6, - thresh, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - vp8_mbfilter_mips(mask, hev, &p0, &p1, &p2, &p3, &p4, &p5); - - /* don't use transpose on output data - * because memory isn't aligned - */ - __asm__ __volatile__( - "sb %[p5], 2(%[s4]) \n\t" - "sb %[p4], 1(%[s4]) \n\t" - "sb %[p3], 0(%[s4]) \n\t" - "sb %[p2], -1(%[s4]) \n\t" - "sb %[p1], -2(%[s4]) \n\t" - "sb %[p0], -3(%[s4]) \n\t" - : - : [p5] "r"(p5), [p4] "r"(p4), [p3] "r"(p3), [s4] "r"(s4), - [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0)); - - __asm__ __volatile__( - "srl %[p5], %[p5], 8 \n\t" - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - "srl %[p0], %[p0], 8 \n\t" - : [p5] "+r"(p5), [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), - [p1] "+r"(p1), [p0] "+r"(p0) - :); - - __asm__ __volatile__( - "sb %[p5], 2(%[s3]) \n\t" - "sb %[p4], 1(%[s3]) \n\t" - "sb %[p3], 0(%[s3]) \n\t" - "sb %[p2], -1(%[s3]) \n\t" - "sb %[p1], -2(%[s3]) \n\t" - "sb %[p0], -3(%[s3]) \n\t" - : - : [p5] "r"(p5), [p4] "r"(p4), [p3] "r"(p3), [s3] "r"(s3), - [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0)); - - __asm__ __volatile__( - "srl %[p5], %[p5], 8 \n\t" - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - "srl %[p0], %[p0], 8 \n\t" - : [p5] "+r"(p5), [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), - [p1] "+r"(p1), [p0] "+r"(p0) - :); - - __asm__ __volatile__( - "sb %[p5], 2(%[s2]) \n\t" - "sb %[p4], 1(%[s2]) \n\t" - "sb %[p3], 0(%[s2]) \n\t" - "sb %[p2], -1(%[s2]) \n\t" - "sb %[p1], -2(%[s2]) \n\t" - "sb %[p0], -3(%[s2]) \n\t" - : - : [p5] "r"(p5), [p4] "r"(p4), [p3] "r"(p3), [s2] "r"(s2), - [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0)); - - __asm__ __volatile__( - "srl %[p5], %[p5], 8 \n\t" - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - "srl %[p0], %[p0], 8 \n\t" - : [p5] "+r"(p5), [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), - [p1] "+r"(p1), [p0] "+r"(p0) - :); - - __asm__ __volatile__( - "sb %[p5], 2(%[s1]) \n\t" - "sb %[p4], 1(%[s1]) \n\t" - "sb %[p3], 0(%[s1]) \n\t" - "sb %[p2], -1(%[s1]) \n\t" - "sb %[p1], -2(%[s1]) \n\t" - "sb %[p0], -3(%[s1]) \n\t" - : - : [p5] "r"(p5), [p4] "r"(p4), [p3] "r"(p3), [s1] "r"(s1), - [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0)); - } - } - - s1 = s4 + p; - s2 = s1 + p; - s3 = s2 + p; - s4 = s3 + p; - - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p2 = *((uint32_t *)(s1 - 4)); - p6 = *((uint32_t *)(s1)); - p1 = *((uint32_t *)(s2 - 4)); - p5 = *((uint32_t *)(s2)); - p0 = *((uint32_t *)(s3 - 4)); - p4 = *((uint32_t *)(s3)); - pm1 = *((uint32_t *)(s4 - 4)); - p3 = *((uint32_t *)(s4)); - - /* transpose pm1, p0, p1, p2 */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p2], %[p1] \n\t" - "precr.qb.ph %[prim2], %[p2], %[p1] \n\t" - "precrq.qb.ph %[prim3], %[p0], %[pm1] \n\t" - "precr.qb.ph %[prim4], %[p0], %[pm1] \n\t" - - "precrq.qb.ph %[p1], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[pm1], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p2], %[p1], %[sec3] \n\t" - "precrq.ph.w %[p0], %[pm1], %[sec4] \n\t" - "append %[p1], %[sec3], 16 \n\t" - "append %[pm1], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p2] "+r"(p2), [p1] "+r"(p1), [p0] "+r"(p0), - [pm1] "+r"(pm1), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* transpose p3, p4, p5, p6 */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p6], %[p5] \n\t" - "precr.qb.ph %[prim2], %[p6], %[p5] \n\t" - "precrq.qb.ph %[prim3], %[p4], %[p3] \n\t" - "precr.qb.ph %[prim4], %[p4], %[p3] \n\t" - - "precrq.qb.ph %[p5], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[p3], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p6], %[p5], %[sec3] \n\t" - "precrq.ph.w %[p4], %[p3], %[sec4] \n\t" - "append %[p5], %[sec3], 16 \n\t" - "append %[p3], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p6] "+r"(p6), [p5] "+r"(p5), [p4] "+r"(p4), - [p3] "+r"(p3), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - vp8_filter_mask_vec_mips(limit, flimit, p1, p2, pm1, p0, p3, p4, p5, p6, - thresh, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - vp8_mbfilter_mips(mask, hev, &p0, &p1, &p2, &p3, &p4, &p5); - - /* don't use transpose on output data - * because memory isn't aligned - */ - __asm__ __volatile__( - "sb %[p5], 2(%[s4]) \n\t" - "sb %[p4], 1(%[s4]) \n\t" - "sb %[p3], 0(%[s4]) \n\t" - "sb %[p2], -1(%[s4]) \n\t" - "sb %[p1], -2(%[s4]) \n\t" - "sb %[p0], -3(%[s4]) \n\t" - : - : [p5] "r"(p5), [p4] "r"(p4), [p3] "r"(p3), [s4] "r"(s4), - [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0)); - - __asm__ __volatile__( - "srl %[p5], %[p5], 8 \n\t" - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - "srl %[p0], %[p0], 8 \n\t" - : [p5] "+r"(p5), [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), - [p1] "+r"(p1), [p0] "+r"(p0) - :); - - __asm__ __volatile__( - "sb %[p5], 2(%[s3]) \n\t" - "sb %[p4], 1(%[s3]) \n\t" - "sb %[p3], 0(%[s3]) \n\t" - "sb %[p2], -1(%[s3]) \n\t" - "sb %[p1], -2(%[s3]) \n\t" - "sb %[p0], -3(%[s3]) \n\t" - : - : [p5] "r"(p5), [p4] "r"(p4), [p3] "r"(p3), [s3] "r"(s3), - [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0)); - - __asm__ __volatile__( - "srl %[p5], %[p5], 8 \n\t" - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - "srl %[p0], %[p0], 8 \n\t" - : [p5] "+r"(p5), [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), - [p1] "+r"(p1), [p0] "+r"(p0) - :); - - __asm__ __volatile__( - "sb %[p5], 2(%[s2]) \n\t" - "sb %[p4], 1(%[s2]) \n\t" - "sb %[p3], 0(%[s2]) \n\t" - "sb %[p2], -1(%[s2]) \n\t" - "sb %[p1], -2(%[s2]) \n\t" - "sb %[p0], -3(%[s2]) \n\t" - : - : [p5] "r"(p5), [p4] "r"(p4), [p3] "r"(p3), [s2] "r"(s2), - [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0)); - - __asm__ __volatile__( - "srl %[p5], %[p5], 8 \n\t" - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - "srl %[p0], %[p0], 8 \n\t" - : [p5] "+r"(p5), [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), - [p1] "+r"(p1), [p0] "+r"(p0) - :); - - __asm__ __volatile__( - "sb %[p5], 2(%[s1]) \n\t" - "sb %[p4], 1(%[s1]) \n\t" - "sb %[p3], 0(%[s1]) \n\t" - "sb %[p2], -1(%[s1]) \n\t" - "sb %[p1], -2(%[s1]) \n\t" - "sb %[p0], -3(%[s1]) \n\t" - : - : [p5] "r"(p5), [p4] "r"(p4), [p3] "r"(p3), [s1] "r"(s1), - [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0)); - } - } -} - -/* Horizontal MB filtering */ -void vp8_loop_filter_mbh_dspr2(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, - int uv_stride, loop_filter_info *lfi) { - unsigned int thresh_vec, flimit_vec, limit_vec; - unsigned char thresh, flimit, limit, flimit_temp; - - /* use direct value instead pointers */ - limit = *(lfi->lim); - flimit_temp = *(lfi->mblim); - thresh = *(lfi->hev_thr); - flimit = flimit_temp; - - /* create quad-byte */ - __asm__ __volatile__( - "replv.qb %[thresh_vec], %[thresh] \n\t" - "replv.qb %[flimit_vec], %[flimit] \n\t" - "replv.qb %[limit_vec], %[limit] \n\t" - : [thresh_vec] "=&r"(thresh_vec), [flimit_vec] "=&r"(flimit_vec), - [limit_vec] "=r"(limit_vec) - : [thresh] "r"(thresh), [flimit] "r"(flimit), [limit] "r"(limit)); - - vp8_mbloop_filter_horizontal_edge_mips(y_ptr, y_stride, flimit_vec, limit_vec, - thresh_vec, 16); - - if (u_ptr) { - vp8_mbloop_filter_uvhorizontal_edge_mips(u_ptr, uv_stride, flimit_vec, - limit_vec, thresh_vec, 0); - } - - if (v_ptr) { - vp8_mbloop_filter_uvhorizontal_edge_mips(v_ptr, uv_stride, flimit_vec, - limit_vec, thresh_vec, 0); - } -} - -/* Vertical MB Filtering */ -void vp8_loop_filter_mbv_dspr2(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, - int uv_stride, loop_filter_info *lfi) { - unsigned int thresh_vec, flimit_vec, limit_vec; - unsigned char thresh, flimit, limit, flimit_temp; - - /* use direct value instead pointers */ - limit = *(lfi->lim); - flimit_temp = *(lfi->mblim); - thresh = *(lfi->hev_thr); - flimit = flimit_temp; - - /* create quad-byte */ - __asm__ __volatile__( - "replv.qb %[thresh_vec], %[thresh] \n\t" - "replv.qb %[flimit_vec], %[flimit] \n\t" - "replv.qb %[limit_vec], %[limit] \n\t" - : [thresh_vec] "=&r"(thresh_vec), [flimit_vec] "=&r"(flimit_vec), - [limit_vec] "=r"(limit_vec) - : [thresh] "r"(thresh), [flimit] "r"(flimit), [limit] "r"(limit)); - - vp8_mbloop_filter_vertical_edge_mips(y_ptr, y_stride, flimit_vec, limit_vec, - thresh_vec, 16); - - if (u_ptr) - vp8_mbloop_filter_uvvertical_edge_mips(u_ptr, uv_stride, flimit_vec, - limit_vec, thresh_vec, 0); - - if (v_ptr) - vp8_mbloop_filter_uvvertical_edge_mips(v_ptr, uv_stride, flimit_vec, - limit_vec, thresh_vec, 0); -} - -/* Horizontal B Filtering */ -void vp8_loop_filter_bh_dspr2(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { - unsigned int thresh_vec, flimit_vec, limit_vec; - unsigned char thresh, flimit, limit, flimit_temp; - - /* use direct value instead pointers */ - limit = *(lfi->lim); - flimit_temp = *(lfi->blim); - thresh = *(lfi->hev_thr); - flimit = flimit_temp; - - /* create quad-byte */ - __asm__ __volatile__( - "replv.qb %[thresh_vec], %[thresh] \n\t" - "replv.qb %[flimit_vec], %[flimit] \n\t" - "replv.qb %[limit_vec], %[limit] \n\t" - : [thresh_vec] "=&r"(thresh_vec), [flimit_vec] "=&r"(flimit_vec), - [limit_vec] "=r"(limit_vec) - : [thresh] "r"(thresh), [flimit] "r"(flimit), [limit] "r"(limit)); - - vp8_loop_filter_horizontal_edge_mips(y_ptr + 4 * y_stride, y_stride, - flimit_vec, limit_vec, thresh_vec, 16); - vp8_loop_filter_horizontal_edge_mips(y_ptr + 8 * y_stride, y_stride, - flimit_vec, limit_vec, thresh_vec, 16); - vp8_loop_filter_horizontal_edge_mips(y_ptr + 12 * y_stride, y_stride, - flimit_vec, limit_vec, thresh_vec, 16); - - if (u_ptr) - vp8_loop_filter_uvhorizontal_edge_mips( - u_ptr + 4 * uv_stride, uv_stride, flimit_vec, limit_vec, thresh_vec, 0); - - if (v_ptr) - vp8_loop_filter_uvhorizontal_edge_mips( - v_ptr + 4 * uv_stride, uv_stride, flimit_vec, limit_vec, thresh_vec, 0); -} - -/* Vertical B Filtering */ -void vp8_loop_filter_bv_dspr2(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { - unsigned int thresh_vec, flimit_vec, limit_vec; - unsigned char thresh, flimit, limit, flimit_temp; - - /* use direct value instead pointers */ - limit = *(lfi->lim); - flimit_temp = *(lfi->blim); - thresh = *(lfi->hev_thr); - flimit = flimit_temp; - - /* create quad-byte */ - __asm__ __volatile__( - "replv.qb %[thresh_vec], %[thresh] \n\t" - "replv.qb %[flimit_vec], %[flimit] \n\t" - "replv.qb %[limit_vec], %[limit] \n\t" - : [thresh_vec] "=&r"(thresh_vec), [flimit_vec] "=&r"(flimit_vec), - [limit_vec] "=r"(limit_vec) - : [thresh] "r"(thresh), [flimit] "r"(flimit), [limit] "r"(limit)); - - vp8_loop_filter_vertical_edge_mips(y_ptr + 4, y_stride, flimit_vec, limit_vec, - thresh_vec, 16); - vp8_loop_filter_vertical_edge_mips(y_ptr + 8, y_stride, flimit_vec, limit_vec, - thresh_vec, 16); - vp8_loop_filter_vertical_edge_mips(y_ptr + 12, y_stride, flimit_vec, - limit_vec, thresh_vec, 16); - - if (u_ptr) - vp8_loop_filter_uvvertical_edge_mips(u_ptr + 4, uv_stride, flimit_vec, - limit_vec, thresh_vec, 0); - - if (v_ptr) - vp8_loop_filter_uvvertical_edge_mips(v_ptr + 4, uv_stride, flimit_vec, - limit_vec, thresh_vec, 0); -} - -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/copymem_mmi.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/copymem_mmi.c deleted file mode 100644 index 86a32aa9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/copymem_mmi.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vpx_ports/asmdefs_mmi.h" - -#define COPY_MEM_16X2 \ - "gsldlc1 %[ftmp0], 0x07(%[src]) \n\t" \ - "gsldrc1 %[ftmp0], 0x00(%[src]) \n\t" \ - "ldl %[tmp0], 0x0f(%[src]) \n\t" \ - "ldr %[tmp0], 0x08(%[src]) \n\t" \ - MMI_ADDU(%[src], %[src], %[src_stride]) \ - "gssdlc1 %[ftmp0], 0x07(%[dst]) \n\t" \ - "gssdrc1 %[ftmp0], 0x00(%[dst]) \n\t" \ - "sdl %[tmp0], 0x0f(%[dst]) \n\t" \ - "sdr %[tmp0], 0x08(%[dst]) \n\t" \ - MMI_ADDU(%[dst], %[dst], %[dst_stride]) \ - "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[src]) \n\t" \ - "ldl %[tmp1], 0x0f(%[src]) \n\t" \ - "ldr %[tmp1], 0x08(%[src]) \n\t" \ - MMI_ADDU(%[src], %[src], %[src_stride]) \ - "gssdlc1 %[ftmp1], 0x07(%[dst]) \n\t" \ - "gssdrc1 %[ftmp1], 0x00(%[dst]) \n\t" \ - "sdl %[tmp1], 0x0f(%[dst]) \n\t" \ - "sdr %[tmp1], 0x08(%[dst]) \n\t" \ - MMI_ADDU(%[dst], %[dst], %[dst_stride]) - -#define COPY_MEM_8X2 \ - "gsldlc1 %[ftmp0], 0x07(%[src]) \n\t" \ - "gsldrc1 %[ftmp0], 0x00(%[src]) \n\t" \ - MMI_ADDU(%[src], %[src], %[src_stride]) \ - "ldl %[tmp0], 0x07(%[src]) \n\t" \ - "ldr %[tmp0], 0x00(%[src]) \n\t" \ - MMI_ADDU(%[src], %[src], %[src_stride]) \ - \ - "gssdlc1 %[ftmp0], 0x07(%[dst]) \n\t" \ - "gssdrc1 %[ftmp0], 0x00(%[dst]) \n\t" \ - MMI_ADDU(%[dst], %[dst], %[dst_stride]) \ - "sdl %[tmp0], 0x07(%[dst]) \n\t" \ - "sdr %[tmp0], 0x00(%[dst]) \n\t" \ - MMI_ADDU(%[dst], %[dst], %[dst_stride]) - -void vp8_copy_mem16x16_mmi(unsigned char *src, int src_stride, - unsigned char *dst, int dst_stride) { - double ftmp[2]; - uint64_t tmp[2]; - uint8_t loop_count = 4; - - /* clang-format off */ - __asm__ volatile ( - "1: \n\t" - COPY_MEM_16X2 - COPY_MEM_16X2 - MMI_ADDIU(%[loop_count], %[loop_count], -0x01) - "bnez %[loop_count], 1b \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]), - [loop_count]"+&r"(loop_count), - [dst]"+&r"(dst), [src]"+&r"(src) - : [src_stride]"r"((mips_reg)src_stride), - [dst_stride]"r"((mips_reg)dst_stride) - : "memory" - ); - /* clang-format on */ -} - -void vp8_copy_mem8x8_mmi(unsigned char *src, int src_stride, unsigned char *dst, - int dst_stride) { - double ftmp[2]; - uint64_t tmp[1]; - uint8_t loop_count = 4; - - /* clang-format off */ - __asm__ volatile ( - "1: \n\t" - COPY_MEM_8X2 - MMI_ADDIU(%[loop_count], %[loop_count], -0x01) - "bnez %[loop_count], 1b \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [tmp0]"=&r"(tmp[0]), [loop_count]"+&r"(loop_count), - [dst]"+&r"(dst), [src]"+&r"(src) - : [src_stride]"r"((mips_reg)src_stride), - [dst_stride]"r"((mips_reg)dst_stride) - : "memory" - ); - /* clang-format on */ -} - -void vp8_copy_mem8x4_mmi(unsigned char *src, int src_stride, unsigned char *dst, - int dst_stride) { - double ftmp[2]; - uint64_t tmp[1]; - - /* clang-format off */ - __asm__ volatile ( - COPY_MEM_8X2 - COPY_MEM_8X2 - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [tmp0]"=&r"(tmp[0]), - [dst]"+&r"(dst), [src]"+&r"(src) - : [src_stride]"r"((mips_reg)src_stride), - [dst_stride]"r"((mips_reg)dst_stride) - : "memory" - ); - /* clang-format on */ -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/dequantize_mmi.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/dequantize_mmi.c deleted file mode 100644 index b9330a66..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/dequantize_mmi.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vp8/common/blockd.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/asmdefs_mmi.h" - -void vp8_dequantize_b_mmi(BLOCKD *d, int16_t *DQC) { - double ftmp[8]; - - __asm__ volatile( - "gsldlc1 %[ftmp0], 0x07(%[qcoeff]) \n\t" - "gsldrc1 %[ftmp0], 0x00(%[qcoeff]) \n\t" - "gsldlc1 %[ftmp1], 0x0f(%[qcoeff]) \n\t" - "gsldrc1 %[ftmp1], 0x08(%[qcoeff]) \n\t" - "gsldlc1 %[ftmp2], 0x17(%[qcoeff]) \n\t" - "gsldrc1 %[ftmp2], 0x10(%[qcoeff]) \n\t" - "gsldlc1 %[ftmp3], 0x1f(%[qcoeff]) \n\t" - "gsldrc1 %[ftmp3], 0x18(%[qcoeff]) \n\t" - - "gsldlc1 %[ftmp4], 0x07(%[DQC]) \n\t" - "gsldrc1 %[ftmp4], 0x00(%[DQC]) \n\t" - "gsldlc1 %[ftmp5], 0x0f(%[DQC]) \n\t" - "gsldrc1 %[ftmp5], 0x08(%[DQC]) \n\t" - "gsldlc1 %[ftmp6], 0x17(%[DQC]) \n\t" - "gsldrc1 %[ftmp6], 0x10(%[DQC]) \n\t" - "gsldlc1 %[ftmp7], 0x1f(%[DQC]) \n\t" - "gsldrc1 %[ftmp7], 0x18(%[DQC]) \n\t" - - "pmullh %[ftmp0], %[ftmp0], %[ftmp4] \n\t" - "pmullh %[ftmp1], %[ftmp1], %[ftmp5] \n\t" - "pmullh %[ftmp2], %[ftmp2], %[ftmp6] \n\t" - "pmullh %[ftmp3], %[ftmp3], %[ftmp7] \n\t" - - "gssdlc1 %[ftmp0], 0x07(%[dqcoeff]) \n\t" - "gssdrc1 %[ftmp0], 0x00(%[dqcoeff]) \n\t" - "gssdlc1 %[ftmp1], 0x0f(%[dqcoeff]) \n\t" - "gssdrc1 %[ftmp1], 0x08(%[dqcoeff]) \n\t" - "gssdlc1 %[ftmp2], 0x17(%[dqcoeff]) \n\t" - "gssdrc1 %[ftmp2], 0x10(%[dqcoeff]) \n\t" - "gssdlc1 %[ftmp3], 0x1f(%[dqcoeff]) \n\t" - "gssdrc1 %[ftmp3], 0x18(%[dqcoeff]) \n\t" - : [ftmp0] "=&f"(ftmp[0]), [ftmp1] "=&f"(ftmp[1]), [ftmp2] "=&f"(ftmp[2]), - [ftmp3] "=&f"(ftmp[3]), [ftmp4] "=&f"(ftmp[4]), [ftmp5] "=&f"(ftmp[5]), - [ftmp6] "=&f"(ftmp[6]), [ftmp7] "=&f"(ftmp[7]) - : [dqcoeff] "r"(d->dqcoeff), [qcoeff] "r"(d->qcoeff), [DQC] "r"(DQC) - : "memory"); -} - -void vp8_dequant_idct_add_mmi(int16_t *input, int16_t *dq, unsigned char *dest, - int stride) { - double ftmp[8]; - - __asm__ volatile( - "gsldlc1 %[ftmp0], 0x07(%[dq]) \n\t" - "gsldrc1 %[ftmp0], 0x00(%[dq]) \n\t" - "gsldlc1 %[ftmp1], 0x0f(%[dq]) \n\t" - "gsldrc1 %[ftmp1], 0x08(%[dq]) \n\t" - "gsldlc1 %[ftmp2], 0x17(%[dq]) \n\t" - "gsldrc1 %[ftmp2], 0x10(%[dq]) \n\t" - "gsldlc1 %[ftmp3], 0x1f(%[dq]) \n\t" - "gsldrc1 %[ftmp3], 0x18(%[dq]) \n\t" - - "gsldlc1 %[ftmp4], 0x07(%[input]) \n\t" - "gsldrc1 %[ftmp4], 0x00(%[input]) \n\t" - "gsldlc1 %[ftmp5], 0x0f(%[input]) \n\t" - "gsldrc1 %[ftmp5], 0x08(%[input]) \n\t" - "gsldlc1 %[ftmp6], 0x17(%[input]) \n\t" - "gsldrc1 %[ftmp6], 0x10(%[input]) \n\t" - "gsldlc1 %[ftmp7], 0x1f(%[input]) \n\t" - "gsldrc1 %[ftmp7], 0x18(%[input]) \n\t" - - "pmullh %[ftmp0], %[ftmp0], %[ftmp4] \n\t" - "pmullh %[ftmp1], %[ftmp1], %[ftmp5] \n\t" - "pmullh %[ftmp2], %[ftmp2], %[ftmp6] \n\t" - "pmullh %[ftmp3], %[ftmp3], %[ftmp7] \n\t" - - "gssdlc1 %[ftmp0], 0x07(%[input]) \n\t" - "gssdrc1 %[ftmp0], 0x00(%[input]) \n\t" - "gssdlc1 %[ftmp1], 0x0f(%[input]) \n\t" - "gssdrc1 %[ftmp1], 0x08(%[input]) \n\t" - "gssdlc1 %[ftmp2], 0x17(%[input]) \n\t" - "gssdrc1 %[ftmp2], 0x10(%[input]) \n\t" - "gssdlc1 %[ftmp3], 0x1f(%[input]) \n\t" - "gssdrc1 %[ftmp3], 0x18(%[input]) \n\t" - : [ftmp0] "=&f"(ftmp[0]), [ftmp1] "=&f"(ftmp[1]), [ftmp2] "=&f"(ftmp[2]), - [ftmp3] "=&f"(ftmp[3]), [ftmp4] "=&f"(ftmp[4]), [ftmp5] "=&f"(ftmp[5]), - [ftmp6] "=&f"(ftmp[6]), [ftmp7] "=&f"(ftmp[7]) - : [dq] "r"(dq), [input] "r"(input) - : "memory"); - - vp8_short_idct4x4llm_mmi(input, dest, stride, dest, stride); - - __asm__ volatile( - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "gssdlc1 %[ftmp0], 0x07(%[input]) \n\t" - "gssdrc1 %[ftmp0], 0x00(%[input]) \n\t" - "sdl $0, 0x0f(%[input]) \n\t" - "sdr $0, 0x08(%[input]) \n\t" - "gssdlc1 %[ftmp0], 0x17(%[input]) \n\t" - "gssdrc1 %[ftmp0], 0x10(%[input]) \n\t" - "sdl $0, 0x1f(%[input]) \n\t" - "sdr $0, 0x18(%[input]) \n\t" - : [ftmp0] "=&f"(ftmp[0]) - : [input] "r"(input) - : "memory"); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/idct_blk_mmi.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/idct_blk_mmi.c deleted file mode 100644 index 4fd6854c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/idct_blk_mmi.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vpx_mem/vpx_mem.h" - -void vp8_dequant_idct_add_y_block_mmi(int16_t *q, int16_t *dq, uint8_t *dst, - int stride, char *eobs) { - int i, j; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - if (*eobs++ > 1) { - vp8_dequant_idct_add_mmi(q, dq, dst, stride); - } else { - vp8_dc_only_idct_add_mmi(q[0] * dq[0], dst, stride, dst, stride); - memset(q, 0, 2 * sizeof(q[0])); - } - - q += 16; - dst += 4; - } - - dst += 4 * stride - 16; - } -} - -void vp8_dequant_idct_add_uv_block_mmi(int16_t *q, int16_t *dq, uint8_t *dst_u, - uint8_t *dst_v, int stride, char *eobs) { - int i, j; - - for (i = 0; i < 2; i++) { - for (j = 0; j < 2; j++) { - if (*eobs++ > 1) { - vp8_dequant_idct_add_mmi(q, dq, dst_u, stride); - } else { - vp8_dc_only_idct_add_mmi(q[0] * dq[0], dst_u, stride, dst_u, stride); - memset(q, 0, 2 * sizeof(q[0])); - } - - q += 16; - dst_u += 4; - } - - dst_u += 4 * stride - 8; - } - - for (i = 0; i < 2; i++) { - for (j = 0; j < 2; j++) { - if (*eobs++ > 1) { - vp8_dequant_idct_add_mmi(q, dq, dst_v, stride); - } else { - vp8_dc_only_idct_add_mmi(q[0] * dq[0], dst_v, stride, dst_v, stride); - memset(q, 0, 2 * sizeof(q[0])); - } - - q += 16; - dst_v += 4; - } - - dst_v += 4 * stride - 8; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/idctllm_mmi.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/idctllm_mmi.c deleted file mode 100644 index a35689dd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/idctllm_mmi.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/asmdefs_mmi.h" - -#define TRANSPOSE_4H \ - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" \ - MMI_LI(%[tmp0], 0x93) \ - "mtc1 %[tmp0], %[ftmp10] \n\t" \ - "punpcklhw %[ftmp5], %[ftmp1], %[ftmp0] \n\t" \ - "punpcklhw %[ftmp9], %[ftmp2], %[ftmp0] \n\t" \ - "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ - "por %[ftmp5], %[ftmp5], %[ftmp9] \n\t" \ - "punpckhhw %[ftmp6], %[ftmp1], %[ftmp0] \n\t" \ - "punpckhhw %[ftmp9], %[ftmp2], %[ftmp0] \n\t" \ - "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ - "por %[ftmp6], %[ftmp6], %[ftmp9] \n\t" \ - "punpcklhw %[ftmp7], %[ftmp3], %[ftmp0] \n\t" \ - "punpcklhw %[ftmp9], %[ftmp4], %[ftmp0] \n\t" \ - "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ - "por %[ftmp7], %[ftmp7], %[ftmp9] \n\t" \ - "punpckhhw %[ftmp8], %[ftmp3], %[ftmp0] \n\t" \ - "punpckhhw %[ftmp9], %[ftmp4], %[ftmp0] \n\t" \ - "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ - "por %[ftmp8], %[ftmp8], %[ftmp9] \n\t" \ - "punpcklwd %[ftmp1], %[ftmp5], %[ftmp7] \n\t" \ - "punpckhwd %[ftmp2], %[ftmp5], %[ftmp7] \n\t" \ - "punpcklwd %[ftmp3], %[ftmp6], %[ftmp8] \n\t" \ - "punpckhwd %[ftmp4], %[ftmp6], %[ftmp8] \n\t" - -void vp8_short_idct4x4llm_mmi(int16_t *input, unsigned char *pred_ptr, - int pred_stride, unsigned char *dst_ptr, - int dst_stride) { - double ftmp[12]; - uint64_t tmp[1]; - double ff_ph_04, ff_ph_4e7b, ff_ph_22a3; - - __asm__ volatile ( - "dli %[tmp0], 0x0004000400040004 \n\t" - "dmtc1 %[tmp0], %[ff_ph_04] \n\t" - "dli %[tmp0], 0x4e7b4e7b4e7b4e7b \n\t" - "dmtc1 %[tmp0], %[ff_ph_4e7b] \n\t" - "dli %[tmp0], 0x22a322a322a322a3 \n\t" - "dmtc1 %[tmp0], %[ff_ph_22a3] \n\t" - MMI_LI(%[tmp0], 0x02) - "dmtc1 %[tmp0], %[ftmp11] \n\t" - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - - "gsldlc1 %[ftmp1], 0x07(%[ip]) \n\t" - "gsldrc1 %[ftmp1], 0x00(%[ip]) \n\t" - "gsldlc1 %[ftmp2], 0x0f(%[ip]) \n\t" - "gsldrc1 %[ftmp2], 0x08(%[ip]) \n\t" - "gsldlc1 %[ftmp3], 0x17(%[ip]) \n\t" - "gsldrc1 %[ftmp3], 0x10(%[ip]) \n\t" - "gsldlc1 %[ftmp4], 0x1f(%[ip]) \n\t" - "gsldrc1 %[ftmp4], 0x18(%[ip]) \n\t" - - // ip[0...3] + ip[8...11] - "paddh %[ftmp5], %[ftmp1], %[ftmp3] \n\t" - // ip[0...3] - ip[8...11] - "psubh %[ftmp6], %[ftmp1], %[ftmp3] \n\t" - // (ip[12...15] * sinpi8sqrt2) >> 16 - "psllh %[ftmp9], %[ftmp4], %[ftmp11] \n\t" - "pmulhh %[ftmp7], %[ftmp9], %[ff_ph_22a3] \n\t" - // (ip[ 4... 7] * sinpi8sqrt2) >> 16 - "psllh %[ftmp9], %[ftmp2], %[ftmp11] \n\t" - "pmulhh %[ftmp8], %[ftmp9], %[ff_ph_22a3] \n\t" - // ip[ 4... 7] + ((ip[ 4... 7] * cospi8sqrt2minus1) >> 16) - "pmulhh %[ftmp9], %[ftmp2], %[ff_ph_4e7b] \n\t" - "paddh %[ftmp9], %[ftmp9], %[ftmp2] \n\t" - // ip[12...15] + ((ip[12...15] * cospi8sqrt2minus1) >> 16) - "pmulhh %[ftmp10], %[ftmp4], %[ff_ph_4e7b] \n\t" - "paddh %[ftmp10], %[ftmp10], %[ftmp4] \n\t" - - "paddh %[ftmp1], %[ftmp5], %[ftmp7] \n\t" - "paddh %[ftmp1], %[ftmp1], %[ftmp9] \n\t" - "paddh %[ftmp2], %[ftmp6], %[ftmp8] \n\t" - "psubh %[ftmp2], %[ftmp2], %[ftmp10] \n\t" - "psubh %[ftmp3], %[ftmp6], %[ftmp8] \n\t" - "paddh %[ftmp3], %[ftmp3], %[ftmp10] \n\t" - "psubh %[ftmp4], %[ftmp5], %[ftmp7] \n\t" - "psubh %[ftmp4], %[ftmp4], %[ftmp9] \n\t" - - TRANSPOSE_4H - // a - "paddh %[ftmp5], %[ftmp1], %[ftmp3] \n\t" - // b - "psubh %[ftmp6], %[ftmp1], %[ftmp3] \n\t" - // c - "psllh %[ftmp9], %[ftmp2], %[ftmp11] \n\t" - "pmulhh %[ftmp9], %[ftmp9], %[ff_ph_22a3] \n\t" - "psubh %[ftmp7], %[ftmp9], %[ftmp4] \n\t" - "pmulhh %[ftmp10], %[ftmp4], %[ff_ph_4e7b] \n\t" - "psubh %[ftmp7], %[ftmp7], %[ftmp10] \n\t" - // d - "psllh %[ftmp9], %[ftmp4], %[ftmp11] \n\t" - "pmulhh %[ftmp9], %[ftmp9], %[ff_ph_22a3] \n\t" - "paddh %[ftmp8], %[ftmp9], %[ftmp2] \n\t" - "pmulhh %[ftmp10], %[ftmp2], %[ff_ph_4e7b] \n\t" - "paddh %[ftmp8], %[ftmp8], %[ftmp10] \n\t" - - MMI_LI(%[tmp0], 0x03) - "mtc1 %[tmp0], %[ftmp11] \n\t" - // a + d - "paddh %[ftmp1], %[ftmp5], %[ftmp8] \n\t" - "paddh %[ftmp1], %[ftmp1], %[ff_ph_04] \n\t" - "psrah %[ftmp1], %[ftmp1], %[ftmp11] \n\t" - // b + c - "paddh %[ftmp2], %[ftmp6], %[ftmp7] \n\t" - "paddh %[ftmp2], %[ftmp2], %[ff_ph_04] \n\t" - "psrah %[ftmp2], %[ftmp2], %[ftmp11] \n\t" - // b - c - "psubh %[ftmp3], %[ftmp6], %[ftmp7] \n\t" - "paddh %[ftmp3], %[ftmp3], %[ff_ph_04] \n\t" - "psrah %[ftmp3], %[ftmp3], %[ftmp11] \n\t" - // a - d - "psubh %[ftmp4], %[ftmp5], %[ftmp8] \n\t" - "paddh %[ftmp4], %[ftmp4], %[ff_ph_04] \n\t" - "psrah %[ftmp4], %[ftmp4], %[ftmp11] \n\t" - - TRANSPOSE_4H -#if _MIPS_SIM == _ABIO32 - "ulw %[tmp0], 0x00(%[pred_prt]) \n\t" - "mtc1 %[tmp0], %[ftmp5] \n\t" -#else - "gslwlc1 %[ftmp5], 0x03(%[pred_ptr]) \n\t" - "gslwrc1 %[ftmp5], 0x00(%[pred_ptr]) \n\t" -#endif - "punpcklbh %[ftmp5], %[ftmp5], %[ftmp0] \n\t" - "paddh %[ftmp1], %[ftmp1], %[ftmp5] \n\t" - "packushb %[ftmp1], %[ftmp1], %[ftmp0] \n\t" - "gsswlc1 %[ftmp1], 0x03(%[dst_ptr]) \n\t" - "gsswrc1 %[ftmp1], 0x00(%[dst_ptr]) \n\t" - MMI_ADDU(%[pred_ptr], %[pred_ptr], %[pred_stride]) - MMI_ADDU(%[dst_ptr], %[dst_ptr], %[dst_stride]) - -#if _MIPS_SIM == _ABIO32 - "ulw %[tmp0], 0x00(%[pred_prt]) \n\t" - "mtc1 %[tmp0], %[ftmp6] \n\t" -#else - "gslwlc1 %[ftmp6], 0x03(%[pred_ptr]) \n\t" - "gslwrc1 %[ftmp6], 0x00(%[pred_ptr]) \n\t" -#endif - "punpcklbh %[ftmp6], %[ftmp6], %[ftmp0] \n\t" - "paddh %[ftmp2], %[ftmp2], %[ftmp6] \n\t" - "packushb %[ftmp2], %[ftmp2], %[ftmp0] \n\t" - "gsswlc1 %[ftmp2], 0x03(%[dst_ptr]) \n\t" - "gsswrc1 %[ftmp2], 0x00(%[dst_ptr]) \n\t" - MMI_ADDU(%[pred_ptr], %[pred_ptr], %[pred_stride]) - MMI_ADDU(%[dst_ptr], %[dst_ptr], %[dst_stride]) - -#if _MIPS_SIM == _ABIO32 - "ulw %[tmp0], 0x00(%[pred_prt]) \n\t" - "mtc1 %[tmp0], %[ftmp7] \n\t" -#else - "gslwlc1 %[ftmp7], 0x03(%[pred_ptr]) \n\t" - "gslwrc1 %[ftmp7], 0x00(%[pred_ptr]) \n\t" -#endif - "punpcklbh %[ftmp7], %[ftmp7], %[ftmp0] \n\t" - "paddh %[ftmp3], %[ftmp3], %[ftmp7] \n\t" - "packushb %[ftmp3], %[ftmp3], %[ftmp0] \n\t" - "gsswlc1 %[ftmp3], 0x03(%[dst_ptr]) \n\t" - "gsswrc1 %[ftmp3], 0x00(%[dst_ptr]) \n\t" - MMI_ADDU(%[pred_ptr], %[pred_ptr], %[pred_stride]) - MMI_ADDU(%[dst_ptr], %[dst_ptr], %[dst_stride]) - -#if _MIPS_SIM == _ABIO32 - "ulw %[tmp0], 0x00(%[pred_prt]) \n\t" - "mtc1 %[tmp0], %[ftmp8] \n\t" -#else - "gslwlc1 %[ftmp8], 0x03(%[pred_ptr]) \n\t" - "gslwrc1 %[ftmp8], 0x00(%[pred_ptr]) \n\t" -#endif - "punpcklbh %[ftmp8], %[ftmp8], %[ftmp0] \n\t" - "paddh %[ftmp4], %[ftmp4], %[ftmp8] \n\t" - "packushb %[ftmp4], %[ftmp4], %[ftmp0] \n\t" - "gsswlc1 %[ftmp4], 0x03(%[dst_ptr]) \n\t" - "gsswrc1 %[ftmp4], 0x00(%[dst_ptr]) \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), [ftmp2]"=&f"(ftmp[2]), - [ftmp3]"=&f"(ftmp[3]), [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), - [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), [ftmp8]"=&f"(ftmp[8]), - [ftmp9]"=&f"(ftmp[9]), [ftmp10]"=&f"(ftmp[10]), - [ftmp11]"=&f"(ftmp[11]), [tmp0]"=&r"(tmp[0]), - [pred_ptr]"+&r"(pred_ptr), [dst_ptr]"+&r"(dst_ptr), - [ff_ph_4e7b]"=&f"(ff_ph_4e7b), [ff_ph_04]"=&f"(ff_ph_04), - [ff_ph_22a3]"=&f"(ff_ph_22a3) - : [ip]"r"(input), - [pred_stride]"r"((mips_reg)pred_stride), - [dst_stride]"r"((mips_reg)dst_stride) - : "memory" - ); -} - -void vp8_dc_only_idct_add_mmi(int16_t input_dc, unsigned char *pred_ptr, - int pred_stride, unsigned char *dst_ptr, - int dst_stride) { - int a0 = ((input_dc + 4) >> 3); - double a1, ftmp[5]; - int low32; - - __asm__ volatile ( - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "dmtc1 %[a0], %[a1] \n\t" - "pshufh %[a1], %[a1], %[ftmp0] \n\t" - "ulw %[low32], 0x00(%[pred_ptr]) \n\t" - "mtc1 %[low32], %[ftmp1] \n\t" - "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" - "paddsh %[ftmp2], %[ftmp2], %[a1] \n\t" - "packushb %[ftmp1], %[ftmp2], %[ftmp0] \n\t" - "gsswlc1 %[ftmp1], 0x03(%[dst_ptr]) \n\t" - "gsswrc1 %[ftmp1], 0x00(%[dst_ptr]) \n\t" - - MMI_ADDU(%[pred_ptr], %[pred_ptr], %[pred_stride]) - MMI_ADDU(%[dst_ptr], %[dst_ptr], %[dst_stride]) - "ulw %[low32], 0x00(%[pred_ptr]) \n\t" - "mtc1 %[low32], %[ftmp1] \n\t" - "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" - "paddsh %[ftmp2], %[ftmp2], %[a1] \n\t" - "packushb %[ftmp1], %[ftmp2], %[ftmp0] \n\t" - "gsswlc1 %[ftmp1], 0x03(%[dst_ptr]) \n\t" - "gsswrc1 %[ftmp1], 0x00(%[dst_ptr]) \n\t" - - MMI_ADDU(%[pred_ptr], %[pred_ptr], %[pred_stride]) - MMI_ADDU(%[dst_ptr], %[dst_ptr], %[dst_stride]) - "ulw %[low32], 0x00(%[pred_ptr]) \n\t" - "mtc1 %[low32], %[ftmp1] \n\t" - "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" - "paddsh %[ftmp2], %[ftmp2], %[a1] \n\t" - "packushb %[ftmp1], %[ftmp2], %[ftmp0] \n\t" - "gsswlc1 %[ftmp1], 0x03(%[dst_ptr]) \n\t" - "gsswrc1 %[ftmp1], 0x00(%[dst_ptr]) \n\t" - - MMI_ADDU(%[pred_ptr], %[pred_ptr], %[pred_stride]) - MMI_ADDU(%[dst_ptr], %[dst_ptr], %[dst_stride]) - "ulw %[low32], 0x00(%[pred_ptr]) \n\t" - "mtc1 %[low32], %[ftmp1] \n\t" - "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" - "paddsh %[ftmp2], %[ftmp2], %[a1] \n\t" - "packushb %[ftmp1], %[ftmp2], %[ftmp0] \n\t" - "gsswlc1 %[ftmp1], 0x03(%[dst_ptr]) \n\t" - "gsswrc1 %[ftmp1], 0x00(%[dst_ptr]) \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), [ftmp2]"=&f"(ftmp[2]), - [ftmp3]"=&f"(ftmp[3]), [ftmp4]"=&f"(ftmp[4]), [low32]"=&r"(low32), - [dst_ptr]"+&r"(dst_ptr), [pred_ptr]"+&r"(pred_ptr), [a1]"=&f"(a1) - : [dst_stride]"r"((mips_reg)dst_stride), - [pred_stride]"r"((mips_reg)pred_stride), [a0]"r"(a0) - : "memory" - ); -} - -void vp8_short_inv_walsh4x4_mmi(int16_t *input, int16_t *mb_dqcoeff) { - int i; - int16_t output[16]; - double ff_ph_03, ftmp[12]; - uint64_t tmp[1]; - - __asm__ volatile ( - "dli %[tmp0], 0x0003000300030003 \n\t" - "dmtc1 %[tmp0], %[ff_ph_03] \n\t" - MMI_LI(%[tmp0], 0x03) - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "dmtc1 %[tmp0], %[ftmp11] \n\t" - "gsldlc1 %[ftmp1], 0x07(%[ip]) \n\t" - "gsldrc1 %[ftmp1], 0x00(%[ip]) \n\t" - "gsldlc1 %[ftmp2], 0x0f(%[ip]) \n\t" - "gsldrc1 %[ftmp2], 0x08(%[ip]) \n\t" - "gsldlc1 %[ftmp3], 0x17(%[ip]) \n\t" - "gsldrc1 %[ftmp3], 0x10(%[ip]) \n\t" - "gsldlc1 %[ftmp4], 0x1f(%[ip]) \n\t" - "gsldrc1 %[ftmp4], 0x18(%[ip]) \n\t" - "paddh %[ftmp5], %[ftmp1], %[ftmp2] \n\t" - "psubh %[ftmp6], %[ftmp1], %[ftmp2] \n\t" - "paddh %[ftmp7], %[ftmp3], %[ftmp4] \n\t" - "psubh %[ftmp8], %[ftmp3], %[ftmp4] \n\t" - - "paddh %[ftmp1], %[ftmp5], %[ftmp7] \n\t" - "psubh %[ftmp2], %[ftmp5], %[ftmp7] \n\t" - "psubh %[ftmp3], %[ftmp6], %[ftmp8] \n\t" - "paddh %[ftmp4], %[ftmp6], %[ftmp8] \n\t" - - TRANSPOSE_4H - // a - "paddh %[ftmp5], %[ftmp1], %[ftmp4] \n\t" - // d - "psubh %[ftmp6], %[ftmp1], %[ftmp4] \n\t" - // b - "paddh %[ftmp7], %[ftmp2], %[ftmp3] \n\t" - // c - "psubh %[ftmp8], %[ftmp2], %[ftmp3] \n\t" - - "paddh %[ftmp1], %[ftmp5], %[ftmp7] \n\t" - "paddh %[ftmp2], %[ftmp6], %[ftmp8] \n\t" - "psubh %[ftmp3], %[ftmp5], %[ftmp7] \n\t" - "psubh %[ftmp4], %[ftmp6], %[ftmp8] \n\t" - - "paddh %[ftmp1], %[ftmp1], %[ff_ph_03] \n\t" - "psrah %[ftmp1], %[ftmp1], %[ftmp11] \n\t" - "paddh %[ftmp2], %[ftmp2], %[ff_ph_03] \n\t" - "psrah %[ftmp2], %[ftmp2], %[ftmp11] \n\t" - "paddh %[ftmp3], %[ftmp3], %[ff_ph_03] \n\t" - "psrah %[ftmp3], %[ftmp3], %[ftmp11] \n\t" - "paddh %[ftmp4], %[ftmp4], %[ff_ph_03] \n\t" - "psrah %[ftmp4], %[ftmp4], %[ftmp11] \n\t" - - TRANSPOSE_4H - "gssdlc1 %[ftmp1], 0x07(%[op]) \n\t" - "gssdrc1 %[ftmp1], 0x00(%[op]) \n\t" - "gssdlc1 %[ftmp2], 0x0f(%[op]) \n\t" - "gssdrc1 %[ftmp2], 0x08(%[op]) \n\t" - "gssdlc1 %[ftmp3], 0x17(%[op]) \n\t" - "gssdrc1 %[ftmp3], 0x10(%[op]) \n\t" - "gssdlc1 %[ftmp4], 0x1f(%[op]) \n\t" - "gssdrc1 %[ftmp4], 0x18(%[op]) \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), [ftmp2]"=&f"(ftmp[2]), - [ftmp3]"=&f"(ftmp[3]), [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), - [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), [ftmp8]"=&f"(ftmp[8]), - [ftmp9]"=&f"(ftmp[9]), [ftmp10]"=&f"(ftmp[10]), - [ftmp11]"=&f"(ftmp[11]), [tmp0]"=&r"(tmp[0]), [ff_ph_03]"=&f"(ff_ph_03) - : [ip]"r"(input), [op]"r"(output) - : "memory" - ); - - for (i = 0; i < 16; i++) { - mb_dqcoeff[i * 16] = output[i]; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/loopfilter_filters_mmi.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/loopfilter_filters_mmi.c deleted file mode 100644 index a07a7e3b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/loopfilter_filters_mmi.c +++ /dev/null @@ -1,1415 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vp8/common/loopfilter.h" -#include "vp8/common/onyxc_int.h" -#include "vpx_ports/asmdefs_mmi.h" - -void vp8_loop_filter_horizontal_edge_mmi( - unsigned char *src_ptr, int src_pixel_step, const unsigned char *blimit, - const unsigned char *limit, const unsigned char *thresh, int count) { - uint64_t tmp[1]; - mips_reg addr[2]; - double ftmp[12]; - double ff_ph_01, ff_pb_fe, ff_pb_80, ff_pb_04, ff_pb_03; - /* clang-format off */ - __asm__ volatile ( - "dli %[tmp0], 0x0001000100010001 \n\t" - "dmtc1 %[tmp0], %[ff_ph_01] \n\t" - "dli %[tmp0], 0xfefefefefefefefe \n\t" - "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" - "dli %[tmp0], 0x8080808080808080 \n\t" - "dmtc1 %[tmp0], %[ff_pb_80] \n\t" - "dli %[tmp0], 0x0404040404040404 \n\t" - "dmtc1 %[tmp0], %[ff_pb_04] \n\t" - "dli %[tmp0], 0x0303030303030303 \n\t" - "dmtc1 %[tmp0], %[ff_pb_03] \n\t" - "1: \n\t" - "gsldlc1 %[ftmp10], 0x07(%[limit]) \n\t" - "gsldrc1 %[ftmp10], 0x00(%[limit]) \n\t" - - MMI_ADDU(%[addr0], %[src_ptr], %[src_pixel_step]) - - MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step_x4]) - "gsldlc1 %[ftmp1], 0x07(%[addr1]) \n\t" - "gsldrc1 %[ftmp1], 0x00(%[addr1]) \n\t" - - MMI_SUBU(%[addr1], %[addr0], %[src_pixel_step_x4]) - "gsldlc1 %[ftmp3], 0x07(%[addr1]) \n\t" - "gsldrc1 %[ftmp3], 0x00(%[addr1]) \n\t" - "pasubub %[ftmp0], %[ftmp1], %[ftmp3] \n\t" - "psubusb %[ftmp0], %[ftmp0], %[ftmp10] \n\t" - - MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step_x2]) - "gsldlc1 %[ftmp4], 0x07(%[addr1]) \n\t" - "gsldrc1 %[ftmp4], 0x00(%[addr1]) \n\t" - "pasubub %[ftmp1], %[ftmp3], %[ftmp4] \n\t" - "psubusb %[ftmp1], %[ftmp1], %[ftmp10] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - - MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) - "gsldlc1 %[ftmp5], 0x07(%[addr1]) \n\t" - "gsldrc1 %[ftmp5], 0x00(%[addr1]) \n\t" - "pasubub %[ftmp9], %[ftmp4], %[ftmp5] \n\t" - "psubusb %[ftmp1], %[ftmp9], %[ftmp10] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - - "gsldlc1 %[ftmp6], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp6], 0x00(%[src_ptr]) \n\t" - - "gsldlc1 %[ftmp7], 0x07(%[addr0]) \n\t" - "gsldrc1 %[ftmp7], 0x00(%[addr0]) \n\t" - "pasubub %[ftmp11], %[ftmp7], %[ftmp6] \n\t" - "psubusb %[ftmp1], %[ftmp11], %[ftmp10] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - - MMI_ADDU(%[addr1], %[src_ptr], %[src_pixel_step_x2]) - "gsldlc1 %[ftmp8], 0x07(%[addr1]) \n\t" - "gsldrc1 %[ftmp8], 0x00(%[addr1]) \n\t" - "pasubub %[ftmp1], %[ftmp8], %[ftmp7] \n\t" - "psubusb %[ftmp1], %[ftmp1], %[ftmp10] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - - MMI_ADDU(%[addr1], %[addr0], %[src_pixel_step_x2]) - "gsldlc1 %[ftmp2], 0x07(%[addr1]) \n\t" - "gsldrc1 %[ftmp2], 0x00(%[addr1]) \n\t" - "pasubub %[ftmp1], %[ftmp2], %[ftmp8] \n\t" - "psubusb %[ftmp1], %[ftmp1], %[ftmp10] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - - "pasubub %[ftmp1], %[ftmp5], %[ftmp6] \n\t" - "paddusb %[ftmp1], %[ftmp1], %[ftmp1] \n\t" - "pasubub %[ftmp2], %[ftmp4], %[ftmp7] \n\t" - "pand %[ftmp2], %[ftmp2], %[ff_pb_fe] \n\t" - "dli %[tmp0], 0x01 \n\t" - "dmtc1 %[tmp0], %[ftmp10] \n\t" - "psrlh %[ftmp2], %[ftmp2], %[ftmp10] \n\t" - "paddusb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" - "gsldlc1 %[ftmp10], 0x07(%[blimit]) \n\t" - "gsldrc1 %[ftmp10], 0x00(%[blimit]) \n\t" - "psubusb %[ftmp1], %[ftmp1], %[ftmp10] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" - "pcmpeqb %[ftmp0], %[ftmp0], %[ftmp10] \n\t" - - "gsldlc1 %[ftmp10], 0x07(%[thresh]) \n\t" - "gsldrc1 %[ftmp10], 0x00(%[thresh]) \n\t" - "psubusb %[ftmp1], %[ftmp9], %[ftmp10] \n\t" - "psubusb %[ftmp2], %[ftmp11], %[ftmp10] \n\t" - "paddb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" - "pxor %[ftmp2], %[ftmp2], %[ftmp2] \n\t" - "pcmpeqb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" - "pcmpeqb %[ftmp2], %[ftmp2], %[ftmp2] \n\t" - "pxor %[ftmp1], %[ftmp1], %[ftmp2] \n\t" - - "pxor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" - "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" - "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" - "pxor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" - - "psubsb %[ftmp2], %[ftmp4], %[ftmp7] \n\t" - "pand %[ftmp2], %[ftmp2], %[ftmp1] \n\t" - "psubsb %[ftmp3], %[ftmp6], %[ftmp5] \n\t" - "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" - "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" - "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" - "pand %[ftmp2], %[ftmp2], %[ftmp0] \n\t" - - "paddsb %[ftmp8], %[ftmp2], %[ff_pb_03] \n\t" - "paddsb %[ftmp9], %[ftmp2], %[ff_pb_04] \n\t" - - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "pxor %[ftmp11], %[ftmp11], %[ftmp11] \n\t" - "punpcklbh %[ftmp0], %[ftmp0], %[ftmp8] \n\t" - "punpckhbh %[ftmp11], %[ftmp11], %[ftmp8] \n\t" - - "dli %[tmp0], 0x0b \n\t" - "dmtc1 %[tmp0], %[ftmp10] \n\t" - "psrah %[ftmp0], %[ftmp0], %[ftmp10] \n\t" - "psrah %[ftmp11], %[ftmp11], %[ftmp10] \n\t" - "packsshb %[ftmp8], %[ftmp0], %[ftmp11] \n\t" - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "punpcklbh %[ftmp0], %[ftmp0], %[ftmp9] \n\t" - "psrah %[ftmp0], %[ftmp0], %[ftmp10] \n\t" - "pxor %[ftmp11], %[ftmp11], %[ftmp11] \n\t" - "punpckhbh %[ftmp9], %[ftmp11], %[ftmp9] \n\t" - "psrah %[ftmp9], %[ftmp9], %[ftmp10] \n\t" - "paddsh %[ftmp11], %[ftmp0], %[ff_ph_01] \n\t" - "packsshb %[ftmp0], %[ftmp0], %[ftmp9] \n\t" - "paddsh %[ftmp9], %[ftmp9], %[ff_ph_01] \n\t" - - "dli %[tmp0], 0x01 \n\t" - "dmtc1 %[tmp0], %[ftmp10] \n\t" - "psrah %[ftmp11], %[ftmp11], %[ftmp10] \n\t" - "psrah %[ftmp9], %[ftmp9], %[ftmp10] \n\t" - "packsshb %[ftmp11], %[ftmp11], %[ftmp9] \n\t" - "pandn %[ftmp1], %[ftmp1], %[ftmp11] \n\t" - "paddsb %[ftmp5], %[ftmp5], %[ftmp8] \n\t" - "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" - - MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) - "gssdlc1 %[ftmp5], 0x07(%[addr1]) \n\t" - "gssdrc1 %[ftmp5], 0x00(%[addr1]) \n\t" - MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step_x2]) - "paddsb %[ftmp4], %[ftmp4], %[ftmp1] \n\t" - "pxor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" - "gssdlc1 %[ftmp4], 0x07(%[addr1]) \n\t" - "gssdrc1 %[ftmp4], 0x00(%[addr1]) \n\t" - - "psubsb %[ftmp6], %[ftmp6], %[ftmp0] \n\t" - "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" - "gssdlc1 %[ftmp6], 0x07(%[src_ptr]) \n\t" - "gssdrc1 %[ftmp6], 0x00(%[src_ptr]) \n\t" - - "psubsb %[ftmp7], %[ftmp7], %[ftmp1] \n\t" - "pxor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" - "gssdlc1 %[ftmp7], 0x07(%[addr0]) \n\t" - "gssdrc1 %[ftmp7], 0x00(%[addr0]) \n\t" - - "addiu %[count], %[count], -0x01 \n\t" - MMI_ADDIU(%[src_ptr], %[src_ptr], 0x08) - "bnez %[count], 1b \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), - [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), - [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), - [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), - [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), - [tmp0]"=&r"(tmp[0]), - [addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1]), - [src_ptr]"+&r"(src_ptr), [count]"+&r"(count), - [ff_ph_01]"=&f"(ff_ph_01), [ff_pb_fe]"=&f"(ff_pb_fe), - [ff_pb_80]"=&f"(ff_pb_80), [ff_pb_04]"=&f"(ff_pb_04), - [ff_pb_03]"=&f"(ff_pb_03) - : [limit]"r"(limit), [blimit]"r"(blimit), - [thresh]"r"(thresh), - [src_pixel_step]"r"((mips_reg)src_pixel_step), - [src_pixel_step_x2]"r"((mips_reg)(src_pixel_step<<1)), - [src_pixel_step_x4]"r"((mips_reg)(src_pixel_step<<2)) - : "memory" - ); - /* clang-format on */ -} - -void vp8_loop_filter_vertical_edge_mmi(unsigned char *src_ptr, - int src_pixel_step, - const unsigned char *blimit, - const unsigned char *limit, - const unsigned char *thresh, int count) { - uint64_t tmp[1]; - mips_reg addr[2]; - double ftmp[13]; - double ff_pb_fe, ff_ph_01, ff_pb_03, ff_pb_04, ff_pb_80; - - /* clang-format off */ - __asm__ volatile ( - "dli %[tmp0], 0xfefefefefefefefe \n\t" - "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" - "dli %[tmp0], 0x0001000100010001 \n\t" - "dmtc1 %[tmp0], %[ff_ph_01] \n\t" - "dli %[tmp0], 0x0303030303030303 \n\t" - "dmtc1 %[tmp0], %[ff_pb_03] \n\t" - "dli %[tmp0], 0x0404040404040404 \n\t" - "dmtc1 %[tmp0], %[ff_pb_04] \n\t" - "dli %[tmp0], 0x8080808080808080 \n\t" - "dmtc1 %[tmp0], %[ff_pb_80] \n\t" - MMI_SLL(%[tmp0], %[src_pixel_step], 0x02) - MMI_ADDU(%[src_ptr], %[src_ptr], %[tmp0]) - MMI_SUBU(%[src_ptr], %[src_ptr], 0x04) - - "1: \n\t" - MMI_ADDU(%[addr0], %[src_ptr], %[src_pixel_step]) - - MMI_SLL (%[tmp0], %[src_pixel_step], 0x01) - MMI_ADDU(%[addr1], %[src_ptr], %[tmp0]) - "gsldlc1 %[ftmp11], 0x07(%[addr1]) \n\t" - "gsldrc1 %[ftmp11], 0x00(%[addr1]) \n\t" - MMI_ADDU(%[addr1], %[addr0], %[tmp0]) - "gsldlc1 %[ftmp12], 0x07(%[addr1]) \n\t" - "gsldrc1 %[ftmp12], 0x00(%[addr1]) \n\t" - "punpcklbh %[ftmp1], %[ftmp11], %[ftmp12] \n\t" - "punpckhbh %[ftmp2], %[ftmp11], %[ftmp12] \n\t" - - "gsldlc1 %[ftmp11], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp11], 0x00(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp12], 0x07(%[addr0]) \n\t" - "gsldrc1 %[ftmp12], 0x00(%[addr0]) \n\t" - "punpcklbh %[ftmp3], %[ftmp11], %[ftmp12] \n\t" - "punpckhbh %[ftmp4], %[ftmp11], %[ftmp12] \n\t" - - "punpcklhw %[ftmp5], %[ftmp4], %[ftmp2] \n\t" - "punpckhhw %[ftmp6], %[ftmp4], %[ftmp2] \n\t" - "punpcklhw %[ftmp7], %[ftmp3], %[ftmp1] \n\t" - "punpckhhw %[ftmp8], %[ftmp3], %[ftmp1] \n\t" - - MMI_SLL(%[tmp0], %[src_pixel_step], 0x01) - MMI_SUBU(%[addr1], %[src_ptr], %[tmp0]) - "gsldlc1 %[ftmp11], 0x07(%[addr1]) \n\t" - "gsldrc1 %[ftmp11], 0x00(%[addr1]) \n\t" - MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) - "gsldlc1 %[ftmp12], 0x07(%[addr1]) \n\t" - "gsldrc1 %[ftmp12], 0x00(%[addr1]) \n\t" - "punpcklbh %[ftmp9], %[ftmp11], %[ftmp12] \n\t" - "punpckhbh %[ftmp10], %[ftmp11], %[ftmp12] \n\t" - - MMI_SLL(%[tmp0], %[src_pixel_step], 0x02) - MMI_SUBU(%[addr1], %[src_ptr], %[tmp0]) - "gsldlc1 %[ftmp11], 0x07(%[addr1]) \n\t" - "gsldrc1 %[ftmp11], 0x00(%[addr1]) \n\t" - MMI_SLL(%[tmp0], %[src_pixel_step], 0x02) - MMI_SUBU(%[addr1], %[addr0], %[tmp0]) - "gsldlc1 %[ftmp12], 0x07(%[addr1]) \n\t" - "gsldrc1 %[ftmp12], 0x00(%[addr1]) \n\t" - "punpcklbh %[ftmp0], %[ftmp11], %[ftmp12] \n\t" - "punpckhbh %[ftmp11], %[ftmp11], %[ftmp12] \n\t" - - "punpcklhw %[ftmp1], %[ftmp11], %[ftmp10] \n\t" - "punpckhhw %[ftmp2], %[ftmp11], %[ftmp10] \n\t" - "punpcklhw %[ftmp3], %[ftmp0], %[ftmp9] \n\t" - "punpckhhw %[ftmp4], %[ftmp0], %[ftmp9] \n\t" - - /* ftmp9:q0 ftmp10:q1 */ - "punpcklwd %[ftmp9], %[ftmp1], %[ftmp5] \n\t" - "punpckhwd %[ftmp10], %[ftmp1], %[ftmp5] \n\t" - /* ftmp11:q2 ftmp12:q3 */ - "punpcklwd %[ftmp11], %[ftmp2], %[ftmp6] \n\t" - "punpckhwd %[ftmp12], %[ftmp2], %[ftmp6] \n\t" - /* ftmp1:p3 ftmp2:p2 */ - "punpcklwd %[ftmp1], %[ftmp3], %[ftmp7] \n\t" - "punpckhwd %[ftmp2], %[ftmp3], %[ftmp7] \n\t" - /* ftmp5:p1 ftmp6:p0 */ - "punpcklwd %[ftmp5], %[ftmp4], %[ftmp8] \n\t" - "punpckhwd %[ftmp6], %[ftmp4], %[ftmp8] \n\t" - - "gsldlc1 %[ftmp8], 0x07(%[limit]) \n\t" - "gsldrc1 %[ftmp8], 0x00(%[limit]) \n\t" - - /* abs (q3-q2) */ - "pasubub %[ftmp7], %[ftmp12], %[ftmp11] \n\t" - "psubusb %[ftmp0], %[ftmp7], %[ftmp8] \n\t" - /* abs (q2-q1) */ - "pasubub %[ftmp7], %[ftmp11], %[ftmp10] \n\t" - "psubusb %[ftmp7], %[ftmp7], %[ftmp8] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - /* ftmp3: abs(q1-q0) */ - "pasubub %[ftmp3], %[ftmp10], %[ftmp9] \n\t" - "psubusb %[ftmp7], %[ftmp3], %[ftmp8] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - /* ftmp4: abs(p1-p0) */ - "pasubub %[ftmp4], %[ftmp5], %[ftmp6] \n\t" - "psubusb %[ftmp7], %[ftmp4], %[ftmp8] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - /* abs (p2-p1) */ - "pasubub %[ftmp7], %[ftmp2], %[ftmp5] \n\t" - "psubusb %[ftmp7], %[ftmp7], %[ftmp8] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - /* abs (p3-p2) */ - "pasubub %[ftmp7], %[ftmp1], %[ftmp2] \n\t" - "psubusb %[ftmp7], %[ftmp7], %[ftmp8] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - - "gsldlc1 %[ftmp8], 0x07(%[blimit]) \n\t" - "gsldrc1 %[ftmp8], 0x00(%[blimit]) \n\t" - - /* abs (p0-q0) */ - "pasubub %[ftmp11], %[ftmp9], %[ftmp6] \n\t" - "paddusb %[ftmp11], %[ftmp11], %[ftmp11] \n\t" - /* abs (p1-q1) */ - "pasubub %[ftmp12], %[ftmp10], %[ftmp5] \n\t" - "pand %[ftmp12], %[ftmp12], %[ff_pb_fe] \n\t" - "dli %[tmp0], 0x01 \n\t" - "dmtc1 %[tmp0], %[ftmp1] \n\t" - "psrlh %[ftmp12], %[ftmp12], %[ftmp1] \n\t" - "paddusb %[ftmp1], %[ftmp11], %[ftmp12] \n\t" - "psubusb %[ftmp1], %[ftmp1], %[ftmp8] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - "pxor %[ftmp1], %[ftmp1], %[ftmp1] \n\t" - /* ftmp0:mask */ - "pcmpeqb %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - - "gsldlc1 %[ftmp8], 0x07(%[thresh]) \n\t" - "gsldrc1 %[ftmp8], 0x00(%[thresh]) \n\t" - - /* ftmp3: abs(q1-q0) ftmp4: abs(p1-p0) */ - "psubusb %[ftmp4], %[ftmp4], %[ftmp8] \n\t" - "psubusb %[ftmp3], %[ftmp3], %[ftmp8] \n\t" - "por %[ftmp2], %[ftmp4], %[ftmp3] \n\t" - "pcmpeqb %[ftmp2], %[ftmp2], %[ftmp1] \n\t" - "pcmpeqb %[ftmp1], %[ftmp1], %[ftmp1] \n\t" - /* ftmp1:hev */ - "pxor %[ftmp1], %[ftmp2], %[ftmp1] \n\t" - - "pxor %[ftmp10], %[ftmp10], %[ff_pb_80] \n\t" - "pxor %[ftmp9], %[ftmp9], %[ff_pb_80] \n\t" - "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" - "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" - - "psubsb %[ftmp2], %[ftmp5], %[ftmp10] \n\t" - "pand %[ftmp2], %[ftmp2], %[ftmp1] \n\t" - "psubsb %[ftmp3], %[ftmp9], %[ftmp6] \n\t" - "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" - "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" - "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" - /* ftmp2:filter_value */ - "pand %[ftmp2], %[ftmp2], %[ftmp0] \n\t" - - "paddsb %[ftmp11], %[ftmp2], %[ff_pb_04] \n\t" - "paddsb %[ftmp12], %[ftmp2], %[ff_pb_03] \n\t" - - "dli %[tmp0], 0x0b \n\t" - "dmtc1 %[tmp0], %[ftmp7] \n\t" - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" - "punpcklbh %[ftmp0], %[ftmp0], %[ftmp12] \n\t" - "punpckhbh %[ftmp8], %[ftmp8], %[ftmp12] \n\t" - "psrah %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - "psrah %[ftmp8], %[ftmp8], %[ftmp7] \n\t" - "packsshb %[ftmp12], %[ftmp0], %[ftmp8] \n\t" - - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" - "punpcklbh %[ftmp0], %[ftmp0], %[ftmp11] \n\t" - "punpckhbh %[ftmp8], %[ftmp8], %[ftmp11] \n\t" - "psrah %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - "psrah %[ftmp8], %[ftmp8], %[ftmp7] \n\t" - "packsshb %[ftmp11], %[ftmp0], %[ftmp8] \n\t" - - "psubsb %[ftmp9], %[ftmp9], %[ftmp11] \n\t" - "pxor %[ftmp9], %[ftmp9], %[ff_pb_80] \n\t" - "paddsb %[ftmp6], %[ftmp6], %[ftmp12] \n\t" - "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" - "paddsh %[ftmp0], %[ftmp0], %[ff_ph_01] \n\t" - "paddsh %[ftmp8], %[ftmp8], %[ff_ph_01] \n\t" - - "dli %[tmp0], 0x01 \n\t" - "dmtc1 %[tmp0], %[ftmp7] \n\t" - "psrah %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - "psrah %[ftmp8], %[ftmp8], %[ftmp7] \n\t" - "packsshb %[ftmp2], %[ftmp0], %[ftmp8] \n\t" - "pandn %[ftmp2], %[ftmp1], %[ftmp2] \n\t" - "psubsb %[ftmp10], %[ftmp10], %[ftmp2] \n\t" - "pxor %[ftmp10], %[ftmp10], %[ff_pb_80] \n\t" - "paddsb %[ftmp5], %[ftmp5], %[ftmp2] \n\t" - "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" - - /* ftmp5: *op1 ; ftmp6: *op0 */ - "punpcklbh %[ftmp2], %[ftmp5], %[ftmp6] \n\t" - "punpckhbh %[ftmp1], %[ftmp5], %[ftmp6] \n\t" - /* ftmp9: *oq0 ; ftmp10: *oq1 */ - "punpcklbh %[ftmp4], %[ftmp9], %[ftmp10] \n\t" - "punpckhbh %[ftmp3], %[ftmp9], %[ftmp10] \n\t" - "punpckhhw %[ftmp6], %[ftmp2], %[ftmp4] \n\t" - "punpcklhw %[ftmp2], %[ftmp2], %[ftmp4] \n\t" - "punpckhhw %[ftmp5], %[ftmp1], %[ftmp3] \n\t" - "punpcklhw %[ftmp1], %[ftmp1], %[ftmp3] \n\t" - - MMI_SLL(%[tmp0], %[src_pixel_step], 0x02) - MMI_SUBU(%[addr1], %[src_ptr], %[tmp0]) - "gsswlc1 %[ftmp2], 0x05(%[addr1]) \n\t" - "gsswrc1 %[ftmp2], 0x02(%[addr1]) \n\t" - - "li %[tmp0], 0x20 \n\t" - "mtc1 %[tmp0], %[ftmp9] \n\t" - "ssrld %[ftmp2], %[ftmp2], %[ftmp9] \n\t" - MMI_SLL(%[tmp0], %[src_pixel_step], 0x02) - MMI_SUBU(%[addr1], %[addr0], %[tmp0]) - "gsswlc1 %[ftmp2], 0x05(%[addr1]) \n\t" - "gsswrc1 %[ftmp2], 0x02(%[addr1]) \n\t" - - MMI_SLL(%[tmp0], %[src_pixel_step], 0x01) - MMI_SUBU(%[addr1], %[src_ptr], %[tmp0]) - "gsswlc1 %[ftmp6], 0x05(%[addr1]) \n\t" - "gsswrc1 %[ftmp6], 0x02(%[addr1]) \n\t" - - "ssrld %[ftmp6], %[ftmp6], %[ftmp9] \n\t" - MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) - "gsswlc1 %[ftmp6], 0x05(%[addr1]) \n\t" - "gsswrc1 %[ftmp6], 0x02(%[addr1]) \n\t" - "gsswlc1 %[ftmp1], 0x05(%[src_ptr]) \n\t" - "gsswrc1 %[ftmp1], 0x02(%[src_ptr]) \n\t" - - "ssrld %[ftmp1], %[ftmp1], %[ftmp9] \n\t" - "gsswlc1 %[ftmp1], 0x05(%[addr0]) \n\t" - "gsswrc1 %[ftmp1], 0x02(%[addr0]) \n\t" - MMI_ADDU(%[addr1], %[addr0], %[src_pixel_step]) - "gsswlc1 %[ftmp5], 0x05(%[addr1]) \n\t" - "gsswrc1 %[ftmp5], 0x02(%[addr1]) \n\t" - - "ssrld %[ftmp5], %[ftmp5], %[ftmp9] \n\t" - MMI_ADDU(%[addr1], %[addr0], %[tmp0]) - "gsswlc1 %[ftmp5], 0x05(%[addr1]) \n\t" - "gsswrc1 %[ftmp5], 0x02(%[addr1]) \n\t" - - MMI_ADDIU(%[count], %[count], -0x01) - MMI_SLL(%[tmp0], %[src_pixel_step], 0x03) - MMI_ADDU(%[src_ptr], %[src_ptr], %[tmp0]) - "bnez %[count], 1b \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), - [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), - [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), - [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), - [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), - [ftmp12]"=&f"(ftmp[12]), [tmp0]"=&r"(tmp[0]), - [addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1]), - [src_ptr]"+&r"(src_ptr), [count]"+&r"(count), - [ff_ph_01]"=&f"(ff_ph_01), [ff_pb_03]"=&f"(ff_pb_03), - [ff_pb_04]"=&f"(ff_pb_04), [ff_pb_80]"=&f"(ff_pb_80), - [ff_pb_fe]"=&f"(ff_pb_fe) - : [limit]"r"(limit), [blimit]"r"(blimit), - [thresh]"r"(thresh), - [src_pixel_step]"r"((mips_reg)src_pixel_step) - : "memory" - ); - /* clang-format on */ -} - -/* clang-format off */ -#define VP8_MBLOOP_HPSRAB \ - "punpcklbh %[ftmp10], %[ftmp10], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp11], %[ftmp11], %[ftmp0] \n\t" \ - "psrah %[ftmp10], %[ftmp10], %[ftmp9] \n\t" \ - "psrah %[ftmp11], %[ftmp11], %[ftmp9] \n\t" \ - "packsshb %[ftmp0], %[ftmp10], %[ftmp11] \n\t" - -#define VP8_MBLOOP_HPSRAB_ADD(reg) \ - "punpcklbh %[ftmp1], %[ftmp0], %[ftmp12] \n\t" \ - "punpckhbh %[ftmp2], %[ftmp0], %[ftmp12] \n\t" \ - "pmulhh %[ftmp1], %[ftmp1], " #reg " \n\t" \ - "pmulhh %[ftmp2], %[ftmp2], " #reg " \n\t" \ - "paddh %[ftmp1], %[ftmp1], %[ff_ph_003f] \n\t" \ - "paddh %[ftmp2], %[ftmp2], %[ff_ph_003f] \n\t" \ - "psrah %[ftmp1], %[ftmp1], %[ftmp9] \n\t" \ - "psrah %[ftmp2], %[ftmp2], %[ftmp9] \n\t" \ - "packsshb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" -/* clang-format on */ - -void vp8_mbloop_filter_horizontal_edge_mmi( - unsigned char *src_ptr, int src_pixel_step, const unsigned char *blimit, - const unsigned char *limit, const unsigned char *thresh, int count) { - uint64_t tmp[1]; - double ftmp[13]; - double ff_pb_fe, ff_pb_80, ff_pb_04, ff_pb_03, ff_ph_003f, ff_ph_0900, - ff_ph_1200, ff_ph_1b00; - - /* clang-format off */ - __asm__ volatile ( - "dli %[tmp0], 0xfefefefefefefefe \n\t" - "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" - "dli %[tmp0], 0x8080808080808080 \n\t" - "dmtc1 %[tmp0], %[ff_pb_80] \n\t" - "dli %[tmp0], 0x0404040404040404 \n\t" - "dmtc1 %[tmp0], %[ff_pb_04] \n\t" - "dli %[tmp0], 0x0303030303030303 \n\t" - "dmtc1 %[tmp0], %[ff_pb_03] \n\t" - "dli %[tmp0], 0x003f003f003f003f \n\t" - "dmtc1 %[tmp0], %[ff_ph_003f] \n\t" - "dli %[tmp0], 0x0900090009000900 \n\t" - "dmtc1 %[tmp0], %[ff_ph_0900] \n\t" - "dli %[tmp0], 0x1200120012001200 \n\t" - "dmtc1 %[tmp0], %[ff_ph_1200] \n\t" - "dli %[tmp0], 0x1b001b001b001b00 \n\t" - "dmtc1 %[tmp0], %[ff_ph_1b00] \n\t" - MMI_SLL(%[tmp0], %[src_pixel_step], 0x02) - MMI_SUBU(%[src_ptr], %[src_ptr], %[tmp0]) - "1: \n\t" - "gsldlc1 %[ftmp9], 0x07(%[limit]) \n\t" - "gsldrc1 %[ftmp9], 0x00(%[limit]) \n\t" - /* ftmp1: p3 */ - "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" - /* ftmp3: p2 */ - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gsldlc1 %[ftmp3], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp3], 0x00(%[src_ptr]) \n\t" - /* ftmp4: p1 */ - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gsldlc1 %[ftmp4], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp4], 0x00(%[src_ptr]) \n\t" - /* ftmp5: p0 */ - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gsldlc1 %[ftmp5], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp5], 0x00(%[src_ptr]) \n\t" - /* ftmp6: q0 */ - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gsldlc1 %[ftmp6], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp6], 0x00(%[src_ptr]) \n\t" - /* ftmp7: q1 */ - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gsldlc1 %[ftmp7], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp7], 0x00(%[src_ptr]) \n\t" - /* ftmp8: q2 */ - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gsldlc1 %[ftmp8], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp8], 0x00(%[src_ptr]) \n\t" - /* ftmp2: q3 */ - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gsldlc1 %[ftmp2], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x00(%[src_ptr]) \n\t" - - "gsldlc1 %[ftmp12], 0x07(%[blimit]) \n\t" - "gsldrc1 %[ftmp12], 0x00(%[blimit]) \n\t" - - "pasubub %[ftmp0], %[ftmp1], %[ftmp3] \n\t" - "psubusb %[ftmp0], %[ftmp0], %[ftmp9] \n\t" - "pasubub %[ftmp1], %[ftmp3], %[ftmp4] \n\t" - "psubusb %[ftmp1], %[ftmp1], %[ftmp9] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - "pasubub %[ftmp10], %[ftmp4], %[ftmp5] \n\t" - "psubusb %[ftmp1], %[ftmp10], %[ftmp9] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - "pasubub %[ftmp11], %[ftmp7], %[ftmp6] \n\t" - "psubusb %[ftmp1], %[ftmp11], %[ftmp9] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - "pasubub %[ftmp1], %[ftmp8], %[ftmp7] \n\t" - "psubusb %[ftmp1], %[ftmp1], %[ftmp9] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - "pasubub %[ftmp1], %[ftmp2], %[ftmp8] \n\t" - "psubusb %[ftmp1], %[ftmp1], %[ftmp9] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - - "pasubub %[ftmp1], %[ftmp5], %[ftmp6] \n\t" - "paddusb %[ftmp1], %[ftmp1], %[ftmp1] \n\t" - "pasubub %[ftmp2], %[ftmp4], %[ftmp7] \n\t" - "pand %[ftmp2], %[ftmp2], %[ff_pb_fe] \n\t" - "dli %[tmp0], 0x01 \n\t" - "dmtc1 %[tmp0], %[ftmp9] \n\t" - "psrlh %[ftmp2], %[ftmp2], %[ftmp9] \n\t" - "paddusb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" - "psubusb %[ftmp1], %[ftmp1], %[ftmp12] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - "pxor %[ftmp9], %[ftmp9], %[ftmp9] \n\t" - /* ftmp0: mask */ - "pcmpeqb %[ftmp0], %[ftmp0], %[ftmp9] \n\t" - - "gsldlc1 %[ftmp9], 0x07(%[thresh]) \n\t" - "gsldrc1 %[ftmp9], 0x00(%[thresh]) \n\t" - "psubusb %[ftmp1], %[ftmp10], %[ftmp9] \n\t" - "psubusb %[ftmp2], %[ftmp11], %[ftmp9] \n\t" - "paddb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" - "pxor %[ftmp2], %[ftmp2], %[ftmp2] \n\t" - "pcmpeqb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" - "pcmpeqb %[ftmp2], %[ftmp2], %[ftmp2] \n\t" - /* ftmp1: hev */ - "pxor %[ftmp1], %[ftmp1], %[ftmp2] \n\t" - - "pxor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" - "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" - "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" - "pxor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" - "psubsb %[ftmp2], %[ftmp4], %[ftmp7] \n\t" - "psubsb %[ftmp9], %[ftmp6], %[ftmp5] \n\t" - "paddsb %[ftmp2], %[ftmp2], %[ftmp9] \n\t" - "paddsb %[ftmp2], %[ftmp2], %[ftmp9] \n\t" - "paddsb %[ftmp2], %[ftmp2], %[ftmp9] \n\t" - "pand %[ftmp2], %[ftmp2], %[ftmp0] \n\t" - "pandn %[ftmp12], %[ftmp1], %[ftmp2] \n\t" - "pand %[ftmp2], %[ftmp2], %[ftmp1] \n\t" - - "dli %[tmp0], 0x0b \n\t" - "dmtc1 %[tmp0], %[ftmp9] \n\t" - "paddsb %[ftmp0], %[ftmp2], %[ff_pb_03] \n\t" - VP8_MBLOOP_HPSRAB - "paddsb %[ftmp5], %[ftmp5], %[ftmp0] \n\t" - "paddsb %[ftmp0], %[ftmp2], %[ff_pb_04] \n\t" - VP8_MBLOOP_HPSRAB - "psubsb %[ftmp6], %[ftmp6], %[ftmp0] \n\t" - - "dli %[tmp0], 0x07 \n\t" - "dmtc1 %[tmp0], %[ftmp9] \n\t" - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - - VP8_MBLOOP_HPSRAB_ADD(%[ff_ph_1b00]) - "psubsb %[ftmp6], %[ftmp6], %[ftmp1] \n\t" - "paddsb %[ftmp5], %[ftmp5], %[ftmp1] \n\t" - "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" - "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" - MMI_SLL(%[tmp0], %[src_pixel_step], 0x02) - MMI_SUBU(%[src_ptr], %[src_ptr], %[tmp0]) - "gssdlc1 %[ftmp5], 0x07(%[src_ptr]) \n\t" - "gssdrc1 %[ftmp5], 0x00(%[src_ptr]) \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gssdlc1 %[ftmp6], 0x07(%[src_ptr]) \n\t" - "gssdrc1 %[ftmp6], 0x00(%[src_ptr]) \n\t" - - VP8_MBLOOP_HPSRAB_ADD(%[ff_ph_1200]) - "paddsb %[ftmp4], %[ftmp4], %[ftmp1] \n\t" - "psubsb %[ftmp7], %[ftmp7], %[ftmp1] \n\t" - "pxor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" - "pxor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gssdlc1 %[ftmp7], 0x07(%[src_ptr]) \n\t" - "gssdrc1 %[ftmp7], 0x00(%[src_ptr]) \n\t" - MMI_SUBU(%[src_ptr], %[src_ptr], %[tmp0]) - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gssdlc1 %[ftmp4], 0x07(%[src_ptr]) \n\t" - "gssdrc1 %[ftmp4], 0x00(%[src_ptr]) \n\t" - - VP8_MBLOOP_HPSRAB_ADD(%[ff_ph_0900]) - "pxor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" - "pxor %[ftmp8], %[ftmp8], %[ff_pb_80] \n\t" - "paddsb %[ftmp3], %[ftmp3], %[ftmp1] \n\t" - "psubsb %[ftmp8], %[ftmp8], %[ftmp1] \n\t" - "pxor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" - "pxor %[ftmp8], %[ftmp8], %[ff_pb_80] \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[tmp0]) - "gssdlc1 %[ftmp8], 0x07(%[src_ptr]) \n\t" - "gssdrc1 %[ftmp8], 0x00(%[src_ptr]) \n\t" - MMI_SUBU(%[src_ptr], %[src_ptr], %[tmp0]) - MMI_SUBU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gssdlc1 %[ftmp3], 0x07(%[src_ptr]) \n\t" - "gssdrc1 %[ftmp3], 0x00(%[src_ptr]) \n\t" - - MMI_SUBU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - MMI_ADDIU(%[src_ptr], %[src_ptr], 0x08) - "addiu %[count], %[count], -0x01 \n\t" - "bnez %[count], 1b \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), - [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), - [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), - [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), - [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), - [ftmp12]"=&f"(ftmp[12]), [tmp0]"=&r"(tmp[0]), - [src_ptr]"+&r"(src_ptr), [count]"+&r"(count), - [ff_pb_fe]"=&f"(ff_pb_fe), [ff_pb_80]"=&f"(ff_pb_80), - [ff_pb_04]"=&f"(ff_pb_04), [ff_pb_03]"=&f"(ff_pb_03), - [ff_ph_0900]"=&f"(ff_ph_0900), [ff_ph_1b00]"=&f"(ff_ph_1b00), - [ff_ph_1200]"=&f"(ff_ph_1200), [ff_ph_003f]"=&f"(ff_ph_003f) - : [limit]"r"(limit), [blimit]"r"(blimit), - [thresh]"r"(thresh), - [src_pixel_step]"r"((mips_reg)src_pixel_step) - : "memory" - ); - /* clang-format on */ -} - -/* clang-format off */ -#define VP8_MBLOOP_VPSRAB_ADDH \ - "pxor %[ftmp7], %[ftmp7], %[ftmp7] \n\t" \ - "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" \ - "punpcklbh %[ftmp7], %[ftmp7], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp8], %[ftmp8], %[ftmp0] \n\t" - -#define VP8_MBLOOP_VPSRAB_ADDT \ - "paddh %[ftmp7], %[ftmp7], %[ff_ph_003f] \n\t" \ - "paddh %[ftmp8], %[ftmp8], %[ff_ph_003f] \n\t" \ - "psrah %[ftmp7], %[ftmp7], %[ftmp12] \n\t" \ - "psrah %[ftmp8], %[ftmp8], %[ftmp12] \n\t" \ - "packsshb %[ftmp3], %[ftmp7], %[ftmp8] \n\t" -/* clang-format on */ - -void vp8_mbloop_filter_vertical_edge_mmi( - unsigned char *src_ptr, int src_pixel_step, const unsigned char *blimit, - const unsigned char *limit, const unsigned char *thresh, int count) { - mips_reg tmp[1]; - DECLARE_ALIGNED(8, const uint64_t, srct[2]); - double ftmp[14]; - double ff_ph_003f, ff_ph_0900, ff_pb_fe, ff_pb_80, ff_pb_04, ff_pb_03; - - /* clang-format off */ - __asm__ volatile ( - "dli %[tmp0], 0x003f003f003f003f \n\t" - "dmtc1 %[tmp0], %[ff_ph_003f] \n\t" - "dli %[tmp0], 0x0900090009000900 \n\t" - "dmtc1 %[tmp0], %[ff_ph_0900] \n\t" - "dli %[tmp0], 0xfefefefefefefefe \n\t" - "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" - "dli %[tmp0], 0x8080808080808080 \n\t" - "dmtc1 %[tmp0], %[ff_pb_80] \n\t" - "dli %[tmp0], 0x0404040404040404 \n\t" - "dmtc1 %[tmp0], %[ff_pb_04] \n\t" - "dli %[tmp0], 0x0303030303030303 \n\t" - "dmtc1 %[tmp0], %[ff_pb_03] \n\t" - MMI_SUBU(%[src_ptr], %[src_ptr], 0x04) - - "1: \n\t" - "gsldlc1 %[ftmp5], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp5], 0x00(%[src_ptr]) \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gsldlc1 %[ftmp6], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp6], 0x00(%[src_ptr]) \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gsldlc1 %[ftmp7], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp7], 0x00(%[src_ptr]) \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gsldlc1 %[ftmp8], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp8], 0x00(%[src_ptr]) \n\t" - - "punpcklbh %[ftmp11], %[ftmp5], %[ftmp6] \n\t" - "punpckhbh %[ftmp12], %[ftmp5], %[ftmp6] \n\t" - "punpcklbh %[ftmp9], %[ftmp7], %[ftmp8] \n\t" - "punpckhbh %[ftmp10], %[ftmp7], %[ftmp8] \n\t" - - "punpcklhw %[ftmp1], %[ftmp12], %[ftmp10] \n\t" - "punpckhhw %[ftmp2], %[ftmp12], %[ftmp10] \n\t" - "punpcklhw %[ftmp3], %[ftmp11], %[ftmp9] \n\t" - "punpckhhw %[ftmp4], %[ftmp11], %[ftmp9] \n\t" - - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gsldlc1 %[ftmp5], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp5], 0x00(%[src_ptr]) \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gsldlc1 %[ftmp6], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp6], 0x00(%[src_ptr]) \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gsldlc1 %[ftmp7], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp7], 0x00(%[src_ptr]) \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gsldlc1 %[ftmp8], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp8], 0x00(%[src_ptr]) \n\t" - - "punpcklbh %[ftmp11], %[ftmp5], %[ftmp6] \n\t" - "punpckhbh %[ftmp12], %[ftmp5], %[ftmp6] \n\t" - "punpcklbh %[ftmp9], %[ftmp7], %[ftmp8] \n\t" - "punpckhbh %[ftmp10], %[ftmp7], %[ftmp8] \n\t" - - "punpcklhw %[ftmp5], %[ftmp12], %[ftmp10] \n\t" - "punpckhhw %[ftmp6], %[ftmp12], %[ftmp10] \n\t" - "punpcklhw %[ftmp7], %[ftmp11], %[ftmp9] \n\t" - "punpckhhw %[ftmp8], %[ftmp11], %[ftmp9] \n\t" - - "gsldlc1 %[ftmp13], 0x07(%[limit]) \n\t" - "gsldrc1 %[ftmp13], 0x00(%[limit]) \n\t" - /* ftmp9:q0 ftmp10:q1 */ - "punpcklwd %[ftmp9], %[ftmp1], %[ftmp5] \n\t" - "punpckhwd %[ftmp10], %[ftmp1], %[ftmp5] \n\t" - /* ftmp11:q2 ftmp12:q3 */ - "punpcklwd %[ftmp11], %[ftmp2], %[ftmp6] \n\t" - "punpckhwd %[ftmp12], %[ftmp2], %[ftmp6] \n\t" - /* srct[0x00]: q3 */ - "sdc1 %[ftmp12], 0x00(%[srct]) \n\t" - /* ftmp1:p3 ftmp2:p2 */ - "punpcklwd %[ftmp1], %[ftmp3], %[ftmp7] \n\t" - "punpckhwd %[ftmp2], %[ftmp3], %[ftmp7] \n\t" - /* srct[0x08]: p3 */ - "sdc1 %[ftmp1], 0x08(%[srct]) \n\t" - /* ftmp5:p1 ftmp6:p0 */ - "punpcklwd %[ftmp5], %[ftmp4], %[ftmp8] \n\t" - "punpckhwd %[ftmp6], %[ftmp4], %[ftmp8] \n\t" - - /* abs (q3-q2) */ - "pasubub %[ftmp7], %[ftmp12], %[ftmp11] \n\t" - "psubusb %[ftmp0], %[ftmp7], %[ftmp13] \n\t" - /* abs (q2-q1) */ - "pasubub %[ftmp7], %[ftmp11], %[ftmp10] \n\t" - "psubusb %[ftmp7], %[ftmp7], %[ftmp13] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - /* ftmp3: abs(q1-q0) */ - "pasubub %[ftmp3], %[ftmp10], %[ftmp9] \n\t" - "psubusb %[ftmp7], %[ftmp3], %[ftmp13] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - /* ftmp4: abs(p1-p0) */ - "pasubub %[ftmp4], %[ftmp5], %[ftmp6] \n\t" - "psubusb %[ftmp7], %[ftmp4], %[ftmp13] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - /* abs (p2-p1) */ - "pasubub %[ftmp7], %[ftmp2], %[ftmp5] \n\t" - "psubusb %[ftmp7], %[ftmp7], %[ftmp13] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - /* abs (p3-p2) */ - "pasubub %[ftmp7], %[ftmp1], %[ftmp2] \n\t" - "psubusb %[ftmp7], %[ftmp7], %[ftmp13] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - - "gsldlc1 %[ftmp13], 0x07(%[blimit]) \n\t" - "gsldrc1 %[ftmp13], 0x00(%[blimit]) \n\t" - "gsldlc1 %[ftmp7], 0x07(%[thresh]) \n\t" - "gsldrc1 %[ftmp7], 0x00(%[thresh]) \n\t" - /* abs (p0-q0) * 2 */ - "pasubub %[ftmp1], %[ftmp9], %[ftmp6] \n\t" - "paddusb %[ftmp1], %[ftmp1], %[ftmp1] \n\t" - /* abs (p1-q1) / 2 */ - "pasubub %[ftmp12], %[ftmp10], %[ftmp5] \n\t" - "pand %[ftmp12], %[ftmp12], %[ff_pb_fe] \n\t" - "dli %[tmp0], 0x01 \n\t" - "dmtc1 %[tmp0], %[ftmp8] \n\t" - "psrlh %[ftmp12], %[ftmp12], %[ftmp8] \n\t" - "paddusb %[ftmp12], %[ftmp1], %[ftmp12] \n\t" - "psubusb %[ftmp12], %[ftmp12], %[ftmp13] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp12] \n\t" - "pxor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" - /* ftmp0: mask */ - "pcmpeqb %[ftmp0], %[ftmp0], %[ftmp12] \n\t" - - /* abs(p1-p0) - thresh */ - "psubusb %[ftmp4], %[ftmp4], %[ftmp7] \n\t" - /* abs(q1-q0) - thresh */ - "psubusb %[ftmp3], %[ftmp3], %[ftmp7] \n\t" - "por %[ftmp3], %[ftmp4], %[ftmp3] \n\t" - "pcmpeqb %[ftmp3], %[ftmp3], %[ftmp12] \n\t" - "pcmpeqb %[ftmp1], %[ftmp1], %[ftmp1] \n\t" - /* ftmp1: hev */ - "pxor %[ftmp1], %[ftmp3], %[ftmp1] \n\t" - - /* ftmp2:ps2, ftmp5:ps1, ftmp6:ps0, ftmp9:qs0, ftmp10:qs1, ftmp11:qs2 */ - "pxor %[ftmp11], %[ftmp11], %[ff_pb_80] \n\t" - "pxor %[ftmp10], %[ftmp10], %[ff_pb_80] \n\t" - "pxor %[ftmp9], %[ftmp9], %[ff_pb_80] \n\t" - "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" - "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" - "pxor %[ftmp2], %[ftmp2], %[ff_pb_80] \n\t" - - "psubsb %[ftmp3], %[ftmp5], %[ftmp10] \n\t" - "psubsb %[ftmp4], %[ftmp9], %[ftmp6] \n\t" - "paddsb %[ftmp3], %[ftmp3], %[ftmp4] \n\t" - "paddsb %[ftmp3], %[ftmp3], %[ftmp4] \n\t" - "paddsb %[ftmp3], %[ftmp3], %[ftmp4] \n\t" - /* filter_value &= mask */ - "pand %[ftmp0], %[ftmp0], %[ftmp3] \n\t" - /* Filter2 = filter_value & hev */ - "pand %[ftmp3], %[ftmp1], %[ftmp0] \n\t" - /* filter_value &= ~hev */ - "pandn %[ftmp0], %[ftmp1], %[ftmp0] \n\t" - - "paddsb %[ftmp4], %[ftmp3], %[ff_pb_04] \n\t" - "dli %[tmp0], 0x0b \n\t" - "dmtc1 %[tmp0], %[ftmp12] \n\t" - "punpcklbh %[ftmp7], %[ftmp7], %[ftmp4] \n\t" - "punpckhbh %[ftmp8], %[ftmp8], %[ftmp4] \n\t" - "psrah %[ftmp7], %[ftmp7], %[ftmp12] \n\t" - "psrah %[ftmp8], %[ftmp8], %[ftmp12] \n\t" - "packsshb %[ftmp4], %[ftmp7], %[ftmp8] \n\t" - /* ftmp9: qs0 */ - "psubsb %[ftmp9], %[ftmp9], %[ftmp4] \n\t" - "paddsb %[ftmp3], %[ftmp3], %[ff_pb_03] \n\t" - "punpcklbh %[ftmp7], %[ftmp7], %[ftmp3] \n\t" - "punpckhbh %[ftmp8], %[ftmp8], %[ftmp3] \n\t" - "psrah %[ftmp7], %[ftmp7], %[ftmp12] \n\t" - "psrah %[ftmp8], %[ftmp8], %[ftmp12] \n\t" - "packsshb %[ftmp3], %[ftmp7], %[ftmp8] \n\t" - /* ftmp6: ps0 */ - "paddsb %[ftmp6], %[ftmp6], %[ftmp3] \n\t" - - "dli %[tmp0], 0x07 \n\t" - "dmtc1 %[tmp0], %[ftmp12] \n\t" - VP8_MBLOOP_VPSRAB_ADDH - "paddh %[ftmp1], %[ff_ph_0900], %[ff_ph_0900] \n\t" - "paddh %[ftmp1], %[ftmp1], %[ff_ph_0900] \n\t" - "pmulhh %[ftmp7], %[ftmp7], %[ftmp1] \n\t" - "pmulhh %[ftmp8], %[ftmp8], %[ftmp1] \n\t" - VP8_MBLOOP_VPSRAB_ADDT - "psubsb %[ftmp4], %[ftmp9], %[ftmp3] \n\t" - /* ftmp9: oq0 */ - "pxor %[ftmp9], %[ftmp4], %[ff_pb_80] \n\t" - "paddsb %[ftmp4], %[ftmp6], %[ftmp3] \n\t" - /* ftmp6: op0 */ - "pxor %[ftmp6], %[ftmp4], %[ff_pb_80] \n\t" - - VP8_MBLOOP_VPSRAB_ADDH - "paddh %[ftmp1], %[ff_ph_0900], %[ff_ph_0900] \n\t" - "pmulhh %[ftmp7], %[ftmp7], %[ftmp1] \n\t" - "pmulhh %[ftmp8], %[ftmp8], %[ftmp1] \n\t" - VP8_MBLOOP_VPSRAB_ADDT - "psubsb %[ftmp4], %[ftmp10], %[ftmp3] \n\t" - /* ftmp10: oq1 */ - "pxor %[ftmp10], %[ftmp4], %[ff_pb_80] \n\t" - "paddsb %[ftmp4], %[ftmp5], %[ftmp3] \n\t" - /* ftmp5: op1 */ - "pxor %[ftmp5], %[ftmp4], %[ff_pb_80] \n\t" - - VP8_MBLOOP_VPSRAB_ADDH - "pmulhh %[ftmp7], %[ftmp7], %[ff_ph_0900] \n\t" - "pmulhh %[ftmp8], %[ftmp8], %[ff_ph_0900] \n\t" - VP8_MBLOOP_VPSRAB_ADDT - "psubsb %[ftmp4], %[ftmp11], %[ftmp3] \n\t" - /* ftmp11: oq2 */ - "pxor %[ftmp11], %[ftmp4], %[ff_pb_80] \n\t" - "paddsb %[ftmp4], %[ftmp2], %[ftmp3] \n\t" - /* ftmp2: op2 */ - "pxor %[ftmp2], %[ftmp4], %[ff_pb_80] \n\t" - - "ldc1 %[ftmp12], 0x00(%[srct]) \n\t" - "ldc1 %[ftmp8], 0x08(%[srct]) \n\t" - - "punpcklbh %[ftmp0], %[ftmp8], %[ftmp2] \n\t" - "punpckhbh %[ftmp1], %[ftmp8], %[ftmp2] \n\t" - "punpcklbh %[ftmp2], %[ftmp5], %[ftmp6] \n\t" - "punpckhbh %[ftmp3], %[ftmp5], %[ftmp6] \n\t" - "punpcklhw %[ftmp4], %[ftmp0], %[ftmp2] \n\t" - "punpckhhw %[ftmp5], %[ftmp0], %[ftmp2] \n\t" - "punpcklhw %[ftmp6], %[ftmp1], %[ftmp3] \n\t" - "punpckhhw %[ftmp7], %[ftmp1], %[ftmp3] \n\t" - - "punpcklbh %[ftmp0], %[ftmp9], %[ftmp10] \n\t" - "punpckhbh %[ftmp1], %[ftmp9], %[ftmp10] \n\t" - "punpcklbh %[ftmp2], %[ftmp11], %[ftmp12] \n\t" - "punpckhbh %[ftmp3], %[ftmp11], %[ftmp12] \n\t" - "punpcklhw %[ftmp8], %[ftmp0], %[ftmp2] \n\t" - "punpckhhw %[ftmp9], %[ftmp0], %[ftmp2] \n\t" - "punpcklhw %[ftmp10], %[ftmp1], %[ftmp3] \n\t" - "punpckhhw %[ftmp11], %[ftmp1], %[ftmp3] \n\t" - - "punpcklwd %[ftmp0], %[ftmp7], %[ftmp11] \n\t" - "punpckhwd %[ftmp1], %[ftmp7], %[ftmp11] \n\t" - "gssdlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" - "gssdrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" - MMI_SUBU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gssdlc1 %[ftmp0], 0x07(%[src_ptr]) \n\t" - "gssdrc1 %[ftmp0], 0x00(%[src_ptr]) \n\t" - - "punpcklwd %[ftmp0], %[ftmp6], %[ftmp10] \n\t" - "punpckhwd %[ftmp1], %[ftmp6], %[ftmp10] \n\t" - MMI_SUBU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gssdlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" - "gssdrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" - MMI_SUBU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gssdlc1 %[ftmp0], 0x07(%[src_ptr]) \n\t" - "gssdrc1 %[ftmp0], 0x00(%[src_ptr]) \n\t" - - "punpcklwd %[ftmp1], %[ftmp5], %[ftmp9] \n\t" - "punpckhwd %[ftmp0], %[ftmp5], %[ftmp9] \n\t" - MMI_SUBU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gssdlc1 %[ftmp0], 0x07(%[src_ptr]) \n\t" - "gssdrc1 %[ftmp0], 0x00(%[src_ptr]) \n\t" - MMI_SUBU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gssdlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" - "gssdrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" - - "punpcklwd %[ftmp1], %[ftmp4], %[ftmp8] \n\t" - "punpckhwd %[ftmp0], %[ftmp4], %[ftmp8] \n\t" - MMI_SUBU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gssdlc1 %[ftmp0], 0x07(%[src_ptr]) \n\t" - "gssdrc1 %[ftmp0], 0x00(%[src_ptr]) \n\t" - MMI_SUBU(%[src_ptr], %[src_ptr], %[src_pixel_step]) - "gssdlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" - "gssdrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" - "addiu %[count], %[count], -0x01 \n\t" - - MMI_SLL(%[tmp0], %[src_pixel_step], 0x03) - MMI_ADDU(%[src_ptr], %[src_ptr], %[tmp0]) - "bnez %[count], 1b \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), - [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), - [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), - [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), - [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), - [ftmp12]"=&f"(ftmp[12]), [ftmp13]"=&f"(ftmp[13]), - [tmp0]"=&r"(tmp[0]), [src_ptr]"+&r"(src_ptr), - [count]"+&r"(count), - [ff_ph_003f]"=&f"(ff_ph_003f), [ff_ph_0900]"=&f"(ff_ph_0900), - [ff_pb_03]"=&f"(ff_pb_03), [ff_pb_04]"=&f"(ff_pb_04), - [ff_pb_80]"=&f"(ff_pb_80), [ff_pb_fe]"=&f"(ff_pb_fe) - : [limit]"r"(limit), [blimit]"r"(blimit), - [srct]"r"(srct), [thresh]"r"(thresh), - [src_pixel_step]"r"((mips_reg)src_pixel_step) - : "memory" - ); - /* clang-format on */ -} - -/* clang-format off */ -#define VP8_SIMPLE_HPSRAB \ - "psllh %[ftmp0], %[ftmp5], %[ftmp8] \n\t" \ - "psrah %[ftmp0], %[ftmp0], %[ftmp9] \n\t" \ - "psrlh %[ftmp0], %[ftmp0], %[ftmp8] \n\t" \ - "psrah %[ftmp1], %[ftmp5], %[ftmp10] \n\t" \ - "psllh %[ftmp1], %[ftmp1], %[ftmp8] \n\t" \ - "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" -/* clang-format on */ - -void vp8_loop_filter_simple_horizontal_edge_mmi(unsigned char *src_ptr, - int src_pixel_step, - const unsigned char *blimit) { - uint64_t tmp[1], count = 2; - mips_reg addr[2]; - double ftmp[12]; - double ff_pb_fe, ff_pb_80, ff_pb_04, ff_pb_01; - - /* clang-format off */ - __asm__ volatile ( - "dli %[tmp0], 0x0b \n\t" - "dmtc1 %[tmp0], %[ftmp10] \n\t" - "dli %[tmp0], 0x01 \n\t" - "dmtc1 %[tmp0], %[ftmp11] \n\t" - "dli %[tmp0], 0x08 \n\t" - "dmtc1 %[tmp0], %[ftmp8] \n\t" - "dli %[tmp0], 0x03 \n\t" - "dmtc1 %[tmp0], %[ftmp9] \n\t" - "dli %[tmp0], 0x0b \n\t" - "dmtc1 %[tmp0], %[ftmp10] \n\t" - "dli %[tmp0], 0x01 \n\t" - "dmtc1 %[tmp0], %[ftmp11] \n\t" - "dli %[tmp0], 0xfefefefefefefefe \n\t" - "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" - "dli %[tmp0], 0x8080808080808080 \n\t" - "dmtc1 %[tmp0], %[ff_pb_80] \n\t" - "dli %[tmp0], 0x0404040404040404 \n\t" - "dmtc1 %[tmp0], %[ff_pb_04] \n\t" - "dli %[tmp0], 0x0101010101010101 \n\t" - "dmtc1 %[tmp0], %[ff_pb_01] \n\t" - - "1: \n\t" - "gsldlc1 %[ftmp3], 0x07(%[blimit]) \n\t" - "gsldrc1 %[ftmp3], 0x00(%[blimit]) \n\t" - - MMI_ADDU(%[addr0], %[src_ptr], %[src_pixel_step]) - - MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step_x2]) - "gsldlc1 %[ftmp2], 0x07(%[addr1]) \n\t" - "gsldrc1 %[ftmp2], 0x00(%[addr1]) \n\t" - "gsldlc1 %[ftmp7], 0x07(%[addr0]) \n\t" - "gsldrc1 %[ftmp7], 0x00(%[addr0]) \n\t" - "pasubub %[ftmp1], %[ftmp7], %[ftmp2] \n\t" - "pand %[ftmp1], %[ftmp1], %[ff_pb_fe] \n\t" - "psrlh %[ftmp1], %[ftmp1], %[ftmp11] \n\t" - - MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) - "gsldlc1 %[ftmp6], 0x07(%[addr1]) \n\t" - "gsldrc1 %[ftmp6], 0x00(%[addr1]) \n\t" - "gsldlc1 %[ftmp0], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp0], 0x00(%[src_ptr]) \n\t" - "pasubub %[ftmp5], %[ftmp6], %[ftmp0] \n\t" - "paddusb %[ftmp5], %[ftmp5], %[ftmp5] \n\t" - "paddusb %[ftmp5], %[ftmp5], %[ftmp1] \n\t" - "psubusb %[ftmp5], %[ftmp5], %[ftmp3] \n\t" - "pxor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" - "pcmpeqb %[ftmp5], %[ftmp5], %[ftmp3] \n\t" - - "pxor %[ftmp2], %[ftmp2], %[ff_pb_80] \n\t" - "pxor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" - "psubsb %[ftmp2], %[ftmp2], %[ftmp7] \n\t" - "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" - "pxor %[ftmp3], %[ftmp0], %[ff_pb_80] \n\t" - "psubsb %[ftmp0], %[ftmp3], %[ftmp6] \n\t" - "paddsb %[ftmp2], %[ftmp2], %[ftmp0] \n\t" - "paddsb %[ftmp2], %[ftmp2], %[ftmp0] \n\t" - "paddsb %[ftmp2], %[ftmp2], %[ftmp0] \n\t" - "pand %[ftmp5], %[ftmp5], %[ftmp2] \n\t" - - "paddsb %[ftmp5], %[ftmp5], %[ff_pb_04] \n\t" - VP8_SIMPLE_HPSRAB - "psubsb %[ftmp3], %[ftmp3], %[ftmp0] \n\t" - "pxor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" - "gssdlc1 %[ftmp3], 0x07(%[src_ptr]) \n\t" - "gssdrc1 %[ftmp3], 0x00(%[src_ptr]) \n\t" - - "psubsb %[ftmp5], %[ftmp5], %[ff_pb_01] \n\t" - VP8_SIMPLE_HPSRAB - "paddsb %[ftmp6], %[ftmp6], %[ftmp0] \n\t" - "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" - MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) - "gssdlc1 %[ftmp6], 0x07(%[addr1]) \n\t" - "gssdrc1 %[ftmp6], 0x00(%[addr1]) \n\t" - - "addiu %[count], %[count], -0x01 \n\t" - MMI_ADDIU(%[src_ptr], %[src_ptr], 0x08) - "bnez %[count], 1b \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), - [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), - [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), - [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), - [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), - [tmp0]"=&r"(tmp[0]), - [addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1]), - [src_ptr]"+&r"(src_ptr), [count]"+&r"(count), - [ff_pb_fe]"=&f"(ff_pb_fe), [ff_pb_80]"=&f"(ff_pb_80), - [ff_pb_04]"=&f"(ff_pb_04), [ff_pb_01]"=&f"(ff_pb_01) - : [blimit]"r"(blimit), - [src_pixel_step]"r"((mips_reg)src_pixel_step), - [src_pixel_step_x2]"r"((mips_reg)(src_pixel_step<<1)) - : "memory" - ); - /* clang-format on */ -} - -void vp8_loop_filter_simple_vertical_edge_mmi(unsigned char *src_ptr, - int src_pixel_step, - const unsigned char *blimit) { - uint64_t tmp[1], count = 2; - mips_reg addr[2]; - DECLARE_ALIGNED(8, const uint64_t, srct[2]); - double ftmp[12], ff_pb_fe, ff_pb_80, ff_pb_04, ff_pb_01; - - /* clang-format off */ - __asm__ volatile ( - "dli %[tmp0], 0x08 \n\t" - "dmtc1 %[tmp0], %[ftmp8] \n\t" - "dli %[tmp0], 0x20 \n\t" - "dmtc1 %[tmp0], %[ftmp10] \n\t" - "dli %[tmp0], 0x08 \n\t" - "dmtc1 %[tmp0], %[ftmp8] \n\t" - "dli %[tmp0], 0x20 \n\t" - "dmtc1 %[tmp0], %[ftmp10] \n\t" - "dli %[tmp0], 0xfefefefefefefefe \n\t" - "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" - "dli %[tmp0], 0x8080808080808080 \n\t" - "dmtc1 %[tmp0], %[ff_pb_80] \n\t" - "dli %[tmp0], 0x0404040404040404 \n\t" - "dmtc1 %[tmp0], %[ff_pb_04] \n\t" - "dli %[tmp0], 0x0101010101010101 \n\t" - "dmtc1 %[tmp0], %[ff_pb_01] \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step_x4]) - MMI_SUBU(%[src_ptr], %[src_ptr], 0x02) - - "1: \n\t" - MMI_ADDU(%[addr0], %[src_ptr], %[src_pixel_step]) - MMI_ADDU(%[addr1], %[addr0], %[src_pixel_step_x2]) - "gslwlc1 %[ftmp0], 0x03(%[addr1]) \n\t" - "gslwrc1 %[ftmp0], 0x00(%[addr1]) \n\t" - MMI_ADDU(%[addr1], %[src_ptr], %[src_pixel_step_x2]) - "gslwlc1 %[ftmp6], 0x03(%[addr1]) \n\t" - "gslwrc1 %[ftmp6], 0x00(%[addr1]) \n\t" - "punpcklbh %[ftmp6], %[ftmp6], %[ftmp0] \n\t" - - MMI_ADDU(%[addr1], %[src_ptr], %[src_pixel_step]) - "gslwlc1 %[ftmp0], 0x03(%[addr1]) \n\t" - "gslwrc1 %[ftmp0], 0x00(%[addr1]) \n\t" - "gslwlc1 %[ftmp4], 0x03(%[src_ptr]) \n\t" - "gslwrc1 %[ftmp4], 0x00(%[src_ptr]) \n\t" - - "punpcklbh %[ftmp4], %[ftmp4], %[ftmp0] \n\t" - "punpckhhw %[ftmp5], %[ftmp4], %[ftmp6] \n\t" - "punpcklhw %[ftmp4], %[ftmp4], %[ftmp6] \n\t" - - MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) - "gslwlc1 %[ftmp7], 0x03(%[addr1]) \n\t" - "gslwrc1 %[ftmp7], 0x00(%[addr1]) \n\t" - MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step_x2]) - "gslwlc1 %[ftmp6], 0x03(%[addr1]) \n\t" - "gslwrc1 %[ftmp6], 0x00(%[addr1]) \n\t" - "punpcklbh %[ftmp6], %[ftmp6], %[ftmp7] \n\t" - - MMI_SUBU(%[addr1], %[addr0], %[src_pixel_step_x4]) - "gslwlc1 %[ftmp1], 0x03(%[addr1]) \n\t" - "gslwrc1 %[ftmp1], 0x00(%[addr1]) \n\t" - MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step_x4]) - "gslwlc1 %[ftmp0], 0x03(%[addr1]) \n\t" - "gslwrc1 %[ftmp0], 0x00(%[addr1]) \n\t" - "punpcklbh %[ftmp0], %[ftmp0], %[ftmp1] \n\t" - - "punpckhhw %[ftmp2], %[ftmp0], %[ftmp6] \n\t" - "punpcklhw %[ftmp0], %[ftmp0], %[ftmp6] \n\t" - "punpckhwd %[ftmp1], %[ftmp0], %[ftmp4] \n\t" - "punpcklwd %[ftmp0], %[ftmp0], %[ftmp4] \n\t" - "punpckhwd %[ftmp3], %[ftmp2], %[ftmp5] \n\t" - "punpcklwd %[ftmp2], %[ftmp2], %[ftmp5] \n\t" - - "dli %[tmp0], 0x01 \n\t" - "dmtc1 %[tmp0], %[ftmp9] \n\t" - "pasubub %[ftmp6], %[ftmp3], %[ftmp0] \n\t" - "pand %[ftmp6], %[ftmp6], %[ff_pb_fe] \n\t" - "psrlh %[ftmp6], %[ftmp6], %[ftmp9] \n\t" - "pasubub %[ftmp5], %[ftmp1], %[ftmp2] \n\t" - "paddusb %[ftmp5], %[ftmp5], %[ftmp5] \n\t" - "paddusb %[ftmp5], %[ftmp5], %[ftmp6] \n\t" - - "gsldlc1 %[ftmp7], 0x07(%[blimit]) \n\t" - "gsldrc1 %[ftmp7], 0x00(%[blimit]) \n\t" - "psubusb %[ftmp5], %[ftmp5], %[ftmp7] \n\t" - "pxor %[ftmp7], %[ftmp7], %[ftmp7] \n\t" - "pcmpeqb %[ftmp5], %[ftmp5], %[ftmp7] \n\t" - - "sdc1 %[ftmp0], 0x00(%[srct]) \n\t" - "sdc1 %[ftmp3], 0x08(%[srct]) \n\t" - - "pxor %[ftmp0], %[ftmp0], %[ff_pb_80] \n\t" - "pxor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" - "psubsb %[ftmp0], %[ftmp0], %[ftmp3] \n\t" - - "pxor %[ftmp6], %[ftmp1], %[ff_pb_80] \n\t" - "pxor %[ftmp3], %[ftmp2], %[ff_pb_80] \n\t" - "psubsb %[ftmp7], %[ftmp3], %[ftmp6] \n\t" - "paddsb %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - "paddsb %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - "paddsb %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - "pand %[ftmp5], %[ftmp5], %[ftmp0] \n\t" - "paddsb %[ftmp5], %[ftmp5], %[ff_pb_04] \n\t" - - "dli %[tmp0], 0x03 \n\t" - "dmtc1 %[tmp0], %[ftmp9] \n\t" - "psllh %[ftmp0], %[ftmp5], %[ftmp8] \n\t" - "psrah %[ftmp0], %[ftmp0], %[ftmp9] \n\t" - "psrlh %[ftmp0], %[ftmp0], %[ftmp8] \n\t" - - "dli %[tmp0], 0x0b \n\t" - "dmtc1 %[tmp0], %[ftmp9] \n\t" - "psrah %[ftmp7], %[ftmp5], %[ftmp9] \n\t" - "psllh %[ftmp7], %[ftmp7], %[ftmp8] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" - "psubsb %[ftmp3], %[ftmp3], %[ftmp0] \n\t" - "pxor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" - "psubsb %[ftmp5], %[ftmp5], %[ff_pb_01] \n\t" - - "dli %[tmp0], 0x03 \n\t" - "dmtc1 %[tmp0], %[ftmp9] \n\t" - "psllh %[ftmp0], %[ftmp5], %[ftmp8] \n\t" - "psrah %[ftmp0], %[ftmp0], %[ftmp9] \n\t" - "psrlh %[ftmp0], %[ftmp0], %[ftmp8] \n\t" - - "dli %[tmp0], 0x0b \n\t" - "dmtc1 %[tmp0], %[ftmp9] \n\t" - "psrah %[ftmp5], %[ftmp5], %[ftmp9] \n\t" - "psllh %[ftmp5], %[ftmp5], %[ftmp8] \n\t" - "por %[ftmp0], %[ftmp0], %[ftmp5] \n\t" - "paddsb %[ftmp6], %[ftmp6], %[ftmp0] \n\t" - "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" - - "ldc1 %[ftmp0], 0x00(%[srct]) \n\t" - "ldc1 %[ftmp4], 0x08(%[srct]) \n\t" - - "punpckhbh %[ftmp1], %[ftmp0], %[ftmp6] \n\t" - "punpcklbh %[ftmp0], %[ftmp0], %[ftmp6] \n\t" - "punpcklbh %[ftmp2], %[ftmp3], %[ftmp4] \n\t" - "punpckhbh %[ftmp3], %[ftmp3], %[ftmp4] \n\t" - - "punpckhhw %[ftmp6], %[ftmp0], %[ftmp2] \n\t" - "punpcklhw %[ftmp0], %[ftmp0], %[ftmp2] \n\t" - - MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step_x4]) - "gsswlc1 %[ftmp0], 0x03(%[addr1]) \n\t" - "gsswrc1 %[ftmp0], 0x00(%[addr1]) \n\t" - "punpckhhw %[ftmp5], %[ftmp1], %[ftmp3] \n\t" - "punpcklhw %[ftmp1], %[ftmp1], %[ftmp3] \n\t" - - "ssrld %[ftmp0], %[ftmp0], %[ftmp10] \n\t" - MMI_SUBU(%[addr1], %[addr0], %[src_pixel_step_x4]) - "gsswlc1 %[ftmp0], 0x03(%[addr1]) \n\t" - "gsswrc1 %[ftmp0], 0x00(%[addr1]) \n\t" - MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step_x2]) - "gsswlc1 %[ftmp6], 0x03(%[addr1]) \n\t" - "gsswrc1 %[ftmp6], 0x00(%[addr1]) \n\t" - - "ssrld %[ftmp6], %[ftmp6], %[ftmp10] \n\t" - "gsswlc1 %[ftmp1], 0x03(%[src_ptr]) \n\t" - "gsswrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" - - MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) - "gsswlc1 %[ftmp6], 0x03(%[addr1]) \n\t" - "gsswrc1 %[ftmp6], 0x00(%[addr1]) \n\t" - - MMI_ADDU(%[addr1], %[src_ptr], %[src_pixel_step_x2]) - "gsswlc1 %[ftmp5], 0x03(%[addr1]) \n\t" - "gsswrc1 %[ftmp5], 0x00(%[addr1]) \n\t" - - "ssrld %[ftmp1], %[ftmp1], %[ftmp10] \n\t" - "gsswlc1 %[ftmp1], 0x03(%[addr0]) \n\t" - "gsswrc1 %[ftmp1], 0x00(%[addr0]) \n\t" - - "ssrld %[ftmp5], %[ftmp5], %[ftmp10] \n\t" - MMI_ADDU(%[addr1], %[addr0], %[src_pixel_step_x2]) - "gsswlc1 %[ftmp5], 0x03(%[addr1]) \n\t" - "gsswrc1 %[ftmp5], 0x00(%[addr1]) \n\t" - - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step_x8]) - "addiu %[count], %[count], -0x01 \n\t" - "bnez %[count], 1b \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), - [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), - [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), - [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), - [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), - [tmp0]"=&r"(tmp[0]), - [addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1]), - [src_ptr]"+&r"(src_ptr), [count]"+&r"(count), - [ff_pb_fe]"=&f"(ff_pb_fe), [ff_pb_80]"=&f"(ff_pb_80), - [ff_pb_04]"=&f"(ff_pb_04), [ff_pb_01]"=&f"(ff_pb_01) - : [blimit]"r"(blimit), [srct]"r"(srct), - [src_pixel_step]"r"((mips_reg)src_pixel_step), - [src_pixel_step_x2]"r"((mips_reg)(src_pixel_step<<1)), - [src_pixel_step_x4]"r"((mips_reg)(src_pixel_step<<2)), - [src_pixel_step_x8]"r"((mips_reg)(src_pixel_step<<3)) - : "memory" - ); - /* clang-format on */ -} - -/* Horizontal MB filtering */ -void vp8_loop_filter_mbh_mmi(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { - vp8_mbloop_filter_horizontal_edge_mmi(y_ptr, y_stride, lfi->mblim, lfi->lim, - lfi->hev_thr, 2); - - if (u_ptr) - vp8_mbloop_filter_horizontal_edge_mmi(u_ptr, uv_stride, lfi->mblim, - lfi->lim, lfi->hev_thr, 1); - - if (v_ptr) - vp8_mbloop_filter_horizontal_edge_mmi(v_ptr, uv_stride, lfi->mblim, - lfi->lim, lfi->hev_thr, 1); -} - -/* Vertical MB Filtering */ -void vp8_loop_filter_mbv_mmi(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { - vp8_mbloop_filter_vertical_edge_mmi(y_ptr, y_stride, lfi->mblim, lfi->lim, - lfi->hev_thr, 2); - - if (u_ptr) - vp8_mbloop_filter_vertical_edge_mmi(u_ptr, uv_stride, lfi->mblim, lfi->lim, - lfi->hev_thr, 1); - - if (v_ptr) - vp8_mbloop_filter_vertical_edge_mmi(v_ptr, uv_stride, lfi->mblim, lfi->lim, - lfi->hev_thr, 1); -} - -/* Horizontal B Filtering */ -void vp8_loop_filter_bh_mmi(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { - vp8_loop_filter_horizontal_edge_mmi(y_ptr + 4 * y_stride, y_stride, lfi->blim, - lfi->lim, lfi->hev_thr, 2); - vp8_loop_filter_horizontal_edge_mmi(y_ptr + 8 * y_stride, y_stride, lfi->blim, - lfi->lim, lfi->hev_thr, 2); - vp8_loop_filter_horizontal_edge_mmi(y_ptr + 12 * y_stride, y_stride, - lfi->blim, lfi->lim, lfi->hev_thr, 2); - - if (u_ptr) - vp8_loop_filter_horizontal_edge_mmi(u_ptr + 4 * uv_stride, uv_stride, - lfi->blim, lfi->lim, lfi->hev_thr, 1); - - if (v_ptr) - vp8_loop_filter_horizontal_edge_mmi(v_ptr + 4 * uv_stride, uv_stride, - lfi->blim, lfi->lim, lfi->hev_thr, 1); -} - -/* Vertical B Filtering */ -void vp8_loop_filter_bv_mmi(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { - vp8_loop_filter_vertical_edge_mmi(y_ptr + 4, y_stride, lfi->blim, lfi->lim, - lfi->hev_thr, 2); - vp8_loop_filter_vertical_edge_mmi(y_ptr + 8, y_stride, lfi->blim, lfi->lim, - lfi->hev_thr, 2); - vp8_loop_filter_vertical_edge_mmi(y_ptr + 12, y_stride, lfi->blim, lfi->lim, - lfi->hev_thr, 2); - - if (u_ptr) - vp8_loop_filter_vertical_edge_mmi(u_ptr + 4, uv_stride, lfi->blim, lfi->lim, - lfi->hev_thr, 1); - - if (v_ptr) - vp8_loop_filter_vertical_edge_mmi(v_ptr + 4, uv_stride, lfi->blim, lfi->lim, - lfi->hev_thr, 1); -} - -void vp8_loop_filter_bhs_mmi(unsigned char *y_ptr, int y_stride, - const unsigned char *blimit) { - vp8_loop_filter_simple_horizontal_edge_mmi(y_ptr + 4 * y_stride, y_stride, - blimit); - vp8_loop_filter_simple_horizontal_edge_mmi(y_ptr + 8 * y_stride, y_stride, - blimit); - vp8_loop_filter_simple_horizontal_edge_mmi(y_ptr + 12 * y_stride, y_stride, - blimit); -} - -void vp8_loop_filter_bvs_mmi(unsigned char *y_ptr, int y_stride, - const unsigned char *blimit) { - vp8_loop_filter_simple_vertical_edge_mmi(y_ptr + 4, y_stride, blimit); - vp8_loop_filter_simple_vertical_edge_mmi(y_ptr + 8, y_stride, blimit); - vp8_loop_filter_simple_vertical_edge_mmi(y_ptr + 12, y_stride, blimit); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/sixtap_filter_mmi.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/sixtap_filter_mmi.c deleted file mode 100644 index b85f73fd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/mmi/sixtap_filter_mmi.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp8/common/filter.h" -#include "vpx_ports/asmdefs_mmi.h" - -DECLARE_ALIGNED(8, static const int16_t, vp8_six_tap_mmi[8][6 * 8]) = { - { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, - { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xfffa, 0xfffa, 0xfffa, 0xfffa, 0xfffa, 0xfffa, 0xfffa, 0xfffa, - 0x007b, 0x007b, 0x007b, 0x007b, 0x007b, 0x007b, 0x007b, 0x007b, - 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, - { 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, - 0xfff5, 0xfff5, 0xfff5, 0xfff5, 0xfff5, 0xfff5, 0xfff5, 0xfff5, - 0x006c, 0x006c, 0x006c, 0x006c, 0x006c, 0x006c, 0x006c, 0x006c, - 0x0024, 0x0024, 0x0024, 0x0024, 0x0024, 0x0024, 0x0024, 0x0024, - 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, - 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001 }, - { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xfff7, 0xfff7, 0xfff7, 0xfff7, 0xfff7, 0xfff7, 0xfff7, 0xfff7, - 0x005d, 0x005d, 0x005d, 0x005d, 0x005d, 0x005d, 0x005d, 0x005d, - 0x0032, 0x0032, 0x0032, 0x0032, 0x0032, 0x0032, 0x0032, 0x0032, - 0xfffa, 0xfffa, 0xfffa, 0xfffa, 0xfffa, 0xfffa, 0xfffa, 0xfffa, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, - { 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, - 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, - 0x004d, 0x004d, 0x004d, 0x004d, 0x004d, 0x004d, 0x004d, 0x004d, - 0x004d, 0x004d, 0x004d, 0x004d, 0x004d, 0x004d, 0x004d, 0x004d, - 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, 0xfff0, - 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003 }, - { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xfffa, 0xfffa, 0xfffa, 0xfffa, 0xfffa, 0xfffa, 0xfffa, 0xfffa, - 0x0032, 0x0032, 0x0032, 0x0032, 0x0032, 0x0032, 0x0032, 0x0032, - 0x005d, 0x005d, 0x005d, 0x005d, 0x005d, 0x005d, 0x005d, 0x005d, - 0xfff7, 0xfff7, 0xfff7, 0xfff7, 0xfff7, 0xfff7, 0xfff7, 0xfff7, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, - { 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, - 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, 0xfff8, - 0x0024, 0x0024, 0x0024, 0x0024, 0x0024, 0x0024, 0x0024, 0x0024, - 0x006c, 0x006c, 0x006c, 0x006c, 0x006c, 0x006c, 0x006c, 0x006c, - 0xfff5, 0xfff5, 0xfff5, 0xfff5, 0xfff5, 0xfff5, 0xfff5, 0xfff5, - 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002 }, - { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, - 0x007b, 0x007b, 0x007b, 0x007b, 0x007b, 0x007b, 0x007b, 0x007b, - 0xfffa, 0xfffa, 0xfffa, 0xfffa, 0xfffa, 0xfffa, 0xfffa, 0xfffa, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 } -}; - -/* Horizontal filter: pixel_step is 1, output_height and output_width are - the size of horizontal filtering output, output_height is always H + 5 */ -static INLINE void vp8_filter_block1d_h6_mmi(unsigned char *src_ptr, - uint16_t *output_ptr, - unsigned int src_pixels_per_line, - unsigned int output_height, - unsigned int output_width, - const int16_t *vp8_filter) { - uint64_t tmp[1]; - double ff_ph_40; -#if _MIPS_SIM == _ABIO32 - register double fzero asm("$f0"); - register double ftmp0 asm("$f2"); - register double ftmp1 asm("$f4"); - register double ftmp2 asm("$f6"); - register double ftmp3 asm("$f8"); - register double ftmp4 asm("$f10"); - register double ftmp5 asm("$f12"); - register double ftmp6 asm("$f14"); - register double ftmp7 asm("$f16"); - register double ftmp8 asm("$f18"); - register double ftmp9 asm("$f20"); - register double ftmp10 asm("$f22"); - register double ftmp11 asm("$f24"); -#else - register double fzero asm("$f0"); - register double ftmp0 asm("$f1"); - register double ftmp1 asm("$f2"); - register double ftmp2 asm("$f3"); - register double ftmp3 asm("$f4"); - register double ftmp4 asm("$f5"); - register double ftmp5 asm("$f6"); - register double ftmp6 asm("$f7"); - register double ftmp7 asm("$f8"); - register double ftmp8 asm("$f9"); - register double ftmp9 asm("$f10"); - register double ftmp10 asm("$f11"); - register double ftmp11 asm("$f12"); -#endif // _MIPS_SIM == _ABIO32 - - /* clang-format off */ - __asm__ volatile ( - "dli %[tmp0], 0x0040004000400040 \n\t" - "dmtc1 %[tmp0], %[ff_ph_40] \n\t" - "ldc1 %[ftmp0], 0x00(%[vp8_filter]) \n\t" - "ldc1 %[ftmp1], 0x10(%[vp8_filter]) \n\t" - "ldc1 %[ftmp2], 0x20(%[vp8_filter]) \n\t" - "ldc1 %[ftmp3], 0x30(%[vp8_filter]) \n\t" - "ldc1 %[ftmp4], 0x40(%[vp8_filter]) \n\t" - "ldc1 %[ftmp5], 0x50(%[vp8_filter]) \n\t" - "pxor %[fzero], %[fzero], %[fzero] \n\t" - "dli %[tmp0], 0x07 \n\t" - "dmtc1 %[tmp0], %[ftmp7] \n\t" - "dli %[tmp0], 0x08 \n\t" - "dmtc1 %[tmp0], %[ftmp11] \n\t" - - "1: \n\t" - "gsldlc1 %[ftmp9], 0x05(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp9], -0x02(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp10], 0x06(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp10], -0x01(%[src_ptr]) \n\t" - - "punpcklbh %[ftmp6], %[ftmp9], %[fzero] \n\t" - "pmullh %[ftmp8], %[ftmp6], %[ftmp0] \n\t" - - "punpckhbh %[ftmp6], %[ftmp9], %[fzero] \n\t" - "pmullh %[ftmp6], %[ftmp6], %[ftmp4] \n\t" - "paddsh %[ftmp8], %[ftmp8], %[ftmp6] \n\t" - - "punpcklbh %[ftmp6], %[ftmp10], %[fzero] \n\t" - "pmullh %[ftmp6], %[ftmp6], %[ftmp1] \n\t" - "paddsh %[ftmp8], %[ftmp8], %[ftmp6] \n\t" - - "punpckhbh %[ftmp6], %[ftmp10], %[fzero] \n\t" - "pmullh %[ftmp6], %[ftmp6], %[ftmp5] \n\t" - "paddsh %[ftmp8], %[ftmp8], %[ftmp6] \n\t" - - "ssrld %[ftmp10], %[ftmp10], %[ftmp11] \n\t" - "punpcklbh %[ftmp6], %[ftmp10], %[fzero] \n\t" - "pmullh %[ftmp6], %[ftmp6], %[ftmp2] \n\t" - "paddsh %[ftmp8], %[ftmp8], %[ftmp6] \n\t" - - "ssrld %[ftmp10], %[ftmp10], %[ftmp11] \n\t" - "punpcklbh %[ftmp6], %[ftmp10], %[fzero] \n\t" - "pmullh %[ftmp6], %[ftmp6], %[ftmp3] \n\t" - "paddsh %[ftmp8], %[ftmp8], %[ftmp6] \n\t" - - "paddsh %[ftmp8], %[ftmp8], %[ff_ph_40] \n\t" - "psrah %[ftmp8], %[ftmp8], %[ftmp7] \n\t" - "packushb %[ftmp8], %[ftmp8], %[fzero] \n\t" - "punpcklbh %[ftmp8], %[ftmp8], %[fzero] \n\t" - "gssdlc1 %[ftmp8], 0x07(%[output_ptr]) \n\t" - "gssdrc1 %[ftmp8], 0x00(%[output_ptr]) \n\t" - - "addiu %[output_height], %[output_height], -0x01 \n\t" - MMI_ADDU(%[output_ptr], %[output_ptr], %[output_width]) - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixels_per_line]) - "bnez %[output_height], 1b \n\t" - : [fzero]"=&f"(fzero), [ftmp0]"=&f"(ftmp0), - [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), - [ftmp3]"=&f"(ftmp3), [ftmp4]"=&f"(ftmp4), - [ftmp5]"=&f"(ftmp5), [ftmp6]"=&f"(ftmp6), - [ftmp7]"=&f"(ftmp7), [ftmp8]"=&f"(ftmp8), - [ftmp9]"=&f"(ftmp9), [ftmp10]"=&f"(ftmp10), - [ftmp11]"=&f"(ftmp11), [tmp0]"=&r"(tmp[0]), - [output_ptr]"+&r"(output_ptr), [output_height]"+&r"(output_height), - [src_ptr]"+&r"(src_ptr), [ff_ph_40]"=&f"(ff_ph_40) - : [src_pixels_per_line]"r"((mips_reg)src_pixels_per_line), - [vp8_filter]"r"(vp8_filter), [output_width]"r"(output_width) - : "memory" - ); - /* clang-format on */ -} - -/* Horizontal filter: pixel_step is always W */ -static INLINE void vp8_filter_block1dc_v6_mmi( - uint16_t *src_ptr, unsigned char *output_ptr, unsigned int output_height, - int output_pitch, unsigned int pixels_per_line, const int16_t *vp8_filter) { - double ff_ph_40; - uint64_t tmp[1]; - mips_reg addr[1]; - -#if _MIPS_SIM == _ABIO32 - register double fzero asm("$f0"); - register double ftmp0 asm("$f2"); - register double ftmp1 asm("$f4"); - register double ftmp2 asm("$f6"); - register double ftmp3 asm("$f8"); - register double ftmp4 asm("$f10"); - register double ftmp5 asm("$f12"); - register double ftmp6 asm("$f14"); - register double ftmp7 asm("$f16"); - register double ftmp8 asm("$f18"); - register double ftmp9 asm("$f20"); - register double ftmp10 asm("$f22"); - register double ftmp11 asm("$f24"); - register double ftmp12 asm("$f26"); - register double ftmp13 asm("$f28"); -#else - register double fzero asm("$f0"); - register double ftmp0 asm("$f1"); - register double ftmp1 asm("$f2"); - register double ftmp2 asm("$f3"); - register double ftmp3 asm("$f4"); - register double ftmp4 asm("$f5"); - register double ftmp5 asm("$f6"); - register double ftmp6 asm("$f7"); - register double ftmp7 asm("$f8"); - register double ftmp8 asm("$f9"); - register double ftmp9 asm("$f10"); - register double ftmp10 asm("$f11"); - register double ftmp11 asm("$f12"); - register double ftmp12 asm("$f13"); - register double ftmp13 asm("$f14"); -#endif // _MIPS_SIM == _ABIO32 - - /* clang-format off */ - __asm__ volatile ( - "dli %[tmp0], 0x0040004000400040 \n\t" - "dmtc1 %[tmp0], %[ff_ph_40] \n\t" - "ldc1 %[ftmp0], 0x00(%[vp8_filter]) \n\t" - "ldc1 %[ftmp1], 0x10(%[vp8_filter]) \n\t" - "ldc1 %[ftmp2], 0x20(%[vp8_filter]) \n\t" - "ldc1 %[ftmp3], 0x30(%[vp8_filter]) \n\t" - "ldc1 %[ftmp4], 0x40(%[vp8_filter]) \n\t" - "ldc1 %[ftmp5], 0x50(%[vp8_filter]) \n\t" - "pxor %[fzero], %[fzero], %[fzero] \n\t" - "dli %[tmp0], 0x07 \n\t" - "dmtc1 %[tmp0], %[ftmp13] \n\t" - - /* In order to make full use of memory load delay slot, - * Operation of memory loading and calculating has been rearranged. - */ - "1: \n\t" - "gsldlc1 %[ftmp6], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp6], 0x00(%[src_ptr]) \n\t" - MMI_ADDU(%[addr0], %[src_ptr], %[pixels_per_line]) - "gsldlc1 %[ftmp7], 0x07(%[addr0]) \n\t" - "gsldrc1 %[ftmp7], 0x00(%[addr0]) \n\t" - MMI_ADDU(%[addr0], %[src_ptr], %[pixels_per_line_x2]) - "gsldlc1 %[ftmp8], 0x07(%[addr0]) \n\t" - "gsldrc1 %[ftmp8], 0x00(%[addr0]) \n\t" - - MMI_ADDU(%[addr0], %[src_ptr], %[pixels_per_line_x4]) - "gsldlc1 %[ftmp9], 0x07(%[addr0]) \n\t" - "gsldrc1 %[ftmp9], 0x00(%[addr0]) \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[pixels_per_line]) - MMI_ADDU(%[addr0], %[src_ptr], %[pixels_per_line_x2]) - "gsldlc1 %[ftmp10], 0x07(%[addr0]) \n\t" - "gsldrc1 %[ftmp10], 0x00(%[addr0]) \n\t" - MMI_ADDU(%[addr0], %[src_ptr], %[pixels_per_line_x4]) - "gsldlc1 %[ftmp11], 0x07(%[addr0]) \n\t" - "gsldrc1 %[ftmp11], 0x00(%[addr0]) \n\t" - - "pmullh %[ftmp12], %[ftmp6], %[ftmp0] \n\t" - - "pmullh %[ftmp7], %[ftmp7], %[ftmp1] \n\t" - "paddsh %[ftmp12], %[ftmp12], %[ftmp7] \n\t" - - "pmullh %[ftmp8], %[ftmp8], %[ftmp2] \n\t" - "paddsh %[ftmp12], %[ftmp12], %[ftmp8] \n\t" - - "pmullh %[ftmp9], %[ftmp9], %[ftmp4] \n\t" - "paddsh %[ftmp12], %[ftmp12], %[ftmp9] \n\t" - - "pmullh %[ftmp10], %[ftmp10], %[ftmp3] \n\t" - "paddsh %[ftmp12], %[ftmp12], %[ftmp10] \n\t" - - "pmullh %[ftmp11], %[ftmp11], %[ftmp5] \n\t" - "paddsh %[ftmp12], %[ftmp12], %[ftmp11] \n\t" - - "paddsh %[ftmp12], %[ftmp12], %[ff_ph_40] \n\t" - "psrah %[ftmp12], %[ftmp12], %[ftmp13] \n\t" - "packushb %[ftmp12], %[ftmp12], %[fzero] \n\t" - "gsswlc1 %[ftmp12], 0x03(%[output_ptr]) \n\t" - "gsswrc1 %[ftmp12], 0x00(%[output_ptr]) \n\t" - - MMI_ADDIU(%[output_height], %[output_height], -0x01) - MMI_ADDU(%[output_ptr], %[output_ptr], %[output_pitch]) - "bnez %[output_height], 1b \n\t" - : [fzero]"=&f"(fzero), [ftmp0]"=&f"(ftmp0), - [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), - [ftmp3]"=&f"(ftmp3), [ftmp4]"=&f"(ftmp4), - [ftmp5]"=&f"(ftmp5), [ftmp6]"=&f"(ftmp6), - [ftmp7]"=&f"(ftmp7), [ftmp8]"=&f"(ftmp8), - [ftmp9]"=&f"(ftmp9), [ftmp10]"=&f"(ftmp10), - [ftmp11]"=&f"(ftmp11), [ftmp12]"=&f"(ftmp12), - [ftmp13]"=&f"(ftmp13), [tmp0]"=&r"(tmp[0]), - [addr0]"=&r"(addr[0]), [src_ptr]"+&r"(src_ptr), - [output_ptr]"+&r"(output_ptr), [output_height]"+&r"(output_height), - [ff_ph_40]"=&f"(ff_ph_40) - : [pixels_per_line]"r"((mips_reg)pixels_per_line), - [pixels_per_line_x2]"r"((mips_reg)(pixels_per_line<<1)), - [pixels_per_line_x4]"r"((mips_reg)(pixels_per_line<<2)), - [vp8_filter]"r"(vp8_filter), - [output_pitch]"r"((mips_reg)output_pitch) - : "memory" - ); - /* clang-format on */ -} - -/* When xoffset == 0, vp8_filter= {0,0,128,0,0,0}, - function vp8_filter_block1d_h6_mmi and vp8_filter_block1d_v6_mmi can - be simplified */ -static INLINE void vp8_filter_block1d_h6_filter0_mmi( - unsigned char *src_ptr, uint16_t *output_ptr, - unsigned int src_pixels_per_line, unsigned int output_height, - unsigned int output_width) { -#if _MIPS_SIM == _ABIO32 - register double fzero asm("$f0"); - register double ftmp0 asm("$f2"); - register double ftmp1 asm("$f4"); -#else - register double fzero asm("$f0"); - register double ftmp0 asm("$f1"); - register double ftmp1 asm("$f2"); -#endif // _MIPS_SIM == _ABIO32 - - /* clang-format off */ - __asm__ volatile ( - "pxor %[fzero], %[fzero], %[fzero] \n\t" - - "1: \n\t" - "gsldlc1 %[ftmp0], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp0], 0x00(%[src_ptr]) \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixels_per_line]) - - "punpcklbh %[ftmp1], %[ftmp0], %[fzero] \n\t" - "gssdlc1 %[ftmp1], 0x07(%[output_ptr]) \n\t" - "gssdrc1 %[ftmp1], 0x00(%[output_ptr]) \n\t" - - "addiu %[output_height], %[output_height], -0x01 \n\t" - MMI_ADDU(%[output_ptr], %[output_ptr], %[output_width]) - "bnez %[output_height], 1b \n\t" - : [fzero]"=&f"(fzero), [ftmp0]"=&f"(ftmp0), - [ftmp1]"=&f"(ftmp1), [src_ptr]"+&r"(src_ptr), - [output_ptr]"+&r"(output_ptr), [output_height]"+&r"(output_height) - : [src_pixels_per_line]"r"((mips_reg)src_pixels_per_line), - [output_width]"r"(output_width) - : "memory" - ); - /* clang-format on */ -} - -static INLINE void vp8_filter_block1dc_v6_filter0_mmi( - uint16_t *src_ptr, unsigned char *output_ptr, unsigned int output_height, - int output_pitch, unsigned int pixels_per_line) { -#if _MIPS_SIM == _ABIO32 - register double fzero asm("$f0"); - register double ftmp0 asm("$f2"); - register double ftmp1 asm("$f4"); -#else - register double fzero asm("$f0"); - register double ftmp0 asm("$f1"); - register double ftmp1 asm("$f2"); -#endif // _MIPS_SIM == _ABIO32 - - /* clang-format on */ - __asm__ volatile ( - "pxor %[fzero], %[fzero], %[fzero] \n\t" - - "1: \n\t" - "gsldlc1 %[ftmp0], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp0], 0x00(%[src_ptr]) \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[pixels_per_line]) - MMI_ADDIU(%[output_height], %[output_height], -0x01) - "packushb %[ftmp1], %[ftmp0], %[fzero] \n\t" - "gsswlc1 %[ftmp1], 0x03(%[output_ptr]) \n\t" - "gsswrc1 %[ftmp1], 0x00(%[output_ptr]) \n\t" - - MMI_ADDU(%[output_ptr], %[output_ptr], %[output_pitch]) - "bnez %[output_height], 1b \n\t" - : [fzero]"=&f"(fzero), [ftmp0]"=&f"(ftmp0), - [ftmp1]"=&f"(ftmp1), [src_ptr]"+&r"(src_ptr), - [output_ptr]"+&r"(output_ptr), [output_height]"+&r"(output_height) - : [pixels_per_line]"r"((mips_reg)pixels_per_line), - [output_pitch]"r"((mips_reg)output_pitch) - : "memory" - ); - /* clang-format on */ -} - -#define sixtapNxM(n, m) \ - void vp8_sixtap_predict##n##x##m##_mmi( \ - unsigned char *src_ptr, int src_pixels_per_line, int xoffset, \ - int yoffset, unsigned char *dst_ptr, int dst_pitch) { \ - DECLARE_ALIGNED(16, uint16_t, \ - FData2[(n + 5) * (n == 16 ? 24 : (n == 8 ? 16 : n))]); \ - const int16_t *HFilter, *VFilter; \ - int i, loop = n / 4; \ - HFilter = vp8_six_tap_mmi[xoffset]; \ - VFilter = vp8_six_tap_mmi[yoffset]; \ - \ - if (xoffset == 0) { \ - for (i = 0; i < loop; ++i) { \ - vp8_filter_block1d_h6_filter0_mmi( \ - src_ptr - (2 * src_pixels_per_line) + i * 4, FData2 + i * 4, \ - src_pixels_per_line, m + 5, n * 2); \ - } \ - } else { \ - for (i = 0; i < loop; ++i) { \ - vp8_filter_block1d_h6_mmi(src_ptr - (2 * src_pixels_per_line) + i * 4, \ - FData2 + i * 4, src_pixels_per_line, m + 5, \ - n * 2, HFilter); \ - } \ - } \ - if (yoffset == 0) { \ - for (i = 0; i < loop; ++i) { \ - vp8_filter_block1dc_v6_filter0_mmi( \ - FData2 + n * 2 + i * 4, dst_ptr + i * 4, m, dst_pitch, n * 2); \ - } \ - } else { \ - for (i = 0; i < loop; ++i) { \ - vp8_filter_block1dc_v6_mmi(FData2 + i * 4, dst_ptr + i * 4, m, \ - dst_pitch, n * 2, VFilter); \ - } \ - } \ - } - -sixtapNxM(4, 4); -sixtapNxM(8, 8); -sixtapNxM(8, 4); -sixtapNxM(16, 16); diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/bilinear_filter_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/bilinear_filter_msa.c deleted file mode 100644 index c7fb1ed3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/bilinear_filter_msa.c +++ /dev/null @@ -1,797 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vpx_ports/mem.h" -#include "vp8/common/filter.h" -#include "vp8/common/mips/msa/vp8_macros_msa.h" - -DECLARE_ALIGNED(16, static const int8_t, vp8_bilinear_filters_msa[7][2]) = { - { 112, 16 }, { 96, 32 }, { 80, 48 }, { 64, 64 }, - { 48, 80 }, { 32, 96 }, { 16, 112 } -}; - -static const uint8_t vp8_mc_filt_mask_arr[16 * 3] = { - /* 8 width cases */ - 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, - /* 4 width cases */ - 0, 1, 1, 2, 2, 3, 3, 4, 16, 17, 17, 18, 18, 19, 19, 20, - /* 4 width cases */ - 8, 9, 9, 10, 10, 11, 11, 12, 24, 25, 25, 26, 26, 27, 27, 28 -}; - -static void common_hz_2t_4x4_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter) { - v16i8 src0, src1, src2, src3, mask; - v16u8 filt0, vec0, vec1, res0, res1; - v8u16 vec2, vec3, filt; - - mask = LD_SB(&vp8_mc_filt_mask_arr[16]); - - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB4(src, src_stride, src0, src1, src2, src3); - VSHF_B2_UB(src0, src1, src2, src3, mask, mask, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt0, filt0, vec2, vec3); - SRARI_H2_UH(vec2, vec3, VP8_FILTER_SHIFT); - PCKEV_B2_UB(vec2, vec2, vec3, vec3, res0, res1); - ST4x4_UB(res0, res1, 0, 1, 0, 1, dst, dst_stride); -} - -static void common_hz_2t_4x8_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter) { - v16u8 vec0, vec1, vec2, vec3, filt0; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask; - v16i8 res0, res1, res2, res3; - v8u16 vec4, vec5, vec6, vec7, filt; - - mask = LD_SB(&vp8_mc_filt_mask_arr[16]); - - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - VSHF_B2_UB(src0, src1, src2, src3, mask, mask, vec0, vec1); - VSHF_B2_UB(src4, src5, src6, src7, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec4, vec5, - vec6, vec7); - SRARI_H4_UH(vec4, vec5, vec6, vec7, VP8_FILTER_SHIFT); - PCKEV_B4_SB(vec4, vec4, vec5, vec5, vec6, vec6, vec7, vec7, res0, res1, res2, - res3); - ST4x4_UB(res0, res1, 0, 1, 0, 1, dst, dst_stride); - dst += (4 * dst_stride); - ST4x4_UB(res2, res3, 0, 1, 0, 1, dst, dst_stride); -} - -static void common_hz_2t_4w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - if (4 == height) { - common_hz_2t_4x4_msa(src, src_stride, dst, dst_stride, filter); - } else if (8 == height) { - common_hz_2t_4x8_msa(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_hz_2t_8x4_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter) { - v16u8 filt0; - v16i8 src0, src1, src2, src3, mask; - v8u16 vec0, vec1, vec2, vec3, filt; - - mask = LD_SB(&vp8_mc_filt_mask_arr[0]); - - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB4(src, src_stride, src0, src1, src2, src3); - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, VP8_FILTER_SHIFT); - PCKEV_B2_SB(vec1, vec0, vec3, vec2, src0, src1); - ST8x4_UB(src0, src1, dst, dst_stride); -} - -static void common_hz_2t_8x8mult_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - v16u8 filt0; - v16i8 src0, src1, src2, src3, mask, out0, out1; - v8u16 vec0, vec1, vec2, vec3, filt; - - mask = LD_SB(&vp8_mc_filt_mask_arr[0]); - - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, VP8_FILTER_SHIFT); - - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - PCKEV_B2_SB(vec1, vec0, vec3, vec2, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += (4 * dst_stride); - - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, VP8_FILTER_SHIFT); - PCKEV_B2_SB(vec1, vec0, vec3, vec2, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += (4 * dst_stride); - - if (16 == height) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, VP8_FILTER_SHIFT); - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - PCKEV_B2_SB(vec1, vec0, vec3, vec2, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); - - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, VP8_FILTER_SHIFT); - PCKEV_B2_SB(vec1, vec0, vec3, vec2, out0, out1); - ST8x4_UB(out0, out1, dst + 4 * dst_stride, dst_stride); - } -} - -static void common_hz_2t_8w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - if (4 == height) { - common_hz_2t_8x4_msa(src, src_stride, dst, dst_stride, filter); - } else { - common_hz_2t_8x8mult_msa(src, src_stride, dst, dst_stride, filter, height); - } -} - -static void common_hz_2t_16w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask; - v16u8 filt0, vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8u16 out0, out1, out2, out3, out4, out5, out6, out7, filt; - - mask = LD_SB(&vp8_mc_filt_mask_arr[0]); - - loop_cnt = (height >> 2) - 1; - - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB4(src, src_stride, src0, src2, src4, src6); - LD_SB4(src + 8, src_stride, src1, src3, src5, src7); - src += (4 * src_stride); - - VSHF_B2_UB(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UB(src2, src2, src3, src3, mask, mask, vec2, vec3); - VSHF_B2_UB(src4, src4, src5, src5, mask, mask, vec4, vec5); - VSHF_B2_UB(src6, src6, src7, src7, mask, mask, vec6, vec7); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, out0, out1, - out2, out3); - DOTP_UB4_UH(vec4, vec5, vec6, vec7, filt0, filt0, filt0, filt0, out4, out5, - out6, out7); - SRARI_H4_UH(out0, out1, out2, out3, VP8_FILTER_SHIFT); - SRARI_H4_UH(out4, out5, out6, out7, VP8_FILTER_SHIFT); - PCKEV_ST_SB(out0, out1, dst); - dst += dst_stride; - PCKEV_ST_SB(out2, out3, dst); - dst += dst_stride; - PCKEV_ST_SB(out4, out5, dst); - dst += dst_stride; - PCKEV_ST_SB(out6, out7, dst); - dst += dst_stride; - - for (; loop_cnt--;) { - LD_SB4(src, src_stride, src0, src2, src4, src6); - LD_SB4(src + 8, src_stride, src1, src3, src5, src7); - src += (4 * src_stride); - - VSHF_B2_UB(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UB(src2, src2, src3, src3, mask, mask, vec2, vec3); - VSHF_B2_UB(src4, src4, src5, src5, mask, mask, vec4, vec5); - VSHF_B2_UB(src6, src6, src7, src7, mask, mask, vec6, vec7); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, out0, out1, - out2, out3); - DOTP_UB4_UH(vec4, vec5, vec6, vec7, filt0, filt0, filt0, filt0, out4, out5, - out6, out7); - SRARI_H4_UH(out0, out1, out2, out3, VP8_FILTER_SHIFT); - SRARI_H4_UH(out4, out5, out6, out7, VP8_FILTER_SHIFT); - PCKEV_ST_SB(out0, out1, dst); - dst += dst_stride; - PCKEV_ST_SB(out2, out3, dst); - dst += dst_stride; - PCKEV_ST_SB(out4, out5, dst); - dst += dst_stride; - PCKEV_ST_SB(out6, out7, dst); - dst += dst_stride; - } -} - -static void common_vt_2t_4x4_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter) { - v16i8 src0, src1, src2, src3, src4; - v16i8 src10_r, src32_r, src21_r, src43_r, src2110, src4332; - v16u8 filt0; - v8i16 filt; - v8u16 tmp0, tmp1; - - filt = LD_SH(filter); - filt0 = (v16u8)__msa_splati_h(filt, 0); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - - ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, - src32_r, src43_r); - ILVR_D2_SB(src21_r, src10_r, src43_r, src32_r, src2110, src4332); - DOTP_UB2_UH(src2110, src4332, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, VP8_FILTER_SHIFT); - src2110 = __msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - ST4x4_UB(src2110, src2110, 0, 1, 2, 3, dst, dst_stride); -} - -static void common_vt_2t_4x8_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter) { - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r; - v16i8 src65_r, src87_r, src2110, src4332, src6554, src8776; - v8u16 tmp0, tmp1, tmp2, tmp3; - v16u8 filt0; - v8i16 filt; - - filt = LD_SH(filter); - filt0 = (v16u8)__msa_splati_h(filt, 0); - - LD_SB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - - src8 = LD_SB(src); - src += src_stride; - - ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, - src32_r, src43_r); - ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_r, src65_r, - src76_r, src87_r); - ILVR_D4_SB(src21_r, src10_r, src43_r, src32_r, src65_r, src54_r, src87_r, - src76_r, src2110, src4332, src6554, src8776); - DOTP_UB4_UH(src2110, src4332, src6554, src8776, filt0, filt0, filt0, filt0, - tmp0, tmp1, tmp2, tmp3); - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, VP8_FILTER_SHIFT); - PCKEV_B2_SB(tmp1, tmp0, tmp3, tmp2, src2110, src4332); - ST4x4_UB(src2110, src2110, 0, 1, 2, 3, dst, dst_stride); - ST4x4_UB(src4332, src4332, 0, 1, 2, 3, dst + 4 * dst_stride, dst_stride); -} - -static void common_vt_2t_4w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - if (4 == height) { - common_vt_2t_4x4_msa(src, src_stride, dst, dst_stride, filter); - } else if (8 == height) { - common_vt_2t_4x8_msa(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_vt_2t_8x4_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter) { - v16u8 src0, src1, src2, src3, src4, vec0, vec1, vec2, vec3, filt0; - v16i8 out0, out1; - v8u16 tmp0, tmp1, tmp2, tmp3; - v8i16 filt; - - filt = LD_SH(filter); - filt0 = (v16u8)__msa_splati_h(filt, 0); - - LD_UB5(src, src_stride, src0, src1, src2, src3, src4); - ILVR_B2_UB(src1, src0, src2, src1, vec0, vec1); - ILVR_B2_UB(src3, src2, src4, src3, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, tmp0, tmp1, - tmp2, tmp3); - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, VP8_FILTER_SHIFT); - PCKEV_B2_SB(tmp1, tmp0, tmp3, tmp2, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); -} - -static void common_vt_2t_8x8mult_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, filt0; - v16i8 out0, out1; - v8u16 tmp0, tmp1, tmp2, tmp3; - v8i16 filt; - - filt = LD_SH(filter); - filt0 = (v16u8)__msa_splati_h(filt, 0); - - src0 = LD_UB(src); - src += src_stride; - - for (loop_cnt = (height >> 3); loop_cnt--;) { - LD_UB8(src, src_stride, src1, src2, src3, src4, src5, src6, src7, src8); - src += (8 * src_stride); - - ILVR_B4_UB(src1, src0, src2, src1, src3, src2, src4, src3, vec0, vec1, vec2, - vec3); - ILVR_B4_UB(src5, src4, src6, src5, src7, src6, src8, src7, vec4, vec5, vec6, - vec7); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, tmp0, tmp1, - tmp2, tmp3); - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, VP8_FILTER_SHIFT); - PCKEV_B2_SB(tmp1, tmp0, tmp3, tmp2, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += (4 * dst_stride); - - DOTP_UB4_UH(vec4, vec5, vec6, vec7, filt0, filt0, filt0, filt0, tmp0, tmp1, - tmp2, tmp3); - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, VP8_FILTER_SHIFT); - PCKEV_B2_SB(tmp1, tmp0, tmp3, tmp2, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += (4 * dst_stride); - - src0 = src8; - } -} - -static void common_vt_2t_8w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - if (4 == height) { - common_vt_2t_8x4_msa(src, src_stride, dst, dst_stride, filter); - } else { - common_vt_2t_8x8mult_msa(src, src_stride, dst, dst_stride, filter, height); - } -} - -static void common_vt_2t_16w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16u8 src0, src1, src2, src3, src4; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, filt0; - v8u16 tmp0, tmp1, tmp2, tmp3; - v8i16 filt; - - filt = LD_SH(filter); - filt0 = (v16u8)__msa_splati_h(filt, 0); - - src0 = LD_UB(src); - src += src_stride; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - - ILVR_B2_UB(src1, src0, src2, src1, vec0, vec2); - ILVL_B2_UB(src1, src0, src2, src1, vec1, vec3); - DOTP_UB2_UH(vec0, vec1, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, VP8_FILTER_SHIFT); - PCKEV_ST_SB(tmp0, tmp1, dst); - dst += dst_stride; - - ILVR_B2_UB(src3, src2, src4, src3, vec4, vec6); - ILVL_B2_UB(src3, src2, src4, src3, vec5, vec7); - DOTP_UB2_UH(vec2, vec3, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, VP8_FILTER_SHIFT); - PCKEV_ST_SB(tmp2, tmp3, dst); - dst += dst_stride; - - DOTP_UB2_UH(vec4, vec5, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, VP8_FILTER_SHIFT); - PCKEV_ST_SB(tmp0, tmp1, dst); - dst += dst_stride; - - DOTP_UB2_UH(vec6, vec7, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, VP8_FILTER_SHIFT); - PCKEV_ST_SB(tmp2, tmp3, dst); - dst += dst_stride; - - src0 = src4; - } -} - -static void common_hv_2ht_2vt_4x4_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert) { - v16i8 src0, src1, src2, src3, src4, mask; - v16u8 filt_vt, filt_hz, vec0, vec1, res0, res1; - v8u16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, filt, tmp0, tmp1; - - mask = LD_SB(&vp8_mc_filt_mask_arr[16]); - - filt = LD_UH(filter_horiz); - filt_hz = (v16u8)__msa_splati_h((v8i16)filt, 0); - filt = LD_UH(filter_vert); - filt_vt = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src1, mask, filt_hz, VP8_FILTER_SHIFT); - hz_out2 = HORIZ_2TAP_FILT_UH(src2, src3, mask, filt_hz, VP8_FILTER_SHIFT); - hz_out4 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, VP8_FILTER_SHIFT); - hz_out1 = (v8u16)__msa_sldi_b((v16i8)hz_out2, (v16i8)hz_out0, 8); - hz_out3 = (v8u16)__msa_pckod_d((v2i64)hz_out4, (v2i64)hz_out2); - - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, VP8_FILTER_SHIFT); - PCKEV_B2_UB(tmp0, tmp0, tmp1, tmp1, res0, res1); - ST4x4_UB(res0, res1, 0, 1, 0, 1, dst, dst_stride); -} - -static void common_hv_2ht_2vt_4x8_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert) { - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, mask; - v16i8 res0, res1, res2, res3; - v16u8 filt_hz, filt_vt, vec0, vec1, vec2, vec3; - v8u16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; - v8u16 hz_out7, hz_out8, vec4, vec5, vec6, vec7, filt; - - mask = LD_SB(&vp8_mc_filt_mask_arr[16]); - - filt = LD_UH(filter_horiz); - filt_hz = (v16u8)__msa_splati_h((v8i16)filt, 0); - filt = LD_UH(filter_vert); - filt_vt = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - src8 = LD_SB(src); - - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src1, mask, filt_hz, VP8_FILTER_SHIFT); - hz_out2 = HORIZ_2TAP_FILT_UH(src2, src3, mask, filt_hz, VP8_FILTER_SHIFT); - hz_out4 = HORIZ_2TAP_FILT_UH(src4, src5, mask, filt_hz, VP8_FILTER_SHIFT); - hz_out6 = HORIZ_2TAP_FILT_UH(src6, src7, mask, filt_hz, VP8_FILTER_SHIFT); - hz_out8 = HORIZ_2TAP_FILT_UH(src8, src8, mask, filt_hz, VP8_FILTER_SHIFT); - SLDI_B3_UH(hz_out2, hz_out4, hz_out6, hz_out0, hz_out2, hz_out4, hz_out1, - hz_out3, hz_out5, 8); - hz_out7 = (v8u16)__msa_pckod_d((v2i64)hz_out8, (v2i64)hz_out6); - - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - ILVEV_B2_UB(hz_out4, hz_out5, hz_out6, hz_out7, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt_vt, filt_vt, filt_vt, filt_vt, vec4, - vec5, vec6, vec7); - SRARI_H4_UH(vec4, vec5, vec6, vec7, VP8_FILTER_SHIFT); - PCKEV_B4_SB(vec4, vec4, vec5, vec5, vec6, vec6, vec7, vec7, res0, res1, res2, - res3); - ST4x4_UB(res0, res1, 0, 1, 0, 1, dst, dst_stride); - dst += (4 * dst_stride); - ST4x4_UB(res2, res3, 0, 1, 0, 1, dst, dst_stride); -} - -static void common_hv_2ht_2vt_4w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - if (4 == height) { - common_hv_2ht_2vt_4x4_msa(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert); - } else if (8 == height) { - common_hv_2ht_2vt_4x8_msa(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert); - } -} - -static void common_hv_2ht_2vt_8x4_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert) { - v16i8 src0, src1, src2, src3, src4, mask, out0, out1; - v16u8 filt_hz, filt_vt, vec0, vec1, vec2, vec3; - v8u16 hz_out0, hz_out1, tmp0, tmp1, tmp2, tmp3; - v8i16 filt; - - mask = LD_SB(&vp8_mc_filt_mask_arr[0]); - - filt = LD_SH(filter_horiz); - filt_hz = (v16u8)__msa_splati_h(filt, 0); - filt = LD_SH(filter_vert); - filt_vt = (v16u8)__msa_splati_h(filt, 0); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, VP8_FILTER_SHIFT); - hz_out1 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, VP8_FILTER_SHIFT); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp0 = __msa_dotp_u_h(vec0, filt_vt); - - hz_out0 = HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, VP8_FILTER_SHIFT); - vec1 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp1 = __msa_dotp_u_h(vec1, filt_vt); - - hz_out1 = HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, VP8_FILTER_SHIFT); - vec2 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp2 = __msa_dotp_u_h(vec2, filt_vt); - - hz_out0 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, VP8_FILTER_SHIFT); - vec3 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp3 = __msa_dotp_u_h(vec3, filt_vt); - - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, VP8_FILTER_SHIFT); - PCKEV_B2_SB(tmp1, tmp0, tmp3, tmp2, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); -} - -static void common_hv_2ht_2vt_8x8mult_msa( - uint8_t *RESTRICT src, int32_t src_stride, uint8_t *RESTRICT dst, - int32_t dst_stride, const int8_t *filter_horiz, const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, mask, out0, out1; - v16u8 filt_hz, filt_vt, vec0; - v8u16 hz_out0, hz_out1, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; - v8i16 filt; - - mask = LD_SB(&vp8_mc_filt_mask_arr[0]); - - filt = LD_SH(filter_horiz); - filt_hz = (v16u8)__msa_splati_h(filt, 0); - filt = LD_SH(filter_vert); - filt_vt = (v16u8)__msa_splati_h(filt, 0); - - src0 = LD_SB(src); - src += src_stride; - - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, VP8_FILTER_SHIFT); - - for (loop_cnt = (height >> 3); loop_cnt--;) { - LD_SB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - - hz_out1 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, VP8_FILTER_SHIFT); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp1 = __msa_dotp_u_h(vec0, filt_vt); - - hz_out0 = HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, VP8_FILTER_SHIFT); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp2 = __msa_dotp_u_h(vec0, filt_vt); - - SRARI_H2_UH(tmp1, tmp2, VP8_FILTER_SHIFT); - - hz_out1 = HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, VP8_FILTER_SHIFT); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp3 = __msa_dotp_u_h(vec0, filt_vt); - - hz_out0 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, VP8_FILTER_SHIFT); - LD_SB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp4 = __msa_dotp_u_h(vec0, filt_vt); - - SRARI_H2_UH(tmp3, tmp4, VP8_FILTER_SHIFT); - PCKEV_B2_SB(tmp2, tmp1, tmp4, tmp3, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += (4 * dst_stride); - - hz_out1 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, VP8_FILTER_SHIFT); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp5 = __msa_dotp_u_h(vec0, filt_vt); - - hz_out0 = HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, VP8_FILTER_SHIFT); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp6 = __msa_dotp_u_h(vec0, filt_vt); - - hz_out1 = HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, VP8_FILTER_SHIFT); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp7 = __msa_dotp_u_h(vec0, filt_vt); - - hz_out0 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, VP8_FILTER_SHIFT); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp8 = __msa_dotp_u_h(vec0, filt_vt); - - SRARI_H4_UH(tmp5, tmp6, tmp7, tmp8, VP8_FILTER_SHIFT); - PCKEV_B2_SB(tmp6, tmp5, tmp8, tmp7, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += (4 * dst_stride); - } -} - -static void common_hv_2ht_2vt_8w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - if (4 == height) { - common_hv_2ht_2vt_8x4_msa(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert); - } else { - common_hv_2ht_2vt_8x8mult_msa(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height); - } -} - -static void common_hv_2ht_2vt_16w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask; - v16u8 filt_hz, filt_vt, vec0, vec1; - v8u16 tmp1, tmp2, hz_out0, hz_out1, hz_out2, hz_out3; - v8i16 filt; - - mask = LD_SB(&vp8_mc_filt_mask_arr[0]); - - /* rearranging filter */ - filt = LD_SH(filter_horiz); - filt_hz = (v16u8)__msa_splati_h(filt, 0); - filt = LD_SH(filter_vert); - filt_vt = (v16u8)__msa_splati_h(filt, 0); - - LD_SB2(src, 8, src0, src1); - src += src_stride; - - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, VP8_FILTER_SHIFT); - hz_out2 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, VP8_FILTER_SHIFT); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src2, src4, src6); - LD_SB4(src + 8, src_stride, src1, src3, src5, src7); - src += (4 * src_stride); - - hz_out1 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, VP8_FILTER_SHIFT); - hz_out3 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, VP8_FILTER_SHIFT); - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp1, tmp2); - SRARI_H2_UH(tmp1, tmp2, VP8_FILTER_SHIFT); - PCKEV_ST_SB(tmp1, tmp2, dst); - dst += dst_stride; - - hz_out0 = HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, VP8_FILTER_SHIFT); - hz_out2 = HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, VP8_FILTER_SHIFT); - ILVEV_B2_UB(hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp1, tmp2); - SRARI_H2_UH(tmp1, tmp2, VP8_FILTER_SHIFT); - PCKEV_ST_SB(tmp1, tmp2, dst); - dst += dst_stride; - - hz_out1 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, VP8_FILTER_SHIFT); - hz_out3 = HORIZ_2TAP_FILT_UH(src5, src5, mask, filt_hz, VP8_FILTER_SHIFT); - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp1, tmp2); - SRARI_H2_UH(tmp1, tmp2, VP8_FILTER_SHIFT); - PCKEV_ST_SB(tmp1, tmp2, dst); - dst += dst_stride; - - hz_out0 = HORIZ_2TAP_FILT_UH(src6, src6, mask, filt_hz, VP8_FILTER_SHIFT); - hz_out2 = HORIZ_2TAP_FILT_UH(src7, src7, mask, filt_hz, VP8_FILTER_SHIFT); - ILVEV_B2_UB(hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp1, tmp2); - SRARI_H2_UH(tmp1, tmp2, VP8_FILTER_SHIFT); - PCKEV_ST_SB(tmp1, tmp2, dst); - dst += dst_stride; - } -} - -void vp8_bilinear_predict4x4_msa(uint8_t *RESTRICT src, int32_t src_stride, - int32_t xoffset, int32_t yoffset, - uint8_t *RESTRICT dst, int32_t dst_stride) { - const int8_t *h_filter = vp8_bilinear_filters_msa[xoffset - 1]; - const int8_t *v_filter = vp8_bilinear_filters_msa[yoffset - 1]; - - if (yoffset) { - if (xoffset) { - common_hv_2ht_2vt_4w_msa(src, src_stride, dst, dst_stride, h_filter, - v_filter, 4); - } else { - common_vt_2t_4w_msa(src, src_stride, dst, dst_stride, v_filter, 4); - } - } else { - if (xoffset) { - common_hz_2t_4w_msa(src, src_stride, dst, dst_stride, h_filter, 4); - } else { - uint32_t tp0, tp1, tp2, tp3; - - LW4(src, src_stride, tp0, tp1, tp2, tp3); - SW4(tp0, tp1, tp2, tp3, dst, dst_stride); - } - } -} - -void vp8_bilinear_predict8x4_msa(uint8_t *RESTRICT src, int32_t src_stride, - int32_t xoffset, int32_t yoffset, - uint8_t *RESTRICT dst, int32_t dst_stride) { - const int8_t *h_filter = vp8_bilinear_filters_msa[xoffset - 1]; - const int8_t *v_filter = vp8_bilinear_filters_msa[yoffset - 1]; - - if (yoffset) { - if (xoffset) { - common_hv_2ht_2vt_8w_msa(src, src_stride, dst, dst_stride, h_filter, - v_filter, 4); - } else { - common_vt_2t_8w_msa(src, src_stride, dst, dst_stride, v_filter, 4); - } - } else { - if (xoffset) { - common_hz_2t_8w_msa(src, src_stride, dst, dst_stride, h_filter, 4); - } else { - vp8_copy_mem8x4(src, src_stride, dst, dst_stride); - } - } -} - -void vp8_bilinear_predict8x8_msa(uint8_t *RESTRICT src, int32_t src_stride, - int32_t xoffset, int32_t yoffset, - uint8_t *RESTRICT dst, int32_t dst_stride) { - const int8_t *h_filter = vp8_bilinear_filters_msa[xoffset - 1]; - const int8_t *v_filter = vp8_bilinear_filters_msa[yoffset - 1]; - - if (yoffset) { - if (xoffset) { - common_hv_2ht_2vt_8w_msa(src, src_stride, dst, dst_stride, h_filter, - v_filter, 8); - } else { - common_vt_2t_8w_msa(src, src_stride, dst, dst_stride, v_filter, 8); - } - } else { - if (xoffset) { - common_hz_2t_8w_msa(src, src_stride, dst, dst_stride, h_filter, 8); - } else { - vp8_copy_mem8x8(src, src_stride, dst, dst_stride); - } - } -} - -void vp8_bilinear_predict16x16_msa(uint8_t *RESTRICT src, int32_t src_stride, - int32_t xoffset, int32_t yoffset, - uint8_t *RESTRICT dst, int32_t dst_stride) { - const int8_t *h_filter = vp8_bilinear_filters_msa[xoffset - 1]; - const int8_t *v_filter = vp8_bilinear_filters_msa[yoffset - 1]; - - if (yoffset) { - if (xoffset) { - common_hv_2ht_2vt_16w_msa(src, src_stride, dst, dst_stride, h_filter, - v_filter, 16); - } else { - common_vt_2t_16w_msa(src, src_stride, dst, dst_stride, v_filter, 16); - } - } else { - if (xoffset) { - common_hz_2t_16w_msa(src, src_stride, dst, dst_stride, h_filter, 16); - } else { - vp8_copy_mem16x16(src, src_stride, dst, dst_stride); - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/copymem_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/copymem_msa.c deleted file mode 100644 index 357c99b8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/copymem_msa.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vp8/common/mips/msa/vp8_macros_msa.h" - -static void copy_8x4_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, - int32_t dst_stride) { - uint64_t src0, src1, src2, src3; - - LD4(src, src_stride, src0, src1, src2, src3); - SD4(src0, src1, src2, src3, dst, dst_stride); -} - -static void copy_8x8_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, - int32_t dst_stride) { - uint64_t src0, src1, src2, src3; - - LD4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - SD4(src0, src1, src2, src3, dst, dst_stride); - dst += (4 * dst_stride); - - LD4(src, src_stride, src0, src1, src2, src3); - SD4(src0, src1, src2, src3, dst, dst_stride); -} - -static void copy_16x16_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, - int32_t dst_stride) { - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v16u8 src8, src9, src10, src11, src12, src13, src14, src15; - - LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - LD_UB8(src, src_stride, src8, src9, src10, src11, src12, src13, src14, src15); - - ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst, dst_stride); - dst += (8 * dst_stride); - ST_UB8(src8, src9, src10, src11, src12, src13, src14, src15, dst, dst_stride); -} - -void vp8_copy_mem16x16_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, - int32_t dst_stride) { - copy_16x16_msa(src, src_stride, dst, dst_stride); -} - -void vp8_copy_mem8x8_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, - int32_t dst_stride) { - copy_8x8_msa(src, src_stride, dst, dst_stride); -} - -void vp8_copy_mem8x4_msa(uint8_t *src, int32_t src_stride, uint8_t *dst, - int32_t dst_stride) { - copy_8x4_msa(src, src_stride, dst, dst_stride); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/idct_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/idct_msa.c deleted file mode 100644 index efad0c29..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/idct_msa.c +++ /dev/null @@ -1,406 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vp8/common/blockd.h" -#include "vp8/common/mips/msa/vp8_macros_msa.h" - -static const int32_t cospi8sqrt2minus1 = 20091; -static const int32_t sinpi8sqrt2 = 35468; - -#define TRANSPOSE_TWO_4x4_H(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - v8i16 s4_m, s5_m, s6_m, s7_m; \ - \ - TRANSPOSE8X4_SH_SH(in0, in1, in2, in3, s4_m, s5_m, s6_m, s7_m); \ - ILVR_D2_SH(s6_m, s4_m, s7_m, s5_m, out0, out2); \ - out1 = (v8i16)__msa_ilvl_d((v2i64)s6_m, (v2i64)s4_m); \ - out3 = (v8i16)__msa_ilvl_d((v2i64)s7_m, (v2i64)s5_m); \ - } - -#define EXPAND_TO_H_MULTIPLY_SINPI8SQRT2_PCK_TO_W(in) \ - ({ \ - v8i16 out_m; \ - v8i16 zero_m = { 0 }; \ - v4i32 tmp1_m, tmp2_m; \ - v4i32 sinpi8_sqrt2_m = __msa_fill_w(sinpi8sqrt2); \ - \ - ILVRL_H2_SW(in, zero_m, tmp1_m, tmp2_m); \ - tmp1_m >>= 16; \ - tmp2_m >>= 16; \ - tmp1_m = (tmp1_m * sinpi8_sqrt2_m) >> 16; \ - tmp2_m = (tmp2_m * sinpi8_sqrt2_m) >> 16; \ - out_m = __msa_pckev_h((v8i16)tmp2_m, (v8i16)tmp1_m); \ - \ - out_m; \ - }) - -#define VP8_IDCT_1D_H(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - v8i16 a1_m, b1_m, c1_m, d1_m; \ - v8i16 c_tmp1_m, c_tmp2_m, d_tmp1_m, d_tmp2_m; \ - v8i16 const_cospi8sqrt2minus1_m; \ - \ - const_cospi8sqrt2minus1_m = __msa_fill_h(cospi8sqrt2minus1); \ - a1_m = in0 + in2; \ - b1_m = in0 - in2; \ - c_tmp1_m = EXPAND_TO_H_MULTIPLY_SINPI8SQRT2_PCK_TO_W(in1); \ - c_tmp2_m = __msa_mul_q_h(in3, const_cospi8sqrt2minus1_m); \ - c_tmp2_m = c_tmp2_m >> 1; \ - c_tmp2_m = in3 + c_tmp2_m; \ - c1_m = c_tmp1_m - c_tmp2_m; \ - d_tmp1_m = __msa_mul_q_h(in1, const_cospi8sqrt2minus1_m); \ - d_tmp1_m = d_tmp1_m >> 1; \ - d_tmp1_m = in1 + d_tmp1_m; \ - d_tmp2_m = EXPAND_TO_H_MULTIPLY_SINPI8SQRT2_PCK_TO_W(in3); \ - d1_m = d_tmp1_m + d_tmp2_m; \ - BUTTERFLY_4(a1_m, b1_m, c1_m, d1_m, out0, out1, out2, out3); \ - } - -#define VP8_IDCT_1D_W(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - v4i32 a1_m, b1_m, c1_m, d1_m; \ - v4i32 c_tmp1_m, c_tmp2_m, d_tmp1_m, d_tmp2_m; \ - v4i32 const_cospi8sqrt2minus1_m, sinpi8_sqrt2_m; \ - \ - const_cospi8sqrt2minus1_m = __msa_fill_w(cospi8sqrt2minus1); \ - sinpi8_sqrt2_m = __msa_fill_w(sinpi8sqrt2); \ - a1_m = in0 + in2; \ - b1_m = in0 - in2; \ - c_tmp1_m = (in1 * sinpi8_sqrt2_m) >> 16; \ - c_tmp2_m = in3 + ((in3 * const_cospi8sqrt2minus1_m) >> 16); \ - c1_m = c_tmp1_m - c_tmp2_m; \ - d_tmp1_m = in1 + ((in1 * const_cospi8sqrt2minus1_m) >> 16); \ - d_tmp2_m = (in3 * sinpi8_sqrt2_m) >> 16; \ - d1_m = d_tmp1_m + d_tmp2_m; \ - BUTTERFLY_4(a1_m, b1_m, c1_m, d1_m, out0, out1, out2, out3); \ - } - -static void idct4x4_addblk_msa(int16_t *input, uint8_t *pred, - int32_t pred_stride, uint8_t *dest, - int32_t dest_stride) { - v8i16 input0, input1; - v4i32 in0, in1, in2, in3, hz0, hz1, hz2, hz3, vt0, vt1, vt2, vt3; - v4i32 res0, res1, res2, res3; - v16i8 zero = { 0 }; - v16i8 pred0, pred1, pred2, pred3; - - LD_SH2(input, 8, input0, input1); - UNPCK_SH_SW(input0, in0, in1); - UNPCK_SH_SW(input1, in2, in3); - VP8_IDCT_1D_W(in0, in1, in2, in3, hz0, hz1, hz2, hz3); - TRANSPOSE4x4_SW_SW(hz0, hz1, hz2, hz3, hz0, hz1, hz2, hz3); - VP8_IDCT_1D_W(hz0, hz1, hz2, hz3, vt0, vt1, vt2, vt3); - SRARI_W4_SW(vt0, vt1, vt2, vt3, 3); - TRANSPOSE4x4_SW_SW(vt0, vt1, vt2, vt3, vt0, vt1, vt2, vt3); - LD_SB4(pred, pred_stride, pred0, pred1, pred2, pred3); - ILVR_B4_SW(zero, pred0, zero, pred1, zero, pred2, zero, pred3, res0, res1, - res2, res3); - ILVR_H4_SW(zero, res0, zero, res1, zero, res2, zero, res3, res0, res1, res2, - res3); - ADD4(res0, vt0, res1, vt1, res2, vt2, res3, vt3, res0, res1, res2, res3); - res0 = CLIP_SW_0_255(res0); - res1 = CLIP_SW_0_255(res1); - res2 = CLIP_SW_0_255(res2); - res3 = CLIP_SW_0_255(res3); - PCKEV_B2_SW(res0, res1, res2, res3, vt0, vt1); - res0 = (v4i32)__msa_pckev_b((v16i8)vt0, (v16i8)vt1); - ST4x4_UB(res0, res0, 3, 2, 1, 0, dest, dest_stride); -} - -static void idct4x4_addconst_msa(int16_t in_dc, uint8_t *pred, - int32_t pred_stride, uint8_t *dest, - int32_t dest_stride) { - v8i16 vec, res0, res1, res2, res3, dst0, dst1; - v16i8 zero = { 0 }; - v16i8 pred0, pred1, pred2, pred3; - - vec = __msa_fill_h(in_dc); - vec = __msa_srari_h(vec, 3); - LD_SB4(pred, pred_stride, pred0, pred1, pred2, pred3); - ILVR_B4_SH(zero, pred0, zero, pred1, zero, pred2, zero, pred3, res0, res1, - res2, res3); - ADD4(res0, vec, res1, vec, res2, vec, res3, vec, res0, res1, res2, res3); - CLIP_SH4_0_255(res0, res1, res2, res3); - PCKEV_B2_SH(res1, res0, res3, res2, dst0, dst1); - dst0 = (v8i16)__msa_pckev_w((v4i32)dst1, (v4i32)dst0); - ST4x4_UB(dst0, dst0, 0, 1, 2, 3, dest, dest_stride); -} - -void vp8_short_inv_walsh4x4_msa(int16_t *input, int16_t *mb_dqcoeff) { - v8i16 input0, input1, tmp0, tmp1, tmp2, tmp3, out0, out1; - const v8i16 mask0 = { 0, 1, 2, 3, 8, 9, 10, 11 }; - const v8i16 mask1 = { 4, 5, 6, 7, 12, 13, 14, 15 }; - const v8i16 mask2 = { 0, 4, 8, 12, 1, 5, 9, 13 }; - const v8i16 mask3 = { 3, 7, 11, 15, 2, 6, 10, 14 }; - - LD_SH2(input, 8, input0, input1); - input1 = (v8i16)__msa_sldi_b((v16i8)input1, (v16i8)input1, 8); - tmp0 = input0 + input1; - tmp1 = input0 - input1; - VSHF_H2_SH(tmp0, tmp1, tmp0, tmp1, mask0, mask1, tmp2, tmp3); - out0 = tmp2 + tmp3; - out1 = tmp2 - tmp3; - VSHF_H2_SH(out0, out1, out0, out1, mask2, mask3, input0, input1); - tmp0 = input0 + input1; - tmp1 = input0 - input1; - VSHF_H2_SH(tmp0, tmp1, tmp0, tmp1, mask0, mask1, tmp2, tmp3); - tmp0 = tmp2 + tmp3; - tmp1 = tmp2 - tmp3; - ADD2(tmp0, 3, tmp1, 3, out0, out1); - out0 >>= 3; - out1 >>= 3; - mb_dqcoeff[0] = __msa_copy_s_h(out0, 0); - mb_dqcoeff[16] = __msa_copy_s_h(out0, 4); - mb_dqcoeff[32] = __msa_copy_s_h(out1, 0); - mb_dqcoeff[48] = __msa_copy_s_h(out1, 4); - mb_dqcoeff[64] = __msa_copy_s_h(out0, 1); - mb_dqcoeff[80] = __msa_copy_s_h(out0, 5); - mb_dqcoeff[96] = __msa_copy_s_h(out1, 1); - mb_dqcoeff[112] = __msa_copy_s_h(out1, 5); - mb_dqcoeff[128] = __msa_copy_s_h(out0, 2); - mb_dqcoeff[144] = __msa_copy_s_h(out0, 6); - mb_dqcoeff[160] = __msa_copy_s_h(out1, 2); - mb_dqcoeff[176] = __msa_copy_s_h(out1, 6); - mb_dqcoeff[192] = __msa_copy_s_h(out0, 3); - mb_dqcoeff[208] = __msa_copy_s_h(out0, 7); - mb_dqcoeff[224] = __msa_copy_s_h(out1, 3); - mb_dqcoeff[240] = __msa_copy_s_h(out1, 7); -} - -static void dequant_idct4x4_addblk_msa(int16_t *input, int16_t *dequant_input, - uint8_t *dest, int32_t dest_stride) { - v8i16 input0, input1, dequant_in0, dequant_in1, mul0, mul1; - v8i16 in0, in1, in2, in3, hz0_h, hz1_h, hz2_h, hz3_h; - v16u8 dest0, dest1, dest2, dest3; - v4i32 hz0_w, hz1_w, hz2_w, hz3_w, vt0, vt1, vt2, vt3, res0, res1, res2, res3; - v2i64 zero = { 0 }; - - LD_SH2(input, 8, input0, input1); - LD_SH2(dequant_input, 8, dequant_in0, dequant_in1); - MUL2(input0, dequant_in0, input1, dequant_in1, mul0, mul1); - PCKEV_D2_SH(zero, mul0, zero, mul1, in0, in2); - PCKOD_D2_SH(zero, mul0, zero, mul1, in1, in3); - VP8_IDCT_1D_H(in0, in1, in2, in3, hz0_h, hz1_h, hz2_h, hz3_h); - PCKEV_D2_SH(hz1_h, hz0_h, hz3_h, hz2_h, mul0, mul1); - UNPCK_SH_SW(mul0, hz0_w, hz1_w); - UNPCK_SH_SW(mul1, hz2_w, hz3_w); - TRANSPOSE4x4_SW_SW(hz0_w, hz1_w, hz2_w, hz3_w, hz0_w, hz1_w, hz2_w, hz3_w); - VP8_IDCT_1D_W(hz0_w, hz1_w, hz2_w, hz3_w, vt0, vt1, vt2, vt3); - SRARI_W4_SW(vt0, vt1, vt2, vt3, 3); - TRANSPOSE4x4_SW_SW(vt0, vt1, vt2, vt3, vt0, vt1, vt2, vt3); - LD_UB4(dest, dest_stride, dest0, dest1, dest2, dest3); - ILVR_B4_SW(zero, dest0, zero, dest1, zero, dest2, zero, dest3, res0, res1, - res2, res3); - ILVR_H4_SW(zero, res0, zero, res1, zero, res2, zero, res3, res0, res1, res2, - res3); - ADD4(res0, vt0, res1, vt1, res2, vt2, res3, vt3, res0, res1, res2, res3); - res0 = CLIP_SW_0_255(res0); - res1 = CLIP_SW_0_255(res1); - res2 = CLIP_SW_0_255(res2); - res3 = CLIP_SW_0_255(res3); - PCKEV_B2_SW(res0, res1, res2, res3, vt0, vt1); - res0 = (v4i32)__msa_pckev_b((v16i8)vt0, (v16i8)vt1); - ST4x4_UB(res0, res0, 3, 2, 1, 0, dest, dest_stride); -} - -static void dequant_idct4x4_addblk_2x_msa(int16_t *input, - int16_t *dequant_input, uint8_t *dest, - int32_t dest_stride) { - v16u8 dest0, dest1, dest2, dest3; - v8i16 in0, in1, in2, in3, mul0, mul1, mul2, mul3, dequant_in0, dequant_in1; - v8i16 hz0, hz1, hz2, hz3, vt0, vt1, vt2, vt3, res0, res1, res2, res3; - v4i32 hz0l, hz1l, hz2l, hz3l, hz0r, hz1r, hz2r, hz3r; - v4i32 vt0l, vt1l, vt2l, vt3l, vt0r, vt1r, vt2r, vt3r; - v16i8 zero = { 0 }; - - LD_SH4(input, 8, in0, in1, in2, in3); - LD_SH2(dequant_input, 8, dequant_in0, dequant_in1); - MUL4(in0, dequant_in0, in1, dequant_in1, in2, dequant_in0, in3, dequant_in1, - mul0, mul1, mul2, mul3); - PCKEV_D2_SH(mul2, mul0, mul3, mul1, in0, in2); - PCKOD_D2_SH(mul2, mul0, mul3, mul1, in1, in3); - VP8_IDCT_1D_H(in0, in1, in2, in3, hz0, hz1, hz2, hz3); - TRANSPOSE_TWO_4x4_H(hz0, hz1, hz2, hz3, hz0, hz1, hz2, hz3); - UNPCK_SH_SW(hz0, hz0r, hz0l); - UNPCK_SH_SW(hz1, hz1r, hz1l); - UNPCK_SH_SW(hz2, hz2r, hz2l); - UNPCK_SH_SW(hz3, hz3r, hz3l); - VP8_IDCT_1D_W(hz0l, hz1l, hz2l, hz3l, vt0l, vt1l, vt2l, vt3l); - SRARI_W4_SW(vt0l, vt1l, vt2l, vt3l, 3); - VP8_IDCT_1D_W(hz0r, hz1r, hz2r, hz3r, vt0r, vt1r, vt2r, vt3r); - SRARI_W4_SW(vt0r, vt1r, vt2r, vt3r, 3); - PCKEV_H4_SH(vt0l, vt0r, vt1l, vt1r, vt2l, vt2r, vt3l, vt3r, vt0, vt1, vt2, - vt3); - TRANSPOSE_TWO_4x4_H(vt0, vt1, vt2, vt3, vt0, vt1, vt2, vt3); - LD_UB4(dest, dest_stride, dest0, dest1, dest2, dest3); - ILVR_B4_SH(zero, dest0, zero, dest1, zero, dest2, zero, dest3, res0, res1, - res2, res3); - ADD4(res0, vt0, res1, vt1, res2, vt2, res3, vt3, res0, res1, res2, res3); - CLIP_SH4_0_255(res0, res1, res2, res3); - PCKEV_B2_SW(res1, res0, res3, res2, vt0l, vt1l); - ST8x4_UB(vt0l, vt1l, dest, dest_stride); - - __asm__ __volatile__( - "sw $zero, 0(%[input]) \n\t" - "sw $zero, 4(%[input]) \n\t" - "sw $zero, 8(%[input]) \n\t" - "sw $zero, 12(%[input]) \n\t" - "sw $zero, 16(%[input]) \n\t" - "sw $zero, 20(%[input]) \n\t" - "sw $zero, 24(%[input]) \n\t" - "sw $zero, 28(%[input]) \n\t" - "sw $zero, 32(%[input]) \n\t" - "sw $zero, 36(%[input]) \n\t" - "sw $zero, 40(%[input]) \n\t" - "sw $zero, 44(%[input]) \n\t" - "sw $zero, 48(%[input]) \n\t" - "sw $zero, 52(%[input]) \n\t" - "sw $zero, 56(%[input]) \n\t" - "sw $zero, 60(%[input]) \n\t" :: - - [input] "r"(input)); -} - -static void dequant_idct_addconst_2x_msa(int16_t *input, int16_t *dequant_input, - uint8_t *dest, int32_t dest_stride) { - v8i16 input_dc0, input_dc1, vec, res0, res1, res2, res3; - v16u8 dest0, dest1, dest2, dest3; - v16i8 zero = { 0 }; - - input_dc0 = __msa_fill_h(input[0] * dequant_input[0]); - input_dc1 = __msa_fill_h(input[16] * dequant_input[0]); - SRARI_H2_SH(input_dc0, input_dc1, 3); - vec = (v8i16)__msa_pckev_d((v2i64)input_dc1, (v2i64)input_dc0); - input[0] = 0; - input[16] = 0; - LD_UB4(dest, dest_stride, dest0, dest1, dest2, dest3); - ILVR_B4_SH(zero, dest0, zero, dest1, zero, dest2, zero, dest3, res0, res1, - res2, res3); - ADD4(res0, vec, res1, vec, res2, vec, res3, vec, res0, res1, res2, res3); - CLIP_SH4_0_255(res0, res1, res2, res3); - PCKEV_B2_SH(res1, res0, res3, res2, res0, res1); - ST8x4_UB(res0, res1, dest, dest_stride); -} - -void vp8_short_idct4x4llm_msa(int16_t *input, uint8_t *pred_ptr, - int32_t pred_stride, uint8_t *dst_ptr, - int32_t dst_stride) { - idct4x4_addblk_msa(input, pred_ptr, pred_stride, dst_ptr, dst_stride); -} - -void vp8_dc_only_idct_add_msa(int16_t input_dc, uint8_t *pred_ptr, - int32_t pred_stride, uint8_t *dst_ptr, - int32_t dst_stride) { - idct4x4_addconst_msa(input_dc, pred_ptr, pred_stride, dst_ptr, dst_stride); -} - -void vp8_dequantize_b_msa(BLOCKD *d, int16_t *DQC) { - v8i16 dqc0, dqc1, q0, q1, dq0, dq1; - - LD_SH2(DQC, 8, dqc0, dqc1); - LD_SH2(d->qcoeff, 8, q0, q1); - MUL2(dqc0, q0, dqc1, q1, dq0, dq1); - ST_SH2(dq0, dq1, d->dqcoeff, 8); -} - -void vp8_dequant_idct_add_msa(int16_t *input, int16_t *dq, uint8_t *dest, - int32_t stride) { - dequant_idct4x4_addblk_msa(input, dq, dest, stride); - - __asm__ __volatile__( - "sw $zero, 0(%[input]) \n\t" - "sw $zero, 4(%[input]) \n\t" - "sw $zero, 8(%[input]) \n\t" - "sw $zero, 12(%[input]) \n\t" - "sw $zero, 16(%[input]) \n\t" - "sw $zero, 20(%[input]) \n\t" - "sw $zero, 24(%[input]) \n\t" - "sw $zero, 28(%[input]) \n\t" - - : - : [input] "r"(input)); -} - -void vp8_dequant_idct_add_y_block_msa(int16_t *q, int16_t *dq, uint8_t *dst, - int32_t stride, char *eobs) { - int16_t *eobs_h = (int16_t *)eobs; - uint8_t i; - - for (i = 4; i--;) { - if (eobs_h[0]) { - if (eobs_h[0] & 0xfefe) { - dequant_idct4x4_addblk_2x_msa(q, dq, dst, stride); - } else { - dequant_idct_addconst_2x_msa(q, dq, dst, stride); - } - } - - q += 32; - - if (eobs_h[1]) { - if (eobs_h[1] & 0xfefe) { - dequant_idct4x4_addblk_2x_msa(q, dq, dst + 8, stride); - } else { - dequant_idct_addconst_2x_msa(q, dq, dst + 8, stride); - } - } - - q += 32; - dst += (4 * stride); - eobs_h += 2; - } -} - -void vp8_dequant_idct_add_uv_block_msa(int16_t *q, int16_t *dq, uint8_t *dst_u, - uint8_t *dst_v, int32_t stride, - char *eobs) { - int16_t *eobs_h = (int16_t *)eobs; - - if (eobs_h[0]) { - if (eobs_h[0] & 0xfefe) { - dequant_idct4x4_addblk_2x_msa(q, dq, dst_u, stride); - } else { - dequant_idct_addconst_2x_msa(q, dq, dst_u, stride); - } - } - - q += 32; - dst_u += (stride * 4); - - if (eobs_h[1]) { - if (eobs_h[1] & 0xfefe) { - dequant_idct4x4_addblk_2x_msa(q, dq, dst_u, stride); - } else { - dequant_idct_addconst_2x_msa(q, dq, dst_u, stride); - } - } - - q += 32; - - if (eobs_h[2]) { - if (eobs_h[2] & 0xfefe) { - dequant_idct4x4_addblk_2x_msa(q, dq, dst_v, stride); - } else { - dequant_idct_addconst_2x_msa(q, dq, dst_v, stride); - } - } - - q += 32; - dst_v += (stride * 4); - - if (eobs_h[3]) { - if (eobs_h[3] & 0xfefe) { - dequant_idct4x4_addblk_2x_msa(q, dq, dst_v, stride); - } else { - dequant_idct_addconst_2x_msa(q, dq, dst_v, stride); - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/loopfilter_filters_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/loopfilter_filters_msa.c deleted file mode 100644 index 98a4fc09..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/loopfilter_filters_msa.c +++ /dev/null @@ -1,709 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vp8/common/loopfilter.h" -#include "vp8/common/mips/msa/vp8_macros_msa.h" - -#define VP8_SIMPLE_MASK(p1, p0, q0, q1, b_limit, mask) \ - { \ - v16u8 p1_a_sub_q1, p0_a_sub_q0; \ - \ - p0_a_sub_q0 = __msa_asub_u_b(p0, q0); \ - p1_a_sub_q1 = __msa_asub_u_b(p1, q1); \ - p1_a_sub_q1 = (v16u8)__msa_srli_b((v16i8)p1_a_sub_q1, 1); \ - p0_a_sub_q0 = __msa_adds_u_b(p0_a_sub_q0, p0_a_sub_q0); \ - mask = __msa_adds_u_b(p0_a_sub_q0, p1_a_sub_q1); \ - mask = ((v16u8)mask <= b_limit); \ - } - -#define VP8_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev) \ - { \ - v16i8 p1_m, p0_m, q0_m, q1_m, filt, q0_sub_p0, t1, t2; \ - const v16i8 cnst4b = __msa_ldi_b(4); \ - const v16i8 cnst3b = __msa_ldi_b(3); \ - \ - p1_m = (v16i8)__msa_xori_b(p1, 0x80); \ - p0_m = (v16i8)__msa_xori_b(p0, 0x80); \ - q0_m = (v16i8)__msa_xori_b(q0, 0x80); \ - q1_m = (v16i8)__msa_xori_b(q1, 0x80); \ - \ - filt = __msa_subs_s_b(p1_m, q1_m); \ - filt &= hev; \ - q0_sub_p0 = __msa_subs_s_b(q0_m, p0_m); \ - filt = __msa_adds_s_b(filt, q0_sub_p0); \ - filt = __msa_adds_s_b(filt, q0_sub_p0); \ - filt = __msa_adds_s_b(filt, q0_sub_p0); \ - filt &= mask; \ - t1 = __msa_adds_s_b(filt, cnst4b); \ - t1 >>= cnst3b; \ - t2 = __msa_adds_s_b(filt, cnst3b); \ - t2 >>= cnst3b; \ - q0_m = __msa_subs_s_b(q0_m, t1); \ - q0 = __msa_xori_b((v16u8)q0_m, 0x80); \ - p0_m = __msa_adds_s_b(p0_m, t2); \ - p0 = __msa_xori_b((v16u8)p0_m, 0x80); \ - filt = __msa_srari_b(t1, 1); \ - hev = __msa_xori_b(hev, 0xff); \ - filt &= hev; \ - q1_m = __msa_subs_s_b(q1_m, filt); \ - q1 = __msa_xori_b((v16u8)q1_m, 0x80); \ - p1_m = __msa_adds_s_b(p1_m, filt); \ - p1 = __msa_xori_b((v16u8)p1_m, 0x80); \ - } - -#define VP8_SIMPLE_FILT(p1_in, p0_in, q0_in, q1_in, mask) \ - { \ - v16i8 p1_m, p0_m, q0_m, q1_m, filt, filt1, filt2; \ - v16i8 q0_sub_p0; \ - const v16i8 cnst4b = __msa_ldi_b(4); \ - const v16i8 cnst3b = __msa_ldi_b(3); \ - \ - p1_m = (v16i8)__msa_xori_b(p1_in, 0x80); \ - p0_m = (v16i8)__msa_xori_b(p0_in, 0x80); \ - q0_m = (v16i8)__msa_xori_b(q0_in, 0x80); \ - q1_m = (v16i8)__msa_xori_b(q1_in, 0x80); \ - \ - filt = __msa_subs_s_b(p1_m, q1_m); \ - q0_sub_p0 = __msa_subs_s_b(q0_m, p0_m); \ - filt = __msa_adds_s_b(filt, q0_sub_p0); \ - filt = __msa_adds_s_b(filt, q0_sub_p0); \ - filt = __msa_adds_s_b(filt, q0_sub_p0); \ - filt &= mask; \ - filt1 = __msa_adds_s_b(filt, cnst4b); \ - filt1 >>= cnst3b; \ - filt2 = __msa_adds_s_b(filt, cnst3b); \ - filt2 >>= cnst3b; \ - q0_m = __msa_subs_s_b(q0_m, filt1); \ - p0_m = __msa_adds_s_b(p0_m, filt2); \ - q0_in = __msa_xori_b((v16u8)q0_m, 0x80); \ - p0_in = __msa_xori_b((v16u8)p0_m, 0x80); \ - } - -#define VP8_MBFILTER(p2, p1, p0, q0, q1, q2, mask, hev) \ - { \ - v16i8 p2_m, p1_m, p0_m, q2_m, q1_m, q0_m; \ - v16i8 u, filt, t1, t2, filt_sign, q0_sub_p0; \ - v8i16 filt_r, filt_l, u_r, u_l; \ - v8i16 temp0, temp1, temp2, temp3; \ - const v16i8 cnst4b = __msa_ldi_b(4); \ - const v16i8 cnst3b = __msa_ldi_b(3); \ - const v8i16 cnst9h = __msa_ldi_h(9); \ - const v8i16 cnst63h = __msa_ldi_h(63); \ - \ - p2_m = (v16i8)__msa_xori_b(p2, 0x80); \ - p1_m = (v16i8)__msa_xori_b(p1, 0x80); \ - p0_m = (v16i8)__msa_xori_b(p0, 0x80); \ - q0_m = (v16i8)__msa_xori_b(q0, 0x80); \ - q1_m = (v16i8)__msa_xori_b(q1, 0x80); \ - q2_m = (v16i8)__msa_xori_b(q2, 0x80); \ - \ - filt = __msa_subs_s_b(p1_m, q1_m); \ - q0_sub_p0 = __msa_subs_s_b(q0_m, p0_m); \ - filt = __msa_adds_s_b(filt, q0_sub_p0); \ - filt = __msa_adds_s_b(filt, q0_sub_p0); \ - filt = __msa_adds_s_b(filt, q0_sub_p0); \ - filt &= mask; \ - \ - t2 = filt & hev; \ - hev = __msa_xori_b(hev, 0xff); \ - filt &= hev; \ - t1 = __msa_adds_s_b(t2, cnst4b); \ - t1 >>= cnst3b; \ - t2 = __msa_adds_s_b(t2, cnst3b); \ - t2 >>= cnst3b; \ - q0_m = __msa_subs_s_b(q0_m, t1); \ - p0_m = __msa_adds_s_b(p0_m, t2); \ - filt_sign = __msa_clti_s_b(filt, 0); \ - ILVRL_B2_SH(filt_sign, filt, filt_r, filt_l); \ - temp0 = filt_r * cnst9h; \ - temp1 = temp0 + cnst63h; \ - temp2 = filt_l * cnst9h; \ - temp3 = temp2 + cnst63h; \ - \ - u_r = temp1 >> 7; \ - u_r = __msa_sat_s_h(u_r, 7); \ - u_l = temp3 >> 7; \ - u_l = __msa_sat_s_h(u_l, 7); \ - u = __msa_pckev_b((v16i8)u_l, (v16i8)u_r); \ - q2_m = __msa_subs_s_b(q2_m, u); \ - p2_m = __msa_adds_s_b(p2_m, u); \ - q2 = __msa_xori_b((v16u8)q2_m, 0x80); \ - p2 = __msa_xori_b((v16u8)p2_m, 0x80); \ - \ - temp1 += temp0; \ - temp3 += temp2; \ - \ - u_r = temp1 >> 7; \ - u_r = __msa_sat_s_h(u_r, 7); \ - u_l = temp3 >> 7; \ - u_l = __msa_sat_s_h(u_l, 7); \ - u = __msa_pckev_b((v16i8)u_l, (v16i8)u_r); \ - q1_m = __msa_subs_s_b(q1_m, u); \ - p1_m = __msa_adds_s_b(p1_m, u); \ - q1 = __msa_xori_b((v16u8)q1_m, 0x80); \ - p1 = __msa_xori_b((v16u8)p1_m, 0x80); \ - \ - temp1 += temp0; \ - temp3 += temp2; \ - \ - u_r = temp1 >> 7; \ - u_r = __msa_sat_s_h(u_r, 7); \ - u_l = temp3 >> 7; \ - u_l = __msa_sat_s_h(u_l, 7); \ - u = __msa_pckev_b((v16i8)u_l, (v16i8)u_r); \ - q0_m = __msa_subs_s_b(q0_m, u); \ - p0_m = __msa_adds_s_b(p0_m, u); \ - q0 = __msa_xori_b((v16u8)q0_m, 0x80); \ - p0 = __msa_xori_b((v16u8)p0_m, 0x80); \ - } - -#define LPF_MASK_HEV(p3_in, p2_in, p1_in, p0_in, q0_in, q1_in, q2_in, q3_in, \ - limit_in, b_limit_in, thresh_in, hev_out, mask_out, \ - flat_out) \ - { \ - v16u8 p3_asub_p2_m, p2_asub_p1_m, p1_asub_p0_m, q1_asub_q0_m; \ - v16u8 p1_asub_q1_m, p0_asub_q0_m, q3_asub_q2_m, q2_asub_q1_m; \ - \ - p3_asub_p2_m = __msa_asub_u_b((p3_in), (p2_in)); \ - p2_asub_p1_m = __msa_asub_u_b((p2_in), (p1_in)); \ - p1_asub_p0_m = __msa_asub_u_b((p1_in), (p0_in)); \ - q1_asub_q0_m = __msa_asub_u_b((q1_in), (q0_in)); \ - q2_asub_q1_m = __msa_asub_u_b((q2_in), (q1_in)); \ - q3_asub_q2_m = __msa_asub_u_b((q3_in), (q2_in)); \ - p0_asub_q0_m = __msa_asub_u_b((p0_in), (q0_in)); \ - p1_asub_q1_m = __msa_asub_u_b((p1_in), (q1_in)); \ - flat_out = __msa_max_u_b(p1_asub_p0_m, q1_asub_q0_m); \ - hev_out = (thresh_in) < (v16u8)flat_out; \ - p0_asub_q0_m = __msa_adds_u_b(p0_asub_q0_m, p0_asub_q0_m); \ - p1_asub_q1_m >>= 1; \ - p0_asub_q0_m = __msa_adds_u_b(p0_asub_q0_m, p1_asub_q1_m); \ - mask_out = (b_limit_in) < p0_asub_q0_m; \ - mask_out = __msa_max_u_b(flat_out, mask_out); \ - p3_asub_p2_m = __msa_max_u_b(p3_asub_p2_m, p2_asub_p1_m); \ - mask_out = __msa_max_u_b(p3_asub_p2_m, mask_out); \ - q2_asub_q1_m = __msa_max_u_b(q2_asub_q1_m, q3_asub_q2_m); \ - mask_out = __msa_max_u_b(q2_asub_q1_m, mask_out); \ - mask_out = (limit_in) < (v16u8)mask_out; \ - mask_out = __msa_xori_b(mask_out, 0xff); \ - } - -#define VP8_ST6x1_UB(in0, in0_idx, in1, in1_idx, pdst, stride) \ - { \ - uint16_t tmp0_h; \ - uint32_t tmp0_w; \ - \ - tmp0_w = __msa_copy_u_w((v4i32)in0, in0_idx); \ - tmp0_h = __msa_copy_u_h((v8i16)in1, in1_idx); \ - SW(tmp0_w, pdst); \ - SH(tmp0_h, pdst + stride); \ - } - -static void loop_filter_horizontal_4_dual_msa(uint8_t *src, int32_t pitch, - const uint8_t *b_limit0_ptr, - const uint8_t *limit0_ptr, - const uint8_t *thresh0_ptr, - const uint8_t *b_limit1_ptr, - const uint8_t *limit1_ptr, - const uint8_t *thresh1_ptr) { - v16u8 mask, hev, flat; - v16u8 thresh0, b_limit0, limit0, thresh1, b_limit1, limit1; - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - - LD_UB8((src - 4 * pitch), pitch, p3, p2, p1, p0, q0, q1, q2, q3); - thresh0 = (v16u8)__msa_fill_b(*thresh0_ptr); - thresh1 = (v16u8)__msa_fill_b(*thresh1_ptr); - thresh0 = (v16u8)__msa_ilvr_d((v2i64)thresh1, (v2i64)thresh0); - - b_limit0 = (v16u8)__msa_fill_b(*b_limit0_ptr); - b_limit1 = (v16u8)__msa_fill_b(*b_limit1_ptr); - b_limit0 = (v16u8)__msa_ilvr_d((v2i64)b_limit1, (v2i64)b_limit0); - - limit0 = (v16u8)__msa_fill_b(*limit0_ptr); - limit1 = (v16u8)__msa_fill_b(*limit1_ptr); - limit0 = (v16u8)__msa_ilvr_d((v2i64)limit1, (v2i64)limit0); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit0, b_limit0, thresh0, hev, - mask, flat); - VP8_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev); - - ST_UB4(p1, p0, q0, q1, (src - 2 * pitch), pitch); -} - -static void loop_filter_vertical_4_dual_msa(uint8_t *src, int32_t pitch, - const uint8_t *b_limit0_ptr, - const uint8_t *limit0_ptr, - const uint8_t *thresh0_ptr, - const uint8_t *b_limit1_ptr, - const uint8_t *limit1_ptr, - const uint8_t *thresh1_ptr) { - v16u8 mask, hev, flat; - v16u8 thresh0, b_limit0, limit0, thresh1, b_limit1, limit1; - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - v16u8 row0, row1, row2, row3, row4, row5, row6, row7; - v16u8 row8, row9, row10, row11, row12, row13, row14, row15; - v8i16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; - - LD_UB8(src - 4, pitch, row0, row1, row2, row3, row4, row5, row6, row7); - LD_UB8(src - 4 + (8 * pitch), pitch, row8, row9, row10, row11, row12, row13, - row14, row15); - TRANSPOSE16x8_UB_UB(row0, row1, row2, row3, row4, row5, row6, row7, row8, - row9, row10, row11, row12, row13, row14, row15, p3, p2, - p1, p0, q0, q1, q2, q3); - - thresh0 = (v16u8)__msa_fill_b(*thresh0_ptr); - thresh1 = (v16u8)__msa_fill_b(*thresh1_ptr); - thresh0 = (v16u8)__msa_ilvr_d((v2i64)thresh1, (v2i64)thresh0); - - b_limit0 = (v16u8)__msa_fill_b(*b_limit0_ptr); - b_limit1 = (v16u8)__msa_fill_b(*b_limit1_ptr); - b_limit0 = (v16u8)__msa_ilvr_d((v2i64)b_limit1, (v2i64)b_limit0); - - limit0 = (v16u8)__msa_fill_b(*limit0_ptr); - limit1 = (v16u8)__msa_fill_b(*limit1_ptr); - limit0 = (v16u8)__msa_ilvr_d((v2i64)limit1, (v2i64)limit0); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit0, b_limit0, thresh0, hev, - mask, flat); - VP8_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev); - ILVR_B2_SH(p0, p1, q1, q0, tmp0, tmp1); - ILVRL_H2_SH(tmp1, tmp0, tmp2, tmp3); - ILVL_B2_SH(p0, p1, q1, q0, tmp0, tmp1); - ILVRL_H2_SH(tmp1, tmp0, tmp4, tmp5); - - src -= 2; - ST4x8_UB(tmp2, tmp3, src, pitch); - src += (8 * pitch); - ST4x8_UB(tmp4, tmp5, src, pitch); -} - -static void mbloop_filter_horizontal_edge_y_msa(uint8_t *src, int32_t pitch, - const uint8_t b_limit_in, - const uint8_t limit_in, - const uint8_t thresh_in) { - uint8_t *temp_src; - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - v16u8 mask, hev, flat, thresh, limit, b_limit; - - b_limit = (v16u8)__msa_fill_b(b_limit_in); - limit = (v16u8)__msa_fill_b(limit_in); - thresh = (v16u8)__msa_fill_b(thresh_in); - temp_src = src - (pitch << 2); - LD_UB8(temp_src, pitch, p3, p2, p1, p0, q0, q1, q2, q3); - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP8_MBFILTER(p2, p1, p0, q0, q1, q2, mask, hev); - temp_src = src - 3 * pitch; - ST_UB4(p2, p1, p0, q0, temp_src, pitch); - temp_src += (4 * pitch); - ST_UB2(q1, q2, temp_src, pitch); -} - -static void mbloop_filter_horizontal_edge_uv_msa(uint8_t *src_u, uint8_t *src_v, - int32_t pitch, - const uint8_t b_limit_in, - const uint8_t limit_in, - const uint8_t thresh_in) { - uint8_t *temp_src; - uint64_t p2_d, p1_d, p0_d, q0_d, q1_d, q2_d; - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - v16u8 mask, hev, flat, thresh, limit, b_limit; - v16u8 p3_u, p2_u, p1_u, p0_u, q3_u, q2_u, q1_u, q0_u; - v16u8 p3_v, p2_v, p1_v, p0_v, q3_v, q2_v, q1_v, q0_v; - - b_limit = (v16u8)__msa_fill_b(b_limit_in); - limit = (v16u8)__msa_fill_b(limit_in); - thresh = (v16u8)__msa_fill_b(thresh_in); - - temp_src = src_u - (pitch << 2); - LD_UB8(temp_src, pitch, p3_u, p2_u, p1_u, p0_u, q0_u, q1_u, q2_u, q3_u); - temp_src = src_v - (pitch << 2); - LD_UB8(temp_src, pitch, p3_v, p2_v, p1_v, p0_v, q0_v, q1_v, q2_v, q3_v); - - ILVR_D4_UB(p3_v, p3_u, p2_v, p2_u, p1_v, p1_u, p0_v, p0_u, p3, p2, p1, p0); - ILVR_D4_UB(q0_v, q0_u, q1_v, q1_u, q2_v, q2_u, q3_v, q3_u, q0, q1, q2, q3); - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP8_MBFILTER(p2, p1, p0, q0, q1, q2, mask, hev); - - p2_d = __msa_copy_u_d((v2i64)p2, 0); - p1_d = __msa_copy_u_d((v2i64)p1, 0); - p0_d = __msa_copy_u_d((v2i64)p0, 0); - q0_d = __msa_copy_u_d((v2i64)q0, 0); - q1_d = __msa_copy_u_d((v2i64)q1, 0); - q2_d = __msa_copy_u_d((v2i64)q2, 0); - src_u -= (pitch * 3); - SD4(p2_d, p1_d, p0_d, q0_d, src_u, pitch); - src_u += 4 * pitch; - SD(q1_d, src_u); - src_u += pitch; - SD(q2_d, src_u); - - p2_d = __msa_copy_u_d((v2i64)p2, 1); - p1_d = __msa_copy_u_d((v2i64)p1, 1); - p0_d = __msa_copy_u_d((v2i64)p0, 1); - q0_d = __msa_copy_u_d((v2i64)q0, 1); - q1_d = __msa_copy_u_d((v2i64)q1, 1); - q2_d = __msa_copy_u_d((v2i64)q2, 1); - src_v -= (pitch * 3); - SD4(p2_d, p1_d, p0_d, q0_d, src_v, pitch); - src_v += 4 * pitch; - SD(q1_d, src_v); - src_v += pitch; - SD(q2_d, src_v); -} - -static void mbloop_filter_vertical_edge_y_msa(uint8_t *src, int32_t pitch, - const uint8_t b_limit_in, - const uint8_t limit_in, - const uint8_t thresh_in) { - uint8_t *temp_src; - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - v16u8 mask, hev, flat, thresh, limit, b_limit; - v16u8 row0, row1, row2, row3, row4, row5, row6, row7, row8; - v16u8 row9, row10, row11, row12, row13, row14, row15; - v8i16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - - b_limit = (v16u8)__msa_fill_b(b_limit_in); - limit = (v16u8)__msa_fill_b(limit_in); - thresh = (v16u8)__msa_fill_b(thresh_in); - temp_src = src - 4; - LD_UB8(temp_src, pitch, row0, row1, row2, row3, row4, row5, row6, row7); - temp_src += (8 * pitch); - LD_UB8(temp_src, pitch, row8, row9, row10, row11, row12, row13, row14, row15); - TRANSPOSE16x8_UB_UB(row0, row1, row2, row3, row4, row5, row6, row7, row8, - row9, row10, row11, row12, row13, row14, row15, p3, p2, - p1, p0, q0, q1, q2, q3); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP8_MBFILTER(p2, p1, p0, q0, q1, q2, mask, hev); - ILVR_B2_SH(p1, p2, q0, p0, tmp0, tmp1); - ILVRL_H2_SH(tmp1, tmp0, tmp3, tmp4); - ILVL_B2_SH(p1, p2, q0, p0, tmp0, tmp1); - ILVRL_H2_SH(tmp1, tmp0, tmp6, tmp7); - ILVRL_B2_SH(q2, q1, tmp2, tmp5); - - temp_src = src - 3; - VP8_ST6x1_UB(tmp3, 0, tmp2, 0, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_UB(tmp3, 1, tmp2, 1, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_UB(tmp3, 2, tmp2, 2, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_UB(tmp3, 3, tmp2, 3, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_UB(tmp4, 0, tmp2, 4, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_UB(tmp4, 1, tmp2, 5, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_UB(tmp4, 2, tmp2, 6, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_UB(tmp4, 3, tmp2, 7, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_UB(tmp6, 0, tmp5, 0, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_UB(tmp6, 1, tmp5, 1, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_UB(tmp6, 2, tmp5, 2, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_UB(tmp6, 3, tmp5, 3, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_UB(tmp7, 0, tmp5, 4, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_UB(tmp7, 1, tmp5, 5, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_UB(tmp7, 2, tmp5, 6, temp_src, 4); - temp_src += pitch; - VP8_ST6x1_UB(tmp7, 3, tmp5, 7, temp_src, 4); -} - -static void mbloop_filter_vertical_edge_uv_msa(uint8_t *src_u, uint8_t *src_v, - int32_t pitch, - const uint8_t b_limit_in, - const uint8_t limit_in, - const uint8_t thresh_in) { - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - v16u8 mask, hev, flat, thresh, limit, b_limit; - v16u8 row0, row1, row2, row3, row4, row5, row6, row7, row8; - v16u8 row9, row10, row11, row12, row13, row14, row15; - v8i16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - - b_limit = (v16u8)__msa_fill_b(b_limit_in); - limit = (v16u8)__msa_fill_b(limit_in); - thresh = (v16u8)__msa_fill_b(thresh_in); - - LD_UB8(src_u - 4, pitch, row0, row1, row2, row3, row4, row5, row6, row7); - LD_UB8(src_v - 4, pitch, row8, row9, row10, row11, row12, row13, row14, - row15); - TRANSPOSE16x8_UB_UB(row0, row1, row2, row3, row4, row5, row6, row7, row8, - row9, row10, row11, row12, row13, row14, row15, p3, p2, - p1, p0, q0, q1, q2, q3); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP8_MBFILTER(p2, p1, p0, q0, q1, q2, mask, hev); - - ILVR_B2_SH(p1, p2, q0, p0, tmp0, tmp1); - ILVRL_H2_SH(tmp1, tmp0, tmp3, tmp4); - ILVL_B2_SH(p1, p2, q0, p0, tmp0, tmp1); - ILVRL_H2_SH(tmp1, tmp0, tmp6, tmp7); - ILVRL_B2_SH(q2, q1, tmp2, tmp5); - - src_u -= 3; - VP8_ST6x1_UB(tmp3, 0, tmp2, 0, src_u, 4); - src_u += pitch; - VP8_ST6x1_UB(tmp3, 1, tmp2, 1, src_u, 4); - src_u += pitch; - VP8_ST6x1_UB(tmp3, 2, tmp2, 2, src_u, 4); - src_u += pitch; - VP8_ST6x1_UB(tmp3, 3, tmp2, 3, src_u, 4); - src_u += pitch; - VP8_ST6x1_UB(tmp4, 0, tmp2, 4, src_u, 4); - src_u += pitch; - VP8_ST6x1_UB(tmp4, 1, tmp2, 5, src_u, 4); - src_u += pitch; - VP8_ST6x1_UB(tmp4, 2, tmp2, 6, src_u, 4); - src_u += pitch; - VP8_ST6x1_UB(tmp4, 3, tmp2, 7, src_u, 4); - - src_v -= 3; - VP8_ST6x1_UB(tmp6, 0, tmp5, 0, src_v, 4); - src_v += pitch; - VP8_ST6x1_UB(tmp6, 1, tmp5, 1, src_v, 4); - src_v += pitch; - VP8_ST6x1_UB(tmp6, 2, tmp5, 2, src_v, 4); - src_v += pitch; - VP8_ST6x1_UB(tmp6, 3, tmp5, 3, src_v, 4); - src_v += pitch; - VP8_ST6x1_UB(tmp7, 0, tmp5, 4, src_v, 4); - src_v += pitch; - VP8_ST6x1_UB(tmp7, 1, tmp5, 5, src_v, 4); - src_v += pitch; - VP8_ST6x1_UB(tmp7, 2, tmp5, 6, src_v, 4); - src_v += pitch; - VP8_ST6x1_UB(tmp7, 3, tmp5, 7, src_v, 4); -} - -void vp8_loop_filter_simple_horizontal_edge_msa(uint8_t *src, int32_t pitch, - const uint8_t *b_limit_ptr) { - v16u8 p1, p0, q1, q0; - v16u8 mask, b_limit; - - b_limit = (v16u8)__msa_fill_b(*b_limit_ptr); - LD_UB4(src - (pitch << 1), pitch, p1, p0, q0, q1); - VP8_SIMPLE_MASK(p1, p0, q0, q1, b_limit, mask); - VP8_SIMPLE_FILT(p1, p0, q0, q1, mask); - ST_UB2(p0, q0, (src - pitch), pitch); -} - -void vp8_loop_filter_simple_vertical_edge_msa(uint8_t *src, int32_t pitch, - const uint8_t *b_limit_ptr) { - uint8_t *temp_src; - v16u8 p1, p0, q1, q0; - v16u8 mask, b_limit; - v16u8 row0, row1, row2, row3, row4, row5, row6, row7, row8; - v16u8 row9, row10, row11, row12, row13, row14, row15; - v8i16 tmp0, tmp1; - - b_limit = (v16u8)__msa_fill_b(*b_limit_ptr); - temp_src = src - 2; - LD_UB8(temp_src, pitch, row0, row1, row2, row3, row4, row5, row6, row7); - temp_src += (8 * pitch); - LD_UB8(temp_src, pitch, row8, row9, row10, row11, row12, row13, row14, row15); - TRANSPOSE16x4_UB_UB(row0, row1, row2, row3, row4, row5, row6, row7, row8, - row9, row10, row11, row12, row13, row14, row15, p1, p0, - q0, q1); - VP8_SIMPLE_MASK(p1, p0, q0, q1, b_limit, mask); - VP8_SIMPLE_FILT(p1, p0, q0, q1, mask); - ILVRL_B2_SH(q0, p0, tmp1, tmp0); - - src -= 1; - ST2x4_UB(tmp1, 0, src, pitch); - src += 4 * pitch; - ST2x4_UB(tmp1, 4, src, pitch); - src += 4 * pitch; - ST2x4_UB(tmp0, 0, src, pitch); - src += 4 * pitch; - ST2x4_UB(tmp0, 4, src, pitch); - src += 4 * pitch; -} - -static void loop_filter_horizontal_edge_uv_msa(uint8_t *src_u, uint8_t *src_v, - int32_t pitch, - const uint8_t b_limit_in, - const uint8_t limit_in, - const uint8_t thresh_in) { - uint64_t p1_d, p0_d, q0_d, q1_d; - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - v16u8 mask, hev, flat, thresh, limit, b_limit; - v16u8 p3_u, p2_u, p1_u, p0_u, q3_u, q2_u, q1_u, q0_u; - v16u8 p3_v, p2_v, p1_v, p0_v, q3_v, q2_v, q1_v, q0_v; - - thresh = (v16u8)__msa_fill_b(thresh_in); - limit = (v16u8)__msa_fill_b(limit_in); - b_limit = (v16u8)__msa_fill_b(b_limit_in); - - src_u = src_u - (pitch << 2); - LD_UB8(src_u, pitch, p3_u, p2_u, p1_u, p0_u, q0_u, q1_u, q2_u, q3_u); - src_u += (5 * pitch); - src_v = src_v - (pitch << 2); - LD_UB8(src_v, pitch, p3_v, p2_v, p1_v, p0_v, q0_v, q1_v, q2_v, q3_v); - src_v += (5 * pitch); - - /* right 8 element of p3 are u pixel and - left 8 element of p3 are v pixel */ - ILVR_D4_UB(p3_v, p3_u, p2_v, p2_u, p1_v, p1_u, p0_v, p0_u, p3, p2, p1, p0); - ILVR_D4_UB(q0_v, q0_u, q1_v, q1_u, q2_v, q2_u, q3_v, q3_u, q0, q1, q2, q3); - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP8_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev); - - p1_d = __msa_copy_u_d((v2i64)p1, 0); - p0_d = __msa_copy_u_d((v2i64)p0, 0); - q0_d = __msa_copy_u_d((v2i64)q0, 0); - q1_d = __msa_copy_u_d((v2i64)q1, 0); - SD4(q1_d, q0_d, p0_d, p1_d, src_u, (-pitch)); - - p1_d = __msa_copy_u_d((v2i64)p1, 1); - p0_d = __msa_copy_u_d((v2i64)p0, 1); - q0_d = __msa_copy_u_d((v2i64)q0, 1); - q1_d = __msa_copy_u_d((v2i64)q1, 1); - SD4(q1_d, q0_d, p0_d, p1_d, src_v, (-pitch)); -} - -static void loop_filter_vertical_edge_uv_msa(uint8_t *src_u, uint8_t *src_v, - int32_t pitch, - const uint8_t b_limit_in, - const uint8_t limit_in, - const uint8_t thresh_in) { - uint8_t *temp_src_u, *temp_src_v; - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - v16u8 mask, hev, flat, thresh, limit, b_limit; - v16u8 row0, row1, row2, row3, row4, row5, row6, row7, row8; - v16u8 row9, row10, row11, row12, row13, row14, row15; - v4i32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; - - thresh = (v16u8)__msa_fill_b(thresh_in); - limit = (v16u8)__msa_fill_b(limit_in); - b_limit = (v16u8)__msa_fill_b(b_limit_in); - - LD_UB8(src_u - 4, pitch, row0, row1, row2, row3, row4, row5, row6, row7); - LD_UB8(src_v - 4, pitch, row8, row9, row10, row11, row12, row13, row14, - row15); - TRANSPOSE16x8_UB_UB(row0, row1, row2, row3, row4, row5, row6, row7, row8, - row9, row10, row11, row12, row13, row14, row15, p3, p2, - p1, p0, q0, q1, q2, q3); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP8_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev); - ILVR_B2_SW(p0, p1, q1, q0, tmp0, tmp1); - ILVRL_H2_SW(tmp1, tmp0, tmp2, tmp3); - tmp0 = (v4i32)__msa_ilvl_b((v16i8)p0, (v16i8)p1); - tmp1 = (v4i32)__msa_ilvl_b((v16i8)q1, (v16i8)q0); - ILVRL_H2_SW(tmp1, tmp0, tmp4, tmp5); - - temp_src_u = src_u - 2; - ST4x4_UB(tmp2, tmp2, 0, 1, 2, 3, temp_src_u, pitch); - temp_src_u += 4 * pitch; - ST4x4_UB(tmp3, tmp3, 0, 1, 2, 3, temp_src_u, pitch); - - temp_src_v = src_v - 2; - ST4x4_UB(tmp4, tmp4, 0, 1, 2, 3, temp_src_v, pitch); - temp_src_v += 4 * pitch; - ST4x4_UB(tmp5, tmp5, 0, 1, 2, 3, temp_src_v, pitch); -} - -void vp8_loop_filter_mbh_msa(uint8_t *src_y, uint8_t *src_u, uint8_t *src_v, - int32_t pitch_y, int32_t pitch_u_v, - loop_filter_info *lpf_info_ptr) { - mbloop_filter_horizontal_edge_y_msa(src_y, pitch_y, *lpf_info_ptr->mblim, - *lpf_info_ptr->lim, - *lpf_info_ptr->hev_thr); - if (src_u) { - mbloop_filter_horizontal_edge_uv_msa( - src_u, src_v, pitch_u_v, *lpf_info_ptr->mblim, *lpf_info_ptr->lim, - *lpf_info_ptr->hev_thr); - } -} - -void vp8_loop_filter_mbv_msa(uint8_t *src_y, uint8_t *src_u, uint8_t *src_v, - int32_t pitch_y, int32_t pitch_u_v, - loop_filter_info *lpf_info_ptr) { - mbloop_filter_vertical_edge_y_msa(src_y, pitch_y, *lpf_info_ptr->mblim, - *lpf_info_ptr->lim, *lpf_info_ptr->hev_thr); - if (src_u) { - mbloop_filter_vertical_edge_uv_msa(src_u, src_v, pitch_u_v, - *lpf_info_ptr->mblim, *lpf_info_ptr->lim, - *lpf_info_ptr->hev_thr); - } -} - -void vp8_loop_filter_bh_msa(uint8_t *src_y, uint8_t *src_u, uint8_t *src_v, - int32_t pitch_y, int32_t pitch_u_v, - loop_filter_info *lpf_info_ptr) { - loop_filter_horizontal_4_dual_msa(src_y + 4 * pitch_y, pitch_y, - lpf_info_ptr->blim, lpf_info_ptr->lim, - lpf_info_ptr->hev_thr, lpf_info_ptr->blim, - lpf_info_ptr->lim, lpf_info_ptr->hev_thr); - loop_filter_horizontal_4_dual_msa(src_y + 8 * pitch_y, pitch_y, - lpf_info_ptr->blim, lpf_info_ptr->lim, - lpf_info_ptr->hev_thr, lpf_info_ptr->blim, - lpf_info_ptr->lim, lpf_info_ptr->hev_thr); - loop_filter_horizontal_4_dual_msa(src_y + 12 * pitch_y, pitch_y, - lpf_info_ptr->blim, lpf_info_ptr->lim, - lpf_info_ptr->hev_thr, lpf_info_ptr->blim, - lpf_info_ptr->lim, lpf_info_ptr->hev_thr); - if (src_u) { - loop_filter_horizontal_edge_uv_msa( - src_u + (4 * pitch_u_v), src_v + (4 * pitch_u_v), pitch_u_v, - *lpf_info_ptr->blim, *lpf_info_ptr->lim, *lpf_info_ptr->hev_thr); - } -} - -void vp8_loop_filter_bv_msa(uint8_t *src_y, uint8_t *src_u, uint8_t *src_v, - int32_t pitch_y, int32_t pitch_u_v, - loop_filter_info *lpf_info_ptr) { - loop_filter_vertical_4_dual_msa(src_y + 4, pitch_y, lpf_info_ptr->blim, - lpf_info_ptr->lim, lpf_info_ptr->hev_thr, - lpf_info_ptr->blim, lpf_info_ptr->lim, - lpf_info_ptr->hev_thr); - loop_filter_vertical_4_dual_msa(src_y + 8, pitch_y, lpf_info_ptr->blim, - lpf_info_ptr->lim, lpf_info_ptr->hev_thr, - lpf_info_ptr->blim, lpf_info_ptr->lim, - lpf_info_ptr->hev_thr); - loop_filter_vertical_4_dual_msa(src_y + 12, pitch_y, lpf_info_ptr->blim, - lpf_info_ptr->lim, lpf_info_ptr->hev_thr, - lpf_info_ptr->blim, lpf_info_ptr->lim, - lpf_info_ptr->hev_thr); - if (src_u) { - loop_filter_vertical_edge_uv_msa(src_u + 4, src_v + 4, pitch_u_v, - *lpf_info_ptr->blim, *lpf_info_ptr->lim, - *lpf_info_ptr->hev_thr); - } -} - -void vp8_loop_filter_bhs_msa(uint8_t *src_y, int32_t pitch_y, - const uint8_t *b_limit_ptr) { - vp8_loop_filter_simple_horizontal_edge_msa(src_y + (4 * pitch_y), pitch_y, - b_limit_ptr); - vp8_loop_filter_simple_horizontal_edge_msa(src_y + (8 * pitch_y), pitch_y, - b_limit_ptr); - vp8_loop_filter_simple_horizontal_edge_msa(src_y + (12 * pitch_y), pitch_y, - b_limit_ptr); -} - -void vp8_loop_filter_bvs_msa(uint8_t *src_y, int32_t pitch_y, - const uint8_t *b_limit_ptr) { - vp8_loop_filter_simple_vertical_edge_msa(src_y + 4, pitch_y, b_limit_ptr); - vp8_loop_filter_simple_vertical_edge_msa(src_y + 8, pitch_y, b_limit_ptr); - vp8_loop_filter_simple_vertical_edge_msa(src_y + 12, pitch_y, b_limit_ptr); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/mfqe_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/mfqe_msa.c deleted file mode 100644 index 9aac95b2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/mfqe_msa.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vp8/common/postproc.h" -#include "vp8/common/mips/msa/vp8_macros_msa.h" - -static void filter_by_weight8x8_msa(uint8_t *src_ptr, int32_t src_stride, - uint8_t *dst_ptr, int32_t dst_stride, - int32_t src_weight) { - int32_t dst_weight = (1 << MFQE_PRECISION) - src_weight; - int32_t row; - uint64_t src0_d, src1_d, dst0_d, dst1_d; - v16i8 src0 = { 0 }; - v16i8 src1 = { 0 }; - v16i8 dst0 = { 0 }; - v16i8 dst1 = { 0 }; - v8i16 src_wt, dst_wt, res_h_r, res_h_l, src_r, src_l, dst_r, dst_l; - - src_wt = __msa_fill_h(src_weight); - dst_wt = __msa_fill_h(dst_weight); - - for (row = 2; row--;) { - LD2(src_ptr, src_stride, src0_d, src1_d); - src_ptr += (2 * src_stride); - LD2(dst_ptr, dst_stride, dst0_d, dst1_d); - INSERT_D2_SB(src0_d, src1_d, src0); - INSERT_D2_SB(dst0_d, dst1_d, dst0); - - LD2(src_ptr, src_stride, src0_d, src1_d); - src_ptr += (2 * src_stride); - LD2((dst_ptr + 2 * dst_stride), dst_stride, dst0_d, dst1_d); - INSERT_D2_SB(src0_d, src1_d, src1); - INSERT_D2_SB(dst0_d, dst1_d, dst1); - - UNPCK_UB_SH(src0, src_r, src_l); - UNPCK_UB_SH(dst0, dst_r, dst_l); - res_h_r = (src_r * src_wt); - res_h_r += (dst_r * dst_wt); - res_h_l = (src_l * src_wt); - res_h_l += (dst_l * dst_wt); - SRARI_H2_SH(res_h_r, res_h_l, MFQE_PRECISION); - dst0 = (v16i8)__msa_pckev_b((v16i8)res_h_l, (v16i8)res_h_r); - ST8x2_UB(dst0, dst_ptr, dst_stride); - dst_ptr += (2 * dst_stride); - - UNPCK_UB_SH(src1, src_r, src_l); - UNPCK_UB_SH(dst1, dst_r, dst_l); - res_h_r = (src_r * src_wt); - res_h_r += (dst_r * dst_wt); - res_h_l = (src_l * src_wt); - res_h_l += (dst_l * dst_wt); - SRARI_H2_SH(res_h_r, res_h_l, MFQE_PRECISION); - dst1 = (v16i8)__msa_pckev_b((v16i8)res_h_l, (v16i8)res_h_r); - ST8x2_UB(dst1, dst_ptr, dst_stride); - dst_ptr += (2 * dst_stride); - } -} - -static void filter_by_weight16x16_msa(uint8_t *src_ptr, int32_t src_stride, - uint8_t *dst_ptr, int32_t dst_stride, - int32_t src_weight) { - int32_t dst_weight = (1 << MFQE_PRECISION) - src_weight; - int32_t row; - v16i8 src0, src1, src2, src3; - v16i8 dst0, dst1, dst2, dst3; - v8i16 src_wt, dst_wt; - v8i16 res_h_r, res_h_l; - v8i16 src_r, src_l, dst_r, dst_l; - - src_wt = __msa_fill_h(src_weight); - dst_wt = __msa_fill_h(dst_weight); - - for (row = 4; row--;) { - LD_SB4(src_ptr, src_stride, src0, src1, src2, src3); - src_ptr += (4 * src_stride); - LD_SB4(dst_ptr, dst_stride, dst0, dst1, dst2, dst3); - - UNPCK_UB_SH(src0, src_r, src_l); - UNPCK_UB_SH(dst0, dst_r, dst_l); - res_h_r = (src_r * src_wt); - res_h_r += (dst_r * dst_wt); - res_h_l = (src_l * src_wt); - res_h_l += (dst_l * dst_wt); - SRARI_H2_SH(res_h_r, res_h_l, MFQE_PRECISION); - PCKEV_ST_SB(res_h_r, res_h_l, dst_ptr); - dst_ptr += dst_stride; - - UNPCK_UB_SH(src1, src_r, src_l); - UNPCK_UB_SH(dst1, dst_r, dst_l); - res_h_r = (src_r * src_wt); - res_h_r += (dst_r * dst_wt); - res_h_l = (src_l * src_wt); - res_h_l += (dst_l * dst_wt); - SRARI_H2_SH(res_h_r, res_h_l, MFQE_PRECISION); - PCKEV_ST_SB(res_h_r, res_h_l, dst_ptr); - dst_ptr += dst_stride; - - UNPCK_UB_SH(src2, src_r, src_l); - UNPCK_UB_SH(dst2, dst_r, dst_l); - res_h_r = (src_r * src_wt); - res_h_r += (dst_r * dst_wt); - res_h_l = (src_l * src_wt); - res_h_l += (dst_l * dst_wt); - SRARI_H2_SH(res_h_r, res_h_l, MFQE_PRECISION); - PCKEV_ST_SB(res_h_r, res_h_l, dst_ptr); - dst_ptr += dst_stride; - - UNPCK_UB_SH(src3, src_r, src_l); - UNPCK_UB_SH(dst3, dst_r, dst_l); - res_h_r = (src_r * src_wt); - res_h_r += (dst_r * dst_wt); - res_h_l = (src_l * src_wt); - res_h_l += (dst_l * dst_wt); - SRARI_H2_SH(res_h_r, res_h_l, MFQE_PRECISION); - PCKEV_ST_SB(res_h_r, res_h_l, dst_ptr); - dst_ptr += dst_stride; - } -} - -void vp8_filter_by_weight16x16_msa(uint8_t *src_ptr, int32_t src_stride, - uint8_t *dst_ptr, int32_t dst_stride, - int32_t src_weight) { - filter_by_weight16x16_msa(src_ptr, src_stride, dst_ptr, dst_stride, - src_weight); -} - -void vp8_filter_by_weight8x8_msa(uint8_t *src_ptr, int32_t src_stride, - uint8_t *dst_ptr, int32_t dst_stride, - int32_t src_weight) { - filter_by_weight8x8_msa(src_ptr, src_stride, dst_ptr, dst_stride, src_weight); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/sixtap_filter_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/sixtap_filter_msa.c deleted file mode 100644 index 3a1bb7cd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/sixtap_filter_msa.c +++ /dev/null @@ -1,1738 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vpx_ports/mem.h" -#include "vp8/common/filter.h" -#include "vp8/common/mips/msa/vp8_macros_msa.h" - -DECLARE_ALIGNED(16, static const int8_t, vp8_subpel_filters_msa[7][8]) = { - { 0, -6, 123, 12, -1, 0, 0, 0 }, - { 2, -11, 108, 36, -8, 1, 0, 0 }, /* New 1/4 pel 6 tap filter */ - { 0, -9, 93, 50, -6, 0, 0, 0 }, - { 3, -16, 77, 77, -16, 3, 0, 0 }, /* New 1/2 pel 6 tap filter */ - { 0, -6, 50, 93, -9, 0, 0, 0 }, - { 1, -8, 36, 108, -11, 2, 0, 0 }, /* New 1/4 pel 6 tap filter */ - { 0, -1, 12, 123, -6, 0, 0, 0 }, -}; - -static const uint8_t vp8_mc_filt_mask_arr[16 * 3] = { - /* 8 width cases */ - 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, - /* 4 width cases */ - 0, 1, 1, 2, 2, 3, 3, 4, 16, 17, 17, 18, 18, 19, 19, 20, - /* 4 width cases */ - 8, 9, 9, 10, 10, 11, 11, 12, 24, 25, 25, 26, 26, 27, 27, 28 -}; - -#define HORIZ_6TAP_FILT(src0, src1, mask0, mask1, mask2, filt_h0, filt_h1, \ - filt_h2) \ - ({ \ - v16i8 _6tap_vec0_m, _6tap_vec1_m, _6tap_vec2_m; \ - v8i16 _6tap_out_m; \ - \ - VSHF_B3_SB(src0, src1, src0, src1, src0, src1, mask0, mask1, mask2, \ - _6tap_vec0_m, _6tap_vec1_m, _6tap_vec2_m); \ - _6tap_out_m = DPADD_SH3_SH(_6tap_vec0_m, _6tap_vec1_m, _6tap_vec2_m, \ - filt_h0, filt_h1, filt_h2); \ - \ - _6tap_out_m = __msa_srari_h(_6tap_out_m, VP8_FILTER_SHIFT); \ - _6tap_out_m = __msa_sat_s_h(_6tap_out_m, 7); \ - \ - _6tap_out_m; \ - }) - -#define HORIZ_6TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, \ - mask2, filt0, filt1, filt2, out0, out1) \ - { \ - v16i8 _6tap_4wid_vec0_m, _6tap_4wid_vec1_m, _6tap_4wid_vec2_m, \ - _6tap_4wid_vec3_m, _6tap_4wid_vec4_m, _6tap_4wid_vec5_m; \ - \ - VSHF_B2_SB(src0, src1, src2, src3, mask0, mask0, _6tap_4wid_vec0_m, \ - _6tap_4wid_vec1_m); \ - DOTP_SB2_SH(_6tap_4wid_vec0_m, _6tap_4wid_vec1_m, filt0, filt0, out0, \ - out1); \ - VSHF_B2_SB(src0, src1, src2, src3, mask1, mask1, _6tap_4wid_vec2_m, \ - _6tap_4wid_vec3_m); \ - DPADD_SB2_SH(_6tap_4wid_vec2_m, _6tap_4wid_vec3_m, filt1, filt1, out0, \ - out1); \ - VSHF_B2_SB(src0, src1, src2, src3, mask2, mask2, _6tap_4wid_vec4_m, \ - _6tap_4wid_vec5_m); \ - DPADD_SB2_SH(_6tap_4wid_vec4_m, _6tap_4wid_vec5_m, filt2, filt2, out0, \ - out1); \ - } - -#define HORIZ_6TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, \ - mask2, filt0, filt1, filt2, out0, out1, \ - out2, out3) \ - { \ - v16i8 _6tap_8wid_vec0_m, _6tap_8wid_vec1_m, _6tap_8wid_vec2_m, \ - _6tap_8wid_vec3_m, _6tap_8wid_vec4_m, _6tap_8wid_vec5_m, \ - _6tap_8wid_vec6_m, _6tap_8wid_vec7_m; \ - \ - VSHF_B2_SB(src0, src0, src1, src1, mask0, mask0, _6tap_8wid_vec0_m, \ - _6tap_8wid_vec1_m); \ - VSHF_B2_SB(src2, src2, src3, src3, mask0, mask0, _6tap_8wid_vec2_m, \ - _6tap_8wid_vec3_m); \ - DOTP_SB4_SH(_6tap_8wid_vec0_m, _6tap_8wid_vec1_m, _6tap_8wid_vec2_m, \ - _6tap_8wid_vec3_m, filt0, filt0, filt0, filt0, out0, out1, \ - out2, out3); \ - VSHF_B2_SB(src0, src0, src1, src1, mask1, mask1, _6tap_8wid_vec0_m, \ - _6tap_8wid_vec1_m); \ - VSHF_B2_SB(src2, src2, src3, src3, mask1, mask1, _6tap_8wid_vec2_m, \ - _6tap_8wid_vec3_m); \ - VSHF_B2_SB(src0, src0, src1, src1, mask2, mask2, _6tap_8wid_vec4_m, \ - _6tap_8wid_vec5_m); \ - VSHF_B2_SB(src2, src2, src3, src3, mask2, mask2, _6tap_8wid_vec6_m, \ - _6tap_8wid_vec7_m); \ - DPADD_SB4_SH(_6tap_8wid_vec0_m, _6tap_8wid_vec1_m, _6tap_8wid_vec2_m, \ - _6tap_8wid_vec3_m, filt1, filt1, filt1, filt1, out0, out1, \ - out2, out3); \ - DPADD_SB4_SH(_6tap_8wid_vec4_m, _6tap_8wid_vec5_m, _6tap_8wid_vec6_m, \ - _6tap_8wid_vec7_m, filt2, filt2, filt2, filt2, out0, out1, \ - out2, out3); \ - } - -#define FILT_4TAP_DPADD_S_H(vec0, vec1, filt0, filt1) \ - ({ \ - v8i16 _4tap_dpadd_tmp0; \ - \ - _4tap_dpadd_tmp0 = __msa_dotp_s_h((v16i8)vec0, (v16i8)filt0); \ - _4tap_dpadd_tmp0 = \ - __msa_dpadd_s_h(_4tap_dpadd_tmp0, (v16i8)vec1, (v16i8)filt1); \ - \ - _4tap_dpadd_tmp0; \ - }) - -#define HORIZ_4TAP_FILT(src0, src1, mask0, mask1, filt_h0, filt_h1) \ - ({ \ - v16i8 _4tap_vec0_m, _4tap_vec1_m; \ - v8i16 _4tap_out_m; \ - \ - VSHF_B2_SB(src0, src1, src0, src1, mask0, mask1, _4tap_vec0_m, \ - _4tap_vec1_m); \ - _4tap_out_m = \ - FILT_4TAP_DPADD_S_H(_4tap_vec0_m, _4tap_vec1_m, filt_h0, filt_h1); \ - \ - _4tap_out_m = __msa_srari_h(_4tap_out_m, VP8_FILTER_SHIFT); \ - _4tap_out_m = __msa_sat_s_h(_4tap_out_m, 7); \ - \ - _4tap_out_m; \ - }) - -#define HORIZ_4TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, \ - filt0, filt1, out0, out1) \ - { \ - v16i8 _4tap_4wid_vec0_m, _4tap_4wid_vec1_m, _4tap_4wid_vec2_m, \ - _4tap_4wid_vec3_m; \ - \ - VSHF_B2_SB(src0, src1, src2, src3, mask0, mask0, _4tap_4wid_vec0_m, \ - _4tap_4wid_vec1_m); \ - DOTP_SB2_SH(_4tap_4wid_vec0_m, _4tap_4wid_vec1_m, filt0, filt0, out0, \ - out1); \ - VSHF_B2_SB(src0, src1, src2, src3, mask1, mask1, _4tap_4wid_vec2_m, \ - _4tap_4wid_vec3_m); \ - DPADD_SB2_SH(_4tap_4wid_vec2_m, _4tap_4wid_vec3_m, filt1, filt1, out0, \ - out1); \ - } - -#define HORIZ_4TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, \ - filt0, filt1, out0, out1, out2, out3) \ - { \ - v16i8 _4tap_8wid_vec0_m, _4tap_8wid_vec1_m, _4tap_8wid_vec2_m, \ - _4tap_8wid_vec3_m; \ - \ - VSHF_B2_SB(src0, src0, src1, src1, mask0, mask0, _4tap_8wid_vec0_m, \ - _4tap_8wid_vec1_m); \ - VSHF_B2_SB(src2, src2, src3, src3, mask0, mask0, _4tap_8wid_vec2_m, \ - _4tap_8wid_vec3_m); \ - DOTP_SB4_SH(_4tap_8wid_vec0_m, _4tap_8wid_vec1_m, _4tap_8wid_vec2_m, \ - _4tap_8wid_vec3_m, filt0, filt0, filt0, filt0, out0, out1, \ - out2, out3); \ - VSHF_B2_SB(src0, src0, src1, src1, mask1, mask1, _4tap_8wid_vec0_m, \ - _4tap_8wid_vec1_m); \ - VSHF_B2_SB(src2, src2, src3, src3, mask1, mask1, _4tap_8wid_vec2_m, \ - _4tap_8wid_vec3_m); \ - DPADD_SB4_SH(_4tap_8wid_vec0_m, _4tap_8wid_vec1_m, _4tap_8wid_vec2_m, \ - _4tap_8wid_vec3_m, filt1, filt1, filt1, filt1, out0, out1, \ - out2, out3); \ - } - -static void common_hz_6t_4x4_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter) { - v16i8 src0, src1, src2, src3, filt0, filt1, filt2; - v16u8 mask0, mask1, mask2, out; - v8i16 filt, out0, out1; - - mask0 = LD_UB(&vp8_mc_filt_mask_arr[16]); - src -= 2; - - filt = LD_SH(filter); - SPLATI_H3_SB(filt, 0, 1, 2, filt0, filt1, filt2); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - HORIZ_6TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, filt0, - filt1, filt2, out0, out1); - SRARI_H2_SH(out0, out1, VP8_FILTER_SHIFT); - SAT_SH2_SH(out0, out1, 7); - out = PCKEV_XORI128_UB(out0, out1); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); -} - -static void common_hz_6t_4x8_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter) { - v16i8 src0, src1, src2, src3, filt0, filt1, filt2; - v16u8 mask0, mask1, mask2, out; - v8i16 filt, out0, out1, out2, out3; - - mask0 = LD_UB(&vp8_mc_filt_mask_arr[16]); - src -= 2; - - filt = LD_SH(filter); - SPLATI_H3_SB(filt, 0, 1, 2, filt0, filt1, filt2); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - src += (4 * src_stride); - HORIZ_6TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, filt0, - filt1, filt2, out0, out1); - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - HORIZ_6TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, filt0, - filt1, filt2, out2, out3); - SRARI_H4_SH(out0, out1, out2, out3, VP8_FILTER_SHIFT); - SAT_SH4_SH(out0, out1, out2, out3, 7); - out = PCKEV_XORI128_UB(out0, out1); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - out = PCKEV_XORI128_UB(out2, out3); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); -} - -static void common_hz_6t_4w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - if (4 == height) { - common_hz_6t_4x4_msa(src, src_stride, dst, dst_stride, filter); - } else if (8 == height) { - common_hz_6t_4x8_msa(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_hz_6t_8w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, filt0, filt1, filt2; - v16u8 mask0, mask1, mask2, tmp0, tmp1; - v8i16 filt, out0, out1, out2, out3; - - mask0 = LD_UB(&vp8_mc_filt_mask_arr[0]); - src -= 2; - - filt = LD_SH(filter); - SPLATI_H3_SB(filt, 0, 1, 2, filt0, filt1, filt2); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - src += (4 * src_stride); - HORIZ_6TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, filt0, - filt1, filt2, out0, out1, out2, out3); - SRARI_H4_SH(out0, out1, out2, out3, VP8_FILTER_SHIFT); - SAT_SH4_SH(out0, out1, out2, out3, 7); - tmp0 = PCKEV_XORI128_UB(out0, out1); - tmp1 = PCKEV_XORI128_UB(out2, out3); - ST8x4_UB(tmp0, tmp1, dst, dst_stride); - dst += (4 * dst_stride); - - for (loop_cnt = (height >> 2) - 1; loop_cnt--;) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - src += (4 * src_stride); - HORIZ_6TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - filt0, filt1, filt2, out0, out1, out2, out3); - SRARI_H4_SH(out0, out1, out2, out3, VP8_FILTER_SHIFT); - SAT_SH4_SH(out0, out1, out2, out3, 7); - tmp0 = PCKEV_XORI128_UB(out0, out1); - tmp1 = PCKEV_XORI128_UB(out2, out3); - ST8x4_UB(tmp0, tmp1, dst, dst_stride); - dst += (4 * dst_stride); - } -} - -static void common_hz_6t_16w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, filt0, filt1, filt2; - v16u8 mask0, mask1, mask2, out; - v8i16 filt, out0, out1, out2, out3, out4, out5, out6, out7; - - mask0 = LD_UB(&vp8_mc_filt_mask_arr[0]); - src -= 2; - - filt = LD_SH(filter); - SPLATI_H3_SB(filt, 0, 1, 2, filt0, filt1, filt2); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src2, src4, src6); - LD_SB4(src + 8, src_stride, src1, src3, src5, src7); - XORI_B8_128_SB(src0, src1, src2, src3, src4, src5, src6, src7); - src += (4 * src_stride); - - HORIZ_6TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - filt0, filt1, filt2, out0, out1, out2, out3); - HORIZ_6TAP_8WID_4VECS_FILT(src4, src5, src6, src7, mask0, mask1, mask2, - filt0, filt1, filt2, out4, out5, out6, out7); - SRARI_H4_SH(out0, out1, out2, out3, VP8_FILTER_SHIFT); - SRARI_H4_SH(out4, out5, out6, out7, VP8_FILTER_SHIFT); - SAT_SH4_SH(out0, out1, out2, out3, 7); - SAT_SH4_SH(out4, out5, out6, out7, 7); - out = PCKEV_XORI128_UB(out0, out1); - ST_UB(out, dst); - dst += dst_stride; - out = PCKEV_XORI128_UB(out2, out3); - ST_UB(out, dst); - dst += dst_stride; - out = PCKEV_XORI128_UB(out4, out5); - ST_UB(out, dst); - dst += dst_stride; - out = PCKEV_XORI128_UB(out6, out7); - ST_UB(out, dst); - dst += dst_stride; - } -} - -static void common_vt_6t_4w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; - v16i8 src87_r, src2110, src4332, src6554, src8776, filt0, filt1, filt2; - v16u8 out; - v8i16 filt, out10, out32; - - src -= (2 * src_stride); - - filt = LD_SH(filter); - SPLATI_H3_SB(filt, 0, 1, 2, filt0, filt1, filt2); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - - ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, - src32_r, src43_r); - ILVR_D2_SB(src21_r, src10_r, src43_r, src32_r, src2110, src4332); - XORI_B2_128_SB(src2110, src4332); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src5, src6, src7, src8); - src += (4 * src_stride); - - ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_r, src65_r, - src76_r, src87_r); - ILVR_D2_SB(src65_r, src54_r, src87_r, src76_r, src6554, src8776); - XORI_B2_128_SB(src6554, src8776); - out10 = DPADD_SH3_SH(src2110, src4332, src6554, filt0, filt1, filt2); - out32 = DPADD_SH3_SH(src4332, src6554, src8776, filt0, filt1, filt2); - SRARI_H2_SH(out10, out32, VP8_FILTER_SHIFT); - SAT_SH2_SH(out10, out32, 7); - out = PCKEV_XORI128_UB(out10, out32); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - - src2110 = src6554; - src4332 = src8776; - src4 = src8; - } -} - -static void common_vt_6t_8w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src7, src8, src9, src10; - v16i8 src10_r, src32_r, src76_r, src98_r, src21_r, src43_r, src87_r; - v16i8 src109_r, filt0, filt1, filt2; - v16u8 tmp0, tmp1; - v8i16 filt, out0_r, out1_r, out2_r, out3_r; - - src -= (2 * src_stride); - - filt = LD_SH(filter); - SPLATI_H3_SB(filt, 0, 1, 2, filt0, filt1, filt2); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - - XORI_B5_128_SB(src0, src1, src2, src3, src4); - ILVR_B4_SB(src1, src0, src3, src2, src2, src1, src4, src3, src10_r, src32_r, - src21_r, src43_r); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src7, src8, src9, src10); - XORI_B4_128_SB(src7, src8, src9, src10); - src += (4 * src_stride); - - ILVR_B4_SB(src7, src4, src8, src7, src9, src8, src10, src9, src76_r, - src87_r, src98_r, src109_r); - out0_r = DPADD_SH3_SH(src10_r, src32_r, src76_r, filt0, filt1, filt2); - out1_r = DPADD_SH3_SH(src21_r, src43_r, src87_r, filt0, filt1, filt2); - out2_r = DPADD_SH3_SH(src32_r, src76_r, src98_r, filt0, filt1, filt2); - out3_r = DPADD_SH3_SH(src43_r, src87_r, src109_r, filt0, filt1, filt2); - SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, VP8_FILTER_SHIFT); - SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); - tmp0 = PCKEV_XORI128_UB(out0_r, out1_r); - tmp1 = PCKEV_XORI128_UB(out2_r, out3_r); - ST8x4_UB(tmp0, tmp1, dst, dst_stride); - dst += (4 * dst_stride); - - src10_r = src76_r; - src32_r = src98_r; - src21_r = src87_r; - src43_r = src109_r; - src4 = src10; - } -} - -static void common_vt_6t_16w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; - v16i8 src87_r, src10_l, src32_l, src54_l, src76_l, src21_l, src43_l; - v16i8 src65_l, src87_l, filt0, filt1, filt2; - v16u8 tmp0, tmp1, tmp2, tmp3; - v8i16 out0_r, out1_r, out2_r, out3_r, out0_l, out1_l, out2_l, out3_l, filt; - - src -= (2 * src_stride); - - filt = LD_SH(filter); - SPLATI_H3_SB(filt, 0, 1, 2, filt0, filt1, filt2); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - - XORI_B5_128_SB(src0, src1, src2, src3, src4); - ILVR_B4_SB(src1, src0, src3, src2, src4, src3, src2, src1, src10_r, src32_r, - src43_r, src21_r); - ILVL_B4_SB(src1, src0, src3, src2, src4, src3, src2, src1, src10_l, src32_l, - src43_l, src21_l); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src5, src6, src7, src8); - src += (4 * src_stride); - - XORI_B4_128_SB(src5, src6, src7, src8); - ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_r, src65_r, - src76_r, src87_r); - ILVL_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_l, src65_l, - src76_l, src87_l); - out0_r = DPADD_SH3_SH(src10_r, src32_r, src54_r, filt0, filt1, filt2); - out1_r = DPADD_SH3_SH(src21_r, src43_r, src65_r, filt0, filt1, filt2); - out2_r = DPADD_SH3_SH(src32_r, src54_r, src76_r, filt0, filt1, filt2); - out3_r = DPADD_SH3_SH(src43_r, src65_r, src87_r, filt0, filt1, filt2); - out0_l = DPADD_SH3_SH(src10_l, src32_l, src54_l, filt0, filt1, filt2); - out1_l = DPADD_SH3_SH(src21_l, src43_l, src65_l, filt0, filt1, filt2); - out2_l = DPADD_SH3_SH(src32_l, src54_l, src76_l, filt0, filt1, filt2); - out3_l = DPADD_SH3_SH(src43_l, src65_l, src87_l, filt0, filt1, filt2); - SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, VP8_FILTER_SHIFT); - SRARI_H4_SH(out0_l, out1_l, out2_l, out3_l, VP8_FILTER_SHIFT); - SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); - SAT_SH4_SH(out0_l, out1_l, out2_l, out3_l, 7); - PCKEV_B4_UB(out0_l, out0_r, out1_l, out1_r, out2_l, out2_r, out3_l, out3_r, - tmp0, tmp1, tmp2, tmp3); - XORI_B4_128_UB(tmp0, tmp1, tmp2, tmp3); - ST_UB4(tmp0, tmp1, tmp2, tmp3, dst, dst_stride); - dst += (4 * dst_stride); - - src10_r = src54_r; - src32_r = src76_r; - src21_r = src65_r; - src43_r = src87_r; - src10_l = src54_l; - src32_l = src76_l; - src21_l = src65_l; - src43_l = src87_l; - src4 = src8; - } -} - -static void common_hv_6ht_6vt_4w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16i8 filt_hz0, filt_hz1, filt_hz2; - v16u8 mask0, mask1, mask2, out; - v8i16 tmp0, tmp1; - v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; - v8i16 hz_out7, filt, filt_vt0, filt_vt1, filt_vt2, out0, out1, out2, out3; - - mask0 = LD_UB(&vp8_mc_filt_mask_arr[16]); - src -= (2 + 2 * src_stride); - - filt = LD_SH(filter_horiz); - SPLATI_H3_SB(filt, 0, 1, 2, filt_hz0, filt_hz1, filt_hz2); - filt = LD_SH(filter_vert); - SPLATI_H3_SH(filt, 0, 1, 2, filt_vt0, filt_vt1, filt_vt2); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - - XORI_B5_128_SB(src0, src1, src2, src3, src4); - hz_out0 = HORIZ_6TAP_FILT(src0, src1, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out2 = HORIZ_6TAP_FILT(src2, src3, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out1 = (v8i16)__msa_sldi_b((v16i8)hz_out2, (v16i8)hz_out0, 8); - hz_out3 = HORIZ_6TAP_FILT(src3, src4, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - ILVEV_B2_SH(hz_out0, hz_out1, hz_out2, hz_out3, out0, out1); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB2(src, src_stride, src5, src6); - src += (2 * src_stride); - - XORI_B2_128_SB(src5, src6); - hz_out5 = HORIZ_6TAP_FILT(src5, src6, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - hz_out4 = (v8i16)__msa_sldi_b((v16i8)hz_out5, (v16i8)hz_out3, 8); - - LD_SB2(src, src_stride, src7, src8); - src += (2 * src_stride); - - XORI_B2_128_SB(src7, src8); - hz_out7 = HORIZ_6TAP_FILT(src7, src8, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - hz_out6 = (v8i16)__msa_sldi_b((v16i8)hz_out7, (v16i8)hz_out5, 8); - - out2 = (v8i16)__msa_ilvev_b((v16i8)hz_out5, (v16i8)hz_out4); - tmp0 = DPADD_SH3_SH(out0, out1, out2, filt_vt0, filt_vt1, filt_vt2); - - out3 = (v8i16)__msa_ilvev_b((v16i8)hz_out7, (v16i8)hz_out6); - tmp1 = DPADD_SH3_SH(out1, out2, out3, filt_vt0, filt_vt1, filt_vt2); - - SRARI_H2_SH(tmp0, tmp1, 7); - SAT_SH2_SH(tmp0, tmp1, 7); - out = PCKEV_XORI128_UB(tmp0, tmp1); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - - hz_out3 = hz_out7; - out0 = out2; - out1 = out3; - } -} - -static void common_hv_6ht_6vt_8w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16i8 filt_hz0, filt_hz1, filt_hz2; - v16u8 mask0, mask1, mask2, vec0, vec1; - v8i16 filt, filt_vt0, filt_vt1, filt_vt2; - v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; - v8i16 hz_out7, hz_out8, out0, out1, out2, out3, out4, out5, out6, out7; - v8i16 tmp0, tmp1, tmp2, tmp3; - - mask0 = LD_UB(&vp8_mc_filt_mask_arr[0]); - src -= (2 + 2 * src_stride); - - filt = LD_SH(filter_horiz); - SPLATI_H3_SB(filt, 0, 1, 2, filt_hz0, filt_hz1, filt_hz2); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - - XORI_B5_128_SB(src0, src1, src2, src3, src4); - hz_out0 = HORIZ_6TAP_FILT(src0, src0, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out1 = HORIZ_6TAP_FILT(src1, src1, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out2 = HORIZ_6TAP_FILT(src2, src2, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out3 = HORIZ_6TAP_FILT(src3, src3, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out4 = HORIZ_6TAP_FILT(src4, src4, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - - filt = LD_SH(filter_vert); - SPLATI_H3_SH(filt, 0, 1, 2, filt_vt0, filt_vt1, filt_vt2); - - ILVEV_B2_SH(hz_out0, hz_out1, hz_out2, hz_out3, out0, out1); - ILVEV_B2_SH(hz_out1, hz_out2, hz_out3, hz_out4, out3, out4); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src5, src6, src7, src8); - src += (4 * src_stride); - - XORI_B4_128_SB(src5, src6, src7, src8); - hz_out5 = HORIZ_6TAP_FILT(src5, src5, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - out2 = (v8i16)__msa_ilvev_b((v16i8)hz_out5, (v16i8)hz_out4); - tmp0 = DPADD_SH3_SH(out0, out1, out2, filt_vt0, filt_vt1, filt_vt2); - - hz_out6 = HORIZ_6TAP_FILT(src6, src6, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - out5 = (v8i16)__msa_ilvev_b((v16i8)hz_out6, (v16i8)hz_out5); - tmp1 = DPADD_SH3_SH(out3, out4, out5, filt_vt0, filt_vt1, filt_vt2); - - hz_out7 = HORIZ_6TAP_FILT(src7, src7, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - out7 = (v8i16)__msa_ilvev_b((v16i8)hz_out7, (v16i8)hz_out6); - tmp2 = DPADD_SH3_SH(out1, out2, out7, filt_vt0, filt_vt1, filt_vt2); - - hz_out8 = HORIZ_6TAP_FILT(src8, src8, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - out6 = (v8i16)__msa_ilvev_b((v16i8)hz_out8, (v16i8)hz_out7); - tmp3 = DPADD_SH3_SH(out4, out5, out6, filt_vt0, filt_vt1, filt_vt2); - - SRARI_H4_SH(tmp0, tmp1, tmp2, tmp3, 7); - SAT_SH4_SH(tmp0, tmp1, tmp2, tmp3, 7); - vec0 = PCKEV_XORI128_UB(tmp0, tmp1); - vec1 = PCKEV_XORI128_UB(tmp2, tmp3); - ST8x4_UB(vec0, vec1, dst, dst_stride); - dst += (4 * dst_stride); - - hz_out4 = hz_out8; - out0 = out2; - out1 = out7; - out3 = out5; - out4 = out6; - } -} - -static void common_hv_6ht_6vt_16w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 2; multiple8_cnt--;) { - common_hv_6ht_6vt_8w_msa(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - src += 8; - dst += 8; - } -} - -static void common_hz_4t_4x4_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter) { - v16i8 src0, src1, src2, src3, filt0, filt1, mask0, mask1; - v8i16 filt, out0, out1; - v16u8 out; - - mask0 = LD_SB(&vp8_mc_filt_mask_arr[16]); - src -= 1; - - filt = LD_SH(filter); - SPLATI_H2_SB(filt, 0, 1, filt0, filt1); - - mask1 = mask0 + 2; - - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - HORIZ_4TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, filt0, filt1, - out0, out1); - SRARI_H2_SH(out0, out1, VP8_FILTER_SHIFT); - SAT_SH2_SH(out0, out1, 7); - out = PCKEV_XORI128_UB(out0, out1); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); -} - -static void common_hz_4t_4x8_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter) { - v16i8 src0, src1, src2, src3, filt0, filt1, mask0, mask1; - v16u8 out; - v8i16 filt, out0, out1, out2, out3; - - mask0 = LD_SB(&vp8_mc_filt_mask_arr[16]); - src -= 1; - - filt = LD_SH(filter); - SPLATI_H2_SB(filt, 0, 1, filt0, filt1); - - mask1 = mask0 + 2; - - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - XORI_B4_128_SB(src0, src1, src2, src3); - HORIZ_4TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, filt0, filt1, - out0, out1); - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - HORIZ_4TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, filt0, filt1, - out2, out3); - SRARI_H4_SH(out0, out1, out2, out3, VP8_FILTER_SHIFT); - SAT_SH4_SH(out0, out1, out2, out3, 7); - out = PCKEV_XORI128_UB(out0, out1); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - out = PCKEV_XORI128_UB(out2, out3); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); -} - -static void common_hz_4t_4w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - if (4 == height) { - common_hz_4t_4x4_msa(src, src_stride, dst, dst_stride, filter); - } else if (8 == height) { - common_hz_4t_4x8_msa(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_hz_4t_8w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, filt0, filt1, mask0, mask1; - v16u8 tmp0, tmp1; - v8i16 filt, out0, out1, out2, out3; - - mask0 = LD_SB(&vp8_mc_filt_mask_arr[0]); - src -= 1; - - filt = LD_SH(filter); - SPLATI_H2_SB(filt, 0, 1, filt0, filt1); - - mask1 = mask0 + 2; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - XORI_B4_128_SB(src0, src1, src2, src3); - HORIZ_4TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, filt0, - filt1, out0, out1, out2, out3); - SRARI_H4_SH(out0, out1, out2, out3, VP8_FILTER_SHIFT); - SAT_SH4_SH(out0, out1, out2, out3, 7); - tmp0 = PCKEV_XORI128_UB(out0, out1); - tmp1 = PCKEV_XORI128_UB(out2, out3); - ST8x4_UB(tmp0, tmp1, dst, dst_stride); - dst += (4 * dst_stride); - } -} - -static void common_hz_4t_16w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7; - v16i8 filt0, filt1, mask0, mask1; - v8i16 filt, out0, out1, out2, out3, out4, out5, out6, out7; - v16u8 out; - - mask0 = LD_SB(&vp8_mc_filt_mask_arr[0]); - src -= 1; - - filt = LD_SH(filter); - SPLATI_H2_SB(filt, 0, 1, filt0, filt1); - - mask1 = mask0 + 2; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src2, src4, src6); - LD_SB4(src + 8, src_stride, src1, src3, src5, src7); - src += (4 * src_stride); - - XORI_B8_128_SB(src0, src1, src2, src3, src4, src5, src6, src7); - HORIZ_4TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, filt0, - filt1, out0, out1, out2, out3); - HORIZ_4TAP_8WID_4VECS_FILT(src4, src5, src6, src7, mask0, mask1, filt0, - filt1, out4, out5, out6, out7); - SRARI_H4_SH(out0, out1, out2, out3, VP8_FILTER_SHIFT); - SRARI_H4_SH(out4, out5, out6, out7, VP8_FILTER_SHIFT); - SAT_SH4_SH(out0, out1, out2, out3, 7); - SAT_SH4_SH(out4, out5, out6, out7, 7); - out = PCKEV_XORI128_UB(out0, out1); - ST_UB(out, dst); - dst += dst_stride; - out = PCKEV_XORI128_UB(out2, out3); - ST_UB(out, dst); - dst += dst_stride; - out = PCKEV_XORI128_UB(out4, out5); - ST_UB(out, dst); - dst += dst_stride; - out = PCKEV_XORI128_UB(out6, out7); - ST_UB(out, dst); - dst += dst_stride; - } -} - -static void common_vt_4t_4w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5; - v16i8 src10_r, src32_r, src54_r, src21_r, src43_r, src65_r; - v16i8 src2110, src4332, filt0, filt1; - v8i16 filt, out10, out32; - v16u8 out; - - src -= src_stride; - - filt = LD_SH(filter); - SPLATI_H2_SB(filt, 0, 1, filt0, filt1); - - LD_SB3(src, src_stride, src0, src1, src2); - src += (3 * src_stride); - - ILVR_B2_SB(src1, src0, src2, src1, src10_r, src21_r); - - src2110 = (v16i8)__msa_ilvr_d((v2i64)src21_r, (v2i64)src10_r); - src2110 = (v16i8)__msa_xori_b((v16u8)src2110, 128); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB3(src, src_stride, src3, src4, src5); - src += (3 * src_stride); - ILVR_B2_SB(src3, src2, src4, src3, src32_r, src43_r); - src4332 = (v16i8)__msa_ilvr_d((v2i64)src43_r, (v2i64)src32_r); - src4332 = (v16i8)__msa_xori_b((v16u8)src4332, 128); - out10 = FILT_4TAP_DPADD_S_H(src2110, src4332, filt0, filt1); - - src2 = LD_SB(src); - src += (src_stride); - ILVR_B2_SB(src5, src4, src2, src5, src54_r, src65_r); - src2110 = (v16i8)__msa_ilvr_d((v2i64)src65_r, (v2i64)src54_r); - src2110 = (v16i8)__msa_xori_b((v16u8)src2110, 128); - out32 = FILT_4TAP_DPADD_S_H(src4332, src2110, filt0, filt1); - SRARI_H2_SH(out10, out32, VP8_FILTER_SHIFT); - SAT_SH2_SH(out10, out32, 7); - out = PCKEV_XORI128_UB(out10, out32); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - } -} - -static void common_vt_4t_8w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src7, src8, src9, src10; - v16i8 src10_r, src72_r, src98_r, src21_r, src87_r, src109_r, filt0, filt1; - v16u8 tmp0, tmp1; - v8i16 filt, out0_r, out1_r, out2_r, out3_r; - - src -= src_stride; - - filt = LD_SH(filter); - SPLATI_H2_SB(filt, 0, 1, filt0, filt1); - - LD_SB3(src, src_stride, src0, src1, src2); - src += (3 * src_stride); - - XORI_B3_128_SB(src0, src1, src2); - ILVR_B2_SB(src1, src0, src2, src1, src10_r, src21_r); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src7, src8, src9, src10); - src += (4 * src_stride); - - XORI_B4_128_SB(src7, src8, src9, src10); - ILVR_B4_SB(src7, src2, src8, src7, src9, src8, src10, src9, src72_r, - src87_r, src98_r, src109_r); - out0_r = FILT_4TAP_DPADD_S_H(src10_r, src72_r, filt0, filt1); - out1_r = FILT_4TAP_DPADD_S_H(src21_r, src87_r, filt0, filt1); - out2_r = FILT_4TAP_DPADD_S_H(src72_r, src98_r, filt0, filt1); - out3_r = FILT_4TAP_DPADD_S_H(src87_r, src109_r, filt0, filt1); - SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, VP8_FILTER_SHIFT); - SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); - tmp0 = PCKEV_XORI128_UB(out0_r, out1_r); - tmp1 = PCKEV_XORI128_UB(out2_r, out3_r); - ST8x4_UB(tmp0, tmp1, dst, dst_stride); - dst += (4 * dst_stride); - - src10_r = src98_r; - src21_r = src109_r; - src2 = src10; - } -} - -static void common_vt_4t_16w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6; - v16i8 src10_r, src32_r, src54_r, src21_r, src43_r, src65_r, src10_l; - v16i8 src32_l, src54_l, src21_l, src43_l, src65_l, filt0, filt1; - v16u8 tmp0, tmp1, tmp2, tmp3; - v8i16 filt, out0_r, out1_r, out2_r, out3_r, out0_l, out1_l, out2_l, out3_l; - - src -= src_stride; - - filt = LD_SH(filter); - SPLATI_H2_SB(filt, 0, 1, filt0, filt1); - - LD_SB3(src, src_stride, src0, src1, src2); - src += (3 * src_stride); - - XORI_B3_128_SB(src0, src1, src2); - ILVR_B2_SB(src1, src0, src2, src1, src10_r, src21_r); - ILVL_B2_SB(src1, src0, src2, src1, src10_l, src21_l); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src3, src4, src5, src6); - src += (4 * src_stride); - - XORI_B4_128_SB(src3, src4, src5, src6); - ILVR_B4_SB(src3, src2, src4, src3, src5, src4, src6, src5, src32_r, src43_r, - src54_r, src65_r); - ILVL_B4_SB(src3, src2, src4, src3, src5, src4, src6, src5, src32_l, src43_l, - src54_l, src65_l); - out0_r = FILT_4TAP_DPADD_S_H(src10_r, src32_r, filt0, filt1); - out1_r = FILT_4TAP_DPADD_S_H(src21_r, src43_r, filt0, filt1); - out2_r = FILT_4TAP_DPADD_S_H(src32_r, src54_r, filt0, filt1); - out3_r = FILT_4TAP_DPADD_S_H(src43_r, src65_r, filt0, filt1); - out0_l = FILT_4TAP_DPADD_S_H(src10_l, src32_l, filt0, filt1); - out1_l = FILT_4TAP_DPADD_S_H(src21_l, src43_l, filt0, filt1); - out2_l = FILT_4TAP_DPADD_S_H(src32_l, src54_l, filt0, filt1); - out3_l = FILT_4TAP_DPADD_S_H(src43_l, src65_l, filt0, filt1); - SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, VP8_FILTER_SHIFT); - SRARI_H4_SH(out0_l, out1_l, out2_l, out3_l, VP8_FILTER_SHIFT); - SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); - SAT_SH4_SH(out0_l, out1_l, out2_l, out3_l, 7); - PCKEV_B4_UB(out0_l, out0_r, out1_l, out1_r, out2_l, out2_r, out3_l, out3_r, - tmp0, tmp1, tmp2, tmp3); - XORI_B4_128_UB(tmp0, tmp1, tmp2, tmp3); - ST_UB4(tmp0, tmp1, tmp2, tmp3, dst, dst_stride); - dst += (4 * dst_stride); - - src10_r = src54_r; - src21_r = src65_r; - src10_l = src54_l; - src21_l = src65_l; - src2 = src6; - } -} - -static void common_hv_4ht_4vt_4w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, filt_hz0, filt_hz1; - v16u8 mask0, mask1, out; - v8i16 filt, filt_vt0, filt_vt1, tmp0, tmp1, vec0, vec1, vec2; - v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5; - - mask0 = LD_UB(&vp8_mc_filt_mask_arr[16]); - src -= (1 + 1 * src_stride); - - filt = LD_SH(filter_horiz); - SPLATI_H2_SB(filt, 0, 1, filt_hz0, filt_hz1); - - mask1 = mask0 + 2; - - LD_SB3(src, src_stride, src0, src1, src2); - src += (3 * src_stride); - - XORI_B3_128_SB(src0, src1, src2); - hz_out0 = HORIZ_4TAP_FILT(src0, src1, mask0, mask1, filt_hz0, filt_hz1); - hz_out1 = HORIZ_4TAP_FILT(src1, src2, mask0, mask1, filt_hz0, filt_hz1); - vec0 = (v8i16)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - - filt = LD_SH(filter_vert); - SPLATI_H2_SH(filt, 0, 1, filt_vt0, filt_vt1); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src3, src4, src5, src6); - src += (4 * src_stride); - - XORI_B2_128_SB(src3, src4); - hz_out3 = HORIZ_4TAP_FILT(src3, src4, mask0, mask1, filt_hz0, filt_hz1); - hz_out2 = (v8i16)__msa_sldi_b((v16i8)hz_out3, (v16i8)hz_out1, 8); - vec1 = (v8i16)__msa_ilvev_b((v16i8)hz_out3, (v16i8)hz_out2); - tmp0 = FILT_4TAP_DPADD_S_H(vec0, vec1, filt_vt0, filt_vt1); - - XORI_B2_128_SB(src5, src6); - hz_out5 = HORIZ_4TAP_FILT(src5, src6, mask0, mask1, filt_hz0, filt_hz1); - hz_out4 = (v8i16)__msa_sldi_b((v16i8)hz_out5, (v16i8)hz_out3, 8); - vec2 = (v8i16)__msa_ilvev_b((v16i8)hz_out5, (v16i8)hz_out4); - tmp1 = FILT_4TAP_DPADD_S_H(vec1, vec2, filt_vt0, filt_vt1); - - SRARI_H2_SH(tmp0, tmp1, 7); - SAT_SH2_SH(tmp0, tmp1, 7); - out = PCKEV_XORI128_UB(tmp0, tmp1); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - - hz_out1 = hz_out5; - vec0 = vec2; - } -} - -static void common_hv_4ht_4vt_8w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, filt_hz0, filt_hz1; - v16u8 mask0, mask1, out0, out1; - v8i16 filt, filt_vt0, filt_vt1, tmp0, tmp1, tmp2, tmp3; - v8i16 hz_out0, hz_out1, hz_out2, hz_out3; - v8i16 vec0, vec1, vec2, vec3, vec4; - - mask0 = LD_UB(&vp8_mc_filt_mask_arr[0]); - src -= (1 + 1 * src_stride); - - filt = LD_SH(filter_horiz); - SPLATI_H2_SB(filt, 0, 1, filt_hz0, filt_hz1); - - mask1 = mask0 + 2; - - LD_SB3(src, src_stride, src0, src1, src2); - src += (3 * src_stride); - - XORI_B3_128_SB(src0, src1, src2); - hz_out0 = HORIZ_4TAP_FILT(src0, src0, mask0, mask1, filt_hz0, filt_hz1); - hz_out1 = HORIZ_4TAP_FILT(src1, src1, mask0, mask1, filt_hz0, filt_hz1); - hz_out2 = HORIZ_4TAP_FILT(src2, src2, mask0, mask1, filt_hz0, filt_hz1); - ILVEV_B2_SH(hz_out0, hz_out1, hz_out1, hz_out2, vec0, vec2); - - filt = LD_SH(filter_vert); - SPLATI_H2_SH(filt, 0, 1, filt_vt0, filt_vt1); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src3, src4, src5, src6); - src += (4 * src_stride); - - XORI_B4_128_SB(src3, src4, src5, src6); - hz_out3 = HORIZ_4TAP_FILT(src3, src3, mask0, mask1, filt_hz0, filt_hz1); - vec1 = (v8i16)__msa_ilvev_b((v16i8)hz_out3, (v16i8)hz_out2); - tmp0 = FILT_4TAP_DPADD_S_H(vec0, vec1, filt_vt0, filt_vt1); - - hz_out0 = HORIZ_4TAP_FILT(src4, src4, mask0, mask1, filt_hz0, filt_hz1); - vec3 = (v8i16)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out3); - tmp1 = FILT_4TAP_DPADD_S_H(vec2, vec3, filt_vt0, filt_vt1); - - hz_out1 = HORIZ_4TAP_FILT(src5, src5, mask0, mask1, filt_hz0, filt_hz1); - vec4 = (v8i16)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp2 = FILT_4TAP_DPADD_S_H(vec1, vec4, filt_vt0, filt_vt1); - - hz_out2 = HORIZ_4TAP_FILT(src6, src6, mask0, mask1, filt_hz0, filt_hz1); - ILVEV_B2_SH(hz_out3, hz_out0, hz_out1, hz_out2, vec0, vec1); - tmp3 = FILT_4TAP_DPADD_S_H(vec0, vec1, filt_vt0, filt_vt1); - - SRARI_H4_SH(tmp0, tmp1, tmp2, tmp3, 7); - SAT_SH4_SH(tmp0, tmp1, tmp2, tmp3, 7); - out0 = PCKEV_XORI128_UB(tmp0, tmp1); - out1 = PCKEV_XORI128_UB(tmp2, tmp3); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += (4 * dst_stride); - - vec0 = vec4; - vec2 = vec1; - } -} - -static void common_hv_4ht_4vt_16w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 2; multiple8_cnt--;) { - common_hv_4ht_4vt_8w_msa(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - src += 8; - dst += 8; - } -} - -static void common_hv_6ht_4vt_4w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6; - v16i8 filt_hz0, filt_hz1, filt_hz2; - v16u8 res0, res1, mask0, mask1, mask2; - v8i16 filt, filt_vt0, filt_vt1, tmp0, tmp1, vec0, vec1, vec2; - v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5; - - mask0 = LD_UB(&vp8_mc_filt_mask_arr[16]); - src -= (2 + 1 * src_stride); - - filt = LD_SH(filter_horiz); - SPLATI_H3_SB(filt, 0, 1, 2, filt_hz0, filt_hz1, filt_hz2); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - - LD_SB3(src, src_stride, src0, src1, src2); - src += (3 * src_stride); - - XORI_B3_128_SB(src0, src1, src2); - hz_out0 = HORIZ_6TAP_FILT(src0, src1, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out1 = HORIZ_6TAP_FILT(src1, src2, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - vec0 = (v8i16)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - - filt = LD_SH(filter_vert); - SPLATI_H2_SH(filt, 0, 1, filt_vt0, filt_vt1); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src3, src4, src5, src6); - src += (4 * src_stride); - - XORI_B4_128_SB(src3, src4, src5, src6); - hz_out3 = HORIZ_6TAP_FILT(src3, src4, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - hz_out2 = (v8i16)__msa_sldi_b((v16i8)hz_out3, (v16i8)hz_out1, 8); - vec1 = (v8i16)__msa_ilvev_b((v16i8)hz_out3, (v16i8)hz_out2); - tmp0 = FILT_4TAP_DPADD_S_H(vec0, vec1, filt_vt0, filt_vt1); - - hz_out5 = HORIZ_6TAP_FILT(src5, src6, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - hz_out4 = (v8i16)__msa_sldi_b((v16i8)hz_out5, (v16i8)hz_out3, 8); - vec2 = (v8i16)__msa_ilvev_b((v16i8)hz_out5, (v16i8)hz_out4); - tmp1 = FILT_4TAP_DPADD_S_H(vec1, vec2, filt_vt0, filt_vt1); - - SRARI_H2_SH(tmp0, tmp1, 7); - SAT_SH2_SH(tmp0, tmp1, 7); - PCKEV_B2_UB(tmp0, tmp0, tmp1, tmp1, res0, res1); - XORI_B2_128_UB(res0, res1); - ST4x4_UB(res0, res1, 0, 1, 0, 1, dst, dst_stride); - dst += (4 * dst_stride); - - hz_out1 = hz_out5; - vec0 = vec2; - } -} - -static void common_hv_6ht_4vt_8w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6; - v16i8 filt_hz0, filt_hz1, filt_hz2, mask0, mask1, mask2; - v8i16 filt, filt_vt0, filt_vt1, hz_out0, hz_out1, hz_out2, hz_out3; - v8i16 tmp0, tmp1, tmp2, tmp3, vec0, vec1, vec2, vec3; - v16u8 out0, out1; - - mask0 = LD_SB(&vp8_mc_filt_mask_arr[0]); - src -= (2 + src_stride); - - filt = LD_SH(filter_horiz); - SPLATI_H3_SB(filt, 0, 1, 2, filt_hz0, filt_hz1, filt_hz2); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - - LD_SB3(src, src_stride, src0, src1, src2); - src += (3 * src_stride); - - XORI_B3_128_SB(src0, src1, src2); - hz_out0 = HORIZ_6TAP_FILT(src0, src0, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out1 = HORIZ_6TAP_FILT(src1, src1, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - hz_out2 = HORIZ_6TAP_FILT(src2, src2, mask0, mask1, mask2, filt_hz0, filt_hz1, - filt_hz2); - ILVEV_B2_SH(hz_out0, hz_out1, hz_out1, hz_out2, vec0, vec2); - - filt = LD_SH(filter_vert); - SPLATI_H2_SH(filt, 0, 1, filt_vt0, filt_vt1); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src3, src4, src5, src6); - src += (4 * src_stride); - - XORI_B4_128_SB(src3, src4, src5, src6); - - hz_out3 = HORIZ_6TAP_FILT(src3, src3, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - vec1 = (v8i16)__msa_ilvev_b((v16i8)hz_out3, (v16i8)hz_out2); - tmp0 = FILT_4TAP_DPADD_S_H(vec0, vec1, filt_vt0, filt_vt1); - - hz_out0 = HORIZ_6TAP_FILT(src4, src4, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - vec3 = (v8i16)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out3); - tmp1 = FILT_4TAP_DPADD_S_H(vec2, vec3, filt_vt0, filt_vt1); - - hz_out1 = HORIZ_6TAP_FILT(src5, src5, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - vec0 = (v8i16)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp2 = FILT_4TAP_DPADD_S_H(vec1, vec0, filt_vt0, filt_vt1); - - hz_out2 = HORIZ_6TAP_FILT(src6, src6, mask0, mask1, mask2, filt_hz0, - filt_hz1, filt_hz2); - ILVEV_B2_SH(hz_out3, hz_out0, hz_out1, hz_out2, vec1, vec2); - tmp3 = FILT_4TAP_DPADD_S_H(vec1, vec2, filt_vt0, filt_vt1); - - SRARI_H4_SH(tmp0, tmp1, tmp2, tmp3, 7); - SAT_SH4_SH(tmp0, tmp1, tmp2, tmp3, 7); - out0 = PCKEV_XORI128_UB(tmp0, tmp1); - out1 = PCKEV_XORI128_UB(tmp2, tmp3); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += (4 * dst_stride); - } -} - -static void common_hv_6ht_4vt_16w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 2; multiple8_cnt--;) { - common_hv_6ht_4vt_8w_msa(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - src += 8; - dst += 8; - } -} - -static void common_hv_4ht_6vt_4w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16i8 filt_hz0, filt_hz1, mask0, mask1; - v16u8 out; - v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; - v8i16 hz_out7, tmp0, tmp1, out0, out1, out2, out3; - v8i16 filt, filt_vt0, filt_vt1, filt_vt2; - - mask0 = LD_SB(&vp8_mc_filt_mask_arr[16]); - - src -= (1 + 2 * src_stride); - - filt = LD_SH(filter_horiz); - SPLATI_H2_SB(filt, 0, 1, filt_hz0, filt_hz1); - - mask1 = mask0 + 2; - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - - XORI_B5_128_SB(src0, src1, src2, src3, src4); - hz_out0 = HORIZ_4TAP_FILT(src0, src1, mask0, mask1, filt_hz0, filt_hz1); - hz_out2 = HORIZ_4TAP_FILT(src2, src3, mask0, mask1, filt_hz0, filt_hz1); - hz_out3 = HORIZ_4TAP_FILT(src3, src4, mask0, mask1, filt_hz0, filt_hz1); - hz_out1 = (v8i16)__msa_sldi_b((v16i8)hz_out2, (v16i8)hz_out0, 8); - ILVEV_B2_SH(hz_out0, hz_out1, hz_out2, hz_out3, out0, out1); - - filt = LD_SH(filter_vert); - SPLATI_H3_SH(filt, 0, 1, 2, filt_vt0, filt_vt1, filt_vt2); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src5, src6, src7, src8); - XORI_B4_128_SB(src5, src6, src7, src8); - src += (4 * src_stride); - - hz_out5 = HORIZ_4TAP_FILT(src5, src6, mask0, mask1, filt_hz0, filt_hz1); - hz_out4 = (v8i16)__msa_sldi_b((v16i8)hz_out5, (v16i8)hz_out3, 8); - out2 = (v8i16)__msa_ilvev_b((v16i8)hz_out5, (v16i8)hz_out4); - tmp0 = DPADD_SH3_SH(out0, out1, out2, filt_vt0, filt_vt1, filt_vt2); - - hz_out7 = HORIZ_4TAP_FILT(src7, src8, mask0, mask1, filt_hz0, filt_hz1); - hz_out6 = (v8i16)__msa_sldi_b((v16i8)hz_out7, (v16i8)hz_out5, 8); - out3 = (v8i16)__msa_ilvev_b((v16i8)hz_out7, (v16i8)hz_out6); - tmp1 = DPADD_SH3_SH(out1, out2, out3, filt_vt0, filt_vt1, filt_vt2); - - SRARI_H2_SH(tmp0, tmp1, 7); - SAT_SH2_SH(tmp0, tmp1, 7); - out = PCKEV_XORI128_UB(tmp0, tmp1); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - - hz_out3 = hz_out7; - out0 = out2; - out1 = out3; - } -} - -static void common_hv_4ht_6vt_8w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16i8 filt_hz0, filt_hz1, mask0, mask1; - v8i16 filt, filt_vt0, filt_vt1, filt_vt2, tmp0, tmp1, tmp2, tmp3; - v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; - v8i16 hz_out7, hz_out8, out0, out1, out2, out3, out4, out5, out6, out7; - v16u8 vec0, vec1; - - mask0 = LD_SB(&vp8_mc_filt_mask_arr[0]); - src -= (1 + 2 * src_stride); - - filt = LD_SH(filter_horiz); - SPLATI_H2_SB(filt, 0, 1, filt_hz0, filt_hz1); - - mask1 = mask0 + 2; - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - - XORI_B5_128_SB(src0, src1, src2, src3, src4); - hz_out0 = HORIZ_4TAP_FILT(src0, src0, mask0, mask1, filt_hz0, filt_hz1); - hz_out1 = HORIZ_4TAP_FILT(src1, src1, mask0, mask1, filt_hz0, filt_hz1); - hz_out2 = HORIZ_4TAP_FILT(src2, src2, mask0, mask1, filt_hz0, filt_hz1); - hz_out3 = HORIZ_4TAP_FILT(src3, src3, mask0, mask1, filt_hz0, filt_hz1); - hz_out4 = HORIZ_4TAP_FILT(src4, src4, mask0, mask1, filt_hz0, filt_hz1); - ILVEV_B2_SH(hz_out0, hz_out1, hz_out2, hz_out3, out0, out1); - ILVEV_B2_SH(hz_out1, hz_out2, hz_out3, hz_out4, out3, out4); - - filt = LD_SH(filter_vert); - SPLATI_H3_SH(filt, 0, 1, 2, filt_vt0, filt_vt1, filt_vt2); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src5, src6, src7, src8); - src += (4 * src_stride); - - XORI_B4_128_SB(src5, src6, src7, src8); - - hz_out5 = HORIZ_4TAP_FILT(src5, src5, mask0, mask1, filt_hz0, filt_hz1); - out2 = (v8i16)__msa_ilvev_b((v16i8)hz_out5, (v16i8)hz_out4); - tmp0 = DPADD_SH3_SH(out0, out1, out2, filt_vt0, filt_vt1, filt_vt2); - - hz_out6 = HORIZ_4TAP_FILT(src6, src6, mask0, mask1, filt_hz0, filt_hz1); - out5 = (v8i16)__msa_ilvev_b((v16i8)hz_out6, (v16i8)hz_out5); - tmp1 = DPADD_SH3_SH(out3, out4, out5, filt_vt0, filt_vt1, filt_vt2); - - hz_out7 = HORIZ_4TAP_FILT(src7, src7, mask0, mask1, filt_hz0, filt_hz1); - out6 = (v8i16)__msa_ilvev_b((v16i8)hz_out7, (v16i8)hz_out6); - tmp2 = DPADD_SH3_SH(out1, out2, out6, filt_vt0, filt_vt1, filt_vt2); - - hz_out8 = HORIZ_4TAP_FILT(src8, src8, mask0, mask1, filt_hz0, filt_hz1); - out7 = (v8i16)__msa_ilvev_b((v16i8)hz_out8, (v16i8)hz_out7); - tmp3 = DPADD_SH3_SH(out4, out5, out7, filt_vt0, filt_vt1, filt_vt2); - - SRARI_H4_SH(tmp0, tmp1, tmp2, tmp3, 7); - SAT_SH4_SH(tmp0, tmp1, tmp2, tmp3, 7); - vec0 = PCKEV_XORI128_UB(tmp0, tmp1); - vec1 = PCKEV_XORI128_UB(tmp2, tmp3); - ST8x4_UB(vec0, vec1, dst, dst_stride); - dst += (4 * dst_stride); - - hz_out4 = hz_out8; - out0 = out2; - out1 = out6; - out3 = out5; - out4 = out7; - } -} - -static void common_hv_4ht_6vt_16w_msa(uint8_t *RESTRICT src, int32_t src_stride, - uint8_t *RESTRICT dst, int32_t dst_stride, - const int8_t *filter_horiz, - const int8_t *filter_vert, - int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 2; multiple8_cnt--;) { - common_hv_4ht_6vt_8w_msa(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - src += 8; - dst += 8; - } -} - -void vp8_sixtap_predict4x4_msa(uint8_t *RESTRICT src, int32_t src_stride, - int32_t xoffset, int32_t yoffset, - uint8_t *RESTRICT dst, int32_t dst_stride) { - const int8_t *h_filter = vp8_subpel_filters_msa[xoffset - 1]; - const int8_t *v_filter = vp8_subpel_filters_msa[yoffset - 1]; - - if (yoffset) { - if (xoffset) { - switch (xoffset) { - case 2: - case 4: - case 6: - switch (yoffset) { - case 2: - case 4: - case 6: - common_hv_6ht_6vt_4w_msa(src, src_stride, dst, dst_stride, - h_filter, v_filter, 4); - break; - - case 1: - case 3: - case 5: - case 7: - common_hv_6ht_4vt_4w_msa(src, src_stride, dst, dst_stride, - h_filter, v_filter + 1, 4); - break; - } - break; - - case 1: - case 3: - case 5: - case 7: - switch (yoffset) { - case 2: - case 4: - case 6: - common_hv_4ht_6vt_4w_msa(src, src_stride, dst, dst_stride, - h_filter + 1, v_filter, 4); - break; - - case 1: - case 3: - case 5: - case 7: - common_hv_4ht_4vt_4w_msa(src, src_stride, dst, dst_stride, - h_filter + 1, v_filter + 1, 4); - break; - } - break; - } - } else { - switch (yoffset) { - case 2: - case 4: - case 6: - common_vt_6t_4w_msa(src, src_stride, dst, dst_stride, v_filter, 4); - break; - - case 1: - case 3: - case 5: - case 7: - common_vt_4t_4w_msa(src, src_stride, dst, dst_stride, v_filter + 1, - 4); - break; - } - } - } else { - switch (xoffset) { - case 0: { - uint32_t tp0, tp1, tp2, tp3; - - LW4(src, src_stride, tp0, tp1, tp2, tp3); - SW4(tp0, tp1, tp2, tp3, dst, dst_stride); - break; - } - case 2: - case 4: - case 6: - common_hz_6t_4w_msa(src, src_stride, dst, dst_stride, h_filter, 4); - break; - - case 1: - case 3: - case 5: - case 7: - common_hz_4t_4w_msa(src, src_stride, dst, dst_stride, h_filter + 1, 4); - break; - } - } -} - -void vp8_sixtap_predict8x4_msa(uint8_t *RESTRICT src, int32_t src_stride, - int32_t xoffset, int32_t yoffset, - uint8_t *RESTRICT dst, int32_t dst_stride) { - const int8_t *h_filter = vp8_subpel_filters_msa[xoffset - 1]; - const int8_t *v_filter = vp8_subpel_filters_msa[yoffset - 1]; - - if (yoffset) { - if (xoffset) { - switch (xoffset) { - case 2: - case 4: - case 6: - switch (yoffset) { - case 2: - case 4: - case 6: - common_hv_6ht_6vt_8w_msa(src, src_stride, dst, dst_stride, - h_filter, v_filter, 4); - break; - - case 1: - case 3: - case 5: - case 7: - common_hv_6ht_4vt_8w_msa(src, src_stride, dst, dst_stride, - h_filter, v_filter + 1, 4); - break; - } - break; - - case 1: - case 3: - case 5: - case 7: - switch (yoffset) { - case 2: - case 4: - case 6: - common_hv_4ht_6vt_8w_msa(src, src_stride, dst, dst_stride, - h_filter + 1, v_filter, 4); - break; - - case 1: - case 3: - case 5: - case 7: - common_hv_4ht_4vt_8w_msa(src, src_stride, dst, dst_stride, - h_filter + 1, v_filter + 1, 4); - break; - } - break; - } - } else { - switch (yoffset) { - case 2: - case 4: - case 6: - common_vt_6t_8w_msa(src, src_stride, dst, dst_stride, v_filter, 4); - break; - - case 1: - case 3: - case 5: - case 7: - common_vt_4t_8w_msa(src, src_stride, dst, dst_stride, v_filter + 1, - 4); - break; - } - } - } else { - switch (xoffset) { - case 0: vp8_copy_mem8x4(src, src_stride, dst, dst_stride); break; - case 2: - case 4: - case 6: - common_hz_6t_8w_msa(src, src_stride, dst, dst_stride, h_filter, 4); - break; - - case 1: - case 3: - case 5: - case 7: - common_hz_4t_8w_msa(src, src_stride, dst, dst_stride, h_filter + 1, 4); - break; - } - } -} - -void vp8_sixtap_predict8x8_msa(uint8_t *RESTRICT src, int32_t src_stride, - int32_t xoffset, int32_t yoffset, - uint8_t *RESTRICT dst, int32_t dst_stride) { - const int8_t *h_filter = vp8_subpel_filters_msa[xoffset - 1]; - const int8_t *v_filter = vp8_subpel_filters_msa[yoffset - 1]; - - if (yoffset) { - if (xoffset) { - switch (xoffset) { - case 2: - case 4: - case 6: - switch (yoffset) { - case 2: - case 4: - case 6: - common_hv_6ht_6vt_8w_msa(src, src_stride, dst, dst_stride, - h_filter, v_filter, 8); - break; - - case 1: - case 3: - case 5: - case 7: - common_hv_6ht_4vt_8w_msa(src, src_stride, dst, dst_stride, - h_filter, v_filter + 1, 8); - break; - } - break; - - case 1: - case 3: - case 5: - case 7: - switch (yoffset) { - case 2: - case 4: - case 6: - common_hv_4ht_6vt_8w_msa(src, src_stride, dst, dst_stride, - h_filter + 1, v_filter, 8); - break; - - case 1: - case 3: - case 5: - case 7: - common_hv_4ht_4vt_8w_msa(src, src_stride, dst, dst_stride, - h_filter + 1, v_filter + 1, 8); - break; - } - break; - } - } else { - switch (yoffset) { - case 2: - case 4: - case 6: - common_vt_6t_8w_msa(src, src_stride, dst, dst_stride, v_filter, 8); - break; - - case 1: - case 3: - case 5: - case 7: - common_vt_4t_8w_msa(src, src_stride, dst, dst_stride, v_filter + 1, - 8); - break; - } - } - } else { - switch (xoffset) { - case 0: vp8_copy_mem8x8(src, src_stride, dst, dst_stride); break; - case 2: - case 4: - case 6: - common_hz_6t_8w_msa(src, src_stride, dst, dst_stride, h_filter, 8); - break; - - case 1: - case 3: - case 5: - case 7: - common_hz_4t_8w_msa(src, src_stride, dst, dst_stride, h_filter + 1, 8); - break; - } - } -} - -void vp8_sixtap_predict16x16_msa(uint8_t *RESTRICT src, int32_t src_stride, - int32_t xoffset, int32_t yoffset, - uint8_t *RESTRICT dst, int32_t dst_stride) { - const int8_t *h_filter = vp8_subpel_filters_msa[xoffset - 1]; - const int8_t *v_filter = vp8_subpel_filters_msa[yoffset - 1]; - - if (yoffset) { - if (xoffset) { - switch (xoffset) { - case 2: - case 4: - case 6: - switch (yoffset) { - case 2: - case 4: - case 6: - common_hv_6ht_6vt_16w_msa(src, src_stride, dst, dst_stride, - h_filter, v_filter, 16); - break; - - case 1: - case 3: - case 5: - case 7: - common_hv_6ht_4vt_16w_msa(src, src_stride, dst, dst_stride, - h_filter, v_filter + 1, 16); - break; - } - break; - - case 1: - case 3: - case 5: - case 7: - switch (yoffset) { - case 2: - case 4: - case 6: - common_hv_4ht_6vt_16w_msa(src, src_stride, dst, dst_stride, - h_filter + 1, v_filter, 16); - break; - - case 1: - case 3: - case 5: - case 7: - common_hv_4ht_4vt_16w_msa(src, src_stride, dst, dst_stride, - h_filter + 1, v_filter + 1, 16); - break; - } - break; - } - } else { - switch (yoffset) { - case 2: - case 4: - case 6: - common_vt_6t_16w_msa(src, src_stride, dst, dst_stride, v_filter, 16); - break; - - case 1: - case 3: - case 5: - case 7: - common_vt_4t_16w_msa(src, src_stride, dst, dst_stride, v_filter + 1, - 16); - break; - } - } - } else { - switch (xoffset) { - case 0: vp8_copy_mem16x16(src, src_stride, dst, dst_stride); break; - case 2: - case 4: - case 6: - common_hz_6t_16w_msa(src, src_stride, dst, dst_stride, h_filter, 16); - break; - - case 1: - case 3: - case 5: - case 7: - common_hz_4t_16w_msa(src, src_stride, dst, dst_stride, h_filter + 1, - 16); - break; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/vp8_macros_msa.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/vp8_macros_msa.h deleted file mode 100644 index cc85b9a1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mips/msa/vp8_macros_msa.h +++ /dev/null @@ -1,1762 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_MIPS_MSA_VP8_MACROS_MSA_H_ -#define VPX_VP8_COMMON_MIPS_MSA_VP8_MACROS_MSA_H_ - -#include - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" - -#define LD_B(RTYPE, psrc) *((const RTYPE *)(psrc)) -#define LD_UB(...) LD_B(v16u8, __VA_ARGS__) -#define LD_SB(...) LD_B(v16i8, __VA_ARGS__) - -#define LD_H(RTYPE, psrc) *((const RTYPE *)(psrc)) -#define LD_UH(...) LD_H(v8u16, __VA_ARGS__) -#define LD_SH(...) LD_H(v8i16, __VA_ARGS__) - -#define LD_W(RTYPE, psrc) *((const RTYPE *)(psrc)) -#define LD_UW(...) LD_W(v4u32, __VA_ARGS__) -#define LD_SW(...) LD_W(v4i32, __VA_ARGS__) - -#define ST_B(RTYPE, in, pdst) *((RTYPE *)(pdst)) = (in) -#define ST_UB(...) ST_B(v16u8, __VA_ARGS__) -#define ST_SB(...) ST_B(v16i8, __VA_ARGS__) - -#define ST_H(RTYPE, in, pdst) *((RTYPE *)(pdst)) = (in) -#define ST_UH(...) ST_H(v8u16, __VA_ARGS__) -#define ST_SH(...) ST_H(v8i16, __VA_ARGS__) - -#define ST_W(RTYPE, in, pdst) *((RTYPE *)(pdst)) = (in) -#define ST_SW(...) ST_W(v4i32, __VA_ARGS__) - -#if (__mips_isa_rev >= 6) -#define LW(psrc) \ - ({ \ - const uint8_t *lw_psrc_m = (const uint8_t *)(psrc); \ - uint32_t lw_val_m; \ - \ - asm volatile("lw %[lw_val_m], %[lw_psrc_m] \n\t" \ - \ - : [lw_val_m] "=r"(lw_val_m) \ - : [lw_psrc_m] "m"(*lw_psrc_m)); \ - \ - lw_val_m; \ - }) - -#if (__mips == 64) -#define LD(psrc) \ - ({ \ - const uint8_t *ld_psrc_m = (const uint8_t *)(psrc); \ - uint64_t ld_val_m = 0; \ - \ - asm volatile("ld %[ld_val_m], %[ld_psrc_m] \n\t" \ - \ - : [ld_val_m] "=r"(ld_val_m) \ - : [ld_psrc_m] "m"(*ld_psrc_m)); \ - \ - ld_val_m; \ - }) -#else // !(__mips == 64) -#define LD(psrc) \ - ({ \ - const uint8_t *ld_psrc_m = (const uint8_t *)(psrc); \ - uint32_t ld_val0_m, ld_val1_m; \ - uint64_t ld_val_m = 0; \ - \ - ld_val0_m = LW(ld_psrc_m); \ - ld_val1_m = LW(ld_psrc_m + 4); \ - \ - ld_val_m = (uint64_t)(ld_val1_m); \ - ld_val_m = (uint64_t)((ld_val_m << 32) & 0xFFFFFFFF00000000); \ - ld_val_m = (uint64_t)(ld_val_m | (uint64_t)ld_val0_m); \ - \ - ld_val_m; \ - }) -#endif // (__mips == 64) - -#define SH(val, pdst) \ - { \ - uint8_t *sh_pdst_m = (uint8_t *)(pdst); \ - const uint16_t sh_val_m = (val); \ - \ - asm volatile("sh %[sh_val_m], %[sh_pdst_m] \n\t" \ - \ - : [sh_pdst_m] "=m"(*sh_pdst_m) \ - : [sh_val_m] "r"(sh_val_m)); \ - } - -#define SW(val, pdst) \ - { \ - uint8_t *sw_pdst_m = (uint8_t *)(pdst); \ - const uint32_t sw_val_m = (val); \ - \ - asm volatile("sw %[sw_val_m], %[sw_pdst_m] \n\t" \ - \ - : [sw_pdst_m] "=m"(*sw_pdst_m) \ - : [sw_val_m] "r"(sw_val_m)); \ - } - -#define SD(val, pdst) \ - { \ - uint8_t *sd_pdst_m = (uint8_t *)(pdst); \ - const uint64_t sd_val_m = (val); \ - \ - asm volatile("sd %[sd_val_m], %[sd_pdst_m] \n\t" \ - \ - : [sd_pdst_m] "=m"(*sd_pdst_m) \ - : [sd_val_m] "r"(sd_val_m)); \ - } -#else // !(__mips_isa_rev >= 6) -#define LW(psrc) \ - ({ \ - const uint8_t *lw_psrc_m = (const uint8_t *)(psrc); \ - uint32_t lw_val_m; \ - \ - asm volatile( \ - "lwr %[lw_val_m], 0(%[lw_psrc_m]) \n\t" \ - "lwl %[lw_val_m], 3(%[lw_psrc_m]) \n\t" \ - : [lw_val_m] "=&r"(lw_val_m) \ - : [lw_psrc_m] "r"(lw_psrc_m)); \ - \ - lw_val_m; \ - }) - -#if (__mips == 64) -#define LD(psrc) \ - ({ \ - const uint8_t *ld_psrc_m = (const uint8_t *)(psrc); \ - uint64_t ld_val_m = 0; \ - \ - asm volatile( \ - "ldr %[ld_val_m], 0(%[ld_psrc_m]) \n\t" \ - "ldl %[ld_val_m], 7(%[ld_psrc_m]) \n\t" \ - : [ld_val_m] "=&r"(ld_val_m) \ - : [ld_psrc_m] "r"(ld_psrc_m)); \ - \ - ld_val_m; \ - }) -#else // !(__mips == 64) -#define LD(psrc) \ - ({ \ - const uint8_t *ld_psrc_m1 = (const uint8_t *)(psrc); \ - uint32_t ld_val0_m, ld_val1_m; \ - uint64_t ld_val_m = 0; \ - \ - ld_val0_m = LW(ld_psrc_m1); \ - ld_val1_m = LW(ld_psrc_m1 + 4); \ - \ - ld_val_m = (uint64_t)(ld_val1_m); \ - ld_val_m = (uint64_t)((ld_val_m << 32) & 0xFFFFFFFF00000000); \ - ld_val_m = (uint64_t)(ld_val_m | (uint64_t)ld_val0_m); \ - \ - ld_val_m; \ - }) -#endif // (__mips == 64) -#define SH(val, pdst) \ - { \ - uint8_t *sh_pdst_m = (uint8_t *)(pdst); \ - const uint16_t sh_val_m = (val); \ - \ - asm volatile("ush %[sh_val_m], %[sh_pdst_m] \n\t" \ - \ - : [sh_pdst_m] "=m"(*sh_pdst_m) \ - : [sh_val_m] "r"(sh_val_m)); \ - } - -#define SW(val, pdst) \ - { \ - uint8_t *sw_pdst_m = (uint8_t *)(pdst); \ - const uint32_t sw_val_m = (val); \ - \ - asm volatile("usw %[sw_val_m], %[sw_pdst_m] \n\t" \ - \ - : [sw_pdst_m] "=m"(*sw_pdst_m) \ - : [sw_val_m] "r"(sw_val_m)); \ - } - -#define SD(val, pdst) \ - { \ - uint8_t *sd_pdst_m1 = (uint8_t *)(pdst); \ - uint32_t sd_val0_m, sd_val1_m; \ - \ - sd_val0_m = (uint32_t)((val)&0x00000000FFFFFFFF); \ - sd_val1_m = (uint32_t)(((val) >> 32) & 0x00000000FFFFFFFF); \ - \ - SW(sd_val0_m, sd_pdst_m1); \ - SW(sd_val1_m, sd_pdst_m1 + 4); \ - } -#endif // (__mips_isa_rev >= 6) - -/* Description : Load 4 words with stride - Arguments : Inputs - psrc, stride - Outputs - out0, out1, out2, out3 - Details : Load word in 'out0' from (psrc) - Load word in 'out1' from (psrc + stride) - Load word in 'out2' from (psrc + 2 * stride) - Load word in 'out3' from (psrc + 3 * stride) -*/ -#define LW4(psrc, stride, out0, out1, out2, out3) \ - { \ - out0 = LW((psrc)); \ - out1 = LW((psrc) + stride); \ - out2 = LW((psrc) + 2 * stride); \ - out3 = LW((psrc) + 3 * stride); \ - } - -/* Description : Load double words with stride - Arguments : Inputs - psrc, stride - Outputs - out0, out1 - Details : Load double word in 'out0' from (psrc) - Load double word in 'out1' from (psrc + stride) -*/ -#define LD2(psrc, stride, out0, out1) \ - { \ - out0 = LD((psrc)); \ - out1 = LD((psrc) + stride); \ - } -#define LD4(psrc, stride, out0, out1, out2, out3) \ - { \ - LD2((psrc), stride, out0, out1); \ - LD2((psrc) + 2 * stride, stride, out2, out3); \ - } - -/* Description : Store 4 words with stride - Arguments : Inputs - in0, in1, in2, in3, pdst, stride - Details : Store word from 'in0' to (pdst) - Store word from 'in1' to (pdst + stride) - Store word from 'in2' to (pdst + 2 * stride) - Store word from 'in3' to (pdst + 3 * stride) -*/ -#define SW4(in0, in1, in2, in3, pdst, stride) \ - { \ - SW(in0, (pdst)); \ - SW(in1, (pdst) + stride); \ - SW(in2, (pdst) + 2 * stride); \ - SW(in3, (pdst) + 3 * stride); \ - } - -/* Description : Store 4 double words with stride - Arguments : Inputs - in0, in1, in2, in3, pdst, stride - Details : Store double word from 'in0' to (pdst) - Store double word from 'in1' to (pdst + stride) - Store double word from 'in2' to (pdst + 2 * stride) - Store double word from 'in3' to (pdst + 3 * stride) -*/ -#define SD4(in0, in1, in2, in3, pdst, stride) \ - { \ - SD(in0, (pdst)); \ - SD(in1, (pdst) + stride); \ - SD(in2, (pdst) + 2 * stride); \ - SD(in3, (pdst) + 3 * stride); \ - } - -/* Description : Load vectors with 16 byte elements with stride - Arguments : Inputs - psrc, stride - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Load 16 byte elements in 'out0' from (psrc) - Load 16 byte elements in 'out1' from (psrc + stride) -*/ -#define LD_B2(RTYPE, psrc, stride, out0, out1) \ - { \ - out0 = LD_B(RTYPE, (psrc)); \ - out1 = LD_B(RTYPE, (psrc) + stride); \ - } -#define LD_UB2(...) LD_B2(v16u8, __VA_ARGS__) -#define LD_SB2(...) LD_B2(v16i8, __VA_ARGS__) - -#define LD_B3(RTYPE, psrc, stride, out0, out1, out2) \ - { \ - LD_B2(RTYPE, (psrc), stride, out0, out1); \ - out2 = LD_B(RTYPE, (psrc) + 2 * stride); \ - } -#define LD_UB3(...) LD_B3(v16u8, __VA_ARGS__) -#define LD_SB3(...) LD_B3(v16i8, __VA_ARGS__) - -#define LD_B4(RTYPE, psrc, stride, out0, out1, out2, out3) \ - { \ - LD_B2(RTYPE, (psrc), stride, out0, out1); \ - LD_B2(RTYPE, (psrc) + 2 * stride, stride, out2, out3); \ - } -#define LD_UB4(...) LD_B4(v16u8, __VA_ARGS__) -#define LD_SB4(...) LD_B4(v16i8, __VA_ARGS__) - -#define LD_B5(RTYPE, psrc, stride, out0, out1, out2, out3, out4) \ - { \ - LD_B4(RTYPE, (psrc), stride, out0, out1, out2, out3); \ - out4 = LD_B(RTYPE, (psrc) + 4 * stride); \ - } -#define LD_UB5(...) LD_B5(v16u8, __VA_ARGS__) -#define LD_SB5(...) LD_B5(v16i8, __VA_ARGS__) - -#define LD_B8(RTYPE, psrc, stride, out0, out1, out2, out3, out4, out5, out6, \ - out7) \ - { \ - LD_B4(RTYPE, (psrc), stride, out0, out1, out2, out3); \ - LD_B4(RTYPE, (psrc) + 4 * stride, stride, out4, out5, out6, out7); \ - } -#define LD_UB8(...) LD_B8(v16u8, __VA_ARGS__) -#define LD_SB8(...) LD_B8(v16i8, __VA_ARGS__) - -/* Description : Load vectors with 8 halfword elements with stride - Arguments : Inputs - psrc, stride - Outputs - out0, out1 - Details : Load 8 halfword elements in 'out0' from (psrc) - Load 8 halfword elements in 'out1' from (psrc + stride) -*/ -#define LD_H2(RTYPE, psrc, stride, out0, out1) \ - { \ - out0 = LD_H(RTYPE, (psrc)); \ - out1 = LD_H(RTYPE, (psrc) + (stride)); \ - } -#define LD_SH2(...) LD_H2(v8i16, __VA_ARGS__) - -#define LD_H4(RTYPE, psrc, stride, out0, out1, out2, out3) \ - { \ - LD_H2(RTYPE, (psrc), stride, out0, out1); \ - LD_H2(RTYPE, (psrc) + 2 * stride, stride, out2, out3); \ - } -#define LD_SH4(...) LD_H4(v8i16, __VA_ARGS__) - -/* Description : Load 2 vectors of signed word elements with stride - Arguments : Inputs - psrc, stride - Outputs - out0, out1 - Return Type - signed word -*/ -#define LD_SW2(psrc, stride, out0, out1) \ - { \ - out0 = LD_SW((psrc)); \ - out1 = LD_SW((psrc) + stride); \ - } - -/* Description : Store vectors of 16 byte elements with stride - Arguments : Inputs - in0, in1, pdst, stride - Details : Store 16 byte elements from 'in0' to (pdst) - Store 16 byte elements from 'in1' to (pdst + stride) -*/ -#define ST_B2(RTYPE, in0, in1, pdst, stride) \ - { \ - ST_B(RTYPE, in0, (pdst)); \ - ST_B(RTYPE, in1, (pdst) + stride); \ - } -#define ST_UB2(...) ST_B2(v16u8, __VA_ARGS__) - -#define ST_B4(RTYPE, in0, in1, in2, in3, pdst, stride) \ - { \ - ST_B2(RTYPE, in0, in1, (pdst), stride); \ - ST_B2(RTYPE, in2, in3, (pdst) + 2 * stride, stride); \ - } -#define ST_UB4(...) ST_B4(v16u8, __VA_ARGS__) -#define ST_SB4(...) ST_B4(v16i8, __VA_ARGS__) - -#define ST_B8(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride) \ - { \ - ST_B4(RTYPE, in0, in1, in2, in3, pdst, stride); \ - ST_B4(RTYPE, in4, in5, in6, in7, (pdst) + 4 * stride, stride); \ - } -#define ST_UB8(...) ST_B8(v16u8, __VA_ARGS__) - -/* Description : Store vectors of 8 halfword elements with stride - Arguments : Inputs - in0, in1, pdst, stride - Details : Store 8 halfword elements from 'in0' to (pdst) - Store 8 halfword elements from 'in1' to (pdst + stride) -*/ -#define ST_H2(RTYPE, in0, in1, pdst, stride) \ - { \ - ST_H(RTYPE, in0, (pdst)); \ - ST_H(RTYPE, in1, (pdst) + stride); \ - } -#define ST_SH2(...) ST_H2(v8i16, __VA_ARGS__) - -/* Description : Store vectors of word elements with stride - Arguments : Inputs - in0, in1, pdst, stride - Details : Store 4 word elements from 'in0' to (pdst) - Store 4 word elements from 'in1' to (pdst + stride) -*/ -#define ST_SW2(in0, in1, pdst, stride) \ - { \ - ST_SW(in0, (pdst)); \ - ST_SW(in1, (pdst) + stride); \ - } - -/* Description : Store 2x4 byte block to destination memory from input vector - Arguments : Inputs - in, stidx, pdst, stride - Details : Index 'stidx' halfword element from 'in' vector is copied to - the GP register and stored to (pdst) - Index 'stidx+1' halfword element from 'in' vector is copied to - the GP register and stored to (pdst + stride) - Index 'stidx+2' halfword element from 'in' vector is copied to - the GP register and stored to (pdst + 2 * stride) - Index 'stidx+3' halfword element from 'in' vector is copied to - the GP register and stored to (pdst + 3 * stride) -*/ -#define ST2x4_UB(in, stidx, pdst, stride) \ - { \ - uint16_t out0_m, out1_m, out2_m, out3_m; \ - uint8_t *pblk_2x4_m = (uint8_t *)(pdst); \ - \ - out0_m = __msa_copy_u_h((v8i16)in, (stidx)); \ - out1_m = __msa_copy_u_h((v8i16)in, (stidx + 1)); \ - out2_m = __msa_copy_u_h((v8i16)in, (stidx + 2)); \ - out3_m = __msa_copy_u_h((v8i16)in, (stidx + 3)); \ - \ - SH(out0_m, pblk_2x4_m); \ - SH(out1_m, pblk_2x4_m + stride); \ - SH(out2_m, pblk_2x4_m + 2 * stride); \ - SH(out3_m, pblk_2x4_m + 3 * stride); \ - } - -/* Description : Store 4x4 byte block to destination memory from input vector - Arguments : Inputs - in0, in1, pdst, stride - Details : 'Idx0' word element from input vector 'in0' is copied to the - GP register and stored to (pdst) - 'Idx1' word element from input vector 'in0' is copied to the - GP register and stored to (pdst + stride) - 'Idx2' word element from input vector 'in0' is copied to the - GP register and stored to (pdst + 2 * stride) - 'Idx3' word element from input vector 'in0' is copied to the - GP register and stored to (pdst + 3 * stride) -*/ -#define ST4x4_UB(in0, in1, idx0, idx1, idx2, idx3, pdst, stride) \ - { \ - uint32_t out0_m, out1_m, out2_m, out3_m; \ - uint8_t *pblk_4x4_m = (uint8_t *)(pdst); \ - \ - out0_m = __msa_copy_u_w((v4i32)in0, idx0); \ - out1_m = __msa_copy_u_w((v4i32)in0, idx1); \ - out2_m = __msa_copy_u_w((v4i32)in1, idx2); \ - out3_m = __msa_copy_u_w((v4i32)in1, idx3); \ - \ - SW4(out0_m, out1_m, out2_m, out3_m, pblk_4x4_m, stride); \ - } -#define ST4x8_UB(in0, in1, pdst, stride) \ - { \ - uint8_t *pblk_4x8 = (uint8_t *)(pdst); \ - \ - ST4x4_UB(in0, in0, 0, 1, 2, 3, pblk_4x8, stride); \ - ST4x4_UB(in1, in1, 0, 1, 2, 3, pblk_4x8 + 4 * stride, stride); \ - } - -/* Description : Store 8x1 byte block to destination memory from input vector - Arguments : Inputs - in, pdst - Details : Index 0 double word element from 'in' vector is copied to the - GP register and stored to (pdst) -*/ -#define ST8x1_UB(in, pdst) \ - { \ - uint64_t out0_m; \ - \ - out0_m = __msa_copy_u_d((v2i64)in, 0); \ - SD(out0_m, pdst); \ - } - -/* Description : Store 8x2 byte block to destination memory from input vector - Arguments : Inputs - in, pdst, stride - Details : Index 0 double word element from 'in' vector is copied to the - GP register and stored to (pdst) - Index 1 double word element from 'in' vector is copied to the - GP register and stored to (pdst + stride) -*/ -#define ST8x2_UB(in, pdst, stride) \ - { \ - uint64_t out0_m, out1_m; \ - uint8_t *pblk_8x2_m = (uint8_t *)(pdst); \ - \ - out0_m = __msa_copy_u_d((v2i64)in, 0); \ - out1_m = __msa_copy_u_d((v2i64)in, 1); \ - \ - SD(out0_m, pblk_8x2_m); \ - SD(out1_m, pblk_8x2_m + stride); \ - } - -/* Description : Store 8x4 byte block to destination memory from input - vectors - Arguments : Inputs - in0, in1, pdst, stride - Details : Index 0 double word element from 'in0' vector is copied to the - GP register and stored to (pdst) - Index 1 double word element from 'in0' vector is copied to the - GP register and stored to (pdst + stride) - Index 0 double word element from 'in1' vector is copied to the - GP register and stored to (pdst + 2 * stride) - Index 1 double word element from 'in1' vector is copied to the - GP register and stored to (pdst + 3 * stride) -*/ -#define ST8x4_UB(in0, in1, pdst, stride) \ - { \ - uint64_t out0_m, out1_m, out2_m, out3_m; \ - uint8_t *pblk_8x4_m = (uint8_t *)(pdst); \ - \ - out0_m = __msa_copy_u_d((v2i64)in0, 0); \ - out1_m = __msa_copy_u_d((v2i64)in0, 1); \ - out2_m = __msa_copy_u_d((v2i64)in1, 0); \ - out3_m = __msa_copy_u_d((v2i64)in1, 1); \ - \ - SD4(out0_m, out1_m, out2_m, out3_m, pblk_8x4_m, stride); \ - } - -/* Description : Immediate number of elements to slide with zero - Arguments : Inputs - in0, in1, slide_val - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Byte elements from 'zero_m' vector are slid into 'in0' by - value specified in the 'slide_val' -*/ -#define SLDI_B2_0(RTYPE, in0, in1, out0, out1, slide_val) \ - { \ - v16i8 zero_m = { 0 }; \ - \ - out0 = (RTYPE)__msa_sldi_b((v16i8)zero_m, (v16i8)in0, slide_val); \ - out1 = (RTYPE)__msa_sldi_b((v16i8)zero_m, (v16i8)in1, slide_val); \ - } -#define SLDI_B2_0_UB(...) SLDI_B2_0(v16u8, __VA_ARGS__) - -/* Description : Immediate number of elements to slide - Arguments : Inputs - in0_0, in0_1, in1_0, in1_1, slide_val - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Byte elements from 'in0_0' vector are slid into 'in1_0' by - value specified in the 'slide_val' -*/ -#define SLDI_B2(RTYPE, in0_0, in0_1, in1_0, in1_1, out0, out1, slide_val) \ - { \ - out0 = (RTYPE)__msa_sldi_b((v16i8)in0_0, (v16i8)in1_0, slide_val); \ - out1 = (RTYPE)__msa_sldi_b((v16i8)in0_1, (v16i8)in1_1, slide_val); \ - } - -#define SLDI_B3(RTYPE, in0_0, in0_1, in0_2, in1_0, in1_1, in1_2, out0, out1, \ - out2, slide_val) \ - { \ - SLDI_B2(RTYPE, in0_0, in0_1, in1_0, in1_1, out0, out1, slide_val); \ - out2 = (RTYPE)__msa_sldi_b((v16i8)in0_2, (v16i8)in1_2, slide_val); \ - } -#define SLDI_B3_UH(...) SLDI_B3(v8u16, __VA_ARGS__) - -/* Description : Shuffle byte vector elements as per mask vector - Arguments : Inputs - in0, in1, in2, in3, mask0, mask1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Byte elements from 'in0' & 'in1' are copied selectively to - 'out0' as per control vector 'mask0' -*/ -#define VSHF_B2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_vshf_b((v16i8)mask0, (v16i8)in1, (v16i8)in0); \ - out1 = (RTYPE)__msa_vshf_b((v16i8)mask1, (v16i8)in3, (v16i8)in2); \ - } -#define VSHF_B2_UB(...) VSHF_B2(v16u8, __VA_ARGS__) -#define VSHF_B2_SB(...) VSHF_B2(v16i8, __VA_ARGS__) -#define VSHF_B2_UH(...) VSHF_B2(v8u16, __VA_ARGS__) - -#define VSHF_B3(RTYPE, in0, in1, in2, in3, in4, in5, mask0, mask1, mask2, \ - out0, out1, out2) \ - { \ - VSHF_B2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1); \ - out2 = (RTYPE)__msa_vshf_b((v16i8)mask2, (v16i8)in5, (v16i8)in4); \ - } -#define VSHF_B3_SB(...) VSHF_B3(v16i8, __VA_ARGS__) - -/* Description : Shuffle halfword vector elements as per mask vector - Arguments : Inputs - in0, in1, in2, in3, mask0, mask1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : halfword elements from 'in0' & 'in1' are copied selectively to - 'out0' as per control vector 'mask0' -*/ -#define VSHF_H2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_vshf_h((v8i16)mask0, (v8i16)in1, (v8i16)in0); \ - out1 = (RTYPE)__msa_vshf_h((v8i16)mask1, (v8i16)in3, (v8i16)in2); \ - } -#define VSHF_H2_SH(...) VSHF_H2(v8i16, __VA_ARGS__) - -/* Description : Dot product of byte vector elements - Arguments : Inputs - mult0, mult1, cnst0, cnst1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Unsigned byte elements from 'mult0' are multiplied with - unsigned byte elements from 'cnst0' producing a result - twice the size of input i.e. unsigned halfword. - The multiplication result of adjacent odd-even elements - are added together and written to the 'out0' vector -*/ -#define DOTP_UB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_dotp_u_h((v16u8)mult0, (v16u8)cnst0); \ - out1 = (RTYPE)__msa_dotp_u_h((v16u8)mult1, (v16u8)cnst1); \ - } -#define DOTP_UB2_UH(...) DOTP_UB2(v8u16, __VA_ARGS__) - -#define DOTP_UB4(RTYPE, mult0, mult1, mult2, mult3, cnst0, cnst1, cnst2, \ - cnst3, out0, out1, out2, out3) \ - { \ - DOTP_UB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1); \ - DOTP_UB2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3); \ - } -#define DOTP_UB4_UH(...) DOTP_UB4(v8u16, __VA_ARGS__) - -/* Description : Dot product of byte vector elements - Arguments : Inputs - mult0, mult1, cnst0, cnst1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Signed byte elements from 'mult0' are multiplied with - signed byte elements from 'cnst0' producing a result - twice the size of input i.e. signed halfword. - The multiplication result of adjacent odd-even elements - are added together and written to the 'out0' vector -*/ -#define DOTP_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_dotp_s_h((v16i8)mult0, (v16i8)cnst0); \ - out1 = (RTYPE)__msa_dotp_s_h((v16i8)mult1, (v16i8)cnst1); \ - } -#define DOTP_SB2_SH(...) DOTP_SB2(v8i16, __VA_ARGS__) - -#define DOTP_SB4(RTYPE, mult0, mult1, mult2, mult3, cnst0, cnst1, cnst2, \ - cnst3, out0, out1, out2, out3) \ - { \ - DOTP_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1); \ - DOTP_SB2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3); \ - } -#define DOTP_SB4_SH(...) DOTP_SB4(v8i16, __VA_ARGS__) - -/* Description : Dot product of halfword vector elements - Arguments : Inputs - mult0, mult1, cnst0, cnst1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Signed halfword elements from 'mult0' are multiplied with - signed halfword elements from 'cnst0' producing a result - twice the size of input i.e. signed word. - The multiplication result of adjacent odd-even elements - are added together and written to the 'out0' vector -*/ -#define DOTP_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_dotp_s_w((v8i16)mult0, (v8i16)cnst0); \ - out1 = (RTYPE)__msa_dotp_s_w((v8i16)mult1, (v8i16)cnst1); \ - } - -#define DOTP_SH4(RTYPE, mult0, mult1, mult2, mult3, cnst0, cnst1, cnst2, \ - cnst3, out0, out1, out2, out3) \ - { \ - DOTP_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1); \ - DOTP_SH2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3); \ - } -#define DOTP_SH4_SW(...) DOTP_SH4(v4i32, __VA_ARGS__) - -/* Description : Dot product of word vector elements - Arguments : Inputs - mult0, mult1, cnst0, cnst1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Signed word elements from 'mult0' are multiplied with - signed word elements from 'cnst0' producing a result - twice the size of input i.e. signed double word. - The multiplication result of adjacent odd-even elements - are added together and written to the 'out0' vector -*/ -#define DOTP_SW2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_dotp_s_d((v4i32)mult0, (v4i32)cnst0); \ - out1 = (RTYPE)__msa_dotp_s_d((v4i32)mult1, (v4i32)cnst1); \ - } -#define DOTP_SW2_SD(...) DOTP_SW2(v2i64, __VA_ARGS__) - -/* Description : Dot product & addition of byte vector elements - Arguments : Inputs - mult0, mult1, cnst0, cnst1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Signed byte elements from 'mult0' are multiplied with - signed byte elements from 'cnst0' producing a result - twice the size of input i.e. signed halfword. - The multiplication result of adjacent odd-even elements - are added to the 'out0' vector -*/ -#define DPADD_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_dpadd_s_h((v8i16)out0, (v16i8)mult0, (v16i8)cnst0); \ - out1 = (RTYPE)__msa_dpadd_s_h((v8i16)out1, (v16i8)mult1, (v16i8)cnst1); \ - } -#define DPADD_SB2_SH(...) DPADD_SB2(v8i16, __VA_ARGS__) - -#define DPADD_SB4(RTYPE, mult0, mult1, mult2, mult3, cnst0, cnst1, cnst2, \ - cnst3, out0, out1, out2, out3) \ - { \ - DPADD_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1); \ - DPADD_SB2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3); \ - } -#define DPADD_SB4_SH(...) DPADD_SB4(v8i16, __VA_ARGS__) - -/* Description : Dot product & addition of halfword vector elements - Arguments : Inputs - mult0, mult1, cnst0, cnst1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Signed halfword elements from 'mult0' are multiplied with - signed halfword elements from 'cnst0' producing a result - twice the size of input i.e. signed word. - The multiplication result of adjacent odd-even elements - are added to the 'out0' vector -*/ -#define DPADD_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_dpadd_s_w((v4i32)out0, (v8i16)mult0, (v8i16)cnst0); \ - out1 = (RTYPE)__msa_dpadd_s_w((v4i32)out1, (v8i16)mult1, (v8i16)cnst1); \ - } -#define DPADD_SH2_SW(...) DPADD_SH2(v4i32, __VA_ARGS__) - -#define DPADD_SH4(RTYPE, mult0, mult1, mult2, mult3, cnst0, cnst1, cnst2, \ - cnst3, out0, out1, out2, out3) \ - { \ - DPADD_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1); \ - DPADD_SH2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3); \ - } -#define DPADD_SH4_SW(...) DPADD_SH4(v4i32, __VA_ARGS__) - -/* Description : Dot product & addition of double word vector elements - Arguments : Inputs - mult0, mult1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Each signed word element from 'mult0' is multiplied with itself - producing an intermediate result twice the size of it - i.e. signed double word - The multiplication result of adjacent odd-even elements - are added to the 'out0' vector -*/ -#define DPADD_SD2(RTYPE, mult0, mult1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_dpadd_s_d((v2i64)out0, (v4i32)mult0, (v4i32)mult0); \ - out1 = (RTYPE)__msa_dpadd_s_d((v2i64)out1, (v4i32)mult1, (v4i32)mult1); \ - } -#define DPADD_SD2_SD(...) DPADD_SD2(v2i64, __VA_ARGS__) - -/* Description : Clips all signed halfword elements of input vector - between 0 & 255 - Arguments : Input - in - Output - out_m - Return Type - signed halfword -*/ -#define CLIP_SH_0_255(in) \ - ({ \ - v8i16 max_m = __msa_ldi_h(255); \ - v8i16 out_m; \ - \ - out_m = __msa_maxi_s_h((v8i16)in, 0); \ - out_m = __msa_min_s_h((v8i16)max_m, (v8i16)out_m); \ - out_m; \ - }) -#define CLIP_SH2_0_255(in0, in1) \ - { \ - in0 = CLIP_SH_0_255(in0); \ - in1 = CLIP_SH_0_255(in1); \ - } -#define CLIP_SH4_0_255(in0, in1, in2, in3) \ - { \ - CLIP_SH2_0_255(in0, in1); \ - CLIP_SH2_0_255(in2, in3); \ - } - -/* Description : Clips all signed word elements of input vector - between 0 & 255 - Arguments : Input - in - Output - out_m - Return Type - signed word -*/ -#define CLIP_SW_0_255(in) \ - ({ \ - v4i32 max_m = __msa_ldi_w(255); \ - v4i32 out_m; \ - \ - out_m = __msa_maxi_s_w((v4i32)in, 0); \ - out_m = __msa_min_s_w((v4i32)max_m, (v4i32)out_m); \ - out_m; \ - }) - -/* Description : Horizontal addition of 4 signed word elements of input vector - Arguments : Input - in (signed word vector) - Output - sum_m (i32 sum) - Return Type - signed word (GP) - Details : 4 signed word elements of 'in' vector are added together and - the resulting integer sum is returned -*/ -#define HADD_SW_S32(in) \ - ({ \ - v2i64 res0_m, res1_m; \ - int32_t sum_m; \ - \ - res0_m = __msa_hadd_s_d((v4i32)in, (v4i32)in); \ - res1_m = __msa_splati_d(res0_m, 1); \ - res0_m = res0_m + res1_m; \ - sum_m = __msa_copy_s_w((v4i32)res0_m, 0); \ - sum_m; \ - }) - -/* Description : Horizontal addition of 8 unsigned halfword elements - Arguments : Inputs - in (unsigned halfword vector) - Outputs - sum_m (u32 sum) - Return Type - unsigned word - Details : 8 unsigned halfword elements of input vector are added - together and the resulting integer sum is returned -*/ -#define HADD_UH_U32(in) \ - ({ \ - v4u32 res_m; \ - v2u64 res0_m, res1_m; \ - uint32_t sum_m; \ - \ - res_m = __msa_hadd_u_w((v8u16)in, (v8u16)in); \ - res0_m = __msa_hadd_u_d(res_m, res_m); \ - res1_m = (v2u64)__msa_splati_d((v2i64)res0_m, 1); \ - res0_m = res0_m + res1_m; \ - sum_m = __msa_copy_u_w((v4i32)res0_m, 0); \ - sum_m; \ - }) - -/* Description : Horizontal addition of unsigned byte vector elements - Arguments : Inputs - in0, in1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Each unsigned odd byte element from 'in0' is added to - even unsigned byte element from 'in0' (pairwise) and the - halfword result is written to 'out0' -*/ -#define HADD_UB2(RTYPE, in0, in1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_hadd_u_h((v16u8)in0, (v16u8)in0); \ - out1 = (RTYPE)__msa_hadd_u_h((v16u8)in1, (v16u8)in1); \ - } -#define HADD_UB2_UH(...) HADD_UB2(v8u16, __VA_ARGS__) - -/* Description : Horizontal subtraction of unsigned byte vector elements - Arguments : Inputs - in0, in1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Each unsigned odd byte element from 'in0' is subtracted from - even unsigned byte element from 'in0' (pairwise) and the - halfword result is written to 'out0' -*/ -#define HSUB_UB2(RTYPE, in0, in1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_hsub_u_h((v16u8)in0, (v16u8)in0); \ - out1 = (RTYPE)__msa_hsub_u_h((v16u8)in1, (v16u8)in1); \ - } -#define HSUB_UB2_SH(...) HSUB_UB2(v8i16, __VA_ARGS__) - -/* Description : Horizontal subtraction of signed halfword vector elements - Arguments : Inputs - in0, in1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Each signed odd halfword element from 'in0' is subtracted from - even signed halfword element from 'in0' (pairwise) and the - word result is written to 'out0' -*/ -#define HSUB_UH2(RTYPE, in0, in1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_hsub_s_w((v8i16)in0, (v8i16)in0); \ - out1 = (RTYPE)__msa_hsub_s_w((v8i16)in1, (v8i16)in1); \ - } -#define HSUB_UH2_SW(...) HSUB_UH2(v4i32, __VA_ARGS__) - -/* Description : Set element n input vector to GPR value - Arguments : Inputs - in0, in1, in2, in3 - Output - out - Return Type - as per RTYPE - Details : Set element 0 in vector 'out' to value specified in 'in0' -*/ -#define INSERT_D2(RTYPE, in0, in1, out) \ - { \ - out = (RTYPE)__msa_insert_d((v2i64)out, 0, in0); \ - out = (RTYPE)__msa_insert_d((v2i64)out, 1, in1); \ - } -#define INSERT_D2_SB(...) INSERT_D2(v16i8, __VA_ARGS__) - -/* Description : Interleave even byte elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Even byte elements of 'in0' and 'in1' are interleaved - and written to 'out0' -*/ -#define ILVEV_B2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvev_b((v16i8)in1, (v16i8)in0); \ - out1 = (RTYPE)__msa_ilvev_b((v16i8)in3, (v16i8)in2); \ - } -#define ILVEV_B2_UB(...) ILVEV_B2(v16u8, __VA_ARGS__) -#define ILVEV_B2_SH(...) ILVEV_B2(v8i16, __VA_ARGS__) -#define ILVEV_B2_SD(...) ILVEV_B2(v2i64, __VA_ARGS__) - -/* Description : Interleave even halfword elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Even halfword elements of 'in0' and 'in1' are interleaved - and written to 'out0' -*/ -#define ILVEV_H2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvev_h((v8i16)in1, (v8i16)in0); \ - out1 = (RTYPE)__msa_ilvev_h((v8i16)in3, (v8i16)in2); \ - } -#define ILVEV_H2_UB(...) ILVEV_H2(v16u8, __VA_ARGS__) -#define ILVEV_H2_SH(...) ILVEV_H2(v8i16, __VA_ARGS__) - -/* Description : Interleave even word elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Even word elements of 'in0' and 'in1' are interleaved - and written to 'out0' -*/ -#define ILVEV_W2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvev_w((v4i32)in1, (v4i32)in0); \ - out1 = (RTYPE)__msa_ilvev_w((v4i32)in3, (v4i32)in2); \ - } -#define ILVEV_W2_SD(...) ILVEV_W2(v2i64, __VA_ARGS__) - -/* Description : Interleave even double word elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Even double word elements of 'in0' and 'in1' are interleaved - and written to 'out0' -*/ -#define ILVEV_D2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvev_d((v2i64)in1, (v2i64)in0); \ - out1 = (RTYPE)__msa_ilvev_d((v2i64)in3, (v2i64)in2); \ - } -#define ILVEV_D2_UB(...) ILVEV_D2(v16u8, __VA_ARGS__) - -/* Description : Interleave left half of byte elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Left half of byte elements of 'in0' and 'in1' are interleaved - and written to 'out0'. -*/ -#define ILVL_B2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvl_b((v16i8)in0, (v16i8)in1); \ - out1 = (RTYPE)__msa_ilvl_b((v16i8)in2, (v16i8)in3); \ - } -#define ILVL_B2_UB(...) ILVL_B2(v16u8, __VA_ARGS__) -#define ILVL_B2_SB(...) ILVL_B2(v16i8, __VA_ARGS__) -#define ILVL_B2_SH(...) ILVL_B2(v8i16, __VA_ARGS__) - -#define ILVL_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3) \ - { \ - ILVL_B2(RTYPE, in0, in1, in2, in3, out0, out1); \ - ILVL_B2(RTYPE, in4, in5, in6, in7, out2, out3); \ - } -#define ILVL_B4_SB(...) ILVL_B4(v16i8, __VA_ARGS__) -#define ILVL_B4_SH(...) ILVL_B4(v8i16, __VA_ARGS__) - -/* Description : Interleave left half of halfword elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Left half of halfword elements of 'in0' and 'in1' are - interleaved and written to 'out0'. -*/ -#define ILVL_H2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvl_h((v8i16)in0, (v8i16)in1); \ - out1 = (RTYPE)__msa_ilvl_h((v8i16)in2, (v8i16)in3); \ - } -#define ILVL_H2_SH(...) ILVL_H2(v8i16, __VA_ARGS__) -#define ILVL_H2_SW(...) ILVL_H2(v4i32, __VA_ARGS__) - -/* Description : Interleave left half of word elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Left half of word elements of 'in0' and 'in1' are interleaved - and written to 'out0'. -*/ -#define ILVL_W2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvl_w((v4i32)in0, (v4i32)in1); \ - out1 = (RTYPE)__msa_ilvl_w((v4i32)in2, (v4i32)in3); \ - } -#define ILVL_W2_SH(...) ILVL_W2(v8i16, __VA_ARGS__) - -/* Description : Interleave right half of byte elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Right half of byte elements of 'in0' and 'in1' are interleaved - and written to out0. -*/ -#define ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvr_b((v16i8)in0, (v16i8)in1); \ - out1 = (RTYPE)__msa_ilvr_b((v16i8)in2, (v16i8)in3); \ - } -#define ILVR_B2_UB(...) ILVR_B2(v16u8, __VA_ARGS__) -#define ILVR_B2_SB(...) ILVR_B2(v16i8, __VA_ARGS__) -#define ILVR_B2_SH(...) ILVR_B2(v8i16, __VA_ARGS__) -#define ILVR_B2_SW(...) ILVR_B2(v4i32, __VA_ARGS__) - -#define ILVR_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3) \ - { \ - ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1); \ - ILVR_B2(RTYPE, in4, in5, in6, in7, out2, out3); \ - } -#define ILVR_B4_UB(...) ILVR_B4(v16u8, __VA_ARGS__) -#define ILVR_B4_SB(...) ILVR_B4(v16i8, __VA_ARGS__) -#define ILVR_B4_UH(...) ILVR_B4(v8u16, __VA_ARGS__) -#define ILVR_B4_SH(...) ILVR_B4(v8i16, __VA_ARGS__) -#define ILVR_B4_SW(...) ILVR_B4(v4i32, __VA_ARGS__) - -/* Description : Interleave right half of halfword elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Right half of halfword elements of 'in0' and 'in1' are - interleaved and written to 'out0'. -*/ -#define ILVR_H2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvr_h((v8i16)in0, (v8i16)in1); \ - out1 = (RTYPE)__msa_ilvr_h((v8i16)in2, (v8i16)in3); \ - } -#define ILVR_H2_SH(...) ILVR_H2(v8i16, __VA_ARGS__) -#define ILVR_H2_SW(...) ILVR_H2(v4i32, __VA_ARGS__) - -#define ILVR_H4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3) \ - { \ - ILVR_H2(RTYPE, in0, in1, in2, in3, out0, out1); \ - ILVR_H2(RTYPE, in4, in5, in6, in7, out2, out3); \ - } -#define ILVR_H4_SH(...) ILVR_H4(v8i16, __VA_ARGS__) -#define ILVR_H4_SW(...) ILVR_H4(v4i32, __VA_ARGS__) - -#define ILVR_W2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvr_w((v4i32)in0, (v4i32)in1); \ - out1 = (RTYPE)__msa_ilvr_w((v4i32)in2, (v4i32)in3); \ - } -#define ILVR_W2_SH(...) ILVR_W2(v8i16, __VA_ARGS__) - -/* Description : Interleave right half of double word elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Right half of double word elements of 'in0' and 'in1' are - interleaved and written to 'out0'. -*/ -#define ILVR_D2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvr_d((v2i64)(in0), (v2i64)(in1)); \ - out1 = (RTYPE)__msa_ilvr_d((v2i64)(in2), (v2i64)(in3)); \ - } -#define ILVR_D2_UB(...) ILVR_D2(v16u8, __VA_ARGS__) -#define ILVR_D2_SB(...) ILVR_D2(v16i8, __VA_ARGS__) -#define ILVR_D2_SH(...) ILVR_D2(v8i16, __VA_ARGS__) - -#define ILVR_D4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3) \ - { \ - ILVR_D2(RTYPE, in0, in1, in2, in3, out0, out1); \ - ILVR_D2(RTYPE, in4, in5, in6, in7, out2, out3); \ - } -#define ILVR_D4_SB(...) ILVR_D4(v16i8, __VA_ARGS__) -#define ILVR_D4_UB(...) ILVR_D4(v16u8, __VA_ARGS__) - -/* Description : Interleave both left and right half of input vectors - Arguments : Inputs - in0, in1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Right half of byte elements from 'in0' and 'in1' are - interleaved and written to 'out0' -*/ -#define ILVRL_B2(RTYPE, in0, in1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvr_b((v16i8)in0, (v16i8)in1); \ - out1 = (RTYPE)__msa_ilvl_b((v16i8)in0, (v16i8)in1); \ - } -#define ILVRL_B2_UB(...) ILVRL_B2(v16u8, __VA_ARGS__) -#define ILVRL_B2_SB(...) ILVRL_B2(v16i8, __VA_ARGS__) -#define ILVRL_B2_UH(...) ILVRL_B2(v8u16, __VA_ARGS__) -#define ILVRL_B2_SH(...) ILVRL_B2(v8i16, __VA_ARGS__) - -#define ILVRL_H2(RTYPE, in0, in1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvr_h((v8i16)in0, (v8i16)in1); \ - out1 = (RTYPE)__msa_ilvl_h((v8i16)in0, (v8i16)in1); \ - } -#define ILVRL_H2_SH(...) ILVRL_H2(v8i16, __VA_ARGS__) -#define ILVRL_H2_SW(...) ILVRL_H2(v4i32, __VA_ARGS__) - -#define ILVRL_W2(RTYPE, in0, in1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvr_w((v4i32)in0, (v4i32)in1); \ - out1 = (RTYPE)__msa_ilvl_w((v4i32)in0, (v4i32)in1); \ - } -#define ILVRL_W2_UB(...) ILVRL_W2(v16u8, __VA_ARGS__) -#define ILVRL_W2_SH(...) ILVRL_W2(v8i16, __VA_ARGS__) -#define ILVRL_W2_SW(...) ILVRL_W2(v4i32, __VA_ARGS__) - -/* Description : Maximum values between signed elements of vector and - 5-bit signed immediate value are copied to the output vector - Arguments : Inputs - in0, in1, in2, in3, max_val - Outputs - in place operation - Return Type - unsigned halfword - Details : Maximum of signed halfword element values from 'in0' and - 'max_val' are written in place -*/ -#define MAXI_SH2(RTYPE, in0, in1, max_val) \ - { \ - in0 = (RTYPE)__msa_maxi_s_h((v8i16)in0, (max_val)); \ - in1 = (RTYPE)__msa_maxi_s_h((v8i16)in1, (max_val)); \ - } -#define MAXI_SH2_SH(...) MAXI_SH2(v8i16, __VA_ARGS__) - -/* Description : Saturate the halfword element values to the max - unsigned value of (sat_val + 1) bits - The element data width remains unchanged - Arguments : Inputs - in0, in1, sat_val - Outputs - in place operation - Return Type - as per RTYPE - Details : Each unsigned halfword element from 'in0' is saturated to the - value generated with (sat_val + 1) bit range. - The results are written in place -*/ -#define SAT_UH2(RTYPE, in0, in1, sat_val) \ - { \ - in0 = (RTYPE)__msa_sat_u_h((v8u16)in0, sat_val); \ - in1 = (RTYPE)__msa_sat_u_h((v8u16)in1, sat_val); \ - } -#define SAT_UH2_SH(...) SAT_UH2(v8i16, __VA_ARGS__) - -/* Description : Saturate the halfword element values to the max - unsigned value of (sat_val + 1) bits - The element data width remains unchanged - Arguments : Inputs - in0, in1, sat_val - Outputs - in place operation - Return Type - as per RTYPE - Details : Each unsigned halfword element from 'in0' is saturated to the - value generated with (sat_val + 1) bit range - The results are written in place -*/ -#define SAT_SH2(RTYPE, in0, in1, sat_val) \ - { \ - in0 = (RTYPE)__msa_sat_s_h((v8i16)in0, sat_val); \ - in1 = (RTYPE)__msa_sat_s_h((v8i16)in1, sat_val); \ - } -#define SAT_SH2_SH(...) SAT_SH2(v8i16, __VA_ARGS__) - -#define SAT_SH4(RTYPE, in0, in1, in2, in3, sat_val) \ - { \ - SAT_SH2(RTYPE, in0, in1, sat_val); \ - SAT_SH2(RTYPE, in2, in3, sat_val); \ - } -#define SAT_SH4_SH(...) SAT_SH4(v8i16, __VA_ARGS__) - -/* Description : Indexed halfword element values are replicated to all - elements in output vector - Arguments : Inputs - in, idx0, idx1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : 'idx0' element value from 'in' vector is replicated to all - elements in 'out0' vector - Valid index range for halfword operation is 0-7 -*/ -#define SPLATI_H2(RTYPE, in, idx0, idx1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_splati_h((v8i16)in, idx0); \ - out1 = (RTYPE)__msa_splati_h((v8i16)in, idx1); \ - } -#define SPLATI_H2_SB(...) SPLATI_H2(v16i8, __VA_ARGS__) -#define SPLATI_H2_SH(...) SPLATI_H2(v8i16, __VA_ARGS__) - -#define SPLATI_H3(RTYPE, in, idx0, idx1, idx2, out0, out1, out2) \ - { \ - SPLATI_H2(RTYPE, in, idx0, idx1, out0, out1); \ - out2 = (RTYPE)__msa_splati_h((v8i16)in, idx2); \ - } -#define SPLATI_H3_SB(...) SPLATI_H3(v16i8, __VA_ARGS__) -#define SPLATI_H3_SH(...) SPLATI_H3(v8i16, __VA_ARGS__) - -/* Description : Indexed word element values are replicated to all - elements in output vector - Arguments : Inputs - in, stidx - Outputs - out0, out1 - Return Type - as per RTYPE - Details : 'stidx' element value from 'in' vector is replicated to all - elements in 'out0' vector - 'stidx + 1' element value from 'in' vector is replicated to all - elements in 'out1' vector - Valid index range for word operation is 0-3 -*/ -#define SPLATI_W2(RTYPE, in, stidx, out0, out1) \ - { \ - out0 = (RTYPE)__msa_splati_w((v4i32)in, stidx); \ - out1 = (RTYPE)__msa_splati_w((v4i32)in, (stidx + 1)); \ - } -#define SPLATI_W2_SW(...) SPLATI_W2(v4i32, __VA_ARGS__) - -/* Description : Pack even byte elements of vector pairs - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Even byte elements of 'in0' are copied to the left half of - 'out0' & even byte elements of 'in1' are copied to the right - half of 'out0'. -*/ -#define PCKEV_B2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_pckev_b((v16i8)in0, (v16i8)in1); \ - out1 = (RTYPE)__msa_pckev_b((v16i8)in2, (v16i8)in3); \ - } -#define PCKEV_B2_SB(...) PCKEV_B2(v16i8, __VA_ARGS__) -#define PCKEV_B2_UB(...) PCKEV_B2(v16u8, __VA_ARGS__) -#define PCKEV_B2_SH(...) PCKEV_B2(v8i16, __VA_ARGS__) -#define PCKEV_B2_SW(...) PCKEV_B2(v4i32, __VA_ARGS__) - -#define PCKEV_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3) \ - { \ - PCKEV_B2(RTYPE, in0, in1, in2, in3, out0, out1); \ - PCKEV_B2(RTYPE, in4, in5, in6, in7, out2, out3); \ - } -#define PCKEV_B4_SB(...) PCKEV_B4(v16i8, __VA_ARGS__) -#define PCKEV_B4_UB(...) PCKEV_B4(v16u8, __VA_ARGS__) -#define PCKEV_B4_SH(...) PCKEV_B4(v8i16, __VA_ARGS__) - -/* Description : Pack even halfword elements of vector pairs - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Even halfword elements of 'in0' are copied to the left half of - 'out0' & even halfword elements of 'in1' are copied to the - right half of 'out0'. -*/ -#define PCKEV_H2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_pckev_h((v8i16)in0, (v8i16)in1); \ - out1 = (RTYPE)__msa_pckev_h((v8i16)in2, (v8i16)in3); \ - } -#define PCKEV_H2_SH(...) PCKEV_H2(v8i16, __VA_ARGS__) - -#define PCKEV_H4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3) \ - { \ - PCKEV_H2(RTYPE, in0, in1, in2, in3, out0, out1); \ - PCKEV_H2(RTYPE, in4, in5, in6, in7, out2, out3); \ - } -#define PCKEV_H4_SH(...) PCKEV_H4(v8i16, __VA_ARGS__) - -/* Description : Pack even double word elements of vector pairs - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Even double elements of 'in0' are copied to the left half of - 'out0' & even double elements of 'in1' are copied to the right - half of 'out0'. -*/ -#define PCKEV_D2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_pckev_d((v2i64)in0, (v2i64)in1); \ - out1 = (RTYPE)__msa_pckev_d((v2i64)in2, (v2i64)in3); \ - } -#define PCKEV_D2_UB(...) PCKEV_D2(v16u8, __VA_ARGS__) -#define PCKEV_D2_SH(...) PCKEV_D2(v8i16, __VA_ARGS__) - -/* Description : Pack odd double word elements of vector pairs - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Odd double word elements of 'in0' are copied to the left half - of 'out0' & odd double word elements of 'in1' are copied to - the right half of 'out0'. -*/ -#define PCKOD_D2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_pckod_d((v2i64)in0, (v2i64)in1); \ - out1 = (RTYPE)__msa_pckod_d((v2i64)in2, (v2i64)in3); \ - } -#define PCKOD_D2_UB(...) PCKOD_D2(v16u8, __VA_ARGS__) -#define PCKOD_D2_SH(...) PCKOD_D2(v8i16, __VA_ARGS__) - -/* Description : Each byte element is logically xor'ed with immediate 128 - Arguments : Inputs - in0, in1 - Outputs - in place operation - Return Type - as per RTYPE - Details : Each unsigned byte element from input vector 'in0' is - logically xor'ed with 128 and the result is stored in-place. -*/ -#define XORI_B2_128(RTYPE, in0, in1) \ - { \ - in0 = (RTYPE)__msa_xori_b((v16u8)in0, 128); \ - in1 = (RTYPE)__msa_xori_b((v16u8)in1, 128); \ - } -#define XORI_B2_128_UB(...) XORI_B2_128(v16u8, __VA_ARGS__) -#define XORI_B2_128_SB(...) XORI_B2_128(v16i8, __VA_ARGS__) - -#define XORI_B3_128(RTYPE, in0, in1, in2) \ - { \ - XORI_B2_128(RTYPE, in0, in1); \ - in2 = (RTYPE)__msa_xori_b((v16u8)in2, 128); \ - } -#define XORI_B3_128_SB(...) XORI_B3_128(v16i8, __VA_ARGS__) - -#define XORI_B4_128(RTYPE, in0, in1, in2, in3) \ - { \ - XORI_B2_128(RTYPE, in0, in1); \ - XORI_B2_128(RTYPE, in2, in3); \ - } -#define XORI_B4_128_UB(...) XORI_B4_128(v16u8, __VA_ARGS__) -#define XORI_B4_128_SB(...) XORI_B4_128(v16i8, __VA_ARGS__) - -#define XORI_B5_128(RTYPE, in0, in1, in2, in3, in4) \ - { \ - XORI_B3_128(RTYPE, in0, in1, in2); \ - XORI_B2_128(RTYPE, in3, in4); \ - } -#define XORI_B5_128_SB(...) XORI_B5_128(v16i8, __VA_ARGS__) - -#define XORI_B8_128(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7) \ - { \ - XORI_B4_128(RTYPE, in0, in1, in2, in3); \ - XORI_B4_128(RTYPE, in4, in5, in6, in7); \ - } -#define XORI_B8_128_SB(...) XORI_B8_128(v16i8, __VA_ARGS__) - -/* Description : Shift left all elements of vector (generic for all data types) - Arguments : Inputs - in0, in1, in2, in3, shift - Outputs - in place operation - Return Type - as per input vector RTYPE - Details : Each element of vector 'in0' is left shifted by 'shift' and - the result is written in-place. -*/ -#define SLLI_4V(in0, in1, in2, in3, shift) \ - { \ - in0 = in0 << shift; \ - in1 = in1 << shift; \ - in2 = in2 << shift; \ - in3 = in3 << shift; \ - } - -/* Description : Arithmetic shift right all elements of vector - (generic for all data types) - Arguments : Inputs - in0, in1, in2, in3, shift - Outputs - in place operation - Return Type - as per input vector RTYPE - Details : Each element of vector 'in0' is right shifted by 'shift' and - the result is written in-place. 'shift' is a GP variable. -*/ -#define SRA_4V(in0, in1, in2, in3, shift) \ - { \ - in0 = in0 >> shift; \ - in1 = in1 >> shift; \ - in2 = in2 >> shift; \ - in3 = in3 >> shift; \ - } - -/* Description : Shift right arithmetic rounded words - Arguments : Inputs - in0, in1, shift - Outputs - in place operation - Return Type - as per RTYPE - Details : Each element of vector 'in0' is shifted right arithmetically by - the number of bits in the corresponding element in the vector - 'shift'. The last discarded bit is added to shifted value for - rounding and the result is written in-place. - 'shift' is a vector. -*/ -#define SRAR_W2(RTYPE, in0, in1, shift) \ - { \ - in0 = (RTYPE)__msa_srar_w((v4i32)in0, (v4i32)shift); \ - in1 = (RTYPE)__msa_srar_w((v4i32)in1, (v4i32)shift); \ - } - -#define SRAR_W4(RTYPE, in0, in1, in2, in3, shift) \ - { \ - SRAR_W2(RTYPE, in0, in1, shift); \ - SRAR_W2(RTYPE, in2, in3, shift); \ - } -#define SRAR_W4_SW(...) SRAR_W4(v4i32, __VA_ARGS__) - -/* Description : Shift right arithmetic rounded (immediate) - Arguments : Inputs - in0, in1, shift - Outputs - in place operation - Return Type - as per RTYPE - Details : Each element of vector 'in0' is shifted right arithmetically by - the value in 'shift'. The last discarded bit is added to the - shifted value for rounding and the result is written in-place. - 'shift' is an immediate value. -*/ -#define SRARI_H2(RTYPE, in0, in1, shift) \ - { \ - in0 = (RTYPE)__msa_srari_h((v8i16)in0, shift); \ - in1 = (RTYPE)__msa_srari_h((v8i16)in1, shift); \ - } -#define SRARI_H2_UH(...) SRARI_H2(v8u16, __VA_ARGS__) -#define SRARI_H2_SH(...) SRARI_H2(v8i16, __VA_ARGS__) - -#define SRARI_H4(RTYPE, in0, in1, in2, in3, shift) \ - { \ - SRARI_H2(RTYPE, in0, in1, shift); \ - SRARI_H2(RTYPE, in2, in3, shift); \ - } -#define SRARI_H4_UH(...) SRARI_H4(v8u16, __VA_ARGS__) -#define SRARI_H4_SH(...) SRARI_H4(v8i16, __VA_ARGS__) - -#define SRARI_W2(RTYPE, in0, in1, shift) \ - { \ - in0 = (RTYPE)__msa_srari_w((v4i32)in0, shift); \ - in1 = (RTYPE)__msa_srari_w((v4i32)in1, shift); \ - } - -#define SRARI_W4(RTYPE, in0, in1, in2, in3, shift) \ - { \ - SRARI_W2(RTYPE, in0, in1, shift); \ - SRARI_W2(RTYPE, in2, in3, shift); \ - } -#define SRARI_W4_SW(...) SRARI_W4(v4i32, __VA_ARGS__) - -/* Description : Multiplication of pairs of vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Details : Each element from 'in0' is multiplied with elements from 'in1' - and the result is written to 'out0' -*/ -#define MUL2(in0, in1, in2, in3, out0, out1) \ - { \ - out0 = in0 * in1; \ - out1 = in2 * in3; \ - } -#define MUL4(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, out3) \ - { \ - MUL2(in0, in1, in2, in3, out0, out1); \ - MUL2(in4, in5, in6, in7, out2, out3); \ - } - -/* Description : Addition of 2 pairs of vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Details : Each element in 'in0' is added to 'in1' and result is written - to 'out0'. -*/ -#define ADD2(in0, in1, in2, in3, out0, out1) \ - { \ - out0 = in0 + in1; \ - out1 = in2 + in3; \ - } -#define ADD4(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, out3) \ - { \ - ADD2(in0, in1, in2, in3, out0, out1); \ - ADD2(in4, in5, in6, in7, out2, out3); \ - } - -/* Description : Subtraction of 2 pairs of vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Details : Each element in 'in1' is subtracted from 'in0' and result is - written to 'out0'. -*/ -#define SUB2(in0, in1, in2, in3, out0, out1) \ - { \ - out0 = in0 - in1; \ - out1 = in2 - in3; \ - } -#define SUB4(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, out3) \ - { \ - out0 = in0 - in1; \ - out1 = in2 - in3; \ - out2 = in4 - in5; \ - out3 = in6 - in7; \ - } - -/* Description : Sign extend halfword elements from right half of the vector - Arguments : Input - in (halfword vector) - Output - out (sign extended word vector) - Return Type - signed word - Details : Sign bit of halfword elements from input vector 'in' is - extracted and interleaved with same vector 'in0' to generate - 4 word elements keeping sign intact -*/ -#define UNPCK_R_SH_SW(in, out) \ - { \ - v8i16 sign_m; \ - \ - sign_m = __msa_clti_s_h((v8i16)in, 0); \ - out = (v4i32)__msa_ilvr_h(sign_m, (v8i16)in); \ - } - -/* Description : Zero extend unsigned byte elements to halfword elements - Arguments : Input - in (unsigned byte vector) - Outputs - out0, out1 (unsigned halfword vectors) - Return Type - signed halfword - Details : Zero extended right half of vector is returned in 'out0' - Zero extended left half of vector is returned in 'out1' -*/ -#define UNPCK_UB_SH(in, out0, out1) \ - { \ - v16i8 zero_m = { 0 }; \ - \ - ILVRL_B2_SH(zero_m, in, out0, out1); \ - } - -/* Description : Sign extend halfword elements from input vector and return - the result in pair of vectors - Arguments : Input - in (halfword vector) - Outputs - out0, out1 (sign extended word vectors) - Return Type - signed word - Details : Sign bit of halfword elements from input vector 'in' is - extracted and interleaved right with same vector 'in0' to - generate 4 signed word elements in 'out0' - Then interleaved left with same vector 'in0' to - generate 4 signed word elements in 'out1' -*/ -#define UNPCK_SH_SW(in, out0, out1) \ - { \ - v8i16 tmp_m; \ - \ - tmp_m = __msa_clti_s_h((v8i16)in, 0); \ - ILVRL_H2_SW(tmp_m, in, out0, out1); \ - } - -/* Description : Butterfly of 4 input vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1, out2, out3 - Details : Butterfly operation -*/ -#define BUTTERFLY_4(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - out0 = in0 + in3; \ - out1 = in1 + in2; \ - \ - out2 = in1 - in2; \ - out3 = in0 - in3; \ - } - -/* Description : Transpose input 8x8 byte block - Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7 - Outputs - out0, out1, out2, out3, out4, out5, out6, out7 - Return Type - as per RTYPE -*/ -#define TRANSPOSE8x8_UB(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, \ - out1, out2, out3, out4, out5, out6, out7) \ - { \ - v16i8 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ - v16i8 tmp4_m, tmp5_m, tmp6_m, tmp7_m; \ - \ - ILVR_B4_SB(in2, in0, in3, in1, in6, in4, in7, in5, tmp0_m, tmp1_m, tmp2_m, \ - tmp3_m); \ - ILVRL_B2_SB(tmp1_m, tmp0_m, tmp4_m, tmp5_m); \ - ILVRL_B2_SB(tmp3_m, tmp2_m, tmp6_m, tmp7_m); \ - ILVRL_W2(RTYPE, tmp6_m, tmp4_m, out0, out2); \ - ILVRL_W2(RTYPE, tmp7_m, tmp5_m, out4, out6); \ - SLDI_B2_0(RTYPE, out0, out2, out1, out3, 8); \ - SLDI_B2_0(RTYPE, out4, out6, out5, out7, 8); \ - } -#define TRANSPOSE8x8_UB_UB(...) TRANSPOSE8x8_UB(v16u8, __VA_ARGS__) - -/* Description : Transpose 16x4 block into 4x16 with byte elements in vectors - Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7, - in8, in9, in10, in11, in12, in13, in14, in15 - Outputs - out0, out1, out2, out3 - Return Type - unsigned byte -*/ -#define TRANSPOSE16x4_UB_UB(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, \ - in10, in11, in12, in13, in14, in15, out0, out1, \ - out2, out3) \ - { \ - v2i64 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ - \ - ILVEV_W2_SD(in0, in4, in8, in12, tmp0_m, tmp1_m); \ - out1 = (v16u8)__msa_ilvev_d(tmp1_m, tmp0_m); \ - \ - ILVEV_W2_SD(in1, in5, in9, in13, tmp0_m, tmp1_m); \ - out3 = (v16u8)__msa_ilvev_d(tmp1_m, tmp0_m); \ - \ - ILVEV_W2_SD(in2, in6, in10, in14, tmp0_m, tmp1_m); \ - \ - tmp2_m = __msa_ilvev_d(tmp1_m, tmp0_m); \ - ILVEV_W2_SD(in3, in7, in11, in15, tmp0_m, tmp1_m); \ - \ - tmp3_m = __msa_ilvev_d(tmp1_m, tmp0_m); \ - ILVEV_B2_SD(out1, out3, tmp2_m, tmp3_m, tmp0_m, tmp1_m); \ - out0 = (v16u8)__msa_ilvev_h((v8i16)tmp1_m, (v8i16)tmp0_m); \ - out2 = (v16u8)__msa_ilvod_h((v8i16)tmp1_m, (v8i16)tmp0_m); \ - \ - tmp0_m = (v2i64)__msa_ilvod_b((v16i8)out3, (v16i8)out1); \ - tmp1_m = (v2i64)__msa_ilvod_b((v16i8)tmp3_m, (v16i8)tmp2_m); \ - out1 = (v16u8)__msa_ilvev_h((v8i16)tmp1_m, (v8i16)tmp0_m); \ - out3 = (v16u8)__msa_ilvod_h((v8i16)tmp1_m, (v8i16)tmp0_m); \ - } - -/* Description : Transpose 16x8 block into 8x16 with byte elements in vectors - Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7, - in8, in9, in10, in11, in12, in13, in14, in15 - Outputs - out0, out1, out2, out3, out4, out5, out6, out7 - Return Type - unsigned byte -*/ -#define TRANSPOSE16x8_UB_UB(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, \ - in10, in11, in12, in13, in14, in15, out0, out1, \ - out2, out3, out4, out5, out6, out7) \ - { \ - v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ - v16u8 tmp4_m, tmp5_m, tmp6_m, tmp7_m; \ - \ - ILVEV_D2_UB(in0, in8, in1, in9, out7, out6); \ - ILVEV_D2_UB(in2, in10, in3, in11, out5, out4); \ - ILVEV_D2_UB(in4, in12, in5, in13, out3, out2); \ - ILVEV_D2_UB(in6, in14, in7, in15, out1, out0); \ - \ - tmp0_m = (v16u8)__msa_ilvev_b((v16i8)out6, (v16i8)out7); \ - tmp4_m = (v16u8)__msa_ilvod_b((v16i8)out6, (v16i8)out7); \ - tmp1_m = (v16u8)__msa_ilvev_b((v16i8)out4, (v16i8)out5); \ - tmp5_m = (v16u8)__msa_ilvod_b((v16i8)out4, (v16i8)out5); \ - out5 = (v16u8)__msa_ilvev_b((v16i8)out2, (v16i8)out3); \ - tmp6_m = (v16u8)__msa_ilvod_b((v16i8)out2, (v16i8)out3); \ - out7 = (v16u8)__msa_ilvev_b((v16i8)out0, (v16i8)out1); \ - tmp7_m = (v16u8)__msa_ilvod_b((v16i8)out0, (v16i8)out1); \ - \ - ILVEV_H2_UB(tmp0_m, tmp1_m, out5, out7, tmp2_m, tmp3_m); \ - out0 = (v16u8)__msa_ilvev_w((v4i32)tmp3_m, (v4i32)tmp2_m); \ - out4 = (v16u8)__msa_ilvod_w((v4i32)tmp3_m, (v4i32)tmp2_m); \ - \ - tmp2_m = (v16u8)__msa_ilvod_h((v8i16)tmp1_m, (v8i16)tmp0_m); \ - tmp3_m = (v16u8)__msa_ilvod_h((v8i16)out7, (v8i16)out5); \ - out2 = (v16u8)__msa_ilvev_w((v4i32)tmp3_m, (v4i32)tmp2_m); \ - out6 = (v16u8)__msa_ilvod_w((v4i32)tmp3_m, (v4i32)tmp2_m); \ - \ - ILVEV_H2_UB(tmp4_m, tmp5_m, tmp6_m, tmp7_m, tmp2_m, tmp3_m); \ - out1 = (v16u8)__msa_ilvev_w((v4i32)tmp3_m, (v4i32)tmp2_m); \ - out5 = (v16u8)__msa_ilvod_w((v4i32)tmp3_m, (v4i32)tmp2_m); \ - \ - tmp2_m = (v16u8)__msa_ilvod_h((v8i16)tmp5_m, (v8i16)tmp4_m); \ - tmp2_m = (v16u8)__msa_ilvod_h((v8i16)tmp5_m, (v8i16)tmp4_m); \ - tmp3_m = (v16u8)__msa_ilvod_h((v8i16)tmp7_m, (v8i16)tmp6_m); \ - tmp3_m = (v16u8)__msa_ilvod_h((v8i16)tmp7_m, (v8i16)tmp6_m); \ - out3 = (v16u8)__msa_ilvev_w((v4i32)tmp3_m, (v4i32)tmp2_m); \ - out7 = (v16u8)__msa_ilvod_w((v4i32)tmp3_m, (v4i32)tmp2_m); \ - } - -/* Description : Transpose 4x4 block with half word elements in vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1, out2, out3 - Return Type - signed halfword -*/ -#define TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - v8i16 s0_m, s1_m; \ - \ - ILVR_H2_SH(in1, in0, in3, in2, s0_m, s1_m); \ - ILVRL_W2_SH(s1_m, s0_m, out0, out2); \ - out1 = (v8i16)__msa_ilvl_d((v2i64)out0, (v2i64)out0); \ - out3 = (v8i16)__msa_ilvl_d((v2i64)out0, (v2i64)out2); \ - } - -/* Description : Transpose 8x4 block with half word elements in vectors - Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7 - Outputs - out0, out1, out2, out3, out4, out5, out6, out7 - Return Type - signed halfword -*/ -#define TRANSPOSE8X4_SH_SH(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - v8i16 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ - \ - ILVR_H2_SH(in1, in0, in3, in2, tmp0_m, tmp1_m); \ - ILVL_H2_SH(in1, in0, in3, in2, tmp2_m, tmp3_m); \ - ILVR_W2_SH(tmp1_m, tmp0_m, tmp3_m, tmp2_m, out0, out2); \ - ILVL_W2_SH(tmp1_m, tmp0_m, tmp3_m, tmp2_m, out1, out3); \ - } - -/* Description : Transpose 4x4 block with word elements in vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1, out2, out3 - Return Type - signed word -*/ -#define TRANSPOSE4x4_SW_SW(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - v4i32 s0_m, s1_m, s2_m, s3_m; \ - \ - ILVRL_W2_SW(in1, in0, s0_m, s1_m); \ - ILVRL_W2_SW(in3, in2, s2_m, s3_m); \ - \ - out0 = (v4i32)__msa_ilvr_d((v2i64)s2_m, (v2i64)s0_m); \ - out1 = (v4i32)__msa_ilvl_d((v2i64)s2_m, (v2i64)s0_m); \ - out2 = (v4i32)__msa_ilvr_d((v2i64)s3_m, (v2i64)s1_m); \ - out3 = (v4i32)__msa_ilvl_d((v2i64)s3_m, (v2i64)s1_m); \ - } - -/* Description : Dot product and addition of 3 signed halfword input vectors - Arguments : Inputs - in0, in1, in2, coeff0, coeff1, coeff2 - Output - out0_m - Return Type - signed halfword - Details : Dot product of 'in0' with 'coeff0' - Dot product of 'in1' with 'coeff1' - Dot product of 'in2' with 'coeff2' - Addition of all the 3 vector results - out0_m = (in0 * coeff0) + (in1 * coeff1) + (in2 * coeff2) -*/ -#define DPADD_SH3_SH(in0, in1, in2, coeff0, coeff1, coeff2) \ - ({ \ - v8i16 tmp1_m; \ - v8i16 out0_m; \ - \ - out0_m = __msa_dotp_s_h((v16i8)in0, (v16i8)coeff0); \ - out0_m = __msa_dpadd_s_h(out0_m, (v16i8)in1, (v16i8)coeff1); \ - tmp1_m = __msa_dotp_s_h((v16i8)in2, (v16i8)coeff2); \ - out0_m = __msa_adds_s_h(out0_m, tmp1_m); \ - \ - out0_m; \ - }) - -/* Description : Pack even elements of input vectors & xor with 128 - Arguments : Inputs - in0, in1 - Output - out_m - Return Type - unsigned byte - Details : Signed byte even elements from 'in0' and 'in1' are packed - together in one vector and the resulting vector is xor'ed with - 128 to shift the range from signed to unsigned byte -*/ -#define PCKEV_XORI128_UB(in0, in1) \ - ({ \ - v16u8 out_m; \ - out_m = (v16u8)__msa_pckev_b((v16i8)in1, (v16i8)in0); \ - out_m = (v16u8)__msa_xori_b((v16u8)out_m, 128); \ - out_m; \ - }) - -/* Description : Pack even byte elements and store byte vector in destination - memory - Arguments : Inputs - in0, in1, pdst -*/ -#define PCKEV_ST_SB(in0, in1, pdst) \ - { \ - v16i8 tmp_m; \ - tmp_m = __msa_pckev_b((v16i8)in1, (v16i8)in0); \ - ST_SB(tmp_m, (pdst)); \ - } - -/* Description : Horizontal 2 tap filter kernel code - Arguments : Inputs - in0, in1, mask, coeff, shift -*/ -#define HORIZ_2TAP_FILT_UH(in0, in1, mask, coeff, shift) \ - ({ \ - v16i8 tmp0_m; \ - v8u16 tmp1_m; \ - \ - tmp0_m = __msa_vshf_b((v16i8)mask, (v16i8)in1, (v16i8)in0); \ - tmp1_m = __msa_dotp_u_h((v16u8)tmp0_m, (v16u8)coeff); \ - tmp1_m = (v8u16)__msa_srari_h((v8i16)tmp1_m, shift); \ - \ - tmp1_m; \ - }) -#endif // VPX_VP8_COMMON_MIPS_MSA_VP8_MACROS_MSA_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/modecont.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/modecont.c deleted file mode 100644 index bab41037..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/modecont.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "entropy.h" - -const int vp8_mode_contexts[6][4] = { - { /* 0 */ - 7, 1, 1, 143 }, - { /* 1 */ - 14, 18, 14, 107 }, - { /* 2 */ - 135, 64, 57, 68 }, - { /* 3 */ - 60, 56, 128, 65 }, - { /* 4 */ - 159, 134, 128, 34 }, - { /* 5 */ - 234, 188, 128, 28 }, -}; diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/modecont.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/modecont.h deleted file mode 100644 index 031f74f2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/modecont.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_MODECONT_H_ -#define VPX_VP8_COMMON_MODECONT_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -extern const int vp8_mode_contexts[6][4]; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_MODECONT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mv.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/mv.h deleted file mode 100644 index 4cde12f2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/mv.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_MV_H_ -#define VPX_VP8_COMMON_MV_H_ -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - short row; - short col; -} MV; - -typedef union int_mv { - uint32_t as_int; - MV as_mv; -} int_mv; /* facilitates faster equality tests and copies */ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_MV_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/onyx.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/onyx.h deleted file mode 100644 index 2038c000..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/onyx.h +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_ONYX_H_ -#define VPX_VP8_COMMON_ONYX_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "vpx_config.h" -#include "vpx/internal/vpx_codec_internal.h" -#include "vpx/vp8cx.h" -#include "vpx/vpx_encoder.h" -#include "vpx_scale/yv12config.h" -#include "ppflags.h" - -struct VP8_COMP; - -/* Create/destroy static data structures. */ - -typedef enum { - USAGE_LOCAL_FILE_PLAYBACK = 0x0, - USAGE_STREAM_FROM_SERVER = 0x1, - USAGE_CONSTRAINED_QUALITY = 0x2, - USAGE_CONSTANT_QUALITY = 0x3 -} END_USAGE; - -typedef enum { - MODE_REALTIME = 0x0, - MODE_GOODQUALITY = 0x1, - MODE_BESTQUALITY = 0x2, - MODE_FIRSTPASS = 0x3, - MODE_SECONDPASS = 0x4, - MODE_SECONDPASS_BEST = 0x5 -} MODE; - -typedef enum { - FRAMEFLAGS_KEY = 1, - FRAMEFLAGS_GOLDEN = 2, - FRAMEFLAGS_ALTREF = 4 -} FRAMETYPE_FLAGS; - -#include -static INLINE void Scale2Ratio(int mode, int *hr, int *hs) { - switch (mode) { - case VP8E_NORMAL: - *hr = 1; - *hs = 1; - break; - case VP8E_FOURFIVE: - *hr = 4; - *hs = 5; - break; - case VP8E_THREEFIVE: - *hr = 3; - *hs = 5; - break; - case VP8E_ONETWO: - *hr = 1; - *hs = 2; - break; - default: - *hr = 1; - *hs = 1; - assert(0); - break; - } -} - -typedef struct { - /* 4 versions of bitstream defined: - * 0 best quality/slowest decode, 3 lowest quality/fastest decode - */ - int Version; - int Width; - int Height; - struct vpx_rational timebase; - /* In either kilobits per second or bits per second, depending on which - * copy of oxcf this is in. - * - ctx->oxcf.target_bandwidth is in kilobits per second. See - * set_vp8e_config(). - * - ctx->cpi->oxcf.target_bandwidth in is bits per second. See - * vp8_change_config(). - */ - unsigned int target_bandwidth; - - /* Parameter used for applying denoiser. - * For temporal denoiser: noise_sensitivity = 0 means off, - * noise_sensitivity = 1 means temporal denoiser on for Y channel only, - * noise_sensitivity = 2 means temporal denoiser on for all channels. - * noise_sensitivity = 3 means aggressive denoising mode. - * noise_sensitivity >= 4 means adaptive denoising mode. - * Temporal denoiser is enabled via the configuration option: - * CONFIG_TEMPORAL_DENOISING. - * For spatial denoiser: noise_sensitivity controls the amount of - * pre-processing blur: noise_sensitivity = 0 means off. - * Spatial denoiser invoked under !CONFIG_TEMPORAL_DENOISING. - */ - int noise_sensitivity; - - /* parameter used for sharpening output: recommendation 0: */ - int Sharpness; - int cpu_used; - unsigned int rc_max_intra_bitrate_pct; - /* percent of rate boost for golden frame in CBR mode. */ - unsigned int gf_cbr_boost_pct; - unsigned int screen_content_mode; - - /* mode -> - *(0)=Realtime/Live Encoding. This mode is optimized for realtim - * encoding (for example, capturing a television signal or feed - * from a live camera). ( speed setting controls how fast ) - *(1)=Good Quality Fast Encoding. The encoder balances quality with - * the amount of time it takes to encode the output. ( speed - * setting controls how fast ) - *(2)=One Pass - Best Quality. The encoder places priority on the - * quality of the output over encoding speed. The output is - * compressed at the highest possible quality. This option takes - * the longest amount of time to encode. ( speed setting ignored - * ) - *(3)=Two Pass - First Pass. The encoder generates a file of - * statistics for use in the second encoding pass. ( speed - * setting controls how fast ) - *(4)=Two Pass - Second Pass. The encoder uses the statistics that - * were generated in the first encoding pass to create the - * compressed output. ( speed setting controls how fast ) - *(5)=Two Pass - Second Pass Best. The encoder uses the statistics - * that were generated in the first encoding pass to create the - * compressed output using the highest possible quality, and - * taking a longer amount of time to encode.. ( speed setting - * ignored ) - */ - int Mode; - - /* Key Framing Operations */ - int auto_key; /* automatically detect cut scenes */ - int key_freq; /* maximum distance to key frame. */ - - /* lagged compression (if allow_lag == 0 lag_in_frames is ignored) */ - int allow_lag; - int lag_in_frames; /* how many frames lag before we start encoding */ - - /* - * DATARATE CONTROL OPTIONS - */ - - int end_usage; /* vbr or cbr */ - - /* buffer targeting aggressiveness */ - int under_shoot_pct; - int over_shoot_pct; - - /* buffering parameters */ - int64_t starting_buffer_level; - int64_t optimal_buffer_level; - int64_t maximum_buffer_size; - - int64_t starting_buffer_level_in_ms; - int64_t optimal_buffer_level_in_ms; - int64_t maximum_buffer_size_in_ms; - - /* controlling quality */ - int fixed_q; - int worst_allowed_q; - int best_allowed_q; - int cq_level; - - /* allow internal resizing */ - int allow_spatial_resampling; - int resample_down_water_mark; - int resample_up_water_mark; - - /* allow internal frame rate alterations */ - int allow_df; - int drop_frames_water_mark; - - /* two pass datarate control */ - int two_pass_vbrbias; - int two_pass_vbrmin_section; - int two_pass_vbrmax_section; - - /* - * END DATARATE CONTROL OPTIONS - */ - - /* these parameters aren't to be used in final build don't use!!! */ - int play_alternate; - int alt_freq; - int alt_q; - int key_q; - int gold_q; - - int multi_threaded; /* how many threads to run the encoder on */ - int token_partitions; /* how many token partitions to create */ - - /* early breakout threshold: for video conf recommend 800 */ - int encode_breakout; - - /* Bitfield defining the error resiliency features to enable. - * Can provide decodable frames after losses in previous - * frames and decodable partitions after losses in the same frame. - */ - unsigned int error_resilient_mode; - - int arnr_max_frames; - int arnr_strength; - int arnr_type; - - vpx_fixed_buf_t two_pass_stats_in; - struct vpx_codec_pkt_list *output_pkt_list; - - vp8e_tuning tuning; - - /* Temporal scaling parameters */ - unsigned int number_of_layers; - /* kilobits per second */ - unsigned int target_bitrate[VPX_TS_MAX_PERIODICITY]; - unsigned int rate_decimator[VPX_TS_MAX_PERIODICITY]; - unsigned int periodicity; - unsigned int layer_id[VPX_TS_MAX_PERIODICITY]; - -#if CONFIG_MULTI_RES_ENCODING - /* Number of total resolutions encoded */ - unsigned int mr_total_resolutions; - - /* Current encoder ID */ - unsigned int mr_encoder_id; - - /* Down-sampling factor */ - vpx_rational_t mr_down_sampling_factor; - - /* Memory location to store low-resolution encoder's mode info */ - void *mr_low_res_mode_info; -#endif -} VP8_CONFIG; - -void vp8_initialize(void); - -struct VP8_COMP *vp8_create_compressor(const VP8_CONFIG *oxcf); -void vp8_remove_compressor(struct VP8_COMP **comp); - -void vp8_init_config(struct VP8_COMP *onyx, VP8_CONFIG *oxcf); -void vp8_change_config(struct VP8_COMP *cpi, const VP8_CONFIG *oxcf); - -int vp8_receive_raw_frame(struct VP8_COMP *cpi, unsigned int frame_flags, - YV12_BUFFER_CONFIG *sd, int64_t time_stamp, - int64_t end_time); -int vp8_get_compressed_data(struct VP8_COMP *cpi, unsigned int *frame_flags, - size_t *size, unsigned char *dest, - unsigned char *dest_end, int64_t *time_stamp, - int64_t *time_end, int flush); -int vp8_get_preview_raw_frame(struct VP8_COMP *cpi, YV12_BUFFER_CONFIG *dest, - vp8_ppflags_t *flags); - -int vp8_use_as_reference(struct VP8_COMP *cpi, int ref_frame_flags); -int vp8_update_reference(struct VP8_COMP *cpi, int ref_frame_flags); -int vp8_get_reference(struct VP8_COMP *cpi, - enum vpx_ref_frame_type ref_frame_flag, - YV12_BUFFER_CONFIG *sd); -int vp8_set_reference(struct VP8_COMP *cpi, - enum vpx_ref_frame_type ref_frame_flag, - YV12_BUFFER_CONFIG *sd); -int vp8_update_entropy(struct VP8_COMP *cpi, int update); -int vp8_set_roimap(struct VP8_COMP *cpi, unsigned char *map, unsigned int rows, - unsigned int cols, int delta_q[4], int delta_lf[4], - unsigned int threshold[4]); -int vp8_set_active_map(struct VP8_COMP *cpi, unsigned char *map, - unsigned int rows, unsigned int cols); -int vp8_set_internal_size(struct VP8_COMP *cpi, VPX_SCALING_MODE horiz_mode, - VPX_SCALING_MODE vert_mode); -int vp8_get_quantizer(struct VP8_COMP *cpi); - -#ifdef __cplusplus -} -#endif - -#endif // VPX_VP8_COMMON_ONYX_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/onyxc_int.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/onyxc_int.h deleted file mode 100644 index d4824d24..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/onyxc_int.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_ONYXC_INT_H_ -#define VPX_VP8_COMMON_ONYXC_INT_H_ - -#include "vpx_config.h" -#include "vp8_rtcd.h" -#include "vpx/internal/vpx_codec_internal.h" -#include "loopfilter.h" -#include "entropymv.h" -#include "entropy.h" -#if CONFIG_POSTPROC -#include "postproc.h" -#endif - -/*#ifdef PACKET_TESTING*/ -#include "header.h" -/*#endif*/ - -#ifdef __cplusplus -extern "C" { -#endif - -#define MINQ 0 -#define MAXQ 127 -#define QINDEX_RANGE (MAXQ + 1) - -#define NUM_YV12_BUFFERS 4 - -#define MAX_PARTITIONS 9 - -typedef struct frame_contexts { - vp8_prob bmode_prob[VP8_BINTRAMODES - 1]; - vp8_prob ymode_prob[VP8_YMODES - 1]; /* interframe intra mode probs */ - vp8_prob uv_mode_prob[VP8_UV_MODES - 1]; - vp8_prob sub_mv_ref_prob[VP8_SUBMVREFS - 1]; - vp8_prob coef_probs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS] - [ENTROPY_NODES]; - MV_CONTEXT mvc[2]; -} FRAME_CONTEXT; - -typedef enum { - ONE_PARTITION = 0, - TWO_PARTITION = 1, - FOUR_PARTITION = 2, - EIGHT_PARTITION = 3 -} TOKEN_PARTITION; - -typedef enum { - RECON_CLAMP_REQUIRED = 0, - RECON_CLAMP_NOTREQUIRED = 1 -} CLAMP_TYPE; - -typedef struct VP8Common { - struct vpx_internal_error_info error; - - DECLARE_ALIGNED(16, short, Y1dequant[QINDEX_RANGE][2]); - DECLARE_ALIGNED(16, short, Y2dequant[QINDEX_RANGE][2]); - DECLARE_ALIGNED(16, short, UVdequant[QINDEX_RANGE][2]); - - int Width; - int Height; - int horiz_scale; - int vert_scale; - - CLAMP_TYPE clamp_type; - - YV12_BUFFER_CONFIG *frame_to_show; - - YV12_BUFFER_CONFIG yv12_fb[NUM_YV12_BUFFERS]; - int fb_idx_ref_cnt[NUM_YV12_BUFFERS]; - int new_fb_idx, lst_fb_idx, gld_fb_idx, alt_fb_idx; - - YV12_BUFFER_CONFIG temp_scale_frame; - -#if CONFIG_POSTPROC - YV12_BUFFER_CONFIG post_proc_buffer; - YV12_BUFFER_CONFIG post_proc_buffer_int; - int post_proc_buffer_int_used; - unsigned char *pp_limits_buffer; /* post-processing filter coefficients */ -#endif - - FRAME_TYPE - last_frame_type; /* Save last frame's frame type for motion search. */ - FRAME_TYPE frame_type; - - int show_frame; - - int frame_flags; - int MBs; - int mb_rows; - int mb_cols; - int mode_info_stride; - - /* profile settings */ - int mb_no_coeff_skip; - int no_lpf; - int use_bilinear_mc_filter; - int full_pixel; - - int base_qindex; - - int y1dc_delta_q; - int y2dc_delta_q; - int y2ac_delta_q; - int uvdc_delta_q; - int uvac_delta_q; - - /* We allocate a MODE_INFO struct for each macroblock, together with - an extra row on top and column on the left to simplify prediction. */ - - MODE_INFO *mip; /* Base of allocated array */ - MODE_INFO *mi; /* Corresponds to upper left visible macroblock */ -#if CONFIG_ERROR_CONCEALMENT - MODE_INFO *prev_mip; /* MODE_INFO array 'mip' from last decoded frame */ - MODE_INFO *prev_mi; /* 'mi' from last frame (points into prev_mip) */ -#endif - /* MODE_INFO for the last decoded frame to show */ - MODE_INFO *show_frame_mi; - LOOPFILTERTYPE filter_type; - - loop_filter_info_n lf_info; - - int filter_level; - int last_sharpness_level; - int sharpness_level; - - int refresh_last_frame; /* Two state 0 = NO, 1 = YES */ - int refresh_golden_frame; /* Two state 0 = NO, 1 = YES */ - int refresh_alt_ref_frame; /* Two state 0 = NO, 1 = YES */ - - int copy_buffer_to_gf; /* 0 none, 1 Last to GF, 2 ARF to GF */ - int copy_buffer_to_arf; /* 0 none, 1 Last to ARF, 2 GF to ARF */ - - int refresh_entropy_probs; /* Two state 0 = NO, 1 = YES */ - - int ref_frame_sign_bias[MAX_REF_FRAMES]; /* Two state 0, 1 */ - - /* Y,U,V,Y2 */ - ENTROPY_CONTEXT_PLANES *above_context; /* row of context for each plane */ - ENTROPY_CONTEXT_PLANES left_context; /* (up to) 4 contexts "" */ - - FRAME_CONTEXT lfc; /* last frame entropy */ - FRAME_CONTEXT fc; /* this frame entropy */ - - unsigned int current_video_frame; - - int version; - - TOKEN_PARTITION multi_token_partition; - -#ifdef PACKET_TESTING - VP8_HEADER oh; -#endif - -#if CONFIG_MULTITHREAD - int processor_core_count; -#endif -#if CONFIG_POSTPROC - struct postproc_state postproc_state; -#endif -} VP8_COMMON; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_ONYXC_INT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/onyxd.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/onyxd.h deleted file mode 100644 index 217a598d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/onyxd.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_ONYXD_H_ -#define VPX_VP8_COMMON_ONYXD_H_ - -/* Create/destroy static data structures. */ -#ifdef __cplusplus -extern "C" { -#endif -#include "vpx_scale/yv12config.h" -#include "ppflags.h" -#include "vpx_ports/mem.h" -#include "vpx/vpx_codec.h" -#include "vpx/vp8.h" - -struct VP8D_COMP; -struct VP8Common; - -typedef struct { - int Width; - int Height; - int Version; - int postprocess; - int max_threads; - int error_concealment; -} VP8D_CONFIG; - -typedef enum { VP8D_OK = 0 } VP8D_SETTING; - -void vp8dx_initialize(void); - -void vp8dx_set_setting(struct VP8D_COMP *comp, VP8D_SETTING oxst, int x); - -int vp8dx_get_setting(struct VP8D_COMP *comp, VP8D_SETTING oxst); - -int vp8dx_receive_compressed_data(struct VP8D_COMP *pbi); -int vp8dx_get_raw_frame(struct VP8D_COMP *pbi, YV12_BUFFER_CONFIG *sd, - vp8_ppflags_t *flags); -int vp8dx_references_buffer(struct VP8Common *oci, int ref_frame); - -vpx_codec_err_t vp8dx_get_reference(struct VP8D_COMP *pbi, - enum vpx_ref_frame_type ref_frame_flag, - YV12_BUFFER_CONFIG *sd); -vpx_codec_err_t vp8dx_set_reference(struct VP8D_COMP *pbi, - enum vpx_ref_frame_type ref_frame_flag, - YV12_BUFFER_CONFIG *sd); -int vp8dx_get_quantizer(const struct VP8D_COMP *pbi); - -#ifdef __cplusplus -} -#endif - -#endif // VPX_VP8_COMMON_ONYXD_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/postproc.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/postproc.c deleted file mode 100644 index c03b16b2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/postproc.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "vpx_dsp_rtcd.h" -#include "vp8_rtcd.h" -#include "vpx_dsp/postproc.h" -#include "vpx_ports/system_state.h" -#include "vpx_scale_rtcd.h" -#include "vpx_scale/yv12config.h" -#include "postproc.h" -#include "common.h" -#include "vpx_scale/vpx_scale.h" -#include "systemdependent.h" - -#include -#include -#include -#include - -/* clang-format off */ -#define RGB_TO_YUV(t) \ - (unsigned char)((0.257 * (float)(t >> 16)) + \ - (0.504 * (float)(t >> 8 & 0xff)) + \ - (0.098 * (float)(t & 0xff)) + 16), \ - (unsigned char)(-(0.148 * (float)(t >> 16)) - \ - (0.291 * (float)(t >> 8 & 0xff)) + \ - (0.439 * (float)(t & 0xff)) + 128), \ - (unsigned char)((0.439 * (float)(t >> 16)) - \ - (0.368 * (float)(t >> 8 & 0xff)) - \ - (0.071 * (float)(t & 0xff)) + 128) -/* clang-format on */ - -extern void vp8_blit_text(const char *msg, unsigned char *address, - const int pitch); -extern void vp8_blit_line(int x0, int x1, int y0, int y1, unsigned char *image, - const int pitch); -/*********************************************************************************************************** - */ -#if CONFIG_POSTPROC -static int q2mbl(int x) { - if (x < 20) x = 20; - - x = 50 + (x - 50) * 10 / 8; - return x * x / 3; -} - -static void vp8_de_mblock(YV12_BUFFER_CONFIG *post, int q) { - vpx_mbpost_proc_across_ip(post->y_buffer, post->y_stride, post->y_height, - post->y_width, q2mbl(q)); - vpx_mbpost_proc_down(post->y_buffer, post->y_stride, post->y_height, - post->y_width, q2mbl(q)); -} - -void vp8_deblock(VP8_COMMON *cm, YV12_BUFFER_CONFIG *source, - YV12_BUFFER_CONFIG *post, int q) { - double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065; - int ppl = (int)(level + .5); - - const MODE_INFO *mode_info_context = cm->mi; - int mbr, mbc; - - /* The pixel thresholds are adjusted according to if or not the macroblock - * is a skipped block. */ - unsigned char *ylimits = cm->pp_limits_buffer; - unsigned char *uvlimits = cm->pp_limits_buffer + 16 * cm->mb_cols; - - if (ppl > 0) { - for (mbr = 0; mbr < cm->mb_rows; ++mbr) { - unsigned char *ylptr = ylimits; - unsigned char *uvlptr = uvlimits; - for (mbc = 0; mbc < cm->mb_cols; ++mbc) { - unsigned char mb_ppl; - - if (mode_info_context->mbmi.mb_skip_coeff) { - mb_ppl = (unsigned char)ppl >> 1; - } else { - mb_ppl = (unsigned char)ppl; - } - - memset(ylptr, mb_ppl, 16); - memset(uvlptr, mb_ppl, 8); - - ylptr += 16; - uvlptr += 8; - mode_info_context++; - } - mode_info_context++; - - vpx_post_proc_down_and_across_mb_row( - source->y_buffer + 16 * mbr * source->y_stride, - post->y_buffer + 16 * mbr * post->y_stride, source->y_stride, - post->y_stride, source->y_width, ylimits, 16); - - vpx_post_proc_down_and_across_mb_row( - source->u_buffer + 8 * mbr * source->uv_stride, - post->u_buffer + 8 * mbr * post->uv_stride, source->uv_stride, - post->uv_stride, source->uv_width, uvlimits, 8); - vpx_post_proc_down_and_across_mb_row( - source->v_buffer + 8 * mbr * source->uv_stride, - post->v_buffer + 8 * mbr * post->uv_stride, source->uv_stride, - post->uv_stride, source->uv_width, uvlimits, 8); - } - } else { - vp8_yv12_copy_frame(source, post); - } -} - -void vp8_de_noise(VP8_COMMON *cm, YV12_BUFFER_CONFIG *source, int q, - int uvfilter) { - int mbr; - double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065; - int ppl = (int)(level + .5); - int mb_rows = cm->mb_rows; - int mb_cols = cm->mb_cols; - unsigned char *limits = cm->pp_limits_buffer; - - memset(limits, (unsigned char)ppl, 16 * mb_cols); - - /* TODO: The original code don't filter the 2 outer rows and columns. */ - for (mbr = 0; mbr < mb_rows; ++mbr) { - vpx_post_proc_down_and_across_mb_row( - source->y_buffer + 16 * mbr * source->y_stride, - source->y_buffer + 16 * mbr * source->y_stride, source->y_stride, - source->y_stride, source->y_width, limits, 16); - if (uvfilter == 1) { - vpx_post_proc_down_and_across_mb_row( - source->u_buffer + 8 * mbr * source->uv_stride, - source->u_buffer + 8 * mbr * source->uv_stride, source->uv_stride, - source->uv_stride, source->uv_width, limits, 8); - vpx_post_proc_down_and_across_mb_row( - source->v_buffer + 8 * mbr * source->uv_stride, - source->v_buffer + 8 * mbr * source->uv_stride, source->uv_stride, - source->uv_stride, source->uv_width, limits, 8); - } - } -} -#endif // CONFIG_POSTPROC - -#if CONFIG_POSTPROC -int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, - vp8_ppflags_t *ppflags) { - int q = oci->filter_level * 10 / 6; - int flags = ppflags->post_proc_flag; - int deblock_level = ppflags->deblocking_level; - int noise_level = ppflags->noise_level; - - if (!oci->frame_to_show) return -1; - - if (q > 63) q = 63; - - if (!flags) { - *dest = *oci->frame_to_show; - - /* handle problem with extending borders */ - dest->y_width = oci->Width; - dest->y_height = oci->Height; - dest->uv_height = dest->y_height / 2; - oci->postproc_state.last_base_qindex = oci->base_qindex; - oci->postproc_state.last_frame_valid = 1; - return 0; - } - if (flags & VP8D_ADDNOISE) { - if (!oci->postproc_state.generated_noise) { - oci->postproc_state.generated_noise = vpx_calloc( - oci->Width + 256, sizeof(*oci->postproc_state.generated_noise)); - if (!oci->postproc_state.generated_noise) return 1; - } - } - - /* Allocate post_proc_buffer_int if needed */ - if ((flags & VP8D_MFQE) && !oci->post_proc_buffer_int_used) { - if ((flags & VP8D_DEBLOCK) || (flags & VP8D_DEMACROBLOCK)) { - int width = (oci->Width + 15) & ~15; - int height = (oci->Height + 15) & ~15; - - if (vp8_yv12_alloc_frame_buffer(&oci->post_proc_buffer_int, width, height, - VP8BORDERINPIXELS)) { - vpx_internal_error(&oci->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate MFQE framebuffer"); - } - - oci->post_proc_buffer_int_used = 1; - - /* insure that postproc is set to all 0's so that post proc - * doesn't pull random data in from edge - */ - memset((&oci->post_proc_buffer_int)->buffer_alloc, 128, - (&oci->post_proc_buffer)->frame_size); - } - } - - vpx_clear_system_state(); - - if ((flags & VP8D_MFQE) && oci->postproc_state.last_frame_valid && - oci->current_video_frame > 10 && - oci->postproc_state.last_base_qindex < 60 && - oci->base_qindex - oci->postproc_state.last_base_qindex >= 20) { - vp8_multiframe_quality_enhance(oci); - if (((flags & VP8D_DEBLOCK) || (flags & VP8D_DEMACROBLOCK)) && - oci->post_proc_buffer_int_used) { - vp8_yv12_copy_frame(&oci->post_proc_buffer, &oci->post_proc_buffer_int); - if (flags & VP8D_DEMACROBLOCK) { - vp8_deblock(oci, &oci->post_proc_buffer_int, &oci->post_proc_buffer, - q + (deblock_level - 5) * 10); - vp8_de_mblock(&oci->post_proc_buffer, q + (deblock_level - 5) * 10); - } else if (flags & VP8D_DEBLOCK) { - vp8_deblock(oci, &oci->post_proc_buffer_int, &oci->post_proc_buffer, q); - } - } - /* Move partially towards the base q of the previous frame */ - oci->postproc_state.last_base_qindex = - (3 * oci->postproc_state.last_base_qindex + oci->base_qindex) >> 2; - } else if (flags & VP8D_DEMACROBLOCK) { - vp8_deblock(oci, oci->frame_to_show, &oci->post_proc_buffer, - q + (deblock_level - 5) * 10); - vp8_de_mblock(&oci->post_proc_buffer, q + (deblock_level - 5) * 10); - - oci->postproc_state.last_base_qindex = oci->base_qindex; - } else if (flags & VP8D_DEBLOCK) { - vp8_deblock(oci, oci->frame_to_show, &oci->post_proc_buffer, q); - oci->postproc_state.last_base_qindex = oci->base_qindex; - } else { - vp8_yv12_copy_frame(oci->frame_to_show, &oci->post_proc_buffer); - oci->postproc_state.last_base_qindex = oci->base_qindex; - } - oci->postproc_state.last_frame_valid = 1; - - if (flags & VP8D_ADDNOISE) { - if (oci->postproc_state.last_q != q || - oci->postproc_state.last_noise != noise_level) { - double sigma; - struct postproc_state *ppstate = &oci->postproc_state; - vpx_clear_system_state(); - sigma = noise_level + .5 + .6 * q / 63.0; - ppstate->clamp = - vpx_setup_noise(sigma, ppstate->generated_noise, oci->Width + 256); - ppstate->last_q = q; - ppstate->last_noise = noise_level; - } - - vpx_plane_add_noise( - oci->post_proc_buffer.y_buffer, oci->postproc_state.generated_noise, - oci->postproc_state.clamp, oci->postproc_state.clamp, - oci->post_proc_buffer.y_width, oci->post_proc_buffer.y_height, - oci->post_proc_buffer.y_stride); - } - - *dest = oci->post_proc_buffer; - - /* handle problem with extending borders */ - dest->y_width = oci->Width; - dest->y_height = oci->Height; - dest->uv_height = dest->y_height / 2; - return 0; -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/postproc.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/postproc.h deleted file mode 100644 index 492c52ae..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/postproc.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_POSTPROC_H_ -#define VPX_VP8_COMMON_POSTPROC_H_ - -#include "vpx_ports/mem.h" -struct postproc_state { - int last_q; - int last_noise; - int last_base_qindex; - int last_frame_valid; - int clamp; - int8_t *generated_noise; -}; -#include "onyxc_int.h" -#include "ppflags.h" - -#ifdef __cplusplus -extern "C" { -#endif -int vp8_post_proc_frame(struct VP8Common *oci, YV12_BUFFER_CONFIG *dest, - vp8_ppflags_t *ppflags); - -void vp8_de_noise(struct VP8Common *cm, YV12_BUFFER_CONFIG *source, int q, - int uvfilter); - -void vp8_deblock(struct VP8Common *cm, YV12_BUFFER_CONFIG *source, - YV12_BUFFER_CONFIG *post, int q); - -#define MFQE_PRECISION 4 - -void vp8_multiframe_quality_enhance(struct VP8Common *cm); -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_POSTPROC_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/ppflags.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/ppflags.h deleted file mode 100644 index bdf08734..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/ppflags.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_PPFLAGS_H_ -#define VPX_VP8_COMMON_PPFLAGS_H_ - -#ifdef __cplusplus -extern "C" { -#endif -enum { - VP8D_NOFILTERING = 0, - VP8D_DEBLOCK = 1 << 0, - VP8D_DEMACROBLOCK = 1 << 1, - VP8D_ADDNOISE = 1 << 2, - VP8D_MFQE = 1 << 3 -}; - -typedef struct { - int post_proc_flag; - int deblocking_level; - int noise_level; - int display_ref_frame_flag; - int display_mb_modes_flag; - int display_b_modes_flag; - int display_mv_flag; -} vp8_ppflags_t; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_PPFLAGS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/quant_common.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/quant_common.c deleted file mode 100644 index e290eec9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/quant_common.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "quant_common.h" - -static const int dc_qlookup[QINDEX_RANGE] = { - 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, - 17, 18, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 25, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 91, 93, 95, 96, 98, 100, 101, 102, 104, - 106, 108, 110, 112, 114, 116, 118, 122, 124, 126, 128, 130, 132, 134, 136, - 138, 140, 143, 145, 148, 151, 154, 157, -}; - -static const int ac_qlookup[QINDEX_RANGE] = { - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 62, 64, 66, 68, - 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, - 100, 102, 104, 106, 108, 110, 112, 114, 116, 119, 122, 125, 128, 131, 134, - 137, 140, 143, 146, 149, 152, 155, 158, 161, 164, 167, 170, 173, 177, 181, - 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 234, 239, 245, - 249, 254, 259, 264, 269, 274, 279, 284, -}; - -int vp8_dc_quant(int QIndex, int Delta) { - int retval; - - QIndex = QIndex + Delta; - - if (QIndex > 127) { - QIndex = 127; - } else if (QIndex < 0) { - QIndex = 0; - } - - retval = dc_qlookup[QIndex]; - return retval; -} - -int vp8_dc2quant(int QIndex, int Delta) { - int retval; - - QIndex = QIndex + Delta; - - if (QIndex > 127) { - QIndex = 127; - } else if (QIndex < 0) { - QIndex = 0; - } - - retval = dc_qlookup[QIndex] * 2; - return retval; -} -int vp8_dc_uv_quant(int QIndex, int Delta) { - int retval; - - QIndex = QIndex + Delta; - - if (QIndex > 127) { - QIndex = 127; - } else if (QIndex < 0) { - QIndex = 0; - } - - retval = dc_qlookup[QIndex]; - - if (retval > 132) retval = 132; - - return retval; -} - -int vp8_ac_yquant(int QIndex) { - int retval; - - if (QIndex > 127) { - QIndex = 127; - } else if (QIndex < 0) { - QIndex = 0; - } - - retval = ac_qlookup[QIndex]; - return retval; -} - -int vp8_ac2quant(int QIndex, int Delta) { - int retval; - - QIndex = QIndex + Delta; - - if (QIndex > 127) { - QIndex = 127; - } else if (QIndex < 0) { - QIndex = 0; - } - - /* For all x in [0..284], x*155/100 is bitwise equal to (x*101581) >> 16. - * The smallest precision for that is '(x*6349) >> 12' but 16 is a good - * word size. */ - retval = (ac_qlookup[QIndex] * 101581) >> 16; - - if (retval < 8) retval = 8; - - return retval; -} -int vp8_ac_uv_quant(int QIndex, int Delta) { - int retval; - - QIndex = QIndex + Delta; - - if (QIndex > 127) { - QIndex = 127; - } else if (QIndex < 0) { - QIndex = 0; - } - - retval = ac_qlookup[QIndex]; - return retval; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/quant_common.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/quant_common.h deleted file mode 100644 index 049840a2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/quant_common.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_QUANT_COMMON_H_ -#define VPX_VP8_COMMON_QUANT_COMMON_H_ - -#include "string.h" -#include "blockd.h" -#include "onyxc_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern int vp8_ac_yquant(int QIndex); -extern int vp8_dc_quant(int QIndex, int Delta); -extern int vp8_dc2quant(int QIndex, int Delta); -extern int vp8_ac2quant(int QIndex, int Delta); -extern int vp8_dc_uv_quant(int QIndex, int Delta); -extern int vp8_ac_uv_quant(int QIndex, int Delta); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_QUANT_COMMON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconinter.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconinter.c deleted file mode 100644 index 2cb07093..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconinter.c +++ /dev/null @@ -1,503 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "vpx_config.h" -#include "vp8_rtcd.h" -#include "vpx/vpx_integer.h" -#include "blockd.h" -#include "reconinter.h" -#if CONFIG_RUNTIME_CPU_DETECT -#include "onyxc_int.h" -#endif - -void vp8_copy_mem16x16_c(unsigned char *src, int src_stride, unsigned char *dst, - int dst_stride) { - int r; - - for (r = 0; r < 16; ++r) { - memcpy(dst, src, 16); - - src += src_stride; - dst += dst_stride; - } -} - -void vp8_copy_mem8x8_c(unsigned char *src, int src_stride, unsigned char *dst, - int dst_stride) { - int r; - - for (r = 0; r < 8; ++r) { - memcpy(dst, src, 8); - - src += src_stride; - dst += dst_stride; - } -} - -void vp8_copy_mem8x4_c(unsigned char *src, int src_stride, unsigned char *dst, - int dst_stride) { - int r; - - for (r = 0; r < 4; ++r) { - memcpy(dst, src, 8); - - src += src_stride; - dst += dst_stride; - } -} - -void vp8_build_inter_predictors_b(BLOCKD *d, int pitch, unsigned char *base_pre, - int pre_stride, vp8_subpix_fn_t sppf) { - int r; - unsigned char *pred_ptr = d->predictor; - unsigned char *ptr; - ptr = base_pre + d->offset + (d->bmi.mv.as_mv.row >> 3) * pre_stride + - (d->bmi.mv.as_mv.col >> 3); - - if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7) { - sppf(ptr, pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, - pred_ptr, pitch); - } else { - for (r = 0; r < 4; ++r) { - pred_ptr[0] = ptr[0]; - pred_ptr[1] = ptr[1]; - pred_ptr[2] = ptr[2]; - pred_ptr[3] = ptr[3]; - pred_ptr += pitch; - ptr += pre_stride; - } - } -} - -static void build_inter_predictors4b(MACROBLOCKD *x, BLOCKD *d, - unsigned char *dst, int dst_stride, - unsigned char *base_pre, int pre_stride) { - unsigned char *ptr; - ptr = base_pre + d->offset + (d->bmi.mv.as_mv.row >> 3) * pre_stride + - (d->bmi.mv.as_mv.col >> 3); - - if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7) { - x->subpixel_predict8x8(ptr, pre_stride, d->bmi.mv.as_mv.col & 7, - d->bmi.mv.as_mv.row & 7, dst, dst_stride); - } else { - vp8_copy_mem8x8(ptr, pre_stride, dst, dst_stride); - } -} - -static void build_inter_predictors2b(MACROBLOCKD *x, BLOCKD *d, - unsigned char *dst, int dst_stride, - unsigned char *base_pre, int pre_stride) { - unsigned char *ptr; - ptr = base_pre + d->offset + (d->bmi.mv.as_mv.row >> 3) * pre_stride + - (d->bmi.mv.as_mv.col >> 3); - - if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7) { - x->subpixel_predict8x4(ptr, pre_stride, d->bmi.mv.as_mv.col & 7, - d->bmi.mv.as_mv.row & 7, dst, dst_stride); - } else { - vp8_copy_mem8x4(ptr, pre_stride, dst, dst_stride); - } -} - -static void build_inter_predictors_b(BLOCKD *d, unsigned char *dst, - int dst_stride, unsigned char *base_pre, - int pre_stride, vp8_subpix_fn_t sppf) { - int r; - unsigned char *ptr; - ptr = base_pre + d->offset + (d->bmi.mv.as_mv.row >> 3) * pre_stride + - (d->bmi.mv.as_mv.col >> 3); - - if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7) { - sppf(ptr, pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, dst, - dst_stride); - } else { - for (r = 0; r < 4; ++r) { - dst[0] = ptr[0]; - dst[1] = ptr[1]; - dst[2] = ptr[2]; - dst[3] = ptr[3]; - dst += dst_stride; - ptr += pre_stride; - } - } -} - -/*encoder only*/ -void vp8_build_inter16x16_predictors_mbuv(MACROBLOCKD *x) { - unsigned char *uptr, *vptr; - unsigned char *upred_ptr = &x->predictor[256]; - unsigned char *vpred_ptr = &x->predictor[320]; - - int mv_row = x->mode_info_context->mbmi.mv.as_mv.row; - int mv_col = x->mode_info_context->mbmi.mv.as_mv.col; - int offset; - int pre_stride = x->pre.uv_stride; - - /* calc uv motion vectors */ - mv_row += 1 | (mv_row >> (sizeof(int) * CHAR_BIT - 1)); - mv_col += 1 | (mv_col >> (sizeof(int) * CHAR_BIT - 1)); - mv_row /= 2; - mv_col /= 2; - mv_row &= x->fullpixel_mask; - mv_col &= x->fullpixel_mask; - - offset = (mv_row >> 3) * pre_stride + (mv_col >> 3); - uptr = x->pre.u_buffer + offset; - vptr = x->pre.v_buffer + offset; - - if ((mv_row | mv_col) & 7) { - x->subpixel_predict8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, - 8); - x->subpixel_predict8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, - 8); - } else { - vp8_copy_mem8x8(uptr, pre_stride, upred_ptr, 8); - vp8_copy_mem8x8(vptr, pre_stride, vpred_ptr, 8); - } -} - -/*encoder only*/ -void vp8_build_inter4x4_predictors_mbuv(MACROBLOCKD *x) { - int i, j; - int pre_stride = x->pre.uv_stride; - unsigned char *base_pre; - - /* build uv mvs */ - for (i = 0; i < 2; ++i) { - for (j = 0; j < 2; ++j) { - int yoffset = i * 8 + j * 2; - int uoffset = 16 + i * 2 + j; - int voffset = 20 + i * 2 + j; - - int temp; - - temp = x->block[yoffset].bmi.mv.as_mv.row + - x->block[yoffset + 1].bmi.mv.as_mv.row + - x->block[yoffset + 4].bmi.mv.as_mv.row + - x->block[yoffset + 5].bmi.mv.as_mv.row; - - temp += 4 + ((temp >> (sizeof(temp) * CHAR_BIT - 1)) * 8); - - x->block[uoffset].bmi.mv.as_mv.row = (temp / 8) & x->fullpixel_mask; - - temp = x->block[yoffset].bmi.mv.as_mv.col + - x->block[yoffset + 1].bmi.mv.as_mv.col + - x->block[yoffset + 4].bmi.mv.as_mv.col + - x->block[yoffset + 5].bmi.mv.as_mv.col; - - temp += 4 + ((temp >> (sizeof(temp) * CHAR_BIT - 1)) * 8); - - x->block[uoffset].bmi.mv.as_mv.col = (temp / 8) & x->fullpixel_mask; - - x->block[voffset].bmi.mv.as_int = x->block[uoffset].bmi.mv.as_int; - } - } - - base_pre = x->pre.u_buffer; - for (i = 16; i < 20; i += 2) { - BLOCKD *d0 = &x->block[i]; - BLOCKD *d1 = &x->block[i + 1]; - - if (d0->bmi.mv.as_int == d1->bmi.mv.as_int) { - build_inter_predictors2b(x, d0, d0->predictor, 8, base_pre, pre_stride); - } else { - vp8_build_inter_predictors_b(d0, 8, base_pre, pre_stride, - x->subpixel_predict); - vp8_build_inter_predictors_b(d1, 8, base_pre, pre_stride, - x->subpixel_predict); - } - } - - base_pre = x->pre.v_buffer; - for (i = 20; i < 24; i += 2) { - BLOCKD *d0 = &x->block[i]; - BLOCKD *d1 = &x->block[i + 1]; - - if (d0->bmi.mv.as_int == d1->bmi.mv.as_int) { - build_inter_predictors2b(x, d0, d0->predictor, 8, base_pre, pre_stride); - } else { - vp8_build_inter_predictors_b(d0, 8, base_pre, pre_stride, - x->subpixel_predict); - vp8_build_inter_predictors_b(d1, 8, base_pre, pre_stride, - x->subpixel_predict); - } - } -} - -/*encoder only*/ -void vp8_build_inter16x16_predictors_mby(MACROBLOCKD *x, unsigned char *dst_y, - int dst_ystride) { - unsigned char *ptr_base; - unsigned char *ptr; - int mv_row = x->mode_info_context->mbmi.mv.as_mv.row; - int mv_col = x->mode_info_context->mbmi.mv.as_mv.col; - int pre_stride = x->pre.y_stride; - - ptr_base = x->pre.y_buffer; - ptr = ptr_base + (mv_row >> 3) * pre_stride + (mv_col >> 3); - - if ((mv_row | mv_col) & 7) { - x->subpixel_predict16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, dst_y, - dst_ystride); - } else { - vp8_copy_mem16x16(ptr, pre_stride, dst_y, dst_ystride); - } -} - -static void clamp_mv_to_umv_border(MV *mv, const MACROBLOCKD *xd) { - /* If the MV points so far into the UMV border that no visible pixels - * are used for reconstruction, the subpel part of the MV can be - * discarded and the MV limited to 16 pixels with equivalent results. - * - * This limit kicks in at 19 pixels for the top and left edges, for - * the 16 pixels plus 3 taps right of the central pixel when subpel - * filtering. The bottom and right edges use 16 pixels plus 2 pixels - * left of the central pixel when filtering. - */ - if (mv->col < (xd->mb_to_left_edge - (19 << 3))) { - mv->col = xd->mb_to_left_edge - (16 << 3); - } else if (mv->col > xd->mb_to_right_edge + (18 << 3)) { - mv->col = xd->mb_to_right_edge + (16 << 3); - } - - if (mv->row < (xd->mb_to_top_edge - (19 << 3))) { - mv->row = xd->mb_to_top_edge - (16 << 3); - } else if (mv->row > xd->mb_to_bottom_edge + (18 << 3)) { - mv->row = xd->mb_to_bottom_edge + (16 << 3); - } -} - -/* A version of the above function for chroma block MVs.*/ -static void clamp_uvmv_to_umv_border(MV *mv, const MACROBLOCKD *xd) { - mv->col = (2 * mv->col < (xd->mb_to_left_edge - (19 << 3))) - ? (xd->mb_to_left_edge - (16 << 3)) >> 1 - : mv->col; - mv->col = (2 * mv->col > xd->mb_to_right_edge + (18 << 3)) - ? (xd->mb_to_right_edge + (16 << 3)) >> 1 - : mv->col; - - mv->row = (2 * mv->row < (xd->mb_to_top_edge - (19 << 3))) - ? (xd->mb_to_top_edge - (16 << 3)) >> 1 - : mv->row; - mv->row = (2 * mv->row > xd->mb_to_bottom_edge + (18 << 3)) - ? (xd->mb_to_bottom_edge + (16 << 3)) >> 1 - : mv->row; -} - -void vp8_build_inter16x16_predictors_mb(MACROBLOCKD *x, unsigned char *dst_y, - unsigned char *dst_u, - unsigned char *dst_v, int dst_ystride, - int dst_uvstride) { - int offset; - unsigned char *ptr; - unsigned char *uptr, *vptr; - - int_mv _16x16mv; - - unsigned char *ptr_base = x->pre.y_buffer; - int pre_stride = x->pre.y_stride; - - _16x16mv.as_int = x->mode_info_context->mbmi.mv.as_int; - - if (x->mode_info_context->mbmi.need_to_clamp_mvs) { - clamp_mv_to_umv_border(&_16x16mv.as_mv, x); - } - - ptr = ptr_base + (_16x16mv.as_mv.row >> 3) * pre_stride + - (_16x16mv.as_mv.col >> 3); - - if (_16x16mv.as_int & 0x00070007) { - x->subpixel_predict16x16(ptr, pre_stride, _16x16mv.as_mv.col & 7, - _16x16mv.as_mv.row & 7, dst_y, dst_ystride); - } else { - vp8_copy_mem16x16(ptr, pre_stride, dst_y, dst_ystride); - } - - /* calc uv motion vectors */ - _16x16mv.as_mv.row += - 1 | (_16x16mv.as_mv.row >> (sizeof(int) * CHAR_BIT - 1)); - _16x16mv.as_mv.col += - 1 | (_16x16mv.as_mv.col >> (sizeof(int) * CHAR_BIT - 1)); - _16x16mv.as_mv.row /= 2; - _16x16mv.as_mv.col /= 2; - _16x16mv.as_mv.row &= x->fullpixel_mask; - _16x16mv.as_mv.col &= x->fullpixel_mask; - - if (2 * _16x16mv.as_mv.col < (x->mb_to_left_edge - (19 << 3)) || - 2 * _16x16mv.as_mv.col > x->mb_to_right_edge + (18 << 3) || - 2 * _16x16mv.as_mv.row < (x->mb_to_top_edge - (19 << 3)) || - 2 * _16x16mv.as_mv.row > x->mb_to_bottom_edge + (18 << 3)) { - return; - } - - pre_stride >>= 1; - offset = (_16x16mv.as_mv.row >> 3) * pre_stride + (_16x16mv.as_mv.col >> 3); - uptr = x->pre.u_buffer + offset; - vptr = x->pre.v_buffer + offset; - - if (_16x16mv.as_int & 0x00070007) { - x->subpixel_predict8x8(uptr, pre_stride, _16x16mv.as_mv.col & 7, - _16x16mv.as_mv.row & 7, dst_u, dst_uvstride); - x->subpixel_predict8x8(vptr, pre_stride, _16x16mv.as_mv.col & 7, - _16x16mv.as_mv.row & 7, dst_v, dst_uvstride); - } else { - vp8_copy_mem8x8(uptr, pre_stride, dst_u, dst_uvstride); - vp8_copy_mem8x8(vptr, pre_stride, dst_v, dst_uvstride); - } -} - -static void build_inter4x4_predictors_mb(MACROBLOCKD *x) { - int i; - unsigned char *base_dst = x->dst.y_buffer; - unsigned char *base_pre = x->pre.y_buffer; - - if (x->mode_info_context->mbmi.partitioning < 3) { - BLOCKD *b; - int dst_stride = x->dst.y_stride; - - x->block[0].bmi = x->mode_info_context->bmi[0]; - x->block[2].bmi = x->mode_info_context->bmi[2]; - x->block[8].bmi = x->mode_info_context->bmi[8]; - x->block[10].bmi = x->mode_info_context->bmi[10]; - if (x->mode_info_context->mbmi.need_to_clamp_mvs) { - clamp_mv_to_umv_border(&x->block[0].bmi.mv.as_mv, x); - clamp_mv_to_umv_border(&x->block[2].bmi.mv.as_mv, x); - clamp_mv_to_umv_border(&x->block[8].bmi.mv.as_mv, x); - clamp_mv_to_umv_border(&x->block[10].bmi.mv.as_mv, x); - } - - b = &x->block[0]; - build_inter_predictors4b(x, b, base_dst + b->offset, dst_stride, base_pre, - dst_stride); - b = &x->block[2]; - build_inter_predictors4b(x, b, base_dst + b->offset, dst_stride, base_pre, - dst_stride); - b = &x->block[8]; - build_inter_predictors4b(x, b, base_dst + b->offset, dst_stride, base_pre, - dst_stride); - b = &x->block[10]; - build_inter_predictors4b(x, b, base_dst + b->offset, dst_stride, base_pre, - dst_stride); - } else { - for (i = 0; i < 16; i += 2) { - BLOCKD *d0 = &x->block[i]; - BLOCKD *d1 = &x->block[i + 1]; - int dst_stride = x->dst.y_stride; - - x->block[i + 0].bmi = x->mode_info_context->bmi[i + 0]; - x->block[i + 1].bmi = x->mode_info_context->bmi[i + 1]; - if (x->mode_info_context->mbmi.need_to_clamp_mvs) { - clamp_mv_to_umv_border(&x->block[i + 0].bmi.mv.as_mv, x); - clamp_mv_to_umv_border(&x->block[i + 1].bmi.mv.as_mv, x); - } - - if (d0->bmi.mv.as_int == d1->bmi.mv.as_int) { - build_inter_predictors2b(x, d0, base_dst + d0->offset, dst_stride, - base_pre, dst_stride); - } else { - build_inter_predictors_b(d0, base_dst + d0->offset, dst_stride, - base_pre, dst_stride, x->subpixel_predict); - build_inter_predictors_b(d1, base_dst + d1->offset, dst_stride, - base_pre, dst_stride, x->subpixel_predict); - } - } - } - base_dst = x->dst.u_buffer; - base_pre = x->pre.u_buffer; - for (i = 16; i < 20; i += 2) { - BLOCKD *d0 = &x->block[i]; - BLOCKD *d1 = &x->block[i + 1]; - int dst_stride = x->dst.uv_stride; - - /* Note: uv mvs already clamped in build_4x4uvmvs() */ - - if (d0->bmi.mv.as_int == d1->bmi.mv.as_int) { - build_inter_predictors2b(x, d0, base_dst + d0->offset, dst_stride, - base_pre, dst_stride); - } else { - build_inter_predictors_b(d0, base_dst + d0->offset, dst_stride, base_pre, - dst_stride, x->subpixel_predict); - build_inter_predictors_b(d1, base_dst + d1->offset, dst_stride, base_pre, - dst_stride, x->subpixel_predict); - } - } - - base_dst = x->dst.v_buffer; - base_pre = x->pre.v_buffer; - for (i = 20; i < 24; i += 2) { - BLOCKD *d0 = &x->block[i]; - BLOCKD *d1 = &x->block[i + 1]; - int dst_stride = x->dst.uv_stride; - - /* Note: uv mvs already clamped in build_4x4uvmvs() */ - - if (d0->bmi.mv.as_int == d1->bmi.mv.as_int) { - build_inter_predictors2b(x, d0, base_dst + d0->offset, dst_stride, - base_pre, dst_stride); - } else { - build_inter_predictors_b(d0, base_dst + d0->offset, dst_stride, base_pre, - dst_stride, x->subpixel_predict); - build_inter_predictors_b(d1, base_dst + d1->offset, dst_stride, base_pre, - dst_stride, x->subpixel_predict); - } - } -} - -static void build_4x4uvmvs(MACROBLOCKD *x) { - int i, j; - - for (i = 0; i < 2; ++i) { - for (j = 0; j < 2; ++j) { - int yoffset = i * 8 + j * 2; - int uoffset = 16 + i * 2 + j; - int voffset = 20 + i * 2 + j; - - int temp; - - temp = x->mode_info_context->bmi[yoffset + 0].mv.as_mv.row + - x->mode_info_context->bmi[yoffset + 1].mv.as_mv.row + - x->mode_info_context->bmi[yoffset + 4].mv.as_mv.row + - x->mode_info_context->bmi[yoffset + 5].mv.as_mv.row; - - temp += 4 + ((temp >> (sizeof(temp) * CHAR_BIT - 1)) * 8); - - x->block[uoffset].bmi.mv.as_mv.row = (temp / 8) & x->fullpixel_mask; - - temp = x->mode_info_context->bmi[yoffset + 0].mv.as_mv.col + - x->mode_info_context->bmi[yoffset + 1].mv.as_mv.col + - x->mode_info_context->bmi[yoffset + 4].mv.as_mv.col + - x->mode_info_context->bmi[yoffset + 5].mv.as_mv.col; - - temp += 4 + ((temp >> (sizeof(temp) * CHAR_BIT - 1)) * 8); - - x->block[uoffset].bmi.mv.as_mv.col = (temp / 8) & x->fullpixel_mask; - - if (x->mode_info_context->mbmi.need_to_clamp_mvs) { - clamp_uvmv_to_umv_border(&x->block[uoffset].bmi.mv.as_mv, x); - } - - x->block[voffset].bmi.mv.as_int = x->block[uoffset].bmi.mv.as_int; - } - } -} - -void vp8_build_inter_predictors_mb(MACROBLOCKD *xd) { - if (xd->mode_info_context->mbmi.mode != SPLITMV) { - vp8_build_inter16x16_predictors_mb(xd, xd->dst.y_buffer, xd->dst.u_buffer, - xd->dst.v_buffer, xd->dst.y_stride, - xd->dst.uv_stride); - } else { - build_4x4uvmvs(xd); - build_inter4x4_predictors_mb(xd); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconinter.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconinter.h deleted file mode 100644 index 974e7ce7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconinter.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_RECONINTER_H_ -#define VPX_VP8_COMMON_RECONINTER_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -void vp8_build_inter_predictors_mb(MACROBLOCKD *xd); -void vp8_build_inter16x16_predictors_mb(MACROBLOCKD *x, unsigned char *dst_y, - unsigned char *dst_u, - unsigned char *dst_v, int dst_ystride, - int dst_uvstride); - -void vp8_build_inter16x16_predictors_mby(MACROBLOCKD *x, unsigned char *dst_y, - int dst_ystride); -void vp8_build_inter_predictors_b(BLOCKD *d, int pitch, unsigned char *base_pre, - int pre_stride, vp8_subpix_fn_t sppf); - -void vp8_build_inter16x16_predictors_mbuv(MACROBLOCKD *x); -void vp8_build_inter4x4_predictors_mbuv(MACROBLOCKD *x); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_RECONINTER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconintra.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconintra.c deleted file mode 100644 index 8e2094da..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconintra.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "./vp8_rtcd.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/vpx_once.h" -#include "blockd.h" -#include "vp8/common/reconintra.h" -#include "vp8/common/reconintra4x4.h" - -enum { - SIZE_16, - SIZE_8, - NUM_SIZES, -}; - -typedef void (*intra_pred_fn)(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left); - -static intra_pred_fn pred[4][NUM_SIZES]; -static intra_pred_fn dc_pred[2][2][NUM_SIZES]; - -static void vp8_init_intra_predictors_internal(void) { -#define INIT_SIZE(sz) \ - pred[V_PRED][SIZE_##sz] = vpx_v_predictor_##sz##x##sz; \ - pred[H_PRED][SIZE_##sz] = vpx_h_predictor_##sz##x##sz; \ - pred[TM_PRED][SIZE_##sz] = vpx_tm_predictor_##sz##x##sz; \ - \ - dc_pred[0][0][SIZE_##sz] = vpx_dc_128_predictor_##sz##x##sz; \ - dc_pred[0][1][SIZE_##sz] = vpx_dc_top_predictor_##sz##x##sz; \ - dc_pred[1][0][SIZE_##sz] = vpx_dc_left_predictor_##sz##x##sz; \ - dc_pred[1][1][SIZE_##sz] = vpx_dc_predictor_##sz##x##sz - - INIT_SIZE(16); - INIT_SIZE(8); - vp8_init_intra4x4_predictors_internal(); -} - -void vp8_build_intra_predictors_mby_s(MACROBLOCKD *x, unsigned char *yabove_row, - unsigned char *yleft, int left_stride, - unsigned char *ypred_ptr, int y_stride) { - MB_PREDICTION_MODE mode = x->mode_info_context->mbmi.mode; - DECLARE_ALIGNED(16, uint8_t, yleft_col[16]); - int i; - intra_pred_fn fn; - - for (i = 0; i < 16; ++i) { - yleft_col[i] = yleft[i * left_stride]; - } - - if (mode == DC_PRED) { - fn = dc_pred[x->left_available][x->up_available][SIZE_16]; - } else { - fn = pred[mode][SIZE_16]; - } - - fn(ypred_ptr, y_stride, yabove_row, yleft_col); -} - -void vp8_build_intra_predictors_mbuv_s( - MACROBLOCKD *x, unsigned char *uabove_row, unsigned char *vabove_row, - unsigned char *uleft, unsigned char *vleft, int left_stride, - unsigned char *upred_ptr, unsigned char *vpred_ptr, int pred_stride) { - MB_PREDICTION_MODE uvmode = x->mode_info_context->mbmi.uv_mode; -#if HAVE_VSX - /* Power PC implementation uses "vec_vsx_ld" to read 16 bytes from - uleft_col and vleft_col. Play it safe by reserving enough stack - space here. */ - unsigned char uleft_col[16]; - unsigned char vleft_col[16]; -#else - unsigned char uleft_col[8]; - unsigned char vleft_col[8]; -#endif - int i; - intra_pred_fn fn; - - for (i = 0; i < 8; ++i) { - uleft_col[i] = uleft[i * left_stride]; - vleft_col[i] = vleft[i * left_stride]; - } - - if (uvmode == DC_PRED) { - fn = dc_pred[x->left_available][x->up_available][SIZE_8]; - } else { - fn = pred[uvmode][SIZE_8]; - } - - fn(upred_ptr, pred_stride, uabove_row, uleft_col); - fn(vpred_ptr, pred_stride, vabove_row, vleft_col); -} - -void vp8_init_intra_predictors(void) { - once(vp8_init_intra_predictors_internal); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconintra.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconintra.h deleted file mode 100644 index 029ac00a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconintra.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_RECONINTRA_H_ -#define VPX_VP8_COMMON_RECONINTRA_H_ - -#include "vp8/common/blockd.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vp8_build_intra_predictors_mby_s(MACROBLOCKD *x, unsigned char *yabove_row, - unsigned char *yleft, int left_stride, - unsigned char *ypred_ptr, int y_stride); - -void vp8_build_intra_predictors_mbuv_s( - MACROBLOCKD *x, unsigned char *uabove_row, unsigned char *vabove_row, - unsigned char *uleft, unsigned char *vleft, int left_stride, - unsigned char *upred_ptr, unsigned char *vpred_ptr, int pred_stride); - -void vp8_init_intra_predictors(void); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_RECONINTRA_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconintra4x4.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconintra4x4.c deleted file mode 100644 index be936df5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconintra4x4.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vp8_rtcd.h" -#include "blockd.h" -#include "reconintra4x4.h" -#include "vp8/common/common.h" -#include "vpx_ports/compiler_attributes.h" - -typedef void (*intra_pred_fn)(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left); - -static intra_pred_fn pred[10]; - -void vp8_init_intra4x4_predictors_internal(void) { - pred[B_DC_PRED] = vpx_dc_predictor_4x4; - pred[B_TM_PRED] = vpx_tm_predictor_4x4; - pred[B_VE_PRED] = vpx_ve_predictor_4x4; - pred[B_HE_PRED] = vpx_he_predictor_4x4; - pred[B_LD_PRED] = vpx_d45e_predictor_4x4; - pred[B_RD_PRED] = vpx_d135_predictor_4x4; - pred[B_VR_PRED] = vpx_d117_predictor_4x4; - pred[B_VL_PRED] = vpx_d63e_predictor_4x4; - pred[B_HD_PRED] = vpx_d153_predictor_4x4; - pred[B_HU_PRED] = vpx_d207_predictor_4x4; -} - -void vp8_intra4x4_predict(unsigned char *above, unsigned char *yleft, - int left_stride, B_PREDICTION_MODE b_mode, - unsigned char *dst, int dst_stride, - unsigned char top_left) { -/* Power PC implementation uses "vec_vsx_ld" to read 16 bytes from - Above (aka, Aboveb + 4). Play it safe by reserving enough stack - space here. Similary for "Left". */ -#if HAVE_VSX - unsigned char Aboveb[20]; -#else - unsigned char Aboveb[12]; -#endif - unsigned char *Above = Aboveb + 4; -#if HAVE_NEON - // Neon intrinsics are unable to load 32 bits, or 4 8 bit values. Instead, it - // over reads but does not use the extra 4 values. - unsigned char Left[8]; -#if VPX_WITH_ASAN - // Silence an 'uninitialized read' warning. Although uninitialized values are - // indeed read, they are not used. - vp8_zero_array(Left, 8); -#endif // VPX_WITH_ASAN -#elif HAVE_VSX - unsigned char Left[16]; -#else - unsigned char Left[4]; -#endif // HAVE_NEON - - Left[0] = yleft[0]; - Left[1] = yleft[left_stride]; - Left[2] = yleft[2 * left_stride]; - Left[3] = yleft[3 * left_stride]; - memcpy(Above, above, 8); - Above[-1] = top_left; - - pred[b_mode](dst, dst_stride, Above, Left); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconintra4x4.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconintra4x4.h deleted file mode 100644 index 3618ec5c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/reconintra4x4.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_RECONINTRA4X4_H_ -#define VPX_VP8_COMMON_RECONINTRA4X4_H_ -#include "vp8/common/blockd.h" - -#ifdef __cplusplus -extern "C" { -#endif - -static INLINE void intra_prediction_down_copy(MACROBLOCKD *xd, - unsigned char *above_right_src) { - int dst_stride = xd->dst.y_stride; - unsigned char *above_right_dst = xd->dst.y_buffer - dst_stride + 16; - - unsigned int *src_ptr = (unsigned int *)above_right_src; - unsigned int *dst_ptr0 = (unsigned int *)(above_right_dst + 4 * dst_stride); - unsigned int *dst_ptr1 = (unsigned int *)(above_right_dst + 8 * dst_stride); - unsigned int *dst_ptr2 = (unsigned int *)(above_right_dst + 12 * dst_stride); - - *dst_ptr0 = *src_ptr; - *dst_ptr1 = *src_ptr; - *dst_ptr2 = *src_ptr; -} - -void vp8_intra4x4_predict(unsigned char *above, unsigned char *yleft, - int left_stride, B_PREDICTION_MODE b_mode, - unsigned char *dst, int dst_stride, - unsigned char top_left); - -void vp8_init_intra4x4_predictors_internal(void); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_RECONINTRA4X4_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/rtcd.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/rtcd.c deleted file mode 100644 index 102b7ccd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/rtcd.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2011 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "./vpx_config.h" -#define RTCD_C -#include "./vp8_rtcd.h" -#include "vpx_ports/vpx_once.h" - -void vp8_rtcd(void) { once(setup_rtcd_internal); } diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/rtcd_defs.pl b/presentation/src/main/cpp/third_party/libvpx/vp8/common/rtcd_defs.pl deleted file mode 100644 index 12b474d9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/rtcd_defs.pl +++ /dev/null @@ -1,244 +0,0 @@ -## -## Copyright (c) 2017 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -sub vp8_common_forward_decls() { -print <y_buffer - 1 - ybf->y_stride, 127, ybf->y_width + 5); - for (i = 0; i < ybf->y_height; ++i) { - ybf->y_buffer[ybf->y_stride * i - 1] = (unsigned char)129; - } - - memset(ybf->u_buffer - 1 - ybf->uv_stride, 127, ybf->uv_width + 5); - for (i = 0; i < ybf->uv_height; ++i) { - ybf->u_buffer[ybf->uv_stride * i - 1] = (unsigned char)129; - } - - memset(ybf->v_buffer - 1 - ybf->uv_stride, 127, ybf->uv_width + 5); - for (i = 0; i < ybf->uv_height; ++i) { - ybf->v_buffer[ybf->uv_stride * i - 1] = (unsigned char)129; - } -} - -void vp8_setup_intra_recon_top_line(YV12_BUFFER_CONFIG *ybf) { - memset(ybf->y_buffer - 1 - ybf->y_stride, 127, ybf->y_width + 5); - memset(ybf->u_buffer - 1 - ybf->uv_stride, 127, ybf->uv_width + 5); - memset(ybf->v_buffer - 1 - ybf->uv_stride, 127, ybf->uv_width + 5); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/setupintrarecon.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/setupintrarecon.h deleted file mode 100644 index 903a536a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/setupintrarecon.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_SETUPINTRARECON_H_ -#define VPX_VP8_COMMON_SETUPINTRARECON_H_ - -#include "./vpx_config.h" -#include "vpx_scale/yv12config.h" - -#ifdef __cplusplus -extern "C" { -#endif -extern void vp8_setup_intra_recon(YV12_BUFFER_CONFIG *ybf); -extern void vp8_setup_intra_recon_top_line(YV12_BUFFER_CONFIG *ybf); - -static INLINE void setup_intra_recon_left(unsigned char *y_buffer, - unsigned char *u_buffer, - unsigned char *v_buffer, int y_stride, - int uv_stride) { - int i; - - for (i = 0; i < 16; ++i) y_buffer[y_stride * i] = (unsigned char)129; - - for (i = 0; i < 8; ++i) u_buffer[uv_stride * i] = (unsigned char)129; - - for (i = 0; i < 8; ++i) v_buffer[uv_stride * i] = (unsigned char)129; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_SETUPINTRARECON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/swapyv12buffer.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/swapyv12buffer.c deleted file mode 100644 index 5ff21e94..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/swapyv12buffer.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "swapyv12buffer.h" - -void vp8_swap_yv12_buffer(YV12_BUFFER_CONFIG *new_frame, - YV12_BUFFER_CONFIG *last_frame) { - unsigned char *temp; - - temp = last_frame->buffer_alloc; - last_frame->buffer_alloc = new_frame->buffer_alloc; - new_frame->buffer_alloc = temp; - - temp = last_frame->y_buffer; - last_frame->y_buffer = new_frame->y_buffer; - new_frame->y_buffer = temp; - - temp = last_frame->u_buffer; - last_frame->u_buffer = new_frame->u_buffer; - new_frame->u_buffer = temp; - - temp = last_frame->v_buffer; - last_frame->v_buffer = new_frame->v_buffer; - new_frame->v_buffer = temp; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/swapyv12buffer.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/swapyv12buffer.h deleted file mode 100644 index e37c471f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/swapyv12buffer.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_SWAPYV12BUFFER_H_ -#define VPX_VP8_COMMON_SWAPYV12BUFFER_H_ - -#include "vpx_scale/yv12config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vp8_swap_yv12_buffer(YV12_BUFFER_CONFIG *new_frame, - YV12_BUFFER_CONFIG *last_frame); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_SWAPYV12BUFFER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/systemdependent.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/systemdependent.h deleted file mode 100644 index 83a5513a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/systemdependent.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_SYSTEMDEPENDENT_H_ -#define VPX_VP8_COMMON_SYSTEMDEPENDENT_H_ - -#include "vpx_config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct VP8Common; -void vp8_machine_specific_config(struct VP8Common *); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_SYSTEMDEPENDENT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/threading.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/threading.h deleted file mode 100644 index 0de75cfd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/threading.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_THREADING_H_ -#define VPX_VP8_COMMON_THREADING_H_ - -#include "./vpx_config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if CONFIG_OS_SUPPORT && CONFIG_MULTITHREAD - -#if defined(_WIN32) && !HAVE_PTHREAD_H -/* Win32 */ -#include -#else -/* pthreads */ -#ifdef __APPLE__ -#include -#include -#include -#include -#include -#else -#include -#endif -#endif - -/* Synchronization macros: Win32 and Pthreads */ -#if defined(_WIN32) && !HAVE_PTHREAD_H -#define vp8_sem_t HANDLE -#define vp8_sem_init(sem, pshared, value) \ - (int)((*sem = CreateSemaphore(NULL, value, 32768, NULL)) == NULL) -#define vp8_sem_wait(sem) \ - (int)(WAIT_OBJECT_0 != WaitForSingleObject(*sem, INFINITE)) -#define vp8_sem_post(sem) ReleaseSemaphore(*sem, 1, NULL) -#define vp8_sem_destroy(sem) \ - if (*sem) ((int)(CloseHandle(*sem)) == TRUE) -#define thread_sleep(nms) Sleep(nms) - -#else - -#ifdef __APPLE__ -#define vp8_sem_t semaphore_t -#define vp8_sem_init(sem, pshared, value) \ - semaphore_create(mach_task_self(), sem, SYNC_POLICY_FIFO, value) -#define vp8_sem_wait(sem) semaphore_wait(*sem) -#define vp8_sem_post(sem) semaphore_signal(*sem) -#define vp8_sem_destroy(sem) semaphore_destroy(mach_task_self(), *sem) -#else -#include -#include -#include -#define vp8_sem_t sem_t -#define vp8_sem_init sem_init -static INLINE int vp8_sem_wait(vp8_sem_t *sem) { - int ret; - while ((ret = sem_wait(sem)) == -1 && errno == EINTR) { - } - return ret; -} -#define vp8_sem_post sem_post -#define vp8_sem_destroy sem_destroy -#endif /* __APPLE__ */ -/* Not Windows. Assume pthreads */ - -/* thread_sleep implementation: yield unless Linux/Unix. */ -#if defined(__unix__) || defined(__APPLE__) -#define thread_sleep(nms) -/* {struct timespec ts;ts.tv_sec=0; - ts.tv_nsec = 1000*nms;nanosleep(&ts, NULL);} */ -#else -#define thread_sleep(nms) sched_yield(); -#endif /* __unix__ || __APPLE__ */ - -#endif - -#if VPX_ARCH_X86 || VPX_ARCH_X86_64 -#include "vpx_ports/x86.h" -#else -#define x86_pause_hint() -#endif - -#include "vpx_util/vpx_atomics.h" - -static INLINE void vp8_atomic_spin_wait( - int mb_col, const vpx_atomic_int *last_row_current_mb_col, - const int nsync) { - while (mb_col > (vpx_atomic_load_acquire(last_row_current_mb_col) - nsync)) { - x86_pause_hint(); - thread_sleep(0); - } -} - -#endif /* CONFIG_OS_SUPPORT && CONFIG_MULTITHREAD */ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_THREADING_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/treecoder.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/treecoder.c deleted file mode 100644 index f1e78f43..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/treecoder.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "vp8/common/treecoder.h" -#include "vpx/vpx_integer.h" - -static void tree2tok(struct vp8_token_struct *const p, vp8_tree t, int i, int v, - int L) { - v += v; - ++L; - - do { - const vp8_tree_index j = t[i++]; - - if (j <= 0) { - p[-j].value = v; - p[-j].Len = L; - } else { - tree2tok(p, t, j, v, L); - } - } while (++v & 1); -} - -void vp8_tokens_from_tree(struct vp8_token_struct *p, vp8_tree t) { - tree2tok(p, t, 0, 0, 0); -} - -void vp8_tokens_from_tree_offset(struct vp8_token_struct *p, vp8_tree t, - int offset) { - tree2tok(p - offset, t, 0, 0, 0); -} - -static void branch_counts(int n, /* n = size of alphabet */ - vp8_token tok[/* n */], vp8_tree tree, - unsigned int branch_ct[/* n-1 */][2], - const unsigned int num_events[/* n */]) { - const int tree_len = n - 1; - int t = 0; - - assert(tree_len); - - do { - branch_ct[t][0] = branch_ct[t][1] = 0; - } while (++t < tree_len); - - t = 0; - - do { - int L = tok[t].Len; - const int enc = tok[t].value; - const unsigned int ct = num_events[t]; - - vp8_tree_index i = 0; - - do { - const int b = (enc >> --L) & 1; - const int j = i >> 1; - assert(j < tree_len && 0 <= L); - - branch_ct[j][b] += ct; - i = tree[i + b]; - } while (i > 0); - - assert(!L); - } while (++t < n); -} - -void vp8_tree_probs_from_distribution(int n, /* n = size of alphabet */ - vp8_token tok[/* n */], vp8_tree tree, - vp8_prob probs[/* n-1 */], - unsigned int branch_ct[/* n-1 */][2], - const unsigned int num_events[/* n */], - unsigned int Pfactor, int Round) { - const int tree_len = n - 1; - int t = 0; - - branch_counts(n, tok, tree, branch_ct, num_events); - - do { - const unsigned int *const c = branch_ct[t]; - const unsigned int tot = c[0] + c[1]; - - if (tot) { - const unsigned int p = - (unsigned int)(((uint64_t)c[0] * Pfactor) + (Round ? tot >> 1 : 0)) / - tot; - probs[t] = p < 256 ? (p ? p : 1) : 255; /* agree w/old version for now */ - } else { - probs[t] = vp8_prob_half; - } - } while (++t < tree_len); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/treecoder.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/treecoder.h deleted file mode 100644 index d7d8d0ea..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/treecoder.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_TREECODER_H_ -#define VPX_VP8_COMMON_TREECODER_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef unsigned char vp8bc_index_t; /* probability index */ - -typedef unsigned char vp8_prob; - -#define vp8_prob_half ((vp8_prob)128) - -typedef signed char vp8_tree_index; -struct bool_coder_spec; - -typedef struct bool_coder_spec bool_coder_spec; -typedef struct bool_writer bool_writer; -typedef struct bool_reader bool_reader; - -typedef const bool_coder_spec c_bool_coder_spec; -typedef const bool_writer c_bool_writer; -typedef const bool_reader c_bool_reader; - -#define vp8_complement(x) (255 - (x)) - -/* We build coding trees compactly in arrays. - Each node of the tree is a pair of vp8_tree_indices. - Array index often references a corresponding probability table. - Index <= 0 means done encoding/decoding and value = -Index, - Index > 0 means need another bit, specification at index. - Nonnegative indices are always even; processing begins at node 0. */ - -typedef const vp8_tree_index vp8_tree[], *vp8_tree_p; - -typedef const struct vp8_token_struct { - int value; - int Len; -} vp8_token; - -/* Construct encoding array from tree. */ - -void vp8_tokens_from_tree(struct vp8_token_struct *, vp8_tree); -void vp8_tokens_from_tree_offset(struct vp8_token_struct *, vp8_tree, - int offset); - -/* Convert array of token occurrence counts into a table of probabilities - for the associated binary encoding tree. Also writes count of branches - taken for each node on the tree; this facilitiates decisions as to - probability updates. */ - -void vp8_tree_probs_from_distribution(int n, /* n = size of alphabet */ - vp8_token tok[/* n */], vp8_tree tree, - vp8_prob probs[/* n-1 */], - unsigned int branch_ct[/* n-1 */][2], - const unsigned int num_events[/* n */], - unsigned int Pfactor, int Round); - -/* Variant of above using coder spec rather than hardwired 8-bit probs. */ - -void vp8bc_tree_probs_from_distribution(int n, /* n = size of alphabet */ - vp8_token tok[/* n */], vp8_tree tree, - vp8_prob probs[/* n-1 */], - unsigned int branch_ct[/* n-1 */][2], - const unsigned int num_events[/* n */], - c_bool_coder_spec *s); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_TREECODER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/vp8_entropymodedata.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/vp8_entropymodedata.h deleted file mode 100644 index 3fc942e0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/vp8_entropymodedata.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_VP8_ENTROPYMODEDATA_H_ -#define VPX_VP8_COMMON_VP8_ENTROPYMODEDATA_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/*Generated file, included by entropymode.c*/ - -const struct vp8_token_struct vp8_bmode_encodings[VP8_BINTRAMODES] = { - { 0, 1 }, { 2, 2 }, { 6, 3 }, { 28, 5 }, { 30, 5 }, - { 58, 6 }, { 59, 6 }, { 62, 6 }, { 126, 7 }, { 127, 7 } -}; - -const struct vp8_token_struct vp8_ymode_encodings[VP8_YMODES] = { - { 0, 1 }, { 4, 3 }, { 5, 3 }, { 6, 3 }, { 7, 3 } -}; - -const struct vp8_token_struct vp8_kf_ymode_encodings[VP8_YMODES] = { - { 4, 3 }, { 5, 3 }, { 6, 3 }, { 7, 3 }, { 0, 1 } -}; - -const struct vp8_token_struct vp8_uv_mode_encodings[VP8_UV_MODES] = { - { 0, 1 }, { 2, 2 }, { 6, 3 }, { 7, 3 } -}; - -const struct vp8_token_struct vp8_mbsplit_encodings[VP8_NUMMBSPLITS] = { - { 6, 3 }, { 7, 3 }, { 2, 2 }, { 0, 1 } -}; - -const struct vp8_token_struct vp8_mv_ref_encoding_array[VP8_MVREFS] = { - { 2, 2 }, { 6, 3 }, { 0, 1 }, { 14, 4 }, { 15, 4 } -}; - -const struct vp8_token_struct vp8_sub_mv_ref_encoding_array[VP8_SUBMVREFS] = { - { 0, 1 }, { 2, 2 }, { 6, 3 }, { 7, 3 } -}; - -const struct vp8_token_struct vp8_small_mvencodings[8] = { - { 0, 3 }, { 1, 3 }, { 2, 3 }, { 3, 3 }, { 4, 3 }, { 5, 3 }, { 6, 3 }, { 7, 3 } -}; - -const vp8_prob vp8_ymode_prob[VP8_YMODES - 1] = { 112, 86, 140, 37 }; - -const vp8_prob vp8_kf_ymode_prob[VP8_YMODES - 1] = { 145, 156, 163, 128 }; - -const vp8_prob vp8_uv_mode_prob[VP8_UV_MODES - 1] = { 162, 101, 204 }; - -const vp8_prob vp8_kf_uv_mode_prob[VP8_UV_MODES - 1] = { 142, 114, 183 }; - -const vp8_prob vp8_bmode_prob[VP8_BINTRAMODES - 1] = { 120, 90, 79, 133, 87, - 85, 80, 111, 151 }; - -const vp8_prob - vp8_kf_bmode_prob[VP8_BINTRAMODES][VP8_BINTRAMODES][VP8_BINTRAMODES - 1] = { - { { 231, 120, 48, 89, 115, 113, 120, 152, 112 }, - { 152, 179, 64, 126, 170, 118, 46, 70, 95 }, - { 175, 69, 143, 80, 85, 82, 72, 155, 103 }, - { 56, 58, 10, 171, 218, 189, 17, 13, 152 }, - { 144, 71, 10, 38, 171, 213, 144, 34, 26 }, - { 114, 26, 17, 163, 44, 195, 21, 10, 173 }, - { 121, 24, 80, 195, 26, 62, 44, 64, 85 }, - { 170, 46, 55, 19, 136, 160, 33, 206, 71 }, - { 63, 20, 8, 114, 114, 208, 12, 9, 226 }, - { 81, 40, 11, 96, 182, 84, 29, 16, 36 } }, - { { 134, 183, 89, 137, 98, 101, 106, 165, 148 }, - { 72, 187, 100, 130, 157, 111, 32, 75, 80 }, - { 66, 102, 167, 99, 74, 62, 40, 234, 128 }, - { 41, 53, 9, 178, 241, 141, 26, 8, 107 }, - { 104, 79, 12, 27, 217, 255, 87, 17, 7 }, - { 74, 43, 26, 146, 73, 166, 49, 23, 157 }, - { 65, 38, 105, 160, 51, 52, 31, 115, 128 }, - { 87, 68, 71, 44, 114, 51, 15, 186, 23 }, - { 47, 41, 14, 110, 182, 183, 21, 17, 194 }, - { 66, 45, 25, 102, 197, 189, 23, 18, 22 } }, - { { 88, 88, 147, 150, 42, 46, 45, 196, 205 }, - { 43, 97, 183, 117, 85, 38, 35, 179, 61 }, - { 39, 53, 200, 87, 26, 21, 43, 232, 171 }, - { 56, 34, 51, 104, 114, 102, 29, 93, 77 }, - { 107, 54, 32, 26, 51, 1, 81, 43, 31 }, - { 39, 28, 85, 171, 58, 165, 90, 98, 64 }, - { 34, 22, 116, 206, 23, 34, 43, 166, 73 }, - { 68, 25, 106, 22, 64, 171, 36, 225, 114 }, - { 34, 19, 21, 102, 132, 188, 16, 76, 124 }, - { 62, 18, 78, 95, 85, 57, 50, 48, 51 } }, - { { 193, 101, 35, 159, 215, 111, 89, 46, 111 }, - { 60, 148, 31, 172, 219, 228, 21, 18, 111 }, - { 112, 113, 77, 85, 179, 255, 38, 120, 114 }, - { 40, 42, 1, 196, 245, 209, 10, 25, 109 }, - { 100, 80, 8, 43, 154, 1, 51, 26, 71 }, - { 88, 43, 29, 140, 166, 213, 37, 43, 154 }, - { 61, 63, 30, 155, 67, 45, 68, 1, 209 }, - { 142, 78, 78, 16, 255, 128, 34, 197, 171 }, - { 41, 40, 5, 102, 211, 183, 4, 1, 221 }, - { 51, 50, 17, 168, 209, 192, 23, 25, 82 } }, - { { 125, 98, 42, 88, 104, 85, 117, 175, 82 }, - { 95, 84, 53, 89, 128, 100, 113, 101, 45 }, - { 75, 79, 123, 47, 51, 128, 81, 171, 1 }, - { 57, 17, 5, 71, 102, 57, 53, 41, 49 }, - { 115, 21, 2, 10, 102, 255, 166, 23, 6 }, - { 38, 33, 13, 121, 57, 73, 26, 1, 85 }, - { 41, 10, 67, 138, 77, 110, 90, 47, 114 }, - { 101, 29, 16, 10, 85, 128, 101, 196, 26 }, - { 57, 18, 10, 102, 102, 213, 34, 20, 43 }, - { 117, 20, 15, 36, 163, 128, 68, 1, 26 } }, - { { 138, 31, 36, 171, 27, 166, 38, 44, 229 }, - { 67, 87, 58, 169, 82, 115, 26, 59, 179 }, - { 63, 59, 90, 180, 59, 166, 93, 73, 154 }, - { 40, 40, 21, 116, 143, 209, 34, 39, 175 }, - { 57, 46, 22, 24, 128, 1, 54, 17, 37 }, - { 47, 15, 16, 183, 34, 223, 49, 45, 183 }, - { 46, 17, 33, 183, 6, 98, 15, 32, 183 }, - { 65, 32, 73, 115, 28, 128, 23, 128, 205 }, - { 40, 3, 9, 115, 51, 192, 18, 6, 223 }, - { 87, 37, 9, 115, 59, 77, 64, 21, 47 } }, - { { 104, 55, 44, 218, 9, 54, 53, 130, 226 }, - { 64, 90, 70, 205, 40, 41, 23, 26, 57 }, - { 54, 57, 112, 184, 5, 41, 38, 166, 213 }, - { 30, 34, 26, 133, 152, 116, 10, 32, 134 }, - { 75, 32, 12, 51, 192, 255, 160, 43, 51 }, - { 39, 19, 53, 221, 26, 114, 32, 73, 255 }, - { 31, 9, 65, 234, 2, 15, 1, 118, 73 }, - { 88, 31, 35, 67, 102, 85, 55, 186, 85 }, - { 56, 21, 23, 111, 59, 205, 45, 37, 192 }, - { 55, 38, 70, 124, 73, 102, 1, 34, 98 } }, - { { 102, 61, 71, 37, 34, 53, 31, 243, 192 }, - { 69, 60, 71, 38, 73, 119, 28, 222, 37 }, - { 68, 45, 128, 34, 1, 47, 11, 245, 171 }, - { 62, 17, 19, 70, 146, 85, 55, 62, 70 }, - { 75, 15, 9, 9, 64, 255, 184, 119, 16 }, - { 37, 43, 37, 154, 100, 163, 85, 160, 1 }, - { 63, 9, 92, 136, 28, 64, 32, 201, 85 }, - { 86, 6, 28, 5, 64, 255, 25, 248, 1 }, - { 56, 8, 17, 132, 137, 255, 55, 116, 128 }, - { 58, 15, 20, 82, 135, 57, 26, 121, 40 } }, - { { 164, 50, 31, 137, 154, 133, 25, 35, 218 }, - { 51, 103, 44, 131, 131, 123, 31, 6, 158 }, - { 86, 40, 64, 135, 148, 224, 45, 183, 128 }, - { 22, 26, 17, 131, 240, 154, 14, 1, 209 }, - { 83, 12, 13, 54, 192, 255, 68, 47, 28 }, - { 45, 16, 21, 91, 64, 222, 7, 1, 197 }, - { 56, 21, 39, 155, 60, 138, 23, 102, 213 }, - { 85, 26, 85, 85, 128, 128, 32, 146, 171 }, - { 18, 11, 7, 63, 144, 171, 4, 4, 246 }, - { 35, 27, 10, 146, 174, 171, 12, 26, 128 } }, - { { 190, 80, 35, 99, 180, 80, 126, 54, 45 }, - { 85, 126, 47, 87, 176, 51, 41, 20, 32 }, - { 101, 75, 128, 139, 118, 146, 116, 128, 85 }, - { 56, 41, 15, 176, 236, 85, 37, 9, 62 }, - { 146, 36, 19, 30, 171, 255, 97, 27, 20 }, - { 71, 30, 17, 119, 118, 255, 17, 18, 138 }, - { 101, 38, 60, 138, 55, 70, 43, 26, 142 }, - { 138, 45, 61, 62, 219, 1, 81, 188, 64 }, - { 32, 41, 20, 117, 151, 142, 20, 21, 163 }, - { 112, 19, 12, 61, 195, 128, 48, 4, 24 } } - }; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_VP8_ENTROPYMODEDATA_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/vp8_loopfilter.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/vp8_loopfilter.c deleted file mode 100644 index 4576c185..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/vp8_loopfilter.c +++ /dev/null @@ -1,566 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "vp8_rtcd.h" -#include "loopfilter.h" -#include "onyxc_int.h" -#include "vpx_mem/vpx_mem.h" - -static void lf_init_lut(loop_filter_info_n *lfi) { - int filt_lvl; - - for (filt_lvl = 0; filt_lvl <= MAX_LOOP_FILTER; ++filt_lvl) { - if (filt_lvl >= 40) { - lfi->hev_thr_lut[KEY_FRAME][filt_lvl] = 2; - lfi->hev_thr_lut[INTER_FRAME][filt_lvl] = 3; - } else if (filt_lvl >= 20) { - lfi->hev_thr_lut[KEY_FRAME][filt_lvl] = 1; - lfi->hev_thr_lut[INTER_FRAME][filt_lvl] = 2; - } else if (filt_lvl >= 15) { - lfi->hev_thr_lut[KEY_FRAME][filt_lvl] = 1; - lfi->hev_thr_lut[INTER_FRAME][filt_lvl] = 1; - } else { - lfi->hev_thr_lut[KEY_FRAME][filt_lvl] = 0; - lfi->hev_thr_lut[INTER_FRAME][filt_lvl] = 0; - } - } - - lfi->mode_lf_lut[DC_PRED] = 1; - lfi->mode_lf_lut[V_PRED] = 1; - lfi->mode_lf_lut[H_PRED] = 1; - lfi->mode_lf_lut[TM_PRED] = 1; - lfi->mode_lf_lut[B_PRED] = 0; - - lfi->mode_lf_lut[ZEROMV] = 1; - lfi->mode_lf_lut[NEARESTMV] = 2; - lfi->mode_lf_lut[NEARMV] = 2; - lfi->mode_lf_lut[NEWMV] = 2; - lfi->mode_lf_lut[SPLITMV] = 3; -} - -void vp8_loop_filter_update_sharpness(loop_filter_info_n *lfi, - int sharpness_lvl) { - int i; - - /* For each possible value for the loop filter fill out limits */ - for (i = 0; i <= MAX_LOOP_FILTER; ++i) { - int filt_lvl = i; - int block_inside_limit = 0; - - /* Set loop filter paramaeters that control sharpness. */ - block_inside_limit = filt_lvl >> (sharpness_lvl > 0); - block_inside_limit = block_inside_limit >> (sharpness_lvl > 4); - - if (sharpness_lvl > 0) { - if (block_inside_limit > (9 - sharpness_lvl)) { - block_inside_limit = (9 - sharpness_lvl); - } - } - - if (block_inside_limit < 1) block_inside_limit = 1; - - memset(lfi->lim[i], block_inside_limit, SIMD_WIDTH); - memset(lfi->blim[i], (2 * filt_lvl + block_inside_limit), SIMD_WIDTH); - memset(lfi->mblim[i], (2 * (filt_lvl + 2) + block_inside_limit), - SIMD_WIDTH); - } -} - -void vp8_loop_filter_init(VP8_COMMON *cm) { - loop_filter_info_n *lfi = &cm->lf_info; - int i; - - /* init limits for given sharpness*/ - vp8_loop_filter_update_sharpness(lfi, cm->sharpness_level); - cm->last_sharpness_level = cm->sharpness_level; - - /* init LUT for lvl and hev thr picking */ - lf_init_lut(lfi); - - /* init hev threshold const vectors */ - for (i = 0; i < 4; ++i) { - memset(lfi->hev_thr[i], i, SIMD_WIDTH); - } -} - -void vp8_loop_filter_frame_init(VP8_COMMON *cm, MACROBLOCKD *mbd, - int default_filt_lvl) { - int seg, /* segment number */ - ref, /* index in ref_lf_deltas */ - mode; /* index in mode_lf_deltas */ - - loop_filter_info_n *lfi = &cm->lf_info; - - /* update limits if sharpness has changed */ - if (cm->last_sharpness_level != cm->sharpness_level) { - vp8_loop_filter_update_sharpness(lfi, cm->sharpness_level); - cm->last_sharpness_level = cm->sharpness_level; - } - - for (seg = 0; seg < MAX_MB_SEGMENTS; ++seg) { - int lvl_seg = default_filt_lvl; - int lvl_ref, lvl_mode; - - /* Note the baseline filter values for each segment */ - if (mbd->segmentation_enabled) { - if (mbd->mb_segment_abs_delta == SEGMENT_ABSDATA) { - lvl_seg = mbd->segment_feature_data[MB_LVL_ALT_LF][seg]; - } else { /* Delta Value */ - lvl_seg += mbd->segment_feature_data[MB_LVL_ALT_LF][seg]; - } - lvl_seg = (lvl_seg > 0) ? ((lvl_seg > 63) ? 63 : lvl_seg) : 0; - } - - if (!mbd->mode_ref_lf_delta_enabled) { - /* we could get rid of this if we assume that deltas are set to - * zero when not in use; encoder always uses deltas - */ - memset(lfi->lvl[seg][0], lvl_seg, 4 * 4); - continue; - } - - /* INTRA_FRAME */ - ref = INTRA_FRAME; - - /* Apply delta for reference frame */ - lvl_ref = lvl_seg + mbd->ref_lf_deltas[ref]; - - /* Apply delta for Intra modes */ - mode = 0; /* B_PRED */ - /* Only the split mode BPRED has a further special case */ - lvl_mode = lvl_ref + mbd->mode_lf_deltas[mode]; - /* clamp */ - lvl_mode = (lvl_mode > 0) ? (lvl_mode > 63 ? 63 : lvl_mode) : 0; - - lfi->lvl[seg][ref][mode] = lvl_mode; - - mode = 1; /* all the rest of Intra modes */ - /* clamp */ - lvl_mode = (lvl_ref > 0) ? (lvl_ref > 63 ? 63 : lvl_ref) : 0; - lfi->lvl[seg][ref][mode] = lvl_mode; - - /* LAST, GOLDEN, ALT */ - for (ref = 1; ref < MAX_REF_FRAMES; ++ref) { - /* Apply delta for reference frame */ - lvl_ref = lvl_seg + mbd->ref_lf_deltas[ref]; - - /* Apply delta for Inter modes */ - for (mode = 1; mode < 4; ++mode) { - lvl_mode = lvl_ref + mbd->mode_lf_deltas[mode]; - /* clamp */ - lvl_mode = (lvl_mode > 0) ? (lvl_mode > 63 ? 63 : lvl_mode) : 0; - - lfi->lvl[seg][ref][mode] = lvl_mode; - } - } - } -} - -void vp8_loop_filter_row_normal(VP8_COMMON *cm, MODE_INFO *mode_info_context, - int mb_row, int post_ystride, int post_uvstride, - unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr) { - int mb_col; - int filter_level; - loop_filter_info_n *lfi_n = &cm->lf_info; - loop_filter_info lfi; - FRAME_TYPE frame_type = cm->frame_type; - - for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) { - int skip_lf = (mode_info_context->mbmi.mode != B_PRED && - mode_info_context->mbmi.mode != SPLITMV && - mode_info_context->mbmi.mb_skip_coeff); - - const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode]; - const int seg = mode_info_context->mbmi.segment_id; - const int ref_frame = mode_info_context->mbmi.ref_frame; - - filter_level = lfi_n->lvl[seg][ref_frame][mode_index]; - - if (filter_level) { - const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level]; - lfi.mblim = lfi_n->mblim[filter_level]; - lfi.blim = lfi_n->blim[filter_level]; - lfi.lim = lfi_n->lim[filter_level]; - lfi.hev_thr = lfi_n->hev_thr[hev_index]; - - if (mb_col > 0) - vp8_loop_filter_mbv(y_ptr, u_ptr, v_ptr, post_ystride, post_uvstride, - &lfi); - - if (!skip_lf) - vp8_loop_filter_bv(y_ptr, u_ptr, v_ptr, post_ystride, post_uvstride, - &lfi); - - /* don't apply across umv border */ - if (mb_row > 0) - vp8_loop_filter_mbh(y_ptr, u_ptr, v_ptr, post_ystride, post_uvstride, - &lfi); - - if (!skip_lf) - vp8_loop_filter_bh(y_ptr, u_ptr, v_ptr, post_ystride, post_uvstride, - &lfi); - } - - y_ptr += 16; - u_ptr += 8; - v_ptr += 8; - - mode_info_context++; /* step to next MB */ - } -} - -void vp8_loop_filter_row_simple(VP8_COMMON *cm, MODE_INFO *mode_info_context, - int mb_row, int post_ystride, - unsigned char *y_ptr) { - int mb_col; - int filter_level; - loop_filter_info_n *lfi_n = &cm->lf_info; - - for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) { - int skip_lf = (mode_info_context->mbmi.mode != B_PRED && - mode_info_context->mbmi.mode != SPLITMV && - mode_info_context->mbmi.mb_skip_coeff); - - const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode]; - const int seg = mode_info_context->mbmi.segment_id; - const int ref_frame = mode_info_context->mbmi.ref_frame; - - filter_level = lfi_n->lvl[seg][ref_frame][mode_index]; - - if (filter_level) { - if (mb_col > 0) - vp8_loop_filter_simple_mbv(y_ptr, post_ystride, - lfi_n->mblim[filter_level]); - - if (!skip_lf) - vp8_loop_filter_simple_bv(y_ptr, post_ystride, - lfi_n->blim[filter_level]); - - /* don't apply across umv border */ - if (mb_row > 0) - vp8_loop_filter_simple_mbh(y_ptr, post_ystride, - lfi_n->mblim[filter_level]); - - if (!skip_lf) - vp8_loop_filter_simple_bh(y_ptr, post_ystride, - lfi_n->blim[filter_level]); - } - - y_ptr += 16; - - mode_info_context++; /* step to next MB */ - } -} -void vp8_loop_filter_frame(VP8_COMMON *cm, MACROBLOCKD *mbd, int frame_type) { - YV12_BUFFER_CONFIG *post = cm->frame_to_show; - loop_filter_info_n *lfi_n = &cm->lf_info; - loop_filter_info lfi; - - int mb_row; - int mb_col; - int mb_rows = cm->mb_rows; - int mb_cols = cm->mb_cols; - - int filter_level; - - unsigned char *y_ptr, *u_ptr, *v_ptr; - - /* Point at base of Mb MODE_INFO list */ - const MODE_INFO *mode_info_context = cm->mi; - int post_y_stride = post->y_stride; - int post_uv_stride = post->uv_stride; - - /* Initialize the loop filter for this frame. */ - vp8_loop_filter_frame_init(cm, mbd, cm->filter_level); - - /* Set up the buffer pointers */ - y_ptr = post->y_buffer; - u_ptr = post->u_buffer; - v_ptr = post->v_buffer; - - /* vp8_filter each macro block */ - if (cm->filter_type == NORMAL_LOOPFILTER) { - for (mb_row = 0; mb_row < mb_rows; ++mb_row) { - for (mb_col = 0; mb_col < mb_cols; ++mb_col) { - int skip_lf = (mode_info_context->mbmi.mode != B_PRED && - mode_info_context->mbmi.mode != SPLITMV && - mode_info_context->mbmi.mb_skip_coeff); - - const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode]; - const int seg = mode_info_context->mbmi.segment_id; - const int ref_frame = mode_info_context->mbmi.ref_frame; - - filter_level = lfi_n->lvl[seg][ref_frame][mode_index]; - - if (filter_level) { - const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level]; - lfi.mblim = lfi_n->mblim[filter_level]; - lfi.blim = lfi_n->blim[filter_level]; - lfi.lim = lfi_n->lim[filter_level]; - lfi.hev_thr = lfi_n->hev_thr[hev_index]; - - if (mb_col > 0) - vp8_loop_filter_mbv(y_ptr, u_ptr, v_ptr, post_y_stride, - post_uv_stride, &lfi); - - if (!skip_lf) - vp8_loop_filter_bv(y_ptr, u_ptr, v_ptr, post_y_stride, - post_uv_stride, &lfi); - - /* don't apply across umv border */ - if (mb_row > 0) - vp8_loop_filter_mbh(y_ptr, u_ptr, v_ptr, post_y_stride, - post_uv_stride, &lfi); - - if (!skip_lf) - vp8_loop_filter_bh(y_ptr, u_ptr, v_ptr, post_y_stride, - post_uv_stride, &lfi); - } - - y_ptr += 16; - u_ptr += 8; - v_ptr += 8; - - mode_info_context++; /* step to next MB */ - } - y_ptr += post_y_stride * 16 - post->y_width; - u_ptr += post_uv_stride * 8 - post->uv_width; - v_ptr += post_uv_stride * 8 - post->uv_width; - - mode_info_context++; /* Skip border mb */ - } - } else { /* SIMPLE_LOOPFILTER */ - for (mb_row = 0; mb_row < mb_rows; ++mb_row) { - for (mb_col = 0; mb_col < mb_cols; ++mb_col) { - int skip_lf = (mode_info_context->mbmi.mode != B_PRED && - mode_info_context->mbmi.mode != SPLITMV && - mode_info_context->mbmi.mb_skip_coeff); - - const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode]; - const int seg = mode_info_context->mbmi.segment_id; - const int ref_frame = mode_info_context->mbmi.ref_frame; - - filter_level = lfi_n->lvl[seg][ref_frame][mode_index]; - if (filter_level) { - const unsigned char *mblim = lfi_n->mblim[filter_level]; - const unsigned char *blim = lfi_n->blim[filter_level]; - - if (mb_col > 0) - vp8_loop_filter_simple_mbv(y_ptr, post_y_stride, mblim); - - if (!skip_lf) vp8_loop_filter_simple_bv(y_ptr, post_y_stride, blim); - - /* don't apply across umv border */ - if (mb_row > 0) - vp8_loop_filter_simple_mbh(y_ptr, post_y_stride, mblim); - - if (!skip_lf) vp8_loop_filter_simple_bh(y_ptr, post_y_stride, blim); - } - - y_ptr += 16; - u_ptr += 8; - v_ptr += 8; - - mode_info_context++; /* step to next MB */ - } - y_ptr += post_y_stride * 16 - post->y_width; - u_ptr += post_uv_stride * 8 - post->uv_width; - v_ptr += post_uv_stride * 8 - post->uv_width; - - mode_info_context++; /* Skip border mb */ - } - } -} - -void vp8_loop_filter_frame_yonly(VP8_COMMON *cm, MACROBLOCKD *mbd, - int default_filt_lvl) { - YV12_BUFFER_CONFIG *post = cm->frame_to_show; - - unsigned char *y_ptr; - int mb_row; - int mb_col; - - loop_filter_info_n *lfi_n = &cm->lf_info; - loop_filter_info lfi; - - int filter_level; - FRAME_TYPE frame_type = cm->frame_type; - - /* Point at base of Mb MODE_INFO list */ - const MODE_INFO *mode_info_context = cm->mi; - -#if 0 - if(default_filt_lvl == 0) /* no filter applied */ - return; -#endif - - /* Initialize the loop filter for this frame. */ - vp8_loop_filter_frame_init(cm, mbd, default_filt_lvl); - - /* Set up the buffer pointers */ - y_ptr = post->y_buffer; - - /* vp8_filter each macro block */ - for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) { - for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) { - int skip_lf = (mode_info_context->mbmi.mode != B_PRED && - mode_info_context->mbmi.mode != SPLITMV && - mode_info_context->mbmi.mb_skip_coeff); - - const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode]; - const int seg = mode_info_context->mbmi.segment_id; - const int ref_frame = mode_info_context->mbmi.ref_frame; - - filter_level = lfi_n->lvl[seg][ref_frame][mode_index]; - - if (filter_level) { - if (cm->filter_type == NORMAL_LOOPFILTER) { - const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level]; - lfi.mblim = lfi_n->mblim[filter_level]; - lfi.blim = lfi_n->blim[filter_level]; - lfi.lim = lfi_n->lim[filter_level]; - lfi.hev_thr = lfi_n->hev_thr[hev_index]; - - if (mb_col > 0) - vp8_loop_filter_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi); - - if (!skip_lf) - vp8_loop_filter_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi); - - /* don't apply across umv border */ - if (mb_row > 0) - vp8_loop_filter_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi); - - if (!skip_lf) - vp8_loop_filter_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi); - } else { - if (mb_col > 0) - vp8_loop_filter_simple_mbv(y_ptr, post->y_stride, - lfi_n->mblim[filter_level]); - - if (!skip_lf) - vp8_loop_filter_simple_bv(y_ptr, post->y_stride, - lfi_n->blim[filter_level]); - - /* don't apply across umv border */ - if (mb_row > 0) - vp8_loop_filter_simple_mbh(y_ptr, post->y_stride, - lfi_n->mblim[filter_level]); - - if (!skip_lf) - vp8_loop_filter_simple_bh(y_ptr, post->y_stride, - lfi_n->blim[filter_level]); - } - } - - y_ptr += 16; - mode_info_context++; /* step to next MB */ - } - - y_ptr += post->y_stride * 16 - post->y_width; - mode_info_context++; /* Skip border mb */ - } -} - -void vp8_loop_filter_partial_frame(VP8_COMMON *cm, MACROBLOCKD *mbd, - int default_filt_lvl) { - YV12_BUFFER_CONFIG *post = cm->frame_to_show; - - unsigned char *y_ptr; - int mb_row; - int mb_col; - int mb_cols = post->y_width >> 4; - int mb_rows = post->y_height >> 4; - - int linestocopy; - - loop_filter_info_n *lfi_n = &cm->lf_info; - loop_filter_info lfi; - - int filter_level; - FRAME_TYPE frame_type = cm->frame_type; - - const MODE_INFO *mode_info_context; - -#if 0 - if(default_filt_lvl == 0) /* no filter applied */ - return; -#endif - - /* Initialize the loop filter for this frame. */ - vp8_loop_filter_frame_init(cm, mbd, default_filt_lvl); - - /* number of MB rows to use in partial filtering */ - linestocopy = mb_rows / PARTIAL_FRAME_FRACTION; - linestocopy = linestocopy ? linestocopy << 4 : 16; /* 16 lines per MB */ - - /* Set up the buffer pointers; partial image starts at ~middle of frame */ - y_ptr = post->y_buffer + ((post->y_height >> 5) * 16) * post->y_stride; - mode_info_context = cm->mi + (post->y_height >> 5) * (mb_cols + 1); - - /* vp8_filter each macro block */ - for (mb_row = 0; mb_row < (linestocopy >> 4); ++mb_row) { - for (mb_col = 0; mb_col < mb_cols; ++mb_col) { - int skip_lf = (mode_info_context->mbmi.mode != B_PRED && - mode_info_context->mbmi.mode != SPLITMV && - mode_info_context->mbmi.mb_skip_coeff); - - const int mode_index = lfi_n->mode_lf_lut[mode_info_context->mbmi.mode]; - const int seg = mode_info_context->mbmi.segment_id; - const int ref_frame = mode_info_context->mbmi.ref_frame; - - filter_level = lfi_n->lvl[seg][ref_frame][mode_index]; - - if (filter_level) { - if (cm->filter_type == NORMAL_LOOPFILTER) { - const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level]; - lfi.mblim = lfi_n->mblim[filter_level]; - lfi.blim = lfi_n->blim[filter_level]; - lfi.lim = lfi_n->lim[filter_level]; - lfi.hev_thr = lfi_n->hev_thr[hev_index]; - - if (mb_col > 0) - vp8_loop_filter_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi); - - if (!skip_lf) - vp8_loop_filter_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi); - - vp8_loop_filter_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi); - - if (!skip_lf) - vp8_loop_filter_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi); - } else { - if (mb_col > 0) - vp8_loop_filter_simple_mbv(y_ptr, post->y_stride, - lfi_n->mblim[filter_level]); - - if (!skip_lf) - vp8_loop_filter_simple_bv(y_ptr, post->y_stride, - lfi_n->blim[filter_level]); - - vp8_loop_filter_simple_mbh(y_ptr, post->y_stride, - lfi_n->mblim[filter_level]); - - if (!skip_lf) - vp8_loop_filter_simple_bh(y_ptr, post->y_stride, - lfi_n->blim[filter_level]); - } - } - - y_ptr += 16; - mode_info_context += 1; /* step to next MB */ - } - - y_ptr += post->y_stride * 16 - post->y_width; - mode_info_context += 1; /* Skip border mb */ - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/vp8_skin_detection.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/vp8_skin_detection.c deleted file mode 100644 index 6739efa5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/vp8_skin_detection.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp8/common/alloccommon.h" -#include "vp8/common/vp8_skin_detection.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_util/vpx_write_yuv_frame.h" - -static int avg_2x2(const uint8_t *s, int p) { - int i, j; - int sum = 0; - for (i = 0; i < 2; ++i, s += p) { - for (j = 0; j < 2; ++j) { - sum += s[j]; - } - } - return (sum + 2) >> 2; -} - -int vp8_compute_skin_block(const uint8_t *y, const uint8_t *u, const uint8_t *v, - int stride, int strideuv, - SKIN_DETECTION_BLOCK_SIZE bsize, int consec_zeromv, - int curr_motion_magn) { - // No skin if block has been zero/small motion for long consecutive time. - if (consec_zeromv > 60 && curr_motion_magn == 0) { - return 0; - } else { - int motion = 1; - if (consec_zeromv > 25 && curr_motion_magn == 0) motion = 0; - if (bsize == SKIN_16X16) { - // Take the average of center 2x2 pixels. - const int ysource = avg_2x2(y + 7 * stride + 7, stride); - const int usource = avg_2x2(u + 3 * strideuv + 3, strideuv); - const int vsource = avg_2x2(v + 3 * strideuv + 3, strideuv); - return vpx_skin_pixel(ysource, usource, vsource, motion); - } else { - int num_skin = 0; - int i, j; - for (i = 0; i < 2; i++) { - for (j = 0; j < 2; j++) { - // Take the average of center 2x2 pixels. - const int ysource = avg_2x2(y + 3 * stride + 3, stride); - const int usource = avg_2x2(u + strideuv + 1, strideuv); - const int vsource = avg_2x2(v + strideuv + 1, strideuv); - num_skin += vpx_skin_pixel(ysource, usource, vsource, motion); - if (num_skin >= 2) return 1; - y += 8; - u += 4; - v += 4; - } - y += (stride << 3) - 16; - u += (strideuv << 2) - 8; - v += (strideuv << 2) - 8; - } - - return 0; - } - } -} - -#ifdef OUTPUT_YUV_SKINMAP -// For viewing skin map on input source. -void vp8_compute_skin_map(VP8_COMP *const cpi, FILE *yuv_skinmap_file) { - int i, j, mb_row, mb_col, num_bl; - VP8_COMMON *const cm = &cpi->common; - uint8_t *y; - const uint8_t *src_y = cpi->Source->y_buffer; - const int src_ystride = cpi->Source->y_stride; - int offset = 0; - - YV12_BUFFER_CONFIG skinmap; - memset(&skinmap, 0, sizeof(skinmap)); - if (vp8_yv12_alloc_frame_buffer(&skinmap, cm->Width, cm->Height, - VP8BORDERINPIXELS) < 0) { - vpx_free_frame_buffer(&skinmap); - return; - } - memset(skinmap.buffer_alloc, 128, skinmap.frame_size); - y = skinmap.y_buffer; - // Loop through blocks and set skin map based on center pixel of block. - // Set y to white for skin block, otherwise set to source with gray scale. - for (mb_row = 0; mb_row < cm->mb_rows; mb_row += 1) { - num_bl = 0; - for (mb_col = 0; mb_col < cm->mb_cols; mb_col += 1) { - const int is_skin = cpi->skin_map[offset++]; - for (i = 0; i < 16; i++) { - for (j = 0; j < 16; j++) { - y[i * src_ystride + j] = is_skin ? 255 : src_y[i * src_ystride + j]; - } - } - num_bl++; - y += 16; - src_y += 16; - } - y += (src_ystride << 4) - (num_bl << 4); - src_y += (src_ystride << 4) - (num_bl << 4); - } - vpx_write_yuv_frame(yuv_skinmap_file, &skinmap); - vpx_free_frame_buffer(&skinmap); -} -#endif // OUTPUT_YUV_SKINMAP diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/vp8_skin_detection.h b/presentation/src/main/cpp/third_party/libvpx/vp8/common/vp8_skin_detection.h deleted file mode 100644 index ef0e4ae4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/vp8_skin_detection.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_COMMON_VP8_SKIN_DETECTION_H_ -#define VPX_VP8_COMMON_VP8_SKIN_DETECTION_H_ - -#include "vp8/encoder/onyx_int.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/skin_detection.h" -#include "vpx_scale/yv12config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct VP8_COMP; - -typedef enum { - // Skin detection based on 8x8 block. If two of them are identified as skin, - // the macroblock is marked as skin. - SKIN_8X8, - // Skin detection based on 16x16 block. - SKIN_16X16 -} SKIN_DETECTION_BLOCK_SIZE; - -int vp8_compute_skin_block(const uint8_t *y, const uint8_t *u, const uint8_t *v, - int stride, int strideuv, - SKIN_DETECTION_BLOCK_SIZE bsize, int consec_zeromv, - int curr_motion_magn); - -#ifdef OUTPUT_YUV_SKINMAP -// For viewing skin map on input source. -void vp8_compute_skin_map(struct VP8_COMP *const cpi, FILE *yuv_skinmap_file); -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_COMMON_VP8_SKIN_DETECTION_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/bilinear_filter_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/bilinear_filter_sse2.c deleted file mode 100644 index ff6cbbd6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/bilinear_filter_sse2.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vp8_rtcd.h" -#include "./vpx_config.h" -#include "vp8/common/filter.h" -#include "vpx_dsp/x86/mem_sse2.h" -#include "vpx_ports/mem.h" - -static INLINE void horizontal_16x16(uint8_t *src, const int stride, - uint16_t *dst, const int xoffset) { - int h; - const __m128i zero = _mm_setzero_si128(); - - if (xoffset == 0) { - for (h = 0; h < 17; ++h) { - const __m128i a = _mm_loadu_si128((__m128i *)src); - const __m128i a_lo = _mm_unpacklo_epi8(a, zero); - const __m128i a_hi = _mm_unpackhi_epi8(a, zero); - _mm_store_si128((__m128i *)dst, a_lo); - _mm_store_si128((__m128i *)(dst + 8), a_hi); - src += stride; - dst += 16; - } - return; - } - - { - const __m128i round_factor = _mm_set1_epi16(1 << (VP8_FILTER_SHIFT - 1)); - const __m128i hfilter_0 = _mm_set1_epi16(vp8_bilinear_filters[xoffset][0]); - const __m128i hfilter_1 = _mm_set1_epi16(vp8_bilinear_filters[xoffset][1]); - - for (h = 0; h < 17; ++h) { - const __m128i a = _mm_loadu_si128((__m128i *)src); - const __m128i a_lo = _mm_unpacklo_epi8(a, zero); - const __m128i a_hi = _mm_unpackhi_epi8(a, zero); - const __m128i a_lo_filtered = _mm_mullo_epi16(a_lo, hfilter_0); - const __m128i a_hi_filtered = _mm_mullo_epi16(a_hi, hfilter_0); - - const __m128i b = _mm_loadu_si128((__m128i *)(src + 1)); - const __m128i b_lo = _mm_unpacklo_epi8(b, zero); - const __m128i b_hi = _mm_unpackhi_epi8(b, zero); - const __m128i b_lo_filtered = _mm_mullo_epi16(b_lo, hfilter_1); - const __m128i b_hi_filtered = _mm_mullo_epi16(b_hi, hfilter_1); - - const __m128i sum_lo = _mm_add_epi16(a_lo_filtered, b_lo_filtered); - const __m128i sum_hi = _mm_add_epi16(a_hi_filtered, b_hi_filtered); - - const __m128i compensated_lo = _mm_add_epi16(sum_lo, round_factor); - const __m128i compensated_hi = _mm_add_epi16(sum_hi, round_factor); - - const __m128i shifted_lo = - _mm_srai_epi16(compensated_lo, VP8_FILTER_SHIFT); - const __m128i shifted_hi = - _mm_srai_epi16(compensated_hi, VP8_FILTER_SHIFT); - - _mm_store_si128((__m128i *)dst, shifted_lo); - _mm_store_si128((__m128i *)(dst + 8), shifted_hi); - src += stride; - dst += 16; - } - } -} - -static INLINE void vertical_16x16(uint16_t *src, uint8_t *dst, const int stride, - const int yoffset) { - int h; - - if (yoffset == 0) { - for (h = 0; h < 16; ++h) { - const __m128i row_lo = _mm_load_si128((__m128i *)src); - const __m128i row_hi = _mm_load_si128((__m128i *)(src + 8)); - const __m128i packed = _mm_packus_epi16(row_lo, row_hi); - _mm_store_si128((__m128i *)dst, packed); - src += 16; - dst += stride; - } - return; - } - - { - const __m128i round_factor = _mm_set1_epi16(1 << (VP8_FILTER_SHIFT - 1)); - const __m128i vfilter_0 = _mm_set1_epi16(vp8_bilinear_filters[yoffset][0]); - const __m128i vfilter_1 = _mm_set1_epi16(vp8_bilinear_filters[yoffset][1]); - - __m128i row_0_lo = _mm_load_si128((__m128i *)src); - __m128i row_0_hi = _mm_load_si128((__m128i *)(src + 8)); - src += 16; - for (h = 0; h < 16; ++h) { - const __m128i row_0_lo_filtered = _mm_mullo_epi16(row_0_lo, vfilter_0); - const __m128i row_0_hi_filtered = _mm_mullo_epi16(row_0_hi, vfilter_0); - - const __m128i row_1_lo = _mm_load_si128((__m128i *)src); - const __m128i row_1_hi = _mm_load_si128((__m128i *)(src + 8)); - const __m128i row_1_lo_filtered = _mm_mullo_epi16(row_1_lo, vfilter_1); - const __m128i row_1_hi_filtered = _mm_mullo_epi16(row_1_hi, vfilter_1); - - const __m128i sum_lo = - _mm_add_epi16(row_0_lo_filtered, row_1_lo_filtered); - const __m128i sum_hi = - _mm_add_epi16(row_0_hi_filtered, row_1_hi_filtered); - - const __m128i compensated_lo = _mm_add_epi16(sum_lo, round_factor); - const __m128i compensated_hi = _mm_add_epi16(sum_hi, round_factor); - - const __m128i shifted_lo = - _mm_srai_epi16(compensated_lo, VP8_FILTER_SHIFT); - const __m128i shifted_hi = - _mm_srai_epi16(compensated_hi, VP8_FILTER_SHIFT); - - const __m128i packed = _mm_packus_epi16(shifted_lo, shifted_hi); - _mm_store_si128((__m128i *)dst, packed); - row_0_lo = row_1_lo; - row_0_hi = row_1_hi; - src += 16; - dst += stride; - } - } -} - -void vp8_bilinear_predict16x16_sse2(uint8_t *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, uint8_t *dst_ptr, - int dst_pitch) { - DECLARE_ALIGNED(16, uint16_t, FData[16 * 17]); - - assert((xoffset | yoffset) != 0); - - horizontal_16x16(src_ptr, src_pixels_per_line, FData, xoffset); - - vertical_16x16(FData, dst_ptr, dst_pitch, yoffset); -} - -static INLINE void horizontal_8xN(uint8_t *src, const int stride, uint16_t *dst, - const int xoffset, const int height) { - int h; - const __m128i zero = _mm_setzero_si128(); - - if (xoffset == 0) { - for (h = 0; h < height; ++h) { - const __m128i a = _mm_loadl_epi64((__m128i *)src); - const __m128i a_u16 = _mm_unpacklo_epi8(a, zero); - _mm_store_si128((__m128i *)dst, a_u16); - src += stride; - dst += 8; - } - return; - } - - { - const __m128i round_factor = _mm_set1_epi16(1 << (VP8_FILTER_SHIFT - 1)); - const __m128i hfilter_0 = _mm_set1_epi16(vp8_bilinear_filters[xoffset][0]); - const __m128i hfilter_1 = _mm_set1_epi16(vp8_bilinear_filters[xoffset][1]); - - // Filter horizontally. Rather than load the whole array and transpose, load - // 16 values (overreading) and shift to set up the second value. Do an - // "extra" 9th line so the vertical pass has the necessary context. - for (h = 0; h < height; ++h) { - const __m128i a = _mm_loadu_si128((__m128i *)src); - const __m128i b = _mm_srli_si128(a, 1); - const __m128i a_u16 = _mm_unpacklo_epi8(a, zero); - const __m128i b_u16 = _mm_unpacklo_epi8(b, zero); - const __m128i a_filtered = _mm_mullo_epi16(a_u16, hfilter_0); - const __m128i b_filtered = _mm_mullo_epi16(b_u16, hfilter_1); - const __m128i sum = _mm_add_epi16(a_filtered, b_filtered); - const __m128i compensated = _mm_add_epi16(sum, round_factor); - const __m128i shifted = _mm_srai_epi16(compensated, VP8_FILTER_SHIFT); - _mm_store_si128((__m128i *)dst, shifted); - src += stride; - dst += 8; - } - } -} - -static INLINE void vertical_8xN(uint16_t *src, uint8_t *dst, const int stride, - const int yoffset, const int height) { - int h; - - if (yoffset == 0) { - for (h = 0; h < height; ++h) { - const __m128i row = _mm_load_si128((__m128i *)src); - const __m128i packed = _mm_packus_epi16(row, row); - _mm_storel_epi64((__m128i *)dst, packed); - src += 8; - dst += stride; - } - return; - } - - { - const __m128i round_factor = _mm_set1_epi16(1 << (VP8_FILTER_SHIFT - 1)); - const __m128i vfilter_0 = _mm_set1_epi16(vp8_bilinear_filters[yoffset][0]); - const __m128i vfilter_1 = _mm_set1_epi16(vp8_bilinear_filters[yoffset][1]); - - __m128i row_0 = _mm_load_si128((__m128i *)src); - src += 8; - for (h = 0; h < height; ++h) { - const __m128i row_1 = _mm_load_si128((__m128i *)src); - const __m128i row_0_filtered = _mm_mullo_epi16(row_0, vfilter_0); - const __m128i row_1_filtered = _mm_mullo_epi16(row_1, vfilter_1); - const __m128i sum = _mm_add_epi16(row_0_filtered, row_1_filtered); - const __m128i compensated = _mm_add_epi16(sum, round_factor); - const __m128i shifted = _mm_srai_epi16(compensated, VP8_FILTER_SHIFT); - const __m128i packed = _mm_packus_epi16(shifted, shifted); - _mm_storel_epi64((__m128i *)dst, packed); - row_0 = row_1; - src += 8; - dst += stride; - } - } -} - -void vp8_bilinear_predict8x8_sse2(uint8_t *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, uint8_t *dst_ptr, - int dst_pitch) { - DECLARE_ALIGNED(16, uint16_t, FData[8 * 9]); - - assert((xoffset | yoffset) != 0); - - horizontal_8xN(src_ptr, src_pixels_per_line, FData, xoffset, 9); - - vertical_8xN(FData, dst_ptr, dst_pitch, yoffset, 8); -} - -void vp8_bilinear_predict8x4_sse2(uint8_t *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, uint8_t *dst_ptr, - int dst_pitch) { - DECLARE_ALIGNED(16, uint16_t, FData[8 * 5]); - - assert((xoffset | yoffset) != 0); - - horizontal_8xN(src_ptr, src_pixels_per_line, FData, xoffset, 5); - - vertical_8xN(FData, dst_ptr, dst_pitch, yoffset, 4); -} - -static INLINE void horizontal_4x4(uint8_t *src, const int stride, uint16_t *dst, - const int xoffset) { - int h; - const __m128i zero = _mm_setzero_si128(); - - if (xoffset == 0) { - for (h = 0; h < 5; ++h) { - const __m128i a = load_unaligned_u32(src); - const __m128i a_u16 = _mm_unpacklo_epi8(a, zero); - _mm_storel_epi64((__m128i *)dst, a_u16); - src += stride; - dst += 4; - } - return; - } - - { - const __m128i round_factor = _mm_set1_epi16(1 << (VP8_FILTER_SHIFT - 1)); - const __m128i hfilter_0 = _mm_set1_epi16(vp8_bilinear_filters[xoffset][0]); - const __m128i hfilter_1 = _mm_set1_epi16(vp8_bilinear_filters[xoffset][1]); - - for (h = 0; h < 5; ++h) { - const __m128i a = load_unaligned_u32(src); - const __m128i b = load_unaligned_u32(src + 1); - const __m128i a_u16 = _mm_unpacklo_epi8(a, zero); - const __m128i b_u16 = _mm_unpacklo_epi8(b, zero); - const __m128i a_filtered = _mm_mullo_epi16(a_u16, hfilter_0); - const __m128i b_filtered = _mm_mullo_epi16(b_u16, hfilter_1); - const __m128i sum = _mm_add_epi16(a_filtered, b_filtered); - const __m128i compensated = _mm_add_epi16(sum, round_factor); - const __m128i shifted = _mm_srai_epi16(compensated, VP8_FILTER_SHIFT); - _mm_storel_epi64((__m128i *)dst, shifted); - src += stride; - dst += 4; - } - } -} - -static INLINE void vertical_4x4(uint16_t *src, uint8_t *dst, const int stride, - const int yoffset) { - int h; - - if (yoffset == 0) { - for (h = 0; h < 4; h += 2) { - const __m128i row = _mm_load_si128((__m128i *)src); - __m128i packed = _mm_packus_epi16(row, row); - store_unaligned_u32(dst, packed); - dst += stride; - packed = _mm_srli_si128(packed, 4); - store_unaligned_u32(dst, packed); - dst += stride; - src += 8; - } - return; - } - - { - const __m128i round_factor = _mm_set1_epi16(1 << (VP8_FILTER_SHIFT - 1)); - const __m128i vfilter_0 = _mm_set1_epi16(vp8_bilinear_filters[yoffset][0]); - const __m128i vfilter_1 = _mm_set1_epi16(vp8_bilinear_filters[yoffset][1]); - - for (h = 0; h < 4; h += 2) { - const __m128i row_0 = _mm_load_si128((__m128i *)src); - const __m128i row_1 = _mm_loadu_si128((__m128i *)(src + 4)); - const __m128i row_0_filtered = _mm_mullo_epi16(row_0, vfilter_0); - const __m128i row_1_filtered = _mm_mullo_epi16(row_1, vfilter_1); - const __m128i sum = _mm_add_epi16(row_0_filtered, row_1_filtered); - const __m128i compensated = _mm_add_epi16(sum, round_factor); - const __m128i shifted = _mm_srai_epi16(compensated, VP8_FILTER_SHIFT); - __m128i packed = _mm_packus_epi16(shifted, shifted); - storeu_int32(dst, _mm_cvtsi128_si32(packed)); - packed = _mm_srli_si128(packed, 4); - dst += stride; - storeu_int32(dst, _mm_cvtsi128_si32(packed)); - dst += stride; - src += 8; - } - } -} - -void vp8_bilinear_predict4x4_sse2(uint8_t *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, uint8_t *dst_ptr, - int dst_pitch) { - DECLARE_ALIGNED(16, uint16_t, FData[4 * 5]); - - assert((xoffset | yoffset) != 0); - - horizontal_4x4(src_ptr, src_pixels_per_line, FData, xoffset); - - vertical_4x4(FData, dst_ptr, dst_pitch, yoffset); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/dequantize_mmx.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/dequantize_mmx.asm deleted file mode 100644 index 0a269e15..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/dequantize_mmx.asm +++ /dev/null @@ -1,259 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -SECTION .text - -;void vp8_dequantize_b_impl_mmx(short *sq, short *dq, short *q) -globalsym(vp8_dequantize_b_impl_mmx) -sym(vp8_dequantize_b_impl_mmx): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 3 - push rsi - push rdi - ; end prolog - - mov rsi, arg(0) ;sq - mov rdi, arg(1) ;dq - mov rax, arg(2) ;q - - movq mm1, [rsi] - pmullw mm1, [rax+0] ; mm4 *= kernel 0 modifiers. - movq [rdi], mm1 - - movq mm1, [rsi+8] - pmullw mm1, [rax+8] ; mm4 *= kernel 0 modifiers. - movq [rdi+8], mm1 - - movq mm1, [rsi+16] - pmullw mm1, [rax+16] ; mm4 *= kernel 0 modifiers. - movq [rdi+16], mm1 - - movq mm1, [rsi+24] - pmullw mm1, [rax+24] ; mm4 *= kernel 0 modifiers. - movq [rdi+24], mm1 - - ; begin epilog - pop rdi - pop rsi - UNSHADOW_ARGS - pop rbp - ret - - -;void dequant_idct_add_mmx( -;short *input, 0 -;short *dq, 1 -;unsigned char *dest, 2 -;int stride) 3 -globalsym(vp8_dequant_idct_add_mmx) -sym(vp8_dequant_idct_add_mmx): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 4 - GET_GOT rbx - push rdi - ; end prolog - - mov rax, arg(0) ;input - mov rdx, arg(1) ;dq - - - movq mm0, [rax ] - pmullw mm0, [rdx] - - movq mm1, [rax +8] - pmullw mm1, [rdx +8] - - movq mm2, [rax+16] - pmullw mm2, [rdx+16] - - movq mm3, [rax+24] - pmullw mm3, [rdx+24] - - mov rdx, arg(2) ;dest - - pxor mm7, mm7 - - - movq [rax], mm7 - movq [rax+8], mm7 - - movq [rax+16],mm7 - movq [rax+24],mm7 - - - movsxd rdi, dword ptr arg(3) ;stride - - psubw mm0, mm2 ; b1= 0-2 - paddw mm2, mm2 ; - - movq mm5, mm1 - paddw mm2, mm0 ; a1 =0+2 - - pmulhw mm5, [GLOBAL(x_s1sqr2)]; - paddw mm5, mm1 ; ip1 * sin(pi/8) * sqrt(2) - - movq mm7, mm3 ; - pmulhw mm7, [GLOBAL(x_c1sqr2less1)]; - - paddw mm7, mm3 ; ip3 * cos(pi/8) * sqrt(2) - psubw mm7, mm5 ; c1 - - movq mm5, mm1 - movq mm4, mm3 - - pmulhw mm5, [GLOBAL(x_c1sqr2less1)] - paddw mm5, mm1 - - pmulhw mm3, [GLOBAL(x_s1sqr2)] - paddw mm3, mm4 - - paddw mm3, mm5 ; d1 - movq mm6, mm2 ; a1 - - movq mm4, mm0 ; b1 - paddw mm2, mm3 ;0 - - paddw mm4, mm7 ;1 - psubw mm0, mm7 ;2 - - psubw mm6, mm3 ;3 - - movq mm1, mm2 ; 03 02 01 00 - movq mm3, mm4 ; 23 22 21 20 - - punpcklwd mm1, mm0 ; 11 01 10 00 - punpckhwd mm2, mm0 ; 13 03 12 02 - - punpcklwd mm3, mm6 ; 31 21 30 20 - punpckhwd mm4, mm6 ; 33 23 32 22 - - movq mm0, mm1 ; 11 01 10 00 - movq mm5, mm2 ; 13 03 12 02 - - punpckldq mm0, mm3 ; 30 20 10 00 - punpckhdq mm1, mm3 ; 31 21 11 01 - - punpckldq mm2, mm4 ; 32 22 12 02 - punpckhdq mm5, mm4 ; 33 23 13 03 - - movq mm3, mm5 ; 33 23 13 03 - - psubw mm0, mm2 ; b1= 0-2 - paddw mm2, mm2 ; - - movq mm5, mm1 - paddw mm2, mm0 ; a1 =0+2 - - pmulhw mm5, [GLOBAL(x_s1sqr2)]; - paddw mm5, mm1 ; ip1 * sin(pi/8) * sqrt(2) - - movq mm7, mm3 ; - pmulhw mm7, [GLOBAL(x_c1sqr2less1)]; - - paddw mm7, mm3 ; ip3 * cos(pi/8) * sqrt(2) - psubw mm7, mm5 ; c1 - - movq mm5, mm1 - movq mm4, mm3 - - pmulhw mm5, [GLOBAL(x_c1sqr2less1)] - paddw mm5, mm1 - - pmulhw mm3, [GLOBAL(x_s1sqr2)] - paddw mm3, mm4 - - paddw mm3, mm5 ; d1 - paddw mm0, [GLOBAL(fours)] - - paddw mm2, [GLOBAL(fours)] - movq mm6, mm2 ; a1 - - movq mm4, mm0 ; b1 - paddw mm2, mm3 ;0 - - paddw mm4, mm7 ;1 - psubw mm0, mm7 ;2 - - psubw mm6, mm3 ;3 - psraw mm2, 3 - - psraw mm0, 3 - psraw mm4, 3 - - psraw mm6, 3 - - movq mm1, mm2 ; 03 02 01 00 - movq mm3, mm4 ; 23 22 21 20 - - punpcklwd mm1, mm0 ; 11 01 10 00 - punpckhwd mm2, mm0 ; 13 03 12 02 - - punpcklwd mm3, mm6 ; 31 21 30 20 - punpckhwd mm4, mm6 ; 33 23 32 22 - - movq mm0, mm1 ; 11 01 10 00 - movq mm5, mm2 ; 13 03 12 02 - - punpckldq mm0, mm3 ; 30 20 10 00 - punpckhdq mm1, mm3 ; 31 21 11 01 - - punpckldq mm2, mm4 ; 32 22 12 02 - punpckhdq mm5, mm4 ; 33 23 13 03 - - pxor mm7, mm7 - - movd mm4, [rdx] - punpcklbw mm4, mm7 - paddsw mm0, mm4 - packuswb mm0, mm7 - movd [rdx], mm0 - - movd mm4, [rdx+rdi] - punpcklbw mm4, mm7 - paddsw mm1, mm4 - packuswb mm1, mm7 - movd [rdx+rdi], mm1 - - movd mm4, [rdx+2*rdi] - punpcklbw mm4, mm7 - paddsw mm2, mm4 - packuswb mm2, mm7 - movd [rdx+rdi*2], mm2 - - add rdx, rdi - - movd mm4, [rdx+2*rdi] - punpcklbw mm4, mm7 - paddsw mm5, mm4 - packuswb mm5, mm7 - movd [rdx+rdi*2], mm5 - - ; begin epilog - pop rdi - RESTORE_GOT - UNSHADOW_ARGS - pop rbp - ret - -SECTION_RODATA -align 16 -x_s1sqr2: - times 4 dw 0x8A8C -align 16 -x_c1sqr2less1: - times 4 dw 0x4E7B -align 16 -fours: - times 4 dw 0x0004 diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/idct_blk_mmx.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/idct_blk_mmx.c deleted file mode 100644 index fd804b1c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/idct_blk_mmx.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "vp8_rtcd.h" -#include "vp8/common/blockd.h" -#include "vpx_mem/vpx_mem.h" - -extern void vp8_dequantize_b_impl_mmx(short *sq, short *dq, short *q); - -void vp8_dequantize_b_mmx(BLOCKD *d, short *DQC) { - short *sq = (short *)d->qcoeff; - short *dq = (short *)d->dqcoeff; - - vp8_dequantize_b_impl_mmx(sq, dq, DQC); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/idct_blk_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/idct_blk_sse2.c deleted file mode 100644 index 897ed5b6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/idct_blk_sse2.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "vp8_rtcd.h" - -void vp8_idct_dequant_0_2x_sse2(short *q, short *dq, unsigned char *dst, - int dst_stride); -void vp8_idct_dequant_full_2x_sse2(short *q, short *dq, unsigned char *dst, - int dst_stride); - -void vp8_dequant_idct_add_y_block_sse2(short *q, short *dq, unsigned char *dst, - int stride, char *eobs) { - int i; - - for (i = 0; i < 4; ++i) { - if (((short *)(eobs))[0]) { - if (((short *)(eobs))[0] & 0xfefe) { - vp8_idct_dequant_full_2x_sse2(q, dq, dst, stride); - } else { - vp8_idct_dequant_0_2x_sse2(q, dq, dst, stride); - } - } - if (((short *)(eobs))[1]) { - if (((short *)(eobs))[1] & 0xfefe) { - vp8_idct_dequant_full_2x_sse2(q + 32, dq, dst + 8, stride); - } else { - vp8_idct_dequant_0_2x_sse2(q + 32, dq, dst + 8, stride); - } - } - q += 64; - dst += stride * 4; - eobs += 4; - } -} - -void vp8_dequant_idct_add_uv_block_sse2(short *q, short *dq, - unsigned char *dst_u, - unsigned char *dst_v, int stride, - char *eobs) { - if (((short *)(eobs))[0]) { - if (((short *)(eobs))[0] & 0xfefe) { - vp8_idct_dequant_full_2x_sse2(q, dq, dst_u, stride); - } else { - vp8_idct_dequant_0_2x_sse2(q, dq, dst_u, stride); - } - } - q += 32; - dst_u += stride * 4; - - if (((short *)(eobs))[1]) { - if (((short *)(eobs))[1] & 0xfefe) { - vp8_idct_dequant_full_2x_sse2(q, dq, dst_u, stride); - } else { - vp8_idct_dequant_0_2x_sse2(q, dq, dst_u, stride); - } - } - q += 32; - - if (((short *)(eobs))[2]) { - if (((short *)(eobs))[2] & 0xfefe) { - vp8_idct_dequant_full_2x_sse2(q, dq, dst_v, stride); - } else { - vp8_idct_dequant_0_2x_sse2(q, dq, dst_v, stride); - } - } - q += 32; - dst_v += stride * 4; - - if (((short *)(eobs))[3]) { - if (((short *)(eobs))[3] & 0xfefe) { - vp8_idct_dequant_full_2x_sse2(q, dq, dst_v, stride); - } else { - vp8_idct_dequant_0_2x_sse2(q, dq, dst_v, stride); - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/idctllm_mmx.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/idctllm_mmx.asm deleted file mode 100644 index 6cea86fe..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/idctllm_mmx.asm +++ /dev/null @@ -1,296 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -; /**************************************************************************** -; * Notes: -; * -; * This implementation makes use of 16 bit fixed point version of two multiply -; * constants: -; * 1. sqrt(2) * cos (pi/8) -; * 2. sqrt(2) * sin (pi/8) -; * Because the first constant is bigger than 1, to maintain the same 16 bit -; * fixed point precision as the second one, we use a trick of -; * x * a = x + x*(a-1) -; * so -; * x * sqrt(2) * cos (pi/8) = x + x * (sqrt(2) *cos(pi/8)-1). -; * -; * For the second constant, because of the 16bit version is 35468, which -; * is bigger than 32768, in signed 16 bit multiply, it becomes a negative -; * number. -; * (x * (unsigned)35468 >> 16) = x * (signed)35468 >> 16 + x -; * -; **************************************************************************/ - -SECTION .text - -;void vp8_short_idct4x4llm_mmx(short *input, unsigned char *pred, -;int pitch, unsigned char *dest,int stride) -globalsym(vp8_short_idct4x4llm_mmx) -sym(vp8_short_idct4x4llm_mmx): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 5 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - mov rax, arg(0) ;input - mov rsi, arg(1) ;pred - - movq mm0, [rax ] - movq mm1, [rax+ 8] - movq mm2, [rax+16] - movq mm3, [rax+24] - -%if 0 - pxor mm7, mm7 - movq [rax], mm7 - movq [rax+8], mm7 - movq [rax+16],mm7 - movq [rax+24],mm7 -%endif - movsxd rax, dword ptr arg(2) ;pitch - mov rdx, arg(3) ;dest - movsxd rdi, dword ptr arg(4) ;stride - - - psubw mm0, mm2 ; b1= 0-2 - paddw mm2, mm2 ; - - movq mm5, mm1 - paddw mm2, mm0 ; a1 =0+2 - - pmulhw mm5, [GLOBAL(x_s1sqr2)]; - paddw mm5, mm1 ; ip1 * sin(pi/8) * sqrt(2) - - movq mm7, mm3 ; - pmulhw mm7, [GLOBAL(x_c1sqr2less1)]; - - paddw mm7, mm3 ; ip3 * cos(pi/8) * sqrt(2) - psubw mm7, mm5 ; c1 - - movq mm5, mm1 - movq mm4, mm3 - - pmulhw mm5, [GLOBAL(x_c1sqr2less1)] - paddw mm5, mm1 - - pmulhw mm3, [GLOBAL(x_s1sqr2)] - paddw mm3, mm4 - - paddw mm3, mm5 ; d1 - movq mm6, mm2 ; a1 - - movq mm4, mm0 ; b1 - paddw mm2, mm3 ;0 - - paddw mm4, mm7 ;1 - psubw mm0, mm7 ;2 - - psubw mm6, mm3 ;3 - - movq mm1, mm2 ; 03 02 01 00 - movq mm3, mm4 ; 23 22 21 20 - - punpcklwd mm1, mm0 ; 11 01 10 00 - punpckhwd mm2, mm0 ; 13 03 12 02 - - punpcklwd mm3, mm6 ; 31 21 30 20 - punpckhwd mm4, mm6 ; 33 23 32 22 - - movq mm0, mm1 ; 11 01 10 00 - movq mm5, mm2 ; 13 03 12 02 - - punpckldq mm0, mm3 ; 30 20 10 00 - punpckhdq mm1, mm3 ; 31 21 11 01 - - punpckldq mm2, mm4 ; 32 22 12 02 - punpckhdq mm5, mm4 ; 33 23 13 03 - - movq mm3, mm5 ; 33 23 13 03 - - psubw mm0, mm2 ; b1= 0-2 - paddw mm2, mm2 ; - - movq mm5, mm1 - paddw mm2, mm0 ; a1 =0+2 - - pmulhw mm5, [GLOBAL(x_s1sqr2)]; - paddw mm5, mm1 ; ip1 * sin(pi/8) * sqrt(2) - - movq mm7, mm3 ; - pmulhw mm7, [GLOBAL(x_c1sqr2less1)]; - - paddw mm7, mm3 ; ip3 * cos(pi/8) * sqrt(2) - psubw mm7, mm5 ; c1 - - movq mm5, mm1 - movq mm4, mm3 - - pmulhw mm5, [GLOBAL(x_c1sqr2less1)] - paddw mm5, mm1 - - pmulhw mm3, [GLOBAL(x_s1sqr2)] - paddw mm3, mm4 - - paddw mm3, mm5 ; d1 - paddw mm0, [GLOBAL(fours)] - - paddw mm2, [GLOBAL(fours)] - movq mm6, mm2 ; a1 - - movq mm4, mm0 ; b1 - paddw mm2, mm3 ;0 - - paddw mm4, mm7 ;1 - psubw mm0, mm7 ;2 - - psubw mm6, mm3 ;3 - psraw mm2, 3 - - psraw mm0, 3 - psraw mm4, 3 - - psraw mm6, 3 - - movq mm1, mm2 ; 03 02 01 00 - movq mm3, mm4 ; 23 22 21 20 - - punpcklwd mm1, mm0 ; 11 01 10 00 - punpckhwd mm2, mm0 ; 13 03 12 02 - - punpcklwd mm3, mm6 ; 31 21 30 20 - punpckhwd mm4, mm6 ; 33 23 32 22 - - movq mm0, mm1 ; 11 01 10 00 - movq mm5, mm2 ; 13 03 12 02 - - punpckldq mm0, mm3 ; 30 20 10 00 - punpckhdq mm1, mm3 ; 31 21 11 01 - - punpckldq mm2, mm4 ; 32 22 12 02 - punpckhdq mm5, mm4 ; 33 23 13 03 - - pxor mm7, mm7 - - movd mm4, [rsi] - punpcklbw mm4, mm7 - paddsw mm0, mm4 - packuswb mm0, mm7 - movd [rdx], mm0 - - movd mm4, [rsi+rax] - punpcklbw mm4, mm7 - paddsw mm1, mm4 - packuswb mm1, mm7 - movd [rdx+rdi], mm1 - - movd mm4, [rsi+2*rax] - punpcklbw mm4, mm7 - paddsw mm2, mm4 - packuswb mm2, mm7 - movd [rdx+rdi*2], mm2 - - add rdx, rdi - add rsi, rax - - movd mm4, [rsi+2*rax] - punpcklbw mm4, mm7 - paddsw mm5, mm4 - packuswb mm5, mm7 - movd [rdx+rdi*2], mm5 - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - UNSHADOW_ARGS - pop rbp - ret - -;void vp8_dc_only_idct_add_mmx( -;short input_dc, -;unsigned char *pred_ptr, -;int pred_stride, -;unsigned char *dst_ptr, -;int stride) -globalsym(vp8_dc_only_idct_add_mmx) -sym(vp8_dc_only_idct_add_mmx): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 5 - GET_GOT rbx - ; end prolog - - movd mm5, arg(0) ;input_dc - mov rax, arg(1) ;pred_ptr - movsxd rdx, dword ptr arg(2) ;pred_stride - - pxor mm0, mm0 - - paddw mm5, [GLOBAL(fours)] - lea rcx, [rdx + rdx*2] - - psraw mm5, 3 - - punpcklwd mm5, mm5 - - punpckldq mm5, mm5 - - movd mm1, [rax] - movd mm2, [rax+rdx] - movd mm3, [rax+2*rdx] - movd mm4, [rax+rcx] - - mov rax, arg(3) ;d -- destination - movsxd rdx, dword ptr arg(4) ;dst_stride - - punpcklbw mm1, mm0 - paddsw mm1, mm5 - packuswb mm1, mm0 ; pack and unpack to saturate - lea rcx, [rdx + rdx*2] - - punpcklbw mm2, mm0 - paddsw mm2, mm5 - packuswb mm2, mm0 ; pack and unpack to saturate - - punpcklbw mm3, mm0 - paddsw mm3, mm5 - packuswb mm3, mm0 ; pack and unpack to saturate - - punpcklbw mm4, mm0 - paddsw mm4, mm5 - packuswb mm4, mm0 ; pack and unpack to saturate - - movd [rax], mm1 - movd [rax+rdx], mm2 - movd [rax+2*rdx], mm3 - movd [rax+rcx], mm4 - - ; begin epilog - RESTORE_GOT - UNSHADOW_ARGS - pop rbp - ret - -SECTION_RODATA -align 16 -x_s1sqr2: - times 4 dw 0x8A8C -align 16 -x_c1sqr2less1: - times 4 dw 0x4E7B -align 16 -fours: - times 4 dw 0x0004 diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/idctllm_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/idctllm_sse2.asm deleted file mode 100644 index bb79d2da..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/idctllm_sse2.asm +++ /dev/null @@ -1,710 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -;void vp8_idct_dequant_0_2x_sse2 -; ( -; short *qcoeff - 0 -; short *dequant - 1 -; unsigned char *dst - 2 -; int dst_stride - 3 -; ) - -SECTION .text - -globalsym(vp8_idct_dequant_0_2x_sse2) -sym(vp8_idct_dequant_0_2x_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 4 - GET_GOT rbx - ; end prolog - - mov rdx, arg(1) ; dequant - mov rax, arg(0) ; qcoeff - - movd xmm4, [rax] - movd xmm5, [rdx] - - pinsrw xmm4, [rax+32], 4 - pinsrw xmm5, [rdx], 4 - - pmullw xmm4, xmm5 - - ; Zero out xmm5, for use unpacking - pxor xmm5, xmm5 - - ; clear coeffs - movd [rax], xmm5 - movd [rax+32], xmm5 -;pshufb - mov rax, arg(2) ; dst - movsxd rdx, dword ptr arg(3) ; dst_stride - - pshuflw xmm4, xmm4, 00000000b - pshufhw xmm4, xmm4, 00000000b - - lea rcx, [rdx + rdx*2] - paddw xmm4, [GLOBAL(fours)] - - psraw xmm4, 3 - - movq xmm0, [rax] - movq xmm1, [rax+rdx] - movq xmm2, [rax+2*rdx] - movq xmm3, [rax+rcx] - - punpcklbw xmm0, xmm5 - punpcklbw xmm1, xmm5 - punpcklbw xmm2, xmm5 - punpcklbw xmm3, xmm5 - - - ; Add to predict buffer - paddw xmm0, xmm4 - paddw xmm1, xmm4 - paddw xmm2, xmm4 - paddw xmm3, xmm4 - - ; pack up before storing - packuswb xmm0, xmm5 - packuswb xmm1, xmm5 - packuswb xmm2, xmm5 - packuswb xmm3, xmm5 - - ; store blocks back out - movq [rax], xmm0 - movq [rax + rdx], xmm1 - - lea rax, [rax + 2*rdx] - - movq [rax], xmm2 - movq [rax + rdx], xmm3 - - ; begin epilog - RESTORE_GOT - UNSHADOW_ARGS - pop rbp - ret - -;void vp8_idct_dequant_full_2x_sse2 -; ( -; short *qcoeff - 0 -; short *dequant - 1 -; unsigned char *dst - 2 -; int dst_stride - 3 -; ) -globalsym(vp8_idct_dequant_full_2x_sse2) -sym(vp8_idct_dequant_full_2x_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 4 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - ; special case when 2 blocks have 0 or 1 coeffs - ; dc is set as first coeff, so no need to load qcoeff - mov rax, arg(0) ; qcoeff - mov rdx, arg(1) ; dequant - mov rdi, arg(2) ; dst - - - ; Zero out xmm7, for use unpacking - pxor xmm7, xmm7 - - - ; note the transpose of xmm1 and xmm2, necessary for shuffle - ; to spit out sensicle data - movdqa xmm0, [rax] - movdqa xmm2, [rax+16] - movdqa xmm1, [rax+32] - movdqa xmm3, [rax+48] - - ; Clear out coeffs - movdqa [rax], xmm7 - movdqa [rax+16], xmm7 - movdqa [rax+32], xmm7 - movdqa [rax+48], xmm7 - - ; dequantize qcoeff buffer - pmullw xmm0, [rdx] - pmullw xmm2, [rdx+16] - pmullw xmm1, [rdx] - pmullw xmm3, [rdx+16] - movsxd rdx, dword ptr arg(3) ; dst_stride - - ; repack so block 0 row x and block 1 row x are together - movdqa xmm4, xmm0 - punpckldq xmm0, xmm1 - punpckhdq xmm4, xmm1 - - pshufd xmm0, xmm0, 11011000b - pshufd xmm1, xmm4, 11011000b - - movdqa xmm4, xmm2 - punpckldq xmm2, xmm3 - punpckhdq xmm4, xmm3 - - pshufd xmm2, xmm2, 11011000b - pshufd xmm3, xmm4, 11011000b - - ; first pass - psubw xmm0, xmm2 ; b1 = 0-2 - paddw xmm2, xmm2 ; - - movdqa xmm5, xmm1 - paddw xmm2, xmm0 ; a1 = 0+2 - - pmulhw xmm5, [GLOBAL(x_s1sqr2)] - lea rcx, [rdx + rdx*2] ;dst_stride * 3 - paddw xmm5, xmm1 ; ip1 * sin(pi/8) * sqrt(2) - - movdqa xmm7, xmm3 - pmulhw xmm7, [GLOBAL(x_c1sqr2less1)] - - paddw xmm7, xmm3 ; ip3 * cos(pi/8) * sqrt(2) - psubw xmm7, xmm5 ; c1 - - movdqa xmm5, xmm1 - movdqa xmm4, xmm3 - - pmulhw xmm5, [GLOBAL(x_c1sqr2less1)] - paddw xmm5, xmm1 - - pmulhw xmm3, [GLOBAL(x_s1sqr2)] - paddw xmm3, xmm4 - - paddw xmm3, xmm5 ; d1 - movdqa xmm6, xmm2 ; a1 - - movdqa xmm4, xmm0 ; b1 - paddw xmm2, xmm3 ;0 - - paddw xmm4, xmm7 ;1 - psubw xmm0, xmm7 ;2 - - psubw xmm6, xmm3 ;3 - - ; transpose for the second pass - movdqa xmm7, xmm2 ; 103 102 101 100 003 002 001 000 - punpcklwd xmm2, xmm0 ; 007 003 006 002 005 001 004 000 - punpckhwd xmm7, xmm0 ; 107 103 106 102 105 101 104 100 - - movdqa xmm5, xmm4 ; 111 110 109 108 011 010 009 008 - punpcklwd xmm4, xmm6 ; 015 011 014 010 013 009 012 008 - punpckhwd xmm5, xmm6 ; 115 111 114 110 113 109 112 108 - - - movdqa xmm1, xmm2 ; 007 003 006 002 005 001 004 000 - punpckldq xmm2, xmm4 ; 013 009 005 001 012 008 004 000 - punpckhdq xmm1, xmm4 ; 015 011 007 003 014 010 006 002 - - movdqa xmm6, xmm7 ; 107 103 106 102 105 101 104 100 - punpckldq xmm7, xmm5 ; 113 109 105 101 112 108 104 100 - punpckhdq xmm6, xmm5 ; 115 111 107 103 114 110 106 102 - - - movdqa xmm5, xmm2 ; 013 009 005 001 012 008 004 000 - punpckldq xmm2, xmm7 ; 112 108 012 008 104 100 004 000 - punpckhdq xmm5, xmm7 ; 113 109 013 009 105 101 005 001 - - movdqa xmm7, xmm1 ; 015 011 007 003 014 010 006 002 - punpckldq xmm1, xmm6 ; 114 110 014 010 106 102 006 002 - punpckhdq xmm7, xmm6 ; 115 111 015 011 107 103 007 003 - - pshufd xmm0, xmm2, 11011000b - pshufd xmm2, xmm1, 11011000b - - pshufd xmm1, xmm5, 11011000b - pshufd xmm3, xmm7, 11011000b - - ; second pass - psubw xmm0, xmm2 ; b1 = 0-2 - paddw xmm2, xmm2 - - movdqa xmm5, xmm1 - paddw xmm2, xmm0 ; a1 = 0+2 - - pmulhw xmm5, [GLOBAL(x_s1sqr2)] - paddw xmm5, xmm1 ; ip1 * sin(pi/8) * sqrt(2) - - movdqa xmm7, xmm3 - pmulhw xmm7, [GLOBAL(x_c1sqr2less1)] - - paddw xmm7, xmm3 ; ip3 * cos(pi/8) * sqrt(2) - psubw xmm7, xmm5 ; c1 - - movdqa xmm5, xmm1 - movdqa xmm4, xmm3 - - pmulhw xmm5, [GLOBAL(x_c1sqr2less1)] - paddw xmm5, xmm1 - - pmulhw xmm3, [GLOBAL(x_s1sqr2)] - paddw xmm3, xmm4 - - paddw xmm3, xmm5 ; d1 - paddw xmm0, [GLOBAL(fours)] - - paddw xmm2, [GLOBAL(fours)] - movdqa xmm6, xmm2 ; a1 - - movdqa xmm4, xmm0 ; b1 - paddw xmm2, xmm3 ;0 - - paddw xmm4, xmm7 ;1 - psubw xmm0, xmm7 ;2 - - psubw xmm6, xmm3 ;3 - psraw xmm2, 3 - - psraw xmm0, 3 - psraw xmm4, 3 - - psraw xmm6, 3 - - ; transpose to save - movdqa xmm7, xmm2 ; 103 102 101 100 003 002 001 000 - punpcklwd xmm2, xmm0 ; 007 003 006 002 005 001 004 000 - punpckhwd xmm7, xmm0 ; 107 103 106 102 105 101 104 100 - - movdqa xmm5, xmm4 ; 111 110 109 108 011 010 009 008 - punpcklwd xmm4, xmm6 ; 015 011 014 010 013 009 012 008 - punpckhwd xmm5, xmm6 ; 115 111 114 110 113 109 112 108 - - - movdqa xmm1, xmm2 ; 007 003 006 002 005 001 004 000 - punpckldq xmm2, xmm4 ; 013 009 005 001 012 008 004 000 - punpckhdq xmm1, xmm4 ; 015 011 007 003 014 010 006 002 - - movdqa xmm6, xmm7 ; 107 103 106 102 105 101 104 100 - punpckldq xmm7, xmm5 ; 113 109 105 101 112 108 104 100 - punpckhdq xmm6, xmm5 ; 115 111 107 103 114 110 106 102 - - - movdqa xmm5, xmm2 ; 013 009 005 001 012 008 004 000 - punpckldq xmm2, xmm7 ; 112 108 012 008 104 100 004 000 - punpckhdq xmm5, xmm7 ; 113 109 013 009 105 101 005 001 - - movdqa xmm7, xmm1 ; 015 011 007 003 014 010 006 002 - punpckldq xmm1, xmm6 ; 114 110 014 010 106 102 006 002 - punpckhdq xmm7, xmm6 ; 115 111 015 011 107 103 007 003 - - pshufd xmm0, xmm2, 11011000b - pshufd xmm2, xmm1, 11011000b - - pshufd xmm1, xmm5, 11011000b - pshufd xmm3, xmm7, 11011000b - - pxor xmm7, xmm7 - - ; Load up predict blocks - movq xmm4, [rdi] - movq xmm5, [rdi+rdx] - - punpcklbw xmm4, xmm7 - punpcklbw xmm5, xmm7 - - paddw xmm0, xmm4 - paddw xmm1, xmm5 - - movq xmm4, [rdi+2*rdx] - movq xmm5, [rdi+rcx] - - punpcklbw xmm4, xmm7 - punpcklbw xmm5, xmm7 - - paddw xmm2, xmm4 - paddw xmm3, xmm5 - -.finish: - - ; pack up before storing - packuswb xmm0, xmm7 - packuswb xmm1, xmm7 - packuswb xmm2, xmm7 - packuswb xmm3, xmm7 - - ; store blocks back out - movq [rdi], xmm0 - movq [rdi + rdx], xmm1 - movq [rdi + rdx*2], xmm2 - movq [rdi + rcx], xmm3 - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -;void vp8_idct_dequant_dc_0_2x_sse2 -; ( -; short *qcoeff - 0 -; short *dequant - 1 -; unsigned char *dst - 2 -; int dst_stride - 3 -; short *dc - 4 -; ) -globalsym(vp8_idct_dequant_dc_0_2x_sse2) -sym(vp8_idct_dequant_dc_0_2x_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 5 - GET_GOT rbx - push rdi - ; end prolog - - ; special case when 2 blocks have 0 or 1 coeffs - ; dc is set as first coeff, so no need to load qcoeff - mov rax, arg(0) ; qcoeff - - mov rdi, arg(2) ; dst - mov rdx, arg(4) ; dc - - ; Zero out xmm5, for use unpacking - pxor xmm5, xmm5 - - ; load up 2 dc words here == 2*16 = doubleword - movd xmm4, [rdx] - - movsxd rdx, dword ptr arg(3) ; dst_stride - lea rcx, [rdx + rdx*2] - ; Load up predict blocks - movq xmm0, [rdi] - movq xmm1, [rdi+rdx*1] - movq xmm2, [rdi+rdx*2] - movq xmm3, [rdi+rcx] - - ; Duplicate and expand dc across - punpcklwd xmm4, xmm4 - punpckldq xmm4, xmm4 - - ; Rounding to dequant and downshift - paddw xmm4, [GLOBAL(fours)] - psraw xmm4, 3 - - ; Predict buffer needs to be expanded from bytes to words - punpcklbw xmm0, xmm5 - punpcklbw xmm1, xmm5 - punpcklbw xmm2, xmm5 - punpcklbw xmm3, xmm5 - - ; Add to predict buffer - paddw xmm0, xmm4 - paddw xmm1, xmm4 - paddw xmm2, xmm4 - paddw xmm3, xmm4 - - ; pack up before storing - packuswb xmm0, xmm5 - packuswb xmm1, xmm5 - packuswb xmm2, xmm5 - packuswb xmm3, xmm5 - - ; store blocks back out - movq [rdi], xmm0 - movq [rdi + rdx], xmm1 - movq [rdi + rdx*2], xmm2 - movq [rdi + rcx], xmm3 - - ; begin epilog - pop rdi - RESTORE_GOT - UNSHADOW_ARGS - pop rbp - ret -;void vp8_idct_dequant_dc_full_2x_sse2 -; ( -; short *qcoeff - 0 -; short *dequant - 1 -; unsigned char *dst - 2 -; int dst_stride - 3 -; short *dc - 4 -; ) -globalsym(vp8_idct_dequant_dc_full_2x_sse2) -sym(vp8_idct_dequant_dc_full_2x_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 5 - SAVE_XMM 7 - GET_GOT rbx - push rdi - ; end prolog - - ; special case when 2 blocks have 0 or 1 coeffs - ; dc is set as first coeff, so no need to load qcoeff - mov rax, arg(0) ; qcoeff - mov rdx, arg(1) ; dequant - - mov rdi, arg(2) ; dst - - ; Zero out xmm7, for use unpacking - pxor xmm7, xmm7 - - - ; note the transpose of xmm1 and xmm2, necessary for shuffle - ; to spit out sensicle data - movdqa xmm0, [rax] - movdqa xmm2, [rax+16] - movdqa xmm1, [rax+32] - movdqa xmm3, [rax+48] - - ; Clear out coeffs - movdqa [rax], xmm7 - movdqa [rax+16], xmm7 - movdqa [rax+32], xmm7 - movdqa [rax+48], xmm7 - - ; dequantize qcoeff buffer - pmullw xmm0, [rdx] - pmullw xmm2, [rdx+16] - pmullw xmm1, [rdx] - pmullw xmm3, [rdx+16] - - ; DC component - mov rdx, arg(4) - - ; repack so block 0 row x and block 1 row x are together - movdqa xmm4, xmm0 - punpckldq xmm0, xmm1 - punpckhdq xmm4, xmm1 - - pshufd xmm0, xmm0, 11011000b - pshufd xmm1, xmm4, 11011000b - - movdqa xmm4, xmm2 - punpckldq xmm2, xmm3 - punpckhdq xmm4, xmm3 - - pshufd xmm2, xmm2, 11011000b - pshufd xmm3, xmm4, 11011000b - - ; insert DC component - pinsrw xmm0, [rdx], 0 - pinsrw xmm0, [rdx+2], 4 - - ; first pass - psubw xmm0, xmm2 ; b1 = 0-2 - paddw xmm2, xmm2 ; - - movdqa xmm5, xmm1 - paddw xmm2, xmm0 ; a1 = 0+2 - - pmulhw xmm5, [GLOBAL(x_s1sqr2)] - paddw xmm5, xmm1 ; ip1 * sin(pi/8) * sqrt(2) - - movdqa xmm7, xmm3 - pmulhw xmm7, [GLOBAL(x_c1sqr2less1)] - - paddw xmm7, xmm3 ; ip3 * cos(pi/8) * sqrt(2) - psubw xmm7, xmm5 ; c1 - - movdqa xmm5, xmm1 - movdqa xmm4, xmm3 - - pmulhw xmm5, [GLOBAL(x_c1sqr2less1)] - paddw xmm5, xmm1 - - pmulhw xmm3, [GLOBAL(x_s1sqr2)] - paddw xmm3, xmm4 - - paddw xmm3, xmm5 ; d1 - movdqa xmm6, xmm2 ; a1 - - movdqa xmm4, xmm0 ; b1 - paddw xmm2, xmm3 ;0 - - paddw xmm4, xmm7 ;1 - psubw xmm0, xmm7 ;2 - - psubw xmm6, xmm3 ;3 - - ; transpose for the second pass - movdqa xmm7, xmm2 ; 103 102 101 100 003 002 001 000 - punpcklwd xmm2, xmm0 ; 007 003 006 002 005 001 004 000 - punpckhwd xmm7, xmm0 ; 107 103 106 102 105 101 104 100 - - movdqa xmm5, xmm4 ; 111 110 109 108 011 010 009 008 - punpcklwd xmm4, xmm6 ; 015 011 014 010 013 009 012 008 - punpckhwd xmm5, xmm6 ; 115 111 114 110 113 109 112 108 - - - movdqa xmm1, xmm2 ; 007 003 006 002 005 001 004 000 - punpckldq xmm2, xmm4 ; 013 009 005 001 012 008 004 000 - punpckhdq xmm1, xmm4 ; 015 011 007 003 014 010 006 002 - - movdqa xmm6, xmm7 ; 107 103 106 102 105 101 104 100 - punpckldq xmm7, xmm5 ; 113 109 105 101 112 108 104 100 - punpckhdq xmm6, xmm5 ; 115 111 107 103 114 110 106 102 - - - movdqa xmm5, xmm2 ; 013 009 005 001 012 008 004 000 - punpckldq xmm2, xmm7 ; 112 108 012 008 104 100 004 000 - punpckhdq xmm5, xmm7 ; 113 109 013 009 105 101 005 001 - - movdqa xmm7, xmm1 ; 015 011 007 003 014 010 006 002 - punpckldq xmm1, xmm6 ; 114 110 014 010 106 102 006 002 - punpckhdq xmm7, xmm6 ; 115 111 015 011 107 103 007 003 - - pshufd xmm0, xmm2, 11011000b - pshufd xmm2, xmm1, 11011000b - - pshufd xmm1, xmm5, 11011000b - pshufd xmm3, xmm7, 11011000b - - ; second pass - psubw xmm0, xmm2 ; b1 = 0-2 - paddw xmm2, xmm2 - - movdqa xmm5, xmm1 - paddw xmm2, xmm0 ; a1 = 0+2 - - pmulhw xmm5, [GLOBAL(x_s1sqr2)] - paddw xmm5, xmm1 ; ip1 * sin(pi/8) * sqrt(2) - - movdqa xmm7, xmm3 - pmulhw xmm7, [GLOBAL(x_c1sqr2less1)] - - paddw xmm7, xmm3 ; ip3 * cos(pi/8) * sqrt(2) - psubw xmm7, xmm5 ; c1 - - movdqa xmm5, xmm1 - movdqa xmm4, xmm3 - - pmulhw xmm5, [GLOBAL(x_c1sqr2less1)] - paddw xmm5, xmm1 - - pmulhw xmm3, [GLOBAL(x_s1sqr2)] - paddw xmm3, xmm4 - - paddw xmm3, xmm5 ; d1 - paddw xmm0, [GLOBAL(fours)] - - paddw xmm2, [GLOBAL(fours)] - movdqa xmm6, xmm2 ; a1 - - movdqa xmm4, xmm0 ; b1 - paddw xmm2, xmm3 ;0 - - paddw xmm4, xmm7 ;1 - psubw xmm0, xmm7 ;2 - - psubw xmm6, xmm3 ;3 - psraw xmm2, 3 - - psraw xmm0, 3 - psraw xmm4, 3 - - psraw xmm6, 3 - - ; transpose to save - movdqa xmm7, xmm2 ; 103 102 101 100 003 002 001 000 - punpcklwd xmm2, xmm0 ; 007 003 006 002 005 001 004 000 - punpckhwd xmm7, xmm0 ; 107 103 106 102 105 101 104 100 - - movdqa xmm5, xmm4 ; 111 110 109 108 011 010 009 008 - punpcklwd xmm4, xmm6 ; 015 011 014 010 013 009 012 008 - punpckhwd xmm5, xmm6 ; 115 111 114 110 113 109 112 108 - - - movdqa xmm1, xmm2 ; 007 003 006 002 005 001 004 000 - punpckldq xmm2, xmm4 ; 013 009 005 001 012 008 004 000 - punpckhdq xmm1, xmm4 ; 015 011 007 003 014 010 006 002 - - movdqa xmm6, xmm7 ; 107 103 106 102 105 101 104 100 - punpckldq xmm7, xmm5 ; 113 109 105 101 112 108 104 100 - punpckhdq xmm6, xmm5 ; 115 111 107 103 114 110 106 102 - - - movdqa xmm5, xmm2 ; 013 009 005 001 012 008 004 000 - punpckldq xmm2, xmm7 ; 112 108 012 008 104 100 004 000 - punpckhdq xmm5, xmm7 ; 113 109 013 009 105 101 005 001 - - movdqa xmm7, xmm1 ; 015 011 007 003 014 010 006 002 - punpckldq xmm1, xmm6 ; 114 110 014 010 106 102 006 002 - punpckhdq xmm7, xmm6 ; 115 111 015 011 107 103 007 003 - - pshufd xmm0, xmm2, 11011000b - pshufd xmm2, xmm1, 11011000b - - pshufd xmm1, xmm5, 11011000b - pshufd xmm3, xmm7, 11011000b - - pxor xmm7, xmm7 - - ; Load up predict blocks - movsxd rdx, dword ptr arg(3) ; dst_stride - movq xmm4, [rdi] - movq xmm5, [rdi+rdx] - lea rcx, [rdx + rdx*2] - - punpcklbw xmm4, xmm7 - punpcklbw xmm5, xmm7 - - paddw xmm0, xmm4 - paddw xmm1, xmm5 - - movq xmm4, [rdi+rdx*2] - movq xmm5, [rdi+rcx] - - punpcklbw xmm4, xmm7 - punpcklbw xmm5, xmm7 - - paddw xmm2, xmm4 - paddw xmm3, xmm5 - -.finish: - - ; pack up before storing - packuswb xmm0, xmm7 - packuswb xmm1, xmm7 - packuswb xmm2, xmm7 - packuswb xmm3, xmm7 - - ; Load destination stride before writing out, - ; doesn't need to persist - movsxd rdx, dword ptr arg(3) ; dst_stride - - ; store blocks back out - movq [rdi], xmm0 - movq [rdi + rdx], xmm1 - - lea rdi, [rdi + 2*rdx] - - movq [rdi], xmm2 - movq [rdi + rdx], xmm3 - - - ; begin epilog - pop rdi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -SECTION_RODATA -align 16 -fours: - times 8 dw 0x0004 -align 16 -x_s1sqr2: - times 8 dw 0x8A8C -align 16 -x_c1sqr2less1: - times 8 dw 0x4E7B diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/iwalsh_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/iwalsh_sse2.asm deleted file mode 100644 index 56f37c3e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/iwalsh_sse2.asm +++ /dev/null @@ -1,123 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -SECTION .text - -;void vp8_short_inv_walsh4x4_sse2(short *input, short *mb_dqcoeff) -globalsym(vp8_short_inv_walsh4x4_sse2) -sym(vp8_short_inv_walsh4x4_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 2 - ; end prolog - - mov rcx, arg(0) - mov rdx, arg(1) - mov rax, 30003h - - movdqa xmm0, [rcx + 0] ;ip[4] ip[0] - movdqa xmm1, [rcx + 16] ;ip[12] ip[8] - - - pshufd xmm2, xmm1, 4eh ;ip[8] ip[12] - movdqa xmm3, xmm0 ;ip[4] ip[0] - - paddw xmm0, xmm2 ;ip[4]+ip[8] ip[0]+ip[12] aka b1 a1 - psubw xmm3, xmm2 ;ip[4]-ip[8] ip[0]-ip[12] aka c1 d1 - - movdqa xmm4, xmm0 - punpcklqdq xmm0, xmm3 ;d1 a1 - punpckhqdq xmm4, xmm3 ;c1 b1 - - movdqa xmm1, xmm4 ;c1 b1 - paddw xmm4, xmm0 ;dl+cl a1+b1 aka op[4] op[0] - psubw xmm0, xmm1 ;d1-c1 a1-b1 aka op[12] op[8] - - ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ; 13 12 11 10 03 02 01 00 - ; - ; 33 32 31 30 23 22 21 20 - ; - movdqa xmm3, xmm4 ; 13 12 11 10 03 02 01 00 - punpcklwd xmm4, xmm0 ; 23 03 22 02 21 01 20 00 - punpckhwd xmm3, xmm0 ; 33 13 32 12 31 11 30 10 - movdqa xmm1, xmm4 ; 23 03 22 02 21 01 20 00 - punpcklwd xmm4, xmm3 ; 31 21 11 01 30 20 10 00 - punpckhwd xmm1, xmm3 ; 33 23 13 03 32 22 12 02 - ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - movd xmm0, eax - pshufd xmm2, xmm1, 4eh ;ip[8] ip[12] - movdqa xmm3, xmm4 ;ip[4] ip[0] - - pshufd xmm0, xmm0, 0 ;03 03 03 03 03 03 03 03 - - paddw xmm4, xmm2 ;ip[4]+ip[8] ip[0]+ip[12] aka b1 a1 - psubw xmm3, xmm2 ;ip[4]-ip[8] ip[0]-ip[12] aka c1 d1 - - movdqa xmm5, xmm4 - punpcklqdq xmm4, xmm3 ;d1 a1 - punpckhqdq xmm5, xmm3 ;c1 b1 - - movdqa xmm1, xmm5 ;c1 b1 - paddw xmm5, xmm4 ;dl+cl a1+b1 aka op[4] op[0] - psubw xmm4, xmm1 ;d1-c1 a1-b1 aka op[12] op[8] - - paddw xmm5, xmm0 - paddw xmm4, xmm0 - psraw xmm5, 3 - psraw xmm4, 3 - - movd eax, xmm5 - movd ecx, xmm4 - psrldq xmm5, 4 - psrldq xmm4, 4 - mov word ptr[rdx+32*0], ax - mov word ptr[rdx+32*2], cx - shr eax, 16 - shr ecx, 16 - mov word ptr[rdx+32*4], ax - mov word ptr[rdx+32*6], cx - movd eax, xmm5 - movd ecx, xmm4 - psrldq xmm5, 4 - psrldq xmm4, 4 - mov word ptr[rdx+32*8], ax - mov word ptr[rdx+32*10], cx - shr eax, 16 - shr ecx, 16 - mov word ptr[rdx+32*12], ax - mov word ptr[rdx+32*14], cx - - movd eax, xmm5 - movd ecx, xmm4 - psrldq xmm5, 4 - psrldq xmm4, 4 - mov word ptr[rdx+32*1], ax - mov word ptr[rdx+32*3], cx - shr eax, 16 - shr ecx, 16 - mov word ptr[rdx+32*5], ax - mov word ptr[rdx+32*7], cx - movd eax, xmm5 - movd ecx, xmm4 - mov word ptr[rdx+32*9], ax - mov word ptr[rdx+32*11], cx - shr eax, 16 - shr ecx, 16 - mov word ptr[rdx+32*13], ax - mov word ptr[rdx+32*15], cx - - ; begin epilog - UNSHADOW_ARGS - pop rbp - ret diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/loopfilter_block_sse2_x86_64.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/loopfilter_block_sse2_x86_64.asm deleted file mode 100644 index 8d12f538..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/loopfilter_block_sse2_x86_64.asm +++ /dev/null @@ -1,817 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -%macro LF_ABS 2 - ; %1 value not preserved - ; %2 value preserved - ; output in %1 - movdqa scratch1, %2 ; v2 - - psubusb scratch1, %1 ; v2 - v1 - psubusb %1, %2 ; v1 - v2 - por %1, scratch1 ; abs(v2 - v1) -%endmacro - -%macro LF_FILTER_HEV_MASK 8-9 - - LF_ABS %1, %2 ; abs(p3 - p2) - LF_ABS %2, %3 ; abs(p2 - p1) - pmaxub %1, %2 ; accumulate mask -%if %0 == 8 - movdqa scratch2, %3 ; save p1 - LF_ABS scratch2, %4 ; abs(p1 - p0) -%endif - LF_ABS %4, %5 ; abs(p0 - q0) - LF_ABS %5, %6 ; abs(q0 - q1) -%if %0 == 8 - pmaxub %5, scratch2 ; accumulate hev -%else - pmaxub %5, %9 -%endif - pmaxub %1, %5 ; accumulate mask - - LF_ABS %3, %6 ; abs(p1 - q1) - LF_ABS %6, %7 ; abs(q1 - q2) - pmaxub %1, %6 ; accumulate mask - LF_ABS %7, %8 ; abs(q2 - q3) - pmaxub %1, %7 ; accumulate mask - - paddusb %4, %4 ; 2 * abs(p0 - q0) - pand %3, [GLOBAL(tfe)] - psrlw %3, 1 ; abs(p1 - q1) / 2 - paddusb %4, %3 ; abs(p0 - q0) * 2 + abs(p1 - q1) / 2 - - psubusb %1, [limit] - psubusb %4, [blimit] - por %1, %4 - pcmpeqb %1, zero ; mask - - psubusb %5, [thresh] - pcmpeqb %5, zero ; ~hev -%endmacro - -%macro LF_FILTER 6 - ; %1-%4: p1-q1 - ; %5: mask - ; %6: hev - - movdqa scratch2, %6 ; save hev - - pxor %1, [GLOBAL(t80)] ; ps1 - pxor %4, [GLOBAL(t80)] ; qs1 - movdqa scratch1, %1 - psubsb scratch1, %4 ; signed_char_clamp(ps1 - qs1) - pandn scratch2, scratch1 ; vp8_filter &= hev - - pxor %2, [GLOBAL(t80)] ; ps0 - pxor %3, [GLOBAL(t80)] ; qs0 - movdqa scratch1, %3 - psubsb scratch1, %2 ; qs0 - ps0 - paddsb scratch2, scratch1 ; vp8_filter += (qs0 - ps0) - paddsb scratch2, scratch1 ; vp8_filter += (qs0 - ps0) - paddsb scratch2, scratch1 ; vp8_filter += (qs0 - ps0) - pand %5, scratch2 ; &= mask - - movdqa scratch2, %5 - paddsb %5, [GLOBAL(t4)] ; Filter1 - paddsb scratch2, [GLOBAL(t3)] ; Filter2 - - ; Filter1 >> 3 - movdqa scratch1, zero - pcmpgtb scratch1, %5 - psrlw %5, 3 - pand scratch1, [GLOBAL(te0)] - pand %5, [GLOBAL(t1f)] - por %5, scratch1 - - psubsb %3, %5 ; qs0 - Filter1 - pxor %3, [GLOBAL(t80)] - - ; Filter2 >> 3 - movdqa scratch1, zero - pcmpgtb scratch1, scratch2 - psrlw scratch2, 3 - pand scratch1, [GLOBAL(te0)] - pand scratch2, [GLOBAL(t1f)] - por scratch2, scratch1 - - paddsb %2, scratch2 ; ps0 + Filter2 - pxor %2, [GLOBAL(t80)] - - ; outer tap adjustments - paddsb %5, [GLOBAL(t1)] - movdqa scratch1, zero - pcmpgtb scratch1, %5 - psrlw %5, 1 - pand scratch1, [GLOBAL(t80)] - pand %5, [GLOBAL(t7f)] - por %5, scratch1 - pand %5, %6 ; vp8_filter &= ~hev - - psubsb %4, %5 ; qs1 - vp8_filter - pxor %4, [GLOBAL(t80)] - - paddsb %1, %5 ; ps1 + vp8_filter - pxor %1, [GLOBAL(t80)] -%endmacro - -SECTION .text - -;void vp8_loop_filter_bh_y_sse2 -;( -; unsigned char *src_ptr, -; int src_pixel_step, -; const char *blimit, -; const char *limit, -; const char *thresh -;) -globalsym(vp8_loop_filter_bh_y_sse2) -sym(vp8_loop_filter_bh_y_sse2): - -%if LIBVPX_YASM_WIN64 - %define src rcx ; src_ptr - %define stride rdx ; src_pixel_step - %define blimit r8 - %define limit r9 - %define thresh r10 - - %define spp rax - %define stride3 r11 - %define stride5 r12 - %define stride7 r13 - - push rbp - mov rbp, rsp - SAVE_XMM 11 - push r12 - push r13 - mov thresh, arg(4) -%else - %define src rdi ; src_ptr - %define stride rsi ; src_pixel_step - %define blimit rdx - %define limit rcx - %define thresh r8 - - %define spp rax - %define stride3 r9 - %define stride5 r10 - %define stride7 r11 -%endif - - %define scratch1 xmm5 - %define scratch2 xmm6 - %define zero xmm7 - - %define i0 [src] - %define i1 [spp] - %define i2 [src + 2 * stride] - %define i3 [spp + 2 * stride] - %define i4 [src + 4 * stride] - %define i5 [spp + 4 * stride] - %define i6 [src + 2 * stride3] - %define i7 [spp + 2 * stride3] - %define i8 [src + 8 * stride] - %define i9 [spp + 8 * stride] - %define i10 [src + 2 * stride5] - %define i11 [spp + 2 * stride5] - %define i12 [src + 4 * stride3] - %define i13 [spp + 4 * stride3] - %define i14 [src + 2 * stride7] - %define i15 [spp + 2 * stride7] - - ; prep work - lea spp, [src + stride] - lea stride3, [stride + 2 * stride] - lea stride5, [stride3 + 2 * stride] - lea stride7, [stride3 + 4 * stride] - pxor zero, zero - - ; load the first set into registers - movdqa xmm0, i0 - movdqa xmm1, i1 - movdqa xmm2, i2 - movdqa xmm3, i3 - movdqa xmm4, i4 - movdqa xmm8, i5 - movdqa xmm9, i6 ; q2, will contain abs(p1-p0) - movdqa xmm10, i7 -LF_FILTER_HEV_MASK xmm0, xmm1, xmm2, xmm3, xmm4, xmm8, xmm9, xmm10 - - movdqa xmm1, i2 - movdqa xmm2, i3 - movdqa xmm3, i4 - movdqa xmm8, i5 -LF_FILTER xmm1, xmm2, xmm3, xmm8, xmm0, xmm4 - movdqa i2, xmm1 - movdqa i3, xmm2 - -; second set - movdqa i4, xmm3 - movdqa i5, xmm8 - - movdqa xmm0, i6 - movdqa xmm1, i7 - movdqa xmm2, i8 - movdqa xmm4, i9 - movdqa xmm10, i10 ; q2, will contain abs(p1-p0) - movdqa xmm11, i11 -LF_FILTER_HEV_MASK xmm3, xmm8, xmm0, xmm1, xmm2, xmm4, xmm10, xmm11, xmm9 - - movdqa xmm0, i6 - movdqa xmm1, i7 - movdqa xmm4, i8 - movdqa xmm8, i9 -LF_FILTER xmm0, xmm1, xmm4, xmm8, xmm3, xmm2 - movdqa i6, xmm0 - movdqa i7, xmm1 - -; last set - movdqa i8, xmm4 - movdqa i9, xmm8 - - movdqa xmm0, i10 - movdqa xmm1, i11 - movdqa xmm2, i12 - movdqa xmm3, i13 - movdqa xmm9, i14 ; q2, will contain abs(p1-p0) - movdqa xmm11, i15 -LF_FILTER_HEV_MASK xmm4, xmm8, xmm0, xmm1, xmm2, xmm3, xmm9, xmm11, xmm10 - - movdqa xmm0, i10 - movdqa xmm1, i11 - movdqa xmm3, i12 - movdqa xmm8, i13 -LF_FILTER xmm0, xmm1, xmm3, xmm8, xmm4, xmm2 - movdqa i10, xmm0 - movdqa i11, xmm1 - movdqa i12, xmm3 - movdqa i13, xmm8 - -%if LIBVPX_YASM_WIN64 - pop r13 - pop r12 - RESTORE_XMM - pop rbp -%endif - - ret - - -;void vp8_loop_filter_bv_y_sse2 -;( -; unsigned char *src_ptr, -; int src_pixel_step, -; const char *blimit, -; const char *limit, -; const char *thresh -;) - -globalsym(vp8_loop_filter_bv_y_sse2) -sym(vp8_loop_filter_bv_y_sse2): - -%if LIBVPX_YASM_WIN64 - %define src rcx ; src_ptr - %define stride rdx ; src_pixel_step - %define blimit r8 - %define limit r9 - %define thresh r10 - - %define spp rax - %define stride3 r11 - %define stride5 r12 - %define stride7 r13 - - push rbp - mov rbp, rsp - SAVE_XMM 15 - push r12 - push r13 - mov thresh, arg(4) -%else - %define src rdi - %define stride rsi - %define blimit rdx - %define limit rcx - %define thresh r8 - - %define spp rax - %define stride3 r9 - %define stride5 r10 - %define stride7 r11 -%endif - - %define scratch1 xmm5 - %define scratch2 xmm6 - %define zero xmm7 - - %define s0 [src] - %define s1 [spp] - %define s2 [src + 2 * stride] - %define s3 [spp + 2 * stride] - %define s4 [src + 4 * stride] - %define s5 [spp + 4 * stride] - %define s6 [src + 2 * stride3] - %define s7 [spp + 2 * stride3] - %define s8 [src + 8 * stride] - %define s9 [spp + 8 * stride] - %define s10 [src + 2 * stride5] - %define s11 [spp + 2 * stride5] - %define s12 [src + 4 * stride3] - %define s13 [spp + 4 * stride3] - %define s14 [src + 2 * stride7] - %define s15 [spp + 2 * stride7] - - %define i0 [rsp] - %define i1 [rsp + 16] - %define i2 [rsp + 32] - %define i3 [rsp + 48] - %define i4 [rsp + 64] - %define i5 [rsp + 80] - %define i6 [rsp + 96] - %define i7 [rsp + 112] - %define i8 [rsp + 128] - %define i9 [rsp + 144] - %define i10 [rsp + 160] - %define i11 [rsp + 176] - %define i12 [rsp + 192] - %define i13 [rsp + 208] - %define i14 [rsp + 224] - %define i15 [rsp + 240] - - ALIGN_STACK 16, rax - - ; reserve stack space - %define temp_storage 0 ; size is 256 (16*16) - %define stack_size 256 - sub rsp, stack_size - - ; prep work - lea spp, [src + stride] - lea stride3, [stride + 2 * stride] - lea stride5, [stride3 + 2 * stride] - lea stride7, [stride3 + 4 * stride] - - ; 8-f - movdqa xmm0, s8 - movdqa xmm1, xmm0 - punpcklbw xmm0, s9 ; 80 90 - punpckhbw xmm1, s9 ; 88 98 - - movdqa xmm2, s10 - movdqa xmm3, xmm2 - punpcklbw xmm2, s11 ; a0 b0 - punpckhbw xmm3, s11 ; a8 b8 - - movdqa xmm4, xmm0 - punpcklwd xmm0, xmm2 ; 80 90 a0 b0 - punpckhwd xmm4, xmm2 ; 84 94 a4 b4 - - movdqa xmm2, xmm1 - punpcklwd xmm1, xmm3 ; 88 98 a8 b8 - punpckhwd xmm2, xmm3 ; 8c 9c ac bc - - ; using xmm[0124] - ; work on next 4 rows - - movdqa xmm3, s12 - movdqa xmm5, xmm3 - punpcklbw xmm3, s13 ; c0 d0 - punpckhbw xmm5, s13 ; c8 d8 - - movdqa xmm6, s14 - movdqa xmm7, xmm6 - punpcklbw xmm6, s15 ; e0 f0 - punpckhbw xmm7, s15 ; e8 f8 - - movdqa xmm8, xmm3 - punpcklwd xmm3, xmm6 ; c0 d0 e0 f0 - punpckhwd xmm8, xmm6 ; c4 d4 e4 f4 - - movdqa xmm6, xmm5 - punpcklwd xmm5, xmm7 ; c8 d8 e8 f8 - punpckhwd xmm6, xmm7 ; cc dc ec fc - - ; pull the third and fourth sets together - - movdqa xmm7, xmm0 - punpckldq xmm0, xmm3 ; 80 90 a0 b0 c0 d0 e0 f0 - punpckhdq xmm7, xmm3 ; 82 92 a2 b2 c2 d2 e2 f2 - - movdqa xmm3, xmm4 - punpckldq xmm4, xmm8 ; 84 94 a4 b4 c4 d4 e4 f4 - punpckhdq xmm3, xmm8 ; 86 96 a6 b6 c6 d6 e6 f6 - - movdqa xmm8, xmm1 - punpckldq xmm1, xmm5 ; 88 88 a8 b8 c8 d8 e8 f8 - punpckhdq xmm8, xmm5 ; 8a 9a aa ba ca da ea fa - - movdqa xmm5, xmm2 - punpckldq xmm2, xmm6 ; 8c 9c ac bc cc dc ec fc - punpckhdq xmm5, xmm6 ; 8e 9e ae be ce de ee fe - - ; save the calculations. we only have 15 registers ... - movdqa i0, xmm0 - movdqa i1, xmm7 - movdqa i2, xmm4 - movdqa i3, xmm3 - movdqa i4, xmm1 - movdqa i5, xmm8 - movdqa i6, xmm2 - movdqa i7, xmm5 - - ; 0-7 - movdqa xmm0, s0 - movdqa xmm1, xmm0 - punpcklbw xmm0, s1 ; 00 10 - punpckhbw xmm1, s1 ; 08 18 - - movdqa xmm2, s2 - movdqa xmm3, xmm2 - punpcklbw xmm2, s3 ; 20 30 - punpckhbw xmm3, s3 ; 28 38 - - movdqa xmm4, xmm0 - punpcklwd xmm0, xmm2 ; 00 10 20 30 - punpckhwd xmm4, xmm2 ; 04 14 24 34 - - movdqa xmm2, xmm1 - punpcklwd xmm1, xmm3 ; 08 18 28 38 - punpckhwd xmm2, xmm3 ; 0c 1c 2c 3c - - ; using xmm[0124] - ; work on next 4 rows - - movdqa xmm3, s4 - movdqa xmm5, xmm3 - punpcklbw xmm3, s5 ; 40 50 - punpckhbw xmm5, s5 ; 48 58 - - movdqa xmm6, s6 - movdqa xmm7, xmm6 - punpcklbw xmm6, s7 ; 60 70 - punpckhbw xmm7, s7 ; 68 78 - - movdqa xmm8, xmm3 - punpcklwd xmm3, xmm6 ; 40 50 60 70 - punpckhwd xmm8, xmm6 ; 44 54 64 74 - - movdqa xmm6, xmm5 - punpcklwd xmm5, xmm7 ; 48 58 68 78 - punpckhwd xmm6, xmm7 ; 4c 5c 6c 7c - - ; pull the first two sets together - - movdqa xmm7, xmm0 - punpckldq xmm0, xmm3 ; 00 10 20 30 40 50 60 70 - punpckhdq xmm7, xmm3 ; 02 12 22 32 42 52 62 72 - - movdqa xmm3, xmm4 - punpckldq xmm4, xmm8 ; 04 14 24 34 44 54 64 74 - punpckhdq xmm3, xmm8 ; 06 16 26 36 46 56 66 76 - - movdqa xmm8, xmm1 - punpckldq xmm1, xmm5 ; 08 18 28 38 48 58 68 78 - punpckhdq xmm8, xmm5 ; 0a 1a 2a 3a 4a 5a 6a 7a - - movdqa xmm5, xmm2 - punpckldq xmm2, xmm6 ; 0c 1c 2c 3c 4c 5c 6c 7c - punpckhdq xmm5, xmm6 ; 0e 1e 2e 3e 4e 5e 6e 7e - ; final combination - - movdqa xmm6, xmm0 - punpcklqdq xmm0, i0 - punpckhqdq xmm6, i0 - - movdqa xmm9, xmm7 - punpcklqdq xmm7, i1 - punpckhqdq xmm9, i1 - - movdqa xmm10, xmm4 - punpcklqdq xmm4, i2 - punpckhqdq xmm10, i2 - - movdqa xmm11, xmm3 - punpcklqdq xmm3, i3 - punpckhqdq xmm11, i3 - - movdqa xmm12, xmm1 - punpcklqdq xmm1, i4 - punpckhqdq xmm12, i4 - - movdqa xmm13, xmm8 - punpcklqdq xmm8, i5 - punpckhqdq xmm13, i5 - - movdqa xmm14, xmm2 - punpcklqdq xmm2, i6 - punpckhqdq xmm14, i6 - - movdqa xmm15, xmm5 - punpcklqdq xmm5, i7 - punpckhqdq xmm15, i7 - - movdqa i0, xmm0 - movdqa i1, xmm6 - movdqa i2, xmm7 - movdqa i3, xmm9 - movdqa i4, xmm4 - movdqa i5, xmm10 - movdqa i6, xmm3 - movdqa i7, xmm11 - movdqa i8, xmm1 - movdqa i9, xmm12 - movdqa i10, xmm8 - movdqa i11, xmm13 - movdqa i12, xmm2 - movdqa i13, xmm14 - movdqa i14, xmm5 - movdqa i15, xmm15 - -; TRANSPOSED DATA AVAILABLE ON THE STACK - - movdqa xmm12, xmm6 - movdqa xmm13, xmm7 - - pxor zero, zero - -LF_FILTER_HEV_MASK xmm0, xmm12, xmm13, xmm9, xmm4, xmm10, xmm3, xmm11 - - movdqa xmm1, i2 - movdqa xmm2, i3 - movdqa xmm8, i4 - movdqa xmm9, i5 -LF_FILTER xmm1, xmm2, xmm8, xmm9, xmm0, xmm4 - movdqa i2, xmm1 - movdqa i3, xmm2 - -; second set - movdqa i4, xmm8 - movdqa i5, xmm9 - - movdqa xmm0, i6 - movdqa xmm1, i7 - movdqa xmm2, i8 - movdqa xmm4, i9 - movdqa xmm10, i10 ; q2, will contain abs(p1-p0) - movdqa xmm11, i11 -LF_FILTER_HEV_MASK xmm8, xmm9, xmm0, xmm1, xmm2, xmm4, xmm10, xmm11, xmm3 - - movdqa xmm0, i6 - movdqa xmm1, i7 - movdqa xmm3, i8 - movdqa xmm4, i9 -LF_FILTER xmm0, xmm1, xmm3, xmm4, xmm8, xmm2 - movdqa i6, xmm0 - movdqa i7, xmm1 - -; last set - movdqa i8, xmm3 - movdqa i9, xmm4 - - movdqa xmm0, i10 - movdqa xmm1, i11 - movdqa xmm2, i12 - movdqa xmm8, i13 - movdqa xmm9, i14 ; q2, will contain abs(p1-p0) - movdqa xmm11, i15 -LF_FILTER_HEV_MASK xmm3, xmm4, xmm0, xmm1, xmm2, xmm8, xmm9, xmm11, xmm10 - - movdqa xmm0, i10 - movdqa xmm1, i11 - movdqa xmm4, i12 - movdqa xmm8, i13 -LF_FILTER xmm0, xmm1, xmm4, xmm8, xmm3, xmm2 - movdqa i10, xmm0 - movdqa i11, xmm1 - movdqa i12, xmm4 - movdqa i13, xmm8 - - -; RESHUFFLE AND WRITE OUT - ; 8-f - movdqa xmm0, i8 - movdqa xmm1, xmm0 - punpcklbw xmm0, i9 ; 80 90 - punpckhbw xmm1, i9 ; 88 98 - - movdqa xmm2, i10 - movdqa xmm3, xmm2 - punpcklbw xmm2, i11 ; a0 b0 - punpckhbw xmm3, i11 ; a8 b8 - - movdqa xmm4, xmm0 - punpcklwd xmm0, xmm2 ; 80 90 a0 b0 - punpckhwd xmm4, xmm2 ; 84 94 a4 b4 - - movdqa xmm2, xmm1 - punpcklwd xmm1, xmm3 ; 88 98 a8 b8 - punpckhwd xmm2, xmm3 ; 8c 9c ac bc - - ; using xmm[0124] - ; work on next 4 rows - - movdqa xmm3, i12 - movdqa xmm5, xmm3 - punpcklbw xmm3, i13 ; c0 d0 - punpckhbw xmm5, i13 ; c8 d8 - - movdqa xmm6, i14 - movdqa xmm7, xmm6 - punpcklbw xmm6, i15 ; e0 f0 - punpckhbw xmm7, i15 ; e8 f8 - - movdqa xmm8, xmm3 - punpcklwd xmm3, xmm6 ; c0 d0 e0 f0 - punpckhwd xmm8, xmm6 ; c4 d4 e4 f4 - - movdqa xmm6, xmm5 - punpcklwd xmm5, xmm7 ; c8 d8 e8 f8 - punpckhwd xmm6, xmm7 ; cc dc ec fc - - ; pull the third and fourth sets together - - movdqa xmm7, xmm0 - punpckldq xmm0, xmm3 ; 80 90 a0 b0 c0 d0 e0 f0 - punpckhdq xmm7, xmm3 ; 82 92 a2 b2 c2 d2 e2 f2 - - movdqa xmm3, xmm4 - punpckldq xmm4, xmm8 ; 84 94 a4 b4 c4 d4 e4 f4 - punpckhdq xmm3, xmm8 ; 86 96 a6 b6 c6 d6 e6 f6 - - movdqa xmm8, xmm1 - punpckldq xmm1, xmm5 ; 88 88 a8 b8 c8 d8 e8 f8 - punpckhdq xmm8, xmm5 ; 8a 9a aa ba ca da ea fa - - movdqa xmm5, xmm2 - punpckldq xmm2, xmm6 ; 8c 9c ac bc cc dc ec fc - punpckhdq xmm5, xmm6 ; 8e 9e ae be ce de ee fe - - ; save the calculations. we only have 15 registers ... - movdqa i8, xmm0 - movdqa i9, xmm7 - movdqa i10, xmm4 - movdqa i11, xmm3 - movdqa i12, xmm1 - movdqa i13, xmm8 - movdqa i14, xmm2 - movdqa i15, xmm5 - - ; 0-7 - movdqa xmm0, i0 - movdqa xmm1, xmm0 - punpcklbw xmm0, i1 ; 00 10 - punpckhbw xmm1, i1 ; 08 18 - - movdqa xmm2, i2 - movdqa xmm3, xmm2 - punpcklbw xmm2, i3 ; 20 30 - punpckhbw xmm3, i3 ; 28 38 - - movdqa xmm4, xmm0 - punpcklwd xmm0, xmm2 ; 00 10 20 30 - punpckhwd xmm4, xmm2 ; 04 14 24 34 - - movdqa xmm2, xmm1 - punpcklwd xmm1, xmm3 ; 08 18 28 38 - punpckhwd xmm2, xmm3 ; 0c 1c 2c 3c - - ; using xmm[0124] - ; work on next 4 rows - - movdqa xmm3, i4 - movdqa xmm5, xmm3 - punpcklbw xmm3, i5 ; 40 50 - punpckhbw xmm5, i5 ; 48 58 - - movdqa xmm6, i6 - movdqa xmm7, xmm6 - punpcklbw xmm6, i7 ; 60 70 - punpckhbw xmm7, i7 ; 68 78 - - movdqa xmm8, xmm3 - punpcklwd xmm3, xmm6 ; 40 50 60 70 - punpckhwd xmm8, xmm6 ; 44 54 64 74 - - movdqa xmm6, xmm5 - punpcklwd xmm5, xmm7 ; 48 58 68 78 - punpckhwd xmm6, xmm7 ; 4c 5c 6c 7c - - ; pull the first two sets together - - movdqa xmm7, xmm0 - punpckldq xmm0, xmm3 ; 00 10 20 30 40 50 60 70 - punpckhdq xmm7, xmm3 ; 02 12 22 32 42 52 62 72 - - movdqa xmm3, xmm4 - punpckldq xmm4, xmm8 ; 04 14 24 34 44 54 64 74 - punpckhdq xmm3, xmm8 ; 06 16 26 36 46 56 66 76 - - movdqa xmm8, xmm1 - punpckldq xmm1, xmm5 ; 08 18 28 38 48 58 68 78 - punpckhdq xmm8, xmm5 ; 0a 1a 2a 3a 4a 5a 6a 7a - - movdqa xmm5, xmm2 - punpckldq xmm2, xmm6 ; 0c 1c 2c 3c 4c 5c 6c 7c - punpckhdq xmm5, xmm6 ; 0e 1e 2e 3e 4e 5e 6e 7e - ; final combination - - movdqa xmm6, xmm0 - punpcklqdq xmm0, i8 - punpckhqdq xmm6, i8 - - movdqa xmm9, xmm7 - punpcklqdq xmm7, i9 - punpckhqdq xmm9, i9 - - movdqa xmm10, xmm4 - punpcklqdq xmm4, i10 - punpckhqdq xmm10, i10 - - movdqa xmm11, xmm3 - punpcklqdq xmm3, i11 - punpckhqdq xmm11, i11 - - movdqa xmm12, xmm1 - punpcklqdq xmm1, i12 - punpckhqdq xmm12, i12 - - movdqa xmm13, xmm8 - punpcklqdq xmm8, i13 - punpckhqdq xmm13, i13 - - movdqa xmm14, xmm2 - punpcklqdq xmm2, i14 - punpckhqdq xmm14, i14 - - movdqa xmm15, xmm5 - punpcklqdq xmm5, i15 - punpckhqdq xmm15, i15 - - movdqa s0, xmm0 - movdqa s1, xmm6 - movdqa s2, xmm7 - movdqa s3, xmm9 - movdqa s4, xmm4 - movdqa s5, xmm10 - movdqa s6, xmm3 - movdqa s7, xmm11 - movdqa s8, xmm1 - movdqa s9, xmm12 - movdqa s10, xmm8 - movdqa s11, xmm13 - movdqa s12, xmm2 - movdqa s13, xmm14 - movdqa s14, xmm5 - movdqa s15, xmm15 - - ; free stack space - add rsp, stack_size - - ; un-ALIGN_STACK - pop rsp - -%if LIBVPX_YASM_WIN64 - pop r13 - pop r12 - RESTORE_XMM - pop rbp -%endif - - ret - -SECTION_RODATA -align 16 -te0: - times 16 db 0xe0 -align 16 -t7f: - times 16 db 0x7f -align 16 -tfe: - times 16 db 0xfe -align 16 -t1f: - times 16 db 0x1f -align 16 -t80: - times 16 db 0x80 -align 16 -t1: - times 16 db 0x01 -align 16 -t3: - times 16 db 0x03 -align 16 -t4: - times 16 db 0x04 diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/loopfilter_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/loopfilter_sse2.asm deleted file mode 100644 index ce5c3131..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/loopfilter_sse2.asm +++ /dev/null @@ -1,1642 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" -%define _t0 0 -%define _t1 _t0 + 16 -%define _p3 _t1 + 16 -%define _p2 _p3 + 16 -%define _p1 _p2 + 16 -%define _p0 _p1 + 16 -%define _q0 _p0 + 16 -%define _q1 _q0 + 16 -%define _q2 _q1 + 16 -%define _q3 _q2 + 16 -%define lf_var_size 160 - -; Use of pmaxub instead of psubusb to compute filter mask was seen -; in ffvp8 - -%macro LFH_FILTER_AND_HEV_MASK 1 -%if %1 - movdqa xmm2, [rdi+2*rax] ; q3 - movdqa xmm1, [rsi+2*rax] ; q2 - movdqa xmm4, [rsi+rax] ; q1 - movdqa xmm5, [rsi] ; q0 - neg rax ; negate pitch to deal with above border -%else - movlps xmm2, [rsi + rcx*2] ; q3 - movlps xmm1, [rsi + rcx] ; q2 - movlps xmm4, [rsi] ; q1 - movlps xmm5, [rsi + rax] ; q0 - - movhps xmm2, [rdi + rcx*2] - movhps xmm1, [rdi + rcx] - movhps xmm4, [rdi] - movhps xmm5, [rdi + rax] - - lea rsi, [rsi + rax*4] - lea rdi, [rdi + rax*4] - - movdqa [rsp+_q2], xmm1 ; store q2 - movdqa [rsp+_q1], xmm4 ; store q1 -%endif - movdqa xmm7, [rdx] ;limit - - movdqa xmm6, xmm1 ; q2 - movdqa xmm3, xmm4 ; q1 - - psubusb xmm1, xmm2 ; q2-=q3 - psubusb xmm2, xmm6 ; q3-=q2 - - psubusb xmm4, xmm6 ; q1-=q2 - psubusb xmm6, xmm3 ; q2-=q1 - - por xmm4, xmm6 ; abs(q2-q1) - por xmm1, xmm2 ; abs(q3-q2) - - movdqa xmm0, xmm5 ; q0 - pmaxub xmm1, xmm4 - - psubusb xmm5, xmm3 ; q0-=q1 - psubusb xmm3, xmm0 ; q1-=q0 - - por xmm5, xmm3 ; abs(q0-q1) - movdqa [rsp+_t0], xmm5 ; save to t0 - - pmaxub xmm1, xmm5 - -%if %1 - movdqa xmm2, [rsi+4*rax] ; p3 - movdqa xmm4, [rdi+4*rax] ; p2 - movdqa xmm6, [rsi+2*rax] ; p1 -%else - movlps xmm2, [rsi + rax] ; p3 - movlps xmm4, [rsi] ; p2 - movlps xmm6, [rsi + rcx] ; p1 - - movhps xmm2, [rdi + rax] - movhps xmm4, [rdi] - movhps xmm6, [rdi + rcx] - - movdqa [rsp+_p2], xmm4 ; store p2 - movdqa [rsp+_p1], xmm6 ; store p1 -%endif - - movdqa xmm5, xmm4 ; p2 - movdqa xmm3, xmm6 ; p1 - - psubusb xmm4, xmm2 ; p2-=p3 - psubusb xmm2, xmm5 ; p3-=p2 - - psubusb xmm3, xmm5 ; p1-=p2 - pmaxub xmm1, xmm4 ; abs(p3 - p2) - - psubusb xmm5, xmm6 ; p2-=p1 - pmaxub xmm1, xmm2 ; abs(p3 - p2) - - pmaxub xmm1, xmm5 ; abs(p2 - p1) - movdqa xmm2, xmm6 ; p1 - - pmaxub xmm1, xmm3 ; abs(p2 - p1) -%if %1 - movdqa xmm4, [rsi+rax] ; p0 - movdqa xmm3, [rdi] ; q1 -%else - movlps xmm4, [rsi + rcx*2] ; p0 - movhps xmm4, [rdi + rcx*2] - movdqa xmm3, [rsp+_q1] ; q1 -%endif - - movdqa xmm5, xmm4 ; p0 - psubusb xmm4, xmm6 ; p0-=p1 - - psubusb xmm6, xmm5 ; p1-=p0 - - por xmm6, xmm4 ; abs(p1 - p0) - mov rdx, arg(2) ; get blimit - - movdqa [rsp+_t1], xmm6 ; save to t1 - - movdqa xmm4, xmm3 ; q1 - pmaxub xmm1, xmm6 - - psubusb xmm3, xmm2 ; q1-=p1 - psubusb xmm2, xmm4 ; p1-=q1 - - psubusb xmm1, xmm7 - por xmm2, xmm3 ; abs(p1-q1) - - movdqa xmm7, [rdx] ; blimit - mov rdx, arg(4) ; hev get thresh - - movdqa xmm3, xmm0 ; q0 - pand xmm2, [GLOBAL(tfe)] ; set lsb of each byte to zero - - movdqa xmm6, xmm5 ; p0 - psrlw xmm2, 1 ; abs(p1-q1)/2 - - psubusb xmm5, xmm3 ; p0-=q0 - psubusb xmm3, xmm6 ; q0-=p0 - por xmm5, xmm3 ; abs(p0 - q0) - - paddusb xmm5, xmm5 ; abs(p0-q0)*2 - - movdqa xmm4, [rsp+_t0] ; hev get abs (q1 - q0) - movdqa xmm3, [rsp+_t1] ; get abs (p1 - p0) - - paddusb xmm5, xmm2 ; abs (p0 - q0) *2 + abs(p1-q1)/2 - - movdqa xmm2, [rdx] ; hev - - psubusb xmm5, xmm7 ; abs (p0 - q0) *2 + abs(p1-q1)/2 > blimit - psubusb xmm4, xmm2 ; hev - - psubusb xmm3, xmm2 ; hev - por xmm1, xmm5 - - pxor xmm7, xmm7 - paddb xmm4, xmm3 ; hev abs(q1 - q0) > thresh || abs(p1 - p0) > thresh - - pcmpeqb xmm4, xmm5 ; hev - pcmpeqb xmm3, xmm3 ; hev - - pcmpeqb xmm1, xmm7 ; mask xmm1 - pxor xmm4, xmm3 ; hev -%endmacro - -%macro B_FILTER 1 - movdqa xmm3, [GLOBAL(t80)] -%if %1 == 0 - movdqa xmm2, [rsp+_p1] ; p1 - movdqa xmm7, [rsp+_q1] ; q1 -%elif %1 == 1 - movdqa xmm2, [rsi+2*rax] ; p1 - movdqa xmm7, [rdi] ; q1 -%elif %1 == 2 - movdqa xmm2, [rsp+_p1] ; p1 - movdqa xmm6, [rsp+_p0] ; p0 - movdqa xmm0, [rsp+_q0] ; q0 - movdqa xmm7, [rsp+_q1] ; q1 -%endif - - pxor xmm2, xmm3 ; p1 offset to convert to signed values - pxor xmm7, xmm3 ; q1 offset to convert to signed values - - psubsb xmm2, xmm7 ; p1 - q1 - pxor xmm6, xmm3 ; offset to convert to signed values - - pand xmm2, xmm4 ; high var mask (hvm)(p1 - q1) - pxor xmm0, xmm3 ; offset to convert to signed values - - movdqa xmm3, xmm0 ; q0 - psubsb xmm0, xmm6 ; q0 - p0 - paddsb xmm2, xmm0 ; 1 * (q0 - p0) + hvm(p1 - q1) - paddsb xmm2, xmm0 ; 2 * (q0 - p0) + hvm(p1 - q1) - paddsb xmm2, xmm0 ; 3 * (q0 - p0) + hvm(p1 - q1) - pand xmm1, xmm2 ; mask filter values we don't care about - - movdqa xmm2, xmm1 - paddsb xmm1, [GLOBAL(t4)] ; 3* (q0 - p0) + hvm(p1 - q1) + 4 - paddsb xmm2, [GLOBAL(t3)] ; 3* (q0 - p0) + hvm(p1 - q1) + 3 - - punpckhbw xmm5, xmm2 ; axbxcxdx - punpcklbw xmm2, xmm2 ; exfxgxhx - - punpcklbw xmm0, xmm1 ; exfxgxhx - psraw xmm5, 11 ; sign extended shift right by 3 - - punpckhbw xmm1, xmm1 ; axbxcxdx - psraw xmm2, 11 ; sign extended shift right by 3 - - packsswb xmm2, xmm5 ; (3* (q0 - p0) + hvm(p1 - q1) + 3) >> 3; - psraw xmm0, 11 ; sign extended shift right by 3 - - psraw xmm1, 11 ; sign extended shift right by 3 - movdqa xmm5, xmm0 ; save results - - packsswb xmm0, xmm1 ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>3 - - paddsb xmm6, xmm2 ; p0+= p0 add - - movdqa xmm2, [GLOBAL(ones)] - paddsw xmm5, xmm2 - paddsw xmm1, xmm2 - psraw xmm5, 1 ; partial shifted one more time for 2nd tap - psraw xmm1, 1 ; partial shifted one more time for 2nd tap - packsswb xmm5, xmm1 ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>4 - movdqa xmm2, [GLOBAL(t80)] - -%if %1 == 0 - movdqa xmm1, [rsp+_p1] ; p1 - lea rsi, [rsi + rcx*2] - lea rdi, [rdi + rcx*2] -%elif %1 == 1 - movdqa xmm1, [rsi+2*rax] ; p1 -%elif %1 == 2 - movdqa xmm1, [rsp+_p1] ; p1 -%endif - - pandn xmm4, xmm5 ; high edge variance additive - pxor xmm6, xmm2 ; unoffset - - pxor xmm1, xmm2 ; reoffset - psubsb xmm3, xmm0 ; q0-= q0 add - - paddsb xmm1, xmm4 ; p1+= p1 add - pxor xmm3, xmm2 ; unoffset - - pxor xmm1, xmm2 ; unoffset - psubsb xmm7, xmm4 ; q1-= q1 add - - pxor xmm7, xmm2 ; unoffset -%if %1 == 0 - movq [rsi], xmm6 ; p0 - movhps [rdi], xmm6 - movq [rsi + rax], xmm1 ; p1 - movhps [rdi + rax], xmm1 - movq [rsi + rcx], xmm3 ; q0 - movhps [rdi + rcx], xmm3 - movq [rsi + rcx*2], xmm7 ; q1 - movhps [rdi + rcx*2], xmm7 -%elif %1 == 1 - movdqa [rsi+rax], xmm6 ; write back - movdqa [rsi+2*rax], xmm1 ; write back - movdqa [rsi], xmm3 ; write back - movdqa [rdi], xmm7 ; write back -%endif - -%endmacro - -SECTION .text - -%if ABI_IS_32BIT - -;void vp8_loop_filter_horizontal_edge_sse2 -;( -; unsigned char *src_ptr, -; int src_pixel_step, -; const char *blimit, -; const char *limit, -; const char *thresh, -;) -globalsym(vp8_loop_filter_horizontal_edge_sse2) -sym(vp8_loop_filter_horizontal_edge_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 5 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, lf_var_size - - mov rsi, arg(0) ;src_ptr - movsxd rax, dword ptr arg(1) ;src_pixel_step - - mov rdx, arg(3) ;limit - - lea rdi, [rsi+rax] ; rdi points to row +1 for indirect addressing - - ; calculate breakout conditions and high edge variance - LFH_FILTER_AND_HEV_MASK 1 - ; filter and write back the result - B_FILTER 1 - - add rsp, lf_var_size - pop rsp - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -%endif - -;void vp8_loop_filter_horizontal_edge_uv_sse2 -;( -; unsigned char *src_ptr, -; int src_pixel_step, -; const char *blimit, -; const char *limit, -; const char *thresh, -; int count -;) -globalsym(vp8_loop_filter_horizontal_edge_uv_sse2) -sym(vp8_loop_filter_horizontal_edge_uv_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, lf_var_size - - mov rsi, arg(0) ; u - mov rdi, arg(5) ; v - movsxd rax, dword ptr arg(1) ; src_pixel_step - mov rcx, rax - neg rax ; negate pitch to deal with above border - - mov rdx, arg(3) ;limit - - lea rsi, [rsi + rcx] - lea rdi, [rdi + rcx] - - ; calculate breakout conditions and high edge variance - LFH_FILTER_AND_HEV_MASK 0 - ; filter and write back the result - B_FILTER 0 - - add rsp, lf_var_size - pop rsp - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - - -%macro MB_FILTER_AND_WRITEBACK 1 - movdqa xmm3, [GLOBAL(t80)] -%if %1 == 0 - movdqa xmm2, [rsp+_p1] ; p1 - movdqa xmm7, [rsp+_q1] ; q1 -%elif %1 == 1 - movdqa xmm2, [rsi+2*rax] ; p1 - movdqa xmm7, [rdi] ; q1 - - mov rcx, rax - neg rcx -%elif %1 == 2 - movdqa xmm2, [rsp+_p1] ; p1 - movdqa xmm6, [rsp+_p0] ; p0 - movdqa xmm0, [rsp+_q0] ; q0 - movdqa xmm7, [rsp+_q1] ; q1 -%endif - - pxor xmm2, xmm3 ; p1 offset to convert to signed values - pxor xmm7, xmm3 ; q1 offset to convert to signed values - pxor xmm6, xmm3 ; offset to convert to signed values - pxor xmm0, xmm3 ; offset to convert to signed values - - psubsb xmm2, xmm7 ; p1 - q1 - - movdqa xmm3, xmm0 ; q0 - psubsb xmm0, xmm6 ; q0 - p0 - paddsb xmm2, xmm0 ; 1 * (q0 - p0) + (p1 - q1) - paddsb xmm2, xmm0 ; 2 * (q0 - p0) - paddsb xmm2, xmm0 ; 3 * (q0 - p0) + (p1 - q1) - pand xmm1, xmm2 ; mask filter values we don't care about - - movdqa xmm2, xmm1 ; vp8_filter - - pand xmm2, xmm4 ; Filter2 = vp8_filter & hev - pxor xmm0, xmm0 - - pandn xmm4, xmm1 ; vp8_filter&=~hev - pxor xmm1, xmm1 - - punpcklbw xmm0, xmm4 ; Filter 2 (hi) - punpckhbw xmm1, xmm4 ; Filter 2 (lo) - - movdqa xmm5, xmm2 - - movdqa xmm4, [GLOBAL(s9)] - paddsb xmm5, [GLOBAL(t3)] ; vp8_signed_char_clamp(Filter2 + 3) - paddsb xmm2, [GLOBAL(t4)] ; vp8_signed_char_clamp(Filter2 + 4) - - pmulhw xmm1, xmm4 ; Filter 2 (lo) * 9 - pmulhw xmm0, xmm4 ; Filter 2 (hi) * 9 - - punpckhbw xmm7, xmm5 ; axbxcxdx - punpcklbw xmm5, xmm5 ; exfxgxhx - - psraw xmm7, 11 ; sign extended shift right by 3 - - psraw xmm5, 11 ; sign extended shift right by 3 - punpckhbw xmm4, xmm2 ; axbxcxdx - - punpcklbw xmm2, xmm2 ; exfxgxhx - psraw xmm4, 11 ; sign extended shift right by 3 - - packsswb xmm5, xmm7 ; Filter2 >>=3; - psraw xmm2, 11 ; sign extended shift right by 3 - - packsswb xmm2, xmm4 ; Filter1 >>=3; - - paddsb xmm6, xmm5 ; ps0 =ps0 + Fitler2 - - psubsb xmm3, xmm2 ; qs0 =qs0 - Filter1 - movdqa xmm7, xmm1 - - movdqa xmm4, [GLOBAL(s63)] - movdqa xmm5, xmm0 - movdqa xmm2, xmm5 - paddw xmm0, xmm4 ; Filter 2 (hi) * 9 + 63 - paddw xmm1, xmm4 ; Filter 2 (lo) * 9 + 63 - movdqa xmm4, xmm7 - - paddw xmm5, xmm5 ; Filter 2 (hi) * 18 - - paddw xmm7, xmm7 ; Filter 2 (lo) * 18 - paddw xmm5, xmm0 ; Filter 2 (hi) * 27 + 63 - - paddw xmm7, xmm1 ; Filter 2 (lo) * 27 + 63 - paddw xmm2, xmm0 ; Filter 2 (hi) * 18 + 63 - psraw xmm0, 7 ; (Filter 2 (hi) * 9 + 63) >> 7 - - paddw xmm4, xmm1 ; Filter 2 (lo) * 18 + 63 - psraw xmm1, 7 ; (Filter 2 (lo) * 9 + 63) >> 7 - psraw xmm2, 7 ; (Filter 2 (hi) * 18 + 63) >> 7 - - packsswb xmm0, xmm1 ; u1 = vp8_signed_char_clamp((63 + Filter2 * 9)>>7) - - psraw xmm4, 7 ; (Filter 2 (lo) * 18 + 63) >> 7 - psraw xmm5, 7 ; (Filter 2 (hi) * 27 + 63) >> 7 - psraw xmm7, 7 ; (Filter 2 (lo) * 27 + 63) >> 7 - - packsswb xmm5, xmm7 ; u3 = vp8_signed_char_clamp((63 + Filter2 * 27)>>7) - packsswb xmm2, xmm4 ; u2 = vp8_signed_char_clamp((63 + Filter2 * 18)>>7) - movdqa xmm7, [GLOBAL(t80)] - -%if %1 == 0 - movdqa xmm1, [rsp+_q1] ; q1 - movdqa xmm4, [rsp+_p1] ; p1 - lea rsi, [rsi+rcx*2] - lea rdi, [rdi+rcx*2] - -%elif %1 == 1 - movdqa xmm1, [rdi] ; q1 - movdqa xmm4, [rsi+rax*2] ; p1 -%elif %1 == 2 - movdqa xmm4, [rsp+_p1] ; p1 - movdqa xmm1, [rsp+_q1] ; q1 -%endif - - pxor xmm1, xmm7 - pxor xmm4, xmm7 - - psubsb xmm3, xmm5 ; sq = vp8_signed_char_clamp(qs0 - u3) - paddsb xmm6, xmm5 ; sp = vp8_signed_char_clamp(ps0 - u3) - psubsb xmm1, xmm2 ; sq = vp8_signed_char_clamp(qs1 - u2) - paddsb xmm4, xmm2 ; sp = vp8_signed_char_clamp(ps1 - u2) - -%if %1 == 1 - movdqa xmm2, [rdi+rax*4] ; p2 - movdqa xmm5, [rdi+rcx] ; q2 -%else - movdqa xmm2, [rsp+_p2] ; p2 - movdqa xmm5, [rsp+_q2] ; q2 -%endif - - pxor xmm1, xmm7 ; *oq1 = sq^0x80; - pxor xmm4, xmm7 ; *op1 = sp^0x80; - pxor xmm2, xmm7 - pxor xmm5, xmm7 - paddsb xmm2, xmm0 ; sp = vp8_signed_char_clamp(ps2 - u) - psubsb xmm5, xmm0 ; sq = vp8_signed_char_clamp(qs2 - u) - pxor xmm2, xmm7 ; *op2 = sp^0x80; - pxor xmm5, xmm7 ; *oq2 = sq^0x80; - pxor xmm3, xmm7 ; *oq0 = sq^0x80 - pxor xmm6, xmm7 ; *oq0 = sp^0x80 -%if %1 == 0 - movq [rsi], xmm6 ; p0 - movhps [rdi], xmm6 - movq [rsi + rcx], xmm3 ; q0 - movhps [rdi + rcx], xmm3 - lea rdx, [rcx + rcx*2] - movq [rsi+rcx*2], xmm1 ; q1 - movhps [rdi+rcx*2], xmm1 - - movq [rsi + rax], xmm4 ; p1 - movhps [rdi + rax], xmm4 - - movq [rsi+rax*2], xmm2 ; p2 - movhps [rdi+rax*2], xmm2 - - movq [rsi+rdx], xmm5 ; q2 - movhps [rdi+rdx], xmm5 -%elif %1 == 1 - movdqa [rdi+rcx], xmm5 ; q2 - movdqa [rdi], xmm1 ; q1 - movdqa [rsi], xmm3 ; q0 - movdqa [rsi+rax ], xmm6 ; p0 - movdqa [rsi+rax*2], xmm4 ; p1 - movdqa [rdi+rax*4], xmm2 ; p2 -%elif %1 == 2 - movdqa [rsp+_p1], xmm4 ; p1 - movdqa [rsp+_p0], xmm6 ; p0 - movdqa [rsp+_q0], xmm3 ; q0 - movdqa [rsp+_q1], xmm1 ; q1 -%endif - -%endmacro - - -;void vp8_mbloop_filter_horizontal_edge_sse2 -;( -; unsigned char *src_ptr, -; int src_pixel_step, -; const char *blimit, -; const char *limit, -; const char *thresh, -;) -globalsym(vp8_mbloop_filter_horizontal_edge_sse2) -sym(vp8_mbloop_filter_horizontal_edge_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 5 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, lf_var_size - - mov rsi, arg(0) ;src_ptr - movsxd rax, dword ptr arg(1) ;src_pixel_step - mov rdx, arg(3) ;limit - - lea rdi, [rsi+rax] ; rdi points to row +1 for indirect addressing - - ; calculate breakout conditions and high edge variance - LFH_FILTER_AND_HEV_MASK 1 - ; filter and write back the results - MB_FILTER_AND_WRITEBACK 1 - - add rsp, lf_var_size - pop rsp - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - - -;void vp8_mbloop_filter_horizontal_edge_uv_sse2 -;( -; unsigned char *u, -; int src_pixel_step, -; const char *blimit, -; const char *limit, -; const char *thresh, -; unsigned char *v -;) -globalsym(vp8_mbloop_filter_horizontal_edge_uv_sse2) -sym(vp8_mbloop_filter_horizontal_edge_uv_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, lf_var_size - - mov rsi, arg(0) ; u - mov rdi, arg(5) ; v - movsxd rax, dword ptr arg(1) ; src_pixel_step - mov rcx, rax - neg rax ; negate pitch to deal with above border - mov rdx, arg(3) ;limit - - lea rsi, [rsi + rcx] - lea rdi, [rdi + rcx] - - ; calculate breakout conditions and high edge variance - LFH_FILTER_AND_HEV_MASK 0 - ; filter and write back the results - MB_FILTER_AND_WRITEBACK 0 - - add rsp, lf_var_size - pop rsp - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - - -%macro TRANSPOSE_16X8 2 - movq xmm4, [rsi] ; xx xx xx xx xx xx xx xx 07 06 05 04 03 02 01 00 - movq xmm1, [rdi] ; xx xx xx xx xx xx xx xx 17 16 15 14 13 12 11 10 - movq xmm0, [rsi+2*rax] ; xx xx xx xx xx xx xx xx 27 26 25 24 23 22 21 20 - movq xmm7, [rdi+2*rax] ; xx xx xx xx xx xx xx xx 37 36 35 34 33 32 31 30 - movq xmm5, [rsi+4*rax] ; xx xx xx xx xx xx xx xx 47 46 45 44 43 42 41 40 - movq xmm2, [rdi+4*rax] ; xx xx xx xx xx xx xx xx 57 56 55 54 53 52 51 50 - - punpcklbw xmm4, xmm1 ; 17 07 16 06 15 05 14 04 13 03 12 02 11 01 10 00 - - movq xmm1, [rdi+2*rcx] ; xx xx xx xx xx xx xx xx 77 76 75 74 73 72 71 70 - - movdqa xmm3, xmm4 ; 17 07 16 06 15 05 14 04 13 03 12 02 11 01 10 00 - punpcklbw xmm0, xmm7 ; 37 27 36 36 35 25 34 24 33 23 32 22 31 21 30 20 - - movq xmm7, [rsi+2*rcx] ; xx xx xx xx xx xx xx xx 67 66 65 64 63 62 61 60 - - punpcklbw xmm5, xmm2 ; 57 47 56 46 55 45 54 44 53 43 52 42 51 41 50 40 -%if %1 - lea rsi, [rsi+rax*8] - lea rdi, [rdi+rax*8] -%else - mov rsi, arg(5) ; v_ptr -%endif - - movdqa xmm6, xmm5 ; 57 47 56 46 55 45 54 44 53 43 52 42 51 41 50 40 - punpcklbw xmm7, xmm1 ; 77 67 76 66 75 65 74 64 73 63 72 62 71 61 70 60 - punpcklwd xmm5, xmm7 ; 73 63 53 43 72 62 52 42 71 61 51 41 70 60 50 40 - punpckhwd xmm6, xmm7 ; 77 67 57 47 76 66 56 46 75 65 55 45 74 64 54 44 - punpcklwd xmm3, xmm0 ; 33 23 13 03 32 22 12 02 31 21 11 01 30 20 10 00 - -%if %1 == 0 - lea rdi, [rsi + rax - 4] ; rdi points to row +1 for indirect addressing - lea rsi, [rsi - 4] -%endif - - movdqa xmm2, xmm3 ; 33 23 13 03 32 22 12 02 31 21 11 01 30 20 10 00 - punpckhwd xmm4, xmm0 ; 37 27 17 07 36 26 16 06 35 25 15 05 34 24 14 04 - - movdqa xmm7, xmm4 ; 37 27 17 07 36 26 16 06 35 25 15 05 34 24 14 04 - punpckhdq xmm3, xmm5 ; 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02 - - punpckhdq xmm7, xmm6 ; 77 67 57 47 37 27 17 07 76 66 56 46 36 26 16 06 - - punpckldq xmm4, xmm6 ; 75 65 55 45 35 25 15 05 74 64 54 44 34 24 14 04 - - punpckldq xmm2, xmm5 ; 71 61 51 41 31 21 11 01 70 60 50 40 30 20 10 00 - - movdqa [rsp+_t0], xmm2 ; save to free XMM2 - - movq xmm2, [rsi] ; xx xx xx xx xx xx xx xx 87 86 85 84 83 82 81 80 - movq xmm6, [rdi] ; xx xx xx xx xx xx xx xx 97 96 95 94 93 92 91 90 - movq xmm0, [rsi+2*rax] ; xx xx xx xx xx xx xx xx a7 a6 a5 a4 a3 a2 a1 a0 - movq xmm5, [rdi+2*rax] ; xx xx xx xx xx xx xx xx b7 b6 b5 b4 b3 b2 b1 b0 - movq xmm1, [rsi+4*rax] ; xx xx xx xx xx xx xx xx c7 c6 c5 c4 c3 c2 c1 c0 - - punpcklbw xmm2, xmm6 ; 97 87 96 86 95 85 94 84 93 83 92 82 91 81 90 80 - - movq xmm6, [rdi+4*rax] ; xx xx xx xx xx xx xx xx d7 d6 d5 d4 d3 d2 d1 d0 - - punpcklbw xmm0, xmm5 ; b7 a7 b6 a6 b5 a5 b4 a4 b3 a3 b2 a2 b1 a1 b0 a0 - - movq xmm5, [rsi+2*rcx] ; xx xx xx xx xx xx xx xx e7 e6 e5 e4 e3 e2 e1 e0 - - punpcklbw xmm1, xmm6 ; d7 c7 d6 c6 d5 c5 d4 c4 d3 c3 d2 c2 d1 e1 d0 c0 - - movq xmm6, [rdi+2*rcx] ; xx xx xx xx xx xx xx xx f7 f6 f5 f4 f3 f2 f1 f0 - - punpcklbw xmm5, xmm6 ; f7 e7 f6 e6 f5 e5 f4 e4 f3 e3 f2 e2 f1 e1 f0 e0 - - movdqa xmm6, xmm1 ; - punpckhwd xmm6, xmm5 ; f7 e7 d7 c7 f6 e6 d6 c6 f5 e5 d5 c5 f4 e4 d4 c4 - - punpcklwd xmm1, xmm5 ; f3 e3 d3 c3 f2 e2 d2 c2 f1 e1 d1 c1 f0 e0 d0 c0 - movdqa xmm5, xmm2 ; 97 87 96 86 95 85 94 84 93 83 92 82 91 81 90 80 - - punpcklwd xmm5, xmm0 ; b3 a3 93 83 b2 a2 92 82 b1 a1 91 81 b0 a0 90 80 - - punpckhwd xmm2, xmm0 ; b7 a7 97 87 b6 a6 96 86 b5 a5 95 85 b4 a4 94 84 - - movdqa xmm0, xmm5 - punpckldq xmm0, xmm1 ; f1 e1 d1 c1 b1 a1 91 81 f0 e0 d0 c0 b0 a0 90 80 - - punpckhdq xmm5, xmm1 ; f3 e3 d3 c3 b3 a3 93 83 f2 e2 d2 c2 b2 a2 92 82 - movdqa xmm1, xmm2 ; b7 a7 97 87 b6 a6 96 86 b5 a5 95 85 b4 a4 94 84 - - punpckldq xmm1, xmm6 ; f5 e5 d5 c5 b5 a5 95 85 f4 e4 d4 c4 b4 a4 94 84 - - punpckhdq xmm2, xmm6 ; f7 e7 d7 c7 b7 a7 97 87 f6 e6 d6 c6 b6 a6 96 86 - movdqa xmm6, xmm7 ; 77 67 57 47 37 27 17 07 76 66 56 46 36 26 16 06 - - punpcklqdq xmm6, xmm2 ; f6 e6 d6 c6 b6 a6 96 86 76 66 56 46 36 26 16 06 - - punpckhqdq xmm7, xmm2 ; f7 e7 d7 c7 b7 a7 97 87 77 67 57 47 37 27 17 07 - -%if %2 == 0 - movdqa [rsp+_q3], xmm7 ; save 7 - movdqa [rsp+_q2], xmm6 ; save 6 -%endif - movdqa xmm2, xmm3 ; 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02 - punpckhqdq xmm3, xmm5 ; f3 e3 d3 c3 b3 a3 93 83 73 63 53 43 33 23 13 03 - punpcklqdq xmm2, xmm5 ; f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02 - movdqa [rsp+_p1], xmm2 ; save 2 - - movdqa xmm5, xmm4 ; 75 65 55 45 35 25 15 05 74 64 54 44 34 24 14 04 - punpcklqdq xmm4, xmm1 ; f4 e4 d4 c4 b4 a4 94 84 74 64 54 44 34 24 14 04 - movdqa [rsp+_p0], xmm3 ; save 3 - - punpckhqdq xmm5, xmm1 ; f5 e5 d5 c5 b5 a5 95 85 75 65 55 45 35 25 15 05 - - movdqa [rsp+_q0], xmm4 ; save 4 - movdqa [rsp+_q1], xmm5 ; save 5 - movdqa xmm1, [rsp+_t0] - - movdqa xmm2, xmm1 ; - punpckhqdq xmm1, xmm0 ; f1 e1 d1 c1 b1 a1 91 81 71 61 51 41 31 21 11 01 - punpcklqdq xmm2, xmm0 ; f0 e0 d0 c0 b0 a0 90 80 70 60 50 40 30 20 10 00 - -%if %2 == 0 - movdqa [rsp+_p2], xmm1 - movdqa [rsp+_p3], xmm2 -%endif - -%endmacro - -%macro LFV_FILTER_MASK_HEV_MASK 0 - movdqa xmm0, xmm6 ; q2 - psubusb xmm0, xmm7 ; q2-q3 - - psubusb xmm7, xmm6 ; q3-q2 - movdqa xmm4, xmm5 ; q1 - - por xmm7, xmm0 ; abs (q3-q2) - psubusb xmm4, xmm6 ; q1-q2 - - movdqa xmm0, xmm1 - psubusb xmm6, xmm5 ; q2-q1 - - por xmm6, xmm4 ; abs (q2-q1) - psubusb xmm0, xmm2 ; p2 - p3; - - psubusb xmm2, xmm1 ; p3 - p2; - por xmm0, xmm2 ; abs(p2-p3) - - movdqa xmm5, [rsp+_p1] ; p1 - pmaxub xmm0, xmm7 - - movdqa xmm2, xmm5 ; p1 - psubusb xmm5, xmm1 ; p1-p2 - psubusb xmm1, xmm2 ; p2-p1 - - movdqa xmm7, xmm3 ; p0 - psubusb xmm7, xmm2 ; p0-p1 - - por xmm1, xmm5 ; abs(p2-p1) - pmaxub xmm0, xmm6 - - pmaxub xmm0, xmm1 - movdqa xmm1, xmm2 ; p1 - - psubusb xmm2, xmm3 ; p1-p0 - - por xmm2, xmm7 ; abs(p1-p0) - - pmaxub xmm0, xmm2 - - movdqa xmm5, [rsp+_q0] ; q0 - movdqa xmm7, [rsp+_q1] ; q1 - - mov rdx, arg(3) ; limit - - movdqa xmm6, xmm5 ; q0 - movdqa xmm4, xmm7 ; q1 - - psubusb xmm5, xmm7 ; q0-q1 - psubusb xmm7, xmm6 ; q1-q0 - - por xmm7, xmm5 ; abs(q1-q0) - - pmaxub xmm0, xmm7 - - psubusb xmm0, [rdx] ; limit - - mov rdx, arg(2) ; blimit - movdqa xmm5, xmm4 ; q1 - - psubusb xmm5, xmm1 ; q1-=p1 - psubusb xmm1, xmm4 ; p1-=q1 - - por xmm5, xmm1 ; abs(p1-q1) - movdqa xmm1, xmm3 ; p0 - - pand xmm5, [GLOBAL(tfe)] ; set lsb of each byte to zero - psubusb xmm1, xmm6 ; p0-q0 - - movdqa xmm4, [rdx] ; blimit - mov rdx, arg(4) ; get thresh - - psrlw xmm5, 1 ; abs(p1-q1)/2 - psubusb xmm6, xmm3 ; q0-p0 - - por xmm1, xmm6 ; abs(q0-p0) - paddusb xmm1, xmm1 ; abs(q0-p0)*2 - movdqa xmm3, [rdx] - - paddusb xmm1, xmm5 ; abs (p0 - q0) *2 + abs(p1-q1)/2 - psubusb xmm2, xmm3 ; abs(q1 - q0) > thresh - - psubusb xmm7, xmm3 ; abs(p1 - p0)> thresh - - psubusb xmm1, xmm4 ; abs (p0 - q0) *2 + abs(p1-q1)/2 > blimit - por xmm2, xmm7 ; abs(q1 - q0) > thresh || abs(p1 - p0) > thresh - - por xmm1, xmm0 ; mask - pcmpeqb xmm2, xmm0 - - pxor xmm0, xmm0 - pcmpeqb xmm4, xmm4 - - pcmpeqb xmm1, xmm0 - pxor xmm4, xmm2 -%endmacro - -%macro BV_TRANSPOSE 0 - ; xmm1 = f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02 - ; xmm6 = f3 e3 d3 c3 b3 a3 93 83 73 63 53 43 33 23 13 03 - ; xmm3 = f4 e4 d4 c4 b4 a4 94 84 74 64 54 44 34 24 14 04 - ; xmm7 = f5 e5 d5 c5 b5 a5 95 85 75 65 55 45 35 25 15 05 - movdqa xmm2, xmm1 ; f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02 - punpcklbw xmm2, xmm6 ; 73 72 63 62 53 52 43 42 33 32 23 22 13 12 03 02 - - movdqa xmm4, xmm3 ; f4 e4 d4 c4 b4 a4 94 84 74 64 54 44 34 24 14 04 - punpckhbw xmm1, xmm6 ; f3 f2 e3 e2 d3 d2 c3 c2 b3 b2 a3 a2 93 92 83 82 - - punpcklbw xmm4, xmm7 ; 75 74 65 64 55 54 45 44 35 34 25 24 15 14 05 04 - - punpckhbw xmm3, xmm7 ; f5 f4 e5 e4 d5 d4 c5 c4 b5 b4 a5 a4 95 94 85 84 - - movdqa xmm6, xmm2 ; 73 72 63 62 53 52 43 42 33 32 23 22 13 12 03 02 - punpcklwd xmm2, xmm4 ; 35 34 33 32 25 24 23 22 15 14 13 12 05 04 03 02 - - punpckhwd xmm6, xmm4 ; 75 74 73 72 65 64 63 62 55 54 53 52 45 44 43 42 - movdqa xmm5, xmm1 ; f3 f2 e3 e2 d3 d2 c3 c2 b3 b2 a3 a2 93 92 83 82 - - punpcklwd xmm1, xmm3 ; b5 b4 b3 b2 a5 a4 a3 a2 95 94 93 92 85 84 83 82 - - punpckhwd xmm5, xmm3 ; f5 f4 f3 f2 e5 e4 e3 e2 d5 d4 d3 d2 c5 c4 c3 c2 - ; xmm2 = 35 34 33 32 25 24 23 22 15 14 13 12 05 04 03 02 - ; xmm6 = 75 74 73 72 65 64 63 62 55 54 53 52 45 44 43 42 - ; xmm1 = b5 b4 b3 b2 a5 a4 a3 a2 95 94 93 92 85 84 83 82 - ; xmm5 = f5 f4 f3 f2 e5 e4 e3 e2 d5 d4 d3 d2 c5 c4 c3 c2 -%endmacro - -%macro BV_WRITEBACK 2 - movd [rsi+2], %1 - movd [rsi+4*rax+2], %2 - psrldq %1, 4 - psrldq %2, 4 - movd [rdi+2], %1 - movd [rdi+4*rax+2], %2 - psrldq %1, 4 - psrldq %2, 4 - movd [rsi+2*rax+2], %1 - movd [rsi+2*rcx+2], %2 - psrldq %1, 4 - psrldq %2, 4 - movd [rdi+2*rax+2], %1 - movd [rdi+2*rcx+2], %2 -%endmacro - -%if ABI_IS_32BIT - -;void vp8_loop_filter_vertical_edge_sse2 -;( -; unsigned char *src_ptr, -; int src_pixel_step, -; const char *blimit, -; const char *limit, -; const char *thresh, -;) -globalsym(vp8_loop_filter_vertical_edge_sse2) -sym(vp8_loop_filter_vertical_edge_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 5 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, lf_var_size - - mov rsi, arg(0) ; src_ptr - movsxd rax, dword ptr arg(1) ; src_pixel_step - - lea rsi, [rsi - 4] - lea rdi, [rsi + rax] ; rdi points to row +1 for indirect addressing - lea rcx, [rax*2+rax] - - ;transpose 16x8 to 8x16, and store the 8-line result on stack. - TRANSPOSE_16X8 1, 1 - - ; calculate filter mask and high edge variance - LFV_FILTER_MASK_HEV_MASK - - ; start work on filters - B_FILTER 2 - - ; transpose and write back - only work on q1, q0, p0, p1 - BV_TRANSPOSE - ; store 16-line result - - lea rdx, [rax] - neg rdx - - BV_WRITEBACK xmm1, xmm5 - - lea rsi, [rsi+rdx*8] - lea rdi, [rdi+rdx*8] - BV_WRITEBACK xmm2, xmm6 - - add rsp, lf_var_size - pop rsp - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -%endif - -;void vp8_loop_filter_vertical_edge_uv_sse2 -;( -; unsigned char *u, -; int src_pixel_step, -; const char *blimit, -; const char *limit, -; const char *thresh, -; unsigned char *v -;) -globalsym(vp8_loop_filter_vertical_edge_uv_sse2) -sym(vp8_loop_filter_vertical_edge_uv_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, lf_var_size - - mov rsi, arg(0) ; u_ptr - movsxd rax, dword ptr arg(1) ; src_pixel_step - - lea rsi, [rsi - 4] - lea rdi, [rsi + rax] ; rdi points to row +1 for indirect addressing - lea rcx, [rax+2*rax] - - ;transpose 16x8 to 8x16, and store the 8-line result on stack. - TRANSPOSE_16X8 0, 1 - - ; calculate filter mask and high edge variance - LFV_FILTER_MASK_HEV_MASK - - ; start work on filters - B_FILTER 2 - - ; transpose and write back - only work on q1, q0, p0, p1 - BV_TRANSPOSE - - lea rdi, [rsi + rax] ; rdi points to row +1 for indirect addressing - - ; store 16-line result - BV_WRITEBACK xmm1, xmm5 - - mov rsi, arg(0) ; u_ptr - lea rsi, [rsi - 4] - lea rdi, [rsi + rax] ; rdi points to row +1 for indirect addressing - BV_WRITEBACK xmm2, xmm6 - - add rsp, lf_var_size - pop rsp - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -%macro MBV_TRANSPOSE 0 - movdqa xmm0, [rsp+_p3] ; f0 e0 d0 c0 b0 a0 90 80 70 60 50 40 30 20 10 00 - movdqa xmm1, xmm0 ; f0 e0 d0 c0 b0 a0 90 80 70 60 50 40 30 20 10 00 - - punpcklbw xmm0, xmm2 ; 71 70 61 60 51 50 41 40 31 30 21 20 11 10 01 00 - punpckhbw xmm1, xmm2 ; f1 f0 e1 e0 d1 d0 c1 c0 b1 b0 a1 a0 91 90 81 80 - - movdqa xmm7, [rsp+_p1] ; f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02 - movdqa xmm6, xmm7 ; f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02 - - punpcklbw xmm7, [rsp+_p0] ; 73 72 63 62 53 52 43 42 33 32 23 22 13 12 03 02 - punpckhbw xmm6, [rsp+_p0] ; f3 f2 e3 e2 d3 d2 c3 c2 b3 b2 a3 a2 93 92 83 82 - - movdqa xmm3, xmm0 ; 71 70 61 60 51 50 41 40 31 30 21 20 11 10 01 00 - punpcklwd xmm0, xmm7 ; 33 32 31 30 23 22 21 20 13 12 11 10 03 02 01 00 - - punpckhwd xmm3, xmm7 ; 73 72 71 70 63 62 61 60 53 52 51 50 43 42 41 40 - movdqa xmm4, xmm1 ; f1 f0 e1 e0 d1 d0 c1 c0 b1 b0 a1 a0 91 90 81 80 - - punpcklwd xmm1, xmm6 ; b3 b2 b1 b0 a3 a2 a1 a0 93 92 91 90 83 82 81 80 - punpckhwd xmm4, xmm6 ; f3 f2 f1 f0 e3 e2 e1 e0 d3 d2 d1 d0 c3 c2 c1 c0 - - movdqa xmm7, [rsp+_q0] ; f4 e4 d4 c4 b4 a4 94 84 74 64 54 44 34 24 14 04 - punpcklbw xmm7, [rsp+_q1] ; 75 74 65 64 55 54 45 44 35 34 25 24 15 14 05 04 - - movdqa xmm6, xmm5 ; f6 e6 d6 c6 b6 a6 96 86 76 66 56 46 36 26 16 06 - punpcklbw xmm6, [rsp+_q3] ; 77 76 67 66 57 56 47 46 37 36 27 26 17 16 07 06 - - movdqa xmm2, xmm7 ; 75 74 65 64 55 54 45 44 35 34 25 24 15 14 05 04 - punpcklwd xmm7, xmm6 ; 37 36 35 34 27 26 25 24 17 16 15 14 07 06 05 04 - - punpckhwd xmm2, xmm6 ; 77 76 75 74 67 66 65 64 57 56 55 54 47 46 45 44 - movdqa xmm6, xmm0 ; 33 32 31 30 23 22 21 20 13 12 11 10 03 02 01 00 - - punpckldq xmm0, xmm7 ; 17 16 15 14 13 12 11 10 07 06 05 04 03 02 01 00 - punpckhdq xmm6, xmm7 ; 37 36 35 34 33 32 31 30 27 26 25 24 23 22 21 20 -%endmacro - -%macro MBV_WRITEBACK_1 0 - movq [rsi], xmm0 - movhps [rdi], xmm0 - - movq [rsi+2*rax], xmm6 - movhps [rdi+2*rax], xmm6 - - movdqa xmm0, xmm3 ; 73 72 71 70 63 62 61 60 53 52 51 50 43 42 41 40 - punpckldq xmm0, xmm2 ; 57 56 55 54 53 52 51 50 47 46 45 44 43 42 41 40 - punpckhdq xmm3, xmm2 ; 77 76 75 74 73 72 71 70 67 66 65 64 63 62 61 60 - - movq [rsi+4*rax], xmm0 - movhps [rdi+4*rax], xmm0 - - movq [rsi+2*rcx], xmm3 - movhps [rdi+2*rcx], xmm3 - - movdqa xmm7, [rsp+_q0] ; f4 e4 d4 c4 b4 a4 94 84 74 64 54 44 34 24 14 04 - punpckhbw xmm7, [rsp+_q1] ; f5 f4 e5 e4 d5 d4 c5 c4 b5 b4 a5 a4 95 94 85 84 - punpckhbw xmm5, [rsp+_q3] ; f7 f6 e7 e6 d7 d6 c7 c6 b7 b6 a7 a6 97 96 87 86 - - movdqa xmm0, xmm7 - punpcklwd xmm0, xmm5 ; b7 b6 b4 b4 a7 a6 a5 a4 97 96 95 94 87 86 85 84 - punpckhwd xmm7, xmm5 ; f7 f6 f5 f4 e7 e6 e5 e4 d7 d6 d5 d4 c7 c6 c5 c4 - - movdqa xmm5, xmm1 ; b3 b2 b1 b0 a3 a2 a1 a0 93 92 91 90 83 82 81 80 - punpckldq xmm1, xmm0 ; 97 96 95 94 93 92 91 90 87 86 85 83 84 82 81 80 - punpckhdq xmm5, xmm0 ; b7 b6 b5 b4 b3 b2 b1 b0 a7 a6 a5 a4 a3 a2 a1 a0 -%endmacro - -%macro MBV_WRITEBACK_2 0 - movq [rsi], xmm1 - movhps [rdi], xmm1 - - movq [rsi+2*rax], xmm5 - movhps [rdi+2*rax], xmm5 - - movdqa xmm1, xmm4 ; f3 f2 f1 f0 e3 e2 e1 e0 d3 d2 d1 d0 c3 c2 c1 c0 - punpckldq xmm1, xmm7 ; d7 d6 d5 d4 d3 d2 d1 d0 c7 c6 c5 c4 c3 c2 c1 c0 - punpckhdq xmm4, xmm7 ; f7 f6 f4 f4 f3 f2 f1 f0 e7 e6 e5 e4 e3 e2 e1 e0 - - movq [rsi+4*rax], xmm1 - movhps [rdi+4*rax], xmm1 - - movq [rsi+2*rcx], xmm4 - movhps [rdi+2*rcx], xmm4 -%endmacro - - -;void vp8_mbloop_filter_vertical_edge_sse2 -;( -; unsigned char *src_ptr, -; int src_pixel_step, -; const char *blimit, -; const char *limit, -; const char *thresh, -;) -globalsym(vp8_mbloop_filter_vertical_edge_sse2) -sym(vp8_mbloop_filter_vertical_edge_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 5 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, lf_var_size - - mov rsi, arg(0) ; src_ptr - movsxd rax, dword ptr arg(1) ; src_pixel_step - - lea rsi, [rsi - 4] - lea rdi, [rsi + rax] ; rdi points to row +1 for indirect addressing - lea rcx, [rax*2+rax] - - ; Transpose - TRANSPOSE_16X8 1, 0 - - ; calculate filter mask and high edge variance - LFV_FILTER_MASK_HEV_MASK - - neg rax - ; start work on filters - MB_FILTER_AND_WRITEBACK 2 - - lea rsi, [rsi+rax*8] - lea rdi, [rdi+rax*8] - - ; transpose and write back - MBV_TRANSPOSE - - neg rax - - MBV_WRITEBACK_1 - - - lea rsi, [rsi+rax*8] - lea rdi, [rdi+rax*8] - MBV_WRITEBACK_2 - - add rsp, lf_var_size - pop rsp - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - - -;void vp8_mbloop_filter_vertical_edge_uv_sse2 -;( -; unsigned char *u, -; int src_pixel_step, -; const char *blimit, -; const char *limit, -; const char *thresh, -; unsigned char *v -;) -globalsym(vp8_mbloop_filter_vertical_edge_uv_sse2) -sym(vp8_mbloop_filter_vertical_edge_uv_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, lf_var_size - - mov rsi, arg(0) ; u_ptr - movsxd rax, dword ptr arg(1) ; src_pixel_step - - lea rsi, [rsi - 4] - lea rdi, [rsi + rax] ; rdi points to row +1 for indirect addressing - lea rcx, [rax+2*rax] - - ; Transpose - TRANSPOSE_16X8 0, 0 - - ; calculate filter mask and high edge variance - LFV_FILTER_MASK_HEV_MASK - - ; start work on filters - MB_FILTER_AND_WRITEBACK 2 - - ; transpose and write back - MBV_TRANSPOSE - - mov rsi, arg(0) ;u_ptr - lea rsi, [rsi - 4] - lea rdi, [rsi + rax] - MBV_WRITEBACK_1 - mov rsi, arg(5) ;v_ptr - lea rsi, [rsi - 4] - lea rdi, [rsi + rax] - MBV_WRITEBACK_2 - - add rsp, lf_var_size - pop rsp - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - - -;void vp8_loop_filter_simple_horizontal_edge_sse2 -;( -; unsigned char *src_ptr, -; int src_pixel_step, -; const char *blimit, -;) -globalsym(vp8_loop_filter_simple_horizontal_edge_sse2) -sym(vp8_loop_filter_simple_horizontal_edge_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 3 - SAVE_XMM 7 - GET_GOT rbx - ; end prolog - - mov rcx, arg(0) ;src_ptr - movsxd rax, dword ptr arg(1) ;src_pixel_step ; destination pitch? - movdqa xmm6, [GLOBAL(tfe)] - lea rdx, [rcx + rax] - neg rax - - ; calculate mask - movdqa xmm0, [rdx] ; q1 - mov rdx, arg(2) ;blimit - movdqa xmm1, [rcx+2*rax] ; p1 - - movdqa xmm2, xmm1 - movdqa xmm3, xmm0 - - psubusb xmm0, xmm1 ; q1-=p1 - psubusb xmm1, xmm3 ; p1-=q1 - por xmm1, xmm0 ; abs(p1-q1) - pand xmm1, xmm6 ; set lsb of each byte to zero - psrlw xmm1, 1 ; abs(p1-q1)/2 - - movdqa xmm7, XMMWORD PTR [rdx] - - movdqa xmm5, [rcx+rax] ; p0 - movdqa xmm4, [rcx] ; q0 - movdqa xmm0, xmm4 ; q0 - movdqa xmm6, xmm5 ; p0 - psubusb xmm5, xmm4 ; p0-=q0 - psubusb xmm4, xmm6 ; q0-=p0 - por xmm5, xmm4 ; abs(p0 - q0) - - movdqa xmm4, [GLOBAL(t80)] - - paddusb xmm5, xmm5 ; abs(p0-q0)*2 - paddusb xmm5, xmm1 ; abs (p0 - q0) *2 + abs(p1-q1)/2 - psubusb xmm5, xmm7 ; abs(p0 - q0) *2 + abs(p1-q1)/2 > blimit - pxor xmm7, xmm7 - pcmpeqb xmm5, xmm7 - - - ; start work on filters - pxor xmm2, xmm4 ; p1 offset to convert to signed values - pxor xmm3, xmm4 ; q1 offset to convert to signed values - psubsb xmm2, xmm3 ; p1 - q1 - - pxor xmm6, xmm4 ; offset to convert to signed values - pxor xmm0, xmm4 ; offset to convert to signed values - movdqa xmm3, xmm0 ; q0 - psubsb xmm0, xmm6 ; q0 - p0 - paddsb xmm2, xmm0 ; p1 - q1 + 1 * (q0 - p0) - paddsb xmm2, xmm0 ; p1 - q1 + 2 * (q0 - p0) - paddsb xmm2, xmm0 ; p1 - q1 + 3 * (q0 - p0) - pand xmm5, xmm2 ; mask filter values we don't care about - - movdqa xmm0, xmm5 - paddsb xmm5, [GLOBAL(t3)] ; 3* (q0 - p0) + (p1 - q1) + 4 - paddsb xmm0, [GLOBAL(t4)] ; +3 instead of +4 - - movdqa xmm1, [GLOBAL(te0)] - movdqa xmm2, [GLOBAL(t1f)] - -; pxor xmm7, xmm7 - pcmpgtb xmm7, xmm0 ;save sign - pand xmm7, xmm1 ;preserve the upper 3 bits - psrlw xmm0, 3 - pand xmm0, xmm2 ;clear out upper 3 bits - por xmm0, xmm7 ;add sign - psubsb xmm3, xmm0 ; q0-= q0sz add - - pxor xmm7, xmm7 - pcmpgtb xmm7, xmm5 ;save sign - pand xmm7, xmm1 ;preserve the upper 3 bits - psrlw xmm5, 3 - pand xmm5, xmm2 ;clear out upper 3 bits - por xmm5, xmm7 ;add sign - paddsb xmm6, xmm5 ; p0+= p0 add - - pxor xmm3, xmm4 ; unoffset - movdqa [rcx], xmm3 ; write back - - pxor xmm6, xmm4 ; unoffset - movdqa [rcx+rax], xmm6 ; write back - - ; begin epilog - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - - -;void vp8_loop_filter_simple_vertical_edge_sse2 -;( -; unsigned char *src_ptr, -; int src_pixel_step, -; const char *blimit, -;) -globalsym(vp8_loop_filter_simple_vertical_edge_sse2) -sym(vp8_loop_filter_simple_vertical_edge_sse2): - push rbp ; save old base pointer value. - mov rbp, rsp ; set new base pointer value. - SHADOW_ARGS_TO_STACK 3 - SAVE_XMM 7 - GET_GOT rbx ; save callee-saved reg - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 32 ; reserve 32 bytes - %define t0 [rsp + 0] ;__declspec(align(16)) char t0[16]; - %define t1 [rsp + 16] ;__declspec(align(16)) char t1[16]; - - mov rsi, arg(0) ;src_ptr - movsxd rax, dword ptr arg(1) ;src_pixel_step ; destination pitch? - - lea rsi, [rsi - 2 ] - lea rdi, [rsi + rax] - lea rdx, [rsi + rax*4] - lea rcx, [rdx + rax] - - movd xmm0, [rsi] ; (high 96 bits unused) 03 02 01 00 - movd xmm1, [rdx] ; (high 96 bits unused) 43 42 41 40 - movd xmm2, [rdi] ; 13 12 11 10 - movd xmm3, [rcx] ; 53 52 51 50 - punpckldq xmm0, xmm1 ; (high 64 bits unused) 43 42 41 40 03 02 01 00 - punpckldq xmm2, xmm3 ; 53 52 51 50 13 12 11 10 - - movd xmm4, [rsi + rax*2] ; 23 22 21 20 - movd xmm5, [rdx + rax*2] ; 63 62 61 60 - movd xmm6, [rdi + rax*2] ; 33 32 31 30 - movd xmm7, [rcx + rax*2] ; 73 72 71 70 - punpckldq xmm4, xmm5 ; 63 62 61 60 23 22 21 20 - punpckldq xmm6, xmm7 ; 73 72 71 70 33 32 31 30 - - punpcklbw xmm0, xmm2 ; 53 43 52 42 51 41 50 40 13 03 12 02 11 01 10 00 - punpcklbw xmm4, xmm6 ; 73 63 72 62 71 61 70 60 33 23 32 22 31 21 30 20 - - movdqa xmm1, xmm0 - punpcklwd xmm0, xmm4 ; 33 23 13 03 32 22 12 02 31 21 11 01 30 20 10 00 - punpckhwd xmm1, xmm4 ; 73 63 53 43 72 62 52 42 71 61 51 41 70 60 50 40 - - movdqa xmm2, xmm0 - punpckldq xmm0, xmm1 ; 71 61 51 41 31 21 11 01 70 60 50 40 30 20 10 00 - punpckhdq xmm2, xmm1 ; 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02 - - lea rsi, [rsi + rax*8] - lea rdi, [rsi + rax] - lea rdx, [rsi + rax*4] - lea rcx, [rdx + rax] - - movd xmm4, [rsi] ; 83 82 81 80 - movd xmm1, [rdx] ; c3 c2 c1 c0 - movd xmm6, [rdi] ; 93 92 91 90 - movd xmm3, [rcx] ; d3 d2 d1 d0 - punpckldq xmm4, xmm1 ; c3 c2 c1 c0 83 82 81 80 - punpckldq xmm6, xmm3 ; d3 d2 d1 d0 93 92 91 90 - - movd xmm1, [rsi + rax*2] ; a3 a2 a1 a0 - movd xmm5, [rdx + rax*2] ; e3 e2 e1 e0 - movd xmm3, [rdi + rax*2] ; b3 b2 b1 b0 - movd xmm7, [rcx + rax*2] ; f3 f2 f1 f0 - punpckldq xmm1, xmm5 ; e3 e2 e1 e0 a3 a2 a1 a0 - punpckldq xmm3, xmm7 ; f3 f2 f1 f0 b3 b2 b1 b0 - - punpcklbw xmm4, xmm6 ; d3 c3 d2 c2 d1 c1 d0 c0 93 83 92 82 91 81 90 80 - punpcklbw xmm1, xmm3 ; f3 e3 f2 e2 f1 e1 f0 e0 b3 a3 b2 a2 b1 a1 b0 a0 - - movdqa xmm7, xmm4 - punpcklwd xmm4, xmm1 ; b3 a3 93 83 b2 a2 92 82 b1 a1 91 81 b0 a0 90 80 - punpckhwd xmm7, xmm1 ; f3 e3 d3 c3 f2 e2 d2 c2 f1 e1 d1 c1 f0 e0 d0 c0 - - movdqa xmm6, xmm4 - punpckldq xmm4, xmm7 ; f1 e1 d1 c1 b1 a1 91 81 f0 e0 d0 c0 b0 a0 90 80 - punpckhdq xmm6, xmm7 ; f3 e3 d3 c3 b3 a3 93 83 f2 e2 d2 c2 b2 a2 92 82 - - movdqa xmm1, xmm0 - movdqa xmm3, xmm2 - - punpcklqdq xmm0, xmm4 ; p1 f0 e0 d0 c0 b0 a0 90 80 70 60 50 40 30 20 10 00 - punpckhqdq xmm1, xmm4 ; p0 f1 e1 d1 c1 b1 a1 91 81 71 61 51 41 31 21 11 01 - punpcklqdq xmm2, xmm6 ; q0 f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02 - punpckhqdq xmm3, xmm6 ; q1 f3 e3 d3 c3 b3 a3 93 83 73 63 53 43 33 23 13 03 - - mov rdx, arg(2) ;blimit - - ; calculate mask - movdqa xmm6, xmm0 ; p1 - movdqa xmm7, xmm3 ; q1 - psubusb xmm7, xmm0 ; q1-=p1 - psubusb xmm6, xmm3 ; p1-=q1 - por xmm6, xmm7 ; abs(p1-q1) - pand xmm6, [GLOBAL(tfe)] ; set lsb of each byte to zero - psrlw xmm6, 1 ; abs(p1-q1)/2 - - movdqa xmm7, [rdx] - - movdqa xmm5, xmm1 ; p0 - movdqa xmm4, xmm2 ; q0 - psubusb xmm5, xmm2 ; p0-=q0 - psubusb xmm4, xmm1 ; q0-=p0 - por xmm5, xmm4 ; abs(p0 - q0) - paddusb xmm5, xmm5 ; abs(p0-q0)*2 - paddusb xmm5, xmm6 ; abs (p0 - q0) *2 + abs(p1-q1)/2 - - movdqa xmm4, [GLOBAL(t80)] - - psubusb xmm5, xmm7 ; abs(p0 - q0) *2 + abs(p1-q1)/2 > blimit - pxor xmm7, xmm7 - pcmpeqb xmm5, xmm7 ; mm5 = mask - - ; start work on filters - movdqa t0, xmm0 - movdqa t1, xmm3 - - pxor xmm0, xmm4 ; p1 offset to convert to signed values - pxor xmm3, xmm4 ; q1 offset to convert to signed values - psubsb xmm0, xmm3 ; p1 - q1 - - pxor xmm1, xmm4 ; offset to convert to signed values - pxor xmm2, xmm4 ; offset to convert to signed values - - movdqa xmm3, xmm2 ; offseted ; q0 - psubsb xmm2, xmm1 ; q0 - p0 - paddsb xmm0, xmm2 ; p1 - q1 + 1 * (q0 - p0) - paddsb xmm0, xmm2 ; p1 - q1 + 2 * (q0 - p0) - paddsb xmm0, xmm2 ; p1 - q1 + 3 * (q0 - p0) - pand xmm5, xmm0 ; mask filter values we don't care about - - movdqa xmm0, xmm5 - paddsb xmm5, [GLOBAL(t3)] ; 3* (q0 - p0) + (p1 - q1) + 4 - paddsb xmm0, [GLOBAL(t4)] ; +3 instead of +4 - - movdqa xmm6, [GLOBAL(te0)] - movdqa xmm2, [GLOBAL(t1f)] - -; pxor xmm7, xmm7 - pcmpgtb xmm7, xmm0 ;save sign - pand xmm7, xmm6 ;preserve the upper 3 bits - psrlw xmm0, 3 - pand xmm0, xmm2 ;clear out upper 3 bits - por xmm0, xmm7 ;add sign - psubsb xmm3, xmm0 ; q0-= q0sz add - - pxor xmm7, xmm7 - pcmpgtb xmm7, xmm5 ;save sign - pand xmm7, xmm6 ;preserve the upper 3 bits - psrlw xmm5, 3 - pand xmm5, xmm2 ;clear out upper 3 bits - por xmm5, xmm7 ;add sign - paddsb xmm1, xmm5 ; p0+= p0 add - - pxor xmm3, xmm4 ; unoffset q0 - pxor xmm1, xmm4 ; unoffset p0 - - movdqa xmm0, t0 ; p1 - movdqa xmm4, t1 ; q1 - - ; write out order: xmm0 xmm2 xmm1 xmm3 - lea rdx, [rsi + rax*4] - - ; transpose back to write out - ; p1 f0 e0 d0 c0 b0 a0 90 80 70 60 50 40 30 20 10 00 - ; p0 f1 e1 d1 c1 b1 a1 91 81 71 61 51 41 31 21 11 01 - ; q0 f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02 - ; q1 f3 e3 d3 c3 b3 a3 93 83 73 63 53 43 33 23 13 03 - movdqa xmm6, xmm0 - punpcklbw xmm0, xmm1 ; 71 70 61 60 51 50 41 40 31 30 21 20 11 10 01 00 - punpckhbw xmm6, xmm1 ; f1 f0 e1 e0 d1 d0 c1 c0 b1 b0 a1 a0 91 90 81 80 - - movdqa xmm5, xmm3 - punpcklbw xmm3, xmm4 ; 73 72 63 62 53 52 43 42 33 32 23 22 13 12 03 02 - punpckhbw xmm5, xmm4 ; f3 f2 e3 e2 d3 d2 c3 c2 b3 b2 a3 a2 93 92 83 82 - - movdqa xmm2, xmm0 - punpcklwd xmm0, xmm3 ; 33 32 31 30 23 22 21 20 13 12 11 10 03 02 01 00 - punpckhwd xmm2, xmm3 ; 73 72 71 70 63 62 61 60 53 52 51 50 43 42 41 40 - - movdqa xmm3, xmm6 - punpcklwd xmm6, xmm5 ; b3 b2 b1 b0 a3 a2 a1 a0 93 92 91 90 83 82 81 80 - punpckhwd xmm3, xmm5 ; f3 f2 f1 f0 e3 e2 e1 e0 d3 d2 d1 d0 c3 c2 c1 c0 - - movd [rsi], xmm6 ; write the second 8-line result - movd [rdx], xmm3 - psrldq xmm6, 4 - psrldq xmm3, 4 - movd [rdi], xmm6 - movd [rcx], xmm3 - psrldq xmm6, 4 - psrldq xmm3, 4 - movd [rsi + rax*2], xmm6 - movd [rdx + rax*2], xmm3 - psrldq xmm6, 4 - psrldq xmm3, 4 - movd [rdi + rax*2], xmm6 - movd [rcx + rax*2], xmm3 - - neg rax - lea rsi, [rsi + rax*8] - neg rax - lea rdi, [rsi + rax] - lea rdx, [rsi + rax*4] - lea rcx, [rdx + rax] - - movd [rsi], xmm0 ; write the first 8-line result - movd [rdx], xmm2 - psrldq xmm0, 4 - psrldq xmm2, 4 - movd [rdi], xmm0 - movd [rcx], xmm2 - psrldq xmm0, 4 - psrldq xmm2, 4 - movd [rsi + rax*2], xmm0 - movd [rdx + rax*2], xmm2 - psrldq xmm0, 4 - psrldq xmm2, 4 - movd [rdi + rax*2], xmm0 - movd [rcx + rax*2], xmm2 - - add rsp, 32 - pop rsp - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -SECTION_RODATA -align 16 -tfe: - times 16 db 0xfe -align 16 -t80: - times 16 db 0x80 -align 16 -t1s: - times 16 db 0x01 -align 16 -t3: - times 16 db 0x03 -align 16 -t4: - times 16 db 0x04 -align 16 -ones: - times 8 dw 0x0001 -align 16 -s9: - times 8 dw 0x0900 -align 16 -s63: - times 8 dw 0x003f -align 16 -te0: - times 16 db 0xe0 -align 16 -t1f: - times 16 db 0x1f diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/loopfilter_x86.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/loopfilter_x86.c deleted file mode 100644 index cfa13a2d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/loopfilter_x86.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "vp8/common/loopfilter.h" - -#define prototype_loopfilter(sym) \ - void sym(unsigned char *src, int pitch, const unsigned char *blimit, \ - const unsigned char *limit, const unsigned char *thresh, int count) - -#define prototype_loopfilter_nc(sym) \ - void sym(unsigned char *src, int pitch, const unsigned char *blimit, \ - const unsigned char *limit, const unsigned char *thresh) - -#define prototype_simple_loopfilter(sym) \ - void sym(unsigned char *y, int ystride, const unsigned char *blimit) - -#if HAVE_SSE2 && VPX_ARCH_X86_64 -prototype_loopfilter(vp8_loop_filter_bv_y_sse2); -prototype_loopfilter(vp8_loop_filter_bh_y_sse2); -#else -prototype_loopfilter_nc(vp8_loop_filter_vertical_edge_sse2); -prototype_loopfilter_nc(vp8_loop_filter_horizontal_edge_sse2); -#endif -prototype_loopfilter_nc(vp8_mbloop_filter_vertical_edge_sse2); -prototype_loopfilter_nc(vp8_mbloop_filter_horizontal_edge_sse2); - -extern loop_filter_uvfunction vp8_loop_filter_horizontal_edge_uv_sse2; -extern loop_filter_uvfunction vp8_loop_filter_vertical_edge_uv_sse2; -extern loop_filter_uvfunction vp8_mbloop_filter_horizontal_edge_uv_sse2; -extern loop_filter_uvfunction vp8_mbloop_filter_vertical_edge_uv_sse2; - -/* Horizontal MB filtering */ -#if HAVE_SSE2 -void vp8_loop_filter_mbh_sse2(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { - vp8_mbloop_filter_horizontal_edge_sse2(y_ptr, y_stride, lfi->mblim, lfi->lim, - lfi->hev_thr); - - if (u_ptr) { - vp8_mbloop_filter_horizontal_edge_uv_sse2(u_ptr, uv_stride, lfi->mblim, - lfi->lim, lfi->hev_thr, v_ptr); - } -} - -/* Vertical MB Filtering */ -void vp8_loop_filter_mbv_sse2(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { - vp8_mbloop_filter_vertical_edge_sse2(y_ptr, y_stride, lfi->mblim, lfi->lim, - lfi->hev_thr); - - if (u_ptr) { - vp8_mbloop_filter_vertical_edge_uv_sse2(u_ptr, uv_stride, lfi->mblim, - lfi->lim, lfi->hev_thr, v_ptr); - } -} - -/* Horizontal B Filtering */ -void vp8_loop_filter_bh_sse2(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { -#if VPX_ARCH_X86_64 - vp8_loop_filter_bh_y_sse2(y_ptr, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, - 2); -#else - vp8_loop_filter_horizontal_edge_sse2(y_ptr + 4 * y_stride, y_stride, - lfi->blim, lfi->lim, lfi->hev_thr); - vp8_loop_filter_horizontal_edge_sse2(y_ptr + 8 * y_stride, y_stride, - lfi->blim, lfi->lim, lfi->hev_thr); - vp8_loop_filter_horizontal_edge_sse2(y_ptr + 12 * y_stride, y_stride, - lfi->blim, lfi->lim, lfi->hev_thr); -#endif - - if (u_ptr) { - vp8_loop_filter_horizontal_edge_uv_sse2(u_ptr + 4 * uv_stride, uv_stride, - lfi->blim, lfi->lim, lfi->hev_thr, - v_ptr + 4 * uv_stride); - } -} - -void vp8_loop_filter_bhs_sse2(unsigned char *y_ptr, int y_stride, - const unsigned char *blimit) { - vp8_loop_filter_simple_horizontal_edge_sse2(y_ptr + 4 * y_stride, y_stride, - blimit); - vp8_loop_filter_simple_horizontal_edge_sse2(y_ptr + 8 * y_stride, y_stride, - blimit); - vp8_loop_filter_simple_horizontal_edge_sse2(y_ptr + 12 * y_stride, y_stride, - blimit); -} - -/* Vertical B Filtering */ -void vp8_loop_filter_bv_sse2(unsigned char *y_ptr, unsigned char *u_ptr, - unsigned char *v_ptr, int y_stride, int uv_stride, - loop_filter_info *lfi) { -#if VPX_ARCH_X86_64 - vp8_loop_filter_bv_y_sse2(y_ptr, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, - 2); -#else - vp8_loop_filter_vertical_edge_sse2(y_ptr + 4, y_stride, lfi->blim, lfi->lim, - lfi->hev_thr); - vp8_loop_filter_vertical_edge_sse2(y_ptr + 8, y_stride, lfi->blim, lfi->lim, - lfi->hev_thr); - vp8_loop_filter_vertical_edge_sse2(y_ptr + 12, y_stride, lfi->blim, lfi->lim, - lfi->hev_thr); -#endif - - if (u_ptr) { - vp8_loop_filter_vertical_edge_uv_sse2(u_ptr + 4, uv_stride, lfi->blim, - lfi->lim, lfi->hev_thr, v_ptr + 4); - } -} - -void vp8_loop_filter_bvs_sse2(unsigned char *y_ptr, int y_stride, - const unsigned char *blimit) { - vp8_loop_filter_simple_vertical_edge_sse2(y_ptr + 4, y_stride, blimit); - vp8_loop_filter_simple_vertical_edge_sse2(y_ptr + 8, y_stride, blimit); - vp8_loop_filter_simple_vertical_edge_sse2(y_ptr + 12, y_stride, blimit); -} - -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/mfqe_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/mfqe_sse2.asm deleted file mode 100644 index 3ec2a99e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/mfqe_sse2.asm +++ /dev/null @@ -1,289 +0,0 @@ -; -; Copyright (c) 2012 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -SECTION .text - -;void vp8_filter_by_weight16x16_sse2 -;( -; unsigned char *src, -; int src_stride, -; unsigned char *dst, -; int dst_stride, -; int src_weight -;) -globalsym(vp8_filter_by_weight16x16_sse2) -sym(vp8_filter_by_weight16x16_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 5 - SAVE_XMM 6 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - movd xmm0, arg(4) ; src_weight - pshuflw xmm0, xmm0, 0x0 ; replicate to all low words - punpcklqdq xmm0, xmm0 ; replicate to all hi words - - movdqa xmm1, [GLOBAL(tMFQE)] - psubw xmm1, xmm0 ; dst_weight - - mov rax, arg(0) ; src - mov rsi, arg(1) ; src_stride - mov rdx, arg(2) ; dst - mov rdi, arg(3) ; dst_stride - - mov rcx, 16 ; loop count - pxor xmm6, xmm6 - -.combine: - movdqa xmm2, [rax] - movdqa xmm4, [rdx] - add rax, rsi - - ; src * src_weight - movdqa xmm3, xmm2 - punpcklbw xmm2, xmm6 - punpckhbw xmm3, xmm6 - pmullw xmm2, xmm0 - pmullw xmm3, xmm0 - - ; dst * dst_weight - movdqa xmm5, xmm4 - punpcklbw xmm4, xmm6 - punpckhbw xmm5, xmm6 - pmullw xmm4, xmm1 - pmullw xmm5, xmm1 - - ; sum, round and shift - paddw xmm2, xmm4 - paddw xmm3, xmm5 - paddw xmm2, [GLOBAL(tMFQE_round)] - paddw xmm3, [GLOBAL(tMFQE_round)] - psrlw xmm2, 4 - psrlw xmm3, 4 - - packuswb xmm2, xmm3 - movdqa [rdx], xmm2 - add rdx, rdi - - dec rcx - jnz .combine - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - - ret - -;void vp8_filter_by_weight8x8_sse2 -;( -; unsigned char *src, -; int src_stride, -; unsigned char *dst, -; int dst_stride, -; int src_weight -;) -globalsym(vp8_filter_by_weight8x8_sse2) -sym(vp8_filter_by_weight8x8_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 5 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - movd xmm0, arg(4) ; src_weight - pshuflw xmm0, xmm0, 0x0 ; replicate to all low words - punpcklqdq xmm0, xmm0 ; replicate to all hi words - - movdqa xmm1, [GLOBAL(tMFQE)] - psubw xmm1, xmm0 ; dst_weight - - mov rax, arg(0) ; src - mov rsi, arg(1) ; src_stride - mov rdx, arg(2) ; dst - mov rdi, arg(3) ; dst_stride - - mov rcx, 8 ; loop count - pxor xmm4, xmm4 - -.combine: - movq xmm2, [rax] - movq xmm3, [rdx] - add rax, rsi - - ; src * src_weight - punpcklbw xmm2, xmm4 - pmullw xmm2, xmm0 - - ; dst * dst_weight - punpcklbw xmm3, xmm4 - pmullw xmm3, xmm1 - - ; sum, round and shift - paddw xmm2, xmm3 - paddw xmm2, [GLOBAL(tMFQE_round)] - psrlw xmm2, 4 - - packuswb xmm2, xmm4 - movq [rdx], xmm2 - add rdx, rdi - - dec rcx - jnz .combine - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - UNSHADOW_ARGS - pop rbp - - ret - -;void vp8_variance_and_sad_16x16_sse2 | arg -;( -; unsigned char *src1, 0 -; int stride1, 1 -; unsigned char *src2, 2 -; int stride2, 3 -; unsigned int *variance, 4 -; unsigned int *sad, 5 -;) -globalsym(vp8_variance_and_sad_16x16_sse2) -sym(vp8_variance_and_sad_16x16_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - mov rax, arg(0) ; src1 - mov rcx, arg(1) ; stride1 - mov rdx, arg(2) ; src2 - mov rdi, arg(3) ; stride2 - - mov rsi, 16 ; block height - - ; Prep accumulator registers - pxor xmm3, xmm3 ; SAD - pxor xmm4, xmm4 ; sum of src2 - pxor xmm5, xmm5 ; sum of src2^2 - - ; Because we're working with the actual output frames - ; we can't depend on any kind of data alignment. -.accumulate: - movdqa xmm0, [rax] ; src1 - movdqa xmm1, [rdx] ; src2 - add rax, rcx ; src1 + stride1 - add rdx, rdi ; src2 + stride2 - - ; SAD(src1, src2) - psadbw xmm0, xmm1 - paddusw xmm3, xmm0 - - ; SUM(src2) - pxor xmm2, xmm2 - psadbw xmm2, xmm1 ; sum src2 by misusing SAD against 0 - paddusw xmm4, xmm2 - - ; pmaddubsw would be ideal if it took two unsigned values. instead, - ; it expects a signed and an unsigned value. so instead we zero extend - ; and operate on words. - pxor xmm2, xmm2 - movdqa xmm0, xmm1 - punpcklbw xmm0, xmm2 - punpckhbw xmm1, xmm2 - pmaddwd xmm0, xmm0 - pmaddwd xmm1, xmm1 - paddd xmm5, xmm0 - paddd xmm5, xmm1 - - sub rsi, 1 - jnz .accumulate - - ; phaddd only operates on adjacent double words. - ; Finalize SAD and store - movdqa xmm0, xmm3 - psrldq xmm0, 8 - paddusw xmm0, xmm3 - paddd xmm0, [GLOBAL(t128)] - psrld xmm0, 8 - - mov rax, arg(5) - movd [rax], xmm0 - - ; Accumulate sum of src2 - movdqa xmm0, xmm4 - psrldq xmm0, 8 - paddusw xmm0, xmm4 - ; Square src2. Ignore high value - pmuludq xmm0, xmm0 - psrld xmm0, 8 - - ; phaddw could be used to sum adjacent values but we want - ; all the values summed. promote to doubles, accumulate, - ; shift and sum - pxor xmm2, xmm2 - movdqa xmm1, xmm5 - punpckldq xmm1, xmm2 - punpckhdq xmm5, xmm2 - paddd xmm1, xmm5 - movdqa xmm2, xmm1 - psrldq xmm1, 8 - paddd xmm1, xmm2 - - psubd xmm1, xmm0 - - ; (variance + 128) >> 8 - paddd xmm1, [GLOBAL(t128)] - psrld xmm1, 8 - mov rax, arg(4) - - movd [rax], xmm1 - - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - UNSHADOW_ARGS - pop rbp - ret - -SECTION_RODATA -align 16 -t128: -%ifndef __NASM_VER__ - ddq 128 -%elif CONFIG_BIG_ENDIAN - dq 0, 128 -%else - dq 128, 0 -%endif -align 16 -tMFQE: ; 1 << MFQE_PRECISION - times 8 dw 0x10 -align 16 -tMFQE_round: ; 1 << (MFQE_PRECISION - 1) - times 8 dw 0x08 - diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/recon_mmx.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/recon_mmx.asm deleted file mode 100644 index 01cf0668..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/recon_mmx.asm +++ /dev/null @@ -1,120 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -SECTION .text - -;void copy_mem8x8_mmx( -; unsigned char *src, -; int src_stride, -; unsigned char *dst, -; int dst_stride -; ) -globalsym(vp8_copy_mem8x8_mmx) -sym(vp8_copy_mem8x8_mmx): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 4 - push rsi - push rdi - ; end prolog - - mov rsi, arg(0) ;src; - movq mm0, [rsi] - - movsxd rax, dword ptr arg(1) ;src_stride; - mov rdi, arg(2) ;dst; - - movq mm1, [rsi+rax] - movq mm2, [rsi+rax*2] - - movsxd rcx, dword ptr arg(3) ;dst_stride - lea rsi, [rsi+rax*2] - - movq [rdi], mm0 - add rsi, rax - - movq [rdi+rcx], mm1 - movq [rdi+rcx*2], mm2 - - - lea rdi, [rdi+rcx*2] - movq mm3, [rsi] - - add rdi, rcx - movq mm4, [rsi+rax] - - movq mm5, [rsi+rax*2] - movq [rdi], mm3 - - lea rsi, [rsi+rax*2] - movq [rdi+rcx], mm4 - - movq [rdi+rcx*2], mm5 - lea rdi, [rdi+rcx*2] - - movq mm0, [rsi+rax] - movq mm1, [rsi+rax*2] - - movq [rdi+rcx], mm0 - movq [rdi+rcx*2],mm1 - - ; begin epilog - pop rdi - pop rsi - UNSHADOW_ARGS - pop rbp - ret - - -;void copy_mem8x4_mmx( -; unsigned char *src, -; int src_stride, -; unsigned char *dst, -; int dst_stride -; ) -globalsym(vp8_copy_mem8x4_mmx) -sym(vp8_copy_mem8x4_mmx): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 4 - push rsi - push rdi - ; end prolog - - mov rsi, arg(0) ;src; - movq mm0, [rsi] - - movsxd rax, dword ptr arg(1) ;src_stride; - mov rdi, arg(2) ;dst; - - movq mm1, [rsi+rax] - movq mm2, [rsi+rax*2] - - movsxd rcx, dword ptr arg(3) ;dst_stride - lea rsi, [rsi+rax*2] - - movq [rdi], mm0 - movq [rdi+rcx], mm1 - - movq [rdi+rcx*2], mm2 - lea rdi, [rdi+rcx*2] - - movq mm3, [rsi+rax] - movq [rdi+rcx], mm3 - - ; begin epilog - pop rdi - pop rsi - UNSHADOW_ARGS - pop rbp - ret diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/recon_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/recon_sse2.asm deleted file mode 100644 index 17baf094..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/recon_sse2.asm +++ /dev/null @@ -1,118 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -SECTION .text - -;void copy_mem16x16_sse2( -; unsigned char *src, -; int src_stride, -; unsigned char *dst, -; int dst_stride -; ) -globalsym(vp8_copy_mem16x16_sse2) -sym(vp8_copy_mem16x16_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 4 - push rsi - push rdi - ; end prolog - - mov rsi, arg(0) ;src; - movdqu xmm0, [rsi] - - movsxd rax, dword ptr arg(1) ;src_stride; - mov rdi, arg(2) ;dst; - - movdqu xmm1, [rsi+rax] - movdqu xmm2, [rsi+rax*2] - - movsxd rcx, dword ptr arg(3) ;dst_stride - lea rsi, [rsi+rax*2] - - movdqa [rdi], xmm0 - add rsi, rax - - movdqa [rdi+rcx], xmm1 - movdqa [rdi+rcx*2],xmm2 - - lea rdi, [rdi+rcx*2] - movdqu xmm3, [rsi] - - add rdi, rcx - movdqu xmm4, [rsi+rax] - - movdqu xmm5, [rsi+rax*2] - lea rsi, [rsi+rax*2] - - movdqa [rdi], xmm3 - add rsi, rax - - movdqa [rdi+rcx], xmm4 - movdqa [rdi+rcx*2],xmm5 - - lea rdi, [rdi+rcx*2] - movdqu xmm0, [rsi] - - add rdi, rcx - movdqu xmm1, [rsi+rax] - - movdqu xmm2, [rsi+rax*2] - lea rsi, [rsi+rax*2] - - movdqa [rdi], xmm0 - add rsi, rax - - movdqa [rdi+rcx], xmm1 - - movdqa [rdi+rcx*2], xmm2 - movdqu xmm3, [rsi] - - movdqu xmm4, [rsi+rax] - lea rdi, [rdi+rcx*2] - - add rdi, rcx - movdqu xmm5, [rsi+rax*2] - - lea rsi, [rsi+rax*2] - movdqa [rdi], xmm3 - - add rsi, rax - movdqa [rdi+rcx], xmm4 - - movdqa [rdi+rcx*2],xmm5 - movdqu xmm0, [rsi] - - lea rdi, [rdi+rcx*2] - movdqu xmm1, [rsi+rax] - - add rdi, rcx - movdqu xmm2, [rsi+rax*2] - - lea rsi, [rsi+rax*2] - movdqa [rdi], xmm0 - - movdqa [rdi+rcx], xmm1 - movdqa [rdi+rcx*2],xmm2 - - movdqu xmm3, [rsi+rax] - lea rdi, [rdi+rcx*2] - - movdqa [rdi+rcx], xmm3 - - ; begin epilog - pop rdi - pop rsi - UNSHADOW_ARGS - pop rbp - ret diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/subpixel_mmx.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/subpixel_mmx.asm deleted file mode 100644 index 8f0f6fcc..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/subpixel_mmx.asm +++ /dev/null @@ -1,270 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -%define BLOCK_HEIGHT_WIDTH 4 -%define vp8_filter_weight 128 -%define VP8_FILTER_SHIFT 7 - -SECTION .text - -;void vp8_filter_block1d_h6_mmx -;( -; unsigned char *src_ptr, -; unsigned short *output_ptr, -; unsigned int src_pixels_per_line, -; unsigned int pixel_step, -; unsigned int output_height, -; unsigned int output_width, -; short * vp8_filter -;) -globalsym(vp8_filter_block1d_h6_mmx) -sym(vp8_filter_block1d_h6_mmx): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - mov rdx, arg(6) ;vp8_filter - - movq mm1, [rdx + 16] ; do both the negative taps first!!! - movq mm2, [rdx + 32] ; - movq mm6, [rdx + 48] ; - movq mm7, [rdx + 64] ; - - mov rdi, arg(1) ;output_ptr - mov rsi, arg(0) ;src_ptr - movsxd rcx, dword ptr arg(4) ;output_height - movsxd rax, dword ptr arg(5) ;output_width ; destination pitch? - pxor mm0, mm0 ; mm0 = 00000000 - -.nextrow: - movq mm3, [rsi-2] ; mm3 = p-2..p5 - movq mm4, mm3 ; mm4 = p-2..p5 - psrlq mm3, 8 ; mm3 = p-1..p5 - punpcklbw mm3, mm0 ; mm3 = p-1..p2 - pmullw mm3, mm1 ; mm3 *= kernel 1 modifiers. - - movq mm5, mm4 ; mm5 = p-2..p5 - punpckhbw mm4, mm0 ; mm5 = p2..p5 - pmullw mm4, mm7 ; mm5 *= kernel 4 modifiers - paddsw mm3, mm4 ; mm3 += mm5 - - movq mm4, mm5 ; mm4 = p-2..p5; - psrlq mm5, 16 ; mm5 = p0..p5; - punpcklbw mm5, mm0 ; mm5 = p0..p3 - pmullw mm5, mm2 ; mm5 *= kernel 2 modifiers - paddsw mm3, mm5 ; mm3 += mm5 - - movq mm5, mm4 ; mm5 = p-2..p5 - psrlq mm4, 24 ; mm4 = p1..p5 - punpcklbw mm4, mm0 ; mm4 = p1..p4 - pmullw mm4, mm6 ; mm5 *= kernel 3 modifiers - paddsw mm3, mm4 ; mm3 += mm5 - - ; do outer positive taps - movd mm4, [rsi+3] - punpcklbw mm4, mm0 ; mm5 = p3..p6 - pmullw mm4, [rdx+80] ; mm5 *= kernel 0 modifiers - paddsw mm3, mm4 ; mm3 += mm5 - - punpcklbw mm5, mm0 ; mm5 = p-2..p1 - pmullw mm5, [rdx] ; mm5 *= kernel 5 modifiers - paddsw mm3, mm5 ; mm3 += mm5 - - paddsw mm3, [GLOBAL(rd)] ; mm3 += round value - psraw mm3, VP8_FILTER_SHIFT ; mm3 /= 128 - packuswb mm3, mm0 ; pack and unpack to saturate - punpcklbw mm3, mm0 ; - - movq [rdi], mm3 ; store the results in the destination - -%if ABI_IS_32BIT - add rsi, dword ptr arg(2) ;src_pixels_per_line ; next line - add rdi, rax; -%else - movsxd r8, dword ptr arg(2) ;src_pixels_per_line - add rdi, rax; - - add rsi, r8 ; next line -%endif - - dec rcx ; decrement count - jnz .nextrow ; next row - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - UNSHADOW_ARGS - pop rbp - ret - - -;void vp8_filter_block1dc_v6_mmx -;( -; short *src_ptr, -; unsigned char *output_ptr, -; int output_pitch, -; unsigned int pixels_per_line, -; unsigned int pixel_step, -; unsigned int output_height, -; unsigned int output_width, -; short * vp8_filter -;) -globalsym(vp8_filter_block1dc_v6_mmx) -sym(vp8_filter_block1dc_v6_mmx): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 8 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - movq mm5, [GLOBAL(rd)] - push rbx - mov rbx, arg(7) ;vp8_filter - movq mm1, [rbx + 16] ; do both the negative taps first!!! - movq mm2, [rbx + 32] ; - movq mm6, [rbx + 48] ; - movq mm7, [rbx + 64] ; - - movsxd rdx, dword ptr arg(3) ;pixels_per_line - mov rdi, arg(1) ;output_ptr - mov rsi, arg(0) ;src_ptr - sub rsi, rdx - sub rsi, rdx - movsxd rcx, DWORD PTR arg(5) ;output_height - movsxd rax, DWORD PTR arg(2) ;output_pitch ; destination pitch? - pxor mm0, mm0 ; mm0 = 00000000 - - -.nextrow_cv: - movq mm3, [rsi+rdx] ; mm3 = p0..p8 = row -1 - pmullw mm3, mm1 ; mm3 *= kernel 1 modifiers. - - - movq mm4, [rsi + 4*rdx] ; mm4 = p0..p3 = row 2 - pmullw mm4, mm7 ; mm4 *= kernel 4 modifiers. - paddsw mm3, mm4 ; mm3 += mm4 - - movq mm4, [rsi + 2*rdx] ; mm4 = p0..p3 = row 0 - pmullw mm4, mm2 ; mm4 *= kernel 2 modifiers. - paddsw mm3, mm4 ; mm3 += mm4 - - movq mm4, [rsi] ; mm4 = p0..p3 = row -2 - pmullw mm4, [rbx] ; mm4 *= kernel 0 modifiers. - paddsw mm3, mm4 ; mm3 += mm4 - - - add rsi, rdx ; move source forward 1 line to avoid 3 * pitch - movq mm4, [rsi + 2*rdx] ; mm4 = p0..p3 = row 1 - pmullw mm4, mm6 ; mm4 *= kernel 3 modifiers. - paddsw mm3, mm4 ; mm3 += mm4 - - movq mm4, [rsi + 4*rdx] ; mm4 = p0..p3 = row 3 - pmullw mm4, [rbx +80] ; mm4 *= kernel 3 modifiers. - paddsw mm3, mm4 ; mm3 += mm4 - - - paddsw mm3, mm5 ; mm3 += round value - psraw mm3, VP8_FILTER_SHIFT ; mm3 /= 128 - packuswb mm3, mm0 ; pack and saturate - - movd [rdi],mm3 ; store the results in the destination - ; the subsequent iterations repeat 3 out of 4 of these reads. Since the - ; recon block should be in cache this shouldn't cost much. Its obviously - ; avoidable!!!. - lea rdi, [rdi+rax] ; - dec rcx ; decrement count - jnz .nextrow_cv ; next row - - pop rbx - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - UNSHADOW_ARGS - pop rbp - ret - - -SECTION_RODATA -align 16 -rd: - times 4 dw 0x40 - -align 16 -global HIDDEN_DATA(sym(vp8_six_tap_x86)) -sym(vp8_six_tap_x86): - times 8 dw 0 - times 8 dw 0 - times 8 dw 128 - times 8 dw 0 - times 8 dw 0 - times 8 dw 0 - - times 8 dw 0 - times 8 dw -6 - times 8 dw 123 - times 8 dw 12 - times 8 dw -1 - times 8 dw 0 - - times 8 dw 2 - times 8 dw -11 - times 8 dw 108 - times 8 dw 36 - times 8 dw -8 - times 8 dw 1 - - times 8 dw 0 - times 8 dw -9 - times 8 dw 93 - times 8 dw 50 - times 8 dw -6 - times 8 dw 0 - - times 8 dw 3 - times 8 dw -16 - times 8 dw 77 - times 8 dw 77 - times 8 dw -16 - times 8 dw 3 - - times 8 dw 0 - times 8 dw -6 - times 8 dw 50 - times 8 dw 93 - times 8 dw -9 - times 8 dw 0 - - times 8 dw 1 - times 8 dw -8 - times 8 dw 36 - times 8 dw 108 - times 8 dw -11 - times 8 dw 2 - - times 8 dw 0 - times 8 dw -1 - times 8 dw 12 - times 8 dw 123 - times 8 dw -6 - times 8 dw 0 - - diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/subpixel_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/subpixel_sse2.asm deleted file mode 100644 index 94e14aed..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/subpixel_sse2.asm +++ /dev/null @@ -1,963 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -%define BLOCK_HEIGHT_WIDTH 4 -%define VP8_FILTER_WEIGHT 128 -%define VP8_FILTER_SHIFT 7 - -SECTION .text - -;/************************************************************************************ -; Notes: filter_block1d_h6 applies a 6 tap filter horizontally to the input pixels. The -; input pixel array has output_height rows. This routine assumes that output_height is an -; even number. This function handles 8 pixels in horizontal direction, calculating ONE -; rows each iteration to take advantage of the 128 bits operations. -;*************************************************************************************/ -;void vp8_filter_block1d8_h6_sse2 -;( -; unsigned char *src_ptr, -; unsigned short *output_ptr, -; unsigned int src_pixels_per_line, -; unsigned int pixel_step, -; unsigned int output_height, -; unsigned int output_width, -; short *vp8_filter -;) -globalsym(vp8_filter_block1d8_h6_sse2) -sym(vp8_filter_block1d8_h6_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - mov rdx, arg(6) ;vp8_filter - mov rsi, arg(0) ;src_ptr - - mov rdi, arg(1) ;output_ptr - - movsxd rcx, dword ptr arg(4) ;output_height - movsxd rax, dword ptr arg(2) ;src_pixels_per_line ; Pitch for Source -%if ABI_IS_32BIT=0 - movsxd r8, dword ptr arg(5) ;output_width -%endif - pxor xmm0, xmm0 ; clear xmm0 for unpack - -.filter_block1d8_h6_rowloop: - movq xmm3, MMWORD PTR [rsi - 2] - movq xmm1, MMWORD PTR [rsi + 6] - - prefetcht2 [rsi+rax-2] - - pslldq xmm1, 8 - por xmm1, xmm3 - - movdqa xmm4, xmm1 - movdqa xmm5, xmm1 - - movdqa xmm6, xmm1 - movdqa xmm7, xmm1 - - punpcklbw xmm3, xmm0 ; xx05 xx04 xx03 xx02 xx01 xx01 xx-1 xx-2 - psrldq xmm4, 1 ; xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 -1 - - pmullw xmm3, XMMWORD PTR [rdx] ; x[-2] * H[-2]; Tap 1 - punpcklbw xmm4, xmm0 ; xx06 xx05 xx04 xx03 xx02 xx01 xx00 xx-1 - - psrldq xmm5, 2 ; xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 - pmullw xmm4, XMMWORD PTR [rdx+16] ; x[-1] * H[-1]; Tap 2 - - - punpcklbw xmm5, xmm0 ; xx07 xx06 xx05 xx04 xx03 xx02 xx01 xx00 - psrldq xmm6, 3 ; xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 - - pmullw xmm5, [rdx+32] ; x[ 0] * H[ 0]; Tap 3 - - punpcklbw xmm6, xmm0 ; xx08 xx07 xx06 xx05 xx04 xx03 xx02 xx01 - psrldq xmm7, 4 ; xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 - - pmullw xmm6, [rdx+48] ; x[ 1] * h[ 1] ; Tap 4 - - punpcklbw xmm7, xmm0 ; xx09 xx08 xx07 xx06 xx05 xx04 xx03 xx02 - psrldq xmm1, 5 ; xx xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 - - - pmullw xmm7, [rdx+64] ; x[ 2] * h[ 2] ; Tap 5 - - punpcklbw xmm1, xmm0 ; xx0a xx09 xx08 xx07 xx06 xx05 xx04 xx03 - pmullw xmm1, [rdx+80] ; x[ 3] * h[ 3] ; Tap 6 - - - paddsw xmm4, xmm7 - paddsw xmm4, xmm5 - - paddsw xmm4, xmm3 - paddsw xmm4, xmm6 - - paddsw xmm4, xmm1 - paddsw xmm4, [GLOBAL(rd)] - - psraw xmm4, 7 - - packuswb xmm4, xmm0 - punpcklbw xmm4, xmm0 - - movdqa XMMWORD Ptr [rdi], xmm4 - lea rsi, [rsi + rax] - -%if ABI_IS_32BIT - add rdi, DWORD Ptr arg(5) ;[output_width] -%else - add rdi, r8 -%endif - dec rcx - - jnz .filter_block1d8_h6_rowloop ; next row - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - - -;void vp8_filter_block1d16_h6_sse2 -;( -; unsigned char *src_ptr, -; unsigned short *output_ptr, -; unsigned int src_pixels_per_line, -; unsigned int pixel_step, -; unsigned int output_height, -; unsigned int output_width, -; short *vp8_filter -;) -;/************************************************************************************ -; Notes: filter_block1d_h6 applies a 6 tap filter horizontally to the input pixels. The -; input pixel array has output_height rows. This routine assumes that output_height is an -; even number. This function handles 8 pixels in horizontal direction, calculating ONE -; rows each iteration to take advantage of the 128 bits operations. -;*************************************************************************************/ -globalsym(vp8_filter_block1d16_h6_sse2) -sym(vp8_filter_block1d16_h6_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - mov rdx, arg(6) ;vp8_filter - mov rsi, arg(0) ;src_ptr - - mov rdi, arg(1) ;output_ptr - - movsxd rcx, dword ptr arg(4) ;output_height - movsxd rax, dword ptr arg(2) ;src_pixels_per_line ; Pitch for Source -%if ABI_IS_32BIT=0 - movsxd r8, dword ptr arg(5) ;output_width -%endif - - pxor xmm0, xmm0 ; clear xmm0 for unpack - -.filter_block1d16_h6_sse2_rowloop: - movq xmm3, MMWORD PTR [rsi - 2] - movq xmm1, MMWORD PTR [rsi + 6] - - ; Load from 11 to avoid reading out of bounds. - movq xmm2, MMWORD PTR [rsi +11] - ; The lower bits are not cleared before 'or'ing with xmm1, - ; but that is OK because the values in the overlapping positions - ; are already equal to the ones in xmm1. - pslldq xmm2, 5 - - por xmm2, xmm1 - prefetcht2 [rsi+rax-2] - - pslldq xmm1, 8 - por xmm1, xmm3 - - movdqa xmm4, xmm1 - movdqa xmm5, xmm1 - - movdqa xmm6, xmm1 - movdqa xmm7, xmm1 - - punpcklbw xmm3, xmm0 ; xx05 xx04 xx03 xx02 xx01 xx01 xx-1 xx-2 - psrldq xmm4, 1 ; xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 -1 - - pmullw xmm3, XMMWORD PTR [rdx] ; x[-2] * H[-2]; Tap 1 - punpcklbw xmm4, xmm0 ; xx06 xx05 xx04 xx03 xx02 xx01 xx00 xx-1 - - psrldq xmm5, 2 ; xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 - pmullw xmm4, XMMWORD PTR [rdx+16] ; x[-1] * H[-1]; Tap 2 - - - punpcklbw xmm5, xmm0 ; xx07 xx06 xx05 xx04 xx03 xx02 xx01 xx00 - psrldq xmm6, 3 ; xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 - - pmullw xmm5, [rdx+32] ; x[ 0] * H[ 0]; Tap 3 - - punpcklbw xmm6, xmm0 ; xx08 xx07 xx06 xx05 xx04 xx03 xx02 xx01 - psrldq xmm7, 4 ; xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 - - pmullw xmm6, [rdx+48] ; x[ 1] * h[ 1] ; Tap 4 - - punpcklbw xmm7, xmm0 ; xx09 xx08 xx07 xx06 xx05 xx04 xx03 xx02 - psrldq xmm1, 5 ; xx xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 - - - pmullw xmm7, [rdx+64] ; x[ 2] * h[ 2] ; Tap 5 - - punpcklbw xmm1, xmm0 ; xx0a xx09 xx08 xx07 xx06 xx05 xx04 xx03 - pmullw xmm1, [rdx+80] ; x[ 3] * h[ 3] ; Tap 6 - - paddsw xmm4, xmm7 - paddsw xmm4, xmm5 - - paddsw xmm4, xmm3 - paddsw xmm4, xmm6 - - paddsw xmm4, xmm1 - paddsw xmm4, [GLOBAL(rd)] - - psraw xmm4, 7 - - packuswb xmm4, xmm0 - punpcklbw xmm4, xmm0 - - movdqa XMMWORD Ptr [rdi], xmm4 - - movdqa xmm3, xmm2 - movdqa xmm4, xmm2 - - movdqa xmm5, xmm2 - movdqa xmm6, xmm2 - - movdqa xmm7, xmm2 - - punpcklbw xmm3, xmm0 ; xx05 xx04 xx03 xx02 xx01 xx01 xx-1 xx-2 - psrldq xmm4, 1 ; xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 -1 - - pmullw xmm3, XMMWORD PTR [rdx] ; x[-2] * H[-2]; Tap 1 - punpcklbw xmm4, xmm0 ; xx06 xx05 xx04 xx03 xx02 xx01 xx00 xx-1 - - psrldq xmm5, 2 ; xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 - pmullw xmm4, XMMWORD PTR [rdx+16] ; x[-1] * H[-1]; Tap 2 - - - punpcklbw xmm5, xmm0 ; xx07 xx06 xx05 xx04 xx03 xx02 xx01 xx00 - psrldq xmm6, 3 ; xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 - - pmullw xmm5, [rdx+32] ; x[ 0] * H[ 0]; Tap 3 - - punpcklbw xmm6, xmm0 ; xx08 xx07 xx06 xx05 xx04 xx03 xx02 xx01 - psrldq xmm7, 4 ; xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 - - pmullw xmm6, [rdx+48] ; x[ 1] * h[ 1] ; Tap 4 - - punpcklbw xmm7, xmm0 ; xx09 xx08 xx07 xx06 xx05 xx04 xx03 xx02 - psrldq xmm2, 5 ; xx xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 - - pmullw xmm7, [rdx+64] ; x[ 2] * h[ 2] ; Tap 5 - - punpcklbw xmm2, xmm0 ; xx0a xx09 xx08 xx07 xx06 xx05 xx04 xx03 - pmullw xmm2, [rdx+80] ; x[ 3] * h[ 3] ; Tap 6 - - - paddsw xmm4, xmm7 - paddsw xmm4, xmm5 - - paddsw xmm4, xmm3 - paddsw xmm4, xmm6 - - paddsw xmm4, xmm2 - paddsw xmm4, [GLOBAL(rd)] - - psraw xmm4, 7 - - packuswb xmm4, xmm0 - punpcklbw xmm4, xmm0 - - movdqa XMMWORD Ptr [rdi+16], xmm4 - - lea rsi, [rsi + rax] -%if ABI_IS_32BIT - add rdi, DWORD Ptr arg(5) ;[output_width] -%else - add rdi, r8 -%endif - - dec rcx - jnz .filter_block1d16_h6_sse2_rowloop ; next row - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - - -;void vp8_filter_block1d8_v6_sse2 -;( -; short *src_ptr, -; unsigned char *output_ptr, -; int dst_ptich, -; unsigned int pixels_per_line, -; unsigned int pixel_step, -; unsigned int output_height, -; unsigned int output_width, -; short * vp8_filter -;) -;/************************************************************************************ -; Notes: filter_block1d8_v6 applies a 6 tap filter vertically to the input pixels. The -; input pixel array has output_height rows. -;*************************************************************************************/ -globalsym(vp8_filter_block1d8_v6_sse2) -sym(vp8_filter_block1d8_v6_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 8 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - mov rax, arg(7) ;vp8_filter - movsxd rdx, dword ptr arg(3) ;pixels_per_line - - mov rdi, arg(1) ;output_ptr - mov rsi, arg(0) ;src_ptr - - sub rsi, rdx - sub rsi, rdx - - movsxd rcx, DWORD PTR arg(5) ;[output_height] - pxor xmm0, xmm0 ; clear xmm0 - - movdqa xmm7, XMMWORD PTR [GLOBAL(rd)] -%if ABI_IS_32BIT=0 - movsxd r8, dword ptr arg(2) ; dst_ptich -%endif - -.vp8_filter_block1d8_v6_sse2_loop: - movdqa xmm1, XMMWORD PTR [rsi] - pmullw xmm1, [rax] - - movdqa xmm2, XMMWORD PTR [rsi + rdx] - pmullw xmm2, [rax + 16] - - movdqa xmm3, XMMWORD PTR [rsi + rdx * 2] - pmullw xmm3, [rax + 32] - - movdqa xmm5, XMMWORD PTR [rsi + rdx * 4] - pmullw xmm5, [rax + 64] - - add rsi, rdx - movdqa xmm4, XMMWORD PTR [rsi + rdx * 2] - - pmullw xmm4, [rax + 48] - movdqa xmm6, XMMWORD PTR [rsi + rdx * 4] - - pmullw xmm6, [rax + 80] - - paddsw xmm2, xmm5 - paddsw xmm2, xmm3 - - paddsw xmm2, xmm1 - paddsw xmm2, xmm4 - - paddsw xmm2, xmm6 - paddsw xmm2, xmm7 - - psraw xmm2, 7 - packuswb xmm2, xmm0 ; pack and saturate - - movq QWORD PTR [rdi], xmm2 ; store the results in the destination -%if ABI_IS_32BIT - add rdi, DWORD PTR arg(2) ;[dst_ptich] -%else - add rdi, r8 -%endif - dec rcx ; decrement count - jnz .vp8_filter_block1d8_v6_sse2_loop ; next row - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - - -;void vp8_filter_block1d16_v6_sse2 -;( -; unsigned short *src_ptr, -; unsigned char *output_ptr, -; int dst_ptich, -; unsigned int pixels_per_line, -; unsigned int pixel_step, -; unsigned int output_height, -; unsigned int output_width, -; const short *vp8_filter -;) -;/************************************************************************************ -; Notes: filter_block1d16_v6 applies a 6 tap filter vertically to the input pixels. The -; input pixel array has output_height rows. -;*************************************************************************************/ -globalsym(vp8_filter_block1d16_v6_sse2) -sym(vp8_filter_block1d16_v6_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 8 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - mov rax, arg(7) ;vp8_filter - movsxd rdx, dword ptr arg(3) ;pixels_per_line - - mov rdi, arg(1) ;output_ptr - mov rsi, arg(0) ;src_ptr - - sub rsi, rdx - sub rsi, rdx - - movsxd rcx, DWORD PTR arg(5) ;[output_height] -%if ABI_IS_32BIT=0 - movsxd r8, dword ptr arg(2) ; dst_ptich -%endif - -.vp8_filter_block1d16_v6_sse2_loop: -; The order for adding 6-tap is 2 5 3 1 4 6. Read in data in that order. - movdqa xmm1, XMMWORD PTR [rsi + rdx] ; line 2 - movdqa xmm2, XMMWORD PTR [rsi + rdx + 16] - pmullw xmm1, [rax + 16] - pmullw xmm2, [rax + 16] - - movdqa xmm3, XMMWORD PTR [rsi + rdx * 4] ; line 5 - movdqa xmm4, XMMWORD PTR [rsi + rdx * 4 + 16] - pmullw xmm3, [rax + 64] - pmullw xmm4, [rax + 64] - - movdqa xmm5, XMMWORD PTR [rsi + rdx * 2] ; line 3 - movdqa xmm6, XMMWORD PTR [rsi + rdx * 2 + 16] - pmullw xmm5, [rax + 32] - pmullw xmm6, [rax + 32] - - movdqa xmm7, XMMWORD PTR [rsi] ; line 1 - movdqa xmm0, XMMWORD PTR [rsi + 16] - pmullw xmm7, [rax] - pmullw xmm0, [rax] - - paddsw xmm1, xmm3 - paddsw xmm2, xmm4 - paddsw xmm1, xmm5 - paddsw xmm2, xmm6 - paddsw xmm1, xmm7 - paddsw xmm2, xmm0 - - add rsi, rdx - - movdqa xmm3, XMMWORD PTR [rsi + rdx * 2] ; line 4 - movdqa xmm4, XMMWORD PTR [rsi + rdx * 2 + 16] - pmullw xmm3, [rax + 48] - pmullw xmm4, [rax + 48] - - movdqa xmm5, XMMWORD PTR [rsi + rdx * 4] ; line 6 - movdqa xmm6, XMMWORD PTR [rsi + rdx * 4 + 16] - pmullw xmm5, [rax + 80] - pmullw xmm6, [rax + 80] - - movdqa xmm7, XMMWORD PTR [GLOBAL(rd)] - pxor xmm0, xmm0 ; clear xmm0 - - paddsw xmm1, xmm3 - paddsw xmm2, xmm4 - paddsw xmm1, xmm5 - paddsw xmm2, xmm6 - - paddsw xmm1, xmm7 - paddsw xmm2, xmm7 - - psraw xmm1, 7 - psraw xmm2, 7 - - packuswb xmm1, xmm2 ; pack and saturate - movdqa XMMWORD PTR [rdi], xmm1 ; store the results in the destination -%if ABI_IS_32BIT - add rdi, DWORD PTR arg(2) ;[dst_ptich] -%else - add rdi, r8 -%endif - dec rcx ; decrement count - jnz .vp8_filter_block1d16_v6_sse2_loop ; next row - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - - -;void vp8_filter_block1d8_h6_only_sse2 -;( -; unsigned char *src_ptr, -; unsigned int src_pixels_per_line, -; unsigned char *output_ptr, -; int dst_ptich, -; unsigned int output_height, -; const short *vp8_filter -;) -; First-pass filter only when yoffset==0 -globalsym(vp8_filter_block1d8_h6_only_sse2) -sym(vp8_filter_block1d8_h6_only_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - mov rdx, arg(5) ;vp8_filter - mov rsi, arg(0) ;src_ptr - - mov rdi, arg(2) ;output_ptr - - movsxd rcx, dword ptr arg(4) ;output_height - movsxd rax, dword ptr arg(1) ;src_pixels_per_line ; Pitch for Source -%if ABI_IS_32BIT=0 - movsxd r8, dword ptr arg(3) ;dst_ptich -%endif - pxor xmm0, xmm0 ; clear xmm0 for unpack - -.filter_block1d8_h6_only_rowloop: - movq xmm3, MMWORD PTR [rsi - 2] - movq xmm1, MMWORD PTR [rsi + 6] - - prefetcht2 [rsi+rax-2] - - pslldq xmm1, 8 - por xmm1, xmm3 - - movdqa xmm4, xmm1 - movdqa xmm5, xmm1 - - movdqa xmm6, xmm1 - movdqa xmm7, xmm1 - - punpcklbw xmm3, xmm0 ; xx05 xx04 xx03 xx02 xx01 xx01 xx-1 xx-2 - psrldq xmm4, 1 ; xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 -1 - - pmullw xmm3, XMMWORD PTR [rdx] ; x[-2] * H[-2]; Tap 1 - punpcklbw xmm4, xmm0 ; xx06 xx05 xx04 xx03 xx02 xx01 xx00 xx-1 - - psrldq xmm5, 2 ; xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 - pmullw xmm4, XMMWORD PTR [rdx+16] ; x[-1] * H[-1]; Tap 2 - - - punpcklbw xmm5, xmm0 ; xx07 xx06 xx05 xx04 xx03 xx02 xx01 xx00 - psrldq xmm6, 3 ; xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 - - pmullw xmm5, [rdx+32] ; x[ 0] * H[ 0]; Tap 3 - - punpcklbw xmm6, xmm0 ; xx08 xx07 xx06 xx05 xx04 xx03 xx02 xx01 - psrldq xmm7, 4 ; xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 - - pmullw xmm6, [rdx+48] ; x[ 1] * h[ 1] ; Tap 4 - - punpcklbw xmm7, xmm0 ; xx09 xx08 xx07 xx06 xx05 xx04 xx03 xx02 - psrldq xmm1, 5 ; xx xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 - - - pmullw xmm7, [rdx+64] ; x[ 2] * h[ 2] ; Tap 5 - - punpcklbw xmm1, xmm0 ; xx0a xx09 xx08 xx07 xx06 xx05 xx04 xx03 - pmullw xmm1, [rdx+80] ; x[ 3] * h[ 3] ; Tap 6 - - - paddsw xmm4, xmm7 - paddsw xmm4, xmm5 - - paddsw xmm4, xmm3 - paddsw xmm4, xmm6 - - paddsw xmm4, xmm1 - paddsw xmm4, [GLOBAL(rd)] - - psraw xmm4, 7 - - packuswb xmm4, xmm0 - - movq QWORD PTR [rdi], xmm4 ; store the results in the destination - lea rsi, [rsi + rax] - -%if ABI_IS_32BIT - add rdi, DWORD Ptr arg(3) ;dst_ptich -%else - add rdi, r8 -%endif - dec rcx - - jnz .filter_block1d8_h6_only_rowloop ; next row - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - - -;void vp8_filter_block1d16_h6_only_sse2 -;( -; unsigned char *src_ptr, -; unsigned int src_pixels_per_line, -; unsigned char *output_ptr, -; int dst_ptich, -; unsigned int output_height, -; const short *vp8_filter -;) -; First-pass filter only when yoffset==0 -globalsym(vp8_filter_block1d16_h6_only_sse2) -sym(vp8_filter_block1d16_h6_only_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - mov rdx, arg(5) ;vp8_filter - mov rsi, arg(0) ;src_ptr - - mov rdi, arg(2) ;output_ptr - - movsxd rcx, dword ptr arg(4) ;output_height - movsxd rax, dword ptr arg(1) ;src_pixels_per_line ; Pitch for Source -%if ABI_IS_32BIT=0 - movsxd r8, dword ptr arg(3) ;dst_ptich -%endif - - pxor xmm0, xmm0 ; clear xmm0 for unpack - -.filter_block1d16_h6_only_sse2_rowloop: - movq xmm3, MMWORD PTR [rsi - 2] - movq xmm1, MMWORD PTR [rsi + 6] - - movq xmm2, MMWORD PTR [rsi +14] - pslldq xmm2, 8 - - por xmm2, xmm1 - prefetcht2 [rsi+rax-2] - - pslldq xmm1, 8 - por xmm1, xmm3 - - movdqa xmm4, xmm1 - movdqa xmm5, xmm1 - - movdqa xmm6, xmm1 - movdqa xmm7, xmm1 - - punpcklbw xmm3, xmm0 ; xx05 xx04 xx03 xx02 xx01 xx01 xx-1 xx-2 - psrldq xmm4, 1 ; xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 -1 - - pmullw xmm3, XMMWORD PTR [rdx] ; x[-2] * H[-2]; Tap 1 - punpcklbw xmm4, xmm0 ; xx06 xx05 xx04 xx03 xx02 xx01 xx00 xx-1 - - psrldq xmm5, 2 ; xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 - pmullw xmm4, XMMWORD PTR [rdx+16] ; x[-1] * H[-1]; Tap 2 - - punpcklbw xmm5, xmm0 ; xx07 xx06 xx05 xx04 xx03 xx02 xx01 xx00 - psrldq xmm6, 3 ; xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 - - pmullw xmm5, [rdx+32] ; x[ 0] * H[ 0]; Tap 3 - - punpcklbw xmm6, xmm0 ; xx08 xx07 xx06 xx05 xx04 xx03 xx02 xx01 - psrldq xmm7, 4 ; xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 - - pmullw xmm6, [rdx+48] ; x[ 1] * h[ 1] ; Tap 4 - - punpcklbw xmm7, xmm0 ; xx09 xx08 xx07 xx06 xx05 xx04 xx03 xx02 - psrldq xmm1, 5 ; xx xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 - - pmullw xmm7, [rdx+64] ; x[ 2] * h[ 2] ; Tap 5 - - punpcklbw xmm1, xmm0 ; xx0a xx09 xx08 xx07 xx06 xx05 xx04 xx03 - pmullw xmm1, [rdx+80] ; x[ 3] * h[ 3] ; Tap 6 - - paddsw xmm4, xmm7 - paddsw xmm4, xmm5 - - paddsw xmm4, xmm3 - paddsw xmm4, xmm6 - - paddsw xmm4, xmm1 - paddsw xmm4, [GLOBAL(rd)] - - psraw xmm4, 7 - - packuswb xmm4, xmm0 ; lower 8 bytes - - movq QWORD Ptr [rdi], xmm4 ; store the results in the destination - - movdqa xmm3, xmm2 - movdqa xmm4, xmm2 - - movdqa xmm5, xmm2 - movdqa xmm6, xmm2 - - movdqa xmm7, xmm2 - - punpcklbw xmm3, xmm0 ; xx05 xx04 xx03 xx02 xx01 xx01 xx-1 xx-2 - psrldq xmm4, 1 ; xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 -1 - - pmullw xmm3, XMMWORD PTR [rdx] ; x[-2] * H[-2]; Tap 1 - punpcklbw xmm4, xmm0 ; xx06 xx05 xx04 xx03 xx02 xx01 xx00 xx-1 - - psrldq xmm5, 2 ; xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 - pmullw xmm4, XMMWORD PTR [rdx+16] ; x[-1] * H[-1]; Tap 2 - - punpcklbw xmm5, xmm0 ; xx07 xx06 xx05 xx04 xx03 xx02 xx01 xx00 - psrldq xmm6, 3 ; xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 - - pmullw xmm5, [rdx+32] ; x[ 0] * H[ 0]; Tap 3 - - punpcklbw xmm6, xmm0 ; xx08 xx07 xx06 xx05 xx04 xx03 xx02 xx01 - psrldq xmm7, 4 ; xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 - - pmullw xmm6, [rdx+48] ; x[ 1] * h[ 1] ; Tap 4 - - punpcklbw xmm7, xmm0 ; xx09 xx08 xx07 xx06 xx05 xx04 xx03 xx02 - psrldq xmm2, 5 ; xx xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 - - pmullw xmm7, [rdx+64] ; x[ 2] * h[ 2] ; Tap 5 - - punpcklbw xmm2, xmm0 ; xx0a xx09 xx08 xx07 xx06 xx05 xx04 xx03 - pmullw xmm2, [rdx+80] ; x[ 3] * h[ 3] ; Tap 6 - - paddsw xmm4, xmm7 - paddsw xmm4, xmm5 - - paddsw xmm4, xmm3 - paddsw xmm4, xmm6 - - paddsw xmm4, xmm2 - paddsw xmm4, [GLOBAL(rd)] - - psraw xmm4, 7 - - packuswb xmm4, xmm0 ; higher 8 bytes - - movq QWORD Ptr [rdi+8], xmm4 ; store the results in the destination - - lea rsi, [rsi + rax] -%if ABI_IS_32BIT - add rdi, DWORD Ptr arg(3) ;dst_ptich -%else - add rdi, r8 -%endif - - dec rcx - jnz .filter_block1d16_h6_only_sse2_rowloop ; next row - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - - -;void vp8_filter_block1d8_v6_only_sse2 -;( -; unsigned char *src_ptr, -; unsigned int src_pixels_per_line, -; unsigned char *output_ptr, -; int dst_ptich, -; unsigned int output_height, -; const short *vp8_filter -;) -; Second-pass filter only when xoffset==0 -globalsym(vp8_filter_block1d8_v6_only_sse2) -sym(vp8_filter_block1d8_v6_only_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - - movsxd rcx, dword ptr arg(4) ;output_height - movsxd rdx, dword ptr arg(1) ;src_pixels_per_line - - mov rax, arg(5) ;vp8_filter - - pxor xmm0, xmm0 ; clear xmm0 - - movdqa xmm7, XMMWORD PTR [GLOBAL(rd)] -%if ABI_IS_32BIT=0 - movsxd r8, dword ptr arg(3) ; dst_ptich -%endif - -.vp8_filter_block1d8_v6_only_sse2_loop: - movq xmm1, MMWORD PTR [rsi] - movq xmm2, MMWORD PTR [rsi + rdx] - movq xmm3, MMWORD PTR [rsi + rdx * 2] - movq xmm5, MMWORD PTR [rsi + rdx * 4] - add rsi, rdx - movq xmm4, MMWORD PTR [rsi + rdx * 2] - movq xmm6, MMWORD PTR [rsi + rdx * 4] - - punpcklbw xmm1, xmm0 - pmullw xmm1, [rax] - - punpcklbw xmm2, xmm0 - pmullw xmm2, [rax + 16] - - punpcklbw xmm3, xmm0 - pmullw xmm3, [rax + 32] - - punpcklbw xmm5, xmm0 - pmullw xmm5, [rax + 64] - - punpcklbw xmm4, xmm0 - pmullw xmm4, [rax + 48] - - punpcklbw xmm6, xmm0 - pmullw xmm6, [rax + 80] - - paddsw xmm2, xmm5 - paddsw xmm2, xmm3 - - paddsw xmm2, xmm1 - paddsw xmm2, xmm4 - - paddsw xmm2, xmm6 - paddsw xmm2, xmm7 - - psraw xmm2, 7 - packuswb xmm2, xmm0 ; pack and saturate - - movq QWORD PTR [rdi], xmm2 ; store the results in the destination -%if ABI_IS_32BIT - add rdi, DWORD PTR arg(3) ;[dst_ptich] -%else - add rdi, r8 -%endif - dec rcx ; decrement count - jnz .vp8_filter_block1d8_v6_only_sse2_loop ; next row - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - - -;void vp8_unpack_block1d16_h6_sse2 -;( -; unsigned char *src_ptr, -; unsigned short *output_ptr, -; unsigned int src_pixels_per_line, -; unsigned int output_height, -; unsigned int output_width -;) -globalsym(vp8_unpack_block1d16_h6_sse2) -sym(vp8_unpack_block1d16_h6_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 5 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - mov rsi, arg(0) ;src_ptr - mov rdi, arg(1) ;output_ptr - - movsxd rcx, dword ptr arg(3) ;output_height - movsxd rax, dword ptr arg(2) ;src_pixels_per_line ; Pitch for Source - - pxor xmm0, xmm0 ; clear xmm0 for unpack -%if ABI_IS_32BIT=0 - movsxd r8, dword ptr arg(4) ;output_width ; Pitch for Source -%endif - -.unpack_block1d16_h6_sse2_rowloop: - movq xmm1, MMWORD PTR [rsi] ; 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 -1 -2 - movq xmm3, MMWORD PTR [rsi+8] ; make copy of xmm1 - - punpcklbw xmm3, xmm0 ; xx05 xx04 xx03 xx02 xx01 xx01 xx-1 xx-2 - punpcklbw xmm1, xmm0 - - movdqa XMMWORD Ptr [rdi], xmm1 - movdqa XMMWORD Ptr [rdi + 16], xmm3 - - lea rsi, [rsi + rax] -%if ABI_IS_32BIT - add rdi, DWORD Ptr arg(4) ;[output_width] -%else - add rdi, r8 -%endif - dec rcx - jnz .unpack_block1d16_h6_sse2_rowloop ; next row - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - UNSHADOW_ARGS - pop rbp - ret - - -SECTION_RODATA -align 16 -rd: - times 8 dw 0x40 diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/subpixel_ssse3.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/subpixel_ssse3.asm deleted file mode 100644 index 17247227..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/subpixel_ssse3.asm +++ /dev/null @@ -1,1515 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -%define BLOCK_HEIGHT_WIDTH 4 -%define VP8_FILTER_WEIGHT 128 -%define VP8_FILTER_SHIFT 7 - -SECTION .text - -;/************************************************************************************ -; Notes: filter_block1d_h6 applies a 6 tap filter horizontally to the input pixels. The -; input pixel array has output_height rows. This routine assumes that output_height is an -; even number. This function handles 8 pixels in horizontal direction, calculating ONE -; rows each iteration to take advantage of the 128 bits operations. -; -; This is an implementation of some of the SSE optimizations first seen in ffvp8 -; -;*************************************************************************************/ -;void vp8_filter_block1d8_h6_ssse3 -;( -; unsigned char *src_ptr, -; unsigned int src_pixels_per_line, -; unsigned char *output_ptr, -; unsigned int output_pitch, -; unsigned int output_height, -; unsigned int vp8_filter_index -;) -globalsym(vp8_filter_block1d8_h6_ssse3) -sym(vp8_filter_block1d8_h6_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - movsxd rdx, DWORD PTR arg(5) ;table index - xor rsi, rsi - shl rdx, 4 - - movdqa xmm7, [GLOBAL(rd)] - - lea rax, [GLOBAL(k0_k5)] - add rax, rdx - mov rdi, arg(2) ;output_ptr - - cmp esi, DWORD PTR [rax] - je vp8_filter_block1d8_h4_ssse3 - - movdqa xmm4, XMMWORD PTR [rax] ;k0_k5 - movdqa xmm5, XMMWORD PTR [rax+256] ;k2_k4 - movdqa xmm6, XMMWORD PTR [rax+128] ;k1_k3 - - mov rsi, arg(0) ;src_ptr - movsxd rax, dword ptr arg(1) ;src_pixels_per_line - movsxd rcx, dword ptr arg(4) ;output_height - - movsxd rdx, dword ptr arg(3) ;output_pitch - - sub rdi, rdx -;xmm3 free -.filter_block1d8_h6_rowloop_ssse3: - movq xmm0, MMWORD PTR [rsi - 2] ; -2 -1 0 1 2 3 4 5 - - movq xmm2, MMWORD PTR [rsi + 3] ; 3 4 5 6 7 8 9 10 - - punpcklbw xmm0, xmm2 ; -2 3 -1 4 0 5 1 6 2 7 3 8 4 9 5 10 - - movdqa xmm1, xmm0 - pmaddubsw xmm0, xmm4 - - movdqa xmm2, xmm1 - pshufb xmm1, [GLOBAL(shuf2bfrom1)] - - pshufb xmm2, [GLOBAL(shuf3bfrom1)] - pmaddubsw xmm1, xmm5 - - lea rdi, [rdi + rdx] - pmaddubsw xmm2, xmm6 - - lea rsi, [rsi + rax] - dec rcx - - paddsw xmm0, xmm1 - paddsw xmm2, xmm7 - - paddsw xmm0, xmm2 - - psraw xmm0, 7 - - packuswb xmm0, xmm0 - - movq MMWORD Ptr [rdi], xmm0 - jnz .filter_block1d8_h6_rowloop_ssse3 - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -vp8_filter_block1d8_h4_ssse3: - movdqa xmm5, XMMWORD PTR [rax+256] ;k2_k4 - movdqa xmm6, XMMWORD PTR [rax+128] ;k1_k3 - - movdqa xmm3, XMMWORD PTR [GLOBAL(shuf2bfrom1)] - movdqa xmm4, XMMWORD PTR [GLOBAL(shuf3bfrom1)] - - mov rsi, arg(0) ;src_ptr - - movsxd rax, dword ptr arg(1) ;src_pixels_per_line - movsxd rcx, dword ptr arg(4) ;output_height - - movsxd rdx, dword ptr arg(3) ;output_pitch - - sub rdi, rdx - -.filter_block1d8_h4_rowloop_ssse3: - movq xmm0, MMWORD PTR [rsi - 2] ; -2 -1 0 1 2 3 4 5 - - movq xmm1, MMWORD PTR [rsi + 3] ; 3 4 5 6 7 8 9 10 - - punpcklbw xmm0, xmm1 ; -2 3 -1 4 0 5 1 6 2 7 3 8 4 9 5 10 - - movdqa xmm2, xmm0 - pshufb xmm0, xmm3 - - pshufb xmm2, xmm4 - pmaddubsw xmm0, xmm5 - - lea rdi, [rdi + rdx] - pmaddubsw xmm2, xmm6 - - lea rsi, [rsi + rax] - dec rcx - - paddsw xmm0, xmm7 - - paddsw xmm0, xmm2 - - psraw xmm0, 7 - - packuswb xmm0, xmm0 - - movq MMWORD Ptr [rdi], xmm0 - - jnz .filter_block1d8_h4_rowloop_ssse3 - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret -;void vp8_filter_block1d16_h6_ssse3 -;( -; unsigned char *src_ptr, -; unsigned int src_pixels_per_line, -; unsigned char *output_ptr, -; unsigned int output_pitch, -; unsigned int output_height, -; unsigned int vp8_filter_index -;) -globalsym(vp8_filter_block1d16_h6_ssse3) -sym(vp8_filter_block1d16_h6_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - movsxd rdx, DWORD PTR arg(5) ;table index - xor rsi, rsi - shl rdx, 4 ; - - lea rax, [GLOBAL(k0_k5)] - add rax, rdx - - mov rdi, arg(2) ;output_ptr - - mov rsi, arg(0) ;src_ptr - - movdqa xmm4, XMMWORD PTR [rax] ;k0_k5 - movdqa xmm5, XMMWORD PTR [rax+256] ;k2_k4 - movdqa xmm6, XMMWORD PTR [rax+128] ;k1_k3 - - movsxd rax, dword ptr arg(1) ;src_pixels_per_line - movsxd rcx, dword ptr arg(4) ;output_height - movsxd rdx, dword ptr arg(3) ;output_pitch - -.filter_block1d16_h6_rowloop_ssse3: - movq xmm0, MMWORD PTR [rsi - 2] ; -2 -1 0 1 2 3 4 5 - - movq xmm3, MMWORD PTR [rsi + 3] ; 3 4 5 6 7 8 9 10 - - punpcklbw xmm0, xmm3 ; -2 3 -1 4 0 5 1 6 2 7 3 8 4 9 5 10 - - movdqa xmm1, xmm0 - pmaddubsw xmm0, xmm4 - - movdqa xmm2, xmm1 - pshufb xmm1, [GLOBAL(shuf2bfrom1)] - - pshufb xmm2, [GLOBAL(shuf3bfrom1)] - movq xmm3, MMWORD PTR [rsi + 6] - - pmaddubsw xmm1, xmm5 - movq xmm7, MMWORD PTR [rsi + 11] - - pmaddubsw xmm2, xmm6 - punpcklbw xmm3, xmm7 - - paddsw xmm0, xmm1 - movdqa xmm1, xmm3 - - pmaddubsw xmm3, xmm4 - paddsw xmm0, xmm2 - - movdqa xmm2, xmm1 - paddsw xmm0, [GLOBAL(rd)] - - pshufb xmm1, [GLOBAL(shuf2bfrom1)] - pshufb xmm2, [GLOBAL(shuf3bfrom1)] - - psraw xmm0, 7 - pmaddubsw xmm1, xmm5 - - pmaddubsw xmm2, xmm6 - packuswb xmm0, xmm0 - - lea rsi, [rsi + rax] - paddsw xmm3, xmm1 - - paddsw xmm3, xmm2 - - paddsw xmm3, [GLOBAL(rd)] - - psraw xmm3, 7 - - packuswb xmm3, xmm3 - - punpcklqdq xmm0, xmm3 - - movdqa XMMWORD Ptr [rdi], xmm0 - - lea rdi, [rdi + rdx] - dec rcx - jnz .filter_block1d16_h6_rowloop_ssse3 - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -;void vp8_filter_block1d4_h6_ssse3 -;( -; unsigned char *src_ptr, -; unsigned int src_pixels_per_line, -; unsigned char *output_ptr, -; unsigned int output_pitch, -; unsigned int output_height, -; unsigned int vp8_filter_index -;) -globalsym(vp8_filter_block1d4_h6_ssse3) -sym(vp8_filter_block1d4_h6_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - movsxd rdx, DWORD PTR arg(5) ;table index - xor rsi, rsi - shl rdx, 4 ; - - lea rax, [GLOBAL(k0_k5)] - add rax, rdx - movdqa xmm7, [GLOBAL(rd)] - - cmp esi, DWORD PTR [rax] - je .vp8_filter_block1d4_h4_ssse3 - - movdqa xmm4, XMMWORD PTR [rax] ;k0_k5 - movdqa xmm5, XMMWORD PTR [rax+256] ;k2_k4 - movdqa xmm6, XMMWORD PTR [rax+128] ;k1_k3 - - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - movsxd rax, dword ptr arg(1) ;src_pixels_per_line - movsxd rcx, dword ptr arg(4) ;output_height - - movsxd rdx, dword ptr arg(3) ;output_pitch - -;xmm3 free -.filter_block1d4_h6_rowloop_ssse3: - movdqu xmm0, XMMWORD PTR [rsi - 2] - - movdqa xmm1, xmm0 - pshufb xmm0, [GLOBAL(shuf1b)] - - movdqa xmm2, xmm1 - pshufb xmm1, [GLOBAL(shuf2b)] - pmaddubsw xmm0, xmm4 - pshufb xmm2, [GLOBAL(shuf3b)] - pmaddubsw xmm1, xmm5 - -;-- - pmaddubsw xmm2, xmm6 - - lea rsi, [rsi + rax] -;-- - paddsw xmm0, xmm1 - paddsw xmm0, xmm7 - pxor xmm1, xmm1 - paddsw xmm0, xmm2 - psraw xmm0, 7 - packuswb xmm0, xmm0 - - movd DWORD PTR [rdi], xmm0 - - add rdi, rdx - dec rcx - jnz .filter_block1d4_h6_rowloop_ssse3 - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -.vp8_filter_block1d4_h4_ssse3: - movdqa xmm5, XMMWORD PTR [rax+256] ;k2_k4 - movdqa xmm6, XMMWORD PTR [rax+128] ;k1_k3 - movdqa xmm0, XMMWORD PTR [GLOBAL(shuf2b)] - movdqa xmm3, XMMWORD PTR [GLOBAL(shuf3b)] - - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - movsxd rax, dword ptr arg(1) ;src_pixels_per_line - movsxd rcx, dword ptr arg(4) ;output_height - - movsxd rdx, dword ptr arg(3) ;output_pitch - -.filter_block1d4_h4_rowloop_ssse3: - movdqu xmm1, XMMWORD PTR [rsi - 2] - - movdqa xmm2, xmm1 - pshufb xmm1, xmm0 ;;[GLOBAL(shuf2b)] - pshufb xmm2, xmm3 ;;[GLOBAL(shuf3b)] - pmaddubsw xmm1, xmm5 - -;-- - pmaddubsw xmm2, xmm6 - - lea rsi, [rsi + rax] -;-- - paddsw xmm1, xmm7 - paddsw xmm1, xmm2 - psraw xmm1, 7 - packuswb xmm1, xmm1 - - movd DWORD PTR [rdi], xmm1 - - add rdi, rdx - dec rcx - jnz .filter_block1d4_h4_rowloop_ssse3 - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - - - -;void vp8_filter_block1d16_v6_ssse3 -;( -; unsigned char *src_ptr, -; unsigned int src_pitch, -; unsigned char *output_ptr, -; unsigned int out_pitch, -; unsigned int output_height, -; unsigned int vp8_filter_index -;) -globalsym(vp8_filter_block1d16_v6_ssse3) -sym(vp8_filter_block1d16_v6_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - movsxd rdx, DWORD PTR arg(5) ;table index - xor rsi, rsi - shl rdx, 4 ; - - lea rax, [GLOBAL(k0_k5)] - add rax, rdx - - cmp esi, DWORD PTR [rax] - je .vp8_filter_block1d16_v4_ssse3 - - movdqa xmm5, XMMWORD PTR [rax] ;k0_k5 - movdqa xmm6, XMMWORD PTR [rax+256] ;k2_k4 - movdqa xmm7, XMMWORD PTR [rax+128] ;k1_k3 - - mov rsi, arg(0) ;src_ptr - movsxd rdx, DWORD PTR arg(1) ;pixels_per_line - mov rdi, arg(2) ;output_ptr - -%if ABI_IS_32BIT=0 - movsxd r8, DWORD PTR arg(3) ;out_pitch -%endif - mov rax, rsi - movsxd rcx, DWORD PTR arg(4) ;output_height - add rax, rdx - - -.vp8_filter_block1d16_v6_ssse3_loop: - movq xmm1, MMWORD PTR [rsi] ;A - movq xmm2, MMWORD PTR [rsi + rdx] ;B - movq xmm3, MMWORD PTR [rsi + rdx * 2] ;C - movq xmm4, MMWORD PTR [rax + rdx * 2] ;D - movq xmm0, MMWORD PTR [rsi + rdx * 4] ;E - - punpcklbw xmm2, xmm4 ;B D - punpcklbw xmm3, xmm0 ;C E - - movq xmm0, MMWORD PTR [rax + rdx * 4] ;F - - pmaddubsw xmm3, xmm6 - punpcklbw xmm1, xmm0 ;A F - pmaddubsw xmm2, xmm7 - pmaddubsw xmm1, xmm5 - - paddsw xmm2, xmm3 - paddsw xmm2, xmm1 - paddsw xmm2, [GLOBAL(rd)] - psraw xmm2, 7 - packuswb xmm2, xmm2 - - movq MMWORD PTR [rdi], xmm2 ;store the results - - movq xmm1, MMWORD PTR [rsi + 8] ;A - movq xmm2, MMWORD PTR [rsi + rdx + 8] ;B - movq xmm3, MMWORD PTR [rsi + rdx * 2 + 8] ;C - movq xmm4, MMWORD PTR [rax + rdx * 2 + 8] ;D - movq xmm0, MMWORD PTR [rsi + rdx * 4 + 8] ;E - - punpcklbw xmm2, xmm4 ;B D - punpcklbw xmm3, xmm0 ;C E - - movq xmm0, MMWORD PTR [rax + rdx * 4 + 8] ;F - pmaddubsw xmm3, xmm6 - punpcklbw xmm1, xmm0 ;A F - pmaddubsw xmm2, xmm7 - pmaddubsw xmm1, xmm5 - - add rsi, rdx - add rax, rdx -;-- -;-- - paddsw xmm2, xmm3 - paddsw xmm2, xmm1 - paddsw xmm2, [GLOBAL(rd)] - psraw xmm2, 7 - packuswb xmm2, xmm2 - - movq MMWORD PTR [rdi+8], xmm2 - -%if ABI_IS_32BIT - add rdi, DWORD PTR arg(3) ;out_pitch -%else - add rdi, r8 -%endif - dec rcx - jnz .vp8_filter_block1d16_v6_ssse3_loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -.vp8_filter_block1d16_v4_ssse3: - movdqa xmm6, XMMWORD PTR [rax+256] ;k2_k4 - movdqa xmm7, XMMWORD PTR [rax+128] ;k1_k3 - - mov rsi, arg(0) ;src_ptr - movsxd rdx, DWORD PTR arg(1) ;pixels_per_line - mov rdi, arg(2) ;output_ptr - -%if ABI_IS_32BIT=0 - movsxd r8, DWORD PTR arg(3) ;out_pitch -%endif - mov rax, rsi - movsxd rcx, DWORD PTR arg(4) ;output_height - add rax, rdx - -.vp8_filter_block1d16_v4_ssse3_loop: - movq xmm2, MMWORD PTR [rsi + rdx] ;B - movq xmm3, MMWORD PTR [rsi + rdx * 2] ;C - movq xmm4, MMWORD PTR [rax + rdx * 2] ;D - movq xmm0, MMWORD PTR [rsi + rdx * 4] ;E - - punpcklbw xmm2, xmm4 ;B D - punpcklbw xmm3, xmm0 ;C E - - pmaddubsw xmm3, xmm6 - pmaddubsw xmm2, xmm7 - movq xmm5, MMWORD PTR [rsi + rdx + 8] ;B - movq xmm1, MMWORD PTR [rsi + rdx * 2 + 8] ;C - movq xmm4, MMWORD PTR [rax + rdx * 2 + 8] ;D - movq xmm0, MMWORD PTR [rsi + rdx * 4 + 8] ;E - - paddsw xmm2, [GLOBAL(rd)] - paddsw xmm2, xmm3 - psraw xmm2, 7 - packuswb xmm2, xmm2 - - punpcklbw xmm5, xmm4 ;B D - punpcklbw xmm1, xmm0 ;C E - - pmaddubsw xmm1, xmm6 - pmaddubsw xmm5, xmm7 - - movdqa xmm4, [GLOBAL(rd)] - add rsi, rdx - add rax, rdx -;-- -;-- - paddsw xmm5, xmm1 - paddsw xmm5, xmm4 - psraw xmm5, 7 - packuswb xmm5, xmm5 - - punpcklqdq xmm2, xmm5 - - movdqa XMMWORD PTR [rdi], xmm2 - -%if ABI_IS_32BIT - add rdi, DWORD PTR arg(3) ;out_pitch -%else - add rdi, r8 -%endif - dec rcx - jnz .vp8_filter_block1d16_v4_ssse3_loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -;void vp8_filter_block1d8_v6_ssse3 -;( -; unsigned char *src_ptr, -; unsigned int src_pitch, -; unsigned char *output_ptr, -; unsigned int out_pitch, -; unsigned int output_height, -; unsigned int vp8_filter_index -;) -globalsym(vp8_filter_block1d8_v6_ssse3) -sym(vp8_filter_block1d8_v6_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - movsxd rdx, DWORD PTR arg(5) ;table index - xor rsi, rsi - shl rdx, 4 ; - - lea rax, [GLOBAL(k0_k5)] - add rax, rdx - - movsxd rdx, DWORD PTR arg(1) ;pixels_per_line - mov rdi, arg(2) ;output_ptr -%if ABI_IS_32BIT=0 - movsxd r8, DWORD PTR arg(3) ; out_pitch -%endif - movsxd rcx, DWORD PTR arg(4) ;[output_height] - - cmp esi, DWORD PTR [rax] - je .vp8_filter_block1d8_v4_ssse3 - - movdqa xmm5, XMMWORD PTR [rax] ;k0_k5 - movdqa xmm6, XMMWORD PTR [rax+256] ;k2_k4 - movdqa xmm7, XMMWORD PTR [rax+128] ;k1_k3 - - mov rsi, arg(0) ;src_ptr - - mov rax, rsi - add rax, rdx - -.vp8_filter_block1d8_v6_ssse3_loop: - movq xmm1, MMWORD PTR [rsi] ;A - movq xmm2, MMWORD PTR [rsi + rdx] ;B - movq xmm3, MMWORD PTR [rsi + rdx * 2] ;C - movq xmm4, MMWORD PTR [rax + rdx * 2] ;D - movq xmm0, MMWORD PTR [rsi + rdx * 4] ;E - - punpcklbw xmm2, xmm4 ;B D - punpcklbw xmm3, xmm0 ;C E - - movq xmm0, MMWORD PTR [rax + rdx * 4] ;F - movdqa xmm4, [GLOBAL(rd)] - - pmaddubsw xmm3, xmm6 - punpcklbw xmm1, xmm0 ;A F - pmaddubsw xmm2, xmm7 - pmaddubsw xmm1, xmm5 - add rsi, rdx - add rax, rdx -;-- -;-- - paddsw xmm2, xmm3 - paddsw xmm2, xmm1 - paddsw xmm2, xmm4 - psraw xmm2, 7 - packuswb xmm2, xmm2 - - movq MMWORD PTR [rdi], xmm2 - -%if ABI_IS_32BIT - add rdi, DWORD PTR arg(3) ;[out_pitch] -%else - add rdi, r8 -%endif - dec rcx - jnz .vp8_filter_block1d8_v6_ssse3_loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -.vp8_filter_block1d8_v4_ssse3: - movdqa xmm6, XMMWORD PTR [rax+256] ;k2_k4 - movdqa xmm7, XMMWORD PTR [rax+128] ;k1_k3 - movdqa xmm5, [GLOBAL(rd)] - - mov rsi, arg(0) ;src_ptr - - mov rax, rsi - add rax, rdx - -.vp8_filter_block1d8_v4_ssse3_loop: - movq xmm2, MMWORD PTR [rsi + rdx] ;B - movq xmm3, MMWORD PTR [rsi + rdx * 2] ;C - movq xmm4, MMWORD PTR [rax + rdx * 2] ;D - movq xmm0, MMWORD PTR [rsi + rdx * 4] ;E - - punpcklbw xmm2, xmm4 ;B D - punpcklbw xmm3, xmm0 ;C E - - pmaddubsw xmm3, xmm6 - pmaddubsw xmm2, xmm7 - add rsi, rdx - add rax, rdx -;-- -;-- - paddsw xmm2, xmm3 - paddsw xmm2, xmm5 - psraw xmm2, 7 - packuswb xmm2, xmm2 - - movq MMWORD PTR [rdi], xmm2 - -%if ABI_IS_32BIT - add rdi, DWORD PTR arg(3) ;[out_pitch] -%else - add rdi, r8 -%endif - dec rcx - jnz .vp8_filter_block1d8_v4_ssse3_loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret -;void vp8_filter_block1d4_v6_ssse3 -;( -; unsigned char *src_ptr, -; unsigned int src_pitch, -; unsigned char *output_ptr, -; unsigned int out_pitch, -; unsigned int output_height, -; unsigned int vp8_filter_index -;) -globalsym(vp8_filter_block1d4_v6_ssse3) -sym(vp8_filter_block1d4_v6_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - movsxd rdx, DWORD PTR arg(5) ;table index - xor rsi, rsi - shl rdx, 4 ; - - lea rax, [GLOBAL(k0_k5)] - add rax, rdx - - movsxd rdx, DWORD PTR arg(1) ;pixels_per_line - mov rdi, arg(2) ;output_ptr -%if ABI_IS_32BIT=0 - movsxd r8, DWORD PTR arg(3) ; out_pitch -%endif - movsxd rcx, DWORD PTR arg(4) ;[output_height] - - cmp esi, DWORD PTR [rax] - je .vp8_filter_block1d4_v4_ssse3 - - movq mm5, MMWORD PTR [rax] ;k0_k5 - movq mm6, MMWORD PTR [rax+256] ;k2_k4 - movq mm7, MMWORD PTR [rax+128] ;k1_k3 - - mov rsi, arg(0) ;src_ptr - - mov rax, rsi - add rax, rdx - -.vp8_filter_block1d4_v6_ssse3_loop: - movd mm1, DWORD PTR [rsi] ;A - movd mm2, DWORD PTR [rsi + rdx] ;B - movd mm3, DWORD PTR [rsi + rdx * 2] ;C - movd mm4, DWORD PTR [rax + rdx * 2] ;D - movd mm0, DWORD PTR [rsi + rdx * 4] ;E - - punpcklbw mm2, mm4 ;B D - punpcklbw mm3, mm0 ;C E - - movd mm0, DWORD PTR [rax + rdx * 4] ;F - - movq mm4, [GLOBAL(rd)] - - pmaddubsw mm3, mm6 - punpcklbw mm1, mm0 ;A F - pmaddubsw mm2, mm7 - pmaddubsw mm1, mm5 - add rsi, rdx - add rax, rdx -;-- -;-- - paddsw mm2, mm3 - paddsw mm2, mm1 - paddsw mm2, mm4 - psraw mm2, 7 - packuswb mm2, mm2 - - movd DWORD PTR [rdi], mm2 - -%if ABI_IS_32BIT - add rdi, DWORD PTR arg(3) ;[out_pitch] -%else - add rdi, r8 -%endif - dec rcx - jnz .vp8_filter_block1d4_v6_ssse3_loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - UNSHADOW_ARGS - pop rbp - ret - -.vp8_filter_block1d4_v4_ssse3: - movq mm6, MMWORD PTR [rax+256] ;k2_k4 - movq mm7, MMWORD PTR [rax+128] ;k1_k3 - movq mm5, MMWORD PTR [GLOBAL(rd)] - - mov rsi, arg(0) ;src_ptr - - mov rax, rsi - add rax, rdx - -.vp8_filter_block1d4_v4_ssse3_loop: - movd mm2, DWORD PTR [rsi + rdx] ;B - movd mm3, DWORD PTR [rsi + rdx * 2] ;C - movd mm4, DWORD PTR [rax + rdx * 2] ;D - movd mm0, DWORD PTR [rsi + rdx * 4] ;E - - punpcklbw mm2, mm4 ;B D - punpcklbw mm3, mm0 ;C E - - pmaddubsw mm3, mm6 - pmaddubsw mm2, mm7 - add rsi, rdx - add rax, rdx -;-- -;-- - paddsw mm2, mm3 - paddsw mm2, mm5 - psraw mm2, 7 - packuswb mm2, mm2 - - movd DWORD PTR [rdi], mm2 - -%if ABI_IS_32BIT - add rdi, DWORD PTR arg(3) ;[out_pitch] -%else - add rdi, r8 -%endif - dec rcx - jnz .vp8_filter_block1d4_v4_ssse3_loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - UNSHADOW_ARGS - pop rbp - ret - -;void vp8_bilinear_predict16x16_ssse3 -;( -; unsigned char *src_ptr, -; int src_pixels_per_line, -; int xoffset, -; int yoffset, -; unsigned char *dst_ptr, -; int dst_pitch -;) -globalsym(vp8_bilinear_predict16x16_ssse3) -sym(vp8_bilinear_predict16x16_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - lea rcx, [GLOBAL(vp8_bilinear_filters_ssse3)] - movsxd rax, dword ptr arg(2) ; xoffset - - cmp rax, 0 ; skip first_pass filter if xoffset=0 - je .b16x16_sp_only - - shl rax, 4 - lea rax, [rax + rcx] ; HFilter - - mov rdi, arg(4) ; dst_ptr - mov rsi, arg(0) ; src_ptr - movsxd rdx, dword ptr arg(5) ; dst_pitch - - movdqa xmm1, [rax] - - movsxd rax, dword ptr arg(3) ; yoffset - - cmp rax, 0 ; skip second_pass filter if yoffset=0 - je .b16x16_fp_only - - shl rax, 4 - lea rax, [rax + rcx] ; VFilter - - lea rcx, [rdi+rdx*8] - lea rcx, [rcx+rdx*8] - movsxd rdx, dword ptr arg(1) ; src_pixels_per_line - - movdqa xmm2, [rax] - -%if ABI_IS_32BIT=0 - movsxd r8, dword ptr arg(5) ; dst_pitch -%endif - movq xmm3, [rsi] ; 00 01 02 03 04 05 06 07 - movq xmm5, [rsi+1] ; 01 02 03 04 05 06 07 08 - - punpcklbw xmm3, xmm5 ; 00 01 01 02 02 03 03 04 04 05 05 06 06 07 07 08 - movq xmm4, [rsi+8] ; 08 09 10 11 12 13 14 15 - - movq xmm5, [rsi+9] ; 09 10 11 12 13 14 15 16 - - lea rsi, [rsi + rdx] ; next line - - pmaddubsw xmm3, xmm1 ; 00 02 04 06 08 10 12 14 - - punpcklbw xmm4, xmm5 ; 08 09 09 10 10 11 11 12 12 13 13 14 14 15 15 16 - pmaddubsw xmm4, xmm1 ; 01 03 05 07 09 11 13 15 - - paddw xmm3, [GLOBAL(rd)] ; xmm3 += round value - psraw xmm3, VP8_FILTER_SHIFT ; xmm3 /= 128 - - paddw xmm4, [GLOBAL(rd)] ; xmm4 += round value - psraw xmm4, VP8_FILTER_SHIFT ; xmm4 /= 128 - - movdqa xmm7, xmm3 - packuswb xmm7, xmm4 ; 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 - -.next_row: - movq xmm6, [rsi] ; 00 01 02 03 04 05 06 07 - movq xmm5, [rsi+1] ; 01 02 03 04 05 06 07 08 - - punpcklbw xmm6, xmm5 - movq xmm4, [rsi+8] ; 08 09 10 11 12 13 14 15 - - movq xmm5, [rsi+9] ; 09 10 11 12 13 14 15 16 - lea rsi, [rsi + rdx] ; next line - - pmaddubsw xmm6, xmm1 - - punpcklbw xmm4, xmm5 - pmaddubsw xmm4, xmm1 - - paddw xmm6, [GLOBAL(rd)] ; xmm6 += round value - psraw xmm6, VP8_FILTER_SHIFT ; xmm6 /= 128 - - paddw xmm4, [GLOBAL(rd)] ; xmm4 += round value - psraw xmm4, VP8_FILTER_SHIFT ; xmm4 /= 128 - - packuswb xmm6, xmm4 - movdqa xmm5, xmm7 - - punpcklbw xmm5, xmm6 - pmaddubsw xmm5, xmm2 - - punpckhbw xmm7, xmm6 - pmaddubsw xmm7, xmm2 - - paddw xmm5, [GLOBAL(rd)] ; xmm5 += round value - psraw xmm5, VP8_FILTER_SHIFT ; xmm5 /= 128 - - paddw xmm7, [GLOBAL(rd)] ; xmm7 += round value - psraw xmm7, VP8_FILTER_SHIFT ; xmm7 /= 128 - - packuswb xmm5, xmm7 - movdqa xmm7, xmm6 - - movdqa [rdi], xmm5 ; store the results in the destination -%if ABI_IS_32BIT - add rdi, DWORD PTR arg(5) ; dst_pitch -%else - add rdi, r8 -%endif - - cmp rdi, rcx - jne .next_row - - jmp .done - -.b16x16_sp_only: - movsxd rax, dword ptr arg(3) ; yoffset - shl rax, 4 - lea rax, [rax + rcx] ; VFilter - - mov rdi, arg(4) ; dst_ptr - mov rsi, arg(0) ; src_ptr - movsxd rdx, dword ptr arg(5) ; dst_pitch - - movdqa xmm1, [rax] ; VFilter - - lea rcx, [rdi+rdx*8] - lea rcx, [rcx+rdx*8] - movsxd rax, dword ptr arg(1) ; src_pixels_per_line - - ; get the first horizontal line done - movq xmm4, [rsi] ; load row 0 - movq xmm2, [rsi + 8] ; load row 0 - - lea rsi, [rsi + rax] ; next line -.next_row_sp: - movq xmm3, [rsi] ; load row + 1 - movq xmm5, [rsi + 8] ; load row + 1 - - punpcklbw xmm4, xmm3 - punpcklbw xmm2, xmm5 - - pmaddubsw xmm4, xmm1 - movq xmm7, [rsi + rax] ; load row + 2 - - pmaddubsw xmm2, xmm1 - movq xmm6, [rsi + rax + 8] ; load row + 2 - - punpcklbw xmm3, xmm7 - punpcklbw xmm5, xmm6 - - pmaddubsw xmm3, xmm1 - paddw xmm4, [GLOBAL(rd)] - - pmaddubsw xmm5, xmm1 - paddw xmm2, [GLOBAL(rd)] - - psraw xmm4, VP8_FILTER_SHIFT - psraw xmm2, VP8_FILTER_SHIFT - - packuswb xmm4, xmm2 - paddw xmm3, [GLOBAL(rd)] - - movdqa [rdi], xmm4 ; store row 0 - paddw xmm5, [GLOBAL(rd)] - - psraw xmm3, VP8_FILTER_SHIFT - psraw xmm5, VP8_FILTER_SHIFT - - packuswb xmm3, xmm5 - movdqa xmm4, xmm7 - - movdqa [rdi + rdx],xmm3 ; store row 1 - lea rsi, [rsi + 2*rax] - - movdqa xmm2, xmm6 - lea rdi, [rdi + 2*rdx] - - cmp rdi, rcx - jne .next_row_sp - - jmp .done - -.b16x16_fp_only: - lea rcx, [rdi+rdx*8] - lea rcx, [rcx+rdx*8] - movsxd rax, dword ptr arg(1) ; src_pixels_per_line - -.next_row_fp: - movq xmm2, [rsi] ; 00 01 02 03 04 05 06 07 - movq xmm4, [rsi+1] ; 01 02 03 04 05 06 07 08 - - punpcklbw xmm2, xmm4 - movq xmm3, [rsi+8] ; 08 09 10 11 12 13 14 15 - - pmaddubsw xmm2, xmm1 - movq xmm4, [rsi+9] ; 09 10 11 12 13 14 15 16 - - lea rsi, [rsi + rax] ; next line - punpcklbw xmm3, xmm4 - - pmaddubsw xmm3, xmm1 - movq xmm5, [rsi] - - paddw xmm2, [GLOBAL(rd)] - movq xmm7, [rsi+1] - - movq xmm6, [rsi+8] - psraw xmm2, VP8_FILTER_SHIFT - - punpcklbw xmm5, xmm7 - movq xmm7, [rsi+9] - - paddw xmm3, [GLOBAL(rd)] - pmaddubsw xmm5, xmm1 - - psraw xmm3, VP8_FILTER_SHIFT - punpcklbw xmm6, xmm7 - - packuswb xmm2, xmm3 - pmaddubsw xmm6, xmm1 - - movdqa [rdi], xmm2 ; store the results in the destination - paddw xmm5, [GLOBAL(rd)] - - lea rdi, [rdi + rdx] ; dst_pitch - psraw xmm5, VP8_FILTER_SHIFT - - paddw xmm6, [GLOBAL(rd)] - psraw xmm6, VP8_FILTER_SHIFT - - packuswb xmm5, xmm6 - lea rsi, [rsi + rax] ; next line - - movdqa [rdi], xmm5 ; store the results in the destination - lea rdi, [rdi + rdx] ; dst_pitch - - cmp rdi, rcx - - jne .next_row_fp - -.done: - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -;void vp8_bilinear_predict8x8_ssse3 -;( -; unsigned char *src_ptr, -; int src_pixels_per_line, -; int xoffset, -; int yoffset, -; unsigned char *dst_ptr, -; int dst_pitch -;) -globalsym(vp8_bilinear_predict8x8_ssse3) -sym(vp8_bilinear_predict8x8_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 144 ; reserve 144 bytes - - lea rcx, [GLOBAL(vp8_bilinear_filters_ssse3)] - - mov rsi, arg(0) ;src_ptr - movsxd rdx, dword ptr arg(1) ;src_pixels_per_line - - ;Read 9-line unaligned data in and put them on stack. This gives a big - ;performance boost. - movdqu xmm0, [rsi] - lea rax, [rdx + rdx*2] - movdqu xmm1, [rsi+rdx] - movdqu xmm2, [rsi+rdx*2] - add rsi, rax - movdqu xmm3, [rsi] - movdqu xmm4, [rsi+rdx] - movdqu xmm5, [rsi+rdx*2] - add rsi, rax - movdqu xmm6, [rsi] - movdqu xmm7, [rsi+rdx] - - movdqa XMMWORD PTR [rsp], xmm0 - - movdqu xmm0, [rsi+rdx*2] - - movdqa XMMWORD PTR [rsp+16], xmm1 - movdqa XMMWORD PTR [rsp+32], xmm2 - movdqa XMMWORD PTR [rsp+48], xmm3 - movdqa XMMWORD PTR [rsp+64], xmm4 - movdqa XMMWORD PTR [rsp+80], xmm5 - movdqa XMMWORD PTR [rsp+96], xmm6 - movdqa XMMWORD PTR [rsp+112], xmm7 - movdqa XMMWORD PTR [rsp+128], xmm0 - - movsxd rax, dword ptr arg(2) ; xoffset - cmp rax, 0 ; skip first_pass filter if xoffset=0 - je .b8x8_sp_only - - shl rax, 4 - add rax, rcx ; HFilter - - mov rdi, arg(4) ; dst_ptr - movsxd rdx, dword ptr arg(5) ; dst_pitch - - movdqa xmm0, [rax] - - movsxd rax, dword ptr arg(3) ; yoffset - cmp rax, 0 ; skip second_pass filter if yoffset=0 - je .b8x8_fp_only - - shl rax, 4 - lea rax, [rax + rcx] ; VFilter - - lea rcx, [rdi+rdx*8] - - movdqa xmm1, [rax] - - ; get the first horizontal line done - movdqa xmm3, [rsp] ; 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 - movdqa xmm5, xmm3 ; 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 xx - - psrldq xmm5, 1 - lea rsp, [rsp + 16] ; next line - - punpcklbw xmm3, xmm5 ; 00 01 01 02 02 03 03 04 04 05 05 06 06 07 07 08 - pmaddubsw xmm3, xmm0 ; 00 02 04 06 08 10 12 14 - - paddw xmm3, [GLOBAL(rd)] ; xmm3 += round value - psraw xmm3, VP8_FILTER_SHIFT ; xmm3 /= 128 - - movdqa xmm7, xmm3 - packuswb xmm7, xmm7 ; 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 - -.next_row: - movdqa xmm6, [rsp] ; 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 - lea rsp, [rsp + 16] ; next line - - movdqa xmm5, xmm6 - - psrldq xmm5, 1 - - punpcklbw xmm6, xmm5 - pmaddubsw xmm6, xmm0 - - paddw xmm6, [GLOBAL(rd)] ; xmm6 += round value - psraw xmm6, VP8_FILTER_SHIFT ; xmm6 /= 128 - - packuswb xmm6, xmm6 - - punpcklbw xmm7, xmm6 - pmaddubsw xmm7, xmm1 - - paddw xmm7, [GLOBAL(rd)] ; xmm7 += round value - psraw xmm7, VP8_FILTER_SHIFT ; xmm7 /= 128 - - packuswb xmm7, xmm7 - - movq [rdi], xmm7 ; store the results in the destination - lea rdi, [rdi + rdx] - - movdqa xmm7, xmm6 - - cmp rdi, rcx - jne .next_row - - jmp .done8x8 - -.b8x8_sp_only: - movsxd rax, dword ptr arg(3) ; yoffset - shl rax, 4 - lea rax, [rax + rcx] ; VFilter - - mov rdi, arg(4) ;dst_ptr - movsxd rdx, dword ptr arg(5) ; dst_pitch - - movdqa xmm0, [rax] ; VFilter - - movq xmm1, XMMWORD PTR [rsp] - movq xmm2, XMMWORD PTR [rsp+16] - - movq xmm3, XMMWORD PTR [rsp+32] - punpcklbw xmm1, xmm2 - - movq xmm4, XMMWORD PTR [rsp+48] - punpcklbw xmm2, xmm3 - - movq xmm5, XMMWORD PTR [rsp+64] - punpcklbw xmm3, xmm4 - - movq xmm6, XMMWORD PTR [rsp+80] - punpcklbw xmm4, xmm5 - - movq xmm7, XMMWORD PTR [rsp+96] - punpcklbw xmm5, xmm6 - - ; Because the source register (xmm0) is always treated as signed by - ; pmaddubsw, the constant '128' is treated as '-128'. - pmaddubsw xmm1, xmm0 - pmaddubsw xmm2, xmm0 - - pmaddubsw xmm3, xmm0 - pmaddubsw xmm4, xmm0 - - pmaddubsw xmm5, xmm0 - punpcklbw xmm6, xmm7 - - pmaddubsw xmm6, xmm0 - paddw xmm1, [GLOBAL(rd)] - - paddw xmm2, [GLOBAL(rd)] - psraw xmm1, VP8_FILTER_SHIFT - - paddw xmm3, [GLOBAL(rd)] - psraw xmm2, VP8_FILTER_SHIFT - - paddw xmm4, [GLOBAL(rd)] - psraw xmm3, VP8_FILTER_SHIFT - - paddw xmm5, [GLOBAL(rd)] - psraw xmm4, VP8_FILTER_SHIFT - - paddw xmm6, [GLOBAL(rd)] - psraw xmm5, VP8_FILTER_SHIFT - - psraw xmm6, VP8_FILTER_SHIFT - - ; Having multiplied everything by '-128' and obtained negative - ; numbers, the unsigned saturation truncates those values to 0, - ; resulting in incorrect handling of xoffset == 0 && yoffset == 0 - packuswb xmm1, xmm1 - - packuswb xmm2, xmm2 - movq [rdi], xmm1 - - packuswb xmm3, xmm3 - movq [rdi+rdx], xmm2 - - packuswb xmm4, xmm4 - movq xmm1, XMMWORD PTR [rsp+112] - - lea rdi, [rdi + 2*rdx] - movq xmm2, XMMWORD PTR [rsp+128] - - packuswb xmm5, xmm5 - movq [rdi], xmm3 - - packuswb xmm6, xmm6 - movq [rdi+rdx], xmm4 - - lea rdi, [rdi + 2*rdx] - punpcklbw xmm7, xmm1 - - movq [rdi], xmm5 - pmaddubsw xmm7, xmm0 - - movq [rdi+rdx], xmm6 - punpcklbw xmm1, xmm2 - - pmaddubsw xmm1, xmm0 - paddw xmm7, [GLOBAL(rd)] - - psraw xmm7, VP8_FILTER_SHIFT - paddw xmm1, [GLOBAL(rd)] - - psraw xmm1, VP8_FILTER_SHIFT - packuswb xmm7, xmm7 - - packuswb xmm1, xmm1 - lea rdi, [rdi + 2*rdx] - - movq [rdi], xmm7 - - movq [rdi+rdx], xmm1 - lea rsp, [rsp + 144] - - jmp .done8x8 - -.b8x8_fp_only: - lea rcx, [rdi+rdx*8] - -.next_row_fp: - movdqa xmm1, XMMWORD PTR [rsp] - movdqa xmm3, XMMWORD PTR [rsp+16] - - movdqa xmm2, xmm1 - movdqa xmm5, XMMWORD PTR [rsp+32] - - psrldq xmm2, 1 - movdqa xmm7, XMMWORD PTR [rsp+48] - - movdqa xmm4, xmm3 - psrldq xmm4, 1 - - movdqa xmm6, xmm5 - psrldq xmm6, 1 - - punpcklbw xmm1, xmm2 - pmaddubsw xmm1, xmm0 - - punpcklbw xmm3, xmm4 - pmaddubsw xmm3, xmm0 - - punpcklbw xmm5, xmm6 - pmaddubsw xmm5, xmm0 - - movdqa xmm2, xmm7 - psrldq xmm2, 1 - - punpcklbw xmm7, xmm2 - pmaddubsw xmm7, xmm0 - - paddw xmm1, [GLOBAL(rd)] - psraw xmm1, VP8_FILTER_SHIFT - - paddw xmm3, [GLOBAL(rd)] - psraw xmm3, VP8_FILTER_SHIFT - - paddw xmm5, [GLOBAL(rd)] - psraw xmm5, VP8_FILTER_SHIFT - - paddw xmm7, [GLOBAL(rd)] - psraw xmm7, VP8_FILTER_SHIFT - - packuswb xmm1, xmm1 - packuswb xmm3, xmm3 - - packuswb xmm5, xmm5 - movq [rdi], xmm1 - - packuswb xmm7, xmm7 - movq [rdi+rdx], xmm3 - - lea rdi, [rdi + 2*rdx] - movq [rdi], xmm5 - - lea rsp, [rsp + 4*16] - movq [rdi+rdx], xmm7 - - lea rdi, [rdi + 2*rdx] - cmp rdi, rcx - - jne .next_row_fp - - lea rsp, [rsp + 16] - -.done8x8: - ;add rsp, 144 - pop rsp - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -SECTION_RODATA -align 16 -shuf1b: - db 0, 5, 1, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12 -shuf2b: - db 2, 4, 3, 5, 4, 6, 5, 7, 6, 8, 7, 9, 8, 10, 9, 11 -shuf3b: - db 1, 3, 2, 4, 3, 5, 4, 6, 5, 7, 6, 8, 7, 9, 8, 10 - -align 16 -shuf2bfrom1: - db 4, 8, 6, 1, 8, 3, 1, 5, 3, 7, 5, 9, 7,11, 9,13 -align 16 -shuf3bfrom1: - db 2, 6, 4, 8, 6, 1, 8, 3, 1, 5, 3, 7, 5, 9, 7,11 - -align 16 -rd: - times 8 dw 0x40 - -align 16 -k0_k5: - times 8 db 0, 0 ;placeholder - times 8 db 0, 0 - times 8 db 2, 1 - times 8 db 0, 0 - times 8 db 3, 3 - times 8 db 0, 0 - times 8 db 1, 2 - times 8 db 0, 0 -k1_k3: - times 8 db 0, 0 ;placeholder - times 8 db -6, 12 - times 8 db -11, 36 - times 8 db -9, 50 - times 8 db -16, 77 - times 8 db -6, 93 - times 8 db -8, 108 - times 8 db -1, 123 -k2_k4: - times 8 db 128, 0 ;placeholder - times 8 db 123, -1 - times 8 db 108, -8 - times 8 db 93, -6 - times 8 db 77, -16 - times 8 db 50, -9 - times 8 db 36, -11 - times 8 db 12, -6 -align 16 -vp8_bilinear_filters_ssse3: - times 8 db 128, 0 - times 8 db 112, 16 - times 8 db 96, 32 - times 8 db 80, 48 - times 8 db 64, 64 - times 8 db 48, 80 - times 8 db 32, 96 - times 8 db 16, 112 - diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/vp8_asm_stubs.c b/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/vp8_asm_stubs.c deleted file mode 100644 index 7fb83c2d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/common/x86/vp8_asm_stubs.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "vp8_rtcd.h" -#include "vpx_ports/mem.h" - -extern const short vp8_six_tap_x86[8][6 * 8]; - -extern void vp8_filter_block1d_h6_mmx(unsigned char *src_ptr, - unsigned short *output_ptr, - unsigned int src_pixels_per_line, - unsigned int pixel_step, - unsigned int output_height, - unsigned int output_width, - const short *vp8_filter); -extern void vp8_filter_block1dc_v6_mmx( - unsigned short *src_ptr, unsigned char *output_ptr, int output_pitch, - unsigned int pixels_per_line, unsigned int pixel_step, - unsigned int output_height, unsigned int output_width, - const short *vp8_filter); -extern void vp8_filter_block1d8_h6_sse2(unsigned char *src_ptr, - unsigned short *output_ptr, - unsigned int src_pixels_per_line, - unsigned int pixel_step, - unsigned int output_height, - unsigned int output_width, - const short *vp8_filter); -extern void vp8_filter_block1d16_h6_sse2(unsigned char *src_ptr, - unsigned short *output_ptr, - unsigned int src_pixels_per_line, - unsigned int pixel_step, - unsigned int output_height, - unsigned int output_width, - const short *vp8_filter); -extern void vp8_filter_block1d8_v6_sse2( - unsigned short *src_ptr, unsigned char *output_ptr, int dst_ptich, - unsigned int pixels_per_line, unsigned int pixel_step, - unsigned int output_height, unsigned int output_width, - const short *vp8_filter); -extern void vp8_filter_block1d16_v6_sse2( - unsigned short *src_ptr, unsigned char *output_ptr, int dst_ptich, - unsigned int pixels_per_line, unsigned int pixel_step, - unsigned int output_height, unsigned int output_width, - const short *vp8_filter); -extern void vp8_unpack_block1d16_h6_sse2(unsigned char *src_ptr, - unsigned short *output_ptr, - unsigned int src_pixels_per_line, - unsigned int output_height, - unsigned int output_width); -extern void vp8_filter_block1d8_h6_only_sse2(unsigned char *src_ptr, - unsigned int src_pixels_per_line, - unsigned char *output_ptr, - int dst_ptich, - unsigned int output_height, - const short *vp8_filter); -extern void vp8_filter_block1d16_h6_only_sse2(unsigned char *src_ptr, - unsigned int src_pixels_per_line, - unsigned char *output_ptr, - int dst_ptich, - unsigned int output_height, - const short *vp8_filter); -extern void vp8_filter_block1d8_v6_only_sse2(unsigned char *src_ptr, - unsigned int src_pixels_per_line, - unsigned char *output_ptr, - int dst_ptich, - unsigned int output_height, - const short *vp8_filter); - -#if HAVE_MMX -void vp8_sixtap_predict4x4_mmx(unsigned char *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - DECLARE_ALIGNED(16, unsigned short, - FData2[16 * 16]); /* Temp data bufffer used in filtering */ - const short *HFilter, *VFilter; - HFilter = vp8_six_tap_x86[xoffset]; - vp8_filter_block1d_h6_mmx(src_ptr - (2 * src_pixels_per_line), FData2, - src_pixels_per_line, 1, 9, 8, HFilter); - VFilter = vp8_six_tap_x86[yoffset]; - vp8_filter_block1dc_v6_mmx(FData2 + 8, dst_ptr, dst_pitch, 8, 4, 4, 4, - VFilter); -} -#endif - -#if HAVE_SSE2 -void vp8_sixtap_predict16x16_sse2(unsigned char *src_ptr, - int src_pixels_per_line, int xoffset, - int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - DECLARE_ALIGNED(16, unsigned short, - FData2[24 * 24]); /* Temp data bufffer used in filtering */ - - const short *HFilter, *VFilter; - - if (xoffset) { - if (yoffset) { - HFilter = vp8_six_tap_x86[xoffset]; - vp8_filter_block1d16_h6_sse2(src_ptr - (2 * src_pixels_per_line), FData2, - src_pixels_per_line, 1, 21, 32, HFilter); - VFilter = vp8_six_tap_x86[yoffset]; - vp8_filter_block1d16_v6_sse2(FData2 + 32, dst_ptr, dst_pitch, 32, 16, 16, - dst_pitch, VFilter); - } else { - /* First-pass only */ - HFilter = vp8_six_tap_x86[xoffset]; - vp8_filter_block1d16_h6_only_sse2(src_ptr, src_pixels_per_line, dst_ptr, - dst_pitch, 16, HFilter); - } - } else { - /* Second-pass only */ - VFilter = vp8_six_tap_x86[yoffset]; - vp8_unpack_block1d16_h6_sse2(src_ptr - (2 * src_pixels_per_line), FData2, - src_pixels_per_line, 21, 32); - vp8_filter_block1d16_v6_sse2(FData2 + 32, dst_ptr, dst_pitch, 32, 16, 16, - dst_pitch, VFilter); - } -} - -void vp8_sixtap_predict8x8_sse2(unsigned char *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, - unsigned char *dst_ptr, int dst_pitch) { - DECLARE_ALIGNED(16, unsigned short, - FData2[256]); /* Temp data bufffer used in filtering */ - const short *HFilter, *VFilter; - - if (xoffset) { - if (yoffset) { - HFilter = vp8_six_tap_x86[xoffset]; - vp8_filter_block1d8_h6_sse2(src_ptr - (2 * src_pixels_per_line), FData2, - src_pixels_per_line, 1, 13, 16, HFilter); - VFilter = vp8_six_tap_x86[yoffset]; - vp8_filter_block1d8_v6_sse2(FData2 + 16, dst_ptr, dst_pitch, 16, 8, 8, - dst_pitch, VFilter); - } else { - /* First-pass only */ - HFilter = vp8_six_tap_x86[xoffset]; - vp8_filter_block1d8_h6_only_sse2(src_ptr, src_pixels_per_line, dst_ptr, - dst_pitch, 8, HFilter); - } - } else { - /* Second-pass only */ - VFilter = vp8_six_tap_x86[yoffset]; - vp8_filter_block1d8_v6_only_sse2(src_ptr - (2 * src_pixels_per_line), - src_pixels_per_line, dst_ptr, dst_pitch, 8, - VFilter); - } -} - -void vp8_sixtap_predict8x4_sse2(unsigned char *src_ptr, int src_pixels_per_line, - int xoffset, int yoffset, - unsigned char *dst_ptr, int dst_pitch) { - DECLARE_ALIGNED(16, unsigned short, - FData2[256]); /* Temp data bufffer used in filtering */ - const short *HFilter, *VFilter; - - if (xoffset) { - if (yoffset) { - HFilter = vp8_six_tap_x86[xoffset]; - vp8_filter_block1d8_h6_sse2(src_ptr - (2 * src_pixels_per_line), FData2, - src_pixels_per_line, 1, 9, 16, HFilter); - VFilter = vp8_six_tap_x86[yoffset]; - vp8_filter_block1d8_v6_sse2(FData2 + 16, dst_ptr, dst_pitch, 16, 8, 4, - dst_pitch, VFilter); - } else { - /* First-pass only */ - HFilter = vp8_six_tap_x86[xoffset]; - vp8_filter_block1d8_h6_only_sse2(src_ptr, src_pixels_per_line, dst_ptr, - dst_pitch, 4, HFilter); - } - } else { - /* Second-pass only */ - VFilter = vp8_six_tap_x86[yoffset]; - vp8_filter_block1d8_v6_only_sse2(src_ptr - (2 * src_pixels_per_line), - src_pixels_per_line, dst_ptr, dst_pitch, 4, - VFilter); - } -} - -#endif - -#if HAVE_SSSE3 - -extern void vp8_filter_block1d8_h6_ssse3(unsigned char *src_ptr, - unsigned int src_pixels_per_line, - unsigned char *output_ptr, - unsigned int output_pitch, - unsigned int output_height, - unsigned int vp8_filter_index); - -extern void vp8_filter_block1d16_h6_ssse3(unsigned char *src_ptr, - unsigned int src_pixels_per_line, - unsigned char *output_ptr, - unsigned int output_pitch, - unsigned int output_height, - unsigned int vp8_filter_index); - -extern void vp8_filter_block1d16_v6_ssse3(unsigned char *src_ptr, - unsigned int src_pitch, - unsigned char *output_ptr, - unsigned int out_pitch, - unsigned int output_height, - unsigned int vp8_filter_index); - -extern void vp8_filter_block1d8_v6_ssse3(unsigned char *src_ptr, - unsigned int src_pitch, - unsigned char *output_ptr, - unsigned int out_pitch, - unsigned int output_height, - unsigned int vp8_filter_index); - -extern void vp8_filter_block1d4_h6_ssse3(unsigned char *src_ptr, - unsigned int src_pixels_per_line, - unsigned char *output_ptr, - unsigned int output_pitch, - unsigned int output_height, - unsigned int vp8_filter_index); - -extern void vp8_filter_block1d4_v6_ssse3(unsigned char *src_ptr, - unsigned int src_pitch, - unsigned char *output_ptr, - unsigned int out_pitch, - unsigned int output_height, - unsigned int vp8_filter_index); - -void vp8_sixtap_predict16x16_ssse3(unsigned char *src_ptr, - int src_pixels_per_line, int xoffset, - int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - DECLARE_ALIGNED(16, unsigned char, FData2[24 * 24]); - - if (xoffset) { - if (yoffset) { - vp8_filter_block1d16_h6_ssse3(src_ptr - (2 * src_pixels_per_line), - src_pixels_per_line, FData2, 16, 21, - xoffset); - vp8_filter_block1d16_v6_ssse3(FData2, 16, dst_ptr, dst_pitch, 16, - yoffset); - } else { - /* First-pass only */ - vp8_filter_block1d16_h6_ssse3(src_ptr, src_pixels_per_line, dst_ptr, - dst_pitch, 16, xoffset); - } - } else { - if (yoffset) { - /* Second-pass only */ - vp8_filter_block1d16_v6_ssse3(src_ptr - (2 * src_pixels_per_line), - src_pixels_per_line, dst_ptr, dst_pitch, 16, - yoffset); - } else { - /* ssse3 second-pass only function couldn't handle (xoffset==0 && - * yoffset==0) case correctly. Add copy function here to guarantee - * six-tap function handles all possible offsets. */ - vp8_copy_mem16x16(src_ptr, src_pixels_per_line, dst_ptr, dst_pitch); - } - } -} - -void vp8_sixtap_predict8x8_ssse3(unsigned char *src_ptr, - int src_pixels_per_line, int xoffset, - int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - DECLARE_ALIGNED(16, unsigned char, FData2[256]); - - if (xoffset) { - if (yoffset) { - vp8_filter_block1d8_h6_ssse3(src_ptr - (2 * src_pixels_per_line), - src_pixels_per_line, FData2, 8, 13, xoffset); - vp8_filter_block1d8_v6_ssse3(FData2, 8, dst_ptr, dst_pitch, 8, yoffset); - } else { - vp8_filter_block1d8_h6_ssse3(src_ptr, src_pixels_per_line, dst_ptr, - dst_pitch, 8, xoffset); - } - } else { - if (yoffset) { - /* Second-pass only */ - vp8_filter_block1d8_v6_ssse3(src_ptr - (2 * src_pixels_per_line), - src_pixels_per_line, dst_ptr, dst_pitch, 8, - yoffset); - } else { - /* ssse3 second-pass only function couldn't handle (xoffset==0 && - * yoffset==0) case correctly. Add copy function here to guarantee - * six-tap function handles all possible offsets. */ - vp8_copy_mem8x8(src_ptr, src_pixels_per_line, dst_ptr, dst_pitch); - } - } -} - -void vp8_sixtap_predict8x4_ssse3(unsigned char *src_ptr, - int src_pixels_per_line, int xoffset, - int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - DECLARE_ALIGNED(16, unsigned char, FData2[256]); - - if (xoffset) { - if (yoffset) { - vp8_filter_block1d8_h6_ssse3(src_ptr - (2 * src_pixels_per_line), - src_pixels_per_line, FData2, 8, 9, xoffset); - vp8_filter_block1d8_v6_ssse3(FData2, 8, dst_ptr, dst_pitch, 4, yoffset); - } else { - /* First-pass only */ - vp8_filter_block1d8_h6_ssse3(src_ptr, src_pixels_per_line, dst_ptr, - dst_pitch, 4, xoffset); - } - } else { - if (yoffset) { - /* Second-pass only */ - vp8_filter_block1d8_v6_ssse3(src_ptr - (2 * src_pixels_per_line), - src_pixels_per_line, dst_ptr, dst_pitch, 4, - yoffset); - } else { - /* ssse3 second-pass only function couldn't handle (xoffset==0 && - * yoffset==0) case correctly. Add copy function here to guarantee - * six-tap function handles all possible offsets. */ - vp8_copy_mem8x4(src_ptr, src_pixels_per_line, dst_ptr, dst_pitch); - } - } -} - -void vp8_sixtap_predict4x4_ssse3(unsigned char *src_ptr, - int src_pixels_per_line, int xoffset, - int yoffset, unsigned char *dst_ptr, - int dst_pitch) { - DECLARE_ALIGNED(16, unsigned char, FData2[4 * 9]); - - if (xoffset) { - if (yoffset) { - vp8_filter_block1d4_h6_ssse3(src_ptr - (2 * src_pixels_per_line), - src_pixels_per_line, FData2, 4, 9, xoffset); - vp8_filter_block1d4_v6_ssse3(FData2, 4, dst_ptr, dst_pitch, 4, yoffset); - } else { - vp8_filter_block1d4_h6_ssse3(src_ptr, src_pixels_per_line, dst_ptr, - dst_pitch, 4, xoffset); - } - } else { - if (yoffset) { - vp8_filter_block1d4_v6_ssse3(src_ptr - (2 * src_pixels_per_line), - src_pixels_per_line, dst_ptr, dst_pitch, 4, - yoffset); - } else { - /* ssse3 second-pass only function couldn't handle (xoffset==0 && - * yoffset==0) case correctly. Add copy function here to guarantee - * six-tap function handles all possible offsets. */ - int r; - - for (r = 0; r < 4; ++r) { - dst_ptr[0] = src_ptr[0]; - dst_ptr[1] = src_ptr[1]; - dst_ptr[2] = src_ptr[2]; - dst_ptr[3] = src_ptr[3]; - dst_ptr += dst_pitch; - src_ptr += src_pixels_per_line; - } - } - } -} - -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/dboolhuff.c b/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/dboolhuff.c deleted file mode 100644 index 11099c45..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/dboolhuff.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "dboolhuff.h" -#include "vp8/common/common.h" -#include "vpx_dsp/vpx_dsp_common.h" - -int vp8dx_start_decode(BOOL_DECODER *br, const unsigned char *source, - unsigned int source_sz, vpx_decrypt_cb decrypt_cb, - void *decrypt_state) { - if (source_sz && !source) return 1; - - // To simplify calling code this fuction can be called with |source| == null - // and |source_sz| == 0. This and vp8dx_bool_decoder_fill() are essentially - // no-ops in this case. - // Work around a ubsan warning with a ternary to avoid adding 0 to null. - br->user_buffer_end = source ? source + source_sz : source; - br->user_buffer = source; - br->value = 0; - br->count = -8; - br->range = 255; - br->decrypt_cb = decrypt_cb; - br->decrypt_state = decrypt_state; - - /* Populate the buffer */ - vp8dx_bool_decoder_fill(br); - - return 0; -} - -void vp8dx_bool_decoder_fill(BOOL_DECODER *br) { - const unsigned char *bufptr = br->user_buffer; - VP8_BD_VALUE value = br->value; - int count = br->count; - int shift = VP8_BD_VALUE_SIZE - CHAR_BIT - (count + CHAR_BIT); - size_t bytes_left = br->user_buffer_end - bufptr; - size_t bits_left = bytes_left * CHAR_BIT; - int x = shift + CHAR_BIT - (int)bits_left; - int loop_end = 0; - unsigned char decrypted[sizeof(VP8_BD_VALUE) + 1]; - - if (br->decrypt_cb) { - size_t n = VPXMIN(sizeof(decrypted), bytes_left); - br->decrypt_cb(br->decrypt_state, bufptr, decrypted, (int)n); - bufptr = decrypted; - } - - if (x >= 0) { - count += VP8_LOTS_OF_BITS; - loop_end = x; - } - - if (x < 0 || bits_left) { - while (shift >= loop_end) { - count += CHAR_BIT; - value |= (VP8_BD_VALUE)*bufptr << shift; - ++bufptr; - ++br->user_buffer; - shift -= CHAR_BIT; - } - } - - br->value = value; - br->count = count; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/dboolhuff.h b/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/dboolhuff.h deleted file mode 100644 index 673b2fbd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/dboolhuff.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_DECODER_DBOOLHUFF_H_ -#define VPX_VP8_DECODER_DBOOLHUFF_H_ - -#include -#include - -#include "./vpx_config.h" -#include "vpx_ports/compiler_attributes.h" -#include "vpx_ports/mem.h" -#include "vpx/vp8dx.h" -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef size_t VP8_BD_VALUE; - -#define VP8_BD_VALUE_SIZE ((int)sizeof(VP8_BD_VALUE) * CHAR_BIT) - -/*This is meant to be a large, positive constant that can still be efficiently - loaded as an immediate (on platforms like ARM, for example). - Even relatively modest values like 100 would work fine.*/ -#define VP8_LOTS_OF_BITS (0x40000000) - -typedef struct { - const unsigned char *user_buffer_end; - const unsigned char *user_buffer; - VP8_BD_VALUE value; - int count; - unsigned int range; - vpx_decrypt_cb decrypt_cb; - void *decrypt_state; -} BOOL_DECODER; - -DECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]); - -int vp8dx_start_decode(BOOL_DECODER *br, const unsigned char *source, - unsigned int source_sz, vpx_decrypt_cb decrypt_cb, - void *decrypt_state); - -void vp8dx_bool_decoder_fill(BOOL_DECODER *br); - -static VPX_NO_UNSIGNED_SHIFT_CHECK int vp8dx_decode_bool(BOOL_DECODER *br, - int probability) { - unsigned int bit = 0; - VP8_BD_VALUE value; - unsigned int split; - VP8_BD_VALUE bigsplit; - int count; - unsigned int range; - - split = 1 + (((br->range - 1) * probability) >> 8); - - if (br->count < 0) vp8dx_bool_decoder_fill(br); - - value = br->value; - count = br->count; - - bigsplit = (VP8_BD_VALUE)split << (VP8_BD_VALUE_SIZE - 8); - - range = split; - - if (value >= bigsplit) { - range = br->range - split; - value = value - bigsplit; - bit = 1; - } - - { - const unsigned char shift = vp8_norm[(unsigned char)range]; - range <<= shift; - value <<= shift; - count -= shift; - } - br->value = value; - br->count = count; - br->range = range; - - return bit; -} - -static INLINE int vp8_decode_value(BOOL_DECODER *br, int bits) { - int z = 0; - int bit; - - for (bit = bits - 1; bit >= 0; bit--) { - z |= (vp8dx_decode_bool(br, 0x80) << bit); - } - - return z; -} - -static INLINE int vp8dx_bool_error(BOOL_DECODER *br) { - /* Check if we have reached the end of the buffer. - * - * Variable 'count' stores the number of bits in the 'value' buffer, minus - * 8. The top byte is part of the algorithm, and the remainder is buffered - * to be shifted into it. So if count == 8, the top 16 bits of 'value' are - * occupied, 8 for the algorithm and 8 in the buffer. - * - * When reading a byte from the user's buffer, count is filled with 8 and - * one byte is filled into the value buffer. When we reach the end of the - * data, count is additionally filled with VP8_LOTS_OF_BITS. So when - * count == VP8_LOTS_OF_BITS - 1, the user's data has been exhausted. - */ - if ((br->count > VP8_BD_VALUE_SIZE) && (br->count < VP8_LOTS_OF_BITS)) { - /* We have tried to decode bits after the end of - * stream was encountered. - */ - return 1; - } - - /* No error. */ - return 0; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_DECODER_DBOOLHUFF_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/decodeframe.c b/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/decodeframe.c deleted file mode 100644 index af9a98c1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/decodeframe.c +++ /dev/null @@ -1,1263 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "vp8_rtcd.h" -#include "./vpx_scale_rtcd.h" -#include "onyxd_int.h" -#include "vp8/common/header.h" -#include "vp8/common/reconintra4x4.h" -#include "vp8/common/reconinter.h" -#include "detokenize.h" -#include "vp8/common/common.h" -#include "vp8/common/invtrans.h" -#include "vp8/common/alloccommon.h" -#include "vp8/common/entropymode.h" -#include "vp8/common/quant_common.h" -#include "vpx_scale/vpx_scale.h" -#include "vp8/common/reconintra.h" -#include "vp8/common/setupintrarecon.h" - -#include "decodemv.h" -#include "vp8/common/extend.h" -#if CONFIG_ERROR_CONCEALMENT -#include "error_concealment.h" -#endif -#include "vpx_mem/vpx_mem.h" -#include "vp8/common/threading.h" -#include "decoderthreading.h" -#include "dboolhuff.h" -#include "vpx_dsp/vpx_dsp_common.h" - -#include -#include - -void vp8cx_init_de_quantizer(VP8D_COMP *pbi) { - int Q; - VP8_COMMON *const pc = &pbi->common; - - for (Q = 0; Q < QINDEX_RANGE; ++Q) { - pc->Y1dequant[Q][0] = (short)vp8_dc_quant(Q, pc->y1dc_delta_q); - pc->Y2dequant[Q][0] = (short)vp8_dc2quant(Q, pc->y2dc_delta_q); - pc->UVdequant[Q][0] = (short)vp8_dc_uv_quant(Q, pc->uvdc_delta_q); - - pc->Y1dequant[Q][1] = (short)vp8_ac_yquant(Q); - pc->Y2dequant[Q][1] = (short)vp8_ac2quant(Q, pc->y2ac_delta_q); - pc->UVdequant[Q][1] = (short)vp8_ac_uv_quant(Q, pc->uvac_delta_q); - } -} - -void vp8_mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd) { - int i; - int QIndex; - MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi; - VP8_COMMON *const pc = &pbi->common; - - /* Decide whether to use the default or alternate baseline Q value. */ - if (xd->segmentation_enabled) { - /* Abs Value */ - if (xd->mb_segment_abs_delta == SEGMENT_ABSDATA) { - QIndex = xd->segment_feature_data[MB_LVL_ALT_Q][mbmi->segment_id]; - - /* Delta Value */ - } else { - QIndex = pc->base_qindex + - xd->segment_feature_data[MB_LVL_ALT_Q][mbmi->segment_id]; - } - - QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) - : 0; /* Clamp to valid range */ - } else { - QIndex = pc->base_qindex; - } - - /* Set up the macroblock dequant constants */ - xd->dequant_y1_dc[0] = 1; - xd->dequant_y1[0] = pc->Y1dequant[QIndex][0]; - xd->dequant_y2[0] = pc->Y2dequant[QIndex][0]; - xd->dequant_uv[0] = pc->UVdequant[QIndex][0]; - - for (i = 1; i < 16; ++i) { - xd->dequant_y1_dc[i] = xd->dequant_y1[i] = pc->Y1dequant[QIndex][1]; - xd->dequant_y2[i] = pc->Y2dequant[QIndex][1]; - xd->dequant_uv[i] = pc->UVdequant[QIndex][1]; - } -} - -static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, - unsigned int mb_idx) { - MB_PREDICTION_MODE mode; - int i; -#if CONFIG_ERROR_CONCEALMENT - int corruption_detected = 0; -#else - (void)mb_idx; -#endif - - if (xd->mode_info_context->mbmi.mb_skip_coeff) { - vp8_reset_mb_tokens_context(xd); - } else if (!vp8dx_bool_error(xd->current_bc)) { - int eobtotal; - eobtotal = vp8_decode_mb_tokens(pbi, xd); - - /* Special case: Force the loopfilter to skip when eobtotal is zero */ - xd->mode_info_context->mbmi.mb_skip_coeff = (eobtotal == 0); - } - - mode = xd->mode_info_context->mbmi.mode; - - if (xd->segmentation_enabled) vp8_mb_init_dequantizer(pbi, xd); - -#if CONFIG_ERROR_CONCEALMENT - - if (pbi->ec_active) { - int throw_residual; - /* When we have independent partitions we can apply residual even - * though other partitions within the frame are corrupt. - */ - throw_residual = - (!pbi->independent_partitions && pbi->frame_corrupt_residual); - throw_residual = (throw_residual || vp8dx_bool_error(xd->current_bc)); - - if ((mb_idx >= pbi->mvs_corrupt_from_mb || throw_residual)) { - /* MB with corrupt residuals or corrupt mode/motion vectors. - * Better to use the predictor as reconstruction. - */ - pbi->frame_corrupt_residual = 1; - memset(xd->qcoeff, 0, sizeof(xd->qcoeff)); - - corruption_detected = 1; - - /* force idct to be skipped for B_PRED and use the - * prediction only for reconstruction - * */ - memset(xd->eobs, 0, 25); - } - } -#endif - - /* do prediction */ - if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) { - vp8_build_intra_predictors_mbuv_s( - xd, xd->recon_above[1], xd->recon_above[2], xd->recon_left[1], - xd->recon_left[2], xd->recon_left_stride[1], xd->dst.u_buffer, - xd->dst.v_buffer, xd->dst.uv_stride); - - if (mode != B_PRED) { - vp8_build_intra_predictors_mby_s( - xd, xd->recon_above[0], xd->recon_left[0], xd->recon_left_stride[0], - xd->dst.y_buffer, xd->dst.y_stride); - } else { - short *DQC = xd->dequant_y1; - int dst_stride = xd->dst.y_stride; - - /* clear out residual eob info */ - if (xd->mode_info_context->mbmi.mb_skip_coeff) memset(xd->eobs, 0, 25); - - intra_prediction_down_copy(xd, xd->recon_above[0] + 16); - - for (i = 0; i < 16; ++i) { - BLOCKD *b = &xd->block[i]; - unsigned char *dst = xd->dst.y_buffer + b->offset; - B_PREDICTION_MODE b_mode = xd->mode_info_context->bmi[i].as_mode; - unsigned char *Above = dst - dst_stride; - unsigned char *yleft = dst - 1; - int left_stride = dst_stride; - unsigned char top_left = Above[-1]; - - vp8_intra4x4_predict(Above, yleft, left_stride, b_mode, dst, dst_stride, - top_left); - - if (xd->eobs[i]) { - if (xd->eobs[i] > 1) { - vp8_dequant_idct_add(b->qcoeff, DQC, dst, dst_stride); - } else { - vp8_dc_only_idct_add(b->qcoeff[0] * DQC[0], dst, dst_stride, dst, - dst_stride); - memset(b->qcoeff, 0, 2 * sizeof(b->qcoeff[0])); - } - } - } - } - } else { - vp8_build_inter_predictors_mb(xd); - } - -#if CONFIG_ERROR_CONCEALMENT - if (corruption_detected) { - return; - } -#endif - - if (!xd->mode_info_context->mbmi.mb_skip_coeff) { - /* dequantization and idct */ - if (mode != B_PRED) { - short *DQC = xd->dequant_y1; - - if (mode != SPLITMV) { - BLOCKD *b = &xd->block[24]; - - /* do 2nd order transform on the dc block */ - if (xd->eobs[24] > 1) { - vp8_dequantize_b(b, xd->dequant_y2); - - vp8_short_inv_walsh4x4(&b->dqcoeff[0], xd->qcoeff); - memset(b->qcoeff, 0, 16 * sizeof(b->qcoeff[0])); - } else { - b->dqcoeff[0] = (short)(b->qcoeff[0] * xd->dequant_y2[0]); - vp8_short_inv_walsh4x4_1(&b->dqcoeff[0], xd->qcoeff); - memset(b->qcoeff, 0, 2 * sizeof(b->qcoeff[0])); - } - - /* override the dc dequant constant in order to preserve the - * dc components - */ - DQC = xd->dequant_y1_dc; - } - - vp8_dequant_idct_add_y_block(xd->qcoeff, DQC, xd->dst.y_buffer, - xd->dst.y_stride, xd->eobs); - } - - vp8_dequant_idct_add_uv_block(xd->qcoeff + 16 * 16, xd->dequant_uv, - xd->dst.u_buffer, xd->dst.v_buffer, - xd->dst.uv_stride, xd->eobs + 16); - } -} - -static int get_delta_q(vp8_reader *bc, int prev, int *q_update) { - int ret_val = 0; - - if (vp8_read_bit(bc)) { - ret_val = vp8_read_literal(bc, 4); - - if (vp8_read_bit(bc)) ret_val = -ret_val; - } - - /* Trigger a quantizer update if the delta-q value has changed */ - if (ret_val != prev) *q_update = 1; - - return ret_val; -} - -#ifdef PACKET_TESTING -#include -FILE *vpxlog = 0; -#endif - -static void yv12_extend_frame_top_c(YV12_BUFFER_CONFIG *ybf) { - int i; - unsigned char *src_ptr1; - unsigned char *dest_ptr1; - - unsigned int Border; - int plane_stride; - - /***********/ - /* Y Plane */ - /***********/ - Border = ybf->border; - plane_stride = ybf->y_stride; - src_ptr1 = ybf->y_buffer - Border; - dest_ptr1 = src_ptr1 - (Border * plane_stride); - - for (i = 0; i < (int)Border; ++i) { - memcpy(dest_ptr1, src_ptr1, plane_stride); - dest_ptr1 += plane_stride; - } - - /***********/ - /* U Plane */ - /***********/ - plane_stride = ybf->uv_stride; - Border /= 2; - src_ptr1 = ybf->u_buffer - Border; - dest_ptr1 = src_ptr1 - (Border * plane_stride); - - for (i = 0; i < (int)(Border); ++i) { - memcpy(dest_ptr1, src_ptr1, plane_stride); - dest_ptr1 += plane_stride; - } - - /***********/ - /* V Plane */ - /***********/ - - src_ptr1 = ybf->v_buffer - Border; - dest_ptr1 = src_ptr1 - (Border * plane_stride); - - for (i = 0; i < (int)(Border); ++i) { - memcpy(dest_ptr1, src_ptr1, plane_stride); - dest_ptr1 += plane_stride; - } -} - -static void yv12_extend_frame_bottom_c(YV12_BUFFER_CONFIG *ybf) { - int i; - unsigned char *src_ptr1, *src_ptr2; - unsigned char *dest_ptr2; - - unsigned int Border; - int plane_stride; - int plane_height; - - /***********/ - /* Y Plane */ - /***********/ - Border = ybf->border; - plane_stride = ybf->y_stride; - plane_height = ybf->y_height; - - src_ptr1 = ybf->y_buffer - Border; - src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride; - dest_ptr2 = src_ptr2 + plane_stride; - - for (i = 0; i < (int)Border; ++i) { - memcpy(dest_ptr2, src_ptr2, plane_stride); - dest_ptr2 += plane_stride; - } - - /***********/ - /* U Plane */ - /***********/ - plane_stride = ybf->uv_stride; - plane_height = ybf->uv_height; - Border /= 2; - - src_ptr1 = ybf->u_buffer - Border; - src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride; - dest_ptr2 = src_ptr2 + plane_stride; - - for (i = 0; i < (int)(Border); ++i) { - memcpy(dest_ptr2, src_ptr2, plane_stride); - dest_ptr2 += plane_stride; - } - - /***********/ - /* V Plane */ - /***********/ - - src_ptr1 = ybf->v_buffer - Border; - src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride; - dest_ptr2 = src_ptr2 + plane_stride; - - for (i = 0; i < (int)(Border); ++i) { - memcpy(dest_ptr2, src_ptr2, plane_stride); - dest_ptr2 += plane_stride; - } -} - -static void yv12_extend_frame_left_right_c(YV12_BUFFER_CONFIG *ybf, - unsigned char *y_src, - unsigned char *u_src, - unsigned char *v_src) { - int i; - unsigned char *src_ptr1, *src_ptr2; - unsigned char *dest_ptr1, *dest_ptr2; - - unsigned int Border; - int plane_stride; - int plane_height; - int plane_width; - - /***********/ - /* Y Plane */ - /***********/ - Border = ybf->border; - plane_stride = ybf->y_stride; - plane_height = 16; - plane_width = ybf->y_width; - - /* copy the left and right most columns out */ - src_ptr1 = y_src; - src_ptr2 = src_ptr1 + plane_width - 1; - dest_ptr1 = src_ptr1 - Border; - dest_ptr2 = src_ptr2 + 1; - - for (i = 0; i < plane_height; ++i) { - memset(dest_ptr1, src_ptr1[0], Border); - memset(dest_ptr2, src_ptr2[0], Border); - src_ptr1 += plane_stride; - src_ptr2 += plane_stride; - dest_ptr1 += plane_stride; - dest_ptr2 += plane_stride; - } - - /***********/ - /* U Plane */ - /***********/ - plane_stride = ybf->uv_stride; - plane_height = 8; - plane_width = ybf->uv_width; - Border /= 2; - - /* copy the left and right most columns out */ - src_ptr1 = u_src; - src_ptr2 = src_ptr1 + plane_width - 1; - dest_ptr1 = src_ptr1 - Border; - dest_ptr2 = src_ptr2 + 1; - - for (i = 0; i < plane_height; ++i) { - memset(dest_ptr1, src_ptr1[0], Border); - memset(dest_ptr2, src_ptr2[0], Border); - src_ptr1 += plane_stride; - src_ptr2 += plane_stride; - dest_ptr1 += plane_stride; - dest_ptr2 += plane_stride; - } - - /***********/ - /* V Plane */ - /***********/ - - /* copy the left and right most columns out */ - src_ptr1 = v_src; - src_ptr2 = src_ptr1 + plane_width - 1; - dest_ptr1 = src_ptr1 - Border; - dest_ptr2 = src_ptr2 + 1; - - for (i = 0; i < plane_height; ++i) { - memset(dest_ptr1, src_ptr1[0], Border); - memset(dest_ptr2, src_ptr2[0], Border); - src_ptr1 += plane_stride; - src_ptr2 += plane_stride; - dest_ptr1 += plane_stride; - dest_ptr2 += plane_stride; - } -} - -static void decode_mb_rows(VP8D_COMP *pbi) { - VP8_COMMON *const pc = &pbi->common; - MACROBLOCKD *const xd = &pbi->mb; - - MODE_INFO *lf_mic = xd->mode_info_context; - - int ibc = 0; - int num_part = 1 << pc->multi_token_partition; - - int recon_yoffset, recon_uvoffset; - int mb_row, mb_col; - int mb_idx = 0; - - YV12_BUFFER_CONFIG *yv12_fb_new = pbi->dec_fb_ref[INTRA_FRAME]; - - int recon_y_stride = yv12_fb_new->y_stride; - int recon_uv_stride = yv12_fb_new->uv_stride; - - unsigned char *ref_buffer[MAX_REF_FRAMES][3]; - unsigned char *dst_buffer[3]; - unsigned char *lf_dst[3]; - unsigned char *eb_dst[3]; - int i; - int ref_fb_corrupted[MAX_REF_FRAMES]; - - ref_fb_corrupted[INTRA_FRAME] = 0; - - for (i = 1; i < MAX_REF_FRAMES; ++i) { - YV12_BUFFER_CONFIG *this_fb = pbi->dec_fb_ref[i]; - - ref_buffer[i][0] = this_fb->y_buffer; - ref_buffer[i][1] = this_fb->u_buffer; - ref_buffer[i][2] = this_fb->v_buffer; - - ref_fb_corrupted[i] = this_fb->corrupted; - } - - /* Set up the buffer pointers */ - eb_dst[0] = lf_dst[0] = dst_buffer[0] = yv12_fb_new->y_buffer; - eb_dst[1] = lf_dst[1] = dst_buffer[1] = yv12_fb_new->u_buffer; - eb_dst[2] = lf_dst[2] = dst_buffer[2] = yv12_fb_new->v_buffer; - - xd->up_available = 0; - - /* Initialize the loop filter for this frame. */ - if (pc->filter_level) vp8_loop_filter_frame_init(pc, xd, pc->filter_level); - - vp8_setup_intra_recon_top_line(yv12_fb_new); - - /* Decode the individual macro block */ - for (mb_row = 0; mb_row < pc->mb_rows; ++mb_row) { - if (num_part > 1) { - xd->current_bc = &pbi->mbc[ibc]; - ibc++; - - if (ibc == num_part) ibc = 0; - } - - recon_yoffset = mb_row * recon_y_stride * 16; - recon_uvoffset = mb_row * recon_uv_stride * 8; - - /* reset contexts */ - xd->above_context = pc->above_context; - memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)); - - xd->left_available = 0; - - xd->mb_to_top_edge = -((mb_row * 16) << 3); - xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3; - - xd->recon_above[0] = dst_buffer[0] + recon_yoffset; - xd->recon_above[1] = dst_buffer[1] + recon_uvoffset; - xd->recon_above[2] = dst_buffer[2] + recon_uvoffset; - - xd->recon_left[0] = xd->recon_above[0] - 1; - xd->recon_left[1] = xd->recon_above[1] - 1; - xd->recon_left[2] = xd->recon_above[2] - 1; - - xd->recon_above[0] -= xd->dst.y_stride; - xd->recon_above[1] -= xd->dst.uv_stride; - xd->recon_above[2] -= xd->dst.uv_stride; - - /* TODO: move to outside row loop */ - xd->recon_left_stride[0] = xd->dst.y_stride; - xd->recon_left_stride[1] = xd->dst.uv_stride; - - setup_intra_recon_left(xd->recon_left[0], xd->recon_left[1], - xd->recon_left[2], xd->dst.y_stride, - xd->dst.uv_stride); - - for (mb_col = 0; mb_col < pc->mb_cols; ++mb_col) { - /* Distance of Mb to the various image edges. - * These are specified to 8th pel as they are always compared to values - * that are in 1/8th pel units - */ - xd->mb_to_left_edge = -((mb_col * 16) << 3); - xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3; - -#if CONFIG_ERROR_CONCEALMENT - { - int corrupt_residual = - (!pbi->independent_partitions && pbi->frame_corrupt_residual) || - vp8dx_bool_error(xd->current_bc); - if (pbi->ec_active && - xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME && - corrupt_residual) { - /* We have an intra block with corrupt coefficients, better to - * conceal with an inter block. Interpolate MVs from neighboring - * MBs. - * - * Note that for the first mb with corrupt residual in a frame, - * we might not discover that before decoding the residual. That - * happens after this check, and therefore no inter concealment - * will be done. - */ - vp8_interpolate_motion(xd, mb_row, mb_col, pc->mb_rows, pc->mb_cols); - } - } -#endif - - xd->dst.y_buffer = dst_buffer[0] + recon_yoffset; - xd->dst.u_buffer = dst_buffer[1] + recon_uvoffset; - xd->dst.v_buffer = dst_buffer[2] + recon_uvoffset; - - if (xd->mode_info_context->mbmi.ref_frame >= LAST_FRAME) { - const MV_REFERENCE_FRAME ref = xd->mode_info_context->mbmi.ref_frame; - xd->pre.y_buffer = ref_buffer[ref][0] + recon_yoffset; - xd->pre.u_buffer = ref_buffer[ref][1] + recon_uvoffset; - xd->pre.v_buffer = ref_buffer[ref][2] + recon_uvoffset; - } else { - // ref_frame is INTRA_FRAME, pre buffer should not be used. - xd->pre.y_buffer = 0; - xd->pre.u_buffer = 0; - xd->pre.v_buffer = 0; - } - - /* propagate errors from reference frames */ - xd->corrupted |= ref_fb_corrupted[xd->mode_info_context->mbmi.ref_frame]; - - decode_macroblock(pbi, xd, mb_idx); - - mb_idx++; - xd->left_available = 1; - - /* check if the boolean decoder has suffered an error */ - xd->corrupted |= vp8dx_bool_error(xd->current_bc); - - xd->recon_above[0] += 16; - xd->recon_above[1] += 8; - xd->recon_above[2] += 8; - xd->recon_left[0] += 16; - xd->recon_left[1] += 8; - xd->recon_left[2] += 8; - - recon_yoffset += 16; - recon_uvoffset += 8; - - ++xd->mode_info_context; /* next mb */ - - xd->above_context++; - } - - /* adjust to the next row of mbs */ - vp8_extend_mb_row(yv12_fb_new, xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, - xd->dst.v_buffer + 8); - - ++xd->mode_info_context; /* skip prediction column */ - xd->up_available = 1; - - if (pc->filter_level) { - if (mb_row > 0) { - if (pc->filter_type == NORMAL_LOOPFILTER) { - vp8_loop_filter_row_normal(pc, lf_mic, mb_row - 1, recon_y_stride, - recon_uv_stride, lf_dst[0], lf_dst[1], - lf_dst[2]); - } else { - vp8_loop_filter_row_simple(pc, lf_mic, mb_row - 1, recon_y_stride, - lf_dst[0]); - } - if (mb_row > 1) { - yv12_extend_frame_left_right_c(yv12_fb_new, eb_dst[0], eb_dst[1], - eb_dst[2]); - - eb_dst[0] += recon_y_stride * 16; - eb_dst[1] += recon_uv_stride * 8; - eb_dst[2] += recon_uv_stride * 8; - } - - lf_dst[0] += recon_y_stride * 16; - lf_dst[1] += recon_uv_stride * 8; - lf_dst[2] += recon_uv_stride * 8; - lf_mic += pc->mb_cols; - lf_mic++; /* Skip border mb */ - } - } else { - if (mb_row > 0) { - /**/ - yv12_extend_frame_left_right_c(yv12_fb_new, eb_dst[0], eb_dst[1], - eb_dst[2]); - eb_dst[0] += recon_y_stride * 16; - eb_dst[1] += recon_uv_stride * 8; - eb_dst[2] += recon_uv_stride * 8; - } - } - } - - if (pc->filter_level) { - if (pc->filter_type == NORMAL_LOOPFILTER) { - vp8_loop_filter_row_normal(pc, lf_mic, mb_row - 1, recon_y_stride, - recon_uv_stride, lf_dst[0], lf_dst[1], - lf_dst[2]); - } else { - vp8_loop_filter_row_simple(pc, lf_mic, mb_row - 1, recon_y_stride, - lf_dst[0]); - } - - yv12_extend_frame_left_right_c(yv12_fb_new, eb_dst[0], eb_dst[1], - eb_dst[2]); - eb_dst[0] += recon_y_stride * 16; - eb_dst[1] += recon_uv_stride * 8; - eb_dst[2] += recon_uv_stride * 8; - } - yv12_extend_frame_left_right_c(yv12_fb_new, eb_dst[0], eb_dst[1], eb_dst[2]); - yv12_extend_frame_top_c(yv12_fb_new); - yv12_extend_frame_bottom_c(yv12_fb_new); -} - -static unsigned int read_partition_size(VP8D_COMP *pbi, - const unsigned char *cx_size) { - unsigned char temp[3]; - if (pbi->decrypt_cb) { - pbi->decrypt_cb(pbi->decrypt_state, cx_size, temp, 3); - cx_size = temp; - } - return cx_size[0] + (cx_size[1] << 8) + (cx_size[2] << 16); -} - -static int read_is_valid(const unsigned char *start, size_t len, - const unsigned char *end) { - return len != 0 && end > start && len <= (size_t)(end - start); -} - -static unsigned int read_available_partition_size( - VP8D_COMP *pbi, const unsigned char *token_part_sizes, - const unsigned char *fragment_start, - const unsigned char *first_fragment_end, const unsigned char *fragment_end, - int i, int num_part) { - VP8_COMMON *pc = &pbi->common; - const unsigned char *partition_size_ptr = token_part_sizes + i * 3; - unsigned int partition_size = 0; - ptrdiff_t bytes_left = fragment_end - fragment_start; - if (bytes_left < 0) { - vpx_internal_error( - &pc->error, VPX_CODEC_CORRUPT_FRAME, - "Truncated packet or corrupt partition. No bytes left %d.", - (int)bytes_left); - } - /* Calculate the length of this partition. The last partition - * size is implicit. If the partition size can't be read, then - * either use the remaining data in the buffer (for EC mode) - * or throw an error. - */ - if (i < num_part - 1) { - if (read_is_valid(partition_size_ptr, 3, first_fragment_end)) { - partition_size = read_partition_size(pbi, partition_size_ptr); - } else if (pbi->ec_active) { - partition_size = (unsigned int)bytes_left; - } else { - vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, - "Truncated partition size data"); - } - } else { - partition_size = (unsigned int)bytes_left; - } - - /* Validate the calculated partition length. If the buffer - * described by the partition can't be fully read, then restrict - * it to the portion that can be (for EC mode) or throw an error. - */ - if (!read_is_valid(fragment_start, partition_size, fragment_end)) { - if (pbi->ec_active) { - partition_size = (unsigned int)bytes_left; - } else { - vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, - "Truncated packet or corrupt partition " - "%d length", - i + 1); - } - } - return partition_size; -} - -static void setup_token_decoder(VP8D_COMP *pbi, - const unsigned char *token_part_sizes) { - vp8_reader *bool_decoder = &pbi->mbc[0]; - unsigned int partition_idx; - unsigned int fragment_idx; - unsigned int num_token_partitions; - const unsigned char *first_fragment_end = - pbi->fragments.ptrs[0] + pbi->fragments.sizes[0]; - - TOKEN_PARTITION multi_token_partition = - (TOKEN_PARTITION)vp8_read_literal(&pbi->mbc[8], 2); - if (!vp8dx_bool_error(&pbi->mbc[8])) { - pbi->common.multi_token_partition = multi_token_partition; - } - num_token_partitions = 1 << pbi->common.multi_token_partition; - - /* Check for partitions within the fragments and unpack the fragments - * so that each fragment pointer points to its corresponding partition. */ - for (fragment_idx = 0; fragment_idx < pbi->fragments.count; ++fragment_idx) { - unsigned int fragment_size = pbi->fragments.sizes[fragment_idx]; - const unsigned char *fragment_end = - pbi->fragments.ptrs[fragment_idx] + fragment_size; - /* Special case for handling the first partition since we have already - * read its size. */ - if (fragment_idx == 0) { - /* Size of first partition + token partition sizes element */ - ptrdiff_t ext_first_part_size = token_part_sizes - - pbi->fragments.ptrs[0] + - 3 * (num_token_partitions - 1); - if (fragment_size < (unsigned int)ext_first_part_size) - vpx_internal_error(&pbi->common.error, VPX_CODEC_CORRUPT_FRAME, - "Corrupted fragment size %d", fragment_size); - fragment_size -= (unsigned int)ext_first_part_size; - if (fragment_size > 0) { - pbi->fragments.sizes[0] = (unsigned int)ext_first_part_size; - /* The fragment contains an additional partition. Move to - * next. */ - fragment_idx++; - pbi->fragments.ptrs[fragment_idx] = - pbi->fragments.ptrs[0] + pbi->fragments.sizes[0]; - } - } - /* Split the chunk into partitions read from the bitstream */ - while (fragment_size > 0) { - ptrdiff_t partition_size = read_available_partition_size( - pbi, token_part_sizes, pbi->fragments.ptrs[fragment_idx], - first_fragment_end, fragment_end, fragment_idx - 1, - num_token_partitions); - pbi->fragments.sizes[fragment_idx] = (unsigned int)partition_size; - if (fragment_size < (unsigned int)partition_size) - vpx_internal_error(&pbi->common.error, VPX_CODEC_CORRUPT_FRAME, - "Corrupted fragment size %d", fragment_size); - fragment_size -= (unsigned int)partition_size; - assert(fragment_idx <= num_token_partitions); - if (fragment_size > 0) { - /* The fragment contains an additional partition. - * Move to next. */ - fragment_idx++; - pbi->fragments.ptrs[fragment_idx] = - pbi->fragments.ptrs[fragment_idx - 1] + partition_size; - } - } - } - - pbi->fragments.count = num_token_partitions + 1; - - for (partition_idx = 1; partition_idx < pbi->fragments.count; - ++partition_idx) { - if (vp8dx_start_decode(bool_decoder, pbi->fragments.ptrs[partition_idx], - pbi->fragments.sizes[partition_idx], pbi->decrypt_cb, - pbi->decrypt_state)) { - vpx_internal_error(&pbi->common.error, VPX_CODEC_MEM_ERROR, - "Failed to allocate bool decoder %d", partition_idx); - } - - bool_decoder++; - } - -#if CONFIG_MULTITHREAD - /* Clamp number of decoder threads */ - if (pbi->decoding_thread_count > num_token_partitions - 1) { - pbi->decoding_thread_count = num_token_partitions - 1; - } - if ((int)pbi->decoding_thread_count > pbi->common.mb_rows - 1) { - assert(pbi->common.mb_rows > 0); - pbi->decoding_thread_count = pbi->common.mb_rows - 1; - } -#endif -} - -static void init_frame(VP8D_COMP *pbi) { - VP8_COMMON *const pc = &pbi->common; - MACROBLOCKD *const xd = &pbi->mb; - - if (pc->frame_type == KEY_FRAME) { - /* Various keyframe initializations */ - memcpy(pc->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context)); - - vp8_init_mbmode_probs(pc); - - vp8_default_coef_probs(pc); - - /* reset the segment feature data to 0 with delta coding (Default state). */ - memset(xd->segment_feature_data, 0, sizeof(xd->segment_feature_data)); - xd->mb_segment_abs_delta = SEGMENT_DELTADATA; - - /* reset the mode ref deltasa for loop filter */ - memset(xd->ref_lf_deltas, 0, sizeof(xd->ref_lf_deltas)); - memset(xd->mode_lf_deltas, 0, sizeof(xd->mode_lf_deltas)); - - /* All buffers are implicitly updated on key frames. */ - pc->refresh_golden_frame = 1; - pc->refresh_alt_ref_frame = 1; - pc->copy_buffer_to_gf = 0; - pc->copy_buffer_to_arf = 0; - - /* Note that Golden and Altref modes cannot be used on a key frame so - * ref_frame_sign_bias[] is undefined and meaningless - */ - pc->ref_frame_sign_bias[GOLDEN_FRAME] = 0; - pc->ref_frame_sign_bias[ALTREF_FRAME] = 0; - } else { - /* To enable choice of different interploation filters */ - if (!pc->use_bilinear_mc_filter) { - xd->subpixel_predict = vp8_sixtap_predict4x4; - xd->subpixel_predict8x4 = vp8_sixtap_predict8x4; - xd->subpixel_predict8x8 = vp8_sixtap_predict8x8; - xd->subpixel_predict16x16 = vp8_sixtap_predict16x16; - } else { - xd->subpixel_predict = vp8_bilinear_predict4x4; - xd->subpixel_predict8x4 = vp8_bilinear_predict8x4; - xd->subpixel_predict8x8 = vp8_bilinear_predict8x8; - xd->subpixel_predict16x16 = vp8_bilinear_predict16x16; - } - - if (pbi->decoded_key_frame && pbi->ec_enabled && !pbi->ec_active) { - pbi->ec_active = 1; - } - } - - xd->left_context = &pc->left_context; - xd->mode_info_context = pc->mi; - xd->frame_type = pc->frame_type; - xd->mode_info_context->mbmi.mode = DC_PRED; - xd->mode_info_stride = pc->mode_info_stride; - xd->corrupted = 0; /* init without corruption */ - - xd->fullpixel_mask = ~0; - if (pc->full_pixel) xd->fullpixel_mask = ~7; -} - -int vp8_decode_frame(VP8D_COMP *pbi) { - vp8_reader *const bc = &pbi->mbc[8]; - VP8_COMMON *const pc = &pbi->common; - MACROBLOCKD *const xd = &pbi->mb; - const unsigned char *data = pbi->fragments.ptrs[0]; - const unsigned int data_sz = pbi->fragments.sizes[0]; - const unsigned char *data_end = data + data_sz; - ptrdiff_t first_partition_length_in_bytes; - - int i, j, k, l; - const int *const mb_feature_data_bits = vp8_mb_feature_data_bits; - int corrupt_tokens = 0; - int prev_independent_partitions = pbi->independent_partitions; - - YV12_BUFFER_CONFIG *yv12_fb_new = pbi->dec_fb_ref[INTRA_FRAME]; - - /* start with no corruption of current frame */ - xd->corrupted = 0; - yv12_fb_new->corrupted = 0; - - if (data_end - data < 3) { - if (!pbi->ec_active) { - vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, - "Truncated packet"); - } - - /* Declare the missing frame as an inter frame since it will - be handled as an inter frame when we have estimated its - motion vectors. */ - pc->frame_type = INTER_FRAME; - pc->version = 0; - pc->show_frame = 1; - first_partition_length_in_bytes = 0; - } else { - unsigned char clear_buffer[10]; - const unsigned char *clear = data; - if (pbi->decrypt_cb) { - int n = (int)VPXMIN(sizeof(clear_buffer), data_sz); - pbi->decrypt_cb(pbi->decrypt_state, data, clear_buffer, n); - clear = clear_buffer; - } - - pc->frame_type = (FRAME_TYPE)(clear[0] & 1); - pc->version = (clear[0] >> 1) & 7; - pc->show_frame = (clear[0] >> 4) & 1; - first_partition_length_in_bytes = - (clear[0] | (clear[1] << 8) | (clear[2] << 16)) >> 5; - - if (!pbi->ec_active && (data + first_partition_length_in_bytes > data_end || - data + first_partition_length_in_bytes < data)) { - vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, - "Truncated packet or corrupt partition 0 length"); - } - - data += 3; - clear += 3; - - vp8_setup_version(pc); - - if (pc->frame_type == KEY_FRAME) { - /* vet via sync code */ - /* When error concealment is enabled we should only check the sync - * code if we have enough bits available - */ - if (data + 3 < data_end) { - if (clear[0] != 0x9d || clear[1] != 0x01 || clear[2] != 0x2a) { - vpx_internal_error(&pc->error, VPX_CODEC_UNSUP_BITSTREAM, - "Invalid frame sync code"); - } - } - - /* If error concealment is enabled we should only parse the new size - * if we have enough data. Otherwise we will end up with the wrong - * size. - */ - if (data + 6 < data_end) { - pc->Width = (clear[3] | (clear[4] << 8)) & 0x3fff; - pc->horiz_scale = clear[4] >> 6; - pc->Height = (clear[5] | (clear[6] << 8)) & 0x3fff; - pc->vert_scale = clear[6] >> 6; - data += 7; - } else if (!pbi->ec_active) { - vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, - "Truncated key frame header"); - } else { - /* Error concealment is active, clear the frame. */ - data = data_end; - } - } else { - memcpy(&xd->pre, yv12_fb_new, sizeof(YV12_BUFFER_CONFIG)); - memcpy(&xd->dst, yv12_fb_new, sizeof(YV12_BUFFER_CONFIG)); - } - } - if ((!pbi->decoded_key_frame && pc->frame_type != KEY_FRAME)) { - return -1; - } - - init_frame(pbi); - - if (vp8dx_start_decode(bc, data, (unsigned int)(data_end - data), - pbi->decrypt_cb, pbi->decrypt_state)) { - vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate bool decoder 0"); - } - if (pc->frame_type == KEY_FRAME) { - (void)vp8_read_bit(bc); // colorspace - pc->clamp_type = (CLAMP_TYPE)vp8_read_bit(bc); - } - - /* Is segmentation enabled */ - xd->segmentation_enabled = (unsigned char)vp8_read_bit(bc); - - if (xd->segmentation_enabled) { - /* Signal whether or not the segmentation map is being explicitly updated - * this frame. */ - xd->update_mb_segmentation_map = (unsigned char)vp8_read_bit(bc); - xd->update_mb_segmentation_data = (unsigned char)vp8_read_bit(bc); - - if (xd->update_mb_segmentation_data) { - xd->mb_segment_abs_delta = (unsigned char)vp8_read_bit(bc); - - memset(xd->segment_feature_data, 0, sizeof(xd->segment_feature_data)); - - /* For each segmentation feature (Quant and loop filter level) */ - for (i = 0; i < MB_LVL_MAX; ++i) { - for (j = 0; j < MAX_MB_SEGMENTS; ++j) { - /* Frame level data */ - if (vp8_read_bit(bc)) { - xd->segment_feature_data[i][j] = - (signed char)vp8_read_literal(bc, mb_feature_data_bits[i]); - - if (vp8_read_bit(bc)) { - xd->segment_feature_data[i][j] = -xd->segment_feature_data[i][j]; - } - } else { - xd->segment_feature_data[i][j] = 0; - } - } - } - } - - if (xd->update_mb_segmentation_map) { - /* Which macro block level features are enabled */ - memset(xd->mb_segment_tree_probs, 255, sizeof(xd->mb_segment_tree_probs)); - - /* Read the probs used to decode the segment id for each macro block. */ - for (i = 0; i < MB_FEATURE_TREE_PROBS; ++i) { - /* If not explicitly set value is defaulted to 255 by memset above */ - if (vp8_read_bit(bc)) { - xd->mb_segment_tree_probs[i] = (vp8_prob)vp8_read_literal(bc, 8); - } - } - } - } else { - /* No segmentation updates on this frame */ - xd->update_mb_segmentation_map = 0; - xd->update_mb_segmentation_data = 0; - } - - /* Read the loop filter level and type */ - pc->filter_type = (LOOPFILTERTYPE)vp8_read_bit(bc); - pc->filter_level = vp8_read_literal(bc, 6); - pc->sharpness_level = vp8_read_literal(bc, 3); - - /* Read in loop filter deltas applied at the MB level based on mode or ref - * frame. */ - xd->mode_ref_lf_delta_update = 0; - xd->mode_ref_lf_delta_enabled = (unsigned char)vp8_read_bit(bc); - - if (xd->mode_ref_lf_delta_enabled) { - /* Do the deltas need to be updated */ - xd->mode_ref_lf_delta_update = (unsigned char)vp8_read_bit(bc); - - if (xd->mode_ref_lf_delta_update) { - /* Send update */ - for (i = 0; i < MAX_REF_LF_DELTAS; ++i) { - if (vp8_read_bit(bc)) { - /*sign = vp8_read_bit( bc );*/ - xd->ref_lf_deltas[i] = (signed char)vp8_read_literal(bc, 6); - - if (vp8_read_bit(bc)) { /* Apply sign */ - xd->ref_lf_deltas[i] = xd->ref_lf_deltas[i] * -1; - } - } - } - - /* Send update */ - for (i = 0; i < MAX_MODE_LF_DELTAS; ++i) { - if (vp8_read_bit(bc)) { - /*sign = vp8_read_bit( bc );*/ - xd->mode_lf_deltas[i] = (signed char)vp8_read_literal(bc, 6); - - if (vp8_read_bit(bc)) { /* Apply sign */ - xd->mode_lf_deltas[i] = xd->mode_lf_deltas[i] * -1; - } - } - } - } - } - - setup_token_decoder(pbi, data + first_partition_length_in_bytes); - - xd->current_bc = &pbi->mbc[0]; - - /* Read the default quantizers. */ - { - int Q, q_update; - - Q = vp8_read_literal(bc, 7); /* AC 1st order Q = default */ - pc->base_qindex = Q; - q_update = 0; - pc->y1dc_delta_q = get_delta_q(bc, pc->y1dc_delta_q, &q_update); - pc->y2dc_delta_q = get_delta_q(bc, pc->y2dc_delta_q, &q_update); - pc->y2ac_delta_q = get_delta_q(bc, pc->y2ac_delta_q, &q_update); - pc->uvdc_delta_q = get_delta_q(bc, pc->uvdc_delta_q, &q_update); - pc->uvac_delta_q = get_delta_q(bc, pc->uvac_delta_q, &q_update); - - if (q_update) vp8cx_init_de_quantizer(pbi); - - /* MB level dequantizer setup */ - vp8_mb_init_dequantizer(pbi, &pbi->mb); - } - - /* Determine if the golden frame or ARF buffer should be updated and how. - * For all non key frames the GF and ARF refresh flags and sign bias - * flags must be set explicitly. - */ - if (pc->frame_type != KEY_FRAME) { - /* Should the GF or ARF be updated from the current frame */ - pc->refresh_golden_frame = vp8_read_bit(bc); -#if CONFIG_ERROR_CONCEALMENT - /* Assume we shouldn't refresh golden if the bit is missing */ - xd->corrupted |= vp8dx_bool_error(bc); - if (pbi->ec_active && xd->corrupted) pc->refresh_golden_frame = 0; -#endif - - pc->refresh_alt_ref_frame = vp8_read_bit(bc); -#if CONFIG_ERROR_CONCEALMENT - /* Assume we shouldn't refresh altref if the bit is missing */ - xd->corrupted |= vp8dx_bool_error(bc); - if (pbi->ec_active && xd->corrupted) pc->refresh_alt_ref_frame = 0; -#endif - - /* Buffer to buffer copy flags. */ - pc->copy_buffer_to_gf = 0; - - if (!pc->refresh_golden_frame) { - pc->copy_buffer_to_gf = vp8_read_literal(bc, 2); - } - -#if CONFIG_ERROR_CONCEALMENT - /* Assume we shouldn't copy to the golden if the bit is missing */ - xd->corrupted |= vp8dx_bool_error(bc); - if (pbi->ec_active && xd->corrupted) pc->copy_buffer_to_gf = 0; -#endif - - pc->copy_buffer_to_arf = 0; - - if (!pc->refresh_alt_ref_frame) { - pc->copy_buffer_to_arf = vp8_read_literal(bc, 2); - } - -#if CONFIG_ERROR_CONCEALMENT - /* Assume we shouldn't copy to the alt-ref if the bit is missing */ - xd->corrupted |= vp8dx_bool_error(bc); - if (pbi->ec_active && xd->corrupted) pc->copy_buffer_to_arf = 0; -#endif - - pc->ref_frame_sign_bias[GOLDEN_FRAME] = vp8_read_bit(bc); - pc->ref_frame_sign_bias[ALTREF_FRAME] = vp8_read_bit(bc); - } - - pc->refresh_entropy_probs = vp8_read_bit(bc); -#if CONFIG_ERROR_CONCEALMENT - /* Assume we shouldn't refresh the probabilities if the bit is - * missing */ - xd->corrupted |= vp8dx_bool_error(bc); - if (pbi->ec_active && xd->corrupted) pc->refresh_entropy_probs = 0; -#endif - if (pc->refresh_entropy_probs == 0) { - memcpy(&pc->lfc, &pc->fc, sizeof(pc->fc)); - } - - pc->refresh_last_frame = pc->frame_type == KEY_FRAME || vp8_read_bit(bc); - -#if CONFIG_ERROR_CONCEALMENT - /* Assume we should refresh the last frame if the bit is missing */ - xd->corrupted |= vp8dx_bool_error(bc); - if (pbi->ec_active && xd->corrupted) pc->refresh_last_frame = 1; -#endif - - { - pbi->independent_partitions = 1; - - /* read coef probability tree */ - for (i = 0; i < BLOCK_TYPES; ++i) { - for (j = 0; j < COEF_BANDS; ++j) { - for (k = 0; k < PREV_COEF_CONTEXTS; ++k) { - for (l = 0; l < ENTROPY_NODES; ++l) { - vp8_prob *const p = pc->fc.coef_probs[i][j][k] + l; - - if (vp8_read(bc, vp8_coef_update_probs[i][j][k][l])) { - *p = (vp8_prob)vp8_read_literal(bc, 8); - } - if (k > 0 && *p != pc->fc.coef_probs[i][j][k - 1][l]) { - pbi->independent_partitions = 0; - } - } - } - } - } - } - - /* clear out the coeff buffer */ - memset(xd->qcoeff, 0, sizeof(xd->qcoeff)); - - vp8_decode_mode_mvs(pbi); - -#if CONFIG_ERROR_CONCEALMENT - if (pbi->ec_active && - pbi->mvs_corrupt_from_mb < (unsigned int)pc->mb_cols * pc->mb_rows) { - /* Motion vectors are missing in this frame. We will try to estimate - * them and then continue decoding the frame as usual */ - vp8_estimate_missing_mvs(pbi); - } -#endif - - memset(pc->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) * pc->mb_cols); - pbi->frame_corrupt_residual = 0; - -#if CONFIG_MULTITHREAD - if (vpx_atomic_load_acquire(&pbi->b_multithreaded_rd) && - pc->multi_token_partition != ONE_PARTITION) { - unsigned int thread; - if (vp8mt_decode_mb_rows(pbi, xd)) { - vp8_decoder_remove_threads(pbi); - pbi->restart_threads = 1; - vpx_internal_error(&pbi->common.error, VPX_CODEC_CORRUPT_FRAME, NULL); - } - vp8_yv12_extend_frame_borders(yv12_fb_new); - for (thread = 0; thread < pbi->decoding_thread_count; ++thread) { - corrupt_tokens |= pbi->mb_row_di[thread].mbd.corrupted; - } - } else -#endif - { - decode_mb_rows(pbi); - corrupt_tokens |= xd->corrupted; - } - - /* Collect information about decoder corruption. */ - /* 1. Check first boolean decoder for errors. */ - yv12_fb_new->corrupted = vp8dx_bool_error(bc); - /* 2. Check the macroblock information */ - yv12_fb_new->corrupted |= corrupt_tokens; - - if (!pbi->decoded_key_frame) { - if (pc->frame_type == KEY_FRAME && !yv12_fb_new->corrupted) { - pbi->decoded_key_frame = 1; - } else { - vpx_internal_error(&pbi->common.error, VPX_CODEC_CORRUPT_FRAME, - "A stream must start with a complete key frame"); - } - } - - /* vpx_log("Decoder: Frame Decoded, Size Roughly:%d bytes - * \n",bc->pos+pbi->bc2.pos); */ - - if (pc->refresh_entropy_probs == 0) { - memcpy(&pc->fc, &pc->lfc, sizeof(pc->fc)); - pbi->independent_partitions = prev_independent_partitions; - } - -#ifdef PACKET_TESTING - { - FILE *f = fopen("decompressor.VP8", "ab"); - unsigned int size = pbi->bc2.pos + pbi->bc.pos + 8; - fwrite((void *)&size, 4, 1, f); - fwrite((void *)pbi->Source, size, 1, f); - fclose(f); - } -#endif - - return 0; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/decodemv.c b/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/decodemv.c deleted file mode 100644 index 3f459d62..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/decodemv.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "decodemv.h" -#include "treereader.h" -#include "vp8/common/entropymv.h" -#include "vp8/common/entropymode.h" -#include "onyxd_int.h" -#include "vp8/common/findnearmv.h" - -static B_PREDICTION_MODE read_bmode(vp8_reader *bc, const vp8_prob *p) { - const int i = vp8_treed_read(bc, vp8_bmode_tree, p); - - return (B_PREDICTION_MODE)i; -} - -static MB_PREDICTION_MODE read_ymode(vp8_reader *bc, const vp8_prob *p) { - const int i = vp8_treed_read(bc, vp8_ymode_tree, p); - - return (MB_PREDICTION_MODE)i; -} - -static MB_PREDICTION_MODE read_kf_ymode(vp8_reader *bc, const vp8_prob *p) { - const int i = vp8_treed_read(bc, vp8_kf_ymode_tree, p); - - return (MB_PREDICTION_MODE)i; -} - -static MB_PREDICTION_MODE read_uv_mode(vp8_reader *bc, const vp8_prob *p) { - const int i = vp8_treed_read(bc, vp8_uv_mode_tree, p); - - return (MB_PREDICTION_MODE)i; -} - -static void read_kf_modes(VP8D_COMP *pbi, MODE_INFO *mi) { - vp8_reader *const bc = &pbi->mbc[8]; - const int mis = pbi->common.mode_info_stride; - - mi->mbmi.ref_frame = INTRA_FRAME; - mi->mbmi.mode = read_kf_ymode(bc, vp8_kf_ymode_prob); - - if (mi->mbmi.mode == B_PRED) { - int i = 0; - mi->mbmi.is_4x4 = 1; - - do { - const B_PREDICTION_MODE A = above_block_mode(mi, i, mis); - const B_PREDICTION_MODE L = left_block_mode(mi, i); - - mi->bmi[i].as_mode = read_bmode(bc, vp8_kf_bmode_prob[A][L]); - } while (++i < 16); - } - - mi->mbmi.uv_mode = read_uv_mode(bc, vp8_kf_uv_mode_prob); -} - -static int read_mvcomponent(vp8_reader *r, const MV_CONTEXT *mvc) { - const vp8_prob *const p = (const vp8_prob *)mvc; - int x = 0; - - if (vp8_read(r, p[mvpis_short])) { /* Large */ - int i = 0; - - do { - x += vp8_read(r, p[MVPbits + i]) << i; - } while (++i < 3); - - i = mvlong_width - 1; /* Skip bit 3, which is sometimes implicit */ - - do { - x += vp8_read(r, p[MVPbits + i]) << i; - } while (--i > 3); - - if (!(x & 0xFFF0) || vp8_read(r, p[MVPbits + 3])) x += 8; - } else { /* small */ - x = vp8_treed_read(r, vp8_small_mvtree, p + MVPshort); - } - - if (x && vp8_read(r, p[MVPsign])) x = -x; - - return x; -} - -static void read_mv(vp8_reader *r, MV *mv, const MV_CONTEXT *mvc) { - mv->row = (short)(read_mvcomponent(r, mvc) * 2); - mv->col = (short)(read_mvcomponent(r, ++mvc) * 2); -} - -static void read_mvcontexts(vp8_reader *bc, MV_CONTEXT *mvc) { - int i = 0; - - do { - const vp8_prob *up = vp8_mv_update_probs[i].prob; - vp8_prob *p = (vp8_prob *)(mvc + i); - vp8_prob *const pstop = p + MVPcount; - - do { - if (vp8_read(bc, *up++)) { - const vp8_prob x = (vp8_prob)vp8_read_literal(bc, 7); - - *p = x ? x << 1 : 1; - } - } while (++p < pstop); - } while (++i < 2); -} - -static const unsigned char mbsplit_fill_count[4] = { 8, 8, 4, 1 }; -static const unsigned char mbsplit_fill_offset[4][16] = { - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, - { 0, 1, 4, 5, 8, 9, 12, 13, 2, 3, 6, 7, 10, 11, 14, 15 }, - { 0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15 }, - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } -}; - -static void mb_mode_mv_init(VP8D_COMP *pbi) { - vp8_reader *const bc = &pbi->mbc[8]; - MV_CONTEXT *const mvc = pbi->common.fc.mvc; - -#if CONFIG_ERROR_CONCEALMENT - /* Default is that no macroblock is corrupt, therefore we initialize - * mvs_corrupt_from_mb to something very big, which we can be sure is - * outside the frame. */ - pbi->mvs_corrupt_from_mb = UINT_MAX; -#endif - /* Read the mb_no_coeff_skip flag */ - pbi->common.mb_no_coeff_skip = (int)vp8_read_bit(bc); - - pbi->prob_skip_false = 0; - if (pbi->common.mb_no_coeff_skip) { - pbi->prob_skip_false = (vp8_prob)vp8_read_literal(bc, 8); - } - - if (pbi->common.frame_type != KEY_FRAME) { - pbi->prob_intra = (vp8_prob)vp8_read_literal(bc, 8); - pbi->prob_last = (vp8_prob)vp8_read_literal(bc, 8); - pbi->prob_gf = (vp8_prob)vp8_read_literal(bc, 8); - - if (vp8_read_bit(bc)) { - int i = 0; - - do { - pbi->common.fc.ymode_prob[i] = (vp8_prob)vp8_read_literal(bc, 8); - } while (++i < 4); - } - - if (vp8_read_bit(bc)) { - int i = 0; - - do { - pbi->common.fc.uv_mode_prob[i] = (vp8_prob)vp8_read_literal(bc, 8); - } while (++i < 3); - } - - read_mvcontexts(bc, mvc); - } -} - -const vp8_prob vp8_sub_mv_ref_prob3[8][VP8_SUBMVREFS - 1] = { - { 147, 136, 18 }, /* SUBMVREF_NORMAL */ - { 223, 1, 34 }, /* SUBMVREF_LEFT_ABOVE_SAME */ - { 106, 145, 1 }, /* SUBMVREF_LEFT_ZED */ - { 208, 1, 1 }, /* SUBMVREF_LEFT_ABOVE_ZED */ - { 179, 121, 1 }, /* SUBMVREF_ABOVE_ZED */ - { 223, 1, 34 }, /* SUBMVREF_LEFT_ABOVE_SAME */ - { 179, 121, 1 }, /* SUBMVREF_ABOVE_ZED */ - { 208, 1, 1 } /* SUBMVREF_LEFT_ABOVE_ZED */ -}; - -static const vp8_prob *get_sub_mv_ref_prob(const uint32_t left, - const uint32_t above) { - int lez = (left == 0); - int aez = (above == 0); - int lea = (left == above); - const vp8_prob *prob; - - prob = vp8_sub_mv_ref_prob3[(aez << 2) | (lez << 1) | (lea)]; - - return prob; -} - -static void decode_split_mv(vp8_reader *const bc, MODE_INFO *mi, - const MODE_INFO *left_mb, const MODE_INFO *above_mb, - MB_MODE_INFO *mbmi, int_mv best_mv, - MV_CONTEXT *const mvc, int mb_to_left_edge, - int mb_to_right_edge, int mb_to_top_edge, - int mb_to_bottom_edge) { - int s; /* split configuration (16x8, 8x16, 8x8, 4x4) */ - /* number of partitions in the split configuration (see vp8_mbsplit_count) */ - int num_p; - int j = 0; - - s = 3; - num_p = 16; - if (vp8_read(bc, 110)) { - s = 2; - num_p = 4; - if (vp8_read(bc, 111)) { - s = vp8_read(bc, 150); - num_p = 2; - } - } - - do /* for each subset j */ - { - int_mv leftmv, abovemv; - int_mv blockmv; - int k; /* first block in subset j */ - - const vp8_prob *prob; - k = vp8_mbsplit_offset[s][j]; - - if (!(k & 3)) { - /* On L edge, get from MB to left of us */ - if (left_mb->mbmi.mode != SPLITMV) { - leftmv.as_int = left_mb->mbmi.mv.as_int; - } else { - leftmv.as_int = (left_mb->bmi + k + 4 - 1)->mv.as_int; - } - } else { - leftmv.as_int = (mi->bmi + k - 1)->mv.as_int; - } - - if (!(k >> 2)) { - /* On top edge, get from MB above us */ - if (above_mb->mbmi.mode != SPLITMV) { - abovemv.as_int = above_mb->mbmi.mv.as_int; - } else { - abovemv.as_int = (above_mb->bmi + k + 16 - 4)->mv.as_int; - } - } else { - abovemv.as_int = (mi->bmi + k - 4)->mv.as_int; - } - - prob = get_sub_mv_ref_prob(leftmv.as_int, abovemv.as_int); - - if (vp8_read(bc, prob[0])) { - if (vp8_read(bc, prob[1])) { - blockmv.as_int = 0; - if (vp8_read(bc, prob[2])) { - blockmv.as_mv.row = read_mvcomponent(bc, &mvc[0]) * 2; - blockmv.as_mv.row += best_mv.as_mv.row; - blockmv.as_mv.col = read_mvcomponent(bc, &mvc[1]) * 2; - blockmv.as_mv.col += best_mv.as_mv.col; - } - } else { - blockmv.as_int = abovemv.as_int; - } - } else { - blockmv.as_int = leftmv.as_int; - } - - mbmi->need_to_clamp_mvs |= - vp8_check_mv_bounds(&blockmv, mb_to_left_edge, mb_to_right_edge, - mb_to_top_edge, mb_to_bottom_edge); - - { - /* Fill (uniform) modes, mvs of jth subset. - Must do it here because ensuing subsets can - refer back to us via "left" or "above". */ - const unsigned char *fill_offset; - unsigned int fill_count = mbsplit_fill_count[s]; - - fill_offset = - &mbsplit_fill_offset[s][(unsigned char)j * mbsplit_fill_count[s]]; - - do { - mi->bmi[*fill_offset].mv.as_int = blockmv.as_int; - fill_offset++; - } while (--fill_count); - } - - } while (++j < num_p); - - mbmi->partitioning = s; -} - -static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, - MB_MODE_INFO *mbmi) { - vp8_reader *const bc = &pbi->mbc[8]; - mbmi->ref_frame = (MV_REFERENCE_FRAME)vp8_read(bc, pbi->prob_intra); - if (mbmi->ref_frame) { /* inter MB */ - enum { CNT_INTRA, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV }; - int cnt[4]; - int *cntx = cnt; - int_mv near_mvs[4]; - int_mv *nmv = near_mvs; - const int mis = pbi->mb.mode_info_stride; - const MODE_INFO *above = mi - mis; - const MODE_INFO *left = mi - 1; - const MODE_INFO *aboveleft = above - 1; - int *ref_frame_sign_bias = pbi->common.ref_frame_sign_bias; - - mbmi->need_to_clamp_mvs = 0; - - if (vp8_read(bc, pbi->prob_last)) { - mbmi->ref_frame = - (MV_REFERENCE_FRAME)((int)(2 + vp8_read(bc, pbi->prob_gf))); - } - - /* Zero accumulators */ - nmv[0].as_int = nmv[1].as_int = nmv[2].as_int = 0; - cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0; - - /* Process above */ - if (above->mbmi.ref_frame != INTRA_FRAME) { - if (above->mbmi.mv.as_int) { - (++nmv)->as_int = above->mbmi.mv.as_int; - mv_bias(ref_frame_sign_bias[above->mbmi.ref_frame], mbmi->ref_frame, - nmv, ref_frame_sign_bias); - ++cntx; - } - - *cntx += 2; - } - - /* Process left */ - if (left->mbmi.ref_frame != INTRA_FRAME) { - if (left->mbmi.mv.as_int) { - int_mv this_mv; - - this_mv.as_int = left->mbmi.mv.as_int; - mv_bias(ref_frame_sign_bias[left->mbmi.ref_frame], mbmi->ref_frame, - &this_mv, ref_frame_sign_bias); - - if (this_mv.as_int != nmv->as_int) { - (++nmv)->as_int = this_mv.as_int; - ++cntx; - } - - *cntx += 2; - } else { - cnt[CNT_INTRA] += 2; - } - } - - /* Process above left */ - if (aboveleft->mbmi.ref_frame != INTRA_FRAME) { - if (aboveleft->mbmi.mv.as_int) { - int_mv this_mv; - - this_mv.as_int = aboveleft->mbmi.mv.as_int; - mv_bias(ref_frame_sign_bias[aboveleft->mbmi.ref_frame], mbmi->ref_frame, - &this_mv, ref_frame_sign_bias); - - if (this_mv.as_int != nmv->as_int) { - (++nmv)->as_int = this_mv.as_int; - ++cntx; - } - - *cntx += 1; - } else { - cnt[CNT_INTRA] += 1; - } - } - - if (vp8_read(bc, vp8_mode_contexts[cnt[CNT_INTRA]][0])) { - /* If we have three distinct MV's ... */ - /* See if above-left MV can be merged with NEAREST */ - cnt[CNT_NEAREST] += ((cnt[CNT_SPLITMV] > 0) & - (nmv->as_int == near_mvs[CNT_NEAREST].as_int)); - - /* Swap near and nearest if necessary */ - if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) { - int tmp; - tmp = cnt[CNT_NEAREST]; - cnt[CNT_NEAREST] = cnt[CNT_NEAR]; - cnt[CNT_NEAR] = tmp; - tmp = (int)near_mvs[CNT_NEAREST].as_int; - near_mvs[CNT_NEAREST].as_int = near_mvs[CNT_NEAR].as_int; - near_mvs[CNT_NEAR].as_int = (uint32_t)tmp; - } - - if (vp8_read(bc, vp8_mode_contexts[cnt[CNT_NEAREST]][1])) { - if (vp8_read(bc, vp8_mode_contexts[cnt[CNT_NEAR]][2])) { - int mb_to_top_edge; - int mb_to_bottom_edge; - int mb_to_left_edge; - int mb_to_right_edge; - MV_CONTEXT *const mvc = pbi->common.fc.mvc; - int near_index; - - mb_to_top_edge = pbi->mb.mb_to_top_edge; - mb_to_bottom_edge = pbi->mb.mb_to_bottom_edge; - mb_to_top_edge -= LEFT_TOP_MARGIN; - mb_to_bottom_edge += RIGHT_BOTTOM_MARGIN; - mb_to_right_edge = pbi->mb.mb_to_right_edge; - mb_to_right_edge += RIGHT_BOTTOM_MARGIN; - mb_to_left_edge = pbi->mb.mb_to_left_edge; - mb_to_left_edge -= LEFT_TOP_MARGIN; - - /* Use near_mvs[0] to store the "best" MV */ - near_index = CNT_INTRA + (cnt[CNT_NEAREST] >= cnt[CNT_INTRA]); - - vp8_clamp_mv2(&near_mvs[near_index], &pbi->mb); - - cnt[CNT_SPLITMV] = - ((above->mbmi.mode == SPLITMV) + (left->mbmi.mode == SPLITMV)) * - 2 + - (aboveleft->mbmi.mode == SPLITMV); - - if (vp8_read(bc, vp8_mode_contexts[cnt[CNT_SPLITMV]][3])) { - decode_split_mv(bc, mi, left, above, mbmi, near_mvs[near_index], - mvc, mb_to_left_edge, mb_to_right_edge, - mb_to_top_edge, mb_to_bottom_edge); - mbmi->mv.as_int = mi->bmi[15].mv.as_int; - mbmi->mode = SPLITMV; - mbmi->is_4x4 = 1; - } else { - int_mv *const mbmi_mv = &mbmi->mv; - read_mv(bc, &mbmi_mv->as_mv, (const MV_CONTEXT *)mvc); - mbmi_mv->as_mv.row += near_mvs[near_index].as_mv.row; - mbmi_mv->as_mv.col += near_mvs[near_index].as_mv.col; - - /* Don't need to check this on NEARMV and NEARESTMV - * modes since those modes clamp the MV. The NEWMV mode - * does not, so signal to the prediction stage whether - * special handling may be required. - */ - mbmi->need_to_clamp_mvs = - vp8_check_mv_bounds(mbmi_mv, mb_to_left_edge, mb_to_right_edge, - mb_to_top_edge, mb_to_bottom_edge); - mbmi->mode = NEWMV; - } - } else { - mbmi->mode = NEARMV; - mbmi->mv.as_int = near_mvs[CNT_NEAR].as_int; - vp8_clamp_mv2(&mbmi->mv, &pbi->mb); - } - } else { - mbmi->mode = NEARESTMV; - mbmi->mv.as_int = near_mvs[CNT_NEAREST].as_int; - vp8_clamp_mv2(&mbmi->mv, &pbi->mb); - } - } else { - mbmi->mode = ZEROMV; - mbmi->mv.as_int = 0; - } - -#if CONFIG_ERROR_CONCEALMENT - if (pbi->ec_enabled && (mbmi->mode != SPLITMV)) { - mi->bmi[0].mv.as_int = mi->bmi[1].mv.as_int = mi->bmi[2].mv.as_int = - mi->bmi[3].mv.as_int = mi->bmi[4].mv.as_int = mi->bmi[5].mv.as_int = - mi->bmi[6].mv.as_int = mi->bmi[7].mv.as_int = - mi->bmi[8].mv.as_int = mi->bmi[9].mv.as_int = - mi->bmi[10].mv.as_int = mi->bmi[11].mv.as_int = - mi->bmi[12].mv.as_int = mi->bmi[13].mv.as_int = - mi->bmi[14].mv.as_int = mi->bmi[15].mv.as_int = - mbmi->mv.as_int; - } -#endif - } else { - /* required for left and above block mv */ - mbmi->mv.as_int = 0; - - /* MB is intra coded */ - if ((mbmi->mode = read_ymode(bc, pbi->common.fc.ymode_prob)) == B_PRED) { - int j = 0; - mbmi->is_4x4 = 1; - do { - mi->bmi[j].as_mode = read_bmode(bc, pbi->common.fc.bmode_prob); - } while (++j < 16); - } - - mbmi->uv_mode = read_uv_mode(bc, pbi->common.fc.uv_mode_prob); - } -} - -static void read_mb_features(vp8_reader *r, MB_MODE_INFO *mi, MACROBLOCKD *x) { - /* Is segmentation enabled */ - if (x->segmentation_enabled && x->update_mb_segmentation_map) { - /* If so then read the segment id. */ - if (vp8_read(r, x->mb_segment_tree_probs[0])) { - mi->segment_id = - (unsigned char)(2 + vp8_read(r, x->mb_segment_tree_probs[2])); - } else { - mi->segment_id = - (unsigned char)(vp8_read(r, x->mb_segment_tree_probs[1])); - } - } -} - -static void decode_mb_mode_mvs(VP8D_COMP *pbi, MODE_INFO *mi) { - /* Read the Macroblock segmentation map if it is being updated explicitly - * this frame (reset to 0 above by default) - * By default on a key frame reset all MBs to segment 0 - */ - if (pbi->mb.update_mb_segmentation_map) { - read_mb_features(&pbi->mbc[8], &mi->mbmi, &pbi->mb); - } else if (pbi->common.frame_type == KEY_FRAME) { - mi->mbmi.segment_id = 0; - } - - /* Read the macroblock coeff skip flag if this feature is in use, - * else default to 0 */ - if (pbi->common.mb_no_coeff_skip) { - mi->mbmi.mb_skip_coeff = vp8_read(&pbi->mbc[8], pbi->prob_skip_false); - } else { - mi->mbmi.mb_skip_coeff = 0; - } - - mi->mbmi.is_4x4 = 0; - if (pbi->common.frame_type == KEY_FRAME) { - read_kf_modes(pbi, mi); - } else { - read_mb_modes_mv(pbi, mi, &mi->mbmi); - } -} - -void vp8_decode_mode_mvs(VP8D_COMP *pbi) { - MODE_INFO *mi = pbi->common.mi; - int mb_row = -1; - int mb_to_right_edge_start; - - mb_mode_mv_init(pbi); - - pbi->mb.mb_to_top_edge = 0; - pbi->mb.mb_to_bottom_edge = ((pbi->common.mb_rows - 1) * 16) << 3; - mb_to_right_edge_start = ((pbi->common.mb_cols - 1) * 16) << 3; - - while (++mb_row < pbi->common.mb_rows) { - int mb_col = -1; - - pbi->mb.mb_to_left_edge = 0; - pbi->mb.mb_to_right_edge = mb_to_right_edge_start; - - while (++mb_col < pbi->common.mb_cols) { -#if CONFIG_ERROR_CONCEALMENT - int mb_num = mb_row * pbi->common.mb_cols + mb_col; -#endif - - decode_mb_mode_mvs(pbi, mi); - -#if CONFIG_ERROR_CONCEALMENT - /* look for corruption. set mvs_corrupt_from_mb to the current - * mb_num if the frame is corrupt from this macroblock. */ - if (vp8dx_bool_error(&pbi->mbc[8]) && - mb_num < (int)pbi->mvs_corrupt_from_mb) { - pbi->mvs_corrupt_from_mb = mb_num; - /* no need to continue since the partition is corrupt from - * here on. - */ - return; - } -#endif - - pbi->mb.mb_to_left_edge -= (16 << 3); - pbi->mb.mb_to_right_edge -= (16 << 3); - mi++; /* next macroblock */ - } - pbi->mb.mb_to_top_edge -= (16 << 3); - pbi->mb.mb_to_bottom_edge -= (16 << 3); - - mi++; /* skip left predictor each row */ - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/decodemv.h b/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/decodemv.h deleted file mode 100644 index 504e943d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/decodemv.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_DECODER_DECODEMV_H_ -#define VPX_VP8_DECODER_DECODEMV_H_ - -#include "onyxd_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vp8_decode_mode_mvs(VP8D_COMP *); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_DECODER_DECODEMV_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/decoderthreading.h b/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/decoderthreading.h deleted file mode 100644 index 3d49bc83..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/decoderthreading.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_DECODER_DECODERTHREADING_H_ -#define VPX_VP8_DECODER_DECODERTHREADING_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#if CONFIG_MULTITHREAD -int vp8mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd); -void vp8_decoder_remove_threads(VP8D_COMP *pbi); -void vp8_decoder_create_threads(VP8D_COMP *pbi); -void vp8mt_alloc_temp_buffers(VP8D_COMP *pbi, int width, int prev_mb_rows); -void vp8mt_de_alloc_temp_buffers(VP8D_COMP *pbi, int mb_rows); -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_DECODER_DECODERTHREADING_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/detokenize.c b/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/detokenize.c deleted file mode 100644 index 1c77873f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/detokenize.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp8/common/blockd.h" -#include "onyxd_int.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/compiler_attributes.h" -#include "vpx_ports/mem.h" -#include "detokenize.h" - -void vp8_reset_mb_tokens_context(MACROBLOCKD *x) { - ENTROPY_CONTEXT *a_ctx = ((ENTROPY_CONTEXT *)x->above_context); - ENTROPY_CONTEXT *l_ctx = ((ENTROPY_CONTEXT *)x->left_context); - - memset(a_ctx, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1); - memset(l_ctx, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1); - - /* Clear entropy contexts for Y2 blocks */ - if (!x->mode_info_context->mbmi.is_4x4) { - a_ctx[8] = l_ctx[8] = 0; - } -} - -/* - ------------------------------------------------------------------------------ - Residual decoding (Paragraph 13.2 / 13.3) -*/ -static const uint8_t kBands[16 + 1] = { - 0, 1, 2, 3, 6, 4, 5, 6, 6, - 6, 6, 6, 6, 6, 6, 7, 0 /* extra entry as sentinel */ -}; - -static const uint8_t kCat3[] = { 173, 148, 140, 0 }; -static const uint8_t kCat4[] = { 176, 155, 140, 135, 0 }; -static const uint8_t kCat5[] = { 180, 157, 141, 134, 130, 0 }; -static const uint8_t kCat6[] = { 254, 254, 243, 230, 196, 177, - 153, 140, 133, 130, 129, 0 }; -static const uint8_t *const kCat3456[] = { kCat3, kCat4, kCat5, kCat6 }; -static const uint8_t kZigzag[16] = { 0, 1, 4, 8, 5, 2, 3, 6, - 9, 12, 13, 10, 7, 11, 14, 15 }; - -#define VP8GetBit vp8dx_decode_bool -#define NUM_PROBAS 11 -#define NUM_CTX 3 - -/* for const-casting */ -typedef const uint8_t (*ProbaArray)[NUM_CTX][NUM_PROBAS]; - -// With corrupt / fuzzed streams the calculation of br->value may overflow. See -// b/148271109. -static VPX_NO_UNSIGNED_OVERFLOW_CHECK int GetSigned(BOOL_DECODER *br, - int value_to_sign) { - int split = (br->range + 1) >> 1; - VP8_BD_VALUE bigsplit = (VP8_BD_VALUE)split << (VP8_BD_VALUE_SIZE - 8); - int v; - - if (br->count < 0) vp8dx_bool_decoder_fill(br); - - if (br->value < bigsplit) { - br->range = split; - v = value_to_sign; - } else { - br->range = br->range - split; - br->value = br->value - bigsplit; - v = -value_to_sign; - } - br->range += br->range; - br->value += br->value; - br->count--; - - return v; -} -/* - Returns the position of the last non-zero coeff plus one - (and 0 if there's no coeff at all) -*/ -static int GetCoeffs(BOOL_DECODER *br, ProbaArray prob, int ctx, int n, - int16_t *out) { - const uint8_t *p = prob[n][ctx]; - if (!VP8GetBit(br, p[0])) { /* first EOB is more a 'CBP' bit. */ - return 0; - } - while (1) { - ++n; - if (!VP8GetBit(br, p[1])) { - p = prob[kBands[n]][0]; - } else { /* non zero coeff */ - int v, j; - if (!VP8GetBit(br, p[2])) { - p = prob[kBands[n]][1]; - v = 1; - } else { - if (!VP8GetBit(br, p[3])) { - if (!VP8GetBit(br, p[4])) { - v = 2; - } else { - v = 3 + VP8GetBit(br, p[5]); - } - } else { - if (!VP8GetBit(br, p[6])) { - if (!VP8GetBit(br, p[7])) { - v = 5 + VP8GetBit(br, 159); - } else { - v = 7 + 2 * VP8GetBit(br, 165); - v += VP8GetBit(br, 145); - } - } else { - const uint8_t *tab; - const int bit1 = VP8GetBit(br, p[8]); - const int bit0 = VP8GetBit(br, p[9 + bit1]); - const int cat = 2 * bit1 + bit0; - v = 0; - for (tab = kCat3456[cat]; *tab; ++tab) { - v += v + VP8GetBit(br, *tab); - } - v += 3 + (8 << cat); - } - } - p = prob[kBands[n]][2]; - } - j = kZigzag[n - 1]; - - out[j] = GetSigned(br, v); - - if (n == 16 || !VP8GetBit(br, p[0])) { /* EOB */ - return n; - } - } - if (n == 16) { - return 16; - } - } -} - -int vp8_decode_mb_tokens(VP8D_COMP *dx, MACROBLOCKD *x) { - BOOL_DECODER *bc = x->current_bc; - const FRAME_CONTEXT *const fc = &dx->common.fc; - char *eobs = x->eobs; - - int i; - int nonzeros; - int eobtotal = 0; - - short *qcoeff_ptr; - ProbaArray coef_probs; - ENTROPY_CONTEXT *a_ctx = ((ENTROPY_CONTEXT *)x->above_context); - ENTROPY_CONTEXT *l_ctx = ((ENTROPY_CONTEXT *)x->left_context); - ENTROPY_CONTEXT *a; - ENTROPY_CONTEXT *l; - int skip_dc = 0; - - qcoeff_ptr = &x->qcoeff[0]; - - if (!x->mode_info_context->mbmi.is_4x4) { - a = a_ctx + 8; - l = l_ctx + 8; - - coef_probs = fc->coef_probs[1]; - - nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), 0, qcoeff_ptr + 24 * 16); - *a = *l = (nonzeros > 0); - - eobs[24] = nonzeros; - eobtotal += nonzeros - 16; - - coef_probs = fc->coef_probs[0]; - skip_dc = 1; - } else { - coef_probs = fc->coef_probs[3]; - skip_dc = 0; - } - - for (i = 0; i < 16; ++i) { - a = a_ctx + (i & 3); - l = l_ctx + ((i & 0xc) >> 2); - - nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), skip_dc, qcoeff_ptr); - *a = *l = (nonzeros > 0); - - nonzeros += skip_dc; - eobs[i] = nonzeros; - eobtotal += nonzeros; - qcoeff_ptr += 16; - } - - coef_probs = fc->coef_probs[2]; - - a_ctx += 4; - l_ctx += 4; - for (i = 16; i < 24; ++i) { - a = a_ctx + ((i > 19) << 1) + (i & 1); - l = l_ctx + ((i > 19) << 1) + ((i & 3) > 1); - - nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), 0, qcoeff_ptr); - *a = *l = (nonzeros > 0); - - eobs[i] = nonzeros; - eobtotal += nonzeros; - qcoeff_ptr += 16; - } - - return eobtotal; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/detokenize.h b/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/detokenize.h deleted file mode 100644 index 410a431b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/detokenize.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_DECODER_DETOKENIZE_H_ -#define VPX_VP8_DECODER_DETOKENIZE_H_ - -#include "onyxd_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vp8_reset_mb_tokens_context(MACROBLOCKD *x); -int vp8_decode_mb_tokens(VP8D_COMP *, MACROBLOCKD *); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_DECODER_DETOKENIZE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/ec_types.h b/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/ec_types.h deleted file mode 100644 index 84feb269..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/ec_types.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2011 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_DECODER_EC_TYPES_H_ -#define VPX_VP8_DECODER_EC_TYPES_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_OVERLAPS 16 - -/* The area (pixel area in Q6) the block pointed to by bmi overlaps - * another block with. - */ -typedef struct { - int overlap; - union b_mode_info *bmi; -} OVERLAP_NODE; - -/* Structure to keep track of overlapping blocks on a block level. */ -typedef struct { - /* TODO(holmer): This array should be exchanged for a linked list */ - OVERLAP_NODE overlaps[MAX_OVERLAPS]; -} B_OVERLAP; - -/* Structure used to hold all the overlaps of a macroblock. The overlaps of a - * macroblock is further divided into block overlaps. - */ -typedef struct { - B_OVERLAP overlaps[16]; -} MB_OVERLAP; - -/* Structure for keeping track of motion vectors and which reference frame they - * refer to. Used for motion vector interpolation. - */ -typedef struct { - MV mv; - MV_REFERENCE_FRAME ref_frame; -} EC_BLOCK; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_DECODER_EC_TYPES_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/error_concealment.c b/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/error_concealment.c deleted file mode 100644 index 85982e4d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/error_concealment.c +++ /dev/null @@ -1,482 +0,0 @@ -/* - * Copyright (c) 2011 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "error_concealment.h" -#include "onyxd_int.h" -#include "decodemv.h" -#include "vpx_mem/vpx_mem.h" -#include "vp8/common/findnearmv.h" -#include "vp8/common/common.h" -#include "vpx_dsp/vpx_dsp_common.h" - -#define FLOOR(x, q) ((x) & -(1 << (q))) - -#define NUM_NEIGHBORS 20 - -typedef struct ec_position { - int row; - int col; -} EC_POS; - -/* - * Regenerate the table in Matlab with: - * x = meshgrid((1:4), (1:4)); - * y = meshgrid((1:4), (1:4))'; - * W = round((1./(sqrt(x.^2 + y.^2))*2^7)); - * W(1,1) = 0; - */ -static const int weights_q7[5][5] = { { 0, 128, 64, 43, 32 }, - { 128, 91, 57, 40, 31 }, - { 64, 57, 45, 36, 29 }, - { 43, 40, 36, 30, 26 }, - { 32, 31, 29, 26, 23 } }; - -int vp8_alloc_overlap_lists(VP8D_COMP *pbi) { - if (pbi->overlaps != NULL) { - vpx_free(pbi->overlaps); - pbi->overlaps = NULL; - } - - pbi->overlaps = - vpx_calloc(pbi->common.mb_rows * pbi->common.mb_cols, sizeof(MB_OVERLAP)); - - if (pbi->overlaps == NULL) return -1; - - return 0; -} - -void vp8_de_alloc_overlap_lists(VP8D_COMP *pbi) { - vpx_free(pbi->overlaps); - pbi->overlaps = NULL; -} - -/* Inserts a new overlap area value to the list of overlaps of a block */ -static void assign_overlap(OVERLAP_NODE *overlaps, union b_mode_info *bmi, - int overlap) { - int i; - if (overlap <= 0) return; - /* Find and assign to the next empty overlap node in the list of overlaps. - * Empty is defined as bmi == NULL */ - for (i = 0; i < MAX_OVERLAPS; ++i) { - if (overlaps[i].bmi == NULL) { - overlaps[i].bmi = bmi; - overlaps[i].overlap = overlap; - break; - } - } -} - -/* Calculates the overlap area between two 4x4 squares, where the first - * square has its upper-left corner at (b1_row, b1_col) and the second - * square has its upper-left corner at (b2_row, b2_col). Doesn't - * properly handle squares which do not overlap. - */ -static int block_overlap(int b1_row, int b1_col, int b2_row, int b2_col) { - const int int_top = VPXMAX(b1_row, b2_row); // top - const int int_left = VPXMAX(b1_col, b2_col); // left - /* Since each block is 4x4 pixels, adding 4 (Q3) to the left/top edge - * gives us the right/bottom edge. - */ - const int int_right = VPXMIN(b1_col + (4 << 3), b2_col + (4 << 3)); // right - const int int_bottom = - VPXMIN(b1_row + (4 << 3), b2_row + (4 << 3)); // bottom - return (int_bottom - int_top) * (int_right - int_left); -} - -/* Calculates the overlap area for all blocks in a macroblock at position - * (mb_row, mb_col) in macroblocks, which are being overlapped by a given - * overlapping block at position (new_row, new_col) (in pixels, Q3). The - * first block being overlapped in the macroblock has position (first_blk_row, - * first_blk_col) in blocks relative the upper-left corner of the image. - */ -static void calculate_overlaps_mb(B_OVERLAP *b_overlaps, union b_mode_info *bmi, - int new_row, int new_col, int mb_row, - int mb_col, int first_blk_row, - int first_blk_col) { - /* Find the blocks within this MB (defined by mb_row, mb_col) which are - * overlapped by bmi and calculate and assign overlap for each of those - * blocks. */ - - /* Block coordinates relative the upper-left block */ - const int rel_ol_blk_row = first_blk_row - mb_row * 4; - const int rel_ol_blk_col = first_blk_col - mb_col * 4; - /* If the block partly overlaps any previous MB, these coordinates - * can be < 0. We don't want to access blocks in previous MBs. - */ - const int blk_idx = VPXMAX(rel_ol_blk_row, 0) * 4 + VPXMAX(rel_ol_blk_col, 0); - /* Upper left overlapping block */ - B_OVERLAP *b_ol_ul = &(b_overlaps[blk_idx]); - - /* Calculate and assign overlaps for all blocks in this MB - * which the motion compensated block overlaps - */ - /* Avoid calculating overlaps for blocks in later MBs */ - int end_row = VPXMIN(4 + mb_row * 4 - first_blk_row, 2); - int end_col = VPXMIN(4 + mb_col * 4 - first_blk_col, 2); - int row, col; - - /* Check if new_row and new_col are evenly divisible by 4 (Q3), - * and if so we shouldn't check neighboring blocks - */ - if (new_row >= 0 && (new_row & 0x1F) == 0) end_row = 1; - if (new_col >= 0 && (new_col & 0x1F) == 0) end_col = 1; - - /* Check if the overlapping block partly overlaps a previous MB - * and if so, we're overlapping fewer blocks in this MB. - */ - if (new_row < (mb_row * 16) << 3) end_row = 1; - if (new_col < (mb_col * 16) << 3) end_col = 1; - - for (row = 0; row < end_row; ++row) { - for (col = 0; col < end_col; ++col) { - /* input in Q3, result in Q6 */ - const int overlap = - block_overlap(new_row, new_col, (((first_blk_row + row) * 4) << 3), - (((first_blk_col + col) * 4) << 3)); - assign_overlap(b_ol_ul[row * 4 + col].overlaps, bmi, overlap); - } - } -} - -static void calculate_overlaps(MB_OVERLAP *overlap_ul, int mb_rows, int mb_cols, - union b_mode_info *bmi, int b_row, int b_col) { - MB_OVERLAP *mb_overlap; - int row, col, rel_row, rel_col; - int new_row, new_col; - int end_row, end_col; - int overlap_b_row, overlap_b_col; - int overlap_mb_row, overlap_mb_col; - - /* mb subpixel position */ - row = (4 * b_row) << 3; /* Q3 */ - col = (4 * b_col) << 3; /* Q3 */ - - /* reverse compensate for motion */ - new_row = row - bmi->mv.as_mv.row; - new_col = col - bmi->mv.as_mv.col; - - if (new_row >= ((16 * mb_rows) << 3) || new_col >= ((16 * mb_cols) << 3)) { - /* the new block ended up outside the frame */ - return; - } - - if (new_row <= -32 || new_col <= -32) { - /* outside the frame */ - return; - } - /* overlapping block's position in blocks */ - overlap_b_row = FLOOR(new_row / 4, 3) >> 3; - overlap_b_col = FLOOR(new_col / 4, 3) >> 3; - - /* overlapping block's MB position in MBs - * operations are done in Q3 - */ - overlap_mb_row = FLOOR((overlap_b_row << 3) / 4, 3) >> 3; - overlap_mb_col = FLOOR((overlap_b_col << 3) / 4, 3) >> 3; - - end_row = VPXMIN(mb_rows - overlap_mb_row, 2); - end_col = VPXMIN(mb_cols - overlap_mb_col, 2); - - /* Don't calculate overlap for MBs we don't overlap */ - /* Check if the new block row starts at the last block row of the MB */ - if (abs(new_row - ((16 * overlap_mb_row) << 3)) < ((3 * 4) << 3)) end_row = 1; - /* Check if the new block col starts at the last block col of the MB */ - if (abs(new_col - ((16 * overlap_mb_col) << 3)) < ((3 * 4) << 3)) end_col = 1; - - /* find the MB(s) this block is overlapping */ - for (rel_row = 0; rel_row < end_row; ++rel_row) { - for (rel_col = 0; rel_col < end_col; ++rel_col) { - if (overlap_mb_row + rel_row < 0 || overlap_mb_col + rel_col < 0) - continue; - mb_overlap = overlap_ul + (overlap_mb_row + rel_row) * mb_cols + - overlap_mb_col + rel_col; - - calculate_overlaps_mb(mb_overlap->overlaps, bmi, new_row, new_col, - overlap_mb_row + rel_row, overlap_mb_col + rel_col, - overlap_b_row + rel_row, overlap_b_col + rel_col); - } - } -} - -/* Estimates a motion vector given the overlapping blocks' motion vectors. - * Filters out all overlapping blocks which do not refer to the correct - * reference frame type. - */ -static void estimate_mv(const OVERLAP_NODE *overlaps, union b_mode_info *bmi) { - int i; - int overlap_sum = 0; - int row_acc = 0; - int col_acc = 0; - - bmi->mv.as_int = 0; - for (i = 0; i < MAX_OVERLAPS; ++i) { - if (overlaps[i].bmi == NULL) break; - col_acc += overlaps[i].overlap * overlaps[i].bmi->mv.as_mv.col; - row_acc += overlaps[i].overlap * overlaps[i].bmi->mv.as_mv.row; - overlap_sum += overlaps[i].overlap; - } - if (overlap_sum > 0) { - /* Q9 / Q6 = Q3 */ - bmi->mv.as_mv.col = col_acc / overlap_sum; - bmi->mv.as_mv.row = row_acc / overlap_sum; - } else { - bmi->mv.as_mv.col = 0; - bmi->mv.as_mv.row = 0; - } -} - -/* Estimates all motion vectors for a macroblock given the lists of - * overlaps for each block. Decides whether or not the MVs must be clamped. - */ -static void estimate_mb_mvs(const B_OVERLAP *block_overlaps, MODE_INFO *mi, - int mb_to_left_edge, int mb_to_right_edge, - int mb_to_top_edge, int mb_to_bottom_edge) { - int row, col; - int non_zero_count = 0; - MV *const filtered_mv = &(mi->mbmi.mv.as_mv); - union b_mode_info *const bmi = mi->bmi; - filtered_mv->col = 0; - filtered_mv->row = 0; - mi->mbmi.need_to_clamp_mvs = 0; - for (row = 0; row < 4; ++row) { - int this_b_to_top_edge = mb_to_top_edge + ((row * 4) << 3); - int this_b_to_bottom_edge = mb_to_bottom_edge - ((row * 4) << 3); - for (col = 0; col < 4; ++col) { - int i = row * 4 + col; - int this_b_to_left_edge = mb_to_left_edge + ((col * 4) << 3); - int this_b_to_right_edge = mb_to_right_edge - ((col * 4) << 3); - /* Estimate vectors for all blocks which are overlapped by this */ - /* type. Interpolate/extrapolate the rest of the block's MVs */ - estimate_mv(block_overlaps[i].overlaps, &(bmi[i])); - mi->mbmi.need_to_clamp_mvs |= vp8_check_mv_bounds( - &bmi[i].mv, this_b_to_left_edge, this_b_to_right_edge, - this_b_to_top_edge, this_b_to_bottom_edge); - if (bmi[i].mv.as_int != 0) { - ++non_zero_count; - filtered_mv->col += bmi[i].mv.as_mv.col; - filtered_mv->row += bmi[i].mv.as_mv.row; - } - } - } - if (non_zero_count > 0) { - filtered_mv->col /= non_zero_count; - filtered_mv->row /= non_zero_count; - } -} - -static void calc_prev_mb_overlaps(MB_OVERLAP *overlaps, MODE_INFO *prev_mi, - int mb_row, int mb_col, int mb_rows, - int mb_cols) { - int sub_row; - int sub_col; - for (sub_row = 0; sub_row < 4; ++sub_row) { - for (sub_col = 0; sub_col < 4; ++sub_col) { - calculate_overlaps(overlaps, mb_rows, mb_cols, - &(prev_mi->bmi[sub_row * 4 + sub_col]), - 4 * mb_row + sub_row, 4 * mb_col + sub_col); - } - } -} - -/* Estimate all missing motion vectors. This function does the same as the one - * above, but has different input arguments. */ -static void estimate_missing_mvs(MB_OVERLAP *overlaps, MODE_INFO *mi, - MODE_INFO *prev_mi, int mb_rows, int mb_cols, - unsigned int first_corrupt) { - int mb_row, mb_col; - memset(overlaps, 0, sizeof(MB_OVERLAP) * mb_rows * mb_cols); - /* First calculate the overlaps for all blocks */ - for (mb_row = 0; mb_row < mb_rows; ++mb_row) { - for (mb_col = 0; mb_col < mb_cols; ++mb_col) { - /* We're only able to use blocks referring to the last frame - * when extrapolating new vectors. - */ - if (prev_mi->mbmi.ref_frame == LAST_FRAME) { - calc_prev_mb_overlaps(overlaps, prev_mi, mb_row, mb_col, mb_rows, - mb_cols); - } - ++prev_mi; - } - ++prev_mi; - } - - mb_row = first_corrupt / mb_cols; - mb_col = first_corrupt - mb_row * mb_cols; - mi += mb_row * (mb_cols + 1) + mb_col; - /* Go through all macroblocks in the current image with missing MVs - * and calculate new MVs using the overlaps. - */ - for (; mb_row < mb_rows; ++mb_row) { - int mb_to_top_edge = -((mb_row * 16)) << 3; - int mb_to_bottom_edge = ((mb_rows - 1 - mb_row) * 16) << 3; - for (; mb_col < mb_cols; ++mb_col) { - int mb_to_left_edge = -((mb_col * 16) << 3); - int mb_to_right_edge = ((mb_cols - 1 - mb_col) * 16) << 3; - const B_OVERLAP *block_overlaps = - overlaps[mb_row * mb_cols + mb_col].overlaps; - mi->mbmi.ref_frame = LAST_FRAME; - mi->mbmi.mode = SPLITMV; - mi->mbmi.uv_mode = DC_PRED; - mi->mbmi.partitioning = 3; - mi->mbmi.segment_id = 0; - estimate_mb_mvs(block_overlaps, mi, mb_to_left_edge, mb_to_right_edge, - mb_to_top_edge, mb_to_bottom_edge); - ++mi; - } - mb_col = 0; - ++mi; - } -} - -void vp8_estimate_missing_mvs(VP8D_COMP *pbi) { - VP8_COMMON *const pc = &pbi->common; - estimate_missing_mvs(pbi->overlaps, pc->mi, pc->prev_mi, pc->mb_rows, - pc->mb_cols, pbi->mvs_corrupt_from_mb); -} - -static void assign_neighbor(EC_BLOCK *neighbor, MODE_INFO *mi, int block_idx) { - assert(mi->mbmi.ref_frame < MAX_REF_FRAMES); - neighbor->ref_frame = mi->mbmi.ref_frame; - neighbor->mv = mi->bmi[block_idx].mv.as_mv; -} - -/* Finds the neighboring blocks of a macroblocks. In the general case - * 20 blocks are found. If a fewer number of blocks are found due to - * image boundaries, those positions in the EC_BLOCK array are left "empty". - * The neighbors are enumerated with the upper-left neighbor as the first - * element, the second element refers to the neighbor to right of the previous - * neighbor, and so on. The last element refers to the neighbor below the first - * neighbor. - */ -static void find_neighboring_blocks(MODE_INFO *mi, EC_BLOCK *neighbors, - int mb_row, int mb_col, int mb_rows, - int mb_cols, int mi_stride) { - int i = 0; - int j; - if (mb_row > 0) { - /* upper left */ - if (mb_col > 0) assign_neighbor(&neighbors[i], mi - mi_stride - 1, 15); - ++i; - /* above */ - for (j = 12; j < 16; ++j, ++i) - assign_neighbor(&neighbors[i], mi - mi_stride, j); - } else - i += 5; - if (mb_col < mb_cols - 1) { - /* upper right */ - if (mb_row > 0) assign_neighbor(&neighbors[i], mi - mi_stride + 1, 12); - ++i; - /* right */ - for (j = 0; j <= 12; j += 4, ++i) assign_neighbor(&neighbors[i], mi + 1, j); - } else - i += 5; - if (mb_row < mb_rows - 1) { - /* lower right */ - if (mb_col < mb_cols - 1) - assign_neighbor(&neighbors[i], mi + mi_stride + 1, 0); - ++i; - /* below */ - for (j = 0; j < 4; ++j, ++i) - assign_neighbor(&neighbors[i], mi + mi_stride, j); - } else - i += 5; - if (mb_col > 0) { - /* lower left */ - if (mb_row < mb_rows - 1) - assign_neighbor(&neighbors[i], mi + mi_stride - 1, 4); - ++i; - /* left */ - for (j = 3; j < 16; j += 4, ++i) { - assign_neighbor(&neighbors[i], mi - 1, j); - } - } else - i += 5; - assert(i == 20); -} - -/* Interpolates all motion vectors for a macroblock from the neighboring blocks' - * motion vectors. - */ -static void interpolate_mvs(MACROBLOCKD *mb, EC_BLOCK *neighbors, - MV_REFERENCE_FRAME dom_ref_frame) { - int row, col, i; - MODE_INFO *const mi = mb->mode_info_context; - /* Table with the position of the neighboring blocks relative the position - * of the upper left block of the current MB. Starting with the upper left - * neighbor and going to the right. - */ - const EC_POS neigh_pos[NUM_NEIGHBORS] = { - { -1, -1 }, { -1, 0 }, { -1, 1 }, { -1, 2 }, { -1, 3 }, { -1, 4 }, { 0, 4 }, - { 1, 4 }, { 2, 4 }, { 3, 4 }, { 4, 4 }, { 4, 3 }, { 4, 2 }, { 4, 1 }, - { 4, 0 }, { 4, -1 }, { 3, -1 }, { 2, -1 }, { 1, -1 }, { 0, -1 } - }; - mi->mbmi.need_to_clamp_mvs = 0; - for (row = 0; row < 4; ++row) { - int mb_to_top_edge = mb->mb_to_top_edge + ((row * 4) << 3); - int mb_to_bottom_edge = mb->mb_to_bottom_edge - ((row * 4) << 3); - for (col = 0; col < 4; ++col) { - int mb_to_left_edge = mb->mb_to_left_edge + ((col * 4) << 3); - int mb_to_right_edge = mb->mb_to_right_edge - ((col * 4) << 3); - int w_sum = 0; - int mv_row_sum = 0; - int mv_col_sum = 0; - int_mv *const mv = &(mi->bmi[row * 4 + col].mv); - mv->as_int = 0; - for (i = 0; i < NUM_NEIGHBORS; ++i) { - /* Calculate the weighted sum of neighboring MVs referring - * to the dominant frame type. - */ - const int w = weights_q7[abs(row - neigh_pos[i].row)] - [abs(col - neigh_pos[i].col)]; - if (neighbors[i].ref_frame != dom_ref_frame) continue; - w_sum += w; - /* Q7 * Q3 = Q10 */ - mv_row_sum += w * neighbors[i].mv.row; - mv_col_sum += w * neighbors[i].mv.col; - } - if (w_sum > 0) { - /* Avoid division by zero. - * Normalize with the sum of the coefficients - * Q3 = Q10 / Q7 - */ - mv->as_mv.row = mv_row_sum / w_sum; - mv->as_mv.col = mv_col_sum / w_sum; - mi->mbmi.need_to_clamp_mvs |= - vp8_check_mv_bounds(mv, mb_to_left_edge, mb_to_right_edge, - mb_to_top_edge, mb_to_bottom_edge); - } - } - } -} - -void vp8_interpolate_motion(MACROBLOCKD *mb, int mb_row, int mb_col, - int mb_rows, int mb_cols) { - /* Find relevant neighboring blocks */ - EC_BLOCK neighbors[NUM_NEIGHBORS]; - int i; - /* Initialize the array. MAX_REF_FRAMES is interpreted as "doesn't exist" */ - for (i = 0; i < NUM_NEIGHBORS; ++i) { - neighbors[i].ref_frame = MAX_REF_FRAMES; - neighbors[i].mv.row = neighbors[i].mv.col = 0; - } - find_neighboring_blocks(mb->mode_info_context, neighbors, mb_row, mb_col, - mb_rows, mb_cols, mb->mode_info_stride); - /* Interpolate MVs for the missing blocks from the surrounding - * blocks which refer to the last frame. */ - interpolate_mvs(mb, neighbors, LAST_FRAME); - - mb->mode_info_context->mbmi.ref_frame = LAST_FRAME; - mb->mode_info_context->mbmi.mode = SPLITMV; - mb->mode_info_context->mbmi.uv_mode = DC_PRED; - mb->mode_info_context->mbmi.partitioning = 3; - mb->mode_info_context->mbmi.segment_id = 0; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/error_concealment.h b/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/error_concealment.h deleted file mode 100644 index 608a79f1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/error_concealment.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2011 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_DECODER_ERROR_CONCEALMENT_H_ -#define VPX_VP8_DECODER_ERROR_CONCEALMENT_H_ - -#include "onyxd_int.h" -#include "ec_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Allocate memory for the overlap lists */ -int vp8_alloc_overlap_lists(VP8D_COMP *pbi); - -/* Deallocate the overlap lists */ -void vp8_de_alloc_overlap_lists(VP8D_COMP *pbi); - -/* Estimate all missing motion vectors. */ -void vp8_estimate_missing_mvs(VP8D_COMP *pbi); - -/* Functions for spatial MV interpolation */ - -/* Interpolates all motion vectors for a macroblock mb at position - * (mb_row, mb_col). */ -void vp8_interpolate_motion(MACROBLOCKD *mb, int mb_row, int mb_col, - int mb_rows, int mb_cols); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_DECODER_ERROR_CONCEALMENT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/onyxd_if.c b/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/onyxd_if.c deleted file mode 100644 index 88f2de02..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/onyxd_if.c +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp8/common/onyxc_int.h" -#if CONFIG_POSTPROC -#include "vp8/common/postproc.h" -#endif -#include "vp8/common/onyxd.h" -#include "onyxd_int.h" -#include "vpx_mem/vpx_mem.h" -#include "vp8/common/alloccommon.h" -#include "vp8/common/common.h" -#include "vp8/common/loopfilter.h" -#include "vp8/common/swapyv12buffer.h" -#include "vp8/common/threading.h" -#include "decoderthreading.h" -#include -#include - -#include "vp8/common/quant_common.h" -#include "vp8/common/reconintra.h" -#include "./vpx_dsp_rtcd.h" -#include "./vpx_scale_rtcd.h" -#include "vpx_scale/vpx_scale.h" -#include "vp8/common/systemdependent.h" -#include "vpx_ports/system_state.h" -#include "vpx_ports/vpx_once.h" -#include "vpx_ports/vpx_timer.h" -#include "detokenize.h" -#if CONFIG_ERROR_CONCEALMENT -#include "error_concealment.h" -#endif -#if VPX_ARCH_ARM -#include "vpx_ports/arm.h" -#endif - -extern void vp8_init_loop_filter(VP8_COMMON *cm); -static int get_free_fb(VP8_COMMON *cm); -static void ref_cnt_fb(int *buf, int *idx, int new_idx); - -static void initialize_dec(void) { - static volatile int init_done = 0; - - if (!init_done) { - vpx_dsp_rtcd(); - vp8_init_intra_predictors(); - init_done = 1; - } -} - -static void remove_decompressor(VP8D_COMP *pbi) { -#if CONFIG_ERROR_CONCEALMENT - vp8_de_alloc_overlap_lists(pbi); -#endif - vp8_remove_common(&pbi->common); - vpx_free(pbi); -} - -static struct VP8D_COMP *create_decompressor(VP8D_CONFIG *oxcf) { - VP8D_COMP *pbi = vpx_memalign(32, sizeof(VP8D_COMP)); - - if (!pbi) return NULL; - - memset(pbi, 0, sizeof(VP8D_COMP)); - - if (setjmp(pbi->common.error.jmp)) { - pbi->common.error.setjmp = 0; - remove_decompressor(pbi); - return 0; - } - - pbi->common.error.setjmp = 1; - - vp8_create_common(&pbi->common); - - pbi->common.current_video_frame = 0; - pbi->ready_for_new_data = 1; - - /* vp8cx_init_de_quantizer() is first called here. Add check in - * frame_init_dequantizer() to avoid - * unnecessary calling of vp8cx_init_de_quantizer() for every frame. - */ - vp8cx_init_de_quantizer(pbi); - - vp8_loop_filter_init(&pbi->common); - - pbi->common.error.setjmp = 0; - -#if CONFIG_ERROR_CONCEALMENT - pbi->ec_enabled = oxcf->error_concealment; - pbi->overlaps = NULL; -#else - (void)oxcf; - pbi->ec_enabled = 0; -#endif - /* Error concealment is activated after a key frame has been - * decoded without errors when error concealment is enabled. - */ - pbi->ec_active = 0; - - pbi->decoded_key_frame = 0; - - /* Independent partitions is activated when a frame updates the - * token probability table to have equal probabilities over the - * PREV_COEF context. - */ - pbi->independent_partitions = 0; - - vp8_setup_block_dptrs(&pbi->mb); - - once(initialize_dec); - - return pbi; -} - -vpx_codec_err_t vp8dx_get_reference(VP8D_COMP *pbi, - enum vpx_ref_frame_type ref_frame_flag, - YV12_BUFFER_CONFIG *sd) { - VP8_COMMON *cm = &pbi->common; - int ref_fb_idx; - - if (ref_frame_flag == VP8_LAST_FRAME) { - ref_fb_idx = cm->lst_fb_idx; - } else if (ref_frame_flag == VP8_GOLD_FRAME) { - ref_fb_idx = cm->gld_fb_idx; - } else if (ref_frame_flag == VP8_ALTR_FRAME) { - ref_fb_idx = cm->alt_fb_idx; - } else { - vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR, - "Invalid reference frame"); - return pbi->common.error.error_code; - } - - if (cm->yv12_fb[ref_fb_idx].y_height != sd->y_height || - cm->yv12_fb[ref_fb_idx].y_width != sd->y_width || - cm->yv12_fb[ref_fb_idx].uv_height != sd->uv_height || - cm->yv12_fb[ref_fb_idx].uv_width != sd->uv_width) { - vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR, - "Incorrect buffer dimensions"); - } else - vp8_yv12_copy_frame(&cm->yv12_fb[ref_fb_idx], sd); - - return pbi->common.error.error_code; -} - -vpx_codec_err_t vp8dx_set_reference(VP8D_COMP *pbi, - enum vpx_ref_frame_type ref_frame_flag, - YV12_BUFFER_CONFIG *sd) { - VP8_COMMON *cm = &pbi->common; - int *ref_fb_ptr = NULL; - int free_fb; - - if (ref_frame_flag == VP8_LAST_FRAME) { - ref_fb_ptr = &cm->lst_fb_idx; - } else if (ref_frame_flag == VP8_GOLD_FRAME) { - ref_fb_ptr = &cm->gld_fb_idx; - } else if (ref_frame_flag == VP8_ALTR_FRAME) { - ref_fb_ptr = &cm->alt_fb_idx; - } else { - vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR, - "Invalid reference frame"); - return pbi->common.error.error_code; - } - - if (cm->yv12_fb[*ref_fb_ptr].y_height != sd->y_height || - cm->yv12_fb[*ref_fb_ptr].y_width != sd->y_width || - cm->yv12_fb[*ref_fb_ptr].uv_height != sd->uv_height || - cm->yv12_fb[*ref_fb_ptr].uv_width != sd->uv_width) { - vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR, - "Incorrect buffer dimensions"); - } else { - /* Find an empty frame buffer. */ - free_fb = get_free_fb(cm); - /* Decrease fb_idx_ref_cnt since it will be increased again in - * ref_cnt_fb() below. */ - cm->fb_idx_ref_cnt[free_fb]--; - - /* Manage the reference counters and copy image. */ - ref_cnt_fb(cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb); - vp8_yv12_copy_frame(sd, &cm->yv12_fb[*ref_fb_ptr]); - } - - return pbi->common.error.error_code; -} - -static int get_free_fb(VP8_COMMON *cm) { - int i; - for (i = 0; i < NUM_YV12_BUFFERS; ++i) { - if (cm->fb_idx_ref_cnt[i] == 0) break; - } - - assert(i < NUM_YV12_BUFFERS); - cm->fb_idx_ref_cnt[i] = 1; - return i; -} - -static void ref_cnt_fb(int *buf, int *idx, int new_idx) { - if (buf[*idx] > 0) buf[*idx]--; - - *idx = new_idx; - - buf[new_idx]++; -} - -/* If any buffer copy / swapping is signalled it should be done here. */ -static int swap_frame_buffers(VP8_COMMON *cm) { - int err = 0; - - /* The alternate reference frame or golden frame can be updated - * using the new, last, or golden/alt ref frame. If it - * is updated using the newly decoded frame it is a refresh. - * An update using the last or golden/alt ref frame is a copy. - */ - if (cm->copy_buffer_to_arf) { - int new_fb = 0; - - if (cm->copy_buffer_to_arf == 1) { - new_fb = cm->lst_fb_idx; - } else if (cm->copy_buffer_to_arf == 2) { - new_fb = cm->gld_fb_idx; - } else { - err = -1; - } - - ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->alt_fb_idx, new_fb); - } - - if (cm->copy_buffer_to_gf) { - int new_fb = 0; - - if (cm->copy_buffer_to_gf == 1) { - new_fb = cm->lst_fb_idx; - } else if (cm->copy_buffer_to_gf == 2) { - new_fb = cm->alt_fb_idx; - } else { - err = -1; - } - - ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->gld_fb_idx, new_fb); - } - - if (cm->refresh_golden_frame) { - ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->gld_fb_idx, cm->new_fb_idx); - } - - if (cm->refresh_alt_ref_frame) { - ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->alt_fb_idx, cm->new_fb_idx); - } - - if (cm->refresh_last_frame) { - ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->lst_fb_idx, cm->new_fb_idx); - - cm->frame_to_show = &cm->yv12_fb[cm->lst_fb_idx]; - } else { - cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx]; - } - - cm->fb_idx_ref_cnt[cm->new_fb_idx]--; - - return err; -} - -static int check_fragments_for_errors(VP8D_COMP *pbi) { - if (!pbi->ec_active && pbi->fragments.count <= 1 && - pbi->fragments.sizes[0] == 0) { - VP8_COMMON *cm = &pbi->common; - - /* If error concealment is disabled we won't signal missing frames - * to the decoder. - */ - if (cm->fb_idx_ref_cnt[cm->lst_fb_idx] > 1) { - /* The last reference shares buffer with another reference - * buffer. Move it to its own buffer before setting it as - * corrupt, otherwise we will make multiple buffers corrupt. - */ - const int prev_idx = cm->lst_fb_idx; - cm->fb_idx_ref_cnt[prev_idx]--; - cm->lst_fb_idx = get_free_fb(cm); - vp8_yv12_copy_frame(&cm->yv12_fb[prev_idx], &cm->yv12_fb[cm->lst_fb_idx]); - } - /* This is used to signal that we are missing frames. - * We do not know if the missing frame(s) was supposed to update - * any of the reference buffers, but we act conservative and - * mark only the last buffer as corrupted. - */ - cm->yv12_fb[cm->lst_fb_idx].corrupted = 1; - - /* Signal that we have no frame to show. */ - cm->show_frame = 0; - - /* Nothing more to do. */ - return 0; - } - - return 1; -} - -int vp8dx_receive_compressed_data(VP8D_COMP *pbi) { - VP8_COMMON *cm = &pbi->common; - int retcode = -1; - - pbi->common.error.error_code = VPX_CODEC_OK; - - retcode = check_fragments_for_errors(pbi); - if (retcode <= 0) return retcode; - - cm->new_fb_idx = get_free_fb(cm); - - /* setup reference frames for vp8_decode_frame */ - pbi->dec_fb_ref[INTRA_FRAME] = &cm->yv12_fb[cm->new_fb_idx]; - pbi->dec_fb_ref[LAST_FRAME] = &cm->yv12_fb[cm->lst_fb_idx]; - pbi->dec_fb_ref[GOLDEN_FRAME] = &cm->yv12_fb[cm->gld_fb_idx]; - pbi->dec_fb_ref[ALTREF_FRAME] = &cm->yv12_fb[cm->alt_fb_idx]; - - retcode = vp8_decode_frame(pbi); - - if (retcode < 0) { - if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) { - cm->fb_idx_ref_cnt[cm->new_fb_idx]--; - } - - pbi->common.error.error_code = VPX_CODEC_ERROR; - // Propagate the error info. - if (pbi->mb.error_info.error_code != 0) { - pbi->common.error.error_code = pbi->mb.error_info.error_code; - memcpy(pbi->common.error.detail, pbi->mb.error_info.detail, - sizeof(pbi->mb.error_info.detail)); - } - goto decode_exit; - } - - if (swap_frame_buffers(cm)) { - pbi->common.error.error_code = VPX_CODEC_ERROR; - goto decode_exit; - } - - vpx_clear_system_state(); - - if (cm->show_frame) { - cm->current_video_frame++; - cm->show_frame_mi = cm->mi; - } - -#if CONFIG_ERROR_CONCEALMENT - /* swap the mode infos to storage for future error concealment */ - if (pbi->ec_enabled && pbi->common.prev_mi) { - MODE_INFO *tmp = pbi->common.prev_mi; - int row, col; - pbi->common.prev_mi = pbi->common.mi; - pbi->common.mi = tmp; - - /* Propagate the segment_ids to the next frame */ - for (row = 0; row < pbi->common.mb_rows; ++row) { - for (col = 0; col < pbi->common.mb_cols; ++col) { - const int i = row * pbi->common.mode_info_stride + col; - pbi->common.mi[i].mbmi.segment_id = - pbi->common.prev_mi[i].mbmi.segment_id; - } - } - } -#endif - - pbi->ready_for_new_data = 0; - -decode_exit: - vpx_clear_system_state(); - return retcode; -} -int vp8dx_get_raw_frame(VP8D_COMP *pbi, YV12_BUFFER_CONFIG *sd, - vp8_ppflags_t *flags) { - int ret = -1; - - if (pbi->ready_for_new_data == 1) return ret; - - /* ie no raw frame to show!!! */ - if (pbi->common.show_frame == 0) return ret; - - pbi->ready_for_new_data = 1; - -#if CONFIG_POSTPROC - ret = vp8_post_proc_frame(&pbi->common, sd, flags); -#else - (void)flags; - - if (pbi->common.frame_to_show) { - *sd = *pbi->common.frame_to_show; - sd->y_width = pbi->common.Width; - sd->y_height = pbi->common.Height; - sd->uv_height = pbi->common.Height / 2; - ret = 0; - } else { - ret = -1; - } - -#endif /*!CONFIG_POSTPROC*/ - vpx_clear_system_state(); - return ret; -} - -/* This function as written isn't decoder specific, but the encoder has - * much faster ways of computing this, so it's ok for it to live in a - * decode specific file. - */ -int vp8dx_references_buffer(VP8_COMMON *oci, int ref_frame) { - const MODE_INFO *mi = oci->mi; - int mb_row, mb_col; - - for (mb_row = 0; mb_row < oci->mb_rows; ++mb_row) { - for (mb_col = 0; mb_col < oci->mb_cols; mb_col++, mi++) { - if (mi->mbmi.ref_frame == ref_frame) return 1; - } - mi++; - } - return 0; -} - -int vp8_create_decoder_instances(struct frame_buffers *fb, VP8D_CONFIG *oxcf) { - /* decoder instance for single thread mode */ - fb->pbi[0] = create_decompressor(oxcf); - if (!fb->pbi[0]) return VPX_CODEC_ERROR; - -#if CONFIG_MULTITHREAD - if (setjmp(fb->pbi[0]->common.error.jmp)) { - fb->pbi[0]->common.error.setjmp = 0; - vp8_remove_decoder_instances(fb); - vp8_zero(fb->pbi); - vpx_clear_system_state(); - return VPX_CODEC_ERROR; - } - - fb->pbi[0]->common.error.setjmp = 1; - fb->pbi[0]->max_threads = oxcf->max_threads; - vp8_decoder_create_threads(fb->pbi[0]); - fb->pbi[0]->common.error.setjmp = 0; -#endif - return VPX_CODEC_OK; -} - -int vp8_remove_decoder_instances(struct frame_buffers *fb) { - VP8D_COMP *pbi = fb->pbi[0]; - - if (!pbi) return VPX_CODEC_ERROR; -#if CONFIG_MULTITHREAD - vp8_decoder_remove_threads(pbi); -#endif - - /* decoder instance for single thread mode */ - remove_decompressor(pbi); - fb->pbi[0] = NULL; - return VPX_CODEC_OK; -} - -int vp8dx_get_quantizer(const VP8D_COMP *pbi) { - return pbi->common.base_qindex; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/onyxd_int.h b/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/onyxd_int.h deleted file mode 100644 index 08a60b31..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/onyxd_int.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_DECODER_ONYXD_INT_H_ -#define VPX_VP8_DECODER_ONYXD_INT_H_ - -#include - -#include "vpx_config.h" -#include "vpx_util/vpx_pthread.h" -#include "vp8/common/onyxd.h" -#include "treereader.h" -#include "vp8/common/onyxc_int.h" -#include "vp8/common/threading.h" - -#if CONFIG_ERROR_CONCEALMENT -#include "ec_types.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - int ithread; - void *ptr1; - void *ptr2; -} DECODETHREAD_DATA; - -typedef struct { - MACROBLOCKD mbd; -} MB_ROW_DEC; - -typedef struct { - int enabled; - unsigned int count; - const unsigned char *ptrs[MAX_PARTITIONS]; - unsigned int sizes[MAX_PARTITIONS]; -} FRAGMENT_DATA; - -#define MAX_FB_MT_DEC 32 - -struct frame_buffers { - /* - * this struct will be populated with frame buffer management - * info in future commits. */ - - /* decoder instances */ - struct VP8D_COMP *pbi[MAX_FB_MT_DEC]; -}; - -typedef struct VP8D_COMP { - DECLARE_ALIGNED(16, MACROBLOCKD, mb); - - YV12_BUFFER_CONFIG *dec_fb_ref[NUM_YV12_BUFFERS]; - - DECLARE_ALIGNED(16, VP8_COMMON, common); - - /* the last partition will be used for the modes/mvs */ - vp8_reader mbc[MAX_PARTITIONS]; - - VP8D_CONFIG oxcf; - - FRAGMENT_DATA fragments; - -#if CONFIG_MULTITHREAD - /* variable for threading */ - - vpx_atomic_int b_multithreaded_rd; - int max_threads; - int current_mb_col_main; - unsigned int decoding_thread_count; - int allocated_decoding_thread_count; - - int mt_baseline_filter_level[MAX_MB_SEGMENTS]; - int sync_range; - /* Each row remembers its already decoded column. */ - vpx_atomic_int *mt_current_mb_col; - - unsigned char **mt_yabove_row; /* mb_rows x width */ - unsigned char **mt_uabove_row; - unsigned char **mt_vabove_row; - unsigned char **mt_yleft_col; /* mb_rows x 16 */ - unsigned char **mt_uleft_col; /* mb_rows x 8 */ - unsigned char **mt_vleft_col; /* mb_rows x 8 */ - - MB_ROW_DEC *mb_row_di; - DECODETHREAD_DATA *de_thread_data; - - pthread_t *h_decoding_thread; - vp8_sem_t *h_event_start_decoding; - vp8_sem_t h_event_end_decoding; -/* end of threading data */ -#endif - - int ready_for_new_data; - - vp8_prob prob_intra; - vp8_prob prob_last; - vp8_prob prob_gf; - vp8_prob prob_skip_false; - -#if CONFIG_ERROR_CONCEALMENT - MB_OVERLAP *overlaps; - /* the mb num from which modes and mvs (first partition) are corrupt */ - unsigned int mvs_corrupt_from_mb; -#endif - int ec_enabled; - int ec_active; - int decoded_key_frame; - int independent_partitions; - int frame_corrupt_residual; - - vpx_decrypt_cb decrypt_cb; - void *decrypt_state; -#if CONFIG_MULTITHREAD - // Restart threads on next frame if set to 1. - // This is set when error happens in multithreaded decoding and all threads - // are shut down. - int restart_threads; -#endif -} VP8D_COMP; - -void vp8cx_init_de_quantizer(VP8D_COMP *pbi); -void vp8_mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd); -int vp8_decode_frame(VP8D_COMP *pbi); - -int vp8_create_decoder_instances(struct frame_buffers *fb, VP8D_CONFIG *oxcf); -int vp8_remove_decoder_instances(struct frame_buffers *fb); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_DECODER_ONYXD_INT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/threading.c b/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/threading.c deleted file mode 100644 index d16284d1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/threading.c +++ /dev/null @@ -1,910 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "vp8_rtcd.h" -#if !defined(_WIN32) && CONFIG_OS_SUPPORT == 1 -#include -#endif -#include "onyxd_int.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_util/vpx_pthread.h" -#include "vp8/common/common.h" -#include "vp8/common/threading.h" -#include "vp8/common/loopfilter.h" -#include "vp8/common/extend.h" -#include "vpx_ports/vpx_timer.h" -#include "decoderthreading.h" -#include "detokenize.h" -#include "vp8/common/reconintra4x4.h" -#include "vp8/common/reconinter.h" -#include "vp8/common/reconintra.h" -#include "vp8/common/setupintrarecon.h" -#if CONFIG_ERROR_CONCEALMENT -#include "error_concealment.h" -#endif - -#define CALLOC_ARRAY(p, n) \ - CHECK_MEM_ERROR(&pbi->common.error, (p), vpx_calloc(sizeof(*(p)), (n))) -#define CALLOC_ARRAY_ALIGNED(p, n, algn) \ - do { \ - CHECK_MEM_ERROR(&pbi->common.error, (p), \ - vpx_memalign((algn), sizeof(*(p)) * (n))); \ - memset((p), 0, (n) * sizeof(*(p))); \ - } while (0) - -static void setup_decoding_thread_data(VP8D_COMP *pbi, MACROBLOCKD *xd, - MB_ROW_DEC *mbrd, int count) { - VP8_COMMON *const pc = &pbi->common; - int i; - - for (i = 0; i < count; ++i) { - MACROBLOCKD *mbd = &mbrd[i].mbd; - mbd->subpixel_predict = xd->subpixel_predict; - mbd->subpixel_predict8x4 = xd->subpixel_predict8x4; - mbd->subpixel_predict8x8 = xd->subpixel_predict8x8; - mbd->subpixel_predict16x16 = xd->subpixel_predict16x16; - - mbd->frame_type = pc->frame_type; - mbd->pre = xd->pre; - mbd->dst = xd->dst; - - mbd->segmentation_enabled = xd->segmentation_enabled; - mbd->mb_segment_abs_delta = xd->mb_segment_abs_delta; - memcpy(mbd->segment_feature_data, xd->segment_feature_data, - sizeof(xd->segment_feature_data)); - - /*signed char ref_lf_deltas[MAX_REF_LF_DELTAS];*/ - memcpy(mbd->ref_lf_deltas, xd->ref_lf_deltas, sizeof(xd->ref_lf_deltas)); - /*signed char mode_lf_deltas[MAX_MODE_LF_DELTAS];*/ - memcpy(mbd->mode_lf_deltas, xd->mode_lf_deltas, sizeof(xd->mode_lf_deltas)); - /*unsigned char mode_ref_lf_delta_enabled; - unsigned char mode_ref_lf_delta_update;*/ - mbd->mode_ref_lf_delta_enabled = xd->mode_ref_lf_delta_enabled; - mbd->mode_ref_lf_delta_update = xd->mode_ref_lf_delta_update; - - mbd->current_bc = &pbi->mbc[0]; - - memcpy(mbd->dequant_y1_dc, xd->dequant_y1_dc, sizeof(xd->dequant_y1_dc)); - memcpy(mbd->dequant_y1, xd->dequant_y1, sizeof(xd->dequant_y1)); - memcpy(mbd->dequant_y2, xd->dequant_y2, sizeof(xd->dequant_y2)); - memcpy(mbd->dequant_uv, xd->dequant_uv, sizeof(xd->dequant_uv)); - - mbd->fullpixel_mask = ~0; - - if (pc->full_pixel) mbd->fullpixel_mask = ~7; - } - - for (i = 0; i < pc->mb_rows; ++i) - vpx_atomic_store_release(&pbi->mt_current_mb_col[i], -1); -} - -static void mt_decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, - unsigned int mb_idx) { - MB_PREDICTION_MODE mode; - int i; -#if CONFIG_ERROR_CONCEALMENT - int corruption_detected = 0; -#else - (void)mb_idx; -#endif - - if (xd->mode_info_context->mbmi.mb_skip_coeff) { - vp8_reset_mb_tokens_context(xd); - } else if (!vp8dx_bool_error(xd->current_bc)) { - int eobtotal; - eobtotal = vp8_decode_mb_tokens(pbi, xd); - - /* Special case: Force the loopfilter to skip when eobtotal is zero */ - xd->mode_info_context->mbmi.mb_skip_coeff = (eobtotal == 0); - } - - mode = xd->mode_info_context->mbmi.mode; - - if (xd->segmentation_enabled) vp8_mb_init_dequantizer(pbi, xd); - -#if CONFIG_ERROR_CONCEALMENT - - if (pbi->ec_active) { - int throw_residual; - /* When we have independent partitions we can apply residual even - * though other partitions within the frame are corrupt. - */ - throw_residual = - (!pbi->independent_partitions && pbi->frame_corrupt_residual); - throw_residual = (throw_residual || vp8dx_bool_error(xd->current_bc)); - - if ((mb_idx >= pbi->mvs_corrupt_from_mb || throw_residual)) { - /* MB with corrupt residuals or corrupt mode/motion vectors. - * Better to use the predictor as reconstruction. - */ - pbi->frame_corrupt_residual = 1; - memset(xd->qcoeff, 0, sizeof(xd->qcoeff)); - - corruption_detected = 1; - - /* force idct to be skipped for B_PRED and use the - * prediction only for reconstruction - * */ - memset(xd->eobs, 0, 25); - } - } -#endif - - /* do prediction */ - if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) { - vp8_build_intra_predictors_mbuv_s( - xd, xd->recon_above[1], xd->recon_above[2], xd->recon_left[1], - xd->recon_left[2], xd->recon_left_stride[1], xd->dst.u_buffer, - xd->dst.v_buffer, xd->dst.uv_stride); - - if (mode != B_PRED) { - vp8_build_intra_predictors_mby_s( - xd, xd->recon_above[0], xd->recon_left[0], xd->recon_left_stride[0], - xd->dst.y_buffer, xd->dst.y_stride); - } else { - short *DQC = xd->dequant_y1; - int dst_stride = xd->dst.y_stride; - - /* clear out residual eob info */ - if (xd->mode_info_context->mbmi.mb_skip_coeff) memset(xd->eobs, 0, 25); - - intra_prediction_down_copy(xd, xd->recon_above[0] + 16); - - for (i = 0; i < 16; ++i) { - BLOCKD *b = &xd->block[i]; - unsigned char *dst = xd->dst.y_buffer + b->offset; - B_PREDICTION_MODE b_mode = xd->mode_info_context->bmi[i].as_mode; - unsigned char *Above; - unsigned char *yleft; - int left_stride; - unsigned char top_left; - - /*Caution: For some b_mode, it needs 8 pixels (4 above + 4 - * above-right).*/ - if (i < 4 && pbi->common.filter_level) { - Above = xd->recon_above[0] + b->offset; - } else { - Above = dst - dst_stride; - } - - if (i % 4 == 0 && pbi->common.filter_level) { - yleft = xd->recon_left[0] + i; - left_stride = 1; - } else { - yleft = dst - 1; - left_stride = dst_stride; - } - - if ((i == 4 || i == 8 || i == 12) && pbi->common.filter_level) { - top_left = *(xd->recon_left[0] + i - 1); - } else { - top_left = Above[-1]; - } - - vp8_intra4x4_predict(Above, yleft, left_stride, b_mode, dst, dst_stride, - top_left); - - if (xd->eobs[i]) { - if (xd->eobs[i] > 1) { - vp8_dequant_idct_add(b->qcoeff, DQC, dst, dst_stride); - } else { - vp8_dc_only_idct_add(b->qcoeff[0] * DQC[0], dst, dst_stride, dst, - dst_stride); - memset(b->qcoeff, 0, 2 * sizeof(b->qcoeff[0])); - } - } - } - } - } else { - vp8_build_inter_predictors_mb(xd); - } - -#if CONFIG_ERROR_CONCEALMENT - if (corruption_detected) { - return; - } -#endif - - if (!xd->mode_info_context->mbmi.mb_skip_coeff) { - /* dequantization and idct */ - if (mode != B_PRED) { - short *DQC = xd->dequant_y1; - - if (mode != SPLITMV) { - BLOCKD *b = &xd->block[24]; - - /* do 2nd order transform on the dc block */ - if (xd->eobs[24] > 1) { - vp8_dequantize_b(b, xd->dequant_y2); - - vp8_short_inv_walsh4x4(&b->dqcoeff[0], xd->qcoeff); - memset(b->qcoeff, 0, 16 * sizeof(b->qcoeff[0])); - } else { - b->dqcoeff[0] = b->qcoeff[0] * xd->dequant_y2[0]; - vp8_short_inv_walsh4x4_1(&b->dqcoeff[0], xd->qcoeff); - memset(b->qcoeff, 0, 2 * sizeof(b->qcoeff[0])); - } - - /* override the dc dequant constant in order to preserve the - * dc components - */ - DQC = xd->dequant_y1_dc; - } - - vp8_dequant_idct_add_y_block(xd->qcoeff, DQC, xd->dst.y_buffer, - xd->dst.y_stride, xd->eobs); - } - - vp8_dequant_idct_add_uv_block(xd->qcoeff + 16 * 16, xd->dequant_uv, - xd->dst.u_buffer, xd->dst.v_buffer, - xd->dst.uv_stride, xd->eobs + 16); - } -} - -static void mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd, - int start_mb_row) { - const vpx_atomic_int *last_row_current_mb_col; - vpx_atomic_int *current_mb_col; - int mb_row; - VP8_COMMON *pc = &pbi->common; - const int nsync = pbi->sync_range; - const vpx_atomic_int first_row_no_sync_above = - VPX_ATOMIC_INIT(pc->mb_cols + nsync); - int num_part = 1 << pbi->common.multi_token_partition; - int last_mb_row = start_mb_row; - - YV12_BUFFER_CONFIG *yv12_fb_new = pbi->dec_fb_ref[INTRA_FRAME]; - YV12_BUFFER_CONFIG *yv12_fb_lst = pbi->dec_fb_ref[LAST_FRAME]; - - int recon_y_stride = yv12_fb_new->y_stride; - int recon_uv_stride = yv12_fb_new->uv_stride; - - unsigned char *ref_buffer[MAX_REF_FRAMES][3]; - unsigned char *dst_buffer[3]; - int i; - int ref_fb_corrupted[MAX_REF_FRAMES]; - - ref_fb_corrupted[INTRA_FRAME] = 0; - - for (i = 1; i < MAX_REF_FRAMES; ++i) { - YV12_BUFFER_CONFIG *this_fb = pbi->dec_fb_ref[i]; - - ref_buffer[i][0] = this_fb->y_buffer; - ref_buffer[i][1] = this_fb->u_buffer; - ref_buffer[i][2] = this_fb->v_buffer; - - ref_fb_corrupted[i] = this_fb->corrupted; - } - - dst_buffer[0] = yv12_fb_new->y_buffer; - dst_buffer[1] = yv12_fb_new->u_buffer; - dst_buffer[2] = yv12_fb_new->v_buffer; - - xd->up_available = (start_mb_row != 0); - - xd->mode_info_context = pc->mi + pc->mode_info_stride * start_mb_row; - xd->mode_info_stride = pc->mode_info_stride; - - for (mb_row = start_mb_row; mb_row < pc->mb_rows; - mb_row += (pbi->decoding_thread_count + 1)) { - int recon_yoffset, recon_uvoffset; - int mb_col; - int filter_level; - loop_filter_info_n *lfi_n = &pc->lf_info; - - /* save last row processed by this thread */ - last_mb_row = mb_row; - /* select bool coder for current partition */ - xd->current_bc = &pbi->mbc[mb_row % num_part]; - - if (mb_row > 0) { - last_row_current_mb_col = &pbi->mt_current_mb_col[mb_row - 1]; - } else { - last_row_current_mb_col = &first_row_no_sync_above; - } - - current_mb_col = &pbi->mt_current_mb_col[mb_row]; - - recon_yoffset = mb_row * recon_y_stride * 16; - recon_uvoffset = mb_row * recon_uv_stride * 8; - - /* reset contexts */ - xd->above_context = pc->above_context; - memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)); - - xd->left_available = 0; - - xd->mb_to_top_edge = -((mb_row * 16) << 3); - xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3; - - if (pbi->common.filter_level) { - xd->recon_above[0] = pbi->mt_yabove_row[mb_row] + 0 * 16 + 32; - xd->recon_above[1] = pbi->mt_uabove_row[mb_row] + 0 * 8 + 16; - xd->recon_above[2] = pbi->mt_vabove_row[mb_row] + 0 * 8 + 16; - - xd->recon_left[0] = pbi->mt_yleft_col[mb_row]; - xd->recon_left[1] = pbi->mt_uleft_col[mb_row]; - xd->recon_left[2] = pbi->mt_vleft_col[mb_row]; - - /* TODO: move to outside row loop */ - xd->recon_left_stride[0] = 1; - xd->recon_left_stride[1] = 1; - } else { - xd->recon_above[0] = dst_buffer[0] + recon_yoffset; - xd->recon_above[1] = dst_buffer[1] + recon_uvoffset; - xd->recon_above[2] = dst_buffer[2] + recon_uvoffset; - - xd->recon_left[0] = xd->recon_above[0] - 1; - xd->recon_left[1] = xd->recon_above[1] - 1; - xd->recon_left[2] = xd->recon_above[2] - 1; - - xd->recon_above[0] -= xd->dst.y_stride; - xd->recon_above[1] -= xd->dst.uv_stride; - xd->recon_above[2] -= xd->dst.uv_stride; - - /* TODO: move to outside row loop */ - xd->recon_left_stride[0] = xd->dst.y_stride; - xd->recon_left_stride[1] = xd->dst.uv_stride; - - setup_intra_recon_left(xd->recon_left[0], xd->recon_left[1], - xd->recon_left[2], xd->dst.y_stride, - xd->dst.uv_stride); - } - - for (mb_col = 0; mb_col < pc->mb_cols; ++mb_col) { - if (((mb_col - 1) % nsync) == 0) { - vpx_atomic_store_release(current_mb_col, mb_col - 1); - } - - if (mb_row && !(mb_col & (nsync - 1))) { - vp8_atomic_spin_wait(mb_col, last_row_current_mb_col, nsync); - } - - /* Distance of MB to the various image edges. - * These are specified to 8th pel as they are always - * compared to values that are in 1/8th pel units. - */ - xd->mb_to_left_edge = -((mb_col * 16) << 3); - xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3; - -#if CONFIG_ERROR_CONCEALMENT - { - int corrupt_residual = - (!pbi->independent_partitions && pbi->frame_corrupt_residual) || - vp8dx_bool_error(xd->current_bc); - if (pbi->ec_active && - (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) && - corrupt_residual) { - /* We have an intra block with corrupt - * coefficients, better to conceal with an inter - * block. - * Interpolate MVs from neighboring MBs - * - * Note that for the first mb with corrupt - * residual in a frame, we might not discover - * that before decoding the residual. That - * happens after this check, and therefore no - * inter concealment will be done. - */ - vp8_interpolate_motion(xd, mb_row, mb_col, pc->mb_rows, pc->mb_cols); - } - } -#endif - - xd->dst.y_buffer = dst_buffer[0] + recon_yoffset; - xd->dst.u_buffer = dst_buffer[1] + recon_uvoffset; - xd->dst.v_buffer = dst_buffer[2] + recon_uvoffset; - - /* propagate errors from reference frames */ - xd->corrupted |= ref_fb_corrupted[xd->mode_info_context->mbmi.ref_frame]; - - if (xd->corrupted) { - // Move current decoding marcoblock to the end of row for all rows - // assigned to this thread, such that other threads won't be waiting. - for (; mb_row < pc->mb_rows; - mb_row += (pbi->decoding_thread_count + 1)) { - current_mb_col = &pbi->mt_current_mb_col[mb_row]; - vpx_atomic_store_release(current_mb_col, pc->mb_cols + nsync); - } - vpx_internal_error(&xd->error_info, VPX_CODEC_CORRUPT_FRAME, - "Corrupted reference frame"); - } - - if (xd->mode_info_context->mbmi.ref_frame >= LAST_FRAME) { - const MV_REFERENCE_FRAME ref = xd->mode_info_context->mbmi.ref_frame; - xd->pre.y_buffer = ref_buffer[ref][0] + recon_yoffset; - xd->pre.u_buffer = ref_buffer[ref][1] + recon_uvoffset; - xd->pre.v_buffer = ref_buffer[ref][2] + recon_uvoffset; - } else { - // ref_frame is INTRA_FRAME, pre buffer should not be used. - xd->pre.y_buffer = 0; - xd->pre.u_buffer = 0; - xd->pre.v_buffer = 0; - } - mt_decode_macroblock(pbi, xd, 0); - - xd->left_available = 1; - - /* check if the boolean decoder has suffered an error */ - xd->corrupted |= vp8dx_bool_error(xd->current_bc); - - xd->recon_above[0] += 16; - xd->recon_above[1] += 8; - xd->recon_above[2] += 8; - - if (!pbi->common.filter_level) { - xd->recon_left[0] += 16; - xd->recon_left[1] += 8; - xd->recon_left[2] += 8; - } - - if (pbi->common.filter_level) { - int skip_lf = (xd->mode_info_context->mbmi.mode != B_PRED && - xd->mode_info_context->mbmi.mode != SPLITMV && - xd->mode_info_context->mbmi.mb_skip_coeff); - - const int mode_index = - lfi_n->mode_lf_lut[xd->mode_info_context->mbmi.mode]; - const int seg = xd->mode_info_context->mbmi.segment_id; - const int ref_frame = xd->mode_info_context->mbmi.ref_frame; - - filter_level = lfi_n->lvl[seg][ref_frame][mode_index]; - - if (mb_row != pc->mb_rows - 1) { - /* Save decoded MB last row data for next-row decoding */ - memcpy((pbi->mt_yabove_row[mb_row + 1] + 32 + mb_col * 16), - (xd->dst.y_buffer + 15 * recon_y_stride), 16); - memcpy((pbi->mt_uabove_row[mb_row + 1] + 16 + mb_col * 8), - (xd->dst.u_buffer + 7 * recon_uv_stride), 8); - memcpy((pbi->mt_vabove_row[mb_row + 1] + 16 + mb_col * 8), - (xd->dst.v_buffer + 7 * recon_uv_stride), 8); - } - - /* save left_col for next MB decoding */ - if (mb_col != pc->mb_cols - 1) { - MODE_INFO *next = xd->mode_info_context + 1; - - if (next->mbmi.ref_frame == INTRA_FRAME) { - for (i = 0; i < 16; ++i) { - pbi->mt_yleft_col[mb_row][i] = - xd->dst.y_buffer[i * recon_y_stride + 15]; - } - for (i = 0; i < 8; ++i) { - pbi->mt_uleft_col[mb_row][i] = - xd->dst.u_buffer[i * recon_uv_stride + 7]; - pbi->mt_vleft_col[mb_row][i] = - xd->dst.v_buffer[i * recon_uv_stride + 7]; - } - } - } - - /* loopfilter on this macroblock. */ - if (filter_level) { - if (pc->filter_type == NORMAL_LOOPFILTER) { - loop_filter_info lfi; - FRAME_TYPE frame_type = pc->frame_type; - const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level]; - lfi.mblim = lfi_n->mblim[filter_level]; - lfi.blim = lfi_n->blim[filter_level]; - lfi.lim = lfi_n->lim[filter_level]; - lfi.hev_thr = lfi_n->hev_thr[hev_index]; - - if (mb_col > 0) - vp8_loop_filter_mbv(xd->dst.y_buffer, xd->dst.u_buffer, - xd->dst.v_buffer, recon_y_stride, - recon_uv_stride, &lfi); - - if (!skip_lf) - vp8_loop_filter_bv(xd->dst.y_buffer, xd->dst.u_buffer, - xd->dst.v_buffer, recon_y_stride, - recon_uv_stride, &lfi); - - /* don't apply across umv border */ - if (mb_row > 0) - vp8_loop_filter_mbh(xd->dst.y_buffer, xd->dst.u_buffer, - xd->dst.v_buffer, recon_y_stride, - recon_uv_stride, &lfi); - - if (!skip_lf) - vp8_loop_filter_bh(xd->dst.y_buffer, xd->dst.u_buffer, - xd->dst.v_buffer, recon_y_stride, - recon_uv_stride, &lfi); - } else { - if (mb_col > 0) - vp8_loop_filter_simple_mbv(xd->dst.y_buffer, recon_y_stride, - lfi_n->mblim[filter_level]); - - if (!skip_lf) - vp8_loop_filter_simple_bv(xd->dst.y_buffer, recon_y_stride, - lfi_n->blim[filter_level]); - - /* don't apply across umv border */ - if (mb_row > 0) - vp8_loop_filter_simple_mbh(xd->dst.y_buffer, recon_y_stride, - lfi_n->mblim[filter_level]); - - if (!skip_lf) - vp8_loop_filter_simple_bh(xd->dst.y_buffer, recon_y_stride, - lfi_n->blim[filter_level]); - } - } - } - - recon_yoffset += 16; - recon_uvoffset += 8; - - ++xd->mode_info_context; /* next mb */ - - xd->above_context++; - } - - /* adjust to the next row of mbs */ - if (pbi->common.filter_level) { - if (mb_row != pc->mb_rows - 1) { - int lasty = yv12_fb_lst->y_width + VP8BORDERINPIXELS; - int lastuv = (yv12_fb_lst->y_width >> 1) + (VP8BORDERINPIXELS >> 1); - - for (i = 0; i < 4; ++i) { - pbi->mt_yabove_row[mb_row + 1][lasty + i] = - pbi->mt_yabove_row[mb_row + 1][lasty - 1]; - pbi->mt_uabove_row[mb_row + 1][lastuv + i] = - pbi->mt_uabove_row[mb_row + 1][lastuv - 1]; - pbi->mt_vabove_row[mb_row + 1][lastuv + i] = - pbi->mt_vabove_row[mb_row + 1][lastuv - 1]; - } - } - } else { - vp8_extend_mb_row(yv12_fb_new, xd->dst.y_buffer + 16, - xd->dst.u_buffer + 8, xd->dst.v_buffer + 8); - } - - /* last MB of row is ready just after extension is done */ - vpx_atomic_store_release(current_mb_col, mb_col + nsync); - - ++xd->mode_info_context; /* skip prediction column */ - xd->up_available = 1; - - /* since we have multithread */ - xd->mode_info_context += xd->mode_info_stride * pbi->decoding_thread_count; - } - - /* signal end of decoding of current thread for current frame */ - if (last_mb_row + (int)pbi->decoding_thread_count + 1 >= pc->mb_rows) - vp8_sem_post(&pbi->h_event_end_decoding); -} - -static THREADFN thread_decoding_proc(void *p_data) { - int ithread = ((DECODETHREAD_DATA *)p_data)->ithread; - VP8D_COMP *pbi = (VP8D_COMP *)(((DECODETHREAD_DATA *)p_data)->ptr1); - MB_ROW_DEC *mbrd = (MB_ROW_DEC *)(((DECODETHREAD_DATA *)p_data)->ptr2); - ENTROPY_CONTEXT_PLANES mb_row_left_context; - - while (1) { - if (vpx_atomic_load_acquire(&pbi->b_multithreaded_rd) == 0) break; - - if (vp8_sem_wait(&pbi->h_event_start_decoding[ithread]) == 0) { - if (vpx_atomic_load_acquire(&pbi->b_multithreaded_rd) == 0) { - break; - } else { - MACROBLOCKD *xd = &mbrd->mbd; - xd->left_context = &mb_row_left_context; - if (setjmp(xd->error_info.jmp)) { - xd->error_info.setjmp = 0; - // Signal the end of decoding for current thread. - vp8_sem_post(&pbi->h_event_end_decoding); - continue; - } - xd->error_info.setjmp = 1; - mt_decode_mb_rows(pbi, xd, ithread + 1); - xd->error_info.setjmp = 0; - } - } - } - - return THREAD_EXIT_SUCCESS; -} - -void vp8_decoder_create_threads(VP8D_COMP *pbi) { - int core_count = 0; - unsigned int ithread; - - vpx_atomic_init(&pbi->b_multithreaded_rd, 0); - pbi->allocated_decoding_thread_count = 0; - - /* limit decoding threads to the max number of token partitions */ - core_count = (pbi->max_threads > 8) ? 8 : pbi->max_threads; - - /* limit decoding threads to the available cores */ - if (core_count > pbi->common.processor_core_count) { - core_count = pbi->common.processor_core_count; - } - - if (core_count > 1) { - vpx_atomic_init(&pbi->b_multithreaded_rd, 1); - pbi->decoding_thread_count = core_count - 1; - - CALLOC_ARRAY(pbi->h_decoding_thread, pbi->decoding_thread_count); - CALLOC_ARRAY(pbi->h_event_start_decoding, pbi->decoding_thread_count); - CALLOC_ARRAY_ALIGNED(pbi->mb_row_di, pbi->decoding_thread_count, 32); - CALLOC_ARRAY(pbi->de_thread_data, pbi->decoding_thread_count); - - if (vp8_sem_init(&pbi->h_event_end_decoding, 0, 0)) { - vpx_internal_error(&pbi->common.error, VPX_CODEC_MEM_ERROR, - "Failed to initialize semaphore"); - } - - for (ithread = 0; ithread < pbi->decoding_thread_count; ++ithread) { - if (vp8_sem_init(&pbi->h_event_start_decoding[ithread], 0, 0)) break; - - vp8_setup_block_dptrs(&pbi->mb_row_di[ithread].mbd); - - pbi->de_thread_data[ithread].ithread = ithread; - pbi->de_thread_data[ithread].ptr1 = (void *)pbi; - pbi->de_thread_data[ithread].ptr2 = (void *)&pbi->mb_row_di[ithread]; - - if (pthread_create(&pbi->h_decoding_thread[ithread], 0, - thread_decoding_proc, &pbi->de_thread_data[ithread])) { - vp8_sem_destroy(&pbi->h_event_start_decoding[ithread]); - break; - } - } - - pbi->allocated_decoding_thread_count = ithread; - if (pbi->allocated_decoding_thread_count != - (int)pbi->decoding_thread_count) { - /* the remainder of cleanup cases will be handled in - * vp8_decoder_remove_threads(). */ - if (pbi->allocated_decoding_thread_count == 0) { - vp8_sem_destroy(&pbi->h_event_end_decoding); - } - vpx_internal_error(&pbi->common.error, VPX_CODEC_MEM_ERROR, - "Failed to create threads"); - } - } -} - -void vp8mt_de_alloc_temp_buffers(VP8D_COMP *pbi, int mb_rows) { - int i; - - vpx_free(pbi->mt_current_mb_col); - pbi->mt_current_mb_col = NULL; - - /* Free above_row buffers. */ - if (pbi->mt_yabove_row) { - for (i = 0; i < mb_rows; ++i) { - vpx_free(pbi->mt_yabove_row[i]); - pbi->mt_yabove_row[i] = NULL; - } - vpx_free(pbi->mt_yabove_row); - pbi->mt_yabove_row = NULL; - } - - if (pbi->mt_uabove_row) { - for (i = 0; i < mb_rows; ++i) { - vpx_free(pbi->mt_uabove_row[i]); - pbi->mt_uabove_row[i] = NULL; - } - vpx_free(pbi->mt_uabove_row); - pbi->mt_uabove_row = NULL; - } - - if (pbi->mt_vabove_row) { - for (i = 0; i < mb_rows; ++i) { - vpx_free(pbi->mt_vabove_row[i]); - pbi->mt_vabove_row[i] = NULL; - } - vpx_free(pbi->mt_vabove_row); - pbi->mt_vabove_row = NULL; - } - - /* Free left_col buffers. */ - if (pbi->mt_yleft_col) { - for (i = 0; i < mb_rows; ++i) { - vpx_free(pbi->mt_yleft_col[i]); - pbi->mt_yleft_col[i] = NULL; - } - vpx_free(pbi->mt_yleft_col); - pbi->mt_yleft_col = NULL; - } - - if (pbi->mt_uleft_col) { - for (i = 0; i < mb_rows; ++i) { - vpx_free(pbi->mt_uleft_col[i]); - pbi->mt_uleft_col[i] = NULL; - } - vpx_free(pbi->mt_uleft_col); - pbi->mt_uleft_col = NULL; - } - - if (pbi->mt_vleft_col) { - for (i = 0; i < mb_rows; ++i) { - vpx_free(pbi->mt_vleft_col[i]); - pbi->mt_vleft_col[i] = NULL; - } - vpx_free(pbi->mt_vleft_col); - pbi->mt_vleft_col = NULL; - } -} - -void vp8mt_alloc_temp_buffers(VP8D_COMP *pbi, int width, int prev_mb_rows) { - VP8_COMMON *const pc = &pbi->common; - int i; - int uv_width; - - if (vpx_atomic_load_acquire(&pbi->b_multithreaded_rd)) { - vp8mt_de_alloc_temp_buffers(pbi, prev_mb_rows); - - /* our internal buffers are always multiples of 16 */ - if ((width & 0xf) != 0) width += 16 - (width & 0xf); - - if (width < 640) { - pbi->sync_range = 1; - } else if (width <= 1280) { - pbi->sync_range = 8; - } else if (width <= 2560) { - pbi->sync_range = 16; - } else { - pbi->sync_range = 32; - } - - uv_width = width >> 1; - - /* Allocate a vpx_atomic_int for each mb row. */ - CHECK_MEM_ERROR(&pc->error, pbi->mt_current_mb_col, - vpx_malloc(sizeof(*pbi->mt_current_mb_col) * pc->mb_rows)); - for (i = 0; i < pc->mb_rows; ++i) - vpx_atomic_init(&pbi->mt_current_mb_col[i], 0); - - /* Allocate memory for above_row buffers. */ - CALLOC_ARRAY(pbi->mt_yabove_row, pc->mb_rows); - for (i = 0; i < pc->mb_rows; ++i) { - CHECK_MEM_ERROR(&pc->error, pbi->mt_yabove_row[i], - vpx_memalign(16, sizeof(unsigned char) * - (width + (VP8BORDERINPIXELS << 1)))); - vp8_zero_array(pbi->mt_yabove_row[i], width + (VP8BORDERINPIXELS << 1)); - } - - CALLOC_ARRAY(pbi->mt_uabove_row, pc->mb_rows); - for (i = 0; i < pc->mb_rows; ++i) { - CHECK_MEM_ERROR(&pc->error, pbi->mt_uabove_row[i], - vpx_memalign(16, sizeof(unsigned char) * - (uv_width + VP8BORDERINPIXELS))); - vp8_zero_array(pbi->mt_uabove_row[i], uv_width + VP8BORDERINPIXELS); - } - - CALLOC_ARRAY(pbi->mt_vabove_row, pc->mb_rows); - for (i = 0; i < pc->mb_rows; ++i) { - CHECK_MEM_ERROR(&pc->error, pbi->mt_vabove_row[i], - vpx_memalign(16, sizeof(unsigned char) * - (uv_width + VP8BORDERINPIXELS))); - vp8_zero_array(pbi->mt_vabove_row[i], uv_width + VP8BORDERINPIXELS); - } - - /* Allocate memory for left_col buffers. */ - CALLOC_ARRAY(pbi->mt_yleft_col, pc->mb_rows); - for (i = 0; i < pc->mb_rows; ++i) - CHECK_MEM_ERROR(&pc->error, pbi->mt_yleft_col[i], - vpx_calloc(sizeof(unsigned char) * 16, 1)); - - CALLOC_ARRAY(pbi->mt_uleft_col, pc->mb_rows); - for (i = 0; i < pc->mb_rows; ++i) - CHECK_MEM_ERROR(&pc->error, pbi->mt_uleft_col[i], - vpx_calloc(sizeof(unsigned char) * 8, 1)); - - CALLOC_ARRAY(pbi->mt_vleft_col, pc->mb_rows); - for (i = 0; i < pc->mb_rows; ++i) - CHECK_MEM_ERROR(&pc->error, pbi->mt_vleft_col[i], - vpx_calloc(sizeof(unsigned char) * 8, 1)); - } -} - -void vp8_decoder_remove_threads(VP8D_COMP *pbi) { - /* shutdown MB Decoding thread; */ - if (vpx_atomic_load_acquire(&pbi->b_multithreaded_rd)) { - int i; - vpx_atomic_store_release(&pbi->b_multithreaded_rd, 0); - - /* allow all threads to exit */ - for (i = 0; i < pbi->allocated_decoding_thread_count; ++i) { - vp8_sem_post(&pbi->h_event_start_decoding[i]); - pthread_join(pbi->h_decoding_thread[i], NULL); - } - - for (i = 0; i < pbi->allocated_decoding_thread_count; ++i) { - vp8_sem_destroy(&pbi->h_event_start_decoding[i]); - } - - if (pbi->allocated_decoding_thread_count) { - vp8_sem_destroy(&pbi->h_event_end_decoding); - } - - vpx_free(pbi->h_decoding_thread); - pbi->h_decoding_thread = NULL; - - vpx_free(pbi->h_event_start_decoding); - pbi->h_event_start_decoding = NULL; - - vpx_free(pbi->mb_row_di); - pbi->mb_row_di = NULL; - - vpx_free(pbi->de_thread_data); - pbi->de_thread_data = NULL; - - vp8mt_de_alloc_temp_buffers(pbi, pbi->common.mb_rows); - } -} - -int vp8mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd) { - VP8_COMMON *pc = &pbi->common; - unsigned int i; - int j; - - int filter_level = pc->filter_level; - YV12_BUFFER_CONFIG *yv12_fb_new = pbi->dec_fb_ref[INTRA_FRAME]; - - if (filter_level) { - /* Set above_row buffer to 127 for decoding first MB row */ - memset(pbi->mt_yabove_row[0] + VP8BORDERINPIXELS - 1, 127, - yv12_fb_new->y_width + 5); - memset(pbi->mt_uabove_row[0] + (VP8BORDERINPIXELS >> 1) - 1, 127, - (yv12_fb_new->y_width >> 1) + 5); - memset(pbi->mt_vabove_row[0] + (VP8BORDERINPIXELS >> 1) - 1, 127, - (yv12_fb_new->y_width >> 1) + 5); - - for (j = 1; j < pc->mb_rows; ++j) { - memset(pbi->mt_yabove_row[j] + VP8BORDERINPIXELS - 1, (unsigned char)129, - 1); - memset(pbi->mt_uabove_row[j] + (VP8BORDERINPIXELS >> 1) - 1, - (unsigned char)129, 1); - memset(pbi->mt_vabove_row[j] + (VP8BORDERINPIXELS >> 1) - 1, - (unsigned char)129, 1); - } - - /* Set left_col to 129 initially */ - for (j = 0; j < pc->mb_rows; ++j) { - memset(pbi->mt_yleft_col[j], (unsigned char)129, 16); - memset(pbi->mt_uleft_col[j], (unsigned char)129, 8); - memset(pbi->mt_vleft_col[j], (unsigned char)129, 8); - } - - /* Initialize the loop filter for this frame. */ - vp8_loop_filter_frame_init(pc, &pbi->mb, filter_level); - } else { - vp8_setup_intra_recon_top_line(yv12_fb_new); - } - - setup_decoding_thread_data(pbi, xd, pbi->mb_row_di, - pbi->decoding_thread_count); - - for (i = 0; i < pbi->decoding_thread_count; ++i) { - vp8_sem_post(&pbi->h_event_start_decoding[i]); - } - - if (setjmp(xd->error_info.jmp)) { - xd->error_info.setjmp = 0; - xd->corrupted = 1; - // Wait for other threads to finish. This prevents other threads decoding - // the current frame while the main thread starts decoding the next frame, - // which causes a data race. - for (i = 0; i < pbi->decoding_thread_count; ++i) - vp8_sem_wait(&pbi->h_event_end_decoding); - return -1; - } - - xd->error_info.setjmp = 1; - mt_decode_mb_rows(pbi, xd, 0); - xd->error_info.setjmp = 0; - - for (i = 0; i < pbi->decoding_thread_count + 1; ++i) - vp8_sem_wait(&pbi->h_event_end_decoding); /* add back for each frame */ - - return 0; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/treereader.h b/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/treereader.h deleted file mode 100644 index 4bf938a7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/decoder/treereader.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_DECODER_TREEREADER_H_ -#define VPX_VP8_DECODER_TREEREADER_H_ - -#include "./vpx_config.h" -#include "vp8/common/treecoder.h" -#include "dboolhuff.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef BOOL_DECODER vp8_reader; - -#define vp8_read vp8dx_decode_bool -#define vp8_read_literal vp8_decode_value -#define vp8_read_bit(R) vp8_read(R, vp8_prob_half) - -/* Intent of tree data structure is to make decoding trivial. */ - -static INLINE int vp8_treed_read( - vp8_reader *const r, /* !!! must return a 0 or 1 !!! */ - vp8_tree t, const vp8_prob *const p) { - vp8_tree_index i = 0; - - while ((i = t[i + vp8_read(r, p[i >> 1])]) > 0) { - } - - return -i; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_DECODER_TREEREADER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/arm/neon/denoising_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/arm/neon/denoising_neon.c deleted file mode 100644 index 67267b8f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/arm/neon/denoising_neon.c +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "vp8/encoder/denoising.h" -#include "vpx_mem/vpx_mem.h" -#include "./vp8_rtcd.h" - -/* - * The filter function was modified to reduce the computational complexity. - * - * Step 1: - * Instead of applying tap coefficients for each pixel, we calculated the - * pixel adjustments vs. pixel diff value ahead of time. - * adjustment = filtered_value - current_raw - * = (filter_coefficient * diff + 128) >> 8 - * where - * filter_coefficient = (255 << 8) / (256 + ((abs_diff * 330) >> 3)); - * filter_coefficient += filter_coefficient / - * (3 + motion_magnitude_adjustment); - * filter_coefficient is clamped to 0 ~ 255. - * - * Step 2: - * The adjustment vs. diff curve becomes flat very quick when diff increases. - * This allowed us to use only several levels to approximate the curve without - * changing the filtering algorithm too much. - * The adjustments were further corrected by checking the motion magnitude. - * The levels used are: - * diff level adjustment w/o adjustment w/ - * motion correction motion correction - * [-255, -16] 3 -6 -7 - * [-15, -8] 2 -4 -5 - * [-7, -4] 1 -3 -4 - * [-3, 3] 0 diff diff - * [4, 7] 1 3 4 - * [8, 15] 2 4 5 - * [16, 255] 3 6 7 - */ - -int vp8_denoiser_filter_neon(unsigned char *mc_running_avg_y, - int mc_running_avg_y_stride, - unsigned char *running_avg_y, - int running_avg_y_stride, unsigned char *sig, - int sig_stride, unsigned int motion_magnitude, - int increase_denoising) { - /* If motion_magnitude is small, making the denoiser more aggressive by - * increasing the adjustment for each level, level1 adjustment is - * increased, the deltas stay the same. - */ - int shift_inc = - (increase_denoising && motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) - ? 1 - : 0; - const uint8x16_t v_level1_adjustment = vmovq_n_u8( - (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) ? 4 + shift_inc : 3); - const uint8x16_t v_delta_level_1_and_2 = vdupq_n_u8(1); - const uint8x16_t v_delta_level_2_and_3 = vdupq_n_u8(2); - const uint8x16_t v_level1_threshold = vmovq_n_u8(4 + shift_inc); - const uint8x16_t v_level2_threshold = vdupq_n_u8(8); - const uint8x16_t v_level3_threshold = vdupq_n_u8(16); - int64x2_t v_sum_diff_total = vdupq_n_s64(0); - - /* Go over lines. */ - int r; - for (r = 0; r < 16; ++r) { - /* Load inputs. */ - const uint8x16_t v_sig = vld1q_u8(sig); - const uint8x16_t v_mc_running_avg_y = vld1q_u8(mc_running_avg_y); - - /* Calculate absolute difference and sign masks. */ - const uint8x16_t v_abs_diff = vabdq_u8(v_sig, v_mc_running_avg_y); - const uint8x16_t v_diff_pos_mask = vcltq_u8(v_sig, v_mc_running_avg_y); - const uint8x16_t v_diff_neg_mask = vcgtq_u8(v_sig, v_mc_running_avg_y); - - /* Figure out which level that put us in. */ - const uint8x16_t v_level1_mask = vcleq_u8(v_level1_threshold, v_abs_diff); - const uint8x16_t v_level2_mask = vcleq_u8(v_level2_threshold, v_abs_diff); - const uint8x16_t v_level3_mask = vcleq_u8(v_level3_threshold, v_abs_diff); - - /* Calculate absolute adjustments for level 1, 2 and 3. */ - const uint8x16_t v_level2_adjustment = - vandq_u8(v_level2_mask, v_delta_level_1_and_2); - const uint8x16_t v_level3_adjustment = - vandq_u8(v_level3_mask, v_delta_level_2_and_3); - const uint8x16_t v_level1and2_adjustment = - vaddq_u8(v_level1_adjustment, v_level2_adjustment); - const uint8x16_t v_level1and2and3_adjustment = - vaddq_u8(v_level1and2_adjustment, v_level3_adjustment); - - /* Figure adjustment absolute value by selecting between the absolute - * difference if in level0 or the value for level 1, 2 and 3. - */ - const uint8x16_t v_abs_adjustment = - vbslq_u8(v_level1_mask, v_level1and2and3_adjustment, v_abs_diff); - - /* Calculate positive and negative adjustments. Apply them to the signal - * and accumulate them. Adjustments are less than eight and the maximum - * sum of them (7 * 16) can fit in a signed char. - */ - const uint8x16_t v_pos_adjustment = - vandq_u8(v_diff_pos_mask, v_abs_adjustment); - const uint8x16_t v_neg_adjustment = - vandq_u8(v_diff_neg_mask, v_abs_adjustment); - - uint8x16_t v_running_avg_y = vqaddq_u8(v_sig, v_pos_adjustment); - v_running_avg_y = vqsubq_u8(v_running_avg_y, v_neg_adjustment); - - /* Store results. */ - vst1q_u8(running_avg_y, v_running_avg_y); - - /* Sum all the accumulators to have the sum of all pixel differences - * for this macroblock. - */ - { - const int8x16_t v_sum_diff = - vqsubq_s8(vreinterpretq_s8_u8(v_pos_adjustment), - vreinterpretq_s8_u8(v_neg_adjustment)); - - const int16x8_t fe_dc_ba_98_76_54_32_10 = vpaddlq_s8(v_sum_diff); - - const int32x4_t fedc_ba98_7654_3210 = - vpaddlq_s16(fe_dc_ba_98_76_54_32_10); - - const int64x2_t fedcba98_76543210 = vpaddlq_s32(fedc_ba98_7654_3210); - - v_sum_diff_total = vqaddq_s64(v_sum_diff_total, fedcba98_76543210); - } - - /* Update pointers for next iteration. */ - sig += sig_stride; - mc_running_avg_y += mc_running_avg_y_stride; - running_avg_y += running_avg_y_stride; - } - - /* Too much adjustments => copy block. */ - { - int64x1_t x = vqadd_s64(vget_high_s64(v_sum_diff_total), - vget_low_s64(v_sum_diff_total)); - int sum_diff = vget_lane_s32(vabs_s32(vreinterpret_s32_s64(x)), 0); - int sum_diff_thresh = SUM_DIFF_THRESHOLD; - - if (increase_denoising) sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH; - if (sum_diff > sum_diff_thresh) { - // Before returning to copy the block (i.e., apply no denoising), - // checK if we can still apply some (weaker) temporal filtering to - // this block, that would otherwise not be denoised at all. Simplest - // is to apply an additional adjustment to running_avg_y to bring it - // closer to sig. The adjustment is capped by a maximum delta, and - // chosen such that in most cases the resulting sum_diff will be - // within the accceptable range given by sum_diff_thresh. - - // The delta is set by the excess of absolute pixel diff over the - // threshold. - int delta = ((sum_diff - sum_diff_thresh) >> 8) + 1; - // Only apply the adjustment for max delta up to 3. - if (delta < 4) { - const uint8x16_t k_delta = vmovq_n_u8(delta); - sig -= sig_stride * 16; - mc_running_avg_y -= mc_running_avg_y_stride * 16; - running_avg_y -= running_avg_y_stride * 16; - for (r = 0; r < 16; ++r) { - uint8x16_t v_running_avg_y = vld1q_u8(running_avg_y); - const uint8x16_t v_sig = vld1q_u8(sig); - const uint8x16_t v_mc_running_avg_y = vld1q_u8(mc_running_avg_y); - - /* Calculate absolute difference and sign masks. */ - const uint8x16_t v_abs_diff = vabdq_u8(v_sig, v_mc_running_avg_y); - const uint8x16_t v_diff_pos_mask = - vcltq_u8(v_sig, v_mc_running_avg_y); - const uint8x16_t v_diff_neg_mask = - vcgtq_u8(v_sig, v_mc_running_avg_y); - // Clamp absolute difference to delta to get the adjustment. - const uint8x16_t v_abs_adjustment = vminq_u8(v_abs_diff, (k_delta)); - - const uint8x16_t v_pos_adjustment = - vandq_u8(v_diff_pos_mask, v_abs_adjustment); - const uint8x16_t v_neg_adjustment = - vandq_u8(v_diff_neg_mask, v_abs_adjustment); - - v_running_avg_y = vqsubq_u8(v_running_avg_y, v_pos_adjustment); - v_running_avg_y = vqaddq_u8(v_running_avg_y, v_neg_adjustment); - - /* Store results. */ - vst1q_u8(running_avg_y, v_running_avg_y); - - { - const int8x16_t v_sum_diff = - vqsubq_s8(vreinterpretq_s8_u8(v_neg_adjustment), - vreinterpretq_s8_u8(v_pos_adjustment)); - - const int16x8_t fe_dc_ba_98_76_54_32_10 = vpaddlq_s8(v_sum_diff); - const int32x4_t fedc_ba98_7654_3210 = - vpaddlq_s16(fe_dc_ba_98_76_54_32_10); - const int64x2_t fedcba98_76543210 = - vpaddlq_s32(fedc_ba98_7654_3210); - - v_sum_diff_total = vqaddq_s64(v_sum_diff_total, fedcba98_76543210); - } - /* Update pointers for next iteration. */ - sig += sig_stride; - mc_running_avg_y += mc_running_avg_y_stride; - running_avg_y += running_avg_y_stride; - } - { - // Update the sum of all pixel differences of this MB. - x = vqadd_s64(vget_high_s64(v_sum_diff_total), - vget_low_s64(v_sum_diff_total)); - sum_diff = vget_lane_s32(vabs_s32(vreinterpret_s32_s64(x)), 0); - - if (sum_diff > sum_diff_thresh) { - return COPY_BLOCK; - } - } - } else { - return COPY_BLOCK; - } - } - } - - /* Tell above level that block was filtered. */ - running_avg_y -= running_avg_y_stride * 16; - sig -= sig_stride * 16; - - vp8_copy_mem16x16(running_avg_y, running_avg_y_stride, sig, sig_stride); - - return FILTER_BLOCK; -} - -int vp8_denoiser_filter_uv_neon(unsigned char *mc_running_avg, - int mc_running_avg_stride, - unsigned char *running_avg, - int running_avg_stride, unsigned char *sig, - int sig_stride, unsigned int motion_magnitude, - int increase_denoising) { - /* If motion_magnitude is small, making the denoiser more aggressive by - * increasing the adjustment for each level, level1 adjustment is - * increased, the deltas stay the same. - */ - int shift_inc = - (increase_denoising && motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD_UV) - ? 1 - : 0; - const uint8x16_t v_level1_adjustment = vmovq_n_u8( - (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD_UV) ? 4 + shift_inc : 3); - - const uint8x16_t v_delta_level_1_and_2 = vdupq_n_u8(1); - const uint8x16_t v_delta_level_2_and_3 = vdupq_n_u8(2); - const uint8x16_t v_level1_threshold = vmovq_n_u8(4 + shift_inc); - const uint8x16_t v_level2_threshold = vdupq_n_u8(8); - const uint8x16_t v_level3_threshold = vdupq_n_u8(16); - int64x2_t v_sum_diff_total = vdupq_n_s64(0); - int r; - - { - uint16x4_t v_sum_block = vdup_n_u16(0); - - // Avoid denoising color signal if its close to average level. - for (r = 0; r < 8; ++r) { - const uint8x8_t v_sig = vld1_u8(sig); - const uint16x4_t _76_54_32_10 = vpaddl_u8(v_sig); - v_sum_block = vqadd_u16(v_sum_block, _76_54_32_10); - sig += sig_stride; - } - sig -= sig_stride * 8; - { - const uint32x2_t _7654_3210 = vpaddl_u16(v_sum_block); - const uint64x1_t _76543210 = vpaddl_u32(_7654_3210); - const int sum_block = vget_lane_s32(vreinterpret_s32_u64(_76543210), 0); - if (abs(sum_block - (128 * 8 * 8)) < SUM_DIFF_FROM_AVG_THRESH_UV) { - return COPY_BLOCK; - } - } - } - - /* Go over lines. */ - for (r = 0; r < 4; ++r) { - /* Load inputs. */ - const uint8x8_t v_sig_lo = vld1_u8(sig); - const uint8x8_t v_sig_hi = vld1_u8(&sig[sig_stride]); - const uint8x16_t v_sig = vcombine_u8(v_sig_lo, v_sig_hi); - const uint8x8_t v_mc_running_avg_lo = vld1_u8(mc_running_avg); - const uint8x8_t v_mc_running_avg_hi = - vld1_u8(&mc_running_avg[mc_running_avg_stride]); - const uint8x16_t v_mc_running_avg = - vcombine_u8(v_mc_running_avg_lo, v_mc_running_avg_hi); - /* Calculate absolute difference and sign masks. */ - const uint8x16_t v_abs_diff = vabdq_u8(v_sig, v_mc_running_avg); - const uint8x16_t v_diff_pos_mask = vcltq_u8(v_sig, v_mc_running_avg); - const uint8x16_t v_diff_neg_mask = vcgtq_u8(v_sig, v_mc_running_avg); - - /* Figure out which level that put us in. */ - const uint8x16_t v_level1_mask = vcleq_u8(v_level1_threshold, v_abs_diff); - const uint8x16_t v_level2_mask = vcleq_u8(v_level2_threshold, v_abs_diff); - const uint8x16_t v_level3_mask = vcleq_u8(v_level3_threshold, v_abs_diff); - - /* Calculate absolute adjustments for level 1, 2 and 3. */ - const uint8x16_t v_level2_adjustment = - vandq_u8(v_level2_mask, v_delta_level_1_and_2); - const uint8x16_t v_level3_adjustment = - vandq_u8(v_level3_mask, v_delta_level_2_and_3); - const uint8x16_t v_level1and2_adjustment = - vaddq_u8(v_level1_adjustment, v_level2_adjustment); - const uint8x16_t v_level1and2and3_adjustment = - vaddq_u8(v_level1and2_adjustment, v_level3_adjustment); - - /* Figure adjustment absolute value by selecting between the absolute - * difference if in level0 or the value for level 1, 2 and 3. - */ - const uint8x16_t v_abs_adjustment = - vbslq_u8(v_level1_mask, v_level1and2and3_adjustment, v_abs_diff); - - /* Calculate positive and negative adjustments. Apply them to the signal - * and accumulate them. Adjustments are less than eight and the maximum - * sum of them (7 * 16) can fit in a signed char. - */ - const uint8x16_t v_pos_adjustment = - vandq_u8(v_diff_pos_mask, v_abs_adjustment); - const uint8x16_t v_neg_adjustment = - vandq_u8(v_diff_neg_mask, v_abs_adjustment); - - uint8x16_t v_running_avg = vqaddq_u8(v_sig, v_pos_adjustment); - v_running_avg = vqsubq_u8(v_running_avg, v_neg_adjustment); - - /* Store results. */ - vst1_u8(running_avg, vget_low_u8(v_running_avg)); - vst1_u8(&running_avg[running_avg_stride], vget_high_u8(v_running_avg)); - - /* Sum all the accumulators to have the sum of all pixel differences - * for this macroblock. - */ - { - const int8x16_t v_sum_diff = - vqsubq_s8(vreinterpretq_s8_u8(v_pos_adjustment), - vreinterpretq_s8_u8(v_neg_adjustment)); - - const int16x8_t fe_dc_ba_98_76_54_32_10 = vpaddlq_s8(v_sum_diff); - - const int32x4_t fedc_ba98_7654_3210 = - vpaddlq_s16(fe_dc_ba_98_76_54_32_10); - - const int64x2_t fedcba98_76543210 = vpaddlq_s32(fedc_ba98_7654_3210); - - v_sum_diff_total = vqaddq_s64(v_sum_diff_total, fedcba98_76543210); - } - - /* Update pointers for next iteration. */ - sig += sig_stride * 2; - mc_running_avg += mc_running_avg_stride * 2; - running_avg += running_avg_stride * 2; - } - - /* Too much adjustments => copy block. */ - { - int64x1_t x = vqadd_s64(vget_high_s64(v_sum_diff_total), - vget_low_s64(v_sum_diff_total)); - int sum_diff = vget_lane_s32(vabs_s32(vreinterpret_s32_s64(x)), 0); - int sum_diff_thresh = SUM_DIFF_THRESHOLD_UV; - if (increase_denoising) sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH_UV; - if (sum_diff > sum_diff_thresh) { - // Before returning to copy the block (i.e., apply no denoising), - // checK if we can still apply some (weaker) temporal filtering to - // this block, that would otherwise not be denoised at all. Simplest - // is to apply an additional adjustment to running_avg_y to bring it - // closer to sig. The adjustment is capped by a maximum delta, and - // chosen such that in most cases the resulting sum_diff will be - // within the accceptable range given by sum_diff_thresh. - - // The delta is set by the excess of absolute pixel diff over the - // threshold. - int delta = ((sum_diff - sum_diff_thresh) >> 8) + 1; - // Only apply the adjustment for max delta up to 3. - if (delta < 4) { - const uint8x16_t k_delta = vmovq_n_u8(delta); - sig -= sig_stride * 8; - mc_running_avg -= mc_running_avg_stride * 8; - running_avg -= running_avg_stride * 8; - for (r = 0; r < 4; ++r) { - const uint8x8_t v_sig_lo = vld1_u8(sig); - const uint8x8_t v_sig_hi = vld1_u8(&sig[sig_stride]); - const uint8x16_t v_sig = vcombine_u8(v_sig_lo, v_sig_hi); - const uint8x8_t v_mc_running_avg_lo = vld1_u8(mc_running_avg); - const uint8x8_t v_mc_running_avg_hi = - vld1_u8(&mc_running_avg[mc_running_avg_stride]); - const uint8x16_t v_mc_running_avg = - vcombine_u8(v_mc_running_avg_lo, v_mc_running_avg_hi); - /* Calculate absolute difference and sign masks. */ - const uint8x16_t v_abs_diff = vabdq_u8(v_sig, v_mc_running_avg); - const uint8x16_t v_diff_pos_mask = vcltq_u8(v_sig, v_mc_running_avg); - const uint8x16_t v_diff_neg_mask = vcgtq_u8(v_sig, v_mc_running_avg); - // Clamp absolute difference to delta to get the adjustment. - const uint8x16_t v_abs_adjustment = vminq_u8(v_abs_diff, (k_delta)); - - const uint8x16_t v_pos_adjustment = - vandq_u8(v_diff_pos_mask, v_abs_adjustment); - const uint8x16_t v_neg_adjustment = - vandq_u8(v_diff_neg_mask, v_abs_adjustment); - const uint8x8_t v_running_avg_lo = vld1_u8(running_avg); - const uint8x8_t v_running_avg_hi = - vld1_u8(&running_avg[running_avg_stride]); - uint8x16_t v_running_avg = - vcombine_u8(v_running_avg_lo, v_running_avg_hi); - - v_running_avg = vqsubq_u8(v_running_avg, v_pos_adjustment); - v_running_avg = vqaddq_u8(v_running_avg, v_neg_adjustment); - - /* Store results. */ - vst1_u8(running_avg, vget_low_u8(v_running_avg)); - vst1_u8(&running_avg[running_avg_stride], - vget_high_u8(v_running_avg)); - - { - const int8x16_t v_sum_diff = - vqsubq_s8(vreinterpretq_s8_u8(v_neg_adjustment), - vreinterpretq_s8_u8(v_pos_adjustment)); - - const int16x8_t fe_dc_ba_98_76_54_32_10 = vpaddlq_s8(v_sum_diff); - const int32x4_t fedc_ba98_7654_3210 = - vpaddlq_s16(fe_dc_ba_98_76_54_32_10); - const int64x2_t fedcba98_76543210 = - vpaddlq_s32(fedc_ba98_7654_3210); - - v_sum_diff_total = vqaddq_s64(v_sum_diff_total, fedcba98_76543210); - } - /* Update pointers for next iteration. */ - sig += sig_stride * 2; - mc_running_avg += mc_running_avg_stride * 2; - running_avg += running_avg_stride * 2; - } - { - // Update the sum of all pixel differences of this MB. - x = vqadd_s64(vget_high_s64(v_sum_diff_total), - vget_low_s64(v_sum_diff_total)); - sum_diff = vget_lane_s32(vabs_s32(vreinterpret_s32_s64(x)), 0); - - if (sum_diff > sum_diff_thresh) { - return COPY_BLOCK; - } - } - } else { - return COPY_BLOCK; - } - } - } - - /* Tell above level that block was filtered. */ - running_avg -= running_avg_stride * 8; - sig -= sig_stride * 8; - - vp8_copy_mem8x8(running_avg, running_avg_stride, sig, sig_stride); - - return FILTER_BLOCK; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/arm/neon/fastquantizeb_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/arm/neon/fastquantizeb_neon.c deleted file mode 100644 index 950c9433..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/arm/neon/fastquantizeb_neon.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp8_rtcd.h" -#include "vp8/encoder/block.h" - -static const uint16_t inv_zig_zag[16] = { 1, 2, 6, 7, 3, 5, 8, 13, - 4, 9, 12, 14, 10, 11, 15, 16 }; - -void vp8_fast_quantize_b_neon(BLOCK *b, BLOCKD *d) { - const int16x8_t one_q = vdupq_n_s16(-1), z0 = vld1q_s16(b->coeff), - z1 = vld1q_s16(b->coeff + 8), round0 = vld1q_s16(b->round), - round1 = vld1q_s16(b->round + 8), - quant0 = vld1q_s16(b->quant_fast), - quant1 = vld1q_s16(b->quant_fast + 8), - dequant0 = vld1q_s16(d->dequant), - dequant1 = vld1q_s16(d->dequant + 8); - const uint16x8_t zig_zag0 = vld1q_u16(inv_zig_zag), - zig_zag1 = vld1q_u16(inv_zig_zag + 8); - int16x8_t x0, x1, sz0, sz1, y0, y1; - uint16x8_t eob0, eob1; -#if !VPX_ARCH_AARCH64 - uint16x4_t eob_d16; - uint32x2_t eob_d32; - uint32x4_t eob_q32; -#endif // !VPX_ARCH_AARCH64 - - /* sign of z: z >> 15 */ - sz0 = vshrq_n_s16(z0, 15); - sz1 = vshrq_n_s16(z1, 15); - - /* x = abs(z) */ - x0 = vabsq_s16(z0); - x1 = vabsq_s16(z1); - - /* x += round */ - x0 = vaddq_s16(x0, round0); - x1 = vaddq_s16(x1, round1); - - /* y = 2 * (x * quant) >> 16 */ - y0 = vqdmulhq_s16(x0, quant0); - y1 = vqdmulhq_s16(x1, quant1); - - /* Compensate for doubling in vqdmulhq */ - y0 = vshrq_n_s16(y0, 1); - y1 = vshrq_n_s16(y1, 1); - - /* Restore sign bit */ - y0 = veorq_s16(y0, sz0); - y1 = veorq_s16(y1, sz1); - x0 = vsubq_s16(y0, sz0); - x1 = vsubq_s16(y1, sz1); - - /* find non-zero elements */ - eob0 = vtstq_s16(x0, one_q); - eob1 = vtstq_s16(x1, one_q); - - /* mask zig zag */ - eob0 = vandq_u16(eob0, zig_zag0); - eob1 = vandq_u16(eob1, zig_zag1); - - /* select the largest value */ - eob0 = vmaxq_u16(eob0, eob1); -#if VPX_ARCH_AARCH64 - *d->eob = (int8_t)vmaxvq_u16(eob0); -#else - eob_d16 = vmax_u16(vget_low_u16(eob0), vget_high_u16(eob0)); - eob_q32 = vmovl_u16(eob_d16); - eob_d32 = vmax_u32(vget_low_u32(eob_q32), vget_high_u32(eob_q32)); - eob_d32 = vpmax_u32(eob_d32, eob_d32); - - vst1_lane_s8((int8_t *)d->eob, vreinterpret_s8_u32(eob_d32), 0); -#endif // VPX_ARCH_AARCH64 - - /* qcoeff = x */ - vst1q_s16(d->qcoeff, x0); - vst1q_s16(d->qcoeff + 8, x1); - - /* dqcoeff = x * dequant */ - vst1q_s16(d->dqcoeff, vmulq_s16(dequant0, x0)); - vst1q_s16(d->dqcoeff + 8, vmulq_s16(dequant1, x1)); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/arm/neon/shortfdct_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/arm/neon/shortfdct_neon.c deleted file mode 100644 index 99dff6b5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/arm/neon/shortfdct_neon.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp8_rtcd.h" - -void vp8_short_fdct4x4_neon(int16_t *input, int16_t *output, int pitch) { - int16x4_t d0s16, d1s16, d2s16, d3s16, d4s16, d5s16, d6s16, d7s16; - int16x4_t d16s16, d17s16, d26s16, dEmptys16; - uint16x4_t d4u16; - int16x8_t q0s16, q1s16; - int32x4_t q9s32, q10s32, q11s32, q12s32; - int16x4x2_t v2tmp0, v2tmp1; - int32x2x2_t v2tmp2, v2tmp3; - - d16s16 = vdup_n_s16(5352); - d17s16 = vdup_n_s16(2217); - q9s32 = vdupq_n_s32(14500); - q10s32 = vdupq_n_s32(7500); - q11s32 = vdupq_n_s32(12000); - q12s32 = vdupq_n_s32(51000); - - // Part one - pitch >>= 1; - d0s16 = vld1_s16(input); - input += pitch; - d1s16 = vld1_s16(input); - input += pitch; - d2s16 = vld1_s16(input); - input += pitch; - d3s16 = vld1_s16(input); - - v2tmp2 = vtrn_s32(vreinterpret_s32_s16(d0s16), vreinterpret_s32_s16(d2s16)); - v2tmp3 = vtrn_s32(vreinterpret_s32_s16(d1s16), vreinterpret_s32_s16(d3s16)); - v2tmp0 = vtrn_s16(vreinterpret_s16_s32(v2tmp2.val[0]), // d0 - vreinterpret_s16_s32(v2tmp3.val[0])); // d1 - v2tmp1 = vtrn_s16(vreinterpret_s16_s32(v2tmp2.val[1]), // d2 - vreinterpret_s16_s32(v2tmp3.val[1])); // d3 - - d4s16 = vadd_s16(v2tmp0.val[0], v2tmp1.val[1]); - d5s16 = vadd_s16(v2tmp0.val[1], v2tmp1.val[0]); - d6s16 = vsub_s16(v2tmp0.val[1], v2tmp1.val[0]); - d7s16 = vsub_s16(v2tmp0.val[0], v2tmp1.val[1]); - - d4s16 = vshl_n_s16(d4s16, 3); - d5s16 = vshl_n_s16(d5s16, 3); - d6s16 = vshl_n_s16(d6s16, 3); - d7s16 = vshl_n_s16(d7s16, 3); - - d0s16 = vadd_s16(d4s16, d5s16); - d2s16 = vsub_s16(d4s16, d5s16); - - q9s32 = vmlal_s16(q9s32, d7s16, d16s16); - q10s32 = vmlal_s16(q10s32, d7s16, d17s16); - q9s32 = vmlal_s16(q9s32, d6s16, d17s16); - q10s32 = vmlsl_s16(q10s32, d6s16, d16s16); - - d1s16 = vshrn_n_s32(q9s32, 12); - d3s16 = vshrn_n_s32(q10s32, 12); - - // Part two - v2tmp2 = vtrn_s32(vreinterpret_s32_s16(d0s16), vreinterpret_s32_s16(d2s16)); - v2tmp3 = vtrn_s32(vreinterpret_s32_s16(d1s16), vreinterpret_s32_s16(d3s16)); - v2tmp0 = vtrn_s16(vreinterpret_s16_s32(v2tmp2.val[0]), // d0 - vreinterpret_s16_s32(v2tmp3.val[0])); // d1 - v2tmp1 = vtrn_s16(vreinterpret_s16_s32(v2tmp2.val[1]), // d2 - vreinterpret_s16_s32(v2tmp3.val[1])); // d3 - - d4s16 = vadd_s16(v2tmp0.val[0], v2tmp1.val[1]); - d5s16 = vadd_s16(v2tmp0.val[1], v2tmp1.val[0]); - d6s16 = vsub_s16(v2tmp0.val[1], v2tmp1.val[0]); - d7s16 = vsub_s16(v2tmp0.val[0], v2tmp1.val[1]); - - d26s16 = vdup_n_s16(7); - d4s16 = vadd_s16(d4s16, d26s16); - - d0s16 = vadd_s16(d4s16, d5s16); - d2s16 = vsub_s16(d4s16, d5s16); - - q11s32 = vmlal_s16(q11s32, d7s16, d16s16); - q12s32 = vmlal_s16(q12s32, d7s16, d17s16); - - dEmptys16 = vdup_n_s16(0); - d4u16 = vceq_s16(d7s16, dEmptys16); - - d0s16 = vshr_n_s16(d0s16, 4); - d2s16 = vshr_n_s16(d2s16, 4); - - q11s32 = vmlal_s16(q11s32, d6s16, d17s16); - q12s32 = vmlsl_s16(q12s32, d6s16, d16s16); - - d4u16 = vmvn_u16(d4u16); - d1s16 = vshrn_n_s32(q11s32, 16); - d1s16 = vsub_s16(d1s16, vreinterpret_s16_u16(d4u16)); - d3s16 = vshrn_n_s32(q12s32, 16); - - q0s16 = vcombine_s16(d0s16, d1s16); - q1s16 = vcombine_s16(d2s16, d3s16); - - vst1q_s16(output, q0s16); - vst1q_s16(output + 8, q1s16); - return; -} - -void vp8_short_fdct8x4_neon(int16_t *input, int16_t *output, int pitch) { - int16x4_t d0s16, d1s16, d2s16, d3s16, d4s16, d5s16, d6s16, d7s16; - int16x4_t d16s16, d17s16, d26s16, d27s16, d28s16, d29s16; - uint16x4_t d28u16, d29u16; - uint16x8_t q14u16; - int16x8_t q0s16, q1s16, q2s16, q3s16; - int16x8_t q11s16, q12s16, q13s16, q14s16, q15s16, qEmptys16; - int32x4_t q9s32, q10s32, q11s32, q12s32; - int16x8x2_t v2tmp0, v2tmp1; - int32x4x2_t v2tmp2, v2tmp3; - - d16s16 = vdup_n_s16(5352); - d17s16 = vdup_n_s16(2217); - q9s32 = vdupq_n_s32(14500); - q10s32 = vdupq_n_s32(7500); - - // Part one - pitch >>= 1; - q0s16 = vld1q_s16(input); - input += pitch; - q1s16 = vld1q_s16(input); - input += pitch; - q2s16 = vld1q_s16(input); - input += pitch; - q3s16 = vld1q_s16(input); - - v2tmp2 = - vtrnq_s32(vreinterpretq_s32_s16(q0s16), vreinterpretq_s32_s16(q2s16)); - v2tmp3 = - vtrnq_s32(vreinterpretq_s32_s16(q1s16), vreinterpretq_s32_s16(q3s16)); - v2tmp0 = vtrnq_s16(vreinterpretq_s16_s32(v2tmp2.val[0]), // q0 - vreinterpretq_s16_s32(v2tmp3.val[0])); // q1 - v2tmp1 = vtrnq_s16(vreinterpretq_s16_s32(v2tmp2.val[1]), // q2 - vreinterpretq_s16_s32(v2tmp3.val[1])); // q3 - - q11s16 = vaddq_s16(v2tmp0.val[0], v2tmp1.val[1]); - q12s16 = vaddq_s16(v2tmp0.val[1], v2tmp1.val[0]); - q13s16 = vsubq_s16(v2tmp0.val[1], v2tmp1.val[0]); - q14s16 = vsubq_s16(v2tmp0.val[0], v2tmp1.val[1]); - - q11s16 = vshlq_n_s16(q11s16, 3); - q12s16 = vshlq_n_s16(q12s16, 3); - q13s16 = vshlq_n_s16(q13s16, 3); - q14s16 = vshlq_n_s16(q14s16, 3); - - q0s16 = vaddq_s16(q11s16, q12s16); - q2s16 = vsubq_s16(q11s16, q12s16); - - q11s32 = q9s32; - q12s32 = q10s32; - - d26s16 = vget_low_s16(q13s16); - d27s16 = vget_high_s16(q13s16); - d28s16 = vget_low_s16(q14s16); - d29s16 = vget_high_s16(q14s16); - - q9s32 = vmlal_s16(q9s32, d28s16, d16s16); - q10s32 = vmlal_s16(q10s32, d28s16, d17s16); - q11s32 = vmlal_s16(q11s32, d29s16, d16s16); - q12s32 = vmlal_s16(q12s32, d29s16, d17s16); - - q9s32 = vmlal_s16(q9s32, d26s16, d17s16); - q10s32 = vmlsl_s16(q10s32, d26s16, d16s16); - q11s32 = vmlal_s16(q11s32, d27s16, d17s16); - q12s32 = vmlsl_s16(q12s32, d27s16, d16s16); - - d2s16 = vshrn_n_s32(q9s32, 12); - d6s16 = vshrn_n_s32(q10s32, 12); - d3s16 = vshrn_n_s32(q11s32, 12); - d7s16 = vshrn_n_s32(q12s32, 12); - q1s16 = vcombine_s16(d2s16, d3s16); - q3s16 = vcombine_s16(d6s16, d7s16); - - // Part two - q9s32 = vdupq_n_s32(12000); - q10s32 = vdupq_n_s32(51000); - - v2tmp2 = - vtrnq_s32(vreinterpretq_s32_s16(q0s16), vreinterpretq_s32_s16(q2s16)); - v2tmp3 = - vtrnq_s32(vreinterpretq_s32_s16(q1s16), vreinterpretq_s32_s16(q3s16)); - v2tmp0 = vtrnq_s16(vreinterpretq_s16_s32(v2tmp2.val[0]), // q0 - vreinterpretq_s16_s32(v2tmp3.val[0])); // q1 - v2tmp1 = vtrnq_s16(vreinterpretq_s16_s32(v2tmp2.val[1]), // q2 - vreinterpretq_s16_s32(v2tmp3.val[1])); // q3 - - q11s16 = vaddq_s16(v2tmp0.val[0], v2tmp1.val[1]); - q12s16 = vaddq_s16(v2tmp0.val[1], v2tmp1.val[0]); - q13s16 = vsubq_s16(v2tmp0.val[1], v2tmp1.val[0]); - q14s16 = vsubq_s16(v2tmp0.val[0], v2tmp1.val[1]); - - q15s16 = vdupq_n_s16(7); - q11s16 = vaddq_s16(q11s16, q15s16); - q0s16 = vaddq_s16(q11s16, q12s16); - q1s16 = vsubq_s16(q11s16, q12s16); - - q11s32 = q9s32; - q12s32 = q10s32; - - d0s16 = vget_low_s16(q0s16); - d1s16 = vget_high_s16(q0s16); - d2s16 = vget_low_s16(q1s16); - d3s16 = vget_high_s16(q1s16); - - d0s16 = vshr_n_s16(d0s16, 4); - d4s16 = vshr_n_s16(d1s16, 4); - d2s16 = vshr_n_s16(d2s16, 4); - d6s16 = vshr_n_s16(d3s16, 4); - - d26s16 = vget_low_s16(q13s16); - d27s16 = vget_high_s16(q13s16); - d28s16 = vget_low_s16(q14s16); - d29s16 = vget_high_s16(q14s16); - - q9s32 = vmlal_s16(q9s32, d28s16, d16s16); - q10s32 = vmlal_s16(q10s32, d28s16, d17s16); - q11s32 = vmlal_s16(q11s32, d29s16, d16s16); - q12s32 = vmlal_s16(q12s32, d29s16, d17s16); - - q9s32 = vmlal_s16(q9s32, d26s16, d17s16); - q10s32 = vmlsl_s16(q10s32, d26s16, d16s16); - q11s32 = vmlal_s16(q11s32, d27s16, d17s16); - q12s32 = vmlsl_s16(q12s32, d27s16, d16s16); - - d1s16 = vshrn_n_s32(q9s32, 16); - d3s16 = vshrn_n_s32(q10s32, 16); - d5s16 = vshrn_n_s32(q11s32, 16); - d7s16 = vshrn_n_s32(q12s32, 16); - - qEmptys16 = vdupq_n_s16(0); - q14u16 = vceqq_s16(q14s16, qEmptys16); - q14u16 = vmvnq_u16(q14u16); - - d28u16 = vget_low_u16(q14u16); - d29u16 = vget_high_u16(q14u16); - d1s16 = vsub_s16(d1s16, vreinterpret_s16_u16(d28u16)); - d5s16 = vsub_s16(d5s16, vreinterpret_s16_u16(d29u16)); - - q0s16 = vcombine_s16(d0s16, d1s16); - q1s16 = vcombine_s16(d2s16, d3s16); - q2s16 = vcombine_s16(d4s16, d5s16); - q3s16 = vcombine_s16(d6s16, d7s16); - - vst1q_s16(output, q0s16); - vst1q_s16(output + 8, q1s16); - vst1q_s16(output + 16, q2s16); - vst1q_s16(output + 24, q3s16); - return; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/arm/neon/vp8_shortwalsh4x4_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/arm/neon/vp8_shortwalsh4x4_neon.c deleted file mode 100644 index 02056f2f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/arm/neon/vp8_shortwalsh4x4_neon.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp8_rtcd.h" -#include "vpx_ports/arm.h" - -#ifdef VPX_INCOMPATIBLE_GCC -#include "./vp8_rtcd.h" -void vp8_short_walsh4x4_neon(int16_t *input, int16_t *output, int pitch) { - vp8_short_walsh4x4_c(input, output, pitch); -} -#else -void vp8_short_walsh4x4_neon(int16_t *input, int16_t *output, int pitch) { - uint16x4_t d16u16; - int16x8_t q0s16, q1s16; - int16x4_t dEmptys16, d0s16, d1s16, d2s16, d3s16, d4s16, d5s16, d6s16, d7s16; - int32x4_t qEmptys32, q0s32, q1s32, q2s32, q3s32, q8s32; - int32x4_t q9s32, q10s32, q11s32, q15s32; - uint32x4_t q8u32, q9u32, q10u32, q11u32; - int16x4x2_t v2tmp0, v2tmp1; - int32x2x2_t v2tmp2, v2tmp3; - - dEmptys16 = vdup_n_s16(0); - qEmptys32 = vdupq_n_s32(0); - q15s32 = vdupq_n_s32(3); - - d0s16 = vld1_s16(input); - input += pitch / 2; - d1s16 = vld1_s16(input); - input += pitch / 2; - d2s16 = vld1_s16(input); - input += pitch / 2; - d3s16 = vld1_s16(input); - - v2tmp2 = vtrn_s32(vreinterpret_s32_s16(d0s16), vreinterpret_s32_s16(d2s16)); - v2tmp3 = vtrn_s32(vreinterpret_s32_s16(d1s16), vreinterpret_s32_s16(d3s16)); - v2tmp0 = vtrn_s16(vreinterpret_s16_s32(v2tmp2.val[0]), // d0 - vreinterpret_s16_s32(v2tmp3.val[0])); // d1 - v2tmp1 = vtrn_s16(vreinterpret_s16_s32(v2tmp2.val[1]), // d2 - vreinterpret_s16_s32(v2tmp3.val[1])); // d3 - - d4s16 = vadd_s16(v2tmp0.val[0], v2tmp1.val[0]); - d5s16 = vadd_s16(v2tmp0.val[1], v2tmp1.val[1]); - d6s16 = vsub_s16(v2tmp0.val[1], v2tmp1.val[1]); - d7s16 = vsub_s16(v2tmp0.val[0], v2tmp1.val[0]); - - d4s16 = vshl_n_s16(d4s16, 2); - d5s16 = vshl_n_s16(d5s16, 2); - d6s16 = vshl_n_s16(d6s16, 2); - d7s16 = vshl_n_s16(d7s16, 2); - - d16u16 = vceq_s16(d4s16, dEmptys16); - d16u16 = vmvn_u16(d16u16); - - d0s16 = vadd_s16(d4s16, d5s16); - d3s16 = vsub_s16(d4s16, d5s16); - d1s16 = vadd_s16(d7s16, d6s16); - d2s16 = vsub_s16(d7s16, d6s16); - - d0s16 = vsub_s16(d0s16, vreinterpret_s16_u16(d16u16)); - - // Second for-loop - v2tmp2 = vtrn_s32(vreinterpret_s32_s16(d1s16), vreinterpret_s32_s16(d3s16)); - v2tmp3 = vtrn_s32(vreinterpret_s32_s16(d0s16), vreinterpret_s32_s16(d2s16)); - v2tmp0 = vtrn_s16(vreinterpret_s16_s32(v2tmp3.val[1]), // d2 - vreinterpret_s16_s32(v2tmp2.val[1])); // d3 - v2tmp1 = vtrn_s16(vreinterpret_s16_s32(v2tmp3.val[0]), // d0 - vreinterpret_s16_s32(v2tmp2.val[0])); // d1 - - q8s32 = vaddl_s16(v2tmp1.val[0], v2tmp0.val[0]); - q9s32 = vaddl_s16(v2tmp1.val[1], v2tmp0.val[1]); - q10s32 = vsubl_s16(v2tmp1.val[1], v2tmp0.val[1]); - q11s32 = vsubl_s16(v2tmp1.val[0], v2tmp0.val[0]); - - q0s32 = vaddq_s32(q8s32, q9s32); - q1s32 = vaddq_s32(q11s32, q10s32); - q2s32 = vsubq_s32(q11s32, q10s32); - q3s32 = vsubq_s32(q8s32, q9s32); - - q8u32 = vcltq_s32(q0s32, qEmptys32); - q9u32 = vcltq_s32(q1s32, qEmptys32); - q10u32 = vcltq_s32(q2s32, qEmptys32); - q11u32 = vcltq_s32(q3s32, qEmptys32); - - q8s32 = vreinterpretq_s32_u32(q8u32); - q9s32 = vreinterpretq_s32_u32(q9u32); - q10s32 = vreinterpretq_s32_u32(q10u32); - q11s32 = vreinterpretq_s32_u32(q11u32); - - q0s32 = vsubq_s32(q0s32, q8s32); - q1s32 = vsubq_s32(q1s32, q9s32); - q2s32 = vsubq_s32(q2s32, q10s32); - q3s32 = vsubq_s32(q3s32, q11s32); - - q8s32 = vaddq_s32(q0s32, q15s32); - q9s32 = vaddq_s32(q1s32, q15s32); - q10s32 = vaddq_s32(q2s32, q15s32); - q11s32 = vaddq_s32(q3s32, q15s32); - - d0s16 = vshrn_n_s32(q8s32, 3); - d1s16 = vshrn_n_s32(q9s32, 3); - d2s16 = vshrn_n_s32(q10s32, 3); - d3s16 = vshrn_n_s32(q11s32, 3); - - q0s16 = vcombine_s16(d0s16, d1s16); - q1s16 = vcombine_s16(d2s16, d3s16); - - vst1q_s16(output, q0s16); - vst1q_s16(output + 8, q1s16); - return; -} -#endif // VPX_INCOMPATIBLE_GCC diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/bitstream.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/bitstream.c deleted file mode 100644 index 7bcdf777..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/bitstream.c +++ /dev/null @@ -1,1381 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp8/common/header.h" -#include "encodemv.h" -#include "vp8/common/entropymode.h" -#include "vp8/common/findnearmv.h" -#include "mcomp.h" -#include "vp8/common/systemdependent.h" -#include -#include -#include -#include "vpx/vpx_encoder.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/compiler_attributes.h" -#include "vpx_ports/system_state.h" -#include "bitstream.h" - -#include "defaultcoefcounts.h" -#include "vp8/common/common.h" - -const int vp8cx_base_skip_false_prob[128] = { - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 251, 248, 244, 240, - 236, 232, 229, 225, 221, 217, 213, 208, 204, 199, 194, 190, 187, 183, 179, - 175, 172, 168, 164, 160, 157, 153, 149, 145, 142, 138, 134, 130, 127, 124, - 120, 117, 114, 110, 107, 104, 101, 98, 95, 92, 89, 86, 83, 80, 77, - 74, 71, 68, 65, 62, 59, 56, 53, 50, 47, 44, 41, 38, 35, 32, - 30, 28, 26, 24, 22, 20, 18, 16, -}; - -#if defined(SECTIONBITS_OUTPUT) -unsigned __int64 Sectionbits[500]; -#endif - -#ifdef MODE_STATS -int count_mb_seg[4] = { 0, 0, 0, 0 }; -#endif - -static void update_mode(vp8_writer *const w, int n, vp8_token tok[/* n */], - vp8_tree tree, vp8_prob Pnew[/* n-1 */], - vp8_prob Pcur[/* n-1 */], - unsigned int bct[/* n-1 */][2], - const unsigned int num_events[/* n */]) { - unsigned int new_b = 0, old_b = 0; - int i = 0; - - vp8_tree_probs_from_distribution(n--, tok, tree, Pnew, bct, num_events, 256, - 1); - - do { - new_b += vp8_cost_branch(bct[i], Pnew[i]); - old_b += vp8_cost_branch(bct[i], Pcur[i]); - } while (++i < n); - - if (new_b + (n << 8) < old_b) { - int j = 0; - - vp8_write_bit(w, 1); - - do { - const vp8_prob p = Pnew[j]; - - vp8_write_literal(w, Pcur[j] = p ? p : 1, 8); - } while (++j < n); - } else - vp8_write_bit(w, 0); -} - -static void update_mbintra_mode_probs(VP8_COMP *cpi) { - VP8_COMMON *const x = &cpi->common; - - vp8_writer *const w = cpi->bc; - - { - vp8_prob Pnew[VP8_YMODES - 1]; - unsigned int bct[VP8_YMODES - 1][2]; - - update_mode(w, VP8_YMODES, vp8_ymode_encodings, vp8_ymode_tree, Pnew, - x->fc.ymode_prob, bct, (unsigned int *)cpi->mb.ymode_count); - } - { - vp8_prob Pnew[VP8_UV_MODES - 1]; - unsigned int bct[VP8_UV_MODES - 1][2]; - - update_mode(w, VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree, Pnew, - x->fc.uv_mode_prob, bct, (unsigned int *)cpi->mb.uv_mode_count); - } -} - -static void write_ymode(vp8_writer *bc, int m, const vp8_prob *p) { - vp8_write_token(bc, vp8_ymode_tree, p, vp8_ymode_encodings + m); -} - -static void kfwrite_ymode(vp8_writer *bc, int m, const vp8_prob *p) { - vp8_write_token(bc, vp8_kf_ymode_tree, p, vp8_kf_ymode_encodings + m); -} - -static void write_uv_mode(vp8_writer *bc, int m, const vp8_prob *p) { - vp8_write_token(bc, vp8_uv_mode_tree, p, vp8_uv_mode_encodings + m); -} - -static void write_bmode(vp8_writer *bc, int m, const vp8_prob *p) { - vp8_write_token(bc, vp8_bmode_tree, p, vp8_bmode_encodings + m); -} - -static void write_split(vp8_writer *bc, int x) { - vp8_write_token(bc, vp8_mbsplit_tree, vp8_mbsplit_probs, - vp8_mbsplit_encodings + x); -} - -void VPX_NO_UNSIGNED_SHIFT_CHECK vp8_pack_tokens(vp8_writer *w, - const TOKENEXTRA *p, - int xcount) { - const TOKENEXTRA *stop = p + xcount; - unsigned int split; - int shift; - int count = w->count; - unsigned int range = w->range; - unsigned int lowvalue = w->lowvalue; - - while (p < stop) { - const int t = p->Token; - vp8_token *a = vp8_coef_encodings + t; - const vp8_extra_bit_struct *b = vp8_extra_bits + t; - int i = 0; - const unsigned char *pp = p->context_tree; - int v = a->value; - int n = a->Len; - - if (p->skip_eob_node) { - n--; - i = 2; - } - - do { - const int bb = (v >> --n) & 1; - split = 1 + (((range - 1) * pp[i >> 1]) >> 8); - i = vp8_coef_tree[i + bb]; - - if (bb) { - lowvalue += split; - range = range - split; - } else { - range = split; - } - - shift = vp8_norm[range]; - range <<= shift; - count += shift; - - if (count >= 0) { - int offset = shift - count; - - if ((lowvalue << (offset - 1)) & 0x80000000) { - int x = w->pos - 1; - - while (x >= 0 && w->buffer[x] == 0xff) { - w->buffer[x] = (unsigned char)0; - x--; - } - - w->buffer[x] += 1; - } - - validate_buffer(w->buffer + w->pos, 1, w->buffer_end, w->error); - - w->buffer[w->pos++] = (lowvalue >> (24 - offset)) & 0xff; - shift = count; - lowvalue = (int)(((uint64_t)lowvalue << offset) & 0xffffff); - count -= 8; - } - - lowvalue <<= shift; - } while (n); - - if (b->base_val) { - const int e = p->Extra, L = b->Len; - - if (L) { - const unsigned char *proba = b->prob; - const int v2 = e >> 1; - int n2 = L; /* number of bits in v2, assumed nonzero */ - i = 0; - - do { - const int bb = (v2 >> --n2) & 1; - split = 1 + (((range - 1) * proba[i >> 1]) >> 8); - i = b->tree[i + bb]; - - if (bb) { - lowvalue += split; - range = range - split; - } else { - range = split; - } - - shift = vp8_norm[range]; - range <<= shift; - count += shift; - - if (count >= 0) { - int offset = shift - count; - - if ((lowvalue << (offset - 1)) & 0x80000000) { - int x = w->pos - 1; - - while (x >= 0 && w->buffer[x] == 0xff) { - w->buffer[x] = (unsigned char)0; - x--; - } - - w->buffer[x] += 1; - } - - validate_buffer(w->buffer + w->pos, 1, w->buffer_end, w->error); - - w->buffer[w->pos++] = (lowvalue >> (24 - offset)) & 0xff; - shift = count; - lowvalue = (int)(((uint64_t)lowvalue << offset) & 0xffffff); - count -= 8; - } - - lowvalue <<= shift; - } while (n2); - } - - { - split = (range + 1) >> 1; - - if (e & 1) { - lowvalue += split; - range = range - split; - } else { - range = split; - } - - range <<= 1; - - if ((lowvalue & 0x80000000)) { - int x = w->pos - 1; - - while (x >= 0 && w->buffer[x] == 0xff) { - w->buffer[x] = (unsigned char)0; - x--; - } - - w->buffer[x] += 1; - } - - lowvalue <<= 1; - - if (!++count) { - count = -8; - - validate_buffer(w->buffer + w->pos, 1, w->buffer_end, w->error); - - w->buffer[w->pos++] = (lowvalue >> 24); - lowvalue &= 0xffffff; - } - } - } - - ++p; - } - - w->count = count; - w->lowvalue = lowvalue; - w->range = range; -} - -static void write_partition_size(unsigned char *cx_data, int size) { - signed char csize; - - csize = size & 0xff; - *cx_data = csize; - csize = (size >> 8) & 0xff; - *(cx_data + 1) = csize; - csize = (size >> 16) & 0xff; - *(cx_data + 2) = csize; -} - -static void pack_tokens_into_partitions(VP8_COMP *cpi, unsigned char *cx_data, - unsigned char *cx_data_end, - int num_part) { - int i; - unsigned char *ptr = cx_data; - unsigned char *ptr_end = cx_data_end; - vp8_writer *w; - - for (i = 0; i < num_part; ++i) { - int mb_row; - - w = cpi->bc + i + 1; - - vp8_start_encode(w, ptr, ptr_end); - - for (mb_row = i; mb_row < cpi->common.mb_rows; mb_row += num_part) { - const TOKENEXTRA *p = cpi->tplist[mb_row].start; - const TOKENEXTRA *stop = cpi->tplist[mb_row].stop; - int tokens = (int)(stop - p); - - vp8_pack_tokens(w, p, tokens); - } - - vp8_stop_encode(w); - ptr += w->pos; - } -} - -#if CONFIG_MULTITHREAD -static void pack_mb_row_tokens(VP8_COMP *cpi, vp8_writer *w) { - int mb_row; - - for (mb_row = 0; mb_row < cpi->common.mb_rows; ++mb_row) { - const TOKENEXTRA *p = cpi->tplist[mb_row].start; - const TOKENEXTRA *stop = cpi->tplist[mb_row].stop; - int tokens = (int)(stop - p); - - vp8_pack_tokens(w, p, tokens); - } -} -#endif // CONFIG_MULTITHREAD - -static void write_mv_ref(vp8_writer *w, MB_PREDICTION_MODE m, - const vp8_prob *p) { - assert(NEARESTMV <= m && m <= SPLITMV); - vp8_write_token(w, vp8_mv_ref_tree, p, - vp8_mv_ref_encoding_array + (m - NEARESTMV)); -} - -static void write_sub_mv_ref(vp8_writer *w, B_PREDICTION_MODE m, - const vp8_prob *p) { - assert(LEFT4X4 <= m && m <= NEW4X4); - vp8_write_token(w, vp8_sub_mv_ref_tree, p, - vp8_sub_mv_ref_encoding_array + (m - LEFT4X4)); -} - -static void write_mv(vp8_writer *w, const MV *mv, const int_mv *ref, - const MV_CONTEXT *mvc) { - MV e; - e.row = mv->row - ref->as_mv.row; - e.col = mv->col - ref->as_mv.col; - - vp8_encode_motion_vector(w, &e, mvc); -} - -static void write_mb_features(vp8_writer *w, const MB_MODE_INFO *mi, - const MACROBLOCKD *x) { - /* Encode the MB segment id. */ - if (x->segmentation_enabled && x->update_mb_segmentation_map) { - switch (mi->segment_id) { - case 0: - vp8_write(w, 0, x->mb_segment_tree_probs[0]); - vp8_write(w, 0, x->mb_segment_tree_probs[1]); - break; - case 1: - vp8_write(w, 0, x->mb_segment_tree_probs[0]); - vp8_write(w, 1, x->mb_segment_tree_probs[1]); - break; - case 2: - vp8_write(w, 1, x->mb_segment_tree_probs[0]); - vp8_write(w, 0, x->mb_segment_tree_probs[2]); - break; - case 3: - vp8_write(w, 1, x->mb_segment_tree_probs[0]); - vp8_write(w, 1, x->mb_segment_tree_probs[2]); - break; - - /* TRAP.. This should not happen */ - default: - vp8_write(w, 0, x->mb_segment_tree_probs[0]); - vp8_write(w, 0, x->mb_segment_tree_probs[1]); - break; - } - } -} -void vp8_convert_rfct_to_prob(VP8_COMP *const cpi) { - const int *const rfct = cpi->mb.count_mb_ref_frame_usage; - const int rf_intra = rfct[INTRA_FRAME]; - const int rf_inter = - rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]; - - /* Calculate the probabilities used to code the ref frame based on usage */ - if (!(cpi->prob_intra_coded = rf_intra * 255 / (rf_intra + rf_inter))) { - cpi->prob_intra_coded = 1; - } - - cpi->prob_last_coded = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128; - - if (!cpi->prob_last_coded) cpi->prob_last_coded = 1; - - cpi->prob_gf_coded = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) - ? (rfct[GOLDEN_FRAME] * 255) / - (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) - : 128; - - if (!cpi->prob_gf_coded) cpi->prob_gf_coded = 1; -} - -static void pack_inter_mode_mvs(VP8_COMP *const cpi) { - VP8_COMMON *const pc = &cpi->common; - vp8_writer *const w = cpi->bc; - const MV_CONTEXT *mvc = pc->fc.mvc; - - MODE_INFO *m = pc->mi; - const int mis = pc->mode_info_stride; - int mb_row = -1; - - int prob_skip_false = 0; - - cpi->mb.partition_info = cpi->mb.pi; - - vp8_convert_rfct_to_prob(cpi); - - if (pc->mb_no_coeff_skip) { - int total_mbs = pc->mb_rows * pc->mb_cols; - - prob_skip_false = (total_mbs - cpi->mb.skip_true_count) * 256 / total_mbs; - - if (prob_skip_false <= 1) prob_skip_false = 1; - - if (prob_skip_false > 255) prob_skip_false = 255; - - cpi->prob_skip_false = prob_skip_false; - vp8_write_literal(w, prob_skip_false, 8); - } - - vp8_write_literal(w, cpi->prob_intra_coded, 8); - vp8_write_literal(w, cpi->prob_last_coded, 8); - vp8_write_literal(w, cpi->prob_gf_coded, 8); - - update_mbintra_mode_probs(cpi); - - vp8_write_mvprobs(cpi); - - while (++mb_row < pc->mb_rows) { - int mb_col = -1; - - while (++mb_col < pc->mb_cols) { - const MB_MODE_INFO *const mi = &m->mbmi; - const MV_REFERENCE_FRAME rf = mi->ref_frame; - const MB_PREDICTION_MODE mode = mi->mode; - - MACROBLOCKD *xd = &cpi->mb.e_mbd; - - /* Distance of Mb to the various image edges. - * These specified to 8th pel as they are always compared to MV - * values that are in 1/8th pel units - */ - xd->mb_to_left_edge = -((mb_col * 16) << 3); - xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3; - xd->mb_to_top_edge = -((mb_row * 16) << 3); - xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3; - - if (cpi->mb.e_mbd.update_mb_segmentation_map) { - write_mb_features(w, mi, &cpi->mb.e_mbd); - } - - if (pc->mb_no_coeff_skip) { - vp8_encode_bool(w, m->mbmi.mb_skip_coeff, prob_skip_false); - } - - if (rf == INTRA_FRAME) { - vp8_write(w, 0, cpi->prob_intra_coded); - write_ymode(w, mode, pc->fc.ymode_prob); - - if (mode == B_PRED) { - int j = 0; - - do { - write_bmode(w, m->bmi[j].as_mode, pc->fc.bmode_prob); - } while (++j < 16); - } - - write_uv_mode(w, mi->uv_mode, pc->fc.uv_mode_prob); - } else { /* inter coded */ - int_mv best_mv; - vp8_prob mv_ref_p[VP8_MVREFS - 1]; - - vp8_write(w, 1, cpi->prob_intra_coded); - - if (rf == LAST_FRAME) - vp8_write(w, 0, cpi->prob_last_coded); - else { - vp8_write(w, 1, cpi->prob_last_coded); - vp8_write(w, (rf == GOLDEN_FRAME) ? 0 : 1, cpi->prob_gf_coded); - } - - { - int_mv n1, n2; - int ct[4]; - - vp8_find_near_mvs(xd, m, &n1, &n2, &best_mv, ct, rf, - pc->ref_frame_sign_bias); - vp8_clamp_mv2(&best_mv, xd); - - vp8_mv_ref_probs(mv_ref_p, ct); - } - - write_mv_ref(w, mode, mv_ref_p); - - switch (mode) /* new, split require MVs */ - { - case NEWMV: write_mv(w, &mi->mv.as_mv, &best_mv, mvc); break; - - case SPLITMV: { - int j = 0; - -#ifdef MODE_STATS - ++count_mb_seg[mi->partitioning]; -#endif - - write_split(w, mi->partitioning); - - do { - B_PREDICTION_MODE blockmode; - int_mv blockmv; - const int *const L = vp8_mbsplits[mi->partitioning]; - int k = -1; /* first block in subset j */ - int mv_contz; - int_mv leftmv, abovemv; - - blockmode = cpi->mb.partition_info->bmi[j].mode; - blockmv = cpi->mb.partition_info->bmi[j].mv; - while (j != L[++k]) { - assert(k < 16); - } - leftmv.as_int = left_block_mv(m, k); - abovemv.as_int = above_block_mv(m, k, mis); - mv_contz = vp8_mv_cont(&leftmv, &abovemv); - - write_sub_mv_ref(w, blockmode, vp8_sub_mv_ref_prob2[mv_contz]); - - if (blockmode == NEW4X4) { - write_mv(w, &blockmv.as_mv, &best_mv, (const MV_CONTEXT *)mvc); - } - } while (++j < cpi->mb.partition_info->count); - break; - } - default: break; - } - } - - ++m; - cpi->mb.partition_info++; - } - - ++m; /* skip L prediction border */ - cpi->mb.partition_info++; - } -} - -static void write_kfmodes(VP8_COMP *cpi) { - vp8_writer *const bc = cpi->bc; - const VP8_COMMON *const c = &cpi->common; - /* const */ - MODE_INFO *m = c->mi; - - int mb_row = -1; - int prob_skip_false = 0; - - if (c->mb_no_coeff_skip) { - int total_mbs = c->mb_rows * c->mb_cols; - - prob_skip_false = (total_mbs - cpi->mb.skip_true_count) * 256 / total_mbs; - - if (prob_skip_false <= 1) prob_skip_false = 1; - - if (prob_skip_false >= 255) prob_skip_false = 255; - - cpi->prob_skip_false = prob_skip_false; - vp8_write_literal(bc, prob_skip_false, 8); - } - - while (++mb_row < c->mb_rows) { - int mb_col = -1; - - while (++mb_col < c->mb_cols) { - const int ym = m->mbmi.mode; - - if (cpi->mb.e_mbd.update_mb_segmentation_map) { - write_mb_features(bc, &m->mbmi, &cpi->mb.e_mbd); - } - - if (c->mb_no_coeff_skip) { - vp8_encode_bool(bc, m->mbmi.mb_skip_coeff, prob_skip_false); - } - - kfwrite_ymode(bc, ym, vp8_kf_ymode_prob); - - if (ym == B_PRED) { - const int mis = c->mode_info_stride; - int i = 0; - - do { - const B_PREDICTION_MODE A = above_block_mode(m, i, mis); - const B_PREDICTION_MODE L = left_block_mode(m, i); - const int bm = m->bmi[i].as_mode; - - write_bmode(bc, bm, vp8_kf_bmode_prob[A][L]); - } while (++i < 16); - } - - write_uv_mode(bc, (m++)->mbmi.uv_mode, vp8_kf_uv_mode_prob); - } - - m++; /* skip L prediction border */ - } -} - -#if 0 -/* This function is used for debugging probability trees. */ -static void print_prob_tree(vp8_prob - coef_probs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES]) -{ - /* print coef probability tree */ - int i,j,k,l; - FILE* f = fopen("enc_tree_probs.txt", "a"); - fprintf(f, "{\n"); - for (i = 0; i < BLOCK_TYPES; ++i) - { - fprintf(f, " {\n"); - for (j = 0; j < COEF_BANDS; ++j) - { - fprintf(f, " {\n"); - for (k = 0; k < PREV_COEF_CONTEXTS; ++k) - { - fprintf(f, " {"); - for (l = 0; l < ENTROPY_NODES; ++l) - { - fprintf(f, "%3u, ", - (unsigned int)(coef_probs [i][j][k][l])); - } - fprintf(f, " }\n"); - } - fprintf(f, " }\n"); - } - fprintf(f, " }\n"); - } - fprintf(f, "}\n"); - fclose(f); -} -#endif - -static void sum_probs_over_prev_coef_context( - const unsigned int probs[PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS], - unsigned int *out) { - int i, j; - for (i = 0; i < MAX_ENTROPY_TOKENS; ++i) { - for (j = 0; j < PREV_COEF_CONTEXTS; ++j) { - const unsigned int tmp = out[i]; - out[i] += probs[j][i]; - /* check for wrap */ - if (out[i] < tmp) out[i] = UINT_MAX; - } - } -} - -static int prob_update_savings(const unsigned int *ct, const vp8_prob oldp, - const vp8_prob newp, const vp8_prob upd) { - const int old_b = vp8_cost_branch(ct, oldp); - const int new_b = vp8_cost_branch(ct, newp); - const int update_b = 8 + ((vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8); - - return old_b - new_b - update_b; -} - -static int independent_coef_context_savings(VP8_COMP *cpi) { - MACROBLOCK *const x = &cpi->mb; - int savings = 0; - int i = 0; - do { - int j = 0; - do { - int k = 0; - unsigned int prev_coef_count_sum[MAX_ENTROPY_TOKENS] = { 0 }; - int prev_coef_savings[MAX_ENTROPY_TOKENS] = { 0 }; - const unsigned int(*probs)[MAX_ENTROPY_TOKENS]; - /* Calculate new probabilities given the constraint that - * they must be equal over the prev coef contexts - */ - - probs = (const unsigned int(*)[MAX_ENTROPY_TOKENS])x->coef_counts[i][j]; - - /* Reset to default probabilities at key frames */ - if (cpi->common.frame_type == KEY_FRAME) { - probs = default_coef_counts[i][j]; - } - - sum_probs_over_prev_coef_context(probs, prev_coef_count_sum); - - do { - /* at every context */ - - /* calc probs and branch cts for this frame only */ - int t = 0; /* token/prob index */ - - vp8_tree_probs_from_distribution( - MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree, - cpi->frame_coef_probs[i][j][k], cpi->frame_branch_ct[i][j][k], - prev_coef_count_sum, 256, 1); - - do { - const unsigned int *ct = cpi->frame_branch_ct[i][j][k][t]; - const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t]; - const vp8_prob oldp = cpi->common.fc.coef_probs[i][j][k][t]; - const vp8_prob upd = vp8_coef_update_probs[i][j][k][t]; - const int s = prob_update_savings(ct, oldp, newp, upd); - - if (cpi->common.frame_type != KEY_FRAME || - (cpi->common.frame_type == KEY_FRAME && newp != oldp)) { - prev_coef_savings[t] += s; - } - } while (++t < ENTROPY_NODES); - } while (++k < PREV_COEF_CONTEXTS); - k = 0; - do { - /* We only update probabilities if we can save bits, except - * for key frames where we have to update all probabilities - * to get the equal probabilities across the prev coef - * contexts. - */ - if (prev_coef_savings[k] > 0 || cpi->common.frame_type == KEY_FRAME) { - savings += prev_coef_savings[k]; - } - } while (++k < ENTROPY_NODES); - } while (++j < COEF_BANDS); - } while (++i < BLOCK_TYPES); - return savings; -} - -static int default_coef_context_savings(VP8_COMP *cpi) { - MACROBLOCK *const x = &cpi->mb; - int savings = 0; - int i = 0; - do { - int j = 0; - do { - int k = 0; - do { - /* at every context */ - - /* calc probs and branch cts for this frame only */ - int t = 0; /* token/prob index */ - - vp8_tree_probs_from_distribution( - MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree, - cpi->frame_coef_probs[i][j][k], cpi->frame_branch_ct[i][j][k], - x->coef_counts[i][j][k], 256, 1); - - do { - const unsigned int *ct = cpi->frame_branch_ct[i][j][k][t]; - const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t]; - const vp8_prob oldp = cpi->common.fc.coef_probs[i][j][k][t]; - const vp8_prob upd = vp8_coef_update_probs[i][j][k][t]; - const int s = prob_update_savings(ct, oldp, newp, upd); - - if (s > 0) { - savings += s; - } - } while (++t < ENTROPY_NODES); - } while (++k < PREV_COEF_CONTEXTS); - } while (++j < COEF_BANDS); - } while (++i < BLOCK_TYPES); - return savings; -} - -void vp8_calc_ref_frame_costs(int *ref_frame_cost, int prob_intra, - int prob_last, int prob_garf) { - assert(prob_intra >= 0); - assert(prob_intra <= 255); - assert(prob_last >= 0); - assert(prob_last <= 255); - assert(prob_garf >= 0); - assert(prob_garf <= 255); - ref_frame_cost[INTRA_FRAME] = vp8_cost_zero(prob_intra); - ref_frame_cost[LAST_FRAME] = - vp8_cost_one(prob_intra) + vp8_cost_zero(prob_last); - ref_frame_cost[GOLDEN_FRAME] = vp8_cost_one(prob_intra) + - vp8_cost_one(prob_last) + - vp8_cost_zero(prob_garf); - ref_frame_cost[ALTREF_FRAME] = vp8_cost_one(prob_intra) + - vp8_cost_one(prob_last) + - vp8_cost_one(prob_garf); -} - -int vp8_estimate_entropy_savings(VP8_COMP *cpi) { - int savings = 0; - - const int *const rfct = cpi->mb.count_mb_ref_frame_usage; - const int rf_intra = rfct[INTRA_FRAME]; - const int rf_inter = - rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]; - int new_intra, new_last, new_garf, oldtotal, newtotal; - int ref_frame_cost[MAX_REF_FRAMES]; - - vpx_clear_system_state(); - - if (cpi->common.frame_type != KEY_FRAME) { - if (!(new_intra = rf_intra * 255 / (rf_intra + rf_inter))) new_intra = 1; - - new_last = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128; - - new_garf = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) - ? (rfct[GOLDEN_FRAME] * 255) / - (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) - : 128; - - vp8_calc_ref_frame_costs(ref_frame_cost, new_intra, new_last, new_garf); - - newtotal = rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] + - rfct[LAST_FRAME] * ref_frame_cost[LAST_FRAME] + - rfct[GOLDEN_FRAME] * ref_frame_cost[GOLDEN_FRAME] + - rfct[ALTREF_FRAME] * ref_frame_cost[ALTREF_FRAME]; - - /* old costs */ - vp8_calc_ref_frame_costs(ref_frame_cost, cpi->prob_intra_coded, - cpi->prob_last_coded, cpi->prob_gf_coded); - - oldtotal = rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] + - rfct[LAST_FRAME] * ref_frame_cost[LAST_FRAME] + - rfct[GOLDEN_FRAME] * ref_frame_cost[GOLDEN_FRAME] + - rfct[ALTREF_FRAME] * ref_frame_cost[ALTREF_FRAME]; - - savings += (oldtotal - newtotal) / 256; - } - - if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) { - savings += independent_coef_context_savings(cpi); - } else { - savings += default_coef_context_savings(cpi); - } - - return savings; -} - -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING -int vp8_update_coef_context(VP8_COMP *cpi) { - int savings = 0; - - if (cpi->common.frame_type == KEY_FRAME) { - /* Reset to default counts/probabilities at key frames */ - vp8_copy(cpi->mb.coef_counts, default_coef_counts); - } - - if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) - savings += independent_coef_context_savings(cpi); - else - savings += default_coef_context_savings(cpi); - - return savings; -} -#endif - -void vp8_update_coef_probs(VP8_COMP *cpi) { - int i = 0; -#if !(CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING) - vp8_writer *const w = cpi->bc; -#endif - - vpx_clear_system_state(); - - do { - int j = 0; - - do { - int k = 0; - int prev_coef_savings[ENTROPY_NODES] = { 0 }; - if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) { - for (k = 0; k < PREV_COEF_CONTEXTS; ++k) { - int t; /* token/prob index */ - for (t = 0; t < ENTROPY_NODES; ++t) { - const unsigned int *ct = cpi->frame_branch_ct[i][j][k][t]; - const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t]; - const vp8_prob oldp = cpi->common.fc.coef_probs[i][j][k][t]; - const vp8_prob upd = vp8_coef_update_probs[i][j][k][t]; - - prev_coef_savings[t] += prob_update_savings(ct, oldp, newp, upd); - } - } - k = 0; - } - do { - /* note: use result from vp8_estimate_entropy_savings, so no - * need to call vp8_tree_probs_from_distribution here. - */ - - /* at every context */ - - /* calc probs and branch cts for this frame only */ - int t = 0; /* token/prob index */ - - do { - const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t]; - - vp8_prob *Pold = cpi->common.fc.coef_probs[i][j][k] + t; - const vp8_prob upd = vp8_coef_update_probs[i][j][k][t]; - - int s = prev_coef_savings[t]; - int u = 0; - - if (!(cpi->oxcf.error_resilient_mode & - VPX_ERROR_RESILIENT_PARTITIONS)) { - s = prob_update_savings(cpi->frame_branch_ct[i][j][k][t], *Pold, - newp, upd); - } - - if (s > 0) u = 1; - - /* Force updates on key frames if the new is different, - * so that we can be sure we end up with equal probabilities - * over the prev coef contexts. - */ - if ((cpi->oxcf.error_resilient_mode & - VPX_ERROR_RESILIENT_PARTITIONS) && - cpi->common.frame_type == KEY_FRAME && newp != *Pold) { - u = 1; - } - -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING - cpi->update_probs[i][j][k][t] = u; -#else - vp8_write(w, u, upd); -#endif - - if (u) { - /* send/use new probability */ - - *Pold = newp; -#if !(CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING) - vp8_write_literal(w, newp, 8); -#endif - } - - } while (++t < ENTROPY_NODES); - - } while (++k < PREV_COEF_CONTEXTS); - } while (++j < COEF_BANDS); - } while (++i < BLOCK_TYPES); -} - -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING -static void pack_coef_probs(VP8_COMP *cpi) { - int i = 0; - vp8_writer *const w = cpi->bc; - - do { - int j = 0; - - do { - int k = 0; - - do { - int t = 0; /* token/prob index */ - - do { - const vp8_prob newp = cpi->common.fc.coef_probs[i][j][k][t]; - const vp8_prob upd = vp8_coef_update_probs[i][j][k][t]; - - const char u = cpi->update_probs[i][j][k][t]; - - vp8_write(w, u, upd); - - if (u) { - /* send/use new probability */ - vp8_write_literal(w, newp, 8); - } - } while (++t < ENTROPY_NODES); - } while (++k < PREV_COEF_CONTEXTS); - } while (++j < COEF_BANDS); - } while (++i < BLOCK_TYPES); -} -#endif - -#ifdef PACKET_TESTING -FILE *vpxlogc = 0; -#endif - -static void put_delta_q(vp8_writer *bc, int delta_q) { - if (delta_q != 0) { - vp8_write_bit(bc, 1); - vp8_write_literal(bc, abs(delta_q), 4); - - if (delta_q < 0) - vp8_write_bit(bc, 1); - else - vp8_write_bit(bc, 0); - } else - vp8_write_bit(bc, 0); -} - -void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, - unsigned char *dest_end, size_t *size) { - int i, j; - VP8_HEADER oh; - VP8_COMMON *const pc = &cpi->common; - vp8_writer *const bc = cpi->bc; - MACROBLOCKD *const xd = &cpi->mb.e_mbd; - int extra_bytes_packed = 0; - - unsigned char *cx_data = dest; - unsigned char *cx_data_end = dest_end; - const int *mb_feature_data_bits; - - oh.show_frame = (int)pc->show_frame; - oh.type = (int)pc->frame_type; - oh.version = pc->version; - oh.first_partition_length_in_bytes = 0; - - mb_feature_data_bits = vp8_mb_feature_data_bits; - - bc[0].error = &pc->error; - - validate_buffer(cx_data, 3, cx_data_end, &pc->error); - cx_data += 3; - -#if defined(SECTIONBITS_OUTPUT) - Sectionbits[active_section = 1] += sizeof(VP8_HEADER) * 8 * 256; -#endif - - /* every keyframe send startcode, width, height, scale factor, clamp - * and color type - */ - if (oh.type == KEY_FRAME) { - int v; - - validate_buffer(cx_data, 7, cx_data_end, &pc->error); - - /* Start / synch code */ - cx_data[0] = 0x9D; - cx_data[1] = 0x01; - cx_data[2] = 0x2a; - - /* Pack scale and frame size into 16 bits. Store it 8 bits at a time. - * https://tools.ietf.org/html/rfc6386 - * 9.1. Uncompressed Data Chunk - * 16 bits : (2 bits Horizontal Scale << 14) | Width (14 bits) - * 16 bits : (2 bits Vertical Scale << 14) | Height (14 bits) - */ - v = (pc->horiz_scale << 14) | pc->Width; - cx_data[3] = v & 0xff; - cx_data[4] = v >> 8; - - v = (pc->vert_scale << 14) | pc->Height; - cx_data[5] = v & 0xff; - cx_data[6] = v >> 8; - - extra_bytes_packed = 7; - cx_data += extra_bytes_packed; - - vp8_start_encode(bc, cx_data, cx_data_end); - - /* signal clr type */ - vp8_write_bit(bc, 0); - vp8_write_bit(bc, pc->clamp_type); - - } else { - vp8_start_encode(bc, cx_data, cx_data_end); - } - - /* Signal whether or not Segmentation is enabled */ - vp8_write_bit(bc, xd->segmentation_enabled); - - /* Indicate which features are enabled */ - if (xd->segmentation_enabled) { - /* Signal whether or not the segmentation map is being updated. */ - vp8_write_bit(bc, xd->update_mb_segmentation_map); - vp8_write_bit(bc, xd->update_mb_segmentation_data); - - if (xd->update_mb_segmentation_data) { - signed char Data; - - vp8_write_bit(bc, xd->mb_segment_abs_delta); - - /* For each segmentation feature (Quant and loop filter level) */ - for (i = 0; i < MB_LVL_MAX; ++i) { - /* For each of the segments */ - for (j = 0; j < MAX_MB_SEGMENTS; ++j) { - Data = xd->segment_feature_data[i][j]; - - /* Frame level data */ - if (Data) { - vp8_write_bit(bc, 1); - - if (Data < 0) { - Data = -Data; - vp8_write_literal(bc, Data, mb_feature_data_bits[i]); - vp8_write_bit(bc, 1); - } else { - vp8_write_literal(bc, Data, mb_feature_data_bits[i]); - vp8_write_bit(bc, 0); - } - } else - vp8_write_bit(bc, 0); - } - } - } - - if (xd->update_mb_segmentation_map) { - /* Write the probs used to decode the segment id for each mb */ - for (i = 0; i < MB_FEATURE_TREE_PROBS; ++i) { - int Data = xd->mb_segment_tree_probs[i]; - - if (Data != 255) { - vp8_write_bit(bc, 1); - vp8_write_literal(bc, Data, 8); - } else - vp8_write_bit(bc, 0); - } - } - } - - vp8_write_bit(bc, pc->filter_type); - vp8_write_literal(bc, pc->filter_level, 6); - vp8_write_literal(bc, pc->sharpness_level, 3); - - /* Write out loop filter deltas applied at the MB level based on mode - * or ref frame (if they are enabled). - */ - vp8_write_bit(bc, xd->mode_ref_lf_delta_enabled); - - if (xd->mode_ref_lf_delta_enabled) { - /* Do the deltas need to be updated */ - int send_update = - xd->mode_ref_lf_delta_update || cpi->oxcf.error_resilient_mode; - - vp8_write_bit(bc, send_update); - if (send_update) { - int Data; - - /* Send update */ - for (i = 0; i < MAX_REF_LF_DELTAS; ++i) { - Data = xd->ref_lf_deltas[i]; - - /* Frame level data */ - if (xd->ref_lf_deltas[i] != xd->last_ref_lf_deltas[i] || - cpi->oxcf.error_resilient_mode) { - xd->last_ref_lf_deltas[i] = xd->ref_lf_deltas[i]; - vp8_write_bit(bc, 1); - - if (Data > 0) { - vp8_write_literal(bc, (Data & 0x3F), 6); - vp8_write_bit(bc, 0); /* sign */ - } else { - Data = -Data; - vp8_write_literal(bc, (Data & 0x3F), 6); - vp8_write_bit(bc, 1); /* sign */ - } - } else - vp8_write_bit(bc, 0); - } - - /* Send update */ - for (i = 0; i < MAX_MODE_LF_DELTAS; ++i) { - Data = xd->mode_lf_deltas[i]; - - if (xd->mode_lf_deltas[i] != xd->last_mode_lf_deltas[i] || - cpi->oxcf.error_resilient_mode) { - xd->last_mode_lf_deltas[i] = xd->mode_lf_deltas[i]; - vp8_write_bit(bc, 1); - - if (Data > 0) { - vp8_write_literal(bc, (Data & 0x3F), 6); - vp8_write_bit(bc, 0); /* sign */ - } else { - Data = -Data; - vp8_write_literal(bc, (Data & 0x3F), 6); - vp8_write_bit(bc, 1); /* sign */ - } - } else - vp8_write_bit(bc, 0); - } - } - } - - /* signal here is multi token partition is enabled */ - vp8_write_literal(bc, pc->multi_token_partition, 2); - - /* Frame Qbaseline quantizer index */ - vp8_write_literal(bc, pc->base_qindex, 7); - - /* Transmit Dc, Second order and Uv quantizer delta information */ - put_delta_q(bc, pc->y1dc_delta_q); - put_delta_q(bc, pc->y2dc_delta_q); - put_delta_q(bc, pc->y2ac_delta_q); - put_delta_q(bc, pc->uvdc_delta_q); - put_delta_q(bc, pc->uvac_delta_q); - - /* When there is a key frame all reference buffers are updated using - * the new key frame - */ - if (pc->frame_type != KEY_FRAME) { - /* Should the GF or ARF be updated using the transmitted frame - * or buffer - */ - vp8_write_bit(bc, pc->refresh_golden_frame); - vp8_write_bit(bc, pc->refresh_alt_ref_frame); - - /* If not being updated from current frame should either GF or ARF - * be updated from another buffer - */ - if (!pc->refresh_golden_frame) - vp8_write_literal(bc, pc->copy_buffer_to_gf, 2); - - if (!pc->refresh_alt_ref_frame) - vp8_write_literal(bc, pc->copy_buffer_to_arf, 2); - - /* Indicate reference frame sign bias for Golden and ARF frames - * (always 0 for last frame buffer) - */ - vp8_write_bit(bc, pc->ref_frame_sign_bias[GOLDEN_FRAME]); - vp8_write_bit(bc, pc->ref_frame_sign_bias[ALTREF_FRAME]); - } - -#if !(CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING) - if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) { - if (pc->frame_type == KEY_FRAME) { - pc->refresh_entropy_probs = 1; - } else { - pc->refresh_entropy_probs = 0; - } - } -#endif - - vp8_write_bit(bc, pc->refresh_entropy_probs); - - if (pc->frame_type != KEY_FRAME) vp8_write_bit(bc, pc->refresh_last_frame); - - vpx_clear_system_state(); - -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING - pack_coef_probs(cpi); -#else - if (pc->refresh_entropy_probs == 0) { - /* save a copy for later refresh */ - pc->lfc = pc->fc; - } - - vp8_update_coef_probs(cpi); -#endif - - /* Write out the mb_no_coeff_skip flag */ - vp8_write_bit(bc, pc->mb_no_coeff_skip); - - if (pc->frame_type == KEY_FRAME) { - write_kfmodes(cpi); - } else { - pack_inter_mode_mvs(cpi); - } - - vp8_stop_encode(bc); - - cx_data += bc->pos; - - oh.first_partition_length_in_bytes = cpi->bc->pos; - - /* update frame tag */ - { - /* Pack partition size, show frame, version and frame type into to 24 bits. - * Store it 8 bits at a time. - * https://tools.ietf.org/html/rfc6386 - * 9.1. Uncompressed Data Chunk - * The uncompressed data chunk comprises a common (for key frames and - * interframes) 3-byte frame tag that contains four fields, as follows: - * - * 1. A 1-bit frame type (0 for key frames, 1 for interframes). - * - * 2. A 3-bit version number (0 - 3 are defined as four different - * profiles with different decoding complexity; other values may be - * defined for future variants of the VP8 data format). - * - * 3. A 1-bit show_frame flag (0 when current frame is not for display, - * 1 when current frame is for display). - * - * 4. A 19-bit field containing the size of the first data partition in - * bytes - */ - int v = (oh.first_partition_length_in_bytes << 5) | (oh.show_frame << 4) | - (oh.version << 1) | oh.type; - - dest[0] = v & 0xff; - dest[1] = (v >> 8) & 0xff; - dest[2] = v >> 16; - } - - *size = VP8_HEADER_SIZE + extra_bytes_packed + cpi->bc->pos; - - cpi->partition_sz[0] = (unsigned int)*size; - -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING - { - const int num_part = (1 << pc->multi_token_partition); - unsigned char *dp = cpi->partition_d[0] + cpi->partition_sz[0]; - - if (num_part > 1) { - /* write token part sizes (all but last) if more than 1 */ - validate_buffer(dp, 3 * (num_part - 1), cpi->partition_d_end[0], - &pc->error); - - cpi->partition_sz[0] += 3 * (num_part - 1); - - for (i = 1; i < num_part; ++i) { - write_partition_size(dp, cpi->partition_sz[i]); - dp += 3; - } - } - - if (!cpi->output_partition) { - /* concatenate partition buffers */ - for (i = 0; i < num_part; ++i) { - memmove(dp, cpi->partition_d[i + 1], cpi->partition_sz[i + 1]); - cpi->partition_d[i + 1] = dp; - dp += cpi->partition_sz[i + 1]; - } - } - - /* update total size */ - *size = 0; - for (i = 0; i < num_part + 1; ++i) { - *size += cpi->partition_sz[i]; - } - } -#else - if (pc->multi_token_partition != ONE_PARTITION) { - int num_part = 1 << pc->multi_token_partition; - - /* partition size table at the end of first partition */ - cpi->partition_sz[0] += 3 * (num_part - 1); - *size += 3 * (num_part - 1); - - validate_buffer(cx_data, 3 * (num_part - 1), cx_data_end, &pc->error); - - for (i = 1; i < num_part + 1; ++i) { - cpi->bc[i].error = &pc->error; - } - - pack_tokens_into_partitions(cpi, cx_data + 3 * (num_part - 1), cx_data_end, - num_part); - - for (i = 1; i < num_part; ++i) { - cpi->partition_sz[i] = cpi->bc[i].pos; - write_partition_size(cx_data, cpi->partition_sz[i]); - cx_data += 3; - *size += cpi->partition_sz[i]; /* add to total */ - } - - /* add last partition to total size */ - cpi->partition_sz[i] = cpi->bc[i].pos; - *size += cpi->partition_sz[i]; - } else { - bc[1].error = &pc->error; - - vp8_start_encode(&cpi->bc[1], cx_data, cx_data_end); - -#if CONFIG_MULTITHREAD - if (vpx_atomic_load_acquire(&cpi->b_multi_threaded)) { - pack_mb_row_tokens(cpi, &cpi->bc[1]); - } else { - vp8_pack_tokens(&cpi->bc[1], cpi->tok, cpi->tok_count); - } -#else - vp8_pack_tokens(&cpi->bc[1], cpi->tok, cpi->tok_count); -#endif // CONFIG_MULTITHREAD - - vp8_stop_encode(&cpi->bc[1]); - - *size += cpi->bc[1].pos; - cpi->partition_sz[1] = cpi->bc[1].pos; - } -#endif -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/bitstream.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/bitstream.h deleted file mode 100644 index ee3f3e4a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/bitstream.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_BITSTREAM_H_ -#define VPX_VP8_ENCODER_BITSTREAM_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "vp8/encoder/treewriter.h" -#include "vp8/encoder/tokenize.h" - -void vp8_pack_tokens(vp8_writer *w, const TOKENEXTRA *p, int xcount); -void vp8_convert_rfct_to_prob(struct VP8_COMP *const cpi); -void vp8_calc_ref_frame_costs(int *ref_frame_cost, int prob_intra, - int prob_last, int prob_garf); -int vp8_estimate_entropy_savings(struct VP8_COMP *cpi); -void vp8_update_coef_probs(struct VP8_COMP *cpi); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_BITSTREAM_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/block.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/block.h deleted file mode 100644 index 1bc5ef75..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/block.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_BLOCK_H_ -#define VPX_VP8_ENCODER_BLOCK_H_ - -#include "vp8/common/onyx.h" -#include "vp8/common/blockd.h" -#include "vp8/common/entropymv.h" -#include "vp8/common/entropy.h" -#include "vpx_ports/mem.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_MODES 20 -#define MAX_ERROR_BINS 1024 - -/* motion search site */ -typedef struct { - MV mv; - int offset; -} search_site; - -typedef struct block { - /* 16 Y blocks, 4 U blocks, 4 V blocks each with 16 entries */ - short *src_diff; - short *coeff; - - /* 16 Y blocks, 4 U blocks, 4 V blocks each with 16 entries */ - short *quant; - short *quant_fast; - short *quant_shift; - short *zbin; - short *zrun_zbin_boost; - short *round; - - /* Zbin Over Quant value */ - short zbin_extra; - - unsigned char **base_src; - int src; - int src_stride; -} BLOCK; - -typedef struct { - int count; - struct { - B_PREDICTION_MODE mode; - int_mv mv; - } bmi[16]; -} PARTITION_INFO; - -typedef struct macroblock { - DECLARE_ALIGNED(16, short, src_diff[400]); /* 25 blocks Y,U,V,Y2 */ - DECLARE_ALIGNED(16, short, coeff[400]); /* 25 blocks Y,U,V,Y2 */ - DECLARE_ALIGNED(16, unsigned char, thismb[256]); - - unsigned char *thismb_ptr; - /* 16 Y, 4 U, 4 V, 1 DC 2nd order block */ - BLOCK block[25]; - - YV12_BUFFER_CONFIG src; - - MACROBLOCKD e_mbd; - PARTITION_INFO *partition_info; /* work pointer */ - PARTITION_INFO *pi; /* Corresponds to upper left visible macroblock */ - PARTITION_INFO *pip; /* Base of allocated array */ - - int ref_frame_cost[MAX_REF_FRAMES]; - - search_site *ss; - int ss_count; - int searches_per_step; - - int errorperbit; - int sadperbit16; - int sadperbit4; - int rddiv; - int rdmult; - unsigned int *mb_activity_ptr; - int *mb_norm_activity_ptr; - signed int act_zbin_adj; - signed int last_act_zbin_adj; - - int *mvcost[2]; - int *mvsadcost[2]; - int (*mbmode_cost)[MB_MODE_COUNT]; - int (*intra_uv_mode_cost)[MB_MODE_COUNT]; - int (*bmode_costs)[10][10]; - int *inter_bmode_costs; - int (*token_costs)[COEF_BANDS][PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS]; - - /* These define limits to motion vector components to prevent - * them from extending outside the UMV borders. - */ - int mv_col_min; - int mv_col_max; - int mv_row_min; - int mv_row_max; - - int skip; - - unsigned int encode_breakout; - - signed char *gf_active_ptr; - - unsigned char *active_ptr; - MV_CONTEXT *mvc; - - int optimize; - int q_index; - int is_skin; - int denoise_zeromv; - -#if CONFIG_TEMPORAL_DENOISING - int increase_denoising; - MB_PREDICTION_MODE best_sse_inter_mode; - int_mv best_sse_mv; - MV_REFERENCE_FRAME best_reference_frame; - MV_REFERENCE_FRAME best_zeromv_reference_frame; - unsigned char need_to_clamp_best_mvs; -#endif - - int skip_true_count; - unsigned int coef_counts[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS] - [MAX_ENTROPY_TOKENS]; - unsigned int MVcount[2][MVvals]; /* (row,col) MV cts this frame */ - int ymode_count[VP8_YMODES]; /* intra MB type cts this frame */ - int uv_mode_count[VP8_UV_MODES]; /* intra MB type cts this frame */ - int64_t prediction_error; - int64_t intra_error; - int count_mb_ref_frame_usage[MAX_REF_FRAMES]; - - int rd_thresh_mult[MAX_MODES]; - int rd_threshes[MAX_MODES]; - unsigned int mbs_tested_so_far; - unsigned int mode_test_hit_counts[MAX_MODES]; - int zbin_mode_boost_enabled; - int zbin_mode_boost; - int last_zbin_mode_boost; - - int last_zbin_over_quant; - int zbin_over_quant; - int error_bins[MAX_ERROR_BINS]; - - void (*short_fdct4x4)(short *input, short *output, int pitch); - void (*short_fdct8x4)(short *input, short *output, int pitch); - void (*short_walsh4x4)(short *input, short *output, int pitch); - void (*quantize_b)(BLOCK *b, BLOCKD *d); - - unsigned int mbs_zero_last_dot_suppress; - int zero_last_dot_suppress; -} MACROBLOCK; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_BLOCK_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/boolhuff.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/boolhuff.c deleted file mode 100644 index 819c2f22..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/boolhuff.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "boolhuff.h" - -#if defined(SECTIONBITS_OUTPUT) -unsigned __int64 Sectionbits[500]; - -#endif - -const unsigned int vp8_prob_cost[256] = { - 2047, 2047, 1791, 1641, 1535, 1452, 1385, 1328, 1279, 1235, 1196, 1161, 1129, - 1099, 1072, 1046, 1023, 1000, 979, 959, 940, 922, 905, 889, 873, 858, - 843, 829, 816, 803, 790, 778, 767, 755, 744, 733, 723, 713, 703, - 693, 684, 675, 666, 657, 649, 641, 633, 625, 617, 609, 602, 594, - 587, 580, 573, 567, 560, 553, 547, 541, 534, 528, 522, 516, 511, - 505, 499, 494, 488, 483, 477, 472, 467, 462, 457, 452, 447, 442, - 437, 433, 428, 424, 419, 415, 410, 406, 401, 397, 393, 389, 385, - 381, 377, 373, 369, 365, 361, 357, 353, 349, 346, 342, 338, 335, - 331, 328, 324, 321, 317, 314, 311, 307, 304, 301, 297, 294, 291, - 288, 285, 281, 278, 275, 272, 269, 266, 263, 260, 257, 255, 252, - 249, 246, 243, 240, 238, 235, 232, 229, 227, 224, 221, 219, 216, - 214, 211, 208, 206, 203, 201, 198, 196, 194, 191, 189, 186, 184, - 181, 179, 177, 174, 172, 170, 168, 165, 163, 161, 159, 156, 154, - 152, 150, 148, 145, 143, 141, 139, 137, 135, 133, 131, 129, 127, - 125, 123, 121, 119, 117, 115, 113, 111, 109, 107, 105, 103, 101, - 99, 97, 95, 93, 92, 90, 88, 86, 84, 82, 81, 79, 77, - 75, 73, 72, 70, 68, 66, 65, 63, 61, 60, 58, 56, 55, - 53, 51, 50, 48, 46, 45, 43, 41, 40, 38, 37, 35, 33, - 32, 30, 29, 27, 25, 24, 22, 21, 19, 18, 16, 15, 13, - 12, 10, 9, 7, 6, 4, 3, 1, 1 -}; - -void vp8_start_encode(BOOL_CODER *bc, unsigned char *source, - unsigned char *source_end) { - bc->lowvalue = 0; - bc->range = 255; - bc->count = -24; - bc->buffer = source; - bc->buffer_end = source_end; - bc->pos = 0; -} - -void vp8_stop_encode(BOOL_CODER *bc) { - int i; - - for (i = 0; i < 32; ++i) vp8_encode_bool(bc, 0, 128); -} - -void vp8_encode_value(BOOL_CODER *bc, int data, int bits) { - int bit; - - for (bit = bits - 1; bit >= 0; bit--) { - vp8_encode_bool(bc, (1 & (data >> bit)), 0x80); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/boolhuff.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/boolhuff.h deleted file mode 100644 index a8c536b9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/boolhuff.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/**************************************************************************** - * - * Module Title : boolhuff.h - * - * Description : Bool Coder header file. - * - ****************************************************************************/ -#ifndef VPX_VP8_ENCODER_BOOLHUFF_H_ -#define VPX_VP8_ENCODER_BOOLHUFF_H_ - -#include "vpx_ports/mem.h" -#include "vpx/internal/vpx_codec_internal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - unsigned int lowvalue; - unsigned int range; - int count; - unsigned int pos; - unsigned char *buffer; - unsigned char *buffer_end; - struct vpx_internal_error_info *error; -} BOOL_CODER; - -void vp8_start_encode(BOOL_CODER *bc, unsigned char *source, - unsigned char *source_end); - -void vp8_encode_value(BOOL_CODER *bc, int data, int bits); -void vp8_stop_encode(BOOL_CODER *bc); -extern const unsigned int vp8_prob_cost[256]; - -DECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]); - -static int validate_buffer(const unsigned char *start, size_t len, - const unsigned char *end, - struct vpx_internal_error_info *error) { - if (start + len > start && start + len < end) { - return 1; - } else { - vpx_internal_error(error, VPX_CODEC_CORRUPT_FRAME, - "Truncated packet or corrupt partition "); - } - - return 0; -} -static void vp8_encode_bool(BOOL_CODER *bc, int bit, int probability) { - unsigned int split; - int count = bc->count; - unsigned int range = bc->range; - unsigned int lowvalue = bc->lowvalue; - int shift; - - split = 1 + (((range - 1) * probability) >> 8); - - range = split; - - if (bit) { - lowvalue += split; - range = bc->range - split; - } - - shift = vp8_norm[range]; - - range <<= shift; - count += shift; - - if (count >= 0) { - int offset = shift - count; - - if ((lowvalue << (offset - 1)) & 0x80000000) { - int x = bc->pos - 1; - - while (x >= 0 && bc->buffer[x] == 0xff) { - bc->buffer[x] = (unsigned char)0; - x--; - } - - bc->buffer[x] += 1; - } - - validate_buffer(bc->buffer + bc->pos, 1, bc->buffer_end, bc->error); - bc->buffer[bc->pos++] = (lowvalue >> (24 - offset) & 0xff); - - shift = count; - lowvalue = (int)(((uint64_t)lowvalue << offset) & 0xffffff); - count -= 8; - } - - lowvalue <<= shift; - bc->count = count; - bc->lowvalue = lowvalue; - bc->range = range; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_BOOLHUFF_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/copy_c.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/copy_c.c deleted file mode 100644 index 47461252..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/copy_c.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp8_rtcd.h" -#include "vpx/vpx_integer.h" - -/* Copy 2 macroblocks to a buffer */ -void vp8_copy32xn_c(const unsigned char *src_ptr, int src_stride, - unsigned char *dst_ptr, int dst_stride, int height) { - int r; - - for (r = 0; r < height; ++r) { - memcpy(dst_ptr, src_ptr, 32); - - src_ptr += src_stride; - dst_ptr += dst_stride; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/dct.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/dct.c deleted file mode 100644 index 7d214eaf..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/dct.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp8_rtcd.h" - -void vp8_short_fdct4x4_c(short *input, short *output, int pitch) { - int i; - int a1, b1, c1, d1; - short *ip = input; - short *op = output; - - for (i = 0; i < 4; ++i) { - a1 = ((ip[0] + ip[3]) * 8); - b1 = ((ip[1] + ip[2]) * 8); - c1 = ((ip[1] - ip[2]) * 8); - d1 = ((ip[0] - ip[3]) * 8); - - op[0] = a1 + b1; - op[2] = a1 - b1; - - op[1] = (c1 * 2217 + d1 * 5352 + 14500) >> 12; - op[3] = (d1 * 2217 - c1 * 5352 + 7500) >> 12; - - ip += pitch / 2; - op += 4; - } - ip = output; - op = output; - for (i = 0; i < 4; ++i) { - a1 = ip[0] + ip[12]; - b1 = ip[4] + ip[8]; - c1 = ip[4] - ip[8]; - d1 = ip[0] - ip[12]; - - op[0] = (a1 + b1 + 7) >> 4; - op[8] = (a1 - b1 + 7) >> 4; - - op[4] = ((c1 * 2217 + d1 * 5352 + 12000) >> 16) + (d1 != 0); - op[12] = (d1 * 2217 - c1 * 5352 + 51000) >> 16; - - ip++; - op++; - } -} - -void vp8_short_fdct8x4_c(short *input, short *output, int pitch) { - vp8_short_fdct4x4_c(input, output, pitch); - vp8_short_fdct4x4_c(input + 4, output + 16, pitch); -} - -void vp8_short_walsh4x4_c(short *input, short *output, int pitch) { - int i; - int a1, b1, c1, d1; - int a2, b2, c2, d2; - short *ip = input; - short *op = output; - - for (i = 0; i < 4; ++i) { - a1 = ((ip[0] + ip[2]) * 4); - d1 = ((ip[1] + ip[3]) * 4); - c1 = ((ip[1] - ip[3]) * 4); - b1 = ((ip[0] - ip[2]) * 4); - - op[0] = a1 + d1 + (a1 != 0); - op[1] = b1 + c1; - op[2] = b1 - c1; - op[3] = a1 - d1; - ip += pitch / 2; - op += 4; - } - - ip = output; - op = output; - - for (i = 0; i < 4; ++i) { - a1 = ip[0] + ip[8]; - d1 = ip[4] + ip[12]; - c1 = ip[4] - ip[12]; - b1 = ip[0] - ip[8]; - - a2 = a1 + d1; - b2 = b1 + c1; - c2 = b1 - c1; - d2 = a1 - d1; - - a2 += a2 < 0; - b2 += b2 < 0; - c2 += c2 < 0; - d2 += d2 < 0; - - op[0] = (a2 + 3) >> 3; - op[4] = (b2 + 3) >> 3; - op[8] = (c2 + 3) >> 3; - op[12] = (d2 + 3) >> 3; - - ip++; - op++; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/dct_value_cost.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/dct_value_cost.h deleted file mode 100644 index 0cd6cb4e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/dct_value_cost.h +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_DCT_VALUE_COST_H_ -#define VPX_VP8_ENCODER_DCT_VALUE_COST_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Generated file, included by tokenize.c */ -/* Values generated by fill_value_tokens() */ - -static const short dct_value_cost[2048 * 2] = { - 8285, 8277, 8267, 8259, 8253, 8245, 8226, 8218, 8212, 8204, 8194, 8186, 8180, - 8172, 8150, 8142, 8136, 8128, 8118, 8110, 8104, 8096, 8077, 8069, 8063, 8055, - 8045, 8037, 8031, 8023, 7997, 7989, 7983, 7975, 7965, 7957, 7951, 7943, 7924, - 7916, 7910, 7902, 7892, 7884, 7878, 7870, 7848, 7840, 7834, 7826, 7816, 7808, - 7802, 7794, 7775, 7767, 7761, 7753, 7743, 7735, 7729, 7721, 7923, 7915, 7909, - 7901, 7891, 7883, 7877, 7869, 7850, 7842, 7836, 7828, 7818, 7810, 7804, 7796, - 7774, 7766, 7760, 7752, 7742, 7734, 7728, 7720, 7701, 7693, 7687, 7679, 7669, - 7661, 7655, 7647, 7621, 7613, 7607, 7599, 7589, 7581, 7575, 7567, 7548, 7540, - 7534, 7526, 7516, 7508, 7502, 7494, 7472, 7464, 7458, 7450, 7440, 7432, 7426, - 7418, 7399, 7391, 7385, 7377, 7367, 7359, 7353, 7345, 7479, 7471, 7465, 7457, - 7447, 7439, 7433, 7425, 7406, 7398, 7392, 7384, 7374, 7366, 7360, 7352, 7330, - 7322, 7316, 7308, 7298, 7290, 7284, 7276, 7257, 7249, 7243, 7235, 7225, 7217, - 7211, 7203, 7177, 7169, 7163, 7155, 7145, 7137, 7131, 7123, 7104, 7096, 7090, - 7082, 7072, 7064, 7058, 7050, 7028, 7020, 7014, 7006, 6996, 6988, 6982, 6974, - 6955, 6947, 6941, 6933, 6923, 6915, 6909, 6901, 7632, 7624, 7618, 7610, 7600, - 7592, 7586, 7578, 7559, 7551, 7545, 7537, 7527, 7519, 7513, 7505, 7483, 7475, - 7469, 7461, 7451, 7443, 7437, 7429, 7410, 7402, 7396, 7388, 7378, 7370, 7364, - 7356, 7330, 7322, 7316, 7308, 7298, 7290, 7284, 7276, 7257, 7249, 7243, 7235, - 7225, 7217, 7211, 7203, 7181, 7173, 7167, 7159, 7149, 7141, 7135, 7127, 7108, - 7100, 7094, 7086, 7076, 7068, 7062, 7054, 7188, 7180, 7174, 7166, 7156, 7148, - 7142, 7134, 7115, 7107, 7101, 7093, 7083, 7075, 7069, 7061, 7039, 7031, 7025, - 7017, 7007, 6999, 6993, 6985, 6966, 6958, 6952, 6944, 6934, 6926, 6920, 6912, - 6886, 6878, 6872, 6864, 6854, 6846, 6840, 6832, 6813, 6805, 6799, 6791, 6781, - 6773, 6767, 6759, 6737, 6729, 6723, 6715, 6705, 6697, 6691, 6683, 6664, 6656, - 6650, 6642, 6632, 6624, 6618, 6610, 6812, 6804, 6798, 6790, 6780, 6772, 6766, - 6758, 6739, 6731, 6725, 6717, 6707, 6699, 6693, 6685, 6663, 6655, 6649, 6641, - 6631, 6623, 6617, 6609, 6590, 6582, 6576, 6568, 6558, 6550, 6544, 6536, 6510, - 6502, 6496, 6488, 6478, 6470, 6464, 6456, 6437, 6429, 6423, 6415, 6405, 6397, - 6391, 6383, 6361, 6353, 6347, 6339, 6329, 6321, 6315, 6307, 6288, 6280, 6274, - 6266, 6256, 6248, 6242, 6234, 6368, 6360, 6354, 6346, 6336, 6328, 6322, 6314, - 6295, 6287, 6281, 6273, 6263, 6255, 6249, 6241, 6219, 6211, 6205, 6197, 6187, - 6179, 6173, 6165, 6146, 6138, 6132, 6124, 6114, 6106, 6100, 6092, 6066, 6058, - 6052, 6044, 6034, 6026, 6020, 6012, 5993, 5985, 5979, 5971, 5961, 5953, 5947, - 5939, 5917, 5909, 5903, 5895, 5885, 5877, 5871, 5863, 5844, 5836, 5830, 5822, - 5812, 5804, 5798, 5790, 6697, 6689, 6683, 6675, 6665, 6657, 6651, 6643, 6624, - 6616, 6610, 6602, 6592, 6584, 6578, 6570, 6548, 6540, 6534, 6526, 6516, 6508, - 6502, 6494, 6475, 6467, 6461, 6453, 6443, 6435, 6429, 6421, 6395, 6387, 6381, - 6373, 6363, 6355, 6349, 6341, 6322, 6314, 6308, 6300, 6290, 6282, 6276, 6268, - 6246, 6238, 6232, 6224, 6214, 6206, 6200, 6192, 6173, 6165, 6159, 6151, 6141, - 6133, 6127, 6119, 6253, 6245, 6239, 6231, 6221, 6213, 6207, 6199, 6180, 6172, - 6166, 6158, 6148, 6140, 6134, 6126, 6104, 6096, 6090, 6082, 6072, 6064, 6058, - 6050, 6031, 6023, 6017, 6009, 5999, 5991, 5985, 5977, 5951, 5943, 5937, 5929, - 5919, 5911, 5905, 5897, 5878, 5870, 5864, 5856, 5846, 5838, 5832, 5824, 5802, - 5794, 5788, 5780, 5770, 5762, 5756, 5748, 5729, 5721, 5715, 5707, 5697, 5689, - 5683, 5675, 5877, 5869, 5863, 5855, 5845, 5837, 5831, 5823, 5804, 5796, 5790, - 5782, 5772, 5764, 5758, 5750, 5728, 5720, 5714, 5706, 5696, 5688, 5682, 5674, - 5655, 5647, 5641, 5633, 5623, 5615, 5609, 5601, 5575, 5567, 5561, 5553, 5543, - 5535, 5529, 5521, 5502, 5494, 5488, 5480, 5470, 5462, 5456, 5448, 5426, 5418, - 5412, 5404, 5394, 5386, 5380, 5372, 5353, 5345, 5339, 5331, 5321, 5313, 5307, - 5299, 5433, 5425, 5419, 5411, 5401, 5393, 5387, 5379, 5360, 5352, 5346, 5338, - 5328, 5320, 5314, 5306, 5284, 5276, 5270, 5262, 5252, 5244, 5238, 5230, 5211, - 5203, 5197, 5189, 5179, 5171, 5165, 5157, 5131, 5123, 5117, 5109, 5099, 5091, - 5085, 5077, 5058, 5050, 5044, 5036, 5026, 5018, 5012, 5004, 4982, 4974, 4968, - 4960, 4950, 4942, 4936, 4928, 4909, 4901, 4895, 4887, 4877, 4869, 4863, 4855, - 5586, 5578, 5572, 5564, 5554, 5546, 5540, 5532, 5513, 5505, 5499, 5491, 5481, - 5473, 5467, 5459, 5437, 5429, 5423, 5415, 5405, 5397, 5391, 5383, 5364, 5356, - 5350, 5342, 5332, 5324, 5318, 5310, 5284, 5276, 5270, 5262, 5252, 5244, 5238, - 5230, 5211, 5203, 5197, 5189, 5179, 5171, 5165, 5157, 5135, 5127, 5121, 5113, - 5103, 5095, 5089, 5081, 5062, 5054, 5048, 5040, 5030, 5022, 5016, 5008, 5142, - 5134, 5128, 5120, 5110, 5102, 5096, 5088, 5069, 5061, 5055, 5047, 5037, 5029, - 5023, 5015, 4993, 4985, 4979, 4971, 4961, 4953, 4947, 4939, 4920, 4912, 4906, - 4898, 4888, 4880, 4874, 4866, 4840, 4832, 4826, 4818, 4808, 4800, 4794, 4786, - 4767, 4759, 4753, 4745, 4735, 4727, 4721, 4713, 4691, 4683, 4677, 4669, 4659, - 4651, 4645, 4637, 4618, 4610, 4604, 4596, 4586, 4578, 4572, 4564, 4766, 4758, - 4752, 4744, 4734, 4726, 4720, 4712, 4693, 4685, 4679, 4671, 4661, 4653, 4647, - 4639, 4617, 4609, 4603, 4595, 4585, 4577, 4571, 4563, 4544, 4536, 4530, 4522, - 4512, 4504, 4498, 4490, 4464, 4456, 4450, 4442, 4432, 4424, 4418, 4410, 4391, - 4383, 4377, 4369, 4359, 4351, 4345, 4337, 4315, 4307, 4301, 4293, 4283, 4275, - 4269, 4261, 4242, 4234, 4228, 4220, 4210, 4202, 4196, 4188, 4322, 4314, 4308, - 4300, 4290, 4282, 4276, 4268, 4249, 4241, 4235, 4227, 4217, 4209, 4203, 4195, - 4173, 4165, 4159, 4151, 4141, 4133, 4127, 4119, 4100, 4092, 4086, 4078, 4068, - 4060, 4054, 4046, 4020, 4012, 4006, 3998, 3988, 3980, 3974, 3966, 3947, 3939, - 3933, 3925, 3915, 3907, 3901, 3893, 3871, 3863, 3857, 3849, 3839, 3831, 3825, - 3817, 3798, 3790, 3784, 3776, 3766, 3758, 3752, 3744, 6697, 6689, 6683, 6675, - 6665, 6657, 6651, 6643, 6624, 6616, 6610, 6602, 6592, 6584, 6578, 6570, 6548, - 6540, 6534, 6526, 6516, 6508, 6502, 6494, 6475, 6467, 6461, 6453, 6443, 6435, - 6429, 6421, 6395, 6387, 6381, 6373, 6363, 6355, 6349, 6341, 6322, 6314, 6308, - 6300, 6290, 6282, 6276, 6268, 6246, 6238, 6232, 6224, 6214, 6206, 6200, 6192, - 6173, 6165, 6159, 6151, 6141, 6133, 6127, 6119, 6253, 6245, 6239, 6231, 6221, - 6213, 6207, 6199, 6180, 6172, 6166, 6158, 6148, 6140, 6134, 6126, 6104, 6096, - 6090, 6082, 6072, 6064, 6058, 6050, 6031, 6023, 6017, 6009, 5999, 5991, 5985, - 5977, 5951, 5943, 5937, 5929, 5919, 5911, 5905, 5897, 5878, 5870, 5864, 5856, - 5846, 5838, 5832, 5824, 5802, 5794, 5788, 5780, 5770, 5762, 5756, 5748, 5729, - 5721, 5715, 5707, 5697, 5689, 5683, 5675, 5877, 5869, 5863, 5855, 5845, 5837, - 5831, 5823, 5804, 5796, 5790, 5782, 5772, 5764, 5758, 5750, 5728, 5720, 5714, - 5706, 5696, 5688, 5682, 5674, 5655, 5647, 5641, 5633, 5623, 5615, 5609, 5601, - 5575, 5567, 5561, 5553, 5543, 5535, 5529, 5521, 5502, 5494, 5488, 5480, 5470, - 5462, 5456, 5448, 5426, 5418, 5412, 5404, 5394, 5386, 5380, 5372, 5353, 5345, - 5339, 5331, 5321, 5313, 5307, 5299, 5433, 5425, 5419, 5411, 5401, 5393, 5387, - 5379, 5360, 5352, 5346, 5338, 5328, 5320, 5314, 5306, 5284, 5276, 5270, 5262, - 5252, 5244, 5238, 5230, 5211, 5203, 5197, 5189, 5179, 5171, 5165, 5157, 5131, - 5123, 5117, 5109, 5099, 5091, 5085, 5077, 5058, 5050, 5044, 5036, 5026, 5018, - 5012, 5004, 4982, 4974, 4968, 4960, 4950, 4942, 4936, 4928, 4909, 4901, 4895, - 4887, 4877, 4869, 4863, 4855, 5586, 5578, 5572, 5564, 5554, 5546, 5540, 5532, - 5513, 5505, 5499, 5491, 5481, 5473, 5467, 5459, 5437, 5429, 5423, 5415, 5405, - 5397, 5391, 5383, 5364, 5356, 5350, 5342, 5332, 5324, 5318, 5310, 5284, 5276, - 5270, 5262, 5252, 5244, 5238, 5230, 5211, 5203, 5197, 5189, 5179, 5171, 5165, - 5157, 5135, 5127, 5121, 5113, 5103, 5095, 5089, 5081, 5062, 5054, 5048, 5040, - 5030, 5022, 5016, 5008, 5142, 5134, 5128, 5120, 5110, 5102, 5096, 5088, 5069, - 5061, 5055, 5047, 5037, 5029, 5023, 5015, 4993, 4985, 4979, 4971, 4961, 4953, - 4947, 4939, 4920, 4912, 4906, 4898, 4888, 4880, 4874, 4866, 4840, 4832, 4826, - 4818, 4808, 4800, 4794, 4786, 4767, 4759, 4753, 4745, 4735, 4727, 4721, 4713, - 4691, 4683, 4677, 4669, 4659, 4651, 4645, 4637, 4618, 4610, 4604, 4596, 4586, - 4578, 4572, 4564, 4766, 4758, 4752, 4744, 4734, 4726, 4720, 4712, 4693, 4685, - 4679, 4671, 4661, 4653, 4647, 4639, 4617, 4609, 4603, 4595, 4585, 4577, 4571, - 4563, 4544, 4536, 4530, 4522, 4512, 4504, 4498, 4490, 4464, 4456, 4450, 4442, - 4432, 4424, 4418, 4410, 4391, 4383, 4377, 4369, 4359, 4351, 4345, 4337, 4315, - 4307, 4301, 4293, 4283, 4275, 4269, 4261, 4242, 4234, 4228, 4220, 4210, 4202, - 4196, 4188, 4322, 4314, 4308, 4300, 4290, 4282, 4276, 4268, 4249, 4241, 4235, - 4227, 4217, 4209, 4203, 4195, 4173, 4165, 4159, 4151, 4141, 4133, 4127, 4119, - 4100, 4092, 4086, 4078, 4068, 4060, 4054, 4046, 4020, 4012, 4006, 3998, 3988, - 3980, 3974, 3966, 3947, 3939, 3933, 3925, 3915, 3907, 3901, 3893, 3871, 3863, - 3857, 3849, 3839, 3831, 3825, 3817, 3798, 3790, 3784, 3776, 3766, 3758, 3752, - 3744, 4651, 4643, 4637, 4629, 4619, 4611, 4605, 4597, 4578, 4570, 4564, 4556, - 4546, 4538, 4532, 4524, 4502, 4494, 4488, 4480, 4470, 4462, 4456, 4448, 4429, - 4421, 4415, 4407, 4397, 4389, 4383, 4375, 4349, 4341, 4335, 4327, 4317, 4309, - 4303, 4295, 4276, 4268, 4262, 4254, 4244, 4236, 4230, 4222, 4200, 4192, 4186, - 4178, 4168, 4160, 4154, 4146, 4127, 4119, 4113, 4105, 4095, 4087, 4081, 4073, - 4207, 4199, 4193, 4185, 4175, 4167, 4161, 4153, 4134, 4126, 4120, 4112, 4102, - 4094, 4088, 4080, 4058, 4050, 4044, 4036, 4026, 4018, 4012, 4004, 3985, 3977, - 3971, 3963, 3953, 3945, 3939, 3931, 3905, 3897, 3891, 3883, 3873, 3865, 3859, - 3851, 3832, 3824, 3818, 3810, 3800, 3792, 3786, 3778, 3756, 3748, 3742, 3734, - 3724, 3716, 3710, 3702, 3683, 3675, 3669, 3661, 3651, 3643, 3637, 3629, 3831, - 3823, 3817, 3809, 3799, 3791, 3785, 3777, 3758, 3750, 3744, 3736, 3726, 3718, - 3712, 3704, 3682, 3674, 3668, 3660, 3650, 3642, 3636, 3628, 3609, 3601, 3595, - 3587, 3577, 3569, 3563, 3555, 3529, 3521, 3515, 3507, 3497, 3489, 3483, 3475, - 3456, 3448, 3442, 3434, 3424, 3416, 3410, 3402, 3380, 3372, 3366, 3358, 3348, - 3340, 3334, 3326, 3307, 3299, 3293, 3285, 3275, 3267, 3261, 3253, 3387, 3379, - 3373, 3365, 3355, 3347, 3341, 3333, 3314, 3306, 3300, 3292, 3282, 3274, 3268, - 3260, 3238, 3230, 3224, 3216, 3206, 3198, 3192, 3184, 3165, 3157, 3151, 3143, - 3133, 3125, 3119, 3111, 3085, 3077, 3071, 3063, 3053, 3045, 3039, 3031, 3012, - 3004, 2998, 2990, 2980, 2972, 2966, 2958, 2936, 2928, 2922, 2914, 2904, 2896, - 2890, 2882, 2863, 2855, 2849, 2841, 2831, 2823, 2817, 2809, 3540, 3532, 3526, - 3518, 3508, 3500, 3494, 3486, 3467, 3459, 3453, 3445, 3435, 3427, 3421, 3413, - 3391, 3383, 3377, 3369, 3359, 3351, 3345, 3337, 3318, 3310, 3304, 3296, 3286, - 3278, 3272, 3264, 3238, 3230, 3224, 3216, 3206, 3198, 3192, 3184, 3165, 3157, - 3151, 3143, 3133, 3125, 3119, 3111, 3089, 3081, 3075, 3067, 3057, 3049, 3043, - 3035, 3016, 3008, 3002, 2994, 2984, 2976, 2970, 2962, 3096, 3088, 3082, 3074, - 3064, 3056, 3050, 3042, 3023, 3015, 3009, 3001, 2991, 2983, 2977, 2969, 2947, - 2939, 2933, 2925, 2915, 2907, 2901, 2893, 2874, 2866, 2860, 2852, 2842, 2834, - 2828, 2820, 2794, 2786, 2780, 2772, 2762, 2754, 2748, 2740, 2721, 2713, 2707, - 2699, 2689, 2681, 2675, 2667, 2645, 2637, 2631, 2623, 2613, 2605, 2599, 2591, - 2572, 2564, 2558, 2550, 2540, 2532, 2526, 2518, 2720, 2712, 2706, 2698, 2688, - 2680, 2674, 2666, 2647, 2639, 2633, 2625, 2615, 2607, 2601, 2593, 2571, 2563, - 2557, 2549, 2539, 2531, 2525, 2517, 2498, 2490, 2484, 2476, 2466, 2458, 2452, - 2444, 2418, 2410, 2404, 2396, 2386, 2378, 2372, 2364, 2345, 2337, 2331, 2323, - 2313, 2305, 2299, 2291, 2269, 2261, 2255, 2247, 2237, 2229, 2223, 2215, 2196, - 2188, 2182, 2174, 2164, 2156, 2150, 2142, 2276, 2268, 2262, 2254, 2244, 2236, - 2230, 2222, 2203, 2195, 2189, 2181, 2171, 2163, 2157, 2149, 2127, 2119, 2113, - 2105, 2095, 2087, 2081, 2073, 2054, 2046, 2040, 2032, 2022, 2014, 2008, 2000, - 1974, 1966, 1960, 1952, 1942, 1934, 1928, 1920, 1901, 1893, 1887, 1879, 1869, - 1861, 1855, 1847, 1825, 1817, 1811, 1803, 1793, 1785, 1779, 1771, 1752, 1744, - 1738, 1730, 1720, 1712, 1706, 1698, 1897, 1883, 1860, 1846, 1819, 1805, 1782, - 1768, 1723, 1709, 1686, 1672, 1645, 1631, 1608, 1594, 1574, 1560, 1537, 1523, - 1496, 1482, 1459, 1445, 1400, 1386, 1363, 1349, 1322, 1308, 1285, 1271, 1608, - 1565, 1535, 1492, 1446, 1403, 1373, 1330, 1312, 1269, 1239, 1196, 1150, 1107, - 1077, 1034, 1291, 1218, 1171, 1098, 1015, 942, 895, 822, 953, 850, 729, - 626, 618, 431, 257, 257, 257, 257, 0, 255, 255, 255, 255, 429, - 616, 624, 727, 848, 951, 820, 893, 940, 1013, 1096, 1169, 1216, 1289, - 1032, 1075, 1105, 1148, 1194, 1237, 1267, 1310, 1328, 1371, 1401, 1444, 1490, - 1533, 1563, 1606, 1269, 1283, 1306, 1320, 1347, 1361, 1384, 1398, 1443, 1457, - 1480, 1494, 1521, 1535, 1558, 1572, 1592, 1606, 1629, 1643, 1670, 1684, 1707, - 1721, 1766, 1780, 1803, 1817, 1844, 1858, 1881, 1895, 1696, 1704, 1710, 1718, - 1728, 1736, 1742, 1750, 1769, 1777, 1783, 1791, 1801, 1809, 1815, 1823, 1845, - 1853, 1859, 1867, 1877, 1885, 1891, 1899, 1918, 1926, 1932, 1940, 1950, 1958, - 1964, 1972, 1998, 2006, 2012, 2020, 2030, 2038, 2044, 2052, 2071, 2079, 2085, - 2093, 2103, 2111, 2117, 2125, 2147, 2155, 2161, 2169, 2179, 2187, 2193, 2201, - 2220, 2228, 2234, 2242, 2252, 2260, 2266, 2274, 2140, 2148, 2154, 2162, 2172, - 2180, 2186, 2194, 2213, 2221, 2227, 2235, 2245, 2253, 2259, 2267, 2289, 2297, - 2303, 2311, 2321, 2329, 2335, 2343, 2362, 2370, 2376, 2384, 2394, 2402, 2408, - 2416, 2442, 2450, 2456, 2464, 2474, 2482, 2488, 2496, 2515, 2523, 2529, 2537, - 2547, 2555, 2561, 2569, 2591, 2599, 2605, 2613, 2623, 2631, 2637, 2645, 2664, - 2672, 2678, 2686, 2696, 2704, 2710, 2718, 2516, 2524, 2530, 2538, 2548, 2556, - 2562, 2570, 2589, 2597, 2603, 2611, 2621, 2629, 2635, 2643, 2665, 2673, 2679, - 2687, 2697, 2705, 2711, 2719, 2738, 2746, 2752, 2760, 2770, 2778, 2784, 2792, - 2818, 2826, 2832, 2840, 2850, 2858, 2864, 2872, 2891, 2899, 2905, 2913, 2923, - 2931, 2937, 2945, 2967, 2975, 2981, 2989, 2999, 3007, 3013, 3021, 3040, 3048, - 3054, 3062, 3072, 3080, 3086, 3094, 2960, 2968, 2974, 2982, 2992, 3000, 3006, - 3014, 3033, 3041, 3047, 3055, 3065, 3073, 3079, 3087, 3109, 3117, 3123, 3131, - 3141, 3149, 3155, 3163, 3182, 3190, 3196, 3204, 3214, 3222, 3228, 3236, 3262, - 3270, 3276, 3284, 3294, 3302, 3308, 3316, 3335, 3343, 3349, 3357, 3367, 3375, - 3381, 3389, 3411, 3419, 3425, 3433, 3443, 3451, 3457, 3465, 3484, 3492, 3498, - 3506, 3516, 3524, 3530, 3538, 2807, 2815, 2821, 2829, 2839, 2847, 2853, 2861, - 2880, 2888, 2894, 2902, 2912, 2920, 2926, 2934, 2956, 2964, 2970, 2978, 2988, - 2996, 3002, 3010, 3029, 3037, 3043, 3051, 3061, 3069, 3075, 3083, 3109, 3117, - 3123, 3131, 3141, 3149, 3155, 3163, 3182, 3190, 3196, 3204, 3214, 3222, 3228, - 3236, 3258, 3266, 3272, 3280, 3290, 3298, 3304, 3312, 3331, 3339, 3345, 3353, - 3363, 3371, 3377, 3385, 3251, 3259, 3265, 3273, 3283, 3291, 3297, 3305, 3324, - 3332, 3338, 3346, 3356, 3364, 3370, 3378, 3400, 3408, 3414, 3422, 3432, 3440, - 3446, 3454, 3473, 3481, 3487, 3495, 3505, 3513, 3519, 3527, 3553, 3561, 3567, - 3575, 3585, 3593, 3599, 3607, 3626, 3634, 3640, 3648, 3658, 3666, 3672, 3680, - 3702, 3710, 3716, 3724, 3734, 3742, 3748, 3756, 3775, 3783, 3789, 3797, 3807, - 3815, 3821, 3829, 3627, 3635, 3641, 3649, 3659, 3667, 3673, 3681, 3700, 3708, - 3714, 3722, 3732, 3740, 3746, 3754, 3776, 3784, 3790, 3798, 3808, 3816, 3822, - 3830, 3849, 3857, 3863, 3871, 3881, 3889, 3895, 3903, 3929, 3937, 3943, 3951, - 3961, 3969, 3975, 3983, 4002, 4010, 4016, 4024, 4034, 4042, 4048, 4056, 4078, - 4086, 4092, 4100, 4110, 4118, 4124, 4132, 4151, 4159, 4165, 4173, 4183, 4191, - 4197, 4205, 4071, 4079, 4085, 4093, 4103, 4111, 4117, 4125, 4144, 4152, 4158, - 4166, 4176, 4184, 4190, 4198, 4220, 4228, 4234, 4242, 4252, 4260, 4266, 4274, - 4293, 4301, 4307, 4315, 4325, 4333, 4339, 4347, 4373, 4381, 4387, 4395, 4405, - 4413, 4419, 4427, 4446, 4454, 4460, 4468, 4478, 4486, 4492, 4500, 4522, 4530, - 4536, 4544, 4554, 4562, 4568, 4576, 4595, 4603, 4609, 4617, 4627, 4635, 4641, - 4649, 3742, 3750, 3756, 3764, 3774, 3782, 3788, 3796, 3815, 3823, 3829, 3837, - 3847, 3855, 3861, 3869, 3891, 3899, 3905, 3913, 3923, 3931, 3937, 3945, 3964, - 3972, 3978, 3986, 3996, 4004, 4010, 4018, 4044, 4052, 4058, 4066, 4076, 4084, - 4090, 4098, 4117, 4125, 4131, 4139, 4149, 4157, 4163, 4171, 4193, 4201, 4207, - 4215, 4225, 4233, 4239, 4247, 4266, 4274, 4280, 4288, 4298, 4306, 4312, 4320, - 4186, 4194, 4200, 4208, 4218, 4226, 4232, 4240, 4259, 4267, 4273, 4281, 4291, - 4299, 4305, 4313, 4335, 4343, 4349, 4357, 4367, 4375, 4381, 4389, 4408, 4416, - 4422, 4430, 4440, 4448, 4454, 4462, 4488, 4496, 4502, 4510, 4520, 4528, 4534, - 4542, 4561, 4569, 4575, 4583, 4593, 4601, 4607, 4615, 4637, 4645, 4651, 4659, - 4669, 4677, 4683, 4691, 4710, 4718, 4724, 4732, 4742, 4750, 4756, 4764, 4562, - 4570, 4576, 4584, 4594, 4602, 4608, 4616, 4635, 4643, 4649, 4657, 4667, 4675, - 4681, 4689, 4711, 4719, 4725, 4733, 4743, 4751, 4757, 4765, 4784, 4792, 4798, - 4806, 4816, 4824, 4830, 4838, 4864, 4872, 4878, 4886, 4896, 4904, 4910, 4918, - 4937, 4945, 4951, 4959, 4969, 4977, 4983, 4991, 5013, 5021, 5027, 5035, 5045, - 5053, 5059, 5067, 5086, 5094, 5100, 5108, 5118, 5126, 5132, 5140, 5006, 5014, - 5020, 5028, 5038, 5046, 5052, 5060, 5079, 5087, 5093, 5101, 5111, 5119, 5125, - 5133, 5155, 5163, 5169, 5177, 5187, 5195, 5201, 5209, 5228, 5236, 5242, 5250, - 5260, 5268, 5274, 5282, 5308, 5316, 5322, 5330, 5340, 5348, 5354, 5362, 5381, - 5389, 5395, 5403, 5413, 5421, 5427, 5435, 5457, 5465, 5471, 5479, 5489, 5497, - 5503, 5511, 5530, 5538, 5544, 5552, 5562, 5570, 5576, 5584, 4853, 4861, 4867, - 4875, 4885, 4893, 4899, 4907, 4926, 4934, 4940, 4948, 4958, 4966, 4972, 4980, - 5002, 5010, 5016, 5024, 5034, 5042, 5048, 5056, 5075, 5083, 5089, 5097, 5107, - 5115, 5121, 5129, 5155, 5163, 5169, 5177, 5187, 5195, 5201, 5209, 5228, 5236, - 5242, 5250, 5260, 5268, 5274, 5282, 5304, 5312, 5318, 5326, 5336, 5344, 5350, - 5358, 5377, 5385, 5391, 5399, 5409, 5417, 5423, 5431, 5297, 5305, 5311, 5319, - 5329, 5337, 5343, 5351, 5370, 5378, 5384, 5392, 5402, 5410, 5416, 5424, 5446, - 5454, 5460, 5468, 5478, 5486, 5492, 5500, 5519, 5527, 5533, 5541, 5551, 5559, - 5565, 5573, 5599, 5607, 5613, 5621, 5631, 5639, 5645, 5653, 5672, 5680, 5686, - 5694, 5704, 5712, 5718, 5726, 5748, 5756, 5762, 5770, 5780, 5788, 5794, 5802, - 5821, 5829, 5835, 5843, 5853, 5861, 5867, 5875, 5673, 5681, 5687, 5695, 5705, - 5713, 5719, 5727, 5746, 5754, 5760, 5768, 5778, 5786, 5792, 5800, 5822, 5830, - 5836, 5844, 5854, 5862, 5868, 5876, 5895, 5903, 5909, 5917, 5927, 5935, 5941, - 5949, 5975, 5983, 5989, 5997, 6007, 6015, 6021, 6029, 6048, 6056, 6062, 6070, - 6080, 6088, 6094, 6102, 6124, 6132, 6138, 6146, 6156, 6164, 6170, 6178, 6197, - 6205, 6211, 6219, 6229, 6237, 6243, 6251, 6117, 6125, 6131, 6139, 6149, 6157, - 6163, 6171, 6190, 6198, 6204, 6212, 6222, 6230, 6236, 6244, 6266, 6274, 6280, - 6288, 6298, 6306, 6312, 6320, 6339, 6347, 6353, 6361, 6371, 6379, 6385, 6393, - 6419, 6427, 6433, 6441, 6451, 6459, 6465, 6473, 6492, 6500, 6506, 6514, 6524, - 6532, 6538, 6546, 6568, 6576, 6582, 6590, 6600, 6608, 6614, 6622, 6641, 6649, - 6655, 6663, 6673, 6681, 6687, 6695, 3742, 3750, 3756, 3764, 3774, 3782, 3788, - 3796, 3815, 3823, 3829, 3837, 3847, 3855, 3861, 3869, 3891, 3899, 3905, 3913, - 3923, 3931, 3937, 3945, 3964, 3972, 3978, 3986, 3996, 4004, 4010, 4018, 4044, - 4052, 4058, 4066, 4076, 4084, 4090, 4098, 4117, 4125, 4131, 4139, 4149, 4157, - 4163, 4171, 4193, 4201, 4207, 4215, 4225, 4233, 4239, 4247, 4266, 4274, 4280, - 4288, 4298, 4306, 4312, 4320, 4186, 4194, 4200, 4208, 4218, 4226, 4232, 4240, - 4259, 4267, 4273, 4281, 4291, 4299, 4305, 4313, 4335, 4343, 4349, 4357, 4367, - 4375, 4381, 4389, 4408, 4416, 4422, 4430, 4440, 4448, 4454, 4462, 4488, 4496, - 4502, 4510, 4520, 4528, 4534, 4542, 4561, 4569, 4575, 4583, 4593, 4601, 4607, - 4615, 4637, 4645, 4651, 4659, 4669, 4677, 4683, 4691, 4710, 4718, 4724, 4732, - 4742, 4750, 4756, 4764, 4562, 4570, 4576, 4584, 4594, 4602, 4608, 4616, 4635, - 4643, 4649, 4657, 4667, 4675, 4681, 4689, 4711, 4719, 4725, 4733, 4743, 4751, - 4757, 4765, 4784, 4792, 4798, 4806, 4816, 4824, 4830, 4838, 4864, 4872, 4878, - 4886, 4896, 4904, 4910, 4918, 4937, 4945, 4951, 4959, 4969, 4977, 4983, 4991, - 5013, 5021, 5027, 5035, 5045, 5053, 5059, 5067, 5086, 5094, 5100, 5108, 5118, - 5126, 5132, 5140, 5006, 5014, 5020, 5028, 5038, 5046, 5052, 5060, 5079, 5087, - 5093, 5101, 5111, 5119, 5125, 5133, 5155, 5163, 5169, 5177, 5187, 5195, 5201, - 5209, 5228, 5236, 5242, 5250, 5260, 5268, 5274, 5282, 5308, 5316, 5322, 5330, - 5340, 5348, 5354, 5362, 5381, 5389, 5395, 5403, 5413, 5421, 5427, 5435, 5457, - 5465, 5471, 5479, 5489, 5497, 5503, 5511, 5530, 5538, 5544, 5552, 5562, 5570, - 5576, 5584, 4853, 4861, 4867, 4875, 4885, 4893, 4899, 4907, 4926, 4934, 4940, - 4948, 4958, 4966, 4972, 4980, 5002, 5010, 5016, 5024, 5034, 5042, 5048, 5056, - 5075, 5083, 5089, 5097, 5107, 5115, 5121, 5129, 5155, 5163, 5169, 5177, 5187, - 5195, 5201, 5209, 5228, 5236, 5242, 5250, 5260, 5268, 5274, 5282, 5304, 5312, - 5318, 5326, 5336, 5344, 5350, 5358, 5377, 5385, 5391, 5399, 5409, 5417, 5423, - 5431, 5297, 5305, 5311, 5319, 5329, 5337, 5343, 5351, 5370, 5378, 5384, 5392, - 5402, 5410, 5416, 5424, 5446, 5454, 5460, 5468, 5478, 5486, 5492, 5500, 5519, - 5527, 5533, 5541, 5551, 5559, 5565, 5573, 5599, 5607, 5613, 5621, 5631, 5639, - 5645, 5653, 5672, 5680, 5686, 5694, 5704, 5712, 5718, 5726, 5748, 5756, 5762, - 5770, 5780, 5788, 5794, 5802, 5821, 5829, 5835, 5843, 5853, 5861, 5867, 5875, - 5673, 5681, 5687, 5695, 5705, 5713, 5719, 5727, 5746, 5754, 5760, 5768, 5778, - 5786, 5792, 5800, 5822, 5830, 5836, 5844, 5854, 5862, 5868, 5876, 5895, 5903, - 5909, 5917, 5927, 5935, 5941, 5949, 5975, 5983, 5989, 5997, 6007, 6015, 6021, - 6029, 6048, 6056, 6062, 6070, 6080, 6088, 6094, 6102, 6124, 6132, 6138, 6146, - 6156, 6164, 6170, 6178, 6197, 6205, 6211, 6219, 6229, 6237, 6243, 6251, 6117, - 6125, 6131, 6139, 6149, 6157, 6163, 6171, 6190, 6198, 6204, 6212, 6222, 6230, - 6236, 6244, 6266, 6274, 6280, 6288, 6298, 6306, 6312, 6320, 6339, 6347, 6353, - 6361, 6371, 6379, 6385, 6393, 6419, 6427, 6433, 6441, 6451, 6459, 6465, 6473, - 6492, 6500, 6506, 6514, 6524, 6532, 6538, 6546, 6568, 6576, 6582, 6590, 6600, - 6608, 6614, 6622, 6641, 6649, 6655, 6663, 6673, 6681, 6687, 6695, 5788, 5796, - 5802, 5810, 5820, 5828, 5834, 5842, 5861, 5869, 5875, 5883, 5893, 5901, 5907, - 5915, 5937, 5945, 5951, 5959, 5969, 5977, 5983, 5991, 6010, 6018, 6024, 6032, - 6042, 6050, 6056, 6064, 6090, 6098, 6104, 6112, 6122, 6130, 6136, 6144, 6163, - 6171, 6177, 6185, 6195, 6203, 6209, 6217, 6239, 6247, 6253, 6261, 6271, 6279, - 6285, 6293, 6312, 6320, 6326, 6334, 6344, 6352, 6358, 6366, 6232, 6240, 6246, - 6254, 6264, 6272, 6278, 6286, 6305, 6313, 6319, 6327, 6337, 6345, 6351, 6359, - 6381, 6389, 6395, 6403, 6413, 6421, 6427, 6435, 6454, 6462, 6468, 6476, 6486, - 6494, 6500, 6508, 6534, 6542, 6548, 6556, 6566, 6574, 6580, 6588, 6607, 6615, - 6621, 6629, 6639, 6647, 6653, 6661, 6683, 6691, 6697, 6705, 6715, 6723, 6729, - 6737, 6756, 6764, 6770, 6778, 6788, 6796, 6802, 6810, 6608, 6616, 6622, 6630, - 6640, 6648, 6654, 6662, 6681, 6689, 6695, 6703, 6713, 6721, 6727, 6735, 6757, - 6765, 6771, 6779, 6789, 6797, 6803, 6811, 6830, 6838, 6844, 6852, 6862, 6870, - 6876, 6884, 6910, 6918, 6924, 6932, 6942, 6950, 6956, 6964, 6983, 6991, 6997, - 7005, 7015, 7023, 7029, 7037, 7059, 7067, 7073, 7081, 7091, 7099, 7105, 7113, - 7132, 7140, 7146, 7154, 7164, 7172, 7178, 7186, 7052, 7060, 7066, 7074, 7084, - 7092, 7098, 7106, 7125, 7133, 7139, 7147, 7157, 7165, 7171, 7179, 7201, 7209, - 7215, 7223, 7233, 7241, 7247, 7255, 7274, 7282, 7288, 7296, 7306, 7314, 7320, - 7328, 7354, 7362, 7368, 7376, 7386, 7394, 7400, 7408, 7427, 7435, 7441, 7449, - 7459, 7467, 7473, 7481, 7503, 7511, 7517, 7525, 7535, 7543, 7549, 7557, 7576, - 7584, 7590, 7598, 7608, 7616, 7622, 7630, 6899, 6907, 6913, 6921, 6931, 6939, - 6945, 6953, 6972, 6980, 6986, 6994, 7004, 7012, 7018, 7026, 7048, 7056, 7062, - 7070, 7080, 7088, 7094, 7102, 7121, 7129, 7135, 7143, 7153, 7161, 7167, 7175, - 7201, 7209, 7215, 7223, 7233, 7241, 7247, 7255, 7274, 7282, 7288, 7296, 7306, - 7314, 7320, 7328, 7350, 7358, 7364, 7372, 7382, 7390, 7396, 7404, 7423, 7431, - 7437, 7445, 7455, 7463, 7469, 7477, 7343, 7351, 7357, 7365, 7375, 7383, 7389, - 7397, 7416, 7424, 7430, 7438, 7448, 7456, 7462, 7470, 7492, 7500, 7506, 7514, - 7524, 7532, 7538, 7546, 7565, 7573, 7579, 7587, 7597, 7605, 7611, 7619, 7645, - 7653, 7659, 7667, 7677, 7685, 7691, 7699, 7718, 7726, 7732, 7740, 7750, 7758, - 7764, 7772, 7794, 7802, 7808, 7816, 7826, 7834, 7840, 7848, 7867, 7875, 7881, - 7889, 7899, 7907, 7913, 7921, 7719, 7727, 7733, 7741, 7751, 7759, 7765, 7773, - 7792, 7800, 7806, 7814, 7824, 7832, 7838, 7846, 7868, 7876, 7882, 7890, 7900, - 7908, 7914, 7922, 7941, 7949, 7955, 7963, 7973, 7981, 7987, 7995, 8021, 8029, - 8035, 8043, 8053, 8061, 8067, 8075, 8094, 8102, 8108, 8116, 8126, 8134, 8140, - 8148, 8170, 8178, 8184, 8192, 8202, 8210, 8216, 8224, 8243, 8251, 8257, 8265, - 8275 -}; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_DCT_VALUE_COST_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/dct_value_tokens.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/dct_value_tokens.h deleted file mode 100644 index 5cc4505f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/dct_value_tokens.h +++ /dev/null @@ -1,848 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_DCT_VALUE_TOKENS_H_ -#define VPX_VP8_ENCODER_DCT_VALUE_TOKENS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Generated file, included by tokenize.c */ -/* Values generated by fill_value_tokens() */ - -static const TOKENVALUE dct_value_tokens[2048 * 2] = { - { 10, 3963 }, { 10, 3961 }, { 10, 3959 }, { 10, 3957 }, { 10, 3955 }, - { 10, 3953 }, { 10, 3951 }, { 10, 3949 }, { 10, 3947 }, { 10, 3945 }, - { 10, 3943 }, { 10, 3941 }, { 10, 3939 }, { 10, 3937 }, { 10, 3935 }, - { 10, 3933 }, { 10, 3931 }, { 10, 3929 }, { 10, 3927 }, { 10, 3925 }, - { 10, 3923 }, { 10, 3921 }, { 10, 3919 }, { 10, 3917 }, { 10, 3915 }, - { 10, 3913 }, { 10, 3911 }, { 10, 3909 }, { 10, 3907 }, { 10, 3905 }, - { 10, 3903 }, { 10, 3901 }, { 10, 3899 }, { 10, 3897 }, { 10, 3895 }, - { 10, 3893 }, { 10, 3891 }, { 10, 3889 }, { 10, 3887 }, { 10, 3885 }, - { 10, 3883 }, { 10, 3881 }, { 10, 3879 }, { 10, 3877 }, { 10, 3875 }, - { 10, 3873 }, { 10, 3871 }, { 10, 3869 }, { 10, 3867 }, { 10, 3865 }, - { 10, 3863 }, { 10, 3861 }, { 10, 3859 }, { 10, 3857 }, { 10, 3855 }, - { 10, 3853 }, { 10, 3851 }, { 10, 3849 }, { 10, 3847 }, { 10, 3845 }, - { 10, 3843 }, { 10, 3841 }, { 10, 3839 }, { 10, 3837 }, { 10, 3835 }, - { 10, 3833 }, { 10, 3831 }, { 10, 3829 }, { 10, 3827 }, { 10, 3825 }, - { 10, 3823 }, { 10, 3821 }, { 10, 3819 }, { 10, 3817 }, { 10, 3815 }, - { 10, 3813 }, { 10, 3811 }, { 10, 3809 }, { 10, 3807 }, { 10, 3805 }, - { 10, 3803 }, { 10, 3801 }, { 10, 3799 }, { 10, 3797 }, { 10, 3795 }, - { 10, 3793 }, { 10, 3791 }, { 10, 3789 }, { 10, 3787 }, { 10, 3785 }, - { 10, 3783 }, { 10, 3781 }, { 10, 3779 }, { 10, 3777 }, { 10, 3775 }, - { 10, 3773 }, { 10, 3771 }, { 10, 3769 }, { 10, 3767 }, { 10, 3765 }, - { 10, 3763 }, { 10, 3761 }, { 10, 3759 }, { 10, 3757 }, { 10, 3755 }, - { 10, 3753 }, { 10, 3751 }, { 10, 3749 }, { 10, 3747 }, { 10, 3745 }, - { 10, 3743 }, { 10, 3741 }, { 10, 3739 }, { 10, 3737 }, { 10, 3735 }, - { 10, 3733 }, { 10, 3731 }, { 10, 3729 }, { 10, 3727 }, { 10, 3725 }, - { 10, 3723 }, { 10, 3721 }, { 10, 3719 }, { 10, 3717 }, { 10, 3715 }, - { 10, 3713 }, { 10, 3711 }, { 10, 3709 }, { 10, 3707 }, { 10, 3705 }, - { 10, 3703 }, { 10, 3701 }, { 10, 3699 }, { 10, 3697 }, { 10, 3695 }, - { 10, 3693 }, { 10, 3691 }, { 10, 3689 }, { 10, 3687 }, { 10, 3685 }, - { 10, 3683 }, { 10, 3681 }, { 10, 3679 }, { 10, 3677 }, { 10, 3675 }, - { 10, 3673 }, { 10, 3671 }, { 10, 3669 }, { 10, 3667 }, { 10, 3665 }, - { 10, 3663 }, { 10, 3661 }, { 10, 3659 }, { 10, 3657 }, { 10, 3655 }, - { 10, 3653 }, { 10, 3651 }, { 10, 3649 }, { 10, 3647 }, { 10, 3645 }, - { 10, 3643 }, { 10, 3641 }, { 10, 3639 }, { 10, 3637 }, { 10, 3635 }, - { 10, 3633 }, { 10, 3631 }, { 10, 3629 }, { 10, 3627 }, { 10, 3625 }, - { 10, 3623 }, { 10, 3621 }, { 10, 3619 }, { 10, 3617 }, { 10, 3615 }, - { 10, 3613 }, { 10, 3611 }, { 10, 3609 }, { 10, 3607 }, { 10, 3605 }, - { 10, 3603 }, { 10, 3601 }, { 10, 3599 }, { 10, 3597 }, { 10, 3595 }, - { 10, 3593 }, { 10, 3591 }, { 10, 3589 }, { 10, 3587 }, { 10, 3585 }, - { 10, 3583 }, { 10, 3581 }, { 10, 3579 }, { 10, 3577 }, { 10, 3575 }, - { 10, 3573 }, { 10, 3571 }, { 10, 3569 }, { 10, 3567 }, { 10, 3565 }, - { 10, 3563 }, { 10, 3561 }, { 10, 3559 }, { 10, 3557 }, { 10, 3555 }, - { 10, 3553 }, { 10, 3551 }, { 10, 3549 }, { 10, 3547 }, { 10, 3545 }, - { 10, 3543 }, { 10, 3541 }, { 10, 3539 }, { 10, 3537 }, { 10, 3535 }, - { 10, 3533 }, { 10, 3531 }, { 10, 3529 }, { 10, 3527 }, { 10, 3525 }, - { 10, 3523 }, { 10, 3521 }, { 10, 3519 }, { 10, 3517 }, { 10, 3515 }, - { 10, 3513 }, { 10, 3511 }, { 10, 3509 }, { 10, 3507 }, { 10, 3505 }, - { 10, 3503 }, { 10, 3501 }, { 10, 3499 }, { 10, 3497 }, { 10, 3495 }, - { 10, 3493 }, { 10, 3491 }, { 10, 3489 }, { 10, 3487 }, { 10, 3485 }, - { 10, 3483 }, { 10, 3481 }, { 10, 3479 }, { 10, 3477 }, { 10, 3475 }, - { 10, 3473 }, { 10, 3471 }, { 10, 3469 }, { 10, 3467 }, { 10, 3465 }, - { 10, 3463 }, { 10, 3461 }, { 10, 3459 }, { 10, 3457 }, { 10, 3455 }, - { 10, 3453 }, { 10, 3451 }, { 10, 3449 }, { 10, 3447 }, { 10, 3445 }, - { 10, 3443 }, { 10, 3441 }, { 10, 3439 }, { 10, 3437 }, { 10, 3435 }, - { 10, 3433 }, { 10, 3431 }, { 10, 3429 }, { 10, 3427 }, { 10, 3425 }, - { 10, 3423 }, { 10, 3421 }, { 10, 3419 }, { 10, 3417 }, { 10, 3415 }, - { 10, 3413 }, { 10, 3411 }, { 10, 3409 }, { 10, 3407 }, { 10, 3405 }, - { 10, 3403 }, { 10, 3401 }, { 10, 3399 }, { 10, 3397 }, { 10, 3395 }, - { 10, 3393 }, { 10, 3391 }, { 10, 3389 }, { 10, 3387 }, { 10, 3385 }, - { 10, 3383 }, { 10, 3381 }, { 10, 3379 }, { 10, 3377 }, { 10, 3375 }, - { 10, 3373 }, { 10, 3371 }, { 10, 3369 }, { 10, 3367 }, { 10, 3365 }, - { 10, 3363 }, { 10, 3361 }, { 10, 3359 }, { 10, 3357 }, { 10, 3355 }, - { 10, 3353 }, { 10, 3351 }, { 10, 3349 }, { 10, 3347 }, { 10, 3345 }, - { 10, 3343 }, { 10, 3341 }, { 10, 3339 }, { 10, 3337 }, { 10, 3335 }, - { 10, 3333 }, { 10, 3331 }, { 10, 3329 }, { 10, 3327 }, { 10, 3325 }, - { 10, 3323 }, { 10, 3321 }, { 10, 3319 }, { 10, 3317 }, { 10, 3315 }, - { 10, 3313 }, { 10, 3311 }, { 10, 3309 }, { 10, 3307 }, { 10, 3305 }, - { 10, 3303 }, { 10, 3301 }, { 10, 3299 }, { 10, 3297 }, { 10, 3295 }, - { 10, 3293 }, { 10, 3291 }, { 10, 3289 }, { 10, 3287 }, { 10, 3285 }, - { 10, 3283 }, { 10, 3281 }, { 10, 3279 }, { 10, 3277 }, { 10, 3275 }, - { 10, 3273 }, { 10, 3271 }, { 10, 3269 }, { 10, 3267 }, { 10, 3265 }, - { 10, 3263 }, { 10, 3261 }, { 10, 3259 }, { 10, 3257 }, { 10, 3255 }, - { 10, 3253 }, { 10, 3251 }, { 10, 3249 }, { 10, 3247 }, { 10, 3245 }, - { 10, 3243 }, { 10, 3241 }, { 10, 3239 }, { 10, 3237 }, { 10, 3235 }, - { 10, 3233 }, { 10, 3231 }, { 10, 3229 }, { 10, 3227 }, { 10, 3225 }, - { 10, 3223 }, { 10, 3221 }, { 10, 3219 }, { 10, 3217 }, { 10, 3215 }, - { 10, 3213 }, { 10, 3211 }, { 10, 3209 }, { 10, 3207 }, { 10, 3205 }, - { 10, 3203 }, { 10, 3201 }, { 10, 3199 }, { 10, 3197 }, { 10, 3195 }, - { 10, 3193 }, { 10, 3191 }, { 10, 3189 }, { 10, 3187 }, { 10, 3185 }, - { 10, 3183 }, { 10, 3181 }, { 10, 3179 }, { 10, 3177 }, { 10, 3175 }, - { 10, 3173 }, { 10, 3171 }, { 10, 3169 }, { 10, 3167 }, { 10, 3165 }, - { 10, 3163 }, { 10, 3161 }, { 10, 3159 }, { 10, 3157 }, { 10, 3155 }, - { 10, 3153 }, { 10, 3151 }, { 10, 3149 }, { 10, 3147 }, { 10, 3145 }, - { 10, 3143 }, { 10, 3141 }, { 10, 3139 }, { 10, 3137 }, { 10, 3135 }, - { 10, 3133 }, { 10, 3131 }, { 10, 3129 }, { 10, 3127 }, { 10, 3125 }, - { 10, 3123 }, { 10, 3121 }, { 10, 3119 }, { 10, 3117 }, { 10, 3115 }, - { 10, 3113 }, { 10, 3111 }, { 10, 3109 }, { 10, 3107 }, { 10, 3105 }, - { 10, 3103 }, { 10, 3101 }, { 10, 3099 }, { 10, 3097 }, { 10, 3095 }, - { 10, 3093 }, { 10, 3091 }, { 10, 3089 }, { 10, 3087 }, { 10, 3085 }, - { 10, 3083 }, { 10, 3081 }, { 10, 3079 }, { 10, 3077 }, { 10, 3075 }, - { 10, 3073 }, { 10, 3071 }, { 10, 3069 }, { 10, 3067 }, { 10, 3065 }, - { 10, 3063 }, { 10, 3061 }, { 10, 3059 }, { 10, 3057 }, { 10, 3055 }, - { 10, 3053 }, { 10, 3051 }, { 10, 3049 }, { 10, 3047 }, { 10, 3045 }, - { 10, 3043 }, { 10, 3041 }, { 10, 3039 }, { 10, 3037 }, { 10, 3035 }, - { 10, 3033 }, { 10, 3031 }, { 10, 3029 }, { 10, 3027 }, { 10, 3025 }, - { 10, 3023 }, { 10, 3021 }, { 10, 3019 }, { 10, 3017 }, { 10, 3015 }, - { 10, 3013 }, { 10, 3011 }, { 10, 3009 }, { 10, 3007 }, { 10, 3005 }, - { 10, 3003 }, { 10, 3001 }, { 10, 2999 }, { 10, 2997 }, { 10, 2995 }, - { 10, 2993 }, { 10, 2991 }, { 10, 2989 }, { 10, 2987 }, { 10, 2985 }, - { 10, 2983 }, { 10, 2981 }, { 10, 2979 }, { 10, 2977 }, { 10, 2975 }, - { 10, 2973 }, { 10, 2971 }, { 10, 2969 }, { 10, 2967 }, { 10, 2965 }, - { 10, 2963 }, { 10, 2961 }, { 10, 2959 }, { 10, 2957 }, { 10, 2955 }, - { 10, 2953 }, { 10, 2951 }, { 10, 2949 }, { 10, 2947 }, { 10, 2945 }, - { 10, 2943 }, { 10, 2941 }, { 10, 2939 }, { 10, 2937 }, { 10, 2935 }, - { 10, 2933 }, { 10, 2931 }, { 10, 2929 }, { 10, 2927 }, { 10, 2925 }, - { 10, 2923 }, { 10, 2921 }, { 10, 2919 }, { 10, 2917 }, { 10, 2915 }, - { 10, 2913 }, { 10, 2911 }, { 10, 2909 }, { 10, 2907 }, { 10, 2905 }, - { 10, 2903 }, { 10, 2901 }, { 10, 2899 }, { 10, 2897 }, { 10, 2895 }, - { 10, 2893 }, { 10, 2891 }, { 10, 2889 }, { 10, 2887 }, { 10, 2885 }, - { 10, 2883 }, { 10, 2881 }, { 10, 2879 }, { 10, 2877 }, { 10, 2875 }, - { 10, 2873 }, { 10, 2871 }, { 10, 2869 }, { 10, 2867 }, { 10, 2865 }, - { 10, 2863 }, { 10, 2861 }, { 10, 2859 }, { 10, 2857 }, { 10, 2855 }, - { 10, 2853 }, { 10, 2851 }, { 10, 2849 }, { 10, 2847 }, { 10, 2845 }, - { 10, 2843 }, { 10, 2841 }, { 10, 2839 }, { 10, 2837 }, { 10, 2835 }, - { 10, 2833 }, { 10, 2831 }, { 10, 2829 }, { 10, 2827 }, { 10, 2825 }, - { 10, 2823 }, { 10, 2821 }, { 10, 2819 }, { 10, 2817 }, { 10, 2815 }, - { 10, 2813 }, { 10, 2811 }, { 10, 2809 }, { 10, 2807 }, { 10, 2805 }, - { 10, 2803 }, { 10, 2801 }, { 10, 2799 }, { 10, 2797 }, { 10, 2795 }, - { 10, 2793 }, { 10, 2791 }, { 10, 2789 }, { 10, 2787 }, { 10, 2785 }, - { 10, 2783 }, { 10, 2781 }, { 10, 2779 }, { 10, 2777 }, { 10, 2775 }, - { 10, 2773 }, { 10, 2771 }, { 10, 2769 }, { 10, 2767 }, { 10, 2765 }, - { 10, 2763 }, { 10, 2761 }, { 10, 2759 }, { 10, 2757 }, { 10, 2755 }, - { 10, 2753 }, { 10, 2751 }, { 10, 2749 }, { 10, 2747 }, { 10, 2745 }, - { 10, 2743 }, { 10, 2741 }, { 10, 2739 }, { 10, 2737 }, { 10, 2735 }, - { 10, 2733 }, { 10, 2731 }, { 10, 2729 }, { 10, 2727 }, { 10, 2725 }, - { 10, 2723 }, { 10, 2721 }, { 10, 2719 }, { 10, 2717 }, { 10, 2715 }, - { 10, 2713 }, { 10, 2711 }, { 10, 2709 }, { 10, 2707 }, { 10, 2705 }, - { 10, 2703 }, { 10, 2701 }, { 10, 2699 }, { 10, 2697 }, { 10, 2695 }, - { 10, 2693 }, { 10, 2691 }, { 10, 2689 }, { 10, 2687 }, { 10, 2685 }, - { 10, 2683 }, { 10, 2681 }, { 10, 2679 }, { 10, 2677 }, { 10, 2675 }, - { 10, 2673 }, { 10, 2671 }, { 10, 2669 }, { 10, 2667 }, { 10, 2665 }, - { 10, 2663 }, { 10, 2661 }, { 10, 2659 }, { 10, 2657 }, { 10, 2655 }, - { 10, 2653 }, { 10, 2651 }, { 10, 2649 }, { 10, 2647 }, { 10, 2645 }, - { 10, 2643 }, { 10, 2641 }, { 10, 2639 }, { 10, 2637 }, { 10, 2635 }, - { 10, 2633 }, { 10, 2631 }, { 10, 2629 }, { 10, 2627 }, { 10, 2625 }, - { 10, 2623 }, { 10, 2621 }, { 10, 2619 }, { 10, 2617 }, { 10, 2615 }, - { 10, 2613 }, { 10, 2611 }, { 10, 2609 }, { 10, 2607 }, { 10, 2605 }, - { 10, 2603 }, { 10, 2601 }, { 10, 2599 }, { 10, 2597 }, { 10, 2595 }, - { 10, 2593 }, { 10, 2591 }, { 10, 2589 }, { 10, 2587 }, { 10, 2585 }, - { 10, 2583 }, { 10, 2581 }, { 10, 2579 }, { 10, 2577 }, { 10, 2575 }, - { 10, 2573 }, { 10, 2571 }, { 10, 2569 }, { 10, 2567 }, { 10, 2565 }, - { 10, 2563 }, { 10, 2561 }, { 10, 2559 }, { 10, 2557 }, { 10, 2555 }, - { 10, 2553 }, { 10, 2551 }, { 10, 2549 }, { 10, 2547 }, { 10, 2545 }, - { 10, 2543 }, { 10, 2541 }, { 10, 2539 }, { 10, 2537 }, { 10, 2535 }, - { 10, 2533 }, { 10, 2531 }, { 10, 2529 }, { 10, 2527 }, { 10, 2525 }, - { 10, 2523 }, { 10, 2521 }, { 10, 2519 }, { 10, 2517 }, { 10, 2515 }, - { 10, 2513 }, { 10, 2511 }, { 10, 2509 }, { 10, 2507 }, { 10, 2505 }, - { 10, 2503 }, { 10, 2501 }, { 10, 2499 }, { 10, 2497 }, { 10, 2495 }, - { 10, 2493 }, { 10, 2491 }, { 10, 2489 }, { 10, 2487 }, { 10, 2485 }, - { 10, 2483 }, { 10, 2481 }, { 10, 2479 }, { 10, 2477 }, { 10, 2475 }, - { 10, 2473 }, { 10, 2471 }, { 10, 2469 }, { 10, 2467 }, { 10, 2465 }, - { 10, 2463 }, { 10, 2461 }, { 10, 2459 }, { 10, 2457 }, { 10, 2455 }, - { 10, 2453 }, { 10, 2451 }, { 10, 2449 }, { 10, 2447 }, { 10, 2445 }, - { 10, 2443 }, { 10, 2441 }, { 10, 2439 }, { 10, 2437 }, { 10, 2435 }, - { 10, 2433 }, { 10, 2431 }, { 10, 2429 }, { 10, 2427 }, { 10, 2425 }, - { 10, 2423 }, { 10, 2421 }, { 10, 2419 }, { 10, 2417 }, { 10, 2415 }, - { 10, 2413 }, { 10, 2411 }, { 10, 2409 }, { 10, 2407 }, { 10, 2405 }, - { 10, 2403 }, { 10, 2401 }, { 10, 2399 }, { 10, 2397 }, { 10, 2395 }, - { 10, 2393 }, { 10, 2391 }, { 10, 2389 }, { 10, 2387 }, { 10, 2385 }, - { 10, 2383 }, { 10, 2381 }, { 10, 2379 }, { 10, 2377 }, { 10, 2375 }, - { 10, 2373 }, { 10, 2371 }, { 10, 2369 }, { 10, 2367 }, { 10, 2365 }, - { 10, 2363 }, { 10, 2361 }, { 10, 2359 }, { 10, 2357 }, { 10, 2355 }, - { 10, 2353 }, { 10, 2351 }, { 10, 2349 }, { 10, 2347 }, { 10, 2345 }, - { 10, 2343 }, { 10, 2341 }, { 10, 2339 }, { 10, 2337 }, { 10, 2335 }, - { 10, 2333 }, { 10, 2331 }, { 10, 2329 }, { 10, 2327 }, { 10, 2325 }, - { 10, 2323 }, { 10, 2321 }, { 10, 2319 }, { 10, 2317 }, { 10, 2315 }, - { 10, 2313 }, { 10, 2311 }, { 10, 2309 }, { 10, 2307 }, { 10, 2305 }, - { 10, 2303 }, { 10, 2301 }, { 10, 2299 }, { 10, 2297 }, { 10, 2295 }, - { 10, 2293 }, { 10, 2291 }, { 10, 2289 }, { 10, 2287 }, { 10, 2285 }, - { 10, 2283 }, { 10, 2281 }, { 10, 2279 }, { 10, 2277 }, { 10, 2275 }, - { 10, 2273 }, { 10, 2271 }, { 10, 2269 }, { 10, 2267 }, { 10, 2265 }, - { 10, 2263 }, { 10, 2261 }, { 10, 2259 }, { 10, 2257 }, { 10, 2255 }, - { 10, 2253 }, { 10, 2251 }, { 10, 2249 }, { 10, 2247 }, { 10, 2245 }, - { 10, 2243 }, { 10, 2241 }, { 10, 2239 }, { 10, 2237 }, { 10, 2235 }, - { 10, 2233 }, { 10, 2231 }, { 10, 2229 }, { 10, 2227 }, { 10, 2225 }, - { 10, 2223 }, { 10, 2221 }, { 10, 2219 }, { 10, 2217 }, { 10, 2215 }, - { 10, 2213 }, { 10, 2211 }, { 10, 2209 }, { 10, 2207 }, { 10, 2205 }, - { 10, 2203 }, { 10, 2201 }, { 10, 2199 }, { 10, 2197 }, { 10, 2195 }, - { 10, 2193 }, { 10, 2191 }, { 10, 2189 }, { 10, 2187 }, { 10, 2185 }, - { 10, 2183 }, { 10, 2181 }, { 10, 2179 }, { 10, 2177 }, { 10, 2175 }, - { 10, 2173 }, { 10, 2171 }, { 10, 2169 }, { 10, 2167 }, { 10, 2165 }, - { 10, 2163 }, { 10, 2161 }, { 10, 2159 }, { 10, 2157 }, { 10, 2155 }, - { 10, 2153 }, { 10, 2151 }, { 10, 2149 }, { 10, 2147 }, { 10, 2145 }, - { 10, 2143 }, { 10, 2141 }, { 10, 2139 }, { 10, 2137 }, { 10, 2135 }, - { 10, 2133 }, { 10, 2131 }, { 10, 2129 }, { 10, 2127 }, { 10, 2125 }, - { 10, 2123 }, { 10, 2121 }, { 10, 2119 }, { 10, 2117 }, { 10, 2115 }, - { 10, 2113 }, { 10, 2111 }, { 10, 2109 }, { 10, 2107 }, { 10, 2105 }, - { 10, 2103 }, { 10, 2101 }, { 10, 2099 }, { 10, 2097 }, { 10, 2095 }, - { 10, 2093 }, { 10, 2091 }, { 10, 2089 }, { 10, 2087 }, { 10, 2085 }, - { 10, 2083 }, { 10, 2081 }, { 10, 2079 }, { 10, 2077 }, { 10, 2075 }, - { 10, 2073 }, { 10, 2071 }, { 10, 2069 }, { 10, 2067 }, { 10, 2065 }, - { 10, 2063 }, { 10, 2061 }, { 10, 2059 }, { 10, 2057 }, { 10, 2055 }, - { 10, 2053 }, { 10, 2051 }, { 10, 2049 }, { 10, 2047 }, { 10, 2045 }, - { 10, 2043 }, { 10, 2041 }, { 10, 2039 }, { 10, 2037 }, { 10, 2035 }, - { 10, 2033 }, { 10, 2031 }, { 10, 2029 }, { 10, 2027 }, { 10, 2025 }, - { 10, 2023 }, { 10, 2021 }, { 10, 2019 }, { 10, 2017 }, { 10, 2015 }, - { 10, 2013 }, { 10, 2011 }, { 10, 2009 }, { 10, 2007 }, { 10, 2005 }, - { 10, 2003 }, { 10, 2001 }, { 10, 1999 }, { 10, 1997 }, { 10, 1995 }, - { 10, 1993 }, { 10, 1991 }, { 10, 1989 }, { 10, 1987 }, { 10, 1985 }, - { 10, 1983 }, { 10, 1981 }, { 10, 1979 }, { 10, 1977 }, { 10, 1975 }, - { 10, 1973 }, { 10, 1971 }, { 10, 1969 }, { 10, 1967 }, { 10, 1965 }, - { 10, 1963 }, { 10, 1961 }, { 10, 1959 }, { 10, 1957 }, { 10, 1955 }, - { 10, 1953 }, { 10, 1951 }, { 10, 1949 }, { 10, 1947 }, { 10, 1945 }, - { 10, 1943 }, { 10, 1941 }, { 10, 1939 }, { 10, 1937 }, { 10, 1935 }, - { 10, 1933 }, { 10, 1931 }, { 10, 1929 }, { 10, 1927 }, { 10, 1925 }, - { 10, 1923 }, { 10, 1921 }, { 10, 1919 }, { 10, 1917 }, { 10, 1915 }, - { 10, 1913 }, { 10, 1911 }, { 10, 1909 }, { 10, 1907 }, { 10, 1905 }, - { 10, 1903 }, { 10, 1901 }, { 10, 1899 }, { 10, 1897 }, { 10, 1895 }, - { 10, 1893 }, { 10, 1891 }, { 10, 1889 }, { 10, 1887 }, { 10, 1885 }, - { 10, 1883 }, { 10, 1881 }, { 10, 1879 }, { 10, 1877 }, { 10, 1875 }, - { 10, 1873 }, { 10, 1871 }, { 10, 1869 }, { 10, 1867 }, { 10, 1865 }, - { 10, 1863 }, { 10, 1861 }, { 10, 1859 }, { 10, 1857 }, { 10, 1855 }, - { 10, 1853 }, { 10, 1851 }, { 10, 1849 }, { 10, 1847 }, { 10, 1845 }, - { 10, 1843 }, { 10, 1841 }, { 10, 1839 }, { 10, 1837 }, { 10, 1835 }, - { 10, 1833 }, { 10, 1831 }, { 10, 1829 }, { 10, 1827 }, { 10, 1825 }, - { 10, 1823 }, { 10, 1821 }, { 10, 1819 }, { 10, 1817 }, { 10, 1815 }, - { 10, 1813 }, { 10, 1811 }, { 10, 1809 }, { 10, 1807 }, { 10, 1805 }, - { 10, 1803 }, { 10, 1801 }, { 10, 1799 }, { 10, 1797 }, { 10, 1795 }, - { 10, 1793 }, { 10, 1791 }, { 10, 1789 }, { 10, 1787 }, { 10, 1785 }, - { 10, 1783 }, { 10, 1781 }, { 10, 1779 }, { 10, 1777 }, { 10, 1775 }, - { 10, 1773 }, { 10, 1771 }, { 10, 1769 }, { 10, 1767 }, { 10, 1765 }, - { 10, 1763 }, { 10, 1761 }, { 10, 1759 }, { 10, 1757 }, { 10, 1755 }, - { 10, 1753 }, { 10, 1751 }, { 10, 1749 }, { 10, 1747 }, { 10, 1745 }, - { 10, 1743 }, { 10, 1741 }, { 10, 1739 }, { 10, 1737 }, { 10, 1735 }, - { 10, 1733 }, { 10, 1731 }, { 10, 1729 }, { 10, 1727 }, { 10, 1725 }, - { 10, 1723 }, { 10, 1721 }, { 10, 1719 }, { 10, 1717 }, { 10, 1715 }, - { 10, 1713 }, { 10, 1711 }, { 10, 1709 }, { 10, 1707 }, { 10, 1705 }, - { 10, 1703 }, { 10, 1701 }, { 10, 1699 }, { 10, 1697 }, { 10, 1695 }, - { 10, 1693 }, { 10, 1691 }, { 10, 1689 }, { 10, 1687 }, { 10, 1685 }, - { 10, 1683 }, { 10, 1681 }, { 10, 1679 }, { 10, 1677 }, { 10, 1675 }, - { 10, 1673 }, { 10, 1671 }, { 10, 1669 }, { 10, 1667 }, { 10, 1665 }, - { 10, 1663 }, { 10, 1661 }, { 10, 1659 }, { 10, 1657 }, { 10, 1655 }, - { 10, 1653 }, { 10, 1651 }, { 10, 1649 }, { 10, 1647 }, { 10, 1645 }, - { 10, 1643 }, { 10, 1641 }, { 10, 1639 }, { 10, 1637 }, { 10, 1635 }, - { 10, 1633 }, { 10, 1631 }, { 10, 1629 }, { 10, 1627 }, { 10, 1625 }, - { 10, 1623 }, { 10, 1621 }, { 10, 1619 }, { 10, 1617 }, { 10, 1615 }, - { 10, 1613 }, { 10, 1611 }, { 10, 1609 }, { 10, 1607 }, { 10, 1605 }, - { 10, 1603 }, { 10, 1601 }, { 10, 1599 }, { 10, 1597 }, { 10, 1595 }, - { 10, 1593 }, { 10, 1591 }, { 10, 1589 }, { 10, 1587 }, { 10, 1585 }, - { 10, 1583 }, { 10, 1581 }, { 10, 1579 }, { 10, 1577 }, { 10, 1575 }, - { 10, 1573 }, { 10, 1571 }, { 10, 1569 }, { 10, 1567 }, { 10, 1565 }, - { 10, 1563 }, { 10, 1561 }, { 10, 1559 }, { 10, 1557 }, { 10, 1555 }, - { 10, 1553 }, { 10, 1551 }, { 10, 1549 }, { 10, 1547 }, { 10, 1545 }, - { 10, 1543 }, { 10, 1541 }, { 10, 1539 }, { 10, 1537 }, { 10, 1535 }, - { 10, 1533 }, { 10, 1531 }, { 10, 1529 }, { 10, 1527 }, { 10, 1525 }, - { 10, 1523 }, { 10, 1521 }, { 10, 1519 }, { 10, 1517 }, { 10, 1515 }, - { 10, 1513 }, { 10, 1511 }, { 10, 1509 }, { 10, 1507 }, { 10, 1505 }, - { 10, 1503 }, { 10, 1501 }, { 10, 1499 }, { 10, 1497 }, { 10, 1495 }, - { 10, 1493 }, { 10, 1491 }, { 10, 1489 }, { 10, 1487 }, { 10, 1485 }, - { 10, 1483 }, { 10, 1481 }, { 10, 1479 }, { 10, 1477 }, { 10, 1475 }, - { 10, 1473 }, { 10, 1471 }, { 10, 1469 }, { 10, 1467 }, { 10, 1465 }, - { 10, 1463 }, { 10, 1461 }, { 10, 1459 }, { 10, 1457 }, { 10, 1455 }, - { 10, 1453 }, { 10, 1451 }, { 10, 1449 }, { 10, 1447 }, { 10, 1445 }, - { 10, 1443 }, { 10, 1441 }, { 10, 1439 }, { 10, 1437 }, { 10, 1435 }, - { 10, 1433 }, { 10, 1431 }, { 10, 1429 }, { 10, 1427 }, { 10, 1425 }, - { 10, 1423 }, { 10, 1421 }, { 10, 1419 }, { 10, 1417 }, { 10, 1415 }, - { 10, 1413 }, { 10, 1411 }, { 10, 1409 }, { 10, 1407 }, { 10, 1405 }, - { 10, 1403 }, { 10, 1401 }, { 10, 1399 }, { 10, 1397 }, { 10, 1395 }, - { 10, 1393 }, { 10, 1391 }, { 10, 1389 }, { 10, 1387 }, { 10, 1385 }, - { 10, 1383 }, { 10, 1381 }, { 10, 1379 }, { 10, 1377 }, { 10, 1375 }, - { 10, 1373 }, { 10, 1371 }, { 10, 1369 }, { 10, 1367 }, { 10, 1365 }, - { 10, 1363 }, { 10, 1361 }, { 10, 1359 }, { 10, 1357 }, { 10, 1355 }, - { 10, 1353 }, { 10, 1351 }, { 10, 1349 }, { 10, 1347 }, { 10, 1345 }, - { 10, 1343 }, { 10, 1341 }, { 10, 1339 }, { 10, 1337 }, { 10, 1335 }, - { 10, 1333 }, { 10, 1331 }, { 10, 1329 }, { 10, 1327 }, { 10, 1325 }, - { 10, 1323 }, { 10, 1321 }, { 10, 1319 }, { 10, 1317 }, { 10, 1315 }, - { 10, 1313 }, { 10, 1311 }, { 10, 1309 }, { 10, 1307 }, { 10, 1305 }, - { 10, 1303 }, { 10, 1301 }, { 10, 1299 }, { 10, 1297 }, { 10, 1295 }, - { 10, 1293 }, { 10, 1291 }, { 10, 1289 }, { 10, 1287 }, { 10, 1285 }, - { 10, 1283 }, { 10, 1281 }, { 10, 1279 }, { 10, 1277 }, { 10, 1275 }, - { 10, 1273 }, { 10, 1271 }, { 10, 1269 }, { 10, 1267 }, { 10, 1265 }, - { 10, 1263 }, { 10, 1261 }, { 10, 1259 }, { 10, 1257 }, { 10, 1255 }, - { 10, 1253 }, { 10, 1251 }, { 10, 1249 }, { 10, 1247 }, { 10, 1245 }, - { 10, 1243 }, { 10, 1241 }, { 10, 1239 }, { 10, 1237 }, { 10, 1235 }, - { 10, 1233 }, { 10, 1231 }, { 10, 1229 }, { 10, 1227 }, { 10, 1225 }, - { 10, 1223 }, { 10, 1221 }, { 10, 1219 }, { 10, 1217 }, { 10, 1215 }, - { 10, 1213 }, { 10, 1211 }, { 10, 1209 }, { 10, 1207 }, { 10, 1205 }, - { 10, 1203 }, { 10, 1201 }, { 10, 1199 }, { 10, 1197 }, { 10, 1195 }, - { 10, 1193 }, { 10, 1191 }, { 10, 1189 }, { 10, 1187 }, { 10, 1185 }, - { 10, 1183 }, { 10, 1181 }, { 10, 1179 }, { 10, 1177 }, { 10, 1175 }, - { 10, 1173 }, { 10, 1171 }, { 10, 1169 }, { 10, 1167 }, { 10, 1165 }, - { 10, 1163 }, { 10, 1161 }, { 10, 1159 }, { 10, 1157 }, { 10, 1155 }, - { 10, 1153 }, { 10, 1151 }, { 10, 1149 }, { 10, 1147 }, { 10, 1145 }, - { 10, 1143 }, { 10, 1141 }, { 10, 1139 }, { 10, 1137 }, { 10, 1135 }, - { 10, 1133 }, { 10, 1131 }, { 10, 1129 }, { 10, 1127 }, { 10, 1125 }, - { 10, 1123 }, { 10, 1121 }, { 10, 1119 }, { 10, 1117 }, { 10, 1115 }, - { 10, 1113 }, { 10, 1111 }, { 10, 1109 }, { 10, 1107 }, { 10, 1105 }, - { 10, 1103 }, { 10, 1101 }, { 10, 1099 }, { 10, 1097 }, { 10, 1095 }, - { 10, 1093 }, { 10, 1091 }, { 10, 1089 }, { 10, 1087 }, { 10, 1085 }, - { 10, 1083 }, { 10, 1081 }, { 10, 1079 }, { 10, 1077 }, { 10, 1075 }, - { 10, 1073 }, { 10, 1071 }, { 10, 1069 }, { 10, 1067 }, { 10, 1065 }, - { 10, 1063 }, { 10, 1061 }, { 10, 1059 }, { 10, 1057 }, { 10, 1055 }, - { 10, 1053 }, { 10, 1051 }, { 10, 1049 }, { 10, 1047 }, { 10, 1045 }, - { 10, 1043 }, { 10, 1041 }, { 10, 1039 }, { 10, 1037 }, { 10, 1035 }, - { 10, 1033 }, { 10, 1031 }, { 10, 1029 }, { 10, 1027 }, { 10, 1025 }, - { 10, 1023 }, { 10, 1021 }, { 10, 1019 }, { 10, 1017 }, { 10, 1015 }, - { 10, 1013 }, { 10, 1011 }, { 10, 1009 }, { 10, 1007 }, { 10, 1005 }, - { 10, 1003 }, { 10, 1001 }, { 10, 999 }, { 10, 997 }, { 10, 995 }, - { 10, 993 }, { 10, 991 }, { 10, 989 }, { 10, 987 }, { 10, 985 }, - { 10, 983 }, { 10, 981 }, { 10, 979 }, { 10, 977 }, { 10, 975 }, - { 10, 973 }, { 10, 971 }, { 10, 969 }, { 10, 967 }, { 10, 965 }, - { 10, 963 }, { 10, 961 }, { 10, 959 }, { 10, 957 }, { 10, 955 }, - { 10, 953 }, { 10, 951 }, { 10, 949 }, { 10, 947 }, { 10, 945 }, - { 10, 943 }, { 10, 941 }, { 10, 939 }, { 10, 937 }, { 10, 935 }, - { 10, 933 }, { 10, 931 }, { 10, 929 }, { 10, 927 }, { 10, 925 }, - { 10, 923 }, { 10, 921 }, { 10, 919 }, { 10, 917 }, { 10, 915 }, - { 10, 913 }, { 10, 911 }, { 10, 909 }, { 10, 907 }, { 10, 905 }, - { 10, 903 }, { 10, 901 }, { 10, 899 }, { 10, 897 }, { 10, 895 }, - { 10, 893 }, { 10, 891 }, { 10, 889 }, { 10, 887 }, { 10, 885 }, - { 10, 883 }, { 10, 881 }, { 10, 879 }, { 10, 877 }, { 10, 875 }, - { 10, 873 }, { 10, 871 }, { 10, 869 }, { 10, 867 }, { 10, 865 }, - { 10, 863 }, { 10, 861 }, { 10, 859 }, { 10, 857 }, { 10, 855 }, - { 10, 853 }, { 10, 851 }, { 10, 849 }, { 10, 847 }, { 10, 845 }, - { 10, 843 }, { 10, 841 }, { 10, 839 }, { 10, 837 }, { 10, 835 }, - { 10, 833 }, { 10, 831 }, { 10, 829 }, { 10, 827 }, { 10, 825 }, - { 10, 823 }, { 10, 821 }, { 10, 819 }, { 10, 817 }, { 10, 815 }, - { 10, 813 }, { 10, 811 }, { 10, 809 }, { 10, 807 }, { 10, 805 }, - { 10, 803 }, { 10, 801 }, { 10, 799 }, { 10, 797 }, { 10, 795 }, - { 10, 793 }, { 10, 791 }, { 10, 789 }, { 10, 787 }, { 10, 785 }, - { 10, 783 }, { 10, 781 }, { 10, 779 }, { 10, 777 }, { 10, 775 }, - { 10, 773 }, { 10, 771 }, { 10, 769 }, { 10, 767 }, { 10, 765 }, - { 10, 763 }, { 10, 761 }, { 10, 759 }, { 10, 757 }, { 10, 755 }, - { 10, 753 }, { 10, 751 }, { 10, 749 }, { 10, 747 }, { 10, 745 }, - { 10, 743 }, { 10, 741 }, { 10, 739 }, { 10, 737 }, { 10, 735 }, - { 10, 733 }, { 10, 731 }, { 10, 729 }, { 10, 727 }, { 10, 725 }, - { 10, 723 }, { 10, 721 }, { 10, 719 }, { 10, 717 }, { 10, 715 }, - { 10, 713 }, { 10, 711 }, { 10, 709 }, { 10, 707 }, { 10, 705 }, - { 10, 703 }, { 10, 701 }, { 10, 699 }, { 10, 697 }, { 10, 695 }, - { 10, 693 }, { 10, 691 }, { 10, 689 }, { 10, 687 }, { 10, 685 }, - { 10, 683 }, { 10, 681 }, { 10, 679 }, { 10, 677 }, { 10, 675 }, - { 10, 673 }, { 10, 671 }, { 10, 669 }, { 10, 667 }, { 10, 665 }, - { 10, 663 }, { 10, 661 }, { 10, 659 }, { 10, 657 }, { 10, 655 }, - { 10, 653 }, { 10, 651 }, { 10, 649 }, { 10, 647 }, { 10, 645 }, - { 10, 643 }, { 10, 641 }, { 10, 639 }, { 10, 637 }, { 10, 635 }, - { 10, 633 }, { 10, 631 }, { 10, 629 }, { 10, 627 }, { 10, 625 }, - { 10, 623 }, { 10, 621 }, { 10, 619 }, { 10, 617 }, { 10, 615 }, - { 10, 613 }, { 10, 611 }, { 10, 609 }, { 10, 607 }, { 10, 605 }, - { 10, 603 }, { 10, 601 }, { 10, 599 }, { 10, 597 }, { 10, 595 }, - { 10, 593 }, { 10, 591 }, { 10, 589 }, { 10, 587 }, { 10, 585 }, - { 10, 583 }, { 10, 581 }, { 10, 579 }, { 10, 577 }, { 10, 575 }, - { 10, 573 }, { 10, 571 }, { 10, 569 }, { 10, 567 }, { 10, 565 }, - { 10, 563 }, { 10, 561 }, { 10, 559 }, { 10, 557 }, { 10, 555 }, - { 10, 553 }, { 10, 551 }, { 10, 549 }, { 10, 547 }, { 10, 545 }, - { 10, 543 }, { 10, 541 }, { 10, 539 }, { 10, 537 }, { 10, 535 }, - { 10, 533 }, { 10, 531 }, { 10, 529 }, { 10, 527 }, { 10, 525 }, - { 10, 523 }, { 10, 521 }, { 10, 519 }, { 10, 517 }, { 10, 515 }, - { 10, 513 }, { 10, 511 }, { 10, 509 }, { 10, 507 }, { 10, 505 }, - { 10, 503 }, { 10, 501 }, { 10, 499 }, { 10, 497 }, { 10, 495 }, - { 10, 493 }, { 10, 491 }, { 10, 489 }, { 10, 487 }, { 10, 485 }, - { 10, 483 }, { 10, 481 }, { 10, 479 }, { 10, 477 }, { 10, 475 }, - { 10, 473 }, { 10, 471 }, { 10, 469 }, { 10, 467 }, { 10, 465 }, - { 10, 463 }, { 10, 461 }, { 10, 459 }, { 10, 457 }, { 10, 455 }, - { 10, 453 }, { 10, 451 }, { 10, 449 }, { 10, 447 }, { 10, 445 }, - { 10, 443 }, { 10, 441 }, { 10, 439 }, { 10, 437 }, { 10, 435 }, - { 10, 433 }, { 10, 431 }, { 10, 429 }, { 10, 427 }, { 10, 425 }, - { 10, 423 }, { 10, 421 }, { 10, 419 }, { 10, 417 }, { 10, 415 }, - { 10, 413 }, { 10, 411 }, { 10, 409 }, { 10, 407 }, { 10, 405 }, - { 10, 403 }, { 10, 401 }, { 10, 399 }, { 10, 397 }, { 10, 395 }, - { 10, 393 }, { 10, 391 }, { 10, 389 }, { 10, 387 }, { 10, 385 }, - { 10, 383 }, { 10, 381 }, { 10, 379 }, { 10, 377 }, { 10, 375 }, - { 10, 373 }, { 10, 371 }, { 10, 369 }, { 10, 367 }, { 10, 365 }, - { 10, 363 }, { 10, 361 }, { 10, 359 }, { 10, 357 }, { 10, 355 }, - { 10, 353 }, { 10, 351 }, { 10, 349 }, { 10, 347 }, { 10, 345 }, - { 10, 343 }, { 10, 341 }, { 10, 339 }, { 10, 337 }, { 10, 335 }, - { 10, 333 }, { 10, 331 }, { 10, 329 }, { 10, 327 }, { 10, 325 }, - { 10, 323 }, { 10, 321 }, { 10, 319 }, { 10, 317 }, { 10, 315 }, - { 10, 313 }, { 10, 311 }, { 10, 309 }, { 10, 307 }, { 10, 305 }, - { 10, 303 }, { 10, 301 }, { 10, 299 }, { 10, 297 }, { 10, 295 }, - { 10, 293 }, { 10, 291 }, { 10, 289 }, { 10, 287 }, { 10, 285 }, - { 10, 283 }, { 10, 281 }, { 10, 279 }, { 10, 277 }, { 10, 275 }, - { 10, 273 }, { 10, 271 }, { 10, 269 }, { 10, 267 }, { 10, 265 }, - { 10, 263 }, { 10, 261 }, { 10, 259 }, { 10, 257 }, { 10, 255 }, - { 10, 253 }, { 10, 251 }, { 10, 249 }, { 10, 247 }, { 10, 245 }, - { 10, 243 }, { 10, 241 }, { 10, 239 }, { 10, 237 }, { 10, 235 }, - { 10, 233 }, { 10, 231 }, { 10, 229 }, { 10, 227 }, { 10, 225 }, - { 10, 223 }, { 10, 221 }, { 10, 219 }, { 10, 217 }, { 10, 215 }, - { 10, 213 }, { 10, 211 }, { 10, 209 }, { 10, 207 }, { 10, 205 }, - { 10, 203 }, { 10, 201 }, { 10, 199 }, { 10, 197 }, { 10, 195 }, - { 10, 193 }, { 10, 191 }, { 10, 189 }, { 10, 187 }, { 10, 185 }, - { 10, 183 }, { 10, 181 }, { 10, 179 }, { 10, 177 }, { 10, 175 }, - { 10, 173 }, { 10, 171 }, { 10, 169 }, { 10, 167 }, { 10, 165 }, - { 10, 163 }, { 10, 161 }, { 10, 159 }, { 10, 157 }, { 10, 155 }, - { 10, 153 }, { 10, 151 }, { 10, 149 }, { 10, 147 }, { 10, 145 }, - { 10, 143 }, { 10, 141 }, { 10, 139 }, { 10, 137 }, { 10, 135 }, - { 10, 133 }, { 10, 131 }, { 10, 129 }, { 10, 127 }, { 10, 125 }, - { 10, 123 }, { 10, 121 }, { 10, 119 }, { 10, 117 }, { 10, 115 }, - { 10, 113 }, { 10, 111 }, { 10, 109 }, { 10, 107 }, { 10, 105 }, - { 10, 103 }, { 10, 101 }, { 10, 99 }, { 10, 97 }, { 10, 95 }, - { 10, 93 }, { 10, 91 }, { 10, 89 }, { 10, 87 }, { 10, 85 }, - { 10, 83 }, { 10, 81 }, { 10, 79 }, { 10, 77 }, { 10, 75 }, - { 10, 73 }, { 10, 71 }, { 10, 69 }, { 10, 67 }, { 10, 65 }, - { 10, 63 }, { 10, 61 }, { 10, 59 }, { 10, 57 }, { 10, 55 }, - { 10, 53 }, { 10, 51 }, { 10, 49 }, { 10, 47 }, { 10, 45 }, - { 10, 43 }, { 10, 41 }, { 10, 39 }, { 10, 37 }, { 10, 35 }, - { 10, 33 }, { 10, 31 }, { 10, 29 }, { 10, 27 }, { 10, 25 }, - { 10, 23 }, { 10, 21 }, { 10, 19 }, { 10, 17 }, { 10, 15 }, - { 10, 13 }, { 10, 11 }, { 10, 9 }, { 10, 7 }, { 10, 5 }, - { 10, 3 }, { 10, 1 }, { 9, 63 }, { 9, 61 }, { 9, 59 }, - { 9, 57 }, { 9, 55 }, { 9, 53 }, { 9, 51 }, { 9, 49 }, - { 9, 47 }, { 9, 45 }, { 9, 43 }, { 9, 41 }, { 9, 39 }, - { 9, 37 }, { 9, 35 }, { 9, 33 }, { 9, 31 }, { 9, 29 }, - { 9, 27 }, { 9, 25 }, { 9, 23 }, { 9, 21 }, { 9, 19 }, - { 9, 17 }, { 9, 15 }, { 9, 13 }, { 9, 11 }, { 9, 9 }, - { 9, 7 }, { 9, 5 }, { 9, 3 }, { 9, 1 }, { 8, 31 }, - { 8, 29 }, { 8, 27 }, { 8, 25 }, { 8, 23 }, { 8, 21 }, - { 8, 19 }, { 8, 17 }, { 8, 15 }, { 8, 13 }, { 8, 11 }, - { 8, 9 }, { 8, 7 }, { 8, 5 }, { 8, 3 }, { 8, 1 }, - { 7, 15 }, { 7, 13 }, { 7, 11 }, { 7, 9 }, { 7, 7 }, - { 7, 5 }, { 7, 3 }, { 7, 1 }, { 6, 7 }, { 6, 5 }, - { 6, 3 }, { 6, 1 }, { 5, 3 }, { 5, 1 }, { 4, 1 }, - { 3, 1 }, { 2, 1 }, { 1, 1 }, { 0, 0 }, { 1, 0 }, - { 2, 0 }, { 3, 0 }, { 4, 0 }, { 5, 0 }, { 5, 2 }, - { 6, 0 }, { 6, 2 }, { 6, 4 }, { 6, 6 }, { 7, 0 }, - { 7, 2 }, { 7, 4 }, { 7, 6 }, { 7, 8 }, { 7, 10 }, - { 7, 12 }, { 7, 14 }, { 8, 0 }, { 8, 2 }, { 8, 4 }, - { 8, 6 }, { 8, 8 }, { 8, 10 }, { 8, 12 }, { 8, 14 }, - { 8, 16 }, { 8, 18 }, { 8, 20 }, { 8, 22 }, { 8, 24 }, - { 8, 26 }, { 8, 28 }, { 8, 30 }, { 9, 0 }, { 9, 2 }, - { 9, 4 }, { 9, 6 }, { 9, 8 }, { 9, 10 }, { 9, 12 }, - { 9, 14 }, { 9, 16 }, { 9, 18 }, { 9, 20 }, { 9, 22 }, - { 9, 24 }, { 9, 26 }, { 9, 28 }, { 9, 30 }, { 9, 32 }, - { 9, 34 }, { 9, 36 }, { 9, 38 }, { 9, 40 }, { 9, 42 }, - { 9, 44 }, { 9, 46 }, { 9, 48 }, { 9, 50 }, { 9, 52 }, - { 9, 54 }, { 9, 56 }, { 9, 58 }, { 9, 60 }, { 9, 62 }, - { 10, 0 }, { 10, 2 }, { 10, 4 }, { 10, 6 }, { 10, 8 }, - { 10, 10 }, { 10, 12 }, { 10, 14 }, { 10, 16 }, { 10, 18 }, - { 10, 20 }, { 10, 22 }, { 10, 24 }, { 10, 26 }, { 10, 28 }, - { 10, 30 }, { 10, 32 }, { 10, 34 }, { 10, 36 }, { 10, 38 }, - { 10, 40 }, { 10, 42 }, { 10, 44 }, { 10, 46 }, { 10, 48 }, - { 10, 50 }, { 10, 52 }, { 10, 54 }, { 10, 56 }, { 10, 58 }, - { 10, 60 }, { 10, 62 }, { 10, 64 }, { 10, 66 }, { 10, 68 }, - { 10, 70 }, { 10, 72 }, { 10, 74 }, { 10, 76 }, { 10, 78 }, - { 10, 80 }, { 10, 82 }, { 10, 84 }, { 10, 86 }, { 10, 88 }, - { 10, 90 }, { 10, 92 }, { 10, 94 }, { 10, 96 }, { 10, 98 }, - { 10, 100 }, { 10, 102 }, { 10, 104 }, { 10, 106 }, { 10, 108 }, - { 10, 110 }, { 10, 112 }, { 10, 114 }, { 10, 116 }, { 10, 118 }, - { 10, 120 }, { 10, 122 }, { 10, 124 }, { 10, 126 }, { 10, 128 }, - { 10, 130 }, { 10, 132 }, { 10, 134 }, { 10, 136 }, { 10, 138 }, - { 10, 140 }, { 10, 142 }, { 10, 144 }, { 10, 146 }, { 10, 148 }, - { 10, 150 }, { 10, 152 }, { 10, 154 }, { 10, 156 }, { 10, 158 }, - { 10, 160 }, { 10, 162 }, { 10, 164 }, { 10, 166 }, { 10, 168 }, - { 10, 170 }, { 10, 172 }, { 10, 174 }, { 10, 176 }, { 10, 178 }, - { 10, 180 }, { 10, 182 }, { 10, 184 }, { 10, 186 }, { 10, 188 }, - { 10, 190 }, { 10, 192 }, { 10, 194 }, { 10, 196 }, { 10, 198 }, - { 10, 200 }, { 10, 202 }, { 10, 204 }, { 10, 206 }, { 10, 208 }, - { 10, 210 }, { 10, 212 }, { 10, 214 }, { 10, 216 }, { 10, 218 }, - { 10, 220 }, { 10, 222 }, { 10, 224 }, { 10, 226 }, { 10, 228 }, - { 10, 230 }, { 10, 232 }, { 10, 234 }, { 10, 236 }, { 10, 238 }, - { 10, 240 }, { 10, 242 }, { 10, 244 }, { 10, 246 }, { 10, 248 }, - { 10, 250 }, { 10, 252 }, { 10, 254 }, { 10, 256 }, { 10, 258 }, - { 10, 260 }, { 10, 262 }, { 10, 264 }, { 10, 266 }, { 10, 268 }, - { 10, 270 }, { 10, 272 }, { 10, 274 }, { 10, 276 }, { 10, 278 }, - { 10, 280 }, { 10, 282 }, { 10, 284 }, { 10, 286 }, { 10, 288 }, - { 10, 290 }, { 10, 292 }, { 10, 294 }, { 10, 296 }, { 10, 298 }, - { 10, 300 }, { 10, 302 }, { 10, 304 }, { 10, 306 }, { 10, 308 }, - { 10, 310 }, { 10, 312 }, { 10, 314 }, { 10, 316 }, { 10, 318 }, - { 10, 320 }, { 10, 322 }, { 10, 324 }, { 10, 326 }, { 10, 328 }, - { 10, 330 }, { 10, 332 }, { 10, 334 }, { 10, 336 }, { 10, 338 }, - { 10, 340 }, { 10, 342 }, { 10, 344 }, { 10, 346 }, { 10, 348 }, - { 10, 350 }, { 10, 352 }, { 10, 354 }, { 10, 356 }, { 10, 358 }, - { 10, 360 }, { 10, 362 }, { 10, 364 }, { 10, 366 }, { 10, 368 }, - { 10, 370 }, { 10, 372 }, { 10, 374 }, { 10, 376 }, { 10, 378 }, - { 10, 380 }, { 10, 382 }, { 10, 384 }, { 10, 386 }, { 10, 388 }, - { 10, 390 }, { 10, 392 }, { 10, 394 }, { 10, 396 }, { 10, 398 }, - { 10, 400 }, { 10, 402 }, { 10, 404 }, { 10, 406 }, { 10, 408 }, - { 10, 410 }, { 10, 412 }, { 10, 414 }, { 10, 416 }, { 10, 418 }, - { 10, 420 }, { 10, 422 }, { 10, 424 }, { 10, 426 }, { 10, 428 }, - { 10, 430 }, { 10, 432 }, { 10, 434 }, { 10, 436 }, { 10, 438 }, - { 10, 440 }, { 10, 442 }, { 10, 444 }, { 10, 446 }, { 10, 448 }, - { 10, 450 }, { 10, 452 }, { 10, 454 }, { 10, 456 }, { 10, 458 }, - { 10, 460 }, { 10, 462 }, { 10, 464 }, { 10, 466 }, { 10, 468 }, - { 10, 470 }, { 10, 472 }, { 10, 474 }, { 10, 476 }, { 10, 478 }, - { 10, 480 }, { 10, 482 }, { 10, 484 }, { 10, 486 }, { 10, 488 }, - { 10, 490 }, { 10, 492 }, { 10, 494 }, { 10, 496 }, { 10, 498 }, - { 10, 500 }, { 10, 502 }, { 10, 504 }, { 10, 506 }, { 10, 508 }, - { 10, 510 }, { 10, 512 }, { 10, 514 }, { 10, 516 }, { 10, 518 }, - { 10, 520 }, { 10, 522 }, { 10, 524 }, { 10, 526 }, { 10, 528 }, - { 10, 530 }, { 10, 532 }, { 10, 534 }, { 10, 536 }, { 10, 538 }, - { 10, 540 }, { 10, 542 }, { 10, 544 }, { 10, 546 }, { 10, 548 }, - { 10, 550 }, { 10, 552 }, { 10, 554 }, { 10, 556 }, { 10, 558 }, - { 10, 560 }, { 10, 562 }, { 10, 564 }, { 10, 566 }, { 10, 568 }, - { 10, 570 }, { 10, 572 }, { 10, 574 }, { 10, 576 }, { 10, 578 }, - { 10, 580 }, { 10, 582 }, { 10, 584 }, { 10, 586 }, { 10, 588 }, - { 10, 590 }, { 10, 592 }, { 10, 594 }, { 10, 596 }, { 10, 598 }, - { 10, 600 }, { 10, 602 }, { 10, 604 }, { 10, 606 }, { 10, 608 }, - { 10, 610 }, { 10, 612 }, { 10, 614 }, { 10, 616 }, { 10, 618 }, - { 10, 620 }, { 10, 622 }, { 10, 624 }, { 10, 626 }, { 10, 628 }, - { 10, 630 }, { 10, 632 }, { 10, 634 }, { 10, 636 }, { 10, 638 }, - { 10, 640 }, { 10, 642 }, { 10, 644 }, { 10, 646 }, { 10, 648 }, - { 10, 650 }, { 10, 652 }, { 10, 654 }, { 10, 656 }, { 10, 658 }, - { 10, 660 }, { 10, 662 }, { 10, 664 }, { 10, 666 }, { 10, 668 }, - { 10, 670 }, { 10, 672 }, { 10, 674 }, { 10, 676 }, { 10, 678 }, - { 10, 680 }, { 10, 682 }, { 10, 684 }, { 10, 686 }, { 10, 688 }, - { 10, 690 }, { 10, 692 }, { 10, 694 }, { 10, 696 }, { 10, 698 }, - { 10, 700 }, { 10, 702 }, { 10, 704 }, { 10, 706 }, { 10, 708 }, - { 10, 710 }, { 10, 712 }, { 10, 714 }, { 10, 716 }, { 10, 718 }, - { 10, 720 }, { 10, 722 }, { 10, 724 }, { 10, 726 }, { 10, 728 }, - { 10, 730 }, { 10, 732 }, { 10, 734 }, { 10, 736 }, { 10, 738 }, - { 10, 740 }, { 10, 742 }, { 10, 744 }, { 10, 746 }, { 10, 748 }, - { 10, 750 }, { 10, 752 }, { 10, 754 }, { 10, 756 }, { 10, 758 }, - { 10, 760 }, { 10, 762 }, { 10, 764 }, { 10, 766 }, { 10, 768 }, - { 10, 770 }, { 10, 772 }, { 10, 774 }, { 10, 776 }, { 10, 778 }, - { 10, 780 }, { 10, 782 }, { 10, 784 }, { 10, 786 }, { 10, 788 }, - { 10, 790 }, { 10, 792 }, { 10, 794 }, { 10, 796 }, { 10, 798 }, - { 10, 800 }, { 10, 802 }, { 10, 804 }, { 10, 806 }, { 10, 808 }, - { 10, 810 }, { 10, 812 }, { 10, 814 }, { 10, 816 }, { 10, 818 }, - { 10, 820 }, { 10, 822 }, { 10, 824 }, { 10, 826 }, { 10, 828 }, - { 10, 830 }, { 10, 832 }, { 10, 834 }, { 10, 836 }, { 10, 838 }, - { 10, 840 }, { 10, 842 }, { 10, 844 }, { 10, 846 }, { 10, 848 }, - { 10, 850 }, { 10, 852 }, { 10, 854 }, { 10, 856 }, { 10, 858 }, - { 10, 860 }, { 10, 862 }, { 10, 864 }, { 10, 866 }, { 10, 868 }, - { 10, 870 }, { 10, 872 }, { 10, 874 }, { 10, 876 }, { 10, 878 }, - { 10, 880 }, { 10, 882 }, { 10, 884 }, { 10, 886 }, { 10, 888 }, - { 10, 890 }, { 10, 892 }, { 10, 894 }, { 10, 896 }, { 10, 898 }, - { 10, 900 }, { 10, 902 }, { 10, 904 }, { 10, 906 }, { 10, 908 }, - { 10, 910 }, { 10, 912 }, { 10, 914 }, { 10, 916 }, { 10, 918 }, - { 10, 920 }, { 10, 922 }, { 10, 924 }, { 10, 926 }, { 10, 928 }, - { 10, 930 }, { 10, 932 }, { 10, 934 }, { 10, 936 }, { 10, 938 }, - { 10, 940 }, { 10, 942 }, { 10, 944 }, { 10, 946 }, { 10, 948 }, - { 10, 950 }, { 10, 952 }, { 10, 954 }, { 10, 956 }, { 10, 958 }, - { 10, 960 }, { 10, 962 }, { 10, 964 }, { 10, 966 }, { 10, 968 }, - { 10, 970 }, { 10, 972 }, { 10, 974 }, { 10, 976 }, { 10, 978 }, - { 10, 980 }, { 10, 982 }, { 10, 984 }, { 10, 986 }, { 10, 988 }, - { 10, 990 }, { 10, 992 }, { 10, 994 }, { 10, 996 }, { 10, 998 }, - { 10, 1000 }, { 10, 1002 }, { 10, 1004 }, { 10, 1006 }, { 10, 1008 }, - { 10, 1010 }, { 10, 1012 }, { 10, 1014 }, { 10, 1016 }, { 10, 1018 }, - { 10, 1020 }, { 10, 1022 }, { 10, 1024 }, { 10, 1026 }, { 10, 1028 }, - { 10, 1030 }, { 10, 1032 }, { 10, 1034 }, { 10, 1036 }, { 10, 1038 }, - { 10, 1040 }, { 10, 1042 }, { 10, 1044 }, { 10, 1046 }, { 10, 1048 }, - { 10, 1050 }, { 10, 1052 }, { 10, 1054 }, { 10, 1056 }, { 10, 1058 }, - { 10, 1060 }, { 10, 1062 }, { 10, 1064 }, { 10, 1066 }, { 10, 1068 }, - { 10, 1070 }, { 10, 1072 }, { 10, 1074 }, { 10, 1076 }, { 10, 1078 }, - { 10, 1080 }, { 10, 1082 }, { 10, 1084 }, { 10, 1086 }, { 10, 1088 }, - { 10, 1090 }, { 10, 1092 }, { 10, 1094 }, { 10, 1096 }, { 10, 1098 }, - { 10, 1100 }, { 10, 1102 }, { 10, 1104 }, { 10, 1106 }, { 10, 1108 }, - { 10, 1110 }, { 10, 1112 }, { 10, 1114 }, { 10, 1116 }, { 10, 1118 }, - { 10, 1120 }, { 10, 1122 }, { 10, 1124 }, { 10, 1126 }, { 10, 1128 }, - { 10, 1130 }, { 10, 1132 }, { 10, 1134 }, { 10, 1136 }, { 10, 1138 }, - { 10, 1140 }, { 10, 1142 }, { 10, 1144 }, { 10, 1146 }, { 10, 1148 }, - { 10, 1150 }, { 10, 1152 }, { 10, 1154 }, { 10, 1156 }, { 10, 1158 }, - { 10, 1160 }, { 10, 1162 }, { 10, 1164 }, { 10, 1166 }, { 10, 1168 }, - { 10, 1170 }, { 10, 1172 }, { 10, 1174 }, { 10, 1176 }, { 10, 1178 }, - { 10, 1180 }, { 10, 1182 }, { 10, 1184 }, { 10, 1186 }, { 10, 1188 }, - { 10, 1190 }, { 10, 1192 }, { 10, 1194 }, { 10, 1196 }, { 10, 1198 }, - { 10, 1200 }, { 10, 1202 }, { 10, 1204 }, { 10, 1206 }, { 10, 1208 }, - { 10, 1210 }, { 10, 1212 }, { 10, 1214 }, { 10, 1216 }, { 10, 1218 }, - { 10, 1220 }, { 10, 1222 }, { 10, 1224 }, { 10, 1226 }, { 10, 1228 }, - { 10, 1230 }, { 10, 1232 }, { 10, 1234 }, { 10, 1236 }, { 10, 1238 }, - { 10, 1240 }, { 10, 1242 }, { 10, 1244 }, { 10, 1246 }, { 10, 1248 }, - { 10, 1250 }, { 10, 1252 }, { 10, 1254 }, { 10, 1256 }, { 10, 1258 }, - { 10, 1260 }, { 10, 1262 }, { 10, 1264 }, { 10, 1266 }, { 10, 1268 }, - { 10, 1270 }, { 10, 1272 }, { 10, 1274 }, { 10, 1276 }, { 10, 1278 }, - { 10, 1280 }, { 10, 1282 }, { 10, 1284 }, { 10, 1286 }, { 10, 1288 }, - { 10, 1290 }, { 10, 1292 }, { 10, 1294 }, { 10, 1296 }, { 10, 1298 }, - { 10, 1300 }, { 10, 1302 }, { 10, 1304 }, { 10, 1306 }, { 10, 1308 }, - { 10, 1310 }, { 10, 1312 }, { 10, 1314 }, { 10, 1316 }, { 10, 1318 }, - { 10, 1320 }, { 10, 1322 }, { 10, 1324 }, { 10, 1326 }, { 10, 1328 }, - { 10, 1330 }, { 10, 1332 }, { 10, 1334 }, { 10, 1336 }, { 10, 1338 }, - { 10, 1340 }, { 10, 1342 }, { 10, 1344 }, { 10, 1346 }, { 10, 1348 }, - { 10, 1350 }, { 10, 1352 }, { 10, 1354 }, { 10, 1356 }, { 10, 1358 }, - { 10, 1360 }, { 10, 1362 }, { 10, 1364 }, { 10, 1366 }, { 10, 1368 }, - { 10, 1370 }, { 10, 1372 }, { 10, 1374 }, { 10, 1376 }, { 10, 1378 }, - { 10, 1380 }, { 10, 1382 }, { 10, 1384 }, { 10, 1386 }, { 10, 1388 }, - { 10, 1390 }, { 10, 1392 }, { 10, 1394 }, { 10, 1396 }, { 10, 1398 }, - { 10, 1400 }, { 10, 1402 }, { 10, 1404 }, { 10, 1406 }, { 10, 1408 }, - { 10, 1410 }, { 10, 1412 }, { 10, 1414 }, { 10, 1416 }, { 10, 1418 }, - { 10, 1420 }, { 10, 1422 }, { 10, 1424 }, { 10, 1426 }, { 10, 1428 }, - { 10, 1430 }, { 10, 1432 }, { 10, 1434 }, { 10, 1436 }, { 10, 1438 }, - { 10, 1440 }, { 10, 1442 }, { 10, 1444 }, { 10, 1446 }, { 10, 1448 }, - { 10, 1450 }, { 10, 1452 }, { 10, 1454 }, { 10, 1456 }, { 10, 1458 }, - { 10, 1460 }, { 10, 1462 }, { 10, 1464 }, { 10, 1466 }, { 10, 1468 }, - { 10, 1470 }, { 10, 1472 }, { 10, 1474 }, { 10, 1476 }, { 10, 1478 }, - { 10, 1480 }, { 10, 1482 }, { 10, 1484 }, { 10, 1486 }, { 10, 1488 }, - { 10, 1490 }, { 10, 1492 }, { 10, 1494 }, { 10, 1496 }, { 10, 1498 }, - { 10, 1500 }, { 10, 1502 }, { 10, 1504 }, { 10, 1506 }, { 10, 1508 }, - { 10, 1510 }, { 10, 1512 }, { 10, 1514 }, { 10, 1516 }, { 10, 1518 }, - { 10, 1520 }, { 10, 1522 }, { 10, 1524 }, { 10, 1526 }, { 10, 1528 }, - { 10, 1530 }, { 10, 1532 }, { 10, 1534 }, { 10, 1536 }, { 10, 1538 }, - { 10, 1540 }, { 10, 1542 }, { 10, 1544 }, { 10, 1546 }, { 10, 1548 }, - { 10, 1550 }, { 10, 1552 }, { 10, 1554 }, { 10, 1556 }, { 10, 1558 }, - { 10, 1560 }, { 10, 1562 }, { 10, 1564 }, { 10, 1566 }, { 10, 1568 }, - { 10, 1570 }, { 10, 1572 }, { 10, 1574 }, { 10, 1576 }, { 10, 1578 }, - { 10, 1580 }, { 10, 1582 }, { 10, 1584 }, { 10, 1586 }, { 10, 1588 }, - { 10, 1590 }, { 10, 1592 }, { 10, 1594 }, { 10, 1596 }, { 10, 1598 }, - { 10, 1600 }, { 10, 1602 }, { 10, 1604 }, { 10, 1606 }, { 10, 1608 }, - { 10, 1610 }, { 10, 1612 }, { 10, 1614 }, { 10, 1616 }, { 10, 1618 }, - { 10, 1620 }, { 10, 1622 }, { 10, 1624 }, { 10, 1626 }, { 10, 1628 }, - { 10, 1630 }, { 10, 1632 }, { 10, 1634 }, { 10, 1636 }, { 10, 1638 }, - { 10, 1640 }, { 10, 1642 }, { 10, 1644 }, { 10, 1646 }, { 10, 1648 }, - { 10, 1650 }, { 10, 1652 }, { 10, 1654 }, { 10, 1656 }, { 10, 1658 }, - { 10, 1660 }, { 10, 1662 }, { 10, 1664 }, { 10, 1666 }, { 10, 1668 }, - { 10, 1670 }, { 10, 1672 }, { 10, 1674 }, { 10, 1676 }, { 10, 1678 }, - { 10, 1680 }, { 10, 1682 }, { 10, 1684 }, { 10, 1686 }, { 10, 1688 }, - { 10, 1690 }, { 10, 1692 }, { 10, 1694 }, { 10, 1696 }, { 10, 1698 }, - { 10, 1700 }, { 10, 1702 }, { 10, 1704 }, { 10, 1706 }, { 10, 1708 }, - { 10, 1710 }, { 10, 1712 }, { 10, 1714 }, { 10, 1716 }, { 10, 1718 }, - { 10, 1720 }, { 10, 1722 }, { 10, 1724 }, { 10, 1726 }, { 10, 1728 }, - { 10, 1730 }, { 10, 1732 }, { 10, 1734 }, { 10, 1736 }, { 10, 1738 }, - { 10, 1740 }, { 10, 1742 }, { 10, 1744 }, { 10, 1746 }, { 10, 1748 }, - { 10, 1750 }, { 10, 1752 }, { 10, 1754 }, { 10, 1756 }, { 10, 1758 }, - { 10, 1760 }, { 10, 1762 }, { 10, 1764 }, { 10, 1766 }, { 10, 1768 }, - { 10, 1770 }, { 10, 1772 }, { 10, 1774 }, { 10, 1776 }, { 10, 1778 }, - { 10, 1780 }, { 10, 1782 }, { 10, 1784 }, { 10, 1786 }, { 10, 1788 }, - { 10, 1790 }, { 10, 1792 }, { 10, 1794 }, { 10, 1796 }, { 10, 1798 }, - { 10, 1800 }, { 10, 1802 }, { 10, 1804 }, { 10, 1806 }, { 10, 1808 }, - { 10, 1810 }, { 10, 1812 }, { 10, 1814 }, { 10, 1816 }, { 10, 1818 }, - { 10, 1820 }, { 10, 1822 }, { 10, 1824 }, { 10, 1826 }, { 10, 1828 }, - { 10, 1830 }, { 10, 1832 }, { 10, 1834 }, { 10, 1836 }, { 10, 1838 }, - { 10, 1840 }, { 10, 1842 }, { 10, 1844 }, { 10, 1846 }, { 10, 1848 }, - { 10, 1850 }, { 10, 1852 }, { 10, 1854 }, { 10, 1856 }, { 10, 1858 }, - { 10, 1860 }, { 10, 1862 }, { 10, 1864 }, { 10, 1866 }, { 10, 1868 }, - { 10, 1870 }, { 10, 1872 }, { 10, 1874 }, { 10, 1876 }, { 10, 1878 }, - { 10, 1880 }, { 10, 1882 }, { 10, 1884 }, { 10, 1886 }, { 10, 1888 }, - { 10, 1890 }, { 10, 1892 }, { 10, 1894 }, { 10, 1896 }, { 10, 1898 }, - { 10, 1900 }, { 10, 1902 }, { 10, 1904 }, { 10, 1906 }, { 10, 1908 }, - { 10, 1910 }, { 10, 1912 }, { 10, 1914 }, { 10, 1916 }, { 10, 1918 }, - { 10, 1920 }, { 10, 1922 }, { 10, 1924 }, { 10, 1926 }, { 10, 1928 }, - { 10, 1930 }, { 10, 1932 }, { 10, 1934 }, { 10, 1936 }, { 10, 1938 }, - { 10, 1940 }, { 10, 1942 }, { 10, 1944 }, { 10, 1946 }, { 10, 1948 }, - { 10, 1950 }, { 10, 1952 }, { 10, 1954 }, { 10, 1956 }, { 10, 1958 }, - { 10, 1960 }, { 10, 1962 }, { 10, 1964 }, { 10, 1966 }, { 10, 1968 }, - { 10, 1970 }, { 10, 1972 }, { 10, 1974 }, { 10, 1976 }, { 10, 1978 }, - { 10, 1980 }, { 10, 1982 }, { 10, 1984 }, { 10, 1986 }, { 10, 1988 }, - { 10, 1990 }, { 10, 1992 }, { 10, 1994 }, { 10, 1996 }, { 10, 1998 }, - { 10, 2000 }, { 10, 2002 }, { 10, 2004 }, { 10, 2006 }, { 10, 2008 }, - { 10, 2010 }, { 10, 2012 }, { 10, 2014 }, { 10, 2016 }, { 10, 2018 }, - { 10, 2020 }, { 10, 2022 }, { 10, 2024 }, { 10, 2026 }, { 10, 2028 }, - { 10, 2030 }, { 10, 2032 }, { 10, 2034 }, { 10, 2036 }, { 10, 2038 }, - { 10, 2040 }, { 10, 2042 }, { 10, 2044 }, { 10, 2046 }, { 10, 2048 }, - { 10, 2050 }, { 10, 2052 }, { 10, 2054 }, { 10, 2056 }, { 10, 2058 }, - { 10, 2060 }, { 10, 2062 }, { 10, 2064 }, { 10, 2066 }, { 10, 2068 }, - { 10, 2070 }, { 10, 2072 }, { 10, 2074 }, { 10, 2076 }, { 10, 2078 }, - { 10, 2080 }, { 10, 2082 }, { 10, 2084 }, { 10, 2086 }, { 10, 2088 }, - { 10, 2090 }, { 10, 2092 }, { 10, 2094 }, { 10, 2096 }, { 10, 2098 }, - { 10, 2100 }, { 10, 2102 }, { 10, 2104 }, { 10, 2106 }, { 10, 2108 }, - { 10, 2110 }, { 10, 2112 }, { 10, 2114 }, { 10, 2116 }, { 10, 2118 }, - { 10, 2120 }, { 10, 2122 }, { 10, 2124 }, { 10, 2126 }, { 10, 2128 }, - { 10, 2130 }, { 10, 2132 }, { 10, 2134 }, { 10, 2136 }, { 10, 2138 }, - { 10, 2140 }, { 10, 2142 }, { 10, 2144 }, { 10, 2146 }, { 10, 2148 }, - { 10, 2150 }, { 10, 2152 }, { 10, 2154 }, { 10, 2156 }, { 10, 2158 }, - { 10, 2160 }, { 10, 2162 }, { 10, 2164 }, { 10, 2166 }, { 10, 2168 }, - { 10, 2170 }, { 10, 2172 }, { 10, 2174 }, { 10, 2176 }, { 10, 2178 }, - { 10, 2180 }, { 10, 2182 }, { 10, 2184 }, { 10, 2186 }, { 10, 2188 }, - { 10, 2190 }, { 10, 2192 }, { 10, 2194 }, { 10, 2196 }, { 10, 2198 }, - { 10, 2200 }, { 10, 2202 }, { 10, 2204 }, { 10, 2206 }, { 10, 2208 }, - { 10, 2210 }, { 10, 2212 }, { 10, 2214 }, { 10, 2216 }, { 10, 2218 }, - { 10, 2220 }, { 10, 2222 }, { 10, 2224 }, { 10, 2226 }, { 10, 2228 }, - { 10, 2230 }, { 10, 2232 }, { 10, 2234 }, { 10, 2236 }, { 10, 2238 }, - { 10, 2240 }, { 10, 2242 }, { 10, 2244 }, { 10, 2246 }, { 10, 2248 }, - { 10, 2250 }, { 10, 2252 }, { 10, 2254 }, { 10, 2256 }, { 10, 2258 }, - { 10, 2260 }, { 10, 2262 }, { 10, 2264 }, { 10, 2266 }, { 10, 2268 }, - { 10, 2270 }, { 10, 2272 }, { 10, 2274 }, { 10, 2276 }, { 10, 2278 }, - { 10, 2280 }, { 10, 2282 }, { 10, 2284 }, { 10, 2286 }, { 10, 2288 }, - { 10, 2290 }, { 10, 2292 }, { 10, 2294 }, { 10, 2296 }, { 10, 2298 }, - { 10, 2300 }, { 10, 2302 }, { 10, 2304 }, { 10, 2306 }, { 10, 2308 }, - { 10, 2310 }, { 10, 2312 }, { 10, 2314 }, { 10, 2316 }, { 10, 2318 }, - { 10, 2320 }, { 10, 2322 }, { 10, 2324 }, { 10, 2326 }, { 10, 2328 }, - { 10, 2330 }, { 10, 2332 }, { 10, 2334 }, { 10, 2336 }, { 10, 2338 }, - { 10, 2340 }, { 10, 2342 }, { 10, 2344 }, { 10, 2346 }, { 10, 2348 }, - { 10, 2350 }, { 10, 2352 }, { 10, 2354 }, { 10, 2356 }, { 10, 2358 }, - { 10, 2360 }, { 10, 2362 }, { 10, 2364 }, { 10, 2366 }, { 10, 2368 }, - { 10, 2370 }, { 10, 2372 }, { 10, 2374 }, { 10, 2376 }, { 10, 2378 }, - { 10, 2380 }, { 10, 2382 }, { 10, 2384 }, { 10, 2386 }, { 10, 2388 }, - { 10, 2390 }, { 10, 2392 }, { 10, 2394 }, { 10, 2396 }, { 10, 2398 }, - { 10, 2400 }, { 10, 2402 }, { 10, 2404 }, { 10, 2406 }, { 10, 2408 }, - { 10, 2410 }, { 10, 2412 }, { 10, 2414 }, { 10, 2416 }, { 10, 2418 }, - { 10, 2420 }, { 10, 2422 }, { 10, 2424 }, { 10, 2426 }, { 10, 2428 }, - { 10, 2430 }, { 10, 2432 }, { 10, 2434 }, { 10, 2436 }, { 10, 2438 }, - { 10, 2440 }, { 10, 2442 }, { 10, 2444 }, { 10, 2446 }, { 10, 2448 }, - { 10, 2450 }, { 10, 2452 }, { 10, 2454 }, { 10, 2456 }, { 10, 2458 }, - { 10, 2460 }, { 10, 2462 }, { 10, 2464 }, { 10, 2466 }, { 10, 2468 }, - { 10, 2470 }, { 10, 2472 }, { 10, 2474 }, { 10, 2476 }, { 10, 2478 }, - { 10, 2480 }, { 10, 2482 }, { 10, 2484 }, { 10, 2486 }, { 10, 2488 }, - { 10, 2490 }, { 10, 2492 }, { 10, 2494 }, { 10, 2496 }, { 10, 2498 }, - { 10, 2500 }, { 10, 2502 }, { 10, 2504 }, { 10, 2506 }, { 10, 2508 }, - { 10, 2510 }, { 10, 2512 }, { 10, 2514 }, { 10, 2516 }, { 10, 2518 }, - { 10, 2520 }, { 10, 2522 }, { 10, 2524 }, { 10, 2526 }, { 10, 2528 }, - { 10, 2530 }, { 10, 2532 }, { 10, 2534 }, { 10, 2536 }, { 10, 2538 }, - { 10, 2540 }, { 10, 2542 }, { 10, 2544 }, { 10, 2546 }, { 10, 2548 }, - { 10, 2550 }, { 10, 2552 }, { 10, 2554 }, { 10, 2556 }, { 10, 2558 }, - { 10, 2560 }, { 10, 2562 }, { 10, 2564 }, { 10, 2566 }, { 10, 2568 }, - { 10, 2570 }, { 10, 2572 }, { 10, 2574 }, { 10, 2576 }, { 10, 2578 }, - { 10, 2580 }, { 10, 2582 }, { 10, 2584 }, { 10, 2586 }, { 10, 2588 }, - { 10, 2590 }, { 10, 2592 }, { 10, 2594 }, { 10, 2596 }, { 10, 2598 }, - { 10, 2600 }, { 10, 2602 }, { 10, 2604 }, { 10, 2606 }, { 10, 2608 }, - { 10, 2610 }, { 10, 2612 }, { 10, 2614 }, { 10, 2616 }, { 10, 2618 }, - { 10, 2620 }, { 10, 2622 }, { 10, 2624 }, { 10, 2626 }, { 10, 2628 }, - { 10, 2630 }, { 10, 2632 }, { 10, 2634 }, { 10, 2636 }, { 10, 2638 }, - { 10, 2640 }, { 10, 2642 }, { 10, 2644 }, { 10, 2646 }, { 10, 2648 }, - { 10, 2650 }, { 10, 2652 }, { 10, 2654 }, { 10, 2656 }, { 10, 2658 }, - { 10, 2660 }, { 10, 2662 }, { 10, 2664 }, { 10, 2666 }, { 10, 2668 }, - { 10, 2670 }, { 10, 2672 }, { 10, 2674 }, { 10, 2676 }, { 10, 2678 }, - { 10, 2680 }, { 10, 2682 }, { 10, 2684 }, { 10, 2686 }, { 10, 2688 }, - { 10, 2690 }, { 10, 2692 }, { 10, 2694 }, { 10, 2696 }, { 10, 2698 }, - { 10, 2700 }, { 10, 2702 }, { 10, 2704 }, { 10, 2706 }, { 10, 2708 }, - { 10, 2710 }, { 10, 2712 }, { 10, 2714 }, { 10, 2716 }, { 10, 2718 }, - { 10, 2720 }, { 10, 2722 }, { 10, 2724 }, { 10, 2726 }, { 10, 2728 }, - { 10, 2730 }, { 10, 2732 }, { 10, 2734 }, { 10, 2736 }, { 10, 2738 }, - { 10, 2740 }, { 10, 2742 }, { 10, 2744 }, { 10, 2746 }, { 10, 2748 }, - { 10, 2750 }, { 10, 2752 }, { 10, 2754 }, { 10, 2756 }, { 10, 2758 }, - { 10, 2760 }, { 10, 2762 }, { 10, 2764 }, { 10, 2766 }, { 10, 2768 }, - { 10, 2770 }, { 10, 2772 }, { 10, 2774 }, { 10, 2776 }, { 10, 2778 }, - { 10, 2780 }, { 10, 2782 }, { 10, 2784 }, { 10, 2786 }, { 10, 2788 }, - { 10, 2790 }, { 10, 2792 }, { 10, 2794 }, { 10, 2796 }, { 10, 2798 }, - { 10, 2800 }, { 10, 2802 }, { 10, 2804 }, { 10, 2806 }, { 10, 2808 }, - { 10, 2810 }, { 10, 2812 }, { 10, 2814 }, { 10, 2816 }, { 10, 2818 }, - { 10, 2820 }, { 10, 2822 }, { 10, 2824 }, { 10, 2826 }, { 10, 2828 }, - { 10, 2830 }, { 10, 2832 }, { 10, 2834 }, { 10, 2836 }, { 10, 2838 }, - { 10, 2840 }, { 10, 2842 }, { 10, 2844 }, { 10, 2846 }, { 10, 2848 }, - { 10, 2850 }, { 10, 2852 }, { 10, 2854 }, { 10, 2856 }, { 10, 2858 }, - { 10, 2860 }, { 10, 2862 }, { 10, 2864 }, { 10, 2866 }, { 10, 2868 }, - { 10, 2870 }, { 10, 2872 }, { 10, 2874 }, { 10, 2876 }, { 10, 2878 }, - { 10, 2880 }, { 10, 2882 }, { 10, 2884 }, { 10, 2886 }, { 10, 2888 }, - { 10, 2890 }, { 10, 2892 }, { 10, 2894 }, { 10, 2896 }, { 10, 2898 }, - { 10, 2900 }, { 10, 2902 }, { 10, 2904 }, { 10, 2906 }, { 10, 2908 }, - { 10, 2910 }, { 10, 2912 }, { 10, 2914 }, { 10, 2916 }, { 10, 2918 }, - { 10, 2920 }, { 10, 2922 }, { 10, 2924 }, { 10, 2926 }, { 10, 2928 }, - { 10, 2930 }, { 10, 2932 }, { 10, 2934 }, { 10, 2936 }, { 10, 2938 }, - { 10, 2940 }, { 10, 2942 }, { 10, 2944 }, { 10, 2946 }, { 10, 2948 }, - { 10, 2950 }, { 10, 2952 }, { 10, 2954 }, { 10, 2956 }, { 10, 2958 }, - { 10, 2960 }, { 10, 2962 }, { 10, 2964 }, { 10, 2966 }, { 10, 2968 }, - { 10, 2970 }, { 10, 2972 }, { 10, 2974 }, { 10, 2976 }, { 10, 2978 }, - { 10, 2980 }, { 10, 2982 }, { 10, 2984 }, { 10, 2986 }, { 10, 2988 }, - { 10, 2990 }, { 10, 2992 }, { 10, 2994 }, { 10, 2996 }, { 10, 2998 }, - { 10, 3000 }, { 10, 3002 }, { 10, 3004 }, { 10, 3006 }, { 10, 3008 }, - { 10, 3010 }, { 10, 3012 }, { 10, 3014 }, { 10, 3016 }, { 10, 3018 }, - { 10, 3020 }, { 10, 3022 }, { 10, 3024 }, { 10, 3026 }, { 10, 3028 }, - { 10, 3030 }, { 10, 3032 }, { 10, 3034 }, { 10, 3036 }, { 10, 3038 }, - { 10, 3040 }, { 10, 3042 }, { 10, 3044 }, { 10, 3046 }, { 10, 3048 }, - { 10, 3050 }, { 10, 3052 }, { 10, 3054 }, { 10, 3056 }, { 10, 3058 }, - { 10, 3060 }, { 10, 3062 }, { 10, 3064 }, { 10, 3066 }, { 10, 3068 }, - { 10, 3070 }, { 10, 3072 }, { 10, 3074 }, { 10, 3076 }, { 10, 3078 }, - { 10, 3080 }, { 10, 3082 }, { 10, 3084 }, { 10, 3086 }, { 10, 3088 }, - { 10, 3090 }, { 10, 3092 }, { 10, 3094 }, { 10, 3096 }, { 10, 3098 }, - { 10, 3100 }, { 10, 3102 }, { 10, 3104 }, { 10, 3106 }, { 10, 3108 }, - { 10, 3110 }, { 10, 3112 }, { 10, 3114 }, { 10, 3116 }, { 10, 3118 }, - { 10, 3120 }, { 10, 3122 }, { 10, 3124 }, { 10, 3126 }, { 10, 3128 }, - { 10, 3130 }, { 10, 3132 }, { 10, 3134 }, { 10, 3136 }, { 10, 3138 }, - { 10, 3140 }, { 10, 3142 }, { 10, 3144 }, { 10, 3146 }, { 10, 3148 }, - { 10, 3150 }, { 10, 3152 }, { 10, 3154 }, { 10, 3156 }, { 10, 3158 }, - { 10, 3160 }, { 10, 3162 }, { 10, 3164 }, { 10, 3166 }, { 10, 3168 }, - { 10, 3170 }, { 10, 3172 }, { 10, 3174 }, { 10, 3176 }, { 10, 3178 }, - { 10, 3180 }, { 10, 3182 }, { 10, 3184 }, { 10, 3186 }, { 10, 3188 }, - { 10, 3190 }, { 10, 3192 }, { 10, 3194 }, { 10, 3196 }, { 10, 3198 }, - { 10, 3200 }, { 10, 3202 }, { 10, 3204 }, { 10, 3206 }, { 10, 3208 }, - { 10, 3210 }, { 10, 3212 }, { 10, 3214 }, { 10, 3216 }, { 10, 3218 }, - { 10, 3220 }, { 10, 3222 }, { 10, 3224 }, { 10, 3226 }, { 10, 3228 }, - { 10, 3230 }, { 10, 3232 }, { 10, 3234 }, { 10, 3236 }, { 10, 3238 }, - { 10, 3240 }, { 10, 3242 }, { 10, 3244 }, { 10, 3246 }, { 10, 3248 }, - { 10, 3250 }, { 10, 3252 }, { 10, 3254 }, { 10, 3256 }, { 10, 3258 }, - { 10, 3260 }, { 10, 3262 }, { 10, 3264 }, { 10, 3266 }, { 10, 3268 }, - { 10, 3270 }, { 10, 3272 }, { 10, 3274 }, { 10, 3276 }, { 10, 3278 }, - { 10, 3280 }, { 10, 3282 }, { 10, 3284 }, { 10, 3286 }, { 10, 3288 }, - { 10, 3290 }, { 10, 3292 }, { 10, 3294 }, { 10, 3296 }, { 10, 3298 }, - { 10, 3300 }, { 10, 3302 }, { 10, 3304 }, { 10, 3306 }, { 10, 3308 }, - { 10, 3310 }, { 10, 3312 }, { 10, 3314 }, { 10, 3316 }, { 10, 3318 }, - { 10, 3320 }, { 10, 3322 }, { 10, 3324 }, { 10, 3326 }, { 10, 3328 }, - { 10, 3330 }, { 10, 3332 }, { 10, 3334 }, { 10, 3336 }, { 10, 3338 }, - { 10, 3340 }, { 10, 3342 }, { 10, 3344 }, { 10, 3346 }, { 10, 3348 }, - { 10, 3350 }, { 10, 3352 }, { 10, 3354 }, { 10, 3356 }, { 10, 3358 }, - { 10, 3360 }, { 10, 3362 }, { 10, 3364 }, { 10, 3366 }, { 10, 3368 }, - { 10, 3370 }, { 10, 3372 }, { 10, 3374 }, { 10, 3376 }, { 10, 3378 }, - { 10, 3380 }, { 10, 3382 }, { 10, 3384 }, { 10, 3386 }, { 10, 3388 }, - { 10, 3390 }, { 10, 3392 }, { 10, 3394 }, { 10, 3396 }, { 10, 3398 }, - { 10, 3400 }, { 10, 3402 }, { 10, 3404 }, { 10, 3406 }, { 10, 3408 }, - { 10, 3410 }, { 10, 3412 }, { 10, 3414 }, { 10, 3416 }, { 10, 3418 }, - { 10, 3420 }, { 10, 3422 }, { 10, 3424 }, { 10, 3426 }, { 10, 3428 }, - { 10, 3430 }, { 10, 3432 }, { 10, 3434 }, { 10, 3436 }, { 10, 3438 }, - { 10, 3440 }, { 10, 3442 }, { 10, 3444 }, { 10, 3446 }, { 10, 3448 }, - { 10, 3450 }, { 10, 3452 }, { 10, 3454 }, { 10, 3456 }, { 10, 3458 }, - { 10, 3460 }, { 10, 3462 }, { 10, 3464 }, { 10, 3466 }, { 10, 3468 }, - { 10, 3470 }, { 10, 3472 }, { 10, 3474 }, { 10, 3476 }, { 10, 3478 }, - { 10, 3480 }, { 10, 3482 }, { 10, 3484 }, { 10, 3486 }, { 10, 3488 }, - { 10, 3490 }, { 10, 3492 }, { 10, 3494 }, { 10, 3496 }, { 10, 3498 }, - { 10, 3500 }, { 10, 3502 }, { 10, 3504 }, { 10, 3506 }, { 10, 3508 }, - { 10, 3510 }, { 10, 3512 }, { 10, 3514 }, { 10, 3516 }, { 10, 3518 }, - { 10, 3520 }, { 10, 3522 }, { 10, 3524 }, { 10, 3526 }, { 10, 3528 }, - { 10, 3530 }, { 10, 3532 }, { 10, 3534 }, { 10, 3536 }, { 10, 3538 }, - { 10, 3540 }, { 10, 3542 }, { 10, 3544 }, { 10, 3546 }, { 10, 3548 }, - { 10, 3550 }, { 10, 3552 }, { 10, 3554 }, { 10, 3556 }, { 10, 3558 }, - { 10, 3560 }, { 10, 3562 }, { 10, 3564 }, { 10, 3566 }, { 10, 3568 }, - { 10, 3570 }, { 10, 3572 }, { 10, 3574 }, { 10, 3576 }, { 10, 3578 }, - { 10, 3580 }, { 10, 3582 }, { 10, 3584 }, { 10, 3586 }, { 10, 3588 }, - { 10, 3590 }, { 10, 3592 }, { 10, 3594 }, { 10, 3596 }, { 10, 3598 }, - { 10, 3600 }, { 10, 3602 }, { 10, 3604 }, { 10, 3606 }, { 10, 3608 }, - { 10, 3610 }, { 10, 3612 }, { 10, 3614 }, { 10, 3616 }, { 10, 3618 }, - { 10, 3620 }, { 10, 3622 }, { 10, 3624 }, { 10, 3626 }, { 10, 3628 }, - { 10, 3630 }, { 10, 3632 }, { 10, 3634 }, { 10, 3636 }, { 10, 3638 }, - { 10, 3640 }, { 10, 3642 }, { 10, 3644 }, { 10, 3646 }, { 10, 3648 }, - { 10, 3650 }, { 10, 3652 }, { 10, 3654 }, { 10, 3656 }, { 10, 3658 }, - { 10, 3660 }, { 10, 3662 }, { 10, 3664 }, { 10, 3666 }, { 10, 3668 }, - { 10, 3670 }, { 10, 3672 }, { 10, 3674 }, { 10, 3676 }, { 10, 3678 }, - { 10, 3680 }, { 10, 3682 }, { 10, 3684 }, { 10, 3686 }, { 10, 3688 }, - { 10, 3690 }, { 10, 3692 }, { 10, 3694 }, { 10, 3696 }, { 10, 3698 }, - { 10, 3700 }, { 10, 3702 }, { 10, 3704 }, { 10, 3706 }, { 10, 3708 }, - { 10, 3710 }, { 10, 3712 }, { 10, 3714 }, { 10, 3716 }, { 10, 3718 }, - { 10, 3720 }, { 10, 3722 }, { 10, 3724 }, { 10, 3726 }, { 10, 3728 }, - { 10, 3730 }, { 10, 3732 }, { 10, 3734 }, { 10, 3736 }, { 10, 3738 }, - { 10, 3740 }, { 10, 3742 }, { 10, 3744 }, { 10, 3746 }, { 10, 3748 }, - { 10, 3750 }, { 10, 3752 }, { 10, 3754 }, { 10, 3756 }, { 10, 3758 }, - { 10, 3760 }, { 10, 3762 }, { 10, 3764 }, { 10, 3766 }, { 10, 3768 }, - { 10, 3770 }, { 10, 3772 }, { 10, 3774 }, { 10, 3776 }, { 10, 3778 }, - { 10, 3780 }, { 10, 3782 }, { 10, 3784 }, { 10, 3786 }, { 10, 3788 }, - { 10, 3790 }, { 10, 3792 }, { 10, 3794 }, { 10, 3796 }, { 10, 3798 }, - { 10, 3800 }, { 10, 3802 }, { 10, 3804 }, { 10, 3806 }, { 10, 3808 }, - { 10, 3810 }, { 10, 3812 }, { 10, 3814 }, { 10, 3816 }, { 10, 3818 }, - { 10, 3820 }, { 10, 3822 }, { 10, 3824 }, { 10, 3826 }, { 10, 3828 }, - { 10, 3830 }, { 10, 3832 }, { 10, 3834 }, { 10, 3836 }, { 10, 3838 }, - { 10, 3840 }, { 10, 3842 }, { 10, 3844 }, { 10, 3846 }, { 10, 3848 }, - { 10, 3850 }, { 10, 3852 }, { 10, 3854 }, { 10, 3856 }, { 10, 3858 }, - { 10, 3860 }, { 10, 3862 }, { 10, 3864 }, { 10, 3866 }, { 10, 3868 }, - { 10, 3870 }, { 10, 3872 }, { 10, 3874 }, { 10, 3876 }, { 10, 3878 }, - { 10, 3880 }, { 10, 3882 }, { 10, 3884 }, { 10, 3886 }, { 10, 3888 }, - { 10, 3890 }, { 10, 3892 }, { 10, 3894 }, { 10, 3896 }, { 10, 3898 }, - { 10, 3900 }, { 10, 3902 }, { 10, 3904 }, { 10, 3906 }, { 10, 3908 }, - { 10, 3910 }, { 10, 3912 }, { 10, 3914 }, { 10, 3916 }, { 10, 3918 }, - { 10, 3920 }, { 10, 3922 }, { 10, 3924 }, { 10, 3926 }, { 10, 3928 }, - { 10, 3930 }, { 10, 3932 }, { 10, 3934 }, { 10, 3936 }, { 10, 3938 }, - { 10, 3940 }, { 10, 3942 }, { 10, 3944 }, { 10, 3946 }, { 10, 3948 }, - { 10, 3950 }, { 10, 3952 }, { 10, 3954 }, { 10, 3956 }, { 10, 3958 }, - { 10, 3960 } -}; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_DCT_VALUE_TOKENS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/defaultcoefcounts.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/defaultcoefcounts.h deleted file mode 100644 index a3ab34c8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/defaultcoefcounts.h +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_DEFAULTCOEFCOUNTS_H_ -#define VPX_VP8_ENCODER_DEFAULTCOEFCOUNTS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Generated file, included by entropy.c */ - -static const unsigned int default_coef_counts - [BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS] = { - - { - /* Block Type ( 0 ) */ - { - /* Coeff Band ( 0 ) */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - }, - { - /* Coeff Band ( 1 ) */ - { 30190, 26544, 225, 24, 4, 0, 0, 0, 0, 0, 0, 4171593 }, - { 26846, 25157, 1241, 130, 26, 6, 1, 0, 0, 0, 0, 149987 }, - { 10484, 9538, 1006, 160, 36, 18, 0, 0, 0, 0, 0, 15104 }, - }, - { - /* Coeff Band ( 2 ) */ - { 25842, 40456, 1126, 83, 11, 2, 0, 0, 0, 0, 0, 0 }, - { 9338, 8010, 512, 73, 7, 3, 2, 0, 0, 0, 0, 43294 }, - { 1047, 751, 149, 31, 13, 6, 1, 0, 0, 0, 0, 879 }, - }, - { - /* Coeff Band ( 3 ) */ - { 26136, 9826, 252, 13, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 8134, 5574, 191, 14, 2, 0, 0, 0, 0, 0, 0, 35302 }, - { 605, 677, 116, 9, 1, 0, 0, 0, 0, 0, 0, 611 }, - }, - { - /* Coeff Band ( 4 ) */ - { 10263, 15463, 283, 17, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 2773, 2191, 128, 9, 2, 2, 0, 0, 0, 0, 0, 10073 }, - { 134, 125, 32, 4, 0, 2, 0, 0, 0, 0, 0, 50 }, - }, - { - /* Coeff Band ( 5 ) */ - { 10483, 2663, 23, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 2137, 1251, 27, 1, 1, 0, 0, 0, 0, 0, 0, 14362 }, - { 116, 156, 14, 2, 1, 0, 0, 0, 0, 0, 0, 190 }, - }, - { - /* Coeff Band ( 6 ) */ - { 40977, 27614, 412, 28, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 6113, 5213, 261, 22, 3, 0, 0, 0, 0, 0, 0, 26164 }, - { 382, 312, 50, 14, 2, 0, 0, 0, 0, 0, 0, 345 }, - }, - { - /* Coeff Band ( 7 ) */ - { 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 319 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 }, - }, - }, - { - /* Block Type ( 1 ) */ - { - /* Coeff Band ( 0 ) */ - { 3268, 19382, 1043, 250, 93, 82, 49, 26, 17, 8, 25, 82289 }, - { 8758, 32110, 5436, 1832, 827, 668, 420, 153, 24, 0, 3, 52914 }, - { 9337, 23725, 8487, 3954, 2107, 1836, 1069, 399, 59, 0, 0, - 18620 }, - }, - { - /* Coeff Band ( 1 ) */ - { 12419, 8420, 452, 62, 9, 1, 0, 0, 0, 0, 0, 0 }, - { 11715, 8705, 693, 92, 15, 7, 2, 0, 0, 0, 0, 53988 }, - { 7603, 8585, 2306, 778, 270, 145, 39, 5, 0, 0, 0, 9136 }, - }, - { - /* Coeff Band ( 2 ) */ - { 15938, 14335, 1207, 184, 55, 13, 4, 1, 0, 0, 0, 0 }, - { 7415, 6829, 1138, 244, 71, 26, 7, 0, 0, 0, 0, 9980 }, - { 1580, 1824, 655, 241, 89, 46, 10, 2, 0, 0, 0, 429 }, - }, - { - /* Coeff Band ( 3 ) */ - { 19453, 5260, 201, 19, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 9173, 3758, 213, 22, 1, 1, 0, 0, 0, 0, 0, 9820 }, - { 1689, 1277, 276, 51, 17, 4, 0, 0, 0, 0, 0, 679 }, - }, - { - /* Coeff Band ( 4 ) */ - { 12076, 10667, 620, 85, 19, 9, 5, 0, 0, 0, 0, 0 }, - { 4665, 3625, 423, 55, 19, 9, 0, 0, 0, 0, 0, 5127 }, - { 415, 440, 143, 34, 20, 7, 2, 0, 0, 0, 0, 101 }, - }, - { - /* Coeff Band ( 5 ) */ - { 12183, 4846, 115, 11, 1, 0, 0, 0, 0, 0, 0, 0 }, - { 4226, 3149, 177, 21, 2, 0, 0, 0, 0, 0, 0, 7157 }, - { 375, 621, 189, 51, 11, 4, 1, 0, 0, 0, 0, 198 }, - }, - { - /* Coeff Band ( 6 ) */ - { 61658, 37743, 1203, 94, 10, 3, 0, 0, 0, 0, 0, 0 }, - { 15514, 11563, 903, 111, 14, 5, 0, 0, 0, 0, 0, 25195 }, - { 929, 1077, 291, 78, 14, 7, 1, 0, 0, 0, 0, 507 }, - }, - { - /* Coeff Band ( 7 ) */ - { 0, 990, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 412, 13, 0, 0, 0, 0, 0, 0, 0, 0, 1641 }, - { 0, 18, 7, 1, 0, 0, 0, 0, 0, 0, 0, 30 }, - }, - }, - { - /* Block Type ( 2 ) */ - { - /* Coeff Band ( 0 ) */ - { 953, 24519, 628, 120, 28, 12, 4, 0, 0, 0, 0, 2248798 }, - { 1525, 25654, 2647, 617, 239, 143, 42, 5, 0, 0, 0, 66837 }, - { 1180, 11011, 3001, 1237, 532, 448, 239, 54, 5, 0, 0, 7122 }, - }, - { - /* Coeff Band ( 1 ) */ - { 1356, 2220, 67, 10, 4, 1, 0, 0, 0, 0, 0, 0 }, - { 1450, 2544, 102, 18, 4, 3, 0, 0, 0, 0, 0, 57063 }, - { 1182, 2110, 470, 130, 41, 21, 0, 0, 0, 0, 0, 6047 }, - }, - { - /* Coeff Band ( 2 ) */ - { 370, 3378, 200, 30, 5, 4, 1, 0, 0, 0, 0, 0 }, - { 293, 1006, 131, 29, 11, 0, 0, 0, 0, 0, 0, 5404 }, - { 114, 387, 98, 23, 4, 8, 1, 0, 0, 0, 0, 236 }, - }, - { - /* Coeff Band ( 3 ) */ - { 579, 194, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 395, 213, 5, 1, 0, 0, 0, 0, 0, 0, 0, 4157 }, - { 119, 122, 4, 0, 0, 0, 0, 0, 0, 0, 0, 300 }, - }, - { - /* Coeff Band ( 4 ) */ - { 38, 557, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 21, 114, 12, 1, 0, 0, 0, 0, 0, 0, 0, 427 }, - { 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7 }, - }, - { - /* Coeff Band ( 5 ) */ - { 52, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 18, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 652 }, - { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30 }, - }, - { - /* Coeff Band ( 6 ) */ - { 640, 569, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 25, 77, 2, 0, 0, 0, 0, 0, 0, 0, 0, 517 }, - { 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 }, - }, - { - /* Coeff Band ( 7 ) */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - }, - }, - { - /* Block Type ( 3 ) */ - { - /* Coeff Band ( 0 ) */ - { 2506, 20161, 2707, 767, 261, 178, 107, 30, 14, 3, 0, 100694 }, - { 8806, 36478, 8817, 3268, 1280, 850, 401, 114, 42, 0, 0, 58572 }, - { 11003, 27214, 11798, 5716, 2482, 2072, 1048, 175, 32, 0, 0, - 19284 }, - }, - { - /* Coeff Band ( 1 ) */ - { 9738, 11313, 959, 205, 70, 18, 11, 1, 0, 0, 0, 0 }, - { 12628, 15085, 1507, 273, 52, 19, 9, 0, 0, 0, 0, 54280 }, - { 10701, 15846, 5561, 1926, 813, 570, 249, 36, 0, 0, 0, 6460 }, - }, - { - /* Coeff Band ( 2 ) */ - { 6781, 22539, 2784, 634, 182, 123, 20, 4, 0, 0, 0, 0 }, - { 6263, 11544, 2649, 790, 259, 168, 27, 5, 0, 0, 0, 20539 }, - { 3109, 4075, 2031, 896, 457, 386, 158, 29, 0, 0, 0, 1138 }, - }, - { - /* Coeff Band ( 3 ) */ - { 11515, 4079, 465, 73, 5, 14, 2, 0, 0, 0, 0, 0 }, - { 9361, 5834, 650, 96, 24, 8, 4, 0, 0, 0, 0, 22181 }, - { 4343, 3974, 1360, 415, 132, 96, 14, 1, 0, 0, 0, 1267 }, - }, - { - /* Coeff Band ( 4 ) */ - { 4787, 9297, 823, 168, 44, 12, 4, 0, 0, 0, 0, 0 }, - { 3619, 4472, 719, 198, 60, 31, 3, 0, 0, 0, 0, 8401 }, - { 1157, 1175, 483, 182, 88, 31, 8, 0, 0, 0, 0, 268 }, - }, - { - /* Coeff Band ( 5 ) */ - { 8299, 1226, 32, 5, 1, 0, 0, 0, 0, 0, 0, 0 }, - { 3502, 1568, 57, 4, 1, 1, 0, 0, 0, 0, 0, 9811 }, - { 1055, 1070, 166, 29, 6, 1, 0, 0, 0, 0, 0, 527 }, - }, - { - /* Coeff Band ( 6 ) */ - { 27414, 27927, 1989, 347, 69, 26, 0, 0, 0, 0, 0, 0 }, - { 5876, 10074, 1574, 341, 91, 24, 4, 0, 0, 0, 0, 21954 }, - { 1571, 2171, 778, 324, 124, 65, 16, 0, 0, 0, 0, 979 }, - }, - { - /* Coeff Band ( 7 ) */ - { 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 459 }, - { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13 }, - }, - }, - }; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_DEFAULTCOEFCOUNTS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/denoising.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/denoising.c deleted file mode 100644 index a666bca4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/denoising.c +++ /dev/null @@ -1,725 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "denoising.h" - -#include "vp8/common/reconinter.h" -#include "vpx/vpx_integer.h" -#include "vpx_mem/vpx_mem.h" -#include "vp8_rtcd.h" - -static const unsigned int NOISE_MOTION_THRESHOLD = 25 * 25; -/* SSE_DIFF_THRESHOLD is selected as ~95% confidence assuming - * var(noise) ~= 100. - */ -static const unsigned int SSE_DIFF_THRESHOLD = 16 * 16 * 20; -static const unsigned int SSE_THRESHOLD = 16 * 16 * 40; -static const unsigned int SSE_THRESHOLD_HIGH = 16 * 16 * 80; - -/* - * The filter function was modified to reduce the computational complexity. - * Step 1: - * Instead of applying tap coefficients for each pixel, we calculated the - * pixel adjustments vs. pixel diff value ahead of time. - * adjustment = filtered_value - current_raw - * = (filter_coefficient * diff + 128) >> 8 - * where - * filter_coefficient = (255 << 8) / (256 + ((absdiff * 330) >> 3)); - * filter_coefficient += filter_coefficient / - * (3 + motion_magnitude_adjustment); - * filter_coefficient is clamped to 0 ~ 255. - * - * Step 2: - * The adjustment vs. diff curve becomes flat very quick when diff increases. - * This allowed us to use only several levels to approximate the curve without - * changing the filtering algorithm too much. - * The adjustments were further corrected by checking the motion magnitude. - * The levels used are: - * diff adjustment w/o motion correction adjustment w/ motion correction - * [-255, -16] -6 -7 - * [-15, -8] -4 -5 - * [-7, -4] -3 -4 - * [-3, 3] diff diff - * [4, 7] 3 4 - * [8, 15] 4 5 - * [16, 255] 6 7 - */ - -int vp8_denoiser_filter_c(unsigned char *mc_running_avg_y, int mc_avg_y_stride, - unsigned char *running_avg_y, int avg_y_stride, - unsigned char *sig, int sig_stride, - unsigned int motion_magnitude, - int increase_denoising) { - unsigned char *running_avg_y_start = running_avg_y; - unsigned char *sig_start = sig; - int sum_diff_thresh; - int r, c; - int sum_diff = 0; - int adj_val[3] = { 3, 4, 6 }; - int shift_inc1 = 0; - int shift_inc2 = 1; - int col_sum[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - /* If motion_magnitude is small, making the denoiser more aggressive by - * increasing the adjustment for each level. Add another increment for - * blocks that are labeled for increase denoising. */ - if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) { - if (increase_denoising) { - shift_inc1 = 1; - shift_inc2 = 2; - } - adj_val[0] += shift_inc2; - adj_val[1] += shift_inc2; - adj_val[2] += shift_inc2; - } - - for (r = 0; r < 16; ++r) { - for (c = 0; c < 16; ++c) { - int diff = 0; - int adjustment = 0; - int absdiff = 0; - - diff = mc_running_avg_y[c] - sig[c]; - absdiff = abs(diff); - - // When |diff| <= |3 + shift_inc1|, use pixel value from - // last denoised raw. - if (absdiff <= 3 + shift_inc1) { - running_avg_y[c] = mc_running_avg_y[c]; - col_sum[c] += diff; - } else { - if (absdiff >= 4 + shift_inc1 && absdiff <= 7) { - adjustment = adj_val[0]; - } else if (absdiff >= 8 && absdiff <= 15) { - adjustment = adj_val[1]; - } else { - adjustment = adj_val[2]; - } - - if (diff > 0) { - if ((sig[c] + adjustment) > 255) { - running_avg_y[c] = 255; - } else { - running_avg_y[c] = sig[c] + adjustment; - } - - col_sum[c] += adjustment; - } else { - if ((sig[c] - adjustment) < 0) { - running_avg_y[c] = 0; - } else { - running_avg_y[c] = sig[c] - adjustment; - } - - col_sum[c] -= adjustment; - } - } - } - - /* Update pointers for next iteration. */ - sig += sig_stride; - mc_running_avg_y += mc_avg_y_stride; - running_avg_y += avg_y_stride; - } - - for (c = 0; c < 16; ++c) { - // Below we clip the value in the same way which SSE code use. - // When adopting aggressive denoiser, the adj_val for each pixel - // could be at most 8 (this is current max adjustment of the map). - // In SSE code, we calculate the sum of adj_val for - // the columns, so the sum could be up to 128(16 rows). However, - // the range of the value is -128 ~ 127 in SSE code, that's why - // we do this change in C code. - // We don't do this for UV denoiser, since there are only 8 rows, - // and max adjustments <= 8, so the sum of the columns will not - // exceed 64. - if (col_sum[c] >= 128) { - col_sum[c] = 127; - } - sum_diff += col_sum[c]; - } - - sum_diff_thresh = SUM_DIFF_THRESHOLD; - if (increase_denoising) sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH; - if (abs(sum_diff) > sum_diff_thresh) { - // Before returning to copy the block (i.e., apply no denoising), check - // if we can still apply some (weaker) temporal filtering to this block, - // that would otherwise not be denoised at all. Simplest is to apply - // an additional adjustment to running_avg_y to bring it closer to sig. - // The adjustment is capped by a maximum delta, and chosen such that - // in most cases the resulting sum_diff will be within the - // accceptable range given by sum_diff_thresh. - - // The delta is set by the excess of absolute pixel diff over threshold. - int delta = ((abs(sum_diff) - sum_diff_thresh) >> 8) + 1; - // Only apply the adjustment for max delta up to 3. - if (delta < 4) { - sig -= sig_stride * 16; - mc_running_avg_y -= mc_avg_y_stride * 16; - running_avg_y -= avg_y_stride * 16; - for (r = 0; r < 16; ++r) { - for (c = 0; c < 16; ++c) { - int diff = mc_running_avg_y[c] - sig[c]; - int adjustment = abs(diff); - if (adjustment > delta) adjustment = delta; - if (diff > 0) { - // Bring denoised signal down. - if (running_avg_y[c] - adjustment < 0) { - running_avg_y[c] = 0; - } else { - running_avg_y[c] = running_avg_y[c] - adjustment; - } - col_sum[c] -= adjustment; - } else if (diff < 0) { - // Bring denoised signal up. - if (running_avg_y[c] + adjustment > 255) { - running_avg_y[c] = 255; - } else { - running_avg_y[c] = running_avg_y[c] + adjustment; - } - col_sum[c] += adjustment; - } - } - // TODO(marpan): Check here if abs(sum_diff) has gone below the - // threshold sum_diff_thresh, and if so, we can exit the row loop. - sig += sig_stride; - mc_running_avg_y += mc_avg_y_stride; - running_avg_y += avg_y_stride; - } - - sum_diff = 0; - for (c = 0; c < 16; ++c) { - if (col_sum[c] >= 128) { - col_sum[c] = 127; - } - sum_diff += col_sum[c]; - } - - if (abs(sum_diff) > sum_diff_thresh) return COPY_BLOCK; - } else { - return COPY_BLOCK; - } - } - - vp8_copy_mem16x16(running_avg_y_start, avg_y_stride, sig_start, sig_stride); - return FILTER_BLOCK; -} - -int vp8_denoiser_filter_uv_c(unsigned char *mc_running_avg, int mc_avg_stride, - unsigned char *running_avg, int avg_stride, - unsigned char *sig, int sig_stride, - unsigned int motion_magnitude, - int increase_denoising) { - unsigned char *running_avg_start = running_avg; - unsigned char *sig_start = sig; - int sum_diff_thresh; - int r, c; - int sum_diff = 0; - int sum_block = 0; - int adj_val[3] = { 3, 4, 6 }; - int shift_inc1 = 0; - int shift_inc2 = 1; - /* If motion_magnitude is small, making the denoiser more aggressive by - * increasing the adjustment for each level. Add another increment for - * blocks that are labeled for increase denoising. */ - if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD_UV) { - if (increase_denoising) { - shift_inc1 = 1; - shift_inc2 = 2; - } - adj_val[0] += shift_inc2; - adj_val[1] += shift_inc2; - adj_val[2] += shift_inc2; - } - - // Avoid denoising color signal if its close to average level. - for (r = 0; r < 8; ++r) { - for (c = 0; c < 8; ++c) { - sum_block += sig[c]; - } - sig += sig_stride; - } - if (abs(sum_block - (128 * 8 * 8)) < SUM_DIFF_FROM_AVG_THRESH_UV) { - return COPY_BLOCK; - } - - sig -= sig_stride * 8; - for (r = 0; r < 8; ++r) { - for (c = 0; c < 8; ++c) { - int diff = 0; - int adjustment = 0; - int absdiff = 0; - - diff = mc_running_avg[c] - sig[c]; - absdiff = abs(diff); - - // When |diff| <= |3 + shift_inc1|, use pixel value from - // last denoised raw. - if (absdiff <= 3 + shift_inc1) { - running_avg[c] = mc_running_avg[c]; - sum_diff += diff; - } else { - if (absdiff >= 4 && absdiff <= 7) { - adjustment = adj_val[0]; - } else if (absdiff >= 8 && absdiff <= 15) { - adjustment = adj_val[1]; - } else { - adjustment = adj_val[2]; - } - if (diff > 0) { - if ((sig[c] + adjustment) > 255) { - running_avg[c] = 255; - } else { - running_avg[c] = sig[c] + adjustment; - } - sum_diff += adjustment; - } else { - if ((sig[c] - adjustment) < 0) { - running_avg[c] = 0; - } else { - running_avg[c] = sig[c] - adjustment; - } - sum_diff -= adjustment; - } - } - } - /* Update pointers for next iteration. */ - sig += sig_stride; - mc_running_avg += mc_avg_stride; - running_avg += avg_stride; - } - - sum_diff_thresh = SUM_DIFF_THRESHOLD_UV; - if (increase_denoising) sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH_UV; - if (abs(sum_diff) > sum_diff_thresh) { - // Before returning to copy the block (i.e., apply no denoising), check - // if we can still apply some (weaker) temporal filtering to this block, - // that would otherwise not be denoised at all. Simplest is to apply - // an additional adjustment to running_avg_y to bring it closer to sig. - // The adjustment is capped by a maximum delta, and chosen such that - // in most cases the resulting sum_diff will be within the - // accceptable range given by sum_diff_thresh. - - // The delta is set by the excess of absolute pixel diff over threshold. - int delta = ((abs(sum_diff) - sum_diff_thresh) >> 8) + 1; - // Only apply the adjustment for max delta up to 3. - if (delta < 4) { - sig -= sig_stride * 8; - mc_running_avg -= mc_avg_stride * 8; - running_avg -= avg_stride * 8; - for (r = 0; r < 8; ++r) { - for (c = 0; c < 8; ++c) { - int diff = mc_running_avg[c] - sig[c]; - int adjustment = abs(diff); - if (adjustment > delta) adjustment = delta; - if (diff > 0) { - // Bring denoised signal down. - if (running_avg[c] - adjustment < 0) { - running_avg[c] = 0; - } else { - running_avg[c] = running_avg[c] - adjustment; - } - sum_diff -= adjustment; - } else if (diff < 0) { - // Bring denoised signal up. - if (running_avg[c] + adjustment > 255) { - running_avg[c] = 255; - } else { - running_avg[c] = running_avg[c] + adjustment; - } - sum_diff += adjustment; - } - } - // TODO(marpan): Check here if abs(sum_diff) has gone below the - // threshold sum_diff_thresh, and if so, we can exit the row loop. - sig += sig_stride; - mc_running_avg += mc_avg_stride; - running_avg += avg_stride; - } - if (abs(sum_diff) > sum_diff_thresh) return COPY_BLOCK; - } else { - return COPY_BLOCK; - } - } - - vp8_copy_mem8x8(running_avg_start, avg_stride, sig_start, sig_stride); - return FILTER_BLOCK; -} - -void vp8_denoiser_set_parameters(VP8_DENOISER *denoiser, int mode) { - assert(mode > 0); // Denoiser is allocated only if mode > 0. - if (mode == 1) { - denoiser->denoiser_mode = kDenoiserOnYOnly; - } else if (mode == 2) { - denoiser->denoiser_mode = kDenoiserOnYUV; - } else if (mode == 3) { - denoiser->denoiser_mode = kDenoiserOnYUVAggressive; - } else { - denoiser->denoiser_mode = kDenoiserOnYUV; - } - if (denoiser->denoiser_mode != kDenoiserOnYUVAggressive) { - denoiser->denoise_pars.scale_sse_thresh = 1; - denoiser->denoise_pars.scale_motion_thresh = 8; - denoiser->denoise_pars.scale_increase_filter = 0; - denoiser->denoise_pars.denoise_mv_bias = 95; - denoiser->denoise_pars.pickmode_mv_bias = 100; - denoiser->denoise_pars.qp_thresh = 0; - denoiser->denoise_pars.consec_zerolast = UINT_MAX; - denoiser->denoise_pars.spatial_blur = 0; - } else { - denoiser->denoise_pars.scale_sse_thresh = 2; - denoiser->denoise_pars.scale_motion_thresh = 16; - denoiser->denoise_pars.scale_increase_filter = 1; - denoiser->denoise_pars.denoise_mv_bias = 60; - denoiser->denoise_pars.pickmode_mv_bias = 75; - denoiser->denoise_pars.qp_thresh = 80; - denoiser->denoise_pars.consec_zerolast = 15; - denoiser->denoise_pars.spatial_blur = 0; - } -} - -int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height, - int num_mb_rows, int num_mb_cols, int mode) { - int i; - assert(denoiser); - denoiser->num_mb_cols = num_mb_cols; - - for (i = 0; i < MAX_REF_FRAMES; ++i) { - denoiser->yv12_running_avg[i].flags = 0; - - if (vp8_yv12_alloc_frame_buffer(&(denoiser->yv12_running_avg[i]), width, - height, VP8BORDERINPIXELS) < 0) { - vp8_denoiser_free(denoiser); - return 1; - } - memset(denoiser->yv12_running_avg[i].buffer_alloc, 0, - denoiser->yv12_running_avg[i].frame_size); - } - denoiser->yv12_mc_running_avg.flags = 0; - - if (vp8_yv12_alloc_frame_buffer(&(denoiser->yv12_mc_running_avg), width, - height, VP8BORDERINPIXELS) < 0) { - vp8_denoiser_free(denoiser); - return 1; - } - - memset(denoiser->yv12_mc_running_avg.buffer_alloc, 0, - denoiser->yv12_mc_running_avg.frame_size); - - if (vp8_yv12_alloc_frame_buffer(&denoiser->yv12_last_source, width, height, - VP8BORDERINPIXELS) < 0) { - vp8_denoiser_free(denoiser); - return 1; - } - memset(denoiser->yv12_last_source.buffer_alloc, 0, - denoiser->yv12_last_source.frame_size); - - denoiser->denoise_state = vpx_calloc((num_mb_rows * num_mb_cols), 1); - if (!denoiser->denoise_state) { - vp8_denoiser_free(denoiser); - return 1; - } - memset(denoiser->denoise_state, 0, (num_mb_rows * num_mb_cols)); - vp8_denoiser_set_parameters(denoiser, mode); - denoiser->nmse_source_diff = 0; - denoiser->nmse_source_diff_count = 0; - denoiser->qp_avg = 0; - // QP threshold below which we can go up to aggressive mode. - denoiser->qp_threshold_up = 80; - // QP threshold above which we can go back down to normal mode. - // For now keep this second threshold high, so not used currently. - denoiser->qp_threshold_down = 128; - // Bitrate thresholds and noise metric (nmse) thresholds for switching to - // aggressive mode. - // TODO(marpan): Adjust thresholds, including effect on resolution. - denoiser->bitrate_threshold = 400000; // (bits/sec). - denoiser->threshold_aggressive_mode = 80; - if (width * height > 1280 * 720) { - denoiser->bitrate_threshold = 3000000; - denoiser->threshold_aggressive_mode = 200; - } else if (width * height > 960 * 540) { - denoiser->bitrate_threshold = 1200000; - denoiser->threshold_aggressive_mode = 120; - } else if (width * height > 640 * 480) { - denoiser->bitrate_threshold = 600000; - denoiser->threshold_aggressive_mode = 100; - } - return 0; -} - -void vp8_denoiser_free(VP8_DENOISER *denoiser) { - int i; - assert(denoiser); - - for (i = 0; i < MAX_REF_FRAMES; ++i) { - vp8_yv12_de_alloc_frame_buffer(&denoiser->yv12_running_avg[i]); - } - vp8_yv12_de_alloc_frame_buffer(&denoiser->yv12_mc_running_avg); - vp8_yv12_de_alloc_frame_buffer(&denoiser->yv12_last_source); - vpx_free(denoiser->denoise_state); -} - -void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser, MACROBLOCK *x, - unsigned int best_sse, unsigned int zero_mv_sse, - int recon_yoffset, int recon_uvoffset, - loop_filter_info_n *lfi_n, int mb_row, int mb_col, - int block_index, int consec_zero_last) - -{ - int mv_row; - int mv_col; - unsigned int motion_threshold; - unsigned int motion_magnitude2; - unsigned int sse_thresh; - int sse_diff_thresh = 0; - // Spatial loop filter: only applied selectively based on - // temporal filter state of block relative to top/left neighbors. - int apply_spatial_loop_filter = 1; - MV_REFERENCE_FRAME frame = x->best_reference_frame; - MV_REFERENCE_FRAME zero_frame = x->best_zeromv_reference_frame; - - enum vp8_denoiser_decision decision = FILTER_BLOCK; - enum vp8_denoiser_decision decision_u = COPY_BLOCK; - enum vp8_denoiser_decision decision_v = COPY_BLOCK; - - if (zero_frame) { - YV12_BUFFER_CONFIG *src = &denoiser->yv12_running_avg[frame]; - YV12_BUFFER_CONFIG *dst = &denoiser->yv12_mc_running_avg; - YV12_BUFFER_CONFIG saved_pre, saved_dst; - MB_MODE_INFO saved_mbmi; - MACROBLOCKD *filter_xd = &x->e_mbd; - MB_MODE_INFO *mbmi = &filter_xd->mode_info_context->mbmi; - int sse_diff = 0; - // Bias on zero motion vector sse. - const int zero_bias = denoiser->denoise_pars.denoise_mv_bias; - zero_mv_sse = (unsigned int)((int64_t)zero_mv_sse * zero_bias / 100); - sse_diff = (int)zero_mv_sse - (int)best_sse; - - saved_mbmi = *mbmi; - - /* Use the best MV for the compensation. */ - mbmi->ref_frame = x->best_reference_frame; - mbmi->mode = x->best_sse_inter_mode; - mbmi->mv = x->best_sse_mv; - mbmi->need_to_clamp_mvs = x->need_to_clamp_best_mvs; - mv_col = x->best_sse_mv.as_mv.col; - mv_row = x->best_sse_mv.as_mv.row; - // Bias to zero_mv if small amount of motion. - // Note sse_diff_thresh is intialized to zero, so this ensures - // we will always choose zero_mv for denoising if - // zero_mv_see <= best_sse (i.e., sse_diff <= 0). - if ((unsigned int)(mv_row * mv_row + mv_col * mv_col) <= - NOISE_MOTION_THRESHOLD) { - sse_diff_thresh = (int)SSE_DIFF_THRESHOLD; - } - - if (frame == INTRA_FRAME || sse_diff <= sse_diff_thresh) { - /* - * Handle intra blocks as referring to last frame with zero motion - * and let the absolute pixel difference affect the filter factor. - * Also consider small amount of motion as being random walk due - * to noise, if it doesn't mean that we get a much bigger error. - * Note that any changes to the mode info only affects the - * denoising. - */ - x->denoise_zeromv = 1; - mbmi->ref_frame = x->best_zeromv_reference_frame; - - src = &denoiser->yv12_running_avg[zero_frame]; - - mbmi->mode = ZEROMV; - mbmi->mv.as_int = 0; - x->best_sse_inter_mode = ZEROMV; - x->best_sse_mv.as_int = 0; - best_sse = zero_mv_sse; - } - - mv_row = x->best_sse_mv.as_mv.row; - mv_col = x->best_sse_mv.as_mv.col; - motion_magnitude2 = mv_row * mv_row + mv_col * mv_col; - motion_threshold = - denoiser->denoise_pars.scale_motion_thresh * NOISE_MOTION_THRESHOLD; - - if (motion_magnitude2 < - denoiser->denoise_pars.scale_increase_filter * NOISE_MOTION_THRESHOLD) { - x->increase_denoising = 1; - } - - sse_thresh = denoiser->denoise_pars.scale_sse_thresh * SSE_THRESHOLD; - if (x->increase_denoising) { - sse_thresh = denoiser->denoise_pars.scale_sse_thresh * SSE_THRESHOLD_HIGH; - } - - if (best_sse > sse_thresh || motion_magnitude2 > motion_threshold) { - decision = COPY_BLOCK; - } - - // If block is considered skin, don't denoise if the block - // (1) is selected as non-zero motion for current frame, or - // (2) has not been selected as ZERO_LAST mode at least x past frames - // in a row. - // TODO(marpan): Parameter "x" should be varied with framerate. - // In particualar, should be reduced for layers (base layer/LAST). - if (x->is_skin && (consec_zero_last < 2 || motion_magnitude2 > 0)) { - decision = COPY_BLOCK; - } - - if (decision == FILTER_BLOCK) { - saved_pre = filter_xd->pre; - saved_dst = filter_xd->dst; - - /* Compensate the running average. */ - filter_xd->pre.y_buffer = src->y_buffer + recon_yoffset; - filter_xd->pre.u_buffer = src->u_buffer + recon_uvoffset; - filter_xd->pre.v_buffer = src->v_buffer + recon_uvoffset; - /* Write the compensated running average to the destination buffer. */ - filter_xd->dst.y_buffer = dst->y_buffer + recon_yoffset; - filter_xd->dst.u_buffer = dst->u_buffer + recon_uvoffset; - filter_xd->dst.v_buffer = dst->v_buffer + recon_uvoffset; - - if (!x->skip) { - vp8_build_inter_predictors_mb(filter_xd); - } else { - vp8_build_inter16x16_predictors_mb( - filter_xd, filter_xd->dst.y_buffer, filter_xd->dst.u_buffer, - filter_xd->dst.v_buffer, filter_xd->dst.y_stride, - filter_xd->dst.uv_stride); - } - filter_xd->pre = saved_pre; - filter_xd->dst = saved_dst; - *mbmi = saved_mbmi; - } - } else { - // zero_frame should always be 1 for real-time mode, as the - // ZEROMV mode is always checked, so we should never go into this branch. - // If case ZEROMV is not checked, then we will force no denoise (COPY). - decision = COPY_BLOCK; - } - - if (decision == FILTER_BLOCK) { - unsigned char *mc_running_avg_y = - denoiser->yv12_mc_running_avg.y_buffer + recon_yoffset; - int mc_avg_y_stride = denoiser->yv12_mc_running_avg.y_stride; - unsigned char *running_avg_y = - denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset; - int avg_y_stride = denoiser->yv12_running_avg[INTRA_FRAME].y_stride; - - /* Filter. */ - decision = vp8_denoiser_filter(mc_running_avg_y, mc_avg_y_stride, - running_avg_y, avg_y_stride, x->thismb, 16, - motion_magnitude2, x->increase_denoising); - denoiser->denoise_state[block_index] = - motion_magnitude2 > 0 ? kFilterNonZeroMV : kFilterZeroMV; - // Only denoise UV for zero motion, and if y channel was denoised. - if (denoiser->denoiser_mode != kDenoiserOnYOnly && motion_magnitude2 == 0 && - decision == FILTER_BLOCK) { - unsigned char *mc_running_avg_u = - denoiser->yv12_mc_running_avg.u_buffer + recon_uvoffset; - unsigned char *running_avg_u = - denoiser->yv12_running_avg[INTRA_FRAME].u_buffer + recon_uvoffset; - unsigned char *mc_running_avg_v = - denoiser->yv12_mc_running_avg.v_buffer + recon_uvoffset; - unsigned char *running_avg_v = - denoiser->yv12_running_avg[INTRA_FRAME].v_buffer + recon_uvoffset; - int mc_avg_uv_stride = denoiser->yv12_mc_running_avg.uv_stride; - int avg_uv_stride = denoiser->yv12_running_avg[INTRA_FRAME].uv_stride; - int signal_stride = x->block[16].src_stride; - decision_u = vp8_denoiser_filter_uv( - mc_running_avg_u, mc_avg_uv_stride, running_avg_u, avg_uv_stride, - x->block[16].src + *x->block[16].base_src, signal_stride, - motion_magnitude2, 0); - decision_v = vp8_denoiser_filter_uv( - mc_running_avg_v, mc_avg_uv_stride, running_avg_v, avg_uv_stride, - x->block[20].src + *x->block[20].base_src, signal_stride, - motion_magnitude2, 0); - } - } - if (decision == COPY_BLOCK) { - /* No filtering of this block; it differs too much from the predictor, - * or the motion vector magnitude is considered too big. - */ - x->denoise_zeromv = 0; - vp8_copy_mem16x16( - x->thismb, 16, - denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset, - denoiser->yv12_running_avg[INTRA_FRAME].y_stride); - denoiser->denoise_state[block_index] = kNoFilter; - } - if (denoiser->denoiser_mode != kDenoiserOnYOnly) { - if (decision_u == COPY_BLOCK) { - vp8_copy_mem8x8( - x->block[16].src + *x->block[16].base_src, x->block[16].src_stride, - denoiser->yv12_running_avg[INTRA_FRAME].u_buffer + recon_uvoffset, - denoiser->yv12_running_avg[INTRA_FRAME].uv_stride); - } - if (decision_v == COPY_BLOCK) { - vp8_copy_mem8x8( - x->block[20].src + *x->block[20].base_src, x->block[16].src_stride, - denoiser->yv12_running_avg[INTRA_FRAME].v_buffer + recon_uvoffset, - denoiser->yv12_running_avg[INTRA_FRAME].uv_stride); - } - } - // Option to selectively deblock the denoised signal, for y channel only. - if (apply_spatial_loop_filter) { - loop_filter_info lfi; - int apply_filter_col = 0; - int apply_filter_row = 0; - int apply_filter = 0; - int y_stride = denoiser->yv12_running_avg[INTRA_FRAME].y_stride; - int uv_stride = denoiser->yv12_running_avg[INTRA_FRAME].uv_stride; - - // Fix filter level to some nominal value for now. - int filter_level = 48; - - int hev_index = lfi_n->hev_thr_lut[INTER_FRAME][filter_level]; - lfi.mblim = lfi_n->mblim[filter_level]; - lfi.blim = lfi_n->blim[filter_level]; - lfi.lim = lfi_n->lim[filter_level]; - lfi.hev_thr = lfi_n->hev_thr[hev_index]; - - // Apply filter if there is a difference in the denoiser filter state - // between the current and left/top block, or if non-zero motion vector - // is used for the motion-compensated filtering. - if (mb_col > 0) { - apply_filter_col = - !((denoiser->denoise_state[block_index] == - denoiser->denoise_state[block_index - 1]) && - denoiser->denoise_state[block_index] != kFilterNonZeroMV); - if (apply_filter_col) { - // Filter left vertical edge. - apply_filter = 1; - vp8_loop_filter_mbv( - denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset, - NULL, NULL, y_stride, uv_stride, &lfi); - } - } - if (mb_row > 0) { - apply_filter_row = - !((denoiser->denoise_state[block_index] == - denoiser->denoise_state[block_index - denoiser->num_mb_cols]) && - denoiser->denoise_state[block_index] != kFilterNonZeroMV); - if (apply_filter_row) { - // Filter top horizontal edge. - apply_filter = 1; - vp8_loop_filter_mbh( - denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset, - NULL, NULL, y_stride, uv_stride, &lfi); - } - } - if (apply_filter) { - // Update the signal block |x|. Pixel changes are only to top and/or - // left boundary pixels: can we avoid full block copy here. - vp8_copy_mem16x16( - denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset, - y_stride, x->thismb, 16); - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/denoising.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/denoising.h deleted file mode 100644 index 51ae3b0a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/denoising.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_DENOISING_H_ -#define VPX_VP8_ENCODER_DENOISING_H_ - -#include "block.h" -#include "vp8/common/loopfilter.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define SUM_DIFF_THRESHOLD 512 -#define SUM_DIFF_THRESHOLD_HIGH 600 -#define MOTION_MAGNITUDE_THRESHOLD (8 * 3) - -#define SUM_DIFF_THRESHOLD_UV (96) // (8 * 8 * 1.5) -#define SUM_DIFF_THRESHOLD_HIGH_UV (8 * 8 * 2) -#define SUM_DIFF_FROM_AVG_THRESH_UV (8 * 8 * 8) -#define MOTION_MAGNITUDE_THRESHOLD_UV (8 * 3) - -#define MAX_GF_ARF_DENOISE_RANGE (8) - -enum vp8_denoiser_decision { COPY_BLOCK, FILTER_BLOCK }; - -enum vp8_denoiser_filter_state { kNoFilter, kFilterZeroMV, kFilterNonZeroMV }; - -enum vp8_denoiser_mode { - kDenoiserOff, - kDenoiserOnYOnly, - kDenoiserOnYUV, - kDenoiserOnYUVAggressive, - kDenoiserOnAdaptive -}; - -typedef struct { - // Scale factor on sse threshold above which no denoising is done. - unsigned int scale_sse_thresh; - // Scale factor on motion magnitude threshold above which no - // denoising is done. - unsigned int scale_motion_thresh; - // Scale factor on motion magnitude below which we increase the strength of - // the temporal filter (in function vp8_denoiser_filter). - unsigned int scale_increase_filter; - // Scale factor to bias to ZEROMV for denoising. - unsigned int denoise_mv_bias; - // Scale factor to bias to ZEROMV for coding mode selection. - unsigned int pickmode_mv_bias; - // Quantizer threshold below which we use the segmentation map to switch off - // loop filter for blocks that have been coded as ZEROMV-LAST a certain number - // (consec_zerolast) of consecutive frames. Note that the delta-QP is set to - // 0 when segmentation map is used for shutting off loop filter. - unsigned int qp_thresh; - // Threshold for number of consecutive frames for blocks coded as ZEROMV-LAST. - unsigned int consec_zerolast; - // Threshold for amount of spatial blur on Y channel. 0 means no spatial blur. - unsigned int spatial_blur; -} denoise_params; - -typedef struct vp8_denoiser { - YV12_BUFFER_CONFIG yv12_running_avg[MAX_REF_FRAMES]; - YV12_BUFFER_CONFIG yv12_mc_running_avg; - // TODO(marpan): Should remove yv12_last_source and use vp8_lookahead_peak. - YV12_BUFFER_CONFIG yv12_last_source; - unsigned char *denoise_state; - int num_mb_cols; - int denoiser_mode; - int threshold_aggressive_mode; - int nmse_source_diff; - int nmse_source_diff_count; - int qp_avg; - int qp_threshold_up; - int qp_threshold_down; - int bitrate_threshold; - denoise_params denoise_pars; -} VP8_DENOISER; - -int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height, - int num_mb_rows, int num_mb_cols, int mode); - -void vp8_denoiser_free(VP8_DENOISER *denoiser); - -void vp8_denoiser_set_parameters(VP8_DENOISER *denoiser, int mode); - -void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser, MACROBLOCK *x, - unsigned int best_sse, unsigned int zero_mv_sse, - int recon_yoffset, int recon_uvoffset, - loop_filter_info_n *lfi_n, int mb_row, int mb_col, - int block_index, int consec_zero_last); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_DENOISING_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodeframe.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodeframe.c deleted file mode 100644 index fa433404..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodeframe.c +++ /dev/null @@ -1,1303 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include - -#include "vpx_config.h" - -#include "vp8/common/common.h" -#include "vp8/common/entropymode.h" -#include "vp8/common/extend.h" -#include "vp8/common/invtrans.h" -#include "vp8/common/quant_common.h" -#include "vp8/common/reconinter.h" -#include "vp8/common/setupintrarecon.h" -#include "vp8/common/threading.h" -#include "vp8/encoder/bitstream.h" -#include "vp8/encoder/encodeframe.h" -#include "vp8/encoder/encodeintra.h" -#include "vp8/encoder/encodemb.h" -#include "vp8/encoder/onyx_int.h" -#include "vp8/encoder/pickinter.h" -#include "vp8/encoder/rdopt.h" -#include "vp8_rtcd.h" -#include "vpx/internal/vpx_codec_internal.h" -#include "vpx_dsp_rtcd.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/vpx_timer.h" - -#if CONFIG_MULTITHREAD -#include "vp8/encoder/ethreading.h" -#endif - -extern void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t); -static void adjust_act_zbin(VP8_COMP *cpi, MACROBLOCK *x); - -#ifdef MODE_STATS -unsigned int inter_y_modes[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -unsigned int inter_uv_modes[4] = { 0, 0, 0, 0 }; -unsigned int inter_b_modes[15] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; -unsigned int y_modes[5] = { 0, 0, 0, 0, 0 }; -unsigned int uv_modes[4] = { 0, 0, 0, 0 }; -unsigned int b_modes[14] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -#endif - -/* activity_avg must be positive, or flat regions could get a zero weight - * (infinite lambda), which confounds analysis. - * This also avoids the need for divide by zero checks in - * vp8_activity_masking(). - */ -#define VP8_ACTIVITY_AVG_MIN (64) - -/* This is used as a reference when computing the source variance for the - * purposes of activity masking. - * Eventually this should be replaced by custom no-reference routines, - * which will be faster. - */ -static const unsigned char VP8_VAR_OFFS[16] = { 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128 }; - -/* Original activity measure from Tim T's code. */ -static unsigned int tt_activity_measure(MACROBLOCK *x) { - unsigned int act; - unsigned int sse; - /* TODO: This could also be done over smaller areas (8x8), but that would - * require extensive changes elsewhere, as lambda is assumed to be fixed - * over an entire MB in most of the code. - * Another option is to compute four 8x8 variances, and pick a single - * lambda using a non-linear combination (e.g., the smallest, or second - * smallest, etc.). - */ - act = vpx_variance16x16(x->src.y_buffer, x->src.y_stride, VP8_VAR_OFFS, 0, - &sse); - act = act << 4; - - /* If the region is flat, lower the activity some more. */ - if (act < 8 << 12) act = act < 5 << 12 ? act : 5 << 12; - - return act; -} - -/* Measure the activity of the current macroblock - * What we measure here is TBD so abstracted to this function - */ -#define ALT_ACT_MEASURE 1 -static unsigned int mb_activity_measure(MACROBLOCK *x, int mb_row, int mb_col) { - unsigned int mb_activity; - - if (ALT_ACT_MEASURE) { - int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row); - - /* Or use an alternative. */ - mb_activity = vp8_encode_intra(x, use_dc_pred); - } else { - /* Original activity measure from Tim T's code. */ - mb_activity = tt_activity_measure(x); - } - - if (mb_activity < VP8_ACTIVITY_AVG_MIN) mb_activity = VP8_ACTIVITY_AVG_MIN; - - return mb_activity; -} - -/* Calculate an "average" mb activity value for the frame */ -#define ACT_MEDIAN 0 -static void calc_av_activity(VP8_COMP *cpi, int64_t activity_sum) { -#if ACT_MEDIAN - /* Find median: Simple n^2 algorithm for experimentation */ - { - unsigned int median; - unsigned int i, j; - unsigned int *sortlist; - unsigned int tmp; - - /* Create a list to sort to */ - CHECK_MEM_ERROR(&cpi->common.error, sortlist, - vpx_calloc(sizeof(unsigned int), cpi->common.MBs)); - - /* Copy map to sort list */ - memcpy(sortlist, cpi->mb_activity_map, - sizeof(unsigned int) * cpi->common.MBs); - - /* Ripple each value down to its correct position */ - for (i = 1; i < cpi->common.MBs; ++i) { - for (j = i; j > 0; j--) { - if (sortlist[j] < sortlist[j - 1]) { - /* Swap values */ - tmp = sortlist[j - 1]; - sortlist[j - 1] = sortlist[j]; - sortlist[j] = tmp; - } else - break; - } - } - - /* Even number MBs so estimate median as mean of two either side. */ - median = (1 + sortlist[cpi->common.MBs >> 1] + - sortlist[(cpi->common.MBs >> 1) + 1]) >> - 1; - - cpi->activity_avg = median; - - vpx_free(sortlist); - } -#else - /* Simple mean for now */ - cpi->activity_avg = (unsigned int)(activity_sum / cpi->common.MBs); -#endif - - if (cpi->activity_avg < VP8_ACTIVITY_AVG_MIN) { - cpi->activity_avg = VP8_ACTIVITY_AVG_MIN; - } - - /* Experimental code: return fixed value normalized for several clips */ - if (ALT_ACT_MEASURE) cpi->activity_avg = 100000; -} - -#define USE_ACT_INDEX 0 -#define OUTPUT_NORM_ACT_STATS 0 - -#if USE_ACT_INDEX -/* Calculate and activity index for each mb */ -static void calc_activity_index(VP8_COMP *cpi, MACROBLOCK *x) { - VP8_COMMON *const cm = &cpi->common; - int mb_row, mb_col; - - int64_t act; - int64_t a; - int64_t b; - -#if OUTPUT_NORM_ACT_STATS - FILE *f = fopen("norm_act.stt", "a"); - fprintf(f, "\n%12d\n", cpi->activity_avg); -#endif - - /* Reset pointers to start of activity map */ - x->mb_activity_ptr = cpi->mb_activity_map; - - /* Calculate normalized mb activity number. */ - for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) { - /* for each macroblock col in image */ - for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) { - /* Read activity from the map */ - act = *(x->mb_activity_ptr); - - /* Calculate a normalized activity number */ - a = act + 4 * cpi->activity_avg; - b = 4 * act + cpi->activity_avg; - - if (b >= a) - *(x->activity_ptr) = (int)((b + (a >> 1)) / a) - 1; - else - *(x->activity_ptr) = 1 - (int)((a + (b >> 1)) / b); - -#if OUTPUT_NORM_ACT_STATS - fprintf(f, " %6d", *(x->mb_activity_ptr)); -#endif - /* Increment activity map pointers */ - x->mb_activity_ptr++; - } - -#if OUTPUT_NORM_ACT_STATS - fprintf(f, "\n"); -#endif - } - -#if OUTPUT_NORM_ACT_STATS - fclose(f); -#endif -} -#endif - -/* Loop through all MBs. Note activity of each, average activity and - * calculate a normalized activity for each - */ -static void build_activity_map(VP8_COMP *cpi) { - MACROBLOCK *const x = &cpi->mb; - MACROBLOCKD *xd = &x->e_mbd; - VP8_COMMON *const cm = &cpi->common; - -#if ALT_ACT_MEASURE - YV12_BUFFER_CONFIG *new_yv12 = &cm->yv12_fb[cm->new_fb_idx]; - int recon_yoffset; - int recon_y_stride = new_yv12->y_stride; -#endif - - int mb_row, mb_col; - unsigned int mb_activity; - int64_t activity_sum = 0; - - /* for each macroblock row in image */ - for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) { -#if ALT_ACT_MEASURE - /* reset above block coeffs */ - xd->up_available = (mb_row != 0); - recon_yoffset = (mb_row * recon_y_stride * 16); -#endif - /* for each macroblock col in image */ - for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) { -#if ALT_ACT_MEASURE - xd->dst.y_buffer = new_yv12->y_buffer + recon_yoffset; - xd->left_available = (mb_col != 0); - recon_yoffset += 16; -#endif - /* Copy current mb to a buffer */ - vp8_copy_mem16x16(x->src.y_buffer, x->src.y_stride, x->thismb, 16); - - /* measure activity */ - mb_activity = mb_activity_measure(x, mb_row, mb_col); - - /* Keep frame sum */ - activity_sum += mb_activity; - - /* Store MB level activity details. */ - *x->mb_activity_ptr = mb_activity; - - /* Increment activity map pointer */ - x->mb_activity_ptr++; - - /* adjust to the next column of source macroblocks */ - x->src.y_buffer += 16; - } - - /* adjust to the next row of mbs */ - x->src.y_buffer += 16 * x->src.y_stride - 16 * cm->mb_cols; - -#if ALT_ACT_MEASURE - /* extend the recon for intra prediction */ - vp8_extend_mb_row(new_yv12, xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, - xd->dst.v_buffer + 8); -#endif - } - - /* Calculate an "average" MB activity */ - calc_av_activity(cpi, activity_sum); - -#if USE_ACT_INDEX - /* Calculate an activity index number of each mb */ - calc_activity_index(cpi, x); -#endif -} - -/* Macroblock activity masking */ -void vp8_activity_masking(VP8_COMP *cpi, MACROBLOCK *x) { -#if USE_ACT_INDEX - x->rdmult += *(x->mb_activity_ptr) * (x->rdmult >> 2); - x->errorperbit = x->rdmult * 100 / (110 * x->rddiv); - x->errorperbit += (x->errorperbit == 0); -#else - int64_t a; - int64_t b; - int64_t act = *(x->mb_activity_ptr); - - /* Apply the masking to the RD multiplier. */ - a = act + (2 * cpi->activity_avg); - b = (2 * act) + cpi->activity_avg; - - x->rdmult = (unsigned int)(((int64_t)x->rdmult * b + (a >> 1)) / a); - x->errorperbit = x->rdmult * 100 / (110 * x->rddiv); - x->errorperbit += (x->errorperbit == 0); -#endif - - /* Activity based Zbin adjustment */ - adjust_act_zbin(cpi, x); -} - -static void encode_mb_row(VP8_COMP *cpi, VP8_COMMON *cm, int mb_row, - MACROBLOCK *x, MACROBLOCKD *xd, TOKENEXTRA **tp, - int *segment_counts, int *totalrate) { - int recon_yoffset, recon_uvoffset; - int mb_col; - int ref_fb_idx = cm->lst_fb_idx; - int dst_fb_idx = cm->new_fb_idx; - int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride; - int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride; - int map_index = (mb_row * cpi->common.mb_cols); - -#if (CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING) - const int num_part = (1 << cm->multi_token_partition); - TOKENEXTRA *tp_start = cpi->tok; - vp8_writer *w; -#endif - -#if CONFIG_MULTITHREAD - const int nsync = cpi->mt_sync_range; - vpx_atomic_int rightmost_col = VPX_ATOMIC_INIT(cm->mb_cols + nsync); - const vpx_atomic_int *last_row_current_mb_col; - vpx_atomic_int *current_mb_col = NULL; - - if (vpx_atomic_load_acquire(&cpi->b_multi_threaded) != 0) { - current_mb_col = &cpi->mt_current_mb_col[mb_row]; - } - if (vpx_atomic_load_acquire(&cpi->b_multi_threaded) != 0 && mb_row != 0) { - last_row_current_mb_col = &cpi->mt_current_mb_col[mb_row - 1]; - } else { - last_row_current_mb_col = &rightmost_col; - } -#endif - -#if (CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING) - if (num_part > 1) - w = &cpi->bc[1 + (mb_row % num_part)]; - else - w = &cpi->bc[1]; -#endif - - /* reset above block coeffs */ - xd->above_context = cm->above_context; - - xd->up_available = (mb_row != 0); - recon_yoffset = (mb_row * recon_y_stride * 16); - recon_uvoffset = (mb_row * recon_uv_stride * 8); - - cpi->tplist[mb_row].start = *tp; - /* printf("Main mb_row = %d\n", mb_row); */ - - /* Distance of Mb to the top & bottom edges, specified in 1/8th pel - * units as they are always compared to values that are in 1/8th pel - */ - xd->mb_to_top_edge = -((mb_row * 16) << 3); - xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3; - - /* Set up limit values for vertical motion vector components - * to prevent them extending beyond the UMV borders - */ - x->mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 16)); - x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16) + (VP8BORDERINPIXELS - 16); - - /* Set the mb activity pointer to the start of the row. */ - x->mb_activity_ptr = &cpi->mb_activity_map[map_index]; - - /* for each macroblock col in image */ - for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) { -#if (CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING) - *tp = cpi->tok; -#endif - /* Distance of Mb to the left & right edges, specified in - * 1/8th pel units as they are always compared to values - * that are in 1/8th pel units - */ - xd->mb_to_left_edge = -((mb_col * 16) << 3); - xd->mb_to_right_edge = ((cm->mb_cols - 1 - mb_col) * 16) << 3; - - /* Set up limit values for horizontal motion vector components - * to prevent them extending beyond the UMV borders - */ - x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16)); - x->mv_col_max = - ((cm->mb_cols - 1 - mb_col) * 16) + (VP8BORDERINPIXELS - 16); - - xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset; - xd->dst.u_buffer = cm->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset; - xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset; - xd->left_available = (mb_col != 0); - - x->rddiv = cpi->RDDIV; - x->rdmult = cpi->RDMULT; - - /* Copy current mb to a buffer */ - vp8_copy_mem16x16(x->src.y_buffer, x->src.y_stride, x->thismb, 16); - -#if CONFIG_MULTITHREAD - if (vpx_atomic_load_acquire(&cpi->b_multi_threaded) != 0) { - if (((mb_col - 1) % nsync) == 0) { - vpx_atomic_store_release(current_mb_col, mb_col - 1); - } - - if (mb_row && !(mb_col & (nsync - 1))) { - vp8_atomic_spin_wait(mb_col, last_row_current_mb_col, nsync); - } - } -#endif - - if (cpi->oxcf.tuning == VP8_TUNE_SSIM) vp8_activity_masking(cpi, x); - - /* Is segmentation enabled */ - /* MB level adjustment to quantizer */ - if (xd->segmentation_enabled) { - /* Code to set segment id in xd->mbmi.segment_id for current MB - * (with range checking) - */ - if (cpi->segmentation_map[map_index + mb_col] <= 3) { - xd->mode_info_context->mbmi.segment_id = - cpi->segmentation_map[map_index + mb_col]; - } else { - xd->mode_info_context->mbmi.segment_id = 0; - } - - vp8cx_mb_init_quantizer(cpi, x, 1); - } else { - /* Set to Segment 0 by default */ - xd->mode_info_context->mbmi.segment_id = 0; - } - - x->active_ptr = cpi->active_map + map_index + mb_col; - - if (cm->frame_type == KEY_FRAME) { - const int intra_rate_cost = vp8cx_encode_intra_macroblock(cpi, x, tp); - if (INT_MAX - *totalrate > intra_rate_cost) - *totalrate += intra_rate_cost; - else - *totalrate = INT_MAX; -#ifdef MODE_STATS - y_modes[xd->mbmi.mode]++; -#endif - } else { - const int inter_rate_cost = vp8cx_encode_inter_macroblock( - cpi, x, tp, recon_yoffset, recon_uvoffset, mb_row, mb_col); - if (INT_MAX - *totalrate > inter_rate_cost) - *totalrate += inter_rate_cost; - else - *totalrate = INT_MAX; - -#ifdef MODE_STATS - inter_y_modes[xd->mbmi.mode]++; - - if (xd->mbmi.mode == SPLITMV) { - int b; - - for (b = 0; b < xd->mbmi.partition_count; ++b) { - inter_b_modes[x->partition->bmi[b].mode]++; - } - } - -#endif - - // Keep track of how many (consecutive) times a block is coded - // as ZEROMV_LASTREF, for base layer frames. - // Reset to 0 if its coded as anything else. - if (cpi->current_layer == 0) { - if (xd->mode_info_context->mbmi.mode == ZEROMV && - xd->mode_info_context->mbmi.ref_frame == LAST_FRAME) { - // Increment, check for wrap-around. - if (cpi->consec_zero_last[map_index + mb_col] < 255) { - cpi->consec_zero_last[map_index + mb_col] += 1; - } - if (cpi->consec_zero_last_mvbias[map_index + mb_col] < 255) { - cpi->consec_zero_last_mvbias[map_index + mb_col] += 1; - } - } else { - cpi->consec_zero_last[map_index + mb_col] = 0; - cpi->consec_zero_last_mvbias[map_index + mb_col] = 0; - } - if (x->zero_last_dot_suppress) { - cpi->consec_zero_last_mvbias[map_index + mb_col] = 0; - } - } - - /* Special case code for cyclic refresh - * If cyclic update enabled then copy xd->mbmi.segment_id; (which - * may have been updated based on mode during - * vp8cx_encode_inter_macroblock()) back into the global - * segmentation map - */ - if ((cpi->current_layer == 0) && - (cpi->cyclic_refresh_mode_enabled && xd->segmentation_enabled)) { - cpi->segmentation_map[map_index + mb_col] = - xd->mode_info_context->mbmi.segment_id; - - /* If the block has been refreshed mark it as clean (the - * magnitude of the -ve influences how long it will be before - * we consider another refresh): - * Else if it was coded (last frame 0,0) and has not already - * been refreshed then mark it as a candidate for cleanup - * next time (marked 0) else mark it as dirty (1). - */ - if (xd->mode_info_context->mbmi.segment_id) { - cpi->cyclic_refresh_map[map_index + mb_col] = -1; - } else if ((xd->mode_info_context->mbmi.mode == ZEROMV) && - (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)) { - if (cpi->cyclic_refresh_map[map_index + mb_col] == 1) { - cpi->cyclic_refresh_map[map_index + mb_col] = 0; - } - } else { - cpi->cyclic_refresh_map[map_index + mb_col] = 1; - } - } - } - - cpi->tplist[mb_row].stop = *tp; - -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING - /* pack tokens for this MB */ - { - int tok_count = *tp - tp_start; - vp8_pack_tokens(w, tp_start, tok_count); - } -#endif - /* Increment pointer into gf usage flags structure. */ - x->gf_active_ptr++; - - /* Increment the activity mask pointers. */ - x->mb_activity_ptr++; - - /* adjust to the next column of macroblocks */ - x->src.y_buffer += 16; - x->src.u_buffer += 8; - x->src.v_buffer += 8; - - recon_yoffset += 16; - recon_uvoffset += 8; - - /* Keep track of segment usage */ - segment_counts[xd->mode_info_context->mbmi.segment_id]++; - - /* skip to next mb */ - xd->mode_info_context++; - x->partition_info++; - xd->above_context++; - } - - /* extend the recon for intra prediction */ - vp8_extend_mb_row(&cm->yv12_fb[dst_fb_idx], xd->dst.y_buffer + 16, - xd->dst.u_buffer + 8, xd->dst.v_buffer + 8); - -#if CONFIG_MULTITHREAD - if (vpx_atomic_load_acquire(&cpi->b_multi_threaded) != 0) { - vpx_atomic_store_release(current_mb_col, - vpx_atomic_load_acquire(&rightmost_col)); - } -#endif - - /* this is to account for the border */ - xd->mode_info_context++; - x->partition_info++; -} - -static void init_encode_frame_mb_context(VP8_COMP *cpi) { - MACROBLOCK *const x = &cpi->mb; - VP8_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &x->e_mbd; - - /* GF active flags data structure */ - x->gf_active_ptr = (signed char *)cpi->gf_active_flags; - - /* Activity map pointer */ - x->mb_activity_ptr = cpi->mb_activity_map; - - x->act_zbin_adj = 0; - - x->partition_info = x->pi; - - xd->mode_info_context = cm->mi; - xd->mode_info_stride = cm->mode_info_stride; - - xd->frame_type = cm->frame_type; - - /* reset intra mode contexts */ - if (cm->frame_type == KEY_FRAME) vp8_init_mbmode_probs(cm); - - /* Copy data over into macro block data structures. */ - x->src = *cpi->Source; - xd->pre = cm->yv12_fb[cm->lst_fb_idx]; - xd->dst = cm->yv12_fb[cm->new_fb_idx]; - - /* set up frame for intra coded blocks */ - vp8_setup_intra_recon(&cm->yv12_fb[cm->new_fb_idx]); - - vp8_build_block_offsets(x); - - xd->mode_info_context->mbmi.mode = DC_PRED; - xd->mode_info_context->mbmi.uv_mode = DC_PRED; - - xd->left_context = &cm->left_context; - - x->mvc = cm->fc.mvc; - - memset(cm->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) * cm->mb_cols); - - /* Special case treatment when GF and ARF are not sensible options - * for reference - */ - if (cpi->ref_frame_flags == VP8_LAST_FRAME) { - vp8_calc_ref_frame_costs(x->ref_frame_cost, cpi->prob_intra_coded, 255, - 128); - } else if ((cpi->oxcf.number_of_layers > 1) && - (cpi->ref_frame_flags == VP8_GOLD_FRAME)) { - vp8_calc_ref_frame_costs(x->ref_frame_cost, cpi->prob_intra_coded, 1, 255); - } else if ((cpi->oxcf.number_of_layers > 1) && - (cpi->ref_frame_flags == VP8_ALTR_FRAME)) { - vp8_calc_ref_frame_costs(x->ref_frame_cost, cpi->prob_intra_coded, 1, 1); - } else { - vp8_calc_ref_frame_costs(x->ref_frame_cost, cpi->prob_intra_coded, - cpi->prob_last_coded, cpi->prob_gf_coded); - } - - xd->fullpixel_mask = ~0; - if (cm->full_pixel) xd->fullpixel_mask = ~7; - - vp8_zero(x->coef_counts); - vp8_zero(x->ymode_count); - vp8_zero(x->uv_mode_count); - x->prediction_error = 0; - x->intra_error = 0; - vp8_zero(x->count_mb_ref_frame_usage); -} - -#if CONFIG_MULTITHREAD -static void sum_coef_counts(MACROBLOCK *x, MACROBLOCK *x_thread) { - int i = 0; - do { - int j = 0; - do { - int k = 0; - do { - /* at every context */ - - /* calc probs and branch cts for this frame only */ - int t = 0; /* token/prob index */ - - do { - x->coef_counts[i][j][k][t] += x_thread->coef_counts[i][j][k][t]; - } while (++t < ENTROPY_NODES); - } while (++k < PREV_COEF_CONTEXTS); - } while (++j < COEF_BANDS); - } while (++i < BLOCK_TYPES); -} -#endif // CONFIG_MULTITHREAD - -void vp8_encode_frame(VP8_COMP *cpi) { - int mb_row; - MACROBLOCK *const x = &cpi->mb; - VP8_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &x->e_mbd; - TOKENEXTRA *tp = cpi->tok; - int segment_counts[MAX_MB_SEGMENTS]; - int totalrate; -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING - BOOL_CODER *bc = &cpi->bc[1]; /* bc[0] is for control partition */ - const int num_part = (1 << cm->multi_token_partition); -#endif - - memset(segment_counts, 0, sizeof(segment_counts)); - totalrate = 0; - - if (cpi->compressor_speed == 2) { - if (cpi->oxcf.cpu_used < 0) { - cpi->Speed = -(cpi->oxcf.cpu_used); - } else { - vp8_auto_select_speed(cpi); - } - } - - /* Functions setup for all frame types so we can use MC in AltRef */ - if (!cm->use_bilinear_mc_filter) { - xd->subpixel_predict = vp8_sixtap_predict4x4; - xd->subpixel_predict8x4 = vp8_sixtap_predict8x4; - xd->subpixel_predict8x8 = vp8_sixtap_predict8x8; - xd->subpixel_predict16x16 = vp8_sixtap_predict16x16; - } else { - xd->subpixel_predict = vp8_bilinear_predict4x4; - xd->subpixel_predict8x4 = vp8_bilinear_predict8x4; - xd->subpixel_predict8x8 = vp8_bilinear_predict8x8; - xd->subpixel_predict16x16 = vp8_bilinear_predict16x16; - } - - cpi->mb.skip_true_count = 0; - cpi->tok_count = 0; - -#if 0 - /* Experimental code */ - cpi->frame_distortion = 0; - cpi->last_mb_distortion = 0; -#endif - - xd->mode_info_context = cm->mi; - - vp8_zero(cpi->mb.MVcount); - - vp8cx_frame_init_quantizer(cpi); - - vp8_initialize_rd_consts(cpi, x, - vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q)); - - vp8cx_initialize_me_consts(cpi, cm->base_qindex); - - if (cpi->oxcf.tuning == VP8_TUNE_SSIM) { - /* Initialize encode frame context. */ - init_encode_frame_mb_context(cpi); - - /* Build a frame level activity map */ - build_activity_map(cpi); - } - - /* re-init encode frame context. */ - init_encode_frame_mb_context(cpi); - -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING - { - int i; - for (i = 0; i < num_part; ++i) { - vp8_start_encode(&bc[i], cpi->partition_d[i + 1], - cpi->partition_d_end[i + 1]); - bc[i].error = &cm->error; - } - } - -#endif - - { - struct vpx_usec_timer emr_timer; - vpx_usec_timer_start(&emr_timer); - -#if CONFIG_MULTITHREAD - if (vpx_atomic_load_acquire(&cpi->b_multi_threaded)) { - int i; - - vp8cx_init_mbrthread_data(cpi, x, cpi->mb_row_ei, - cpi->encoding_thread_count); - - if (cpi->mt_current_mb_col_size != cm->mb_rows) { - vpx_free(cpi->mt_current_mb_col); - cpi->mt_current_mb_col = NULL; - cpi->mt_current_mb_col_size = 0; - CHECK_MEM_ERROR( - &cpi->common.error, cpi->mt_current_mb_col, - vpx_malloc(sizeof(*cpi->mt_current_mb_col) * cm->mb_rows)); - cpi->mt_current_mb_col_size = cm->mb_rows; - } - for (i = 0; i < cm->mb_rows; ++i) - vpx_atomic_store_release(&cpi->mt_current_mb_col[i], -1); - - for (i = 0; i < cpi->encoding_thread_count; ++i) { - vp8_sem_post(&cpi->h_event_start_encoding[i]); - } - - for (mb_row = 0; mb_row < cm->mb_rows; - mb_row += (cpi->encoding_thread_count + 1)) { - vp8_zero(cm->left_context); - -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING - tp = cpi->tok; -#else - tp = cpi->tok + mb_row * (cm->mb_cols * 16 * 24); -#endif - - encode_mb_row(cpi, cm, mb_row, x, xd, &tp, segment_counts, &totalrate); - - /* adjust to the next row of mbs */ - x->src.y_buffer += - 16 * x->src.y_stride * (cpi->encoding_thread_count + 1) - - 16 * cm->mb_cols; - x->src.u_buffer += - 8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - - 8 * cm->mb_cols; - x->src.v_buffer += - 8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - - 8 * cm->mb_cols; - - xd->mode_info_context += - xd->mode_info_stride * cpi->encoding_thread_count; - x->partition_info += xd->mode_info_stride * cpi->encoding_thread_count; - x->gf_active_ptr += cm->mb_cols * cpi->encoding_thread_count; - } - /* Wait for all the threads to finish. */ - for (i = 0; i < cpi->encoding_thread_count; ++i) { - vp8_sem_wait(&cpi->h_event_end_encoding[i]); - } - - for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) { - cpi->tok_count += (unsigned int)(cpi->tplist[mb_row].stop - - cpi->tplist[mb_row].start); - } - - if (xd->segmentation_enabled) { - int j; - - if (xd->segmentation_enabled) { - for (i = 0; i < cpi->encoding_thread_count; ++i) { - for (j = 0; j < 4; ++j) { - segment_counts[j] += cpi->mb_row_ei[i].segment_counts[j]; - } - } - } - } - - for (i = 0; i < cpi->encoding_thread_count; ++i) { - int mode_count; - int c_idx; - totalrate += cpi->mb_row_ei[i].totalrate; - - cpi->mb.skip_true_count += cpi->mb_row_ei[i].mb.skip_true_count; - - for (mode_count = 0; mode_count < VP8_YMODES; ++mode_count) { - cpi->mb.ymode_count[mode_count] += - cpi->mb_row_ei[i].mb.ymode_count[mode_count]; - } - - for (mode_count = 0; mode_count < VP8_UV_MODES; ++mode_count) { - cpi->mb.uv_mode_count[mode_count] += - cpi->mb_row_ei[i].mb.uv_mode_count[mode_count]; - } - - for (c_idx = 0; c_idx < MVvals; ++c_idx) { - cpi->mb.MVcount[0][c_idx] += cpi->mb_row_ei[i].mb.MVcount[0][c_idx]; - cpi->mb.MVcount[1][c_idx] += cpi->mb_row_ei[i].mb.MVcount[1][c_idx]; - } - - cpi->mb.prediction_error += cpi->mb_row_ei[i].mb.prediction_error; - cpi->mb.intra_error += cpi->mb_row_ei[i].mb.intra_error; - - for (c_idx = 0; c_idx < MAX_REF_FRAMES; ++c_idx) { - cpi->mb.count_mb_ref_frame_usage[c_idx] += - cpi->mb_row_ei[i].mb.count_mb_ref_frame_usage[c_idx]; - } - - for (c_idx = 0; c_idx < MAX_ERROR_BINS; ++c_idx) { - cpi->mb.error_bins[c_idx] += cpi->mb_row_ei[i].mb.error_bins[c_idx]; - } - - /* add up counts for each thread */ - sum_coef_counts(x, &cpi->mb_row_ei[i].mb); - } - - } else -#endif // CONFIG_MULTITHREAD - { - - /* for each macroblock row in image */ - for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) { - vp8_zero(cm->left_context); - -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING - tp = cpi->tok; -#endif - - encode_mb_row(cpi, cm, mb_row, x, xd, &tp, segment_counts, &totalrate); - - /* adjust to the next row of mbs */ - x->src.y_buffer += 16 * x->src.y_stride - 16 * cm->mb_cols; - x->src.u_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols; - x->src.v_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols; - } - - cpi->tok_count = (unsigned int)(tp - cpi->tok); - } - -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING - { - int i; - for (i = 0; i < num_part; ++i) { - vp8_stop_encode(&bc[i]); - cpi->partition_sz[i + 1] = bc[i].pos; - } - } -#endif - - vpx_usec_timer_mark(&emr_timer); - cpi->time_encode_mb_row += vpx_usec_timer_elapsed(&emr_timer); - } - - // Work out the segment probabilities if segmentation is enabled - // and needs to be updated - if (xd->segmentation_enabled && xd->update_mb_segmentation_map) { - int tot_count; - int i; - - /* Set to defaults */ - memset(xd->mb_segment_tree_probs, 255, sizeof(xd->mb_segment_tree_probs)); - - tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + - segment_counts[3]; - - if (tot_count) { - xd->mb_segment_tree_probs[0] = - ((segment_counts[0] + segment_counts[1]) * 255) / tot_count; - - tot_count = segment_counts[0] + segment_counts[1]; - - if (tot_count > 0) { - xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) / tot_count; - } - - tot_count = segment_counts[2] + segment_counts[3]; - - if (tot_count > 0) { - xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) / tot_count; - } - - /* Zero probabilities not allowed */ - for (i = 0; i < MB_FEATURE_TREE_PROBS; ++i) { - if (xd->mb_segment_tree_probs[i] == 0) xd->mb_segment_tree_probs[i] = 1; - } - } - } - - /* projected_frame_size in units of BYTES */ - cpi->projected_frame_size = totalrate >> 8; - - /* Make a note of the percentage MBs coded Intra. */ - if (cm->frame_type == KEY_FRAME) { - cpi->this_frame_percent_intra = 100; - } else { - int tot_modes; - - tot_modes = cpi->mb.count_mb_ref_frame_usage[INTRA_FRAME] + - cpi->mb.count_mb_ref_frame_usage[LAST_FRAME] + - cpi->mb.count_mb_ref_frame_usage[GOLDEN_FRAME] + - cpi->mb.count_mb_ref_frame_usage[ALTREF_FRAME]; - - if (tot_modes) { - cpi->this_frame_percent_intra = - cpi->mb.count_mb_ref_frame_usage[INTRA_FRAME] * 100 / tot_modes; - } - } - -#if !CONFIG_REALTIME_ONLY - /* Adjust the projected reference frame usage probability numbers to - * reflect what we have just seen. This may be useful when we make - * multiple iterations of the recode loop rather than continuing to use - * values from the previous frame. - */ - if ((cm->frame_type != KEY_FRAME) && - ((cpi->oxcf.number_of_layers > 1) || - (!cm->refresh_alt_ref_frame && !cm->refresh_golden_frame))) { - vp8_convert_rfct_to_prob(cpi); - } -#endif -} -void vp8_setup_block_ptrs(MACROBLOCK *x) { - int r, c; - int i; - - for (r = 0; r < 4; ++r) { - for (c = 0; c < 4; ++c) { - x->block[r * 4 + c].src_diff = x->src_diff + r * 4 * 16 + c * 4; - } - } - - for (r = 0; r < 2; ++r) { - for (c = 0; c < 2; ++c) { - x->block[16 + r * 2 + c].src_diff = x->src_diff + 256 + r * 4 * 8 + c * 4; - } - } - - for (r = 0; r < 2; ++r) { - for (c = 0; c < 2; ++c) { - x->block[20 + r * 2 + c].src_diff = x->src_diff + 320 + r * 4 * 8 + c * 4; - } - } - - x->block[24].src_diff = x->src_diff + 384; - - for (i = 0; i < 25; ++i) { - x->block[i].coeff = x->coeff + i * 16; - } -} - -void vp8_build_block_offsets(MACROBLOCK *x) { - int block = 0; - int br, bc; - - vp8_build_block_doffsets(&x->e_mbd); - - /* y blocks */ - x->thismb_ptr = &x->thismb[0]; - for (br = 0; br < 4; ++br) { - for (bc = 0; bc < 4; ++bc) { - BLOCK *this_block = &x->block[block]; - this_block->base_src = &x->thismb_ptr; - this_block->src_stride = 16; - this_block->src = 4 * br * 16 + 4 * bc; - ++block; - } - } - - /* u blocks */ - for (br = 0; br < 2; ++br) { - for (bc = 0; bc < 2; ++bc) { - BLOCK *this_block = &x->block[block]; - this_block->base_src = &x->src.u_buffer; - this_block->src_stride = x->src.uv_stride; - this_block->src = 4 * br * this_block->src_stride + 4 * bc; - ++block; - } - } - - /* v blocks */ - for (br = 0; br < 2; ++br) { - for (bc = 0; bc < 2; ++bc) { - BLOCK *this_block = &x->block[block]; - this_block->base_src = &x->src.v_buffer; - this_block->src_stride = x->src.uv_stride; - this_block->src = 4 * br * this_block->src_stride + 4 * bc; - ++block; - } - } -} - -static void sum_intra_stats(VP8_COMP *cpi, MACROBLOCK *x) { - const MACROBLOCKD *xd = &x->e_mbd; - const MB_PREDICTION_MODE m = xd->mode_info_context->mbmi.mode; - const MB_PREDICTION_MODE uvm = xd->mode_info_context->mbmi.uv_mode; - -#ifdef MODE_STATS - const int is_key = cpi->common.frame_type == KEY_FRAME; - - ++(is_key ? uv_modes : inter_uv_modes)[uvm]; - - if (m == B_PRED) { - unsigned int *const bct = is_key ? b_modes : inter_b_modes; - - int b = 0; - - do { - ++bct[xd->block[b].bmi.mode]; - } while (++b < 16); - } - -#else - (void)cpi; -#endif - - ++x->ymode_count[m]; - ++x->uv_mode_count[uvm]; -} - -/* Experimental stub function to create a per MB zbin adjustment based on - * some previously calculated measure of MB activity. - */ -static void adjust_act_zbin(VP8_COMP *cpi, MACROBLOCK *x) { -#if USE_ACT_INDEX - x->act_zbin_adj = *(x->mb_activity_ptr); -#else - int64_t a; - int64_t b; - int64_t act = *(x->mb_activity_ptr); - - /* Apply the masking to the RD multiplier. */ - a = act + 4 * cpi->activity_avg; - b = 4 * act + cpi->activity_avg; - - if (act > cpi->activity_avg) { - x->act_zbin_adj = (int)(((int64_t)b + (a >> 1)) / a) - 1; - } else { - x->act_zbin_adj = 1 - (int)(((int64_t)a + (b >> 1)) / b); - } -#endif -} - -int vp8cx_encode_intra_macroblock(VP8_COMP *cpi, MACROBLOCK *x, - TOKENEXTRA **t) { - MACROBLOCKD *xd = &x->e_mbd; - int rate; - - if (cpi->sf.RD && cpi->compressor_speed != 2) { - vp8_rd_pick_intra_mode(x, &rate); - } else { - vp8_pick_intra_mode(x, &rate); - } - - if (cpi->oxcf.tuning == VP8_TUNE_SSIM) { - adjust_act_zbin(cpi, x); - vp8_update_zbin_extra(cpi, x); - } - - if (x->e_mbd.mode_info_context->mbmi.mode == B_PRED) { - vp8_encode_intra4x4mby(x); - } else { - vp8_encode_intra16x16mby(x); - } - - vp8_encode_intra16x16mbuv(x); - - sum_intra_stats(cpi, x); - - vp8_tokenize_mb(cpi, x, t); - - if (xd->mode_info_context->mbmi.mode != B_PRED) vp8_inverse_transform_mby(xd); - - vp8_dequant_idct_add_uv_block(xd->qcoeff + 16 * 16, xd->dequant_uv, - xd->dst.u_buffer, xd->dst.v_buffer, - xd->dst.uv_stride, xd->eobs + 16); - return rate; -} -#ifdef SPEEDSTATS -extern int cnt_pm; -#endif - -extern void vp8_fix_contexts(MACROBLOCKD *x); - -int vp8cx_encode_inter_macroblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t, - int recon_yoffset, int recon_uvoffset, - int mb_row, int mb_col) { - MACROBLOCKD *const xd = &x->e_mbd; - int intra_error = 0; - int rate; - int distortion; - - x->skip = 0; - - if (xd->segmentation_enabled) { - x->encode_breakout = - cpi->segment_encode_breakout[xd->mode_info_context->mbmi.segment_id]; - } else { - x->encode_breakout = cpi->oxcf.encode_breakout; - } - -#if CONFIG_TEMPORAL_DENOISING - /* Reset the best sse mode/mv for each macroblock. */ - x->best_reference_frame = INTRA_FRAME; - x->best_zeromv_reference_frame = INTRA_FRAME; - x->best_sse_inter_mode = 0; - x->best_sse_mv.as_int = 0; - x->need_to_clamp_best_mvs = 0; -#endif - - if (cpi->sf.RD) { - int zbin_mode_boost_enabled = x->zbin_mode_boost_enabled; - - /* Are we using the fast quantizer for the mode selection? */ - if (cpi->sf.use_fastquant_for_pick) { - x->quantize_b = vp8_fast_quantize_b; - - /* the fast quantizer does not use zbin_extra, so - * do not recalculate */ - x->zbin_mode_boost_enabled = 0; - } - vp8_rd_pick_inter_mode(cpi, x, recon_yoffset, recon_uvoffset, &rate, - &distortion, &intra_error, mb_row, mb_col); - - /* switch back to the regular quantizer for the encode */ - if (cpi->sf.improved_quant) { - x->quantize_b = vp8_regular_quantize_b; - } - - /* restore cpi->zbin_mode_boost_enabled */ - x->zbin_mode_boost_enabled = zbin_mode_boost_enabled; - - } else { - vp8_pick_inter_mode(cpi, x, recon_yoffset, recon_uvoffset, &rate, - &distortion, &intra_error, mb_row, mb_col); - } - - x->prediction_error += distortion; - x->intra_error += intra_error; - - if (cpi->oxcf.tuning == VP8_TUNE_SSIM) { - /* Adjust the zbin based on this MB rate. */ - adjust_act_zbin(cpi, x); - } - -#if 0 - /* Experimental RD code */ - cpi->frame_distortion += distortion; - cpi->last_mb_distortion = distortion; -#endif - - /* MB level adjutment to quantizer setup */ - if (xd->segmentation_enabled) { - /* If cyclic update enabled */ - if (cpi->current_layer == 0 && cpi->cyclic_refresh_mode_enabled) { - /* Clear segment_id back to 0 if not coded (last frame 0,0) */ - if ((xd->mode_info_context->mbmi.segment_id == 1) && - ((xd->mode_info_context->mbmi.ref_frame != LAST_FRAME) || - (xd->mode_info_context->mbmi.mode != ZEROMV))) { - xd->mode_info_context->mbmi.segment_id = 0; - - /* segment_id changed, so update */ - vp8cx_mb_init_quantizer(cpi, x, 1); - } - } - } - - { - /* Experimental code. - * Special case for gf and arf zeromv modes, for 1 temporal layer. - * Increase zbin size to supress noise. - */ - x->zbin_mode_boost = 0; - if (x->zbin_mode_boost_enabled) { - if (xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME) { - if (xd->mode_info_context->mbmi.mode == ZEROMV) { - if (xd->mode_info_context->mbmi.ref_frame != LAST_FRAME && - cpi->oxcf.number_of_layers == 1) { - x->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST; - } else { - x->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST; - } - } else if (xd->mode_info_context->mbmi.mode == SPLITMV) { - x->zbin_mode_boost = 0; - } else { - x->zbin_mode_boost = MV_ZBIN_BOOST; - } - } - } - - /* The fast quantizer doesn't use zbin_extra, only do so with - * the regular quantizer. */ - if (cpi->sf.improved_quant) vp8_update_zbin_extra(cpi, x); - } - - x->count_mb_ref_frame_usage[xd->mode_info_context->mbmi.ref_frame]++; - - if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) { - vp8_encode_intra16x16mbuv(x); - - if (xd->mode_info_context->mbmi.mode == B_PRED) { - vp8_encode_intra4x4mby(x); - } else { - vp8_encode_intra16x16mby(x); - } - - sum_intra_stats(cpi, x); - } else { - int ref_fb_idx; - - if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME) { - ref_fb_idx = cpi->common.lst_fb_idx; - } else if (xd->mode_info_context->mbmi.ref_frame == GOLDEN_FRAME) { - ref_fb_idx = cpi->common.gld_fb_idx; - } else { - ref_fb_idx = cpi->common.alt_fb_idx; - } - - xd->pre.y_buffer = cpi->common.yv12_fb[ref_fb_idx].y_buffer + recon_yoffset; - xd->pre.u_buffer = - cpi->common.yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset; - xd->pre.v_buffer = - cpi->common.yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset; - - if (!x->skip) { - vp8_encode_inter16x16(x); - } else { - vp8_build_inter16x16_predictors_mb(xd, xd->dst.y_buffer, xd->dst.u_buffer, - xd->dst.v_buffer, xd->dst.y_stride, - xd->dst.uv_stride); - } - } - - if (!x->skip) { - vp8_tokenize_mb(cpi, x, t); - - if (xd->mode_info_context->mbmi.mode != B_PRED) { - vp8_inverse_transform_mby(xd); - } - - vp8_dequant_idct_add_uv_block(xd->qcoeff + 16 * 16, xd->dequant_uv, - xd->dst.u_buffer, xd->dst.v_buffer, - xd->dst.uv_stride, xd->eobs + 16); - } else { - /* always set mb_skip_coeff as it is needed by the loopfilter */ - xd->mode_info_context->mbmi.mb_skip_coeff = 1; - - if (cpi->common.mb_no_coeff_skip) { - x->skip_true_count++; - vp8_fix_contexts(xd); - } else { - vp8_stuff_mb(cpi, x, t); - } - } - - return rate; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodeframe.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodeframe.h deleted file mode 100644 index cc8cf4d7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodeframe.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_VP8_ENCODER_ENCODEFRAME_H_ -#define VPX_VP8_ENCODER_ENCODEFRAME_H_ - -#include "vp8/encoder/tokenize.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct VP8_COMP; -struct macroblock; - -void vp8_activity_masking(struct VP8_COMP *cpi, MACROBLOCK *x); - -void vp8_build_block_offsets(struct macroblock *x); - -void vp8_setup_block_ptrs(struct macroblock *x); - -void vp8_encode_frame(struct VP8_COMP *cpi); - -int vp8cx_encode_inter_macroblock(struct VP8_COMP *cpi, struct macroblock *x, - TOKENEXTRA **t, int recon_yoffset, - int recon_uvoffset, int mb_row, int mb_col); - -int vp8cx_encode_intra_macroblock(struct VP8_COMP *cpi, struct macroblock *x, - TOKENEXTRA **t); -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_ENCODEFRAME_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodeintra.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodeintra.c deleted file mode 100644 index 7d448c0e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodeintra.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "vp8_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "vp8/encoder/quantize.h" -#include "vp8/common/reconintra.h" -#include "vp8/common/reconintra4x4.h" -#include "encodemb.h" -#include "vp8/common/invtrans.h" -#include "encodeintra.h" - -int vp8_encode_intra(MACROBLOCK *x, int use_dc_pred) { - int i; - int intra_pred_var = 0; - - if (use_dc_pred) { - x->e_mbd.mode_info_context->mbmi.mode = DC_PRED; - x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED; - x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME; - - vp8_encode_intra16x16mby(x); - - vp8_inverse_transform_mby(&x->e_mbd); - } else { - for (i = 0; i < 16; ++i) { - x->e_mbd.block[i].bmi.as_mode = B_DC_PRED; - vp8_encode_intra4x4block(x, i); - } - } - - intra_pred_var = vpx_get_mb_ss(x->src_diff); - - return intra_pred_var; -} - -void vp8_encode_intra4x4block(MACROBLOCK *x, int ib) { - BLOCKD *b = &x->e_mbd.block[ib]; - BLOCK *be = &x->block[ib]; - int dst_stride = x->e_mbd.dst.y_stride; - unsigned char *dst = x->e_mbd.dst.y_buffer + b->offset; - unsigned char *Above = dst - dst_stride; - unsigned char *yleft = dst - 1; - unsigned char top_left = Above[-1]; - - vp8_intra4x4_predict(Above, yleft, dst_stride, b->bmi.as_mode, b->predictor, - 16, top_left); - - vp8_subtract_b(be, b, 16); - - x->short_fdct4x4(be->src_diff, be->coeff, 32); - - x->quantize_b(be, b); - - if (*b->eob > 1) { - vp8_short_idct4x4llm(b->dqcoeff, b->predictor, 16, dst, dst_stride); - } else { - vp8_dc_only_idct_add(b->dqcoeff[0], b->predictor, 16, dst, dst_stride); - } -} - -void vp8_encode_intra4x4mby(MACROBLOCK *mb) { - int i; - - MACROBLOCKD *xd = &mb->e_mbd; - intra_prediction_down_copy(xd, xd->dst.y_buffer - xd->dst.y_stride + 16); - - for (i = 0; i < 16; ++i) vp8_encode_intra4x4block(mb, i); - return; -} - -void vp8_encode_intra16x16mby(MACROBLOCK *x) { - BLOCK *b = &x->block[0]; - MACROBLOCKD *xd = &x->e_mbd; - - vp8_build_intra_predictors_mby_s(xd, xd->dst.y_buffer - xd->dst.y_stride, - xd->dst.y_buffer - 1, xd->dst.y_stride, - xd->dst.y_buffer, xd->dst.y_stride); - - vp8_subtract_mby(x->src_diff, *(b->base_src), b->src_stride, xd->dst.y_buffer, - xd->dst.y_stride); - - vp8_transform_intra_mby(x); - - vp8_quantize_mby(x); - - if (x->optimize) vp8_optimize_mby(x); -} - -void vp8_encode_intra16x16mbuv(MACROBLOCK *x) { - MACROBLOCKD *xd = &x->e_mbd; - - vp8_build_intra_predictors_mbuv_s(xd, xd->dst.u_buffer - xd->dst.uv_stride, - xd->dst.v_buffer - xd->dst.uv_stride, - xd->dst.u_buffer - 1, xd->dst.v_buffer - 1, - xd->dst.uv_stride, xd->dst.u_buffer, - xd->dst.v_buffer, xd->dst.uv_stride); - - vp8_subtract_mbuv(x->src_diff, x->src.u_buffer, x->src.v_buffer, - x->src.uv_stride, xd->dst.u_buffer, xd->dst.v_buffer, - xd->dst.uv_stride); - - vp8_transform_mbuv(x); - - vp8_quantize_mbuv(x); - - if (x->optimize) vp8_optimize_mbuv(x); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodeintra.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodeintra.h deleted file mode 100644 index 9a378abf..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodeintra.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_ENCODEINTRA_H_ -#define VPX_VP8_ENCODER_ENCODEINTRA_H_ -#include "onyx_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int vp8_encode_intra(MACROBLOCK *x, int use_dc_pred); -void vp8_encode_intra16x16mby(MACROBLOCK *x); -void vp8_encode_intra16x16mbuv(MACROBLOCK *x); -void vp8_encode_intra4x4mby(MACROBLOCK *mb); -void vp8_encode_intra4x4block(MACROBLOCK *x, int ib); -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_ENCODEINTRA_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodemb.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodemb.c deleted file mode 100644 index 3fd8d5fa..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodemb.c +++ /dev/null @@ -1,512 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" - -#include "vpx_config.h" -#include "vp8_rtcd.h" -#include "encodemb.h" -#include "vp8/common/reconinter.h" -#include "vp8/encoder/quantize.h" -#include "tokenize.h" -#include "vp8/common/invtrans.h" -#include "vpx_mem/vpx_mem.h" -#include "rdopt.h" - -void vp8_subtract_b(BLOCK *be, BLOCKD *bd, int pitch) { - unsigned char *src_ptr = (*(be->base_src) + be->src); - short *diff_ptr = be->src_diff; - unsigned char *pred_ptr = bd->predictor; - int src_stride = be->src_stride; - - vpx_subtract_block(4, 4, diff_ptr, pitch, src_ptr, src_stride, pred_ptr, - pitch); -} - -void vp8_subtract_mbuv(short *diff, unsigned char *usrc, unsigned char *vsrc, - int src_stride, unsigned char *upred, - unsigned char *vpred, int pred_stride) { - short *udiff = diff + 256; - short *vdiff = diff + 320; - - vpx_subtract_block(8, 8, udiff, 8, usrc, src_stride, upred, pred_stride); - vpx_subtract_block(8, 8, vdiff, 8, vsrc, src_stride, vpred, pred_stride); -} - -void vp8_subtract_mby(short *diff, unsigned char *src, int src_stride, - unsigned char *pred, int pred_stride) { - vpx_subtract_block(16, 16, diff, 16, src, src_stride, pred, pred_stride); -} - -static void vp8_subtract_mb(MACROBLOCK *x) { - BLOCK *b = &x->block[0]; - - vp8_subtract_mby(x->src_diff, *(b->base_src), b->src_stride, - x->e_mbd.dst.y_buffer, x->e_mbd.dst.y_stride); - vp8_subtract_mbuv(x->src_diff, x->src.u_buffer, x->src.v_buffer, - x->src.uv_stride, x->e_mbd.dst.u_buffer, - x->e_mbd.dst.v_buffer, x->e_mbd.dst.uv_stride); -} - -static void build_dcblock(MACROBLOCK *x) { - short *src_diff_ptr = &x->src_diff[384]; - int i; - - for (i = 0; i < 16; ++i) { - src_diff_ptr[i] = x->coeff[i * 16]; - } -} - -void vp8_transform_mbuv(MACROBLOCK *x) { - int i; - - for (i = 16; i < 24; i += 2) { - x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 16); - } -} - -void vp8_transform_intra_mby(MACROBLOCK *x) { - int i; - - for (i = 0; i < 16; i += 2) { - x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 32); - } - - /* build dc block from 16 y dc values */ - build_dcblock(x); - - /* do 2nd order transform on the dc block */ - x->short_walsh4x4(&x->block[24].src_diff[0], &x->block[24].coeff[0], 8); -} - -static void transform_mb(MACROBLOCK *x) { - int i; - - for (i = 0; i < 16; i += 2) { - x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 32); - } - - /* build dc block from 16 y dc values */ - if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) build_dcblock(x); - - for (i = 16; i < 24; i += 2) { - x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 16); - } - - /* do 2nd order transform on the dc block */ - if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) { - x->short_walsh4x4(&x->block[24].src_diff[0], &x->block[24].coeff[0], 8); - } -} - -static void transform_mby(MACROBLOCK *x) { - int i; - - for (i = 0; i < 16; i += 2) { - x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 32); - } - - /* build dc block from 16 y dc values */ - if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) { - build_dcblock(x); - x->short_walsh4x4(&x->block[24].src_diff[0], &x->block[24].coeff[0], 8); - } -} - -#define RDTRUNC(RM, DM, R, D) ((128 + (R) * (RM)) & 0xFF) - -typedef struct vp8_token_state vp8_token_state; - -struct vp8_token_state { - int rate; - int error; - signed char next; - signed char token; - short qc; -}; - -/* TODO: experiments to find optimal multiple numbers */ -#define Y1_RD_MULT 4 -#define UV_RD_MULT 2 -#define Y2_RD_MULT 16 - -static const int plane_rd_mult[4] = { Y1_RD_MULT, Y2_RD_MULT, UV_RD_MULT, - Y1_RD_MULT }; - -static void optimize_b(MACROBLOCK *mb, int ib, int type, ENTROPY_CONTEXT *a, - ENTROPY_CONTEXT *l) { - BLOCK *b; - BLOCKD *d; - vp8_token_state tokens[17][2]; - unsigned best_mask[2]; - const short *dequant_ptr; - const short *coeff_ptr; - short *qcoeff_ptr; - short *dqcoeff_ptr; - int eob; - int i0; - int rc; - int x; - int sz = 0; - int next; - int rdmult; - int rddiv; - int final_eob; - int rd_cost0; - int rd_cost1; - int rate0; - int rate1; - int error0; - int error1; - int t0; - int t1; - int best; - int band; - int pt; - int i; - int err_mult = plane_rd_mult[type]; - - b = &mb->block[ib]; - d = &mb->e_mbd.block[ib]; - - dequant_ptr = d->dequant; - coeff_ptr = b->coeff; - qcoeff_ptr = d->qcoeff; - dqcoeff_ptr = d->dqcoeff; - i0 = !type; - eob = *d->eob; - - /* Now set up a Viterbi trellis to evaluate alternative roundings. */ - rdmult = mb->rdmult * err_mult; - if (mb->e_mbd.mode_info_context->mbmi.ref_frame == INTRA_FRAME) { - rdmult = (rdmult * 9) >> 4; - } - - rddiv = mb->rddiv; - best_mask[0] = best_mask[1] = 0; - /* Initialize the sentinel node of the trellis. */ - tokens[eob][0].rate = 0; - tokens[eob][0].error = 0; - tokens[eob][0].next = 16; - tokens[eob][0].token = DCT_EOB_TOKEN; - tokens[eob][0].qc = 0; - *(tokens[eob] + 1) = *(tokens[eob] + 0); - next = eob; - for (i = eob; i-- > i0;) { - int base_bits; - int d2; - int dx; - - rc = vp8_default_zig_zag1d[i]; - x = qcoeff_ptr[rc]; - /* Only add a trellis state for non-zero coefficients. */ - if (x) { - int shortcut = 0; - error0 = tokens[next][0].error; - error1 = tokens[next][1].error; - /* Evaluate the first possibility for this state. */ - rate0 = tokens[next][0].rate; - rate1 = tokens[next][1].rate; - t0 = (vp8_dct_value_tokens_ptr + x)->Token; - /* Consider both possible successor states. */ - if (next < 16) { - band = vp8_coef_bands[i + 1]; - pt = vp8_prev_token_class[t0]; - rate0 += mb->token_costs[type][band][pt][tokens[next][0].token]; - rate1 += mb->token_costs[type][band][pt][tokens[next][1].token]; - } - rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0); - rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1); - if (rd_cost0 == rd_cost1) { - rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0); - rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1); - } - /* And pick the best. */ - best = rd_cost1 < rd_cost0; - base_bits = *(vp8_dct_value_cost_ptr + x); - dx = dqcoeff_ptr[rc] - coeff_ptr[rc]; - d2 = dx * dx; - tokens[i][0].rate = base_bits + (best ? rate1 : rate0); - tokens[i][0].error = d2 + (best ? error1 : error0); - tokens[i][0].next = next; - tokens[i][0].token = t0; - tokens[i][0].qc = x; - best_mask[0] |= best << i; - /* Evaluate the second possibility for this state. */ - rate0 = tokens[next][0].rate; - rate1 = tokens[next][1].rate; - - if ((abs(x) * dequant_ptr[rc] > abs(coeff_ptr[rc])) && - (abs(x) * dequant_ptr[rc] < abs(coeff_ptr[rc]) + dequant_ptr[rc])) { - shortcut = 1; - } else { - shortcut = 0; - } - - if (shortcut) { - sz = -(x < 0); - x -= 2 * sz + 1; - } - - /* Consider both possible successor states. */ - if (!x) { - /* If we reduced this coefficient to zero, check to see if - * we need to move the EOB back here. - */ - t0 = - tokens[next][0].token == DCT_EOB_TOKEN ? DCT_EOB_TOKEN : ZERO_TOKEN; - t1 = - tokens[next][1].token == DCT_EOB_TOKEN ? DCT_EOB_TOKEN : ZERO_TOKEN; - } else { - t0 = t1 = (vp8_dct_value_tokens_ptr + x)->Token; - } - if (next < 16) { - band = vp8_coef_bands[i + 1]; - if (t0 != DCT_EOB_TOKEN) { - pt = vp8_prev_token_class[t0]; - rate0 += mb->token_costs[type][band][pt][tokens[next][0].token]; - } - if (t1 != DCT_EOB_TOKEN) { - pt = vp8_prev_token_class[t1]; - rate1 += mb->token_costs[type][band][pt][tokens[next][1].token]; - } - } - - rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0); - rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1); - if (rd_cost0 == rd_cost1) { - rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0); - rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1); - } - /* And pick the best. */ - best = rd_cost1 < rd_cost0; - base_bits = *(vp8_dct_value_cost_ptr + x); - - if (shortcut) { - dx -= (dequant_ptr[rc] + sz) ^ sz; - d2 = dx * dx; - } - tokens[i][1].rate = base_bits + (best ? rate1 : rate0); - tokens[i][1].error = d2 + (best ? error1 : error0); - tokens[i][1].next = next; - tokens[i][1].token = best ? t1 : t0; - tokens[i][1].qc = x; - best_mask[1] |= best << i; - /* Finally, make this the new head of the trellis. */ - next = i; - } - /* There's no choice to make for a zero coefficient, so we don't - * add a new trellis node, but we do need to update the costs. - */ - else { - band = vp8_coef_bands[i + 1]; - t0 = tokens[next][0].token; - t1 = tokens[next][1].token; - /* Update the cost of each path if we're past the EOB token. */ - if (t0 != DCT_EOB_TOKEN) { - tokens[next][0].rate += mb->token_costs[type][band][0][t0]; - tokens[next][0].token = ZERO_TOKEN; - } - if (t1 != DCT_EOB_TOKEN) { - tokens[next][1].rate += mb->token_costs[type][band][0][t1]; - tokens[next][1].token = ZERO_TOKEN; - } - /* Don't update next, because we didn't add a new node. */ - } - } - - /* Now pick the best path through the whole trellis. */ - band = vp8_coef_bands[i + 1]; - VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); - rate0 = tokens[next][0].rate; - rate1 = tokens[next][1].rate; - error0 = tokens[next][0].error; - error1 = tokens[next][1].error; - t0 = tokens[next][0].token; - t1 = tokens[next][1].token; - rate0 += mb->token_costs[type][band][pt][t0]; - rate1 += mb->token_costs[type][band][pt][t1]; - rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0); - rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1); - if (rd_cost0 == rd_cost1) { - rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0); - rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1); - } - best = rd_cost1 < rd_cost0; - final_eob = i0 - 1; - for (i = next; i < eob; i = next) { - x = tokens[i][best].qc; - if (x) final_eob = i; - rc = vp8_default_zig_zag1d[i]; - qcoeff_ptr[rc] = x; - dqcoeff_ptr[rc] = x * dequant_ptr[rc]; - next = tokens[i][best].next; - best = (best_mask[best] >> i) & 1; - } - final_eob++; - - *a = *l = (final_eob != !type); - *d->eob = (char)final_eob; -} -static void check_reset_2nd_coeffs(MACROBLOCKD *x, int type, ENTROPY_CONTEXT *a, - ENTROPY_CONTEXT *l) { - int sum = 0; - int i; - BLOCKD *bd = &x->block[24]; - - if (bd->dequant[0] >= 35 && bd->dequant[1] >= 35) return; - - for (i = 0; i < (*bd->eob); ++i) { - int coef = bd->dqcoeff[vp8_default_zig_zag1d[i]]; - sum += (coef >= 0) ? coef : -coef; - if (sum >= 35) return; - } - /************************************************************************** - our inverse hadamard transform effectively is weighted sum of all 16 inputs - with weight either 1 or -1. It has a last stage scaling of (sum+3)>>3. And - dc only idct is (dc+4)>>3. So if all the sums are between -35 and 29, the - output after inverse wht and idct will be all zero. A sum of absolute value - smaller than 35 guarantees all 16 different (+1/-1) weighted sums in wht - fall between -35 and +35. - **************************************************************************/ - if (sum < 35) { - for (i = 0; i < (*bd->eob); ++i) { - int rc = vp8_default_zig_zag1d[i]; - bd->qcoeff[rc] = 0; - bd->dqcoeff[rc] = 0; - } - *bd->eob = 0; - *a = *l = (*bd->eob != !type); - } -} - -static void optimize_mb(MACROBLOCK *x) { - int b; - int type; - int has_2nd_order; - - ENTROPY_CONTEXT_PLANES t_above, t_left; - ENTROPY_CONTEXT *ta; - ENTROPY_CONTEXT *tl; - - memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES)); - memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES)); - - ta = (ENTROPY_CONTEXT *)&t_above; - tl = (ENTROPY_CONTEXT *)&t_left; - - has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED && - x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); - type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC; - - for (b = 0; b < 16; ++b) { - optimize_b(x, b, type, ta + vp8_block2above[b], tl + vp8_block2left[b]); - } - - for (b = 16; b < 24; ++b) { - optimize_b(x, b, PLANE_TYPE_UV, ta + vp8_block2above[b], - tl + vp8_block2left[b]); - } - - if (has_2nd_order) { - b = 24; - optimize_b(x, b, PLANE_TYPE_Y2, ta + vp8_block2above[b], - tl + vp8_block2left[b]); - check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2, ta + vp8_block2above[b], - tl + vp8_block2left[b]); - } -} - -void vp8_optimize_mby(MACROBLOCK *x) { - int b; - int type; - int has_2nd_order; - - ENTROPY_CONTEXT_PLANES t_above, t_left; - ENTROPY_CONTEXT *ta; - ENTROPY_CONTEXT *tl; - - if (!x->e_mbd.above_context) return; - - if (!x->e_mbd.left_context) return; - - memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES)); - memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES)); - - ta = (ENTROPY_CONTEXT *)&t_above; - tl = (ENTROPY_CONTEXT *)&t_left; - - has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED && - x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); - type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC; - - for (b = 0; b < 16; ++b) { - optimize_b(x, b, type, ta + vp8_block2above[b], tl + vp8_block2left[b]); - } - - if (has_2nd_order) { - b = 24; - optimize_b(x, b, PLANE_TYPE_Y2, ta + vp8_block2above[b], - tl + vp8_block2left[b]); - check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2, ta + vp8_block2above[b], - tl + vp8_block2left[b]); - } -} - -void vp8_optimize_mbuv(MACROBLOCK *x) { - int b; - ENTROPY_CONTEXT_PLANES t_above, t_left; - ENTROPY_CONTEXT *ta; - ENTROPY_CONTEXT *tl; - - if (!x->e_mbd.above_context) return; - - if (!x->e_mbd.left_context) return; - - memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES)); - memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES)); - - ta = (ENTROPY_CONTEXT *)&t_above; - tl = (ENTROPY_CONTEXT *)&t_left; - - for (b = 16; b < 24; ++b) { - optimize_b(x, b, PLANE_TYPE_UV, ta + vp8_block2above[b], - tl + vp8_block2left[b]); - } -} - -void vp8_encode_inter16x16(MACROBLOCK *x) { - vp8_build_inter_predictors_mb(&x->e_mbd); - - vp8_subtract_mb(x); - - transform_mb(x); - - vp8_quantize_mb(x); - - if (x->optimize) optimize_mb(x); -} - -/* this funciton is used by first pass only */ -void vp8_encode_inter16x16y(MACROBLOCK *x) { - BLOCK *b = &x->block[0]; - - vp8_build_inter16x16_predictors_mby(&x->e_mbd, x->e_mbd.dst.y_buffer, - x->e_mbd.dst.y_stride); - - vp8_subtract_mby(x->src_diff, *(b->base_src), b->src_stride, - x->e_mbd.dst.y_buffer, x->e_mbd.dst.y_stride); - - transform_mby(x); - - vp8_quantize_mby(x); - - vp8_inverse_transform_mby(&x->e_mbd); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodemb.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodemb.h deleted file mode 100644 index db577ddc..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodemb.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_ENCODEMB_H_ -#define VPX_VP8_ENCODER_ENCODEMB_H_ - -#include "onyx_int.h" - -#ifdef __cplusplus -extern "C" { -#endif -void vp8_encode_inter16x16(MACROBLOCK *x); - -void vp8_subtract_b(BLOCK *be, BLOCKD *bd, int pitch); -void vp8_subtract_mbuv(short *diff, unsigned char *usrc, unsigned char *vsrc, - int src_stride, unsigned char *upred, - unsigned char *vpred, int pred_stride); -void vp8_subtract_mby(short *diff, unsigned char *src, int src_stride, - unsigned char *pred, int pred_stride); - -void vp8_build_dcblock(MACROBLOCK *b); -void vp8_transform_mb(MACROBLOCK *mb); -void vp8_transform_mbuv(MACROBLOCK *x); -void vp8_transform_intra_mby(MACROBLOCK *x); - -void vp8_optimize_mby(MACROBLOCK *x); -void vp8_optimize_mbuv(MACROBLOCK *x); -void vp8_encode_inter16x16y(MACROBLOCK *x); -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_ENCODEMB_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodemv.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodemv.c deleted file mode 100644 index 384bb293..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodemv.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp8/common/common.h" -#include "encodemv.h" -#include "vp8/common/entropymode.h" -#include "vp8/common/systemdependent.h" -#include "vpx_ports/system_state.h" - -#include - -static void encode_mvcomponent(vp8_writer *const w, const int v, - const struct mv_context *mvc) { - const vp8_prob *p = mvc->prob; - const int x = v < 0 ? -v : v; - - if (x < mvnum_short) { /* Small */ - vp8_write(w, 0, p[mvpis_short]); - vp8_treed_write(w, vp8_small_mvtree, p + MVPshort, x, 3); - - if (!x) return; /* no sign bit */ - } else { /* Large */ - int i = 0; - - vp8_write(w, 1, p[mvpis_short]); - - do { - vp8_write(w, (x >> i) & 1, p[MVPbits + i]); - } while (++i < 3); - - i = mvlong_width - 1; /* Skip bit 3, which is sometimes implicit */ - - do { - vp8_write(w, (x >> i) & 1, p[MVPbits + i]); - } while (--i > 3); - - if (x & 0xFFF0) vp8_write(w, (x >> 3) & 1, p[MVPbits + 3]); - } - - vp8_write(w, v < 0, p[MVPsign]); -} -#if 0 -static int max_mv_r = 0; -static int max_mv_c = 0; -#endif -void vp8_encode_motion_vector(vp8_writer *w, const MV *mv, - const MV_CONTEXT *mvc) { -#if 0 - { - if (abs(mv->row >> 1) > max_mv_r) - { - FILE *f = fopen("maxmv.stt", "a"); - max_mv_r = abs(mv->row >> 1); - fprintf(f, "New Mv Row Max %6d\n", (mv->row >> 1)); - - if ((abs(mv->row) / 2) != max_mv_r) - fprintf(f, "MV Row conversion error %6d\n", abs(mv->row) / 2); - - fclose(f); - } - - if (abs(mv->col >> 1) > max_mv_c) - { - FILE *f = fopen("maxmv.stt", "a"); - fprintf(f, "New Mv Col Max %6d\n", (mv->col >> 1)); - max_mv_c = abs(mv->col >> 1); - fclose(f); - } - } -#endif - - encode_mvcomponent(w, mv->row >> 1, &mvc[0]); - encode_mvcomponent(w, mv->col >> 1, &mvc[1]); -} - -static unsigned int cost_mvcomponent(const int v, - const struct mv_context *mvc) { - const vp8_prob *p = mvc->prob; - const int x = v; - unsigned int cost; - - if (x < mvnum_short) { - cost = vp8_cost_zero(p[mvpis_short]) + - vp8_treed_cost(vp8_small_mvtree, p + MVPshort, x, 3); - - if (!x) return cost; - } else { - int i = 0; - cost = vp8_cost_one(p[mvpis_short]); - - do { - cost += vp8_cost_bit(p[MVPbits + i], (x >> i) & 1); - - } while (++i < 3); - - i = mvlong_width - 1; /* Skip bit 3, which is sometimes implicit */ - - do { - cost += vp8_cost_bit(p[MVPbits + i], (x >> i) & 1); - - } while (--i > 3); - - if (x & 0xFFF0) cost += vp8_cost_bit(p[MVPbits + 3], (x >> 3) & 1); - } - - return cost; /* + vp8_cost_bit( p [MVPsign], v < 0); */ -} - -void vp8_build_component_cost_table(int *mvcost[2], const MV_CONTEXT *mvc, - int mvc_flag[2]) { - int i = 1; - unsigned int cost0 = 0; - unsigned int cost1 = 0; - - vpx_clear_system_state(); - - i = 1; - - if (mvc_flag[0]) { - mvcost[0][0] = cost_mvcomponent(0, &mvc[0]); - - do { - cost0 = cost_mvcomponent(i, &mvc[0]); - - mvcost[0][i] = cost0 + vp8_cost_zero(mvc[0].prob[MVPsign]); - mvcost[0][-i] = cost0 + vp8_cost_one(mvc[0].prob[MVPsign]); - } while (++i <= mv_max); - } - - i = 1; - - if (mvc_flag[1]) { - mvcost[1][0] = cost_mvcomponent(0, &mvc[1]); - - do { - cost1 = cost_mvcomponent(i, &mvc[1]); - - mvcost[1][i] = cost1 + vp8_cost_zero(mvc[1].prob[MVPsign]); - mvcost[1][-i] = cost1 + vp8_cost_one(mvc[1].prob[MVPsign]); - } while (++i <= mv_max); - } -} - -/* Motion vector probability table update depends on benefit. - * Small correction allows for the fact that an update to an MV probability - * may have benefit in subsequent frames as well as the current one. - */ -#define MV_PROB_UPDATE_CORRECTION -1 - -static void calc_prob(vp8_prob *p, const unsigned int ct[2]) { - const unsigned int tot = ct[0] + ct[1]; - - if (tot) { - const vp8_prob x = ((ct[0] * 255) / tot) & ~1u; - *p = x ? x : 1; - } -} - -static void update(vp8_writer *const w, const unsigned int ct[2], - vp8_prob *const cur_p, const vp8_prob new_p, - const vp8_prob update_p, int *updated) { - const int cur_b = vp8_cost_branch(ct, *cur_p); - const int new_b = vp8_cost_branch(ct, new_p); - const int cost = - 7 + MV_PROB_UPDATE_CORRECTION + - ((vp8_cost_one(update_p) - vp8_cost_zero(update_p) + 128) >> 8); - - if (cur_b - new_b > cost) { - *cur_p = new_p; - vp8_write(w, 1, update_p); - vp8_write_literal(w, new_p >> 1, 7); - *updated = 1; - - } else - vp8_write(w, 0, update_p); -} - -static void write_component_probs(vp8_writer *const w, - struct mv_context *cur_mvc, - const struct mv_context *default_mvc_, - const struct mv_context *update_mvc, - const unsigned int events[MVvals], - unsigned int rc, int *updated) { - vp8_prob *Pcur = cur_mvc->prob; - const vp8_prob *default_mvc = default_mvc_->prob; - const vp8_prob *Pupdate = update_mvc->prob; - unsigned int is_short_ct[2], sign_ct[2]; - - unsigned int bit_ct[mvlong_width][2]; - - unsigned int short_ct[mvnum_short]; - unsigned int short_bct[mvnum_short - 1][2]; - - vp8_prob Pnew[MVPcount]; - - (void)rc; - vp8_copy_array(Pnew, default_mvc, MVPcount); - - vp8_zero(is_short_ct); - vp8_zero(sign_ct); - vp8_zero(bit_ct); - vp8_zero(short_ct); - vp8_zero(short_bct); - - /* j=0 */ - { - const int c = events[mv_max]; - - is_short_ct[0] += c; /* Short vector */ - short_ct[0] += c; /* Magnitude distribution */ - } - - /* j: 1 ~ mv_max (1023) */ - { - int j = 1; - - do { - const int c1 = events[mv_max + j]; /* positive */ - const int c2 = events[mv_max - j]; /* negative */ - const int c = c1 + c2; - int a = j; - - sign_ct[0] += c1; - sign_ct[1] += c2; - - if (a < mvnum_short) { - is_short_ct[0] += c; /* Short vector */ - short_ct[a] += c; /* Magnitude distribution */ - } else { - int k = mvlong_width - 1; - is_short_ct[1] += c; /* Long vector */ - - /* bit 3 not always encoded. */ - do { - bit_ct[k][(a >> k) & 1] += c; - - } while (--k >= 0); - } - } while (++j <= mv_max); - } - - calc_prob(Pnew + mvpis_short, is_short_ct); - - calc_prob(Pnew + MVPsign, sign_ct); - - { - vp8_prob p[mvnum_short - 1]; /* actually only need branch ct */ - int j = 0; - - vp8_tree_probs_from_distribution(8, vp8_small_mvencodings, vp8_small_mvtree, - p, short_bct, short_ct, 256, 1); - - do { - calc_prob(Pnew + MVPshort + j, short_bct[j]); - - } while (++j < mvnum_short - 1); - } - - { - int j = 0; - - do { - calc_prob(Pnew + MVPbits + j, bit_ct[j]); - - } while (++j < mvlong_width); - } - - update(w, is_short_ct, Pcur + mvpis_short, Pnew[mvpis_short], *Pupdate++, - updated); - - update(w, sign_ct, Pcur + MVPsign, Pnew[MVPsign], *Pupdate++, updated); - - { - const vp8_prob *const new_p = Pnew + MVPshort; - vp8_prob *const cur_p = Pcur + MVPshort; - - int j = 0; - - do { - update(w, short_bct[j], cur_p + j, new_p[j], *Pupdate++, updated); - - } while (++j < mvnum_short - 1); - } - - { - const vp8_prob *const new_p = Pnew + MVPbits; - vp8_prob *const cur_p = Pcur + MVPbits; - - int j = 0; - - do { - update(w, bit_ct[j], cur_p + j, new_p[j], *Pupdate++, updated); - - } while (++j < mvlong_width); - } -} - -void vp8_write_mvprobs(VP8_COMP *cpi) { - vp8_writer *const w = cpi->bc; - MV_CONTEXT *mvc = cpi->common.fc.mvc; - int flags[2] = { 0, 0 }; - write_component_probs(w, &mvc[0], &vp8_default_mv_context[0], - &vp8_mv_update_probs[0], cpi->mb.MVcount[0], 0, - &flags[0]); - write_component_probs(w, &mvc[1], &vp8_default_mv_context[1], - &vp8_mv_update_probs[1], cpi->mb.MVcount[1], 1, - &flags[1]); - - if (flags[0] || flags[1]) { - vp8_build_component_cost_table( - cpi->mb.mvcost, (const MV_CONTEXT *)cpi->common.fc.mvc, flags); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodemv.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodemv.h deleted file mode 100644 index 347b9fef..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/encodemv.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_ENCODEMV_H_ -#define VPX_VP8_ENCODER_ENCODEMV_H_ - -#include "onyx_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vp8_write_mvprobs(VP8_COMP *); -void vp8_encode_motion_vector(vp8_writer *, const MV *, const MV_CONTEXT *); -void vp8_build_component_cost_table(int *mvcost[2], const MV_CONTEXT *mvc, - int mvc_flag[2]); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_ENCODEMV_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/ethreading.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/ethreading.c deleted file mode 100644 index 98c87d3c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/ethreading.c +++ /dev/null @@ -1,665 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include - -#include "onyx_int.h" -#include "vpx_util/vpx_pthread.h" -#include "vp8/common/threading.h" -#include "vp8/common/common.h" -#include "vp8/common/extend.h" -#include "bitstream.h" -#include "encodeframe.h" -#include "ethreading.h" - -#if CONFIG_MULTITHREAD - -extern void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x, - int ok_to_skip); - -static THREADFN thread_loopfilter(void *p_data) { - VP8_COMP *cpi = (VP8_COMP *)(((LPFTHREAD_DATA *)p_data)->ptr1); - VP8_COMMON *cm = &cpi->common; - - while (1) { - if (vpx_atomic_load_acquire(&cpi->b_multi_threaded) == 0) break; - - if (vp8_sem_wait(&cpi->h_event_start_lpf) == 0) { - /* we're shutting down */ - if (vpx_atomic_load_acquire(&cpi->b_multi_threaded) == 0) break; - - vp8_loopfilter_frame(cpi, cm); - - vp8_sem_post(&cpi->h_event_end_lpf); - } - } - - return THREAD_EXIT_SUCCESS; -} - -static THREADFN thread_encoding_proc(void *p_data) { - int ithread = ((ENCODETHREAD_DATA *)p_data)->ithread; - VP8_COMP *cpi = (VP8_COMP *)(((ENCODETHREAD_DATA *)p_data)->ptr1); - MB_ROW_COMP *mbri = (MB_ROW_COMP *)(((ENCODETHREAD_DATA *)p_data)->ptr2); - ENTROPY_CONTEXT_PLANES mb_row_left_context; - - while (1) { - if (vpx_atomic_load_acquire(&cpi->b_multi_threaded) == 0) break; - - if (vp8_sem_wait(&cpi->h_event_start_encoding[ithread]) == 0) { - const int nsync = cpi->mt_sync_range; - VP8_COMMON *cm = &cpi->common; - int mb_row; - MACROBLOCK *x = &mbri->mb; - MACROBLOCKD *xd = &x->e_mbd; - TOKENEXTRA *tp; -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING - TOKENEXTRA *tp_start = cpi->tok + (1 + ithread) * (16 * 24); - const int num_part = (1 << cm->multi_token_partition); -#endif - - int *segment_counts = mbri->segment_counts; - int *totalrate = &mbri->totalrate; - - /* we're shutting down */ - if (vpx_atomic_load_acquire(&cpi->b_multi_threaded) == 0) break; - - xd->mode_info_context = cm->mi + cm->mode_info_stride * (ithread + 1); - xd->mode_info_stride = cm->mode_info_stride; - - for (mb_row = ithread + 1; mb_row < cm->mb_rows; - mb_row += (cpi->encoding_thread_count + 1)) { - int recon_yoffset, recon_uvoffset; - int mb_col; - int ref_fb_idx = cm->lst_fb_idx; - int dst_fb_idx = cm->new_fb_idx; - int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride; - int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride; - int map_index = (mb_row * cm->mb_cols); - const vpx_atomic_int *last_row_current_mb_col; - vpx_atomic_int *current_mb_col = &cpi->mt_current_mb_col[mb_row]; - -#if (CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING) - vp8_writer *w = &cpi->bc[1 + (mb_row % num_part)]; -#else - tp = cpi->tok + (mb_row * (cm->mb_cols * 16 * 24)); - cpi->tplist[mb_row].start = tp; -#endif - - last_row_current_mb_col = &cpi->mt_current_mb_col[mb_row - 1]; - - /* reset above block coeffs */ - xd->above_context = cm->above_context; - xd->left_context = &mb_row_left_context; - - vp8_zero(mb_row_left_context); - - xd->up_available = (mb_row != 0); - recon_yoffset = (mb_row * recon_y_stride * 16); - recon_uvoffset = (mb_row * recon_uv_stride * 8); - - /* Set the mb activity pointer to the start of the row. */ - x->mb_activity_ptr = &cpi->mb_activity_map[map_index]; - - /* for each macroblock col in image */ - for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) { - if (((mb_col - 1) % nsync) == 0) { - vpx_atomic_store_release(current_mb_col, mb_col - 1); - } - - if (mb_row && !(mb_col & (nsync - 1))) { - vp8_atomic_spin_wait(mb_col, last_row_current_mb_col, nsync); - } - -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING - tp = tp_start; -#endif - - /* Distance of Mb to the various image edges. - * These specified to 8th pel as they are always compared - * to values that are in 1/8th pel units - */ - xd->mb_to_left_edge = -((mb_col * 16) << 3); - xd->mb_to_right_edge = ((cm->mb_cols - 1 - mb_col) * 16) << 3; - xd->mb_to_top_edge = -((mb_row * 16) << 3); - xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3; - - /* Set up limit values for motion vectors used to prevent - * them extending outside the UMV borders - */ - x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16)); - x->mv_col_max = - ((cm->mb_cols - 1 - mb_col) * 16) + (VP8BORDERINPIXELS - 16); - x->mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 16)); - x->mv_row_max = - ((cm->mb_rows - 1 - mb_row) * 16) + (VP8BORDERINPIXELS - 16); - - xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset; - xd->dst.u_buffer = cm->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset; - xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset; - xd->left_available = (mb_col != 0); - - x->rddiv = cpi->RDDIV; - x->rdmult = cpi->RDMULT; - - /* Copy current mb to a buffer */ - vp8_copy_mem16x16(x->src.y_buffer, x->src.y_stride, x->thismb, 16); - - if (cpi->oxcf.tuning == VP8_TUNE_SSIM) vp8_activity_masking(cpi, x); - - /* Is segmentation enabled */ - /* MB level adjustment to quantizer */ - if (xd->segmentation_enabled) { - /* Code to set segment id in xd->mbmi.segment_id for - * current MB (with range checking) - */ - if (cpi->segmentation_map[map_index + mb_col] <= 3) { - xd->mode_info_context->mbmi.segment_id = - cpi->segmentation_map[map_index + mb_col]; - } else { - xd->mode_info_context->mbmi.segment_id = 0; - } - - vp8cx_mb_init_quantizer(cpi, x, 1); - } else { - /* Set to Segment 0 by default */ - xd->mode_info_context->mbmi.segment_id = 0; - } - - x->active_ptr = cpi->active_map + map_index + mb_col; - - if (cm->frame_type == KEY_FRAME) { - *totalrate += vp8cx_encode_intra_macroblock(cpi, x, &tp); -#ifdef MODE_STATS - y_modes[xd->mbmi.mode]++; -#endif - } else { - *totalrate += vp8cx_encode_inter_macroblock( - cpi, x, &tp, recon_yoffset, recon_uvoffset, mb_row, mb_col); - -#ifdef MODE_STATS - inter_y_modes[xd->mbmi.mode]++; - - if (xd->mbmi.mode == SPLITMV) { - int b; - - for (b = 0; b < xd->mbmi.partition_count; ++b) { - inter_b_modes[x->partition->bmi[b].mode]++; - } - } - -#endif - // Keep track of how many (consecutive) times a block - // is coded as ZEROMV_LASTREF, for base layer frames. - // Reset to 0 if its coded as anything else. - if (cpi->current_layer == 0) { - if (xd->mode_info_context->mbmi.mode == ZEROMV && - xd->mode_info_context->mbmi.ref_frame == LAST_FRAME) { - // Increment, check for wrap-around. - if (cpi->consec_zero_last[map_index + mb_col] < 255) { - cpi->consec_zero_last[map_index + mb_col] += 1; - } - if (cpi->consec_zero_last_mvbias[map_index + mb_col] < 255) { - cpi->consec_zero_last_mvbias[map_index + mb_col] += 1; - } - } else { - cpi->consec_zero_last[map_index + mb_col] = 0; - cpi->consec_zero_last_mvbias[map_index + mb_col] = 0; - } - if (x->zero_last_dot_suppress) { - cpi->consec_zero_last_mvbias[map_index + mb_col] = 0; - } - } - - /* Special case code for cyclic refresh - * If cyclic update enabled then copy - * xd->mbmi.segment_id; (which may have been updated - * based on mode during - * vp8cx_encode_inter_macroblock()) back into the - * global segmentation map - */ - if ((cpi->current_layer == 0) && - (cpi->cyclic_refresh_mode_enabled && - xd->segmentation_enabled)) { - const MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi; - cpi->segmentation_map[map_index + mb_col] = mbmi->segment_id; - - /* If the block has been refreshed mark it as clean - * (the magnitude of the -ve influences how long it - * will be before we consider another refresh): - * Else if it was coded (last frame 0,0) and has - * not already been refreshed then mark it as a - * candidate for cleanup next time (marked 0) else - * mark it as dirty (1). - */ - if (mbmi->segment_id) { - cpi->cyclic_refresh_map[map_index + mb_col] = -1; - } else if ((mbmi->mode == ZEROMV) && - (mbmi->ref_frame == LAST_FRAME)) { - if (cpi->cyclic_refresh_map[map_index + mb_col] == 1) { - cpi->cyclic_refresh_map[map_index + mb_col] = 0; - } - } else { - cpi->cyclic_refresh_map[map_index + mb_col] = 1; - } - } - } - -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING - /* pack tokens for this MB */ - { - int tok_count = tp - tp_start; - vp8_pack_tokens(w, tp_start, tok_count); - } -#else - cpi->tplist[mb_row].stop = tp; -#endif - /* Increment pointer into gf usage flags structure. */ - x->gf_active_ptr++; - - /* Increment the activity mask pointers. */ - x->mb_activity_ptr++; - - /* adjust to the next column of macroblocks */ - x->src.y_buffer += 16; - x->src.u_buffer += 8; - x->src.v_buffer += 8; - - recon_yoffset += 16; - recon_uvoffset += 8; - - /* Keep track of segment usage */ - segment_counts[xd->mode_info_context->mbmi.segment_id]++; - - /* skip to next mb */ - xd->mode_info_context++; - x->partition_info++; - xd->above_context++; - } - - vp8_extend_mb_row(&cm->yv12_fb[dst_fb_idx], xd->dst.y_buffer + 16, - xd->dst.u_buffer + 8, xd->dst.v_buffer + 8); - - vpx_atomic_store_release(current_mb_col, mb_col + nsync); - - /* this is to account for the border */ - xd->mode_info_context++; - x->partition_info++; - - x->src.y_buffer += - 16 * x->src.y_stride * (cpi->encoding_thread_count + 1) - - 16 * cm->mb_cols; - x->src.u_buffer += - 8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - - 8 * cm->mb_cols; - x->src.v_buffer += - 8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - - 8 * cm->mb_cols; - - xd->mode_info_context += - xd->mode_info_stride * cpi->encoding_thread_count; - x->partition_info += xd->mode_info_stride * cpi->encoding_thread_count; - x->gf_active_ptr += cm->mb_cols * cpi->encoding_thread_count; - } - /* Signal that this thread has completed processing its rows. */ - vp8_sem_post(&cpi->h_event_end_encoding[ithread]); - } - } - - /* printf("exit thread %d\n", ithread); */ - return THREAD_EXIT_SUCCESS; -} - -static void setup_mbby_copy(MACROBLOCK *mbdst, MACROBLOCK *mbsrc) { - MACROBLOCK *x = mbsrc; - MACROBLOCK *z = mbdst; - int i; - - z->ss = x->ss; - z->ss_count = x->ss_count; - z->searches_per_step = x->searches_per_step; - z->errorperbit = x->errorperbit; - - z->sadperbit16 = x->sadperbit16; - z->sadperbit4 = x->sadperbit4; - - /* - z->mv_col_min = x->mv_col_min; - z->mv_col_max = x->mv_col_max; - z->mv_row_min = x->mv_row_min; - z->mv_row_max = x->mv_row_max; - */ - - z->short_fdct4x4 = x->short_fdct4x4; - z->short_fdct8x4 = x->short_fdct8x4; - z->short_walsh4x4 = x->short_walsh4x4; - z->quantize_b = x->quantize_b; - z->optimize = x->optimize; - - /* - z->mvc = x->mvc; - z->src.y_buffer = x->src.y_buffer; - z->src.u_buffer = x->src.u_buffer; - z->src.v_buffer = x->src.v_buffer; - */ - - z->mvcost[0] = x->mvcost[0]; - z->mvcost[1] = x->mvcost[1]; - z->mvsadcost[0] = x->mvsadcost[0]; - z->mvsadcost[1] = x->mvsadcost[1]; - - z->token_costs = x->token_costs; - z->inter_bmode_costs = x->inter_bmode_costs; - z->mbmode_cost = x->mbmode_cost; - z->intra_uv_mode_cost = x->intra_uv_mode_cost; - z->bmode_costs = x->bmode_costs; - - for (i = 0; i < 25; ++i) { - z->block[i].quant = x->block[i].quant; - z->block[i].quant_fast = x->block[i].quant_fast; - z->block[i].quant_shift = x->block[i].quant_shift; - z->block[i].zbin = x->block[i].zbin; - z->block[i].zrun_zbin_boost = x->block[i].zrun_zbin_boost; - z->block[i].round = x->block[i].round; - z->block[i].src_stride = x->block[i].src_stride; - } - - z->q_index = x->q_index; - z->act_zbin_adj = x->act_zbin_adj; - z->last_act_zbin_adj = x->last_act_zbin_adj; - - { - MACROBLOCKD *xd = &x->e_mbd; - MACROBLOCKD *zd = &z->e_mbd; - - /* - zd->mode_info_context = xd->mode_info_context; - zd->mode_info = xd->mode_info; - - zd->mode_info_stride = xd->mode_info_stride; - zd->frame_type = xd->frame_type; - zd->up_available = xd->up_available ; - zd->left_available = xd->left_available; - zd->left_context = xd->left_context; - zd->last_frame_dc = xd->last_frame_dc; - zd->last_frame_dccons = xd->last_frame_dccons; - zd->gold_frame_dc = xd->gold_frame_dc; - zd->gold_frame_dccons = xd->gold_frame_dccons; - zd->mb_to_left_edge = xd->mb_to_left_edge; - zd->mb_to_right_edge = xd->mb_to_right_edge; - zd->mb_to_top_edge = xd->mb_to_top_edge ; - zd->mb_to_bottom_edge = xd->mb_to_bottom_edge; - zd->gf_active_ptr = xd->gf_active_ptr; - zd->frames_since_golden = xd->frames_since_golden; - zd->frames_till_alt_ref_frame = xd->frames_till_alt_ref_frame; - */ - zd->subpixel_predict = xd->subpixel_predict; - zd->subpixel_predict8x4 = xd->subpixel_predict8x4; - zd->subpixel_predict8x8 = xd->subpixel_predict8x8; - zd->subpixel_predict16x16 = xd->subpixel_predict16x16; - zd->segmentation_enabled = xd->segmentation_enabled; - zd->mb_segment_abs_delta = xd->mb_segment_abs_delta; - memcpy(zd->segment_feature_data, xd->segment_feature_data, - sizeof(xd->segment_feature_data)); - - memcpy(zd->dequant_y1_dc, xd->dequant_y1_dc, sizeof(xd->dequant_y1_dc)); - memcpy(zd->dequant_y1, xd->dequant_y1, sizeof(xd->dequant_y1)); - memcpy(zd->dequant_y2, xd->dequant_y2, sizeof(xd->dequant_y2)); - memcpy(zd->dequant_uv, xd->dequant_uv, sizeof(xd->dequant_uv)); - -#if 1 - /*TODO: Remove dequant from BLOCKD. This is a temporary solution until - * the quantizer code uses a passed in pointer to the dequant constants. - * This will also require modifications to the x86 and neon assembly. - * */ - for (i = 0; i < 16; ++i) zd->block[i].dequant = zd->dequant_y1; - for (i = 16; i < 24; ++i) zd->block[i].dequant = zd->dequant_uv; - zd->block[24].dequant = zd->dequant_y2; -#endif - - memcpy(z->rd_threshes, x->rd_threshes, sizeof(x->rd_threshes)); - memcpy(z->rd_thresh_mult, x->rd_thresh_mult, sizeof(x->rd_thresh_mult)); - - z->zbin_over_quant = x->zbin_over_quant; - z->zbin_mode_boost_enabled = x->zbin_mode_boost_enabled; - z->zbin_mode_boost = x->zbin_mode_boost; - - memset(z->error_bins, 0, sizeof(z->error_bins)); - } -} - -void vp8cx_init_mbrthread_data(VP8_COMP *cpi, MACROBLOCK *x, - MB_ROW_COMP *mbr_ei, int count) { - VP8_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &x->e_mbd; - int i; - - for (i = 0; i < count; ++i) { - MACROBLOCK *mb = &mbr_ei[i].mb; - MACROBLOCKD *mbd = &mb->e_mbd; - - mbd->subpixel_predict = xd->subpixel_predict; - mbd->subpixel_predict8x4 = xd->subpixel_predict8x4; - mbd->subpixel_predict8x8 = xd->subpixel_predict8x8; - mbd->subpixel_predict16x16 = xd->subpixel_predict16x16; - mb->gf_active_ptr = x->gf_active_ptr; - - memset(mbr_ei[i].segment_counts, 0, sizeof(mbr_ei[i].segment_counts)); - mbr_ei[i].totalrate = 0; - - mb->partition_info = x->pi + x->e_mbd.mode_info_stride * (i + 1); - - mbd->frame_type = cm->frame_type; - - mb->src = *cpi->Source; - mbd->pre = cm->yv12_fb[cm->lst_fb_idx]; - mbd->dst = cm->yv12_fb[cm->new_fb_idx]; - - mb->src.y_buffer += 16 * x->src.y_stride * (i + 1); - mb->src.u_buffer += 8 * x->src.uv_stride * (i + 1); - mb->src.v_buffer += 8 * x->src.uv_stride * (i + 1); - - vp8_build_block_offsets(mb); - - mbd->left_context = &cm->left_context; - mb->mvc = cm->fc.mvc; - - setup_mbby_copy(&mbr_ei[i].mb, x); - - mbd->fullpixel_mask = ~0; - if (cm->full_pixel) mbd->fullpixel_mask = ~7; - - vp8_zero(mb->coef_counts); - vp8_zero(x->ymode_count); - mb->skip_true_count = 0; - vp8_zero(mb->MVcount); - mb->prediction_error = 0; - mb->intra_error = 0; - vp8_zero(mb->count_mb_ref_frame_usage); - mb->mbs_tested_so_far = 0; - mb->mbs_zero_last_dot_suppress = 0; - } -} - -int vp8cx_create_encoder_threads(VP8_COMP *cpi) { - const VP8_COMMON *cm = &cpi->common; - int th_count = 0; - - if (cm->processor_core_count > 1 && cpi->oxcf.multi_threaded > 1) { - th_count = cpi->oxcf.multi_threaded - 1; - - /* don't allocate more threads than cores available */ - if (cpi->oxcf.multi_threaded > cm->processor_core_count) { - th_count = cm->processor_core_count - 1; - } - - /* we have th_count + 1 (main) threads processing one row each */ - /* no point to have more threads than the sync range allows */ - if (th_count > ((cm->mb_cols / cpi->mt_sync_range) - 1)) { - th_count = (cm->mb_cols / cpi->mt_sync_range) - 1; - } - } - if (th_count == cpi->encoding_thread_count) return 0; - - vp8cx_remove_encoder_threads(cpi); - if (th_count != 0) { - int ithread; - int rc = 0; - - CHECK_MEM_ERROR(&cpi->common.error, cpi->h_encoding_thread, - vpx_malloc(sizeof(pthread_t) * th_count)); - CHECK_MEM_ERROR(&cpi->common.error, cpi->h_event_start_encoding, - vpx_malloc(sizeof(vp8_sem_t) * th_count)); - CHECK_MEM_ERROR(&cpi->common.error, cpi->h_event_end_encoding, - vpx_malloc(sizeof(vp8_sem_t) * th_count)); - CHECK_MEM_ERROR(&cpi->common.error, cpi->mb_row_ei, - vpx_memalign(32, sizeof(MB_ROW_COMP) * th_count)); - memset(cpi->mb_row_ei, 0, sizeof(MB_ROW_COMP) * th_count); - CHECK_MEM_ERROR(&cpi->common.error, cpi->en_thread_data, - vpx_malloc(sizeof(ENCODETHREAD_DATA) * th_count)); - - vpx_atomic_store_release(&cpi->b_multi_threaded, 1); - cpi->encoding_thread_count = th_count; - - /* - printf("[VP8:] multi_threaded encoding is enabled with %d threads\n\n", - (cpi->encoding_thread_count +1)); - */ - - for (ithread = 0; ithread < th_count; ++ithread) { - ENCODETHREAD_DATA *ethd = &cpi->en_thread_data[ithread]; - - /* Setup block ptrs and offsets */ - vp8_setup_block_ptrs(&cpi->mb_row_ei[ithread].mb); - vp8_setup_block_dptrs(&cpi->mb_row_ei[ithread].mb.e_mbd); - - vp8_sem_init(&cpi->h_event_start_encoding[ithread], 0, 0); - vp8_sem_init(&cpi->h_event_end_encoding[ithread], 0, 0); - - ethd->ithread = ithread; - ethd->ptr1 = (void *)cpi; - ethd->ptr2 = (void *)&cpi->mb_row_ei[ithread]; - - rc = pthread_create(&cpi->h_encoding_thread[ithread], 0, - thread_encoding_proc, ethd); - if (rc) break; - } - - if (rc) { - /* shutdown other threads */ - vpx_atomic_store_release(&cpi->b_multi_threaded, 0); - for (--ithread; ithread >= 0; ithread--) { - vp8_sem_post(&cpi->h_event_start_encoding[ithread]); - vp8_sem_post(&cpi->h_event_end_encoding[ithread]); - pthread_join(cpi->h_encoding_thread[ithread], 0); - vp8_sem_destroy(&cpi->h_event_start_encoding[ithread]); - vp8_sem_destroy(&cpi->h_event_end_encoding[ithread]); - } - - /* free thread related resources */ - vpx_free(cpi->h_event_start_encoding); - cpi->h_event_start_encoding = NULL; - vpx_free(cpi->h_event_end_encoding); - cpi->h_event_end_encoding = NULL; - vpx_free(cpi->h_encoding_thread); - cpi->h_encoding_thread = NULL; - vpx_free(cpi->mb_row_ei); - cpi->mb_row_ei = NULL; - vpx_free(cpi->en_thread_data); - cpi->en_thread_data = NULL; - cpi->encoding_thread_count = 0; - - return -1; - } - - { - LPFTHREAD_DATA *lpfthd = &cpi->lpf_thread_data; - - vp8_sem_init(&cpi->h_event_start_lpf, 0, 0); - vp8_sem_init(&cpi->h_event_end_lpf, 0, 0); - - lpfthd->ptr1 = (void *)cpi; - rc = pthread_create(&cpi->h_filter_thread, 0, thread_loopfilter, lpfthd); - - if (rc) { - /* shutdown other threads */ - vpx_atomic_store_release(&cpi->b_multi_threaded, 0); - for (--ithread; ithread >= 0; ithread--) { - vp8_sem_post(&cpi->h_event_start_encoding[ithread]); - vp8_sem_post(&cpi->h_event_end_encoding[ithread]); - pthread_join(cpi->h_encoding_thread[ithread], 0); - vp8_sem_destroy(&cpi->h_event_start_encoding[ithread]); - vp8_sem_destroy(&cpi->h_event_end_encoding[ithread]); - } - vp8_sem_destroy(&cpi->h_event_end_lpf); - vp8_sem_destroy(&cpi->h_event_start_lpf); - - /* free thread related resources */ - vpx_free(cpi->h_event_start_encoding); - cpi->h_event_start_encoding = NULL; - vpx_free(cpi->h_event_end_encoding); - cpi->h_event_end_encoding = NULL; - vpx_free(cpi->h_encoding_thread); - cpi->h_encoding_thread = NULL; - vpx_free(cpi->mb_row_ei); - cpi->mb_row_ei = NULL; - vpx_free(cpi->en_thread_data); - cpi->en_thread_data = NULL; - cpi->encoding_thread_count = 0; - - return -2; - } - } - } - return 0; -} - -void vp8cx_remove_encoder_threads(VP8_COMP *cpi) { - if (vpx_atomic_load_acquire(&cpi->b_multi_threaded)) { - /* shutdown other threads */ - vpx_atomic_store_release(&cpi->b_multi_threaded, 0); - { - int i; - - for (i = 0; i < cpi->encoding_thread_count; ++i) { - vp8_sem_post(&cpi->h_event_start_encoding[i]); - vp8_sem_post(&cpi->h_event_end_encoding[i]); - - pthread_join(cpi->h_encoding_thread[i], 0); - - vp8_sem_destroy(&cpi->h_event_start_encoding[i]); - vp8_sem_destroy(&cpi->h_event_end_encoding[i]); - } - - vp8_sem_post(&cpi->h_event_start_lpf); - pthread_join(cpi->h_filter_thread, 0); - } - - vp8_sem_destroy(&cpi->h_event_end_lpf); - vp8_sem_destroy(&cpi->h_event_start_lpf); - cpi->b_lpf_running = 0; - - /* free thread related resources */ - vpx_free(cpi->mt_current_mb_col); - cpi->mt_current_mb_col = NULL; - cpi->mt_current_mb_col_size = 0; - vpx_free(cpi->h_event_start_encoding); - cpi->h_event_start_encoding = NULL; - vpx_free(cpi->h_event_end_encoding); - cpi->h_event_end_encoding = NULL; - vpx_free(cpi->h_encoding_thread); - cpi->h_encoding_thread = NULL; - vpx_free(cpi->mb_row_ei); - cpi->mb_row_ei = NULL; - vpx_free(cpi->en_thread_data); - cpi->en_thread_data = NULL; - cpi->encoding_thread_count = 0; - } -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/ethreading.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/ethreading.h deleted file mode 100644 index 598fe605..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/ethreading.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_ETHREADING_H_ -#define VPX_VP8_ENCODER_ETHREADING_H_ - -#include "vp8/encoder/onyx_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct VP8_COMP; -struct macroblock; - -void vp8cx_init_mbrthread_data(struct VP8_COMP *cpi, struct macroblock *x, - MB_ROW_COMP *mbr_ei, int count); -int vp8cx_create_encoder_threads(struct VP8_COMP *cpi); -void vp8cx_remove_encoder_threads(struct VP8_COMP *cpi); - -#ifdef __cplusplus -} -#endif - -#endif // VPX_VP8_ENCODER_ETHREADING_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/firstpass.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/firstpass.c deleted file mode 100644 index 8a3861e6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/firstpass.c +++ /dev/null @@ -1,3098 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "./vpx_scale_rtcd.h" -#include "block.h" -#include "onyx_int.h" -#include "vpx_dsp/variance.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "encodeintra.h" -#include "vp8/common/common.h" -#include "vp8/common/setupintrarecon.h" -#include "vp8/common/systemdependent.h" -#include "mcomp.h" -#include "firstpass.h" -#include "vpx_scale/vpx_scale.h" -#include "encodemb.h" -#include "vp8/common/extend.h" -#include "vpx_ports/system_state.h" -#include "vpx_mem/vpx_mem.h" -#include "vp8/common/swapyv12buffer.h" -#include "rdopt.h" -#include "vp8/common/quant_common.h" -#include "encodemv.h" -#include "encodeframe.h" - -#define OUTPUT_FPF 0 - -extern void vp8cx_frame_init_quantizer(VP8_COMP *cpi); - -#define GFQ_ADJUSTMENT vp8_gf_boost_qadjustment[Q] -extern int vp8_kf_boost_qadjustment[QINDEX_RANGE]; - -extern const int vp8_gf_boost_qadjustment[QINDEX_RANGE]; - -#define IIFACTOR 1.5 -#define IIKFACTOR1 1.40 -#define IIKFACTOR2 1.5 -#define RMAX 14.0 -#define GF_RMAX 48.0 - -#define KF_MB_INTRA_MIN 300 -#define GF_MB_INTRA_MIN 200 - -#define DOUBLE_DIVIDE_CHECK(X) ((X) < 0 ? (X)-.000001 : (X) + .000001) - -#define POW1 (double)cpi->oxcf.two_pass_vbrbias / 100.0 -#define POW2 (double)cpi->oxcf.two_pass_vbrbias / 100.0 - -#define NEW_BOOST 1 - -static int vscale_lookup[7] = { 0, 1, 1, 2, 2, 3, 3 }; -static int hscale_lookup[7] = { 0, 0, 1, 1, 2, 2, 3 }; - -static const int cq_level[QINDEX_RANGE] = { - 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, 11, - 11, 12, 13, 13, 14, 15, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 24, - 24, 25, 26, 27, 27, 28, 29, 30, 30, 31, 32, 33, 33, 34, 35, 36, 36, 37, 38, - 39, 39, 40, 41, 42, 42, 43, 44, 45, 46, 46, 47, 48, 49, 50, 50, 51, 52, 53, - 54, 55, 55, 56, 57, 58, 59, 60, 60, 61, 62, 63, 64, 65, 66, 67, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 -}; - -static void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame); - -/* Resets the first pass file to the given position using a relative seek - * from the current position - */ -static void reset_fpf_position(VP8_COMP *cpi, FIRSTPASS_STATS *Position) { - cpi->twopass.stats_in = Position; -} - -static int lookup_next_frame_stats(VP8_COMP *cpi, FIRSTPASS_STATS *next_frame) { - if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end) return EOF; - - *next_frame = *cpi->twopass.stats_in; - return 1; -} - -/* Read frame stats at an offset from the current position */ -static int read_frame_stats(VP8_COMP *cpi, FIRSTPASS_STATS *frame_stats, - int offset) { - FIRSTPASS_STATS *fps_ptr = cpi->twopass.stats_in; - - /* Check legality of offset */ - if (offset >= 0) { - if (&fps_ptr[offset] >= cpi->twopass.stats_in_end) return EOF; - } else if (offset < 0) { - if (&fps_ptr[offset] < cpi->twopass.stats_in_start) return EOF; - } - - *frame_stats = fps_ptr[offset]; - return 1; -} - -static int input_stats(VP8_COMP *cpi, FIRSTPASS_STATS *fps) { - if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end) return EOF; - - *fps = *cpi->twopass.stats_in; - cpi->twopass.stats_in = - (void *)((char *)cpi->twopass.stats_in + sizeof(FIRSTPASS_STATS)); - return 1; -} - -static void output_stats(struct vpx_codec_pkt_list *pktlist, - FIRSTPASS_STATS *stats) { - struct vpx_codec_cx_pkt pkt; - pkt.kind = VPX_CODEC_STATS_PKT; - pkt.data.twopass_stats.buf = stats; - pkt.data.twopass_stats.sz = sizeof(FIRSTPASS_STATS); - vpx_codec_pkt_list_add(pktlist, &pkt); - -/* TEMP debug code */ -#if OUTPUT_FPF - - { - FILE *fpfile; - fpfile = fopen("firstpass.stt", "a"); - - fprintf(fpfile, - "%12.0f %12.0f %12.0f %12.4f %12.4f %12.4f %12.4f" - " %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f" - " %12.0f %12.0f %12.4f\n", - stats->frame, stats->intra_error, stats->coded_error, - stats->ssim_weighted_pred_err, stats->pcnt_inter, - stats->pcnt_motion, stats->pcnt_second_ref, stats->pcnt_neutral, - stats->MVr, stats->mvr_abs, stats->MVc, stats->mvc_abs, stats->MVrv, - stats->MVcv, stats->mv_in_out_count, stats->new_mv_count, - stats->count, stats->duration); - fclose(fpfile); - } -#endif -} - -static void zero_stats(FIRSTPASS_STATS *section) { - section->frame = 0.0; - section->intra_error = 0.0; - section->coded_error = 0.0; - section->ssim_weighted_pred_err = 0.0; - section->pcnt_inter = 0.0; - section->pcnt_motion = 0.0; - section->pcnt_second_ref = 0.0; - section->pcnt_neutral = 0.0; - section->MVr = 0.0; - section->mvr_abs = 0.0; - section->MVc = 0.0; - section->mvc_abs = 0.0; - section->MVrv = 0.0; - section->MVcv = 0.0; - section->mv_in_out_count = 0.0; - section->new_mv_count = 0.0; - section->count = 0.0; - section->duration = 1.0; -} - -static void accumulate_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame) { - section->frame += frame->frame; - section->intra_error += frame->intra_error; - section->coded_error += frame->coded_error; - section->ssim_weighted_pred_err += frame->ssim_weighted_pred_err; - section->pcnt_inter += frame->pcnt_inter; - section->pcnt_motion += frame->pcnt_motion; - section->pcnt_second_ref += frame->pcnt_second_ref; - section->pcnt_neutral += frame->pcnt_neutral; - section->MVr += frame->MVr; - section->mvr_abs += frame->mvr_abs; - section->MVc += frame->MVc; - section->mvc_abs += frame->mvc_abs; - section->MVrv += frame->MVrv; - section->MVcv += frame->MVcv; - section->mv_in_out_count += frame->mv_in_out_count; - section->new_mv_count += frame->new_mv_count; - section->count += frame->count; - section->duration += frame->duration; -} - -static void subtract_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame) { - section->frame -= frame->frame; - section->intra_error -= frame->intra_error; - section->coded_error -= frame->coded_error; - section->ssim_weighted_pred_err -= frame->ssim_weighted_pred_err; - section->pcnt_inter -= frame->pcnt_inter; - section->pcnt_motion -= frame->pcnt_motion; - section->pcnt_second_ref -= frame->pcnt_second_ref; - section->pcnt_neutral -= frame->pcnt_neutral; - section->MVr -= frame->MVr; - section->mvr_abs -= frame->mvr_abs; - section->MVc -= frame->MVc; - section->mvc_abs -= frame->mvc_abs; - section->MVrv -= frame->MVrv; - section->MVcv -= frame->MVcv; - section->mv_in_out_count -= frame->mv_in_out_count; - section->new_mv_count -= frame->new_mv_count; - section->count -= frame->count; - section->duration -= frame->duration; -} - -static void avg_stats(FIRSTPASS_STATS *section) { - if (section->count < 1.0) return; - - section->intra_error /= section->count; - section->coded_error /= section->count; - section->ssim_weighted_pred_err /= section->count; - section->pcnt_inter /= section->count; - section->pcnt_second_ref /= section->count; - section->pcnt_neutral /= section->count; - section->pcnt_motion /= section->count; - section->MVr /= section->count; - section->mvr_abs /= section->count; - section->MVc /= section->count; - section->mvc_abs /= section->count; - section->MVrv /= section->count; - section->MVcv /= section->count; - section->mv_in_out_count /= section->count; - section->duration /= section->count; -} - -/* Calculate a modified Error used in distributing bits between easier - * and harder frames - */ -static double calculate_modified_err(VP8_COMP *cpi, - FIRSTPASS_STATS *this_frame) { - double av_err = (cpi->twopass.total_stats.ssim_weighted_pred_err / - cpi->twopass.total_stats.count); - double this_err = this_frame->ssim_weighted_pred_err; - double modified_err; - - if (this_err > av_err) { - modified_err = av_err * pow((this_err / DOUBLE_DIVIDE_CHECK(av_err)), POW1); - } else { - modified_err = av_err * pow((this_err / DOUBLE_DIVIDE_CHECK(av_err)), POW2); - } - - return modified_err; -} - -static const double weight_table[256] = { - 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, - 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, - 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, - 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, - 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.031250, 0.062500, - 0.093750, 0.125000, 0.156250, 0.187500, 0.218750, 0.250000, 0.281250, - 0.312500, 0.343750, 0.375000, 0.406250, 0.437500, 0.468750, 0.500000, - 0.531250, 0.562500, 0.593750, 0.625000, 0.656250, 0.687500, 0.718750, - 0.750000, 0.781250, 0.812500, 0.843750, 0.875000, 0.906250, 0.937500, - 0.968750, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, - 1.000000, 1.000000, 1.000000, 1.000000 -}; - -static double simple_weight(YV12_BUFFER_CONFIG *source) { - int i, j; - - unsigned char *src = source->y_buffer; - double sum_weights = 0.0; - - /* Loop throught the Y plane raw examining levels and creating a weight - * for the image - */ - i = source->y_height; - do { - j = source->y_width; - do { - sum_weights += weight_table[*src]; - src++; - } while (--j); - src -= source->y_width; - src += source->y_stride; - } while (--i); - - sum_weights /= (source->y_height * source->y_width); - - return sum_weights; -} - -/* This function returns the current per frame maximum bitrate target */ -static int frame_max_bits(VP8_COMP *cpi) { - /* Max allocation for a single frame based on the max section guidelines - * passed in and how many bits are left - */ - int max_bits; - - /* For CBR we need to also consider buffer fullness. - * If we are running below the optimal level then we need to gradually - * tighten up on max_bits. - */ - if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { - double buffer_fullness_ratio = - (double)cpi->buffer_level / - DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.optimal_buffer_level); - - /* For CBR base this on the target average bits per frame plus the - * maximum sedction rate passed in by the user - */ - max_bits = (int)(cpi->av_per_frame_bandwidth * - ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0)); - - /* If our buffer is below the optimum level */ - if (buffer_fullness_ratio < 1.0) { - /* The lower of max_bits / 4 or cpi->av_per_frame_bandwidth / 4. */ - int min_max_bits = ((cpi->av_per_frame_bandwidth >> 2) < (max_bits >> 2)) - ? cpi->av_per_frame_bandwidth >> 2 - : max_bits >> 2; - - max_bits = (int)(max_bits * buffer_fullness_ratio); - - /* Lowest value we will set ... which should allow the buffer to - * refill. - */ - if (max_bits < min_max_bits) max_bits = min_max_bits; - } - } - /* VBR */ - else { - /* For VBR base this on the bits and frames left plus the - * two_pass_vbrmax_section rate passed in by the user - */ - max_bits = saturate_cast_double_to_int( - ((double)cpi->twopass.bits_left / - (cpi->twopass.total_stats.count - - (double)cpi->common.current_video_frame)) * - ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0)); - } - - /* Trap case where we are out of bits */ - if (max_bits < 0) max_bits = 0; - - return max_bits; -} - -void vp8_init_first_pass(VP8_COMP *cpi) { - zero_stats(&cpi->twopass.total_stats); -} - -void vp8_end_first_pass(VP8_COMP *cpi) { - output_stats(cpi->output_pkt_list, &cpi->twopass.total_stats); -} - -static void zz_motion_search(MACROBLOCK *x, YV12_BUFFER_CONFIG *raw_buffer, - int *raw_motion_err, - YV12_BUFFER_CONFIG *recon_buffer, - int *best_motion_err, int recon_yoffset) { - MACROBLOCKD *const xd = &x->e_mbd; - BLOCK *b = &x->block[0]; - BLOCKD *d = &x->e_mbd.block[0]; - - unsigned char *src_ptr = (*(b->base_src) + b->src); - int src_stride = b->src_stride; - unsigned char *raw_ptr; - int raw_stride = raw_buffer->y_stride; - unsigned char *ref_ptr; - int ref_stride = x->e_mbd.pre.y_stride; - - /* Set up pointers for this macro block raw buffer */ - raw_ptr = (unsigned char *)(raw_buffer->y_buffer + recon_yoffset + d->offset); - vpx_mse16x16(src_ptr, src_stride, raw_ptr, raw_stride, - (unsigned int *)(raw_motion_err)); - - /* Set up pointers for this macro block recon buffer */ - xd->pre.y_buffer = recon_buffer->y_buffer + recon_yoffset; - ref_ptr = (unsigned char *)(xd->pre.y_buffer + d->offset); - vpx_mse16x16(src_ptr, src_stride, ref_ptr, ref_stride, - (unsigned int *)(best_motion_err)); -} - -static void first_pass_motion_search(VP8_COMP *cpi, MACROBLOCK *x, - int_mv *ref_mv, MV *best_mv, - YV12_BUFFER_CONFIG *recon_buffer, - int *best_motion_err, int recon_yoffset) { - MACROBLOCKD *const xd = &x->e_mbd; - BLOCK *b = &x->block[0]; - BLOCKD *d = &x->e_mbd.block[0]; - int num00; - - int_mv tmp_mv; - int_mv ref_mv_full; - - int tmp_err; - int step_param = 3; /* Don't search over full range for first pass */ - int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param; - int n; - vp8_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[BLOCK_16X16]; - int new_mv_mode_penalty = 256; - - /* override the default variance function to use MSE */ - v_fn_ptr.vf = vpx_mse16x16; - - /* Set up pointers for this macro block recon buffer */ - xd->pre.y_buffer = recon_buffer->y_buffer + recon_yoffset; - - /* Initial step/diamond search centred on best mv */ - tmp_mv.as_int = 0; - ref_mv_full.as_mv.col = ref_mv->as_mv.col >> 3; - ref_mv_full.as_mv.row = ref_mv->as_mv.row >> 3; - tmp_err = cpi->diamond_search_sad(x, b, d, &ref_mv_full, &tmp_mv, step_param, - x->sadperbit16, &num00, &v_fn_ptr, - x->mvcost, ref_mv); - if (tmp_err < INT_MAX - new_mv_mode_penalty) tmp_err += new_mv_mode_penalty; - - if (tmp_err < *best_motion_err) { - *best_motion_err = tmp_err; - best_mv->row = tmp_mv.as_mv.row; - best_mv->col = tmp_mv.as_mv.col; - } - - /* Further step/diamond searches as necessary */ - n = num00; - num00 = 0; - - while (n < further_steps) { - n++; - - if (num00) { - num00--; - } else { - tmp_err = cpi->diamond_search_sad(x, b, d, &ref_mv_full, &tmp_mv, - step_param + n, x->sadperbit16, &num00, - &v_fn_ptr, x->mvcost, ref_mv); - if (tmp_err < INT_MAX - new_mv_mode_penalty) { - tmp_err += new_mv_mode_penalty; - } - - if (tmp_err < *best_motion_err) { - *best_motion_err = tmp_err; - best_mv->row = tmp_mv.as_mv.row; - best_mv->col = tmp_mv.as_mv.col; - } - } - } -} - -void vp8_first_pass(VP8_COMP *cpi) { - int mb_row, mb_col; - MACROBLOCK *const x = &cpi->mb; - VP8_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &x->e_mbd; - - int recon_yoffset, recon_uvoffset; - YV12_BUFFER_CONFIG *lst_yv12 = &cm->yv12_fb[cm->lst_fb_idx]; - YV12_BUFFER_CONFIG *new_yv12 = &cm->yv12_fb[cm->new_fb_idx]; - YV12_BUFFER_CONFIG *gld_yv12 = &cm->yv12_fb[cm->gld_fb_idx]; - int recon_y_stride = lst_yv12->y_stride; - int recon_uv_stride = lst_yv12->uv_stride; - int64_t intra_error = 0; - int64_t coded_error = 0; - - int sum_mvr = 0, sum_mvc = 0; - int sum_mvr_abs = 0, sum_mvc_abs = 0; - int sum_mvrs = 0, sum_mvcs = 0; - int mvcount = 0; - int intercount = 0; - int second_ref_count = 0; - int intrapenalty = 256; - int neutral_count = 0; - int new_mv_count = 0; - int sum_in_vectors = 0; - uint32_t lastmv_as_int = 0; - - int_mv zero_ref_mv; - - zero_ref_mv.as_int = 0; - - vpx_clear_system_state(); - - x->src = *cpi->Source; - xd->pre = *lst_yv12; - xd->dst = *new_yv12; - - x->partition_info = x->pi; - - xd->mode_info_context = cm->mi; - - if (!cm->use_bilinear_mc_filter) { - xd->subpixel_predict = vp8_sixtap_predict4x4; - xd->subpixel_predict8x4 = vp8_sixtap_predict8x4; - xd->subpixel_predict8x8 = vp8_sixtap_predict8x8; - xd->subpixel_predict16x16 = vp8_sixtap_predict16x16; - } else { - xd->subpixel_predict = vp8_bilinear_predict4x4; - xd->subpixel_predict8x4 = vp8_bilinear_predict8x4; - xd->subpixel_predict8x8 = vp8_bilinear_predict8x8; - xd->subpixel_predict16x16 = vp8_bilinear_predict16x16; - } - - vp8_build_block_offsets(x); - - /* set up frame new frame for intra coded blocks */ - vp8_setup_intra_recon(new_yv12); - vp8cx_frame_init_quantizer(cpi); - - /* Initialise the MV cost table to the defaults */ - { - int flag[2] = { 1, 1 }; - vp8_initialize_rd_consts(cpi, x, - vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q)); - memcpy(cm->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context)); - vp8_build_component_cost_table(cpi->mb.mvcost, - (const MV_CONTEXT *)cm->fc.mvc, flag); - } - - /* for each macroblock row in image */ - for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) { - int_mv best_ref_mv; - - best_ref_mv.as_int = 0; - - /* reset above block coeffs */ - xd->up_available = (mb_row != 0); - recon_yoffset = (mb_row * recon_y_stride * 16); - recon_uvoffset = (mb_row * recon_uv_stride * 8); - - /* Set up limit values for motion vectors to prevent them extending - * outside the UMV borders - */ - x->mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 16)); - x->mv_row_max = - ((cm->mb_rows - 1 - mb_row) * 16) + (VP8BORDERINPIXELS - 16); - - /* for each macroblock col in image */ - for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) { - int this_error; - int gf_motion_error = INT_MAX; - int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row); - - xd->dst.y_buffer = new_yv12->y_buffer + recon_yoffset; - xd->dst.u_buffer = new_yv12->u_buffer + recon_uvoffset; - xd->dst.v_buffer = new_yv12->v_buffer + recon_uvoffset; - xd->left_available = (mb_col != 0); - - /* Copy current mb to a buffer */ - vp8_copy_mem16x16(x->src.y_buffer, x->src.y_stride, x->thismb, 16); - - /* do intra 16x16 prediction */ - this_error = vp8_encode_intra(x, use_dc_pred); - - /* "intrapenalty" below deals with situations where the intra - * and inter error scores are very low (eg a plain black frame) - * We do not have special cases in first pass for 0,0 and - * nearest etc so all inter modes carry an overhead cost - * estimate fot the mv. When the error score is very low this - * causes us to pick all or lots of INTRA modes and throw lots - * of key frames. This penalty adds a cost matching that of a - * 0,0 mv to the intra case. - */ - this_error += intrapenalty; - - /* Cumulative intra error total */ - intra_error += (int64_t)this_error; - - /* Set up limit values for motion vectors to prevent them - * extending outside the UMV borders - */ - x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16)); - x->mv_col_max = - ((cm->mb_cols - 1 - mb_col) * 16) + (VP8BORDERINPIXELS - 16); - - /* Other than for the first frame do a motion search */ - if (cm->current_video_frame > 0) { - BLOCKD *d = &x->e_mbd.block[0]; - MV tmp_mv = { 0, 0 }; - int tmp_err; - int motion_error = INT_MAX; - int raw_motion_error = INT_MAX; - - /* Simple 0,0 motion with no mv overhead */ - zz_motion_search(x, cpi->last_frame_unscaled_source, &raw_motion_error, - lst_yv12, &motion_error, recon_yoffset); - d->bmi.mv.as_mv.row = 0; - d->bmi.mv.as_mv.col = 0; - - if (raw_motion_error < cpi->oxcf.encode_breakout) { - goto skip_motion_search; - } - - /* Test last reference frame using the previous best mv as the - * starting point (best reference) for the search - */ - first_pass_motion_search(cpi, x, &best_ref_mv, &d->bmi.mv.as_mv, - lst_yv12, &motion_error, recon_yoffset); - - /* If the current best reference mv is not centred on 0,0 - * then do a 0,0 based search as well - */ - if (best_ref_mv.as_int) { - tmp_err = INT_MAX; - first_pass_motion_search(cpi, x, &zero_ref_mv, &tmp_mv, lst_yv12, - &tmp_err, recon_yoffset); - - if (tmp_err < motion_error) { - motion_error = tmp_err; - d->bmi.mv.as_mv.row = tmp_mv.row; - d->bmi.mv.as_mv.col = tmp_mv.col; - } - } - - /* Experimental search in a second reference frame ((0,0) - * based only) - */ - if (cm->current_video_frame > 1) { - first_pass_motion_search(cpi, x, &zero_ref_mv, &tmp_mv, gld_yv12, - &gf_motion_error, recon_yoffset); - - if ((gf_motion_error < motion_error) && - (gf_motion_error < this_error)) { - second_ref_count++; - } - - /* Reset to last frame as reference buffer */ - xd->pre.y_buffer = lst_yv12->y_buffer + recon_yoffset; - xd->pre.u_buffer = lst_yv12->u_buffer + recon_uvoffset; - xd->pre.v_buffer = lst_yv12->v_buffer + recon_uvoffset; - } - - skip_motion_search: - /* Intra assumed best */ - best_ref_mv.as_int = 0; - - if (motion_error <= this_error) { - /* Keep a count of cases where the inter and intra were - * very close and very low. This helps with scene cut - * detection for example in cropped clips with black bars - * at the sides or top and bottom. - */ - if ((((this_error - intrapenalty) * 9) <= (motion_error * 10)) && - (this_error < (2 * intrapenalty))) { - neutral_count++; - } - - d->bmi.mv.as_mv.row *= 8; - d->bmi.mv.as_mv.col *= 8; - this_error = motion_error; - vp8_set_mbmode_and_mvs(x, NEWMV, &d->bmi.mv); - vp8_encode_inter16x16y(x); - sum_mvr += d->bmi.mv.as_mv.row; - sum_mvr_abs += abs(d->bmi.mv.as_mv.row); - sum_mvc += d->bmi.mv.as_mv.col; - sum_mvc_abs += abs(d->bmi.mv.as_mv.col); - sum_mvrs += d->bmi.mv.as_mv.row * d->bmi.mv.as_mv.row; - sum_mvcs += d->bmi.mv.as_mv.col * d->bmi.mv.as_mv.col; - intercount++; - - best_ref_mv.as_int = d->bmi.mv.as_int; - - /* Was the vector non-zero */ - if (d->bmi.mv.as_int) { - mvcount++; - - /* Was it different from the last non zero vector */ - if (d->bmi.mv.as_int != lastmv_as_int) new_mv_count++; - lastmv_as_int = d->bmi.mv.as_int; - - /* Does the Row vector point inwards or outwards */ - if (mb_row < cm->mb_rows / 2) { - if (d->bmi.mv.as_mv.row > 0) { - sum_in_vectors--; - } else if (d->bmi.mv.as_mv.row < 0) { - sum_in_vectors++; - } - } else if (mb_row > cm->mb_rows / 2) { - if (d->bmi.mv.as_mv.row > 0) { - sum_in_vectors++; - } else if (d->bmi.mv.as_mv.row < 0) { - sum_in_vectors--; - } - } - - /* Does the Row vector point inwards or outwards */ - if (mb_col < cm->mb_cols / 2) { - if (d->bmi.mv.as_mv.col > 0) { - sum_in_vectors--; - } else if (d->bmi.mv.as_mv.col < 0) { - sum_in_vectors++; - } - } else if (mb_col > cm->mb_cols / 2) { - if (d->bmi.mv.as_mv.col > 0) { - sum_in_vectors++; - } else if (d->bmi.mv.as_mv.col < 0) { - sum_in_vectors--; - } - } - } - } - } - - coded_error += (int64_t)this_error; - - /* adjust to the next column of macroblocks */ - x->src.y_buffer += 16; - x->src.u_buffer += 8; - x->src.v_buffer += 8; - - recon_yoffset += 16; - recon_uvoffset += 8; - } - - /* adjust to the next row of mbs */ - x->src.y_buffer += 16 * x->src.y_stride - 16 * cm->mb_cols; - x->src.u_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols; - x->src.v_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols; - - /* extend the recon for intra prediction */ - vp8_extend_mb_row(new_yv12, xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, - xd->dst.v_buffer + 8); - vpx_clear_system_state(); - } - - vpx_clear_system_state(); - { - double weight = 0.0; - - FIRSTPASS_STATS fps; - - fps.frame = cm->current_video_frame; - fps.intra_error = (double)(intra_error >> 8); - fps.coded_error = (double)(coded_error >> 8); - weight = simple_weight(cpi->Source); - - if (weight < 0.1) weight = 0.1; - - fps.ssim_weighted_pred_err = fps.coded_error * weight; - - fps.pcnt_inter = 0.0; - fps.pcnt_motion = 0.0; - fps.MVr = 0.0; - fps.mvr_abs = 0.0; - fps.MVc = 0.0; - fps.mvc_abs = 0.0; - fps.MVrv = 0.0; - fps.MVcv = 0.0; - fps.mv_in_out_count = 0.0; - fps.new_mv_count = 0.0; - fps.count = 1.0; - - fps.pcnt_inter = 1.0 * (double)intercount / cm->MBs; - fps.pcnt_second_ref = 1.0 * (double)second_ref_count / cm->MBs; - fps.pcnt_neutral = 1.0 * (double)neutral_count / cm->MBs; - - if (mvcount > 0) { - fps.MVr = (double)sum_mvr / (double)mvcount; - fps.mvr_abs = (double)sum_mvr_abs / (double)mvcount; - fps.MVc = (double)sum_mvc / (double)mvcount; - fps.mvc_abs = (double)sum_mvc_abs / (double)mvcount; - fps.MVrv = ((double)sum_mvrs - (fps.MVr * fps.MVr / (double)mvcount)) / - (double)mvcount; - fps.MVcv = ((double)sum_mvcs - (fps.MVc * fps.MVc / (double)mvcount)) / - (double)mvcount; - fps.mv_in_out_count = (double)sum_in_vectors / (double)(mvcount * 2); - fps.new_mv_count = new_mv_count; - - fps.pcnt_motion = 1.0 * (double)mvcount / cpi->common.MBs; - } - - /* TODO: handle the case when duration is set to 0, or something less - * than the full time between subsequent cpi->source_time_stamps - */ - fps.duration = (double)(cpi->source->ts_end - cpi->source->ts_start); - - /* don't want to do output stats with a stack variable! */ - memcpy(&cpi->twopass.this_frame_stats, &fps, sizeof(FIRSTPASS_STATS)); - output_stats(cpi->output_pkt_list, &cpi->twopass.this_frame_stats); - accumulate_stats(&cpi->twopass.total_stats, &fps); - } - - /* Copy the previous Last Frame into the GF buffer if specific - * conditions for doing so are met - */ - if ((cm->current_video_frame > 0) && - (cpi->twopass.this_frame_stats.pcnt_inter > 0.20) && - ((cpi->twopass.this_frame_stats.intra_error / - DOUBLE_DIVIDE_CHECK(cpi->twopass.this_frame_stats.coded_error)) > - 2.0)) { - vp8_yv12_copy_frame(lst_yv12, gld_yv12); - } - - /* swap frame pointers so last frame refers to the frame we just - * compressed - */ - vp8_swap_yv12_buffer(lst_yv12, new_yv12); - vp8_yv12_extend_frame_borders(lst_yv12); - - /* Special case for the first frame. Copy into the GF buffer as a - * second reference. - */ - if (cm->current_video_frame == 0) { - vp8_yv12_copy_frame(lst_yv12, gld_yv12); - } - - cm->current_video_frame++; -} -extern const int vp8_bits_per_mb[2][QINDEX_RANGE]; - -/* Estimate a cost per mb attributable to overheads such as the coding of - * modes and motion vectors. - * Currently simplistic in its assumptions for testing. - */ - -static double bitcost(double prob) { - if (prob > 0.000122) { - return -log(prob) / log(2.0); - } else { - return 13.0; - } -} -static int64_t estimate_modemvcost(VP8_COMP *cpi, FIRSTPASS_STATS *fpstats) { - int mv_cost; - int64_t mode_cost; - - double av_pct_inter = fpstats->pcnt_inter / fpstats->count; - double av_pct_motion = fpstats->pcnt_motion / fpstats->count; - double av_intra = (1.0 - av_pct_inter); - - double zz_cost; - double motion_cost; - double intra_cost; - - zz_cost = bitcost(av_pct_inter - av_pct_motion); - motion_cost = bitcost(av_pct_motion); - intra_cost = bitcost(av_intra); - - /* Estimate of extra bits per mv overhead for mbs - * << 9 is the normalization to the (bits * 512) used in vp8_bits_per_mb - */ - mv_cost = ((int)(fpstats->new_mv_count / fpstats->count) * 8) << 9; - - /* Crude estimate of overhead cost from modes - * << 9 is the normalization to (bits * 512) used in vp8_bits_per_mb - */ - mode_cost = - (int64_t)((((av_pct_inter - av_pct_motion) * zz_cost) + - (av_pct_motion * motion_cost) + (av_intra * intra_cost)) * - cpi->common.MBs) * - 512; - - return mv_cost + mode_cost; -} - -static double calc_correction_factor(double err_per_mb, double err_devisor, - double pt_low, double pt_high, int Q) { - double power_term; - double error_term = err_per_mb / err_devisor; - double correction_factor; - - /* Adjustment based on Q to power term. */ - power_term = pt_low + (Q * 0.01); - power_term = (power_term > pt_high) ? pt_high : power_term; - - /* Adjustments to error term */ - /* TBD */ - - /* Calculate correction factor */ - correction_factor = pow(error_term, power_term); - - /* Clip range */ - correction_factor = (correction_factor < 0.05) ? 0.05 - : (correction_factor > 5.0) ? 5.0 - : correction_factor; - - return correction_factor; -} - -static int estimate_max_q(VP8_COMP *cpi, FIRSTPASS_STATS *fpstats, - int section_target_bandwitdh, int overhead_bits) { - int Q; - int num_mbs = cpi->common.MBs; - int target_norm_bits_per_mb; - - double section_err = (fpstats->coded_error / fpstats->count); - double err_per_mb = section_err / num_mbs; - double err_correction_factor; - double speed_correction = 1.0; - int overhead_bits_per_mb; - - if (section_target_bandwitdh <= 0) { - return cpi->twopass.maxq_max_limit; /* Highest value allowed */ - } - - target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) - ? (512 * section_target_bandwitdh) / num_mbs - : 512 * (section_target_bandwitdh / num_mbs); - - /* Calculate a corrective factor based on a rolling ratio of bits spent - * vs target bits - */ - if ((cpi->rolling_target_bits > 0) && - (cpi->active_worst_quality < cpi->worst_quality)) { - double rolling_ratio; - - rolling_ratio = - (double)cpi->rolling_actual_bits / (double)cpi->rolling_target_bits; - - if (rolling_ratio < 0.95) { - cpi->twopass.est_max_qcorrection_factor -= 0.005; - } else if (rolling_ratio > 1.05) { - cpi->twopass.est_max_qcorrection_factor += 0.005; - } - - cpi->twopass.est_max_qcorrection_factor = - (cpi->twopass.est_max_qcorrection_factor < 0.1) ? 0.1 - : (cpi->twopass.est_max_qcorrection_factor > 10.0) - ? 10.0 - : cpi->twopass.est_max_qcorrection_factor; - } - - /* Corrections for higher compression speed settings - * (reduced compression expected) - */ - if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1)) { - if (cpi->oxcf.cpu_used <= 5) { - speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04); - } else { - speed_correction = 1.25; - } - } - - /* Estimate of overhead bits per mb */ - /* Correction to overhead bits for min allowed Q. */ - overhead_bits_per_mb = overhead_bits / num_mbs; - overhead_bits_per_mb = (int)(overhead_bits_per_mb * - pow(0.98, (double)cpi->twopass.maxq_min_limit)); - - /* Try and pick a max Q that will be high enough to encode the - * content at the given rate. - */ - for (Q = cpi->twopass.maxq_min_limit; Q < cpi->twopass.maxq_max_limit; ++Q) { - int bits_per_mb_at_this_q; - - /* Error per MB based correction factor */ - err_correction_factor = - calc_correction_factor(err_per_mb, 150.0, 0.40, 0.90, Q); - - bits_per_mb_at_this_q = - vp8_bits_per_mb[INTER_FRAME][Q] + overhead_bits_per_mb; - - bits_per_mb_at_this_q = - (int)(.5 + err_correction_factor * speed_correction * - cpi->twopass.est_max_qcorrection_factor * - cpi->twopass.section_max_qfactor * - (double)bits_per_mb_at_this_q); - - /* Mode and motion overhead */ - /* As Q rises in real encode loop rd code will force overhead down - * We make a crude adjustment for this here as *.98 per Q step. - */ - overhead_bits_per_mb = (int)((double)overhead_bits_per_mb * 0.98); - - if (bits_per_mb_at_this_q <= target_norm_bits_per_mb) break; - } - - /* Restriction on active max q for constrained quality mode. */ - if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && - (Q < cpi->cq_target_quality)) { - Q = cpi->cq_target_quality; - } - - /* Adjust maxq_min_limit and maxq_max_limit limits based on - * average q observed in clip for non kf/gf.arf frames - * Give average a chance to settle though. - */ - if ((cpi->ni_frames > ((int)cpi->twopass.total_stats.count >> 8)) && - (cpi->ni_frames > 150)) { - cpi->twopass.maxq_max_limit = ((cpi->ni_av_qi + 32) < cpi->worst_quality) - ? (cpi->ni_av_qi + 32) - : cpi->worst_quality; - cpi->twopass.maxq_min_limit = ((cpi->ni_av_qi - 32) > cpi->best_quality) - ? (cpi->ni_av_qi - 32) - : cpi->best_quality; - } - - return Q; -} - -/* For cq mode estimate a cq level that matches the observed - * complexity and data rate. - */ -static int estimate_cq(VP8_COMP *cpi, FIRSTPASS_STATS *fpstats, - int section_target_bandwitdh, int overhead_bits) { - int Q; - int num_mbs = cpi->common.MBs; - int target_norm_bits_per_mb; - - double section_err = (fpstats->coded_error / fpstats->count); - double err_per_mb = section_err / num_mbs; - double err_correction_factor; - double speed_correction = 1.0; - double clip_iiratio; - double clip_iifactor; - int overhead_bits_per_mb; - - target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) - ? (512 * section_target_bandwitdh) / num_mbs - : 512 * (section_target_bandwitdh / num_mbs); - - /* Estimate of overhead bits per mb */ - overhead_bits_per_mb = overhead_bits / num_mbs; - - /* Corrections for higher compression speed settings - * (reduced compression expected) - */ - if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1)) { - if (cpi->oxcf.cpu_used <= 5) { - speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04); - } else { - speed_correction = 1.25; - } - } - - /* II ratio correction factor for clip as a whole */ - clip_iiratio = cpi->twopass.total_stats.intra_error / - DOUBLE_DIVIDE_CHECK(cpi->twopass.total_stats.coded_error); - clip_iifactor = 1.0 - ((clip_iiratio - 10.0) * 0.025); - if (clip_iifactor < 0.80) clip_iifactor = 0.80; - - /* Try and pick a Q that can encode the content at the given rate. */ - for (Q = 0; Q < MAXQ; ++Q) { - int bits_per_mb_at_this_q; - - /* Error per MB based correction factor */ - err_correction_factor = - calc_correction_factor(err_per_mb, 100.0, 0.40, 0.90, Q); - - bits_per_mb_at_this_q = - vp8_bits_per_mb[INTER_FRAME][Q] + overhead_bits_per_mb; - - bits_per_mb_at_this_q = - (int)(.5 + err_correction_factor * speed_correction * clip_iifactor * - (double)bits_per_mb_at_this_q); - - /* Mode and motion overhead */ - /* As Q rises in real encode loop rd code will force overhead down - * We make a crude adjustment for this here as *.98 per Q step. - */ - overhead_bits_per_mb = (int)((double)overhead_bits_per_mb * 0.98); - - if (bits_per_mb_at_this_q <= target_norm_bits_per_mb) break; - } - - /* Clip value to range "best allowed to (worst allowed - 1)" */ - Q = cq_level[Q]; - if (Q >= cpi->worst_quality) Q = cpi->worst_quality - 1; - if (Q < cpi->best_quality) Q = cpi->best_quality; - - return Q; -} - -static int estimate_q(VP8_COMP *cpi, double section_err, - int section_target_bandwitdh) { - int Q; - int num_mbs = cpi->common.MBs; - int target_norm_bits_per_mb; - - double err_per_mb = section_err / num_mbs; - double err_correction_factor; - double speed_correction = 1.0; - - target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) - ? (512 * section_target_bandwitdh) / num_mbs - : 512 * (section_target_bandwitdh / num_mbs); - - /* Corrections for higher compression speed settings - * (reduced compression expected) - */ - if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1)) { - if (cpi->oxcf.cpu_used <= 5) { - speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04); - } else { - speed_correction = 1.25; - } - } - - /* Try and pick a Q that can encode the content at the given rate. */ - for (Q = 0; Q < MAXQ; ++Q) { - int bits_per_mb_at_this_q; - - /* Error per MB based correction factor */ - err_correction_factor = - calc_correction_factor(err_per_mb, 150.0, 0.40, 0.90, Q); - - bits_per_mb_at_this_q = - (int)(.5 + (err_correction_factor * speed_correction * - cpi->twopass.est_max_qcorrection_factor * - (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0)); - - if (bits_per_mb_at_this_q <= target_norm_bits_per_mb) break; - } - - return Q; -} - -/* Estimate a worst case Q for a KF group */ -static int estimate_kf_group_q(VP8_COMP *cpi, double section_err, - int section_target_bandwitdh, - double group_iiratio) { - int Q; - int num_mbs = cpi->common.MBs; - int target_norm_bits_per_mb = (512 * section_target_bandwitdh) / num_mbs; - int bits_per_mb_at_this_q; - - double err_per_mb = section_err / num_mbs; - double err_correction_factor; - double speed_correction = 1.0; - double current_spend_ratio = 1.0; - - double pow_highq = (POW1 < 0.6) ? POW1 + 0.3 : 0.90; - double pow_lowq = (POW1 < 0.7) ? POW1 + 0.1 : 0.80; - - double iiratio_correction_factor = 1.0; - - double combined_correction_factor; - - /* Trap special case where the target is <= 0 */ - if (target_norm_bits_per_mb <= 0) return MAXQ * 2; - - /* Calculate a corrective factor based on a rolling ratio of bits spent - * vs target bits - * This is clamped to the range 0.1 to 10.0 - */ - if (cpi->long_rolling_target_bits <= 0) { - current_spend_ratio = 10.0; - } else { - current_spend_ratio = (double)cpi->long_rolling_actual_bits / - (double)cpi->long_rolling_target_bits; - current_spend_ratio = (current_spend_ratio > 10.0) ? 10.0 - : (current_spend_ratio < 0.1) ? 0.1 - : current_spend_ratio; - } - - /* Calculate a correction factor based on the quality of prediction in - * the sequence as indicated by intra_inter error score ratio (IIRatio) - * The idea here is to favour subsampling in the hardest sections vs - * the easyest. - */ - iiratio_correction_factor = 1.0 - ((group_iiratio - 6.0) * 0.1); - - if (iiratio_correction_factor < 0.5) iiratio_correction_factor = 0.5; - - /* Corrections for higher compression speed settings - * (reduced compression expected) - */ - if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1)) { - if (cpi->oxcf.cpu_used <= 5) { - speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04); - } else { - speed_correction = 1.25; - } - } - - /* Combine the various factors calculated above */ - combined_correction_factor = - speed_correction * iiratio_correction_factor * current_spend_ratio; - - /* Try and pick a Q that should be high enough to encode the content at - * the given rate. - */ - for (Q = 0; Q < MAXQ; ++Q) { - /* Error per MB based correction factor */ - err_correction_factor = - calc_correction_factor(err_per_mb, 150.0, pow_lowq, pow_highq, Q); - - bits_per_mb_at_this_q = - (int)(.5 + (err_correction_factor * combined_correction_factor * - (double)vp8_bits_per_mb[INTER_FRAME][Q])); - - if (bits_per_mb_at_this_q <= target_norm_bits_per_mb) break; - } - - /* If we could not hit the target even at Max Q then estimate what Q - * would have been required - */ - while ((bits_per_mb_at_this_q > target_norm_bits_per_mb) && - (Q < (MAXQ * 2))) { - bits_per_mb_at_this_q = (int)(0.96 * bits_per_mb_at_this_q); - Q++; - } - - return Q; -} - -void vp8_init_second_pass(VP8_COMP *cpi) { - FIRSTPASS_STATS this_frame; - FIRSTPASS_STATS *start_pos; - - double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth * - cpi->oxcf.two_pass_vbrmin_section / 100); - - zero_stats(&cpi->twopass.total_stats); - zero_stats(&cpi->twopass.total_left_stats); - - if (!cpi->twopass.stats_in_end) return; - - cpi->twopass.total_stats = *cpi->twopass.stats_in_end; - cpi->twopass.total_left_stats = cpi->twopass.total_stats; - - /* each frame can have a different duration, as the frame rate in the - * source isn't guaranteed to be constant. The frame rate prior to - * the first frame encoded in the second pass is a guess. However the - * sum duration is not. Its calculated based on the actual durations of - * all frames from the first pass. - */ - vp8_new_framerate(cpi, 10000000.0 * cpi->twopass.total_stats.count / - cpi->twopass.total_stats.duration); - - cpi->twopass.bits_left = (int64_t)(cpi->twopass.total_stats.duration * - cpi->oxcf.target_bandwidth / 10000000.0); - cpi->twopass.bits_left -= (int64_t)(cpi->twopass.total_stats.duration * - two_pass_min_rate / 10000000.0); - - /* Calculate a minimum intra value to be used in determining the IIratio - * scores used in the second pass. We have this minimum to make sure - * that clips that are static but "low complexity" in the intra domain - * are still boosted appropriately for KF/GF/ARF - */ - cpi->twopass.kf_intra_err_min = KF_MB_INTRA_MIN * cpi->common.MBs; - cpi->twopass.gf_intra_err_min = GF_MB_INTRA_MIN * cpi->common.MBs; - - /* Scan the first pass file and calculate an average Intra / Inter error - * score ratio for the sequence - */ - { - double sum_iiratio = 0.0; - double IIRatio; - - start_pos = cpi->twopass.stats_in; /* Note starting "file" position */ - - while (input_stats(cpi, &this_frame) != EOF) { - IIRatio = - this_frame.intra_error / DOUBLE_DIVIDE_CHECK(this_frame.coded_error); - IIRatio = (IIRatio < 1.0) ? 1.0 : (IIRatio > 20.0) ? 20.0 : IIRatio; - sum_iiratio += IIRatio; - } - - cpi->twopass.avg_iiratio = - sum_iiratio / - DOUBLE_DIVIDE_CHECK((double)cpi->twopass.total_stats.count); - - /* Reset file position */ - reset_fpf_position(cpi, start_pos); - } - - /* Scan the first pass file and calculate a modified total error based - * upon the bias/power function used to allocate bits - */ - { - start_pos = cpi->twopass.stats_in; /* Note starting "file" position */ - - cpi->twopass.modified_error_total = 0.0; - cpi->twopass.modified_error_used = 0.0; - - while (input_stats(cpi, &this_frame) != EOF) { - cpi->twopass.modified_error_total += - calculate_modified_err(cpi, &this_frame); - } - cpi->twopass.modified_error_left = cpi->twopass.modified_error_total; - - reset_fpf_position(cpi, start_pos); /* Reset file position */ - } -} - -void vp8_end_second_pass(VP8_COMP *cpi) { (void)cpi; } - -/* This function gives and estimate of how badly we believe the prediction - * quality is decaying from frame to frame. - */ -static double get_prediction_decay_rate(FIRSTPASS_STATS *next_frame) { - double prediction_decay_rate; - double motion_decay; - double motion_pct = next_frame->pcnt_motion; - - /* Initial basis is the % mbs inter coded */ - prediction_decay_rate = next_frame->pcnt_inter; - - /* High % motion -> somewhat higher decay rate */ - motion_decay = (1.0 - (motion_pct / 20.0)); - if (motion_decay < prediction_decay_rate) { - prediction_decay_rate = motion_decay; - } - - /* Adjustment to decay rate based on speed of motion */ - { - double this_mv_rabs; - double this_mv_cabs; - double distance_factor; - - this_mv_rabs = fabs(next_frame->mvr_abs * motion_pct); - this_mv_cabs = fabs(next_frame->mvc_abs * motion_pct); - - distance_factor = - sqrt((this_mv_rabs * this_mv_rabs) + (this_mv_cabs * this_mv_cabs)) / - 250.0; - distance_factor = ((distance_factor > 1.0) ? 0.0 : (1.0 - distance_factor)); - if (distance_factor < prediction_decay_rate) { - prediction_decay_rate = distance_factor; - } - } - - return prediction_decay_rate; -} - -/* Function to test for a condition where a complex transition is followed - * by a static section. For example in slide shows where there is a fade - * between slides. This is to help with more optimal kf and gf positioning. - */ -static int detect_transition_to_still(VP8_COMP *cpi, int frame_interval, - int still_interval, - double loop_decay_rate, - double decay_accumulator) { - int trans_to_still = 0; - - /* Break clause to detect very still sections after motion - * For example a static image after a fade or other transition - * instead of a clean scene cut. - */ - if ((frame_interval > MIN_GF_INTERVAL) && (loop_decay_rate >= 0.999) && - (decay_accumulator < 0.9)) { - int j; - FIRSTPASS_STATS *position = cpi->twopass.stats_in; - FIRSTPASS_STATS tmp_next_frame; - double decay_rate; - - /* Look ahead a few frames to see if static condition persists... */ - for (j = 0; j < still_interval; ++j) { - if (EOF == input_stats(cpi, &tmp_next_frame)) break; - - decay_rate = get_prediction_decay_rate(&tmp_next_frame); - if (decay_rate < 0.999) break; - } - /* Reset file position */ - reset_fpf_position(cpi, position); - - /* Only if it does do we signal a transition to still */ - if (j == still_interval) trans_to_still = 1; - } - - return trans_to_still; -} - -/* This function detects a flash through the high relative pcnt_second_ref - * score in the frame following a flash frame. The offset passed in should - * reflect this - */ -static int detect_flash(VP8_COMP *cpi, int offset) { - FIRSTPASS_STATS next_frame; - - int flash_detected = 0; - - /* Read the frame data. */ - /* The return is 0 (no flash detected) if not a valid frame */ - if (read_frame_stats(cpi, &next_frame, offset) != EOF) { - /* What we are looking for here is a situation where there is a - * brief break in prediction (such as a flash) but subsequent frames - * are reasonably well predicted by an earlier (pre flash) frame. - * The recovery after a flash is indicated by a high pcnt_second_ref - * comapred to pcnt_inter. - */ - if ((next_frame.pcnt_second_ref > next_frame.pcnt_inter) && - (next_frame.pcnt_second_ref >= 0.5)) { - flash_detected = 1; - - /*if (1) - { - FILE *f = fopen("flash.stt", "a"); - fprintf(f, "%8.0f %6.2f %6.2f\n", - next_frame.frame, - next_frame.pcnt_inter, - next_frame.pcnt_second_ref); - fclose(f); - }*/ - } - } - - return flash_detected; -} - -/* Update the motion related elements to the GF arf boost calculation */ -static void accumulate_frame_motion_stats(FIRSTPASS_STATS *this_frame, - double *this_frame_mv_in_out, - double *mv_in_out_accumulator, - double *abs_mv_in_out_accumulator, - double *mv_ratio_accumulator) { - double this_frame_mvr_ratio; - double this_frame_mvc_ratio; - double motion_pct; - - /* Accumulate motion stats. */ - motion_pct = this_frame->pcnt_motion; - - /* Accumulate Motion In/Out of frame stats */ - *this_frame_mv_in_out = this_frame->mv_in_out_count * motion_pct; - *mv_in_out_accumulator += this_frame->mv_in_out_count * motion_pct; - *abs_mv_in_out_accumulator += fabs(this_frame->mv_in_out_count * motion_pct); - - /* Accumulate a measure of how uniform (or conversely how random) - * the motion field is. (A ratio of absmv / mv) - */ - if (motion_pct > 0.05) { - this_frame_mvr_ratio = - fabs(this_frame->mvr_abs) / DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVr)); - - this_frame_mvc_ratio = - fabs(this_frame->mvc_abs) / DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVc)); - - *mv_ratio_accumulator += (this_frame_mvr_ratio < this_frame->mvr_abs) - ? (this_frame_mvr_ratio * motion_pct) - : this_frame->mvr_abs * motion_pct; - - *mv_ratio_accumulator += (this_frame_mvc_ratio < this_frame->mvc_abs) - ? (this_frame_mvc_ratio * motion_pct) - : this_frame->mvc_abs * motion_pct; - } -} - -/* Calculate a baseline boost number for the current frame. */ -static double calc_frame_boost(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame, - double this_frame_mv_in_out) { - double frame_boost; - - /* Underlying boost factor is based on inter intra error ratio */ - if (this_frame->intra_error > cpi->twopass.gf_intra_err_min) { - frame_boost = (IIFACTOR * this_frame->intra_error / - DOUBLE_DIVIDE_CHECK(this_frame->coded_error)); - } else { - frame_boost = (IIFACTOR * cpi->twopass.gf_intra_err_min / - DOUBLE_DIVIDE_CHECK(this_frame->coded_error)); - } - - /* Increase boost for frames where new data coming into frame - * (eg zoom out). Slightly reduce boost if there is a net balance - * of motion out of the frame (zoom in). - * The range for this_frame_mv_in_out is -1.0 to +1.0 - */ - if (this_frame_mv_in_out > 0.0) { - frame_boost += frame_boost * (this_frame_mv_in_out * 2.0); - /* In extreme case boost is halved */ - } else { - frame_boost += frame_boost * (this_frame_mv_in_out / 2.0); - } - - /* Clip to maximum */ - if (frame_boost > GF_RMAX) frame_boost = GF_RMAX; - - return frame_boost; -} - -#if NEW_BOOST -static int calc_arf_boost(VP8_COMP *cpi, int offset, int f_frames, int b_frames, - int *f_boost, int *b_boost) { - FIRSTPASS_STATS this_frame; - - int i; - double boost_score = 0.0; - double mv_ratio_accumulator = 0.0; - double decay_accumulator = 1.0; - double this_frame_mv_in_out = 0.0; - double mv_in_out_accumulator = 0.0; - double abs_mv_in_out_accumulator = 0.0; - double r; - int flash_detected = 0; - - /* Search forward from the proposed arf/next gf position */ - for (i = 0; i < f_frames; ++i) { - if (read_frame_stats(cpi, &this_frame, (i + offset)) == EOF) break; - - /* Update the motion related elements to the boost calculation */ - accumulate_frame_motion_stats( - &this_frame, &this_frame_mv_in_out, &mv_in_out_accumulator, - &abs_mv_in_out_accumulator, &mv_ratio_accumulator); - - /* Calculate the baseline boost number for this frame */ - r = calc_frame_boost(cpi, &this_frame, this_frame_mv_in_out); - - /* We want to discount the flash frame itself and the recovery - * frame that follows as both will have poor scores. - */ - flash_detected = - detect_flash(cpi, (i + offset)) || detect_flash(cpi, (i + offset + 1)); - - /* Cumulative effect of prediction quality decay */ - if (!flash_detected) { - decay_accumulator = - decay_accumulator * get_prediction_decay_rate(&this_frame); - decay_accumulator = decay_accumulator < 0.1 ? 0.1 : decay_accumulator; - } - boost_score += (decay_accumulator * r); - - /* Break out conditions. */ - if ((!flash_detected) && - ((mv_ratio_accumulator > 100.0) || (abs_mv_in_out_accumulator > 3.0) || - (mv_in_out_accumulator < -2.0))) { - break; - } - } - - *f_boost = (int)(boost_score * 100.0) >> 4; - - /* Reset for backward looking loop */ - boost_score = 0.0; - mv_ratio_accumulator = 0.0; - decay_accumulator = 1.0; - this_frame_mv_in_out = 0.0; - mv_in_out_accumulator = 0.0; - abs_mv_in_out_accumulator = 0.0; - - /* Search forward from the proposed arf/next gf position */ - for (i = -1; i >= -b_frames; i--) { - if (read_frame_stats(cpi, &this_frame, (i + offset)) == EOF) break; - - /* Update the motion related elements to the boost calculation */ - accumulate_frame_motion_stats( - &this_frame, &this_frame_mv_in_out, &mv_in_out_accumulator, - &abs_mv_in_out_accumulator, &mv_ratio_accumulator); - - /* Calculate the baseline boost number for this frame */ - r = calc_frame_boost(cpi, &this_frame, this_frame_mv_in_out); - - /* We want to discount the flash frame itself and the recovery - * frame that follows as both will have poor scores. - */ - flash_detected = - detect_flash(cpi, (i + offset)) || detect_flash(cpi, (i + offset + 1)); - - /* Cumulative effect of prediction quality decay */ - if (!flash_detected) { - decay_accumulator = - decay_accumulator * get_prediction_decay_rate(&this_frame); - decay_accumulator = decay_accumulator < 0.1 ? 0.1 : decay_accumulator; - } - - boost_score += (decay_accumulator * r); - - /* Break out conditions. */ - if ((!flash_detected) && - ((mv_ratio_accumulator > 100.0) || (abs_mv_in_out_accumulator > 3.0) || - (mv_in_out_accumulator < -2.0))) { - break; - } - } - *b_boost = (int)(boost_score * 100.0) >> 4; - - return (*f_boost + *b_boost); -} -#endif - -/* Analyse and define a gf/arf group . */ -static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) { - FIRSTPASS_STATS next_frame; - FIRSTPASS_STATS *start_pos; - int i; - double r; - double boost_score = 0.0; - double old_boost_score = 0.0; - double gf_group_err = 0.0; - double gf_first_frame_err = 0.0; - double mod_frame_err = 0.0; - - double mv_ratio_accumulator = 0.0; - double decay_accumulator = 1.0; - - double loop_decay_rate = 1.00; /* Starting decay rate */ - - double this_frame_mv_in_out = 0.0; - double mv_in_out_accumulator = 0.0; - double abs_mv_in_out_accumulator = 0.0; - - int max_bits = frame_max_bits(cpi); /* Max for a single frame */ - - unsigned int allow_alt_ref = - cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames; - - int alt_boost = 0; - int f_boost = 0; - int b_boost = 0; - int flash_detected; - - cpi->twopass.gf_group_bits = 0; - cpi->twopass.gf_decay_rate = 0; - - vpx_clear_system_state(); - - start_pos = cpi->twopass.stats_in; - - memset(&next_frame, 0, sizeof(next_frame)); /* assure clean */ - - /* Load stats for the current frame. */ - mod_frame_err = calculate_modified_err(cpi, this_frame); - - /* Note the error of the frame at the start of the group (this will be - * the GF frame error if we code a normal gf - */ - gf_first_frame_err = mod_frame_err; - - /* Special treatment if the current frame is a key frame (which is also - * a gf). If it is then its error score (and hence bit allocation) need - * to be subtracted out from the calculation for the GF group - */ - if (cpi->common.frame_type == KEY_FRAME) gf_group_err -= gf_first_frame_err; - - /* Scan forward to try and work out how many frames the next gf group - * should contain and what level of boost is appropriate for the GF - * or ARF that will be coded with the group - */ - i = 0; - - while (((i < cpi->twopass.static_scene_max_gf_interval) || - ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL)) && - (i < cpi->twopass.frames_to_key)) { - i++; - - /* Accumulate error score of frames in this gf group */ - mod_frame_err = calculate_modified_err(cpi, this_frame); - - gf_group_err += mod_frame_err; - - if (EOF == input_stats(cpi, &next_frame)) break; - - /* Test for the case where there is a brief flash but the prediction - * quality back to an earlier frame is then restored. - */ - flash_detected = detect_flash(cpi, 0); - - /* Update the motion related elements to the boost calculation */ - accumulate_frame_motion_stats( - &next_frame, &this_frame_mv_in_out, &mv_in_out_accumulator, - &abs_mv_in_out_accumulator, &mv_ratio_accumulator); - - /* Calculate a baseline boost number for this frame */ - r = calc_frame_boost(cpi, &next_frame, this_frame_mv_in_out); - - /* Cumulative effect of prediction quality decay */ - if (!flash_detected) { - loop_decay_rate = get_prediction_decay_rate(&next_frame); - decay_accumulator = decay_accumulator * loop_decay_rate; - decay_accumulator = decay_accumulator < 0.1 ? 0.1 : decay_accumulator; - } - boost_score += (decay_accumulator * r); - - /* Break clause to detect very still sections after motion - * For example a staic image after a fade or other transition. - */ - if (detect_transition_to_still(cpi, i, 5, loop_decay_rate, - decay_accumulator)) { - allow_alt_ref = 0; - boost_score = old_boost_score; - break; - } - - /* Break out conditions. */ - if ( - /* Break at cpi->max_gf_interval unless almost totally static */ - (i >= cpi->max_gf_interval && (decay_accumulator < 0.995)) || - ( - /* Don't break out with a very short interval */ - (i > MIN_GF_INTERVAL) && - /* Don't break out very close to a key frame */ - ((cpi->twopass.frames_to_key - i) >= MIN_GF_INTERVAL) && - ((boost_score > 20.0) || (next_frame.pcnt_inter < 0.75)) && - (!flash_detected) && - ((mv_ratio_accumulator > 100.0) || - (abs_mv_in_out_accumulator > 3.0) || - (mv_in_out_accumulator < -2.0) || - ((boost_score - old_boost_score) < 2.0)))) { - boost_score = old_boost_score; - break; - } - - memcpy(this_frame, &next_frame, sizeof(*this_frame)); - - old_boost_score = boost_score; - } - - cpi->twopass.gf_decay_rate = - (i > 0) ? (int)(100.0 * (1.0 - decay_accumulator)) / i : 0; - - /* When using CBR apply additional buffer related upper limits */ - if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { - double max_boost; - - /* For cbr apply buffer related limits */ - if (cpi->drop_frames_allowed) { - int64_t df_buffer_level = cpi->oxcf.drop_frames_water_mark * - (cpi->oxcf.optimal_buffer_level / 100); - - if (cpi->buffer_level > df_buffer_level) { - max_boost = - ((double)((cpi->buffer_level - df_buffer_level) * 2 / 3) * 16.0) / - DOUBLE_DIVIDE_CHECK((double)cpi->av_per_frame_bandwidth); - } else { - max_boost = 0.0; - } - } else if (cpi->buffer_level > 0) { - max_boost = ((double)(cpi->buffer_level * 2 / 3) * 16.0) / - DOUBLE_DIVIDE_CHECK((double)cpi->av_per_frame_bandwidth); - } else { - max_boost = 0.0; - } - - if (boost_score > max_boost) boost_score = max_boost; - } - - /* Don't allow conventional gf too near the next kf */ - if ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL) { - while (i < cpi->twopass.frames_to_key) { - i++; - - if (EOF == input_stats(cpi, this_frame)) break; - - if (i < cpi->twopass.frames_to_key) { - mod_frame_err = calculate_modified_err(cpi, this_frame); - gf_group_err += mod_frame_err; - } - } - } - - cpi->gfu_boost = (int)(boost_score * 100.0) >> 4; - -#if NEW_BOOST - /* Alterrnative boost calculation for alt ref */ - alt_boost = calc_arf_boost(cpi, 0, (i - 1), (i - 1), &f_boost, &b_boost); -#endif - - /* Should we use the alternate reference frame */ - if (allow_alt_ref && (i >= MIN_GF_INTERVAL) && - /* don't use ARF very near next kf */ - (i <= (cpi->twopass.frames_to_key - MIN_GF_INTERVAL)) && -#if NEW_BOOST - ((next_frame.pcnt_inter > 0.75) || (next_frame.pcnt_second_ref > 0.5)) && - ((mv_in_out_accumulator / (double)i > -0.2) || - (mv_in_out_accumulator > -2.0)) && - (b_boost > 100) && (f_boost > 100)) -#else - (next_frame.pcnt_inter > 0.75) && - ((mv_in_out_accumulator / (double)i > -0.2) || - (mv_in_out_accumulator > -2.0)) && - (cpi->gfu_boost > 100) && - (cpi->twopass.gf_decay_rate <= - (ARF_DECAY_THRESH + (cpi->gfu_boost / 200)))) -#endif - { - int Boost; - int allocation_chunks; - int Q = - (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q; - int tmp_q; - int arf_frame_bits = 0; - int group_bits; - -#if NEW_BOOST - cpi->gfu_boost = alt_boost; -#endif - - /* Estimate the bits to be allocated to the group as a whole */ - if ((cpi->twopass.kf_group_bits > 0) && - (cpi->twopass.kf_group_error_left > 0)) { - group_bits = - (int)((double)cpi->twopass.kf_group_bits * - (gf_group_err / (double)cpi->twopass.kf_group_error_left)); - } else { - group_bits = 0; - } - -/* Boost for arf frame */ -#if NEW_BOOST - Boost = (alt_boost * GFQ_ADJUSTMENT) / 100; -#else - Boost = (cpi->gfu_boost * 3 * GFQ_ADJUSTMENT) / (2 * 100); -#endif - Boost += (i * 50); - - /* Set max and minimum boost and hence minimum allocation */ - if (Boost > ((cpi->baseline_gf_interval + 1) * 200)) { - Boost = ((cpi->baseline_gf_interval + 1) * 200); - } else if (Boost < 125) { - Boost = 125; - } - - allocation_chunks = (i * 100) + Boost; - - /* Normalize Altboost and allocations chunck down to prevent overflow */ - while (Boost > 1000) { - Boost /= 2; - allocation_chunks /= 2; - } - - /* Calculate the number of bits to be spent on the arf based on the - * boost number - */ - arf_frame_bits = - (int)((double)Boost * (group_bits / (double)allocation_chunks)); - - /* Estimate if there are enough bits available to make worthwhile use - * of an arf. - */ - tmp_q = estimate_q(cpi, mod_frame_err, (int)arf_frame_bits); - - /* Only use an arf if it is likely we will be able to code - * it at a lower Q than the surrounding frames. - */ - if (tmp_q < cpi->worst_quality) { - int half_gf_int; - int frames_after_arf; - int frames_bwd = cpi->oxcf.arnr_max_frames - 1; - int frames_fwd = cpi->oxcf.arnr_max_frames - 1; - - cpi->source_alt_ref_pending = 1; - - /* - * For alt ref frames the error score for the end frame of the - * group (the alt ref frame) should not contribute to the group - * total and hence the number of bit allocated to the group. - * Rather it forms part of the next group (it is the GF at the - * start of the next group) - * gf_group_err -= mod_frame_err; - * - * For alt ref frames alt ref frame is technically part of the - * GF frame for the next group but we always base the error - * calculation and bit allocation on the current group of frames. - * - * Set the interval till the next gf or arf. - * For ARFs this is the number of frames to be coded before the - * future frame that is coded as an ARF. - * The future frame itself is part of the next group - */ - cpi->baseline_gf_interval = i; - - /* - * Define the arnr filter width for this group of frames: - * We only filter frames that lie within a distance of half - * the GF interval from the ARF frame. We also have to trap - * cases where the filter extends beyond the end of clip. - * Note: this_frame->frame has been updated in the loop - * so it now points at the ARF frame. - */ - half_gf_int = cpi->baseline_gf_interval >> 1; - frames_after_arf = - (int)(cpi->twopass.total_stats.count - this_frame->frame - 1); - - switch (cpi->oxcf.arnr_type) { - case 1: /* Backward filter */ - frames_fwd = 0; - if (frames_bwd > half_gf_int) frames_bwd = half_gf_int; - break; - - case 2: /* Forward filter */ - if (frames_fwd > half_gf_int) frames_fwd = half_gf_int; - if (frames_fwd > frames_after_arf) frames_fwd = frames_after_arf; - frames_bwd = 0; - break; - - case 3: /* Centered filter */ - default: - frames_fwd >>= 1; - if (frames_fwd > frames_after_arf) frames_fwd = frames_after_arf; - if (frames_fwd > half_gf_int) frames_fwd = half_gf_int; - - frames_bwd = frames_fwd; - - /* For even length filter there is one more frame backward - * than forward: e.g. len=6 ==> bbbAff, len=7 ==> bbbAfff. - */ - if (frames_bwd < half_gf_int) { - frames_bwd += (cpi->oxcf.arnr_max_frames + 1) & 0x1; - } - break; - } - - cpi->active_arnr_frames = frames_bwd + 1 + frames_fwd; - } else { - cpi->source_alt_ref_pending = 0; - cpi->baseline_gf_interval = i; - } - } else { - cpi->source_alt_ref_pending = 0; - cpi->baseline_gf_interval = i; - } - - /* - * Now decide how many bits should be allocated to the GF group as a - * proportion of those remaining in the kf group. - * The final key frame group in the clip is treated as a special case - * where cpi->twopass.kf_group_bits is tied to cpi->twopass.bits_left. - * This is also important for short clips where there may only be one - * key frame. - */ - if (cpi->twopass.frames_to_key >= - (int)(cpi->twopass.total_stats.count - cpi->common.current_video_frame)) { - cpi->twopass.kf_group_bits = - (cpi->twopass.bits_left > 0) ? cpi->twopass.bits_left : 0; - } - - /* Calculate the bits to be allocated to the group as a whole */ - if ((cpi->twopass.kf_group_bits > 0) && - (cpi->twopass.kf_group_error_left > 0)) { - cpi->twopass.gf_group_bits = - (int64_t)(cpi->twopass.kf_group_bits * - (gf_group_err / cpi->twopass.kf_group_error_left)); - } else { - cpi->twopass.gf_group_bits = 0; - } - - cpi->twopass.gf_group_bits = - (cpi->twopass.gf_group_bits < 0) ? 0 - : (cpi->twopass.gf_group_bits > cpi->twopass.kf_group_bits) - ? cpi->twopass.kf_group_bits - : cpi->twopass.gf_group_bits; - - /* Clip cpi->twopass.gf_group_bits based on user supplied data rate - * variability limit (cpi->oxcf.two_pass_vbrmax_section) - */ - if (cpi->twopass.gf_group_bits > - (int64_t)max_bits * cpi->baseline_gf_interval) { - cpi->twopass.gf_group_bits = (int64_t)max_bits * cpi->baseline_gf_interval; - } - - /* Reset the file position */ - reset_fpf_position(cpi, start_pos); - - /* Update the record of error used so far (only done once per gf group) */ - cpi->twopass.modified_error_used += gf_group_err; - - /* Assign bits to the arf or gf. */ - for (i = 0; i <= (cpi->source_alt_ref_pending && - cpi->common.frame_type != KEY_FRAME); - i++) { - int Boost; - int allocation_chunks; - int Q = - (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q; - int gf_bits; - - /* For ARF frames */ - if (cpi->source_alt_ref_pending && i == 0) { -#if NEW_BOOST - Boost = (alt_boost * GFQ_ADJUSTMENT) / 100; -#else - Boost = (cpi->gfu_boost * 3 * GFQ_ADJUSTMENT) / (2 * 100); -#endif - Boost += (cpi->baseline_gf_interval * 50); - - /* Set max and minimum boost and hence minimum allocation */ - if (Boost > ((cpi->baseline_gf_interval + 1) * 200)) { - Boost = ((cpi->baseline_gf_interval + 1) * 200); - } else if (Boost < 125) { - Boost = 125; - } - - allocation_chunks = ((cpi->baseline_gf_interval + 1) * 100) + Boost; - } - /* Else for standard golden frames */ - else { - /* boost based on inter / intra ratio of subsequent frames */ - Boost = (cpi->gfu_boost * GFQ_ADJUSTMENT) / 100; - - /* Set max and minimum boost and hence minimum allocation */ - if (Boost > (cpi->baseline_gf_interval * 150)) { - Boost = (cpi->baseline_gf_interval * 150); - } else if (Boost < 125) { - Boost = 125; - } - - allocation_chunks = (cpi->baseline_gf_interval * 100) + (Boost - 100); - } - - /* Normalize Altboost and allocations chunck down to prevent overflow */ - while (Boost > 1000) { - Boost /= 2; - allocation_chunks /= 2; - } - - /* Calculate the number of bits to be spent on the gf or arf based on - * the boost number - */ - gf_bits = saturate_cast_double_to_int( - (double)Boost * - (cpi->twopass.gf_group_bits / (double)allocation_chunks)); - - /* If the frame that is to be boosted is simpler than the average for - * the gf/arf group then use an alternative calculation - * based on the error score of the frame itself - */ - if (mod_frame_err < gf_group_err / (double)cpi->baseline_gf_interval) { - double alt_gf_grp_bits; - int alt_gf_bits; - - alt_gf_grp_bits = - (double)cpi->twopass.kf_group_bits * - (mod_frame_err * (double)cpi->baseline_gf_interval) / - DOUBLE_DIVIDE_CHECK((double)cpi->twopass.kf_group_error_left); - - alt_gf_bits = - (int)((double)Boost * (alt_gf_grp_bits / (double)allocation_chunks)); - - if (gf_bits > alt_gf_bits) { - gf_bits = alt_gf_bits; - } - } - /* Else if it is harder than other frames in the group make sure it at - * least receives an allocation in keeping with its relative error - * score, otherwise it may be worse off than an "un-boosted" frame - */ - else { - // Avoid division by 0 by clamping cpi->twopass.kf_group_error_left to 1 - int alt_gf_bits = saturate_cast_double_to_int( - (double)cpi->twopass.kf_group_bits * mod_frame_err / - (double)VPXMAX(cpi->twopass.kf_group_error_left, 1)); - - if (alt_gf_bits > gf_bits) { - gf_bits = alt_gf_bits; - } - } - - /* Apply an additional limit for CBR */ - if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { - if (cpi->twopass.gf_bits > (int)(cpi->buffer_level >> 1)) { - cpi->twopass.gf_bits = (int)(cpi->buffer_level >> 1); - } - } - - /* Don't allow a negative value for gf_bits */ - if (gf_bits < 0) gf_bits = 0; - - /* Add in minimum for a frame */ - gf_bits += cpi->min_frame_bandwidth; - - if (i == 0) { - cpi->twopass.gf_bits = gf_bits; - } - if (i == 1 || (!cpi->source_alt_ref_pending && - (cpi->common.frame_type != KEY_FRAME))) { - /* Per frame bit target for this frame */ - cpi->per_frame_bandwidth = gf_bits; - } - } - - { - /* Adjust KF group bits and error remainin */ - cpi->twopass.kf_group_error_left -= (int64_t)gf_group_err; - cpi->twopass.kf_group_bits -= cpi->twopass.gf_group_bits; - - if (cpi->twopass.kf_group_bits < 0) cpi->twopass.kf_group_bits = 0; - - /* Note the error score left in the remaining frames of the group. - * For normal GFs we want to remove the error score for the first - * frame of the group (except in Key frame case where this has - * already happened) - */ - if (!cpi->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME) { - cpi->twopass.gf_group_error_left = - (int)(gf_group_err - gf_first_frame_err); - } else { - cpi->twopass.gf_group_error_left = (int)gf_group_err; - } - - cpi->twopass.gf_group_bits -= - cpi->twopass.gf_bits - cpi->min_frame_bandwidth; - - if (cpi->twopass.gf_group_bits < 0) cpi->twopass.gf_group_bits = 0; - - /* This condition could fail if there are two kfs very close together - * despite (MIN_GF_INTERVAL) and would cause a divide by 0 in the - * calculation of cpi->twopass.alt_extra_bits. - */ - if (cpi->baseline_gf_interval >= 3) { -#if NEW_BOOST - int boost = (cpi->source_alt_ref_pending) ? b_boost : cpi->gfu_boost; -#else - int boost = cpi->gfu_boost; -#endif - if (boost >= 150) { - int pct_extra; - - pct_extra = (boost - 100) / 50; - pct_extra = (pct_extra > 20) ? 20 : pct_extra; - - cpi->twopass.alt_extra_bits = - (int)(cpi->twopass.gf_group_bits * pct_extra) / 100; - cpi->twopass.gf_group_bits -= cpi->twopass.alt_extra_bits; - cpi->twopass.alt_extra_bits /= ((cpi->baseline_gf_interval - 1) >> 1); - } else { - cpi->twopass.alt_extra_bits = 0; - } - } else { - cpi->twopass.alt_extra_bits = 0; - } - } - - /* Adjustments based on a measure of complexity of the section */ - if (cpi->common.frame_type != KEY_FRAME) { - FIRSTPASS_STATS sectionstats; - double Ratio; - - zero_stats(§ionstats); - reset_fpf_position(cpi, start_pos); - - for (i = 0; i < cpi->baseline_gf_interval; ++i) { - input_stats(cpi, &next_frame); - accumulate_stats(§ionstats, &next_frame); - } - - avg_stats(§ionstats); - - cpi->twopass.section_intra_rating = - (unsigned int)(sectionstats.intra_error / - DOUBLE_DIVIDE_CHECK(sectionstats.coded_error)); - - Ratio = sectionstats.intra_error / - DOUBLE_DIVIDE_CHECK(sectionstats.coded_error); - cpi->twopass.section_max_qfactor = 1.0 - ((Ratio - 10.0) * 0.025); - - if (cpi->twopass.section_max_qfactor < 0.80) { - cpi->twopass.section_max_qfactor = 0.80; - } - - reset_fpf_position(cpi, start_pos); - } -} - -/* Allocate bits to a normal frame that is neither a gf an arf or a key frame. - */ -static void assign_std_frame_bits(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) { - int target_frame_size; - - double modified_err; - double err_fraction; - - int max_bits = frame_max_bits(cpi); /* Max for a single frame */ - - /* Calculate modified prediction error used in bit allocation */ - modified_err = calculate_modified_err(cpi, this_frame); - - /* What portion of the remaining GF group error is used by this frame */ - if (cpi->twopass.gf_group_error_left > 0) { - err_fraction = modified_err / cpi->twopass.gf_group_error_left; - } else { - err_fraction = 0.0; - } - - /* How many of those bits available for allocation should we give it? */ - target_frame_size = saturate_cast_double_to_int( - (double)cpi->twopass.gf_group_bits * err_fraction); - - /* Clip to target size to 0 - max_bits (or cpi->twopass.gf_group_bits) - * at the top end. - */ - if (target_frame_size < 0) { - target_frame_size = 0; - } else { - if (target_frame_size > max_bits) target_frame_size = max_bits; - - if (target_frame_size > cpi->twopass.gf_group_bits) { - target_frame_size = (int)cpi->twopass.gf_group_bits; - } - } - - /* Adjust error and bits remaining */ - cpi->twopass.gf_group_error_left -= (int)modified_err; - cpi->twopass.gf_group_bits -= target_frame_size; - - if (cpi->twopass.gf_group_bits < 0) cpi->twopass.gf_group_bits = 0; - - /* Add in the minimum number of bits that is set aside for every frame. */ - target_frame_size += cpi->min_frame_bandwidth; - - /* Every other frame gets a few extra bits */ - if ((cpi->frames_since_golden & 0x01) && - (cpi->frames_till_gf_update_due > 0)) { - target_frame_size += cpi->twopass.alt_extra_bits; - } - - /* Per frame bit target for this frame */ - cpi->per_frame_bandwidth = target_frame_size; -} - -void vp8_second_pass(VP8_COMP *cpi) { - int tmp_q; - int frames_left = - (int)(cpi->twopass.total_stats.count - cpi->common.current_video_frame); - - FIRSTPASS_STATS this_frame; - FIRSTPASS_STATS this_frame_copy; - - double this_frame_intra_error; - double this_frame_coded_error; - - int overhead_bits; - - vp8_zero(this_frame); - - if (!cpi->twopass.stats_in) { - return; - } - - vpx_clear_system_state(); - - if (EOF == input_stats(cpi, &this_frame)) return; - - this_frame_intra_error = this_frame.intra_error; - this_frame_coded_error = this_frame.coded_error; - - /* keyframe and section processing ! */ - if (cpi->twopass.frames_to_key == 0) { - /* Define next KF group and assign bits to it */ - memcpy(&this_frame_copy, &this_frame, sizeof(this_frame)); - find_next_key_frame(cpi, &this_frame_copy); - - /* Special case: Error error_resilient_mode mode does not make much - * sense for two pass but with its current meaning this code is - * designed to stop outlandish behaviour if someone does set it when - * using two pass. It effectively disables GF groups. This is - * temporary code until we decide what should really happen in this - * case. - */ - if (cpi->oxcf.error_resilient_mode) { - cpi->twopass.gf_group_bits = cpi->twopass.kf_group_bits; - cpi->twopass.gf_group_error_left = (int)cpi->twopass.kf_group_error_left; - cpi->baseline_gf_interval = cpi->twopass.frames_to_key; - cpi->frames_till_gf_update_due = cpi->baseline_gf_interval; - cpi->source_alt_ref_pending = 0; - } - } - - /* Is this a GF / ARF (Note that a KF is always also a GF) */ - if (cpi->frames_till_gf_update_due == 0) { - /* Define next gf group and assign bits to it */ - memcpy(&this_frame_copy, &this_frame, sizeof(this_frame)); - define_gf_group(cpi, &this_frame_copy); - - /* If we are going to code an altref frame at the end of the group - * and the current frame is not a key frame.... If the previous - * group used an arf this frame has already benefited from that arf - * boost and it should not be given extra bits If the previous - * group was NOT coded using arf we may want to apply some boost to - * this GF as well - */ - if (cpi->source_alt_ref_pending && (cpi->common.frame_type != KEY_FRAME)) { - /* Assign a standard frames worth of bits from those allocated - * to the GF group - */ - int bak = cpi->per_frame_bandwidth; - memcpy(&this_frame_copy, &this_frame, sizeof(this_frame)); - assign_std_frame_bits(cpi, &this_frame_copy); - cpi->per_frame_bandwidth = bak; - } - } - - /* Otherwise this is an ordinary frame */ - else { - /* Special case: Error error_resilient_mode mode does not make much - * sense for two pass but with its current meaning but this code is - * designed to stop outlandish behaviour if someone does set it - * when using two pass. It effectively disables GF groups. This is - * temporary code till we decide what should really happen in this - * case. - */ - if (cpi->oxcf.error_resilient_mode) { - cpi->frames_till_gf_update_due = cpi->twopass.frames_to_key; - - if (cpi->common.frame_type != KEY_FRAME) { - /* Assign bits from those allocated to the GF group */ - memcpy(&this_frame_copy, &this_frame, sizeof(this_frame)); - assign_std_frame_bits(cpi, &this_frame_copy); - } - } else { - /* Assign bits from those allocated to the GF group */ - memcpy(&this_frame_copy, &this_frame, sizeof(this_frame)); - assign_std_frame_bits(cpi, &this_frame_copy); - } - } - - /* Keep a globally available copy of this and the next frame's iiratio. */ - cpi->twopass.this_iiratio = - (unsigned int)(this_frame_intra_error / - DOUBLE_DIVIDE_CHECK(this_frame_coded_error)); - { - FIRSTPASS_STATS next_frame; - if (lookup_next_frame_stats(cpi, &next_frame) != EOF) { - cpi->twopass.next_iiratio = - (unsigned int)(next_frame.intra_error / - DOUBLE_DIVIDE_CHECK(next_frame.coded_error)); - } - } - - /* Set nominal per second bandwidth for this frame */ - cpi->target_bandwidth = - (int)(cpi->per_frame_bandwidth * cpi->output_framerate); - if (cpi->target_bandwidth < 0) cpi->target_bandwidth = 0; - - /* Account for mv, mode and other overheads. */ - overhead_bits = (int)estimate_modemvcost(cpi, &cpi->twopass.total_left_stats); - - /* Special case code for first frame. */ - if (cpi->common.current_video_frame == 0) { - cpi->twopass.est_max_qcorrection_factor = 1.0; - - int64_t section_target_bandwidth = cpi->twopass.bits_left / frames_left; - section_target_bandwidth = VPXMIN(section_target_bandwidth, INT_MAX); - - /* Set a cq_level in constrained quality mode. */ - if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) { - int est_cq; - - est_cq = estimate_cq(cpi, &cpi->twopass.total_left_stats, - (int)section_target_bandwidth, overhead_bits); - - cpi->cq_target_quality = cpi->oxcf.cq_level; - if (est_cq > cpi->cq_target_quality) cpi->cq_target_quality = est_cq; - } - - /* guess at maxq needed in 2nd pass */ - cpi->twopass.maxq_max_limit = cpi->worst_quality; - cpi->twopass.maxq_min_limit = cpi->best_quality; - - tmp_q = estimate_max_q(cpi, &cpi->twopass.total_left_stats, - (int)section_target_bandwidth, overhead_bits); - - /* Limit the maxq value returned subsequently. - * This increases the risk of overspend or underspend if the initial - * estimate for the clip is bad, but helps prevent excessive - * variation in Q, especially near the end of a clip - * where for example a small overspend may cause Q to crash - */ - cpi->twopass.maxq_max_limit = - ((tmp_q + 32) < cpi->worst_quality) ? (tmp_q + 32) : cpi->worst_quality; - cpi->twopass.maxq_min_limit = - ((tmp_q - 32) > cpi->best_quality) ? (tmp_q - 32) : cpi->best_quality; - - cpi->active_worst_quality = tmp_q; - cpi->ni_av_qi = tmp_q; - } - - /* The last few frames of a clip almost always have to few or too many - * bits and for the sake of over exact rate control we don't want to make - * radical adjustments to the allowed quantizer range just to use up a - * few surplus bits or get beneath the target rate. - */ - else if ((cpi->common.current_video_frame < - (((unsigned int)cpi->twopass.total_stats.count * 255) >> 8)) && - ((cpi->common.current_video_frame + cpi->baseline_gf_interval) < - (unsigned int)cpi->twopass.total_stats.count)) { - if (frames_left < 1) frames_left = 1; - - int64_t section_target_bandwidth = cpi->twopass.bits_left / frames_left; - section_target_bandwidth = VPXMIN(section_target_bandwidth, INT_MAX); - - tmp_q = estimate_max_q(cpi, &cpi->twopass.total_left_stats, - (int)section_target_bandwidth, overhead_bits); - - /* Move active_worst_quality but in a damped way */ - if (tmp_q > cpi->active_worst_quality) { - cpi->active_worst_quality++; - } else if (tmp_q < cpi->active_worst_quality) { - cpi->active_worst_quality--; - } - - cpi->active_worst_quality = - ((cpi->active_worst_quality * 3) + tmp_q + 2) / 4; - } - - cpi->twopass.frames_to_key--; - - /* Update the total stats remaining sturcture */ - subtract_stats(&cpi->twopass.total_left_stats, &this_frame); -} - -static int test_candidate_kf(VP8_COMP *cpi, FIRSTPASS_STATS *last_frame, - FIRSTPASS_STATS *this_frame, - FIRSTPASS_STATS *next_frame) { - int is_viable_kf = 0; - - /* Does the frame satisfy the primary criteria of a key frame - * If so, then examine how well it predicts subsequent frames - */ - if ((this_frame->pcnt_second_ref < 0.10) && - (next_frame->pcnt_second_ref < 0.10) && - ((this_frame->pcnt_inter < 0.05) || - (((this_frame->pcnt_inter - this_frame->pcnt_neutral) < .25) && - ((this_frame->intra_error / - DOUBLE_DIVIDE_CHECK(this_frame->coded_error)) < 2.5) && - ((fabs(last_frame->coded_error - this_frame->coded_error) / - DOUBLE_DIVIDE_CHECK(this_frame->coded_error) > - .40) || - (fabs(last_frame->intra_error - this_frame->intra_error) / - DOUBLE_DIVIDE_CHECK(this_frame->intra_error) > - .40) || - ((next_frame->intra_error / - DOUBLE_DIVIDE_CHECK(next_frame->coded_error)) > 3.5))))) { - int i; - FIRSTPASS_STATS *start_pos; - - FIRSTPASS_STATS local_next_frame; - - double boost_score = 0.0; - double old_boost_score = 0.0; - double decay_accumulator = 1.0; - double next_iiratio; - - memcpy(&local_next_frame, next_frame, sizeof(*next_frame)); - - /* Note the starting file position so we can reset to it */ - start_pos = cpi->twopass.stats_in; - - /* Examine how well the key frame predicts subsequent frames */ - for (i = 0; i < 16; ++i) { - next_iiratio = (IIKFACTOR1 * local_next_frame.intra_error / - DOUBLE_DIVIDE_CHECK(local_next_frame.coded_error)); - - if (next_iiratio > RMAX) next_iiratio = RMAX; - - /* Cumulative effect of decay in prediction quality */ - if (local_next_frame.pcnt_inter > 0.85) { - decay_accumulator = decay_accumulator * local_next_frame.pcnt_inter; - } else { - decay_accumulator = - decay_accumulator * ((0.85 + local_next_frame.pcnt_inter) / 2.0); - } - - /* Keep a running total */ - boost_score += (decay_accumulator * next_iiratio); - - /* Test various breakout clauses */ - if ((local_next_frame.pcnt_inter < 0.05) || (next_iiratio < 1.5) || - (((local_next_frame.pcnt_inter - local_next_frame.pcnt_neutral) < - 0.20) && - (next_iiratio < 3.0)) || - ((boost_score - old_boost_score) < 0.5) || - (local_next_frame.intra_error < 200)) { - break; - } - - old_boost_score = boost_score; - - /* Get the next frame details */ - if (EOF == input_stats(cpi, &local_next_frame)) break; - } - - /* If there is tolerable prediction for at least the next 3 frames - * then break out else discard this pottential key frame and move on - */ - if (boost_score > 5.0 && (i > 3)) { - is_viable_kf = 1; - } else { - /* Reset the file position */ - reset_fpf_position(cpi, start_pos); - - is_viable_kf = 0; - } - } - - return is_viable_kf; -} -static void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) { - int i, j; - FIRSTPASS_STATS last_frame; - FIRSTPASS_STATS first_frame; - FIRSTPASS_STATS next_frame; - FIRSTPASS_STATS *start_position; - - double decay_accumulator = 1.0; - double boost_score = 0; - double old_boost_score = 0.0; - double loop_decay_rate; - - double kf_mod_err = 0.0; - double kf_group_err = 0.0; - double kf_group_intra_err = 0.0; - double kf_group_coded_err = 0.0; - double recent_loop_decay[8] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }; - - memset(&next_frame, 0, sizeof(next_frame)); - - vpx_clear_system_state(); - start_position = cpi->twopass.stats_in; - - cpi->common.frame_type = KEY_FRAME; - - /* is this a forced key frame by interval */ - cpi->this_key_frame_forced = cpi->next_key_frame_forced; - - /* Clear the alt ref active flag as this can never be active on a key - * frame - */ - cpi->source_alt_ref_active = 0; - - /* Kf is always a gf so clear frames till next gf counter */ - cpi->frames_till_gf_update_due = 0; - - cpi->twopass.frames_to_key = 1; - - /* Take a copy of the initial frame details */ - memcpy(&first_frame, this_frame, sizeof(*this_frame)); - - cpi->twopass.kf_group_bits = 0; - cpi->twopass.kf_group_error_left = 0; - - kf_mod_err = calculate_modified_err(cpi, this_frame); - - /* find the next keyframe */ - i = 0; - while (cpi->twopass.stats_in < cpi->twopass.stats_in_end) { - /* Accumulate kf group error */ - kf_group_err += calculate_modified_err(cpi, this_frame); - - /* These figures keep intra and coded error counts for all frames - * including key frames in the group. The effect of the key frame - * itself can be subtracted out using the first_frame data - * collected above - */ - kf_group_intra_err += this_frame->intra_error; - kf_group_coded_err += this_frame->coded_error; - - /* Load the next frame's stats. */ - memcpy(&last_frame, this_frame, sizeof(*this_frame)); - input_stats(cpi, this_frame); - - /* Provided that we are not at the end of the file... */ - if (cpi->oxcf.auto_key && - lookup_next_frame_stats(cpi, &next_frame) != EOF) { - /* Normal scene cut check */ - if ((i >= MIN_GF_INTERVAL) && - test_candidate_kf(cpi, &last_frame, this_frame, &next_frame)) { - break; - } - - /* How fast is prediction quality decaying */ - loop_decay_rate = get_prediction_decay_rate(&next_frame); - - /* We want to know something about the recent past... rather than - * as used elsewhere where we are concened with decay in prediction - * quality since the last GF or KF. - */ - recent_loop_decay[i % 8] = loop_decay_rate; - decay_accumulator = 1.0; - for (j = 0; j < 8; ++j) { - decay_accumulator = decay_accumulator * recent_loop_decay[j]; - } - - /* Special check for transition or high motion followed by a - * static scene. - */ - if (detect_transition_to_still(cpi, i, - ((int)(cpi->key_frame_frequency) - (int)i), - loop_decay_rate, decay_accumulator)) { - break; - } - - /* Step on to the next frame */ - cpi->twopass.frames_to_key++; - - /* If we don't have a real key frame within the next two - * forcekeyframeevery intervals then break out of the loop. - */ - if (cpi->twopass.frames_to_key >= 2 * (int)cpi->key_frame_frequency) { - break; - } - } else { - cpi->twopass.frames_to_key++; - } - - i++; - } - - /* If there is a max kf interval set by the user we must obey it. - * We already breakout of the loop above at 2x max. - * This code centers the extra kf if the actual natural - * interval is between 1x and 2x - */ - if (cpi->oxcf.auto_key && - cpi->twopass.frames_to_key > (int)cpi->key_frame_frequency) { - FIRSTPASS_STATS *current_pos = cpi->twopass.stats_in; - FIRSTPASS_STATS tmp_frame; - - cpi->twopass.frames_to_key /= 2; - - /* Copy first frame details */ - memcpy(&tmp_frame, &first_frame, sizeof(first_frame)); - - /* Reset to the start of the group */ - reset_fpf_position(cpi, start_position); - - kf_group_err = 0; - kf_group_intra_err = 0; - kf_group_coded_err = 0; - - /* Rescan to get the correct error data for the forced kf group */ - for (i = 0; i < cpi->twopass.frames_to_key; ++i) { - /* Accumulate kf group errors */ - kf_group_err += calculate_modified_err(cpi, &tmp_frame); - kf_group_intra_err += tmp_frame.intra_error; - kf_group_coded_err += tmp_frame.coded_error; - - /* Load a the next frame's stats */ - input_stats(cpi, &tmp_frame); - } - - /* Reset to the start of the group */ - reset_fpf_position(cpi, current_pos); - - cpi->next_key_frame_forced = 1; - } else { - cpi->next_key_frame_forced = 0; - } - - /* Special case for the last frame of the file */ - if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end) { - /* Accumulate kf group error */ - kf_group_err += calculate_modified_err(cpi, this_frame); - - /* These figures keep intra and coded error counts for all frames - * including key frames in the group. The effect of the key frame - * itself can be subtracted out using the first_frame data - * collected above - */ - kf_group_intra_err += this_frame->intra_error; - kf_group_coded_err += this_frame->coded_error; - } - - /* Calculate the number of bits that should be assigned to the kf group. */ - if ((cpi->twopass.bits_left > 0) && - (cpi->twopass.modified_error_left > 0.0)) { - /* Max for a single normal frame (not key frame) */ - int max_bits = frame_max_bits(cpi); - - /* Maximum bits for the kf group */ - int64_t max_grp_bits; - - /* Default allocation based on bits left and relative - * complexity of the section - */ - cpi->twopass.kf_group_bits = - (int64_t)(cpi->twopass.bits_left * - (kf_group_err / cpi->twopass.modified_error_left)); - - /* Clip based on maximum per frame rate defined by the user. */ - max_grp_bits = (int64_t)max_bits * (int64_t)cpi->twopass.frames_to_key; - if (cpi->twopass.kf_group_bits > max_grp_bits) { - cpi->twopass.kf_group_bits = max_grp_bits; - } - - /* Additional special case for CBR if buffer is getting full. */ - if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { - int64_t opt_buffer_lvl = cpi->oxcf.optimal_buffer_level; - int64_t buffer_lvl = cpi->buffer_level; - - /* If the buffer is near or above the optimal and this kf group is - * not being allocated much then increase the allocation a bit. - */ - if (buffer_lvl >= opt_buffer_lvl) { - int64_t high_water_mark = - (opt_buffer_lvl + cpi->oxcf.maximum_buffer_size) >> 1; - - int64_t av_group_bits; - - /* Av bits per frame * number of frames */ - av_group_bits = (int64_t)cpi->av_per_frame_bandwidth * - (int64_t)cpi->twopass.frames_to_key; - - /* We are at or above the maximum. */ - if (cpi->buffer_level >= high_water_mark) { - int64_t min_group_bits; - - min_group_bits = - av_group_bits + (int64_t)(buffer_lvl - high_water_mark); - - if (cpi->twopass.kf_group_bits < min_group_bits) { - cpi->twopass.kf_group_bits = min_group_bits; - } - } - /* We are above optimal but below the maximum */ - else if (cpi->twopass.kf_group_bits < av_group_bits) { - int64_t bits_below_av = av_group_bits - cpi->twopass.kf_group_bits; - - cpi->twopass.kf_group_bits += - (int64_t)((double)bits_below_av * - (double)(buffer_lvl - opt_buffer_lvl) / - (double)(high_water_mark - opt_buffer_lvl)); - } - } - } - } else { - cpi->twopass.kf_group_bits = 0; - } - - /* Reset the first pass file position */ - reset_fpf_position(cpi, start_position); - - /* determine how big to make this keyframe based on how well the - * subsequent frames use inter blocks - */ - decay_accumulator = 1.0; - boost_score = 0.0; - - for (i = 0; i < cpi->twopass.frames_to_key; ++i) { - double r; - - if (EOF == input_stats(cpi, &next_frame)) break; - - if (next_frame.intra_error > cpi->twopass.kf_intra_err_min) { - r = (IIKFACTOR2 * next_frame.intra_error / - DOUBLE_DIVIDE_CHECK(next_frame.coded_error)); - } else { - r = (IIKFACTOR2 * cpi->twopass.kf_intra_err_min / - DOUBLE_DIVIDE_CHECK(next_frame.coded_error)); - } - - if (r > RMAX) r = RMAX; - - /* How fast is prediction quality decaying */ - loop_decay_rate = get_prediction_decay_rate(&next_frame); - - decay_accumulator = decay_accumulator * loop_decay_rate; - decay_accumulator = decay_accumulator < 0.1 ? 0.1 : decay_accumulator; - - boost_score += (decay_accumulator * r); - - if ((i > MIN_GF_INTERVAL) && ((boost_score - old_boost_score) < 1.0)) { - break; - } - - old_boost_score = boost_score; - } - - if (1) { - FIRSTPASS_STATS sectionstats; - double Ratio; - - zero_stats(§ionstats); - reset_fpf_position(cpi, start_position); - - for (i = 0; i < cpi->twopass.frames_to_key; ++i) { - input_stats(cpi, &next_frame); - accumulate_stats(§ionstats, &next_frame); - } - - avg_stats(§ionstats); - - cpi->twopass.section_intra_rating = - (unsigned int)(sectionstats.intra_error / - DOUBLE_DIVIDE_CHECK(sectionstats.coded_error)); - - Ratio = sectionstats.intra_error / - DOUBLE_DIVIDE_CHECK(sectionstats.coded_error); - cpi->twopass.section_max_qfactor = 1.0 - ((Ratio - 10.0) * 0.025); - - if (cpi->twopass.section_max_qfactor < 0.80) { - cpi->twopass.section_max_qfactor = 0.80; - } - } - - /* When using CBR apply additional buffer fullness related upper limits */ - if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { - double max_boost; - - if (cpi->drop_frames_allowed) { - int df_buffer_level = (int)(cpi->oxcf.drop_frames_water_mark * - (cpi->oxcf.optimal_buffer_level / 100)); - - if (cpi->buffer_level > df_buffer_level) { - max_boost = - ((double)((cpi->buffer_level - df_buffer_level) * 2 / 3) * 16.0) / - DOUBLE_DIVIDE_CHECK((double)cpi->av_per_frame_bandwidth); - } else { - max_boost = 0.0; - } - } else if (cpi->buffer_level > 0) { - max_boost = ((double)(cpi->buffer_level * 2 / 3) * 16.0) / - DOUBLE_DIVIDE_CHECK((double)cpi->av_per_frame_bandwidth); - } else { - max_boost = 0.0; - } - - if (boost_score > max_boost) boost_score = max_boost; - } - - /* Reset the first pass file position */ - reset_fpf_position(cpi, start_position); - - /* Work out how many bits to allocate for the key frame itself */ - if (1) { - int kf_boost = (int)boost_score; - int allocation_chunks; - int Counter = cpi->twopass.frames_to_key; - int alt_kf_bits; - YV12_BUFFER_CONFIG *lst_yv12 = &cpi->common.yv12_fb[cpi->common.lst_fb_idx]; -/* Min boost based on kf interval */ -#if 0 - - while ((kf_boost < 48) && (Counter > 0)) - { - Counter -= 2; - kf_boost ++; - } - -#endif - - if (kf_boost < 48) { - kf_boost += ((Counter + 1) >> 1); - - if (kf_boost > 48) kf_boost = 48; - } - - /* bigger frame sizes need larger kf boosts, smaller frames smaller - * boosts... - */ - if ((lst_yv12->y_width * lst_yv12->y_height) > (320 * 240)) { - kf_boost += 2 * (lst_yv12->y_width * lst_yv12->y_height) / (320 * 240); - } else if ((lst_yv12->y_width * lst_yv12->y_height) < (320 * 240)) { - kf_boost -= 4 * (320 * 240) / (lst_yv12->y_width * lst_yv12->y_height); - } - - /* Min KF boost */ - kf_boost = (int)((double)kf_boost * 100.0) >> 4; /* Scale 16 to 100 */ - if (kf_boost < 250) kf_boost = 250; - - /* - * We do three calculations for kf size. - * The first is based on the error score for the whole kf group. - * The second (optionaly) on the key frames own error if this is - * smaller than the average for the group. - * The final one insures that the frame receives at least the - * allocation it would have received based on its own error score vs - * the error score remaining - * Special case if the sequence appears almost totaly static - * as measured by the decay accumulator. In this case we want to - * spend almost all of the bits on the key frame. - * cpi->twopass.frames_to_key-1 because key frame itself is taken - * care of by kf_boost. - */ - if (decay_accumulator >= 0.99) { - allocation_chunks = ((cpi->twopass.frames_to_key - 1) * 10) + kf_boost; - } else { - allocation_chunks = ((cpi->twopass.frames_to_key - 1) * 100) + kf_boost; - } - - /* Normalize Altboost and allocations chunck down to prevent overflow */ - while (kf_boost > 1000) { - kf_boost /= 2; - allocation_chunks /= 2; - } - - cpi->twopass.kf_group_bits = - (cpi->twopass.kf_group_bits < 0) ? 0 : cpi->twopass.kf_group_bits; - - /* Calculate the number of bits to be spent on the key frame */ - cpi->twopass.kf_bits = - (int)((double)kf_boost * - ((double)cpi->twopass.kf_group_bits / (double)allocation_chunks)); - - /* Apply an additional limit for CBR */ - if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { - if (cpi->twopass.kf_bits > (int)((3 * cpi->buffer_level) >> 2)) { - cpi->twopass.kf_bits = (int)((3 * cpi->buffer_level) >> 2); - } - } - - /* If the key frame is actually easier than the average for the - * kf group (which does sometimes happen... eg a blank intro frame) - * Then use an alternate calculation based on the kf error score - * which should give a smaller key frame. - */ - if (kf_mod_err < kf_group_err / cpi->twopass.frames_to_key) { - double alt_kf_grp_bits = - ((double)cpi->twopass.bits_left * - (kf_mod_err * (double)cpi->twopass.frames_to_key) / - DOUBLE_DIVIDE_CHECK(cpi->twopass.modified_error_left)); - - alt_kf_bits = (int)((double)kf_boost * - (alt_kf_grp_bits / (double)allocation_chunks)); - - if (cpi->twopass.kf_bits > alt_kf_bits) { - cpi->twopass.kf_bits = alt_kf_bits; - } - } - /* Else if it is much harder than other frames in the group make sure - * it at least receives an allocation in keeping with its relative - * error score - */ - else { - alt_kf_bits = (int)((double)cpi->twopass.bits_left * - (kf_mod_err / DOUBLE_DIVIDE_CHECK( - cpi->twopass.modified_error_left))); - - if (alt_kf_bits > cpi->twopass.kf_bits) { - cpi->twopass.kf_bits = alt_kf_bits; - } - } - - cpi->twopass.kf_group_bits -= cpi->twopass.kf_bits; - /* Add in the minimum frame allowance */ - cpi->twopass.kf_bits += cpi->min_frame_bandwidth; - - /* Peer frame bit target for this frame */ - cpi->per_frame_bandwidth = cpi->twopass.kf_bits; - - /* Convert to a per second bitrate */ - cpi->target_bandwidth = (int)(cpi->twopass.kf_bits * cpi->output_framerate); - } - - /* Note the total error score of the kf group minus the key frame itself */ - cpi->twopass.kf_group_error_left = (int)(kf_group_err - kf_mod_err); - - /* Adjust the count of total modified error left. The count of bits left - * is adjusted elsewhere based on real coded frame sizes - */ - cpi->twopass.modified_error_left -= kf_group_err; - - if (cpi->oxcf.allow_spatial_resampling) { - int resample_trigger = 0; - int last_kf_resampled = 0; - int kf_q; - int scale_val = 0; - int hr, hs, vr, vs; - int new_width = cpi->oxcf.Width; - int new_height = cpi->oxcf.Height; - - int projected_buffer_level; - int tmp_q; - - double projected_bits_perframe; - double group_iiratio = (kf_group_intra_err - first_frame.intra_error) / - (kf_group_coded_err - first_frame.coded_error); - double err_per_frame = kf_group_err / cpi->twopass.frames_to_key; - double bits_per_frame; - double av_bits_per_frame; - double effective_size_ratio; - - if ((cpi->common.Width != cpi->oxcf.Width) || - (cpi->common.Height != cpi->oxcf.Height)) { - last_kf_resampled = 1; - } - - /* Set back to unscaled by defaults */ - cpi->common.horiz_scale = VP8E_NORMAL; - cpi->common.vert_scale = VP8E_NORMAL; - - /* Calculate Average bits per frame. */ - av_bits_per_frame = - cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK(cpi->framerate); - - /* CBR... Use the clip average as the target for deciding resample */ - if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { - bits_per_frame = av_bits_per_frame; - } - - /* In VBR we want to avoid downsampling in easy section unless we - * are under extreme pressure So use the larger of target bitrate - * for this section or average bitrate for sequence - */ - else { - /* This accounts for how hard the section is... */ - bits_per_frame = - (double)(cpi->twopass.kf_group_bits / cpi->twopass.frames_to_key); - - /* Don't turn to resampling in easy sections just because they - * have been assigned a small number of bits - */ - if (bits_per_frame < av_bits_per_frame) { - bits_per_frame = av_bits_per_frame; - } - } - - /* bits_per_frame should comply with our minimum */ - if (bits_per_frame < (cpi->oxcf.target_bandwidth * - cpi->oxcf.two_pass_vbrmin_section / 100)) { - bits_per_frame = (cpi->oxcf.target_bandwidth * - cpi->oxcf.two_pass_vbrmin_section / 100); - } - - /* Work out if spatial resampling is necessary */ - kf_q = estimate_kf_group_q(cpi, err_per_frame, (int)bits_per_frame, - group_iiratio); - - /* If we project a required Q higher than the maximum allowed Q then - * make a guess at the actual size of frames in this section - */ - projected_bits_perframe = bits_per_frame; - tmp_q = kf_q; - - while (tmp_q > cpi->worst_quality) { - projected_bits_perframe *= 1.04; - tmp_q--; - } - - /* Guess at buffer level at the end of the section */ - projected_buffer_level = - (int)(cpi->buffer_level - - (int)((projected_bits_perframe - av_bits_per_frame) * - cpi->twopass.frames_to_key)); - - /* The trigger for spatial resampling depends on the various - * parameters such as whether we are streaming (CBR) or VBR. - */ - if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { - /* Trigger resample if we are projected to fall below down - * sample level or resampled last time and are projected to - * remain below the up sample level - */ - if ((projected_buffer_level < (cpi->oxcf.resample_down_water_mark * - cpi->oxcf.optimal_buffer_level / 100)) || - (last_kf_resampled && - (projected_buffer_level < (cpi->oxcf.resample_up_water_mark * - cpi->oxcf.optimal_buffer_level / 100)))) { - resample_trigger = 1; - } else { - resample_trigger = 0; - } - } else { - int64_t clip_bits = (int64_t)(cpi->twopass.total_stats.count * - cpi->oxcf.target_bandwidth / - DOUBLE_DIVIDE_CHECK(cpi->framerate)); - int64_t over_spend = cpi->oxcf.starting_buffer_level - cpi->buffer_level; - - /* If triggered last time the threshold for triggering again is - * reduced: - * - * Projected Q higher than allowed and Overspend > 5% of total - * bits - */ - if ((last_kf_resampled && (kf_q > cpi->worst_quality)) || - ((kf_q > cpi->worst_quality) && (over_spend > clip_bits / 20))) { - resample_trigger = 1; - } else { - resample_trigger = 0; - } - } - - if (resample_trigger) { - while ((kf_q >= cpi->worst_quality) && (scale_val < 6)) { - scale_val++; - - cpi->common.vert_scale = vscale_lookup[scale_val]; - cpi->common.horiz_scale = hscale_lookup[scale_val]; - - Scale2Ratio(cpi->common.horiz_scale, &hr, &hs); - Scale2Ratio(cpi->common.vert_scale, &vr, &vs); - - new_width = ((hs - 1) + (cpi->oxcf.Width * hr)) / hs; - new_height = ((vs - 1) + (cpi->oxcf.Height * vr)) / vs; - - /* Reducing the area to 1/4 does not reduce the complexity - * (err_per_frame) to 1/4... effective_sizeratio attempts - * to provide a crude correction for this - */ - effective_size_ratio = (double)(new_width * new_height) / - (double)(cpi->oxcf.Width * cpi->oxcf.Height); - effective_size_ratio = (1.0 + (3.0 * effective_size_ratio)) / 4.0; - - /* Now try again and see what Q we get with the smaller - * image size - */ - kf_q = estimate_kf_group_q(cpi, err_per_frame * effective_size_ratio, - (int)bits_per_frame, group_iiratio); - } - } - - if ((cpi->common.Width != new_width) || - (cpi->common.Height != new_height)) { - cpi->common.Width = new_width; - cpi->common.Height = new_height; - vp8_alloc_compressor_data(cpi); - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/firstpass.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/firstpass.h deleted file mode 100644 index f5490f1e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/firstpass.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_FIRSTPASS_H_ -#define VPX_VP8_ENCODER_FIRSTPASS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -extern void vp8_init_first_pass(VP8_COMP *cpi); -extern void vp8_first_pass(VP8_COMP *cpi); -extern void vp8_end_first_pass(VP8_COMP *cpi); - -extern void vp8_init_second_pass(VP8_COMP *cpi); -extern void vp8_second_pass(VP8_COMP *cpi); -extern void vp8_end_second_pass(VP8_COMP *cpi); - -extern size_t vp8_firstpass_stats_sz(unsigned int mb_count); -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_FIRSTPASS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/lookahead.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/lookahead.c deleted file mode 100644 index 49f851d0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/lookahead.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2011 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include -#include "vpx_config.h" -#include "lookahead.h" -#include "vp8/common/extend.h" - -#define MAX_LAG_BUFFERS (CONFIG_REALTIME_ONLY ? 1 : 25) - -struct lookahead_ctx { - unsigned int max_sz; /* Absolute size of the queue */ - unsigned int sz; /* Number of buffers currently in the queue */ - unsigned int read_idx; /* Read index */ - unsigned int write_idx; /* Write index */ - struct lookahead_entry *buf; /* Buffer list */ -}; - -/* Return the buffer at the given absolute index and increment the index */ -static struct lookahead_entry *pop(struct lookahead_ctx *ctx, - unsigned int *idx) { - unsigned int index = *idx; - struct lookahead_entry *buf = ctx->buf + index; - - assert(index < ctx->max_sz); - if (++index >= ctx->max_sz) index -= ctx->max_sz; - *idx = index; - return buf; -} - -void vp8_lookahead_destroy(struct lookahead_ctx *ctx) { - if (ctx) { - if (ctx->buf) { - unsigned int i; - - for (i = 0; i < ctx->max_sz; ++i) { - vp8_yv12_de_alloc_frame_buffer(&ctx->buf[i].img); - } - free(ctx->buf); - } - free(ctx); - } -} - -struct lookahead_ctx *vp8_lookahead_init(unsigned int width, - unsigned int height, - unsigned int depth) { - struct lookahead_ctx *ctx = NULL; - unsigned int i; - - /* Clamp the lookahead queue depth */ - if (depth < 1) { - depth = 1; - } else if (depth > MAX_LAG_BUFFERS) { - depth = MAX_LAG_BUFFERS; - } - - /* Keep last frame in lookahead buffer by increasing depth by 1.*/ - depth += 1; - - /* Align the buffer dimensions */ - width = (width + 15) & ~15u; - height = (height + 15) & ~15u; - - /* Allocate the lookahead structures */ - ctx = calloc(1, sizeof(*ctx)); - if (ctx) { - ctx->max_sz = depth; - ctx->buf = calloc(depth, sizeof(*ctx->buf)); - if (!ctx->buf) goto bail; - for (i = 0; i < depth; ++i) { - if (vp8_yv12_alloc_frame_buffer(&ctx->buf[i].img, width, height, - VP8BORDERINPIXELS)) { - goto bail; - } - } - } - return ctx; -bail: - vp8_lookahead_destroy(ctx); - return NULL; -} - -int vp8_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src, - int64_t ts_start, int64_t ts_end, unsigned int flags, - unsigned char *active_map) { - struct lookahead_entry *buf; - int row, col, active_end; - int mb_rows = (src->y_height + 15) >> 4; - int mb_cols = (src->y_width + 15) >> 4; - - if (ctx->sz + 2 > ctx->max_sz) return 1; - ctx->sz++; - buf = pop(ctx, &ctx->write_idx); - - /* Only do this partial copy if the following conditions are all met: - * 1. Lookahead queue has has size of 1. - * 2. Active map is provided. - * 3. This is not a key frame, golden nor altref frame. - */ - if (ctx->max_sz == 1 && active_map && !flags) { - for (row = 0; row < mb_rows; ++row) { - col = 0; - - while (1) { - /* Find the first active macroblock in this row. */ - for (; col < mb_cols; ++col) { - if (active_map[col]) break; - } - - /* No more active macroblock in this row. */ - if (col == mb_cols) break; - - /* Find the end of active region in this row. */ - active_end = col; - - for (; active_end < mb_cols; ++active_end) { - if (!active_map[active_end]) break; - } - - /* Only copy this active region. */ - vp8_copy_and_extend_frame_with_rect(src, &buf->img, row << 4, col << 4, - 16, (active_end - col) << 4); - - /* Start again from the end of this active region. */ - col = active_end; - } - - active_map += mb_cols; - } - } else { - vp8_copy_and_extend_frame(src, &buf->img); - } - buf->ts_start = ts_start; - buf->ts_end = ts_end; - buf->flags = flags; - return 0; -} - -struct lookahead_entry *vp8_lookahead_pop(struct lookahead_ctx *ctx, - int drain) { - struct lookahead_entry *buf = NULL; - - assert(ctx != NULL); - if (ctx->sz && (drain || ctx->sz == ctx->max_sz - 1)) { - buf = pop(ctx, &ctx->read_idx); - ctx->sz--; - } - return buf; -} - -struct lookahead_entry *vp8_lookahead_peek(struct lookahead_ctx *ctx, - unsigned int index, int direction) { - struct lookahead_entry *buf = NULL; - - if (direction == PEEK_FORWARD) { - assert(index < ctx->max_sz - 1); - if (index < ctx->sz) { - index += ctx->read_idx; - if (index >= ctx->max_sz) index -= ctx->max_sz; - buf = ctx->buf + index; - } - } else if (direction == PEEK_BACKWARD) { - assert(index == 1); - - if (ctx->read_idx == 0) { - index = ctx->max_sz - 1; - } else { - index = ctx->read_idx - index; - } - buf = ctx->buf + index; - } - - return buf; -} - -unsigned int vp8_lookahead_depth(struct lookahead_ctx *ctx) { return ctx->sz; } diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/lookahead.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/lookahead.h deleted file mode 100644 index bf040119..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/lookahead.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2011 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_VP8_ENCODER_LOOKAHEAD_H_ -#define VPX_VP8_ENCODER_LOOKAHEAD_H_ -#include "vpx_scale/yv12config.h" -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct lookahead_entry { - YV12_BUFFER_CONFIG img; - int64_t ts_start; - int64_t ts_end; - unsigned int flags; -}; - -struct lookahead_ctx; - -/**\brief Initializes the lookahead stage - * - * The lookahead stage is a queue of frame buffers on which some analysis - * may be done when buffers are enqueued. - * - * - */ -struct lookahead_ctx *vp8_lookahead_init(unsigned int width, - unsigned int height, - unsigned int depth); - -/**\brief Destroys the lookahead stage - * - */ -void vp8_lookahead_destroy(struct lookahead_ctx *ctx); - -/**\brief Enqueue a source buffer - * - * This function will copy the source image into a new framebuffer with - * the expected stride/border. - * - * If active_map is non-NULL and there is only one frame in the queue, then copy - * only active macroblocks. - * - * \param[in] ctx Pointer to the lookahead context - * \param[in] src Pointer to the image to enqueue - * \param[in] ts_start Timestamp for the start of this frame - * \param[in] ts_end Timestamp for the end of this frame - * \param[in] flags Flags set on this frame - * \param[in] active_map Map that specifies which macroblock is active - */ -int vp8_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src, - int64_t ts_start, int64_t ts_end, unsigned int flags, - unsigned char *active_map); - -/**\brief Get the next source buffer to encode - * - * - * \param[in] ctx Pointer to the lookahead context - * \param[in] drain Flag indicating the buffer should be drained - * (return a buffer regardless of the current queue depth) - * - * \retval NULL, if drain set and queue is empty - * \retval NULL, if drain not set and queue not of the configured depth - * - */ -struct lookahead_entry *vp8_lookahead_pop(struct lookahead_ctx *ctx, int drain); - -#define PEEK_FORWARD 1 -#define PEEK_BACKWARD (-1) -/**\brief Get a future source buffer to encode - * - * \param[in] ctx Pointer to the lookahead context - * \param[in] index Index of the frame to be returned, 0 == next frame - * - * \retval NULL, if no buffer exists at the specified index - * - */ -struct lookahead_entry *vp8_lookahead_peek(struct lookahead_ctx *ctx, - unsigned int index, int direction); - -/**\brief Get the number of frames currently in the lookahead queue - * - * \param[in] ctx Pointer to the lookahead context - */ -unsigned int vp8_lookahead_depth(struct lookahead_ctx *ctx); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_LOOKAHEAD_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/loongarch/dct_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/loongarch/dct_lsx.c deleted file mode 100644 index a08d4d3f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/loongarch/dct_lsx.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vp8_rtcd.h" -#include "vpx_util/loongson_intrinsics.h" - -#define LSX_TRANSPOSE4x4_H(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ - { \ - __m128i _s0, _s1, _s2, _s3, _t0, _t1, _t2, _t3; \ - \ - DUP2_ARG2(__lsx_vilvl_h, _in2, _in0, _in3, _in1, _s0, _s1); \ - DUP2_ARG2(__lsx_vilvh_h, _in2, _in0, _in3, _in1, _s2, _s3); \ - _t0 = __lsx_vilvl_h(_s1, _s0); \ - _t1 = __lsx_vilvh_h(_s1, _s0); \ - _t2 = __lsx_vilvl_h(_s3, _s2); \ - _t3 = __lsx_vilvh_h(_s3, _s2); \ - DUP2_ARG2(__lsx_vpickev_d, _t2, _t0, _t3, _t1, _out0, _out2); \ - DUP2_ARG2(__lsx_vpickod_d, _t2, _t0, _t3, _t1, _out1, _out3); \ - } - -#define SET_DOTP_VALUES(coeff, val0, val1, val2, const1, const2) \ - { \ - __m128i tmp0_m, tmp1_m, tmp2_m; \ - \ - tmp0_m = __lsx_vreplvei_h(coeff, val0); \ - DUP2_ARG2(__lsx_vreplvei_h, coeff, val1, coeff, val2, tmp1_m, tmp2_m); \ - DUP2_ARG2(__lsx_vpackev_h, tmp1_m, tmp0_m, tmp0_m, tmp2_m, const1, \ - const2); \ - } - -#define RET_1_IF_NZERO_H(_in) \ - ({ \ - __m128i tmp_m; \ - __m128i one_m = __lsx_vldi(0x401); \ - __m128i max_m = __lsx_vldi(0xFF); \ - \ - tmp_m = __lsx_vseqi_h(_in, 0); \ - tmp_m = __lsx_vxor_v(tmp_m, max_m); \ - tmp_m = __lsx_vand_v(tmp_m, one_m); \ - \ - tmp_m; \ - }) - -void vp8_short_fdct4x4_lsx(int16_t *input, int16_t *output, int32_t pitch) { - __m128i in0, in1, in2, in3; - __m128i tmp0, tmp1, tmp2, tmp3, const0, const1; - __m128i coeff = { 0x38a4eb1814e808a9, 0x659061a82ee01d4c }; - __m128i out0, out1, out2, out3; - __m128i zero = __lsx_vldi(0); - int32_t pitch2 = pitch << 1; - int32_t pitch3 = pitch2 + pitch; - - in0 = __lsx_vld(input, 0); - DUP2_ARG2(__lsx_vldx, input, pitch, input, pitch2, in1, in2); - in3 = __lsx_vldx(input, pitch3); - - LSX_TRANSPOSE4x4_H(in0, in1, in2, in3, in0, in1, in2, in3); - LSX_BUTTERFLY_4_H(in0, in1, in2, in3, tmp0, tmp1, in1, in3); - DUP4_ARG2(__lsx_vslli_h, tmp0, 3, tmp1, 3, in1, 3, in3, 3, tmp0, tmp1, in1, - in3); - in0 = __lsx_vadd_h(tmp0, tmp1); - in2 = __lsx_vsub_h(tmp0, tmp1); - SET_DOTP_VALUES(coeff, 0, 1, 2, const0, const1); - tmp0 = __lsx_vilvl_h(in3, in1); - in1 = __lsx_vreplvei_h(coeff, 3); - out0 = __lsx_vpackev_h(zero, in1); - coeff = __lsx_vilvl_h(zero, coeff); - out1 = __lsx_vreplvei_w(coeff, 0); - DUP2_ARG3(__lsx_vdp2add_w_h, out0, tmp0, const0, out1, tmp0, const1, out0, - out1); - DUP2_ARG3(__lsx_vsrani_h_w, out0, out0, 12, out1, out1, 12, in1, in3); - LSX_TRANSPOSE4x4_H(in0, in1, in2, in3, in0, in1, in2, in3); - LSX_BUTTERFLY_4_H(in0, in1, in2, in3, tmp0, tmp1, in1, in3); - tmp2 = __lsx_vadd_h(tmp0, tmp1); - tmp3 = __lsx_vsub_h(tmp0, tmp1); - DUP2_ARG2(__lsx_vaddi_hu, tmp2, 7, tmp3, 7, in0, in2); - DUP2_ARG2(__lsx_vsrai_h, in0, 4, in2, 4, in0, in2); - DUP2_ARG2(__lsx_vilvl_h, zero, in0, zero, in2, out0, out2); - tmp1 = RET_1_IF_NZERO_H(in3); - DUP2_ARG2(__lsx_vilvl_h, zero, tmp1, in3, in1, tmp1, tmp0); - DUP2_ARG2(__lsx_vreplvei_w, coeff, 2, coeff, 3, out3, out1); - out3 = __lsx_vadd_w(out3, out1); - out1 = __lsx_vreplvei_w(coeff, 1); - DUP2_ARG3(__lsx_vdp2add_w_h, out1, tmp0, const0, out3, tmp0, const1, out1, - out3); - DUP2_ARG2(__lsx_vsrai_w, out1, 16, out3, 16, out1, out3); - out1 = __lsx_vadd_w(out1, tmp1); - DUP2_ARG2(__lsx_vpickev_h, out1, out0, out3, out2, in0, in2); - __lsx_vst(in0, output, 0); - __lsx_vst(in2, output, 16); -} - -void vp8_short_fdct8x4_lsx(int16_t *input, int16_t *output, int32_t pitch) { - __m128i in0, in1, in2, in3, temp0, temp1, tmp0, tmp1; - __m128i const0, const1, const2, vec0_w, vec1_w, vec2_w, vec3_w; - __m128i coeff = { 0x38a4eb1814e808a9, 0x659061a82ee01d4c }; - __m128i zero = __lsx_vldi(0); - int32_t pitch2 = pitch << 1; - int32_t pitch3 = pitch2 + pitch; - - in0 = __lsx_vld(input, 0); - DUP2_ARG2(__lsx_vldx, input, pitch, input, pitch2, in1, in2); - in3 = __lsx_vldx(input, pitch3); - LSX_TRANSPOSE4x4_H(in0, in1, in2, in3, in0, in1, in2, in3); - - LSX_BUTTERFLY_4_H(in0, in1, in2, in3, temp0, temp1, in1, in3); - DUP4_ARG2(__lsx_vslli_h, temp0, 3, temp1, 3, in1, 3, in3, 3, temp0, temp1, - in1, in3); - in0 = __lsx_vadd_h(temp0, temp1); - in2 = __lsx_vsub_h(temp0, temp1); - SET_DOTP_VALUES(coeff, 0, 1, 2, const1, const2); - temp0 = __lsx_vreplvei_h(coeff, 3); - vec1_w = __lsx_vpackev_h(zero, temp0); - coeff = __lsx_vilvh_h(zero, coeff); - vec3_w = __lsx_vreplvei_w(coeff, 0); - tmp1 = __lsx_vilvl_h(in3, in1); - tmp0 = __lsx_vilvh_h(in3, in1); - vec0_w = vec1_w; - vec2_w = vec3_w; - DUP4_ARG3(__lsx_vdp2add_w_h, vec0_w, tmp1, const1, vec1_w, tmp0, const1, - vec2_w, tmp1, const2, vec3_w, tmp0, const2, vec0_w, vec1_w, vec2_w, - vec3_w); - DUP2_ARG3(__lsx_vsrani_h_w, vec1_w, vec0_w, 12, vec3_w, vec2_w, 12, in1, in3); - LSX_TRANSPOSE4x4_H(in0, in1, in2, in3, in0, in1, in2, in3); - - LSX_BUTTERFLY_4_H(in0, in1, in2, in3, temp0, temp1, in1, in3); - in0 = __lsx_vadd_h(temp0, temp1); - in0 = __lsx_vaddi_hu(in0, 7); - in2 = __lsx_vsub_h(temp0, temp1); - in2 = __lsx_vaddi_hu(in2, 7); - in0 = __lsx_vsrai_h(in0, 4); - in2 = __lsx_vsrai_h(in2, 4); - DUP2_ARG2(__lsx_vreplvei_w, coeff, 2, coeff, 3, vec3_w, vec1_w); - vec3_w = __lsx_vadd_w(vec3_w, vec1_w); - vec1_w = __lsx_vreplvei_w(coeff, 1); - const0 = RET_1_IF_NZERO_H(in3); - tmp1 = __lsx_vilvl_h(in3, in1); - tmp0 = __lsx_vilvh_h(in3, in1); - vec0_w = vec1_w; - vec2_w = vec3_w; - DUP4_ARG3(__lsx_vdp2add_w_h, vec0_w, tmp1, const1, vec1_w, tmp0, const1, - vec2_w, tmp1, const2, vec3_w, tmp0, const2, vec0_w, vec1_w, vec2_w, - vec3_w); - DUP2_ARG3(__lsx_vsrani_h_w, vec1_w, vec0_w, 16, vec3_w, vec2_w, 16, in1, in3); - in1 = __lsx_vadd_h(in1, const0); - DUP2_ARG2(__lsx_vpickev_d, in1, in0, in3, in2, temp0, temp1); - __lsx_vst(temp0, output, 0); - __lsx_vst(temp1, output, 16); - - DUP2_ARG2(__lsx_vpickod_d, in1, in0, in3, in2, in0, in2); - __lsx_vst(in0, output, 32); - __lsx_vst(in2, output, 48); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/loongarch/encodeopt_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/loongarch/encodeopt_lsx.c deleted file mode 100644 index 4ad4caba..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/loongarch/encodeopt_lsx.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vpx_util/loongson_intrinsics.h" -#include "vp8/encoder/block.h" - -int32_t vp8_block_error_lsx(int16_t *coeff_ptr, int16_t *dq_coeff_ptr) { - int32_t err = 0; - __m128i dq_coeff0, dq_coeff1, coeff0, coeff1; - __m128i reg0, reg1, reg2, reg3, error; - - DUP4_ARG2(__lsx_vld, coeff_ptr, 0, coeff_ptr, 16, dq_coeff_ptr, 0, - dq_coeff_ptr, 16, coeff0, coeff1, dq_coeff0, dq_coeff1); - DUP2_ARG2(__lsx_vsubwev_w_h, coeff0, dq_coeff0, coeff1, dq_coeff1, reg0, - reg2); - DUP2_ARG2(__lsx_vsubwod_w_h, coeff0, dq_coeff0, coeff1, dq_coeff1, reg1, - reg3); - error = __lsx_vmul_w(reg0, reg0); - DUP2_ARG3(__lsx_vmadd_w, error, reg1, reg1, error, reg2, reg2, error, error); - error = __lsx_vmadd_w(error, reg3, reg3); - error = __lsx_vhaddw_d_w(error, error); - err = __lsx_vpickve2gr_w(error, 0); - err += __lsx_vpickve2gr_w(error, 2); - return err; -} - -int32_t vp8_mbblock_error_lsx(MACROBLOCK *mb, int32_t dc) { - BLOCK *be; - BLOCKD *bd; - int16_t *coeff, *dq_coeff; - int32_t err = 0; - uint32_t loop_cnt; - __m128i src0, src1, src2, src3; - __m128i tmp0, tmp1, tmp2, tmp3; - __m128i reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7, error; - __m128i mask0 = __lsx_vldi(0xFF); - __m128i zero = __lsx_vldi(0); - - if (dc == 1) { - mask0 = __lsx_vinsgr2vr_w(mask0, 0, 0); - } - - for (loop_cnt = 0; loop_cnt < 8; loop_cnt++) { - int32_t loop_tmp = loop_cnt << 1; - be = &mb->block[loop_tmp]; - bd = &mb->e_mbd.block[loop_tmp]; - coeff = be->coeff; - dq_coeff = bd->dqcoeff; - DUP4_ARG2(__lsx_vld, coeff, 0, coeff, 16, dq_coeff, 0, dq_coeff, 16, src0, - src1, tmp0, tmp1); - be = &mb->block[loop_tmp + 1]; - bd = &mb->e_mbd.block[loop_tmp + 1]; - coeff = be->coeff; - dq_coeff = bd->dqcoeff; - DUP4_ARG2(__lsx_vld, coeff, 0, coeff, 16, dq_coeff, 0, dq_coeff, 16, src2, - src3, tmp2, tmp3); - DUP4_ARG2(__lsx_vsubwev_w_h, src0, tmp0, src1, tmp1, src2, tmp2, src3, tmp3, - reg0, reg2, reg4, reg6); - DUP4_ARG2(__lsx_vsubwod_w_h, src0, tmp0, src1, tmp1, src2, tmp2, src3, tmp3, - reg1, reg3, reg5, reg7); - DUP2_ARG3(__lsx_vbitsel_v, zero, reg0, mask0, zero, reg4, mask0, reg0, - reg4); - error = __lsx_vmul_w(reg0, reg0); - DUP4_ARG3(__lsx_vmadd_w, error, reg1, reg1, error, reg2, reg2, error, reg3, - reg3, error, reg4, reg4, error, error, error, error); - DUP2_ARG3(__lsx_vmadd_w, error, reg5, reg5, error, reg6, reg6, error, - error); - error = __lsx_vmadd_w(error, reg7, reg7); - error = __lsx_vhaddw_d_w(error, error); - error = __lsx_vhaddw_q_d(error, error); - err += __lsx_vpickve2gr_w(error, 0); - } - return err; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/loongarch/vp8_quantize_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/loongarch/vp8_quantize_lsx.c deleted file mode 100644 index 75889192..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/loongarch/vp8_quantize_lsx.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vp8_rtcd.h" -#include "vpx_util/loongson_intrinsics.h" -#include "vp8/encoder/block.h" - -#define BOOST_QUANT1(_in0, _in1, _in2, _ui) \ - { \ - if (boost_temp[0] <= __lsx_vpickve2gr_h(_in0, _ui)) { \ - if (__lsx_vpickve2gr_h(_in1, _ui)) { \ - eob = _ui; \ - boost_temp = zbin_boost; \ - } else { \ - boost_temp++; \ - } \ - } else { \ - _in2 = __lsx_vinsgr2vr_h(_in2, 0, _ui); \ - boost_temp++; \ - } \ - } - -#define BOOST_QUANT2(_in0, _in1, _in2, _ui) \ - { \ - if (boost_temp[0] <= __lsx_vpickve2gr_h(_in0, _ui)) { \ - if (__lsx_vpickve2gr_h(_in1, _ui)) { \ - eob = _ui + 8; \ - boost_temp = zbin_boost; \ - } else { \ - boost_temp++; \ - } \ - } else { \ - _in2 = __lsx_vinsgr2vr_h(_in2, 0, _ui); \ - boost_temp++; \ - } \ - } - -static int8_t exact_regular_quantize_b_lsx( - int16_t *zbin_boost, int16_t *coeff_ptr, int16_t *zbin, int16_t *round, - int16_t *quant, int16_t *quant_shift, int16_t *de_quant, int16_t zbin_oq_in, - int16_t *q_coeff, int16_t *dq_coeff) { - int32_t eob; - int16_t *boost_temp = zbin_boost; - __m128i inv_zig_zag = { 0x0C07040206050100, 0x0F0E0A090D0B0803 }; - __m128i sign_z0, sign_z1, q_coeff0, q_coeff1; - __m128i z_bin0, z_bin1, zbin_o_q, x0, x1, sign_x0, sign_x1, de_quant0, - de_quant1; - __m128i z0, z1, round0, round1, quant0, quant2; - __m128i inv_zig_zag0, inv_zig_zag1; - __m128i zigzag_mask0 = { 0x0008000400010000, 0x0006000300020005 }; - __m128i zigzag_mask1 = { 0x000A000D000C0009, 0X000F000E000B0007 }; - __m128i tmp0, tmp1, tmp2, tmp3; - __m128i zero = __lsx_vldi(0); - - zbin_o_q = __lsx_vreplgr2vr_h(zbin_oq_in); - inv_zig_zag0 = __lsx_vilvl_b(zero, inv_zig_zag); - inv_zig_zag1 = __lsx_vilvh_b(zero, inv_zig_zag); - eob = -1; - DUP4_ARG2(__lsx_vld, coeff_ptr, 0, coeff_ptr, 16, round, 0, round, 16, tmp0, - tmp1, tmp2, tmp3); - DUP4_ARG3(__lsx_vshuf_h, zigzag_mask0, tmp1, tmp0, zigzag_mask1, tmp1, tmp0, - zigzag_mask0, tmp3, tmp2, zigzag_mask1, tmp3, tmp2, z0, z1, round0, - round1); - DUP4_ARG2(__lsx_vld, quant, 0, quant, 16, zbin, 0, zbin, 16, tmp0, tmp1, tmp2, - tmp3); - DUP4_ARG3(__lsx_vshuf_h, zigzag_mask0, tmp1, tmp0, zigzag_mask1, tmp1, tmp0, - zigzag_mask0, tmp3, tmp2, zigzag_mask1, tmp3, tmp2, quant0, quant2, - z_bin0, z_bin1); - DUP2_ARG2(__lsx_vsrai_h, z0, 15, z1, 15, sign_z0, sign_z1); - DUP2_ARG2(__lsx_vadda_h, z0, zero, z1, zero, x0, x1); - DUP2_ARG2(__lsx_vsub_h, x0, z_bin0, x1, z_bin1, z_bin0, z_bin1); - DUP2_ARG2(__lsx_vsub_h, z_bin0, zbin_o_q, z_bin1, zbin_o_q, z_bin0, z_bin1); - DUP2_ARG2(__lsx_vmulwev_w_h, quant0, round0, quant2, round1, tmp0, tmp2); - DUP2_ARG2(__lsx_vmulwod_w_h, quant0, round0, quant2, round1, tmp1, tmp3); - DUP2_ARG3(__lsx_vmaddwev_w_h, tmp0, quant0, x0, tmp2, quant2, x1, tmp0, tmp2); - DUP2_ARG3(__lsx_vmaddwod_w_h, tmp1, quant0, x0, tmp3, quant2, x1, tmp1, tmp3); - DUP2_ARG2(__lsx_vpackod_h, tmp1, tmp0, tmp3, tmp2, q_coeff0, q_coeff1); - - DUP2_ARG2(__lsx_vld, quant_shift, 0, quant_shift, 16, tmp1, tmp3); - DUP2_ARG3(__lsx_vshuf_h, zigzag_mask0, tmp3, tmp1, zigzag_mask1, tmp3, tmp1, - quant0, quant2); - DUP2_ARG2(__lsx_vadd_h, x0, round0, x1, round1, x0, x1); - DUP2_ARG2(__lsx_vmulwev_w_h, quant0, q_coeff0, quant2, q_coeff1, tmp0, tmp2); - DUP2_ARG2(__lsx_vmulwod_w_h, quant0, q_coeff0, quant2, q_coeff1, tmp1, tmp3); - DUP2_ARG3(__lsx_vmaddwev_w_h, tmp0, quant0, x0, tmp2, quant2, x1, tmp0, tmp2); - DUP2_ARG3(__lsx_vmaddwod_w_h, tmp1, quant0, x0, tmp3, quant2, x1, tmp1, tmp3); - DUP2_ARG2(__lsx_vpackod_h, tmp1, tmp0, tmp3, tmp2, x0, x1); - DUP2_ARG2(__lsx_vxor_v, x0, sign_z0, x1, sign_z1, sign_x0, sign_x1); - DUP2_ARG2(__lsx_vsub_h, sign_x0, sign_z0, sign_x1, sign_z1, sign_x0, sign_x1); - - BOOST_QUANT1(z_bin0, x0, sign_x0, 0); - BOOST_QUANT1(z_bin0, x0, sign_x0, 1); - BOOST_QUANT1(z_bin0, x0, sign_x0, 2); - BOOST_QUANT1(z_bin0, x0, sign_x0, 3); - BOOST_QUANT1(z_bin0, x0, sign_x0, 4); - BOOST_QUANT1(z_bin0, x0, sign_x0, 5); - BOOST_QUANT1(z_bin0, x0, sign_x0, 6); - BOOST_QUANT1(z_bin0, x0, sign_x0, 7); - - BOOST_QUANT2(z_bin1, x1, sign_x1, 0); - BOOST_QUANT2(z_bin1, x1, sign_x1, 1); - BOOST_QUANT2(z_bin1, x1, sign_x1, 2); - BOOST_QUANT2(z_bin1, x1, sign_x1, 3); - BOOST_QUANT2(z_bin1, x1, sign_x1, 4); - BOOST_QUANT2(z_bin1, x1, sign_x1, 5); - BOOST_QUANT2(z_bin1, x1, sign_x1, 6); - BOOST_QUANT2(z_bin1, x1, sign_x1, 7); - - DUP2_ARG2(__lsx_vld, de_quant, 0, de_quant, 16, de_quant0, de_quant1); - DUP2_ARG3(__lsx_vshuf_h, inv_zig_zag0, sign_x1, sign_x0, inv_zig_zag1, - sign_x1, sign_x0, q_coeff0, q_coeff1); - DUP2_ARG2(__lsx_vmul_h, de_quant0, q_coeff0, de_quant1, q_coeff1, de_quant0, - de_quant1); - __lsx_vst(q_coeff0, q_coeff, 0); - __lsx_vst(q_coeff1, q_coeff, 16); - __lsx_vst(de_quant0, dq_coeff, 0); - __lsx_vst(de_quant1, dq_coeff, 16); - - return (int8_t)(eob + 1); -} - -void vp8_regular_quantize_b_lsx(BLOCK *b, BLOCKD *d) { - int16_t *zbin_boost_ptr = b->zrun_zbin_boost; - int16_t *coeff_ptr = b->coeff; - int16_t *zbin_ptr = b->zbin; - int16_t *round_ptr = b->round; - int16_t *quant_ptr = b->quant; - int16_t *quant_shift_ptr = b->quant_shift; - int16_t *qcoeff_ptr = d->qcoeff; - int16_t *dqcoeff_ptr = d->dqcoeff; - int16_t *dequant_ptr = d->dequant; - int16_t zbin_oq_value = b->zbin_extra; - - *d->eob = exact_regular_quantize_b_lsx( - zbin_boost_ptr, coeff_ptr, zbin_ptr, round_ptr, quant_ptr, - quant_shift_ptr, dequant_ptr, zbin_oq_value, qcoeff_ptr, dqcoeff_ptr); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mcomp.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mcomp.c deleted file mode 100644 index 3ec85a17..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mcomp.c +++ /dev/null @@ -1,1561 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "onyx_int.h" -#include "mcomp.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_config.h" -#include -#include -#include -#include "vp8/common/findnearmv.h" -#include "vp8/common/common.h" -#include "vpx_dsp/vpx_dsp_common.h" - -int vp8_mv_bit_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int Weight) { - /* MV costing is based on the distribution of vectors in the previous - * frame and as such will tend to over state the cost of vectors. In - * addition coding a new vector can have a knock on effect on the cost - * of subsequent vectors and the quality of prediction from NEAR and - * NEAREST for subsequent blocks. The "Weight" parameter allows, to a - * limited extent, for some account to be taken of these factors. - */ - const int mv_idx_row = - clamp((mv->as_mv.row - ref->as_mv.row) >> 1, 0, MVvals); - const int mv_idx_col = - clamp((mv->as_mv.col - ref->as_mv.col) >> 1, 0, MVvals); - return ((mvcost[0][mv_idx_row] + mvcost[1][mv_idx_col]) * Weight) >> 7; -} - -static int mv_err_cost(int_mv *mv, int_mv *ref, int *mvcost[2], - int error_per_bit) { - /* Ignore mv costing if mvcost is NULL */ - if (mvcost) { - const int mv_idx_row = - clamp((mv->as_mv.row - ref->as_mv.row) >> 1, 0, MVvals); - const int mv_idx_col = - clamp((mv->as_mv.col - ref->as_mv.col) >> 1, 0, MVvals); - return ((mvcost[0][mv_idx_row] + mvcost[1][mv_idx_col]) * error_per_bit + - 128) >> - 8; - } - return 0; -} - -static int mvsad_err_cost(int_mv *mv, int_mv *ref, int *mvsadcost[2], - int error_per_bit) { - /* Calculate sad error cost on full pixel basis. */ - /* Ignore mv costing if mvsadcost is NULL */ - if (mvsadcost) { - return ((mvsadcost[0][(mv->as_mv.row - ref->as_mv.row)] + - mvsadcost[1][(mv->as_mv.col - ref->as_mv.col)]) * - error_per_bit + - 128) >> - 8; - } - return 0; -} - -void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride) { - int Len; - int search_site_count = 0; - - /* Generate offsets for 4 search sites per step. */ - Len = MAX_FIRST_STEP; - x->ss[search_site_count].mv.col = 0; - x->ss[search_site_count].mv.row = 0; - x->ss[search_site_count].offset = 0; - search_site_count++; - - while (Len > 0) { - /* Compute offsets for search sites. */ - x->ss[search_site_count].mv.col = 0; - x->ss[search_site_count].mv.row = -Len; - x->ss[search_site_count].offset = -Len * stride; - search_site_count++; - - /* Compute offsets for search sites. */ - x->ss[search_site_count].mv.col = 0; - x->ss[search_site_count].mv.row = Len; - x->ss[search_site_count].offset = Len * stride; - search_site_count++; - - /* Compute offsets for search sites. */ - x->ss[search_site_count].mv.col = -Len; - x->ss[search_site_count].mv.row = 0; - x->ss[search_site_count].offset = -Len; - search_site_count++; - - /* Compute offsets for search sites. */ - x->ss[search_site_count].mv.col = Len; - x->ss[search_site_count].mv.row = 0; - x->ss[search_site_count].offset = Len; - search_site_count++; - - /* Contract. */ - Len /= 2; - } - - x->ss_count = search_site_count; - x->searches_per_step = 4; -} - -void vp8_init3smotion_compensation(MACROBLOCK *x, int stride) { - int Len; - int search_site_count = 0; - - /* Generate offsets for 8 search sites per step. */ - Len = MAX_FIRST_STEP; - x->ss[search_site_count].mv.col = 0; - x->ss[search_site_count].mv.row = 0; - x->ss[search_site_count].offset = 0; - search_site_count++; - - while (Len > 0) { - /* Compute offsets for search sites. */ - x->ss[search_site_count].mv.col = 0; - x->ss[search_site_count].mv.row = -Len; - x->ss[search_site_count].offset = -Len * stride; - search_site_count++; - - /* Compute offsets for search sites. */ - x->ss[search_site_count].mv.col = 0; - x->ss[search_site_count].mv.row = Len; - x->ss[search_site_count].offset = Len * stride; - search_site_count++; - - /* Compute offsets for search sites. */ - x->ss[search_site_count].mv.col = -Len; - x->ss[search_site_count].mv.row = 0; - x->ss[search_site_count].offset = -Len; - search_site_count++; - - /* Compute offsets for search sites. */ - x->ss[search_site_count].mv.col = Len; - x->ss[search_site_count].mv.row = 0; - x->ss[search_site_count].offset = Len; - search_site_count++; - - /* Compute offsets for search sites. */ - x->ss[search_site_count].mv.col = -Len; - x->ss[search_site_count].mv.row = -Len; - x->ss[search_site_count].offset = -Len * stride - Len; - search_site_count++; - - /* Compute offsets for search sites. */ - x->ss[search_site_count].mv.col = Len; - x->ss[search_site_count].mv.row = -Len; - x->ss[search_site_count].offset = -Len * stride + Len; - search_site_count++; - - /* Compute offsets for search sites. */ - x->ss[search_site_count].mv.col = -Len; - x->ss[search_site_count].mv.row = Len; - x->ss[search_site_count].offset = Len * stride - Len; - search_site_count++; - - /* Compute offsets for search sites. */ - x->ss[search_site_count].mv.col = Len; - x->ss[search_site_count].mv.row = Len; - x->ss[search_site_count].offset = Len * stride + Len; - search_site_count++; - - /* Contract. */ - Len /= 2; - } - - x->ss_count = search_site_count; - x->searches_per_step = 8; -} - -/* - * To avoid the penalty for crossing cache-line read, preload the reference - * area in a small buffer, which is aligned to make sure there won't be crossing - * cache-line read while reading from this buffer. This reduced the cpu - * cycles spent on reading ref data in sub-pixel filter functions. - * TODO: Currently, since sub-pixel search range here is -3 ~ 3, copy 22 rows x - * 32 cols area that is enough for 16x16 macroblock. Later, for SPLITMV, we - * could reduce the area. - */ - -/* estimated cost of a motion vector (r,c) */ -#define MVC(r, c) \ - (mvcost \ - ? ((mvcost[0][(r)-rr] + mvcost[1][(c)-rc]) * error_per_bit + 128) >> 8 \ - : 0) -/* pointer to predictor base of a motionvector */ -#define PRE(r, c) (y + (((r) >> 2) * y_stride + ((c) >> 2) - (offset))) -/* convert motion vector component to offset for svf calc */ -#define SP(x) (((x)&3) << 1) -/* returns subpixel variance error function. */ -#define DIST(r, c) \ - vfp->svf(PRE(r, c), y_stride, SP(c), SP(r), z, b->src_stride, &sse) -#define IFMVCV(r, c, s, e) \ - if (c >= minc && c <= maxc && r >= minr && r <= maxr) s else e; -/* returns distortion + motion vector cost */ -#define ERR(r, c) (MVC(r, c) + DIST(r, c)) -/* checks if (r,c) has better score than previous best */ -#define CHECK_BETTER(v, r, c) \ - do { \ - IFMVCV( \ - r, c, \ - { \ - thismse = DIST(r, c); \ - if ((v = (MVC(r, c) + thismse)) < besterr) { \ - besterr = v; \ - br = r; \ - bc = c; \ - *distortion = thismse; \ - *sse1 = sse; \ - } \ - }, \ - v = UINT_MAX;) \ - } while (0) - -int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d, - int_mv *bestmv, int_mv *ref_mv, - int error_per_bit, - const vp8_variance_fn_ptr_t *vfp, - int *mvcost[2], int *distortion, - unsigned int *sse1) { - unsigned char *z = (*(b->base_src) + b->src); - - int rr = ref_mv->as_mv.row >> 1, rc = ref_mv->as_mv.col >> 1; - int br = bestmv->as_mv.row * 4, bc = bestmv->as_mv.col * 4; - int tr = br, tc = bc; - unsigned int besterr; - unsigned int left, right, up, down, diag; - unsigned int sse; - unsigned int whichdir; - unsigned int halfiters = 4; - unsigned int quarteriters = 4; - int thismse; - - int minc = VPXMAX(x->mv_col_min * 4, - (ref_mv->as_mv.col >> 1) - ((1 << mvlong_width) - 1)); - int maxc = VPXMIN(x->mv_col_max * 4, - (ref_mv->as_mv.col >> 1) + ((1 << mvlong_width) - 1)); - int minr = VPXMAX(x->mv_row_min * 4, - (ref_mv->as_mv.row >> 1) - ((1 << mvlong_width) - 1)); - int maxr = VPXMIN(x->mv_row_max * 4, - (ref_mv->as_mv.row >> 1) + ((1 << mvlong_width) - 1)); - - int y_stride; - int offset; - int pre_stride = x->e_mbd.pre.y_stride; - unsigned char *base_pre = x->e_mbd.pre.y_buffer; - -#if VPX_ARCH_X86 || VPX_ARCH_X86_64 - MACROBLOCKD *xd = &x->e_mbd; - unsigned char *y_0 = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + - bestmv->as_mv.col; - unsigned char *y; - int buf_r1, buf_r2, buf_c1; - - /* Clamping to avoid out-of-range data access */ - buf_r1 = ((bestmv->as_mv.row - 3) < x->mv_row_min) - ? (bestmv->as_mv.row - x->mv_row_min) - : 3; - buf_r2 = ((bestmv->as_mv.row + 3) > x->mv_row_max) - ? (x->mv_row_max - bestmv->as_mv.row) - : 3; - buf_c1 = ((bestmv->as_mv.col - 3) < x->mv_col_min) - ? (bestmv->as_mv.col - x->mv_col_min) - : 3; - y_stride = 32; - - /* Copy to intermediate buffer before searching. */ - vfp->copymem(y_0 - buf_c1 - pre_stride * buf_r1, pre_stride, xd->y_buf, - y_stride, 16 + buf_r1 + buf_r2); - y = xd->y_buf + y_stride * buf_r1 + buf_c1; -#else - unsigned char *y = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + - bestmv->as_mv.col; - y_stride = pre_stride; -#endif - - offset = (bestmv->as_mv.row) * y_stride + bestmv->as_mv.col; - - /* central mv */ - bestmv->as_mv.row = clamp(bestmv->as_mv.row * 8, SHRT_MIN, SHRT_MAX); - bestmv->as_mv.col = clamp(bestmv->as_mv.col * 8, SHRT_MIN, SHRT_MAX); - - /* calculate central point error */ - besterr = vfp->vf(y, y_stride, z, b->src_stride, sse1); - *distortion = besterr; - besterr += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit); - - /* TODO: Each subsequent iteration checks at least one point in common - * with the last iteration could be 2 ( if diag selected) - */ - while (--halfiters) { - /* 1/2 pel */ - CHECK_BETTER(left, tr, tc - 2); - CHECK_BETTER(right, tr, tc + 2); - CHECK_BETTER(up, tr - 2, tc); - CHECK_BETTER(down, tr + 2, tc); - - whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2); - - switch (whichdir) { - case 0: CHECK_BETTER(diag, tr - 2, tc - 2); break; - case 1: CHECK_BETTER(diag, tr - 2, tc + 2); break; - case 2: CHECK_BETTER(diag, tr + 2, tc - 2); break; - case 3: CHECK_BETTER(diag, tr + 2, tc + 2); break; - } - - /* no reason to check the same one again. */ - if (tr == br && tc == bc) break; - - tr = br; - tc = bc; - } - - /* TODO: Each subsequent iteration checks at least one point in common - * with the last iteration could be 2 ( if diag selected) - */ - - /* 1/4 pel */ - while (--quarteriters) { - CHECK_BETTER(left, tr, tc - 1); - CHECK_BETTER(right, tr, tc + 1); - CHECK_BETTER(up, tr - 1, tc); - CHECK_BETTER(down, tr + 1, tc); - - whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2); - - switch (whichdir) { - case 0: CHECK_BETTER(diag, tr - 1, tc - 1); break; - case 1: CHECK_BETTER(diag, tr - 1, tc + 1); break; - case 2: CHECK_BETTER(diag, tr + 1, tc - 1); break; - case 3: CHECK_BETTER(diag, tr + 1, tc + 1); break; - } - - /* no reason to check the same one again. */ - if (tr == br && tc == bc) break; - - tr = br; - tc = bc; - } - - bestmv->as_mv.row = clamp(br * 2, SHRT_MIN, SHRT_MAX); - bestmv->as_mv.col = clamp(bc * 2, SHRT_MIN, SHRT_MAX); - - if ((abs(bestmv->as_mv.col - ref_mv->as_mv.col) > (MAX_FULL_PEL_VAL << 3)) || - (abs(bestmv->as_mv.row - ref_mv->as_mv.row) > (MAX_FULL_PEL_VAL << 3))) { - return INT_MAX; - } - - return besterr; -} -#undef MVC -#undef PRE -#undef SP -#undef DIST -#undef IFMVCV -#undef ERR -#undef CHECK_BETTER - -int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, - int_mv *bestmv, int_mv *ref_mv, - int error_per_bit, - const vp8_variance_fn_ptr_t *vfp, - int *mvcost[2], int *distortion, - unsigned int *sse1) { - int bestmse = INT_MAX; - int_mv startmv; - int_mv this_mv; - unsigned char *z = (*(b->base_src) + b->src); - int left, right, up, down, diag; - unsigned int sse; - int whichdir; - int thismse; - int y_stride; - int pre_stride = x->e_mbd.pre.y_stride; - unsigned char *base_pre = x->e_mbd.pre.y_buffer; - -#if VPX_ARCH_X86 || VPX_ARCH_X86_64 - MACROBLOCKD *xd = &x->e_mbd; - unsigned char *y_0 = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + - bestmv->as_mv.col; - unsigned char *y; - - y_stride = 32; - /* Copy 18 rows x 32 cols area to intermediate buffer before searching. */ - vfp->copymem(y_0 - 1 - pre_stride, pre_stride, xd->y_buf, y_stride, 18); - y = xd->y_buf + y_stride + 1; -#else - unsigned char *y = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + - bestmv->as_mv.col; - y_stride = pre_stride; -#endif - - /* central mv */ - bestmv->as_mv.row = clamp(bestmv->as_mv.row * 8, SHRT_MIN, SHRT_MAX); - bestmv->as_mv.col = clamp(bestmv->as_mv.col * 8, SHRT_MIN, SHRT_MAX); - startmv = *bestmv; - - /* calculate central point error */ - bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1); - *distortion = bestmse; - bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit); - - /* go left then right and check error */ - this_mv.as_mv.row = startmv.as_mv.row; - this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4); - /* "halfpix" horizontal variance */ - thismse = vfp->svf(y - 1, y_stride, 4, 0, z, b->src_stride, &sse); - left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit); - - if (left < bestmse) { - *bestmv = this_mv; - bestmse = left; - *distortion = thismse; - *sse1 = sse; - } - - this_mv.as_mv.col += 8; - /* "halfpix" horizontal variance */ - thismse = vfp->svf(y, y_stride, 4, 0, z, b->src_stride, &sse); - right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit); - - if (right < bestmse) { - *bestmv = this_mv; - bestmse = right; - *distortion = thismse; - *sse1 = sse; - } - - /* go up then down and check error */ - this_mv.as_mv.col = startmv.as_mv.col; - this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4); - /* "halfpix" vertical variance */ - thismse = vfp->svf(y - y_stride, y_stride, 0, 4, z, b->src_stride, &sse); - up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit); - - if (up < bestmse) { - *bestmv = this_mv; - bestmse = up; - *distortion = thismse; - *sse1 = sse; - } - - this_mv.as_mv.row += 8; - /* "halfpix" vertical variance */ - thismse = vfp->svf(y, y_stride, 0, 4, z, b->src_stride, &sse); - down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit); - - if (down < bestmse) { - *bestmv = this_mv; - bestmse = down; - *distortion = thismse; - *sse1 = sse; - } - - /* now check 1 more diagonal */ - whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2); - this_mv = startmv; - - switch (whichdir) { - case 0: - this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4; - this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4; - /* "halfpix" horizontal/vertical variance */ - thismse = - vfp->svf(y - 1 - y_stride, y_stride, 4, 4, z, b->src_stride, &sse); - break; - case 1: - this_mv.as_mv.col += 4; - this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4; - /* "halfpix" horizontal/vertical variance */ - thismse = vfp->svf(y - y_stride, y_stride, 4, 4, z, b->src_stride, &sse); - break; - case 2: - this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4; - this_mv.as_mv.row += 4; - /* "halfpix" horizontal/vertical variance */ - thismse = vfp->svf(y - 1, y_stride, 4, 4, z, b->src_stride, &sse); - break; - case 3: - default: - this_mv.as_mv.col += 4; - this_mv.as_mv.row += 4; - /* "halfpix" horizontal/vertical variance */ - thismse = vfp->svf(y, y_stride, 4, 4, z, b->src_stride, &sse); - break; - } - - diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit); - - if (diag < bestmse) { - *bestmv = this_mv; - bestmse = diag; - *distortion = thismse; - *sse1 = sse; - } - - /* time to check quarter pels. */ - if (bestmv->as_mv.row < startmv.as_mv.row) y -= y_stride; - - if (bestmv->as_mv.col < startmv.as_mv.col) y--; - - startmv = *bestmv; - - /* go left then right and check error */ - this_mv.as_mv.row = startmv.as_mv.row; - - if (startmv.as_mv.col & 7) { - this_mv.as_mv.col = startmv.as_mv.col - 2; - thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, - this_mv.as_mv.row & 7, z, b->src_stride, &sse); - } else { - this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6; - thismse = vfp->svf(y - 1, y_stride, 6, this_mv.as_mv.row & 7, z, - b->src_stride, &sse); - } - - left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit); - - if (left < bestmse) { - *bestmv = this_mv; - bestmse = left; - *distortion = thismse; - *sse1 = sse; - } - - this_mv.as_mv.col += 4; - thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, - z, b->src_stride, &sse); - right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit); - - if (right < bestmse) { - *bestmv = this_mv; - bestmse = right; - *distortion = thismse; - *sse1 = sse; - } - - /* go up then down and check error */ - this_mv.as_mv.col = startmv.as_mv.col; - - if (startmv.as_mv.row & 7) { - this_mv.as_mv.row = startmv.as_mv.row - 2; - thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, - this_mv.as_mv.row & 7, z, b->src_stride, &sse); - } else { - this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6; - thismse = vfp->svf(y - y_stride, y_stride, this_mv.as_mv.col & 7, 6, z, - b->src_stride, &sse); - } - - up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit); - - if (up < bestmse) { - *bestmv = this_mv; - bestmse = up; - *distortion = thismse; - *sse1 = sse; - } - - this_mv.as_mv.row += 4; - thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, - z, b->src_stride, &sse); - down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit); - - if (down < bestmse) { - *bestmv = this_mv; - bestmse = down; - *distortion = thismse; - *sse1 = sse; - } - - /* now check 1 more diagonal */ - whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2); - - this_mv = startmv; - - switch (whichdir) { - case 0: - - if (startmv.as_mv.row & 7) { - this_mv.as_mv.row -= 2; - - if (startmv.as_mv.col & 7) { - this_mv.as_mv.col -= 2; - thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, - this_mv.as_mv.row & 7, z, b->src_stride, &sse); - } else { - this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6; - thismse = vfp->svf(y - 1, y_stride, 6, this_mv.as_mv.row & 7, z, - b->src_stride, &sse); - } - } else { - this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6; - - if (startmv.as_mv.col & 7) { - this_mv.as_mv.col -= 2; - thismse = vfp->svf(y - y_stride, y_stride, this_mv.as_mv.col & 7, 6, - z, b->src_stride, &sse); - } else { - this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6; - thismse = vfp->svf(y - y_stride - 1, y_stride, 6, 6, z, b->src_stride, - &sse); - } - } - - break; - case 1: - this_mv.as_mv.col += 2; - - if (startmv.as_mv.row & 7) { - this_mv.as_mv.row -= 2; - thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, - this_mv.as_mv.row & 7, z, b->src_stride, &sse); - } else { - this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6; - thismse = vfp->svf(y - y_stride, y_stride, this_mv.as_mv.col & 7, 6, z, - b->src_stride, &sse); - } - - break; - case 2: - this_mv.as_mv.row += 2; - - if (startmv.as_mv.col & 7) { - this_mv.as_mv.col -= 2; - thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, - this_mv.as_mv.row & 7, z, b->src_stride, &sse); - } else { - this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6; - thismse = vfp->svf(y - 1, y_stride, 6, this_mv.as_mv.row & 7, z, - b->src_stride, &sse); - } - - break; - case 3: - this_mv.as_mv.col += 2; - this_mv.as_mv.row += 2; - thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, - this_mv.as_mv.row & 7, z, b->src_stride, &sse); - break; - } - - diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit); - - if (diag < bestmse) { - *bestmv = this_mv; - bestmse = diag; - *distortion = thismse; - *sse1 = sse; - } - - return bestmse; -} - -int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, - int_mv *bestmv, int_mv *ref_mv, - int error_per_bit, - const vp8_variance_fn_ptr_t *vfp, - int *mvcost[2], int *distortion, - unsigned int *sse1) { - int bestmse = INT_MAX; - int_mv startmv; - int_mv this_mv; - unsigned char *z = (*(b->base_src) + b->src); - int left, right, up, down, diag; - unsigned int sse; - int whichdir; - int thismse; - int y_stride; - int pre_stride = x->e_mbd.pre.y_stride; - unsigned char *base_pre = x->e_mbd.pre.y_buffer; - -#if VPX_ARCH_X86 || VPX_ARCH_X86_64 - MACROBLOCKD *xd = &x->e_mbd; - unsigned char *y_0 = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + - bestmv->as_mv.col; - unsigned char *y; - - y_stride = 32; - /* Copy 18 rows x 32 cols area to intermediate buffer before searching. */ - vfp->copymem(y_0 - 1 - pre_stride, pre_stride, xd->y_buf, y_stride, 18); - y = xd->y_buf + y_stride + 1; -#else - unsigned char *y = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + - bestmv->as_mv.col; - y_stride = pre_stride; -#endif - - /* central mv */ - bestmv->as_mv.row = clamp(bestmv->as_mv.row * 8, SHRT_MIN, SHRT_MAX); - bestmv->as_mv.col = clamp(bestmv->as_mv.col * 8, SHRT_MIN, SHRT_MAX); - startmv = *bestmv; - - /* calculate central point error */ - bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1); - *distortion = bestmse; - bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit); - - /* go left then right and check error */ - this_mv.as_mv.row = startmv.as_mv.row; - this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4); - /* "halfpix" horizontal variance */ - thismse = vfp->svf(y - 1, y_stride, 4, 0, z, b->src_stride, &sse); - left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit); - - if (left < bestmse) { - *bestmv = this_mv; - bestmse = left; - *distortion = thismse; - *sse1 = sse; - } - - this_mv.as_mv.col += 8; - /* "halfpix" horizontal variance */ - thismse = vfp->svf(y, y_stride, 4, 0, z, b->src_stride, &sse); - right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit); - - if (right < bestmse) { - *bestmv = this_mv; - bestmse = right; - *distortion = thismse; - *sse1 = sse; - } - - /* go up then down and check error */ - this_mv.as_mv.col = startmv.as_mv.col; - this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4); - /* "halfpix" vertical variance */ - thismse = vfp->svf(y - y_stride, y_stride, 0, 4, z, b->src_stride, &sse); - up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit); - - if (up < bestmse) { - *bestmv = this_mv; - bestmse = up; - *distortion = thismse; - *sse1 = sse; - } - - this_mv.as_mv.row += 8; - /* "halfpix" vertical variance */ - thismse = vfp->svf(y, y_stride, 0, 4, z, b->src_stride, &sse); - down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit); - - if (down < bestmse) { - *bestmv = this_mv; - bestmse = down; - *distortion = thismse; - *sse1 = sse; - } - - /* now check 1 more diagonal - */ - whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2); - this_mv = startmv; - - switch (whichdir) { - case 0: - this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4; - this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4; - /* "halfpix" horizontal/vertical variance */ - thismse = - vfp->svf(y - 1 - y_stride, y_stride, 4, 4, z, b->src_stride, &sse); - break; - case 1: - this_mv.as_mv.col += 4; - this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4; - /* "halfpix" horizontal/vertical variance */ - thismse = vfp->svf(y - y_stride, y_stride, 4, 4, z, b->src_stride, &sse); - break; - case 2: - this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4; - this_mv.as_mv.row += 4; - /* "halfpix" horizontal/vertical variance */ - thismse = vfp->svf(y - 1, y_stride, 4, 4, z, b->src_stride, &sse); - break; - case 3: - default: - this_mv.as_mv.col += 4; - this_mv.as_mv.row += 4; - /* "halfpix" horizontal/vertical variance */ - thismse = vfp->svf(y, y_stride, 4, 4, z, b->src_stride, &sse); - break; - } - - diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit); - - if (diag < bestmse) { - *bestmv = this_mv; - bestmse = diag; - *distortion = thismse; - *sse1 = sse; - } - - return bestmse; -} - -#define CHECK_BOUNDS(range) \ - do { \ - all_in = 1; \ - all_in &= ((br - range) >= x->mv_row_min); \ - all_in &= ((br + range) <= x->mv_row_max); \ - all_in &= ((bc - range) >= x->mv_col_min); \ - all_in &= ((bc + range) <= x->mv_col_max); \ - } while (0) - -#define CHECK_POINT \ - { \ - if (this_mv.as_mv.col < x->mv_col_min) continue; \ - if (this_mv.as_mv.col > x->mv_col_max) continue; \ - if (this_mv.as_mv.row < x->mv_row_min) continue; \ - if (this_mv.as_mv.row > x->mv_row_max) continue; \ - } - -#define CHECK_BETTER \ - do { \ - if (thissad < bestsad) { \ - thissad += \ - mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit); \ - if (thissad < bestsad) { \ - bestsad = thissad; \ - best_site = i; \ - } \ - } \ - } while (0) - -static const MV next_chkpts[6][3] = { - { { -2, 0 }, { -1, -2 }, { 1, -2 } }, { { -1, -2 }, { 1, -2 }, { 2, 0 } }, - { { 1, -2 }, { 2, 0 }, { 1, 2 } }, { { 2, 0 }, { 1, 2 }, { -1, 2 } }, - { { 1, 2 }, { -1, 2 }, { -2, 0 } }, { { -1, 2 }, { -2, 0 }, { -1, -2 } } -}; - -int vp8_hex_search(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, - int_mv *best_mv, int search_param, int sad_per_bit, - const vp8_variance_fn_ptr_t *vfp, int *mvsadcost[2], - int_mv *center_mv) { - MV hex[6] = { - { -1, -2 }, { 1, -2 }, { 2, 0 }, { 1, 2 }, { -1, 2 }, { -2, 0 } - }; - MV neighbors[4] = { { 0, -1 }, { -1, 0 }, { 1, 0 }, { 0, 1 } }; - int i, j; - - unsigned char *what = (*(b->base_src) + b->src); - int what_stride = b->src_stride; - int pre_stride = x->e_mbd.pre.y_stride; - unsigned char *base_pre = x->e_mbd.pre.y_buffer; - - int in_what_stride = pre_stride; - int br, bc; - int_mv this_mv; - unsigned int bestsad; - unsigned int thissad; - unsigned char *base_offset; - unsigned char *this_offset; - int k = -1; - int all_in; - int best_site = -1; - int hex_range = 127; - int dia_range = 8; - - int_mv fcenter_mv; - fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3; - fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3; - - /* adjust ref_mv to make sure it is within MV range */ - vp8_clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, - x->mv_row_max); - br = ref_mv->as_mv.row; - bc = ref_mv->as_mv.col; - - /* Work out the start point for the search */ - base_offset = (unsigned char *)(base_pre + d->offset); - this_offset = base_offset + (br * (pre_stride)) + bc; - this_mv.as_mv.row = br; - this_mv.as_mv.col = bc; - bestsad = vfp->sdf(what, what_stride, this_offset, in_what_stride) + - mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit); - -#if CONFIG_MULTI_RES_ENCODING - /* Lower search range based on prediction info */ - if (search_param >= 6) - goto cal_neighbors; - else if (search_param >= 5) - hex_range = 4; - else if (search_param >= 4) - hex_range = 6; - else if (search_param >= 3) - hex_range = 15; - else if (search_param >= 2) - hex_range = 31; - else if (search_param >= 1) - hex_range = 63; - - dia_range = 8; -#else - (void)search_param; -#endif - - /* hex search */ - CHECK_BOUNDS(2); - - if (all_in) { - for (i = 0; i < 6; ++i) { - this_mv.as_mv.row = br + hex[i].row; - this_mv.as_mv.col = bc + hex[i].col; - this_offset = base_offset + (this_mv.as_mv.row * in_what_stride) + - this_mv.as_mv.col; - thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride); - CHECK_BETTER; - } - } else { - for (i = 0; i < 6; ++i) { - this_mv.as_mv.row = br + hex[i].row; - this_mv.as_mv.col = bc + hex[i].col; - CHECK_POINT - this_offset = base_offset + (this_mv.as_mv.row * in_what_stride) + - this_mv.as_mv.col; - thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride); - CHECK_BETTER; - } - } - - if (best_site == -1) { - goto cal_neighbors; - } else { - br += hex[best_site].row; - bc += hex[best_site].col; - k = best_site; - } - - for (j = 1; j < hex_range; ++j) { - best_site = -1; - CHECK_BOUNDS(2); - - if (all_in) { - for (i = 0; i < 3; ++i) { - this_mv.as_mv.row = br + next_chkpts[k][i].row; - this_mv.as_mv.col = bc + next_chkpts[k][i].col; - this_offset = base_offset + (this_mv.as_mv.row * (in_what_stride)) + - this_mv.as_mv.col; - thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride); - CHECK_BETTER; - } - } else { - for (i = 0; i < 3; ++i) { - this_mv.as_mv.row = br + next_chkpts[k][i].row; - this_mv.as_mv.col = bc + next_chkpts[k][i].col; - CHECK_POINT - this_offset = base_offset + (this_mv.as_mv.row * (in_what_stride)) + - this_mv.as_mv.col; - thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride); - CHECK_BETTER; - } - } - - if (best_site == -1) { - break; - } else { - br += next_chkpts[k][best_site].row; - bc += next_chkpts[k][best_site].col; - k += 5 + best_site; - if (k >= 12) { - k -= 12; - } else if (k >= 6) { - k -= 6; - } - } - } - -/* check 4 1-away neighbors */ -cal_neighbors: - for (j = 0; j < dia_range; ++j) { - best_site = -1; - CHECK_BOUNDS(1); - - if (all_in) { - for (i = 0; i < 4; ++i) { - this_mv.as_mv.row = br + neighbors[i].row; - this_mv.as_mv.col = bc + neighbors[i].col; - this_offset = base_offset + (this_mv.as_mv.row * (in_what_stride)) + - this_mv.as_mv.col; - thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride); - CHECK_BETTER; - } - } else { - for (i = 0; i < 4; ++i) { - this_mv.as_mv.row = br + neighbors[i].row; - this_mv.as_mv.col = bc + neighbors[i].col; - CHECK_POINT - this_offset = base_offset + (this_mv.as_mv.row * (in_what_stride)) + - this_mv.as_mv.col; - thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride); - CHECK_BETTER; - } - } - - if (best_site == -1) { - break; - } else { - br += neighbors[best_site].row; - bc += neighbors[best_site].col; - } - } - - best_mv->as_mv.row = br; - best_mv->as_mv.col = bc; - - return bestsad; -} -#undef CHECK_BOUNDS -#undef CHECK_POINT -#undef CHECK_BETTER - -int vp8_diamond_search_sad_c(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, - int_mv *best_mv, int search_param, int sad_per_bit, - int *num00, vp8_variance_fn_ptr_t *fn_ptr, - int *mvcost[2], int_mv *center_mv) { - int i, j, step; - - unsigned char *what = (*(b->base_src) + b->src); - int what_stride = b->src_stride; - unsigned char *in_what; - int pre_stride = x->e_mbd.pre.y_stride; - unsigned char *base_pre = x->e_mbd.pre.y_buffer; - int in_what_stride = pre_stride; - unsigned char *best_address; - - int tot_steps; - int_mv this_mv; - - unsigned int bestsad; - unsigned int thissad; - int best_site = 0; - int last_site = 0; - - int ref_row; - int ref_col; - int this_row_offset; - int this_col_offset; - search_site *ss; - - unsigned char *check_here; - - int *mvsadcost[2]; - int_mv fcenter_mv; - - mvsadcost[0] = x->mvsadcost[0]; - mvsadcost[1] = x->mvsadcost[1]; - fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3; - fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3; - - vp8_clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, - x->mv_row_max); - ref_row = ref_mv->as_mv.row; - ref_col = ref_mv->as_mv.col; - *num00 = 0; - best_mv->as_mv.row = ref_row; - best_mv->as_mv.col = ref_col; - - /* Work out the start point for the search */ - in_what = (unsigned char *)(base_pre + d->offset + (ref_row * pre_stride) + - ref_col); - best_address = in_what; - - /* Check the starting position */ - bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride) + - mvsad_err_cost(best_mv, &fcenter_mv, mvsadcost, sad_per_bit); - - /* search_param determines the length of the initial step and hence - * the number of iterations 0 = initial step (MAX_FIRST_STEP) pel : - * 1 = (MAX_FIRST_STEP/2) pel, 2 = (MAX_FIRST_STEP/4) pel... etc. - */ - ss = &x->ss[search_param * x->searches_per_step]; - tot_steps = (x->ss_count / x->searches_per_step) - search_param; - - i = 1; - - for (step = 0; step < tot_steps; ++step) { - for (j = 0; j < x->searches_per_step; ++j) { - /* Trap illegal vectors */ - this_row_offset = best_mv->as_mv.row + ss[i].mv.row; - this_col_offset = best_mv->as_mv.col + ss[i].mv.col; - - if ((this_col_offset > x->mv_col_min) && - (this_col_offset < x->mv_col_max) && - (this_row_offset > x->mv_row_min) && - (this_row_offset < x->mv_row_max)) - - { - check_here = ss[i].offset + best_address; - thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride); - - if (thissad < bestsad) { - this_mv.as_mv.row = this_row_offset; - this_mv.as_mv.col = this_col_offset; - thissad += - mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit); - - if (thissad < bestsad) { - bestsad = thissad; - best_site = i; - } - } - } - - i++; - } - - if (best_site != last_site) { - best_mv->as_mv.row += ss[best_site].mv.row; - best_mv->as_mv.col += ss[best_site].mv.col; - best_address += ss[best_site].offset; - last_site = best_site; - } else if (best_address == in_what) { - (*num00)++; - } - } - - this_mv.as_mv.row = clamp(best_mv->as_mv.row * 8, SHRT_MIN, SHRT_MAX); - this_mv.as_mv.col = clamp(best_mv->as_mv.col * 8, SHRT_MIN, SHRT_MAX); - - return fn_ptr->vf(what, what_stride, best_address, in_what_stride, &thissad) + - mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit); -} - -#if HAVE_SSE2 || HAVE_MSA || HAVE_LSX -int vp8_diamond_search_sadx4(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, - int_mv *best_mv, int search_param, int sad_per_bit, - int *num00, vp8_variance_fn_ptr_t *fn_ptr, - int *mvcost[2], int_mv *center_mv) { - int i, j, step; - - unsigned char *what = (*(b->base_src) + b->src); - int what_stride = b->src_stride; - unsigned char *in_what; - int pre_stride = x->e_mbd.pre.y_stride; - unsigned char *base_pre = x->e_mbd.pre.y_buffer; - int in_what_stride = pre_stride; - unsigned char *best_address; - - int tot_steps; - int_mv this_mv; - - unsigned int bestsad; - unsigned int thissad; - int best_site = 0; - int last_site = 0; - - int ref_row; - int ref_col; - int this_row_offset; - int this_col_offset; - search_site *ss; - - unsigned char *check_here; - - int *mvsadcost[2]; - int_mv fcenter_mv; - - mvsadcost[0] = x->mvsadcost[0]; - mvsadcost[1] = x->mvsadcost[1]; - fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3; - fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3; - - vp8_clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, - x->mv_row_max); - ref_row = ref_mv->as_mv.row; - ref_col = ref_mv->as_mv.col; - *num00 = 0; - best_mv->as_mv.row = ref_row; - best_mv->as_mv.col = ref_col; - - /* Work out the start point for the search */ - in_what = (unsigned char *)(base_pre + d->offset + (ref_row * pre_stride) + - ref_col); - best_address = in_what; - - /* Check the starting position */ - bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride) + - mvsad_err_cost(best_mv, &fcenter_mv, mvsadcost, sad_per_bit); - - /* search_param determines the length of the initial step and hence the - * number of iterations 0 = initial step (MAX_FIRST_STEP) pel : 1 = - * (MAX_FIRST_STEP/2) pel, 2 = (MAX_FIRST_STEP/4) pel... etc. - */ - ss = &x->ss[search_param * x->searches_per_step]; - tot_steps = (x->ss_count / x->searches_per_step) - search_param; - - i = 1; - - for (step = 0; step < tot_steps; ++step) { - int all_in = 1, t; - - /* To know if all neighbor points are within the bounds, 4 bounds - * checking are enough instead of checking 4 bounds for each - * points. - */ - all_in &= ((best_mv->as_mv.row + ss[i].mv.row) > x->mv_row_min); - all_in &= ((best_mv->as_mv.row + ss[i + 1].mv.row) < x->mv_row_max); - all_in &= ((best_mv->as_mv.col + ss[i + 2].mv.col) > x->mv_col_min); - all_in &= ((best_mv->as_mv.col + ss[i + 3].mv.col) < x->mv_col_max); - - if (all_in) { - unsigned int sad_array[4]; - - for (j = 0; j < x->searches_per_step; j += 4) { - const unsigned char *block_offset[4]; - - for (t = 0; t < 4; ++t) { - block_offset[t] = ss[i + t].offset + best_address; - } - - fn_ptr->sdx4df(what, what_stride, block_offset, in_what_stride, - sad_array); - - for (t = 0; t < 4; t++, i++) { - if (sad_array[t] < bestsad) { - this_mv.as_mv.row = best_mv->as_mv.row + ss[i].mv.row; - this_mv.as_mv.col = best_mv->as_mv.col + ss[i].mv.col; - sad_array[t] += - mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit); - - if (sad_array[t] < bestsad) { - bestsad = sad_array[t]; - best_site = i; - } - } - } - } - } else { - for (j = 0; j < x->searches_per_step; ++j) { - /* Trap illegal vectors */ - this_row_offset = best_mv->as_mv.row + ss[i].mv.row; - this_col_offset = best_mv->as_mv.col + ss[i].mv.col; - - if ((this_col_offset > x->mv_col_min) && - (this_col_offset < x->mv_col_max) && - (this_row_offset > x->mv_row_min) && - (this_row_offset < x->mv_row_max)) { - check_here = ss[i].offset + best_address; - thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride); - - if (thissad < bestsad) { - this_mv.as_mv.row = this_row_offset; - this_mv.as_mv.col = this_col_offset; - thissad += - mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit); - - if (thissad < bestsad) { - bestsad = thissad; - best_site = i; - } - } - } - i++; - } - } - - if (best_site != last_site) { - best_mv->as_mv.row += ss[best_site].mv.row; - best_mv->as_mv.col += ss[best_site].mv.col; - best_address += ss[best_site].offset; - last_site = best_site; - } else if (best_address == in_what) { - (*num00)++; - } - } - - this_mv.as_mv.row = clamp(best_mv->as_mv.row * 8, SHRT_MIN, SHRT_MAX); - this_mv.as_mv.col = clamp(best_mv->as_mv.col * 8, SHRT_MIN, SHRT_MAX); - - return fn_ptr->vf(what, what_stride, best_address, in_what_stride, &thissad) + - mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit); -} -#endif // HAVE_SSE2 || HAVE_MSA || HAVE_LSX - -int vp8_full_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, - int sad_per_bit, int distance, - vp8_variance_fn_ptr_t *fn_ptr, int *mvcost[2], - int_mv *center_mv) { - unsigned char *what = (*(b->base_src) + b->src); - int what_stride = b->src_stride; - unsigned char *in_what; - int pre_stride = x->e_mbd.pre.y_stride; - unsigned char *base_pre = x->e_mbd.pre.y_buffer; - int in_what_stride = pre_stride; - int mv_stride = pre_stride; - unsigned char *bestaddress; - int_mv *best_mv = &d->bmi.mv; - int_mv this_mv; - unsigned int bestsad; - unsigned int thissad; - int r, c; - - unsigned char *check_here; - - int ref_row = ref_mv->as_mv.row; - int ref_col = ref_mv->as_mv.col; - - int row_min = ref_row - distance; - int row_max = ref_row + distance; - int col_min = ref_col - distance; - int col_max = ref_col + distance; - - int *mvsadcost[2]; - int_mv fcenter_mv; - - mvsadcost[0] = x->mvsadcost[0]; - mvsadcost[1] = x->mvsadcost[1]; - fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3; - fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3; - - /* Work out the mid point for the search */ - in_what = base_pre + d->offset; - bestaddress = in_what + (ref_row * pre_stride) + ref_col; - - best_mv->as_mv.row = ref_row; - best_mv->as_mv.col = ref_col; - - /* Baseline value at the centre */ - bestsad = fn_ptr->sdf(what, what_stride, bestaddress, in_what_stride) + - mvsad_err_cost(best_mv, &fcenter_mv, mvsadcost, sad_per_bit); - - /* Apply further limits to prevent us looking using vectors that stretch - * beyond the UMV border - */ - if (col_min < x->mv_col_min) col_min = x->mv_col_min; - - if (col_max > x->mv_col_max) col_max = x->mv_col_max; - - if (row_min < x->mv_row_min) row_min = x->mv_row_min; - - if (row_max > x->mv_row_max) row_max = x->mv_row_max; - - for (r = row_min; r < row_max; ++r) { - this_mv.as_mv.row = r; - check_here = r * mv_stride + in_what + col_min; - - for (c = col_min; c < col_max; ++c) { - thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride); - - if (thissad < bestsad) { - this_mv.as_mv.col = c; - thissad += - mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit); - - if (thissad < bestsad) { - bestsad = thissad; - best_mv->as_mv.row = r; - best_mv->as_mv.col = c; - bestaddress = check_here; - } - } - - check_here++; - } - } - - this_mv.as_mv.row = clamp(best_mv->as_mv.row * 8, SHRT_MIN, SHRT_MAX); - this_mv.as_mv.col = clamp(best_mv->as_mv.col * 8, SHRT_MIN, SHRT_MAX); - - return fn_ptr->vf(what, what_stride, bestaddress, in_what_stride, &thissad) + - mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit); -} - -int vp8_refining_search_sad_c(MACROBLOCK *x, BLOCK *b, BLOCKD *d, - int_mv *ref_mv, int error_per_bit, - int search_range, vp8_variance_fn_ptr_t *fn_ptr, - int *mvcost[2], int_mv *center_mv) { - MV neighbors[4] = { { -1, 0 }, { 0, -1 }, { 0, 1 }, { 1, 0 } }; - int i, j; - short this_row_offset, this_col_offset; - - int what_stride = b->src_stride; - int pre_stride = x->e_mbd.pre.y_stride; - unsigned char *base_pre = x->e_mbd.pre.y_buffer; - int in_what_stride = pre_stride; - unsigned char *what = (*(b->base_src) + b->src); - unsigned char *best_address = - (unsigned char *)(base_pre + d->offset + - (ref_mv->as_mv.row * pre_stride) + ref_mv->as_mv.col); - unsigned char *check_here; - int_mv this_mv; - unsigned int bestsad; - unsigned int thissad; - - int *mvsadcost[2]; - int_mv fcenter_mv; - - mvsadcost[0] = x->mvsadcost[0]; - mvsadcost[1] = x->mvsadcost[1]; - fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3; - fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3; - - bestsad = fn_ptr->sdf(what, what_stride, best_address, in_what_stride) + - mvsad_err_cost(ref_mv, &fcenter_mv, mvsadcost, error_per_bit); - - for (i = 0; i < search_range; ++i) { - int best_site = -1; - - for (j = 0; j < 4; ++j) { - this_row_offset = ref_mv->as_mv.row + neighbors[j].row; - this_col_offset = ref_mv->as_mv.col + neighbors[j].col; - - if ((this_col_offset > x->mv_col_min) && - (this_col_offset < x->mv_col_max) && - (this_row_offset > x->mv_row_min) && - (this_row_offset < x->mv_row_max)) { - check_here = (neighbors[j].row) * in_what_stride + neighbors[j].col + - best_address; - thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride); - - if (thissad < bestsad) { - this_mv.as_mv.row = this_row_offset; - this_mv.as_mv.col = this_col_offset; - thissad += - mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, error_per_bit); - - if (thissad < bestsad) { - bestsad = thissad; - best_site = j; - } - } - } - } - - if (best_site == -1) { - break; - } else { - ref_mv->as_mv.row += neighbors[best_site].row; - ref_mv->as_mv.col += neighbors[best_site].col; - best_address += (neighbors[best_site].row) * in_what_stride + - neighbors[best_site].col; - } - } - - this_mv.as_mv.row = clamp(ref_mv->as_mv.row * 8, SHRT_MIN, SHRT_MAX); - this_mv.as_mv.col = clamp(ref_mv->as_mv.col * 8, SHRT_MIN, SHRT_MAX); - - return fn_ptr->vf(what, what_stride, best_address, in_what_stride, &thissad) + - mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit); -} - -#if HAVE_SSE2 || HAVE_MSA -int vp8_refining_search_sadx4(MACROBLOCK *x, BLOCK *b, BLOCKD *d, - int_mv *ref_mv, int error_per_bit, - int search_range, vp8_variance_fn_ptr_t *fn_ptr, - int *mvcost[2], int_mv *center_mv) { - MV neighbors[4] = { { -1, 0 }, { 0, -1 }, { 0, 1 }, { 1, 0 } }; - int i, j; - short this_row_offset, this_col_offset; - - int what_stride = b->src_stride; - int pre_stride = x->e_mbd.pre.y_stride; - unsigned char *base_pre = x->e_mbd.pre.y_buffer; - int in_what_stride = pre_stride; - unsigned char *what = (*(b->base_src) + b->src); - unsigned char *best_address = - (unsigned char *)(base_pre + d->offset + - (ref_mv->as_mv.row * pre_stride) + ref_mv->as_mv.col); - unsigned char *check_here; - int_mv this_mv; - unsigned int bestsad; - unsigned int thissad; - - int *mvsadcost[2]; - int_mv fcenter_mv; - - mvsadcost[0] = x->mvsadcost[0]; - mvsadcost[1] = x->mvsadcost[1]; - fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3; - fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3; - - bestsad = fn_ptr->sdf(what, what_stride, best_address, in_what_stride) + - mvsad_err_cost(ref_mv, &fcenter_mv, mvsadcost, error_per_bit); - - for (i = 0; i < search_range; ++i) { - int best_site = -1; - int all_in = 1; - - all_in &= ((ref_mv->as_mv.row - 1) > x->mv_row_min); - all_in &= ((ref_mv->as_mv.row + 1) < x->mv_row_max); - all_in &= ((ref_mv->as_mv.col - 1) > x->mv_col_min); - all_in &= ((ref_mv->as_mv.col + 1) < x->mv_col_max); - - if (all_in) { - unsigned int sad_array[4]; - const unsigned char *block_offset[4]; - block_offset[0] = best_address - in_what_stride; - block_offset[1] = best_address - 1; - block_offset[2] = best_address + 1; - block_offset[3] = best_address + in_what_stride; - - fn_ptr->sdx4df(what, what_stride, block_offset, in_what_stride, - sad_array); - - for (j = 0; j < 4; ++j) { - if (sad_array[j] < bestsad) { - this_mv.as_mv.row = ref_mv->as_mv.row + neighbors[j].row; - this_mv.as_mv.col = ref_mv->as_mv.col + neighbors[j].col; - sad_array[j] += - mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, error_per_bit); - - if (sad_array[j] < bestsad) { - bestsad = sad_array[j]; - best_site = j; - } - } - } - } else { - for (j = 0; j < 4; ++j) { - this_row_offset = ref_mv->as_mv.row + neighbors[j].row; - this_col_offset = ref_mv->as_mv.col + neighbors[j].col; - - if ((this_col_offset > x->mv_col_min) && - (this_col_offset < x->mv_col_max) && - (this_row_offset > x->mv_row_min) && - (this_row_offset < x->mv_row_max)) { - check_here = (neighbors[j].row) * in_what_stride + neighbors[j].col + - best_address; - thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride); - - if (thissad < bestsad) { - this_mv.as_mv.row = this_row_offset; - this_mv.as_mv.col = this_col_offset; - thissad += - mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, error_per_bit); - - if (thissad < bestsad) { - bestsad = thissad; - best_site = j; - } - } - } - } - } - - if (best_site == -1) { - break; - } else { - ref_mv->as_mv.row += neighbors[best_site].row; - ref_mv->as_mv.col += neighbors[best_site].col; - best_address += (neighbors[best_site].row) * in_what_stride + - neighbors[best_site].col; - } - } - - this_mv.as_mv.row = clamp(ref_mv->as_mv.row * 8, SHRT_MIN, SHRT_MAX); - this_mv.as_mv.col = clamp(ref_mv->as_mv.col * 8, SHRT_MIN, SHRT_MAX); - - return fn_ptr->vf(what, what_stride, best_address, in_what_stride, &thissad) + - mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit); -} -#endif // HAVE_SSE2 || HAVE_MSA diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mcomp.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mcomp.h deleted file mode 100644 index 1ee6fe5d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mcomp.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_MCOMP_H_ -#define VPX_VP8_ENCODER_MCOMP_H_ - -#include "block.h" -#include "vpx_dsp/variance.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* The maximum number of steps in a step search given the largest allowed - * initial step - */ -#define MAX_MVSEARCH_STEPS 8 - -/* Max full pel mv specified in 1 pel units */ -#define MAX_FULL_PEL_VAL ((1 << (MAX_MVSEARCH_STEPS)) - 1) - -/* Maximum size of the first step in full pel units */ -#define MAX_FIRST_STEP (1 << (MAX_MVSEARCH_STEPS - 1)) - -int vp8_mv_bit_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int Weight); -void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride); -void vp8_init3smotion_compensation(MACROBLOCK *x, int stride); - -int vp8_hex_search(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, - int_mv *best_mv, int search_param, int sad_per_bit, - const vp8_variance_fn_ptr_t *vfp, int *mvsadcost[2], - int_mv *center_mv); - -typedef int(fractional_mv_step_fp)(MACROBLOCK *x, BLOCK *b, BLOCKD *d, - int_mv *bestmv, int_mv *ref_mv, - int error_per_bit, - const vp8_variance_fn_ptr_t *vfp, - int *mvcost[2], int *distortion, - unsigned int *sse); - -fractional_mv_step_fp vp8_find_best_sub_pixel_step_iteratively; -fractional_mv_step_fp vp8_find_best_sub_pixel_step; -fractional_mv_step_fp vp8_find_best_half_pixel_step; -fractional_mv_step_fp vp8_skip_fractional_mv_step; - -int vp8_full_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, - int sad_per_bit, int distance, - vp8_variance_fn_ptr_t *fn_ptr, int *mvcost[2], - int_mv *center_mv); - -typedef int (*vp8_refining_search_fn_t)(MACROBLOCK *x, BLOCK *b, BLOCKD *d, - int_mv *ref_mv, int sad_per_bit, - int distance, - vp8_variance_fn_ptr_t *fn_ptr, - int *mvcost[2], int_mv *center_mv); - -typedef int (*vp8_diamond_search_fn_t)(MACROBLOCK *x, BLOCK *b, BLOCKD *d, - int_mv *ref_mv, int_mv *best_mv, - int search_param, int sad_per_bit, - int *num00, - vp8_variance_fn_ptr_t *fn_ptr, - int *mvcost[2], int_mv *center_mv); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_MCOMP_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/mmi/dct_mmi.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/mmi/dct_mmi.c deleted file mode 100644 index 0fd25fcd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/mmi/dct_mmi.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/asmdefs_mmi.h" - -/* clang-format off */ -/* TRANSPOSE_4H: transpose 4x4 matrix. - Input: ftmp1,ftmp2,ftmp3,ftmp4 - Output: ftmp1,ftmp2,ftmp3,ftmp4 - Note: ftmp0 always be 0, ftmp5~9 used for temporary value. - */ -#define TRANSPOSE_4H \ - MMI_LI(%[tmp0], 0x93) \ - "mtc1 %[tmp0], %[ftmp10] \n\t" \ - "punpcklhw %[ftmp5], %[ftmp1], %[ftmp0] \n\t" \ - "punpcklhw %[ftmp9], %[ftmp2], %[ftmp0] \n\t" \ - "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ - "por %[ftmp5], %[ftmp5], %[ftmp9] \n\t" \ - "punpckhhw %[ftmp6], %[ftmp1], %[ftmp0] \n\t" \ - "punpckhhw %[ftmp9], %[ftmp2], %[ftmp0] \n\t" \ - "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ - "por %[ftmp6], %[ftmp6], %[ftmp9] \n\t" \ - "punpcklhw %[ftmp7], %[ftmp3], %[ftmp0] \n\t" \ - "punpcklhw %[ftmp9], %[ftmp4], %[ftmp0] \n\t" \ - "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ - "por %[ftmp7], %[ftmp7], %[ftmp9] \n\t" \ - "punpckhhw %[ftmp8], %[ftmp3], %[ftmp0] \n\t" \ - "punpckhhw %[ftmp9], %[ftmp4], %[ftmp0] \n\t" \ - "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ - "por %[ftmp8], %[ftmp8], %[ftmp9] \n\t" \ - "punpcklwd %[ftmp1], %[ftmp5], %[ftmp7] \n\t" \ - "punpckhwd %[ftmp2], %[ftmp5], %[ftmp7] \n\t" \ - "punpcklwd %[ftmp3], %[ftmp6], %[ftmp8] \n\t" \ - "punpckhwd %[ftmp4], %[ftmp6], %[ftmp8] \n\t" -/* clang-format on */ - -void vp8_short_fdct4x4_mmi(int16_t *input, int16_t *output, int pitch) { - uint64_t tmp[1]; - int16_t *ip = input; - double ff_ph_op1, ff_ph_op3; - -#if _MIPS_SIM == _ABIO32 - register double ftmp0 asm("$f0"); - register double ftmp1 asm("$f2"); - register double ftmp2 asm("$f4"); - register double ftmp3 asm("$f6"); - register double ftmp4 asm("$f8"); - register double ftmp5 asm("$f10"); - register double ftmp6 asm("$f12"); - register double ftmp7 asm("$f14"); - register double ftmp8 asm("$f16"); - register double ftmp9 asm("$f18"); - register double ftmp10 asm("$f20"); - register double ftmp11 asm("$f22"); - register double ftmp12 asm("$f24"); -#else - register double ftmp0 asm("$f0"); - register double ftmp1 asm("$f1"); - register double ftmp2 asm("$f2"); - register double ftmp3 asm("$f3"); - register double ftmp4 asm("$f4"); - register double ftmp5 asm("$f5"); - register double ftmp6 asm("$f6"); - register double ftmp7 asm("$f7"); - register double ftmp8 asm("$f8"); - register double ftmp9 asm("$f9"); - register double ftmp10 asm("$f10"); - register double ftmp11 asm("$f11"); - register double ftmp12 asm("$f12"); -#endif // _MIPS_SIM == _ABIO32 - - DECLARE_ALIGNED(8, const uint64_t, ff_ph_01) = { 0x0001000100010001ULL }; - DECLARE_ALIGNED(8, const uint64_t, ff_ph_07) = { 0x0007000700070007ULL }; - DECLARE_ALIGNED(8, const uint64_t, ff_pw_12000) = { 0x00002ee000002ee0ULL }; - DECLARE_ALIGNED(8, const uint64_t, ff_pw_51000) = { 0x0000c7380000c738ULL }; - DECLARE_ALIGNED(8, const uint64_t, ff_pw_14500) = { 0x000038a4000038a4ULL }; - DECLARE_ALIGNED(8, const uint64_t, ff_pw_7500) = { 0x00001d4c00001d4cULL }; - DECLARE_ALIGNED(8, const uint64_t, ff_pw_5352) = { 0x000014e8000014e8ULL }; - DECLARE_ALIGNED(8, const uint64_t, ff_pw_2217) = { 0x000008a9000008a9ULL }; - DECLARE_ALIGNED(8, const uint64_t, ff_ph_8) = { 0x0008000800080008ULL }; - - /* clang-format off */ - __asm__ volatile ( - "dli %[tmp0], 0x14e808a914e808a9 \n\t" - "dmtc1 %[tmp0], %[ff_ph_op1] \n\t" - "dli %[tmp0], 0xeb1808a9eb1808a9 \n\t" - "dmtc1 %[tmp0], %[ff_ph_op3] \n\t" - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "gsldlc1 %[ftmp1], 0x07(%[ip]) \n\t" - "gsldrc1 %[ftmp1], 0x00(%[ip]) \n\t" - MMI_ADDU(%[ip], %[ip], %[pitch]) - "gsldlc1 %[ftmp2], 0x07(%[ip]) \n\t" - "gsldrc1 %[ftmp2], 0x00(%[ip]) \n\t" - MMI_ADDU(%[ip], %[ip], %[pitch]) - "gsldlc1 %[ftmp3], 0x07(%[ip]) \n\t" - "gsldrc1 %[ftmp3], 0x00(%[ip]) \n\t" - MMI_ADDU(%[ip], %[ip], %[pitch]) - "gsldlc1 %[ftmp4], 0x07(%[ip]) \n\t" - "gsldrc1 %[ftmp4], 0x00(%[ip]) \n\t" - MMI_ADDU(%[ip], %[ip], %[pitch]) - TRANSPOSE_4H - - "ldc1 %[ftmp11], %[ff_ph_8] \n\t" - // f1 + f4 - "paddh %[ftmp5], %[ftmp1], %[ftmp4] \n\t" - // a1 - "pmullh %[ftmp5], %[ftmp5], %[ftmp11] \n\t" - // f2 + f3 - "paddh %[ftmp6], %[ftmp2], %[ftmp3] \n\t" - // b1 - "pmullh %[ftmp6], %[ftmp6], %[ftmp11] \n\t" - // f2 - f3 - "psubh %[ftmp7], %[ftmp2], %[ftmp3] \n\t" - // c1 - "pmullh %[ftmp7], %[ftmp7], %[ftmp11] \n\t" - // f1 - f4 - "psubh %[ftmp8], %[ftmp1], %[ftmp4] \n\t" - // d1 - "pmullh %[ftmp8], %[ftmp8], %[ftmp11] \n\t" - // op[0] = a1 + b1 - "paddh %[ftmp1], %[ftmp5], %[ftmp6] \n\t" - // op[2] = a1 - b1 - "psubh %[ftmp3], %[ftmp5], %[ftmp6] \n\t" - - // op[1] = (c1 * 2217 + d1 * 5352 + 14500) >> 12 - MMI_LI(%[tmp0], 0x0c) - "dmtc1 %[tmp0], %[ftmp11] \n\t" - "ldc1 %[ftmp12], %[ff_pw_14500] \n\t" - "punpcklhw %[ftmp9], %[ftmp7], %[ftmp8] \n\t" - "pmaddhw %[ftmp5], %[ftmp9], %[ff_ph_op1] \n\t" - "punpckhhw %[ftmp9], %[ftmp7], %[ftmp8] \n\t" - "pmaddhw %[ftmp6], %[ftmp9], %[ff_ph_op1] \n\t" - "paddw %[ftmp5], %[ftmp5], %[ftmp12] \n\t" - "paddw %[ftmp6], %[ftmp6], %[ftmp12] \n\t" - "psraw %[ftmp5], %[ftmp5], %[ftmp11] \n\t" - "psraw %[ftmp6], %[ftmp6], %[ftmp11] \n\t" - "packsswh %[ftmp2], %[ftmp5], %[ftmp6] \n\t" - - // op[3] = (d1 * 2217 - c1 * 5352 + 7500) >> 12 - "ldc1 %[ftmp12], %[ff_pw_7500] \n\t" - "punpcklhw %[ftmp9], %[ftmp8], %[ftmp7] \n\t" - "pmaddhw %[ftmp5], %[ftmp9], %[ff_ph_op3] \n\t" - "punpckhhw %[ftmp9], %[ftmp8], %[ftmp7] \n\t" - "pmaddhw %[ftmp6], %[ftmp9], %[ff_ph_op3] \n\t" - "paddw %[ftmp5], %[ftmp5], %[ftmp12] \n\t" - "paddw %[ftmp6], %[ftmp6], %[ftmp12] \n\t" - "psraw %[ftmp5], %[ftmp5], %[ftmp11] \n\t" - "psraw %[ftmp6], %[ftmp6], %[ftmp11] \n\t" - "packsswh %[ftmp4], %[ftmp5], %[ftmp6] \n\t" - TRANSPOSE_4H - - "paddh %[ftmp5], %[ftmp1], %[ftmp4] \n\t" - "paddh %[ftmp6], %[ftmp2], %[ftmp3] \n\t" - "psubh %[ftmp7], %[ftmp2], %[ftmp3] \n\t" - "psubh %[ftmp8], %[ftmp1], %[ftmp4] \n\t" - - "pcmpeqh %[ftmp0], %[ftmp8], %[ftmp0] \n\t" - "ldc1 %[ftmp9], %[ff_ph_01] \n\t" - "paddh %[ftmp0], %[ftmp0], %[ftmp9] \n\t" - - "paddh %[ftmp1], %[ftmp5], %[ftmp6] \n\t" - "psubh %[ftmp2], %[ftmp5], %[ftmp6] \n\t" - "ldc1 %[ftmp9], %[ff_ph_07] \n\t" - "paddh %[ftmp1], %[ftmp1], %[ftmp9] \n\t" - "paddh %[ftmp2], %[ftmp2], %[ftmp9] \n\t" - MMI_LI(%[tmp0], 0x04) - "dmtc1 %[tmp0], %[ftmp9] \n\t" - "psrah %[ftmp1], %[ftmp1], %[ftmp9] \n\t" - "psrah %[ftmp2], %[ftmp2], %[ftmp9] \n\t" - - MMI_LI(%[tmp0], 0x10) - "mtc1 %[tmp0], %[ftmp9] \n\t" - "ldc1 %[ftmp12], %[ff_pw_12000] \n\t" - "punpcklhw %[ftmp5], %[ftmp7], %[ftmp8] \n\t" - "pmaddhw %[ftmp10], %[ftmp5], %[ff_ph_op1] \n\t" - "punpckhhw %[ftmp5], %[ftmp7], %[ftmp8] \n\t" - "pmaddhw %[ftmp11], %[ftmp5], %[ff_ph_op1] \n\t" - "paddw %[ftmp10], %[ftmp10], %[ftmp12] \n\t" - "paddw %[ftmp11], %[ftmp11], %[ftmp12] \n\t" - "psraw %[ftmp10], %[ftmp10], %[ftmp9] \n\t" - "psraw %[ftmp11], %[ftmp11], %[ftmp9] \n\t" - "packsswh %[ftmp3], %[ftmp10], %[ftmp11] \n\t" - "paddh %[ftmp3], %[ftmp3], %[ftmp0] \n\t" - - "ldc1 %[ftmp12], %[ff_pw_51000] \n\t" - "punpcklhw %[ftmp5], %[ftmp8], %[ftmp7] \n\t" - "pmaddhw %[ftmp10], %[ftmp5], %[ff_ph_op3] \n\t" - "punpckhhw %[ftmp5], %[ftmp8], %[ftmp7] \n\t" - "pmaddhw %[ftmp11], %[ftmp5], %[ff_ph_op3] \n\t" - "paddw %[ftmp10], %[ftmp10], %[ftmp12] \n\t" - "paddw %[ftmp11], %[ftmp11], %[ftmp12] \n\t" - "psraw %[ftmp10], %[ftmp10], %[ftmp9] \n\t" - "psraw %[ftmp11], %[ftmp11], %[ftmp9] \n\t" - "packsswh %[ftmp4], %[ftmp10], %[ftmp11] \n\t" - - "gssdlc1 %[ftmp1], 0x07(%[output]) \n\t" - "gssdrc1 %[ftmp1], 0x00(%[output]) \n\t" - "gssdlc1 %[ftmp3], 0x0f(%[output]) \n\t" - "gssdrc1 %[ftmp3], 0x08(%[output]) \n\t" - "gssdlc1 %[ftmp2], 0x17(%[output]) \n\t" - "gssdrc1 %[ftmp2], 0x10(%[output]) \n\t" - "gssdlc1 %[ftmp4], 0x1f(%[output]) \n\t" - "gssdrc1 %[ftmp4], 0x18(%[output]) \n\t" - - : [ftmp0] "=&f"(ftmp0), [ftmp1] "=&f"(ftmp1), [ftmp2] "=&f"(ftmp2), - [ftmp3] "=&f"(ftmp3), [ftmp4] "=&f"(ftmp4), [ftmp5] "=&f"(ftmp5), - [ftmp6] "=&f"(ftmp6), [ftmp7] "=&f"(ftmp7), [ftmp8] "=&f"(ftmp8), - [ftmp9] "=&f"(ftmp9), [ftmp10] "=&f"(ftmp10), [ftmp11] "=&f"(ftmp11), - [ftmp12] "=&f"(ftmp12), [tmp0] "=&r"(tmp[0]), [ip]"+&r"(ip), - [ff_ph_op1] "=&f"(ff_ph_op1), [ff_ph_op3] "=&f"(ff_ph_op3) - : [ff_ph_01] "m"(ff_ph_01), [ff_ph_07] "m"(ff_ph_07), - [ff_pw_14500] "m"(ff_pw_14500), [ff_pw_7500] "m"(ff_pw_7500), - [ff_pw_12000] "m"(ff_pw_12000), [ff_pw_51000] "m"(ff_pw_51000), - [ff_pw_5352]"m"(ff_pw_5352), [ff_pw_2217]"m"(ff_pw_2217), - [ff_ph_8]"m"(ff_ph_8), [pitch]"r"(pitch), [output] "r"(output) - : "memory" - ); - /* clang-format on */ -} - -void vp8_short_fdct8x4_mmi(int16_t *input, int16_t *output, int pitch) { - vp8_short_fdct4x4_mmi(input, output, pitch); - vp8_short_fdct4x4_mmi(input + 4, output + 16, pitch); -} - -void vp8_short_walsh4x4_mmi(int16_t *input, int16_t *output, int pitch) { - double ftmp[13], ff_ph_01, ff_pw_01, ff_pw_03, ff_pw_mask; - uint64_t tmp[1]; - - /* clang-format off */ - __asm__ volatile ( - "dli %[tmp0], 0x0001000100010001 \n\t" - "dmtc1 %[tmp0], %[ff_ph_01] \n\t" - "dli %[tmp0], 0x0000000100000001 \n\t" - "dmtc1 %[tmp0], %[ff_pw_01] \n\t" - "dli %[tmp0], 0x0000000300000003 \n\t" - "dmtc1 %[tmp0], %[ff_pw_03] \n\t" - "dli %[tmp0], 0x0001000000010000 \n\t" - "dmtc1 %[tmp0], %[ff_pw_mask] \n\t" - MMI_LI(%[tmp0], 0x02) - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "dmtc1 %[tmp0], %[ftmp11] \n\t" - - "gsldlc1 %[ftmp1], 0x07(%[ip]) \n\t" - "gsldrc1 %[ftmp1], 0x00(%[ip]) \n\t" - MMI_ADDU(%[ip], %[ip], %[pitch]) - "gsldlc1 %[ftmp2], 0x07(%[ip]) \n\t" - "gsldrc1 %[ftmp2], 0x00(%[ip]) \n\t" - MMI_ADDU(%[ip], %[ip], %[pitch]) - "gsldlc1 %[ftmp3], 0x07(%[ip]) \n\t" - "gsldrc1 %[ftmp3], 0x00(%[ip]) \n\t" - MMI_ADDU(%[ip], %[ip], %[pitch]) - "gsldlc1 %[ftmp4], 0x07(%[ip]) \n\t" - "gsldrc1 %[ftmp4], 0x00(%[ip]) \n\t" - TRANSPOSE_4H - - "psllh %[ftmp1], %[ftmp1], %[ftmp11] \n\t" - "psllh %[ftmp2], %[ftmp2], %[ftmp11] \n\t" - "psllh %[ftmp3], %[ftmp3], %[ftmp11] \n\t" - "psllh %[ftmp4], %[ftmp4], %[ftmp11] \n\t" - // a - "paddh %[ftmp5], %[ftmp1], %[ftmp3] \n\t" - // d - "paddh %[ftmp6], %[ftmp2], %[ftmp4] \n\t" - // c - "psubh %[ftmp7], %[ftmp2], %[ftmp4] \n\t" - // b - "psubh %[ftmp8], %[ftmp1], %[ftmp3] \n\t" - - // a + d - "paddh %[ftmp1], %[ftmp5], %[ftmp6] \n\t" - // b + c - "paddh %[ftmp2], %[ftmp8], %[ftmp7] \n\t" - // b - c - "psubh %[ftmp3], %[ftmp8], %[ftmp7] \n\t" - // a - d - "psubh %[ftmp4], %[ftmp5], %[ftmp6] \n\t" - - "pcmpeqh %[ftmp6], %[ftmp5], %[ftmp0] \n\t" - "paddh %[ftmp6], %[ftmp6], %[ff_ph_01] \n\t" - "paddh %[ftmp1], %[ftmp1], %[ftmp6] \n\t" - TRANSPOSE_4H - - // op[2], op[0] - "pmaddhw %[ftmp5], %[ftmp1], %[ff_pw_01] \n\t" - // op[3], op[1] - "pmaddhw %[ftmp1], %[ftmp1], %[ff_pw_mask] \n\t" - - // op[6], op[4] - "pmaddhw %[ftmp6], %[ftmp2], %[ff_pw_01] \n\t" - // op[7], op[5] - "pmaddhw %[ftmp2], %[ftmp2], %[ff_pw_mask] \n\t" - - // op[10], op[8] - "pmaddhw %[ftmp7], %[ftmp3], %[ff_pw_01] \n\t" - // op[11], op[9] - "pmaddhw %[ftmp3], %[ftmp3], %[ff_pw_mask] \n\t" - - // op[14], op[12] - "pmaddhw %[ftmp8], %[ftmp4], %[ff_pw_01] \n\t" - // op[15], op[13] - "pmaddhw %[ftmp4], %[ftmp4], %[ff_pw_mask] \n\t" - - // a1, a3 - "paddw %[ftmp9], %[ftmp5], %[ftmp7] \n\t" - // d1, d3 - "paddw %[ftmp10], %[ftmp6], %[ftmp8] \n\t" - // c1, c3 - "psubw %[ftmp11], %[ftmp6], %[ftmp8] \n\t" - // b1, b3 - "psubw %[ftmp12], %[ftmp5], %[ftmp7] \n\t" - - // a1 + d1, a3 + d3 - "paddw %[ftmp5], %[ftmp9], %[ftmp10] \n\t" - // b1 + c1, b3 + c3 - "paddw %[ftmp6], %[ftmp12], %[ftmp11] \n\t" - // b1 - c1, b3 - c3 - "psubw %[ftmp7], %[ftmp12], %[ftmp11] \n\t" - // a1 - d1, a3 - d3 - "psubw %[ftmp8], %[ftmp9], %[ftmp10] \n\t" - - // a2, a4 - "paddw %[ftmp9], %[ftmp1], %[ftmp3] \n\t" - // d2, d4 - "paddw %[ftmp10], %[ftmp2], %[ftmp4] \n\t" - // c2, c4 - "psubw %[ftmp11], %[ftmp2], %[ftmp4] \n\t" - // b2, b4 - "psubw %[ftmp12], %[ftmp1], %[ftmp3] \n\t" - - // a2 + d2, a4 + d4 - "paddw %[ftmp1], %[ftmp9], %[ftmp10] \n\t" - // b2 + c2, b4 + c4 - "paddw %[ftmp2], %[ftmp12], %[ftmp11] \n\t" - // b2 - c2, b4 - c4 - "psubw %[ftmp3], %[ftmp12], %[ftmp11] \n\t" - // a2 - d2, a4 - d4 - "psubw %[ftmp4], %[ftmp9], %[ftmp10] \n\t" - - MMI_LI(%[tmp0], 0x03) - "dmtc1 %[tmp0], %[ftmp11] \n\t" - - "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp1] \n\t" - "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" - "paddw %[ftmp1], %[ftmp1], %[ftmp9] \n\t" - "paddw %[ftmp1], %[ftmp1], %[ff_pw_03] \n\t" - "psraw %[ftmp1], %[ftmp1], %[ftmp11] \n\t" - - "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp2] \n\t" - "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" - "paddw %[ftmp2], %[ftmp2], %[ftmp9] \n\t" - "paddw %[ftmp2], %[ftmp2], %[ff_pw_03] \n\t" - "psraw %[ftmp2], %[ftmp2], %[ftmp11] \n\t" - - "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp3] \n\t" - "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" - "paddw %[ftmp3], %[ftmp3], %[ftmp9] \n\t" - "paddw %[ftmp3], %[ftmp3], %[ff_pw_03] \n\t" - "psraw %[ftmp3], %[ftmp3], %[ftmp11] \n\t" - - "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp4] \n\t" - "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" - "paddw %[ftmp4], %[ftmp4], %[ftmp9] \n\t" - "paddw %[ftmp4], %[ftmp4], %[ff_pw_03] \n\t" - "psraw %[ftmp4], %[ftmp4], %[ftmp11] \n\t" - - "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp5] \n\t" - "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" - "paddw %[ftmp5], %[ftmp5], %[ftmp9] \n\t" - "paddw %[ftmp5], %[ftmp5], %[ff_pw_03] \n\t" - "psraw %[ftmp5], %[ftmp5], %[ftmp11] \n\t" - - "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp6] \n\t" - "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" - "paddw %[ftmp6], %[ftmp6], %[ftmp9] \n\t" - "paddw %[ftmp6], %[ftmp6], %[ff_pw_03] \n\t" - "psraw %[ftmp6], %[ftmp6], %[ftmp11] \n\t" - - "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp7] \n\t" - "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" - "paddw %[ftmp7], %[ftmp7], %[ftmp9] \n\t" - "paddw %[ftmp7], %[ftmp7], %[ff_pw_03] \n\t" - "psraw %[ftmp7], %[ftmp7], %[ftmp11] \n\t" - - "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp8] \n\t" - "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" - "paddw %[ftmp8], %[ftmp8], %[ftmp9] \n\t" - "paddw %[ftmp8], %[ftmp8], %[ff_pw_03] \n\t" - "psraw %[ftmp8], %[ftmp8], %[ftmp11] \n\t" - - "packsswh %[ftmp1], %[ftmp1], %[ftmp5] \n\t" - "packsswh %[ftmp2], %[ftmp2], %[ftmp6] \n\t" - "packsswh %[ftmp3], %[ftmp3], %[ftmp7] \n\t" - "packsswh %[ftmp4], %[ftmp4], %[ftmp8] \n\t" - - MMI_LI(%[tmp0], 0x72) - "dmtc1 %[tmp0], %[ftmp11] \n\t" - "pshufh %[ftmp1], %[ftmp1], %[ftmp11] \n\t" - "pshufh %[ftmp2], %[ftmp2], %[ftmp11] \n\t" - "pshufh %[ftmp3], %[ftmp3], %[ftmp11] \n\t" - "pshufh %[ftmp4], %[ftmp4], %[ftmp11] \n\t" - - "gssdlc1 %[ftmp1], 0x07(%[op]) \n\t" - "gssdrc1 %[ftmp1], 0x00(%[op]) \n\t" - "gssdlc1 %[ftmp2], 0x0f(%[op]) \n\t" - "gssdrc1 %[ftmp2], 0x08(%[op]) \n\t" - "gssdlc1 %[ftmp3], 0x17(%[op]) \n\t" - "gssdrc1 %[ftmp3], 0x10(%[op]) \n\t" - "gssdlc1 %[ftmp4], 0x1f(%[op]) \n\t" - "gssdrc1 %[ftmp4], 0x18(%[op]) \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), - [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), - [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), - [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), - [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), - [ftmp12]"=&f"(ftmp[12]), [ff_pw_mask]"=&f"(ff_pw_mask), - [tmp0]"=&r"(tmp[0]), [ff_pw_01]"=&f"(ff_pw_01), - [ip]"+&r"(input), [ff_pw_03]"=&f"(ff_pw_03), - [ff_ph_01]"=&f"(ff_ph_01) - : [op]"r"(output), [pitch]"r"((mips_reg)pitch) - : "memory" - ); - /* clang-format on */ -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/mmi/vp8_quantize_mmi.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/mmi/vp8_quantize_mmi.c deleted file mode 100644 index 1986444a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/mmi/vp8_quantize_mmi.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/asmdefs_mmi.h" -#include "vp8/encoder/onyx_int.h" -#include "vp8/encoder/quantize.h" -#include "vp8/common/quant_common.h" - -#define REGULAR_SELECT_EOB(i, rc) \ - z = coeff_ptr[rc]; \ - sz = (z >> 31); \ - x = (z ^ sz) - sz; \ - zbin = zbin_ptr[rc] + *(zbin_boost_ptr++) + zbin_oq_value; \ - if (x >= zbin) { \ - x += round_ptr[rc]; \ - y = ((((x * quant_ptr[rc]) >> 16) + x) * quant_shift_ptr[rc]) >> 16; \ - if (y) { \ - x = (y ^ sz) - sz; \ - qcoeff_ptr[rc] = x; \ - dqcoeff_ptr[rc] = x * dequant_ptr[rc]; \ - eob = i; \ - zbin_boost_ptr = b->zrun_zbin_boost; \ - } \ - } - -void vp8_fast_quantize_b_mmi(BLOCK *b, BLOCKD *d) { - const int16_t *coeff_ptr = b->coeff; - const int16_t *round_ptr = b->round; - const int16_t *quant_ptr = b->quant_fast; - int16_t *qcoeff_ptr = d->qcoeff; - int16_t *dqcoeff_ptr = d->dqcoeff; - const int16_t *dequant_ptr = d->dequant; - const int16_t *inv_zig_zag = vp8_default_inv_zig_zag; - - double ftmp[13]; - uint64_t tmp[1]; - int64_t eob = 0; - double ones; - - __asm__ volatile( - // loop 0 ~ 7 - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "pcmpeqh %[ones], %[ones], %[ones] \n\t" - "gsldlc1 %[ftmp1], 0x07(%[coeff_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x00(%[coeff_ptr]) \n\t" - "dli %[tmp0], 0x0f \n\t" - "dmtc1 %[tmp0], %[ftmp9] \n\t" - "gsldlc1 %[ftmp2], 0x0f(%[coeff_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x08(%[coeff_ptr]) \n\t" - - "psrah %[ftmp3], %[ftmp1], %[ftmp9] \n\t" - "pxor %[ftmp1], %[ftmp3], %[ftmp1] \n\t" - "psubh %[ftmp1], %[ftmp1], %[ftmp3] \n\t" - "psrah %[ftmp4], %[ftmp2], %[ftmp9] \n\t" - "pxor %[ftmp2], %[ftmp4], %[ftmp2] \n\t" - "psubh %[ftmp2], %[ftmp2], %[ftmp4] \n\t" - - "gsldlc1 %[ftmp5], 0x07(%[round_ptr]) \n\t" - "gsldrc1 %[ftmp5], 0x00(%[round_ptr]) \n\t" - "gsldlc1 %[ftmp6], 0x0f(%[round_ptr]) \n\t" - "gsldrc1 %[ftmp6], 0x08(%[round_ptr]) \n\t" - "paddh %[ftmp5], %[ftmp5], %[ftmp1] \n\t" - "paddh %[ftmp6], %[ftmp6], %[ftmp2] \n\t" - "gsldlc1 %[ftmp7], 0x07(%[quant_ptr]) \n\t" - "gsldrc1 %[ftmp7], 0x00(%[quant_ptr]) \n\t" - "gsldlc1 %[ftmp8], 0x0f(%[quant_ptr]) \n\t" - "gsldrc1 %[ftmp8], 0x08(%[quant_ptr]) \n\t" - "pmulhuh %[ftmp5], %[ftmp5], %[ftmp7] \n\t" - "pmulhuh %[ftmp6], %[ftmp6], %[ftmp8] \n\t" - - "pxor %[ftmp7], %[ftmp5], %[ftmp3] \n\t" - "pxor %[ftmp8], %[ftmp6], %[ftmp4] \n\t" - "psubh %[ftmp7], %[ftmp7], %[ftmp3] \n\t" - "psubh %[ftmp8], %[ftmp8], %[ftmp4] \n\t" - "gssdlc1 %[ftmp7], 0x07(%[qcoeff_ptr]) \n\t" - "gssdrc1 %[ftmp7], 0x00(%[qcoeff_ptr]) \n\t" - "gssdlc1 %[ftmp8], 0x0f(%[qcoeff_ptr]) \n\t" - "gssdrc1 %[ftmp8], 0x08(%[qcoeff_ptr]) \n\t" - - "gsldlc1 %[ftmp1], 0x07(%[inv_zig_zag]) \n\t" - "gsldrc1 %[ftmp1], 0x00(%[inv_zig_zag]) \n\t" - "gsldlc1 %[ftmp2], 0x0f(%[inv_zig_zag]) \n\t" - "gsldrc1 %[ftmp2], 0x08(%[inv_zig_zag]) \n\t" - "pcmpeqh %[ftmp5], %[ftmp5], %[ftmp0] \n\t" - "pcmpeqh %[ftmp6], %[ftmp6], %[ftmp0] \n\t" - "pxor %[ftmp5], %[ftmp5], %[ones] \n\t" - "pxor %[ftmp6], %[ftmp6], %[ones] \n\t" - "pand %[ftmp5], %[ftmp5], %[ftmp1] \n\t" - "pand %[ftmp6], %[ftmp6], %[ftmp2] \n\t" - "pmaxsh %[ftmp10], %[ftmp5], %[ftmp6] \n\t" - - "gsldlc1 %[ftmp5], 0x07(%[dequant_ptr]) \n\t" - "gsldrc1 %[ftmp5], 0x00(%[dequant_ptr]) \n\t" - "gsldlc1 %[ftmp6], 0x0f(%[dequant_ptr]) \n\t" - "gsldrc1 %[ftmp6], 0x08(%[dequant_ptr]) \n\t" - "pmullh %[ftmp5], %[ftmp5], %[ftmp7] \n\t" - "pmullh %[ftmp6], %[ftmp6], %[ftmp8] \n\t" - "gssdlc1 %[ftmp5], 0x07(%[dqcoeff_ptr]) \n\t" - "gssdrc1 %[ftmp5], 0x00(%[dqcoeff_ptr]) \n\t" - "gssdlc1 %[ftmp6], 0x0f(%[dqcoeff_ptr]) \n\t" - "gssdrc1 %[ftmp6], 0x08(%[dqcoeff_ptr]) \n\t" - - // loop 8 ~ 15 - "gsldlc1 %[ftmp1], 0x17(%[coeff_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x10(%[coeff_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x1f(%[coeff_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x18(%[coeff_ptr]) \n\t" - - "psrah %[ftmp3], %[ftmp1], %[ftmp9] \n\t" - "pxor %[ftmp1], %[ftmp3], %[ftmp1] \n\t" - "psubh %[ftmp1], %[ftmp1], %[ftmp3] \n\t" - "psrah %[ftmp4], %[ftmp2], %[ftmp9] \n\t" - "pxor %[ftmp2], %[ftmp4], %[ftmp2] \n\t" - "psubh %[ftmp2], %[ftmp2], %[ftmp4] \n\t" - - "gsldlc1 %[ftmp5], 0x17(%[round_ptr]) \n\t" - "gsldrc1 %[ftmp5], 0x10(%[round_ptr]) \n\t" - "gsldlc1 %[ftmp6], 0x1f(%[round_ptr]) \n\t" - "gsldrc1 %[ftmp6], 0x18(%[round_ptr]) \n\t" - "paddh %[ftmp5], %[ftmp5], %[ftmp1] \n\t" - "paddh %[ftmp6], %[ftmp6], %[ftmp2] \n\t" - "gsldlc1 %[ftmp7], 0x17(%[quant_ptr]) \n\t" - "gsldrc1 %[ftmp7], 0x10(%[quant_ptr]) \n\t" - "gsldlc1 %[ftmp8], 0x1f(%[quant_ptr]) \n\t" - "gsldrc1 %[ftmp8], 0x18(%[quant_ptr]) \n\t" - "pmulhuh %[ftmp5], %[ftmp5], %[ftmp7] \n\t" - "pmulhuh %[ftmp6], %[ftmp6], %[ftmp8] \n\t" - - "pxor %[ftmp7], %[ftmp5], %[ftmp3] \n\t" - "pxor %[ftmp8], %[ftmp6], %[ftmp4] \n\t" - "psubh %[ftmp7], %[ftmp7], %[ftmp3] \n\t" - "psubh %[ftmp8], %[ftmp8], %[ftmp4] \n\t" - "gssdlc1 %[ftmp7], 0x17(%[qcoeff_ptr]) \n\t" - "gssdrc1 %[ftmp7], 0x10(%[qcoeff_ptr]) \n\t" - "gssdlc1 %[ftmp8], 0x1f(%[qcoeff_ptr]) \n\t" - "gssdrc1 %[ftmp8], 0x18(%[qcoeff_ptr]) \n\t" - - "gsldlc1 %[ftmp1], 0x17(%[inv_zig_zag]) \n\t" - "gsldrc1 %[ftmp1], 0x10(%[inv_zig_zag]) \n\t" - "gsldlc1 %[ftmp2], 0x1f(%[inv_zig_zag]) \n\t" - "gsldrc1 %[ftmp2], 0x18(%[inv_zig_zag]) \n\t" - "pcmpeqh %[ftmp5], %[ftmp5], %[ftmp0] \n\t" - "pcmpeqh %[ftmp6], %[ftmp6], %[ftmp0] \n\t" - "pxor %[ftmp5], %[ftmp5], %[ones] \n\t" - "pxor %[ftmp6], %[ftmp6], %[ones] \n\t" - "pand %[ftmp5], %[ftmp5], %[ftmp1] \n\t" - "pand %[ftmp6], %[ftmp6], %[ftmp2] \n\t" - "pmaxsh %[ftmp11], %[ftmp5], %[ftmp6] \n\t" - - "gsldlc1 %[ftmp5], 0x17(%[dequant_ptr]) \n\t" - "gsldrc1 %[ftmp5], 0x10(%[dequant_ptr]) \n\t" - "gsldlc1 %[ftmp6], 0x1f(%[dequant_ptr]) \n\t" - "gsldrc1 %[ftmp6], 0x18(%[dequant_ptr]) \n\t" - "pmullh %[ftmp5], %[ftmp5], %[ftmp7] \n\t" - "pmullh %[ftmp6], %[ftmp6], %[ftmp8] \n\t" - "gssdlc1 %[ftmp5], 0x17(%[dqcoeff_ptr]) \n\t" - "gssdrc1 %[ftmp5], 0x10(%[dqcoeff_ptr]) \n\t" - "gssdlc1 %[ftmp6], 0x1f(%[dqcoeff_ptr]) \n\t" - "gssdrc1 %[ftmp6], 0x18(%[dqcoeff_ptr]) \n\t" - - "dli %[tmp0], 0x10 \n\t" - "dmtc1 %[tmp0], %[ftmp9] \n\t" - - "pmaxsh %[ftmp10], %[ftmp10], %[ftmp11] \n\t" - "psrlw %[ftmp11], %[ftmp10], %[ftmp9] \n\t" - "pmaxsh %[ftmp10], %[ftmp10], %[ftmp11] \n\t" - "dli %[tmp0], 0xaa \n\t" - "dmtc1 %[tmp0], %[ftmp9] \n\t" - "pshufh %[ftmp11], %[ftmp10], %[ftmp9] \n\t" - "pmaxsh %[ftmp10], %[ftmp10], %[ftmp11] \n\t" - "dli %[tmp0], 0xffff \n\t" - "dmtc1 %[tmp0], %[ftmp9] \n\t" - "pand %[ftmp10], %[ftmp10], %[ftmp9] \n\t" - "gssdlc1 %[ftmp10], 0x07(%[eob]) \n\t" - "gssdrc1 %[ftmp10], 0x00(%[eob]) \n\t" - : [ftmp0] "=&f"(ftmp[0]), [ftmp1] "=&f"(ftmp[1]), [ftmp2] "=&f"(ftmp[2]), - [ftmp3] "=&f"(ftmp[3]), [ftmp4] "=&f"(ftmp[4]), [ftmp5] "=&f"(ftmp[5]), - [ftmp6] "=&f"(ftmp[6]), [ftmp7] "=&f"(ftmp[7]), [ftmp8] "=&f"(ftmp[8]), - [ftmp9] "=&f"(ftmp[9]), [ftmp10] "=&f"(ftmp[10]), - [ftmp11] "=&f"(ftmp[11]), [ftmp12] "=&f"(ftmp[12]), - [tmp0] "=&r"(tmp[0]), [ones] "=&f"(ones) - : [coeff_ptr] "r"((mips_reg)coeff_ptr), - [qcoeff_ptr] "r"((mips_reg)qcoeff_ptr), - [dequant_ptr] "r"((mips_reg)dequant_ptr), - [round_ptr] "r"((mips_reg)round_ptr), - [quant_ptr] "r"((mips_reg)quant_ptr), - [dqcoeff_ptr] "r"((mips_reg)dqcoeff_ptr), - [inv_zig_zag] "r"((mips_reg)inv_zig_zag), [eob] "r"((mips_reg)&eob) - : "memory"); - - *d->eob = eob; -} - -void vp8_regular_quantize_b_mmi(BLOCK *b, BLOCKD *d) { - int eob = 0; - int x, y, z, sz, zbin; - const int16_t *zbin_boost_ptr = b->zrun_zbin_boost; - const int16_t *coeff_ptr = b->coeff; - const int16_t *zbin_ptr = b->zbin; - const int16_t *round_ptr = b->round; - const int16_t *quant_ptr = b->quant; - const int16_t *quant_shift_ptr = b->quant_shift; - int16_t *qcoeff_ptr = d->qcoeff; - int16_t *dqcoeff_ptr = d->dqcoeff; - const int16_t *dequant_ptr = d->dequant; - const int16_t zbin_oq_value = b->zbin_extra; - register double ftmp0 asm("$f0"); - - // memset(qcoeff_ptr, 0, 32); - // memset(dqcoeff_ptr, 0, 32); - /* clang-format off */ - __asm__ volatile ( - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "gssdlc1 %[ftmp0], 0x07(%[qcoeff_ptr]) \n\t" - "gssdrc1 %[ftmp0], 0x00(%[qcoeff_ptr]) \n\t" - "gssdlc1 %[ftmp0], 0x0f(%[qcoeff_ptr]) \n\t" - "gssdrc1 %[ftmp0], 0x08(%[qcoeff_ptr]) \n\t" - "gssdlc1 %[ftmp0], 0x17(%[qcoeff_ptr]) \n\t" - "gssdrc1 %[ftmp0], 0x10(%[qcoeff_ptr]) \n\t" - "gssdlc1 %[ftmp0], 0x1f(%[qcoeff_ptr]) \n\t" - "gssdrc1 %[ftmp0], 0x18(%[qcoeff_ptr]) \n\t" - - "gssdlc1 %[ftmp0], 0x07(%[dqcoeff_ptr]) \n\t" - "gssdrc1 %[ftmp0], 0x00(%[dqcoeff_ptr]) \n\t" - "gssdlc1 %[ftmp0], 0x0f(%[dqcoeff_ptr]) \n\t" - "gssdrc1 %[ftmp0], 0x08(%[dqcoeff_ptr]) \n\t" - "gssdlc1 %[ftmp0], 0x17(%[dqcoeff_ptr]) \n\t" - "gssdrc1 %[ftmp0], 0x10(%[dqcoeff_ptr]) \n\t" - "gssdlc1 %[ftmp0], 0x1f(%[dqcoeff_ptr]) \n\t" - "gssdrc1 %[ftmp0], 0x18(%[dqcoeff_ptr]) \n\t" - : [ftmp0]"=&f"(ftmp0) - : [qcoeff_ptr]"r"(qcoeff_ptr), [dqcoeff_ptr]"r"(dqcoeff_ptr) - : "memory" - ); - /* clang-format on */ - - REGULAR_SELECT_EOB(1, 0); - REGULAR_SELECT_EOB(2, 1); - REGULAR_SELECT_EOB(3, 4); - REGULAR_SELECT_EOB(4, 8); - REGULAR_SELECT_EOB(5, 5); - REGULAR_SELECT_EOB(6, 2); - REGULAR_SELECT_EOB(7, 3); - REGULAR_SELECT_EOB(8, 6); - REGULAR_SELECT_EOB(9, 9); - REGULAR_SELECT_EOB(10, 12); - REGULAR_SELECT_EOB(11, 13); - REGULAR_SELECT_EOB(12, 10); - REGULAR_SELECT_EOB(13, 7); - REGULAR_SELECT_EOB(14, 11); - REGULAR_SELECT_EOB(15, 14); - REGULAR_SELECT_EOB(16, 15); - - *d->eob = (char)eob; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/msa/dct_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/msa/dct_msa.c deleted file mode 100644 index 30846675..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/msa/dct_msa.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vp8/common/mips/msa/vp8_macros_msa.h" - -#define TRANSPOSE4x4_H(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - v8i16 s0_m, s1_m, tp0_m, tp1_m, tp2_m, tp3_m; \ - \ - ILVR_H2_SH(in2, in0, in3, in1, s0_m, s1_m); \ - ILVRL_H2_SH(s1_m, s0_m, tp0_m, tp1_m); \ - ILVL_H2_SH(in2, in0, in3, in1, s0_m, s1_m); \ - ILVRL_H2_SH(s1_m, s0_m, tp2_m, tp3_m); \ - PCKEV_D2_SH(tp2_m, tp0_m, tp3_m, tp1_m, out0, out2); \ - PCKOD_D2_SH(tp2_m, tp0_m, tp3_m, tp1_m, out1, out3); \ - } - -#define SET_DOTP_VALUES(coeff, val0, val1, val2, const1, const2) \ - { \ - v8i16 tmp0_m; \ - \ - SPLATI_H3_SH(coeff, val0, val1, val2, tmp0_m, const1, const2); \ - ILVEV_H2_SH(tmp0_m, const1, const2, tmp0_m, const1, const2); \ - } - -#define RET_1_IF_NZERO_H(in0) \ - ({ \ - v8i16 tmp0_m; \ - v8i16 one_m = __msa_ldi_h(1); \ - \ - tmp0_m = __msa_ceqi_h(in0, 0); \ - tmp0_m = tmp0_m ^ 255; \ - tmp0_m = one_m & tmp0_m; \ - \ - tmp0_m; \ - }) - -#define RET_1_IF_NZERO_W(in0) \ - ({ \ - v4i32 tmp0_m; \ - v4i32 one_m = __msa_ldi_w(1); \ - \ - tmp0_m = __msa_ceqi_w(in0, 0); \ - tmp0_m = tmp0_m ^ 255; \ - tmp0_m = one_m & tmp0_m; \ - \ - tmp0_m; \ - }) - -#define RET_1_IF_NEG_W(in0) \ - ({ \ - v4i32 tmp0_m; \ - \ - v4i32 one_m = __msa_ldi_w(1); \ - tmp0_m = __msa_clti_s_w(in0, 0); \ - tmp0_m = one_m & tmp0_m; \ - \ - tmp0_m; \ - }) - -void vp8_short_fdct4x4_msa(int16_t *input, int16_t *output, int32_t pitch) { - v8i16 in0, in1, in2, in3; - v8i16 temp0, temp1; - v8i16 const0, const1; - v8i16 coeff = { 2217, 5352, -5352, 14500, 7500, 12000, 25000, 26000 }; - v4i32 out0, out1, out2, out3; - v8i16 zero = { 0 }; - - LD_SH4(input, pitch / 2, in0, in1, in2, in3); - TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); - - BUTTERFLY_4(in0, in1, in2, in3, temp0, temp1, in1, in3); - SLLI_4V(temp0, temp1, in1, in3, 3); - in0 = temp0 + temp1; - in2 = temp0 - temp1; - SET_DOTP_VALUES(coeff, 0, 1, 2, const0, const1); - temp0 = __msa_ilvr_h(in3, in1); - in1 = __msa_splati_h(coeff, 3); - out0 = (v4i32)__msa_ilvev_h(zero, in1); - coeff = __msa_ilvl_h(zero, coeff); - out1 = __msa_splati_w((v4i32)coeff, 0); - DPADD_SH2_SW(temp0, temp0, const0, const1, out0, out1); - out0 >>= 12; - out1 >>= 12; - PCKEV_H2_SH(out0, out0, out1, out1, in1, in3); - TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); - - BUTTERFLY_4(in0, in1, in2, in3, temp0, temp1, in1, in3); - in0 = temp0 + temp1 + 7; - in2 = temp0 - temp1 + 7; - in0 >>= 4; - in2 >>= 4; - ILVR_H2_SW(zero, in0, zero, in2, out0, out2); - temp1 = RET_1_IF_NZERO_H(in3); - ILVR_H2_SH(zero, temp1, in3, in1, temp1, temp0); - SPLATI_W2_SW(coeff, 2, out3, out1); - out3 += out1; - out1 = __msa_splati_w((v4i32)coeff, 1); - DPADD_SH2_SW(temp0, temp0, const0, const1, out1, out3); - out1 >>= 16; - out3 >>= 16; - out1 += (v4i32)temp1; - PCKEV_H2_SH(out1, out0, out3, out2, in0, in2); - ST_SH2(in0, in2, output, 8); -} - -void vp8_short_fdct8x4_msa(int16_t *input, int16_t *output, int32_t pitch) { - v8i16 in0, in1, in2, in3; - v8i16 temp0, temp1, tmp0, tmp1; - v8i16 const0, const1, const2; - v8i16 coeff = { 2217, 5352, -5352, 14500, 7500, 12000, 25000, 26000 }; - v8i16 zero = { 0 }; - v4i32 vec0_w, vec1_w, vec2_w, vec3_w; - - LD_SH4(input, pitch / 2, in0, in1, in2, in3); - TRANSPOSE4x4_H(in0, in1, in2, in3, in0, in1, in2, in3); - - BUTTERFLY_4(in0, in1, in2, in3, temp0, temp1, in1, in3); - SLLI_4V(temp0, temp1, in1, in3, 3); - in0 = temp0 + temp1; - in2 = temp0 - temp1; - SET_DOTP_VALUES(coeff, 0, 1, 2, const1, const2); - temp0 = __msa_splati_h(coeff, 3); - vec1_w = (v4i32)__msa_ilvev_h(zero, temp0); - coeff = __msa_ilvl_h(zero, coeff); - vec3_w = __msa_splati_w((v4i32)coeff, 0); - ILVRL_H2_SH(in3, in1, tmp1, tmp0); - vec0_w = vec1_w; - vec2_w = vec3_w; - DPADD_SH4_SW(tmp1, tmp0, tmp1, tmp0, const1, const1, const2, const2, vec0_w, - vec1_w, vec2_w, vec3_w); - SRA_4V(vec1_w, vec0_w, vec3_w, vec2_w, 12); - PCKEV_H2_SH(vec1_w, vec0_w, vec3_w, vec2_w, in1, in3); - TRANSPOSE4x4_H(in0, in1, in2, in3, in0, in1, in2, in3); - - BUTTERFLY_4(in0, in1, in2, in3, temp0, temp1, in1, in3); - in0 = temp0 + temp1 + 7; - in2 = temp0 - temp1 + 7; - in0 >>= 4; - in2 >>= 4; - SPLATI_W2_SW(coeff, 2, vec3_w, vec1_w); - vec3_w += vec1_w; - vec1_w = __msa_splati_w((v4i32)coeff, 1); - const0 = RET_1_IF_NZERO_H(in3); - ILVRL_H2_SH(in3, in1, tmp1, tmp0); - vec0_w = vec1_w; - vec2_w = vec3_w; - DPADD_SH4_SW(tmp1, tmp0, tmp1, tmp0, const1, const1, const2, const2, vec0_w, - vec1_w, vec2_w, vec3_w); - SRA_4V(vec1_w, vec0_w, vec3_w, vec2_w, 16); - PCKEV_H2_SH(vec1_w, vec0_w, vec3_w, vec2_w, in1, in3); - in1 += const0; - PCKEV_D2_SH(in1, in0, in3, in2, temp0, temp1); - ST_SH2(temp0, temp1, output, 8); - - PCKOD_D2_SH(in1, in0, in3, in2, in0, in2); - ST_SH2(in0, in2, output + 16, 8); -} - -void vp8_short_walsh4x4_msa(int16_t *input, int16_t *output, int32_t pitch) { - v8i16 in0_h, in1_h, in2_h, in3_h; - v4i32 in0_w, in1_w, in2_w, in3_w, temp0, temp1, temp2, temp3; - - LD_SH4(input, pitch / 2, in0_h, in1_h, in2_h, in3_h); - TRANSPOSE4x4_SH_SH(in0_h, in1_h, in2_h, in3_h, in0_h, in1_h, in2_h, in3_h); - - UNPCK_R_SH_SW(in0_h, in0_w); - UNPCK_R_SH_SW(in1_h, in1_w); - UNPCK_R_SH_SW(in2_h, in2_w); - UNPCK_R_SH_SW(in3_h, in3_w); - BUTTERFLY_4(in0_w, in1_w, in3_w, in2_w, temp0, temp3, temp2, temp1); - SLLI_4V(temp0, temp1, temp2, temp3, 2); - BUTTERFLY_4(temp0, temp1, temp2, temp3, in0_w, in1_w, in2_w, in3_w); - temp0 = RET_1_IF_NZERO_W(temp0); - in0_w += temp0; - TRANSPOSE4x4_SW_SW(in0_w, in1_w, in2_w, in3_w, in0_w, in1_w, in2_w, in3_w); - - BUTTERFLY_4(in0_w, in1_w, in3_w, in2_w, temp0, temp3, temp2, temp1); - BUTTERFLY_4(temp0, temp1, temp2, temp3, in0_w, in1_w, in2_w, in3_w); - in0_w += RET_1_IF_NEG_W(in0_w); - in1_w += RET_1_IF_NEG_W(in1_w); - in2_w += RET_1_IF_NEG_W(in2_w); - in3_w += RET_1_IF_NEG_W(in3_w); - ADD4(in0_w, 3, in1_w, 3, in2_w, 3, in3_w, 3, in0_w, in1_w, in2_w, in3_w); - SRA_4V(in0_w, in1_w, in2_w, in3_w, 3); - PCKEV_H2_SH(in1_w, in0_w, in3_w, in2_w, in0_h, in1_h); - ST_SH2(in0_h, in1_h, output, 8); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/msa/denoising_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/msa/denoising_msa.c deleted file mode 100644 index f8b653a9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/msa/denoising_msa.c +++ /dev/null @@ -1,568 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vp8_rtcd.h" -#include "vp8/common/mips/msa/vp8_macros_msa.h" -#include "vp8/encoder/denoising.h" - -int32_t vp8_denoiser_filter_msa(uint8_t *mc_running_avg_y_ptr, - int32_t mc_avg_y_stride, - uint8_t *running_avg_y_ptr, - int32_t avg_y_stride, uint8_t *sig_ptr, - int32_t sig_stride, uint32_t motion_magnitude, - int32_t increase_denoising) { - uint8_t *running_avg_y_start = running_avg_y_ptr; - uint8_t *sig_start = sig_ptr; - int32_t cnt = 0; - int32_t sum_diff = 0; - int32_t shift_inc1 = 3; - int32_t delta = 0; - int32_t sum_diff_thresh; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v16u8 src8, src9, src10, src11, src12, src13, src14, src15; - v16u8 mc_running_avg_y0, running_avg_y, sig0; - v16u8 mc_running_avg_y1, running_avg_y1, sig1; - v16u8 coeff0, coeff1; - v8i16 diff0, diff1, abs_diff0, abs_diff1, abs_diff_neg0, abs_diff_neg1; - v8i16 adjust0, adjust1, adjust2, adjust3; - v8i16 shift_inc1_vec = { 0 }; - v8i16 col_sum0 = { 0 }; - v8i16 col_sum1 = { 0 }; - v8i16 col_sum2 = { 0 }; - v8i16 col_sum3 = { 0 }; - v8i16 temp0_h, temp1_h, temp2_h, temp3_h, cmp, delta_vec; - v4i32 temp0_w; - v2i64 temp0_d, temp1_d; - v8i16 zero = { 0 }; - v8i16 one = __msa_ldi_h(1); - v8i16 four = __msa_ldi_h(4); - v8i16 val_127 = __msa_ldi_h(127); - v8i16 adj_val = { 6, 4, 3, 0, -6, -4, -3, 0 }; - - if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) { - adj_val = __msa_add_a_h(adj_val, one); - if (increase_denoising) { - adj_val = __msa_add_a_h(adj_val, one); - shift_inc1 = 4; - } - - temp0_h = zero - adj_val; - adj_val = (v8i16)__msa_ilvev_d((v2i64)temp0_h, (v2i64)adj_val); - } - - adj_val = __msa_insert_h(adj_val, 3, cnt); - adj_val = __msa_insert_h(adj_val, 7, cnt); - shift_inc1_vec = __msa_fill_h(shift_inc1); - - for (cnt = 8; cnt--;) { - v8i16 mask0 = { 0 }; - v8i16 mask1 = { 0 }; - - mc_running_avg_y0 = LD_UB(mc_running_avg_y_ptr); - sig0 = LD_UB(sig_ptr); - sig_ptr += sig_stride; - mc_running_avg_y_ptr += mc_avg_y_stride; - - mc_running_avg_y1 = LD_UB(mc_running_avg_y_ptr); - sig1 = LD_UB(sig_ptr); - - ILVRL_B2_UB(mc_running_avg_y0, sig0, coeff0, coeff1); - HSUB_UB2_SH(coeff0, coeff1, diff0, diff1); - abs_diff0 = __msa_add_a_h(diff0, zero); - abs_diff1 = __msa_add_a_h(diff1, zero); - cmp = __msa_clei_s_h(abs_diff0, 15); - cmp = cmp & one; - mask0 += cmp; - cmp = __msa_clei_s_h(abs_diff0, 7); - cmp = cmp & one; - mask0 += cmp; - cmp = abs_diff0 < shift_inc1_vec; - cmp = cmp & one; - mask0 += cmp; - cmp = __msa_clei_s_h(abs_diff1, 15); - cmp = cmp & one; - mask1 += cmp; - cmp = __msa_clei_s_h(abs_diff1, 7); - cmp = cmp & one; - mask1 += cmp; - cmp = abs_diff1 < shift_inc1_vec; - cmp = cmp & one; - mask1 += cmp; - temp0_h = __msa_clei_s_h(diff0, 0); - temp0_h = temp0_h & four; - mask0 += temp0_h; - temp1_h = __msa_clei_s_h(diff1, 0); - temp1_h = temp1_h & four; - mask1 += temp1_h; - VSHF_H2_SH(adj_val, adj_val, adj_val, adj_val, mask0, mask1, adjust0, - adjust1); - temp2_h = __msa_ceqi_h(adjust0, 0); - temp3_h = __msa_ceqi_h(adjust1, 0); - adjust0 = (v8i16)__msa_bmnz_v((v16u8)adjust0, (v16u8)diff0, (v16u8)temp2_h); - adjust1 = (v8i16)__msa_bmnz_v((v16u8)adjust1, (v16u8)diff1, (v16u8)temp3_h); - ADD2(col_sum0, adjust0, col_sum1, adjust1, col_sum0, col_sum1); - UNPCK_UB_SH(sig0, temp0_h, temp1_h); - ADD2(temp0_h, adjust0, temp1_h, adjust1, temp0_h, temp1_h); - MAXI_SH2_SH(temp0_h, temp1_h, 0); - SAT_UH2_SH(temp0_h, temp1_h, 7); - temp2_h = (v8i16)__msa_pckev_b((v16i8)temp3_h, (v16i8)temp2_h); - running_avg_y = (v16u8)__msa_pckev_b((v16i8)temp1_h, (v16i8)temp0_h); - running_avg_y = - __msa_bmnz_v(running_avg_y, mc_running_avg_y0, (v16u8)temp2_h); - ST_UB(running_avg_y, running_avg_y_ptr); - running_avg_y_ptr += avg_y_stride; - - mask0 = zero; - mask1 = zero; - ILVRL_B2_UB(mc_running_avg_y1, sig1, coeff0, coeff1); - HSUB_UB2_SH(coeff0, coeff1, diff0, diff1); - abs_diff0 = __msa_add_a_h(diff0, zero); - abs_diff1 = __msa_add_a_h(diff1, zero); - cmp = __msa_clei_s_h(abs_diff0, 15); - cmp = cmp & one; - mask0 += cmp; - cmp = __msa_clei_s_h(abs_diff0, 7); - cmp = cmp & one; - mask0 += cmp; - cmp = abs_diff0 < shift_inc1_vec; - cmp = cmp & one; - mask0 += cmp; - cmp = __msa_clei_s_h(abs_diff1, 15); - cmp = cmp & one; - mask1 += cmp; - cmp = __msa_clei_s_h(abs_diff1, 7); - cmp = cmp & one; - mask1 += cmp; - cmp = abs_diff1 < shift_inc1_vec; - cmp = cmp & one; - mask1 += cmp; - temp0_h = __msa_clei_s_h(diff0, 0); - temp0_h = temp0_h & four; - mask0 += temp0_h; - temp1_h = __msa_clei_s_h(diff1, 0); - temp1_h = temp1_h & four; - mask1 += temp1_h; - VSHF_H2_SH(adj_val, adj_val, adj_val, adj_val, mask0, mask1, adjust0, - adjust1); - temp2_h = __msa_ceqi_h(adjust0, 0); - temp3_h = __msa_ceqi_h(adjust1, 0); - adjust0 = (v8i16)__msa_bmnz_v((v16u8)adjust0, (v16u8)diff0, (v16u8)temp2_h); - adjust1 = (v8i16)__msa_bmnz_v((v16u8)adjust1, (v16u8)diff1, (v16u8)temp3_h); - ADD2(col_sum0, adjust0, col_sum1, adjust1, col_sum0, col_sum1); - UNPCK_UB_SH(sig1, temp0_h, temp1_h); - ADD2(temp0_h, adjust0, temp1_h, adjust1, temp0_h, temp1_h); - MAXI_SH2_SH(temp0_h, temp1_h, 0); - SAT_UH2_SH(temp0_h, temp1_h, 7); - temp2_h = (v8i16)__msa_pckev_b((v16i8)temp3_h, (v16i8)temp2_h); - running_avg_y = (v16u8)__msa_pckev_b((v16i8)temp1_h, (v16i8)temp0_h); - running_avg_y = - __msa_bmnz_v(running_avg_y, mc_running_avg_y1, (v16u8)temp2_h); - ST_UB(running_avg_y, running_avg_y_ptr); - sig_ptr += sig_stride; - mc_running_avg_y_ptr += mc_avg_y_stride; - running_avg_y_ptr += avg_y_stride; - } - - col_sum0 = __msa_min_s_h(col_sum0, val_127); - col_sum1 = __msa_min_s_h(col_sum1, val_127); - temp0_h = col_sum0 + col_sum1; - temp0_w = __msa_hadd_s_w(temp0_h, temp0_h); - temp0_d = __msa_hadd_s_d(temp0_w, temp0_w); - temp1_d = __msa_splati_d(temp0_d, 1); - temp0_d += temp1_d; - sum_diff = __msa_copy_s_w((v4i32)temp0_d, 0); - sig_ptr -= sig_stride * 16; - mc_running_avg_y_ptr -= mc_avg_y_stride * 16; - running_avg_y_ptr -= avg_y_stride * 16; - - if (increase_denoising) { - sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH; - } - - if (abs(sum_diff) > sum_diff_thresh) { - delta = ((abs(sum_diff) - sum_diff_thresh) >> 8) + 1; - delta_vec = __msa_fill_h(delta); - if (delta < 4) { - for (cnt = 8; cnt--;) { - running_avg_y = LD_UB(running_avg_y_ptr); - mc_running_avg_y0 = LD_UB(mc_running_avg_y_ptr); - sig0 = LD_UB(sig_ptr); - sig_ptr += sig_stride; - mc_running_avg_y_ptr += mc_avg_y_stride; - running_avg_y_ptr += avg_y_stride; - mc_running_avg_y1 = LD_UB(mc_running_avg_y_ptr); - sig1 = LD_UB(sig_ptr); - running_avg_y1 = LD_UB(running_avg_y_ptr); - ILVRL_B2_UB(mc_running_avg_y0, sig0, coeff0, coeff1); - HSUB_UB2_SH(coeff0, coeff1, diff0, diff1); - abs_diff0 = __msa_add_a_h(diff0, zero); - abs_diff1 = __msa_add_a_h(diff1, zero); - temp0_h = abs_diff0 < delta_vec; - temp1_h = abs_diff1 < delta_vec; - abs_diff0 = (v8i16)__msa_bmz_v((v16u8)abs_diff0, (v16u8)delta_vec, - (v16u8)temp0_h); - abs_diff1 = (v8i16)__msa_bmz_v((v16u8)abs_diff1, (v16u8)delta_vec, - (v16u8)temp1_h); - SUB2(zero, abs_diff0, zero, abs_diff1, abs_diff_neg0, abs_diff_neg1); - abs_diff_neg0 = zero - abs_diff0; - abs_diff_neg1 = zero - abs_diff1; - temp0_h = __msa_clei_s_h(diff0, 0); - temp1_h = __msa_clei_s_h(diff1, 0); - adjust0 = (v8i16)__msa_bmnz_v((v16u8)abs_diff0, (v16u8)abs_diff_neg0, - (v16u8)temp0_h); - adjust1 = (v8i16)__msa_bmnz_v((v16u8)abs_diff1, (v16u8)abs_diff_neg1, - (v16u8)temp1_h); - ILVRL_B2_SH(zero, running_avg_y, temp2_h, temp3_h); - ADD2(temp2_h, adjust0, temp3_h, adjust1, adjust2, adjust3); - MAXI_SH2_SH(adjust2, adjust3, 0); - SAT_UH2_SH(adjust2, adjust3, 7); - temp0_h = __msa_ceqi_h(diff0, 0); - temp1_h = __msa_ceqi_h(diff1, 0); - adjust2 = - (v8i16)__msa_bmz_v((v16u8)adjust2, (v16u8)temp2_h, (v16u8)temp0_h); - adjust3 = - (v8i16)__msa_bmz_v((v16u8)adjust3, (v16u8)temp3_h, (v16u8)temp1_h); - adjust0 = - (v8i16)__msa_bmnz_v((v16u8)adjust0, (v16u8)zero, (v16u8)temp0_h); - adjust1 = - (v8i16)__msa_bmnz_v((v16u8)adjust1, (v16u8)zero, (v16u8)temp1_h); - ADD2(col_sum2, adjust0, col_sum3, adjust1, col_sum2, col_sum3); - running_avg_y = (v16u8)__msa_pckev_b((v16i8)adjust3, (v16i8)adjust2); - ST_UB(running_avg_y, running_avg_y_ptr - avg_y_stride); - ILVRL_B2_UB(mc_running_avg_y1, sig1, coeff0, coeff1); - HSUB_UB2_SH(coeff0, coeff1, diff0, diff1); - abs_diff0 = __msa_add_a_h(diff0, zero); - abs_diff1 = __msa_add_a_h(diff1, zero); - temp0_h = abs_diff0 < delta_vec; - temp1_h = abs_diff1 < delta_vec; - abs_diff0 = (v8i16)__msa_bmz_v((v16u8)abs_diff0, (v16u8)delta_vec, - (v16u8)temp0_h); - abs_diff1 = (v8i16)__msa_bmz_v((v16u8)abs_diff1, (v16u8)delta_vec, - (v16u8)temp1_h); - SUB2(zero, abs_diff0, zero, abs_diff1, abs_diff_neg0, abs_diff_neg1); - temp0_h = __msa_clei_s_h(diff0, 0); - temp1_h = __msa_clei_s_h(diff1, 0); - adjust0 = (v8i16)__msa_bmnz_v((v16u8)abs_diff0, (v16u8)abs_diff_neg0, - (v16u8)temp0_h); - adjust1 = (v8i16)__msa_bmnz_v((v16u8)abs_diff1, (v16u8)abs_diff_neg1, - (v16u8)temp1_h); - ILVRL_H2_SH(zero, running_avg_y1, temp2_h, temp3_h); - ADD2(temp2_h, adjust0, temp3_h, adjust1, adjust2, adjust3); - MAXI_SH2_SH(adjust2, adjust3, 0); - SAT_UH2_SH(adjust2, adjust3, 7); - temp0_h = __msa_ceqi_h(diff0, 0); - temp1_h = __msa_ceqi_h(diff1, 0); - adjust2 = - (v8i16)__msa_bmz_v((v16u8)adjust2, (v16u8)temp2_h, (v16u8)temp0_h); - adjust3 = - (v8i16)__msa_bmz_v((v16u8)adjust3, (v16u8)temp3_h, (v16u8)temp1_h); - adjust0 = - (v8i16)__msa_bmz_v((v16u8)adjust0, (v16u8)zero, (v16u8)temp0_h); - adjust1 = - (v8i16)__msa_bmz_v((v16u8)adjust1, (v16u8)zero, (v16u8)temp1_h); - ADD2(col_sum2, adjust0, col_sum3, adjust1, col_sum2, col_sum3); - running_avg_y = (v16u8)__msa_pckev_b((v16i8)adjust3, (v16i8)adjust2); - ST_UB(running_avg_y, running_avg_y_ptr); - running_avg_y_ptr += avg_y_stride; - } - - col_sum2 = __msa_min_s_h(col_sum2, val_127); - col_sum3 = __msa_min_s_h(col_sum3, val_127); - temp0_h = col_sum2 + col_sum3; - temp0_w = __msa_hadd_s_w(temp0_h, temp0_h); - temp0_d = __msa_hadd_s_d(temp0_w, temp0_w); - temp1_d = __msa_splati_d(temp0_d, 1); - temp0_d += (v2i64)temp1_d; - sum_diff = __msa_copy_s_w((v4i32)temp0_d, 0); - if (abs(sum_diff) > SUM_DIFF_THRESHOLD) { - return COPY_BLOCK; - } - } else { - return COPY_BLOCK; - } - } - - LD_UB8(sig_start, sig_stride, src0, src1, src2, src3, src4, src5, src6, src7); - sig_start += (8 * sig_stride); - LD_UB8(sig_start, sig_stride, src8, src9, src10, src11, src12, src13, src14, - src15); - - ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, running_avg_y_start, - avg_y_stride); - running_avg_y_start += (8 * avg_y_stride); - ST_UB8(src8, src9, src10, src11, src12, src13, src14, src15, - running_avg_y_start, avg_y_stride); - - return FILTER_BLOCK; -} - -int32_t vp8_denoiser_filter_uv_msa( - uint8_t *mc_running_avg_y_ptr, int32_t mc_avg_y_stride, - uint8_t *running_avg_y_ptr, int32_t avg_y_stride, uint8_t *sig_ptr, - int32_t sig_stride, uint32_t motion_magnitude, int32_t increase_denoising) { - uint8_t *running_avg_y_start = running_avg_y_ptr; - uint8_t *sig_start = sig_ptr; - int32_t cnt = 0; - int32_t sum_diff = 0; - int32_t shift_inc1 = 3; - int32_t delta = 0; - int32_t sum_block = 0; - int32_t sum_diff_thresh; - int64_t dst0, dst1, src0, src1, src2, src3; - v16u8 mc_running_avg_y0, running_avg_y, sig0; - v16u8 mc_running_avg_y1, running_avg_y1, sig1; - v16u8 sig2, sig3, sig4, sig5, sig6, sig7; - v16u8 coeff0; - v8i16 diff0, abs_diff0, abs_diff_neg0; - v8i16 adjust0, adjust2; - v8i16 shift_inc1_vec = { 0 }; - v8i16 col_sum0 = { 0 }; - v8i16 temp0_h, temp2_h, cmp, delta_vec; - v4i32 temp0_w; - v2i64 temp0_d, temp1_d; - v16i8 zero = { 0 }; - v8i16 one = __msa_ldi_h(1); - v8i16 four = __msa_ldi_h(4); - v8i16 adj_val = { 6, 4, 3, 0, -6, -4, -3, 0 }; - - sig0 = LD_UB(sig_ptr); - sig_ptr += sig_stride; - temp0_h = (v8i16)__msa_ilvr_b(zero, (v16i8)sig0); - sig1 = LD_UB(sig_ptr); - sig_ptr += sig_stride; - temp0_h += (v8i16)__msa_ilvr_b(zero, (v16i8)sig1); - sig2 = LD_UB(sig_ptr); - sig_ptr += sig_stride; - temp0_h += (v8i16)__msa_ilvr_b(zero, (v16i8)sig2); - sig3 = LD_UB(sig_ptr); - sig_ptr += sig_stride; - temp0_h += (v8i16)__msa_ilvr_b(zero, (v16i8)sig3); - sig4 = LD_UB(sig_ptr); - sig_ptr += sig_stride; - temp0_h += (v8i16)__msa_ilvr_b(zero, (v16i8)sig4); - sig5 = LD_UB(sig_ptr); - sig_ptr += sig_stride; - temp0_h += (v8i16)__msa_ilvr_b(zero, (v16i8)sig5); - sig6 = LD_UB(sig_ptr); - sig_ptr += sig_stride; - temp0_h += (v8i16)__msa_ilvr_b(zero, (v16i8)sig6); - sig7 = LD_UB(sig_ptr); - sig_ptr += sig_stride; - temp0_h += (v8i16)__msa_ilvr_b(zero, (v16i8)sig7); - temp0_w = __msa_hadd_s_w(temp0_h, temp0_h); - temp0_d = __msa_hadd_s_d(temp0_w, temp0_w); - temp1_d = __msa_splati_d(temp0_d, 1); - temp0_d += temp1_d; - sum_block = __msa_copy_s_w((v4i32)temp0_d, 0); - sig_ptr -= sig_stride * 8; - - if (abs(sum_block - (128 * 8 * 8)) < SUM_DIFF_FROM_AVG_THRESH_UV) { - return COPY_BLOCK; - } - - if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) { - adj_val = __msa_add_a_h(adj_val, one); - - if (increase_denoising) { - adj_val = __msa_add_a_h(adj_val, one); - shift_inc1 = 4; - } - - temp0_h = (v8i16)zero - adj_val; - adj_val = (v8i16)__msa_ilvev_d((v2i64)temp0_h, (v2i64)adj_val); - } - - adj_val = __msa_insert_h(adj_val, 3, cnt); - adj_val = __msa_insert_h(adj_val, 7, cnt); - shift_inc1_vec = __msa_fill_h(shift_inc1); - for (cnt = 4; cnt--;) { - v8i16 mask0 = { 0 }; - mc_running_avg_y0 = LD_UB(mc_running_avg_y_ptr); - sig0 = LD_UB(sig_ptr); - sig_ptr += sig_stride; - mc_running_avg_y_ptr += mc_avg_y_stride; - mc_running_avg_y1 = LD_UB(mc_running_avg_y_ptr); - sig1 = LD_UB(sig_ptr); - coeff0 = (v16u8)__msa_ilvr_b((v16i8)mc_running_avg_y0, (v16i8)sig0); - diff0 = __msa_hsub_u_h(coeff0, coeff0); - abs_diff0 = __msa_add_a_h(diff0, (v8i16)zero); - cmp = __msa_clei_s_h(abs_diff0, 15); - cmp = cmp & one; - mask0 += cmp; - cmp = __msa_clei_s_h(abs_diff0, 7); - cmp = cmp & one; - mask0 += cmp; - cmp = abs_diff0 < shift_inc1_vec; - cmp = cmp & one; - mask0 += cmp; - temp0_h = __msa_clei_s_h(diff0, 0); - temp0_h = temp0_h & four; - mask0 += temp0_h; - adjust0 = __msa_vshf_h(mask0, adj_val, adj_val); - temp2_h = __msa_ceqi_h(adjust0, 0); - adjust0 = (v8i16)__msa_bmnz_v((v16u8)adjust0, (v16u8)diff0, (v16u8)temp2_h); - col_sum0 += adjust0; - temp0_h = (v8i16)__msa_ilvr_b(zero, (v16i8)sig0); - temp0_h += adjust0; - temp0_h = __msa_maxi_s_h(temp0_h, 0); - temp0_h = (v8i16)__msa_sat_u_h((v8u16)temp0_h, 7); - temp2_h = (v8i16)__msa_pckev_b((v16i8)temp2_h, (v16i8)temp2_h); - running_avg_y = (v16u8)__msa_pckev_b((v16i8)temp0_h, (v16i8)temp0_h); - running_avg_y = - __msa_bmnz_v(running_avg_y, mc_running_avg_y0, (v16u8)temp2_h); - dst0 = __msa_copy_s_d((v2i64)running_avg_y, 0); - SD(dst0, running_avg_y_ptr); - running_avg_y_ptr += avg_y_stride; - - mask0 = __msa_ldi_h(0); - coeff0 = (v16u8)__msa_ilvr_b((v16i8)mc_running_avg_y1, (v16i8)sig1); - diff0 = __msa_hsub_u_h(coeff0, coeff0); - abs_diff0 = __msa_add_a_h(diff0, (v8i16)zero); - cmp = __msa_clei_s_h(abs_diff0, 15); - cmp = cmp & one; - mask0 += cmp; - cmp = __msa_clei_s_h(abs_diff0, 7); - cmp = cmp & one; - mask0 += cmp; - cmp = abs_diff0 < shift_inc1_vec; - cmp = cmp & one; - mask0 += cmp; - temp0_h = __msa_clei_s_h(diff0, 0); - temp0_h = temp0_h & four; - mask0 += temp0_h; - adjust0 = __msa_vshf_h(mask0, adj_val, adj_val); - temp2_h = __msa_ceqi_h(adjust0, 0); - adjust0 = (v8i16)__msa_bmnz_v((v16u8)adjust0, (v16u8)diff0, (v16u8)temp2_h); - col_sum0 += adjust0; - temp0_h = (v8i16)__msa_ilvr_b(zero, (v16i8)sig1); - temp0_h += adjust0; - temp0_h = __msa_maxi_s_h(temp0_h, 0); - temp0_h = (v8i16)__msa_sat_u_h((v8u16)temp0_h, 7); - - temp2_h = (v8i16)__msa_pckev_b((v16i8)temp2_h, (v16i8)temp2_h); - running_avg_y = (v16u8)__msa_pckev_b((v16i8)temp0_h, (v16i8)temp0_h); - running_avg_y = - __msa_bmnz_v(running_avg_y, mc_running_avg_y1, (v16u8)temp2_h); - dst1 = __msa_copy_s_d((v2i64)running_avg_y, 0); - SD(dst1, running_avg_y_ptr); - - sig_ptr += sig_stride; - mc_running_avg_y_ptr += mc_avg_y_stride; - running_avg_y_ptr += avg_y_stride; - } - - temp0_h = col_sum0; - temp0_w = __msa_hadd_s_w(temp0_h, temp0_h); - temp0_d = __msa_hadd_s_d(temp0_w, temp0_w); - temp1_d = __msa_splati_d(temp0_d, 1); - temp0_d += temp1_d; - sum_diff = __msa_copy_s_w((v4i32)temp0_d, 0); - sig_ptr -= sig_stride * 8; - mc_running_avg_y_ptr -= mc_avg_y_stride * 8; - running_avg_y_ptr -= avg_y_stride * 8; - sum_diff_thresh = SUM_DIFF_THRESHOLD_UV; - - if (increase_denoising) { - sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH_UV; - } - - if (abs(sum_diff) > sum_diff_thresh) { - delta = ((abs(sum_diff) - sum_diff_thresh) >> 8) + 1; - delta_vec = __msa_fill_h(delta); - if (delta < 4) { - for (cnt = 4; cnt--;) { - running_avg_y = LD_UB(running_avg_y_ptr); - mc_running_avg_y0 = LD_UB(mc_running_avg_y_ptr); - sig0 = LD_UB(sig_ptr); - /* Update pointers for next iteration. */ - sig_ptr += sig_stride; - mc_running_avg_y_ptr += mc_avg_y_stride; - running_avg_y_ptr += avg_y_stride; - - mc_running_avg_y1 = LD_UB(mc_running_avg_y_ptr); - sig1 = LD_UB(sig_ptr); - running_avg_y1 = LD_UB(running_avg_y_ptr); - - coeff0 = (v16u8)__msa_ilvr_b((v16i8)mc_running_avg_y0, (v16i8)sig0); - diff0 = __msa_hsub_u_h(coeff0, coeff0); - abs_diff0 = __msa_add_a_h(diff0, (v8i16)zero); - temp0_h = delta_vec < abs_diff0; - abs_diff0 = (v8i16)__msa_bmnz_v((v16u8)abs_diff0, (v16u8)delta_vec, - (v16u8)temp0_h); - abs_diff_neg0 = (v8i16)zero - abs_diff0; - temp0_h = __msa_clei_s_h(diff0, 0); - adjust0 = (v8i16)__msa_bmz_v((v16u8)abs_diff0, (v16u8)abs_diff_neg0, - (v16u8)temp0_h); - temp2_h = (v8i16)__msa_ilvr_b(zero, (v16i8)running_avg_y); - adjust2 = temp2_h + adjust0; - adjust2 = __msa_maxi_s_h(adjust2, 0); - adjust2 = (v8i16)__msa_sat_u_h((v8u16)adjust2, 7); - temp0_h = __msa_ceqi_h(diff0, 0); - adjust2 = - (v8i16)__msa_bmnz_v((v16u8)adjust2, (v16u8)temp2_h, (v16u8)temp0_h); - adjust0 = - (v8i16)__msa_bmnz_v((v16u8)adjust0, (v16u8)zero, (v16u8)temp0_h); - col_sum0 += adjust0; - running_avg_y = (v16u8)__msa_pckev_b((v16i8)adjust2, (v16i8)adjust2); - dst0 = __msa_copy_s_d((v2i64)running_avg_y, 0); - SD(dst0, running_avg_y_ptr - avg_y_stride); - - coeff0 = (v16u8)__msa_ilvr_b((v16i8)mc_running_avg_y1, (v16i8)sig1); - diff0 = __msa_hsub_u_h(coeff0, coeff0); - abs_diff0 = __msa_add_a_h(diff0, (v8i16)zero); - temp0_h = delta_vec < abs_diff0; - abs_diff0 = (v8i16)__msa_bmnz_v((v16u8)abs_diff0, (v16u8)delta_vec, - (v16u8)temp0_h); - abs_diff_neg0 = (v8i16)zero - abs_diff0; - temp0_h = __msa_clei_s_h(diff0, 0); - adjust0 = (v8i16)__msa_bmz_v((v16u8)abs_diff0, (v16u8)abs_diff_neg0, - (v16u8)temp0_h); - temp2_h = (v8i16)__msa_ilvr_b(zero, (v16i8)running_avg_y1); - adjust2 = temp2_h + adjust0; - adjust2 = __msa_maxi_s_h(adjust2, 0); - adjust2 = (v8i16)__msa_sat_u_h((v8u16)adjust2, 7); - temp0_h = __msa_ceqi_h(diff0, 0); - adjust2 = - (v8i16)__msa_bmnz_v((v16u8)adjust2, (v16u8)temp2_h, (v16u8)temp0_h); - adjust0 = - (v8i16)__msa_bmnz_v((v16u8)adjust0, (v16u8)zero, (v16u8)temp0_h); - col_sum0 += adjust0; - running_avg_y = (v16u8)__msa_pckev_b((v16i8)adjust2, (v16i8)adjust2); - dst1 = __msa_copy_s_d((v2i64)running_avg_y, 0); - SD(dst1, running_avg_y_ptr); - running_avg_y_ptr += avg_y_stride; - } - - temp0_h = col_sum0; - temp0_w = __msa_hadd_s_w(temp0_h, temp0_h); - temp0_d = __msa_hadd_s_d(temp0_w, temp0_w); - temp1_d = __msa_splati_d(temp0_d, 1); - temp0_d += temp1_d; - sum_diff = __msa_copy_s_w((v4i32)temp0_d, 0); - - if (abs(sum_diff) > sum_diff_thresh) { - return COPY_BLOCK; - } - } else { - return COPY_BLOCK; - } - } - - LD4(sig_start, sig_stride, src0, src1, src2, src3); - sig_start += (4 * sig_stride); - SD4(src0, src1, src2, src3, running_avg_y_start, avg_y_stride); - running_avg_y_start += (4 * avg_y_stride); - - LD4(sig_start, sig_stride, src0, src1, src2, src3); - SD4(src0, src1, src2, src3, running_avg_y_start, avg_y_stride); - - return FILTER_BLOCK; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/msa/encodeopt_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/msa/encodeopt_msa.c deleted file mode 100644 index 2bcddb62..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/msa/encodeopt_msa.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vp8/common/mips/msa/vp8_macros_msa.h" -#include "vp8/encoder/block.h" - -int32_t vp8_block_error_msa(int16_t *coeff_ptr, int16_t *dq_coeff_ptr) { - int32_t err = 0; - uint32_t loop_cnt; - v8i16 coeff, dq_coeff, coeff0, coeff1; - v4i32 diff0, diff1; - v2i64 err0 = { 0 }; - v2i64 err1 = { 0 }; - - for (loop_cnt = 2; loop_cnt--;) { - coeff = LD_SH(coeff_ptr); - dq_coeff = LD_SH(dq_coeff_ptr); - ILVRL_H2_SH(coeff, dq_coeff, coeff0, coeff1); - HSUB_UH2_SW(coeff0, coeff1, diff0, diff1); - DPADD_SD2_SD(diff0, diff1, err0, err1); - coeff_ptr += 8; - dq_coeff_ptr += 8; - } - - err0 += __msa_splati_d(err0, 1); - err1 += __msa_splati_d(err1, 1); - err = __msa_copy_s_d(err0, 0); - err += __msa_copy_s_d(err1, 0); - - return err; -} - -int32_t vp8_mbblock_error_msa(MACROBLOCK *mb, int32_t dc) { - BLOCK *be; - BLOCKD *bd; - int16_t *coeff_ptr, *dq_coeff_ptr; - int32_t err = 0; - uint32_t loop_cnt; - v8i16 coeff, coeff0, coeff1, coeff2, coeff3, coeff4; - v8i16 dq_coeff, dq_coeff2, dq_coeff3, dq_coeff4; - v4i32 diff0, diff1; - v2i64 err0, err1; - v16u8 zero = { 0 }; - v16u8 mask0 = (v16u8)__msa_ldi_b(255); - - if (1 == dc) { - mask0 = (v16u8)__msa_insve_w((v4i32)mask0, 0, (v4i32)zero); - } - - for (loop_cnt = 0; loop_cnt < 8; ++loop_cnt) { - be = &mb->block[2 * loop_cnt]; - bd = &mb->e_mbd.block[2 * loop_cnt]; - coeff_ptr = be->coeff; - dq_coeff_ptr = bd->dqcoeff; - coeff = LD_SH(coeff_ptr); - dq_coeff = LD_SH(dq_coeff_ptr); - coeff_ptr += 8; - dq_coeff_ptr += 8; - coeff2 = LD_SH(coeff_ptr); - dq_coeff2 = LD_SH(dq_coeff_ptr); - be = &mb->block[2 * loop_cnt + 1]; - bd = &mb->e_mbd.block[2 * loop_cnt + 1]; - coeff_ptr = be->coeff; - dq_coeff_ptr = bd->dqcoeff; - coeff3 = LD_SH(coeff_ptr); - dq_coeff3 = LD_SH(dq_coeff_ptr); - coeff_ptr += 8; - dq_coeff_ptr += 8; - coeff4 = LD_SH(coeff_ptr); - dq_coeff4 = LD_SH(dq_coeff_ptr); - ILVRL_H2_SH(coeff, dq_coeff, coeff0, coeff1); - HSUB_UH2_SW(coeff0, coeff1, diff0, diff1); - diff0 = (v4i32)__msa_bmnz_v(zero, (v16u8)diff0, mask0); - DOTP_SW2_SD(diff0, diff1, diff0, diff1, err0, err1); - ILVRL_H2_SH(coeff2, dq_coeff2, coeff0, coeff1); - HSUB_UH2_SW(coeff0, coeff1, diff0, diff1); - DPADD_SD2_SD(diff0, diff1, err0, err1); - err0 += __msa_splati_d(err0, 1); - err1 += __msa_splati_d(err1, 1); - err += __msa_copy_s_d(err0, 0); - err += __msa_copy_s_d(err1, 0); - - ILVRL_H2_SH(coeff3, dq_coeff3, coeff0, coeff1); - HSUB_UH2_SW(coeff0, coeff1, diff0, diff1); - diff0 = (v4i32)__msa_bmnz_v(zero, (v16u8)diff0, mask0); - DOTP_SW2_SD(diff0, diff1, diff0, diff1, err0, err1); - ILVRL_H2_SH(coeff4, dq_coeff4, coeff0, coeff1); - HSUB_UH2_SW(coeff0, coeff1, diff0, diff1); - DPADD_SD2_SD(diff0, diff1, err0, err1); - err0 += __msa_splati_d(err0, 1); - err1 += __msa_splati_d(err1, 1); - err += __msa_copy_s_d(err0, 0); - err += __msa_copy_s_d(err1, 0); - } - - return err; -} - -int32_t vp8_mbuverror_msa(MACROBLOCK *mb) { - BLOCK *be; - BLOCKD *bd; - int16_t *coeff_ptr, *dq_coeff_ptr; - int32_t err = 0; - uint32_t loop_cnt; - v8i16 coeff, coeff0, coeff1, coeff2, coeff3, coeff4; - v8i16 dq_coeff, dq_coeff2, dq_coeff3, dq_coeff4; - v4i32 diff0, diff1; - v2i64 err0, err1, err_dup0, err_dup1; - - for (loop_cnt = 16; loop_cnt < 24; loop_cnt += 2) { - be = &mb->block[loop_cnt]; - bd = &mb->e_mbd.block[loop_cnt]; - coeff_ptr = be->coeff; - dq_coeff_ptr = bd->dqcoeff; - coeff = LD_SH(coeff_ptr); - dq_coeff = LD_SH(dq_coeff_ptr); - coeff_ptr += 8; - dq_coeff_ptr += 8; - coeff2 = LD_SH(coeff_ptr); - dq_coeff2 = LD_SH(dq_coeff_ptr); - be = &mb->block[loop_cnt + 1]; - bd = &mb->e_mbd.block[loop_cnt + 1]; - coeff_ptr = be->coeff; - dq_coeff_ptr = bd->dqcoeff; - coeff3 = LD_SH(coeff_ptr); - dq_coeff3 = LD_SH(dq_coeff_ptr); - coeff_ptr += 8; - dq_coeff_ptr += 8; - coeff4 = LD_SH(coeff_ptr); - dq_coeff4 = LD_SH(dq_coeff_ptr); - - ILVRL_H2_SH(coeff, dq_coeff, coeff0, coeff1); - HSUB_UH2_SW(coeff0, coeff1, diff0, diff1); - DOTP_SW2_SD(diff0, diff1, diff0, diff1, err0, err1); - - ILVRL_H2_SH(coeff2, dq_coeff2, coeff0, coeff1); - HSUB_UH2_SW(coeff0, coeff1, diff0, diff1); - DPADD_SD2_SD(diff0, diff1, err0, err1); - err_dup0 = __msa_splati_d(err0, 1); - err_dup1 = __msa_splati_d(err1, 1); - ADD2(err0, err_dup0, err1, err_dup1, err0, err1); - err += __msa_copy_s_d(err0, 0); - err += __msa_copy_s_d(err1, 0); - - ILVRL_H2_SH(coeff3, dq_coeff3, coeff0, coeff1); - HSUB_UH2_SW(coeff0, coeff1, diff0, diff1); - DOTP_SW2_SD(diff0, diff1, diff0, diff1, err0, err1); - ILVRL_H2_SH(coeff4, dq_coeff4, coeff0, coeff1); - HSUB_UH2_SW(coeff0, coeff1, diff0, diff1); - DPADD_SD2_SD(diff0, diff1, err0, err1); - err_dup0 = __msa_splati_d(err0, 1); - err_dup1 = __msa_splati_d(err1, 1); - ADD2(err0, err_dup0, err1, err_dup1, err0, err1); - err += __msa_copy_s_d(err0, 0); - err += __msa_copy_s_d(err1, 0); - } - - return err; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/msa/quantize_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/msa/quantize_msa.c deleted file mode 100644 index 9f5fbd39..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/msa/quantize_msa.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vp8/common/mips/msa/vp8_macros_msa.h" -#include "vp8/encoder/block.h" - -static int8_t fast_quantize_b_msa(int16_t *coeff_ptr, int16_t *round, - int16_t *quant, int16_t *de_quant, - int16_t *q_coeff, int16_t *dq_coeff) { - int32_t cnt, eob; - v16i8 inv_zig_zag = { 0, 1, 5, 6, 2, 4, 7, 12, 3, 8, 11, 13, 9, 10, 14, 15 }; - v8i16 round0, round1; - v8i16 sign_z0, sign_z1; - v8i16 q_coeff0, q_coeff1; - v8i16 x0, x1, de_quant0, de_quant1; - v8i16 coeff0, coeff1, z0, z1; - v8i16 quant0, quant1, quant2, quant3; - v8i16 zero = { 0 }; - v8i16 inv_zig_zag0, inv_zig_zag1; - v8i16 zigzag_mask0 = { 0, 1, 4, 8, 5, 2, 3, 6 }; - v8i16 zigzag_mask1 = { 9, 12, 13, 10, 7, 11, 14, 15 }; - v8i16 temp0_h, temp1_h, temp2_h, temp3_h; - v4i32 temp0_w, temp1_w, temp2_w, temp3_w; - - ILVRL_B2_SH(zero, inv_zig_zag, inv_zig_zag0, inv_zig_zag1); - eob = -1; - LD_SH2(coeff_ptr, 8, coeff0, coeff1); - VSHF_H2_SH(coeff0, coeff1, coeff0, coeff1, zigzag_mask0, zigzag_mask1, z0, - z1); - LD_SH2(round, 8, coeff0, coeff1); - VSHF_H2_SH(coeff0, coeff1, coeff0, coeff1, zigzag_mask0, zigzag_mask1, round0, - round1); - LD_SH2(quant, 8, coeff0, coeff1); - VSHF_H2_SH(coeff0, coeff1, coeff0, coeff1, zigzag_mask0, zigzag_mask1, quant0, - quant2); - sign_z0 = z0 >> 15; - sign_z1 = z1 >> 15; - x0 = __msa_add_a_h(z0, zero); - x1 = __msa_add_a_h(z1, zero); - ILVL_H2_SH(quant0, quant0, quant2, quant2, quant1, quant3); - ILVR_H2_SH(quant0, quant0, quant2, quant2, quant0, quant2); - ILVL_H2_SH(round0, x0, round1, x1, temp1_h, temp3_h); - ILVR_H2_SH(round0, x0, round1, x1, temp0_h, temp2_h); - DOTP_SH4_SW(temp0_h, temp1_h, temp2_h, temp3_h, quant0, quant1, quant2, - quant3, temp0_w, temp1_w, temp2_w, temp3_w); - SRA_4V(temp0_w, temp1_w, temp2_w, temp3_w, 16); - PCKEV_H2_SH(temp1_w, temp0_w, temp3_w, temp2_w, x0, x1); - x0 = x0 ^ sign_z0; - x1 = x1 ^ sign_z1; - SUB2(x0, sign_z0, x1, sign_z1, x0, x1); - VSHF_H2_SH(x0, x1, x0, x1, inv_zig_zag0, inv_zig_zag1, q_coeff0, q_coeff1); - ST_SH2(q_coeff0, q_coeff1, q_coeff, 8); - LD_SH2(de_quant, 8, de_quant0, de_quant1); - q_coeff0 *= de_quant0; - q_coeff1 *= de_quant1; - ST_SH2(q_coeff0, q_coeff1, dq_coeff, 8); - - for (cnt = 0; cnt < 16; ++cnt) { - if ((cnt <= 7) && (x1[7 - cnt] != 0)) { - eob = (15 - cnt); - break; - } - - if ((cnt > 7) && (x0[7 - (cnt - 8)] != 0)) { - eob = (7 - (cnt - 8)); - break; - } - } - - return (int8_t)(eob + 1); -} - -static int8_t exact_regular_quantize_b_msa( - int16_t *zbin_boost, int16_t *coeff_ptr, int16_t *zbin, int16_t *round, - int16_t *quant, int16_t *quant_shift, int16_t *de_quant, int16_t zbin_oq_in, - int16_t *q_coeff, int16_t *dq_coeff) { - int32_t cnt, eob; - int16_t *boost_temp = zbin_boost; - v16i8 inv_zig_zag = { 0, 1, 5, 6, 2, 4, 7, 12, 3, 8, 11, 13, 9, 10, 14, 15 }; - v8i16 round0, round1; - v8i16 sign_z0, sign_z1; - v8i16 q_coeff0, q_coeff1; - v8i16 z_bin0, z_bin1, zbin_o_q; - v8i16 x0, x1, sign_x0, sign_x1, de_quant0, de_quant1; - v8i16 coeff0, coeff1, z0, z1; - v8i16 quant0, quant1, quant2, quant3; - v8i16 zero = { 0 }; - v8i16 inv_zig_zag0, inv_zig_zag1; - v8i16 zigzag_mask0 = { 0, 1, 4, 8, 5, 2, 3, 6 }; - v8i16 zigzag_mask1 = { 9, 12, 13, 10, 7, 11, 14, 15 }; - v8i16 temp0_h, temp1_h, temp2_h, temp3_h; - v4i32 temp0_w, temp1_w, temp2_w, temp3_w; - - ILVRL_B2_SH(zero, inv_zig_zag, inv_zig_zag0, inv_zig_zag1); - zbin_o_q = __msa_fill_h(zbin_oq_in); - eob = -1; - LD_SH2(coeff_ptr, 8, coeff0, coeff1); - VSHF_H2_SH(coeff0, coeff1, coeff0, coeff1, zigzag_mask0, zigzag_mask1, z0, - z1); - LD_SH2(round, 8, coeff0, coeff1); - VSHF_H2_SH(coeff0, coeff1, coeff0, coeff1, zigzag_mask0, zigzag_mask1, round0, - round1); - LD_SH2(quant, 8, coeff0, coeff1); - VSHF_H2_SH(coeff0, coeff1, coeff0, coeff1, zigzag_mask0, zigzag_mask1, quant0, - quant2); - LD_SH2(zbin, 8, coeff0, coeff1); - VSHF_H2_SH(coeff0, coeff1, coeff0, coeff1, zigzag_mask0, zigzag_mask1, z_bin0, - z_bin1); - sign_z0 = z0 >> 15; - sign_z1 = z1 >> 15; - x0 = __msa_add_a_h(z0, zero); - x1 = __msa_add_a_h(z1, zero); - SUB2(x0, z_bin0, x1, z_bin1, z_bin0, z_bin1); - SUB2(z_bin0, zbin_o_q, z_bin1, zbin_o_q, z_bin0, z_bin1); - ILVL_H2_SH(quant0, quant0, quant2, quant2, quant1, quant3); - ILVR_H2_SH(quant0, quant0, quant2, quant2, quant0, quant2); - ILVL_H2_SH(round0, x0, round1, x1, temp1_h, temp3_h); - ILVR_H2_SH(round0, x0, round1, x1, temp0_h, temp2_h); - DOTP_SH4_SW(temp0_h, temp1_h, temp2_h, temp3_h, quant0, quant1, quant2, - quant3, temp0_w, temp1_w, temp2_w, temp3_w); - SRA_4V(temp0_w, temp1_w, temp2_w, temp3_w, 16); - PCKEV_H2_SH(temp1_w, temp0_w, temp3_w, temp2_w, temp0_h, temp2_h); - LD_SH2(quant_shift, 8, coeff0, coeff1); - VSHF_H2_SH(coeff0, coeff1, coeff0, coeff1, zigzag_mask0, zigzag_mask1, quant0, - quant2); - ILVL_H2_SH(quant0, quant0, quant2, quant2, quant1, quant3); - ILVR_H2_SH(quant0, quant0, quant2, quant2, quant0, quant2); - ADD2(x0, round0, x1, round1, x0, x1); - ILVL_H2_SH(temp0_h, x0, temp2_h, x1, temp1_h, temp3_h); - ILVR_H2_SH(temp0_h, x0, temp2_h, x1, temp0_h, temp2_h); - DOTP_SH4_SW(temp0_h, temp1_h, temp2_h, temp3_h, quant0, quant1, quant2, - quant3, temp0_w, temp1_w, temp2_w, temp3_w); - SRA_4V(temp0_w, temp1_w, temp2_w, temp3_w, 16); - PCKEV_H2_SH(temp1_w, temp0_w, temp3_w, temp2_w, x0, x1); - sign_x0 = x0 ^ sign_z0; - sign_x1 = x1 ^ sign_z1; - SUB2(sign_x0, sign_z0, sign_x1, sign_z1, sign_x0, sign_x1); - for (cnt = 0; cnt < 16; ++cnt) { - if (cnt <= 7) { - if (boost_temp[0] <= z_bin0[cnt]) { - if (x0[cnt]) { - eob = cnt; - boost_temp = zbin_boost; - } else { - boost_temp++; - } - } else { - sign_x0[cnt] = 0; - boost_temp++; - } - } else { - if (boost_temp[0] <= z_bin1[cnt - 8]) { - if (x1[cnt - 8]) { - eob = cnt; - boost_temp = zbin_boost; - } else { - boost_temp++; - } - } else { - sign_x1[cnt - 8] = 0; - boost_temp++; - } - } - } - - VSHF_H2_SH(sign_x0, sign_x1, sign_x0, sign_x1, inv_zig_zag0, inv_zig_zag1, - q_coeff0, q_coeff1); - ST_SH2(q_coeff0, q_coeff1, q_coeff, 8); - LD_SH2(de_quant, 8, de_quant0, de_quant1); - MUL2(de_quant0, q_coeff0, de_quant1, q_coeff1, de_quant0, de_quant1); - ST_SH2(de_quant0, de_quant1, dq_coeff, 8); - - return (int8_t)(eob + 1); -} - -void vp8_fast_quantize_b_msa(BLOCK *b, BLOCKD *d) { - int16_t *coeff_ptr = b->coeff; - int16_t *round_ptr = b->round; - int16_t *quant_ptr = b->quant_fast; - int16_t *qcoeff_ptr = d->qcoeff; - int16_t *dqcoeff_ptr = d->dqcoeff; - int16_t *dequant_ptr = d->dequant; - - *d->eob = fast_quantize_b_msa(coeff_ptr, round_ptr, quant_ptr, dequant_ptr, - qcoeff_ptr, dqcoeff_ptr); -} - -void vp8_regular_quantize_b_msa(BLOCK *b, BLOCKD *d) { - int16_t *zbin_boost_ptr = b->zrun_zbin_boost; - int16_t *coeff_ptr = b->coeff; - int16_t *zbin_ptr = b->zbin; - int16_t *round_ptr = b->round; - int16_t *quant_ptr = b->quant; - int16_t *quant_shift_ptr = b->quant_shift; - int16_t *qcoeff_ptr = d->qcoeff; - int16_t *dqcoeff_ptr = d->dqcoeff; - int16_t *dequant_ptr = d->dequant; - int16_t zbin_oq_value = b->zbin_extra; - - *d->eob = exact_regular_quantize_b_msa( - zbin_boost_ptr, coeff_ptr, zbin_ptr, round_ptr, quant_ptr, - quant_shift_ptr, dequant_ptr, zbin_oq_value, qcoeff_ptr, dqcoeff_ptr); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/msa/temporal_filter_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/msa/temporal_filter_msa.c deleted file mode 100644 index fb83f07b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mips/msa/temporal_filter_msa.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp8_rtcd.h" -#include "vp8/common/mips/msa/vp8_macros_msa.h" - -static void temporal_filter_apply_16size_msa( - uint8_t *frame1_ptr, uint32_t stride, uint8_t *frame2_ptr, - int32_t strength_in, int32_t filter_wt_in, uint32_t *acc, uint16_t *cnt) { - uint32_t row; - v16i8 frame1_0_b, frame1_1_b, frame2_0_b, frame2_1_b; - v16u8 frame_l, frame_h; - v16i8 zero = { 0 }; - v8i16 frame2_0_h, frame2_1_h, mod0_h, mod1_h; - v8i16 diff0, diff1, cnt0, cnt1; - v4i32 const3, const16, filter_wt, strength; - v4i32 mod0_w, mod1_w, mod2_w, mod3_w; - v4i32 diff0_r, diff0_l, diff1_r, diff1_l; - v4i32 frame2_0, frame2_1, frame2_2, frame2_3; - v4i32 acc0, acc1, acc2, acc3; - - filter_wt = __msa_fill_w(filter_wt_in); - strength = __msa_fill_w(strength_in); - const3 = __msa_ldi_w(3); - const16 = __msa_ldi_w(16); - - for (row = 8; row--;) { - frame1_0_b = LD_SB(frame1_ptr); - frame2_0_b = LD_SB(frame2_ptr); - frame1_ptr += stride; - frame2_ptr += 16; - frame1_1_b = LD_SB(frame1_ptr); - frame2_1_b = LD_SB(frame2_ptr); - LD_SW2(acc, 4, acc0, acc1); - LD_SW2(acc + 8, 4, acc2, acc3); - LD_SH2(cnt, 8, cnt0, cnt1); - ILVRL_B2_UB(frame1_0_b, frame2_0_b, frame_l, frame_h); - HSUB_UB2_SH(frame_l, frame_h, diff0, diff1); - UNPCK_SH_SW(diff0, diff0_r, diff0_l); - UNPCK_SH_SW(diff1, diff1_r, diff1_l); - MUL4(diff0_r, diff0_r, diff0_l, diff0_l, diff1_r, diff1_r, diff1_l, diff1_l, - mod0_w, mod1_w, mod2_w, mod3_w); - MUL4(mod0_w, const3, mod1_w, const3, mod2_w, const3, mod3_w, const3, mod0_w, - mod1_w, mod2_w, mod3_w); - SRAR_W4_SW(mod0_w, mod1_w, mod2_w, mod3_w, strength); - diff0_r = (mod0_w < const16); - diff0_l = (mod1_w < const16); - diff1_r = (mod2_w < const16); - diff1_l = (mod3_w < const16); - SUB4(const16, mod0_w, const16, mod1_w, const16, mod2_w, const16, mod3_w, - mod0_w, mod1_w, mod2_w, mod3_w); - mod0_w = diff0_r & mod0_w; - mod1_w = diff0_l & mod1_w; - mod2_w = diff1_r & mod2_w; - mod3_w = diff1_l & mod3_w; - MUL4(mod0_w, filter_wt, mod1_w, filter_wt, mod2_w, filter_wt, mod3_w, - filter_wt, mod0_w, mod1_w, mod2_w, mod3_w); - PCKEV_H2_SH(mod1_w, mod0_w, mod3_w, mod2_w, mod0_h, mod1_h) - ADD2(mod0_h, cnt0, mod1_h, cnt1, mod0_h, mod1_h); - ST_SH2(mod0_h, mod1_h, cnt, 8); - cnt += 16; - ILVRL_B2_SH(zero, frame2_0_b, frame2_0_h, frame2_1_h); - UNPCK_SH_SW(frame2_0_h, frame2_0, frame2_1); - UNPCK_SH_SW(frame2_1_h, frame2_2, frame2_3); - MUL4(mod0_w, frame2_0, mod1_w, frame2_1, mod2_w, frame2_2, mod3_w, frame2_3, - mod0_w, mod1_w, mod2_w, mod3_w); - ADD4(mod0_w, acc0, mod1_w, acc1, mod2_w, acc2, mod3_w, acc3, mod0_w, mod1_w, - mod2_w, mod3_w); - ST_SW2(mod0_w, mod1_w, acc, 4); - ST_SW2(mod2_w, mod3_w, acc + 8, 4); - acc += 16; - LD_SW2(acc, 4, acc0, acc1); - LD_SW2(acc + 8, 4, acc2, acc3); - LD_SH2(cnt, 8, cnt0, cnt1); - ILVRL_B2_UB(frame1_1_b, frame2_1_b, frame_l, frame_h); - HSUB_UB2_SH(frame_l, frame_h, diff0, diff1); - UNPCK_SH_SW(diff0, diff0_r, diff0_l); - UNPCK_SH_SW(diff1, diff1_r, diff1_l); - MUL4(diff0_r, diff0_r, diff0_l, diff0_l, diff1_r, diff1_r, diff1_l, diff1_l, - mod0_w, mod1_w, mod2_w, mod3_w); - MUL4(mod0_w, const3, mod1_w, const3, mod2_w, const3, mod3_w, const3, mod0_w, - mod1_w, mod2_w, mod3_w); - SRAR_W4_SW(mod0_w, mod1_w, mod2_w, mod3_w, strength); - diff0_r = (mod0_w < const16); - diff0_l = (mod1_w < const16); - diff1_r = (mod2_w < const16); - diff1_l = (mod3_w < const16); - SUB4(const16, mod0_w, const16, mod1_w, const16, mod2_w, const16, mod3_w, - mod0_w, mod1_w, mod2_w, mod3_w); - mod0_w = diff0_r & mod0_w; - mod1_w = diff0_l & mod1_w; - mod2_w = diff1_r & mod2_w; - mod3_w = diff1_l & mod3_w; - MUL4(mod0_w, filter_wt, mod1_w, filter_wt, mod2_w, filter_wt, mod3_w, - filter_wt, mod0_w, mod1_w, mod2_w, mod3_w); - PCKEV_H2_SH(mod1_w, mod0_w, mod3_w, mod2_w, mod0_h, mod1_h); - ADD2(mod0_h, cnt0, mod1_h, cnt1, mod0_h, mod1_h); - ST_SH2(mod0_h, mod1_h, cnt, 8); - cnt += 16; - - UNPCK_UB_SH(frame2_1_b, frame2_0_h, frame2_1_h); - UNPCK_SH_SW(frame2_0_h, frame2_0, frame2_1); - UNPCK_SH_SW(frame2_1_h, frame2_2, frame2_3); - MUL4(mod0_w, frame2_0, mod1_w, frame2_1, mod2_w, frame2_2, mod3_w, frame2_3, - mod0_w, mod1_w, mod2_w, mod3_w); - ADD4(mod0_w, acc0, mod1_w, acc1, mod2_w, acc2, mod3_w, acc3, mod0_w, mod1_w, - mod2_w, mod3_w); - ST_SW2(mod0_w, mod1_w, acc, 4); - ST_SW2(mod2_w, mod3_w, acc + 8, 4); - acc += 16; - frame1_ptr += stride; - frame2_ptr += 16; - } -} - -static void temporal_filter_apply_8size_msa( - uint8_t *frame1_ptr, uint32_t stride, uint8_t *frame2_ptr, - int32_t strength_in, int32_t filter_wt_in, uint32_t *acc, uint16_t *cnt) { - uint32_t row; - uint64_t f0, f1, f2, f3, f4, f5, f6, f7; - v16i8 frame1 = { 0 }; - v16i8 frame2 = { 0 }; - v16i8 frame3 = { 0 }; - v16i8 frame4 = { 0 }; - v16u8 frame_l, frame_h; - v8i16 frame2_0_h, frame2_1_h, mod0_h, mod1_h; - v8i16 diff0, diff1, cnt0, cnt1; - v4i32 const3, const16; - v4i32 filter_wt, strength; - v4i32 mod0_w, mod1_w, mod2_w, mod3_w; - v4i32 diff0_r, diff0_l, diff1_r, diff1_l; - v4i32 frame2_0, frame2_1, frame2_2, frame2_3; - v4i32 acc0, acc1, acc2, acc3; - - filter_wt = __msa_fill_w(filter_wt_in); - strength = __msa_fill_w(strength_in); - const3 = __msa_ldi_w(3); - const16 = __msa_ldi_w(16); - - for (row = 2; row--;) { - LD2(frame1_ptr, stride, f0, f1); - frame1_ptr += (2 * stride); - LD2(frame2_ptr, 8, f2, f3); - frame2_ptr += 16; - LD2(frame1_ptr, stride, f4, f5); - frame1_ptr += (2 * stride); - LD2(frame2_ptr, 8, f6, f7); - frame2_ptr += 16; - - LD_SW2(acc, 4, acc0, acc1); - LD_SW2(acc + 8, 4, acc2, acc3); - LD_SH2(cnt, 8, cnt0, cnt1); - INSERT_D2_SB(f0, f1, frame1); - INSERT_D2_SB(f2, f3, frame2); - INSERT_D2_SB(f4, f5, frame3); - INSERT_D2_SB(f6, f7, frame4); - ILVRL_B2_UB(frame1, frame2, frame_l, frame_h); - HSUB_UB2_SH(frame_l, frame_h, diff0, diff1); - UNPCK_SH_SW(diff0, diff0_r, diff0_l); - UNPCK_SH_SW(diff1, diff1_r, diff1_l); - MUL4(diff0_r, diff0_r, diff0_l, diff0_l, diff1_r, diff1_r, diff1_l, diff1_l, - mod0_w, mod1_w, mod2_w, mod3_w); - MUL4(mod0_w, const3, mod1_w, const3, mod2_w, const3, mod3_w, const3, mod0_w, - mod1_w, mod2_w, mod3_w); - SRAR_W4_SW(mod0_w, mod1_w, mod2_w, mod3_w, strength); - diff0_r = (mod0_w < const16); - diff0_l = (mod1_w < const16); - diff1_r = (mod2_w < const16); - diff1_l = (mod3_w < const16); - SUB4(const16, mod0_w, const16, mod1_w, const16, mod2_w, const16, mod3_w, - mod0_w, mod1_w, mod2_w, mod3_w); - mod0_w = diff0_r & mod0_w; - mod1_w = diff0_l & mod1_w; - mod2_w = diff1_r & mod2_w; - mod3_w = diff1_l & mod3_w; - MUL4(mod0_w, filter_wt, mod1_w, filter_wt, mod2_w, filter_wt, mod3_w, - filter_wt, mod0_w, mod1_w, mod2_w, mod3_w); - PCKEV_H2_SH(mod1_w, mod0_w, mod3_w, mod2_w, mod0_h, mod1_h); - ADD2(mod0_h, cnt0, mod1_h, cnt1, mod0_h, mod1_h); - ST_SH2(mod0_h, mod1_h, cnt, 8); - cnt += 16; - - UNPCK_UB_SH(frame2, frame2_0_h, frame2_1_h); - UNPCK_SH_SW(frame2_0_h, frame2_0, frame2_1); - UNPCK_SH_SW(frame2_1_h, frame2_2, frame2_3); - MUL4(mod0_w, frame2_0, mod1_w, frame2_1, mod2_w, frame2_2, mod3_w, frame2_3, - mod0_w, mod1_w, mod2_w, mod3_w); - ADD4(mod0_w, acc0, mod1_w, acc1, mod2_w, acc2, mod3_w, acc3, mod0_w, mod1_w, - mod2_w, mod3_w); - ST_SW2(mod0_w, mod1_w, acc, 4); - ST_SW2(mod2_w, mod3_w, acc + 8, 4); - acc += 16; - - LD_SW2(acc, 4, acc0, acc1); - LD_SW2(acc + 8, 4, acc2, acc3); - LD_SH2(cnt, 8, cnt0, cnt1); - ILVRL_B2_UB(frame3, frame4, frame_l, frame_h); - HSUB_UB2_SH(frame_l, frame_h, diff0, diff1); - UNPCK_SH_SW(diff0, diff0_r, diff0_l); - UNPCK_SH_SW(diff1, diff1_r, diff1_l); - MUL4(diff0_r, diff0_r, diff0_l, diff0_l, diff1_r, diff1_r, diff1_l, diff1_l, - mod0_w, mod1_w, mod2_w, mod3_w); - MUL4(mod0_w, const3, mod1_w, const3, mod2_w, const3, mod3_w, const3, mod0_w, - mod1_w, mod2_w, mod3_w); - SRAR_W4_SW(mod0_w, mod1_w, mod2_w, mod3_w, strength); - diff0_r = (mod0_w < const16); - diff0_l = (mod1_w < const16); - diff1_r = (mod2_w < const16); - diff1_l = (mod3_w < const16); - SUB4(const16, mod0_w, const16, mod1_w, const16, mod2_w, const16, mod3_w, - mod0_w, mod1_w, mod2_w, mod3_w); - mod0_w = diff0_r & mod0_w; - mod1_w = diff0_l & mod1_w; - mod2_w = diff1_r & mod2_w; - mod3_w = diff1_l & mod3_w; - MUL4(mod0_w, filter_wt, mod1_w, filter_wt, mod2_w, filter_wt, mod3_w, - filter_wt, mod0_w, mod1_w, mod2_w, mod3_w); - PCKEV_H2_SH(mod1_w, mod0_w, mod3_w, mod2_w, mod0_h, mod1_h); - ADD2(mod0_h, cnt0, mod1_h, cnt1, mod0_h, mod1_h); - ST_SH2(mod0_h, mod1_h, cnt, 8); - cnt += 16; - - UNPCK_UB_SH(frame4, frame2_0_h, frame2_1_h); - UNPCK_SH_SW(frame2_0_h, frame2_0, frame2_1); - UNPCK_SH_SW(frame2_1_h, frame2_2, frame2_3); - MUL4(mod0_w, frame2_0, mod1_w, frame2_1, mod2_w, frame2_2, mod3_w, frame2_3, - mod0_w, mod1_w, mod2_w, mod3_w); - ADD4(mod0_w, acc0, mod1_w, acc1, mod2_w, acc2, mod3_w, acc3, mod0_w, mod1_w, - mod2_w, mod3_w); - ST_SW2(mod0_w, mod1_w, acc, 4); - ST_SW2(mod2_w, mod3_w, acc + 8, 4); - acc += 16; - } -} - -void vp8_temporal_filter_apply_msa(uint8_t *frame1, uint32_t stride, - uint8_t *frame2, uint32_t block_size, - int32_t strength, int32_t filter_weight, - uint32_t *accumulator, uint16_t *count) { - if (8 == block_size) { - temporal_filter_apply_8size_msa(frame1, stride, frame2, strength, - filter_weight, accumulator, count); - } else if (16 == block_size) { - temporal_filter_apply_16size_msa(frame1, stride, frame2, strength, - filter_weight, accumulator, count); - } else { - uint32_t i, j, k; - int32_t modifier; - int32_t byte = 0; - const int32_t rounding = strength > 0 ? 1 << (strength - 1) : 0; - - for (i = 0, k = 0; i < block_size; ++i) { - for (j = 0; j < block_size; ++j, ++k) { - int src_byte = frame1[byte]; - int pixel_value = *frame2++; - - modifier = src_byte - pixel_value; - modifier *= modifier; - modifier *= 3; - modifier += rounding; - modifier >>= strength; - - if (modifier > 16) modifier = 16; - - modifier = 16 - modifier; - modifier *= filter_weight; - - count[k] += modifier; - accumulator[k] += modifier * pixel_value; - - byte++; - } - - byte += stride - block_size; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/modecosts.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/modecosts.c deleted file mode 100644 index b1c3120a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/modecosts.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp8/common/blockd.h" -#include "modecosts.h" -#include "onyx_int.h" -#include "treewriter.h" -#include "vp8/common/entropymode.h" - -void vp8_init_mode_costs(VP8_COMP *c) { - VP8_COMMON *x = &c->common; - struct rd_costs_struct *rd_costs = &c->rd_costs; - - { - const vp8_tree_p T = vp8_bmode_tree; - - int i = 0; - - do { - int j = 0; - - do { - vp8_cost_tokens(rd_costs->bmode_costs[i][j], vp8_kf_bmode_prob[i][j], - T); - } while (++j < VP8_BINTRAMODES); - } while (++i < VP8_BINTRAMODES); - - vp8_cost_tokens(rd_costs->inter_bmode_costs, x->fc.bmode_prob, T); - } - vp8_cost_tokens(rd_costs->inter_bmode_costs, x->fc.sub_mv_ref_prob, - vp8_sub_mv_ref_tree); - - vp8_cost_tokens(rd_costs->mbmode_cost[1], x->fc.ymode_prob, vp8_ymode_tree); - vp8_cost_tokens(rd_costs->mbmode_cost[0], vp8_kf_ymode_prob, - vp8_kf_ymode_tree); - - vp8_cost_tokens(rd_costs->intra_uv_mode_cost[1], x->fc.uv_mode_prob, - vp8_uv_mode_tree); - vp8_cost_tokens(rd_costs->intra_uv_mode_cost[0], vp8_kf_uv_mode_prob, - vp8_uv_mode_tree); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/modecosts.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/modecosts.h deleted file mode 100644 index 09ee2b55..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/modecosts.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_MODECOSTS_H_ -#define VPX_VP8_ENCODER_MODECOSTS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -struct VP8_COMP; - -void vp8_init_mode_costs(struct VP8_COMP *c); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_MODECOSTS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mr_dissim.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mr_dissim.c deleted file mode 100644 index b1bfb4b5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mr_dissim.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "vpx_config.h" -#include "onyx_int.h" -#include "mr_dissim.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "rdopt.h" -#include "vp8/common/common.h" - -void vp8_cal_low_res_mb_cols(VP8_COMP *cpi) { - int low_res_w; - - /* Support arbitrary down-sampling factor */ - unsigned int iw = cpi->oxcf.Width * cpi->oxcf.mr_down_sampling_factor.den + - cpi->oxcf.mr_down_sampling_factor.num - 1; - - low_res_w = iw / cpi->oxcf.mr_down_sampling_factor.num; - cpi->mr_low_res_mb_cols = ((low_res_w + 15) >> 4); -} - -#define GET_MV(x) \ - if (x->mbmi.ref_frame != INTRA_FRAME) { \ - mvx[cnt] = x->mbmi.mv.as_mv.row; \ - mvy[cnt] = x->mbmi.mv.as_mv.col; \ - cnt++; \ - } - -#define GET_MV_SIGN(x) \ - if (x->mbmi.ref_frame != INTRA_FRAME) { \ - mvx[cnt] = x->mbmi.mv.as_mv.row; \ - mvy[cnt] = x->mbmi.mv.as_mv.col; \ - if (cm->ref_frame_sign_bias[x->mbmi.ref_frame] != \ - cm->ref_frame_sign_bias[tmp->mbmi.ref_frame]) { \ - mvx[cnt] *= -1; \ - mvy[cnt] *= -1; \ - } \ - cnt++; \ - } - -void vp8_cal_dissimilarity(VP8_COMP *cpi) { - VP8_COMMON *cm = &cpi->common; - - /* Note: The first row & first column in mip are outside the frame, which - * were initialized to all 0.(ref_frame, mode, mv...) - * Their ref_frame = 0 means they won't be counted in the following - * calculation. - */ - if (cpi->oxcf.mr_total_resolutions > 1 && - cpi->oxcf.mr_encoder_id < (cpi->oxcf.mr_total_resolutions - 1)) { - /* Store info for show/no-show frames for supporting alt_ref. - * If parent frame is alt_ref, child has one too. - */ - LOWER_RES_FRAME_INFO *store_info = - (LOWER_RES_FRAME_INFO *)cpi->oxcf.mr_low_res_mode_info; - - store_info->frame_type = cm->frame_type; - - if (cm->frame_type != KEY_FRAME) { - int i; - store_info->is_frame_dropped = 0; - for (i = 1; i < MAX_REF_FRAMES; ++i) - store_info->low_res_ref_frames[i] = cpi->current_ref_frames[i]; - } - - if (cm->frame_type != KEY_FRAME) { - int mb_row; - int mb_col; - /* Point to beginning of allocated MODE_INFO arrays. */ - MODE_INFO *tmp = cm->mip + cm->mode_info_stride; - LOWER_RES_MB_INFO *store_mode_info = store_info->mb_info; - - for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) { - tmp++; - for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) { - int dissim = INT_MAX; - - if (tmp->mbmi.ref_frame != INTRA_FRAME) { - int mvx[8]; - int mvy[8]; - int mmvx; - int mmvy; - int cnt = 0; - const MODE_INFO *here = tmp; - const MODE_INFO *above = here - cm->mode_info_stride; - const MODE_INFO *left = here - 1; - const MODE_INFO *aboveleft = above - 1; - const MODE_INFO *aboveright = NULL; - const MODE_INFO *right = NULL; - const MODE_INFO *belowleft = NULL; - const MODE_INFO *below = NULL; - const MODE_INFO *belowright = NULL; - - /* If alternate reference frame is used, we have to - * check sign of MV. */ - if (cpi->oxcf.play_alternate) { - /* Gather mv of neighboring MBs */ - GET_MV_SIGN(above) - GET_MV_SIGN(left) - GET_MV_SIGN(aboveleft) - - if (mb_col < (cm->mb_cols - 1)) { - right = here + 1; - aboveright = above + 1; - GET_MV_SIGN(right) - GET_MV_SIGN(aboveright) - } - - if (mb_row < (cm->mb_rows - 1)) { - below = here + cm->mode_info_stride; - belowleft = below - 1; - GET_MV_SIGN(below) - GET_MV_SIGN(belowleft) - } - - if (mb_col < (cm->mb_cols - 1) && mb_row < (cm->mb_rows - 1)) { - belowright = below + 1; - GET_MV_SIGN(belowright) - } - } else { - /* No alt_ref and gather mv of neighboring MBs */ - GET_MV(above) - GET_MV(left) - GET_MV(aboveleft) - - if (mb_col < (cm->mb_cols - 1)) { - right = here + 1; - aboveright = above + 1; - GET_MV(right) - GET_MV(aboveright) - } - - if (mb_row < (cm->mb_rows - 1)) { - below = here + cm->mode_info_stride; - belowleft = below - 1; - GET_MV(below) - GET_MV(belowleft) - } - - if (mb_col < (cm->mb_cols - 1) && mb_row < (cm->mb_rows - 1)) { - belowright = below + 1; - GET_MV(belowright) - } - } - - if (cnt > 0) { - int max_mvx = mvx[0]; - int min_mvx = mvx[0]; - int max_mvy = mvy[0]; - int min_mvy = mvy[0]; - int i; - - if (cnt > 1) { - for (i = 1; i < cnt; ++i) { - if (mvx[i] > max_mvx) - max_mvx = mvx[i]; - else if (mvx[i] < min_mvx) - min_mvx = mvx[i]; - if (mvy[i] > max_mvy) - max_mvy = mvy[i]; - else if (mvy[i] < min_mvy) - min_mvy = mvy[i]; - } - } - - mmvx = VPXMAX(abs(min_mvx - here->mbmi.mv.as_mv.row), - abs(max_mvx - here->mbmi.mv.as_mv.row)); - mmvy = VPXMAX(abs(min_mvy - here->mbmi.mv.as_mv.col), - abs(max_mvy - here->mbmi.mv.as_mv.col)); - dissim = VPXMAX(mmvx, mmvy); - } - } - - /* Store mode info for next resolution encoding */ - store_mode_info->mode = tmp->mbmi.mode; - store_mode_info->ref_frame = tmp->mbmi.ref_frame; - store_mode_info->mv.as_int = tmp->mbmi.mv.as_int; - store_mode_info->dissim = dissim; - tmp++; - store_mode_info++; - } - } - } - } -} - -/* This function is called only when this frame is dropped at current - resolution level. */ -void vp8_store_drop_frame_info(VP8_COMP *cpi) { - /* If the frame is dropped in lower-resolution encoding, this information - is passed to higher resolution level so that the encoder knows there - is no mode & motion info available. - */ - if (cpi->oxcf.mr_total_resolutions > 1 && - cpi->oxcf.mr_encoder_id < (cpi->oxcf.mr_total_resolutions - 1)) { - /* Store info for show/no-show frames for supporting alt_ref. - * If parent frame is alt_ref, child has one too. - */ - LOWER_RES_FRAME_INFO *store_info = - (LOWER_RES_FRAME_INFO *)cpi->oxcf.mr_low_res_mode_info; - - /* Set frame_type to be INTER_FRAME since we won't drop key frame. */ - store_info->frame_type = INTER_FRAME; - store_info->is_frame_dropped = 1; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mr_dissim.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mr_dissim.h deleted file mode 100644 index 58f5a976..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/mr_dissim.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_MR_DISSIM_H_ -#define VPX_VP8_ENCODER_MR_DISSIM_H_ -#include "vpx_config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern void vp8_cal_low_res_mb_cols(VP8_COMP *cpi); -extern void vp8_cal_dissimilarity(VP8_COMP *cpi); -extern void vp8_store_drop_frame_info(VP8_COMP *cpi); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_MR_DISSIM_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/onyx_if.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/onyx_if.c deleted file mode 100644 index 17726fad..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/onyx_if.c +++ /dev/null @@ -1,5434 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "./vpx_scale_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "./vp8_rtcd.h" -#include "bitstream.h" -#include "vp8/common/onyxc_int.h" -#include "vp8/common/blockd.h" -#include "onyx_int.h" -#include "vp8/common/systemdependent.h" -#include "vp8/common/vp8_skin_detection.h" -#include "vp8/encoder/quantize.h" -#include "vp8/common/alloccommon.h" -#include "mcomp.h" -#include "firstpass.h" -#include "vpx_dsp/psnr.h" -#include "vpx_scale/vpx_scale.h" -#include "vp8/common/extend.h" -#include "ratectrl.h" -#include "vp8/common/quant_common.h" -#include "segmentation.h" -#if CONFIG_POSTPROC -#include "vp8/common/postproc.h" -#endif -#include "vpx_mem/vpx_mem.h" -#include "vp8/common/reconintra.h" -#include "vp8/common/swapyv12buffer.h" -#include "vp8/common/threading.h" -#include "vpx_ports/system_state.h" -#include "vpx_ports/vpx_once.h" -#include "vpx_ports/vpx_timer.h" -#include "vpx_util/vpx_write_yuv_frame.h" -#if VPX_ARCH_ARM -#include "vpx_ports/arm.h" -#endif -#if CONFIG_MULTI_RES_ENCODING -#include "mr_dissim.h" -#endif -#include "encodeframe.h" -#if CONFIG_MULTITHREAD -#include "ethreading.h" -#endif -#include "picklpf.h" -#if !CONFIG_REALTIME_ONLY -#include "temporal_filter.h" -#endif - -#include -#include -#include -#include - -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING -extern int vp8_update_coef_context(VP8_COMP *cpi); -#endif - -extern unsigned int vp8_get_processor_freq(void); - -int vp8_calc_ss_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest); - -static void set_default_lf_deltas(VP8_COMP *cpi); - -extern const int vp8_gf_interval_table[101]; - -#if CONFIG_INTERNAL_STATS -#include "math.h" -#include "vpx_dsp/ssim.h" -#endif - -#ifdef OUTPUT_YUV_SRC -FILE *yuv_file; -#endif -#ifdef OUTPUT_YUV_DENOISED -FILE *yuv_denoised_file; -#endif -#ifdef OUTPUT_YUV_SKINMAP -static FILE *yuv_skinmap_file = NULL; -#endif - -#if 0 -FILE *framepsnr; -FILE *kf_list; -FILE *keyfile; -#endif - -#if 0 -extern int skip_true_count; -extern int skip_false_count; -#endif - -#ifdef SPEEDSTATS -unsigned int frames_at_speed[16] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 }; -unsigned int tot_pm = 0; -unsigned int cnt_pm = 0; -unsigned int tot_ef = 0; -unsigned int cnt_ef = 0; -#endif - -#ifdef MODE_STATS -extern unsigned __int64 Sectionbits[50]; -extern int y_modes[5]; -extern int uv_modes[4]; -extern int b_modes[10]; - -extern int inter_y_modes[10]; -extern int inter_uv_modes[4]; -extern unsigned int inter_b_modes[15]; -#endif - -extern const int vp8_bits_per_mb[2][QINDEX_RANGE]; - -extern const int qrounding_factors[129]; -extern const int qzbin_factors[129]; -extern void vp8cx_init_quantizer(VP8_COMP *cpi); -extern const int vp8cx_base_skip_false_prob[128]; - -/* Tables relating active max Q to active min Q */ -static const unsigned char kf_low_motion_minq[QINDEX_RANGE] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, - 5, 5, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 10, 10, 10, 10, 11, - 11, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, - 17, 17, 18, 18, 18, 18, 19, 20, 20, 21, 21, 22, 23, 23 -}; -static const unsigned char kf_high_motion_minq[QINDEX_RANGE] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, - 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 10, 10, - 10, 10, 11, 11, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, - 16, 16, 16, 17, 17, 18, 18, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, - 22, 22, 23, 23, 24, 25, 25, 26, 26, 27, 28, 28, 29, 30 -}; -static const unsigned char gf_low_motion_minq[QINDEX_RANGE] = { - 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, - 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, - 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, - 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, - 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, - 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58 -}; -static const unsigned char gf_mid_motion_minq[QINDEX_RANGE] = { - 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, - 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, - 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 17, 17, 18, - 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, - 37, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 -}; -static const unsigned char gf_high_motion_minq[QINDEX_RANGE] = { - 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, - 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, - 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, - 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, - 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, - 40, 41, 41, 42, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80 -}; -static const unsigned char inter_minq[QINDEX_RANGE] = { - 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, 11, - 11, 12, 13, 13, 14, 15, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 24, - 24, 25, 26, 27, 27, 28, 29, 30, 30, 31, 32, 33, 33, 34, 35, 36, 36, 37, 38, - 39, 39, 40, 41, 42, 42, 43, 44, 45, 46, 46, 47, 48, 49, 50, 50, 51, 52, 53, - 54, 55, 55, 56, 57, 58, 59, 60, 60, 61, 62, 63, 64, 65, 66, 67, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 -}; - -#ifdef PACKET_TESTING -extern FILE *vpxlogc; -#endif - -void vp8_save_layer_context(VP8_COMP *cpi) { - LAYER_CONTEXT *lc = &cpi->layer_context[cpi->current_layer]; - - /* Save layer dependent coding state */ - lc->target_bandwidth = cpi->target_bandwidth; - lc->starting_buffer_level = cpi->oxcf.starting_buffer_level; - lc->optimal_buffer_level = cpi->oxcf.optimal_buffer_level; - lc->maximum_buffer_size = cpi->oxcf.maximum_buffer_size; - lc->starting_buffer_level_in_ms = cpi->oxcf.starting_buffer_level_in_ms; - lc->optimal_buffer_level_in_ms = cpi->oxcf.optimal_buffer_level_in_ms; - lc->maximum_buffer_size_in_ms = cpi->oxcf.maximum_buffer_size_in_ms; - lc->buffer_level = cpi->buffer_level; - lc->bits_off_target = cpi->bits_off_target; - lc->total_actual_bits = cpi->total_actual_bits; - lc->worst_quality = cpi->worst_quality; - lc->active_worst_quality = cpi->active_worst_quality; - lc->best_quality = cpi->best_quality; - lc->active_best_quality = cpi->active_best_quality; - lc->ni_av_qi = cpi->ni_av_qi; - lc->ni_tot_qi = cpi->ni_tot_qi; - lc->ni_frames = cpi->ni_frames; - lc->avg_frame_qindex = cpi->avg_frame_qindex; - lc->rate_correction_factor = cpi->rate_correction_factor; - lc->key_frame_rate_correction_factor = cpi->key_frame_rate_correction_factor; - lc->gf_rate_correction_factor = cpi->gf_rate_correction_factor; - lc->zbin_over_quant = cpi->mb.zbin_over_quant; - lc->inter_frame_target = cpi->inter_frame_target; - lc->total_byte_count = cpi->total_byte_count; - lc->filter_level = cpi->common.filter_level; - lc->frames_since_last_drop_overshoot = cpi->frames_since_last_drop_overshoot; - lc->force_maxqp = cpi->force_maxqp; - lc->last_frame_percent_intra = cpi->last_frame_percent_intra; - lc->last_q[0] = cpi->last_q[0]; - lc->last_q[1] = cpi->last_q[1]; - - memcpy(lc->count_mb_ref_frame_usage, cpi->mb.count_mb_ref_frame_usage, - sizeof(cpi->mb.count_mb_ref_frame_usage)); -} - -void vp8_restore_layer_context(VP8_COMP *cpi, const int layer) { - LAYER_CONTEXT *lc = &cpi->layer_context[layer]; - - /* Restore layer dependent coding state */ - cpi->current_layer = layer; - cpi->target_bandwidth = lc->target_bandwidth; - cpi->oxcf.target_bandwidth = lc->target_bandwidth; - cpi->oxcf.starting_buffer_level = lc->starting_buffer_level; - cpi->oxcf.optimal_buffer_level = lc->optimal_buffer_level; - cpi->oxcf.maximum_buffer_size = lc->maximum_buffer_size; - cpi->oxcf.starting_buffer_level_in_ms = lc->starting_buffer_level_in_ms; - cpi->oxcf.optimal_buffer_level_in_ms = lc->optimal_buffer_level_in_ms; - cpi->oxcf.maximum_buffer_size_in_ms = lc->maximum_buffer_size_in_ms; - cpi->buffer_level = lc->buffer_level; - cpi->bits_off_target = lc->bits_off_target; - cpi->total_actual_bits = lc->total_actual_bits; - cpi->active_worst_quality = lc->active_worst_quality; - cpi->active_best_quality = lc->active_best_quality; - cpi->ni_av_qi = lc->ni_av_qi; - cpi->ni_tot_qi = lc->ni_tot_qi; - cpi->ni_frames = lc->ni_frames; - cpi->avg_frame_qindex = lc->avg_frame_qindex; - cpi->rate_correction_factor = lc->rate_correction_factor; - cpi->key_frame_rate_correction_factor = lc->key_frame_rate_correction_factor; - cpi->gf_rate_correction_factor = lc->gf_rate_correction_factor; - cpi->mb.zbin_over_quant = lc->zbin_over_quant; - cpi->inter_frame_target = lc->inter_frame_target; - cpi->total_byte_count = lc->total_byte_count; - cpi->common.filter_level = lc->filter_level; - cpi->frames_since_last_drop_overshoot = lc->frames_since_last_drop_overshoot; - cpi->force_maxqp = lc->force_maxqp; - cpi->last_frame_percent_intra = lc->last_frame_percent_intra; - cpi->last_q[0] = lc->last_q[0]; - cpi->last_q[1] = lc->last_q[1]; - - memcpy(cpi->mb.count_mb_ref_frame_usage, lc->count_mb_ref_frame_usage, - sizeof(cpi->mb.count_mb_ref_frame_usage)); -} - -static int rescale(int val, int num, int denom) { - int64_t llnum = num; - int64_t llden = denom; - int64_t llval = val; - - int64_t result = (llval * llnum / llden); - if (result <= INT_MAX) - return (int)result; - else - return INT_MAX; -} - -void vp8_init_temporal_layer_context(VP8_COMP *cpi, const VP8_CONFIG *oxcf, - const int layer, - double prev_layer_framerate) { - LAYER_CONTEXT *lc = &cpi->layer_context[layer]; - - lc->framerate = cpi->output_framerate / cpi->oxcf.rate_decimator[layer]; - if (cpi->oxcf.target_bitrate[layer] > INT_MAX / 1000) - lc->target_bandwidth = INT_MAX; - else - lc->target_bandwidth = cpi->oxcf.target_bitrate[layer] * 1000; - - lc->starting_buffer_level_in_ms = oxcf->starting_buffer_level; - lc->optimal_buffer_level_in_ms = oxcf->optimal_buffer_level; - lc->maximum_buffer_size_in_ms = oxcf->maximum_buffer_size; - - lc->starting_buffer_level = - rescale((int)(oxcf->starting_buffer_level), lc->target_bandwidth, 1000); - - if (oxcf->optimal_buffer_level == 0) { - lc->optimal_buffer_level = lc->target_bandwidth / 8; - } else { - lc->optimal_buffer_level = - rescale((int)(oxcf->optimal_buffer_level), lc->target_bandwidth, 1000); - } - - if (oxcf->maximum_buffer_size == 0) { - lc->maximum_buffer_size = lc->target_bandwidth / 8; - } else { - lc->maximum_buffer_size = - rescale((int)(oxcf->maximum_buffer_size), lc->target_bandwidth, 1000); - } - - /* Work out the average size of a frame within this layer */ - if (layer > 0) { - lc->avg_frame_size_for_layer = - (int)round((cpi->oxcf.target_bitrate[layer] - - cpi->oxcf.target_bitrate[layer - 1]) * - 1000 / (lc->framerate - prev_layer_framerate)); - } - - lc->active_worst_quality = cpi->oxcf.worst_allowed_q; - lc->active_best_quality = cpi->oxcf.best_allowed_q; - lc->avg_frame_qindex = cpi->oxcf.worst_allowed_q; - - lc->buffer_level = lc->starting_buffer_level; - lc->bits_off_target = lc->starting_buffer_level; - - lc->total_actual_bits = 0; - lc->ni_av_qi = 0; - lc->ni_tot_qi = 0; - lc->ni_frames = 0; - lc->rate_correction_factor = 1.0; - lc->key_frame_rate_correction_factor = 1.0; - lc->gf_rate_correction_factor = 1.0; - lc->inter_frame_target = 0; -} - -// Upon a run-time change in temporal layers, reset the layer context parameters -// for any "new" layers. For "existing" layers, let them inherit the parameters -// from the previous layer state (at the same layer #). In future we may want -// to better map the previous layer state(s) to the "new" ones. -void vp8_reset_temporal_layer_change(VP8_COMP *cpi, const VP8_CONFIG *oxcf, - const int prev_num_layers) { - int i; - double prev_layer_framerate = 0; - const int curr_num_layers = cpi->oxcf.number_of_layers; - // If the previous state was 1 layer, get current layer context from cpi. - // We need this to set the layer context for the new layers below. - if (prev_num_layers == 1) { - cpi->current_layer = 0; - vp8_save_layer_context(cpi); - } - for (i = 0; i < curr_num_layers; ++i) { - LAYER_CONTEXT *lc = &cpi->layer_context[i]; - if (i >= prev_num_layers) { - vp8_init_temporal_layer_context(cpi, oxcf, i, prev_layer_framerate); - } - // The initial buffer levels are set based on their starting levels. - // We could set the buffer levels based on the previous state (normalized - // properly by the layer bandwidths) but we would need to keep track of - // the previous set of layer bandwidths (i.e., target_bitrate[i]) - // before the layer change. For now, reset to the starting levels. - lc->buffer_level = - cpi->oxcf.starting_buffer_level_in_ms * cpi->oxcf.target_bitrate[i]; - lc->bits_off_target = lc->buffer_level; - // TDOD(marpan): Should we set the rate_correction_factor and - // active_worst/best_quality to values derived from the previous layer - // state (to smooth-out quality dips/rate fluctuation at transition)? - - // We need to treat the 1 layer case separately: oxcf.target_bitrate[i] - // is not set for 1 layer, and the vp8_restore_layer_context/save_context() - // are not called in the encoding loop, so we need to call it here to - // pass the layer context state to |cpi|. - if (curr_num_layers == 1) { - lc->target_bandwidth = cpi->oxcf.target_bandwidth; - lc->buffer_level = - cpi->oxcf.starting_buffer_level_in_ms * lc->target_bandwidth / 1000; - lc->bits_off_target = lc->buffer_level; - vp8_restore_layer_context(cpi, 0); - } - prev_layer_framerate = cpi->output_framerate / cpi->oxcf.rate_decimator[i]; - } -} - -static void setup_features(VP8_COMP *cpi) { - // If segmentation enabled set the update flags - if (cpi->mb.e_mbd.segmentation_enabled) { - cpi->mb.e_mbd.update_mb_segmentation_map = 1; - cpi->mb.e_mbd.update_mb_segmentation_data = 1; - } else { - cpi->mb.e_mbd.update_mb_segmentation_map = 0; - cpi->mb.e_mbd.update_mb_segmentation_data = 0; - } - - cpi->mb.e_mbd.mode_ref_lf_delta_enabled = 0; - cpi->mb.e_mbd.mode_ref_lf_delta_update = 0; - memset(cpi->mb.e_mbd.ref_lf_deltas, 0, sizeof(cpi->mb.e_mbd.ref_lf_deltas)); - memset(cpi->mb.e_mbd.mode_lf_deltas, 0, sizeof(cpi->mb.e_mbd.mode_lf_deltas)); - memset(cpi->mb.e_mbd.last_ref_lf_deltas, 0, - sizeof(cpi->mb.e_mbd.ref_lf_deltas)); - memset(cpi->mb.e_mbd.last_mode_lf_deltas, 0, - sizeof(cpi->mb.e_mbd.mode_lf_deltas)); - - set_default_lf_deltas(cpi); -} - -static void dealloc_raw_frame_buffers(VP8_COMP *cpi); - -static void initialize_enc(void) { - vpx_dsp_rtcd(); - vp8_init_intra_predictors(); -} - -void vp8_initialize_enc(void) { once(initialize_enc); } - -static void dealloc_compressor_data(VP8_COMP *cpi) { - vpx_free(cpi->tplist); - cpi->tplist = NULL; - - /* Delete last frame MV storage buffers */ - vpx_free(cpi->lfmv); - cpi->lfmv = 0; - - vpx_free(cpi->lf_ref_frame_sign_bias); - cpi->lf_ref_frame_sign_bias = 0; - - vpx_free(cpi->lf_ref_frame); - cpi->lf_ref_frame = 0; - - /* Delete sementation map */ - vpx_free(cpi->segmentation_map); - cpi->segmentation_map = 0; - - vpx_free(cpi->active_map); - cpi->active_map = 0; - - vp8_de_alloc_frame_buffers(&cpi->common); - - vp8_yv12_de_alloc_frame_buffer(&cpi->pick_lf_lvl_frame); - vp8_yv12_de_alloc_frame_buffer(&cpi->scaled_source); - dealloc_raw_frame_buffers(cpi); - - vpx_free(cpi->tok); - cpi->tok = 0; - - /* Structure used to monitor GF usage */ - vpx_free(cpi->gf_active_flags); - cpi->gf_active_flags = 0; - - /* Activity mask based per mb zbin adjustments */ - vpx_free(cpi->mb_activity_map); - cpi->mb_activity_map = 0; - - vpx_free(cpi->mb.pip); - cpi->mb.pip = 0; -} - -static void enable_segmentation(VP8_COMP *cpi) { - /* Set the appropriate feature bit */ - cpi->mb.e_mbd.segmentation_enabled = 1; - cpi->mb.e_mbd.update_mb_segmentation_map = 1; - cpi->mb.e_mbd.update_mb_segmentation_data = 1; -} -static void disable_segmentation(VP8_COMP *cpi) { - /* Clear the appropriate feature bit */ - cpi->mb.e_mbd.segmentation_enabled = 0; -} - -/* Valid values for a segment are 0 to 3 - * Segmentation map is arrange as [Rows][Columns] - */ -static void set_segmentation_map(VP8_COMP *cpi, - unsigned char *segmentation_map) { - /* Copy in the new segmentation map */ - memcpy(cpi->segmentation_map, segmentation_map, - (cpi->common.mb_rows * cpi->common.mb_cols)); - - /* Signal that the map should be updated. */ - cpi->mb.e_mbd.update_mb_segmentation_map = 1; - cpi->mb.e_mbd.update_mb_segmentation_data = 1; -} - -/* The values given for each segment can be either deltas (from the default - * value chosen for the frame) or absolute values. - * - * Valid range for abs values is: - * (0-127 for MB_LVL_ALT_Q), (0-63 for SEGMENT_ALT_LF) - * Valid range for delta values are: - * (+/-127 for MB_LVL_ALT_Q), (+/-63 for SEGMENT_ALT_LF) - * - * abs_delta = SEGMENT_DELTADATA (deltas) - * abs_delta = SEGMENT_ABSDATA (use the absolute values given). - * - */ -static void set_segment_data(VP8_COMP *cpi, signed char *feature_data, - unsigned char abs_delta) { - cpi->mb.e_mbd.mb_segment_abs_delta = abs_delta; - memcpy(cpi->segment_feature_data, feature_data, - sizeof(cpi->segment_feature_data)); -} - -/* A simple function to cyclically refresh the background at a lower Q */ -static void cyclic_background_refresh(VP8_COMP *cpi, int Q, int lf_adjustment) { - unsigned char *seg_map = cpi->segmentation_map; - signed char feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; - int i; - int block_count = cpi->cyclic_refresh_mode_max_mbs_perframe; - int mbs_in_frame = cpi->common.mb_rows * cpi->common.mb_cols; - - cpi->cyclic_refresh_q = Q / 2; - - if (cpi->oxcf.screen_content_mode) { - // Modify quality ramp-up based on Q. Above some Q level, increase the - // number of blocks to be refreshed, and reduce it below the thredhold. - // Turn-off under certain conditions (i.e., away from key frame, and if - // we are at good quality (low Q) and most of the blocks were - // skipped-encoded - // in previous frame. - int qp_thresh = (cpi->oxcf.screen_content_mode == 2) ? 80 : 100; - if (Q >= qp_thresh) { - cpi->cyclic_refresh_mode_max_mbs_perframe = - (cpi->common.mb_rows * cpi->common.mb_cols) / 10; - } else if (cpi->frames_since_key > 250 && Q < 20 && - cpi->mb.skip_true_count > (int)(0.95 * mbs_in_frame)) { - cpi->cyclic_refresh_mode_max_mbs_perframe = 0; - } else { - cpi->cyclic_refresh_mode_max_mbs_perframe = - (cpi->common.mb_rows * cpi->common.mb_cols) / 20; - } - block_count = cpi->cyclic_refresh_mode_max_mbs_perframe; - } - - // Set every macroblock to be eligible for update. - // For key frame this will reset seg map to 0. - memset(cpi->segmentation_map, 0, mbs_in_frame); - - if (cpi->common.frame_type != KEY_FRAME && block_count > 0) { - /* Cycle through the macro_block rows */ - /* MB loop to set local segmentation map */ - i = cpi->cyclic_refresh_mode_index; - assert(i < mbs_in_frame); - do { - /* If the MB is as a candidate for clean up then mark it for - * possible boost/refresh (segment 1) The segment id may get - * reset to 0 later if the MB gets coded anything other than - * last frame 0,0 as only (last frame 0,0) MBs are eligable for - * refresh : that is to say Mbs likely to be background blocks. - */ - if (cpi->cyclic_refresh_map[i] == 0) { - seg_map[i] = 1; - block_count--; - } else if (cpi->cyclic_refresh_map[i] < 0) { - cpi->cyclic_refresh_map[i]++; - } - - i++; - if (i == mbs_in_frame) i = 0; - - } while (block_count && i != cpi->cyclic_refresh_mode_index); - - cpi->cyclic_refresh_mode_index = i; - -#if CONFIG_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity > 0) { - if (cpi->denoiser.denoiser_mode == kDenoiserOnYUVAggressive && - Q < (int)cpi->denoiser.denoise_pars.qp_thresh && - (cpi->frames_since_key > - 2 * cpi->denoiser.denoise_pars.consec_zerolast)) { - // Under aggressive denoising, use segmentation to turn off loop - // filter below some qp thresh. The filter is reduced for all - // blocks that have been encoded as ZEROMV LAST x frames in a row, - // where x is set by cpi->denoiser.denoise_pars.consec_zerolast. - // This is to avoid "dot" artifacts that can occur from repeated - // loop filtering on noisy input source. - cpi->cyclic_refresh_q = Q; - // lf_adjustment = -MAX_LOOP_FILTER; - lf_adjustment = -40; - for (i = 0; i < mbs_in_frame; ++i) { - seg_map[i] = (cpi->consec_zero_last[i] > - cpi->denoiser.denoise_pars.consec_zerolast) - ? 1 - : 0; - } - } - } -#endif - } - - /* Activate segmentation. */ - cpi->mb.e_mbd.update_mb_segmentation_map = 1; - cpi->mb.e_mbd.update_mb_segmentation_data = 1; - enable_segmentation(cpi); - - /* Set up the quant segment data */ - feature_data[MB_LVL_ALT_Q][0] = 0; - feature_data[MB_LVL_ALT_Q][1] = (cpi->cyclic_refresh_q - Q); - feature_data[MB_LVL_ALT_Q][2] = 0; - feature_data[MB_LVL_ALT_Q][3] = 0; - - /* Set up the loop segment data */ - feature_data[MB_LVL_ALT_LF][0] = 0; - feature_data[MB_LVL_ALT_LF][1] = lf_adjustment; - feature_data[MB_LVL_ALT_LF][2] = 0; - feature_data[MB_LVL_ALT_LF][3] = 0; - - /* Initialise the feature data structure */ - set_segment_data(cpi, &feature_data[0][0], SEGMENT_DELTADATA); -} - -static void compute_skin_map(VP8_COMP *cpi) { - int mb_row, mb_col, num_bl; - VP8_COMMON *cm = &cpi->common; - const uint8_t *src_y = cpi->Source->y_buffer; - const uint8_t *src_u = cpi->Source->u_buffer; - const uint8_t *src_v = cpi->Source->v_buffer; - const int src_ystride = cpi->Source->y_stride; - const int src_uvstride = cpi->Source->uv_stride; - - const SKIN_DETECTION_BLOCK_SIZE bsize = - (cm->Width * cm->Height <= 352 * 288) ? SKIN_8X8 : SKIN_16X16; - - for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) { - num_bl = 0; - for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { - const int bl_index = mb_row * cm->mb_cols + mb_col; - cpi->skin_map[bl_index] = - vp8_compute_skin_block(src_y, src_u, src_v, src_ystride, src_uvstride, - bsize, cpi->consec_zero_last[bl_index], 0); - num_bl++; - src_y += 16; - src_u += 8; - src_v += 8; - } - src_y += (src_ystride << 4) - (num_bl << 4); - src_u += (src_uvstride << 3) - (num_bl << 3); - src_v += (src_uvstride << 3) - (num_bl << 3); - } - - // Remove isolated skin blocks (none of its neighbors are skin) and isolated - // non-skin blocks (all of its neighbors are skin). Skip the boundary. - for (mb_row = 1; mb_row < cm->mb_rows - 1; mb_row++) { - for (mb_col = 1; mb_col < cm->mb_cols - 1; mb_col++) { - const int bl_index = mb_row * cm->mb_cols + mb_col; - int num_neighbor = 0; - int mi, mj; - int non_skin_threshold = 8; - - for (mi = -1; mi <= 1; mi += 1) { - for (mj = -1; mj <= 1; mj += 1) { - int bl_neighbor_index = (mb_row + mi) * cm->mb_cols + mb_col + mj; - if (cpi->skin_map[bl_neighbor_index]) num_neighbor++; - } - } - - if (cpi->skin_map[bl_index] && num_neighbor < 2) - cpi->skin_map[bl_index] = 0; - if (!cpi->skin_map[bl_index] && num_neighbor == non_skin_threshold) - cpi->skin_map[bl_index] = 1; - } - } -} - -static void set_default_lf_deltas(VP8_COMP *cpi) { - cpi->mb.e_mbd.mode_ref_lf_delta_enabled = 1; - cpi->mb.e_mbd.mode_ref_lf_delta_update = 1; - - memset(cpi->mb.e_mbd.ref_lf_deltas, 0, sizeof(cpi->mb.e_mbd.ref_lf_deltas)); - memset(cpi->mb.e_mbd.mode_lf_deltas, 0, sizeof(cpi->mb.e_mbd.mode_lf_deltas)); - - /* Test of ref frame deltas */ - cpi->mb.e_mbd.ref_lf_deltas[INTRA_FRAME] = 2; - cpi->mb.e_mbd.ref_lf_deltas[LAST_FRAME] = 0; - cpi->mb.e_mbd.ref_lf_deltas[GOLDEN_FRAME] = -2; - cpi->mb.e_mbd.ref_lf_deltas[ALTREF_FRAME] = -2; - - cpi->mb.e_mbd.mode_lf_deltas[0] = 4; /* BPRED */ - - if (cpi->oxcf.Mode == MODE_REALTIME) { - cpi->mb.e_mbd.mode_lf_deltas[1] = -12; /* Zero */ - } else { - cpi->mb.e_mbd.mode_lf_deltas[1] = -2; /* Zero */ - } - - cpi->mb.e_mbd.mode_lf_deltas[2] = 2; /* New mv */ - cpi->mb.e_mbd.mode_lf_deltas[3] = 4; /* Split mv */ -} - -/* Convenience macros for mapping speed and mode into a continuous - * range - */ -#define GOOD(x) ((x) + 1) -#define RT(x) ((x) + 7) - -static int speed_map(int speed, const int *map) { - int res; - - do { - res = *map++; - } while (speed >= *map++); - return res; -} - -static const int thresh_mult_map_znn[] = { - /* map common to zero, nearest, and near */ - 0, GOOD(2), 1500, GOOD(3), 2000, RT(0), 1000, RT(2), 2000, INT_MAX -}; - -static const int thresh_mult_map_vhpred[] = { 1000, GOOD(2), 1500, GOOD(3), - 2000, RT(0), 1000, RT(1), - 2000, RT(7), INT_MAX, INT_MAX }; - -static const int thresh_mult_map_bpred[] = { 2000, GOOD(0), 2500, GOOD(2), - 5000, GOOD(3), 7500, RT(0), - 2500, RT(1), 5000, RT(6), - INT_MAX, INT_MAX }; - -static const int thresh_mult_map_tm[] = { 1000, GOOD(2), 1500, GOOD(3), - 2000, RT(0), 0, RT(1), - 1000, RT(2), 2000, RT(7), - INT_MAX, INT_MAX }; - -static const int thresh_mult_map_new1[] = { 1000, GOOD(2), 2000, - RT(0), 2000, INT_MAX }; - -static const int thresh_mult_map_new2[] = { 1000, GOOD(2), 2000, GOOD(3), - 2500, GOOD(5), 4000, RT(0), - 2000, RT(2), 2500, RT(5), - 4000, INT_MAX }; - -static const int thresh_mult_map_split1[] = { - 2500, GOOD(0), 1700, GOOD(2), 10000, GOOD(3), 25000, GOOD(4), INT_MAX, - RT(0), 5000, RT(1), 10000, RT(2), 25000, RT(3), INT_MAX, INT_MAX -}; - -static const int thresh_mult_map_split2[] = { - 5000, GOOD(0), 4500, GOOD(2), 20000, GOOD(3), 50000, GOOD(4), INT_MAX, - RT(0), 10000, RT(1), 20000, RT(2), 50000, RT(3), INT_MAX, INT_MAX -}; - -static const int mode_check_freq_map_zn2[] = { - /* {zero,nearest}{2,3} */ - 0, RT(10), 1 << 1, RT(11), 1 << 2, RT(12), 1 << 3, INT_MAX -}; - -static const int mode_check_freq_map_vhbpred[] = { 0, GOOD(5), 2, RT(0), - 0, RT(3), 2, RT(5), - 4, INT_MAX }; - -static const int mode_check_freq_map_near2[] = { - 0, GOOD(5), 2, RT(0), 0, RT(3), 2, - RT(10), 1 << 2, RT(11), 1 << 3, RT(12), 1 << 4, INT_MAX -}; - -static const int mode_check_freq_map_new1[] = { - 0, RT(10), 1 << 1, RT(11), 1 << 2, RT(12), 1 << 3, INT_MAX -}; - -static const int mode_check_freq_map_new2[] = { 0, GOOD(5), 4, RT(0), - 0, RT(3), 4, RT(10), - 1 << 3, RT(11), 1 << 4, RT(12), - 1 << 5, INT_MAX }; - -static const int mode_check_freq_map_split1[] = { 0, GOOD(2), 2, GOOD(3), - 7, RT(1), 2, RT(2), - 7, INT_MAX }; - -static const int mode_check_freq_map_split2[] = { 0, GOOD(1), 2, GOOD(2), - 4, GOOD(3), 15, RT(1), - 4, RT(2), 15, INT_MAX }; - -void vp8_set_speed_features(VP8_COMP *cpi) { - SPEED_FEATURES *sf = &cpi->sf; - int Mode = cpi->compressor_speed; - int Speed = cpi->Speed; - int Speed2; - int i; - VP8_COMMON *cm = &cpi->common; - int last_improved_quant = sf->improved_quant; - int ref_frames; - - /* Initialise default mode frequency sampling variables */ - for (i = 0; i < MAX_MODES; ++i) { - cpi->mode_check_freq[i] = 0; - } - - cpi->mb.mbs_tested_so_far = 0; - cpi->mb.mbs_zero_last_dot_suppress = 0; - - /* best quality defaults */ - sf->RD = 1; - sf->search_method = NSTEP; - sf->improved_quant = 1; - sf->improved_dct = 1; - sf->auto_filter = 1; - sf->recode_loop = 1; - sf->quarter_pixel_search = 1; - sf->half_pixel_search = 1; - sf->iterative_sub_pixel = 1; - sf->optimize_coefficients = 1; - sf->use_fastquant_for_pick = 0; - sf->no_skip_block4x4_search = 1; - - sf->first_step = 0; - sf->max_step_search_steps = MAX_MVSEARCH_STEPS; - sf->improved_mv_pred = 1; - - /* default thresholds to 0 */ - for (i = 0; i < MAX_MODES; ++i) sf->thresh_mult[i] = 0; - - /* Count enabled references */ - ref_frames = 1; - if (cpi->ref_frame_flags & VP8_LAST_FRAME) ref_frames++; - if (cpi->ref_frame_flags & VP8_GOLD_FRAME) ref_frames++; - if (cpi->ref_frame_flags & VP8_ALTR_FRAME) ref_frames++; - - /* Convert speed to continuous range, with clamping */ - if (Mode == 0) { - Speed = 0; - } else if (Mode == 2) { - Speed = RT(Speed); - } else { - if (Speed > 5) Speed = 5; - Speed = GOOD(Speed); - } - - sf->thresh_mult[THR_ZERO1] = sf->thresh_mult[THR_NEAREST1] = - sf->thresh_mult[THR_NEAR1] = sf->thresh_mult[THR_DC] = 0; /* always */ - - sf->thresh_mult[THR_ZERO2] = sf->thresh_mult[THR_ZERO3] = - sf->thresh_mult[THR_NEAREST2] = sf->thresh_mult[THR_NEAREST3] = - sf->thresh_mult[THR_NEAR2] = sf->thresh_mult[THR_NEAR3] = - speed_map(Speed, thresh_mult_map_znn); - - sf->thresh_mult[THR_V_PRED] = sf->thresh_mult[THR_H_PRED] = - speed_map(Speed, thresh_mult_map_vhpred); - sf->thresh_mult[THR_B_PRED] = speed_map(Speed, thresh_mult_map_bpred); - sf->thresh_mult[THR_TM] = speed_map(Speed, thresh_mult_map_tm); - sf->thresh_mult[THR_NEW1] = speed_map(Speed, thresh_mult_map_new1); - sf->thresh_mult[THR_NEW2] = sf->thresh_mult[THR_NEW3] = - speed_map(Speed, thresh_mult_map_new2); - sf->thresh_mult[THR_SPLIT1] = speed_map(Speed, thresh_mult_map_split1); - sf->thresh_mult[THR_SPLIT2] = sf->thresh_mult[THR_SPLIT3] = - speed_map(Speed, thresh_mult_map_split2); - - // Special case for temporal layers. - // Reduce the thresholds for zero/nearest/near for GOLDEN, if GOLDEN is - // used as second reference. We don't modify thresholds for ALTREF case - // since ALTREF is usually used as long-term reference in temporal layers. - if ((cpi->Speed <= 6) && (cpi->oxcf.number_of_layers > 1) && - (cpi->ref_frame_flags & VP8_LAST_FRAME) && - (cpi->ref_frame_flags & VP8_GOLD_FRAME)) { - if (cpi->closest_reference_frame == GOLDEN_FRAME) { - sf->thresh_mult[THR_ZERO2] = sf->thresh_mult[THR_ZERO2] >> 3; - sf->thresh_mult[THR_NEAREST2] = sf->thresh_mult[THR_NEAREST2] >> 3; - sf->thresh_mult[THR_NEAR2] = sf->thresh_mult[THR_NEAR2] >> 3; - } else { - sf->thresh_mult[THR_ZERO2] = sf->thresh_mult[THR_ZERO2] >> 1; - sf->thresh_mult[THR_NEAREST2] = sf->thresh_mult[THR_NEAREST2] >> 1; - sf->thresh_mult[THR_NEAR2] = sf->thresh_mult[THR_NEAR2] >> 1; - } - } - - cpi->mode_check_freq[THR_ZERO1] = cpi->mode_check_freq[THR_NEAREST1] = - cpi->mode_check_freq[THR_NEAR1] = cpi->mode_check_freq[THR_TM] = - cpi->mode_check_freq[THR_DC] = 0; /* always */ - - cpi->mode_check_freq[THR_ZERO2] = cpi->mode_check_freq[THR_ZERO3] = - cpi->mode_check_freq[THR_NEAREST2] = cpi->mode_check_freq[THR_NEAREST3] = - speed_map(Speed, mode_check_freq_map_zn2); - - cpi->mode_check_freq[THR_NEAR2] = cpi->mode_check_freq[THR_NEAR3] = - speed_map(Speed, mode_check_freq_map_near2); - - cpi->mode_check_freq[THR_V_PRED] = cpi->mode_check_freq[THR_H_PRED] = - cpi->mode_check_freq[THR_B_PRED] = - speed_map(Speed, mode_check_freq_map_vhbpred); - - // For real-time mode at speed 10 keep the mode_check_freq threshold - // for NEW1 similar to that of speed 9. - Speed2 = Speed; - if (cpi->Speed == 10 && Mode == 2) Speed2 = RT(9); - cpi->mode_check_freq[THR_NEW1] = speed_map(Speed2, mode_check_freq_map_new1); - - cpi->mode_check_freq[THR_NEW2] = cpi->mode_check_freq[THR_NEW3] = - speed_map(Speed, mode_check_freq_map_new2); - - cpi->mode_check_freq[THR_SPLIT1] = - speed_map(Speed, mode_check_freq_map_split1); - cpi->mode_check_freq[THR_SPLIT2] = cpi->mode_check_freq[THR_SPLIT3] = - speed_map(Speed, mode_check_freq_map_split2); - Speed = cpi->Speed; - switch (Mode) { -#if !CONFIG_REALTIME_ONLY - case 0: /* best quality mode */ - sf->first_step = 0; - sf->max_step_search_steps = MAX_MVSEARCH_STEPS; - break; - case 1: - case 3: - if (Speed > 0) { - /* Disable coefficient optimization above speed 0 */ - sf->optimize_coefficients = 0; - sf->use_fastquant_for_pick = 1; - sf->no_skip_block4x4_search = 0; - - sf->first_step = 1; - } - - if (Speed > 2) { - sf->improved_quant = 0; - sf->improved_dct = 0; - - /* Only do recode loop on key frames, golden frames and - * alt ref frames - */ - sf->recode_loop = 2; - } - - if (Speed > 3) { - sf->auto_filter = 1; - sf->recode_loop = 0; /* recode loop off */ - sf->RD = 0; /* Turn rd off */ - } - - if (Speed > 4) { - sf->auto_filter = 0; /* Faster selection of loop filter */ - } - - break; -#endif - case 2: - sf->optimize_coefficients = 0; - sf->recode_loop = 0; - sf->auto_filter = 1; - sf->iterative_sub_pixel = 1; - sf->search_method = NSTEP; - - if (Speed > 0) { - sf->improved_quant = 0; - sf->improved_dct = 0; - - sf->use_fastquant_for_pick = 1; - sf->no_skip_block4x4_search = 0; - sf->first_step = 1; - } - - if (Speed > 2) sf->auto_filter = 0; /* Faster selection of loop filter */ - - if (Speed > 3) { - sf->RD = 0; - sf->auto_filter = 1; - } - - if (Speed > 4) { - sf->auto_filter = 0; /* Faster selection of loop filter */ - sf->search_method = HEX; - sf->iterative_sub_pixel = 0; - } - - if (Speed > 6) { - unsigned int sum = 0; - unsigned int total_mbs = cm->MBs; - int thresh; - unsigned int total_skip; - - int min = 2000; - - if (cpi->oxcf.encode_breakout > 2000) min = cpi->oxcf.encode_breakout; - - min >>= 7; - - for (i = 0; i < min; ++i) { - sum += cpi->mb.error_bins[i]; - } - - total_skip = sum; - sum = 0; - - /* i starts from 2 to make sure thresh started from 2048 */ - for (; i < 1024; ++i) { - sum += cpi->mb.error_bins[i]; - - if (10 * sum >= - (unsigned int)(cpi->Speed - 6) * (total_mbs - total_skip)) { - break; - } - } - - i--; - thresh = (i << 7); - - if (thresh < 2000) thresh = 2000; - - if (ref_frames > 1) { - sf->thresh_mult[THR_NEW1] = thresh; - sf->thresh_mult[THR_NEAREST1] = thresh >> 1; - sf->thresh_mult[THR_NEAR1] = thresh >> 1; - } - - if (ref_frames > 2) { - sf->thresh_mult[THR_NEW2] = thresh << 1; - sf->thresh_mult[THR_NEAREST2] = thresh; - sf->thresh_mult[THR_NEAR2] = thresh; - } - - if (ref_frames > 3) { - sf->thresh_mult[THR_NEW3] = thresh << 1; - sf->thresh_mult[THR_NEAREST3] = thresh; - sf->thresh_mult[THR_NEAR3] = thresh; - } - - sf->improved_mv_pred = 0; - } - - if (Speed > 8) sf->quarter_pixel_search = 0; - - if (cm->version == 0) { - cm->filter_type = NORMAL_LOOPFILTER; - - if (Speed >= 14) cm->filter_type = SIMPLE_LOOPFILTER; - } else { - cm->filter_type = SIMPLE_LOOPFILTER; - } - - /* This has a big hit on quality. Last resort */ - if (Speed >= 15) sf->half_pixel_search = 0; - - memset(cpi->mb.error_bins, 0, sizeof(cpi->mb.error_bins)); - - } /* switch */ - - /* Slow quant, dct and trellis not worthwhile for first pass - * so make sure they are always turned off. - */ - if (cpi->pass == 1) { - sf->improved_quant = 0; - sf->optimize_coefficients = 0; - sf->improved_dct = 0; - } - - if (cpi->sf.search_method == NSTEP) { - vp8_init3smotion_compensation(&cpi->mb, - cm->yv12_fb[cm->lst_fb_idx].y_stride); - } else if (cpi->sf.search_method == DIAMOND) { - vp8_init_dsmotion_compensation(&cpi->mb, - cm->yv12_fb[cm->lst_fb_idx].y_stride); - } - - if (cpi->sf.improved_dct) { - cpi->mb.short_fdct8x4 = vp8_short_fdct8x4; - cpi->mb.short_fdct4x4 = vp8_short_fdct4x4; - } else { - /* No fast FDCT defined for any platform at this time. */ - cpi->mb.short_fdct8x4 = vp8_short_fdct8x4; - cpi->mb.short_fdct4x4 = vp8_short_fdct4x4; - } - - cpi->mb.short_walsh4x4 = vp8_short_walsh4x4; - - if (cpi->sf.improved_quant) { - cpi->mb.quantize_b = vp8_regular_quantize_b; - } else { - cpi->mb.quantize_b = vp8_fast_quantize_b; - } - if (cpi->sf.improved_quant != last_improved_quant) vp8cx_init_quantizer(cpi); - - if (cpi->sf.iterative_sub_pixel == 1) { - cpi->find_fractional_mv_step = vp8_find_best_sub_pixel_step_iteratively; - } else if (cpi->sf.quarter_pixel_search) { - cpi->find_fractional_mv_step = vp8_find_best_sub_pixel_step; - } else if (cpi->sf.half_pixel_search) { - cpi->find_fractional_mv_step = vp8_find_best_half_pixel_step; - } else { - cpi->find_fractional_mv_step = vp8_skip_fractional_mv_step; - } - - if (cpi->sf.optimize_coefficients == 1 && cpi->pass != 1) { - cpi->mb.optimize = 1; - } else { - cpi->mb.optimize = 0; - } - - if (cpi->common.full_pixel) { - cpi->find_fractional_mv_step = vp8_skip_fractional_mv_step; - } - -#ifdef SPEEDSTATS - frames_at_speed[cpi->Speed]++; -#endif -} -#undef GOOD -#undef RT - -static void alloc_raw_frame_buffers(VP8_COMP *cpi) { -#if VP8_TEMPORAL_ALT_REF - int width = (cpi->oxcf.Width + 15) & ~15; - int height = (cpi->oxcf.Height + 15) & ~15; -#endif - - cpi->lookahead = vp8_lookahead_init(cpi->oxcf.Width, cpi->oxcf.Height, - cpi->oxcf.lag_in_frames); - if (!cpi->lookahead) { - vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, - "Failed to allocate lag buffers"); - } - -#if VP8_TEMPORAL_ALT_REF - - if (vp8_yv12_alloc_frame_buffer(&cpi->alt_ref_buffer, width, height, - VP8BORDERINPIXELS)) { - vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, - "Failed to allocate altref buffer"); - } - -#endif -} - -static void dealloc_raw_frame_buffers(VP8_COMP *cpi) { -#if VP8_TEMPORAL_ALT_REF - vp8_yv12_de_alloc_frame_buffer(&cpi->alt_ref_buffer); -#endif - vp8_lookahead_destroy(cpi->lookahead); -} - -static int vp8_alloc_partition_data(VP8_COMP *cpi) { - vpx_free(cpi->mb.pip); - - cpi->mb.pip = - vpx_calloc((cpi->common.mb_cols + 1) * (cpi->common.mb_rows + 1), - sizeof(PARTITION_INFO)); - if (!cpi->mb.pip) return 1; - - cpi->mb.pi = cpi->mb.pip + cpi->common.mode_info_stride + 1; - - return 0; -} - -void vp8_alloc_compressor_data(VP8_COMP *cpi) { - VP8_COMMON *cm = &cpi->common; - - int width = cm->Width; - int height = cm->Height; - - if (vp8_alloc_frame_buffers(cm, width, height)) { - vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, - "Failed to allocate frame buffers"); - } - - if (vp8_alloc_partition_data(cpi)) { - vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, - "Failed to allocate partition data"); - } - - if ((width & 0xf) != 0) width += 16 - (width & 0xf); - - if ((height & 0xf) != 0) height += 16 - (height & 0xf); - - if (vp8_yv12_alloc_frame_buffer(&cpi->pick_lf_lvl_frame, width, height, - VP8BORDERINPIXELS)) { - vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, - "Failed to allocate last frame buffer"); - } - - if (vp8_yv12_alloc_frame_buffer(&cpi->scaled_source, width, height, - VP8BORDERINPIXELS)) { - vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, - "Failed to allocate scaled source buffer"); - } - - vpx_free(cpi->tok); - - { -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING - unsigned int tokens = 8 * 24 * 16; /* one MB for each thread */ -#else - unsigned int tokens = cm->mb_rows * cm->mb_cols * 24 * 16; -#endif - CHECK_MEM_ERROR(&cpi->common.error, cpi->tok, - vpx_calloc(tokens, sizeof(*cpi->tok))); - } - - /* Data used for real time vc mode to see if gf needs refreshing */ - cpi->zeromv_count = 0; - - /* Structures used to monitor GF usage */ - vpx_free(cpi->gf_active_flags); - CHECK_MEM_ERROR( - &cpi->common.error, cpi->gf_active_flags, - vpx_calloc(sizeof(*cpi->gf_active_flags), cm->mb_rows * cm->mb_cols)); - cpi->gf_active_count = cm->mb_rows * cm->mb_cols; - - vpx_free(cpi->mb_activity_map); - CHECK_MEM_ERROR( - &cpi->common.error, cpi->mb_activity_map, - vpx_calloc(sizeof(*cpi->mb_activity_map), cm->mb_rows * cm->mb_cols)); - - /* allocate memory for storing last frame's MVs for MV prediction. */ - vpx_free(cpi->lfmv); - CHECK_MEM_ERROR( - &cpi->common.error, cpi->lfmv, - vpx_calloc((cm->mb_rows + 2) * (cm->mb_cols + 2), sizeof(*cpi->lfmv))); - vpx_free(cpi->lf_ref_frame_sign_bias); - CHECK_MEM_ERROR(&cpi->common.error, cpi->lf_ref_frame_sign_bias, - vpx_calloc((cm->mb_rows + 2) * (cm->mb_cols + 2), - sizeof(*cpi->lf_ref_frame_sign_bias))); - vpx_free(cpi->lf_ref_frame); - CHECK_MEM_ERROR(&cpi->common.error, cpi->lf_ref_frame, - vpx_calloc((cm->mb_rows + 2) * (cm->mb_cols + 2), - sizeof(*cpi->lf_ref_frame))); - - /* Create the encoder segmentation map and set all entries to 0 */ - vpx_free(cpi->segmentation_map); - CHECK_MEM_ERROR( - &cpi->common.error, cpi->segmentation_map, - vpx_calloc(cm->mb_rows * cm->mb_cols, sizeof(*cpi->segmentation_map))); - cpi->cyclic_refresh_mode_index = 0; - vpx_free(cpi->active_map); - CHECK_MEM_ERROR( - &cpi->common.error, cpi->active_map, - vpx_calloc(cm->mb_rows * cm->mb_cols, sizeof(*cpi->active_map))); - memset(cpi->active_map, 1, (cm->mb_rows * cm->mb_cols)); - -#if CONFIG_MULTITHREAD - if (width < 640) { - cpi->mt_sync_range = 1; - } else if (width <= 1280) { - cpi->mt_sync_range = 4; - } else if (width <= 2560) { - cpi->mt_sync_range = 8; - } else { - cpi->mt_sync_range = 16; - } -#endif - - vpx_free(cpi->tplist); - CHECK_MEM_ERROR(&cpi->common.error, cpi->tplist, - vpx_malloc(sizeof(TOKENLIST) * cm->mb_rows)); - -#if CONFIG_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity > 0) { - vp8_denoiser_free(&cpi->denoiser); - if (vp8_denoiser_allocate(&cpi->denoiser, width, height, cm->mb_rows, - cm->mb_cols, cpi->oxcf.noise_sensitivity)) { - vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, - "Failed to allocate denoiser"); - } - } -#endif -} - -/* Quant MOD */ -static const int q_trans[] = { - 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19, - 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 35, 37, 39, 41, - 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 64, 67, 70, 73, 76, 79, - 82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, 127, -}; - -int vp8_reverse_trans(int x) { - int i; - - for (i = 0; i < 64; ++i) { - if (q_trans[i] >= x) return i; - } - - return 63; -} -void vp8_new_framerate(VP8_COMP *cpi, double framerate) { - if (framerate < .1) framerate = 30; - - cpi->framerate = framerate; - cpi->output_framerate = framerate; - const double per_frame_bandwidth = - round(cpi->oxcf.target_bandwidth / cpi->output_framerate); - cpi->per_frame_bandwidth = (int)VPXMIN(per_frame_bandwidth, INT_MAX); - cpi->av_per_frame_bandwidth = cpi->per_frame_bandwidth; - const int64_t vbr_min_bits = (int64_t)cpi->av_per_frame_bandwidth * - cpi->oxcf.two_pass_vbrmin_section / 100; - cpi->min_frame_bandwidth = (int)VPXMIN(vbr_min_bits, INT_MAX); - - /* Set Maximum gf/arf interval */ - cpi->max_gf_interval = ((int)(cpi->output_framerate / 2.0) + 2); - - if (cpi->max_gf_interval < 12) cpi->max_gf_interval = 12; - - /* Extended interval for genuinely static scenes */ - cpi->twopass.static_scene_max_gf_interval = cpi->key_frame_frequency >> 1; - - /* Special conditions when altr ref frame enabled in lagged compress mode */ - if (cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames) { - if (cpi->max_gf_interval > cpi->oxcf.lag_in_frames - 1) { - cpi->max_gf_interval = cpi->oxcf.lag_in_frames - 1; - } - - if (cpi->twopass.static_scene_max_gf_interval > - cpi->oxcf.lag_in_frames - 1) { - cpi->twopass.static_scene_max_gf_interval = cpi->oxcf.lag_in_frames - 1; - } - } - - if (cpi->max_gf_interval > cpi->twopass.static_scene_max_gf_interval) { - cpi->max_gf_interval = cpi->twopass.static_scene_max_gf_interval; - } -} - -static void init_config(VP8_COMP *cpi, const VP8_CONFIG *oxcf) { - VP8_COMMON *cm = &cpi->common; - - cpi->oxcf = *oxcf; - - cpi->auto_gold = 1; - cpi->auto_adjust_gold_quantizer = 1; - - cm->version = oxcf->Version; - vp8_setup_version(cm); - - /* Frame rate is not available on the first frame, as it's derived from - * the observed timestamps. The actual value used here doesn't matter - * too much, as it will adapt quickly. - */ - if (oxcf->timebase.num > 0) { - cpi->framerate = - (double)(oxcf->timebase.den) / (double)(oxcf->timebase.num); - } else { - cpi->framerate = 30; - } - - /* If the reciprocal of the timebase seems like a reasonable framerate, - * then use that as a guess, otherwise use 30. - */ - if (cpi->framerate > 180) cpi->framerate = 30; - - cpi->ref_framerate = cpi->framerate; - - cpi->ref_frame_flags = VP8_ALTR_FRAME | VP8_GOLD_FRAME | VP8_LAST_FRAME; - - cm->refresh_golden_frame = 0; - cm->refresh_last_frame = 1; - cm->refresh_entropy_probs = 1; - - /* change includes all joint functionality */ - vp8_change_config(cpi, oxcf); - - /* Initialize active best and worst q and average q values. */ - cpi->active_worst_quality = cpi->oxcf.worst_allowed_q; - cpi->active_best_quality = cpi->oxcf.best_allowed_q; - cpi->avg_frame_qindex = cpi->oxcf.worst_allowed_q; - - /* Initialise the starting buffer levels */ - cpi->buffer_level = cpi->oxcf.starting_buffer_level; - cpi->bits_off_target = cpi->oxcf.starting_buffer_level; - - cpi->rolling_target_bits = cpi->av_per_frame_bandwidth; - cpi->rolling_actual_bits = cpi->av_per_frame_bandwidth; - cpi->long_rolling_target_bits = cpi->av_per_frame_bandwidth; - cpi->long_rolling_actual_bits = cpi->av_per_frame_bandwidth; - - cpi->total_actual_bits = 0; - cpi->total_target_vs_actual = 0; - - /* Temporal scalabilty */ - if (cpi->oxcf.number_of_layers > 1) { - unsigned int i; - double prev_layer_framerate = 0; - - for (i = 0; i < cpi->oxcf.number_of_layers; ++i) { - vp8_init_temporal_layer_context(cpi, oxcf, i, prev_layer_framerate); - prev_layer_framerate = - cpi->output_framerate / cpi->oxcf.rate_decimator[i]; - } - } - -#if VP8_TEMPORAL_ALT_REF - { - int i; - - cpi->fixed_divide[0] = 0; - - for (i = 1; i < 512; ++i) cpi->fixed_divide[i] = 0x80000 / i; - } -#endif -} - -void vp8_update_layer_contexts(VP8_COMP *cpi) { - VP8_CONFIG *oxcf = &cpi->oxcf; - - /* Update snapshots of the layer contexts to reflect new parameters */ - if (oxcf->number_of_layers > 1) { - unsigned int i; - double prev_layer_framerate = 0; - - assert(oxcf->number_of_layers <= VPX_TS_MAX_LAYERS); - for (i = 0; i < oxcf->number_of_layers && i < VPX_TS_MAX_LAYERS; ++i) { - LAYER_CONTEXT *lc = &cpi->layer_context[i]; - - lc->framerate = cpi->ref_framerate / oxcf->rate_decimator[i]; - if (oxcf->target_bitrate[i] > INT_MAX / 1000) - lc->target_bandwidth = INT_MAX; - else - lc->target_bandwidth = oxcf->target_bitrate[i] * 1000; - - lc->starting_buffer_level = rescale( - (int)oxcf->starting_buffer_level_in_ms, lc->target_bandwidth, 1000); - - if (oxcf->optimal_buffer_level == 0) { - lc->optimal_buffer_level = lc->target_bandwidth / 8; - } else { - lc->optimal_buffer_level = rescale( - (int)oxcf->optimal_buffer_level_in_ms, lc->target_bandwidth, 1000); - } - - if (oxcf->maximum_buffer_size == 0) { - lc->maximum_buffer_size = lc->target_bandwidth / 8; - } else { - lc->maximum_buffer_size = rescale((int)oxcf->maximum_buffer_size_in_ms, - lc->target_bandwidth, 1000); - } - - /* Work out the average size of a frame within this layer */ - if (i > 0) { - lc->avg_frame_size_for_layer = - (int)round((oxcf->target_bitrate[i] - oxcf->target_bitrate[i - 1]) * - 1000 / (lc->framerate - prev_layer_framerate)); - } - - prev_layer_framerate = lc->framerate; - } - } -} - -void vp8_change_config(VP8_COMP *cpi, const VP8_CONFIG *oxcf) { - VP8_COMMON *cm = &cpi->common; - int last_w, last_h; - unsigned int prev_number_of_layers; - double raw_target_rate; - - if (!cpi) return; - - if (!oxcf) return; - - if (cm->version != oxcf->Version) { - cm->version = oxcf->Version; - vp8_setup_version(cm); - } - - last_w = cpi->oxcf.Width; - last_h = cpi->oxcf.Height; - prev_number_of_layers = cpi->oxcf.number_of_layers; - - cpi->oxcf = *oxcf; - - switch (cpi->oxcf.Mode) { - case MODE_REALTIME: - cpi->pass = 0; - cpi->compressor_speed = 2; - - if (cpi->oxcf.cpu_used < -16) { - cpi->oxcf.cpu_used = -16; - } - - if (cpi->oxcf.cpu_used > 16) cpi->oxcf.cpu_used = 16; - - break; - - case MODE_GOODQUALITY: - cpi->pass = 0; - cpi->compressor_speed = 1; - - if (cpi->oxcf.cpu_used < -5) { - cpi->oxcf.cpu_used = -5; - } - - if (cpi->oxcf.cpu_used > 5) cpi->oxcf.cpu_used = 5; - - break; - - case MODE_BESTQUALITY: - cpi->pass = 0; - cpi->compressor_speed = 0; - break; - - case MODE_FIRSTPASS: - cpi->pass = 1; - cpi->compressor_speed = 1; - break; - case MODE_SECONDPASS: - cpi->pass = 2; - cpi->compressor_speed = 1; - - if (cpi->oxcf.cpu_used < -5) { - cpi->oxcf.cpu_used = -5; - } - - if (cpi->oxcf.cpu_used > 5) cpi->oxcf.cpu_used = 5; - - break; - case MODE_SECONDPASS_BEST: - cpi->pass = 2; - cpi->compressor_speed = 0; - break; - } - - if (cpi->pass == 0) cpi->auto_worst_q = 1; - - cpi->oxcf.worst_allowed_q = q_trans[oxcf->worst_allowed_q]; - cpi->oxcf.best_allowed_q = q_trans[oxcf->best_allowed_q]; - cpi->oxcf.cq_level = q_trans[cpi->oxcf.cq_level]; - - if (oxcf->fixed_q >= 0) { - if (oxcf->worst_allowed_q < 0) { - cpi->oxcf.fixed_q = q_trans[0]; - } else { - cpi->oxcf.fixed_q = q_trans[oxcf->worst_allowed_q]; - } - - if (oxcf->alt_q < 0) { - cpi->oxcf.alt_q = q_trans[0]; - } else { - cpi->oxcf.alt_q = q_trans[oxcf->alt_q]; - } - - if (oxcf->key_q < 0) { - cpi->oxcf.key_q = q_trans[0]; - } else { - cpi->oxcf.key_q = q_trans[oxcf->key_q]; - } - - if (oxcf->gold_q < 0) { - cpi->oxcf.gold_q = q_trans[0]; - } else { - cpi->oxcf.gold_q = q_trans[oxcf->gold_q]; - } - } - - cpi->ext_refresh_frame_flags_pending = 0; - - cpi->baseline_gf_interval = - cpi->oxcf.alt_freq ? cpi->oxcf.alt_freq : DEFAULT_GF_INTERVAL; - - // GF behavior for 1 pass CBR, used when error_resilience is off. - if (!cpi->oxcf.error_resilient_mode && - cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER && - cpi->oxcf.Mode == MODE_REALTIME) - cpi->baseline_gf_interval = cpi->gf_interval_onepass_cbr; - -#if (CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING) - cpi->oxcf.token_partitions = 3; -#endif - - if (cpi->oxcf.token_partitions >= 0 && cpi->oxcf.token_partitions <= 3) { - cm->multi_token_partition = (TOKEN_PARTITION)cpi->oxcf.token_partitions; - } - - setup_features(cpi); - - if (!cpi->use_roi_static_threshold) { - int i; - for (i = 0; i < MAX_MB_SEGMENTS; ++i) { - cpi->segment_encode_breakout[i] = cpi->oxcf.encode_breakout; - } - } - - /* At the moment the first order values may not be > MAXQ */ - if (cpi->oxcf.fixed_q > MAXQ) cpi->oxcf.fixed_q = MAXQ; - - /* local file playback mode == really big buffer */ - if (cpi->oxcf.end_usage == USAGE_LOCAL_FILE_PLAYBACK) { - cpi->oxcf.starting_buffer_level = 60000; - cpi->oxcf.optimal_buffer_level = 60000; - cpi->oxcf.maximum_buffer_size = 240000; - cpi->oxcf.starting_buffer_level_in_ms = 60000; - cpi->oxcf.optimal_buffer_level_in_ms = 60000; - cpi->oxcf.maximum_buffer_size_in_ms = 240000; - } - - raw_target_rate = ((int64_t)cpi->oxcf.Width * cpi->oxcf.Height * 8 * 3 * - cpi->framerate / 1000.0); - if (cpi->oxcf.target_bandwidth > raw_target_rate) - cpi->oxcf.target_bandwidth = (unsigned int)raw_target_rate; - /* Convert target bandwidth from Kbit/s to Bit/s */ - cpi->oxcf.target_bandwidth *= 1000; - - cpi->oxcf.starting_buffer_level = rescale( - (int)cpi->oxcf.starting_buffer_level, cpi->oxcf.target_bandwidth, 1000); - - /* Set or reset optimal and maximum buffer levels. */ - if (cpi->oxcf.optimal_buffer_level == 0) { - cpi->oxcf.optimal_buffer_level = cpi->oxcf.target_bandwidth / 8; - } else { - cpi->oxcf.optimal_buffer_level = rescale( - (int)cpi->oxcf.optimal_buffer_level, cpi->oxcf.target_bandwidth, 1000); - } - - if (cpi->oxcf.maximum_buffer_size == 0) { - cpi->oxcf.maximum_buffer_size = cpi->oxcf.target_bandwidth / 8; - } else { - cpi->oxcf.maximum_buffer_size = rescale((int)cpi->oxcf.maximum_buffer_size, - cpi->oxcf.target_bandwidth, 1000); - } - // Under a configuration change, where maximum_buffer_size may change, - // keep buffer level clipped to the maximum allowed buffer size. - if (cpi->bits_off_target > cpi->oxcf.maximum_buffer_size) { - cpi->bits_off_target = cpi->oxcf.maximum_buffer_size; - cpi->buffer_level = cpi->bits_off_target; - } - - /* Set up frame rate and related parameters rate control values. */ - vp8_new_framerate(cpi, cpi->framerate); - - /* Set absolute upper and lower quality limits */ - cpi->worst_quality = cpi->oxcf.worst_allowed_q; - cpi->best_quality = cpi->oxcf.best_allowed_q; - - /* active values should only be modified if out of new range */ - if (cpi->active_worst_quality > cpi->oxcf.worst_allowed_q) { - cpi->active_worst_quality = cpi->oxcf.worst_allowed_q; - } - /* less likely */ - else if (cpi->active_worst_quality < cpi->oxcf.best_allowed_q) { - cpi->active_worst_quality = cpi->oxcf.best_allowed_q; - } - if (cpi->active_best_quality < cpi->oxcf.best_allowed_q) { - cpi->active_best_quality = cpi->oxcf.best_allowed_q; - } - /* less likely */ - else if (cpi->active_best_quality > cpi->oxcf.worst_allowed_q) { - cpi->active_best_quality = cpi->oxcf.worst_allowed_q; - } - - cpi->buffered_mode = cpi->oxcf.optimal_buffer_level > 0; - - cpi->cq_target_quality = cpi->oxcf.cq_level; - - /* Only allow dropped frames in buffered mode */ - cpi->drop_frames_allowed = cpi->oxcf.allow_df && cpi->buffered_mode; - - cpi->target_bandwidth = cpi->oxcf.target_bandwidth; - - // Check if the number of temporal layers has changed, and if so reset the - // pattern counter and set/initialize the temporal layer context for the - // new layer configuration. - if (cpi->oxcf.number_of_layers != prev_number_of_layers) { - // If the number of temporal layers are changed we must start at the - // base of the pattern cycle, so set the layer id to 0 and reset - // the temporal pattern counter. - if (cpi->temporal_layer_id > 0) { - cpi->temporal_layer_id = 0; - } - cpi->temporal_pattern_counter = 0; - vp8_reset_temporal_layer_change(cpi, oxcf, prev_number_of_layers); - } - - if (!cpi->initial_width) { - cpi->initial_width = cpi->oxcf.Width; - cpi->initial_height = cpi->oxcf.Height; - } - - cm->Width = cpi->oxcf.Width; - cm->Height = cpi->oxcf.Height; - assert(cm->Width <= cpi->initial_width); - assert(cm->Height <= cpi->initial_height); - - /* TODO(jkoleszar): if an internal spatial resampling is active, - * and we downsize the input image, maybe we should clear the - * internal scale immediately rather than waiting for it to - * correct. - */ - - /* VP8 sharpness level mapping 0-7 (vs 0-10 in general VPx dialogs) */ - if (cpi->oxcf.Sharpness > 7) cpi->oxcf.Sharpness = 7; - - cm->sharpness_level = cpi->oxcf.Sharpness; - - if (cm->horiz_scale != VP8E_NORMAL || cm->vert_scale != VP8E_NORMAL) { - int hr, hs, vr, vs; - - Scale2Ratio(cm->horiz_scale, &hr, &hs); - Scale2Ratio(cm->vert_scale, &vr, &vs); - - /* always go to the next whole number */ - cm->Width = (hs - 1 + cpi->oxcf.Width * hr) / hs; - cm->Height = (vs - 1 + cpi->oxcf.Height * vr) / vs; - } - - if (last_w != cpi->oxcf.Width || last_h != cpi->oxcf.Height) { - cpi->force_next_frame_intra = 1; - } - - if (((cm->Width + 15) & ~15) != cm->yv12_fb[cm->lst_fb_idx].y_width || - ((cm->Height + 15) & ~15) != cm->yv12_fb[cm->lst_fb_idx].y_height || - cm->yv12_fb[cm->lst_fb_idx].y_width == 0) { - dealloc_raw_frame_buffers(cpi); - alloc_raw_frame_buffers(cpi); - vp8_alloc_compressor_data(cpi); - } - - if (cpi->oxcf.fixed_q >= 0) { - cpi->last_q[0] = cpi->oxcf.fixed_q; - cpi->last_q[1] = cpi->oxcf.fixed_q; - } - - cpi->Speed = cpi->oxcf.cpu_used; - - /* force to allowlag to 0 if lag_in_frames is 0; */ - if (cpi->oxcf.lag_in_frames == 0) { - cpi->oxcf.allow_lag = 0; - } - /* Limit on lag buffers as these are not currently dynamically allocated */ - else if (cpi->oxcf.lag_in_frames > MAX_LAG_BUFFERS) { - cpi->oxcf.lag_in_frames = MAX_LAG_BUFFERS; - } - - /* YX Temp */ - cpi->alt_ref_source = NULL; - cpi->is_src_frame_alt_ref = 0; - -#if CONFIG_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity) { - if (!cpi->denoiser.yv12_mc_running_avg.buffer_alloc) { - int width = (cpi->oxcf.Width + 15) & ~15; - int height = (cpi->oxcf.Height + 15) & ~15; - if (vp8_denoiser_allocate(&cpi->denoiser, width, height, cm->mb_rows, - cm->mb_cols, cpi->oxcf.noise_sensitivity)) { - vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, - "Failed to allocate denoiser"); - } - } - } -#endif - -#if 0 - /* Experimental RD Code */ - cpi->frame_distortion = 0; - cpi->last_frame_distortion = 0; -#endif -} - -#ifndef M_LOG2_E -#define M_LOG2_E 0.693147180559945309417 -#endif -#define log2f(x) (log(x) / (float)M_LOG2_E) - -static void cal_mvsadcosts(int *mvsadcost[2]) { - int i = 1; - - mvsadcost[0][0] = 300; - mvsadcost[1][0] = 300; - - do { - double z = 256 * (2 * (log2f(8 * i) + .6)); - mvsadcost[0][i] = (int)z; - mvsadcost[1][i] = (int)z; - mvsadcost[0][-i] = (int)z; - mvsadcost[1][-i] = (int)z; - } while (++i <= mvfp_max); -} - -struct VP8_COMP *vp8_create_compressor(const VP8_CONFIG *oxcf) { - int i; - - VP8_COMP *cpi; - VP8_COMMON *cm; - - cpi = vpx_memalign(32, sizeof(VP8_COMP)); - /* Check that the CPI instance is valid */ - if (!cpi) return 0; - - cm = &cpi->common; - - memset(cpi, 0, sizeof(VP8_COMP)); - - if (setjmp(cm->error.jmp)) { - cpi->common.error.setjmp = 0; - vp8_remove_compressor(&cpi); - return 0; - } - - cpi->common.error.setjmp = 1; - - CHECK_MEM_ERROR( - &cpi->common.error, cpi->mb.ss, - vpx_calloc(sizeof(search_site), (MAX_MVSEARCH_STEPS * 8) + 1)); - - vp8_create_common(&cpi->common); - - init_config(cpi, oxcf); - - memcpy(cpi->base_skip_false_prob, vp8cx_base_skip_false_prob, - sizeof(vp8cx_base_skip_false_prob)); - cpi->common.current_video_frame = 0; - cpi->temporal_pattern_counter = 0; - cpi->temporal_layer_id = -1; - cpi->kf_overspend_bits = 0; - cpi->kf_bitrate_adjustment = 0; - cpi->frames_till_gf_update_due = 0; - cpi->gf_overspend_bits = 0; - cpi->non_gf_bitrate_adjustment = 0; - cpi->prob_last_coded = 128; - cpi->prob_gf_coded = 128; - cpi->prob_intra_coded = 63; - - /* Prime the recent reference frame usage counters. - * Hereafter they will be maintained as a sort of moving average - */ - cpi->recent_ref_frame_usage[INTRA_FRAME] = 1; - cpi->recent_ref_frame_usage[LAST_FRAME] = 1; - cpi->recent_ref_frame_usage[GOLDEN_FRAME] = 1; - cpi->recent_ref_frame_usage[ALTREF_FRAME] = 1; - - /* Set reference frame sign bias for ALTREF frame to 1 (for now) */ - cpi->common.ref_frame_sign_bias[ALTREF_FRAME] = 1; - - cpi->twopass.gf_decay_rate = 0; - cpi->baseline_gf_interval = DEFAULT_GF_INTERVAL; - - cpi->gold_is_last = 0; - cpi->alt_is_last = 0; - cpi->gold_is_alt = 0; - - cpi->active_map_enabled = 0; - - cpi->use_roi_static_threshold = 0; - -#if 0 - /* Experimental code for lagged and one pass */ - /* Initialise one_pass GF frames stats */ - /* Update stats used for GF selection */ - if (cpi->pass == 0) - { - cpi->one_pass_frame_index = 0; - - for (i = 0; i < MAX_LAG_BUFFERS; ++i) - { - cpi->one_pass_frame_stats[i].frames_so_far = 0; - cpi->one_pass_frame_stats[i].frame_intra_error = 0.0; - cpi->one_pass_frame_stats[i].frame_coded_error = 0.0; - cpi->one_pass_frame_stats[i].frame_pcnt_inter = 0.0; - cpi->one_pass_frame_stats[i].frame_pcnt_motion = 0.0; - cpi->one_pass_frame_stats[i].frame_mvr = 0.0; - cpi->one_pass_frame_stats[i].frame_mvr_abs = 0.0; - cpi->one_pass_frame_stats[i].frame_mvc = 0.0; - cpi->one_pass_frame_stats[i].frame_mvc_abs = 0.0; - } - } -#endif - - cpi->mse_source_denoised = 0; - - /* Should we use the cyclic refresh method. - * Currently there is no external control for this. - * Enable it for error_resilient_mode, or for 1 pass CBR mode. - */ - cpi->cyclic_refresh_mode_enabled = - (cpi->oxcf.error_resilient_mode || - (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER && - cpi->oxcf.Mode <= 2)); - cpi->cyclic_refresh_mode_max_mbs_perframe = - (cpi->common.mb_rows * cpi->common.mb_cols) / 7; - if (cpi->oxcf.number_of_layers == 1) { - cpi->cyclic_refresh_mode_max_mbs_perframe = - (cpi->common.mb_rows * cpi->common.mb_cols) / 20; - } else if (cpi->oxcf.number_of_layers == 2) { - cpi->cyclic_refresh_mode_max_mbs_perframe = - (cpi->common.mb_rows * cpi->common.mb_cols) / 10; - } - cpi->cyclic_refresh_mode_index = 0; - cpi->cyclic_refresh_q = 32; - - // GF behavior for 1 pass CBR, used when error_resilience is off. - cpi->gf_update_onepass_cbr = 0; - cpi->gf_noboost_onepass_cbr = 0; - if (!cpi->oxcf.error_resilient_mode && - cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER && cpi->oxcf.Mode <= 2) { - cpi->gf_update_onepass_cbr = 1; - cpi->gf_noboost_onepass_cbr = 1; - cpi->gf_interval_onepass_cbr = - cpi->cyclic_refresh_mode_max_mbs_perframe > 0 - ? (2 * (cpi->common.mb_rows * cpi->common.mb_cols) / - cpi->cyclic_refresh_mode_max_mbs_perframe) - : 10; - cpi->gf_interval_onepass_cbr = - VPXMIN(40, VPXMAX(6, cpi->gf_interval_onepass_cbr)); - cpi->baseline_gf_interval = cpi->gf_interval_onepass_cbr; - } - - if (cpi->cyclic_refresh_mode_enabled) { - CHECK_MEM_ERROR(&cpi->common.error, cpi->cyclic_refresh_map, - vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1)); - } else { - cpi->cyclic_refresh_map = (signed char *)NULL; - } - - CHECK_MEM_ERROR( - &cpi->common.error, cpi->skin_map, - vpx_calloc(cm->mb_rows * cm->mb_cols, sizeof(cpi->skin_map[0]))); - - CHECK_MEM_ERROR(&cpi->common.error, cpi->consec_zero_last, - vpx_calloc(cm->mb_rows * cm->mb_cols, 1)); - CHECK_MEM_ERROR(&cpi->common.error, cpi->consec_zero_last_mvbias, - vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1)); - - /*Initialize the feed-forward activity masking.*/ - cpi->activity_avg = 90 << 12; - - /* Give a sensible default for the first frame. */ - cpi->frames_since_key = 8; - cpi->key_frame_frequency = cpi->oxcf.key_freq; - cpi->this_key_frame_forced = 0; - cpi->next_key_frame_forced = 0; - - cpi->source_alt_ref_pending = 0; - cpi->source_alt_ref_active = 0; - cpi->common.refresh_alt_ref_frame = 0; - - cpi->force_maxqp = 0; - cpi->frames_since_last_drop_overshoot = 0; - cpi->rt_always_update_correction_factor = 0; - cpi->rt_drop_recode_on_overshoot = 1; - - cpi->b_calculate_psnr = CONFIG_INTERNAL_STATS; -#if CONFIG_INTERNAL_STATS - cpi->b_calculate_ssimg = 0; - - cpi->count = 0; - cpi->bytes = 0; - - if (cpi->b_calculate_psnr) { - cpi->total_sq_error = 0.0; - cpi->total_sq_error2 = 0.0; - cpi->total_y = 0.0; - cpi->total_u = 0.0; - cpi->total_v = 0.0; - cpi->total = 0.0; - cpi->totalp_y = 0.0; - cpi->totalp_u = 0.0; - cpi->totalp_v = 0.0; - cpi->totalp = 0.0; - cpi->tot_recode_hits = 0; - cpi->summed_quality = 0; - cpi->summed_weights = 0; - } - -#endif - - cpi->first_time_stamp_ever = 0x7FFFFFFF; - - cpi->frames_till_gf_update_due = 0; - cpi->key_frame_count = 1; - - cpi->ni_av_qi = cpi->oxcf.worst_allowed_q; - cpi->ni_tot_qi = 0; - cpi->ni_frames = 0; - cpi->total_byte_count = 0; - - cpi->drop_frame = 0; - - cpi->rate_correction_factor = 1.0; - cpi->key_frame_rate_correction_factor = 1.0; - cpi->gf_rate_correction_factor = 1.0; - cpi->twopass.est_max_qcorrection_factor = 1.0; - - for (i = 0; i < KEY_FRAME_CONTEXT; ++i) { - cpi->prior_key_frame_distance[i] = (int)cpi->output_framerate; - } - -#ifdef OUTPUT_YUV_SRC - yuv_file = fopen("bd.yuv", "ab"); -#endif -#ifdef OUTPUT_YUV_DENOISED - yuv_denoised_file = fopen("denoised.yuv", "ab"); -#endif -#ifdef OUTPUT_YUV_SKINMAP - yuv_skinmap_file = fopen("skinmap.yuv", "wb"); -#endif - -#if 0 - framepsnr = fopen("framepsnr.stt", "a"); - kf_list = fopen("kf_list.stt", "w"); -#endif - - cpi->output_pkt_list = oxcf->output_pkt_list; - -#if !CONFIG_REALTIME_ONLY - - if (cpi->pass == 1) { - vp8_init_first_pass(cpi); - } else if (cpi->pass == 2) { - size_t packet_sz = sizeof(FIRSTPASS_STATS); - int packets = (int)(oxcf->two_pass_stats_in.sz / packet_sz); - - cpi->twopass.stats_in_start = oxcf->two_pass_stats_in.buf; - cpi->twopass.stats_in = cpi->twopass.stats_in_start; - cpi->twopass.stats_in_end = - (void *)((char *)cpi->twopass.stats_in + (packets - 1) * packet_sz); - vp8_init_second_pass(cpi); - } - -#endif - - if (cpi->compressor_speed == 2) { - cpi->avg_encode_time = 0; - cpi->avg_pick_mode_time = 0; - } - - vp8_set_speed_features(cpi); - - /* Set starting values of RD threshold multipliers (128 = *1) */ - for (i = 0; i < MAX_MODES; ++i) { - cpi->mb.rd_thresh_mult[i] = 128; - } - -#if CONFIG_MULTITHREAD - if (vp8cx_create_encoder_threads(cpi)) { - cpi->common.error.setjmp = 0; - vp8_remove_compressor(&cpi); - return 0; - } -#endif - - cpi->fn_ptr[BLOCK_16X16].sdf = vpx_sad16x16; - cpi->fn_ptr[BLOCK_16X16].vf = vpx_variance16x16; - cpi->fn_ptr[BLOCK_16X16].svf = vpx_sub_pixel_variance16x16; - cpi->fn_ptr[BLOCK_16X16].sdx4df = vpx_sad16x16x4d; - - cpi->fn_ptr[BLOCK_16X8].sdf = vpx_sad16x8; - cpi->fn_ptr[BLOCK_16X8].vf = vpx_variance16x8; - cpi->fn_ptr[BLOCK_16X8].svf = vpx_sub_pixel_variance16x8; - cpi->fn_ptr[BLOCK_16X8].sdx4df = vpx_sad16x8x4d; - - cpi->fn_ptr[BLOCK_8X16].sdf = vpx_sad8x16; - cpi->fn_ptr[BLOCK_8X16].vf = vpx_variance8x16; - cpi->fn_ptr[BLOCK_8X16].svf = vpx_sub_pixel_variance8x16; - cpi->fn_ptr[BLOCK_8X16].sdx4df = vpx_sad8x16x4d; - - cpi->fn_ptr[BLOCK_8X8].sdf = vpx_sad8x8; - cpi->fn_ptr[BLOCK_8X8].vf = vpx_variance8x8; - cpi->fn_ptr[BLOCK_8X8].svf = vpx_sub_pixel_variance8x8; - cpi->fn_ptr[BLOCK_8X8].sdx4df = vpx_sad8x8x4d; - - cpi->fn_ptr[BLOCK_4X4].sdf = vpx_sad4x4; - cpi->fn_ptr[BLOCK_4X4].vf = vpx_variance4x4; - cpi->fn_ptr[BLOCK_4X4].svf = vpx_sub_pixel_variance4x4; - cpi->fn_ptr[BLOCK_4X4].sdx4df = vpx_sad4x4x4d; - -#if VPX_ARCH_X86 || VPX_ARCH_X86_64 - cpi->fn_ptr[BLOCK_16X16].copymem = vp8_copy32xn; - cpi->fn_ptr[BLOCK_16X8].copymem = vp8_copy32xn; - cpi->fn_ptr[BLOCK_8X16].copymem = vp8_copy32xn; - cpi->fn_ptr[BLOCK_8X8].copymem = vp8_copy32xn; - cpi->fn_ptr[BLOCK_4X4].copymem = vp8_copy32xn; -#endif - - cpi->diamond_search_sad = vp8_diamond_search_sad; - cpi->refining_search_sad = vp8_refining_search_sad; - - /* make sure frame 1 is okay */ - cpi->mb.error_bins[0] = cpi->common.MBs; - - /* vp8cx_init_quantizer() is first called here. Add check in - * vp8cx_frame_init_quantizer() so that vp8cx_init_quantizer is only - * called later when needed. This will avoid unnecessary calls of - * vp8cx_init_quantizer() for every frame. - */ - vp8cx_init_quantizer(cpi); - - vp8_loop_filter_init(cm); - -#if CONFIG_MULTI_RES_ENCODING - - /* Calculate # of MBs in a row in lower-resolution level image. */ - if (cpi->oxcf.mr_encoder_id > 0) vp8_cal_low_res_mb_cols(cpi); - -#endif - - /* setup RD costs to MACROBLOCK struct */ - - cpi->mb.mvcost[0] = &cpi->rd_costs.mvcosts[0][mv_max + 1]; - cpi->mb.mvcost[1] = &cpi->rd_costs.mvcosts[1][mv_max + 1]; - cpi->mb.mvsadcost[0] = &cpi->rd_costs.mvsadcosts[0][mvfp_max + 1]; - cpi->mb.mvsadcost[1] = &cpi->rd_costs.mvsadcosts[1][mvfp_max + 1]; - - cal_mvsadcosts(cpi->mb.mvsadcost); - - cpi->mb.mbmode_cost = cpi->rd_costs.mbmode_cost; - cpi->mb.intra_uv_mode_cost = cpi->rd_costs.intra_uv_mode_cost; - cpi->mb.bmode_costs = cpi->rd_costs.bmode_costs; - cpi->mb.inter_bmode_costs = cpi->rd_costs.inter_bmode_costs; - cpi->mb.token_costs = cpi->rd_costs.token_costs; - - /* setup block ptrs & offsets */ - vp8_setup_block_ptrs(&cpi->mb); - vp8_setup_block_dptrs(&cpi->mb.e_mbd); - - cpi->common.error.setjmp = 0; - - return cpi; -} - -void vp8_remove_compressor(VP8_COMP **comp) { - VP8_COMP *cpi = *comp; - - if (!cpi) return; - - if (cpi && (cpi->common.current_video_frame > 0)) { -#if !CONFIG_REALTIME_ONLY - - if (cpi->pass == 2) { - vp8_end_second_pass(cpi); - } - -#endif - -#if CONFIG_INTERNAL_STATS - - if (cpi->pass != 1) { - FILE *f = fopen("opsnr.stt", "a"); - double time_encoded = - (cpi->last_end_time_stamp_seen - cpi->first_time_stamp_ever) / - 10000000.000; - - if (cpi->b_calculate_psnr) { - if (cpi->oxcf.number_of_layers > 1) { - int i; - - fprintf(f, - "Layer\tBitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\t" - "GLPsnrP\tVPXSSIM\n"); - for (i = 0; i < (int)cpi->oxcf.number_of_layers; ++i) { - double dr = - (double)cpi->bytes_in_layer[i] * 8.0 / 1000.0 / time_encoded; - double samples = 3.0 / 2 * cpi->frames_in_layer[i] * - cpi->common.Width * cpi->common.Height; - double total_psnr = - vpx_sse_to_psnr(samples, 255.0, cpi->total_error2[i]); - double total_psnr2 = - vpx_sse_to_psnr(samples, 255.0, cpi->total_error2_p[i]); - double total_ssim = - 100 * pow(cpi->sum_ssim[i] / cpi->sum_weights[i], 8.0); - - fprintf(f, - "%5d\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t" - "%7.3f\t%7.3f\n", - i, dr, cpi->sum_psnr[i] / cpi->frames_in_layer[i], - total_psnr, cpi->sum_psnr_p[i] / cpi->frames_in_layer[i], - total_psnr2, total_ssim); - } - } else { - double dr = (double)cpi->bytes * 8.0 / 1000.0 / time_encoded; - double samples = - 3.0 / 2 * cpi->count * cpi->common.Width * cpi->common.Height; - double total_psnr = - vpx_sse_to_psnr(samples, 255.0, cpi->total_sq_error); - double total_psnr2 = - vpx_sse_to_psnr(samples, 255.0, cpi->total_sq_error2); - double total_ssim = - 100 * pow(cpi->summed_quality / cpi->summed_weights, 8.0); - - fprintf(f, - "Bitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\t" - "GLPsnrP\tVPXSSIM\n"); - fprintf(f, - "%7.3f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t" - "%7.3f\n", - dr, cpi->total / cpi->count, total_psnr, - cpi->totalp / cpi->count, total_psnr2, total_ssim); - } - } - fclose(f); -#if 0 - f = fopen("qskip.stt", "a"); - fprintf(f, "minq:%d -maxq:%d skiptrue:skipfalse = %d:%d\n", cpi->oxcf.best_allowed_q, cpi->oxcf.worst_allowed_q, skiptruecount, skipfalsecount); - fclose(f); -#endif - } - -#endif - -#ifdef SPEEDSTATS - - if (cpi->compressor_speed == 2) { - int i; - FILE *f = fopen("cxspeed.stt", "a"); - cnt_pm /= cpi->common.MBs; - - for (i = 0; i < 16; ++i) fprintf(f, "%5d", frames_at_speed[i]); - - fprintf(f, "\n"); - fclose(f); - } - -#endif - -#ifdef MODE_STATS - { - extern int count_mb_seg[4]; - FILE *f = fopen("modes.stt", "a"); - double dr = cpi->framerate * (double)bytes * (double)8 / (double)count / - (double)1000; - fprintf(f, "intra_mode in Intra Frames:\n"); - fprintf(f, "Y: %8d, %8d, %8d, %8d, %8d\n", y_modes[0], y_modes[1], - y_modes[2], y_modes[3], y_modes[4]); - fprintf(f, "UV:%8d, %8d, %8d, %8d\n", uv_modes[0], uv_modes[1], - uv_modes[2], uv_modes[3]); - fprintf(f, "B: "); - { - int i; - - for (i = 0; i < 10; ++i) fprintf(f, "%8d, ", b_modes[i]); - - fprintf(f, "\n"); - } - - fprintf(f, "Modes in Inter Frames:\n"); - fprintf(f, "Y: %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d\n", - inter_y_modes[0], inter_y_modes[1], inter_y_modes[2], - inter_y_modes[3], inter_y_modes[4], inter_y_modes[5], - inter_y_modes[6], inter_y_modes[7], inter_y_modes[8], - inter_y_modes[9]); - fprintf(f, "UV:%8d, %8d, %8d, %8d\n", inter_uv_modes[0], - inter_uv_modes[1], inter_uv_modes[2], inter_uv_modes[3]); - fprintf(f, "B: "); - { - int i; - - for (i = 0; i < 15; ++i) fprintf(f, "%8d, ", inter_b_modes[i]); - - fprintf(f, "\n"); - } - fprintf(f, "P:%8d, %8d, %8d, %8d\n", count_mb_seg[0], count_mb_seg[1], - count_mb_seg[2], count_mb_seg[3]); - fprintf(f, "PB:%8d, %8d, %8d, %8d\n", inter_b_modes[LEFT4X4], - inter_b_modes[ABOVE4X4], inter_b_modes[ZERO4X4], - inter_b_modes[NEW4X4]); - - fclose(f); - } -#endif - -#if defined(SECTIONBITS_OUTPUT) - - if (0) { - int i; - FILE *f = fopen("tokenbits.stt", "a"); - - for (i = 0; i < 28; ++i) fprintf(f, "%8d", (int)(Sectionbits[i] / 256)); - - fprintf(f, "\n"); - fclose(f); - } - -#endif - -#if 0 - { - printf("\n_pick_loop_filter_level:%d\n", cpi->time_pick_lpf / 1000); - printf("\n_frames receive_data encod_mb_row compress_frame Total\n"); - printf("%6d %10ld %10ld %10ld %10ld\n", cpi->common.current_video_frame, cpi->time_receive_data / 1000, cpi->time_encode_mb_row / 1000, cpi->time_compress_data / 1000, (cpi->time_receive_data + cpi->time_compress_data) / 1000); - } -#endif - } - -#if CONFIG_MULTITHREAD - vp8cx_remove_encoder_threads(cpi); -#endif - -#if CONFIG_TEMPORAL_DENOISING - vp8_denoiser_free(&cpi->denoiser); -#endif - dealloc_compressor_data(cpi); - vpx_free(cpi->mb.ss); - vpx_free(cpi->tok); - vpx_free(cpi->skin_map); - vpx_free(cpi->cyclic_refresh_map); - vpx_free(cpi->consec_zero_last); - vpx_free(cpi->consec_zero_last_mvbias); - - vp8_remove_common(&cpi->common); - vpx_free(cpi); - *comp = 0; - -#ifdef OUTPUT_YUV_SRC - fclose(yuv_file); -#endif -#ifdef OUTPUT_YUV_DENOISED - fclose(yuv_denoised_file); -#endif -#ifdef OUTPUT_YUV_SKINMAP - fclose(yuv_skinmap_file); -#endif - -#if 0 - - if (keyfile) - fclose(keyfile); - - if (framepsnr) - fclose(framepsnr); - - if (kf_list) - fclose(kf_list); - -#endif -} - -static uint64_t calc_plane_error(unsigned char *orig, int orig_stride, - unsigned char *recon, int recon_stride, - unsigned int cols, unsigned int rows) { - unsigned int row, col; - uint64_t total_sse = 0; - int diff; - - for (row = 0; row + 16 <= rows; row += 16) { - for (col = 0; col + 16 <= cols; col += 16) { - unsigned int sse; - - vpx_mse16x16(orig + col, orig_stride, recon + col, recon_stride, &sse); - total_sse += sse; - } - - /* Handle odd-sized width */ - if (col < cols) { - unsigned int border_row, border_col; - unsigned char *border_orig = orig; - unsigned char *border_recon = recon; - - for (border_row = 0; border_row < 16; ++border_row) { - for (border_col = col; border_col < cols; ++border_col) { - diff = border_orig[border_col] - border_recon[border_col]; - total_sse += diff * diff; - } - - border_orig += orig_stride; - border_recon += recon_stride; - } - } - - orig += orig_stride * 16; - recon += recon_stride * 16; - } - - /* Handle odd-sized height */ - for (; row < rows; ++row) { - for (col = 0; col < cols; ++col) { - diff = orig[col] - recon[col]; - total_sse += diff * diff; - } - - orig += orig_stride; - recon += recon_stride; - } - - vpx_clear_system_state(); - return total_sse; -} - -static void generate_psnr_packet(VP8_COMP *cpi) { - YV12_BUFFER_CONFIG *orig = cpi->Source; - YV12_BUFFER_CONFIG *recon = cpi->common.frame_to_show; - struct vpx_codec_cx_pkt pkt; - uint64_t sse; - int i; - unsigned int width = cpi->common.Width; - unsigned int height = cpi->common.Height; - - pkt.kind = VPX_CODEC_PSNR_PKT; - sse = calc_plane_error(orig->y_buffer, orig->y_stride, recon->y_buffer, - recon->y_stride, width, height); - pkt.data.psnr.sse[0] = sse; - pkt.data.psnr.sse[1] = sse; - pkt.data.psnr.samples[0] = width * height; - pkt.data.psnr.samples[1] = width * height; - - width = (width + 1) / 2; - height = (height + 1) / 2; - - sse = calc_plane_error(orig->u_buffer, orig->uv_stride, recon->u_buffer, - recon->uv_stride, width, height); - pkt.data.psnr.sse[0] += sse; - pkt.data.psnr.sse[2] = sse; - pkt.data.psnr.samples[0] += width * height; - pkt.data.psnr.samples[2] = width * height; - - sse = calc_plane_error(orig->v_buffer, orig->uv_stride, recon->v_buffer, - recon->uv_stride, width, height); - pkt.data.psnr.sse[0] += sse; - pkt.data.psnr.sse[3] = sse; - pkt.data.psnr.samples[0] += width * height; - pkt.data.psnr.samples[3] = width * height; - - for (i = 0; i < 4; ++i) { - pkt.data.psnr.psnr[i] = vpx_sse_to_psnr(pkt.data.psnr.samples[i], 255.0, - (double)(pkt.data.psnr.sse[i])); - } - - vpx_codec_pkt_list_add(cpi->output_pkt_list, &pkt); -} - -int vp8_use_as_reference(VP8_COMP *cpi, int ref_frame_flags) { - if (ref_frame_flags > 7) return -1; - - cpi->ref_frame_flags = ref_frame_flags; - return 0; -} -int vp8_update_reference(VP8_COMP *cpi, int ref_frame_flags) { - if (ref_frame_flags > 7) return -1; - - cpi->common.refresh_golden_frame = 0; - cpi->common.refresh_alt_ref_frame = 0; - cpi->common.refresh_last_frame = 0; - - if (ref_frame_flags & VP8_LAST_FRAME) cpi->common.refresh_last_frame = 1; - - if (ref_frame_flags & VP8_GOLD_FRAME) cpi->common.refresh_golden_frame = 1; - - if (ref_frame_flags & VP8_ALTR_FRAME) cpi->common.refresh_alt_ref_frame = 1; - - cpi->ext_refresh_frame_flags_pending = 1; - return 0; -} - -int vp8_get_reference(VP8_COMP *cpi, enum vpx_ref_frame_type ref_frame_flag, - YV12_BUFFER_CONFIG *sd) { - VP8_COMMON *cm = &cpi->common; - int ref_fb_idx; - - if (ref_frame_flag == VP8_LAST_FRAME) { - ref_fb_idx = cm->lst_fb_idx; - } else if (ref_frame_flag == VP8_GOLD_FRAME) { - ref_fb_idx = cm->gld_fb_idx; - } else if (ref_frame_flag == VP8_ALTR_FRAME) { - ref_fb_idx = cm->alt_fb_idx; - } else { - return -1; - } - - vp8_yv12_copy_frame(&cm->yv12_fb[ref_fb_idx], sd); - - return 0; -} -int vp8_set_reference(VP8_COMP *cpi, enum vpx_ref_frame_type ref_frame_flag, - YV12_BUFFER_CONFIG *sd) { - VP8_COMMON *cm = &cpi->common; - - int ref_fb_idx; - - if (ref_frame_flag == VP8_LAST_FRAME) { - ref_fb_idx = cm->lst_fb_idx; - } else if (ref_frame_flag == VP8_GOLD_FRAME) { - ref_fb_idx = cm->gld_fb_idx; - } else if (ref_frame_flag == VP8_ALTR_FRAME) { - ref_fb_idx = cm->alt_fb_idx; - } else { - return -1; - } - - vp8_yv12_copy_frame(sd, &cm->yv12_fb[ref_fb_idx]); - - return 0; -} -int vp8_update_entropy(VP8_COMP *cpi, int update) { - VP8_COMMON *cm = &cpi->common; - cm->refresh_entropy_probs = update; - - return 0; -} - -static void scale_and_extend_source(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) { - VP8_COMMON *cm = &cpi->common; - - /* are we resizing the image */ - if (cm->horiz_scale != 0 || cm->vert_scale != 0) { -#if CONFIG_SPATIAL_RESAMPLING - int hr, hs, vr, vs; - int tmp_height; - - if (cm->vert_scale == 3) { - tmp_height = 9; - } else { - tmp_height = 11; - } - - Scale2Ratio(cm->horiz_scale, &hr, &hs); - Scale2Ratio(cm->vert_scale, &vr, &vs); - - vpx_scale_frame(sd, &cpi->scaled_source, cm->temp_scale_frame.y_buffer, - tmp_height, hs, hr, vs, vr, 0); - - vp8_yv12_extend_frame_borders(&cpi->scaled_source); - cpi->Source = &cpi->scaled_source; -#endif - } else { - cpi->Source = sd; - } -} - -static int resize_key_frame(VP8_COMP *cpi) { -#if CONFIG_SPATIAL_RESAMPLING - VP8_COMMON *cm = &cpi->common; - - /* Do we need to apply resampling for one pass cbr. - * In one pass this is more limited than in two pass cbr. - * The test and any change is only made once per key frame sequence. - */ - if (cpi->oxcf.allow_spatial_resampling && - (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)) { - int hr, hs, vr, vs; - int new_width, new_height; - - /* If we are below the resample DOWN watermark then scale down a - * notch. - */ - if (cpi->buffer_level < (cpi->oxcf.resample_down_water_mark * - cpi->oxcf.optimal_buffer_level / 100)) { - cm->horiz_scale = - (cm->horiz_scale < VP8E_ONETWO) ? cm->horiz_scale + 1 : VP8E_ONETWO; - cm->vert_scale = - (cm->vert_scale < VP8E_ONETWO) ? cm->vert_scale + 1 : VP8E_ONETWO; - } - /* Should we now start scaling back up */ - else if (cpi->buffer_level > (cpi->oxcf.resample_up_water_mark * - cpi->oxcf.optimal_buffer_level / 100)) { - cm->horiz_scale = - (cm->horiz_scale > VP8E_NORMAL) ? cm->horiz_scale - 1 : VP8E_NORMAL; - cm->vert_scale = - (cm->vert_scale > VP8E_NORMAL) ? cm->vert_scale - 1 : VP8E_NORMAL; - } - - /* Get the new height and width */ - Scale2Ratio(cm->horiz_scale, &hr, &hs); - Scale2Ratio(cm->vert_scale, &vr, &vs); - new_width = ((hs - 1) + (cpi->oxcf.Width * hr)) / hs; - new_height = ((vs - 1) + (cpi->oxcf.Height * vr)) / vs; - - /* If the image size has changed we need to reallocate the buffers - * and resample the source image - */ - if ((cm->Width != new_width) || (cm->Height != new_height)) { - cm->Width = new_width; - cm->Height = new_height; - vp8_alloc_compressor_data(cpi); - scale_and_extend_source(cpi->un_scaled_source, cpi); - return 1; - } - } - -#endif - return 0; -} - -static void update_alt_ref_frame_stats(VP8_COMP *cpi) { - VP8_COMMON *cm = &cpi->common; - - /* Select an interval before next GF or altref */ - if (!cpi->auto_gold) cpi->frames_till_gf_update_due = DEFAULT_GF_INTERVAL; - - if ((cpi->pass != 2) && cpi->frames_till_gf_update_due) { - cpi->current_gf_interval = cpi->frames_till_gf_update_due; - - /* Set the bits per frame that we should try and recover in - * subsequent inter frames to account for the extra GF spend... - * note that his does not apply for GF updates that occur - * coincident with a key frame as the extra cost of key frames is - * dealt with elsewhere. - */ - cpi->gf_overspend_bits += cpi->projected_frame_size; - cpi->non_gf_bitrate_adjustment = - cpi->gf_overspend_bits / cpi->frames_till_gf_update_due; - } - - /* Update data structure that monitors level of reference to last GF */ - memset(cpi->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols)); - cpi->gf_active_count = cm->mb_rows * cm->mb_cols; - - /* this frame refreshes means next frames don't unless specified by user */ - cpi->frames_since_golden = 0; - - /* Clear the alternate reference update pending flag. */ - cpi->source_alt_ref_pending = 0; - - /* Set the alternate reference frame active flag */ - cpi->source_alt_ref_active = 1; -} -static void update_golden_frame_stats(VP8_COMP *cpi) { - VP8_COMMON *cm = &cpi->common; - - /* Update the Golden frame usage counts. */ - if (cm->refresh_golden_frame) { - /* Select an interval before next GF */ - if (!cpi->auto_gold) cpi->frames_till_gf_update_due = DEFAULT_GF_INTERVAL; - - if ((cpi->pass != 2) && (cpi->frames_till_gf_update_due > 0)) { - cpi->current_gf_interval = cpi->frames_till_gf_update_due; - - /* Set the bits per frame that we should try and recover in - * subsequent inter frames to account for the extra GF spend... - * note that his does not apply for GF updates that occur - * coincident with a key frame as the extra cost of key frames - * is dealt with elsewhere. - */ - if ((cm->frame_type != KEY_FRAME) && !cpi->source_alt_ref_active) { - /* Calcluate GF bits to be recovered - * Projected size - av frame bits available for inter - * frames for clip as a whole - */ - cpi->gf_overspend_bits += - (cpi->projected_frame_size - cpi->inter_frame_target); - } - - cpi->non_gf_bitrate_adjustment = - cpi->gf_overspend_bits / cpi->frames_till_gf_update_due; - } - - /* Update data structure that monitors level of reference to last GF */ - memset(cpi->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols)); - cpi->gf_active_count = cm->mb_rows * cm->mb_cols; - - /* this frame refreshes means next frames don't unless specified by - * user - */ - cm->refresh_golden_frame = 0; - cpi->frames_since_golden = 0; - - cpi->recent_ref_frame_usage[INTRA_FRAME] = 1; - cpi->recent_ref_frame_usage[LAST_FRAME] = 1; - cpi->recent_ref_frame_usage[GOLDEN_FRAME] = 1; - cpi->recent_ref_frame_usage[ALTREF_FRAME] = 1; - - /* ******** Fixed Q test code only ************ */ - /* If we are going to use the ALT reference for the next group of - * frames set a flag to say so. - */ - if (cpi->oxcf.fixed_q >= 0 && cpi->oxcf.play_alternate && - !cpi->common.refresh_alt_ref_frame) { - cpi->source_alt_ref_pending = 1; - cpi->frames_till_gf_update_due = cpi->baseline_gf_interval; - } - - if (!cpi->source_alt_ref_pending) cpi->source_alt_ref_active = 0; - - /* Decrement count down till next gf */ - if (cpi->frames_till_gf_update_due > 0) cpi->frames_till_gf_update_due--; - - } else if (!cpi->common.refresh_alt_ref_frame) { - /* Decrement count down till next gf */ - if (cpi->frames_till_gf_update_due > 0) cpi->frames_till_gf_update_due--; - - if (cpi->frames_till_alt_ref_frame) cpi->frames_till_alt_ref_frame--; - - cpi->frames_since_golden++; - - if (cpi->frames_since_golden > 1) { - cpi->recent_ref_frame_usage[INTRA_FRAME] += - cpi->mb.count_mb_ref_frame_usage[INTRA_FRAME]; - cpi->recent_ref_frame_usage[LAST_FRAME] += - cpi->mb.count_mb_ref_frame_usage[LAST_FRAME]; - cpi->recent_ref_frame_usage[GOLDEN_FRAME] += - cpi->mb.count_mb_ref_frame_usage[GOLDEN_FRAME]; - cpi->recent_ref_frame_usage[ALTREF_FRAME] += - cpi->mb.count_mb_ref_frame_usage[ALTREF_FRAME]; - } - } -} - -/* This function updates the reference frame probability estimates that - * will be used during mode selection - */ -static void update_rd_ref_frame_probs(VP8_COMP *cpi) { - VP8_COMMON *cm = &cpi->common; - - const int *const rfct = cpi->mb.count_mb_ref_frame_usage; - const int rf_intra = rfct[INTRA_FRAME]; - const int rf_inter = - rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]; - - if (cm->frame_type == KEY_FRAME) { - cpi->prob_intra_coded = 255; - cpi->prob_last_coded = 128; - cpi->prob_gf_coded = 128; - } else if (!(rf_intra + rf_inter)) { - cpi->prob_intra_coded = 63; - cpi->prob_last_coded = 128; - cpi->prob_gf_coded = 128; - } - - /* update reference frame costs since we can do better than what we got - * last frame. - */ - if (cpi->oxcf.number_of_layers == 1) { - if (cpi->common.refresh_alt_ref_frame) { - cpi->prob_intra_coded += 40; - if (cpi->prob_intra_coded > 255) cpi->prob_intra_coded = 255; - cpi->prob_last_coded = 200; - cpi->prob_gf_coded = 1; - } else if (cpi->frames_since_golden == 0) { - cpi->prob_last_coded = 214; - } else if (cpi->frames_since_golden == 1) { - cpi->prob_last_coded = 192; - cpi->prob_gf_coded = 220; - } else if (cpi->source_alt_ref_active) { - cpi->prob_gf_coded -= 20; - - if (cpi->prob_gf_coded < 10) cpi->prob_gf_coded = 10; - } - if (!cpi->source_alt_ref_active) cpi->prob_gf_coded = 255; - } -} - -#if !CONFIG_REALTIME_ONLY -/* 1 = key, 0 = inter */ -static int decide_key_frame(VP8_COMP *cpi) { - VP8_COMMON *cm = &cpi->common; - - int code_key_frame = 0; - - cpi->kf_boost = 0; - - if (cpi->Speed > 11) return 0; - - /* Clear down mmx registers */ - vpx_clear_system_state(); - - if ((cpi->compressor_speed == 2) && (cpi->Speed >= 5) && (cpi->sf.RD == 0)) { - double change = 1.0 * - abs((int)(cpi->mb.intra_error - cpi->last_intra_error)) / - (1 + cpi->last_intra_error); - double change2 = - 1.0 * - abs((int)(cpi->mb.prediction_error - cpi->last_prediction_error)) / - (1 + cpi->last_prediction_error); - double minerror = cm->MBs * 256; - - cpi->last_intra_error = cpi->mb.intra_error; - cpi->last_prediction_error = cpi->mb.prediction_error; - - if (10 * cpi->mb.intra_error / (1 + cpi->mb.prediction_error) < 15 && - cpi->mb.prediction_error > minerror && - (change > .25 || change2 > .25)) { - /*(change > 1.4 || change < .75)&& cpi->this_frame_percent_intra > - * cpi->last_frame_percent_intra + 3*/ - return 1; - } - - return 0; - } - - /* If the following are true we might as well code a key frame */ - if (((cpi->this_frame_percent_intra == 100) && - (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra + 2))) || - ((cpi->this_frame_percent_intra > 95) && - (cpi->this_frame_percent_intra >= - (cpi->last_frame_percent_intra + 5)))) { - code_key_frame = 1; - } - /* in addition if the following are true and this is not a golden frame - * then code a key frame Note that on golden frames there often seems - * to be a pop in intra usage anyway hence this restriction is - * designed to prevent spurious key frames. The Intra pop needs to be - * investigated. - */ - else if (((cpi->this_frame_percent_intra > 60) && - (cpi->this_frame_percent_intra > - (cpi->last_frame_percent_intra * 2))) || - ((cpi->this_frame_percent_intra > 75) && - (cpi->this_frame_percent_intra > - (cpi->last_frame_percent_intra * 3 / 2))) || - ((cpi->this_frame_percent_intra > 90) && - (cpi->this_frame_percent_intra > - (cpi->last_frame_percent_intra + 10)))) { - if (!cm->refresh_golden_frame) code_key_frame = 1; - } - - return code_key_frame; -} - -static void Pass1Encode(VP8_COMP *cpi) { - vp8_set_quantizer(cpi, 26); - vp8_first_pass(cpi); -} -#endif - -#if 0 -void write_cx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame) -{ - - /* write the frame */ - FILE *yframe; - int i; - char filename[255]; - - sprintf(filename, "cx\\y%04d.raw", this_frame); - yframe = fopen(filename, "wb"); - - for (i = 0; i < frame->y_height; ++i) - fwrite(frame->y_buffer + i * frame->y_stride, frame->y_width, 1, yframe); - - fclose(yframe); - sprintf(filename, "cx\\u%04d.raw", this_frame); - yframe = fopen(filename, "wb"); - - for (i = 0; i < frame->uv_height; ++i) - fwrite(frame->u_buffer + i * frame->uv_stride, frame->uv_width, 1, yframe); - - fclose(yframe); - sprintf(filename, "cx\\v%04d.raw", this_frame); - yframe = fopen(filename, "wb"); - - for (i = 0; i < frame->uv_height; ++i) - fwrite(frame->v_buffer + i * frame->uv_stride, frame->uv_width, 1, yframe); - - fclose(yframe); -} -#endif - -#if !CONFIG_REALTIME_ONLY -/* Function to test for conditions that indeicate we should loop - * back and recode a frame. - */ -static int recode_loop_test(VP8_COMP *cpi, int high_limit, int low_limit, int q, - int maxq, int minq) { - int force_recode = 0; - VP8_COMMON *cm = &cpi->common; - - /* Is frame recode allowed at all - * Yes if either recode mode 1 is selected or mode two is selcted - * and the frame is a key frame. golden frame or alt_ref_frame - */ - if ((cpi->sf.recode_loop == 1) || - ((cpi->sf.recode_loop == 2) && - ((cm->frame_type == KEY_FRAME) || cm->refresh_golden_frame || - cm->refresh_alt_ref_frame))) { - /* General over and under shoot tests */ - if (((cpi->projected_frame_size > high_limit) && (q < maxq)) || - ((cpi->projected_frame_size < low_limit) && (q > minq))) { - force_recode = 1; - } - /* Special Constrained quality tests */ - else if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) { - /* Undershoot and below auto cq level */ - if ((q > cpi->cq_target_quality) && - (cpi->projected_frame_size < ((cpi->this_frame_target * 7) >> 3))) { - force_recode = 1; - } - /* Severe undershoot and between auto and user cq level */ - else if ((q > cpi->oxcf.cq_level) && - (cpi->projected_frame_size < cpi->min_frame_bandwidth) && - (cpi->active_best_quality > cpi->oxcf.cq_level)) { - force_recode = 1; - cpi->active_best_quality = cpi->oxcf.cq_level; - } - } - } - - return force_recode; -} -#endif // !CONFIG_REALTIME_ONLY - -static void update_reference_frames(VP8_COMP *cpi) { - VP8_COMMON *cm = &cpi->common; - YV12_BUFFER_CONFIG *yv12_fb = cm->yv12_fb; - - /* At this point the new frame has been encoded. - * If any buffer copy / swapping is signaled it should be done here. - */ - - if (cm->frame_type == KEY_FRAME) { - yv12_fb[cm->new_fb_idx].flags |= VP8_GOLD_FRAME | VP8_ALTR_FRAME; - - yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FRAME; - yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALTR_FRAME; - - cm->alt_fb_idx = cm->gld_fb_idx = cm->new_fb_idx; - - cpi->current_ref_frames[GOLDEN_FRAME] = cm->current_video_frame; - cpi->current_ref_frames[ALTREF_FRAME] = cm->current_video_frame; - } else { - if (cm->refresh_alt_ref_frame) { - assert(!cm->copy_buffer_to_arf); - - cm->yv12_fb[cm->new_fb_idx].flags |= VP8_ALTR_FRAME; - cm->yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALTR_FRAME; - cm->alt_fb_idx = cm->new_fb_idx; - - cpi->current_ref_frames[ALTREF_FRAME] = cm->current_video_frame; - } else if (cm->copy_buffer_to_arf) { - assert(!(cm->copy_buffer_to_arf & ~0x3)); - - if (cm->copy_buffer_to_arf == 1) { - if (cm->alt_fb_idx != cm->lst_fb_idx) { - yv12_fb[cm->lst_fb_idx].flags |= VP8_ALTR_FRAME; - yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALTR_FRAME; - cm->alt_fb_idx = cm->lst_fb_idx; - - cpi->current_ref_frames[ALTREF_FRAME] = - cpi->current_ref_frames[LAST_FRAME]; - } - } else { - if (cm->alt_fb_idx != cm->gld_fb_idx) { - yv12_fb[cm->gld_fb_idx].flags |= VP8_ALTR_FRAME; - yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALTR_FRAME; - cm->alt_fb_idx = cm->gld_fb_idx; - - cpi->current_ref_frames[ALTREF_FRAME] = - cpi->current_ref_frames[GOLDEN_FRAME]; - } - } - } - - if (cm->refresh_golden_frame) { - assert(!cm->copy_buffer_to_gf); - - cm->yv12_fb[cm->new_fb_idx].flags |= VP8_GOLD_FRAME; - cm->yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FRAME; - cm->gld_fb_idx = cm->new_fb_idx; - - cpi->current_ref_frames[GOLDEN_FRAME] = cm->current_video_frame; - } else if (cm->copy_buffer_to_gf) { - assert(!(cm->copy_buffer_to_arf & ~0x3)); - - if (cm->copy_buffer_to_gf == 1) { - if (cm->gld_fb_idx != cm->lst_fb_idx) { - yv12_fb[cm->lst_fb_idx].flags |= VP8_GOLD_FRAME; - yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FRAME; - cm->gld_fb_idx = cm->lst_fb_idx; - - cpi->current_ref_frames[GOLDEN_FRAME] = - cpi->current_ref_frames[LAST_FRAME]; - } - } else { - if (cm->alt_fb_idx != cm->gld_fb_idx) { - yv12_fb[cm->alt_fb_idx].flags |= VP8_GOLD_FRAME; - yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FRAME; - cm->gld_fb_idx = cm->alt_fb_idx; - - cpi->current_ref_frames[GOLDEN_FRAME] = - cpi->current_ref_frames[ALTREF_FRAME]; - } - } - } - } - - if (cm->refresh_last_frame) { - cm->yv12_fb[cm->new_fb_idx].flags |= VP8_LAST_FRAME; - cm->yv12_fb[cm->lst_fb_idx].flags &= ~VP8_LAST_FRAME; - cm->lst_fb_idx = cm->new_fb_idx; - - cpi->current_ref_frames[LAST_FRAME] = cm->current_video_frame; - } - -#if CONFIG_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity) { - /* we shouldn't have to keep multiple copies as we know in advance which - * buffer we should start - for now to get something up and running - * I've chosen to copy the buffers - */ - if (cm->frame_type == KEY_FRAME) { - int i; - for (i = LAST_FRAME; i < MAX_REF_FRAMES; ++i) - vp8_yv12_copy_frame(cpi->Source, &cpi->denoiser.yv12_running_avg[i]); - } else { - vp8_yv12_extend_frame_borders( - &cpi->denoiser.yv12_running_avg[INTRA_FRAME]); - - if (cm->refresh_alt_ref_frame || cm->copy_buffer_to_arf) { - vp8_yv12_copy_frame(&cpi->denoiser.yv12_running_avg[INTRA_FRAME], - &cpi->denoiser.yv12_running_avg[ALTREF_FRAME]); - } - if (cm->refresh_golden_frame || cm->copy_buffer_to_gf) { - vp8_yv12_copy_frame(&cpi->denoiser.yv12_running_avg[INTRA_FRAME], - &cpi->denoiser.yv12_running_avg[GOLDEN_FRAME]); - } - if (cm->refresh_last_frame) { - vp8_yv12_copy_frame(&cpi->denoiser.yv12_running_avg[INTRA_FRAME], - &cpi->denoiser.yv12_running_avg[LAST_FRAME]); - } - } - if (cpi->oxcf.noise_sensitivity == 4) - vp8_yv12_copy_frame(cpi->Source, &cpi->denoiser.yv12_last_source); - } -#endif -} - -static int measure_square_diff_partial(YV12_BUFFER_CONFIG *source, - YV12_BUFFER_CONFIG *dest, - VP8_COMP *cpi) { - int i, j; - int Total = 0; - int num_blocks = 0; - int skip = 2; - int min_consec_zero_last = 10; - int tot_num_blocks = (source->y_height * source->y_width) >> 8; - unsigned char *src = source->y_buffer; - unsigned char *dst = dest->y_buffer; - - /* Loop through the Y plane, every |skip| blocks along rows and colmumns, - * summing the square differences, and only for blocks that have been - * zero_last mode at least |x| frames in a row. - */ - for (i = 0; i < source->y_height; i += 16 * skip) { - int block_index_row = (i >> 4) * cpi->common.mb_cols; - for (j = 0; j < source->y_width; j += 16 * skip) { - int index = block_index_row + (j >> 4); - if (cpi->consec_zero_last[index] >= min_consec_zero_last) { - unsigned int sse; - Total += vpx_mse16x16(src + j, source->y_stride, dst + j, - dest->y_stride, &sse); - num_blocks++; - } - } - src += 16 * skip * source->y_stride; - dst += 16 * skip * dest->y_stride; - } - // Only return non-zero if we have at least ~1/16 samples for estimate. - if (num_blocks > (tot_num_blocks >> 4)) { - assert(num_blocks != 0); - return (Total / num_blocks); - } else { - return 0; - } -} - -#if CONFIG_TEMPORAL_DENOISING -static void process_denoiser_mode_change(VP8_COMP *cpi) { - const VP8_COMMON *const cm = &cpi->common; - int i, j; - int total = 0; - int num_blocks = 0; - // Number of blocks skipped along row/column in computing the - // nmse (normalized mean square error) of source. - int skip = 2; - // Only select blocks for computing nmse that have been encoded - // as ZERO LAST min_consec_zero_last frames in a row. - // Scale with number of temporal layers. - int min_consec_zero_last = 12 / cpi->oxcf.number_of_layers; - // Decision is tested for changing the denoising mode every - // num_mode_change times this function is called. Note that this - // function called every 8 frames, so (8 * num_mode_change) is number - // of frames where denoising mode change is tested for switch. - int num_mode_change = 20; - // Framerate factor, to compensate for larger mse at lower framerates. - // Use ref_framerate, which is full source framerate for temporal layers. - // TODO(marpan): Adjust this factor. - int fac_framerate = cpi->ref_framerate < 25.0f ? 80 : 100; - int tot_num_blocks = cm->mb_rows * cm->mb_cols; - int ystride = cpi->Source->y_stride; - unsigned char *src = cpi->Source->y_buffer; - unsigned char *dst = cpi->denoiser.yv12_last_source.y_buffer; - static const unsigned char const_source[16] = { 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128 }; - int bandwidth = (int)(cpi->target_bandwidth); - // For temporal layers, use full bandwidth (top layer). - if (cpi->oxcf.number_of_layers > 1) { - LAYER_CONTEXT *lc = &cpi->layer_context[cpi->oxcf.number_of_layers - 1]; - bandwidth = (int)(lc->target_bandwidth); - } - // Loop through the Y plane, every skip blocks along rows and columns, - // summing the normalized mean square error, only for blocks that have - // been encoded as ZEROMV LAST at least min_consec_zero_last least frames in - // a row and have small sum difference between current and previous frame. - // Normalization here is by the contrast of the current frame block. - for (i = 0; i < cm->Height; i += 16 * skip) { - int block_index_row = (i >> 4) * cm->mb_cols; - for (j = 0; j < cm->Width; j += 16 * skip) { - int index = block_index_row + (j >> 4); - if (cpi->consec_zero_last[index] >= min_consec_zero_last) { - unsigned int sse; - const unsigned int var = - vpx_variance16x16(src + j, ystride, dst + j, ystride, &sse); - // Only consider this block as valid for noise measurement - // if the sum_diff average of the current and previous frame - // is small (to avoid effects from lighting change). - if ((sse - var) < 128) { - unsigned int sse2; - const unsigned int act = - vpx_variance16x16(src + j, ystride, const_source, 0, &sse2); - if (act > 0) total += sse / act; - num_blocks++; - } - } - } - src += 16 * skip * ystride; - dst += 16 * skip * ystride; - } - total = total * fac_framerate / 100; - - // Only consider this frame as valid sample if we have computed nmse over - // at least ~1/16 blocks, and Total > 0 (Total == 0 can happen if the - // application inputs duplicate frames, or contrast is all zero). - if (total > 0 && (num_blocks > (tot_num_blocks >> 4))) { - // Update the recursive mean square source_diff. - total = (total << 8) / num_blocks; - if (cpi->denoiser.nmse_source_diff_count == 0) { - // First sample in new interval. - cpi->denoiser.nmse_source_diff = total; - cpi->denoiser.qp_avg = cm->base_qindex; - } else { - // For subsequent samples, use average with weight ~1/4 for new sample. - cpi->denoiser.nmse_source_diff = - (int)((total + 3 * cpi->denoiser.nmse_source_diff) >> 2); - cpi->denoiser.qp_avg = - (int)((cm->base_qindex + 3 * cpi->denoiser.qp_avg) >> 2); - } - cpi->denoiser.nmse_source_diff_count++; - } - // Check for changing the denoiser mode, when we have obtained #samples = - // num_mode_change. Condition the change also on the bitrate and QP. - if (cpi->denoiser.nmse_source_diff_count == num_mode_change) { - // Check for going up: from normal to aggressive mode. - if ((cpi->denoiser.denoiser_mode == kDenoiserOnYUV) && - (cpi->denoiser.nmse_source_diff > - cpi->denoiser.threshold_aggressive_mode) && - (cpi->denoiser.qp_avg < cpi->denoiser.qp_threshold_up && - bandwidth > cpi->denoiser.bitrate_threshold)) { - vp8_denoiser_set_parameters(&cpi->denoiser, kDenoiserOnYUVAggressive); - } else { - // Check for going down: from aggressive to normal mode. - if (((cpi->denoiser.denoiser_mode == kDenoiserOnYUVAggressive) && - (cpi->denoiser.nmse_source_diff < - cpi->denoiser.threshold_aggressive_mode)) || - ((cpi->denoiser.denoiser_mode == kDenoiserOnYUVAggressive) && - (cpi->denoiser.qp_avg > cpi->denoiser.qp_threshold_down || - bandwidth < cpi->denoiser.bitrate_threshold))) { - vp8_denoiser_set_parameters(&cpi->denoiser, kDenoiserOnYUV); - } - } - // Reset metric and counter for next interval. - cpi->denoiser.nmse_source_diff = 0; - cpi->denoiser.qp_avg = 0; - cpi->denoiser.nmse_source_diff_count = 0; - } -} -#endif - -void vp8_loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm) { - const FRAME_TYPE frame_type = cm->frame_type; - - int update_any_ref_buffers = 1; - if (cpi->common.refresh_last_frame == 0 && - cpi->common.refresh_golden_frame == 0 && - cpi->common.refresh_alt_ref_frame == 0) { - update_any_ref_buffers = 0; - } - - if (cm->no_lpf) { - cm->filter_level = 0; - } else { - struct vpx_usec_timer timer; - - vpx_clear_system_state(); - - vpx_usec_timer_start(&timer); - if (cpi->sf.auto_filter == 0) { -#if CONFIG_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity && cm->frame_type != KEY_FRAME) { - // Use the denoised buffer for selecting base loop filter level. - // Denoised signal for current frame is stored in INTRA_FRAME. - // No denoising on key frames. - vp8cx_pick_filter_level_fast( - &cpi->denoiser.yv12_running_avg[INTRA_FRAME], cpi); - } else { - vp8cx_pick_filter_level_fast(cpi->Source, cpi); - } -#else - vp8cx_pick_filter_level_fast(cpi->Source, cpi); -#endif - } else { -#if CONFIG_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity && cm->frame_type != KEY_FRAME) { - // Use the denoised buffer for selecting base loop filter level. - // Denoised signal for current frame is stored in INTRA_FRAME. - // No denoising on key frames. - vp8cx_pick_filter_level(&cpi->denoiser.yv12_running_avg[INTRA_FRAME], - cpi); - } else { - vp8cx_pick_filter_level(cpi->Source, cpi); - } -#else - vp8cx_pick_filter_level(cpi->Source, cpi); -#endif - } - - if (cm->filter_level > 0) { - vp8cx_set_alt_lf_level(cpi, cm->filter_level); - } - - vpx_usec_timer_mark(&timer); - cpi->time_pick_lpf += vpx_usec_timer_elapsed(&timer); - } - -#if CONFIG_MULTITHREAD - if (vpx_atomic_load_acquire(&cpi->b_multi_threaded)) { - /* signal that we have set filter_level */ - vp8_sem_post(&cpi->h_event_end_lpf); - } -#endif - - // No need to apply loop-filter if the encoded frame does not update - // any reference buffers. - if (cm->filter_level > 0 && update_any_ref_buffers) { - vp8_loop_filter_frame(cm, &cpi->mb.e_mbd, frame_type); - } - - vp8_yv12_extend_frame_borders(cm->frame_to_show); -} -// Return 1 if frame is to be dropped. Update frame drop decimation -// counters. -int vp8_check_drop_buffer(VP8_COMP *cpi) { - VP8_COMMON *cm = &cpi->common; - int drop_mark = (int)(cpi->oxcf.drop_frames_water_mark * - cpi->oxcf.optimal_buffer_level / 100); - int drop_mark75 = drop_mark * 2 / 3; - int drop_mark50 = drop_mark / 4; - int drop_mark25 = drop_mark / 8; - if (cpi->drop_frames_allowed) { - /* The reset to decimation 0 is only done here for one pass. - * Once it is set two pass leaves decimation on till the next kf. - */ - if (cpi->buffer_level > drop_mark && cpi->decimation_factor > 0) { - cpi->decimation_factor--; - } - - if (cpi->buffer_level > drop_mark75 && cpi->decimation_factor > 0) { - cpi->decimation_factor = 1; - - } else if (cpi->buffer_level < drop_mark25 && - (cpi->decimation_factor == 2 || cpi->decimation_factor == 3)) { - cpi->decimation_factor = 3; - } else if (cpi->buffer_level < drop_mark50 && - (cpi->decimation_factor == 1 || cpi->decimation_factor == 2)) { - cpi->decimation_factor = 2; - } else if (cpi->buffer_level < drop_mark75 && - (cpi->decimation_factor == 0 || cpi->decimation_factor == 1)) { - cpi->decimation_factor = 1; - } - } - - /* The following decimates the frame rate according to a regular - * pattern (i.e. to 1/2 or 2/3 frame rate) This can be used to help - * prevent buffer under-run in CBR mode. Alternatively it might be - * desirable in some situations to drop frame rate but throw more bits - * at each frame. - * - * Note that dropping a key frame can be problematic if spatial - * resampling is also active - */ - if (cpi->decimation_factor > 0 && cpi->drop_frames_allowed) { - switch (cpi->decimation_factor) { - case 1: - cpi->per_frame_bandwidth = cpi->per_frame_bandwidth * 3 / 2; - break; - case 2: - cpi->per_frame_bandwidth = cpi->per_frame_bandwidth * 5 / 4; - break; - case 3: - cpi->per_frame_bandwidth = cpi->per_frame_bandwidth * 5 / 4; - break; - } - - /* Note that we should not throw out a key frame (especially when - * spatial resampling is enabled). - */ - if (cm->frame_type == KEY_FRAME) { - cpi->decimation_count = cpi->decimation_factor; - } else if (cpi->decimation_count > 0) { - cpi->decimation_count--; - - cpi->bits_off_target += cpi->av_per_frame_bandwidth; - if (cpi->bits_off_target > cpi->oxcf.maximum_buffer_size) { - cpi->bits_off_target = cpi->oxcf.maximum_buffer_size; - } - -#if CONFIG_MULTI_RES_ENCODING - vp8_store_drop_frame_info(cpi); -#endif - - cm->current_video_frame++; - cpi->frames_since_key++; - cpi->ext_refresh_frame_flags_pending = 0; - // We advance the temporal pattern for dropped frames. - cpi->temporal_pattern_counter++; - -#if CONFIG_INTERNAL_STATS - cpi->count++; -#endif - - cpi->buffer_level = cpi->bits_off_target; - - if (cpi->oxcf.number_of_layers > 1) { - unsigned int i; - - /* Propagate bits saved by dropping the frame to higher - * layers - */ - for (i = cpi->current_layer + 1; i < cpi->oxcf.number_of_layers; ++i) { - LAYER_CONTEXT *lc = &cpi->layer_context[i]; - lc->bits_off_target += (int)(lc->target_bandwidth / lc->framerate); - if (lc->bits_off_target > lc->maximum_buffer_size) { - lc->bits_off_target = lc->maximum_buffer_size; - } - lc->buffer_level = lc->bits_off_target; - } - } - return 1; - } else { - cpi->decimation_count = cpi->decimation_factor; - } - } else { - cpi->decimation_count = 0; - } - return 0; -} - -static void encode_frame_to_data_rate(VP8_COMP *cpi, size_t *size, - unsigned char *dest, - unsigned char *dest_end, - unsigned int *frame_flags) { - int Q; - int frame_over_shoot_limit; - int frame_under_shoot_limit; - - int Loop = 0; - - VP8_COMMON *cm = &cpi->common; - int active_worst_qchanged = 0; - -#if !CONFIG_REALTIME_ONLY - int q_low; - int q_high; - int zbin_oq_high; - int zbin_oq_low = 0; - int top_index; - int bottom_index; - int overshoot_seen = 0; - int undershoot_seen = 0; -#endif - - /* Clear down mmx registers to allow floating point in what follows */ - vpx_clear_system_state(); - - if (cpi->force_next_frame_intra) { - cm->frame_type = KEY_FRAME; /* delayed intra frame */ - cpi->force_next_frame_intra = 0; - } - - /* For an alt ref frame in 2 pass we skip the call to the second pass - * function that sets the target bandwidth - */ - switch (cpi->pass) { -#if !CONFIG_REALTIME_ONLY - case 2: - if (cpi->common.refresh_alt_ref_frame) { - /* Per frame bit target for the alt ref frame */ - cpi->per_frame_bandwidth = cpi->twopass.gf_bits; - /* per second target bitrate */ - cpi->target_bandwidth = - (int)(cpi->twopass.gf_bits * cpi->output_framerate); - } - break; -#endif // !CONFIG_REALTIME_ONLY - default: { - const double per_frame_bandwidth = - round(cpi->target_bandwidth / cpi->output_framerate); - cpi->per_frame_bandwidth = (int)VPXMIN(per_frame_bandwidth, INT_MAX); - break; - } - } - - /* Default turn off buffer to buffer copying */ - cm->copy_buffer_to_gf = 0; - cm->copy_buffer_to_arf = 0; - - /* Clear zbin over-quant value and mode boost values. */ - cpi->mb.zbin_over_quant = 0; - cpi->mb.zbin_mode_boost = 0; - - /* Enable or disable mode based tweaking of the zbin - * For 2 Pass Only used where GF/ARF prediction quality - * is above a threshold - */ - cpi->mb.zbin_mode_boost_enabled = 1; - if (cpi->pass == 2) { - if (cpi->gfu_boost <= 400) { - cpi->mb.zbin_mode_boost_enabled = 0; - } - } - - /* Current default encoder behaviour for the altref sign bias */ - if (cpi->source_alt_ref_active) { - cpi->common.ref_frame_sign_bias[ALTREF_FRAME] = 1; - } else { - cpi->common.ref_frame_sign_bias[ALTREF_FRAME] = 0; - } - - /* Check to see if a key frame is signaled - * For two pass with auto key frame enabled cm->frame_type may already - * be set, but not for one pass. - */ - if ((cm->current_video_frame == 0) || (cm->frame_flags & FRAMEFLAGS_KEY) || - (cpi->oxcf.auto_key && - (cpi->frames_since_key % cpi->key_frame_frequency == 0))) { - /* Key frame from VFW/auto-keyframe/first frame */ - cm->frame_type = KEY_FRAME; -#if CONFIG_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity == 4) { - // For adaptive mode, reset denoiser to normal mode on key frame. - vp8_denoiser_set_parameters(&cpi->denoiser, kDenoiserOnYUV); - } -#endif - } - -#if CONFIG_MULTI_RES_ENCODING - if (cpi->oxcf.mr_total_resolutions > 1) { - LOWER_RES_FRAME_INFO *low_res_frame_info = - (LOWER_RES_FRAME_INFO *)cpi->oxcf.mr_low_res_mode_info; - - if (cpi->oxcf.mr_encoder_id) { - // Check if lower resolution is available for motion vector reuse. - if (cm->frame_type != KEY_FRAME) { - cpi->mr_low_res_mv_avail = 1; - cpi->mr_low_res_mv_avail &= !(low_res_frame_info->is_frame_dropped); - - if (cpi->ref_frame_flags & VP8_LAST_FRAME) - cpi->mr_low_res_mv_avail &= - (cpi->current_ref_frames[LAST_FRAME] == - low_res_frame_info->low_res_ref_frames[LAST_FRAME]); - - if (cpi->ref_frame_flags & VP8_GOLD_FRAME) - cpi->mr_low_res_mv_avail &= - (cpi->current_ref_frames[GOLDEN_FRAME] == - low_res_frame_info->low_res_ref_frames[GOLDEN_FRAME]); - - // Don't use altref to determine whether low res is available. - // TODO (marpan): Should we make this type of condition on a - // per-reference frame basis? - /* - if (cpi->ref_frame_flags & VP8_ALTR_FRAME) - cpi->mr_low_res_mv_avail &= (cpi->current_ref_frames[ALTREF_FRAME] - == low_res_frame_info->low_res_ref_frames[ALTREF_FRAME]); - */ - } - // Disable motion vector reuse (i.e., disable any usage of the low_res) - // if the previous lower stream is skipped/disabled. - if (low_res_frame_info->skip_encoding_prev_stream) { - cpi->mr_low_res_mv_avail = 0; - } - } - // This stream is not skipped (i.e., it's being encoded), so set this skip - // flag to 0. This is needed for the next stream (i.e., which is the next - // frame to be encoded). - low_res_frame_info->skip_encoding_prev_stream = 0; - - // On a key frame: For the lowest resolution, keep track of the key frame - // counter value. For the higher resolutions, reset the current video - // frame counter to that of the lowest resolution. - // This is done to the handle the case where we may stop/start encoding - // higher layer(s). The restart-encoding of higher layer is only signaled - // by a key frame for now. - // TODO (marpan): Add flag to indicate restart-encoding of higher layer. - if (cm->frame_type == KEY_FRAME) { - if (cpi->oxcf.mr_encoder_id) { - // If the initial starting value of the buffer level is zero (this can - // happen because we may have not started encoding this higher stream), - // then reset it to non-zero value based on |starting_buffer_level|. - if (cpi->common.current_video_frame == 0 && cpi->buffer_level == 0) { - unsigned int i; - cpi->bits_off_target = cpi->oxcf.starting_buffer_level; - cpi->buffer_level = cpi->oxcf.starting_buffer_level; - for (i = 0; i < cpi->oxcf.number_of_layers; ++i) { - LAYER_CONTEXT *lc = &cpi->layer_context[i]; - lc->bits_off_target = lc->starting_buffer_level; - lc->buffer_level = lc->starting_buffer_level; - } - } - cpi->common.current_video_frame = - low_res_frame_info->key_frame_counter_value; - } else { - low_res_frame_info->key_frame_counter_value = - cpi->common.current_video_frame; - } - } - } -#endif - - // Find the reference frame closest to the current frame. - cpi->closest_reference_frame = LAST_FRAME; - if (cm->frame_type != KEY_FRAME) { - int i; - MV_REFERENCE_FRAME closest_ref = INTRA_FRAME; - if (cpi->ref_frame_flags & VP8_LAST_FRAME) { - closest_ref = LAST_FRAME; - } else if (cpi->ref_frame_flags & VP8_GOLD_FRAME) { - closest_ref = GOLDEN_FRAME; - } else if (cpi->ref_frame_flags & VP8_ALTR_FRAME) { - closest_ref = ALTREF_FRAME; - } - for (i = 1; i <= 3; ++i) { - vpx_ref_frame_type_t ref_frame_type = - (vpx_ref_frame_type_t)((i == 3) ? 4 : i); - if (cpi->ref_frame_flags & ref_frame_type) { - if ((cm->current_video_frame - cpi->current_ref_frames[i]) < - (cm->current_video_frame - cpi->current_ref_frames[closest_ref])) { - closest_ref = i; - } - } - } - cpi->closest_reference_frame = closest_ref; - } - - /* Set various flags etc to special state if it is a key frame */ - if (cm->frame_type == KEY_FRAME) { - int i; - - // Set the loop filter deltas and segmentation map update - setup_features(cpi); - - /* The alternate reference frame cannot be active for a key frame */ - cpi->source_alt_ref_active = 0; - - /* Reset the RD threshold multipliers to default of * 1 (128) */ - for (i = 0; i < MAX_MODES; ++i) { - cpi->mb.rd_thresh_mult[i] = 128; - } - - // Reset the zero_last counter to 0 on key frame. - memset(cpi->consec_zero_last, 0, cm->mb_rows * cm->mb_cols); - memset(cpi->consec_zero_last_mvbias, 0, - (cpi->common.mb_rows * cpi->common.mb_cols)); - } - -#if 0 - /* Experimental code for lagged compress and one pass - * Initialise one_pass GF frames stats - * Update stats used for GF selection - */ - { - cpi->one_pass_frame_index = cm->current_video_frame % MAX_LAG_BUFFERS; - - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frames_so_far = 0; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_intra_error = 0.0; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_coded_error = 0.0; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_pcnt_inter = 0.0; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_pcnt_motion = 0.0; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_mvr = 0.0; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_mvr_abs = 0.0; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_mvc = 0.0; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_mvc_abs = 0.0; - } -#endif - - update_rd_ref_frame_probs(cpi); - - if (vp8_check_drop_buffer(cpi)) { - return; - } - - /* Decide how big to make the frame */ - if (!vp8_pick_frame_size(cpi)) { -/*TODO: 2 drop_frame and return code could be put together. */ -#if CONFIG_MULTI_RES_ENCODING - vp8_store_drop_frame_info(cpi); -#endif - cm->current_video_frame++; - cpi->frames_since_key++; - cpi->ext_refresh_frame_flags_pending = 0; - // We advance the temporal pattern for dropped frames. - cpi->temporal_pattern_counter++; - return; - } - - /* Reduce active_worst_allowed_q for CBR if our buffer is getting too full. - * This has a knock on effect on active best quality as well. - * For CBR if the buffer reaches its maximum level then we can no longer - * save up bits for later frames so we might as well use them up - * on the current frame. - */ - if ((cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) && - (cpi->buffer_level >= cpi->oxcf.optimal_buffer_level) && - cpi->buffered_mode) { - /* Max adjustment is 1/4 */ - int Adjustment = cpi->active_worst_quality / 4; - - if (Adjustment) { - int buff_lvl_step; - - if (cpi->buffer_level < cpi->oxcf.maximum_buffer_size) { - buff_lvl_step = (int)((cpi->oxcf.maximum_buffer_size - - cpi->oxcf.optimal_buffer_level) / - Adjustment); - - if (buff_lvl_step) { - Adjustment = - (int)((cpi->buffer_level - cpi->oxcf.optimal_buffer_level) / - buff_lvl_step); - } else { - Adjustment = 0; - } - } - - cpi->active_worst_quality -= Adjustment; - - if (cpi->active_worst_quality < cpi->active_best_quality) { - cpi->active_worst_quality = cpi->active_best_quality; - } - } - } - - /* Set an active best quality and if necessary active worst quality - * There is some odd behavior for one pass here that needs attention. - */ - if ((cpi->pass == 2) || (cpi->ni_frames > 150)) { - vpx_clear_system_state(); - - Q = cpi->active_worst_quality; - - if (cm->frame_type == KEY_FRAME) { - if (cpi->pass == 2) { - if (cpi->gfu_boost > 600) { - cpi->active_best_quality = kf_low_motion_minq[Q]; - } else { - cpi->active_best_quality = kf_high_motion_minq[Q]; - } - - /* Special case for key frames forced because we have reached - * the maximum key frame interval. Here force the Q to a range - * based on the ambient Q to reduce the risk of popping - */ - if (cpi->this_key_frame_forced) { - if (cpi->active_best_quality > cpi->avg_frame_qindex * 7 / 8) { - cpi->active_best_quality = cpi->avg_frame_qindex * 7 / 8; - } else if (cpi->active_best_quality < (cpi->avg_frame_qindex >> 2)) { - cpi->active_best_quality = cpi->avg_frame_qindex >> 2; - } - } - } - /* One pass more conservative */ - else { - cpi->active_best_quality = kf_high_motion_minq[Q]; - } - } - - else if (cpi->oxcf.number_of_layers == 1 && - (cm->refresh_golden_frame || cpi->common.refresh_alt_ref_frame)) { - /* Use the lower of cpi->active_worst_quality and recent - * average Q as basis for GF/ARF Q limit unless last frame was - * a key frame. - */ - if ((cpi->frames_since_key > 1) && - (cpi->avg_frame_qindex < cpi->active_worst_quality)) { - Q = cpi->avg_frame_qindex; - } - - /* For constrained quality don't allow Q less than the cq level */ - if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && - (Q < cpi->cq_target_quality)) { - Q = cpi->cq_target_quality; - } - - if (cpi->pass == 2) { - if (cpi->gfu_boost > 1000) { - cpi->active_best_quality = gf_low_motion_minq[Q]; - } else if (cpi->gfu_boost < 400) { - cpi->active_best_quality = gf_high_motion_minq[Q]; - } else { - cpi->active_best_quality = gf_mid_motion_minq[Q]; - } - - /* Constrained quality use slightly lower active best. */ - if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) { - cpi->active_best_quality = cpi->active_best_quality * 15 / 16; - } - } - /* One pass more conservative */ - else { - cpi->active_best_quality = gf_high_motion_minq[Q]; - } - } else { - cpi->active_best_quality = inter_minq[Q]; - - /* For the constant/constrained quality mode we don't want - * q to fall below the cq level. - */ - if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && - (cpi->active_best_quality < cpi->cq_target_quality)) { - /* If we are strongly undershooting the target rate in the last - * frames then use the user passed in cq value not the auto - * cq value. - */ - if (cpi->rolling_actual_bits < cpi->min_frame_bandwidth) { - cpi->active_best_quality = cpi->oxcf.cq_level; - } else { - cpi->active_best_quality = cpi->cq_target_quality; - } - } - } - - /* If CBR and the buffer is as full then it is reasonable to allow - * higher quality on the frames to prevent bits just going to waste. - */ - if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { - /* Note that the use of >= here elliminates the risk of a divide - * by 0 error in the else if clause - */ - if (cpi->buffer_level >= cpi->oxcf.maximum_buffer_size) { - cpi->active_best_quality = cpi->best_quality; - - } else if (cpi->buffer_level > cpi->oxcf.optimal_buffer_level) { - int Fraction = - (int)(((cpi->buffer_level - cpi->oxcf.optimal_buffer_level) * 128) / - (cpi->oxcf.maximum_buffer_size - - cpi->oxcf.optimal_buffer_level)); - int min_qadjustment = - ((cpi->active_best_quality - cpi->best_quality) * Fraction) / 128; - - cpi->active_best_quality -= min_qadjustment; - } - } - } - /* Make sure constrained quality mode limits are adhered to for the first - * few frames of one pass encodes - */ - else if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) { - if ((cm->frame_type == KEY_FRAME) || cm->refresh_golden_frame || - cpi->common.refresh_alt_ref_frame) { - cpi->active_best_quality = cpi->best_quality; - } else if (cpi->active_best_quality < cpi->cq_target_quality) { - cpi->active_best_quality = cpi->cq_target_quality; - } - } - - /* Clip the active best and worst quality values to limits */ - if (cpi->active_worst_quality > cpi->worst_quality) { - cpi->active_worst_quality = cpi->worst_quality; - } - - if (cpi->active_best_quality < cpi->best_quality) { - cpi->active_best_quality = cpi->best_quality; - } - - if (cpi->active_worst_quality < cpi->active_best_quality) { - cpi->active_worst_quality = cpi->active_best_quality; - } - - /* Determine initial Q to try */ - Q = vp8_regulate_q(cpi, cpi->this_frame_target); - -#if !CONFIG_REALTIME_ONLY - - /* Set highest allowed value for Zbin over quant */ - if (cm->frame_type == KEY_FRAME) { - zbin_oq_high = 0; - } else if ((cpi->oxcf.number_of_layers == 1) && - ((cm->refresh_alt_ref_frame || - (cm->refresh_golden_frame && !cpi->source_alt_ref_active)))) { - zbin_oq_high = 16; - } else { - zbin_oq_high = ZBIN_OQ_MAX; - } -#endif - - compute_skin_map(cpi); - - /* Setup background Q adjustment for error resilient mode. - * For multi-layer encodes only enable this for the base layer. - */ - if (cpi->cyclic_refresh_mode_enabled) { - // Special case for screen_content_mode with golden frame updates. - int disable_cr_gf = - (cpi->oxcf.screen_content_mode == 2 && cm->refresh_golden_frame); - if (cpi->current_layer == 0 && cpi->force_maxqp == 0 && !disable_cr_gf) { - cyclic_background_refresh(cpi, Q, 0); - } else { - disable_segmentation(cpi); - } - } - - vp8_compute_frame_size_bounds(cpi, &frame_under_shoot_limit, - &frame_over_shoot_limit); - -#if !CONFIG_REALTIME_ONLY - /* Limit Q range for the adaptive loop. */ - bottom_index = cpi->active_best_quality; - top_index = cpi->active_worst_quality; - q_low = cpi->active_best_quality; - q_high = cpi->active_worst_quality; -#endif - - vp8_save_coding_context(cpi); - - scale_and_extend_source(cpi->un_scaled_source, cpi); - -#if CONFIG_TEMPORAL_DENOISING && CONFIG_POSTPROC - // Option to apply spatial blur under the aggressive or adaptive - // (temporal denoising) mode. - if (cpi->oxcf.noise_sensitivity >= 3) { - if (cpi->denoiser.denoise_pars.spatial_blur != 0) { - vp8_de_noise(cm, cpi->Source, cpi->denoiser.denoise_pars.spatial_blur, 1); - } - } -#endif - -#if !(CONFIG_REALTIME_ONLY) && CONFIG_POSTPROC && !(CONFIG_TEMPORAL_DENOISING) - - if (cpi->oxcf.noise_sensitivity > 0) { - unsigned char *src; - int l = 0; - - switch (cpi->oxcf.noise_sensitivity) { - case 1: l = 20; break; - case 2: l = 40; break; - case 3: l = 60; break; - case 4: l = 80; break; - case 5: l = 100; break; - case 6: l = 150; break; - } - - if (cm->frame_type == KEY_FRAME) { - vp8_de_noise(cm, cpi->Source, l, 1); - } else { - vp8_de_noise(cm, cpi->Source, l, 1); - - src = cpi->Source->y_buffer; - - if (cpi->Source->y_stride < 0) { - src += cpi->Source->y_stride * (cpi->Source->y_height - 1); - } - } - } - -#endif - -#ifdef OUTPUT_YUV_SRC - vpx_write_yuv_frame(yuv_file, cpi->Source); -#endif - - do { - vpx_clear_system_state(); - - vp8_set_quantizer(cpi, Q); - - /* setup skip prob for costing in mode/mv decision */ - if (cpi->common.mb_no_coeff_skip) { - cpi->prob_skip_false = cpi->base_skip_false_prob[Q]; - - if (cm->frame_type != KEY_FRAME) { - if (cpi->common.refresh_alt_ref_frame) { - if (cpi->last_skip_false_probs[2] != 0) { - cpi->prob_skip_false = cpi->last_skip_false_probs[2]; - } - - /* - if(cpi->last_skip_false_probs[2]!=0 && abs(Q- - cpi->last_skip_probs_q[2])<=16 ) - cpi->prob_skip_false = cpi->last_skip_false_probs[2]; - else if (cpi->last_skip_false_probs[2]!=0) - cpi->prob_skip_false = (cpi->last_skip_false_probs[2] + - cpi->prob_skip_false ) / 2; - */ - } else if (cpi->common.refresh_golden_frame) { - if (cpi->last_skip_false_probs[1] != 0) { - cpi->prob_skip_false = cpi->last_skip_false_probs[1]; - } - - /* - if(cpi->last_skip_false_probs[1]!=0 && abs(Q- - cpi->last_skip_probs_q[1])<=16 ) - cpi->prob_skip_false = cpi->last_skip_false_probs[1]; - else if (cpi->last_skip_false_probs[1]!=0) - cpi->prob_skip_false = (cpi->last_skip_false_probs[1] + - cpi->prob_skip_false ) / 2; - */ - } else { - if (cpi->last_skip_false_probs[0] != 0) { - cpi->prob_skip_false = cpi->last_skip_false_probs[0]; - } - - /* - if(cpi->last_skip_false_probs[0]!=0 && abs(Q- - cpi->last_skip_probs_q[0])<=16 ) - cpi->prob_skip_false = cpi->last_skip_false_probs[0]; - else if(cpi->last_skip_false_probs[0]!=0) - cpi->prob_skip_false = (cpi->last_skip_false_probs[0] + - cpi->prob_skip_false ) / 2; - */ - } - - /* as this is for cost estimate, let's make sure it does not - * go extreme eitehr way - */ - if (cpi->prob_skip_false < 5) cpi->prob_skip_false = 5; - - if (cpi->prob_skip_false > 250) cpi->prob_skip_false = 250; - - if (cpi->oxcf.number_of_layers == 1 && cpi->is_src_frame_alt_ref) { - cpi->prob_skip_false = 1; - } - } - -#if 0 - - if (cpi->pass != 1) - { - FILE *f = fopen("skip.stt", "a"); - fprintf(f, "%d, %d, %4d ", cpi->common.refresh_golden_frame, cpi->common.refresh_alt_ref_frame, cpi->prob_skip_false); - fclose(f); - } - -#endif - } - - if (cm->frame_type == KEY_FRAME) { - if (resize_key_frame(cpi)) { - /* If the frame size has changed, need to reset Q, quantizer, - * and background refresh. - */ - Q = vp8_regulate_q(cpi, cpi->this_frame_target); - if (cpi->cyclic_refresh_mode_enabled) { - if (cpi->current_layer == 0) { - cyclic_background_refresh(cpi, Q, 0); - } else { - disable_segmentation(cpi); - } - } - // Reset the zero_last counter to 0 on key frame. - memset(cpi->consec_zero_last, 0, cm->mb_rows * cm->mb_cols); - memset(cpi->consec_zero_last_mvbias, 0, - (cpi->common.mb_rows * cpi->common.mb_cols)); - vp8_set_quantizer(cpi, Q); - } - - vp8_setup_key_frame(cpi); - } - -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING - { - if (cpi->oxcf.error_resilient_mode) cm->refresh_entropy_probs = 0; - - if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) { - if (cm->frame_type == KEY_FRAME) cm->refresh_entropy_probs = 1; - } - - if (cm->refresh_entropy_probs == 0) { - /* save a copy for later refresh */ - memcpy(&cm->lfc, &cm->fc, sizeof(cm->fc)); - } - - vp8_update_coef_context(cpi); - - vp8_update_coef_probs(cpi); - - /* transform / motion compensation build reconstruction frame - * +pack coef partitions - */ - vp8_encode_frame(cpi); - - /* cpi->projected_frame_size is not needed for RT mode */ - } -#else - /* transform / motion compensation build reconstruction frame */ - vp8_encode_frame(cpi); - - if (cpi->pass == 0 && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER && - cpi->rt_drop_recode_on_overshoot == 1) { - if (vp8_drop_encodedframe_overshoot(cpi, Q)) { - vpx_clear_system_state(); - return; - } - if (cm->frame_type != KEY_FRAME) - cpi->last_pred_err_mb = - (int)(cpi->mb.prediction_error / cpi->common.MBs); - } - - cpi->projected_frame_size -= vp8_estimate_entropy_savings(cpi); - cpi->projected_frame_size = - (cpi->projected_frame_size > 0) ? cpi->projected_frame_size : 0; -#endif - vpx_clear_system_state(); - - /* Test to see if the stats generated for this frame indicate that - * we should have coded a key frame (assuming that we didn't)! - */ - - if (cpi->pass != 2 && cpi->oxcf.auto_key && cm->frame_type != KEY_FRAME && - cpi->compressor_speed != 2) { -#if !CONFIG_REALTIME_ONLY - if (decide_key_frame(cpi)) { - /* Reset all our sizing numbers and recode */ - cm->frame_type = KEY_FRAME; - - vp8_pick_frame_size(cpi); - - /* Clear the Alt reference frame active flag when we have - * a key frame - */ - cpi->source_alt_ref_active = 0; - - // Set the loop filter deltas and segmentation map update - setup_features(cpi); - - vp8_restore_coding_context(cpi); - - Q = vp8_regulate_q(cpi, cpi->this_frame_target); - - vp8_compute_frame_size_bounds(cpi, &frame_under_shoot_limit, - &frame_over_shoot_limit); - - /* Limit Q range for the adaptive loop. */ - bottom_index = cpi->active_best_quality; - top_index = cpi->active_worst_quality; - q_low = cpi->active_best_quality; - q_high = cpi->active_worst_quality; - - Loop = 1; - - continue; - } -#endif - } - - vpx_clear_system_state(); - - if (frame_over_shoot_limit == 0) frame_over_shoot_limit = 1; - - /* Are we are overshooting and up against the limit of active max Q. */ - if (!cpi->rt_always_update_correction_factor && - ((cpi->pass != 2) || - (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)) && - (Q == cpi->active_worst_quality) && - (cpi->active_worst_quality < cpi->worst_quality) && - (cpi->projected_frame_size > frame_over_shoot_limit)) { - int over_size_percent = - ((cpi->projected_frame_size - frame_over_shoot_limit) * 100) / - frame_over_shoot_limit; - - /* If so is there any scope for relaxing it */ - while ((cpi->active_worst_quality < cpi->worst_quality) && - (over_size_percent > 0)) { - cpi->active_worst_quality++; - /* Assume 1 qstep = about 4% on frame size. */ - over_size_percent = (int)(over_size_percent * 0.96); - } -#if !CONFIG_REALTIME_ONLY - top_index = cpi->active_worst_quality; -#endif // !CONFIG_REALTIME_ONLY - /* If we have updated the active max Q do not call - * vp8_update_rate_correction_factors() this loop. - */ - active_worst_qchanged = 1; - } else { - active_worst_qchanged = 0; - } - -#if CONFIG_REALTIME_ONLY - Loop = 0; -#else - /* Special case handling for forced key frames */ - if ((cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced) { - int last_q = Q; - int kf_err = vp8_calc_ss_err(cpi->Source, &cm->yv12_fb[cm->new_fb_idx]); - - /* The key frame is not good enough */ - if (kf_err > ((cpi->ambient_err * 7) >> 3)) { - /* Lower q_high */ - q_high = (Q > q_low) ? (Q - 1) : q_low; - - /* Adjust Q */ - Q = (q_high + q_low) >> 1; - } - /* The key frame is much better than the previous frame */ - else if (kf_err < (cpi->ambient_err >> 1)) { - /* Raise q_low */ - q_low = (Q < q_high) ? (Q + 1) : q_high; - - /* Adjust Q */ - Q = (q_high + q_low + 1) >> 1; - } - - /* Clamp Q to upper and lower limits: */ - if (Q > q_high) { - Q = q_high; - } else if (Q < q_low) { - Q = q_low; - } - - Loop = Q != last_q; - } - - /* Is the projected frame size out of range and are we allowed - * to attempt to recode. - */ - else if (recode_loop_test(cpi, frame_over_shoot_limit, - frame_under_shoot_limit, Q, top_index, - bottom_index)) { - int last_q = Q; - int Retries = 0; - - /* Frame size out of permitted range. Update correction factor - * & compute new Q to try... - */ - - /* Frame is too large */ - if (cpi->projected_frame_size > cpi->this_frame_target) { - /* Raise Qlow as to at least the current value */ - q_low = (Q < q_high) ? (Q + 1) : q_high; - - /* If we are using over quant do the same for zbin_oq_low */ - if (cpi->mb.zbin_over_quant > 0) { - zbin_oq_low = (cpi->mb.zbin_over_quant < zbin_oq_high) - ? (cpi->mb.zbin_over_quant + 1) - : zbin_oq_high; - } - - if (undershoot_seen) { - /* Update rate_correction_factor unless - * cpi->active_worst_quality has changed. - */ - if (!active_worst_qchanged) { - vp8_update_rate_correction_factors(cpi, 1); - } - - Q = (q_high + q_low + 1) / 2; - - /* Adjust cpi->zbin_over_quant (only allowed when Q - * is max) - */ - if (Q < MAXQ) { - cpi->mb.zbin_over_quant = 0; - } else { - zbin_oq_low = (cpi->mb.zbin_over_quant < zbin_oq_high) - ? (cpi->mb.zbin_over_quant + 1) - : zbin_oq_high; - cpi->mb.zbin_over_quant = (zbin_oq_high + zbin_oq_low) / 2; - } - } else { - /* Update rate_correction_factor unless - * cpi->active_worst_quality has changed. - */ - if (!active_worst_qchanged) { - vp8_update_rate_correction_factors(cpi, 0); - } - - Q = vp8_regulate_q(cpi, cpi->this_frame_target); - - while (((Q < q_low) || (cpi->mb.zbin_over_quant < zbin_oq_low)) && - (Retries < 10)) { - vp8_update_rate_correction_factors(cpi, 0); - Q = vp8_regulate_q(cpi, cpi->this_frame_target); - Retries++; - } - } - - overshoot_seen = 1; - } - /* Frame is too small */ - else { - if (cpi->mb.zbin_over_quant == 0) { - /* Lower q_high if not using over quant */ - q_high = (Q > q_low) ? (Q - 1) : q_low; - } else { - /* else lower zbin_oq_high */ - zbin_oq_high = (cpi->mb.zbin_over_quant > zbin_oq_low) - ? (cpi->mb.zbin_over_quant - 1) - : zbin_oq_low; - } - - if (overshoot_seen) { - /* Update rate_correction_factor unless - * cpi->active_worst_quality has changed. - */ - if (!active_worst_qchanged) { - vp8_update_rate_correction_factors(cpi, 1); - } - - Q = (q_high + q_low) / 2; - - /* Adjust cpi->zbin_over_quant (only allowed when Q - * is max) - */ - if (Q < MAXQ) { - cpi->mb.zbin_over_quant = 0; - } else { - cpi->mb.zbin_over_quant = (zbin_oq_high + zbin_oq_low) / 2; - } - } else { - /* Update rate_correction_factor unless - * cpi->active_worst_quality has changed. - */ - if (!active_worst_qchanged) { - vp8_update_rate_correction_factors(cpi, 0); - } - - Q = vp8_regulate_q(cpi, cpi->this_frame_target); - - /* Special case reset for qlow for constrained quality. - * This should only trigger where there is very substantial - * undershoot on a frame and the auto cq level is above - * the user passsed in value. - */ - if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && - (Q < q_low)) { - q_low = Q; - } - - while (((Q > q_high) || (cpi->mb.zbin_over_quant > zbin_oq_high)) && - (Retries < 10)) { - vp8_update_rate_correction_factors(cpi, 0); - Q = vp8_regulate_q(cpi, cpi->this_frame_target); - Retries++; - } - } - - undershoot_seen = 1; - } - - /* Clamp Q to upper and lower limits: */ - if (Q > q_high) { - Q = q_high; - } else if (Q < q_low) { - Q = q_low; - } - - /* Clamp cpi->zbin_over_quant */ - cpi->mb.zbin_over_quant = - (cpi->mb.zbin_over_quant < zbin_oq_low) ? zbin_oq_low - : (cpi->mb.zbin_over_quant > zbin_oq_high) ? zbin_oq_high - : cpi->mb.zbin_over_quant; - - Loop = Q != last_q; - } else { - Loop = 0; - } -#endif // CONFIG_REALTIME_ONLY - - if (cpi->is_src_frame_alt_ref) Loop = 0; - - if (Loop == 1) { - vp8_restore_coding_context(cpi); -#if CONFIG_INTERNAL_STATS - cpi->tot_recode_hits++; -#endif - } - } while (Loop == 1); - -#if defined(DROP_UNCODED_FRAMES) - /* if there are no coded macroblocks at all drop this frame */ - if (cpi->common.MBs == cpi->mb.skip_true_count && - (cpi->drop_frame_count & 7) != 7 && cm->frame_type != KEY_FRAME) { - cpi->common.current_video_frame++; - cpi->frames_since_key++; - cpi->drop_frame_count++; - cpi->ext_refresh_frame_flags_pending = 0; - // We advance the temporal pattern for dropped frames. - cpi->temporal_pattern_counter++; - return; - } - cpi->drop_frame_count = 0; -#endif - -#if 0 - /* Experimental code for lagged and one pass - * Update stats used for one pass GF selection - */ - { - cpi->one_pass_frame_stats[cpi->one_pass_frame_index].frame_coded_error = (double)cpi->prediction_error; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index].frame_intra_error = (double)cpi->intra_error; - cpi->one_pass_frame_stats[cpi->one_pass_frame_index].frame_pcnt_inter = (double)(100 - cpi->this_frame_percent_intra) / 100.0; - } -#endif - - /* Special case code to reduce pulsing when key frames are forced at a - * fixed interval. Note the reconstruction error if it is the frame before - * the force key frame - */ - if (cpi->next_key_frame_forced && (cpi->twopass.frames_to_key == 0)) { - cpi->ambient_err = - vp8_calc_ss_err(cpi->Source, &cm->yv12_fb[cm->new_fb_idx]); - } - -/* This frame's MVs are saved and will be used in next frame's MV predictor. - * Last frame has one more line(add to bottom) and one more column(add to - * right) than cm->mip. The edge elements are initialized to 0. - */ -#if CONFIG_MULTI_RES_ENCODING - if (!cpi->oxcf.mr_encoder_id && cm->show_frame) -#else - if (cm->show_frame) /* do not save for altref frame */ -#endif - { - int mb_row; - int mb_col; - /* Point to beginning of allocated MODE_INFO arrays. */ - MODE_INFO *tmp = cm->mip; - - if (cm->frame_type != KEY_FRAME) { - for (mb_row = 0; mb_row < cm->mb_rows + 1; ++mb_row) { - for (mb_col = 0; mb_col < cm->mb_cols + 1; ++mb_col) { - if (tmp->mbmi.ref_frame != INTRA_FRAME) { - cpi->lfmv[mb_col + mb_row * (cm->mode_info_stride + 1)].as_int = - tmp->mbmi.mv.as_int; - } - - cpi->lf_ref_frame_sign_bias[mb_col + - mb_row * (cm->mode_info_stride + 1)] = - cm->ref_frame_sign_bias[tmp->mbmi.ref_frame]; - cpi->lf_ref_frame[mb_col + mb_row * (cm->mode_info_stride + 1)] = - tmp->mbmi.ref_frame; - tmp++; - } - } - } - } - - /* Count last ref frame 0,0 usage on current encoded frame. */ - { - int mb_row; - int mb_col; - /* Point to beginning of MODE_INFO arrays. */ - MODE_INFO *tmp = cm->mi; - - cpi->zeromv_count = 0; - - if (cm->frame_type != KEY_FRAME) { - for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) { - for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) { - if (tmp->mbmi.mode == ZEROMV && tmp->mbmi.ref_frame == LAST_FRAME) { - cpi->zeromv_count++; - } - tmp++; - } - tmp++; - } - } - } - -#if CONFIG_MULTI_RES_ENCODING - vp8_cal_dissimilarity(cpi); -#endif - - /* Update the GF usage maps. - * This is done after completing the compression of a frame when all - * modes etc. are finalized but before loop filter - */ - if (cpi->oxcf.number_of_layers == 1) { - vp8_update_gf_usage_maps(cpi, cm, &cpi->mb); - } - - if (cm->frame_type == KEY_FRAME) cm->refresh_last_frame = 1; - -#if 0 - { - FILE *f = fopen("gfactive.stt", "a"); - fprintf(f, "%8d %8d %8d %8d %8d\n", cm->current_video_frame, (100 * cpi->gf_active_count) / (cpi->common.mb_rows * cpi->common.mb_cols), cpi->this_iiratio, cpi->next_iiratio, cm->refresh_golden_frame); - fclose(f); - } -#endif - - /* For inter frames the current default behavior is that when - * cm->refresh_golden_frame is set we copy the old GF over to the ARF buffer - * This is purely an encoder decision at present. - * Avoid this behavior when refresh flags are set by the user. - */ - if (!cpi->oxcf.error_resilient_mode && cm->refresh_golden_frame && - !cpi->ext_refresh_frame_flags_pending) { - cm->copy_buffer_to_arf = 2; - } else { - cm->copy_buffer_to_arf = 0; - } - - cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx]; - -#if CONFIG_TEMPORAL_DENOISING - // Get some measure of the amount of noise, by measuring the (partial) mse - // between source and denoised buffer, for y channel. Partial refers to - // computing the sse for a sub-sample of the frame (i.e., skip x blocks along - // row/column), - // and only for blocks in that set that are consecutive ZEROMV_LAST mode. - // Do this every ~8 frames, to further reduce complexity. - // TODO(marpan): Keep this for now for the case cpi->oxcf.noise_sensitivity < - // 4, - // should be removed in favor of the process_denoiser_mode_change() function - // below. - if (cpi->oxcf.noise_sensitivity > 0 && cpi->oxcf.noise_sensitivity < 4 && - !cpi->oxcf.screen_content_mode && cpi->frames_since_key % 8 == 0 && - cm->frame_type != KEY_FRAME) { - cpi->mse_source_denoised = measure_square_diff_partial( - &cpi->denoiser.yv12_running_avg[INTRA_FRAME], cpi->Source, cpi); - } - - // For the adaptive denoising mode (noise_sensitivity == 4), sample the mse - // of source diff (between current and previous frame), and determine if we - // should switch the denoiser mode. Sampling refers to computing the mse for - // a sub-sample of the frame (i.e., skip x blocks along row/column), and - // only for blocks in that set that have used ZEROMV LAST, along with some - // constraint on the sum diff between blocks. This process is called every - // ~8 frames, to further reduce complexity. - if (cpi->oxcf.noise_sensitivity == 4 && !cpi->oxcf.screen_content_mode && - cpi->frames_since_key % 8 == 0 && cm->frame_type != KEY_FRAME) { - process_denoiser_mode_change(cpi); - } -#endif - -#ifdef OUTPUT_YUV_SKINMAP - if (cpi->common.current_video_frame > 1) { - vp8_compute_skin_map(cpi, yuv_skinmap_file); - } -#endif - -#if CONFIG_MULTITHREAD - if (vpx_atomic_load_acquire(&cpi->b_multi_threaded)) { - /* start loopfilter in separate thread */ - vp8_sem_post(&cpi->h_event_start_lpf); - cpi->b_lpf_running = 1; - /* wait for the filter_level to be picked so that we can continue with - * stream packing */ - vp8_sem_wait(&cpi->h_event_end_lpf); - } else -#endif - { - vp8_loopfilter_frame(cpi, cm); - } - - update_reference_frames(cpi); - -#ifdef OUTPUT_YUV_DENOISED - vpx_write_yuv_frame(yuv_denoised_file, - &cpi->denoiser.yv12_running_avg[INTRA_FRAME]); -#endif - -#if !(CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING) - if (cpi->oxcf.error_resilient_mode) { - cm->refresh_entropy_probs = 0; - } -#endif - - /* build the bitstream */ - vp8_pack_bitstream(cpi, dest, dest_end, size); - - /* Move storing frame_type out of the above loop since it is also - * needed in motion search besides loopfilter */ - cm->last_frame_type = cm->frame_type; - - /* Update rate control heuristics */ - cpi->total_byte_count += (*size); - cpi->projected_frame_size = (int)(*size) << 3; - - if (cpi->oxcf.number_of_layers > 1) { - unsigned int i; - for (i = cpi->current_layer + 1; i < cpi->oxcf.number_of_layers; ++i) { - cpi->layer_context[i].total_byte_count += (*size); - } - } - - if (!active_worst_qchanged) vp8_update_rate_correction_factors(cpi, 2); - - cpi->last_q[cm->frame_type] = cm->base_qindex; - - if (cm->frame_type == KEY_FRAME) { - vp8_adjust_key_frame_context(cpi); - } - - /* Keep a record of ambient average Q. */ - if (cm->frame_type != KEY_FRAME) { - cpi->avg_frame_qindex = - (2 + 3 * cpi->avg_frame_qindex + cm->base_qindex) >> 2; - } - - /* Keep a record from which we can calculate the average Q excluding - * GF updates and key frames - */ - if ((cm->frame_type != KEY_FRAME) && - ((cpi->oxcf.number_of_layers > 1) || - (!cm->refresh_golden_frame && !cm->refresh_alt_ref_frame))) { - cpi->ni_frames++; - - /* Calculate the average Q for normal inter frames (not key or GFU - * frames). - */ - if (cpi->pass == 2) { - cpi->ni_tot_qi += Q; - cpi->ni_av_qi = (cpi->ni_tot_qi / cpi->ni_frames); - } else { - /* Damp value for first few frames */ - if (cpi->ni_frames > 150) { - cpi->ni_tot_qi += Q; - cpi->ni_av_qi = (cpi->ni_tot_qi / cpi->ni_frames); - } - /* For one pass, early in the clip ... average the current frame Q - * value with the worstq entered by the user as a dampening measure - */ - else { - cpi->ni_tot_qi += Q; - cpi->ni_av_qi = - ((cpi->ni_tot_qi / cpi->ni_frames) + cpi->worst_quality + 1) / 2; - } - - /* If the average Q is higher than what was used in the last - * frame (after going through the recode loop to keep the frame - * size within range) then use the last frame value - 1. The -1 - * is designed to stop Q and hence the data rate, from - * progressively falling away during difficult sections, but at - * the same time reduce the number of iterations around the - * recode loop. - */ - if (Q > cpi->ni_av_qi) cpi->ni_av_qi = Q - 1; - } - } - - /* Update the buffer level variable. */ - /* Non-viewable frames are a special case and are treated as pure overhead. */ - if (!cm->show_frame) { - cpi->bits_off_target -= cpi->projected_frame_size; - } else { - cpi->bits_off_target += - cpi->av_per_frame_bandwidth - cpi->projected_frame_size; - } - - /* Clip the buffer level to the maximum specified buffer size */ - if (cpi->bits_off_target > cpi->oxcf.maximum_buffer_size) { - cpi->bits_off_target = cpi->oxcf.maximum_buffer_size; - } - - // Don't let the buffer level go below some threshold, given here - // by -|maximum_buffer_size|. For now we only do this for - // screen content input. - if (cpi->oxcf.screen_content_mode && - cpi->bits_off_target < -cpi->oxcf.maximum_buffer_size) { - cpi->bits_off_target = -cpi->oxcf.maximum_buffer_size; - } - - /* Rolling monitors of whether we are over or underspending used to - * help regulate min and Max Q in two pass. - */ - cpi->rolling_target_bits = (int)ROUND64_POWER_OF_TWO( - (int64_t)cpi->rolling_target_bits * 3 + cpi->this_frame_target, 2); - cpi->rolling_actual_bits = (int)ROUND64_POWER_OF_TWO( - (int64_t)cpi->rolling_actual_bits * 3 + cpi->projected_frame_size, 2); - cpi->long_rolling_target_bits = (int)ROUND64_POWER_OF_TWO( - (int64_t)cpi->long_rolling_target_bits * 31 + cpi->this_frame_target, 5); - cpi->long_rolling_actual_bits = (int)ROUND64_POWER_OF_TWO( - (int64_t)cpi->long_rolling_actual_bits * 31 + cpi->projected_frame_size, - 5); - - /* Actual bits spent */ - cpi->total_actual_bits += cpi->projected_frame_size; - -#if 0 && CONFIG_INTERNAL_STATS - /* Debug stats */ - cpi->total_target_vs_actual += - (cpi->this_frame_target - cpi->projected_frame_size); -#endif - - cpi->buffer_level = cpi->bits_off_target; - - /* Propagate values to higher temporal layers */ - if (cpi->oxcf.number_of_layers > 1) { - unsigned int i; - - for (i = cpi->current_layer + 1; i < cpi->oxcf.number_of_layers; ++i) { - LAYER_CONTEXT *lc = &cpi->layer_context[i]; - int bits_off_for_this_layer = (int)round( - lc->target_bandwidth / lc->framerate - cpi->projected_frame_size); - - lc->bits_off_target += bits_off_for_this_layer; - - /* Clip buffer level to maximum buffer size for the layer */ - if (lc->bits_off_target > lc->maximum_buffer_size) { - lc->bits_off_target = lc->maximum_buffer_size; - } - - lc->total_actual_bits += cpi->projected_frame_size; - lc->total_target_vs_actual += bits_off_for_this_layer; - lc->buffer_level = lc->bits_off_target; - } - } - - /* Update bits left to the kf and gf groups to account for overshoot - * or undershoot on these frames - */ - if (cm->frame_type == KEY_FRAME) { - cpi->twopass.kf_group_bits += - cpi->this_frame_target - cpi->projected_frame_size; - - if (cpi->twopass.kf_group_bits < 0) cpi->twopass.kf_group_bits = 0; - } else if (cm->refresh_golden_frame || cm->refresh_alt_ref_frame) { - cpi->twopass.gf_group_bits += - cpi->this_frame_target - cpi->projected_frame_size; - - if (cpi->twopass.gf_group_bits < 0) cpi->twopass.gf_group_bits = 0; - } - - if (cm->frame_type != KEY_FRAME) { - if (cpi->common.refresh_alt_ref_frame) { - cpi->last_skip_false_probs[2] = cpi->prob_skip_false; - cpi->last_skip_probs_q[2] = cm->base_qindex; - } else if (cpi->common.refresh_golden_frame) { - cpi->last_skip_false_probs[1] = cpi->prob_skip_false; - cpi->last_skip_probs_q[1] = cm->base_qindex; - } else { - cpi->last_skip_false_probs[0] = cpi->prob_skip_false; - cpi->last_skip_probs_q[0] = cm->base_qindex; - - /* update the baseline */ - cpi->base_skip_false_prob[cm->base_qindex] = cpi->prob_skip_false; - } - } - -#if 0 && CONFIG_INTERNAL_STATS - { - FILE *f = fopen("tmp.stt", "a"); - - vpx_clear_system_state(); - - if (cpi->twopass.total_left_stats.coded_error != 0.0) - fprintf(f, "%10d %10d %10d %10d %10d %10"PRId64" %10"PRId64 - "%10"PRId64" %10d %6d %6d %6d %6d %5d %5d %5d %8d " - "%8.2lf %"PRId64" %10.3lf %10"PRId64" %8d\n", - cpi->common.current_video_frame, cpi->this_frame_target, - cpi->projected_frame_size, - (cpi->projected_frame_size - cpi->this_frame_target), - cpi->total_target_vs_actual, - cpi->buffer_level, - (cpi->oxcf.starting_buffer_level-cpi->bits_off_target), - cpi->total_actual_bits, cm->base_qindex, - cpi->active_best_quality, cpi->active_worst_quality, - cpi->ni_av_qi, cpi->cq_target_quality, - cm->refresh_golden_frame, cm->refresh_alt_ref_frame, - cm->frame_type, cpi->gfu_boost, - cpi->twopass.est_max_qcorrection_factor, - cpi->twopass.bits_left, - cpi->twopass.total_left_stats.coded_error, - (double)cpi->twopass.bits_left / - cpi->twopass.total_left_stats.coded_error, - cpi->tot_recode_hits); - else - fprintf(f, "%10d %10d %10d %10d %10d %10"PRId64" %10"PRId64 - "%10"PRId64" %10d %6d %6d %6d %6d %5d %5d %5d %8d " - "%8.2lf %"PRId64" %10.3lf %8d\n", - cpi->common.current_video_frame, cpi->this_frame_target, - cpi->projected_frame_size, - (cpi->projected_frame_size - cpi->this_frame_target), - cpi->total_target_vs_actual, - cpi->buffer_level, - (cpi->oxcf.starting_buffer_level-cpi->bits_off_target), - cpi->total_actual_bits, cm->base_qindex, - cpi->active_best_quality, cpi->active_worst_quality, - cpi->ni_av_qi, cpi->cq_target_quality, - cm->refresh_golden_frame, cm->refresh_alt_ref_frame, - cm->frame_type, cpi->gfu_boost, - cpi->twopass.est_max_qcorrection_factor, - cpi->twopass.bits_left, - cpi->twopass.total_left_stats.coded_error, - cpi->tot_recode_hits); - - fclose(f); - - { - FILE *fmodes = fopen("Modes.stt", "a"); - - fprintf(fmodes, "%6d:%1d:%1d:%1d ", - cpi->common.current_video_frame, - cm->frame_type, cm->refresh_golden_frame, - cm->refresh_alt_ref_frame); - - fprintf(fmodes, "\n"); - - fclose(fmodes); - } - } - -#endif - - cpi->ext_refresh_frame_flags_pending = 0; - - if (cm->refresh_golden_frame == 1) { - cm->frame_flags = cm->frame_flags | FRAMEFLAGS_GOLDEN; - } else { - cm->frame_flags = cm->frame_flags & ~FRAMEFLAGS_GOLDEN; - } - - if (cm->refresh_alt_ref_frame == 1) { - cm->frame_flags = cm->frame_flags | FRAMEFLAGS_ALTREF; - } else { - cm->frame_flags = cm->frame_flags & ~FRAMEFLAGS_ALTREF; - } - - if (cm->refresh_last_frame & cm->refresh_golden_frame) { /* both refreshed */ - cpi->gold_is_last = 1; - } else if (cm->refresh_last_frame ^ cm->refresh_golden_frame) { - /* 1 refreshed but not the other */ - cpi->gold_is_last = 0; - } - - if (cm->refresh_last_frame & cm->refresh_alt_ref_frame) { /* both refreshed */ - cpi->alt_is_last = 1; - } else if (cm->refresh_last_frame ^ cm->refresh_alt_ref_frame) { - /* 1 refreshed but not the other */ - cpi->alt_is_last = 0; - } - - if (cm->refresh_alt_ref_frame & - cm->refresh_golden_frame) { /* both refreshed */ - cpi->gold_is_alt = 1; - } else if (cm->refresh_alt_ref_frame ^ cm->refresh_golden_frame) { - /* 1 refreshed but not the other */ - cpi->gold_is_alt = 0; - } - - cpi->ref_frame_flags = VP8_ALTR_FRAME | VP8_GOLD_FRAME | VP8_LAST_FRAME; - - if (cpi->gold_is_last) cpi->ref_frame_flags &= ~VP8_GOLD_FRAME; - - if (cpi->alt_is_last) cpi->ref_frame_flags &= ~VP8_ALTR_FRAME; - - if (cpi->gold_is_alt) cpi->ref_frame_flags &= ~VP8_ALTR_FRAME; - - if (!cpi->oxcf.error_resilient_mode) { - if (cpi->oxcf.play_alternate && cm->refresh_alt_ref_frame && - (cm->frame_type != KEY_FRAME)) { - /* Update the alternate reference frame stats as appropriate. */ - update_alt_ref_frame_stats(cpi); - } else { - /* Update the Golden frame stats as appropriate. */ - update_golden_frame_stats(cpi); - } - } - - if (cm->frame_type == KEY_FRAME) { - /* Tell the caller that the frame was coded as a key frame */ - *frame_flags = cm->frame_flags | FRAMEFLAGS_KEY; - - /* As this frame is a key frame the next defaults to an inter frame. */ - cm->frame_type = INTER_FRAME; - - cpi->last_frame_percent_intra = 100; - } else { - *frame_flags = cm->frame_flags & ~FRAMEFLAGS_KEY; - - cpi->last_frame_percent_intra = cpi->this_frame_percent_intra; - } - - /* Clear the one shot update flags for segmentation map and mode/ref - * loop filter deltas. - */ - cpi->mb.e_mbd.update_mb_segmentation_map = 0; - cpi->mb.e_mbd.update_mb_segmentation_data = 0; - cpi->mb.e_mbd.mode_ref_lf_delta_update = 0; - - /* Don't increment frame counters if this was an altref buffer update - * not a real frame - */ - if (cm->show_frame) { - cm->current_video_frame++; - cpi->frames_since_key++; - cpi->temporal_pattern_counter++; - } - -#if 0 - { - char filename[512]; - FILE *recon_file; - sprintf(filename, "enc%04d.yuv", (int) cm->current_video_frame); - recon_file = fopen(filename, "wb"); - fwrite(cm->yv12_fb[cm->lst_fb_idx].buffer_alloc, - cm->yv12_fb[cm->lst_fb_idx].frame_size, 1, recon_file); - fclose(recon_file); - } -#endif - - /* DEBUG */ - /* vpx_write_yuv_frame("encoder_recon.yuv", cm->frame_to_show); */ -} -#if !CONFIG_REALTIME_ONLY -static void Pass2Encode(VP8_COMP *cpi, size_t *size, unsigned char *dest, - unsigned char *dest_end, unsigned int *frame_flags) { - if (!cpi->common.refresh_alt_ref_frame) vp8_second_pass(cpi); - - encode_frame_to_data_rate(cpi, size, dest, dest_end, frame_flags); - cpi->twopass.bits_left -= 8 * (int)(*size); - - if (!cpi->common.refresh_alt_ref_frame) { - double two_pass_min_rate = - (double)(cpi->oxcf.target_bandwidth * - cpi->oxcf.two_pass_vbrmin_section / 100); - cpi->twopass.bits_left += (int64_t)(two_pass_min_rate / cpi->framerate); - } -} -#endif - -int vp8_receive_raw_frame(VP8_COMP *cpi, unsigned int frame_flags, - YV12_BUFFER_CONFIG *sd, int64_t time_stamp, - int64_t end_time) { - struct vpx_usec_timer timer; - int res = 0; - - vpx_usec_timer_start(&timer); - - /* Reinit the lookahead buffer if the frame size changes */ - if (sd->y_width != cpi->oxcf.Width || sd->y_height != cpi->oxcf.Height) { - assert(cpi->oxcf.lag_in_frames < 2); - dealloc_raw_frame_buffers(cpi); - alloc_raw_frame_buffers(cpi); - } - - if (vp8_lookahead_push(cpi->lookahead, sd, time_stamp, end_time, frame_flags, - cpi->active_map_enabled ? cpi->active_map : NULL)) { - res = -1; - } - vpx_usec_timer_mark(&timer); - cpi->time_receive_data += vpx_usec_timer_elapsed(&timer); - - return res; -} - -static int frame_is_reference(const VP8_COMP *cpi) { - const VP8_COMMON *cm = &cpi->common; - const MACROBLOCKD *xd = &cpi->mb.e_mbd; - - return cm->frame_type == KEY_FRAME || cm->refresh_last_frame || - cm->refresh_golden_frame || cm->refresh_alt_ref_frame || - cm->copy_buffer_to_gf || cm->copy_buffer_to_arf || - cm->refresh_entropy_probs || xd->mode_ref_lf_delta_update || - xd->update_mb_segmentation_map || xd->update_mb_segmentation_data; -} - -int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags, - size_t *size, unsigned char *dest, - unsigned char *dest_end, int64_t *time_stamp, - int64_t *time_end, int flush) { - VP8_COMMON *cm; - struct vpx_usec_timer tsctimer; - struct vpx_usec_timer ticktimer; - struct vpx_usec_timer cmptimer; - YV12_BUFFER_CONFIG *force_src_buffer = NULL; - - if (!cpi) return -1; - - cm = &cpi->common; - - vpx_usec_timer_start(&cmptimer); - - cpi->source = NULL; - -#if !CONFIG_REALTIME_ONLY - /* Should we code an alternate reference frame */ - if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.play_alternate && - cpi->source_alt_ref_pending) { - if ((cpi->source = vp8_lookahead_peek( - cpi->lookahead, cpi->frames_till_gf_update_due, PEEK_FORWARD))) { - cpi->alt_ref_source = cpi->source; - if (cpi->oxcf.arnr_max_frames > 0) { - vp8_temporal_filter_prepare_c(cpi, cpi->frames_till_gf_update_due); - force_src_buffer = &cpi->alt_ref_buffer; - } - cpi->frames_till_alt_ref_frame = cpi->frames_till_gf_update_due; - cm->refresh_alt_ref_frame = 1; - cm->refresh_golden_frame = 0; - cm->refresh_last_frame = 0; - cm->show_frame = 0; - /* Clear Pending alt Ref flag. */ - cpi->source_alt_ref_pending = 0; - cpi->is_src_frame_alt_ref = 0; - } - } -#endif - - if (!cpi->source) { - /* Read last frame source if we are encoding first pass. */ - if (cpi->pass == 1 && cm->current_video_frame > 0) { - if ((cpi->last_source = - vp8_lookahead_peek(cpi->lookahead, 1, PEEK_BACKWARD)) == NULL) { - return -1; - } - } - - if ((cpi->source = vp8_lookahead_pop(cpi->lookahead, flush))) { - cm->show_frame = 1; - - cpi->is_src_frame_alt_ref = - cpi->alt_ref_source && (cpi->source == cpi->alt_ref_source); - - if (cpi->is_src_frame_alt_ref) cpi->alt_ref_source = NULL; - } - } - - if (cpi->source) { - cpi->Source = force_src_buffer ? force_src_buffer : &cpi->source->img; - cpi->un_scaled_source = cpi->Source; - *time_stamp = cpi->source->ts_start; - *time_end = cpi->source->ts_end; - *frame_flags = cpi->source->flags; - - if (cpi->pass == 1 && cm->current_video_frame > 0) { - cpi->last_frame_unscaled_source = &cpi->last_source->img; - } - } else { - *size = 0; -#if !CONFIG_REALTIME_ONLY - - if (flush && cpi->pass == 1 && !cpi->twopass.first_pass_done) { - vp8_end_first_pass(cpi); /* get last stats packet */ - cpi->twopass.first_pass_done = 1; - } - -#endif - - return -1; - } - - if (cpi->source->ts_start < cpi->first_time_stamp_ever) { - cpi->first_time_stamp_ever = cpi->source->ts_start; - cpi->last_end_time_stamp_seen = cpi->source->ts_start; - } - - /* adjust frame rates based on timestamps given */ - if (cm->show_frame) { - int64_t this_duration; - int step = 0; - - if (cpi->source->ts_start == cpi->first_time_stamp_ever) { - this_duration = cpi->source->ts_end - cpi->source->ts_start; - step = 1; - } else { - int64_t last_duration; - - this_duration = cpi->source->ts_end - cpi->last_end_time_stamp_seen; - last_duration = cpi->last_end_time_stamp_seen - cpi->last_time_stamp_seen; - // Cap this to avoid overflow of (this_duration - last_duration) * 10 - this_duration = VPXMIN(this_duration, INT64_MAX / 10); - /* do a step update if the duration changes by 10% */ - if (last_duration) { - step = (int)(((this_duration - last_duration) * 10 / last_duration)); - } - } - - if (this_duration) { - if (step) { - cpi->ref_framerate = 10000000.0 / this_duration; - } else { - double avg_duration, interval; - - /* Average this frame's rate into the last second's average - * frame rate. If we haven't seen 1 second yet, then average - * over the whole interval seen. - */ - interval = (double)(cpi->source->ts_end - cpi->first_time_stamp_ever); - if (interval > 10000000.0) interval = 10000000; - - avg_duration = 10000000.0 / cpi->ref_framerate; - avg_duration *= (interval - avg_duration + this_duration); - avg_duration /= interval; - - cpi->ref_framerate = 10000000.0 / avg_duration; - } -#if CONFIG_MULTI_RES_ENCODING - if (cpi->oxcf.mr_total_resolutions > 1) { - LOWER_RES_FRAME_INFO *low_res_frame_info = - (LOWER_RES_FRAME_INFO *)cpi->oxcf.mr_low_res_mode_info; - // Frame rate should be the same for all spatial layers in - // multi-res-encoding (simulcast), so we constrain the frame for - // higher layers to be that of lowest resolution. This is needed - // as he application may decide to skip encoding a high layer and - // then start again, in which case a big jump in time-stamps will - // be received for that high layer, which will yield an incorrect - // frame rate (from time-stamp adjustment in above calculation). - if (cpi->oxcf.mr_encoder_id) { - if (!low_res_frame_info->skip_encoding_base_stream) - cpi->ref_framerate = low_res_frame_info->low_res_framerate; - } else { - // Keep track of frame rate for lowest resolution. - low_res_frame_info->low_res_framerate = cpi->ref_framerate; - // The base stream is being encoded so set skip flag to 0. - low_res_frame_info->skip_encoding_base_stream = 0; - } - } -#endif - if (cpi->oxcf.number_of_layers > 1) { - unsigned int i; - - /* Update frame rates for each layer */ - assert(cpi->oxcf.number_of_layers <= VPX_TS_MAX_LAYERS); - for (i = 0; i < cpi->oxcf.number_of_layers && i < VPX_TS_MAX_LAYERS; - ++i) { - LAYER_CONTEXT *lc = &cpi->layer_context[i]; - lc->framerate = cpi->ref_framerate / cpi->oxcf.rate_decimator[i]; - } - } else { - vp8_new_framerate(cpi, cpi->ref_framerate); - } - } - - cpi->last_time_stamp_seen = cpi->source->ts_start; - cpi->last_end_time_stamp_seen = cpi->source->ts_end; - } - - if (cpi->oxcf.number_of_layers > 1) { - int layer; - - vp8_update_layer_contexts(cpi); - - /* Restore layer specific context & set frame rate */ - if (cpi->temporal_layer_id >= 0) { - layer = cpi->temporal_layer_id; - } else { - layer = - cpi->oxcf - .layer_id[cpi->temporal_pattern_counter % cpi->oxcf.periodicity]; - } - vp8_restore_layer_context(cpi, layer); - vp8_new_framerate(cpi, cpi->layer_context[layer].framerate); - } - - if (cpi->compressor_speed == 2) { - vpx_usec_timer_start(&tsctimer); - vpx_usec_timer_start(&ticktimer); - } - - cpi->lf_zeromv_pct = (cpi->zeromv_count * 100) / cm->MBs; - -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING - { - int i; - const int num_part = (1 << cm->multi_token_partition); - /* the available bytes in dest */ - const unsigned long dest_size = dest_end - dest; - const int tok_part_buff_size = (dest_size * 9) / (10 * num_part); - - unsigned char *dp = dest; - - cpi->partition_d[0] = dp; - dp += dest_size / 10; /* reserve 1/10 for control partition */ - cpi->partition_d_end[0] = dp; - - for (i = 0; i < num_part; ++i) { - cpi->partition_d[i + 1] = dp; - dp += tok_part_buff_size; - cpi->partition_d_end[i + 1] = dp; - } - } -#endif - - /* start with a 0 size frame */ - *size = 0; - - /* Clear down mmx registers */ - vpx_clear_system_state(); - - cm->frame_type = INTER_FRAME; - cm->frame_flags = *frame_flags; - -#if 0 - - if (cm->refresh_alt_ref_frame) - { - cm->refresh_golden_frame = 0; - cm->refresh_last_frame = 0; - } - else - { - cm->refresh_golden_frame = 0; - cm->refresh_last_frame = 1; - } - -#endif - /* find a free buffer for the new frame */ - { - int i = 0; - for (; i < NUM_YV12_BUFFERS; ++i) { - if (!cm->yv12_fb[i].flags) { - cm->new_fb_idx = i; - break; - } - } - - assert(i < NUM_YV12_BUFFERS); - } - switch (cpi->pass) { -#if !CONFIG_REALTIME_ONLY - case 1: Pass1Encode(cpi); break; - case 2: Pass2Encode(cpi, size, dest, dest_end, frame_flags); break; -#endif // !CONFIG_REALTIME_ONLY - default: - encode_frame_to_data_rate(cpi, size, dest, dest_end, frame_flags); - break; - } - - if (cpi->compressor_speed == 2) { - unsigned int duration, duration2; - vpx_usec_timer_mark(&tsctimer); - vpx_usec_timer_mark(&ticktimer); - - duration = (int)(vpx_usec_timer_elapsed(&ticktimer)); - duration2 = (unsigned int)((double)duration / 2); - - if (cm->frame_type != KEY_FRAME) { - if (cpi->avg_encode_time == 0) { - cpi->avg_encode_time = duration; - } else { - cpi->avg_encode_time = (7 * cpi->avg_encode_time + duration) >> 3; - } - } - - if (duration2) { - { - if (cpi->avg_pick_mode_time == 0) { - cpi->avg_pick_mode_time = duration2; - } else { - cpi->avg_pick_mode_time = - (7 * cpi->avg_pick_mode_time + duration2) >> 3; - } - } - } - } - - if (cm->refresh_entropy_probs == 0) { - memcpy(&cm->fc, &cm->lfc, sizeof(cm->fc)); - } - - /* Save the contexts separately for alt ref, gold and last. */ - /* (TODO jbb -> Optimize this with pointers to avoid extra copies. ) */ - if (cm->refresh_alt_ref_frame) memcpy(&cpi->lfc_a, &cm->fc, sizeof(cm->fc)); - - if (cm->refresh_golden_frame) memcpy(&cpi->lfc_g, &cm->fc, sizeof(cm->fc)); - - if (cm->refresh_last_frame) memcpy(&cpi->lfc_n, &cm->fc, sizeof(cm->fc)); - - /* if it's a dropped frame honor the requests on subsequent frames */ - if (*size > 0) { - cpi->droppable = !frame_is_reference(cpi); - - /* return to normal state */ - cm->refresh_entropy_probs = 1; - cm->refresh_alt_ref_frame = 0; - cm->refresh_golden_frame = 0; - cm->refresh_last_frame = 1; - cm->frame_type = INTER_FRAME; - } - - /* Save layer specific state */ - if (cpi->oxcf.number_of_layers > 1) vp8_save_layer_context(cpi); - - vpx_usec_timer_mark(&cmptimer); - cpi->time_compress_data += vpx_usec_timer_elapsed(&cmptimer); - -#if CONFIG_MULTITHREAD - /* wait for the lpf thread done */ - if (vpx_atomic_load_acquire(&cpi->b_multi_threaded) && cpi->b_lpf_running) { - vp8_sem_wait(&cpi->h_event_end_lpf); - cpi->b_lpf_running = 0; - } -#endif - - if (cpi->b_calculate_psnr && cpi->pass != 1 && cm->show_frame) { - generate_psnr_packet(cpi); - } - -#if CONFIG_INTERNAL_STATS - - if (cpi->pass != 1) { - cpi->bytes += *size; - - if (cm->show_frame) { - cpi->common.show_frame_mi = cpi->common.mi; - cpi->count++; - - if (cpi->b_calculate_psnr) { - uint64_t ye, ue, ve; - double frame_psnr; - YV12_BUFFER_CONFIG *orig = cpi->Source; - YV12_BUFFER_CONFIG *recon = cpi->common.frame_to_show; - unsigned int y_width = cpi->common.Width; - unsigned int y_height = cpi->common.Height; - unsigned int uv_width = (y_width + 1) / 2; - unsigned int uv_height = (y_height + 1) / 2; - int y_samples = y_height * y_width; - int uv_samples = uv_height * uv_width; - int t_samples = y_samples + 2 * uv_samples; - double sq_error; - - ye = calc_plane_error(orig->y_buffer, orig->y_stride, recon->y_buffer, - recon->y_stride, y_width, y_height); - - ue = calc_plane_error(orig->u_buffer, orig->uv_stride, recon->u_buffer, - recon->uv_stride, uv_width, uv_height); - - ve = calc_plane_error(orig->v_buffer, orig->uv_stride, recon->v_buffer, - recon->uv_stride, uv_width, uv_height); - - sq_error = (double)(ye + ue + ve); - - frame_psnr = vpx_sse_to_psnr(t_samples, 255.0, sq_error); - - cpi->total_y += vpx_sse_to_psnr(y_samples, 255.0, (double)ye); - cpi->total_u += vpx_sse_to_psnr(uv_samples, 255.0, (double)ue); - cpi->total_v += vpx_sse_to_psnr(uv_samples, 255.0, (double)ve); - cpi->total_sq_error += sq_error; - cpi->total += frame_psnr; -#if CONFIG_POSTPROC - { - YV12_BUFFER_CONFIG *pp = &cm->post_proc_buffer; - double sq_error2; - double frame_psnr2, frame_ssim2 = 0; - double weight = 0; - - vp8_deblock(cm, cm->frame_to_show, &cm->post_proc_buffer, - cm->filter_level * 10 / 6); - vpx_clear_system_state(); - - ye = calc_plane_error(orig->y_buffer, orig->y_stride, pp->y_buffer, - pp->y_stride, y_width, y_height); - - ue = calc_plane_error(orig->u_buffer, orig->uv_stride, pp->u_buffer, - pp->uv_stride, uv_width, uv_height); - - ve = calc_plane_error(orig->v_buffer, orig->uv_stride, pp->v_buffer, - pp->uv_stride, uv_width, uv_height); - - sq_error2 = (double)(ye + ue + ve); - - frame_psnr2 = vpx_sse_to_psnr(t_samples, 255.0, sq_error2); - - cpi->totalp_y += vpx_sse_to_psnr(y_samples, 255.0, (double)ye); - cpi->totalp_u += vpx_sse_to_psnr(uv_samples, 255.0, (double)ue); - cpi->totalp_v += vpx_sse_to_psnr(uv_samples, 255.0, (double)ve); - cpi->total_sq_error2 += sq_error2; - cpi->totalp += frame_psnr2; - - frame_ssim2 = - vpx_calc_ssim(cpi->Source, &cm->post_proc_buffer, &weight); - - cpi->summed_quality += frame_ssim2 * weight; - cpi->summed_weights += weight; - - if (cpi->oxcf.number_of_layers > 1) { - unsigned int i; - - for (i = cpi->current_layer; i < cpi->oxcf.number_of_layers; ++i) { - cpi->frames_in_layer[i]++; - - cpi->bytes_in_layer[i] += *size; - cpi->sum_psnr[i] += frame_psnr; - cpi->sum_psnr_p[i] += frame_psnr2; - cpi->total_error2[i] += sq_error; - cpi->total_error2_p[i] += sq_error2; - cpi->sum_ssim[i] += frame_ssim2 * weight; - cpi->sum_weights[i] += weight; - } - } - } -#endif - } - } - } - -#if 0 - - if (cpi->common.frame_type != 0 && cpi->common.base_qindex == cpi->oxcf.worst_allowed_q) - { - skiptruecount += cpi->skip_true_count; - skipfalsecount += cpi->skip_false_count; - } - -#endif -#if 0 - - if (cpi->pass != 1) - { - FILE *f = fopen("skip.stt", "a"); - fprintf(f, "frame:%4d flags:%4x Q:%4d P:%4d Size:%5d\n", cpi->common.current_video_frame, *frame_flags, cpi->common.base_qindex, cpi->prob_skip_false, *size); - - if (cpi->is_src_frame_alt_ref == 1) - fprintf(f, "skipcount: %4d framesize: %d\n", cpi->skip_true_count , *size); - - fclose(f); - } - -#endif -#endif - - return 0; -} - -int vp8_get_preview_raw_frame(VP8_COMP *cpi, YV12_BUFFER_CONFIG *dest, - vp8_ppflags_t *flags) { - if (cpi->common.refresh_alt_ref_frame) { - return -1; - } else { - int ret; - -#if CONFIG_POSTPROC - cpi->common.show_frame_mi = cpi->common.mi; - ret = vp8_post_proc_frame(&cpi->common, dest, flags); -#else - (void)flags; - - if (cpi->common.frame_to_show) { - *dest = *cpi->common.frame_to_show; - dest->y_width = cpi->common.Width; - dest->y_height = cpi->common.Height; - dest->uv_height = cpi->common.Height / 2; - ret = 0; - } else { - ret = -1; - } - -#endif - vpx_clear_system_state(); - return ret; - } -} - -int vp8_set_roimap(VP8_COMP *cpi, unsigned char *map, unsigned int rows, - unsigned int cols, int delta_q[4], int delta_lf[4], - unsigned int threshold[4]) { - signed char feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; - int internal_delta_q[MAX_MB_SEGMENTS]; - const int range = 63; - int i; - - // Check number of rows and columns match - if (cpi->common.mb_rows != (int)rows || cpi->common.mb_cols != (int)cols) { - return -1; - } - - for (i = 0; i < MAX_MB_SEGMENTS; ++i) { - // Note abs() alone can't be used as the behavior of abs(INT_MIN) is - // undefined. - if (delta_q[i] > range || delta_q[i] < -range || delta_lf[i] > range || - delta_lf[i] < -range) { - return -1; - } - } - - // Also disable segmentation if no deltas are specified. - if (!map || (delta_q[0] == 0 && delta_q[1] == 0 && delta_q[2] == 0 && - delta_q[3] == 0 && delta_lf[0] == 0 && delta_lf[1] == 0 && - delta_lf[2] == 0 && delta_lf[3] == 0 && threshold[0] == 0 && - threshold[1] == 0 && threshold[2] == 0 && threshold[3] == 0)) { - disable_segmentation(cpi); - return 0; - } - - // Translate the external delta q values to internal values. - for (i = 0; i < MAX_MB_SEGMENTS; ++i) { - internal_delta_q[i] = - (delta_q[i] >= 0) ? q_trans[delta_q[i]] : -q_trans[-delta_q[i]]; - } - - /* Set the segmentation Map */ - set_segmentation_map(cpi, map); - - /* Activate segmentation. */ - enable_segmentation(cpi); - - /* Set up the quant segment data */ - feature_data[MB_LVL_ALT_Q][0] = internal_delta_q[0]; - feature_data[MB_LVL_ALT_Q][1] = internal_delta_q[1]; - feature_data[MB_LVL_ALT_Q][2] = internal_delta_q[2]; - feature_data[MB_LVL_ALT_Q][3] = internal_delta_q[3]; - - /* Set up the loop segment data s */ - feature_data[MB_LVL_ALT_LF][0] = delta_lf[0]; - feature_data[MB_LVL_ALT_LF][1] = delta_lf[1]; - feature_data[MB_LVL_ALT_LF][2] = delta_lf[2]; - feature_data[MB_LVL_ALT_LF][3] = delta_lf[3]; - - cpi->segment_encode_breakout[0] = threshold[0]; - cpi->segment_encode_breakout[1] = threshold[1]; - cpi->segment_encode_breakout[2] = threshold[2]; - cpi->segment_encode_breakout[3] = threshold[3]; - - /* Initialise the feature data structure */ - set_segment_data(cpi, &feature_data[0][0], SEGMENT_DELTADATA); - - if (threshold[0] != 0 || threshold[1] != 0 || threshold[2] != 0 || - threshold[3] != 0) - cpi->use_roi_static_threshold = 1; - cpi->cyclic_refresh_mode_enabled = 0; - - return 0; -} - -int vp8_set_active_map(VP8_COMP *cpi, unsigned char *map, unsigned int rows, - unsigned int cols) { - if ((int)rows == cpi->common.mb_rows && (int)cols == cpi->common.mb_cols) { - if (map) { - memcpy(cpi->active_map, map, rows * cols); - cpi->active_map_enabled = 1; - } else { - cpi->active_map_enabled = 0; - } - - return 0; - } else { - return -1; - } -} - -int vp8_set_internal_size(VP8_COMP *cpi, VPX_SCALING_MODE horiz_mode, - VPX_SCALING_MODE vert_mode) { - if (horiz_mode <= VP8E_ONETWO) { - cpi->common.horiz_scale = horiz_mode; - } else { - return -1; - } - - if (vert_mode <= VP8E_ONETWO) { - cpi->common.vert_scale = vert_mode; - } else { - return -1; - } - - return 0; -} - -int vp8_calc_ss_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest) { - int i, j; - int Total = 0; - - unsigned char *src = source->y_buffer; - unsigned char *dst = dest->y_buffer; - - /* Loop through the Y plane raw and reconstruction data summing - * (square differences) - */ - for (i = 0; i < source->y_height; i += 16) { - for (j = 0; j < source->y_width; j += 16) { - unsigned int sse; - Total += vpx_mse16x16(src + j, source->y_stride, dst + j, dest->y_stride, - &sse); - } - - src += 16 * source->y_stride; - dst += 16 * dest->y_stride; - } - - return Total; -} - -int vp8_get_quantizer(VP8_COMP *cpi) { return cpi->common.base_qindex; } diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/onyx_int.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/onyx_int.h deleted file mode 100644 index 0f4550af..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/onyx_int.h +++ /dev/null @@ -1,746 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_ONYX_INT_H_ -#define VPX_VP8_ENCODER_ONYX_INT_H_ - -#include -#include - -#include "vpx_config.h" -#include "vp8/common/onyx.h" -#include "treewriter.h" -#include "tokenize.h" -#include "vp8/common/onyxc_int.h" -#include "vpx_dsp/variance.h" -#include "vpx_util/vpx_pthread.h" -#include "encodemb.h" -#include "vp8/encoder/quantize.h" -#include "vp8/common/entropy.h" -#include "vp8/common/threading.h" -#include "vpx_ports/mem.h" -#include "vpx/internal/vpx_codec_internal.h" -#include "vpx/vp8.h" -#include "mcomp.h" -#include "vp8/common/findnearmv.h" -#include "lookahead.h" -#if CONFIG_TEMPORAL_DENOISING -#include "vp8/encoder/denoising.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define MIN_GF_INTERVAL 4 -#define DEFAULT_GF_INTERVAL 7 - -#define KEY_FRAME_CONTEXT 5 - -#define MAX_LAG_BUFFERS (CONFIG_REALTIME_ONLY ? 1 : 25) - -#define AF_THRESH 25 -#define AF_THRESH2 100 -#define ARF_DECAY_THRESH 12 - -#define MIN_THRESHMULT 32 -#define MAX_THRESHMULT 512 - -#define GF_ZEROMV_ZBIN_BOOST 12 -#define LF_ZEROMV_ZBIN_BOOST 6 -#define MV_ZBIN_BOOST 4 -#define ZBIN_OQ_MAX 192 - -#define VP8_TEMPORAL_ALT_REF !CONFIG_REALTIME_ONLY - -/* vp8 uses 10,000,000 ticks/second as time stamp */ -#define TICKS_PER_SEC 10000000 - -typedef struct { - int kf_indicated; - unsigned int frames_since_key; - unsigned int frames_since_golden; - int filter_level; - int frames_till_gf_update_due; - int recent_ref_frame_usage[MAX_REF_FRAMES]; - - MV_CONTEXT mvc[2]; - int mvcosts[2][MVvals + 1]; - -#ifdef MODE_STATS - int y_modes[5]; - int uv_modes[4]; - int b_modes[10]; - int inter_y_modes[10]; - int inter_uv_modes[4]; - int inter_b_modes[10]; -#endif - - vp8_prob ymode_prob[4], uv_mode_prob[3]; /* interframe intra mode probs */ - vp8_prob kf_ymode_prob[4], kf_uv_mode_prob[3]; /* keyframe "" */ - - int ymode_count[5], uv_mode_count[4]; /* intra MB type cts this frame */ - - int count_mb_ref_frame_usage[MAX_REF_FRAMES]; - - int this_frame_percent_intra; - int last_frame_percent_intra; - -} CODING_CONTEXT; - -typedef struct { - double frame; - double intra_error; - double coded_error; - double ssim_weighted_pred_err; - double pcnt_inter; - double pcnt_motion; - double pcnt_second_ref; - double pcnt_neutral; - double MVr; - double mvr_abs; - double MVc; - double mvc_abs; - double MVrv; - double MVcv; - double mv_in_out_count; - double new_mv_count; - double duration; - double count; -} FIRSTPASS_STATS; - -typedef struct { - int frames_so_far; - double frame_intra_error; - double frame_coded_error; - double frame_pcnt_inter; - double frame_pcnt_motion; - double frame_mvr; - double frame_mvr_abs; - double frame_mvc; - double frame_mvc_abs; - -} ONEPASS_FRAMESTATS; - -typedef enum { - THR_ZERO1 = 0, - THR_DC = 1, - - THR_NEAREST1 = 2, - THR_NEAR1 = 3, - - THR_ZERO2 = 4, - THR_NEAREST2 = 5, - - THR_ZERO3 = 6, - THR_NEAREST3 = 7, - - THR_NEAR2 = 8, - THR_NEAR3 = 9, - - THR_V_PRED = 10, - THR_H_PRED = 11, - THR_TM = 12, - - THR_NEW1 = 13, - THR_NEW2 = 14, - THR_NEW3 = 15, - - THR_SPLIT1 = 16, - THR_SPLIT2 = 17, - THR_SPLIT3 = 18, - - THR_B_PRED = 19 -} THR_MODES; - -typedef enum { DIAMOND = 0, NSTEP = 1, HEX = 2 } SEARCH_METHODS; - -typedef struct { - int RD; - SEARCH_METHODS search_method; - int improved_quant; - int improved_dct; - int auto_filter; - int recode_loop; - int iterative_sub_pixel; - int half_pixel_search; - int quarter_pixel_search; - int thresh_mult[MAX_MODES]; - int max_step_search_steps; - int first_step; - int optimize_coefficients; - - int use_fastquant_for_pick; - int no_skip_block4x4_search; - int improved_mv_pred; - -} SPEED_FEATURES; - -typedef struct { - MACROBLOCK mb; - int segment_counts[MAX_MB_SEGMENTS]; - int totalrate; -} MB_ROW_COMP; - -typedef struct { - TOKENEXTRA *start; - TOKENEXTRA *stop; -} TOKENLIST; - -typedef struct { - int ithread; - void *ptr1; - void *ptr2; -} ENCODETHREAD_DATA; -typedef struct { - int ithread; - void *ptr1; -} LPFTHREAD_DATA; - -enum { - BLOCK_16X8, - BLOCK_8X16, - BLOCK_8X8, - BLOCK_4X4, - BLOCK_16X16, - BLOCK_MAX_SEGMENTS -}; - -typedef struct { - /* Layer configuration */ - double framerate; - int target_bandwidth; /* bits per second */ - - /* Layer specific coding parameters */ - int64_t starting_buffer_level; - int64_t optimal_buffer_level; - int64_t maximum_buffer_size; - int64_t starting_buffer_level_in_ms; - int64_t optimal_buffer_level_in_ms; - int64_t maximum_buffer_size_in_ms; - - int avg_frame_size_for_layer; - - int64_t buffer_level; - int64_t bits_off_target; - - int64_t total_actual_bits; - int64_t total_target_vs_actual; - - int worst_quality; - int active_worst_quality; - int best_quality; - int active_best_quality; - - int ni_av_qi; - int ni_tot_qi; - int ni_frames; - int avg_frame_qindex; - - double rate_correction_factor; - double key_frame_rate_correction_factor; - double gf_rate_correction_factor; - - int zbin_over_quant; - - int inter_frame_target; - int64_t total_byte_count; - - int filter_level; - - int frames_since_last_drop_overshoot; - - int force_maxqp; - - int last_frame_percent_intra; - - int count_mb_ref_frame_usage[MAX_REF_FRAMES]; - - int last_q[2]; -} LAYER_CONTEXT; - -typedef struct VP8_COMP { - DECLARE_ALIGNED(16, short, Y1quant[QINDEX_RANGE][16]); - DECLARE_ALIGNED(16, short, Y1quant_shift[QINDEX_RANGE][16]); - DECLARE_ALIGNED(16, short, Y1zbin[QINDEX_RANGE][16]); - DECLARE_ALIGNED(16, short, Y1round[QINDEX_RANGE][16]); - - DECLARE_ALIGNED(16, short, Y2quant[QINDEX_RANGE][16]); - DECLARE_ALIGNED(16, short, Y2quant_shift[QINDEX_RANGE][16]); - DECLARE_ALIGNED(16, short, Y2zbin[QINDEX_RANGE][16]); - DECLARE_ALIGNED(16, short, Y2round[QINDEX_RANGE][16]); - - DECLARE_ALIGNED(16, short, UVquant[QINDEX_RANGE][16]); - DECLARE_ALIGNED(16, short, UVquant_shift[QINDEX_RANGE][16]); - DECLARE_ALIGNED(16, short, UVzbin[QINDEX_RANGE][16]); - DECLARE_ALIGNED(16, short, UVround[QINDEX_RANGE][16]); - - DECLARE_ALIGNED(16, short, zrun_zbin_boost_y1[QINDEX_RANGE][16]); - DECLARE_ALIGNED(16, short, zrun_zbin_boost_y2[QINDEX_RANGE][16]); - DECLARE_ALIGNED(16, short, zrun_zbin_boost_uv[QINDEX_RANGE][16]); - DECLARE_ALIGNED(16, short, Y1quant_fast[QINDEX_RANGE][16]); - DECLARE_ALIGNED(16, short, Y2quant_fast[QINDEX_RANGE][16]); - DECLARE_ALIGNED(16, short, UVquant_fast[QINDEX_RANGE][16]); - - MACROBLOCK mb; - VP8_COMMON common; - vp8_writer bc[9]; /* one boolcoder for each partition */ - - VP8_CONFIG oxcf; - - struct lookahead_ctx *lookahead; - struct lookahead_entry *source; - struct lookahead_entry *alt_ref_source; - struct lookahead_entry *last_source; - - YV12_BUFFER_CONFIG *Source; - YV12_BUFFER_CONFIG *un_scaled_source; - YV12_BUFFER_CONFIG scaled_source; - YV12_BUFFER_CONFIG *last_frame_unscaled_source; - - unsigned int frames_till_alt_ref_frame; - /* frame in src_buffers has been identified to be encoded as an alt ref */ - int source_alt_ref_pending; - /* an alt ref frame has been encoded and is usable */ - int source_alt_ref_active; - /* source of frame to encode is an exact copy of an alt ref frame */ - int is_src_frame_alt_ref; - - /* golden frame same as last frame ( short circuit gold searches) */ - int gold_is_last; - /* Alt reference frame same as last ( short circuit altref search) */ - int alt_is_last; - /* don't do both alt and gold search ( just do gold). */ - int gold_is_alt; - - YV12_BUFFER_CONFIG pick_lf_lvl_frame; - - TOKENEXTRA *tok; - unsigned int tok_count; - - unsigned int frames_since_key; - unsigned int key_frame_frequency; - unsigned int this_key_frame_forced; - unsigned int next_key_frame_forced; - - /* Ambient reconstruction err target for force key frames */ - int ambient_err; - - unsigned int mode_check_freq[MAX_MODES]; - - int rd_baseline_thresh[MAX_MODES]; - - int RDMULT; - int RDDIV; - - CODING_CONTEXT coding_context; - - /* Rate targeting variables */ - int64_t last_prediction_error; - int64_t last_intra_error; - - int this_frame_target; - int projected_frame_size; - int last_q[2]; /* Separate values for Intra/Inter */ - - double rate_correction_factor; - double key_frame_rate_correction_factor; - double gf_rate_correction_factor; - - int frames_since_golden; - /* Count down till next GF */ - int frames_till_gf_update_due; - - /* GF interval chosen when we coded the last GF */ - int current_gf_interval; - - /* Total bits overspent because of GF boost (cumulative) */ - int gf_overspend_bits; - - /* Used in the few frames following a GF to recover the extra bits - * spent in that GF - */ - int non_gf_bitrate_adjustment; - - /* Extra bits spent on key frames that need to be recovered */ - int kf_overspend_bits; - - /* Current number of bit s to try and recover on each inter frame. */ - int kf_bitrate_adjustment; - int max_gf_interval; - int baseline_gf_interval; - int active_arnr_frames; - - int64_t key_frame_count; - int prior_key_frame_distance[KEY_FRAME_CONTEXT]; - /* Current section per frame bandwidth target */ - int per_frame_bandwidth; - /* Average frame size target for clip */ - int av_per_frame_bandwidth; - /* Minimum allocation that should be used for any frame */ - int min_frame_bandwidth; - int inter_frame_target; - double output_framerate; - int64_t last_time_stamp_seen; - int64_t last_end_time_stamp_seen; - int64_t first_time_stamp_ever; - - int ni_av_qi; - int ni_tot_qi; - int ni_frames; - int avg_frame_qindex; - - int64_t total_byte_count; - - int buffered_mode; - - double framerate; - double ref_framerate; - int64_t buffer_level; - int64_t bits_off_target; - - int rolling_target_bits; - int rolling_actual_bits; - - int long_rolling_target_bits; - int long_rolling_actual_bits; - - int64_t total_actual_bits; - int64_t total_target_vs_actual; /* debug stats */ - - int worst_quality; - int active_worst_quality; - int best_quality; - int active_best_quality; - - int cq_target_quality; - - int drop_frames_allowed; /* Are we permitted to drop frames? */ - int drop_frame; /* Drop this frame? */ -#if defined(DROP_UNCODED_FRAMES) - int drop_frame_count; -#endif - - vp8_prob frame_coef_probs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS] - [ENTROPY_NODES]; - char update_probs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES]; - - unsigned int frame_branch_ct[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS] - [ENTROPY_NODES][2]; - - int gfu_boost; - int kf_boost; - int last_boost; - - int target_bandwidth; /* bits per second */ - struct vpx_codec_pkt_list *output_pkt_list; - -#if 0 - /* Experimental code for lagged and one pass */ - ONEPASS_FRAMESTATS one_pass_frame_stats[MAX_LAG_BUFFERS]; - int one_pass_frame_index; -#endif - - int decimation_factor; - int decimation_count; - - /* for real time encoding */ - int avg_encode_time; /* microsecond */ - int avg_pick_mode_time; /* microsecond */ - int Speed; - int compressor_speed; - - int auto_gold; - int auto_adjust_gold_quantizer; - int auto_worst_q; - int cpu_used; - int pass; - - int prob_intra_coded; - int prob_last_coded; - int prob_gf_coded; - int prob_skip_false; - int last_skip_false_probs[3]; - int last_skip_probs_q[3]; - int recent_ref_frame_usage[MAX_REF_FRAMES]; - - int this_frame_percent_intra; - int last_frame_percent_intra; - - int ref_frame_flags; - - SPEED_FEATURES sf; - - /* Count ZEROMV on all reference frames. */ - int zeromv_count; - int lf_zeromv_pct; - - unsigned char *skin_map; - - unsigned char *segmentation_map; - signed char segment_feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; - unsigned int segment_encode_breakout[MAX_MB_SEGMENTS]; - - unsigned char *active_map; - unsigned int active_map_enabled; - - /* Video conferencing cyclic refresh mode flags. This is a mode - * designed to clean up the background over time in live encoding - * scenarious. It uses segmentation. - */ - int cyclic_refresh_mode_enabled; - int cyclic_refresh_mode_max_mbs_perframe; - int cyclic_refresh_mode_index; - int cyclic_refresh_q; - signed char *cyclic_refresh_map; - // Count on how many (consecutive) times a macroblock uses ZER0MV_LAST. - unsigned char *consec_zero_last; - // Counter that is reset when a block is checked for a mode-bias against - // ZEROMV_LASTREF. - unsigned char *consec_zero_last_mvbias; - - // Frame counter for the temporal pattern. Counter is rest when the temporal - // layers are changed dynamically (run-time change). - unsigned int temporal_pattern_counter; - // Temporal layer id. - int temporal_layer_id; - - // Measure of average squared difference between source and denoised signal. - int mse_source_denoised; - - int force_maxqp; - int frames_since_last_drop_overshoot; - int last_pred_err_mb; - - // GF update for 1 pass cbr. - int gf_update_onepass_cbr; - int gf_interval_onepass_cbr; - int gf_noboost_onepass_cbr; - -#if CONFIG_MULTITHREAD - /* multithread data */ - vpx_atomic_int *mt_current_mb_col; - int mt_current_mb_col_size; - int mt_sync_range; - vpx_atomic_int b_multi_threaded; - int encoding_thread_count; - int b_lpf_running; - - pthread_t *h_encoding_thread; - pthread_t h_filter_thread; - - MB_ROW_COMP *mb_row_ei; - ENCODETHREAD_DATA *en_thread_data; - LPFTHREAD_DATA lpf_thread_data; - - /* events */ - vp8_sem_t *h_event_start_encoding; - vp8_sem_t *h_event_end_encoding; - vp8_sem_t h_event_start_lpf; - vp8_sem_t h_event_end_lpf; -#endif - - TOKENLIST *tplist; - unsigned int partition_sz[MAX_PARTITIONS]; - unsigned char *partition_d[MAX_PARTITIONS]; - unsigned char *partition_d_end[MAX_PARTITIONS]; - - fractional_mv_step_fp *find_fractional_mv_step; - vp8_refining_search_fn_t refining_search_sad; - vp8_diamond_search_fn_t diamond_search_sad; - vp8_variance_fn_ptr_t fn_ptr[BLOCK_MAX_SEGMENTS]; - uint64_t time_receive_data; - uint64_t time_compress_data; - uint64_t time_pick_lpf; - uint64_t time_encode_mb_row; - - int base_skip_false_prob[128]; - - FRAME_CONTEXT lfc_n; /* last frame entropy */ - FRAME_CONTEXT lfc_a; /* last alt ref entropy */ - FRAME_CONTEXT lfc_g; /* last gold ref entropy */ - - struct twopass_rc { - unsigned int section_intra_rating; - double section_max_qfactor; - unsigned int next_iiratio; - unsigned int this_iiratio; - FIRSTPASS_STATS total_stats; - FIRSTPASS_STATS this_frame_stats; - FIRSTPASS_STATS *stats_in, *stats_in_end, *stats_in_start; - FIRSTPASS_STATS total_left_stats; - int first_pass_done; - int64_t bits_left; - int64_t clip_bits_total; - double avg_iiratio; - double modified_error_total; - double modified_error_used; - double modified_error_left; - double kf_intra_err_min; - double gf_intra_err_min; - int frames_to_key; - int maxq_max_limit; - int maxq_min_limit; - int gf_decay_rate; - int static_scene_max_gf_interval; - int kf_bits; - /* Remaining error from uncoded frames in a gf group. */ - int gf_group_error_left; - /* Projected total bits available for a key frame group of frames */ - int64_t kf_group_bits; - /* Error score of frames still to be coded in kf group */ - int64_t kf_group_error_left; - /* Projected Bits available for a group including 1 GF or ARF */ - int64_t gf_group_bits; - /* Bits for the golden frame or ARF */ - int gf_bits; - int alt_extra_bits; - double est_max_qcorrection_factor; - } twopass; - -#if VP8_TEMPORAL_ALT_REF - YV12_BUFFER_CONFIG alt_ref_buffer; - YV12_BUFFER_CONFIG *frames[MAX_LAG_BUFFERS]; - int fixed_divide[512]; -#endif - -#if CONFIG_INTERNAL_STATS - int count; - double total_y; - double total_u; - double total_v; - double total; - double total_sq_error; - double totalp_y; - double totalp_u; - double totalp_v; - double totalp; - double total_sq_error2; - uint64_t bytes; - double summed_quality; - double summed_weights; - unsigned int tot_recode_hits; - - int b_calculate_ssimg; -#endif - int b_calculate_psnr; - - /* Per MB activity measurement */ - unsigned int activity_avg; - unsigned int *mb_activity_map; - - /* Record of which MBs still refer to last golden frame either - * directly or through 0,0 - */ - unsigned char *gf_active_flags; - int gf_active_count; - - int output_partition; - - /* Store last frame's MV info for next frame MV prediction */ - int_mv *lfmv; - int *lf_ref_frame_sign_bias; - int *lf_ref_frame; - - /* force next frame to intra when kf_auto says so */ - int force_next_frame_intra; - - int droppable; - - int initial_width; - int initial_height; - -#if CONFIG_TEMPORAL_DENOISING - VP8_DENOISER denoiser; -#endif - - /* Coding layer state variables */ - unsigned int current_layer; - LAYER_CONTEXT layer_context[VPX_TS_MAX_LAYERS]; - - int64_t frames_in_layer[VPX_TS_MAX_LAYERS]; - int64_t bytes_in_layer[VPX_TS_MAX_LAYERS]; - double sum_psnr[VPX_TS_MAX_LAYERS]; - double sum_psnr_p[VPX_TS_MAX_LAYERS]; - double total_error2[VPX_TS_MAX_LAYERS]; - double total_error2_p[VPX_TS_MAX_LAYERS]; - double sum_ssim[VPX_TS_MAX_LAYERS]; - double sum_weights[VPX_TS_MAX_LAYERS]; - - double total_ssimg_y_in_layer[VPX_TS_MAX_LAYERS]; - double total_ssimg_u_in_layer[VPX_TS_MAX_LAYERS]; - double total_ssimg_v_in_layer[VPX_TS_MAX_LAYERS]; - double total_ssimg_all_in_layer[VPX_TS_MAX_LAYERS]; - -#if CONFIG_MULTI_RES_ENCODING - /* Number of MBs per row at lower-resolution level */ - int mr_low_res_mb_cols; - /* Indicate if lower-res mv info is available */ - unsigned char mr_low_res_mv_avail; -#endif - /* The frame number of each reference frames */ - unsigned int current_ref_frames[MAX_REF_FRAMES]; - // Closest reference frame to current frame. - MV_REFERENCE_FRAME closest_reference_frame; - - struct rd_costs_struct { - int mvcosts[2][MVvals + 1]; - int mvsadcosts[2][MVfpvals + 1]; - int mbmode_cost[2][MB_MODE_COUNT]; - int intra_uv_mode_cost[2][MB_MODE_COUNT]; - int bmode_costs[10][10][10]; - int inter_bmode_costs[B_MODE_COUNT]; - int token_costs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS] - [MAX_ENTROPY_TOKENS]; - } rd_costs; - - // Use the static threshold from ROI settings. - int use_roi_static_threshold; - - int ext_refresh_frame_flags_pending; - - // Always update correction factor used for rate control after each frame for - // realtime encoding. - int rt_always_update_correction_factor; - - // Flag to indicate frame may be dropped due to large expected overshoot, - // and re-encoded on next frame at max_qp. - int rt_drop_recode_on_overshoot; -} VP8_COMP; - -void vp8_initialize_enc(void); - -void vp8_alloc_compressor_data(VP8_COMP *cpi); -int vp8_reverse_trans(int x); -void vp8_reset_temporal_layer_change(VP8_COMP *cpi, const VP8_CONFIG *oxcf, - const int prev_num_layers); -void vp8_init_temporal_layer_context(VP8_COMP *cpi, const VP8_CONFIG *oxcf, - const int layer, - double prev_layer_framerate); -void vp8_update_layer_contexts(VP8_COMP *cpi); -void vp8_save_layer_context(VP8_COMP *cpi); -void vp8_restore_layer_context(VP8_COMP *cpi, const int layer); -void vp8_new_framerate(VP8_COMP *cpi, double framerate); -void vp8_loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm); - -void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, - unsigned char *dest_end, size_t *size); - -void vp8_tokenize_mb(VP8_COMP *, MACROBLOCK *, TOKENEXTRA **); - -void vp8_set_speed_features(VP8_COMP *cpi); - -int vp8_check_drop_buffer(VP8_COMP *cpi); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_ONYX_INT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/pickinter.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/pickinter.c deleted file mode 100644 index ca6c18f4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/pickinter.c +++ /dev/null @@ -1,1353 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include "vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "onyx_int.h" -#include "modecosts.h" -#include "encodeintra.h" -#include "vp8/common/common.h" -#include "vp8/common/entropymode.h" -#include "pickinter.h" -#include "vp8/common/findnearmv.h" -#include "encodemb.h" -#include "vp8/common/reconinter.h" -#include "vp8/common/reconintra.h" -#include "vp8/common/reconintra4x4.h" -#include "vpx_dsp/variance.h" -#include "mcomp.h" -#include "vp8/common/vp8_skin_detection.h" -#include "rdopt.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#if CONFIG_TEMPORAL_DENOISING -#include "denoising.h" -#endif - -#ifdef SPEEDSTATS -extern unsigned int cnt_pm; -#endif - -extern const int vp8_ref_frame_order[MAX_MODES]; -extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES]; - -static int macroblock_corner_grad(unsigned char *signal, int stride, - int offsetx, int offsety, int sgnx, - int sgny) { - int y1 = signal[offsetx * stride + offsety]; - int y2 = signal[offsetx * stride + offsety + sgny]; - int y3 = signal[(offsetx + sgnx) * stride + offsety]; - int y4 = signal[(offsetx + sgnx) * stride + offsety + sgny]; - return VPXMAX(VPXMAX(abs(y1 - y2), abs(y1 - y3)), abs(y1 - y4)); -} - -static int check_dot_artifact_candidate(VP8_COMP *cpi, MACROBLOCK *x, - unsigned char *target_last, int stride, - unsigned char *last_ref, int mb_row, - int mb_col, int channel) { - int threshold1 = 6; - int threshold2 = 3; - unsigned int max_num = (cpi->common.MBs) / 10; - int grad_last = 0; - int grad_source = 0; - int index = mb_row * cpi->common.mb_cols + mb_col; - // Threshold for #consecutive (base layer) frames using zero_last mode. - int num_frames = 30; - int shift = 15; - if (channel > 0) { - shift = 7; - } - if (cpi->oxcf.number_of_layers > 1) { - num_frames = 20; - } - x->zero_last_dot_suppress = 0; - // Blocks on base layer frames that have been using ZEROMV_LAST repeatedly - // (i.e, at least |x| consecutive frames are candidates for increasing the - // rd adjustment for zero_last mode. - // Only allow this for at most |max_num| blocks per frame. - // Don't allow this for screen content input. - if (cpi->current_layer == 0 && - cpi->consec_zero_last_mvbias[index] > num_frames && - x->mbs_zero_last_dot_suppress < max_num && - !cpi->oxcf.screen_content_mode) { - // If this block is checked here, label it so we don't check it again until - // ~|x| framaes later. - x->zero_last_dot_suppress = 1; - // Dot artifact is noticeable as strong gradient at corners of macroblock, - // for flat areas. As a simple detector for now, we look for a high - // corner gradient on last ref, and a smaller gradient on source. - // Check 4 corners, return if any satisfy condition. - // Top-left: - grad_last = macroblock_corner_grad(last_ref, stride, 0, 0, 1, 1); - grad_source = macroblock_corner_grad(target_last, stride, 0, 0, 1, 1); - if (grad_last >= threshold1 && grad_source <= threshold2) { - x->mbs_zero_last_dot_suppress++; - return 1; - } - // Top-right: - grad_last = macroblock_corner_grad(last_ref, stride, 0, shift, 1, -1); - grad_source = macroblock_corner_grad(target_last, stride, 0, shift, 1, -1); - if (grad_last >= threshold1 && grad_source <= threshold2) { - x->mbs_zero_last_dot_suppress++; - return 1; - } - // Bottom-left: - grad_last = macroblock_corner_grad(last_ref, stride, shift, 0, -1, 1); - grad_source = macroblock_corner_grad(target_last, stride, shift, 0, -1, 1); - if (grad_last >= threshold1 && grad_source <= threshold2) { - x->mbs_zero_last_dot_suppress++; - return 1; - } - // Bottom-right: - grad_last = macroblock_corner_grad(last_ref, stride, shift, shift, -1, -1); - grad_source = - macroblock_corner_grad(target_last, stride, shift, shift, -1, -1); - if (grad_last >= threshold1 && grad_source <= threshold2) { - x->mbs_zero_last_dot_suppress++; - return 1; - } - return 0; - } - return 0; -} - -int vp8_skip_fractional_mv_step(MACROBLOCK *mb, BLOCK *b, BLOCKD *d, - int_mv *bestmv, int_mv *ref_mv, - int error_per_bit, - const vp8_variance_fn_ptr_t *vfp, - int *mvcost[2], int *distortion, - unsigned int *sse) { - (void)b; - (void)d; - (void)ref_mv; - (void)error_per_bit; - (void)vfp; - (void)mb; - (void)mvcost; - (void)distortion; - (void)sse; - bestmv->as_mv.row = clamp(bestmv->as_mv.row * 8, SHRT_MIN, SHRT_MAX); - bestmv->as_mv.col = clamp(bestmv->as_mv.col * 8, SHRT_MIN, SHRT_MAX); - return 0; -} - -int vp8_get_inter_mbpred_error(MACROBLOCK *mb, const vp8_variance_fn_ptr_t *vfp, - unsigned int *sse, int_mv this_mv) { - BLOCK *b = &mb->block[0]; - BLOCKD *d = &mb->e_mbd.block[0]; - unsigned char *what = (*(b->base_src) + b->src); - int what_stride = b->src_stride; - int pre_stride = mb->e_mbd.pre.y_stride; - unsigned char *in_what = mb->e_mbd.pre.y_buffer + d->offset; - int in_what_stride = pre_stride; - int xoffset = this_mv.as_mv.col & 7; - int yoffset = this_mv.as_mv.row & 7; - - in_what += (this_mv.as_mv.row >> 3) * pre_stride + (this_mv.as_mv.col >> 3); - - if (xoffset | yoffset) { - return vfp->svf(in_what, in_what_stride, xoffset, yoffset, what, - what_stride, sse); - } else { - return vfp->vf(what, what_stride, in_what, in_what_stride, sse); - } -} - -static int get_prediction_error(BLOCK *be, BLOCKD *b) { - unsigned char *sptr; - unsigned char *dptr; - sptr = (*(be->base_src) + be->src); - dptr = b->predictor; - - return vpx_get4x4sse_cs(sptr, be->src_stride, dptr, 16); -} - -static int pick_intra4x4block(MACROBLOCK *x, int ib, - B_PREDICTION_MODE *best_mode, - const int *mode_costs, int *bestrate, - int *bestdistortion) { - BLOCKD *b = &x->e_mbd.block[ib]; - BLOCK *be = &x->block[ib]; - int dst_stride = x->e_mbd.dst.y_stride; - unsigned char *dst = x->e_mbd.dst.y_buffer + b->offset; - B_PREDICTION_MODE mode; - int best_rd = INT_MAX; - int rate; - int distortion; - - unsigned char *Above = dst - dst_stride; - unsigned char *yleft = dst - 1; - unsigned char top_left = Above[-1]; - - for (mode = B_DC_PRED; mode <= B_HE_PRED; ++mode) { - int this_rd; - - rate = mode_costs[mode]; - - vp8_intra4x4_predict(Above, yleft, dst_stride, mode, b->predictor, 16, - top_left); - distortion = get_prediction_error(be, b); - this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion); - - if (this_rd < best_rd) { - *bestrate = rate; - *bestdistortion = distortion; - best_rd = this_rd; - *best_mode = mode; - } - } - - b->bmi.as_mode = *best_mode; - vp8_encode_intra4x4block(x, ib); - return best_rd; -} - -static int pick_intra4x4mby_modes(MACROBLOCK *mb, int *Rate, int *best_dist) { - MACROBLOCKD *const xd = &mb->e_mbd; - int i; - int cost = mb->mbmode_cost[xd->frame_type][B_PRED]; - int error; - int distortion = 0; - const int *bmode_costs; - - intra_prediction_down_copy(xd, xd->dst.y_buffer - xd->dst.y_stride + 16); - - bmode_costs = mb->inter_bmode_costs; - - for (i = 0; i < 16; ++i) { - MODE_INFO *const mic = xd->mode_info_context; - const int mis = xd->mode_info_stride; - - B_PREDICTION_MODE best_mode = B_MODE_COUNT; - int r = 0, d = 0; - - if (mb->e_mbd.frame_type == KEY_FRAME) { - const B_PREDICTION_MODE A = above_block_mode(mic, i, mis); - const B_PREDICTION_MODE L = left_block_mode(mic, i); - - bmode_costs = mb->bmode_costs[A][L]; - } - - pick_intra4x4block(mb, i, &best_mode, bmode_costs, &r, &d); - - cost += r; - distortion += d; - assert(best_mode != B_MODE_COUNT); - mic->bmi[i].as_mode = best_mode; - - /* Break out case where we have already exceeded best so far value - * that was passed in - */ - if (distortion > *best_dist) break; - } - - *Rate = cost; - - if (i == 16) { - *best_dist = distortion; - error = RDCOST(mb->rdmult, mb->rddiv, cost, distortion); - } else { - *best_dist = INT_MAX; - error = INT_MAX; - } - - return error; -} - -static void pick_intra_mbuv_mode(MACROBLOCK *mb) { - MACROBLOCKD *x = &mb->e_mbd; - unsigned char *uabove_row = x->dst.u_buffer - x->dst.uv_stride; - unsigned char *vabove_row = x->dst.v_buffer - x->dst.uv_stride; - unsigned char *usrc_ptr = (mb->block[16].src + *mb->block[16].base_src); - unsigned char *vsrc_ptr = (mb->block[20].src + *mb->block[20].base_src); - int uvsrc_stride = mb->block[16].src_stride; - unsigned char uleft_col[8]; - unsigned char vleft_col[8]; - unsigned char utop_left = uabove_row[-1]; - unsigned char vtop_left = vabove_row[-1]; - int i, j; - int expected_udc; - int expected_vdc; - int shift; - int Uaverage = 0; - int Vaverage = 0; - int diff; - int pred_error[4] = { 0, 0, 0, 0 }, best_error = INT_MAX; - MB_PREDICTION_MODE best_mode = MB_MODE_COUNT; - - for (i = 0; i < 8; ++i) { - uleft_col[i] = x->dst.u_buffer[i * x->dst.uv_stride - 1]; - vleft_col[i] = x->dst.v_buffer[i * x->dst.uv_stride - 1]; - } - - if (!x->up_available && !x->left_available) { - expected_udc = 128; - expected_vdc = 128; - } else { - shift = 2; - - if (x->up_available) { - for (i = 0; i < 8; ++i) { - Uaverage += uabove_row[i]; - Vaverage += vabove_row[i]; - } - - shift++; - } - - if (x->left_available) { - for (i = 0; i < 8; ++i) { - Uaverage += uleft_col[i]; - Vaverage += vleft_col[i]; - } - - shift++; - } - - expected_udc = (Uaverage + (1 << (shift - 1))) >> shift; - expected_vdc = (Vaverage + (1 << (shift - 1))) >> shift; - } - - for (i = 0; i < 8; ++i) { - for (j = 0; j < 8; ++j) { - int predu = uleft_col[i] + uabove_row[j] - utop_left; - int predv = vleft_col[i] + vabove_row[j] - vtop_left; - int u_p, v_p; - - u_p = usrc_ptr[j]; - v_p = vsrc_ptr[j]; - - if (predu < 0) predu = 0; - - if (predu > 255) predu = 255; - - if (predv < 0) predv = 0; - - if (predv > 255) predv = 255; - - diff = u_p - expected_udc; - pred_error[DC_PRED] += diff * diff; - diff = v_p - expected_vdc; - pred_error[DC_PRED] += diff * diff; - - diff = u_p - uabove_row[j]; - pred_error[V_PRED] += diff * diff; - diff = v_p - vabove_row[j]; - pred_error[V_PRED] += diff * diff; - - diff = u_p - uleft_col[i]; - pred_error[H_PRED] += diff * diff; - diff = v_p - vleft_col[i]; - pred_error[H_PRED] += diff * diff; - - diff = u_p - predu; - pred_error[TM_PRED] += diff * diff; - diff = v_p - predv; - pred_error[TM_PRED] += diff * diff; - } - - usrc_ptr += uvsrc_stride; - vsrc_ptr += uvsrc_stride; - - if (i == 3) { - usrc_ptr = (mb->block[18].src + *mb->block[18].base_src); - vsrc_ptr = (mb->block[22].src + *mb->block[22].base_src); - } - } - - for (i = DC_PRED; i <= TM_PRED; ++i) { - if (best_error > pred_error[i]) { - best_error = pred_error[i]; - best_mode = (MB_PREDICTION_MODE)i; - } - } - - assert(best_mode != MB_MODE_COUNT); - mb->e_mbd.mode_info_context->mbmi.uv_mode = best_mode; -} - -static void update_mvcount(MACROBLOCK *x, int_mv *best_ref_mv) { - MACROBLOCKD *xd = &x->e_mbd; - /* Split MV modes currently not supported when RD is nopt enabled, - * therefore, only need to modify MVcount in NEWMV mode. */ - if (xd->mode_info_context->mbmi.mode == NEWMV) { - const int row_val = - ((xd->mode_info_context->mbmi.mv.as_mv.row - best_ref_mv->as_mv.row) >> - 1); - const int row_idx = mv_max + row_val; - const int col_val = - ((xd->mode_info_context->mbmi.mv.as_mv.col - best_ref_mv->as_mv.col) >> - 1); - const int col_idx = mv_max + col_val; - if (row_idx >= 0 && row_idx < MVvals && col_idx >= 0 && col_idx < MVvals) { - x->MVcount[0][row_idx]++; - x->MVcount[1][col_idx]++; - } - } -} - -#if CONFIG_MULTI_RES_ENCODING -static void get_lower_res_motion_info(VP8_COMP *cpi, MACROBLOCKD *xd, - int *dissim, int *parent_ref_frame, - MB_PREDICTION_MODE *parent_mode, - int_mv *parent_ref_mv, int mb_row, - int mb_col) { - LOWER_RES_MB_INFO *store_mode_info = - ((LOWER_RES_FRAME_INFO *)cpi->oxcf.mr_low_res_mode_info)->mb_info; - unsigned int parent_mb_index; - - /* Consider different down_sampling_factor. */ - { - /* TODO: Removed the loop that supports special down_sampling_factor - * such as 2, 4, 8. Will revisit it if needed. - * Should also try using a look-up table to see if it helps - * performance. */ - int parent_mb_row, parent_mb_col; - - parent_mb_row = mb_row * cpi->oxcf.mr_down_sampling_factor.den / - cpi->oxcf.mr_down_sampling_factor.num; - parent_mb_col = mb_col * cpi->oxcf.mr_down_sampling_factor.den / - cpi->oxcf.mr_down_sampling_factor.num; - parent_mb_index = parent_mb_row * cpi->mr_low_res_mb_cols + parent_mb_col; - } - - /* Read lower-resolution mode & motion result from memory.*/ - *parent_ref_frame = store_mode_info[parent_mb_index].ref_frame; - *parent_mode = store_mode_info[parent_mb_index].mode; - *dissim = store_mode_info[parent_mb_index].dissim; - - /* For highest-resolution encoder, adjust dissim value. Lower its quality - * for good performance. */ - if (cpi->oxcf.mr_encoder_id == (cpi->oxcf.mr_total_resolutions - 1)) - *dissim >>= 1; - - if (*parent_ref_frame != INTRA_FRAME) { - /* Consider different down_sampling_factor. - * The result can be rounded to be more precise, but it takes more time. - */ - (*parent_ref_mv).as_mv.row = store_mode_info[parent_mb_index].mv.as_mv.row * - cpi->oxcf.mr_down_sampling_factor.num / - cpi->oxcf.mr_down_sampling_factor.den; - (*parent_ref_mv).as_mv.col = store_mode_info[parent_mb_index].mv.as_mv.col * - cpi->oxcf.mr_down_sampling_factor.num / - cpi->oxcf.mr_down_sampling_factor.den; - - vp8_clamp_mv2(parent_ref_mv, xd); - } -} -#endif - -static void check_for_encode_breakout(unsigned int sse, MACROBLOCK *x) { - MACROBLOCKD *xd = &x->e_mbd; - - unsigned int threshold = - (xd->block[0].dequant[1] * xd->block[0].dequant[1] >> 4); - - if (threshold < x->encode_breakout) threshold = x->encode_breakout; - - if (sse < threshold) { - /* Check u and v to make sure skip is ok */ - unsigned int sse2 = 0; - - sse2 = VP8_UVSSE(x); - - if (sse2 * 2 < x->encode_breakout) { - x->skip = 1; - } else { - x->skip = 0; - } - } -} - -static int evaluate_inter_mode(unsigned int *sse, int rate2, int *distortion2, - VP8_COMP *cpi, MACROBLOCK *x, int rd_adj) { - MB_PREDICTION_MODE this_mode = x->e_mbd.mode_info_context->mbmi.mode; - int_mv mv = x->e_mbd.mode_info_context->mbmi.mv; - int this_rd; - int denoise_aggressive = 0; - /* Exit early and don't compute the distortion if this macroblock - * is marked inactive. */ - if (cpi->active_map_enabled && x->active_ptr[0] == 0) { - *sse = 0; - *distortion2 = 0; - x->skip = 1; - return INT_MAX; - } - - if ((this_mode != NEWMV) || !(cpi->sf.half_pixel_search) || - cpi->common.full_pixel == 1) { - *distortion2 = - vp8_get_inter_mbpred_error(x, &cpi->fn_ptr[BLOCK_16X16], sse, mv); - } - - this_rd = RDCOST(x->rdmult, x->rddiv, rate2, *distortion2); - -#if CONFIG_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity > 0) { - denoise_aggressive = - (cpi->denoiser.denoiser_mode == kDenoiserOnYUVAggressive) ? 1 : 0; - } -#endif - - // Adjust rd for ZEROMV and LAST, if LAST is the closest reference frame. - // TODO: We should also add condition on distance of closest to current. - if (!cpi->oxcf.screen_content_mode && this_mode == ZEROMV && - x->e_mbd.mode_info_context->mbmi.ref_frame == LAST_FRAME && - (denoise_aggressive || (cpi->closest_reference_frame == LAST_FRAME))) { - // No adjustment if block is considered to be skin area. - if (x->is_skin) rd_adj = 100; - - this_rd = (int)(((int64_t)this_rd) * rd_adj / 100); - } - - check_for_encode_breakout(*sse, x); - return this_rd; -} - -static void calculate_zeromv_rd_adjustment(VP8_COMP *cpi, MACROBLOCK *x, - int *rd_adjustment) { - MODE_INFO *mic = x->e_mbd.mode_info_context; - int_mv mv_l, mv_a, mv_al; - int local_motion_check = 0; - - if (cpi->lf_zeromv_pct > 40) { - /* left mb */ - mic -= 1; - mv_l = mic->mbmi.mv; - - if (mic->mbmi.ref_frame != INTRA_FRAME) { - if (abs(mv_l.as_mv.row) < 8 && abs(mv_l.as_mv.col) < 8) { - local_motion_check++; - } - } - - /* above-left mb */ - mic -= x->e_mbd.mode_info_stride; - mv_al = mic->mbmi.mv; - - if (mic->mbmi.ref_frame != INTRA_FRAME) { - if (abs(mv_al.as_mv.row) < 8 && abs(mv_al.as_mv.col) < 8) { - local_motion_check++; - } - } - - /* above mb */ - mic += 1; - mv_a = mic->mbmi.mv; - - if (mic->mbmi.ref_frame != INTRA_FRAME) { - if (abs(mv_a.as_mv.row) < 8 && abs(mv_a.as_mv.col) < 8) { - local_motion_check++; - } - } - - if (((!x->e_mbd.mb_to_top_edge || !x->e_mbd.mb_to_left_edge) && - local_motion_check > 0) || - local_motion_check > 2) { - *rd_adjustment = 80; - } else if (local_motion_check > 0) { - *rd_adjustment = 90; - } - } -} - -void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, - int recon_uvoffset, int *returnrate, - int *returndistortion, int *returnintra, int mb_row, - int mb_col) { - BLOCK *b = &x->block[0]; - BLOCKD *d = &x->e_mbd.block[0]; - MACROBLOCKD *xd = &x->e_mbd; - MB_MODE_INFO best_mbmode; - - int_mv best_ref_mv_sb[2] = { { 0 }, { 0 } }; - int_mv mode_mv_sb[2][MB_MODE_COUNT]; - int_mv best_ref_mv; - int_mv *mode_mv; - MB_PREDICTION_MODE this_mode; - int num00; - int mdcounts[4]; - int best_rd = INT_MAX; - int rd_adjustment = 100; - int best_intra_rd = INT_MAX; - int mode_index; - int rate; - int rate2; - int distortion2; - int bestsme = INT_MAX; - int best_mode_index = 0; - unsigned int sse = UINT_MAX, best_rd_sse = UINT_MAX; -#if CONFIG_TEMPORAL_DENOISING - unsigned int zero_mv_sse = UINT_MAX, best_sse = UINT_MAX; -#endif - - int sf_improved_mv_pred = cpi->sf.improved_mv_pred; - -#if CONFIG_MULTI_RES_ENCODING - int dissim = INT_MAX; - int parent_ref_frame = 0; - int_mv parent_ref_mv; - MB_PREDICTION_MODE parent_mode = 0; - int parent_ref_valid = 0; -#endif - - int_mv mvp; - - int near_sadidx[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - int saddone = 0; - /* search range got from mv_pred(). It uses step_param levels. (0-7) */ - int sr = 0; - - unsigned char *plane[4][3] = { { 0, 0 } }; - int ref_frame_map[4]; - int sign_bias = 0; - int dot_artifact_candidate = 0; - get_predictor_pointers(cpi, plane, recon_yoffset, recon_uvoffset); - - // If the current frame is using LAST as a reference, check for - // biasing the mode selection for dot artifacts. - if (cpi->ref_frame_flags & VP8_LAST_FRAME) { - unsigned char *target_y = x->src.y_buffer; - unsigned char *target_u = x->block[16].src + *x->block[16].base_src; - unsigned char *target_v = x->block[20].src + *x->block[20].base_src; - int stride = x->src.y_stride; - int stride_uv = x->block[16].src_stride; -#if CONFIG_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity) { - const int uv_denoise = (cpi->oxcf.noise_sensitivity >= 2) ? 1 : 0; - target_y = - cpi->denoiser.yv12_running_avg[LAST_FRAME].y_buffer + recon_yoffset; - stride = cpi->denoiser.yv12_running_avg[LAST_FRAME].y_stride; - if (uv_denoise) { - target_u = cpi->denoiser.yv12_running_avg[LAST_FRAME].u_buffer + - recon_uvoffset; - target_v = cpi->denoiser.yv12_running_avg[LAST_FRAME].v_buffer + - recon_uvoffset; - stride_uv = cpi->denoiser.yv12_running_avg[LAST_FRAME].uv_stride; - } - } -#endif - assert(plane[LAST_FRAME][0] != NULL); - dot_artifact_candidate = check_dot_artifact_candidate( - cpi, x, target_y, stride, plane[LAST_FRAME][0], mb_row, mb_col, 0); - // If not found in Y channel, check UV channel. - if (!dot_artifact_candidate) { - assert(plane[LAST_FRAME][1] != NULL); - dot_artifact_candidate = check_dot_artifact_candidate( - cpi, x, target_u, stride_uv, plane[LAST_FRAME][1], mb_row, mb_col, 1); - if (!dot_artifact_candidate) { - assert(plane[LAST_FRAME][2] != NULL); - dot_artifact_candidate = check_dot_artifact_candidate( - cpi, x, target_v, stride_uv, plane[LAST_FRAME][2], mb_row, mb_col, - 2); - } - } - } - -#if CONFIG_MULTI_RES_ENCODING - // |parent_ref_valid| will be set here if potentially we can do mv resue for - // this higher resol (|cpi->oxcf.mr_encoder_id| > 0) frame. - // |parent_ref_valid| may be reset depending on |parent_ref_frame| for - // the current macroblock below. - parent_ref_valid = cpi->oxcf.mr_encoder_id && cpi->mr_low_res_mv_avail; - if (parent_ref_valid) { - int parent_ref_flag; - - get_lower_res_motion_info(cpi, xd, &dissim, &parent_ref_frame, &parent_mode, - &parent_ref_mv, mb_row, mb_col); - - /* TODO(jkoleszar): The references available (ref_frame_flags) to the - * lower res encoder should match those available to this encoder, but - * there seems to be a situation where this mismatch can happen in the - * case of frame dropping and temporal layers. For example, - * GOLD being disallowed in ref_frame_flags, but being returned as - * parent_ref_frame. - * - * In this event, take the conservative approach of disabling the - * lower res info for this MB. - */ - - parent_ref_flag = 0; - // Note availability for mv reuse is only based on last and golden. - if (parent_ref_frame == LAST_FRAME) - parent_ref_flag = (cpi->ref_frame_flags & VP8_LAST_FRAME); - else if (parent_ref_frame == GOLDEN_FRAME) - parent_ref_flag = (cpi->ref_frame_flags & VP8_GOLD_FRAME); - - // assert(!parent_ref_frame || parent_ref_flag); - - // If |parent_ref_frame| did not match either last or golden then - // shut off mv reuse. - if (parent_ref_frame && !parent_ref_flag) parent_ref_valid = 0; - - // Don't do mv reuse since we want to allow for another mode besides - // ZEROMV_LAST to remove dot artifact. - if (dot_artifact_candidate) parent_ref_valid = 0; - } -#endif - - // Check if current macroblock is in skin area. - x->is_skin = 0; - if (!cpi->oxcf.screen_content_mode) { - int block_index = mb_row * cpi->common.mb_cols + mb_col; - x->is_skin = cpi->skin_map[block_index]; - } -#if CONFIG_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity) { - // Under aggressive denoising mode, should we use skin map to reduce - // denoiser - // and ZEROMV bias? Will need to revisit the accuracy of this detection for - // very noisy input. For now keep this as is (i.e., don't turn it off). - // if (cpi->denoiser.denoiser_mode == kDenoiserOnYUVAggressive) - // x->is_skin = 0; - } -#endif - - mode_mv = mode_mv_sb[sign_bias]; - best_ref_mv.as_int = 0; - memset(mode_mv_sb, 0, sizeof(mode_mv_sb)); - memset(&best_mbmode, 0, sizeof(best_mbmode)); - -/* Setup search priorities */ -#if CONFIG_MULTI_RES_ENCODING - if (parent_ref_valid && parent_ref_frame && dissim < 8) { - ref_frame_map[0] = -1; - ref_frame_map[1] = parent_ref_frame; - ref_frame_map[2] = -1; - ref_frame_map[3] = -1; - } else -#endif - get_reference_search_order(cpi, ref_frame_map); - - /* Check to see if there is at least 1 valid reference frame that we need - * to calculate near_mvs. - */ - if (ref_frame_map[1] > 0) { - sign_bias = vp8_find_near_mvs_bias( - &x->e_mbd, x->e_mbd.mode_info_context, mode_mv_sb, best_ref_mv_sb, - mdcounts, ref_frame_map[1], cpi->common.ref_frame_sign_bias); - - mode_mv = mode_mv_sb[sign_bias]; - best_ref_mv.as_int = best_ref_mv_sb[sign_bias].as_int; - } - - /* Count of the number of MBs tested so far this frame */ - x->mbs_tested_so_far++; - - *returnintra = INT_MAX; - x->skip = 0; - - x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME; - - /* If the frame has big static background and current MB is in low - * motion area, its mode decision is biased to ZEROMV mode. - * No adjustment if cpu_used is <= -12 (i.e., cpi->Speed >= 12). - * At such speed settings, ZEROMV is already heavily favored. - */ - if (cpi->Speed < 12) { - calculate_zeromv_rd_adjustment(cpi, x, &rd_adjustment); - } - -#if CONFIG_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity) { - rd_adjustment = (int)(rd_adjustment * - cpi->denoiser.denoise_pars.pickmode_mv_bias / 100); - } -#endif - - if (dot_artifact_candidate) { - // Bias against ZEROMV_LAST mode. - rd_adjustment = 150; - } - - /* if we encode a new mv this is important - * find the best new motion vector - */ - for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) { - int frame_cost; - int this_rd = INT_MAX; - int this_ref_frame = ref_frame_map[vp8_ref_frame_order[mode_index]]; - - if (best_rd <= x->rd_threshes[mode_index]) continue; - - if (this_ref_frame < 0) continue; - - x->e_mbd.mode_info_context->mbmi.ref_frame = this_ref_frame; - - /* everything but intra */ - if (x->e_mbd.mode_info_context->mbmi.ref_frame) { - x->e_mbd.pre.y_buffer = plane[this_ref_frame][0]; - x->e_mbd.pre.u_buffer = plane[this_ref_frame][1]; - x->e_mbd.pre.v_buffer = plane[this_ref_frame][2]; - - if (sign_bias != cpi->common.ref_frame_sign_bias[this_ref_frame]) { - sign_bias = cpi->common.ref_frame_sign_bias[this_ref_frame]; - mode_mv = mode_mv_sb[sign_bias]; - best_ref_mv.as_int = best_ref_mv_sb[sign_bias].as_int; - } - -#if CONFIG_MULTI_RES_ENCODING - if (parent_ref_valid) { - if (vp8_mode_order[mode_index] == NEARESTMV && - mode_mv[NEARESTMV].as_int == 0) - continue; - if (vp8_mode_order[mode_index] == NEARMV && mode_mv[NEARMV].as_int == 0) - continue; - - if (vp8_mode_order[mode_index] == NEWMV && parent_mode == ZEROMV && - best_ref_mv.as_int == 0) - continue; - else if (vp8_mode_order[mode_index] == NEWMV && dissim == 0 && - best_ref_mv.as_int == parent_ref_mv.as_int) - continue; - } -#endif - } - - /* Check to see if the testing frequency for this mode is at its max - * If so then prevent it from being tested and increase the threshold - * for its testing */ - if (x->mode_test_hit_counts[mode_index] && - (cpi->mode_check_freq[mode_index] > 1)) { - if (x->mbs_tested_so_far <= (cpi->mode_check_freq[mode_index] * - x->mode_test_hit_counts[mode_index])) { - /* Increase the threshold for coding this mode to make it less - * likely to be chosen */ - x->rd_thresh_mult[mode_index] += 4; - - if (x->rd_thresh_mult[mode_index] > MAX_THRESHMULT) { - x->rd_thresh_mult[mode_index] = MAX_THRESHMULT; - } - - x->rd_threshes[mode_index] = - (cpi->rd_baseline_thresh[mode_index] >> 7) * - x->rd_thresh_mult[mode_index]; - continue; - } - } - - /* We have now reached the point where we are going to test the current - * mode so increment the counter for the number of times it has been - * tested */ - x->mode_test_hit_counts[mode_index]++; - - rate2 = 0; - distortion2 = 0; - - this_mode = vp8_mode_order[mode_index]; - - x->e_mbd.mode_info_context->mbmi.mode = this_mode; - x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED; - - /* Work out the cost assosciated with selecting the reference frame */ - frame_cost = x->ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame]; - rate2 += frame_cost; - - /* Only consider ZEROMV/ALTREF_FRAME for alt ref frame, - * unless ARNR filtering is enabled in which case we want - * an unfiltered alternative */ - if (cpi->is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) { - if (this_mode != ZEROMV || - x->e_mbd.mode_info_context->mbmi.ref_frame != ALTREF_FRAME) { - continue; - } - } - - switch (this_mode) { - case B_PRED: - /* Pass best so far to pick_intra4x4mby_modes to use as breakout */ - distortion2 = best_rd_sse; - pick_intra4x4mby_modes(x, &rate, &distortion2); - - if (distortion2 == INT_MAX) { - this_rd = INT_MAX; - } else { - rate2 += rate; - distortion2 = vpx_variance16x16(*(b->base_src), b->src_stride, - x->e_mbd.predictor, 16, &sse); - this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2); - - if (this_rd < best_intra_rd) { - best_intra_rd = this_rd; - *returnintra = distortion2; - } - } - - break; - - case SPLITMV: - - /* Split MV modes currently not supported when RD is not enabled. */ - break; - - case DC_PRED: - case V_PRED: - case H_PRED: - case TM_PRED: - vp8_build_intra_predictors_mby_s( - xd, xd->dst.y_buffer - xd->dst.y_stride, xd->dst.y_buffer - 1, - xd->dst.y_stride, xd->predictor, 16); - distortion2 = vpx_variance16x16(*(b->base_src), b->src_stride, - x->e_mbd.predictor, 16, &sse); - rate2 += x->mbmode_cost[x->e_mbd.frame_type] - [x->e_mbd.mode_info_context->mbmi.mode]; - this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2); - - if (this_rd < best_intra_rd) { - best_intra_rd = this_rd; - *returnintra = distortion2; - } - break; - - case NEWMV: { - int thissme; - int step_param; - int further_steps; - int n = 0; - int sadpb = x->sadperbit16; - int_mv mvp_full; - - int col_min = ((best_ref_mv.as_mv.col + 7) >> 3) - MAX_FULL_PEL_VAL; - int row_min = ((best_ref_mv.as_mv.row + 7) >> 3) - MAX_FULL_PEL_VAL; - int col_max = (best_ref_mv.as_mv.col >> 3) + MAX_FULL_PEL_VAL; - int row_max = (best_ref_mv.as_mv.row >> 3) + MAX_FULL_PEL_VAL; - - int tmp_col_min = x->mv_col_min; - int tmp_col_max = x->mv_col_max; - int tmp_row_min = x->mv_row_min; - int tmp_row_max = x->mv_row_max; - - int speed_adjust = (cpi->Speed > 5) ? ((cpi->Speed >= 8) ? 3 : 2) : 1; - - /* Further step/diamond searches as necessary */ - step_param = cpi->sf.first_step + speed_adjust; - -#if CONFIG_MULTI_RES_ENCODING - /* If lower-res frame is not available for mv reuse (because of - frame dropping or different temporal layer pattern), then higher - resol encoder does motion search without any previous knowledge. - Also, since last frame motion info is not stored, then we can not - use improved_mv_pred. */ - if (cpi->oxcf.mr_encoder_id) sf_improved_mv_pred = 0; - - // Only use parent MV as predictor if this candidate reference frame - // (|this_ref_frame|) is equal to |parent_ref_frame|. - if (parent_ref_valid && (parent_ref_frame == this_ref_frame)) { - /* Use parent MV as predictor. Adjust search range - * accordingly. - */ - mvp.as_int = parent_ref_mv.as_int; - mvp_full.as_mv.col = parent_ref_mv.as_mv.col >> 3; - mvp_full.as_mv.row = parent_ref_mv.as_mv.row >> 3; - - if (dissim <= 32) - step_param += 3; - else if (dissim <= 128) - step_param += 2; - else - step_param += 1; - } else -#endif - { - if (sf_improved_mv_pred) { - if (!saddone) { - vp8_cal_sad(cpi, xd, x, recon_yoffset, &near_sadidx[0]); - saddone = 1; - } - - vp8_mv_pred(cpi, &x->e_mbd, x->e_mbd.mode_info_context, &mvp, - x->e_mbd.mode_info_context->mbmi.ref_frame, - cpi->common.ref_frame_sign_bias, &sr, &near_sadidx[0]); - - sr += speed_adjust; - /* adjust search range according to sr from mv prediction */ - if (sr > step_param) step_param = sr; - - mvp_full.as_mv.col = mvp.as_mv.col >> 3; - mvp_full.as_mv.row = mvp.as_mv.row >> 3; - } else { - mvp.as_int = best_ref_mv.as_int; - mvp_full.as_mv.col = best_ref_mv.as_mv.col >> 3; - mvp_full.as_mv.row = best_ref_mv.as_mv.row >> 3; - } - } - -#if CONFIG_MULTI_RES_ENCODING - if (parent_ref_valid && (parent_ref_frame == this_ref_frame) && - dissim <= 2 && - VPXMAX(abs(best_ref_mv.as_mv.row - parent_ref_mv.as_mv.row), - abs(best_ref_mv.as_mv.col - parent_ref_mv.as_mv.col)) <= 4) { - d->bmi.mv.as_int = mvp_full.as_int; - mode_mv[NEWMV].as_int = mvp_full.as_int; - - cpi->find_fractional_mv_step( - x, b, d, &d->bmi.mv, &best_ref_mv, x->errorperbit, - &cpi->fn_ptr[BLOCK_16X16], cpi->mb.mvcost, &distortion2, &sse); - } else -#endif - { - /* Get intersection of UMV window and valid MV window to - * reduce # of checks in diamond search. */ - if (x->mv_col_min < col_min) x->mv_col_min = col_min; - if (x->mv_col_max > col_max) x->mv_col_max = col_max; - if (x->mv_row_min < row_min) x->mv_row_min = row_min; - if (x->mv_row_max > row_max) x->mv_row_max = row_max; - - further_steps = - (cpi->Speed >= 8) - ? 0 - : (cpi->sf.max_step_search_steps - 1 - step_param); - - if (cpi->sf.search_method == HEX) { -#if CONFIG_MULTI_RES_ENCODING - /* TODO: In higher-res pick_inter_mode, step_param is used to - * modify hex search range. Here, set step_param to 0 not to - * change the behavior in lowest-resolution encoder. - * Will improve it later. - */ - /* Set step_param to 0 to ensure large-range motion search - * when mv reuse if not valid (i.e. |parent_ref_valid| = 0), - * or if this candidate reference frame (|this_ref_frame|) is - * not equal to |parent_ref_frame|. - */ - if (!parent_ref_valid || (parent_ref_frame != this_ref_frame)) - step_param = 0; -#endif - bestsme = vp8_hex_search(x, b, d, &mvp_full, &d->bmi.mv, step_param, - sadpb, &cpi->fn_ptr[BLOCK_16X16], - x->mvsadcost, &best_ref_mv); - mode_mv[NEWMV].as_int = d->bmi.mv.as_int; - } else { - bestsme = cpi->diamond_search_sad( - x, b, d, &mvp_full, &d->bmi.mv, step_param, sadpb, &num00, - &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &best_ref_mv); - mode_mv[NEWMV].as_int = d->bmi.mv.as_int; - - /* Further step/diamond searches as necessary */ - n = num00; - num00 = 0; - - while (n < further_steps) { - n++; - - if (num00) { - num00--; - } else { - thissme = cpi->diamond_search_sad( - x, b, d, &mvp_full, &d->bmi.mv, step_param + n, sadpb, - &num00, &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &best_ref_mv); - if (thissme < bestsme) { - bestsme = thissme; - mode_mv[NEWMV].as_int = d->bmi.mv.as_int; - } else { - d->bmi.mv.as_int = mode_mv[NEWMV].as_int; - } - } - } - } - - x->mv_col_min = tmp_col_min; - x->mv_col_max = tmp_col_max; - x->mv_row_min = tmp_row_min; - x->mv_row_max = tmp_row_max; - - if (bestsme < INT_MAX) { - cpi->find_fractional_mv_step( - x, b, d, &d->bmi.mv, &best_ref_mv, x->errorperbit, - &cpi->fn_ptr[BLOCK_16X16], cpi->mb.mvcost, &distortion2, &sse); - } - } - - mode_mv[NEWMV].as_int = d->bmi.mv.as_int; - // The clamp below is not necessary from the perspective - // of VP8 bitstream, but is added to improve ChromeCast - // mirroring's robustness. Please do not remove. - vp8_clamp_mv2(&mode_mv[this_mode], xd); - /* mv cost; */ - rate2 += - vp8_mv_bit_cost(&mode_mv[NEWMV], &best_ref_mv, cpi->mb.mvcost, 128); - } - // fall through - - case NEARESTMV: - case NEARMV: - if (mode_mv[this_mode].as_int == 0) continue; - // fall through - - case ZEROMV: - - /* Trap vectors that reach beyond the UMV borders - * Note that ALL New MV, Nearest MV Near MV and Zero MV code drops - * through to this point because of the lack of break statements - * in the previous two cases. - */ - if (((mode_mv[this_mode].as_mv.row >> 3) < x->mv_row_min) || - ((mode_mv[this_mode].as_mv.row >> 3) > x->mv_row_max) || - ((mode_mv[this_mode].as_mv.col >> 3) < x->mv_col_min) || - ((mode_mv[this_mode].as_mv.col >> 3) > x->mv_col_max)) { - continue; - } - - rate2 += vp8_cost_mv_ref(this_mode, mdcounts); - x->e_mbd.mode_info_context->mbmi.mv.as_int = mode_mv[this_mode].as_int; - this_rd = evaluate_inter_mode(&sse, rate2, &distortion2, cpi, x, - rd_adjustment); - - break; - default: break; - } - -#if CONFIG_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity) { - /* Store for later use by denoiser. */ - // Don't denoise with GOLDEN OR ALTREF is they are old reference - // frames (greater than MAX_GF_ARF_DENOISE_RANGE frames in past). - int skip_old_reference = ((this_ref_frame != LAST_FRAME) && - (cpi->common.current_video_frame - - cpi->current_ref_frames[this_ref_frame] > - MAX_GF_ARF_DENOISE_RANGE)) - ? 1 - : 0; - if (this_mode == ZEROMV && sse < zero_mv_sse && !skip_old_reference) { - zero_mv_sse = sse; - x->best_zeromv_reference_frame = - x->e_mbd.mode_info_context->mbmi.ref_frame; - } - - // Store the best NEWMV in x for later use in the denoiser. - if (x->e_mbd.mode_info_context->mbmi.mode == NEWMV && sse < best_sse && - !skip_old_reference) { - best_sse = sse; - x->best_sse_inter_mode = NEWMV; - x->best_sse_mv = x->e_mbd.mode_info_context->mbmi.mv; - x->need_to_clamp_best_mvs = - x->e_mbd.mode_info_context->mbmi.need_to_clamp_mvs; - x->best_reference_frame = x->e_mbd.mode_info_context->mbmi.ref_frame; - } - } -#endif - - if (this_rd < best_rd || x->skip) { - /* Note index of best mode */ - best_mode_index = mode_index; - - *returnrate = rate2; - *returndistortion = distortion2; - best_rd_sse = sse; - best_rd = this_rd; - memcpy(&best_mbmode, &x->e_mbd.mode_info_context->mbmi, - sizeof(MB_MODE_INFO)); - - /* Testing this mode gave rise to an improvement in best error - * score. Lower threshold a bit for next time - */ - x->rd_thresh_mult[mode_index] = - (x->rd_thresh_mult[mode_index] >= (MIN_THRESHMULT + 2)) - ? x->rd_thresh_mult[mode_index] - 2 - : MIN_THRESHMULT; - x->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) * - x->rd_thresh_mult[mode_index]; - } - - /* If the mode did not help improve the best error case then raise the - * threshold for testing that mode next time around. - */ - else { - x->rd_thresh_mult[mode_index] += 4; - - if (x->rd_thresh_mult[mode_index] > MAX_THRESHMULT) { - x->rd_thresh_mult[mode_index] = MAX_THRESHMULT; - } - - x->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) * - x->rd_thresh_mult[mode_index]; - } - - if (x->skip) break; - } - - /* Reduce the activation RD thresholds for the best choice mode */ - if ((cpi->rd_baseline_thresh[best_mode_index] > 0) && - (cpi->rd_baseline_thresh[best_mode_index] < (INT_MAX >> 2))) { - int best_adjustment = (x->rd_thresh_mult[best_mode_index] >> 3); - - x->rd_thresh_mult[best_mode_index] = - (x->rd_thresh_mult[best_mode_index] >= - (MIN_THRESHMULT + best_adjustment)) - ? x->rd_thresh_mult[best_mode_index] - best_adjustment - : MIN_THRESHMULT; - x->rd_threshes[best_mode_index] = - (cpi->rd_baseline_thresh[best_mode_index] >> 7) * - x->rd_thresh_mult[best_mode_index]; - } - - { - int this_rdbin = (*returndistortion >> 7); - - if (this_rdbin >= 1024) { - this_rdbin = 1023; - } - - x->error_bins[this_rdbin]++; - } - -#if CONFIG_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity) { - int block_index = mb_row * cpi->common.mb_cols + mb_col; - int reevaluate = 0; - int is_noisy = 0; - if (x->best_sse_inter_mode == DC_PRED) { - /* No best MV found. */ - x->best_sse_inter_mode = best_mbmode.mode; - x->best_sse_mv = best_mbmode.mv; - x->need_to_clamp_best_mvs = best_mbmode.need_to_clamp_mvs; - x->best_reference_frame = best_mbmode.ref_frame; - best_sse = best_rd_sse; - } - // For non-skin blocks that have selected ZEROMV for this current frame, - // and have been selecting ZEROMV_LAST (on the base layer frame) at - // least |x~20| consecutive past frames in a row, label the block for - // possible increase in denoising strength. We also condition this - // labeling on there being significant denoising in the scene - if (cpi->oxcf.noise_sensitivity == 4) { - if (cpi->denoiser.nmse_source_diff > - 70 * cpi->denoiser.threshold_aggressive_mode / 100) { - is_noisy = 1; - } - } else { - if (cpi->mse_source_denoised > 1000) is_noisy = 1; - } - x->increase_denoising = 0; - if (!x->is_skin && x->best_sse_inter_mode == ZEROMV && - (x->best_reference_frame == LAST_FRAME || - x->best_reference_frame == cpi->closest_reference_frame) && - cpi->consec_zero_last[block_index] >= 20 && is_noisy) { - x->increase_denoising = 1; - } - x->denoise_zeromv = 0; - vp8_denoiser_denoise_mb(&cpi->denoiser, x, best_sse, zero_mv_sse, - recon_yoffset, recon_uvoffset, &cpi->common.lf_info, - mb_row, mb_col, block_index, - cpi->consec_zero_last_mvbias[block_index]); - - // Reevaluate ZEROMV after denoising: for large noise content - // (i.e., cpi->mse_source_denoised is above threshold), do this for all - // blocks that did not pick ZEROMV as best mode but are using ZEROMV - // for denoising. Otherwise, always re-evaluate for blocks that picked - // INTRA mode as best mode. - // Avoid blocks that have been biased against ZERO_LAST - // (i.e., dot artifact candidate blocks). - reevaluate = (best_mbmode.ref_frame == INTRA_FRAME) || - (best_mbmode.mode != ZEROMV && x->denoise_zeromv && - cpi->mse_source_denoised > 2000); - if (!dot_artifact_candidate && reevaluate && - x->best_zeromv_reference_frame != INTRA_FRAME) { - int this_rd = 0; - int this_ref_frame = x->best_zeromv_reference_frame; - rd_adjustment = 100; - rate2 = - x->ref_frame_cost[this_ref_frame] + vp8_cost_mv_ref(ZEROMV, mdcounts); - distortion2 = 0; - - /* set up the proper prediction buffers for the frame */ - x->e_mbd.mode_info_context->mbmi.ref_frame = this_ref_frame; - x->e_mbd.pre.y_buffer = plane[this_ref_frame][0]; - x->e_mbd.pre.u_buffer = plane[this_ref_frame][1]; - x->e_mbd.pre.v_buffer = plane[this_ref_frame][2]; - - x->e_mbd.mode_info_context->mbmi.mode = ZEROMV; - x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED; - x->e_mbd.mode_info_context->mbmi.mv.as_int = 0; - this_rd = - evaluate_inter_mode(&sse, rate2, &distortion2, cpi, x, rd_adjustment); - - if (this_rd < best_rd) { - memcpy(&best_mbmode, &x->e_mbd.mode_info_context->mbmi, - sizeof(MB_MODE_INFO)); - } - } - } -#endif - - if (cpi->is_src_frame_alt_ref && - (best_mbmode.mode != ZEROMV || best_mbmode.ref_frame != ALTREF_FRAME)) { - x->e_mbd.mode_info_context->mbmi.mode = ZEROMV; - x->e_mbd.mode_info_context->mbmi.ref_frame = ALTREF_FRAME; - x->e_mbd.mode_info_context->mbmi.mv.as_int = 0; - x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED; - x->e_mbd.mode_info_context->mbmi.mb_skip_coeff = - (cpi->common.mb_no_coeff_skip); - x->e_mbd.mode_info_context->mbmi.partitioning = 0; - - return; - } - - /* set to the best mb mode, this copy can be skip if x->skip since it - * already has the right content */ - if (!x->skip) { - memcpy(&x->e_mbd.mode_info_context->mbmi, &best_mbmode, - sizeof(MB_MODE_INFO)); - } - - if (best_mbmode.mode <= B_PRED) { - /* set mode_info_context->mbmi.uv_mode */ - pick_intra_mbuv_mode(x); - } - - if (sign_bias != - cpi->common.ref_frame_sign_bias[xd->mode_info_context->mbmi.ref_frame]) { - best_ref_mv.as_int = best_ref_mv_sb[!sign_bias].as_int; - } - - update_mvcount(x, &best_ref_mv); -} - -void vp8_pick_intra_mode(MACROBLOCK *x, int *rate) { - int error4x4, error16x16 = INT_MAX; - int rate_, best_rate = 0, distortion, best_sse; - MB_PREDICTION_MODE mode, best_mode = DC_PRED; - int this_rd; - unsigned int sse; - BLOCK *b = &x->block[0]; - MACROBLOCKD *xd = &x->e_mbd; - - xd->mode_info_context->mbmi.ref_frame = INTRA_FRAME; - - pick_intra_mbuv_mode(x); - - for (mode = DC_PRED; mode <= TM_PRED; ++mode) { - xd->mode_info_context->mbmi.mode = mode; - vp8_build_intra_predictors_mby_s(xd, xd->dst.y_buffer - xd->dst.y_stride, - xd->dst.y_buffer - 1, xd->dst.y_stride, - xd->predictor, 16); - distortion = vpx_variance16x16(*(b->base_src), b->src_stride, xd->predictor, - 16, &sse); - rate_ = x->mbmode_cost[xd->frame_type][mode]; - this_rd = RDCOST(x->rdmult, x->rddiv, rate_, distortion); - - if (error16x16 > this_rd) { - error16x16 = this_rd; - best_mode = mode; - best_sse = sse; - best_rate = rate_; - } - } - xd->mode_info_context->mbmi.mode = best_mode; - - error4x4 = pick_intra4x4mby_modes(x, &rate_, &best_sse); - if (error4x4 < error16x16) { - xd->mode_info_context->mbmi.mode = B_PRED; - best_rate = rate_; - } - - *rate = best_rate; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/pickinter.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/pickinter.h deleted file mode 100644 index 392fb415..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/pickinter.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_PICKINTER_H_ -#define VPX_VP8_ENCODER_PICKINTER_H_ -#include "vpx_config.h" -#include "vp8/common/onyxc_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, - int recon_uvoffset, int *returnrate, - int *returndistortion, int *returnintra, - int mb_row, int mb_col); -extern void vp8_pick_intra_mode(MACROBLOCK *x, int *rate); - -extern int vp8_get_inter_mbpred_error(MACROBLOCK *mb, - const vp8_variance_fn_ptr_t *vfp, - unsigned int *sse, int_mv this_mv); -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_PICKINTER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/picklpf.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/picklpf.c deleted file mode 100644 index 498738fd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/picklpf.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "./vpx_scale_rtcd.h" -#include "vp8/common/onyxc_int.h" -#include "onyx_int.h" -#include "vp8/encoder/picklpf.h" -#include "vp8/encoder/quantize.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_scale/vpx_scale.h" -#include "vp8/common/alloccommon.h" -#include "vp8/common/loopfilter.h" -#if VPX_ARCH_ARM -#include "vpx_ports/arm.h" -#endif - -extern int vp8_calc_ss_err(YV12_BUFFER_CONFIG *source, - YV12_BUFFER_CONFIG *dest); - -static void yv12_copy_partial_frame(YV12_BUFFER_CONFIG *src_ybc, - YV12_BUFFER_CONFIG *dst_ybc) { - unsigned char *src_y, *dst_y; - int yheight; - int ystride; - int yoffset; - int linestocopy; - - yheight = src_ybc->y_height; - ystride = src_ybc->y_stride; - - /* number of MB rows to use in partial filtering */ - linestocopy = (yheight >> 4) / PARTIAL_FRAME_FRACTION; - linestocopy = linestocopy ? linestocopy << 4 : 16; /* 16 lines per MB */ - - /* Copy extra 4 so that full filter context is available if filtering done - * on the copied partial frame and not original. Partial filter does mb - * filtering for top row also, which can modify3 pixels above. - */ - linestocopy += 4; - /* partial image starts at ~middle of frame (macroblock border)*/ - yoffset = ystride * (((yheight >> 5) * 16) - 4); - src_y = src_ybc->y_buffer + yoffset; - dst_y = dst_ybc->y_buffer + yoffset; - - // The border will be used in vp8_loop_filter_partial_frame so it needs to be - // extended to avoid a valgrind warning. - const unsigned char *const top_row = src_ybc->y_buffer; - for (int i = yoffset; i < 0; i += ystride, --linestocopy) { - memcpy(dst_y, top_row, ystride); - dst_y += ystride; - src_y += ystride; - } - memcpy(dst_y, src_y, ystride * linestocopy); -} - -static int calc_partial_ssl_err(YV12_BUFFER_CONFIG *source, - YV12_BUFFER_CONFIG *dest) { - int i, j; - int Total = 0; - int srcoffset, dstoffset; - unsigned char *src = source->y_buffer; - unsigned char *dst = dest->y_buffer; - - int linestocopy; - - /* number of MB rows to use in partial filtering */ - linestocopy = (source->y_height >> 4) / PARTIAL_FRAME_FRACTION; - linestocopy = linestocopy ? linestocopy << 4 : 16; /* 16 lines per MB */ - - /* partial image starts at ~middle of frame (macroblock border)*/ - srcoffset = source->y_stride * ((dest->y_height >> 5) * 16); - dstoffset = dest->y_stride * ((dest->y_height >> 5) * 16); - - src += srcoffset; - dst += dstoffset; - - /* Loop through the Y plane raw and reconstruction data summing - * (square differences) - */ - for (i = 0; i < linestocopy; i += 16) { - for (j = 0; j < source->y_width; j += 16) { - unsigned int sse; - Total += vpx_mse16x16(src + j, source->y_stride, dst + j, dest->y_stride, - &sse); - } - - src += 16 * source->y_stride; - dst += 16 * dest->y_stride; - } - - return Total; -} - -/* Enforce a minimum filter level based upon baseline Q */ -static int get_min_filter_level(VP8_COMP *cpi, int base_qindex) { - int min_filter_level; - - if (cpi->source_alt_ref_active && cpi->common.refresh_golden_frame && - !cpi->common.refresh_alt_ref_frame) { - min_filter_level = 0; - } else { - if (base_qindex <= 6) { - min_filter_level = 0; - } else if (base_qindex <= 16) { - min_filter_level = 1; - } else { - min_filter_level = (base_qindex / 8); - } - } - - return min_filter_level; -} - -/* Enforce a maximum filter level based upon baseline Q */ -static int get_max_filter_level(VP8_COMP *cpi, int base_qindex) { - /* PGW August 2006: Highest filter values almost always a bad idea */ - - /* jbb chg: 20100118 - not so any more with this overquant stuff allow - * high values with lots of intra coming in. - */ - int max_filter_level = MAX_LOOP_FILTER; - (void)base_qindex; - - if (cpi->twopass.section_intra_rating > 8) { - max_filter_level = MAX_LOOP_FILTER * 3 / 4; - } - - return max_filter_level; -} - -void vp8cx_pick_filter_level_fast(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) { - VP8_COMMON *cm = &cpi->common; - - int best_err = 0; - int filt_err = 0; - int min_filter_level = get_min_filter_level(cpi, cm->base_qindex); - int max_filter_level = get_max_filter_level(cpi, cm->base_qindex); - int filt_val; - int best_filt_val; - YV12_BUFFER_CONFIG *saved_frame = cm->frame_to_show; - - /* Replace unfiltered frame buffer with a new one */ - cm->frame_to_show = &cpi->pick_lf_lvl_frame; - - if (cm->frame_type == KEY_FRAME) { - cm->sharpness_level = 0; - } else { - cm->sharpness_level = cpi->oxcf.Sharpness; - } - - if (cm->sharpness_level != cm->last_sharpness_level) { - vp8_loop_filter_update_sharpness(&cm->lf_info, cm->sharpness_level); - cm->last_sharpness_level = cm->sharpness_level; - } - - /* Start the search at the previous frame filter level unless it is - * now out of range. - */ - if (cm->filter_level < min_filter_level) { - cm->filter_level = min_filter_level; - } else if (cm->filter_level > max_filter_level) { - cm->filter_level = max_filter_level; - } - - filt_val = cm->filter_level; - best_filt_val = filt_val; - - /* Get the err using the previous frame's filter value. */ - - /* Copy the unfiltered / processed recon buffer to the new buffer */ - yv12_copy_partial_frame(saved_frame, cm->frame_to_show); - vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val); - - best_err = calc_partial_ssl_err(sd, cm->frame_to_show); - - filt_val -= 1 + (filt_val > 10); - - /* Search lower filter levels */ - while (filt_val >= min_filter_level) { - /* Apply the loop filter */ - yv12_copy_partial_frame(saved_frame, cm->frame_to_show); - vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val); - - /* Get the err for filtered frame */ - filt_err = calc_partial_ssl_err(sd, cm->frame_to_show); - - /* Update the best case record or exit loop. */ - if (filt_err < best_err) { - best_err = filt_err; - best_filt_val = filt_val; - } else { - break; - } - - /* Adjust filter level */ - filt_val -= 1 + (filt_val > 10); - } - - /* Search up (note that we have already done filt_val = cm->filter_level) */ - filt_val = cm->filter_level + 1 + (filt_val > 10); - - if (best_filt_val == cm->filter_level) { - /* Resist raising filter level for very small gains */ - best_err -= (best_err >> 10); - - while (filt_val < max_filter_level) { - /* Apply the loop filter */ - yv12_copy_partial_frame(saved_frame, cm->frame_to_show); - - vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val); - - /* Get the err for filtered frame */ - filt_err = calc_partial_ssl_err(sd, cm->frame_to_show); - - /* Update the best case record or exit loop. */ - if (filt_err < best_err) { - /* Do not raise filter level if improvement is < 1 part - * in 4096 - */ - best_err = filt_err - (filt_err >> 10); - - best_filt_val = filt_val; - } else { - break; - } - - /* Adjust filter level */ - filt_val += 1 + (filt_val > 10); - } - } - - cm->filter_level = best_filt_val; - - if (cm->filter_level < min_filter_level) cm->filter_level = min_filter_level; - - if (cm->filter_level > max_filter_level) cm->filter_level = max_filter_level; - - /* restore unfiltered frame pointer */ - cm->frame_to_show = saved_frame; -} - -/* Stub function for now Alt LF not used */ -void vp8cx_set_alt_lf_level(VP8_COMP *cpi, int filt_val) { - MACROBLOCKD *mbd = &cpi->mb.e_mbd; - (void)filt_val; - - mbd->segment_feature_data[MB_LVL_ALT_LF][0] = - cpi->segment_feature_data[MB_LVL_ALT_LF][0]; - mbd->segment_feature_data[MB_LVL_ALT_LF][1] = - cpi->segment_feature_data[MB_LVL_ALT_LF][1]; - mbd->segment_feature_data[MB_LVL_ALT_LF][2] = - cpi->segment_feature_data[MB_LVL_ALT_LF][2]; - mbd->segment_feature_data[MB_LVL_ALT_LF][3] = - cpi->segment_feature_data[MB_LVL_ALT_LF][3]; -} - -void vp8cx_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) { - VP8_COMMON *cm = &cpi->common; - - int best_err = 0; - int filt_err = 0; - int min_filter_level = get_min_filter_level(cpi, cm->base_qindex); - int max_filter_level = get_max_filter_level(cpi, cm->base_qindex); - - int filter_step; - int filt_high = 0; - int filt_mid; - int filt_low = 0; - int filt_best; - int filt_direction = 0; - - /* Bias against raising loop filter and in favor of lowering it */ - int Bias = 0; - - int ss_err[MAX_LOOP_FILTER + 1]; - - YV12_BUFFER_CONFIG *saved_frame = cm->frame_to_show; - - memset(ss_err, 0, sizeof(ss_err)); - - /* Replace unfiltered frame buffer with a new one */ - cm->frame_to_show = &cpi->pick_lf_lvl_frame; - - if (cm->frame_type == KEY_FRAME) { - cm->sharpness_level = 0; - } else { - cm->sharpness_level = cpi->oxcf.Sharpness; - } - - /* Start the search at the previous frame filter level unless it is - * now out of range. - */ - filt_mid = cm->filter_level; - - if (filt_mid < min_filter_level) { - filt_mid = min_filter_level; - } else if (filt_mid > max_filter_level) { - filt_mid = max_filter_level; - } - - /* Define the initial step size */ - filter_step = (filt_mid < 16) ? 4 : filt_mid / 4; - - /* Get baseline error score */ - - /* Copy the unfiltered / processed recon buffer to the new buffer */ - vpx_yv12_copy_y(saved_frame, cm->frame_to_show); - - vp8cx_set_alt_lf_level(cpi, filt_mid); - vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_mid); - - best_err = vp8_calc_ss_err(sd, cm->frame_to_show); - - ss_err[filt_mid] = best_err; - - filt_best = filt_mid; - - while (filter_step > 0) { - Bias = (best_err >> (15 - (filt_mid / 8))) * filter_step; - - if (cpi->twopass.section_intra_rating < 20) { - Bias = Bias * cpi->twopass.section_intra_rating / 20; - } - - filt_high = ((filt_mid + filter_step) > max_filter_level) - ? max_filter_level - : (filt_mid + filter_step); - filt_low = ((filt_mid - filter_step) < min_filter_level) - ? min_filter_level - : (filt_mid - filter_step); - - if ((filt_direction <= 0) && (filt_low != filt_mid)) { - if (ss_err[filt_low] == 0) { - /* Get Low filter error score */ - vpx_yv12_copy_y(saved_frame, cm->frame_to_show); - vp8cx_set_alt_lf_level(cpi, filt_low); - vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_low); - - filt_err = vp8_calc_ss_err(sd, cm->frame_to_show); - ss_err[filt_low] = filt_err; - } else { - filt_err = ss_err[filt_low]; - } - - /* If value is close to the best so far then bias towards a - * lower loop filter value. - */ - if ((filt_err - Bias) < best_err) { - /* Was it actually better than the previous best? */ - if (filt_err < best_err) best_err = filt_err; - - filt_best = filt_low; - } - } - - /* Now look at filt_high */ - if ((filt_direction >= 0) && (filt_high != filt_mid)) { - if (ss_err[filt_high] == 0) { - vpx_yv12_copy_y(saved_frame, cm->frame_to_show); - vp8cx_set_alt_lf_level(cpi, filt_high); - vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_high); - - filt_err = vp8_calc_ss_err(sd, cm->frame_to_show); - ss_err[filt_high] = filt_err; - } else { - filt_err = ss_err[filt_high]; - } - - /* Was it better than the previous best? */ - if (filt_err < (best_err - Bias)) { - best_err = filt_err; - filt_best = filt_high; - } - } - - /* Half the step distance if the best filter value was the same - * as last time - */ - if (filt_best == filt_mid) { - filter_step = filter_step / 2; - filt_direction = 0; - } else { - filt_direction = (filt_best < filt_mid) ? -1 : 1; - filt_mid = filt_best; - } - } - - cm->filter_level = filt_best; - - /* restore unfiltered frame pointer */ - cm->frame_to_show = saved_frame; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/picklpf.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/picklpf.h deleted file mode 100644 index 03597e54..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/picklpf.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_PICKLPF_H_ -#define VPX_VP8_ENCODER_PICKLPF_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -struct VP8_COMP; -struct yv12_buffer_config; - -void vp8cx_pick_filter_level_fast(struct yv12_buffer_config *sd, - struct VP8_COMP *cpi); -void vp8cx_set_alt_lf_level(struct VP8_COMP *cpi, int filt_val); -void vp8cx_pick_filter_level(struct yv12_buffer_config *sd, VP8_COMP *cpi); - -#ifdef __cplusplus -} -#endif - -#endif // VPX_VP8_ENCODER_PICKLPF_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/quantize.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/quantize.h deleted file mode 100644 index 78746c0c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/quantize.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_QUANTIZE_H_ -#define VPX_VP8_ENCODER_QUANTIZE_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -struct VP8_COMP; -struct macroblock; -extern void vp8_quantize_mb(struct macroblock *x); -extern void vp8_quantize_mby(struct macroblock *x); -extern void vp8_quantize_mbuv(struct macroblock *x); -extern void vp8_set_quantizer(struct VP8_COMP *cpi, int Q); -extern void vp8cx_frame_init_quantizer(struct VP8_COMP *cpi); -extern void vp8_update_zbin_extra(struct VP8_COMP *cpi, struct macroblock *x); -extern void vp8cx_mb_init_quantizer(struct VP8_COMP *cpi, struct macroblock *x, - int ok_to_skip); -extern void vp8cx_init_quantizer(struct VP8_COMP *cpi); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_QUANTIZE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/ratectrl.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/ratectrl.c deleted file mode 100644 index 2f75ec9f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/ratectrl.c +++ /dev/null @@ -1,1607 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include - -#include "math.h" -#include "vp8/common/common.h" -#include "ratectrl.h" -#include "vp8/common/entropymode.h" -#include "vpx_mem/vpx_mem.h" -#include "vp8/common/systemdependent.h" -#include "encodemv.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_ports/system_state.h" - -#define MIN_BPB_FACTOR 0.01 -#define MAX_BPB_FACTOR 50 - -extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES]; - -#ifdef MODE_STATS -extern int y_modes[5]; -extern int uv_modes[4]; -extern int b_modes[10]; - -extern int inter_y_modes[10]; -extern int inter_uv_modes[4]; -extern int inter_b_modes[10]; -#endif - -/* Bits Per MB at different Q (Multiplied by 512) */ -#define BPER_MB_NORMBITS 9 - -/* Work in progress recalibration of baseline rate tables based on - * the assumption that bits per mb is inversely proportional to the - * quantizer value. - */ -const int vp8_bits_per_mb[2][QINDEX_RANGE] = { - /* Intra case 450000/Qintra */ - { - 1125000, 900000, 750000, 642857, 562500, 500000, 450000, 450000, 409090, - 375000, 346153, 321428, 300000, 281250, 264705, 264705, 250000, 236842, - 225000, 225000, 214285, 214285, 204545, 204545, 195652, 195652, 187500, - 180000, 180000, 173076, 166666, 160714, 155172, 150000, 145161, 140625, - 136363, 132352, 128571, 125000, 121621, 121621, 118421, 115384, 112500, - 109756, 107142, 104651, 102272, 100000, 97826, 97826, 95744, 93750, - 91836, 90000, 88235, 86538, 84905, 83333, 81818, 80357, 78947, - 77586, 76271, 75000, 73770, 72580, 71428, 70312, 69230, 68181, - 67164, 66176, 65217, 64285, 63380, 62500, 61643, 60810, 60000, - 59210, 59210, 58441, 57692, 56962, 56250, 55555, 54878, 54216, - 53571, 52941, 52325, 51724, 51136, 50561, 49450, 48387, 47368, - 46875, 45918, 45000, 44554, 44117, 43269, 42452, 41666, 40909, - 40178, 39473, 38793, 38135, 36885, 36290, 35714, 35156, 34615, - 34090, 33582, 33088, 32608, 32142, 31468, 31034, 30405, 29801, - 29220, 28662, - }, - /* Inter case 285000/Qinter */ - { - 712500, 570000, 475000, 407142, 356250, 316666, 285000, 259090, 237500, - 219230, 203571, 190000, 178125, 167647, 158333, 150000, 142500, 135714, - 129545, 123913, 118750, 114000, 109615, 105555, 101785, 98275, 95000, - 91935, 89062, 86363, 83823, 81428, 79166, 77027, 75000, 73076, - 71250, 69512, 67857, 66279, 64772, 63333, 61956, 60638, 59375, - 58163, 57000, 55882, 54807, 53773, 52777, 51818, 50892, 50000, - 49137, 47500, 45967, 44531, 43181, 41911, 40714, 39583, 38513, - 37500, 36538, 35625, 34756, 33928, 33139, 32386, 31666, 30978, - 30319, 29687, 29081, 28500, 27941, 27403, 26886, 26388, 25909, - 25446, 25000, 24568, 23949, 23360, 22800, 22265, 21755, 21268, - 20802, 20357, 19930, 19520, 19127, 18750, 18387, 18037, 17701, - 17378, 17065, 16764, 16473, 16101, 15745, 15405, 15079, 14766, - 14467, 14179, 13902, 13636, 13380, 13133, 12895, 12666, 12445, - 12179, 11924, 11632, 11445, 11220, 11003, 10795, 10594, 10401, - 10215, 10035, - } -}; - -static const int kf_boost_qadjustment[QINDEX_RANGE] = { - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 200, 201, - 201, 202, 203, 203, 203, 204, 204, 205, 205, 206, 206, 207, 207, 208, 208, - 209, 209, 210, 210, 211, 211, 212, 212, 213, 213, 214, 214, 215, 215, 216, - 216, 217, 217, 218, 218, 219, 219, 220, 220, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 220, 220, 220, 220, -}; - -/* #define GFQ_ADJUSTMENT (Q+100) */ -#define GFQ_ADJUSTMENT vp8_gf_boost_qadjustment[Q] -const int vp8_gf_boost_qadjustment[QINDEX_RANGE] = { - 80, 82, 84, 86, 88, 90, 92, 94, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, - 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 184, 185, 185, 186, 186, 187, 187, 188, - 188, 189, 189, 190, 190, 191, 191, 192, 192, 193, 193, 194, 194, 194, 194, - 195, 195, 196, 196, 197, 197, 198, 198 -}; - -/* -const int vp8_gf_boost_qadjustment[QINDEX_RANGE] = -{ - 100,101,102,103,104,105,105,106, - 106,107,107,108,109,109,110,111, - 112,113,114,115,116,117,118,119, - 120,121,122,123,124,125,126,127, - 128,129,130,131,132,133,134,135, - 136,137,138,139,140,141,142,143, - 144,145,146,147,148,149,150,151, - 152,153,154,155,156,157,158,159, - 160,161,162,163,164,165,166,167, - 168,169,170,170,171,171,172,172, - 173,173,173,174,174,174,175,175, - 175,176,176,176,177,177,177,177, - 178,178,179,179,180,180,181,181, - 182,182,183,183,184,184,185,185, - 186,186,187,187,188,188,189,189, - 190,190,191,191,192,192,193,193, -}; -*/ - -static const int kf_gf_boost_qlimits[QINDEX_RANGE] = { - 150, 155, 160, 165, 170, 175, 180, 185, 190, 195, 200, 205, 210, 215, 220, - 225, 230, 235, 240, 245, 250, 255, 260, 265, 270, 275, 280, 285, 290, 295, - 300, 305, 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 410, 420, 430, - 440, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540, 550, 560, 570, 580, - 590, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, - 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, - 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, - 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, - 600, 600, 600, 600, 600, 600, 600, 600, -}; - -static const int gf_adjust_table[101] = { - 100, 115, 130, 145, 160, 175, 190, 200, 210, 220, 230, 240, 260, 270, 280, - 290, 300, 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, -}; - -static const int gf_intra_usage_adjustment[20] = { - 125, 120, 115, 110, 105, 100, 95, 85, 80, 75, - 70, 65, 60, 55, 50, 50, 50, 50, 50, 50, -}; - -static const int gf_interval_table[101] = { - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -}; - -static const unsigned int prior_key_frame_weight[KEY_FRAME_CONTEXT] = { 1, 2, 3, - 4, 5 }; - -void vp8_save_coding_context(VP8_COMP *cpi) { - CODING_CONTEXT *const cc = &cpi->coding_context; - - /* Stores a snapshot of key state variables which can subsequently be - * restored with a call to vp8_restore_coding_context. These functions are - * intended for use in a re-code loop in vp8_compress_frame where the - * quantizer value is adjusted between loop iterations. - */ - - cc->frames_since_key = cpi->frames_since_key; - cc->filter_level = cpi->common.filter_level; - cc->frames_till_gf_update_due = cpi->frames_till_gf_update_due; - cc->frames_since_golden = cpi->frames_since_golden; - - vp8_copy(cc->mvc, cpi->common.fc.mvc); - vp8_copy(cc->mvcosts, cpi->rd_costs.mvcosts); - - vp8_copy(cc->ymode_prob, cpi->common.fc.ymode_prob); - vp8_copy(cc->uv_mode_prob, cpi->common.fc.uv_mode_prob); - - vp8_copy(cc->ymode_count, cpi->mb.ymode_count); - vp8_copy(cc->uv_mode_count, cpi->mb.uv_mode_count); - -/* Stats */ -#ifdef MODE_STATS - vp8_copy(cc->y_modes, y_modes); - vp8_copy(cc->uv_modes, uv_modes); - vp8_copy(cc->b_modes, b_modes); - vp8_copy(cc->inter_y_modes, inter_y_modes); - vp8_copy(cc->inter_uv_modes, inter_uv_modes); - vp8_copy(cc->inter_b_modes, inter_b_modes); -#endif - - cc->this_frame_percent_intra = cpi->this_frame_percent_intra; -} - -void vp8_restore_coding_context(VP8_COMP *cpi) { - CODING_CONTEXT *const cc = &cpi->coding_context; - - /* Restore key state variables to the snapshot state stored in the - * previous call to vp8_save_coding_context. - */ - - cpi->frames_since_key = cc->frames_since_key; - cpi->common.filter_level = cc->filter_level; - cpi->frames_till_gf_update_due = cc->frames_till_gf_update_due; - cpi->frames_since_golden = cc->frames_since_golden; - - vp8_copy(cpi->common.fc.mvc, cc->mvc); - - vp8_copy(cpi->rd_costs.mvcosts, cc->mvcosts); - - vp8_copy(cpi->common.fc.ymode_prob, cc->ymode_prob); - vp8_copy(cpi->common.fc.uv_mode_prob, cc->uv_mode_prob); - - vp8_copy(cpi->mb.ymode_count, cc->ymode_count); - vp8_copy(cpi->mb.uv_mode_count, cc->uv_mode_count); - -/* Stats */ -#ifdef MODE_STATS - vp8_copy(y_modes, cc->y_modes); - vp8_copy(uv_modes, cc->uv_modes); - vp8_copy(b_modes, cc->b_modes); - vp8_copy(inter_y_modes, cc->inter_y_modes); - vp8_copy(inter_uv_modes, cc->inter_uv_modes); - vp8_copy(inter_b_modes, cc->inter_b_modes); -#endif - - cpi->this_frame_percent_intra = cc->this_frame_percent_intra; -} - -void vp8_setup_key_frame(VP8_COMP *cpi) { - /* Setup for Key frame: */ - - vp8_default_coef_probs(&cpi->common); - - memcpy(cpi->common.fc.mvc, vp8_default_mv_context, - sizeof(vp8_default_mv_context)); - { - int flag[2] = { 1, 1 }; - vp8_build_component_cost_table( - cpi->mb.mvcost, (const MV_CONTEXT *)cpi->common.fc.mvc, flag); - } - - /* Make sure we initialize separate contexts for altref,gold, and normal. - * TODO shouldn't need 3 different copies of structure to do this! - */ - memcpy(&cpi->lfc_a, &cpi->common.fc, sizeof(cpi->common.fc)); - memcpy(&cpi->lfc_g, &cpi->common.fc, sizeof(cpi->common.fc)); - memcpy(&cpi->lfc_n, &cpi->common.fc, sizeof(cpi->common.fc)); - - cpi->common.filter_level = cpi->common.base_qindex * 3 / 8; - - /* Provisional interval before next GF */ - if (cpi->auto_gold) { - cpi->frames_till_gf_update_due = cpi->baseline_gf_interval; - } else { - cpi->frames_till_gf_update_due = DEFAULT_GF_INTERVAL; - } - - cpi->common.refresh_golden_frame = 1; - cpi->common.refresh_alt_ref_frame = 1; -} - -static int estimate_bits_at_q(int frame_kind, int Q, int MBs, - double correction_factor) { - int Bpm = (int)(.5 + correction_factor * vp8_bits_per_mb[frame_kind][Q]); - - /* Attempt to retain reasonable accuracy without overflow. The cutoff is - * chosen such that the maximum product of Bpm and MBs fits 31 bits. The - * largest Bpm takes 20 bits. - */ - if (MBs > (1 << 11)) { - return (Bpm >> BPER_MB_NORMBITS) * MBs; - } else { - return (Bpm * MBs) >> BPER_MB_NORMBITS; - } -} - -static void calc_iframe_target_size(VP8_COMP *cpi) { - /* boost defaults to half second */ - int kf_boost; - uint64_t target; - - /* Clear down mmx registers to allow floating point in what follows */ - vpx_clear_system_state(); - - if (cpi->oxcf.fixed_q >= 0) { - int Q = cpi->oxcf.key_q; - - target = estimate_bits_at_q(INTRA_FRAME, Q, cpi->common.MBs, - cpi->key_frame_rate_correction_factor); - } else if (cpi->pass == 2) { - /* New Two pass RC */ - target = cpi->per_frame_bandwidth; - } - /* First Frame is a special case */ - else if (cpi->common.current_video_frame == 0) { - /* 1 Pass there is no information on which to base size so use - * bandwidth per second * fraction of the initial buffer - * level - */ - target = (uint64_t)cpi->oxcf.starting_buffer_level / 2; - - if (target > cpi->oxcf.target_bandwidth * 3 / 2) { - target = cpi->oxcf.target_bandwidth * 3 / 2; - } - } else { - /* if this keyframe was forced, use a more recent Q estimate */ - int Q = (cpi->common.frame_flags & FRAMEFLAGS_KEY) ? cpi->avg_frame_qindex - : cpi->ni_av_qi; - - int initial_boost = 32; /* |3.0 * per_frame_bandwidth| */ - /* Boost depends somewhat on frame rate: only used for 1 layer case. */ - if (cpi->oxcf.number_of_layers == 1) { - kf_boost = - VPXMAX(initial_boost, (int)round(2 * cpi->output_framerate - 16)); - // cpi->output_framerate may be as large as 10M. Keep kf_boost small - // enough to allow for integer math when multiplying by values in - // kf_boost_qadjustment[]. - const int kMaxKfBoost = 2000; - if (kf_boost > kMaxKfBoost) kf_boost = kMaxKfBoost; - } else { - /* Initial factor: set target size to: |3.0 * per_frame_bandwidth|. */ - kf_boost = initial_boost; - } - - /* adjustment up based on q: this factor ranges from ~1.2 to 2.2. */ - kf_boost = kf_boost * kf_boost_qadjustment[Q] / 100; - - /* frame separation adjustment ( down) */ - if (cpi->frames_since_key < cpi->output_framerate / 2) { - kf_boost = - (int)(kf_boost * cpi->frames_since_key / (cpi->output_framerate / 2)); - } - - /* Minimal target size is |2* per_frame_bandwidth|. */ - if (kf_boost < 16) kf_boost = 16; - - target = ((uint64_t)(16 + kf_boost) * cpi->per_frame_bandwidth) >> 4; - target = VPXMIN(INT_MAX, target); - } - - if (cpi->oxcf.rc_max_intra_bitrate_pct) { - unsigned int max_rate; - // This product may overflow unsigned int - uint64_t product = cpi->per_frame_bandwidth; - product *= cpi->oxcf.rc_max_intra_bitrate_pct; - product /= 100; - max_rate = (unsigned int)VPXMIN(INT_MAX, product); - - if (target > max_rate) target = max_rate; - } - - cpi->this_frame_target = (int)target; - - /* TODO: if we separate rate targeting from Q targeting, move this. - * Reset the active worst quality to the baseline value for key frames. - */ - if (cpi->pass != 2) cpi->active_worst_quality = cpi->worst_quality; - -#if 0 - { - FILE *f; - - f = fopen("kf_boost.stt", "a"); - fprintf(f, " %8u %10d %10d %10d\n", - cpi->common.current_video_frame, cpi->gfu_boost, cpi->baseline_gf_interval, cpi->source_alt_ref_pending); - - fclose(f); - } -#endif -} - -/* Do the best we can to define the parameters for the next GF based on what - * information we have available. - */ -static void calc_gf_params(VP8_COMP *cpi) { - int Q = - (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q; - int Boost = 0; - - int gf_frame_usage = 0; /* Golden frame usage since last GF */ - int tot_mbs = cpi->recent_ref_frame_usage[INTRA_FRAME] + - cpi->recent_ref_frame_usage[LAST_FRAME] + - cpi->recent_ref_frame_usage[GOLDEN_FRAME] + - cpi->recent_ref_frame_usage[ALTREF_FRAME]; - - int pct_gf_active = (100 * cpi->gf_active_count) / - (cpi->common.mb_rows * cpi->common.mb_cols); - - if (tot_mbs) { - gf_frame_usage = (cpi->recent_ref_frame_usage[GOLDEN_FRAME] + - cpi->recent_ref_frame_usage[ALTREF_FRAME]) * - 100 / tot_mbs; - } - - if (pct_gf_active > gf_frame_usage) gf_frame_usage = pct_gf_active; - - /* Not two pass */ - if (cpi->pass != 2) { - /* Single Pass lagged mode: TBD */ - if (0) { - } - - /* Single Pass compression: Has to use current and historical data */ - else { -#if 0 - /* Experimental code */ - int index = cpi->one_pass_frame_index; - int frames_to_scan = (cpi->max_gf_interval <= MAX_LAG_BUFFERS) ? cpi->max_gf_interval : MAX_LAG_BUFFERS; - - /* ************** Experimental code - incomplete */ - /* - double decay_val = 1.0; - double IIAccumulator = 0.0; - double last_iiaccumulator = 0.0; - double IIRatio; - - cpi->one_pass_frame_index = cpi->common.current_video_frame%MAX_LAG_BUFFERS; - - for ( i = 0; i < (frames_to_scan - 1); i++ ) - { - if ( index < 0 ) - index = MAX_LAG_BUFFERS; - index --; - - if ( cpi->one_pass_frame_stats[index].frame_coded_error > 0.0 ) - { - IIRatio = cpi->one_pass_frame_stats[index].frame_intra_error / cpi->one_pass_frame_stats[index].frame_coded_error; - - if ( IIRatio > 30.0 ) - IIRatio = 30.0; - } - else - IIRatio = 30.0; - - IIAccumulator += IIRatio * decay_val; - - decay_val = decay_val * cpi->one_pass_frame_stats[index].frame_pcnt_inter; - - if ( (i > MIN_GF_INTERVAL) && - ((IIAccumulator - last_iiaccumulator) < 2.0) ) - { - break; - } - last_iiaccumulator = IIAccumulator; - } - - Boost = IIAccumulator*100.0/16.0; - cpi->baseline_gf_interval = i; - - */ -#else - - /*************************************************************/ - /* OLD code */ - - /* Adjust boost based upon ambient Q */ - Boost = GFQ_ADJUSTMENT; - - /* Adjust based upon most recently measure intra usage */ - Boost = Boost * - gf_intra_usage_adjustment[(cpi->this_frame_percent_intra < 15) - ? cpi->this_frame_percent_intra - : 14] / - 100; - - /* Adjust gf boost based upon GF usage since last GF */ - Boost = Boost * gf_adjust_table[gf_frame_usage] / 100; -#endif - } - - /* golden frame boost without recode loop often goes awry. be - * safe by keeping numbers down. - */ - if (!cpi->sf.recode_loop) { - if (cpi->compressor_speed == 2) Boost = Boost / 2; - } - - /* Apply an upper limit based on Q for 1 pass encodes */ - if (Boost > kf_gf_boost_qlimits[Q] && (cpi->pass == 0)) { - Boost = kf_gf_boost_qlimits[Q]; - - /* Apply lower limits to boost. */ - } else if (Boost < 110) { - Boost = 110; - } - - /* Note the boost used */ - cpi->last_boost = Boost; - } - - /* Estimate next interval - * This is updated once the real frame size/boost is known. - */ - if (cpi->oxcf.fixed_q == -1) { - if (cpi->pass == 2) { /* 2 Pass */ - cpi->frames_till_gf_update_due = cpi->baseline_gf_interval; - } else { /* 1 Pass */ - cpi->frames_till_gf_update_due = cpi->baseline_gf_interval; - - if (cpi->last_boost > 750) cpi->frames_till_gf_update_due++; - - if (cpi->last_boost > 1000) cpi->frames_till_gf_update_due++; - - if (cpi->last_boost > 1250) cpi->frames_till_gf_update_due++; - - if (cpi->last_boost >= 1500) cpi->frames_till_gf_update_due++; - - if (gf_interval_table[gf_frame_usage] > cpi->frames_till_gf_update_due) { - cpi->frames_till_gf_update_due = gf_interval_table[gf_frame_usage]; - } - - if (cpi->frames_till_gf_update_due > cpi->max_gf_interval) { - cpi->frames_till_gf_update_due = cpi->max_gf_interval; - } - } - } else { - cpi->frames_till_gf_update_due = cpi->baseline_gf_interval; - } - - /* ARF on or off */ - if (cpi->pass != 2) { - /* For now Alt ref is not allowed except in 2 pass modes. */ - cpi->source_alt_ref_pending = 0; - - /*if ( cpi->oxcf.fixed_q == -1) - { - if ( cpi->oxcf.play_alternate && (cpi->last_boost > (100 + - (AF_THRESH*cpi->frames_till_gf_update_due)) ) ) - cpi->source_alt_ref_pending = 1; - else - cpi->source_alt_ref_pending = 0; - }*/ - } -} - -static void calc_pframe_target_size(VP8_COMP *cpi) { - int min_frame_target; - int old_per_frame_bandwidth = cpi->per_frame_bandwidth; - - if (cpi->current_layer > 0) { - cpi->per_frame_bandwidth = - cpi->layer_context[cpi->current_layer].avg_frame_size_for_layer; - } - - min_frame_target = 0; - - if (cpi->pass == 2) { - min_frame_target = cpi->min_frame_bandwidth; - - if (min_frame_target < (cpi->av_per_frame_bandwidth >> 5)) { - min_frame_target = cpi->av_per_frame_bandwidth >> 5; - } - } else if (min_frame_target < cpi->per_frame_bandwidth / 4) { - min_frame_target = cpi->per_frame_bandwidth / 4; - } - - /* Special alt reference frame case */ - if ((cpi->common.refresh_alt_ref_frame) && - (cpi->oxcf.number_of_layers == 1)) { - if (cpi->pass == 2) { - /* Per frame bit target for the alt ref frame */ - cpi->per_frame_bandwidth = cpi->twopass.gf_bits; - cpi->this_frame_target = cpi->per_frame_bandwidth; - } - - /* One Pass ??? TBD */ - } - - /* Normal frames (gf,and inter) */ - else { - /* 2 pass */ - if (cpi->pass == 2) { - cpi->this_frame_target = cpi->per_frame_bandwidth; - } - /* 1 pass */ - else { - int Adjustment; - /* Make rate adjustment to recover bits spent in key frame - * Test to see if the key frame inter data rate correction - * should still be in force - */ - if (cpi->kf_overspend_bits > 0) { - Adjustment = (cpi->kf_bitrate_adjustment <= cpi->kf_overspend_bits) - ? cpi->kf_bitrate_adjustment - : cpi->kf_overspend_bits; - - if (Adjustment > (cpi->per_frame_bandwidth - min_frame_target)) { - Adjustment = (cpi->per_frame_bandwidth - min_frame_target); - } - - cpi->kf_overspend_bits -= Adjustment; - - /* Calculate an inter frame bandwidth target for the next - * few frames designed to recover any extra bits spent on - * the key frame. - */ - cpi->this_frame_target = cpi->per_frame_bandwidth - Adjustment; - - if (cpi->this_frame_target < min_frame_target) { - cpi->this_frame_target = min_frame_target; - } - } else { - cpi->this_frame_target = cpi->per_frame_bandwidth; - } - - /* If appropriate make an adjustment to recover bits spent on a - * recent GF - */ - if ((cpi->gf_overspend_bits > 0) && - (cpi->this_frame_target > min_frame_target)) { - Adjustment = (cpi->non_gf_bitrate_adjustment <= cpi->gf_overspend_bits) - ? cpi->non_gf_bitrate_adjustment - : cpi->gf_overspend_bits; - - if (Adjustment > (cpi->this_frame_target - min_frame_target)) { - Adjustment = (cpi->this_frame_target - min_frame_target); - } - - cpi->gf_overspend_bits -= Adjustment; - cpi->this_frame_target -= Adjustment; - } - - /* Apply small + and - boosts for non gf frames */ - if ((cpi->last_boost > 150) && (cpi->frames_till_gf_update_due > 0) && - (cpi->current_gf_interval >= (MIN_GF_INTERVAL << 1))) { - /* % Adjustment limited to the range 1% to 10% */ - Adjustment = (cpi->last_boost - 100) >> 5; - - if (Adjustment < 1) { - Adjustment = 1; - } else if (Adjustment > 10) { - Adjustment = 10; - } - - /* Convert to bits */ - Adjustment = (cpi->this_frame_target * Adjustment) / 100; - - if (Adjustment > (cpi->this_frame_target - min_frame_target)) { - Adjustment = (cpi->this_frame_target - min_frame_target); - } - - if (cpi->frames_since_golden == (cpi->current_gf_interval >> 1)) { - Adjustment = (cpi->current_gf_interval - 1) * Adjustment; - // Limit adjustment to 10% of current target. - if (Adjustment > (10 * cpi->this_frame_target) / 100) { - Adjustment = (10 * cpi->this_frame_target) / 100; - } - cpi->this_frame_target += Adjustment; - } else { - cpi->this_frame_target -= Adjustment; - } - } - } - } - - /* Sanity check that the total sum of adjustments is not above the - * maximum allowed That is that having allowed for KF and GF penalties - * we have not pushed the current interframe target to low. If the - * adjustment we apply here is not capable of recovering all the extra - * bits we have spent in the KF or GF then the remainder will have to - * be recovered over a longer time span via other buffer / rate control - * mechanisms. - */ - if (cpi->this_frame_target < min_frame_target) { - cpi->this_frame_target = min_frame_target; - } - - if (!cpi->common.refresh_alt_ref_frame) { - /* Note the baseline target data rate for this inter frame. */ - cpi->inter_frame_target = cpi->this_frame_target; - } - - /* One Pass specific code */ - if (cpi->pass == 0) { - /* Adapt target frame size with respect to any buffering constraints: */ - if (cpi->buffered_mode) { - int one_percent_bits = (int)(1 + cpi->oxcf.optimal_buffer_level / 100); - - if ((cpi->buffer_level < cpi->oxcf.optimal_buffer_level) || - (cpi->bits_off_target < cpi->oxcf.optimal_buffer_level)) { - int percent_low = 0; - - /* Decide whether or not we need to adjust the frame data - * rate target. - * - * If we are are below the optimal buffer fullness level - * and adherence to buffering constraints is important to - * the end usage then adjust the per frame target. - */ - if ((cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) && - (cpi->buffer_level < cpi->oxcf.optimal_buffer_level)) { - percent_low = - (int)((cpi->oxcf.optimal_buffer_level - cpi->buffer_level) / - one_percent_bits); - } - /* Are we overshooting the long term clip data rate... */ - else if (cpi->bits_off_target < 0) { - /* Adjust per frame data target downwards to compensate. */ - percent_low = - (int)(100 * -cpi->bits_off_target / (cpi->total_byte_count * 8)); - } - - if (percent_low > cpi->oxcf.under_shoot_pct) { - percent_low = cpi->oxcf.under_shoot_pct; - } else if (percent_low < 0) { - percent_low = 0; - } - - /* lower the target bandwidth for this frame. */ - cpi->this_frame_target -= - (int)(((int64_t)cpi->this_frame_target * percent_low) / 200); - - /* Are we using allowing control of active_worst_allowed_q - * according to buffer level. - */ - if (cpi->auto_worst_q && cpi->ni_frames > 150) { - int64_t critical_buffer_level; - - /* For streaming applications the most important factor is - * cpi->buffer_level as this takes into account the - * specified short term buffering constraints. However, - * hitting the long term clip data rate target is also - * important. - */ - if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { - /* Take the smaller of cpi->buffer_level and - * cpi->bits_off_target - */ - critical_buffer_level = (cpi->buffer_level < cpi->bits_off_target) - ? cpi->buffer_level - : cpi->bits_off_target; - } - /* For local file playback short term buffering constraints - * are less of an issue - */ - else { - /* Consider only how we are doing for the clip as a - * whole - */ - critical_buffer_level = cpi->bits_off_target; - } - - /* Set the active worst quality based upon the selected - * buffer fullness number. - */ - if (critical_buffer_level < cpi->oxcf.optimal_buffer_level) { - if (critical_buffer_level > (cpi->oxcf.optimal_buffer_level >> 2)) { - int64_t qadjustment_range = cpi->worst_quality - cpi->ni_av_qi; - int64_t above_base = (critical_buffer_level - - (cpi->oxcf.optimal_buffer_level >> 2)); - - /* Step active worst quality down from - * cpi->ni_av_qi when (critical_buffer_level == - * cpi->optimal_buffer_level) to - * cpi->worst_quality when - * (critical_buffer_level == - * cpi->optimal_buffer_level >> 2) - */ - cpi->active_worst_quality = - cpi->worst_quality - - (int)((qadjustment_range * above_base) / - (cpi->oxcf.optimal_buffer_level * 3 >> 2)); - } else { - cpi->active_worst_quality = cpi->worst_quality; - } - } else { - cpi->active_worst_quality = cpi->ni_av_qi; - } - } else { - cpi->active_worst_quality = cpi->worst_quality; - } - } else { - int percent_high = 0; - int64_t target = cpi->this_frame_target; - - if ((cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) && - (cpi->buffer_level > cpi->oxcf.optimal_buffer_level)) { - percent_high = - (int)((cpi->buffer_level - cpi->oxcf.optimal_buffer_level) / - one_percent_bits); - } else if (cpi->bits_off_target > cpi->oxcf.optimal_buffer_level) { - if (cpi->total_byte_count > 0) { - percent_high = (int)((100 * cpi->bits_off_target) / - (cpi->total_byte_count * 8)); - } else { - percent_high = cpi->oxcf.over_shoot_pct; - } - } - - if (percent_high > cpi->oxcf.over_shoot_pct) { - percent_high = cpi->oxcf.over_shoot_pct; - } else if (percent_high < 0) { - percent_high = 0; - } - - target += (target * percent_high) / 200; - target = VPXMIN(target, INT_MAX); - cpi->this_frame_target = (int)target; - - /* Are we allowing control of active_worst_allowed_q according - * to buffer level. - */ - if (cpi->auto_worst_q && cpi->ni_frames > 150) { - /* When using the relaxed buffer model stick to the - * user specified value - */ - cpi->active_worst_quality = cpi->ni_av_qi; - } else { - cpi->active_worst_quality = cpi->worst_quality; - } - } - - /* Set active_best_quality to prevent quality rising too high */ - cpi->active_best_quality = cpi->best_quality; - - /* Worst quality obviously must not be better than best quality */ - if (cpi->active_worst_quality <= cpi->active_best_quality) { - cpi->active_worst_quality = cpi->active_best_quality + 1; - } - - if (cpi->active_worst_quality > 127) cpi->active_worst_quality = 127; - } - /* Unbuffered mode (eg. video conferencing) */ - else { - /* Set the active worst quality */ - cpi->active_worst_quality = cpi->worst_quality; - } - - /* Special trap for constrained quality mode - * "active_worst_quality" may never drop below cq level - * for any frame type. - */ - if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY && - cpi->active_worst_quality < cpi->cq_target_quality) { - cpi->active_worst_quality = cpi->cq_target_quality; - } - } - - /* Test to see if we have to drop a frame - * The auto-drop frame code is only used in buffered mode. - * In unbufferd mode (eg vide conferencing) the descision to - * code or drop a frame is made outside the codec in response to real - * world comms or buffer considerations. - */ - if (cpi->drop_frames_allowed && - (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) && - ((cpi->common.frame_type != KEY_FRAME))) { - /* Check for a buffer underun-crisis in which case we have to drop - * a frame - */ - if ((cpi->buffer_level < 0)) { -#if 0 - FILE *f = fopen("dec.stt", "a"); - fprintf(f, "%10d %10d %10d %10d ***** BUFFER EMPTY\n", - (int) cpi->common.current_video_frame, - cpi->decimation_factor, cpi->common.horiz_scale, - (cpi->buffer_level * 100) / cpi->oxcf.optimal_buffer_level); - fclose(f); -#endif - cpi->drop_frame = 1; - - /* Update the buffer level variable. */ - cpi->bits_off_target += cpi->av_per_frame_bandwidth; - if (cpi->bits_off_target > cpi->oxcf.maximum_buffer_size) { - cpi->bits_off_target = (int)cpi->oxcf.maximum_buffer_size; - } - cpi->buffer_level = cpi->bits_off_target; - - if (cpi->oxcf.number_of_layers > 1) { - unsigned int i; - - // Propagate bits saved by dropping the frame to higher layers. - for (i = cpi->current_layer + 1; i < cpi->oxcf.number_of_layers; ++i) { - LAYER_CONTEXT *lc = &cpi->layer_context[i]; - lc->bits_off_target += (int)(lc->target_bandwidth / lc->framerate); - if (lc->bits_off_target > lc->maximum_buffer_size) { - lc->bits_off_target = lc->maximum_buffer_size; - } - lc->buffer_level = lc->bits_off_target; - } - } - } - } - - /* Adjust target frame size for Golden Frames: */ - if (cpi->oxcf.error_resilient_mode == 0 && - (cpi->frames_till_gf_update_due == 0) && !cpi->drop_frame) { - if (!cpi->gf_update_onepass_cbr) { - int Q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] - : cpi->oxcf.fixed_q; - - int gf_frame_usage = 0; /* Golden frame usage since last GF */ - int tot_mbs = cpi->recent_ref_frame_usage[INTRA_FRAME] + - cpi->recent_ref_frame_usage[LAST_FRAME] + - cpi->recent_ref_frame_usage[GOLDEN_FRAME] + - cpi->recent_ref_frame_usage[ALTREF_FRAME]; - - int pct_gf_active = (100 * cpi->gf_active_count) / - (cpi->common.mb_rows * cpi->common.mb_cols); - - if (tot_mbs) { - gf_frame_usage = (cpi->recent_ref_frame_usage[GOLDEN_FRAME] + - cpi->recent_ref_frame_usage[ALTREF_FRAME]) * - 100 / tot_mbs; - } - - if (pct_gf_active > gf_frame_usage) gf_frame_usage = pct_gf_active; - - /* Is a fixed manual GF frequency being used */ - if (cpi->auto_gold) { - /* For one pass throw a GF if recent frame intra usage is - * low or the GF usage is high - */ - if ((cpi->pass == 0) && - (cpi->this_frame_percent_intra < 15 || gf_frame_usage >= 5)) { - cpi->common.refresh_golden_frame = 1; - - /* Two pass GF descision */ - } else if (cpi->pass == 2) { - cpi->common.refresh_golden_frame = 1; - } - } - -#if 0 - - /* Debug stats */ - if (0) { - FILE *f; - - f = fopen("gf_usaget.stt", "a"); - fprintf(f, " %8ld %10ld %10ld %10ld %10ld\n", - cpi->common.current_video_frame, cpi->gfu_boost, - GFQ_ADJUSTMENT, cpi->gfu_boost, gf_frame_usage); - fclose(f); - } - -#endif - - if (cpi->common.refresh_golden_frame == 1) { -#if 0 - - if (0) { - FILE *f; - - f = fopen("GFexit.stt", "a"); - fprintf(f, "%8ld GF coded\n", cpi->common.current_video_frame); - fclose(f); - } - -#endif - - if (cpi->auto_adjust_gold_quantizer) { - calc_gf_params(cpi); - } - - /* If we are using alternate ref instead of gf then do not apply the - * boost It will instead be applied to the altref update Jims - * modified boost - */ - if (!cpi->source_alt_ref_active) { - if (cpi->oxcf.fixed_q < 0) { - if (cpi->pass == 2) { - /* The spend on the GF is defined in the two pass - * code for two pass encodes - */ - cpi->this_frame_target = cpi->per_frame_bandwidth; - } else { - int Boost = cpi->last_boost; - int frames_in_section = cpi->frames_till_gf_update_due + 1; - int allocation_chunks = (frames_in_section * 100) + (Boost - 100); - int bits_in_section = cpi->inter_frame_target * frames_in_section; - - /* Normalize Altboost and allocations chunck down to - * prevent overflow - */ - while (Boost > 1000) { - Boost /= 2; - allocation_chunks /= 2; - } - - /* Avoid loss of precision but avoid overflow */ - if ((bits_in_section >> 7) > allocation_chunks) { - cpi->this_frame_target = - Boost * (bits_in_section / allocation_chunks); - } else { - cpi->this_frame_target = - (Boost * bits_in_section) / allocation_chunks; - } - } - } else { - cpi->this_frame_target = - (estimate_bits_at_q(1, Q, cpi->common.MBs, 1.0) * - cpi->last_boost) / - 100; - } - } else { - /* If there is an active ARF at this location use the minimum - * bits on this frame even if it is a contructed arf. - * The active maximum quantizer insures that an appropriate - * number of bits will be spent if needed for contstructed ARFs. - */ - cpi->this_frame_target = 0; - } - - cpi->current_gf_interval = cpi->frames_till_gf_update_due; - } - } else { - // Special case for 1 pass CBR: fixed gf period. - // TODO(marpan): Adjust this boost/interval logic. - // If gf_cbr_boost_pct is small (below threshold) set the flag - // gf_noboost_onepass_cbr = 1, which forces the gf to use the same - // rate correction factor as last. - cpi->gf_noboost_onepass_cbr = (cpi->oxcf.gf_cbr_boost_pct <= 100); - cpi->baseline_gf_interval = cpi->gf_interval_onepass_cbr; - // Skip this update if the zero_mvcount is low. - if (cpi->zeromv_count > (cpi->common.MBs >> 1)) { - cpi->common.refresh_golden_frame = 1; - cpi->this_frame_target = - (cpi->this_frame_target * (100 + cpi->oxcf.gf_cbr_boost_pct)) / 100; - } - cpi->frames_till_gf_update_due = cpi->baseline_gf_interval; - cpi->current_gf_interval = cpi->frames_till_gf_update_due; - } - } - - cpi->per_frame_bandwidth = old_per_frame_bandwidth; -} - -void vp8_update_rate_correction_factors(VP8_COMP *cpi, int damp_var) { - int Q = cpi->common.base_qindex; - int correction_factor = 100; - double rate_correction_factor; - double adjustment_limit; - - int projected_size_based_on_q = 0; - - /* Clear down mmx registers to allow floating point in what follows */ - vpx_clear_system_state(); - - if (cpi->common.frame_type == KEY_FRAME) { - rate_correction_factor = cpi->key_frame_rate_correction_factor; - } else { - if (cpi->oxcf.number_of_layers == 1 && !cpi->gf_noboost_onepass_cbr && - (cpi->common.refresh_alt_ref_frame || - cpi->common.refresh_golden_frame)) { - rate_correction_factor = cpi->gf_rate_correction_factor; - } else { - rate_correction_factor = cpi->rate_correction_factor; - } - } - - /* Work out how big we would have expected the frame to be at this Q - * given the current correction factor. Stay in double to avoid int - * overflow when values are large - */ - projected_size_based_on_q = - (int)(((.5 + rate_correction_factor * - vp8_bits_per_mb[cpi->common.frame_type][Q]) * - cpi->common.MBs) / - (1 << BPER_MB_NORMBITS)); - - /* Make some allowance for cpi->zbin_over_quant */ - if (cpi->mb.zbin_over_quant > 0) { - int Z = cpi->mb.zbin_over_quant; - double Factor = 0.99; - double factor_adjustment = 0.01 / 256.0; - - while (Z > 0) { - Z--; - projected_size_based_on_q = (int)(Factor * projected_size_based_on_q); - Factor += factor_adjustment; - - if (Factor >= 0.999) Factor = 0.999; - } - } - - /* Work out a size correction factor. */ - if (projected_size_based_on_q > 0) { - correction_factor = (int)((100 * (int64_t)cpi->projected_frame_size) / - projected_size_based_on_q); - } - - /* More heavily damped adjustment used if we have been oscillating - * either side of target - */ - switch (damp_var) { - case 0: adjustment_limit = 0.75; break; - case 1: adjustment_limit = 0.375; break; - case 2: - default: adjustment_limit = 0.25; break; - } - - if (correction_factor > 102) { - /* We are not already at the worst allowable quality */ - correction_factor = - (int)(100.5 + ((correction_factor - 100) * adjustment_limit)); - rate_correction_factor = - ((rate_correction_factor * correction_factor) / 100); - - /* Keep rate_correction_factor within limits */ - if (rate_correction_factor > MAX_BPB_FACTOR) { - rate_correction_factor = MAX_BPB_FACTOR; - } - } else if (correction_factor < 99) { - /* We are not already at the best allowable quality */ - correction_factor = - (int)(100.5 - ((100 - correction_factor) * adjustment_limit)); - rate_correction_factor = - ((rate_correction_factor * correction_factor) / 100); - - /* Keep rate_correction_factor within limits */ - if (rate_correction_factor < MIN_BPB_FACTOR) { - rate_correction_factor = MIN_BPB_FACTOR; - } - } - - if (cpi->common.frame_type == KEY_FRAME) { - cpi->key_frame_rate_correction_factor = rate_correction_factor; - } else { - if (cpi->oxcf.number_of_layers == 1 && !cpi->gf_noboost_onepass_cbr && - (cpi->common.refresh_alt_ref_frame || - cpi->common.refresh_golden_frame)) { - cpi->gf_rate_correction_factor = rate_correction_factor; - } else { - cpi->rate_correction_factor = rate_correction_factor; - } - } -} - -static int limit_q_cbr_inter(int last_q, int current_q) { - int limit_down = 12; - if (last_q - current_q > limit_down) - return (last_q - limit_down); - else - return current_q; -} - -int vp8_regulate_q(VP8_COMP *cpi, int target_bits_per_frame) { - int Q = cpi->active_worst_quality; - - if (cpi->force_maxqp == 1) { - cpi->active_worst_quality = cpi->worst_quality; - return cpi->worst_quality; - } - /* Reset Zbin OQ value */ - cpi->mb.zbin_over_quant = 0; - - if (cpi->oxcf.fixed_q >= 0) { - Q = cpi->oxcf.fixed_q; - - if (cpi->common.frame_type == KEY_FRAME) { - Q = cpi->oxcf.key_q; - } else if (cpi->oxcf.number_of_layers == 1 && - cpi->common.refresh_alt_ref_frame && - !cpi->gf_noboost_onepass_cbr) { - Q = cpi->oxcf.alt_q; - } else if (cpi->oxcf.number_of_layers == 1 && - cpi->common.refresh_golden_frame && - !cpi->gf_noboost_onepass_cbr) { - Q = cpi->oxcf.gold_q; - } - } else { - int i; - int last_error = INT_MAX; - int target_bits_per_mb; - int bits_per_mb_at_this_q; - double correction_factor; - - /* Select the appropriate correction factor based upon type of frame. */ - if (cpi->common.frame_type == KEY_FRAME) { - correction_factor = cpi->key_frame_rate_correction_factor; - } else { - if (cpi->oxcf.number_of_layers == 1 && !cpi->gf_noboost_onepass_cbr && - (cpi->common.refresh_alt_ref_frame || - cpi->common.refresh_golden_frame)) { - correction_factor = cpi->gf_rate_correction_factor; - } else { - correction_factor = cpi->rate_correction_factor; - } - } - - /* Calculate required scaling factor based on target frame size and - * size of frame produced using previous Q - */ - if (target_bits_per_frame > (INT_MAX >> BPER_MB_NORMBITS)) { - int temp = target_bits_per_frame / cpi->common.MBs; - if (temp > (INT_MAX >> BPER_MB_NORMBITS)) { - target_bits_per_mb = INT_MAX; - } else { - target_bits_per_mb = temp << BPER_MB_NORMBITS; - } - } else { - target_bits_per_mb = - (target_bits_per_frame << BPER_MB_NORMBITS) / cpi->common.MBs; - } - - i = cpi->active_best_quality; - - do { - bits_per_mb_at_this_q = - (int)(.5 + - correction_factor * vp8_bits_per_mb[cpi->common.frame_type][i]); - - if (bits_per_mb_at_this_q <= target_bits_per_mb) { - if ((target_bits_per_mb - bits_per_mb_at_this_q) <= last_error) { - Q = i; - } else { - Q = i - 1; - } - - break; - } else { - last_error = bits_per_mb_at_this_q - target_bits_per_mb; - } - } while (++i <= cpi->active_worst_quality); - - /* If we are at MAXQ then enable Q over-run which seeks to claw - * back additional bits through things like the RD multiplier - * and zero bin size. - */ - if (Q >= MAXQ) { - int zbin_oqmax; - - double Factor = 0.99; - double factor_adjustment = 0.01 / 256.0; - - if (cpi->common.frame_type == KEY_FRAME) { - zbin_oqmax = 0; - } else if (cpi->oxcf.number_of_layers == 1 && - !cpi->gf_noboost_onepass_cbr && - (cpi->common.refresh_alt_ref_frame || - (cpi->common.refresh_golden_frame && - !cpi->source_alt_ref_active))) { - zbin_oqmax = 16; - } else { - zbin_oqmax = ZBIN_OQ_MAX; - } - - /*{ - double Factor = - (double)target_bits_per_mb/(double)bits_per_mb_at_this_q; - double Oq; - - Factor = Factor/1.2683; - - Oq = pow( Factor, (1.0/-0.165) ); - - if ( Oq > zbin_oqmax ) - Oq = zbin_oqmax; - - cpi->zbin_over_quant = (int)Oq; - }*/ - - /* Each incrment in the zbin is assumed to have a fixed effect - * on bitrate. This is not of course true. The effect will be - * highly clip dependent and may well have sudden steps. The - * idea here is to acheive higher effective quantizers than the - * normal maximum by expanding the zero bin and hence - * decreasing the number of low magnitude non zero coefficients. - */ - while (cpi->mb.zbin_over_quant < zbin_oqmax) { - cpi->mb.zbin_over_quant++; - - if (cpi->mb.zbin_over_quant > zbin_oqmax) { - cpi->mb.zbin_over_quant = zbin_oqmax; - } - - /* Adjust bits_per_mb_at_this_q estimate */ - bits_per_mb_at_this_q = (int)(Factor * bits_per_mb_at_this_q); - Factor += factor_adjustment; - - if (Factor >= 0.999) Factor = 0.999; - - /* Break out if we get down to the target rate */ - if (bits_per_mb_at_this_q <= target_bits_per_mb) break; - } - } - } - - // Limit decrease in Q for 1 pass CBR screen content mode. - if (cpi->common.frame_type != KEY_FRAME && cpi->pass == 0 && - cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER && - cpi->oxcf.screen_content_mode) - Q = limit_q_cbr_inter(cpi->last_q[1], Q); - - return Q; -} - -static int estimate_keyframe_frequency(VP8_COMP *cpi) { - int i; - - /* Average key frame frequency */ - int av_key_frame_frequency = 0; - - /* First key frame at start of sequence is a special case. We have no - * frequency data. - */ - if (cpi->key_frame_count == 1) { - /* Assume a default of 1 kf every 2 seconds, or the max kf interval, - * whichever is smaller. - */ - int key_freq = cpi->oxcf.key_freq > 0 ? cpi->oxcf.key_freq : 1; - av_key_frame_frequency = 1 + (int)cpi->output_framerate * 2; - - if (cpi->oxcf.auto_key && av_key_frame_frequency > key_freq) { - av_key_frame_frequency = key_freq; - } - - cpi->prior_key_frame_distance[KEY_FRAME_CONTEXT - 1] = - av_key_frame_frequency; - } else { - unsigned int total_weight = 0; - int last_kf_interval = - (cpi->frames_since_key > 0) ? cpi->frames_since_key : 1; - - /* reset keyframe context and calculate weighted average of last - * KEY_FRAME_CONTEXT keyframes - */ - for (i = 0; i < KEY_FRAME_CONTEXT; ++i) { - if (i < KEY_FRAME_CONTEXT - 1) { - cpi->prior_key_frame_distance[i] = cpi->prior_key_frame_distance[i + 1]; - } else { - cpi->prior_key_frame_distance[i] = last_kf_interval; - } - - av_key_frame_frequency += - prior_key_frame_weight[i] * cpi->prior_key_frame_distance[i]; - total_weight += prior_key_frame_weight[i]; - } - - av_key_frame_frequency /= total_weight; - } - // TODO (marpan): Given the checks above, |av_key_frame_frequency| - // should always be above 0. But for now we keep the sanity check in. - if (av_key_frame_frequency == 0) av_key_frame_frequency = 1; - return av_key_frame_frequency; -} - -void vp8_adjust_key_frame_context(VP8_COMP *cpi) { - /* Clear down mmx registers to allow floating point in what follows */ - vpx_clear_system_state(); - - /* Do we have any key frame overspend to recover? */ - /* Two-pass overspend handled elsewhere. */ - if ((cpi->pass != 2) && - (cpi->projected_frame_size > cpi->per_frame_bandwidth)) { - int overspend; - - /* Update the count of key frame overspend to be recovered in - * subsequent frames. A portion of the KF overspend is treated as gf - * overspend (and hence recovered more quickly) as the kf is also a - * gf. Otherwise the few frames following each kf tend to get more - * bits allocated than those following other gfs. - */ - overspend = (cpi->projected_frame_size - cpi->per_frame_bandwidth); - - if (cpi->oxcf.number_of_layers > 1) { - cpi->kf_overspend_bits += overspend; - } else { - cpi->kf_overspend_bits += overspend * 7 / 8; - cpi->gf_overspend_bits += overspend * 1 / 8; - } - - /* Work out how much to try and recover per frame. */ - cpi->kf_bitrate_adjustment = - cpi->kf_overspend_bits / estimate_keyframe_frequency(cpi); - } - - cpi->frames_since_key = 0; - cpi->key_frame_count++; -} - -void vp8_compute_frame_size_bounds(VP8_COMP *cpi, int *frame_under_shoot_limit, - int *frame_over_shoot_limit) { - /* Set-up bounds on acceptable frame size: */ - if (cpi->oxcf.fixed_q >= 0) { - /* Fixed Q scenario: frame size never outranges target - * (there is no target!) - */ - *frame_under_shoot_limit = 0; - *frame_over_shoot_limit = INT_MAX; - } else { - const int64_t this_frame_target = cpi->this_frame_target; - int64_t over_shoot_limit, under_shoot_limit; - - if (cpi->common.frame_type == KEY_FRAME) { - over_shoot_limit = this_frame_target * 9 / 8; - under_shoot_limit = this_frame_target * 7 / 8; - } else { - if (cpi->oxcf.number_of_layers > 1 || cpi->common.refresh_alt_ref_frame || - cpi->common.refresh_golden_frame) { - over_shoot_limit = this_frame_target * 9 / 8; - under_shoot_limit = this_frame_target * 7 / 8; - } else { - /* For CBR take buffer fullness into account */ - if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) { - if (cpi->buffer_level >= ((cpi->oxcf.optimal_buffer_level + - cpi->oxcf.maximum_buffer_size) >> - 1)) { - /* Buffer is too full so relax overshoot and tighten - * undershoot - */ - over_shoot_limit = this_frame_target * 12 / 8; - under_shoot_limit = this_frame_target * 6 / 8; - } else if (cpi->buffer_level <= - (cpi->oxcf.optimal_buffer_level >> 1)) { - /* Buffer is too low so relax undershoot and tighten - * overshoot - */ - over_shoot_limit = this_frame_target * 10 / 8; - under_shoot_limit = this_frame_target * 4 / 8; - } else { - over_shoot_limit = this_frame_target * 11 / 8; - under_shoot_limit = this_frame_target * 5 / 8; - } - } - /* VBR and CQ mode */ - /* Note that tighter restrictions here can help quality - * but hurt encode speed - */ - else { - /* Stron overshoot limit for constrained quality */ - if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) { - over_shoot_limit = this_frame_target * 11 / 8; - under_shoot_limit = this_frame_target * 2 / 8; - } else { - over_shoot_limit = this_frame_target * 11 / 8; - under_shoot_limit = this_frame_target * 5 / 8; - } - } - } - } - - /* For very small rate targets where the fractional adjustment - * (eg * 7/8) may be tiny make sure there is at least a minimum - * range. - */ - over_shoot_limit += 200; - under_shoot_limit -= 200; - if (under_shoot_limit < 0) under_shoot_limit = 0; - if (under_shoot_limit > INT_MAX) under_shoot_limit = INT_MAX; - if (over_shoot_limit > INT_MAX) over_shoot_limit = INT_MAX; - *frame_under_shoot_limit = (int)under_shoot_limit; - *frame_over_shoot_limit = (int)over_shoot_limit; - } -} - -/* return of 0 means drop frame */ -int vp8_pick_frame_size(VP8_COMP *cpi) { - VP8_COMMON *cm = &cpi->common; - - if (cm->frame_type == KEY_FRAME) { - calc_iframe_target_size(cpi); - } else { - calc_pframe_target_size(cpi); - - /* Check if we're dropping the frame: */ - if (cpi->drop_frame) { - cpi->drop_frame = 0; - return 0; - } - } - return 1; -} -// If this just encoded frame (mcomp/transform/quant, but before loopfilter and -// pack_bitstream) has large overshoot, and was not being encoded close to the -// max QP, then drop this frame and force next frame to be encoded at max QP. -// Allow this for screen_content_mode = 2, or if drop frames is allowed. -// TODO(marpan): Should do this exit condition during the encode_frame -// (i.e., halfway during the encoding of the frame) to save cycles. -int vp8_drop_encodedframe_overshoot(VP8_COMP *cpi, int Q) { - int force_drop_overshoot = 0; -#if CONFIG_MULTI_RES_ENCODING - // Only check for dropping due to overshoot on the lowest stream. - // If the lowest stream of the multi-res encoding was dropped due to - // overshoot, then force dropping on all upper layer streams - // (mr_encoder_id > 0). - LOWER_RES_FRAME_INFO *low_res_frame_info = - (LOWER_RES_FRAME_INFO *)cpi->oxcf.mr_low_res_mode_info; - if (cpi->oxcf.mr_total_resolutions > 1 && cpi->oxcf.mr_encoder_id > 0) { - force_drop_overshoot = low_res_frame_info->is_frame_dropped_overshoot_maxqp; - if (!force_drop_overshoot) { - cpi->force_maxqp = 0; - cpi->frames_since_last_drop_overshoot++; - return 0; - } - } -#endif - if (cpi->common.frame_type != KEY_FRAME && - (cpi->oxcf.screen_content_mode == 2 || - (cpi->drop_frames_allowed && - (force_drop_overshoot || - (cpi->rate_correction_factor < (8.0f * MIN_BPB_FACTOR) && - cpi->frames_since_last_drop_overshoot > (int)cpi->framerate))))) { - // Note: the "projected_frame_size" from encode_frame() only gives estimate - // of mode/motion vector rate (in non-rd mode): so below we only require - // that projected_frame_size is somewhat greater than per-frame-bandwidth, - // but add additional condition with high threshold on prediction residual. - - // QP threshold: only allow dropping if we are not close to qp_max. - int thresh_qp = 3 * cpi->worst_quality >> 2; - // Rate threshold, in bytes. - int thresh_rate = 2 * (cpi->av_per_frame_bandwidth >> 3); - // Threshold for the average (over all macroblocks) of the pixel-sum - // residual error over 16x16 block. - int thresh_pred_err_mb = (200 << 4); - int pred_err_mb = (int)(cpi->mb.prediction_error / cpi->common.MBs); - // Reduce/ignore thresh_rate if pred_err_mb much larger than its threshold, - // give more weight to pred_err metric for overshoot detection. - if (cpi->drop_frames_allowed && pred_err_mb > (thresh_pred_err_mb << 4)) - thresh_rate = thresh_rate >> 3; - if ((Q < thresh_qp && cpi->projected_frame_size > thresh_rate && - pred_err_mb > thresh_pred_err_mb && - pred_err_mb > 2 * cpi->last_pred_err_mb) || - force_drop_overshoot) { - unsigned int i; - double new_correction_factor; - int target_bits_per_mb; - const int target_size = cpi->av_per_frame_bandwidth; - // Flag to indicate we will force next frame to be encoded at max QP. - cpi->force_maxqp = 1; - // Reset the buffer levels. - cpi->buffer_level = cpi->oxcf.optimal_buffer_level; - cpi->bits_off_target = cpi->oxcf.optimal_buffer_level; - // Compute a new rate correction factor, corresponding to the current - // target frame size and max_QP, and adjust the rate correction factor - // upwards, if needed. - // This is to prevent a bad state where the re-encoded frame at max_QP - // undershoots significantly, and then we end up dropping every other - // frame because the QP/rate_correction_factor may have been too low - // before the drop and then takes too long to come up. - if (target_size > (INT_MAX >> BPER_MB_NORMBITS)) { - int temp = target_size / cpi->common.MBs; - if (temp > (INT_MAX >> BPER_MB_NORMBITS)) { - target_bits_per_mb = INT_MAX; - } else { - target_bits_per_mb = temp << BPER_MB_NORMBITS; - } - } else { - target_bits_per_mb = - (target_size << BPER_MB_NORMBITS) / cpi->common.MBs; - } - // Rate correction factor based on target_size_per_mb and max_QP. - new_correction_factor = - (double)target_bits_per_mb / - (double)vp8_bits_per_mb[INTER_FRAME][cpi->worst_quality]; - if (new_correction_factor > cpi->rate_correction_factor) { - cpi->rate_correction_factor = - VPXMIN(2.0 * cpi->rate_correction_factor, new_correction_factor); - } - if (cpi->rate_correction_factor > MAX_BPB_FACTOR) { - cpi->rate_correction_factor = MAX_BPB_FACTOR; - } - // Drop this frame: update frame counters. - cpi->common.current_video_frame++; - cpi->frames_since_key++; - cpi->temporal_pattern_counter++; - cpi->frames_since_last_drop_overshoot = 0; - if (cpi->oxcf.number_of_layers > 1) { - // Set max_qp and rate correction for all temporal layers if overshoot - // is detected. - for (i = 0; i < cpi->oxcf.number_of_layers; ++i) { - LAYER_CONTEXT *lc = &cpi->layer_context[i]; - lc->force_maxqp = 1; - lc->frames_since_last_drop_overshoot = 0; - lc->rate_correction_factor = cpi->rate_correction_factor; - } - } -#if CONFIG_MULTI_RES_ENCODING - if (cpi->oxcf.mr_total_resolutions > 1) - low_res_frame_info->is_frame_dropped_overshoot_maxqp = 1; -#endif - return 1; - } - cpi->force_maxqp = 0; - cpi->frames_since_last_drop_overshoot++; -#if CONFIG_MULTI_RES_ENCODING - if (cpi->oxcf.mr_total_resolutions > 1) - low_res_frame_info->is_frame_dropped_overshoot_maxqp = 0; -#endif - return 0; - } - cpi->force_maxqp = 0; - cpi->frames_since_last_drop_overshoot++; -#if CONFIG_MULTI_RES_ENCODING - if (cpi->oxcf.mr_total_resolutions > 1) - low_res_frame_info->is_frame_dropped_overshoot_maxqp = 0; -#endif - return 0; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/ratectrl.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/ratectrl.h deleted file mode 100644 index 844c72cb..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/ratectrl.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_RATECTRL_H_ -#define VPX_VP8_ENCODER_RATECTRL_H_ - -#include "onyx_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern void vp8_save_coding_context(VP8_COMP *cpi); -extern void vp8_restore_coding_context(VP8_COMP *cpi); - -extern void vp8_setup_key_frame(VP8_COMP *cpi); -extern void vp8_update_rate_correction_factors(VP8_COMP *cpi, int damp_var); -extern int vp8_regulate_q(VP8_COMP *cpi, int target_bits_per_frame); -extern void vp8_adjust_key_frame_context(VP8_COMP *cpi); -extern void vp8_compute_frame_size_bounds(VP8_COMP *cpi, - int *frame_under_shoot_limit, - int *frame_over_shoot_limit); - -/* return of 0 means drop frame */ -extern int vp8_pick_frame_size(VP8_COMP *cpi); - -extern int vp8_drop_encodedframe_overshoot(VP8_COMP *cpi, int Q); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_RATECTRL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/rdopt.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/rdopt.c deleted file mode 100644 index 671cccd1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/rdopt.c +++ /dev/null @@ -1,2407 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include -#include "vpx_config.h" -#include "vp8_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "encodeframe.h" -#include "tokenize.h" -#include "treewriter.h" -#include "onyx_int.h" -#include "modecosts.h" -#include "encodeintra.h" -#include "pickinter.h" -#include "vp8/common/common.h" -#include "vp8/common/entropymode.h" -#include "vp8/common/reconinter.h" -#include "vp8/common/reconintra.h" -#include "vp8/common/reconintra4x4.h" -#include "vp8/common/findnearmv.h" -#include "vp8/common/quant_common.h" -#include "encodemb.h" -#include "vp8/encoder/quantize.h" -#include "vpx_dsp/variance.h" -#include "vpx_ports/system_state.h" -#include "mcomp.h" -#include "rdopt.h" -#include "vpx_mem/vpx_mem.h" -#include "vp8/common/systemdependent.h" -#if CONFIG_TEMPORAL_DENOISING -#include "denoising.h" -#endif -extern void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x); - -#define MAXF(a, b) (((a) > (b)) ? (a) : (b)) - -typedef struct rate_distortion_struct { - int rate2; - int rate_y; - int rate_uv; - int distortion2; - int distortion_uv; -} RATE_DISTORTION; - -typedef struct best_mode_struct { - int yrd; - int rd; - int intra_rd; - MB_MODE_INFO mbmode; - union b_mode_info bmodes[16]; - PARTITION_INFO partition; -} BEST_MODE; - -static const int auto_speed_thresh[17] = { 1000, 200, 150, 130, 150, 125, - 120, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 105 }; - -const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES] = { - ZEROMV, DC_PRED, - - NEARESTMV, NEARMV, - - ZEROMV, NEARESTMV, - - ZEROMV, NEARESTMV, - - NEARMV, NEARMV, - - V_PRED, H_PRED, TM_PRED, - - NEWMV, NEWMV, NEWMV, - - SPLITMV, SPLITMV, SPLITMV, - - B_PRED, -}; - -/* This table determines the search order in reference frame priority order, - * which may not necessarily match INTRA,LAST,GOLDEN,ARF - */ -const int vp8_ref_frame_order[MAX_MODES] = { - 1, 0, - - 1, 1, - - 2, 2, - - 3, 3, - - 2, 3, - - 0, 0, 0, - - 1, 2, 3, - - 1, 2, 3, - - 0, -}; - -static void fill_token_costs( - int c[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS], - const vp8_prob p[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS] - [ENTROPY_NODES]) { - int i, j, k; - - for (i = 0; i < BLOCK_TYPES; ++i) { - for (j = 0; j < COEF_BANDS; ++j) { - for (k = 0; k < PREV_COEF_CONTEXTS; ++k) { - /* check for pt=0 and band > 1 if block type 0 - * and 0 if blocktype 1 - */ - if (k == 0 && j > (i == 0)) { - vp8_cost_tokens2(c[i][j][k], p[i][j][k], vp8_coef_tree, 2); - } else { - vp8_cost_tokens(c[i][j][k], p[i][j][k], vp8_coef_tree); - } - } - } - } -} - -static const int rd_iifactor[32] = { 4, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -/* values are now correlated to quantizer */ -static const int sad_per_bit16lut[QINDEX_RANGE] = { - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, - 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14 -}; -static const int sad_per_bit4lut[QINDEX_RANGE] = { - 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, - 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, - 12, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, - 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, -}; - -void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex) { - cpi->mb.sadperbit16 = sad_per_bit16lut[QIndex]; - cpi->mb.sadperbit4 = sad_per_bit4lut[QIndex]; -} - -void vp8_initialize_rd_consts(VP8_COMP *cpi, MACROBLOCK *x, int Qvalue) { - int q; - int i; - double capped_q = (Qvalue < 160) ? (double)Qvalue : 160.0; - double rdconst = 2.80; - - vpx_clear_system_state(); - - /* Further tests required to see if optimum is different - * for key frames, golden frames and arf frames. - */ - cpi->RDMULT = (int)(rdconst * (capped_q * capped_q)); - - /* Extend rate multiplier along side quantizer zbin increases */ - if (cpi->mb.zbin_over_quant > 0) { - double oq_factor; - double modq; - - /* Experimental code using the same basic equation as used for Q above - * The units of cpi->mb.zbin_over_quant are 1/128 of Q bin size - */ - oq_factor = 1.0 + ((double)0.0015625 * cpi->mb.zbin_over_quant); - modq = (int)((double)capped_q * oq_factor); - cpi->RDMULT = (int)(rdconst * (modq * modq)); - } - - if (cpi->pass == 2 && (cpi->common.frame_type != KEY_FRAME)) { - if (cpi->twopass.next_iiratio > 31) { - cpi->RDMULT += (cpi->RDMULT * rd_iifactor[31]) >> 4; - } else { - cpi->RDMULT += - (cpi->RDMULT * rd_iifactor[cpi->twopass.next_iiratio]) >> 4; - } - } - - cpi->mb.errorperbit = (cpi->RDMULT / 110); - cpi->mb.errorperbit += (cpi->mb.errorperbit == 0); - - vp8_set_speed_features(cpi); - - for (i = 0; i < MAX_MODES; ++i) { - x->mode_test_hit_counts[i] = 0; - } - - q = (int)pow(Qvalue, 1.25); - - if (q < 8) q = 8; - - if (cpi->RDMULT > 1000) { - cpi->RDDIV = 1; - cpi->RDMULT /= 100; - - for (i = 0; i < MAX_MODES; ++i) { - if (cpi->sf.thresh_mult[i] < INT_MAX) { - x->rd_threshes[i] = cpi->sf.thresh_mult[i] * q / 100; - } else { - x->rd_threshes[i] = INT_MAX; - } - - cpi->rd_baseline_thresh[i] = x->rd_threshes[i]; - } - } else { - cpi->RDDIV = 100; - - for (i = 0; i < MAX_MODES; ++i) { - if (cpi->sf.thresh_mult[i] < (INT_MAX / q)) { - x->rd_threshes[i] = cpi->sf.thresh_mult[i] * q; - } else { - x->rd_threshes[i] = INT_MAX; - } - - cpi->rd_baseline_thresh[i] = x->rd_threshes[i]; - } - } - - { - /* build token cost array for the type of frame we have now */ - FRAME_CONTEXT *l = &cpi->lfc_n; - - if (cpi->common.refresh_alt_ref_frame) { - l = &cpi->lfc_a; - } else if (cpi->common.refresh_golden_frame) { - l = &cpi->lfc_g; - } - - fill_token_costs(cpi->mb.token_costs, - (const vp8_prob(*)[8][3][11])l->coef_probs); - /* - fill_token_costs( - cpi->mb.token_costs, - (const vp8_prob( *)[8][3][11]) cpi->common.fc.coef_probs); - */ - - /* TODO make these mode costs depend on last,alt or gold too. (jbb) */ - vp8_init_mode_costs(cpi); - } -} - -void vp8_auto_select_speed(VP8_COMP *cpi) { - int milliseconds_for_compress = (int)(1000000 / cpi->framerate); - - milliseconds_for_compress = - milliseconds_for_compress * (16 - cpi->oxcf.cpu_used) / 16; - -#if 0 - - if (0) - { - FILE *f; - - f = fopen("speed.stt", "a"); - fprintf(f, " %8ld %10ld %10ld %10ld\n", - cpi->common.current_video_frame, cpi->Speed, milliseconds_for_compress, cpi->avg_pick_mode_time); - fclose(f); - } - -#endif - - if (cpi->avg_pick_mode_time < milliseconds_for_compress && - (cpi->avg_encode_time - cpi->avg_pick_mode_time) < - milliseconds_for_compress) { - if (cpi->avg_pick_mode_time == 0) { - cpi->Speed = 4; - } else { - if (milliseconds_for_compress * 100 < cpi->avg_encode_time * 95) { - cpi->Speed += 2; - cpi->avg_pick_mode_time = 0; - cpi->avg_encode_time = 0; - - if (cpi->Speed > 16) { - cpi->Speed = 16; - } - } - - if (milliseconds_for_compress * 100 > - cpi->avg_encode_time * auto_speed_thresh[cpi->Speed]) { - cpi->Speed -= 1; - cpi->avg_pick_mode_time = 0; - cpi->avg_encode_time = 0; - - /* In real-time mode, cpi->speed is in [4, 16]. */ - if (cpi->Speed < 4) { - cpi->Speed = 4; - } - } - } - } else { - cpi->Speed += 4; - - if (cpi->Speed > 16) cpi->Speed = 16; - - cpi->avg_pick_mode_time = 0; - cpi->avg_encode_time = 0; - } -} - -int vp8_block_error_c(short *coeff, short *dqcoeff) { - int i; - int error = 0; - - for (i = 0; i < 16; ++i) { - int this_diff = coeff[i] - dqcoeff[i]; - error += this_diff * this_diff; - } - - return error; -} - -int vp8_mbblock_error_c(MACROBLOCK *mb, int dc) { - BLOCK *be; - BLOCKD *bd; - int i, j; - int berror, error = 0; - - for (i = 0; i < 16; ++i) { - be = &mb->block[i]; - bd = &mb->e_mbd.block[i]; - - berror = 0; - - for (j = dc; j < 16; ++j) { - int this_diff = be->coeff[j] - bd->dqcoeff[j]; - berror += this_diff * this_diff; - } - - error += berror; - } - - return error; -} - -int vp8_mbuverror_c(MACROBLOCK *mb) { - BLOCK *be; - BLOCKD *bd; - - int i; - int error = 0; - - for (i = 16; i < 24; ++i) { - be = &mb->block[i]; - bd = &mb->e_mbd.block[i]; - - error += vp8_block_error_c(be->coeff, bd->dqcoeff); - } - - return error; -} - -int VP8_UVSSE(MACROBLOCK *x) { - unsigned char *uptr, *vptr; - unsigned char *upred_ptr = (*(x->block[16].base_src) + x->block[16].src); - unsigned char *vpred_ptr = (*(x->block[20].base_src) + x->block[20].src); - int uv_stride = x->block[16].src_stride; - - unsigned int sse1 = 0; - unsigned int sse2 = 0; - int mv_row = x->e_mbd.mode_info_context->mbmi.mv.as_mv.row; - int mv_col = x->e_mbd.mode_info_context->mbmi.mv.as_mv.col; - int offset; - int pre_stride = x->e_mbd.pre.uv_stride; - - if (mv_row < 0) { - mv_row -= 1; - } else { - mv_row += 1; - } - - if (mv_col < 0) { - mv_col -= 1; - } else { - mv_col += 1; - } - - mv_row /= 2; - mv_col /= 2; - - offset = (mv_row >> 3) * pre_stride + (mv_col >> 3); - uptr = x->e_mbd.pre.u_buffer + offset; - vptr = x->e_mbd.pre.v_buffer + offset; - - if ((mv_row | mv_col) & 7) { - vpx_sub_pixel_variance8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, - upred_ptr, uv_stride, &sse2); - vpx_sub_pixel_variance8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, - vpred_ptr, uv_stride, &sse1); - sse2 += sse1; - } else { - vpx_variance8x8(uptr, pre_stride, upred_ptr, uv_stride, &sse2); - vpx_variance8x8(vptr, pre_stride, vpred_ptr, uv_stride, &sse1); - sse2 += sse1; - } - return sse2; -} - -static int cost_coeffs(MACROBLOCK *mb, BLOCKD *b, int type, ENTROPY_CONTEXT *a, - ENTROPY_CONTEXT *l) { - int c = !type; /* start at coef 0, unless Y with Y2 */ - int eob = (int)(*b->eob); - int pt; /* surrounding block/prev coef predictor */ - int cost = 0; - short *qcoeff_ptr = b->qcoeff; - - VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); - - assert(eob <= 16); - for (; c < eob; ++c) { - const int v = qcoeff_ptr[vp8_default_zig_zag1d[c]]; - const int t = vp8_dct_value_tokens_ptr[v].Token; - cost += mb->token_costs[type][vp8_coef_bands[c]][pt][t]; - cost += vp8_dct_value_cost_ptr[v]; - pt = vp8_prev_token_class[t]; - } - - if (c < 16) { - cost += mb->token_costs[type][vp8_coef_bands[c]][pt][DCT_EOB_TOKEN]; - } - - pt = (c != !type); /* is eob first coefficient; */ - *a = *l = pt; - - return cost; -} - -static int vp8_rdcost_mby(MACROBLOCK *mb) { - int cost = 0; - int b; - MACROBLOCKD *x = &mb->e_mbd; - ENTROPY_CONTEXT_PLANES t_above, t_left; - ENTROPY_CONTEXT *ta; - ENTROPY_CONTEXT *tl; - - memcpy(&t_above, mb->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES)); - memcpy(&t_left, mb->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES)); - - ta = (ENTROPY_CONTEXT *)&t_above; - tl = (ENTROPY_CONTEXT *)&t_left; - - for (b = 0; b < 16; ++b) { - cost += cost_coeffs(mb, x->block + b, PLANE_TYPE_Y_NO_DC, - ta + vp8_block2above[b], tl + vp8_block2left[b]); - } - - cost += cost_coeffs(mb, x->block + 24, PLANE_TYPE_Y2, - ta + vp8_block2above[24], tl + vp8_block2left[24]); - - return cost; -} - -static void macro_block_yrd(MACROBLOCK *mb, int *Rate, int *Distortion) { - int b; - MACROBLOCKD *const x = &mb->e_mbd; - BLOCK *const mb_y2 = mb->block + 24; - BLOCKD *const x_y2 = x->block + 24; - short *Y2DCPtr = mb_y2->src_diff; - BLOCK *beptr; - int d; - - vp8_subtract_mby(mb->src_diff, *(mb->block[0].base_src), - mb->block[0].src_stride, mb->e_mbd.predictor, 16); - - /* Fdct and building the 2nd order block */ - for (beptr = mb->block; beptr < mb->block + 16; beptr += 2) { - mb->short_fdct8x4(beptr->src_diff, beptr->coeff, 32); - *Y2DCPtr++ = beptr->coeff[0]; - *Y2DCPtr++ = beptr->coeff[16]; - } - - /* 2nd order fdct */ - mb->short_walsh4x4(mb_y2->src_diff, mb_y2->coeff, 8); - - /* Quantization */ - for (b = 0; b < 16; ++b) { - mb->quantize_b(&mb->block[b], &mb->e_mbd.block[b]); - } - - /* DC predication and Quantization of 2nd Order block */ - mb->quantize_b(mb_y2, x_y2); - - /* Distortion */ - d = vp8_mbblock_error(mb, 1) << 2; - d += vp8_block_error(mb_y2->coeff, x_y2->dqcoeff); - - *Distortion = (d >> 4); - - /* rate */ - *Rate = vp8_rdcost_mby(mb); -} - -static void copy_predictor(unsigned char *dst, const unsigned char *predictor) { - const unsigned int *p = (const unsigned int *)predictor; - unsigned int *d = (unsigned int *)dst; - d[0] = p[0]; - d[4] = p[4]; - d[8] = p[8]; - d[12] = p[12]; -} -static int rd_pick_intra4x4block(MACROBLOCK *x, BLOCK *be, BLOCKD *b, - B_PREDICTION_MODE *best_mode, - const int *bmode_costs, ENTROPY_CONTEXT *a, - ENTROPY_CONTEXT *l, - - int *bestrate, int *bestratey, - int *bestdistortion) { - B_PREDICTION_MODE mode; - int best_rd = INT_MAX; - int rate = 0; - int distortion; - - ENTROPY_CONTEXT ta = *a, tempa = *a; - ENTROPY_CONTEXT tl = *l, templ = *l; - /* - * The predictor buffer is a 2d buffer with a stride of 16. Create - * a temp buffer that meets the stride requirements, but we are only - * interested in the left 4x4 block - * */ - DECLARE_ALIGNED(16, unsigned char, best_predictor[16 * 4]); - DECLARE_ALIGNED(16, short, best_dqcoeff[16]); - int dst_stride = x->e_mbd.dst.y_stride; - unsigned char *dst = x->e_mbd.dst.y_buffer + b->offset; - - unsigned char *Above = dst - dst_stride; - unsigned char *yleft = dst - 1; - unsigned char top_left = Above[-1]; - - for (mode = B_DC_PRED; mode <= B_HU_PRED; ++mode) { - int this_rd; - int ratey; - - rate = bmode_costs[mode]; - - vp8_intra4x4_predict(Above, yleft, dst_stride, mode, b->predictor, 16, - top_left); - vp8_subtract_b(be, b, 16); - x->short_fdct4x4(be->src_diff, be->coeff, 32); - x->quantize_b(be, b); - - tempa = ta; - templ = tl; - - ratey = cost_coeffs(x, b, PLANE_TYPE_Y_WITH_DC, &tempa, &templ); - rate += ratey; - distortion = vp8_block_error(be->coeff, b->dqcoeff) >> 2; - - this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion); - - if (this_rd < best_rd) { - *bestrate = rate; - *bestratey = ratey; - *bestdistortion = distortion; - best_rd = this_rd; - *best_mode = mode; - *a = tempa; - *l = templ; - copy_predictor(best_predictor, b->predictor); - memcpy(best_dqcoeff, b->dqcoeff, 32); - } - } - b->bmi.as_mode = *best_mode; - - vp8_short_idct4x4llm(best_dqcoeff, best_predictor, 16, dst, dst_stride); - - return best_rd; -} - -static int rd_pick_intra4x4mby_modes(MACROBLOCK *mb, int *Rate, int *rate_y, - int *Distortion, int best_rd) { - MACROBLOCKD *const xd = &mb->e_mbd; - int i; - int cost = mb->mbmode_cost[xd->frame_type][B_PRED]; - int distortion = 0; - int tot_rate_y = 0; - int64_t total_rd = 0; - ENTROPY_CONTEXT_PLANES t_above, t_left; - ENTROPY_CONTEXT *ta; - ENTROPY_CONTEXT *tl; - const int *bmode_costs; - - memcpy(&t_above, mb->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES)); - memcpy(&t_left, mb->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES)); - - ta = (ENTROPY_CONTEXT *)&t_above; - tl = (ENTROPY_CONTEXT *)&t_left; - - intra_prediction_down_copy(xd, xd->dst.y_buffer - xd->dst.y_stride + 16); - - bmode_costs = mb->inter_bmode_costs; - - for (i = 0; i < 16; ++i) { - MODE_INFO *const mic = xd->mode_info_context; - const int mis = xd->mode_info_stride; - B_PREDICTION_MODE best_mode = B_MODE_COUNT; - int r = 0, ry = 0, d = 0; - - if (mb->e_mbd.frame_type == KEY_FRAME) { - const B_PREDICTION_MODE A = above_block_mode(mic, i, mis); - const B_PREDICTION_MODE L = left_block_mode(mic, i); - - bmode_costs = mb->bmode_costs[A][L]; - } - - total_rd += rd_pick_intra4x4block( - mb, mb->block + i, xd->block + i, &best_mode, bmode_costs, - ta + vp8_block2above[i], tl + vp8_block2left[i], &r, &ry, &d); - - cost += r; - distortion += d; - tot_rate_y += ry; - - assert(best_mode != B_MODE_COUNT); - mic->bmi[i].as_mode = best_mode; - - if (total_rd >= (int64_t)best_rd) break; - } - - if (total_rd >= (int64_t)best_rd) return INT_MAX; - - *Rate = cost; - *rate_y = tot_rate_y; - *Distortion = distortion; - - return RDCOST(mb->rdmult, mb->rddiv, cost, distortion); -} - -static int rd_pick_intra16x16mby_mode(MACROBLOCK *x, int *Rate, int *rate_y, - int *Distortion) { - MB_PREDICTION_MODE mode; - MB_PREDICTION_MODE mode_selected = MB_MODE_COUNT; - int rate, ratey; - int distortion; - int best_rd = INT_MAX; - int this_rd; - MACROBLOCKD *xd = &x->e_mbd; - - /* Y Search for 16x16 intra prediction mode */ - for (mode = DC_PRED; mode <= TM_PRED; ++mode) { - xd->mode_info_context->mbmi.mode = mode; - - vp8_build_intra_predictors_mby_s(xd, xd->dst.y_buffer - xd->dst.y_stride, - xd->dst.y_buffer - 1, xd->dst.y_stride, - xd->predictor, 16); - - macro_block_yrd(x, &ratey, &distortion); - rate = ratey + - x->mbmode_cost[xd->frame_type][xd->mode_info_context->mbmi.mode]; - - this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion); - - if (this_rd < best_rd) { - mode_selected = mode; - best_rd = this_rd; - *Rate = rate; - *rate_y = ratey; - *Distortion = distortion; - } - } - - assert(mode_selected != MB_MODE_COUNT); - xd->mode_info_context->mbmi.mode = mode_selected; - return best_rd; -} - -static int rd_cost_mbuv(MACROBLOCK *mb) { - int b; - int cost = 0; - MACROBLOCKD *x = &mb->e_mbd; - ENTROPY_CONTEXT_PLANES t_above, t_left; - ENTROPY_CONTEXT *ta; - ENTROPY_CONTEXT *tl; - - memcpy(&t_above, mb->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES)); - memcpy(&t_left, mb->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES)); - - ta = (ENTROPY_CONTEXT *)&t_above; - tl = (ENTROPY_CONTEXT *)&t_left; - - for (b = 16; b < 24; ++b) { - cost += cost_coeffs(mb, x->block + b, PLANE_TYPE_UV, - ta + vp8_block2above[b], tl + vp8_block2left[b]); - } - - return cost; -} - -static int rd_inter16x16_uv(VP8_COMP *cpi, MACROBLOCK *x, int *rate, - int *distortion, int fullpixel) { - (void)cpi; - (void)fullpixel; - - vp8_build_inter16x16_predictors_mbuv(&x->e_mbd); - vp8_subtract_mbuv(x->src_diff, x->src.u_buffer, x->src.v_buffer, - x->src.uv_stride, &x->e_mbd.predictor[256], - &x->e_mbd.predictor[320], 8); - - vp8_transform_mbuv(x); - vp8_quantize_mbuv(x); - - *rate = rd_cost_mbuv(x); - *distortion = vp8_mbuverror(x) / 4; - - return RDCOST(x->rdmult, x->rddiv, *rate, *distortion); -} - -static int rd_inter4x4_uv(VP8_COMP *cpi, MACROBLOCK *x, int *rate, - int *distortion, int fullpixel) { - (void)cpi; - (void)fullpixel; - - vp8_build_inter4x4_predictors_mbuv(&x->e_mbd); - vp8_subtract_mbuv(x->src_diff, x->src.u_buffer, x->src.v_buffer, - x->src.uv_stride, &x->e_mbd.predictor[256], - &x->e_mbd.predictor[320], 8); - - vp8_transform_mbuv(x); - vp8_quantize_mbuv(x); - - *rate = rd_cost_mbuv(x); - *distortion = vp8_mbuverror(x) / 4; - - return RDCOST(x->rdmult, x->rddiv, *rate, *distortion); -} - -static void rd_pick_intra_mbuv_mode(MACROBLOCK *x, int *rate, - int *rate_tokenonly, int *distortion) { - MB_PREDICTION_MODE mode; - MB_PREDICTION_MODE mode_selected = MB_MODE_COUNT; - int best_rd = INT_MAX; - int d = 0, r = 0; - int rate_to; - MACROBLOCKD *xd = &x->e_mbd; - - for (mode = DC_PRED; mode <= TM_PRED; ++mode) { - int this_rate; - int this_distortion; - int this_rd; - - xd->mode_info_context->mbmi.uv_mode = mode; - - vp8_build_intra_predictors_mbuv_s( - xd, xd->dst.u_buffer - xd->dst.uv_stride, - xd->dst.v_buffer - xd->dst.uv_stride, xd->dst.u_buffer - 1, - xd->dst.v_buffer - 1, xd->dst.uv_stride, &xd->predictor[256], - &xd->predictor[320], 8); - - vp8_subtract_mbuv(x->src_diff, x->src.u_buffer, x->src.v_buffer, - x->src.uv_stride, &xd->predictor[256], - &xd->predictor[320], 8); - vp8_transform_mbuv(x); - vp8_quantize_mbuv(x); - - rate_to = rd_cost_mbuv(x); - this_rate = - rate_to + x->intra_uv_mode_cost[xd->frame_type] - [xd->mode_info_context->mbmi.uv_mode]; - - this_distortion = vp8_mbuverror(x) / 4; - - this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion); - - if (this_rd < best_rd) { - best_rd = this_rd; - d = this_distortion; - r = this_rate; - *rate_tokenonly = rate_to; - mode_selected = mode; - } - } - - *rate = r; - *distortion = d; - - assert(mode_selected != MB_MODE_COUNT); - xd->mode_info_context->mbmi.uv_mode = mode_selected; -} - -int vp8_cost_mv_ref(MB_PREDICTION_MODE m, const int near_mv_ref_ct[4]) { - vp8_prob p[VP8_MVREFS - 1]; - assert(NEARESTMV <= m && m <= SPLITMV); - vp8_mv_ref_probs(p, near_mv_ref_ct); - return vp8_cost_token(vp8_mv_ref_tree, p, - vp8_mv_ref_encoding_array + (m - NEARESTMV)); -} - -void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv) { - x->e_mbd.mode_info_context->mbmi.mode = mb; - x->e_mbd.mode_info_context->mbmi.mv.as_int = mv->as_int; -} - -static int labels2mode(MACROBLOCK *x, int const *labelings, int which_label, - B_PREDICTION_MODE this_mode, int_mv *this_mv, - int_mv *best_ref_mv, int *mvcost[2]) { - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mic = xd->mode_info_context; - const int mis = xd->mode_info_stride; - - int cost = 0; - int thismvcost = 0; - - /* We have to be careful retrieving previously-encoded motion vectors. - Ones from this macroblock have to be pulled from the BLOCKD array - as they have not yet made it to the bmi array in our MB_MODE_INFO. */ - - int i = 0; - - do { - BLOCKD *const d = xd->block + i; - const int row = i >> 2, col = i & 3; - - B_PREDICTION_MODE m; - - if (labelings[i] != which_label) continue; - - if (col && labelings[i] == labelings[i - 1]) { - m = LEFT4X4; - } else if (row && labelings[i] == labelings[i - 4]) { - m = ABOVE4X4; - } else { - /* the only time we should do costing for new motion vector - * or mode is when we are on a new label (jbb May 08, 2007) - */ - switch (m = this_mode) { - case NEW4X4: - thismvcost = vp8_mv_bit_cost(this_mv, best_ref_mv, mvcost, 102); - break; - case LEFT4X4: - this_mv->as_int = col ? d[-1].bmi.mv.as_int : left_block_mv(mic, i); - break; - case ABOVE4X4: - this_mv->as_int = - row ? d[-4].bmi.mv.as_int : above_block_mv(mic, i, mis); - break; - case ZERO4X4: this_mv->as_int = 0; break; - default: break; - } - - if (m == ABOVE4X4) { /* replace above with left if same */ - int_mv left_mv; - - left_mv.as_int = col ? d[-1].bmi.mv.as_int : left_block_mv(mic, i); - - if (left_mv.as_int == this_mv->as_int) m = LEFT4X4; - } - - cost = x->inter_bmode_costs[m]; - } - - d->bmi.mv.as_int = this_mv->as_int; - - x->partition_info->bmi[i].mode = m; - x->partition_info->bmi[i].mv.as_int = this_mv->as_int; - - } while (++i < 16); - - cost += thismvcost; - return cost; -} - -static int rdcost_mbsegment_y(MACROBLOCK *mb, const int *labels, - int which_label, ENTROPY_CONTEXT *ta, - ENTROPY_CONTEXT *tl) { - int cost = 0; - int b; - MACROBLOCKD *x = &mb->e_mbd; - - for (b = 0; b < 16; ++b) { - if (labels[b] == which_label) { - cost += cost_coeffs(mb, x->block + b, PLANE_TYPE_Y_WITH_DC, - ta + vp8_block2above[b], tl + vp8_block2left[b]); - } - } - - return cost; -} -static unsigned int vp8_encode_inter_mb_segment(MACROBLOCK *x, - int const *labels, - int which_label) { - int i; - unsigned int distortion = 0; - int pre_stride = x->e_mbd.pre.y_stride; - unsigned char *base_pre = x->e_mbd.pre.y_buffer; - - for (i = 0; i < 16; ++i) { - if (labels[i] == which_label) { - BLOCKD *bd = &x->e_mbd.block[i]; - BLOCK *be = &x->block[i]; - - vp8_build_inter_predictors_b(bd, 16, base_pre, pre_stride, - x->e_mbd.subpixel_predict); - vp8_subtract_b(be, bd, 16); - x->short_fdct4x4(be->src_diff, be->coeff, 32); - x->quantize_b(be, bd); - - distortion += vp8_block_error(be->coeff, bd->dqcoeff); - } - } - - return distortion; -} - -static const unsigned int segmentation_to_sseshift[4] = { 3, 3, 2, 0 }; - -typedef struct { - int_mv *ref_mv; - int_mv mvp; - - int segment_rd; - int segment_num; - int r; - int d; - int segment_yrate; - B_PREDICTION_MODE modes[16]; - int_mv mvs[16]; - unsigned char eobs[16]; - - int mvthresh; - int *mdcounts; - - int_mv sv_mvp[4]; /* save 4 mvp from 8x8 */ - int sv_istep[2]; /* save 2 initial step_param for 16x8/8x16 */ - -} BEST_SEG_INFO; - -static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, BEST_SEG_INFO *bsi, - unsigned int segmentation) { - int i; - int const *labels; - int br = 0; - int bd = 0; - B_PREDICTION_MODE this_mode; - - int label_count; - int this_segment_rd = 0; - int label_mv_thresh; - int rate = 0; - int sbr = 0; - int sbd = 0; - int segmentyrate = 0; - - vp8_variance_fn_ptr_t *v_fn_ptr; - - ENTROPY_CONTEXT_PLANES t_above, t_left; - ENTROPY_CONTEXT_PLANES t_above_b, t_left_b; - - memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES)); - memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES)); - - vp8_zero(t_above_b); - vp8_zero(t_left_b); - - br = 0; - bd = 0; - - v_fn_ptr = &cpi->fn_ptr[segmentation]; - labels = vp8_mbsplits[segmentation]; - label_count = vp8_mbsplit_count[segmentation]; - - /* 64 makes this threshold really big effectively making it so that we - * very rarely check mvs on segments. setting this to 1 would make mv - * thresh roughly equal to what it is for macroblocks - */ - label_mv_thresh = 1 * bsi->mvthresh / label_count; - - /* Segmentation method overheads */ - rate = vp8_cost_token(vp8_mbsplit_tree, vp8_mbsplit_probs, - vp8_mbsplit_encodings + segmentation); - rate += vp8_cost_mv_ref(SPLITMV, bsi->mdcounts); - this_segment_rd += RDCOST(x->rdmult, x->rddiv, rate, 0); - br += rate; - - for (i = 0; i < label_count; ++i) { - int_mv mode_mv[B_MODE_COUNT] = { { 0 }, { 0 } }; - int best_label_rd = INT_MAX; - B_PREDICTION_MODE mode_selected = ZERO4X4; - int bestlabelyrate = 0; - - /* search for the best motion vector on this segment */ - for (this_mode = LEFT4X4; this_mode <= NEW4X4; ++this_mode) { - int this_rd; - int distortion; - int labelyrate; - ENTROPY_CONTEXT_PLANES t_above_s, t_left_s; - ENTROPY_CONTEXT *ta_s; - ENTROPY_CONTEXT *tl_s; - - memcpy(&t_above_s, &t_above, sizeof(ENTROPY_CONTEXT_PLANES)); - memcpy(&t_left_s, &t_left, sizeof(ENTROPY_CONTEXT_PLANES)); - - ta_s = (ENTROPY_CONTEXT *)&t_above_s; - tl_s = (ENTROPY_CONTEXT *)&t_left_s; - - if (this_mode == NEW4X4) { - int sseshift; - int num00; - int step_param = 0; - int further_steps; - int n; - int thissme; - int bestsme = INT_MAX; - int_mv temp_mv; - BLOCK *c; - BLOCKD *e; - - /* Is the best so far sufficiently good that we can't justify - * doing a new motion search. - */ - if (best_label_rd < label_mv_thresh) break; - - if (cpi->compressor_speed) { - if (segmentation == BLOCK_8X16 || segmentation == BLOCK_16X8) { - bsi->mvp.as_int = bsi->sv_mvp[i].as_int; - if (i == 1 && segmentation == BLOCK_16X8) { - bsi->mvp.as_int = bsi->sv_mvp[2].as_int; - } - - step_param = bsi->sv_istep[i]; - } - - /* use previous block's result as next block's MV - * predictor. - */ - if (segmentation == BLOCK_4X4 && i > 0) { - bsi->mvp.as_int = x->e_mbd.block[i - 1].bmi.mv.as_int; - if (i == 4 || i == 8 || i == 12) { - bsi->mvp.as_int = x->e_mbd.block[i - 4].bmi.mv.as_int; - } - step_param = 2; - } - } - - further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param; - - { - int sadpb = x->sadperbit4; - int_mv mvp_full; - - mvp_full.as_mv.row = bsi->mvp.as_mv.row >> 3; - mvp_full.as_mv.col = bsi->mvp.as_mv.col >> 3; - - /* find first label */ - n = vp8_mbsplit_offset[segmentation][i]; - - c = &x->block[n]; - e = &x->e_mbd.block[n]; - - { - bestsme = cpi->diamond_search_sad( - x, c, e, &mvp_full, &mode_mv[NEW4X4], step_param, sadpb, &num00, - v_fn_ptr, x->mvcost, bsi->ref_mv); - - n = num00; - num00 = 0; - - while (n < further_steps) { - n++; - - if (num00) { - num00--; - } else { - thissme = cpi->diamond_search_sad( - x, c, e, &mvp_full, &temp_mv, step_param + n, sadpb, &num00, - v_fn_ptr, x->mvcost, bsi->ref_mv); - - if (thissme < bestsme) { - bestsme = thissme; - mode_mv[NEW4X4].as_int = temp_mv.as_int; - } - } - } - } - - sseshift = segmentation_to_sseshift[segmentation]; - - /* Should we do a full search (best quality only) */ - if ((cpi->compressor_speed == 0) && (bestsme >> sseshift) > 4000) { - /* Check if mvp_full is within the range. */ - vp8_clamp_mv(&mvp_full, x->mv_col_min, x->mv_col_max, x->mv_row_min, - x->mv_row_max); - - thissme = vp8_full_search_sad(x, c, e, &mvp_full, sadpb, 16, - v_fn_ptr, x->mvcost, bsi->ref_mv); - - if (thissme < bestsme) { - bestsme = thissme; - mode_mv[NEW4X4].as_int = e->bmi.mv.as_int; - } else { - /* The full search result is actually worse so - * re-instate the previous best vector - */ - e->bmi.mv.as_int = mode_mv[NEW4X4].as_int; - } - } - } - - if (bestsme < INT_MAX) { - int disto; - unsigned int sse; - cpi->find_fractional_mv_step(x, c, e, &mode_mv[NEW4X4], bsi->ref_mv, - x->errorperbit, v_fn_ptr, x->mvcost, - &disto, &sse); - } - } /* NEW4X4 */ - - rate = labels2mode(x, labels, i, this_mode, &mode_mv[this_mode], - bsi->ref_mv, x->mvcost); - - /* Trap vectors that reach beyond the UMV borders */ - if (((mode_mv[this_mode].as_mv.row >> 3) < x->mv_row_min) || - ((mode_mv[this_mode].as_mv.row >> 3) > x->mv_row_max) || - ((mode_mv[this_mode].as_mv.col >> 3) < x->mv_col_min) || - ((mode_mv[this_mode].as_mv.col >> 3) > x->mv_col_max)) { - continue; - } - - distortion = vp8_encode_inter_mb_segment(x, labels, i) / 4; - - labelyrate = rdcost_mbsegment_y(x, labels, i, ta_s, tl_s); - rate += labelyrate; - - this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion); - - if (this_rd < best_label_rd) { - sbr = rate; - sbd = distortion; - bestlabelyrate = labelyrate; - mode_selected = this_mode; - best_label_rd = this_rd; - - memcpy(&t_above_b, &t_above_s, sizeof(ENTROPY_CONTEXT_PLANES)); - memcpy(&t_left_b, &t_left_s, sizeof(ENTROPY_CONTEXT_PLANES)); - } - } /*for each 4x4 mode*/ - - memcpy(&t_above, &t_above_b, sizeof(ENTROPY_CONTEXT_PLANES)); - memcpy(&t_left, &t_left_b, sizeof(ENTROPY_CONTEXT_PLANES)); - - labels2mode(x, labels, i, mode_selected, &mode_mv[mode_selected], - bsi->ref_mv, x->mvcost); - - br += sbr; - bd += sbd; - segmentyrate += bestlabelyrate; - this_segment_rd += best_label_rd; - - if (this_segment_rd >= bsi->segment_rd) break; - - } /* for each label */ - - if (this_segment_rd < bsi->segment_rd) { - bsi->r = br; - bsi->d = bd; - bsi->segment_yrate = segmentyrate; - bsi->segment_rd = this_segment_rd; - bsi->segment_num = segmentation; - - /* store everything needed to come back to this!! */ - for (i = 0; i < 16; ++i) { - bsi->mvs[i].as_mv = x->partition_info->bmi[i].mv.as_mv; - bsi->modes[i] = x->partition_info->bmi[i].mode; - bsi->eobs[i] = x->e_mbd.eobs[i]; - } - } -} - -static void vp8_cal_step_param(int sr, int *sp) { - int step = 0; - - if (sr > MAX_FIRST_STEP) { - sr = MAX_FIRST_STEP; - } else if (sr < 1) { - sr = 1; - } - - while (sr >>= 1) step++; - - *sp = MAX_MVSEARCH_STEPS - 1 - step; -} - -static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, - int_mv *best_ref_mv, int best_rd, - int *mdcounts, int *returntotrate, - int *returnyrate, - int *returndistortion, - int mvthresh) { - int i; - BEST_SEG_INFO bsi; - - memset(&bsi, 0, sizeof(bsi)); - - bsi.segment_rd = best_rd; - bsi.ref_mv = best_ref_mv; - bsi.mvp.as_int = best_ref_mv->as_int; - bsi.mvthresh = mvthresh; - bsi.mdcounts = mdcounts; - - for (i = 0; i < 16; ++i) { - bsi.modes[i] = ZERO4X4; - } - - if (cpi->compressor_speed == 0) { - /* for now, we will keep the original segmentation order - when in best quality mode */ - rd_check_segment(cpi, x, &bsi, BLOCK_16X8); - rd_check_segment(cpi, x, &bsi, BLOCK_8X16); - rd_check_segment(cpi, x, &bsi, BLOCK_8X8); - rd_check_segment(cpi, x, &bsi, BLOCK_4X4); - } else { - int sr; - - rd_check_segment(cpi, x, &bsi, BLOCK_8X8); - - if (bsi.segment_rd < best_rd) { - int col_min = ((best_ref_mv->as_mv.col + 7) >> 3) - MAX_FULL_PEL_VAL; - int row_min = ((best_ref_mv->as_mv.row + 7) >> 3) - MAX_FULL_PEL_VAL; - int col_max = (best_ref_mv->as_mv.col >> 3) + MAX_FULL_PEL_VAL; - int row_max = (best_ref_mv->as_mv.row >> 3) + MAX_FULL_PEL_VAL; - - int tmp_col_min = x->mv_col_min; - int tmp_col_max = x->mv_col_max; - int tmp_row_min = x->mv_row_min; - int tmp_row_max = x->mv_row_max; - - /* Get intersection of UMV window and valid MV window to reduce # of - * checks in diamond search. */ - if (x->mv_col_min < col_min) x->mv_col_min = col_min; - if (x->mv_col_max > col_max) x->mv_col_max = col_max; - if (x->mv_row_min < row_min) x->mv_row_min = row_min; - if (x->mv_row_max > row_max) x->mv_row_max = row_max; - - /* Get 8x8 result */ - bsi.sv_mvp[0].as_int = bsi.mvs[0].as_int; - bsi.sv_mvp[1].as_int = bsi.mvs[2].as_int; - bsi.sv_mvp[2].as_int = bsi.mvs[8].as_int; - bsi.sv_mvp[3].as_int = bsi.mvs[10].as_int; - - /* Use 8x8 result as 16x8/8x16's predictor MV. Adjust search range - * according to the closeness of 2 MV. */ - /* block 8X16 */ - { - sr = - MAXF((abs(bsi.sv_mvp[0].as_mv.row - bsi.sv_mvp[2].as_mv.row)) >> 3, - (abs(bsi.sv_mvp[0].as_mv.col - bsi.sv_mvp[2].as_mv.col)) >> 3); - vp8_cal_step_param(sr, &bsi.sv_istep[0]); - - sr = - MAXF((abs(bsi.sv_mvp[1].as_mv.row - bsi.sv_mvp[3].as_mv.row)) >> 3, - (abs(bsi.sv_mvp[1].as_mv.col - bsi.sv_mvp[3].as_mv.col)) >> 3); - vp8_cal_step_param(sr, &bsi.sv_istep[1]); - - rd_check_segment(cpi, x, &bsi, BLOCK_8X16); - } - - /* block 16X8 */ - { - sr = - MAXF((abs(bsi.sv_mvp[0].as_mv.row - bsi.sv_mvp[1].as_mv.row)) >> 3, - (abs(bsi.sv_mvp[0].as_mv.col - bsi.sv_mvp[1].as_mv.col)) >> 3); - vp8_cal_step_param(sr, &bsi.sv_istep[0]); - - sr = - MAXF((abs(bsi.sv_mvp[2].as_mv.row - bsi.sv_mvp[3].as_mv.row)) >> 3, - (abs(bsi.sv_mvp[2].as_mv.col - bsi.sv_mvp[3].as_mv.col)) >> 3); - vp8_cal_step_param(sr, &bsi.sv_istep[1]); - - rd_check_segment(cpi, x, &bsi, BLOCK_16X8); - } - - /* If 8x8 is better than 16x8/8x16, then do 4x4 search */ - /* Not skip 4x4 if speed=0 (good quality) */ - if (cpi->sf.no_skip_block4x4_search || bsi.segment_num == BLOCK_8X8) - /* || (sv_segment_rd8x8-bsi.segment_rd) < sv_segment_rd8x8>>5) */ - { - bsi.mvp.as_int = bsi.sv_mvp[0].as_int; - rd_check_segment(cpi, x, &bsi, BLOCK_4X4); - } - - /* restore UMV window */ - x->mv_col_min = tmp_col_min; - x->mv_col_max = tmp_col_max; - x->mv_row_min = tmp_row_min; - x->mv_row_max = tmp_row_max; - } - } - - /* set it to the best */ - for (i = 0; i < 16; ++i) { - BLOCKD *bd = &x->e_mbd.block[i]; - - bd->bmi.mv.as_int = bsi.mvs[i].as_int; - *bd->eob = bsi.eobs[i]; - } - - *returntotrate = bsi.r; - *returndistortion = bsi.d; - *returnyrate = bsi.segment_yrate; - - /* save partitions */ - x->e_mbd.mode_info_context->mbmi.partitioning = bsi.segment_num; - x->partition_info->count = vp8_mbsplit_count[bsi.segment_num]; - - for (i = 0; i < x->partition_info->count; ++i) { - int j; - - j = vp8_mbsplit_offset[bsi.segment_num][i]; - - x->partition_info->bmi[i].mode = bsi.modes[j]; - x->partition_info->bmi[i].mv.as_mv = bsi.mvs[j].as_mv; - } - /* - * used to set x->e_mbd.mode_info_context->mbmi.mv.as_int - */ - x->partition_info->bmi[15].mv.as_int = bsi.mvs[15].as_int; - - return bsi.segment_rd; -} - -/* The improved MV prediction */ -void vp8_mv_pred(VP8_COMP *cpi, MACROBLOCKD *xd, const MODE_INFO *here, - int_mv *mvp, int refframe, int *ref_frame_sign_bias, int *sr, - int near_sadidx[]) { - const MODE_INFO *above = here - xd->mode_info_stride; - const MODE_INFO *left = here - 1; - const MODE_INFO *aboveleft = above - 1; - int_mv near_mvs[8]; - int near_ref[8]; - int_mv mv; - int vcnt = 0; - int find = 0; - int mb_offset; - - int mvx[8]; - int mvy[8]; - int i; - - mv.as_int = 0; - - if (here->mbmi.ref_frame != INTRA_FRAME) { - near_mvs[0].as_int = near_mvs[1].as_int = near_mvs[2].as_int = - near_mvs[3].as_int = near_mvs[4].as_int = near_mvs[5].as_int = - near_mvs[6].as_int = near_mvs[7].as_int = 0; - near_ref[0] = near_ref[1] = near_ref[2] = near_ref[3] = near_ref[4] = - near_ref[5] = near_ref[6] = near_ref[7] = 0; - - /* read in 3 nearby block's MVs from current frame as prediction - * candidates. - */ - if (above->mbmi.ref_frame != INTRA_FRAME) { - near_mvs[vcnt].as_int = above->mbmi.mv.as_int; - mv_bias(ref_frame_sign_bias[above->mbmi.ref_frame], refframe, - &near_mvs[vcnt], ref_frame_sign_bias); - near_ref[vcnt] = above->mbmi.ref_frame; - } - vcnt++; - if (left->mbmi.ref_frame != INTRA_FRAME) { - near_mvs[vcnt].as_int = left->mbmi.mv.as_int; - mv_bias(ref_frame_sign_bias[left->mbmi.ref_frame], refframe, - &near_mvs[vcnt], ref_frame_sign_bias); - near_ref[vcnt] = left->mbmi.ref_frame; - } - vcnt++; - if (aboveleft->mbmi.ref_frame != INTRA_FRAME) { - near_mvs[vcnt].as_int = aboveleft->mbmi.mv.as_int; - mv_bias(ref_frame_sign_bias[aboveleft->mbmi.ref_frame], refframe, - &near_mvs[vcnt], ref_frame_sign_bias); - near_ref[vcnt] = aboveleft->mbmi.ref_frame; - } - vcnt++; - - /* read in 5 nearby block's MVs from last frame. */ - if (cpi->common.last_frame_type != KEY_FRAME) { - mb_offset = (-xd->mb_to_top_edge / 128 + 1) * (xd->mode_info_stride + 1) + - (-xd->mb_to_left_edge / 128 + 1); - - /* current in last frame */ - if (cpi->lf_ref_frame[mb_offset] != INTRA_FRAME) { - near_mvs[vcnt].as_int = cpi->lfmv[mb_offset].as_int; - mv_bias(cpi->lf_ref_frame_sign_bias[mb_offset], refframe, - &near_mvs[vcnt], ref_frame_sign_bias); - near_ref[vcnt] = cpi->lf_ref_frame[mb_offset]; - } - vcnt++; - - /* above in last frame */ - if (cpi->lf_ref_frame[mb_offset - xd->mode_info_stride - 1] != - INTRA_FRAME) { - near_mvs[vcnt].as_int = - cpi->lfmv[mb_offset - xd->mode_info_stride - 1].as_int; - mv_bias( - cpi->lf_ref_frame_sign_bias[mb_offset - xd->mode_info_stride - 1], - refframe, &near_mvs[vcnt], ref_frame_sign_bias); - near_ref[vcnt] = - cpi->lf_ref_frame[mb_offset - xd->mode_info_stride - 1]; - } - vcnt++; - - /* left in last frame */ - if (cpi->lf_ref_frame[mb_offset - 1] != INTRA_FRAME) { - near_mvs[vcnt].as_int = cpi->lfmv[mb_offset - 1].as_int; - mv_bias(cpi->lf_ref_frame_sign_bias[mb_offset - 1], refframe, - &near_mvs[vcnt], ref_frame_sign_bias); - near_ref[vcnt] = cpi->lf_ref_frame[mb_offset - 1]; - } - vcnt++; - - /* right in last frame */ - if (cpi->lf_ref_frame[mb_offset + 1] != INTRA_FRAME) { - near_mvs[vcnt].as_int = cpi->lfmv[mb_offset + 1].as_int; - mv_bias(cpi->lf_ref_frame_sign_bias[mb_offset + 1], refframe, - &near_mvs[vcnt], ref_frame_sign_bias); - near_ref[vcnt] = cpi->lf_ref_frame[mb_offset + 1]; - } - vcnt++; - - /* below in last frame */ - if (cpi->lf_ref_frame[mb_offset + xd->mode_info_stride + 1] != - INTRA_FRAME) { - near_mvs[vcnt].as_int = - cpi->lfmv[mb_offset + xd->mode_info_stride + 1].as_int; - mv_bias( - cpi->lf_ref_frame_sign_bias[mb_offset + xd->mode_info_stride + 1], - refframe, &near_mvs[vcnt], ref_frame_sign_bias); - near_ref[vcnt] = - cpi->lf_ref_frame[mb_offset + xd->mode_info_stride + 1]; - } - vcnt++; - } - - for (i = 0; i < vcnt; ++i) { - if (near_ref[near_sadidx[i]] != INTRA_FRAME) { - if (here->mbmi.ref_frame == near_ref[near_sadidx[i]]) { - mv.as_int = near_mvs[near_sadidx[i]].as_int; - find = 1; - if (i < 3) { - *sr = 3; - } else { - *sr = 2; - } - break; - } - } - } - - if (!find) { - for (i = 0; i < vcnt; ++i) { - mvx[i] = near_mvs[i].as_mv.row; - mvy[i] = near_mvs[i].as_mv.col; - } - - insertsortmv(mvx, vcnt); - insertsortmv(mvy, vcnt); - mv.as_mv.row = mvx[vcnt / 2]; - mv.as_mv.col = mvy[vcnt / 2]; - - /* sr is set to 0 to allow calling function to decide the search - * range. - */ - *sr = 0; - } - } - - /* Set up return values */ - mvp->as_int = mv.as_int; - vp8_clamp_mv2(mvp, xd); -} - -void vp8_cal_sad(VP8_COMP *cpi, MACROBLOCKD *xd, MACROBLOCK *x, - int recon_yoffset, int near_sadidx[]) { - /* near_sad indexes: - * 0-cf above, 1-cf left, 2-cf aboveleft, - * 3-lf current, 4-lf above, 5-lf left, 6-lf right, 7-lf below - */ - int near_sad[8] = { 0 }; - BLOCK *b = &x->block[0]; - unsigned char *src_y_ptr = *(b->base_src); - - /* calculate sad for current frame 3 nearby MBs. */ - if (xd->mb_to_top_edge == 0 && xd->mb_to_left_edge == 0) { - near_sad[0] = near_sad[1] = near_sad[2] = INT_MAX; - } else if (xd->mb_to_top_edge == - 0) { /* only has left MB for sad calculation. */ - near_sad[0] = near_sad[2] = INT_MAX; - near_sad[1] = cpi->fn_ptr[BLOCK_16X16].sdf( - src_y_ptr, b->src_stride, xd->dst.y_buffer - 16, xd->dst.y_stride); - } else if (xd->mb_to_left_edge == - 0) { /* only has left MB for sad calculation. */ - near_sad[1] = near_sad[2] = INT_MAX; - near_sad[0] = cpi->fn_ptr[BLOCK_16X16].sdf( - src_y_ptr, b->src_stride, xd->dst.y_buffer - xd->dst.y_stride * 16, - xd->dst.y_stride); - } else { - near_sad[0] = cpi->fn_ptr[BLOCK_16X16].sdf( - src_y_ptr, b->src_stride, xd->dst.y_buffer - xd->dst.y_stride * 16, - xd->dst.y_stride); - near_sad[1] = cpi->fn_ptr[BLOCK_16X16].sdf( - src_y_ptr, b->src_stride, xd->dst.y_buffer - 16, xd->dst.y_stride); - near_sad[2] = cpi->fn_ptr[BLOCK_16X16].sdf( - src_y_ptr, b->src_stride, xd->dst.y_buffer - xd->dst.y_stride * 16 - 16, - xd->dst.y_stride); - } - - if (cpi->common.last_frame_type != KEY_FRAME) { - /* calculate sad for last frame 5 nearby MBs. */ - unsigned char *pre_y_buffer = - cpi->common.yv12_fb[cpi->common.lst_fb_idx].y_buffer + recon_yoffset; - int pre_y_stride = cpi->common.yv12_fb[cpi->common.lst_fb_idx].y_stride; - - if (xd->mb_to_top_edge == 0) near_sad[4] = INT_MAX; - if (xd->mb_to_left_edge == 0) near_sad[5] = INT_MAX; - if (xd->mb_to_right_edge == 0) near_sad[6] = INT_MAX; - if (xd->mb_to_bottom_edge == 0) near_sad[7] = INT_MAX; - - if (near_sad[4] != INT_MAX) { - near_sad[4] = cpi->fn_ptr[BLOCK_16X16].sdf( - src_y_ptr, b->src_stride, pre_y_buffer - pre_y_stride * 16, - pre_y_stride); - } - if (near_sad[5] != INT_MAX) { - near_sad[5] = cpi->fn_ptr[BLOCK_16X16].sdf( - src_y_ptr, b->src_stride, pre_y_buffer - 16, pre_y_stride); - } - near_sad[3] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, - pre_y_buffer, pre_y_stride); - if (near_sad[6] != INT_MAX) { - near_sad[6] = cpi->fn_ptr[BLOCK_16X16].sdf( - src_y_ptr, b->src_stride, pre_y_buffer + 16, pre_y_stride); - } - if (near_sad[7] != INT_MAX) { - near_sad[7] = cpi->fn_ptr[BLOCK_16X16].sdf( - src_y_ptr, b->src_stride, pre_y_buffer + pre_y_stride * 16, - pre_y_stride); - } - } - - if (cpi->common.last_frame_type != KEY_FRAME) { - insertsortsad(near_sad, near_sadidx, 8); - } else { - insertsortsad(near_sad, near_sadidx, 3); - } -} - -static void rd_update_mvcount(MACROBLOCK *x, int_mv *best_ref_mv) { - if (x->e_mbd.mode_info_context->mbmi.mode == SPLITMV) { - int i; - - for (i = 0; i < x->partition_info->count; ++i) { - if (x->partition_info->bmi[i].mode == NEW4X4) { - const int row_val = ((x->partition_info->bmi[i].mv.as_mv.row - - best_ref_mv->as_mv.row) >> - 1); - const int row_idx = mv_max + row_val; - const int col_val = ((x->partition_info->bmi[i].mv.as_mv.col - - best_ref_mv->as_mv.col) >> - 1); - const int col_idx = mv_max + col_val; - if (row_idx >= 0 && row_idx < MVvals && col_idx >= 0 && - col_idx < MVvals) { - x->MVcount[0][row_idx]++; - x->MVcount[1][col_idx]++; - } - } - } - } else if (x->e_mbd.mode_info_context->mbmi.mode == NEWMV) { - const int row_val = ((x->e_mbd.mode_info_context->mbmi.mv.as_mv.row - - best_ref_mv->as_mv.row) >> - 1); - const int row_idx = mv_max + row_val; - const int col_val = ((x->e_mbd.mode_info_context->mbmi.mv.as_mv.col - - best_ref_mv->as_mv.col) >> - 1); - const int col_idx = mv_max + col_val; - if (row_idx >= 0 && row_idx < MVvals && col_idx >= 0 && col_idx < MVvals) { - x->MVcount[0][row_idx]++; - x->MVcount[1][col_idx]++; - } - } -} - -static int evaluate_inter_mode_rd(int mdcounts[4], RATE_DISTORTION *rd, - int *disable_skip, VP8_COMP *cpi, - MACROBLOCK *x) { - MB_PREDICTION_MODE this_mode = x->e_mbd.mode_info_context->mbmi.mode; - BLOCK *b = &x->block[0]; - MACROBLOCKD *xd = &x->e_mbd; - int distortion; - vp8_build_inter16x16_predictors_mby(&x->e_mbd, x->e_mbd.predictor, 16); - - if (cpi->active_map_enabled && x->active_ptr[0] == 0) { - x->skip = 1; - } else if (x->encode_breakout) { - unsigned int sse; - unsigned int var; - unsigned int threshold = - (xd->block[0].dequant[1] * xd->block[0].dequant[1] >> 4); - - if (threshold < x->encode_breakout) threshold = x->encode_breakout; - - var = vpx_variance16x16(*(b->base_src), b->src_stride, x->e_mbd.predictor, - 16, &sse); - - if (sse < threshold) { - unsigned int q2dc = xd->block[24].dequant[0]; - /* If theres is no codeable 2nd order dc - or a very small uniform pixel change change */ - if ((sse - var < q2dc * q2dc >> 4) || (sse / 2 > var && sse - var < 64)) { - /* Check u and v to make sure skip is ok */ - unsigned int sse2 = VP8_UVSSE(x); - if (sse2 * 2 < threshold) { - x->skip = 1; - rd->distortion2 = sse + sse2; - rd->rate2 = 500; - - /* for best_yrd calculation */ - rd->rate_uv = 0; - rd->distortion_uv = sse2; - - *disable_skip = 1; - return RDCOST(x->rdmult, x->rddiv, rd->rate2, rd->distortion2); - } - } - } - } - - /* Add in the Mv/mode cost */ - rd->rate2 += vp8_cost_mv_ref(this_mode, mdcounts); - - /* Y cost and distortion */ - macro_block_yrd(x, &rd->rate_y, &distortion); - rd->rate2 += rd->rate_y; - rd->distortion2 += distortion; - - /* UV cost and distortion */ - rd_inter16x16_uv(cpi, x, &rd->rate_uv, &rd->distortion_uv, - cpi->common.full_pixel); - rd->rate2 += rd->rate_uv; - rd->distortion2 += rd->distortion_uv; - return INT_MAX; -} - -static int calculate_final_rd_costs(int this_rd, RATE_DISTORTION *rd, - int *other_cost, int disable_skip, - int uv_intra_tteob, int intra_rd_penalty, - VP8_COMP *cpi, MACROBLOCK *x) { - MB_PREDICTION_MODE this_mode = x->e_mbd.mode_info_context->mbmi.mode; - - /* Where skip is allowable add in the default per mb cost for the no - * skip case. where we then decide to skip we have to delete this and - * replace it with the cost of signalling a skip - */ - if (cpi->common.mb_no_coeff_skip) { - *other_cost += vp8_cost_bit(cpi->prob_skip_false, 0); - rd->rate2 += *other_cost; - } - - /* Estimate the reference frame signaling cost and add it - * to the rolling cost variable. - */ - rd->rate2 += x->ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame]; - - if (!disable_skip) { - /* Test for the condition where skip block will be activated - * because there are no non zero coefficients and make any - * necessary adjustment for rate - */ - if (cpi->common.mb_no_coeff_skip) { - int i; - int tteob; - int has_y2_block = (this_mode != SPLITMV && this_mode != B_PRED); - - tteob = 0; - if (has_y2_block) tteob += x->e_mbd.eobs[24]; - - for (i = 0; i < 16; ++i) tteob += (x->e_mbd.eobs[i] > has_y2_block); - - if (x->e_mbd.mode_info_context->mbmi.ref_frame) { - for (i = 16; i < 24; ++i) tteob += x->e_mbd.eobs[i]; - } else { - tteob += uv_intra_tteob; - } - - if (tteob == 0) { - rd->rate2 -= (rd->rate_y + rd->rate_uv); - /* for best_yrd calculation */ - rd->rate_uv = 0; - - /* Back out no skip flag costing and add in skip flag costing */ - if (cpi->prob_skip_false) { - int prob_skip_cost; - - prob_skip_cost = vp8_cost_bit(cpi->prob_skip_false, 1); - prob_skip_cost -= (int)vp8_cost_bit(cpi->prob_skip_false, 0); - rd->rate2 += prob_skip_cost; - *other_cost += prob_skip_cost; - } - } - } - /* Calculate the final RD estimate for this mode */ - this_rd = RDCOST(x->rdmult, x->rddiv, rd->rate2, rd->distortion2); - if (this_rd < INT_MAX && - x->e_mbd.mode_info_context->mbmi.ref_frame == INTRA_FRAME) { - this_rd += intra_rd_penalty; - } - } - return this_rd; -} - -static void update_best_mode(BEST_MODE *best_mode, int this_rd, - RATE_DISTORTION *rd, int other_cost, - MACROBLOCK *x) { - MB_PREDICTION_MODE this_mode = x->e_mbd.mode_info_context->mbmi.mode; - - other_cost += x->ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame]; - - /* Calculate the final y RD estimate for this mode */ - best_mode->yrd = - RDCOST(x->rdmult, x->rddiv, (rd->rate2 - rd->rate_uv - other_cost), - (rd->distortion2 - rd->distortion_uv)); - - best_mode->rd = this_rd; - memcpy(&best_mode->mbmode, &x->e_mbd.mode_info_context->mbmi, - sizeof(MB_MODE_INFO)); - memcpy(&best_mode->partition, x->partition_info, sizeof(PARTITION_INFO)); - - if ((this_mode == B_PRED) || (this_mode == SPLITMV)) { - int i; - for (i = 0; i < 16; ++i) { - best_mode->bmodes[i] = x->e_mbd.block[i].bmi; - } - } -} - -void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, - int recon_uvoffset, int *returnrate, - int *returndistortion, int *returnintra, int mb_row, - int mb_col) { - BLOCK *b = &x->block[0]; - BLOCKD *d = &x->e_mbd.block[0]; - MACROBLOCKD *xd = &x->e_mbd; - int_mv best_ref_mv_sb[2]; - int_mv mode_mv_sb[2][MB_MODE_COUNT]; - int_mv best_ref_mv; - int_mv *mode_mv; - MB_PREDICTION_MODE this_mode; - int num00; - int best_mode_index = 0; - BEST_MODE best_mode; - - int i; - int mode_index; - int mdcounts[4]; - int rate; - RATE_DISTORTION rd; - int uv_intra_rate, uv_intra_distortion, uv_intra_rate_tokenonly; - int uv_intra_tteob = 0; - int uv_intra_done = 0; - - MB_PREDICTION_MODE uv_intra_mode = 0; - int_mv mvp; - int near_sadidx[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - int saddone = 0; - /* search range got from mv_pred(). It uses step_param levels. (0-7) */ - int sr = 0; - - unsigned char *plane[4][3] = { { 0, 0 } }; - int ref_frame_map[4]; - int sign_bias = 0; - - int intra_rd_penalty = - 10 * vp8_dc_quant(cpi->common.base_qindex, cpi->common.y1dc_delta_q); - -#if CONFIG_TEMPORAL_DENOISING - unsigned int zero_mv_sse = UINT_MAX, best_sse = UINT_MAX, - best_rd_sse = UINT_MAX; -#endif - - // _uv variables are not set consistantly before calling update_best_mode. - rd.rate_uv = 0; - rd.distortion_uv = 0; - - mode_mv = mode_mv_sb[sign_bias]; - best_ref_mv.as_int = 0; - best_mode.rd = INT_MAX; - best_mode.yrd = INT_MAX; - best_mode.intra_rd = INT_MAX; - memset(mode_mv_sb, 0, sizeof(mode_mv_sb)); - memset(&best_mode.mbmode, 0, sizeof(best_mode.mbmode)); - memset(&best_mode.bmodes, 0, sizeof(best_mode.bmodes)); - - /* Setup search priorities */ - get_reference_search_order(cpi, ref_frame_map); - - /* Check to see if there is at least 1 valid reference frame that we need - * to calculate near_mvs. - */ - if (ref_frame_map[1] > 0) { - sign_bias = vp8_find_near_mvs_bias( - &x->e_mbd, x->e_mbd.mode_info_context, mode_mv_sb, best_ref_mv_sb, - mdcounts, ref_frame_map[1], cpi->common.ref_frame_sign_bias); - - mode_mv = mode_mv_sb[sign_bias]; - best_ref_mv.as_int = best_ref_mv_sb[sign_bias].as_int; - } - - get_predictor_pointers(cpi, plane, recon_yoffset, recon_uvoffset); - - *returnintra = INT_MAX; - /* Count of the number of MBs tested so far this frame */ - x->mbs_tested_so_far++; - - x->skip = 0; - - for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) { - int this_rd = INT_MAX; - int disable_skip = 0; - int other_cost = 0; - int this_ref_frame = ref_frame_map[vp8_ref_frame_order[mode_index]]; - - /* Test best rd so far against threshold for trying this mode. */ - if (best_mode.rd <= x->rd_threshes[mode_index]) continue; - - if (this_ref_frame < 0) continue; - - /* These variables hold are rolling total cost and distortion for - * this mode - */ - rd.rate2 = 0; - rd.distortion2 = 0; - - this_mode = vp8_mode_order[mode_index]; - - x->e_mbd.mode_info_context->mbmi.mode = this_mode; - x->e_mbd.mode_info_context->mbmi.ref_frame = this_ref_frame; - - /* Only consider ZEROMV/ALTREF_FRAME for alt ref frame, - * unless ARNR filtering is enabled in which case we want - * an unfiltered alternative - */ - if (cpi->is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) { - if (this_mode != ZEROMV || - x->e_mbd.mode_info_context->mbmi.ref_frame != ALTREF_FRAME) { - continue; - } - } - - /* everything but intra */ - if (x->e_mbd.mode_info_context->mbmi.ref_frame) { - assert(plane[this_ref_frame][0] != NULL && - plane[this_ref_frame][1] != NULL && - plane[this_ref_frame][2] != NULL); - x->e_mbd.pre.y_buffer = plane[this_ref_frame][0]; - x->e_mbd.pre.u_buffer = plane[this_ref_frame][1]; - x->e_mbd.pre.v_buffer = plane[this_ref_frame][2]; - - if (sign_bias != cpi->common.ref_frame_sign_bias[this_ref_frame]) { - sign_bias = cpi->common.ref_frame_sign_bias[this_ref_frame]; - mode_mv = mode_mv_sb[sign_bias]; - best_ref_mv.as_int = best_ref_mv_sb[sign_bias].as_int; - } - } - - /* Check to see if the testing frequency for this mode is at its - * max If so then prevent it from being tested and increase the - * threshold for its testing - */ - if (x->mode_test_hit_counts[mode_index] && - (cpi->mode_check_freq[mode_index] > 1)) { - if (x->mbs_tested_so_far <= cpi->mode_check_freq[mode_index] * - x->mode_test_hit_counts[mode_index]) { - /* Increase the threshold for coding this mode to make it - * less likely to be chosen - */ - x->rd_thresh_mult[mode_index] += 4; - - if (x->rd_thresh_mult[mode_index] > MAX_THRESHMULT) { - x->rd_thresh_mult[mode_index] = MAX_THRESHMULT; - } - - x->rd_threshes[mode_index] = - (cpi->rd_baseline_thresh[mode_index] >> 7) * - x->rd_thresh_mult[mode_index]; - - continue; - } - } - - /* We have now reached the point where we are going to test the - * current mode so increment the counter for the number of times - * it has been tested - */ - x->mode_test_hit_counts[mode_index]++; - - /* Experimental code. Special case for gf and arf zeromv modes. - * Increase zbin size to supress noise - */ - if (x->zbin_mode_boost_enabled) { - if (this_ref_frame == INTRA_FRAME) { - x->zbin_mode_boost = 0; - } else { - if (vp8_mode_order[mode_index] == ZEROMV) { - if (this_ref_frame != LAST_FRAME) { - x->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST; - } else { - x->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST; - } - } else if (vp8_mode_order[mode_index] == SPLITMV) { - x->zbin_mode_boost = 0; - } else { - x->zbin_mode_boost = MV_ZBIN_BOOST; - } - } - - vp8_update_zbin_extra(cpi, x); - } - - if (!uv_intra_done && this_ref_frame == INTRA_FRAME) { - rd_pick_intra_mbuv_mode(x, &uv_intra_rate, &uv_intra_rate_tokenonly, - &uv_intra_distortion); - uv_intra_mode = x->e_mbd.mode_info_context->mbmi.uv_mode; - - /* - * Total of the eobs is used later to further adjust rate2. Since uv - * block's intra eobs will be overwritten when we check inter modes, - * we need to save uv_intra_tteob here. - */ - for (i = 16; i < 24; ++i) uv_intra_tteob += x->e_mbd.eobs[i]; - - uv_intra_done = 1; - } - - switch (this_mode) { - case B_PRED: { - int tmp_rd; - - /* Note the rate value returned here includes the cost of - * coding the BPRED mode: x->mbmode_cost[x->e_mbd.frame_type][BPRED] - */ - int distortion; - tmp_rd = rd_pick_intra4x4mby_modes(x, &rate, &rd.rate_y, &distortion, - best_mode.yrd); - rd.rate2 += rate; - rd.distortion2 += distortion; - - if (tmp_rd < best_mode.yrd) { - assert(uv_intra_done); - rd.rate2 += uv_intra_rate; - rd.rate_uv = uv_intra_rate_tokenonly; - rd.distortion2 += uv_intra_distortion; - rd.distortion_uv = uv_intra_distortion; - } else { - this_rd = INT_MAX; - disable_skip = 1; - } - break; - } - - case SPLITMV: { - int tmp_rd; - int this_rd_thresh; - int distortion; - - this_rd_thresh = (vp8_ref_frame_order[mode_index] == 1) - ? x->rd_threshes[THR_NEW1] - : x->rd_threshes[THR_NEW3]; - this_rd_thresh = (vp8_ref_frame_order[mode_index] == 2) - ? x->rd_threshes[THR_NEW2] - : this_rd_thresh; - - tmp_rd = vp8_rd_pick_best_mbsegmentation( - cpi, x, &best_ref_mv, best_mode.yrd, mdcounts, &rate, &rd.rate_y, - &distortion, this_rd_thresh); - - rd.rate2 += rate; - rd.distortion2 += distortion; - - /* If even the 'Y' rd value of split is higher than best so far - * then don't bother looking at UV - */ - if (tmp_rd < best_mode.yrd) { - /* Now work out UV cost and add it in */ - rd_inter4x4_uv(cpi, x, &rd.rate_uv, &rd.distortion_uv, - cpi->common.full_pixel); - rd.rate2 += rd.rate_uv; - rd.distortion2 += rd.distortion_uv; - } else { - this_rd = INT_MAX; - disable_skip = 1; - } - break; - } - case DC_PRED: - case V_PRED: - case H_PRED: - case TM_PRED: { - int distortion; - x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME; - - vp8_build_intra_predictors_mby_s( - xd, xd->dst.y_buffer - xd->dst.y_stride, xd->dst.y_buffer - 1, - xd->dst.y_stride, xd->predictor, 16); - macro_block_yrd(x, &rd.rate_y, &distortion); - rd.rate2 += rd.rate_y; - rd.distortion2 += distortion; - rd.rate2 += x->mbmode_cost[x->e_mbd.frame_type] - [x->e_mbd.mode_info_context->mbmi.mode]; - assert(uv_intra_done); - rd.rate2 += uv_intra_rate; - rd.rate_uv = uv_intra_rate_tokenonly; - rd.distortion2 += uv_intra_distortion; - rd.distortion_uv = uv_intra_distortion; - break; - } - - case NEWMV: { - int thissme; - int bestsme = INT_MAX; - int step_param = cpi->sf.first_step; - int further_steps; - int n; - /* If last step (1-away) of n-step search doesn't pick the center point - as the best match, we will do a final 1-away diamond refining search - */ - int do_refine = 1; - - int sadpb = x->sadperbit16; - int_mv mvp_full; - - int col_min = ((best_ref_mv.as_mv.col + 7) >> 3) - MAX_FULL_PEL_VAL; - int row_min = ((best_ref_mv.as_mv.row + 7) >> 3) - MAX_FULL_PEL_VAL; - int col_max = (best_ref_mv.as_mv.col >> 3) + MAX_FULL_PEL_VAL; - int row_max = (best_ref_mv.as_mv.row >> 3) + MAX_FULL_PEL_VAL; - - int tmp_col_min = x->mv_col_min; - int tmp_col_max = x->mv_col_max; - int tmp_row_min = x->mv_row_min; - int tmp_row_max = x->mv_row_max; - - if (!saddone) { - vp8_cal_sad(cpi, xd, x, recon_yoffset, &near_sadidx[0]); - saddone = 1; - } - - vp8_mv_pred(cpi, &x->e_mbd, x->e_mbd.mode_info_context, &mvp, - x->e_mbd.mode_info_context->mbmi.ref_frame, - cpi->common.ref_frame_sign_bias, &sr, &near_sadidx[0]); - - mvp_full.as_mv.col = mvp.as_mv.col >> 3; - mvp_full.as_mv.row = mvp.as_mv.row >> 3; - - /* Get intersection of UMV window and valid MV window to - * reduce # of checks in diamond search. - */ - if (x->mv_col_min < col_min) x->mv_col_min = col_min; - if (x->mv_col_max > col_max) x->mv_col_max = col_max; - if (x->mv_row_min < row_min) x->mv_row_min = row_min; - if (x->mv_row_max > row_max) x->mv_row_max = row_max; - - /* adjust search range according to sr from mv prediction */ - if (sr > step_param) step_param = sr; - - /* Initial step/diamond search */ - { - bestsme = cpi->diamond_search_sad( - x, b, d, &mvp_full, &d->bmi.mv, step_param, sadpb, &num00, - &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &best_ref_mv); - mode_mv[NEWMV].as_int = d->bmi.mv.as_int; - - /* Further step/diamond searches as necessary */ - further_steps = (cpi->sf.max_step_search_steps - 1) - step_param; - - n = num00; - num00 = 0; - - /* If there won't be more n-step search, check to see if refining - * search is needed. */ - if (n > further_steps) do_refine = 0; - - while (n < further_steps) { - n++; - - if (num00) { - num00--; - } else { - thissme = cpi->diamond_search_sad( - x, b, d, &mvp_full, &d->bmi.mv, step_param + n, sadpb, &num00, - &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &best_ref_mv); - - /* check to see if refining search is needed. */ - if (num00 > (further_steps - n)) do_refine = 0; - - if (thissme < bestsme) { - bestsme = thissme; - mode_mv[NEWMV].as_int = d->bmi.mv.as_int; - } else { - d->bmi.mv.as_int = mode_mv[NEWMV].as_int; - } - } - } - } - - /* final 1-away diamond refining search */ - if (do_refine == 1) { - int search_range; - - search_range = 8; - - thissme = cpi->refining_search_sad( - x, b, d, &d->bmi.mv, sadpb, search_range, - &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &best_ref_mv); - - if (thissme < bestsme) { - bestsme = thissme; - mode_mv[NEWMV].as_int = d->bmi.mv.as_int; - } else { - d->bmi.mv.as_int = mode_mv[NEWMV].as_int; - } - } - - x->mv_col_min = tmp_col_min; - x->mv_col_max = tmp_col_max; - x->mv_row_min = tmp_row_min; - x->mv_row_max = tmp_row_max; - - if (bestsme < INT_MAX) { - int dis; /* TODO: use dis in distortion calculation later. */ - unsigned int sse; - cpi->find_fractional_mv_step( - x, b, d, &d->bmi.mv, &best_ref_mv, x->errorperbit, - &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &dis, &sse); - } - - mode_mv[NEWMV].as_int = d->bmi.mv.as_int; - - /* Add the new motion vector cost to our rolling cost variable */ - rd.rate2 += - vp8_mv_bit_cost(&mode_mv[NEWMV], &best_ref_mv, x->mvcost, 96); - } - // fall through - - case NEARESTMV: - case NEARMV: - /* Clip "next_nearest" so that it does not extend to far out - * of image - */ - vp8_clamp_mv2(&mode_mv[this_mode], xd); - - /* Do not bother proceeding if the vector (from newmv, nearest - * or near) is 0,0 as this should then be coded using the zeromv - * mode. - */ - if (((this_mode == NEARMV) || (this_mode == NEARESTMV)) && - (mode_mv[this_mode].as_int == 0)) { - continue; - } - // fall through - - case ZEROMV: - - /* Trap vectors that reach beyond the UMV borders - * Note that ALL New MV, Nearest MV Near MV and Zero MV code - * drops through to this point because of the lack of break - * statements in the previous two cases. - */ - if (((mode_mv[this_mode].as_mv.row >> 3) < x->mv_row_min) || - ((mode_mv[this_mode].as_mv.row >> 3) > x->mv_row_max) || - ((mode_mv[this_mode].as_mv.col >> 3) < x->mv_col_min) || - ((mode_mv[this_mode].as_mv.col >> 3) > x->mv_col_max)) { - continue; - } - - vp8_set_mbmode_and_mvs(x, this_mode, &mode_mv[this_mode]); - this_rd = evaluate_inter_mode_rd(mdcounts, &rd, &disable_skip, cpi, x); - break; - - default: break; - } - - this_rd = - calculate_final_rd_costs(this_rd, &rd, &other_cost, disable_skip, - uv_intra_tteob, intra_rd_penalty, cpi, x); - - /* Keep record of best intra distortion */ - if ((x->e_mbd.mode_info_context->mbmi.ref_frame == INTRA_FRAME) && - (this_rd < best_mode.intra_rd)) { - best_mode.intra_rd = this_rd; - *returnintra = rd.distortion2; - } -#if CONFIG_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity) { - unsigned int sse; - vp8_get_inter_mbpred_error(x, &cpi->fn_ptr[BLOCK_16X16], &sse, - mode_mv[this_mode]); - - if (sse < best_rd_sse) best_rd_sse = sse; - - /* Store for later use by denoiser. */ - if (this_mode == ZEROMV && sse < zero_mv_sse) { - zero_mv_sse = sse; - x->best_zeromv_reference_frame = - x->e_mbd.mode_info_context->mbmi.ref_frame; - } - - /* Store the best NEWMV in x for later use in the denoiser. */ - if (x->e_mbd.mode_info_context->mbmi.mode == NEWMV && sse < best_sse) { - best_sse = sse; - vp8_get_inter_mbpred_error(x, &cpi->fn_ptr[BLOCK_16X16], &best_sse, - mode_mv[this_mode]); - x->best_sse_inter_mode = NEWMV; - x->best_sse_mv = x->e_mbd.mode_info_context->mbmi.mv; - x->need_to_clamp_best_mvs = - x->e_mbd.mode_info_context->mbmi.need_to_clamp_mvs; - x->best_reference_frame = x->e_mbd.mode_info_context->mbmi.ref_frame; - } - } -#endif - - /* Did this mode help.. i.i is it the new best mode */ - if (this_rd < best_mode.rd || x->skip) { - /* Note index of best mode so far */ - best_mode_index = mode_index; - *returnrate = rd.rate2; - *returndistortion = rd.distortion2; - if (this_mode <= B_PRED) { - x->e_mbd.mode_info_context->mbmi.uv_mode = uv_intra_mode; - /* required for left and above block mv */ - x->e_mbd.mode_info_context->mbmi.mv.as_int = 0; - } - update_best_mode(&best_mode, this_rd, &rd, other_cost, x); - - /* Testing this mode gave rise to an improvement in best error - * score. Lower threshold a bit for next time - */ - x->rd_thresh_mult[mode_index] = - (x->rd_thresh_mult[mode_index] >= (MIN_THRESHMULT + 2)) - ? x->rd_thresh_mult[mode_index] - 2 - : MIN_THRESHMULT; - } - - /* If the mode did not help improve the best error case then raise - * the threshold for testing that mode next time around. - */ - else { - x->rd_thresh_mult[mode_index] += 4; - - if (x->rd_thresh_mult[mode_index] > MAX_THRESHMULT) { - x->rd_thresh_mult[mode_index] = MAX_THRESHMULT; - } - } - x->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) * - x->rd_thresh_mult[mode_index]; - - if (x->skip) break; - } - - /* Reduce the activation RD thresholds for the best choice mode */ - if ((cpi->rd_baseline_thresh[best_mode_index] > 0) && - (cpi->rd_baseline_thresh[best_mode_index] < (INT_MAX >> 2))) { - int best_adjustment = (x->rd_thresh_mult[best_mode_index] >> 2); - - x->rd_thresh_mult[best_mode_index] = - (x->rd_thresh_mult[best_mode_index] >= - (MIN_THRESHMULT + best_adjustment)) - ? x->rd_thresh_mult[best_mode_index] - best_adjustment - : MIN_THRESHMULT; - x->rd_threshes[best_mode_index] = - (cpi->rd_baseline_thresh[best_mode_index] >> 7) * - x->rd_thresh_mult[best_mode_index]; - } - -#if CONFIG_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity) { - int block_index = mb_row * cpi->common.mb_cols + mb_col; - if (x->best_sse_inter_mode == DC_PRED) { - /* No best MV found. */ - x->best_sse_inter_mode = best_mode.mbmode.mode; - x->best_sse_mv = best_mode.mbmode.mv; - x->need_to_clamp_best_mvs = best_mode.mbmode.need_to_clamp_mvs; - x->best_reference_frame = best_mode.mbmode.ref_frame; - best_sse = best_rd_sse; - } - vp8_denoiser_denoise_mb(&cpi->denoiser, x, best_sse, zero_mv_sse, - recon_yoffset, recon_uvoffset, &cpi->common.lf_info, - mb_row, mb_col, block_index, 0); - - /* Reevaluate ZEROMV after denoising. */ - if (best_mode.mbmode.ref_frame == INTRA_FRAME && - x->best_zeromv_reference_frame != INTRA_FRAME) { - int this_rd = INT_MAX; - int disable_skip = 0; - int other_cost = 0; - int this_ref_frame = x->best_zeromv_reference_frame; - rd.rate2 = - x->ref_frame_cost[this_ref_frame] + vp8_cost_mv_ref(ZEROMV, mdcounts); - rd.distortion2 = 0; - - /* set up the proper prediction buffers for the frame */ - x->e_mbd.mode_info_context->mbmi.ref_frame = this_ref_frame; - x->e_mbd.pre.y_buffer = plane[this_ref_frame][0]; - x->e_mbd.pre.u_buffer = plane[this_ref_frame][1]; - x->e_mbd.pre.v_buffer = plane[this_ref_frame][2]; - - x->e_mbd.mode_info_context->mbmi.mode = ZEROMV; - x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED; - x->e_mbd.mode_info_context->mbmi.mv.as_int = 0; - - this_rd = evaluate_inter_mode_rd(mdcounts, &rd, &disable_skip, cpi, x); - this_rd = - calculate_final_rd_costs(this_rd, &rd, &other_cost, disable_skip, - uv_intra_tteob, intra_rd_penalty, cpi, x); - if (this_rd < best_mode.rd || x->skip) { - *returnrate = rd.rate2; - *returndistortion = rd.distortion2; - update_best_mode(&best_mode, this_rd, &rd, other_cost, x); - } - } - } -#endif - - if (cpi->is_src_frame_alt_ref && - (best_mode.mbmode.mode != ZEROMV || - best_mode.mbmode.ref_frame != ALTREF_FRAME)) { - x->e_mbd.mode_info_context->mbmi.mode = ZEROMV; - x->e_mbd.mode_info_context->mbmi.ref_frame = ALTREF_FRAME; - x->e_mbd.mode_info_context->mbmi.mv.as_int = 0; - x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED; - x->e_mbd.mode_info_context->mbmi.mb_skip_coeff = - (cpi->common.mb_no_coeff_skip); - x->e_mbd.mode_info_context->mbmi.partitioning = 0; - return; - } - - /* macroblock modes */ - memcpy(&x->e_mbd.mode_info_context->mbmi, &best_mode.mbmode, - sizeof(MB_MODE_INFO)); - - if (best_mode.mbmode.mode == B_PRED) { - for (i = 0; i < 16; ++i) { - xd->mode_info_context->bmi[i].as_mode = best_mode.bmodes[i].as_mode; - } - } - - if (best_mode.mbmode.mode == SPLITMV) { - for (i = 0; i < 16; ++i) { - xd->mode_info_context->bmi[i].mv.as_int = best_mode.bmodes[i].mv.as_int; - } - - memcpy(x->partition_info, &best_mode.partition, sizeof(PARTITION_INFO)); - - x->e_mbd.mode_info_context->mbmi.mv.as_int = - x->partition_info->bmi[15].mv.as_int; - } - - if (sign_bias != - cpi->common.ref_frame_sign_bias[xd->mode_info_context->mbmi.ref_frame]) { - best_ref_mv.as_int = best_ref_mv_sb[!sign_bias].as_int; - } - - rd_update_mvcount(x, &best_ref_mv); -} - -void vp8_rd_pick_intra_mode(MACROBLOCK *x, int *rate) { - int error4x4, error16x16; - int rate4x4, rate16x16 = 0, rateuv; - int dist4x4, dist16x16, distuv; - int rate_; - int rate4x4_tokenonly = 0; - int rate16x16_tokenonly = 0; - int rateuv_tokenonly = 0; - - x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME; - - rd_pick_intra_mbuv_mode(x, &rateuv, &rateuv_tokenonly, &distuv); - rate_ = rateuv; - - error16x16 = rd_pick_intra16x16mby_mode(x, &rate16x16, &rate16x16_tokenonly, - &dist16x16); - - error4x4 = rd_pick_intra4x4mby_modes(x, &rate4x4, &rate4x4_tokenonly, - &dist4x4, error16x16); - - if (error4x4 < error16x16) { - x->e_mbd.mode_info_context->mbmi.mode = B_PRED; - rate_ += rate4x4; - } else { - rate_ += rate16x16; - } - - *rate = rate_; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/rdopt.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/rdopt.h deleted file mode 100644 index cc3db819..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/rdopt.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_RDOPT_H_ -#define VPX_VP8_ENCODER_RDOPT_H_ - -#include "./vpx_config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define RDCOST(RM, DM, R, D) (((128 + (R) * (RM)) >> 8) + (DM) * (D)) - -void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex); -void vp8_auto_select_speed(VP8_COMP *cpi); - -static INLINE void insertsortmv(int arr[], int len) { - int i, j, k; - - for (i = 1; i <= len - 1; ++i) { - for (j = 0; j < i; ++j) { - if (arr[j] > arr[i]) { - int temp; - - temp = arr[i]; - - for (k = i; k > j; k--) arr[k] = arr[k - 1]; - - arr[j] = temp; - } - } - } -} - -static INLINE void insertsortsad(int arr[], int idx[], int len) { - int i, j, k; - - for (i = 1; i <= len - 1; ++i) { - for (j = 0; j < i; ++j) { - if (arr[j] > arr[i]) { - int temp, tempi; - - temp = arr[i]; - tempi = idx[i]; - - for (k = i; k > j; k--) { - arr[k] = arr[k - 1]; - idx[k] = idx[k - 1]; - } - - arr[j] = temp; - idx[j] = tempi; - } - } - } -} - -void vp8_initialize_rd_consts(VP8_COMP *cpi, MACROBLOCK *x, int Qvalue); -void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, - int recon_uvoffset, int *returnrate, - int *returndistortion, int *returnintra, int mb_row, - int mb_col); -void vp8_rd_pick_intra_mode(MACROBLOCK *x, int *rate); - -static INLINE void get_plane_pointers(const YV12_BUFFER_CONFIG *fb, - unsigned char *plane[3], - unsigned int recon_yoffset, - unsigned int recon_uvoffset) { - plane[0] = fb->y_buffer + recon_yoffset; - plane[1] = fb->u_buffer + recon_uvoffset; - plane[2] = fb->v_buffer + recon_uvoffset; -} - -static INLINE void get_predictor_pointers(const VP8_COMP *cpi, - unsigned char *plane[4][3], - unsigned int recon_yoffset, - unsigned int recon_uvoffset) { - if (cpi->ref_frame_flags & VP8_LAST_FRAME) { - get_plane_pointers(&cpi->common.yv12_fb[cpi->common.lst_fb_idx], - plane[LAST_FRAME], recon_yoffset, recon_uvoffset); - } - - if (cpi->ref_frame_flags & VP8_GOLD_FRAME) { - get_plane_pointers(&cpi->common.yv12_fb[cpi->common.gld_fb_idx], - plane[GOLDEN_FRAME], recon_yoffset, recon_uvoffset); - } - - if (cpi->ref_frame_flags & VP8_ALTR_FRAME) { - get_plane_pointers(&cpi->common.yv12_fb[cpi->common.alt_fb_idx], - plane[ALTREF_FRAME], recon_yoffset, recon_uvoffset); - } -} - -static INLINE void get_reference_search_order(const VP8_COMP *cpi, - int ref_frame_map[4]) { - int i = 0; - - ref_frame_map[i++] = INTRA_FRAME; - if (cpi->ref_frame_flags & VP8_LAST_FRAME) ref_frame_map[i++] = LAST_FRAME; - if (cpi->ref_frame_flags & VP8_GOLD_FRAME) ref_frame_map[i++] = GOLDEN_FRAME; - if (cpi->ref_frame_flags & VP8_ALTR_FRAME) ref_frame_map[i++] = ALTREF_FRAME; - for (; i < 4; ++i) ref_frame_map[i] = -1; -} - -void vp8_mv_pred(VP8_COMP *cpi, MACROBLOCKD *xd, const MODE_INFO *here, - int_mv *mvp, int refframe, int *ref_frame_sign_bias, int *sr, - int near_sadidx[]); -void vp8_cal_sad(VP8_COMP *cpi, MACROBLOCKD *xd, MACROBLOCK *x, - int recon_yoffset, int near_sadidx[]); -int VP8_UVSSE(MACROBLOCK *x); -int vp8_cost_mv_ref(MB_PREDICTION_MODE m, const int near_mv_ref_ct[4]); -void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_RDOPT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/segmentation.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/segmentation.c deleted file mode 100644 index 21272581..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/segmentation.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "segmentation.h" -#include "vpx_mem/vpx_mem.h" - -void vp8_update_gf_usage_maps(VP8_COMP *cpi, VP8_COMMON *cm, MACROBLOCK *x) { - int mb_row, mb_col; - - MODE_INFO *this_mb_mode_info = cm->mi; - - x->gf_active_ptr = (signed char *)cpi->gf_active_flags; - - if ((cm->frame_type == KEY_FRAME) || (cm->refresh_golden_frame)) { - /* Reset Gf usage monitors */ - memset(cpi->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols)); - cpi->gf_active_count = cm->mb_rows * cm->mb_cols; - } else { - /* for each macroblock row in image */ - for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) { - /* for each macroblock col in image */ - for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) { - /* If using golden then set GF active flag if not already set. - * If using last frame 0,0 mode then leave flag as it is - * else if using non 0,0 motion or intra modes then clear - * flag if it is currently set - */ - if ((this_mb_mode_info->mbmi.ref_frame == GOLDEN_FRAME) || - (this_mb_mode_info->mbmi.ref_frame == ALTREF_FRAME)) { - if (*(x->gf_active_ptr) == 0) { - *(x->gf_active_ptr) = 1; - cpi->gf_active_count++; - } - } else if ((this_mb_mode_info->mbmi.mode != ZEROMV) && - *(x->gf_active_ptr)) { - *(x->gf_active_ptr) = 0; - cpi->gf_active_count--; - } - - x->gf_active_ptr++; /* Step onto next entry */ - this_mb_mode_info++; /* skip to next mb */ - } - - /* this is to account for the border */ - this_mb_mode_info++; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/segmentation.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/segmentation.h deleted file mode 100644 index 0fecfc22..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/segmentation.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_SEGMENTATION_H_ -#define VPX_VP8_ENCODER_SEGMENTATION_H_ - -#include "string.h" -#include "vp8/common/blockd.h" -#include "onyx_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern void vp8_update_gf_usage_maps(VP8_COMP *cpi, VP8_COMMON *cm, - MACROBLOCK *x); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_SEGMENTATION_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/temporal_filter.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/temporal_filter.c deleted file mode 100644 index 1c1a55fd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/temporal_filter.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp8/common/onyxc_int.h" -#include "onyx_int.h" -#include "vp8/common/systemdependent.h" -#include "vp8/encoder/quantize.h" -#include "vp8/common/alloccommon.h" -#include "mcomp.h" -#include "firstpass.h" -#include "vpx_scale/vpx_scale.h" -#include "vp8/common/extend.h" -#include "ratectrl.h" -#include "vp8/common/quant_common.h" -#include "segmentation.h" -#include "temporal_filter.h" -#include "vpx_mem/vpx_mem.h" -#include "vp8/common/swapyv12buffer.h" -#include "vp8/common/threading.h" -#include "vpx_ports/vpx_timer.h" - -#include -#include - -#define ALT_REF_MC_ENABLED 1 /* toggle MC in AltRef filtering */ -#define ALT_REF_SUBPEL_ENABLED 1 /* toggle subpel in MC AltRef filtering */ - -#if VP8_TEMPORAL_ALT_REF - -static void vp8_temporal_filter_predictors_mb_c( - MACROBLOCKD *x, unsigned char *y_mb_ptr, unsigned char *u_mb_ptr, - unsigned char *v_mb_ptr, int stride, int mv_row, int mv_col, - unsigned char *pred) { - int offset; - unsigned char *yptr, *uptr, *vptr; - - /* Y */ - yptr = y_mb_ptr + (mv_row >> 3) * stride + (mv_col >> 3); - - if ((mv_row | mv_col) & 7) { - x->subpixel_predict16x16(yptr, stride, mv_col & 7, mv_row & 7, &pred[0], - 16); - } else { - vp8_copy_mem16x16(yptr, stride, &pred[0], 16); - } - - /* U & V */ - mv_row >>= 1; - mv_col >>= 1; - stride = (stride + 1) >> 1; - offset = (mv_row >> 3) * stride + (mv_col >> 3); - uptr = u_mb_ptr + offset; - vptr = v_mb_ptr + offset; - - if ((mv_row | mv_col) & 7) { - x->subpixel_predict8x8(uptr, stride, mv_col & 7, mv_row & 7, &pred[256], 8); - x->subpixel_predict8x8(vptr, stride, mv_col & 7, mv_row & 7, &pred[320], 8); - } else { - vp8_copy_mem8x8(uptr, stride, &pred[256], 8); - vp8_copy_mem8x8(vptr, stride, &pred[320], 8); - } -} -void vp8_temporal_filter_apply_c(unsigned char *frame1, unsigned int stride, - unsigned char *frame2, unsigned int block_size, - int strength, int filter_weight, - unsigned int *accumulator, - unsigned short *count) { - unsigned int i, j, k; - int modifier; - int byte = 0; - const int rounding = strength > 0 ? 1 << (strength - 1) : 0; - - for (i = 0, k = 0; i < block_size; ++i) { - for (j = 0; j < block_size; j++, k++) { - int src_byte = frame1[byte]; - int pixel_value = *frame2++; - - modifier = src_byte - pixel_value; - /* This is an integer approximation of: - * float coeff = (3.0 * modifer * modifier) / pow(2, strength); - * modifier = (int)roundf(coeff > 16 ? 0 : 16-coeff); - */ - modifier *= modifier; - modifier *= 3; - modifier += rounding; - modifier >>= strength; - - if (modifier > 16) modifier = 16; - - modifier = 16 - modifier; - modifier *= filter_weight; - - count[k] += modifier; - accumulator[k] += modifier * pixel_value; - - byte++; - } - - byte += stride - block_size; - } -} - -#if ALT_REF_MC_ENABLED - -static int vp8_temporal_filter_find_matching_mb_c(VP8_COMP *cpi, - YV12_BUFFER_CONFIG *arf_frame, - YV12_BUFFER_CONFIG *frame_ptr, - int mb_offset, - int error_thresh) { - MACROBLOCK *x = &cpi->mb; - int step_param; - int sadpb = x->sadperbit16; - int bestsme = INT_MAX; - - BLOCK *b = &x->block[0]; - BLOCKD *d = &x->e_mbd.block[0]; - int_mv best_ref_mv1; - int_mv best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */ - - /* Save input state */ - unsigned char **base_src = b->base_src; - int src = b->src; - int src_stride = b->src_stride; - unsigned char *base_pre = x->e_mbd.pre.y_buffer; - int pre = d->offset; - int pre_stride = x->e_mbd.pre.y_stride; - - (void)error_thresh; - - best_ref_mv1.as_int = 0; - best_ref_mv1_full.as_mv.col = best_ref_mv1.as_mv.col >> 3; - best_ref_mv1_full.as_mv.row = best_ref_mv1.as_mv.row >> 3; - - /* Setup frame pointers */ - b->base_src = &arf_frame->y_buffer; - b->src_stride = arf_frame->y_stride; - b->src = mb_offset; - - x->e_mbd.pre.y_buffer = frame_ptr->y_buffer; - x->e_mbd.pre.y_stride = frame_ptr->y_stride; - d->offset = mb_offset; - - /* Further step/diamond searches as necessary */ - if (cpi->Speed < 8) { - step_param = cpi->sf.first_step + (cpi->Speed > 5); - } else { - step_param = cpi->sf.first_step + 2; - } - - /* TODO Check that the 16x16 vf & sdf are selected here */ - /* Ignore mv costing by sending NULL cost arrays */ - bestsme = - vp8_hex_search(x, b, d, &best_ref_mv1_full, &d->bmi.mv, step_param, sadpb, - &cpi->fn_ptr[BLOCK_16X16], NULL, &best_ref_mv1); - (void)bestsme; // Ignore unused return value. - -#if ALT_REF_SUBPEL_ENABLED - /* Try sub-pixel MC? */ - { - int distortion; - unsigned int sse; - /* Ignore mv costing by sending NULL cost array */ - bestsme = cpi->find_fractional_mv_step( - x, b, d, &d->bmi.mv, &best_ref_mv1, x->errorperbit, - &cpi->fn_ptr[BLOCK_16X16], NULL, &distortion, &sse); - } -#endif - - /* Save input state */ - b->base_src = base_src; - b->src = src; - b->src_stride = src_stride; - x->e_mbd.pre.y_buffer = base_pre; - d->offset = pre; - x->e_mbd.pre.y_stride = pre_stride; - - return bestsme; -} -#endif - -static void vp8_temporal_filter_iterate_c(VP8_COMP *cpi, int frame_count, - int alt_ref_index, int strength) { - int byte; - int frame; - int mb_col, mb_row; - unsigned int filter_weight; - int mb_cols = cpi->common.mb_cols; - int mb_rows = cpi->common.mb_rows; - int mb_y_offset = 0; - int mb_uv_offset = 0; - DECLARE_ALIGNED(16, unsigned int, accumulator[16 * 16 + 8 * 8 + 8 * 8]); - DECLARE_ALIGNED(16, unsigned short, count[16 * 16 + 8 * 8 + 8 * 8]); - MACROBLOCKD *mbd = &cpi->mb.e_mbd; - YV12_BUFFER_CONFIG *f = cpi->frames[alt_ref_index]; - unsigned char *dst1, *dst2; - DECLARE_ALIGNED(16, unsigned char, predictor[16 * 16 + 8 * 8 + 8 * 8]); - - /* Save input state */ - unsigned char *y_buffer = mbd->pre.y_buffer; - unsigned char *u_buffer = mbd->pre.u_buffer; - unsigned char *v_buffer = mbd->pre.v_buffer; - - for (mb_row = 0; mb_row < mb_rows; ++mb_row) { -#if ALT_REF_MC_ENABLED - /* Source frames are extended to 16 pixels. This is different than - * L/A/G reference frames that have a border of 32 (VP8BORDERINPIXELS) - * A 6 tap filter is used for motion search. This requires 2 pixels - * before and 3 pixels after. So the largest Y mv on a border would - * then be 16 - 3. The UV blocks are half the size of the Y and - * therefore only extended by 8. The largest mv that a UV block - * can support is 8 - 3. A UV mv is half of a Y mv. - * (16 - 3) >> 1 == 6 which is greater than 8 - 3. - * To keep the mv in play for both Y and UV planes the max that it - * can be on a border is therefore 16 - 5. - */ - cpi->mb.mv_row_min = -((mb_row * 16) + (16 - 5)); - cpi->mb.mv_row_max = ((cpi->common.mb_rows - 1 - mb_row) * 16) + (16 - 5); -#endif - - for (mb_col = 0; mb_col < mb_cols; ++mb_col) { - int i, j, k; - int stride; - - memset(accumulator, 0, 384 * sizeof(unsigned int)); - memset(count, 0, 384 * sizeof(unsigned short)); - -#if ALT_REF_MC_ENABLED - cpi->mb.mv_col_min = -((mb_col * 16) + (16 - 5)); - cpi->mb.mv_col_max = ((cpi->common.mb_cols - 1 - mb_col) * 16) + (16 - 5); -#endif - - for (frame = 0; frame < frame_count; ++frame) { - if (cpi->frames[frame] == NULL) continue; - - mbd->block[0].bmi.mv.as_mv.row = 0; - mbd->block[0].bmi.mv.as_mv.col = 0; - - if (frame == alt_ref_index) { - filter_weight = 2; - } else { - int err = 0; -#if ALT_REF_MC_ENABLED -#define THRESH_LOW 10000 -#define THRESH_HIGH 20000 - /* Find best match in this frame by MC */ - err = vp8_temporal_filter_find_matching_mb_c( - cpi, cpi->frames[alt_ref_index], cpi->frames[frame], mb_y_offset, - THRESH_LOW); -#endif - /* Assign higher weight to matching MB if it's error - * score is lower. If not applying MC default behavior - * is to weight all MBs equal. - */ - filter_weight = err < THRESH_LOW ? 2 : err < THRESH_HIGH ? 1 : 0; - } - - if (filter_weight != 0) { - /* Construct the predictors */ - vp8_temporal_filter_predictors_mb_c( - mbd, cpi->frames[frame]->y_buffer + mb_y_offset, - cpi->frames[frame]->u_buffer + mb_uv_offset, - cpi->frames[frame]->v_buffer + mb_uv_offset, - cpi->frames[frame]->y_stride, mbd->block[0].bmi.mv.as_mv.row, - mbd->block[0].bmi.mv.as_mv.col, predictor); - - /* Apply the filter (YUV) */ - vp8_temporal_filter_apply(f->y_buffer + mb_y_offset, f->y_stride, - predictor, 16, strength, filter_weight, - accumulator, count); - - vp8_temporal_filter_apply(f->u_buffer + mb_uv_offset, f->uv_stride, - predictor + 256, 8, strength, filter_weight, - accumulator + 256, count + 256); - - vp8_temporal_filter_apply(f->v_buffer + mb_uv_offset, f->uv_stride, - predictor + 320, 8, strength, filter_weight, - accumulator + 320, count + 320); - } - } - - /* Normalize filter output to produce AltRef frame */ - dst1 = cpi->alt_ref_buffer.y_buffer; - stride = cpi->alt_ref_buffer.y_stride; - byte = mb_y_offset; - for (i = 0, k = 0; i < 16; ++i) { - for (j = 0; j < 16; j++, k++) { - unsigned int pval = accumulator[k] + (count[k] >> 1); - pval *= cpi->fixed_divide[count[k]]; - pval >>= 19; - - dst1[byte] = (unsigned char)pval; - - /* move to next pixel */ - byte++; - } - - byte += stride - 16; - } - - dst1 = cpi->alt_ref_buffer.u_buffer; - dst2 = cpi->alt_ref_buffer.v_buffer; - stride = cpi->alt_ref_buffer.uv_stride; - byte = mb_uv_offset; - for (i = 0, k = 256; i < 8; ++i) { - for (j = 0; j < 8; j++, k++) { - int m = k + 64; - - /* U */ - unsigned int pval = accumulator[k] + (count[k] >> 1); - pval *= cpi->fixed_divide[count[k]]; - pval >>= 19; - dst1[byte] = (unsigned char)pval; - - /* V */ - pval = accumulator[m] + (count[m] >> 1); - pval *= cpi->fixed_divide[count[m]]; - pval >>= 19; - dst2[byte] = (unsigned char)pval; - - /* move to next pixel */ - byte++; - } - - byte += stride - 8; - } - - mb_y_offset += 16; - mb_uv_offset += 8; - } - - mb_y_offset += 16 * (f->y_stride - mb_cols); - mb_uv_offset += 8 * (f->uv_stride - mb_cols); - } - - /* Restore input state */ - mbd->pre.y_buffer = y_buffer; - mbd->pre.u_buffer = u_buffer; - mbd->pre.v_buffer = v_buffer; -} - -void vp8_temporal_filter_prepare_c(VP8_COMP *cpi, int distance) { - int frame = 0; - - int num_frames_backward = 0; - int num_frames_forward = 0; - int frames_to_blur_backward = 0; - int frames_to_blur_forward = 0; - int frames_to_blur = 0; - int start_frame = 0; - - int strength = cpi->oxcf.arnr_strength; - - int blur_type = cpi->oxcf.arnr_type; - - int max_frames = cpi->active_arnr_frames; - - num_frames_backward = distance; - num_frames_forward = - vp8_lookahead_depth(cpi->lookahead) - (num_frames_backward + 1); - - switch (blur_type) { - case 1: - /* Backward Blur */ - - frames_to_blur_backward = num_frames_backward; - - if (frames_to_blur_backward >= max_frames) { - frames_to_blur_backward = max_frames - 1; - } - - frames_to_blur = frames_to_blur_backward + 1; - break; - - case 2: - /* Forward Blur */ - - frames_to_blur_forward = num_frames_forward; - - if (frames_to_blur_forward >= max_frames) { - frames_to_blur_forward = max_frames - 1; - } - - frames_to_blur = frames_to_blur_forward + 1; - break; - - case 3: - default: - /* Center Blur */ - frames_to_blur_forward = num_frames_forward; - frames_to_blur_backward = num_frames_backward; - - if (frames_to_blur_forward > frames_to_blur_backward) { - frames_to_blur_forward = frames_to_blur_backward; - } - - if (frames_to_blur_backward > frames_to_blur_forward) { - frames_to_blur_backward = frames_to_blur_forward; - } - - /* When max_frames is even we have 1 more frame backward than forward */ - if (frames_to_blur_forward > (max_frames - 1) / 2) { - frames_to_blur_forward = ((max_frames - 1) / 2); - } - - if (frames_to_blur_backward > (max_frames / 2)) { - frames_to_blur_backward = (max_frames / 2); - } - - frames_to_blur = frames_to_blur_backward + frames_to_blur_forward + 1; - break; - } - - start_frame = distance + frames_to_blur_forward; - - /* Setup frame pointers, NULL indicates frame not included in filter */ - memset(cpi->frames, 0, max_frames * sizeof(YV12_BUFFER_CONFIG *)); - for (frame = 0; frame < frames_to_blur; ++frame) { - int which_buffer = start_frame - frame; - struct lookahead_entry *buf = - vp8_lookahead_peek(cpi->lookahead, which_buffer, PEEK_FORWARD); - cpi->frames[frames_to_blur - 1 - frame] = &buf->img; - } - - vp8_temporal_filter_iterate_c(cpi, frames_to_blur, frames_to_blur_backward, - strength); -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/temporal_filter.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/temporal_filter.h deleted file mode 100644 index fd39f5cb..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/temporal_filter.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_TEMPORAL_FILTER_H_ -#define VPX_VP8_ENCODER_TEMPORAL_FILTER_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -struct VP8_COMP; - -void vp8_temporal_filter_prepare_c(struct VP8_COMP *cpi, int distance); - -#ifdef __cplusplus -} -#endif - -#endif // VPX_VP8_ENCODER_TEMPORAL_FILTER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/tokenize.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/tokenize.c deleted file mode 100644 index c3d70266..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/tokenize.c +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include "onyx_int.h" -#include "tokenize.h" -#include "vpx_mem/vpx_mem.h" - -/* Global event counters used for accumulating statistics across several - compressions, then generating context.c = initial stats. */ - -void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t); -void vp8_fix_contexts(MACROBLOCKD *x); - -#include "dct_value_tokens.h" -#include "dct_value_cost.h" - -const TOKENVALUE *const vp8_dct_value_tokens_ptr = - dct_value_tokens + DCT_MAX_VALUE; -const short *const vp8_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE; - -#if 0 -int skip_true_count = 0; -int skip_false_count = 0; -#endif - -/* function used to generate dct_value_tokens and dct_value_cost tables */ -/* -static void fill_value_tokens() -{ - - TOKENVALUE *t = dct_value_tokens + DCT_MAX_VALUE; - const vp8_extra_bit_struct *e = vp8_extra_bits; - - int i = -DCT_MAX_VALUE; - int sign = 1; - - do - { - if (!i) - sign = 0; - - { - const int a = sign ? -i : i; - int eb = sign; - - if (a > 4) - { - int j = 4; - - while (++j < 11 && e[j].base_val <= a) {} - - t[i].Token = --j; - eb |= (a - e[j].base_val) << 1; - } - else - t[i].Token = a; - - t[i].Extra = eb; - } - - // initialize the cost for extra bits for all possible coefficient -value. - { - int cost = 0; - const vp8_extra_bit_struct *p = vp8_extra_bits + t[i].Token; - - if (p->base_val) - { - const int extra = t[i].Extra; - const int Length = p->Len; - - if (Length) - cost += vp8_treed_cost(p->tree, p->prob, extra >> 1, -Length); - - cost += vp8_cost_bit(vp8_prob_half, extra & 1); // sign - dct_value_cost[i + DCT_MAX_VALUE] = cost; - } - - } - - } - while (++i < DCT_MAX_VALUE); - - vp8_dct_value_tokens_ptr = dct_value_tokens + DCT_MAX_VALUE; - vp8_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE; -} -*/ - -static void tokenize2nd_order_b(MACROBLOCK *x, TOKENEXTRA **tp, VP8_COMP *cpi) { - MACROBLOCKD *xd = &x->e_mbd; - int pt; /* near block/prev token context index */ - int c; /* start at DC */ - TOKENEXTRA *t = *tp; /* store tokens starting here */ - const BLOCKD *b; - const short *qcoeff_ptr; - ENTROPY_CONTEXT *a; - ENTROPY_CONTEXT *l; - int band, rc, v, token; - int eob; - - b = xd->block + 24; - qcoeff_ptr = b->qcoeff; - a = (ENTROPY_CONTEXT *)xd->above_context + 8; - l = (ENTROPY_CONTEXT *)xd->left_context + 8; - eob = xd->eobs[24]; - VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); - - if (!eob) { - /* c = band for this case */ - t->Token = DCT_EOB_TOKEN; - t->context_tree = cpi->common.fc.coef_probs[1][0][pt]; - t->skip_eob_node = 0; - - ++x->coef_counts[1][0][pt][DCT_EOB_TOKEN]; - t++; - *tp = t; - *a = *l = 0; - return; - } - - v = qcoeff_ptr[0]; - t->Extra = vp8_dct_value_tokens_ptr[v].Extra; - token = vp8_dct_value_tokens_ptr[v].Token; - t->Token = token; - - t->context_tree = cpi->common.fc.coef_probs[1][0][pt]; - t->skip_eob_node = 0; - ++x->coef_counts[1][0][pt][token]; - pt = vp8_prev_token_class[token]; - t++; - c = 1; - - for (; c < eob; ++c) { - rc = vp8_default_zig_zag1d[c]; - band = vp8_coef_bands[c]; - v = qcoeff_ptr[rc]; - - t->Extra = vp8_dct_value_tokens_ptr[v].Extra; - token = vp8_dct_value_tokens_ptr[v].Token; - - t->Token = token; - t->context_tree = cpi->common.fc.coef_probs[1][band][pt]; - - t->skip_eob_node = ((pt == 0)); - - ++x->coef_counts[1][band][pt][token]; - - pt = vp8_prev_token_class[token]; - t++; - } - if (c < 16) { - band = vp8_coef_bands[c]; - t->Token = DCT_EOB_TOKEN; - t->context_tree = cpi->common.fc.coef_probs[1][band][pt]; - - t->skip_eob_node = 0; - - ++x->coef_counts[1][band][pt][DCT_EOB_TOKEN]; - - t++; - } - - *tp = t; - *a = *l = 1; -} - -static void tokenize1st_order_b( - MACROBLOCK *x, TOKENEXTRA **tp, - int type, /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */ - VP8_COMP *cpi) { - MACROBLOCKD *xd = &x->e_mbd; - unsigned int block; - const BLOCKD *b; - int pt; /* near block/prev token context index */ - int c; - int token; - TOKENEXTRA *t = *tp; /* store tokens starting here */ - const short *qcoeff_ptr; - ENTROPY_CONTEXT *a; - ENTROPY_CONTEXT *l; - int band, rc, v; - int tmp1, tmp2; - - b = xd->block; - /* Luma */ - for (block = 0; block < 16; block++, b++) { - const int eob = *b->eob; - tmp1 = vp8_block2above[block]; - tmp2 = vp8_block2left[block]; - qcoeff_ptr = b->qcoeff; - a = (ENTROPY_CONTEXT *)xd->above_context + tmp1; - l = (ENTROPY_CONTEXT *)xd->left_context + tmp2; - - VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); - - c = type ? 0 : 1; - - if (c >= eob) { - /* c = band for this case */ - t->Token = DCT_EOB_TOKEN; - t->context_tree = cpi->common.fc.coef_probs[type][c][pt]; - t->skip_eob_node = 0; - - ++x->coef_counts[type][c][pt][DCT_EOB_TOKEN]; - t++; - *tp = t; - *a = *l = 0; - continue; - } - - v = qcoeff_ptr[c]; - - t->Extra = vp8_dct_value_tokens_ptr[v].Extra; - token = vp8_dct_value_tokens_ptr[v].Token; - t->Token = token; - - t->context_tree = cpi->common.fc.coef_probs[type][c][pt]; - t->skip_eob_node = 0; - ++x->coef_counts[type][c][pt][token]; - pt = vp8_prev_token_class[token]; - t++; - c++; - - assert(eob <= 16); - for (; c < eob; ++c) { - rc = vp8_default_zig_zag1d[c]; - band = vp8_coef_bands[c]; - v = qcoeff_ptr[rc]; - - t->Extra = vp8_dct_value_tokens_ptr[v].Extra; - token = vp8_dct_value_tokens_ptr[v].Token; - - t->Token = token; - t->context_tree = cpi->common.fc.coef_probs[type][band][pt]; - - t->skip_eob_node = (pt == 0); - ++x->coef_counts[type][band][pt][token]; - - pt = vp8_prev_token_class[token]; - t++; - } - if (c < 16) { - band = vp8_coef_bands[c]; - t->Token = DCT_EOB_TOKEN; - t->context_tree = cpi->common.fc.coef_probs[type][band][pt]; - - t->skip_eob_node = 0; - ++x->coef_counts[type][band][pt][DCT_EOB_TOKEN]; - - t++; - } - *tp = t; - *a = *l = 1; - } - - /* Chroma */ - for (block = 16; block < 24; block++, b++) { - const int eob = *b->eob; - tmp1 = vp8_block2above[block]; - tmp2 = vp8_block2left[block]; - qcoeff_ptr = b->qcoeff; - a = (ENTROPY_CONTEXT *)xd->above_context + tmp1; - l = (ENTROPY_CONTEXT *)xd->left_context + tmp2; - - VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); - - if (!eob) { - /* c = band for this case */ - t->Token = DCT_EOB_TOKEN; - t->context_tree = cpi->common.fc.coef_probs[2][0][pt]; - t->skip_eob_node = 0; - - ++x->coef_counts[2][0][pt][DCT_EOB_TOKEN]; - t++; - *tp = t; - *a = *l = 0; - continue; - } - - v = qcoeff_ptr[0]; - - t->Extra = vp8_dct_value_tokens_ptr[v].Extra; - token = vp8_dct_value_tokens_ptr[v].Token; - t->Token = token; - - t->context_tree = cpi->common.fc.coef_probs[2][0][pt]; - t->skip_eob_node = 0; - ++x->coef_counts[2][0][pt][token]; - pt = vp8_prev_token_class[token]; - t++; - c = 1; - - assert(eob <= 16); - for (; c < eob; ++c) { - rc = vp8_default_zig_zag1d[c]; - band = vp8_coef_bands[c]; - v = qcoeff_ptr[rc]; - - t->Extra = vp8_dct_value_tokens_ptr[v].Extra; - token = vp8_dct_value_tokens_ptr[v].Token; - - t->Token = token; - t->context_tree = cpi->common.fc.coef_probs[2][band][pt]; - - t->skip_eob_node = (pt == 0); - - ++x->coef_counts[2][band][pt][token]; - - pt = vp8_prev_token_class[token]; - t++; - } - if (c < 16) { - band = vp8_coef_bands[c]; - t->Token = DCT_EOB_TOKEN; - t->context_tree = cpi->common.fc.coef_probs[2][band][pt]; - - t->skip_eob_node = 0; - - ++x->coef_counts[2][band][pt][DCT_EOB_TOKEN]; - - t++; - } - *tp = t; - *a = *l = 1; - } -} - -static int mb_is_skippable(MACROBLOCKD *x, int has_y2_block) { - int skip = 1; - int i = 0; - - if (has_y2_block) { - for (i = 0; i < 16; ++i) skip &= (x->eobs[i] < 2); - } - - for (; i < 24 + has_y2_block; ++i) skip &= (!x->eobs[i]); - - return skip; -} - -void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t) { - MACROBLOCKD *xd = &x->e_mbd; - int plane_type; - int has_y2_block; - - has_y2_block = (xd->mode_info_context->mbmi.mode != B_PRED && - xd->mode_info_context->mbmi.mode != SPLITMV); - - xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable(xd, has_y2_block); - if (xd->mode_info_context->mbmi.mb_skip_coeff) { - if (!cpi->common.mb_no_coeff_skip) { - vp8_stuff_mb(cpi, x, t); - } else { - vp8_fix_contexts(xd); - x->skip_true_count++; - } - - return; - } - - plane_type = 3; - if (has_y2_block) { - tokenize2nd_order_b(x, t, cpi); - plane_type = 0; - } - - tokenize1st_order_b(x, t, plane_type, cpi); -} - -static void stuff2nd_order_b(TOKENEXTRA **tp, ENTROPY_CONTEXT *a, - ENTROPY_CONTEXT *l, VP8_COMP *cpi, MACROBLOCK *x) { - int pt; /* near block/prev token context index */ - TOKENEXTRA *t = *tp; /* store tokens starting here */ - VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); - - t->Token = DCT_EOB_TOKEN; - t->context_tree = cpi->common.fc.coef_probs[1][0][pt]; - t->skip_eob_node = 0; - ++x->coef_counts[1][0][pt][DCT_EOB_TOKEN]; - ++t; - - *tp = t; - pt = 0; - *a = *l = pt; -} - -static void stuff1st_order_b(TOKENEXTRA **tp, ENTROPY_CONTEXT *a, - ENTROPY_CONTEXT *l, int type, VP8_COMP *cpi, - MACROBLOCK *x) { - int pt; /* near block/prev token context index */ - int band; - TOKENEXTRA *t = *tp; /* store tokens starting here */ - VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); - band = type ? 0 : 1; - t->Token = DCT_EOB_TOKEN; - t->context_tree = cpi->common.fc.coef_probs[type][band][pt]; - t->skip_eob_node = 0; - ++x->coef_counts[type][band][pt][DCT_EOB_TOKEN]; - ++t; - *tp = t; - pt = 0; /* 0 <-> all coeff data is zero */ - *a = *l = pt; -} - -static void stuff1st_order_buv(TOKENEXTRA **tp, ENTROPY_CONTEXT *a, - ENTROPY_CONTEXT *l, VP8_COMP *cpi, - MACROBLOCK *x) { - int pt; /* near block/prev token context index */ - TOKENEXTRA *t = *tp; /* store tokens starting here */ - VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l); - - t->Token = DCT_EOB_TOKEN; - t->context_tree = cpi->common.fc.coef_probs[2][0][pt]; - t->skip_eob_node = 0; - ++x->coef_counts[2][0][pt][DCT_EOB_TOKEN]; - ++t; - *tp = t; - pt = 0; /* 0 <-> all coeff data is zero */ - *a = *l = pt; -} - -void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t) { - MACROBLOCKD *xd = &x->e_mbd; - ENTROPY_CONTEXT *A = (ENTROPY_CONTEXT *)xd->above_context; - ENTROPY_CONTEXT *L = (ENTROPY_CONTEXT *)xd->left_context; - int plane_type; - int b; - plane_type = 3; - if ((xd->mode_info_context->mbmi.mode != B_PRED && - xd->mode_info_context->mbmi.mode != SPLITMV)) { - stuff2nd_order_b(t, A + vp8_block2above[24], L + vp8_block2left[24], cpi, - x); - plane_type = 0; - } - - for (b = 0; b < 16; ++b) { - stuff1st_order_b(t, A + vp8_block2above[b], L + vp8_block2left[b], - plane_type, cpi, x); - } - - for (b = 16; b < 24; ++b) { - stuff1st_order_buv(t, A + vp8_block2above[b], L + vp8_block2left[b], cpi, - x); - } -} -void vp8_fix_contexts(MACROBLOCKD *x) { - /* Clear entropy contexts for Y2 blocks */ - if (x->mode_info_context->mbmi.mode != B_PRED && - x->mode_info_context->mbmi.mode != SPLITMV) { - memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)); - memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)); - } else { - memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1); - memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) - 1); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/tokenize.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/tokenize.h deleted file mode 100644 index 5223aa2d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/tokenize.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_TOKENIZE_H_ -#define VPX_VP8_ENCODER_TOKENIZE_H_ - -#include "vp8/common/entropy.h" -#include "block.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - short Token; - short Extra; -} TOKENVALUE; - -typedef struct { - const vp8_prob *context_tree; - short Extra; - unsigned char Token; - unsigned char skip_eob_node; -} TOKENEXTRA; - -int rd_cost_mby(MACROBLOCKD *); - -extern const short *const vp8_dct_value_cost_ptr; -/* TODO: The Token field should be broken out into a separate char array to - * improve cache locality, since it's needed for costing when the rest of the - * fields are not. - */ -extern const TOKENVALUE *const vp8_dct_value_tokens_ptr; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_TOKENIZE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/treewriter.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/treewriter.c deleted file mode 100644 index f055f052..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/treewriter.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "treewriter.h" - -static void cost(int *const C, vp8_tree T, const vp8_prob *const P, int i, - int c) { - const vp8_prob p = P[i >> 1]; - - do { - const vp8_tree_index j = T[i]; - const int d = c + vp8_cost_bit(p, i & 1); - - if (j <= 0) { - C[-j] = d; - } else { - cost(C, T, P, j, d); - } - } while (++i & 1); -} -void vp8_cost_tokens(int *c, const vp8_prob *p, vp8_tree t) { - cost(c, t, p, 0, 0); -} -void vp8_cost_tokens2(int *c, const vp8_prob *p, vp8_tree t, int start) { - cost(c, t, p, start, 0); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/treewriter.h b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/treewriter.h deleted file mode 100644 index 4e9ed6af..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/treewriter.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_ENCODER_TREEWRITER_H_ -#define VPX_VP8_ENCODER_TREEWRITER_H_ - -/* Trees map alphabets into huffman-like codes suitable for an arithmetic - bit coder. Timothy S Murphy 11 October 2004 */ - -#include - -#include "./vpx_config.h" -#include "vp8/common/treecoder.h" - -#include "boolhuff.h" /* for now */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef BOOL_CODER vp8_writer; - -#define vp8_write vp8_encode_bool -#define vp8_write_literal vp8_encode_value -#define vp8_write_bit(W, V) vp8_write(W, V, vp8_prob_half) - -#define vp8bc_write vp8bc_write_bool -#define vp8bc_write_literal vp8bc_write_bits -#define vp8bc_write_bit(W, V) vp8bc_write_bits(W, V, 1) - -/* Approximate length of an encoded bool in 256ths of a bit at given prob */ - -#define vp8_cost_zero(x) (vp8_prob_cost[x]) -#define vp8_cost_one(x) vp8_cost_zero(vp8_complement(x)) - -#define vp8_cost_bit(x, b) vp8_cost_zero((b) ? vp8_complement(x) : (x)) - -/* VP8BC version is scaled by 2^20 rather than 2^8; see bool_coder.h */ - -/* Both of these return bits, not scaled bits. */ - -static INLINE unsigned int vp8_cost_branch(const unsigned int ct[2], - vp8_prob p) { - /* Imitate existing calculation */ - - return (unsigned int)(((((uint64_t)ct[0]) * vp8_cost_zero(p)) + - (((uint64_t)ct[1]) * vp8_cost_one(p))) >> - 8); -} - -/* Small functions to write explicit values and tokens, as well as - estimate their lengths. */ - -static void vp8_treed_write(vp8_writer *const w, vp8_tree t, - const vp8_prob *const p, int v, - int n) { /* number of bits in v, assumed nonzero */ - vp8_tree_index i = 0; - - do { - const int b = (v >> --n) & 1; - vp8_write(w, b, p[i >> 1]); - i = t[i + b]; - } while (n); -} -static INLINE void vp8_write_token(vp8_writer *const w, vp8_tree t, - const vp8_prob *const p, - vp8_token *const x) { - vp8_treed_write(w, t, p, x->value, x->Len); -} - -static int vp8_treed_cost(vp8_tree t, const vp8_prob *const p, int v, - int n) { /* number of bits in v, assumed nonzero */ - int c = 0; - vp8_tree_index i = 0; - - do { - const int b = (v >> --n) & 1; - c += vp8_cost_bit(p[i >> 1], b); - i = t[i + b]; - } while (n); - - return c; -} -static INLINE int vp8_cost_token(vp8_tree t, const vp8_prob *const p, - vp8_token *const x) { - return vp8_treed_cost(t, p, x->value, x->Len); -} - -/* Fill array of costs for all possible token values. */ - -void vp8_cost_tokens(int *c, const vp8_prob *, vp8_tree); - -void vp8_cost_tokens2(int *c, const vp8_prob *, vp8_tree, int); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP8_ENCODER_TREEWRITER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/vp8_quantize.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/vp8_quantize.c deleted file mode 100644 index 8b9b22ba..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/vp8_quantize.c +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "vpx_ports/bitops.h" -#include "vpx_mem/vpx_mem.h" - -#include "onyx_int.h" -#include "vp8/encoder/quantize.h" -#include "vp8/common/quant_common.h" - -void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d) { - int i, rc, eob; - int x, y, z, sz; - short *coeff_ptr = b->coeff; - short *round_ptr = b->round; - short *quant_ptr = b->quant_fast; - short *qcoeff_ptr = d->qcoeff; - short *dqcoeff_ptr = d->dqcoeff; - short *dequant_ptr = d->dequant; - - eob = -1; - for (i = 0; i < 16; ++i) { - rc = vp8_default_zig_zag1d[i]; - z = coeff_ptr[rc]; - - sz = (z >> 31); /* sign of z */ - x = (z ^ sz) - sz; /* x = abs(z) */ - - y = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; /* quantize (x) */ - x = (y ^ sz) - sz; /* get the sign back */ - qcoeff_ptr[rc] = x; /* write to destination */ - dqcoeff_ptr[rc] = x * dequant_ptr[rc]; /* dequantized value */ - - if (y) { - eob = i; /* last nonzero coeffs */ - } - } - *d->eob = (char)(eob + 1); -} - -void vp8_regular_quantize_b_c(BLOCK *b, BLOCKD *d) { - int i, rc, eob; - int zbin; - int x, y, z, sz; - short *zbin_boost_ptr = b->zrun_zbin_boost; - short *coeff_ptr = b->coeff; - short *zbin_ptr = b->zbin; - short *round_ptr = b->round; - short *quant_ptr = b->quant; - short *quant_shift_ptr = b->quant_shift; - short *qcoeff_ptr = d->qcoeff; - short *dqcoeff_ptr = d->dqcoeff; - short *dequant_ptr = d->dequant; - short zbin_oq_value = b->zbin_extra; - - memset(qcoeff_ptr, 0, 32); - memset(dqcoeff_ptr, 0, 32); - - eob = -1; - - for (i = 0; i < 16; ++i) { - rc = vp8_default_zig_zag1d[i]; - z = coeff_ptr[rc]; - - zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value; - - zbin_boost_ptr++; - sz = (z >> 31); /* sign of z */ - x = (z ^ sz) - sz; /* x = abs(z) */ - - if (x >= zbin) { - x += round_ptr[rc]; - y = ((((x * quant_ptr[rc]) >> 16) + x) * quant_shift_ptr[rc]) >> - 16; /* quantize (x) */ - x = (y ^ sz) - sz; /* get the sign back */ - qcoeff_ptr[rc] = x; /* write to destination */ - dqcoeff_ptr[rc] = x * dequant_ptr[rc]; /* dequantized value */ - - if (y) { - eob = i; /* last nonzero coeffs */ - zbin_boost_ptr = b->zrun_zbin_boost; /* reset zero runlength */ - } - } - } - - *d->eob = (char)(eob + 1); -} - -void vp8_quantize_mby(MACROBLOCK *x) { - int i; - int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED && - x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); - - for (i = 0; i < 16; ++i) x->quantize_b(&x->block[i], &x->e_mbd.block[i]); - - if (has_2nd_order) x->quantize_b(&x->block[24], &x->e_mbd.block[24]); -} - -void vp8_quantize_mb(MACROBLOCK *x) { - int i; - int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED && - x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); - - for (i = 0; i < 24 + has_2nd_order; ++i) { - x->quantize_b(&x->block[i], &x->e_mbd.block[i]); - } -} - -void vp8_quantize_mbuv(MACROBLOCK *x) { - int i; - - for (i = 16; i < 24; ++i) x->quantize_b(&x->block[i], &x->e_mbd.block[i]); -} - -static const int qrounding_factors[129] = { - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 -}; - -static const int qzbin_factors[129] = { - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80 -}; - -static const int qrounding_factors_y2[129] = { - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 -}; - -static const int qzbin_factors_y2[129] = { - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80 -}; - -static void invert_quant(int improved_quant, short *quant, short *shift, - short d) { - if (improved_quant) { - unsigned int t; - int l, m; - t = (unsigned int)d; - l = get_msb(t); - m = 1 + (1 << (16 + l)) / d; - *quant = (short)(m - (1 << 16)); - *shift = l; - /* use multiplication and constant shift by 16 */ - *shift = 1 << (16 - *shift); - } else { - *quant = (1 << 16) / d; - *shift = 0; - } -} - -void vp8cx_init_quantizer(VP8_COMP *cpi) { - int i; - int quant_val; - int Q; - - int zbin_boost[16] = { 0, 0, 8, 10, 12, 14, 16, 20, - 24, 28, 32, 36, 40, 44, 44, 44 }; - - for (Q = 0; Q < QINDEX_RANGE; ++Q) { - /* dc values */ - quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q); - cpi->Y1quant_fast[Q][0] = (1 << 16) / quant_val; - invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 0, - cpi->Y1quant_shift[Q] + 0, quant_val); - cpi->Y1zbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; - cpi->Y1round[Q][0] = (qrounding_factors[Q] * quant_val) >> 7; - cpi->common.Y1dequant[Q][0] = quant_val; - cpi->zrun_zbin_boost_y1[Q][0] = (quant_val * zbin_boost[0]) >> 7; - - quant_val = vp8_dc2quant(Q, cpi->common.y2dc_delta_q); - cpi->Y2quant_fast[Q][0] = (1 << 16) / quant_val; - invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 0, - cpi->Y2quant_shift[Q] + 0, quant_val); - cpi->Y2zbin[Q][0] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7; - cpi->Y2round[Q][0] = (qrounding_factors_y2[Q] * quant_val) >> 7; - cpi->common.Y2dequant[Q][0] = quant_val; - cpi->zrun_zbin_boost_y2[Q][0] = (quant_val * zbin_boost[0]) >> 7; - - quant_val = vp8_dc_uv_quant(Q, cpi->common.uvdc_delta_q); - cpi->UVquant_fast[Q][0] = (1 << 16) / quant_val; - invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 0, - cpi->UVquant_shift[Q] + 0, quant_val); - cpi->UVzbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; - cpi->UVround[Q][0] = (qrounding_factors[Q] * quant_val) >> 7; - cpi->common.UVdequant[Q][0] = quant_val; - cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7; - - /* all the ac values = ; */ - quant_val = vp8_ac_yquant(Q); - cpi->Y1quant_fast[Q][1] = (1 << 16) / quant_val; - invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 1, - cpi->Y1quant_shift[Q] + 1, quant_val); - cpi->Y1zbin[Q][1] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; - cpi->Y1round[Q][1] = (qrounding_factors[Q] * quant_val) >> 7; - cpi->common.Y1dequant[Q][1] = quant_val; - cpi->zrun_zbin_boost_y1[Q][1] = (quant_val * zbin_boost[1]) >> 7; - - quant_val = vp8_ac2quant(Q, cpi->common.y2ac_delta_q); - cpi->Y2quant_fast[Q][1] = (1 << 16) / quant_val; - invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 1, - cpi->Y2quant_shift[Q] + 1, quant_val); - cpi->Y2zbin[Q][1] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7; - cpi->Y2round[Q][1] = (qrounding_factors_y2[Q] * quant_val) >> 7; - cpi->common.Y2dequant[Q][1] = quant_val; - cpi->zrun_zbin_boost_y2[Q][1] = (quant_val * zbin_boost[1]) >> 7; - - quant_val = vp8_ac_uv_quant(Q, cpi->common.uvac_delta_q); - cpi->UVquant_fast[Q][1] = (1 << 16) / quant_val; - invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 1, - cpi->UVquant_shift[Q] + 1, quant_val); - cpi->UVzbin[Q][1] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; - cpi->UVround[Q][1] = (qrounding_factors[Q] * quant_val) >> 7; - cpi->common.UVdequant[Q][1] = quant_val; - cpi->zrun_zbin_boost_uv[Q][1] = (quant_val * zbin_boost[1]) >> 7; - - for (i = 2; i < 16; ++i) { - cpi->Y1quant_fast[Q][i] = cpi->Y1quant_fast[Q][1]; - cpi->Y1quant[Q][i] = cpi->Y1quant[Q][1]; - cpi->Y1quant_shift[Q][i] = cpi->Y1quant_shift[Q][1]; - cpi->Y1zbin[Q][i] = cpi->Y1zbin[Q][1]; - cpi->Y1round[Q][i] = cpi->Y1round[Q][1]; - cpi->zrun_zbin_boost_y1[Q][i] = - (cpi->common.Y1dequant[Q][1] * zbin_boost[i]) >> 7; - - cpi->Y2quant_fast[Q][i] = cpi->Y2quant_fast[Q][1]; - cpi->Y2quant[Q][i] = cpi->Y2quant[Q][1]; - cpi->Y2quant_shift[Q][i] = cpi->Y2quant_shift[Q][1]; - cpi->Y2zbin[Q][i] = cpi->Y2zbin[Q][1]; - cpi->Y2round[Q][i] = cpi->Y2round[Q][1]; - cpi->zrun_zbin_boost_y2[Q][i] = - (cpi->common.Y2dequant[Q][1] * zbin_boost[i]) >> 7; - - cpi->UVquant_fast[Q][i] = cpi->UVquant_fast[Q][1]; - cpi->UVquant[Q][i] = cpi->UVquant[Q][1]; - cpi->UVquant_shift[Q][i] = cpi->UVquant_shift[Q][1]; - cpi->UVzbin[Q][i] = cpi->UVzbin[Q][1]; - cpi->UVround[Q][i] = cpi->UVround[Q][1]; - cpi->zrun_zbin_boost_uv[Q][i] = - (cpi->common.UVdequant[Q][1] * zbin_boost[i]) >> 7; - } - } -} - -#define ZBIN_EXTRA_Y \ - ((cpi->common.Y1dequant[QIndex][1] * \ - (x->zbin_over_quant + x->zbin_mode_boost + x->act_zbin_adj)) >> \ - 7) - -#define ZBIN_EXTRA_UV \ - ((cpi->common.UVdequant[QIndex][1] * \ - (x->zbin_over_quant + x->zbin_mode_boost + x->act_zbin_adj)) >> \ - 7) - -#define ZBIN_EXTRA_Y2 \ - ((cpi->common.Y2dequant[QIndex][1] * \ - ((x->zbin_over_quant / 2) + x->zbin_mode_boost + x->act_zbin_adj)) >> \ - 7) - -void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x, int ok_to_skip) { - int i; - int QIndex; - MACROBLOCKD *xd = &x->e_mbd; - int zbin_extra; - - /* Select the baseline MB Q index. */ - if (xd->segmentation_enabled) { - /* Abs Value */ - if (xd->mb_segment_abs_delta == SEGMENT_ABSDATA) { - QIndex = xd->segment_feature_data[MB_LVL_ALT_Q] - [xd->mode_info_context->mbmi.segment_id]; - /* Delta Value */ - } else { - QIndex = cpi->common.base_qindex + - xd->segment_feature_data[MB_LVL_ALT_Q] - [xd->mode_info_context->mbmi.segment_id]; - /* Clamp to valid range */ - QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0; - } - } else { - QIndex = cpi->common.base_qindex; - } - - /* This initialization should be called at least once. Use ok_to_skip to - * decide if it is ok to skip. - * Before encoding a frame, this function is always called with ok_to_skip - * =0, which means no skiping of calculations. The "last" values are - * initialized at that time. - */ - if (!ok_to_skip || QIndex != x->q_index) { - xd->dequant_y1_dc[0] = 1; - xd->dequant_y1[0] = cpi->common.Y1dequant[QIndex][0]; - xd->dequant_y2[0] = cpi->common.Y2dequant[QIndex][0]; - xd->dequant_uv[0] = cpi->common.UVdequant[QIndex][0]; - - for (i = 1; i < 16; ++i) { - xd->dequant_y1_dc[i] = xd->dequant_y1[i] = - cpi->common.Y1dequant[QIndex][1]; - xd->dequant_y2[i] = cpi->common.Y2dequant[QIndex][1]; - xd->dequant_uv[i] = cpi->common.UVdequant[QIndex][1]; - } -#if 1 - /*TODO: Remove dequant from BLOCKD. This is a temporary solution until - * the quantizer code uses a passed in pointer to the dequant constants. - * This will also require modifications to the x86 and neon assembly. - * */ - for (i = 0; i < 16; ++i) x->e_mbd.block[i].dequant = xd->dequant_y1; - for (i = 16; i < 24; ++i) x->e_mbd.block[i].dequant = xd->dequant_uv; - x->e_mbd.block[24].dequant = xd->dequant_y2; -#endif - - /* Y */ - zbin_extra = ZBIN_EXTRA_Y; - - for (i = 0; i < 16; ++i) { - x->block[i].quant = cpi->Y1quant[QIndex]; - x->block[i].quant_fast = cpi->Y1quant_fast[QIndex]; - x->block[i].quant_shift = cpi->Y1quant_shift[QIndex]; - x->block[i].zbin = cpi->Y1zbin[QIndex]; - x->block[i].round = cpi->Y1round[QIndex]; - x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_y1[QIndex]; - x->block[i].zbin_extra = (short)zbin_extra; - } - - /* UV */ - zbin_extra = ZBIN_EXTRA_UV; - - for (i = 16; i < 24; ++i) { - x->block[i].quant = cpi->UVquant[QIndex]; - x->block[i].quant_fast = cpi->UVquant_fast[QIndex]; - x->block[i].quant_shift = cpi->UVquant_shift[QIndex]; - x->block[i].zbin = cpi->UVzbin[QIndex]; - x->block[i].round = cpi->UVround[QIndex]; - x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_uv[QIndex]; - x->block[i].zbin_extra = (short)zbin_extra; - } - - /* Y2 */ - zbin_extra = ZBIN_EXTRA_Y2; - - x->block[24].quant_fast = cpi->Y2quant_fast[QIndex]; - x->block[24].quant = cpi->Y2quant[QIndex]; - x->block[24].quant_shift = cpi->Y2quant_shift[QIndex]; - x->block[24].zbin = cpi->Y2zbin[QIndex]; - x->block[24].round = cpi->Y2round[QIndex]; - x->block[24].zrun_zbin_boost = cpi->zrun_zbin_boost_y2[QIndex]; - x->block[24].zbin_extra = (short)zbin_extra; - - /* save this macroblock QIndex for vp8_update_zbin_extra() */ - x->q_index = QIndex; - - x->last_zbin_over_quant = x->zbin_over_quant; - x->last_zbin_mode_boost = x->zbin_mode_boost; - x->last_act_zbin_adj = x->act_zbin_adj; - - } else if (x->last_zbin_over_quant != x->zbin_over_quant || - x->last_zbin_mode_boost != x->zbin_mode_boost || - x->last_act_zbin_adj != x->act_zbin_adj) { - /* Y */ - zbin_extra = ZBIN_EXTRA_Y; - - for (i = 0; i < 16; ++i) x->block[i].zbin_extra = (short)zbin_extra; - - /* UV */ - zbin_extra = ZBIN_EXTRA_UV; - - for (i = 16; i < 24; ++i) x->block[i].zbin_extra = (short)zbin_extra; - - /* Y2 */ - zbin_extra = ZBIN_EXTRA_Y2; - x->block[24].zbin_extra = (short)zbin_extra; - - x->last_zbin_over_quant = x->zbin_over_quant; - x->last_zbin_mode_boost = x->zbin_mode_boost; - x->last_act_zbin_adj = x->act_zbin_adj; - } -} - -void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x) { - int i; - int QIndex = x->q_index; - int zbin_extra; - - /* Y */ - zbin_extra = ZBIN_EXTRA_Y; - - for (i = 0; i < 16; ++i) x->block[i].zbin_extra = (short)zbin_extra; - - /* UV */ - zbin_extra = ZBIN_EXTRA_UV; - - for (i = 16; i < 24; ++i) x->block[i].zbin_extra = (short)zbin_extra; - - /* Y2 */ - zbin_extra = ZBIN_EXTRA_Y2; - x->block[24].zbin_extra = (short)zbin_extra; -} -#undef ZBIN_EXTRA_Y -#undef ZBIN_EXTRA_UV -#undef ZBIN_EXTRA_Y2 - -void vp8cx_frame_init_quantizer(VP8_COMP *cpi) { - /* Clear Zbin mode boost for default case */ - cpi->mb.zbin_mode_boost = 0; - - /* MB level quantizer setup */ - vp8cx_mb_init_quantizer(cpi, &cpi->mb, 0); -} - -void vp8_set_quantizer(struct VP8_COMP *cpi, int Q) { - VP8_COMMON *cm = &cpi->common; - MACROBLOCKD *mbd = &cpi->mb.e_mbd; - int update = 0; - int new_delta_q; - int new_uv_delta_q; - cm->base_qindex = Q; - - /* if any of the delta_q values are changing update flag has to be set */ - /* currently only y2dc_delta_q may change */ - - cm->y1dc_delta_q = 0; - cm->y2ac_delta_q = 0; - - if (Q < 4) { - new_delta_q = 4 - Q; - } else { - new_delta_q = 0; - } - - update |= cm->y2dc_delta_q != new_delta_q; - cm->y2dc_delta_q = new_delta_q; - - new_uv_delta_q = 0; - // For screen content, lower the q value for UV channel. For now, select - // conservative delta; same delta for dc and ac, and decrease it with lower - // Q, and set to 0 below some threshold. May want to condition this in - // future on the variance/energy in UV channel. - if (cpi->oxcf.screen_content_mode && Q > 40) { - new_uv_delta_q = -(int)(0.15 * Q); - // Check range: magnitude of delta is 4 bits. - if (new_uv_delta_q < -15) { - new_uv_delta_q = -15; - } - } - update |= cm->uvdc_delta_q != new_uv_delta_q; - cm->uvdc_delta_q = new_uv_delta_q; - cm->uvac_delta_q = new_uv_delta_q; - - /* Set Segment specific quatizers */ - mbd->segment_feature_data[MB_LVL_ALT_Q][0] = - cpi->segment_feature_data[MB_LVL_ALT_Q][0]; - mbd->segment_feature_data[MB_LVL_ALT_Q][1] = - cpi->segment_feature_data[MB_LVL_ALT_Q][1]; - mbd->segment_feature_data[MB_LVL_ALT_Q][2] = - cpi->segment_feature_data[MB_LVL_ALT_Q][2]; - mbd->segment_feature_data[MB_LVL_ALT_Q][3] = - cpi->segment_feature_data[MB_LVL_ALT_Q][3]; - - /* quantizer has to be reinitialized for any delta_q changes */ - if (update) vp8cx_init_quantizer(cpi); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/block_error_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/block_error_sse2.asm deleted file mode 100644 index 200b4ccf..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/block_error_sse2.asm +++ /dev/null @@ -1,188 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -SECTION .text - -;int vp8_block_error_sse2(short *coeff_ptr, short *dcoef_ptr) -globalsym(vp8_block_error_sse2) -sym(vp8_block_error_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 2 - push rsi - push rdi - ; end prologue - - mov rsi, arg(0) ;coeff_ptr - mov rdi, arg(1) ;dcoef_ptr - - movdqa xmm0, [rsi] - movdqa xmm1, [rdi] - - movdqa xmm2, [rsi+16] - movdqa xmm3, [rdi+16] - - psubw xmm0, xmm1 - psubw xmm2, xmm3 - - pmaddwd xmm0, xmm0 - pmaddwd xmm2, xmm2 - - paddd xmm0, xmm2 - - pxor xmm5, xmm5 - movdqa xmm1, xmm0 - - punpckldq xmm0, xmm5 - punpckhdq xmm1, xmm5 - - paddd xmm0, xmm1 - movdqa xmm1, xmm0 - - psrldq xmm0, 8 - paddd xmm0, xmm1 - - movq rax, xmm0 - - pop rdi - pop rsi - ; begin epilog - UNSHADOW_ARGS - pop rbp - ret - -;int vp8_mbblock_error_sse2_impl(short *coeff_ptr, short *dcoef_ptr, int dc); -globalsym(vp8_mbblock_error_sse2_impl) -sym(vp8_mbblock_error_sse2_impl): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 3 - SAVE_XMM 6 - push rsi - push rdi - ; end prolog - - - mov rsi, arg(0) ;coeff_ptr - pxor xmm6, xmm6 - - mov rdi, arg(1) ;dcoef_ptr - pxor xmm4, xmm4 - - movd xmm5, dword ptr arg(2) ;dc - por xmm5, xmm4 - - pcmpeqw xmm5, xmm6 - mov rcx, 16 - -.mberror_loop: - movdqa xmm0, [rsi] - movdqa xmm1, [rdi] - - movdqa xmm2, [rsi+16] - movdqa xmm3, [rdi+16] - - - psubw xmm2, xmm3 - pmaddwd xmm2, xmm2 - - psubw xmm0, xmm1 - pand xmm0, xmm5 - - pmaddwd xmm0, xmm0 - add rsi, 32 - - add rdi, 32 - - sub rcx, 1 - paddd xmm4, xmm2 - - paddd xmm4, xmm0 - jnz .mberror_loop - - movdqa xmm0, xmm4 - punpckldq xmm0, xmm6 - - punpckhdq xmm4, xmm6 - paddd xmm0, xmm4 - - movdqa xmm1, xmm0 - psrldq xmm0, 8 - - paddd xmm0, xmm1 - movq rax, xmm0 - - pop rdi - pop rsi - ; begin epilog - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - - -;int vp8_mbuverror_sse2_impl(short *s_ptr, short *d_ptr); -globalsym(vp8_mbuverror_sse2_impl) -sym(vp8_mbuverror_sse2_impl): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 2 - push rsi - push rdi - ; end prolog - - - mov rsi, arg(0) ;s_ptr - mov rdi, arg(1) ;d_ptr - - mov rcx, 16 - pxor xmm3, xmm3 - -.mbuverror_loop: - - movdqa xmm1, [rsi] - movdqa xmm2, [rdi] - - psubw xmm1, xmm2 - pmaddwd xmm1, xmm1 - - paddd xmm3, xmm1 - - add rsi, 16 - add rdi, 16 - - dec rcx - jnz .mbuverror_loop - - pxor xmm0, xmm0 - movdqa xmm1, xmm3 - - movdqa xmm2, xmm1 - punpckldq xmm1, xmm0 - - punpckhdq xmm2, xmm0 - paddd xmm1, xmm2 - - movdqa xmm2, xmm1 - - psrldq xmm1, 8 - paddd xmm1, xmm2 - - movq rax, xmm1 - - pop rdi - pop rsi - ; begin epilog - UNSHADOW_ARGS - pop rbp - ret diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/copy_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/copy_sse2.asm deleted file mode 100644 index fe78da39..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/copy_sse2.asm +++ /dev/null @@ -1,94 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -SECTION .text - -;void vp8_copy32xn_sse2( -; unsigned char *src_ptr, -; int src_stride, -; unsigned char *dst_ptr, -; int dst_stride, -; int height); -globalsym(vp8_copy32xn_sse2) -sym(vp8_copy32xn_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 5 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;dst_ptr - - movsxd rax, dword ptr arg(1) ;src_stride - movsxd rdx, dword ptr arg(3) ;dst_stride - movsxd rcx, dword ptr arg(4) ;height - -.block_copy_sse2_loopx4: - movdqu xmm0, XMMWORD PTR [rsi] - movdqu xmm1, XMMWORD PTR [rsi + 16] - movdqu xmm2, XMMWORD PTR [rsi + rax] - movdqu xmm3, XMMWORD PTR [rsi + rax + 16] - - lea rsi, [rsi+rax*2] - - movdqu xmm4, XMMWORD PTR [rsi] - movdqu xmm5, XMMWORD PTR [rsi + 16] - movdqu xmm6, XMMWORD PTR [rsi + rax] - movdqu xmm7, XMMWORD PTR [rsi + rax + 16] - - lea rsi, [rsi+rax*2] - - movdqa XMMWORD PTR [rdi], xmm0 - movdqa XMMWORD PTR [rdi + 16], xmm1 - movdqa XMMWORD PTR [rdi + rdx], xmm2 - movdqa XMMWORD PTR [rdi + rdx + 16], xmm3 - - lea rdi, [rdi+rdx*2] - - movdqa XMMWORD PTR [rdi], xmm4 - movdqa XMMWORD PTR [rdi + 16], xmm5 - movdqa XMMWORD PTR [rdi + rdx], xmm6 - movdqa XMMWORD PTR [rdi + rdx + 16], xmm7 - - lea rdi, [rdi+rdx*2] - - sub rcx, 4 - cmp rcx, 4 - jge .block_copy_sse2_loopx4 - - cmp rcx, 0 - je .copy_is_done - -.block_copy_sse2_loop: - movdqu xmm0, XMMWORD PTR [rsi] - movdqu xmm1, XMMWORD PTR [rsi + 16] - lea rsi, [rsi+rax] - - movdqa XMMWORD PTR [rdi], xmm0 - movdqa XMMWORD PTR [rdi + 16], xmm1 - lea rdi, [rdi+rdx] - - sub rcx, 1 - jne .block_copy_sse2_loop - -.copy_is_done: - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/copy_sse3.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/copy_sse3.asm deleted file mode 100644 index c40b2d8b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/copy_sse3.asm +++ /dev/null @@ -1,147 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "vpx_ports/x86_abi_support.asm" - -%macro STACK_FRAME_CREATE_X3 0 -%if ABI_IS_32BIT - %define src_ptr rsi - %define src_stride rax - %define ref_ptr rdi - %define ref_stride rdx - %define end_ptr rcx - %define ret_var rbx - %define result_ptr arg(4) - %define max_sad arg(4) - %define height dword ptr arg(4) - push rbp - mov rbp, rsp - push rsi - push rdi - push rbx - - mov rsi, arg(0) ; src_ptr - mov rdi, arg(2) ; ref_ptr - - movsxd rax, dword ptr arg(1) ; src_stride - movsxd rdx, dword ptr arg(3) ; ref_stride -%else - %if LIBVPX_YASM_WIN64 - SAVE_XMM 7, u - %define src_ptr rcx - %define src_stride rdx - %define ref_ptr r8 - %define ref_stride r9 - %define end_ptr r10 - %define ret_var r11 - %define result_ptr [rsp+xmm_stack_space+8+4*8] - %define max_sad [rsp+xmm_stack_space+8+4*8] - %define height dword ptr [rsp+xmm_stack_space+8+4*8] - %else - %define src_ptr rdi - %define src_stride rsi - %define ref_ptr rdx - %define ref_stride rcx - %define end_ptr r9 - %define ret_var r10 - %define result_ptr r8 - %define max_sad r8 - %define height r8 - %endif -%endif - -%endmacro - -%macro STACK_FRAME_DESTROY_X3 0 - %define src_ptr - %define src_stride - %define ref_ptr - %define ref_stride - %define end_ptr - %define ret_var - %define result_ptr - %define max_sad - %define height - -%if ABI_IS_32BIT - pop rbx - pop rdi - pop rsi - pop rbp -%else - %if LIBVPX_YASM_WIN64 - RESTORE_XMM - %endif -%endif - ret -%endmacro - -SECTION .text - -;void vp8_copy32xn_sse3( -; unsigned char *src_ptr, -; int src_stride, -; unsigned char *dst_ptr, -; int dst_stride, -; int height); -globalsym(vp8_copy32xn_sse3) -sym(vp8_copy32xn_sse3): - - STACK_FRAME_CREATE_X3 - -.block_copy_sse3_loopx4: - lea end_ptr, [src_ptr+src_stride*2] - - movdqu xmm0, XMMWORD PTR [src_ptr] - movdqu xmm1, XMMWORD PTR [src_ptr + 16] - movdqu xmm2, XMMWORD PTR [src_ptr + src_stride] - movdqu xmm3, XMMWORD PTR [src_ptr + src_stride + 16] - movdqu xmm4, XMMWORD PTR [end_ptr] - movdqu xmm5, XMMWORD PTR [end_ptr + 16] - movdqu xmm6, XMMWORD PTR [end_ptr + src_stride] - movdqu xmm7, XMMWORD PTR [end_ptr + src_stride + 16] - - lea src_ptr, [src_ptr+src_stride*4] - - lea end_ptr, [ref_ptr+ref_stride*2] - - movdqa XMMWORD PTR [ref_ptr], xmm0 - movdqa XMMWORD PTR [ref_ptr + 16], xmm1 - movdqa XMMWORD PTR [ref_ptr + ref_stride], xmm2 - movdqa XMMWORD PTR [ref_ptr + ref_stride + 16], xmm3 - movdqa XMMWORD PTR [end_ptr], xmm4 - movdqa XMMWORD PTR [end_ptr + 16], xmm5 - movdqa XMMWORD PTR [end_ptr + ref_stride], xmm6 - movdqa XMMWORD PTR [end_ptr + ref_stride + 16], xmm7 - - lea ref_ptr, [ref_ptr+ref_stride*4] - - sub height, 4 - cmp height, 4 - jge .block_copy_sse3_loopx4 - - ;Check to see if there is more rows need to be copied. - cmp height, 0 - je .copy_is_done - -.block_copy_sse3_loop: - movdqu xmm0, XMMWORD PTR [src_ptr] - movdqu xmm1, XMMWORD PTR [src_ptr + 16] - lea src_ptr, [src_ptr+src_stride] - - movdqa XMMWORD PTR [ref_ptr], xmm0 - movdqa XMMWORD PTR [ref_ptr + 16], xmm1 - lea ref_ptr, [ref_ptr+ref_stride] - - sub height, 1 - jne .block_copy_sse3_loop - -.copy_is_done: - STACK_FRAME_DESTROY_X3 diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/dct_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/dct_sse2.asm deleted file mode 100644 index 3c28cb90..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/dct_sse2.asm +++ /dev/null @@ -1,434 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -%macro STACK_FRAME_CREATE 0 -%if ABI_IS_32BIT - %define input rsi - %define output rdi - %define pitch rax - push rbp - mov rbp, rsp - GET_GOT rbx - push rsi - push rdi - ; end prolog - - mov rsi, arg(0) - mov rdi, arg(1) - - movsxd rax, dword ptr arg(2) - lea rcx, [rsi + rax*2] -%else - %if LIBVPX_YASM_WIN64 - %define input rcx - %define output rdx - %define pitch r8 - SAVE_XMM 7, u - %else - %define input rdi - %define output rsi - %define pitch rdx - %endif -%endif -%endmacro - -%macro STACK_FRAME_DESTROY 0 - %define input - %define output - %define pitch - -%if ABI_IS_32BIT - pop rdi - pop rsi - RESTORE_GOT - pop rbp -%else - %if LIBVPX_YASM_WIN64 - RESTORE_XMM - %endif -%endif - ret -%endmacro - -SECTION .text - -;void vp8_short_fdct4x4_sse2(short *input, short *output, int pitch) -globalsym(vp8_short_fdct4x4_sse2) -sym(vp8_short_fdct4x4_sse2): - - STACK_FRAME_CREATE - - movq xmm0, MMWORD PTR[input ] ;03 02 01 00 - movq xmm2, MMWORD PTR[input+ pitch] ;13 12 11 10 - lea input, [input+2*pitch] - movq xmm1, MMWORD PTR[input ] ;23 22 21 20 - movq xmm3, MMWORD PTR[input+ pitch] ;33 32 31 30 - - punpcklqdq xmm0, xmm2 ;13 12 11 10 03 02 01 00 - punpcklqdq xmm1, xmm3 ;33 32 31 30 23 22 21 20 - - movdqa xmm2, xmm0 - punpckldq xmm0, xmm1 ;23 22 03 02 21 20 01 00 - punpckhdq xmm2, xmm1 ;33 32 13 12 31 30 11 10 - movdqa xmm1, xmm0 - punpckldq xmm0, xmm2 ;31 21 30 20 11 10 01 00 - pshufhw xmm1, xmm1, 0b1h ;22 23 02 03 xx xx xx xx - pshufhw xmm2, xmm2, 0b1h ;32 33 12 13 xx xx xx xx - - punpckhdq xmm1, xmm2 ;32 33 22 23 12 13 02 03 - movdqa xmm3, xmm0 - paddw xmm0, xmm1 ;b1 a1 b1 a1 b1 a1 b1 a1 - psubw xmm3, xmm1 ;c1 d1 c1 d1 c1 d1 c1 d1 - psllw xmm0, 3 ;b1 <<= 3 a1 <<= 3 - psllw xmm3, 3 ;c1 <<= 3 d1 <<= 3 - - movdqa xmm1, xmm0 - pmaddwd xmm0, XMMWORD PTR[GLOBAL(_mult_add)] ;a1 + b1 - pmaddwd xmm1, XMMWORD PTR[GLOBAL(_mult_sub)] ;a1 - b1 - movdqa xmm4, xmm3 - pmaddwd xmm3, XMMWORD PTR[GLOBAL(_5352_2217)] ;c1*2217 + d1*5352 - pmaddwd xmm4, XMMWORD PTR[GLOBAL(_2217_neg5352)];d1*2217 - c1*5352 - - paddd xmm3, XMMWORD PTR[GLOBAL(_14500)] - paddd xmm4, XMMWORD PTR[GLOBAL(_7500)] - psrad xmm3, 12 ;(c1 * 2217 + d1 * 5352 + 14500)>>12 - psrad xmm4, 12 ;(d1 * 2217 - c1 * 5352 + 7500)>>12 - - packssdw xmm0, xmm1 ;op[2] op[0] - packssdw xmm3, xmm4 ;op[3] op[1] - ; 23 22 21 20 03 02 01 00 - ; - ; 33 32 31 30 13 12 11 10 - ; - movdqa xmm2, xmm0 - punpcklqdq xmm0, xmm3 ;13 12 11 10 03 02 01 00 - punpckhqdq xmm2, xmm3 ;23 22 21 20 33 32 31 30 - - movdqa xmm3, xmm0 - punpcklwd xmm0, xmm2 ;32 30 22 20 12 10 02 00 - punpckhwd xmm3, xmm2 ;33 31 23 21 13 11 03 01 - movdqa xmm2, xmm0 - punpcklwd xmm0, xmm3 ;13 12 11 10 03 02 01 00 - punpckhwd xmm2, xmm3 ;33 32 31 30 23 22 21 20 - - movdqa xmm5, XMMWORD PTR[GLOBAL(_7)] - pshufd xmm2, xmm2, 04eh - movdqa xmm3, xmm0 - paddw xmm0, xmm2 ;b1 b1 b1 b1 a1 a1 a1 a1 - psubw xmm3, xmm2 ;c1 c1 c1 c1 d1 d1 d1 d1 - - pshufd xmm0, xmm0, 0d8h ;b1 b1 a1 a1 b1 b1 a1 a1 - movdqa xmm2, xmm3 ;save d1 for compare - pshufd xmm3, xmm3, 0d8h ;c1 c1 d1 d1 c1 c1 d1 d1 - pshuflw xmm0, xmm0, 0d8h ;b1 b1 a1 a1 b1 a1 b1 a1 - pshuflw xmm3, xmm3, 0d8h ;c1 c1 d1 d1 c1 d1 c1 d1 - pshufhw xmm0, xmm0, 0d8h ;b1 a1 b1 a1 b1 a1 b1 a1 - pshufhw xmm3, xmm3, 0d8h ;c1 d1 c1 d1 c1 d1 c1 d1 - movdqa xmm1, xmm0 - pmaddwd xmm0, XMMWORD PTR[GLOBAL(_mult_add)] ;a1 + b1 - pmaddwd xmm1, XMMWORD PTR[GLOBAL(_mult_sub)] ;a1 - b1 - - pxor xmm4, xmm4 ;zero out for compare - paddd xmm0, xmm5 - paddd xmm1, xmm5 - pcmpeqw xmm2, xmm4 - psrad xmm0, 4 ;(a1 + b1 + 7)>>4 - psrad xmm1, 4 ;(a1 - b1 + 7)>>4 - pandn xmm2, XMMWORD PTR[GLOBAL(_cmp_mask)] ;clear upper, - ;and keep bit 0 of lower - - movdqa xmm4, xmm3 - pmaddwd xmm3, XMMWORD PTR[GLOBAL(_5352_2217)] ;c1*2217 + d1*5352 - pmaddwd xmm4, XMMWORD PTR[GLOBAL(_2217_neg5352)] ;d1*2217 - c1*5352 - paddd xmm3, XMMWORD PTR[GLOBAL(_12000)] - paddd xmm4, XMMWORD PTR[GLOBAL(_51000)] - packssdw xmm0, xmm1 ;op[8] op[0] - psrad xmm3, 16 ;(c1 * 2217 + d1 * 5352 + 12000)>>16 - psrad xmm4, 16 ;(d1 * 2217 - c1 * 5352 + 51000)>>16 - - packssdw xmm3, xmm4 ;op[12] op[4] - movdqa xmm1, xmm0 - paddw xmm3, xmm2 ;op[4] += (d1!=0) - punpcklqdq xmm0, xmm3 ;op[4] op[0] - punpckhqdq xmm1, xmm3 ;op[12] op[8] - - movdqa XMMWORD PTR[output + 0], xmm0 - movdqa XMMWORD PTR[output + 16], xmm1 - - STACK_FRAME_DESTROY - -;void vp8_short_fdct8x4_sse2(short *input, short *output, int pitch) -globalsym(vp8_short_fdct8x4_sse2) -sym(vp8_short_fdct8x4_sse2): - - STACK_FRAME_CREATE - - ; read the input data - movdqa xmm0, [input ] - movdqa xmm2, [input+ pitch] - lea input, [input+2*pitch] - movdqa xmm4, [input ] - movdqa xmm3, [input+ pitch] - - ; transpose for the first stage - movdqa xmm1, xmm0 ; 00 01 02 03 04 05 06 07 - movdqa xmm5, xmm4 ; 20 21 22 23 24 25 26 27 - - punpcklwd xmm0, xmm2 ; 00 10 01 11 02 12 03 13 - punpckhwd xmm1, xmm2 ; 04 14 05 15 06 16 07 17 - - punpcklwd xmm4, xmm3 ; 20 30 21 31 22 32 23 33 - punpckhwd xmm5, xmm3 ; 24 34 25 35 26 36 27 37 - - movdqa xmm2, xmm0 ; 00 10 01 11 02 12 03 13 - punpckldq xmm0, xmm4 ; 00 10 20 30 01 11 21 31 - - punpckhdq xmm2, xmm4 ; 02 12 22 32 03 13 23 33 - - movdqa xmm4, xmm1 ; 04 14 05 15 06 16 07 17 - punpckldq xmm4, xmm5 ; 04 14 24 34 05 15 25 35 - - punpckhdq xmm1, xmm5 ; 06 16 26 36 07 17 27 37 - movdqa xmm3, xmm2 ; 02 12 22 32 03 13 23 33 - - punpckhqdq xmm3, xmm1 ; 03 13 23 33 07 17 27 37 - punpcklqdq xmm2, xmm1 ; 02 12 22 32 06 16 26 36 - - movdqa xmm1, xmm0 ; 00 10 20 30 01 11 21 31 - punpcklqdq xmm0, xmm4 ; 00 10 20 30 04 14 24 34 - - punpckhqdq xmm1, xmm4 ; 01 11 21 32 05 15 25 35 - - ; xmm0 0 - ; xmm1 1 - ; xmm2 2 - ; xmm3 3 - - ; first stage - movdqa xmm5, xmm0 - movdqa xmm4, xmm1 - - paddw xmm0, xmm3 ; a1 = 0 + 3 - paddw xmm1, xmm2 ; b1 = 1 + 2 - - psubw xmm4, xmm2 ; c1 = 1 - 2 - psubw xmm5, xmm3 ; d1 = 0 - 3 - - psllw xmm5, 3 - psllw xmm4, 3 - - psllw xmm0, 3 - psllw xmm1, 3 - - ; output 0 and 2 - movdqa xmm2, xmm0 ; a1 - - paddw xmm0, xmm1 ; op[0] = a1 + b1 - psubw xmm2, xmm1 ; op[2] = a1 - b1 - - ; output 1 and 3 - ; interleave c1, d1 - movdqa xmm1, xmm5 ; d1 - punpcklwd xmm1, xmm4 ; c1 d1 - punpckhwd xmm5, xmm4 ; c1 d1 - - movdqa xmm3, xmm1 - movdqa xmm4, xmm5 - - pmaddwd xmm1, XMMWORD PTR[GLOBAL (_5352_2217)] ; c1*2217 + d1*5352 - pmaddwd xmm4, XMMWORD PTR[GLOBAL (_5352_2217)] ; c1*2217 + d1*5352 - - pmaddwd xmm3, XMMWORD PTR[GLOBAL(_2217_neg5352)] ; d1*2217 - c1*5352 - pmaddwd xmm5, XMMWORD PTR[GLOBAL(_2217_neg5352)] ; d1*2217 - c1*5352 - - paddd xmm1, XMMWORD PTR[GLOBAL(_14500)] - paddd xmm4, XMMWORD PTR[GLOBAL(_14500)] - paddd xmm3, XMMWORD PTR[GLOBAL(_7500)] - paddd xmm5, XMMWORD PTR[GLOBAL(_7500)] - - psrad xmm1, 12 ; (c1 * 2217 + d1 * 5352 + 14500)>>12 - psrad xmm4, 12 ; (c1 * 2217 + d1 * 5352 + 14500)>>12 - psrad xmm3, 12 ; (d1 * 2217 - c1 * 5352 + 7500)>>12 - psrad xmm5, 12 ; (d1 * 2217 - c1 * 5352 + 7500)>>12 - - packssdw xmm1, xmm4 ; op[1] - packssdw xmm3, xmm5 ; op[3] - - ; done with vertical - ; transpose for the second stage - movdqa xmm4, xmm0 ; 00 10 20 30 04 14 24 34 - movdqa xmm5, xmm2 ; 02 12 22 32 06 16 26 36 - - punpcklwd xmm0, xmm1 ; 00 01 10 11 20 21 30 31 - punpckhwd xmm4, xmm1 ; 04 05 14 15 24 25 34 35 - - punpcklwd xmm2, xmm3 ; 02 03 12 13 22 23 32 33 - punpckhwd xmm5, xmm3 ; 06 07 16 17 26 27 36 37 - - movdqa xmm1, xmm0 ; 00 01 10 11 20 21 30 31 - punpckldq xmm0, xmm2 ; 00 01 02 03 10 11 12 13 - - punpckhdq xmm1, xmm2 ; 20 21 22 23 30 31 32 33 - - movdqa xmm2, xmm4 ; 04 05 14 15 24 25 34 35 - punpckldq xmm2, xmm5 ; 04 05 06 07 14 15 16 17 - - punpckhdq xmm4, xmm5 ; 24 25 26 27 34 35 36 37 - movdqa xmm3, xmm1 ; 20 21 22 23 30 31 32 33 - - punpckhqdq xmm3, xmm4 ; 30 31 32 33 34 35 36 37 - punpcklqdq xmm1, xmm4 ; 20 21 22 23 24 25 26 27 - - movdqa xmm4, xmm0 ; 00 01 02 03 10 11 12 13 - punpcklqdq xmm0, xmm2 ; 00 01 02 03 04 05 06 07 - - punpckhqdq xmm4, xmm2 ; 10 11 12 13 14 15 16 17 - - ; xmm0 0 - ; xmm1 4 - ; xmm2 1 - ; xmm3 3 - - movdqa xmm5, xmm0 - movdqa xmm2, xmm1 - - paddw xmm0, xmm3 ; a1 = 0 + 3 - paddw xmm1, xmm4 ; b1 = 1 + 2 - - psubw xmm4, xmm2 ; c1 = 1 - 2 - psubw xmm5, xmm3 ; d1 = 0 - 3 - - pxor xmm6, xmm6 ; zero out for compare - - pcmpeqw xmm6, xmm5 ; d1 != 0 - - pandn xmm6, XMMWORD PTR[GLOBAL(_cmp_mask8x4)] ; clear upper, - ; and keep bit 0 of lower - - ; output 0 and 2 - movdqa xmm2, xmm0 ; a1 - - paddw xmm0, xmm1 ; a1 + b1 - psubw xmm2, xmm1 ; a1 - b1 - - paddw xmm0, XMMWORD PTR[GLOBAL(_7w)] - paddw xmm2, XMMWORD PTR[GLOBAL(_7w)] - - psraw xmm0, 4 ; op[0] = (a1 + b1 + 7)>>4 - psraw xmm2, 4 ; op[8] = (a1 - b1 + 7)>>4 - - ; output 1 and 3 - ; interleave c1, d1 - movdqa xmm1, xmm5 ; d1 - punpcklwd xmm1, xmm4 ; c1 d1 - punpckhwd xmm5, xmm4 ; c1 d1 - - movdqa xmm3, xmm1 - movdqa xmm4, xmm5 - - pmaddwd xmm1, XMMWORD PTR[GLOBAL (_5352_2217)] ; c1*2217 + d1*5352 - pmaddwd xmm4, XMMWORD PTR[GLOBAL (_5352_2217)] ; c1*2217 + d1*5352 - - pmaddwd xmm3, XMMWORD PTR[GLOBAL(_2217_neg5352)] ; d1*2217 - c1*5352 - pmaddwd xmm5, XMMWORD PTR[GLOBAL(_2217_neg5352)] ; d1*2217 - c1*5352 - - paddd xmm1, XMMWORD PTR[GLOBAL(_12000)] - paddd xmm4, XMMWORD PTR[GLOBAL(_12000)] - paddd xmm3, XMMWORD PTR[GLOBAL(_51000)] - paddd xmm5, XMMWORD PTR[GLOBAL(_51000)] - - psrad xmm1, 16 ; (c1 * 2217 + d1 * 5352 + 14500)>>16 - psrad xmm4, 16 ; (c1 * 2217 + d1 * 5352 + 14500)>>16 - psrad xmm3, 16 ; (d1 * 2217 - c1 * 5352 + 7500)>>16 - psrad xmm5, 16 ; (d1 * 2217 - c1 * 5352 + 7500)>>16 - - packssdw xmm1, xmm4 ; op[4] - packssdw xmm3, xmm5 ; op[12] - - paddw xmm1, xmm6 ; op[4] += (d1!=0) - - movdqa xmm4, xmm0 - movdqa xmm5, xmm2 - - punpcklqdq xmm0, xmm1 - punpckhqdq xmm4, xmm1 - - punpcklqdq xmm2, xmm3 - punpckhqdq xmm5, xmm3 - - movdqa XMMWORD PTR[output + 0 ], xmm0 - movdqa XMMWORD PTR[output + 16], xmm2 - movdqa XMMWORD PTR[output + 32], xmm4 - movdqa XMMWORD PTR[output + 48], xmm5 - - STACK_FRAME_DESTROY - -SECTION_RODATA -align 16 -_5352_2217: - dw 5352 - dw 2217 - dw 5352 - dw 2217 - dw 5352 - dw 2217 - dw 5352 - dw 2217 -align 16 -_2217_neg5352: - dw 2217 - dw -5352 - dw 2217 - dw -5352 - dw 2217 - dw -5352 - dw 2217 - dw -5352 -align 16 -_mult_add: - times 8 dw 1 -align 16 -_cmp_mask: - times 4 dw 1 - times 4 dw 0 -align 16 -_cmp_mask8x4: - times 8 dw 1 -align 16 -_mult_sub: - dw 1 - dw -1 - dw 1 - dw -1 - dw 1 - dw -1 - dw 1 - dw -1 -align 16 -_7: - times 4 dd 7 -align 16 -_7w: - times 8 dw 7 -align 16 -_14500: - times 4 dd 14500 -align 16 -_7500: - times 4 dd 7500 -align 16 -_12000: - times 4 dd 12000 -align 16 -_51000: - times 4 dd 51000 diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/denoising_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/denoising_sse2.c deleted file mode 100644 index f35b9301..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/denoising_sse2.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp8/encoder/denoising.h" -#include "vp8/common/reconinter.h" -#include "vpx/vpx_integer.h" -#include "vpx_mem/vpx_mem.h" -#include "vp8_rtcd.h" - -#include -#include "vpx_ports/emmintrin_compat.h" - -/* Compute the sum of all pixel differences of this MB. */ -static INLINE unsigned int abs_sum_diff_16x1(__m128i acc_diff) { - const __m128i k_1 = _mm_set1_epi16(1); - const __m128i acc_diff_lo = - _mm_srai_epi16(_mm_unpacklo_epi8(acc_diff, acc_diff), 8); - const __m128i acc_diff_hi = - _mm_srai_epi16(_mm_unpackhi_epi8(acc_diff, acc_diff), 8); - const __m128i acc_diff_16 = _mm_add_epi16(acc_diff_lo, acc_diff_hi); - const __m128i hg_fe_dc_ba = _mm_madd_epi16(acc_diff_16, k_1); - const __m128i hgfe_dcba = - _mm_add_epi32(hg_fe_dc_ba, _mm_srli_si128(hg_fe_dc_ba, 8)); - const __m128i hgfedcba = - _mm_add_epi32(hgfe_dcba, _mm_srli_si128(hgfe_dcba, 4)); - unsigned int sum_diff = (unsigned int)abs(_mm_cvtsi128_si32(hgfedcba)); - - return sum_diff; -} - -int vp8_denoiser_filter_sse2(unsigned char *mc_running_avg_y, - int mc_avg_y_stride, unsigned char *running_avg_y, - int avg_y_stride, unsigned char *sig, - int sig_stride, unsigned int motion_magnitude, - int increase_denoising) { - unsigned char *running_avg_y_start = running_avg_y; - unsigned char *sig_start = sig; - unsigned int sum_diff_thresh; - int r; - int shift_inc = - (increase_denoising && motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) - ? 1 - : 0; - __m128i acc_diff = _mm_setzero_si128(); - const __m128i k_0 = _mm_setzero_si128(); - const __m128i k_4 = _mm_set1_epi8(4 + shift_inc); - const __m128i k_8 = _mm_set1_epi8(8); - const __m128i k_16 = _mm_set1_epi8(16); - /* Modify each level's adjustment according to motion_magnitude. */ - const __m128i l3 = _mm_set1_epi8( - (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) ? 7 + shift_inc : 6); - /* Difference between level 3 and level 2 is 2. */ - const __m128i l32 = _mm_set1_epi8(2); - /* Difference between level 2 and level 1 is 1. */ - const __m128i l21 = _mm_set1_epi8(1); - - for (r = 0; r < 16; ++r) { - /* Calculate differences */ - const __m128i v_sig = _mm_loadu_si128((__m128i *)(&sig[0])); - const __m128i v_mc_running_avg_y = - _mm_loadu_si128((__m128i *)(&mc_running_avg_y[0])); - __m128i v_running_avg_y; - const __m128i pdiff = _mm_subs_epu8(v_mc_running_avg_y, v_sig); - const __m128i ndiff = _mm_subs_epu8(v_sig, v_mc_running_avg_y); - /* Obtain the sign. FF if diff is negative. */ - const __m128i diff_sign = _mm_cmpeq_epi8(pdiff, k_0); - /* Clamp absolute difference to 16 to be used to get mask. Doing this - * allows us to use _mm_cmpgt_epi8, which operates on signed byte. */ - const __m128i clamped_absdiff = - _mm_min_epu8(_mm_or_si128(pdiff, ndiff), k_16); - /* Get masks for l2 l1 and l0 adjustments */ - const __m128i mask2 = _mm_cmpgt_epi8(k_16, clamped_absdiff); - const __m128i mask1 = _mm_cmpgt_epi8(k_8, clamped_absdiff); - const __m128i mask0 = _mm_cmpgt_epi8(k_4, clamped_absdiff); - /* Get adjustments for l2, l1, and l0 */ - __m128i adj2 = _mm_and_si128(mask2, l32); - const __m128i adj1 = _mm_and_si128(mask1, l21); - const __m128i adj0 = _mm_and_si128(mask0, clamped_absdiff); - __m128i adj, padj, nadj; - - /* Combine the adjustments and get absolute adjustments. */ - adj2 = _mm_add_epi8(adj2, adj1); - adj = _mm_sub_epi8(l3, adj2); - adj = _mm_andnot_si128(mask0, adj); - adj = _mm_or_si128(adj, adj0); - - /* Restore the sign and get positive and negative adjustments. */ - padj = _mm_andnot_si128(diff_sign, adj); - nadj = _mm_and_si128(diff_sign, adj); - - /* Calculate filtered value. */ - v_running_avg_y = _mm_adds_epu8(v_sig, padj); - v_running_avg_y = _mm_subs_epu8(v_running_avg_y, nadj); - _mm_storeu_si128((__m128i *)running_avg_y, v_running_avg_y); - - /* Adjustments <=7, and each element in acc_diff can fit in signed - * char. - */ - acc_diff = _mm_adds_epi8(acc_diff, padj); - acc_diff = _mm_subs_epi8(acc_diff, nadj); - - /* Update pointers for next iteration. */ - sig += sig_stride; - mc_running_avg_y += mc_avg_y_stride; - running_avg_y += avg_y_stride; - } - - { - /* Compute the sum of all pixel differences of this MB. */ - unsigned int abs_sum_diff = abs_sum_diff_16x1(acc_diff); - sum_diff_thresh = SUM_DIFF_THRESHOLD; - if (increase_denoising) sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH; - if (abs_sum_diff > sum_diff_thresh) { - // Before returning to copy the block (i.e., apply no denoising), - // check if we can still apply some (weaker) temporal filtering to - // this block, that would otherwise not be denoised at all. Simplest - // is to apply an additional adjustment to running_avg_y to bring it - // closer to sig. The adjustment is capped by a maximum delta, and - // chosen such that in most cases the resulting sum_diff will be - // within the acceptable range given by sum_diff_thresh. - - // The delta is set by the excess of absolute pixel diff over the - // threshold. - int delta = ((abs_sum_diff - sum_diff_thresh) >> 8) + 1; - // Only apply the adjustment for max delta up to 3. - if (delta < 4) { - const __m128i k_delta = _mm_set1_epi8(delta); - sig -= sig_stride * 16; - mc_running_avg_y -= mc_avg_y_stride * 16; - running_avg_y -= avg_y_stride * 16; - for (r = 0; r < 16; ++r) { - __m128i v_running_avg_y = - _mm_loadu_si128((__m128i *)(&running_avg_y[0])); - // Calculate differences. - const __m128i v_sig = _mm_loadu_si128((__m128i *)(&sig[0])); - const __m128i v_mc_running_avg_y = - _mm_loadu_si128((__m128i *)(&mc_running_avg_y[0])); - const __m128i pdiff = _mm_subs_epu8(v_mc_running_avg_y, v_sig); - const __m128i ndiff = _mm_subs_epu8(v_sig, v_mc_running_avg_y); - // Obtain the sign. FF if diff is negative. - const __m128i diff_sign = _mm_cmpeq_epi8(pdiff, k_0); - // Clamp absolute difference to delta to get the adjustment. - const __m128i adj = _mm_min_epu8(_mm_or_si128(pdiff, ndiff), k_delta); - // Restore the sign and get positive and negative adjustments. - __m128i padj, nadj; - padj = _mm_andnot_si128(diff_sign, adj); - nadj = _mm_and_si128(diff_sign, adj); - // Calculate filtered value. - v_running_avg_y = _mm_subs_epu8(v_running_avg_y, padj); - v_running_avg_y = _mm_adds_epu8(v_running_avg_y, nadj); - _mm_storeu_si128((__m128i *)running_avg_y, v_running_avg_y); - - // Accumulate the adjustments. - acc_diff = _mm_subs_epi8(acc_diff, padj); - acc_diff = _mm_adds_epi8(acc_diff, nadj); - - // Update pointers for next iteration. - sig += sig_stride; - mc_running_avg_y += mc_avg_y_stride; - running_avg_y += avg_y_stride; - } - abs_sum_diff = abs_sum_diff_16x1(acc_diff); - if (abs_sum_diff > sum_diff_thresh) { - return COPY_BLOCK; - } - } else { - return COPY_BLOCK; - } - } - } - - vp8_copy_mem16x16(running_avg_y_start, avg_y_stride, sig_start, sig_stride); - return FILTER_BLOCK; -} - -int vp8_denoiser_filter_uv_sse2(unsigned char *mc_running_avg, - int mc_avg_stride, unsigned char *running_avg, - int avg_stride, unsigned char *sig, - int sig_stride, unsigned int motion_magnitude, - int increase_denoising) { - unsigned char *running_avg_start = running_avg; - unsigned char *sig_start = sig; - unsigned int sum_diff_thresh; - int r; - int shift_inc = - (increase_denoising && motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD_UV) - ? 1 - : 0; - __m128i acc_diff = _mm_setzero_si128(); - const __m128i k_0 = _mm_setzero_si128(); - const __m128i k_4 = _mm_set1_epi8(4 + shift_inc); - const __m128i k_8 = _mm_set1_epi8(8); - const __m128i k_16 = _mm_set1_epi8(16); - /* Modify each level's adjustment according to motion_magnitude. */ - const __m128i l3 = _mm_set1_epi8( - (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD_UV) ? 7 + shift_inc : 6); - /* Difference between level 3 and level 2 is 2. */ - const __m128i l32 = _mm_set1_epi8(2); - /* Difference between level 2 and level 1 is 1. */ - const __m128i l21 = _mm_set1_epi8(1); - - { - const __m128i k_1 = _mm_set1_epi16(1); - __m128i vec_sum_block = _mm_setzero_si128(); - - // Avoid denoising color signal if its close to average level. - for (r = 0; r < 8; ++r) { - const __m128i v_sig = _mm_loadl_epi64((__m128i *)(&sig[0])); - const __m128i v_sig_unpack = _mm_unpacklo_epi8(v_sig, k_0); - vec_sum_block = _mm_add_epi16(vec_sum_block, v_sig_unpack); - sig += sig_stride; - } - sig -= sig_stride * 8; - { - const __m128i hg_fe_dc_ba = _mm_madd_epi16(vec_sum_block, k_1); - const __m128i hgfe_dcba = - _mm_add_epi32(hg_fe_dc_ba, _mm_srli_si128(hg_fe_dc_ba, 8)); - const __m128i hgfedcba = - _mm_add_epi32(hgfe_dcba, _mm_srli_si128(hgfe_dcba, 4)); - const int sum_block = _mm_cvtsi128_si32(hgfedcba); - if (abs(sum_block - (128 * 8 * 8)) < SUM_DIFF_FROM_AVG_THRESH_UV) { - return COPY_BLOCK; - } - } - } - - for (r = 0; r < 4; ++r) { - /* Calculate differences */ - const __m128i v_sig_low = - _mm_castpd_si128(_mm_load_sd((double *)(&sig[0]))); - const __m128i v_sig = _mm_castpd_si128(_mm_loadh_pd( - _mm_castsi128_pd(v_sig_low), (double *)(&sig[sig_stride]))); - const __m128i v_mc_running_avg_low = - _mm_castpd_si128(_mm_load_sd((double *)(&mc_running_avg[0]))); - const __m128i v_mc_running_avg = _mm_castpd_si128( - _mm_loadh_pd(_mm_castsi128_pd(v_mc_running_avg_low), - (double *)(&mc_running_avg[mc_avg_stride]))); - const __m128i pdiff = _mm_subs_epu8(v_mc_running_avg, v_sig); - const __m128i ndiff = _mm_subs_epu8(v_sig, v_mc_running_avg); - /* Obtain the sign. FF if diff is negative. */ - const __m128i diff_sign = _mm_cmpeq_epi8(pdiff, k_0); - /* Clamp absolute difference to 16 to be used to get mask. Doing this - * allows us to use _mm_cmpgt_epi8, which operates on signed byte. */ - const __m128i clamped_absdiff = - _mm_min_epu8(_mm_or_si128(pdiff, ndiff), k_16); - /* Get masks for l2 l1 and l0 adjustments */ - const __m128i mask2 = _mm_cmpgt_epi8(k_16, clamped_absdiff); - const __m128i mask1 = _mm_cmpgt_epi8(k_8, clamped_absdiff); - const __m128i mask0 = _mm_cmpgt_epi8(k_4, clamped_absdiff); - /* Get adjustments for l2, l1, and l0 */ - __m128i adj2 = _mm_and_si128(mask2, l32); - const __m128i adj1 = _mm_and_si128(mask1, l21); - const __m128i adj0 = _mm_and_si128(mask0, clamped_absdiff); - __m128i adj, padj, nadj; - __m128i v_running_avg; - - /* Combine the adjustments and get absolute adjustments. */ - adj2 = _mm_add_epi8(adj2, adj1); - adj = _mm_sub_epi8(l3, adj2); - adj = _mm_andnot_si128(mask0, adj); - adj = _mm_or_si128(adj, adj0); - - /* Restore the sign and get positive and negative adjustments. */ - padj = _mm_andnot_si128(diff_sign, adj); - nadj = _mm_and_si128(diff_sign, adj); - - /* Calculate filtered value. */ - v_running_avg = _mm_adds_epu8(v_sig, padj); - v_running_avg = _mm_subs_epu8(v_running_avg, nadj); - - _mm_storel_pd((double *)&running_avg[0], _mm_castsi128_pd(v_running_avg)); - _mm_storeh_pd((double *)&running_avg[avg_stride], - _mm_castsi128_pd(v_running_avg)); - - /* Adjustments <=7, and each element in acc_diff can fit in signed - * char. - */ - acc_diff = _mm_adds_epi8(acc_diff, padj); - acc_diff = _mm_subs_epi8(acc_diff, nadj); - - /* Update pointers for next iteration. */ - sig += sig_stride * 2; - mc_running_avg += mc_avg_stride * 2; - running_avg += avg_stride * 2; - } - - { - unsigned int abs_sum_diff = abs_sum_diff_16x1(acc_diff); - sum_diff_thresh = SUM_DIFF_THRESHOLD_UV; - if (increase_denoising) sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH_UV; - if (abs_sum_diff > sum_diff_thresh) { - // Before returning to copy the block (i.e., apply no denoising), - // check if we can still apply some (weaker) temporal filtering to - // this block, that would otherwise not be denoised at all. Simplest - // is to apply an additional adjustment to running_avg_y to bring it - // closer to sig. The adjustment is capped by a maximum delta, and - // chosen such that in most cases the resulting sum_diff will be - // within the acceptable range given by sum_diff_thresh. - - // The delta is set by the excess of absolute pixel diff over the - // threshold. - int delta = ((abs_sum_diff - sum_diff_thresh) >> 8) + 1; - // Only apply the adjustment for max delta up to 3. - if (delta < 4) { - const __m128i k_delta = _mm_set1_epi8(delta); - sig -= sig_stride * 8; - mc_running_avg -= mc_avg_stride * 8; - running_avg -= avg_stride * 8; - for (r = 0; r < 4; ++r) { - // Calculate differences. - const __m128i v_sig_low = - _mm_castpd_si128(_mm_load_sd((double *)(&sig[0]))); - const __m128i v_sig = _mm_castpd_si128(_mm_loadh_pd( - _mm_castsi128_pd(v_sig_low), (double *)(&sig[sig_stride]))); - const __m128i v_mc_running_avg_low = - _mm_castpd_si128(_mm_load_sd((double *)(&mc_running_avg[0]))); - const __m128i v_mc_running_avg = _mm_castpd_si128( - _mm_loadh_pd(_mm_castsi128_pd(v_mc_running_avg_low), - (double *)(&mc_running_avg[mc_avg_stride]))); - const __m128i pdiff = _mm_subs_epu8(v_mc_running_avg, v_sig); - const __m128i ndiff = _mm_subs_epu8(v_sig, v_mc_running_avg); - // Obtain the sign. FF if diff is negative. - const __m128i diff_sign = _mm_cmpeq_epi8(pdiff, k_0); - // Clamp absolute difference to delta to get the adjustment. - const __m128i adj = _mm_min_epu8(_mm_or_si128(pdiff, ndiff), k_delta); - // Restore the sign and get positive and negative adjustments. - __m128i padj, nadj; - const __m128i v_running_avg_low = - _mm_castpd_si128(_mm_load_sd((double *)(&running_avg[0]))); - __m128i v_running_avg = _mm_castpd_si128( - _mm_loadh_pd(_mm_castsi128_pd(v_running_avg_low), - (double *)(&running_avg[avg_stride]))); - padj = _mm_andnot_si128(diff_sign, adj); - nadj = _mm_and_si128(diff_sign, adj); - // Calculate filtered value. - v_running_avg = _mm_subs_epu8(v_running_avg, padj); - v_running_avg = _mm_adds_epu8(v_running_avg, nadj); - - _mm_storel_pd((double *)&running_avg[0], - _mm_castsi128_pd(v_running_avg)); - _mm_storeh_pd((double *)&running_avg[avg_stride], - _mm_castsi128_pd(v_running_avg)); - - // Accumulate the adjustments. - acc_diff = _mm_subs_epi8(acc_diff, padj); - acc_diff = _mm_adds_epi8(acc_diff, nadj); - - // Update pointers for next iteration. - sig += sig_stride * 2; - mc_running_avg += mc_avg_stride * 2; - running_avg += avg_stride * 2; - } - abs_sum_diff = abs_sum_diff_16x1(acc_diff); - if (abs_sum_diff > sum_diff_thresh) { - return COPY_BLOCK; - } - } else { - return COPY_BLOCK; - } - } - } - - vp8_copy_mem8x8(running_avg_start, avg_stride, sig_start, sig_stride); - return FILTER_BLOCK; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/fwalsh_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/fwalsh_sse2.asm deleted file mode 100644 index 938fc173..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/fwalsh_sse2.asm +++ /dev/null @@ -1,166 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -SECTION .text - -;void vp8_short_walsh4x4_sse2(short *input, short *output, int pitch) -globalsym(vp8_short_walsh4x4_sse2) -sym(vp8_short_walsh4x4_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 3 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - mov rsi, arg(0) ; input - mov rdi, arg(1) ; output - movsxd rdx, dword ptr arg(2) ; pitch - - ; first for loop - movq xmm0, MMWORD PTR [rsi] ; load input - movq xmm1, MMWORD PTR [rsi + rdx] - lea rsi, [rsi + rdx*2] - movq xmm2, MMWORD PTR [rsi] - movq xmm3, MMWORD PTR [rsi + rdx] - - punpcklwd xmm0, xmm1 - punpcklwd xmm2, xmm3 - - movdqa xmm1, xmm0 - punpckldq xmm0, xmm2 ; ip[1] ip[0] - punpckhdq xmm1, xmm2 ; ip[3] ip[2] - - movdqa xmm2, xmm0 - paddw xmm0, xmm1 - psubw xmm2, xmm1 - - psllw xmm0, 2 ; d1 a1 - psllw xmm2, 2 ; c1 b1 - - movdqa xmm1, xmm0 - punpcklqdq xmm0, xmm2 ; b1 a1 - punpckhqdq xmm1, xmm2 ; c1 d1 - - pxor xmm6, xmm6 - movq xmm6, xmm0 - pxor xmm7, xmm7 - pcmpeqw xmm7, xmm6 - paddw xmm7, [GLOBAL(c1)] - - movdqa xmm2, xmm0 - paddw xmm0, xmm1 ; b1+c1 a1+d1 - psubw xmm2, xmm1 ; b1-c1 a1-d1 - paddw xmm0, xmm7 ; b1+c1 a1+d1+(a1!=0) - - ; second for loop - ; input: 13 9 5 1 12 8 4 0 (xmm0) - ; 14 10 6 2 15 11 7 3 (xmm2) - ; after shuffle: - ; 13 5 9 1 12 4 8 0 (xmm0) - ; 14 6 10 2 15 7 11 3 (xmm1) - pshuflw xmm3, xmm0, 0xd8 - pshufhw xmm0, xmm3, 0xd8 - pshuflw xmm3, xmm2, 0xd8 - pshufhw xmm1, xmm3, 0xd8 - - movdqa xmm2, xmm0 - pmaddwd xmm0, [GLOBAL(c1)] ; d11 a11 d10 a10 - pmaddwd xmm2, [GLOBAL(cn1)] ; c11 b11 c10 b10 - movdqa xmm3, xmm1 - pmaddwd xmm1, [GLOBAL(c1)] ; d12 a12 d13 a13 - pmaddwd xmm3, [GLOBAL(cn1)] ; c12 b12 c13 b13 - - pshufd xmm4, xmm0, 0xd8 ; d11 d10 a11 a10 - pshufd xmm5, xmm2, 0xd8 ; c11 c10 b11 b10 - pshufd xmm6, xmm1, 0x72 ; d13 d12 a13 a12 - pshufd xmm7, xmm3, 0x72 ; c13 c12 b13 b12 - - movdqa xmm0, xmm4 - punpcklqdq xmm0, xmm5 ; b11 b10 a11 a10 - punpckhqdq xmm4, xmm5 ; c11 c10 d11 d10 - movdqa xmm1, xmm6 - punpcklqdq xmm1, xmm7 ; b13 b12 a13 a12 - punpckhqdq xmm6, xmm7 ; c13 c12 d13 d12 - - movdqa xmm2, xmm0 - paddd xmm0, xmm4 ; b21 b20 a21 a20 - psubd xmm2, xmm4 ; c21 c20 d21 d20 - movdqa xmm3, xmm1 - paddd xmm1, xmm6 ; b23 b22 a23 a22 - psubd xmm3, xmm6 ; c23 c22 d23 d22 - - pxor xmm4, xmm4 - movdqa xmm5, xmm4 - pcmpgtd xmm4, xmm0 - pcmpgtd xmm5, xmm2 - pand xmm4, [GLOBAL(cd1)] - pand xmm5, [GLOBAL(cd1)] - - pxor xmm6, xmm6 - movdqa xmm7, xmm6 - pcmpgtd xmm6, xmm1 - pcmpgtd xmm7, xmm3 - pand xmm6, [GLOBAL(cd1)] - pand xmm7, [GLOBAL(cd1)] - - paddd xmm0, xmm4 - paddd xmm2, xmm5 - paddd xmm0, [GLOBAL(cd3)] - paddd xmm2, [GLOBAL(cd3)] - paddd xmm1, xmm6 - paddd xmm3, xmm7 - paddd xmm1, [GLOBAL(cd3)] - paddd xmm3, [GLOBAL(cd3)] - - psrad xmm0, 3 - psrad xmm1, 3 - psrad xmm2, 3 - psrad xmm3, 3 - movdqa xmm4, xmm0 - punpcklqdq xmm0, xmm1 ; a23 a22 a21 a20 - punpckhqdq xmm4, xmm1 ; b23 b22 b21 b20 - movdqa xmm5, xmm2 - punpckhqdq xmm2, xmm3 ; c23 c22 c21 c20 - punpcklqdq xmm5, xmm3 ; d23 d22 d21 d20 - - packssdw xmm0, xmm4 ; b23 b22 b21 b20 a23 a22 a21 a20 - packssdw xmm2, xmm5 ; d23 d22 d21 d20 c23 c22 c21 c20 - - movdqa XMMWORD PTR [rdi], xmm0 - movdqa XMMWORD PTR [rdi + 16], xmm2 - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -SECTION_RODATA -align 16 -c1: - dw 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001 -align 16 -cn1: - dw 0x0001, 0xffff, 0x0001, 0xffff, 0x0001, 0xffff, 0x0001, 0xffff -align 16 -cd1: - dd 0x00000001, 0x00000001, 0x00000001, 0x00000001 -align 16 -cd3: - dd 0x00000003, 0x00000003, 0x00000003, 0x00000003 diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/quantize_sse4.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/quantize_sse4.c deleted file mode 100644 index 4c2d24cc..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/quantize_sse4.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include /* SSE4.1 */ - -#include "./vp8_rtcd.h" -#include "vp8/encoder/block.h" -#include "vpx_ports/bitops.h" /* get_lsb */ -#include "vpx_ports/compiler_attributes.h" - -// Unsigned shift overflow is disabled for the use of ~1U << eob with ymask. -VPX_NO_UNSIGNED_SHIFT_CHECK void vp8_regular_quantize_b_sse4_1(BLOCK *b, - BLOCKD *d) { - int eob = -1; - short *zbin_boost_ptr = b->zrun_zbin_boost; - __m128i zbin_boost0 = _mm_load_si128((__m128i *)(zbin_boost_ptr)); - __m128i zbin_boost1 = _mm_load_si128((__m128i *)(zbin_boost_ptr + 8)); - __m128i x0, x1, y0, y1, x_minus_zbin0, x_minus_zbin1, dqcoeff0, dqcoeff1; - __m128i quant_shift0 = _mm_load_si128((__m128i *)(b->quant_shift)); - __m128i quant_shift1 = _mm_load_si128((__m128i *)(b->quant_shift + 8)); - __m128i z0 = _mm_load_si128((__m128i *)(b->coeff)); - __m128i z1 = _mm_load_si128((__m128i *)(b->coeff + 8)); - __m128i zbin_extra = _mm_cvtsi32_si128(b->zbin_extra); - __m128i zbin0 = _mm_load_si128((__m128i *)(b->zbin)); - __m128i zbin1 = _mm_load_si128((__m128i *)(b->zbin + 8)); - __m128i round0 = _mm_load_si128((__m128i *)(b->round)); - __m128i round1 = _mm_load_si128((__m128i *)(b->round + 8)); - __m128i quant0 = _mm_load_si128((__m128i *)(b->quant)); - __m128i quant1 = _mm_load_si128((__m128i *)(b->quant + 8)); - __m128i dequant0 = _mm_load_si128((__m128i *)(d->dequant)); - __m128i dequant1 = _mm_load_si128((__m128i *)(d->dequant + 8)); - __m128i qcoeff0, qcoeff1, t0, t1, x_shuf0, x_shuf1; - uint32_t mask, ymask; - DECLARE_ALIGNED(16, static const uint8_t, - zig_zag_mask[16]) = { 0, 1, 4, 8, 5, 2, 3, 6, - 9, 12, 13, 10, 7, 11, 14, 15 }; - DECLARE_ALIGNED(16, uint16_t, qcoeff[16]) = { 0 }; - - /* Duplicate to all lanes. */ - zbin_extra = _mm_shufflelo_epi16(zbin_extra, 0); - zbin_extra = _mm_unpacklo_epi16(zbin_extra, zbin_extra); - - /* x = abs(z) */ - x0 = _mm_abs_epi16(z0); - x1 = _mm_abs_epi16(z1); - - /* zbin[] + zbin_extra */ - zbin0 = _mm_add_epi16(zbin0, zbin_extra); - zbin1 = _mm_add_epi16(zbin1, zbin_extra); - - /* In C x is compared to zbin where zbin = zbin[] + boost + extra. Rebalance - * the equation because boost is the only value which can change: - * x - (zbin[] + extra) >= boost */ - x_minus_zbin0 = _mm_sub_epi16(x0, zbin0); - x_minus_zbin1 = _mm_sub_epi16(x1, zbin1); - - /* All the remaining calculations are valid whether they are done now with - * simd or later inside the loop one at a time. */ - x0 = _mm_add_epi16(x0, round0); - x1 = _mm_add_epi16(x1, round1); - - y0 = _mm_mulhi_epi16(x0, quant0); - y1 = _mm_mulhi_epi16(x1, quant1); - - y0 = _mm_add_epi16(y0, x0); - y1 = _mm_add_epi16(y1, x1); - - /* Instead of shifting each value independently we convert the scaling - * factor with 1 << (16 - shift) so we can use multiply/return high half. */ - y0 = _mm_mulhi_epi16(y0, quant_shift0); - y1 = _mm_mulhi_epi16(y1, quant_shift1); - - /* Restore the sign. */ - y0 = _mm_sign_epi16(y0, z0); - y1 = _mm_sign_epi16(y1, z1); - - { - const __m128i zig_zag_i16_0 = - _mm_setr_epi8(0, 1, 2, 3, 8, 9, 14, 15, 10, 11, 4, 5, 6, 7, 12, 13); - const __m128i zig_zag_i16_1 = - _mm_setr_epi8(0, 1, 6, 7, 8, 9, 2, 3, 14, 15, 4, 5, 10, 11, 12, 13); - - /* The first part of the zig zag needs a value - * from x_minus_zbin1 and vice versa. */ - t1 = _mm_alignr_epi8(x_minus_zbin1, x_minus_zbin1, 2); - t0 = _mm_blend_epi16(x_minus_zbin0, t1, 0x80); - t1 = _mm_blend_epi16(t1, x_minus_zbin0, 0x80); - x_shuf0 = _mm_shuffle_epi8(t0, zig_zag_i16_0); - x_shuf1 = _mm_shuffle_epi8(t1, zig_zag_i16_1); - } - - /* Check if y is nonzero and put it in zig zag order. */ - t0 = _mm_packs_epi16(y0, y1); - t0 = _mm_cmpeq_epi8(t0, _mm_setzero_si128()); - t0 = _mm_shuffle_epi8(t0, _mm_load_si128((const __m128i *)zig_zag_mask)); - ymask = _mm_movemask_epi8(t0) ^ 0xffff; - - for (;;) { - t0 = _mm_cmpgt_epi16(zbin_boost0, x_shuf0); - t1 = _mm_cmpgt_epi16(zbin_boost1, x_shuf1); - t0 = _mm_packs_epi16(t0, t1); - mask = _mm_movemask_epi8(t0); - mask = ~mask & ymask; - if (!mask) break; - /* |eob| will contain the index of the next found element where: - * boost[i - old_eob - 1] <= x[zigzag[i]] && y[zigzag[i]] != 0 */ - eob = get_lsb(mask); - /* Need to clear the mask from processed elements so that - * they are no longer counted in the next iteration. */ - ymask &= ~1U << eob; - /* It's safe to read ahead of this buffer if struct VP8_COMP has at - * least 32 bytes before the zrun_zbin_boost_* fields (it has 384). - * Any data read outside of the buffer is masked by the updated |ymask|. */ - zbin_boost0 = _mm_loadu_si128((__m128i *)(zbin_boost_ptr - eob - 1)); - zbin_boost1 = _mm_loadu_si128((__m128i *)(zbin_boost_ptr - eob + 7)); - qcoeff[zig_zag_mask[eob]] = 0xffff; - } - - qcoeff0 = _mm_load_si128((__m128i *)(qcoeff)); - qcoeff1 = _mm_load_si128((__m128i *)(qcoeff + 8)); - qcoeff0 = _mm_and_si128(qcoeff0, y0); - qcoeff1 = _mm_and_si128(qcoeff1, y1); - - _mm_store_si128((__m128i *)(d->qcoeff), qcoeff0); - _mm_store_si128((__m128i *)(d->qcoeff + 8), qcoeff1); - - dqcoeff0 = _mm_mullo_epi16(qcoeff0, dequant0); - dqcoeff1 = _mm_mullo_epi16(qcoeff1, dequant1); - - _mm_store_si128((__m128i *)(d->dqcoeff), dqcoeff0); - _mm_store_si128((__m128i *)(d->dqcoeff + 8), dqcoeff1); - - *d->eob = eob + 1; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/temporal_filter_apply_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/temporal_filter_apply_sse2.asm deleted file mode 100644 index 67102064..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/temporal_filter_apply_sse2.asm +++ /dev/null @@ -1,209 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -SECTION .text - -; void vp8_temporal_filter_apply_sse2 | arg -; (unsigned char *frame1, | 0 -; unsigned int stride, | 1 -; unsigned char *frame2, | 2 -; unsigned int block_size, | 3 -; int strength, | 4 -; int filter_weight, | 5 -; unsigned int *accumulator, | 6 -; unsigned short *count) | 7 -globalsym(vp8_temporal_filter_apply_sse2) -sym(vp8_temporal_filter_apply_sse2): - - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 8 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ALIGN_STACK 16, rax - %define block_size 0 - %define strength 16 - %define filter_weight 32 - %define rounding_bit 48 - %define rbp_backup 64 - %define stack_size 80 - sub rsp, stack_size - mov [rsp + rbp_backup], rbp - ; end prolog - - mov rdx, arg(3) - mov [rsp + block_size], rdx - movd xmm6, arg(4) - movdqa [rsp + strength], xmm6 ; where strength is used, all 16 bytes are read - - ; calculate the rounding bit outside the loop - ; 0x8000 >> (16 - strength) - mov rdx, 16 - sub rdx, arg(4) ; 16 - strength - movq xmm4, rdx ; can't use rdx w/ shift - movdqa xmm5, [GLOBAL(_const_top_bit)] - psrlw xmm5, xmm4 - movdqa [rsp + rounding_bit], xmm5 - - mov rsi, arg(0) ; src/frame1 - mov rdx, arg(2) ; predictor frame - mov rdi, arg(6) ; accumulator - mov rax, arg(7) ; count - - ; dup the filter weight and store for later - movd xmm0, arg(5) ; filter_weight - pshuflw xmm0, xmm0, 0 - punpcklwd xmm0, xmm0 - movdqa [rsp + filter_weight], xmm0 - - mov rbp, arg(1) ; stride - pxor xmm7, xmm7 ; zero for extraction - - lea rcx, [rdx + 16*16*1] - cmp dword ptr [rsp + block_size], 8 - jne .temporal_filter_apply_load_16 - lea rcx, [rdx + 8*8*1] - -.temporal_filter_apply_load_8: - movq xmm0, [rsi] ; first row - lea rsi, [rsi + rbp] ; += stride - punpcklbw xmm0, xmm7 ; src[ 0- 7] - movq xmm1, [rsi] ; second row - lea rsi, [rsi + rbp] ; += stride - punpcklbw xmm1, xmm7 ; src[ 8-15] - jmp .temporal_filter_apply_load_finished - -.temporal_filter_apply_load_16: - movdqa xmm0, [rsi] ; src (frame1) - lea rsi, [rsi + rbp] ; += stride - movdqa xmm1, xmm0 - punpcklbw xmm0, xmm7 ; src[ 0- 7] - punpckhbw xmm1, xmm7 ; src[ 8-15] - -.temporal_filter_apply_load_finished: - movdqa xmm2, [rdx] ; predictor (frame2) - movdqa xmm3, xmm2 - punpcklbw xmm2, xmm7 ; pred[ 0- 7] - punpckhbw xmm3, xmm7 ; pred[ 8-15] - - ; modifier = src_byte - pixel_value - psubw xmm0, xmm2 ; src - pred[ 0- 7] - psubw xmm1, xmm3 ; src - pred[ 8-15] - - ; modifier *= modifier - pmullw xmm0, xmm0 ; modifer[ 0- 7]^2 - pmullw xmm1, xmm1 ; modifer[ 8-15]^2 - - ; modifier *= 3 - pmullw xmm0, [GLOBAL(_const_3w)] - pmullw xmm1, [GLOBAL(_const_3w)] - - ; modifer += 0x8000 >> (16 - strength) - paddw xmm0, [rsp + rounding_bit] - paddw xmm1, [rsp + rounding_bit] - - ; modifier >>= strength - psrlw xmm0, [rsp + strength] - psrlw xmm1, [rsp + strength] - - ; modifier = 16 - modifier - ; saturation takes care of modifier > 16 - movdqa xmm3, [GLOBAL(_const_16w)] - movdqa xmm2, [GLOBAL(_const_16w)] - psubusw xmm3, xmm1 - psubusw xmm2, xmm0 - - ; modifier *= filter_weight - pmullw xmm2, [rsp + filter_weight] - pmullw xmm3, [rsp + filter_weight] - - ; count - movdqa xmm4, [rax] - movdqa xmm5, [rax+16] - ; += modifier - paddw xmm4, xmm2 - paddw xmm5, xmm3 - ; write back - movdqa [rax], xmm4 - movdqa [rax+16], xmm5 - lea rax, [rax + 16*2] ; count += 16*(sizeof(short)) - - ; load and extract the predictor up to shorts - pxor xmm7, xmm7 - movdqa xmm0, [rdx] - lea rdx, [rdx + 16*1] ; pred += 16*(sizeof(char)) - movdqa xmm1, xmm0 - punpcklbw xmm0, xmm7 ; pred[ 0- 7] - punpckhbw xmm1, xmm7 ; pred[ 8-15] - - ; modifier *= pixel_value - pmullw xmm0, xmm2 - pmullw xmm1, xmm3 - - ; expand to double words - movdqa xmm2, xmm0 - punpcklwd xmm0, xmm7 ; [ 0- 3] - punpckhwd xmm2, xmm7 ; [ 4- 7] - movdqa xmm3, xmm1 - punpcklwd xmm1, xmm7 ; [ 8-11] - punpckhwd xmm3, xmm7 ; [12-15] - - ; accumulator - movdqa xmm4, [rdi] - movdqa xmm5, [rdi+16] - movdqa xmm6, [rdi+32] - movdqa xmm7, [rdi+48] - ; += modifier - paddd xmm4, xmm0 - paddd xmm5, xmm2 - paddd xmm6, xmm1 - paddd xmm7, xmm3 - ; write back - movdqa [rdi], xmm4 - movdqa [rdi+16], xmm5 - movdqa [rdi+32], xmm6 - movdqa [rdi+48], xmm7 - lea rdi, [rdi + 16*4] ; accumulator += 16*(sizeof(int)) - - cmp rdx, rcx - je .temporal_filter_apply_epilog - pxor xmm7, xmm7 ; zero for extraction - cmp dword ptr [rsp + block_size], 16 - je .temporal_filter_apply_load_16 - jmp .temporal_filter_apply_load_8 - -.temporal_filter_apply_epilog: - ; begin epilog - mov rbp, [rsp + rbp_backup] - add rsp, stack_size - pop rsp - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -SECTION_RODATA -align 16 -_const_3w: - times 8 dw 3 -align 16 -_const_top_bit: - times 8 dw 1<<15 -align 16 -_const_16w: - times 8 dw 16 diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/vp8_enc_stubs_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/vp8_enc_stubs_sse2.c deleted file mode 100644 index d0752453..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/vp8_enc_stubs_sse2.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "vp8_rtcd.h" -#include "vpx_ports/x86.h" -#include "vp8/encoder/block.h" - -int vp8_mbblock_error_sse2_impl(short *coeff_ptr, short *dcoef_ptr, int dc); -int vp8_mbblock_error_sse2(MACROBLOCK *mb, int dc) { - short *coeff_ptr = mb->block[0].coeff; - short *dcoef_ptr = mb->e_mbd.block[0].dqcoeff; - return vp8_mbblock_error_sse2_impl(coeff_ptr, dcoef_ptr, dc); -} - -int vp8_mbuverror_sse2_impl(short *s_ptr, short *d_ptr); -int vp8_mbuverror_sse2(MACROBLOCK *mb) { - short *s_ptr = &mb->coeff[256]; - short *d_ptr = &mb->e_mbd.dqcoeff[256]; - return vp8_mbuverror_sse2_impl(s_ptr, d_ptr); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/vp8_quantize_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/vp8_quantize_sse2.c deleted file mode 100644 index 581d2565..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/vp8_quantize_sse2.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_config.h" -#include "vp8_rtcd.h" -#include "vpx_ports/x86.h" -#include "vpx_mem/vpx_mem.h" -#include "vp8/encoder/block.h" -#include "vp8/common/entropy.h" /* vp8_default_inv_zig_zag */ - -#include /* MMX */ -#include /* SSE */ -#include /* SSE2 */ - -#define SELECT_EOB(i, z) \ - do { \ - short boost = *zbin_boost_ptr; \ - int cmp = (x[z] < boost) | (y[z] == 0); \ - zbin_boost_ptr++; \ - if (cmp) break; \ - qcoeff_ptr[z] = y[z]; \ - eob = i; \ - zbin_boost_ptr = b->zrun_zbin_boost; \ - } while (0) - -void vp8_regular_quantize_b_sse2(BLOCK *b, BLOCKD *d) { - char eob = 0; - short *zbin_boost_ptr; - short *qcoeff_ptr = d->qcoeff; - DECLARE_ALIGNED(16, short, x[16]); - DECLARE_ALIGNED(16, short, y[16]); - - __m128i sz0, x0, sz1, x1, y0, y1, x_minus_zbin0, x_minus_zbin1; - __m128i quant_shift0 = _mm_load_si128((__m128i *)(b->quant_shift)); - __m128i quant_shift1 = _mm_load_si128((__m128i *)(b->quant_shift + 8)); - __m128i z0 = _mm_load_si128((__m128i *)(b->coeff)); - __m128i z1 = _mm_load_si128((__m128i *)(b->coeff + 8)); - __m128i zbin_extra = _mm_cvtsi32_si128(b->zbin_extra); - __m128i zbin0 = _mm_load_si128((__m128i *)(b->zbin)); - __m128i zbin1 = _mm_load_si128((__m128i *)(b->zbin + 8)); - __m128i round0 = _mm_load_si128((__m128i *)(b->round)); - __m128i round1 = _mm_load_si128((__m128i *)(b->round + 8)); - __m128i quant0 = _mm_load_si128((__m128i *)(b->quant)); - __m128i quant1 = _mm_load_si128((__m128i *)(b->quant + 8)); - __m128i dequant0 = _mm_load_si128((__m128i *)(d->dequant)); - __m128i dequant1 = _mm_load_si128((__m128i *)(d->dequant + 8)); - - memset(qcoeff_ptr, 0, 32); - - /* Duplicate to all lanes. */ - zbin_extra = _mm_shufflelo_epi16(zbin_extra, 0); - zbin_extra = _mm_unpacklo_epi16(zbin_extra, zbin_extra); - - /* Sign of z: z >> 15 */ - sz0 = _mm_srai_epi16(z0, 15); - sz1 = _mm_srai_epi16(z1, 15); - - /* x = abs(z): (z ^ sz) - sz */ - x0 = _mm_xor_si128(z0, sz0); - x1 = _mm_xor_si128(z1, sz1); - x0 = _mm_sub_epi16(x0, sz0); - x1 = _mm_sub_epi16(x1, sz1); - - /* zbin[] + zbin_extra */ - zbin0 = _mm_add_epi16(zbin0, zbin_extra); - zbin1 = _mm_add_epi16(zbin1, zbin_extra); - - /* In C x is compared to zbin where zbin = zbin[] + boost + extra. Rebalance - * the equation because boost is the only value which can change: - * x - (zbin[] + extra) >= boost */ - x_minus_zbin0 = _mm_sub_epi16(x0, zbin0); - x_minus_zbin1 = _mm_sub_epi16(x1, zbin1); - - _mm_store_si128((__m128i *)(x), x_minus_zbin0); - _mm_store_si128((__m128i *)(x + 8), x_minus_zbin1); - - /* All the remaining calculations are valid whether they are done now with - * simd or later inside the loop one at a time. */ - x0 = _mm_add_epi16(x0, round0); - x1 = _mm_add_epi16(x1, round1); - - y0 = _mm_mulhi_epi16(x0, quant0); - y1 = _mm_mulhi_epi16(x1, quant1); - - y0 = _mm_add_epi16(y0, x0); - y1 = _mm_add_epi16(y1, x1); - - /* Instead of shifting each value independently we convert the scaling - * factor with 1 << (16 - shift) so we can use multiply/return high half. */ - y0 = _mm_mulhi_epi16(y0, quant_shift0); - y1 = _mm_mulhi_epi16(y1, quant_shift1); - - /* Return the sign: (y ^ sz) - sz */ - y0 = _mm_xor_si128(y0, sz0); - y1 = _mm_xor_si128(y1, sz1); - y0 = _mm_sub_epi16(y0, sz0); - y1 = _mm_sub_epi16(y1, sz1); - - _mm_store_si128((__m128i *)(y), y0); - _mm_store_si128((__m128i *)(y + 8), y1); - - zbin_boost_ptr = b->zrun_zbin_boost; - - /* The loop gets unrolled anyway. Avoid the vp8_default_zig_zag1d lookup. */ - SELECT_EOB(1, 0); - SELECT_EOB(2, 1); - SELECT_EOB(3, 4); - SELECT_EOB(4, 8); - SELECT_EOB(5, 5); - SELECT_EOB(6, 2); - SELECT_EOB(7, 3); - SELECT_EOB(8, 6); - SELECT_EOB(9, 9); - SELECT_EOB(10, 12); - SELECT_EOB(11, 13); - SELECT_EOB(12, 10); - SELECT_EOB(13, 7); - SELECT_EOB(14, 11); - SELECT_EOB(15, 14); - SELECT_EOB(16, 15); - - y0 = _mm_load_si128((__m128i *)(d->qcoeff)); - y1 = _mm_load_si128((__m128i *)(d->qcoeff + 8)); - - /* dqcoeff = qcoeff * dequant */ - y0 = _mm_mullo_epi16(y0, dequant0); - y1 = _mm_mullo_epi16(y1, dequant1); - - _mm_store_si128((__m128i *)(d->dqcoeff), y0); - _mm_store_si128((__m128i *)(d->dqcoeff + 8), y1); - - *d->eob = eob; -} - -void vp8_fast_quantize_b_sse2(BLOCK *b, BLOCKD *d) { - __m128i z0 = _mm_load_si128((__m128i *)(b->coeff)); - __m128i z1 = _mm_load_si128((__m128i *)(b->coeff + 8)); - __m128i round0 = _mm_load_si128((__m128i *)(b->round)); - __m128i round1 = _mm_load_si128((__m128i *)(b->round + 8)); - __m128i quant_fast0 = _mm_load_si128((__m128i *)(b->quant_fast)); - __m128i quant_fast1 = _mm_load_si128((__m128i *)(b->quant_fast + 8)); - __m128i dequant0 = _mm_load_si128((__m128i *)(d->dequant)); - __m128i dequant1 = _mm_load_si128((__m128i *)(d->dequant + 8)); - __m128i inv_zig_zag0 = - _mm_load_si128((const __m128i *)(vp8_default_inv_zig_zag)); - __m128i inv_zig_zag1 = - _mm_load_si128((const __m128i *)(vp8_default_inv_zig_zag + 8)); - - __m128i sz0, sz1, x0, x1, y0, y1, xdq0, xdq1, zeros, ones; - - /* sign of z: z >> 15 */ - sz0 = _mm_srai_epi16(z0, 15); - sz1 = _mm_srai_epi16(z1, 15); - - /* x = abs(z): (z ^ sz) - sz */ - x0 = _mm_xor_si128(z0, sz0); - x1 = _mm_xor_si128(z1, sz1); - x0 = _mm_sub_epi16(x0, sz0); - x1 = _mm_sub_epi16(x1, sz1); - - /* x += round */ - x0 = _mm_add_epi16(x0, round0); - x1 = _mm_add_epi16(x1, round1); - - /* y = (x * quant) >> 16 */ - y0 = _mm_mulhi_epi16(x0, quant_fast0); - y1 = _mm_mulhi_epi16(x1, quant_fast1); - - /* x = abs(y) = (y ^ sz) - sz */ - y0 = _mm_xor_si128(y0, sz0); - y1 = _mm_xor_si128(y1, sz1); - x0 = _mm_sub_epi16(y0, sz0); - x1 = _mm_sub_epi16(y1, sz1); - - /* qcoeff = x */ - _mm_store_si128((__m128i *)(d->qcoeff), x0); - _mm_store_si128((__m128i *)(d->qcoeff + 8), x1); - - /* x * dequant */ - xdq0 = _mm_mullo_epi16(x0, dequant0); - xdq1 = _mm_mullo_epi16(x1, dequant1); - - /* dqcoeff = x * dequant */ - _mm_store_si128((__m128i *)(d->dqcoeff), xdq0); - _mm_store_si128((__m128i *)(d->dqcoeff + 8), xdq1); - - /* build a mask for the zig zag */ - zeros = _mm_setzero_si128(); - - x0 = _mm_cmpeq_epi16(x0, zeros); - x1 = _mm_cmpeq_epi16(x1, zeros); - - ones = _mm_cmpeq_epi16(zeros, zeros); - - x0 = _mm_xor_si128(x0, ones); - x1 = _mm_xor_si128(x1, ones); - - x0 = _mm_and_si128(x0, inv_zig_zag0); - x1 = _mm_and_si128(x1, inv_zig_zag1); - - x0 = _mm_max_epi16(x0, x1); - - /* now down to 8 */ - x1 = _mm_shuffle_epi32(x0, 0xE); // 0b00001110 - - x0 = _mm_max_epi16(x0, x1); - - /* only 4 left */ - x1 = _mm_shufflelo_epi16(x0, 0xE); // 0b00001110 - - x0 = _mm_max_epi16(x0, x1); - - /* okay, just 2! */ - x1 = _mm_shufflelo_epi16(x0, 0x1); // 0b00000001 - - x0 = _mm_max_epi16(x0, x1); - - *d->eob = 0xFF & _mm_cvtsi128_si32(x0); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/vp8_quantize_ssse3.c b/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/vp8_quantize_ssse3.c deleted file mode 100644 index f6df146f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/encoder/x86/vp8_quantize_ssse3.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include /* SSSE3 */ - -#include "./vp8_rtcd.h" -#include "vp8/encoder/block.h" -#include "vpx_ports/bitops.h" /* get_msb */ - -void vp8_fast_quantize_b_ssse3(BLOCK *b, BLOCKD *d) { - int eob, mask; - - __m128i z0 = _mm_load_si128((__m128i *)(b->coeff)); - __m128i z1 = _mm_load_si128((__m128i *)(b->coeff + 8)); - __m128i round0 = _mm_load_si128((__m128i *)(b->round)); - __m128i round1 = _mm_load_si128((__m128i *)(b->round + 8)); - __m128i quant_fast0 = _mm_load_si128((__m128i *)(b->quant_fast)); - __m128i quant_fast1 = _mm_load_si128((__m128i *)(b->quant_fast + 8)); - __m128i dequant0 = _mm_load_si128((__m128i *)(d->dequant)); - __m128i dequant1 = _mm_load_si128((__m128i *)(d->dequant + 8)); - - __m128i sz0, sz1, x, x0, x1, y0, y1, zeros, abs0, abs1; - - DECLARE_ALIGNED(16, const uint8_t, - pshufb_zig_zag_mask[16]) = { 0, 1, 4, 8, 5, 2, 3, 6, - 9, 12, 13, 10, 7, 11, 14, 15 }; - __m128i zig_zag = _mm_load_si128((const __m128i *)pshufb_zig_zag_mask); - - /* sign of z: z >> 15 */ - sz0 = _mm_srai_epi16(z0, 15); - sz1 = _mm_srai_epi16(z1, 15); - - /* x = abs(z) */ - x0 = _mm_abs_epi16(z0); - x1 = _mm_abs_epi16(z1); - - /* x += round */ - x0 = _mm_add_epi16(x0, round0); - x1 = _mm_add_epi16(x1, round1); - - /* y = (x * quant) >> 16 */ - y0 = _mm_mulhi_epi16(x0, quant_fast0); - y1 = _mm_mulhi_epi16(x1, quant_fast1); - - /* ASM saves Y for EOB */ - /* I think we can ignore that because adding the sign doesn't change anything - * and multiplying 0 by dequant is OK as well */ - abs0 = y0; - abs1 = y1; - - /* Restore the sign bit. */ - y0 = _mm_xor_si128(y0, sz0); - y1 = _mm_xor_si128(y1, sz1); - x0 = _mm_sub_epi16(y0, sz0); - x1 = _mm_sub_epi16(y1, sz1); - - /* qcoeff = x */ - _mm_store_si128((__m128i *)(d->qcoeff), x0); - _mm_store_si128((__m128i *)(d->qcoeff + 8), x1); - - /* x * dequant */ - x0 = _mm_mullo_epi16(x0, dequant0); - x1 = _mm_mullo_epi16(x1, dequant1); - - /* dqcoeff = x * dequant */ - _mm_store_si128((__m128i *)(d->dqcoeff), x0); - _mm_store_si128((__m128i *)(d->dqcoeff + 8), x1); - - zeros = _mm_setzero_si128(); - - x0 = _mm_cmpgt_epi16(abs0, zeros); - x1 = _mm_cmpgt_epi16(abs1, zeros); - - x = _mm_packs_epi16(x0, x1); - - x = _mm_shuffle_epi8(x, zig_zag); - - mask = _mm_movemask_epi8(x); - - /* x2 is needed to increase the result from non-zero masks by 1, - * +1 is needed to mask undefined behavior for a null argument, - * the result of get_msb(1) is 0 */ - eob = get_msb(mask * 2 + 1); - - *d->eob = eob; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/exports_dec b/presentation/src/main/cpp/third_party/libvpx/vp8/exports_dec deleted file mode 100644 index 100ac5c2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/exports_dec +++ /dev/null @@ -1,2 +0,0 @@ -data vpx_codec_vp8_dx_algo -text vpx_codec_vp8_dx diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/exports_enc b/presentation/src/main/cpp/third_party/libvpx/vp8/exports_enc deleted file mode 100644 index 29ff35ef..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/exports_enc +++ /dev/null @@ -1,2 +0,0 @@ -data vpx_codec_vp8_cx_algo -text vpx_codec_vp8_cx diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/vp8_common.mk b/presentation/src/main/cpp/third_party/libvpx/vp8/vp8_common.mk deleted file mode 100644 index d485965d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/vp8_common.mk +++ /dev/null @@ -1,149 +0,0 @@ -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -VP8_COMMON_SRCS-yes += vp8_common.mk -VP8_COMMON_SRCS-yes += common/ppflags.h -VP8_COMMON_SRCS-yes += common/onyx.h -VP8_COMMON_SRCS-yes += common/onyxd.h -VP8_COMMON_SRCS-yes += common/alloccommon.c -VP8_COMMON_SRCS-yes += common/blockd.c -VP8_COMMON_SRCS-yes += common/coefupdateprobs.h -# VP8_COMMON_SRCS-yes += common/debugmodes.c -VP8_COMMON_SRCS-yes += common/default_coef_probs.h -VP8_COMMON_SRCS-yes += common/dequantize.c -VP8_COMMON_SRCS-yes += common/entropy.c -VP8_COMMON_SRCS-yes += common/entropymode.c -VP8_COMMON_SRCS-yes += common/entropymv.c -VP8_COMMON_SRCS-yes += common/extend.c -VP8_COMMON_SRCS-yes += common/filter.c -VP8_COMMON_SRCS-yes += common/filter.h -VP8_COMMON_SRCS-yes += common/findnearmv.c -VP8_COMMON_SRCS-yes += common/generic/systemdependent.c -VP8_COMMON_SRCS-yes += common/idct_blk.c -VP8_COMMON_SRCS-yes += common/idctllm.c -VP8_COMMON_SRCS-yes += common/alloccommon.h -VP8_COMMON_SRCS-yes += common/blockd.h -VP8_COMMON_SRCS-yes += common/common.h -VP8_COMMON_SRCS-yes += common/entropy.h -VP8_COMMON_SRCS-yes += common/entropymode.h -VP8_COMMON_SRCS-yes += common/entropymv.h -VP8_COMMON_SRCS-yes += common/extend.h -VP8_COMMON_SRCS-yes += common/findnearmv.h -VP8_COMMON_SRCS-yes += common/header.h -VP8_COMMON_SRCS-yes += common/invtrans.h -VP8_COMMON_SRCS-yes += common/loopfilter.h -VP8_COMMON_SRCS-yes += common/modecont.h -VP8_COMMON_SRCS-yes += common/mv.h -VP8_COMMON_SRCS-yes += common/onyxc_int.h -VP8_COMMON_SRCS-yes += common/quant_common.h -VP8_COMMON_SRCS-yes += common/reconinter.h -VP8_COMMON_SRCS-yes += common/reconintra.h -VP8_COMMON_SRCS-yes += common/reconintra4x4.h -VP8_COMMON_SRCS-yes += common/rtcd.c -VP8_COMMON_SRCS-yes += common/rtcd_defs.pl -VP8_COMMON_SRCS-yes += common/setupintrarecon.h -VP8_COMMON_SRCS-yes += common/swapyv12buffer.h -VP8_COMMON_SRCS-yes += common/systemdependent.h -VP8_COMMON_SRCS-yes += common/threading.h -VP8_COMMON_SRCS-yes += common/treecoder.h -VP8_COMMON_SRCS-yes += common/vp8_loopfilter.c -VP8_COMMON_SRCS-yes += common/loopfilter_filters.c -VP8_COMMON_SRCS-yes += common/mbpitch.c -VP8_COMMON_SRCS-yes += common/modecont.c -VP8_COMMON_SRCS-yes += common/quant_common.c -VP8_COMMON_SRCS-yes += common/reconinter.c -VP8_COMMON_SRCS-yes += common/reconintra.c -VP8_COMMON_SRCS-yes += common/reconintra4x4.c -VP8_COMMON_SRCS-yes += common/setupintrarecon.c -VP8_COMMON_SRCS-yes += common/swapyv12buffer.c -VP8_COMMON_SRCS-yes += common/vp8_entropymodedata.h - - - -VP8_COMMON_SRCS-yes += common/treecoder.c - -VP8_COMMON_SRCS-$(VPX_ARCH_X86)$(VPX_ARCH_X86_64) += common/x86/vp8_asm_stubs.c -VP8_COMMON_SRCS-$(VPX_ARCH_X86)$(VPX_ARCH_X86_64) += common/x86/loopfilter_x86.c -VP8_COMMON_SRCS-$(CONFIG_POSTPROC) += common/mfqe.c -VP8_COMMON_SRCS-$(CONFIG_POSTPROC) += common/postproc.h -VP8_COMMON_SRCS-$(CONFIG_POSTPROC) += common/postproc.c -VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/dequantize_mmx.asm -VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/idct_blk_mmx.c -VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/idctllm_mmx.asm -VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/recon_mmx.asm -VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/subpixel_mmx.asm -VP8_COMMON_SRCS-$(HAVE_SSE2) += common/x86/idct_blk_sse2.c -VP8_COMMON_SRCS-$(HAVE_SSE2) += common/x86/idctllm_sse2.asm -VP8_COMMON_SRCS-$(HAVE_SSE2) += common/x86/recon_sse2.asm -VP8_COMMON_SRCS-$(HAVE_SSE2) += common/x86/bilinear_filter_sse2.c -VP8_COMMON_SRCS-$(HAVE_SSE2) += common/x86/subpixel_sse2.asm -VP8_COMMON_SRCS-$(HAVE_SSE2) += common/x86/loopfilter_sse2.asm -VP8_COMMON_SRCS-$(HAVE_SSE2) += common/x86/iwalsh_sse2.asm -VP8_COMMON_SRCS-$(HAVE_SSSE3) += common/x86/subpixel_ssse3.asm - -ifeq ($(CONFIG_POSTPROC),yes) -VP8_COMMON_SRCS-$(HAVE_SSE2) += common/x86/mfqe_sse2.asm -endif - -ifeq ($(VPX_ARCH_X86_64),yes) -VP8_COMMON_SRCS-$(HAVE_SSE2) += common/x86/loopfilter_block_sse2_x86_64.asm -endif - -# common (c) -VP8_COMMON_SRCS-$(HAVE_DSPR2) += common/mips/dspr2/idctllm_dspr2.c -VP8_COMMON_SRCS-$(HAVE_DSPR2) += common/mips/dspr2/filter_dspr2.c -VP8_COMMON_SRCS-$(HAVE_DSPR2) += common/mips/dspr2/vp8_loopfilter_filters_dspr2.c -VP8_COMMON_SRCS-$(HAVE_DSPR2) += common/mips/dspr2/reconinter_dspr2.c -VP8_COMMON_SRCS-$(HAVE_DSPR2) += common/mips/dspr2/idct_blk_dspr2.c -VP8_COMMON_SRCS-$(HAVE_DSPR2) += common/mips/dspr2/dequantize_dspr2.c - -# common (c) -VP8_COMMON_SRCS-$(HAVE_MSA) += common/mips/msa/bilinear_filter_msa.c -VP8_COMMON_SRCS-$(HAVE_MSA) += common/mips/msa/copymem_msa.c -VP8_COMMON_SRCS-$(HAVE_MSA) += common/mips/msa/idct_msa.c -VP8_COMMON_SRCS-$(HAVE_MSA) += common/mips/msa/loopfilter_filters_msa.c -VP8_COMMON_SRCS-$(HAVE_MSA) += common/mips/msa/sixtap_filter_msa.c -VP8_COMMON_SRCS-$(HAVE_MSA) += common/mips/msa/vp8_macros_msa.h - -# common (c) -VP8_COMMON_SRCS-$(HAVE_MMI) += common/mips/mmi/sixtap_filter_mmi.c -VP8_COMMON_SRCS-$(HAVE_MMI) += common/mips/mmi/loopfilter_filters_mmi.c -VP8_COMMON_SRCS-$(HAVE_MMI) += common/mips/mmi/idctllm_mmi.c -VP8_COMMON_SRCS-$(HAVE_MMI) += common/mips/mmi/dequantize_mmi.c -VP8_COMMON_SRCS-$(HAVE_MMI) += common/mips/mmi/copymem_mmi.c -VP8_COMMON_SRCS-$(HAVE_MMI) += common/mips/mmi/idct_blk_mmi.c - -ifeq ($(CONFIG_POSTPROC),yes) -VP8_COMMON_SRCS-$(HAVE_MSA) += common/mips/msa/mfqe_msa.c -endif - -# common (loongarch LSX intrinsics) -VP8_COMMON_SRCS-$(HAVE_LSX) += common/loongarch/loopfilter_filters_lsx.c -VP8_COMMON_SRCS-$(HAVE_LSX) += common/loongarch/sixtap_filter_lsx.c -VP8_COMMON_SRCS-$(HAVE_LSX) += common/loongarch/idct_lsx.c - -# common (neon intrinsics) -VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/loopfilter_arm.c -VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/loopfilter_arm.h -VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/bilinearpredict_neon.c -VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/copymem_neon.c -VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/dc_only_idct_add_neon.c -VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/dequant_idct_neon.c -VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/dequantizeb_neon.c -VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/idct_blk_neon.c -VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/iwalsh_neon.c -VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp8_loopfilter_neon.c -VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/loopfiltersimplehorizontaledge_neon.c -VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/loopfiltersimpleverticaledge_neon.c -VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/mbloopfilter_neon.c -VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/shortidct4x4llm_neon.c -VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/sixtappredict_neon.c - -$(eval $(call rtcd_h_template,vp8_rtcd,vp8/common/rtcd_defs.pl)) diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/vp8_cx_iface.c b/presentation/src/main/cpp/third_party/libvpx/vp8/vp8_cx_iface.c deleted file mode 100644 index 35c94fb0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/vp8_cx_iface.c +++ /dev/null @@ -1,1435 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "./vpx_config.h" -#include "./vp8_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "./vpx_scale_rtcd.h" -#include "vpx/vpx_encoder.h" -#include "vpx/internal/vpx_codec_internal.h" -#include "vpx_version.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/static_assert.h" -#include "vpx_ports/system_state.h" -#include "vpx_util/vpx_timestamp.h" -#if CONFIG_MULTITHREAD -#include "vp8/encoder/ethreading.h" -#endif -#include "vp8/encoder/onyx_int.h" -#include "vpx/vp8cx.h" -#include "vp8/encoder/firstpass.h" -#include "vp8/common/onyx.h" -#include "vp8/common/common.h" - -struct vp8_extracfg { - struct vpx_codec_pkt_list *pkt_list; - int cpu_used; /** available cpu percentage in 1/16*/ - /** if encoder decides to uses alternate reference frame */ - unsigned int enable_auto_alt_ref; - unsigned int noise_sensitivity; - unsigned int Sharpness; - unsigned int static_thresh; - unsigned int token_partitions; - unsigned int arnr_max_frames; /* alt_ref Noise Reduction Max Frame Count */ - unsigned int arnr_strength; /* alt_ref Noise Reduction Strength */ - unsigned int arnr_type; /* alt_ref filter type */ - vp8e_tuning tuning; - unsigned int cq_level; /* constrained quality level */ - unsigned int rc_max_intra_bitrate_pct; - unsigned int gf_cbr_boost_pct; - unsigned int screen_content_mode; -}; - -static struct vp8_extracfg default_extracfg = { - NULL, -#if !(CONFIG_REALTIME_ONLY) - 0, /* cpu_used */ -#else - 4, /* cpu_used */ -#endif - 0, /* enable_auto_alt_ref */ - 0, /* noise_sensitivity */ - 0, /* Sharpness */ - 0, /* static_thresh */ -#if (CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING) - VP8_EIGHT_TOKENPARTITION, -#else - VP8_ONE_TOKENPARTITION, /* token_partitions */ -#endif - 0, /* arnr_max_frames */ - 3, /* arnr_strength */ - 3, /* arnr_type*/ - 0, /* tuning*/ - 10, /* cq_level */ - 0, /* rc_max_intra_bitrate_pct */ - 0, /* gf_cbr_boost_pct */ - 0, /* screen_content_mode */ -}; - -struct vpx_codec_alg_priv { - vpx_codec_priv_t base; - vpx_codec_enc_cfg_t cfg; - struct vp8_extracfg vp8_cfg; - vpx_rational64_t timestamp_ratio; - vpx_codec_pts_t pts_offset; - unsigned char pts_offset_initialized; - VP8_CONFIG oxcf; - struct VP8_COMP *cpi; - unsigned char *cx_data; - unsigned int cx_data_sz; - vpx_image_t preview_img; - unsigned int next_frame_flag; - vp8_postproc_cfg_t preview_ppcfg; - /* pkt_list size depends on the maximum number of lagged frames allowed. */ - vpx_codec_pkt_list_decl(64) pkt_list; - unsigned int fixed_kf_cntr; - vpx_enc_frame_flags_t control_frame_flags; -}; - -// Called by vp8e_set_config() and vp8e_encode() only. Must not be called -// by vp8e_init() because the `error` paramerer (cpi->common.error) will be -// destroyed by vpx_codec_enc_init_ver() after vp8e_init() returns an error. -// See the "IMPORTANT" comment in vpx_codec_enc_init_ver(). -static vpx_codec_err_t update_error_state( - vpx_codec_alg_priv_t *ctx, const struct vpx_internal_error_info *error) { - const vpx_codec_err_t res = error->error_code; - - if (res != VPX_CODEC_OK) - ctx->base.err_detail = error->has_detail ? error->detail : NULL; - - return res; -} - -#undef ERROR -#define ERROR(str) \ - do { \ - ctx->base.err_detail = str; \ - return VPX_CODEC_INVALID_PARAM; \ - } while (0) - -#define RANGE_CHECK(p, memb, lo, hi) \ - do { \ - if (!(((p)->memb == (lo) || (p)->memb > (lo)) && (p)->memb <= (hi))) \ - ERROR(#memb " out of range [" #lo ".." #hi "]"); \ - } while (0) - -#define RANGE_CHECK_HI(p, memb, hi) \ - do { \ - if (!((p)->memb <= (hi))) ERROR(#memb " out of range [.." #hi "]"); \ - } while (0) - -#define RANGE_CHECK_LO(p, memb, lo) \ - do { \ - if (!((p)->memb >= (lo))) ERROR(#memb " out of range [" #lo "..]"); \ - } while (0) - -#define RANGE_CHECK_BOOL(p, memb) \ - do { \ - if (!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean"); \ - } while (0) - -static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, - const vpx_codec_enc_cfg_t *cfg, - const struct vp8_extracfg *vp8_cfg, - int finalize) { - RANGE_CHECK(cfg, g_w, 1, 16383); /* 14 bits available */ - RANGE_CHECK(cfg, g_h, 1, 16383); /* 14 bits available */ - RANGE_CHECK(cfg, g_timebase.den, 1, 1000000000); - RANGE_CHECK(cfg, g_timebase.num, 1, 1000000000); - RANGE_CHECK_HI(cfg, g_profile, 3); - RANGE_CHECK_HI(cfg, rc_max_quantizer, 63); - RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer); - RANGE_CHECK_HI(cfg, g_threads, 64); -#if CONFIG_REALTIME_ONLY - RANGE_CHECK_HI(cfg, g_lag_in_frames, 0); -#elif CONFIG_MULTI_RES_ENCODING - if (ctx->base.enc.total_encoders > 1) RANGE_CHECK_HI(cfg, g_lag_in_frames, 0); -#else - RANGE_CHECK_HI(cfg, g_lag_in_frames, 25); -#endif - RANGE_CHECK(cfg, rc_end_usage, VPX_VBR, VPX_Q); - RANGE_CHECK_HI(cfg, rc_undershoot_pct, 100); - RANGE_CHECK_HI(cfg, rc_overshoot_pct, 100); - RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100); - RANGE_CHECK(cfg, kf_mode, VPX_KF_DISABLED, VPX_KF_AUTO); - -/* TODO: add spatial re-sampling support and frame dropping in - * multi-res-encoder.*/ -#if CONFIG_MULTI_RES_ENCODING - if (ctx->base.enc.total_encoders > 1) - RANGE_CHECK_HI(cfg, rc_resize_allowed, 0); -#else - RANGE_CHECK_BOOL(cfg, rc_resize_allowed); -#endif - RANGE_CHECK_HI(cfg, rc_dropframe_thresh, 100); - RANGE_CHECK_HI(cfg, rc_resize_up_thresh, 100); - RANGE_CHECK_HI(cfg, rc_resize_down_thresh, 100); - -#if CONFIG_REALTIME_ONLY - RANGE_CHECK(cfg, g_pass, VPX_RC_ONE_PASS, VPX_RC_ONE_PASS); -#elif CONFIG_MULTI_RES_ENCODING - if (ctx->base.enc.total_encoders > 1) - RANGE_CHECK(cfg, g_pass, VPX_RC_ONE_PASS, VPX_RC_ONE_PASS); -#else - RANGE_CHECK(cfg, g_pass, VPX_RC_ONE_PASS, VPX_RC_LAST_PASS); -#endif - - /* VP8 does not support a lower bound on the keyframe interval in - * automatic keyframe placement mode. - */ - if (cfg->kf_mode != VPX_KF_DISABLED && cfg->kf_min_dist != cfg->kf_max_dist && - cfg->kf_min_dist > 0) - ERROR( - "kf_min_dist not supported in auto mode, use 0 " - "or kf_max_dist instead."); - - RANGE_CHECK_BOOL(vp8_cfg, enable_auto_alt_ref); - RANGE_CHECK(vp8_cfg, cpu_used, -16, 16); - -#if CONFIG_REALTIME_ONLY && !CONFIG_TEMPORAL_DENOISING - RANGE_CHECK(vp8_cfg, noise_sensitivity, 0, 0); -#else - RANGE_CHECK_HI(vp8_cfg, noise_sensitivity, 6); -#endif - - RANGE_CHECK(vp8_cfg, token_partitions, VP8_ONE_TOKENPARTITION, - VP8_EIGHT_TOKENPARTITION); - RANGE_CHECK_HI(vp8_cfg, Sharpness, 7); - RANGE_CHECK(vp8_cfg, arnr_max_frames, 0, 15); - RANGE_CHECK_HI(vp8_cfg, arnr_strength, 6); - RANGE_CHECK(vp8_cfg, arnr_type, 1, 3); - RANGE_CHECK(vp8_cfg, cq_level, 0, 63); - RANGE_CHECK_HI(vp8_cfg, screen_content_mode, 2); - if (finalize && (cfg->rc_end_usage == VPX_CQ || cfg->rc_end_usage == VPX_Q)) - RANGE_CHECK(vp8_cfg, cq_level, cfg->rc_min_quantizer, - cfg->rc_max_quantizer); - -#if !(CONFIG_REALTIME_ONLY) - if (cfg->g_pass == VPX_RC_LAST_PASS) { - size_t packet_sz = sizeof(FIRSTPASS_STATS); - int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz); - FIRSTPASS_STATS *stats; - - if (!cfg->rc_twopass_stats_in.buf) - ERROR("rc_twopass_stats_in.buf not set."); - - if (cfg->rc_twopass_stats_in.sz % packet_sz) - ERROR("rc_twopass_stats_in.sz indicates truncated packet."); - - if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz) - ERROR("rc_twopass_stats_in requires at least two packets."); - - stats = (void *)((char *)cfg->rc_twopass_stats_in.buf + - (n_packets - 1) * packet_sz); - - if ((int)(stats->count + 0.5) != n_packets - 1) - ERROR("rc_twopass_stats_in missing EOS stats packet"); - } -#endif - - RANGE_CHECK(cfg, ts_number_layers, 1, 5); - - if (cfg->ts_number_layers > 1) { - unsigned int i; - RANGE_CHECK_HI(cfg, ts_periodicity, 16); - - for (i = 1; i < cfg->ts_number_layers; ++i) { - if (cfg->ts_target_bitrate[i] <= cfg->ts_target_bitrate[i - 1] && - cfg->rc_target_bitrate > 0) - ERROR("ts_target_bitrate entries are not strictly increasing"); - } - - RANGE_CHECK(cfg, ts_rate_decimator[cfg->ts_number_layers - 1], 1, 1); - for (i = cfg->ts_number_layers - 2; i > 0; i--) { - if (cfg->ts_rate_decimator[i - 1] != 2 * cfg->ts_rate_decimator[i]) - ERROR("ts_rate_decimator factors are not powers of 2"); - } - - RANGE_CHECK_HI(cfg, ts_layer_id[i], cfg->ts_number_layers - 1); - } - -#if (CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING) - if (cfg->g_threads > (1 << vp8_cfg->token_partitions)) - ERROR("g_threads cannot be bigger than number of token partitions"); -#endif - - // The range below shall be further tuned. - RANGE_CHECK(cfg, use_vizier_rc_params, 0, 1); - RANGE_CHECK(cfg, active_wq_factor.den, 1, 1000); - RANGE_CHECK(cfg, err_per_mb_factor.den, 1, 1000); - RANGE_CHECK(cfg, sr_default_decay_limit.den, 1, 1000); - RANGE_CHECK(cfg, sr_diff_factor.den, 1, 1000); - RANGE_CHECK(cfg, kf_err_per_mb_factor.den, 1, 1000); - RANGE_CHECK(cfg, kf_frame_min_boost_factor.den, 1, 1000); - RANGE_CHECK(cfg, kf_frame_max_boost_subs_factor.den, 1, 1000); - RANGE_CHECK(cfg, kf_max_total_boost_factor.den, 1, 1000); - RANGE_CHECK(cfg, gf_max_total_boost_factor.den, 1, 1000); - RANGE_CHECK(cfg, gf_frame_max_boost_factor.den, 1, 1000); - RANGE_CHECK(cfg, zm_factor.den, 1, 1000); - RANGE_CHECK(cfg, rd_mult_inter_qp_fac.den, 1, 1000); - RANGE_CHECK(cfg, rd_mult_arf_qp_fac.den, 1, 1000); - RANGE_CHECK(cfg, rd_mult_key_qp_fac.den, 1, 1000); - - return VPX_CODEC_OK; -} - -static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx, - const vpx_image_t *img) { - switch (img->fmt) { - case VPX_IMG_FMT_YV12: - case VPX_IMG_FMT_I420: - case VPX_IMG_FMT_NV12: break; - default: - ERROR( - "Invalid image format. Only YV12, I420 and NV12 images are " - "supported"); - } - - if ((img->d_w != ctx->cfg.g_w) || (img->d_h != ctx->cfg.g_h)) - ERROR("Image size must match encoder init configuration size"); - - return VPX_CODEC_OK; -} - -static vpx_codec_err_t set_vp8e_config(VP8_CONFIG *oxcf, - vpx_codec_enc_cfg_t cfg, - struct vp8_extracfg vp8_cfg, - vpx_codec_priv_enc_mr_cfg_t *mr_cfg) { - oxcf->multi_threaded = cfg.g_threads; - oxcf->Version = cfg.g_profile; - - oxcf->Width = cfg.g_w; - oxcf->Height = cfg.g_h; - oxcf->timebase = cfg.g_timebase; - - oxcf->error_resilient_mode = cfg.g_error_resilient; - - switch (cfg.g_pass) { - case VPX_RC_ONE_PASS: oxcf->Mode = MODE_BESTQUALITY; break; - case VPX_RC_FIRST_PASS: oxcf->Mode = MODE_FIRSTPASS; break; - case VPX_RC_LAST_PASS: oxcf->Mode = MODE_SECONDPASS_BEST; break; - } - - if (cfg.g_pass == VPX_RC_FIRST_PASS || cfg.g_pass == VPX_RC_ONE_PASS) { - oxcf->allow_lag = 0; - oxcf->lag_in_frames = 0; - } else { - oxcf->allow_lag = (cfg.g_lag_in_frames) > 0; - oxcf->lag_in_frames = cfg.g_lag_in_frames; - } - - oxcf->allow_df = (cfg.rc_dropframe_thresh > 0); - oxcf->drop_frames_water_mark = cfg.rc_dropframe_thresh; - - oxcf->allow_spatial_resampling = cfg.rc_resize_allowed; - oxcf->resample_up_water_mark = cfg.rc_resize_up_thresh; - oxcf->resample_down_water_mark = cfg.rc_resize_down_thresh; - - if (cfg.rc_end_usage == VPX_VBR) { - oxcf->end_usage = USAGE_LOCAL_FILE_PLAYBACK; - } else if (cfg.rc_end_usage == VPX_CBR) { - oxcf->end_usage = USAGE_STREAM_FROM_SERVER; - } else if (cfg.rc_end_usage == VPX_CQ) { - oxcf->end_usage = USAGE_CONSTRAINED_QUALITY; - } else if (cfg.rc_end_usage == VPX_Q) { - oxcf->end_usage = USAGE_CONSTANT_QUALITY; - } - - // Cap the target rate to 1000 Mbps to avoid some integer overflows in - // target bandwidth calculations. - oxcf->target_bandwidth = VPXMIN(cfg.rc_target_bitrate, 1000000); - oxcf->rc_max_intra_bitrate_pct = vp8_cfg.rc_max_intra_bitrate_pct; - oxcf->gf_cbr_boost_pct = vp8_cfg.gf_cbr_boost_pct; - - oxcf->best_allowed_q = cfg.rc_min_quantizer; - oxcf->worst_allowed_q = cfg.rc_max_quantizer; - oxcf->cq_level = vp8_cfg.cq_level; - oxcf->fixed_q = -1; - - oxcf->under_shoot_pct = cfg.rc_undershoot_pct; - oxcf->over_shoot_pct = cfg.rc_overshoot_pct; - - oxcf->maximum_buffer_size_in_ms = cfg.rc_buf_sz; - oxcf->starting_buffer_level_in_ms = cfg.rc_buf_initial_sz; - oxcf->optimal_buffer_level_in_ms = cfg.rc_buf_optimal_sz; - - oxcf->maximum_buffer_size = cfg.rc_buf_sz; - oxcf->starting_buffer_level = cfg.rc_buf_initial_sz; - oxcf->optimal_buffer_level = cfg.rc_buf_optimal_sz; - - oxcf->two_pass_vbrbias = cfg.rc_2pass_vbr_bias_pct; - oxcf->two_pass_vbrmin_section = cfg.rc_2pass_vbr_minsection_pct; - oxcf->two_pass_vbrmax_section = cfg.rc_2pass_vbr_maxsection_pct; - - oxcf->auto_key = - cfg.kf_mode == VPX_KF_AUTO && cfg.kf_min_dist != cfg.kf_max_dist; - oxcf->key_freq = cfg.kf_max_dist; - - oxcf->number_of_layers = cfg.ts_number_layers; - oxcf->periodicity = cfg.ts_periodicity; - - if (oxcf->number_of_layers > 1) { - memcpy(oxcf->target_bitrate, cfg.ts_target_bitrate, - sizeof(cfg.ts_target_bitrate)); - memcpy(oxcf->rate_decimator, cfg.ts_rate_decimator, - sizeof(cfg.ts_rate_decimator)); - memcpy(oxcf->layer_id, cfg.ts_layer_id, sizeof(cfg.ts_layer_id)); - } - -#if CONFIG_MULTI_RES_ENCODING - /* When mr_cfg is NULL, oxcf->mr_total_resolutions and oxcf->mr_encoder_id - * are both memset to 0, which ensures the correct logic under this - * situation. - */ - if (mr_cfg) { - oxcf->mr_total_resolutions = mr_cfg->mr_total_resolutions; - oxcf->mr_encoder_id = mr_cfg->mr_encoder_id; - oxcf->mr_down_sampling_factor.num = mr_cfg->mr_down_sampling_factor.num; - oxcf->mr_down_sampling_factor.den = mr_cfg->mr_down_sampling_factor.den; - oxcf->mr_low_res_mode_info = mr_cfg->mr_low_res_mode_info; - } -#else - (void)mr_cfg; -#endif - - oxcf->cpu_used = vp8_cfg.cpu_used; - if (cfg.g_pass == VPX_RC_FIRST_PASS) { - oxcf->cpu_used = VPXMAX(4, oxcf->cpu_used); - } - oxcf->encode_breakout = vp8_cfg.static_thresh; - oxcf->play_alternate = vp8_cfg.enable_auto_alt_ref; - oxcf->noise_sensitivity = vp8_cfg.noise_sensitivity; - oxcf->Sharpness = vp8_cfg.Sharpness; - oxcf->token_partitions = vp8_cfg.token_partitions; - - oxcf->two_pass_stats_in = cfg.rc_twopass_stats_in; - oxcf->output_pkt_list = vp8_cfg.pkt_list; - - oxcf->arnr_max_frames = vp8_cfg.arnr_max_frames; - oxcf->arnr_strength = vp8_cfg.arnr_strength; - oxcf->arnr_type = vp8_cfg.arnr_type; - - oxcf->tuning = vp8_cfg.tuning; - - oxcf->screen_content_mode = vp8_cfg.screen_content_mode; - - /* - printf("Current VP8 Settings: \n"); - printf("target_bandwidth: %d\n", oxcf->target_bandwidth); - printf("noise_sensitivity: %d\n", oxcf->noise_sensitivity); - printf("Sharpness: %d\n", oxcf->Sharpness); - printf("cpu_used: %d\n", oxcf->cpu_used); - printf("Mode: %d\n", oxcf->Mode); - printf("auto_key: %d\n", oxcf->auto_key); - printf("key_freq: %d\n", oxcf->key_freq); - printf("end_usage: %d\n", oxcf->end_usage); - printf("under_shoot_pct: %d\n", oxcf->under_shoot_pct); - printf("over_shoot_pct: %d\n", oxcf->over_shoot_pct); - printf("starting_buffer_level: %d\n", oxcf->starting_buffer_level); - printf("optimal_buffer_level: %d\n", oxcf->optimal_buffer_level); - printf("maximum_buffer_size: %d\n", oxcf->maximum_buffer_size); - printf("fixed_q: %d\n", oxcf->fixed_q); - printf("worst_allowed_q: %d\n", oxcf->worst_allowed_q); - printf("best_allowed_q: %d\n", oxcf->best_allowed_q); - printf("allow_spatial_resampling: %d\n", oxcf->allow_spatial_resampling); - printf("resample_down_water_mark: %d\n", oxcf->resample_down_water_mark); - printf("resample_up_water_mark: %d\n", oxcf->resample_up_water_mark); - printf("allow_df: %d\n", oxcf->allow_df); - printf("drop_frames_water_mark: %d\n", oxcf->drop_frames_water_mark); - printf("two_pass_vbrbias: %d\n", oxcf->two_pass_vbrbias); - printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section); - printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section); - printf("allow_lag: %d\n", oxcf->allow_lag); - printf("lag_in_frames: %d\n", oxcf->lag_in_frames); - printf("play_alternate: %d\n", oxcf->play_alternate); - printf("Version: %d\n", oxcf->Version); - printf("multi_threaded: %d\n", oxcf->multi_threaded); - printf("encode_breakout: %d\n", oxcf->encode_breakout); - */ - return VPX_CODEC_OK; -} - -static vpx_codec_err_t vp8e_set_config(vpx_codec_alg_priv_t *ctx, - const vpx_codec_enc_cfg_t *cfg) { - vpx_codec_err_t res; - - if (cfg->g_w != ctx->cfg.g_w || cfg->g_h != ctx->cfg.g_h) { - if (cfg->g_lag_in_frames > 1 || cfg->g_pass != VPX_RC_ONE_PASS) - ERROR("Cannot change width or height after initialization"); - if ((ctx->cpi->initial_width && (int)cfg->g_w > ctx->cpi->initial_width) || - (ctx->cpi->initial_height && (int)cfg->g_h > ctx->cpi->initial_height)) - ERROR("Cannot increase width or height larger than their initial values"); - } - - /* Prevent increasing lag_in_frames. This check is stricter than it needs - * to be -- the limit is not increasing past the first lag_in_frames - * value, but we don't track the initial config, only the last successful - * config. - */ - if ((cfg->g_lag_in_frames > ctx->cfg.g_lag_in_frames)) - ERROR("Cannot increase lag_in_frames"); - - res = validate_config(ctx, cfg, &ctx->vp8_cfg, 0); - if (res != VPX_CODEC_OK) return res; - - if (setjmp(ctx->cpi->common.error.jmp)) { - const vpx_codec_err_t codec_err = - update_error_state(ctx, &ctx->cpi->common.error); - ctx->cpi->common.error.setjmp = 0; - vpx_clear_system_state(); - assert(codec_err != VPX_CODEC_OK); - return codec_err; - } - - ctx->cpi->common.error.setjmp = 1; - ctx->cfg = *cfg; - set_vp8e_config(&ctx->oxcf, ctx->cfg, ctx->vp8_cfg, NULL); - vp8_change_config(ctx->cpi, &ctx->oxcf); -#if CONFIG_MULTITHREAD - if (vp8cx_create_encoder_threads(ctx->cpi)) { - ctx->cpi->common.error.setjmp = 0; - return VPX_CODEC_ERROR; - } -#endif - ctx->cpi->common.error.setjmp = 0; - return VPX_CODEC_OK; -} - -static vpx_codec_err_t get_quantizer(vpx_codec_alg_priv_t *ctx, va_list args) { - int *const arg = va_arg(args, int *); - if (arg == NULL) return VPX_CODEC_INVALID_PARAM; - *arg = vp8_get_quantizer(ctx->cpi); - return VPX_CODEC_OK; -} - -static vpx_codec_err_t get_quantizer64(vpx_codec_alg_priv_t *ctx, - va_list args) { - int *const arg = va_arg(args, int *); - if (arg == NULL) return VPX_CODEC_INVALID_PARAM; - *arg = vp8_reverse_trans(vp8_get_quantizer(ctx->cpi)); - return VPX_CODEC_OK; -} - -static vpx_codec_err_t update_extracfg(vpx_codec_alg_priv_t *ctx, - const struct vp8_extracfg *extra_cfg) { - const vpx_codec_err_t res = validate_config(ctx, &ctx->cfg, extra_cfg, 0); - if (res == VPX_CODEC_OK) { - ctx->vp8_cfg = *extra_cfg; - set_vp8e_config(&ctx->oxcf, ctx->cfg, ctx->vp8_cfg, NULL); - vp8_change_config(ctx->cpi, &ctx->oxcf); - } - return res; -} - -static vpx_codec_err_t set_cpu_used(vpx_codec_alg_priv_t *ctx, va_list args) { - struct vp8_extracfg extra_cfg = ctx->vp8_cfg; - extra_cfg.cpu_used = CAST(VP8E_SET_CPUUSED, args); - // Use fastest speed setting (speed 16 or -16) if it's set beyond the range. - extra_cfg.cpu_used = VPXMIN(16, extra_cfg.cpu_used); - extra_cfg.cpu_used = VPXMAX(-16, extra_cfg.cpu_used); - return update_extracfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t set_enable_auto_alt_ref(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp8_extracfg extra_cfg = ctx->vp8_cfg; - extra_cfg.enable_auto_alt_ref = CAST(VP8E_SET_ENABLEAUTOALTREF, args); - return update_extracfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t set_noise_sensitivity(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp8_extracfg extra_cfg = ctx->vp8_cfg; - extra_cfg.noise_sensitivity = CAST(VP8E_SET_NOISE_SENSITIVITY, args); - return update_extracfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t set_sharpness(vpx_codec_alg_priv_t *ctx, va_list args) { - struct vp8_extracfg extra_cfg = ctx->vp8_cfg; - extra_cfg.Sharpness = CAST(VP8E_SET_SHARPNESS, args); - return update_extracfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t set_static_thresh(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp8_extracfg extra_cfg = ctx->vp8_cfg; - extra_cfg.static_thresh = CAST(VP8E_SET_STATIC_THRESHOLD, args); - return update_extracfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t set_token_partitions(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp8_extracfg extra_cfg = ctx->vp8_cfg; - extra_cfg.token_partitions = CAST(VP8E_SET_TOKEN_PARTITIONS, args); - return update_extracfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t set_arnr_max_frames(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp8_extracfg extra_cfg = ctx->vp8_cfg; - extra_cfg.arnr_max_frames = CAST(VP8E_SET_ARNR_MAXFRAMES, args); - return update_extracfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t set_arnr_strength(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp8_extracfg extra_cfg = ctx->vp8_cfg; - extra_cfg.arnr_strength = CAST(VP8E_SET_ARNR_STRENGTH, args); - return update_extracfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t set_arnr_type(vpx_codec_alg_priv_t *ctx, va_list args) { - struct vp8_extracfg extra_cfg = ctx->vp8_cfg; - extra_cfg.arnr_type = CAST(VP8E_SET_ARNR_TYPE, args); - return update_extracfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t set_tuning(vpx_codec_alg_priv_t *ctx, va_list args) { - struct vp8_extracfg extra_cfg = ctx->vp8_cfg; - extra_cfg.tuning = CAST(VP8E_SET_TUNING, args); - return update_extracfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t set_cq_level(vpx_codec_alg_priv_t *ctx, va_list args) { - struct vp8_extracfg extra_cfg = ctx->vp8_cfg; - extra_cfg.cq_level = CAST(VP8E_SET_CQ_LEVEL, args); - return update_extracfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t set_rc_max_intra_bitrate_pct(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp8_extracfg extra_cfg = ctx->vp8_cfg; - extra_cfg.rc_max_intra_bitrate_pct = - CAST(VP8E_SET_MAX_INTRA_BITRATE_PCT, args); - return update_extracfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_rc_gf_cbr_boost_pct(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp8_extracfg extra_cfg = ctx->vp8_cfg; - extra_cfg.gf_cbr_boost_pct = CAST(VP8E_SET_GF_CBR_BOOST_PCT, args); - return update_extracfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t set_screen_content_mode(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp8_extracfg extra_cfg = ctx->vp8_cfg; - extra_cfg.screen_content_mode = CAST(VP8E_SET_SCREEN_CONTENT_MODE, args); - return update_extracfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_rtc_external_ratectrl(vpx_codec_alg_priv_t *ctx, - va_list args) { - VP8_COMP *cpi = ctx->cpi; - const unsigned int data = CAST(VP8E_SET_RTC_EXTERNAL_RATECTRL, args); - if (data) { - cpi->cyclic_refresh_mode_enabled = 0; - cpi->rt_always_update_correction_factor = 1; - cpi->rt_drop_recode_on_overshoot = 0; - } - return VPX_CODEC_OK; -} - -static vpx_codec_err_t vp8e_mr_alloc_mem(const vpx_codec_enc_cfg_t *cfg, - void **mem_loc) { - vpx_codec_err_t res = VPX_CODEC_OK; - -#if CONFIG_MULTI_RES_ENCODING - LOWER_RES_FRAME_INFO *shared_mem_loc; - int mb_rows = ((cfg->g_w + 15) >> 4); - int mb_cols = ((cfg->g_h + 15) >> 4); - - shared_mem_loc = calloc(1, sizeof(LOWER_RES_FRAME_INFO)); - if (!shared_mem_loc) { - return VPX_CODEC_MEM_ERROR; - } - - shared_mem_loc->mb_info = - calloc(mb_rows * mb_cols, sizeof(LOWER_RES_MB_INFO)); - if (!(shared_mem_loc->mb_info)) { - free(shared_mem_loc); - res = VPX_CODEC_MEM_ERROR; - } else { - *mem_loc = (void *)shared_mem_loc; - res = VPX_CODEC_OK; - } -#else - (void)cfg; - (void)mem_loc; -#endif - return res; -} - -static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx, - vpx_codec_priv_enc_mr_cfg_t *mr_cfg) { - vpx_codec_err_t res = VPX_CODEC_OK; - - vp8_rtcd(); - vpx_dsp_rtcd(); - vpx_scale_rtcd(); - - if (!ctx->priv) { - struct vpx_codec_alg_priv *priv = - (struct vpx_codec_alg_priv *)vpx_calloc(1, sizeof(*priv)); - - if (!priv) { - return VPX_CODEC_MEM_ERROR; - } - - ctx->priv = (vpx_codec_priv_t *)priv; - ctx->priv->init_flags = ctx->init_flags; - - if (ctx->config.enc) { - /* Update the reference to the config structure to an - * internal copy. - */ - priv->cfg = *ctx->config.enc; - ctx->config.enc = &priv->cfg; - } - - priv->vp8_cfg = default_extracfg; - priv->vp8_cfg.pkt_list = &priv->pkt_list.head; - - priv->cx_data_sz = priv->cfg.g_w * priv->cfg.g_h * 3 / 2 * 2; - - if (priv->cx_data_sz < 32768) priv->cx_data_sz = 32768; - - priv->cx_data = malloc(priv->cx_data_sz); - - if (!priv->cx_data) { - priv->cx_data_sz = 0; - return VPX_CODEC_MEM_ERROR; - } - - if (mr_cfg) { - ctx->priv->enc.total_encoders = mr_cfg->mr_total_resolutions; - } else { - ctx->priv->enc.total_encoders = 1; - } - - vp8_initialize_enc(); - - res = validate_config(priv, &priv->cfg, &priv->vp8_cfg, 0); - - if (!res) { - priv->pts_offset_initialized = 0; - priv->timestamp_ratio.den = priv->cfg.g_timebase.den; - priv->timestamp_ratio.num = (int64_t)priv->cfg.g_timebase.num; - priv->timestamp_ratio.num *= TICKS_PER_SEC; - reduce_ratio(&priv->timestamp_ratio); - - set_vp8e_config(&priv->oxcf, priv->cfg, priv->vp8_cfg, mr_cfg); - priv->cpi = vp8_create_compressor(&priv->oxcf); - if (!priv->cpi) { -#if CONFIG_MULTI_RES_ENCODING - // Release ownership of mr_cfg->mr_low_res_mode_info on failure. This - // prevents ownership confusion with the caller and avoids a double - // free when vpx_codec_destroy() is called on this instance. - priv->oxcf.mr_total_resolutions = 0; - priv->oxcf.mr_encoder_id = 0; - priv->oxcf.mr_low_res_mode_info = NULL; -#endif - res = VPX_CODEC_MEM_ERROR; - } - } - } - - return res; -} - -static vpx_codec_err_t vp8e_destroy(vpx_codec_alg_priv_t *ctx) { -#if CONFIG_MULTI_RES_ENCODING - /* Free multi-encoder shared memory */ - if (ctx->oxcf.mr_total_resolutions > 0 && - (ctx->oxcf.mr_encoder_id == ctx->oxcf.mr_total_resolutions - 1)) { - LOWER_RES_FRAME_INFO *shared_mem_loc = - (LOWER_RES_FRAME_INFO *)ctx->oxcf.mr_low_res_mode_info; - free(shared_mem_loc->mb_info); - free(ctx->oxcf.mr_low_res_mode_info); - } -#endif - - free(ctx->cx_data); - vp8_remove_compressor(&ctx->cpi); - vpx_free(ctx); - return VPX_CODEC_OK; -} - -static vpx_codec_err_t image2yuvconfig(const vpx_image_t *img, - YV12_BUFFER_CONFIG *yv12) { - const int y_w = img->d_w; - const int y_h = img->d_h; - const int uv_w = (img->d_w + 1) / 2; - const int uv_h = (img->d_h + 1) / 2; - vpx_codec_err_t res = VPX_CODEC_OK; - yv12->y_buffer = img->planes[VPX_PLANE_Y]; - yv12->u_buffer = img->planes[VPX_PLANE_U]; - yv12->v_buffer = img->planes[VPX_PLANE_V]; - - yv12->y_crop_width = y_w; - yv12->y_crop_height = y_h; - yv12->y_width = y_w; - yv12->y_height = y_h; - yv12->uv_crop_width = uv_w; - yv12->uv_crop_height = uv_h; - yv12->uv_width = uv_w; - yv12->uv_height = uv_h; - - yv12->y_stride = img->stride[VPX_PLANE_Y]; - yv12->uv_stride = img->stride[VPX_PLANE_U]; - - yv12->border = (img->stride[VPX_PLANE_Y] - img->w) / 2; - return res; -} - -static vpx_codec_err_t pick_quickcompress_mode(vpx_codec_alg_priv_t *ctx, - unsigned long duration, - vpx_enc_deadline_t deadline) { - int new_qc; - -#if !(CONFIG_REALTIME_ONLY) - /* Use best quality mode if no deadline is given. */ - new_qc = MODE_BESTQUALITY; - - if (deadline) { - /* Convert duration parameter from stream timebase to microseconds */ - VPX_STATIC_ASSERT(TICKS_PER_SEC > 1000000 && - (TICKS_PER_SEC % 1000000) == 0); - - if (duration > UINT64_MAX / (uint64_t)ctx->timestamp_ratio.num) { - ERROR("duration is too big"); - } - uint64_t duration_us = - duration * (uint64_t)ctx->timestamp_ratio.num / - ((uint64_t)ctx->timestamp_ratio.den * (TICKS_PER_SEC / 1000000)); - - /* If the deadline is more that the duration this frame is to be shown, - * use good quality mode. Otherwise use realtime mode. - */ - new_qc = (deadline > duration_us) ? MODE_GOODQUALITY : MODE_REALTIME; - } - -#else - (void)duration; - new_qc = MODE_REALTIME; -#endif - - if (deadline == VPX_DL_REALTIME) { - new_qc = MODE_REALTIME; - } else if (ctx->cfg.g_pass == VPX_RC_FIRST_PASS) { - new_qc = MODE_FIRSTPASS; - } else if (ctx->cfg.g_pass == VPX_RC_LAST_PASS) { - new_qc = - (new_qc == MODE_BESTQUALITY) ? MODE_SECONDPASS_BEST : MODE_SECONDPASS; - } - - if (ctx->oxcf.Mode != new_qc) { - ctx->oxcf.Mode = new_qc; - vp8_change_config(ctx->cpi, &ctx->oxcf); - } - return VPX_CODEC_OK; -} - -static vpx_codec_err_t set_reference_and_update(vpx_codec_alg_priv_t *ctx, - vpx_enc_frame_flags_t flags) { - /* Handle Flags */ - if (((flags & VP8_EFLAG_NO_UPD_GF) && (flags & VP8_EFLAG_FORCE_GF)) || - ((flags & VP8_EFLAG_NO_UPD_ARF) && (flags & VP8_EFLAG_FORCE_ARF))) { - ctx->base.err_detail = "Conflicting flags."; - return VPX_CODEC_INVALID_PARAM; - } - - if (flags & - (VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF)) { - int ref = 7; - - if (flags & VP8_EFLAG_NO_REF_LAST) ref ^= VP8_LAST_FRAME; - - if (flags & VP8_EFLAG_NO_REF_GF) ref ^= VP8_GOLD_FRAME; - - if (flags & VP8_EFLAG_NO_REF_ARF) ref ^= VP8_ALTR_FRAME; - - vp8_use_as_reference(ctx->cpi, ref); - } - - if (flags & - (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | - VP8_EFLAG_FORCE_GF | VP8_EFLAG_FORCE_ARF)) { - int upd = 7; - - if (flags & VP8_EFLAG_NO_UPD_LAST) upd ^= VP8_LAST_FRAME; - - if (flags & VP8_EFLAG_NO_UPD_GF) upd ^= VP8_GOLD_FRAME; - - if (flags & VP8_EFLAG_NO_UPD_ARF) upd ^= VP8_ALTR_FRAME; - - vp8_update_reference(ctx->cpi, upd); - } - - if (flags & VP8_EFLAG_NO_UPD_ENTROPY) { - vp8_update_entropy(ctx->cpi, 0); - } - - return VPX_CODEC_OK; -} - -static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t *ctx, - const vpx_image_t *img, vpx_codec_pts_t pts, - unsigned long duration, - vpx_enc_frame_flags_t enc_flags, - vpx_enc_deadline_t deadline) { - volatile vpx_codec_err_t res = VPX_CODEC_OK; - // Make a copy as volatile to avoid -Wclobbered with longjmp. - volatile vpx_enc_frame_flags_t flags = enc_flags; - volatile vpx_codec_pts_t pts_val = pts; - - if (!ctx->cfg.rc_target_bitrate) { -#if CONFIG_MULTI_RES_ENCODING - if (!ctx->cpi) return VPX_CODEC_ERROR; - if (ctx->cpi->oxcf.mr_total_resolutions > 1) { - LOWER_RES_FRAME_INFO *low_res_frame_info = - (LOWER_RES_FRAME_INFO *)ctx->cpi->oxcf.mr_low_res_mode_info; - if (!low_res_frame_info) return VPX_CODEC_ERROR; - low_res_frame_info->skip_encoding_prev_stream = 1; - if (ctx->cpi->oxcf.mr_encoder_id == 0) - low_res_frame_info->skip_encoding_base_stream = 1; - } -#endif - return res; - } - - if (img) res = validate_img(ctx, img); - - if (!res) res = validate_config(ctx, &ctx->cfg, &ctx->vp8_cfg, 1); - - if (!res) res = pick_quickcompress_mode(ctx, duration, deadline); - vpx_codec_pkt_list_init(&ctx->pkt_list); - - // If no flags are set in the encode call, then use the frame flags as - // defined via the control function: vp8e_set_frame_flags. - if (!flags) { - flags = ctx->control_frame_flags; - } - ctx->control_frame_flags = 0; - - if (!res) res = set_reference_and_update(ctx, flags); - - /* Handle fixed keyframe intervals */ - if (ctx->cfg.kf_mode == VPX_KF_AUTO && - ctx->cfg.kf_min_dist == ctx->cfg.kf_max_dist) { - if (++ctx->fixed_kf_cntr > ctx->cfg.kf_min_dist) { - flags |= VPX_EFLAG_FORCE_KF; - ctx->fixed_kf_cntr = 1; - } - } - - /* Initialize the encoder instance on the first frame*/ - if (!res && ctx->cpi) { - unsigned int lib_flags; - int64_t dst_time_stamp, dst_end_time_stamp; - size_t size, cx_data_sz; - unsigned char *cx_data; - unsigned char *cx_data_end; - int comp_data_state = 0; - - if (setjmp(ctx->cpi->common.error.jmp)) { - ctx->cpi->common.error.setjmp = 0; - res = update_error_state(ctx, &ctx->cpi->common.error); - vpx_clear_system_state(); - return res; - } - ctx->cpi->common.error.setjmp = 1; - - /* Set up internal flags */ - if (ctx->base.init_flags & VPX_CODEC_USE_PSNR) { - ((VP8_COMP *)ctx->cpi)->b_calculate_psnr = 1; - } - - if (ctx->base.init_flags & VPX_CODEC_USE_OUTPUT_PARTITION) { - ((VP8_COMP *)ctx->cpi)->output_partition = 1; - } - - /* Convert API flags to internal codec lib flags */ - lib_flags = (flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0; - - if (img != NULL) { - YV12_BUFFER_CONFIG sd; - - if (!ctx->pts_offset_initialized) { - ctx->pts_offset = pts_val; - ctx->pts_offset_initialized = 1; - } - if (pts_val < ctx->pts_offset) { - vpx_internal_error(&ctx->cpi->common.error, VPX_CODEC_INVALID_PARAM, - "pts is smaller than initial pts"); - } - pts_val -= ctx->pts_offset; - if (pts_val > INT64_MAX / ctx->timestamp_ratio.num) { - vpx_internal_error( - &ctx->cpi->common.error, VPX_CODEC_INVALID_PARAM, - "conversion of relative pts to ticks would overflow"); - } - dst_time_stamp = - pts_val * ctx->timestamp_ratio.num / ctx->timestamp_ratio.den; -#if ULONG_MAX > INT64_MAX - if (duration > INT64_MAX) { - vpx_internal_error(&ctx->cpi->common.error, VPX_CODEC_INVALID_PARAM, - "duration is too big"); - } -#endif - if (pts_val > INT64_MAX - (int64_t)duration) { - vpx_internal_error(&ctx->cpi->common.error, VPX_CODEC_INVALID_PARAM, - "relative pts + duration is too big"); - } - vpx_codec_pts_t pts_end = pts_val + (int64_t)duration; - if (pts_end > INT64_MAX / ctx->timestamp_ratio.num) { - vpx_internal_error( - &ctx->cpi->common.error, VPX_CODEC_INVALID_PARAM, - "conversion of relative pts + duration to ticks would overflow"); - } - dst_end_time_stamp = - pts_end * ctx->timestamp_ratio.num / ctx->timestamp_ratio.den; - - res = image2yuvconfig(img, &sd); - - if (vp8_receive_raw_frame(ctx->cpi, ctx->next_frame_flag | lib_flags, &sd, - dst_time_stamp, dst_end_time_stamp)) { - VP8_COMP *cpi = (VP8_COMP *)ctx->cpi; - res = update_error_state(ctx, &cpi->common.error); - } - - /* reset for next frame */ - ctx->next_frame_flag = 0; - } - - cx_data = ctx->cx_data; - cx_data_sz = ctx->cx_data_sz; - cx_data_end = ctx->cx_data + cx_data_sz; - lib_flags = 0; - - while (cx_data_sz >= ctx->cx_data_sz / 2) { - comp_data_state = vp8_get_compressed_data( - ctx->cpi, &lib_flags, &size, cx_data, cx_data_end, &dst_time_stamp, - &dst_end_time_stamp, !img); - - if (comp_data_state == VPX_CODEC_CORRUPT_FRAME) { - ctx->cpi->common.error.setjmp = 0; - return VPX_CODEC_CORRUPT_FRAME; - } else if (comp_data_state == -1) { - break; - } - - if (size) { - vpx_codec_pts_t round, delta; - vpx_codec_cx_pkt_t pkt; - VP8_COMP *cpi = (VP8_COMP *)ctx->cpi; - - /* Add the frame packet to the list of returned packets. */ - round = (vpx_codec_pts_t)ctx->timestamp_ratio.num / 2; - if (round > 0) --round; - delta = (dst_end_time_stamp - dst_time_stamp); - pkt.kind = VPX_CODEC_CX_FRAME_PKT; - pkt.data.frame.pts = - (dst_time_stamp * ctx->timestamp_ratio.den + round) / - ctx->timestamp_ratio.num + - ctx->pts_offset; - pkt.data.frame.duration = - (unsigned long)((delta * ctx->timestamp_ratio.den + round) / - ctx->timestamp_ratio.num); - pkt.data.frame.flags = lib_flags << 16; - pkt.data.frame.width[0] = cpi->common.Width; - pkt.data.frame.height[0] = cpi->common.Height; - pkt.data.frame.spatial_layer_encoded[0] = 1; - - if (lib_flags & FRAMEFLAGS_KEY) { - pkt.data.frame.flags |= VPX_FRAME_IS_KEY; - } - - if (!cpi->common.show_frame) { - pkt.data.frame.flags |= VPX_FRAME_IS_INVISIBLE; - - /* This timestamp should be as close as possible to the - * prior PTS so that if a decoder uses pts to schedule when - * to do this, we start right after last frame was decoded. - * Invisible frames have no duration. - */ - pkt.data.frame.pts = - ((cpi->last_time_stamp_seen * ctx->timestamp_ratio.den + round) / - ctx->timestamp_ratio.num) + - ctx->pts_offset + 1; - pkt.data.frame.duration = 0; - } - - if (cpi->droppable) pkt.data.frame.flags |= VPX_FRAME_IS_DROPPABLE; - - if (cpi->output_partition) { - int i; - const int num_partitions = - (1 << cpi->common.multi_token_partition) + 1; - - pkt.data.frame.flags |= VPX_FRAME_IS_FRAGMENT; - - for (i = 0; i < num_partitions; ++i) { -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING - pkt.data.frame.buf = cpi->partition_d[i]; -#else - pkt.data.frame.buf = cx_data; - cx_data += cpi->partition_sz[i]; - cx_data_sz -= cpi->partition_sz[i]; -#endif - pkt.data.frame.sz = cpi->partition_sz[i]; - pkt.data.frame.partition_id = i; - /* don't set the fragment bit for the last partition */ - if (i == (num_partitions - 1)) { - pkt.data.frame.flags &= ~VPX_FRAME_IS_FRAGMENT; - } - vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt); - } -#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING - /* In lagged mode the encoder can buffer multiple frames. - * We don't want this in partitioned output because - * partitions are spread all over the output buffer. - * So, force an exit! - */ - cx_data_sz -= ctx->cx_data_sz / 2; -#endif - } else { - pkt.data.frame.buf = cx_data; - pkt.data.frame.sz = size; - pkt.data.frame.partition_id = -1; - vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt); - cx_data += size; - cx_data_sz -= size; - } - } - } - ctx->cpi->common.error.setjmp = 0; - } - - return res; -} - -static const vpx_codec_cx_pkt_t *vp8e_get_cxdata(vpx_codec_alg_priv_t *ctx, - vpx_codec_iter_t *iter) { - return vpx_codec_pkt_list_get(&ctx->pkt_list.head, iter); -} - -static vpx_codec_err_t vp8e_set_reference(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *); - - if (data) { - vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data; - YV12_BUFFER_CONFIG sd; - - image2yuvconfig(&frame->img, &sd); - vp8_set_reference(ctx->cpi, frame->frame_type, &sd); - return VPX_CODEC_OK; - } else { - return VPX_CODEC_INVALID_PARAM; - } -} - -static vpx_codec_err_t vp8e_get_reference(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *); - - if (data) { - vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data; - YV12_BUFFER_CONFIG sd; - - image2yuvconfig(&frame->img, &sd); - vp8_get_reference(ctx->cpi, frame->frame_type, &sd); - return VPX_CODEC_OK; - } else { - return VPX_CODEC_INVALID_PARAM; - } -} - -static vpx_codec_err_t vp8e_set_previewpp(vpx_codec_alg_priv_t *ctx, - va_list args) { -#if CONFIG_POSTPROC - vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *); - - if (data) { - ctx->preview_ppcfg = *((vp8_postproc_cfg_t *)data); - return VPX_CODEC_OK; - } else { - return VPX_CODEC_INVALID_PARAM; - } -#else - (void)ctx; - (void)args; - return VPX_CODEC_INCAPABLE; -#endif -} - -static vpx_image_t *vp8e_get_preview(vpx_codec_alg_priv_t *ctx) { - YV12_BUFFER_CONFIG sd; - vp8_ppflags_t flags; - vp8_zero(flags); - - if (ctx->preview_ppcfg.post_proc_flag) { - flags.post_proc_flag = ctx->preview_ppcfg.post_proc_flag; - flags.deblocking_level = ctx->preview_ppcfg.deblocking_level; - flags.noise_level = ctx->preview_ppcfg.noise_level; - } - - if (0 == vp8_get_preview_raw_frame(ctx->cpi, &sd, &flags)) { - /* - vpx_img_wrap(&ctx->preview_img, VPX_IMG_FMT_YV12, - sd.y_width + 2*VP8BORDERINPIXELS, - sd.y_height + 2*VP8BORDERINPIXELS, - 1, - sd.buffer_alloc); - vpx_img_set_rect(&ctx->preview_img, - VP8BORDERINPIXELS, VP8BORDERINPIXELS, - sd.y_width, sd.y_height); - */ - - ctx->preview_img.bps = 12; - ctx->preview_img.planes[VPX_PLANE_Y] = sd.y_buffer; - ctx->preview_img.planes[VPX_PLANE_U] = sd.u_buffer; - ctx->preview_img.planes[VPX_PLANE_V] = sd.v_buffer; - - ctx->preview_img.fmt = VPX_IMG_FMT_I420; - ctx->preview_img.x_chroma_shift = 1; - ctx->preview_img.y_chroma_shift = 1; - - ctx->preview_img.d_w = sd.y_width; - ctx->preview_img.d_h = sd.y_height; - ctx->preview_img.stride[VPX_PLANE_Y] = sd.y_stride; - ctx->preview_img.stride[VPX_PLANE_U] = sd.uv_stride; - ctx->preview_img.stride[VPX_PLANE_V] = sd.uv_stride; - ctx->preview_img.w = sd.y_width; - ctx->preview_img.h = sd.y_height; - - return &ctx->preview_img; - } else { - return NULL; - } -} - -static vpx_codec_err_t vp8e_set_frame_flags(vpx_codec_alg_priv_t *ctx, - va_list args) { - int frame_flags = va_arg(args, int); - ctx->control_frame_flags = frame_flags; - return set_reference_and_update(ctx, frame_flags); -} - -static vpx_codec_err_t vp8e_set_temporal_layer_id(vpx_codec_alg_priv_t *ctx, - va_list args) { - int layer_id = va_arg(args, int); - if (layer_id < 0 || layer_id >= (int)ctx->cfg.ts_number_layers) { - return VPX_CODEC_INVALID_PARAM; - } - ctx->cpi->temporal_layer_id = layer_id; - return VPX_CODEC_OK; -} - -static vpx_codec_err_t vp8e_set_roi_map(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_roi_map_t *data = va_arg(args, vpx_roi_map_t *); - - if (data) { - vpx_roi_map_t *roi = (vpx_roi_map_t *)data; - - if (!vp8_set_roimap(ctx->cpi, roi->roi_map, roi->rows, roi->cols, - roi->delta_q, roi->delta_lf, roi->static_threshold)) { - return VPX_CODEC_OK; - } else { - return VPX_CODEC_INVALID_PARAM; - } - } else { - return VPX_CODEC_INVALID_PARAM; - } -} - -static vpx_codec_err_t vp8e_set_activemap(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_active_map_t *data = va_arg(args, vpx_active_map_t *); - - if (data) { - vpx_active_map_t *map = (vpx_active_map_t *)data; - - if (!vp8_set_active_map(ctx->cpi, map->active_map, map->rows, map->cols)) { - return VPX_CODEC_OK; - } else { - return VPX_CODEC_INVALID_PARAM; - } - } else { - return VPX_CODEC_INVALID_PARAM; - } -} - -static vpx_codec_err_t vp8e_set_scalemode(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_scaling_mode_t *data = va_arg(args, vpx_scaling_mode_t *); - - if (data) { - int res; - vpx_scaling_mode_t scalemode = *(vpx_scaling_mode_t *)data; - res = vp8_set_internal_size(ctx->cpi, scalemode.h_scaling_mode, - scalemode.v_scaling_mode); - - if (!res) { - /*force next frame a key frame to effect scaling mode */ - ctx->next_frame_flag |= FRAMEFLAGS_KEY; - return VPX_CODEC_OK; - } else { - return VPX_CODEC_INVALID_PARAM; - } - } else { - return VPX_CODEC_INVALID_PARAM; - } -} - -static vpx_codec_ctrl_fn_map_t vp8e_ctf_maps[] = { - { VP8_SET_REFERENCE, vp8e_set_reference }, - { VP8_COPY_REFERENCE, vp8e_get_reference }, - { VP8_SET_POSTPROC, vp8e_set_previewpp }, - { VP8E_SET_FRAME_FLAGS, vp8e_set_frame_flags }, - { VP8E_SET_TEMPORAL_LAYER_ID, vp8e_set_temporal_layer_id }, - { VP8E_SET_ROI_MAP, vp8e_set_roi_map }, - { VP8E_SET_ACTIVEMAP, vp8e_set_activemap }, - { VP8E_SET_SCALEMODE, vp8e_set_scalemode }, - { VP8E_SET_CPUUSED, set_cpu_used }, - { VP8E_SET_NOISE_SENSITIVITY, set_noise_sensitivity }, - { VP8E_SET_ENABLEAUTOALTREF, set_enable_auto_alt_ref }, - { VP8E_SET_SHARPNESS, set_sharpness }, - { VP8E_SET_STATIC_THRESHOLD, set_static_thresh }, - { VP8E_SET_TOKEN_PARTITIONS, set_token_partitions }, - { VP8E_GET_LAST_QUANTIZER, get_quantizer }, - { VP8E_GET_LAST_QUANTIZER_64, get_quantizer64 }, - { VP8E_SET_ARNR_MAXFRAMES, set_arnr_max_frames }, - { VP8E_SET_ARNR_STRENGTH, set_arnr_strength }, - { VP8E_SET_ARNR_TYPE, set_arnr_type }, - { VP8E_SET_TUNING, set_tuning }, - { VP8E_SET_CQ_LEVEL, set_cq_level }, - { VP8E_SET_MAX_INTRA_BITRATE_PCT, set_rc_max_intra_bitrate_pct }, - { VP8E_SET_SCREEN_CONTENT_MODE, set_screen_content_mode }, - { VP8E_SET_GF_CBR_BOOST_PCT, ctrl_set_rc_gf_cbr_boost_pct }, - { VP8E_SET_RTC_EXTERNAL_RATECTRL, ctrl_set_rtc_external_ratectrl }, - { -1, NULL }, -}; - -static vpx_codec_enc_cfg_map_t vp8e_usage_cfg_map[] = { - { 0, - { - 0, /* g_usage (unused) */ - 0, /* g_threads */ - 0, /* g_profile */ - - 320, /* g_width */ - 240, /* g_height */ - VPX_BITS_8, /* g_bit_depth */ - 8, /* g_input_bit_depth */ - - { 1, 30 }, /* g_timebase */ - - 0, /* g_error_resilient */ - - VPX_RC_ONE_PASS, /* g_pass */ - - 0, /* g_lag_in_frames */ - - 0, /* rc_dropframe_thresh */ - 0, /* rc_resize_allowed */ - 1, /* rc_scaled_width */ - 1, /* rc_scaled_height */ - 60, /* rc_resize_down_thresh */ - 30, /* rc_resize_up_thresh */ - - VPX_VBR, /* rc_end_usage */ - { NULL, 0 }, /* rc_twopass_stats_in */ - { NULL, 0 }, /* rc_firstpass_mb_stats_in */ - 256, /* rc_target_bitrate */ - 4, /* rc_min_quantizer */ - 63, /* rc_max_quantizer */ - 100, /* rc_undershoot_pct */ - 100, /* rc_overshoot_pct */ - - 6000, /* rc_max_buffer_size */ - 4000, /* rc_buffer_initial_size; */ - 5000, /* rc_buffer_optimal_size; */ - - 50, /* rc_two_pass_vbrbias */ - 0, /* rc_two_pass_vbrmin_section */ - 400, /* rc_two_pass_vbrmax_section */ - 0, // rc_2pass_vbr_corpus_complexity (only has meaningfull for VP9) - - /* keyframing settings (kf) */ - VPX_KF_AUTO, /* g_kfmode*/ - 0, /* kf_min_dist */ - 128, /* kf_max_dist */ - - VPX_SS_DEFAULT_LAYERS, /* ss_number_layers */ - { 0 }, - { 0 }, /* ss_target_bitrate */ - 1, /* ts_number_layers */ - { 0 }, /* ts_target_bitrate */ - { 0 }, /* ts_rate_decimator */ - 0, /* ts_periodicity */ - { 0 }, /* ts_layer_id */ - { 0 }, /* layer_target_bitrate */ - 0, /* temporal_layering_mode */ - 0, /* use_vizier_rc_params */ - { 1, 1 }, /* active_wq_factor */ - { 1, 1 }, /* err_per_mb_factor */ - { 1, 1 }, /* sr_default_decay_limit */ - { 1, 1 }, /* sr_diff_factor */ - { 1, 1 }, /* kf_err_per_mb_factor */ - { 1, 1 }, /* kf_frame_min_boost_factor */ - { 1, 1 }, /* kf_frame_max_boost_first_factor */ - { 1, 1 }, /* kf_frame_max_boost_subs_factor */ - { 1, 1 }, /* kf_max_total_boost_factor */ - { 1, 1 }, /* gf_max_total_boost_factor */ - { 1, 1 }, /* gf_frame_max_boost_factor */ - { 1, 1 }, /* zm_factor */ - { 1, 1 }, /* rd_mult_inter_qp_fac */ - { 1, 1 }, /* rd_mult_arf_qp_fac */ - { 1, 1 }, /* rd_mult_key_qp_fac */ - } }, -}; - -#ifndef VERSION_STRING -#define VERSION_STRING -#endif -CODEC_INTERFACE(vpx_codec_vp8_cx) = { - "WebM Project VP8 Encoder" VERSION_STRING, - VPX_CODEC_INTERNAL_ABI_VERSION, - VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR | VPX_CODEC_CAP_OUTPUT_PARTITION, - /* vpx_codec_caps_t caps; */ - vp8e_init, /* vpx_codec_init_fn_t init; */ - vp8e_destroy, /* vpx_codec_destroy_fn_t destroy; */ - vp8e_ctf_maps, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */ - { - NULL, /* vpx_codec_peek_si_fn_t peek_si; */ - NULL, /* vpx_codec_get_si_fn_t get_si; */ - NULL, /* vpx_codec_decode_fn_t decode; */ - NULL, /* vpx_codec_frame_get_fn_t frame_get; */ - NULL, /* vpx_codec_set_fb_fn_t set_fb_fn; */ - }, - { - 1, /* 1 cfg map */ - vp8e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t cfg_maps; */ - vp8e_encode, /* vpx_codec_encode_fn_t encode; */ - vp8e_get_cxdata, /* vpx_codec_get_cx_data_fn_t get_cx_data; */ - vp8e_set_config, - NULL, - vp8e_get_preview, - vp8e_mr_alloc_mem, - } /* encoder functions */ -}; diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/vp8_dx_iface.c b/presentation/src/main/cpp/third_party/libvpx/vp8/vp8_dx_iface.c deleted file mode 100644 index fa7d7be4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/vp8_dx_iface.c +++ /dev/null @@ -1,752 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include "./vp8_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "./vpx_scale_rtcd.h" -#include "vpx/vpx_decoder.h" -#include "vpx/vp8dx.h" -#include "vpx/internal/vpx_codec_internal.h" -#include "vpx_version.h" -#include "common/alloccommon.h" -#include "common/common.h" -#include "common/onyxc_int.h" -#include "common/onyxd.h" -#include "decoder/onyxd_int.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/system_state.h" -#if CONFIG_ERROR_CONCEALMENT -#include "decoder/error_concealment.h" -#endif -#include "decoder/decoderthreading.h" - -#define VP8_CAP_POSTPROC (CONFIG_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0) -#define VP8_CAP_ERROR_CONCEALMENT \ - (CONFIG_ERROR_CONCEALMENT ? VPX_CODEC_CAP_ERROR_CONCEALMENT : 0) - -typedef vpx_codec_stream_info_t vp8_stream_info_t; - -/* Structures for handling memory allocations */ -typedef enum { VP8_SEG_ALG_PRIV = 256, VP8_SEG_MAX } mem_seg_id_t; -#define NELEMENTS(x) ((int)(sizeof(x) / sizeof((x)[0]))) - -struct vpx_codec_alg_priv { - vpx_codec_priv_t base; - vpx_codec_dec_cfg_t cfg; - vp8_stream_info_t si; - int decoder_init; -#if CONFIG_MULTITHREAD - // Restart threads on next frame if set to 1. - // This is set when error happens in multithreaded decoding and all threads - // are shut down. - int restart_threads; -#endif - int postproc_cfg_set; - vp8_postproc_cfg_t postproc_cfg; - vpx_decrypt_cb decrypt_cb; - void *decrypt_state; - vpx_image_t img; - int img_setup; - struct frame_buffers yv12_frame_buffers; - void *user_priv; - FRAGMENT_DATA fragments; -}; - -static int vp8_init_ctx(vpx_codec_ctx_t *ctx) { - vpx_codec_alg_priv_t *priv = - (vpx_codec_alg_priv_t *)vpx_calloc(1, sizeof(*priv)); - if (!priv) return 1; - - ctx->priv = (vpx_codec_priv_t *)priv; - ctx->priv->init_flags = ctx->init_flags; - - priv->si.sz = sizeof(priv->si); - priv->decrypt_cb = NULL; - priv->decrypt_state = NULL; - - if (ctx->config.dec) { - /* Update the reference to the config structure to an internal copy. */ - priv->cfg = *ctx->config.dec; - ctx->config.dec = &priv->cfg; - } - - return 0; -} - -static vpx_codec_err_t vp8_init(vpx_codec_ctx_t *ctx, - vpx_codec_priv_enc_mr_cfg_t *data) { - vpx_codec_err_t res = VPX_CODEC_OK; - (void)data; - - vp8_rtcd(); - vpx_dsp_rtcd(); - vpx_scale_rtcd(); - - /* This function only allocates space for the vpx_codec_alg_priv_t - * structure. More memory may be required at the time the stream - * information becomes known. - */ - if (!ctx->priv) { - vpx_codec_alg_priv_t *priv; - - if (vp8_init_ctx(ctx)) return VPX_CODEC_MEM_ERROR; - - priv = (vpx_codec_alg_priv_t *)ctx->priv; - - /* initialize number of fragments to zero */ - priv->fragments.count = 0; - /* is input fragments enabled? */ - priv->fragments.enabled = - (priv->base.init_flags & VPX_CODEC_USE_INPUT_FRAGMENTS); - - /*post processing level initialized to do nothing */ - } - - return res; -} - -static vpx_codec_err_t vp8_destroy(vpx_codec_alg_priv_t *ctx) { - vp8_remove_decoder_instances(&ctx->yv12_frame_buffers); - - vpx_free(ctx); - - return VPX_CODEC_OK; -} - -static vpx_codec_err_t vp8_peek_si_internal(const uint8_t *data, - unsigned int data_sz, - vpx_codec_stream_info_t *si, - vpx_decrypt_cb decrypt_cb, - void *decrypt_state) { - vpx_codec_err_t res = VPX_CODEC_OK; - - assert(data != NULL); - - if (data + data_sz <= data) { - res = VPX_CODEC_INVALID_PARAM; - } else { - /* Parse uncompresssed part of key frame header. - * 3 bytes:- including version, frame type and an offset - * 3 bytes:- sync code (0x9d, 0x01, 0x2a) - * 4 bytes:- including image width and height in the lowest 14 bits - * of each 2-byte value. - */ - uint8_t clear_buffer[10]; - const uint8_t *clear = data; - if (decrypt_cb) { - int n = VPXMIN(sizeof(clear_buffer), data_sz); - decrypt_cb(decrypt_state, data, clear_buffer, n); - clear = clear_buffer; - } - si->is_kf = 0; - - if (data_sz >= 10 && !(clear[0] & 0x01)) { /* I-Frame */ - si->is_kf = 1; - - /* vet via sync code */ - if (clear[3] != 0x9d || clear[4] != 0x01 || clear[5] != 0x2a) { - return VPX_CODEC_UNSUP_BITSTREAM; - } - - si->w = (clear[6] | (clear[7] << 8)) & 0x3fff; - si->h = (clear[8] | (clear[9] << 8)) & 0x3fff; - - /*printf("w=%d, h=%d\n", si->w, si->h);*/ - if (!(si->h && si->w)) { - si->w = si->h = 0; - res = VPX_CODEC_CORRUPT_FRAME; - } - } else { - res = VPX_CODEC_UNSUP_BITSTREAM; - } - } - - return res; -} - -static vpx_codec_err_t vp8_peek_si(const uint8_t *data, unsigned int data_sz, - vpx_codec_stream_info_t *si) { - return vp8_peek_si_internal(data, data_sz, si, NULL, NULL); -} - -static vpx_codec_err_t vp8_get_si(vpx_codec_alg_priv_t *ctx, - vpx_codec_stream_info_t *si) { - unsigned int sz; - - if (si->sz >= sizeof(vp8_stream_info_t)) { - sz = sizeof(vp8_stream_info_t); - } else { - sz = sizeof(vpx_codec_stream_info_t); - } - - memcpy(si, &ctx->si, sz); - si->sz = sz; - - return VPX_CODEC_OK; -} - -static vpx_codec_err_t update_error_state( - vpx_codec_alg_priv_t *ctx, const struct vpx_internal_error_info *error) { - vpx_codec_err_t res; - - if ((res = error->error_code)) { - ctx->base.err_detail = error->has_detail ? error->detail : NULL; - } - - return res; -} - -static void yuvconfig2image(vpx_image_t *img, const YV12_BUFFER_CONFIG *yv12, - void *user_priv) { - /** vpx_img_wrap() doesn't allow specifying independent strides for - * the Y, U, and V planes, nor other alignment adjustments that - * might be representable by a YV12_BUFFER_CONFIG, so we just - * initialize all the fields.*/ - img->fmt = VPX_IMG_FMT_I420; - img->w = yv12->y_stride; - img->h = (yv12->y_height + 2 * VP8BORDERINPIXELS + 15) & ~15; - img->d_w = img->r_w = yv12->y_width; - img->d_h = img->r_h = yv12->y_height; - img->x_chroma_shift = 1; - img->y_chroma_shift = 1; - img->planes[VPX_PLANE_Y] = yv12->y_buffer; - img->planes[VPX_PLANE_U] = yv12->u_buffer; - img->planes[VPX_PLANE_V] = yv12->v_buffer; - img->planes[VPX_PLANE_ALPHA] = NULL; - img->stride[VPX_PLANE_Y] = yv12->y_stride; - img->stride[VPX_PLANE_U] = yv12->uv_stride; - img->stride[VPX_PLANE_V] = yv12->uv_stride; - img->stride[VPX_PLANE_ALPHA] = yv12->y_stride; - img->bit_depth = 8; - img->bps = 12; - img->user_priv = user_priv; - img->img_data = yv12->buffer_alloc; - img->img_data_owner = 0; - img->self_allocd = 0; -} - -static int update_fragments(vpx_codec_alg_priv_t *ctx, const uint8_t *data, - unsigned int data_sz, - volatile vpx_codec_err_t *res) { - *res = VPX_CODEC_OK; - - if (ctx->fragments.count == 0) { - /* New frame, reset fragment pointers and sizes */ - memset((void *)ctx->fragments.ptrs, 0, sizeof(ctx->fragments.ptrs)); - memset(ctx->fragments.sizes, 0, sizeof(ctx->fragments.sizes)); - } - if (ctx->fragments.enabled && !(data == NULL && data_sz == 0)) { - /* Store a pointer to this fragment and return. We haven't - * received the complete frame yet, so we will wait with decoding. - */ - if (ctx->fragments.count >= MAX_PARTITIONS) { - ctx->fragments.count = 0; - *res = VPX_CODEC_INVALID_PARAM; - return -1; - } - ctx->fragments.ptrs[ctx->fragments.count] = data; - ctx->fragments.sizes[ctx->fragments.count] = data_sz; - ctx->fragments.count++; - return 0; - } - - if (!ctx->fragments.enabled && (data == NULL && data_sz == 0)) { - return 0; - } - - if (!ctx->fragments.enabled) { - ctx->fragments.ptrs[0] = data; - ctx->fragments.sizes[0] = data_sz; - ctx->fragments.count = 1; - } - - return 1; -} - -static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t *ctx, - const uint8_t *data, unsigned int data_sz, - void *user_priv) { - volatile vpx_codec_err_t res; - volatile unsigned int resolution_change = 0; - volatile unsigned int w, h; - - if (!ctx->fragments.enabled && (data == NULL && data_sz == 0)) { - return 0; - } - - /* Update the input fragment data */ - if (update_fragments(ctx, data, data_sz, &res) <= 0) return res; - - /* Determine the stream parameters. Note that we rely on peek_si to - * validate that we have a buffer that does not wrap around the top - * of the heap. - */ - w = ctx->si.w; - h = ctx->si.h; - - res = vp8_peek_si_internal(ctx->fragments.ptrs[0], ctx->fragments.sizes[0], - &ctx->si, ctx->decrypt_cb, ctx->decrypt_state); - - if ((res == VPX_CODEC_UNSUP_BITSTREAM) && !ctx->si.is_kf) { - /* the peek function returns an error for non keyframes, however for - * this case, it is not an error */ - res = VPX_CODEC_OK; - } - - if (!ctx->decoder_init && !ctx->si.is_kf) res = VPX_CODEC_UNSUP_BITSTREAM; - if (!res && ctx->decoder_init && w == 0 && h == 0 && ctx->si.h == 0 && - ctx->si.w == 0) { - VP8D_COMP *pbi = ctx->yv12_frame_buffers.pbi[0]; - assert(pbi != NULL); - assert(!pbi->common.error.setjmp); - res = VPX_CODEC_CORRUPT_FRAME; - vpx_internal_error(&pbi->common.error, res, - "Keyframe / intra-only frame required to reset decoder" - " state"); - } - - if ((ctx->si.h != h) || (ctx->si.w != w)) resolution_change = 1; - -#if CONFIG_MULTITHREAD - if (!res && ctx->restart_threads) { - VP8D_COMP *pbi = ctx->yv12_frame_buffers.pbi[0]; - VP8_COMMON *const pc = &pbi->common; - if (setjmp(pbi->common.error.jmp)) { - pbi->common.error.setjmp = 0; - vp8_decoder_remove_threads(pbi); - vpx_clear_system_state(); - return VPX_CODEC_ERROR; - } - pbi->common.error.setjmp = 1; - pbi->max_threads = ctx->cfg.threads; - vp8_decoder_create_threads(pbi); - if (vpx_atomic_load_acquire(&pbi->b_multithreaded_rd)) { - vp8mt_alloc_temp_buffers(pbi, pc->Width, pc->mb_rows); - } - ctx->restart_threads = 0; - pbi->common.error.setjmp = 0; - } -#endif - /* Initialize the decoder instance on the first frame*/ - if (!res && !ctx->decoder_init) { - VP8D_CONFIG oxcf; - - oxcf.Width = ctx->si.w; - oxcf.Height = ctx->si.h; - oxcf.Version = 9; - oxcf.postprocess = 0; - oxcf.max_threads = ctx->cfg.threads; - oxcf.error_concealment = - (ctx->base.init_flags & VPX_CODEC_USE_ERROR_CONCEALMENT); - - /* If postprocessing was enabled by the application and a - * configuration has not been provided, default it. - */ - if (!ctx->postproc_cfg_set && - (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) { - ctx->postproc_cfg.post_proc_flag = - VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE; - ctx->postproc_cfg.deblocking_level = 4; - ctx->postproc_cfg.noise_level = 0; - } - - res = vp8_create_decoder_instances(&ctx->yv12_frame_buffers, &oxcf); - if (res == VPX_CODEC_OK) { - ctx->decoder_init = 1; - } else { - /* on failure clear the cached resolution to ensure a full - * reallocation is attempted on resync. */ - ctx->si.w = 0; - ctx->si.h = 0; - } - } - - /* Set these even if already initialized. The caller may have changed the - * decrypt config between frames. - */ - if (ctx->decoder_init) { - ctx->yv12_frame_buffers.pbi[0]->decrypt_cb = ctx->decrypt_cb; - ctx->yv12_frame_buffers.pbi[0]->decrypt_state = ctx->decrypt_state; - } - - if (!res) { - VP8D_COMP *pbi = ctx->yv12_frame_buffers.pbi[0]; - VP8_COMMON *const pc = &pbi->common; - if (resolution_change) { - MACROBLOCKD *const xd = &pbi->mb; -#if CONFIG_MULTITHREAD - int i; -#endif - pc->Width = ctx->si.w; - pc->Height = ctx->si.h; - { - if (setjmp(pbi->common.error.jmp)) { - pbi->common.error.setjmp = 0; - /* on failure clear the cached resolution to ensure a full - * reallocation is attempted on resync. */ - ctx->si.w = 0; - ctx->si.h = 0; - vpx_clear_system_state(); - /* same return value as used in vp8dx_receive_compressed_data */ - return -1; - } - - pbi->common.error.setjmp = 1; - - if (pc->Width <= 0) { - pc->Width = w; - vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, - "Invalid frame width"); - } - - if (pc->Height <= 0) { - pc->Height = h; - vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, - "Invalid frame height"); - } - -#if CONFIG_MULTITHREAD - if (vpx_atomic_load_acquire(&pbi->b_multithreaded_rd)) { - vp8mt_de_alloc_temp_buffers(pbi, pc->mb_rows); - } -#endif - - if (vp8_alloc_frame_buffers(pc, pc->Width, pc->Height)) { - vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate frame buffers"); - } - - xd->pre = pc->yv12_fb[pc->lst_fb_idx]; - xd->dst = pc->yv12_fb[pc->new_fb_idx]; - -#if CONFIG_MULTITHREAD - for (i = 0; i < pbi->allocated_decoding_thread_count; ++i) { - pbi->mb_row_di[i].mbd.dst = pc->yv12_fb[pc->new_fb_idx]; - vp8_build_block_doffsets(&pbi->mb_row_di[i].mbd); - } -#endif - vp8_build_block_doffsets(&pbi->mb); - -/* allocate memory for last frame MODE_INFO array */ -#if CONFIG_ERROR_CONCEALMENT - - if (pbi->ec_enabled) { - /* old prev_mip was released by vp8_de_alloc_frame_buffers() - * called in vp8_alloc_frame_buffers() */ - pc->prev_mip = vpx_calloc((pc->mb_cols + 1) * (pc->mb_rows + 1), - sizeof(MODE_INFO)); - - if (!pc->prev_mip) { - vp8_de_alloc_frame_buffers(pc); - vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate" - "last frame MODE_INFO array"); - } - - pc->prev_mi = pc->prev_mip + pc->mode_info_stride + 1; - - if (vp8_alloc_overlap_lists(pbi)) - vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate overlap lists " - "for error concealment"); - } - -#endif - -#if CONFIG_MULTITHREAD - if (vpx_atomic_load_acquire(&pbi->b_multithreaded_rd)) { - vp8mt_alloc_temp_buffers(pbi, pc->Width, 0); - } -#endif - } - - pbi->common.error.setjmp = 0; - - /* required to get past the first get_free_fb() call */ - pbi->common.fb_idx_ref_cnt[0] = 0; - } - - if (setjmp(pbi->common.error.jmp)) { - vpx_clear_system_state(); - /* We do not know if the missing frame(s) was supposed to update - * any of the reference buffers, but we act conservative and - * mark only the last buffer as corrupted. - */ - pc->yv12_fb[pc->lst_fb_idx].corrupted = 1; - - if (pc->fb_idx_ref_cnt[pc->new_fb_idx] > 0) { - pc->fb_idx_ref_cnt[pc->new_fb_idx]--; - } - pbi->common.error.setjmp = 0; -#if CONFIG_MULTITHREAD - if (pbi->restart_threads) { - ctx->si.w = 0; - ctx->si.h = 0; - ctx->restart_threads = 1; - } -#endif - res = update_error_state(ctx, &pbi->common.error); - return res; - } - - pbi->common.error.setjmp = 1; - - /* update the pbi fragment data */ - pbi->fragments = ctx->fragments; -#if CONFIG_MULTITHREAD - pbi->restart_threads = 0; -#endif - ctx->user_priv = user_priv; - if (vp8dx_receive_compressed_data(pbi)) { - res = update_error_state(ctx, &pbi->common.error); - } - - /* get ready for the next series of fragments */ - ctx->fragments.count = 0; - pbi->common.error.setjmp = 0; - } - - return res; -} - -static vpx_image_t *vp8_get_frame(vpx_codec_alg_priv_t *ctx, - vpx_codec_iter_t *iter) { - vpx_image_t *img = NULL; - - /* iter acts as a flip flop, so an image is only returned on the first - * call to get_frame. - */ - if (!(*iter) && ctx->yv12_frame_buffers.pbi[0]) { - YV12_BUFFER_CONFIG sd; - vp8_ppflags_t flags; - vp8_zero(flags); - - if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) { - flags.post_proc_flag = ctx->postproc_cfg.post_proc_flag; - flags.deblocking_level = ctx->postproc_cfg.deblocking_level; - flags.noise_level = ctx->postproc_cfg.noise_level; - } - - if (0 == vp8dx_get_raw_frame(ctx->yv12_frame_buffers.pbi[0], &sd, &flags)) { - yuvconfig2image(&ctx->img, &sd, ctx->user_priv); - - img = &ctx->img; - *iter = img; - } - } - - return img; -} - -static vpx_codec_err_t image2yuvconfig(const vpx_image_t *img, - YV12_BUFFER_CONFIG *yv12) { - const int y_w = img->d_w; - const int y_h = img->d_h; - const int uv_w = (img->d_w + 1) / 2; - const int uv_h = (img->d_h + 1) / 2; - vpx_codec_err_t res = VPX_CODEC_OK; - yv12->y_buffer = img->planes[VPX_PLANE_Y]; - yv12->u_buffer = img->planes[VPX_PLANE_U]; - yv12->v_buffer = img->planes[VPX_PLANE_V]; - - yv12->y_crop_width = y_w; - yv12->y_crop_height = y_h; - yv12->y_width = y_w; - yv12->y_height = y_h; - yv12->uv_crop_width = uv_w; - yv12->uv_crop_height = uv_h; - yv12->uv_width = uv_w; - yv12->uv_height = uv_h; - - yv12->y_stride = img->stride[VPX_PLANE_Y]; - yv12->uv_stride = img->stride[VPX_PLANE_U]; - - yv12->border = (img->stride[VPX_PLANE_Y] - img->d_w) / 2; - return res; -} - -static vpx_codec_err_t vp8_set_reference(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *); - - if (data) { - vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data; - YV12_BUFFER_CONFIG sd; - - image2yuvconfig(&frame->img, &sd); - - return vp8dx_set_reference(ctx->yv12_frame_buffers.pbi[0], - frame->frame_type, &sd); - } else { - return VPX_CODEC_INVALID_PARAM; - } -} - -static vpx_codec_err_t vp8_get_reference(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *); - - if (data) { - vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data; - YV12_BUFFER_CONFIG sd; - - image2yuvconfig(&frame->img, &sd); - - return vp8dx_get_reference(ctx->yv12_frame_buffers.pbi[0], - frame->frame_type, &sd); - } else { - return VPX_CODEC_INVALID_PARAM; - } -} - -static vpx_codec_err_t vp8_get_quantizer(vpx_codec_alg_priv_t *ctx, - va_list args) { - int *const arg = va_arg(args, int *); - VP8D_COMP *pbi = ctx->yv12_frame_buffers.pbi[0]; - if (arg == NULL) return VPX_CODEC_INVALID_PARAM; - if (pbi == NULL) return VPX_CODEC_CORRUPT_FRAME; - *arg = vp8dx_get_quantizer(pbi); - return VPX_CODEC_OK; -} - -static vpx_codec_err_t vp8_set_postproc(vpx_codec_alg_priv_t *ctx, - va_list args) { -#if CONFIG_POSTPROC - vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *); - - if (data) { - ctx->postproc_cfg_set = 1; - ctx->postproc_cfg = *((vp8_postproc_cfg_t *)data); - return VPX_CODEC_OK; - } else { - return VPX_CODEC_INVALID_PARAM; - } - -#else - (void)ctx; - (void)args; - return VPX_CODEC_INCAPABLE; -#endif -} - -static vpx_codec_err_t vp8_get_last_ref_updates(vpx_codec_alg_priv_t *ctx, - va_list args) { - int *update_info = va_arg(args, int *); - - if (update_info) { - VP8D_COMP *pbi = (VP8D_COMP *)ctx->yv12_frame_buffers.pbi[0]; - if (pbi == NULL) return VPX_CODEC_CORRUPT_FRAME; - - *update_info = pbi->common.refresh_alt_ref_frame * (int)VP8_ALTR_FRAME + - pbi->common.refresh_golden_frame * (int)VP8_GOLD_FRAME + - pbi->common.refresh_last_frame * (int)VP8_LAST_FRAME; - - return VPX_CODEC_OK; - } else { - return VPX_CODEC_INVALID_PARAM; - } -} - -static vpx_codec_err_t vp8_get_last_ref_frame(vpx_codec_alg_priv_t *ctx, - va_list args) { - int *ref_info = va_arg(args, int *); - - if (ref_info) { - VP8D_COMP *pbi = (VP8D_COMP *)ctx->yv12_frame_buffers.pbi[0]; - if (pbi) { - VP8_COMMON *oci = &pbi->common; - *ref_info = - (vp8dx_references_buffer(oci, ALTREF_FRAME) ? VP8_ALTR_FRAME : 0) | - (vp8dx_references_buffer(oci, GOLDEN_FRAME) ? VP8_GOLD_FRAME : 0) | - (vp8dx_references_buffer(oci, LAST_FRAME) ? VP8_LAST_FRAME : 0); - return VPX_CODEC_OK; - } else { - return VPX_CODEC_CORRUPT_FRAME; - } - } else { - return VPX_CODEC_INVALID_PARAM; - } -} - -static vpx_codec_err_t vp8_get_frame_corrupted(vpx_codec_alg_priv_t *ctx, - va_list args) { - int *corrupted = va_arg(args, int *); - VP8D_COMP *pbi = (VP8D_COMP *)ctx->yv12_frame_buffers.pbi[0]; - - if (corrupted && pbi) { - const YV12_BUFFER_CONFIG *const frame = pbi->common.frame_to_show; - if (frame == NULL) return VPX_CODEC_ERROR; - *corrupted = frame->corrupted; - return VPX_CODEC_OK; - } else { - return VPX_CODEC_INVALID_PARAM; - } -} - -static vpx_codec_err_t vp8_set_decryptor(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_decrypt_init *init = va_arg(args, vpx_decrypt_init *); - - if (init) { - ctx->decrypt_cb = init->decrypt_cb; - ctx->decrypt_state = init->decrypt_state; - } else { - ctx->decrypt_cb = NULL; - ctx->decrypt_state = NULL; - } - return VPX_CODEC_OK; -} - -static vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] = { - { VP8_SET_REFERENCE, vp8_set_reference }, - { VP8_COPY_REFERENCE, vp8_get_reference }, - { VP8_SET_POSTPROC, vp8_set_postproc }, - { VP8D_GET_LAST_REF_UPDATES, vp8_get_last_ref_updates }, - { VP8D_GET_FRAME_CORRUPTED, vp8_get_frame_corrupted }, - { VP8D_GET_LAST_REF_USED, vp8_get_last_ref_frame }, - { VPXD_GET_LAST_QUANTIZER, vp8_get_quantizer }, - { VPXD_SET_DECRYPTOR, vp8_set_decryptor }, - { -1, NULL }, -}; - -#ifndef VERSION_STRING -#define VERSION_STRING -#endif -CODEC_INTERFACE(vpx_codec_vp8_dx) = { - "WebM Project VP8 Decoder" VERSION_STRING, - VPX_CODEC_INTERNAL_ABI_VERSION, - VPX_CODEC_CAP_DECODER | VP8_CAP_POSTPROC | VP8_CAP_ERROR_CONCEALMENT | - VPX_CODEC_CAP_INPUT_FRAGMENTS, - /* vpx_codec_caps_t caps; */ - vp8_init, /* vpx_codec_init_fn_t init; */ - vp8_destroy, /* vpx_codec_destroy_fn_t destroy; */ - vp8_ctf_maps, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */ - { - vp8_peek_si, /* vpx_codec_peek_si_fn_t peek_si; */ - vp8_get_si, /* vpx_codec_get_si_fn_t get_si; */ - vp8_decode, /* vpx_codec_decode_fn_t decode; */ - vp8_get_frame, /* vpx_codec_frame_get_fn_t frame_get; */ - NULL, - }, - { - /* encoder functions */ - 0, NULL, /* vpx_codec_enc_cfg_map_t */ - NULL, /* vpx_codec_encode_fn_t */ - NULL, /* vpx_codec_get_cx_data_fn_t */ - NULL, /* vpx_codec_enc_config_set_fn_t */ - NULL, /* vpx_codec_get_global_headers_fn_t */ - NULL, /* vpx_codec_get_preview_frame_fn_t */ - NULL /* vpx_codec_enc_mr_get_mem_loc_fn_t */ - } -}; diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/vp8_ratectrl_rtc.cc b/presentation/src/main/cpp/third_party/libvpx/vp8/vp8_ratectrl_rtc.cc deleted file mode 100644 index 312092f1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/vp8_ratectrl_rtc.cc +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright (c) 2021 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp8/vp8_ratectrl_rtc.h" - -#include - -#include - -#include "vp8/common/common.h" -#include "vp8/encoder/onyx_int.h" -#include "vp8/encoder/ratectrl.h" -#include "vpx_ports/system_state.h" - -namespace libvpx { -/* Quant MOD */ -static const int kQTrans[] = { - 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19, - 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 35, 37, 39, 41, - 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 64, 67, 70, 73, 76, 79, - 82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, 127, -}; - -static const unsigned char kf_high_motion_minq[QINDEX_RANGE] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, - 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 10, 10, - 10, 10, 11, 11, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, - 16, 16, 16, 17, 17, 18, 18, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, - 22, 22, 23, 23, 24, 25, 25, 26, 26, 27, 28, 28, 29, 30 -}; - -static const unsigned char inter_minq[QINDEX_RANGE] = { - 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, 11, - 11, 12, 13, 13, 14, 15, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 24, - 24, 25, 26, 27, 27, 28, 29, 30, 30, 31, 32, 33, 33, 34, 35, 36, 36, 37, 38, - 39, 39, 40, 41, 42, 42, 43, 44, 45, 46, 46, 47, 48, 49, 50, 50, 51, 52, 53, - 54, 55, 55, 56, 57, 58, 59, 60, 60, 61, 62, 63, 64, 65, 66, 67, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 -}; - -static int rescale(int val, int num, int denom) { - int64_t llnum = num; - int64_t llden = denom; - int64_t llval = val; - - return (int)(llval * llnum / llden); -} - -std::unique_ptr VP8RateControlRTC::Create( - const VP8RateControlRtcConfig &cfg) { - std::unique_ptr rc_api(new (std::nothrow) - VP8RateControlRTC()); - if (!rc_api) return nullptr; - rc_api->cpi_ = static_cast(vpx_memalign(32, sizeof(*cpi_))); - if (!rc_api->cpi_) return nullptr; - vp8_zero(*rc_api->cpi_); - - if (!rc_api->InitRateControl(cfg)) return nullptr; - - return rc_api; -} - -VP8RateControlRTC::~VP8RateControlRTC() { - if (cpi_) { - vpx_free(cpi_->gf_active_flags); - vpx_free(cpi_); - } -} - -bool VP8RateControlRTC::InitRateControl(const VP8RateControlRtcConfig &rc_cfg) { - VP8_COMMON *cm = &cpi_->common; - VP8_CONFIG *oxcf = &cpi_->oxcf; - oxcf->end_usage = USAGE_STREAM_FROM_SERVER; - cpi_->pass = 0; - cm->show_frame = 1; - oxcf->drop_frames_water_mark = 0; - cm->current_video_frame = 0; - cpi_->auto_gold = 1; - cpi_->key_frame_count = 1; - cpi_->rate_correction_factor = 1.0; - cpi_->key_frame_rate_correction_factor = 1.0; - cpi_->cyclic_refresh_mode_enabled = 0; - cpi_->auto_worst_q = 1; - cpi_->kf_overspend_bits = 0; - cpi_->kf_bitrate_adjustment = 0; - cpi_->gf_overspend_bits = 0; - cpi_->non_gf_bitrate_adjustment = 0; - if (!UpdateRateControl(rc_cfg)) return false; - cpi_->buffer_level = oxcf->starting_buffer_level; - cpi_->bits_off_target = oxcf->starting_buffer_level; - return true; -} - -bool VP8RateControlRTC::UpdateRateControl( - const VP8RateControlRtcConfig &rc_cfg) { - if (rc_cfg.ts_number_layers < 1 || - rc_cfg.ts_number_layers > VPX_TS_MAX_LAYERS) { - return false; - } - - VP8_COMMON *cm = &cpi_->common; - VP8_CONFIG *oxcf = &cpi_->oxcf; - const unsigned int prev_number_of_layers = oxcf->number_of_layers; - vpx_clear_system_state(); - cm->Width = rc_cfg.width; - cm->Height = rc_cfg.height; - oxcf->Width = rc_cfg.width; - oxcf->Height = rc_cfg.height; - oxcf->worst_allowed_q = kQTrans[rc_cfg.max_quantizer]; - oxcf->best_allowed_q = kQTrans[rc_cfg.min_quantizer]; - cpi_->worst_quality = oxcf->worst_allowed_q; - cpi_->best_quality = oxcf->best_allowed_q; - cpi_->output_framerate = rc_cfg.framerate; - oxcf->target_bandwidth = - static_cast(1000 * rc_cfg.target_bandwidth); - cpi_->ref_framerate = cpi_->output_framerate; - oxcf->fixed_q = -1; - oxcf->error_resilient_mode = 1; - oxcf->starting_buffer_level_in_ms = rc_cfg.buf_initial_sz; - oxcf->optimal_buffer_level_in_ms = rc_cfg.buf_optimal_sz; - oxcf->maximum_buffer_size_in_ms = rc_cfg.buf_sz; - oxcf->starting_buffer_level = rc_cfg.buf_initial_sz; - oxcf->optimal_buffer_level = rc_cfg.buf_optimal_sz; - oxcf->maximum_buffer_size = rc_cfg.buf_sz; - oxcf->number_of_layers = rc_cfg.ts_number_layers; - cpi_->buffered_mode = oxcf->optimal_buffer_level > 0; - oxcf->under_shoot_pct = rc_cfg.undershoot_pct; - oxcf->over_shoot_pct = rc_cfg.overshoot_pct; - oxcf->drop_frames_water_mark = rc_cfg.frame_drop_thresh; - if (oxcf->drop_frames_water_mark > 0) cpi_->drop_frames_allowed = 1; - cpi_->oxcf.rc_max_intra_bitrate_pct = rc_cfg.max_intra_bitrate_pct; - cpi_->framerate = rc_cfg.framerate; - for (int i = 0; i < KEY_FRAME_CONTEXT; ++i) { - cpi_->prior_key_frame_distance[i] = - static_cast(cpi_->output_framerate); - } - oxcf->screen_content_mode = rc_cfg.is_screen; - if (oxcf->number_of_layers > 1 || prev_number_of_layers > 1) { - memcpy(oxcf->target_bitrate, rc_cfg.layer_target_bitrate, - sizeof(rc_cfg.layer_target_bitrate)); - memcpy(oxcf->rate_decimator, rc_cfg.ts_rate_decimator, - sizeof(rc_cfg.ts_rate_decimator)); - if (cm->current_video_frame == 0) { - double prev_layer_framerate = 0; - for (unsigned int i = 0; i < oxcf->number_of_layers; ++i) { - vp8_init_temporal_layer_context(cpi_, oxcf, i, prev_layer_framerate); - prev_layer_framerate = cpi_->output_framerate / oxcf->rate_decimator[i]; - } - } else if (oxcf->number_of_layers != prev_number_of_layers) { - // The number of temporal layers has changed, so reset/initialize the - // temporal layer context for the new layer configuration: this means - // calling vp8_reset_temporal_layer_change() below. - - // Start at the base of the pattern cycle, so set the layer id to 0 and - // reset the temporal pattern counter. - // TODO(marpan/jianj): don't think lines 148-151 are needed (user controls - // the layer_id) so remove. - if (cpi_->temporal_layer_id > 0) { - cpi_->temporal_layer_id = 0; - } - cpi_->temporal_pattern_counter = 0; - - vp8_reset_temporal_layer_change(cpi_, oxcf, - static_cast(prev_number_of_layers)); - } - } - - cpi_->total_actual_bits = 0; - cpi_->total_target_vs_actual = 0; - - cm->mb_rows = cm->Height >> 4; - cm->mb_cols = cm->Width >> 4; - cm->MBs = cm->mb_rows * cm->mb_cols; - cm->mode_info_stride = cm->mb_cols + 1; - - // For temporal layers: starting/maximum/optimal_buffer_level is already set - // via vp8_init_temporal_layer_context() or vp8_reset_temporal_layer_change(). - if (oxcf->number_of_layers <= 1 && prev_number_of_layers <= 1) { - oxcf->starting_buffer_level = - rescale((int)oxcf->starting_buffer_level, oxcf->target_bandwidth, 1000); - /* Set or reset optimal and maximum buffer levels. */ - if (oxcf->optimal_buffer_level == 0) { - oxcf->optimal_buffer_level = oxcf->target_bandwidth / 8; - } else { - oxcf->optimal_buffer_level = rescale((int)oxcf->optimal_buffer_level, - oxcf->target_bandwidth, 1000); - } - if (oxcf->maximum_buffer_size == 0) { - oxcf->maximum_buffer_size = oxcf->target_bandwidth / 8; - } else { - oxcf->maximum_buffer_size = - rescale((int)oxcf->maximum_buffer_size, oxcf->target_bandwidth, 1000); - } - } - - if (cpi_->bits_off_target > oxcf->maximum_buffer_size) { - cpi_->bits_off_target = oxcf->maximum_buffer_size; - cpi_->buffer_level = cpi_->bits_off_target; - } - - vp8_new_framerate(cpi_, cpi_->framerate); - vpx_clear_system_state(); - return true; -} - -FrameDropDecision VP8RateControlRTC::ComputeQP( - const VP8FrameParamsQpRTC &frame_params) { - VP8_COMMON *const cm = &cpi_->common; - vpx_clear_system_state(); - if (cpi_->oxcf.number_of_layers > 1) { - cpi_->temporal_layer_id = frame_params.temporal_layer_id; - const int layer = frame_params.temporal_layer_id; - vp8_update_layer_contexts(cpi_); - /* Restore layer specific context & set frame rate */ - vp8_restore_layer_context(cpi_, layer); - vp8_new_framerate(cpi_, cpi_->layer_context[layer].framerate); - } - cm->frame_type = static_cast(frame_params.frame_type); - cm->refresh_golden_frame = (cm->frame_type == KEY_FRAME) ? 1 : 0; - cm->refresh_alt_ref_frame = (cm->frame_type == KEY_FRAME) ? 1 : 0; - if (cm->frame_type == KEY_FRAME && cpi_->common.current_video_frame > 0) { - cpi_->common.frame_flags |= FRAMEFLAGS_KEY; - } - - cpi_->per_frame_bandwidth = static_cast( - round(cpi_->oxcf.target_bandwidth / cpi_->output_framerate)); - if (vp8_check_drop_buffer(cpi_)) { - if (cpi_->oxcf.number_of_layers > 1) vp8_save_layer_context(cpi_); - return FrameDropDecision::kDrop; - } - - if (!vp8_pick_frame_size(cpi_)) { - cm->current_video_frame++; - cpi_->frames_since_key++; - cpi_->ext_refresh_frame_flags_pending = 0; - if (cpi_->oxcf.number_of_layers > 1) vp8_save_layer_context(cpi_); - return FrameDropDecision::kDrop; - } - - if (cpi_->buffer_level >= cpi_->oxcf.optimal_buffer_level && - cpi_->buffered_mode) { - /* Max adjustment is 1/4 */ - int Adjustment = cpi_->active_worst_quality / 4; - if (Adjustment) { - int buff_lvl_step; - if (cpi_->buffer_level < cpi_->oxcf.maximum_buffer_size) { - buff_lvl_step = (int)((cpi_->oxcf.maximum_buffer_size - - cpi_->oxcf.optimal_buffer_level) / - Adjustment); - if (buff_lvl_step) { - Adjustment = - (int)((cpi_->buffer_level - cpi_->oxcf.optimal_buffer_level) / - buff_lvl_step); - } else { - Adjustment = 0; - } - } - cpi_->active_worst_quality -= Adjustment; - if (cpi_->active_worst_quality < cpi_->active_best_quality) { - cpi_->active_worst_quality = cpi_->active_best_quality; - } - } - } - - if (cpi_->ni_frames > 150) { - int q = cpi_->active_worst_quality; - if (cm->frame_type == KEY_FRAME) { - cpi_->active_best_quality = kf_high_motion_minq[q]; - } else { - cpi_->active_best_quality = inter_minq[q]; - } - - if (cpi_->buffer_level >= cpi_->oxcf.maximum_buffer_size) { - cpi_->active_best_quality = cpi_->best_quality; - - } else if (cpi_->buffer_level > cpi_->oxcf.optimal_buffer_level) { - int Fraction = - (int)(((cpi_->buffer_level - cpi_->oxcf.optimal_buffer_level) * 128) / - (cpi_->oxcf.maximum_buffer_size - - cpi_->oxcf.optimal_buffer_level)); - int min_qadjustment = - ((cpi_->active_best_quality - cpi_->best_quality) * Fraction) / 128; - - cpi_->active_best_quality -= min_qadjustment; - } - } - - /* Clip the active best and worst quality values to limits */ - if (cpi_->active_worst_quality > cpi_->worst_quality) { - cpi_->active_worst_quality = cpi_->worst_quality; - } - if (cpi_->active_best_quality < cpi_->best_quality) { - cpi_->active_best_quality = cpi_->best_quality; - } - if (cpi_->active_worst_quality < cpi_->active_best_quality) { - cpi_->active_worst_quality = cpi_->active_best_quality; - } - - q_ = vp8_regulate_q(cpi_, cpi_->this_frame_target); - vp8_set_quantizer(cpi_, q_); - vpx_clear_system_state(); - return FrameDropDecision::kOk; -} - -int VP8RateControlRTC::GetQP() const { return q_; } - -UVDeltaQP VP8RateControlRTC::GetUVDeltaQP() const { - VP8_COMMON *cm = &cpi_->common; - UVDeltaQP uv_delta_q; - uv_delta_q.uvdc_delta_q = cm->uvdc_delta_q; - uv_delta_q.uvac_delta_q = cm->uvac_delta_q; - return uv_delta_q; -} - -int VP8RateControlRTC::GetLoopfilterLevel() const { - VP8_COMMON *cm = &cpi_->common; - const double qp = q_; - - // This model is from linear regression - if (cm->Width * cm->Height <= 320 * 240) { - cm->filter_level = static_cast(0.352685 * qp + 2.957774); - } else if (cm->Width * cm->Height <= 640 * 480) { - cm->filter_level = static_cast(0.485069 * qp - 0.534462); - } else { - cm->filter_level = static_cast(0.314875 * qp + 7.959003); - } - - int min_filter_level = 0; - // This logic is from get_min_filter_level() in picklpf.c - if (q_ > 6 && q_ <= 16) { - min_filter_level = 1; - } else { - min_filter_level = (q_ / 8); - } - - const int max_filter_level = 63; - if (cm->filter_level < min_filter_level) cm->filter_level = min_filter_level; - if (cm->filter_level > max_filter_level) cm->filter_level = max_filter_level; - - return cm->filter_level; -} - -void VP8RateControlRTC::PostEncodeUpdate(uint64_t encoded_frame_size) { - VP8_COMMON *const cm = &cpi_->common; - vpx_clear_system_state(); - cpi_->total_byte_count += encoded_frame_size; - cpi_->projected_frame_size = static_cast(encoded_frame_size << 3); - if (cpi_->oxcf.number_of_layers > 1) { - for (unsigned int i = cpi_->current_layer + 1; - i < cpi_->oxcf.number_of_layers; ++i) { - cpi_->layer_context[i].total_byte_count += encoded_frame_size; - } - } - - vp8_update_rate_correction_factors(cpi_, 2); - - cpi_->last_q[cm->frame_type] = cm->base_qindex; - - if (cm->frame_type == KEY_FRAME) { - vp8_adjust_key_frame_context(cpi_); - } - - /* Keep a record of ambient average Q. */ - if (cm->frame_type != KEY_FRAME) { - cpi_->avg_frame_qindex = - (2 + 3 * cpi_->avg_frame_qindex + cm->base_qindex) >> 2; - } - /* Keep a record from which we can calculate the average Q excluding - * key frames. - */ - if (cm->frame_type != KEY_FRAME) { - cpi_->ni_frames++; - /* Damp value for first few frames */ - if (cpi_->ni_frames > 150) { - cpi_->ni_tot_qi += q_; - cpi_->ni_av_qi = (cpi_->ni_tot_qi / cpi_->ni_frames); - } else { - cpi_->ni_tot_qi += q_; - cpi_->ni_av_qi = - ((cpi_->ni_tot_qi / cpi_->ni_frames) + cpi_->worst_quality + 1) / 2; - } - - /* If the average Q is higher than what was used in the last - * frame (after going through the recode loop to keep the frame - * size within range) then use the last frame value - 1. The -1 - * is designed to stop Q and hence the data rate, from - * progressively falling away during difficult sections, but at - * the same time reduce the number of itterations around the - * recode loop. - */ - if (q_ > cpi_->ni_av_qi) cpi_->ni_av_qi = q_ - 1; - } - - cpi_->bits_off_target += - cpi_->av_per_frame_bandwidth - cpi_->projected_frame_size; - if (cpi_->bits_off_target > cpi_->oxcf.maximum_buffer_size) { - cpi_->bits_off_target = cpi_->oxcf.maximum_buffer_size; - } - - cpi_->total_actual_bits += cpi_->projected_frame_size; - cpi_->buffer_level = cpi_->bits_off_target; - - /* Propagate values to higher temporal layers */ - if (cpi_->oxcf.number_of_layers > 1) { - for (unsigned int i = cpi_->current_layer + 1; - i < cpi_->oxcf.number_of_layers; ++i) { - LAYER_CONTEXT *lc = &cpi_->layer_context[i]; - int bits_off_for_this_layer = (int)round( - lc->target_bandwidth / lc->framerate - cpi_->projected_frame_size); - - lc->bits_off_target += bits_off_for_this_layer; - - /* Clip buffer level to maximum buffer size for the layer */ - if (lc->bits_off_target > lc->maximum_buffer_size) { - lc->bits_off_target = lc->maximum_buffer_size; - } - - lc->total_actual_bits += cpi_->projected_frame_size; - lc->total_target_vs_actual += bits_off_for_this_layer; - lc->buffer_level = lc->bits_off_target; - } - } - - cpi_->common.current_video_frame++; - cpi_->frames_since_key++; - - if (cpi_->oxcf.number_of_layers > 1) vp8_save_layer_context(cpi_); - vpx_clear_system_state(); -} -} // namespace libvpx diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/vp8_ratectrl_rtc.h b/presentation/src/main/cpp/third_party/libvpx/vp8/vp8_ratectrl_rtc.h deleted file mode 100644 index b458b5ce..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/vp8_ratectrl_rtc.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2021 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP8_RATECTRL_RTC_H_ -#define VPX_VP8_RATECTRL_RTC_H_ - -#include -#include -#include - -#include "vpx/internal/vpx_ratectrl_rtc.h" - -struct VP8_COMP; - -namespace libvpx { -struct VP8RateControlRtcConfig : public VpxRateControlRtcConfig { - VP8RateControlRtcConfig() { - memset(&layer_target_bitrate, 0, sizeof(layer_target_bitrate)); - memset(&ts_rate_decimator, 0, sizeof(ts_rate_decimator)); - } -}; - -struct VP8FrameParamsQpRTC { - RcFrameType frame_type; - int temporal_layer_id; -}; - -class VP8RateControlRTC { - public: - static std::unique_ptr Create( - const VP8RateControlRtcConfig &cfg); - ~VP8RateControlRTC(); - - bool UpdateRateControl(const VP8RateControlRtcConfig &rc_cfg); - // GetQP() needs to be called after ComputeQP() to get the latest QP - int GetQP() const; - // GetUVDeltaQP() needs to be called after ComputeQP() to get the latest - // delta QP for UV. - UVDeltaQP GetUVDeltaQP() const; - // GetLoopfilterLevel() needs to be called after ComputeQP() since loopfilter - // level is calculated from frame qp. - int GetLoopfilterLevel() const; - // ComputeQP computes the QP if the frame is not dropped (kOk return), - // otherwise it returns kDrop and subsequent GetQP and PostEncodeUpdate - // are not to be called. - FrameDropDecision ComputeQP(const VP8FrameParamsQpRTC &frame_params); - // Feedback to rate control with the size of current encoded frame - void PostEncodeUpdate(uint64_t encoded_frame_size); - - private: - VP8RateControlRTC() = default; - bool InitRateControl(const VP8RateControlRtcConfig &cfg); - struct VP8_COMP *cpi_ = nullptr; - int q_ = -1; -}; - -} // namespace libvpx - -#endif // VPX_VP8_RATECTRL_RTC_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/vp8cx.mk b/presentation/src/main/cpp/third_party/libvpx/vp8/vp8cx.mk deleted file mode 100644 index b4b3fda9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/vp8cx.mk +++ /dev/null @@ -1,132 +0,0 @@ -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - - -VP8_CX_EXPORTS += exports_enc - -VP8_CX_SRCS-yes += $(VP8_COMMON_SRCS-yes) -VP8_CX_SRCS-no += $(VP8_COMMON_SRCS-no) -VP8_CX_SRCS_REMOVE-yes += $(VP8_COMMON_SRCS_REMOVE-yes) -VP8_CX_SRCS_REMOVE-no += $(VP8_COMMON_SRCS_REMOVE-no) - -VP8_CX_SRCS-yes += vp8cx.mk - -VP8_CX_SRCS-yes += vp8_cx_iface.c - -VP8_CX_SRCS-yes += encoder/defaultcoefcounts.h -VP8_CX_SRCS-yes += encoder/bitstream.c -VP8_CX_SRCS-yes += encoder/boolhuff.c -VP8_CX_SRCS-yes += encoder/copy_c.c -VP8_CX_SRCS-yes += encoder/dct.c -VP8_CX_SRCS-yes += encoder/encodeframe.c -VP8_CX_SRCS-yes += encoder/encodeframe.h -VP8_CX_SRCS-yes += encoder/encodeintra.c -VP8_CX_SRCS-yes += encoder/encodemb.c -VP8_CX_SRCS-yes += encoder/encodemv.c -VP8_CX_SRCS-$(CONFIG_MULTITHREAD) += encoder/ethreading.c -VP8_CX_SRCS-$(CONFIG_MULTITHREAD) += encoder/ethreading.h -VP8_CX_SRCS-yes += encoder/firstpass.c -VP8_CX_SRCS-yes += encoder/block.h -VP8_CX_SRCS-yes += encoder/boolhuff.h -VP8_CX_SRCS-yes += encoder/bitstream.h -VP8_CX_SRCS-$(CONFIG_TEMPORAL_DENOISING) += encoder/denoising.h -VP8_CX_SRCS-$(CONFIG_TEMPORAL_DENOISING) += encoder/denoising.c -VP8_CX_SRCS-yes += encoder/encodeintra.h -VP8_CX_SRCS-yes += encoder/encodemb.h -VP8_CX_SRCS-yes += encoder/encodemv.h -VP8_CX_SRCS-yes += encoder/firstpass.h -VP8_CX_SRCS-yes += encoder/lookahead.c -VP8_CX_SRCS-yes += encoder/lookahead.h -VP8_CX_SRCS-yes += encoder/mcomp.h -VP8_CX_SRCS-yes += encoder/modecosts.h -VP8_CX_SRCS-yes += encoder/onyx_int.h -VP8_CX_SRCS-yes += encoder/pickinter.h -VP8_CX_SRCS-yes += encoder/quantize.h -VP8_CX_SRCS-yes += encoder/ratectrl.h -VP8_CX_SRCS-yes += encoder/rdopt.h -VP8_CX_SRCS-yes += encoder/tokenize.h -VP8_CX_SRCS-yes += encoder/treewriter.h -VP8_CX_SRCS-yes += encoder/mcomp.c -VP8_CX_SRCS-yes += encoder/modecosts.c -VP8_CX_SRCS-yes += encoder/onyx_if.c -VP8_CX_SRCS-yes += encoder/pickinter.c -VP8_CX_SRCS-yes += encoder/picklpf.c -VP8_CX_SRCS-yes += encoder/picklpf.h -VP8_CX_SRCS-yes += encoder/vp8_quantize.c -VP8_CX_SRCS-yes += encoder/ratectrl.c -VP8_CX_SRCS-yes += encoder/rdopt.c -VP8_CX_SRCS-yes += encoder/segmentation.c -VP8_CX_SRCS-yes += encoder/segmentation.h -VP8_CX_SRCS-yes += common/vp8_skin_detection.c -VP8_CX_SRCS-yes += common/vp8_skin_detection.h -VP8_CX_SRCS-yes += encoder/tokenize.c -VP8_CX_SRCS-yes += encoder/dct_value_cost.h -VP8_CX_SRCS-yes += encoder/dct_value_tokens.h -VP8_CX_SRCS-yes += encoder/treewriter.c -VP8_CX_SRCS-$(CONFIG_INTERNAL_STATS) += common/postproc.h -VP8_CX_SRCS-$(CONFIG_INTERNAL_STATS) += common/postproc.c -VP8_CX_SRCS-yes += encoder/temporal_filter.c -VP8_CX_SRCS-yes += encoder/temporal_filter.h -VP8_CX_SRCS-$(CONFIG_MULTI_RES_ENCODING) += encoder/mr_dissim.c -VP8_CX_SRCS-$(CONFIG_MULTI_RES_ENCODING) += encoder/mr_dissim.h - -ifeq ($(CONFIG_REALTIME_ONLY),yes) -VP8_CX_SRCS_REMOVE-yes += encoder/firstpass.c -VP8_CX_SRCS_REMOVE-yes += encoder/temporal_filter.c -VP8_CX_SRCS_REMOVE-yes += encoder/temporal_filter.h -endif - -VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/copy_sse2.asm -VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/copy_sse3.asm -VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/dct_sse2.asm -VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/fwalsh_sse2.asm -VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp8_quantize_sse2.c -VP8_CX_SRCS-$(HAVE_SSSE3) += encoder/x86/vp8_quantize_ssse3.c -VP8_CX_SRCS-$(HAVE_SSE4_1) += encoder/x86/quantize_sse4.c - -ifeq ($(CONFIG_TEMPORAL_DENOISING),yes) -VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/denoising_sse2.c -endif - -VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/block_error_sse2.asm -VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/temporal_filter_apply_sse2.asm -VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp8_enc_stubs_sse2.c - -ifeq ($(CONFIG_REALTIME_ONLY),yes) -VP8_CX_SRCS_REMOVE-$(HAVE_SSE2) += encoder/x86/temporal_filter_apply_sse2.asm -endif - -VP8_CX_SRCS-$(HAVE_NEON) += encoder/arm/neon/denoising_neon.c -VP8_CX_SRCS-$(HAVE_NEON) += encoder/arm/neon/fastquantizeb_neon.c -VP8_CX_SRCS-$(HAVE_NEON) += encoder/arm/neon/shortfdct_neon.c -VP8_CX_SRCS-$(HAVE_NEON) += encoder/arm/neon/vp8_shortwalsh4x4_neon.c - -VP8_CX_SRCS-$(HAVE_MSA) += encoder/mips/msa/dct_msa.c -VP8_CX_SRCS-$(HAVE_MSA) += encoder/mips/msa/encodeopt_msa.c -VP8_CX_SRCS-$(HAVE_MSA) += encoder/mips/msa/quantize_msa.c -VP8_CX_SRCS-$(HAVE_MSA) += encoder/mips/msa/temporal_filter_msa.c - -VP8_CX_SRCS-$(HAVE_MMI) += encoder/mips/mmi/vp8_quantize_mmi.c -VP8_CX_SRCS-$(HAVE_MMI) += encoder/mips/mmi/dct_mmi.c - -ifeq ($(CONFIG_TEMPORAL_DENOISING),yes) -VP8_CX_SRCS-$(HAVE_MSA) += encoder/mips/msa/denoising_msa.c -endif - -ifeq ($(CONFIG_REALTIME_ONLY),yes) -VP8_CX_SRCS_REMOVE-$(HAVE_MSA) += encoder/mips/msa/temporal_filter_msa.c -endif - -# common (loongarch LSX intrinsics) -VP8_CX_SRCS-$(HAVE_LSX) += encoder/loongarch/dct_lsx.c -VP8_CX_SRCS-$(HAVE_LSX) += encoder/loongarch/encodeopt_lsx.c -VP8_CX_SRCS-$(HAVE_LSX) += encoder/loongarch/vp8_quantize_lsx.c - -VP8_CX_SRCS-yes := $(filter-out $(VP8_CX_SRCS_REMOVE-yes),$(VP8_CX_SRCS-yes)) diff --git a/presentation/src/main/cpp/third_party/libvpx/vp8/vp8dx.mk b/presentation/src/main/cpp/third_party/libvpx/vp8/vp8dx.mk deleted file mode 100644 index 892ed70f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp8/vp8dx.mk +++ /dev/null @@ -1,39 +0,0 @@ -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - - -VP8_DX_EXPORTS += exports_dec - -VP8_DX_SRCS-yes += $(VP8_COMMON_SRCS-yes) -VP8_DX_SRCS-no += $(VP8_COMMON_SRCS-no) -VP8_DX_SRCS_REMOVE-yes += $(VP8_COMMON_SRCS_REMOVE-yes) -VP8_DX_SRCS_REMOVE-no += $(VP8_COMMON_SRCS_REMOVE-no) - -VP8_DX_SRCS-yes += vp8dx.mk - -VP8_DX_SRCS-yes += vp8_dx_iface.c - -VP8_DX_SRCS-yes += decoder/dboolhuff.c -VP8_DX_SRCS-yes += decoder/decodemv.c -VP8_DX_SRCS-yes += decoder/decodeframe.c -VP8_DX_SRCS-yes += decoder/detokenize.c -VP8_DX_SRCS-$(CONFIG_ERROR_CONCEALMENT) += decoder/ec_types.h -VP8_DX_SRCS-$(CONFIG_ERROR_CONCEALMENT) += decoder/error_concealment.h -VP8_DX_SRCS-$(CONFIG_ERROR_CONCEALMENT) += decoder/error_concealment.c -VP8_DX_SRCS-yes += decoder/dboolhuff.h -VP8_DX_SRCS-yes += decoder/decodemv.h -VP8_DX_SRCS-yes += decoder/decoderthreading.h -VP8_DX_SRCS-yes += decoder/detokenize.h -VP8_DX_SRCS-yes += decoder/onyxd_int.h -VP8_DX_SRCS-yes += decoder/treereader.h -VP8_DX_SRCS-yes += decoder/onyxd_if.c -VP8_DX_SRCS-$(CONFIG_MULTITHREAD) += decoder/threading.c - -VP8_DX_SRCS-yes := $(filter-out $(VP8_DX_SRCS_REMOVE-yes),$(VP8_DX_SRCS-yes)) diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_highbd_iht16x16_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_highbd_iht16x16_add_neon.c deleted file mode 100644 index b43d7fa4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_highbd_iht16x16_add_neon.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vp9/common/vp9_enums.h" -#include "vp9/common/arm/neon/vp9_iht_neon.h" -#include "vpx_dsp/arm/highbd_idct_neon.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/inv_txfm.h" - -// Use macros to make sure argument lane is passed in as a constant integer. - -#define vmull_lane_s32_dual(in, c, lane, out) \ - do { \ - out[0].val[0] = vmull_lane_s32(vget_low_s32(in.val[0]), c, lane); \ - out[0].val[1] = vmull_lane_s32(vget_low_s32(in.val[1]), c, lane); \ - out[1].val[0] = vmull_lane_s32(vget_high_s32(in.val[0]), c, lane); \ - out[1].val[1] = vmull_lane_s32(vget_high_s32(in.val[1]), c, lane); \ - } while (0) - -#define vmlal_lane_s32_dual(in, c, lane, out) \ - do { \ - out[0].val[0] = \ - vmlal_lane_s32(out[0].val[0], vget_low_s32(in.val[0]), c, lane); \ - out[0].val[1] = \ - vmlal_lane_s32(out[0].val[1], vget_low_s32(in.val[1]), c, lane); \ - out[1].val[0] = \ - vmlal_lane_s32(out[1].val[0], vget_high_s32(in.val[0]), c, lane); \ - out[1].val[1] = \ - vmlal_lane_s32(out[1].val[1], vget_high_s32(in.val[1]), c, lane); \ - } while (0) - -#define vmlsl_lane_s32_dual(in, c, lane, out) \ - do { \ - out[0].val[0] = \ - vmlsl_lane_s32(out[0].val[0], vget_low_s32(in.val[0]), c, lane); \ - out[0].val[1] = \ - vmlsl_lane_s32(out[0].val[1], vget_low_s32(in.val[1]), c, lane); \ - out[1].val[0] = \ - vmlsl_lane_s32(out[1].val[0], vget_high_s32(in.val[0]), c, lane); \ - out[1].val[1] = \ - vmlsl_lane_s32(out[1].val[1], vget_high_s32(in.val[1]), c, lane); \ - } while (0) - -static INLINE int32x4x2_t -highbd_dct_const_round_shift_low_8(const int64x2x2_t *const in) { - int32x4x2_t out; - out.val[0] = vcombine_s32(vrshrn_n_s64(in[0].val[0], DCT_CONST_BITS), - vrshrn_n_s64(in[1].val[0], DCT_CONST_BITS)); - out.val[1] = vcombine_s32(vrshrn_n_s64(in[0].val[1], DCT_CONST_BITS), - vrshrn_n_s64(in[1].val[1], DCT_CONST_BITS)); - return out; -} - -#define highbd_iadst_half_butterfly(in, c, lane, out) \ - do { \ - int64x2x2_t _t[2]; \ - vmull_lane_s32_dual(in, c, lane, _t); \ - out = highbd_dct_const_round_shift_low_8(_t); \ - } while (0) - -#define highbd_iadst_butterfly(in0, in1, c, lane0, lane1, s0, s1) \ - do { \ - vmull_lane_s32_dual(in0, c, lane0, s0); \ - vmull_lane_s32_dual(in0, c, lane1, s1); \ - vmlal_lane_s32_dual(in1, c, lane1, s0); \ - vmlsl_lane_s32_dual(in1, c, lane0, s1); \ - } while (0) - -static INLINE int32x4x2_t vaddq_s32_dual(const int32x4x2_t in0, - const int32x4x2_t in1) { - int32x4x2_t out; - out.val[0] = vaddq_s32(in0.val[0], in1.val[0]); - out.val[1] = vaddq_s32(in0.val[1], in1.val[1]); - return out; -} - -static INLINE int64x2x2_t vaddq_s64_dual(const int64x2x2_t in0, - const int64x2x2_t in1) { - int64x2x2_t out; - out.val[0] = vaddq_s64(in0.val[0], in1.val[0]); - out.val[1] = vaddq_s64(in0.val[1], in1.val[1]); - return out; -} - -static INLINE int32x4x2_t vsubq_s32_dual(const int32x4x2_t in0, - const int32x4x2_t in1) { - int32x4x2_t out; - out.val[0] = vsubq_s32(in0.val[0], in1.val[0]); - out.val[1] = vsubq_s32(in0.val[1], in1.val[1]); - return out; -} - -static INLINE int64x2x2_t vsubq_s64_dual(const int64x2x2_t in0, - const int64x2x2_t in1) { - int64x2x2_t out; - out.val[0] = vsubq_s64(in0.val[0], in1.val[0]); - out.val[1] = vsubq_s64(in0.val[1], in1.val[1]); - return out; -} - -static INLINE int32x4x2_t vcombine_s32_dual(const int32x2x2_t in0, - const int32x2x2_t in1) { - int32x4x2_t out; - out.val[0] = vcombine_s32(in0.val[0], in1.val[0]); - out.val[1] = vcombine_s32(in0.val[1], in1.val[1]); - return out; -} - -static INLINE int32x4x2_t highbd_add_dct_const_round_shift_low_8( - const int64x2x2_t *const in0, const int64x2x2_t *const in1) { - const int64x2x2_t sum_lo = vaddq_s64_dual(in0[0], in1[0]); - const int64x2x2_t sum_hi = vaddq_s64_dual(in0[1], in1[1]); - int32x2x2_t out_lo, out_hi; - - out_lo.val[0] = vrshrn_n_s64(sum_lo.val[0], DCT_CONST_BITS); - out_lo.val[1] = vrshrn_n_s64(sum_lo.val[1], DCT_CONST_BITS); - out_hi.val[0] = vrshrn_n_s64(sum_hi.val[0], DCT_CONST_BITS); - out_hi.val[1] = vrshrn_n_s64(sum_hi.val[1], DCT_CONST_BITS); - return vcombine_s32_dual(out_lo, out_hi); -} - -static INLINE int32x4x2_t highbd_sub_dct_const_round_shift_low_8( - const int64x2x2_t *const in0, const int64x2x2_t *const in1) { - const int64x2x2_t sub_lo = vsubq_s64_dual(in0[0], in1[0]); - const int64x2x2_t sub_hi = vsubq_s64_dual(in0[1], in1[1]); - int32x2x2_t out_lo, out_hi; - - out_lo.val[0] = vrshrn_n_s64(sub_lo.val[0], DCT_CONST_BITS); - out_lo.val[1] = vrshrn_n_s64(sub_lo.val[1], DCT_CONST_BITS); - out_hi.val[0] = vrshrn_n_s64(sub_hi.val[0], DCT_CONST_BITS); - out_hi.val[1] = vrshrn_n_s64(sub_hi.val[1], DCT_CONST_BITS); - return vcombine_s32_dual(out_lo, out_hi); -} - -static INLINE int32x4x2_t vnegq_s32_dual(const int32x4x2_t in) { - int32x4x2_t out; - out.val[0] = vnegq_s32(in.val[0]); - out.val[1] = vnegq_s32(in.val[1]); - return out; -} - -static void highbd_iadst16_neon(const int32_t *input, int32_t *output, - uint16_t *dest, const int stride, - const int bd) { - const int32x4_t c_1_31_5_27 = - create_s32x4_neon(cospi_1_64, cospi_31_64, cospi_5_64, cospi_27_64); - const int32x4_t c_9_23_13_19 = - create_s32x4_neon(cospi_9_64, cospi_23_64, cospi_13_64, cospi_19_64); - const int32x4_t c_17_15_21_11 = - create_s32x4_neon(cospi_17_64, cospi_15_64, cospi_21_64, cospi_11_64); - const int32x4_t c_25_7_29_3 = - create_s32x4_neon(cospi_25_64, cospi_7_64, cospi_29_64, cospi_3_64); - const int32x4_t c_4_28_20_12 = - create_s32x4_neon(cospi_4_64, cospi_28_64, cospi_20_64, cospi_12_64); - const int32x4_t c_16_n16_8_24 = - create_s32x4_neon(cospi_16_64, -cospi_16_64, cospi_8_64, cospi_24_64); - int32x4x2_t in[16], out[16]; - int32x4x2_t x[16], t[12]; - int64x2x2_t s0[2], s1[2], s2[2], s3[2], s4[2], s5[2], s6[2], s7[2]; - int64x2x2_t s8[2], s9[2], s10[2], s11[2], s12[2], s13[2], s14[2], s15[2]; - - // Load input (16x8) - in[0].val[0] = vld1q_s32(input); - in[0].val[1] = vld1q_s32(input + 4); - input += 8; - in[8].val[0] = vld1q_s32(input); - in[8].val[1] = vld1q_s32(input + 4); - input += 8; - in[1].val[0] = vld1q_s32(input); - in[1].val[1] = vld1q_s32(input + 4); - input += 8; - in[9].val[0] = vld1q_s32(input); - in[9].val[1] = vld1q_s32(input + 4); - input += 8; - in[2].val[0] = vld1q_s32(input); - in[2].val[1] = vld1q_s32(input + 4); - input += 8; - in[10].val[0] = vld1q_s32(input); - in[10].val[1] = vld1q_s32(input + 4); - input += 8; - in[3].val[0] = vld1q_s32(input); - in[3].val[1] = vld1q_s32(input + 4); - input += 8; - in[11].val[0] = vld1q_s32(input); - in[11].val[1] = vld1q_s32(input + 4); - input += 8; - in[4].val[0] = vld1q_s32(input); - in[4].val[1] = vld1q_s32(input + 4); - input += 8; - in[12].val[0] = vld1q_s32(input); - in[12].val[1] = vld1q_s32(input + 4); - input += 8; - in[5].val[0] = vld1q_s32(input); - in[5].val[1] = vld1q_s32(input + 4); - input += 8; - in[13].val[0] = vld1q_s32(input); - in[13].val[1] = vld1q_s32(input + 4); - input += 8; - in[6].val[0] = vld1q_s32(input); - in[6].val[1] = vld1q_s32(input + 4); - input += 8; - in[14].val[0] = vld1q_s32(input); - in[14].val[1] = vld1q_s32(input + 4); - input += 8; - in[7].val[0] = vld1q_s32(input); - in[7].val[1] = vld1q_s32(input + 4); - input += 8; - in[15].val[0] = vld1q_s32(input); - in[15].val[1] = vld1q_s32(input + 4); - - // Transpose - transpose_s32_8x8(&in[0], &in[1], &in[2], &in[3], &in[4], &in[5], &in[6], - &in[7]); - transpose_s32_8x8(&in[8], &in[9], &in[10], &in[11], &in[12], &in[13], &in[14], - &in[15]); - - x[0] = in[15]; - x[1] = in[0]; - x[2] = in[13]; - x[3] = in[2]; - x[4] = in[11]; - x[5] = in[4]; - x[6] = in[9]; - x[7] = in[6]; - x[8] = in[7]; - x[9] = in[8]; - x[10] = in[5]; - x[11] = in[10]; - x[12] = in[3]; - x[13] = in[12]; - x[14] = in[1]; - x[15] = in[14]; - - // stage 1 - highbd_iadst_butterfly(x[0], x[1], vget_low_s32(c_1_31_5_27), 0, 1, s0, s1); - highbd_iadst_butterfly(x[2], x[3], vget_high_s32(c_1_31_5_27), 0, 1, s2, s3); - highbd_iadst_butterfly(x[4], x[5], vget_low_s32(c_9_23_13_19), 0, 1, s4, s5); - highbd_iadst_butterfly(x[6], x[7], vget_high_s32(c_9_23_13_19), 0, 1, s6, s7); - highbd_iadst_butterfly(x[8], x[9], vget_low_s32(c_17_15_21_11), 0, 1, s8, s9); - highbd_iadst_butterfly(x[10], x[11], vget_high_s32(c_17_15_21_11), 0, 1, s10, - s11); - highbd_iadst_butterfly(x[12], x[13], vget_low_s32(c_25_7_29_3), 0, 1, s12, - s13); - highbd_iadst_butterfly(x[14], x[15], vget_high_s32(c_25_7_29_3), 0, 1, s14, - s15); - - x[0] = highbd_add_dct_const_round_shift_low_8(s0, s8); - x[1] = highbd_add_dct_const_round_shift_low_8(s1, s9); - x[2] = highbd_add_dct_const_round_shift_low_8(s2, s10); - x[3] = highbd_add_dct_const_round_shift_low_8(s3, s11); - x[4] = highbd_add_dct_const_round_shift_low_8(s4, s12); - x[5] = highbd_add_dct_const_round_shift_low_8(s5, s13); - x[6] = highbd_add_dct_const_round_shift_low_8(s6, s14); - x[7] = highbd_add_dct_const_round_shift_low_8(s7, s15); - x[8] = highbd_sub_dct_const_round_shift_low_8(s0, s8); - x[9] = highbd_sub_dct_const_round_shift_low_8(s1, s9); - x[10] = highbd_sub_dct_const_round_shift_low_8(s2, s10); - x[11] = highbd_sub_dct_const_round_shift_low_8(s3, s11); - x[12] = highbd_sub_dct_const_round_shift_low_8(s4, s12); - x[13] = highbd_sub_dct_const_round_shift_low_8(s5, s13); - x[14] = highbd_sub_dct_const_round_shift_low_8(s6, s14); - x[15] = highbd_sub_dct_const_round_shift_low_8(s7, s15); - - // stage 2 - t[0] = x[0]; - t[1] = x[1]; - t[2] = x[2]; - t[3] = x[3]; - t[4] = x[4]; - t[5] = x[5]; - t[6] = x[6]; - t[7] = x[7]; - highbd_iadst_butterfly(x[8], x[9], vget_low_s32(c_4_28_20_12), 0, 1, s8, s9); - highbd_iadst_butterfly(x[10], x[11], vget_high_s32(c_4_28_20_12), 0, 1, s10, - s11); - highbd_iadst_butterfly(x[13], x[12], vget_low_s32(c_4_28_20_12), 1, 0, s13, - s12); - highbd_iadst_butterfly(x[15], x[14], vget_high_s32(c_4_28_20_12), 1, 0, s15, - s14); - - x[0] = vaddq_s32_dual(t[0], t[4]); - x[1] = vaddq_s32_dual(t[1], t[5]); - x[2] = vaddq_s32_dual(t[2], t[6]); - x[3] = vaddq_s32_dual(t[3], t[7]); - x[4] = vsubq_s32_dual(t[0], t[4]); - x[5] = vsubq_s32_dual(t[1], t[5]); - x[6] = vsubq_s32_dual(t[2], t[6]); - x[7] = vsubq_s32_dual(t[3], t[7]); - x[8] = highbd_add_dct_const_round_shift_low_8(s8, s12); - x[9] = highbd_add_dct_const_round_shift_low_8(s9, s13); - x[10] = highbd_add_dct_const_round_shift_low_8(s10, s14); - x[11] = highbd_add_dct_const_round_shift_low_8(s11, s15); - x[12] = highbd_sub_dct_const_round_shift_low_8(s8, s12); - x[13] = highbd_sub_dct_const_round_shift_low_8(s9, s13); - x[14] = highbd_sub_dct_const_round_shift_low_8(s10, s14); - x[15] = highbd_sub_dct_const_round_shift_low_8(s11, s15); - - // stage 3 - t[0] = x[0]; - t[1] = x[1]; - t[2] = x[2]; - t[3] = x[3]; - highbd_iadst_butterfly(x[4], x[5], vget_high_s32(c_16_n16_8_24), 0, 1, s4, - s5); - highbd_iadst_butterfly(x[7], x[6], vget_high_s32(c_16_n16_8_24), 1, 0, s7, - s6); - t[8] = x[8]; - t[9] = x[9]; - t[10] = x[10]; - t[11] = x[11]; - highbd_iadst_butterfly(x[12], x[13], vget_high_s32(c_16_n16_8_24), 0, 1, s12, - s13); - highbd_iadst_butterfly(x[15], x[14], vget_high_s32(c_16_n16_8_24), 1, 0, s15, - s14); - - x[0] = vaddq_s32_dual(t[0], t[2]); - x[1] = vaddq_s32_dual(t[1], t[3]); - x[2] = vsubq_s32_dual(t[0], t[2]); - x[3] = vsubq_s32_dual(t[1], t[3]); - x[4] = highbd_add_dct_const_round_shift_low_8(s4, s6); - x[5] = highbd_add_dct_const_round_shift_low_8(s5, s7); - x[6] = highbd_sub_dct_const_round_shift_low_8(s4, s6); - x[7] = highbd_sub_dct_const_round_shift_low_8(s5, s7); - x[8] = vaddq_s32_dual(t[8], t[10]); - x[9] = vaddq_s32_dual(t[9], t[11]); - x[10] = vsubq_s32_dual(t[8], t[10]); - x[11] = vsubq_s32_dual(t[9], t[11]); - x[12] = highbd_add_dct_const_round_shift_low_8(s12, s14); - x[13] = highbd_add_dct_const_round_shift_low_8(s13, s15); - x[14] = highbd_sub_dct_const_round_shift_low_8(s12, s14); - x[15] = highbd_sub_dct_const_round_shift_low_8(s13, s15); - - // stage 4 - { - const int32x4x2_t sum = vaddq_s32_dual(x[2], x[3]); - const int32x4x2_t sub = vsubq_s32_dual(x[2], x[3]); - highbd_iadst_half_butterfly(sum, vget_low_s32(c_16_n16_8_24), 1, x[2]); - highbd_iadst_half_butterfly(sub, vget_low_s32(c_16_n16_8_24), 0, x[3]); - } - { - const int32x4x2_t sum = vaddq_s32_dual(x[7], x[6]); - const int32x4x2_t sub = vsubq_s32_dual(x[7], x[6]); - highbd_iadst_half_butterfly(sum, vget_low_s32(c_16_n16_8_24), 0, x[6]); - highbd_iadst_half_butterfly(sub, vget_low_s32(c_16_n16_8_24), 0, x[7]); - } - { - const int32x4x2_t sum = vaddq_s32_dual(x[11], x[10]); - const int32x4x2_t sub = vsubq_s32_dual(x[11], x[10]); - highbd_iadst_half_butterfly(sum, vget_low_s32(c_16_n16_8_24), 0, x[10]); - highbd_iadst_half_butterfly(sub, vget_low_s32(c_16_n16_8_24), 0, x[11]); - } - { - const int32x4x2_t sum = vaddq_s32_dual(x[14], x[15]); - const int32x4x2_t sub = vsubq_s32_dual(x[14], x[15]); - highbd_iadst_half_butterfly(sum, vget_low_s32(c_16_n16_8_24), 1, x[14]); - highbd_iadst_half_butterfly(sub, vget_low_s32(c_16_n16_8_24), 0, x[15]); - } - - out[0] = x[0]; - out[1] = vnegq_s32_dual(x[8]); - out[2] = x[12]; - out[3] = vnegq_s32_dual(x[4]); - out[4] = x[6]; - out[5] = x[14]; - out[6] = x[10]; - out[7] = x[2]; - out[8] = x[3]; - out[9] = x[11]; - out[10] = x[15]; - out[11] = x[7]; - out[12] = x[5]; - out[13] = vnegq_s32_dual(x[13]); - out[14] = x[9]; - out[15] = vnegq_s32_dual(x[1]); - - if (output) { - highbd_idct16x16_store_pass1(out, output); - } else { - highbd_idct16x16_add_store(out, dest, stride, bd); - } -} - -typedef void (*highbd_iht_1d)(const int32_t *input, int32_t *output, - uint16_t *dest, const int stride, const int bd); - -typedef struct { - highbd_iht_1d cols, rows; // vertical and horizontal -} highbd_iht_2d; - -void vp9_highbd_iht16x16_256_add_neon(const tran_low_t *input, uint16_t *dest, - int stride, int tx_type, int bd) { - if (bd == 8) { - static const iht_2d IHT_16[] = { - { vpx_idct16x16_256_add_half1d, - vpx_idct16x16_256_add_half1d }, // DCT_DCT = 0 - { vpx_iadst16x16_256_add_half1d, - vpx_idct16x16_256_add_half1d }, // ADST_DCT = 1 - { vpx_idct16x16_256_add_half1d, - vpx_iadst16x16_256_add_half1d }, // DCT_ADST = 2 - { vpx_iadst16x16_256_add_half1d, - vpx_iadst16x16_256_add_half1d } // ADST_ADST = 3 - }; - const iht_2d ht = IHT_16[tx_type]; - int16_t row_output[16 * 16]; - - // pass 1 - ht.rows(input, row_output, dest, stride, 1); // upper 8 rows - ht.rows(input + 8 * 16, row_output + 8, dest, stride, 1); // lower 8 rows - - // pass 2 - ht.cols(row_output, NULL, dest, stride, 1); // left 8 columns - ht.cols(row_output + 16 * 8, NULL, dest + 8, stride, 1); // right 8 columns - } else { - static const highbd_iht_2d IHT_16[] = { - { vpx_highbd_idct16x16_256_add_half1d, - vpx_highbd_idct16x16_256_add_half1d }, // DCT_DCT = 0 - { highbd_iadst16_neon, - vpx_highbd_idct16x16_256_add_half1d }, // ADST_DCT = 1 - { vpx_highbd_idct16x16_256_add_half1d, - highbd_iadst16_neon }, // DCT_ADST = 2 - { highbd_iadst16_neon, highbd_iadst16_neon } // ADST_ADST = 3 - }; - const highbd_iht_2d ht = IHT_16[tx_type]; - int32_t row_output[16 * 16]; - - // pass 1 - ht.rows(input, row_output, dest, stride, bd); // upper 8 rows - ht.rows(input + 8 * 16, row_output + 8, dest, stride, bd); // lower 8 rows - - // pass 2 - ht.cols(row_output, NULL, dest, stride, bd); // left 8 columns - ht.cols(row_output + 8 * 16, NULL, dest + 8, stride, - bd); // right 8 columns - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_highbd_iht4x4_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_highbd_iht4x4_add_neon.c deleted file mode 100644 index 52c4f193..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_highbd_iht4x4_add_neon.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "vp9/common/vp9_common.h" -#include "vp9/common/arm/neon/vp9_iht_neon.h" -#include "vpx_dsp/arm/highbd_idct_neon.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/txfm_common.h" - -static INLINE void highbd_iadst4(int32x4_t *const io) { - const int32_t sinpis[4] = { sinpi_1_9, sinpi_2_9, sinpi_3_9, sinpi_4_9 }; - const int32x4_t sinpi = vld1q_s32(sinpis); - int64x2x2_t s[7], t[4]; - int32x4_t s7; - - s[0].val[0] = vmull_lane_s32(vget_low_s32(io[0]), vget_low_s32(sinpi), 0); - s[0].val[1] = vmull_lane_s32(vget_high_s32(io[0]), vget_low_s32(sinpi), 0); - s[1].val[0] = vmull_lane_s32(vget_low_s32(io[0]), vget_low_s32(sinpi), 1); - s[1].val[1] = vmull_lane_s32(vget_high_s32(io[0]), vget_low_s32(sinpi), 1); - s[2].val[0] = vmull_lane_s32(vget_low_s32(io[1]), vget_high_s32(sinpi), 0); - s[2].val[1] = vmull_lane_s32(vget_high_s32(io[1]), vget_high_s32(sinpi), 0); - s[3].val[0] = vmull_lane_s32(vget_low_s32(io[2]), vget_high_s32(sinpi), 1); - s[3].val[1] = vmull_lane_s32(vget_high_s32(io[2]), vget_high_s32(sinpi), 1); - s[4].val[0] = vmull_lane_s32(vget_low_s32(io[2]), vget_low_s32(sinpi), 0); - s[4].val[1] = vmull_lane_s32(vget_high_s32(io[2]), vget_low_s32(sinpi), 0); - s[5].val[0] = vmull_lane_s32(vget_low_s32(io[3]), vget_low_s32(sinpi), 1); - s[5].val[1] = vmull_lane_s32(vget_high_s32(io[3]), vget_low_s32(sinpi), 1); - s[6].val[0] = vmull_lane_s32(vget_low_s32(io[3]), vget_high_s32(sinpi), 1); - s[6].val[1] = vmull_lane_s32(vget_high_s32(io[3]), vget_high_s32(sinpi), 1); - s7 = vsubq_s32(io[0], io[2]); - s7 = vaddq_s32(s7, io[3]); - - s[0].val[0] = vaddq_s64(s[0].val[0], s[3].val[0]); - s[0].val[1] = vaddq_s64(s[0].val[1], s[3].val[1]); - s[0].val[0] = vaddq_s64(s[0].val[0], s[5].val[0]); - s[0].val[1] = vaddq_s64(s[0].val[1], s[5].val[1]); - s[1].val[0] = vsubq_s64(s[1].val[0], s[4].val[0]); - s[1].val[1] = vsubq_s64(s[1].val[1], s[4].val[1]); - s[1].val[0] = vsubq_s64(s[1].val[0], s[6].val[0]); - s[1].val[1] = vsubq_s64(s[1].val[1], s[6].val[1]); - s[3] = s[2]; - s[2].val[0] = vmull_lane_s32(vget_low_s32(s7), vget_high_s32(sinpi), 0); - s[2].val[1] = vmull_lane_s32(vget_high_s32(s7), vget_high_s32(sinpi), 0); - - t[0].val[0] = vaddq_s64(s[0].val[0], s[3].val[0]); - t[0].val[1] = vaddq_s64(s[0].val[1], s[3].val[1]); - t[1].val[0] = vaddq_s64(s[1].val[0], s[3].val[0]); - t[1].val[1] = vaddq_s64(s[1].val[1], s[3].val[1]); - t[2] = s[2]; - t[3].val[0] = vaddq_s64(s[0].val[0], s[1].val[0]); - t[3].val[1] = vaddq_s64(s[0].val[1], s[1].val[1]); - t[3].val[0] = vsubq_s64(t[3].val[0], s[3].val[0]); - t[3].val[1] = vsubq_s64(t[3].val[1], s[3].val[1]); - io[0] = vcombine_s32(vrshrn_n_s64(t[0].val[0], DCT_CONST_BITS), - vrshrn_n_s64(t[0].val[1], DCT_CONST_BITS)); - io[1] = vcombine_s32(vrshrn_n_s64(t[1].val[0], DCT_CONST_BITS), - vrshrn_n_s64(t[1].val[1], DCT_CONST_BITS)); - io[2] = vcombine_s32(vrshrn_n_s64(t[2].val[0], DCT_CONST_BITS), - vrshrn_n_s64(t[2].val[1], DCT_CONST_BITS)); - io[3] = vcombine_s32(vrshrn_n_s64(t[3].val[0], DCT_CONST_BITS), - vrshrn_n_s64(t[3].val[1], DCT_CONST_BITS)); -} - -void vp9_highbd_iht4x4_16_add_neon(const tran_low_t *input, uint16_t *dest, - int stride, int tx_type, int bd) { - const int16x8_t max = vdupq_n_s16((1 << bd) - 1); - int16x8_t a[2]; - int32x4_t c[4]; - - c[0] = vld1q_s32(input); - c[1] = vld1q_s32(input + 4); - c[2] = vld1q_s32(input + 8); - c[3] = vld1q_s32(input + 12); - - if (bd == 8) { - a[0] = vcombine_s16(vmovn_s32(c[0]), vmovn_s32(c[1])); - a[1] = vcombine_s16(vmovn_s32(c[2]), vmovn_s32(c[3])); - transpose_s16_4x4q(&a[0], &a[1]); - - switch (tx_type) { - case DCT_DCT: - idct4x4_16_kernel_bd8(a); - a[1] = vcombine_s16(vget_high_s16(a[1]), vget_low_s16(a[1])); - transpose_s16_4x4q(&a[0], &a[1]); - idct4x4_16_kernel_bd8(a); - a[1] = vcombine_s16(vget_high_s16(a[1]), vget_low_s16(a[1])); - break; - - case ADST_DCT: - idct4x4_16_kernel_bd8(a); - a[1] = vcombine_s16(vget_high_s16(a[1]), vget_low_s16(a[1])); - transpose_s16_4x4q(&a[0], &a[1]); - iadst4(a); - break; - - case DCT_ADST: - iadst4(a); - transpose_s16_4x4q(&a[0], &a[1]); - idct4x4_16_kernel_bd8(a); - a[1] = vcombine_s16(vget_high_s16(a[1]), vget_low_s16(a[1])); - break; - - default: - assert(tx_type == ADST_ADST); - iadst4(a); - transpose_s16_4x4q(&a[0], &a[1]); - iadst4(a); - break; - } - a[0] = vrshrq_n_s16(a[0], 4); - a[1] = vrshrq_n_s16(a[1], 4); - } else { - switch (tx_type) { - case DCT_DCT: { - const int32x4_t cospis = vld1q_s32(kCospi32); - - if (bd == 10) { - idct4x4_16_kernel_bd10(cospis, c); - idct4x4_16_kernel_bd10(cospis, c); - } else { - idct4x4_16_kernel_bd12(cospis, c); - idct4x4_16_kernel_bd12(cospis, c); - } - break; - } - - case ADST_DCT: { - const int32x4_t cospis = vld1q_s32(kCospi32); - - if (bd == 10) { - idct4x4_16_kernel_bd10(cospis, c); - } else { - idct4x4_16_kernel_bd12(cospis, c); - } - transpose_s32_4x4(&c[0], &c[1], &c[2], &c[3]); - highbd_iadst4(c); - break; - } - - case DCT_ADST: { - const int32x4_t cospis = vld1q_s32(kCospi32); - - transpose_s32_4x4(&c[0], &c[1], &c[2], &c[3]); - highbd_iadst4(c); - if (bd == 10) { - idct4x4_16_kernel_bd10(cospis, c); - } else { - idct4x4_16_kernel_bd12(cospis, c); - } - break; - } - - default: { - assert(tx_type == ADST_ADST); - transpose_s32_4x4(&c[0], &c[1], &c[2], &c[3]); - highbd_iadst4(c); - transpose_s32_4x4(&c[0], &c[1], &c[2], &c[3]); - highbd_iadst4(c); - break; - } - } - a[0] = vcombine_s16(vqrshrn_n_s32(c[0], 4), vqrshrn_n_s32(c[1], 4)); - a[1] = vcombine_s16(vqrshrn_n_s32(c[2], 4), vqrshrn_n_s32(c[3], 4)); - } - - highbd_idct4x4_1_add_kernel1(&dest, stride, a[0], max); - highbd_idct4x4_1_add_kernel1(&dest, stride, a[1], max); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_highbd_iht8x8_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_highbd_iht8x8_add_neon.c deleted file mode 100644 index 2232c684..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_highbd_iht8x8_add_neon.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vp9/common/vp9_enums.h" -#include "vp9/common/arm/neon/vp9_iht_neon.h" -#include "vpx_dsp/arm/highbd_idct_neon.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/inv_txfm.h" - -static INLINE void highbd_iadst_half_butterfly_neon(int32x4_t *const x, - const int32x2_t c) { - const int32x4_t sum = vaddq_s32(x[0], x[1]); - const int32x4_t sub = vsubq_s32(x[0], x[1]); - const int64x2_t t0_lo = vmull_lane_s32(vget_low_s32(sum), c, 0); - const int64x2_t t1_lo = vmull_lane_s32(vget_low_s32(sub), c, 0); - const int64x2_t t0_hi = vmull_lane_s32(vget_high_s32(sum), c, 0); - const int64x2_t t1_hi = vmull_lane_s32(vget_high_s32(sub), c, 0); - const int32x2_t out0_lo = vrshrn_n_s64(t0_lo, DCT_CONST_BITS); - const int32x2_t out1_lo = vrshrn_n_s64(t1_lo, DCT_CONST_BITS); - const int32x2_t out0_hi = vrshrn_n_s64(t0_hi, DCT_CONST_BITS); - const int32x2_t out1_hi = vrshrn_n_s64(t1_hi, DCT_CONST_BITS); - - x[0] = vcombine_s32(out0_lo, out0_hi); - x[1] = vcombine_s32(out1_lo, out1_hi); -} - -static INLINE void highbd_iadst_butterfly_lane_0_1_neon(const int32x4_t in0, - const int32x4_t in1, - const int32x2_t c, - int64x2_t *const s0, - int64x2_t *const s1) { - const int64x2_t t0_lo = vmull_lane_s32(vget_low_s32(in0), c, 0); - const int64x2_t t1_lo = vmull_lane_s32(vget_low_s32(in0), c, 1); - const int64x2_t t0_hi = vmull_lane_s32(vget_high_s32(in0), c, 0); - const int64x2_t t1_hi = vmull_lane_s32(vget_high_s32(in0), c, 1); - - s0[0] = vmlal_lane_s32(t0_lo, vget_low_s32(in1), c, 1); - s1[0] = vmlsl_lane_s32(t1_lo, vget_low_s32(in1), c, 0); - s0[1] = vmlal_lane_s32(t0_hi, vget_high_s32(in1), c, 1); - s1[1] = vmlsl_lane_s32(t1_hi, vget_high_s32(in1), c, 0); -} - -static INLINE void highbd_iadst_butterfly_lane_1_0_neon(const int32x4_t in0, - const int32x4_t in1, - const int32x2_t c, - int64x2_t *const s0, - int64x2_t *const s1) { - const int64x2_t t0_lo = vmull_lane_s32(vget_low_s32(in0), c, 1); - const int64x2_t t1_lo = vmull_lane_s32(vget_low_s32(in0), c, 0); - const int64x2_t t0_hi = vmull_lane_s32(vget_high_s32(in0), c, 1); - const int64x2_t t1_hi = vmull_lane_s32(vget_high_s32(in0), c, 0); - - s0[0] = vmlal_lane_s32(t0_lo, vget_low_s32(in1), c, 0); - s1[0] = vmlsl_lane_s32(t1_lo, vget_low_s32(in1), c, 1); - s0[1] = vmlal_lane_s32(t0_hi, vget_high_s32(in1), c, 0); - s1[1] = vmlsl_lane_s32(t1_hi, vget_high_s32(in1), c, 1); -} - -static INLINE int32x4_t highbd_add_dct_const_round_shift_low_8( - const int64x2_t *const in0, const int64x2_t *const in1) { - const int64x2_t sum_lo = vaddq_s64(in0[0], in1[0]); - const int64x2_t sum_hi = vaddq_s64(in0[1], in1[1]); - const int32x2_t out_lo = vrshrn_n_s64(sum_lo, DCT_CONST_BITS); - const int32x2_t out_hi = vrshrn_n_s64(sum_hi, DCT_CONST_BITS); - return vcombine_s32(out_lo, out_hi); -} - -static INLINE int32x4_t highbd_sub_dct_const_round_shift_low_8( - const int64x2_t *const in0, const int64x2_t *const in1) { - const int64x2_t sub_lo = vsubq_s64(in0[0], in1[0]); - const int64x2_t sub_hi = vsubq_s64(in0[1], in1[1]); - const int32x2_t out_lo = vrshrn_n_s64(sub_lo, DCT_CONST_BITS); - const int32x2_t out_hi = vrshrn_n_s64(sub_hi, DCT_CONST_BITS); - return vcombine_s32(out_lo, out_hi); -} - -static INLINE void highbd_iadst8(int32x4_t *const io0, int32x4_t *const io1, - int32x4_t *const io2, int32x4_t *const io3, - int32x4_t *const io4, int32x4_t *const io5, - int32x4_t *const io6, int32x4_t *const io7) { - const int32x4_t c0 = - create_s32x4_neon(cospi_2_64, cospi_30_64, cospi_10_64, cospi_22_64); - const int32x4_t c1 = - create_s32x4_neon(cospi_18_64, cospi_14_64, cospi_26_64, cospi_6_64); - const int32x4_t c2 = - create_s32x4_neon(cospi_16_64, 0, cospi_8_64, cospi_24_64); - int32x4_t x[8], t[4]; - int64x2_t s[8][2]; - - x[0] = *io7; - x[1] = *io0; - x[2] = *io5; - x[3] = *io2; - x[4] = *io3; - x[5] = *io4; - x[6] = *io1; - x[7] = *io6; - - // stage 1 - highbd_iadst_butterfly_lane_0_1_neon(x[0], x[1], vget_low_s32(c0), s[0], - s[1]); - highbd_iadst_butterfly_lane_0_1_neon(x[2], x[3], vget_high_s32(c0), s[2], - s[3]); - highbd_iadst_butterfly_lane_0_1_neon(x[4], x[5], vget_low_s32(c1), s[4], - s[5]); - highbd_iadst_butterfly_lane_0_1_neon(x[6], x[7], vget_high_s32(c1), s[6], - s[7]); - - x[0] = highbd_add_dct_const_round_shift_low_8(s[0], s[4]); - x[1] = highbd_add_dct_const_round_shift_low_8(s[1], s[5]); - x[2] = highbd_add_dct_const_round_shift_low_8(s[2], s[6]); - x[3] = highbd_add_dct_const_round_shift_low_8(s[3], s[7]); - x[4] = highbd_sub_dct_const_round_shift_low_8(s[0], s[4]); - x[5] = highbd_sub_dct_const_round_shift_low_8(s[1], s[5]); - x[6] = highbd_sub_dct_const_round_shift_low_8(s[2], s[6]); - x[7] = highbd_sub_dct_const_round_shift_low_8(s[3], s[7]); - - // stage 2 - t[0] = x[0]; - t[1] = x[1]; - t[2] = x[2]; - t[3] = x[3]; - highbd_iadst_butterfly_lane_0_1_neon(x[4], x[5], vget_high_s32(c2), s[4], - s[5]); - highbd_iadst_butterfly_lane_1_0_neon(x[7], x[6], vget_high_s32(c2), s[7], - s[6]); - - x[0] = vaddq_s32(t[0], t[2]); - x[1] = vaddq_s32(t[1], t[3]); - x[2] = vsubq_s32(t[0], t[2]); - x[3] = vsubq_s32(t[1], t[3]); - x[4] = highbd_add_dct_const_round_shift_low_8(s[4], s[6]); - x[5] = highbd_add_dct_const_round_shift_low_8(s[5], s[7]); - x[6] = highbd_sub_dct_const_round_shift_low_8(s[4], s[6]); - x[7] = highbd_sub_dct_const_round_shift_low_8(s[5], s[7]); - - // stage 3 - highbd_iadst_half_butterfly_neon(x + 2, vget_low_s32(c2)); - highbd_iadst_half_butterfly_neon(x + 6, vget_low_s32(c2)); - - *io0 = x[0]; - *io1 = vnegq_s32(x[4]); - *io2 = x[6]; - *io3 = vnegq_s32(x[2]); - *io4 = x[3]; - *io5 = vnegq_s32(x[7]); - *io6 = x[5]; - *io7 = vnegq_s32(x[1]); -} - -void vp9_highbd_iht8x8_64_add_neon(const tran_low_t *input, uint16_t *dest, - int stride, int tx_type, int bd) { - int32x4_t a[16]; - int16x8_t c[8]; - - a[0] = vld1q_s32(input); - a[1] = vld1q_s32(input + 4); - a[2] = vld1q_s32(input + 8); - a[3] = vld1q_s32(input + 12); - a[4] = vld1q_s32(input + 16); - a[5] = vld1q_s32(input + 20); - a[6] = vld1q_s32(input + 24); - a[7] = vld1q_s32(input + 28); - a[8] = vld1q_s32(input + 32); - a[9] = vld1q_s32(input + 36); - a[10] = vld1q_s32(input + 40); - a[11] = vld1q_s32(input + 44); - a[12] = vld1q_s32(input + 48); - a[13] = vld1q_s32(input + 52); - a[14] = vld1q_s32(input + 56); - a[15] = vld1q_s32(input + 60); - - if (bd == 8) { - c[0] = vcombine_s16(vmovn_s32(a[0]), vmovn_s32(a[1])); - c[1] = vcombine_s16(vmovn_s32(a[2]), vmovn_s32(a[3])); - c[2] = vcombine_s16(vmovn_s32(a[4]), vmovn_s32(a[5])); - c[3] = vcombine_s16(vmovn_s32(a[6]), vmovn_s32(a[7])); - c[4] = vcombine_s16(vmovn_s32(a[8]), vmovn_s32(a[9])); - c[5] = vcombine_s16(vmovn_s32(a[10]), vmovn_s32(a[11])); - c[6] = vcombine_s16(vmovn_s32(a[12]), vmovn_s32(a[13])); - c[7] = vcombine_s16(vmovn_s32(a[14]), vmovn_s32(a[15])); - - switch (tx_type) { - case DCT_DCT: { - const int16x8_t cospis = vld1q_s16(kCospi); - const int16x4_t cospis0 = vget_low_s16(cospis); // cospi 0, 8, 16, 24 - const int16x4_t cospis1 = vget_high_s16(cospis); // cospi 4, 12, 20, 28 - - idct8x8_64_1d_bd8(cospis0, cospis1, c); - idct8x8_64_1d_bd8(cospis0, cospis1, c); - break; - } - - case ADST_DCT: { - const int16x8_t cospis = vld1q_s16(kCospi); - const int16x4_t cospis0 = vget_low_s16(cospis); // cospi 0, 8, 16, 24 - const int16x4_t cospis1 = vget_high_s16(cospis); // cospi 4, 12, 20, 28 - - idct8x8_64_1d_bd8(cospis0, cospis1, c); - transpose_s16_8x8(&c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], - &c[7]); - iadst8(c); - break; - } - - case DCT_ADST: { - const int16x8_t cospis = vld1q_s16(kCospi); - const int16x4_t cospis0 = vget_low_s16(cospis); // cospi 0, 8, 16, 24 - const int16x4_t cospis1 = vget_high_s16(cospis); // cospi 4, 12, 20, 28 - - transpose_s16_8x8(&c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], - &c[7]); - iadst8(c); - idct8x8_64_1d_bd8(cospis0, cospis1, c); - break; - } - - default: { - transpose_s16_8x8(&c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], - &c[7]); - iadst8(c); - transpose_s16_8x8(&c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], - &c[7]); - iadst8(c); - break; - } - } - - c[0] = vrshrq_n_s16(c[0], 5); - c[1] = vrshrq_n_s16(c[1], 5); - c[2] = vrshrq_n_s16(c[2], 5); - c[3] = vrshrq_n_s16(c[3], 5); - c[4] = vrshrq_n_s16(c[4], 5); - c[5] = vrshrq_n_s16(c[5], 5); - c[6] = vrshrq_n_s16(c[6], 5); - c[7] = vrshrq_n_s16(c[7], 5); - } else { - switch (tx_type) { - case DCT_DCT: { - const int32x4_t cospis0 = vld1q_s32(kCospi32); // cospi 0, 8, 16, 24 - const int32x4_t cospis1 = - vld1q_s32(kCospi32 + 4); // cospi 4, 12, 20, 28 - - if (bd == 10) { - idct8x8_64_half1d_bd10(cospis0, cospis1, &a[0], &a[1], &a[2], &a[3], - &a[4], &a[5], &a[6], &a[7]); - idct8x8_64_half1d_bd10(cospis0, cospis1, &a[8], &a[9], &a[10], &a[11], - &a[12], &a[13], &a[14], &a[15]); - idct8x8_64_half1d_bd10(cospis0, cospis1, &a[0], &a[8], &a[1], &a[9], - &a[2], &a[10], &a[3], &a[11]); - idct8x8_64_half1d_bd10(cospis0, cospis1, &a[4], &a[12], &a[5], &a[13], - &a[6], &a[14], &a[7], &a[15]); - } else { - idct8x8_64_half1d_bd12(cospis0, cospis1, &a[0], &a[1], &a[2], &a[3], - &a[4], &a[5], &a[6], &a[7]); - idct8x8_64_half1d_bd12(cospis0, cospis1, &a[8], &a[9], &a[10], &a[11], - &a[12], &a[13], &a[14], &a[15]); - idct8x8_64_half1d_bd12(cospis0, cospis1, &a[0], &a[8], &a[1], &a[9], - &a[2], &a[10], &a[3], &a[11]); - idct8x8_64_half1d_bd12(cospis0, cospis1, &a[4], &a[12], &a[5], &a[13], - &a[6], &a[14], &a[7], &a[15]); - } - break; - } - - case ADST_DCT: { - const int32x4_t cospis0 = vld1q_s32(kCospi32); // cospi 0, 8, 16, 24 - const int32x4_t cospis1 = - vld1q_s32(kCospi32 + 4); // cospi 4, 12, 20, 28 - - idct8x8_64_half1d_bd12(cospis0, cospis1, &a[0], &a[1], &a[2], &a[3], - &a[4], &a[5], &a[6], &a[7]); - idct8x8_64_half1d_bd12(cospis0, cospis1, &a[8], &a[9], &a[10], &a[11], - &a[12], &a[13], &a[14], &a[15]); - transpose_s32_8x4(&a[0], &a[8], &a[1], &a[9], &a[2], &a[10], &a[3], - &a[11]); - highbd_iadst8(&a[0], &a[8], &a[1], &a[9], &a[2], &a[10], &a[3], &a[11]); - transpose_s32_8x4(&a[4], &a[12], &a[5], &a[13], &a[6], &a[14], &a[7], - &a[15]); - highbd_iadst8(&a[4], &a[12], &a[5], &a[13], &a[6], &a[14], &a[7], - &a[15]); - break; - } - - case DCT_ADST: { - const int32x4_t cospis0 = vld1q_s32(kCospi32); // cospi 0, 8, 16, 24 - const int32x4_t cospis1 = - vld1q_s32(kCospi32 + 4); // cospi 4, 12, 20, 28 - - transpose_s32_8x4(&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], - &a[7]); - highbd_iadst8(&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7]); - transpose_s32_8x4(&a[8], &a[9], &a[10], &a[11], &a[12], &a[13], &a[14], - &a[15]); - highbd_iadst8(&a[8], &a[9], &a[10], &a[11], &a[12], &a[13], &a[14], - &a[15]); - idct8x8_64_half1d_bd12(cospis0, cospis1, &a[0], &a[8], &a[1], &a[9], - &a[2], &a[10], &a[3], &a[11]); - idct8x8_64_half1d_bd12(cospis0, cospis1, &a[4], &a[12], &a[5], &a[13], - &a[6], &a[14], &a[7], &a[15]); - break; - } - - default: { - assert(tx_type == ADST_ADST); - transpose_s32_8x4(&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], - &a[7]); - highbd_iadst8(&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7]); - transpose_s32_8x4(&a[8], &a[9], &a[10], &a[11], &a[12], &a[13], &a[14], - &a[15]); - highbd_iadst8(&a[8], &a[9], &a[10], &a[11], &a[12], &a[13], &a[14], - &a[15]); - transpose_s32_8x4(&a[0], &a[8], &a[1], &a[9], &a[2], &a[10], &a[3], - &a[11]); - highbd_iadst8(&a[0], &a[8], &a[1], &a[9], &a[2], &a[10], &a[3], &a[11]); - transpose_s32_8x4(&a[4], &a[12], &a[5], &a[13], &a[6], &a[14], &a[7], - &a[15]); - highbd_iadst8(&a[4], &a[12], &a[5], &a[13], &a[6], &a[14], &a[7], - &a[15]); - break; - } - } - - c[0] = vcombine_s16(vrshrn_n_s32(a[0], 5), vrshrn_n_s32(a[4], 5)); - c[1] = vcombine_s16(vrshrn_n_s32(a[8], 5), vrshrn_n_s32(a[12], 5)); - c[2] = vcombine_s16(vrshrn_n_s32(a[1], 5), vrshrn_n_s32(a[5], 5)); - c[3] = vcombine_s16(vrshrn_n_s32(a[9], 5), vrshrn_n_s32(a[13], 5)); - c[4] = vcombine_s16(vrshrn_n_s32(a[2], 5), vrshrn_n_s32(a[6], 5)); - c[5] = vcombine_s16(vrshrn_n_s32(a[10], 5), vrshrn_n_s32(a[14], 5)); - c[6] = vcombine_s16(vrshrn_n_s32(a[3], 5), vrshrn_n_s32(a[7], 5)); - c[7] = vcombine_s16(vrshrn_n_s32(a[11], 5), vrshrn_n_s32(a[15], 5)); - } - highbd_add8x8(c, dest, stride, bd); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_iht16x16_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_iht16x16_add_neon.c deleted file mode 100644 index db72ff11..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_iht16x16_add_neon.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "vp9/common/vp9_common.h" -#include "vp9/common/arm/neon/vp9_iht_neon.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" - -void vpx_iadst16x16_256_add_half1d(const void *const input, int16_t *output, - void *const dest, const int stride, - const int highbd_flag) { - int16x8_t in[16], out[16]; - const int16x4_t c_1_31_5_27 = - create_s16x4_neon(cospi_1_64, cospi_31_64, cospi_5_64, cospi_27_64); - const int16x4_t c_9_23_13_19 = - create_s16x4_neon(cospi_9_64, cospi_23_64, cospi_13_64, cospi_19_64); - const int16x4_t c_17_15_21_11 = - create_s16x4_neon(cospi_17_64, cospi_15_64, cospi_21_64, cospi_11_64); - const int16x4_t c_25_7_29_3 = - create_s16x4_neon(cospi_25_64, cospi_7_64, cospi_29_64, cospi_3_64); - const int16x4_t c_4_28_20_12 = - create_s16x4_neon(cospi_4_64, cospi_28_64, cospi_20_64, cospi_12_64); - const int16x4_t c_16_n16_8_24 = - create_s16x4_neon(cospi_16_64, -cospi_16_64, cospi_8_64, cospi_24_64); - int16x8_t x[16], t[12]; - int32x4_t s0[2], s1[2], s2[2], s3[2], s4[2], s5[2], s6[2], s7[2]; - int32x4_t s8[2], s9[2], s10[2], s11[2], s12[2], s13[2], s14[2], s15[2]; - - // Load input (16x8) - if (output) { - const tran_low_t *inputT = (const tran_low_t *)input; - in[0] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[8] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[1] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[9] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[2] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[10] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[3] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[11] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[4] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[12] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[5] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[13] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[6] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[14] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[7] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[15] = load_tran_low_to_s16q(inputT); - } else { - const int16_t *inputT = (const int16_t *)input; - in[0] = vld1q_s16(inputT); - inputT += 8; - in[8] = vld1q_s16(inputT); - inputT += 8; - in[1] = vld1q_s16(inputT); - inputT += 8; - in[9] = vld1q_s16(inputT); - inputT += 8; - in[2] = vld1q_s16(inputT); - inputT += 8; - in[10] = vld1q_s16(inputT); - inputT += 8; - in[3] = vld1q_s16(inputT); - inputT += 8; - in[11] = vld1q_s16(inputT); - inputT += 8; - in[4] = vld1q_s16(inputT); - inputT += 8; - in[12] = vld1q_s16(inputT); - inputT += 8; - in[5] = vld1q_s16(inputT); - inputT += 8; - in[13] = vld1q_s16(inputT); - inputT += 8; - in[6] = vld1q_s16(inputT); - inputT += 8; - in[14] = vld1q_s16(inputT); - inputT += 8; - in[7] = vld1q_s16(inputT); - inputT += 8; - in[15] = vld1q_s16(inputT); - } - - // Transpose - transpose_s16_8x8(&in[0], &in[1], &in[2], &in[3], &in[4], &in[5], &in[6], - &in[7]); - transpose_s16_8x8(&in[8], &in[9], &in[10], &in[11], &in[12], &in[13], &in[14], - &in[15]); - - x[0] = in[15]; - x[1] = in[0]; - x[2] = in[13]; - x[3] = in[2]; - x[4] = in[11]; - x[5] = in[4]; - x[6] = in[9]; - x[7] = in[6]; - x[8] = in[7]; - x[9] = in[8]; - x[10] = in[5]; - x[11] = in[10]; - x[12] = in[3]; - x[13] = in[12]; - x[14] = in[1]; - x[15] = in[14]; - - // stage 1 - iadst_butterfly_lane_0_1_neon(x[0], x[1], c_1_31_5_27, s0, s1); - iadst_butterfly_lane_2_3_neon(x[2], x[3], c_1_31_5_27, s2, s3); - iadst_butterfly_lane_0_1_neon(x[4], x[5], c_9_23_13_19, s4, s5); - iadst_butterfly_lane_2_3_neon(x[6], x[7], c_9_23_13_19, s6, s7); - iadst_butterfly_lane_0_1_neon(x[8], x[9], c_17_15_21_11, s8, s9); - iadst_butterfly_lane_2_3_neon(x[10], x[11], c_17_15_21_11, s10, s11); - iadst_butterfly_lane_0_1_neon(x[12], x[13], c_25_7_29_3, s12, s13); - iadst_butterfly_lane_2_3_neon(x[14], x[15], c_25_7_29_3, s14, s15); - - x[0] = add_dct_const_round_shift_low_8(s0, s8); - x[1] = add_dct_const_round_shift_low_8(s1, s9); - x[2] = add_dct_const_round_shift_low_8(s2, s10); - x[3] = add_dct_const_round_shift_low_8(s3, s11); - x[4] = add_dct_const_round_shift_low_8(s4, s12); - x[5] = add_dct_const_round_shift_low_8(s5, s13); - x[6] = add_dct_const_round_shift_low_8(s6, s14); - x[7] = add_dct_const_round_shift_low_8(s7, s15); - x[8] = sub_dct_const_round_shift_low_8(s0, s8); - x[9] = sub_dct_const_round_shift_low_8(s1, s9); - x[10] = sub_dct_const_round_shift_low_8(s2, s10); - x[11] = sub_dct_const_round_shift_low_8(s3, s11); - x[12] = sub_dct_const_round_shift_low_8(s4, s12); - x[13] = sub_dct_const_round_shift_low_8(s5, s13); - x[14] = sub_dct_const_round_shift_low_8(s6, s14); - x[15] = sub_dct_const_round_shift_low_8(s7, s15); - - // stage 2 - t[0] = x[0]; - t[1] = x[1]; - t[2] = x[2]; - t[3] = x[3]; - t[4] = x[4]; - t[5] = x[5]; - t[6] = x[6]; - t[7] = x[7]; - iadst_butterfly_lane_0_1_neon(x[8], x[9], c_4_28_20_12, s8, s9); - iadst_butterfly_lane_2_3_neon(x[10], x[11], c_4_28_20_12, s10, s11); - iadst_butterfly_lane_1_0_neon(x[13], x[12], c_4_28_20_12, s13, s12); - iadst_butterfly_lane_3_2_neon(x[15], x[14], c_4_28_20_12, s15, s14); - - x[0] = vaddq_s16(t[0], t[4]); - x[1] = vaddq_s16(t[1], t[5]); - x[2] = vaddq_s16(t[2], t[6]); - x[3] = vaddq_s16(t[3], t[7]); - x[4] = vsubq_s16(t[0], t[4]); - x[5] = vsubq_s16(t[1], t[5]); - x[6] = vsubq_s16(t[2], t[6]); - x[7] = vsubq_s16(t[3], t[7]); - x[8] = add_dct_const_round_shift_low_8(s8, s12); - x[9] = add_dct_const_round_shift_low_8(s9, s13); - x[10] = add_dct_const_round_shift_low_8(s10, s14); - x[11] = add_dct_const_round_shift_low_8(s11, s15); - x[12] = sub_dct_const_round_shift_low_8(s8, s12); - x[13] = sub_dct_const_round_shift_low_8(s9, s13); - x[14] = sub_dct_const_round_shift_low_8(s10, s14); - x[15] = sub_dct_const_round_shift_low_8(s11, s15); - - // stage 3 - t[0] = x[0]; - t[1] = x[1]; - t[2] = x[2]; - t[3] = x[3]; - iadst_butterfly_lane_2_3_neon(x[4], x[5], c_16_n16_8_24, s4, s5); - iadst_butterfly_lane_3_2_neon(x[7], x[6], c_16_n16_8_24, s7, s6); - t[8] = x[8]; - t[9] = x[9]; - t[10] = x[10]; - t[11] = x[11]; - iadst_butterfly_lane_2_3_neon(x[12], x[13], c_16_n16_8_24, s12, s13); - iadst_butterfly_lane_3_2_neon(x[15], x[14], c_16_n16_8_24, s15, s14); - - x[0] = vaddq_s16(t[0], t[2]); - x[1] = vaddq_s16(t[1], t[3]); - x[2] = vsubq_s16(t[0], t[2]); - x[3] = vsubq_s16(t[1], t[3]); - x[4] = add_dct_const_round_shift_low_8(s4, s6); - x[5] = add_dct_const_round_shift_low_8(s5, s7); - x[6] = sub_dct_const_round_shift_low_8(s4, s6); - x[7] = sub_dct_const_round_shift_low_8(s5, s7); - x[8] = vaddq_s16(t[8], t[10]); - x[9] = vaddq_s16(t[9], t[11]); - x[10] = vsubq_s16(t[8], t[10]); - x[11] = vsubq_s16(t[9], t[11]); - x[12] = add_dct_const_round_shift_low_8(s12, s14); - x[13] = add_dct_const_round_shift_low_8(s13, s15); - x[14] = sub_dct_const_round_shift_low_8(s12, s14); - x[15] = sub_dct_const_round_shift_low_8(s13, s15); - - // stage 4 - iadst_half_butterfly_neg_neon(&x[3], &x[2], c_16_n16_8_24); - iadst_half_butterfly_pos_neon(&x[7], &x[6], c_16_n16_8_24); - iadst_half_butterfly_pos_neon(&x[11], &x[10], c_16_n16_8_24); - iadst_half_butterfly_neg_neon(&x[15], &x[14], c_16_n16_8_24); - - out[0] = x[0]; - out[1] = vnegq_s16(x[8]); - out[2] = x[12]; - out[3] = vnegq_s16(x[4]); - out[4] = x[6]; - out[5] = x[14]; - out[6] = x[10]; - out[7] = x[2]; - out[8] = x[3]; - out[9] = x[11]; - out[10] = x[15]; - out[11] = x[7]; - out[12] = x[5]; - out[13] = vnegq_s16(x[13]); - out[14] = x[9]; - out[15] = vnegq_s16(x[1]); - - if (output) { - idct16x16_store_pass1(out, output); - } else { - if (highbd_flag) { - idct16x16_add_store_bd8(out, dest, stride); - } else { - idct16x16_add_store(out, dest, stride); - } - } -} - -void vp9_iht16x16_256_add_neon(const tran_low_t *input, uint8_t *dest, - int stride, int tx_type) { - static const iht_2d IHT_16[] = { - { vpx_idct16x16_256_add_half1d, - vpx_idct16x16_256_add_half1d }, // DCT_DCT = 0 - { vpx_iadst16x16_256_add_half1d, - vpx_idct16x16_256_add_half1d }, // ADST_DCT = 1 - { vpx_idct16x16_256_add_half1d, - vpx_iadst16x16_256_add_half1d }, // DCT_ADST = 2 - { vpx_iadst16x16_256_add_half1d, - vpx_iadst16x16_256_add_half1d } // ADST_ADST = 3 - }; - const iht_2d ht = IHT_16[tx_type]; - int16_t row_output[16 * 16]; - - // pass 1 - ht.rows(input, row_output, dest, stride, 0); // upper 8 rows - ht.rows(input + 8 * 16, row_output + 8, dest, stride, 0); // lower 8 rows - - // pass 2 - ht.cols(row_output, NULL, dest, stride, 0); // left 8 columns - ht.cols(row_output + 16 * 8, NULL, dest + 8, stride, 0); // right 8 columns -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_iht4x4_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_iht4x4_add_neon.c deleted file mode 100644 index 4f0a90f2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_iht4x4_add_neon.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "vp9/common/vp9_common.h" -#include "vp9/common/arm/neon/vp9_iht_neon.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/txfm_common.h" - -void vp9_iht4x4_16_add_neon(const tran_low_t *input, uint8_t *dest, int stride, - int tx_type) { - int16x8_t a[2]; - uint8x8_t s[2], d[2]; - uint16x8_t sum[2]; - - assert(!((intptr_t)dest % sizeof(uint32_t))); - assert(!(stride % sizeof(uint32_t))); - - a[0] = load_tran_low_to_s16q(input); - a[1] = load_tran_low_to_s16q(input + 8); - transpose_s16_4x4q(&a[0], &a[1]); - - switch (tx_type) { - case DCT_DCT: - idct4x4_16_kernel_bd8(a); - a[1] = vcombine_s16(vget_high_s16(a[1]), vget_low_s16(a[1])); - transpose_s16_4x4q(&a[0], &a[1]); - idct4x4_16_kernel_bd8(a); - a[1] = vcombine_s16(vget_high_s16(a[1]), vget_low_s16(a[1])); - break; - - case ADST_DCT: - idct4x4_16_kernel_bd8(a); - a[1] = vcombine_s16(vget_high_s16(a[1]), vget_low_s16(a[1])); - transpose_s16_4x4q(&a[0], &a[1]); - iadst4(a); - break; - - case DCT_ADST: - iadst4(a); - transpose_s16_4x4q(&a[0], &a[1]); - idct4x4_16_kernel_bd8(a); - a[1] = vcombine_s16(vget_high_s16(a[1]), vget_low_s16(a[1])); - break; - - default: - assert(tx_type == ADST_ADST); - iadst4(a); - transpose_s16_4x4q(&a[0], &a[1]); - iadst4(a); - break; - } - - a[0] = vrshrq_n_s16(a[0], 4); - a[1] = vrshrq_n_s16(a[1], 4); - s[0] = load_u8(dest, stride); - s[1] = load_u8(dest + 2 * stride, stride); - sum[0] = vaddw_u8(vreinterpretq_u16_s16(a[0]), s[0]); - sum[1] = vaddw_u8(vreinterpretq_u16_s16(a[1]), s[1]); - d[0] = vqmovun_s16(vreinterpretq_s16_u16(sum[0])); - d[1] = vqmovun_s16(vreinterpretq_s16_u16(sum[1])); - store_u8(dest, stride, d[0]); - store_u8(dest + 2 * stride, stride, d[1]); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_iht8x8_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_iht8x8_add_neon.c deleted file mode 100644 index 46ee632e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_iht8x8_add_neon.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "vp9/common/vp9_common.h" -#include "vp9/common/arm/neon/vp9_iht_neon.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" - -void vp9_iht8x8_64_add_neon(const tran_low_t *input, uint8_t *dest, int stride, - int tx_type) { - const int16x8_t cospis = vld1q_s16(kCospi); - const int16x4_t cospis0 = vget_low_s16(cospis); // cospi 0, 8, 16, 24 - const int16x4_t cospis1 = vget_high_s16(cospis); // cospi 4, 12, 20, 28 - int16x8_t a[8]; - - a[0] = load_tran_low_to_s16q(input + 0 * 8); - a[1] = load_tran_low_to_s16q(input + 1 * 8); - a[2] = load_tran_low_to_s16q(input + 2 * 8); - a[3] = load_tran_low_to_s16q(input + 3 * 8); - a[4] = load_tran_low_to_s16q(input + 4 * 8); - a[5] = load_tran_low_to_s16q(input + 5 * 8); - a[6] = load_tran_low_to_s16q(input + 6 * 8); - a[7] = load_tran_low_to_s16q(input + 7 * 8); - - transpose_s16_8x8(&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7]); - - switch (tx_type) { - case DCT_DCT: - idct8x8_64_1d_bd8_kernel(cospis0, cospis1, a); - transpose_s16_8x8(&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7]); - idct8x8_64_1d_bd8_kernel(cospis0, cospis1, a); - break; - - case ADST_DCT: - idct8x8_64_1d_bd8_kernel(cospis0, cospis1, a); - transpose_s16_8x8(&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7]); - iadst8(a); - break; - - case DCT_ADST: - iadst8(a); - transpose_s16_8x8(&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7]); - idct8x8_64_1d_bd8_kernel(cospis0, cospis1, a); - break; - - default: - assert(tx_type == ADST_ADST); - iadst8(a); - transpose_s16_8x8(&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7]); - iadst8(a); - break; - } - - idct8x8_add8x8_neon(a, dest, stride); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_iht_neon.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_iht_neon.h deleted file mode 100644 index c64822e2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/arm/neon/vp9_iht_neon.h +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_ARM_NEON_VP9_IHT_NEON_H_ -#define VPX_VP9_COMMON_ARM_NEON_VP9_IHT_NEON_H_ - -#include - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "vp9/common/vp9_common.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/txfm_common.h" - -static INLINE void iadst4(int16x8_t *const io) { - const int32x4_t c3 = vdupq_n_s32(sinpi_3_9); - int16x4_t x[4]; - int32x4_t s[8], output[4]; - const int16x4_t c = - create_s16x4_neon(sinpi_1_9, sinpi_2_9, sinpi_3_9, sinpi_4_9); - - x[0] = vget_low_s16(io[0]); - x[1] = vget_low_s16(io[1]); - x[2] = vget_high_s16(io[0]); - x[3] = vget_high_s16(io[1]); - - s[0] = vmull_lane_s16(x[0], c, 0); - s[1] = vmull_lane_s16(x[0], c, 1); - s[2] = vmull_lane_s16(x[1], c, 2); - s[3] = vmull_lane_s16(x[2], c, 3); - s[4] = vmull_lane_s16(x[2], c, 0); - s[5] = vmull_lane_s16(x[3], c, 1); - s[6] = vmull_lane_s16(x[3], c, 3); - s[7] = vaddl_s16(x[0], x[3]); - s[7] = vsubw_s16(s[7], x[2]); - - s[0] = vaddq_s32(s[0], s[3]); - s[0] = vaddq_s32(s[0], s[5]); - s[1] = vsubq_s32(s[1], s[4]); - s[1] = vsubq_s32(s[1], s[6]); - s[3] = s[2]; - s[2] = vmulq_s32(c3, s[7]); - - output[0] = vaddq_s32(s[0], s[3]); - output[1] = vaddq_s32(s[1], s[3]); - output[2] = s[2]; - output[3] = vaddq_s32(s[0], s[1]); - output[3] = vsubq_s32(output[3], s[3]); - dct_const_round_shift_low_8_dual(output, &io[0], &io[1]); -} - -static INLINE void iadst_half_butterfly_neon(int16x8_t *const x, - const int16x4_t c) { - // Don't add/sub before multiply, which will overflow in iadst8. - const int32x4_t x0_lo = vmull_lane_s16(vget_low_s16(x[0]), c, 0); - const int32x4_t x0_hi = vmull_lane_s16(vget_high_s16(x[0]), c, 0); - const int32x4_t x1_lo = vmull_lane_s16(vget_low_s16(x[1]), c, 0); - const int32x4_t x1_hi = vmull_lane_s16(vget_high_s16(x[1]), c, 0); - int32x4_t t0[2], t1[2]; - - t0[0] = vaddq_s32(x0_lo, x1_lo); - t0[1] = vaddq_s32(x0_hi, x1_hi); - t1[0] = vsubq_s32(x0_lo, x1_lo); - t1[1] = vsubq_s32(x0_hi, x1_hi); - x[0] = dct_const_round_shift_low_8(t0); - x[1] = dct_const_round_shift_low_8(t1); -} - -static INLINE void iadst_half_butterfly_neg_neon(int16x8_t *const x0, - int16x8_t *const x1, - const int16x4_t c) { - // Don't add/sub before multiply, which will overflow in iadst8. - const int32x4_t x0_lo = vmull_lane_s16(vget_low_s16(*x0), c, 1); - const int32x4_t x0_hi = vmull_lane_s16(vget_high_s16(*x0), c, 1); - const int32x4_t x1_lo = vmull_lane_s16(vget_low_s16(*x1), c, 1); - const int32x4_t x1_hi = vmull_lane_s16(vget_high_s16(*x1), c, 1); - int32x4_t t0[2], t1[2]; - - t0[0] = vaddq_s32(x0_lo, x1_lo); - t0[1] = vaddq_s32(x0_hi, x1_hi); - t1[0] = vsubq_s32(x0_lo, x1_lo); - t1[1] = vsubq_s32(x0_hi, x1_hi); - *x1 = dct_const_round_shift_low_8(t0); - *x0 = dct_const_round_shift_low_8(t1); -} - -static INLINE void iadst_half_butterfly_pos_neon(int16x8_t *const x0, - int16x8_t *const x1, - const int16x4_t c) { - // Don't add/sub before multiply, which will overflow in iadst8. - const int32x4_t x0_lo = vmull_lane_s16(vget_low_s16(*x0), c, 0); - const int32x4_t x0_hi = vmull_lane_s16(vget_high_s16(*x0), c, 0); - const int32x4_t x1_lo = vmull_lane_s16(vget_low_s16(*x1), c, 0); - const int32x4_t x1_hi = vmull_lane_s16(vget_high_s16(*x1), c, 0); - int32x4_t t0[2], t1[2]; - - t0[0] = vaddq_s32(x0_lo, x1_lo); - t0[1] = vaddq_s32(x0_hi, x1_hi); - t1[0] = vsubq_s32(x0_lo, x1_lo); - t1[1] = vsubq_s32(x0_hi, x1_hi); - *x1 = dct_const_round_shift_low_8(t0); - *x0 = dct_const_round_shift_low_8(t1); -} - -static INLINE void iadst_butterfly_lane_0_1_neon(const int16x8_t in0, - const int16x8_t in1, - const int16x4_t c, - int32x4_t *const s0, - int32x4_t *const s1) { - s0[0] = vmull_lane_s16(vget_low_s16(in0), c, 0); - s0[1] = vmull_lane_s16(vget_high_s16(in0), c, 0); - s1[0] = vmull_lane_s16(vget_low_s16(in0), c, 1); - s1[1] = vmull_lane_s16(vget_high_s16(in0), c, 1); - - s0[0] = vmlal_lane_s16(s0[0], vget_low_s16(in1), c, 1); - s0[1] = vmlal_lane_s16(s0[1], vget_high_s16(in1), c, 1); - s1[0] = vmlsl_lane_s16(s1[0], vget_low_s16(in1), c, 0); - s1[1] = vmlsl_lane_s16(s1[1], vget_high_s16(in1), c, 0); -} - -static INLINE void iadst_butterfly_lane_2_3_neon(const int16x8_t in0, - const int16x8_t in1, - const int16x4_t c, - int32x4_t *const s0, - int32x4_t *const s1) { - s0[0] = vmull_lane_s16(vget_low_s16(in0), c, 2); - s0[1] = vmull_lane_s16(vget_high_s16(in0), c, 2); - s1[0] = vmull_lane_s16(vget_low_s16(in0), c, 3); - s1[1] = vmull_lane_s16(vget_high_s16(in0), c, 3); - - s0[0] = vmlal_lane_s16(s0[0], vget_low_s16(in1), c, 3); - s0[1] = vmlal_lane_s16(s0[1], vget_high_s16(in1), c, 3); - s1[0] = vmlsl_lane_s16(s1[0], vget_low_s16(in1), c, 2); - s1[1] = vmlsl_lane_s16(s1[1], vget_high_s16(in1), c, 2); -} - -static INLINE void iadst_butterfly_lane_1_0_neon(const int16x8_t in0, - const int16x8_t in1, - const int16x4_t c, - int32x4_t *const s0, - int32x4_t *const s1) { - s0[0] = vmull_lane_s16(vget_low_s16(in0), c, 1); - s0[1] = vmull_lane_s16(vget_high_s16(in0), c, 1); - s1[0] = vmull_lane_s16(vget_low_s16(in0), c, 0); - s1[1] = vmull_lane_s16(vget_high_s16(in0), c, 0); - - s0[0] = vmlal_lane_s16(s0[0], vget_low_s16(in1), c, 0); - s0[1] = vmlal_lane_s16(s0[1], vget_high_s16(in1), c, 0); - s1[0] = vmlsl_lane_s16(s1[0], vget_low_s16(in1), c, 1); - s1[1] = vmlsl_lane_s16(s1[1], vget_high_s16(in1), c, 1); -} - -static INLINE void iadst_butterfly_lane_3_2_neon(const int16x8_t in0, - const int16x8_t in1, - const int16x4_t c, - int32x4_t *const s0, - int32x4_t *const s1) { - s0[0] = vmull_lane_s16(vget_low_s16(in0), c, 3); - s0[1] = vmull_lane_s16(vget_high_s16(in0), c, 3); - s1[0] = vmull_lane_s16(vget_low_s16(in0), c, 2); - s1[1] = vmull_lane_s16(vget_high_s16(in0), c, 2); - - s0[0] = vmlal_lane_s16(s0[0], vget_low_s16(in1), c, 2); - s0[1] = vmlal_lane_s16(s0[1], vget_high_s16(in1), c, 2); - s1[0] = vmlsl_lane_s16(s1[0], vget_low_s16(in1), c, 3); - s1[1] = vmlsl_lane_s16(s1[1], vget_high_s16(in1), c, 3); -} - -static INLINE int16x8_t add_dct_const_round_shift_low_8( - const int32x4_t *const in0, const int32x4_t *const in1) { - int32x4_t sum[2]; - - sum[0] = vaddq_s32(in0[0], in1[0]); - sum[1] = vaddq_s32(in0[1], in1[1]); - return dct_const_round_shift_low_8(sum); -} - -static INLINE int16x8_t sub_dct_const_round_shift_low_8( - const int32x4_t *const in0, const int32x4_t *const in1) { - int32x4_t sum[2]; - - sum[0] = vsubq_s32(in0[0], in1[0]); - sum[1] = vsubq_s32(in0[1], in1[1]); - return dct_const_round_shift_low_8(sum); -} - -static INLINE void iadst8(int16x8_t *const io) { - const int16x4_t c0 = - create_s16x4_neon(cospi_2_64, cospi_30_64, cospi_10_64, cospi_22_64); - const int16x4_t c1 = - create_s16x4_neon(cospi_18_64, cospi_14_64, cospi_26_64, cospi_6_64); - const int16x4_t c2 = - create_s16x4_neon(cospi_16_64, 0, cospi_8_64, cospi_24_64); - int16x8_t x[8], t[4]; - int32x4_t s0[2], s1[2], s2[2], s3[2], s4[2], s5[2], s6[2], s7[2]; - - x[0] = io[7]; - x[1] = io[0]; - x[2] = io[5]; - x[3] = io[2]; - x[4] = io[3]; - x[5] = io[4]; - x[6] = io[1]; - x[7] = io[6]; - - // stage 1 - iadst_butterfly_lane_0_1_neon(x[0], x[1], c0, s0, s1); - iadst_butterfly_lane_2_3_neon(x[2], x[3], c0, s2, s3); - iadst_butterfly_lane_0_1_neon(x[4], x[5], c1, s4, s5); - iadst_butterfly_lane_2_3_neon(x[6], x[7], c1, s6, s7); - - x[0] = add_dct_const_round_shift_low_8(s0, s4); - x[1] = add_dct_const_round_shift_low_8(s1, s5); - x[2] = add_dct_const_round_shift_low_8(s2, s6); - x[3] = add_dct_const_round_shift_low_8(s3, s7); - x[4] = sub_dct_const_round_shift_low_8(s0, s4); - x[5] = sub_dct_const_round_shift_low_8(s1, s5); - x[6] = sub_dct_const_round_shift_low_8(s2, s6); - x[7] = sub_dct_const_round_shift_low_8(s3, s7); - - // stage 2 - t[0] = x[0]; - t[1] = x[1]; - t[2] = x[2]; - t[3] = x[3]; - iadst_butterfly_lane_2_3_neon(x[4], x[5], c2, s4, s5); - iadst_butterfly_lane_3_2_neon(x[7], x[6], c2, s7, s6); - - x[0] = vaddq_s16(t[0], t[2]); - x[1] = vaddq_s16(t[1], t[3]); - x[2] = vsubq_s16(t[0], t[2]); - x[3] = vsubq_s16(t[1], t[3]); - x[4] = add_dct_const_round_shift_low_8(s4, s6); - x[5] = add_dct_const_round_shift_low_8(s5, s7); - x[6] = sub_dct_const_round_shift_low_8(s4, s6); - x[7] = sub_dct_const_round_shift_low_8(s5, s7); - - // stage 3 - iadst_half_butterfly_neon(x + 2, c2); - iadst_half_butterfly_neon(x + 6, c2); - - io[0] = x[0]; - io[1] = vnegq_s16(x[4]); - io[2] = x[6]; - io[3] = vnegq_s16(x[2]); - io[4] = x[3]; - io[5] = vnegq_s16(x[7]); - io[6] = x[5]; - io[7] = vnegq_s16(x[1]); -} - -void vpx_iadst16x16_256_add_half1d(const void *const input, int16_t *output, - void *const dest, const int stride, - const int highbd_flag); - -typedef void (*iht_1d)(const void *const input, int16_t *output, - void *const dest, const int stride, - const int highbd_flag); - -typedef struct { - iht_1d cols, rows; // vertical and horizontal -} iht_2d; - -#endif // VPX_VP9_COMMON_ARM_NEON_VP9_IHT_NEON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/dspr2/vp9_itrans16_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/dspr2/vp9_itrans16_dspr2.c deleted file mode 100644 index e68d01e9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/dspr2/vp9_itrans16_dspr2.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vp9_rtcd.h" -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_idct.h" -#include "vpx_dsp/mips/inv_txfm_dspr2.h" -#include "vpx_dsp/txfm_common.h" -#include "vpx_ports/mem.h" - -#if HAVE_DSPR2 -void vp9_iht16x16_256_add_dspr2(const int16_t *input, uint8_t *dest, int pitch, - int tx_type) { - int i, j; - DECLARE_ALIGNED(32, int16_t, out[16 * 16]); - int16_t *outptr = out; - int16_t temp_out[16]; - uint32_t pos = 45; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" : : [pos] "r"(pos)); - - switch (tx_type) { - case DCT_DCT: // DCT in both horizontal and vertical - idct16_rows_dspr2(input, outptr, 16); - idct16_cols_add_blk_dspr2(out, dest, pitch); - break; - case ADST_DCT: // ADST in vertical, DCT in horizontal - idct16_rows_dspr2(input, outptr, 16); - - outptr = out; - - for (i = 0; i < 16; ++i) { - iadst16_dspr2(outptr, temp_out); - - for (j = 0; j < 16; ++j) - dest[j * pitch + i] = clip_pixel(ROUND_POWER_OF_TWO(temp_out[j], 6) + - dest[j * pitch + i]); - outptr += 16; - } - break; - case DCT_ADST: // DCT in vertical, ADST in horizontal - { - int16_t temp_in[16 * 16]; - - for (i = 0; i < 16; ++i) { - /* prefetch row */ - prefetch_load((const uint8_t *)(input + 16)); - - iadst16_dspr2(input, outptr); - input += 16; - outptr += 16; - } - - for (i = 0; i < 16; ++i) - for (j = 0; j < 16; ++j) temp_in[j * 16 + i] = out[i * 16 + j]; - - idct16_cols_add_blk_dspr2(temp_in, dest, pitch); - break; - } - case ADST_ADST: // ADST in both directions - { - int16_t temp_in[16]; - - for (i = 0; i < 16; ++i) { - /* prefetch row */ - prefetch_load((const uint8_t *)(input + 16)); - - iadst16_dspr2(input, outptr); - input += 16; - outptr += 16; - } - - for (i = 0; i < 16; ++i) { - for (j = 0; j < 16; ++j) temp_in[j] = out[j * 16 + i]; - iadst16_dspr2(temp_in, temp_out); - for (j = 0; j < 16; ++j) - dest[j * pitch + i] = clip_pixel(ROUND_POWER_OF_TWO(temp_out[j], 6) + - dest[j * pitch + i]); - } - break; - } - default: printf("vp9_short_iht16x16_add_dspr2 : Invalid tx_type\n"); break; - } -} -#endif // #if HAVE_DSPR2 diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/dspr2/vp9_itrans4_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/dspr2/vp9_itrans4_dspr2.c deleted file mode 100644 index f6b29265..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/dspr2/vp9_itrans4_dspr2.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vp9_rtcd.h" -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_idct.h" -#include "vpx_dsp/mips/inv_txfm_dspr2.h" -#include "vpx_dsp/txfm_common.h" -#include "vpx_ports/mem.h" - -#if HAVE_DSPR2 -void vp9_iht4x4_16_add_dspr2(const int16_t *input, uint8_t *dest, int stride, - int tx_type) { - int i, j; - DECLARE_ALIGNED(32, int16_t, out[4 * 4]); - int16_t *outptr = out; - int16_t temp_in[4 * 4], temp_out[4]; - uint32_t pos = 45; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - switch (tx_type) { - case DCT_DCT: // DCT in both horizontal and vertical - vpx_idct4_rows_dspr2(input, outptr); - vpx_idct4_columns_add_blk_dspr2(&out[0], dest, stride); - break; - case ADST_DCT: // ADST in vertical, DCT in horizontal - vpx_idct4_rows_dspr2(input, outptr); - - outptr = out; - - for (i = 0; i < 4; ++i) { - iadst4_dspr2(outptr, temp_out); - - for (j = 0; j < 4; ++j) - dest[j * stride + i] = clip_pixel(ROUND_POWER_OF_TWO(temp_out[j], 4) + - dest[j * stride + i]); - - outptr += 4; - } - break; - case DCT_ADST: // DCT in vertical, ADST in horizontal - for (i = 0; i < 4; ++i) { - iadst4_dspr2(input, outptr); - input += 4; - outptr += 4; - } - - for (i = 0; i < 4; ++i) { - for (j = 0; j < 4; ++j) { - temp_in[i * 4 + j] = out[j * 4 + i]; - } - } - vpx_idct4_columns_add_blk_dspr2(&temp_in[0], dest, stride); - break; - case ADST_ADST: // ADST in both directions - for (i = 0; i < 4; ++i) { - iadst4_dspr2(input, outptr); - input += 4; - outptr += 4; - } - - for (i = 0; i < 4; ++i) { - for (j = 0; j < 4; ++j) temp_in[j] = out[j * 4 + i]; - iadst4_dspr2(temp_in, temp_out); - - for (j = 0; j < 4; ++j) - dest[j * stride + i] = clip_pixel(ROUND_POWER_OF_TWO(temp_out[j], 4) + - dest[j * stride + i]); - } - break; - default: printf("vp9_short_iht4x4_add_dspr2 : Invalid tx_type\n"); break; - } -} -#endif // #if HAVE_DSPR2 diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/dspr2/vp9_itrans8_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/dspr2/vp9_itrans8_dspr2.c deleted file mode 100644 index b945e307..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/dspr2/vp9_itrans8_dspr2.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vp9_rtcd.h" -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_blockd.h" -#include "vpx_dsp/mips/inv_txfm_dspr2.h" -#include "vpx_dsp/txfm_common.h" -#include "vpx_ports/mem.h" - -#if HAVE_DSPR2 -void vp9_iht8x8_64_add_dspr2(const int16_t *input, uint8_t *dest, int stride, - int tx_type) { - int i, j; - DECLARE_ALIGNED(32, int16_t, out[8 * 8]); - int16_t *outptr = out; - int16_t temp_in[8 * 8], temp_out[8]; - uint32_t pos = 45; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" : : [pos] "r"(pos)); - - switch (tx_type) { - case DCT_DCT: // DCT in both horizontal and vertical - idct8_rows_dspr2(input, outptr, 8); - idct8_columns_add_blk_dspr2(&out[0], dest, stride); - break; - case ADST_DCT: // ADST in vertical, DCT in horizontal - idct8_rows_dspr2(input, outptr, 8); - - for (i = 0; i < 8; ++i) { - iadst8_dspr2(&out[i * 8], temp_out); - - for (j = 0; j < 8; ++j) - dest[j * stride + i] = clip_pixel(ROUND_POWER_OF_TWO(temp_out[j], 5) + - dest[j * stride + i]); - } - break; - case DCT_ADST: // DCT in vertical, ADST in horizontal - for (i = 0; i < 8; ++i) { - iadst8_dspr2(input, outptr); - input += 8; - outptr += 8; - } - - for (i = 0; i < 8; ++i) { - for (j = 0; j < 8; ++j) { - temp_in[i * 8 + j] = out[j * 8 + i]; - } - } - idct8_columns_add_blk_dspr2(&temp_in[0], dest, stride); - break; - case ADST_ADST: // ADST in both directions - for (i = 0; i < 8; ++i) { - iadst8_dspr2(input, outptr); - input += 8; - outptr += 8; - } - - for (i = 0; i < 8; ++i) { - for (j = 0; j < 8; ++j) temp_in[j] = out[j * 8 + i]; - - iadst8_dspr2(temp_in, temp_out); - - for (j = 0; j < 8; ++j) - dest[j * stride + i] = clip_pixel(ROUND_POWER_OF_TWO(temp_out[j], 5) + - dest[j * stride + i]); - } - break; - default: printf("vp9_short_iht8x8_add_dspr2 : Invalid tx_type\n"); break; - } -} -#endif // #if HAVE_DSPR2 diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/msa/vp9_idct16x16_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/msa/vp9_idct16x16_msa.c deleted file mode 100644 index c0313228..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/msa/vp9_idct16x16_msa.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp9_rtcd.h" -#include "vp9/common/vp9_enums.h" -#include "vpx_dsp/mips/inv_txfm_msa.h" - -void vp9_iht16x16_256_add_msa(const int16_t *input, uint8_t *dst, - int32_t dst_stride, int32_t tx_type) { - int32_t i; - DECLARE_ALIGNED(32, int16_t, out[16 * 16]); - int16_t *out_ptr = &out[0]; - - switch (tx_type) { - case DCT_DCT: - /* transform rows */ - for (i = 0; i < 2; ++i) { - /* process 16 * 8 block */ - vpx_idct16_1d_rows_msa((input + (i << 7)), (out_ptr + (i << 7))); - } - - /* transform columns */ - for (i = 0; i < 2; ++i) { - /* process 8 * 16 block */ - vpx_idct16_1d_columns_addblk_msa((out_ptr + (i << 3)), (dst + (i << 3)), - dst_stride); - } - break; - case ADST_DCT: - /* transform rows */ - for (i = 0; i < 2; ++i) { - /* process 16 * 8 block */ - vpx_idct16_1d_rows_msa((input + (i << 7)), (out_ptr + (i << 7))); - } - - /* transform columns */ - for (i = 0; i < 2; ++i) { - vpx_iadst16_1d_columns_addblk_msa((out_ptr + (i << 3)), - (dst + (i << 3)), dst_stride); - } - break; - case DCT_ADST: - /* transform rows */ - for (i = 0; i < 2; ++i) { - /* process 16 * 8 block */ - vpx_iadst16_1d_rows_msa((input + (i << 7)), (out_ptr + (i << 7))); - } - - /* transform columns */ - for (i = 0; i < 2; ++i) { - /* process 8 * 16 block */ - vpx_idct16_1d_columns_addblk_msa((out_ptr + (i << 3)), (dst + (i << 3)), - dst_stride); - } - break; - case ADST_ADST: - /* transform rows */ - for (i = 0; i < 2; ++i) { - /* process 16 * 8 block */ - vpx_iadst16_1d_rows_msa((input + (i << 7)), (out_ptr + (i << 7))); - } - - /* transform columns */ - for (i = 0; i < 2; ++i) { - vpx_iadst16_1d_columns_addblk_msa((out_ptr + (i << 3)), - (dst + (i << 3)), dst_stride); - } - break; - default: assert(0); break; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/msa/vp9_idct4x4_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/msa/vp9_idct4x4_msa.c deleted file mode 100644 index aaccd5ca..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/msa/vp9_idct4x4_msa.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp9_rtcd.h" -#include "vp9/common/vp9_enums.h" -#include "vpx_dsp/mips/inv_txfm_msa.h" - -void vp9_iht4x4_16_add_msa(const int16_t *input, uint8_t *dst, - int32_t dst_stride, int32_t tx_type) { - v8i16 in0, in1, in2, in3; - - /* load vector elements of 4x4 block */ - LD4x4_SH(input, in0, in1, in2, in3); - TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); - - switch (tx_type) { - case DCT_DCT: - /* DCT in horizontal */ - VP9_IDCT4x4(in0, in1, in2, in3, in0, in1, in2, in3); - /* DCT in vertical */ - TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); - VP9_IDCT4x4(in0, in1, in2, in3, in0, in1, in2, in3); - break; - case ADST_DCT: - /* DCT in horizontal */ - VP9_IDCT4x4(in0, in1, in2, in3, in0, in1, in2, in3); - /* ADST in vertical */ - TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); - VP9_IADST4x4(in0, in1, in2, in3, in0, in1, in2, in3); - break; - case DCT_ADST: - /* ADST in horizontal */ - VP9_IADST4x4(in0, in1, in2, in3, in0, in1, in2, in3); - /* DCT in vertical */ - TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); - VP9_IDCT4x4(in0, in1, in2, in3, in0, in1, in2, in3); - break; - case ADST_ADST: - /* ADST in horizontal */ - VP9_IADST4x4(in0, in1, in2, in3, in0, in1, in2, in3); - /* ADST in vertical */ - TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); - VP9_IADST4x4(in0, in1, in2, in3, in0, in1, in2, in3); - break; - default: assert(0); break; - } - - /* final rounding (add 2^3, divide by 2^4) and shift */ - SRARI_H4_SH(in0, in1, in2, in3, 4); - /* add block and store 4x4 */ - ADDBLK_ST4x4_UB(in0, in1, in2, in3, dst, dst_stride); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/msa/vp9_idct8x8_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/msa/vp9_idct8x8_msa.c deleted file mode 100644 index 76d15ff8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/msa/vp9_idct8x8_msa.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp9_rtcd.h" -#include "vp9/common/vp9_enums.h" -#include "vpx_dsp/mips/inv_txfm_msa.h" - -void vp9_iht8x8_64_add_msa(const int16_t *input, uint8_t *dst, - int32_t dst_stride, int32_t tx_type) { - v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - - /* load vector elements of 8x8 block */ - LD_SH8(input, 8, in0, in1, in2, in3, in4, in5, in6, in7); - - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - - switch (tx_type) { - case DCT_DCT: - /* DCT in horizontal */ - VP9_IDCT8x8_1D(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - /* DCT in vertical */ - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, - in3, in4, in5, in6, in7); - VP9_IDCT8x8_1D(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - break; - case ADST_DCT: - /* DCT in horizontal */ - VP9_IDCT8x8_1D(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - /* ADST in vertical */ - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, - in3, in4, in5, in6, in7); - VP9_ADST8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, - in5, in6, in7); - break; - case DCT_ADST: - /* ADST in horizontal */ - VP9_ADST8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, - in5, in6, in7); - /* DCT in vertical */ - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, - in3, in4, in5, in6, in7); - VP9_IDCT8x8_1D(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - break; - case ADST_ADST: - /* ADST in horizontal */ - VP9_ADST8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, - in5, in6, in7); - /* ADST in vertical */ - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, - in3, in4, in5, in6, in7); - VP9_ADST8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, - in5, in6, in7); - break; - default: assert(0); break; - } - - /* final rounding (add 2^4, divide by 2^5) and shift */ - SRARI_H4_SH(in0, in1, in2, in3, 5); - SRARI_H4_SH(in4, in5, in6, in7, 5); - - /* add block and store 8x8 */ - VP9_ADDBLK_ST8x4_UB(dst, dst_stride, in0, in1, in2, in3); - dst += (4 * dst_stride); - VP9_ADDBLK_ST8x4_UB(dst, dst_stride, in4, in5, in6, in7); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/msa/vp9_mfqe_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/msa/vp9_mfqe_msa.c deleted file mode 100644 index 2c384095..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/mips/msa/vp9_mfqe_msa.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp9_rtcd.h" -#include "vp9/common/vp9_onyxc_int.h" -#include "vpx_dsp/mips/macros_msa.h" - -static void filter_by_weight8x8_msa(const uint8_t *src_ptr, int32_t src_stride, - uint8_t *dst_ptr, int32_t dst_stride, - int32_t src_weight) { - int32_t dst_weight = (1 << MFQE_PRECISION) - src_weight; - int32_t row; - uint64_t src0_d, src1_d, dst0_d, dst1_d; - v16i8 src0 = { 0 }; - v16i8 src1 = { 0 }; - v16i8 dst0 = { 0 }; - v16i8 dst1 = { 0 }; - v8i16 src_wt, dst_wt, res_h_r, res_h_l, src_r, src_l, dst_r, dst_l; - - src_wt = __msa_fill_h(src_weight); - dst_wt = __msa_fill_h(dst_weight); - - for (row = 2; row--;) { - LD2(src_ptr, src_stride, src0_d, src1_d); - src_ptr += (2 * src_stride); - LD2(dst_ptr, dst_stride, dst0_d, dst1_d); - INSERT_D2_SB(src0_d, src1_d, src0); - INSERT_D2_SB(dst0_d, dst1_d, dst0); - - LD2(src_ptr, src_stride, src0_d, src1_d); - src_ptr += (2 * src_stride); - LD2((dst_ptr + 2 * dst_stride), dst_stride, dst0_d, dst1_d); - INSERT_D2_SB(src0_d, src1_d, src1); - INSERT_D2_SB(dst0_d, dst1_d, dst1); - - UNPCK_UB_SH(src0, src_r, src_l); - UNPCK_UB_SH(dst0, dst_r, dst_l); - res_h_r = (src_r * src_wt); - res_h_r += (dst_r * dst_wt); - res_h_l = (src_l * src_wt); - res_h_l += (dst_l * dst_wt); - SRARI_H2_SH(res_h_r, res_h_l, MFQE_PRECISION); - dst0 = (v16i8)__msa_pckev_b((v16i8)res_h_l, (v16i8)res_h_r); - ST8x2_UB(dst0, dst_ptr, dst_stride); - dst_ptr += (2 * dst_stride); - - UNPCK_UB_SH(src1, src_r, src_l); - UNPCK_UB_SH(dst1, dst_r, dst_l); - res_h_r = (src_r * src_wt); - res_h_r += (dst_r * dst_wt); - res_h_l = (src_l * src_wt); - res_h_l += (dst_l * dst_wt); - SRARI_H2_SH(res_h_r, res_h_l, MFQE_PRECISION); - dst1 = (v16i8)__msa_pckev_b((v16i8)res_h_l, (v16i8)res_h_r); - ST8x2_UB(dst1, dst_ptr, dst_stride); - dst_ptr += (2 * dst_stride); - } -} - -static void filter_by_weight16x16_msa(const uint8_t *src_ptr, - int32_t src_stride, uint8_t *dst_ptr, - int32_t dst_stride, int32_t src_weight) { - int32_t dst_weight = (1 << MFQE_PRECISION) - src_weight; - int32_t row; - v16i8 src0, src1, src2, src3, dst0, dst1, dst2, dst3; - v8i16 src_wt, dst_wt, res_h_r, res_h_l, src_r, src_l, dst_r, dst_l; - - src_wt = __msa_fill_h(src_weight); - dst_wt = __msa_fill_h(dst_weight); - - for (row = 4; row--;) { - LD_SB4(src_ptr, src_stride, src0, src1, src2, src3); - src_ptr += (4 * src_stride); - LD_SB4(dst_ptr, dst_stride, dst0, dst1, dst2, dst3); - - UNPCK_UB_SH(src0, src_r, src_l); - UNPCK_UB_SH(dst0, dst_r, dst_l); - res_h_r = (src_r * src_wt); - res_h_r += (dst_r * dst_wt); - res_h_l = (src_l * src_wt); - res_h_l += (dst_l * dst_wt); - SRARI_H2_SH(res_h_r, res_h_l, MFQE_PRECISION); - PCKEV_ST_SB(res_h_r, res_h_l, dst_ptr); - dst_ptr += dst_stride; - - UNPCK_UB_SH(src1, src_r, src_l); - UNPCK_UB_SH(dst1, dst_r, dst_l); - res_h_r = (src_r * src_wt); - res_h_r += (dst_r * dst_wt); - res_h_l = (src_l * src_wt); - res_h_l += (dst_l * dst_wt); - SRARI_H2_SH(res_h_r, res_h_l, MFQE_PRECISION); - PCKEV_ST_SB(res_h_r, res_h_l, dst_ptr); - dst_ptr += dst_stride; - - UNPCK_UB_SH(src2, src_r, src_l); - UNPCK_UB_SH(dst2, dst_r, dst_l); - res_h_r = (src_r * src_wt); - res_h_r += (dst_r * dst_wt); - res_h_l = (src_l * src_wt); - res_h_l += (dst_l * dst_wt); - SRARI_H2_SH(res_h_r, res_h_l, MFQE_PRECISION); - PCKEV_ST_SB(res_h_r, res_h_l, dst_ptr); - dst_ptr += dst_stride; - - UNPCK_UB_SH(src3, src_r, src_l); - UNPCK_UB_SH(dst3, dst_r, dst_l); - res_h_r = (src_r * src_wt); - res_h_r += (dst_r * dst_wt); - res_h_l = (src_l * src_wt); - res_h_l += (dst_l * dst_wt); - SRARI_H2_SH(res_h_r, res_h_l, MFQE_PRECISION); - PCKEV_ST_SB(res_h_r, res_h_l, dst_ptr); - dst_ptr += dst_stride; - } -} - -void vp9_filter_by_weight8x8_msa(const uint8_t *src, int src_stride, - uint8_t *dst, int dst_stride, int src_weight) { - filter_by_weight8x8_msa(src, src_stride, dst, dst_stride, src_weight); -} - -void vp9_filter_by_weight16x16_msa(const uint8_t *src, int src_stride, - uint8_t *dst, int dst_stride, - int src_weight) { - filter_by_weight16x16_msa(src, src_stride, dst, dst_stride, src_weight); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/ppc/vp9_idct_vsx.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/ppc/vp9_idct_vsx.c deleted file mode 100644 index e861596a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/ppc/vp9_idct_vsx.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp9_rtcd.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/ppc/inv_txfm_vsx.h" -#include "vpx_dsp/ppc/bitdepth_conversion_vsx.h" - -#include "vp9/common/vp9_enums.h" - -void vp9_iht4x4_16_add_vsx(const tran_low_t *input, uint8_t *dest, int stride, - int tx_type) { - int16x8_t in[2], out[2]; - - in[0] = load_tran_low(0, input); - in[1] = load_tran_low(8 * sizeof(*input), input); - - switch (tx_type) { - case DCT_DCT: - vpx_idct4_vsx(in, out); - vpx_idct4_vsx(out, in); - break; - case ADST_DCT: - vpx_idct4_vsx(in, out); - vp9_iadst4_vsx(out, in); - break; - case DCT_ADST: - vp9_iadst4_vsx(in, out); - vpx_idct4_vsx(out, in); - break; - default: - assert(tx_type == ADST_ADST); - vp9_iadst4_vsx(in, out); - vp9_iadst4_vsx(out, in); - break; - } - - vpx_round_store4x4_vsx(in, out, dest, stride); -} - -void vp9_iht8x8_64_add_vsx(const tran_low_t *input, uint8_t *dest, int stride, - int tx_type) { - int16x8_t in[8], out[8]; - - // load input data - in[0] = load_tran_low(0, input); - in[1] = load_tran_low(8 * sizeof(*input), input); - in[2] = load_tran_low(2 * 8 * sizeof(*input), input); - in[3] = load_tran_low(3 * 8 * sizeof(*input), input); - in[4] = load_tran_low(4 * 8 * sizeof(*input), input); - in[5] = load_tran_low(5 * 8 * sizeof(*input), input); - in[6] = load_tran_low(6 * 8 * sizeof(*input), input); - in[7] = load_tran_low(7 * 8 * sizeof(*input), input); - - switch (tx_type) { - case DCT_DCT: - vpx_idct8_vsx(in, out); - vpx_idct8_vsx(out, in); - break; - case ADST_DCT: - vpx_idct8_vsx(in, out); - vp9_iadst8_vsx(out, in); - break; - case DCT_ADST: - vp9_iadst8_vsx(in, out); - vpx_idct8_vsx(out, in); - break; - default: - assert(tx_type == ADST_ADST); - vp9_iadst8_vsx(in, out); - vp9_iadst8_vsx(out, in); - break; - } - - vpx_round_store8x8_vsx(in, dest, stride); -} - -void vp9_iht16x16_256_add_vsx(const tran_low_t *input, uint8_t *dest, - int stride, int tx_type) { - int16x8_t in0[16], in1[16]; - - LOAD_INPUT16(load_tran_low, input, 0, 8 * sizeof(*input), in0); - LOAD_INPUT16(load_tran_low, input, 8 * 8 * 2 * sizeof(*input), - 8 * sizeof(*input), in1); - - switch (tx_type) { - case DCT_DCT: - vpx_idct16_vsx(in0, in1); - vpx_idct16_vsx(in0, in1); - break; - case ADST_DCT: - vpx_idct16_vsx(in0, in1); - vpx_iadst16_vsx(in0, in1); - break; - case DCT_ADST: - vpx_iadst16_vsx(in0, in1); - vpx_idct16_vsx(in0, in1); - break; - default: - assert(tx_type == ADST_ADST); - vpx_iadst16_vsx(in0, in1); - vpx_iadst16_vsx(in0, in1); - break; - } - - vpx_round_store16x16_vsx(in0, in1, dest, stride); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_alloccommon.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_alloccommon.c deleted file mode 100644 index 9e73e40e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_alloccommon.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "vpx_mem/vpx_mem.h" - -#include "vp9/common/vp9_alloccommon.h" -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_entropymode.h" -#include "vp9/common/vp9_entropymv.h" -#include "vp9/common/vp9_onyxc_int.h" - -void vp9_set_mi_size(int *mi_rows, int *mi_cols, int *mi_stride, int width, - int height) { - const int aligned_width = ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2); - const int aligned_height = ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2); - *mi_cols = aligned_width >> MI_SIZE_LOG2; - *mi_rows = aligned_height >> MI_SIZE_LOG2; - *mi_stride = calc_mi_size(*mi_cols); -} - -void vp9_set_mb_size(int *mb_rows, int *mb_cols, int *mb_num, int mi_rows, - int mi_cols) { - *mb_cols = (mi_cols + 1) >> 1; - *mb_rows = (mi_rows + 1) >> 1; - *mb_num = (*mb_rows) * (*mb_cols); -} - -void vp9_set_mb_mi(VP9_COMMON *cm, int width, int height) { - vp9_set_mi_size(&cm->mi_rows, &cm->mi_cols, &cm->mi_stride, width, height); - vp9_set_mb_size(&cm->mb_rows, &cm->mb_cols, &cm->MBs, cm->mi_rows, - cm->mi_cols); -} - -static int alloc_seg_map(VP9_COMMON *cm, int seg_map_size) { - int i; - - for (i = 0; i < NUM_PING_PONG_BUFFERS; ++i) { - cm->seg_map_array[i] = (uint8_t *)vpx_calloc(seg_map_size, 1); - if (cm->seg_map_array[i] == NULL) return 1; - } - cm->seg_map_alloc_size = seg_map_size; - - // Init the index. - cm->seg_map_idx = 0; - cm->prev_seg_map_idx = 1; - - cm->current_frame_seg_map = cm->seg_map_array[cm->seg_map_idx]; - cm->last_frame_seg_map = cm->seg_map_array[cm->prev_seg_map_idx]; - - return 0; -} - -static void free_seg_map(VP9_COMMON *cm) { - int i; - - for (i = 0; i < NUM_PING_PONG_BUFFERS; ++i) { - vpx_free(cm->seg_map_array[i]); - cm->seg_map_array[i] = NULL; - } - cm->seg_map_alloc_size = 0; - - cm->current_frame_seg_map = NULL; - cm->last_frame_seg_map = NULL; -} - -void vp9_free_ref_frame_buffers(BufferPool *pool) { - int i; - - if (!pool) return; - - for (i = 0; i < FRAME_BUFFERS; ++i) { - if (!pool->frame_bufs[i].released && - pool->frame_bufs[i].raw_frame_buffer.data != NULL) { - pool->release_fb_cb(pool->cb_priv, &pool->frame_bufs[i].raw_frame_buffer); - pool->frame_bufs[i].ref_count = 0; - pool->frame_bufs[i].released = 1; - } - vpx_free(pool->frame_bufs[i].mvs); - pool->frame_bufs[i].mvs = NULL; - vpx_free_frame_buffer(&pool->frame_bufs[i].buf); - } -} - -void vp9_free_postproc_buffers(VP9_COMMON *cm) { -#if CONFIG_VP9_POSTPROC - vpx_free_frame_buffer(&cm->post_proc_buffer); - vpx_free_frame_buffer(&cm->post_proc_buffer_int); - vpx_free(cm->postproc_state.limits); - cm->postproc_state.limits = NULL; - vpx_free(cm->postproc_state.generated_noise); - cm->postproc_state.generated_noise = NULL; -#else - (void)cm; -#endif -} - -void vp9_free_context_buffers(VP9_COMMON *cm) { - if (cm->free_mi) cm->free_mi(cm); - free_seg_map(cm); - vpx_free(cm->above_context); - cm->above_context = NULL; - vpx_free(cm->above_seg_context); - cm->above_seg_context = NULL; - cm->above_context_alloc_cols = 0; - vpx_free(cm->lf.lfm); - cm->lf.lfm = NULL; -} - -int vp9_alloc_loop_filter(VP9_COMMON *cm) { - vpx_free(cm->lf.lfm); - // Each lfm holds bit masks for all the 8x8 blocks in a 64x64 region. The - // stride and rows are rounded up / truncated to a multiple of 8. - cm->lf.lfm_stride = (cm->mi_cols + (MI_BLOCK_SIZE - 1)) >> 3; - cm->lf.lfm = (LOOP_FILTER_MASK *)vpx_calloc( - ((cm->mi_rows + (MI_BLOCK_SIZE - 1)) >> 3) * cm->lf.lfm_stride, - sizeof(*cm->lf.lfm)); - if (!cm->lf.lfm) return 1; - return 0; -} - -int vp9_alloc_context_buffers(VP9_COMMON *cm, int width, int height) { - int new_mi_size; - - vp9_set_mb_mi(cm, width, height); - new_mi_size = cm->mi_stride * calc_mi_size(cm->mi_rows); - if (cm->mi_alloc_size < new_mi_size) { - cm->free_mi(cm); - if (cm->alloc_mi(cm, new_mi_size)) goto fail; - } - if (cm->above_context_alloc_cols < cm->mi_cols) { - vpx_free(cm->above_context); - cm->above_context = (ENTROPY_CONTEXT *)vpx_calloc( - 2 * mi_cols_aligned_to_sb(cm->mi_cols) * MAX_MB_PLANE, - sizeof(*cm->above_context)); - if (!cm->above_context) goto fail; - - vpx_free(cm->above_seg_context); - cm->above_seg_context = (PARTITION_CONTEXT *)vpx_calloc( - mi_cols_aligned_to_sb(cm->mi_cols), sizeof(*cm->above_seg_context)); - if (!cm->above_seg_context) goto fail; - cm->above_context_alloc_cols = cm->mi_cols; - } - - if (cm->seg_map_alloc_size < cm->mi_rows * cm->mi_cols) { - // Create the segmentation map structure and set to 0. - free_seg_map(cm); - if (alloc_seg_map(cm, cm->mi_rows * cm->mi_cols)) goto fail; - } - - if (vp9_alloc_loop_filter(cm)) goto fail; - - return 0; - -fail: - // clear the mi_* values to force a realloc on resync - vp9_set_mb_mi(cm, 0, 0); - vp9_free_context_buffers(cm); - return 1; -} - -void vp9_remove_common(VP9_COMMON *cm) { -#if CONFIG_VP9_POSTPROC - vp9_free_postproc_buffers(cm); -#endif - vp9_free_context_buffers(cm); - - vpx_free(cm->fc); - cm->fc = NULL; - vpx_free(cm->frame_contexts); - cm->frame_contexts = NULL; -} - -void vp9_init_context_buffers(VP9_COMMON *cm) { - cm->setup_mi(cm); - if (cm->last_frame_seg_map) - memset(cm->last_frame_seg_map, 0, cm->mi_rows * cm->mi_cols); -} - -void vp9_swap_current_and_last_seg_map(VP9_COMMON *cm) { - // Swap indices. - const int tmp = cm->seg_map_idx; - cm->seg_map_idx = cm->prev_seg_map_idx; - cm->prev_seg_map_idx = tmp; - - cm->current_frame_seg_map = cm->seg_map_array[cm->seg_map_idx]; - cm->last_frame_seg_map = cm->seg_map_array[cm->prev_seg_map_idx]; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_alloccommon.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_alloccommon.h deleted file mode 100644 index 90cbb093..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_alloccommon.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_ALLOCCOMMON_H_ -#define VPX_VP9_COMMON_VP9_ALLOCCOMMON_H_ - -#define INVALID_IDX (-1) // Invalid buffer index. - -#ifdef __cplusplus -extern "C" { -#endif - -struct VP9Common; -struct BufferPool; - -void vp9_remove_common(struct VP9Common *cm); - -int vp9_alloc_loop_filter(struct VP9Common *cm); -int vp9_alloc_context_buffers(struct VP9Common *cm, int width, int height); -void vp9_init_context_buffers(struct VP9Common *cm); -void vp9_free_context_buffers(struct VP9Common *cm); - -void vp9_free_ref_frame_buffers(struct BufferPool *pool); -void vp9_free_postproc_buffers(struct VP9Common *cm); - -int vp9_alloc_state_buffers(struct VP9Common *cm, int width, int height); -void vp9_free_state_buffers(struct VP9Common *cm); - -void vp9_set_mi_size(int *mi_rows, int *mi_cols, int *mi_stride, int width, - int height); -void vp9_set_mb_size(int *mb_rows, int *mb_cols, int *mb_num, int mi_rows, - int mi_cols); - -void vp9_set_mb_mi(struct VP9Common *cm, int width, int height); - -void vp9_swap_current_and_last_seg_map(struct VP9Common *cm); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_ALLOCCOMMON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_blockd.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_blockd.c deleted file mode 100644 index 43275995..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_blockd.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp9/common/vp9_blockd.h" - -PREDICTION_MODE vp9_left_block_mode(const MODE_INFO *cur_mi, - const MODE_INFO *left_mi, int b) { - if (b == 0 || b == 2) { - if (!left_mi || is_inter_block(left_mi)) return DC_PRED; - - return get_y_mode(left_mi, b + 1); - } else { - assert(b == 1 || b == 3); - return cur_mi->bmi[b - 1].as_mode; - } -} - -PREDICTION_MODE vp9_above_block_mode(const MODE_INFO *cur_mi, - const MODE_INFO *above_mi, int b) { - if (b == 0 || b == 1) { - if (!above_mi || is_inter_block(above_mi)) return DC_PRED; - - return get_y_mode(above_mi, b + 2); - } else { - assert(b == 2 || b == 3); - return cur_mi->bmi[b - 2].as_mode; - } -} - -void vp9_foreach_transformed_block_in_plane( - const MACROBLOCKD *const xd, BLOCK_SIZE bsize, int plane, - foreach_transformed_block_visitor visit, void *arg) { - const struct macroblockd_plane *const pd = &xd->plane[plane]; - const MODE_INFO *mi = xd->mi[0]; - // block and transform sizes, in number of 4x4 blocks log 2 ("*_b") - // 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8 - // transform size varies per plane, look it up in a common way. - const TX_SIZE tx_size = plane ? get_uv_tx_size(mi, pd) : mi->tx_size; - const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd); - const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize]; - const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize]; - const int step = 1 << (tx_size << 1); - int i = 0, r, c; - - // If mb_to_right_edge is < 0 we are in a situation in which - // the current block size extends into the UMV and we won't - // visit the sub blocks that are wholly within the UMV. - const int max_blocks_wide = - num_4x4_w + (xd->mb_to_right_edge >= 0 - ? 0 - : xd->mb_to_right_edge >> (5 + pd->subsampling_x)); - const int max_blocks_high = - num_4x4_h + (xd->mb_to_bottom_edge >= 0 - ? 0 - : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y)); - const int extra_step = ((num_4x4_w - max_blocks_wide) >> tx_size) * step; - - // Keep track of the row and column of the blocks we use so that we know - // if we are in the unrestricted motion border. - for (r = 0; r < max_blocks_high; r += (1 << tx_size)) { - // Skip visiting the sub blocks that are wholly within the UMV. - for (c = 0; c < max_blocks_wide; c += (1 << tx_size)) { - visit(plane, i, r, c, plane_bsize, tx_size, arg); - i += step; - } - i += extra_step; - } -} - -void vp9_foreach_transformed_block(const MACROBLOCKD *const xd, - BLOCK_SIZE bsize, - foreach_transformed_block_visitor visit, - void *arg) { - int plane; - - for (plane = 0; plane < MAX_MB_PLANE; ++plane) - vp9_foreach_transformed_block_in_plane(xd, bsize, plane, visit, arg); -} - -void vp9_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size, int has_eob, - int aoff, int loff) { - ENTROPY_CONTEXT *const a = pd->above_context + aoff; - ENTROPY_CONTEXT *const l = pd->left_context + loff; - const int tx_size_in_blocks = 1 << tx_size; - - // above - if (has_eob && xd->mb_to_right_edge < 0) { - int i; - const int blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize] + - (xd->mb_to_right_edge >> (5 + pd->subsampling_x)); - int above_contexts = tx_size_in_blocks; - if (above_contexts + aoff > blocks_wide) - above_contexts = blocks_wide - aoff; - - for (i = 0; i < above_contexts; ++i) a[i] = has_eob; - for (i = above_contexts; i < tx_size_in_blocks; ++i) a[i] = 0; - } else { - memset(a, has_eob, sizeof(ENTROPY_CONTEXT) * tx_size_in_blocks); - } - - // left - if (has_eob && xd->mb_to_bottom_edge < 0) { - int i; - const int blocks_high = num_4x4_blocks_high_lookup[plane_bsize] + - (xd->mb_to_bottom_edge >> (5 + pd->subsampling_y)); - int left_contexts = tx_size_in_blocks; - if (left_contexts + loff > blocks_high) left_contexts = blocks_high - loff; - - for (i = 0; i < left_contexts; ++i) l[i] = has_eob; - for (i = left_contexts; i < tx_size_in_blocks; ++i) l[i] = 0; - } else { - memset(l, has_eob, sizeof(ENTROPY_CONTEXT) * tx_size_in_blocks); - } -} - -void vp9_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y) { - int i; - - for (i = 0; i < MAX_MB_PLANE; i++) { - xd->plane[i].subsampling_x = i ? ss_x : 0; - xd->plane[i].subsampling_y = i ? ss_y : 0; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_blockd.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_blockd.h deleted file mode 100644 index aa13d8a0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_blockd.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_BLOCKD_H_ -#define VPX_VP9_COMMON_VP9_BLOCKD_H_ - -#include "./vpx_config.h" - -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_ports/mem.h" -#include "vpx_scale/yv12config.h" - -#include "vp9/common/vp9_common_data.h" -#include "vp9/common/vp9_entropy.h" -#include "vp9/common/vp9_entropymode.h" -#include "vp9/common/vp9_mv.h" -#include "vp9/common/vp9_scale.h" -#include "vp9/common/vp9_seg_common.h" -#include "vp9/common/vp9_tile_common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_MB_PLANE 3 - -typedef enum { - KEY_FRAME = 0, - INTER_FRAME = 1, - FRAME_TYPES, -} FRAME_TYPE; - -static INLINE int is_inter_mode(PREDICTION_MODE mode) { - return mode >= NEARESTMV && mode <= NEWMV; -} - -/* For keyframes, intra block modes are predicted by the (already decoded) - modes for the Y blocks to the left and above us; for interframes, there - is a single probability table. */ - -typedef struct { - PREDICTION_MODE as_mode; - int_mv as_mv[2]; // first, second inter predictor motion vectors -} b_mode_info; - -// Note that the rate-distortion optimization loop, bit-stream writer, and -// decoder implementation modules critically rely on the defined entry values -// specified herein. They should be refactored concurrently. - -#define NO_REF_FRAME (-1) -#define INTRA_FRAME 0 -#define LAST_FRAME 1 -#define GOLDEN_FRAME 2 -#define ALTREF_FRAME 3 -#define MAX_REF_FRAMES 4 -#define MAX_INTER_REF_FRAMES 3 - -typedef int8_t MV_REFERENCE_FRAME; - -static INLINE int mv_ref_frame_to_inter_ref_idx( - MV_REFERENCE_FRAME mv_ref_frame) { - assert(mv_ref_frame >= LAST_FRAME && mv_ref_frame < MAX_REF_FRAMES); - return mv_ref_frame - 1; -} - -// This structure now relates to 8x8 block regions. -typedef struct MODE_INFO { - // Common for both INTER and INTRA blocks - BLOCK_SIZE sb_type; - PREDICTION_MODE mode; - TX_SIZE tx_size; - int8_t skip; - int8_t segment_id; - int8_t seg_id_predicted; // valid only when temporal_update is enabled - - // Only for INTRA blocks - PREDICTION_MODE uv_mode; - - // Only for INTER blocks - INTERP_FILTER interp_filter; - - // if ref_frame[idx] is equal to ALTREF_FRAME then - // MACROBLOCKD::block_ref[idx] is an altref - MV_REFERENCE_FRAME ref_frame[2]; - - // TODO(slavarnway): Delete and use bmi[3].as_mv[] instead. - int_mv mv[2]; - - b_mode_info bmi[4]; -} MODE_INFO; - -static INLINE PREDICTION_MODE get_y_mode(const MODE_INFO *mi, int block) { - return mi->sb_type < BLOCK_8X8 ? mi->bmi[block].as_mode : mi->mode; -} - -static INLINE int is_inter_block(const MODE_INFO *mi) { - return mi->ref_frame[0] > INTRA_FRAME; -} - -static INLINE int has_second_ref(const MODE_INFO *mi) { - return mi->ref_frame[1] > INTRA_FRAME; -} - -PREDICTION_MODE vp9_left_block_mode(const MODE_INFO *cur_mi, - const MODE_INFO *left_mi, int b); - -PREDICTION_MODE vp9_above_block_mode(const MODE_INFO *cur_mi, - const MODE_INFO *above_mi, int b); - -enum mv_precision { MV_PRECISION_Q3, MV_PRECISION_Q4 }; - -struct buf_2d { - uint8_t *buf; - int stride; -}; - -struct macroblockd_plane { - tran_low_t *dqcoeff; - int subsampling_x; - int subsampling_y; - struct buf_2d dst; - struct buf_2d pre[2]; - ENTROPY_CONTEXT *above_context; - ENTROPY_CONTEXT *left_context; - int16_t seg_dequant[MAX_SEGMENTS][2]; - - // number of 4x4s in current block - uint16_t n4_w, n4_h; - // log2 of n4_w, n4_h - uint8_t n4_wl, n4_hl; - - // encoder - const int16_t *dequant; - - int *eob; -}; - -#define BLOCK_OFFSET(x, i) ((x) + (i)*16) - -typedef struct RefBuffer { - // TODO(dkovalev): idx is not really required and should be removed, now it - // is used in vp9_onyxd_if.c - int idx; - YV12_BUFFER_CONFIG *buf; - struct scale_factors sf; -} RefBuffer; - -typedef struct macroblockd { - struct macroblockd_plane plane[MAX_MB_PLANE]; - uint8_t bmode_blocks_wl; - uint8_t bmode_blocks_hl; - - FRAME_COUNTS *counts; - TileInfo tile; - - int mi_stride; - - // Grid of 8x8 cells is placed over the block. - // If some of them belong to the same mbtree-block - // they will just have same mi[i][j] value - MODE_INFO **mi; - MODE_INFO *left_mi; - MODE_INFO *above_mi; - - unsigned int max_blocks_wide; - unsigned int max_blocks_high; - - const vpx_prob (*partition_probs)[PARTITION_TYPES - 1]; - - /* Distance of MB away from frame edges */ - int mb_to_left_edge; - int mb_to_right_edge; - int mb_to_top_edge; - int mb_to_bottom_edge; - - FRAME_CONTEXT *fc; - - /* pointers to reference frames */ - const RefBuffer *block_refs[2]; - - /* pointer to current frame */ - const YV12_BUFFER_CONFIG *cur_buf; - - ENTROPY_CONTEXT *above_context[MAX_MB_PLANE]; - ENTROPY_CONTEXT left_context[MAX_MB_PLANE][16]; - - PARTITION_CONTEXT *above_seg_context; - PARTITION_CONTEXT left_seg_context[8]; - -#if CONFIG_VP9_HIGHBITDEPTH - /* Bit depth: 8, 10, 12 */ - int bd; -#endif - - int lossless; - int corrupted; - - struct vpx_internal_error_info *error_info; - - PARTITION_TYPE *partition; -} MACROBLOCKD; - -static INLINE PLANE_TYPE get_plane_type(int plane) { - return (PLANE_TYPE)(plane > 0); -} - -static INLINE BLOCK_SIZE get_subsize(BLOCK_SIZE bsize, - PARTITION_TYPE partition) { - return subsize_lookup[partition][bsize]; -} - -extern const TX_TYPE intra_mode_to_tx_type_lookup[INTRA_MODES]; - -static INLINE TX_TYPE get_tx_type(PLANE_TYPE plane_type, - const MACROBLOCKD *xd) { - const MODE_INFO *const mi = xd->mi[0]; - - if (plane_type != PLANE_TYPE_Y || xd->lossless || is_inter_block(mi)) - return DCT_DCT; - - return intra_mode_to_tx_type_lookup[mi->mode]; -} - -static INLINE TX_TYPE get_tx_type_4x4(PLANE_TYPE plane_type, - const MACROBLOCKD *xd, int ib) { - const MODE_INFO *const mi = xd->mi[0]; - - if (plane_type != PLANE_TYPE_Y || xd->lossless || is_inter_block(mi)) - return DCT_DCT; - - return intra_mode_to_tx_type_lookup[get_y_mode(mi, ib)]; -} - -void vp9_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y); - -static INLINE TX_SIZE get_uv_tx_size(const MODE_INFO *mi, - const struct macroblockd_plane *pd) { - assert(mi->sb_type < BLOCK_8X8 || - ss_size_lookup[mi->sb_type][pd->subsampling_x][pd->subsampling_y] != - BLOCK_INVALID); - return uv_txsize_lookup[mi->sb_type][mi->tx_size][pd->subsampling_x] - [pd->subsampling_y]; -} - -static INLINE BLOCK_SIZE -get_plane_block_size(BLOCK_SIZE bsize, const struct macroblockd_plane *pd) { - return ss_size_lookup[bsize][pd->subsampling_x][pd->subsampling_y]; -} - -static INLINE void reset_skip_context(MACROBLOCKD *xd, BLOCK_SIZE bsize) { - int i; - for (i = 0; i < MAX_MB_PLANE; i++) { - struct macroblockd_plane *const pd = &xd->plane[i]; - const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd); - memset(pd->above_context, 0, - sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide_lookup[plane_bsize]); - memset(pd->left_context, 0, - sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high_lookup[plane_bsize]); - } -} - -static INLINE const vpx_prob *get_y_mode_probs(const MODE_INFO *mi, - const MODE_INFO *above_mi, - const MODE_INFO *left_mi, - int block) { - const PREDICTION_MODE above = vp9_above_block_mode(mi, above_mi, block); - const PREDICTION_MODE left = vp9_left_block_mode(mi, left_mi, block); - return vp9_kf_y_mode_prob[above][left]; -} - -typedef void (*foreach_transformed_block_visitor)(int plane, int block, int row, - int col, - BLOCK_SIZE plane_bsize, - TX_SIZE tx_size, void *arg); - -void vp9_foreach_transformed_block_in_plane( - const MACROBLOCKD *const xd, BLOCK_SIZE bsize, int plane, - foreach_transformed_block_visitor visit, void *arg); - -void vp9_foreach_transformed_block(const MACROBLOCKD *const xd, - BLOCK_SIZE bsize, - foreach_transformed_block_visitor visit, - void *arg); - -void vp9_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size, int has_eob, - int aoff, int loff); - -#if CONFIG_MISMATCH_DEBUG -#define TX_UNIT_SIZE_LOG2 2 -static INLINE void mi_to_pixel_loc(int *pixel_c, int *pixel_r, int mi_col, - int mi_row, int tx_blk_col, int tx_blk_row, - int subsampling_x, int subsampling_y) { - *pixel_c = ((mi_col << MI_SIZE_LOG2) >> subsampling_x) + - (tx_blk_col << TX_UNIT_SIZE_LOG2); - *pixel_r = ((mi_row << MI_SIZE_LOG2) >> subsampling_y) + - (tx_blk_row << TX_UNIT_SIZE_LOG2); -} - -static INLINE int get_block_width(BLOCK_SIZE bsize) { - const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; - return 4 * num_4x4_w; -} - -static INLINE int get_block_height(BLOCK_SIZE bsize) { - const int num_4x4_h = num_4x4_blocks_high_lookup[bsize]; - return 4 * num_4x4_h; -} -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_BLOCKD_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_common.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_common.h deleted file mode 100644 index d63bad93..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_common.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_COMMON_H_ -#define VPX_VP9_COMMON_VP9_COMMON_H_ - -/* Interface header for common constant data structures and lookup tables */ - -#include - -#include "./vpx_config.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx/vpx_integer.h" -#include "vpx_ports/bitops.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// Only need this for fixed-size arrays, for structs just assign. -#define vp9_copy(dest, src) \ - do { \ - assert(sizeof(dest) == sizeof(src)); \ - memcpy(dest, src, sizeof(src)); \ - } while (0) - -// Use this for variably-sized arrays. -#define vp9_copy_array(dest, src, n) \ - { \ - assert(sizeof(*(dest)) == sizeof(*(src))); \ - memcpy(dest, src, (n) * sizeof(*(src))); \ - } - -#define vp9_zero(dest) memset(&(dest), 0, sizeof(dest)) -#define vp9_zero_array(dest, n) memset(dest, 0, (n) * sizeof(*(dest))) - -static INLINE int get_unsigned_bits(unsigned int num_values) { - return num_values > 0 ? get_msb(num_values) + 1 : 0; -} - -#define VP9_SYNC_CODE_0 0x49 -#define VP9_SYNC_CODE_1 0x83 -#define VP9_SYNC_CODE_2 0x42 - -#define VP9_FRAME_MARKER 0x2 - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_COMMON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_common_data.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_common_data.c deleted file mode 100644 index 809d7317..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_common_data.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp9/common/vp9_common_data.h" -#include "vpx_dsp/vpx_dsp_common.h" - -// Log 2 conversion lookup tables for block width and height -const uint8_t b_width_log2_lookup[BLOCK_SIZES] = { 0, 0, 1, 1, 1, 2, 2, - 2, 3, 3, 3, 4, 4 }; -const uint8_t b_height_log2_lookup[BLOCK_SIZES] = { 0, 1, 0, 1, 2, 1, 2, - 3, 2, 3, 4, 3, 4 }; -const uint8_t num_4x4_blocks_wide_lookup[BLOCK_SIZES] = { 1, 1, 2, 2, 2, 4, 4, - 4, 8, 8, 8, 16, 16 }; -const uint8_t num_4x4_blocks_high_lookup[BLOCK_SIZES] = { 1, 2, 1, 2, 4, 2, 4, - 8, 4, 8, 16, 8, 16 }; -// Log 2 conversion lookup tables for modeinfo width and height -const uint8_t mi_width_log2_lookup[BLOCK_SIZES] = { 0, 0, 0, 0, 0, 1, 1, - 1, 2, 2, 2, 3, 3 }; -const uint8_t num_8x8_blocks_wide_lookup[BLOCK_SIZES] = { 1, 1, 1, 1, 1, 2, 2, - 2, 4, 4, 4, 8, 8 }; -const uint8_t num_8x8_blocks_high_lookup[BLOCK_SIZES] = { 1, 1, 1, 1, 2, 1, 2, - 4, 2, 4, 8, 4, 8 }; - -// VPXMIN(3, VPXMIN(b_width_log2_lookup(bsize), b_height_log2_lookup(bsize))) -const uint8_t size_group_lookup[BLOCK_SIZES] = { 0, 0, 0, 1, 1, 1, 2, - 2, 2, 3, 3, 3, 3 }; - -const uint8_t num_pels_log2_lookup[BLOCK_SIZES] = { 4, 5, 5, 6, 7, 7, 8, - 9, 9, 10, 11, 11, 12 }; - -const PARTITION_TYPE partition_lookup[][BLOCK_SIZES] = { - { // 4X4 - // 4X4, 4X8,8X4,8X8,8X16,16X8,16X16,16X32,32X16,32X32,32X64,64X32,64X64 - PARTITION_NONE, PARTITION_INVALID, PARTITION_INVALID, PARTITION_INVALID, - PARTITION_INVALID, PARTITION_INVALID, PARTITION_INVALID, PARTITION_INVALID, - PARTITION_INVALID, PARTITION_INVALID, PARTITION_INVALID, PARTITION_INVALID, - PARTITION_INVALID }, - { // 8X8 - // 4X4, 4X8,8X4,8X8,8X16,16X8,16X16,16X32,32X16,32X32,32X64,64X32,64X64 - PARTITION_SPLIT, PARTITION_VERT, PARTITION_HORZ, PARTITION_NONE, - PARTITION_INVALID, PARTITION_INVALID, PARTITION_INVALID, PARTITION_INVALID, - PARTITION_INVALID, PARTITION_INVALID, PARTITION_INVALID, PARTITION_INVALID, - PARTITION_INVALID }, - { // 16X16 - // 4X4, 4X8,8X4,8X8,8X16,16X8,16X16,16X32,32X16,32X32,32X64,64X32,64X64 - PARTITION_SPLIT, PARTITION_SPLIT, PARTITION_SPLIT, PARTITION_SPLIT, - PARTITION_VERT, PARTITION_HORZ, PARTITION_NONE, PARTITION_INVALID, - PARTITION_INVALID, PARTITION_INVALID, PARTITION_INVALID, PARTITION_INVALID, - PARTITION_INVALID }, - { // 32X32 - // 4X4, 4X8,8X4,8X8,8X16,16X8,16X16,16X32,32X16,32X32,32X64,64X32,64X64 - PARTITION_SPLIT, PARTITION_SPLIT, PARTITION_SPLIT, PARTITION_SPLIT, - PARTITION_SPLIT, PARTITION_SPLIT, PARTITION_SPLIT, PARTITION_VERT, - PARTITION_HORZ, PARTITION_NONE, PARTITION_INVALID, PARTITION_INVALID, - PARTITION_INVALID }, - { // 64X64 - // 4X4, 4X8,8X4,8X8,8X16,16X8,16X16,16X32,32X16,32X32,32X64,64X32,64X64 - PARTITION_SPLIT, PARTITION_SPLIT, PARTITION_SPLIT, PARTITION_SPLIT, - PARTITION_SPLIT, PARTITION_SPLIT, PARTITION_SPLIT, PARTITION_SPLIT, - PARTITION_SPLIT, PARTITION_SPLIT, PARTITION_VERT, PARTITION_HORZ, - PARTITION_NONE } -}; - -const BLOCK_SIZE subsize_lookup[PARTITION_TYPES][BLOCK_SIZES] = { - { // PARTITION_NONE - BLOCK_4X4, BLOCK_4X8, BLOCK_8X4, BLOCK_8X8, BLOCK_8X16, BLOCK_16X8, - BLOCK_16X16, BLOCK_16X32, BLOCK_32X16, BLOCK_32X32, BLOCK_32X64, - BLOCK_64X32, BLOCK_64X64 }, - { // PARTITION_HORZ - BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, BLOCK_8X4, BLOCK_INVALID, - BLOCK_INVALID, BLOCK_16X8, BLOCK_INVALID, BLOCK_INVALID, BLOCK_32X16, - BLOCK_INVALID, BLOCK_INVALID, BLOCK_64X32 }, - { // PARTITION_VERT - BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, BLOCK_4X8, BLOCK_INVALID, - BLOCK_INVALID, BLOCK_8X16, BLOCK_INVALID, BLOCK_INVALID, BLOCK_16X32, - BLOCK_INVALID, BLOCK_INVALID, BLOCK_32X64 }, - { // PARTITION_SPLIT - BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, BLOCK_4X4, BLOCK_INVALID, - BLOCK_INVALID, BLOCK_8X8, BLOCK_INVALID, BLOCK_INVALID, BLOCK_16X16, - BLOCK_INVALID, BLOCK_INVALID, BLOCK_32X32 } -}; - -const TX_SIZE max_txsize_lookup[BLOCK_SIZES] = { - TX_4X4, TX_4X4, TX_4X4, TX_8X8, TX_8X8, TX_8X8, TX_16X16, - TX_16X16, TX_16X16, TX_32X32, TX_32X32, TX_32X32, TX_32X32 -}; - -const BLOCK_SIZE txsize_to_bsize[TX_SIZES] = { - BLOCK_4X4, // TX_4X4 - BLOCK_8X8, // TX_8X8 - BLOCK_16X16, // TX_16X16 - BLOCK_32X32, // TX_32X32 -}; - -const TX_SIZE tx_mode_to_biggest_tx_size[TX_MODES] = { - TX_4X4, // ONLY_4X4 - TX_8X8, // ALLOW_8X8 - TX_16X16, // ALLOW_16X16 - TX_32X32, // ALLOW_32X32 - TX_32X32, // TX_MODE_SELECT -}; - -const BLOCK_SIZE ss_size_lookup[BLOCK_SIZES][2][2] = { - // ss_x == 0 ss_x == 0 ss_x == 1 ss_x == 1 - // ss_y == 0 ss_y == 1 ss_y == 0 ss_y == 1 - { { BLOCK_4X4, BLOCK_INVALID }, { BLOCK_INVALID, BLOCK_INVALID } }, - { { BLOCK_4X8, BLOCK_4X4 }, { BLOCK_INVALID, BLOCK_INVALID } }, - { { BLOCK_8X4, BLOCK_INVALID }, { BLOCK_4X4, BLOCK_INVALID } }, - { { BLOCK_8X8, BLOCK_8X4 }, { BLOCK_4X8, BLOCK_4X4 } }, - { { BLOCK_8X16, BLOCK_8X8 }, { BLOCK_INVALID, BLOCK_4X8 } }, - { { BLOCK_16X8, BLOCK_INVALID }, { BLOCK_8X8, BLOCK_8X4 } }, - { { BLOCK_16X16, BLOCK_16X8 }, { BLOCK_8X16, BLOCK_8X8 } }, - { { BLOCK_16X32, BLOCK_16X16 }, { BLOCK_INVALID, BLOCK_8X16 } }, - { { BLOCK_32X16, BLOCK_INVALID }, { BLOCK_16X16, BLOCK_16X8 } }, - { { BLOCK_32X32, BLOCK_32X16 }, { BLOCK_16X32, BLOCK_16X16 } }, - { { BLOCK_32X64, BLOCK_32X32 }, { BLOCK_INVALID, BLOCK_16X32 } }, - { { BLOCK_64X32, BLOCK_INVALID }, { BLOCK_32X32, BLOCK_32X16 } }, - { { BLOCK_64X64, BLOCK_64X32 }, { BLOCK_32X64, BLOCK_32X32 } }, -}; - -const TX_SIZE uv_txsize_lookup[BLOCK_SIZES][TX_SIZES][2][2] = { - // ss_x == 0 ss_x == 0 ss_x == 1 ss_x == 1 - // ss_y == 0 ss_y == 1 ss_y == 0 ss_y == 1 - { - // BLOCK_4X4 - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - }, - { - // BLOCK_4X8 - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - }, - { - // BLOCK_8X4 - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - }, - { - // BLOCK_8X8 - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_8X8, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_8X8, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_8X8, TX_4X4 }, { TX_4X4, TX_4X4 } }, - }, - { - // BLOCK_8X16 - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_8X8, TX_8X8 }, { TX_4X4, TX_4X4 } }, - { { TX_8X8, TX_8X8 }, { TX_4X4, TX_4X4 } }, - { { TX_8X8, TX_8X8 }, { TX_4X4, TX_4X4 } }, - }, - { - // BLOCK_16X8 - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_8X8, TX_4X4 }, { TX_8X8, TX_4X4 } }, - { { TX_8X8, TX_4X4 }, { TX_8X8, TX_8X8 } }, - { { TX_8X8, TX_4X4 }, { TX_8X8, TX_8X8 } }, - }, - { - // BLOCK_16X16 - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_8X8, TX_8X8 }, { TX_8X8, TX_8X8 } }, - { { TX_16X16, TX_8X8 }, { TX_8X8, TX_8X8 } }, - { { TX_16X16, TX_8X8 }, { TX_8X8, TX_8X8 } }, - }, - { - // BLOCK_16X32 - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_8X8, TX_8X8 }, { TX_8X8, TX_8X8 } }, - { { TX_16X16, TX_16X16 }, { TX_8X8, TX_8X8 } }, - { { TX_16X16, TX_16X16 }, { TX_8X8, TX_8X8 } }, - }, - { - // BLOCK_32X16 - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_8X8, TX_8X8 }, { TX_8X8, TX_8X8 } }, - { { TX_16X16, TX_8X8 }, { TX_16X16, TX_8X8 } }, - { { TX_16X16, TX_8X8 }, { TX_16X16, TX_8X8 } }, - }, - { - // BLOCK_32X32 - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_8X8, TX_8X8 }, { TX_8X8, TX_8X8 } }, - { { TX_16X16, TX_16X16 }, { TX_16X16, TX_16X16 } }, - { { TX_32X32, TX_16X16 }, { TX_16X16, TX_16X16 } }, - }, - { - // BLOCK_32X64 - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_8X8, TX_8X8 }, { TX_8X8, TX_8X8 } }, - { { TX_16X16, TX_16X16 }, { TX_16X16, TX_16X16 } }, - { { TX_32X32, TX_32X32 }, { TX_16X16, TX_16X16 } }, - }, - { - // BLOCK_64X32 - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_8X8, TX_8X8 }, { TX_8X8, TX_8X8 } }, - { { TX_16X16, TX_16X16 }, { TX_16X16, TX_16X16 } }, - { { TX_32X32, TX_16X16 }, { TX_32X32, TX_16X16 } }, - }, - { - // BLOCK_64X64 - { { TX_4X4, TX_4X4 }, { TX_4X4, TX_4X4 } }, - { { TX_8X8, TX_8X8 }, { TX_8X8, TX_8X8 } }, - { { TX_16X16, TX_16X16 }, { TX_16X16, TX_16X16 } }, - { { TX_32X32, TX_32X32 }, { TX_32X32, TX_32X32 } }, - }, -}; - -// Generates 4 bit field in which each bit set to 1 represents -// a blocksize partition 1111 means we split 64x64, 32x32, 16x16 -// and 8x8. 1000 means we just split the 64x64 to 32x32 -const struct { - PARTITION_CONTEXT above; - PARTITION_CONTEXT left; -} partition_context_lookup[BLOCK_SIZES] = { - { 15, 15 }, // 4X4 - {0b1111, 0b1111} - { 15, 14 }, // 4X8 - {0b1111, 0b1110} - { 14, 15 }, // 8X4 - {0b1110, 0b1111} - { 14, 14 }, // 8X8 - {0b1110, 0b1110} - { 14, 12 }, // 8X16 - {0b1110, 0b1100} - { 12, 14 }, // 16X8 - {0b1100, 0b1110} - { 12, 12 }, // 16X16 - {0b1100, 0b1100} - { 12, 8 }, // 16X32 - {0b1100, 0b1000} - { 8, 12 }, // 32X16 - {0b1000, 0b1100} - { 8, 8 }, // 32X32 - {0b1000, 0b1000} - { 8, 0 }, // 32X64 - {0b1000, 0b0000} - { 0, 8 }, // 64X32 - {0b0000, 0b1000} - { 0, 0 }, // 64X64 - {0b0000, 0b0000} -}; - -#if CONFIG_BETTER_HW_COMPATIBILITY && CONFIG_VP9_HIGHBITDEPTH -const uint8_t need_top_left[INTRA_MODES] = { - 0, // DC_PRED - 0, // V_PRED - 0, // H_PRED - 0, // D45_PRED - 1, // D135_PRED - 1, // D117_PRED - 1, // D153_PRED - 0, // D207_PRED - 0, // D63_PRED - 1, // TM_PRED -}; -#endif // CONFIG_BETTER_HW_COMPATIBILITY && CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_common_data.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_common_data.h deleted file mode 100644 index a533c5f0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_common_data.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_COMMON_DATA_H_ -#define VPX_VP9_COMMON_VP9_COMMON_DATA_H_ - -#include "vp9/common/vp9_enums.h" -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const uint8_t b_width_log2_lookup[BLOCK_SIZES]; -extern const uint8_t b_height_log2_lookup[BLOCK_SIZES]; -extern const uint8_t mi_width_log2_lookup[BLOCK_SIZES]; -extern const uint8_t num_8x8_blocks_wide_lookup[BLOCK_SIZES]; -extern const uint8_t num_8x8_blocks_high_lookup[BLOCK_SIZES]; -extern const uint8_t num_4x4_blocks_high_lookup[BLOCK_SIZES]; -extern const uint8_t num_4x4_blocks_wide_lookup[BLOCK_SIZES]; -extern const uint8_t size_group_lookup[BLOCK_SIZES]; -extern const uint8_t num_pels_log2_lookup[BLOCK_SIZES]; -extern const PARTITION_TYPE partition_lookup[][BLOCK_SIZES]; -extern const BLOCK_SIZE subsize_lookup[PARTITION_TYPES][BLOCK_SIZES]; -extern const TX_SIZE max_txsize_lookup[BLOCK_SIZES]; -extern const BLOCK_SIZE txsize_to_bsize[TX_SIZES]; -extern const TX_SIZE tx_mode_to_biggest_tx_size[TX_MODES]; -extern const BLOCK_SIZE ss_size_lookup[BLOCK_SIZES][2][2]; -extern const TX_SIZE uv_txsize_lookup[BLOCK_SIZES][TX_SIZES][2][2]; -#if CONFIG_BETTER_HW_COMPATIBILITY && CONFIG_VP9_HIGHBITDEPTH -extern const uint8_t need_top_left[INTRA_MODES]; -#endif // CONFIG_BETTER_HW_COMPATIBILITY && CONFIG_VP9_HIGHBITDEPTH - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_COMMON_DATA_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_debugmodes.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_debugmodes.c deleted file mode 100644 index 28cd4a19..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_debugmodes.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_onyxc_int.h" - -static void log_frame_info(VP9_COMMON *cm, const char *str, FILE *f) { - fprintf(f, "%s", str); - fprintf(f, "(Frame %d, Show:%d, Q:%d): \n", cm->current_video_frame, - cm->show_frame, cm->base_qindex); -} -/* This function dereferences a pointer to the mbmi structure - * and uses the passed in member offset to print out the value of an integer - * for each mbmi member value in the mi structure. - */ -static void print_mi_data(VP9_COMMON *cm, FILE *file, const char *descriptor, - size_t member_offset) { - int mi_row, mi_col; - MODE_INFO **mi = cm->mi_grid_visible; - int rows = cm->mi_rows; - int cols = cm->mi_cols; - char prefix = descriptor[0]; - - log_frame_info(cm, descriptor, file); - for (mi_row = 0; mi_row < rows; mi_row++) { - fprintf(file, "%c ", prefix); - for (mi_col = 0; mi_col < cols; mi_col++) { - fprintf(file, "%2d ", *((char *)((char *)(mi[0]) + member_offset))); - mi++; - } - fprintf(file, "\n"); - mi += 8; - } - fprintf(file, "\n"); -} - -void vp9_print_modes_and_motion_vectors(VP9_COMMON *cm, const char *file) { - int mi_row; - int mi_col; - FILE *mvs = fopen(file, "a"); - MODE_INFO **mi = cm->mi_grid_visible; - int rows = cm->mi_rows; - int cols = cm->mi_cols; - - print_mi_data(cm, mvs, "Partitions:", offsetof(MODE_INFO, sb_type)); - print_mi_data(cm, mvs, "Modes:", offsetof(MODE_INFO, mode)); - print_mi_data(cm, mvs, "Ref frame:", offsetof(MODE_INFO, ref_frame[0])); - print_mi_data(cm, mvs, "Transform:", offsetof(MODE_INFO, tx_size)); - print_mi_data(cm, mvs, "UV Modes:", offsetof(MODE_INFO, uv_mode)); - - // output skip infomation. - log_frame_info(cm, "Skips:", mvs); - for (mi_row = 0; mi_row < rows; mi_row++) { - fprintf(mvs, "S "); - for (mi_col = 0; mi_col < cols; mi_col++) { - fprintf(mvs, "%2d ", mi[0]->skip); - mi++; - } - fprintf(mvs, "\n"); - mi += 8; - } - fprintf(mvs, "\n"); - - // output motion vectors. - log_frame_info(cm, "Vectors ", mvs); - mi = cm->mi_grid_visible; - for (mi_row = 0; mi_row < rows; mi_row++) { - fprintf(mvs, "V "); - for (mi_col = 0; mi_col < cols; mi_col++) { - fprintf(mvs, "%4d:%4d ", mi[0]->mv[0].as_mv.row, mi[0]->mv[0].as_mv.col); - mi++; - } - fprintf(mvs, "\n"); - mi += 8; - } - fprintf(mvs, "\n"); - - fclose(mvs); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropy.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropy.c deleted file mode 100644 index 430b917b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropy.c +++ /dev/null @@ -1,1100 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp9/common/vp9_entropy.h" -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_onyxc_int.h" -#include "vp9/common/vp9_entropymode.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx/vpx_integer.h" - -// Unconstrained Node Tree -/* clang-format off */ -const vpx_tree_index vp9_coef_con_tree[TREE_SIZE(ENTROPY_TOKENS)] = { - 2, 6, // 0 = LOW_VAL - -TWO_TOKEN, 4, // 1 = TWO - -THREE_TOKEN, -FOUR_TOKEN, // 2 = THREE - 8, 10, // 3 = HIGH_LOW - -CATEGORY1_TOKEN, -CATEGORY2_TOKEN, // 4 = CAT_ONE - 12, 14, // 5 = CAT_THREEFOUR - -CATEGORY3_TOKEN, -CATEGORY4_TOKEN, // 6 = CAT_THREE - -CATEGORY5_TOKEN, -CATEGORY6_TOKEN // 7 = CAT_FIVE -}; -/* clang-format on */ - -const vpx_prob vp9_cat1_prob[] = { 159 }; -const vpx_prob vp9_cat2_prob[] = { 165, 145 }; -const vpx_prob vp9_cat3_prob[] = { 173, 148, 140 }; -const vpx_prob vp9_cat4_prob[] = { 176, 155, 140, 135 }; -const vpx_prob vp9_cat5_prob[] = { 180, 157, 141, 134, 130 }; -const vpx_prob vp9_cat6_prob[] = { 254, 254, 254, 252, 249, 243, 230, - 196, 177, 153, 140, 133, 130, 129 }; -#if CONFIG_VP9_HIGHBITDEPTH -const vpx_prob vp9_cat6_prob_high12[] = { 255, 255, 255, 255, 254, 254, - 254, 252, 249, 243, 230, 196, - 177, 153, 140, 133, 130, 129 }; -#endif - -/* clang-format off */ -const uint8_t vp9_coefband_trans_8x8plus[1024] = { - 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, - // beyond MAXBAND_INDEX+1 all values are filled as 5 - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -}; -/* clang-format on */ - -const uint8_t vp9_coefband_trans_4x4[16] = { - 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, -}; - -const uint8_t vp9_pt_energy_class[ENTROPY_TOKENS] = { 0, 1, 2, 3, 3, 4, - 4, 5, 5, 5, 5, 5 }; - -// Model obtained from a 2-sided zero-centerd distribuition derived -// from a Pareto distribution. The cdf of the distribution is: -// cdf(x) = 0.5 + 0.5 * sgn(x) * [1 - {alpha/(alpha + |x|)} ^ beta] -// -// For a given beta and a given probablity of the 1-node, the alpha -// is first solved, and then the {alpha, beta} pair is used to generate -// the probabilities for the rest of the nodes. - -// beta = 8 - -// Every odd line in this table can be generated from the even lines -// by averaging : -// vp9_pareto8_full[l][node] = (vp9_pareto8_full[l-1][node] + -// vp9_pareto8_full[l+1][node] ) >> 1; -const vpx_prob vp9_pareto8_full[COEFF_PROB_MODELS][MODEL_NODES] = { - { 3, 86, 128, 6, 86, 23, 88, 29 }, - { 6, 86, 128, 11, 87, 42, 91, 52 }, - { 9, 86, 129, 17, 88, 61, 94, 76 }, - { 12, 86, 129, 22, 88, 77, 97, 93 }, - { 15, 87, 129, 28, 89, 93, 100, 110 }, - { 17, 87, 129, 33, 90, 105, 103, 123 }, - { 20, 88, 130, 38, 91, 118, 106, 136 }, - { 23, 88, 130, 43, 91, 128, 108, 146 }, - { 26, 89, 131, 48, 92, 139, 111, 156 }, - { 28, 89, 131, 53, 93, 147, 114, 163 }, - { 31, 90, 131, 58, 94, 156, 117, 171 }, - { 34, 90, 131, 62, 94, 163, 119, 177 }, - { 37, 90, 132, 66, 95, 171, 122, 184 }, - { 39, 90, 132, 70, 96, 177, 124, 189 }, - { 42, 91, 132, 75, 97, 183, 127, 194 }, - { 44, 91, 132, 79, 97, 188, 129, 198 }, - { 47, 92, 133, 83, 98, 193, 132, 202 }, - { 49, 92, 133, 86, 99, 197, 134, 205 }, - { 52, 93, 133, 90, 100, 201, 137, 208 }, - { 54, 93, 133, 94, 100, 204, 139, 211 }, - { 57, 94, 134, 98, 101, 208, 142, 214 }, - { 59, 94, 134, 101, 102, 211, 144, 216 }, - { 62, 94, 135, 105, 103, 214, 146, 218 }, - { 64, 94, 135, 108, 103, 216, 148, 220 }, - { 66, 95, 135, 111, 104, 219, 151, 222 }, - { 68, 95, 135, 114, 105, 221, 153, 223 }, - { 71, 96, 136, 117, 106, 224, 155, 225 }, - { 73, 96, 136, 120, 106, 225, 157, 226 }, - { 76, 97, 136, 123, 107, 227, 159, 228 }, - { 78, 97, 136, 126, 108, 229, 160, 229 }, - { 80, 98, 137, 129, 109, 231, 162, 231 }, - { 82, 98, 137, 131, 109, 232, 164, 232 }, - { 84, 98, 138, 134, 110, 234, 166, 233 }, - { 86, 98, 138, 137, 111, 235, 168, 234 }, - { 89, 99, 138, 140, 112, 236, 170, 235 }, - { 91, 99, 138, 142, 112, 237, 171, 235 }, - { 93, 100, 139, 145, 113, 238, 173, 236 }, - { 95, 100, 139, 147, 114, 239, 174, 237 }, - { 97, 101, 140, 149, 115, 240, 176, 238 }, - { 99, 101, 140, 151, 115, 241, 177, 238 }, - { 101, 102, 140, 154, 116, 242, 179, 239 }, - { 103, 102, 140, 156, 117, 242, 180, 239 }, - { 105, 103, 141, 158, 118, 243, 182, 240 }, - { 107, 103, 141, 160, 118, 243, 183, 240 }, - { 109, 104, 141, 162, 119, 244, 185, 241 }, - { 111, 104, 141, 164, 119, 244, 186, 241 }, - { 113, 104, 142, 166, 120, 245, 187, 242 }, - { 114, 104, 142, 168, 121, 245, 188, 242 }, - { 116, 105, 143, 170, 122, 246, 190, 243 }, - { 118, 105, 143, 171, 122, 246, 191, 243 }, - { 120, 106, 143, 173, 123, 247, 192, 244 }, - { 121, 106, 143, 175, 124, 247, 193, 244 }, - { 123, 107, 144, 177, 125, 248, 195, 244 }, - { 125, 107, 144, 178, 125, 248, 196, 244 }, - { 127, 108, 145, 180, 126, 249, 197, 245 }, - { 128, 108, 145, 181, 127, 249, 198, 245 }, - { 130, 109, 145, 183, 128, 249, 199, 245 }, - { 132, 109, 145, 184, 128, 249, 200, 245 }, - { 134, 110, 146, 186, 129, 250, 201, 246 }, - { 135, 110, 146, 187, 130, 250, 202, 246 }, - { 137, 111, 147, 189, 131, 251, 203, 246 }, - { 138, 111, 147, 190, 131, 251, 204, 246 }, - { 140, 112, 147, 192, 132, 251, 205, 247 }, - { 141, 112, 147, 193, 132, 251, 206, 247 }, - { 143, 113, 148, 194, 133, 251, 207, 247 }, - { 144, 113, 148, 195, 134, 251, 207, 247 }, - { 146, 114, 149, 197, 135, 252, 208, 248 }, - { 147, 114, 149, 198, 135, 252, 209, 248 }, - { 149, 115, 149, 199, 136, 252, 210, 248 }, - { 150, 115, 149, 200, 137, 252, 210, 248 }, - { 152, 115, 150, 201, 138, 252, 211, 248 }, - { 153, 115, 150, 202, 138, 252, 212, 248 }, - { 155, 116, 151, 204, 139, 253, 213, 249 }, - { 156, 116, 151, 205, 139, 253, 213, 249 }, - { 158, 117, 151, 206, 140, 253, 214, 249 }, - { 159, 117, 151, 207, 141, 253, 215, 249 }, - { 161, 118, 152, 208, 142, 253, 216, 249 }, - { 162, 118, 152, 209, 142, 253, 216, 249 }, - { 163, 119, 153, 210, 143, 253, 217, 249 }, - { 164, 119, 153, 211, 143, 253, 217, 249 }, - { 166, 120, 153, 212, 144, 254, 218, 250 }, - { 167, 120, 153, 212, 145, 254, 219, 250 }, - { 168, 121, 154, 213, 146, 254, 220, 250 }, - { 169, 121, 154, 214, 146, 254, 220, 250 }, - { 171, 122, 155, 215, 147, 254, 221, 250 }, - { 172, 122, 155, 216, 147, 254, 221, 250 }, - { 173, 123, 155, 217, 148, 254, 222, 250 }, - { 174, 123, 155, 217, 149, 254, 222, 250 }, - { 176, 124, 156, 218, 150, 254, 223, 250 }, - { 177, 124, 156, 219, 150, 254, 223, 250 }, - { 178, 125, 157, 220, 151, 254, 224, 251 }, - { 179, 125, 157, 220, 151, 254, 224, 251 }, - { 180, 126, 157, 221, 152, 254, 225, 251 }, - { 181, 126, 157, 221, 152, 254, 225, 251 }, - { 183, 127, 158, 222, 153, 254, 226, 251 }, - { 184, 127, 158, 223, 154, 254, 226, 251 }, - { 185, 128, 159, 224, 155, 255, 227, 251 }, - { 186, 128, 159, 224, 155, 255, 227, 251 }, - { 187, 129, 160, 225, 156, 255, 228, 251 }, - { 188, 130, 160, 225, 156, 255, 228, 251 }, - { 189, 131, 160, 226, 157, 255, 228, 251 }, - { 190, 131, 160, 226, 158, 255, 228, 251 }, - { 191, 132, 161, 227, 159, 255, 229, 251 }, - { 192, 132, 161, 227, 159, 255, 229, 251 }, - { 193, 133, 162, 228, 160, 255, 230, 252 }, - { 194, 133, 162, 229, 160, 255, 230, 252 }, - { 195, 134, 163, 230, 161, 255, 231, 252 }, - { 196, 134, 163, 230, 161, 255, 231, 252 }, - { 197, 135, 163, 231, 162, 255, 231, 252 }, - { 198, 135, 163, 231, 162, 255, 231, 252 }, - { 199, 136, 164, 232, 163, 255, 232, 252 }, - { 200, 136, 164, 232, 164, 255, 232, 252 }, - { 201, 137, 165, 233, 165, 255, 233, 252 }, - { 201, 137, 165, 233, 165, 255, 233, 252 }, - { 202, 138, 166, 233, 166, 255, 233, 252 }, - { 203, 138, 166, 233, 166, 255, 233, 252 }, - { 204, 139, 166, 234, 167, 255, 234, 252 }, - { 205, 139, 166, 234, 167, 255, 234, 252 }, - { 206, 140, 167, 235, 168, 255, 235, 252 }, - { 206, 140, 167, 235, 168, 255, 235, 252 }, - { 207, 141, 168, 236, 169, 255, 235, 252 }, - { 208, 141, 168, 236, 170, 255, 235, 252 }, - { 209, 142, 169, 237, 171, 255, 236, 252 }, - { 209, 143, 169, 237, 171, 255, 236, 252 }, - { 210, 144, 169, 237, 172, 255, 236, 252 }, - { 211, 144, 169, 237, 172, 255, 236, 252 }, - { 212, 145, 170, 238, 173, 255, 237, 252 }, - { 213, 145, 170, 238, 173, 255, 237, 252 }, - { 214, 146, 171, 239, 174, 255, 237, 253 }, - { 214, 146, 171, 239, 174, 255, 237, 253 }, - { 215, 147, 172, 240, 175, 255, 238, 253 }, - { 215, 147, 172, 240, 175, 255, 238, 253 }, - { 216, 148, 173, 240, 176, 255, 238, 253 }, - { 217, 148, 173, 240, 176, 255, 238, 253 }, - { 218, 149, 173, 241, 177, 255, 239, 253 }, - { 218, 149, 173, 241, 178, 255, 239, 253 }, - { 219, 150, 174, 241, 179, 255, 239, 253 }, - { 219, 151, 174, 241, 179, 255, 239, 253 }, - { 220, 152, 175, 242, 180, 255, 240, 253 }, - { 221, 152, 175, 242, 180, 255, 240, 253 }, - { 222, 153, 176, 242, 181, 255, 240, 253 }, - { 222, 153, 176, 242, 181, 255, 240, 253 }, - { 223, 154, 177, 243, 182, 255, 240, 253 }, - { 223, 154, 177, 243, 182, 255, 240, 253 }, - { 224, 155, 178, 244, 183, 255, 241, 253 }, - { 224, 155, 178, 244, 183, 255, 241, 253 }, - { 225, 156, 178, 244, 184, 255, 241, 253 }, - { 225, 157, 178, 244, 184, 255, 241, 253 }, - { 226, 158, 179, 244, 185, 255, 242, 253 }, - { 227, 158, 179, 244, 185, 255, 242, 253 }, - { 228, 159, 180, 245, 186, 255, 242, 253 }, - { 228, 159, 180, 245, 186, 255, 242, 253 }, - { 229, 160, 181, 245, 187, 255, 242, 253 }, - { 229, 160, 181, 245, 187, 255, 242, 253 }, - { 230, 161, 182, 246, 188, 255, 243, 253 }, - { 230, 162, 182, 246, 188, 255, 243, 253 }, - { 231, 163, 183, 246, 189, 255, 243, 253 }, - { 231, 163, 183, 246, 189, 255, 243, 253 }, - { 232, 164, 184, 247, 190, 255, 243, 253 }, - { 232, 164, 184, 247, 190, 255, 243, 253 }, - { 233, 165, 185, 247, 191, 255, 244, 253 }, - { 233, 165, 185, 247, 191, 255, 244, 253 }, - { 234, 166, 185, 247, 192, 255, 244, 253 }, - { 234, 167, 185, 247, 192, 255, 244, 253 }, - { 235, 168, 186, 248, 193, 255, 244, 253 }, - { 235, 168, 186, 248, 193, 255, 244, 253 }, - { 236, 169, 187, 248, 194, 255, 244, 253 }, - { 236, 169, 187, 248, 194, 255, 244, 253 }, - { 236, 170, 188, 248, 195, 255, 245, 253 }, - { 236, 170, 188, 248, 195, 255, 245, 253 }, - { 237, 171, 189, 249, 196, 255, 245, 254 }, - { 237, 172, 189, 249, 196, 255, 245, 254 }, - { 238, 173, 190, 249, 197, 255, 245, 254 }, - { 238, 173, 190, 249, 197, 255, 245, 254 }, - { 239, 174, 191, 249, 198, 255, 245, 254 }, - { 239, 174, 191, 249, 198, 255, 245, 254 }, - { 240, 175, 192, 249, 199, 255, 246, 254 }, - { 240, 176, 192, 249, 199, 255, 246, 254 }, - { 240, 177, 193, 250, 200, 255, 246, 254 }, - { 240, 177, 193, 250, 200, 255, 246, 254 }, - { 241, 178, 194, 250, 201, 255, 246, 254 }, - { 241, 178, 194, 250, 201, 255, 246, 254 }, - { 242, 179, 195, 250, 202, 255, 246, 254 }, - { 242, 180, 195, 250, 202, 255, 246, 254 }, - { 242, 181, 196, 250, 203, 255, 247, 254 }, - { 242, 181, 196, 250, 203, 255, 247, 254 }, - { 243, 182, 197, 251, 204, 255, 247, 254 }, - { 243, 183, 197, 251, 204, 255, 247, 254 }, - { 244, 184, 198, 251, 205, 255, 247, 254 }, - { 244, 184, 198, 251, 205, 255, 247, 254 }, - { 244, 185, 199, 251, 206, 255, 247, 254 }, - { 244, 185, 199, 251, 206, 255, 247, 254 }, - { 245, 186, 200, 251, 207, 255, 247, 254 }, - { 245, 187, 200, 251, 207, 255, 247, 254 }, - { 246, 188, 201, 252, 207, 255, 248, 254 }, - { 246, 188, 201, 252, 207, 255, 248, 254 }, - { 246, 189, 202, 252, 208, 255, 248, 254 }, - { 246, 190, 202, 252, 208, 255, 248, 254 }, - { 247, 191, 203, 252, 209, 255, 248, 254 }, - { 247, 191, 203, 252, 209, 255, 248, 254 }, - { 247, 192, 204, 252, 210, 255, 248, 254 }, - { 247, 193, 204, 252, 210, 255, 248, 254 }, - { 248, 194, 205, 252, 211, 255, 248, 254 }, - { 248, 194, 205, 252, 211, 255, 248, 254 }, - { 248, 195, 206, 252, 212, 255, 249, 254 }, - { 248, 196, 206, 252, 212, 255, 249, 254 }, - { 249, 197, 207, 253, 213, 255, 249, 254 }, - { 249, 197, 207, 253, 213, 255, 249, 254 }, - { 249, 198, 208, 253, 214, 255, 249, 254 }, - { 249, 199, 209, 253, 214, 255, 249, 254 }, - { 250, 200, 210, 253, 215, 255, 249, 254 }, - { 250, 200, 210, 253, 215, 255, 249, 254 }, - { 250, 201, 211, 253, 215, 255, 249, 254 }, - { 250, 202, 211, 253, 215, 255, 249, 254 }, - { 250, 203, 212, 253, 216, 255, 249, 254 }, - { 250, 203, 212, 253, 216, 255, 249, 254 }, - { 251, 204, 213, 253, 217, 255, 250, 254 }, - { 251, 205, 213, 253, 217, 255, 250, 254 }, - { 251, 206, 214, 254, 218, 255, 250, 254 }, - { 251, 206, 215, 254, 218, 255, 250, 254 }, - { 252, 207, 216, 254, 219, 255, 250, 254 }, - { 252, 208, 216, 254, 219, 255, 250, 254 }, - { 252, 209, 217, 254, 220, 255, 250, 254 }, - { 252, 210, 217, 254, 220, 255, 250, 254 }, - { 252, 211, 218, 254, 221, 255, 250, 254 }, - { 252, 212, 218, 254, 221, 255, 250, 254 }, - { 253, 213, 219, 254, 222, 255, 250, 254 }, - { 253, 213, 220, 254, 222, 255, 250, 254 }, - { 253, 214, 221, 254, 223, 255, 250, 254 }, - { 253, 215, 221, 254, 223, 255, 250, 254 }, - { 253, 216, 222, 254, 224, 255, 251, 254 }, - { 253, 217, 223, 254, 224, 255, 251, 254 }, - { 253, 218, 224, 254, 225, 255, 251, 254 }, - { 253, 219, 224, 254, 225, 255, 251, 254 }, - { 254, 220, 225, 254, 225, 255, 251, 254 }, - { 254, 221, 226, 254, 225, 255, 251, 254 }, - { 254, 222, 227, 255, 226, 255, 251, 254 }, - { 254, 223, 227, 255, 226, 255, 251, 254 }, - { 254, 224, 228, 255, 227, 255, 251, 254 }, - { 254, 225, 229, 255, 227, 255, 251, 254 }, - { 254, 226, 230, 255, 228, 255, 251, 254 }, - { 254, 227, 230, 255, 229, 255, 251, 254 }, - { 255, 228, 231, 255, 230, 255, 251, 254 }, - { 255, 229, 232, 255, 230, 255, 251, 254 }, - { 255, 230, 233, 255, 231, 255, 252, 254 }, - { 255, 231, 234, 255, 231, 255, 252, 254 }, - { 255, 232, 235, 255, 232, 255, 252, 254 }, - { 255, 233, 236, 255, 232, 255, 252, 254 }, - { 255, 235, 237, 255, 233, 255, 252, 254 }, - { 255, 236, 238, 255, 234, 255, 252, 254 }, - { 255, 238, 240, 255, 235, 255, 252, 255 }, - { 255, 239, 241, 255, 235, 255, 252, 254 }, - { 255, 241, 243, 255, 236, 255, 252, 254 }, - { 255, 243, 245, 255, 237, 255, 252, 254 }, - { 255, 246, 247, 255, 239, 255, 253, 255 }, -}; - -static const vp9_coeff_probs_model default_coef_probs_4x4[PLANE_TYPES] = { - { // Y plane - { // Intra - { // Band 0 - { 195, 29, 183 }, - { 84, 49, 136 }, - { 8, 42, 71 } }, - { // Band 1 - { 31, 107, 169 }, - { 35, 99, 159 }, - { 17, 82, 140 }, - { 8, 66, 114 }, - { 2, 44, 76 }, - { 1, 19, 32 } }, - { // Band 2 - { 40, 132, 201 }, - { 29, 114, 187 }, - { 13, 91, 157 }, - { 7, 75, 127 }, - { 3, 58, 95 }, - { 1, 28, 47 } }, - { // Band 3 - { 69, 142, 221 }, - { 42, 122, 201 }, - { 15, 91, 159 }, - { 6, 67, 121 }, - { 1, 42, 77 }, - { 1, 17, 31 } }, - { // Band 4 - { 102, 148, 228 }, - { 67, 117, 204 }, - { 17, 82, 154 }, - { 6, 59, 114 }, - { 2, 39, 75 }, - { 1, 15, 29 } }, - { // Band 5 - { 156, 57, 233 }, - { 119, 57, 212 }, - { 58, 48, 163 }, - { 29, 40, 124 }, - { 12, 30, 81 }, - { 3, 12, 31 } } }, - { // Inter - { // Band 0 - { 191, 107, 226 }, - { 124, 117, 204 }, - { 25, 99, 155 } }, - { // Band 1 - { 29, 148, 210 }, - { 37, 126, 194 }, - { 8, 93, 157 }, - { 2, 68, 118 }, - { 1, 39, 69 }, - { 1, 17, 33 } }, - { // Band 2 - { 41, 151, 213 }, - { 27, 123, 193 }, - { 3, 82, 144 }, - { 1, 58, 105 }, - { 1, 32, 60 }, - { 1, 13, 26 } }, - { // Band 3 - { 59, 159, 220 }, - { 23, 126, 198 }, - { 4, 88, 151 }, - { 1, 66, 114 }, - { 1, 38, 71 }, - { 1, 18, 34 } }, - { // Band 4 - { 114, 136, 232 }, - { 51, 114, 207 }, - { 11, 83, 155 }, - { 3, 56, 105 }, - { 1, 33, 65 }, - { 1, 17, 34 } }, - { // Band 5 - { 149, 65, 234 }, - { 121, 57, 215 }, - { 61, 49, 166 }, - { 28, 36, 114 }, - { 12, 25, 76 }, - { 3, 16, 42 } } } }, - { // UV plane - { // Intra - { // Band 0 - { 214, 49, 220 }, - { 132, 63, 188 }, - { 42, 65, 137 } }, - { // Band 1 - { 85, 137, 221 }, - { 104, 131, 216 }, - { 49, 111, 192 }, - { 21, 87, 155 }, - { 2, 49, 87 }, - { 1, 16, 28 } }, - { // Band 2 - { 89, 163, 230 }, - { 90, 137, 220 }, - { 29, 100, 183 }, - { 10, 70, 135 }, - { 2, 42, 81 }, - { 1, 17, 33 } }, - { // Band 3 - { 108, 167, 237 }, - { 55, 133, 222 }, - { 15, 97, 179 }, - { 4, 72, 135 }, - { 1, 45, 85 }, - { 1, 19, 38 } }, - { // Band 4 - { 124, 146, 240 }, - { 66, 124, 224 }, - { 17, 88, 175 }, - { 4, 58, 122 }, - { 1, 36, 75 }, - { 1, 18, 37 } }, - { // Band 5 - { 141, 79, 241 }, - { 126, 70, 227 }, - { 66, 58, 182 }, - { 30, 44, 136 }, - { 12, 34, 96 }, - { 2, 20, 47 } } }, - { // Inter - { // Band 0 - { 229, 99, 249 }, - { 143, 111, 235 }, - { 46, 109, 192 } }, - { // Band 1 - { 82, 158, 236 }, - { 94, 146, 224 }, - { 25, 117, 191 }, - { 9, 87, 149 }, - { 3, 56, 99 }, - { 1, 33, 57 } }, - { // Band 2 - { 83, 167, 237 }, - { 68, 145, 222 }, - { 10, 103, 177 }, - { 2, 72, 131 }, - { 1, 41, 79 }, - { 1, 20, 39 } }, - { // Band 3 - { 99, 167, 239 }, - { 47, 141, 224 }, - { 10, 104, 178 }, - { 2, 73, 133 }, - { 1, 44, 85 }, - { 1, 22, 47 } }, - { // Band 4 - { 127, 145, 243 }, - { 71, 129, 228 }, - { 17, 93, 177 }, - { 3, 61, 124 }, - { 1, 41, 84 }, - { 1, 21, 52 } }, - { // Band 5 - { 157, 78, 244 }, - { 140, 72, 231 }, - { 69, 58, 184 }, - { 31, 44, 137 }, - { 14, 38, 105 }, - { 8, 23, 61 } } } } -}; - -static const vp9_coeff_probs_model default_coef_probs_8x8[PLANE_TYPES] = { - { // Y plane - { // Intra - { // Band 0 - { 125, 34, 187 }, - { 52, 41, 133 }, - { 6, 31, 56 } }, - { // Band 1 - { 37, 109, 153 }, - { 51, 102, 147 }, - { 23, 87, 128 }, - { 8, 67, 101 }, - { 1, 41, 63 }, - { 1, 19, 29 } }, - { // Band 2 - { 31, 154, 185 }, - { 17, 127, 175 }, - { 6, 96, 145 }, - { 2, 73, 114 }, - { 1, 51, 82 }, - { 1, 28, 45 } }, - { // Band 3 - { 23, 163, 200 }, - { 10, 131, 185 }, - { 2, 93, 148 }, - { 1, 67, 111 }, - { 1, 41, 69 }, - { 1, 14, 24 } }, - { // Band 4 - { 29, 176, 217 }, - { 12, 145, 201 }, - { 3, 101, 156 }, - { 1, 69, 111 }, - { 1, 39, 63 }, - { 1, 14, 23 } }, - { // Band 5 - { 57, 192, 233 }, - { 25, 154, 215 }, - { 6, 109, 167 }, - { 3, 78, 118 }, - { 1, 48, 69 }, - { 1, 21, 29 } } }, - { // Inter - { // Band 0 - { 202, 105, 245 }, - { 108, 106, 216 }, - { 18, 90, 144 } }, - { // Band 1 - { 33, 172, 219 }, - { 64, 149, 206 }, - { 14, 117, 177 }, - { 5, 90, 141 }, - { 2, 61, 95 }, - { 1, 37, 57 } }, - { // Band 2 - { 33, 179, 220 }, - { 11, 140, 198 }, - { 1, 89, 148 }, - { 1, 60, 104 }, - { 1, 33, 57 }, - { 1, 12, 21 } }, - { // Band 3 - { 30, 181, 221 }, - { 8, 141, 198 }, - { 1, 87, 145 }, - { 1, 58, 100 }, - { 1, 31, 55 }, - { 1, 12, 20 } }, - { // Band 4 - { 32, 186, 224 }, - { 7, 142, 198 }, - { 1, 86, 143 }, - { 1, 58, 100 }, - { 1, 31, 55 }, - { 1, 12, 22 } }, - { // Band 5 - { 57, 192, 227 }, - { 20, 143, 204 }, - { 3, 96, 154 }, - { 1, 68, 112 }, - { 1, 42, 69 }, - { 1, 19, 32 } } } }, - { // UV plane - { // Intra - { // Band 0 - { 212, 35, 215 }, - { 113, 47, 169 }, - { 29, 48, 105 } }, - { // Band 1 - { 74, 129, 203 }, - { 106, 120, 203 }, - { 49, 107, 178 }, - { 19, 84, 144 }, - { 4, 50, 84 }, - { 1, 15, 25 } }, - { // Band 2 - { 71, 172, 217 }, - { 44, 141, 209 }, - { 15, 102, 173 }, - { 6, 76, 133 }, - { 2, 51, 89 }, - { 1, 24, 42 } }, - { // Band 3 - { 64, 185, 231 }, - { 31, 148, 216 }, - { 8, 103, 175 }, - { 3, 74, 131 }, - { 1, 46, 81 }, - { 1, 18, 30 } }, - { // Band 4 - { 65, 196, 235 }, - { 25, 157, 221 }, - { 5, 105, 174 }, - { 1, 67, 120 }, - { 1, 38, 69 }, - { 1, 15, 30 } }, - { // Band 5 - { 65, 204, 238 }, - { 30, 156, 224 }, - { 7, 107, 177 }, - { 2, 70, 124 }, - { 1, 42, 73 }, - { 1, 18, 34 } } }, - { // Inter - { // Band 0 - { 225, 86, 251 }, - { 144, 104, 235 }, - { 42, 99, 181 } }, - { // Band 1 - { 85, 175, 239 }, - { 112, 165, 229 }, - { 29, 136, 200 }, - { 12, 103, 162 }, - { 6, 77, 123 }, - { 2, 53, 84 } }, - { // Band 2 - { 75, 183, 239 }, - { 30, 155, 221 }, - { 3, 106, 171 }, - { 1, 74, 128 }, - { 1, 44, 76 }, - { 1, 17, 28 } }, - { // Band 3 - { 73, 185, 240 }, - { 27, 159, 222 }, - { 2, 107, 172 }, - { 1, 75, 127 }, - { 1, 42, 73 }, - { 1, 17, 29 } }, - { // Band 4 - { 62, 190, 238 }, - { 21, 159, 222 }, - { 2, 107, 172 }, - { 1, 72, 122 }, - { 1, 40, 71 }, - { 1, 18, 32 } }, - { // Band 5 - { 61, 199, 240 }, - { 27, 161, 226 }, - { 4, 113, 180 }, - { 1, 76, 129 }, - { 1, 46, 80 }, - { 1, 23, 41 } } } } -}; - -static const vp9_coeff_probs_model default_coef_probs_16x16[PLANE_TYPES] = { - { // Y plane - { // Intra - { // Band 0 - { 7, 27, 153 }, - { 5, 30, 95 }, - { 1, 16, 30 } }, - { // Band 1 - { 50, 75, 127 }, - { 57, 75, 124 }, - { 27, 67, 108 }, - { 10, 54, 86 }, - { 1, 33, 52 }, - { 1, 12, 18 } }, - { // Band 2 - { 43, 125, 151 }, - { 26, 108, 148 }, - { 7, 83, 122 }, - { 2, 59, 89 }, - { 1, 38, 60 }, - { 1, 17, 27 } }, - { // Band 3 - { 23, 144, 163 }, - { 13, 112, 154 }, - { 2, 75, 117 }, - { 1, 50, 81 }, - { 1, 31, 51 }, - { 1, 14, 23 } }, - { // Band 4 - { 18, 162, 185 }, - { 6, 123, 171 }, - { 1, 78, 125 }, - { 1, 51, 86 }, - { 1, 31, 54 }, - { 1, 14, 23 } }, - { // Band 5 - { 15, 199, 227 }, - { 3, 150, 204 }, - { 1, 91, 146 }, - { 1, 55, 95 }, - { 1, 30, 53 }, - { 1, 11, 20 } } }, - { // Inter - { // Band 0 - { 19, 55, 240 }, - { 19, 59, 196 }, - { 3, 52, 105 } }, - { // Band 1 - { 41, 166, 207 }, - { 104, 153, 199 }, - { 31, 123, 181 }, - { 14, 101, 152 }, - { 5, 72, 106 }, - { 1, 36, 52 } }, - { // Band 2 - { 35, 176, 211 }, - { 12, 131, 190 }, - { 2, 88, 144 }, - { 1, 60, 101 }, - { 1, 36, 60 }, - { 1, 16, 28 } }, - { // Band 3 - { 28, 183, 213 }, - { 8, 134, 191 }, - { 1, 86, 142 }, - { 1, 56, 96 }, - { 1, 30, 53 }, - { 1, 12, 20 } }, - { // Band 4 - { 20, 190, 215 }, - { 4, 135, 192 }, - { 1, 84, 139 }, - { 1, 53, 91 }, - { 1, 28, 49 }, - { 1, 11, 20 } }, - { // Band 5 - { 13, 196, 216 }, - { 2, 137, 192 }, - { 1, 86, 143 }, - { 1, 57, 99 }, - { 1, 32, 56 }, - { 1, 13, 24 } } } }, - { // UV plane - { // Intra - { // Band 0 - { 211, 29, 217 }, - { 96, 47, 156 }, - { 22, 43, 87 } }, - { // Band 1 - { 78, 120, 193 }, - { 111, 116, 186 }, - { 46, 102, 164 }, - { 15, 80, 128 }, - { 2, 49, 76 }, - { 1, 18, 28 } }, - { // Band 2 - { 71, 161, 203 }, - { 42, 132, 192 }, - { 10, 98, 150 }, - { 3, 69, 109 }, - { 1, 44, 70 }, - { 1, 18, 29 } }, - { // Band 3 - { 57, 186, 211 }, - { 30, 140, 196 }, - { 4, 93, 146 }, - { 1, 62, 102 }, - { 1, 38, 65 }, - { 1, 16, 27 } }, - { // Band 4 - { 47, 199, 217 }, - { 14, 145, 196 }, - { 1, 88, 142 }, - { 1, 57, 98 }, - { 1, 36, 62 }, - { 1, 15, 26 } }, - { // Band 5 - { 26, 219, 229 }, - { 5, 155, 207 }, - { 1, 94, 151 }, - { 1, 60, 104 }, - { 1, 36, 62 }, - { 1, 16, 28 } } }, - { // Inter - { // Band 0 - { 233, 29, 248 }, - { 146, 47, 220 }, - { 43, 52, 140 } }, - { // Band 1 - { 100, 163, 232 }, - { 179, 161, 222 }, - { 63, 142, 204 }, - { 37, 113, 174 }, - { 26, 89, 137 }, - { 18, 68, 97 } }, - { // Band 2 - { 85, 181, 230 }, - { 32, 146, 209 }, - { 7, 100, 164 }, - { 3, 71, 121 }, - { 1, 45, 77 }, - { 1, 18, 30 } }, - { // Band 3 - { 65, 187, 230 }, - { 20, 148, 207 }, - { 2, 97, 159 }, - { 1, 68, 116 }, - { 1, 40, 70 }, - { 1, 14, 29 } }, - { // Band 4 - { 40, 194, 227 }, - { 8, 147, 204 }, - { 1, 94, 155 }, - { 1, 65, 112 }, - { 1, 39, 66 }, - { 1, 14, 26 } }, - { // Band 5 - { 16, 208, 228 }, - { 3, 151, 207 }, - { 1, 98, 160 }, - { 1, 67, 117 }, - { 1, 41, 74 }, - { 1, 17, 31 } } } } -}; - -static const vp9_coeff_probs_model default_coef_probs_32x32[PLANE_TYPES] = { - { // Y plane - { // Intra - { // Band 0 - { 17, 38, 140 }, - { 7, 34, 80 }, - { 1, 17, 29 } }, - { // Band 1 - { 37, 75, 128 }, - { 41, 76, 128 }, - { 26, 66, 116 }, - { 12, 52, 94 }, - { 2, 32, 55 }, - { 1, 10, 16 } }, - { // Band 2 - { 50, 127, 154 }, - { 37, 109, 152 }, - { 16, 82, 121 }, - { 5, 59, 85 }, - { 1, 35, 54 }, - { 1, 13, 20 } }, - { // Band 3 - { 40, 142, 167 }, - { 17, 110, 157 }, - { 2, 71, 112 }, - { 1, 44, 72 }, - { 1, 27, 45 }, - { 1, 11, 17 } }, - { // Band 4 - { 30, 175, 188 }, - { 9, 124, 169 }, - { 1, 74, 116 }, - { 1, 48, 78 }, - { 1, 30, 49 }, - { 1, 11, 18 } }, - { // Band 5 - { 10, 222, 223 }, - { 2, 150, 194 }, - { 1, 83, 128 }, - { 1, 48, 79 }, - { 1, 27, 45 }, - { 1, 11, 17 } } }, - { // Inter - { // Band 0 - { 36, 41, 235 }, - { 29, 36, 193 }, - { 10, 27, 111 } }, - { // Band 1 - { 85, 165, 222 }, - { 177, 162, 215 }, - { 110, 135, 195 }, - { 57, 113, 168 }, - { 23, 83, 120 }, - { 10, 49, 61 } }, - { // Band 2 - { 85, 190, 223 }, - { 36, 139, 200 }, - { 5, 90, 146 }, - { 1, 60, 103 }, - { 1, 38, 65 }, - { 1, 18, 30 } }, - { // Band 3 - { 72, 202, 223 }, - { 23, 141, 199 }, - { 2, 86, 140 }, - { 1, 56, 97 }, - { 1, 36, 61 }, - { 1, 16, 27 } }, - { // Band 4 - { 55, 218, 225 }, - { 13, 145, 200 }, - { 1, 86, 141 }, - { 1, 57, 99 }, - { 1, 35, 61 }, - { 1, 13, 22 } }, - { // Band 5 - { 15, 235, 212 }, - { 1, 132, 184 }, - { 1, 84, 139 }, - { 1, 57, 97 }, - { 1, 34, 56 }, - { 1, 14, 23 } } } }, - { // UV plane - { // Intra - { // Band 0 - { 181, 21, 201 }, - { 61, 37, 123 }, - { 10, 38, 71 } }, - { // Band 1 - { 47, 106, 172 }, - { 95, 104, 173 }, - { 42, 93, 159 }, - { 18, 77, 131 }, - { 4, 50, 81 }, - { 1, 17, 23 } }, - { // Band 2 - { 62, 147, 199 }, - { 44, 130, 189 }, - { 28, 102, 154 }, - { 18, 75, 115 }, - { 2, 44, 65 }, - { 1, 12, 19 } }, - { // Band 3 - { 55, 153, 210 }, - { 24, 130, 194 }, - { 3, 93, 146 }, - { 1, 61, 97 }, - { 1, 31, 50 }, - { 1, 10, 16 } }, - { // Band 4 - { 49, 186, 223 }, - { 17, 148, 204 }, - { 1, 96, 142 }, - { 1, 53, 83 }, - { 1, 26, 44 }, - { 1, 11, 17 } }, - { // Band 5 - { 13, 217, 212 }, - { 2, 136, 180 }, - { 1, 78, 124 }, - { 1, 50, 83 }, - { 1, 29, 49 }, - { 1, 14, 23 } } }, - { // Inter - { // Band 0 - { 197, 13, 247 }, - { 82, 17, 222 }, - { 25, 17, 162 } }, - { // Band 1 - { 126, 186, 247 }, - { 234, 191, 243 }, - { 176, 177, 234 }, - { 104, 158, 220 }, - { 66, 128, 186 }, - { 55, 90, 137 } }, - { // Band 2 - { 111, 197, 242 }, - { 46, 158, 219 }, - { 9, 104, 171 }, - { 2, 65, 125 }, - { 1, 44, 80 }, - { 1, 17, 91 } }, - { // Band 3 - { 104, 208, 245 }, - { 39, 168, 224 }, - { 3, 109, 162 }, - { 1, 79, 124 }, - { 1, 50, 102 }, - { 1, 43, 102 } }, - { // Band 4 - { 84, 220, 246 }, - { 31, 177, 231 }, - { 2, 115, 180 }, - { 1, 79, 134 }, - { 1, 55, 77 }, - { 1, 60, 79 } }, - { // Band 5 - { 43, 243, 240 }, - { 8, 180, 217 }, - { 1, 115, 166 }, - { 1, 84, 121 }, - { 1, 51, 67 }, - { 1, 16, 6 } } } } -}; - -static void extend_to_full_distribution(vpx_prob *probs, vpx_prob p) { - assert(p != 0); - memcpy(probs, vp9_pareto8_full[p - 1], MODEL_NODES * sizeof(vpx_prob)); -} - -void vp9_model_to_full_probs(const vpx_prob *model, vpx_prob *full) { - if (full != model) - memcpy(full, model, sizeof(vpx_prob) * UNCONSTRAINED_NODES); - extend_to_full_distribution(&full[UNCONSTRAINED_NODES], model[PIVOT_NODE]); -} - -void vp9_default_coef_probs(VP9_COMMON *cm) { - vp9_copy(cm->fc->coef_probs[TX_4X4], default_coef_probs_4x4); - vp9_copy(cm->fc->coef_probs[TX_8X8], default_coef_probs_8x8); - vp9_copy(cm->fc->coef_probs[TX_16X16], default_coef_probs_16x16); - vp9_copy(cm->fc->coef_probs[TX_32X32], default_coef_probs_32x32); -} - -#define COEF_COUNT_SAT 24 -#define COEF_MAX_UPDATE_FACTOR 112 -#define COEF_COUNT_SAT_KEY 24 -#define COEF_MAX_UPDATE_FACTOR_KEY 112 -#define COEF_COUNT_SAT_AFTER_KEY 24 -#define COEF_MAX_UPDATE_FACTOR_AFTER_KEY 128 - -static void adapt_coef_probs(VP9_COMMON *cm, TX_SIZE tx_size, - unsigned int count_sat, - unsigned int update_factor) { - const FRAME_CONTEXT *pre_fc = &cm->frame_contexts[cm->frame_context_idx]; - vp9_coeff_probs_model *const probs = cm->fc->coef_probs[tx_size]; - const vp9_coeff_probs_model *const pre_probs = pre_fc->coef_probs[tx_size]; - vp9_coeff_count_model *counts = cm->counts.coef[tx_size]; - unsigned int(*eob_counts)[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS] = - cm->counts.eob_branch[tx_size]; - int i, j, k, l, m; - - for (i = 0; i < PLANE_TYPES; ++i) - for (j = 0; j < REF_TYPES; ++j) - for (k = 0; k < COEF_BANDS; ++k) - for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { - const int n0 = counts[i][j][k][l][ZERO_TOKEN]; - const int n1 = counts[i][j][k][l][ONE_TOKEN]; - const int n2 = counts[i][j][k][l][TWO_TOKEN]; - const int neob = counts[i][j][k][l][EOB_MODEL_TOKEN]; - const unsigned int branch_ct[UNCONSTRAINED_NODES][2] = { - { neob, eob_counts[i][j][k][l] - neob }, { n0, n1 + n2 }, { n1, n2 } - }; - for (m = 0; m < UNCONSTRAINED_NODES; ++m) - probs[i][j][k][l][m] = - merge_probs(pre_probs[i][j][k][l][m], branch_ct[m], count_sat, - update_factor); - } -} - -void vp9_adapt_coef_probs(VP9_COMMON *cm) { - TX_SIZE t; - unsigned int count_sat, update_factor; - - if (frame_is_intra_only(cm)) { - update_factor = COEF_MAX_UPDATE_FACTOR_KEY; - count_sat = COEF_COUNT_SAT_KEY; - } else if (cm->last_frame_type == KEY_FRAME) { - update_factor = COEF_MAX_UPDATE_FACTOR_AFTER_KEY; /* adapt quickly */ - count_sat = COEF_COUNT_SAT_AFTER_KEY; - } else { - update_factor = COEF_MAX_UPDATE_FACTOR; - count_sat = COEF_COUNT_SAT; - } - for (t = TX_4X4; t <= TX_32X32; t++) - adapt_coef_probs(cm, t, count_sat, update_factor); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropy.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropy.h deleted file mode 100644 index d026651d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropy.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_ENTROPY_H_ -#define VPX_VP9_COMMON_VP9_ENTROPY_H_ - -#include "vpx/vpx_integer.h" -#include "vpx_dsp/prob.h" - -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_enums.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DIFF_UPDATE_PROB 252 - -// Coefficient token alphabet -#define ZERO_TOKEN 0 // 0 Extra Bits 0+0 -#define ONE_TOKEN 1 // 1 Extra Bits 0+1 -#define TWO_TOKEN 2 // 2 Extra Bits 0+1 -#define THREE_TOKEN 3 // 3 Extra Bits 0+1 -#define FOUR_TOKEN 4 // 4 Extra Bits 0+1 -#define CATEGORY1_TOKEN 5 // 5-6 Extra Bits 1+1 -#define CATEGORY2_TOKEN 6 // 7-10 Extra Bits 2+1 -#define CATEGORY3_TOKEN 7 // 11-18 Extra Bits 3+1 -#define CATEGORY4_TOKEN 8 // 19-34 Extra Bits 4+1 -#define CATEGORY5_TOKEN 9 // 35-66 Extra Bits 5+1 -#define CATEGORY6_TOKEN 10 // 67+ Extra Bits 14+1 -#define EOB_TOKEN 11 // EOB Extra Bits 0+0 - -#define ENTROPY_TOKENS 12 - -#define ENTROPY_NODES 11 - -DECLARE_ALIGNED(16, extern const uint8_t, vp9_pt_energy_class[ENTROPY_TOKENS]); - -#define CAT1_MIN_VAL 5 -#define CAT2_MIN_VAL 7 -#define CAT3_MIN_VAL 11 -#define CAT4_MIN_VAL 19 -#define CAT5_MIN_VAL 35 -#define CAT6_MIN_VAL 67 - -// Extra bit probabilities. -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat1_prob[1]); -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat2_prob[2]); -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat3_prob[3]); -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat4_prob[4]); -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat5_prob[5]); -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat6_prob[14]); - -#if CONFIG_VP9_HIGHBITDEPTH -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat1_prob_high10[1]); -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat2_prob_high10[2]); -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat3_prob_high10[3]); -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat4_prob_high10[4]); -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat5_prob_high10[5]); -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat6_prob_high10[16]); -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat1_prob_high12[1]); -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat2_prob_high12[2]); -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat3_prob_high12[3]); -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat4_prob_high12[4]); -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat5_prob_high12[5]); -DECLARE_ALIGNED(16, extern const uint8_t, vp9_cat6_prob_high12[18]); -#endif // CONFIG_VP9_HIGHBITDEPTH - -#define EOB_MODEL_TOKEN 3 - -#define DCT_MAX_VALUE 16384 -#if CONFIG_VP9_HIGHBITDEPTH -#define DCT_MAX_VALUE_HIGH10 65536 -#define DCT_MAX_VALUE_HIGH12 262144 -#endif // CONFIG_VP9_HIGHBITDEPTH - -/* Coefficients are predicted via a 3-dimensional probability table. */ - -#define REF_TYPES 2 // intra=0, inter=1 - -/* Middle dimension reflects the coefficient position within the transform. */ -#define COEF_BANDS 6 - -/* Inside dimension is measure of nearby complexity, that reflects the energy - of nearby coefficients are nonzero. For the first coefficient (DC, unless - block type is 0), we look at the (already encoded) blocks above and to the - left of the current block. The context index is then the number (0,1,or 2) - of these blocks having nonzero coefficients. - After decoding a coefficient, the measure is determined by the size of the - most recently decoded coefficient. - Note that the intuitive meaning of this measure changes as coefficients - are decoded, e.g., prior to the first token, a zero means that my neighbors - are empty while, after the first token, because of the use of end-of-block, - a zero means we just decoded a zero and hence guarantees that a non-zero - coefficient will appear later in this block. However, this shift - in meaning is perfectly OK because our context depends also on the - coefficient band (and since zigzag positions 0, 1, and 2 are in - distinct bands). */ - -#define COEFF_CONTEXTS 6 -#define BAND_COEFF_CONTEXTS(band) ((band) == 0 ? 3 : COEFF_CONTEXTS) - -// #define ENTROPY_STATS - -typedef unsigned int vp9_coeff_count[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS] - [ENTROPY_TOKENS]; -typedef unsigned int vp9_coeff_stats[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS] - [ENTROPY_NODES][2]; - -#define SUBEXP_PARAM 4 /* Subexponential code parameter */ -#define MODULUS_PARAM 13 /* Modulus parameter */ - -struct VP9Common; -void vp9_default_coef_probs(struct VP9Common *cm); -void vp9_adapt_coef_probs(struct VP9Common *cm); - -// This is the index in the scan order beyond which all coefficients for -// 8x8 transform and above are in the top band. -// This macro is currently unused but may be used by certain implementations -#define MAXBAND_INDEX 21 - -DECLARE_ALIGNED(16, extern const uint8_t, vp9_coefband_trans_8x8plus[1024]); -DECLARE_ALIGNED(16, extern const uint8_t, vp9_coefband_trans_4x4[16]); - -static INLINE const uint8_t *get_band_translate(TX_SIZE tx_size) { - return tx_size == TX_4X4 ? vp9_coefband_trans_4x4 - : vp9_coefband_trans_8x8plus; -} - -// 128 lists of probabilities are stored for the following ONE node probs: -// 1, 3, 5, 7, ..., 253, 255 -// In between probabilities are interpolated linearly -#define COEFF_PROB_MODELS 255 - -#define UNCONSTRAINED_NODES 3 - -#define PIVOT_NODE 2 // which node is pivot - -#define MODEL_NODES (ENTROPY_NODES - UNCONSTRAINED_NODES) -extern const vpx_tree_index vp9_coef_con_tree[TREE_SIZE(ENTROPY_TOKENS)]; -extern const vpx_prob vp9_pareto8_full[COEFF_PROB_MODELS][MODEL_NODES]; - -typedef vpx_prob vp9_coeff_probs_model[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS] - [UNCONSTRAINED_NODES]; - -typedef unsigned int vp9_coeff_count_model[REF_TYPES][COEF_BANDS] - [COEFF_CONTEXTS] - [UNCONSTRAINED_NODES + 1]; - -void vp9_model_to_full_probs(const vpx_prob *model, vpx_prob *full); - -typedef char ENTROPY_CONTEXT; - -static INLINE int combine_entropy_contexts(ENTROPY_CONTEXT a, - ENTROPY_CONTEXT b) { - return (a != 0) + (b != 0); -} - -static INLINE int get_entropy_context(TX_SIZE tx_size, const ENTROPY_CONTEXT *a, - const ENTROPY_CONTEXT *l) { - ENTROPY_CONTEXT above_ec = 0, left_ec = 0; - - switch (tx_size) { - case TX_4X4: - above_ec = a[0] != 0; - left_ec = l[0] != 0; - break; - case TX_8X8: - above_ec = !!*(const uint16_t *)a; - left_ec = !!*(const uint16_t *)l; - break; - case TX_16X16: - above_ec = !!*(const uint32_t *)a; - left_ec = !!*(const uint32_t *)l; - break; - case TX_32X32: - above_ec = !!*(const uint64_t *)a; - left_ec = !!*(const uint64_t *)l; - break; - default: assert(0 && "Invalid transform size."); break; - } - - return combine_entropy_contexts(above_ec, left_ec); -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_ENTROPY_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropymode.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropymode.c deleted file mode 100644 index 9289fc9e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropymode.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_mem/vpx_mem.h" - -#include "vp9/common/vp9_onyxc_int.h" -#include "vp9/common/vp9_seg_common.h" - -const vpx_prob vp9_kf_y_mode_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1] = { - { - // above = dc - { 137, 30, 42, 148, 151, 207, 70, 52, 91 }, // left = dc - { 92, 45, 102, 136, 116, 180, 74, 90, 100 }, // left = v - { 73, 32, 19, 187, 222, 215, 46, 34, 100 }, // left = h - { 91, 30, 32, 116, 121, 186, 93, 86, 94 }, // left = d45 - { 72, 35, 36, 149, 68, 206, 68, 63, 105 }, // left = d135 - { 73, 31, 28, 138, 57, 124, 55, 122, 151 }, // left = d117 - { 67, 23, 21, 140, 126, 197, 40, 37, 171 }, // left = d153 - { 86, 27, 28, 128, 154, 212, 45, 43, 53 }, // left = d207 - { 74, 32, 27, 107, 86, 160, 63, 134, 102 }, // left = d63 - { 59, 67, 44, 140, 161, 202, 78, 67, 119 } // left = tm - }, - { - // above = v - { 63, 36, 126, 146, 123, 158, 60, 90, 96 }, // left = dc - { 43, 46, 168, 134, 107, 128, 69, 142, 92 }, // left = v - { 44, 29, 68, 159, 201, 177, 50, 57, 77 }, // left = h - { 58, 38, 76, 114, 97, 172, 78, 133, 92 }, // left = d45 - { 46, 41, 76, 140, 63, 184, 69, 112, 57 }, // left = d135 - { 38, 32, 85, 140, 46, 112, 54, 151, 133 }, // left = d117 - { 39, 27, 61, 131, 110, 175, 44, 75, 136 }, // left = d153 - { 52, 30, 74, 113, 130, 175, 51, 64, 58 }, // left = d207 - { 47, 35, 80, 100, 74, 143, 64, 163, 74 }, // left = d63 - { 36, 61, 116, 114, 128, 162, 80, 125, 82 } // left = tm - }, - { - // above = h - { 82, 26, 26, 171, 208, 204, 44, 32, 105 }, // left = dc - { 55, 44, 68, 166, 179, 192, 57, 57, 108 }, // left = v - { 42, 26, 11, 199, 241, 228, 23, 15, 85 }, // left = h - { 68, 42, 19, 131, 160, 199, 55, 52, 83 }, // left = d45 - { 58, 50, 25, 139, 115, 232, 39, 52, 118 }, // left = d135 - { 50, 35, 33, 153, 104, 162, 64, 59, 131 }, // left = d117 - { 44, 24, 16, 150, 177, 202, 33, 19, 156 }, // left = d153 - { 55, 27, 12, 153, 203, 218, 26, 27, 49 }, // left = d207 - { 53, 49, 21, 110, 116, 168, 59, 80, 76 }, // left = d63 - { 38, 72, 19, 168, 203, 212, 50, 50, 107 } // left = tm - }, - { - // above = d45 - { 103, 26, 36, 129, 132, 201, 83, 80, 93 }, // left = dc - { 59, 38, 83, 112, 103, 162, 98, 136, 90 }, // left = v - { 62, 30, 23, 158, 200, 207, 59, 57, 50 }, // left = h - { 67, 30, 29, 84, 86, 191, 102, 91, 59 }, // left = d45 - { 60, 32, 33, 112, 71, 220, 64, 89, 104 }, // left = d135 - { 53, 26, 34, 130, 56, 149, 84, 120, 103 }, // left = d117 - { 53, 21, 23, 133, 109, 210, 56, 77, 172 }, // left = d153 - { 77, 19, 29, 112, 142, 228, 55, 66, 36 }, // left = d207 - { 61, 29, 29, 93, 97, 165, 83, 175, 162 }, // left = d63 - { 47, 47, 43, 114, 137, 181, 100, 99, 95 } // left = tm - }, - { - // above = d135 - { 69, 23, 29, 128, 83, 199, 46, 44, 101 }, // left = dc - { 53, 40, 55, 139, 69, 183, 61, 80, 110 }, // left = v - { 40, 29, 19, 161, 180, 207, 43, 24, 91 }, // left = h - { 60, 34, 19, 105, 61, 198, 53, 64, 89 }, // left = d45 - { 52, 31, 22, 158, 40, 209, 58, 62, 89 }, // left = d135 - { 44, 31, 29, 147, 46, 158, 56, 102, 198 }, // left = d117 - { 35, 19, 12, 135, 87, 209, 41, 45, 167 }, // left = d153 - { 55, 25, 21, 118, 95, 215, 38, 39, 66 }, // left = d207 - { 51, 38, 25, 113, 58, 164, 70, 93, 97 }, // left = d63 - { 47, 54, 34, 146, 108, 203, 72, 103, 151 } // left = tm - }, - { - // above = d117 - { 64, 19, 37, 156, 66, 138, 49, 95, 133 }, // left = dc - { 46, 27, 80, 150, 55, 124, 55, 121, 135 }, // left = v - { 36, 23, 27, 165, 149, 166, 54, 64, 118 }, // left = h - { 53, 21, 36, 131, 63, 163, 60, 109, 81 }, // left = d45 - { 40, 26, 35, 154, 40, 185, 51, 97, 123 }, // left = d135 - { 35, 19, 34, 179, 19, 97, 48, 129, 124 }, // left = d117 - { 36, 20, 26, 136, 62, 164, 33, 77, 154 }, // left = d153 - { 45, 18, 32, 130, 90, 157, 40, 79, 91 }, // left = d207 - { 45, 26, 28, 129, 45, 129, 49, 147, 123 }, // left = d63 - { 38, 44, 51, 136, 74, 162, 57, 97, 121 } // left = tm - }, - { - // above = d153 - { 75, 17, 22, 136, 138, 185, 32, 34, 166 }, // left = dc - { 56, 39, 58, 133, 117, 173, 48, 53, 187 }, // left = v - { 35, 21, 12, 161, 212, 207, 20, 23, 145 }, // left = h - { 56, 29, 19, 117, 109, 181, 55, 68, 112 }, // left = d45 - { 47, 29, 17, 153, 64, 220, 59, 51, 114 }, // left = d135 - { 46, 16, 24, 136, 76, 147, 41, 64, 172 }, // left = d117 - { 34, 17, 11, 108, 152, 187, 13, 15, 209 }, // left = d153 - { 51, 24, 14, 115, 133, 209, 32, 26, 104 }, // left = d207 - { 55, 30, 18, 122, 79, 179, 44, 88, 116 }, // left = d63 - { 37, 49, 25, 129, 168, 164, 41, 54, 148 } // left = tm - }, - { - // above = d207 - { 82, 22, 32, 127, 143, 213, 39, 41, 70 }, // left = dc - { 62, 44, 61, 123, 105, 189, 48, 57, 64 }, // left = v - { 47, 25, 17, 175, 222, 220, 24, 30, 86 }, // left = h - { 68, 36, 17, 106, 102, 206, 59, 74, 74 }, // left = d45 - { 57, 39, 23, 151, 68, 216, 55, 63, 58 }, // left = d135 - { 49, 30, 35, 141, 70, 168, 82, 40, 115 }, // left = d117 - { 51, 25, 15, 136, 129, 202, 38, 35, 139 }, // left = d153 - { 68, 26, 16, 111, 141, 215, 29, 28, 28 }, // left = d207 - { 59, 39, 19, 114, 75, 180, 77, 104, 42 }, // left = d63 - { 40, 61, 26, 126, 152, 206, 61, 59, 93 } // left = tm - }, - { - // above = d63 - { 78, 23, 39, 111, 117, 170, 74, 124, 94 }, // left = dc - { 48, 34, 86, 101, 92, 146, 78, 179, 134 }, // left = v - { 47, 22, 24, 138, 187, 178, 68, 69, 59 }, // left = h - { 56, 25, 33, 105, 112, 187, 95, 177, 129 }, // left = d45 - { 48, 31, 27, 114, 63, 183, 82, 116, 56 }, // left = d135 - { 43, 28, 37, 121, 63, 123, 61, 192, 169 }, // left = d117 - { 42, 17, 24, 109, 97, 177, 56, 76, 122 }, // left = d153 - { 58, 18, 28, 105, 139, 182, 70, 92, 63 }, // left = d207 - { 46, 23, 32, 74, 86, 150, 67, 183, 88 }, // left = d63 - { 36, 38, 48, 92, 122, 165, 88, 137, 91 } // left = tm - }, - { - // above = tm - { 65, 70, 60, 155, 159, 199, 61, 60, 81 }, // left = dc - { 44, 78, 115, 132, 119, 173, 71, 112, 93 }, // left = v - { 39, 38, 21, 184, 227, 206, 42, 32, 64 }, // left = h - { 58, 47, 36, 124, 137, 193, 80, 82, 78 }, // left = d45 - { 49, 50, 35, 144, 95, 205, 63, 78, 59 }, // left = d135 - { 41, 53, 52, 148, 71, 142, 65, 128, 51 }, // left = d117 - { 40, 36, 28, 143, 143, 202, 40, 55, 137 }, // left = d153 - { 52, 34, 29, 129, 183, 227, 42, 35, 43 }, // left = d207 - { 42, 44, 44, 104, 105, 164, 64, 130, 80 }, // left = d63 - { 43, 81, 53, 140, 169, 204, 68, 84, 72 } // left = tm - } -}; - -const vpx_prob vp9_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1] = { - { 144, 11, 54, 157, 195, 130, 46, 58, 108 }, // y = dc - { 118, 15, 123, 148, 131, 101, 44, 93, 131 }, // y = v - { 113, 12, 23, 188, 226, 142, 26, 32, 125 }, // y = h - { 120, 11, 50, 123, 163, 135, 64, 77, 103 }, // y = d45 - { 113, 9, 36, 155, 111, 157, 32, 44, 161 }, // y = d135 - { 116, 9, 55, 176, 76, 96, 37, 61, 149 }, // y = d117 - { 115, 9, 28, 141, 161, 167, 21, 25, 193 }, // y = d153 - { 120, 12, 32, 145, 195, 142, 32, 38, 86 }, // y = d207 - { 116, 12, 64, 120, 140, 125, 49, 115, 121 }, // y = d63 - { 102, 19, 66, 162, 182, 122, 35, 59, 128 } // y = tm -}; - -static const vpx_prob default_if_y_probs[BLOCK_SIZE_GROUPS][INTRA_MODES - 1] = { - { 65, 32, 18, 144, 162, 194, 41, 51, 98 }, // block_size < 8x8 - { 132, 68, 18, 165, 217, 196, 45, 40, 78 }, // block_size < 16x16 - { 173, 80, 19, 176, 240, 193, 64, 35, 46 }, // block_size < 32x32 - { 221, 135, 38, 194, 248, 121, 96, 85, 29 } // block_size >= 32x32 -}; - -static const vpx_prob default_if_uv_probs[INTRA_MODES][INTRA_MODES - 1] = { - { 120, 7, 76, 176, 208, 126, 28, 54, 103 }, // y = dc - { 48, 12, 154, 155, 139, 90, 34, 117, 119 }, // y = v - { 67, 6, 25, 204, 243, 158, 13, 21, 96 }, // y = h - { 97, 5, 44, 131, 176, 139, 48, 68, 97 }, // y = d45 - { 83, 5, 42, 156, 111, 152, 26, 49, 152 }, // y = d135 - { 80, 5, 58, 178, 74, 83, 33, 62, 145 }, // y = d117 - { 86, 5, 32, 154, 192, 168, 14, 22, 163 }, // y = d153 - { 85, 5, 32, 156, 216, 148, 19, 29, 73 }, // y = d207 - { 77, 7, 64, 116, 132, 122, 37, 126, 120 }, // y = d63 - { 101, 21, 107, 181, 192, 103, 19, 67, 125 } // y = tm -}; - -const vpx_prob vp9_kf_partition_probs[PARTITION_CONTEXTS] - [PARTITION_TYPES - 1] = { - // 8x8 -> 4x4 - { 158, 97, 94 }, // a/l both not split - { 93, 24, 99 }, // a split, l not split - { 85, 119, 44 }, // l split, a not split - { 62, 59, 67 }, // a/l both split - - // 16x16 -> 8x8 - { 149, 53, 53 }, // a/l both not split - { 94, 20, 48 }, // a split, l not split - { 83, 53, 24 }, // l split, a not split - { 52, 18, 18 }, // a/l both split - - // 32x32 -> 16x16 - { 150, 40, 39 }, // a/l both not split - { 78, 12, 26 }, // a split, l not split - { 67, 33, 11 }, // l split, a not split - { 24, 7, 5 }, // a/l both split - - // 64x64 -> 32x32 - { 174, 35, 49 }, // a/l both not split - { 68, 11, 27 }, // a split, l not split - { 57, 15, 9 }, // l split, a not split - { 12, 3, 3 }, // a/l both split - }; - -static const vpx_prob - default_partition_probs[PARTITION_CONTEXTS][PARTITION_TYPES - 1] = { - // 8x8 -> 4x4 - { 199, 122, 141 }, // a/l both not split - { 147, 63, 159 }, // a split, l not split - { 148, 133, 118 }, // l split, a not split - { 121, 104, 114 }, // a/l both split - // 16x16 -> 8x8 - { 174, 73, 87 }, // a/l both not split - { 92, 41, 83 }, // a split, l not split - { 82, 99, 50 }, // l split, a not split - { 53, 39, 39 }, // a/l both split - // 32x32 -> 16x16 - { 177, 58, 59 }, // a/l both not split - { 68, 26, 63 }, // a split, l not split - { 52, 79, 25 }, // l split, a not split - { 17, 14, 12 }, // a/l both split - // 64x64 -> 32x32 - { 222, 34, 30 }, // a/l both not split - { 72, 16, 44 }, // a split, l not split - { 58, 32, 12 }, // l split, a not split - { 10, 7, 6 }, // a/l both split - }; - -static const vpx_prob - default_inter_mode_probs[INTER_MODE_CONTEXTS][INTER_MODES - 1] = { - { 2, 173, 34 }, // 0 = both zero mv - { 7, 145, 85 }, // 1 = one zero mv + one a predicted mv - { 7, 166, 63 }, // 2 = two predicted mvs - { 7, 94, 66 }, // 3 = one predicted/zero and one new mv - { 8, 64, 46 }, // 4 = two new mvs - { 17, 81, 31 }, // 5 = one intra neighbour + x - { 25, 29, 30 }, // 6 = two intra neighbours - }; - -/* Array indices are identical to previously-existing INTRAMODECONTEXTNODES. */ -const vpx_tree_index vp9_intra_mode_tree[TREE_SIZE(INTRA_MODES)] = { - -DC_PRED, 2, /* 0 = DC_NODE */ - -TM_PRED, 4, /* 1 = TM_NODE */ - -V_PRED, 6, /* 2 = V_NODE */ - 8, 12, /* 3 = COM_NODE */ - -H_PRED, 10, /* 4 = H_NODE */ - -D135_PRED, -D117_PRED, /* 5 = D135_NODE */ - -D45_PRED, 14, /* 6 = D45_NODE */ - -D63_PRED, 16, /* 7 = D63_NODE */ - -D153_PRED, -D207_PRED /* 8 = D153_NODE */ -}; - -const vpx_tree_index vp9_inter_mode_tree[TREE_SIZE(INTER_MODES)] = { - -INTER_OFFSET(ZEROMV), 2, -INTER_OFFSET(NEARESTMV), 4, -INTER_OFFSET(NEARMV), - -INTER_OFFSET(NEWMV) -}; - -const vpx_tree_index vp9_partition_tree[TREE_SIZE(PARTITION_TYPES)] = { - -PARTITION_NONE, 2, -PARTITION_HORZ, 4, -PARTITION_VERT, -PARTITION_SPLIT -}; - -static const vpx_prob default_intra_inter_p[INTRA_INTER_CONTEXTS] = { 9, 102, - 187, - 225 }; - -static const vpx_prob default_comp_inter_p[COMP_INTER_CONTEXTS] = { 239, 183, - 119, 96, - 41 }; - -static const vpx_prob default_comp_ref_p[REF_CONTEXTS] = { 50, 126, 123, 221, - 226 }; - -static const vpx_prob default_single_ref_p[REF_CONTEXTS][2] = { - { 33, 16 }, { 77, 74 }, { 142, 142 }, { 172, 170 }, { 238, 247 } -}; - -static const struct tx_probs default_tx_probs = { { { 3, 136, 37 }, - { 5, 52, 13 } }, - - { { 20, 152 }, { 15, 101 } }, - - { { 100 }, { 66 } } }; - -void tx_counts_to_branch_counts_32x32(const unsigned int *tx_count_32x32p, - unsigned int (*ct_32x32p)[2]) { - ct_32x32p[0][0] = tx_count_32x32p[TX_4X4]; - ct_32x32p[0][1] = tx_count_32x32p[TX_8X8] + tx_count_32x32p[TX_16X16] + - tx_count_32x32p[TX_32X32]; - ct_32x32p[1][0] = tx_count_32x32p[TX_8X8]; - ct_32x32p[1][1] = tx_count_32x32p[TX_16X16] + tx_count_32x32p[TX_32X32]; - ct_32x32p[2][0] = tx_count_32x32p[TX_16X16]; - ct_32x32p[2][1] = tx_count_32x32p[TX_32X32]; -} - -void tx_counts_to_branch_counts_16x16(const unsigned int *tx_count_16x16p, - unsigned int (*ct_16x16p)[2]) { - ct_16x16p[0][0] = tx_count_16x16p[TX_4X4]; - ct_16x16p[0][1] = tx_count_16x16p[TX_8X8] + tx_count_16x16p[TX_16X16]; - ct_16x16p[1][0] = tx_count_16x16p[TX_8X8]; - ct_16x16p[1][1] = tx_count_16x16p[TX_16X16]; -} - -void tx_counts_to_branch_counts_8x8(const unsigned int *tx_count_8x8p, - unsigned int (*ct_8x8p)[2]) { - ct_8x8p[0][0] = tx_count_8x8p[TX_4X4]; - ct_8x8p[0][1] = tx_count_8x8p[TX_8X8]; -} - -static const vpx_prob default_skip_probs[SKIP_CONTEXTS] = { 192, 128, 64 }; - -static const vpx_prob default_switchable_interp_prob[SWITCHABLE_FILTER_CONTEXTS] - [SWITCHABLE_FILTERS - 1] = { - { 235, 162 }, - { 36, 255 }, - { 34, 3 }, - { 149, 144 }, - }; - -static void init_mode_probs(FRAME_CONTEXT *fc) { - vp9_copy(fc->uv_mode_prob, default_if_uv_probs); - vp9_copy(fc->y_mode_prob, default_if_y_probs); - vp9_copy(fc->switchable_interp_prob, default_switchable_interp_prob); - vp9_copy(fc->partition_prob, default_partition_probs); - vp9_copy(fc->intra_inter_prob, default_intra_inter_p); - vp9_copy(fc->comp_inter_prob, default_comp_inter_p); - vp9_copy(fc->comp_ref_prob, default_comp_ref_p); - vp9_copy(fc->single_ref_prob, default_single_ref_p); - fc->tx_probs = default_tx_probs; - vp9_copy(fc->skip_probs, default_skip_probs); - vp9_copy(fc->inter_mode_probs, default_inter_mode_probs); -} - -const vpx_tree_index vp9_switchable_interp_tree[TREE_SIZE( - SWITCHABLE_FILTERS)] = { -EIGHTTAP, 2, -EIGHTTAP_SMOOTH, -EIGHTTAP_SHARP }; - -void vp9_adapt_mode_probs(VP9_COMMON *cm) { - int i, j; - FRAME_CONTEXT *fc = cm->fc; - const FRAME_CONTEXT *pre_fc = &cm->frame_contexts[cm->frame_context_idx]; - const FRAME_COUNTS *counts = &cm->counts; - - for (i = 0; i < INTRA_INTER_CONTEXTS; i++) - fc->intra_inter_prob[i] = mode_mv_merge_probs(pre_fc->intra_inter_prob[i], - counts->intra_inter[i]); - for (i = 0; i < COMP_INTER_CONTEXTS; i++) - fc->comp_inter_prob[i] = - mode_mv_merge_probs(pre_fc->comp_inter_prob[i], counts->comp_inter[i]); - for (i = 0; i < REF_CONTEXTS; i++) - fc->comp_ref_prob[i] = - mode_mv_merge_probs(pre_fc->comp_ref_prob[i], counts->comp_ref[i]); - for (i = 0; i < REF_CONTEXTS; i++) - for (j = 0; j < 2; j++) - fc->single_ref_prob[i][j] = mode_mv_merge_probs( - pre_fc->single_ref_prob[i][j], counts->single_ref[i][j]); - - for (i = 0; i < INTER_MODE_CONTEXTS; i++) - vpx_tree_merge_probs(vp9_inter_mode_tree, pre_fc->inter_mode_probs[i], - counts->inter_mode[i], fc->inter_mode_probs[i]); - - for (i = 0; i < BLOCK_SIZE_GROUPS; i++) - vpx_tree_merge_probs(vp9_intra_mode_tree, pre_fc->y_mode_prob[i], - counts->y_mode[i], fc->y_mode_prob[i]); - - for (i = 0; i < INTRA_MODES; ++i) - vpx_tree_merge_probs(vp9_intra_mode_tree, pre_fc->uv_mode_prob[i], - counts->uv_mode[i], fc->uv_mode_prob[i]); - - for (i = 0; i < PARTITION_CONTEXTS; i++) - vpx_tree_merge_probs(vp9_partition_tree, pre_fc->partition_prob[i], - counts->partition[i], fc->partition_prob[i]); - - if (cm->interp_filter == SWITCHABLE) { - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) - vpx_tree_merge_probs( - vp9_switchable_interp_tree, pre_fc->switchable_interp_prob[i], - counts->switchable_interp[i], fc->switchable_interp_prob[i]); - } - - if (cm->tx_mode == TX_MODE_SELECT) { - unsigned int branch_ct_8x8p[TX_SIZES - 3][2]; - unsigned int branch_ct_16x16p[TX_SIZES - 2][2]; - unsigned int branch_ct_32x32p[TX_SIZES - 1][2]; - - for (i = 0; i < TX_SIZE_CONTEXTS; ++i) { - tx_counts_to_branch_counts_8x8(counts->tx.p8x8[i], branch_ct_8x8p); - for (j = 0; j < TX_SIZES - 3; ++j) - fc->tx_probs.p8x8[i][j] = - mode_mv_merge_probs(pre_fc->tx_probs.p8x8[i][j], branch_ct_8x8p[j]); - - tx_counts_to_branch_counts_16x16(counts->tx.p16x16[i], branch_ct_16x16p); - for (j = 0; j < TX_SIZES - 2; ++j) - fc->tx_probs.p16x16[i][j] = mode_mv_merge_probs( - pre_fc->tx_probs.p16x16[i][j], branch_ct_16x16p[j]); - - tx_counts_to_branch_counts_32x32(counts->tx.p32x32[i], branch_ct_32x32p); - for (j = 0; j < TX_SIZES - 1; ++j) - fc->tx_probs.p32x32[i][j] = mode_mv_merge_probs( - pre_fc->tx_probs.p32x32[i][j], branch_ct_32x32p[j]); - } - } - - for (i = 0; i < SKIP_CONTEXTS; ++i) - fc->skip_probs[i] = - mode_mv_merge_probs(pre_fc->skip_probs[i], counts->skip[i]); -} - -static void set_default_lf_deltas(struct loopfilter *lf) { - lf->mode_ref_delta_enabled = 1; - lf->mode_ref_delta_update = 1; - - lf->ref_deltas[INTRA_FRAME] = 1; - lf->ref_deltas[LAST_FRAME] = 0; - lf->ref_deltas[GOLDEN_FRAME] = -1; - lf->ref_deltas[ALTREF_FRAME] = -1; - - lf->mode_deltas[0] = 0; - lf->mode_deltas[1] = 0; -} - -void vp9_setup_past_independence(VP9_COMMON *cm) { - // Reset the segment feature data to the default stats: - // Features disabled, 0, with delta coding (Default state). - struct loopfilter *const lf = &cm->lf; - - int i; - vp9_clearall_segfeatures(&cm->seg); - cm->seg.abs_delta = SEGMENT_DELTADATA; - - if (cm->last_frame_seg_map) - memset(cm->last_frame_seg_map, 0, (cm->mi_rows * cm->mi_cols)); - - if (cm->current_frame_seg_map) - memset(cm->current_frame_seg_map, 0, (cm->mi_rows * cm->mi_cols)); - - // Reset the mode ref deltas for loop filter - vp9_zero(lf->last_ref_deltas); - vp9_zero(lf->last_mode_deltas); - set_default_lf_deltas(lf); - - // To force update of the sharpness - lf->last_sharpness_level = -1; - - vp9_default_coef_probs(cm); - init_mode_probs(cm->fc); - vp9_init_mv_probs(cm); - cm->fc->initialized = 1; - - if (cm->frame_type == KEY_FRAME || cm->error_resilient_mode || - cm->reset_frame_context == 3) { - // Reset all frame contexts. - for (i = 0; i < FRAME_CONTEXTS; ++i) cm->frame_contexts[i] = *cm->fc; - } else if (cm->reset_frame_context == 2) { - // Reset only the frame context specified in the frame header. - cm->frame_contexts[cm->frame_context_idx] = *cm->fc; - } - - // prev_mip will only be allocated in encoder. - if (frame_is_intra_only(cm) && cm->prev_mip) - memset(cm->prev_mip, 0, - cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->prev_mip)); - - vp9_zero(cm->ref_frame_sign_bias); - - cm->frame_context_idx = 0; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropymode.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropymode.h deleted file mode 100644 index a756c8d0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropymode.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_ENTROPYMODE_H_ -#define VPX_VP9_COMMON_VP9_ENTROPYMODE_H_ - -#include "vp9/common/vp9_entropy.h" -#include "vp9/common/vp9_entropymv.h" -#include "vp9/common/vp9_filter.h" -#include "vpx_dsp/vpx_filter.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define BLOCK_SIZE_GROUPS 4 - -#define TX_SIZE_CONTEXTS 2 - -#define INTER_OFFSET(mode) ((mode)-NEARESTMV) - -struct VP9Common; - -struct tx_probs { - vpx_prob p32x32[TX_SIZE_CONTEXTS][TX_SIZES - 1]; - vpx_prob p16x16[TX_SIZE_CONTEXTS][TX_SIZES - 2]; - vpx_prob p8x8[TX_SIZE_CONTEXTS][TX_SIZES - 3]; -}; - -struct tx_counts { - unsigned int p32x32[TX_SIZE_CONTEXTS][TX_SIZES]; - unsigned int p16x16[TX_SIZE_CONTEXTS][TX_SIZES - 1]; - unsigned int p8x8[TX_SIZE_CONTEXTS][TX_SIZES - 2]; - unsigned int tx_totals[TX_SIZES]; -}; - -typedef struct frame_contexts { - vpx_prob y_mode_prob[BLOCK_SIZE_GROUPS][INTRA_MODES - 1]; - vpx_prob uv_mode_prob[INTRA_MODES][INTRA_MODES - 1]; - vpx_prob partition_prob[PARTITION_CONTEXTS][PARTITION_TYPES - 1]; - vp9_coeff_probs_model coef_probs[TX_SIZES][PLANE_TYPES]; - vpx_prob switchable_interp_prob[SWITCHABLE_FILTER_CONTEXTS] - [SWITCHABLE_FILTERS - 1]; - vpx_prob inter_mode_probs[INTER_MODE_CONTEXTS][INTER_MODES - 1]; - vpx_prob intra_inter_prob[INTRA_INTER_CONTEXTS]; - vpx_prob comp_inter_prob[COMP_INTER_CONTEXTS]; - vpx_prob single_ref_prob[REF_CONTEXTS][2]; - vpx_prob comp_ref_prob[REF_CONTEXTS]; - struct tx_probs tx_probs; - vpx_prob skip_probs[SKIP_CONTEXTS]; - nmv_context nmvc; - int initialized; -} FRAME_CONTEXT; - -typedef struct FRAME_COUNTS { - unsigned int y_mode[BLOCK_SIZE_GROUPS][INTRA_MODES]; - unsigned int uv_mode[INTRA_MODES][INTRA_MODES]; - unsigned int partition[PARTITION_CONTEXTS][PARTITION_TYPES]; - vp9_coeff_count_model coef[TX_SIZES][PLANE_TYPES]; - unsigned int eob_branch[TX_SIZES][PLANE_TYPES][REF_TYPES][COEF_BANDS] - [COEFF_CONTEXTS]; - unsigned int switchable_interp[SWITCHABLE_FILTER_CONTEXTS] - [SWITCHABLE_FILTERS]; - unsigned int inter_mode[INTER_MODE_CONTEXTS][INTER_MODES]; - unsigned int intra_inter[INTRA_INTER_CONTEXTS][2]; - unsigned int comp_inter[COMP_INTER_CONTEXTS][2]; - unsigned int single_ref[REF_CONTEXTS][2][2]; - unsigned int comp_ref[REF_CONTEXTS][2]; - struct tx_counts tx; - unsigned int skip[SKIP_CONTEXTS][2]; - nmv_context_counts mv; -} FRAME_COUNTS; - -extern const vpx_prob vp9_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1]; -extern const vpx_prob vp9_kf_y_mode_prob[INTRA_MODES][INTRA_MODES] - [INTRA_MODES - 1]; -extern const vpx_prob vp9_kf_partition_probs[PARTITION_CONTEXTS] - [PARTITION_TYPES - 1]; -extern const vpx_tree_index vp9_intra_mode_tree[TREE_SIZE(INTRA_MODES)]; -extern const vpx_tree_index vp9_inter_mode_tree[TREE_SIZE(INTER_MODES)]; -extern const vpx_tree_index vp9_partition_tree[TREE_SIZE(PARTITION_TYPES)]; -extern const vpx_tree_index - vp9_switchable_interp_tree[TREE_SIZE(SWITCHABLE_FILTERS)]; - -void vp9_setup_past_independence(struct VP9Common *cm); - -void vp9_adapt_mode_probs(struct VP9Common *cm); - -void tx_counts_to_branch_counts_32x32(const unsigned int *tx_count_32x32p, - unsigned int (*ct_32x32p)[2]); -void tx_counts_to_branch_counts_16x16(const unsigned int *tx_count_16x16p, - unsigned int (*ct_16x16p)[2]); -void tx_counts_to_branch_counts_8x8(const unsigned int *tx_count_8x8p, - unsigned int (*ct_8x8p)[2]); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_ENTROPYMODE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropymv.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropymv.c deleted file mode 100644 index b6f052d0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropymv.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp9/common/vp9_onyxc_int.h" -#include "vp9/common/vp9_entropymv.h" - -const vpx_tree_index vp9_mv_joint_tree[TREE_SIZE(MV_JOINTS)] = { - -MV_JOINT_ZERO, 2, -MV_JOINT_HNZVZ, 4, -MV_JOINT_HZVNZ, -MV_JOINT_HNZVNZ -}; - -const vpx_tree_index vp9_mv_class_tree[TREE_SIZE(MV_CLASSES)] = { - -MV_CLASS_0, 2, -MV_CLASS_1, 4, 6, - 8, -MV_CLASS_2, -MV_CLASS_3, 10, 12, - -MV_CLASS_4, -MV_CLASS_5, -MV_CLASS_6, 14, 16, - 18, -MV_CLASS_7, -MV_CLASS_8, -MV_CLASS_9, -MV_CLASS_10, -}; - -const vpx_tree_index vp9_mv_class0_tree[TREE_SIZE(CLASS0_SIZE)] = { -0, -1 }; - -const vpx_tree_index vp9_mv_fp_tree[TREE_SIZE(MV_FP_SIZE)] = { -0, 2, -1, - 4, -2, -3 }; - -static const nmv_context default_nmv_context = { - { 32, 64, 96 }, - { { - // Vertical component - 128, // sign - { 224, 144, 192, 168, 192, 176, 192, 198, 198, 245 }, // class - { 216 }, // class0 - { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240 }, // bits - { { 128, 128, 64 }, { 96, 112, 64 } }, // class0_fp - { 64, 96, 64 }, // fp - 160, // class0_hp bit - 128, // hp - }, - { - // Horizontal component - 128, // sign - { 216, 128, 176, 160, 176, 176, 192, 198, 198, 208 }, // class - { 208 }, // class0 - { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240 }, // bits - { { 128, 128, 64 }, { 96, 112, 64 } }, // class0_fp - { 64, 96, 64 }, // fp - 160, // class0_hp bit - 128, // hp - } }, -}; - -static const uint8_t log_in_base_2[] = { - 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10 -}; - -static INLINE int mv_class_base(MV_CLASS_TYPE c) { - return c ? CLASS0_SIZE << (c + 2) : 0; -} - -MV_CLASS_TYPE vp9_get_mv_class(int z, int *offset) { - const MV_CLASS_TYPE c = (z >= CLASS0_SIZE * 4096) - ? MV_CLASS_10 - : (MV_CLASS_TYPE)log_in_base_2[z >> 3]; - if (offset) *offset = z - mv_class_base(c); - return c; -} - -static void inc_mv_component(int v, nmv_component_counts *comp_counts, int incr, - int usehp) { - int s, z, c, o, d, e, f; - assert(v != 0); /* should not be zero */ - s = v < 0; - comp_counts->sign[s] += incr; - z = (s ? -v : v) - 1; /* magnitude - 1 */ - - c = vp9_get_mv_class(z, &o); - comp_counts->classes[c] += incr; - - d = (o >> 3); /* int mv data */ - f = (o >> 1) & 3; /* fractional pel mv data */ - e = (o & 1); /* high precision mv data */ - - if (c == MV_CLASS_0) { - comp_counts->class0[d] += incr; - comp_counts->class0_fp[d][f] += incr; - comp_counts->class0_hp[e] += usehp * incr; - } else { - int i; - int b = c + CLASS0_BITS - 1; // number of bits - for (i = 0; i < b; ++i) comp_counts->bits[i][((d >> i) & 1)] += incr; - comp_counts->fp[f] += incr; - comp_counts->hp[e] += usehp * incr; - } -} - -void vp9_inc_mv(const MV *mv, nmv_context_counts *counts) { - if (counts != NULL) { - const MV_JOINT_TYPE j = vp9_get_mv_joint(mv); - ++counts->joints[j]; - - if (mv_joint_vertical(j)) { - inc_mv_component(mv->row, &counts->comps[0], 1, 1); - } - - if (mv_joint_horizontal(j)) { - inc_mv_component(mv->col, &counts->comps[1], 1, 1); - } - } -} - -void vp9_adapt_mv_probs(VP9_COMMON *cm, int allow_hp) { - int i, j; - - nmv_context *fc = &cm->fc->nmvc; - const nmv_context *pre_fc = &cm->frame_contexts[cm->frame_context_idx].nmvc; - const nmv_context_counts *counts = &cm->counts.mv; - - vpx_tree_merge_probs(vp9_mv_joint_tree, pre_fc->joints, counts->joints, - fc->joints); - - for (i = 0; i < 2; ++i) { - nmv_component *comp = &fc->comps[i]; - const nmv_component *pre_comp = &pre_fc->comps[i]; - const nmv_component_counts *c = &counts->comps[i]; - - comp->sign = mode_mv_merge_probs(pre_comp->sign, c->sign); - vpx_tree_merge_probs(vp9_mv_class_tree, pre_comp->classes, c->classes, - comp->classes); - vpx_tree_merge_probs(vp9_mv_class0_tree, pre_comp->class0, c->class0, - comp->class0); - - for (j = 0; j < MV_OFFSET_BITS; ++j) - comp->bits[j] = mode_mv_merge_probs(pre_comp->bits[j], c->bits[j]); - - for (j = 0; j < CLASS0_SIZE; ++j) - vpx_tree_merge_probs(vp9_mv_fp_tree, pre_comp->class0_fp[j], - c->class0_fp[j], comp->class0_fp[j]); - - vpx_tree_merge_probs(vp9_mv_fp_tree, pre_comp->fp, c->fp, comp->fp); - - if (allow_hp) { - comp->class0_hp = mode_mv_merge_probs(pre_comp->class0_hp, c->class0_hp); - comp->hp = mode_mv_merge_probs(pre_comp->hp, c->hp); - } - } -} - -void vp9_init_mv_probs(VP9_COMMON *cm) { cm->fc->nmvc = default_nmv_context; } diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropymv.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropymv.h deleted file mode 100644 index ee9d3797..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_entropymv.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_ENTROPYMV_H_ -#define VPX_VP9_COMMON_VP9_ENTROPYMV_H_ - -#include "./vpx_config.h" - -#include "vpx_dsp/prob.h" - -#include "vp9/common/vp9_mv.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct VP9Common; - -void vp9_init_mv_probs(struct VP9Common *cm); - -void vp9_adapt_mv_probs(struct VP9Common *cm, int allow_hp); - -static INLINE int use_mv_hp(const MV *ref) { - const int kMvRefThresh = 64; // threshold for use of high-precision 1/8 mv - return abs(ref->row) < kMvRefThresh && abs(ref->col) < kMvRefThresh; -} - -#define MV_UPDATE_PROB 252 - -/* Symbols for coding which components are zero jointly */ -#define MV_JOINTS 4 -typedef enum { - MV_JOINT_ZERO = 0, /* Zero vector */ - MV_JOINT_HNZVZ = 1, /* Vert zero, hor nonzero */ - MV_JOINT_HZVNZ = 2, /* Hor zero, vert nonzero */ - MV_JOINT_HNZVNZ = 3, /* Both components nonzero */ -} MV_JOINT_TYPE; - -static INLINE int mv_joint_vertical(MV_JOINT_TYPE type) { - return type == MV_JOINT_HZVNZ || type == MV_JOINT_HNZVNZ; -} - -static INLINE int mv_joint_horizontal(MV_JOINT_TYPE type) { - return type == MV_JOINT_HNZVZ || type == MV_JOINT_HNZVNZ; -} - -/* Symbols for coding magnitude class of nonzero components */ -#define MV_CLASSES 11 -typedef enum { - MV_CLASS_0 = 0, /* (0, 2] integer pel */ - MV_CLASS_1 = 1, /* (2, 4] integer pel */ - MV_CLASS_2 = 2, /* (4, 8] integer pel */ - MV_CLASS_3 = 3, /* (8, 16] integer pel */ - MV_CLASS_4 = 4, /* (16, 32] integer pel */ - MV_CLASS_5 = 5, /* (32, 64] integer pel */ - MV_CLASS_6 = 6, /* (64, 128] integer pel */ - MV_CLASS_7 = 7, /* (128, 256] integer pel */ - MV_CLASS_8 = 8, /* (256, 512] integer pel */ - MV_CLASS_9 = 9, /* (512, 1024] integer pel */ - MV_CLASS_10 = 10, /* (1024,2048] integer pel */ -} MV_CLASS_TYPE; - -#define CLASS0_BITS 1 /* bits at integer precision for class 0 */ -#define CLASS0_SIZE (1 << CLASS0_BITS) -#define MV_OFFSET_BITS (MV_CLASSES + CLASS0_BITS - 2) -#define MV_FP_SIZE 4 - -#define MV_MAX_BITS (MV_CLASSES + CLASS0_BITS + 2) -#define MV_MAX ((1 << MV_MAX_BITS) - 1) -#define MV_VALS ((MV_MAX << 1) + 1) - -#define MV_IN_USE_BITS 14 -#define MV_UPP ((1 << MV_IN_USE_BITS) - 1) -#define MV_LOW (-(1 << MV_IN_USE_BITS)) - -extern const vpx_tree_index vp9_mv_joint_tree[]; -extern const vpx_tree_index vp9_mv_class_tree[]; -extern const vpx_tree_index vp9_mv_class0_tree[]; -extern const vpx_tree_index vp9_mv_fp_tree[]; - -typedef struct { - vpx_prob sign; - vpx_prob classes[MV_CLASSES - 1]; - vpx_prob class0[CLASS0_SIZE - 1]; - vpx_prob bits[MV_OFFSET_BITS]; - vpx_prob class0_fp[CLASS0_SIZE][MV_FP_SIZE - 1]; - vpx_prob fp[MV_FP_SIZE - 1]; - vpx_prob class0_hp; - vpx_prob hp; -} nmv_component; - -typedef struct { - vpx_prob joints[MV_JOINTS - 1]; - nmv_component comps[2]; -} nmv_context; - -static INLINE MV_JOINT_TYPE vp9_get_mv_joint(const MV *mv) { - if (mv->row == 0) { - return mv->col == 0 ? MV_JOINT_ZERO : MV_JOINT_HNZVZ; - } else { - return mv->col == 0 ? MV_JOINT_HZVNZ : MV_JOINT_HNZVNZ; - } -} - -MV_CLASS_TYPE vp9_get_mv_class(int z, int *offset); - -typedef struct { - unsigned int sign[2]; - unsigned int classes[MV_CLASSES]; - unsigned int class0[CLASS0_SIZE]; - unsigned int bits[MV_OFFSET_BITS][2]; - unsigned int class0_fp[CLASS0_SIZE][MV_FP_SIZE]; - unsigned int fp[MV_FP_SIZE]; - unsigned int class0_hp[2]; - unsigned int hp[2]; -} nmv_component_counts; - -typedef struct { - unsigned int joints[MV_JOINTS]; - nmv_component_counts comps[2]; -} nmv_context_counts; - -void vp9_inc_mv(const MV *mv, nmv_context_counts *counts); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_ENTROPYMV_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_enums.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_enums.h deleted file mode 100644 index b33a3a29..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_enums.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_ENUMS_H_ -#define VPX_VP9_COMMON_VP9_ENUMS_H_ - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MI_SIZE_LOG2 3 -#define MI_BLOCK_SIZE_LOG2 (6 - MI_SIZE_LOG2) // 64 = 2^6 - -#define MI_SIZE (1 << MI_SIZE_LOG2) // pixels per mi-unit -#define MI_BLOCK_SIZE (1 << MI_BLOCK_SIZE_LOG2) // mi-units per max block - -#define MI_MASK (MI_BLOCK_SIZE - 1) - -// Bitstream profiles indicated by 2-3 bits in the uncompressed header. -// 00: Profile 0. 8-bit 4:2:0 only. -// 10: Profile 1. 8-bit 4:4:4, 4:2:2, and 4:4:0. -// 01: Profile 2. 10-bit and 12-bit color only, with 4:2:0 sampling. -// 110: Profile 3. 10-bit and 12-bit color only, with 4:2:2/4:4:4/4:4:0 -// sampling. -// 111: Undefined profile. -typedef enum BITSTREAM_PROFILE { - PROFILE_0, - PROFILE_1, - PROFILE_2, - PROFILE_3, - MAX_PROFILES -} BITSTREAM_PROFILE; - -typedef enum PARSE_RECON_FLAG { PARSE = 1, RECON = 2 } PARSE_RECON_FLAG; - -#define BLOCK_4X4 0 -#define BLOCK_4X8 1 -#define BLOCK_8X4 2 -#define BLOCK_8X8 3 -#define BLOCK_8X16 4 -#define BLOCK_16X8 5 -#define BLOCK_16X16 6 -#define BLOCK_16X32 7 -#define BLOCK_32X16 8 -#define BLOCK_32X32 9 -#define BLOCK_32X64 10 -#define BLOCK_64X32 11 -#define BLOCK_64X64 12 -#define BLOCK_SIZES 13 -#define BLOCK_INVALID BLOCK_SIZES -typedef uint8_t BLOCK_SIZE; - -typedef enum PARTITION_TYPE { - PARTITION_NONE, - PARTITION_HORZ, - PARTITION_VERT, - PARTITION_SPLIT, - PARTITION_TYPES, - PARTITION_INVALID = PARTITION_TYPES -} PARTITION_TYPE; - -typedef char PARTITION_CONTEXT; -#define PARTITION_PLOFFSET 4 // number of probability models per block size -#define PARTITION_CONTEXTS (4 * PARTITION_PLOFFSET) - -// block transform size -typedef uint8_t TX_SIZE; -#define TX_4X4 ((TX_SIZE)0) // 4x4 transform -#define TX_8X8 ((TX_SIZE)1) // 8x8 transform -#define TX_16X16 ((TX_SIZE)2) // 16x16 transform -#define TX_32X32 ((TX_SIZE)3) // 32x32 transform -#define TX_SIZES ((TX_SIZE)4) - -// frame transform mode -typedef enum { - ONLY_4X4 = 0, // only 4x4 transform used - ALLOW_8X8 = 1, // allow block transform size up to 8x8 - ALLOW_16X16 = 2, // allow block transform size up to 16x16 - ALLOW_32X32 = 3, // allow block transform size up to 32x32 - TX_MODE_SELECT = 4, // transform specified for each block - TX_MODES = 5, -} TX_MODE; - -typedef enum { - DCT_DCT = 0, // DCT in both horizontal and vertical - ADST_DCT = 1, // ADST in vertical, DCT in horizontal - DCT_ADST = 2, // DCT in vertical, ADST in horizontal - ADST_ADST = 3, // ADST in both directions - TX_TYPES = 4 -} TX_TYPE; - -typedef enum { - VP9_LAST_FLAG = 1 << 0, - VP9_GOLD_FLAG = 1 << 1, - VP9_ALT_FLAG = 1 << 2, -} VP9_REFFRAME; - -typedef enum { PLANE_TYPE_Y = 0, PLANE_TYPE_UV = 1, PLANE_TYPES } PLANE_TYPE; - -#define DC_PRED 0 // Average of above and left pixels -#define V_PRED 1 // Vertical -#define H_PRED 2 // Horizontal -#define D45_PRED 3 // Directional 45 deg = round(arctan(1/1) * 180/pi) -#define D135_PRED 4 // Directional 135 deg = 180 - 45 -#define D117_PRED 5 // Directional 117 deg = 180 - 63 -#define D153_PRED 6 // Directional 153 deg = 180 - 27 -#define D207_PRED 7 // Directional 207 deg = 180 + 27 -#define D63_PRED 8 // Directional 63 deg = round(arctan(2/1) * 180/pi) -#define TM_PRED 9 // True-motion -#define NEARESTMV 10 -#define NEARMV 11 -#define ZEROMV 12 -#define NEWMV 13 -#define MB_MODE_COUNT 14 -typedef uint8_t PREDICTION_MODE; - -#define INTRA_MODES (TM_PRED + 1) - -#define INTER_MODES (1 + NEWMV - NEARESTMV) - -#define SKIP_CONTEXTS 3 -#define INTER_MODE_CONTEXTS 7 - -/* Segment Feature Masks */ -#define MAX_MV_REF_CANDIDATES 2 - -#define INTRA_INTER_CONTEXTS 4 -#define COMP_INTER_CONTEXTS 5 -#define REF_CONTEXTS 5 - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_ENUMS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_filter.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_filter.c deleted file mode 100644 index adbda6c8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_filter.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "vp9/common/vp9_filter.h" - -DECLARE_ALIGNED(256, static const InterpKernel, - bilinear_filters[SUBPEL_SHIFTS]) = { - { 0, 0, 0, 128, 0, 0, 0, 0 }, { 0, 0, 0, 120, 8, 0, 0, 0 }, - { 0, 0, 0, 112, 16, 0, 0, 0 }, { 0, 0, 0, 104, 24, 0, 0, 0 }, - { 0, 0, 0, 96, 32, 0, 0, 0 }, { 0, 0, 0, 88, 40, 0, 0, 0 }, - { 0, 0, 0, 80, 48, 0, 0, 0 }, { 0, 0, 0, 72, 56, 0, 0, 0 }, - { 0, 0, 0, 64, 64, 0, 0, 0 }, { 0, 0, 0, 56, 72, 0, 0, 0 }, - { 0, 0, 0, 48, 80, 0, 0, 0 }, { 0, 0, 0, 40, 88, 0, 0, 0 }, - { 0, 0, 0, 32, 96, 0, 0, 0 }, { 0, 0, 0, 24, 104, 0, 0, 0 }, - { 0, 0, 0, 16, 112, 0, 0, 0 }, { 0, 0, 0, 8, 120, 0, 0, 0 } -}; - -// Lagrangian interpolation filter -DECLARE_ALIGNED(256, static const InterpKernel, - sub_pel_filters_8[SUBPEL_SHIFTS]) = { - { 0, 0, 0, 128, 0, 0, 0, 0 }, { 0, 1, -5, 126, 8, -3, 1, 0 }, - { -1, 3, -10, 122, 18, -6, 2, 0 }, { -1, 4, -13, 118, 27, -9, 3, -1 }, - { -1, 4, -16, 112, 37, -11, 4, -1 }, { -1, 5, -18, 105, 48, -14, 4, -1 }, - { -1, 5, -19, 97, 58, -16, 5, -1 }, { -1, 6, -19, 88, 68, -18, 5, -1 }, - { -1, 6, -19, 78, 78, -19, 6, -1 }, { -1, 5, -18, 68, 88, -19, 6, -1 }, - { -1, 5, -16, 58, 97, -19, 5, -1 }, { -1, 4, -14, 48, 105, -18, 5, -1 }, - { -1, 4, -11, 37, 112, -16, 4, -1 }, { -1, 3, -9, 27, 118, -13, 4, -1 }, - { 0, 2, -6, 18, 122, -10, 3, -1 }, { 0, 1, -3, 8, 126, -5, 1, 0 } -}; - -// DCT based filter -DECLARE_ALIGNED(256, static const InterpKernel, - sub_pel_filters_8s[SUBPEL_SHIFTS]) = { - { 0, 0, 0, 128, 0, 0, 0, 0 }, { -1, 3, -7, 127, 8, -3, 1, 0 }, - { -2, 5, -13, 125, 17, -6, 3, -1 }, { -3, 7, -17, 121, 27, -10, 5, -2 }, - { -4, 9, -20, 115, 37, -13, 6, -2 }, { -4, 10, -23, 108, 48, -16, 8, -3 }, - { -4, 10, -24, 100, 59, -19, 9, -3 }, { -4, 11, -24, 90, 70, -21, 10, -4 }, - { -4, 11, -23, 80, 80, -23, 11, -4 }, { -4, 10, -21, 70, 90, -24, 11, -4 }, - { -3, 9, -19, 59, 100, -24, 10, -4 }, { -3, 8, -16, 48, 108, -23, 10, -4 }, - { -2, 6, -13, 37, 115, -20, 9, -4 }, { -2, 5, -10, 27, 121, -17, 7, -3 }, - { -1, 3, -6, 17, 125, -13, 5, -2 }, { 0, 1, -3, 8, 127, -7, 3, -1 } -}; - -// freqmultiplier = 0.5 -DECLARE_ALIGNED(256, static const InterpKernel, - sub_pel_filters_8lp[SUBPEL_SHIFTS]) = { - { 0, 0, 0, 128, 0, 0, 0, 0 }, { -3, -1, 32, 64, 38, 1, -3, 0 }, - { -2, -2, 29, 63, 41, 2, -3, 0 }, { -2, -2, 26, 63, 43, 4, -4, 0 }, - { -2, -3, 24, 62, 46, 5, -4, 0 }, { -2, -3, 21, 60, 49, 7, -4, 0 }, - { -1, -4, 18, 59, 51, 9, -4, 0 }, { -1, -4, 16, 57, 53, 12, -4, -1 }, - { -1, -4, 14, 55, 55, 14, -4, -1 }, { -1, -4, 12, 53, 57, 16, -4, -1 }, - { 0, -4, 9, 51, 59, 18, -4, -1 }, { 0, -4, 7, 49, 60, 21, -3, -2 }, - { 0, -4, 5, 46, 62, 24, -3, -2 }, { 0, -4, 4, 43, 63, 26, -2, -2 }, - { 0, -3, 2, 41, 63, 29, -2, -2 }, { 0, -3, 1, 38, 64, 32, -1, -3 } -}; - -// 4-tap filter -DECLARE_ALIGNED(256, static const InterpKernel, - sub_pel_filters_4[SUBPEL_SHIFTS]) = { - { 0, 0, 0, 128, 0, 0, 0, 0 }, { 0, 0, -4, 126, 8, -2, 0, 0 }, - { 0, 0, -6, 120, 18, -4, 0, 0 }, { 0, 0, -8, 114, 28, -6, 0, 0 }, - { 0, 0, -10, 108, 36, -6, 0, 0 }, { 0, 0, -12, 102, 46, -8, 0, 0 }, - { 0, 0, -12, 94, 56, -10, 0, 0 }, { 0, 0, -12, 84, 66, -10, 0, 0 }, - { 0, 0, -12, 76, 76, -12, 0, 0 }, { 0, 0, -10, 66, 84, -12, 0, 0 }, - { 0, 0, -10, 56, 94, -12, 0, 0 }, { 0, 0, -8, 46, 102, -12, 0, 0 }, - { 0, 0, -6, 36, 108, -10, 0, 0 }, { 0, 0, -6, 28, 114, -8, 0, 0 }, - { 0, 0, -4, 18, 120, -6, 0, 0 }, { 0, 0, -2, 8, 126, -4, 0, 0 } -}; - -const InterpKernel *vp9_filter_kernels[5] = { - sub_pel_filters_8, sub_pel_filters_8lp, sub_pel_filters_8s, bilinear_filters, - sub_pel_filters_4 -}; diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_filter.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_filter.h deleted file mode 100644 index 0382c88e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_filter.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2011 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_FILTER_H_ -#define VPX_VP9_COMMON_VP9_FILTER_H_ - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_ports/mem.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define EIGHTTAP 0 -#define EIGHTTAP_SMOOTH 1 -#define EIGHTTAP_SHARP 2 -#define SWITCHABLE_FILTERS 3 /* Number of switchable filters */ -#define BILINEAR 3 -#define FOURTAP 4 -// The codec can operate in four possible inter prediction filter mode: -// 8-tap, 8-tap-smooth, 8-tap-sharp, and switching between the three. -#define SWITCHABLE_FILTER_CONTEXTS (SWITCHABLE_FILTERS + 1) -#define SWITCHABLE 4 /* should be the last one */ - -typedef uint8_t INTERP_FILTER; - -extern const InterpKernel *vp9_filter_kernels[5]; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_FILTER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_frame_buffers.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_frame_buffers.c deleted file mode 100644 index 889b809e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_frame_buffers.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "vp9/common/vp9_frame_buffers.h" -#include "vpx_mem/vpx_mem.h" - -int vp9_alloc_internal_frame_buffers(InternalFrameBufferList *list) { - const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; - assert(list != NULL); - vp9_free_internal_frame_buffers(list); - - list->int_fb = - (InternalFrameBuffer *)vpx_calloc(num_buffers, sizeof(*list->int_fb)); - if (list->int_fb) { - list->num_internal_frame_buffers = num_buffers; - return 0; - } - return -1; -} - -void vp9_free_internal_frame_buffers(InternalFrameBufferList *list) { - int i; - - assert(list != NULL); - - for (i = 0; i < list->num_internal_frame_buffers; ++i) { - vpx_free(list->int_fb[i].data); - list->int_fb[i].data = NULL; - } - vpx_free(list->int_fb); - list->int_fb = NULL; - list->num_internal_frame_buffers = 0; -} - -int vp9_get_frame_buffer(void *cb_priv, size_t min_size, - vpx_codec_frame_buffer_t *fb) { - int i; - InternalFrameBufferList *const int_fb_list = - (InternalFrameBufferList *)cb_priv; - if (int_fb_list == NULL) return -1; - - // Find a free frame buffer. - for (i = 0; i < int_fb_list->num_internal_frame_buffers; ++i) { - if (!int_fb_list->int_fb[i].in_use) break; - } - - if (i == int_fb_list->num_internal_frame_buffers) return -1; - - if (int_fb_list->int_fb[i].size < min_size) { - vpx_free(int_fb_list->int_fb[i].data); - // The data must be zeroed to fix a valgrind error from the C loop filter - // due to access uninitialized memory in frame border. It could be - // skipped if border were totally removed. - int_fb_list->int_fb[i].data = (uint8_t *)vpx_calloc(1, min_size); - if (!int_fb_list->int_fb[i].data) return -1; - int_fb_list->int_fb[i].size = min_size; - } - - fb->data = int_fb_list->int_fb[i].data; - fb->size = int_fb_list->int_fb[i].size; - int_fb_list->int_fb[i].in_use = 1; - - // Set the frame buffer's private data to point at the internal frame buffer. - fb->priv = &int_fb_list->int_fb[i]; - return 0; -} - -int vp9_release_frame_buffer(void *cb_priv, vpx_codec_frame_buffer_t *fb) { - InternalFrameBuffer *const int_fb = (InternalFrameBuffer *)fb->priv; - (void)cb_priv; - if (int_fb) int_fb->in_use = 0; - return 0; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_frame_buffers.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_frame_buffers.h deleted file mode 100644 index 11be838c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_frame_buffers.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_FRAME_BUFFERS_H_ -#define VPX_VP9_COMMON_VP9_FRAME_BUFFERS_H_ - -#include "vpx/vpx_frame_buffer.h" -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct InternalFrameBuffer { - uint8_t *data; - size_t size; - int in_use; -} InternalFrameBuffer; - -typedef struct InternalFrameBufferList { - int num_internal_frame_buffers; - InternalFrameBuffer *int_fb; -} InternalFrameBufferList; - -// Initializes |list|. Returns 0 on success. -int vp9_alloc_internal_frame_buffers(InternalFrameBufferList *list); - -// Free any data allocated to the frame buffers. -void vp9_free_internal_frame_buffers(InternalFrameBufferList *list); - -// Callback used by libvpx to request an external frame buffer. |cb_priv| -// Callback private data, which points to an InternalFrameBufferList. -// |min_size| is the minimum size in bytes needed to decode the next frame. -// |fb| pointer to the frame buffer. -int vp9_get_frame_buffer(void *cb_priv, size_t min_size, - vpx_codec_frame_buffer_t *fb); - -// Callback used by libvpx when there are no references to the frame buffer. -// |cb_priv| is not used. |fb| pointer to the frame buffer. -int vp9_release_frame_buffer(void *cb_priv, vpx_codec_frame_buffer_t *fb); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_FRAME_BUFFERS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_idct.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_idct.c deleted file mode 100644 index 71be0f31..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_idct.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp9_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_idct.h" -#include "vpx_dsp/inv_txfm.h" -#include "vpx_ports/mem.h" - -void vp9_iht4x4_16_add_c(const tran_low_t *input, uint8_t *dest, int stride, - int tx_type) { - const transform_2d IHT_4[] = { - { idct4_c, idct4_c }, // DCT_DCT = 0 - { iadst4_c, idct4_c }, // ADST_DCT = 1 - { idct4_c, iadst4_c }, // DCT_ADST = 2 - { iadst4_c, iadst4_c } // ADST_ADST = 3 - }; - - int i, j; - tran_low_t out[4 * 4]; - tran_low_t *outptr = out; - tran_low_t temp_in[4], temp_out[4]; - - // inverse transform row vectors - for (i = 0; i < 4; ++i) { - IHT_4[tx_type].rows(input, outptr); - input += 4; - outptr += 4; - } - - // inverse transform column vectors - for (i = 0; i < 4; ++i) { - for (j = 0; j < 4; ++j) temp_in[j] = out[j * 4 + i]; - IHT_4[tx_type].cols(temp_in, temp_out); - for (j = 0; j < 4; ++j) { - dest[j * stride + i] = clip_pixel_add(dest[j * stride + i], - ROUND_POWER_OF_TWO(temp_out[j], 4)); - } - } -} - -static const transform_2d IHT_8[] = { - { idct8_c, idct8_c }, // DCT_DCT = 0 - { iadst8_c, idct8_c }, // ADST_DCT = 1 - { idct8_c, iadst8_c }, // DCT_ADST = 2 - { iadst8_c, iadst8_c } // ADST_ADST = 3 -}; - -void vp9_iht8x8_64_add_c(const tran_low_t *input, uint8_t *dest, int stride, - int tx_type) { - int i, j; - tran_low_t out[8 * 8]; - tran_low_t *outptr = out; - tran_low_t temp_in[8], temp_out[8]; - const transform_2d ht = IHT_8[tx_type]; - - // inverse transform row vectors - for (i = 0; i < 8; ++i) { - ht.rows(input, outptr); - input += 8; - outptr += 8; - } - - // inverse transform column vectors - for (i = 0; i < 8; ++i) { - for (j = 0; j < 8; ++j) temp_in[j] = out[j * 8 + i]; - ht.cols(temp_in, temp_out); - for (j = 0; j < 8; ++j) { - dest[j * stride + i] = clip_pixel_add(dest[j * stride + i], - ROUND_POWER_OF_TWO(temp_out[j], 5)); - } - } -} - -static const transform_2d IHT_16[] = { - { idct16_c, idct16_c }, // DCT_DCT = 0 - { iadst16_c, idct16_c }, // ADST_DCT = 1 - { idct16_c, iadst16_c }, // DCT_ADST = 2 - { iadst16_c, iadst16_c } // ADST_ADST = 3 -}; - -void vp9_iht16x16_256_add_c(const tran_low_t *input, uint8_t *dest, int stride, - int tx_type) { - int i, j; - tran_low_t out[16 * 16]; - tran_low_t *outptr = out; - tran_low_t temp_in[16], temp_out[16]; - const transform_2d ht = IHT_16[tx_type]; - - // Rows - for (i = 0; i < 16; ++i) { - ht.rows(input, outptr); - input += 16; - outptr += 16; - } - - // Columns - for (i = 0; i < 16; ++i) { - for (j = 0; j < 16; ++j) temp_in[j] = out[j * 16 + i]; - ht.cols(temp_in, temp_out); - for (j = 0; j < 16; ++j) { - dest[j * stride + i] = clip_pixel_add(dest[j * stride + i], - ROUND_POWER_OF_TWO(temp_out[j], 6)); - } - } -} - -// idct -void vp9_idct4x4_add(const tran_low_t *input, uint8_t *dest, int stride, - int eob) { - if (eob > 1) - vpx_idct4x4_16_add(input, dest, stride); - else - vpx_idct4x4_1_add(input, dest, stride); -} - -void vp9_iwht4x4_add(const tran_low_t *input, uint8_t *dest, int stride, - int eob) { - if (eob > 1) - vpx_iwht4x4_16_add(input, dest, stride); - else - vpx_iwht4x4_1_add(input, dest, stride); -} - -void vp9_idct8x8_add(const tran_low_t *input, uint8_t *dest, int stride, - int eob) { - // If dc is 1, then input[0] is the reconstructed value, do not need - // dequantization. Also, when dc is 1, dc is counted in eobs, namely eobs >=1. - - // The calculation can be simplified if there are not many non-zero dct - // coefficients. Use eobs to decide what to do. - if (eob == 1) - // DC only DCT coefficient - vpx_idct8x8_1_add(input, dest, stride); - else if (eob <= 12) - vpx_idct8x8_12_add(input, dest, stride); - else - vpx_idct8x8_64_add(input, dest, stride); -} - -void vp9_idct16x16_add(const tran_low_t *input, uint8_t *dest, int stride, - int eob) { - assert(((intptr_t)input) % 32 == 0); - /* The calculation can be simplified if there are not many non-zero dct - * coefficients. Use eobs to separate different cases. */ - if (eob == 1) /* DC only DCT coefficient. */ - vpx_idct16x16_1_add(input, dest, stride); - else if (eob <= 10) - vpx_idct16x16_10_add(input, dest, stride); - else if (eob <= 38) - vpx_idct16x16_38_add(input, dest, stride); - else - vpx_idct16x16_256_add(input, dest, stride); -} - -void vp9_idct32x32_add(const tran_low_t *input, uint8_t *dest, int stride, - int eob) { - assert(((intptr_t)input) % 32 == 0); - if (eob == 1) - vpx_idct32x32_1_add(input, dest, stride); - else if (eob <= 34) - // non-zero coeff only in upper-left 8x8 - vpx_idct32x32_34_add(input, dest, stride); - else if (eob <= 135) - // non-zero coeff only in upper-left 16x16 - vpx_idct32x32_135_add(input, dest, stride); - else - vpx_idct32x32_1024_add(input, dest, stride); -} - -// iht -void vp9_iht4x4_add(TX_TYPE tx_type, const tran_low_t *input, uint8_t *dest, - int stride, int eob) { - if (tx_type == DCT_DCT) - vp9_idct4x4_add(input, dest, stride, eob); - else - vp9_iht4x4_16_add(input, dest, stride, tx_type); -} - -void vp9_iht8x8_add(TX_TYPE tx_type, const tran_low_t *input, uint8_t *dest, - int stride, int eob) { - if (tx_type == DCT_DCT) { - vp9_idct8x8_add(input, dest, stride, eob); - } else { - vp9_iht8x8_64_add(input, dest, stride, tx_type); - } -} - -void vp9_iht16x16_add(TX_TYPE tx_type, const tran_low_t *input, uint8_t *dest, - int stride, int eob) { - if (tx_type == DCT_DCT) { - vp9_idct16x16_add(input, dest, stride, eob); - } else { - vp9_iht16x16_256_add(input, dest, stride, tx_type); - } -} - -#if CONFIG_VP9_HIGHBITDEPTH - -void vp9_highbd_iht4x4_16_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int tx_type, int bd) { - const highbd_transform_2d IHT_4[] = { - { vpx_highbd_idct4_c, vpx_highbd_idct4_c }, // DCT_DCT = 0 - { vpx_highbd_iadst4_c, vpx_highbd_idct4_c }, // ADST_DCT = 1 - { vpx_highbd_idct4_c, vpx_highbd_iadst4_c }, // DCT_ADST = 2 - { vpx_highbd_iadst4_c, vpx_highbd_iadst4_c } // ADST_ADST = 3 - }; - - int i, j; - tran_low_t out[4 * 4]; - tran_low_t *outptr = out; - tran_low_t temp_in[4], temp_out[4]; - - // Inverse transform row vectors. - for (i = 0; i < 4; ++i) { - IHT_4[tx_type].rows(input, outptr, bd); - input += 4; - outptr += 4; - } - - // Inverse transform column vectors. - for (i = 0; i < 4; ++i) { - for (j = 0; j < 4; ++j) temp_in[j] = out[j * 4 + i]; - IHT_4[tx_type].cols(temp_in, temp_out, bd); - for (j = 0; j < 4; ++j) { - dest[j * stride + i] = highbd_clip_pixel_add( - dest[j * stride + i], ROUND_POWER_OF_TWO(temp_out[j], 4), bd); - } - } -} - -static const highbd_transform_2d HIGH_IHT_8[] = { - { vpx_highbd_idct8_c, vpx_highbd_idct8_c }, // DCT_DCT = 0 - { vpx_highbd_iadst8_c, vpx_highbd_idct8_c }, // ADST_DCT = 1 - { vpx_highbd_idct8_c, vpx_highbd_iadst8_c }, // DCT_ADST = 2 - { vpx_highbd_iadst8_c, vpx_highbd_iadst8_c } // ADST_ADST = 3 -}; - -void vp9_highbd_iht8x8_64_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int tx_type, int bd) { - int i, j; - tran_low_t out[8 * 8]; - tran_low_t *outptr = out; - tran_low_t temp_in[8], temp_out[8]; - const highbd_transform_2d ht = HIGH_IHT_8[tx_type]; - - // Inverse transform row vectors. - for (i = 0; i < 8; ++i) { - ht.rows(input, outptr, bd); - input += 8; - outptr += 8; - } - - // Inverse transform column vectors. - for (i = 0; i < 8; ++i) { - for (j = 0; j < 8; ++j) temp_in[j] = out[j * 8 + i]; - ht.cols(temp_in, temp_out, bd); - for (j = 0; j < 8; ++j) { - dest[j * stride + i] = highbd_clip_pixel_add( - dest[j * stride + i], ROUND_POWER_OF_TWO(temp_out[j], 5), bd); - } - } -} - -static const highbd_transform_2d HIGH_IHT_16[] = { - { vpx_highbd_idct16_c, vpx_highbd_idct16_c }, // DCT_DCT = 0 - { vpx_highbd_iadst16_c, vpx_highbd_idct16_c }, // ADST_DCT = 1 - { vpx_highbd_idct16_c, vpx_highbd_iadst16_c }, // DCT_ADST = 2 - { vpx_highbd_iadst16_c, vpx_highbd_iadst16_c } // ADST_ADST = 3 -}; - -void vp9_highbd_iht16x16_256_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int tx_type, int bd) { - int i, j; - tran_low_t out[16 * 16]; - tran_low_t *outptr = out; - tran_low_t temp_in[16], temp_out[16]; - const highbd_transform_2d ht = HIGH_IHT_16[tx_type]; - - // Rows - for (i = 0; i < 16; ++i) { - ht.rows(input, outptr, bd); - input += 16; - outptr += 16; - } - - // Columns - for (i = 0; i < 16; ++i) { - for (j = 0; j < 16; ++j) temp_in[j] = out[j * 16 + i]; - ht.cols(temp_in, temp_out, bd); - for (j = 0; j < 16; ++j) { - dest[j * stride + i] = highbd_clip_pixel_add( - dest[j * stride + i], ROUND_POWER_OF_TWO(temp_out[j], 6), bd); - } - } -} - -// idct -void vp9_highbd_idct4x4_add(const tran_low_t *input, uint16_t *dest, int stride, - int eob, int bd) { - if (eob > 1) - vpx_highbd_idct4x4_16_add(input, dest, stride, bd); - else - vpx_highbd_idct4x4_1_add(input, dest, stride, bd); -} - -void vp9_highbd_iwht4x4_add(const tran_low_t *input, uint16_t *dest, int stride, - int eob, int bd) { - if (eob > 1) - vpx_highbd_iwht4x4_16_add(input, dest, stride, bd); - else - vpx_highbd_iwht4x4_1_add(input, dest, stride, bd); -} - -void vp9_highbd_idct8x8_add(const tran_low_t *input, uint16_t *dest, int stride, - int eob, int bd) { - // If dc is 1, then input[0] is the reconstructed value, do not need - // dequantization. Also, when dc is 1, dc is counted in eobs, namely eobs >=1. - - // The calculation can be simplified if there are not many non-zero dct - // coefficients. Use eobs to decide what to do. - // DC only DCT coefficient - if (eob == 1) { - vpx_highbd_idct8x8_1_add(input, dest, stride, bd); - } else if (eob <= 12) { - vpx_highbd_idct8x8_12_add(input, dest, stride, bd); - } else { - vpx_highbd_idct8x8_64_add(input, dest, stride, bd); - } -} - -void vp9_highbd_idct16x16_add(const tran_low_t *input, uint16_t *dest, - int stride, int eob, int bd) { - // The calculation can be simplified if there are not many non-zero dct - // coefficients. Use eobs to separate different cases. - // DC only DCT coefficient. - if (eob == 1) { - vpx_highbd_idct16x16_1_add(input, dest, stride, bd); - } else if (eob <= 10) { - vpx_highbd_idct16x16_10_add(input, dest, stride, bd); - } else if (eob <= 38) { - vpx_highbd_idct16x16_38_add(input, dest, stride, bd); - } else { - vpx_highbd_idct16x16_256_add(input, dest, stride, bd); - } -} - -void vp9_highbd_idct32x32_add(const tran_low_t *input, uint16_t *dest, - int stride, int eob, int bd) { - // Non-zero coeff only in upper-left 8x8 - if (eob == 1) { - vpx_highbd_idct32x32_1_add(input, dest, stride, bd); - } else if (eob <= 34) { - vpx_highbd_idct32x32_34_add(input, dest, stride, bd); - } else if (eob <= 135) { - vpx_highbd_idct32x32_135_add(input, dest, stride, bd); - } else { - vpx_highbd_idct32x32_1024_add(input, dest, stride, bd); - } -} - -// iht -void vp9_highbd_iht4x4_add(TX_TYPE tx_type, const tran_low_t *input, - uint16_t *dest, int stride, int eob, int bd) { - if (tx_type == DCT_DCT) - vp9_highbd_idct4x4_add(input, dest, stride, eob, bd); - else - vp9_highbd_iht4x4_16_add(input, dest, stride, tx_type, bd); -} - -void vp9_highbd_iht8x8_add(TX_TYPE tx_type, const tran_low_t *input, - uint16_t *dest, int stride, int eob, int bd) { - if (tx_type == DCT_DCT) { - vp9_highbd_idct8x8_add(input, dest, stride, eob, bd); - } else { - vp9_highbd_iht8x8_64_add(input, dest, stride, tx_type, bd); - } -} - -void vp9_highbd_iht16x16_add(TX_TYPE tx_type, const tran_low_t *input, - uint16_t *dest, int stride, int eob, int bd) { - if (tx_type == DCT_DCT) { - vp9_highbd_idct16x16_add(input, dest, stride, eob, bd); - } else { - vp9_highbd_iht16x16_256_add(input, dest, stride, tx_type, bd); - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_idct.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_idct.h deleted file mode 100644 index 94eeaf59..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_idct.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_IDCT_H_ -#define VPX_VP9_COMMON_VP9_IDCT_H_ - -#include - -#include "./vpx_config.h" -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_enums.h" -#include "vpx_dsp/inv_txfm.h" -#include "vpx_dsp/txfm_common.h" -#include "vpx_ports/mem.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*transform_1d)(const tran_low_t *, tran_low_t *); - -typedef struct { - transform_1d cols, rows; // vertical and horizontal -} transform_2d; - -#if CONFIG_VP9_HIGHBITDEPTH -typedef void (*highbd_transform_1d)(const tran_low_t *, tran_low_t *, int bd); - -typedef struct { - highbd_transform_1d cols, rows; // vertical and horizontal -} highbd_transform_2d; -#endif // CONFIG_VP9_HIGHBITDEPTH - -void vp9_iwht4x4_add(const tran_low_t *input, uint8_t *dest, int stride, - int eob); -void vp9_idct4x4_add(const tran_low_t *input, uint8_t *dest, int stride, - int eob); -void vp9_idct8x8_add(const tran_low_t *input, uint8_t *dest, int stride, - int eob); -void vp9_idct16x16_add(const tran_low_t *input, uint8_t *dest, int stride, - int eob); -void vp9_idct32x32_add(const tran_low_t *input, uint8_t *dest, int stride, - int eob); - -void vp9_iht4x4_add(TX_TYPE tx_type, const tran_low_t *input, uint8_t *dest, - int stride, int eob); -void vp9_iht8x8_add(TX_TYPE tx_type, const tran_low_t *input, uint8_t *dest, - int stride, int eob); -void vp9_iht16x16_add(TX_TYPE tx_type, const tran_low_t *input, uint8_t *dest, - int stride, int eob); - -#if CONFIG_VP9_HIGHBITDEPTH -void vp9_highbd_iwht4x4_add(const tran_low_t *input, uint16_t *dest, int stride, - int eob, int bd); -void vp9_highbd_idct4x4_add(const tran_low_t *input, uint16_t *dest, int stride, - int eob, int bd); -void vp9_highbd_idct8x8_add(const tran_low_t *input, uint16_t *dest, int stride, - int eob, int bd); -void vp9_highbd_idct16x16_add(const tran_low_t *input, uint16_t *dest, - int stride, int eob, int bd); -void vp9_highbd_idct32x32_add(const tran_low_t *input, uint16_t *dest, - int stride, int eob, int bd); -void vp9_highbd_iht4x4_add(TX_TYPE tx_type, const tran_low_t *input, - uint16_t *dest, int stride, int eob, int bd); -void vp9_highbd_iht8x8_add(TX_TYPE tx_type, const tran_low_t *input, - uint16_t *dest, int stride, int eob, int bd); -void vp9_highbd_iht16x16_add(TX_TYPE tx_type, const tran_low_t *input, - uint16_t *dest, int stride, int eob, int bd); -#endif // CONFIG_VP9_HIGHBITDEPTH -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_IDCT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_loopfilter.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_loopfilter.c deleted file mode 100644 index 1a9d45ae..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_loopfilter.c +++ /dev/null @@ -1,1633 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vp9/common/vp9_loopfilter.h" -#include "vp9/common/vp9_onyxc_int.h" -#include "vp9/common/vp9_reconinter.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" - -#include "vp9/common/vp9_seg_common.h" - -// 64 bit masks for left transform size. Each 1 represents a position where -// we should apply a loop filter across the left border of an 8x8 block -// boundary. -// -// In the case of TX_16X16-> ( in low order byte first we end up with -// a mask that looks like this -// -// 10101010 -// 10101010 -// 10101010 -// 10101010 -// 10101010 -// 10101010 -// 10101010 -// 10101010 -// -// A loopfilter should be applied to every other 8x8 horizontally. -static const uint64_t left_64x64_txform_mask[TX_SIZES] = { - 0xffffffffffffffffULL, // TX_4X4 - 0xffffffffffffffffULL, // TX_8x8 - 0x5555555555555555ULL, // TX_16x16 - 0x1111111111111111ULL, // TX_32x32 -}; - -// 64 bit masks for above transform size. Each 1 represents a position where -// we should apply a loop filter across the top border of an 8x8 block -// boundary. -// -// In the case of TX_32x32 -> ( in low order byte first we end up with -// a mask that looks like this -// -// 11111111 -// 00000000 -// 00000000 -// 00000000 -// 11111111 -// 00000000 -// 00000000 -// 00000000 -// -// A loopfilter should be applied to every other 4 the row vertically. -static const uint64_t above_64x64_txform_mask[TX_SIZES] = { - 0xffffffffffffffffULL, // TX_4X4 - 0xffffffffffffffffULL, // TX_8x8 - 0x00ff00ff00ff00ffULL, // TX_16x16 - 0x000000ff000000ffULL, // TX_32x32 -}; - -// 64 bit masks for prediction sizes (left). Each 1 represents a position -// where left border of an 8x8 block. These are aligned to the right most -// appropriate bit, and then shifted into place. -// -// In the case of TX_16x32 -> ( low order byte first ) we end up with -// a mask that looks like this : -// -// 10000000 -// 10000000 -// 10000000 -// 10000000 -// 00000000 -// 00000000 -// 00000000 -// 00000000 -static const uint64_t left_prediction_mask[BLOCK_SIZES] = { - 0x0000000000000001ULL, // BLOCK_4X4, - 0x0000000000000001ULL, // BLOCK_4X8, - 0x0000000000000001ULL, // BLOCK_8X4, - 0x0000000000000001ULL, // BLOCK_8X8, - 0x0000000000000101ULL, // BLOCK_8X16, - 0x0000000000000001ULL, // BLOCK_16X8, - 0x0000000000000101ULL, // BLOCK_16X16, - 0x0000000001010101ULL, // BLOCK_16X32, - 0x0000000000000101ULL, // BLOCK_32X16, - 0x0000000001010101ULL, // BLOCK_32X32, - 0x0101010101010101ULL, // BLOCK_32X64, - 0x0000000001010101ULL, // BLOCK_64X32, - 0x0101010101010101ULL, // BLOCK_64X64 -}; - -// 64 bit mask to shift and set for each prediction size. -static const uint64_t above_prediction_mask[BLOCK_SIZES] = { - 0x0000000000000001ULL, // BLOCK_4X4 - 0x0000000000000001ULL, // BLOCK_4X8 - 0x0000000000000001ULL, // BLOCK_8X4 - 0x0000000000000001ULL, // BLOCK_8X8 - 0x0000000000000001ULL, // BLOCK_8X16, - 0x0000000000000003ULL, // BLOCK_16X8 - 0x0000000000000003ULL, // BLOCK_16X16 - 0x0000000000000003ULL, // BLOCK_16X32, - 0x000000000000000fULL, // BLOCK_32X16, - 0x000000000000000fULL, // BLOCK_32X32, - 0x000000000000000fULL, // BLOCK_32X64, - 0x00000000000000ffULL, // BLOCK_64X32, - 0x00000000000000ffULL, // BLOCK_64X64 -}; -// 64 bit mask to shift and set for each prediction size. A bit is set for -// each 8x8 block that would be in the left most block of the given block -// size in the 64x64 block. -static const uint64_t size_mask[BLOCK_SIZES] = { - 0x0000000000000001ULL, // BLOCK_4X4 - 0x0000000000000001ULL, // BLOCK_4X8 - 0x0000000000000001ULL, // BLOCK_8X4 - 0x0000000000000001ULL, // BLOCK_8X8 - 0x0000000000000101ULL, // BLOCK_8X16, - 0x0000000000000003ULL, // BLOCK_16X8 - 0x0000000000000303ULL, // BLOCK_16X16 - 0x0000000003030303ULL, // BLOCK_16X32, - 0x0000000000000f0fULL, // BLOCK_32X16, - 0x000000000f0f0f0fULL, // BLOCK_32X32, - 0x0f0f0f0f0f0f0f0fULL, // BLOCK_32X64, - 0x00000000ffffffffULL, // BLOCK_64X32, - 0xffffffffffffffffULL, // BLOCK_64X64 -}; - -// These are used for masking the left and above borders. -static const uint64_t left_border = 0x1111111111111111ULL; -static const uint64_t above_border = 0x000000ff000000ffULL; - -// 16 bit masks for uv transform sizes. -static const uint16_t left_64x64_txform_mask_uv[TX_SIZES] = { - 0xffff, // TX_4X4 - 0xffff, // TX_8x8 - 0x5555, // TX_16x16 - 0x1111, // TX_32x32 -}; - -static const uint16_t above_64x64_txform_mask_uv[TX_SIZES] = { - 0xffff, // TX_4X4 - 0xffff, // TX_8x8 - 0x0f0f, // TX_16x16 - 0x000f, // TX_32x32 -}; - -// 16 bit left mask to shift and set for each uv prediction size. -static const uint16_t left_prediction_mask_uv[BLOCK_SIZES] = { - 0x0001, // BLOCK_4X4, - 0x0001, // BLOCK_4X8, - 0x0001, // BLOCK_8X4, - 0x0001, // BLOCK_8X8, - 0x0001, // BLOCK_8X16, - 0x0001, // BLOCK_16X8, - 0x0001, // BLOCK_16X16, - 0x0011, // BLOCK_16X32, - 0x0001, // BLOCK_32X16, - 0x0011, // BLOCK_32X32, - 0x1111, // BLOCK_32X64 - 0x0011, // BLOCK_64X32, - 0x1111, // BLOCK_64X64 -}; -// 16 bit above mask to shift and set for uv each prediction size. -static const uint16_t above_prediction_mask_uv[BLOCK_SIZES] = { - 0x0001, // BLOCK_4X4 - 0x0001, // BLOCK_4X8 - 0x0001, // BLOCK_8X4 - 0x0001, // BLOCK_8X8 - 0x0001, // BLOCK_8X16, - 0x0001, // BLOCK_16X8 - 0x0001, // BLOCK_16X16 - 0x0001, // BLOCK_16X32, - 0x0003, // BLOCK_32X16, - 0x0003, // BLOCK_32X32, - 0x0003, // BLOCK_32X64, - 0x000f, // BLOCK_64X32, - 0x000f, // BLOCK_64X64 -}; - -// 64 bit mask to shift and set for each uv prediction size -static const uint16_t size_mask_uv[BLOCK_SIZES] = { - 0x0001, // BLOCK_4X4 - 0x0001, // BLOCK_4X8 - 0x0001, // BLOCK_8X4 - 0x0001, // BLOCK_8X8 - 0x0001, // BLOCK_8X16, - 0x0001, // BLOCK_16X8 - 0x0001, // BLOCK_16X16 - 0x0011, // BLOCK_16X32, - 0x0003, // BLOCK_32X16, - 0x0033, // BLOCK_32X32, - 0x3333, // BLOCK_32X64, - 0x00ff, // BLOCK_64X32, - 0xffff, // BLOCK_64X64 -}; -static const uint16_t left_border_uv = 0x1111; -static const uint16_t above_border_uv = 0x000f; - -static const int mode_lf_lut[MB_MODE_COUNT] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // INTRA_MODES - 1, 1, 0, 1 // INTER_MODES (ZEROMV == 0) -}; - -static void update_sharpness(loop_filter_info_n *lfi, int sharpness_lvl) { - int lvl; - - // For each possible value for the loop filter fill out limits - for (lvl = 0; lvl <= MAX_LOOP_FILTER; lvl++) { - // Set loop filter parameters that control sharpness. - int block_inside_limit = lvl >> ((sharpness_lvl > 0) + (sharpness_lvl > 4)); - - if (sharpness_lvl > 0) { - if (block_inside_limit > (9 - sharpness_lvl)) - block_inside_limit = (9 - sharpness_lvl); - } - - if (block_inside_limit < 1) block_inside_limit = 1; - - memset(lfi->lfthr[lvl].lim, block_inside_limit, SIMD_WIDTH); - memset(lfi->lfthr[lvl].mblim, (2 * (lvl + 2) + block_inside_limit), - SIMD_WIDTH); - } -} - -static uint8_t get_filter_level(const loop_filter_info_n *lfi_n, - const MODE_INFO *mi) { - return lfi_n->lvl[mi->segment_id][mi->ref_frame[0]][mode_lf_lut[mi->mode]]; -} - -void vp9_loop_filter_init(VP9_COMMON *cm) { - loop_filter_info_n *lfi = &cm->lf_info; - struct loopfilter *lf = &cm->lf; - int lvl; - - // init limits for given sharpness - update_sharpness(lfi, lf->sharpness_level); - lf->last_sharpness_level = lf->sharpness_level; - - // init hev threshold const vectors - for (lvl = 0; lvl <= MAX_LOOP_FILTER; lvl++) - memset(lfi->lfthr[lvl].hev_thr, (lvl >> 4), SIMD_WIDTH); -} - -void vp9_loop_filter_frame_init(VP9_COMMON *cm, int default_filt_lvl) { - int seg_id; - // n_shift is the multiplier for lf_deltas - // the multiplier is 1 for when filter_lvl is between 0 and 31; - // 2 when filter_lvl is between 32 and 63 - const int scale = 1 << (default_filt_lvl >> 5); - loop_filter_info_n *const lfi = &cm->lf_info; - struct loopfilter *const lf = &cm->lf; - const struct segmentation *const seg = &cm->seg; - - // update limits if sharpness has changed - if (lf->last_sharpness_level != lf->sharpness_level) { - update_sharpness(lfi, lf->sharpness_level); - lf->last_sharpness_level = lf->sharpness_level; - } - - for (seg_id = 0; seg_id < MAX_SEGMENTS; seg_id++) { - int lvl_seg = default_filt_lvl; - if (segfeature_active(seg, seg_id, SEG_LVL_ALT_LF)) { - const int data = get_segdata(seg, seg_id, SEG_LVL_ALT_LF); - lvl_seg = clamp( - seg->abs_delta == SEGMENT_ABSDATA ? data : default_filt_lvl + data, 0, - MAX_LOOP_FILTER); - } - - if (!lf->mode_ref_delta_enabled) { - // we could get rid of this if we assume that deltas are set to - // zero when not in use; encoder always uses deltas - memset(lfi->lvl[seg_id], lvl_seg, sizeof(lfi->lvl[seg_id])); - } else { - int ref, mode; - const int intra_lvl = lvl_seg + lf->ref_deltas[INTRA_FRAME] * scale; - lfi->lvl[seg_id][INTRA_FRAME][0] = clamp(intra_lvl, 0, MAX_LOOP_FILTER); - - for (ref = LAST_FRAME; ref < MAX_REF_FRAMES; ++ref) { - for (mode = 0; mode < MAX_MODE_LF_DELTAS; ++mode) { - const int inter_lvl = lvl_seg + lf->ref_deltas[ref] * scale + - lf->mode_deltas[mode] * scale; - lfi->lvl[seg_id][ref][mode] = clamp(inter_lvl, 0, MAX_LOOP_FILTER); - } - } - } - } -} - -static void filter_selectively_vert_row2( - int subsampling_factor, uint8_t *s, int pitch, unsigned int mask_16x16, - unsigned int mask_8x8, unsigned int mask_4x4, unsigned int mask_4x4_int, - const loop_filter_thresh *lfthr, const uint8_t *lfl) { - const int dual_mask_cutoff = subsampling_factor ? 0xff : 0xffff; - const int lfl_forward = subsampling_factor ? 4 : 8; - const unsigned int dual_one = 1 | (1 << lfl_forward); - unsigned int mask; - uint8_t *ss[2]; - ss[0] = s; - - for (mask = - (mask_16x16 | mask_8x8 | mask_4x4 | mask_4x4_int) & dual_mask_cutoff; - mask; mask = (mask & ~dual_one) >> 1) { - if (mask & dual_one) { - const loop_filter_thresh *lfis[2]; - lfis[0] = lfthr + *lfl; - lfis[1] = lfthr + *(lfl + lfl_forward); - ss[1] = ss[0] + 8 * pitch; - - if (mask_16x16 & dual_one) { - if ((mask_16x16 & dual_one) == dual_one) { - vpx_lpf_vertical_16_dual(ss[0], pitch, lfis[0]->mblim, lfis[0]->lim, - lfis[0]->hev_thr); - } else { - const loop_filter_thresh *lfi = lfis[!(mask_16x16 & 1)]; - vpx_lpf_vertical_16(ss[!(mask_16x16 & 1)], pitch, lfi->mblim, - lfi->lim, lfi->hev_thr); - } - } - - if (mask_8x8 & dual_one) { - if ((mask_8x8 & dual_one) == dual_one) { - vpx_lpf_vertical_8_dual(ss[0], pitch, lfis[0]->mblim, lfis[0]->lim, - lfis[0]->hev_thr, lfis[1]->mblim, - lfis[1]->lim, lfis[1]->hev_thr); - } else { - const loop_filter_thresh *lfi = lfis[!(mask_8x8 & 1)]; - vpx_lpf_vertical_8(ss[!(mask_8x8 & 1)], pitch, lfi->mblim, lfi->lim, - lfi->hev_thr); - } - } - - if (mask_4x4 & dual_one) { - if ((mask_4x4 & dual_one) == dual_one) { - vpx_lpf_vertical_4_dual(ss[0], pitch, lfis[0]->mblim, lfis[0]->lim, - lfis[0]->hev_thr, lfis[1]->mblim, - lfis[1]->lim, lfis[1]->hev_thr); - } else { - const loop_filter_thresh *lfi = lfis[!(mask_4x4 & 1)]; - vpx_lpf_vertical_4(ss[!(mask_4x4 & 1)], pitch, lfi->mblim, lfi->lim, - lfi->hev_thr); - } - } - - if (mask_4x4_int & dual_one) { - if ((mask_4x4_int & dual_one) == dual_one) { - vpx_lpf_vertical_4_dual( - ss[0] + 4, pitch, lfis[0]->mblim, lfis[0]->lim, lfis[0]->hev_thr, - lfis[1]->mblim, lfis[1]->lim, lfis[1]->hev_thr); - } else { - const loop_filter_thresh *lfi = lfis[!(mask_4x4_int & 1)]; - vpx_lpf_vertical_4(ss[!(mask_4x4_int & 1)] + 4, pitch, lfi->mblim, - lfi->lim, lfi->hev_thr); - } - } - } - - ss[0] += 8; - lfl += 1; - mask_16x16 >>= 1; - mask_8x8 >>= 1; - mask_4x4 >>= 1; - mask_4x4_int >>= 1; - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -static void highbd_filter_selectively_vert_row2( - int subsampling_factor, uint16_t *s, int pitch, unsigned int mask_16x16, - unsigned int mask_8x8, unsigned int mask_4x4, unsigned int mask_4x4_int, - const loop_filter_thresh *lfthr, const uint8_t *lfl, int bd) { - const int dual_mask_cutoff = subsampling_factor ? 0xff : 0xffff; - const int lfl_forward = subsampling_factor ? 4 : 8; - const unsigned int dual_one = 1 | (1 << lfl_forward); - unsigned int mask; - uint16_t *ss[2]; - ss[0] = s; - - for (mask = - (mask_16x16 | mask_8x8 | mask_4x4 | mask_4x4_int) & dual_mask_cutoff; - mask; mask = (mask & ~dual_one) >> 1) { - if (mask & dual_one) { - const loop_filter_thresh *lfis[2]; - lfis[0] = lfthr + *lfl; - lfis[1] = lfthr + *(lfl + lfl_forward); - ss[1] = ss[0] + 8 * pitch; - - if (mask_16x16 & dual_one) { - if ((mask_16x16 & dual_one) == dual_one) { - vpx_highbd_lpf_vertical_16_dual(ss[0], pitch, lfis[0]->mblim, - lfis[0]->lim, lfis[0]->hev_thr, bd); - } else { - const loop_filter_thresh *lfi = lfis[!(mask_16x16 & 1)]; - vpx_highbd_lpf_vertical_16(ss[!(mask_16x16 & 1)], pitch, lfi->mblim, - lfi->lim, lfi->hev_thr, bd); - } - } - - if (mask_8x8 & dual_one) { - if ((mask_8x8 & dual_one) == dual_one) { - vpx_highbd_lpf_vertical_8_dual( - ss[0], pitch, lfis[0]->mblim, lfis[0]->lim, lfis[0]->hev_thr, - lfis[1]->mblim, lfis[1]->lim, lfis[1]->hev_thr, bd); - } else { - const loop_filter_thresh *lfi = lfis[!(mask_8x8 & 1)]; - vpx_highbd_lpf_vertical_8(ss[!(mask_8x8 & 1)], pitch, lfi->mblim, - lfi->lim, lfi->hev_thr, bd); - } - } - - if (mask_4x4 & dual_one) { - if ((mask_4x4 & dual_one) == dual_one) { - vpx_highbd_lpf_vertical_4_dual( - ss[0], pitch, lfis[0]->mblim, lfis[0]->lim, lfis[0]->hev_thr, - lfis[1]->mblim, lfis[1]->lim, lfis[1]->hev_thr, bd); - } else { - const loop_filter_thresh *lfi = lfis[!(mask_4x4 & 1)]; - vpx_highbd_lpf_vertical_4(ss[!(mask_4x4 & 1)], pitch, lfi->mblim, - lfi->lim, lfi->hev_thr, bd); - } - } - - if (mask_4x4_int & dual_one) { - if ((mask_4x4_int & dual_one) == dual_one) { - vpx_highbd_lpf_vertical_4_dual( - ss[0] + 4, pitch, lfis[0]->mblim, lfis[0]->lim, lfis[0]->hev_thr, - lfis[1]->mblim, lfis[1]->lim, lfis[1]->hev_thr, bd); - } else { - const loop_filter_thresh *lfi = lfis[!(mask_4x4_int & 1)]; - vpx_highbd_lpf_vertical_4(ss[!(mask_4x4_int & 1)] + 4, pitch, - lfi->mblim, lfi->lim, lfi->hev_thr, bd); - } - } - } - - ss[0] += 8; - lfl += 1; - mask_16x16 >>= 1; - mask_8x8 >>= 1; - mask_4x4 >>= 1; - mask_4x4_int >>= 1; - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static void filter_selectively_horiz( - uint8_t *s, int pitch, unsigned int mask_16x16, unsigned int mask_8x8, - unsigned int mask_4x4, unsigned int mask_4x4_int, - const loop_filter_thresh *lfthr, const uint8_t *lfl) { - unsigned int mask; - int count; - - for (mask = mask_16x16 | mask_8x8 | mask_4x4 | mask_4x4_int; mask; - mask >>= count) { - count = 1; - if (mask & 1) { - const loop_filter_thresh *lfi = lfthr + *lfl; - - if (mask_16x16 & 1) { - if ((mask_16x16 & 3) == 3) { - vpx_lpf_horizontal_16_dual(s, pitch, lfi->mblim, lfi->lim, - lfi->hev_thr); - count = 2; - } else { - vpx_lpf_horizontal_16(s, pitch, lfi->mblim, lfi->lim, lfi->hev_thr); - } - } else if (mask_8x8 & 1) { - if ((mask_8x8 & 3) == 3) { - // Next block's thresholds. - const loop_filter_thresh *lfin = lfthr + *(lfl + 1); - - vpx_lpf_horizontal_8_dual(s, pitch, lfi->mblim, lfi->lim, - lfi->hev_thr, lfin->mblim, lfin->lim, - lfin->hev_thr); - - if ((mask_4x4_int & 3) == 3) { - vpx_lpf_horizontal_4_dual(s + 4 * pitch, pitch, lfi->mblim, - lfi->lim, lfi->hev_thr, lfin->mblim, - lfin->lim, lfin->hev_thr); - } else { - if (mask_4x4_int & 1) - vpx_lpf_horizontal_4(s + 4 * pitch, pitch, lfi->mblim, lfi->lim, - lfi->hev_thr); - else if (mask_4x4_int & 2) - vpx_lpf_horizontal_4(s + 8 + 4 * pitch, pitch, lfin->mblim, - lfin->lim, lfin->hev_thr); - } - count = 2; - } else { - vpx_lpf_horizontal_8(s, pitch, lfi->mblim, lfi->lim, lfi->hev_thr); - - if (mask_4x4_int & 1) - vpx_lpf_horizontal_4(s + 4 * pitch, pitch, lfi->mblim, lfi->lim, - lfi->hev_thr); - } - } else if (mask_4x4 & 1) { - if ((mask_4x4 & 3) == 3) { - // Next block's thresholds. - const loop_filter_thresh *lfin = lfthr + *(lfl + 1); - - vpx_lpf_horizontal_4_dual(s, pitch, lfi->mblim, lfi->lim, - lfi->hev_thr, lfin->mblim, lfin->lim, - lfin->hev_thr); - if ((mask_4x4_int & 3) == 3) { - vpx_lpf_horizontal_4_dual(s + 4 * pitch, pitch, lfi->mblim, - lfi->lim, lfi->hev_thr, lfin->mblim, - lfin->lim, lfin->hev_thr); - } else { - if (mask_4x4_int & 1) - vpx_lpf_horizontal_4(s + 4 * pitch, pitch, lfi->mblim, lfi->lim, - lfi->hev_thr); - else if (mask_4x4_int & 2) - vpx_lpf_horizontal_4(s + 8 + 4 * pitch, pitch, lfin->mblim, - lfin->lim, lfin->hev_thr); - } - count = 2; - } else { - vpx_lpf_horizontal_4(s, pitch, lfi->mblim, lfi->lim, lfi->hev_thr); - - if (mask_4x4_int & 1) - vpx_lpf_horizontal_4(s + 4 * pitch, pitch, lfi->mblim, lfi->lim, - lfi->hev_thr); - } - } else { - vpx_lpf_horizontal_4(s + 4 * pitch, pitch, lfi->mblim, lfi->lim, - lfi->hev_thr); - } - } - s += 8 * count; - lfl += count; - mask_16x16 >>= count; - mask_8x8 >>= count; - mask_4x4 >>= count; - mask_4x4_int >>= count; - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -static void highbd_filter_selectively_horiz( - uint16_t *s, int pitch, unsigned int mask_16x16, unsigned int mask_8x8, - unsigned int mask_4x4, unsigned int mask_4x4_int, - const loop_filter_thresh *lfthr, const uint8_t *lfl, int bd) { - unsigned int mask; - int count; - - for (mask = mask_16x16 | mask_8x8 | mask_4x4 | mask_4x4_int; mask; - mask >>= count) { - count = 1; - if (mask & 1) { - const loop_filter_thresh *lfi = lfthr + *lfl; - - if (mask_16x16 & 1) { - if ((mask_16x16 & 3) == 3) { - vpx_highbd_lpf_horizontal_16_dual(s, pitch, lfi->mblim, lfi->lim, - lfi->hev_thr, bd); - count = 2; - } else { - vpx_highbd_lpf_horizontal_16(s, pitch, lfi->mblim, lfi->lim, - lfi->hev_thr, bd); - } - } else if (mask_8x8 & 1) { - if ((mask_8x8 & 3) == 3) { - // Next block's thresholds. - const loop_filter_thresh *lfin = lfthr + *(lfl + 1); - - vpx_highbd_lpf_horizontal_8_dual(s, pitch, lfi->mblim, lfi->lim, - lfi->hev_thr, lfin->mblim, lfin->lim, - lfin->hev_thr, bd); - - if ((mask_4x4_int & 3) == 3) { - vpx_highbd_lpf_horizontal_4_dual( - s + 4 * pitch, pitch, lfi->mblim, lfi->lim, lfi->hev_thr, - lfin->mblim, lfin->lim, lfin->hev_thr, bd); - } else { - if (mask_4x4_int & 1) { - vpx_highbd_lpf_horizontal_4(s + 4 * pitch, pitch, lfi->mblim, - lfi->lim, lfi->hev_thr, bd); - } else if (mask_4x4_int & 2) { - vpx_highbd_lpf_horizontal_4(s + 8 + 4 * pitch, pitch, lfin->mblim, - lfin->lim, lfin->hev_thr, bd); - } - } - count = 2; - } else { - vpx_highbd_lpf_horizontal_8(s, pitch, lfi->mblim, lfi->lim, - lfi->hev_thr, bd); - - if (mask_4x4_int & 1) { - vpx_highbd_lpf_horizontal_4(s + 4 * pitch, pitch, lfi->mblim, - lfi->lim, lfi->hev_thr, bd); - } - } - } else if (mask_4x4 & 1) { - if ((mask_4x4 & 3) == 3) { - // Next block's thresholds. - const loop_filter_thresh *lfin = lfthr + *(lfl + 1); - - vpx_highbd_lpf_horizontal_4_dual(s, pitch, lfi->mblim, lfi->lim, - lfi->hev_thr, lfin->mblim, lfin->lim, - lfin->hev_thr, bd); - if ((mask_4x4_int & 3) == 3) { - vpx_highbd_lpf_horizontal_4_dual( - s + 4 * pitch, pitch, lfi->mblim, lfi->lim, lfi->hev_thr, - lfin->mblim, lfin->lim, lfin->hev_thr, bd); - } else { - if (mask_4x4_int & 1) { - vpx_highbd_lpf_horizontal_4(s + 4 * pitch, pitch, lfi->mblim, - lfi->lim, lfi->hev_thr, bd); - } else if (mask_4x4_int & 2) { - vpx_highbd_lpf_horizontal_4(s + 8 + 4 * pitch, pitch, lfin->mblim, - lfin->lim, lfin->hev_thr, bd); - } - } - count = 2; - } else { - vpx_highbd_lpf_horizontal_4(s, pitch, lfi->mblim, lfi->lim, - lfi->hev_thr, bd); - - if (mask_4x4_int & 1) { - vpx_highbd_lpf_horizontal_4(s + 4 * pitch, pitch, lfi->mblim, - lfi->lim, lfi->hev_thr, bd); - } - } - } else { - vpx_highbd_lpf_horizontal_4(s + 4 * pitch, pitch, lfi->mblim, lfi->lim, - lfi->hev_thr, bd); - } - } - s += 8 * count; - lfl += count; - mask_16x16 >>= count; - mask_8x8 >>= count; - mask_4x4 >>= count; - mask_4x4_int >>= count; - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -// This function ors into the current lfm structure, where to do loop -// filters for the specific mi we are looking at. It uses information -// including the block_size_type (32x16, 32x32, etc.), the transform size, -// whether there were any coefficients encoded, and the loop filter strength -// block we are currently looking at. Shift is used to position the -// 1's we produce. -static void build_masks(const loop_filter_info_n *const lfi_n, - const MODE_INFO *mi, const int shift_y, - const int shift_uv, LOOP_FILTER_MASK *lfm) { - const BLOCK_SIZE block_size = mi->sb_type; - const TX_SIZE tx_size_y = mi->tx_size; - const TX_SIZE tx_size_uv = uv_txsize_lookup[block_size][tx_size_y][1][1]; - const int filter_level = get_filter_level(lfi_n, mi); - uint64_t *const left_y = &lfm->left_y[tx_size_y]; - uint64_t *const above_y = &lfm->above_y[tx_size_y]; - uint64_t *const int_4x4_y = &lfm->int_4x4_y; - uint16_t *const left_uv = &lfm->left_uv[tx_size_uv]; - uint16_t *const above_uv = &lfm->above_uv[tx_size_uv]; - uint16_t *const int_4x4_uv = &lfm->int_4x4_uv; - int i; - - // If filter level is 0 we don't loop filter. - if (!filter_level) { - return; - } else { - const int w = num_8x8_blocks_wide_lookup[block_size]; - const int h = num_8x8_blocks_high_lookup[block_size]; - int index = shift_y; - for (i = 0; i < h; i++) { - memset(&lfm->lfl_y[index], filter_level, w); - index += 8; - } - } - - // These set 1 in the current block size for the block size edges. - // For instance if the block size is 32x16, we'll set: - // above = 1111 - // 0000 - // and - // left = 1000 - // = 1000 - // NOTE : In this example the low bit is left most ( 1000 ) is stored as - // 1, not 8... - // - // U and V set things on a 16 bit scale. - // - *above_y |= above_prediction_mask[block_size] << shift_y; - *above_uv |= above_prediction_mask_uv[block_size] << shift_uv; - *left_y |= left_prediction_mask[block_size] << shift_y; - *left_uv |= left_prediction_mask_uv[block_size] << shift_uv; - - // If the block has no coefficients and is not intra we skip applying - // the loop filter on block edges. - if (mi->skip && is_inter_block(mi)) return; - - // Here we are adding a mask for the transform size. The transform - // size mask is set to be correct for a 64x64 prediction block size. We - // mask to match the size of the block we are working on and then shift it - // into place.. - *above_y |= (size_mask[block_size] & above_64x64_txform_mask[tx_size_y]) - << shift_y; - *above_uv |= - (size_mask_uv[block_size] & above_64x64_txform_mask_uv[tx_size_uv]) - << shift_uv; - - *left_y |= (size_mask[block_size] & left_64x64_txform_mask[tx_size_y]) - << shift_y; - *left_uv |= (size_mask_uv[block_size] & left_64x64_txform_mask_uv[tx_size_uv]) - << shift_uv; - - // Here we are trying to determine what to do with the internal 4x4 block - // boundaries. These differ from the 4x4 boundaries on the outside edge of - // an 8x8 in that the internal ones can be skipped and don't depend on - // the prediction block size. - if (tx_size_y == TX_4X4) *int_4x4_y |= size_mask[block_size] << shift_y; - - if (tx_size_uv == TX_4X4) - *int_4x4_uv |= (size_mask_uv[block_size] & 0xffff) << shift_uv; -} - -// This function does the same thing as the one above with the exception that -// it only affects the y masks. It exists because for blocks < 16x16 in size, -// we only update u and v masks on the first block. -static void build_y_mask(const loop_filter_info_n *const lfi_n, - const MODE_INFO *mi, const int shift_y, - LOOP_FILTER_MASK *lfm) { - const BLOCK_SIZE block_size = mi->sb_type; - const TX_SIZE tx_size_y = mi->tx_size; - const int filter_level = get_filter_level(lfi_n, mi); - uint64_t *const left_y = &lfm->left_y[tx_size_y]; - uint64_t *const above_y = &lfm->above_y[tx_size_y]; - uint64_t *const int_4x4_y = &lfm->int_4x4_y; - int i; - - if (!filter_level) { - return; - } else { - const int w = num_8x8_blocks_wide_lookup[block_size]; - const int h = num_8x8_blocks_high_lookup[block_size]; - int index = shift_y; - for (i = 0; i < h; i++) { - memset(&lfm->lfl_y[index], filter_level, w); - index += 8; - } - } - - *above_y |= above_prediction_mask[block_size] << shift_y; - *left_y |= left_prediction_mask[block_size] << shift_y; - - if (mi->skip && is_inter_block(mi)) return; - - *above_y |= (size_mask[block_size] & above_64x64_txform_mask[tx_size_y]) - << shift_y; - - *left_y |= (size_mask[block_size] & left_64x64_txform_mask[tx_size_y]) - << shift_y; - - if (tx_size_y == TX_4X4) *int_4x4_y |= size_mask[block_size] << shift_y; -} - -void vp9_adjust_mask(VP9_COMMON *const cm, const int mi_row, const int mi_col, - LOOP_FILTER_MASK *lfm) { - int i; - - // The largest loopfilter we have is 16x16 so we use the 16x16 mask - // for 32x32 transforms also. - lfm->left_y[TX_16X16] |= lfm->left_y[TX_32X32]; - lfm->above_y[TX_16X16] |= lfm->above_y[TX_32X32]; - lfm->left_uv[TX_16X16] |= lfm->left_uv[TX_32X32]; - lfm->above_uv[TX_16X16] |= lfm->above_uv[TX_32X32]; - - // We do at least 8 tap filter on every 32x32 even if the transform size - // is 4x4. So if the 4x4 is set on a border pixel add it to the 8x8 and - // remove it from the 4x4. - lfm->left_y[TX_8X8] |= lfm->left_y[TX_4X4] & left_border; - lfm->left_y[TX_4X4] &= ~left_border; - lfm->above_y[TX_8X8] |= lfm->above_y[TX_4X4] & above_border; - lfm->above_y[TX_4X4] &= ~above_border; - lfm->left_uv[TX_8X8] |= lfm->left_uv[TX_4X4] & left_border_uv; - lfm->left_uv[TX_4X4] &= ~left_border_uv; - lfm->above_uv[TX_8X8] |= lfm->above_uv[TX_4X4] & above_border_uv; - lfm->above_uv[TX_4X4] &= ~above_border_uv; - - // We do some special edge handling. - if (mi_row + MI_BLOCK_SIZE > cm->mi_rows) { - const uint64_t rows = cm->mi_rows - mi_row; - - // Each pixel inside the border gets a 1, - const uint64_t mask_y = (((uint64_t)1 << (rows << 3)) - 1); - const uint16_t mask_uv = (((uint16_t)1 << (((rows + 1) >> 1) << 2)) - 1); - - // Remove values completely outside our border. - for (i = 0; i < TX_32X32; i++) { - lfm->left_y[i] &= mask_y; - lfm->above_y[i] &= mask_y; - lfm->left_uv[i] &= mask_uv; - lfm->above_uv[i] &= mask_uv; - } - lfm->int_4x4_y &= mask_y; - lfm->int_4x4_uv &= mask_uv; - - // We don't apply a wide loop filter on the last uv block row. If set - // apply the shorter one instead. - if (rows == 1) { - lfm->above_uv[TX_8X8] |= lfm->above_uv[TX_16X16]; - lfm->above_uv[TX_16X16] = 0; - } - if (rows == 5) { - lfm->above_uv[TX_8X8] |= lfm->above_uv[TX_16X16] & 0xff00; - lfm->above_uv[TX_16X16] &= ~(lfm->above_uv[TX_16X16] & 0xff00); - } - } - - if (mi_col + MI_BLOCK_SIZE > cm->mi_cols) { - const uint64_t columns = cm->mi_cols - mi_col; - - // Each pixel inside the border gets a 1, the multiply copies the border - // to where we need it. - const uint64_t mask_y = (((1 << columns) - 1)) * 0x0101010101010101ULL; - const uint16_t mask_uv = ((1 << ((columns + 1) >> 1)) - 1) * 0x1111; - - // Internal edges are not applied on the last column of the image so - // we mask 1 more for the internal edges - const uint16_t mask_uv_int = ((1 << (columns >> 1)) - 1) * 0x1111; - - // Remove the bits outside the image edge. - for (i = 0; i < TX_32X32; i++) { - lfm->left_y[i] &= mask_y; - lfm->above_y[i] &= mask_y; - lfm->left_uv[i] &= mask_uv; - lfm->above_uv[i] &= mask_uv; - } - lfm->int_4x4_y &= mask_y; - lfm->int_4x4_uv &= mask_uv_int; - - // We don't apply a wide loop filter on the last uv column. If set - // apply the shorter one instead. - if (columns == 1) { - lfm->left_uv[TX_8X8] |= lfm->left_uv[TX_16X16]; - lfm->left_uv[TX_16X16] = 0; - } - if (columns == 5) { - lfm->left_uv[TX_8X8] |= (lfm->left_uv[TX_16X16] & 0xcccc); - lfm->left_uv[TX_16X16] &= ~(lfm->left_uv[TX_16X16] & 0xcccc); - } - } - // We don't apply a loop filter on the first column in the image, mask that - // out. - if (mi_col == 0) { - for (i = 0; i < TX_32X32; i++) { - lfm->left_y[i] &= 0xfefefefefefefefeULL; - lfm->left_uv[i] &= 0xeeee; - } - } - - // Assert if we try to apply 2 different loop filters at the same position. - assert(!(lfm->left_y[TX_16X16] & lfm->left_y[TX_8X8])); - assert(!(lfm->left_y[TX_16X16] & lfm->left_y[TX_4X4])); - assert(!(lfm->left_y[TX_8X8] & lfm->left_y[TX_4X4])); - assert(!(lfm->int_4x4_y & lfm->left_y[TX_16X16])); - assert(!(lfm->left_uv[TX_16X16] & lfm->left_uv[TX_8X8])); - assert(!(lfm->left_uv[TX_16X16] & lfm->left_uv[TX_4X4])); - assert(!(lfm->left_uv[TX_8X8] & lfm->left_uv[TX_4X4])); - assert(!(lfm->int_4x4_uv & lfm->left_uv[TX_16X16])); - assert(!(lfm->above_y[TX_16X16] & lfm->above_y[TX_8X8])); - assert(!(lfm->above_y[TX_16X16] & lfm->above_y[TX_4X4])); - assert(!(lfm->above_y[TX_8X8] & lfm->above_y[TX_4X4])); - assert(!(lfm->int_4x4_y & lfm->above_y[TX_16X16])); - assert(!(lfm->above_uv[TX_16X16] & lfm->above_uv[TX_8X8])); - assert(!(lfm->above_uv[TX_16X16] & lfm->above_uv[TX_4X4])); - assert(!(lfm->above_uv[TX_8X8] & lfm->above_uv[TX_4X4])); - assert(!(lfm->int_4x4_uv & lfm->above_uv[TX_16X16])); -} - -// This function sets up the bit masks for the entire 64x64 region represented -// by mi_row, mi_col. -void vp9_setup_mask(VP9_COMMON *const cm, const int mi_row, const int mi_col, - MODE_INFO **mi8x8, const int mode_info_stride, - LOOP_FILTER_MASK *lfm) { - int idx_32, idx_16, idx_8; - const loop_filter_info_n *const lfi_n = &cm->lf_info; - MODE_INFO **mip = mi8x8; - MODE_INFO **mip2 = mi8x8; - - // These are offsets to the next mi in the 64x64 block. It is what gets - // added to the mi ptr as we go through each loop. It helps us to avoid - // setting up special row and column counters for each index. The last step - // brings us out back to the starting position. - const int offset_32[] = { 4, (mode_info_stride << 2) - 4, 4, - -(mode_info_stride << 2) - 4 }; - const int offset_16[] = { 2, (mode_info_stride << 1) - 2, 2, - -(mode_info_stride << 1) - 2 }; - const int offset[] = { 1, mode_info_stride - 1, 1, -mode_info_stride - 1 }; - - // Following variables represent shifts to position the current block - // mask over the appropriate block. A shift of 36 to the left will move - // the bits for the final 32 by 32 block in the 64x64 up 4 rows and left - // 4 rows to the appropriate spot. - const int shift_32_y[] = { 0, 4, 32, 36 }; - const int shift_16_y[] = { 0, 2, 16, 18 }; - const int shift_8_y[] = { 0, 1, 8, 9 }; - const int shift_32_uv[] = { 0, 2, 8, 10 }; - const int shift_16_uv[] = { 0, 1, 4, 5 }; - const int max_rows = - (mi_row + MI_BLOCK_SIZE > cm->mi_rows ? cm->mi_rows - mi_row - : MI_BLOCK_SIZE); - const int max_cols = - (mi_col + MI_BLOCK_SIZE > cm->mi_cols ? cm->mi_cols - mi_col - : MI_BLOCK_SIZE); - - vp9_zero(*lfm); - assert(mip[0] != NULL); - - switch (mip[0]->sb_type) { - case BLOCK_64X64: build_masks(lfi_n, mip[0], 0, 0, lfm); break; - case BLOCK_64X32: - build_masks(lfi_n, mip[0], 0, 0, lfm); - mip2 = mip + mode_info_stride * 4; - if (4 >= max_rows) break; - build_masks(lfi_n, mip2[0], 32, 8, lfm); - break; - case BLOCK_32X64: - build_masks(lfi_n, mip[0], 0, 0, lfm); - mip2 = mip + 4; - if (4 >= max_cols) break; - build_masks(lfi_n, mip2[0], 4, 2, lfm); - break; - default: - for (idx_32 = 0; idx_32 < 4; mip += offset_32[idx_32], ++idx_32) { - const int shift_y_32 = shift_32_y[idx_32]; - const int shift_uv_32 = shift_32_uv[idx_32]; - const int mi_32_col_offset = ((idx_32 & 1) << 2); - const int mi_32_row_offset = ((idx_32 >> 1) << 2); - if (mi_32_col_offset >= max_cols || mi_32_row_offset >= max_rows) - continue; - switch (mip[0]->sb_type) { - case BLOCK_32X32: - build_masks(lfi_n, mip[0], shift_y_32, shift_uv_32, lfm); - break; - case BLOCK_32X16: - build_masks(lfi_n, mip[0], shift_y_32, shift_uv_32, lfm); - if (mi_32_row_offset + 2 >= max_rows) continue; - mip2 = mip + mode_info_stride * 2; - build_masks(lfi_n, mip2[0], shift_y_32 + 16, shift_uv_32 + 4, lfm); - break; - case BLOCK_16X32: - build_masks(lfi_n, mip[0], shift_y_32, shift_uv_32, lfm); - if (mi_32_col_offset + 2 >= max_cols) continue; - mip2 = mip + 2; - build_masks(lfi_n, mip2[0], shift_y_32 + 2, shift_uv_32 + 1, lfm); - break; - default: - for (idx_16 = 0; idx_16 < 4; mip += offset_16[idx_16], ++idx_16) { - const int shift_y_16 = shift_y_32 + shift_16_y[idx_16]; - const int shift_uv_16 = shift_uv_32 + shift_16_uv[idx_16]; - const int mi_16_col_offset = - mi_32_col_offset + ((idx_16 & 1) << 1); - const int mi_16_row_offset = - mi_32_row_offset + ((idx_16 >> 1) << 1); - - if (mi_16_col_offset >= max_cols || mi_16_row_offset >= max_rows) - continue; - - switch (mip[0]->sb_type) { - case BLOCK_16X16: - build_masks(lfi_n, mip[0], shift_y_16, shift_uv_16, lfm); - break; - case BLOCK_16X8: - build_masks(lfi_n, mip[0], shift_y_16, shift_uv_16, lfm); - if (mi_16_row_offset + 1 >= max_rows) continue; - mip2 = mip + mode_info_stride; - build_y_mask(lfi_n, mip2[0], shift_y_16 + 8, lfm); - break; - case BLOCK_8X16: - build_masks(lfi_n, mip[0], shift_y_16, shift_uv_16, lfm); - if (mi_16_col_offset + 1 >= max_cols) continue; - mip2 = mip + 1; - build_y_mask(lfi_n, mip2[0], shift_y_16 + 1, lfm); - break; - default: { - const int shift_y_8_0 = shift_y_16 + shift_8_y[0]; - build_masks(lfi_n, mip[0], shift_y_8_0, shift_uv_16, lfm); - mip += offset[0]; - for (idx_8 = 1; idx_8 < 4; mip += offset[idx_8], ++idx_8) { - const int shift_y_8 = shift_y_16 + shift_8_y[idx_8]; - const int mi_8_col_offset = - mi_16_col_offset + ((idx_8 & 1)); - const int mi_8_row_offset = - mi_16_row_offset + ((idx_8 >> 1)); - - if (mi_8_col_offset >= max_cols || - mi_8_row_offset >= max_rows) - continue; - build_y_mask(lfi_n, mip[0], shift_y_8, lfm); - } - break; - } - } - } - break; - } - } - break; - } -} - -static void filter_selectively_vert( - uint8_t *s, int pitch, unsigned int mask_16x16, unsigned int mask_8x8, - unsigned int mask_4x4, unsigned int mask_4x4_int, - const loop_filter_thresh *lfthr, const uint8_t *lfl) { - unsigned int mask; - - for (mask = mask_16x16 | mask_8x8 | mask_4x4 | mask_4x4_int; mask; - mask >>= 1) { - const loop_filter_thresh *lfi = lfthr + *lfl; - - if (mask & 1) { - if (mask_16x16 & 1) { - vpx_lpf_vertical_16(s, pitch, lfi->mblim, lfi->lim, lfi->hev_thr); - } else if (mask_8x8 & 1) { - vpx_lpf_vertical_8(s, pitch, lfi->mblim, lfi->lim, lfi->hev_thr); - } else if (mask_4x4 & 1) { - vpx_lpf_vertical_4(s, pitch, lfi->mblim, lfi->lim, lfi->hev_thr); - } - } - if (mask_4x4_int & 1) - vpx_lpf_vertical_4(s + 4, pitch, lfi->mblim, lfi->lim, lfi->hev_thr); - s += 8; - lfl += 1; - mask_16x16 >>= 1; - mask_8x8 >>= 1; - mask_4x4 >>= 1; - mask_4x4_int >>= 1; - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -static void highbd_filter_selectively_vert( - uint16_t *s, int pitch, unsigned int mask_16x16, unsigned int mask_8x8, - unsigned int mask_4x4, unsigned int mask_4x4_int, - const loop_filter_thresh *lfthr, const uint8_t *lfl, int bd) { - unsigned int mask; - - for (mask = mask_16x16 | mask_8x8 | mask_4x4 | mask_4x4_int; mask; - mask >>= 1) { - const loop_filter_thresh *lfi = lfthr + *lfl; - - if (mask & 1) { - if (mask_16x16 & 1) { - vpx_highbd_lpf_vertical_16(s, pitch, lfi->mblim, lfi->lim, lfi->hev_thr, - bd); - } else if (mask_8x8 & 1) { - vpx_highbd_lpf_vertical_8(s, pitch, lfi->mblim, lfi->lim, lfi->hev_thr, - bd); - } else if (mask_4x4 & 1) { - vpx_highbd_lpf_vertical_4(s, pitch, lfi->mblim, lfi->lim, lfi->hev_thr, - bd); - } - } - if (mask_4x4_int & 1) - vpx_highbd_lpf_vertical_4(s + 4, pitch, lfi->mblim, lfi->lim, - lfi->hev_thr, bd); - s += 8; - lfl += 1; - mask_16x16 >>= 1; - mask_8x8 >>= 1; - mask_4x4 >>= 1; - mask_4x4_int >>= 1; - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -void vp9_filter_block_plane_non420(VP9_COMMON *cm, - struct macroblockd_plane *plane, - MODE_INFO **mi_8x8, int mi_row, int mi_col) { - const int ss_x = plane->subsampling_x; - const int ss_y = plane->subsampling_y; - const int row_step = 1 << ss_y; - const int col_step = 1 << ss_x; - const int row_step_stride = cm->mi_stride * row_step; - struct buf_2d *const dst = &plane->dst; - uint8_t *const dst0 = dst->buf; - unsigned int mask_16x16[MI_BLOCK_SIZE]; - unsigned int mask_8x8[MI_BLOCK_SIZE]; - unsigned int mask_4x4[MI_BLOCK_SIZE]; - unsigned int mask_4x4_int[MI_BLOCK_SIZE]; - uint8_t lfl[MI_BLOCK_SIZE * MI_BLOCK_SIZE]; - int r, c; - - vp9_zero(mask_16x16); - vp9_zero(mask_8x8); - vp9_zero(mask_4x4); - vp9_zero(mask_4x4_int); - vp9_zero(lfl); - - for (r = 0; r < MI_BLOCK_SIZE && mi_row + r < cm->mi_rows; r += row_step) { - unsigned int mask_16x16_c = 0; - unsigned int mask_8x8_c = 0; - unsigned int mask_4x4_c = 0; - unsigned int border_mask; - - // Determine the vertical edges that need filtering - for (c = 0; c < MI_BLOCK_SIZE && mi_col + c < cm->mi_cols; c += col_step) { - const MODE_INFO *mi = mi_8x8[c]; - const BLOCK_SIZE sb_type = mi[0].sb_type; - const int skip_this = mi[0].skip && is_inter_block(mi); - // left edge of current unit is block/partition edge -> no skip - const int block_edge_left = - (num_4x4_blocks_wide_lookup[sb_type] > 1) - ? !(c & (num_8x8_blocks_wide_lookup[sb_type] - 1)) - : 1; - const int skip_this_c = skip_this && !block_edge_left; - // top edge of current unit is block/partition edge -> no skip - const int block_edge_above = - (num_4x4_blocks_high_lookup[sb_type] > 1) - ? !(r & (num_8x8_blocks_high_lookup[sb_type] - 1)) - : 1; - const int skip_this_r = skip_this && !block_edge_above; - const TX_SIZE tx_size = get_uv_tx_size(mi, plane); - const int skip_border_4x4_c = ss_x && mi_col + c == cm->mi_cols - 1; - const int skip_border_4x4_r = ss_y && mi_row + r == cm->mi_rows - 1; - - // Filter level can vary per MI - if (!(lfl[(r << 3) + (c >> ss_x)] = get_filter_level(&cm->lf_info, mi))) - continue; - - // Build masks based on the transform size of each block - if (tx_size == TX_32X32) { - if (!skip_this_c && ((c >> ss_x) & 3) == 0) { - if (!skip_border_4x4_c) - mask_16x16_c |= 1 << (c >> ss_x); - else - mask_8x8_c |= 1 << (c >> ss_x); - } - if (!skip_this_r && ((r >> ss_y) & 3) == 0) { - if (!skip_border_4x4_r) - mask_16x16[r] |= 1 << (c >> ss_x); - else - mask_8x8[r] |= 1 << (c >> ss_x); - } - } else if (tx_size == TX_16X16) { - if (!skip_this_c && ((c >> ss_x) & 1) == 0) { - if (!skip_border_4x4_c) - mask_16x16_c |= 1 << (c >> ss_x); - else - mask_8x8_c |= 1 << (c >> ss_x); - } - if (!skip_this_r && ((r >> ss_y) & 1) == 0) { - if (!skip_border_4x4_r) - mask_16x16[r] |= 1 << (c >> ss_x); - else - mask_8x8[r] |= 1 << (c >> ss_x); - } - } else { - // force 8x8 filtering on 32x32 boundaries - if (!skip_this_c) { - if (tx_size == TX_8X8 || ((c >> ss_x) & 3) == 0) - mask_8x8_c |= 1 << (c >> ss_x); - else - mask_4x4_c |= 1 << (c >> ss_x); - } - - if (!skip_this_r) { - if (tx_size == TX_8X8 || ((r >> ss_y) & 3) == 0) - mask_8x8[r] |= 1 << (c >> ss_x); - else - mask_4x4[r] |= 1 << (c >> ss_x); - } - - if (!skip_this && tx_size < TX_8X8 && !skip_border_4x4_c) - mask_4x4_int[r] |= 1 << (c >> ss_x); - } - } - - // Disable filtering on the leftmost column - border_mask = ~(mi_col == 0 ? 1u : 0u); -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - highbd_filter_selectively_vert( - CONVERT_TO_SHORTPTR(dst->buf), dst->stride, - mask_16x16_c & border_mask, mask_8x8_c & border_mask, - mask_4x4_c & border_mask, mask_4x4_int[r], cm->lf_info.lfthr, - &lfl[r << 3], (int)cm->bit_depth); - } else { -#endif // CONFIG_VP9_HIGHBITDEPTH - filter_selectively_vert(dst->buf, dst->stride, mask_16x16_c & border_mask, - mask_8x8_c & border_mask, - mask_4x4_c & border_mask, mask_4x4_int[r], - cm->lf_info.lfthr, &lfl[r << 3]); -#if CONFIG_VP9_HIGHBITDEPTH - } -#endif // CONFIG_VP9_HIGHBITDEPTH - dst->buf += 8 * dst->stride; - mi_8x8 += row_step_stride; - } - - // Now do horizontal pass - dst->buf = dst0; - for (r = 0; r < MI_BLOCK_SIZE && mi_row + r < cm->mi_rows; r += row_step) { - const int skip_border_4x4_r = ss_y && mi_row + r == cm->mi_rows - 1; - const unsigned int mask_4x4_int_r = skip_border_4x4_r ? 0 : mask_4x4_int[r]; - - unsigned int mask_16x16_r; - unsigned int mask_8x8_r; - unsigned int mask_4x4_r; - - if (mi_row + r == 0) { - mask_16x16_r = 0; - mask_8x8_r = 0; - mask_4x4_r = 0; - } else { - mask_16x16_r = mask_16x16[r]; - mask_8x8_r = mask_8x8[r]; - mask_4x4_r = mask_4x4[r]; - } -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - highbd_filter_selectively_horiz( - CONVERT_TO_SHORTPTR(dst->buf), dst->stride, mask_16x16_r, mask_8x8_r, - mask_4x4_r, mask_4x4_int_r, cm->lf_info.lfthr, &lfl[r << 3], - (int)cm->bit_depth); - } else { -#endif // CONFIG_VP9_HIGHBITDEPTH - filter_selectively_horiz(dst->buf, dst->stride, mask_16x16_r, mask_8x8_r, - mask_4x4_r, mask_4x4_int_r, cm->lf_info.lfthr, - &lfl[r << 3]); -#if CONFIG_VP9_HIGHBITDEPTH - } -#endif // CONFIG_VP9_HIGHBITDEPTH - dst->buf += 8 * dst->stride; - } -} - -void vp9_filter_block_plane_ss00(VP9_COMMON *const cm, - struct macroblockd_plane *const plane, - int mi_row, LOOP_FILTER_MASK *lfm) { - struct buf_2d *const dst = &plane->dst; - uint8_t *const dst0 = dst->buf; - int r; - uint64_t mask_16x16 = lfm->left_y[TX_16X16]; - uint64_t mask_8x8 = lfm->left_y[TX_8X8]; - uint64_t mask_4x4 = lfm->left_y[TX_4X4]; - uint64_t mask_4x4_int = lfm->int_4x4_y; - - assert(plane->subsampling_x == 0 && plane->subsampling_y == 0); - - // Vertical pass: do 2 rows at one time - for (r = 0; r < MI_BLOCK_SIZE && mi_row + r < cm->mi_rows; r += 2) { -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - // Disable filtering on the leftmost column. - highbd_filter_selectively_vert_row2( - plane->subsampling_x, CONVERT_TO_SHORTPTR(dst->buf), dst->stride, - (unsigned int)mask_16x16, (unsigned int)mask_8x8, - (unsigned int)mask_4x4, (unsigned int)mask_4x4_int, cm->lf_info.lfthr, - &lfm->lfl_y[r << 3], (int)cm->bit_depth); - } else { -#endif // CONFIG_VP9_HIGHBITDEPTH - // Disable filtering on the leftmost column. - filter_selectively_vert_row2( - plane->subsampling_x, dst->buf, dst->stride, (unsigned int)mask_16x16, - (unsigned int)mask_8x8, (unsigned int)mask_4x4, - (unsigned int)mask_4x4_int, cm->lf_info.lfthr, &lfm->lfl_y[r << 3]); -#if CONFIG_VP9_HIGHBITDEPTH - } -#endif // CONFIG_VP9_HIGHBITDEPTH - dst->buf += 16 * dst->stride; - mask_16x16 >>= 16; - mask_8x8 >>= 16; - mask_4x4 >>= 16; - mask_4x4_int >>= 16; - } - - // Horizontal pass - dst->buf = dst0; - mask_16x16 = lfm->above_y[TX_16X16]; - mask_8x8 = lfm->above_y[TX_8X8]; - mask_4x4 = lfm->above_y[TX_4X4]; - mask_4x4_int = lfm->int_4x4_y; - - for (r = 0; r < MI_BLOCK_SIZE && mi_row + r < cm->mi_rows; r++) { - unsigned int mask_16x16_r; - unsigned int mask_8x8_r; - unsigned int mask_4x4_r; - - if (mi_row + r == 0) { - mask_16x16_r = 0; - mask_8x8_r = 0; - mask_4x4_r = 0; - } else { - mask_16x16_r = mask_16x16 & 0xff; - mask_8x8_r = mask_8x8 & 0xff; - mask_4x4_r = mask_4x4 & 0xff; - } - -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - highbd_filter_selectively_horiz( - CONVERT_TO_SHORTPTR(dst->buf), dst->stride, mask_16x16_r, mask_8x8_r, - mask_4x4_r, mask_4x4_int & 0xff, cm->lf_info.lfthr, - &lfm->lfl_y[r << 3], (int)cm->bit_depth); - } else { -#endif // CONFIG_VP9_HIGHBITDEPTH - filter_selectively_horiz(dst->buf, dst->stride, mask_16x16_r, mask_8x8_r, - mask_4x4_r, mask_4x4_int & 0xff, - cm->lf_info.lfthr, &lfm->lfl_y[r << 3]); -#if CONFIG_VP9_HIGHBITDEPTH - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - dst->buf += 8 * dst->stride; - mask_16x16 >>= 8; - mask_8x8 >>= 8; - mask_4x4 >>= 8; - mask_4x4_int >>= 8; - } -} - -void vp9_filter_block_plane_ss11(VP9_COMMON *const cm, - struct macroblockd_plane *const plane, - int mi_row, LOOP_FILTER_MASK *lfm) { - struct buf_2d *const dst = &plane->dst; - uint8_t *const dst0 = dst->buf; - int r, c; - uint8_t lfl_uv[16]; - - uint16_t mask_16x16 = lfm->left_uv[TX_16X16]; - uint16_t mask_8x8 = lfm->left_uv[TX_8X8]; - uint16_t mask_4x4 = lfm->left_uv[TX_4X4]; - uint16_t mask_4x4_int = lfm->int_4x4_uv; - - vp9_zero(lfl_uv); - - assert(plane->subsampling_x == 1 && plane->subsampling_y == 1); - - // Vertical pass: do 2 rows at one time - for (r = 0; r < MI_BLOCK_SIZE && mi_row + r < cm->mi_rows; r += 4) { - for (c = 0; c < (MI_BLOCK_SIZE >> 1); c++) { - lfl_uv[(r << 1) + c] = lfm->lfl_y[(r << 3) + (c << 1)]; - lfl_uv[((r + 2) << 1) + c] = lfm->lfl_y[((r + 2) << 3) + (c << 1)]; - } - -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - // Disable filtering on the leftmost column. - highbd_filter_selectively_vert_row2( - plane->subsampling_x, CONVERT_TO_SHORTPTR(dst->buf), dst->stride, - (unsigned int)mask_16x16, (unsigned int)mask_8x8, - (unsigned int)mask_4x4, (unsigned int)mask_4x4_int, cm->lf_info.lfthr, - &lfl_uv[r << 1], (int)cm->bit_depth); - } else { -#endif // CONFIG_VP9_HIGHBITDEPTH - // Disable filtering on the leftmost column. - filter_selectively_vert_row2( - plane->subsampling_x, dst->buf, dst->stride, (unsigned int)mask_16x16, - (unsigned int)mask_8x8, (unsigned int)mask_4x4, - (unsigned int)mask_4x4_int, cm->lf_info.lfthr, &lfl_uv[r << 1]); -#if CONFIG_VP9_HIGHBITDEPTH - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - dst->buf += 16 * dst->stride; - mask_16x16 >>= 8; - mask_8x8 >>= 8; - mask_4x4 >>= 8; - mask_4x4_int >>= 8; - } - - // Horizontal pass - dst->buf = dst0; - mask_16x16 = lfm->above_uv[TX_16X16]; - mask_8x8 = lfm->above_uv[TX_8X8]; - mask_4x4 = lfm->above_uv[TX_4X4]; - mask_4x4_int = lfm->int_4x4_uv; - - for (r = 0; r < MI_BLOCK_SIZE && mi_row + r < cm->mi_rows; r += 2) { - const int skip_border_4x4_r = mi_row + r == cm->mi_rows - 1; - const unsigned int mask_4x4_int_r = - skip_border_4x4_r ? 0 : (mask_4x4_int & 0xf); - unsigned int mask_16x16_r; - unsigned int mask_8x8_r; - unsigned int mask_4x4_r; - - if (mi_row + r == 0) { - mask_16x16_r = 0; - mask_8x8_r = 0; - mask_4x4_r = 0; - } else { - mask_16x16_r = mask_16x16 & 0xf; - mask_8x8_r = mask_8x8 & 0xf; - mask_4x4_r = mask_4x4 & 0xf; - } - -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - highbd_filter_selectively_horiz( - CONVERT_TO_SHORTPTR(dst->buf), dst->stride, mask_16x16_r, mask_8x8_r, - mask_4x4_r, mask_4x4_int_r, cm->lf_info.lfthr, &lfl_uv[r << 1], - (int)cm->bit_depth); - } else { -#endif // CONFIG_VP9_HIGHBITDEPTH - filter_selectively_horiz(dst->buf, dst->stride, mask_16x16_r, mask_8x8_r, - mask_4x4_r, mask_4x4_int_r, cm->lf_info.lfthr, - &lfl_uv[r << 1]); -#if CONFIG_VP9_HIGHBITDEPTH - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - dst->buf += 8 * dst->stride; - mask_16x16 >>= 4; - mask_8x8 >>= 4; - mask_4x4 >>= 4; - mask_4x4_int >>= 4; - } -} - -static void loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, VP9_COMMON *cm, - struct macroblockd_plane planes[MAX_MB_PLANE], - int start, int stop, int y_only) { - const int num_planes = y_only ? 1 : MAX_MB_PLANE; - enum lf_path path; - int mi_row, mi_col; - - if (y_only) - path = LF_PATH_444; - else if (planes[1].subsampling_y == 1 && planes[1].subsampling_x == 1) - path = LF_PATH_420; - else if (planes[1].subsampling_y == 0 && planes[1].subsampling_x == 0) - path = LF_PATH_444; - else - path = LF_PATH_SLOW; - - for (mi_row = start; mi_row < stop; mi_row += MI_BLOCK_SIZE) { - MODE_INFO **mi = cm->mi_grid_visible + mi_row * cm->mi_stride; - LOOP_FILTER_MASK *lfm = get_lfm(&cm->lf, mi_row, 0); - - for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MI_BLOCK_SIZE, ++lfm) { - int plane; - - vp9_setup_dst_planes(planes, frame_buffer, mi_row, mi_col); - - // TODO(jimbankoski): For 444 only need to do y mask. - vp9_adjust_mask(cm, mi_row, mi_col, lfm); - - vp9_filter_block_plane_ss00(cm, &planes[0], mi_row, lfm); - for (plane = 1; plane < num_planes; ++plane) { - switch (path) { - case LF_PATH_420: - vp9_filter_block_plane_ss11(cm, &planes[plane], mi_row, lfm); - break; - case LF_PATH_444: - vp9_filter_block_plane_ss00(cm, &planes[plane], mi_row, lfm); - break; - case LF_PATH_SLOW: - vp9_filter_block_plane_non420(cm, &planes[plane], mi + mi_col, - mi_row, mi_col); - break; - } - } - } - } -} - -void vp9_loop_filter_frame(YV12_BUFFER_CONFIG *frame, VP9_COMMON *cm, - MACROBLOCKD *xd, int frame_filter_level, int y_only, - int partial_frame) { - int start_mi_row, end_mi_row, mi_rows_to_filter; - if (!frame_filter_level) return; - start_mi_row = 0; - mi_rows_to_filter = cm->mi_rows; - if (partial_frame && cm->mi_rows > 8) { - start_mi_row = cm->mi_rows >> 1; - start_mi_row &= 0xfffffff8; - mi_rows_to_filter = VPXMAX(cm->mi_rows / 8, 8); - } - end_mi_row = start_mi_row + mi_rows_to_filter; - loop_filter_rows(frame, cm, xd->plane, start_mi_row, end_mi_row, y_only); -} - -// Used by the encoder to build the loopfilter masks. -// TODO(slavarnway): Do the encoder the same way the decoder does it and -// build the masks in line as part of the encode process. -void vp9_build_mask_frame(VP9_COMMON *cm, int frame_filter_level, - int partial_frame) { - int start_mi_row, end_mi_row, mi_rows_to_filter; - int mi_col, mi_row; - if (!frame_filter_level) return; - start_mi_row = 0; - mi_rows_to_filter = cm->mi_rows; - if (partial_frame && cm->mi_rows > 8) { - start_mi_row = cm->mi_rows >> 1; - start_mi_row &= 0xfffffff8; - mi_rows_to_filter = VPXMAX(cm->mi_rows / 8, 8); - } - end_mi_row = start_mi_row + mi_rows_to_filter; - - vp9_loop_filter_frame_init(cm, frame_filter_level); - - for (mi_row = start_mi_row; mi_row < end_mi_row; mi_row += MI_BLOCK_SIZE) { - MODE_INFO **mi = cm->mi_grid_visible + mi_row * cm->mi_stride; - for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MI_BLOCK_SIZE) { - // vp9_setup_mask() zeros lfm - vp9_setup_mask(cm, mi_row, mi_col, mi + mi_col, cm->mi_stride, - get_lfm(&cm->lf, mi_row, mi_col)); - } - } -} - -// 8x8 blocks in a superblock. A "1" represents the first block in a 16x16 -// or greater area. -static const uint8_t first_block_in_16x16[8][8] = { - { 1, 0, 1, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 1, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 1, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 1, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 } -}; - -// This function sets up the bit masks for a block represented -// by mi_row, mi_col in a 64x64 region. -// TODO(SJL): This function only works for yv12. -void vp9_build_mask(VP9_COMMON *cm, const MODE_INFO *mi, int mi_row, int mi_col, - int bw, int bh) { - const BLOCK_SIZE block_size = mi->sb_type; - const TX_SIZE tx_size_y = mi->tx_size; - const loop_filter_info_n *const lfi_n = &cm->lf_info; - const int filter_level = get_filter_level(lfi_n, mi); - const TX_SIZE tx_size_uv = uv_txsize_lookup[block_size][tx_size_y][1][1]; - LOOP_FILTER_MASK *const lfm = get_lfm(&cm->lf, mi_row, mi_col); - uint64_t *const left_y = &lfm->left_y[tx_size_y]; - uint64_t *const above_y = &lfm->above_y[tx_size_y]; - uint64_t *const int_4x4_y = &lfm->int_4x4_y; - uint16_t *const left_uv = &lfm->left_uv[tx_size_uv]; - uint16_t *const above_uv = &lfm->above_uv[tx_size_uv]; - uint16_t *const int_4x4_uv = &lfm->int_4x4_uv; - const int row_in_sb = (mi_row & 7); - const int col_in_sb = (mi_col & 7); - const int shift_y = col_in_sb + (row_in_sb << 3); - const int shift_uv = (col_in_sb >> 1) + ((row_in_sb >> 1) << 2); - const int build_uv = first_block_in_16x16[row_in_sb][col_in_sb]; - - if (!filter_level) { - return; - } else { - int index = shift_y; - int i; - for (i = 0; i < bh; i++) { - memset(&lfm->lfl_y[index], filter_level, bw); - index += 8; - } - } - - // These set 1 in the current block size for the block size edges. - // For instance if the block size is 32x16, we'll set: - // above = 1111 - // 0000 - // and - // left = 1000 - // = 1000 - // NOTE : In this example the low bit is left most ( 1000 ) is stored as - // 1, not 8... - // - // U and V set things on a 16 bit scale. - // - *above_y |= above_prediction_mask[block_size] << shift_y; - *left_y |= left_prediction_mask[block_size] << shift_y; - - if (build_uv) { - *above_uv |= above_prediction_mask_uv[block_size] << shift_uv; - *left_uv |= left_prediction_mask_uv[block_size] << shift_uv; - } - - // If the block has no coefficients and is not intra we skip applying - // the loop filter on block edges. - if (mi->skip && is_inter_block(mi)) return; - - // Add a mask for the transform size. The transform size mask is set to - // be correct for a 64x64 prediction block size. Mask to match the size of - // the block we are working on and then shift it into place. - *above_y |= (size_mask[block_size] & above_64x64_txform_mask[tx_size_y]) - << shift_y; - *left_y |= (size_mask[block_size] & left_64x64_txform_mask[tx_size_y]) - << shift_y; - - if (build_uv) { - *above_uv |= - (size_mask_uv[block_size] & above_64x64_txform_mask_uv[tx_size_uv]) - << shift_uv; - - *left_uv |= - (size_mask_uv[block_size] & left_64x64_txform_mask_uv[tx_size_uv]) - << shift_uv; - } - - // Try to determine what to do with the internal 4x4 block boundaries. These - // differ from the 4x4 boundaries on the outside edge of an 8x8 in that the - // internal ones can be skipped and don't depend on the prediction block size. - if (tx_size_y == TX_4X4) *int_4x4_y |= size_mask[block_size] << shift_y; - - if (build_uv && tx_size_uv == TX_4X4) - *int_4x4_uv |= (size_mask_uv[block_size] & 0xffff) << shift_uv; -} - -void vp9_loop_filter_data_reset( - LFWorkerData *lf_data, YV12_BUFFER_CONFIG *frame_buffer, - struct VP9Common *cm, const struct macroblockd_plane planes[MAX_MB_PLANE]) { - lf_data->frame_buffer = frame_buffer; - lf_data->cm = cm; - lf_data->start = 0; - lf_data->stop = 0; - lf_data->y_only = 0; - memcpy(lf_data->planes, planes, sizeof(lf_data->planes)); -} - -void vp9_reset_lfm(VP9_COMMON *const cm) { - if (cm->lf.filter_level) { - memset(cm->lf.lfm, 0, - ((cm->mi_rows + (MI_BLOCK_SIZE - 1)) >> 3) * cm->lf.lfm_stride * - sizeof(*cm->lf.lfm)); - } -} - -int vp9_loop_filter_worker(void *arg1, void *unused) { - LFWorkerData *const lf_data = (LFWorkerData *)arg1; - (void)unused; - loop_filter_rows(lf_data->frame_buffer, lf_data->cm, lf_data->planes, - lf_data->start, lf_data->stop, lf_data->y_only); - return 1; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_loopfilter.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_loopfilter.h deleted file mode 100644 index 39648a72..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_loopfilter.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_LOOPFILTER_H_ -#define VPX_VP9_COMMON_VP9_LOOPFILTER_H_ - -#include "vpx_ports/mem.h" -#include "./vpx_config.h" - -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_seg_common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_LOOP_FILTER 63 -#define MAX_SHARPNESS 7 - -#define SIMD_WIDTH 16 - -#define MAX_REF_LF_DELTAS 4 -#define MAX_MODE_LF_DELTAS 2 - -enum lf_path { - LF_PATH_420, - LF_PATH_444, - LF_PATH_SLOW, -}; - -// Need to align this structure so when it is declared and -// passed it can be loaded into vector registers. -typedef struct { - DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, mblim[SIMD_WIDTH]); - DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, lim[SIMD_WIDTH]); - DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, hev_thr[SIMD_WIDTH]); -} loop_filter_thresh; - -typedef struct { - loop_filter_thresh lfthr[MAX_LOOP_FILTER + 1]; - uint8_t lvl[MAX_SEGMENTS][MAX_REF_FRAMES][MAX_MODE_LF_DELTAS]; -} loop_filter_info_n; - -// This structure holds bit masks for all 8x8 blocks in a 64x64 region. -// Each 1 bit represents a position in which we want to apply the loop filter. -// Left_ entries refer to whether we apply a filter on the border to the -// left of the block. Above_ entries refer to whether or not to apply a -// filter on the above border. Int_ entries refer to whether or not to -// apply borders on the 4x4 edges within the 8x8 block that each bit -// represents. -// Since each transform is accompanied by a potentially different type of -// loop filter there is a different entry in the array for each transform size. -typedef struct { - uint64_t left_y[TX_SIZES]; - uint64_t above_y[TX_SIZES]; - uint64_t int_4x4_y; - uint16_t left_uv[TX_SIZES]; - uint16_t above_uv[TX_SIZES]; - uint16_t int_4x4_uv; - uint8_t lfl_y[64]; -} LOOP_FILTER_MASK; - -struct loopfilter { - int filter_level; - int last_filt_level; - - int sharpness_level; - int last_sharpness_level; - - uint8_t mode_ref_delta_enabled; - uint8_t mode_ref_delta_update; - - // 0 = Intra, Last, GF, ARF - signed char ref_deltas[MAX_REF_LF_DELTAS]; - signed char last_ref_deltas[MAX_REF_LF_DELTAS]; - - // 0 = ZERO_MV, MV - signed char mode_deltas[MAX_MODE_LF_DELTAS]; - signed char last_mode_deltas[MAX_MODE_LF_DELTAS]; - - LOOP_FILTER_MASK *lfm; - int lfm_stride; -}; - -/* assorted loopfilter functions which get used elsewhere */ -struct VP9Common; -struct macroblockd; -struct VP9LfSyncData; - -// This function sets up the bit masks for the entire 64x64 region represented -// by mi_row, mi_col. -void vp9_setup_mask(struct VP9Common *const cm, const int mi_row, - const int mi_col, MODE_INFO **mi8x8, - const int mode_info_stride, LOOP_FILTER_MASK *lfm); - -void vp9_filter_block_plane_ss00(struct VP9Common *const cm, - struct macroblockd_plane *const plane, - int mi_row, LOOP_FILTER_MASK *lfm); - -void vp9_filter_block_plane_ss11(struct VP9Common *const cm, - struct macroblockd_plane *const plane, - int mi_row, LOOP_FILTER_MASK *lfm); - -void vp9_filter_block_plane_non420(struct VP9Common *cm, - struct macroblockd_plane *plane, - MODE_INFO **mi_8x8, int mi_row, int mi_col); - -void vp9_loop_filter_init(struct VP9Common *cm); - -// Update the loop filter for the current frame. -// This should be called before vp9_loop_filter_frame(), vp9_build_mask_frame() -// calls this function directly. -void vp9_loop_filter_frame_init(struct VP9Common *cm, int default_filt_lvl); - -void vp9_loop_filter_frame(YV12_BUFFER_CONFIG *frame, struct VP9Common *cm, - struct macroblockd *xd, int frame_filter_level, - int y_only, int partial_frame); - -// Get the superblock lfm for a given mi_row, mi_col. -static INLINE LOOP_FILTER_MASK *get_lfm(const struct loopfilter *lf, - const int mi_row, const int mi_col) { - return &lf->lfm[(mi_col >> 3) + ((mi_row >> 3) * lf->lfm_stride)]; -} - -void vp9_build_mask(struct VP9Common *cm, const MODE_INFO *mi, int mi_row, - int mi_col, int bw, int bh); -void vp9_adjust_mask(struct VP9Common *const cm, const int mi_row, - const int mi_col, LOOP_FILTER_MASK *lfm); -void vp9_build_mask_frame(struct VP9Common *cm, int frame_filter_level, - int partial_frame); -void vp9_reset_lfm(struct VP9Common *const cm); - -typedef struct LoopFilterWorkerData { - YV12_BUFFER_CONFIG *frame_buffer; - struct VP9Common *cm; - struct macroblockd_plane planes[MAX_MB_PLANE]; - - int start; - int stop; - int y_only; -} LFWorkerData; - -void vp9_loop_filter_data_reset( - LFWorkerData *lf_data, YV12_BUFFER_CONFIG *frame_buffer, - struct VP9Common *cm, const struct macroblockd_plane planes[MAX_MB_PLANE]); - -// Operates on the rows described by 'arg1' (cast to LFWorkerData *). -int vp9_loop_filter_worker(void *arg1, void *unused); -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_LOOPFILTER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_mfqe.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_mfqe.c deleted file mode 100644 index cf60fa40..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_mfqe.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "./vp9_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "./vpx_scale_rtcd.h" - -#include "vp9/common/vp9_onyxc_int.h" -#include "vp9/common/vp9_postproc.h" - -// TODO(jackychen): Replace this function with SSE2 code. There is -// one SSE2 implementation in vp8, so will consider how to share it -// between vp8 and vp9. -static void filter_by_weight(const uint8_t *src, int src_stride, uint8_t *dst, - int dst_stride, int block_size, int src_weight) { - const int dst_weight = (1 << MFQE_PRECISION) - src_weight; - const int rounding_bit = 1 << (MFQE_PRECISION - 1); - int r, c; - - for (r = 0; r < block_size; r++) { - for (c = 0; c < block_size; c++) { - dst[c] = (src[c] * src_weight + dst[c] * dst_weight + rounding_bit) >> - MFQE_PRECISION; - } - src += src_stride; - dst += dst_stride; - } -} - -void vp9_filter_by_weight8x8_c(const uint8_t *src, int src_stride, uint8_t *dst, - int dst_stride, int src_weight) { - filter_by_weight(src, src_stride, dst, dst_stride, 8, src_weight); -} - -void vp9_filter_by_weight16x16_c(const uint8_t *src, int src_stride, - uint8_t *dst, int dst_stride, int src_weight) { - filter_by_weight(src, src_stride, dst, dst_stride, 16, src_weight); -} - -static void filter_by_weight32x32(const uint8_t *src, int src_stride, - uint8_t *dst, int dst_stride, int weight) { - vp9_filter_by_weight16x16(src, src_stride, dst, dst_stride, weight); - vp9_filter_by_weight16x16(src + 16, src_stride, dst + 16, dst_stride, weight); - vp9_filter_by_weight16x16(src + src_stride * 16, src_stride, - dst + dst_stride * 16, dst_stride, weight); - vp9_filter_by_weight16x16(src + src_stride * 16 + 16, src_stride, - dst + dst_stride * 16 + 16, dst_stride, weight); -} - -static void filter_by_weight64x64(const uint8_t *src, int src_stride, - uint8_t *dst, int dst_stride, int weight) { - filter_by_weight32x32(src, src_stride, dst, dst_stride, weight); - filter_by_weight32x32(src + 32, src_stride, dst + 32, dst_stride, weight); - filter_by_weight32x32(src + src_stride * 32, src_stride, - dst + dst_stride * 32, dst_stride, weight); - filter_by_weight32x32(src + src_stride * 32 + 32, src_stride, - dst + dst_stride * 32 + 32, dst_stride, weight); -} - -static void apply_ifactor(const uint8_t *y, int y_stride, uint8_t *yd, - int yd_stride, const uint8_t *u, const uint8_t *v, - int uv_stride, uint8_t *ud, uint8_t *vd, - int uvd_stride, BLOCK_SIZE block_size, int weight) { - if (block_size == BLOCK_16X16) { - vp9_filter_by_weight16x16(y, y_stride, yd, yd_stride, weight); - vp9_filter_by_weight8x8(u, uv_stride, ud, uvd_stride, weight); - vp9_filter_by_weight8x8(v, uv_stride, vd, uvd_stride, weight); - } else if (block_size == BLOCK_32X32) { - filter_by_weight32x32(y, y_stride, yd, yd_stride, weight); - vp9_filter_by_weight16x16(u, uv_stride, ud, uvd_stride, weight); - vp9_filter_by_weight16x16(v, uv_stride, vd, uvd_stride, weight); - } else if (block_size == BLOCK_64X64) { - filter_by_weight64x64(y, y_stride, yd, yd_stride, weight); - filter_by_weight32x32(u, uv_stride, ud, uvd_stride, weight); - filter_by_weight32x32(v, uv_stride, vd, uvd_stride, weight); - } -} - -// TODO(jackychen): Determine whether replace it with assembly code. -static void copy_mem8x8(const uint8_t *src, int src_stride, uint8_t *dst, - int dst_stride) { - int r; - for (r = 0; r < 8; r++) { - memcpy(dst, src, 8); - src += src_stride; - dst += dst_stride; - } -} - -static void copy_mem16x16(const uint8_t *src, int src_stride, uint8_t *dst, - int dst_stride) { - int r; - for (r = 0; r < 16; r++) { - memcpy(dst, src, 16); - src += src_stride; - dst += dst_stride; - } -} - -static void copy_mem32x32(const uint8_t *src, int src_stride, uint8_t *dst, - int dst_stride) { - copy_mem16x16(src, src_stride, dst, dst_stride); - copy_mem16x16(src + 16, src_stride, dst + 16, dst_stride); - copy_mem16x16(src + src_stride * 16, src_stride, dst + dst_stride * 16, - dst_stride); - copy_mem16x16(src + src_stride * 16 + 16, src_stride, - dst + dst_stride * 16 + 16, dst_stride); -} - -static void copy_mem64x64(const uint8_t *src, int src_stride, uint8_t *dst, - int dst_stride) { - copy_mem32x32(src, src_stride, dst, dst_stride); - copy_mem32x32(src + 32, src_stride, dst + 32, dst_stride); - copy_mem32x32(src + src_stride * 32, src_stride, dst + src_stride * 32, - dst_stride); - copy_mem32x32(src + src_stride * 32 + 32, src_stride, - dst + src_stride * 32 + 32, dst_stride); -} - -static void copy_block(const uint8_t *y, const uint8_t *u, const uint8_t *v, - int y_stride, int uv_stride, uint8_t *yd, uint8_t *ud, - uint8_t *vd, int yd_stride, int uvd_stride, - BLOCK_SIZE bs) { - if (bs == BLOCK_16X16) { - copy_mem16x16(y, y_stride, yd, yd_stride); - copy_mem8x8(u, uv_stride, ud, uvd_stride); - copy_mem8x8(v, uv_stride, vd, uvd_stride); - } else if (bs == BLOCK_32X32) { - copy_mem32x32(y, y_stride, yd, yd_stride); - copy_mem16x16(u, uv_stride, ud, uvd_stride); - copy_mem16x16(v, uv_stride, vd, uvd_stride); - } else { - copy_mem64x64(y, y_stride, yd, yd_stride); - copy_mem32x32(u, uv_stride, ud, uvd_stride); - copy_mem32x32(v, uv_stride, vd, uvd_stride); - } -} - -static void get_thr(BLOCK_SIZE bs, int qdiff, int *sad_thr, int *vdiff_thr) { - const int adj = qdiff >> MFQE_PRECISION; - if (bs == BLOCK_16X16) { - *sad_thr = 7 + adj; - } else if (bs == BLOCK_32X32) { - *sad_thr = 6 + adj; - } else { // BLOCK_64X64 - *sad_thr = 5 + adj; - } - *vdiff_thr = 125 + qdiff; -} - -static void mfqe_block(BLOCK_SIZE bs, const uint8_t *y, const uint8_t *u, - const uint8_t *v, int y_stride, int uv_stride, - uint8_t *yd, uint8_t *ud, uint8_t *vd, int yd_stride, - int uvd_stride, int qdiff) { - int sad, sad_thr, vdiff, vdiff_thr; - uint32_t sse; - - get_thr(bs, qdiff, &sad_thr, &vdiff_thr); - - if (bs == BLOCK_16X16) { - vdiff = (vpx_variance16x16(y, y_stride, yd, yd_stride, &sse) + 128) >> 8; - sad = (vpx_sad16x16(y, y_stride, yd, yd_stride) + 128) >> 8; - } else if (bs == BLOCK_32X32) { - vdiff = (vpx_variance32x32(y, y_stride, yd, yd_stride, &sse) + 512) >> 10; - sad = (vpx_sad32x32(y, y_stride, yd, yd_stride) + 512) >> 10; - } else /* if (bs == BLOCK_64X64) */ { - vdiff = (vpx_variance64x64(y, y_stride, yd, yd_stride, &sse) + 2048) >> 12; - sad = (vpx_sad64x64(y, y_stride, yd, yd_stride) + 2048) >> 12; - } - - // vdiff > sad * 3 means vdiff should not be too small, otherwise, - // it might be a lighting change in smooth area. When there is a - // lighting change in smooth area, it is dangerous to do MFQE. - if (sad > 1 && vdiff > sad * 3) { - const int weight = 1 << MFQE_PRECISION; - int ifactor = weight * sad * vdiff / (sad_thr * vdiff_thr); - // When ifactor equals weight, no MFQE is done. - if (ifactor > weight) { - ifactor = weight; - } - apply_ifactor(y, y_stride, yd, yd_stride, u, v, uv_stride, ud, vd, - uvd_stride, bs, ifactor); - } else { - // Copy the block from current frame (i.e., no mfqe is done). - copy_block(y, u, v, y_stride, uv_stride, yd, ud, vd, yd_stride, uvd_stride, - bs); - } -} - -static int mfqe_decision(MODE_INFO *mi, BLOCK_SIZE cur_bs) { - // Check the motion in current block(for inter frame), - // or check the motion in the correlated block in last frame (for keyframe). - const int mv_len_square = mi->mv[0].as_mv.row * mi->mv[0].as_mv.row + - mi->mv[0].as_mv.col * mi->mv[0].as_mv.col; - const int mv_threshold = 100; - return mi->mode >= NEARESTMV && // Not an intra block - cur_bs >= BLOCK_16X16 && mv_len_square <= mv_threshold; -} - -// Process each partiton in a super block, recursively. -static void mfqe_partition(VP9_COMMON *cm, MODE_INFO *mi, BLOCK_SIZE bs, - const uint8_t *y, const uint8_t *u, const uint8_t *v, - int y_stride, int uv_stride, uint8_t *yd, - uint8_t *ud, uint8_t *vd, int yd_stride, - int uvd_stride) { - int mi_offset, y_offset, uv_offset; - const BLOCK_SIZE cur_bs = mi->sb_type; - const int qdiff = cm->base_qindex - cm->postproc_state.last_base_qindex; - const int bsl = b_width_log2_lookup[bs]; - PARTITION_TYPE partition = partition_lookup[bsl][cur_bs]; - const BLOCK_SIZE subsize = get_subsize(bs, partition); - BLOCK_SIZE mfqe_bs, bs_tmp; - - if (cur_bs < BLOCK_8X8) { - // If there are blocks smaller than 8x8, it must be on the boundary. - return; - } - // No MFQE on blocks smaller than 16x16 - if (bs == BLOCK_16X16) { - partition = PARTITION_NONE; - } - if (bs == BLOCK_64X64) { - mi_offset = 4; - y_offset = 32; - uv_offset = 16; - } else { - mi_offset = 2; - y_offset = 16; - uv_offset = 8; - } - switch (partition) { - case PARTITION_HORZ: - if (bs == BLOCK_64X64) { - mfqe_bs = BLOCK_64X32; - bs_tmp = BLOCK_32X32; - } else { - mfqe_bs = BLOCK_32X16; - bs_tmp = BLOCK_16X16; - } - if (mfqe_decision(mi, mfqe_bs)) { - // Do mfqe on the first square partition. - mfqe_block(bs_tmp, y, u, v, y_stride, uv_stride, yd, ud, vd, yd_stride, - uvd_stride, qdiff); - // Do mfqe on the second square partition. - mfqe_block(bs_tmp, y + y_offset, u + uv_offset, v + uv_offset, y_stride, - uv_stride, yd + y_offset, ud + uv_offset, vd + uv_offset, - yd_stride, uvd_stride, qdiff); - } - if (mfqe_decision(mi + mi_offset * cm->mi_stride, mfqe_bs)) { - // Do mfqe on the first square partition. - mfqe_block(bs_tmp, y + y_offset * y_stride, u + uv_offset * uv_stride, - v + uv_offset * uv_stride, y_stride, uv_stride, - yd + y_offset * yd_stride, ud + uv_offset * uvd_stride, - vd + uv_offset * uvd_stride, yd_stride, uvd_stride, qdiff); - // Do mfqe on the second square partition. - mfqe_block(bs_tmp, y + y_offset * y_stride + y_offset, - u + uv_offset * uv_stride + uv_offset, - v + uv_offset * uv_stride + uv_offset, y_stride, uv_stride, - yd + y_offset * yd_stride + y_offset, - ud + uv_offset * uvd_stride + uv_offset, - vd + uv_offset * uvd_stride + uv_offset, yd_stride, - uvd_stride, qdiff); - } - break; - case PARTITION_VERT: - if (bs == BLOCK_64X64) { - mfqe_bs = BLOCK_32X64; - bs_tmp = BLOCK_32X32; - } else { - mfqe_bs = BLOCK_16X32; - bs_tmp = BLOCK_16X16; - } - if (mfqe_decision(mi, mfqe_bs)) { - // Do mfqe on the first square partition. - mfqe_block(bs_tmp, y, u, v, y_stride, uv_stride, yd, ud, vd, yd_stride, - uvd_stride, qdiff); - // Do mfqe on the second square partition. - mfqe_block(bs_tmp, y + y_offset * y_stride, u + uv_offset * uv_stride, - v + uv_offset * uv_stride, y_stride, uv_stride, - yd + y_offset * yd_stride, ud + uv_offset * uvd_stride, - vd + uv_offset * uvd_stride, yd_stride, uvd_stride, qdiff); - } - if (mfqe_decision(mi + mi_offset, mfqe_bs)) { - // Do mfqe on the first square partition. - mfqe_block(bs_tmp, y + y_offset, u + uv_offset, v + uv_offset, y_stride, - uv_stride, yd + y_offset, ud + uv_offset, vd + uv_offset, - yd_stride, uvd_stride, qdiff); - // Do mfqe on the second square partition. - mfqe_block(bs_tmp, y + y_offset * y_stride + y_offset, - u + uv_offset * uv_stride + uv_offset, - v + uv_offset * uv_stride + uv_offset, y_stride, uv_stride, - yd + y_offset * yd_stride + y_offset, - ud + uv_offset * uvd_stride + uv_offset, - vd + uv_offset * uvd_stride + uv_offset, yd_stride, - uvd_stride, qdiff); - } - break; - case PARTITION_NONE: - if (mfqe_decision(mi, cur_bs)) { - // Do mfqe on this partition. - mfqe_block(cur_bs, y, u, v, y_stride, uv_stride, yd, ud, vd, yd_stride, - uvd_stride, qdiff); - } else { - // Copy the block from current frame(i.e., no mfqe is done). - copy_block(y, u, v, y_stride, uv_stride, yd, ud, vd, yd_stride, - uvd_stride, bs); - } - break; - case PARTITION_SPLIT: - // Recursion on four square partitions, e.g. if bs is 64X64, - // then look into four 32X32 blocks in it. - mfqe_partition(cm, mi, subsize, y, u, v, y_stride, uv_stride, yd, ud, vd, - yd_stride, uvd_stride); - mfqe_partition(cm, mi + mi_offset, subsize, y + y_offset, u + uv_offset, - v + uv_offset, y_stride, uv_stride, yd + y_offset, - ud + uv_offset, vd + uv_offset, yd_stride, uvd_stride); - mfqe_partition(cm, mi + mi_offset * cm->mi_stride, subsize, - y + y_offset * y_stride, u + uv_offset * uv_stride, - v + uv_offset * uv_stride, y_stride, uv_stride, - yd + y_offset * yd_stride, ud + uv_offset * uvd_stride, - vd + uv_offset * uvd_stride, yd_stride, uvd_stride); - mfqe_partition(cm, mi + mi_offset * cm->mi_stride + mi_offset, subsize, - y + y_offset * y_stride + y_offset, - u + uv_offset * uv_stride + uv_offset, - v + uv_offset * uv_stride + uv_offset, y_stride, uv_stride, - yd + y_offset * yd_stride + y_offset, - ud + uv_offset * uvd_stride + uv_offset, - vd + uv_offset * uvd_stride + uv_offset, yd_stride, - uvd_stride); - break; - default: assert(0); - } -} - -void vp9_mfqe(VP9_COMMON *cm) { - int mi_row, mi_col; - // Current decoded frame. - const YV12_BUFFER_CONFIG *show = cm->frame_to_show; - // Last decoded frame and will store the MFQE result. - YV12_BUFFER_CONFIG *dest = &cm->post_proc_buffer; - // Loop through each super block. - for (mi_row = 0; mi_row < cm->mi_rows; mi_row += MI_BLOCK_SIZE) { - for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MI_BLOCK_SIZE) { - MODE_INFO *mi; - MODE_INFO *mi_local = cm->mi + (mi_row * cm->mi_stride + mi_col); - // Motion Info in last frame. - MODE_INFO *mi_prev = - cm->postproc_state.prev_mi + (mi_row * cm->mi_stride + mi_col); - const uint32_t y_stride = show->y_stride; - const uint32_t uv_stride = show->uv_stride; - const uint32_t yd_stride = dest->y_stride; - const uint32_t uvd_stride = dest->uv_stride; - const uint32_t row_offset_y = mi_row << 3; - const uint32_t row_offset_uv = mi_row << 2; - const uint32_t col_offset_y = mi_col << 3; - const uint32_t col_offset_uv = mi_col << 2; - const uint8_t *y = - show->y_buffer + row_offset_y * y_stride + col_offset_y; - const uint8_t *u = - show->u_buffer + row_offset_uv * uv_stride + col_offset_uv; - const uint8_t *v = - show->v_buffer + row_offset_uv * uv_stride + col_offset_uv; - uint8_t *yd = dest->y_buffer + row_offset_y * yd_stride + col_offset_y; - uint8_t *ud = dest->u_buffer + row_offset_uv * uvd_stride + col_offset_uv; - uint8_t *vd = dest->v_buffer + row_offset_uv * uvd_stride + col_offset_uv; - if (frame_is_intra_only(cm)) { - mi = mi_prev; - } else { - mi = mi_local; - } - mfqe_partition(cm, mi, BLOCK_64X64, y, u, v, y_stride, uv_stride, yd, ud, - vd, yd_stride, uvd_stride); - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_mfqe.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_mfqe.h deleted file mode 100644 index f53e1c2f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_mfqe.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_MFQE_H_ -#define VPX_VP9_COMMON_VP9_MFQE_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -// Multiframe Quality Enhancement. -// The aim for MFQE is to replace pixel blocks in the current frame with -// the correlated pixel blocks (with higher quality) in the last frame. -// The replacement can only be taken in stationary blocks by checking -// the motion of the blocks and other conditions such as the SAD of -// the current block and correlated block, the variance of the block -// difference, etc. -void vp9_mfqe(struct VP9Common *cm); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_MFQE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_mv.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_mv.h deleted file mode 100644 index 76f93cf0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_mv.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_MV_H_ -#define VPX_VP9_COMMON_VP9_MV_H_ - -#include "vpx/vpx_integer.h" - -#include "vp9/common/vp9_common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define INVALID_MV 0x80008000 - -typedef struct mv { - int16_t row; - int16_t col; -} MV; - -typedef union int_mv { - uint32_t as_int; - MV as_mv; -} int_mv; /* facilitates faster equality tests and copies */ - -typedef struct mv32 { - int32_t row; - int32_t col; -} MV32; - -static INLINE int is_zero_mv(const MV *mv) { - return *((const uint32_t *)mv) == 0; -} - -static INLINE int is_equal_mv(const MV *a, const MV *b) { - return *((const uint32_t *)a) == *((const uint32_t *)b); -} - -static INLINE void clamp_mv(MV *mv, int min_col, int max_col, int min_row, - int max_row) { - mv->col = clamp(mv->col, min_col, max_col); - mv->row = clamp(mv->row, min_row, max_row); -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_MV_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_mvref_common.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_mvref_common.c deleted file mode 100644 index 70f77aba..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_mvref_common.c +++ /dev/null @@ -1,199 +0,0 @@ - -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp9/common/vp9_mvref_common.h" - -// This function searches the neighborhood of a given MB/SB -// to try and find candidate reference vectors. -static void find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd, - MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame, - int_mv *mv_ref_list, int block, int mi_row, - int mi_col, uint8_t *mode_context) { - const int *ref_sign_bias = cm->ref_frame_sign_bias; - int i, refmv_count = 0; - const POSITION *const mv_ref_search = mv_ref_blocks[mi->sb_type]; - int different_ref_found = 0; - int context_counter = 0; - const MV_REF *const prev_frame_mvs = - cm->use_prev_frame_mvs - ? cm->prev_frame->mvs + mi_row * cm->mi_cols + mi_col - : NULL; - const TileInfo *const tile = &xd->tile; - - // Blank the reference vector list - memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES); - - // The nearest 2 blocks are treated differently - // if the size < 8x8 we get the mv from the bmi substructure, - // and we also need to keep a mode count. - for (i = 0; i < 2; ++i) { - const POSITION *const mv_ref = &mv_ref_search[i]; - if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { - const MODE_INFO *const candidate_mi = - xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; - // Keep counts for entropy encoding. - context_counter += mode_2_counter[candidate_mi->mode]; - different_ref_found = 1; - - if (candidate_mi->ref_frame[0] == ref_frame) - ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 0, mv_ref->col, block), - refmv_count, mv_ref_list, Done); - else if (candidate_mi->ref_frame[1] == ref_frame) - ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 1, mv_ref->col, block), - refmv_count, mv_ref_list, Done); - } - } - - // Check the rest of the neighbors in much the same way - // as before except we don't need to keep track of sub blocks or - // mode counts. - for (; i < MVREF_NEIGHBOURS; ++i) { - const POSITION *const mv_ref = &mv_ref_search[i]; - if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { - const MODE_INFO *const candidate_mi = - xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; - different_ref_found = 1; - - if (candidate_mi->ref_frame[0] == ref_frame) - ADD_MV_REF_LIST(candidate_mi->mv[0], refmv_count, mv_ref_list, Done); - else if (candidate_mi->ref_frame[1] == ref_frame) - ADD_MV_REF_LIST(candidate_mi->mv[1], refmv_count, mv_ref_list, Done); - } - } - - // Check the last frame's mode and mv info. - if (cm->use_prev_frame_mvs) { - if (prev_frame_mvs->ref_frame[0] == ref_frame) { - ADD_MV_REF_LIST(prev_frame_mvs->mv[0], refmv_count, mv_ref_list, Done); - } else if (prev_frame_mvs->ref_frame[1] == ref_frame) { - ADD_MV_REF_LIST(prev_frame_mvs->mv[1], refmv_count, mv_ref_list, Done); - } - } - - // Since we couldn't find 2 mvs from the same reference frame - // go back through the neighbors and find motion vectors from - // different reference frames. - if (different_ref_found) { - for (i = 0; i < MVREF_NEIGHBOURS; ++i) { - const POSITION *mv_ref = &mv_ref_search[i]; - if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { - const MODE_INFO *const candidate_mi = - xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; - - // If the candidate is INTRA we don't want to consider its mv. - IF_DIFF_REF_FRAME_ADD_MV(candidate_mi, ref_frame, ref_sign_bias, - refmv_count, mv_ref_list, Done); - } - } - } - - // Since we still don't have a candidate we'll try the last frame. - if (cm->use_prev_frame_mvs) { - if (prev_frame_mvs->ref_frame[0] != ref_frame && - prev_frame_mvs->ref_frame[0] > INTRA_FRAME) { - int_mv mv = prev_frame_mvs->mv[0]; - if (ref_sign_bias[prev_frame_mvs->ref_frame[0]] != - ref_sign_bias[ref_frame]) { - mv.as_mv.row *= -1; - mv.as_mv.col *= -1; - } - ADD_MV_REF_LIST(mv, refmv_count, mv_ref_list, Done); - } - - if (prev_frame_mvs->ref_frame[1] > INTRA_FRAME && - prev_frame_mvs->ref_frame[1] != ref_frame && - prev_frame_mvs->mv[1].as_int != prev_frame_mvs->mv[0].as_int) { - int_mv mv = prev_frame_mvs->mv[1]; - if (ref_sign_bias[prev_frame_mvs->ref_frame[1]] != - ref_sign_bias[ref_frame]) { - mv.as_mv.row *= -1; - mv.as_mv.col *= -1; - } - ADD_MV_REF_LIST(mv, refmv_count, mv_ref_list, Done); - } - } - -Done: - - mode_context[ref_frame] = counter_to_context[context_counter]; - - // Clamp vectors - for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) - clamp_mv_ref(&mv_ref_list[i].as_mv, xd); -} - -void vp9_find_mv_refs(const VP9_COMMON *cm, const MACROBLOCKD *xd, - MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame, - int_mv *mv_ref_list, int mi_row, int mi_col, - uint8_t *mode_context) { - find_mv_refs_idx(cm, xd, mi, ref_frame, mv_ref_list, -1, mi_row, mi_col, - mode_context); -} - -void vp9_find_best_ref_mvs(MACROBLOCKD *xd, int allow_hp, int_mv *mvlist, - int_mv *nearest_mv, int_mv *near_mv) { - int i; - // Make sure all the candidates are properly clamped etc - for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) { - lower_mv_precision(&mvlist[i].as_mv, allow_hp); - clamp_mv2(&mvlist[i].as_mv, xd); - } - *nearest_mv = mvlist[0]; - *near_mv = mvlist[1]; -} - -void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd, int block, - int ref, int mi_row, int mi_col, - int_mv *nearest_mv, int_mv *near_mv, - uint8_t *mode_context) { - int_mv mv_list[MAX_MV_REF_CANDIDATES]; - MODE_INFO *const mi = xd->mi[0]; - b_mode_info *bmi = mi->bmi; - int n; - - assert(MAX_MV_REF_CANDIDATES == 2); - - find_mv_refs_idx(cm, xd, mi, mi->ref_frame[ref], mv_list, block, mi_row, - mi_col, mode_context); - - near_mv->as_int = 0; - switch (block) { - case 0: - nearest_mv->as_int = mv_list[0].as_int; - near_mv->as_int = mv_list[1].as_int; - break; - case 1: - case 2: - nearest_mv->as_int = bmi[0].as_mv[ref].as_int; - for (n = 0; n < MAX_MV_REF_CANDIDATES; ++n) - if (nearest_mv->as_int != mv_list[n].as_int) { - near_mv->as_int = mv_list[n].as_int; - break; - } - break; - case 3: { - int_mv candidates[2 + MAX_MV_REF_CANDIDATES]; - candidates[0] = bmi[1].as_mv[ref]; - candidates[1] = bmi[0].as_mv[ref]; - candidates[2] = mv_list[0]; - candidates[3] = mv_list[1]; - - nearest_mv->as_int = bmi[2].as_mv[ref].as_int; - for (n = 0; n < 2 + MAX_MV_REF_CANDIDATES; ++n) - if (nearest_mv->as_int != candidates[n].as_int) { - near_mv->as_int = candidates[n].as_int; - break; - } - break; - } - default: assert(0 && "Invalid block index."); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_mvref_common.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_mvref_common.h deleted file mode 100644 index 5db6772d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_mvref_common.h +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_VP9_COMMON_VP9_MVREF_COMMON_H_ -#define VPX_VP9_COMMON_VP9_MVREF_COMMON_H_ - -#include "vp9/common/vp9_onyxc_int.h" -#include "vp9/common/vp9_blockd.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define LEFT_TOP_MARGIN ((VP9_ENC_BORDER_IN_PIXELS - VP9_INTERP_EXTEND) << 3) -#define RIGHT_BOTTOM_MARGIN \ - ((VP9_ENC_BORDER_IN_PIXELS - VP9_INTERP_EXTEND) << 3) - -#define MVREF_NEIGHBOURS 8 - -typedef struct position { - int row; - int col; -} POSITION; - -typedef enum { - BOTH_ZERO = 0, - ZERO_PLUS_PREDICTED = 1, - BOTH_PREDICTED = 2, - NEW_PLUS_NON_INTRA = 3, - BOTH_NEW = 4, - INTRA_PLUS_NON_INTRA = 5, - BOTH_INTRA = 6, - INVALID_CASE = 9 -} motion_vector_context; - -// This is used to figure out a context for the ref blocks. The code flattens -// an array that would have 3 possible counts (0, 1 & 2) for 3 choices by -// adding 9 for each intra block, 3 for each zero mv and 1 for each new -// motion vector. This single number is then converted into a context -// with a single lookup ( counter_to_context ). -static const int mode_2_counter[MB_MODE_COUNT] = { - 9, // DC_PRED - 9, // V_PRED - 9, // H_PRED - 9, // D45_PRED - 9, // D135_PRED - 9, // D117_PRED - 9, // D153_PRED - 9, // D207_PRED - 9, // D63_PRED - 9, // TM_PRED - 0, // NEARESTMV - 0, // NEARMV - 3, // ZEROMV - 1, // NEWMV -}; - -// There are 3^3 different combinations of 3 counts that can be either 0,1 or -// 2. However the actual count can never be greater than 2 so the highest -// counter we need is 18. 9 is an invalid counter that's never used. -static const int counter_to_context[19] = { - BOTH_PREDICTED, // 0 - NEW_PLUS_NON_INTRA, // 1 - BOTH_NEW, // 2 - ZERO_PLUS_PREDICTED, // 3 - NEW_PLUS_NON_INTRA, // 4 - INVALID_CASE, // 5 - BOTH_ZERO, // 6 - INVALID_CASE, // 7 - INVALID_CASE, // 8 - INTRA_PLUS_NON_INTRA, // 9 - INTRA_PLUS_NON_INTRA, // 10 - INVALID_CASE, // 11 - INTRA_PLUS_NON_INTRA, // 12 - INVALID_CASE, // 13 - INVALID_CASE, // 14 - INVALID_CASE, // 15 - INVALID_CASE, // 16 - INVALID_CASE, // 17 - BOTH_INTRA // 18 -}; - -static const POSITION mv_ref_blocks[BLOCK_SIZES][MVREF_NEIGHBOURS] = { - // 4X4 - { { -1, 0 }, - { 0, -1 }, - { -1, -1 }, - { -2, 0 }, - { 0, -2 }, - { -2, -1 }, - { -1, -2 }, - { -2, -2 } }, - // 4X8 - { { -1, 0 }, - { 0, -1 }, - { -1, -1 }, - { -2, 0 }, - { 0, -2 }, - { -2, -1 }, - { -1, -2 }, - { -2, -2 } }, - // 8X4 - { { -1, 0 }, - { 0, -1 }, - { -1, -1 }, - { -2, 0 }, - { 0, -2 }, - { -2, -1 }, - { -1, -2 }, - { -2, -2 } }, - // 8X8 - { { -1, 0 }, - { 0, -1 }, - { -1, -1 }, - { -2, 0 }, - { 0, -2 }, - { -2, -1 }, - { -1, -2 }, - { -2, -2 } }, - // 8X16 - { { 0, -1 }, - { -1, 0 }, - { 1, -1 }, - { -1, -1 }, - { 0, -2 }, - { -2, 0 }, - { -2, -1 }, - { -1, -2 } }, - // 16X8 - { { -1, 0 }, - { 0, -1 }, - { -1, 1 }, - { -1, -1 }, - { -2, 0 }, - { 0, -2 }, - { -1, -2 }, - { -2, -1 } }, - // 16X16 - { { -1, 0 }, - { 0, -1 }, - { -1, 1 }, - { 1, -1 }, - { -1, -1 }, - { -3, 0 }, - { 0, -3 }, - { -3, -3 } }, - // 16X32 - { { 0, -1 }, - { -1, 0 }, - { 2, -1 }, - { -1, -1 }, - { -1, 1 }, - { 0, -3 }, - { -3, 0 }, - { -3, -3 } }, - // 32X16 - { { -1, 0 }, - { 0, -1 }, - { -1, 2 }, - { -1, -1 }, - { 1, -1 }, - { -3, 0 }, - { 0, -3 }, - { -3, -3 } }, - // 32X32 - { { -1, 1 }, - { 1, -1 }, - { -1, 2 }, - { 2, -1 }, - { -1, -1 }, - { -3, 0 }, - { 0, -3 }, - { -3, -3 } }, - // 32X64 - { { 0, -1 }, - { -1, 0 }, - { 4, -1 }, - { -1, 2 }, - { -1, -1 }, - { 0, -3 }, - { -3, 0 }, - { 2, -1 } }, - // 64X32 - { { -1, 0 }, - { 0, -1 }, - { -1, 4 }, - { 2, -1 }, - { -1, -1 }, - { -3, 0 }, - { 0, -3 }, - { -1, 2 } }, - // 64X64 - { { -1, 3 }, - { 3, -1 }, - { -1, 4 }, - { 4, -1 }, - { -1, -1 }, - { -1, 0 }, - { 0, -1 }, - { -1, 6 } } -}; - -static const int idx_n_column_to_subblock[4][2] = { - { 1, 2 }, { 1, 3 }, { 3, 2 }, { 3, 3 } -}; - -// clamp_mv_ref -#define MV_BORDER (16 << 3) // Allow 16 pels in 1/8th pel units - -static INLINE void clamp_mv_ref(MV *mv, const MACROBLOCKD *xd) { - clamp_mv(mv, xd->mb_to_left_edge - MV_BORDER, - xd->mb_to_right_edge + MV_BORDER, xd->mb_to_top_edge - MV_BORDER, - xd->mb_to_bottom_edge + MV_BORDER); -} - -// This function returns either the appropriate sub block or block's mv -// on whether the block_size < 8x8 and we have check_sub_blocks set. -static INLINE int_mv get_sub_block_mv(const MODE_INFO *candidate, int which_mv, - int search_col, int block_idx) { - return block_idx >= 0 && candidate->sb_type < BLOCK_8X8 - ? candidate - ->bmi[idx_n_column_to_subblock[block_idx][search_col == 0]] - .as_mv[which_mv] - : candidate->mv[which_mv]; -} - -// Performs mv sign inversion if indicated by the reference frame combination. -static INLINE int_mv scale_mv(const MODE_INFO *mi, int ref, - const MV_REFERENCE_FRAME this_ref_frame, - const int *ref_sign_bias) { - int_mv mv = mi->mv[ref]; - if (ref_sign_bias[mi->ref_frame[ref]] != ref_sign_bias[this_ref_frame]) { - mv.as_mv.row *= -1; - mv.as_mv.col *= -1; - } - return mv; -} - -// This macro is used to add a motion vector mv_ref list if it isn't -// already in the list. If it's the second motion vector it will also -// skip all additional processing and jump to Done! -#define ADD_MV_REF_LIST(mv, refmv_count, mv_ref_list, Done) \ - do { \ - if (refmv_count) { \ - if ((mv).as_int != (mv_ref_list)[0].as_int) { \ - (mv_ref_list)[(refmv_count)] = (mv); \ - goto Done; \ - } \ - } else { \ - (mv_ref_list)[(refmv_count)++] = (mv); \ - } \ - } while (0) - -// If either reference frame is different, not INTRA, and they -// are different from each other scale and add the mv to our list. -#define IF_DIFF_REF_FRAME_ADD_MV(mbmi, ref_frame, ref_sign_bias, refmv_count, \ - mv_ref_list, Done) \ - do { \ - if (is_inter_block(mbmi)) { \ - if ((mbmi)->ref_frame[0] != (ref_frame)) \ - ADD_MV_REF_LIST(scale_mv((mbmi), 0, ref_frame, ref_sign_bias), \ - refmv_count, mv_ref_list, Done); \ - if (has_second_ref(mbmi) && (mbmi)->ref_frame[1] != (ref_frame) && \ - (mbmi)->mv[1].as_int != (mbmi)->mv[0].as_int) \ - ADD_MV_REF_LIST(scale_mv((mbmi), 1, ref_frame, ref_sign_bias), \ - refmv_count, mv_ref_list, Done); \ - } \ - } while (0) - -// Checks that the given mi_row, mi_col and search point -// are inside the borders of the tile. -static INLINE int is_inside(const TileInfo *const tile, int mi_col, int mi_row, - int mi_rows, const POSITION *mi_pos) { - return !(mi_row + mi_pos->row < 0 || - mi_col + mi_pos->col < tile->mi_col_start || - mi_row + mi_pos->row >= mi_rows || - mi_col + mi_pos->col >= tile->mi_col_end); -} - -// TODO(jingning): this mv clamping function should be block size dependent. -static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) { - clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN, - xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN, - xd->mb_to_top_edge - LEFT_TOP_MARGIN, - xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN); -} - -static INLINE void lower_mv_precision(MV *mv, int allow_hp) { - const int use_hp = allow_hp && use_mv_hp(mv); - if (!use_hp) { - if (mv->row & 1) mv->row += (mv->row > 0 ? -1 : 1); - if (mv->col & 1) mv->col += (mv->col > 0 ? -1 : 1); - } -} - -typedef void (*find_mv_refs_sync)(void *const data, int mi_row); -void vp9_find_mv_refs(const VP9_COMMON *cm, const MACROBLOCKD *xd, - MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame, - int_mv *mv_ref_list, int mi_row, int mi_col, - uint8_t *mode_context); - -// check a list of motion vectors by sad score using a number rows of pixels -// above and a number cols of pixels in the left to select the one with best -// score to use as ref motion vector -void vp9_find_best_ref_mvs(MACROBLOCKD *xd, int allow_hp, int_mv *mvlist, - int_mv *nearest_mv, int_mv *near_mv); - -void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd, int block, - int ref, int mi_row, int mi_col, - int_mv *nearest_mv, int_mv *near_mv, - uint8_t *mode_context); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_MVREF_COMMON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_onyxc_int.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_onyxc_int.h deleted file mode 100644 index 4c8fcf69..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_onyxc_int.h +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_ONYXC_INT_H_ -#define VPX_VP9_COMMON_VP9_ONYXC_INT_H_ - -#include "./vpx_config.h" -#include "vpx/internal/vpx_codec_internal.h" -#include "./vp9_rtcd.h" -#include "vp9/common/vp9_alloccommon.h" -#include "vp9/common/vp9_loopfilter.h" -#include "vp9/common/vp9_entropymv.h" -#include "vp9/common/vp9_entropy.h" -#include "vp9/common/vp9_entropymode.h" -#include "vp9/common/vp9_frame_buffers.h" -#include "vp9/common/vp9_quant_common.h" -#include "vp9/common/vp9_tile_common.h" - -#if CONFIG_VP9_POSTPROC -#include "vp9/common/vp9_postproc.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define REFS_PER_FRAME 3 - -#define REF_FRAMES_LOG2 3 -#define REF_FRAMES (1 << REF_FRAMES_LOG2) - -// 1 scratch frame for the new frame, REFS_PER_FRAME for scaled references on -// the encoder. -#define FRAME_BUFFERS (REF_FRAMES + 1 + REFS_PER_FRAME) - -#define FRAME_CONTEXTS_LOG2 2 -#define FRAME_CONTEXTS (1 << FRAME_CONTEXTS_LOG2) - -#define NUM_PING_PONG_BUFFERS 2 - -extern const struct { - PARTITION_CONTEXT above; - PARTITION_CONTEXT left; -} partition_context_lookup[BLOCK_SIZES]; - -typedef enum { - SINGLE_REFERENCE = 0, - COMPOUND_REFERENCE = 1, - REFERENCE_MODE_SELECT = 2, - REFERENCE_MODES = 3, -} REFERENCE_MODE; - -typedef struct { - int_mv mv[2]; - MV_REFERENCE_FRAME ref_frame[2]; -} MV_REF; - -typedef struct { - int ref_count; - MV_REF *mvs; - int mi_rows; - int mi_cols; - uint8_t released; - - // Note that frame_index/frame_coding_index are only set by set_frame_index() - // on the encoder side. - - // TODO(angiebird): Set frame_index/frame_coding_index on the decoder side - // properly. - int frame_index; // Display order in the video, it's equivalent to the - // show_idx defined in EncodeFrameInfo. - int frame_coding_index; // The coding order (starting from zero) of this - // frame. - vpx_codec_frame_buffer_t raw_frame_buffer; - YV12_BUFFER_CONFIG buf; -} RefCntBuffer; - -typedef struct BufferPool { - // Private data associated with the frame buffer callbacks. - void *cb_priv; - - vpx_get_frame_buffer_cb_fn_t get_fb_cb; - vpx_release_frame_buffer_cb_fn_t release_fb_cb; - - RefCntBuffer frame_bufs[FRAME_BUFFERS]; - - // Frame buffers allocated internally by the codec. - InternalFrameBufferList int_frame_buffers; -} BufferPool; - -typedef struct VP9Common { - struct vpx_internal_error_info error; - vpx_color_space_t color_space; - vpx_color_range_t color_range; - int width; - int height; - int render_width; - int render_height; - int last_width; - int last_height; - - // TODO(jkoleszar): this implies chroma ss right now, but could vary per - // plane. Revisit as part of the future change to YV12_BUFFER_CONFIG to - // support additional planes. - int subsampling_x; - int subsampling_y; - -#if CONFIG_VP9_HIGHBITDEPTH - int use_highbitdepth; // Marks if we need to use 16bit frame buffers. -#endif - - YV12_BUFFER_CONFIG *frame_to_show; - RefCntBuffer *prev_frame; - - // TODO(hkuang): Combine this with cur_buf in macroblockd. - RefCntBuffer *cur_frame; - - int ref_frame_map[REF_FRAMES]; /* maps fb_idx to reference slot */ - - // Prepare ref_frame_map for the next frame. - // Only used in frame parallel decode. - int next_ref_frame_map[REF_FRAMES]; - - // TODO(jkoleszar): could expand active_ref_idx to 4, with 0 as intra, and - // roll new_fb_idx into it. - - // Each frame can reference REFS_PER_FRAME buffers - RefBuffer frame_refs[REFS_PER_FRAME]; - - int new_fb_idx; - - int cur_show_frame_fb_idx; - -#if CONFIG_VP9_POSTPROC - YV12_BUFFER_CONFIG post_proc_buffer; - YV12_BUFFER_CONFIG post_proc_buffer_int; -#endif - - FRAME_TYPE last_frame_type; /* last frame's frame type for motion search.*/ - FRAME_TYPE frame_type; - - int show_frame; - int last_show_frame; - int show_existing_frame; - - // Flag signaling that the frame is encoded using only INTRA modes. - uint8_t intra_only; - uint8_t last_intra_only; - - int allow_high_precision_mv; - - // Flag signaling that the frame context should be reset to default values. - // 0 or 1 implies don't reset, 2 reset just the context specified in the - // frame header, 3 reset all contexts. - int reset_frame_context; - - // MBs, mb_rows/cols is in 16-pixel units; mi_rows/cols is in - // MODE_INFO (8-pixel) units. - int MBs; - int mb_rows, mi_rows; - int mb_cols, mi_cols; - int mi_stride; - - /* profile settings */ - TX_MODE tx_mode; - - int base_qindex; - int y_dc_delta_q; - int uv_dc_delta_q; - int uv_ac_delta_q; - int16_t y_dequant[MAX_SEGMENTS][2]; - int16_t uv_dequant[MAX_SEGMENTS][2]; - - /* We allocate a MODE_INFO struct for each macroblock, together with - an extra row on top and column on the left to simplify prediction. */ - int mi_alloc_size; - MODE_INFO *mip; /* Base of allocated array */ - MODE_INFO *mi; /* Corresponds to upper left visible macroblock */ - - // TODO(agrange): Move prev_mi into encoder structure. - // prev_mip and prev_mi will only be allocated in VP9 encoder. - MODE_INFO *prev_mip; /* MODE_INFO array 'mip' from last decoded frame */ - MODE_INFO *prev_mi; /* 'mi' from last frame (points into prev_mip) */ - - // Separate mi functions between encoder and decoder. - int (*alloc_mi)(struct VP9Common *cm, int mi_size); - void (*free_mi)(struct VP9Common *cm); - void (*setup_mi)(struct VP9Common *cm); - - // Grid of pointers to 8x8 MODE_INFO structs. Any 8x8 not in the visible - // area will be NULL. - MODE_INFO **mi_grid_base; - MODE_INFO **mi_grid_visible; - MODE_INFO **prev_mi_grid_base; - MODE_INFO **prev_mi_grid_visible; - - // Whether to use previous frame's motion vectors for prediction. - int use_prev_frame_mvs; - - // Persistent mb segment id map used in prediction. - int seg_map_idx; - int prev_seg_map_idx; - - uint8_t *seg_map_array[NUM_PING_PONG_BUFFERS]; - uint8_t *last_frame_seg_map; - uint8_t *current_frame_seg_map; - int seg_map_alloc_size; - - INTERP_FILTER interp_filter; - - loop_filter_info_n lf_info; - - int refresh_frame_context; /* Two state 0 = NO, 1 = YES */ - - int ref_frame_sign_bias[MAX_REF_FRAMES]; /* Two state 0, 1 */ - - struct loopfilter lf; - struct segmentation seg; - - // Context probabilities for reference frame prediction - MV_REFERENCE_FRAME comp_fixed_ref; - MV_REFERENCE_FRAME comp_var_ref[2]; - REFERENCE_MODE reference_mode; - - FRAME_CONTEXT *fc; /* this frame entropy */ - FRAME_CONTEXT *frame_contexts; // FRAME_CONTEXTS - unsigned int frame_context_idx; /* Context to use/update */ - FRAME_COUNTS counts; - - // TODO(angiebird): current_video_frame/current_frame_coding_index into a - // structure - unsigned int current_video_frame; - // Each show or no show frame is assigned with a coding index based on its - // coding order (starting from zero). - - // Current frame's coding index. - int current_frame_coding_index; - BITSTREAM_PROFILE profile; - - // VPX_BITS_8 in profile 0 or 1, VPX_BITS_10 or VPX_BITS_12 in profile 2 or 3. - vpx_bit_depth_t bit_depth; - vpx_bit_depth_t dequant_bit_depth; // bit_depth of current dequantizer - -#if CONFIG_VP9_POSTPROC - struct postproc_state postproc_state; -#endif - - int error_resilient_mode; - int frame_parallel_decoding_mode; - - int log2_tile_cols, log2_tile_rows; - int byte_alignment; - int skip_loop_filter; - - // External BufferPool passed from outside. - BufferPool *buffer_pool; - - PARTITION_CONTEXT *above_seg_context; - ENTROPY_CONTEXT *above_context; - int above_context_alloc_cols; - - int lf_row; -} VP9_COMMON; - -static INLINE void init_frame_indexes(VP9_COMMON *cm) { - cm->current_video_frame = 0; - cm->current_frame_coding_index = 0; -} - -static INLINE void update_frame_indexes(VP9_COMMON *cm, int show_frame) { - if (show_frame) { - // Don't increment frame counters if this was an altref buffer - // update not a real frame - ++cm->current_video_frame; - } - ++cm->current_frame_coding_index; -} - -typedef struct { - int frame_width; - int frame_height; - int render_frame_width; - int render_frame_height; - int mi_rows; - int mi_cols; - int mb_rows; - int mb_cols; - int num_mbs; - vpx_bit_depth_t bit_depth; -} FRAME_INFO; - -static INLINE void init_frame_info(FRAME_INFO *frame_info, - const VP9_COMMON *cm) { - frame_info->frame_width = cm->width; - frame_info->frame_height = cm->height; - frame_info->render_frame_width = cm->render_width; - frame_info->render_frame_height = cm->render_height; - frame_info->mi_cols = cm->mi_cols; - frame_info->mi_rows = cm->mi_rows; - frame_info->mb_cols = cm->mb_cols; - frame_info->mb_rows = cm->mb_rows; - frame_info->num_mbs = cm->MBs; - frame_info->bit_depth = cm->bit_depth; - // TODO(angiebird): Figure out how to get subsampling_x/y here -} - -static INLINE YV12_BUFFER_CONFIG *get_buf_frame(VP9_COMMON *cm, int index) { - if (index < 0 || index >= FRAME_BUFFERS) return NULL; - if (cm->error.error_code != VPX_CODEC_OK) return NULL; - return &cm->buffer_pool->frame_bufs[index].buf; -} - -static INLINE YV12_BUFFER_CONFIG *get_ref_frame(VP9_COMMON *cm, int index) { - if (index < 0 || index >= REF_FRAMES) return NULL; - if (cm->ref_frame_map[index] < 0) return NULL; - assert(cm->ref_frame_map[index] < FRAME_BUFFERS); - return &cm->buffer_pool->frame_bufs[cm->ref_frame_map[index]].buf; -} - -static INLINE YV12_BUFFER_CONFIG *get_frame_new_buffer(VP9_COMMON *cm) { - return &cm->buffer_pool->frame_bufs[cm->new_fb_idx].buf; -} - -static INLINE int get_free_fb(VP9_COMMON *cm) { - RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs; - int i; - - for (i = 0; i < FRAME_BUFFERS; ++i) - if (frame_bufs[i].ref_count == 0) break; - - if (i != FRAME_BUFFERS) { - frame_bufs[i].ref_count = 1; - } else { - // Reset i to be INVALID_IDX to indicate no free buffer found. - i = INVALID_IDX; - } - - return i; -} - -static INLINE void ref_cnt_fb(RefCntBuffer *bufs, int *idx, int new_idx) { - const int ref_index = *idx; - - if (ref_index >= 0 && bufs[ref_index].ref_count > 0) - bufs[ref_index].ref_count--; - - *idx = new_idx; - - bufs[new_idx].ref_count++; -} - -static INLINE int mi_cols_aligned_to_sb(int n_mis) { - return ALIGN_POWER_OF_TWO(n_mis, MI_BLOCK_SIZE_LOG2); -} - -static INLINE int frame_is_intra_only(const VP9_COMMON *const cm) { - return cm->frame_type == KEY_FRAME || cm->intra_only; -} - -static INLINE void set_partition_probs(const VP9_COMMON *const cm, - MACROBLOCKD *const xd) { - xd->partition_probs = - frame_is_intra_only(cm) - ? &vp9_kf_partition_probs[0] - : (const vpx_prob(*)[PARTITION_TYPES - 1]) cm->fc->partition_prob; -} - -static INLINE void vp9_init_macroblockd(VP9_COMMON *cm, MACROBLOCKD *xd, - tran_low_t *dqcoeff) { - int i; - - for (i = 0; i < MAX_MB_PLANE; ++i) { - xd->plane[i].dqcoeff = dqcoeff; - xd->above_context[i] = - cm->above_context + - i * sizeof(*cm->above_context) * 2 * mi_cols_aligned_to_sb(cm->mi_cols); - - if (get_plane_type(i) == PLANE_TYPE_Y) { - memcpy(xd->plane[i].seg_dequant, cm->y_dequant, sizeof(cm->y_dequant)); - } else { - memcpy(xd->plane[i].seg_dequant, cm->uv_dequant, sizeof(cm->uv_dequant)); - } - xd->fc = cm->fc; - } - - xd->above_seg_context = cm->above_seg_context; - xd->mi_stride = cm->mi_stride; - xd->error_info = &cm->error; - - set_partition_probs(cm, xd); -} - -static INLINE const vpx_prob *get_partition_probs(const MACROBLOCKD *xd, - int ctx) { - return xd->partition_probs[ctx]; -} - -static INLINE void set_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col) { - const int above_idx = mi_col * 2; - const int left_idx = (mi_row * 2) & 15; - int i; - for (i = 0; i < MAX_MB_PLANE; ++i) { - struct macroblockd_plane *const pd = &xd->plane[i]; - pd->above_context = &xd->above_context[i][above_idx >> pd->subsampling_x]; - pd->left_context = &xd->left_context[i][left_idx >> pd->subsampling_y]; - } -} - -static INLINE int calc_mi_size(int len) { - // len is in mi units. - return len + MI_BLOCK_SIZE; -} - -static INLINE void set_mi_row_col(MACROBLOCKD *xd, const TileInfo *const tile, - int mi_row, int bh, int mi_col, int bw, - int mi_rows, int mi_cols) { - xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8); - xd->mb_to_bottom_edge = ((mi_rows - bh - mi_row) * MI_SIZE) * 8; - xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8); - xd->mb_to_right_edge = ((mi_cols - bw - mi_col) * MI_SIZE) * 8; - - // Are edges available for intra prediction? - xd->above_mi = (mi_row != 0) ? xd->mi[-xd->mi_stride] : NULL; - xd->left_mi = (mi_col > tile->mi_col_start) ? xd->mi[-1] : NULL; -} - -static INLINE void update_partition_context(MACROBLOCKD *xd, int mi_row, - int mi_col, BLOCK_SIZE subsize, - BLOCK_SIZE bsize) { - PARTITION_CONTEXT *const above_ctx = xd->above_seg_context + mi_col; - PARTITION_CONTEXT *const left_ctx = xd->left_seg_context + (mi_row & MI_MASK); - - // num_4x4_blocks_wide_lookup[bsize] / 2 - const int bs = num_8x8_blocks_wide_lookup[bsize]; - - // update the partition context at the end notes. set partition bits - // of block sizes larger than the current one to be one, and partition - // bits of smaller block sizes to be zero. - memset(above_ctx, partition_context_lookup[subsize].above, bs); - memset(left_ctx, partition_context_lookup[subsize].left, bs); -} - -static INLINE int partition_plane_context(const MACROBLOCKD *xd, int mi_row, - int mi_col, BLOCK_SIZE bsize) { - const PARTITION_CONTEXT *above_ctx = xd->above_seg_context + mi_col; - const PARTITION_CONTEXT *left_ctx = xd->left_seg_context + (mi_row & MI_MASK); - const int bsl = mi_width_log2_lookup[bsize]; - int above = (*above_ctx >> bsl) & 1, left = (*left_ctx >> bsl) & 1; - - assert(b_width_log2_lookup[bsize] == b_height_log2_lookup[bsize]); - assert(bsl >= 0); - - return (left * 2 + above) + bsl * PARTITION_PLOFFSET; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_ONYXC_INT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_postproc.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_postproc.c deleted file mode 100644 index 96519f00..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_postproc.c +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "./vpx_config.h" -#include "./vpx_scale_rtcd.h" -#include "./vp9_rtcd.h" - -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/postproc.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/system_state.h" -#include "vpx_scale/vpx_scale.h" -#include "vpx_scale/yv12config.h" - -#include "vp9/common/vp9_onyxc_int.h" -#include "vp9/common/vp9_postproc.h" - -#if CONFIG_VP9_POSTPROC - -static const uint8_t q_diff_thresh = 20; -static const uint8_t last_q_thresh = 170; -extern const int16_t vpx_rv[]; - -#if CONFIG_VP9_HIGHBITDEPTH -static const int16_t kernel5[] = { 1, 1, 4, 1, 1 }; - -void vp9_highbd_post_proc_down_and_across_c(const uint16_t *src_ptr, - uint16_t *dst_ptr, - int src_pixels_per_line, - int dst_pixels_per_line, int rows, - int cols, int flimit) { - uint16_t const *p_src; - uint16_t *p_dst; - int row, col, i, v, kernel; - int pitch = src_pixels_per_line; - uint16_t d[8]; - - for (row = 0; row < rows; row++) { - // post_proc_down for one row. - p_src = src_ptr; - p_dst = dst_ptr; - - for (col = 0; col < cols; col++) { - kernel = 4; - v = p_src[col]; - - for (i = -2; i <= 2; i++) { - if (abs(v - p_src[col + i * pitch]) > flimit) goto down_skip_convolve; - - kernel += kernel5[2 + i] * p_src[col + i * pitch]; - } - - v = (kernel >> 3); - - down_skip_convolve: - p_dst[col] = v; - } - - /* now post_proc_across */ - p_src = dst_ptr; - p_dst = dst_ptr; - - for (i = 0; i < 8; i++) d[i] = p_src[i]; - - for (col = 0; col < cols; col++) { - kernel = 4; - v = p_src[col]; - - d[col & 7] = v; - - for (i = -2; i <= 2; i++) { - if (abs(v - p_src[col + i]) > flimit) goto across_skip_convolve; - - kernel += kernel5[2 + i] * p_src[col + i]; - } - - d[col & 7] = (kernel >> 3); - - across_skip_convolve: - if (col >= 2) p_dst[col - 2] = d[(col - 2) & 7]; - } - - /* handle the last two pixels */ - p_dst[col - 2] = d[(col - 2) & 7]; - p_dst[col - 1] = d[(col - 1) & 7]; - - /* next row */ - src_ptr += pitch; - dst_ptr += dst_pixels_per_line; - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static int q2mbl(int x) { - if (x < 20) x = 20; - - x = 50 + (x - 50) * 10 / 8; - return x * x / 3; -} - -#if CONFIG_VP9_HIGHBITDEPTH -void vp9_highbd_mbpost_proc_across_ip_c(uint16_t *src, int pitch, int rows, - int cols, int flimit) { - int r, c, i; - - uint16_t *s = src; - uint16_t d[16]; - - for (r = 0; r < rows; r++) { - int sumsq = 0; - int sum = 0; - - for (i = -8; i <= 6; i++) { - sumsq += s[i] * s[i]; - sum += s[i]; - d[i + 8] = 0; - } - - for (c = 0; c < cols + 8; c++) { - int x = s[c + 7] - s[c - 8]; - int y = s[c + 7] + s[c - 8]; - - sum += x; - sumsq += x * y; - - d[c & 15] = s[c]; - - if (sumsq * 15 - sum * sum < flimit) { - d[c & 15] = (8 + sum + s[c]) >> 4; - } - - s[c - 8] = d[(c - 8) & 15]; - } - - s += pitch; - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -#if CONFIG_VP9_HIGHBITDEPTH -void vp9_highbd_mbpost_proc_down_c(uint16_t *dst, int pitch, int rows, int cols, - int flimit) { - int r, c, i; - const int16_t *rv3 = &vpx_rv[63 & rand()]; // NOLINT - - for (c = 0; c < cols; c++) { - uint16_t *s = &dst[c]; - int sumsq = 0; - int sum = 0; - uint16_t d[16]; - const int16_t *rv2 = rv3 + ((c * 17) & 127); - - for (i = -8; i <= 6; i++) { - sumsq += s[i * pitch] * s[i * pitch]; - sum += s[i * pitch]; - } - - for (r = 0; r < rows + 8; r++) { - sumsq += s[7 * pitch] * s[7 * pitch] - s[-8 * pitch] * s[-8 * pitch]; - sum += s[7 * pitch] - s[-8 * pitch]; - d[r & 15] = s[0]; - - if (sumsq * 15 - sum * sum < flimit) { - d[r & 15] = (rv2[r & 127] + sum + s[0]) >> 4; - } - - s[-8 * pitch] = d[(r - 8) & 15]; - s += pitch; - } - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static void deblock_and_de_macro_block(VP9_COMMON *cm, - YV12_BUFFER_CONFIG *source, - YV12_BUFFER_CONFIG *post, int q, - int low_var_thresh, int flag, - uint8_t *limits) { - (void)low_var_thresh; - (void)flag; -#if CONFIG_VP9_HIGHBITDEPTH - if (source->flags & YV12_FLAG_HIGHBITDEPTH) { - double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065; - int ppl = (int)(level + .5); - vp9_highbd_post_proc_down_and_across( - CONVERT_TO_SHORTPTR(source->y_buffer), - CONVERT_TO_SHORTPTR(post->y_buffer), source->y_stride, post->y_stride, - source->y_height, source->y_width, ppl); - - vp9_highbd_mbpost_proc_across_ip(CONVERT_TO_SHORTPTR(post->y_buffer), - post->y_stride, post->y_height, - post->y_width, q2mbl(q)); - - vp9_highbd_mbpost_proc_down(CONVERT_TO_SHORTPTR(post->y_buffer), - post->y_stride, post->y_height, post->y_width, - q2mbl(q)); - - vp9_highbd_post_proc_down_and_across( - CONVERT_TO_SHORTPTR(source->u_buffer), - CONVERT_TO_SHORTPTR(post->u_buffer), source->uv_stride, post->uv_stride, - source->uv_height, source->uv_width, ppl); - vp9_highbd_post_proc_down_and_across( - CONVERT_TO_SHORTPTR(source->v_buffer), - CONVERT_TO_SHORTPTR(post->v_buffer), source->uv_stride, post->uv_stride, - source->uv_height, source->uv_width, ppl); - } else { -#endif // CONFIG_VP9_HIGHBITDEPTH - vp9_deblock(cm, source, post, q, limits); - vpx_mbpost_proc_across_ip(post->y_buffer, post->y_stride, post->y_height, - post->y_width, q2mbl(q)); - vpx_mbpost_proc_down(post->y_buffer, post->y_stride, post->y_height, - post->y_width, q2mbl(q)); -#if CONFIG_VP9_HIGHBITDEPTH - } -#endif // CONFIG_VP9_HIGHBITDEPTH -} - -void vp9_deblock(struct VP9Common *cm, const YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst, int q, uint8_t *limits) { - const int ppl = - (int)(6.0e-05 * q * q * q - 0.0067 * q * q + 0.306 * q + 0.0065 + 0.5); -#if CONFIG_VP9_HIGHBITDEPTH - if (src->flags & YV12_FLAG_HIGHBITDEPTH) { - int i; - const uint8_t *const srcs[3] = { src->y_buffer, src->u_buffer, - src->v_buffer }; - const int src_strides[3] = { src->y_stride, src->uv_stride, - src->uv_stride }; - const int src_widths[3] = { src->y_width, src->uv_width, src->uv_width }; - const int src_heights[3] = { src->y_height, src->uv_height, - src->uv_height }; - - uint8_t *const dsts[3] = { dst->y_buffer, dst->u_buffer, dst->v_buffer }; - const int dst_strides[3] = { dst->y_stride, dst->uv_stride, - dst->uv_stride }; - for (i = 0; i < MAX_MB_PLANE; ++i) { - vp9_highbd_post_proc_down_and_across( - CONVERT_TO_SHORTPTR(srcs[i]), CONVERT_TO_SHORTPTR(dsts[i]), - src_strides[i], dst_strides[i], src_heights[i], src_widths[i], ppl); - } - } else { -#endif // CONFIG_VP9_HIGHBITDEPTH - int mbr; - const int mb_rows = cm->mb_rows; - const int mb_cols = cm->mb_cols; - memset(limits, (unsigned char)ppl, 16 * mb_cols); - - for (mbr = 0; mbr < mb_rows; mbr++) { - vpx_post_proc_down_and_across_mb_row( - src->y_buffer + 16 * mbr * src->y_stride, - dst->y_buffer + 16 * mbr * dst->y_stride, src->y_stride, - dst->y_stride, src->y_width, limits, 16); - vpx_post_proc_down_and_across_mb_row( - src->u_buffer + 8 * mbr * src->uv_stride, - dst->u_buffer + 8 * mbr * dst->uv_stride, src->uv_stride, - dst->uv_stride, src->uv_width, limits, 8); - vpx_post_proc_down_and_across_mb_row( - src->v_buffer + 8 * mbr * src->uv_stride, - dst->v_buffer + 8 * mbr * dst->uv_stride, src->uv_stride, - dst->uv_stride, src->uv_width, limits, 8); - } -#if CONFIG_VP9_HIGHBITDEPTH - } -#endif // CONFIG_VP9_HIGHBITDEPTH -} - -void vp9_denoise(struct VP9Common *cm, const YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst, int q, uint8_t *limits) { - vp9_deblock(cm, src, dst, q, limits); -} - -static void swap_mi_and_prev_mi(VP9_COMMON *cm) { - // Current mip will be the prev_mip for the next frame. - MODE_INFO *temp = cm->postproc_state.prev_mip; - cm->postproc_state.prev_mip = cm->mip; - cm->mip = temp; - - // Update the upper left visible macroblock ptrs. - cm->mi = cm->mip + cm->mi_stride + 1; - cm->postproc_state.prev_mi = cm->postproc_state.prev_mip + cm->mi_stride + 1; -} - -int vp9_post_proc_frame(struct VP9Common *cm, YV12_BUFFER_CONFIG *dest, - vp9_ppflags_t *ppflags, int unscaled_width) { - const int q = VPXMIN(105, cm->lf.filter_level * 2); - const int flags = ppflags->post_proc_flag; - YV12_BUFFER_CONFIG *const ppbuf = &cm->post_proc_buffer; - struct postproc_state *const ppstate = &cm->postproc_state; - - if (!cm->frame_to_show) return -1; - - if (!flags) { - *dest = *cm->frame_to_show; - return 0; - } - - vpx_clear_system_state(); - - // Alloc memory for prev_mip in the first frame. - if (cm->current_video_frame == 1) { - ppstate->last_base_qindex = cm->base_qindex; - ppstate->last_frame_valid = 1; - } - - if ((flags & VP9D_MFQE) && ppstate->prev_mip == NULL) { - ppstate->prev_mip = vpx_calloc(cm->mi_alloc_size, sizeof(*cm->mip)); - if (!ppstate->prev_mip) { - return 1; - } - ppstate->prev_mi = ppstate->prev_mip + cm->mi_stride + 1; - } - - // Allocate post_proc_buffer_int if needed. - if ((flags & VP9D_MFQE) && !cm->post_proc_buffer_int.buffer_alloc) { - if ((flags & VP9D_DEMACROBLOCK) || (flags & VP9D_DEBLOCK)) { - const int width = ALIGN_POWER_OF_TWO(cm->width, 4); - const int height = ALIGN_POWER_OF_TWO(cm->height, 4); - - if (vpx_alloc_frame_buffer(&cm->post_proc_buffer_int, width, height, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif // CONFIG_VP9_HIGHBITDEPTH - VP9_ENC_BORDER_IN_PIXELS, - cm->byte_alignment) < 0) { - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate MFQE framebuffer"); - } - - // Ensure that postproc is set to all 0s so that post proc - // doesn't pull random data in from edge. - memset(cm->post_proc_buffer_int.buffer_alloc, 128, - cm->post_proc_buffer.frame_size); - } - } - - if (vpx_realloc_frame_buffer(&cm->post_proc_buffer, cm->width, cm->height, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_DEC_BORDER_IN_PIXELS, cm->byte_alignment, - NULL, NULL, NULL) < 0) - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate post-processing buffer"); - - if (flags & (VP9D_DEMACROBLOCK | VP9D_DEBLOCK)) { - if (!cm->postproc_state.limits) { - cm->postproc_state.limits = - vpx_calloc(unscaled_width, sizeof(*cm->postproc_state.limits)); - if (!cm->postproc_state.limits) return 1; - } - } - - if (flags & VP9D_ADDNOISE) { - if (!cm->postproc_state.generated_noise) { - cm->postproc_state.generated_noise = vpx_calloc( - cm->width + 256, sizeof(*cm->postproc_state.generated_noise)); - if (!cm->postproc_state.generated_noise) return 1; - } - } - - if ((flags & VP9D_MFQE) && cm->current_video_frame >= 2 && - ppstate->last_frame_valid && cm->bit_depth == 8 && - ppstate->last_base_qindex <= last_q_thresh && - cm->base_qindex - ppstate->last_base_qindex >= q_diff_thresh) { - vp9_mfqe(cm); - // TODO(jackychen): Consider whether enable deblocking by default - // if mfqe is enabled. Need to take both the quality and the speed - // into consideration. - if ((flags & VP9D_DEMACROBLOCK) || (flags & VP9D_DEBLOCK)) { - vpx_yv12_copy_frame(ppbuf, &cm->post_proc_buffer_int); - } - if ((flags & VP9D_DEMACROBLOCK) && cm->post_proc_buffer_int.buffer_alloc) { - deblock_and_de_macro_block(cm, &cm->post_proc_buffer_int, ppbuf, - q + (ppflags->deblocking_level - 5) * 10, 1, 0, - cm->postproc_state.limits); - } else if (flags & VP9D_DEBLOCK) { - vp9_deblock(cm, &cm->post_proc_buffer_int, ppbuf, q, - cm->postproc_state.limits); - } else { - vpx_yv12_copy_frame(&cm->post_proc_buffer_int, ppbuf); - } - } else if (flags & VP9D_DEMACROBLOCK) { - deblock_and_de_macro_block(cm, cm->frame_to_show, ppbuf, - q + (ppflags->deblocking_level - 5) * 10, 1, 0, - cm->postproc_state.limits); - } else if (flags & VP9D_DEBLOCK) { - vp9_deblock(cm, cm->frame_to_show, ppbuf, q, cm->postproc_state.limits); - } else { - vpx_yv12_copy_frame(cm->frame_to_show, ppbuf); - } - - ppstate->last_base_qindex = cm->base_qindex; - ppstate->last_frame_valid = 1; - if (flags & VP9D_ADDNOISE) { - const int noise_level = ppflags->noise_level; - if (ppstate->last_q != q || ppstate->last_noise != noise_level) { - double sigma; - vpx_clear_system_state(); - sigma = noise_level + .5 + .6 * q / 63.0; - ppstate->clamp = - vpx_setup_noise(sigma, ppstate->generated_noise, cm->width + 256); - ppstate->last_q = q; - ppstate->last_noise = noise_level; - } - vpx_plane_add_noise(ppbuf->y_buffer, ppstate->generated_noise, - ppstate->clamp, ppstate->clamp, ppbuf->y_width, - ppbuf->y_height, ppbuf->y_stride); - } - - *dest = *ppbuf; - - /* handle problem with extending borders */ - dest->y_width = cm->width; - dest->y_height = cm->height; - dest->uv_width = dest->y_width >> cm->subsampling_x; - dest->uv_height = dest->y_height >> cm->subsampling_y; - - if (flags & VP9D_MFQE) swap_mi_and_prev_mi(cm); - return 0; -} -#endif // CONFIG_VP9_POSTPROC diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_postproc.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_postproc.h deleted file mode 100644 index bbe3aed8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_postproc.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_POSTPROC_H_ -#define VPX_VP9_COMMON_VP9_POSTPROC_H_ - -#include "vpx_ports/mem.h" -#include "vpx_scale/yv12config.h" -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_mfqe.h" -#include "vp9/common/vp9_ppflags.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct postproc_state { - int last_q; - int last_noise; - int last_base_qindex; - int last_frame_valid; - MODE_INFO *prev_mip; - MODE_INFO *prev_mi; - int clamp; - uint8_t *limits; - int8_t *generated_noise; -}; - -struct VP9Common; - -#define MFQE_PRECISION 4 - -int vp9_post_proc_frame(struct VP9Common *cm, YV12_BUFFER_CONFIG *dest, - vp9_ppflags_t *ppflags, int unscaled_width); - -void vp9_denoise(struct VP9Common *cm, const YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst, int q, uint8_t *limits); - -void vp9_deblock(struct VP9Common *cm, const YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst, int q, uint8_t *limits); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_POSTPROC_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_ppflags.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_ppflags.h deleted file mode 100644 index a0e30176..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_ppflags.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_PPFLAGS_H_ -#define VPX_VP9_COMMON_VP9_PPFLAGS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - VP9D_NOFILTERING = 0, - VP9D_DEBLOCK = 1 << 0, - VP9D_DEMACROBLOCK = 1 << 1, - VP9D_ADDNOISE = 1 << 2, - VP9D_MFQE = 1 << 3 -}; - -typedef struct { - int post_proc_flag; - int deblocking_level; - int noise_level; -} vp9_ppflags_t; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_PPFLAGS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_pred_common.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_pred_common.c deleted file mode 100644 index 375cb4d7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_pred_common.c +++ /dev/null @@ -1,316 +0,0 @@ - -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_pred_common.h" -#include "vp9/common/vp9_seg_common.h" - -int vp9_compound_reference_allowed(const VP9_COMMON *cm) { - int i; - for (i = 1; i < REFS_PER_FRAME; ++i) - if (cm->ref_frame_sign_bias[i + 1] != cm->ref_frame_sign_bias[1]) return 1; - - return 0; -} - -void vp9_setup_compound_reference_mode(VP9_COMMON *cm) { - if (cm->ref_frame_sign_bias[LAST_FRAME] == - cm->ref_frame_sign_bias[GOLDEN_FRAME]) { - cm->comp_fixed_ref = ALTREF_FRAME; - cm->comp_var_ref[0] = LAST_FRAME; - cm->comp_var_ref[1] = GOLDEN_FRAME; - } else if (cm->ref_frame_sign_bias[LAST_FRAME] == - cm->ref_frame_sign_bias[ALTREF_FRAME]) { - cm->comp_fixed_ref = GOLDEN_FRAME; - cm->comp_var_ref[0] = LAST_FRAME; - cm->comp_var_ref[1] = ALTREF_FRAME; - } else { - cm->comp_fixed_ref = LAST_FRAME; - cm->comp_var_ref[0] = GOLDEN_FRAME; - cm->comp_var_ref[1] = ALTREF_FRAME; - } -} - -int vp9_get_reference_mode_context(const VP9_COMMON *cm, - const MACROBLOCKD *xd) { - int ctx; - const MODE_INFO *const above_mi = xd->above_mi; - const MODE_INFO *const left_mi = xd->left_mi; - const int has_above = !!above_mi; - const int has_left = !!left_mi; - // Note: - // The mode info data structure has a one element border above and to the - // left of the entries corresponding to real macroblocks. - // The prediction flags in these dummy entries are initialized to 0. - if (has_above && has_left) { // both edges available - if (!has_second_ref(above_mi) && !has_second_ref(left_mi)) - // neither edge uses comp pred (0/1) - ctx = (above_mi->ref_frame[0] == cm->comp_fixed_ref) ^ - (left_mi->ref_frame[0] == cm->comp_fixed_ref); - else if (!has_second_ref(above_mi)) - // one of two edges uses comp pred (2/3) - ctx = 2 + (above_mi->ref_frame[0] == cm->comp_fixed_ref || - !is_inter_block(above_mi)); - else if (!has_second_ref(left_mi)) - // one of two edges uses comp pred (2/3) - ctx = 2 + (left_mi->ref_frame[0] == cm->comp_fixed_ref || - !is_inter_block(left_mi)); - else // both edges use comp pred (4) - ctx = 4; - } else if (has_above || has_left) { // one edge available - const MODE_INFO *edge_mi = has_above ? above_mi : left_mi; - - if (!has_second_ref(edge_mi)) - // edge does not use comp pred (0/1) - ctx = edge_mi->ref_frame[0] == cm->comp_fixed_ref; - else - // edge uses comp pred (3) - ctx = 3; - } else { // no edges available (1) - ctx = 1; - } - assert(ctx >= 0 && ctx < COMP_INTER_CONTEXTS); - return ctx; -} - -// Returns a context number for the given MB prediction signal -int vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm, - const MACROBLOCKD *xd) { - int pred_context; - const MODE_INFO *const above_mi = xd->above_mi; - const MODE_INFO *const left_mi = xd->left_mi; - const int above_in_image = !!above_mi; - const int left_in_image = !!left_mi; - - // Note: - // The mode info data structure has a one element border above and to the - // left of the entries corresponding to real macroblocks. - // The prediction flags in these dummy entries are initialized to 0. - const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref]; - const int var_ref_idx = !fix_ref_idx; - - if (above_in_image && left_in_image) { // both edges available - const int above_intra = !is_inter_block(above_mi); - const int left_intra = !is_inter_block(left_mi); - - if (above_intra && left_intra) { // intra/intra (2) - pred_context = 2; - } else if (above_intra || left_intra) { // intra/inter - const MODE_INFO *edge_mi = above_intra ? left_mi : above_mi; - - if (!has_second_ref(edge_mi)) // single pred (1/3) - pred_context = 1 + 2 * (edge_mi->ref_frame[0] != cm->comp_var_ref[1]); - else // comp pred (1/3) - pred_context = - 1 + 2 * (edge_mi->ref_frame[var_ref_idx] != cm->comp_var_ref[1]); - } else { // inter/inter - const int l_sg = !has_second_ref(left_mi); - const int a_sg = !has_second_ref(above_mi); - const MV_REFERENCE_FRAME vrfa = - a_sg ? above_mi->ref_frame[0] : above_mi->ref_frame[var_ref_idx]; - const MV_REFERENCE_FRAME vrfl = - l_sg ? left_mi->ref_frame[0] : left_mi->ref_frame[var_ref_idx]; - - if (vrfa == vrfl && cm->comp_var_ref[1] == vrfa) { - pred_context = 0; - } else if (l_sg && a_sg) { // single/single - if ((vrfa == cm->comp_fixed_ref && vrfl == cm->comp_var_ref[0]) || - (vrfl == cm->comp_fixed_ref && vrfa == cm->comp_var_ref[0])) - pred_context = 4; - else if (vrfa == vrfl) - pred_context = 3; - else - pred_context = 1; - } else if (l_sg || a_sg) { // single/comp - const MV_REFERENCE_FRAME vrfc = l_sg ? vrfa : vrfl; - const MV_REFERENCE_FRAME rfs = a_sg ? vrfa : vrfl; - if (vrfc == cm->comp_var_ref[1] && rfs != cm->comp_var_ref[1]) - pred_context = 1; - else if (rfs == cm->comp_var_ref[1] && vrfc != cm->comp_var_ref[1]) - pred_context = 2; - else - pred_context = 4; - } else if (vrfa == vrfl) { // comp/comp - pred_context = 4; - } else { - pred_context = 2; - } - } - } else if (above_in_image || left_in_image) { // one edge available - const MODE_INFO *edge_mi = above_in_image ? above_mi : left_mi; - - if (!is_inter_block(edge_mi)) { - pred_context = 2; - } else { - if (has_second_ref(edge_mi)) - pred_context = - 4 * (edge_mi->ref_frame[var_ref_idx] != cm->comp_var_ref[1]); - else - pred_context = 3 * (edge_mi->ref_frame[0] != cm->comp_var_ref[1]); - } - } else { // no edges available (2) - pred_context = 2; - } - assert(pred_context >= 0 && pred_context < REF_CONTEXTS); - - return pred_context; -} - -int vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) { - int pred_context; - const MODE_INFO *const above_mi = xd->above_mi; - const MODE_INFO *const left_mi = xd->left_mi; - const int has_above = !!above_mi; - const int has_left = !!left_mi; - // Note: - // The mode info data structure has a one element border above and to the - // left of the entries corresponding to real macroblocks. - // The prediction flags in these dummy entries are initialized to 0. - if (has_above && has_left) { // both edges available - const int above_intra = !is_inter_block(above_mi); - const int left_intra = !is_inter_block(left_mi); - - if (above_intra && left_intra) { // intra/intra - pred_context = 2; - } else if (above_intra || left_intra) { // intra/inter or inter/intra - const MODE_INFO *edge_mi = above_intra ? left_mi : above_mi; - if (!has_second_ref(edge_mi)) - pred_context = 4 * (edge_mi->ref_frame[0] == LAST_FRAME); - else - pred_context = 1 + (edge_mi->ref_frame[0] == LAST_FRAME || - edge_mi->ref_frame[1] == LAST_FRAME); - } else { // inter/inter - const int above_has_second = has_second_ref(above_mi); - const int left_has_second = has_second_ref(left_mi); - const MV_REFERENCE_FRAME above0 = above_mi->ref_frame[0]; - const MV_REFERENCE_FRAME above1 = above_mi->ref_frame[1]; - const MV_REFERENCE_FRAME left0 = left_mi->ref_frame[0]; - const MV_REFERENCE_FRAME left1 = left_mi->ref_frame[1]; - - if (above_has_second && left_has_second) { - pred_context = 1 + (above0 == LAST_FRAME || above1 == LAST_FRAME || - left0 == LAST_FRAME || left1 == LAST_FRAME); - } else if (above_has_second || left_has_second) { - const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0; - const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0; - const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1; - - if (rfs == LAST_FRAME) - pred_context = 3 + (crf1 == LAST_FRAME || crf2 == LAST_FRAME); - else - pred_context = (crf1 == LAST_FRAME || crf2 == LAST_FRAME); - } else { - pred_context = 2 * (above0 == LAST_FRAME) + 2 * (left0 == LAST_FRAME); - } - } - } else if (has_above || has_left) { // one edge available - const MODE_INFO *edge_mi = has_above ? above_mi : left_mi; - if (!is_inter_block(edge_mi)) { // intra - pred_context = 2; - } else { // inter - if (!has_second_ref(edge_mi)) - pred_context = 4 * (edge_mi->ref_frame[0] == LAST_FRAME); - else - pred_context = 1 + (edge_mi->ref_frame[0] == LAST_FRAME || - edge_mi->ref_frame[1] == LAST_FRAME); - } - } else { // no edges available - pred_context = 2; - } - - assert(pred_context >= 0 && pred_context < REF_CONTEXTS); - return pred_context; -} - -int vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) { - int pred_context; - const MODE_INFO *const above_mi = xd->above_mi; - const MODE_INFO *const left_mi = xd->left_mi; - const int has_above = !!above_mi; - const int has_left = !!left_mi; - - // Note: - // The mode info data structure has a one element border above and to the - // left of the entries corresponding to real macroblocks. - // The prediction flags in these dummy entries are initialized to 0. - if (has_above && has_left) { // both edges available - const int above_intra = !is_inter_block(above_mi); - const int left_intra = !is_inter_block(left_mi); - - if (above_intra && left_intra) { // intra/intra - pred_context = 2; - } else if (above_intra || left_intra) { // intra/inter or inter/intra - const MODE_INFO *edge_mi = above_intra ? left_mi : above_mi; - if (!has_second_ref(edge_mi)) { - if (edge_mi->ref_frame[0] == LAST_FRAME) - pred_context = 3; - else - pred_context = 4 * (edge_mi->ref_frame[0] == GOLDEN_FRAME); - } else { - pred_context = 1 + 2 * (edge_mi->ref_frame[0] == GOLDEN_FRAME || - edge_mi->ref_frame[1] == GOLDEN_FRAME); - } - } else { // inter/inter - const int above_has_second = has_second_ref(above_mi); - const int left_has_second = has_second_ref(left_mi); - const MV_REFERENCE_FRAME above0 = above_mi->ref_frame[0]; - const MV_REFERENCE_FRAME above1 = above_mi->ref_frame[1]; - const MV_REFERENCE_FRAME left0 = left_mi->ref_frame[0]; - const MV_REFERENCE_FRAME left1 = left_mi->ref_frame[1]; - - if (above_has_second && left_has_second) { - if (above0 == left0 && above1 == left1) - pred_context = - 3 * (above0 == GOLDEN_FRAME || above1 == GOLDEN_FRAME || - left0 == GOLDEN_FRAME || left1 == GOLDEN_FRAME); - else - pred_context = 2; - } else if (above_has_second || left_has_second) { - const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0; - const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0; - const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1; - - if (rfs == GOLDEN_FRAME) - pred_context = 3 + (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME); - else if (rfs == ALTREF_FRAME) - pred_context = crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME; - else - pred_context = 1 + 2 * (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME); - } else { - if (above0 == LAST_FRAME && left0 == LAST_FRAME) { - pred_context = 3; - } else if (above0 == LAST_FRAME || left0 == LAST_FRAME) { - const MV_REFERENCE_FRAME edge0 = - (above0 == LAST_FRAME) ? left0 : above0; - pred_context = 4 * (edge0 == GOLDEN_FRAME); - } else { - pred_context = - 2 * (above0 == GOLDEN_FRAME) + 2 * (left0 == GOLDEN_FRAME); - } - } - } - } else if (has_above || has_left) { // one edge available - const MODE_INFO *edge_mi = has_above ? above_mi : left_mi; - - if (!is_inter_block(edge_mi) || - (edge_mi->ref_frame[0] == LAST_FRAME && !has_second_ref(edge_mi))) - pred_context = 2; - else if (!has_second_ref(edge_mi)) - pred_context = 4 * (edge_mi->ref_frame[0] == GOLDEN_FRAME); - else - pred_context = 3 * (edge_mi->ref_frame[0] == GOLDEN_FRAME || - edge_mi->ref_frame[1] == GOLDEN_FRAME); - } else { // no edges available (2) - pred_context = 2; - } - assert(pred_context >= 0 && pred_context < REF_CONTEXTS); - return pred_context; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_pred_common.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_pred_common.h deleted file mode 100644 index ee596693..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_pred_common.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_PRED_COMMON_H_ -#define VPX_VP9_COMMON_VP9_PRED_COMMON_H_ - -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_onyxc_int.h" -#include "vpx_dsp/vpx_dsp_common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -static INLINE int get_segment_id(const VP9_COMMON *cm, - const uint8_t *segment_ids, BLOCK_SIZE bsize, - int mi_row, int mi_col) { - const int mi_offset = mi_row * cm->mi_cols + mi_col; - const int bw = num_8x8_blocks_wide_lookup[bsize]; - const int bh = num_8x8_blocks_high_lookup[bsize]; - const int xmis = VPXMIN(cm->mi_cols - mi_col, bw); - const int ymis = VPXMIN(cm->mi_rows - mi_row, bh); - int x, y, segment_id = MAX_SEGMENTS; - - for (y = 0; y < ymis; ++y) - for (x = 0; x < xmis; ++x) - segment_id = - VPXMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]); - - assert(segment_id >= 0 && segment_id < MAX_SEGMENTS); - return segment_id; -} - -static INLINE int vp9_get_pred_context_seg_id(const MACROBLOCKD *xd) { - const MODE_INFO *const above_mi = xd->above_mi; - const MODE_INFO *const left_mi = xd->left_mi; - const int above_sip = (above_mi != NULL) ? above_mi->seg_id_predicted : 0; - const int left_sip = (left_mi != NULL) ? left_mi->seg_id_predicted : 0; - - return above_sip + left_sip; -} - -static INLINE vpx_prob vp9_get_pred_prob_seg_id(const struct segmentation *seg, - const MACROBLOCKD *xd) { - return seg->pred_probs[vp9_get_pred_context_seg_id(xd)]; -} - -static INLINE int vp9_get_skip_context(const MACROBLOCKD *xd) { - const MODE_INFO *const above_mi = xd->above_mi; - const MODE_INFO *const left_mi = xd->left_mi; - const int above_skip = (above_mi != NULL) ? above_mi->skip : 0; - const int left_skip = (left_mi != NULL) ? left_mi->skip : 0; - return above_skip + left_skip; -} - -static INLINE vpx_prob vp9_get_skip_prob(const VP9_COMMON *cm, - const MACROBLOCKD *xd) { - return cm->fc->skip_probs[vp9_get_skip_context(xd)]; -} - -// Returns a context number for the given MB prediction signal -static INLINE int get_pred_context_switchable_interp(const MACROBLOCKD *xd) { - // Note: - // The mode info data structure has a one element border above and to the - // left of the entries corresponding to real macroblocks. - // The prediction flags in these dummy entries are initialized to 0. - const MODE_INFO *const left_mi = xd->left_mi; - const int left_type = left_mi ? left_mi->interp_filter : SWITCHABLE_FILTERS; - const MODE_INFO *const above_mi = xd->above_mi; - const int above_type = - above_mi ? above_mi->interp_filter : SWITCHABLE_FILTERS; - - if (left_type == above_type) - return left_type; - else if (left_type == SWITCHABLE_FILTERS) - return above_type; - else if (above_type == SWITCHABLE_FILTERS) - return left_type; - else - return SWITCHABLE_FILTERS; -} - -// The mode info data structure has a one element border above and to the -// left of the entries corresponding to real macroblocks. -// The prediction flags in these dummy entries are initialized to 0. -// 0 - inter/inter, inter/--, --/inter, --/-- -// 1 - intra/inter, inter/intra -// 2 - intra/--, --/intra -// 3 - intra/intra -static INLINE int get_intra_inter_context(const MACROBLOCKD *xd) { - const MODE_INFO *const above_mi = xd->above_mi; - const MODE_INFO *const left_mi = xd->left_mi; - const int has_above = !!above_mi; - const int has_left = !!left_mi; - - if (has_above && has_left) { // both edges available - const int above_intra = !is_inter_block(above_mi); - const int left_intra = !is_inter_block(left_mi); - return left_intra && above_intra ? 3 : left_intra || above_intra; - } else if (has_above || has_left) { // one edge available - return 2 * !is_inter_block(has_above ? above_mi : left_mi); - } - return 0; -} - -static INLINE vpx_prob vp9_get_intra_inter_prob(const VP9_COMMON *cm, - const MACROBLOCKD *xd) { - return cm->fc->intra_inter_prob[get_intra_inter_context(xd)]; -} - -int vp9_get_reference_mode_context(const VP9_COMMON *cm, const MACROBLOCKD *xd); - -static INLINE vpx_prob vp9_get_reference_mode_prob(const VP9_COMMON *cm, - const MACROBLOCKD *xd) { - return cm->fc->comp_inter_prob[vp9_get_reference_mode_context(cm, xd)]; -} - -int vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm, - const MACROBLOCKD *xd); - -static INLINE vpx_prob vp9_get_pred_prob_comp_ref_p(const VP9_COMMON *cm, - const MACROBLOCKD *xd) { - const int pred_context = vp9_get_pred_context_comp_ref_p(cm, xd); - return cm->fc->comp_ref_prob[pred_context]; -} - -int vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd); - -static INLINE vpx_prob vp9_get_pred_prob_single_ref_p1(const VP9_COMMON *cm, - const MACROBLOCKD *xd) { - return cm->fc->single_ref_prob[vp9_get_pred_context_single_ref_p1(xd)][0]; -} - -int vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd); - -static INLINE vpx_prob vp9_get_pred_prob_single_ref_p2(const VP9_COMMON *cm, - const MACROBLOCKD *xd) { - return cm->fc->single_ref_prob[vp9_get_pred_context_single_ref_p2(xd)][1]; -} - -int vp9_compound_reference_allowed(const VP9_COMMON *cm); - -void vp9_setup_compound_reference_mode(VP9_COMMON *cm); - -// Returns a context number for the given MB prediction signal -// The mode info data structure has a one element border above and to the -// left of the entries corresponding to real blocks. -// The prediction flags in these dummy entries are initialized to 0. -static INLINE int get_tx_size_context(const MACROBLOCKD *xd) { - const int max_tx_size = max_txsize_lookup[xd->mi[0]->sb_type]; - const MODE_INFO *const above_mi = xd->above_mi; - const MODE_INFO *const left_mi = xd->left_mi; - const int has_above = !!above_mi; - const int has_left = !!left_mi; - int above_ctx = - (has_above && !above_mi->skip) ? (int)above_mi->tx_size : max_tx_size; - int left_ctx = - (has_left && !left_mi->skip) ? (int)left_mi->tx_size : max_tx_size; - if (!has_left) left_ctx = above_ctx; - - if (!has_above) above_ctx = left_ctx; - - return (above_ctx + left_ctx) > max_tx_size; -} - -static INLINE const vpx_prob *get_tx_probs(TX_SIZE max_tx_size, int ctx, - const struct tx_probs *tx_probs) { - switch (max_tx_size) { - case TX_8X8: return tx_probs->p8x8[ctx]; - case TX_16X16: return tx_probs->p16x16[ctx]; - case TX_32X32: return tx_probs->p32x32[ctx]; - default: assert(0 && "Invalid max_tx_size."); return NULL; - } -} - -static INLINE unsigned int *get_tx_counts(TX_SIZE max_tx_size, int ctx, - struct tx_counts *tx_counts) { - switch (max_tx_size) { - case TX_8X8: return tx_counts->p8x8[ctx]; - case TX_16X16: return tx_counts->p16x16[ctx]; - case TX_32X32: return tx_counts->p32x32[ctx]; - default: assert(0 && "Invalid max_tx_size."); return NULL; - } -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_PRED_COMMON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_quant_common.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_quant_common.c deleted file mode 100644 index 1dc18dc6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_quant_common.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_quant_common.h" -#include "vp9/common/vp9_seg_common.h" - -static const int16_t dc_qlookup[QINDEX_RANGE] = { - 4, 8, 8, 9, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, - 19, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 28, 29, 30, - 31, 32, 32, 33, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42, - 43, 43, 44, 45, 46, 47, 48, 48, 49, 50, 51, 52, 53, 53, - 54, 55, 56, 57, 57, 58, 59, 60, 61, 62, 62, 63, 64, 65, - 66, 66, 67, 68, 69, 70, 70, 71, 72, 73, 74, 74, 75, 76, - 77, 78, 78, 79, 80, 81, 81, 82, 83, 84, 85, 85, 87, 88, - 90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 108, 110, - 111, 113, 114, 116, 117, 118, 120, 121, 123, 125, 127, 129, 131, 134, - 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 161, 164, - 166, 169, 172, 174, 177, 180, 182, 185, 187, 190, 192, 195, 199, 202, - 205, 208, 211, 214, 217, 220, 223, 226, 230, 233, 237, 240, 243, 247, - 250, 253, 257, 261, 265, 269, 272, 276, 280, 284, 288, 292, 296, 300, - 304, 309, 313, 317, 322, 326, 330, 335, 340, 344, 349, 354, 359, 364, - 369, 374, 379, 384, 389, 395, 400, 406, 411, 417, 423, 429, 435, 441, - 447, 454, 461, 467, 475, 482, 489, 497, 505, 513, 522, 530, 539, 549, - 559, 569, 579, 590, 602, 614, 626, 640, 654, 668, 684, 700, 717, 736, - 755, 775, 796, 819, 843, 869, 896, 925, 955, 988, 1022, 1058, 1098, 1139, - 1184, 1232, 1282, 1336, -}; - -#if CONFIG_VP9_HIGHBITDEPTH -static const int16_t dc_qlookup_10[QINDEX_RANGE] = { - 4, 9, 10, 13, 15, 17, 20, 22, 25, 28, 31, 34, 37, - 40, 43, 47, 50, 53, 57, 60, 64, 68, 71, 75, 78, 82, - 86, 90, 93, 97, 101, 105, 109, 113, 116, 120, 124, 128, 132, - 136, 140, 143, 147, 151, 155, 159, 163, 166, 170, 174, 178, 182, - 185, 189, 193, 197, 200, 204, 208, 212, 215, 219, 223, 226, 230, - 233, 237, 241, 244, 248, 251, 255, 259, 262, 266, 269, 273, 276, - 280, 283, 287, 290, 293, 297, 300, 304, 307, 310, 314, 317, 321, - 324, 327, 331, 334, 337, 343, 350, 356, 362, 369, 375, 381, 387, - 394, 400, 406, 412, 418, 424, 430, 436, 442, 448, 454, 460, 466, - 472, 478, 484, 490, 499, 507, 516, 525, 533, 542, 550, 559, 567, - 576, 584, 592, 601, 609, 617, 625, 634, 644, 655, 666, 676, 687, - 698, 708, 718, 729, 739, 749, 759, 770, 782, 795, 807, 819, 831, - 844, 856, 868, 880, 891, 906, 920, 933, 947, 961, 975, 988, 1001, - 1015, 1030, 1045, 1061, 1076, 1090, 1105, 1120, 1137, 1153, 1170, 1186, 1202, - 1218, 1236, 1253, 1271, 1288, 1306, 1323, 1342, 1361, 1379, 1398, 1416, 1436, - 1456, 1476, 1496, 1516, 1537, 1559, 1580, 1601, 1624, 1647, 1670, 1692, 1717, - 1741, 1766, 1791, 1817, 1844, 1871, 1900, 1929, 1958, 1990, 2021, 2054, 2088, - 2123, 2159, 2197, 2236, 2276, 2319, 2363, 2410, 2458, 2508, 2561, 2616, 2675, - 2737, 2802, 2871, 2944, 3020, 3102, 3188, 3280, 3375, 3478, 3586, 3702, 3823, - 3953, 4089, 4236, 4394, 4559, 4737, 4929, 5130, 5347, -}; - -static const int16_t dc_qlookup_12[QINDEX_RANGE] = { - 4, 12, 18, 25, 33, 41, 50, 60, 70, 80, 91, - 103, 115, 127, 140, 153, 166, 180, 194, 208, 222, 237, - 251, 266, 281, 296, 312, 327, 343, 358, 374, 390, 405, - 421, 437, 453, 469, 484, 500, 516, 532, 548, 564, 580, - 596, 611, 627, 643, 659, 674, 690, 706, 721, 737, 752, - 768, 783, 798, 814, 829, 844, 859, 874, 889, 904, 919, - 934, 949, 964, 978, 993, 1008, 1022, 1037, 1051, 1065, 1080, - 1094, 1108, 1122, 1136, 1151, 1165, 1179, 1192, 1206, 1220, 1234, - 1248, 1261, 1275, 1288, 1302, 1315, 1329, 1342, 1368, 1393, 1419, - 1444, 1469, 1494, 1519, 1544, 1569, 1594, 1618, 1643, 1668, 1692, - 1717, 1741, 1765, 1789, 1814, 1838, 1862, 1885, 1909, 1933, 1957, - 1992, 2027, 2061, 2096, 2130, 2165, 2199, 2233, 2267, 2300, 2334, - 2367, 2400, 2434, 2467, 2499, 2532, 2575, 2618, 2661, 2704, 2746, - 2788, 2830, 2872, 2913, 2954, 2995, 3036, 3076, 3127, 3177, 3226, - 3275, 3324, 3373, 3421, 3469, 3517, 3565, 3621, 3677, 3733, 3788, - 3843, 3897, 3951, 4005, 4058, 4119, 4181, 4241, 4301, 4361, 4420, - 4479, 4546, 4612, 4677, 4742, 4807, 4871, 4942, 5013, 5083, 5153, - 5222, 5291, 5367, 5442, 5517, 5591, 5665, 5745, 5825, 5905, 5984, - 6063, 6149, 6234, 6319, 6404, 6495, 6587, 6678, 6769, 6867, 6966, - 7064, 7163, 7269, 7376, 7483, 7599, 7715, 7832, 7958, 8085, 8214, - 8352, 8492, 8635, 8788, 8945, 9104, 9275, 9450, 9639, 9832, 10031, - 10245, 10465, 10702, 10946, 11210, 11482, 11776, 12081, 12409, 12750, 13118, - 13501, 13913, 14343, 14807, 15290, 15812, 16356, 16943, 17575, 18237, 18949, - 19718, 20521, 21387, -}; -#endif - -static const int16_t ac_qlookup[QINDEX_RANGE] = { - 4, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 104, 106, 108, 110, 112, 114, 116, 118, - 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, - 146, 148, 150, 152, 155, 158, 161, 164, 167, 170, 173, 176, 179, - 182, 185, 188, 191, 194, 197, 200, 203, 207, 211, 215, 219, 223, - 227, 231, 235, 239, 243, 247, 251, 255, 260, 265, 270, 275, 280, - 285, 290, 295, 300, 305, 311, 317, 323, 329, 335, 341, 347, 353, - 359, 366, 373, 380, 387, 394, 401, 408, 416, 424, 432, 440, 448, - 456, 465, 474, 483, 492, 501, 510, 520, 530, 540, 550, 560, 571, - 582, 593, 604, 615, 627, 639, 651, 663, 676, 689, 702, 715, 729, - 743, 757, 771, 786, 801, 816, 832, 848, 864, 881, 898, 915, 933, - 951, 969, 988, 1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151, 1173, 1196, - 1219, 1243, 1267, 1292, 1317, 1343, 1369, 1396, 1423, 1451, 1479, 1508, 1537, - 1567, 1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828, -}; - -#if CONFIG_VP9_HIGHBITDEPTH -static const int16_t ac_qlookup_10[QINDEX_RANGE] = { - 4, 9, 11, 13, 16, 18, 21, 24, 27, 30, 33, 37, 40, - 44, 48, 51, 55, 59, 63, 67, 71, 75, 79, 83, 88, 92, - 96, 100, 105, 109, 114, 118, 122, 127, 131, 136, 140, 145, 149, - 154, 158, 163, 168, 172, 177, 181, 186, 190, 195, 199, 204, 208, - 213, 217, 222, 226, 231, 235, 240, 244, 249, 253, 258, 262, 267, - 271, 275, 280, 284, 289, 293, 297, 302, 306, 311, 315, 319, 324, - 328, 332, 337, 341, 345, 349, 354, 358, 362, 367, 371, 375, 379, - 384, 388, 392, 396, 401, 409, 417, 425, 433, 441, 449, 458, 466, - 474, 482, 490, 498, 506, 514, 523, 531, 539, 547, 555, 563, 571, - 579, 588, 596, 604, 616, 628, 640, 652, 664, 676, 688, 700, 713, - 725, 737, 749, 761, 773, 785, 797, 809, 825, 841, 857, 873, 889, - 905, 922, 938, 954, 970, 986, 1002, 1018, 1038, 1058, 1078, 1098, 1118, - 1138, 1158, 1178, 1198, 1218, 1242, 1266, 1290, 1314, 1338, 1362, 1386, 1411, - 1435, 1463, 1491, 1519, 1547, 1575, 1603, 1631, 1663, 1695, 1727, 1759, 1791, - 1823, 1859, 1895, 1931, 1967, 2003, 2039, 2079, 2119, 2159, 2199, 2239, 2283, - 2327, 2371, 2415, 2459, 2507, 2555, 2603, 2651, 2703, 2755, 2807, 2859, 2915, - 2971, 3027, 3083, 3143, 3203, 3263, 3327, 3391, 3455, 3523, 3591, 3659, 3731, - 3803, 3876, 3952, 4028, 4104, 4184, 4264, 4348, 4432, 4516, 4604, 4692, 4784, - 4876, 4972, 5068, 5168, 5268, 5372, 5476, 5584, 5692, 5804, 5916, 6032, 6148, - 6268, 6388, 6512, 6640, 6768, 6900, 7036, 7172, 7312, -}; - -static const int16_t ac_qlookup_12[QINDEX_RANGE] = { - 4, 13, 19, 27, 35, 44, 54, 64, 75, 87, 99, - 112, 126, 139, 154, 168, 183, 199, 214, 230, 247, 263, - 280, 297, 314, 331, 349, 366, 384, 402, 420, 438, 456, - 475, 493, 511, 530, 548, 567, 586, 604, 623, 642, 660, - 679, 698, 716, 735, 753, 772, 791, 809, 828, 846, 865, - 884, 902, 920, 939, 957, 976, 994, 1012, 1030, 1049, 1067, - 1085, 1103, 1121, 1139, 1157, 1175, 1193, 1211, 1229, 1246, 1264, - 1282, 1299, 1317, 1335, 1352, 1370, 1387, 1405, 1422, 1440, 1457, - 1474, 1491, 1509, 1526, 1543, 1560, 1577, 1595, 1627, 1660, 1693, - 1725, 1758, 1791, 1824, 1856, 1889, 1922, 1954, 1987, 2020, 2052, - 2085, 2118, 2150, 2183, 2216, 2248, 2281, 2313, 2346, 2378, 2411, - 2459, 2508, 2556, 2605, 2653, 2701, 2750, 2798, 2847, 2895, 2943, - 2992, 3040, 3088, 3137, 3185, 3234, 3298, 3362, 3426, 3491, 3555, - 3619, 3684, 3748, 3812, 3876, 3941, 4005, 4069, 4149, 4230, 4310, - 4390, 4470, 4550, 4631, 4711, 4791, 4871, 4967, 5064, 5160, 5256, - 5352, 5448, 5544, 5641, 5737, 5849, 5961, 6073, 6185, 6297, 6410, - 6522, 6650, 6778, 6906, 7034, 7162, 7290, 7435, 7579, 7723, 7867, - 8011, 8155, 8315, 8475, 8635, 8795, 8956, 9132, 9308, 9484, 9660, - 9836, 10028, 10220, 10412, 10604, 10812, 11020, 11228, 11437, 11661, 11885, - 12109, 12333, 12573, 12813, 13053, 13309, 13565, 13821, 14093, 14365, 14637, - 14925, 15213, 15502, 15806, 16110, 16414, 16734, 17054, 17390, 17726, 18062, - 18414, 18766, 19134, 19502, 19886, 20270, 20670, 21070, 21486, 21902, 22334, - 22766, 23214, 23662, 24126, 24590, 25070, 25551, 26047, 26559, 27071, 27599, - 28143, 28687, 29247, -}; -#endif - -int16_t vp9_dc_quant(int qindex, int delta, vpx_bit_depth_t bit_depth) { -#if CONFIG_VP9_HIGHBITDEPTH - switch (bit_depth) { - case VPX_BITS_8: return dc_qlookup[clamp(qindex + delta, 0, MAXQ)]; - case VPX_BITS_10: return dc_qlookup_10[clamp(qindex + delta, 0, MAXQ)]; - case VPX_BITS_12: return dc_qlookup_12[clamp(qindex + delta, 0, MAXQ)]; - default: - assert(0 && "bit_depth should be VPX_BITS_8, VPX_BITS_10 or VPX_BITS_12"); - return -1; - } -#else - (void)bit_depth; - return dc_qlookup[clamp(qindex + delta, 0, MAXQ)]; -#endif -} - -int16_t vp9_ac_quant(int qindex, int delta, vpx_bit_depth_t bit_depth) { -#if CONFIG_VP9_HIGHBITDEPTH - switch (bit_depth) { - case VPX_BITS_8: return ac_qlookup[clamp(qindex + delta, 0, MAXQ)]; - case VPX_BITS_10: return ac_qlookup_10[clamp(qindex + delta, 0, MAXQ)]; - case VPX_BITS_12: return ac_qlookup_12[clamp(qindex + delta, 0, MAXQ)]; - default: - assert(0 && "bit_depth should be VPX_BITS_8, VPX_BITS_10 or VPX_BITS_12"); - return -1; - } -#else - (void)bit_depth; - return ac_qlookup[clamp(qindex + delta, 0, MAXQ)]; -#endif -} - -int vp9_get_qindex(const struct segmentation *seg, int segment_id, - int base_qindex) { - if (segfeature_active(seg, segment_id, SEG_LVL_ALT_Q)) { - const int data = get_segdata(seg, segment_id, SEG_LVL_ALT_Q); - const int seg_qindex = - seg->abs_delta == SEGMENT_ABSDATA ? data : base_qindex + data; - return clamp(seg_qindex, 0, MAXQ); - } else { - return base_qindex; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_quant_common.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_quant_common.h deleted file mode 100644 index ec8b9f4c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_quant_common.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_QUANT_COMMON_H_ -#define VPX_VP9_COMMON_VP9_QUANT_COMMON_H_ - -#include "vpx/vpx_codec.h" -#include "vp9/common/vp9_seg_common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MINQ 0 -#define MAXQ 255 -#define QINDEX_RANGE (MAXQ - MINQ + 1) -#define QINDEX_BITS 8 - -int16_t vp9_dc_quant(int qindex, int delta, vpx_bit_depth_t bit_depth); -int16_t vp9_ac_quant(int qindex, int delta, vpx_bit_depth_t bit_depth); - -int vp9_get_qindex(const struct segmentation *seg, int segment_id, - int base_qindex); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_QUANT_COMMON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_reconinter.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_reconinter.c deleted file mode 100644 index 0a60b853..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_reconinter.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_scale_rtcd.h" -#include "./vpx_config.h" - -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_reconinter.h" -#include "vp9/common/vp9_reconintra.h" - -#include "vpx/vpx_integer.h" -#include "vpx_scale/yv12config.h" - -#if CONFIG_VP9_HIGHBITDEPTH -void vp9_highbd_build_inter_predictor( - const uint16_t *src, int src_stride, uint16_t *dst, int dst_stride, - const MV *src_mv, const struct scale_factors *sf, int w, int h, int ref, - const InterpKernel *kernel, enum mv_precision precision, int x, int y, - int bd) { - const int is_q4 = precision == MV_PRECISION_Q4; - const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2, - is_q4 ? src_mv->col : src_mv->col * 2 }; - MV32 mv = vp9_scale_mv(&mv_q4, x, y, sf); - const int subpel_x = mv.col & SUBPEL_MASK; - const int subpel_y = mv.row & SUBPEL_MASK; - - src += (mv.row >> SUBPEL_BITS) * src_stride + (mv.col >> SUBPEL_BITS); - - highbd_inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y, - sf, w, h, ref, kernel, sf->x_step_q4, sf->y_step_q4, - bd); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -void vp9_build_inter_predictor(const uint8_t *src, int src_stride, uint8_t *dst, - int dst_stride, const MV *src_mv, - const struct scale_factors *sf, int w, int h, - int ref, const InterpKernel *kernel, - enum mv_precision precision, int x, int y) { - const int is_q4 = precision == MV_PRECISION_Q4; - const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2, - is_q4 ? src_mv->col : src_mv->col * 2 }; - MV32 mv = vp9_scale_mv(&mv_q4, x, y, sf); - const int subpel_x = mv.col & SUBPEL_MASK; - const int subpel_y = mv.row & SUBPEL_MASK; - - src += (mv.row >> SUBPEL_BITS) * src_stride + (mv.col >> SUBPEL_BITS); - - inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y, sf, w, - h, ref, kernel, sf->x_step_q4, sf->y_step_q4); -} - -static INLINE int round_mv_comp_q4(int value) { - return (value < 0 ? value - 2 : value + 2) / 4; -} - -static MV mi_mv_pred_q4(const MODE_INFO *mi, int idx) { - MV res = { round_mv_comp_q4(mi->bmi[0].as_mv[idx].as_mv.row + - mi->bmi[1].as_mv[idx].as_mv.row + - mi->bmi[2].as_mv[idx].as_mv.row + - mi->bmi[3].as_mv[idx].as_mv.row), - round_mv_comp_q4(mi->bmi[0].as_mv[idx].as_mv.col + - mi->bmi[1].as_mv[idx].as_mv.col + - mi->bmi[2].as_mv[idx].as_mv.col + - mi->bmi[3].as_mv[idx].as_mv.col) }; - return res; -} - -static INLINE int round_mv_comp_q2(int value) { - return (value < 0 ? value - 1 : value + 1) / 2; -} - -static MV mi_mv_pred_q2(const MODE_INFO *mi, int idx, int block0, int block1) { - MV res = { round_mv_comp_q2(mi->bmi[block0].as_mv[idx].as_mv.row + - mi->bmi[block1].as_mv[idx].as_mv.row), - round_mv_comp_q2(mi->bmi[block0].as_mv[idx].as_mv.col + - mi->bmi[block1].as_mv[idx].as_mv.col) }; - return res; -} - -// TODO(jkoleszar): yet another mv clamping function :-( -MV clamp_mv_to_umv_border_sb(const MACROBLOCKD *xd, const MV *src_mv, int bw, - int bh, int ss_x, int ss_y) { - // If the MV points so far into the UMV border that no visible pixels - // are used for reconstruction, the subpel part of the MV can be - // discarded and the MV limited to 16 pixels with equivalent results. - const int spel_left = (VP9_INTERP_EXTEND + bw) << SUBPEL_BITS; - const int spel_right = spel_left - SUBPEL_SHIFTS; - const int spel_top = (VP9_INTERP_EXTEND + bh) << SUBPEL_BITS; - const int spel_bottom = spel_top - SUBPEL_SHIFTS; - MV clamped_mv = { (short)(src_mv->row * (1 << (1 - ss_y))), - (short)(src_mv->col * (1 << (1 - ss_x))) }; - assert(ss_x <= 1); - assert(ss_y <= 1); - - clamp_mv(&clamped_mv, xd->mb_to_left_edge * (1 << (1 - ss_x)) - spel_left, - xd->mb_to_right_edge * (1 << (1 - ss_x)) + spel_right, - xd->mb_to_top_edge * (1 << (1 - ss_y)) - spel_top, - xd->mb_to_bottom_edge * (1 << (1 - ss_y)) + spel_bottom); - - return clamped_mv; -} - -MV average_split_mvs(const struct macroblockd_plane *pd, const MODE_INFO *mi, - int ref, int block) { - const int ss_idx = ((pd->subsampling_x > 0) << 1) | (pd->subsampling_y > 0); - MV res = { 0, 0 }; - switch (ss_idx) { - case 0: res = mi->bmi[block].as_mv[ref].as_mv; break; - case 1: res = mi_mv_pred_q2(mi, ref, block, block + 2); break; - case 2: res = mi_mv_pred_q2(mi, ref, block, block + 1); break; - case 3: res = mi_mv_pred_q4(mi, ref); break; - default: assert(ss_idx <= 3 && ss_idx >= 0); - } - return res; -} - -static void build_inter_predictors(MACROBLOCKD *xd, int plane, int block, - int bw, int bh, int x, int y, int w, int h, - int mi_x, int mi_y) { - struct macroblockd_plane *const pd = &xd->plane[plane]; - const MODE_INFO *mi = xd->mi[0]; - const int is_compound = has_second_ref(mi); - const InterpKernel *kernel = vp9_filter_kernels[mi->interp_filter]; - int ref; - - for (ref = 0; ref < 1 + is_compound; ++ref) { - const struct scale_factors *const sf = &xd->block_refs[ref]->sf; - struct buf_2d *const pre_buf = &pd->pre[ref]; - struct buf_2d *const dst_buf = &pd->dst; - uint8_t *const dst = dst_buf->buf + (int64_t)dst_buf->stride * y + x; - const MV mv = mi->sb_type < BLOCK_8X8 - ? average_split_mvs(pd, mi, ref, block) - : mi->mv[ref].as_mv; - - // TODO(jkoleszar): This clamping is done in the incorrect place for the - // scaling case. It needs to be done on the scaled MV, not the pre-scaling - // MV. Note however that it performs the subsampling aware scaling so - // that the result is always q4. - // mv_precision precision is MV_PRECISION_Q4. - const MV mv_q4 = clamp_mv_to_umv_border_sb( - xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y); - - uint8_t *pre; - MV32 scaled_mv; - int xs, ys, subpel_x, subpel_y; - const int is_scaled = vp9_is_scaled(sf); - - if (is_scaled) { - // Co-ordinate of containing block to pixel precision. - const int x_start = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)); - const int y_start = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)); - const YV12_BUFFER_CONFIG *ref_buf = xd->block_refs[ref]->buf; - uint8_t *buf_array[] = { ref_buf->y_buffer, ref_buf->u_buffer, - ref_buf->v_buffer }; - const int stride_array[] = { ref_buf->y_stride, ref_buf->uv_stride, - ref_buf->uv_stride }; -#if 0 // CONFIG_BETTER_HW_COMPATIBILITY - assert(xd->mi[0]->sb_type != BLOCK_4X8 && - xd->mi[0]->sb_type != BLOCK_8X4); - assert(mv_q4.row == mv.row * (1 << (1 - pd->subsampling_y)) && - mv_q4.col == mv.col * (1 << (1 - pd->subsampling_x))); -#endif - pre_buf->buf = buf_array[plane]; - pre_buf->stride = stride_array[plane]; - - pre_buf->buf += - scaled_buffer_offset(x_start + x, y_start + y, pre_buf->stride, sf); - pre = pre_buf->buf; - scaled_mv = vp9_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf); - xs = sf->x_step_q4; - ys = sf->y_step_q4; - } else { - pre = pre_buf->buf + ((int64_t)y * pre_buf->stride + x); - scaled_mv.row = mv_q4.row; - scaled_mv.col = mv_q4.col; - xs = ys = 16; - } - subpel_x = scaled_mv.col & SUBPEL_MASK; - subpel_y = scaled_mv.row & SUBPEL_MASK; - pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride + - (scaled_mv.col >> SUBPEL_BITS); - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - highbd_inter_predictor(CONVERT_TO_SHORTPTR(pre), pre_buf->stride, - CONVERT_TO_SHORTPTR(dst), dst_buf->stride, - subpel_x, subpel_y, sf, w, h, ref, kernel, xs, ys, - xd->bd); - } else { - inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride, subpel_x, - subpel_y, sf, w, h, ref, kernel, xs, ys); - } -#else - inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride, subpel_x, - subpel_y, sf, w, h, ref, kernel, xs, ys); -#endif // CONFIG_VP9_HIGHBITDEPTH - } -} - -static void build_inter_predictors_for_planes(MACROBLOCKD *xd, BLOCK_SIZE bsize, - int mi_row, int mi_col, - int plane_from, int plane_to) { - int plane; - const int mi_x = mi_col * MI_SIZE; - const int mi_y = mi_row * MI_SIZE; - for (plane = plane_from; plane <= plane_to; ++plane) { - const BLOCK_SIZE plane_bsize = - get_plane_block_size(bsize, &xd->plane[plane]); - const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize]; - const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize]; - const int bw = 4 * num_4x4_w; - const int bh = 4 * num_4x4_h; - - if (xd->mi[0]->sb_type < BLOCK_8X8) { - int i = 0, x, y; - assert(bsize == BLOCK_8X8); - for (y = 0; y < num_4x4_h; ++y) - for (x = 0; x < num_4x4_w; ++x) - build_inter_predictors(xd, plane, i++, bw, bh, 4 * x, 4 * y, 4, 4, - mi_x, mi_y); - } else { - build_inter_predictors(xd, plane, 0, bw, bh, 0, 0, bw, bh, mi_x, mi_y); - } - } -} - -void vp9_build_inter_predictors_sby(MACROBLOCKD *xd, int mi_row, int mi_col, - BLOCK_SIZE bsize) { - build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 0, 0); -} - -void vp9_build_inter_predictors_sbp(MACROBLOCKD *xd, int mi_row, int mi_col, - BLOCK_SIZE bsize, int plane) { - build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, plane, plane); -} - -void vp9_build_inter_predictors_sbuv(MACROBLOCKD *xd, int mi_row, int mi_col, - BLOCK_SIZE bsize) { - build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 1, - MAX_MB_PLANE - 1); -} - -void vp9_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col, - BLOCK_SIZE bsize) { - build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 0, - MAX_MB_PLANE - 1); -} - -void vp9_setup_dst_planes(struct macroblockd_plane planes[MAX_MB_PLANE], - const YV12_BUFFER_CONFIG *src, int mi_row, - int mi_col) { - uint8_t *const buffers[MAX_MB_PLANE] = { src->y_buffer, src->u_buffer, - src->v_buffer }; - const int strides[MAX_MB_PLANE] = { src->y_stride, src->uv_stride, - src->uv_stride }; - int i; - - for (i = 0; i < MAX_MB_PLANE; ++i) { - struct macroblockd_plane *const pd = &planes[i]; - setup_pred_plane(&pd->dst, buffers[i], strides[i], mi_row, mi_col, NULL, - pd->subsampling_x, pd->subsampling_y); - } -} - -void vp9_setup_pre_planes(MACROBLOCKD *xd, int idx, - const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col, - const struct scale_factors *sf) { - if (src != NULL) { - int i; - uint8_t *const buffers[MAX_MB_PLANE] = { src->y_buffer, src->u_buffer, - src->v_buffer }; - const int strides[MAX_MB_PLANE] = { src->y_stride, src->uv_stride, - src->uv_stride }; - for (i = 0; i < MAX_MB_PLANE; ++i) { - struct macroblockd_plane *const pd = &xd->plane[i]; - setup_pred_plane(&pd->pre[idx], buffers[i], strides[i], mi_row, mi_col, - sf, pd->subsampling_x, pd->subsampling_y); - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_reconinter.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_reconinter.h deleted file mode 100644 index 12b54583..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_reconinter.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_RECONINTER_H_ -#define VPX_VP9_COMMON_VP9_RECONINTER_H_ - -#include "vp9/common/vp9_filter.h" -#include "vp9/common/vp9_onyxc_int.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/vpx_filter.h" - -#ifdef __cplusplus -extern "C" { -#endif - -static INLINE void inter_predictor(const uint8_t *src, int src_stride, - uint8_t *dst, int dst_stride, - const int subpel_x, const int subpel_y, - const struct scale_factors *sf, int w, int h, - int ref, const InterpKernel *kernel, int xs, - int ys) { - sf->predict[subpel_x != 0][subpel_y != 0][ref](src, src_stride, dst, - dst_stride, kernel, subpel_x, - xs, subpel_y, ys, w, h); -} - -#if CONFIG_VP9_HIGHBITDEPTH -static INLINE void highbd_inter_predictor( - const uint16_t *src, int src_stride, uint16_t *dst, int dst_stride, - const int subpel_x, const int subpel_y, const struct scale_factors *sf, - int w, int h, int ref, const InterpKernel *kernel, int xs, int ys, int bd) { - sf->highbd_predict[subpel_x != 0][subpel_y != 0][ref]( - src, src_stride, dst, dst_stride, kernel, subpel_x, xs, subpel_y, ys, w, - h, bd); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -MV average_split_mvs(const struct macroblockd_plane *pd, const MODE_INFO *mi, - int ref, int block); - -MV clamp_mv_to_umv_border_sb(const MACROBLOCKD *xd, const MV *src_mv, int bw, - int bh, int ss_x, int ss_y); - -void vp9_build_inter_predictors_sby(MACROBLOCKD *xd, int mi_row, int mi_col, - BLOCK_SIZE bsize); - -void vp9_build_inter_predictors_sbp(MACROBLOCKD *xd, int mi_row, int mi_col, - BLOCK_SIZE bsize, int plane); - -void vp9_build_inter_predictors_sbuv(MACROBLOCKD *xd, int mi_row, int mi_col, - BLOCK_SIZE bsize); - -void vp9_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col, - BLOCK_SIZE bsize); - -void vp9_build_inter_predictor(const uint8_t *src, int src_stride, uint8_t *dst, - int dst_stride, const MV *src_mv, - const struct scale_factors *sf, int w, int h, - int ref, const InterpKernel *kernel, - enum mv_precision precision, int x, int y); - -#if CONFIG_VP9_HIGHBITDEPTH -void vp9_highbd_build_inter_predictor( - const uint16_t *src, int src_stride, uint16_t *dst, int dst_stride, - const MV *src_mv, const struct scale_factors *sf, int w, int h, int ref, - const InterpKernel *kernel, enum mv_precision precision, int x, int y, - int bd); -#endif - -static INLINE int64_t scaled_buffer_offset(int x_offset, int y_offset, - int stride, - const struct scale_factors *sf) { - const int x = sf ? sf->scale_value_x(x_offset, sf) : x_offset; - const int y = sf ? sf->scale_value_y(y_offset, sf) : y_offset; - return (int64_t)y * stride + x; -} - -static INLINE void setup_pred_plane(struct buf_2d *dst, uint8_t *src, - int stride, int mi_row, int mi_col, - const struct scale_factors *scale, - int subsampling_x, int subsampling_y) { - const int x = (MI_SIZE * mi_col) >> subsampling_x; - const int y = (MI_SIZE * mi_row) >> subsampling_y; - dst->buf = src + scaled_buffer_offset(x, y, stride, scale); - dst->stride = stride; -} - -void vp9_setup_dst_planes(struct macroblockd_plane planes[MAX_MB_PLANE], - const YV12_BUFFER_CONFIG *src, int mi_row, - int mi_col); - -void vp9_setup_pre_planes(MACROBLOCKD *xd, int idx, - const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col, - const struct scale_factors *sf); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_RECONINTER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_reconintra.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_reconintra.c deleted file mode 100644 index 3e5ed616..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_reconintra.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#if CONFIG_VP9_HIGHBITDEPTH -#include "vpx_dsp/vpx_dsp_common.h" -#endif // CONFIG_VP9_HIGHBITDEPTH -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/vpx_once.h" - -#include "vp9/common/vp9_reconintra.h" -#include "vp9/common/vp9_onyxc_int.h" - -const TX_TYPE intra_mode_to_tx_type_lookup[INTRA_MODES] = { - DCT_DCT, // DC - ADST_DCT, // V - DCT_ADST, // H - DCT_DCT, // D45 - ADST_ADST, // D135 - ADST_DCT, // D117 - DCT_ADST, // D153 - DCT_ADST, // D207 - ADST_DCT, // D63 - ADST_ADST, // TM -}; - -enum { - NEED_LEFT = 1 << 1, - NEED_ABOVE = 1 << 2, - NEED_ABOVERIGHT = 1 << 3, -}; - -static const uint8_t extend_modes[INTRA_MODES] = { - NEED_ABOVE | NEED_LEFT, // DC - NEED_ABOVE, // V - NEED_LEFT, // H - NEED_ABOVERIGHT, // D45 - NEED_LEFT | NEED_ABOVE, // D135 - NEED_LEFT | NEED_ABOVE, // D117 - NEED_LEFT | NEED_ABOVE, // D153 - NEED_LEFT, // D207 - NEED_ABOVERIGHT, // D63 - NEED_LEFT | NEED_ABOVE, // TM -}; - -typedef void (*intra_pred_fn)(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left); - -static intra_pred_fn pred[INTRA_MODES][TX_SIZES]; -static intra_pred_fn dc_pred[2][2][TX_SIZES]; - -#if CONFIG_VP9_HIGHBITDEPTH -typedef void (*intra_high_pred_fn)(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, const uint16_t *left, - int bd); -static intra_high_pred_fn pred_high[INTRA_MODES][4]; -static intra_high_pred_fn dc_pred_high[2][2][4]; -#endif // CONFIG_VP9_HIGHBITDEPTH - -static void vp9_init_intra_predictors_internal(void) { -#define INIT_ALL_SIZES(p, type) \ - p[TX_4X4] = vpx_##type##_predictor_4x4; \ - p[TX_8X8] = vpx_##type##_predictor_8x8; \ - p[TX_16X16] = vpx_##type##_predictor_16x16; \ - p[TX_32X32] = vpx_##type##_predictor_32x32 - - INIT_ALL_SIZES(pred[V_PRED], v); - INIT_ALL_SIZES(pred[H_PRED], h); - INIT_ALL_SIZES(pred[D207_PRED], d207); - INIT_ALL_SIZES(pred[D45_PRED], d45); - INIT_ALL_SIZES(pred[D63_PRED], d63); - INIT_ALL_SIZES(pred[D117_PRED], d117); - INIT_ALL_SIZES(pred[D135_PRED], d135); - INIT_ALL_SIZES(pred[D153_PRED], d153); - INIT_ALL_SIZES(pred[TM_PRED], tm); - - INIT_ALL_SIZES(dc_pred[0][0], dc_128); - INIT_ALL_SIZES(dc_pred[0][1], dc_top); - INIT_ALL_SIZES(dc_pred[1][0], dc_left); - INIT_ALL_SIZES(dc_pred[1][1], dc); - -#if CONFIG_VP9_HIGHBITDEPTH - INIT_ALL_SIZES(pred_high[V_PRED], highbd_v); - INIT_ALL_SIZES(pred_high[H_PRED], highbd_h); - INIT_ALL_SIZES(pred_high[D207_PRED], highbd_d207); - INIT_ALL_SIZES(pred_high[D45_PRED], highbd_d45); - INIT_ALL_SIZES(pred_high[D63_PRED], highbd_d63); - INIT_ALL_SIZES(pred_high[D117_PRED], highbd_d117); - INIT_ALL_SIZES(pred_high[D135_PRED], highbd_d135); - INIT_ALL_SIZES(pred_high[D153_PRED], highbd_d153); - INIT_ALL_SIZES(pred_high[TM_PRED], highbd_tm); - - INIT_ALL_SIZES(dc_pred_high[0][0], highbd_dc_128); - INIT_ALL_SIZES(dc_pred_high[0][1], highbd_dc_top); - INIT_ALL_SIZES(dc_pred_high[1][0], highbd_dc_left); - INIT_ALL_SIZES(dc_pred_high[1][1], highbd_dc); -#endif // CONFIG_VP9_HIGHBITDEPTH - -#undef intra_pred_allsizes -} - -#if CONFIG_VP9_HIGHBITDEPTH -static void build_intra_predictors_high( - const MACROBLOCKD *xd, const uint8_t *ref8, int ref_stride, uint8_t *dst8, - int dst_stride, PREDICTION_MODE mode, TX_SIZE tx_size, int up_available, - int left_available, int right_available, int x, int y, int plane, int bd) { - int i; - uint16_t *dst = CONVERT_TO_SHORTPTR(dst8); - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); - DECLARE_ALIGNED(16, uint16_t, left_col[32]); - DECLARE_ALIGNED(16, uint16_t, above_data[64 + 16]); - uint16_t *above_row = above_data + 16; - const uint16_t *const_above_row = above_row; - const int bs = 4 << tx_size; - int frame_width, frame_height; - int x0, y0; - const struct macroblockd_plane *const pd = &xd->plane[plane]; - const int need_left = extend_modes[mode] & NEED_LEFT; - const int need_above = extend_modes[mode] & NEED_ABOVE; - const int need_aboveright = extend_modes[mode] & NEED_ABOVERIGHT; - int base = 128 << (bd - 8); - // 127 127 127 .. 127 127 127 127 127 127 - // 129 A B .. Y Z - // 129 C D .. W X - // 129 E F .. U V - // 129 G H .. S T T T T T - // For 10 bit and 12 bit, 127 and 129 are replaced by base -1 and base + 1. - - // Get current frame pointer, width and height. - if (plane == 0) { - frame_width = xd->cur_buf->y_width; - frame_height = xd->cur_buf->y_height; - } else { - frame_width = xd->cur_buf->uv_width; - frame_height = xd->cur_buf->uv_height; - } - - // Get block position in current frame. - x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x; - y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y; - - // NEED_LEFT - if (need_left) { - if (left_available) { - if (xd->mb_to_bottom_edge < 0) { - /* slower path if the block needs border extension */ - if (y0 + bs <= frame_height) { - for (i = 0; i < bs; ++i) left_col[i] = ref[i * ref_stride - 1]; - } else { - const int extend_bottom = frame_height - y0; - for (i = 0; i < extend_bottom; ++i) - left_col[i] = ref[i * ref_stride - 1]; - for (; i < bs; ++i) - left_col[i] = ref[(extend_bottom - 1) * ref_stride - 1]; - } - } else { - /* faster path if the block does not need extension */ - for (i = 0; i < bs; ++i) left_col[i] = ref[i * ref_stride - 1]; - } - } else { - vpx_memset16(left_col, base + 1, bs); - } - } - - // NEED_ABOVE - if (need_above) { - if (up_available) { - const uint16_t *above_ref = ref - ref_stride; - if (xd->mb_to_right_edge < 0) { - /* slower path if the block needs border extension */ - if (x0 + bs <= frame_width) { - memcpy(above_row, above_ref, bs * sizeof(above_row[0])); - } else if (x0 <= frame_width) { - const int r = frame_width - x0; - memcpy(above_row, above_ref, r * sizeof(above_row[0])); - vpx_memset16(above_row + r, above_row[r - 1], x0 + bs - frame_width); - } - } else { - /* faster path if the block does not need extension */ - if (bs == 4 && right_available && left_available) { - const_above_row = above_ref; - } else { - memcpy(above_row, above_ref, bs * sizeof(above_row[0])); - } - } - above_row[-1] = left_available ? above_ref[-1] : (base + 1); - } else { - vpx_memset16(above_row, base - 1, bs); - above_row[-1] = base - 1; - } - } - - // NEED_ABOVERIGHT - if (need_aboveright) { - if (up_available) { - const uint16_t *above_ref = ref - ref_stride; - if (xd->mb_to_right_edge < 0) { - /* slower path if the block needs border extension */ - if (x0 + 2 * bs <= frame_width) { - if (right_available && bs == 4) { - memcpy(above_row, above_ref, 2 * bs * sizeof(above_row[0])); - } else { - memcpy(above_row, above_ref, bs * sizeof(above_row[0])); - vpx_memset16(above_row + bs, above_row[bs - 1], bs); - } - } else if (x0 + bs <= frame_width) { - const int r = frame_width - x0; - if (right_available && bs == 4) { - memcpy(above_row, above_ref, r * sizeof(above_row[0])); - vpx_memset16(above_row + r, above_row[r - 1], - x0 + 2 * bs - frame_width); - } else { - memcpy(above_row, above_ref, bs * sizeof(above_row[0])); - vpx_memset16(above_row + bs, above_row[bs - 1], bs); - } - } else if (x0 <= frame_width) { - const int r = frame_width - x0; - memcpy(above_row, above_ref, r * sizeof(above_row[0])); - vpx_memset16(above_row + r, above_row[r - 1], - x0 + 2 * bs - frame_width); - } - above_row[-1] = left_available ? above_ref[-1] : (base + 1); - } else { - /* faster path if the block does not need extension */ - if (bs == 4 && right_available && left_available) { - const_above_row = above_ref; - } else { - memcpy(above_row, above_ref, bs * sizeof(above_row[0])); - if (bs == 4 && right_available) - memcpy(above_row + bs, above_ref + bs, bs * sizeof(above_row[0])); - else - vpx_memset16(above_row + bs, above_row[bs - 1], bs); - above_row[-1] = left_available ? above_ref[-1] : (base + 1); - } - } - } else { - vpx_memset16(above_row, base - 1, bs * 2); - above_row[-1] = base - 1; - } - } - - // predict - if (mode == DC_PRED) { - dc_pred_high[left_available][up_available][tx_size]( - dst, dst_stride, const_above_row, left_col, xd->bd); - } else { - pred_high[mode][tx_size](dst, dst_stride, const_above_row, left_col, - xd->bd); - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static void build_intra_predictors(const MACROBLOCKD *xd, const uint8_t *ref, - int ref_stride, uint8_t *dst, int dst_stride, - PREDICTION_MODE mode, TX_SIZE tx_size, - int up_available, int left_available, - int right_available, int x, int y, - int plane) { - int i; - DECLARE_ALIGNED(16, uint8_t, left_col[32]); - DECLARE_ALIGNED(16, uint8_t, above_data[64 + 16]); - uint8_t *above_row = above_data + 16; - const uint8_t *const_above_row = above_row; - const int bs = 4 << tx_size; - int frame_width, frame_height; - int x0, y0; - const struct macroblockd_plane *const pd = &xd->plane[plane]; - - // 127 127 127 .. 127 127 127 127 127 127 - // 129 A B .. Y Z - // 129 C D .. W X - // 129 E F .. U V - // 129 G H .. S T T T T T - // .. - - // Get current frame pointer, width and height. - if (plane == 0) { - frame_width = xd->cur_buf->y_width; - frame_height = xd->cur_buf->y_height; - } else { - frame_width = xd->cur_buf->uv_width; - frame_height = xd->cur_buf->uv_height; - } - - // Get block position in current frame. - x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x; - y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y; - - // NEED_LEFT - if (extend_modes[mode] & NEED_LEFT) { - if (left_available) { - if (xd->mb_to_bottom_edge < 0) { - /* slower path if the block needs border extension */ - if (y0 + bs <= frame_height) { - for (i = 0; i < bs; ++i) left_col[i] = ref[i * ref_stride - 1]; - } else { - const int extend_bottom = frame_height - y0; - for (i = 0; i < extend_bottom; ++i) - left_col[i] = ref[i * ref_stride - 1]; - for (; i < bs; ++i) - left_col[i] = ref[(extend_bottom - 1) * ref_stride - 1]; - } - } else { - /* faster path if the block does not need extension */ - for (i = 0; i < bs; ++i) left_col[i] = ref[i * ref_stride - 1]; - } - } else { - memset(left_col, 129, bs); - } - } - - // NEED_ABOVE - if (extend_modes[mode] & NEED_ABOVE) { - if (up_available) { - const uint8_t *above_ref = ref - ref_stride; - if (xd->mb_to_right_edge < 0) { - /* slower path if the block needs border extension */ - if (x0 + bs <= frame_width) { - memcpy(above_row, above_ref, bs); - } else if (x0 <= frame_width) { - const int r = frame_width - x0; - memcpy(above_row, above_ref, r); - memset(above_row + r, above_row[r - 1], x0 + bs - frame_width); - } - } else { - /* faster path if the block does not need extension */ - if (bs == 4 && right_available && left_available) { - const_above_row = above_ref; - } else { - memcpy(above_row, above_ref, bs); - } - } - above_row[-1] = left_available ? above_ref[-1] : 129; - } else { - memset(above_row, 127, bs); - above_row[-1] = 127; - } - } - - // NEED_ABOVERIGHT - if (extend_modes[mode] & NEED_ABOVERIGHT) { - if (up_available) { - const uint8_t *above_ref = ref - ref_stride; - if (xd->mb_to_right_edge < 0) { - /* slower path if the block needs border extension */ - if (x0 + 2 * bs <= frame_width) { - if (right_available && bs == 4) { - memcpy(above_row, above_ref, 2 * bs); - } else { - memcpy(above_row, above_ref, bs); - memset(above_row + bs, above_row[bs - 1], bs); - } - } else if (x0 + bs <= frame_width) { - const int r = frame_width - x0; - if (right_available && bs == 4) { - memcpy(above_row, above_ref, r); - memset(above_row + r, above_row[r - 1], x0 + 2 * bs - frame_width); - } else { - memcpy(above_row, above_ref, bs); - memset(above_row + bs, above_row[bs - 1], bs); - } - } else if (x0 <= frame_width) { - const int r = frame_width - x0; - memcpy(above_row, above_ref, r); - memset(above_row + r, above_row[r - 1], x0 + 2 * bs - frame_width); - } - } else { - /* faster path if the block does not need extension */ - if (bs == 4 && right_available && left_available) { - const_above_row = above_ref; - } else { - memcpy(above_row, above_ref, bs); - if (bs == 4 && right_available) - memcpy(above_row + bs, above_ref + bs, bs); - else - memset(above_row + bs, above_row[bs - 1], bs); - } - } - above_row[-1] = left_available ? above_ref[-1] : 129; - } else { - memset(above_row, 127, bs * 2); - above_row[-1] = 127; - } - } - - // predict - if (mode == DC_PRED) { - dc_pred[left_available][up_available][tx_size](dst, dst_stride, - const_above_row, left_col); - } else { - pred[mode][tx_size](dst, dst_stride, const_above_row, left_col); - } -} - -void vp9_predict_intra_block(const MACROBLOCKD *xd, int bwl_in, TX_SIZE tx_size, - PREDICTION_MODE mode, const uint8_t *ref, - int ref_stride, uint8_t *dst, int dst_stride, - int aoff, int loff, int plane) { - const int bw = (1 << bwl_in); - const int txw = (1 << tx_size); - const int have_top = loff || (xd->above_mi != NULL); - const int have_left = aoff || (xd->left_mi != NULL); - const int have_right = (aoff + txw) < bw; - const int x = aoff * 4; - const int y = loff * 4; - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - build_intra_predictors_high(xd, ref, ref_stride, dst, dst_stride, mode, - tx_size, have_top, have_left, have_right, x, y, - plane, xd->bd); - return; - } -#endif - build_intra_predictors(xd, ref, ref_stride, dst, dst_stride, mode, tx_size, - have_top, have_left, have_right, x, y, plane); -} - -void vp9_init_intra_predictors(void) { - once(vp9_init_intra_predictors_internal); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_reconintra.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_reconintra.h deleted file mode 100644 index 426a35eb..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_reconintra.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_RECONINTRA_H_ -#define VPX_VP9_COMMON_VP9_RECONINTRA_H_ - -#include "vpx/vpx_integer.h" -#include "vp9/common/vp9_blockd.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vp9_init_intra_predictors(void); - -void vp9_predict_intra_block(const MACROBLOCKD *xd, int bwl_in, TX_SIZE tx_size, - PREDICTION_MODE mode, const uint8_t *ref, - int ref_stride, uint8_t *dst, int dst_stride, - int aoff, int loff, int plane); -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_RECONINTRA_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_rtcd.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_rtcd.c deleted file mode 100644 index 1a93b97e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_rtcd.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2011 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "./vpx_config.h" -#define RTCD_C -#include "./vp9_rtcd.h" -#include "vpx_ports/vpx_once.h" - -void vp9_rtcd(void) { once(setup_rtcd_internal); } diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_rtcd_defs.pl b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_rtcd_defs.pl deleted file mode 100644 index af3ff0e9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_rtcd_defs.pl +++ /dev/null @@ -1,228 +0,0 @@ -## -## Copyright (c) 2017 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -sub vp9_common_forward_decls() { -print <x_scale_fp >> REF_SCALE_SHIFT); -} - -static INLINE int scaled_y(int val, const struct scale_factors *sf) { - return (int)((int64_t)val * sf->y_scale_fp >> REF_SCALE_SHIFT); -} - -static int unscaled_value(int val, const struct scale_factors *sf) { - (void)sf; - return val; -} - -static int get_fixed_point_scale_factor(int other_size, int this_size) { - // Calculate scaling factor once for each reference frame - // and use fixed point scaling factors in decoding and encoding routines. - // Hardware implementations can calculate scale factor in device driver - // and use multiplication and shifting on hardware instead of division. - return (other_size << REF_SCALE_SHIFT) / this_size; -} - -MV32 vp9_scale_mv(const MV *mv, int x, int y, const struct scale_factors *sf) { - const int x_off_q4 = scaled_x(x << SUBPEL_BITS, sf) & SUBPEL_MASK; - const int y_off_q4 = scaled_y(y << SUBPEL_BITS, sf) & SUBPEL_MASK; - const MV32 res = { scaled_y(mv->row, sf) + y_off_q4, - scaled_x(mv->col, sf) + x_off_q4 }; - return res; -} - -#if CONFIG_VP9_HIGHBITDEPTH -void vp9_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w, - int other_h, int this_w, int this_h, - int use_highbd) { -#else -void vp9_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w, - int other_h, int this_w, int this_h) { -#endif - if (!valid_ref_frame_size(other_w, other_h, this_w, this_h)) { - sf->x_scale_fp = REF_INVALID_SCALE; - sf->y_scale_fp = REF_INVALID_SCALE; - return; - } - - sf->x_scale_fp = get_fixed_point_scale_factor(other_w, this_w); - sf->y_scale_fp = get_fixed_point_scale_factor(other_h, this_h); - sf->x_step_q4 = scaled_x(16, sf); - sf->y_step_q4 = scaled_y(16, sf); - - if (vp9_is_scaled(sf)) { - sf->scale_value_x = scaled_x; - sf->scale_value_y = scaled_y; - } else { - sf->scale_value_x = unscaled_value; - sf->scale_value_y = unscaled_value; - } - - // TODO(agrange): Investigate the best choice of functions to use here - // for EIGHTTAP_SMOOTH. Since it is not interpolating, need to choose what - // to do at full-pel offsets. The current selection, where the filter is - // applied in one direction only, and not at all for 0,0, seems to give the - // best quality, but it may be worth trying an additional mode that does - // do the filtering on full-pel. - - if (sf->x_step_q4 == 16) { - if (sf->y_step_q4 == 16) { - // No scaling in either direction. - sf->predict[0][0][0] = vpx_convolve_copy; - sf->predict[0][0][1] = vpx_convolve_avg; - sf->predict[0][1][0] = vpx_convolve8_vert; - sf->predict[0][1][1] = vpx_convolve8_avg_vert; - sf->predict[1][0][0] = vpx_convolve8_horiz; - sf->predict[1][0][1] = vpx_convolve8_avg_horiz; - } else { - // No scaling in x direction. Must always scale in the y direction. - sf->predict[0][0][0] = vpx_scaled_vert; - sf->predict[0][0][1] = vpx_scaled_avg_vert; - sf->predict[0][1][0] = vpx_scaled_vert; - sf->predict[0][1][1] = vpx_scaled_avg_vert; - sf->predict[1][0][0] = vpx_scaled_2d; - sf->predict[1][0][1] = vpx_scaled_avg_2d; - } - } else { - if (sf->y_step_q4 == 16) { - // No scaling in the y direction. Must always scale in the x direction. - sf->predict[0][0][0] = vpx_scaled_horiz; - sf->predict[0][0][1] = vpx_scaled_avg_horiz; - sf->predict[0][1][0] = vpx_scaled_2d; - sf->predict[0][1][1] = vpx_scaled_avg_2d; - sf->predict[1][0][0] = vpx_scaled_horiz; - sf->predict[1][0][1] = vpx_scaled_avg_horiz; - } else { - // Must always scale in both directions. - sf->predict[0][0][0] = vpx_scaled_2d; - sf->predict[0][0][1] = vpx_scaled_avg_2d; - sf->predict[0][1][0] = vpx_scaled_2d; - sf->predict[0][1][1] = vpx_scaled_avg_2d; - sf->predict[1][0][0] = vpx_scaled_2d; - sf->predict[1][0][1] = vpx_scaled_avg_2d; - } - } - - // 2D subpel motion always gets filtered in both directions - - if ((sf->x_step_q4 != 16) || (sf->y_step_q4 != 16)) { - sf->predict[1][1][0] = vpx_scaled_2d; - sf->predict[1][1][1] = vpx_scaled_avg_2d; - } else { - sf->predict[1][1][0] = vpx_convolve8; - sf->predict[1][1][1] = vpx_convolve8_avg; - } - -#if CONFIG_VP9_HIGHBITDEPTH - if (use_highbd) { - if (sf->x_step_q4 == 16) { - if (sf->y_step_q4 == 16) { - // No scaling in either direction. - sf->highbd_predict[0][0][0] = vpx_highbd_convolve_copy; - sf->highbd_predict[0][0][1] = vpx_highbd_convolve_avg; - sf->highbd_predict[0][1][0] = vpx_highbd_convolve8_vert; - sf->highbd_predict[0][1][1] = vpx_highbd_convolve8_avg_vert; - sf->highbd_predict[1][0][0] = vpx_highbd_convolve8_horiz; - sf->highbd_predict[1][0][1] = vpx_highbd_convolve8_avg_horiz; - } else { - // No scaling in x direction. Must always scale in the y direction. - sf->highbd_predict[0][0][0] = vpx_highbd_convolve8_vert; - sf->highbd_predict[0][0][1] = vpx_highbd_convolve8_avg_vert; - sf->highbd_predict[0][1][0] = vpx_highbd_convolve8_vert; - sf->highbd_predict[0][1][1] = vpx_highbd_convolve8_avg_vert; - sf->highbd_predict[1][0][0] = vpx_highbd_convolve8; - sf->highbd_predict[1][0][1] = vpx_highbd_convolve8_avg; - } - } else { - if (sf->y_step_q4 == 16) { - // No scaling in the y direction. Must always scale in the x direction. - sf->highbd_predict[0][0][0] = vpx_highbd_convolve8_horiz; - sf->highbd_predict[0][0][1] = vpx_highbd_convolve8_avg_horiz; - sf->highbd_predict[0][1][0] = vpx_highbd_convolve8; - sf->highbd_predict[0][1][1] = vpx_highbd_convolve8_avg; - sf->highbd_predict[1][0][0] = vpx_highbd_convolve8_horiz; - sf->highbd_predict[1][0][1] = vpx_highbd_convolve8_avg_horiz; - } else { - // Must always scale in both directions. - sf->highbd_predict[0][0][0] = vpx_highbd_convolve8; - sf->highbd_predict[0][0][1] = vpx_highbd_convolve8_avg; - sf->highbd_predict[0][1][0] = vpx_highbd_convolve8; - sf->highbd_predict[0][1][1] = vpx_highbd_convolve8_avg; - sf->highbd_predict[1][0][0] = vpx_highbd_convolve8; - sf->highbd_predict[1][0][1] = vpx_highbd_convolve8_avg; - } - } - // 2D subpel motion always gets filtered in both directions. - sf->highbd_predict[1][1][0] = vpx_highbd_convolve8; - sf->highbd_predict[1][1][1] = vpx_highbd_convolve8_avg; - } -#endif -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_scale.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_scale.h deleted file mode 100644 index 2f3b6094..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_scale.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_SCALE_H_ -#define VPX_VP9_COMMON_VP9_SCALE_H_ - -#include "vp9/common/vp9_mv.h" -#include "vpx_dsp/vpx_convolve.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define REF_SCALE_SHIFT 14 -#define REF_NO_SCALE (1 << REF_SCALE_SHIFT) -#define REF_INVALID_SCALE (-1) - -struct scale_factors { - int x_scale_fp; // horizontal fixed point scale factor - int y_scale_fp; // vertical fixed point scale factor - int x_step_q4; - int y_step_q4; - - int (*scale_value_x)(int val, const struct scale_factors *sf); - int (*scale_value_y)(int val, const struct scale_factors *sf); - - convolve_fn_t predict[2][2][2]; // horiz, vert, avg -#if CONFIG_VP9_HIGHBITDEPTH - highbd_convolve_fn_t highbd_predict[2][2][2]; // horiz, vert, avg -#endif -}; - -MV32 vp9_scale_mv(const MV *mv, int x, int y, const struct scale_factors *sf); - -#if CONFIG_VP9_HIGHBITDEPTH -void vp9_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w, - int other_h, int this_w, int this_h, - int use_highbd); -#else -void vp9_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w, - int other_h, int this_w, int this_h); -#endif - -static INLINE int vp9_is_valid_scale(const struct scale_factors *sf) { - return sf->x_scale_fp != REF_INVALID_SCALE && - sf->y_scale_fp != REF_INVALID_SCALE; -} - -static INLINE int vp9_is_scaled(const struct scale_factors *sf) { - return vp9_is_valid_scale(sf) && - (sf->x_scale_fp != REF_NO_SCALE || sf->y_scale_fp != REF_NO_SCALE); -} - -static INLINE int valid_ref_frame_size(int ref_width, int ref_height, - int this_width, int this_height) { - return 2 * this_width >= ref_width && 2 * this_height >= ref_height && - this_width <= 16 * ref_width && this_height <= 16 * ref_height; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_SCALE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_scan.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_scan.c deleted file mode 100644 index adacb7ef..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_scan.c +++ /dev/null @@ -1,725 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "vp9/common/vp9_scan.h" - -DECLARE_ALIGNED(16, static const int16_t, default_scan_4x4[16]) = { - 0, 4, 1, 5, 8, 2, 12, 9, 3, 6, 13, 10, 7, 14, 11, 15, -}; - -DECLARE_ALIGNED(16, static const int16_t, col_scan_4x4[16]) = { - 0, 4, 8, 1, 12, 5, 9, 2, 13, 6, 10, 3, 7, 14, 11, 15, -}; - -DECLARE_ALIGNED(16, static const int16_t, row_scan_4x4[16]) = { - 0, 1, 4, 2, 5, 3, 6, 8, 9, 7, 12, 10, 13, 11, 14, 15, -}; - -DECLARE_ALIGNED(16, static const int16_t, default_scan_8x8[64]) = { - 0, 8, 1, 16, 9, 2, 17, 24, 10, 3, 18, 25, 32, 11, 4, 26, - 33, 19, 40, 12, 34, 27, 5, 41, 20, 48, 13, 35, 42, 28, 21, 6, - 49, 56, 36, 43, 29, 7, 14, 50, 57, 44, 22, 37, 15, 51, 58, 30, - 45, 23, 52, 59, 38, 31, 60, 53, 46, 39, 61, 54, 47, 62, 55, 63, -}; - -DECLARE_ALIGNED(16, static const int16_t, col_scan_8x8[64]) = { - 0, 8, 16, 1, 24, 9, 32, 17, 2, 40, 25, 10, 33, 18, 48, 3, - 26, 41, 11, 56, 19, 34, 4, 49, 27, 42, 12, 35, 20, 57, 50, 28, - 5, 43, 13, 36, 58, 51, 21, 44, 6, 29, 59, 37, 14, 52, 22, 7, - 45, 60, 30, 15, 38, 53, 23, 46, 31, 61, 39, 54, 47, 62, 55, 63, -}; - -DECLARE_ALIGNED(16, static const int16_t, row_scan_8x8[64]) = { - 0, 1, 2, 8, 9, 3, 16, 10, 4, 17, 11, 24, 5, 18, 25, 12, - 19, 26, 32, 6, 13, 20, 33, 27, 7, 34, 40, 21, 28, 41, 14, 35, - 48, 42, 29, 36, 49, 22, 43, 15, 56, 37, 50, 44, 30, 57, 23, 51, - 58, 45, 38, 52, 31, 59, 53, 46, 60, 39, 61, 47, 54, 55, 62, 63, -}; - -DECLARE_ALIGNED(16, static const int16_t, default_scan_16x16[256]) = { - 0, 16, 1, 32, 17, 2, 48, 33, 18, 3, 64, 34, 49, 19, 65, - 80, 50, 4, 35, 66, 20, 81, 96, 51, 5, 36, 82, 97, 67, 112, - 21, 52, 98, 37, 83, 113, 6, 68, 128, 53, 22, 99, 114, 84, 7, - 129, 38, 69, 100, 115, 144, 130, 85, 54, 23, 8, 145, 39, 70, 116, - 101, 131, 160, 146, 55, 86, 24, 71, 132, 117, 161, 40, 9, 102, 147, - 176, 162, 87, 56, 25, 133, 118, 177, 148, 72, 103, 41, 163, 10, 192, - 178, 88, 57, 134, 149, 119, 26, 164, 73, 104, 193, 42, 179, 208, 11, - 135, 89, 165, 120, 150, 58, 194, 180, 27, 74, 209, 105, 151, 136, 43, - 90, 224, 166, 195, 181, 121, 210, 59, 12, 152, 106, 167, 196, 75, 137, - 225, 211, 240, 182, 122, 91, 28, 197, 13, 226, 168, 183, 153, 44, 212, - 138, 107, 241, 60, 29, 123, 198, 184, 227, 169, 242, 76, 213, 154, 45, - 92, 14, 199, 139, 61, 228, 214, 170, 185, 243, 108, 77, 155, 30, 15, - 200, 229, 124, 215, 244, 93, 46, 186, 171, 201, 109, 140, 230, 62, 216, - 245, 31, 125, 78, 156, 231, 47, 187, 202, 217, 94, 246, 141, 63, 232, - 172, 110, 247, 157, 79, 218, 203, 126, 233, 188, 248, 95, 173, 142, 219, - 111, 249, 234, 158, 127, 189, 204, 250, 235, 143, 174, 220, 205, 159, 251, - 190, 221, 175, 236, 237, 191, 206, 252, 222, 253, 207, 238, 223, 254, 239, - 255, -}; - -DECLARE_ALIGNED(16, static const int16_t, col_scan_16x16[256]) = { - 0, 16, 32, 48, 1, 64, 17, 80, 33, 96, 49, 2, 65, 112, 18, - 81, 34, 128, 50, 97, 3, 66, 144, 19, 113, 35, 82, 160, 98, 51, - 129, 4, 67, 176, 20, 114, 145, 83, 36, 99, 130, 52, 192, 5, 161, - 68, 115, 21, 146, 84, 208, 177, 37, 131, 100, 53, 162, 224, 69, 6, - 116, 193, 147, 85, 22, 240, 132, 38, 178, 101, 163, 54, 209, 117, 70, - 7, 148, 194, 86, 179, 225, 23, 133, 39, 164, 8, 102, 210, 241, 55, - 195, 118, 149, 71, 180, 24, 87, 226, 134, 165, 211, 40, 103, 56, 72, - 150, 196, 242, 119, 9, 181, 227, 88, 166, 25, 135, 41, 104, 212, 57, - 151, 197, 120, 73, 243, 182, 136, 167, 213, 89, 10, 228, 105, 152, 198, - 26, 42, 121, 183, 244, 168, 58, 137, 229, 74, 214, 90, 153, 199, 184, - 11, 106, 245, 27, 122, 230, 169, 43, 215, 59, 200, 138, 185, 246, 75, - 12, 91, 154, 216, 231, 107, 28, 44, 201, 123, 170, 60, 247, 232, 76, - 139, 13, 92, 217, 186, 248, 155, 108, 29, 124, 45, 202, 233, 171, 61, - 14, 77, 140, 15, 249, 93, 30, 187, 156, 218, 46, 109, 125, 62, 172, - 78, 203, 31, 141, 234, 94, 47, 188, 63, 157, 110, 250, 219, 79, 126, - 204, 173, 142, 95, 189, 111, 235, 158, 220, 251, 127, 174, 143, 205, 236, - 159, 190, 221, 252, 175, 206, 237, 191, 253, 222, 238, 207, 254, 223, 239, - 255, -}; - -DECLARE_ALIGNED(16, static const int16_t, row_scan_16x16[256]) = { - 0, 1, 2, 16, 3, 17, 4, 18, 32, 5, 33, 19, 6, 34, 48, - 20, 49, 7, 35, 21, 50, 64, 8, 36, 65, 22, 51, 37, 80, 9, - 66, 52, 23, 38, 81, 67, 10, 53, 24, 82, 68, 96, 39, 11, 54, - 83, 97, 69, 25, 98, 84, 40, 112, 55, 12, 70, 99, 113, 85, 26, - 41, 56, 114, 100, 13, 71, 128, 86, 27, 115, 101, 129, 42, 57, 72, - 116, 14, 87, 130, 102, 144, 73, 131, 117, 28, 58, 15, 88, 43, 145, - 103, 132, 146, 118, 74, 160, 89, 133, 104, 29, 59, 147, 119, 44, 161, - 148, 90, 105, 134, 162, 120, 176, 75, 135, 149, 30, 60, 163, 177, 45, - 121, 91, 106, 164, 178, 150, 192, 136, 165, 179, 31, 151, 193, 76, 122, - 61, 137, 194, 107, 152, 180, 208, 46, 166, 167, 195, 92, 181, 138, 209, - 123, 153, 224, 196, 77, 168, 210, 182, 240, 108, 197, 62, 154, 225, 183, - 169, 211, 47, 139, 93, 184, 226, 212, 241, 198, 170, 124, 155, 199, 78, - 213, 185, 109, 227, 200, 63, 228, 242, 140, 214, 171, 186, 156, 229, 243, - 125, 94, 201, 244, 215, 216, 230, 141, 187, 202, 79, 172, 110, 157, 245, - 217, 231, 95, 246, 232, 126, 203, 247, 233, 173, 218, 142, 111, 158, 188, - 248, 127, 234, 219, 249, 189, 204, 143, 174, 159, 250, 235, 205, 220, 175, - 190, 251, 221, 191, 206, 236, 207, 237, 252, 222, 253, 223, 238, 239, 254, - 255, -}; - -DECLARE_ALIGNED(16, static const int16_t, default_scan_32x32[1024]) = { - 0, 32, 1, 64, 33, 2, 96, 65, 34, 128, 3, 97, 66, - 160, 129, 35, 98, 4, 67, 130, 161, 192, 36, 99, 224, 5, - 162, 193, 68, 131, 37, 100, 225, 194, 256, 163, 69, 132, 6, - 226, 257, 288, 195, 101, 164, 38, 258, 7, 227, 289, 133, 320, - 70, 196, 165, 290, 259, 228, 39, 321, 102, 352, 8, 197, 71, - 134, 322, 291, 260, 353, 384, 229, 166, 103, 40, 354, 323, 292, - 135, 385, 198, 261, 72, 9, 416, 167, 386, 355, 230, 324, 104, - 293, 41, 417, 199, 136, 262, 387, 448, 325, 356, 10, 73, 418, - 231, 168, 449, 294, 388, 105, 419, 263, 42, 200, 357, 450, 137, - 480, 74, 326, 232, 11, 389, 169, 295, 420, 106, 451, 481, 358, - 264, 327, 201, 43, 138, 512, 482, 390, 296, 233, 170, 421, 75, - 452, 359, 12, 513, 265, 483, 328, 107, 202, 514, 544, 422, 391, - 453, 139, 44, 234, 484, 297, 360, 171, 76, 515, 545, 266, 329, - 454, 13, 423, 203, 108, 546, 485, 576, 298, 235, 140, 361, 330, - 172, 547, 45, 455, 267, 577, 486, 77, 204, 362, 608, 14, 299, - 578, 109, 236, 487, 609, 331, 141, 579, 46, 15, 173, 610, 363, - 78, 205, 16, 110, 237, 611, 142, 47, 174, 79, 206, 17, 111, - 238, 48, 143, 80, 175, 112, 207, 49, 18, 239, 81, 113, 19, - 50, 82, 114, 51, 83, 115, 640, 516, 392, 268, 144, 20, 672, - 641, 548, 517, 424, 393, 300, 269, 176, 145, 52, 21, 704, 673, - 642, 580, 549, 518, 456, 425, 394, 332, 301, 270, 208, 177, 146, - 84, 53, 22, 736, 705, 674, 643, 612, 581, 550, 519, 488, 457, - 426, 395, 364, 333, 302, 271, 240, 209, 178, 147, 116, 85, 54, - 23, 737, 706, 675, 613, 582, 551, 489, 458, 427, 365, 334, 303, - 241, 210, 179, 117, 86, 55, 738, 707, 614, 583, 490, 459, 366, - 335, 242, 211, 118, 87, 739, 615, 491, 367, 243, 119, 768, 644, - 520, 396, 272, 148, 24, 800, 769, 676, 645, 552, 521, 428, 397, - 304, 273, 180, 149, 56, 25, 832, 801, 770, 708, 677, 646, 584, - 553, 522, 460, 429, 398, 336, 305, 274, 212, 181, 150, 88, 57, - 26, 864, 833, 802, 771, 740, 709, 678, 647, 616, 585, 554, 523, - 492, 461, 430, 399, 368, 337, 306, 275, 244, 213, 182, 151, 120, - 89, 58, 27, 865, 834, 803, 741, 710, 679, 617, 586, 555, 493, - 462, 431, 369, 338, 307, 245, 214, 183, 121, 90, 59, 866, 835, - 742, 711, 618, 587, 494, 463, 370, 339, 246, 215, 122, 91, 867, - 743, 619, 495, 371, 247, 123, 896, 772, 648, 524, 400, 276, 152, - 28, 928, 897, 804, 773, 680, 649, 556, 525, 432, 401, 308, 277, - 184, 153, 60, 29, 960, 929, 898, 836, 805, 774, 712, 681, 650, - 588, 557, 526, 464, 433, 402, 340, 309, 278, 216, 185, 154, 92, - 61, 30, 992, 961, 930, 899, 868, 837, 806, 775, 744, 713, 682, - 651, 620, 589, 558, 527, 496, 465, 434, 403, 372, 341, 310, 279, - 248, 217, 186, 155, 124, 93, 62, 31, 993, 962, 931, 869, 838, - 807, 745, 714, 683, 621, 590, 559, 497, 466, 435, 373, 342, 311, - 249, 218, 187, 125, 94, 63, 994, 963, 870, 839, 746, 715, 622, - 591, 498, 467, 374, 343, 250, 219, 126, 95, 995, 871, 747, 623, - 499, 375, 251, 127, 900, 776, 652, 528, 404, 280, 156, 932, 901, - 808, 777, 684, 653, 560, 529, 436, 405, 312, 281, 188, 157, 964, - 933, 902, 840, 809, 778, 716, 685, 654, 592, 561, 530, 468, 437, - 406, 344, 313, 282, 220, 189, 158, 996, 965, 934, 903, 872, 841, - 810, 779, 748, 717, 686, 655, 624, 593, 562, 531, 500, 469, 438, - 407, 376, 345, 314, 283, 252, 221, 190, 159, 997, 966, 935, 873, - 842, 811, 749, 718, 687, 625, 594, 563, 501, 470, 439, 377, 346, - 315, 253, 222, 191, 998, 967, 874, 843, 750, 719, 626, 595, 502, - 471, 378, 347, 254, 223, 999, 875, 751, 627, 503, 379, 255, 904, - 780, 656, 532, 408, 284, 936, 905, 812, 781, 688, 657, 564, 533, - 440, 409, 316, 285, 968, 937, 906, 844, 813, 782, 720, 689, 658, - 596, 565, 534, 472, 441, 410, 348, 317, 286, 1000, 969, 938, 907, - 876, 845, 814, 783, 752, 721, 690, 659, 628, 597, 566, 535, 504, - 473, 442, 411, 380, 349, 318, 287, 1001, 970, 939, 877, 846, 815, - 753, 722, 691, 629, 598, 567, 505, 474, 443, 381, 350, 319, 1002, - 971, 878, 847, 754, 723, 630, 599, 506, 475, 382, 351, 1003, 879, - 755, 631, 507, 383, 908, 784, 660, 536, 412, 940, 909, 816, 785, - 692, 661, 568, 537, 444, 413, 972, 941, 910, 848, 817, 786, 724, - 693, 662, 600, 569, 538, 476, 445, 414, 1004, 973, 942, 911, 880, - 849, 818, 787, 756, 725, 694, 663, 632, 601, 570, 539, 508, 477, - 446, 415, 1005, 974, 943, 881, 850, 819, 757, 726, 695, 633, 602, - 571, 509, 478, 447, 1006, 975, 882, 851, 758, 727, 634, 603, 510, - 479, 1007, 883, 759, 635, 511, 912, 788, 664, 540, 944, 913, 820, - 789, 696, 665, 572, 541, 976, 945, 914, 852, 821, 790, 728, 697, - 666, 604, 573, 542, 1008, 977, 946, 915, 884, 853, 822, 791, 760, - 729, 698, 667, 636, 605, 574, 543, 1009, 978, 947, 885, 854, 823, - 761, 730, 699, 637, 606, 575, 1010, 979, 886, 855, 762, 731, 638, - 607, 1011, 887, 763, 639, 916, 792, 668, 948, 917, 824, 793, 700, - 669, 980, 949, 918, 856, 825, 794, 732, 701, 670, 1012, 981, 950, - 919, 888, 857, 826, 795, 764, 733, 702, 671, 1013, 982, 951, 889, - 858, 827, 765, 734, 703, 1014, 983, 890, 859, 766, 735, 1015, 891, - 767, 920, 796, 952, 921, 828, 797, 984, 953, 922, 860, 829, 798, - 1016, 985, 954, 923, 892, 861, 830, 799, 1017, 986, 955, 893, 862, - 831, 1018, 987, 894, 863, 1019, 895, 924, 956, 925, 988, 957, 926, - 1020, 989, 958, 927, 1021, 990, 959, 1022, 991, 1023, -}; - -// Neighborhood 2-tuples for various scans and blocksizes, -// in {top, left} order for each position in corresponding scan order. -DECLARE_ALIGNED(16, static const int16_t, - default_scan_4x4_neighbors[17 * MAX_NEIGHBORS]) = { - 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 1, 1, 8, 8, 5, 8, 2, - 2, 2, 5, 9, 12, 6, 9, 3, 6, 10, 13, 7, 10, 11, 14, 0, 0, -}; - -DECLARE_ALIGNED(16, static const int16_t, - col_scan_4x4_neighbors[17 * MAX_NEIGHBORS]) = { - 0, 0, 0, 0, 4, 4, 0, 0, 8, 8, 1, 1, 5, 5, 1, 1, 9, - 9, 2, 2, 6, 6, 2, 2, 3, 3, 10, 10, 7, 7, 11, 11, 0, 0, -}; - -DECLARE_ALIGNED(16, static const int16_t, - row_scan_4x4_neighbors[17 * MAX_NEIGHBORS]) = { - 0, 0, 0, 0, 0, 0, 1, 1, 4, 4, 2, 2, 5, 5, 4, 4, 8, - 8, 6, 6, 8, 8, 9, 9, 12, 12, 10, 10, 13, 13, 14, 14, 0, 0, -}; - -DECLARE_ALIGNED(16, static const int16_t, - col_scan_8x8_neighbors[65 * MAX_NEIGHBORS]) = { - 0, 0, 0, 0, 8, 8, 0, 0, 16, 16, 1, 1, 24, 24, 9, 9, 1, 1, 32, - 32, 17, 17, 2, 2, 25, 25, 10, 10, 40, 40, 2, 2, 18, 18, 33, 33, 3, 3, - 48, 48, 11, 11, 26, 26, 3, 3, 41, 41, 19, 19, 34, 34, 4, 4, 27, 27, 12, - 12, 49, 49, 42, 42, 20, 20, 4, 4, 35, 35, 5, 5, 28, 28, 50, 50, 43, 43, - 13, 13, 36, 36, 5, 5, 21, 21, 51, 51, 29, 29, 6, 6, 44, 44, 14, 14, 6, - 6, 37, 37, 52, 52, 22, 22, 7, 7, 30, 30, 45, 45, 15, 15, 38, 38, 23, 23, - 53, 53, 31, 31, 46, 46, 39, 39, 54, 54, 47, 47, 55, 55, 0, 0, -}; - -DECLARE_ALIGNED(16, static const int16_t, - row_scan_8x8_neighbors[65 * MAX_NEIGHBORS]) = { - 0, 0, 0, 0, 1, 1, 0, 0, 8, 8, 2, 2, 8, 8, 9, 9, 3, 3, 16, - 16, 10, 10, 16, 16, 4, 4, 17, 17, 24, 24, 11, 11, 18, 18, 25, 25, 24, 24, - 5, 5, 12, 12, 19, 19, 32, 32, 26, 26, 6, 6, 33, 33, 32, 32, 20, 20, 27, - 27, 40, 40, 13, 13, 34, 34, 40, 40, 41, 41, 28, 28, 35, 35, 48, 48, 21, 21, - 42, 42, 14, 14, 48, 48, 36, 36, 49, 49, 43, 43, 29, 29, 56, 56, 22, 22, 50, - 50, 57, 57, 44, 44, 37, 37, 51, 51, 30, 30, 58, 58, 52, 52, 45, 45, 59, 59, - 38, 38, 60, 60, 46, 46, 53, 53, 54, 54, 61, 61, 62, 62, 0, 0, -}; - -DECLARE_ALIGNED(16, static const int16_t, - default_scan_8x8_neighbors[65 * MAX_NEIGHBORS]) = { - 0, 0, 0, 0, 0, 0, 8, 8, 1, 8, 1, 1, 9, 16, 16, 16, 2, 9, 2, - 2, 10, 17, 17, 24, 24, 24, 3, 10, 3, 3, 18, 25, 25, 32, 11, 18, 32, 32, - 4, 11, 26, 33, 19, 26, 4, 4, 33, 40, 12, 19, 40, 40, 5, 12, 27, 34, 34, - 41, 20, 27, 13, 20, 5, 5, 41, 48, 48, 48, 28, 35, 35, 42, 21, 28, 6, 6, - 6, 13, 42, 49, 49, 56, 36, 43, 14, 21, 29, 36, 7, 14, 43, 50, 50, 57, 22, - 29, 37, 44, 15, 22, 44, 51, 51, 58, 30, 37, 23, 30, 52, 59, 45, 52, 38, 45, - 31, 38, 53, 60, 46, 53, 39, 46, 54, 61, 47, 54, 55, 62, 0, 0, -}; - -DECLARE_ALIGNED(16, static const int16_t, - col_scan_16x16_neighbors[257 * MAX_NEIGHBORS]) = { - 0, 0, 0, 0, 16, 16, 32, 32, 0, 0, 48, 48, 1, 1, 64, - 64, 17, 17, 80, 80, 33, 33, 1, 1, 49, 49, 96, 96, 2, 2, - 65, 65, 18, 18, 112, 112, 34, 34, 81, 81, 2, 2, 50, 50, 128, - 128, 3, 3, 97, 97, 19, 19, 66, 66, 144, 144, 82, 82, 35, 35, - 113, 113, 3, 3, 51, 51, 160, 160, 4, 4, 98, 98, 129, 129, 67, - 67, 20, 20, 83, 83, 114, 114, 36, 36, 176, 176, 4, 4, 145, 145, - 52, 52, 99, 99, 5, 5, 130, 130, 68, 68, 192, 192, 161, 161, 21, - 21, 115, 115, 84, 84, 37, 37, 146, 146, 208, 208, 53, 53, 5, 5, - 100, 100, 177, 177, 131, 131, 69, 69, 6, 6, 224, 224, 116, 116, 22, - 22, 162, 162, 85, 85, 147, 147, 38, 38, 193, 193, 101, 101, 54, 54, - 6, 6, 132, 132, 178, 178, 70, 70, 163, 163, 209, 209, 7, 7, 117, - 117, 23, 23, 148, 148, 7, 7, 86, 86, 194, 194, 225, 225, 39, 39, - 179, 179, 102, 102, 133, 133, 55, 55, 164, 164, 8, 8, 71, 71, 210, - 210, 118, 118, 149, 149, 195, 195, 24, 24, 87, 87, 40, 40, 56, 56, - 134, 134, 180, 180, 226, 226, 103, 103, 8, 8, 165, 165, 211, 211, 72, - 72, 150, 150, 9, 9, 119, 119, 25, 25, 88, 88, 196, 196, 41, 41, - 135, 135, 181, 181, 104, 104, 57, 57, 227, 227, 166, 166, 120, 120, 151, - 151, 197, 197, 73, 73, 9, 9, 212, 212, 89, 89, 136, 136, 182, 182, - 10, 10, 26, 26, 105, 105, 167, 167, 228, 228, 152, 152, 42, 42, 121, - 121, 213, 213, 58, 58, 198, 198, 74, 74, 137, 137, 183, 183, 168, 168, - 10, 10, 90, 90, 229, 229, 11, 11, 106, 106, 214, 214, 153, 153, 27, - 27, 199, 199, 43, 43, 184, 184, 122, 122, 169, 169, 230, 230, 59, 59, - 11, 11, 75, 75, 138, 138, 200, 200, 215, 215, 91, 91, 12, 12, 28, - 28, 185, 185, 107, 107, 154, 154, 44, 44, 231, 231, 216, 216, 60, 60, - 123, 123, 12, 12, 76, 76, 201, 201, 170, 170, 232, 232, 139, 139, 92, - 92, 13, 13, 108, 108, 29, 29, 186, 186, 217, 217, 155, 155, 45, 45, - 13, 13, 61, 61, 124, 124, 14, 14, 233, 233, 77, 77, 14, 14, 171, - 171, 140, 140, 202, 202, 30, 30, 93, 93, 109, 109, 46, 46, 156, 156, - 62, 62, 187, 187, 15, 15, 125, 125, 218, 218, 78, 78, 31, 31, 172, - 172, 47, 47, 141, 141, 94, 94, 234, 234, 203, 203, 63, 63, 110, 110, - 188, 188, 157, 157, 126, 126, 79, 79, 173, 173, 95, 95, 219, 219, 142, - 142, 204, 204, 235, 235, 111, 111, 158, 158, 127, 127, 189, 189, 220, 220, - 143, 143, 174, 174, 205, 205, 236, 236, 159, 159, 190, 190, 221, 221, 175, - 175, 237, 237, 206, 206, 222, 222, 191, 191, 238, 238, 207, 207, 223, 223, - 239, 239, 0, 0, -}; - -DECLARE_ALIGNED(16, static const int16_t, - row_scan_16x16_neighbors[257 * MAX_NEIGHBORS]) = { - 0, 0, 0, 0, 1, 1, 0, 0, 2, 2, 16, 16, 3, 3, 17, - 17, 16, 16, 4, 4, 32, 32, 18, 18, 5, 5, 33, 33, 32, 32, - 19, 19, 48, 48, 6, 6, 34, 34, 20, 20, 49, 49, 48, 48, 7, - 7, 35, 35, 64, 64, 21, 21, 50, 50, 36, 36, 64, 64, 8, 8, - 65, 65, 51, 51, 22, 22, 37, 37, 80, 80, 66, 66, 9, 9, 52, - 52, 23, 23, 81, 81, 67, 67, 80, 80, 38, 38, 10, 10, 53, 53, - 82, 82, 96, 96, 68, 68, 24, 24, 97, 97, 83, 83, 39, 39, 96, - 96, 54, 54, 11, 11, 69, 69, 98, 98, 112, 112, 84, 84, 25, 25, - 40, 40, 55, 55, 113, 113, 99, 99, 12, 12, 70, 70, 112, 112, 85, - 85, 26, 26, 114, 114, 100, 100, 128, 128, 41, 41, 56, 56, 71, 71, - 115, 115, 13, 13, 86, 86, 129, 129, 101, 101, 128, 128, 72, 72, 130, - 130, 116, 116, 27, 27, 57, 57, 14, 14, 87, 87, 42, 42, 144, 144, - 102, 102, 131, 131, 145, 145, 117, 117, 73, 73, 144, 144, 88, 88, 132, - 132, 103, 103, 28, 28, 58, 58, 146, 146, 118, 118, 43, 43, 160, 160, - 147, 147, 89, 89, 104, 104, 133, 133, 161, 161, 119, 119, 160, 160, 74, - 74, 134, 134, 148, 148, 29, 29, 59, 59, 162, 162, 176, 176, 44, 44, - 120, 120, 90, 90, 105, 105, 163, 163, 177, 177, 149, 149, 176, 176, 135, - 135, 164, 164, 178, 178, 30, 30, 150, 150, 192, 192, 75, 75, 121, 121, - 60, 60, 136, 136, 193, 193, 106, 106, 151, 151, 179, 179, 192, 192, 45, - 45, 165, 165, 166, 166, 194, 194, 91, 91, 180, 180, 137, 137, 208, 208, - 122, 122, 152, 152, 208, 208, 195, 195, 76, 76, 167, 167, 209, 209, 181, - 181, 224, 224, 107, 107, 196, 196, 61, 61, 153, 153, 224, 224, 182, 182, - 168, 168, 210, 210, 46, 46, 138, 138, 92, 92, 183, 183, 225, 225, 211, - 211, 240, 240, 197, 197, 169, 169, 123, 123, 154, 154, 198, 198, 77, 77, - 212, 212, 184, 184, 108, 108, 226, 226, 199, 199, 62, 62, 227, 227, 241, - 241, 139, 139, 213, 213, 170, 170, 185, 185, 155, 155, 228, 228, 242, 242, - 124, 124, 93, 93, 200, 200, 243, 243, 214, 214, 215, 215, 229, 229, 140, - 140, 186, 186, 201, 201, 78, 78, 171, 171, 109, 109, 156, 156, 244, 244, - 216, 216, 230, 230, 94, 94, 245, 245, 231, 231, 125, 125, 202, 202, 246, - 246, 232, 232, 172, 172, 217, 217, 141, 141, 110, 110, 157, 157, 187, 187, - 247, 247, 126, 126, 233, 233, 218, 218, 248, 248, 188, 188, 203, 203, 142, - 142, 173, 173, 158, 158, 249, 249, 234, 234, 204, 204, 219, 219, 174, 174, - 189, 189, 250, 250, 220, 220, 190, 190, 205, 205, 235, 235, 206, 206, 236, - 236, 251, 251, 221, 221, 252, 252, 222, 222, 237, 237, 238, 238, 253, 253, - 254, 254, 0, 0, -}; - -DECLARE_ALIGNED(16, static const int16_t, - default_scan_16x16_neighbors[257 * MAX_NEIGHBORS]) = { - 0, 0, 0, 0, 0, 0, 16, 16, 1, 16, 1, 1, 32, 32, 17, - 32, 2, 17, 2, 2, 48, 48, 18, 33, 33, 48, 3, 18, 49, 64, - 64, 64, 34, 49, 3, 3, 19, 34, 50, 65, 4, 19, 65, 80, 80, - 80, 35, 50, 4, 4, 20, 35, 66, 81, 81, 96, 51, 66, 96, 96, - 5, 20, 36, 51, 82, 97, 21, 36, 67, 82, 97, 112, 5, 5, 52, - 67, 112, 112, 37, 52, 6, 21, 83, 98, 98, 113, 68, 83, 6, 6, - 113, 128, 22, 37, 53, 68, 84, 99, 99, 114, 128, 128, 114, 129, 69, - 84, 38, 53, 7, 22, 7, 7, 129, 144, 23, 38, 54, 69, 100, 115, - 85, 100, 115, 130, 144, 144, 130, 145, 39, 54, 70, 85, 8, 23, 55, - 70, 116, 131, 101, 116, 145, 160, 24, 39, 8, 8, 86, 101, 131, 146, - 160, 160, 146, 161, 71, 86, 40, 55, 9, 24, 117, 132, 102, 117, 161, - 176, 132, 147, 56, 71, 87, 102, 25, 40, 147, 162, 9, 9, 176, 176, - 162, 177, 72, 87, 41, 56, 118, 133, 133, 148, 103, 118, 10, 25, 148, - 163, 57, 72, 88, 103, 177, 192, 26, 41, 163, 178, 192, 192, 10, 10, - 119, 134, 73, 88, 149, 164, 104, 119, 134, 149, 42, 57, 178, 193, 164, - 179, 11, 26, 58, 73, 193, 208, 89, 104, 135, 150, 120, 135, 27, 42, - 74, 89, 208, 208, 150, 165, 179, 194, 165, 180, 105, 120, 194, 209, 43, - 58, 11, 11, 136, 151, 90, 105, 151, 166, 180, 195, 59, 74, 121, 136, - 209, 224, 195, 210, 224, 224, 166, 181, 106, 121, 75, 90, 12, 27, 181, - 196, 12, 12, 210, 225, 152, 167, 167, 182, 137, 152, 28, 43, 196, 211, - 122, 137, 91, 106, 225, 240, 44, 59, 13, 28, 107, 122, 182, 197, 168, - 183, 211, 226, 153, 168, 226, 241, 60, 75, 197, 212, 138, 153, 29, 44, - 76, 91, 13, 13, 183, 198, 123, 138, 45, 60, 212, 227, 198, 213, 154, - 169, 169, 184, 227, 242, 92, 107, 61, 76, 139, 154, 14, 29, 14, 14, - 184, 199, 213, 228, 108, 123, 199, 214, 228, 243, 77, 92, 30, 45, 170, - 185, 155, 170, 185, 200, 93, 108, 124, 139, 214, 229, 46, 61, 200, 215, - 229, 244, 15, 30, 109, 124, 62, 77, 140, 155, 215, 230, 31, 46, 171, - 186, 186, 201, 201, 216, 78, 93, 230, 245, 125, 140, 47, 62, 216, 231, - 156, 171, 94, 109, 231, 246, 141, 156, 63, 78, 202, 217, 187, 202, 110, - 125, 217, 232, 172, 187, 232, 247, 79, 94, 157, 172, 126, 141, 203, 218, - 95, 110, 233, 248, 218, 233, 142, 157, 111, 126, 173, 188, 188, 203, 234, - 249, 219, 234, 127, 142, 158, 173, 204, 219, 189, 204, 143, 158, 235, 250, - 174, 189, 205, 220, 159, 174, 220, 235, 221, 236, 175, 190, 190, 205, 236, - 251, 206, 221, 237, 252, 191, 206, 222, 237, 207, 222, 238, 253, 223, 238, - 239, 254, 0, 0, -}; - -DECLARE_ALIGNED(16, static const int16_t, - default_scan_32x32_neighbors[1025 * MAX_NEIGHBORS]) = { - 0, 0, 0, 0, 0, 0, 32, 32, 1, 32, 1, 1, 64, 64, - 33, 64, 2, 33, 96, 96, 2, 2, 65, 96, 34, 65, 128, 128, - 97, 128, 3, 34, 66, 97, 3, 3, 35, 66, 98, 129, 129, 160, - 160, 160, 4, 35, 67, 98, 192, 192, 4, 4, 130, 161, 161, 192, - 36, 67, 99, 130, 5, 36, 68, 99, 193, 224, 162, 193, 224, 224, - 131, 162, 37, 68, 100, 131, 5, 5, 194, 225, 225, 256, 256, 256, - 163, 194, 69, 100, 132, 163, 6, 37, 226, 257, 6, 6, 195, 226, - 257, 288, 101, 132, 288, 288, 38, 69, 164, 195, 133, 164, 258, 289, - 227, 258, 196, 227, 7, 38, 289, 320, 70, 101, 320, 320, 7, 7, - 165, 196, 39, 70, 102, 133, 290, 321, 259, 290, 228, 259, 321, 352, - 352, 352, 197, 228, 134, 165, 71, 102, 8, 39, 322, 353, 291, 322, - 260, 291, 103, 134, 353, 384, 166, 197, 229, 260, 40, 71, 8, 8, - 384, 384, 135, 166, 354, 385, 323, 354, 198, 229, 292, 323, 72, 103, - 261, 292, 9, 40, 385, 416, 167, 198, 104, 135, 230, 261, 355, 386, - 416, 416, 293, 324, 324, 355, 9, 9, 41, 72, 386, 417, 199, 230, - 136, 167, 417, 448, 262, 293, 356, 387, 73, 104, 387, 418, 231, 262, - 10, 41, 168, 199, 325, 356, 418, 449, 105, 136, 448, 448, 42, 73, - 294, 325, 200, 231, 10, 10, 357, 388, 137, 168, 263, 294, 388, 419, - 74, 105, 419, 450, 449, 480, 326, 357, 232, 263, 295, 326, 169, 200, - 11, 42, 106, 137, 480, 480, 450, 481, 358, 389, 264, 295, 201, 232, - 138, 169, 389, 420, 43, 74, 420, 451, 327, 358, 11, 11, 481, 512, - 233, 264, 451, 482, 296, 327, 75, 106, 170, 201, 482, 513, 512, 512, - 390, 421, 359, 390, 421, 452, 107, 138, 12, 43, 202, 233, 452, 483, - 265, 296, 328, 359, 139, 170, 44, 75, 483, 514, 513, 544, 234, 265, - 297, 328, 422, 453, 12, 12, 391, 422, 171, 202, 76, 107, 514, 545, - 453, 484, 544, 544, 266, 297, 203, 234, 108, 139, 329, 360, 298, 329, - 140, 171, 515, 546, 13, 44, 423, 454, 235, 266, 545, 576, 454, 485, - 45, 76, 172, 203, 330, 361, 576, 576, 13, 13, 267, 298, 546, 577, - 77, 108, 204, 235, 455, 486, 577, 608, 299, 330, 109, 140, 547, 578, - 14, 45, 14, 14, 141, 172, 578, 609, 331, 362, 46, 77, 173, 204, - 15, 15, 78, 109, 205, 236, 579, 610, 110, 141, 15, 46, 142, 173, - 47, 78, 174, 205, 16, 16, 79, 110, 206, 237, 16, 47, 111, 142, - 48, 79, 143, 174, 80, 111, 175, 206, 17, 48, 17, 17, 207, 238, - 49, 80, 81, 112, 18, 18, 18, 49, 50, 81, 82, 113, 19, 50, - 51, 82, 83, 114, 608, 608, 484, 515, 360, 391, 236, 267, 112, 143, - 19, 19, 640, 640, 609, 640, 516, 547, 485, 516, 392, 423, 361, 392, - 268, 299, 237, 268, 144, 175, 113, 144, 20, 51, 20, 20, 672, 672, - 641, 672, 610, 641, 548, 579, 517, 548, 486, 517, 424, 455, 393, 424, - 362, 393, 300, 331, 269, 300, 238, 269, 176, 207, 145, 176, 114, 145, - 52, 83, 21, 52, 21, 21, 704, 704, 673, 704, 642, 673, 611, 642, - 580, 611, 549, 580, 518, 549, 487, 518, 456, 487, 425, 456, 394, 425, - 363, 394, 332, 363, 301, 332, 270, 301, 239, 270, 208, 239, 177, 208, - 146, 177, 115, 146, 84, 115, 53, 84, 22, 53, 22, 22, 705, 736, - 674, 705, 643, 674, 581, 612, 550, 581, 519, 550, 457, 488, 426, 457, - 395, 426, 333, 364, 302, 333, 271, 302, 209, 240, 178, 209, 147, 178, - 85, 116, 54, 85, 23, 54, 706, 737, 675, 706, 582, 613, 551, 582, - 458, 489, 427, 458, 334, 365, 303, 334, 210, 241, 179, 210, 86, 117, - 55, 86, 707, 738, 583, 614, 459, 490, 335, 366, 211, 242, 87, 118, - 736, 736, 612, 643, 488, 519, 364, 395, 240, 271, 116, 147, 23, 23, - 768, 768, 737, 768, 644, 675, 613, 644, 520, 551, 489, 520, 396, 427, - 365, 396, 272, 303, 241, 272, 148, 179, 117, 148, 24, 55, 24, 24, - 800, 800, 769, 800, 738, 769, 676, 707, 645, 676, 614, 645, 552, 583, - 521, 552, 490, 521, 428, 459, 397, 428, 366, 397, 304, 335, 273, 304, - 242, 273, 180, 211, 149, 180, 118, 149, 56, 87, 25, 56, 25, 25, - 832, 832, 801, 832, 770, 801, 739, 770, 708, 739, 677, 708, 646, 677, - 615, 646, 584, 615, 553, 584, 522, 553, 491, 522, 460, 491, 429, 460, - 398, 429, 367, 398, 336, 367, 305, 336, 274, 305, 243, 274, 212, 243, - 181, 212, 150, 181, 119, 150, 88, 119, 57, 88, 26, 57, 26, 26, - 833, 864, 802, 833, 771, 802, 709, 740, 678, 709, 647, 678, 585, 616, - 554, 585, 523, 554, 461, 492, 430, 461, 399, 430, 337, 368, 306, 337, - 275, 306, 213, 244, 182, 213, 151, 182, 89, 120, 58, 89, 27, 58, - 834, 865, 803, 834, 710, 741, 679, 710, 586, 617, 555, 586, 462, 493, - 431, 462, 338, 369, 307, 338, 214, 245, 183, 214, 90, 121, 59, 90, - 835, 866, 711, 742, 587, 618, 463, 494, 339, 370, 215, 246, 91, 122, - 864, 864, 740, 771, 616, 647, 492, 523, 368, 399, 244, 275, 120, 151, - 27, 27, 896, 896, 865, 896, 772, 803, 741, 772, 648, 679, 617, 648, - 524, 555, 493, 524, 400, 431, 369, 400, 276, 307, 245, 276, 152, 183, - 121, 152, 28, 59, 28, 28, 928, 928, 897, 928, 866, 897, 804, 835, - 773, 804, 742, 773, 680, 711, 649, 680, 618, 649, 556, 587, 525, 556, - 494, 525, 432, 463, 401, 432, 370, 401, 308, 339, 277, 308, 246, 277, - 184, 215, 153, 184, 122, 153, 60, 91, 29, 60, 29, 29, 960, 960, - 929, 960, 898, 929, 867, 898, 836, 867, 805, 836, 774, 805, 743, 774, - 712, 743, 681, 712, 650, 681, 619, 650, 588, 619, 557, 588, 526, 557, - 495, 526, 464, 495, 433, 464, 402, 433, 371, 402, 340, 371, 309, 340, - 278, 309, 247, 278, 216, 247, 185, 216, 154, 185, 123, 154, 92, 123, - 61, 92, 30, 61, 30, 30, 961, 992, 930, 961, 899, 930, 837, 868, - 806, 837, 775, 806, 713, 744, 682, 713, 651, 682, 589, 620, 558, 589, - 527, 558, 465, 496, 434, 465, 403, 434, 341, 372, 310, 341, 279, 310, - 217, 248, 186, 217, 155, 186, 93, 124, 62, 93, 31, 62, 962, 993, - 931, 962, 838, 869, 807, 838, 714, 745, 683, 714, 590, 621, 559, 590, - 466, 497, 435, 466, 342, 373, 311, 342, 218, 249, 187, 218, 94, 125, - 63, 94, 963, 994, 839, 870, 715, 746, 591, 622, 467, 498, 343, 374, - 219, 250, 95, 126, 868, 899, 744, 775, 620, 651, 496, 527, 372, 403, - 248, 279, 124, 155, 900, 931, 869, 900, 776, 807, 745, 776, 652, 683, - 621, 652, 528, 559, 497, 528, 404, 435, 373, 404, 280, 311, 249, 280, - 156, 187, 125, 156, 932, 963, 901, 932, 870, 901, 808, 839, 777, 808, - 746, 777, 684, 715, 653, 684, 622, 653, 560, 591, 529, 560, 498, 529, - 436, 467, 405, 436, 374, 405, 312, 343, 281, 312, 250, 281, 188, 219, - 157, 188, 126, 157, 964, 995, 933, 964, 902, 933, 871, 902, 840, 871, - 809, 840, 778, 809, 747, 778, 716, 747, 685, 716, 654, 685, 623, 654, - 592, 623, 561, 592, 530, 561, 499, 530, 468, 499, 437, 468, 406, 437, - 375, 406, 344, 375, 313, 344, 282, 313, 251, 282, 220, 251, 189, 220, - 158, 189, 127, 158, 965, 996, 934, 965, 903, 934, 841, 872, 810, 841, - 779, 810, 717, 748, 686, 717, 655, 686, 593, 624, 562, 593, 531, 562, - 469, 500, 438, 469, 407, 438, 345, 376, 314, 345, 283, 314, 221, 252, - 190, 221, 159, 190, 966, 997, 935, 966, 842, 873, 811, 842, 718, 749, - 687, 718, 594, 625, 563, 594, 470, 501, 439, 470, 346, 377, 315, 346, - 222, 253, 191, 222, 967, 998, 843, 874, 719, 750, 595, 626, 471, 502, - 347, 378, 223, 254, 872, 903, 748, 779, 624, 655, 500, 531, 376, 407, - 252, 283, 904, 935, 873, 904, 780, 811, 749, 780, 656, 687, 625, 656, - 532, 563, 501, 532, 408, 439, 377, 408, 284, 315, 253, 284, 936, 967, - 905, 936, 874, 905, 812, 843, 781, 812, 750, 781, 688, 719, 657, 688, - 626, 657, 564, 595, 533, 564, 502, 533, 440, 471, 409, 440, 378, 409, - 316, 347, 285, 316, 254, 285, 968, 999, 937, 968, 906, 937, 875, 906, - 844, 875, 813, 844, 782, 813, 751, 782, 720, 751, 689, 720, 658, 689, - 627, 658, 596, 627, 565, 596, 534, 565, 503, 534, 472, 503, 441, 472, - 410, 441, 379, 410, 348, 379, 317, 348, 286, 317, 255, 286, 969, 1000, - 938, 969, 907, 938, 845, 876, 814, 845, 783, 814, 721, 752, 690, 721, - 659, 690, 597, 628, 566, 597, 535, 566, 473, 504, 442, 473, 411, 442, - 349, 380, 318, 349, 287, 318, 970, 1001, 939, 970, 846, 877, 815, 846, - 722, 753, 691, 722, 598, 629, 567, 598, 474, 505, 443, 474, 350, 381, - 319, 350, 971, 1002, 847, 878, 723, 754, 599, 630, 475, 506, 351, 382, - 876, 907, 752, 783, 628, 659, 504, 535, 380, 411, 908, 939, 877, 908, - 784, 815, 753, 784, 660, 691, 629, 660, 536, 567, 505, 536, 412, 443, - 381, 412, 940, 971, 909, 940, 878, 909, 816, 847, 785, 816, 754, 785, - 692, 723, 661, 692, 630, 661, 568, 599, 537, 568, 506, 537, 444, 475, - 413, 444, 382, 413, 972, 1003, 941, 972, 910, 941, 879, 910, 848, 879, - 817, 848, 786, 817, 755, 786, 724, 755, 693, 724, 662, 693, 631, 662, - 600, 631, 569, 600, 538, 569, 507, 538, 476, 507, 445, 476, 414, 445, - 383, 414, 973, 1004, 942, 973, 911, 942, 849, 880, 818, 849, 787, 818, - 725, 756, 694, 725, 663, 694, 601, 632, 570, 601, 539, 570, 477, 508, - 446, 477, 415, 446, 974, 1005, 943, 974, 850, 881, 819, 850, 726, 757, - 695, 726, 602, 633, 571, 602, 478, 509, 447, 478, 975, 1006, 851, 882, - 727, 758, 603, 634, 479, 510, 880, 911, 756, 787, 632, 663, 508, 539, - 912, 943, 881, 912, 788, 819, 757, 788, 664, 695, 633, 664, 540, 571, - 509, 540, 944, 975, 913, 944, 882, 913, 820, 851, 789, 820, 758, 789, - 696, 727, 665, 696, 634, 665, 572, 603, 541, 572, 510, 541, 976, 1007, - 945, 976, 914, 945, 883, 914, 852, 883, 821, 852, 790, 821, 759, 790, - 728, 759, 697, 728, 666, 697, 635, 666, 604, 635, 573, 604, 542, 573, - 511, 542, 977, 1008, 946, 977, 915, 946, 853, 884, 822, 853, 791, 822, - 729, 760, 698, 729, 667, 698, 605, 636, 574, 605, 543, 574, 978, 1009, - 947, 978, 854, 885, 823, 854, 730, 761, 699, 730, 606, 637, 575, 606, - 979, 1010, 855, 886, 731, 762, 607, 638, 884, 915, 760, 791, 636, 667, - 916, 947, 885, 916, 792, 823, 761, 792, 668, 699, 637, 668, 948, 979, - 917, 948, 886, 917, 824, 855, 793, 824, 762, 793, 700, 731, 669, 700, - 638, 669, 980, 1011, 949, 980, 918, 949, 887, 918, 856, 887, 825, 856, - 794, 825, 763, 794, 732, 763, 701, 732, 670, 701, 639, 670, 981, 1012, - 950, 981, 919, 950, 857, 888, 826, 857, 795, 826, 733, 764, 702, 733, - 671, 702, 982, 1013, 951, 982, 858, 889, 827, 858, 734, 765, 703, 734, - 983, 1014, 859, 890, 735, 766, 888, 919, 764, 795, 920, 951, 889, 920, - 796, 827, 765, 796, 952, 983, 921, 952, 890, 921, 828, 859, 797, 828, - 766, 797, 984, 1015, 953, 984, 922, 953, 891, 922, 860, 891, 829, 860, - 798, 829, 767, 798, 985, 1016, 954, 985, 923, 954, 861, 892, 830, 861, - 799, 830, 986, 1017, 955, 986, 862, 893, 831, 862, 987, 1018, 863, 894, - 892, 923, 924, 955, 893, 924, 956, 987, 925, 956, 894, 925, 988, 1019, - 957, 988, 926, 957, 895, 926, 989, 1020, 958, 989, 927, 958, 990, 1021, - 959, 990, 991, 1022, 0, 0, -}; - -// Add 1 to iscan values. This represents the EOB position instead of the index. -DECLARE_ALIGNED(16, static const int16_t, vp9_default_iscan_4x4[16]) = { - 1, 3, 6, 9, 2, 4, 10, 13, 5, 8, 12, 15, 7, 11, 14, 16, -}; - -DECLARE_ALIGNED(16, static const int16_t, vp9_col_iscan_4x4[16]) = { - 1, 4, 8, 12, 2, 6, 10, 13, 3, 7, 11, 15, 5, 9, 14, 16, -}; - -DECLARE_ALIGNED(16, static const int16_t, vp9_row_iscan_4x4[16]) = { - 1, 2, 4, 6, 3, 5, 7, 10, 8, 9, 12, 14, 11, 13, 15, 16, -}; - -DECLARE_ALIGNED(16, static const int16_t, vp9_col_iscan_8x8[64]) = { - 1, 4, 9, 16, 23, 33, 41, 48, 2, 6, 12, 19, 27, 35, 45, 52, - 3, 8, 14, 21, 29, 39, 47, 55, 5, 11, 17, 25, 32, 42, 51, 57, - 7, 13, 22, 28, 36, 44, 53, 59, 10, 18, 26, 34, 40, 49, 56, 61, - 15, 24, 31, 38, 46, 54, 60, 63, 20, 30, 37, 43, 50, 58, 62, 64, -}; - -DECLARE_ALIGNED(16, static const int16_t, vp9_row_iscan_8x8[64]) = { - 1, 2, 3, 6, 9, 13, 20, 25, 4, 5, 8, 11, 16, 21, 31, 40, - 7, 10, 14, 17, 22, 28, 38, 47, 12, 15, 18, 24, 29, 35, 45, 53, - 19, 23, 26, 32, 36, 42, 51, 58, 27, 30, 34, 39, 44, 50, 56, 60, - 33, 37, 43, 48, 52, 55, 61, 62, 41, 46, 49, 54, 57, 59, 63, 64, -}; - -DECLARE_ALIGNED(16, static const int16_t, vp9_default_iscan_8x8[64]) = { - 1, 3, 6, 10, 15, 23, 32, 38, 2, 5, 9, 14, 20, 27, 39, 45, - 4, 7, 11, 18, 25, 31, 43, 50, 8, 12, 16, 22, 30, 37, 48, 54, - 13, 17, 21, 28, 35, 44, 53, 58, 19, 24, 29, 36, 42, 49, 57, 61, - 26, 33, 40, 46, 51, 56, 60, 63, 34, 41, 47, 52, 55, 59, 62, 64, -}; - -DECLARE_ALIGNED(16, static const int16_t, vp9_col_iscan_16x16[256]) = { - 1, 5, 12, 21, 32, 44, 60, 76, 86, 110, 131, 151, 166, 182, 196, 199, - 2, 7, 15, 24, 35, 48, 65, 82, 96, 115, 136, 154, 172, 189, 202, 213, - 3, 9, 17, 26, 39, 53, 68, 84, 102, 117, 137, 158, 173, 191, 206, 217, - 4, 11, 19, 30, 42, 56, 72, 90, 104, 120, 142, 160, 177, 195, 209, 219, - 6, 13, 22, 33, 46, 59, 75, 94, 105, 124, 145, 165, 180, 197, 211, 224, - 8, 16, 27, 38, 50, 64, 79, 97, 113, 130, 147, 167, 183, 201, 216, 229, - 10, 20, 29, 40, 55, 70, 87, 103, 118, 133, 152, 171, 188, 207, 221, 231, - 14, 25, 36, 47, 61, 74, 92, 109, 123, 138, 155, 175, 190, 208, 225, 236, - 18, 31, 41, 54, 67, 83, 99, 116, 127, 143, 162, 181, 198, 214, 228, 238, - 23, 37, 49, 63, 77, 93, 106, 121, 134, 148, 168, 187, 204, 220, 233, 241, - 28, 45, 57, 71, 85, 100, 114, 128, 141, 157, 176, 194, 210, 227, 237, 245, - 34, 52, 69, 80, 95, 111, 126, 139, 150, 163, 185, 203, 218, 230, 242, 248, - 43, 62, 78, 91, 107, 122, 135, 149, 161, 174, 192, 212, 226, 239, 246, 252, - 51, 73, 88, 101, 119, 129, 146, 159, 169, 184, 205, 223, 234, 243, 250, 254, - 58, 81, 98, 112, 132, 144, 156, 170, 179, 193, 215, 232, 240, 247, 251, 255, - 66, 89, 108, 125, 140, 153, 164, 178, 186, 200, 222, 235, 244, 249, 253, 256, -}; - -DECLARE_ALIGNED(16, static const int16_t, vp9_row_iscan_16x16[256]) = { - 1, 2, 3, 5, 7, 10, 13, 18, 23, 30, 37, 44, 55, 65, 77, - 87, 4, 6, 8, 12, 16, 20, 26, 33, 39, 49, 60, 69, 85, 100, - 116, 131, 9, 11, 14, 19, 24, 28, 34, 43, 52, 61, 73, 89, 104, - 120, 143, 168, 15, 17, 21, 27, 32, 38, 45, 54, 62, 74, 86, 101, - 117, 136, 162, 186, 22, 25, 31, 36, 41, 48, 56, 66, 75, 82, 95, - 113, 134, 155, 180, 206, 29, 35, 40, 46, 51, 59, 68, 78, 88, 97, - 107, 122, 147, 170, 197, 213, 42, 47, 50, 57, 64, 71, 80, 91, 99, - 108, 123, 139, 160, 183, 208, 223, 53, 58, 63, 70, 76, 84, 94, 103, - 111, 121, 135, 151, 177, 196, 216, 227, 67, 72, 79, 83, 92, 98, 109, - 114, 128, 137, 149, 169, 189, 203, 222, 233, 81, 90, 93, 102, 106, 115, - 126, 132, 140, 152, 163, 178, 193, 209, 224, 235, 96, 105, 110, 118, 124, - 129, 144, 145, 156, 166, 176, 191, 207, 220, 234, 240, 112, 119, 125, 130, - 141, 148, 158, 165, 171, 182, 192, 204, 225, 231, 241, 244, 127, 133, 138, - 146, 154, 161, 175, 179, 185, 198, 205, 217, 232, 238, 245, 247, 142, 150, - 157, 167, 173, 181, 190, 200, 201, 211, 221, 229, 239, 243, 250, 252, 153, - 164, 172, 184, 187, 194, 202, 212, 215, 219, 228, 237, 246, 248, 253, 254, - 159, 174, 188, 195, 199, 210, 214, 218, 226, 230, 236, 242, 249, 251, 255, - 256, -}; - -DECLARE_ALIGNED(16, static const int16_t, vp9_default_iscan_16x16[256]) = { - 1, 3, 6, 10, 18, 25, 37, 45, 56, 73, 89, 105, 129, 144, 167, - 180, 2, 5, 9, 14, 21, 31, 41, 55, 67, 80, 97, 114, 142, 155, - 179, 197, 4, 8, 12, 19, 26, 34, 47, 58, 72, 87, 102, 120, 149, - 165, 187, 202, 7, 13, 17, 24, 32, 40, 54, 65, 79, 93, 111, 128, - 154, 170, 194, 209, 11, 15, 20, 29, 38, 48, 59, 68, 85, 99, 115, - 134, 162, 177, 199, 215, 16, 22, 27, 35, 44, 53, 66, 78, 92, 107, - 121, 141, 166, 186, 206, 222, 23, 28, 33, 42, 49, 61, 74, 86, 100, - 117, 131, 152, 176, 191, 212, 226, 30, 36, 43, 50, 60, 70, 82, 96, - 109, 126, 140, 156, 183, 198, 218, 230, 39, 46, 52, 62, 69, 81, 94, - 106, 119, 135, 151, 169, 192, 208, 224, 235, 51, 57, 64, 75, 84, 95, - 110, 118, 130, 148, 164, 178, 200, 214, 229, 239, 63, 71, 77, 88, 98, - 108, 123, 132, 146, 160, 173, 189, 211, 223, 236, 243, 76, 83, 91, 103, - 113, 125, 139, 147, 158, 174, 188, 203, 220, 231, 241, 246, 90, 101, 112, - 124, 133, 143, 157, 168, 181, 190, 204, 217, 232, 238, 247, 251, 104, 116, - 127, 137, 150, 163, 172, 184, 195, 205, 216, 225, 237, 242, 249, 253, 122, - 136, 145, 159, 171, 182, 193, 201, 210, 219, 228, 234, 244, 245, 252, 255, - 138, 153, 161, 175, 185, 196, 207, 213, 221, 227, 233, 240, 248, 250, 254, - 256, -}; - -DECLARE_ALIGNED(16, static const int16_t, vp9_default_iscan_32x32[1024]) = { - 1, 3, 6, 11, 18, 26, 39, 48, 63, 84, 102, 122, 146, - 171, 194, 205, 211, 220, 230, 234, 246, 258, 276, 300, 343, 357, - 378, 406, 456, 472, 496, 528, 2, 5, 9, 16, 23, 31, 46, - 59, 75, 93, 113, 134, 159, 185, 204, 216, 223, 229, 235, 238, - 257, 275, 299, 318, 356, 377, 405, 427, 471, 495, 527, 552, 4, - 8, 13, 19, 29, 37, 53, 65, 83, 103, 119, 143, 165, 190, - 209, 218, 225, 232, 236, 239, 274, 298, 317, 330, 376, 404, 426, - 441, 494, 526, 551, 568, 7, 12, 17, 24, 32, 44, 61, 74, - 91, 110, 127, 151, 174, 197, 212, 221, 227, 233, 237, 240, 297, - 316, 329, 336, 403, 425, 440, 448, 525, 550, 567, 576, 10, 15, - 20, 30, 38, 51, 66, 79, 96, 117, 135, 158, 180, 202, 215, - 224, 245, 256, 273, 296, 342, 355, 375, 402, 455, 470, 493, 524, - 583, 597, 618, 646, 14, 21, 27, 36, 45, 55, 73, 86, 106, - 124, 141, 164, 183, 206, 217, 226, 255, 272, 295, 315, 354, 374, - 401, 424, 469, 492, 523, 549, 596, 617, 645, 667, 22, 28, 34, - 43, 54, 64, 81, 95, 114, 133, 152, 173, 191, 210, 219, 228, - 271, 294, 314, 328, 373, 400, 423, 439, 491, 522, 548, 566, 616, - 644, 666, 681, 25, 33, 40, 49, 58, 72, 89, 105, 121, 140, - 160, 179, 198, 213, 222, 231, 293, 313, 327, 335, 399, 422, 438, - 447, 521, 547, 565, 575, 643, 665, 680, 688, 35, 41, 47, 57, - 69, 82, 97, 112, 131, 148, 168, 187, 244, 254, 270, 292, 341, - 353, 372, 398, 454, 468, 490, 520, 582, 595, 615, 642, 694, 706, - 724, 748, 42, 50, 56, 68, 78, 92, 108, 125, 139, 162, 178, - 195, 253, 269, 291, 312, 352, 371, 397, 421, 467, 489, 519, 546, - 594, 614, 641, 664, 705, 723, 747, 766, 52, 60, 67, 77, 90, - 100, 120, 132, 150, 169, 182, 201, 268, 290, 311, 326, 370, 396, - 420, 437, 488, 518, 545, 564, 613, 640, 663, 679, 722, 746, 765, - 778, 62, 70, 76, 88, 101, 115, 130, 145, 163, 181, 192, 208, - 289, 310, 325, 334, 395, 419, 436, 446, 517, 544, 563, 574, 639, - 662, 678, 687, 745, 764, 777, 784, 71, 80, 87, 98, 109, 123, - 138, 156, 243, 252, 267, 288, 340, 351, 369, 394, 453, 466, 487, - 516, 581, 593, 612, 638, 693, 704, 721, 744, 789, 799, 814, 834, - 85, 94, 104, 111, 126, 142, 155, 172, 251, 266, 287, 309, 350, - 368, 393, 418, 465, 486, 515, 543, 592, 611, 637, 661, 703, 720, - 743, 763, 798, 813, 833, 849, 99, 107, 116, 128, 144, 157, 170, - 186, 265, 286, 308, 324, 367, 392, 417, 435, 485, 514, 542, 562, - 610, 636, 660, 677, 719, 742, 762, 776, 812, 832, 848, 859, 118, - 129, 137, 149, 161, 176, 189, 199, 285, 307, 323, 333, 391, 416, - 434, 445, 513, 541, 561, 573, 635, 659, 676, 686, 741, 761, 775, - 783, 831, 847, 858, 864, 136, 147, 153, 166, 242, 250, 264, 284, - 339, 349, 366, 390, 452, 464, 484, 512, 580, 591, 609, 634, 692, - 702, 718, 740, 788, 797, 811, 830, 868, 876, 888, 904, 154, 167, - 175, 184, 249, 263, 283, 306, 348, 365, 389, 415, 463, 483, 511, - 540, 590, 608, 633, 658, 701, 717, 739, 760, 796, 810, 829, 846, - 875, 887, 903, 916, 177, 188, 196, 203, 262, 282, 305, 322, 364, - 388, 414, 433, 482, 510, 539, 560, 607, 632, 657, 675, 716, 738, - 759, 774, 809, 828, 845, 857, 886, 902, 915, 924, 193, 200, 207, - 214, 281, 304, 321, 332, 387, 413, 432, 444, 509, 538, 559, 572, - 631, 656, 674, 685, 737, 758, 773, 782, 827, 844, 856, 863, 901, - 914, 923, 928, 241, 248, 261, 280, 338, 347, 363, 386, 451, 462, - 481, 508, 579, 589, 606, 630, 691, 700, 715, 736, 787, 795, 808, - 826, 867, 874, 885, 900, 931, 937, 946, 958, 247, 260, 279, 303, - 346, 362, 385, 412, 461, 480, 507, 537, 588, 605, 629, 655, 699, - 714, 735, 757, 794, 807, 825, 843, 873, 884, 899, 913, 936, 945, - 957, 967, 259, 278, 302, 320, 361, 384, 411, 431, 479, 506, 536, - 558, 604, 628, 654, 673, 713, 734, 756, 772, 806, 824, 842, 855, - 883, 898, 912, 922, 944, 956, 966, 973, 277, 301, 319, 331, 383, - 410, 430, 443, 505, 535, 557, 571, 627, 653, 672, 684, 733, 755, - 771, 781, 823, 841, 854, 862, 897, 911, 921, 927, 955, 965, 972, - 976, 337, 345, 360, 382, 450, 460, 478, 504, 578, 587, 603, 626, - 690, 698, 712, 732, 786, 793, 805, 822, 866, 872, 882, 896, 930, - 935, 943, 954, 978, 982, 988, 996, 344, 359, 381, 409, 459, 477, - 503, 534, 586, 602, 625, 652, 697, 711, 731, 754, 792, 804, 821, - 840, 871, 881, 895, 910, 934, 942, 953, 964, 981, 987, 995, 1002, - 358, 380, 408, 429, 476, 502, 533, 556, 601, 624, 651, 671, 710, - 730, 753, 770, 803, 820, 839, 853, 880, 894, 909, 920, 941, 952, - 963, 971, 986, 994, 1001, 1006, 379, 407, 428, 442, 501, 532, 555, - 570, 623, 650, 670, 683, 729, 752, 769, 780, 819, 838, 852, 861, - 893, 908, 919, 926, 951, 962, 970, 975, 993, 1000, 1005, 1008, 449, - 458, 475, 500, 577, 585, 600, 622, 689, 696, 709, 728, 785, 791, - 802, 818, 865, 870, 879, 892, 929, 933, 940, 950, 977, 980, 985, - 992, 1009, 1011, 1014, 1018, 457, 474, 499, 531, 584, 599, 621, 649, - 695, 708, 727, 751, 790, 801, 817, 837, 869, 878, 891, 907, 932, - 939, 949, 961, 979, 984, 991, 999, 1010, 1013, 1017, 1021, 473, 498, - 530, 554, 598, 620, 648, 669, 707, 726, 750, 768, 800, 816, 836, - 851, 877, 890, 906, 918, 938, 948, 960, 969, 983, 990, 998, 1004, - 1012, 1016, 1020, 1023, 497, 529, 553, 569, 619, 647, 668, 682, 725, - 749, 767, 779, 815, 835, 850, 860, 889, 905, 917, 925, 947, 959, - 968, 974, 989, 997, 1003, 1007, 1015, 1019, 1022, 1024, -}; - -const ScanOrder vp9_default_scan_orders[TX_SIZES] = { - { default_scan_4x4, vp9_default_iscan_4x4, default_scan_4x4_neighbors }, - { default_scan_8x8, vp9_default_iscan_8x8, default_scan_8x8_neighbors }, - { default_scan_16x16, vp9_default_iscan_16x16, default_scan_16x16_neighbors }, - { default_scan_32x32, vp9_default_iscan_32x32, default_scan_32x32_neighbors }, -}; - -const ScanOrder vp9_scan_orders[TX_SIZES][TX_TYPES] = { - { // TX_4X4 - { default_scan_4x4, vp9_default_iscan_4x4, default_scan_4x4_neighbors }, - { row_scan_4x4, vp9_row_iscan_4x4, row_scan_4x4_neighbors }, - { col_scan_4x4, vp9_col_iscan_4x4, col_scan_4x4_neighbors }, - { default_scan_4x4, vp9_default_iscan_4x4, default_scan_4x4_neighbors } }, - { // TX_8X8 - { default_scan_8x8, vp9_default_iscan_8x8, default_scan_8x8_neighbors }, - { row_scan_8x8, vp9_row_iscan_8x8, row_scan_8x8_neighbors }, - { col_scan_8x8, vp9_col_iscan_8x8, col_scan_8x8_neighbors }, - { default_scan_8x8, vp9_default_iscan_8x8, default_scan_8x8_neighbors } }, - { // TX_16X16 - { default_scan_16x16, vp9_default_iscan_16x16, - default_scan_16x16_neighbors }, - { row_scan_16x16, vp9_row_iscan_16x16, row_scan_16x16_neighbors }, - { col_scan_16x16, vp9_col_iscan_16x16, col_scan_16x16_neighbors }, - { default_scan_16x16, vp9_default_iscan_16x16, - default_scan_16x16_neighbors } }, - { // TX_32X32 - { default_scan_32x32, vp9_default_iscan_32x32, - default_scan_32x32_neighbors }, - { default_scan_32x32, vp9_default_iscan_32x32, - default_scan_32x32_neighbors }, - { default_scan_32x32, vp9_default_iscan_32x32, - default_scan_32x32_neighbors }, - { default_scan_32x32, vp9_default_iscan_32x32, - default_scan_32x32_neighbors } } -}; diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_scan.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_scan.h deleted file mode 100644 index 3d1dcc66..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_scan.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_SCAN_H_ -#define VPX_VP9_COMMON_VP9_SCAN_H_ - -#include "vpx/vpx_integer.h" -#include "vpx_ports/mem.h" - -#include "vp9/common/vp9_enums.h" -#include "vp9/common/vp9_blockd.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_NEIGHBORS 2 - -typedef struct ScanOrder { - const int16_t *scan; - const int16_t *iscan; - const int16_t *neighbors; -} ScanOrder; - -extern const ScanOrder vp9_default_scan_orders[TX_SIZES]; -extern const ScanOrder vp9_scan_orders[TX_SIZES][TX_TYPES]; - -static INLINE int get_coef_context(const int16_t *neighbors, - const uint8_t *token_cache, int c) { - return (1 + token_cache[neighbors[MAX_NEIGHBORS * c + 0]] + - token_cache[neighbors[MAX_NEIGHBORS * c + 1]]) >> - 1; -} - -static INLINE const ScanOrder *get_scan(const MACROBLOCKD *xd, TX_SIZE tx_size, - PLANE_TYPE type, int block_idx) { - const MODE_INFO *const mi = xd->mi[0]; - - if (is_inter_block(mi) || type != PLANE_TYPE_Y || xd->lossless) { - return &vp9_default_scan_orders[tx_size]; - } else { - const PREDICTION_MODE mode = get_y_mode(mi, block_idx); - return &vp9_scan_orders[tx_size][intra_mode_to_tx_type_lookup[mode]]; - } -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_SCAN_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_seg_common.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_seg_common.c deleted file mode 100644 index 1c7a1d2e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_seg_common.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_loopfilter.h" -#include "vp9/common/vp9_seg_common.h" -#include "vp9/common/vp9_quant_common.h" - -static const int seg_feature_data_signed[SEG_LVL_MAX] = { 1, 1, 0, 0 }; - -static const int seg_feature_data_max[SEG_LVL_MAX] = { MAXQ, MAX_LOOP_FILTER, 3, - 0 }; - -// These functions provide access to new segment level features. -// Eventually these function may be "optimized out" but for the moment, -// the coding mechanism is still subject to change so these provide a -// convenient single point of change. - -void vp9_clearall_segfeatures(struct segmentation *seg) { - vp9_zero(seg->feature_data); - vp9_zero(seg->feature_mask); - seg->aq_av_offset = 0; -} - -void vp9_enable_segfeature(struct segmentation *seg, int segment_id, - SEG_LVL_FEATURES feature_id) { - seg->feature_mask[segment_id] |= 1 << feature_id; -} - -int vp9_seg_feature_data_max(SEG_LVL_FEATURES feature_id) { - return seg_feature_data_max[feature_id]; -} - -int vp9_is_segfeature_signed(SEG_LVL_FEATURES feature_id) { - return seg_feature_data_signed[feature_id]; -} - -void vp9_set_segdata(struct segmentation *seg, int segment_id, - SEG_LVL_FEATURES feature_id, int seg_data) { - assert(seg_data <= seg_feature_data_max[feature_id]); - if (seg_data < 0) { - assert(seg_feature_data_signed[feature_id]); - assert(-seg_data <= seg_feature_data_max[feature_id]); - } - - seg->feature_data[segment_id][feature_id] = seg_data; -} - -const vpx_tree_index vp9_segment_tree[TREE_SIZE(MAX_SEGMENTS)] = { - 2, 4, 6, 8, 10, 12, 0, -1, -2, -3, -4, -5, -6, -7 -}; - -// TBD? Functions to read and write segment data with range / validity checking diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_seg_common.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_seg_common.h deleted file mode 100644 index 5e71c2fc..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_seg_common.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_SEG_COMMON_H_ -#define VPX_VP9_COMMON_VP9_SEG_COMMON_H_ - -#include "vpx_dsp/prob.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define SEGMENT_DELTADATA 0 -#define SEGMENT_ABSDATA 1 - -#define MAX_SEGMENTS 8 -#define SEG_TREE_PROBS (MAX_SEGMENTS - 1) - -#define PREDICTION_PROBS 3 - -// Segment ID used to skip background encoding -#define BACKGROUND_SEG_SKIP_ID 3 -// Number of frames that don't skip after a key frame -#define FRAMES_NO_SKIPPING_AFTER_KEY 20 - -// Segment level features. -typedef enum { - SEG_LVL_ALT_Q = 0, // Use alternate Quantizer .... - SEG_LVL_ALT_LF = 1, // Use alternate loop filter value... - SEG_LVL_REF_FRAME = 2, // Optional Segment reference frame - SEG_LVL_SKIP = 3, // Optional Segment (0,0) + skip mode - SEG_LVL_MAX = 4 // Number of features supported -} SEG_LVL_FEATURES; - -struct segmentation { - uint8_t enabled; - uint8_t update_map; - uint8_t update_data; - uint8_t abs_delta; - uint8_t temporal_update; - - vpx_prob tree_probs[SEG_TREE_PROBS]; - vpx_prob pred_probs[PREDICTION_PROBS]; - - int16_t feature_data[MAX_SEGMENTS][SEG_LVL_MAX]; - uint32_t feature_mask[MAX_SEGMENTS]; - int aq_av_offset; -}; - -static INLINE int segfeature_active(const struct segmentation *seg, - int segment_id, - SEG_LVL_FEATURES feature_id) { - return seg->enabled && (seg->feature_mask[segment_id] & (1 << feature_id)); -} - -void vp9_clearall_segfeatures(struct segmentation *seg); - -void vp9_enable_segfeature(struct segmentation *seg, int segment_id, - SEG_LVL_FEATURES feature_id); - -int vp9_seg_feature_data_max(SEG_LVL_FEATURES feature_id); - -int vp9_is_segfeature_signed(SEG_LVL_FEATURES feature_id); - -void vp9_set_segdata(struct segmentation *seg, int segment_id, - SEG_LVL_FEATURES feature_id, int seg_data); - -static INLINE int get_segdata(const struct segmentation *seg, int segment_id, - SEG_LVL_FEATURES feature_id) { - return seg->feature_data[segment_id][feature_id]; -} - -extern const vpx_tree_index vp9_segment_tree[TREE_SIZE(MAX_SEGMENTS)]; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_SEG_COMMON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_thread_common.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_thread_common.c deleted file mode 100644 index 24adbcbf..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_thread_common.c +++ /dev/null @@ -1,597 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include "./vpx_config.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_util/vpx_pthread.h" -#include "vp9/common/vp9_entropymode.h" -#include "vp9/common/vp9_thread_common.h" -#include "vp9/common/vp9_reconinter.h" -#include "vp9/common/vp9_loopfilter.h" - -#if CONFIG_MULTITHREAD -static INLINE void mutex_lock(pthread_mutex_t *const mutex) { - const int kMaxTryLocks = 4000; - int locked = 0; - int i; - - for (i = 0; i < kMaxTryLocks; ++i) { - if (!pthread_mutex_trylock(mutex)) { - locked = 1; - break; - } - } - - if (!locked) pthread_mutex_lock(mutex); -} -#endif // CONFIG_MULTITHREAD - -static INLINE void sync_read(VP9LfSync *const lf_sync, int r, int c) { -#if CONFIG_MULTITHREAD - const int nsync = lf_sync->sync_range; - - if (r && !(c & (nsync - 1))) { - pthread_mutex_t *const mutex = &lf_sync->mutex[r - 1]; - mutex_lock(mutex); - - while (c > lf_sync->cur_sb_col[r - 1] - nsync) { - pthread_cond_wait(&lf_sync->cond[r - 1], mutex); - } - pthread_mutex_unlock(mutex); - } -#else - (void)lf_sync; - (void)r; - (void)c; -#endif // CONFIG_MULTITHREAD -} - -static INLINE void sync_write(VP9LfSync *const lf_sync, int r, int c, - const int sb_cols) { -#if CONFIG_MULTITHREAD - const int nsync = lf_sync->sync_range; - int cur; - // Only signal when there are enough filtered SB for next row to run. - int sig = 1; - - if (c < sb_cols - 1) { - cur = c; - if (c % nsync) sig = 0; - } else { - cur = sb_cols + nsync; - } - - if (sig) { - mutex_lock(&lf_sync->mutex[r]); - - lf_sync->cur_sb_col[r] = cur; - - pthread_cond_signal(&lf_sync->cond[r]); - pthread_mutex_unlock(&lf_sync->mutex[r]); - } -#else - (void)lf_sync; - (void)r; - (void)c; - (void)sb_cols; -#endif // CONFIG_MULTITHREAD -} - -// Implement row loopfiltering for each thread. -static INLINE void thread_loop_filter_rows( - const YV12_BUFFER_CONFIG *const frame_buffer, VP9_COMMON *const cm, - struct macroblockd_plane planes[MAX_MB_PLANE], int start, int stop, - int y_only, VP9LfSync *const lf_sync) { - const int num_planes = y_only ? 1 : MAX_MB_PLANE; - const int sb_cols = mi_cols_aligned_to_sb(cm->mi_cols) >> MI_BLOCK_SIZE_LOG2; - const int num_active_workers = lf_sync->num_active_workers; - int mi_row, mi_col; - enum lf_path path; - if (y_only) - path = LF_PATH_444; - else if (planes[1].subsampling_y == 1 && planes[1].subsampling_x == 1) - path = LF_PATH_420; - else if (planes[1].subsampling_y == 0 && planes[1].subsampling_x == 0) - path = LF_PATH_444; - else - path = LF_PATH_SLOW; - - assert(num_active_workers > 0); - - for (mi_row = start; mi_row < stop; - mi_row += num_active_workers * MI_BLOCK_SIZE) { - MODE_INFO **const mi = cm->mi_grid_visible + mi_row * cm->mi_stride; - LOOP_FILTER_MASK *lfm = get_lfm(&cm->lf, mi_row, 0); - - for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MI_BLOCK_SIZE, ++lfm) { - const int r = mi_row >> MI_BLOCK_SIZE_LOG2; - const int c = mi_col >> MI_BLOCK_SIZE_LOG2; - int plane; - - sync_read(lf_sync, r, c); - - vp9_setup_dst_planes(planes, frame_buffer, mi_row, mi_col); - - vp9_adjust_mask(cm, mi_row, mi_col, lfm); - - vp9_filter_block_plane_ss00(cm, &planes[0], mi_row, lfm); - for (plane = 1; plane < num_planes; ++plane) { - switch (path) { - case LF_PATH_420: - vp9_filter_block_plane_ss11(cm, &planes[plane], mi_row, lfm); - break; - case LF_PATH_444: - vp9_filter_block_plane_ss00(cm, &planes[plane], mi_row, lfm); - break; - case LF_PATH_SLOW: - vp9_filter_block_plane_non420(cm, &planes[plane], mi + mi_col, - mi_row, mi_col); - break; - } - } - - sync_write(lf_sync, r, c, sb_cols); - } - } -} - -// Row-based multi-threaded loopfilter hook -static int loop_filter_row_worker(void *arg1, void *arg2) { - VP9LfSync *const lf_sync = (VP9LfSync *)arg1; - LFWorkerData *const lf_data = (LFWorkerData *)arg2; - thread_loop_filter_rows(lf_data->frame_buffer, lf_data->cm, lf_data->planes, - lf_data->start, lf_data->stop, lf_data->y_only, - lf_sync); - return 1; -} - -static void loop_filter_rows_mt(YV12_BUFFER_CONFIG *frame, VP9_COMMON *cm, - struct macroblockd_plane planes[MAX_MB_PLANE], - int start, int stop, int y_only, - VPxWorker *workers, int nworkers, - VP9LfSync *lf_sync) { - const VPxWorkerInterface *const winterface = vpx_get_worker_interface(); - // Number of superblock rows and cols - const int sb_rows = mi_cols_aligned_to_sb(cm->mi_rows) >> MI_BLOCK_SIZE_LOG2; - const int num_tile_cols = 1 << cm->log2_tile_cols; - // Limit the number of workers to prevent changes in frame dimensions from - // causing incorrect sync calculations when sb_rows < threads/tile_cols. - // Further restrict them by the number of tile columns should the user - // request more as this implementation doesn't scale well beyond that. - const int num_workers = VPXMIN(nworkers, VPXMIN(num_tile_cols, sb_rows)); - int i; - - if (!lf_sync->sync_range || sb_rows != lf_sync->rows || - num_workers > lf_sync->num_workers) { - vp9_loop_filter_dealloc(lf_sync); - vp9_loop_filter_alloc(lf_sync, cm, sb_rows, cm->width, num_workers); - } - lf_sync->num_active_workers = num_workers; - - // Initialize cur_sb_col to -1 for all SB rows. - memset(lf_sync->cur_sb_col, -1, sizeof(*lf_sync->cur_sb_col) * sb_rows); - - // Set up loopfilter thread data. - // The decoder is capping num_workers because it has been observed that using - // more threads on the loopfilter than there are cores will hurt performance - // on Android. This is because the system will only schedule the tile decode - // workers on cores equal to the number of tile columns. Then if the decoder - // tries to use more threads for the loopfilter, it will hurt performance - // because of contention. If the multithreading code changes in the future - // then the number of workers used by the loopfilter should be revisited. - for (i = 0; i < num_workers; ++i) { - VPxWorker *const worker = &workers[i]; - LFWorkerData *const lf_data = &lf_sync->lfdata[i]; - - worker->hook = loop_filter_row_worker; - worker->data1 = lf_sync; - worker->data2 = lf_data; - - // Loopfilter data - vp9_loop_filter_data_reset(lf_data, frame, cm, planes); - lf_data->start = start + i * MI_BLOCK_SIZE; - lf_data->stop = stop; - lf_data->y_only = y_only; - - // Start loopfiltering - if (i == num_workers - 1) { - winterface->execute(worker); - } else { - winterface->launch(worker); - } - } - - // Wait till all rows are finished - for (i = 0; i < num_workers; ++i) { - winterface->sync(&workers[i]); - } -} - -void vp9_loop_filter_frame_mt(YV12_BUFFER_CONFIG *frame, VP9_COMMON *cm, - struct macroblockd_plane planes[MAX_MB_PLANE], - int frame_filter_level, int y_only, - int partial_frame, VPxWorker *workers, - int num_workers, VP9LfSync *lf_sync) { - int start_mi_row, end_mi_row, mi_rows_to_filter; - - if (!frame_filter_level) return; - - start_mi_row = 0; - mi_rows_to_filter = cm->mi_rows; - if (partial_frame && cm->mi_rows > 8) { - start_mi_row = cm->mi_rows >> 1; - start_mi_row &= 0xfffffff8; - mi_rows_to_filter = VPXMAX(cm->mi_rows / 8, 8); - } - end_mi_row = start_mi_row + mi_rows_to_filter; - vp9_loop_filter_frame_init(cm, frame_filter_level); - - loop_filter_rows_mt(frame, cm, planes, start_mi_row, end_mi_row, y_only, - workers, num_workers, lf_sync); -} - -void vp9_lpf_mt_init(VP9LfSync *lf_sync, VP9_COMMON *cm, int frame_filter_level, - int num_workers) { - const int sb_rows = mi_cols_aligned_to_sb(cm->mi_rows) >> MI_BLOCK_SIZE_LOG2; - - if (!frame_filter_level) return; - - if (!lf_sync->sync_range || sb_rows != lf_sync->rows || - num_workers > lf_sync->num_workers) { - vp9_loop_filter_dealloc(lf_sync); - vp9_loop_filter_alloc(lf_sync, cm, sb_rows, cm->width, num_workers); - } - - // Initialize cur_sb_col to -1 for all SB rows. - memset(lf_sync->cur_sb_col, -1, sizeof(*lf_sync->cur_sb_col) * sb_rows); - - lf_sync->corrupted = 0; - - memset(lf_sync->num_tiles_done, 0, - sizeof(*lf_sync->num_tiles_done) * sb_rows); - cm->lf_row = 0; -} - -// Set up nsync by width. -static INLINE int get_sync_range(int width) { - // nsync numbers are picked by testing. For example, for 4k - // video, using 4 gives best performance. - if (width < 640) - return 1; - else if (width <= 1280) - return 2; - else if (width <= 4096) - return 4; - else - return 8; -} - -// Allocate memory for lf row synchronization -void vp9_loop_filter_alloc(VP9LfSync *lf_sync, VP9_COMMON *cm, int rows, - int width, int num_workers) { - lf_sync->rows = rows; -#if CONFIG_MULTITHREAD - { - int i; - - CHECK_MEM_ERROR(&cm->error, lf_sync->mutex, - vpx_malloc(sizeof(*lf_sync->mutex) * rows)); - if (lf_sync->mutex) { - for (i = 0; i < rows; ++i) { - pthread_mutex_init(&lf_sync->mutex[i], NULL); - } - } - - CHECK_MEM_ERROR(&cm->error, lf_sync->cond, - vpx_malloc(sizeof(*lf_sync->cond) * rows)); - if (lf_sync->cond) { - for (i = 0; i < rows; ++i) { - pthread_cond_init(&lf_sync->cond[i], NULL); - } - } - - CHECK_MEM_ERROR(&cm->error, lf_sync->lf_mutex, - vpx_malloc(sizeof(*lf_sync->lf_mutex))); - pthread_mutex_init(lf_sync->lf_mutex, NULL); - - CHECK_MEM_ERROR(&cm->error, lf_sync->recon_done_mutex, - vpx_malloc(sizeof(*lf_sync->recon_done_mutex) * rows)); - if (lf_sync->recon_done_mutex) { - for (i = 0; i < rows; ++i) { - pthread_mutex_init(&lf_sync->recon_done_mutex[i], NULL); - } - } - - CHECK_MEM_ERROR(&cm->error, lf_sync->recon_done_cond, - vpx_malloc(sizeof(*lf_sync->recon_done_cond) * rows)); - if (lf_sync->recon_done_cond) { - for (i = 0; i < rows; ++i) { - pthread_cond_init(&lf_sync->recon_done_cond[i], NULL); - } - } - } -#endif // CONFIG_MULTITHREAD - - CHECK_MEM_ERROR(&cm->error, lf_sync->lfdata, - vpx_malloc(num_workers * sizeof(*lf_sync->lfdata))); - lf_sync->num_workers = num_workers; - lf_sync->num_active_workers = lf_sync->num_workers; - - CHECK_MEM_ERROR(&cm->error, lf_sync->cur_sb_col, - vpx_malloc(sizeof(*lf_sync->cur_sb_col) * rows)); - - CHECK_MEM_ERROR(&cm->error, lf_sync->num_tiles_done, - vpx_malloc(sizeof(*lf_sync->num_tiles_done) * - mi_cols_aligned_to_sb(cm->mi_rows) >> - MI_BLOCK_SIZE_LOG2)); - - // Set up nsync. - lf_sync->sync_range = get_sync_range(width); -} - -// Deallocate lf synchronization related mutex and data -void vp9_loop_filter_dealloc(VP9LfSync *lf_sync) { - assert(lf_sync != NULL); - -#if CONFIG_MULTITHREAD - if (lf_sync->mutex != NULL) { - int i; - for (i = 0; i < lf_sync->rows; ++i) { - pthread_mutex_destroy(&lf_sync->mutex[i]); - } - vpx_free(lf_sync->mutex); - } - if (lf_sync->cond != NULL) { - int i; - for (i = 0; i < lf_sync->rows; ++i) { - pthread_cond_destroy(&lf_sync->cond[i]); - } - vpx_free(lf_sync->cond); - } - if (lf_sync->recon_done_mutex != NULL) { - int i; - for (i = 0; i < lf_sync->rows; ++i) { - pthread_mutex_destroy(&lf_sync->recon_done_mutex[i]); - } - vpx_free(lf_sync->recon_done_mutex); - } - - if (lf_sync->lf_mutex != NULL) { - pthread_mutex_destroy(lf_sync->lf_mutex); - vpx_free(lf_sync->lf_mutex); - } - if (lf_sync->recon_done_cond != NULL) { - int i; - for (i = 0; i < lf_sync->rows; ++i) { - pthread_cond_destroy(&lf_sync->recon_done_cond[i]); - } - vpx_free(lf_sync->recon_done_cond); - } -#endif // CONFIG_MULTITHREAD - - vpx_free(lf_sync->lfdata); - vpx_free(lf_sync->cur_sb_col); - vpx_free(lf_sync->num_tiles_done); - // clear the structure as the source of this call may be a resize in which - // case this call will be followed by an _alloc() which may fail. - vp9_zero(*lf_sync); -} - -static int get_next_row(VP9_COMMON *cm, VP9LfSync *lf_sync) { - int return_val = -1; - const int max_rows = cm->mi_rows; - -#if CONFIG_MULTITHREAD - int cur_row; - const int tile_cols = 1 << cm->log2_tile_cols; - - pthread_mutex_lock(lf_sync->lf_mutex); - if (cm->lf_row < max_rows) { - cur_row = cm->lf_row >> MI_BLOCK_SIZE_LOG2; - return_val = cm->lf_row; - cm->lf_row += MI_BLOCK_SIZE; - if (cm->lf_row < max_rows) { - /* If this is not the last row, make sure the next row is also decoded. - * This is because the intra predict has to happen before loop filter */ - cur_row += 1; - } - } - pthread_mutex_unlock(lf_sync->lf_mutex); - - if (return_val == -1) return return_val; - - pthread_mutex_lock(&lf_sync->recon_done_mutex[cur_row]); - if (lf_sync->num_tiles_done[cur_row] < tile_cols) { - pthread_cond_wait(&lf_sync->recon_done_cond[cur_row], - &lf_sync->recon_done_mutex[cur_row]); - } - pthread_mutex_unlock(&lf_sync->recon_done_mutex[cur_row]); - pthread_mutex_lock(lf_sync->lf_mutex); - if (lf_sync->corrupted) { - int row = return_val >> MI_BLOCK_SIZE_LOG2; - pthread_mutex_lock(&lf_sync->mutex[row]); - lf_sync->cur_sb_col[row] = INT_MAX; - pthread_cond_signal(&lf_sync->cond[row]); - pthread_mutex_unlock(&lf_sync->mutex[row]); - return_val = -1; - } - pthread_mutex_unlock(lf_sync->lf_mutex); -#else - (void)lf_sync; - if (cm->lf_row < max_rows) { - return_val = cm->lf_row; - cm->lf_row += MI_BLOCK_SIZE; - } -#endif // CONFIG_MULTITHREAD - - return return_val; -} - -void vp9_loopfilter_rows(LFWorkerData *lf_data, VP9LfSync *lf_sync) { - int mi_row; - VP9_COMMON *cm = lf_data->cm; - - while ((mi_row = get_next_row(cm, lf_sync)) != -1 && mi_row < cm->mi_rows) { - lf_data->start = mi_row; - lf_data->stop = mi_row + MI_BLOCK_SIZE; - - thread_loop_filter_rows(lf_data->frame_buffer, lf_data->cm, lf_data->planes, - lf_data->start, lf_data->stop, lf_data->y_only, - lf_sync); - } -} - -void vp9_set_row(VP9LfSync *lf_sync, int num_tiles, int row, int is_last_row, - int corrupted) { -#if CONFIG_MULTITHREAD - pthread_mutex_lock(lf_sync->lf_mutex); - lf_sync->corrupted |= corrupted; - pthread_mutex_unlock(lf_sync->lf_mutex); - pthread_mutex_lock(&lf_sync->recon_done_mutex[row]); - lf_sync->num_tiles_done[row] += 1; - if (num_tiles == lf_sync->num_tiles_done[row]) { - if (is_last_row) { - /* The last 2 rows wait on the last row to be done. - * So, we have to broadcast the signal in this case. - */ - pthread_cond_broadcast(&lf_sync->recon_done_cond[row]); - } else { - pthread_cond_signal(&lf_sync->recon_done_cond[row]); - } - } - pthread_mutex_unlock(&lf_sync->recon_done_mutex[row]); -#else - (void)lf_sync; - (void)num_tiles; - (void)row; - (void)is_last_row; - (void)corrupted; -#endif // CONFIG_MULTITHREAD -} - -void vp9_loopfilter_job(LFWorkerData *lf_data, VP9LfSync *lf_sync) { - thread_loop_filter_rows(lf_data->frame_buffer, lf_data->cm, lf_data->planes, - lf_data->start, lf_data->stop, lf_data->y_only, - lf_sync); -} - -// Accumulate frame counts. -void vp9_accumulate_frame_counts(FRAME_COUNTS *accum, - const FRAME_COUNTS *counts, int is_dec) { - int i, j, k, l, m; - - for (i = 0; i < BLOCK_SIZE_GROUPS; i++) - for (j = 0; j < INTRA_MODES; j++) - accum->y_mode[i][j] += counts->y_mode[i][j]; - - for (i = 0; i < INTRA_MODES; i++) - for (j = 0; j < INTRA_MODES; j++) - accum->uv_mode[i][j] += counts->uv_mode[i][j]; - - for (i = 0; i < PARTITION_CONTEXTS; i++) - for (j = 0; j < PARTITION_TYPES; j++) - accum->partition[i][j] += counts->partition[i][j]; - - if (is_dec) { - int n; - for (i = 0; i < TX_SIZES; i++) - for (j = 0; j < PLANE_TYPES; j++) - for (k = 0; k < REF_TYPES; k++) - for (l = 0; l < COEF_BANDS; l++) - for (m = 0; m < COEFF_CONTEXTS; m++) { - accum->eob_branch[i][j][k][l][m] += - counts->eob_branch[i][j][k][l][m]; - for (n = 0; n < UNCONSTRAINED_NODES + 1; n++) - accum->coef[i][j][k][l][m][n] += counts->coef[i][j][k][l][m][n]; - } - } else { - for (i = 0; i < TX_SIZES; i++) - for (j = 0; j < PLANE_TYPES; j++) - for (k = 0; k < REF_TYPES; k++) - for (l = 0; l < COEF_BANDS; l++) - for (m = 0; m < COEFF_CONTEXTS; m++) - accum->eob_branch[i][j][k][l][m] += - counts->eob_branch[i][j][k][l][m]; - // In the encoder, coef is only updated at frame - // level, so not need to accumulate it here. - // for (n = 0; n < UNCONSTRAINED_NODES + 1; n++) - // accum->coef[i][j][k][l][m][n] += - // counts->coef[i][j][k][l][m][n]; - } - - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) - for (j = 0; j < SWITCHABLE_FILTERS; j++) - accum->switchable_interp[i][j] += counts->switchable_interp[i][j]; - - for (i = 0; i < INTER_MODE_CONTEXTS; i++) - for (j = 0; j < INTER_MODES; j++) - accum->inter_mode[i][j] += counts->inter_mode[i][j]; - - for (i = 0; i < INTRA_INTER_CONTEXTS; i++) - for (j = 0; j < 2; j++) - accum->intra_inter[i][j] += counts->intra_inter[i][j]; - - for (i = 0; i < COMP_INTER_CONTEXTS; i++) - for (j = 0; j < 2; j++) accum->comp_inter[i][j] += counts->comp_inter[i][j]; - - for (i = 0; i < REF_CONTEXTS; i++) - for (j = 0; j < 2; j++) - for (k = 0; k < 2; k++) - accum->single_ref[i][j][k] += counts->single_ref[i][j][k]; - - for (i = 0; i < REF_CONTEXTS; i++) - for (j = 0; j < 2; j++) accum->comp_ref[i][j] += counts->comp_ref[i][j]; - - for (i = 0; i < TX_SIZE_CONTEXTS; i++) { - for (j = 0; j < TX_SIZES; j++) - accum->tx.p32x32[i][j] += counts->tx.p32x32[i][j]; - - for (j = 0; j < TX_SIZES - 1; j++) - accum->tx.p16x16[i][j] += counts->tx.p16x16[i][j]; - - for (j = 0; j < TX_SIZES - 2; j++) - accum->tx.p8x8[i][j] += counts->tx.p8x8[i][j]; - } - - for (i = 0; i < TX_SIZES; i++) - accum->tx.tx_totals[i] += counts->tx.tx_totals[i]; - - for (i = 0; i < SKIP_CONTEXTS; i++) - for (j = 0; j < 2; j++) accum->skip[i][j] += counts->skip[i][j]; - - for (i = 0; i < MV_JOINTS; i++) accum->mv.joints[i] += counts->mv.joints[i]; - - for (k = 0; k < 2; k++) { - nmv_component_counts *const comps = &accum->mv.comps[k]; - const nmv_component_counts *const comps_t = &counts->mv.comps[k]; - - for (i = 0; i < 2; i++) { - comps->sign[i] += comps_t->sign[i]; - comps->class0_hp[i] += comps_t->class0_hp[i]; - comps->hp[i] += comps_t->hp[i]; - } - - for (i = 0; i < MV_CLASSES; i++) comps->classes[i] += comps_t->classes[i]; - - for (i = 0; i < CLASS0_SIZE; i++) { - comps->class0[i] += comps_t->class0[i]; - for (j = 0; j < MV_FP_SIZE; j++) - comps->class0_fp[i][j] += comps_t->class0_fp[i][j]; - } - - for (i = 0; i < MV_OFFSET_BITS; i++) - for (j = 0; j < 2; j++) comps->bits[i][j] += comps_t->bits[i][j]; - - for (i = 0; i < MV_FP_SIZE; i++) comps->fp[i] += comps_t->fp[i]; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_thread_common.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_thread_common.h deleted file mode 100644 index 96c705d0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_thread_common.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_THREAD_COMMON_H_ -#define VPX_VP9_COMMON_VP9_THREAD_COMMON_H_ -#include "./vpx_config.h" -#include "vp9/common/vp9_loopfilter.h" -#include "vpx_util/vpx_pthread.h" -#include "vpx_util/vpx_thread.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct VP9Common; -struct FRAME_COUNTS; - -// Loopfilter row synchronization -typedef struct VP9LfSyncData { -#if CONFIG_MULTITHREAD - pthread_mutex_t *mutex; - pthread_cond_t *cond; -#endif - // Allocate memory to store the loop-filtered superblock index in each row. - int *cur_sb_col; - // The optimal sync_range for different resolution and platform should be - // determined by testing. Currently, it is chosen to be a power-of-2 number. - int sync_range; - int rows; - - // Row-based parallel loopfilter data - LFWorkerData *lfdata; - int num_workers; // number of allocated workers. - int num_active_workers; // number of scheduled workers. - -#if CONFIG_MULTITHREAD - pthread_mutex_t *lf_mutex; - pthread_mutex_t *recon_done_mutex; - pthread_cond_t *recon_done_cond; -#endif - int *num_tiles_done; - int corrupted; -} VP9LfSync; - -// Allocate memory for loopfilter row synchronization. -void vp9_loop_filter_alloc(VP9LfSync *lf_sync, struct VP9Common *cm, int rows, - int width, int num_workers); - -// Deallocate loopfilter synchronization related mutex and data. -void vp9_loop_filter_dealloc(VP9LfSync *lf_sync); - -// Multi-threaded loopfilter that uses the tile threads. -void vp9_loop_filter_frame_mt(YV12_BUFFER_CONFIG *frame, struct VP9Common *cm, - struct macroblockd_plane planes[MAX_MB_PLANE], - int frame_filter_level, int y_only, - int partial_frame, VPxWorker *workers, - int num_workers, VP9LfSync *lf_sync); - -// Multi-threaded loopfilter initialisations -void vp9_lpf_mt_init(VP9LfSync *lf_sync, struct VP9Common *cm, - int frame_filter_level, int num_workers); - -void vp9_loopfilter_rows(LFWorkerData *lf_data, VP9LfSync *lf_sync); - -void vp9_set_row(VP9LfSync *lf_sync, int num_tiles, int row, int is_last_row, - int corrupted); - -void vp9_loopfilter_job(LFWorkerData *lf_data, VP9LfSync *lf_sync); - -void vp9_accumulate_frame_counts(struct FRAME_COUNTS *accum, - const struct FRAME_COUNTS *counts, int is_dec); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_THREAD_COMMON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_tile_common.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_tile_common.c deleted file mode 100644 index 672f808a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_tile_common.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp9/common/vp9_tile_common.h" -#include "vp9/common/vp9_onyxc_int.h" -#include "vpx_dsp/vpx_dsp_common.h" - -#define MIN_TILE_WIDTH_B64 4 -#define MAX_TILE_WIDTH_B64 64 - -static int get_tile_offset(int idx, int mis, int log2) { - const int sb_cols = mi_cols_aligned_to_sb(mis) >> MI_BLOCK_SIZE_LOG2; - const int offset = ((idx * sb_cols) >> log2) << MI_BLOCK_SIZE_LOG2; - return VPXMIN(offset, mis); -} - -void vp9_tile_set_row(TileInfo *tile, const VP9_COMMON *cm, int row) { - tile->mi_row_start = get_tile_offset(row, cm->mi_rows, cm->log2_tile_rows); - tile->mi_row_end = get_tile_offset(row + 1, cm->mi_rows, cm->log2_tile_rows); -} - -void vp9_tile_set_col(TileInfo *tile, const VP9_COMMON *cm, int col) { - tile->mi_col_start = get_tile_offset(col, cm->mi_cols, cm->log2_tile_cols); - tile->mi_col_end = get_tile_offset(col + 1, cm->mi_cols, cm->log2_tile_cols); -} - -void vp9_tile_init(TileInfo *tile, const VP9_COMMON *cm, int row, int col) { - vp9_tile_set_row(tile, cm, row); - vp9_tile_set_col(tile, cm, col); -} - -static int get_min_log2_tile_cols(const int sb64_cols) { - int min_log2 = 0; - while ((MAX_TILE_WIDTH_B64 << min_log2) < sb64_cols) ++min_log2; - return min_log2; -} - -static int get_max_log2_tile_cols(const int sb64_cols) { - int max_log2 = 1; - while ((sb64_cols >> max_log2) >= MIN_TILE_WIDTH_B64) ++max_log2; - return max_log2 - 1; -} - -void vp9_get_tile_n_bits(int mi_cols, int *min_log2_tile_cols, - int *max_log2_tile_cols) { - const int sb64_cols = mi_cols_aligned_to_sb(mi_cols) >> MI_BLOCK_SIZE_LOG2; - *min_log2_tile_cols = get_min_log2_tile_cols(sb64_cols); - *max_log2_tile_cols = get_max_log2_tile_cols(sb64_cols); - assert(*min_log2_tile_cols <= *max_log2_tile_cols); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_tile_common.h b/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_tile_common.h deleted file mode 100644 index 4ccf0a3d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/vp9_tile_common.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_COMMON_VP9_TILE_COMMON_H_ -#define VPX_VP9_COMMON_VP9_TILE_COMMON_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -struct VP9Common; - -typedef struct TileInfo { - int mi_row_start, mi_row_end; - int mi_col_start, mi_col_end; -} TileInfo; - -// initializes 'tile->mi_(row|col)_(start|end)' for (row, col) based on -// 'cm->log2_tile_(rows|cols)' & 'cm->mi_(rows|cols)' -void vp9_tile_init(TileInfo *tile, const struct VP9Common *cm, int row, - int col); - -void vp9_tile_set_row(TileInfo *tile, const struct VP9Common *cm, int row); -void vp9_tile_set_col(TileInfo *tile, const struct VP9Common *cm, int col); - -void vp9_get_tile_n_bits(int mi_cols, int *min_log2_tile_cols, - int *max_log2_tile_cols); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_COMMON_VP9_TILE_COMMON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/x86/vp9_highbd_iht16x16_add_sse4.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/x86/vp9_highbd_iht16x16_add_sse4.c deleted file mode 100644 index 57b79a73..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/x86/vp9_highbd_iht16x16_add_sse4.c +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp9_rtcd.h" -#include "vp9/common/vp9_idct.h" -#include "vpx_dsp/x86/highbd_inv_txfm_sse4.h" -#include "vpx_dsp/x86/inv_txfm_sse2.h" -#include "vpx_dsp/x86/transpose_sse2.h" -#include "vpx_dsp/x86/txfm_common_sse2.h" - -static INLINE void highbd_iadst_half_butterfly_sse4_1(const __m128i in, - const int c, - __m128i *const s) { - const __m128i pair_c = pair_set_epi32(4 * c, 0); - __m128i x[2]; - - extend_64bit(in, x); - s[0] = _mm_mul_epi32(pair_c, x[0]); - s[1] = _mm_mul_epi32(pair_c, x[1]); -} - -static INLINE void highbd_iadst_butterfly_sse4_1(const __m128i in0, - const __m128i in1, - const int c0, const int c1, - __m128i *const s0, - __m128i *const s1) { - const __m128i pair_c0 = pair_set_epi32(4 * c0, 0); - const __m128i pair_c1 = pair_set_epi32(4 * c1, 0); - __m128i t00[2], t01[2], t10[2], t11[2]; - __m128i x0[2], x1[2]; - - extend_64bit(in0, x0); - extend_64bit(in1, x1); - t00[0] = _mm_mul_epi32(pair_c0, x0[0]); - t00[1] = _mm_mul_epi32(pair_c0, x0[1]); - t01[0] = _mm_mul_epi32(pair_c0, x1[0]); - t01[1] = _mm_mul_epi32(pair_c0, x1[1]); - t10[0] = _mm_mul_epi32(pair_c1, x0[0]); - t10[1] = _mm_mul_epi32(pair_c1, x0[1]); - t11[0] = _mm_mul_epi32(pair_c1, x1[0]); - t11[1] = _mm_mul_epi32(pair_c1, x1[1]); - - s0[0] = _mm_add_epi64(t00[0], t11[0]); - s0[1] = _mm_add_epi64(t00[1], t11[1]); - s1[0] = _mm_sub_epi64(t10[0], t01[0]); - s1[1] = _mm_sub_epi64(t10[1], t01[1]); -} - -static void highbd_iadst16_4col_sse4_1(__m128i *const io /*io[16]*/) { - __m128i s0[2], s1[2], s2[2], s3[2], s4[2], s5[2], s6[2], s7[2], s8[2], s9[2], - s10[2], s11[2], s12[2], s13[2], s14[2], s15[2]; - __m128i x0[2], x1[2], x2[2], x3[2], x4[2], x5[2], x6[2], x7[2], x8[2], x9[2], - x10[2], x11[2], x12[2], x13[2], x14[2], x15[2]; - - // stage 1 - highbd_iadst_butterfly_sse4_1(io[15], io[0], cospi_1_64, cospi_31_64, s0, s1); - highbd_iadst_butterfly_sse4_1(io[13], io[2], cospi_5_64, cospi_27_64, s2, s3); - highbd_iadst_butterfly_sse4_1(io[11], io[4], cospi_9_64, cospi_23_64, s4, s5); - highbd_iadst_butterfly_sse4_1(io[9], io[6], cospi_13_64, cospi_19_64, s6, s7); - highbd_iadst_butterfly_sse4_1(io[7], io[8], cospi_17_64, cospi_15_64, s8, s9); - highbd_iadst_butterfly_sse4_1(io[5], io[10], cospi_21_64, cospi_11_64, s10, - s11); - highbd_iadst_butterfly_sse4_1(io[3], io[12], cospi_25_64, cospi_7_64, s12, - s13); - highbd_iadst_butterfly_sse4_1(io[1], io[14], cospi_29_64, cospi_3_64, s14, - s15); - - x0[0] = _mm_add_epi64(s0[0], s8[0]); - x0[1] = _mm_add_epi64(s0[1], s8[1]); - x1[0] = _mm_add_epi64(s1[0], s9[0]); - x1[1] = _mm_add_epi64(s1[1], s9[1]); - x2[0] = _mm_add_epi64(s2[0], s10[0]); - x2[1] = _mm_add_epi64(s2[1], s10[1]); - x3[0] = _mm_add_epi64(s3[0], s11[0]); - x3[1] = _mm_add_epi64(s3[1], s11[1]); - x4[0] = _mm_add_epi64(s4[0], s12[0]); - x4[1] = _mm_add_epi64(s4[1], s12[1]); - x5[0] = _mm_add_epi64(s5[0], s13[0]); - x5[1] = _mm_add_epi64(s5[1], s13[1]); - x6[0] = _mm_add_epi64(s6[0], s14[0]); - x6[1] = _mm_add_epi64(s6[1], s14[1]); - x7[0] = _mm_add_epi64(s7[0], s15[0]); - x7[1] = _mm_add_epi64(s7[1], s15[1]); - x8[0] = _mm_sub_epi64(s0[0], s8[0]); - x8[1] = _mm_sub_epi64(s0[1], s8[1]); - x9[0] = _mm_sub_epi64(s1[0], s9[0]); - x9[1] = _mm_sub_epi64(s1[1], s9[1]); - x10[0] = _mm_sub_epi64(s2[0], s10[0]); - x10[1] = _mm_sub_epi64(s2[1], s10[1]); - x11[0] = _mm_sub_epi64(s3[0], s11[0]); - x11[1] = _mm_sub_epi64(s3[1], s11[1]); - x12[0] = _mm_sub_epi64(s4[0], s12[0]); - x12[1] = _mm_sub_epi64(s4[1], s12[1]); - x13[0] = _mm_sub_epi64(s5[0], s13[0]); - x13[1] = _mm_sub_epi64(s5[1], s13[1]); - x14[0] = _mm_sub_epi64(s6[0], s14[0]); - x14[1] = _mm_sub_epi64(s6[1], s14[1]); - x15[0] = _mm_sub_epi64(s7[0], s15[0]); - x15[1] = _mm_sub_epi64(s7[1], s15[1]); - - x0[0] = dct_const_round_shift_64bit(x0[0]); - x0[1] = dct_const_round_shift_64bit(x0[1]); - x1[0] = dct_const_round_shift_64bit(x1[0]); - x1[1] = dct_const_round_shift_64bit(x1[1]); - x2[0] = dct_const_round_shift_64bit(x2[0]); - x2[1] = dct_const_round_shift_64bit(x2[1]); - x3[0] = dct_const_round_shift_64bit(x3[0]); - x3[1] = dct_const_round_shift_64bit(x3[1]); - x4[0] = dct_const_round_shift_64bit(x4[0]); - x4[1] = dct_const_round_shift_64bit(x4[1]); - x5[0] = dct_const_round_shift_64bit(x5[0]); - x5[1] = dct_const_round_shift_64bit(x5[1]); - x6[0] = dct_const_round_shift_64bit(x6[0]); - x6[1] = dct_const_round_shift_64bit(x6[1]); - x7[0] = dct_const_round_shift_64bit(x7[0]); - x7[1] = dct_const_round_shift_64bit(x7[1]); - x8[0] = dct_const_round_shift_64bit(x8[0]); - x8[1] = dct_const_round_shift_64bit(x8[1]); - x9[0] = dct_const_round_shift_64bit(x9[0]); - x9[1] = dct_const_round_shift_64bit(x9[1]); - x10[0] = dct_const_round_shift_64bit(x10[0]); - x10[1] = dct_const_round_shift_64bit(x10[1]); - x11[0] = dct_const_round_shift_64bit(x11[0]); - x11[1] = dct_const_round_shift_64bit(x11[1]); - x12[0] = dct_const_round_shift_64bit(x12[0]); - x12[1] = dct_const_round_shift_64bit(x12[1]); - x13[0] = dct_const_round_shift_64bit(x13[0]); - x13[1] = dct_const_round_shift_64bit(x13[1]); - x14[0] = dct_const_round_shift_64bit(x14[0]); - x14[1] = dct_const_round_shift_64bit(x14[1]); - x15[0] = dct_const_round_shift_64bit(x15[0]); - x15[1] = dct_const_round_shift_64bit(x15[1]); - x0[0] = pack_4(x0[0], x0[1]); - x1[0] = pack_4(x1[0], x1[1]); - x2[0] = pack_4(x2[0], x2[1]); - x3[0] = pack_4(x3[0], x3[1]); - x4[0] = pack_4(x4[0], x4[1]); - x5[0] = pack_4(x5[0], x5[1]); - x6[0] = pack_4(x6[0], x6[1]); - x7[0] = pack_4(x7[0], x7[1]); - x8[0] = pack_4(x8[0], x8[1]); - x9[0] = pack_4(x9[0], x9[1]); - x10[0] = pack_4(x10[0], x10[1]); - x11[0] = pack_4(x11[0], x11[1]); - x12[0] = pack_4(x12[0], x12[1]); - x13[0] = pack_4(x13[0], x13[1]); - x14[0] = pack_4(x14[0], x14[1]); - x15[0] = pack_4(x15[0], x15[1]); - - // stage 2 - s0[0] = x0[0]; - s1[0] = x1[0]; - s2[0] = x2[0]; - s3[0] = x3[0]; - s4[0] = x4[0]; - s5[0] = x5[0]; - s6[0] = x6[0]; - s7[0] = x7[0]; - x0[0] = _mm_add_epi32(s0[0], s4[0]); - x1[0] = _mm_add_epi32(s1[0], s5[0]); - x2[0] = _mm_add_epi32(s2[0], s6[0]); - x3[0] = _mm_add_epi32(s3[0], s7[0]); - x4[0] = _mm_sub_epi32(s0[0], s4[0]); - x5[0] = _mm_sub_epi32(s1[0], s5[0]); - x6[0] = _mm_sub_epi32(s2[0], s6[0]); - x7[0] = _mm_sub_epi32(s3[0], s7[0]); - - highbd_iadst_butterfly_sse4_1(x8[0], x9[0], cospi_4_64, cospi_28_64, s8, s9); - highbd_iadst_butterfly_sse4_1(x10[0], x11[0], cospi_20_64, cospi_12_64, s10, - s11); - highbd_iadst_butterfly_sse4_1(x13[0], x12[0], cospi_28_64, cospi_4_64, s13, - s12); - highbd_iadst_butterfly_sse4_1(x15[0], x14[0], cospi_12_64, cospi_20_64, s15, - s14); - - x8[0] = _mm_add_epi64(s8[0], s12[0]); - x8[1] = _mm_add_epi64(s8[1], s12[1]); - x9[0] = _mm_add_epi64(s9[0], s13[0]); - x9[1] = _mm_add_epi64(s9[1], s13[1]); - x10[0] = _mm_add_epi64(s10[0], s14[0]); - x10[1] = _mm_add_epi64(s10[1], s14[1]); - x11[0] = _mm_add_epi64(s11[0], s15[0]); - x11[1] = _mm_add_epi64(s11[1], s15[1]); - x12[0] = _mm_sub_epi64(s8[0], s12[0]); - x12[1] = _mm_sub_epi64(s8[1], s12[1]); - x13[0] = _mm_sub_epi64(s9[0], s13[0]); - x13[1] = _mm_sub_epi64(s9[1], s13[1]); - x14[0] = _mm_sub_epi64(s10[0], s14[0]); - x14[1] = _mm_sub_epi64(s10[1], s14[1]); - x15[0] = _mm_sub_epi64(s11[0], s15[0]); - x15[1] = _mm_sub_epi64(s11[1], s15[1]); - x8[0] = dct_const_round_shift_64bit(x8[0]); - x8[1] = dct_const_round_shift_64bit(x8[1]); - x9[0] = dct_const_round_shift_64bit(x9[0]); - x9[1] = dct_const_round_shift_64bit(x9[1]); - x10[0] = dct_const_round_shift_64bit(x10[0]); - x10[1] = dct_const_round_shift_64bit(x10[1]); - x11[0] = dct_const_round_shift_64bit(x11[0]); - x11[1] = dct_const_round_shift_64bit(x11[1]); - x12[0] = dct_const_round_shift_64bit(x12[0]); - x12[1] = dct_const_round_shift_64bit(x12[1]); - x13[0] = dct_const_round_shift_64bit(x13[0]); - x13[1] = dct_const_round_shift_64bit(x13[1]); - x14[0] = dct_const_round_shift_64bit(x14[0]); - x14[1] = dct_const_round_shift_64bit(x14[1]); - x15[0] = dct_const_round_shift_64bit(x15[0]); - x15[1] = dct_const_round_shift_64bit(x15[1]); - x8[0] = pack_4(x8[0], x8[1]); - x9[0] = pack_4(x9[0], x9[1]); - x10[0] = pack_4(x10[0], x10[1]); - x11[0] = pack_4(x11[0], x11[1]); - x12[0] = pack_4(x12[0], x12[1]); - x13[0] = pack_4(x13[0], x13[1]); - x14[0] = pack_4(x14[0], x14[1]); - x15[0] = pack_4(x15[0], x15[1]); - - // stage 3 - s0[0] = x0[0]; - s1[0] = x1[0]; - s2[0] = x2[0]; - s3[0] = x3[0]; - highbd_iadst_butterfly_sse4_1(x4[0], x5[0], cospi_8_64, cospi_24_64, s4, s5); - highbd_iadst_butterfly_sse4_1(x7[0], x6[0], cospi_24_64, cospi_8_64, s7, s6); - s8[0] = x8[0]; - s9[0] = x9[0]; - s10[0] = x10[0]; - s11[0] = x11[0]; - highbd_iadst_butterfly_sse4_1(x12[0], x13[0], cospi_8_64, cospi_24_64, s12, - s13); - highbd_iadst_butterfly_sse4_1(x15[0], x14[0], cospi_24_64, cospi_8_64, s15, - s14); - - x0[0] = _mm_add_epi32(s0[0], s2[0]); - x1[0] = _mm_add_epi32(s1[0], s3[0]); - x2[0] = _mm_sub_epi32(s0[0], s2[0]); - x3[0] = _mm_sub_epi32(s1[0], s3[0]); - x4[0] = _mm_add_epi64(s4[0], s6[0]); - x4[1] = _mm_add_epi64(s4[1], s6[1]); - x5[0] = _mm_add_epi64(s5[0], s7[0]); - x5[1] = _mm_add_epi64(s5[1], s7[1]); - x6[0] = _mm_sub_epi64(s4[0], s6[0]); - x6[1] = _mm_sub_epi64(s4[1], s6[1]); - x7[0] = _mm_sub_epi64(s5[0], s7[0]); - x7[1] = _mm_sub_epi64(s5[1], s7[1]); - x4[0] = dct_const_round_shift_64bit(x4[0]); - x4[1] = dct_const_round_shift_64bit(x4[1]); - x5[0] = dct_const_round_shift_64bit(x5[0]); - x5[1] = dct_const_round_shift_64bit(x5[1]); - x6[0] = dct_const_round_shift_64bit(x6[0]); - x6[1] = dct_const_round_shift_64bit(x6[1]); - x7[0] = dct_const_round_shift_64bit(x7[0]); - x7[1] = dct_const_round_shift_64bit(x7[1]); - x4[0] = pack_4(x4[0], x4[1]); - x5[0] = pack_4(x5[0], x5[1]); - x6[0] = pack_4(x6[0], x6[1]); - x7[0] = pack_4(x7[0], x7[1]); - x8[0] = _mm_add_epi32(s8[0], s10[0]); - x9[0] = _mm_add_epi32(s9[0], s11[0]); - x10[0] = _mm_sub_epi32(s8[0], s10[0]); - x11[0] = _mm_sub_epi32(s9[0], s11[0]); - x12[0] = _mm_add_epi64(s12[0], s14[0]); - x12[1] = _mm_add_epi64(s12[1], s14[1]); - x13[0] = _mm_add_epi64(s13[0], s15[0]); - x13[1] = _mm_add_epi64(s13[1], s15[1]); - x14[0] = _mm_sub_epi64(s12[0], s14[0]); - x14[1] = _mm_sub_epi64(s12[1], s14[1]); - x15[0] = _mm_sub_epi64(s13[0], s15[0]); - x15[1] = _mm_sub_epi64(s13[1], s15[1]); - x12[0] = dct_const_round_shift_64bit(x12[0]); - x12[1] = dct_const_round_shift_64bit(x12[1]); - x13[0] = dct_const_round_shift_64bit(x13[0]); - x13[1] = dct_const_round_shift_64bit(x13[1]); - x14[0] = dct_const_round_shift_64bit(x14[0]); - x14[1] = dct_const_round_shift_64bit(x14[1]); - x15[0] = dct_const_round_shift_64bit(x15[0]); - x15[1] = dct_const_round_shift_64bit(x15[1]); - x12[0] = pack_4(x12[0], x12[1]); - x13[0] = pack_4(x13[0], x13[1]); - x14[0] = pack_4(x14[0], x14[1]); - x15[0] = pack_4(x15[0], x15[1]); - - // stage 4 - s2[0] = _mm_add_epi32(x2[0], x3[0]); - s3[0] = _mm_sub_epi32(x2[0], x3[0]); - s6[0] = _mm_add_epi32(x7[0], x6[0]); - s7[0] = _mm_sub_epi32(x7[0], x6[0]); - s10[0] = _mm_add_epi32(x11[0], x10[0]); - s11[0] = _mm_sub_epi32(x11[0], x10[0]); - s14[0] = _mm_add_epi32(x14[0], x15[0]); - s15[0] = _mm_sub_epi32(x14[0], x15[0]); - highbd_iadst_half_butterfly_sse4_1(s2[0], -cospi_16_64, s2); - highbd_iadst_half_butterfly_sse4_1(s3[0], cospi_16_64, s3); - highbd_iadst_half_butterfly_sse4_1(s6[0], cospi_16_64, s6); - highbd_iadst_half_butterfly_sse4_1(s7[0], cospi_16_64, s7); - highbd_iadst_half_butterfly_sse4_1(s10[0], cospi_16_64, s10); - highbd_iadst_half_butterfly_sse4_1(s11[0], cospi_16_64, s11); - highbd_iadst_half_butterfly_sse4_1(s14[0], -cospi_16_64, s14); - highbd_iadst_half_butterfly_sse4_1(s15[0], cospi_16_64, s15); - - x2[0] = dct_const_round_shift_64bit(s2[0]); - x2[1] = dct_const_round_shift_64bit(s2[1]); - x3[0] = dct_const_round_shift_64bit(s3[0]); - x3[1] = dct_const_round_shift_64bit(s3[1]); - x6[0] = dct_const_round_shift_64bit(s6[0]); - x6[1] = dct_const_round_shift_64bit(s6[1]); - x7[0] = dct_const_round_shift_64bit(s7[0]); - x7[1] = dct_const_round_shift_64bit(s7[1]); - x10[0] = dct_const_round_shift_64bit(s10[0]); - x10[1] = dct_const_round_shift_64bit(s10[1]); - x11[0] = dct_const_round_shift_64bit(s11[0]); - x11[1] = dct_const_round_shift_64bit(s11[1]); - x14[0] = dct_const_round_shift_64bit(s14[0]); - x14[1] = dct_const_round_shift_64bit(s14[1]); - x15[0] = dct_const_round_shift_64bit(s15[0]); - x15[1] = dct_const_round_shift_64bit(s15[1]); - x2[0] = pack_4(x2[0], x2[1]); - x3[0] = pack_4(x3[0], x3[1]); - x6[0] = pack_4(x6[0], x6[1]); - x7[0] = pack_4(x7[0], x7[1]); - x10[0] = pack_4(x10[0], x10[1]); - x11[0] = pack_4(x11[0], x11[1]); - x14[0] = pack_4(x14[0], x14[1]); - x15[0] = pack_4(x15[0], x15[1]); - - io[0] = x0[0]; - io[1] = _mm_sub_epi32(_mm_setzero_si128(), x8[0]); - io[2] = x12[0]; - io[3] = _mm_sub_epi32(_mm_setzero_si128(), x4[0]); - io[4] = x6[0]; - io[5] = x14[0]; - io[6] = x10[0]; - io[7] = x2[0]; - io[8] = x3[0]; - io[9] = x11[0]; - io[10] = x15[0]; - io[11] = x7[0]; - io[12] = x5[0]; - io[13] = _mm_sub_epi32(_mm_setzero_si128(), x13[0]); - io[14] = x9[0]; - io[15] = _mm_sub_epi32(_mm_setzero_si128(), x1[0]); -} - -void vp9_highbd_iht16x16_256_add_sse4_1(const tran_low_t *input, uint16_t *dest, - int stride, int tx_type, int bd) { - int i; - __m128i out[16], *in; - - if (bd == 8) { - __m128i l[16], r[16]; - - in = l; - for (i = 0; i < 2; i++) { - highbd_load_pack_transpose_32bit_8x8(&input[0], 16, &in[0]); - highbd_load_pack_transpose_32bit_8x8(&input[8], 16, &in[8]); - if (tx_type == DCT_DCT || tx_type == ADST_DCT) { - idct16_8col(in, in); - } else { - vpx_iadst16_8col_sse2(in); - } - in = r; - input += 128; - } - - for (i = 0; i < 16; i += 8) { - int j; - transpose_16bit_8x8(l + i, out); - transpose_16bit_8x8(r + i, out + 8); - if (tx_type == DCT_DCT || tx_type == DCT_ADST) { - idct16_8col(out, out); - } else { - vpx_iadst16_8col_sse2(out); - } - - for (j = 0; j < 16; ++j) { - highbd_write_buffer_8(dest + j * stride, out[j], bd); - } - dest += 8; - } - } else { - __m128i all[4][16]; - - for (i = 0; i < 4; i++) { - in = all[i]; - highbd_load_transpose_32bit_8x4(&input[0], 16, &in[0]); - highbd_load_transpose_32bit_8x4(&input[8], 16, &in[8]); - if (tx_type == DCT_DCT || tx_type == ADST_DCT) { - vpx_highbd_idct16_4col_sse4_1(in); - } else { - highbd_iadst16_4col_sse4_1(in); - } - input += 4 * 16; - } - - for (i = 0; i < 16; i += 4) { - int j; - transpose_32bit_4x4(all[0] + i, out + 0); - transpose_32bit_4x4(all[1] + i, out + 4); - transpose_32bit_4x4(all[2] + i, out + 8); - transpose_32bit_4x4(all[3] + i, out + 12); - if (tx_type == DCT_DCT || tx_type == DCT_ADST) { - vpx_highbd_idct16_4col_sse4_1(out); - } else { - highbd_iadst16_4col_sse4_1(out); - } - - for (j = 0; j < 16; ++j) { - highbd_write_buffer_4(dest + j * stride, out[j], bd); - } - dest += 4; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/x86/vp9_highbd_iht4x4_add_sse4.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/x86/vp9_highbd_iht4x4_add_sse4.c deleted file mode 100644 index af158536..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/x86/vp9_highbd_iht4x4_add_sse4.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp9_rtcd.h" -#include "vp9/common/vp9_idct.h" -#include "vpx_dsp/x86/highbd_inv_txfm_sse4.h" -#include "vpx_dsp/x86/inv_txfm_sse2.h" -#include "vpx_dsp/x86/transpose_sse2.h" -#include "vpx_dsp/x86/txfm_common_sse2.h" - -static INLINE void highbd_iadst4_sse4_1(__m128i *const io) { - const __m128i pair_c1 = pair_set_epi32(4 * sinpi_1_9, 0); - const __m128i pair_c2 = pair_set_epi32(4 * sinpi_2_9, 0); - const __m128i pair_c3 = pair_set_epi32(4 * sinpi_3_9, 0); - const __m128i pair_c4 = pair_set_epi32(4 * sinpi_4_9, 0); - __m128i s0[2], s1[2], s2[2], s3[2], s4[2], s5[2], s6[2], t0[2], t1[2], t2[2]; - __m128i temp[2]; - - transpose_32bit_4x4(io, io); - - extend_64bit(io[0], temp); - s0[0] = _mm_mul_epi32(pair_c1, temp[0]); - s0[1] = _mm_mul_epi32(pair_c1, temp[1]); - s1[0] = _mm_mul_epi32(pair_c2, temp[0]); - s1[1] = _mm_mul_epi32(pair_c2, temp[1]); - - extend_64bit(io[1], temp); - s2[0] = _mm_mul_epi32(pair_c3, temp[0]); - s2[1] = _mm_mul_epi32(pair_c3, temp[1]); - - extend_64bit(io[2], temp); - s3[0] = _mm_mul_epi32(pair_c4, temp[0]); - s3[1] = _mm_mul_epi32(pair_c4, temp[1]); - s4[0] = _mm_mul_epi32(pair_c1, temp[0]); - s4[1] = _mm_mul_epi32(pair_c1, temp[1]); - - extend_64bit(io[3], temp); - s5[0] = _mm_mul_epi32(pair_c2, temp[0]); - s5[1] = _mm_mul_epi32(pair_c2, temp[1]); - s6[0] = _mm_mul_epi32(pair_c4, temp[0]); - s6[1] = _mm_mul_epi32(pair_c4, temp[1]); - - t0[0] = _mm_add_epi64(s0[0], s3[0]); - t0[1] = _mm_add_epi64(s0[1], s3[1]); - t0[0] = _mm_add_epi64(t0[0], s5[0]); - t0[1] = _mm_add_epi64(t0[1], s5[1]); - t1[0] = _mm_sub_epi64(s1[0], s4[0]); - t1[1] = _mm_sub_epi64(s1[1], s4[1]); - t1[0] = _mm_sub_epi64(t1[0], s6[0]); - t1[1] = _mm_sub_epi64(t1[1], s6[1]); - temp[0] = _mm_sub_epi32(io[0], io[2]); - temp[0] = _mm_add_epi32(temp[0], io[3]); - extend_64bit(temp[0], temp); - t2[0] = _mm_mul_epi32(pair_c3, temp[0]); - t2[1] = _mm_mul_epi32(pair_c3, temp[1]); - - s0[0] = _mm_add_epi64(t0[0], s2[0]); - s0[1] = _mm_add_epi64(t0[1], s2[1]); - s1[0] = _mm_add_epi64(t1[0], s2[0]); - s1[1] = _mm_add_epi64(t1[1], s2[1]); - s3[0] = _mm_add_epi64(t0[0], t1[0]); - s3[1] = _mm_add_epi64(t0[1], t1[1]); - s3[0] = _mm_sub_epi64(s3[0], s2[0]); - s3[1] = _mm_sub_epi64(s3[1], s2[1]); - - s0[0] = dct_const_round_shift_64bit(s0[0]); - s0[1] = dct_const_round_shift_64bit(s0[1]); - s1[0] = dct_const_round_shift_64bit(s1[0]); - s1[1] = dct_const_round_shift_64bit(s1[1]); - s2[0] = dct_const_round_shift_64bit(t2[0]); - s2[1] = dct_const_round_shift_64bit(t2[1]); - s3[0] = dct_const_round_shift_64bit(s3[0]); - s3[1] = dct_const_round_shift_64bit(s3[1]); - io[0] = pack_4(s0[0], s0[1]); - io[1] = pack_4(s1[0], s1[1]); - io[2] = pack_4(s2[0], s2[1]); - io[3] = pack_4(s3[0], s3[1]); -} - -void vp9_highbd_iht4x4_16_add_sse4_1(const tran_low_t *input, uint16_t *dest, - int stride, int tx_type, int bd) { - __m128i io[4]; - - io[0] = _mm_load_si128((const __m128i *)(input + 0)); - io[1] = _mm_load_si128((const __m128i *)(input + 4)); - io[2] = _mm_load_si128((const __m128i *)(input + 8)); - io[3] = _mm_load_si128((const __m128i *)(input + 12)); - - if (bd == 8) { - __m128i io_short[2]; - - io_short[0] = _mm_packs_epi32(io[0], io[1]); - io_short[1] = _mm_packs_epi32(io[2], io[3]); - if (tx_type == DCT_DCT || tx_type == ADST_DCT) { - idct4_sse2(io_short); - } else { - iadst4_sse2(io_short); - } - if (tx_type == DCT_DCT || tx_type == DCT_ADST) { - idct4_sse2(io_short); - } else { - iadst4_sse2(io_short); - } - io_short[0] = _mm_add_epi16(io_short[0], _mm_set1_epi16(8)); - io_short[1] = _mm_add_epi16(io_short[1], _mm_set1_epi16(8)); - io[0] = _mm_srai_epi16(io_short[0], 4); - io[1] = _mm_srai_epi16(io_short[1], 4); - } else { - if (tx_type == DCT_DCT || tx_type == ADST_DCT) { - highbd_idct4_sse4_1(io); - } else { - highbd_iadst4_sse4_1(io); - } - if (tx_type == DCT_DCT || tx_type == DCT_ADST) { - highbd_idct4_sse4_1(io); - } else { - highbd_iadst4_sse4_1(io); - } - io[0] = wraplow_16bit_shift4(io[0], io[1], _mm_set1_epi32(8)); - io[1] = wraplow_16bit_shift4(io[2], io[3], _mm_set1_epi32(8)); - } - - recon_and_store_4x4(io, dest, stride, bd); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/x86/vp9_highbd_iht8x8_add_sse4.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/x86/vp9_highbd_iht8x8_add_sse4.c deleted file mode 100644 index 7d949b6d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/x86/vp9_highbd_iht8x8_add_sse4.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp9_rtcd.h" -#include "vp9/common/vp9_idct.h" -#include "vpx_dsp/x86/highbd_inv_txfm_sse4.h" -#include "vpx_dsp/x86/inv_txfm_sse2.h" -#include "vpx_dsp/x86/transpose_sse2.h" -#include "vpx_dsp/x86/txfm_common_sse2.h" - -static INLINE void highbd_iadst_half_butterfly_sse4_1(const __m128i in, - const int c, - __m128i *const s) { - const __m128i pair_c = pair_set_epi32(4 * c, 0); - __m128i x[2]; - - extend_64bit(in, x); - s[0] = _mm_mul_epi32(pair_c, x[0]); - s[1] = _mm_mul_epi32(pair_c, x[1]); -} - -static INLINE void highbd_iadst_butterfly_sse4_1(const __m128i in0, - const __m128i in1, - const int c0, const int c1, - __m128i *const s0, - __m128i *const s1) { - const __m128i pair_c0 = pair_set_epi32(4 * c0, 0); - const __m128i pair_c1 = pair_set_epi32(4 * c1, 0); - __m128i t00[2], t01[2], t10[2], t11[2]; - __m128i x0[2], x1[2]; - - extend_64bit(in0, x0); - extend_64bit(in1, x1); - t00[0] = _mm_mul_epi32(pair_c0, x0[0]); - t00[1] = _mm_mul_epi32(pair_c0, x0[1]); - t01[0] = _mm_mul_epi32(pair_c0, x1[0]); - t01[1] = _mm_mul_epi32(pair_c0, x1[1]); - t10[0] = _mm_mul_epi32(pair_c1, x0[0]); - t10[1] = _mm_mul_epi32(pair_c1, x0[1]); - t11[0] = _mm_mul_epi32(pair_c1, x1[0]); - t11[1] = _mm_mul_epi32(pair_c1, x1[1]); - - s0[0] = _mm_add_epi64(t00[0], t11[0]); - s0[1] = _mm_add_epi64(t00[1], t11[1]); - s1[0] = _mm_sub_epi64(t10[0], t01[0]); - s1[1] = _mm_sub_epi64(t10[1], t01[1]); -} - -static void highbd_iadst8_sse4_1(__m128i *const io) { - __m128i s0[2], s1[2], s2[2], s3[2], s4[2], s5[2], s6[2], s7[2]; - __m128i x0[2], x1[2], x2[2], x3[2], x4[2], x5[2], x6[2], x7[2]; - - transpose_32bit_4x4x2(io, io); - - // stage 1 - highbd_iadst_butterfly_sse4_1(io[7], io[0], cospi_2_64, cospi_30_64, s0, s1); - highbd_iadst_butterfly_sse4_1(io[3], io[4], cospi_18_64, cospi_14_64, s4, s5); - x0[0] = _mm_add_epi64(s0[0], s4[0]); - x0[1] = _mm_add_epi64(s0[1], s4[1]); - x1[0] = _mm_add_epi64(s1[0], s5[0]); - x1[1] = _mm_add_epi64(s1[1], s5[1]); - x4[0] = _mm_sub_epi64(s0[0], s4[0]); - x4[1] = _mm_sub_epi64(s0[1], s4[1]); - x5[0] = _mm_sub_epi64(s1[0], s5[0]); - x5[1] = _mm_sub_epi64(s1[1], s5[1]); - - highbd_iadst_butterfly_sse4_1(io[5], io[2], cospi_10_64, cospi_22_64, s2, s3); - highbd_iadst_butterfly_sse4_1(io[1], io[6], cospi_26_64, cospi_6_64, s6, s7); - x2[0] = _mm_add_epi64(s2[0], s6[0]); - x2[1] = _mm_add_epi64(s2[1], s6[1]); - x3[0] = _mm_add_epi64(s3[0], s7[0]); - x3[1] = _mm_add_epi64(s3[1], s7[1]); - x6[0] = _mm_sub_epi64(s2[0], s6[0]); - x6[1] = _mm_sub_epi64(s2[1], s6[1]); - x7[0] = _mm_sub_epi64(s3[0], s7[0]); - x7[1] = _mm_sub_epi64(s3[1], s7[1]); - - x0[0] = dct_const_round_shift_64bit(x0[0]); - x0[1] = dct_const_round_shift_64bit(x0[1]); - x1[0] = dct_const_round_shift_64bit(x1[0]); - x1[1] = dct_const_round_shift_64bit(x1[1]); - x2[0] = dct_const_round_shift_64bit(x2[0]); - x2[1] = dct_const_round_shift_64bit(x2[1]); - x3[0] = dct_const_round_shift_64bit(x3[0]); - x3[1] = dct_const_round_shift_64bit(x3[1]); - x4[0] = dct_const_round_shift_64bit(x4[0]); - x4[1] = dct_const_round_shift_64bit(x4[1]); - x5[0] = dct_const_round_shift_64bit(x5[0]); - x5[1] = dct_const_round_shift_64bit(x5[1]); - x6[0] = dct_const_round_shift_64bit(x6[0]); - x6[1] = dct_const_round_shift_64bit(x6[1]); - x7[0] = dct_const_round_shift_64bit(x7[0]); - x7[1] = dct_const_round_shift_64bit(x7[1]); - s0[0] = pack_4(x0[0], x0[1]); // s0 = x0; - s1[0] = pack_4(x1[0], x1[1]); // s1 = x1; - s2[0] = pack_4(x2[0], x2[1]); // s2 = x2; - s3[0] = pack_4(x3[0], x3[1]); // s3 = x3; - x4[0] = pack_4(x4[0], x4[1]); - x5[0] = pack_4(x5[0], x5[1]); - x6[0] = pack_4(x6[0], x6[1]); - x7[0] = pack_4(x7[0], x7[1]); - - // stage 2 - x0[0] = _mm_add_epi32(s0[0], s2[0]); - x1[0] = _mm_add_epi32(s1[0], s3[0]); - x2[0] = _mm_sub_epi32(s0[0], s2[0]); - x3[0] = _mm_sub_epi32(s1[0], s3[0]); - - highbd_iadst_butterfly_sse4_1(x4[0], x5[0], cospi_8_64, cospi_24_64, s4, s5); - highbd_iadst_butterfly_sse4_1(x7[0], x6[0], cospi_24_64, cospi_8_64, s7, s6); - - x4[0] = _mm_add_epi64(s4[0], s6[0]); - x4[1] = _mm_add_epi64(s4[1], s6[1]); - x5[0] = _mm_add_epi64(s5[0], s7[0]); - x5[1] = _mm_add_epi64(s5[1], s7[1]); - x6[0] = _mm_sub_epi64(s4[0], s6[0]); - x6[1] = _mm_sub_epi64(s4[1], s6[1]); - x7[0] = _mm_sub_epi64(s5[0], s7[0]); - x7[1] = _mm_sub_epi64(s5[1], s7[1]); - x4[0] = dct_const_round_shift_64bit(x4[0]); - x4[1] = dct_const_round_shift_64bit(x4[1]); - x5[0] = dct_const_round_shift_64bit(x5[0]); - x5[1] = dct_const_round_shift_64bit(x5[1]); - x6[0] = dct_const_round_shift_64bit(x6[0]); - x6[1] = dct_const_round_shift_64bit(x6[1]); - x7[0] = dct_const_round_shift_64bit(x7[0]); - x7[1] = dct_const_round_shift_64bit(x7[1]); - x4[0] = pack_4(x4[0], x4[1]); - x5[0] = pack_4(x5[0], x5[1]); - x6[0] = pack_4(x6[0], x6[1]); - x7[0] = pack_4(x7[0], x7[1]); - - // stage 3 - s2[0] = _mm_add_epi32(x2[0], x3[0]); - s3[0] = _mm_sub_epi32(x2[0], x3[0]); - s6[0] = _mm_add_epi32(x6[0], x7[0]); - s7[0] = _mm_sub_epi32(x6[0], x7[0]); - highbd_iadst_half_butterfly_sse4_1(s2[0], cospi_16_64, s2); - highbd_iadst_half_butterfly_sse4_1(s3[0], cospi_16_64, s3); - highbd_iadst_half_butterfly_sse4_1(s6[0], cospi_16_64, s6); - highbd_iadst_half_butterfly_sse4_1(s7[0], cospi_16_64, s7); - - x2[0] = dct_const_round_shift_64bit(s2[0]); - x2[1] = dct_const_round_shift_64bit(s2[1]); - x3[0] = dct_const_round_shift_64bit(s3[0]); - x3[1] = dct_const_round_shift_64bit(s3[1]); - x6[0] = dct_const_round_shift_64bit(s6[0]); - x6[1] = dct_const_round_shift_64bit(s6[1]); - x7[0] = dct_const_round_shift_64bit(s7[0]); - x7[1] = dct_const_round_shift_64bit(s7[1]); - x2[0] = pack_4(x2[0], x2[1]); - x3[0] = pack_4(x3[0], x3[1]); - x6[0] = pack_4(x6[0], x6[1]); - x7[0] = pack_4(x7[0], x7[1]); - - io[0] = x0[0]; - io[1] = _mm_sub_epi32(_mm_setzero_si128(), x4[0]); - io[2] = x6[0]; - io[3] = _mm_sub_epi32(_mm_setzero_si128(), x2[0]); - io[4] = x3[0]; - io[5] = _mm_sub_epi32(_mm_setzero_si128(), x7[0]); - io[6] = x5[0]; - io[7] = _mm_sub_epi32(_mm_setzero_si128(), x1[0]); -} - -void vp9_highbd_iht8x8_64_add_sse4_1(const tran_low_t *input, uint16_t *dest, - int stride, int tx_type, int bd) { - __m128i io[16]; - - io[0] = _mm_load_si128((const __m128i *)(input + 0 * 8 + 0)); - io[4] = _mm_load_si128((const __m128i *)(input + 0 * 8 + 4)); - io[1] = _mm_load_si128((const __m128i *)(input + 1 * 8 + 0)); - io[5] = _mm_load_si128((const __m128i *)(input + 1 * 8 + 4)); - io[2] = _mm_load_si128((const __m128i *)(input + 2 * 8 + 0)); - io[6] = _mm_load_si128((const __m128i *)(input + 2 * 8 + 4)); - io[3] = _mm_load_si128((const __m128i *)(input + 3 * 8 + 0)); - io[7] = _mm_load_si128((const __m128i *)(input + 3 * 8 + 4)); - io[8] = _mm_load_si128((const __m128i *)(input + 4 * 8 + 0)); - io[12] = _mm_load_si128((const __m128i *)(input + 4 * 8 + 4)); - io[9] = _mm_load_si128((const __m128i *)(input + 5 * 8 + 0)); - io[13] = _mm_load_si128((const __m128i *)(input + 5 * 8 + 4)); - io[10] = _mm_load_si128((const __m128i *)(input + 6 * 8 + 0)); - io[14] = _mm_load_si128((const __m128i *)(input + 6 * 8 + 4)); - io[11] = _mm_load_si128((const __m128i *)(input + 7 * 8 + 0)); - io[15] = _mm_load_si128((const __m128i *)(input + 7 * 8 + 4)); - - if (bd == 8) { - __m128i io_short[8]; - - io_short[0] = _mm_packs_epi32(io[0], io[4]); - io_short[1] = _mm_packs_epi32(io[1], io[5]); - io_short[2] = _mm_packs_epi32(io[2], io[6]); - io_short[3] = _mm_packs_epi32(io[3], io[7]); - io_short[4] = _mm_packs_epi32(io[8], io[12]); - io_short[5] = _mm_packs_epi32(io[9], io[13]); - io_short[6] = _mm_packs_epi32(io[10], io[14]); - io_short[7] = _mm_packs_epi32(io[11], io[15]); - - if (tx_type == DCT_DCT || tx_type == ADST_DCT) { - vpx_idct8_sse2(io_short); - } else { - iadst8_sse2(io_short); - } - if (tx_type == DCT_DCT || tx_type == DCT_ADST) { - vpx_idct8_sse2(io_short); - } else { - iadst8_sse2(io_short); - } - round_shift_8x8(io_short, io); - } else { - __m128i temp[4]; - - if (tx_type == DCT_DCT || tx_type == ADST_DCT) { - vpx_highbd_idct8x8_half1d_sse4_1(io); - vpx_highbd_idct8x8_half1d_sse4_1(&io[8]); - } else { - highbd_iadst8_sse4_1(io); - highbd_iadst8_sse4_1(&io[8]); - } - - temp[0] = io[4]; - temp[1] = io[5]; - temp[2] = io[6]; - temp[3] = io[7]; - io[4] = io[8]; - io[5] = io[9]; - io[6] = io[10]; - io[7] = io[11]; - - if (tx_type == DCT_DCT || tx_type == DCT_ADST) { - vpx_highbd_idct8x8_half1d_sse4_1(io); - io[8] = temp[0]; - io[9] = temp[1]; - io[10] = temp[2]; - io[11] = temp[3]; - vpx_highbd_idct8x8_half1d_sse4_1(&io[8]); - } else { - highbd_iadst8_sse4_1(io); - io[8] = temp[0]; - io[9] = temp[1]; - io[10] = temp[2]; - io[11] = temp[3]; - highbd_iadst8_sse4_1(&io[8]); - } - highbd_idct8x8_final_round(io); - } - recon_and_store_8x8(io, dest, stride, bd); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/x86/vp9_idct_intrin_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vp9/common/x86/vp9_idct_intrin_sse2.c deleted file mode 100644 index ad693718..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/x86/vp9_idct_intrin_sse2.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp9_rtcd.h" -#include "vpx_dsp/x86/inv_txfm_sse2.h" - -void vp9_iht4x4_16_add_sse2(const tran_low_t *input, uint8_t *dest, int stride, - int tx_type) { - __m128i in[2]; - const __m128i eight = _mm_set1_epi16(8); - - in[0] = load_input_data8(input); - in[1] = load_input_data8(input + 8); - - switch (tx_type) { - case DCT_DCT: - idct4_sse2(in); - idct4_sse2(in); - break; - case ADST_DCT: - idct4_sse2(in); - iadst4_sse2(in); - break; - case DCT_ADST: - iadst4_sse2(in); - idct4_sse2(in); - break; - default: - assert(tx_type == ADST_ADST); - iadst4_sse2(in); - iadst4_sse2(in); - break; - } - - // Final round and shift - in[0] = _mm_add_epi16(in[0], eight); - in[1] = _mm_add_epi16(in[1], eight); - - in[0] = _mm_srai_epi16(in[0], 4); - in[1] = _mm_srai_epi16(in[1], 4); - - recon_and_store4x4_sse2(in, dest, stride); -} - -void vp9_iht8x8_64_add_sse2(const tran_low_t *input, uint8_t *dest, int stride, - int tx_type) { - __m128i in[8]; - const __m128i final_rounding = _mm_set1_epi16(1 << 4); - - // load input data - in[0] = load_input_data8(input); - in[1] = load_input_data8(input + 8 * 1); - in[2] = load_input_data8(input + 8 * 2); - in[3] = load_input_data8(input + 8 * 3); - in[4] = load_input_data8(input + 8 * 4); - in[5] = load_input_data8(input + 8 * 5); - in[6] = load_input_data8(input + 8 * 6); - in[7] = load_input_data8(input + 8 * 7); - - switch (tx_type) { - case DCT_DCT: - vpx_idct8_sse2(in); - vpx_idct8_sse2(in); - break; - case ADST_DCT: - vpx_idct8_sse2(in); - iadst8_sse2(in); - break; - case DCT_ADST: - iadst8_sse2(in); - vpx_idct8_sse2(in); - break; - default: - assert(tx_type == ADST_ADST); - iadst8_sse2(in); - iadst8_sse2(in); - break; - } - - // Final rounding and shift - in[0] = _mm_adds_epi16(in[0], final_rounding); - in[1] = _mm_adds_epi16(in[1], final_rounding); - in[2] = _mm_adds_epi16(in[2], final_rounding); - in[3] = _mm_adds_epi16(in[3], final_rounding); - in[4] = _mm_adds_epi16(in[4], final_rounding); - in[5] = _mm_adds_epi16(in[5], final_rounding); - in[6] = _mm_adds_epi16(in[6], final_rounding); - in[7] = _mm_adds_epi16(in[7], final_rounding); - - in[0] = _mm_srai_epi16(in[0], 5); - in[1] = _mm_srai_epi16(in[1], 5); - in[2] = _mm_srai_epi16(in[2], 5); - in[3] = _mm_srai_epi16(in[3], 5); - in[4] = _mm_srai_epi16(in[4], 5); - in[5] = _mm_srai_epi16(in[5], 5); - in[6] = _mm_srai_epi16(in[6], 5); - in[7] = _mm_srai_epi16(in[7], 5); - - recon_and_store(dest + 0 * stride, in[0]); - recon_and_store(dest + 1 * stride, in[1]); - recon_and_store(dest + 2 * stride, in[2]); - recon_and_store(dest + 3 * stride, in[3]); - recon_and_store(dest + 4 * stride, in[4]); - recon_and_store(dest + 5 * stride, in[5]); - recon_and_store(dest + 6 * stride, in[6]); - recon_and_store(dest + 7 * stride, in[7]); -} - -static INLINE void load_buffer_8x16(const tran_low_t *const input, - __m128i *const in) { - in[0] = load_input_data8(input + 0 * 16); - in[1] = load_input_data8(input + 1 * 16); - in[2] = load_input_data8(input + 2 * 16); - in[3] = load_input_data8(input + 3 * 16); - in[4] = load_input_data8(input + 4 * 16); - in[5] = load_input_data8(input + 5 * 16); - in[6] = load_input_data8(input + 6 * 16); - in[7] = load_input_data8(input + 7 * 16); - - in[8] = load_input_data8(input + 8 * 16); - in[9] = load_input_data8(input + 9 * 16); - in[10] = load_input_data8(input + 10 * 16); - in[11] = load_input_data8(input + 11 * 16); - in[12] = load_input_data8(input + 12 * 16); - in[13] = load_input_data8(input + 13 * 16); - in[14] = load_input_data8(input + 14 * 16); - in[15] = load_input_data8(input + 15 * 16); -} - -static INLINE void write_buffer_8x16(uint8_t *const dest, __m128i *const in, - const int stride) { - const __m128i final_rounding = _mm_set1_epi16(1 << 5); - // Final rounding and shift - in[0] = _mm_adds_epi16(in[0], final_rounding); - in[1] = _mm_adds_epi16(in[1], final_rounding); - in[2] = _mm_adds_epi16(in[2], final_rounding); - in[3] = _mm_adds_epi16(in[3], final_rounding); - in[4] = _mm_adds_epi16(in[4], final_rounding); - in[5] = _mm_adds_epi16(in[5], final_rounding); - in[6] = _mm_adds_epi16(in[6], final_rounding); - in[7] = _mm_adds_epi16(in[7], final_rounding); - in[8] = _mm_adds_epi16(in[8], final_rounding); - in[9] = _mm_adds_epi16(in[9], final_rounding); - in[10] = _mm_adds_epi16(in[10], final_rounding); - in[11] = _mm_adds_epi16(in[11], final_rounding); - in[12] = _mm_adds_epi16(in[12], final_rounding); - in[13] = _mm_adds_epi16(in[13], final_rounding); - in[14] = _mm_adds_epi16(in[14], final_rounding); - in[15] = _mm_adds_epi16(in[15], final_rounding); - - in[0] = _mm_srai_epi16(in[0], 6); - in[1] = _mm_srai_epi16(in[1], 6); - in[2] = _mm_srai_epi16(in[2], 6); - in[3] = _mm_srai_epi16(in[3], 6); - in[4] = _mm_srai_epi16(in[4], 6); - in[5] = _mm_srai_epi16(in[5], 6); - in[6] = _mm_srai_epi16(in[6], 6); - in[7] = _mm_srai_epi16(in[7], 6); - in[8] = _mm_srai_epi16(in[8], 6); - in[9] = _mm_srai_epi16(in[9], 6); - in[10] = _mm_srai_epi16(in[10], 6); - in[11] = _mm_srai_epi16(in[11], 6); - in[12] = _mm_srai_epi16(in[12], 6); - in[13] = _mm_srai_epi16(in[13], 6); - in[14] = _mm_srai_epi16(in[14], 6); - in[15] = _mm_srai_epi16(in[15], 6); - - recon_and_store(dest + 0 * stride, in[0]); - recon_and_store(dest + 1 * stride, in[1]); - recon_and_store(dest + 2 * stride, in[2]); - recon_and_store(dest + 3 * stride, in[3]); - recon_and_store(dest + 4 * stride, in[4]); - recon_and_store(dest + 5 * stride, in[5]); - recon_and_store(dest + 6 * stride, in[6]); - recon_and_store(dest + 7 * stride, in[7]); - recon_and_store(dest + 8 * stride, in[8]); - recon_and_store(dest + 9 * stride, in[9]); - recon_and_store(dest + 10 * stride, in[10]); - recon_and_store(dest + 11 * stride, in[11]); - recon_and_store(dest + 12 * stride, in[12]); - recon_and_store(dest + 13 * stride, in[13]); - recon_and_store(dest + 14 * stride, in[14]); - recon_and_store(dest + 15 * stride, in[15]); -} - -void vp9_iht16x16_256_add_sse2(const tran_low_t *input, uint8_t *dest, - int stride, int tx_type) { - __m128i in0[16], in1[16]; - - load_buffer_8x16(input, in0); - input += 8; - load_buffer_8x16(input, in1); - - switch (tx_type) { - case DCT_DCT: - idct16_sse2(in0, in1); - idct16_sse2(in0, in1); - break; - case ADST_DCT: - idct16_sse2(in0, in1); - iadst16_sse2(in0, in1); - break; - case DCT_ADST: - iadst16_sse2(in0, in1); - idct16_sse2(in0, in1); - break; - default: - assert(tx_type == ADST_ADST); - iadst16_sse2(in0, in1); - iadst16_sse2(in0, in1); - break; - } - - write_buffer_8x16(dest, in0, stride); - dest += 8; - write_buffer_8x16(dest, in1, stride); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/common/x86/vp9_mfqe_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vp9/common/x86/vp9_mfqe_sse2.asm deleted file mode 100644 index ae7c94ea..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/common/x86/vp9_mfqe_sse2.asm +++ /dev/null @@ -1,289 +0,0 @@ -; -; Copyright (c) 2015 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -; This file is a duplicate of mfqe_sse2.asm in VP8. -; TODO(jackychen): Find a way to fix the duplicate. -%include "vpx_ports/x86_abi_support.asm" - -SECTION .text - -;void vp9_filter_by_weight16x16_sse2 -;( -; unsigned char *src, -; int src_stride, -; unsigned char *dst, -; int dst_stride, -; int src_weight -;) -globalsym(vp9_filter_by_weight16x16_sse2) -sym(vp9_filter_by_weight16x16_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 5 - SAVE_XMM 6 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - movd xmm0, arg(4) ; src_weight - pshuflw xmm0, xmm0, 0x0 ; replicate to all low words - punpcklqdq xmm0, xmm0 ; replicate to all hi words - - movdqa xmm1, [GLOBAL(tMFQE)] - psubw xmm1, xmm0 ; dst_weight - - mov rax, arg(0) ; src - mov rsi, arg(1) ; src_stride - mov rdx, arg(2) ; dst - mov rdi, arg(3) ; dst_stride - - mov rcx, 16 ; loop count - pxor xmm6, xmm6 - -.combine: - movdqa xmm2, [rax] - movdqa xmm4, [rdx] - add rax, rsi - - ; src * src_weight - movdqa xmm3, xmm2 - punpcklbw xmm2, xmm6 - punpckhbw xmm3, xmm6 - pmullw xmm2, xmm0 - pmullw xmm3, xmm0 - - ; dst * dst_weight - movdqa xmm5, xmm4 - punpcklbw xmm4, xmm6 - punpckhbw xmm5, xmm6 - pmullw xmm4, xmm1 - pmullw xmm5, xmm1 - - ; sum, round and shift - paddw xmm2, xmm4 - paddw xmm3, xmm5 - paddw xmm2, [GLOBAL(tMFQE_round)] - paddw xmm3, [GLOBAL(tMFQE_round)] - psrlw xmm2, 4 - psrlw xmm3, 4 - - packuswb xmm2, xmm3 - movdqa [rdx], xmm2 - add rdx, rdi - - dec rcx - jnz .combine - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - - ret - -;void vp9_filter_by_weight8x8_sse2 -;( -; unsigned char *src, -; int src_stride, -; unsigned char *dst, -; int dst_stride, -; int src_weight -;) -globalsym(vp9_filter_by_weight8x8_sse2) -sym(vp9_filter_by_weight8x8_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 5 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - movd xmm0, arg(4) ; src_weight - pshuflw xmm0, xmm0, 0x0 ; replicate to all low words - punpcklqdq xmm0, xmm0 ; replicate to all hi words - - movdqa xmm1, [GLOBAL(tMFQE)] - psubw xmm1, xmm0 ; dst_weight - - mov rax, arg(0) ; src - mov rsi, arg(1) ; src_stride - mov rdx, arg(2) ; dst - mov rdi, arg(3) ; dst_stride - - mov rcx, 8 ; loop count - pxor xmm4, xmm4 - -.combine: - movq xmm2, [rax] - movq xmm3, [rdx] - add rax, rsi - - ; src * src_weight - punpcklbw xmm2, xmm4 - pmullw xmm2, xmm0 - - ; dst * dst_weight - punpcklbw xmm3, xmm4 - pmullw xmm3, xmm1 - - ; sum, round and shift - paddw xmm2, xmm3 - paddw xmm2, [GLOBAL(tMFQE_round)] - psrlw xmm2, 4 - - packuswb xmm2, xmm4 - movq [rdx], xmm2 - add rdx, rdi - - dec rcx - jnz .combine - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - UNSHADOW_ARGS - pop rbp - - ret - -;void vp9_variance_and_sad_16x16_sse2 | arg -;( -; unsigned char *src1, 0 -; int stride1, 1 -; unsigned char *src2, 2 -; int stride2, 3 -; unsigned int *variance, 4 -; unsigned int *sad, 5 -;) -globalsym(vp9_variance_and_sad_16x16_sse2) -sym(vp9_variance_and_sad_16x16_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - mov rax, arg(0) ; src1 - mov rcx, arg(1) ; stride1 - mov rdx, arg(2) ; src2 - mov rdi, arg(3) ; stride2 - - mov rsi, 16 ; block height - - ; Prep accumulator registers - pxor xmm3, xmm3 ; SAD - pxor xmm4, xmm4 ; sum of src2 - pxor xmm5, xmm5 ; sum of src2^2 - - ; Because we're working with the actual output frames - ; we can't depend on any kind of data alignment. -.accumulate: - movdqa xmm0, [rax] ; src1 - movdqa xmm1, [rdx] ; src2 - add rax, rcx ; src1 + stride1 - add rdx, rdi ; src2 + stride2 - - ; SAD(src1, src2) - psadbw xmm0, xmm1 - paddusw xmm3, xmm0 - - ; SUM(src2) - pxor xmm2, xmm2 - psadbw xmm2, xmm1 ; sum src2 by misusing SAD against 0 - paddusw xmm4, xmm2 - - ; pmaddubsw would be ideal if it took two unsigned values. instead, - ; it expects a signed and an unsigned value. so instead we zero extend - ; and operate on words. - pxor xmm2, xmm2 - movdqa xmm0, xmm1 - punpcklbw xmm0, xmm2 - punpckhbw xmm1, xmm2 - pmaddwd xmm0, xmm0 - pmaddwd xmm1, xmm1 - paddd xmm5, xmm0 - paddd xmm5, xmm1 - - sub rsi, 1 - jnz .accumulate - - ; phaddd only operates on adjacent double words. - ; Finalize SAD and store - movdqa xmm0, xmm3 - psrldq xmm0, 8 - paddusw xmm0, xmm3 - paddd xmm0, [GLOBAL(t128)] - psrld xmm0, 8 - - mov rax, arg(5) - movd [rax], xmm0 - - ; Accumulate sum of src2 - movdqa xmm0, xmm4 - psrldq xmm0, 8 - paddusw xmm0, xmm4 - ; Square src2. Ignore high value - pmuludq xmm0, xmm0 - psrld xmm0, 8 - - ; phaddw could be used to sum adjacent values but we want - ; all the values summed. promote to doubles, accumulate, - ; shift and sum - pxor xmm2, xmm2 - movdqa xmm1, xmm5 - punpckldq xmm1, xmm2 - punpckhdq xmm5, xmm2 - paddd xmm1, xmm5 - movdqa xmm2, xmm1 - psrldq xmm1, 8 - paddd xmm1, xmm2 - - psubd xmm1, xmm0 - - ; (variance + 128) >> 8 - paddd xmm1, [GLOBAL(t128)] - psrld xmm1, 8 - mov rax, arg(4) - - movd [rax], xmm1 - - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - UNSHADOW_ARGS - pop rbp - ret - -SECTION_RODATA -align 16 -t128: -%ifndef __NASM_VER__ - ddq 128 -%elif CONFIG_BIG_ENDIAN - dq 0, 128 -%else - dq 128, 0 -%endif -align 16 -tMFQE: ; 1 << MFQE_PRECISION - times 8 dw 0x10 -align 16 -tMFQE_round: ; 1 << (MFQE_PRECISION - 1) - times 8 dw 0x08 diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decodeframe.c b/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decodeframe.c deleted file mode 100644 index 45ef99ad..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decodeframe.c +++ /dev/null @@ -1,3066 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include // qsort() - -#include "./vp9_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "./vpx_scale_rtcd.h" - -#include "vpx_dsp/bitreader_buffer.h" -#include "vpx_dsp/bitreader.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/mem_ops.h" -#include "vpx_scale/vpx_scale.h" -#include "vpx_util/vpx_pthread.h" -#include "vpx_util/vpx_thread.h" -#if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG -#include "vpx_util/vpx_debug_util.h" -#endif // CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG - -#include "vp9/common/vp9_alloccommon.h" -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_entropy.h" -#include "vp9/common/vp9_entropymode.h" -#include "vp9/common/vp9_idct.h" -#include "vp9/common/vp9_thread_common.h" -#include "vp9/common/vp9_pred_common.h" -#include "vp9/common/vp9_quant_common.h" -#include "vp9/common/vp9_reconintra.h" -#include "vp9/common/vp9_reconinter.h" -#include "vp9/common/vp9_seg_common.h" -#include "vp9/common/vp9_tile_common.h" - -#include "vp9/decoder/vp9_decodeframe.h" -#include "vp9/decoder/vp9_detokenize.h" -#include "vp9/decoder/vp9_decodemv.h" -#include "vp9/decoder/vp9_decoder.h" -#include "vp9/decoder/vp9_dsubexp.h" -#include "vp9/decoder/vp9_job_queue.h" - -#define MAX_VP9_HEADER_SIZE 80 - -typedef int (*predict_recon_func)(TileWorkerData *twd, MODE_INFO *const mi, - int plane, int row, int col, TX_SIZE tx_size); - -typedef void (*intra_recon_func)(TileWorkerData *twd, MODE_INFO *const mi, - int plane, int row, int col, TX_SIZE tx_size); - -static int read_is_valid(const uint8_t *start, size_t len, const uint8_t *end) { - return len != 0 && len <= (size_t)(end - start); -} - -static int decode_unsigned_max(struct vpx_read_bit_buffer *rb, int max) { - const int data = vpx_rb_read_literal(rb, get_unsigned_bits(max)); - return data > max ? max : data; -} - -static TX_MODE read_tx_mode(vpx_reader *r) { - TX_MODE tx_mode = vpx_read_literal(r, 2); - if (tx_mode == ALLOW_32X32) tx_mode += vpx_read_bit(r); - assert(tx_mode < TX_MODES); - return tx_mode; -} - -static void read_tx_mode_probs(struct tx_probs *tx_probs, vpx_reader *r) { - int i, j; - - for (i = 0; i < TX_SIZE_CONTEXTS; ++i) - for (j = 0; j < TX_SIZES - 3; ++j) - vp9_diff_update_prob(r, &tx_probs->p8x8[i][j]); - - for (i = 0; i < TX_SIZE_CONTEXTS; ++i) - for (j = 0; j < TX_SIZES - 2; ++j) - vp9_diff_update_prob(r, &tx_probs->p16x16[i][j]); - - for (i = 0; i < TX_SIZE_CONTEXTS; ++i) - for (j = 0; j < TX_SIZES - 1; ++j) - vp9_diff_update_prob(r, &tx_probs->p32x32[i][j]); -} - -static void read_switchable_interp_probs(FRAME_CONTEXT *fc, vpx_reader *r) { - int i, j; - for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) - for (i = 0; i < SWITCHABLE_FILTERS - 1; ++i) - vp9_diff_update_prob(r, &fc->switchable_interp_prob[j][i]); -} - -static void read_inter_mode_probs(FRAME_CONTEXT *fc, vpx_reader *r) { - int i, j; - for (i = 0; i < INTER_MODE_CONTEXTS; ++i) - for (j = 0; j < INTER_MODES - 1; ++j) - vp9_diff_update_prob(r, &fc->inter_mode_probs[i][j]); -} - -static REFERENCE_MODE read_frame_reference_mode(const VP9_COMMON *cm, - vpx_reader *r) { - if (vp9_compound_reference_allowed(cm)) { - return vpx_read_bit(r) - ? (vpx_read_bit(r) ? REFERENCE_MODE_SELECT : COMPOUND_REFERENCE) - : SINGLE_REFERENCE; - } else { - return SINGLE_REFERENCE; - } -} - -static void read_frame_reference_mode_probs(VP9_COMMON *cm, vpx_reader *r) { - FRAME_CONTEXT *const fc = cm->fc; - int i; - - if (cm->reference_mode == REFERENCE_MODE_SELECT) - for (i = 0; i < COMP_INTER_CONTEXTS; ++i) - vp9_diff_update_prob(r, &fc->comp_inter_prob[i]); - - if (cm->reference_mode != COMPOUND_REFERENCE) - for (i = 0; i < REF_CONTEXTS; ++i) { - vp9_diff_update_prob(r, &fc->single_ref_prob[i][0]); - vp9_diff_update_prob(r, &fc->single_ref_prob[i][1]); - } - - if (cm->reference_mode != SINGLE_REFERENCE) - for (i = 0; i < REF_CONTEXTS; ++i) - vp9_diff_update_prob(r, &fc->comp_ref_prob[i]); -} - -static void update_mv_probs(vpx_prob *p, int n, vpx_reader *r) { - int i; - for (i = 0; i < n; ++i) - if (vpx_read(r, MV_UPDATE_PROB)) p[i] = (vpx_read_literal(r, 7) << 1) | 1; -} - -static void read_mv_probs(nmv_context *ctx, int allow_hp, vpx_reader *r) { - int i, j; - - update_mv_probs(ctx->joints, MV_JOINTS - 1, r); - - for (i = 0; i < 2; ++i) { - nmv_component *const comp_ctx = &ctx->comps[i]; - update_mv_probs(&comp_ctx->sign, 1, r); - update_mv_probs(comp_ctx->classes, MV_CLASSES - 1, r); - update_mv_probs(comp_ctx->class0, CLASS0_SIZE - 1, r); - update_mv_probs(comp_ctx->bits, MV_OFFSET_BITS, r); - } - - for (i = 0; i < 2; ++i) { - nmv_component *const comp_ctx = &ctx->comps[i]; - for (j = 0; j < CLASS0_SIZE; ++j) - update_mv_probs(comp_ctx->class0_fp[j], MV_FP_SIZE - 1, r); - update_mv_probs(comp_ctx->fp, 3, r); - } - - if (allow_hp) { - for (i = 0; i < 2; ++i) { - nmv_component *const comp_ctx = &ctx->comps[i]; - update_mv_probs(&comp_ctx->class0_hp, 1, r); - update_mv_probs(&comp_ctx->hp, 1, r); - } - } -} - -static void inverse_transform_block_inter(MACROBLOCKD *xd, int plane, - const TX_SIZE tx_size, uint8_t *dst, - int stride, int eob) { - struct macroblockd_plane *const pd = &xd->plane[plane]; - tran_low_t *const dqcoeff = pd->dqcoeff; - assert(eob > 0); -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - uint16_t *const dst16 = CONVERT_TO_SHORTPTR(dst); - if (xd->lossless) { - vp9_highbd_iwht4x4_add(dqcoeff, dst16, stride, eob, xd->bd); - } else { - switch (tx_size) { - case TX_4X4: - vp9_highbd_idct4x4_add(dqcoeff, dst16, stride, eob, xd->bd); - break; - case TX_8X8: - vp9_highbd_idct8x8_add(dqcoeff, dst16, stride, eob, xd->bd); - break; - case TX_16X16: - vp9_highbd_idct16x16_add(dqcoeff, dst16, stride, eob, xd->bd); - break; - case TX_32X32: - vp9_highbd_idct32x32_add(dqcoeff, dst16, stride, eob, xd->bd); - break; - default: assert(0 && "Invalid transform size"); - } - } - } else { - if (xd->lossless) { - vp9_iwht4x4_add(dqcoeff, dst, stride, eob); - } else { - switch (tx_size) { - case TX_4X4: vp9_idct4x4_add(dqcoeff, dst, stride, eob); break; - case TX_8X8: vp9_idct8x8_add(dqcoeff, dst, stride, eob); break; - case TX_16X16: vp9_idct16x16_add(dqcoeff, dst, stride, eob); break; - case TX_32X32: vp9_idct32x32_add(dqcoeff, dst, stride, eob); break; - default: assert(0 && "Invalid transform size"); return; - } - } - } -#else - if (xd->lossless) { - vp9_iwht4x4_add(dqcoeff, dst, stride, eob); - } else { - switch (tx_size) { - case TX_4X4: vp9_idct4x4_add(dqcoeff, dst, stride, eob); break; - case TX_8X8: vp9_idct8x8_add(dqcoeff, dst, stride, eob); break; - case TX_16X16: vp9_idct16x16_add(dqcoeff, dst, stride, eob); break; - case TX_32X32: vp9_idct32x32_add(dqcoeff, dst, stride, eob); break; - default: assert(0 && "Invalid transform size"); return; - } - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - if (eob == 1) { - dqcoeff[0] = 0; - } else { - if (tx_size <= TX_16X16 && eob <= 10) - memset(dqcoeff, 0, 4 * (4 << tx_size) * sizeof(dqcoeff[0])); - else if (tx_size == TX_32X32 && eob <= 34) - memset(dqcoeff, 0, 256 * sizeof(dqcoeff[0])); - else - memset(dqcoeff, 0, (16 << (tx_size << 1)) * sizeof(dqcoeff[0])); - } -} - -static void inverse_transform_block_intra(MACROBLOCKD *xd, int plane, - const TX_TYPE tx_type, - const TX_SIZE tx_size, uint8_t *dst, - int stride, int eob) { - struct macroblockd_plane *const pd = &xd->plane[plane]; - tran_low_t *const dqcoeff = pd->dqcoeff; - assert(eob > 0); -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - uint16_t *const dst16 = CONVERT_TO_SHORTPTR(dst); - if (xd->lossless) { - vp9_highbd_iwht4x4_add(dqcoeff, dst16, stride, eob, xd->bd); - } else { - switch (tx_size) { - case TX_4X4: - vp9_highbd_iht4x4_add(tx_type, dqcoeff, dst16, stride, eob, xd->bd); - break; - case TX_8X8: - vp9_highbd_iht8x8_add(tx_type, dqcoeff, dst16, stride, eob, xd->bd); - break; - case TX_16X16: - vp9_highbd_iht16x16_add(tx_type, dqcoeff, dst16, stride, eob, xd->bd); - break; - case TX_32X32: - vp9_highbd_idct32x32_add(dqcoeff, dst16, stride, eob, xd->bd); - break; - default: assert(0 && "Invalid transform size"); - } - } - } else { - if (xd->lossless) { - vp9_iwht4x4_add(dqcoeff, dst, stride, eob); - } else { - switch (tx_size) { - case TX_4X4: vp9_iht4x4_add(tx_type, dqcoeff, dst, stride, eob); break; - case TX_8X8: vp9_iht8x8_add(tx_type, dqcoeff, dst, stride, eob); break; - case TX_16X16: - vp9_iht16x16_add(tx_type, dqcoeff, dst, stride, eob); - break; - case TX_32X32: vp9_idct32x32_add(dqcoeff, dst, stride, eob); break; - default: assert(0 && "Invalid transform size"); return; - } - } - } -#else - if (xd->lossless) { - vp9_iwht4x4_add(dqcoeff, dst, stride, eob); - } else { - switch (tx_size) { - case TX_4X4: vp9_iht4x4_add(tx_type, dqcoeff, dst, stride, eob); break; - case TX_8X8: vp9_iht8x8_add(tx_type, dqcoeff, dst, stride, eob); break; - case TX_16X16: - vp9_iht16x16_add(tx_type, dqcoeff, dst, stride, eob); - break; - case TX_32X32: vp9_idct32x32_add(dqcoeff, dst, stride, eob); break; - default: assert(0 && "Invalid transform size"); return; - } - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - if (eob == 1) { - dqcoeff[0] = 0; - } else { - if (tx_type == DCT_DCT && tx_size <= TX_16X16 && eob <= 10) - memset(dqcoeff, 0, 4 * (4 << tx_size) * sizeof(dqcoeff[0])); - else if (tx_size == TX_32X32 && eob <= 34) - memset(dqcoeff, 0, 256 * sizeof(dqcoeff[0])); - else - memset(dqcoeff, 0, (16 << (tx_size << 1)) * sizeof(dqcoeff[0])); - } -} - -static void predict_and_reconstruct_intra_block(TileWorkerData *twd, - MODE_INFO *const mi, int plane, - int row, int col, - TX_SIZE tx_size) { - MACROBLOCKD *const xd = &twd->xd; - struct macroblockd_plane *const pd = &xd->plane[plane]; - PREDICTION_MODE mode = (plane == 0) ? mi->mode : mi->uv_mode; - uint8_t *dst; - dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col]; - - if (mi->sb_type < BLOCK_8X8) - if (plane == 0) mode = xd->mi[0]->bmi[(row << 1) + col].as_mode; - - vp9_predict_intra_block(xd, pd->n4_wl, tx_size, mode, dst, pd->dst.stride, - dst, pd->dst.stride, col, row, plane); - - if (!mi->skip) { - const TX_TYPE tx_type = - (plane || xd->lossless) ? DCT_DCT : intra_mode_to_tx_type_lookup[mode]; - const ScanOrder *sc = (plane || xd->lossless) - ? &vp9_default_scan_orders[tx_size] - : &vp9_scan_orders[tx_size][tx_type]; - const int eob = vp9_decode_block_tokens(twd, plane, sc, col, row, tx_size, - mi->segment_id); - if (eob > 0) { - inverse_transform_block_intra(xd, plane, tx_type, tx_size, dst, - pd->dst.stride, eob); - } - } -} - -static void parse_intra_block_row_mt(TileWorkerData *twd, MODE_INFO *const mi, - int plane, int row, int col, - TX_SIZE tx_size) { - MACROBLOCKD *const xd = &twd->xd; - PREDICTION_MODE mode = (plane == 0) ? mi->mode : mi->uv_mode; - - if (mi->sb_type < BLOCK_8X8) - if (plane == 0) mode = xd->mi[0]->bmi[(row << 1) + col].as_mode; - - if (!mi->skip) { - struct macroblockd_plane *const pd = &xd->plane[plane]; - const TX_TYPE tx_type = - (plane || xd->lossless) ? DCT_DCT : intra_mode_to_tx_type_lookup[mode]; - const ScanOrder *sc = (plane || xd->lossless) - ? &vp9_default_scan_orders[tx_size] - : &vp9_scan_orders[tx_size][tx_type]; - *pd->eob = vp9_decode_block_tokens(twd, plane, sc, col, row, tx_size, - mi->segment_id); - /* Keep the alignment to 16 */ - pd->dqcoeff += (16 << (tx_size << 1)); - pd->eob++; - } -} - -static void predict_and_reconstruct_intra_block_row_mt(TileWorkerData *twd, - MODE_INFO *const mi, - int plane, int row, - int col, - TX_SIZE tx_size) { - MACROBLOCKD *const xd = &twd->xd; - struct macroblockd_plane *const pd = &xd->plane[plane]; - PREDICTION_MODE mode = (plane == 0) ? mi->mode : mi->uv_mode; - uint8_t *dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col]; - - if (mi->sb_type < BLOCK_8X8) - if (plane == 0) mode = xd->mi[0]->bmi[(row << 1) + col].as_mode; - - vp9_predict_intra_block(xd, pd->n4_wl, tx_size, mode, dst, pd->dst.stride, - dst, pd->dst.stride, col, row, plane); - - if (!mi->skip) { - const TX_TYPE tx_type = - (plane || xd->lossless) ? DCT_DCT : intra_mode_to_tx_type_lookup[mode]; - if (*pd->eob > 0) { - inverse_transform_block_intra(xd, plane, tx_type, tx_size, dst, - pd->dst.stride, *pd->eob); - } - /* Keep the alignment to 16 */ - pd->dqcoeff += (16 << (tx_size << 1)); - pd->eob++; - } -} - -static int reconstruct_inter_block(TileWorkerData *twd, MODE_INFO *const mi, - int plane, int row, int col, TX_SIZE tx_size, - int mi_row, int mi_col) { - MACROBLOCKD *const xd = &twd->xd; - struct macroblockd_plane *const pd = &xd->plane[plane]; - const ScanOrder *sc = &vp9_default_scan_orders[tx_size]; - const int eob = vp9_decode_block_tokens(twd, plane, sc, col, row, tx_size, - mi->segment_id); - uint8_t *dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col]; - - if (eob > 0) { - inverse_transform_block_inter(xd, plane, tx_size, dst, pd->dst.stride, eob); - } -#if CONFIG_MISMATCH_DEBUG - { - int pixel_c, pixel_r; - int blk_w = 1 << (tx_size + TX_UNIT_SIZE_LOG2); - int blk_h = 1 << (tx_size + TX_UNIT_SIZE_LOG2); - mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, col, row, - pd->subsampling_x, pd->subsampling_y); - mismatch_check_block_tx(dst, pd->dst.stride, plane, pixel_c, pixel_r, blk_w, - blk_h, xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH); - } -#else - (void)mi_row; - (void)mi_col; -#endif - return eob; -} - -static int parse_inter_block_row_mt(TileWorkerData *twd, MODE_INFO *const mi, - int plane, int row, int col, - TX_SIZE tx_size) { - MACROBLOCKD *const xd = &twd->xd; - struct macroblockd_plane *const pd = &xd->plane[plane]; - const ScanOrder *sc = &vp9_default_scan_orders[tx_size]; - const int eob = vp9_decode_block_tokens(twd, plane, sc, col, row, tx_size, - mi->segment_id); - - *pd->eob = eob; - pd->dqcoeff += (16 << (tx_size << 1)); - pd->eob++; - - return eob; -} - -static int reconstruct_inter_block_row_mt(TileWorkerData *twd, - MODE_INFO *const mi, int plane, - int row, int col, TX_SIZE tx_size) { - MACROBLOCKD *const xd = &twd->xd; - struct macroblockd_plane *const pd = &xd->plane[plane]; - const int eob = *pd->eob; - - (void)mi; - if (eob > 0) { - inverse_transform_block_inter( - xd, plane, tx_size, &pd->dst.buf[4 * row * pd->dst.stride + 4 * col], - pd->dst.stride, eob); - } - pd->dqcoeff += (16 << (tx_size << 1)); - pd->eob++; - - return eob; -} - -static void build_mc_border(const uint8_t *src, int src_stride, uint8_t *dst, - int dst_stride, int x, int y, int b_w, int b_h, - int w, int h) { - // Get a pointer to the start of the real data for this row. - const uint8_t *ref_row = src - x - y * src_stride; - - if (y >= h) - ref_row += (h - 1) * src_stride; - else if (y > 0) - ref_row += y * src_stride; - - do { - int right = 0, copy; - int left = x < 0 ? -x : 0; - - if (left > b_w) left = b_w; - - if (x + b_w > w) right = x + b_w - w; - - if (right > b_w) right = b_w; - - copy = b_w - left - right; - - if (left) memset(dst, ref_row[0], left); - - if (copy) memcpy(dst + left, ref_row + x + left, copy); - - if (right) memset(dst + left + copy, ref_row[w - 1], right); - - dst += dst_stride; - ++y; - - if (y > 0 && y < h) ref_row += src_stride; - } while (--b_h); -} - -#if CONFIG_VP9_HIGHBITDEPTH -static void high_build_mc_border(const uint8_t *src8, int src_stride, - uint16_t *dst, int dst_stride, int x, int y, - int b_w, int b_h, int w, int h) { - // Get a pointer to the start of the real data for this row. - const uint16_t *src = CONVERT_TO_SHORTPTR(src8); - const uint16_t *ref_row = src - x - y * src_stride; - - if (y >= h) - ref_row += (h - 1) * src_stride; - else if (y > 0) - ref_row += y * src_stride; - - do { - int right = 0, copy; - int left = x < 0 ? -x : 0; - - if (left > b_w) left = b_w; - - if (x + b_w > w) right = x + b_w - w; - - if (right > b_w) right = b_w; - - copy = b_w - left - right; - - if (left) vpx_memset16(dst, ref_row[0], left); - - if (copy) memcpy(dst + left, ref_row + x + left, copy * sizeof(uint16_t)); - - if (right) vpx_memset16(dst + left + copy, ref_row[w - 1], right); - - dst += dst_stride; - ++y; - - if (y > 0 && y < h) ref_row += src_stride; - } while (--b_h); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -#if CONFIG_VP9_HIGHBITDEPTH -static void extend_and_predict(TileWorkerData *twd, const uint8_t *buf_ptr1, - int pre_buf_stride, int x0, int y0, int b_w, - int b_h, int frame_width, int frame_height, - int border_offset, uint8_t *const dst, - int dst_buf_stride, int subpel_x, int subpel_y, - const InterpKernel *kernel, - const struct scale_factors *sf, MACROBLOCKD *xd, - int w, int h, int ref, int xs, int ys) { - uint16_t *mc_buf_high = twd->extend_and_predict_buf; - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - high_build_mc_border(buf_ptr1, pre_buf_stride, mc_buf_high, b_w, x0, y0, - b_w, b_h, frame_width, frame_height); - highbd_inter_predictor(mc_buf_high + border_offset, b_w, - CONVERT_TO_SHORTPTR(dst), dst_buf_stride, subpel_x, - subpel_y, sf, w, h, ref, kernel, xs, ys, xd->bd); - } else { - build_mc_border(buf_ptr1, pre_buf_stride, (uint8_t *)mc_buf_high, b_w, x0, - y0, b_w, b_h, frame_width, frame_height); - inter_predictor(((uint8_t *)mc_buf_high) + border_offset, b_w, dst, - dst_buf_stride, subpel_x, subpel_y, sf, w, h, ref, kernel, - xs, ys); - } -} -#else -static void extend_and_predict(TileWorkerData *twd, const uint8_t *buf_ptr1, - int pre_buf_stride, int x0, int y0, int b_w, - int b_h, int frame_width, int frame_height, - int border_offset, uint8_t *const dst, - int dst_buf_stride, int subpel_x, int subpel_y, - const InterpKernel *kernel, - const struct scale_factors *sf, int w, int h, - int ref, int xs, int ys) { - uint8_t *mc_buf = (uint8_t *)twd->extend_and_predict_buf; - const uint8_t *buf_ptr; - - build_mc_border(buf_ptr1, pre_buf_stride, mc_buf, b_w, x0, y0, b_w, b_h, - frame_width, frame_height); - buf_ptr = mc_buf + border_offset; - - inter_predictor(buf_ptr, b_w, dst, dst_buf_stride, subpel_x, subpel_y, sf, w, - h, ref, kernel, xs, ys); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static void dec_build_inter_predictors( - TileWorkerData *twd, MACROBLOCKD *xd, int plane, int bw, int bh, int x, - int y, int w, int h, int mi_x, int mi_y, const InterpKernel *kernel, - const struct scale_factors *sf, struct buf_2d *pre_buf, - struct buf_2d *dst_buf, const MV *mv, RefCntBuffer *ref_frame_buf, - int is_scaled, int ref) { - struct macroblockd_plane *const pd = &xd->plane[plane]; - uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x; - MV32 scaled_mv; - int xs, ys, x0, y0, x0_16, y0_16, frame_width, frame_height, buf_stride, - subpel_x, subpel_y; - uint8_t *ref_frame, *buf_ptr; - - // Get reference frame pointer, width and height. - if (plane == 0) { - frame_width = ref_frame_buf->buf.y_crop_width; - frame_height = ref_frame_buf->buf.y_crop_height; - ref_frame = ref_frame_buf->buf.y_buffer; - } else { - frame_width = ref_frame_buf->buf.uv_crop_width; - frame_height = ref_frame_buf->buf.uv_crop_height; - ref_frame = - plane == 1 ? ref_frame_buf->buf.u_buffer : ref_frame_buf->buf.v_buffer; - } - - if (is_scaled) { - const MV mv_q4 = clamp_mv_to_umv_border_sb( - xd, mv, bw, bh, pd->subsampling_x, pd->subsampling_y); - // Co-ordinate of containing block to pixel precision. - int x_start = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)); - int y_start = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)); -#if 0 // CONFIG_BETTER_HW_COMPATIBILITY - assert(xd->mi[0]->sb_type != BLOCK_4X8 && - xd->mi[0]->sb_type != BLOCK_8X4); - assert(mv_q4.row == mv->row * (1 << (1 - pd->subsampling_y)) && - mv_q4.col == mv->col * (1 << (1 - pd->subsampling_x))); -#endif - // Co-ordinate of the block to 1/16th pixel precision. - x0_16 = (x_start + x) << SUBPEL_BITS; - y0_16 = (y_start + y) << SUBPEL_BITS; - - // Co-ordinate of current block in reference frame - // to 1/16th pixel precision. - x0_16 = sf->scale_value_x(x0_16, sf); - y0_16 = sf->scale_value_y(y0_16, sf); - - // Map the top left corner of the block into the reference frame. - x0 = sf->scale_value_x(x_start + x, sf); - y0 = sf->scale_value_y(y_start + y, sf); - - // Scale the MV and incorporate the sub-pixel offset of the block - // in the reference frame. - scaled_mv = vp9_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf); - xs = sf->x_step_q4; - ys = sf->y_step_q4; - } else { - // Co-ordinate of containing block to pixel precision. - x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x; - y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y; - - // Co-ordinate of the block to 1/16th pixel precision. - x0_16 = x0 << SUBPEL_BITS; - y0_16 = y0 << SUBPEL_BITS; - - scaled_mv.row = mv->row * (1 << (1 - pd->subsampling_y)); - scaled_mv.col = mv->col * (1 << (1 - pd->subsampling_x)); - xs = ys = 16; - } - subpel_x = scaled_mv.col & SUBPEL_MASK; - subpel_y = scaled_mv.row & SUBPEL_MASK; - - // Calculate the top left corner of the best matching block in the - // reference frame. - x0 += scaled_mv.col >> SUBPEL_BITS; - y0 += scaled_mv.row >> SUBPEL_BITS; - x0_16 += scaled_mv.col; - y0_16 += scaled_mv.row; - - // Get reference block pointer. - buf_ptr = ref_frame + y0 * pre_buf->stride + x0; - buf_stride = pre_buf->stride; - - // Do border extension if there is motion or the - // width/height is not a multiple of 8 pixels. - if (is_scaled || scaled_mv.col || scaled_mv.row || (frame_width & 0x7) || - (frame_height & 0x7)) { - int y1 = ((y0_16 + (h - 1) * ys) >> SUBPEL_BITS) + 1; - - // Get reference block bottom right horizontal coordinate. - int x1 = ((x0_16 + (w - 1) * xs) >> SUBPEL_BITS) + 1; - int x_pad = 0, y_pad = 0; - - if (subpel_x || (sf->x_step_q4 != SUBPEL_SHIFTS)) { - x0 -= VP9_INTERP_EXTEND - 1; - x1 += VP9_INTERP_EXTEND; - x_pad = 1; - } - - if (subpel_y || (sf->y_step_q4 != SUBPEL_SHIFTS)) { - y0 -= VP9_INTERP_EXTEND - 1; - y1 += VP9_INTERP_EXTEND; - y_pad = 1; - } - - // Skip border extension if block is inside the frame. - if (x0 < 0 || x0 > frame_width - 1 || x1 < 0 || x1 > frame_width - 1 || - y0 < 0 || y0 > frame_height - 1 || y1 < 0 || y1 > frame_height - 1) { - // Extend the border. - const uint8_t *const buf_ptr1 = ref_frame + y0 * buf_stride + x0; - const int b_w = x1 - x0 + 1; - const int b_h = y1 - y0 + 1; - const int border_offset = y_pad * 3 * b_w + x_pad * 3; - - extend_and_predict(twd, buf_ptr1, buf_stride, x0, y0, b_w, b_h, - frame_width, frame_height, border_offset, dst, - dst_buf->stride, subpel_x, subpel_y, kernel, sf, -#if CONFIG_VP9_HIGHBITDEPTH - xd, -#endif - w, h, ref, xs, ys); - return; - } - } -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - highbd_inter_predictor(CONVERT_TO_SHORTPTR(buf_ptr), buf_stride, - CONVERT_TO_SHORTPTR(dst), dst_buf->stride, subpel_x, - subpel_y, sf, w, h, ref, kernel, xs, ys, xd->bd); - } else { - inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x, - subpel_y, sf, w, h, ref, kernel, xs, ys); - } -#else - inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x, subpel_y, - sf, w, h, ref, kernel, xs, ys); -#endif // CONFIG_VP9_HIGHBITDEPTH -} - -static void dec_build_inter_predictors_sb(TileWorkerData *twd, - VP9Decoder *const pbi, - MACROBLOCKD *xd, int mi_row, - int mi_col) { - int plane; - const int mi_x = mi_col * MI_SIZE; - const int mi_y = mi_row * MI_SIZE; - const MODE_INFO *mi = xd->mi[0]; - const InterpKernel *kernel = vp9_filter_kernels[mi->interp_filter]; - const BLOCK_SIZE sb_type = mi->sb_type; - const int is_compound = has_second_ref(mi); - int ref; - int is_scaled; - - for (ref = 0; ref < 1 + is_compound; ++ref) { - const MV_REFERENCE_FRAME frame = mi->ref_frame[ref]; - RefBuffer *ref_buf = &pbi->common.frame_refs[frame - LAST_FRAME]; - const struct scale_factors *const sf = &ref_buf->sf; - const int idx = ref_buf->idx; - BufferPool *const pool = pbi->common.buffer_pool; - RefCntBuffer *const ref_frame_buf = &pool->frame_bufs[idx]; - - if (!vp9_is_valid_scale(sf)) - vpx_internal_error(xd->error_info, VPX_CODEC_UNSUP_BITSTREAM, - "Reference frame has invalid dimensions"); - - is_scaled = vp9_is_scaled(sf); - vp9_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col, - is_scaled ? sf : NULL); - xd->block_refs[ref] = ref_buf; - - if (sb_type < BLOCK_8X8) { - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { - struct macroblockd_plane *const pd = &xd->plane[plane]; - struct buf_2d *const dst_buf = &pd->dst; - const int num_4x4_w = pd->n4_w; - const int num_4x4_h = pd->n4_h; - const int n4w_x4 = 4 * num_4x4_w; - const int n4h_x4 = 4 * num_4x4_h; - struct buf_2d *const pre_buf = &pd->pre[ref]; - int i = 0, x, y; - for (y = 0; y < num_4x4_h; ++y) { - for (x = 0; x < num_4x4_w; ++x) { - const MV mv = average_split_mvs(pd, mi, ref, i++); - dec_build_inter_predictors(twd, xd, plane, n4w_x4, n4h_x4, 4 * x, - 4 * y, 4, 4, mi_x, mi_y, kernel, sf, - pre_buf, dst_buf, &mv, ref_frame_buf, - is_scaled, ref); - } - } - } - } else { - const MV mv = mi->mv[ref].as_mv; - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { - struct macroblockd_plane *const pd = &xd->plane[plane]; - struct buf_2d *const dst_buf = &pd->dst; - const int num_4x4_w = pd->n4_w; - const int num_4x4_h = pd->n4_h; - const int n4w_x4 = 4 * num_4x4_w; - const int n4h_x4 = 4 * num_4x4_h; - struct buf_2d *const pre_buf = &pd->pre[ref]; - dec_build_inter_predictors(twd, xd, plane, n4w_x4, n4h_x4, 0, 0, n4w_x4, - n4h_x4, mi_x, mi_y, kernel, sf, pre_buf, - dst_buf, &mv, ref_frame_buf, is_scaled, ref); - } - } - } -} - -static INLINE void dec_reset_skip_context(MACROBLOCKD *xd) { - int i; - for (i = 0; i < MAX_MB_PLANE; i++) { - struct macroblockd_plane *const pd = &xd->plane[i]; - memset(pd->above_context, 0, sizeof(ENTROPY_CONTEXT) * pd->n4_w); - memset(pd->left_context, 0, sizeof(ENTROPY_CONTEXT) * pd->n4_h); - } -} - -static void set_plane_n4(MACROBLOCKD *const xd, int bw, int bh, int bwl, - int bhl) { - int i; - for (i = 0; i < MAX_MB_PLANE; i++) { - xd->plane[i].n4_w = (bw << 1) >> xd->plane[i].subsampling_x; - xd->plane[i].n4_h = (bh << 1) >> xd->plane[i].subsampling_y; - xd->plane[i].n4_wl = bwl - xd->plane[i].subsampling_x; - xd->plane[i].n4_hl = bhl - xd->plane[i].subsampling_y; - } -} - -static MODE_INFO *set_offsets_recon(VP9_COMMON *const cm, MACROBLOCKD *const xd, - int mi_row, int mi_col, int bw, int bh, - int bwl, int bhl) { - const int offset = mi_row * cm->mi_stride + mi_col; - const TileInfo *const tile = &xd->tile; - xd->mi = cm->mi_grid_visible + offset; - - set_plane_n4(xd, bw, bh, bwl, bhl); - - set_skip_context(xd, mi_row, mi_col); - - // Distance of Mb to the various image edges. These are specified to 8th pel - // as they are always compared to values that are in 1/8th pel units - set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); - - vp9_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col); - return xd->mi[0]; -} - -static MODE_INFO *set_offsets(VP9_COMMON *const cm, MACROBLOCKD *const xd, - BLOCK_SIZE bsize, int mi_row, int mi_col, int bw, - int bh, int x_mis, int y_mis, int bwl, int bhl) { - const int offset = mi_row * cm->mi_stride + mi_col; - int x, y; - const TileInfo *const tile = &xd->tile; - - xd->mi = cm->mi_grid_visible + offset; - xd->mi[0] = &cm->mi[offset]; - // TODO(slavarnway): Generate sb_type based on bwl and bhl, instead of - // passing bsize from decode_partition(). - xd->mi[0]->sb_type = bsize; - for (y = 0; y < y_mis; ++y) - for (x = !y; x < x_mis; ++x) { - xd->mi[y * cm->mi_stride + x] = xd->mi[0]; - } - - set_plane_n4(xd, bw, bh, bwl, bhl); - - set_skip_context(xd, mi_row, mi_col); - - // Distance of Mb to the various image edges. These are specified to 8th pel - // as they are always compared to values that are in 1/8th pel units - set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); - - vp9_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col); - return xd->mi[0]; -} - -static INLINE int predict_recon_inter(MACROBLOCKD *xd, MODE_INFO *mi, - TileWorkerData *twd, - predict_recon_func func) { - int eobtotal = 0; - int plane; - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { - const struct macroblockd_plane *const pd = &xd->plane[plane]; - const TX_SIZE tx_size = plane ? get_uv_tx_size(mi, pd) : mi->tx_size; - const int num_4x4_w = pd->n4_w; - const int num_4x4_h = pd->n4_h; - const int step = (1 << tx_size); - int row, col; - const int max_blocks_wide = - num_4x4_w + (xd->mb_to_right_edge >= 0 - ? 0 - : xd->mb_to_right_edge >> (5 + pd->subsampling_x)); - const int max_blocks_high = - num_4x4_h + (xd->mb_to_bottom_edge >= 0 - ? 0 - : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y)); - - xd->max_blocks_wide = xd->mb_to_right_edge >= 0 ? 0 : max_blocks_wide; - xd->max_blocks_high = xd->mb_to_bottom_edge >= 0 ? 0 : max_blocks_high; - - for (row = 0; row < max_blocks_high; row += step) - for (col = 0; col < max_blocks_wide; col += step) - eobtotal += func(twd, mi, plane, row, col, tx_size); - } - return eobtotal; -} - -static INLINE void predict_recon_intra(MACROBLOCKD *xd, MODE_INFO *mi, - TileWorkerData *twd, - intra_recon_func func) { - int plane; - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { - const struct macroblockd_plane *const pd = &xd->plane[plane]; - const TX_SIZE tx_size = plane ? get_uv_tx_size(mi, pd) : mi->tx_size; - const int num_4x4_w = pd->n4_w; - const int num_4x4_h = pd->n4_h; - const int step = (1 << tx_size); - int row, col; - const int max_blocks_wide = - num_4x4_w + (xd->mb_to_right_edge >= 0 - ? 0 - : xd->mb_to_right_edge >> (5 + pd->subsampling_x)); - const int max_blocks_high = - num_4x4_h + (xd->mb_to_bottom_edge >= 0 - ? 0 - : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y)); - - xd->max_blocks_wide = xd->mb_to_right_edge >= 0 ? 0 : max_blocks_wide; - xd->max_blocks_high = xd->mb_to_bottom_edge >= 0 ? 0 : max_blocks_high; - - for (row = 0; row < max_blocks_high; row += step) - for (col = 0; col < max_blocks_wide; col += step) - func(twd, mi, plane, row, col, tx_size); - } -} - -static void decode_block(TileWorkerData *twd, VP9Decoder *const pbi, int mi_row, - int mi_col, BLOCK_SIZE bsize, int bwl, int bhl) { - VP9_COMMON *const cm = &pbi->common; - const int less8x8 = bsize < BLOCK_8X8; - const int bw = 1 << (bwl - 1); - const int bh = 1 << (bhl - 1); - const int x_mis = VPXMIN(bw, cm->mi_cols - mi_col); - const int y_mis = VPXMIN(bh, cm->mi_rows - mi_row); - vpx_reader *r = &twd->bit_reader; - MACROBLOCKD *const xd = &twd->xd; - - MODE_INFO *mi = set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, - y_mis, bwl, bhl); - - if (bsize >= BLOCK_8X8 && (cm->subsampling_x || cm->subsampling_y)) { - const BLOCK_SIZE uv_subsize = - ss_size_lookup[bsize][cm->subsampling_x][cm->subsampling_y]; - if (uv_subsize == BLOCK_INVALID) - vpx_internal_error(xd->error_info, VPX_CODEC_CORRUPT_FRAME, - "Invalid block size."); - } - - vp9_read_mode_info(twd, pbi, mi_row, mi_col, x_mis, y_mis); - - if (mi->skip) { - dec_reset_skip_context(xd); - } - - if (!is_inter_block(mi)) { - int plane; - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { - const struct macroblockd_plane *const pd = &xd->plane[plane]; - const TX_SIZE tx_size = plane ? get_uv_tx_size(mi, pd) : mi->tx_size; - const int num_4x4_w = pd->n4_w; - const int num_4x4_h = pd->n4_h; - const int step = (1 << tx_size); - int row, col; - const int max_blocks_wide = - num_4x4_w + (xd->mb_to_right_edge >= 0 - ? 0 - : xd->mb_to_right_edge >> (5 + pd->subsampling_x)); - const int max_blocks_high = - num_4x4_h + (xd->mb_to_bottom_edge >= 0 - ? 0 - : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y)); - - xd->max_blocks_wide = xd->mb_to_right_edge >= 0 ? 0 : max_blocks_wide; - xd->max_blocks_high = xd->mb_to_bottom_edge >= 0 ? 0 : max_blocks_high; - - for (row = 0; row < max_blocks_high; row += step) - for (col = 0; col < max_blocks_wide; col += step) - predict_and_reconstruct_intra_block(twd, mi, plane, row, col, - tx_size); - } - } else { - // Prediction - dec_build_inter_predictors_sb(twd, pbi, xd, mi_row, mi_col); -#if CONFIG_MISMATCH_DEBUG - { - int plane; - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { - const struct macroblockd_plane *pd = &xd->plane[plane]; - int pixel_c, pixel_r; - const BLOCK_SIZE plane_bsize = - get_plane_block_size(VPXMAX(bsize, BLOCK_8X8), &xd->plane[plane]); - const int bw = get_block_width(plane_bsize); - const int bh = get_block_height(plane_bsize); - mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, 0, 0, - pd->subsampling_x, pd->subsampling_y); - mismatch_check_block_pre(pd->dst.buf, pd->dst.stride, plane, pixel_c, - pixel_r, bw, bh, - xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH); - } - } -#endif - - // Reconstruction - if (!mi->skip) { - int eobtotal = 0; - int plane; - - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { - const struct macroblockd_plane *const pd = &xd->plane[plane]; - const TX_SIZE tx_size = plane ? get_uv_tx_size(mi, pd) : mi->tx_size; - const int num_4x4_w = pd->n4_w; - const int num_4x4_h = pd->n4_h; - const int step = (1 << tx_size); - int row, col; - const int max_blocks_wide = - num_4x4_w + (xd->mb_to_right_edge >= 0 - ? 0 - : xd->mb_to_right_edge >> (5 + pd->subsampling_x)); - const int max_blocks_high = - num_4x4_h + - (xd->mb_to_bottom_edge >= 0 - ? 0 - : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y)); - - xd->max_blocks_wide = xd->mb_to_right_edge >= 0 ? 0 : max_blocks_wide; - xd->max_blocks_high = xd->mb_to_bottom_edge >= 0 ? 0 : max_blocks_high; - - for (row = 0; row < max_blocks_high; row += step) - for (col = 0; col < max_blocks_wide; col += step) - eobtotal += reconstruct_inter_block(twd, mi, plane, row, col, - tx_size, mi_row, mi_col); - } - - if (!less8x8 && eobtotal == 0) mi->skip = 1; // skip loopfilter - } - } - - xd->corrupted |= vpx_reader_has_error(r); - - if (cm->lf.filter_level) { - vp9_build_mask(cm, mi, mi_row, mi_col, bw, bh); - } -} - -static void recon_block(TileWorkerData *twd, VP9Decoder *const pbi, int mi_row, - int mi_col, BLOCK_SIZE bsize, int bwl, int bhl) { - VP9_COMMON *const cm = &pbi->common; - const int bw = 1 << (bwl - 1); - const int bh = 1 << (bhl - 1); - MACROBLOCKD *const xd = &twd->xd; - - MODE_INFO *mi = set_offsets_recon(cm, xd, mi_row, mi_col, bw, bh, bwl, bhl); - - if (bsize >= BLOCK_8X8 && (cm->subsampling_x || cm->subsampling_y)) { - const BLOCK_SIZE uv_subsize = - ss_size_lookup[bsize][cm->subsampling_x][cm->subsampling_y]; - if (uv_subsize == BLOCK_INVALID) - vpx_internal_error(xd->error_info, VPX_CODEC_CORRUPT_FRAME, - "Invalid block size."); - } - - if (!is_inter_block(mi)) { - predict_recon_intra(xd, mi, twd, - predict_and_reconstruct_intra_block_row_mt); - } else { - // Prediction - dec_build_inter_predictors_sb(twd, pbi, xd, mi_row, mi_col); - - // Reconstruction - if (!mi->skip) { - predict_recon_inter(xd, mi, twd, reconstruct_inter_block_row_mt); - } - } - - vp9_build_mask(cm, mi, mi_row, mi_col, bw, bh); -} - -static void parse_block(TileWorkerData *twd, VP9Decoder *const pbi, int mi_row, - int mi_col, BLOCK_SIZE bsize, int bwl, int bhl) { - VP9_COMMON *const cm = &pbi->common; - const int bw = 1 << (bwl - 1); - const int bh = 1 << (bhl - 1); - const int x_mis = VPXMIN(bw, cm->mi_cols - mi_col); - const int y_mis = VPXMIN(bh, cm->mi_rows - mi_row); - vpx_reader *r = &twd->bit_reader; - MACROBLOCKD *const xd = &twd->xd; - - MODE_INFO *mi = set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, - y_mis, bwl, bhl); - - if (bsize >= BLOCK_8X8 && (cm->subsampling_x || cm->subsampling_y)) { - const BLOCK_SIZE uv_subsize = - ss_size_lookup[bsize][cm->subsampling_x][cm->subsampling_y]; - if (uv_subsize == BLOCK_INVALID) - vpx_internal_error(xd->error_info, VPX_CODEC_CORRUPT_FRAME, - "Invalid block size."); - } - - vp9_read_mode_info(twd, pbi, mi_row, mi_col, x_mis, y_mis); - - if (mi->skip) { - dec_reset_skip_context(xd); - } - - if (!is_inter_block(mi)) { - predict_recon_intra(xd, mi, twd, parse_intra_block_row_mt); - } else { - if (!mi->skip) { - tran_low_t *dqcoeff[MAX_MB_PLANE]; - int *eob[MAX_MB_PLANE]; - int plane; - int eobtotal; - // Based on eobtotal and bsize, this may be mi->skip may be set to true - // In that case dqcoeff and eob need to be backed up and restored as - // recon_block will not increment these pointers for skip cases - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { - const struct macroblockd_plane *const pd = &xd->plane[plane]; - dqcoeff[plane] = pd->dqcoeff; - eob[plane] = pd->eob; - } - eobtotal = predict_recon_inter(xd, mi, twd, parse_inter_block_row_mt); - - if (bsize >= BLOCK_8X8 && eobtotal == 0) { - mi->skip = 1; // skip loopfilter - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { - struct macroblockd_plane *pd = &xd->plane[plane]; - pd->dqcoeff = dqcoeff[plane]; - pd->eob = eob[plane]; - } - } - } - } - - xd->corrupted |= vpx_reader_has_error(r); -} - -static INLINE int dec_partition_plane_context(TileWorkerData *twd, int mi_row, - int mi_col, int bsl) { - const PARTITION_CONTEXT *above_ctx = twd->xd.above_seg_context + mi_col; - const PARTITION_CONTEXT *left_ctx = - twd->xd.left_seg_context + (mi_row & MI_MASK); - int above = (*above_ctx >> bsl) & 1, left = (*left_ctx >> bsl) & 1; - - // assert(bsl >= 0); - - return (left * 2 + above) + bsl * PARTITION_PLOFFSET; -} - -static INLINE void dec_update_partition_context(TileWorkerData *twd, int mi_row, - int mi_col, BLOCK_SIZE subsize, - int bw) { - PARTITION_CONTEXT *const above_ctx = twd->xd.above_seg_context + mi_col; - PARTITION_CONTEXT *const left_ctx = - twd->xd.left_seg_context + (mi_row & MI_MASK); - - // update the partition context at the end notes. set partition bits - // of block sizes larger than the current one to be one, and partition - // bits of smaller block sizes to be zero. - memset(above_ctx, partition_context_lookup[subsize].above, bw); - memset(left_ctx, partition_context_lookup[subsize].left, bw); -} - -static PARTITION_TYPE read_partition(TileWorkerData *twd, int mi_row, - int mi_col, int has_rows, int has_cols, - int bsl) { - const int ctx = dec_partition_plane_context(twd, mi_row, mi_col, bsl); - const vpx_prob *const probs = twd->xd.partition_probs[ctx]; - FRAME_COUNTS *counts = twd->xd.counts; - PARTITION_TYPE p; - vpx_reader *r = &twd->bit_reader; - - if (has_rows && has_cols) - p = (PARTITION_TYPE)vpx_read_tree(r, vp9_partition_tree, probs); - else if (!has_rows && has_cols) - p = vpx_read(r, probs[1]) ? PARTITION_SPLIT : PARTITION_HORZ; - else if (has_rows && !has_cols) - p = vpx_read(r, probs[2]) ? PARTITION_SPLIT : PARTITION_VERT; - else - p = PARTITION_SPLIT; - - if (counts) ++counts->partition[ctx][p]; - - return p; -} - -// TODO(slavarnway): eliminate bsize and subsize in future commits -static void decode_partition(TileWorkerData *twd, VP9Decoder *const pbi, - int mi_row, int mi_col, BLOCK_SIZE bsize, - int n4x4_l2) { - VP9_COMMON *const cm = &pbi->common; - const int n8x8_l2 = n4x4_l2 - 1; - const int num_8x8_wh = 1 << n8x8_l2; - const int hbs = num_8x8_wh >> 1; - PARTITION_TYPE partition; - BLOCK_SIZE subsize; - const int has_rows = (mi_row + hbs) < cm->mi_rows; - const int has_cols = (mi_col + hbs) < cm->mi_cols; - MACROBLOCKD *const xd = &twd->xd; - - if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - - partition = read_partition(twd, mi_row, mi_col, has_rows, has_cols, n8x8_l2); - subsize = subsize_lookup[partition][bsize]; // get_subsize(bsize, partition); - if (!hbs) { - // calculate bmode block dimensions (log 2) - xd->bmode_blocks_wl = 1 >> !!(partition & PARTITION_VERT); - xd->bmode_blocks_hl = 1 >> !!(partition & PARTITION_HORZ); - decode_block(twd, pbi, mi_row, mi_col, subsize, 1, 1); - } else { - switch (partition) { - case PARTITION_NONE: - decode_block(twd, pbi, mi_row, mi_col, subsize, n4x4_l2, n4x4_l2); - break; - case PARTITION_HORZ: - decode_block(twd, pbi, mi_row, mi_col, subsize, n4x4_l2, n8x8_l2); - if (has_rows) - decode_block(twd, pbi, mi_row + hbs, mi_col, subsize, n4x4_l2, - n8x8_l2); - break; - case PARTITION_VERT: - decode_block(twd, pbi, mi_row, mi_col, subsize, n8x8_l2, n4x4_l2); - if (has_cols) - decode_block(twd, pbi, mi_row, mi_col + hbs, subsize, n8x8_l2, - n4x4_l2); - break; - case PARTITION_SPLIT: - decode_partition(twd, pbi, mi_row, mi_col, subsize, n8x8_l2); - decode_partition(twd, pbi, mi_row, mi_col + hbs, subsize, n8x8_l2); - decode_partition(twd, pbi, mi_row + hbs, mi_col, subsize, n8x8_l2); - decode_partition(twd, pbi, mi_row + hbs, mi_col + hbs, subsize, - n8x8_l2); - break; - default: assert(0 && "Invalid partition type"); - } - } - - // update partition context - if (bsize >= BLOCK_8X8 && - (bsize == BLOCK_8X8 || partition != PARTITION_SPLIT)) - dec_update_partition_context(twd, mi_row, mi_col, subsize, num_8x8_wh); -} - -static void process_partition(TileWorkerData *twd, VP9Decoder *const pbi, - int mi_row, int mi_col, BLOCK_SIZE bsize, - int n4x4_l2, int parse_recon_flag, - process_block_fn_t process_block) { - VP9_COMMON *const cm = &pbi->common; - const int n8x8_l2 = n4x4_l2 - 1; - const int num_8x8_wh = 1 << n8x8_l2; - const int hbs = num_8x8_wh >> 1; - PARTITION_TYPE partition; - BLOCK_SIZE subsize; - const int has_rows = (mi_row + hbs) < cm->mi_rows; - const int has_cols = (mi_col + hbs) < cm->mi_cols; - MACROBLOCKD *const xd = &twd->xd; - - if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - - if (parse_recon_flag & PARSE) { - *xd->partition = - read_partition(twd, mi_row, mi_col, has_rows, has_cols, n8x8_l2); - } - - partition = *xd->partition; - xd->partition++; - - subsize = get_subsize(bsize, partition); - if (!hbs) { - // calculate bmode block dimensions (log 2) - xd->bmode_blocks_wl = 1 >> !!(partition & PARTITION_VERT); - xd->bmode_blocks_hl = 1 >> !!(partition & PARTITION_HORZ); - process_block(twd, pbi, mi_row, mi_col, subsize, 1, 1); - } else { - switch (partition) { - case PARTITION_NONE: - process_block(twd, pbi, mi_row, mi_col, subsize, n4x4_l2, n4x4_l2); - break; - case PARTITION_HORZ: - process_block(twd, pbi, mi_row, mi_col, subsize, n4x4_l2, n8x8_l2); - if (has_rows) - process_block(twd, pbi, mi_row + hbs, mi_col, subsize, n4x4_l2, - n8x8_l2); - break; - case PARTITION_VERT: - process_block(twd, pbi, mi_row, mi_col, subsize, n8x8_l2, n4x4_l2); - if (has_cols) - process_block(twd, pbi, mi_row, mi_col + hbs, subsize, n8x8_l2, - n4x4_l2); - break; - case PARTITION_SPLIT: - process_partition(twd, pbi, mi_row, mi_col, subsize, n8x8_l2, - parse_recon_flag, process_block); - process_partition(twd, pbi, mi_row, mi_col + hbs, subsize, n8x8_l2, - parse_recon_flag, process_block); - process_partition(twd, pbi, mi_row + hbs, mi_col, subsize, n8x8_l2, - parse_recon_flag, process_block); - process_partition(twd, pbi, mi_row + hbs, mi_col + hbs, subsize, - n8x8_l2, parse_recon_flag, process_block); - break; - default: assert(0 && "Invalid partition type"); - } - } - - if (parse_recon_flag & PARSE) { - // update partition context - if ((bsize == BLOCK_8X8 || partition != PARTITION_SPLIT) && - bsize >= BLOCK_8X8) - dec_update_partition_context(twd, mi_row, mi_col, subsize, num_8x8_wh); - } -} - -static void setup_token_decoder(const uint8_t *data, const uint8_t *data_end, - size_t read_size, - struct vpx_internal_error_info *error_info, - vpx_reader *r, vpx_decrypt_cb decrypt_cb, - void *decrypt_state) { - // Validate the calculated partition length. If the buffer described by the - // partition can't be fully read then throw an error. - if (!read_is_valid(data, read_size, data_end)) - vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME, - "Truncated packet or corrupt tile length"); - - if (vpx_reader_init(r, data, read_size, decrypt_cb, decrypt_state)) - vpx_internal_error(error_info, VPX_CODEC_MEM_ERROR, - "Failed to allocate bool decoder %d", 1); -} - -static void read_coef_probs_common(vp9_coeff_probs_model *coef_probs, - vpx_reader *r) { - int i, j, k, l, m; - - if (vpx_read_bit(r)) - for (i = 0; i < PLANE_TYPES; ++i) - for (j = 0; j < REF_TYPES; ++j) - for (k = 0; k < COEF_BANDS; ++k) - for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) - for (m = 0; m < UNCONSTRAINED_NODES; ++m) - vp9_diff_update_prob(r, &coef_probs[i][j][k][l][m]); -} - -static void read_coef_probs(FRAME_CONTEXT *fc, TX_MODE tx_mode, vpx_reader *r) { - const TX_SIZE max_tx_size = tx_mode_to_biggest_tx_size[tx_mode]; - TX_SIZE tx_size; - for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size) - read_coef_probs_common(fc->coef_probs[tx_size], r); -} - -static void setup_segmentation(struct segmentation *seg, - struct vpx_read_bit_buffer *rb) { - int i, j; - - seg->update_map = 0; - seg->update_data = 0; - - seg->enabled = vpx_rb_read_bit(rb); - if (!seg->enabled) return; - - // Segmentation map update - seg->update_map = vpx_rb_read_bit(rb); - if (seg->update_map) { - for (i = 0; i < SEG_TREE_PROBS; i++) - seg->tree_probs[i] = - vpx_rb_read_bit(rb) ? vpx_rb_read_literal(rb, 8) : MAX_PROB; - - seg->temporal_update = vpx_rb_read_bit(rb); - if (seg->temporal_update) { - for (i = 0; i < PREDICTION_PROBS; i++) - seg->pred_probs[i] = - vpx_rb_read_bit(rb) ? vpx_rb_read_literal(rb, 8) : MAX_PROB; - } else { - for (i = 0; i < PREDICTION_PROBS; i++) seg->pred_probs[i] = MAX_PROB; - } - } - - // Segmentation data update - seg->update_data = vpx_rb_read_bit(rb); - if (seg->update_data) { - seg->abs_delta = vpx_rb_read_bit(rb); - - vp9_clearall_segfeatures(seg); - - for (i = 0; i < MAX_SEGMENTS; i++) { - for (j = 0; j < SEG_LVL_MAX; j++) { - int data = 0; - const int feature_enabled = vpx_rb_read_bit(rb); - if (feature_enabled) { - vp9_enable_segfeature(seg, i, j); - data = decode_unsigned_max(rb, vp9_seg_feature_data_max(j)); - if (vp9_is_segfeature_signed(j)) - data = vpx_rb_read_bit(rb) ? -data : data; - } - vp9_set_segdata(seg, i, j, data); - } - } - } -} - -static void setup_loopfilter(struct loopfilter *lf, - struct vpx_read_bit_buffer *rb) { - lf->filter_level = vpx_rb_read_literal(rb, 6); - lf->sharpness_level = vpx_rb_read_literal(rb, 3); - - // Read in loop filter deltas applied at the MB level based on mode or ref - // frame. - lf->mode_ref_delta_update = 0; - - lf->mode_ref_delta_enabled = vpx_rb_read_bit(rb); - if (lf->mode_ref_delta_enabled) { - lf->mode_ref_delta_update = vpx_rb_read_bit(rb); - if (lf->mode_ref_delta_update) { - int i; - - for (i = 0; i < MAX_REF_LF_DELTAS; i++) - if (vpx_rb_read_bit(rb)) - lf->ref_deltas[i] = vpx_rb_read_signed_literal(rb, 6); - - for (i = 0; i < MAX_MODE_LF_DELTAS; i++) - if (vpx_rb_read_bit(rb)) - lf->mode_deltas[i] = vpx_rb_read_signed_literal(rb, 6); - } - } -} - -static INLINE int read_delta_q(struct vpx_read_bit_buffer *rb) { - return vpx_rb_read_bit(rb) ? vpx_rb_read_signed_literal(rb, 4) : 0; -} - -static void setup_quantization(VP9_COMMON *const cm, MACROBLOCKD *const xd, - struct vpx_read_bit_buffer *rb) { - cm->base_qindex = vpx_rb_read_literal(rb, QINDEX_BITS); - cm->y_dc_delta_q = read_delta_q(rb); - cm->uv_dc_delta_q = read_delta_q(rb); - cm->uv_ac_delta_q = read_delta_q(rb); - cm->dequant_bit_depth = cm->bit_depth; - xd->lossless = cm->base_qindex == 0 && cm->y_dc_delta_q == 0 && - cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0; - -#if CONFIG_VP9_HIGHBITDEPTH - xd->bd = (int)cm->bit_depth; -#endif -} - -static void setup_segmentation_dequant(VP9_COMMON *const cm) { - // Build y/uv dequant values based on segmentation. - if (cm->seg.enabled) { - int i; - for (i = 0; i < MAX_SEGMENTS; ++i) { - const int qindex = vp9_get_qindex(&cm->seg, i, cm->base_qindex); - cm->y_dequant[i][0] = - vp9_dc_quant(qindex, cm->y_dc_delta_q, cm->bit_depth); - cm->y_dequant[i][1] = vp9_ac_quant(qindex, 0, cm->bit_depth); - cm->uv_dequant[i][0] = - vp9_dc_quant(qindex, cm->uv_dc_delta_q, cm->bit_depth); - cm->uv_dequant[i][1] = - vp9_ac_quant(qindex, cm->uv_ac_delta_q, cm->bit_depth); - } - } else { - const int qindex = cm->base_qindex; - // When segmentation is disabled, only the first value is used. The - // remaining are don't cares. - cm->y_dequant[0][0] = vp9_dc_quant(qindex, cm->y_dc_delta_q, cm->bit_depth); - cm->y_dequant[0][1] = vp9_ac_quant(qindex, 0, cm->bit_depth); - cm->uv_dequant[0][0] = - vp9_dc_quant(qindex, cm->uv_dc_delta_q, cm->bit_depth); - cm->uv_dequant[0][1] = - vp9_ac_quant(qindex, cm->uv_ac_delta_q, cm->bit_depth); - } -} - -static INTERP_FILTER read_interp_filter(struct vpx_read_bit_buffer *rb) { - const INTERP_FILTER literal_to_filter[] = { EIGHTTAP_SMOOTH, EIGHTTAP, - EIGHTTAP_SHARP, BILINEAR }; - return vpx_rb_read_bit(rb) ? SWITCHABLE - : literal_to_filter[vpx_rb_read_literal(rb, 2)]; -} - -static void setup_render_size(VP9_COMMON *cm, struct vpx_read_bit_buffer *rb) { - cm->render_width = cm->width; - cm->render_height = cm->height; - if (vpx_rb_read_bit(rb)) - vp9_read_frame_size(rb, &cm->render_width, &cm->render_height); -} - -static void resize_mv_buffer(VP9_COMMON *cm) { - vpx_free(cm->cur_frame->mvs); - cm->cur_frame->mi_rows = cm->mi_rows; - cm->cur_frame->mi_cols = cm->mi_cols; - CHECK_MEM_ERROR(&cm->error, cm->cur_frame->mvs, - (MV_REF *)vpx_calloc(cm->mi_rows * cm->mi_cols, - sizeof(*cm->cur_frame->mvs))); -} - -static void resize_context_buffers(VP9_COMMON *cm, int width, int height) { -#if CONFIG_SIZE_LIMIT - if (width > DECODE_WIDTH_LIMIT || height > DECODE_HEIGHT_LIMIT) - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, - "Dimensions of %dx%d beyond allowed size of %dx%d.", - width, height, DECODE_WIDTH_LIMIT, DECODE_HEIGHT_LIMIT); -#endif - if (cm->width != width || cm->height != height) { - const int new_mi_rows = - ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2) >> MI_SIZE_LOG2; - const int new_mi_cols = - ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2) >> MI_SIZE_LOG2; - - // Allocations in vp9_alloc_context_buffers() depend on individual - // dimensions as well as the overall size. - if (new_mi_cols > cm->mi_cols || new_mi_rows > cm->mi_rows) { - if (vp9_alloc_context_buffers(cm, width, height)) { - // The cm->mi_* values have been cleared and any existing context - // buffers have been freed. Clear cm->width and cm->height to be - // consistent and to force a realloc next time. - cm->width = 0; - cm->height = 0; - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate context buffers"); - } - } else { - vp9_set_mb_mi(cm, width, height); - } - vp9_init_context_buffers(cm); - cm->width = width; - cm->height = height; - } - if (cm->cur_frame->mvs == NULL || cm->mi_rows > cm->cur_frame->mi_rows || - cm->mi_cols > cm->cur_frame->mi_cols) { - resize_mv_buffer(cm); - } -} - -static void setup_frame_size(VP9_COMMON *cm, struct vpx_read_bit_buffer *rb) { - int width, height; - BufferPool *const pool = cm->buffer_pool; - vp9_read_frame_size(rb, &width, &height); - resize_context_buffers(cm, width, height); - setup_render_size(cm, rb); - - if (vpx_realloc_frame_buffer( - get_frame_new_buffer(cm), cm->width, cm->height, cm->subsampling_x, - cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_DEC_BORDER_IN_PIXELS, cm->byte_alignment, - &pool->frame_bufs[cm->new_fb_idx].raw_frame_buffer, pool->get_fb_cb, - pool->cb_priv)) { - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate frame buffer"); - } - - pool->frame_bufs[cm->new_fb_idx].released = 0; - pool->frame_bufs[cm->new_fb_idx].buf.subsampling_x = cm->subsampling_x; - pool->frame_bufs[cm->new_fb_idx].buf.subsampling_y = cm->subsampling_y; - pool->frame_bufs[cm->new_fb_idx].buf.bit_depth = (unsigned int)cm->bit_depth; - pool->frame_bufs[cm->new_fb_idx].buf.color_space = cm->color_space; - pool->frame_bufs[cm->new_fb_idx].buf.color_range = cm->color_range; - pool->frame_bufs[cm->new_fb_idx].buf.render_width = cm->render_width; - pool->frame_bufs[cm->new_fb_idx].buf.render_height = cm->render_height; -} - -static INLINE int valid_ref_frame_img_fmt(vpx_bit_depth_t ref_bit_depth, - int ref_xss, int ref_yss, - vpx_bit_depth_t this_bit_depth, - int this_xss, int this_yss) { - return ref_bit_depth == this_bit_depth && ref_xss == this_xss && - ref_yss == this_yss; -} - -static void setup_frame_size_with_refs(VP9_COMMON *cm, - struct vpx_read_bit_buffer *rb) { - int width, height; - int found = 0, i; - int has_valid_ref_frame = 0; - BufferPool *const pool = cm->buffer_pool; - for (i = 0; i < REFS_PER_FRAME; ++i) { - if (vpx_rb_read_bit(rb)) { - if (cm->frame_refs[i].idx != INVALID_IDX) { - YV12_BUFFER_CONFIG *const buf = cm->frame_refs[i].buf; - width = buf->y_crop_width; - height = buf->y_crop_height; - found = 1; - break; - } else { - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, - "Failed to decode frame size"); - } - } - } - - if (!found) vp9_read_frame_size(rb, &width, &height); - - if (width <= 0 || height <= 0) - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, - "Invalid frame size"); - - // Check to make sure at least one of frames that this frame references - // has valid dimensions. - for (i = 0; i < REFS_PER_FRAME; ++i) { - RefBuffer *const ref_frame = &cm->frame_refs[i]; - has_valid_ref_frame |= - (ref_frame->idx != INVALID_IDX && - valid_ref_frame_size(ref_frame->buf->y_crop_width, - ref_frame->buf->y_crop_height, width, height)); - } - if (!has_valid_ref_frame) - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, - "Referenced frame has invalid size"); - for (i = 0; i < REFS_PER_FRAME; ++i) { - RefBuffer *const ref_frame = &cm->frame_refs[i]; - if (ref_frame->idx == INVALID_IDX || - !valid_ref_frame_img_fmt(ref_frame->buf->bit_depth, - ref_frame->buf->subsampling_x, - ref_frame->buf->subsampling_y, cm->bit_depth, - cm->subsampling_x, cm->subsampling_y)) - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, - "Referenced frame has incompatible color format"); - } - - resize_context_buffers(cm, width, height); - setup_render_size(cm, rb); - - if (vpx_realloc_frame_buffer( - get_frame_new_buffer(cm), cm->width, cm->height, cm->subsampling_x, - cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_DEC_BORDER_IN_PIXELS, cm->byte_alignment, - &pool->frame_bufs[cm->new_fb_idx].raw_frame_buffer, pool->get_fb_cb, - pool->cb_priv)) { - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate frame buffer"); - } - - pool->frame_bufs[cm->new_fb_idx].released = 0; - pool->frame_bufs[cm->new_fb_idx].buf.subsampling_x = cm->subsampling_x; - pool->frame_bufs[cm->new_fb_idx].buf.subsampling_y = cm->subsampling_y; - pool->frame_bufs[cm->new_fb_idx].buf.bit_depth = (unsigned int)cm->bit_depth; - pool->frame_bufs[cm->new_fb_idx].buf.color_space = cm->color_space; - pool->frame_bufs[cm->new_fb_idx].buf.color_range = cm->color_range; - pool->frame_bufs[cm->new_fb_idx].buf.render_width = cm->render_width; - pool->frame_bufs[cm->new_fb_idx].buf.render_height = cm->render_height; -} - -static void setup_tile_info(VP9_COMMON *cm, struct vpx_read_bit_buffer *rb) { - int min_log2_tile_cols, max_log2_tile_cols, max_ones; - vp9_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols); - - // columns - max_ones = max_log2_tile_cols - min_log2_tile_cols; - cm->log2_tile_cols = min_log2_tile_cols; - while (max_ones-- && vpx_rb_read_bit(rb)) cm->log2_tile_cols++; - - if (cm->log2_tile_cols > 6) - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, - "Invalid number of tile columns"); - - // rows - cm->log2_tile_rows = vpx_rb_read_bit(rb); - if (cm->log2_tile_rows) cm->log2_tile_rows += vpx_rb_read_bit(rb); -} - -// Reads the next tile returning its size and adjusting '*data' accordingly -// based on 'is_last'. -static void get_tile_buffer(const uint8_t *const data_end, int is_last, - struct vpx_internal_error_info *error_info, - const uint8_t **data, vpx_decrypt_cb decrypt_cb, - void *decrypt_state, TileBuffer *buf) { - size_t size; - - if (!is_last) { - if (!read_is_valid(*data, 4, data_end)) - vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME, - "Truncated packet or corrupt tile length"); - - if (decrypt_cb) { - uint8_t be_data[4]; - decrypt_cb(decrypt_state, *data, be_data, 4); - size = mem_get_be32(be_data); - } else { - size = mem_get_be32(*data); - } - *data += 4; - - if (size > (size_t)(data_end - *data)) - vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME, - "Truncated packet or corrupt tile size"); - } else { - size = data_end - *data; - } - - buf->data = *data; - buf->size = size; - - *data += size; -} - -static void get_tile_buffers(VP9Decoder *pbi, const uint8_t *data, - const uint8_t *data_end, int tile_cols, - int tile_rows, - TileBuffer (*tile_buffers)[1 << 6]) { - int r, c; - - for (r = 0; r < tile_rows; ++r) { - for (c = 0; c < tile_cols; ++c) { - const int is_last = (r == tile_rows - 1) && (c == tile_cols - 1); - TileBuffer *const buf = &tile_buffers[r][c]; - buf->col = c; - get_tile_buffer(data_end, is_last, &pbi->common.error, &data, - pbi->decrypt_cb, pbi->decrypt_state, buf); - } - } -} - -static void map_write(RowMTWorkerData *const row_mt_worker_data, int map_idx, - int sync_idx) { -#if CONFIG_MULTITHREAD - pthread_mutex_lock(&row_mt_worker_data->recon_sync_mutex[sync_idx]); - row_mt_worker_data->recon_map[map_idx] = 1; - pthread_cond_signal(&row_mt_worker_data->recon_sync_cond[sync_idx]); - pthread_mutex_unlock(&row_mt_worker_data->recon_sync_mutex[sync_idx]); -#else - (void)row_mt_worker_data; - (void)map_idx; - (void)sync_idx; -#endif // CONFIG_MULTITHREAD -} - -static void map_read(RowMTWorkerData *const row_mt_worker_data, int map_idx, - int sync_idx) { -#if CONFIG_MULTITHREAD - volatile int8_t *map = row_mt_worker_data->recon_map + map_idx; - pthread_mutex_t *const mutex = - &row_mt_worker_data->recon_sync_mutex[sync_idx]; - pthread_mutex_lock(mutex); - while (!(*map)) { - pthread_cond_wait(&row_mt_worker_data->recon_sync_cond[sync_idx], mutex); - } - pthread_mutex_unlock(mutex); -#else - (void)row_mt_worker_data; - (void)map_idx; - (void)sync_idx; -#endif // CONFIG_MULTITHREAD -} - -static int lpf_map_write_check(VP9LfSync *lf_sync, int row, int num_tile_cols) { - int return_val = 0; -#if CONFIG_MULTITHREAD - int corrupted; - pthread_mutex_lock(lf_sync->lf_mutex); - corrupted = lf_sync->corrupted; - pthread_mutex_unlock(lf_sync->lf_mutex); - if (!corrupted) { - pthread_mutex_lock(&lf_sync->recon_done_mutex[row]); - lf_sync->num_tiles_done[row] += 1; - if (num_tile_cols == lf_sync->num_tiles_done[row]) return_val = 1; - pthread_mutex_unlock(&lf_sync->recon_done_mutex[row]); - } -#else - (void)lf_sync; - (void)row; - (void)num_tile_cols; -#endif - return return_val; -} - -static void vp9_tile_done(VP9Decoder *pbi) { -#if CONFIG_MULTITHREAD - int terminate; - RowMTWorkerData *const row_mt_worker_data = pbi->row_mt_worker_data; - const int all_parse_done = 1 << pbi->common.log2_tile_cols; - pthread_mutex_lock(&row_mt_worker_data->recon_done_mutex); - row_mt_worker_data->num_tiles_done++; - terminate = all_parse_done == row_mt_worker_data->num_tiles_done; - pthread_mutex_unlock(&row_mt_worker_data->recon_done_mutex); - if (terminate) { - vp9_jobq_terminate(&row_mt_worker_data->jobq); - } -#else - (void)pbi; -#endif -} - -static void vp9_jobq_alloc(VP9Decoder *pbi) { - VP9_COMMON *const cm = &pbi->common; - RowMTWorkerData *const row_mt_worker_data = pbi->row_mt_worker_data; - const int aligned_rows = mi_cols_aligned_to_sb(cm->mi_rows); - const int sb_rows = aligned_rows >> MI_BLOCK_SIZE_LOG2; - const int tile_cols = 1 << cm->log2_tile_cols; - const size_t jobq_size = (tile_cols * sb_rows * 2 + sb_rows) * sizeof(Job); - - if (jobq_size > row_mt_worker_data->jobq_size) { - vpx_free(row_mt_worker_data->jobq_buf); - CHECK_MEM_ERROR(&cm->error, row_mt_worker_data->jobq_buf, - vpx_calloc(1, jobq_size)); - vp9_jobq_init(&row_mt_worker_data->jobq, row_mt_worker_data->jobq_buf, - jobq_size); - row_mt_worker_data->jobq_size = jobq_size; - } -} - -static void recon_tile_row(TileWorkerData *tile_data, VP9Decoder *pbi, - int mi_row, int is_last_row, VP9LfSync *lf_sync, - int cur_tile_col) { - VP9_COMMON *const cm = &pbi->common; - RowMTWorkerData *const row_mt_worker_data = pbi->row_mt_worker_data; - const int tile_cols = 1 << cm->log2_tile_cols; - const int aligned_cols = mi_cols_aligned_to_sb(cm->mi_cols); - const int sb_cols = aligned_cols >> MI_BLOCK_SIZE_LOG2; - const int cur_sb_row = mi_row >> MI_BLOCK_SIZE_LOG2; - int mi_col_start = tile_data->xd.tile.mi_col_start; - int mi_col_end = tile_data->xd.tile.mi_col_end; - int mi_col; - - vp9_zero(tile_data->xd.left_context); - vp9_zero(tile_data->xd.left_seg_context); - for (mi_col = mi_col_start; mi_col < mi_col_end; mi_col += MI_BLOCK_SIZE) { - const int c = mi_col >> MI_BLOCK_SIZE_LOG2; - int plane; - const int sb_num = (cur_sb_row * (aligned_cols >> MI_BLOCK_SIZE_LOG2) + c); - - // Top Dependency - if (cur_sb_row) { - map_read(row_mt_worker_data, ((cur_sb_row - 1) * sb_cols) + c, - ((cur_sb_row - 1) * tile_cols) + cur_tile_col); - } - - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { - tile_data->xd.plane[plane].eob = - row_mt_worker_data->eob[plane] + (sb_num << EOBS_PER_SB_LOG2); - tile_data->xd.plane[plane].dqcoeff = - row_mt_worker_data->dqcoeff[plane] + (sb_num << DQCOEFFS_PER_SB_LOG2); - } - tile_data->xd.partition = - row_mt_worker_data->partition + (sb_num * PARTITIONS_PER_SB); - process_partition(tile_data, pbi, mi_row, mi_col, BLOCK_64X64, 4, RECON, - recon_block); - if (cm->lf.filter_level && !cm->skip_loop_filter) { - // Queue LPF_JOB - int is_lpf_job_ready = 0; - - if (mi_col + MI_BLOCK_SIZE >= mi_col_end) { - // Checks if this row has been decoded in all tiles - is_lpf_job_ready = lpf_map_write_check(lf_sync, cur_sb_row, tile_cols); - - if (is_lpf_job_ready) { - Job lpf_job; - lpf_job.job_type = LPF_JOB; - if (cur_sb_row > 0) { - lpf_job.row_num = mi_row - MI_BLOCK_SIZE; - vp9_jobq_queue(&row_mt_worker_data->jobq, &lpf_job, - sizeof(lpf_job)); - } - if (is_last_row) { - lpf_job.row_num = mi_row; - vp9_jobq_queue(&row_mt_worker_data->jobq, &lpf_job, - sizeof(lpf_job)); - } - } - } - } - map_write(row_mt_worker_data, (cur_sb_row * sb_cols) + c, - (cur_sb_row * tile_cols) + cur_tile_col); - } -} - -static void parse_tile_row(TileWorkerData *tile_data, VP9Decoder *pbi, - int mi_row, int cur_tile_col, uint8_t **data_end) { - int mi_col; - VP9_COMMON *const cm = &pbi->common; - RowMTWorkerData *const row_mt_worker_data = pbi->row_mt_worker_data; - TileInfo *tile = &tile_data->xd.tile; - TileBuffer *const buf = &pbi->tile_buffers[cur_tile_col]; - const int aligned_cols = mi_cols_aligned_to_sb(cm->mi_cols); - - vp9_zero(tile_data->dqcoeff); - vp9_tile_init(tile, cm, 0, cur_tile_col); - - /* Update reader only at the beginning of each row in a tile */ - if (mi_row == 0) { - setup_token_decoder(buf->data, *data_end, buf->size, &tile_data->error_info, - &tile_data->bit_reader, pbi->decrypt_cb, - pbi->decrypt_state); - } - vp9_init_macroblockd(cm, &tile_data->xd, tile_data->dqcoeff); - tile_data->xd.error_info = &tile_data->error_info; - - vp9_zero(tile_data->xd.left_context); - vp9_zero(tile_data->xd.left_seg_context); - for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end; - mi_col += MI_BLOCK_SIZE) { - const int r = mi_row >> MI_BLOCK_SIZE_LOG2; - const int c = mi_col >> MI_BLOCK_SIZE_LOG2; - int plane; - const int sb_num = (r * (aligned_cols >> MI_BLOCK_SIZE_LOG2) + c); - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { - tile_data->xd.plane[plane].eob = - row_mt_worker_data->eob[plane] + (sb_num << EOBS_PER_SB_LOG2); - tile_data->xd.plane[plane].dqcoeff = - row_mt_worker_data->dqcoeff[plane] + (sb_num << DQCOEFFS_PER_SB_LOG2); - } - tile_data->xd.partition = - row_mt_worker_data->partition + sb_num * PARTITIONS_PER_SB; - process_partition(tile_data, pbi, mi_row, mi_col, BLOCK_64X64, 4, PARSE, - parse_block); - } -} - -static int row_decode_worker_hook(void *arg1, void *arg2) { - ThreadData *const thread_data = (ThreadData *)arg1; - uint8_t **data_end = (uint8_t **)arg2; - VP9Decoder *const pbi = thread_data->pbi; - VP9_COMMON *const cm = &pbi->common; - RowMTWorkerData *const row_mt_worker_data = pbi->row_mt_worker_data; - const int aligned_cols = mi_cols_aligned_to_sb(cm->mi_cols); - const int aligned_rows = mi_cols_aligned_to_sb(cm->mi_rows); - const int sb_rows = aligned_rows >> MI_BLOCK_SIZE_LOG2; - const int tile_cols = 1 << cm->log2_tile_cols; - Job job; - LFWorkerData *lf_data = thread_data->lf_data; - VP9LfSync *lf_sync = thread_data->lf_sync; - volatile int corrupted = 0; - TileWorkerData *volatile tile_data_recon = NULL; - - while (!vp9_jobq_dequeue(&row_mt_worker_data->jobq, &job, sizeof(job), 1)) { - int mi_col; - const int mi_row = job.row_num; - - if (job.job_type == LPF_JOB) { - lf_data->start = mi_row; - lf_data->stop = lf_data->start + MI_BLOCK_SIZE; - - if (cm->lf.filter_level && !cm->skip_loop_filter && - mi_row < cm->mi_rows) { - vp9_loopfilter_job(lf_data, lf_sync); - } - } else if (job.job_type == RECON_JOB) { - const int cur_sb_row = mi_row >> MI_BLOCK_SIZE_LOG2; - const int is_last_row = sb_rows - 1 == cur_sb_row; - int mi_col_start, mi_col_end; - if (!tile_data_recon) - CHECK_MEM_ERROR(&cm->error, tile_data_recon, - vpx_memalign(32, sizeof(TileWorkerData))); - - tile_data_recon->xd = pbi->mb; - vp9_tile_init(&tile_data_recon->xd.tile, cm, 0, job.tile_col); - vp9_init_macroblockd(cm, &tile_data_recon->xd, tile_data_recon->dqcoeff); - mi_col_start = tile_data_recon->xd.tile.mi_col_start; - mi_col_end = tile_data_recon->xd.tile.mi_col_end; - - if (setjmp(tile_data_recon->error_info.jmp)) { - const int sb_cols = aligned_cols >> MI_BLOCK_SIZE_LOG2; - tile_data_recon->error_info.setjmp = 0; - corrupted = 1; - for (mi_col = mi_col_start; mi_col < mi_col_end; - mi_col += MI_BLOCK_SIZE) { - const int c = mi_col >> MI_BLOCK_SIZE_LOG2; - map_write(row_mt_worker_data, (cur_sb_row * sb_cols) + c, - (cur_sb_row * tile_cols) + job.tile_col); - } - if (is_last_row) { - vp9_tile_done(pbi); - } - continue; - } - - tile_data_recon->error_info.setjmp = 1; - tile_data_recon->xd.error_info = &tile_data_recon->error_info; - - recon_tile_row(tile_data_recon, pbi, mi_row, is_last_row, lf_sync, - job.tile_col); - - if (corrupted) - vpx_internal_error(&tile_data_recon->error_info, - VPX_CODEC_CORRUPT_FRAME, - "Failed to decode tile data"); - - if (is_last_row) { - vp9_tile_done(pbi); - } - } else if (job.job_type == PARSE_JOB) { - TileWorkerData *const tile_data = &pbi->tile_worker_data[job.tile_col]; - - if (setjmp(tile_data->error_info.jmp)) { - tile_data->error_info.setjmp = 0; - corrupted = 1; - vp9_tile_done(pbi); - continue; - } - - tile_data->xd = pbi->mb; - tile_data->xd.counts = - cm->frame_parallel_decoding_mode ? 0 : &tile_data->counts; - - tile_data->error_info.setjmp = 1; - - parse_tile_row(tile_data, pbi, mi_row, job.tile_col, data_end); - - corrupted |= tile_data->xd.corrupted; - if (corrupted) - vpx_internal_error(&tile_data->error_info, VPX_CODEC_CORRUPT_FRAME, - "Failed to decode tile data"); - - /* Queue in the recon_job for this row */ - { - Job recon_job; - recon_job.row_num = mi_row; - recon_job.tile_col = job.tile_col; - recon_job.job_type = RECON_JOB; - vp9_jobq_queue(&row_mt_worker_data->jobq, &recon_job, - sizeof(recon_job)); - } - - /* Queue next parse job */ - if (mi_row + MI_BLOCK_SIZE < cm->mi_rows) { - Job parse_job; - parse_job.row_num = mi_row + MI_BLOCK_SIZE; - parse_job.tile_col = job.tile_col; - parse_job.job_type = PARSE_JOB; - vp9_jobq_queue(&row_mt_worker_data->jobq, &parse_job, - sizeof(parse_job)); - } - } - } - - vpx_free(tile_data_recon); - return !corrupted; -} - -static const uint8_t *decode_tiles(VP9Decoder *pbi, const uint8_t *data, - const uint8_t *data_end) { - VP9_COMMON *const cm = &pbi->common; - const VPxWorkerInterface *const winterface = vpx_get_worker_interface(); - const int aligned_cols = mi_cols_aligned_to_sb(cm->mi_cols); - const int tile_cols = 1 << cm->log2_tile_cols; - const int tile_rows = 1 << cm->log2_tile_rows; - TileBuffer tile_buffers[4][1 << 6]; - int tile_row, tile_col; - int mi_row, mi_col; - TileWorkerData *tile_data = NULL; - - if (cm->lf.filter_level && !cm->skip_loop_filter && - pbi->lf_worker.data1 == NULL) { - CHECK_MEM_ERROR(&cm->error, pbi->lf_worker.data1, - vpx_memalign(32, sizeof(LFWorkerData))); - pbi->lf_worker.hook = vp9_loop_filter_worker; - if (pbi->max_threads > 1 && !winterface->reset(&pbi->lf_worker)) { - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "Loop filter thread creation failed"); - } - } - - if (cm->lf.filter_level && !cm->skip_loop_filter) { - LFWorkerData *const lf_data = (LFWorkerData *)pbi->lf_worker.data1; - // Be sure to sync as we might be resuming after a failed frame decode. - winterface->sync(&pbi->lf_worker); - vp9_loop_filter_data_reset(lf_data, get_frame_new_buffer(cm), cm, - pbi->mb.plane); - } - - assert(tile_rows <= 4); - assert(tile_cols <= (1 << 6)); - - // Note: this memset assumes above_context[0], [1] and [2] - // are allocated as part of the same buffer. - memset(cm->above_context, 0, - sizeof(*cm->above_context) * MAX_MB_PLANE * 2 * aligned_cols); - - memset(cm->above_seg_context, 0, - sizeof(*cm->above_seg_context) * aligned_cols); - - vp9_reset_lfm(cm); - - get_tile_buffers(pbi, data, data_end, tile_cols, tile_rows, tile_buffers); - - // Load all tile information into tile_data. - for (tile_row = 0; tile_row < tile_rows; ++tile_row) { - for (tile_col = 0; tile_col < tile_cols; ++tile_col) { - const TileBuffer *const buf = &tile_buffers[tile_row][tile_col]; - tile_data = pbi->tile_worker_data + tile_cols * tile_row + tile_col; - tile_data->xd = pbi->mb; - tile_data->xd.corrupted = 0; - tile_data->xd.counts = - cm->frame_parallel_decoding_mode ? NULL : &cm->counts; - vp9_zero(tile_data->dqcoeff); - vp9_tile_init(&tile_data->xd.tile, cm, tile_row, tile_col); - setup_token_decoder(buf->data, data_end, buf->size, &cm->error, - &tile_data->bit_reader, pbi->decrypt_cb, - pbi->decrypt_state); - vp9_init_macroblockd(cm, &tile_data->xd, tile_data->dqcoeff); - } - } - - for (tile_row = 0; tile_row < tile_rows; ++tile_row) { - TileInfo tile; - vp9_tile_set_row(&tile, cm, tile_row); - for (mi_row = tile.mi_row_start; mi_row < tile.mi_row_end; - mi_row += MI_BLOCK_SIZE) { - for (tile_col = 0; tile_col < tile_cols; ++tile_col) { - const int col = - pbi->inv_tile_order ? tile_cols - tile_col - 1 : tile_col; - tile_data = pbi->tile_worker_data + tile_cols * tile_row + col; - vp9_tile_set_col(&tile, cm, col); - vp9_zero(tile_data->xd.left_context); - vp9_zero(tile_data->xd.left_seg_context); - for (mi_col = tile.mi_col_start; mi_col < tile.mi_col_end; - mi_col += MI_BLOCK_SIZE) { - if (pbi->row_mt == 1) { - int plane; - RowMTWorkerData *const row_mt_worker_data = pbi->row_mt_worker_data; - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { - tile_data->xd.plane[plane].eob = row_mt_worker_data->eob[plane]; - tile_data->xd.plane[plane].dqcoeff = - row_mt_worker_data->dqcoeff[plane]; - } - tile_data->xd.partition = row_mt_worker_data->partition; - process_partition(tile_data, pbi, mi_row, mi_col, BLOCK_64X64, 4, - PARSE, parse_block); - - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { - tile_data->xd.plane[plane].eob = row_mt_worker_data->eob[plane]; - tile_data->xd.plane[plane].dqcoeff = - row_mt_worker_data->dqcoeff[plane]; - } - tile_data->xd.partition = row_mt_worker_data->partition; - process_partition(tile_data, pbi, mi_row, mi_col, BLOCK_64X64, 4, - RECON, recon_block); - } else { - decode_partition(tile_data, pbi, mi_row, mi_col, BLOCK_64X64, 4); - } - } - pbi->mb.corrupted |= tile_data->xd.corrupted; - if (pbi->mb.corrupted) - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, - "Failed to decode tile data"); - } - // Loopfilter one row. - if (cm->lf.filter_level && !cm->skip_loop_filter) { - const int lf_start = mi_row - MI_BLOCK_SIZE; - LFWorkerData *const lf_data = (LFWorkerData *)pbi->lf_worker.data1; - - // delay the loopfilter by 1 macroblock row. - if (lf_start < 0) continue; - - // decoding has completed: finish up the loop filter in this thread. - if (mi_row + MI_BLOCK_SIZE >= cm->mi_rows) continue; - - winterface->sync(&pbi->lf_worker); - lf_data->start = lf_start; - lf_data->stop = mi_row; - if (pbi->max_threads > 1) { - winterface->launch(&pbi->lf_worker); - } else { - winterface->execute(&pbi->lf_worker); - } - } - } - } - - // Loopfilter remaining rows in the frame. - if (cm->lf.filter_level && !cm->skip_loop_filter) { - LFWorkerData *const lf_data = (LFWorkerData *)pbi->lf_worker.data1; - winterface->sync(&pbi->lf_worker); - lf_data->start = lf_data->stop; - lf_data->stop = cm->mi_rows; - winterface->execute(&pbi->lf_worker); - } - - // Get last tile data. - tile_data = pbi->tile_worker_data + tile_cols * tile_rows - 1; - - return vpx_reader_find_end(&tile_data->bit_reader); -} - -static void set_rows_after_error(VP9LfSync *lf_sync, int start_row, int mi_rows, - int num_tiles_left, int total_num_tiles) { - do { - int mi_row; - const int aligned_rows = mi_cols_aligned_to_sb(mi_rows); - const int sb_rows = (aligned_rows >> MI_BLOCK_SIZE_LOG2); - const int corrupted = 1; - for (mi_row = start_row; mi_row < mi_rows; mi_row += MI_BLOCK_SIZE) { - const int is_last_row = (sb_rows - 1 == mi_row >> MI_BLOCK_SIZE_LOG2); - vp9_set_row(lf_sync, total_num_tiles, mi_row >> MI_BLOCK_SIZE_LOG2, - is_last_row, corrupted); - } - /* If there are multiple tiles, the second tile should start marking row - * progress from row 0. - */ - start_row = 0; - } while (num_tiles_left--); -} - -// On entry 'tile_data->data_end' points to the end of the input frame, on exit -// it is updated to reflect the bitreader position of the final tile column if -// present in the tile buffer group or NULL otherwise. -static int tile_worker_hook(void *arg1, void *arg2) { - TileWorkerData *const tile_data = (TileWorkerData *)arg1; - VP9Decoder *const pbi = (VP9Decoder *)arg2; - - TileInfo *volatile tile = &tile_data->xd.tile; - const int final_col = (1 << pbi->common.log2_tile_cols) - 1; - const uint8_t *volatile bit_reader_end = NULL; - VP9_COMMON *cm = &pbi->common; - - LFWorkerData *lf_data = tile_data->lf_data; - VP9LfSync *lf_sync = tile_data->lf_sync; - - volatile int mi_row = 0; - volatile int n = tile_data->buf_start; - if (setjmp(tile_data->error_info.jmp)) { - tile_data->error_info.setjmp = 0; - tile_data->xd.corrupted = 1; - tile_data->data_end = NULL; - if (pbi->lpf_mt_opt && cm->lf.filter_level && !cm->skip_loop_filter) { - const int num_tiles_left = tile_data->buf_end - n; - const int mi_row_start = mi_row; - set_rows_after_error(lf_sync, mi_row_start, cm->mi_rows, num_tiles_left, - 1 << cm->log2_tile_cols); - } - return 0; - } - tile_data->error_info.setjmp = 1; - - tile_data->xd.corrupted = 0; - - do { - int mi_col; - const TileBuffer *const buf = pbi->tile_buffers + n; - - /* Initialize to 0 is safe since we do not deal with streams that have - * more than one row of tiles. (So tile->mi_row_start will be 0) - */ - assert(cm->log2_tile_rows == 0); - mi_row = 0; - vp9_zero(tile_data->dqcoeff); - vp9_tile_init(tile, &pbi->common, 0, buf->col); - setup_token_decoder(buf->data, tile_data->data_end, buf->size, - &tile_data->error_info, &tile_data->bit_reader, - pbi->decrypt_cb, pbi->decrypt_state); - vp9_init_macroblockd(&pbi->common, &tile_data->xd, tile_data->dqcoeff); - // init resets xd.error_info - tile_data->xd.error_info = &tile_data->error_info; - - for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end; - mi_row += MI_BLOCK_SIZE) { - vp9_zero(tile_data->xd.left_context); - vp9_zero(tile_data->xd.left_seg_context); - for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end; - mi_col += MI_BLOCK_SIZE) { - decode_partition(tile_data, pbi, mi_row, mi_col, BLOCK_64X64, 4); - } - if (pbi->lpf_mt_opt && cm->lf.filter_level && !cm->skip_loop_filter) { - const int aligned_rows = mi_cols_aligned_to_sb(cm->mi_rows); - const int sb_rows = (aligned_rows >> MI_BLOCK_SIZE_LOG2); - const int is_last_row = (sb_rows - 1 == mi_row >> MI_BLOCK_SIZE_LOG2); - vp9_set_row(lf_sync, 1 << cm->log2_tile_cols, - mi_row >> MI_BLOCK_SIZE_LOG2, is_last_row, - tile_data->xd.corrupted); - } - } - - if (buf->col == final_col) { - bit_reader_end = vpx_reader_find_end(&tile_data->bit_reader); - } - } while (!tile_data->xd.corrupted && ++n <= tile_data->buf_end); - - if (pbi->lpf_mt_opt && n < tile_data->buf_end && cm->lf.filter_level && - !cm->skip_loop_filter) { - /* This was not incremented in the tile loop, so increment before tiles left - * calculation - */ - ++n; - set_rows_after_error(lf_sync, 0, cm->mi_rows, tile_data->buf_end - n, - 1 << cm->log2_tile_cols); - } - - if (pbi->lpf_mt_opt && !tile_data->xd.corrupted && cm->lf.filter_level && - !cm->skip_loop_filter) { - vp9_loopfilter_rows(lf_data, lf_sync); - } - - tile_data->data_end = bit_reader_end; - return !tile_data->xd.corrupted; -} - -// sorts in descending order -static int compare_tile_buffers(const void *a, const void *b) { - const TileBuffer *const buf_a = (const TileBuffer *)a; - const TileBuffer *const buf_b = (const TileBuffer *)b; - return (buf_a->size < buf_b->size) - (buf_a->size > buf_b->size); -} - -static INLINE void init_mt(VP9Decoder *pbi) { - int n; - VP9_COMMON *const cm = &pbi->common; - VP9LfSync *lf_row_sync = &pbi->lf_row_sync; - const int aligned_mi_cols = mi_cols_aligned_to_sb(cm->mi_cols); - const VPxWorkerInterface *const winterface = vpx_get_worker_interface(); - - if (pbi->num_tile_workers == 0) { - const int num_threads = pbi->max_threads; - CHECK_MEM_ERROR(&cm->error, pbi->tile_workers, - vpx_malloc(num_threads * sizeof(*pbi->tile_workers))); - for (n = 0; n < num_threads; ++n) { - VPxWorker *const worker = &pbi->tile_workers[n]; - ++pbi->num_tile_workers; - - winterface->init(worker); - worker->thread_name = "vpx tile worker"; - if (n < num_threads - 1 && !winterface->reset(worker)) { - do { - winterface->end(&pbi->tile_workers[pbi->num_tile_workers - 1]); - } while (--pbi->num_tile_workers != 0); - vpx_free(pbi->tile_workers); - pbi->tile_workers = NULL; - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "Tile decoder thread creation failed"); - } - } - } - - // Initialize LPF - if ((pbi->lpf_mt_opt || pbi->row_mt) && cm->lf.filter_level && - !cm->skip_loop_filter) { - vp9_lpf_mt_init(lf_row_sync, cm, cm->lf.filter_level, - pbi->num_tile_workers); - } - - // Note: this memset assumes above_context[0], [1] and [2] - // are allocated as part of the same buffer. - memset(cm->above_context, 0, - sizeof(*cm->above_context) * MAX_MB_PLANE * 2 * aligned_mi_cols); - - memset(cm->above_seg_context, 0, - sizeof(*cm->above_seg_context) * aligned_mi_cols); - - vp9_reset_lfm(cm); -} - -static const uint8_t *decode_tiles_row_wise_mt(VP9Decoder *pbi, - const uint8_t *data, - const uint8_t *data_end) { - VP9_COMMON *const cm = &pbi->common; - RowMTWorkerData *const row_mt_worker_data = pbi->row_mt_worker_data; - const VPxWorkerInterface *const winterface = vpx_get_worker_interface(); - const int tile_cols = 1 << cm->log2_tile_cols; - const int tile_rows = 1 << cm->log2_tile_rows; - const int num_workers = pbi->max_threads; - int i, n; - int col; - int corrupted = 0; - const int sb_rows = mi_cols_aligned_to_sb(cm->mi_rows) >> MI_BLOCK_SIZE_LOG2; - const int sb_cols = mi_cols_aligned_to_sb(cm->mi_cols) >> MI_BLOCK_SIZE_LOG2; - VP9LfSync *lf_row_sync = &pbi->lf_row_sync; - YV12_BUFFER_CONFIG *const new_fb = get_frame_new_buffer(cm); - - assert(tile_cols <= (1 << 6)); - assert(tile_rows == 1); - (void)tile_rows; - - memset(row_mt_worker_data->recon_map, 0, - sb_rows * sb_cols * sizeof(*row_mt_worker_data->recon_map)); - - init_mt(pbi); - - // Reset tile decoding hook - for (n = 0; n < num_workers; ++n) { - VPxWorker *const worker = &pbi->tile_workers[n]; - ThreadData *const thread_data = &pbi->row_mt_worker_data->thread_data[n]; - winterface->sync(worker); - - if (cm->lf.filter_level && !cm->skip_loop_filter) { - thread_data->lf_sync = lf_row_sync; - thread_data->lf_data = &thread_data->lf_sync->lfdata[n]; - vp9_loop_filter_data_reset(thread_data->lf_data, new_fb, cm, - pbi->mb.plane); - } - - thread_data->pbi = pbi; - - worker->hook = row_decode_worker_hook; - worker->data1 = thread_data; - worker->data2 = (void *)&row_mt_worker_data->data_end; - } - - for (col = 0; col < tile_cols; ++col) { - TileWorkerData *const tile_data = &pbi->tile_worker_data[col]; - tile_data->xd = pbi->mb; - tile_data->xd.counts = - cm->frame_parallel_decoding_mode ? NULL : &tile_data->counts; - } - - /* Reset the jobq to start of the jobq buffer */ - vp9_jobq_reset(&row_mt_worker_data->jobq); - row_mt_worker_data->num_tiles_done = 0; - row_mt_worker_data->data_end = NULL; - - // Load tile data into tile_buffers - get_tile_buffers(pbi, data, data_end, tile_cols, tile_rows, - &pbi->tile_buffers); - - // Initialize thread frame counts. - if (!cm->frame_parallel_decoding_mode) { - for (col = 0; col < tile_cols; ++col) { - TileWorkerData *const tile_data = &pbi->tile_worker_data[col]; - vp9_zero(tile_data->counts); - } - } - - // queue parse jobs for 0th row of every tile - for (col = 0; col < tile_cols; ++col) { - Job parse_job; - parse_job.row_num = 0; - parse_job.tile_col = col; - parse_job.job_type = PARSE_JOB; - vp9_jobq_queue(&row_mt_worker_data->jobq, &parse_job, sizeof(parse_job)); - } - - for (i = 0; i < num_workers; ++i) { - VPxWorker *const worker = &pbi->tile_workers[i]; - worker->had_error = 0; - if (i == num_workers - 1) { - winterface->execute(worker); - } else { - winterface->launch(worker); - } - } - - for (; n > 0; --n) { - VPxWorker *const worker = &pbi->tile_workers[n - 1]; - // TODO(jzern): The tile may have specific error data associated with - // its vpx_internal_error_info which could be propagated to the main info - // in cm. Additionally once the threads have been synced and an error is - // detected, there's no point in continuing to decode tiles. - corrupted |= !winterface->sync(worker); - } - - pbi->mb.corrupted = corrupted; - - { - /* Set data end */ - TileWorkerData *const tile_data = &pbi->tile_worker_data[tile_cols - 1]; - row_mt_worker_data->data_end = vpx_reader_find_end(&tile_data->bit_reader); - } - - // Accumulate thread frame counts. - if (!cm->frame_parallel_decoding_mode) { - for (i = 0; i < tile_cols; ++i) { - TileWorkerData *const tile_data = &pbi->tile_worker_data[i]; - vp9_accumulate_frame_counts(&cm->counts, &tile_data->counts, 1); - } - } - - return row_mt_worker_data->data_end; -} - -static const uint8_t *decode_tiles_mt(VP9Decoder *pbi, const uint8_t *data, - const uint8_t *data_end) { - VP9_COMMON *const cm = &pbi->common; - const VPxWorkerInterface *const winterface = vpx_get_worker_interface(); - const uint8_t *bit_reader_end = NULL; - VP9LfSync *lf_row_sync = &pbi->lf_row_sync; - YV12_BUFFER_CONFIG *const new_fb = get_frame_new_buffer(cm); - const int tile_cols = 1 << cm->log2_tile_cols; - const int tile_rows = 1 << cm->log2_tile_rows; - const int num_workers = VPXMIN(pbi->max_threads, tile_cols); - int n; - - assert(tile_cols <= (1 << 6)); - assert(tile_rows == 1); - (void)tile_rows; - - init_mt(pbi); - - // Reset tile decoding hook - for (n = 0; n < num_workers; ++n) { - VPxWorker *const worker = &pbi->tile_workers[n]; - TileWorkerData *const tile_data = - &pbi->tile_worker_data[n + pbi->total_tiles]; - winterface->sync(worker); - - if (pbi->lpf_mt_opt && cm->lf.filter_level && !cm->skip_loop_filter) { - tile_data->lf_sync = lf_row_sync; - tile_data->lf_data = &tile_data->lf_sync->lfdata[n]; - vp9_loop_filter_data_reset(tile_data->lf_data, new_fb, cm, pbi->mb.plane); - tile_data->lf_data->y_only = 0; - } - - tile_data->xd = pbi->mb; - tile_data->xd.counts = - cm->frame_parallel_decoding_mode ? NULL : &tile_data->counts; - worker->hook = tile_worker_hook; - worker->data1 = tile_data; - worker->data2 = pbi; - } - - // Load tile data into tile_buffers - get_tile_buffers(pbi, data, data_end, tile_cols, tile_rows, - &pbi->tile_buffers); - - // Sort the buffers based on size in descending order. - qsort(pbi->tile_buffers, tile_cols, sizeof(pbi->tile_buffers[0]), - compare_tile_buffers); - - if (num_workers == tile_cols) { - // Rearrange the tile buffers such that the largest, and - // presumably the most difficult, tile will be decoded in the main thread. - // This should help minimize the number of instances where the main thread - // is waiting for a worker to complete. - const TileBuffer largest = pbi->tile_buffers[0]; - memmove(pbi->tile_buffers, pbi->tile_buffers + 1, - (tile_cols - 1) * sizeof(pbi->tile_buffers[0])); - pbi->tile_buffers[tile_cols - 1] = largest; - } else { - int start = 0, end = tile_cols - 2; - TileBuffer tmp; - - // Interleave the tiles to distribute the load between threads, assuming a - // larger tile implies it is more difficult to decode. - while (start < end) { - tmp = pbi->tile_buffers[start]; - pbi->tile_buffers[start] = pbi->tile_buffers[end]; - pbi->tile_buffers[end] = tmp; - start += 2; - end -= 2; - } - } - - // Initialize thread frame counts. - if (!cm->frame_parallel_decoding_mode) { - for (n = 0; n < num_workers; ++n) { - TileWorkerData *const tile_data = - (TileWorkerData *)pbi->tile_workers[n].data1; - vp9_zero(tile_data->counts); - } - } - - { - const int base = tile_cols / num_workers; - const int remain = tile_cols % num_workers; - int buf_start = 0; - - for (n = 0; n < num_workers; ++n) { - const int count = base + (remain + n) / num_workers; - VPxWorker *const worker = &pbi->tile_workers[n]; - TileWorkerData *const tile_data = (TileWorkerData *)worker->data1; - - tile_data->buf_start = buf_start; - tile_data->buf_end = buf_start + count - 1; - tile_data->data_end = data_end; - buf_start += count; - - worker->had_error = 0; - if (n == num_workers - 1) { - assert(tile_data->buf_end == tile_cols - 1); - winterface->execute(worker); - } else { - winterface->launch(worker); - } - } - - for (; n > 0; --n) { - VPxWorker *const worker = &pbi->tile_workers[n - 1]; - TileWorkerData *const tile_data = (TileWorkerData *)worker->data1; - // TODO(jzern): The tile may have specific error data associated with - // its vpx_internal_error_info which could be propagated to the main info - // in cm. Additionally once the threads have been synced and an error is - // detected, there's no point in continuing to decode tiles. - pbi->mb.corrupted |= !winterface->sync(worker); - if (!bit_reader_end) bit_reader_end = tile_data->data_end; - } - } - - // Accumulate thread frame counts. - if (!cm->frame_parallel_decoding_mode) { - for (n = 0; n < num_workers; ++n) { - TileWorkerData *const tile_data = - (TileWorkerData *)pbi->tile_workers[n].data1; - vp9_accumulate_frame_counts(&cm->counts, &tile_data->counts, 1); - } - } - - assert(bit_reader_end || pbi->mb.corrupted); - return bit_reader_end; -} - -static void error_handler(void *data) { - VP9_COMMON *const cm = (VP9_COMMON *)data; - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet"); -} - -static void read_bitdepth_colorspace_sampling(VP9_COMMON *cm, - struct vpx_read_bit_buffer *rb) { - if (cm->profile >= PROFILE_2) { - cm->bit_depth = vpx_rb_read_bit(rb) ? VPX_BITS_12 : VPX_BITS_10; -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth = 1; -#endif - } else { - cm->bit_depth = VPX_BITS_8; -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth = 0; -#endif - } - cm->color_space = vpx_rb_read_literal(rb, 3); - if (cm->color_space != VPX_CS_SRGB) { - cm->color_range = (vpx_color_range_t)vpx_rb_read_bit(rb); - if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) { - cm->subsampling_x = vpx_rb_read_bit(rb); - cm->subsampling_y = vpx_rb_read_bit(rb); - if (cm->subsampling_x == 1 && cm->subsampling_y == 1) - vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, - "4:2:0 color not supported in profile 1 or 3"); - if (vpx_rb_read_bit(rb)) - vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, - "Reserved bit set"); - } else { - cm->subsampling_y = cm->subsampling_x = 1; - } - } else { - cm->color_range = VPX_CR_FULL_RANGE; - if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) { - // Note if colorspace is SRGB then 4:4:4 chroma sampling is assumed. - // 4:2:2 or 4:4:0 chroma sampling is not allowed. - cm->subsampling_y = cm->subsampling_x = 0; - if (vpx_rb_read_bit(rb)) - vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, - "Reserved bit set"); - } else { - vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, - "4:4:4 color not supported in profile 0 or 2"); - } - } -} - -static INLINE void flush_all_fb_on_key(VP9_COMMON *cm) { - if (cm->frame_type == KEY_FRAME && cm->current_video_frame > 0) { - RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs; - BufferPool *const pool = cm->buffer_pool; - int i; - for (i = 0; i < FRAME_BUFFERS; ++i) { - if (i == cm->new_fb_idx) continue; - frame_bufs[i].ref_count = 0; - if (!frame_bufs[i].released) { - pool->release_fb_cb(pool->cb_priv, &frame_bufs[i].raw_frame_buffer); - frame_bufs[i].released = 1; - } - } - } -} - -static size_t read_uncompressed_header(VP9Decoder *pbi, - struct vpx_read_bit_buffer *rb) { - VP9_COMMON *const cm = &pbi->common; - BufferPool *const pool = cm->buffer_pool; - RefCntBuffer *const frame_bufs = pool->frame_bufs; - int i, mask, ref_index = 0; - size_t sz; - - cm->last_frame_type = cm->frame_type; - cm->last_intra_only = cm->intra_only; - - if (vpx_rb_read_literal(rb, 2) != VP9_FRAME_MARKER) - vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, - "Invalid frame marker"); - - cm->profile = vp9_read_profile(rb); -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->profile >= MAX_PROFILES) - vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, - "Unsupported bitstream profile"); -#else - if (cm->profile >= PROFILE_2) - vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, - "Unsupported bitstream profile"); -#endif - - cm->show_existing_frame = vpx_rb_read_bit(rb); - if (cm->show_existing_frame) { - // Show an existing frame directly. - const int frame_to_show = cm->ref_frame_map[vpx_rb_read_literal(rb, 3)]; - if (frame_to_show < 0 || frame_bufs[frame_to_show].ref_count < 1) { - vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, - "Buffer %d does not contain a decoded frame", - frame_to_show); - } - - ref_cnt_fb(frame_bufs, &cm->new_fb_idx, frame_to_show); - pbi->refresh_frame_flags = 0; - cm->lf.filter_level = 0; - cm->show_frame = 1; - - return 0; - } - - cm->frame_type = (FRAME_TYPE)vpx_rb_read_bit(rb); - cm->show_frame = vpx_rb_read_bit(rb); - cm->error_resilient_mode = vpx_rb_read_bit(rb); - - if (cm->frame_type == KEY_FRAME) { - if (!vp9_read_sync_code(rb)) - vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, - "Invalid frame sync code"); - - read_bitdepth_colorspace_sampling(cm, rb); - pbi->refresh_frame_flags = (1 << REF_FRAMES) - 1; - - for (i = 0; i < REFS_PER_FRAME; ++i) { - cm->frame_refs[i].idx = INVALID_IDX; - cm->frame_refs[i].buf = NULL; - } - - setup_frame_size(cm, rb); - if (pbi->need_resync) { - memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map)); - flush_all_fb_on_key(cm); - pbi->need_resync = 0; - } - } else { - cm->intra_only = cm->show_frame ? 0 : vpx_rb_read_bit(rb); - - cm->reset_frame_context = - cm->error_resilient_mode ? 0 : vpx_rb_read_literal(rb, 2); - - if (cm->intra_only) { - if (!vp9_read_sync_code(rb)) - vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, - "Invalid frame sync code"); - if (cm->profile > PROFILE_0) { - read_bitdepth_colorspace_sampling(cm, rb); - } else { - // NOTE: The intra-only frame header does not include the specification - // of either the color format or color sub-sampling in profile 0. VP9 - // specifies that the default color format should be YUV 4:2:0 in this - // case (normative). - cm->color_space = VPX_CS_BT_601; - cm->color_range = VPX_CR_STUDIO_RANGE; - cm->subsampling_y = cm->subsampling_x = 1; - cm->bit_depth = VPX_BITS_8; -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth = 0; -#endif - } - - pbi->refresh_frame_flags = vpx_rb_read_literal(rb, REF_FRAMES); - setup_frame_size(cm, rb); - if (pbi->need_resync) { - memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map)); - pbi->need_resync = 0; - } - } else if (pbi->need_resync != 1) { /* Skip if need resync */ - pbi->refresh_frame_flags = vpx_rb_read_literal(rb, REF_FRAMES); - for (i = 0; i < REFS_PER_FRAME; ++i) { - const int ref = vpx_rb_read_literal(rb, REF_FRAMES_LOG2); - const int idx = cm->ref_frame_map[ref]; - RefBuffer *const ref_frame = &cm->frame_refs[i]; - ref_frame->idx = idx; - ref_frame->buf = &frame_bufs[idx].buf; - cm->ref_frame_sign_bias[LAST_FRAME + i] = vpx_rb_read_bit(rb); - } - - setup_frame_size_with_refs(cm, rb); - - cm->allow_high_precision_mv = vpx_rb_read_bit(rb); - cm->interp_filter = read_interp_filter(rb); - - for (i = 0; i < REFS_PER_FRAME; ++i) { - RefBuffer *const ref_buf = &cm->frame_refs[i]; -#if CONFIG_VP9_HIGHBITDEPTH - vp9_setup_scale_factors_for_frame( - &ref_buf->sf, ref_buf->buf->y_crop_width, - ref_buf->buf->y_crop_height, cm->width, cm->height, - cm->use_highbitdepth); -#else - vp9_setup_scale_factors_for_frame( - &ref_buf->sf, ref_buf->buf->y_crop_width, - ref_buf->buf->y_crop_height, cm->width, cm->height); -#endif - } - } - } -#if CONFIG_VP9_HIGHBITDEPTH - get_frame_new_buffer(cm)->bit_depth = cm->bit_depth; -#endif - get_frame_new_buffer(cm)->color_space = cm->color_space; - get_frame_new_buffer(cm)->color_range = cm->color_range; - get_frame_new_buffer(cm)->render_width = cm->render_width; - get_frame_new_buffer(cm)->render_height = cm->render_height; - - if (pbi->need_resync) { - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, - "Keyframe / intra-only frame required to reset decoder" - " state"); - } - - if (!cm->error_resilient_mode) { - cm->refresh_frame_context = vpx_rb_read_bit(rb); - cm->frame_parallel_decoding_mode = vpx_rb_read_bit(rb); - if (!cm->frame_parallel_decoding_mode) vp9_zero(cm->counts); - } else { - cm->refresh_frame_context = 0; - cm->frame_parallel_decoding_mode = 1; - } - - // This flag will be overridden by the call to vp9_setup_past_independence - // below, forcing the use of context 0 for those frame types. - cm->frame_context_idx = vpx_rb_read_literal(rb, FRAME_CONTEXTS_LOG2); - - // Generate next_ref_frame_map. - for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) { - if (mask & 1) { - cm->next_ref_frame_map[ref_index] = cm->new_fb_idx; - ++frame_bufs[cm->new_fb_idx].ref_count; - } else { - cm->next_ref_frame_map[ref_index] = cm->ref_frame_map[ref_index]; - } - // Current thread holds the reference frame. - if (cm->ref_frame_map[ref_index] >= 0) - ++frame_bufs[cm->ref_frame_map[ref_index]].ref_count; - ++ref_index; - } - - for (; ref_index < REF_FRAMES; ++ref_index) { - cm->next_ref_frame_map[ref_index] = cm->ref_frame_map[ref_index]; - // Current thread holds the reference frame. - if (cm->ref_frame_map[ref_index] >= 0) - ++frame_bufs[cm->ref_frame_map[ref_index]].ref_count; - } - pbi->hold_ref_buf = 1; - - if (frame_is_intra_only(cm) || cm->error_resilient_mode) - vp9_setup_past_independence(cm); - - setup_loopfilter(&cm->lf, rb); - setup_quantization(cm, &pbi->mb, rb); - setup_segmentation(&cm->seg, rb); - setup_segmentation_dequant(cm); - - setup_tile_info(cm, rb); - if (pbi->row_mt == 1) { - int num_sbs = 1; - const int aligned_rows = mi_cols_aligned_to_sb(cm->mi_rows); - const int sb_rows = aligned_rows >> MI_BLOCK_SIZE_LOG2; - const int num_jobs = sb_rows << cm->log2_tile_cols; - - if (pbi->row_mt_worker_data == NULL) { - CHECK_MEM_ERROR(&cm->error, pbi->row_mt_worker_data, - vpx_calloc(1, sizeof(*pbi->row_mt_worker_data))); -#if CONFIG_MULTITHREAD - pthread_mutex_init(&pbi->row_mt_worker_data->recon_done_mutex, NULL); -#endif - } - - if (pbi->max_threads > 1) { - const int aligned_cols = mi_cols_aligned_to_sb(cm->mi_cols); - const int sb_cols = aligned_cols >> MI_BLOCK_SIZE_LOG2; - - num_sbs = sb_cols * sb_rows; - } - - if (num_sbs > pbi->row_mt_worker_data->num_sbs || - num_jobs > pbi->row_mt_worker_data->num_jobs) { - vp9_dec_free_row_mt_mem(pbi->row_mt_worker_data); - vp9_dec_alloc_row_mt_mem(pbi->row_mt_worker_data, cm, num_sbs, - pbi->max_threads, num_jobs); - } - vp9_jobq_alloc(pbi); - } - sz = vpx_rb_read_literal(rb, 16); - - if (sz == 0) - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, - "Invalid header size"); - - return sz; -} - -static int read_compressed_header(VP9Decoder *pbi, const uint8_t *data, - size_t partition_size) { - VP9_COMMON *const cm = &pbi->common; - MACROBLOCKD *const xd = &pbi->mb; - FRAME_CONTEXT *const fc = cm->fc; - vpx_reader r; - int k; - - if (vpx_reader_init(&r, data, partition_size, pbi->decrypt_cb, - pbi->decrypt_state)) - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate bool decoder 0"); - - cm->tx_mode = xd->lossless ? ONLY_4X4 : read_tx_mode(&r); - if (cm->tx_mode == TX_MODE_SELECT) read_tx_mode_probs(&fc->tx_probs, &r); - read_coef_probs(fc, cm->tx_mode, &r); - - for (k = 0; k < SKIP_CONTEXTS; ++k) - vp9_diff_update_prob(&r, &fc->skip_probs[k]); - - if (!frame_is_intra_only(cm)) { - nmv_context *const nmvc = &fc->nmvc; - int i, j; - - read_inter_mode_probs(fc, &r); - - if (cm->interp_filter == SWITCHABLE) read_switchable_interp_probs(fc, &r); - - for (i = 0; i < INTRA_INTER_CONTEXTS; i++) - vp9_diff_update_prob(&r, &fc->intra_inter_prob[i]); - - cm->reference_mode = read_frame_reference_mode(cm, &r); - if (cm->reference_mode != SINGLE_REFERENCE) - vp9_setup_compound_reference_mode(cm); - read_frame_reference_mode_probs(cm, &r); - - for (j = 0; j < BLOCK_SIZE_GROUPS; j++) - for (i = 0; i < INTRA_MODES - 1; ++i) - vp9_diff_update_prob(&r, &fc->y_mode_prob[j][i]); - - for (j = 0; j < PARTITION_CONTEXTS; ++j) - for (i = 0; i < PARTITION_TYPES - 1; ++i) - vp9_diff_update_prob(&r, &fc->partition_prob[j][i]); - - read_mv_probs(nmvc, cm->allow_high_precision_mv, &r); - } - - return vpx_reader_has_error(&r); -} - -static struct vpx_read_bit_buffer *init_read_bit_buffer( - VP9Decoder *pbi, struct vpx_read_bit_buffer *rb, const uint8_t *data, - const uint8_t *data_end, uint8_t clear_data[MAX_VP9_HEADER_SIZE]) { - rb->bit_offset = 0; - rb->error_handler = error_handler; - rb->error_handler_data = &pbi->common; - if (pbi->decrypt_cb) { - const int n = (int)VPXMIN(MAX_VP9_HEADER_SIZE, data_end - data); - pbi->decrypt_cb(pbi->decrypt_state, data, clear_data, n); - rb->bit_buffer = clear_data; - rb->bit_buffer_end = clear_data + n; - } else { - rb->bit_buffer = data; - rb->bit_buffer_end = data_end; - } - return rb; -} - -//------------------------------------------------------------------------------ - -int vp9_read_sync_code(struct vpx_read_bit_buffer *const rb) { - return vpx_rb_read_literal(rb, 8) == VP9_SYNC_CODE_0 && - vpx_rb_read_literal(rb, 8) == VP9_SYNC_CODE_1 && - vpx_rb_read_literal(rb, 8) == VP9_SYNC_CODE_2; -} - -void vp9_read_frame_size(struct vpx_read_bit_buffer *rb, int *width, - int *height) { - *width = vpx_rb_read_literal(rb, 16) + 1; - *height = vpx_rb_read_literal(rb, 16) + 1; -} - -BITSTREAM_PROFILE vp9_read_profile(struct vpx_read_bit_buffer *rb) { - int profile = vpx_rb_read_bit(rb); - profile |= vpx_rb_read_bit(rb) << 1; - if (profile > 2) profile += vpx_rb_read_bit(rb); - return (BITSTREAM_PROFILE)profile; -} - -void vp9_decode_frame(VP9Decoder *pbi, const uint8_t *data, - const uint8_t *data_end, const uint8_t **p_data_end) { - VP9_COMMON *const cm = &pbi->common; - MACROBLOCKD *const xd = &pbi->mb; - struct vpx_read_bit_buffer rb; - int context_updated = 0; - uint8_t clear_data[MAX_VP9_HEADER_SIZE]; - const size_t first_partition_size = read_uncompressed_header( - pbi, init_read_bit_buffer(pbi, &rb, data, data_end, clear_data)); - const int tile_rows = 1 << cm->log2_tile_rows; - const int tile_cols = 1 << cm->log2_tile_cols; - YV12_BUFFER_CONFIG *const new_fb = get_frame_new_buffer(cm); -#if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG - bitstream_queue_set_frame_read(cm->current_video_frame * 2 + cm->show_frame); -#endif -#if CONFIG_MISMATCH_DEBUG - mismatch_move_frame_idx_r(); -#endif - xd->cur_buf = new_fb; - - if (!first_partition_size) { - // showing a frame directly - *p_data_end = data + (cm->profile <= PROFILE_2 ? 1 : 2); - return; - } - - data += vpx_rb_bytes_read(&rb); - if (!read_is_valid(data, first_partition_size, data_end)) - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, - "Truncated packet or corrupt header length"); - - cm->use_prev_frame_mvs = - !cm->error_resilient_mode && cm->width == cm->last_width && - cm->height == cm->last_height && !cm->last_intra_only && - cm->last_show_frame && (cm->last_frame_type != KEY_FRAME); - - vp9_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y); - - *cm->fc = cm->frame_contexts[cm->frame_context_idx]; - if (!cm->fc->initialized) - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, - "Uninitialized entropy context."); - - xd->corrupted = 0; - new_fb->corrupted = read_compressed_header(pbi, data, first_partition_size); - if (new_fb->corrupted) - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, - "Decode failed. Frame data header is corrupted."); - - if (cm->lf.filter_level && !cm->skip_loop_filter) { - vp9_loop_filter_frame_init(cm, cm->lf.filter_level); - } - - if (pbi->tile_worker_data == NULL || - (tile_cols * tile_rows) != pbi->total_tiles) { - const int num_tile_workers = - tile_cols * tile_rows + ((pbi->max_threads > 1) ? pbi->max_threads : 0); - const size_t twd_size = num_tile_workers * sizeof(*pbi->tile_worker_data); - // Ensure tile data offsets will be properly aligned. This may fail on - // platforms without DECLARE_ALIGNED(). - assert((sizeof(*pbi->tile_worker_data) % 16) == 0); - vpx_free(pbi->tile_worker_data); - CHECK_MEM_ERROR(&cm->error, pbi->tile_worker_data, - vpx_memalign(32, twd_size)); - pbi->total_tiles = tile_rows * tile_cols; - } - - if (pbi->max_threads > 1 && tile_rows == 1 && - (tile_cols > 1 || pbi->row_mt == 1)) { - if (pbi->row_mt == 1) { - *p_data_end = - decode_tiles_row_wise_mt(pbi, data + first_partition_size, data_end); - } else { - // Multi-threaded tile decoder - *p_data_end = decode_tiles_mt(pbi, data + first_partition_size, data_end); - if (!pbi->lpf_mt_opt) { - if (!xd->corrupted) { - if (!cm->skip_loop_filter) { - // If multiple threads are used to decode tiles, then we use those - // threads to do parallel loopfiltering. - vp9_loop_filter_frame_mt( - new_fb, cm, pbi->mb.plane, cm->lf.filter_level, 0, 0, - pbi->tile_workers, pbi->num_tile_workers, &pbi->lf_row_sync); - } - } else { - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, - "Decode failed. Frame data is corrupted."); - } - } - } - } else { - *p_data_end = decode_tiles(pbi, data + first_partition_size, data_end); - } - - if (!xd->corrupted) { - if (!cm->error_resilient_mode && !cm->frame_parallel_decoding_mode) { - vp9_adapt_coef_probs(cm); - - if (!frame_is_intra_only(cm)) { - vp9_adapt_mode_probs(cm); - vp9_adapt_mv_probs(cm, cm->allow_high_precision_mv); - } - } - } else { - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, - "Decode failed. Frame data is corrupted."); - } - - // Non frame parallel update frame context here. - if (cm->refresh_frame_context && !context_updated) - cm->frame_contexts[cm->frame_context_idx] = *cm->fc; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decodeframe.h b/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decodeframe.h deleted file mode 100644 index ba95e723..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decodeframe.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_DECODER_VP9_DECODEFRAME_H_ -#define VPX_VP9_DECODER_VP9_DECODEFRAME_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "vp9/common/vp9_enums.h" - -struct VP9Decoder; -struct vpx_read_bit_buffer; - -int vp9_read_sync_code(struct vpx_read_bit_buffer *const rb); -void vp9_read_frame_size(struct vpx_read_bit_buffer *rb, int *width, - int *height); -BITSTREAM_PROFILE vp9_read_profile(struct vpx_read_bit_buffer *rb); - -void vp9_decode_frame(struct VP9Decoder *pbi, const uint8_t *data, - const uint8_t *data_end, const uint8_t **p_data_end); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_DECODER_VP9_DECODEFRAME_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decodemv.c b/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decodemv.c deleted file mode 100644 index 0989cde5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decodemv.c +++ /dev/null @@ -1,850 +0,0 @@ -/* - Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_entropy.h" -#include "vp9/common/vp9_entropymode.h" -#include "vp9/common/vp9_entropymv.h" -#include "vp9/common/vp9_mvref_common.h" -#include "vp9/common/vp9_pred_common.h" -#include "vp9/common/vp9_reconinter.h" -#include "vp9/common/vp9_seg_common.h" - -#include "vp9/decoder/vp9_decodemv.h" -#include "vp9/decoder/vp9_decodeframe.h" - -#include "vpx_dsp/vpx_dsp_common.h" - -static PREDICTION_MODE read_intra_mode(vpx_reader *r, const vpx_prob *p) { - return (PREDICTION_MODE)vpx_read_tree(r, vp9_intra_mode_tree, p); -} - -static PREDICTION_MODE read_intra_mode_y(VP9_COMMON *cm, MACROBLOCKD *xd, - vpx_reader *r, int size_group) { - const PREDICTION_MODE y_mode = - read_intra_mode(r, cm->fc->y_mode_prob[size_group]); - FRAME_COUNTS *counts = xd->counts; - if (counts) ++counts->y_mode[size_group][y_mode]; - return y_mode; -} - -static PREDICTION_MODE read_intra_mode_uv(VP9_COMMON *cm, MACROBLOCKD *xd, - vpx_reader *r, - PREDICTION_MODE y_mode) { - const PREDICTION_MODE uv_mode = - read_intra_mode(r, cm->fc->uv_mode_prob[y_mode]); - FRAME_COUNTS *counts = xd->counts; - if (counts) ++counts->uv_mode[y_mode][uv_mode]; - return uv_mode; -} - -static PREDICTION_MODE read_inter_mode(VP9_COMMON *cm, MACROBLOCKD *xd, - vpx_reader *r, int ctx) { - const int mode = - vpx_read_tree(r, vp9_inter_mode_tree, cm->fc->inter_mode_probs[ctx]); - FRAME_COUNTS *counts = xd->counts; - if (counts) ++counts->inter_mode[ctx][mode]; - - return NEARESTMV + mode; -} - -static int read_segment_id(vpx_reader *r, const struct segmentation *seg) { - return vpx_read_tree(r, vp9_segment_tree, seg->tree_probs); -} - -static TX_SIZE read_selected_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd, - TX_SIZE max_tx_size, vpx_reader *r) { - FRAME_COUNTS *counts = xd->counts; - const int ctx = get_tx_size_context(xd); - const vpx_prob *tx_probs = get_tx_probs(max_tx_size, ctx, &cm->fc->tx_probs); - int tx_size = vpx_read(r, tx_probs[0]); - if (tx_size != TX_4X4 && max_tx_size >= TX_16X16) { - tx_size += vpx_read(r, tx_probs[1]); - if (tx_size != TX_8X8 && max_tx_size >= TX_32X32) - tx_size += vpx_read(r, tx_probs[2]); - } - - if (counts) ++get_tx_counts(max_tx_size, ctx, &counts->tx)[tx_size]; - return (TX_SIZE)tx_size; -} - -static INLINE TX_SIZE read_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd, - int allow_select, vpx_reader *r) { - TX_MODE tx_mode = cm->tx_mode; - BLOCK_SIZE bsize = xd->mi[0]->sb_type; - const TX_SIZE max_tx_size = max_txsize_lookup[bsize]; - if (allow_select && tx_mode == TX_MODE_SELECT && bsize >= BLOCK_8X8) - return read_selected_tx_size(cm, xd, max_tx_size, r); - else - return VPXMIN(max_tx_size, tx_mode_to_biggest_tx_size[tx_mode]); -} - -static int dec_get_segment_id(const VP9_COMMON *cm, const uint8_t *segment_ids, - int mi_offset, int x_mis, int y_mis) { - int x, y, segment_id = INT_MAX; - - for (y = 0; y < y_mis; y++) - for (x = 0; x < x_mis; x++) - segment_id = - VPXMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]); - - assert(segment_id >= 0 && segment_id < MAX_SEGMENTS); - return segment_id; -} - -static void set_segment_id(VP9_COMMON *cm, int mi_offset, int x_mis, int y_mis, - int segment_id) { - int x, y; - - assert(segment_id >= 0 && segment_id < MAX_SEGMENTS); - - for (y = 0; y < y_mis; y++) - for (x = 0; x < x_mis; x++) - cm->current_frame_seg_map[mi_offset + y * cm->mi_cols + x] = segment_id; -} - -static void copy_segment_id(const VP9_COMMON *cm, - const uint8_t *last_segment_ids, - uint8_t *current_segment_ids, int mi_offset, - int x_mis, int y_mis) { - int x, y; - - for (y = 0; y < y_mis; y++) - for (x = 0; x < x_mis; x++) - current_segment_ids[mi_offset + y * cm->mi_cols + x] = - last_segment_ids ? last_segment_ids[mi_offset + y * cm->mi_cols + x] - : 0; -} - -static int read_intra_segment_id(VP9_COMMON *const cm, int mi_offset, int x_mis, - int y_mis, vpx_reader *r) { - struct segmentation *const seg = &cm->seg; - int segment_id; - - if (!seg->enabled) return 0; // Default for disabled segmentation - - if (!seg->update_map) { - copy_segment_id(cm, cm->last_frame_seg_map, cm->current_frame_seg_map, - mi_offset, x_mis, y_mis); - return 0; - } - - segment_id = read_segment_id(r, seg); - set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id); - return segment_id; -} - -static int read_inter_segment_id(VP9_COMMON *const cm, MACROBLOCKD *const xd, - int mi_row, int mi_col, vpx_reader *r, - int x_mis, int y_mis) { - struct segmentation *const seg = &cm->seg; - MODE_INFO *const mi = xd->mi[0]; - int predicted_segment_id, segment_id; - const int mi_offset = mi_row * cm->mi_cols + mi_col; - - if (!seg->enabled) return 0; // Default for disabled segmentation - - predicted_segment_id = cm->last_frame_seg_map - ? dec_get_segment_id(cm, cm->last_frame_seg_map, - mi_offset, x_mis, y_mis) - : 0; - - if (!seg->update_map) { - copy_segment_id(cm, cm->last_frame_seg_map, cm->current_frame_seg_map, - mi_offset, x_mis, y_mis); - return predicted_segment_id; - } - - if (seg->temporal_update) { - const vpx_prob pred_prob = vp9_get_pred_prob_seg_id(seg, xd); - mi->seg_id_predicted = vpx_read(r, pred_prob); - segment_id = - mi->seg_id_predicted ? predicted_segment_id : read_segment_id(r, seg); - } else { - segment_id = read_segment_id(r, seg); - } - set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id); - return segment_id; -} - -static int read_skip(VP9_COMMON *cm, const MACROBLOCKD *xd, int segment_id, - vpx_reader *r) { - if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) { - return 1; - } else { - const int ctx = vp9_get_skip_context(xd); - const int skip = vpx_read(r, cm->fc->skip_probs[ctx]); - FRAME_COUNTS *counts = xd->counts; - if (counts) ++counts->skip[ctx][skip]; - return skip; - } -} - -static void read_intra_frame_mode_info(VP9_COMMON *const cm, - MACROBLOCKD *const xd, int mi_row, - int mi_col, vpx_reader *r, int x_mis, - int y_mis) { - MODE_INFO *const mi = xd->mi[0]; - const MODE_INFO *above_mi = xd->above_mi; - const MODE_INFO *left_mi = xd->left_mi; - const BLOCK_SIZE bsize = mi->sb_type; - int i; - const int mi_offset = mi_row * cm->mi_cols + mi_col; - - mi->segment_id = read_intra_segment_id(cm, mi_offset, x_mis, y_mis, r); - mi->skip = read_skip(cm, xd, mi->segment_id, r); - mi->tx_size = read_tx_size(cm, xd, 1, r); - mi->ref_frame[0] = INTRA_FRAME; - mi->ref_frame[1] = NO_REF_FRAME; - - switch (bsize) { - case BLOCK_4X4: - for (i = 0; i < 4; ++i) - mi->bmi[i].as_mode = - read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, i)); - mi->mode = mi->bmi[3].as_mode; - break; - case BLOCK_4X8: - mi->bmi[0].as_mode = mi->bmi[2].as_mode = - read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0)); - mi->bmi[1].as_mode = mi->bmi[3].as_mode = mi->mode = - read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 1)); - break; - case BLOCK_8X4: - mi->bmi[0].as_mode = mi->bmi[1].as_mode = - read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0)); - mi->bmi[2].as_mode = mi->bmi[3].as_mode = mi->mode = - read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 2)); - break; - default: - mi->mode = read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0)); - } - - mi->uv_mode = read_intra_mode(r, vp9_kf_uv_mode_prob[mi->mode]); -} - -static int read_mv_component(vpx_reader *r, const nmv_component *mvcomp, - int usehp) { - int mag, d, fr, hp; - const int sign = vpx_read(r, mvcomp->sign); - const int mv_class = vpx_read_tree(r, vp9_mv_class_tree, mvcomp->classes); - const int class0 = mv_class == MV_CLASS_0; - - // Integer part - if (class0) { - d = vpx_read(r, mvcomp->class0[0]); - mag = 0; - } else { - int i; - const int n = mv_class + CLASS0_BITS - 1; // number of bits - - d = 0; - for (i = 0; i < n; ++i) d |= vpx_read(r, mvcomp->bits[i]) << i; - mag = CLASS0_SIZE << (mv_class + 2); - } - - // Fractional part - fr = vpx_read_tree(r, vp9_mv_fp_tree, - class0 ? mvcomp->class0_fp[d] : mvcomp->fp); - - // High precision part (if hp is not used, the default value of the hp is 1) - hp = usehp ? vpx_read(r, class0 ? mvcomp->class0_hp : mvcomp->hp) : 1; - - // Result - mag += ((d << 3) | (fr << 1) | hp) + 1; - return sign ? -mag : mag; -} - -static INLINE void read_mv(vpx_reader *r, MV *mv, const MV *ref, - const nmv_context *ctx, nmv_context_counts *counts, - int allow_hp) { - const MV_JOINT_TYPE joint_type = - (MV_JOINT_TYPE)vpx_read_tree(r, vp9_mv_joint_tree, ctx->joints); - const int use_hp = allow_hp && use_mv_hp(ref); - MV diff = { 0, 0 }; - - if (mv_joint_vertical(joint_type)) - diff.row = read_mv_component(r, &ctx->comps[0], use_hp); - - if (mv_joint_horizontal(joint_type)) - diff.col = read_mv_component(r, &ctx->comps[1], use_hp); - - vp9_inc_mv(&diff, counts); - - mv->row = ref->row + diff.row; - mv->col = ref->col + diff.col; -} - -static REFERENCE_MODE read_block_reference_mode(VP9_COMMON *cm, - const MACROBLOCKD *xd, - vpx_reader *r) { - if (cm->reference_mode == REFERENCE_MODE_SELECT) { - const int ctx = vp9_get_reference_mode_context(cm, xd); - const REFERENCE_MODE mode = - (REFERENCE_MODE)vpx_read(r, cm->fc->comp_inter_prob[ctx]); - FRAME_COUNTS *counts = xd->counts; - if (counts) ++counts->comp_inter[ctx][mode]; - return mode; // SINGLE_REFERENCE or COMPOUND_REFERENCE - } else { - return cm->reference_mode; - } -} - -// Read the reference frame -static void read_ref_frames(VP9_COMMON *const cm, MACROBLOCKD *const xd, - vpx_reader *r, int segment_id, - MV_REFERENCE_FRAME ref_frame[2]) { - FRAME_CONTEXT *const fc = cm->fc; - FRAME_COUNTS *counts = xd->counts; - - if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) { - ref_frame[0] = (MV_REFERENCE_FRAME)get_segdata(&cm->seg, segment_id, - SEG_LVL_REF_FRAME); - ref_frame[1] = NO_REF_FRAME; - } else { - const REFERENCE_MODE mode = read_block_reference_mode(cm, xd, r); - // FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding - if (mode == COMPOUND_REFERENCE) { - const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref]; - const int ctx = vp9_get_pred_context_comp_ref_p(cm, xd); - const int bit = vpx_read(r, fc->comp_ref_prob[ctx]); - if (counts) ++counts->comp_ref[ctx][bit]; - ref_frame[idx] = cm->comp_fixed_ref; - ref_frame[!idx] = cm->comp_var_ref[bit]; - } else if (mode == SINGLE_REFERENCE) { - const int ctx0 = vp9_get_pred_context_single_ref_p1(xd); - const int bit0 = vpx_read(r, fc->single_ref_prob[ctx0][0]); - if (counts) ++counts->single_ref[ctx0][0][bit0]; - if (bit0) { - const int ctx1 = vp9_get_pred_context_single_ref_p2(xd); - const int bit1 = vpx_read(r, fc->single_ref_prob[ctx1][1]); - if (counts) ++counts->single_ref[ctx1][1][bit1]; - ref_frame[0] = bit1 ? ALTREF_FRAME : GOLDEN_FRAME; - } else { - ref_frame[0] = LAST_FRAME; - } - - ref_frame[1] = NO_REF_FRAME; - } else { - assert(0 && "Invalid prediction mode."); - } - } -} - -static INLINE INTERP_FILTER read_switchable_interp_filter(VP9_COMMON *const cm, - MACROBLOCKD *const xd, - vpx_reader *r) { - const int ctx = get_pred_context_switchable_interp(xd); - const INTERP_FILTER type = (INTERP_FILTER)vpx_read_tree( - r, vp9_switchable_interp_tree, cm->fc->switchable_interp_prob[ctx]); - FRAME_COUNTS *counts = xd->counts; - if (counts) ++counts->switchable_interp[ctx][type]; - return type; -} - -static void read_intra_block_mode_info(VP9_COMMON *const cm, - MACROBLOCKD *const xd, MODE_INFO *mi, - vpx_reader *r) { - const BLOCK_SIZE bsize = mi->sb_type; - int i; - - switch (bsize) { - case BLOCK_4X4: - for (i = 0; i < 4; ++i) - mi->bmi[i].as_mode = read_intra_mode_y(cm, xd, r, 0); - mi->mode = mi->bmi[3].as_mode; - break; - case BLOCK_4X8: - mi->bmi[0].as_mode = mi->bmi[2].as_mode = read_intra_mode_y(cm, xd, r, 0); - mi->bmi[1].as_mode = mi->bmi[3].as_mode = mi->mode = - read_intra_mode_y(cm, xd, r, 0); - break; - case BLOCK_8X4: - mi->bmi[0].as_mode = mi->bmi[1].as_mode = read_intra_mode_y(cm, xd, r, 0); - mi->bmi[2].as_mode = mi->bmi[3].as_mode = mi->mode = - read_intra_mode_y(cm, xd, r, 0); - break; - default: mi->mode = read_intra_mode_y(cm, xd, r, size_group_lookup[bsize]); - } - - mi->uv_mode = read_intra_mode_uv(cm, xd, r, mi->mode); - - // Initialize interp_filter here so we do not have to check for inter block - // modes in get_pred_context_switchable_interp() - mi->interp_filter = SWITCHABLE_FILTERS; - - mi->ref_frame[0] = INTRA_FRAME; - mi->ref_frame[1] = NO_REF_FRAME; -} - -static INLINE int is_mv_valid(const MV *mv) { - return mv->row > MV_LOW && mv->row < MV_UPP && mv->col > MV_LOW && - mv->col < MV_UPP; -} - -static INLINE void copy_mv_pair(int_mv *dst, const int_mv *src) { - memcpy(dst, src, sizeof(*dst) * 2); -} - -static INLINE void zero_mv_pair(int_mv *dst) { - memset(dst, 0, sizeof(*dst) * 2); -} - -static INLINE int assign_mv(VP9_COMMON *cm, MACROBLOCKD *xd, - PREDICTION_MODE mode, int_mv mv[2], - int_mv ref_mv[2], int_mv near_nearest_mv[2], - int is_compound, int allow_hp, vpx_reader *r) { - int i; - int ret = 1; - - switch (mode) { - case NEWMV: { - FRAME_COUNTS *counts = xd->counts; - nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL; - for (i = 0; i < 1 + is_compound; ++i) { - read_mv(r, &mv[i].as_mv, &ref_mv[i].as_mv, &cm->fc->nmvc, mv_counts, - allow_hp); - ret = ret && is_mv_valid(&mv[i].as_mv); - } - break; - } - case NEARMV: - case NEARESTMV: { - copy_mv_pair(mv, near_nearest_mv); - break; - } - case ZEROMV: { - zero_mv_pair(mv); - break; - } - default: { - return 0; - } - } - return ret; -} - -static int read_is_inter_block(VP9_COMMON *const cm, MACROBLOCKD *const xd, - int segment_id, vpx_reader *r) { - if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) { - return get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME) != INTRA_FRAME; - } else { - const int ctx = get_intra_inter_context(xd); - const int is_inter = vpx_read(r, cm->fc->intra_inter_prob[ctx]); - FRAME_COUNTS *counts = xd->counts; - if (counts) ++counts->intra_inter[ctx][is_inter]; - return is_inter; - } -} - -// This macro is used to add a motion vector mv_ref list if it isn't -// already in the list. If it's the second motion vector or early_break -// it will also skip all additional processing and jump to Done! -#define ADD_MV_REF_LIST_EB(mv, refmv_count, mv_ref_list, Done) \ - do { \ - if (refmv_count) { \ - if ((mv).as_int != (mv_ref_list)[0].as_int) { \ - (mv_ref_list)[(refmv_count)] = (mv); \ - refmv_count++; \ - goto Done; \ - } \ - } else { \ - (mv_ref_list)[(refmv_count)++] = (mv); \ - if (early_break) goto Done; \ - } \ - } while (0) - -// If either reference frame is different, not INTRA, and they -// are different from each other scale and add the mv to our list. -#define IF_DIFF_REF_FRAME_ADD_MV_EB(mbmi, ref_frame, ref_sign_bias, \ - refmv_count, mv_ref_list, Done) \ - do { \ - if (is_inter_block(mbmi)) { \ - if ((mbmi)->ref_frame[0] != ref_frame) \ - ADD_MV_REF_LIST_EB(scale_mv((mbmi), 0, ref_frame, ref_sign_bias), \ - refmv_count, mv_ref_list, Done); \ - if (has_second_ref(mbmi) && (mbmi)->ref_frame[1] != ref_frame && \ - (mbmi)->mv[1].as_int != (mbmi)->mv[0].as_int) \ - ADD_MV_REF_LIST_EB(scale_mv((mbmi), 1, ref_frame, ref_sign_bias), \ - refmv_count, mv_ref_list, Done); \ - } \ - } while (0) - -// This function searches the neighborhood of a given MB/SB -// to try and find candidate reference vectors. -static int dec_find_mv_refs(const VP9_COMMON *cm, const MACROBLOCKD *xd, - PREDICTION_MODE mode, MV_REFERENCE_FRAME ref_frame, - const POSITION *const mv_ref_search, - int_mv *mv_ref_list, int mi_row, int mi_col, - int block) { - const int *ref_sign_bias = cm->ref_frame_sign_bias; - int i, refmv_count = 0; - int different_ref_found = 0; - const MV_REF *const prev_frame_mvs = - cm->use_prev_frame_mvs - ? cm->prev_frame->mvs + mi_row * cm->mi_cols + mi_col - : NULL; - const TileInfo *const tile = &xd->tile; - // If mode is nearestmv or newmv (uses nearestmv as a reference) then stop - // searching after the first mv is found. - const int early_break = (mode != NEARMV); - - // Blank the reference vector list - memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES); - - i = 0; - if (block >= 0) { - // If the size < 8x8 we get the mv from the bmi substructure for the - // nearest two blocks. - for (i = 0; i < 2; ++i) { - const POSITION *const mv_ref = &mv_ref_search[i]; - if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { - const MODE_INFO *const candidate_mi = - xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; - different_ref_found = 1; - - if (candidate_mi->ref_frame[0] == ref_frame) - ADD_MV_REF_LIST_EB( - get_sub_block_mv(candidate_mi, 0, mv_ref->col, block), - refmv_count, mv_ref_list, Done); - else if (candidate_mi->ref_frame[1] == ref_frame) - ADD_MV_REF_LIST_EB( - get_sub_block_mv(candidate_mi, 1, mv_ref->col, block), - refmv_count, mv_ref_list, Done); - } - } - } - - // Check the rest of the neighbors in much the same way - // as before except we don't need to keep track of sub blocks or - // mode counts. - for (; i < MVREF_NEIGHBOURS; ++i) { - const POSITION *const mv_ref = &mv_ref_search[i]; - if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { - const MODE_INFO *const candidate = - xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; - different_ref_found = 1; - - if (candidate->ref_frame[0] == ref_frame) - ADD_MV_REF_LIST_EB(candidate->mv[0], refmv_count, mv_ref_list, Done); - else if (candidate->ref_frame[1] == ref_frame) - ADD_MV_REF_LIST_EB(candidate->mv[1], refmv_count, mv_ref_list, Done); - } - } - - // Check the last frame's mode and mv info. - if (prev_frame_mvs) { - if (prev_frame_mvs->ref_frame[0] == ref_frame) { - ADD_MV_REF_LIST_EB(prev_frame_mvs->mv[0], refmv_count, mv_ref_list, Done); - } else if (prev_frame_mvs->ref_frame[1] == ref_frame) { - ADD_MV_REF_LIST_EB(prev_frame_mvs->mv[1], refmv_count, mv_ref_list, Done); - } - } - - // Since we couldn't find 2 mvs from the same reference frame - // go back through the neighbors and find motion vectors from - // different reference frames. - if (different_ref_found) { - for (i = 0; i < MVREF_NEIGHBOURS; ++i) { - const POSITION *mv_ref = &mv_ref_search[i]; - if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { - const MODE_INFO *const candidate = - xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; - - // If the candidate is INTRA we don't want to consider its mv. - IF_DIFF_REF_FRAME_ADD_MV_EB(candidate, ref_frame, ref_sign_bias, - refmv_count, mv_ref_list, Done); - } - } - } - - // Since we still don't have a candidate we'll try the last frame. - if (prev_frame_mvs) { - if (prev_frame_mvs->ref_frame[0] != ref_frame && - prev_frame_mvs->ref_frame[0] > INTRA_FRAME) { - int_mv mv = prev_frame_mvs->mv[0]; - if (ref_sign_bias[prev_frame_mvs->ref_frame[0]] != - ref_sign_bias[ref_frame]) { - mv.as_mv.row *= -1; - mv.as_mv.col *= -1; - } - ADD_MV_REF_LIST_EB(mv, refmv_count, mv_ref_list, Done); - } - - if (prev_frame_mvs->ref_frame[1] > INTRA_FRAME && - prev_frame_mvs->ref_frame[1] != ref_frame && - prev_frame_mvs->mv[1].as_int != prev_frame_mvs->mv[0].as_int) { - int_mv mv = prev_frame_mvs->mv[1]; - if (ref_sign_bias[prev_frame_mvs->ref_frame[1]] != - ref_sign_bias[ref_frame]) { - mv.as_mv.row *= -1; - mv.as_mv.col *= -1; - } - ADD_MV_REF_LIST_EB(mv, refmv_count, mv_ref_list, Done); - } - } - - if (mode == NEARMV) - refmv_count = MAX_MV_REF_CANDIDATES; - else - // we only care about the nearestmv for the remaining modes - refmv_count = 1; - -Done: - // Clamp vectors - for (i = 0; i < refmv_count; ++i) clamp_mv_ref(&mv_ref_list[i].as_mv, xd); - - return refmv_count; -} - -static void append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd, - const POSITION *const mv_ref_search, - PREDICTION_MODE b_mode, int block, - int ref, int mi_row, int mi_col, - int_mv *best_sub8x8) { - int_mv mv_list[MAX_MV_REF_CANDIDATES]; - MODE_INFO *const mi = xd->mi[0]; - b_mode_info *bmi = mi->bmi; - int n; - int refmv_count; - - assert(MAX_MV_REF_CANDIDATES == 2); - - switch (block) { - case 0: - refmv_count = - dec_find_mv_refs(cm, xd, b_mode, mi->ref_frame[ref], mv_ref_search, - mv_list, mi_row, mi_col, block); - best_sub8x8->as_int = mv_list[refmv_count - 1].as_int; - break; - case 1: - case 2: - if (b_mode == NEARESTMV) { - best_sub8x8->as_int = bmi[0].as_mv[ref].as_int; - } else { - dec_find_mv_refs(cm, xd, b_mode, mi->ref_frame[ref], mv_ref_search, - mv_list, mi_row, mi_col, block); - best_sub8x8->as_int = 0; - for (n = 0; n < 2; ++n) - if (bmi[0].as_mv[ref].as_int != mv_list[n].as_int) { - best_sub8x8->as_int = mv_list[n].as_int; - break; - } - } - break; - case 3: - if (b_mode == NEARESTMV) { - best_sub8x8->as_int = bmi[2].as_mv[ref].as_int; - } else { - best_sub8x8->as_int = 0; - if (bmi[2].as_mv[ref].as_int != bmi[1].as_mv[ref].as_int) { - best_sub8x8->as_int = bmi[1].as_mv[ref].as_int; - break; - } - if (bmi[2].as_mv[ref].as_int != bmi[0].as_mv[ref].as_int) { - best_sub8x8->as_int = bmi[0].as_mv[ref].as_int; - break; - } - dec_find_mv_refs(cm, xd, b_mode, mi->ref_frame[ref], mv_ref_search, - mv_list, mi_row, mi_col, block); - for (n = 0; n < 2; ++n) - if (bmi[2].as_mv[ref].as_int != mv_list[n].as_int) { - best_sub8x8->as_int = mv_list[n].as_int; - break; - } - } - break; - default: assert(0 && "Invalid block index."); - } -} - -static uint8_t get_mode_context(const VP9_COMMON *cm, const MACROBLOCKD *xd, - const POSITION *const mv_ref_search, int mi_row, - int mi_col) { - int i; - int context_counter = 0; - const TileInfo *const tile = &xd->tile; - - // Get mode count from nearest 2 blocks - for (i = 0; i < 2; ++i) { - const POSITION *const mv_ref = &mv_ref_search[i]; - if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { - const MODE_INFO *const candidate = - xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; - // Keep counts for entropy encoding. - context_counter += mode_2_counter[candidate->mode]; - } - } - - return counter_to_context[context_counter]; -} - -static void read_inter_block_mode_info(VP9Decoder *const pbi, - MACROBLOCKD *const xd, - MODE_INFO *const mi, int mi_row, - int mi_col, vpx_reader *r) { - VP9_COMMON *const cm = &pbi->common; - const BLOCK_SIZE bsize = mi->sb_type; - const int allow_hp = cm->allow_high_precision_mv; - int_mv best_ref_mvs[2] = { { 0 }, { 0 } }; - int ref, is_compound; - uint8_t inter_mode_ctx; - const POSITION *const mv_ref_search = mv_ref_blocks[bsize]; - - read_ref_frames(cm, xd, r, mi->segment_id, mi->ref_frame); - is_compound = has_second_ref(mi); - inter_mode_ctx = get_mode_context(cm, xd, mv_ref_search, mi_row, mi_col); - - if (segfeature_active(&cm->seg, mi->segment_id, SEG_LVL_SKIP)) { - mi->mode = ZEROMV; - if (bsize < BLOCK_8X8) { - vpx_internal_error(xd->error_info, VPX_CODEC_UNSUP_BITSTREAM, - "Invalid usage of segment feature on small blocks"); - return; - } - } else { - if (bsize >= BLOCK_8X8) - mi->mode = read_inter_mode(cm, xd, r, inter_mode_ctx); - } - - mi->interp_filter = (cm->interp_filter == SWITCHABLE) - ? read_switchable_interp_filter(cm, xd, r) - : cm->interp_filter; - - if (bsize < BLOCK_8X8) { - const int num_4x4_w = 1 << xd->bmode_blocks_wl; - const int num_4x4_h = 1 << xd->bmode_blocks_hl; - int idx, idy; - PREDICTION_MODE b_mode; - int got_mv_refs_for_new = 0; - int_mv best_sub8x8[2]; - const uint32_t invalid_mv = 0x80008000; - // Initialize the 2nd element as even though it won't be used meaningfully - // if is_compound is false, copying/clamping it may trigger a MSan warning. - best_sub8x8[1].as_int = invalid_mv; - for (idy = 0; idy < 2; idy += num_4x4_h) { - for (idx = 0; idx < 2; idx += num_4x4_w) { - const int j = idy * 2 + idx; - b_mode = read_inter_mode(cm, xd, r, inter_mode_ctx); - - if (b_mode == NEARESTMV || b_mode == NEARMV) { - for (ref = 0; ref < 1 + is_compound; ++ref) - append_sub8x8_mvs_for_idx(cm, xd, mv_ref_search, b_mode, j, ref, - mi_row, mi_col, &best_sub8x8[ref]); - } else if (b_mode == NEWMV && !got_mv_refs_for_new) { - for (ref = 0; ref < 1 + is_compound; ++ref) { - int_mv tmp_mvs[MAX_MV_REF_CANDIDATES]; - const MV_REFERENCE_FRAME frame = mi->ref_frame[ref]; - - dec_find_mv_refs(cm, xd, NEWMV, frame, mv_ref_search, tmp_mvs, - mi_row, mi_col, -1); - - lower_mv_precision(&tmp_mvs[0].as_mv, allow_hp); - best_ref_mvs[ref] = tmp_mvs[0]; - got_mv_refs_for_new = 1; - } - } - - if (!assign_mv(cm, xd, b_mode, mi->bmi[j].as_mv, best_ref_mvs, - best_sub8x8, is_compound, allow_hp, r)) { - xd->corrupted |= 1; - return; - } - - if (num_4x4_h == 2) mi->bmi[j + 2] = mi->bmi[j]; - if (num_4x4_w == 2) mi->bmi[j + 1] = mi->bmi[j]; - } - } - - mi->mode = b_mode; - - copy_mv_pair(mi->mv, mi->bmi[3].as_mv); - } else { - if (mi->mode != ZEROMV) { - for (ref = 0; ref < 1 + is_compound; ++ref) { - int_mv tmp_mvs[MAX_MV_REF_CANDIDATES]; - const MV_REFERENCE_FRAME frame = mi->ref_frame[ref]; - int refmv_count = - dec_find_mv_refs(cm, xd, mi->mode, frame, mv_ref_search, tmp_mvs, - mi_row, mi_col, -1); - lower_mv_precision(&tmp_mvs[refmv_count - 1].as_mv, allow_hp); - best_ref_mvs[ref] = tmp_mvs[refmv_count - 1]; - } - } - xd->corrupted |= !assign_mv(cm, xd, mi->mode, mi->mv, best_ref_mvs, - best_ref_mvs, is_compound, allow_hp, r); - } -} - -static void read_inter_frame_mode_info(VP9Decoder *const pbi, - MACROBLOCKD *const xd, int mi_row, - int mi_col, vpx_reader *r, int x_mis, - int y_mis) { - VP9_COMMON *const cm = &pbi->common; - MODE_INFO *const mi = xd->mi[0]; - int inter_block; - - mi->segment_id = - read_inter_segment_id(cm, xd, mi_row, mi_col, r, x_mis, y_mis); - mi->skip = read_skip(cm, xd, mi->segment_id, r); - inter_block = read_is_inter_block(cm, xd, mi->segment_id, r); - mi->tx_size = read_tx_size(cm, xd, !mi->skip || !inter_block, r); - - if (inter_block) - read_inter_block_mode_info(pbi, xd, mi, mi_row, mi_col, r); - else - read_intra_block_mode_info(cm, xd, mi, r); -} - -static INLINE void copy_ref_frame_pair(MV_REFERENCE_FRAME *dst, - const MV_REFERENCE_FRAME *src) { - memcpy(dst, src, sizeof(*dst) * 2); -} - -void vp9_read_mode_info(TileWorkerData *twd, VP9Decoder *const pbi, int mi_row, - int mi_col, int x_mis, int y_mis) { - vpx_reader *r = &twd->bit_reader; - MACROBLOCKD *const xd = &twd->xd; - VP9_COMMON *const cm = &pbi->common; - MODE_INFO *const mi = xd->mi[0]; - MV_REF *frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col; - int w, h; - - if (frame_is_intra_only(cm)) { - read_intra_frame_mode_info(cm, xd, mi_row, mi_col, r, x_mis, y_mis); - } else { - // Cache mi->ref_frame and mi->mv so that the compiler can prove that they - // are constant for the duration of the loop and avoids reloading them. - MV_REFERENCE_FRAME mi_ref_frame[2]; - int_mv mi_mv[2]; - - read_inter_frame_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis); - - copy_ref_frame_pair(mi_ref_frame, mi->ref_frame); - copy_mv_pair(mi_mv, mi->mv); - - for (h = 0; h < y_mis; ++h) { - for (w = 0; w < x_mis; ++w) { - MV_REF *const mv = frame_mvs + w; - copy_ref_frame_pair(mv->ref_frame, mi_ref_frame); - copy_mv_pair(mv->mv, mi_mv); - } - frame_mvs += cm->mi_cols; - } - } -#if 0 // CONFIG_BETTER_HW_COMPATIBILITY && CONFIG_VP9_HIGHBITDEPTH - if ((xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) && - (xd->above_mi == NULL || xd->left_mi == NULL) && - !is_inter_block(mi) && need_top_left[mi->uv_mode]) - assert(0); -#endif // CONFIG_BETTER_HW_COMPATIBILITY && CONFIG_VP9_HIGHBITDEPTH -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decodemv.h b/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decodemv.h deleted file mode 100644 index 11b45ace..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decodemv.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_DECODER_VP9_DECODEMV_H_ -#define VPX_VP9_DECODER_VP9_DECODEMV_H_ - -#include "vpx_dsp/bitreader.h" - -#include "vp9/decoder/vp9_decoder.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vp9_read_mode_info(TileWorkerData *twd, VP9Decoder *const pbi, int mi_row, - int mi_col, int x_mis, int y_mis); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_DECODER_VP9_DECODEMV_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decoder.c b/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decoder.c deleted file mode 100644 index 5c77df50..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decoder.c +++ /dev/null @@ -1,587 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "./vp9_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "./vpx_scale_rtcd.h" - -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/system_state.h" -#include "vpx_ports/vpx_once.h" -#include "vpx_ports/vpx_timer.h" -#include "vpx_scale/vpx_scale.h" -#include "vpx_util/vpx_pthread.h" -#include "vpx_util/vpx_thread.h" - -#include "vp9/common/vp9_alloccommon.h" -#include "vp9/common/vp9_loopfilter.h" -#include "vp9/common/vp9_onyxc_int.h" -#if CONFIG_VP9_POSTPROC -#include "vp9/common/vp9_postproc.h" -#endif -#include "vp9/common/vp9_quant_common.h" -#include "vp9/common/vp9_reconintra.h" - -#include "vp9/decoder/vp9_decodeframe.h" -#include "vp9/decoder/vp9_decoder.h" -#include "vp9/decoder/vp9_detokenize.h" - -static void initialize_dec(void) { - static volatile int init_done = 0; - - if (!init_done) { - vp9_rtcd(); - vpx_dsp_rtcd(); - vpx_scale_rtcd(); - vp9_init_intra_predictors(); - init_done = 1; - } -} - -static void vp9_dec_setup_mi(VP9_COMMON *cm) { - cm->mi = cm->mip + cm->mi_stride + 1; - cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1; - memset(cm->mi_grid_base, 0, - cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mi_grid_base)); -} - -void vp9_dec_alloc_row_mt_mem(RowMTWorkerData *row_mt_worker_data, - VP9_COMMON *cm, int num_sbs, int max_threads, - int num_jobs) { - int plane; - const size_t dqcoeff_size = (num_sbs << DQCOEFFS_PER_SB_LOG2) * - sizeof(*row_mt_worker_data->dqcoeff[0]); - row_mt_worker_data->num_jobs = num_jobs; -#if CONFIG_MULTITHREAD - { - int i; - CHECK_MEM_ERROR( - &cm->error, row_mt_worker_data->recon_sync_mutex, - vpx_malloc(sizeof(*row_mt_worker_data->recon_sync_mutex) * num_jobs)); - if (row_mt_worker_data->recon_sync_mutex) { - for (i = 0; i < num_jobs; ++i) { - pthread_mutex_init(&row_mt_worker_data->recon_sync_mutex[i], NULL); - } - } - - CHECK_MEM_ERROR( - &cm->error, row_mt_worker_data->recon_sync_cond, - vpx_malloc(sizeof(*row_mt_worker_data->recon_sync_cond) * num_jobs)); - if (row_mt_worker_data->recon_sync_cond) { - for (i = 0; i < num_jobs; ++i) { - pthread_cond_init(&row_mt_worker_data->recon_sync_cond[i], NULL); - } - } - } -#endif - row_mt_worker_data->num_sbs = num_sbs; - for (plane = 0; plane < 3; ++plane) { - CHECK_MEM_ERROR(&cm->error, row_mt_worker_data->dqcoeff[plane], - vpx_memalign(32, dqcoeff_size)); - memset(row_mt_worker_data->dqcoeff[plane], 0, dqcoeff_size); - CHECK_MEM_ERROR(&cm->error, row_mt_worker_data->eob[plane], - vpx_calloc(num_sbs << EOBS_PER_SB_LOG2, - sizeof(*row_mt_worker_data->eob[plane]))); - } - CHECK_MEM_ERROR(&cm->error, row_mt_worker_data->partition, - vpx_calloc(num_sbs * PARTITIONS_PER_SB, - sizeof(*row_mt_worker_data->partition))); - CHECK_MEM_ERROR(&cm->error, row_mt_worker_data->recon_map, - vpx_calloc(num_sbs, sizeof(*row_mt_worker_data->recon_map))); - - // allocate memory for thread_data - if (row_mt_worker_data->thread_data == NULL) { - const size_t thread_size = - max_threads * sizeof(*row_mt_worker_data->thread_data); - CHECK_MEM_ERROR(&cm->error, row_mt_worker_data->thread_data, - vpx_memalign(32, thread_size)); - } -} - -void vp9_dec_free_row_mt_mem(RowMTWorkerData *row_mt_worker_data) { - if (row_mt_worker_data != NULL) { - int plane; -#if CONFIG_MULTITHREAD - int i; - if (row_mt_worker_data->recon_sync_mutex != NULL) { - for (i = 0; i < row_mt_worker_data->num_jobs; ++i) { - pthread_mutex_destroy(&row_mt_worker_data->recon_sync_mutex[i]); - } - vpx_free(row_mt_worker_data->recon_sync_mutex); - row_mt_worker_data->recon_sync_mutex = NULL; - } - if (row_mt_worker_data->recon_sync_cond != NULL) { - for (i = 0; i < row_mt_worker_data->num_jobs; ++i) { - pthread_cond_destroy(&row_mt_worker_data->recon_sync_cond[i]); - } - vpx_free(row_mt_worker_data->recon_sync_cond); - row_mt_worker_data->recon_sync_cond = NULL; - } -#endif - for (plane = 0; plane < 3; ++plane) { - vpx_free(row_mt_worker_data->eob[plane]); - row_mt_worker_data->eob[plane] = NULL; - vpx_free(row_mt_worker_data->dqcoeff[plane]); - row_mt_worker_data->dqcoeff[plane] = NULL; - } - vpx_free(row_mt_worker_data->partition); - row_mt_worker_data->partition = NULL; - vpx_free(row_mt_worker_data->recon_map); - row_mt_worker_data->recon_map = NULL; - vpx_free(row_mt_worker_data->thread_data); - row_mt_worker_data->thread_data = NULL; - } -} - -static int vp9_dec_alloc_mi(VP9_COMMON *cm, int mi_size) { - cm->mip = vpx_calloc(mi_size, sizeof(*cm->mip)); - if (!cm->mip) return 1; - cm->mi_alloc_size = mi_size; - cm->mi_grid_base = (MODE_INFO **)vpx_calloc(mi_size, sizeof(MODE_INFO *)); - if (!cm->mi_grid_base) return 1; - return 0; -} - -static void vp9_dec_free_mi(VP9_COMMON *cm) { -#if CONFIG_VP9_POSTPROC - // MFQE allocates an additional mip and swaps it with cm->mip. - vpx_free(cm->postproc_state.prev_mip); - cm->postproc_state.prev_mip = NULL; -#endif - vpx_free(cm->mip); - cm->mip = NULL; - vpx_free(cm->mi_grid_base); - cm->mi_grid_base = NULL; - cm->mi_alloc_size = 0; -} - -VP9Decoder *vp9_decoder_create(BufferPool *const pool) { - VP9Decoder *volatile const pbi = vpx_memalign(32, sizeof(*pbi)); - VP9_COMMON *volatile const cm = pbi ? &pbi->common : NULL; - - if (!cm) return NULL; - - vp9_zero(*pbi); - - if (setjmp(cm->error.jmp)) { - cm->error.setjmp = 0; - vp9_decoder_remove(pbi); - return NULL; - } - - cm->error.setjmp = 1; - - CHECK_MEM_ERROR(&cm->error, cm->fc, - (FRAME_CONTEXT *)vpx_calloc(1, sizeof(*cm->fc))); - CHECK_MEM_ERROR( - &cm->error, cm->frame_contexts, - (FRAME_CONTEXT *)vpx_calloc(FRAME_CONTEXTS, sizeof(*cm->frame_contexts))); - - pbi->need_resync = 1; - once(initialize_dec); - - // Initialize the references to not point to any frame buffers. - memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map)); - memset(&cm->next_ref_frame_map, -1, sizeof(cm->next_ref_frame_map)); - - init_frame_indexes(cm); - pbi->ready_for_new_data = 1; - pbi->common.buffer_pool = pool; - - cm->bit_depth = VPX_BITS_8; - cm->dequant_bit_depth = VPX_BITS_8; - - cm->alloc_mi = vp9_dec_alloc_mi; - cm->free_mi = vp9_dec_free_mi; - cm->setup_mi = vp9_dec_setup_mi; - - vp9_loop_filter_init(cm); - - cm->error.setjmp = 0; - - vpx_get_worker_interface()->init(&pbi->lf_worker); - pbi->lf_worker.thread_name = "vpx lf worker"; - - return pbi; -} - -void vp9_decoder_remove(VP9Decoder *pbi) { - int i; - - if (!pbi) return; - - vpx_get_worker_interface()->end(&pbi->lf_worker); - vpx_free(pbi->lf_worker.data1); - - for (i = 0; i < pbi->num_tile_workers; ++i) { - VPxWorker *const worker = &pbi->tile_workers[i]; - vpx_get_worker_interface()->end(worker); - } - - vpx_free(pbi->tile_worker_data); - vpx_free(pbi->tile_workers); - - if (pbi->num_tile_workers > 0) { - vp9_loop_filter_dealloc(&pbi->lf_row_sync); - } - - if (pbi->row_mt == 1) { - vp9_dec_free_row_mt_mem(pbi->row_mt_worker_data); - if (pbi->row_mt_worker_data != NULL) { - vp9_jobq_deinit(&pbi->row_mt_worker_data->jobq); - vpx_free(pbi->row_mt_worker_data->jobq_buf); -#if CONFIG_MULTITHREAD - pthread_mutex_destroy(&pbi->row_mt_worker_data->recon_done_mutex); -#endif - } - vpx_free(pbi->row_mt_worker_data); - } - - vp9_remove_common(&pbi->common); - vpx_free(pbi); -} - -static int equal_dimensions(const YV12_BUFFER_CONFIG *a, - const YV12_BUFFER_CONFIG *b) { - return a->y_height == b->y_height && a->y_width == b->y_width && - a->uv_height == b->uv_height && a->uv_width == b->uv_width; -} - -vpx_codec_err_t vp9_copy_reference_dec(VP9Decoder *pbi, - VP9_REFFRAME ref_frame_flag, - YV12_BUFFER_CONFIG *sd) { - VP9_COMMON *cm = &pbi->common; - - /* TODO(jkoleszar): The decoder doesn't have any real knowledge of what the - * encoder is using the frame buffers for. This is just a stub to keep the - * vpxenc --test-decode functionality working, and will be replaced in a - * later commit that adds VP9-specific controls for this functionality. - */ - if (ref_frame_flag == VP9_LAST_FLAG) { - const YV12_BUFFER_CONFIG *const cfg = get_ref_frame(cm, 0); - if (cfg == NULL) { - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "No 'last' reference frame"); - return VPX_CODEC_ERROR; - } - if (!equal_dimensions(cfg, sd)) - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "Incorrect buffer dimensions"); - else - vpx_yv12_copy_frame(cfg, sd); - } else { - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, "Invalid reference frame"); - } - - return cm->error.error_code; -} - -vpx_codec_err_t vp9_set_reference_dec(VP9_COMMON *cm, - VP9_REFFRAME ref_frame_flag, - YV12_BUFFER_CONFIG *sd) { - int idx; - YV12_BUFFER_CONFIG *ref_buf = NULL; - - // TODO(jkoleszar): The decoder doesn't have any real knowledge of what the - // encoder is using the frame buffers for. This is just a stub to keep the - // vpxenc --test-decode functionality working, and will be replaced in a - // later commit that adds VP9-specific controls for this functionality. - // (Yunqing) The set_reference control depends on the following setting in - // encoder. - // cpi->lst_fb_idx = 0; - // cpi->gld_fb_idx = 1; - // cpi->alt_fb_idx = 2; - if (ref_frame_flag == VP9_LAST_FLAG) { - idx = cm->ref_frame_map[0]; - } else if (ref_frame_flag == VP9_GOLD_FLAG) { - idx = cm->ref_frame_map[1]; - } else if (ref_frame_flag == VP9_ALT_FLAG) { - idx = cm->ref_frame_map[2]; - } else { - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, "Invalid reference frame"); - return cm->error.error_code; - } - - if (idx < 0 || idx >= FRAME_BUFFERS) { - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "Invalid reference frame map"); - return cm->error.error_code; - } - - // Get the destination reference buffer. - ref_buf = &cm->buffer_pool->frame_bufs[idx].buf; - - if (!equal_dimensions(ref_buf, sd)) { - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "Incorrect buffer dimensions"); - } else { - // Overwrite the reference frame buffer. - vpx_yv12_copy_frame(sd, ref_buf); - } - - return cm->error.error_code; -} - -/* If any buffer updating is signaled it should be done here. */ -static void swap_frame_buffers(VP9Decoder *pbi) { - int ref_index = 0, mask; - VP9_COMMON *const cm = &pbi->common; - BufferPool *const pool = cm->buffer_pool; - RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs; - - for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) { - const int old_idx = cm->ref_frame_map[ref_index]; - // Current thread releases the holding of reference frame. - decrease_ref_count(old_idx, frame_bufs, pool); - - // Release the reference frame in reference map. - if (mask & 1) { - decrease_ref_count(old_idx, frame_bufs, pool); - } - cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index]; - ++ref_index; - } - - // Current thread releases the holding of reference frame. - for (; ref_index < REF_FRAMES && !cm->show_existing_frame; ++ref_index) { - const int old_idx = cm->ref_frame_map[ref_index]; - decrease_ref_count(old_idx, frame_bufs, pool); - cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index]; - } - pbi->hold_ref_buf = 0; - cm->frame_to_show = get_frame_new_buffer(cm); - - --frame_bufs[cm->new_fb_idx].ref_count; - - // Invalidate these references until the next frame starts. - for (ref_index = 0; ref_index < 3; ref_index++) - cm->frame_refs[ref_index].idx = -1; -} - -static void release_fb_on_decoder_exit(VP9Decoder *pbi) { - const VPxWorkerInterface *const winterface = vpx_get_worker_interface(); - VP9_COMMON *volatile const cm = &pbi->common; - BufferPool *volatile const pool = cm->buffer_pool; - RefCntBuffer *volatile const frame_bufs = cm->buffer_pool->frame_bufs; - int i; - - // Synchronize all threads immediately as a subsequent decode call may - // cause a resize invalidating some allocations. - winterface->sync(&pbi->lf_worker); - for (i = 0; i < pbi->num_tile_workers; ++i) { - winterface->sync(&pbi->tile_workers[i]); - } - - // Release all the reference buffers if worker thread is holding them. - if (pbi->hold_ref_buf == 1) { - int ref_index = 0, mask; - for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) { - const int old_idx = cm->ref_frame_map[ref_index]; - // Current thread releases the holding of reference frame. - decrease_ref_count(old_idx, frame_bufs, pool); - - // Release the reference frame in reference map. - if (mask & 1) { - decrease_ref_count(old_idx, frame_bufs, pool); - } - ++ref_index; - } - - // Current thread releases the holding of reference frame. - for (; ref_index < REF_FRAMES && !cm->show_existing_frame; ++ref_index) { - const int old_idx = cm->ref_frame_map[ref_index]; - decrease_ref_count(old_idx, frame_bufs, pool); - } - pbi->hold_ref_buf = 0; - } -} - -int vp9_receive_compressed_data(VP9Decoder *pbi, size_t size, - const uint8_t **psource) { - VP9_COMMON *volatile const cm = &pbi->common; - BufferPool *volatile const pool = cm->buffer_pool; - RefCntBuffer *volatile const frame_bufs = cm->buffer_pool->frame_bufs; - const uint8_t *source = *psource; - int retcode = 0; - cm->error.error_code = VPX_CODEC_OK; - - if (size == 0) { - // This is used to signal that we are missing frames. - // We do not know if the missing frame(s) was supposed to update - // any of the reference buffers, but we act conservative and - // mark only the last buffer as corrupted. - // - // TODO(jkoleszar): Error concealment is undefined and non-normative - // at this point, but if it becomes so, [0] may not always be the correct - // thing to do here. - if (cm->frame_refs[0].idx > 0) { - assert(cm->frame_refs[0].buf != NULL); - cm->frame_refs[0].buf->corrupted = 1; - } - } - - pbi->ready_for_new_data = 0; - - // Check if the previous frame was a frame without any references to it. - if (cm->new_fb_idx >= 0 && frame_bufs[cm->new_fb_idx].ref_count == 0 && - !frame_bufs[cm->new_fb_idx].released) { - pool->release_fb_cb(pool->cb_priv, - &frame_bufs[cm->new_fb_idx].raw_frame_buffer); - frame_bufs[cm->new_fb_idx].released = 1; - } - - // Find a free frame buffer. Return error if can not find any. - cm->new_fb_idx = get_free_fb(cm); - if (cm->new_fb_idx == INVALID_IDX) { - pbi->ready_for_new_data = 1; - release_fb_on_decoder_exit(pbi); - vpx_clear_system_state(); - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Unable to find free frame buffer"); - return cm->error.error_code; - } - - // Assign a MV array to the frame buffer. - cm->cur_frame = &pool->frame_bufs[cm->new_fb_idx]; - - pbi->hold_ref_buf = 0; - pbi->cur_buf = &frame_bufs[cm->new_fb_idx]; - - if (setjmp(cm->error.jmp)) { - cm->error.setjmp = 0; - pbi->ready_for_new_data = 1; - release_fb_on_decoder_exit(pbi); - // Release current frame. - decrease_ref_count(cm->new_fb_idx, frame_bufs, pool); - vpx_clear_system_state(); - return -1; - } - - cm->error.setjmp = 1; - vp9_decode_frame(pbi, source, source + size, psource); - - swap_frame_buffers(pbi); - - vpx_clear_system_state(); - - if (!cm->show_existing_frame) { - cm->last_show_frame = cm->show_frame; - cm->prev_frame = cm->cur_frame; - if (cm->seg.enabled) vp9_swap_current_and_last_seg_map(cm); - } - - if (cm->show_frame) cm->cur_show_frame_fb_idx = cm->new_fb_idx; - - // Update progress in frame parallel decode. - cm->last_width = cm->width; - cm->last_height = cm->height; - if (cm->show_frame) { - cm->current_video_frame++; - } - - cm->error.setjmp = 0; - return retcode; -} - -int vp9_get_raw_frame(VP9Decoder *pbi, YV12_BUFFER_CONFIG *sd, - vp9_ppflags_t *flags) { - VP9_COMMON *const cm = &pbi->common; - int ret = -1; -#if !CONFIG_VP9_POSTPROC - (void)*flags; -#endif - - if (pbi->ready_for_new_data == 1) return ret; - - pbi->ready_for_new_data = 1; - - /* no raw frame to show!!! */ - if (!cm->show_frame) return ret; - - pbi->ready_for_new_data = 1; - -#if CONFIG_VP9_POSTPROC - if (!cm->show_existing_frame) { - ret = vp9_post_proc_frame(cm, sd, flags, cm->width); - } else { - *sd = *cm->frame_to_show; - ret = 0; - } -#else - *sd = *cm->frame_to_show; - ret = 0; -#endif /*!CONFIG_POSTPROC*/ - vpx_clear_system_state(); - return ret; -} - -vpx_codec_err_t vp9_parse_superframe_index(const uint8_t *data, size_t data_sz, - uint32_t sizes[8], int *count, - vpx_decrypt_cb decrypt_cb, - void *decrypt_state) { - // A chunk ending with a byte matching 0xc0 is an invalid chunk unless - // it is a super frame index. If the last byte of real video compression - // data is 0xc0 the encoder must add a 0 byte. If we have the marker but - // not the associated matching marker byte at the front of the index we have - // an invalid bitstream and need to return an error. - - uint8_t marker; - - assert(data_sz); - marker = read_marker(decrypt_cb, decrypt_state, data + data_sz - 1); - *count = 0; - - if ((marker & 0xe0) == 0xc0) { - const uint32_t frames = (marker & 0x7) + 1; - const uint32_t mag = ((marker >> 3) & 0x3) + 1; - const size_t index_sz = 2 + mag * frames; - - // This chunk is marked as having a superframe index but doesn't have - // enough data for it, thus it's an invalid superframe index. - if (data_sz < index_sz) return VPX_CODEC_CORRUPT_FRAME; - - { - const uint8_t marker2 = - read_marker(decrypt_cb, decrypt_state, data + data_sz - index_sz); - - // This chunk is marked as having a superframe index but doesn't have - // the matching marker byte at the front of the index therefore it's an - // invalid chunk. - if (marker != marker2) return VPX_CODEC_CORRUPT_FRAME; - } - - { - // Found a valid superframe index. - uint32_t i, j; - const uint8_t *x = &data[data_sz - index_sz + 1]; - - // Frames has a maximum of 8 and mag has a maximum of 4. - uint8_t clear_buffer[32]; - assert(sizeof(clear_buffer) >= frames * mag); - if (decrypt_cb) { - decrypt_cb(decrypt_state, x, clear_buffer, frames * mag); - x = clear_buffer; - } - - for (i = 0; i < frames; ++i) { - uint32_t this_sz = 0; - - for (j = 0; j < mag; ++j) this_sz |= ((uint32_t)(*x++)) << (j * 8); - sizes[i] = this_sz; - } - *count = frames; - } - } - return VPX_CODEC_OK; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decoder.h b/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decoder.h deleted file mode 100644 index b3ee4eab..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_decoder.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_DECODER_VP9_DECODER_H_ -#define VPX_VP9_DECODER_VP9_DECODER_H_ - -#include "./vpx_config.h" - -#include "vpx/vpx_codec.h" -#include "vpx_dsp/bitreader.h" -#include "vpx_scale/yv12config.h" -#include "vpx_util/vpx_pthread.h" -#include "vpx_util/vpx_thread.h" - -#include "vp9/common/vp9_thread_common.h" -#include "vp9/common/vp9_onyxc_int.h" -#include "vp9/common/vp9_ppflags.h" -#include "./vp9_job_queue.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define EOBS_PER_SB_LOG2 8 -#define DQCOEFFS_PER_SB_LOG2 12 -#define PARTITIONS_PER_SB 85 - -typedef enum JobType { PARSE_JOB, RECON_JOB, LPF_JOB } JobType; - -typedef struct ThreadData { - struct VP9Decoder *pbi; - LFWorkerData *lf_data; - VP9LfSync *lf_sync; -} ThreadData; - -typedef struct TileBuffer { - const uint8_t *data; - size_t size; - int col; // only used with multi-threaded decoding -} TileBuffer; - -typedef struct TileWorkerData { - const uint8_t *data_end; - int buf_start, buf_end; // pbi->tile_buffers to decode, inclusive - vpx_reader bit_reader; - FRAME_COUNTS counts; - LFWorkerData *lf_data; - VP9LfSync *lf_sync; - DECLARE_ALIGNED(16, MACROBLOCKD, xd); - /* dqcoeff are shared by all the planes. So planes must be decoded serially */ - DECLARE_ALIGNED(32, tran_low_t, dqcoeff[32 * 32]); - DECLARE_ALIGNED(16, uint16_t, extend_and_predict_buf[80 * 2 * 80 * 2]); - struct vpx_internal_error_info error_info; -} TileWorkerData; - -typedef void (*process_block_fn_t)(TileWorkerData *twd, - struct VP9Decoder *const pbi, int mi_row, - int mi_col, BLOCK_SIZE bsize, int bwl, - int bhl); - -typedef struct RowMTWorkerData { - int num_sbs; - int *eob[MAX_MB_PLANE]; - PARTITION_TYPE *partition; - tran_low_t *dqcoeff[MAX_MB_PLANE]; - int8_t *recon_map; - const uint8_t *data_end; - uint8_t *jobq_buf; - JobQueueRowMt jobq; - size_t jobq_size; - int num_tiles_done; - int num_jobs; -#if CONFIG_MULTITHREAD - pthread_mutex_t recon_done_mutex; - pthread_mutex_t *recon_sync_mutex; - pthread_cond_t *recon_sync_cond; -#endif - ThreadData *thread_data; -} RowMTWorkerData; - -/* Structure to queue and dequeue row decode jobs */ -typedef struct Job { - int row_num; - int tile_col; - JobType job_type; -} Job; - -typedef struct VP9Decoder { - DECLARE_ALIGNED(16, MACROBLOCKD, mb); - - DECLARE_ALIGNED(16, VP9_COMMON, common); - - int ready_for_new_data; - - int refresh_frame_flags; - - // TODO(hkuang): Combine this with cur_buf in macroblockd as they are - // the same. - RefCntBuffer *cur_buf; // Current decoding frame buffer. - - VPxWorker lf_worker; - VPxWorker *tile_workers; - TileWorkerData *tile_worker_data; - TileBuffer tile_buffers[64]; - int num_tile_workers; - int total_tiles; - - VP9LfSync lf_row_sync; - - vpx_decrypt_cb decrypt_cb; - void *decrypt_state; - - int max_threads; - int inv_tile_order; - int need_resync; // wait for key/intra-only frame. - int hold_ref_buf; // hold the reference buffer. - - int row_mt; - int lpf_mt_opt; - RowMTWorkerData *row_mt_worker_data; -} VP9Decoder; - -int vp9_receive_compressed_data(struct VP9Decoder *pbi, size_t size, - const uint8_t **psource); - -int vp9_get_raw_frame(struct VP9Decoder *pbi, YV12_BUFFER_CONFIG *sd, - vp9_ppflags_t *flags); - -vpx_codec_err_t vp9_copy_reference_dec(struct VP9Decoder *pbi, - VP9_REFFRAME ref_frame_flag, - YV12_BUFFER_CONFIG *sd); - -vpx_codec_err_t vp9_set_reference_dec(VP9_COMMON *cm, - VP9_REFFRAME ref_frame_flag, - YV12_BUFFER_CONFIG *sd); - -static INLINE uint8_t read_marker(vpx_decrypt_cb decrypt_cb, - void *decrypt_state, const uint8_t *data) { - if (decrypt_cb) { - uint8_t marker; - decrypt_cb(decrypt_state, data, &marker, 1); - return marker; - } - return *data; -} - -// This function is exposed for use in tests, as well as the inlined function -// "read_marker". -vpx_codec_err_t vp9_parse_superframe_index(const uint8_t *data, size_t data_sz, - uint32_t sizes[8], int *count, - vpx_decrypt_cb decrypt_cb, - void *decrypt_state); - -struct VP9Decoder *vp9_decoder_create(BufferPool *const pool); - -void vp9_decoder_remove(struct VP9Decoder *pbi); - -void vp9_dec_alloc_row_mt_mem(RowMTWorkerData *row_mt_worker_data, - VP9_COMMON *cm, int num_sbs, int max_threads, - int num_jobs); -void vp9_dec_free_row_mt_mem(RowMTWorkerData *row_mt_worker_data); - -static INLINE void decrease_ref_count(int idx, RefCntBuffer *const frame_bufs, - BufferPool *const pool) { - if (idx >= 0 && frame_bufs[idx].ref_count > 0) { - --frame_bufs[idx].ref_count; - // A worker may only get a free framebuffer index when calling get_free_fb. - // But the private buffer is not set up until finish decoding header. - // So any error happens during decoding header, the frame_bufs will not - // have valid priv buffer. - if (!frame_bufs[idx].released && frame_bufs[idx].ref_count == 0 && - frame_bufs[idx].raw_frame_buffer.priv) { - pool->release_fb_cb(pool->cb_priv, &frame_bufs[idx].raw_frame_buffer); - frame_bufs[idx].released = 1; - } - } -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_DECODER_VP9_DECODER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_detokenize.c b/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_detokenize.c deleted file mode 100644 index d957dc34..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_detokenize.c +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" - -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_entropy.h" -#if CONFIG_COEFFICIENT_RANGE_CHECKING -#include "vp9/common/vp9_idct.h" -#endif - -#include "vp9/decoder/vp9_detokenize.h" - -#define EOB_CONTEXT_NODE 0 -#define ZERO_CONTEXT_NODE 1 -#define ONE_CONTEXT_NODE 2 - -#define INCREMENT_COUNT(token) \ - do { \ - if (counts) ++coef_counts[band][ctx][token]; \ - } while (0) - -static INLINE int read_bool(vpx_reader *r, int prob, BD_VALUE *value, - int *count, unsigned int *range) { - const unsigned int split = (*range * prob + (256 - prob)) >> CHAR_BIT; - const BD_VALUE bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT); -#if CONFIG_BITSTREAM_DEBUG - const int queue_r = bitstream_queue_get_read(); - const int frame_idx = bitstream_queue_get_frame_read(); - int ref_result, ref_prob; - bitstream_queue_pop(&ref_result, &ref_prob); - if (prob != ref_prob) { - fprintf(stderr, - "\n *** [bit] prob error, frame_idx_r %d prob %d ref_prob %d " - "queue_r %d\n", - frame_idx, prob, ref_prob, queue_r); - - assert(0); - } -#endif - - if (*count < 0) { - r->value = *value; - r->count = *count; - vpx_reader_fill(r); - *value = r->value; - *count = r->count; - } - - if (*value >= bigsplit) { - *range = *range - split; - *value = *value - bigsplit; - { - const int shift = vpx_norm[*range]; - *range <<= shift; - *value <<= shift; - *count -= shift; - } -#if CONFIG_BITSTREAM_DEBUG - { - const int bit = 1; - if (bit != ref_result) { - fprintf( - stderr, - "\n *** [bit] result error, frame_idx_r %d bit %d ref_result %d " - "queue_r %d\n", - frame_idx, bit, ref_result, queue_r); - - assert(0); - } - } -#endif - return 1; - } - *range = split; - { - const int shift = vpx_norm[*range]; - *range <<= shift; - *value <<= shift; - *count -= shift; - } -#if CONFIG_BITSTREAM_DEBUG - { - const int bit = 0; - if (bit != ref_result) { - fprintf(stderr, - "\n *** [bit] result error, frame_idx_r %d bit %d ref_result %d " - "queue_r %d\n", - frame_idx, bit, ref_result, queue_r); - - assert(0); - } - } -#endif - return 0; -} - -static INLINE int read_coeff(vpx_reader *r, const vpx_prob *probs, int n, - BD_VALUE *value, int *count, unsigned int *range) { - int i, val = 0; - for (i = 0; i < n; ++i) - val = (val << 1) | read_bool(r, probs[i], value, count, range); - return val; -} - -static int decode_coefs(const MACROBLOCKD *xd, PLANE_TYPE type, - tran_low_t *dqcoeff, TX_SIZE tx_size, const int16_t *dq, - int ctx, const int16_t *scan, const int16_t *nb, - vpx_reader *r) { - FRAME_COUNTS *counts = xd->counts; - const int max_eob = 16 << (tx_size << 1); - const FRAME_CONTEXT *const fc = xd->fc; - const int ref = is_inter_block(xd->mi[0]); - int band, c = 0; - const vpx_prob(*coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] = - fc->coef_probs[tx_size][type][ref]; - const vpx_prob *prob; - unsigned int(*coef_counts)[COEFF_CONTEXTS][UNCONSTRAINED_NODES + 1]; - unsigned int(*eob_branch_count)[COEFF_CONTEXTS]; - uint8_t token_cache[32 * 32]; - const uint8_t *band_translate = get_band_translate(tx_size); - const int dq_shift = (tx_size == TX_32X32); - int v; - int16_t dqv = dq[0]; - const uint8_t *const cat6_prob = -#if CONFIG_VP9_HIGHBITDEPTH - (xd->bd == VPX_BITS_12) ? vp9_cat6_prob_high12 - : (xd->bd == VPX_BITS_10) ? vp9_cat6_prob_high12 + 2 - : -#endif // CONFIG_VP9_HIGHBITDEPTH - vp9_cat6_prob; - const int cat6_bits = -#if CONFIG_VP9_HIGHBITDEPTH - (xd->bd == VPX_BITS_12) ? 18 - : (xd->bd == VPX_BITS_10) ? 16 - : -#endif // CONFIG_VP9_HIGHBITDEPTH - 14; - // Keep value, range, and count as locals. The compiler produces better - // results with the locals than using r directly. - BD_VALUE value = r->value; - unsigned int range = r->range; - int count = r->count; - - if (counts) { - coef_counts = counts->coef[tx_size][type][ref]; - eob_branch_count = counts->eob_branch[tx_size][type][ref]; - } - - while (c < max_eob) { - int val = -1; - band = *band_translate++; - prob = coef_probs[band][ctx]; - if (counts) ++eob_branch_count[band][ctx]; - if (!read_bool(r, prob[EOB_CONTEXT_NODE], &value, &count, &range)) { - INCREMENT_COUNT(EOB_MODEL_TOKEN); - break; - } - - while (!read_bool(r, prob[ZERO_CONTEXT_NODE], &value, &count, &range)) { - INCREMENT_COUNT(ZERO_TOKEN); - dqv = dq[1]; - token_cache[scan[c]] = 0; - ++c; - if (c >= max_eob) { - r->value = value; - r->range = range; - r->count = count; - return c; // zero tokens at the end (no eob token) - } - ctx = get_coef_context(nb, token_cache, c); - band = *band_translate++; - prob = coef_probs[band][ctx]; - } - - if (read_bool(r, prob[ONE_CONTEXT_NODE], &value, &count, &range)) { - const vpx_prob *p = vp9_pareto8_full[prob[PIVOT_NODE] - 1]; - INCREMENT_COUNT(TWO_TOKEN); - if (read_bool(r, p[0], &value, &count, &range)) { - if (read_bool(r, p[3], &value, &count, &range)) { - token_cache[scan[c]] = 5; - if (read_bool(r, p[5], &value, &count, &range)) { - if (read_bool(r, p[7], &value, &count, &range)) { - val = CAT6_MIN_VAL + - read_coeff(r, cat6_prob, cat6_bits, &value, &count, &range); - } else { - val = CAT5_MIN_VAL + - read_coeff(r, vp9_cat5_prob, 5, &value, &count, &range); - } - } else if (read_bool(r, p[6], &value, &count, &range)) { - val = CAT4_MIN_VAL + - read_coeff(r, vp9_cat4_prob, 4, &value, &count, &range); - } else { - val = CAT3_MIN_VAL + - read_coeff(r, vp9_cat3_prob, 3, &value, &count, &range); - } - } else { - token_cache[scan[c]] = 4; - if (read_bool(r, p[4], &value, &count, &range)) { - val = CAT2_MIN_VAL + - read_coeff(r, vp9_cat2_prob, 2, &value, &count, &range); - } else { - val = CAT1_MIN_VAL + - read_coeff(r, vp9_cat1_prob, 1, &value, &count, &range); - } - } -#if CONFIG_VP9_HIGHBITDEPTH - // val may use 18-bits - v = (int)(((int64_t)val * dqv) >> dq_shift); -#else - v = (val * dqv) >> dq_shift; -#endif - } else { - if (read_bool(r, p[1], &value, &count, &range)) { - token_cache[scan[c]] = 3; - v = ((3 + read_bool(r, p[2], &value, &count, &range)) * dqv) >> - dq_shift; - } else { - token_cache[scan[c]] = 2; - v = (2 * dqv) >> dq_shift; - } - } - } else { - INCREMENT_COUNT(ONE_TOKEN); - token_cache[scan[c]] = 1; - v = dqv >> dq_shift; - } -#if CONFIG_COEFFICIENT_RANGE_CHECKING -#if CONFIG_VP9_HIGHBITDEPTH - dqcoeff[scan[c]] = highbd_check_range( - read_bool(r, 128, &value, &count, &range) ? -v : v, xd->bd); -#else - dqcoeff[scan[c]] = - check_range(read_bool(r, 128, &value, &count, &range) ? -v : v); -#endif // CONFIG_VP9_HIGHBITDEPTH -#else - if (read_bool(r, 128, &value, &count, &range)) { - dqcoeff[scan[c]] = (tran_low_t)-v; - } else { - dqcoeff[scan[c]] = (tran_low_t)v; - } -#endif // CONFIG_COEFFICIENT_RANGE_CHECKING - ++c; - ctx = get_coef_context(nb, token_cache, c); - dqv = dq[1]; - } - - r->value = value; - r->range = range; - r->count = count; - return c; -} - -static void get_ctx_shift(MACROBLOCKD *xd, int *ctx_shift_a, int *ctx_shift_l, - int x, int y, unsigned int tx_size_in_blocks) { - if (xd->max_blocks_wide) { - if (tx_size_in_blocks + x > xd->max_blocks_wide) - *ctx_shift_a = (tx_size_in_blocks - (xd->max_blocks_wide - x)) * 8; - } - if (xd->max_blocks_high) { - if (tx_size_in_blocks + y > xd->max_blocks_high) - *ctx_shift_l = (tx_size_in_blocks - (xd->max_blocks_high - y)) * 8; - } -} - -int vp9_decode_block_tokens(TileWorkerData *twd, int plane, const ScanOrder *sc, - int x, int y, TX_SIZE tx_size, int seg_id) { - vpx_reader *r = &twd->bit_reader; - MACROBLOCKD *xd = &twd->xd; - struct macroblockd_plane *const pd = &xd->plane[plane]; - const int16_t *const dequant = pd->seg_dequant[seg_id]; - int eob; - ENTROPY_CONTEXT *a = pd->above_context + x; - ENTROPY_CONTEXT *l = pd->left_context + y; - int ctx; - int ctx_shift_a = 0; - int ctx_shift_l = 0; - - switch (tx_size) { - case TX_4X4: - ctx = a[0] != 0; - ctx += l[0] != 0; - eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size, - dequant, ctx, sc->scan, sc->neighbors, r); - a[0] = l[0] = (eob > 0); - break; - case TX_8X8: - get_ctx_shift(xd, &ctx_shift_a, &ctx_shift_l, x, y, 1 << TX_8X8); - ctx = !!*(const uint16_t *)a; - ctx += !!*(const uint16_t *)l; - eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size, - dequant, ctx, sc->scan, sc->neighbors, r); - *(uint16_t *)a = ((eob > 0) * 0x0101) >> ctx_shift_a; - *(uint16_t *)l = ((eob > 0) * 0x0101) >> ctx_shift_l; - break; - case TX_16X16: - get_ctx_shift(xd, &ctx_shift_a, &ctx_shift_l, x, y, 1 << TX_16X16); - ctx = !!*(const uint32_t *)a; - ctx += !!*(const uint32_t *)l; - eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size, - dequant, ctx, sc->scan, sc->neighbors, r); - *(uint32_t *)a = ((eob > 0) * 0x01010101) >> ctx_shift_a; - *(uint32_t *)l = ((eob > 0) * 0x01010101) >> ctx_shift_l; - break; - case TX_32X32: - get_ctx_shift(xd, &ctx_shift_a, &ctx_shift_l, x, y, 1 << TX_32X32); - // NOTE: casting to uint64_t here is safe because the default memory - // alignment is at least 8 bytes and the TX_32X32 is aligned on 8 byte - // boundaries. - ctx = !!*(const uint64_t *)a; - ctx += !!*(const uint64_t *)l; - eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size, - dequant, ctx, sc->scan, sc->neighbors, r); - *(uint64_t *)a = ((eob > 0) * 0x0101010101010101ULL) >> ctx_shift_a; - *(uint64_t *)l = ((eob > 0) * 0x0101010101010101ULL) >> ctx_shift_l; - break; - default: - assert(0 && "Invalid transform size."); - eob = 0; - break; - } - - return eob; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_detokenize.h b/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_detokenize.h deleted file mode 100644 index a8e47021..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_detokenize.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_DECODER_VP9_DETOKENIZE_H_ -#define VPX_VP9_DECODER_VP9_DETOKENIZE_H_ - -#include "vpx_dsp/bitreader.h" -#include "vp9/decoder/vp9_decoder.h" -#include "vp9/common/vp9_scan.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int vp9_decode_block_tokens(TileWorkerData *twd, int plane, const ScanOrder *sc, - int x, int y, TX_SIZE tx_size, int seg_id); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_DECODER_VP9_DETOKENIZE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_dsubexp.c b/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_dsubexp.c deleted file mode 100644 index 126ba0b9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_dsubexp.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "vp9/common/vp9_entropy.h" - -#include "vp9/decoder/vp9_dsubexp.h" - -static int inv_recenter_nonneg(int v, int m) { - if (v > 2 * m) return v; - - return (v & 1) ? m - ((v + 1) >> 1) : m + (v >> 1); -} - -static int decode_uniform(vpx_reader *r) { - const int l = 8; - const int m = (1 << l) - 191; - const int v = vpx_read_literal(r, l - 1); - return v < m ? v : (v << 1) - m + vpx_read_bit(r); -} - -static int inv_remap_prob(int v, int m) { - static uint8_t inv_map_table[MAX_PROB] = { - 7, 20, 33, 46, 59, 72, 85, 98, 111, 124, 137, 150, 163, 176, 189, - 202, 215, 228, 241, 254, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, - 174, 175, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 190, - 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 216, 217, 218, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 253 - }; - assert(v < (int)(sizeof(inv_map_table) / sizeof(inv_map_table[0]))); - v = inv_map_table[v]; - m--; - if ((m << 1) <= MAX_PROB) { - return 1 + inv_recenter_nonneg(v, m); - } else { - return MAX_PROB - inv_recenter_nonneg(v, MAX_PROB - 1 - m); - } -} - -static int decode_term_subexp(vpx_reader *r) { - if (!vpx_read_bit(r)) return vpx_read_literal(r, 4); - if (!vpx_read_bit(r)) return vpx_read_literal(r, 4) + 16; - if (!vpx_read_bit(r)) return vpx_read_literal(r, 5) + 32; - return decode_uniform(r) + 64; -} - -void vp9_diff_update_prob(vpx_reader *r, vpx_prob *p) { - if (vpx_read(r, DIFF_UPDATE_PROB)) { - const int delp = decode_term_subexp(r); - *p = (vpx_prob)inv_remap_prob(delp, *p); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_dsubexp.h b/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_dsubexp.h deleted file mode 100644 index b0c77507..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_dsubexp.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_DECODER_VP9_DSUBEXP_H_ -#define VPX_VP9_DECODER_VP9_DSUBEXP_H_ - -#include "vpx_dsp/bitreader.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vp9_diff_update_prob(vpx_reader *r, vpx_prob *p); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_DECODER_VP9_DSUBEXP_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_job_queue.c b/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_job_queue.c deleted file mode 100644 index 926ae877..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_job_queue.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "vpx/vpx_integer.h" -#include "vpx_util/vpx_pthread.h" - -#include "vp9/decoder/vp9_job_queue.h" - -void vp9_jobq_init(JobQueueRowMt *jobq, uint8_t *buf, size_t buf_size) { -#if CONFIG_MULTITHREAD - pthread_mutex_init(&jobq->mutex, NULL); - pthread_cond_init(&jobq->cond, NULL); -#endif - jobq->buf_base = buf; - jobq->buf_wr = buf; - jobq->buf_rd = buf; - jobq->buf_end = buf + buf_size; - jobq->terminate = 0; -} - -void vp9_jobq_reset(JobQueueRowMt *jobq) { -#if CONFIG_MULTITHREAD - pthread_mutex_lock(&jobq->mutex); -#endif - jobq->buf_wr = jobq->buf_base; - jobq->buf_rd = jobq->buf_base; - jobq->terminate = 0; -#if CONFIG_MULTITHREAD - pthread_mutex_unlock(&jobq->mutex); -#endif -} - -void vp9_jobq_deinit(JobQueueRowMt *jobq) { - vp9_jobq_reset(jobq); -#if CONFIG_MULTITHREAD - pthread_mutex_destroy(&jobq->mutex); - pthread_cond_destroy(&jobq->cond); -#endif -} - -void vp9_jobq_terminate(JobQueueRowMt *jobq) { -#if CONFIG_MULTITHREAD - pthread_mutex_lock(&jobq->mutex); -#endif - jobq->terminate = 1; -#if CONFIG_MULTITHREAD - pthread_cond_broadcast(&jobq->cond); - pthread_mutex_unlock(&jobq->mutex); -#endif -} - -int vp9_jobq_queue(JobQueueRowMt *jobq, void *job, size_t job_size) { - int ret = 0; -#if CONFIG_MULTITHREAD - pthread_mutex_lock(&jobq->mutex); -#endif - if (jobq->buf_end >= jobq->buf_wr + job_size) { - memcpy(jobq->buf_wr, job, job_size); - jobq->buf_wr = jobq->buf_wr + job_size; -#if CONFIG_MULTITHREAD - pthread_cond_signal(&jobq->cond); -#endif - ret = 0; - } else { - /* Wrap around case is not supported */ - assert(0); - ret = 1; - } -#if CONFIG_MULTITHREAD - pthread_mutex_unlock(&jobq->mutex); -#endif - return ret; -} - -int vp9_jobq_dequeue(JobQueueRowMt *jobq, void *job, size_t job_size, - int blocking) { - int ret = 0; -#if CONFIG_MULTITHREAD - pthread_mutex_lock(&jobq->mutex); -#endif - if (jobq->buf_end >= jobq->buf_rd + job_size) { - while (1) { - if (jobq->buf_wr >= jobq->buf_rd + job_size) { - memcpy(job, jobq->buf_rd, job_size); - jobq->buf_rd = jobq->buf_rd + job_size; - ret = 0; - break; - } else { - /* If all the entries have been dequeued, then break and return */ - if (jobq->terminate == 1) { - ret = 1; - break; - } - if (blocking == 1) { -#if CONFIG_MULTITHREAD - pthread_cond_wait(&jobq->cond, &jobq->mutex); -#endif - } else { - /* If there is no job available, - * and this is non blocking call then return fail */ - ret = 1; - break; - } - } - } - } else { - /* Wrap around case is not supported */ - ret = 1; - } -#if CONFIG_MULTITHREAD - pthread_mutex_unlock(&jobq->mutex); -#endif - - return ret; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_job_queue.h b/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_job_queue.h deleted file mode 100644 index 59f71fb9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/decoder/vp9_job_queue.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_DECODER_VP9_JOB_QUEUE_H_ -#define VPX_VP9_DECODER_VP9_JOB_QUEUE_H_ - -#include "vpx_util/vpx_pthread.h" - -typedef struct { - // Pointer to buffer base which contains the jobs - uint8_t *buf_base; - - // Pointer to current address where new job can be added - uint8_t *volatile buf_wr; - - // Pointer to current address from where next job can be obtained - uint8_t *volatile buf_rd; - - // Pointer to end of job buffer - uint8_t *buf_end; - - int terminate; - -#if CONFIG_MULTITHREAD - pthread_mutex_t mutex; - pthread_cond_t cond; -#endif -} JobQueueRowMt; - -void vp9_jobq_init(JobQueueRowMt *jobq, uint8_t *buf, size_t buf_size); -void vp9_jobq_reset(JobQueueRowMt *jobq); -void vp9_jobq_deinit(JobQueueRowMt *jobq); -void vp9_jobq_terminate(JobQueueRowMt *jobq); -int vp9_jobq_queue(JobQueueRowMt *jobq, void *job, size_t job_size); -int vp9_jobq_dequeue(JobQueueRowMt *jobq, void *job, size_t job_size, - int blocking); - -#endif // VPX_VP9_DECODER_VP9_JOB_QUEUE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_dct_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_dct_neon.c deleted file mode 100644 index 997b5477..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_dct_neon.c +++ /dev/null @@ -1,2173 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vp9_rtcd.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx_dsp/txfm_common.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/arm/fdct_neon.h" -#include "vpx_dsp/arm/fdct4x4_neon.h" -#include "vpx_dsp/arm/fdct8x8_neon.h" -#include "vpx_dsp/arm/fdct16x16_neon.h" - -static INLINE void load_buffer_4x4(const int16_t *input, int16x8_t *in, - int stride) { - // { 0, 1, 1, 1 }; - const int16x4_t nonzero_bias_a = vext_s16(vdup_n_s16(0), vdup_n_s16(1), 3); - // { 1, 0, 0, 0 }; - const int16x4_t nonzero_bias_b = vext_s16(vdup_n_s16(1), vdup_n_s16(0), 3); - int16x4_t mask; - - int16x4_t input_0 = vshl_n_s16(vld1_s16(input + 0 * stride), 4); - int16x4_t input_1 = vshl_n_s16(vld1_s16(input + 1 * stride), 4); - int16x4_t input_2 = vshl_n_s16(vld1_s16(input + 2 * stride), 4); - int16x4_t input_3 = vshl_n_s16(vld1_s16(input + 3 * stride), 4); - - // Copy the SSE method, use a mask to avoid an 'if' branch here to increase by - // one non-zero first elements - mask = vreinterpret_s16_u16(vceq_s16(input_0, nonzero_bias_a)); - input_0 = vadd_s16(input_0, mask); - input_0 = vadd_s16(input_0, nonzero_bias_b); - - in[0] = vcombine_s16(input_0, input_1); - in[1] = vcombine_s16(input_2, input_3); -} - -static INLINE void write_buffer_4x4(tran_low_t *output, int16x8_t *res) { - const int16x8_t one_s16 = vdupq_n_s16(1); - res[0] = vaddq_s16(res[0], one_s16); - res[1] = vaddq_s16(res[1], one_s16); - res[0] = vshrq_n_s16(res[0], 2); - res[1] = vshrq_n_s16(res[1], 2); - store_s16q_to_tran_low(output + 0 * 8, res[0]); - store_s16q_to_tran_low(output + 1 * 8, res[1]); -} - -static INLINE void fadst4x4_neon(int16x8_t *in) { - int32x4_t u[4], t[4]; - int16x4_t s[4], out[4]; - - s[0] = vget_low_s16(in[0]); // | x_00 | x_01 | x_02 | x_03 | - s[1] = vget_high_s16(in[0]); // | x_10 | x_11 | x_12 | x_13 | - s[2] = vget_low_s16(in[1]); // | x_20 | x_21 | x_22 | x_23 | - s[3] = vget_high_s16(in[1]); // | x_30 | x_31 | x_32 | x_33 | - - // Must expand all elements to s32. See 'needs32' comment in fwd_txfm.c. - // t0 = s0 * sinpi_1_9 + s1 * sinpi_2_9 + s3 * sinpi_4_9 - t[0] = vmull_n_s16(s[0], sinpi_1_9); - t[0] = vmlal_n_s16(t[0], s[1], sinpi_2_9); - t[0] = vmlal_n_s16(t[0], s[3], sinpi_4_9); - - // t1 = (s0 + s1) * sinpi_3_9 - s3 * sinpi_3_9 - t[1] = vmull_n_s16(s[0], sinpi_3_9); - t[1] = vmlal_n_s16(t[1], s[1], sinpi_3_9); - t[1] = vmlsl_n_s16(t[1], s[3], sinpi_3_9); - - // t2 = s0 * sinpi_4_9 - s1* sinpi_1_9 + s3 * sinpi_2_9 - t[2] = vmull_n_s16(s[0], sinpi_4_9); - t[2] = vmlsl_n_s16(t[2], s[1], sinpi_1_9); - t[2] = vmlal_n_s16(t[2], s[3], sinpi_2_9); - - // t3 = s2 * sinpi_3_9 - t[3] = vmull_n_s16(s[2], sinpi_3_9); - - /* - * u0 = t0 + t3 - * u1 = t1 - * u2 = t2 - t3 - * u3 = t2 - t0 + t3 - */ - u[0] = vaddq_s32(t[0], t[3]); - u[1] = t[1]; - u[2] = vsubq_s32(t[2], t[3]); - u[3] = vaddq_s32(vsubq_s32(t[2], t[0]), t[3]); - - // fdct_round_shift - out[0] = vrshrn_n_s32(u[0], DCT_CONST_BITS); - out[1] = vrshrn_n_s32(u[1], DCT_CONST_BITS); - out[2] = vrshrn_n_s32(u[2], DCT_CONST_BITS); - out[3] = vrshrn_n_s32(u[3], DCT_CONST_BITS); - - transpose_s16_4x4d(&out[0], &out[1], &out[2], &out[3]); - - in[0] = vcombine_s16(out[0], out[1]); - in[1] = vcombine_s16(out[2], out[3]); -} - -void vp9_fht4x4_neon(const int16_t *input, tran_low_t *output, int stride, - int tx_type) { - int16x8_t in[2]; - - switch (tx_type) { - case DCT_DCT: vpx_fdct4x4_neon(input, output, stride); break; - case ADST_DCT: - load_buffer_4x4(input, in, stride); - fadst4x4_neon(in); - // pass1 variant is not accurate enough - vpx_fdct4x4_pass2_neon((int16x4_t *)in); - write_buffer_4x4(output, in); - break; - case DCT_ADST: - load_buffer_4x4(input, in, stride); - // pass1 variant is not accurate enough - vpx_fdct4x4_pass2_neon((int16x4_t *)in); - fadst4x4_neon(in); - write_buffer_4x4(output, in); - break; - default: - assert(tx_type == ADST_ADST); - load_buffer_4x4(input, in, stride); - fadst4x4_neon(in); - fadst4x4_neon(in); - write_buffer_4x4(output, in); - break; - } -} - -static INLINE void load_buffer_8x8(const int16_t *input, int16x8_t *in, - int stride) { - in[0] = vshlq_n_s16(vld1q_s16(input + 0 * stride), 2); - in[1] = vshlq_n_s16(vld1q_s16(input + 1 * stride), 2); - in[2] = vshlq_n_s16(vld1q_s16(input + 2 * stride), 2); - in[3] = vshlq_n_s16(vld1q_s16(input + 3 * stride), 2); - in[4] = vshlq_n_s16(vld1q_s16(input + 4 * stride), 2); - in[5] = vshlq_n_s16(vld1q_s16(input + 5 * stride), 2); - in[6] = vshlq_n_s16(vld1q_s16(input + 6 * stride), 2); - in[7] = vshlq_n_s16(vld1q_s16(input + 7 * stride), 2); -} - -/* right shift and rounding - * first get the sign bit (bit 15). - * If bit == 1, it's the simple case of shifting right by one bit. - * If bit == 2, it essentially computes the expression: - * - * out[j * 16 + i] = (temp_out[j] + 1 + (temp_out[j] < 0)) >> 2; - * - * for each row. - */ -static INLINE void right_shift_8x8(int16x8_t *res, const int bit) { - int16x8_t sign0 = vshrq_n_s16(res[0], 15); - int16x8_t sign1 = vshrq_n_s16(res[1], 15); - int16x8_t sign2 = vshrq_n_s16(res[2], 15); - int16x8_t sign3 = vshrq_n_s16(res[3], 15); - int16x8_t sign4 = vshrq_n_s16(res[4], 15); - int16x8_t sign5 = vshrq_n_s16(res[5], 15); - int16x8_t sign6 = vshrq_n_s16(res[6], 15); - int16x8_t sign7 = vshrq_n_s16(res[7], 15); - - if (bit == 2) { - const int16x8_t const_rounding = vdupq_n_s16(1); - res[0] = vaddq_s16(res[0], const_rounding); - res[1] = vaddq_s16(res[1], const_rounding); - res[2] = vaddq_s16(res[2], const_rounding); - res[3] = vaddq_s16(res[3], const_rounding); - res[4] = vaddq_s16(res[4], const_rounding); - res[5] = vaddq_s16(res[5], const_rounding); - res[6] = vaddq_s16(res[6], const_rounding); - res[7] = vaddq_s16(res[7], const_rounding); - } - - res[0] = vsubq_s16(res[0], sign0); - res[1] = vsubq_s16(res[1], sign1); - res[2] = vsubq_s16(res[2], sign2); - res[3] = vsubq_s16(res[3], sign3); - res[4] = vsubq_s16(res[4], sign4); - res[5] = vsubq_s16(res[5], sign5); - res[6] = vsubq_s16(res[6], sign6); - res[7] = vsubq_s16(res[7], sign7); - - if (bit == 1) { - res[0] = vshrq_n_s16(res[0], 1); - res[1] = vshrq_n_s16(res[1], 1); - res[2] = vshrq_n_s16(res[2], 1); - res[3] = vshrq_n_s16(res[3], 1); - res[4] = vshrq_n_s16(res[4], 1); - res[5] = vshrq_n_s16(res[5], 1); - res[6] = vshrq_n_s16(res[6], 1); - res[7] = vshrq_n_s16(res[7], 1); - } else { - res[0] = vshrq_n_s16(res[0], 2); - res[1] = vshrq_n_s16(res[1], 2); - res[2] = vshrq_n_s16(res[2], 2); - res[3] = vshrq_n_s16(res[3], 2); - res[4] = vshrq_n_s16(res[4], 2); - res[5] = vshrq_n_s16(res[5], 2); - res[6] = vshrq_n_s16(res[6], 2); - res[7] = vshrq_n_s16(res[7], 2); - } -} - -static INLINE void write_buffer_8x8(tran_low_t *output, int16x8_t *res, - int stride) { - store_s16q_to_tran_low(output + 0 * stride, res[0]); - store_s16q_to_tran_low(output + 1 * stride, res[1]); - store_s16q_to_tran_low(output + 2 * stride, res[2]); - store_s16q_to_tran_low(output + 3 * stride, res[3]); - store_s16q_to_tran_low(output + 4 * stride, res[4]); - store_s16q_to_tran_low(output + 5 * stride, res[5]); - store_s16q_to_tran_low(output + 6 * stride, res[6]); - store_s16q_to_tran_low(output + 7 * stride, res[7]); -} - -static INLINE void fadst8x8_neon(int16x8_t *in) { - int16x4_t x_lo[8], x_hi[8]; - int32x4_t s_lo[8], s_hi[8]; - int32x4_t t_lo[8], t_hi[8]; - - x_lo[0] = vget_low_s16(in[7]); - x_hi[0] = vget_high_s16(in[7]); - x_lo[1] = vget_low_s16(in[0]); - x_hi[1] = vget_high_s16(in[0]); - x_lo[2] = vget_low_s16(in[5]); - x_hi[2] = vget_high_s16(in[5]); - x_lo[3] = vget_low_s16(in[2]); - x_hi[3] = vget_high_s16(in[2]); - x_lo[4] = vget_low_s16(in[3]); - x_hi[4] = vget_high_s16(in[3]); - x_lo[5] = vget_low_s16(in[4]); - x_hi[5] = vget_high_s16(in[4]); - x_lo[6] = vget_low_s16(in[1]); - x_hi[6] = vget_high_s16(in[1]); - x_lo[7] = vget_low_s16(in[6]); - x_hi[7] = vget_high_s16(in[6]); - - // stage 1 - // s0 = cospi_2_64 * x0 + cospi_30_64 * x1; - // s1 = cospi_30_64 * x0 - cospi_2_64 * x1; - butterfly_two_coeff_s16_s32_noround(x_lo[0], x_hi[0], x_lo[1], x_hi[1], - cospi_2_64, cospi_30_64, &s_lo[0], - &s_hi[0], &s_lo[1], &s_hi[1]); - - // s2 = cospi_10_64 * x2 + cospi_22_64 * x3; - // s3 = cospi_22_64 * x2 - cospi_10_64 * x3; - butterfly_two_coeff_s16_s32_noround(x_lo[2], x_hi[2], x_lo[3], x_hi[3], - cospi_10_64, cospi_22_64, &s_lo[2], - &s_hi[2], &s_lo[3], &s_hi[3]); - - // s4 = cospi_18_64 * x4 + cospi_14_64 * x5; - // s5 = cospi_14_64 * x4 - cospi_18_64 * x5; - butterfly_two_coeff_s16_s32_noround(x_lo[4], x_hi[4], x_lo[5], x_hi[5], - cospi_18_64, cospi_14_64, &s_lo[4], - &s_hi[4], &s_lo[5], &s_hi[5]); - - // s6 = cospi_26_64 * x6 + cospi_6_64 * x7; - // s7 = cospi_6_64 * x6 - cospi_26_64 * x7; - butterfly_two_coeff_s16_s32_noround(x_lo[6], x_hi[6], x_lo[7], x_hi[7], - cospi_26_64, cospi_6_64, &s_lo[6], - &s_hi[6], &s_lo[7], &s_hi[7]); - - // fdct_round_shift - t_lo[0] = vrshrq_n_s32(vaddq_s32(s_lo[0], s_lo[4]), DCT_CONST_BITS); - t_hi[0] = vrshrq_n_s32(vaddq_s32(s_hi[0], s_hi[4]), DCT_CONST_BITS); - t_lo[1] = vrshrq_n_s32(vaddq_s32(s_lo[1], s_lo[5]), DCT_CONST_BITS); - t_hi[1] = vrshrq_n_s32(vaddq_s32(s_hi[1], s_hi[5]), DCT_CONST_BITS); - t_lo[2] = vrshrq_n_s32(vaddq_s32(s_lo[2], s_lo[6]), DCT_CONST_BITS); - t_hi[2] = vrshrq_n_s32(vaddq_s32(s_hi[2], s_hi[6]), DCT_CONST_BITS); - t_lo[3] = vrshrq_n_s32(vaddq_s32(s_lo[3], s_lo[7]), DCT_CONST_BITS); - t_hi[3] = vrshrq_n_s32(vaddq_s32(s_hi[3], s_hi[7]), DCT_CONST_BITS); - t_lo[4] = vrshrq_n_s32(vsubq_s32(s_lo[0], s_lo[4]), DCT_CONST_BITS); - t_hi[4] = vrshrq_n_s32(vsubq_s32(s_hi[0], s_hi[4]), DCT_CONST_BITS); - t_lo[5] = vrshrq_n_s32(vsubq_s32(s_lo[1], s_lo[5]), DCT_CONST_BITS); - t_hi[5] = vrshrq_n_s32(vsubq_s32(s_hi[1], s_hi[5]), DCT_CONST_BITS); - t_lo[6] = vrshrq_n_s32(vsubq_s32(s_lo[2], s_lo[6]), DCT_CONST_BITS); - t_hi[6] = vrshrq_n_s32(vsubq_s32(s_hi[2], s_hi[6]), DCT_CONST_BITS); - t_lo[7] = vrshrq_n_s32(vsubq_s32(s_lo[3], s_lo[7]), DCT_CONST_BITS); - t_hi[7] = vrshrq_n_s32(vsubq_s32(s_hi[3], s_hi[7]), DCT_CONST_BITS); - - // stage 2 - s_lo[0] = t_lo[0]; - s_hi[0] = t_hi[0]; - s_lo[1] = t_lo[1]; - s_hi[1] = t_hi[1]; - s_lo[2] = t_lo[2]; - s_hi[2] = t_hi[2]; - s_lo[3] = t_lo[3]; - s_hi[3] = t_hi[3]; - // s4 = cospi_8_64 * x4 + cospi_24_64 * x5; - // s5 = cospi_24_64 * x4 - cospi_8_64 * x5; - butterfly_two_coeff_s32_noround(t_lo[4], t_hi[4], t_lo[5], t_hi[5], - cospi_8_64, cospi_24_64, &s_lo[4], &s_hi[4], - &s_lo[5], &s_hi[5]); - - // s6 = -cospi_24_64 * x6 + cospi_8_64 * x7; - // s7 = cospi_8_64 * x6 + cospi_24_64 * x7; - butterfly_two_coeff_s32_noround(t_lo[6], t_hi[6], t_lo[7], t_hi[7], - -cospi_24_64, cospi_8_64, &s_lo[6], &s_hi[6], - &s_lo[7], &s_hi[7]); - - // fdct_round_shift - // s0 + s2 - t_lo[0] = vaddq_s32(s_lo[0], s_lo[2]); - t_hi[0] = vaddq_s32(s_hi[0], s_hi[2]); - // s1 + s3 - t_lo[1] = vaddq_s32(s_lo[1], s_lo[3]); - t_hi[1] = vaddq_s32(s_hi[1], s_hi[3]); - // s0 - s2 - t_lo[2] = vsubq_s32(s_lo[0], s_lo[2]); - t_hi[2] = vsubq_s32(s_hi[0], s_hi[2]); - // s1 - s3 - t_lo[3] = vsubq_s32(s_lo[1], s_lo[3]); - t_hi[3] = vsubq_s32(s_hi[1], s_hi[3]); - // s4 + s6 - t_lo[4] = vrshrq_n_s32(vaddq_s32(s_lo[4], s_lo[6]), DCT_CONST_BITS); - t_hi[4] = vrshrq_n_s32(vaddq_s32(s_hi[4], s_hi[6]), DCT_CONST_BITS); - // s5 + s7 - t_lo[5] = vrshrq_n_s32(vaddq_s32(s_lo[5], s_lo[7]), DCT_CONST_BITS); - t_hi[5] = vrshrq_n_s32(vaddq_s32(s_hi[5], s_hi[7]), DCT_CONST_BITS); - // s4 - s6 - t_lo[6] = vrshrq_n_s32(vsubq_s32(s_lo[4], s_lo[6]), DCT_CONST_BITS); - t_hi[6] = vrshrq_n_s32(vsubq_s32(s_hi[4], s_hi[6]), DCT_CONST_BITS); - // s5 - s7 - t_lo[7] = vrshrq_n_s32(vsubq_s32(s_lo[5], s_lo[7]), DCT_CONST_BITS); - t_hi[7] = vrshrq_n_s32(vsubq_s32(s_hi[5], s_hi[7]), DCT_CONST_BITS); - - // stage 3 - // cospi_16_64 * (x2 + x3) - // cospi_16_64 * (x2 - x3) - butterfly_one_coeff_s32_noround(t_lo[2], t_hi[2], t_lo[3], t_hi[3], - cospi_16_64, &s_lo[2], &s_hi[2], &s_lo[3], - &s_hi[3]); - - // cospi_16_64 * (x6 + x7) - // cospi_16_64 * (x2 - x3) - butterfly_one_coeff_s32_noround(t_lo[6], t_hi[6], t_lo[7], t_hi[7], - cospi_16_64, &s_lo[6], &s_hi[6], &s_lo[7], - &s_hi[7]); - - // final fdct_round_shift - x_lo[2] = vrshrn_n_s32(s_lo[2], DCT_CONST_BITS); - x_hi[2] = vrshrn_n_s32(s_hi[2], DCT_CONST_BITS); - x_lo[3] = vrshrn_n_s32(s_lo[3], DCT_CONST_BITS); - x_hi[3] = vrshrn_n_s32(s_hi[3], DCT_CONST_BITS); - x_lo[6] = vrshrn_n_s32(s_lo[6], DCT_CONST_BITS); - x_hi[6] = vrshrn_n_s32(s_hi[6], DCT_CONST_BITS); - x_lo[7] = vrshrn_n_s32(s_lo[7], DCT_CONST_BITS); - x_hi[7] = vrshrn_n_s32(s_hi[7], DCT_CONST_BITS); - - // x0, x1, x4, x5 narrow down to 16-bits directly - x_lo[0] = vmovn_s32(t_lo[0]); - x_hi[0] = vmovn_s32(t_hi[0]); - x_lo[1] = vmovn_s32(t_lo[1]); - x_hi[1] = vmovn_s32(t_hi[1]); - x_lo[4] = vmovn_s32(t_lo[4]); - x_hi[4] = vmovn_s32(t_hi[4]); - x_lo[5] = vmovn_s32(t_lo[5]); - x_hi[5] = vmovn_s32(t_hi[5]); - - in[0] = vcombine_s16(x_lo[0], x_hi[0]); - in[1] = vnegq_s16(vcombine_s16(x_lo[4], x_hi[4])); - in[2] = vcombine_s16(x_lo[6], x_hi[6]); - in[3] = vnegq_s16(vcombine_s16(x_lo[2], x_hi[2])); - in[4] = vcombine_s16(x_lo[3], x_hi[3]); - in[5] = vnegq_s16(vcombine_s16(x_lo[7], x_hi[7])); - in[6] = vcombine_s16(x_lo[5], x_hi[5]); - in[7] = vnegq_s16(vcombine_s16(x_lo[1], x_hi[1])); - - transpose_s16_8x8(&in[0], &in[1], &in[2], &in[3], &in[4], &in[5], &in[6], - &in[7]); -} - -void vp9_fht8x8_neon(const int16_t *input, tran_low_t *output, int stride, - int tx_type) { - int16x8_t in[8]; - - switch (tx_type) { - case DCT_DCT: vpx_fdct8x8_neon(input, output, stride); break; - case ADST_DCT: - load_buffer_8x8(input, in, stride); - fadst8x8_neon(in); - // pass1 variant is not accurate enough - vpx_fdct8x8_pass2_neon(in); - right_shift_8x8(in, 1); - write_buffer_8x8(output, in, 8); - break; - case DCT_ADST: - load_buffer_8x8(input, in, stride); - // pass1 variant is not accurate enough - vpx_fdct8x8_pass2_neon(in); - fadst8x8_neon(in); - right_shift_8x8(in, 1); - write_buffer_8x8(output, in, 8); - break; - default: - assert(tx_type == ADST_ADST); - load_buffer_8x8(input, in, stride); - fadst8x8_neon(in); - fadst8x8_neon(in); - right_shift_8x8(in, 1); - write_buffer_8x8(output, in, 8); - break; - } -} - -static INLINE void load_buffer_16x16(const int16_t *input, int16x8_t *in0, - int16x8_t *in1, int stride) { - // load first 8 columns - load_buffer_8x8(input, in0, stride); - load_buffer_8x8(input + 8 * stride, in0 + 8, stride); - - input += 8; - // load second 8 columns - load_buffer_8x8(input, in1, stride); - load_buffer_8x8(input + 8 * stride, in1 + 8, stride); -} - -static INLINE void write_buffer_16x16(tran_low_t *output, int16x8_t *in0, - int16x8_t *in1, int stride) { - // write first 8 columns - write_buffer_8x8(output, in0, stride); - write_buffer_8x8(output + 8 * stride, in0 + 8, stride); - - // write second 8 columns - output += 8; - write_buffer_8x8(output, in1, stride); - write_buffer_8x8(output + 8 * stride, in1 + 8, stride); -} - -static INLINE void right_shift_16x16(int16x8_t *res0, int16x8_t *res1) { - // perform rounding operations - right_shift_8x8(res0, 2); - right_shift_8x8(res0 + 8, 2); - right_shift_8x8(res1, 2); - right_shift_8x8(res1 + 8, 2); -} - -static void fdct16_8col(int16x8_t *in) { - // perform 16x16 1-D DCT for 8 columns - int16x8_t i[8], s1[8], s2[8], s3[8], t[8]; - int16x4_t t_lo[8], t_hi[8]; - int32x4_t u_lo[8], u_hi[8]; - - // stage 1 - i[0] = vaddq_s16(in[0], in[15]); - i[1] = vaddq_s16(in[1], in[14]); - i[2] = vaddq_s16(in[2], in[13]); - i[3] = vaddq_s16(in[3], in[12]); - i[4] = vaddq_s16(in[4], in[11]); - i[5] = vaddq_s16(in[5], in[10]); - i[6] = vaddq_s16(in[6], in[9]); - i[7] = vaddq_s16(in[7], in[8]); - - // pass1 variant is not accurate enough - vpx_fdct8x8_pass2_neon(i); - transpose_s16_8x8(&i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6], &i[7]); - - // step 2 - s1[0] = vsubq_s16(in[7], in[8]); - s1[1] = vsubq_s16(in[6], in[9]); - s1[2] = vsubq_s16(in[5], in[10]); - s1[3] = vsubq_s16(in[4], in[11]); - s1[4] = vsubq_s16(in[3], in[12]); - s1[5] = vsubq_s16(in[2], in[13]); - s1[6] = vsubq_s16(in[1], in[14]); - s1[7] = vsubq_s16(in[0], in[15]); - - t[2] = vsubq_s16(s1[5], s1[2]); - t[3] = vsubq_s16(s1[4], s1[3]); - t[4] = vaddq_s16(s1[4], s1[3]); - t[5] = vaddq_s16(s1[5], s1[2]); - - t_lo[2] = vget_low_s16(t[2]); - t_hi[2] = vget_high_s16(t[2]); - t_lo[3] = vget_low_s16(t[3]); - t_hi[3] = vget_high_s16(t[3]); - t_lo[4] = vget_low_s16(t[4]); - t_hi[4] = vget_high_s16(t[4]); - t_lo[5] = vget_low_s16(t[5]); - t_hi[5] = vget_high_s16(t[5]); - - u_lo[2] = vmull_n_s16(t_lo[2], cospi_16_64); - u_hi[2] = vmull_n_s16(t_hi[2], cospi_16_64); - u_lo[3] = vmull_n_s16(t_lo[3], cospi_16_64); - u_hi[3] = vmull_n_s16(t_hi[3], cospi_16_64); - u_lo[4] = vmull_n_s16(t_lo[4], cospi_16_64); - u_hi[4] = vmull_n_s16(t_hi[4], cospi_16_64); - u_lo[5] = vmull_n_s16(t_lo[5], cospi_16_64); - u_hi[5] = vmull_n_s16(t_hi[5], cospi_16_64); - - t_lo[2] = vrshrn_n_s32(u_lo[2], DCT_CONST_BITS); - t_hi[2] = vrshrn_n_s32(u_hi[2], DCT_CONST_BITS); - t_lo[3] = vrshrn_n_s32(u_lo[3], DCT_CONST_BITS); - t_hi[3] = vrshrn_n_s32(u_hi[3], DCT_CONST_BITS); - t_lo[4] = vrshrn_n_s32(u_lo[4], DCT_CONST_BITS); - t_hi[4] = vrshrn_n_s32(u_hi[4], DCT_CONST_BITS); - t_lo[5] = vrshrn_n_s32(u_lo[5], DCT_CONST_BITS); - t_hi[5] = vrshrn_n_s32(u_hi[5], DCT_CONST_BITS); - - s2[2] = vcombine_s16(t_lo[2], t_hi[2]); - s2[3] = vcombine_s16(t_lo[3], t_hi[3]); - s2[4] = vcombine_s16(t_lo[4], t_hi[4]); - s2[5] = vcombine_s16(t_lo[5], t_hi[5]); - - // step 3 - s3[0] = vaddq_s16(s1[0], s2[3]); - s3[1] = vaddq_s16(s1[1], s2[2]); - s3[2] = vsubq_s16(s1[1], s2[2]); - s3[3] = vsubq_s16(s1[0], s2[3]); - s3[4] = vsubq_s16(s1[7], s2[4]); - s3[5] = vsubq_s16(s1[6], s2[5]); - s3[6] = vaddq_s16(s1[6], s2[5]); - s3[7] = vaddq_s16(s1[7], s2[4]); - - // step 4 - t_lo[0] = vget_low_s16(s3[0]); - t_hi[0] = vget_high_s16(s3[0]); - t_lo[1] = vget_low_s16(s3[1]); - t_hi[1] = vget_high_s16(s3[1]); - t_lo[2] = vget_low_s16(s3[2]); - t_hi[2] = vget_high_s16(s3[2]); - t_lo[3] = vget_low_s16(s3[3]); - t_hi[3] = vget_high_s16(s3[3]); - t_lo[4] = vget_low_s16(s3[4]); - t_hi[4] = vget_high_s16(s3[4]); - t_lo[5] = vget_low_s16(s3[5]); - t_hi[5] = vget_high_s16(s3[5]); - t_lo[6] = vget_low_s16(s3[6]); - t_hi[6] = vget_high_s16(s3[6]); - t_lo[7] = vget_low_s16(s3[7]); - t_hi[7] = vget_high_s16(s3[7]); - - // u[1] = -cospi_8_64 * t[1] + cospi_24_64 * t[6] - // u[6] = cospi_24_64 * t[1] + cospi_8_64 * t[6] - butterfly_two_coeff_s16_s32_noround(t_lo[1], t_hi[1], t_lo[6], t_hi[6], - -cospi_8_64, cospi_24_64, &u_lo[1], - &u_hi[1], &u_lo[6], &u_hi[6]); - - // u[5] = -cospi_24_64 * t[5] + cospi_8_64 * t[2] - // u[2] = cospi_8_64 * t[5] + cospi_24_64 * t[2] - butterfly_two_coeff_s16_s32_noround(t_lo[5], t_hi[5], t_lo[2], t_hi[2], - -cospi_24_64, cospi_8_64, &u_lo[5], - &u_hi[5], &u_lo[2], &u_hi[2]); - - t_lo[1] = vrshrn_n_s32(u_lo[1], DCT_CONST_BITS); - t_hi[1] = vrshrn_n_s32(u_hi[1], DCT_CONST_BITS); - t_lo[2] = vrshrn_n_s32(u_lo[2], DCT_CONST_BITS); - t_hi[2] = vrshrn_n_s32(u_hi[2], DCT_CONST_BITS); - t_lo[5] = vrshrn_n_s32(u_lo[5], DCT_CONST_BITS); - t_hi[5] = vrshrn_n_s32(u_hi[5], DCT_CONST_BITS); - t_lo[6] = vrshrn_n_s32(u_lo[6], DCT_CONST_BITS); - t_hi[6] = vrshrn_n_s32(u_hi[6], DCT_CONST_BITS); - - s2[1] = vcombine_s16(t_lo[1], t_hi[1]); - s2[2] = vcombine_s16(t_lo[2], t_hi[2]); - s2[5] = vcombine_s16(t_lo[5], t_hi[5]); - s2[6] = vcombine_s16(t_lo[6], t_hi[6]); - - // step 5 - s1[0] = vaddq_s16(s3[0], s2[1]); - s1[1] = vsubq_s16(s3[0], s2[1]); - s1[2] = vaddq_s16(s3[3], s2[2]); - s1[3] = vsubq_s16(s3[3], s2[2]); - s1[4] = vsubq_s16(s3[4], s2[5]); - s1[5] = vaddq_s16(s3[4], s2[5]); - s1[6] = vsubq_s16(s3[7], s2[6]); - s1[7] = vaddq_s16(s3[7], s2[6]); - - // step 6 - t_lo[0] = vget_low_s16(s1[0]); - t_hi[0] = vget_high_s16(s1[0]); - t_lo[1] = vget_low_s16(s1[1]); - t_hi[1] = vget_high_s16(s1[1]); - t_lo[2] = vget_low_s16(s1[2]); - t_hi[2] = vget_high_s16(s1[2]); - t_lo[3] = vget_low_s16(s1[3]); - t_hi[3] = vget_high_s16(s1[3]); - t_lo[4] = vget_low_s16(s1[4]); - t_hi[4] = vget_high_s16(s1[4]); - t_lo[5] = vget_low_s16(s1[5]); - t_hi[5] = vget_high_s16(s1[5]); - t_lo[6] = vget_low_s16(s1[6]); - t_hi[6] = vget_high_s16(s1[6]); - t_lo[7] = vget_low_s16(s1[7]); - t_hi[7] = vget_high_s16(s1[7]); - - // u[0] = step1[7] * cospi_2_64 + step1[0] * cospi_30_64 - // u[7] = step1[7] * cospi_30_64 - step1[0] * cospi_2_64 - butterfly_two_coeff_s16_s32_noround(t_lo[7], t_hi[7], t_lo[0], t_hi[0], - cospi_2_64, cospi_30_64, &u_lo[0], - &u_hi[0], &u_lo[7], &u_hi[7]); - - // u[1] = step1[6] * cospi_18_64 + step1[1] * cospi_14_64 - // u[6] = step1[6] * cospi_14_64 - step1[1] * cospi_18_64 - butterfly_two_coeff_s16_s32_noround(t_lo[6], t_hi[6], t_lo[1], t_hi[1], - cospi_18_64, cospi_14_64, &u_lo[1], - &u_hi[1], &u_lo[6], &u_hi[6]); - - // u[2] = step1[5] * cospi_10_64 + step1[2] * cospi_22_64 - // u[5] = step1[5] * cospi_22_64 - step1[2] * cospi_10_64 - butterfly_two_coeff_s16_s32_noround(t_lo[5], t_hi[5], t_lo[2], t_hi[2], - cospi_10_64, cospi_22_64, &u_lo[2], - &u_hi[2], &u_lo[5], &u_hi[5]); - - // u[3] = step1[4] * cospi_26_64 + step1[3] * cospi_6_64 - // u[4] = step1[4] * cospi_6_64 - step1[3] * cospi_26_64 - butterfly_two_coeff_s16_s32_noround(t_lo[4], t_hi[4], t_lo[3], t_hi[3], - cospi_26_64, cospi_6_64, &u_lo[3], - &u_hi[3], &u_lo[4], &u_hi[4]); - - // final fdct_round_shift - t_lo[0] = vrshrn_n_s32(u_lo[0], DCT_CONST_BITS); - t_hi[0] = vrshrn_n_s32(u_hi[0], DCT_CONST_BITS); - t_lo[1] = vrshrn_n_s32(u_lo[1], DCT_CONST_BITS); - t_hi[1] = vrshrn_n_s32(u_hi[1], DCT_CONST_BITS); - t_lo[2] = vrshrn_n_s32(u_lo[2], DCT_CONST_BITS); - t_hi[2] = vrshrn_n_s32(u_hi[2], DCT_CONST_BITS); - t_lo[3] = vrshrn_n_s32(u_lo[3], DCT_CONST_BITS); - t_hi[3] = vrshrn_n_s32(u_hi[3], DCT_CONST_BITS); - t_lo[4] = vrshrn_n_s32(u_lo[4], DCT_CONST_BITS); - t_hi[4] = vrshrn_n_s32(u_hi[4], DCT_CONST_BITS); - t_lo[5] = vrshrn_n_s32(u_lo[5], DCT_CONST_BITS); - t_hi[5] = vrshrn_n_s32(u_hi[5], DCT_CONST_BITS); - t_lo[6] = vrshrn_n_s32(u_lo[6], DCT_CONST_BITS); - t_hi[6] = vrshrn_n_s32(u_hi[6], DCT_CONST_BITS); - t_lo[7] = vrshrn_n_s32(u_lo[7], DCT_CONST_BITS); - t_hi[7] = vrshrn_n_s32(u_hi[7], DCT_CONST_BITS); - - in[0] = i[0]; - in[2] = i[1]; - in[4] = i[2]; - in[6] = i[3]; - in[8] = i[4]; - in[10] = i[5]; - in[12] = i[6]; - in[14] = i[7]; - in[1] = vcombine_s16(t_lo[0], t_hi[0]); - in[3] = vcombine_s16(t_lo[4], t_hi[4]); - in[5] = vcombine_s16(t_lo[2], t_hi[2]); - in[7] = vcombine_s16(t_lo[6], t_hi[6]); - in[9] = vcombine_s16(t_lo[1], t_hi[1]); - in[11] = vcombine_s16(t_lo[5], t_hi[5]); - in[13] = vcombine_s16(t_lo[3], t_hi[3]); - in[15] = vcombine_s16(t_lo[7], t_hi[7]); -} - -static void fadst16_8col(int16x8_t *in) { - // perform 16x16 1-D ADST for 8 columns - int16x4_t x_lo[16], x_hi[16]; - int32x4_t s_lo[16], s_hi[16]; - int32x4_t t_lo[16], t_hi[16]; - - x_lo[0] = vget_low_s16(in[15]); - x_hi[0] = vget_high_s16(in[15]); - x_lo[1] = vget_low_s16(in[0]); - x_hi[1] = vget_high_s16(in[0]); - x_lo[2] = vget_low_s16(in[13]); - x_hi[2] = vget_high_s16(in[13]); - x_lo[3] = vget_low_s16(in[2]); - x_hi[3] = vget_high_s16(in[2]); - x_lo[4] = vget_low_s16(in[11]); - x_hi[4] = vget_high_s16(in[11]); - x_lo[5] = vget_low_s16(in[4]); - x_hi[5] = vget_high_s16(in[4]); - x_lo[6] = vget_low_s16(in[9]); - x_hi[6] = vget_high_s16(in[9]); - x_lo[7] = vget_low_s16(in[6]); - x_hi[7] = vget_high_s16(in[6]); - x_lo[8] = vget_low_s16(in[7]); - x_hi[8] = vget_high_s16(in[7]); - x_lo[9] = vget_low_s16(in[8]); - x_hi[9] = vget_high_s16(in[8]); - x_lo[10] = vget_low_s16(in[5]); - x_hi[10] = vget_high_s16(in[5]); - x_lo[11] = vget_low_s16(in[10]); - x_hi[11] = vget_high_s16(in[10]); - x_lo[12] = vget_low_s16(in[3]); - x_hi[12] = vget_high_s16(in[3]); - x_lo[13] = vget_low_s16(in[12]); - x_hi[13] = vget_high_s16(in[12]); - x_lo[14] = vget_low_s16(in[1]); - x_hi[14] = vget_high_s16(in[1]); - x_lo[15] = vget_low_s16(in[14]); - x_hi[15] = vget_high_s16(in[14]); - - // stage 1 - // s0 = cospi_1_64 * x0 + cospi_31_64 * x1; - // s1 = cospi_31_64 * x0 - cospi_1_64 * x1; - butterfly_two_coeff_s16_s32_noround(x_lo[0], x_hi[0], x_lo[1], x_hi[1], - cospi_1_64, cospi_31_64, &s_lo[0], - &s_hi[0], &s_lo[1], &s_hi[1]); - // s2 = cospi_5_64 * x2 + cospi_27_64 * x3; - // s3 = cospi_27_64 * x2 - cospi_5_64 * x3; - butterfly_two_coeff_s16_s32_noround(x_lo[2], x_hi[2], x_lo[3], x_hi[3], - cospi_5_64, cospi_27_64, &s_lo[2], - &s_hi[2], &s_lo[3], &s_hi[3]); - // s4 = cospi_9_64 * x4 + cospi_23_64 * x5; - // s5 = cospi_23_64 * x4 - cospi_9_64 * x5; - butterfly_two_coeff_s16_s32_noround(x_lo[4], x_hi[4], x_lo[5], x_hi[5], - cospi_9_64, cospi_23_64, &s_lo[4], - &s_hi[4], &s_lo[5], &s_hi[5]); - // s6 = cospi_13_64 * x6 + cospi_19_64 * x7; - // s7 = cospi_19_64 * x6 - cospi_13_64 * x7; - butterfly_two_coeff_s16_s32_noround(x_lo[6], x_hi[6], x_lo[7], x_hi[7], - cospi_13_64, cospi_19_64, &s_lo[6], - &s_hi[6], &s_lo[7], &s_hi[7]); - // s8 = cospi_17_64 * x8 + cospi_15_64 * x9; - // s9 = cospi_15_64 * x8 - cospi_17_64 * x9; - butterfly_two_coeff_s16_s32_noround(x_lo[8], x_hi[8], x_lo[9], x_hi[9], - cospi_17_64, cospi_15_64, &s_lo[8], - &s_hi[8], &s_lo[9], &s_hi[9]); - // s10 = cospi_21_64 * x10 + cospi_11_64 * x11; - // s11 = cospi_11_64 * x10 - cospi_21_64 * x11; - butterfly_two_coeff_s16_s32_noround(x_lo[10], x_hi[10], x_lo[11], x_hi[11], - cospi_21_64, cospi_11_64, &s_lo[10], - &s_hi[10], &s_lo[11], &s_hi[11]); - // s12 = cospi_25_64 * x12 + cospi_7_64 * x13; - // s13 = cospi_7_64 * x12 - cospi_25_64 * x13; - butterfly_two_coeff_s16_s32_noround(x_lo[12], x_hi[12], x_lo[13], x_hi[13], - cospi_25_64, cospi_7_64, &s_lo[12], - &s_hi[12], &s_lo[13], &s_hi[13]); - // s14 = cospi_29_64 * x14 + cospi_3_64 * x15; - // s15 = cospi_3_64 * x14 - cospi_29_64 * x15; - butterfly_two_coeff_s16_s32_noround(x_lo[14], x_hi[14], x_lo[15], x_hi[15], - cospi_29_64, cospi_3_64, &s_lo[14], - &s_hi[14], &s_lo[15], &s_hi[15]); - - // fdct_round_shift - t_lo[0] = vrshrq_n_s32(vaddq_s32(s_lo[0], s_lo[8]), DCT_CONST_BITS); - t_hi[0] = vrshrq_n_s32(vaddq_s32(s_hi[0], s_hi[8]), DCT_CONST_BITS); - t_lo[1] = vrshrq_n_s32(vaddq_s32(s_lo[1], s_lo[9]), DCT_CONST_BITS); - t_hi[1] = vrshrq_n_s32(vaddq_s32(s_hi[1], s_hi[9]), DCT_CONST_BITS); - t_lo[2] = vrshrq_n_s32(vaddq_s32(s_lo[2], s_lo[10]), DCT_CONST_BITS); - t_hi[2] = vrshrq_n_s32(vaddq_s32(s_hi[2], s_hi[10]), DCT_CONST_BITS); - t_lo[3] = vrshrq_n_s32(vaddq_s32(s_lo[3], s_lo[11]), DCT_CONST_BITS); - t_hi[3] = vrshrq_n_s32(vaddq_s32(s_hi[3], s_hi[11]), DCT_CONST_BITS); - t_lo[4] = vrshrq_n_s32(vaddq_s32(s_lo[4], s_lo[12]), DCT_CONST_BITS); - t_hi[4] = vrshrq_n_s32(vaddq_s32(s_hi[4], s_hi[12]), DCT_CONST_BITS); - t_lo[5] = vrshrq_n_s32(vaddq_s32(s_lo[5], s_lo[13]), DCT_CONST_BITS); - t_hi[5] = vrshrq_n_s32(vaddq_s32(s_hi[5], s_hi[13]), DCT_CONST_BITS); - t_lo[6] = vrshrq_n_s32(vaddq_s32(s_lo[6], s_lo[14]), DCT_CONST_BITS); - t_hi[6] = vrshrq_n_s32(vaddq_s32(s_hi[6], s_hi[14]), DCT_CONST_BITS); - t_lo[7] = vrshrq_n_s32(vaddq_s32(s_lo[7], s_lo[15]), DCT_CONST_BITS); - t_hi[7] = vrshrq_n_s32(vaddq_s32(s_hi[7], s_hi[15]), DCT_CONST_BITS); - t_lo[8] = vrshrq_n_s32(vsubq_s32(s_lo[0], s_lo[8]), DCT_CONST_BITS); - t_hi[8] = vrshrq_n_s32(vsubq_s32(s_hi[0], s_hi[8]), DCT_CONST_BITS); - t_lo[9] = vrshrq_n_s32(vsubq_s32(s_lo[1], s_lo[9]), DCT_CONST_BITS); - t_hi[9] = vrshrq_n_s32(vsubq_s32(s_hi[1], s_hi[9]), DCT_CONST_BITS); - t_lo[10] = vrshrq_n_s32(vsubq_s32(s_lo[2], s_lo[10]), DCT_CONST_BITS); - t_hi[10] = vrshrq_n_s32(vsubq_s32(s_hi[2], s_hi[10]), DCT_CONST_BITS); - t_lo[11] = vrshrq_n_s32(vsubq_s32(s_lo[3], s_lo[11]), DCT_CONST_BITS); - t_hi[11] = vrshrq_n_s32(vsubq_s32(s_hi[3], s_hi[11]), DCT_CONST_BITS); - t_lo[12] = vrshrq_n_s32(vsubq_s32(s_lo[4], s_lo[12]), DCT_CONST_BITS); - t_hi[12] = vrshrq_n_s32(vsubq_s32(s_hi[4], s_hi[12]), DCT_CONST_BITS); - t_lo[13] = vrshrq_n_s32(vsubq_s32(s_lo[5], s_lo[13]), DCT_CONST_BITS); - t_hi[13] = vrshrq_n_s32(vsubq_s32(s_hi[5], s_hi[13]), DCT_CONST_BITS); - t_lo[14] = vrshrq_n_s32(vsubq_s32(s_lo[6], s_lo[14]), DCT_CONST_BITS); - t_hi[14] = vrshrq_n_s32(vsubq_s32(s_hi[6], s_hi[14]), DCT_CONST_BITS); - t_lo[15] = vrshrq_n_s32(vsubq_s32(s_lo[7], s_lo[15]), DCT_CONST_BITS); - t_hi[15] = vrshrq_n_s32(vsubq_s32(s_hi[7], s_hi[15]), DCT_CONST_BITS); - - // stage 2 - s_lo[0] = t_lo[0]; - s_hi[0] = t_hi[0]; - s_lo[1] = t_lo[1]; - s_hi[1] = t_hi[1]; - s_lo[2] = t_lo[2]; - s_hi[2] = t_hi[2]; - s_lo[3] = t_lo[3]; - s_hi[3] = t_hi[3]; - s_lo[4] = t_lo[4]; - s_hi[4] = t_hi[4]; - s_lo[5] = t_lo[5]; - s_hi[5] = t_hi[5]; - s_lo[6] = t_lo[6]; - s_hi[6] = t_hi[6]; - s_lo[7] = t_lo[7]; - s_hi[7] = t_hi[7]; - // s8 = x8 * cospi_4_64 + x9 * cospi_28_64; - // s9 = x8 * cospi_28_64 - x9 * cospi_4_64; - butterfly_two_coeff_s32_noround(t_lo[8], t_hi[8], t_lo[9], t_hi[9], - cospi_4_64, cospi_28_64, &s_lo[8], &s_hi[8], - &s_lo[9], &s_hi[9]); - // s10 = x10 * cospi_20_64 + x11 * cospi_12_64; - // s11 = x10 * cospi_12_64 - x11 * cospi_20_64; - butterfly_two_coeff_s32_noround(t_lo[10], t_hi[10], t_lo[11], t_hi[11], - cospi_20_64, cospi_12_64, &s_lo[10], - &s_hi[10], &s_lo[11], &s_hi[11]); - // s12 = -x12 * cospi_28_64 + x13 * cospi_4_64; - // s13 = x12 * cospi_4_64 + x13 * cospi_28_64; - butterfly_two_coeff_s32_noround(t_lo[13], t_hi[13], t_lo[12], t_hi[12], - cospi_28_64, cospi_4_64, &s_lo[13], &s_hi[13], - &s_lo[12], &s_hi[12]); - // s14 = -x14 * cospi_12_64 + x15 * cospi_20_64; - // s15 = x14 * cospi_20_64 + x15 * cospi_12_64; - butterfly_two_coeff_s32_noround(t_lo[15], t_hi[15], t_lo[14], t_hi[14], - cospi_12_64, cospi_20_64, &s_lo[15], - &s_hi[15], &s_lo[14], &s_hi[14]); - - // s0 + s4 - t_lo[0] = vaddq_s32(s_lo[0], s_lo[4]); - t_hi[0] = vaddq_s32(s_hi[0], s_hi[4]); - // s1 + s5 - t_lo[1] = vaddq_s32(s_lo[1], s_lo[5]); - t_hi[1] = vaddq_s32(s_hi[1], s_hi[5]); - // s2 + s6 - t_lo[2] = vaddq_s32(s_lo[2], s_lo[6]); - t_hi[2] = vaddq_s32(s_hi[2], s_hi[6]); - // s3 + s7 - t_lo[3] = vaddq_s32(s_lo[3], s_lo[7]); - t_hi[3] = vaddq_s32(s_hi[3], s_hi[7]); - // s0 - s4 - t_lo[4] = vsubq_s32(s_lo[0], s_lo[4]); - t_hi[4] = vsubq_s32(s_hi[0], s_hi[4]); - // s1 - s7 - t_lo[5] = vsubq_s32(s_lo[1], s_lo[5]); - t_hi[5] = vsubq_s32(s_hi[1], s_hi[5]); - // s2 - s6 - t_lo[6] = vsubq_s32(s_lo[2], s_lo[6]); - t_hi[6] = vsubq_s32(s_hi[2], s_hi[6]); - // s3 - s7 - t_lo[7] = vsubq_s32(s_lo[3], s_lo[7]); - t_hi[7] = vsubq_s32(s_hi[3], s_hi[7]); - // s8 + s12 - t_lo[8] = vaddq_s32(s_lo[8], s_lo[12]); - t_hi[8] = vaddq_s32(s_hi[8], s_hi[12]); - // s9 + s13 - t_lo[9] = vaddq_s32(s_lo[9], s_lo[13]); - t_hi[9] = vaddq_s32(s_hi[9], s_hi[13]); - // s10 + s14 - t_lo[10] = vaddq_s32(s_lo[10], s_lo[14]); - t_hi[10] = vaddq_s32(s_hi[10], s_hi[14]); - // s11 + s15 - t_lo[11] = vaddq_s32(s_lo[11], s_lo[15]); - t_hi[11] = vaddq_s32(s_hi[11], s_hi[15]); - // s8 + s12 - t_lo[12] = vsubq_s32(s_lo[8], s_lo[12]); - t_hi[12] = vsubq_s32(s_hi[8], s_hi[12]); - // s9 + s13 - t_lo[13] = vsubq_s32(s_lo[9], s_lo[13]); - t_hi[13] = vsubq_s32(s_hi[9], s_hi[13]); - // s10 + s14 - t_lo[14] = vsubq_s32(s_lo[10], s_lo[14]); - t_hi[14] = vsubq_s32(s_hi[10], s_hi[14]); - // s11 + s15 - t_lo[15] = vsubq_s32(s_lo[11], s_lo[15]); - t_hi[15] = vsubq_s32(s_hi[11], s_hi[15]); - - t_lo[8] = vrshrq_n_s32(t_lo[8], DCT_CONST_BITS); - t_hi[8] = vrshrq_n_s32(t_hi[8], DCT_CONST_BITS); - t_lo[9] = vrshrq_n_s32(t_lo[9], DCT_CONST_BITS); - t_hi[9] = vrshrq_n_s32(t_hi[9], DCT_CONST_BITS); - t_lo[10] = vrshrq_n_s32(t_lo[10], DCT_CONST_BITS); - t_hi[10] = vrshrq_n_s32(t_hi[10], DCT_CONST_BITS); - t_lo[11] = vrshrq_n_s32(t_lo[11], DCT_CONST_BITS); - t_hi[11] = vrshrq_n_s32(t_hi[11], DCT_CONST_BITS); - t_lo[12] = vrshrq_n_s32(t_lo[12], DCT_CONST_BITS); - t_hi[12] = vrshrq_n_s32(t_hi[12], DCT_CONST_BITS); - t_lo[13] = vrshrq_n_s32(t_lo[13], DCT_CONST_BITS); - t_hi[13] = vrshrq_n_s32(t_hi[13], DCT_CONST_BITS); - t_lo[14] = vrshrq_n_s32(t_lo[14], DCT_CONST_BITS); - t_hi[14] = vrshrq_n_s32(t_hi[14], DCT_CONST_BITS); - t_lo[15] = vrshrq_n_s32(t_lo[15], DCT_CONST_BITS); - t_hi[15] = vrshrq_n_s32(t_hi[15], DCT_CONST_BITS); - - // stage 3 - s_lo[0] = t_lo[0]; - s_hi[0] = t_hi[0]; - s_lo[1] = t_lo[1]; - s_hi[1] = t_hi[1]; - s_lo[2] = t_lo[2]; - s_hi[2] = t_hi[2]; - s_lo[3] = t_lo[3]; - s_hi[3] = t_hi[3]; - // s4 = x4 * cospi_8_64 + x5 * cospi_24_64; - // s5 = x4 * cospi_24_64 - x5 * cospi_8_64; - butterfly_two_coeff_s32_noround(t_lo[4], t_hi[4], t_lo[5], t_hi[5], - cospi_8_64, cospi_24_64, &s_lo[4], &s_hi[4], - &s_lo[5], &s_hi[5]); - // s6 = -x6 * cospi_24_64 + x7 * cospi_8_64; - // s7 = x6 * cospi_8_64 + x7 * cospi_24_64; - butterfly_two_coeff_s32_noround(t_lo[7], t_hi[7], t_lo[6], t_hi[6], - cospi_24_64, cospi_8_64, &s_lo[7], &s_hi[7], - &s_lo[6], &s_hi[6]); - s_lo[8] = t_lo[8]; - s_hi[8] = t_hi[8]; - s_lo[9] = t_lo[9]; - s_hi[9] = t_hi[9]; - s_lo[10] = t_lo[10]; - s_hi[10] = t_hi[10]; - s_lo[11] = t_lo[11]; - s_hi[11] = t_hi[11]; - // s12 = x12 * cospi_8_64 + x13 * cospi_24_64; - // s13 = x12 * cospi_24_64 - x13 * cospi_8_64; - butterfly_two_coeff_s32_noround(t_lo[12], t_hi[12], t_lo[13], t_hi[13], - cospi_8_64, cospi_24_64, &s_lo[12], &s_hi[12], - &s_lo[13], &s_hi[13]); - // s14 = -x14 * cospi_24_64 + x15 * cospi_8_64; - // s15 = x14 * cospi_8_64 + x15 * cospi_24_64; - butterfly_two_coeff_s32_noround(t_lo[15], t_hi[15], t_lo[14], t_hi[14], - cospi_24_64, cospi_8_64, &s_lo[15], &s_hi[15], - &s_lo[14], &s_hi[14]); - - // s0 + s4 - t_lo[0] = vaddq_s32(s_lo[0], s_lo[2]); - t_hi[0] = vaddq_s32(s_hi[0], s_hi[2]); - // s1 + s3 - t_lo[1] = vaddq_s32(s_lo[1], s_lo[3]); - t_hi[1] = vaddq_s32(s_hi[1], s_hi[3]); - // s0 - s4 - t_lo[2] = vsubq_s32(s_lo[0], s_lo[2]); - t_hi[2] = vsubq_s32(s_hi[0], s_hi[2]); - // s1 - s3 - t_lo[3] = vsubq_s32(s_lo[1], s_lo[3]); - t_hi[3] = vsubq_s32(s_hi[1], s_hi[3]); - // s4 + s6 - t_lo[4] = vaddq_s32(s_lo[4], s_lo[6]); - t_hi[4] = vaddq_s32(s_hi[4], s_hi[6]); - // s5 + s7 - t_lo[5] = vaddq_s32(s_lo[5], s_lo[7]); - t_hi[5] = vaddq_s32(s_hi[5], s_hi[7]); - // s4 - s6 - t_lo[6] = vsubq_s32(s_lo[4], s_lo[6]); - t_hi[6] = vsubq_s32(s_hi[4], s_hi[6]); - // s5 - s7 - t_lo[7] = vsubq_s32(s_lo[5], s_lo[7]); - t_hi[7] = vsubq_s32(s_hi[5], s_hi[7]); - // s8 + s10 - t_lo[8] = vaddq_s32(s_lo[8], s_lo[10]); - t_hi[8] = vaddq_s32(s_hi[8], s_hi[10]); - // s9 + s11 - t_lo[9] = vaddq_s32(s_lo[9], s_lo[11]); - t_hi[9] = vaddq_s32(s_hi[9], s_hi[11]); - // s8 - s10 - t_lo[10] = vsubq_s32(s_lo[8], s_lo[10]); - t_hi[10] = vsubq_s32(s_hi[8], s_hi[10]); - // s9 - s11 - t_lo[11] = vsubq_s32(s_lo[9], s_lo[11]); - t_hi[11] = vsubq_s32(s_hi[9], s_hi[11]); - // s12 + s14 - t_lo[12] = vaddq_s32(s_lo[12], s_lo[14]); - t_hi[12] = vaddq_s32(s_hi[12], s_hi[14]); - // s13 + s15 - t_lo[13] = vaddq_s32(s_lo[13], s_lo[15]); - t_hi[13] = vaddq_s32(s_hi[13], s_hi[15]); - // s12 - s14 - t_lo[14] = vsubq_s32(s_lo[12], s_lo[14]); - t_hi[14] = vsubq_s32(s_hi[12], s_hi[14]); - // s13 - s15 - t_lo[15] = vsubq_s32(s_lo[13], s_lo[15]); - t_hi[15] = vsubq_s32(s_hi[13], s_hi[15]); - - t_lo[4] = vrshrq_n_s32(t_lo[4], DCT_CONST_BITS); - t_hi[4] = vrshrq_n_s32(t_hi[4], DCT_CONST_BITS); - t_lo[5] = vrshrq_n_s32(t_lo[5], DCT_CONST_BITS); - t_hi[5] = vrshrq_n_s32(t_hi[5], DCT_CONST_BITS); - t_lo[6] = vrshrq_n_s32(t_lo[6], DCT_CONST_BITS); - t_hi[6] = vrshrq_n_s32(t_hi[6], DCT_CONST_BITS); - t_lo[7] = vrshrq_n_s32(t_lo[7], DCT_CONST_BITS); - t_hi[7] = vrshrq_n_s32(t_hi[7], DCT_CONST_BITS); - t_lo[12] = vrshrq_n_s32(t_lo[12], DCT_CONST_BITS); - t_hi[12] = vrshrq_n_s32(t_hi[12], DCT_CONST_BITS); - t_lo[13] = vrshrq_n_s32(t_lo[13], DCT_CONST_BITS); - t_hi[13] = vrshrq_n_s32(t_hi[13], DCT_CONST_BITS); - t_lo[14] = vrshrq_n_s32(t_lo[14], DCT_CONST_BITS); - t_hi[14] = vrshrq_n_s32(t_hi[14], DCT_CONST_BITS); - t_lo[15] = vrshrq_n_s32(t_lo[15], DCT_CONST_BITS); - t_hi[15] = vrshrq_n_s32(t_hi[15], DCT_CONST_BITS); - - // stage 4 - // s2 = (-cospi_16_64) * (x2 + x3); - // s3 = cospi_16_64 * (x2 - x3); - butterfly_one_coeff_s32_noround(t_lo[3], t_hi[3], t_lo[2], t_hi[2], - -cospi_16_64, &s_lo[2], &s_hi[2], &s_lo[3], - &s_hi[3]); - // s6 = cospi_16_64 * (x6 + x7); - // s7 = cospi_16_64 * (-x6 + x7); - butterfly_one_coeff_s32_noround(t_lo[7], t_hi[7], t_lo[6], t_hi[6], - cospi_16_64, &s_lo[6], &s_hi[6], &s_lo[7], - &s_hi[7]); - // s10 = cospi_16_64 * (x10 + x11); - // s11 = cospi_16_64 * (-x10 + x11); - butterfly_one_coeff_s32_noround(t_lo[11], t_hi[11], t_lo[10], t_hi[10], - cospi_16_64, &s_lo[10], &s_hi[10], &s_lo[11], - &s_hi[11]); - // s14 = (-cospi_16_64) * (x14 + x15); - // s15 = cospi_16_64 * (x14 - x15); - butterfly_one_coeff_s32_noround(t_lo[15], t_hi[15], t_lo[14], t_hi[14], - -cospi_16_64, &s_lo[14], &s_hi[14], &s_lo[15], - &s_hi[15]); - - // final fdct_round_shift - x_lo[2] = vrshrn_n_s32(s_lo[2], DCT_CONST_BITS); - x_hi[2] = vrshrn_n_s32(s_hi[2], DCT_CONST_BITS); - x_lo[3] = vrshrn_n_s32(s_lo[3], DCT_CONST_BITS); - x_hi[3] = vrshrn_n_s32(s_hi[3], DCT_CONST_BITS); - x_lo[6] = vrshrn_n_s32(s_lo[6], DCT_CONST_BITS); - x_hi[6] = vrshrn_n_s32(s_hi[6], DCT_CONST_BITS); - x_lo[7] = vrshrn_n_s32(s_lo[7], DCT_CONST_BITS); - x_hi[7] = vrshrn_n_s32(s_hi[7], DCT_CONST_BITS); - x_lo[10] = vrshrn_n_s32(s_lo[10], DCT_CONST_BITS); - x_hi[10] = vrshrn_n_s32(s_hi[10], DCT_CONST_BITS); - x_lo[11] = vrshrn_n_s32(s_lo[11], DCT_CONST_BITS); - x_hi[11] = vrshrn_n_s32(s_hi[11], DCT_CONST_BITS); - x_lo[14] = vrshrn_n_s32(s_lo[14], DCT_CONST_BITS); - x_hi[14] = vrshrn_n_s32(s_hi[14], DCT_CONST_BITS); - x_lo[15] = vrshrn_n_s32(s_lo[15], DCT_CONST_BITS); - x_hi[15] = vrshrn_n_s32(s_hi[15], DCT_CONST_BITS); - - // x0, x1, x4, x5, x8, x9, x12, x13 narrow down to 16-bits directly - x_lo[0] = vmovn_s32(t_lo[0]); - x_hi[0] = vmovn_s32(t_hi[0]); - x_lo[1] = vmovn_s32(t_lo[1]); - x_hi[1] = vmovn_s32(t_hi[1]); - x_lo[4] = vmovn_s32(t_lo[4]); - x_hi[4] = vmovn_s32(t_hi[4]); - x_lo[5] = vmovn_s32(t_lo[5]); - x_hi[5] = vmovn_s32(t_hi[5]); - x_lo[8] = vmovn_s32(t_lo[8]); - x_hi[8] = vmovn_s32(t_hi[8]); - x_lo[9] = vmovn_s32(t_lo[9]); - x_hi[9] = vmovn_s32(t_hi[9]); - x_lo[12] = vmovn_s32(t_lo[12]); - x_hi[12] = vmovn_s32(t_hi[12]); - x_lo[13] = vmovn_s32(t_lo[13]); - x_hi[13] = vmovn_s32(t_hi[13]); - - in[0] = vcombine_s16(x_lo[0], x_hi[0]); - in[1] = vnegq_s16(vcombine_s16(x_lo[8], x_hi[8])); - in[2] = vcombine_s16(x_lo[12], x_hi[12]); - in[3] = vnegq_s16(vcombine_s16(x_lo[4], x_hi[4])); - in[4] = vcombine_s16(x_lo[6], x_hi[6]); - in[5] = vcombine_s16(x_lo[14], x_hi[14]); - in[6] = vcombine_s16(x_lo[10], x_hi[10]); - in[7] = vcombine_s16(x_lo[2], x_hi[2]); - in[8] = vcombine_s16(x_lo[3], x_hi[3]); - in[9] = vcombine_s16(x_lo[11], x_hi[11]); - in[10] = vcombine_s16(x_lo[15], x_hi[15]); - in[11] = vcombine_s16(x_lo[7], x_hi[7]); - in[12] = vcombine_s16(x_lo[5], x_hi[5]); - in[13] = vnegq_s16(vcombine_s16(x_lo[13], x_hi[13])); - in[14] = vcombine_s16(x_lo[9], x_hi[9]); - in[15] = vnegq_s16(vcombine_s16(x_lo[1], x_hi[1])); -} - -static void fdct16x16_neon(int16x8_t *in0, int16x8_t *in1) { - // Left half. - fdct16_8col(in0); - // Right half. - fdct16_8col(in1); - transpose_s16_16x16(in0, in1); -} - -static void fadst16x16_neon(int16x8_t *in0, int16x8_t *in1) { - fadst16_8col(in0); - fadst16_8col(in1); - transpose_s16_16x16(in0, in1); -} - -void vp9_fht16x16_neon(const int16_t *input, tran_low_t *output, int stride, - int tx_type) { - int16x8_t in0[16], in1[16]; - - switch (tx_type) { - case DCT_DCT: vpx_fdct16x16_neon(input, output, stride); break; - case ADST_DCT: - load_buffer_16x16(input, in0, in1, stride); - fadst16x16_neon(in0, in1); - right_shift_16x16(in0, in1); - fdct16x16_neon(in0, in1); - write_buffer_16x16(output, in0, in1, 16); - break; - case DCT_ADST: - load_buffer_16x16(input, in0, in1, stride); - fdct16x16_neon(in0, in1); - right_shift_16x16(in0, in1); - fadst16x16_neon(in0, in1); - write_buffer_16x16(output, in0, in1, 16); - break; - default: - assert(tx_type == ADST_ADST); - load_buffer_16x16(input, in0, in1, stride); - fadst16x16_neon(in0, in1); - right_shift_16x16(in0, in1); - fadst16x16_neon(in0, in1); - write_buffer_16x16(output, in0, in1, 16); - break; - } -} - -#if CONFIG_VP9_HIGHBITDEPTH - -static INLINE void highbd_load_buffer_4x4(const int16_t *input, - int32x4_t *in /*[4]*/, int stride) { - // { 0, 1, 1, 1 }; - const int32x4_t nonzero_bias_a = vextq_s32(vdupq_n_s32(0), vdupq_n_s32(1), 3); - // { 1, 0, 0, 0 }; - const int32x4_t nonzero_bias_b = vextq_s32(vdupq_n_s32(1), vdupq_n_s32(0), 3); - int32x4_t mask; - - in[0] = vshll_n_s16(vld1_s16(input + 0 * stride), 4); - in[1] = vshll_n_s16(vld1_s16(input + 1 * stride), 4); - in[2] = vshll_n_s16(vld1_s16(input + 2 * stride), 4); - in[3] = vshll_n_s16(vld1_s16(input + 3 * stride), 4); - - // Copy the SSE method, use a mask to avoid an 'if' branch here to increase by - // one non-zero first elements - mask = vreinterpretq_s32_u32(vceqq_s32(in[0], nonzero_bias_a)); - in[0] = vaddq_s32(in[0], mask); - in[0] = vaddq_s32(in[0], nonzero_bias_b); -} - -static INLINE void highbd_write_buffer_4x4(tran_low_t *output, int32x4_t *res) { - const int32x4_t one = vdupq_n_s32(1); - res[0] = vshrq_n_s32(vaddq_s32(res[0], one), 2); - res[1] = vshrq_n_s32(vaddq_s32(res[1], one), 2); - res[2] = vshrq_n_s32(vaddq_s32(res[2], one), 2); - res[3] = vshrq_n_s32(vaddq_s32(res[3], one), 2); - vst1q_s32(output + 0 * 4, res[0]); - vst1q_s32(output + 1 * 4, res[1]); - vst1q_s32(output + 2 * 4, res[2]); - vst1q_s32(output + 3 * 4, res[3]); -} - -static INLINE void highbd_fadst4x4_neon(int32x4_t *in /*[4]*/) { - int32x2_t s_lo[4], s_hi[4]; - int64x2_t u_lo[4], u_hi[4], t_lo[4], t_hi[4]; - - s_lo[0] = vget_low_s32(in[0]); - s_hi[0] = vget_high_s32(in[0]); - s_lo[1] = vget_low_s32(in[1]); - s_hi[1] = vget_high_s32(in[1]); - s_lo[2] = vget_low_s32(in[2]); - s_hi[2] = vget_high_s32(in[2]); - s_lo[3] = vget_low_s32(in[3]); - s_hi[3] = vget_high_s32(in[3]); - - // t0 = s0 * sinpi_1_9 + s1 * sinpi_2_9 + s3 * sinpi_4_9 - t_lo[0] = vmull_n_s32(s_lo[0], sinpi_1_9); - t_lo[0] = vmlal_n_s32(t_lo[0], s_lo[1], sinpi_2_9); - t_lo[0] = vmlal_n_s32(t_lo[0], s_lo[3], sinpi_4_9); - t_hi[0] = vmull_n_s32(s_hi[0], sinpi_1_9); - t_hi[0] = vmlal_n_s32(t_hi[0], s_hi[1], sinpi_2_9); - t_hi[0] = vmlal_n_s32(t_hi[0], s_hi[3], sinpi_4_9); - - // t1 = (s0 + s1) * sinpi_3_9 - s3 * sinpi_3_9 - t_lo[1] = vmull_n_s32(s_lo[0], sinpi_3_9); - t_lo[1] = vmlal_n_s32(t_lo[1], s_lo[1], sinpi_3_9); - t_lo[1] = vmlsl_n_s32(t_lo[1], s_lo[3], sinpi_3_9); - t_hi[1] = vmull_n_s32(s_hi[0], sinpi_3_9); - t_hi[1] = vmlal_n_s32(t_hi[1], s_hi[1], sinpi_3_9); - t_hi[1] = vmlsl_n_s32(t_hi[1], s_hi[3], sinpi_3_9); - - // t2 = s0 * sinpi_4_9 - s1* sinpi_1_9 + s3 * sinpi_2_9 - t_lo[2] = vmull_n_s32(s_lo[0], sinpi_4_9); - t_lo[2] = vmlsl_n_s32(t_lo[2], s_lo[1], sinpi_1_9); - t_lo[2] = vmlal_n_s32(t_lo[2], s_lo[3], sinpi_2_9); - t_hi[2] = vmull_n_s32(s_hi[0], sinpi_4_9); - t_hi[2] = vmlsl_n_s32(t_hi[2], s_hi[1], sinpi_1_9); - t_hi[2] = vmlal_n_s32(t_hi[2], s_hi[3], sinpi_2_9); - - // t3 = s2 * sinpi_3_9 - t_lo[3] = vmull_n_s32(s_lo[2], sinpi_3_9); - t_hi[3] = vmull_n_s32(s_hi[2], sinpi_3_9); - - /* - * u0 = t0 + t3 - * u1 = t1 - * u2 = t2 - t3 - * u3 = t2 - t0 + t3 - */ - u_lo[0] = vaddq_s64(t_lo[0], t_lo[3]); - u_hi[0] = vaddq_s64(t_hi[0], t_hi[3]); - u_lo[1] = t_lo[1]; - u_hi[1] = t_hi[1]; - u_lo[2] = vsubq_s64(t_lo[2], t_lo[3]); - u_hi[2] = vsubq_s64(t_hi[2], t_hi[3]); - u_lo[3] = vaddq_s64(vsubq_s64(t_lo[2], t_lo[0]), t_lo[3]); - u_hi[3] = vaddq_s64(vsubq_s64(t_hi[2], t_hi[0]), t_hi[3]); - - // fdct_round_shift - in[0] = vcombine_s32(vrshrn_n_s64(u_lo[0], DCT_CONST_BITS), - vrshrn_n_s64(u_hi[0], DCT_CONST_BITS)); - in[1] = vcombine_s32(vrshrn_n_s64(u_lo[1], DCT_CONST_BITS), - vrshrn_n_s64(u_hi[1], DCT_CONST_BITS)); - in[2] = vcombine_s32(vrshrn_n_s64(u_lo[2], DCT_CONST_BITS), - vrshrn_n_s64(u_hi[2], DCT_CONST_BITS)); - in[3] = vcombine_s32(vrshrn_n_s64(u_lo[3], DCT_CONST_BITS), - vrshrn_n_s64(u_hi[3], DCT_CONST_BITS)); - - transpose_s32_4x4(&in[0], &in[1], &in[2], &in[3]); -} - -void vp9_highbd_fht4x4_neon(const int16_t *input, tran_low_t *output, - int stride, int tx_type) { - int32x4_t in[4]; - // int i; - - switch (tx_type) { - case DCT_DCT: vpx_highbd_fdct4x4_neon(input, output, stride); break; - case ADST_DCT: - highbd_load_buffer_4x4(input, in, stride); - highbd_fadst4x4_neon(in); - vpx_highbd_fdct4x4_pass1_neon(in); - highbd_write_buffer_4x4(output, in); - break; - case DCT_ADST: - highbd_load_buffer_4x4(input, in, stride); - vpx_highbd_fdct4x4_pass1_neon(in); - highbd_fadst4x4_neon(in); - highbd_write_buffer_4x4(output, in); - break; - default: - assert(tx_type == ADST_ADST); - highbd_load_buffer_4x4(input, in, stride); - highbd_fadst4x4_neon(in); - highbd_fadst4x4_neon(in); - highbd_write_buffer_4x4(output, in); - break; - } -} - -static INLINE void highbd_load_buffer_8x8(const int16_t *input, - int32x4_t *lo /*[8]*/, - int32x4_t *hi /*[8]*/, int stride) { - int16x8_t in[8]; - in[0] = vld1q_s16(input + 0 * stride); - in[1] = vld1q_s16(input + 1 * stride); - in[2] = vld1q_s16(input + 2 * stride); - in[3] = vld1q_s16(input + 3 * stride); - in[4] = vld1q_s16(input + 4 * stride); - in[5] = vld1q_s16(input + 5 * stride); - in[6] = vld1q_s16(input + 6 * stride); - in[7] = vld1q_s16(input + 7 * stride); - lo[0] = vshll_n_s16(vget_low_s16(in[0]), 2); - hi[0] = vshll_n_s16(vget_high_s16(in[0]), 2); - lo[1] = vshll_n_s16(vget_low_s16(in[1]), 2); - hi[1] = vshll_n_s16(vget_high_s16(in[1]), 2); - lo[2] = vshll_n_s16(vget_low_s16(in[2]), 2); - hi[2] = vshll_n_s16(vget_high_s16(in[2]), 2); - lo[3] = vshll_n_s16(vget_low_s16(in[3]), 2); - hi[3] = vshll_n_s16(vget_high_s16(in[3]), 2); - lo[4] = vshll_n_s16(vget_low_s16(in[4]), 2); - hi[4] = vshll_n_s16(vget_high_s16(in[4]), 2); - lo[5] = vshll_n_s16(vget_low_s16(in[5]), 2); - hi[5] = vshll_n_s16(vget_high_s16(in[5]), 2); - lo[6] = vshll_n_s16(vget_low_s16(in[6]), 2); - hi[6] = vshll_n_s16(vget_high_s16(in[6]), 2); - lo[7] = vshll_n_s16(vget_low_s16(in[7]), 2); - hi[7] = vshll_n_s16(vget_high_s16(in[7]), 2); -} - -/* right shift and rounding - * first get the sign bit (bit 15). - * If bit == 1, it's the simple case of shifting right by one bit. - * If bit == 2, it essentially computes the expression: - * - * out[j * 16 + i] = (temp_out[j] + 1 + (temp_out[j] < 0)) >> 2; - * - * for each row. - */ -static INLINE void highbd_right_shift_8x8(int32x4_t *lo, int32x4_t *hi, - const int bit) { - int32x4_t sign_lo[8], sign_hi[8]; - sign_lo[0] = vshrq_n_s32(lo[0], 31); - sign_hi[0] = vshrq_n_s32(hi[0], 31); - sign_lo[1] = vshrq_n_s32(lo[1], 31); - sign_hi[1] = vshrq_n_s32(hi[1], 31); - sign_lo[2] = vshrq_n_s32(lo[2], 31); - sign_hi[2] = vshrq_n_s32(hi[2], 31); - sign_lo[3] = vshrq_n_s32(lo[3], 31); - sign_hi[3] = vshrq_n_s32(hi[3], 31); - sign_lo[4] = vshrq_n_s32(lo[4], 31); - sign_hi[4] = vshrq_n_s32(hi[4], 31); - sign_lo[5] = vshrq_n_s32(lo[5], 31); - sign_hi[5] = vshrq_n_s32(hi[5], 31); - sign_lo[6] = vshrq_n_s32(lo[6], 31); - sign_hi[6] = vshrq_n_s32(hi[6], 31); - sign_lo[7] = vshrq_n_s32(lo[7], 31); - sign_hi[7] = vshrq_n_s32(hi[7], 31); - - if (bit == 2) { - const int32x4_t const_rounding = vdupq_n_s32(1); - lo[0] = vaddq_s32(lo[0], const_rounding); - hi[0] = vaddq_s32(hi[0], const_rounding); - lo[1] = vaddq_s32(lo[1], const_rounding); - hi[1] = vaddq_s32(hi[1], const_rounding); - lo[2] = vaddq_s32(lo[2], const_rounding); - hi[2] = vaddq_s32(hi[2], const_rounding); - lo[3] = vaddq_s32(lo[3], const_rounding); - hi[3] = vaddq_s32(hi[3], const_rounding); - lo[4] = vaddq_s32(lo[4], const_rounding); - hi[4] = vaddq_s32(hi[4], const_rounding); - lo[5] = vaddq_s32(lo[5], const_rounding); - hi[5] = vaddq_s32(hi[5], const_rounding); - lo[6] = vaddq_s32(lo[6], const_rounding); - hi[6] = vaddq_s32(hi[6], const_rounding); - lo[7] = vaddq_s32(lo[7], const_rounding); - hi[7] = vaddq_s32(hi[7], const_rounding); - } - - lo[0] = vsubq_s32(lo[0], sign_lo[0]); - hi[0] = vsubq_s32(hi[0], sign_hi[0]); - lo[1] = vsubq_s32(lo[1], sign_lo[1]); - hi[1] = vsubq_s32(hi[1], sign_hi[1]); - lo[2] = vsubq_s32(lo[2], sign_lo[2]); - hi[2] = vsubq_s32(hi[2], sign_hi[2]); - lo[3] = vsubq_s32(lo[3], sign_lo[3]); - hi[3] = vsubq_s32(hi[3], sign_hi[3]); - lo[4] = vsubq_s32(lo[4], sign_lo[4]); - hi[4] = vsubq_s32(hi[4], sign_hi[4]); - lo[5] = vsubq_s32(lo[5], sign_lo[5]); - hi[5] = vsubq_s32(hi[5], sign_hi[5]); - lo[6] = vsubq_s32(lo[6], sign_lo[6]); - hi[6] = vsubq_s32(hi[6], sign_hi[6]); - lo[7] = vsubq_s32(lo[7], sign_lo[7]); - hi[7] = vsubq_s32(hi[7], sign_hi[7]); - - if (bit == 1) { - lo[0] = vshrq_n_s32(lo[0], 1); - hi[0] = vshrq_n_s32(hi[0], 1); - lo[1] = vshrq_n_s32(lo[1], 1); - hi[1] = vshrq_n_s32(hi[1], 1); - lo[2] = vshrq_n_s32(lo[2], 1); - hi[2] = vshrq_n_s32(hi[2], 1); - lo[3] = vshrq_n_s32(lo[3], 1); - hi[3] = vshrq_n_s32(hi[3], 1); - lo[4] = vshrq_n_s32(lo[4], 1); - hi[4] = vshrq_n_s32(hi[4], 1); - lo[5] = vshrq_n_s32(lo[5], 1); - hi[5] = vshrq_n_s32(hi[5], 1); - lo[6] = vshrq_n_s32(lo[6], 1); - hi[6] = vshrq_n_s32(hi[6], 1); - lo[7] = vshrq_n_s32(lo[7], 1); - hi[7] = vshrq_n_s32(hi[7], 1); - } else { - lo[0] = vshrq_n_s32(lo[0], 2); - hi[0] = vshrq_n_s32(hi[0], 2); - lo[1] = vshrq_n_s32(lo[1], 2); - hi[1] = vshrq_n_s32(hi[1], 2); - lo[2] = vshrq_n_s32(lo[2], 2); - hi[2] = vshrq_n_s32(hi[2], 2); - lo[3] = vshrq_n_s32(lo[3], 2); - hi[3] = vshrq_n_s32(hi[3], 2); - lo[4] = vshrq_n_s32(lo[4], 2); - hi[4] = vshrq_n_s32(hi[4], 2); - lo[5] = vshrq_n_s32(lo[5], 2); - hi[5] = vshrq_n_s32(hi[5], 2); - lo[6] = vshrq_n_s32(lo[6], 2); - hi[6] = vshrq_n_s32(hi[6], 2); - lo[7] = vshrq_n_s32(lo[7], 2); - hi[7] = vshrq_n_s32(hi[7], 2); - } -} - -static INLINE void highbd_write_buffer_8x8(tran_low_t *output, int32x4_t *lo, - int32x4_t *hi, int stride) { - vst1q_s32(output + 0 * stride, lo[0]); - vst1q_s32(output + 0 * stride + 4, hi[0]); - vst1q_s32(output + 1 * stride, lo[1]); - vst1q_s32(output + 1 * stride + 4, hi[1]); - vst1q_s32(output + 2 * stride, lo[2]); - vst1q_s32(output + 2 * stride + 4, hi[2]); - vst1q_s32(output + 3 * stride, lo[3]); - vst1q_s32(output + 3 * stride + 4, hi[3]); - vst1q_s32(output + 4 * stride, lo[4]); - vst1q_s32(output + 4 * stride + 4, hi[4]); - vst1q_s32(output + 5 * stride, lo[5]); - vst1q_s32(output + 5 * stride + 4, hi[5]); - vst1q_s32(output + 6 * stride, lo[6]); - vst1q_s32(output + 6 * stride + 4, hi[6]); - vst1q_s32(output + 7 * stride, lo[7]); - vst1q_s32(output + 7 * stride + 4, hi[7]); -} - -static INLINE void highbd_fadst8x8_neon(int32x4_t *lo /*[8]*/, - int32x4_t *hi /*[8]*/) { - int32x4_t s_lo[8], s_hi[8]; - int32x4_t t_lo[8], t_hi[8]; - int32x4_t x_lo[8], x_hi[8]; - int64x2_t s64_lo[16], s64_hi[16]; - - x_lo[0] = lo[7]; - x_hi[0] = hi[7]; - x_lo[1] = lo[0]; - x_hi[1] = hi[0]; - x_lo[2] = lo[5]; - x_hi[2] = hi[5]; - x_lo[3] = lo[2]; - x_hi[3] = hi[2]; - x_lo[4] = lo[3]; - x_hi[4] = hi[3]; - x_lo[5] = lo[4]; - x_hi[5] = hi[4]; - x_lo[6] = lo[1]; - x_hi[6] = hi[1]; - x_lo[7] = lo[6]; - x_hi[7] = hi[6]; - - // stage 1 - // s0 = cospi_2_64 * x0 + cospi_30_64 * x1; - // s1 = cospi_30_64 * x0 - cospi_2_64 * x1; - butterfly_two_coeff_s32_s64_noround( - x_lo[0], x_hi[0], x_lo[1], x_hi[1], cospi_2_64, cospi_30_64, - &s64_lo[2 * 0], &s64_hi[2 * 0], &s64_lo[2 * 1], &s64_hi[2 * 1]); - // s2 = cospi_10_64 * x2 + cospi_22_64 * x3; - // s3 = cospi_22_64 * x2 - cospi_10_64 * x3; - butterfly_two_coeff_s32_s64_noround( - x_lo[2], x_hi[2], x_lo[3], x_hi[3], cospi_10_64, cospi_22_64, - &s64_lo[2 * 2], &s64_hi[2 * 2], &s64_lo[2 * 3], &s64_hi[2 * 3]); - - // s4 = cospi_18_64 * x4 + cospi_14_64 * x5; - // s5 = cospi_14_64 * x4 - cospi_18_64 * x5; - butterfly_two_coeff_s32_s64_noround( - x_lo[4], x_hi[4], x_lo[5], x_hi[5], cospi_18_64, cospi_14_64, - &s64_lo[2 * 4], &s64_hi[2 * 4], &s64_lo[2 * 5], &s64_hi[2 * 5]); - - // s6 = cospi_26_64 * x6 + cospi_6_64 * x7; - // s7 = cospi_6_64 * x6 - cospi_26_64 * x7; - butterfly_two_coeff_s32_s64_noround( - x_lo[6], x_hi[6], x_lo[7], x_hi[7], cospi_26_64, cospi_6_64, - &s64_lo[2 * 6], &s64_hi[2 * 6], &s64_lo[2 * 7], &s64_hi[2 * 7]); - - // fdct_round_shift, indices are doubled - t_lo[0] = add_s64_round_narrow(&s64_lo[2 * 0], &s64_lo[2 * 4]); - t_hi[0] = add_s64_round_narrow(&s64_hi[2 * 0], &s64_hi[2 * 4]); - t_lo[1] = add_s64_round_narrow(&s64_lo[2 * 1], &s64_lo[2 * 5]); - t_hi[1] = add_s64_round_narrow(&s64_hi[2 * 1], &s64_hi[2 * 5]); - t_lo[2] = add_s64_round_narrow(&s64_lo[2 * 2], &s64_lo[2 * 6]); - t_hi[2] = add_s64_round_narrow(&s64_hi[2 * 2], &s64_hi[2 * 6]); - t_lo[3] = add_s64_round_narrow(&s64_lo[2 * 3], &s64_lo[2 * 7]); - t_hi[3] = add_s64_round_narrow(&s64_hi[2 * 3], &s64_hi[2 * 7]); - t_lo[4] = sub_s64_round_narrow(&s64_lo[2 * 0], &s64_lo[2 * 4]); - t_hi[4] = sub_s64_round_narrow(&s64_hi[2 * 0], &s64_hi[2 * 4]); - t_lo[5] = sub_s64_round_narrow(&s64_lo[2 * 1], &s64_lo[2 * 5]); - t_hi[5] = sub_s64_round_narrow(&s64_hi[2 * 1], &s64_hi[2 * 5]); - t_lo[6] = sub_s64_round_narrow(&s64_lo[2 * 2], &s64_lo[2 * 6]); - t_hi[6] = sub_s64_round_narrow(&s64_hi[2 * 2], &s64_hi[2 * 6]); - t_lo[7] = sub_s64_round_narrow(&s64_lo[2 * 3], &s64_lo[2 * 7]); - t_hi[7] = sub_s64_round_narrow(&s64_hi[2 * 3], &s64_hi[2 * 7]); - - // stage 2 - s_lo[0] = t_lo[0]; - s_hi[0] = t_hi[0]; - s_lo[1] = t_lo[1]; - s_hi[1] = t_hi[1]; - s_lo[2] = t_lo[2]; - s_hi[2] = t_hi[2]; - s_lo[3] = t_lo[3]; - s_hi[3] = t_hi[3]; - // s4 = cospi_8_64 * x4 + cospi_24_64 * x5; - // s5 = cospi_24_64 * x4 - cospi_8_64 * x5; - butterfly_two_coeff_s32_s64_noround( - t_lo[4], t_hi[4], t_lo[5], t_hi[5], cospi_8_64, cospi_24_64, - &s64_lo[2 * 4], &s64_hi[2 * 4], &s64_lo[2 * 5], &s64_hi[2 * 5]); - - // s6 = -cospi_24_64 * x6 + cospi_8_64 * x7; - // s7 = cospi_8_64 * x6 + cospi_24_64 * x7; - butterfly_two_coeff_s32_s64_noround( - t_lo[6], t_hi[6], t_lo[7], t_hi[7], -cospi_24_64, cospi_8_64, - &s64_lo[2 * 6], &s64_hi[2 * 6], &s64_lo[2 * 7], &s64_hi[2 * 7]); - - // fdct_round_shift - // s0 + s2 - t_lo[0] = add_s32_s64_narrow(s_lo[0], s_lo[2]); - t_hi[0] = add_s32_s64_narrow(s_hi[0], s_hi[2]); - // s0 - s2 - t_lo[2] = sub_s32_s64_narrow(s_lo[0], s_lo[2]); - t_hi[2] = sub_s32_s64_narrow(s_hi[0], s_hi[2]); - - // s1 + s3 - t_lo[1] = add_s32_s64_narrow(s_lo[1], s_lo[3]); - t_hi[1] = add_s32_s64_narrow(s_hi[1], s_hi[3]); - // s1 - s3 - t_lo[3] = sub_s32_s64_narrow(s_lo[1], s_lo[3]); - t_hi[3] = sub_s32_s64_narrow(s_hi[1], s_hi[3]); - - // s4 + s6 - t_lo[4] = add_s64_round_narrow(&s64_lo[2 * 4], &s64_lo[2 * 6]); - t_hi[4] = add_s64_round_narrow(&s64_hi[2 * 4], &s64_hi[2 * 6]); - // s4 - s6 - t_lo[6] = sub_s64_round_narrow(&s64_lo[2 * 4], &s64_lo[2 * 6]); - t_hi[6] = sub_s64_round_narrow(&s64_hi[2 * 4], &s64_hi[2 * 6]); - - // s5 + s7 - t_lo[5] = add_s64_round_narrow(&s64_lo[2 * 5], &s64_lo[2 * 7]); - t_hi[5] = add_s64_round_narrow(&s64_hi[2 * 5], &s64_hi[2 * 7]); - // s5 - s7 - t_lo[7] = sub_s64_round_narrow(&s64_lo[2 * 5], &s64_lo[2 * 7]); - t_hi[7] = sub_s64_round_narrow(&s64_hi[2 * 5], &s64_hi[2 * 7]); - - // stage 3 - // s2 = cospi_16_64 * (x2 + x3) - // s3 = cospi_16_64 * (x2 - x3) - butterfly_one_coeff_s32_fast(t_lo[2], t_hi[2], t_lo[3], t_hi[3], cospi_16_64, - &s_lo[2], &s_hi[2], &s_lo[3], &s_hi[3]); - - // s6 = cospi_16_64 * (x6 + x7) - // s7 = cospi_16_64 * (x6 - x7) - butterfly_one_coeff_s32_fast(t_lo[6], t_hi[6], t_lo[7], t_hi[7], cospi_16_64, - &s_lo[6], &s_hi[6], &s_lo[7], &s_hi[7]); - - // x0, x2, x4, x6 pass through - lo[0] = t_lo[0]; - hi[0] = t_hi[0]; - lo[2] = s_lo[6]; - hi[2] = s_hi[6]; - lo[4] = s_lo[3]; - hi[4] = s_hi[3]; - lo[6] = t_lo[5]; - hi[6] = t_hi[5]; - - lo[1] = vnegq_s32(t_lo[4]); - hi[1] = vnegq_s32(t_hi[4]); - lo[3] = vnegq_s32(s_lo[2]); - hi[3] = vnegq_s32(s_hi[2]); - lo[5] = vnegq_s32(s_lo[7]); - hi[5] = vnegq_s32(s_hi[7]); - lo[7] = vnegq_s32(t_lo[1]); - hi[7] = vnegq_s32(t_hi[1]); - - transpose_s32_8x8_2(lo, hi, lo, hi); -} - -void vp9_highbd_fht8x8_neon(const int16_t *input, tran_low_t *output, - int stride, int tx_type) { - int32x4_t lo[8], hi[8]; - - switch (tx_type) { - case DCT_DCT: vpx_highbd_fdct8x8_neon(input, output, stride); break; - case ADST_DCT: - highbd_load_buffer_8x8(input, lo, hi, stride); - highbd_fadst8x8_neon(lo, hi); - // pass1 variant is not precise enough - vpx_highbd_fdct8x8_pass2_neon(lo, hi); - highbd_right_shift_8x8(lo, hi, 1); - highbd_write_buffer_8x8(output, lo, hi, 8); - break; - case DCT_ADST: - highbd_load_buffer_8x8(input, lo, hi, stride); - // pass1 variant is not precise enough - vpx_highbd_fdct8x8_pass2_neon(lo, hi); - highbd_fadst8x8_neon(lo, hi); - highbd_right_shift_8x8(lo, hi, 1); - highbd_write_buffer_8x8(output, lo, hi, 8); - break; - default: - assert(tx_type == ADST_ADST); - highbd_load_buffer_8x8(input, lo, hi, stride); - highbd_fadst8x8_neon(lo, hi); - highbd_fadst8x8_neon(lo, hi); - highbd_right_shift_8x8(lo, hi, 1); - highbd_write_buffer_8x8(output, lo, hi, 8); - break; - } -} - -static INLINE void highbd_load_buffer_16x16( - const int16_t *input, int32x4_t *left1 /*[16]*/, int32x4_t *right1 /*[16]*/, - int32x4_t *left2 /*[16]*/, int32x4_t *right2 /*[16]*/, int stride) { - // load first 8 columns - highbd_load_buffer_8x8(input, left1, right1, stride); - highbd_load_buffer_8x8(input + 8 * stride, left1 + 8, right1 + 8, stride); - - input += 8; - // load second 8 columns - highbd_load_buffer_8x8(input, left2, right2, stride); - highbd_load_buffer_8x8(input + 8 * stride, left2 + 8, right2 + 8, stride); -} - -static INLINE void highbd_write_buffer_16x16( - tran_low_t *output, int32x4_t *left1 /*[16]*/, int32x4_t *right1 /*[16]*/, - int32x4_t *left2 /*[16]*/, int32x4_t *right2 /*[16]*/, int stride) { - // write first 8 columns - highbd_write_buffer_8x8(output, left1, right1, stride); - highbd_write_buffer_8x8(output + 8 * stride, left1 + 8, right1 + 8, stride); - - // write second 8 columns - output += 8; - highbd_write_buffer_8x8(output, left2, right2, stride); - highbd_write_buffer_8x8(output + 8 * stride, left2 + 8, right2 + 8, stride); -} - -static INLINE void highbd_right_shift_16x16(int32x4_t *left1 /*[16]*/, - int32x4_t *right1 /*[16]*/, - int32x4_t *left2 /*[16]*/, - int32x4_t *right2 /*[16]*/, - const int bit) { - // perform rounding operations - highbd_right_shift_8x8(left1, right1, bit); - highbd_right_shift_8x8(left1 + 8, right1 + 8, bit); - highbd_right_shift_8x8(left2, right2, bit); - highbd_right_shift_8x8(left2 + 8, right2 + 8, bit); -} - -static void highbd_fdct16_8col(int32x4_t *left, int32x4_t *right) { - // perform 16x16 1-D DCT for 8 columns - int32x4_t s1_lo[8], s1_hi[8], s2_lo[8], s2_hi[8], s3_lo[8], s3_hi[8]; - int32x4_t left8[8], right8[8]; - - // stage 1 - left8[0] = vaddq_s32(left[0], left[15]); - right8[0] = vaddq_s32(right[0], right[15]); - left8[1] = vaddq_s32(left[1], left[14]); - right8[1] = vaddq_s32(right[1], right[14]); - left8[2] = vaddq_s32(left[2], left[13]); - right8[2] = vaddq_s32(right[2], right[13]); - left8[3] = vaddq_s32(left[3], left[12]); - right8[3] = vaddq_s32(right[3], right[12]); - left8[4] = vaddq_s32(left[4], left[11]); - right8[4] = vaddq_s32(right[4], right[11]); - left8[5] = vaddq_s32(left[5], left[10]); - right8[5] = vaddq_s32(right[5], right[10]); - left8[6] = vaddq_s32(left[6], left[9]); - right8[6] = vaddq_s32(right[6], right[9]); - left8[7] = vaddq_s32(left[7], left[8]); - right8[7] = vaddq_s32(right[7], right[8]); - - // step 1 - s1_lo[0] = vsubq_s32(left[7], left[8]); - s1_hi[0] = vsubq_s32(right[7], right[8]); - s1_lo[1] = vsubq_s32(left[6], left[9]); - s1_hi[1] = vsubq_s32(right[6], right[9]); - s1_lo[2] = vsubq_s32(left[5], left[10]); - s1_hi[2] = vsubq_s32(right[5], right[10]); - s1_lo[3] = vsubq_s32(left[4], left[11]); - s1_hi[3] = vsubq_s32(right[4], right[11]); - s1_lo[4] = vsubq_s32(left[3], left[12]); - s1_hi[4] = vsubq_s32(right[3], right[12]); - s1_lo[5] = vsubq_s32(left[2], left[13]); - s1_hi[5] = vsubq_s32(right[2], right[13]); - s1_lo[6] = vsubq_s32(left[1], left[14]); - s1_hi[6] = vsubq_s32(right[1], right[14]); - s1_lo[7] = vsubq_s32(left[0], left[15]); - s1_hi[7] = vsubq_s32(right[0], right[15]); - - // pass1 variant is not accurate enough - vpx_highbd_fdct8x8_pass2_notranspose_neon(left8, right8); - - // step 2 - // step2[2] = (step1[5] - step1[2]) * cospi_16_64; - // step2[5] = (step1[5] + step1[2]) * cospi_16_64; - butterfly_one_coeff_s32_s64_narrow(s1_lo[5], s1_hi[5], s1_lo[2], s1_hi[2], - cospi_16_64, &s2_lo[5], &s2_hi[5], - &s2_lo[2], &s2_hi[2]); - // step2[3] = (step1[4] - step1[3]) * cospi_16_64; - // step2[4] = (step1[4] + step1[3]) * cospi_16_64; - butterfly_one_coeff_s32_s64_narrow(s1_lo[4], s1_hi[4], s1_lo[3], s1_hi[3], - cospi_16_64, &s2_lo[4], &s2_hi[4], - &s2_lo[3], &s2_hi[3]); - - // step 3 - s3_lo[0] = vaddq_s32(s1_lo[0], s2_lo[3]); - s3_hi[0] = vaddq_s32(s1_hi[0], s2_hi[3]); - s3_lo[1] = vaddq_s32(s1_lo[1], s2_lo[2]); - s3_hi[1] = vaddq_s32(s1_hi[1], s2_hi[2]); - s3_lo[2] = vsubq_s32(s1_lo[1], s2_lo[2]); - s3_hi[2] = vsubq_s32(s1_hi[1], s2_hi[2]); - s3_lo[3] = vsubq_s32(s1_lo[0], s2_lo[3]); - s3_hi[3] = vsubq_s32(s1_hi[0], s2_hi[3]); - s3_lo[4] = vsubq_s32(s1_lo[7], s2_lo[4]); - s3_hi[4] = vsubq_s32(s1_hi[7], s2_hi[4]); - s3_lo[5] = vsubq_s32(s1_lo[6], s2_lo[5]); - s3_hi[5] = vsubq_s32(s1_hi[6], s2_hi[5]); - s3_lo[6] = vaddq_s32(s1_lo[6], s2_lo[5]); - s3_hi[6] = vaddq_s32(s1_hi[6], s2_hi[5]); - s3_lo[7] = vaddq_s32(s1_lo[7], s2_lo[4]); - s3_hi[7] = vaddq_s32(s1_hi[7], s2_hi[4]); - - // step 4 - // s2[1] = cospi_24_64 * s3[6] - cospi_8_64 * s3[1] - // s2[6] = cospi_8_64 * s3[6] + cospi_24_64 * s3[1] - butterfly_two_coeff_s32_s64_narrow(s3_lo[6], s3_hi[6], s3_lo[1], s3_hi[1], - cospi_8_64, cospi_24_64, &s2_lo[6], - &s2_hi[6], &s2_lo[1], &s2_hi[1]); - - // s2[5] = cospi_8_64 * s3[2] - cospi_24_64 * s3[5] - // s2[2] = cospi_24_64 * s3[2] + cospi_8_64 * s3[5] - butterfly_two_coeff_s32_s64_narrow(s3_lo[2], s3_hi[2], s3_lo[5], s3_hi[5], - cospi_24_64, cospi_8_64, &s2_lo[2], - &s2_hi[2], &s2_lo[5], &s2_hi[5]); - - // step 5 - s1_lo[0] = vaddq_s32(s3_lo[0], s2_lo[1]); - s1_hi[0] = vaddq_s32(s3_hi[0], s2_hi[1]); - s1_lo[1] = vsubq_s32(s3_lo[0], s2_lo[1]); - s1_hi[1] = vsubq_s32(s3_hi[0], s2_hi[1]); - s1_lo[2] = vaddq_s32(s3_lo[3], s2_lo[2]); - s1_hi[2] = vaddq_s32(s3_hi[3], s2_hi[2]); - s1_lo[3] = vsubq_s32(s3_lo[3], s2_lo[2]); - s1_hi[3] = vsubq_s32(s3_hi[3], s2_hi[2]); - s1_lo[4] = vsubq_s32(s3_lo[4], s2_lo[5]); - s1_hi[4] = vsubq_s32(s3_hi[4], s2_hi[5]); - s1_lo[5] = vaddq_s32(s3_lo[4], s2_lo[5]); - s1_hi[5] = vaddq_s32(s3_hi[4], s2_hi[5]); - s1_lo[6] = vsubq_s32(s3_lo[7], s2_lo[6]); - s1_hi[6] = vsubq_s32(s3_hi[7], s2_hi[6]); - s1_lo[7] = vaddq_s32(s3_lo[7], s2_lo[6]); - s1_hi[7] = vaddq_s32(s3_hi[7], s2_hi[6]); - - // step 6 - // out[1] = step1[7] * cospi_2_64 + step1[0] * cospi_30_64 - // out[15] = step1[7] * cospi_30_64 - step1[0] * cospi_2_64 - butterfly_two_coeff_s32_s64_narrow(s1_lo[7], s1_hi[7], s1_lo[0], s1_hi[0], - cospi_2_64, cospi_30_64, &left[1], - &right[1], &left[15], &right[15]); - - // out[9] = step1[6] * cospi_18_64 + step1[1] * cospi_14_64 - // out[7] = step1[6] * cospi_14_64 - step1[1] * cospi_18_64 - butterfly_two_coeff_s32_s64_narrow(s1_lo[6], s1_hi[6], s1_lo[1], s1_hi[1], - cospi_18_64, cospi_14_64, &left[9], - &right[9], &left[7], &right[7]); - - // out[5] = step1[5] * cospi_10_64 + step1[2] * cospi_22_64 - // out[11] = step1[5] * cospi_22_64 - step1[2] * cospi_10_64 - butterfly_two_coeff_s32_s64_narrow(s1_lo[5], s1_hi[5], s1_lo[2], s1_hi[2], - cospi_10_64, cospi_22_64, &left[5], - &right[5], &left[11], &right[11]); - - // out[13] = step1[4] * cospi_26_64 + step1[3] * cospi_6_64 - // out[3] = step1[4] * cospi_6_64 - step1[3] * cospi_26_64 - butterfly_two_coeff_s32_s64_narrow(s1_lo[4], s1_hi[4], s1_lo[3], s1_hi[3], - cospi_26_64, cospi_6_64, &left[13], - &right[13], &left[3], &right[3]); - - left[0] = left8[0]; - right[0] = right8[0]; - left[2] = left8[1]; - right[2] = right8[1]; - left[4] = left8[2]; - right[4] = right8[2]; - left[6] = left8[3]; - right[6] = right8[3]; - left[8] = left8[4]; - right[8] = right8[4]; - left[10] = left8[5]; - right[10] = right8[5]; - left[12] = left8[6]; - right[12] = right8[6]; - left[14] = left8[7]; - right[14] = right8[7]; -} - -static void highbd_fadst16_8col(int32x4_t *left, int32x4_t *right) { - // perform 16x16 1-D ADST for 8 columns - int32x4_t x_lo[16], x_hi[16]; - int32x4_t s_lo[16], s_hi[16]; - int32x4_t t_lo[16], t_hi[16]; - int64x2_t s64_lo[32], s64_hi[32]; - - x_lo[0] = left[15]; - x_hi[0] = right[15]; - x_lo[1] = left[0]; - x_hi[1] = right[0]; - x_lo[2] = left[13]; - x_hi[2] = right[13]; - x_lo[3] = left[2]; - x_hi[3] = right[2]; - x_lo[4] = left[11]; - x_hi[4] = right[11]; - x_lo[5] = left[4]; - x_hi[5] = right[4]; - x_lo[6] = left[9]; - x_hi[6] = right[9]; - x_lo[7] = left[6]; - x_hi[7] = right[6]; - x_lo[8] = left[7]; - x_hi[8] = right[7]; - x_lo[9] = left[8]; - x_hi[9] = right[8]; - x_lo[10] = left[5]; - x_hi[10] = right[5]; - x_lo[11] = left[10]; - x_hi[11] = right[10]; - x_lo[12] = left[3]; - x_hi[12] = right[3]; - x_lo[13] = left[12]; - x_hi[13] = right[12]; - x_lo[14] = left[1]; - x_hi[14] = right[1]; - x_lo[15] = left[14]; - x_hi[15] = right[14]; - - // stage 1, indices are doubled - // s0 = cospi_1_64 * x0 + cospi_31_64 * x1; - // s1 = cospi_31_64 * x0 - cospi_1_64 * x1; - butterfly_two_coeff_s32_s64_noround( - x_lo[0], x_hi[0], x_lo[1], x_hi[1], cospi_1_64, cospi_31_64, - &s64_lo[2 * 0], &s64_hi[2 * 0], &s64_lo[2 * 1], &s64_hi[2 * 1]); - // s2 = cospi_5_64 * x2 + cospi_27_64 * x3; - // s3 = cospi_27_64 * x2 - cospi_5_64 * x3; - butterfly_two_coeff_s32_s64_noround( - x_lo[2], x_hi[2], x_lo[3], x_hi[3], cospi_5_64, cospi_27_64, - &s64_lo[2 * 2], &s64_hi[2 * 2], &s64_lo[2 * 3], &s64_hi[2 * 3]); - // s4 = cospi_9_64 * x4 + cospi_23_64 * x5; - // s5 = cospi_23_64 * x4 - cospi_9_64 * x5; - butterfly_two_coeff_s32_s64_noround( - x_lo[4], x_hi[4], x_lo[5], x_hi[5], cospi_9_64, cospi_23_64, - &s64_lo[2 * 4], &s64_hi[2 * 4], &s64_lo[2 * 5], &s64_hi[2 * 5]); - // s6 = cospi_13_64 * x6 + cospi_19_64 * x7; - // s7 = cospi_19_64 * x6 - cospi_13_64 * x7; - butterfly_two_coeff_s32_s64_noround( - x_lo[6], x_hi[6], x_lo[7], x_hi[7], cospi_13_64, cospi_19_64, - &s64_lo[2 * 6], &s64_hi[2 * 6], &s64_lo[2 * 7], &s64_hi[2 * 7]); - // s8 = cospi_17_64 * x8 + cospi_15_64 * x9; - // s9 = cospi_15_64 * x8 - cospi_17_64 * x9; - butterfly_two_coeff_s32_s64_noround( - x_lo[8], x_hi[8], x_lo[9], x_hi[9], cospi_17_64, cospi_15_64, - &s64_lo[2 * 8], &s64_hi[2 * 8], &s64_lo[2 * 9], &s64_hi[2 * 9]); - // s10 = cospi_21_64 * x10 + cospi_11_64 * x11; - // s11 = cospi_11_64 * x10 - cospi_21_64 * x11; - butterfly_two_coeff_s32_s64_noround( - x_lo[10], x_hi[10], x_lo[11], x_hi[11], cospi_21_64, cospi_11_64, - &s64_lo[2 * 10], &s64_hi[2 * 10], &s64_lo[2 * 11], &s64_hi[2 * 11]); - // s12 = cospi_25_64 * x12 + cospi_7_64 * x13; - // s13 = cospi_7_64 * x12 - cospi_25_64 * x13; - butterfly_two_coeff_s32_s64_noround( - x_lo[12], x_hi[12], x_lo[13], x_hi[13], cospi_25_64, cospi_7_64, - &s64_lo[2 * 12], &s64_hi[2 * 12], &s64_lo[2 * 13], &s64_hi[2 * 13]); - // s14 = cospi_29_64 * x14 + cospi_3_64 * x15; - // s15 = cospi_3_64 * x14 - cospi_29_64 * x15; - butterfly_two_coeff_s32_s64_noround( - x_lo[14], x_hi[14], x_lo[15], x_hi[15], cospi_29_64, cospi_3_64, - &s64_lo[2 * 14], &s64_hi[2 * 14], &s64_lo[2 * 15], &s64_hi[2 * 15]); - - // fdct_round_shift, indices are doubled - t_lo[0] = add_s64_round_narrow(&s64_lo[2 * 0], &s64_lo[2 * 8]); - t_hi[0] = add_s64_round_narrow(&s64_hi[2 * 0], &s64_hi[2 * 8]); - t_lo[1] = add_s64_round_narrow(&s64_lo[2 * 1], &s64_lo[2 * 9]); - t_hi[1] = add_s64_round_narrow(&s64_hi[2 * 1], &s64_hi[2 * 9]); - t_lo[2] = add_s64_round_narrow(&s64_lo[2 * 2], &s64_lo[2 * 10]); - t_hi[2] = add_s64_round_narrow(&s64_hi[2 * 2], &s64_hi[2 * 10]); - t_lo[3] = add_s64_round_narrow(&s64_lo[2 * 3], &s64_lo[2 * 11]); - t_hi[3] = add_s64_round_narrow(&s64_hi[2 * 3], &s64_hi[2 * 11]); - t_lo[4] = add_s64_round_narrow(&s64_lo[2 * 4], &s64_lo[2 * 12]); - t_hi[4] = add_s64_round_narrow(&s64_hi[2 * 4], &s64_hi[2 * 12]); - t_lo[5] = add_s64_round_narrow(&s64_lo[2 * 5], &s64_lo[2 * 13]); - t_hi[5] = add_s64_round_narrow(&s64_hi[2 * 5], &s64_hi[2 * 13]); - t_lo[6] = add_s64_round_narrow(&s64_lo[2 * 6], &s64_lo[2 * 14]); - t_hi[6] = add_s64_round_narrow(&s64_hi[2 * 6], &s64_hi[2 * 14]); - t_lo[7] = add_s64_round_narrow(&s64_lo[2 * 7], &s64_lo[2 * 15]); - t_hi[7] = add_s64_round_narrow(&s64_hi[2 * 7], &s64_hi[2 * 15]); - t_lo[8] = sub_s64_round_narrow(&s64_lo[2 * 0], &s64_lo[2 * 8]); - t_hi[8] = sub_s64_round_narrow(&s64_hi[2 * 0], &s64_hi[2 * 8]); - t_lo[9] = sub_s64_round_narrow(&s64_lo[2 * 1], &s64_lo[2 * 9]); - t_hi[9] = sub_s64_round_narrow(&s64_hi[2 * 1], &s64_hi[2 * 9]); - t_lo[10] = sub_s64_round_narrow(&s64_lo[2 * 2], &s64_lo[2 * 10]); - t_hi[10] = sub_s64_round_narrow(&s64_hi[2 * 2], &s64_hi[2 * 10]); - t_lo[11] = sub_s64_round_narrow(&s64_lo[2 * 3], &s64_lo[2 * 11]); - t_hi[11] = sub_s64_round_narrow(&s64_hi[2 * 3], &s64_hi[2 * 11]); - t_lo[12] = sub_s64_round_narrow(&s64_lo[2 * 4], &s64_lo[2 * 12]); - t_hi[12] = sub_s64_round_narrow(&s64_hi[2 * 4], &s64_hi[2 * 12]); - t_lo[13] = sub_s64_round_narrow(&s64_lo[2 * 5], &s64_lo[2 * 13]); - t_hi[13] = sub_s64_round_narrow(&s64_hi[2 * 5], &s64_hi[2 * 13]); - t_lo[14] = sub_s64_round_narrow(&s64_lo[2 * 6], &s64_lo[2 * 14]); - t_hi[14] = sub_s64_round_narrow(&s64_hi[2 * 6], &s64_hi[2 * 14]); - t_lo[15] = sub_s64_round_narrow(&s64_lo[2 * 7], &s64_lo[2 * 15]); - t_hi[15] = sub_s64_round_narrow(&s64_hi[2 * 7], &s64_hi[2 * 15]); - - // stage 2 - s_lo[0] = t_lo[0]; - s_hi[0] = t_hi[0]; - s_lo[1] = t_lo[1]; - s_hi[1] = t_hi[1]; - s_lo[2] = t_lo[2]; - s_hi[2] = t_hi[2]; - s_lo[3] = t_lo[3]; - s_hi[3] = t_hi[3]; - s_lo[4] = t_lo[4]; - s_hi[4] = t_hi[4]; - s_lo[5] = t_lo[5]; - s_hi[5] = t_hi[5]; - s_lo[6] = t_lo[6]; - s_hi[6] = t_hi[6]; - s_lo[7] = t_lo[7]; - s_hi[7] = t_hi[7]; - // s8 = x8 * cospi_4_64 + x9 * cospi_28_64; - // s9 = x8 * cospi_28_64 - x9 * cospi_4_64; - butterfly_two_coeff_s32_s64_noround( - t_lo[8], t_hi[8], t_lo[9], t_hi[9], cospi_4_64, cospi_28_64, - &s64_lo[2 * 8], &s64_hi[2 * 8], &s64_lo[2 * 9], &s64_hi[2 * 9]); - // s10 = x10 * cospi_20_64 + x11 * cospi_12_64; - // s11 = x10 * cospi_12_64 - x11 * cospi_20_64; - butterfly_two_coeff_s32_s64_noround( - t_lo[10], t_hi[10], t_lo[11], t_hi[11], cospi_20_64, cospi_12_64, - &s64_lo[2 * 10], &s64_hi[2 * 10], &s64_lo[2 * 11], &s64_hi[2 * 11]); - // s12 = -x12 * cospi_28_64 + x13 * cospi_4_64; - // s13 = x12 * cospi_4_64 + x13 * cospi_28_64; - butterfly_two_coeff_s32_s64_noround( - t_lo[13], t_hi[13], t_lo[12], t_hi[12], cospi_28_64, cospi_4_64, - &s64_lo[2 * 13], &s64_hi[2 * 13], &s64_lo[2 * 12], &s64_hi[2 * 12]); - // s14 = -x14 * cospi_12_64 + x15 * cospi_20_64; - // s15 = x14 * cospi_20_64 + x15 * cospi_12_64; - butterfly_two_coeff_s32_s64_noround( - t_lo[15], t_hi[15], t_lo[14], t_hi[14], cospi_12_64, cospi_20_64, - &s64_lo[2 * 15], &s64_hi[2 * 15], &s64_lo[2 * 14], &s64_hi[2 * 14]); - - // s0 + s4 - t_lo[0] = add_s32_s64_narrow(s_lo[0], s_lo[4]); - t_hi[0] = add_s32_s64_narrow(s_hi[0], s_hi[4]); - // s1 + s5 - t_lo[1] = add_s32_s64_narrow(s_lo[1], s_lo[5]); - t_hi[1] = add_s32_s64_narrow(s_hi[1], s_hi[5]); - // s2 + s6 - t_lo[2] = add_s32_s64_narrow(s_lo[2], s_lo[6]); - t_hi[2] = add_s32_s64_narrow(s_hi[2], s_hi[6]); - // s3 + s7 - t_lo[3] = add_s32_s64_narrow(s_lo[3], s_lo[7]); - t_hi[3] = add_s32_s64_narrow(s_hi[3], s_hi[7]); - - // s0 - s4 - t_lo[4] = sub_s32_s64_narrow(s_lo[0], s_lo[4]); - t_hi[4] = sub_s32_s64_narrow(s_hi[0], s_hi[4]); - // s1 - s5 - t_lo[5] = sub_s32_s64_narrow(s_lo[1], s_lo[5]); - t_hi[5] = sub_s32_s64_narrow(s_hi[1], s_hi[5]); - // s2 - s6 - t_lo[6] = sub_s32_s64_narrow(s_lo[2], s_lo[6]); - t_hi[6] = sub_s32_s64_narrow(s_hi[2], s_hi[6]); - // s3 - s7 - t_lo[7] = sub_s32_s64_narrow(s_lo[3], s_lo[7]); - t_hi[7] = sub_s32_s64_narrow(s_hi[3], s_hi[7]); - - // fdct_round_shift() - // s8 + s12 - t_lo[8] = add_s64_round_narrow(&s64_lo[2 * 8], &s64_lo[2 * 12]); - t_hi[8] = add_s64_round_narrow(&s64_hi[2 * 8], &s64_hi[2 * 12]); - // s9 + s13 - t_lo[9] = add_s64_round_narrow(&s64_lo[2 * 9], &s64_lo[2 * 13]); - t_hi[9] = add_s64_round_narrow(&s64_hi[2 * 9], &s64_hi[2 * 13]); - // s10 + s14 - t_lo[10] = add_s64_round_narrow(&s64_lo[2 * 10], &s64_lo[2 * 14]); - t_hi[10] = add_s64_round_narrow(&s64_hi[2 * 10], &s64_hi[2 * 14]); - // s11 + s15 - t_lo[11] = add_s64_round_narrow(&s64_lo[2 * 11], &s64_lo[2 * 15]); - t_hi[11] = add_s64_round_narrow(&s64_hi[2 * 11], &s64_hi[2 * 15]); - - // s8 - s12 - t_lo[12] = sub_s64_round_narrow(&s64_lo[2 * 8], &s64_lo[2 * 12]); - t_hi[12] = sub_s64_round_narrow(&s64_hi[2 * 8], &s64_hi[2 * 12]); - // s9 - s13 - t_lo[13] = sub_s64_round_narrow(&s64_lo[2 * 9], &s64_lo[2 * 13]); - t_hi[13] = sub_s64_round_narrow(&s64_hi[2 * 9], &s64_hi[2 * 13]); - // s10 - s14 - t_lo[14] = sub_s64_round_narrow(&s64_lo[2 * 10], &s64_lo[2 * 14]); - t_hi[14] = sub_s64_round_narrow(&s64_hi[2 * 10], &s64_hi[2 * 14]); - // s11 - s15 - t_lo[15] = sub_s64_round_narrow(&s64_lo[2 * 11], &s64_lo[2 * 15]); - t_hi[15] = sub_s64_round_narrow(&s64_hi[2 * 11], &s64_hi[2 * 15]); - - // stage 3 - s_lo[0] = t_lo[0]; - s_hi[0] = t_hi[0]; - s_lo[1] = t_lo[1]; - s_hi[1] = t_hi[1]; - s_lo[2] = t_lo[2]; - s_hi[2] = t_hi[2]; - s_lo[3] = t_lo[3]; - s_hi[3] = t_hi[3]; - // s4 = x4 * cospi_8_64 + x5 * cospi_24_64; - // s5 = x4 * cospi_24_64 - x5 * cospi_8_64; - butterfly_two_coeff_s32_s64_noround( - t_lo[4], t_hi[4], t_lo[5], t_hi[5], cospi_8_64, cospi_24_64, - &s64_lo[2 * 4], &s64_hi[2 * 4], &s64_lo[2 * 5], &s64_hi[2 * 5]); - // s6 = -x6 * cospi_24_64 + x7 * cospi_8_64; - // s7 = x6 * cospi_8_64 + x7 * cospi_24_64; - butterfly_two_coeff_s32_s64_noround( - t_lo[7], t_hi[7], t_lo[6], t_hi[6], cospi_24_64, cospi_8_64, - &s64_lo[2 * 7], &s64_hi[2 * 7], &s64_lo[2 * 6], &s64_hi[2 * 6]); - s_lo[8] = t_lo[8]; - s_hi[8] = t_hi[8]; - s_lo[9] = t_lo[9]; - s_hi[9] = t_hi[9]; - s_lo[10] = t_lo[10]; - s_hi[10] = t_hi[10]; - s_lo[11] = t_lo[11]; - s_hi[11] = t_hi[11]; - // s12 = x12 * cospi_8_64 + x13 * cospi_24_64; - // s13 = x12 * cospi_24_64 - x13 * cospi_8_64; - butterfly_two_coeff_s32_s64_noround( - t_lo[12], t_hi[12], t_lo[13], t_hi[13], cospi_8_64, cospi_24_64, - &s64_lo[2 * 12], &s64_hi[2 * 12], &s64_lo[2 * 13], &s64_hi[2 * 13]); - // s14 = -x14 * cospi_24_64 + x15 * cospi_8_64; - // s15 = x14 * cospi_8_64 + x15 * cospi_24_64; - butterfly_two_coeff_s32_s64_noround( - t_lo[15], t_hi[15], t_lo[14], t_hi[14], cospi_24_64, cospi_8_64, - &s64_lo[2 * 15], &s64_hi[2 * 15], &s64_lo[2 * 14], &s64_hi[2 * 14]); - - // s0 + s2 - t_lo[0] = add_s32_s64_narrow(s_lo[0], s_lo[2]); - t_hi[0] = add_s32_s64_narrow(s_hi[0], s_hi[2]); - // s1 + s3 - t_lo[1] = add_s32_s64_narrow(s_lo[1], s_lo[3]); - t_hi[1] = add_s32_s64_narrow(s_hi[1], s_hi[3]); - // s0 - s2 - t_lo[2] = sub_s32_s64_narrow(s_lo[0], s_lo[2]); - t_hi[2] = sub_s32_s64_narrow(s_hi[0], s_hi[2]); - // s1 - s3 - t_lo[3] = sub_s32_s64_narrow(s_lo[1], s_lo[3]); - t_hi[3] = sub_s32_s64_narrow(s_hi[1], s_hi[3]); - // fdct_round_shift() - // s4 + s6 - t_lo[4] = add_s64_round_narrow(&s64_lo[2 * 4], &s64_lo[2 * 6]); - t_hi[4] = add_s64_round_narrow(&s64_hi[2 * 4], &s64_hi[2 * 6]); - // s5 + s7 - t_lo[5] = add_s64_round_narrow(&s64_lo[2 * 5], &s64_lo[2 * 7]); - t_hi[5] = add_s64_round_narrow(&s64_hi[2 * 5], &s64_hi[2 * 7]); - // s4 - s6 - t_lo[6] = sub_s64_round_narrow(&s64_lo[2 * 4], &s64_lo[2 * 6]); - t_hi[6] = sub_s64_round_narrow(&s64_hi[2 * 4], &s64_hi[2 * 6]); - // s5 - s7 - t_lo[7] = sub_s64_round_narrow(&s64_lo[2 * 5], &s64_lo[2 * 7]); - t_hi[7] = sub_s64_round_narrow(&s64_hi[2 * 5], &s64_hi[2 * 7]); - // s8 + s10 - t_lo[8] = add_s32_s64_narrow(s_lo[8], s_lo[10]); - t_hi[8] = add_s32_s64_narrow(s_hi[8], s_hi[10]); - // s9 + s11 - t_lo[9] = add_s32_s64_narrow(s_lo[9], s_lo[11]); - t_hi[9] = add_s32_s64_narrow(s_hi[9], s_hi[11]); - // s8 - s10 - t_lo[10] = sub_s32_s64_narrow(s_lo[8], s_lo[10]); - t_hi[10] = sub_s32_s64_narrow(s_hi[8], s_hi[10]); - // s9 - s11 - t_lo[11] = sub_s32_s64_narrow(s_lo[9], s_lo[11]); - t_hi[11] = sub_s32_s64_narrow(s_hi[9], s_hi[11]); - // fdct_round_shift() - // s12 + s14 - t_lo[12] = add_s64_round_narrow(&s64_lo[2 * 12], &s64_lo[2 * 14]); - t_hi[12] = add_s64_round_narrow(&s64_hi[2 * 12], &s64_hi[2 * 14]); - // s13 + s15 - t_lo[13] = add_s64_round_narrow(&s64_lo[2 * 13], &s64_lo[2 * 15]); - t_hi[13] = add_s64_round_narrow(&s64_hi[2 * 13], &s64_hi[2 * 15]); - // s12 - s14 - t_lo[14] = sub_s64_round_narrow(&s64_lo[2 * 12], &s64_lo[2 * 14]); - t_hi[14] = sub_s64_round_narrow(&s64_hi[2 * 12], &s64_hi[2 * 14]); - // s13 - s15 - t_lo[15] = sub_s64_round_narrow(&s64_lo[2 * 13], &s64_lo[2 * 15]); - t_hi[15] = sub_s64_round_narrow(&s64_hi[2 * 13], &s64_hi[2 * 15]); - - // stage 4, with fdct_round_shift - // s2 = (-cospi_16_64) * (x2 + x3); - // s3 = cospi_16_64 * (x2 - x3); - butterfly_one_coeff_s32_s64_narrow(t_lo[3], t_hi[3], t_lo[2], t_hi[2], - -cospi_16_64, &x_lo[2], &x_hi[2], &x_lo[3], - &x_hi[3]); - // s6 = cospi_16_64 * (x6 + x7); - // s7 = cospi_16_64 * (-x6 + x7); - butterfly_one_coeff_s32_s64_narrow(t_lo[7], t_hi[7], t_lo[6], t_hi[6], - cospi_16_64, &x_lo[6], &x_hi[6], &x_lo[7], - &x_hi[7]); - // s10 = cospi_16_64 * (x10 + x11); - // s11 = cospi_16_64 * (-x10 + x11); - butterfly_one_coeff_s32_s64_narrow(t_lo[11], t_hi[11], t_lo[10], t_hi[10], - cospi_16_64, &x_lo[10], &x_hi[10], - &x_lo[11], &x_hi[11]); - // s14 = (-cospi_16_64) * (x14 + x15); - // s15 = cospi_16_64 * (x14 - x15); - butterfly_one_coeff_s32_s64_narrow(t_lo[15], t_hi[15], t_lo[14], t_hi[14], - -cospi_16_64, &x_lo[14], &x_hi[14], - &x_lo[15], &x_hi[15]); - - // Just copy x0, x1, x4, x5, x8, x9, x12, x13 - x_lo[0] = t_lo[0]; - x_hi[0] = t_hi[0]; - x_lo[1] = t_lo[1]; - x_hi[1] = t_hi[1]; - x_lo[4] = t_lo[4]; - x_hi[4] = t_hi[4]; - x_lo[5] = t_lo[5]; - x_hi[5] = t_hi[5]; - x_lo[8] = t_lo[8]; - x_hi[8] = t_hi[8]; - x_lo[9] = t_lo[9]; - x_hi[9] = t_hi[9]; - x_lo[12] = t_lo[12]; - x_hi[12] = t_hi[12]; - x_lo[13] = t_lo[13]; - x_hi[13] = t_hi[13]; - - left[0] = x_lo[0]; - right[0] = x_hi[0]; - left[1] = vnegq_s32(x_lo[8]); - right[1] = vnegq_s32(x_hi[8]); - left[2] = x_lo[12]; - right[2] = x_hi[12]; - left[3] = vnegq_s32(x_lo[4]); - right[3] = vnegq_s32(x_hi[4]); - left[4] = x_lo[6]; - right[4] = x_hi[6]; - left[5] = x_lo[14]; - right[5] = x_hi[14]; - left[6] = x_lo[10]; - right[6] = x_hi[10]; - left[7] = x_lo[2]; - right[7] = x_hi[2]; - left[8] = x_lo[3]; - right[8] = x_hi[3]; - left[9] = x_lo[11]; - right[9] = x_hi[11]; - left[10] = x_lo[15]; - right[10] = x_hi[15]; - left[11] = x_lo[7]; - right[11] = x_hi[7]; - left[12] = x_lo[5]; - right[12] = x_hi[5]; - left[13] = vnegq_s32(x_lo[13]); - right[13] = vnegq_s32(x_hi[13]); - left[14] = x_lo[9]; - right[14] = x_hi[9]; - left[15] = vnegq_s32(x_lo[1]); - right[15] = vnegq_s32(x_hi[1]); -} - -static void highbd_fdct16x16_neon(int32x4_t *left1, int32x4_t *right1, - int32x4_t *left2, int32x4_t *right2) { - // Left half. - highbd_fdct16_8col(left1, right1); - // Right half. - highbd_fdct16_8col(left2, right2); - transpose_s32_16x16(left1, right1, left2, right2); -} - -static void highbd_fadst16x16_neon(int32x4_t *left1, int32x4_t *right1, - int32x4_t *left2, int32x4_t *right2) { - // Left half. - highbd_fadst16_8col(left1, right1); - // Right half. - highbd_fadst16_8col(left2, right2); - transpose_s32_16x16(left1, right1, left2, right2); -} - -void vp9_highbd_fht16x16_neon(const int16_t *input, tran_low_t *output, - int stride, int tx_type) { - int32x4_t left1[16], right1[16], left2[16], right2[16]; - - switch (tx_type) { - case DCT_DCT: vpx_highbd_fdct16x16_neon(input, output, stride); break; - case ADST_DCT: - highbd_load_buffer_16x16(input, left1, right1, left2, right2, stride); - highbd_fadst16x16_neon(left1, right1, left2, right2); - highbd_write_buffer_16x16(output, left1, right1, left2, right2, 16); - highbd_right_shift_16x16(left1, right1, left2, right2, 2); - highbd_fdct16x16_neon(left1, right1, left2, right2); - highbd_write_buffer_16x16(output, left1, right1, left2, right2, 16); - break; - case DCT_ADST: - highbd_load_buffer_16x16(input, left1, right1, left2, right2, stride); - highbd_fdct16x16_neon(left1, right1, left2, right2); - highbd_right_shift_16x16(left1, right1, left2, right2, 2); - highbd_fadst16x16_neon(left1, right1, left2, right2); - highbd_write_buffer_16x16(output, left1, right1, left2, right2, 16); - break; - default: - assert(tx_type == ADST_ADST); - highbd_load_buffer_16x16(input, left1, right1, left2, right2, stride); - highbd_fadst16x16_neon(left1, right1, left2, right2); - highbd_right_shift_16x16(left1, right1, left2, right2, 2); - highbd_fadst16x16_neon(left1, right1, left2, right2); - highbd_write_buffer_16x16(output, left1, right1, left2, right2, 16); - break; - } -} - -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_denoiser_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_denoiser_neon.c deleted file mode 100644 index d631cd43..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_denoiser_neon.c +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vp9_rtcd.h" - -#include "vpx/vpx_integer.h" -#include "vp9/common/vp9_reconinter.h" -#include "vp9/encoder/vp9_context_tree.h" -#include "vp9/encoder/vp9_denoiser.h" -#include "vpx_mem/vpx_mem.h" - -// Compute the sum of all pixel differences of this MB. -static INLINE int horizontal_add_s8x16(const int8x16_t v_sum_diff_total) { -#if VPX_ARCH_AARCH64 - return vaddlvq_s8(v_sum_diff_total); -#else - const int16x8_t fe_dc_ba_98_76_54_32_10 = vpaddlq_s8(v_sum_diff_total); - const int32x4_t fedc_ba98_7654_3210 = vpaddlq_s16(fe_dc_ba_98_76_54_32_10); - const int64x2_t fedcba98_76543210 = vpaddlq_s32(fedc_ba98_7654_3210); - const int64x1_t x = vqadd_s64(vget_high_s64(fedcba98_76543210), - vget_low_s64(fedcba98_76543210)); - const int sum_diff = vget_lane_s32(vreinterpret_s32_s64(x), 0); - return sum_diff; -#endif -} - -// Denoise a 16x1 vector. -static INLINE int8x16_t denoiser_16x1_neon( - const uint8_t *sig, const uint8_t *mc_running_avg_y, uint8_t *running_avg_y, - const uint8x16_t v_level1_threshold, const uint8x16_t v_level2_threshold, - const uint8x16_t v_level3_threshold, const uint8x16_t v_level1_adjustment, - const uint8x16_t v_delta_level_1_and_2, - const uint8x16_t v_delta_level_2_and_3, int8x16_t v_sum_diff_total) { - const uint8x16_t v_sig = vld1q_u8(sig); - const uint8x16_t v_mc_running_avg_y = vld1q_u8(mc_running_avg_y); - - /* Calculate absolute difference and sign masks. */ - const uint8x16_t v_abs_diff = vabdq_u8(v_sig, v_mc_running_avg_y); - const uint8x16_t v_diff_pos_mask = vcltq_u8(v_sig, v_mc_running_avg_y); - const uint8x16_t v_diff_neg_mask = vcgtq_u8(v_sig, v_mc_running_avg_y); - - /* Figure out which level that put us in. */ - const uint8x16_t v_level1_mask = vcleq_u8(v_level1_threshold, v_abs_diff); - const uint8x16_t v_level2_mask = vcleq_u8(v_level2_threshold, v_abs_diff); - const uint8x16_t v_level3_mask = vcleq_u8(v_level3_threshold, v_abs_diff); - - /* Calculate absolute adjustments for level 1, 2 and 3. */ - const uint8x16_t v_level2_adjustment = - vandq_u8(v_level2_mask, v_delta_level_1_and_2); - const uint8x16_t v_level3_adjustment = - vandq_u8(v_level3_mask, v_delta_level_2_and_3); - const uint8x16_t v_level1and2_adjustment = - vaddq_u8(v_level1_adjustment, v_level2_adjustment); - const uint8x16_t v_level1and2and3_adjustment = - vaddq_u8(v_level1and2_adjustment, v_level3_adjustment); - - /* Figure adjustment absolute value by selecting between the absolute - * difference if in level0 or the value for level 1, 2 and 3. - */ - const uint8x16_t v_abs_adjustment = - vbslq_u8(v_level1_mask, v_level1and2and3_adjustment, v_abs_diff); - - /* Calculate positive and negative adjustments. Apply them to the signal - * and accumulate them. Adjustments are less than eight and the maximum - * sum of them (7 * 16) can fit in a signed char. - */ - const uint8x16_t v_pos_adjustment = - vandq_u8(v_diff_pos_mask, v_abs_adjustment); - const uint8x16_t v_neg_adjustment = - vandq_u8(v_diff_neg_mask, v_abs_adjustment); - - uint8x16_t v_running_avg_y = vqaddq_u8(v_sig, v_pos_adjustment); - v_running_avg_y = vqsubq_u8(v_running_avg_y, v_neg_adjustment); - - /* Store results. */ - vst1q_u8(running_avg_y, v_running_avg_y); - - /* Sum all the accumulators to have the sum of all pixel differences - * for this macroblock. - */ - { - const int8x16_t v_sum_diff = - vqsubq_s8(vreinterpretq_s8_u8(v_pos_adjustment), - vreinterpretq_s8_u8(v_neg_adjustment)); - v_sum_diff_total = vaddq_s8(v_sum_diff_total, v_sum_diff); - } - return v_sum_diff_total; -} - -static INLINE int8x16_t denoiser_adjust_16x1_neon( - const uint8_t *sig, const uint8_t *mc_running_avg_y, uint8_t *running_avg_y, - const uint8x16_t k_delta, int8x16_t v_sum_diff_total) { - uint8x16_t v_running_avg_y = vld1q_u8(running_avg_y); - const uint8x16_t v_sig = vld1q_u8(sig); - const uint8x16_t v_mc_running_avg_y = vld1q_u8(mc_running_avg_y); - - /* Calculate absolute difference and sign masks. */ - const uint8x16_t v_abs_diff = vabdq_u8(v_sig, v_mc_running_avg_y); - const uint8x16_t v_diff_pos_mask = vcltq_u8(v_sig, v_mc_running_avg_y); - const uint8x16_t v_diff_neg_mask = vcgtq_u8(v_sig, v_mc_running_avg_y); - // Clamp absolute difference to delta to get the adjustment. - const uint8x16_t v_abs_adjustment = vminq_u8(v_abs_diff, (k_delta)); - - const uint8x16_t v_pos_adjustment = - vandq_u8(v_diff_pos_mask, v_abs_adjustment); - const uint8x16_t v_neg_adjustment = - vandq_u8(v_diff_neg_mask, v_abs_adjustment); - - v_running_avg_y = vqsubq_u8(v_running_avg_y, v_pos_adjustment); - v_running_avg_y = vqaddq_u8(v_running_avg_y, v_neg_adjustment); - - /* Store results. */ - vst1q_u8(running_avg_y, v_running_avg_y); - - { - const int8x16_t v_sum_diff = - vqsubq_s8(vreinterpretq_s8_u8(v_neg_adjustment), - vreinterpretq_s8_u8(v_pos_adjustment)); - v_sum_diff_total = vaddq_s8(v_sum_diff_total, v_sum_diff); - } - return v_sum_diff_total; -} - -// Denoise 8x8 and 8x16 blocks. -static int vp9_denoiser_8xN_neon(const uint8_t *sig, int sig_stride, - const uint8_t *mc_running_avg_y, - int mc_avg_y_stride, uint8_t *running_avg_y, - int avg_y_stride, int increase_denoising, - BLOCK_SIZE bs, int motion_magnitude, - int width) { - int sum_diff_thresh, r, sum_diff = 0; - const int shift_inc = - (increase_denoising && motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) - ? 1 - : 0; - uint8_t sig_buffer[8][16], mc_running_buffer[8][16], running_buffer[8][16]; - - const uint8x16_t v_level1_adjustment = vmovq_n_u8( - (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) ? 4 + shift_inc : 3); - const uint8x16_t v_delta_level_1_and_2 = vdupq_n_u8(1); - const uint8x16_t v_delta_level_2_and_3 = vdupq_n_u8(2); - const uint8x16_t v_level1_threshold = vdupq_n_u8(4 + shift_inc); - const uint8x16_t v_level2_threshold = vdupq_n_u8(8); - const uint8x16_t v_level3_threshold = vdupq_n_u8(16); - - const int b_height = (4 << b_height_log2_lookup[bs]) >> 1; - - int8x16_t v_sum_diff_total = vdupq_n_s8(0); - - for (r = 0; r < b_height; ++r) { - memcpy(sig_buffer[r], sig, width); - memcpy(sig_buffer[r] + width, sig + sig_stride, width); - memcpy(mc_running_buffer[r], mc_running_avg_y, width); - memcpy(mc_running_buffer[r] + width, mc_running_avg_y + mc_avg_y_stride, - width); - memcpy(running_buffer[r], running_avg_y, width); - memcpy(running_buffer[r] + width, running_avg_y + avg_y_stride, width); - v_sum_diff_total = denoiser_16x1_neon( - sig_buffer[r], mc_running_buffer[r], running_buffer[r], - v_level1_threshold, v_level2_threshold, v_level3_threshold, - v_level1_adjustment, v_delta_level_1_and_2, v_delta_level_2_and_3, - v_sum_diff_total); - { - const uint8x16_t v_running_buffer = vld1q_u8(running_buffer[r]); - const uint8x8_t v_running_buffer_high = vget_high_u8(v_running_buffer); - const uint8x8_t v_running_buffer_low = vget_low_u8(v_running_buffer); - vst1_u8(running_avg_y, v_running_buffer_low); - vst1_u8(running_avg_y + avg_y_stride, v_running_buffer_high); - } - // Update pointers for next iteration. - sig += (sig_stride << 1); - mc_running_avg_y += (mc_avg_y_stride << 1); - running_avg_y += (avg_y_stride << 1); - } - - { - sum_diff = horizontal_add_s8x16(v_sum_diff_total); - sum_diff_thresh = total_adj_strong_thresh(bs, increase_denoising); - if (abs(sum_diff) > sum_diff_thresh) { - // Before returning to copy the block (i.e., apply no denoising), - // check if we can still apply some (weaker) temporal filtering to - // this block, that would otherwise not be denoised at all. Simplest - // is to apply an additional adjustment to running_avg_y to bring it - // closer to sig. The adjustment is capped by a maximum delta, and - // chosen such that in most cases the resulting sum_diff will be - // within the acceptable range given by sum_diff_thresh. - - // The delta is set by the excess of absolute pixel diff over the - // threshold. - const int delta = - ((abs(sum_diff) - sum_diff_thresh) >> num_pels_log2_lookup[bs]) + 1; - // Only apply the adjustment for max delta up to 3. - if (delta < 4) { - const uint8x16_t k_delta = vmovq_n_u8(delta); - running_avg_y -= avg_y_stride * (b_height << 1); - for (r = 0; r < b_height; ++r) { - v_sum_diff_total = denoiser_adjust_16x1_neon( - sig_buffer[r], mc_running_buffer[r], running_buffer[r], k_delta, - v_sum_diff_total); - { - const uint8x16_t v_running_buffer = vld1q_u8(running_buffer[r]); - const uint8x8_t v_running_buffer_high = - vget_high_u8(v_running_buffer); - const uint8x8_t v_running_buffer_low = - vget_low_u8(v_running_buffer); - vst1_u8(running_avg_y, v_running_buffer_low); - vst1_u8(running_avg_y + avg_y_stride, v_running_buffer_high); - } - // Update pointers for next iteration. - running_avg_y += (avg_y_stride << 1); - } - sum_diff = horizontal_add_s8x16(v_sum_diff_total); - if (abs(sum_diff) > sum_diff_thresh) { - return COPY_BLOCK; - } - } else { - return COPY_BLOCK; - } - } - } - - return FILTER_BLOCK; -} - -// Denoise 16x16, 16x32, 32x16, 32x32, 32x64, 64x32 and 64x64 blocks. -static int vp9_denoiser_NxM_neon(const uint8_t *sig, int sig_stride, - const uint8_t *mc_running_avg_y, - int mc_avg_y_stride, uint8_t *running_avg_y, - int avg_y_stride, int increase_denoising, - BLOCK_SIZE bs, int motion_magnitude) { - const int shift_inc = - (increase_denoising && motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) - ? 1 - : 0; - const uint8x16_t v_level1_adjustment = vmovq_n_u8( - (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) ? 4 + shift_inc : 3); - const uint8x16_t v_delta_level_1_and_2 = vdupq_n_u8(1); - const uint8x16_t v_delta_level_2_and_3 = vdupq_n_u8(2); - const uint8x16_t v_level1_threshold = vmovq_n_u8(4 + shift_inc); - const uint8x16_t v_level2_threshold = vdupq_n_u8(8); - const uint8x16_t v_level3_threshold = vdupq_n_u8(16); - - const int b_width = (4 << b_width_log2_lookup[bs]); - const int b_height = (4 << b_height_log2_lookup[bs]); - const int b_width_shift4 = b_width >> 4; - - int8x16_t v_sum_diff_total[4][4]; - int r, c, sum_diff = 0; - - for (r = 0; r < 4; ++r) { - for (c = 0; c < b_width_shift4; ++c) { - v_sum_diff_total[c][r] = vdupq_n_s8(0); - } - } - - for (r = 0; r < b_height; ++r) { - for (c = 0; c < b_width_shift4; ++c) { - v_sum_diff_total[c][r >> 4] = denoiser_16x1_neon( - sig, mc_running_avg_y, running_avg_y, v_level1_threshold, - v_level2_threshold, v_level3_threshold, v_level1_adjustment, - v_delta_level_1_and_2, v_delta_level_2_and_3, - v_sum_diff_total[c][r >> 4]); - - // Update pointers for next iteration. - sig += 16; - mc_running_avg_y += 16; - running_avg_y += 16; - } - - if ((r & 0xf) == 0xf || (bs == BLOCK_16X8 && r == 7)) { - for (c = 0; c < b_width_shift4; ++c) { - sum_diff += horizontal_add_s8x16(v_sum_diff_total[c][r >> 4]); - } - } - - // Update pointers for next iteration. - sig = sig - b_width + sig_stride; - mc_running_avg_y = mc_running_avg_y - b_width + mc_avg_y_stride; - running_avg_y = running_avg_y - b_width + avg_y_stride; - } - - { - const int sum_diff_thresh = total_adj_strong_thresh(bs, increase_denoising); - if (abs(sum_diff) > sum_diff_thresh) { - const int delta = - ((abs(sum_diff) - sum_diff_thresh) >> num_pels_log2_lookup[bs]) + 1; - // Only apply the adjustment for max delta up to 3. - if (delta < 4) { - const uint8x16_t k_delta = vdupq_n_u8(delta); - sig -= sig_stride * b_height; - mc_running_avg_y -= mc_avg_y_stride * b_height; - running_avg_y -= avg_y_stride * b_height; - sum_diff = 0; - - for (r = 0; r < b_height; ++r) { - for (c = 0; c < b_width_shift4; ++c) { - v_sum_diff_total[c][r >> 4] = - denoiser_adjust_16x1_neon(sig, mc_running_avg_y, running_avg_y, - k_delta, v_sum_diff_total[c][r >> 4]); - - // Update pointers for next iteration. - sig += 16; - mc_running_avg_y += 16; - running_avg_y += 16; - } - if ((r & 0xf) == 0xf || (bs == BLOCK_16X8 && r == 7)) { - for (c = 0; c < b_width_shift4; ++c) { - sum_diff += horizontal_add_s8x16(v_sum_diff_total[c][r >> 4]); - } - } - - sig = sig - b_width + sig_stride; - mc_running_avg_y = mc_running_avg_y - b_width + mc_avg_y_stride; - running_avg_y = running_avg_y - b_width + avg_y_stride; - } - - if (abs(sum_diff) > sum_diff_thresh) { - return COPY_BLOCK; - } - } else { - return COPY_BLOCK; - } - } - } - return FILTER_BLOCK; -} - -int vp9_denoiser_filter_neon(const uint8_t *sig, int sig_stride, - const uint8_t *mc_avg, int mc_avg_stride, - uint8_t *avg, int avg_stride, - int increase_denoising, BLOCK_SIZE bs, - int motion_magnitude) { - // Rank by frequency of the block type to have an early termination. - if (bs == BLOCK_16X16 || bs == BLOCK_32X32 || bs == BLOCK_64X64 || - bs == BLOCK_16X32 || bs == BLOCK_16X8 || bs == BLOCK_32X16 || - bs == BLOCK_32X64 || bs == BLOCK_64X32) { - return vp9_denoiser_NxM_neon(sig, sig_stride, mc_avg, mc_avg_stride, avg, - avg_stride, increase_denoising, bs, - motion_magnitude); - } else if (bs == BLOCK_8X8 || bs == BLOCK_8X16) { - return vp9_denoiser_8xN_neon(sig, sig_stride, mc_avg, mc_avg_stride, avg, - avg_stride, increase_denoising, bs, - motion_magnitude, 8); - } - return COPY_BLOCK; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_diamond_search_sad_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_diamond_search_sad_neon.c deleted file mode 100644 index b82b3f9d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_diamond_search_sad_neon.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "vpx_dsp/vpx_dsp_common.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vpx_ports/mem.h" - -#ifdef __GNUC__ -#define LIKELY(v) __builtin_expect(v, 1) -#define UNLIKELY(v) __builtin_expect(v, 0) -#else -#define LIKELY(v) (v) -#define UNLIKELY(v) (v) -#endif - -static INLINE int_mv pack_int_mv(int16_t row, int16_t col) { - int_mv result; - result.as_mv.row = row; - result.as_mv.col = col; - return result; -} - -/***************************************************************************** - * This function utilizes 3 properties of the cost function lookup tables, * - * constructed in using 'cal_nmvjointsadcost' and 'cal_nmvsadcosts' in * - * vp9_encoder.c. * - * For the joint cost: * - * - mvjointsadcost[1] == mvjointsadcost[2] == mvjointsadcost[3] * - * For the component costs: * - * - For all i: mvsadcost[0][i] == mvsadcost[1][i] * - * (Equal costs for both components) * - * - For all i: mvsadcost[0][i] == mvsadcost[0][-i] * - * (Cost function is even) * - * If these do not hold, then this function cannot be used without * - * modification, in which case you can revert to using the C implementation, * - * which does not rely on these properties. * - *****************************************************************************/ -int vp9_diamond_search_sad_neon(const MACROBLOCK *x, - const search_site_config *cfg, MV *ref_mv, - uint32_t start_mv_sad, MV *best_mv, - int search_param, int sad_per_bit, int *num00, - const vp9_sad_fn_ptr_t *sad_fn_ptr, - const MV *center_mv) { - static const uint32_t data[4] = { 0, 1, 2, 3 }; - const uint32x4_t v_idx_d = vld1q_u32((const uint32_t *)data); - - const int32x4_t zero_s32 = vdupq_n_s32(0); - const int_mv maxmv = pack_int_mv(x->mv_limits.row_max, x->mv_limits.col_max); - const int16x8_t v_max_mv_w = vreinterpretq_s16_s32(vdupq_n_s32(maxmv.as_int)); - const int_mv minmv = pack_int_mv(x->mv_limits.row_min, x->mv_limits.col_min); - const int16x8_t v_min_mv_w = vreinterpretq_s16_s32(vdupq_n_s32(minmv.as_int)); - - const int32x4_t v_spb_d = vdupq_n_s32(sad_per_bit); - - const int32x4_t v_joint_cost_0_d = vdupq_n_s32(x->nmvjointsadcost[0]); - const int32x4_t v_joint_cost_1_d = vdupq_n_s32(x->nmvjointsadcost[1]); - - // search_param determines the length of the initial step and hence the number - // of iterations. - // 0 = initial step (MAX_FIRST_STEP) pel - // 1 = (MAX_FIRST_STEP/2) pel, - // 2 = (MAX_FIRST_STEP/4) pel... - const MV *ss_mv = &cfg->ss_mv[cfg->searches_per_step * search_param]; - const intptr_t *ss_os = &cfg->ss_os[cfg->searches_per_step * search_param]; - const int tot_steps = cfg->total_steps - search_param; - - const int_mv fcenter_mv = - pack_int_mv(center_mv->row >> 3, center_mv->col >> 3); - const int16x8_t vfcmv = vreinterpretq_s16_s32(vdupq_n_s32(fcenter_mv.as_int)); - - const int ref_row = ref_mv->row; - const int ref_col = ref_mv->col; - - int_mv bmv = pack_int_mv(ref_row, ref_col); - int_mv new_bmv = bmv; - int16x8_t v_bmv_w = vreinterpretq_s16_s32(vdupq_n_s32(bmv.as_int)); - - const int what_stride = x->plane[0].src.stride; - const int in_what_stride = x->e_mbd.plane[0].pre[0].stride; - const uint8_t *const what = x->plane[0].src.buf; - const uint8_t *const in_what = - x->e_mbd.plane[0].pre[0].buf + ref_row * in_what_stride + ref_col; - - // Work out the start point for the search - const uint8_t *best_address = in_what; - const uint8_t *new_best_address = best_address; -#if VPX_ARCH_AARCH64 - int64x2_t v_ba_q = vdupq_n_s64((intptr_t)best_address); -#else - int32x4_t v_ba_d = vdupq_n_s32((intptr_t)best_address); -#endif - // Starting position - unsigned int best_sad = start_mv_sad; - int i, j, step; - - // Check the prerequisite cost function properties that are easy to check - // in an assert. See the function-level documentation for details on all - // prerequisites. - assert(x->nmvjointsadcost[1] == x->nmvjointsadcost[2]); - assert(x->nmvjointsadcost[1] == x->nmvjointsadcost[3]); - - *num00 = 0; - - for (i = 0, step = 0; step < tot_steps; step++) { - for (j = 0; j < cfg->searches_per_step; j += 4, i += 4) { - int16x8_t v_diff_mv_w; - int8x16_t v_inside_d; - uint32x4_t v_outside_d; - int32x4_t v_cost_d, v_sad_d; -#if VPX_ARCH_AARCH64 - int64x2_t v_blocka[2]; -#else - int32x4_t v_blocka[1]; - uint32x2_t horiz_max_0, horiz_max_1; -#endif - - uint32_t horiz_max; - // Compute the candidate motion vectors - const int16x8_t v_ss_mv_w = vld1q_s16((const int16_t *)&ss_mv[i]); - const int16x8_t v_these_mv_w = vaddq_s16(v_bmv_w, v_ss_mv_w); - // Clamp them to the search bounds - int16x8_t v_these_mv_clamp_w = v_these_mv_w; - v_these_mv_clamp_w = vminq_s16(v_these_mv_clamp_w, v_max_mv_w); - v_these_mv_clamp_w = vmaxq_s16(v_these_mv_clamp_w, v_min_mv_w); - // The ones that did not change are inside the search area - v_inside_d = vreinterpretq_s8_u32( - vceqq_s32(vreinterpretq_s32_s16(v_these_mv_clamp_w), - vreinterpretq_s32_s16(v_these_mv_w))); - - // If none of them are inside, then move on -#if VPX_ARCH_AARCH64 - horiz_max = vmaxvq_u32(vreinterpretq_u32_s8(v_inside_d)); -#else - horiz_max_0 = vmax_u32(vget_low_u32(vreinterpretq_u32_s8(v_inside_d)), - vget_high_u32(vreinterpretq_u32_s8(v_inside_d))); - horiz_max_1 = vpmax_u32(horiz_max_0, horiz_max_0); - vst1_lane_u32(&horiz_max, horiz_max_1, 0); -#endif - if (LIKELY(horiz_max == 0)) { - continue; - } - - // The inverse mask indicates which of the MVs are outside - v_outside_d = - vreinterpretq_u32_s8(veorq_s8(v_inside_d, vdupq_n_s8((int8_t)0xff))); - // Shift right to keep the sign bit clear, we will use this later - // to set the cost to the maximum value. - v_outside_d = vshrq_n_u32(v_outside_d, 1); - - // Compute the difference MV - v_diff_mv_w = vsubq_s16(v_these_mv_clamp_w, vfcmv); - // We utilise the fact that the cost function is even, and use the - // absolute difference. This allows us to use unsigned indexes later - // and reduces cache pressure somewhat as only a half of the table - // is ever referenced. - v_diff_mv_w = vabsq_s16(v_diff_mv_w); - - // Compute the SIMD pointer offsets. - { -#if VPX_ARCH_AARCH64 // sizeof(intptr_t) == 8 - // Load the offsets - int64x2_t v_bo10_q = vld1q_s64((const int64_t *)&ss_os[i + 0]); - int64x2_t v_bo32_q = vld1q_s64((const int64_t *)&ss_os[i + 2]); - // Set the ones falling outside to zero - v_bo10_q = vandq_s64( - v_bo10_q, - vmovl_s32(vget_low_s32(vreinterpretq_s32_s8(v_inside_d)))); - v_bo32_q = vandq_s64( - v_bo32_q, - vmovl_s32(vget_high_s32(vreinterpretq_s32_s8(v_inside_d)))); - // Compute the candidate addresses - v_blocka[0] = vaddq_s64(v_ba_q, v_bo10_q); - v_blocka[1] = vaddq_s64(v_ba_q, v_bo32_q); -#else // sizeof(intptr_t) == 4 - int32x4_t v_bo_d = vld1q_s32((const int32_t *)&ss_os[i]); - v_bo_d = vandq_s32(v_bo_d, vreinterpretq_s32_s8(v_inside_d)); - v_blocka[0] = vaddq_s32(v_ba_d, v_bo_d); -#endif - } - - sad_fn_ptr->sdx4df(what, what_stride, (const uint8_t **)&v_blocka[0], - in_what_stride, (uint32_t *)&v_sad_d); - - // Look up the component cost of the residual motion vector - { - uint32_t cost[4]; - DECLARE_ALIGNED(16, int16_t, rowcol[8]); - vst1q_s16(rowcol, v_diff_mv_w); - - // Note: This is a use case for gather instruction - cost[0] = x->nmvsadcost[0][rowcol[0]] + x->nmvsadcost[0][rowcol[1]]; - cost[1] = x->nmvsadcost[0][rowcol[2]] + x->nmvsadcost[0][rowcol[3]]; - cost[2] = x->nmvsadcost[0][rowcol[4]] + x->nmvsadcost[0][rowcol[5]]; - cost[3] = x->nmvsadcost[0][rowcol[6]] + x->nmvsadcost[0][rowcol[7]]; - - v_cost_d = vld1q_s32((int32_t *)cost); - } - - // Now add in the joint cost - { - const uint32x4_t v_sel_d = - vceqq_s32(vreinterpretq_s32_s16(v_diff_mv_w), zero_s32); - const int32x4_t v_joint_cost_d = vreinterpretq_s32_u8( - vbslq_u8(vreinterpretq_u8_u32(v_sel_d), - vreinterpretq_u8_s32(v_joint_cost_0_d), - vreinterpretq_u8_s32(v_joint_cost_1_d))); - v_cost_d = vaddq_s32(v_cost_d, v_joint_cost_d); - } - - // Multiply by sad_per_bit - v_cost_d = vmulq_s32(v_cost_d, v_spb_d); - // ROUND_POWER_OF_TWO(v_cost_d, VP9_PROB_COST_SHIFT) - v_cost_d = - vaddq_s32(v_cost_d, vdupq_n_s32(1 << (VP9_PROB_COST_SHIFT - 1))); - v_cost_d = vshrq_n_s32(v_cost_d, VP9_PROB_COST_SHIFT); - // Add the cost to the sad - v_sad_d = vaddq_s32(v_sad_d, v_cost_d); - - // Make the motion vectors outside the search area have max cost - // by or'ing in the comparison mask, this way the minimum search won't - // pick them. - v_sad_d = vorrq_s32(v_sad_d, vreinterpretq_s32_u32(v_outside_d)); - - // Find the minimum value and index horizontally in v_sad_d - { - uint32_t local_best_sad; -#if VPX_ARCH_AARCH64 - local_best_sad = vminvq_u32(vreinterpretq_u32_s32(v_sad_d)); -#else - uint32x2_t horiz_min_0 = - vmin_u32(vget_low_u32(vreinterpretq_u32_s32(v_sad_d)), - vget_high_u32(vreinterpretq_u32_s32(v_sad_d))); - uint32x2_t horiz_min_1 = vpmin_u32(horiz_min_0, horiz_min_0); - vst1_lane_u32(&local_best_sad, horiz_min_1, 0); -#endif - - // Update the global minimum if the local minimum is smaller - if (LIKELY(local_best_sad < best_sad)) { -#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - uint32_t local_best_idx; - const uint32x4_t v_sel_d = - vceqq_s32(v_sad_d, vdupq_n_s32(local_best_sad)); - uint32x4_t v_mask_d = vandq_u32(v_sel_d, v_idx_d); - v_mask_d = vbslq_u32(v_sel_d, v_mask_d, vdupq_n_u32(0xffffffff)); - -#if VPX_ARCH_AARCH64 - local_best_idx = vminvq_u32(v_mask_d); -#else - horiz_min_0 = - vmin_u32(vget_low_u32(v_mask_d), vget_high_u32(v_mask_d)); - horiz_min_1 = vpmin_u32(horiz_min_0, horiz_min_0); - vst1_lane_u32(&local_best_idx, horiz_min_1, 0); -#endif - - new_bmv = ((const int_mv *)&v_these_mv_w)[local_best_idx]; -#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__clang__) -#pragma GCC diagnostic pop -#endif - new_best_address = ((const uint8_t **)v_blocka)[local_best_idx]; - - best_sad = local_best_sad; - } - } - } - - bmv = new_bmv; - best_address = new_best_address; - - v_bmv_w = vreinterpretq_s16_s32(vdupq_n_s32(bmv.as_int)); -#if VPX_ARCH_AARCH64 - v_ba_q = vdupq_n_s64((intptr_t)best_address); -#else - v_ba_d = vdupq_n_s32((intptr_t)best_address); -#endif - - if (UNLIKELY(best_address == in_what)) { - (*num00)++; - } - } - - *best_mv = bmv.as_mv; - return best_sad; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_error_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_error_neon.c deleted file mode 100644 index 0cf0bf25..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_error_neon.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vp9_rtcd.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" - -int64_t vp9_block_error_neon(const tran_low_t *coeff, const tran_low_t *dqcoeff, - intptr_t block_size, int64_t *ssz) { - uint64x2_t err_u64 = vdupq_n_u64(0); - int64x2_t ssz_s64 = vdupq_n_s64(0); - - assert(block_size >= 16); - assert((block_size % 16) == 0); - - do { - uint32x4_t err; - int32x4_t ssz0, ssz1; - - const int16x8_t c0 = load_tran_low_to_s16q(coeff); - const int16x8_t c1 = load_tran_low_to_s16q(coeff + 8); - const int16x8_t d0 = load_tran_low_to_s16q(dqcoeff); - const int16x8_t d1 = load_tran_low_to_s16q(dqcoeff + 8); - - const uint16x8_t diff0 = vreinterpretq_u16_s16(vabdq_s16(c0, d0)); - const uint16x8_t diff1 = vreinterpretq_u16_s16(vabdq_s16(c1, d1)); - - // diff is 15-bits, the squares 30, so we can store 4 in 32-bits before - // accumulating them in 64-bits. - err = vmull_u16(vget_low_u16(diff0), vget_low_u16(diff0)); - err = vmlal_u16(err, vget_high_u16(diff0), vget_high_u16(diff0)); - err = vmlal_u16(err, vget_low_u16(diff1), vget_low_u16(diff1)); - err = vmlal_u16(err, vget_high_u16(diff1), vget_high_u16(diff1)); - err_u64 = vpadalq_u32(err_u64, err); - - // We can't do the same here as we're operating on signed integers, so we - // can store 2 15-bit diff before accumulating into 64-bits. - ssz0 = vmull_s16(vget_low_s16(c0), vget_low_s16(c0)); - ssz0 = vmlal_s16(ssz0, vget_high_s16(c0), vget_high_s16(c0)); - ssz_s64 = vpadalq_s32(ssz_s64, ssz0); - - ssz1 = vmull_s16(vget_low_s16(c1), vget_low_s16(c1)); - ssz1 = vmlal_s16(ssz1, vget_high_s16(c1), vget_high_s16(c1)); - ssz_s64 = vpadalq_s32(ssz_s64, ssz1); - - coeff += 16; - dqcoeff += 16; - block_size -= 16; - } while (block_size != 0); - - *ssz = horizontal_add_int64x2(ssz_s64); - return (int64_t)horizontal_add_uint64x2(err_u64); -} - -int64_t vp9_block_error_fp_neon(const tran_low_t *coeff, - const tran_low_t *dqcoeff, int block_size) { - uint64x2_t err_u64[2] = { vdupq_n_u64(0), vdupq_n_u64(0) }; - - assert(block_size >= 16); - assert((block_size % 16) == 0); - - do { - uint32x4_t err0, err1; - - const int16x8_t c0 = load_tran_low_to_s16q(coeff); - const int16x8_t c1 = load_tran_low_to_s16q(coeff + 8); - const int16x8_t d0 = load_tran_low_to_s16q(dqcoeff); - const int16x8_t d1 = load_tran_low_to_s16q(dqcoeff + 8); - - const uint16x8_t diff0 = vreinterpretq_u16_s16(vabdq_s16(c0, d0)); - const uint16x8_t diff1 = vreinterpretq_u16_s16(vabdq_s16(c1, d1)); - - // diff is 15-bits, the squares 30, so in theory we can store 4 in 32-bits - // before accumulating them in 64-bits. However splitting into 2 mull, mlal - // pairs is beneficial since it allows us to use both Neon - // multiply-accumulate pipes - on CPUs that have them - rather than having - // a single chain of 4 instructions executing serially. - err0 = vmull_u16(vget_low_u16(diff0), vget_low_u16(diff0)); - err0 = vmlal_u16(err0, vget_high_u16(diff0), vget_high_u16(diff0)); - err_u64[0] = vpadalq_u32(err_u64[0], err0); - - err1 = vmull_u16(vget_low_u16(diff1), vget_low_u16(diff1)); - err1 = vmlal_u16(err1, vget_high_u16(diff1), vget_high_u16(diff1)); - err_u64[1] = vpadalq_u32(err_u64[1], err1); - - coeff += 16; - dqcoeff += 16; - block_size -= 16; - } while (block_size != 0); - - return horizontal_add_uint64x2(vaddq_u64(err_u64[0], err_u64[1])); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_error_sve.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_error_sve.c deleted file mode 100644 index 78e7361d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_error_sve.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2024 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vp9_rtcd.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" -#include "vpx_dsp/arm/vpx_neon_sve_bridge.h" - -int64_t vp9_block_error_sve(const tran_low_t *coeff, const tran_low_t *dqcoeff, - intptr_t block_size, int64_t *ssz) { - int64x2_t err_v = vdupq_n_s64(0); - int64x2_t ssz_v = vdupq_n_s64(0); - - assert(block_size >= 16); - assert((block_size % 16) == 0); - - do { - const int16x8_t c0 = load_tran_low_to_s16q(coeff); - const int16x8_t c1 = load_tran_low_to_s16q(coeff + 8); - - const int16x8_t d0 = load_tran_low_to_s16q(dqcoeff); - const int16x8_t d1 = load_tran_low_to_s16q(dqcoeff + 8); - - const int16x8_t diff0 = vabdq_s16(c0, d0); - const int16x8_t diff1 = vabdq_s16(c1, d1); - - err_v = vpx_dotq_s16(err_v, diff0, diff0); - err_v = vpx_dotq_s16(err_v, diff1, diff1); - - ssz_v = vpx_dotq_s16(ssz_v, c0, c0); - ssz_v = vpx_dotq_s16(ssz_v, c1, c1); - - coeff += 16; - dqcoeff += 16; - block_size -= 16; - } while (block_size != 0); - - *ssz = horizontal_add_int64x2(ssz_v); - return horizontal_add_int64x2(err_v); -} - -int64_t vp9_block_error_fp_sve(const tran_low_t *coeff, - const tran_low_t *dqcoeff, int block_size) { - int64x2_t err = vdupq_n_s64(0); - - assert(block_size >= 16); - assert((block_size % 16) == 0); - - do { - const int16x8_t c0 = load_tran_low_to_s16q(coeff); - const int16x8_t c1 = load_tran_low_to_s16q(coeff + 8); - - const int16x8_t d0 = load_tran_low_to_s16q(dqcoeff); - const int16x8_t d1 = load_tran_low_to_s16q(dqcoeff + 8); - - const int16x8_t diff0 = vabdq_s16(c0, d0); - const int16x8_t diff1 = vabdq_s16(c1, d1); - - err = vpx_dotq_s16(err, diff0, diff0); - err = vpx_dotq_s16(err, diff1, diff1); - - coeff += 16; - dqcoeff += 16; - block_size -= 16; - } while (block_size != 0); - - return horizontal_add_int64x2(err); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_frame_scale_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_frame_scale_neon.c deleted file mode 100644 index bc8dd4a3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_frame_scale_neon.c +++ /dev/null @@ -1,844 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp9_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "./vpx_scale_rtcd.h" -#include "vp9/common/vp9_blockd.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/arm/vpx_convolve8_neon.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_scale/yv12config.h" - -// Note: The scaling functions could write extra rows and columns in dst, which -// exceed the right and bottom boundaries of the destination frame. We rely on -// the following frame extension function to fix these rows and columns. - -static INLINE void scale_plane_2_to_1_phase_0(const uint8_t *src, - const int src_stride, - uint8_t *dst, - const int dst_stride, const int w, - const int h) { - const int max_width = (w + 15) & ~15; - int y = h; - - assert(w && h); - - do { - int x = max_width; - do { - const uint8x16x2_t s = vld2q_u8(src); - vst1q_u8(dst, s.val[0]); - src += 32; - dst += 16; - x -= 16; - } while (x); - src += 2 * (src_stride - max_width); - dst += dst_stride - max_width; - } while (--y); -} - -static INLINE void scale_plane_4_to_1_phase_0(const uint8_t *src, - const int src_stride, - uint8_t *dst, - const int dst_stride, const int w, - const int h) { - const int max_width = (w + 15) & ~15; - int y = h; - - assert(w && h); - - do { - int x = max_width; - do { - const uint8x16x4_t s = vld4q_u8(src); - vst1q_u8(dst, s.val[0]); - src += 64; - dst += 16; - x -= 16; - } while (x); - src += 4 * (src_stride - max_width); - dst += dst_stride - max_width; - } while (--y); -} - -static INLINE void scale_plane_bilinear_kernel( - const uint8x16_t in0, const uint8x16_t in1, const uint8x16_t in2, - const uint8x16_t in3, const uint8x8_t coef0, const uint8x8_t coef1, - uint8_t *const dst) { - const uint16x8_t h0 = vmull_u8(vget_low_u8(in0), coef0); - const uint16x8_t h1 = vmull_u8(vget_high_u8(in0), coef0); - const uint16x8_t h2 = vmull_u8(vget_low_u8(in2), coef0); - const uint16x8_t h3 = vmull_u8(vget_high_u8(in2), coef0); - const uint16x8_t h4 = vmlal_u8(h0, vget_low_u8(in1), coef1); - const uint16x8_t h5 = vmlal_u8(h1, vget_high_u8(in1), coef1); - const uint16x8_t h6 = vmlal_u8(h2, vget_low_u8(in3), coef1); - const uint16x8_t h7 = vmlal_u8(h3, vget_high_u8(in3), coef1); - - const uint8x8_t hor0 = vrshrn_n_u16(h4, 7); // temp: 00 01 02 03 04 05 06 07 - const uint8x8_t hor1 = vrshrn_n_u16(h5, 7); // temp: 08 09 0A 0B 0C 0D 0E 0F - const uint8x8_t hor2 = vrshrn_n_u16(h6, 7); // temp: 10 11 12 13 14 15 16 17 - const uint8x8_t hor3 = vrshrn_n_u16(h7, 7); // temp: 18 19 1A 1B 1C 1D 1E 1F - const uint16x8_t v0 = vmull_u8(hor0, coef0); - const uint16x8_t v1 = vmull_u8(hor1, coef0); - const uint16x8_t v2 = vmlal_u8(v0, hor2, coef1); - const uint16x8_t v3 = vmlal_u8(v1, hor3, coef1); - // dst: 0 1 2 3 4 5 6 7 8 9 A B C D E F - const uint8x16_t d = vcombine_u8(vrshrn_n_u16(v2, 7), vrshrn_n_u16(v3, 7)); - vst1q_u8(dst, d); -} - -static INLINE void scale_plane_2_to_1_bilinear( - const uint8_t *const src, const int src_stride, uint8_t *dst, - const int dst_stride, const int w, const int h, const int16_t c0, - const int16_t c1) { - const int max_width = (w + 15) & ~15; - const uint8_t *src0 = src; - const uint8_t *src1 = src + src_stride; - const uint8x8_t coef0 = vdup_n_u8(c0); - const uint8x8_t coef1 = vdup_n_u8(c1); - int y = h; - - assert(w && h); - - do { - int x = max_width; - do { - // 000 002 004 006 008 00A 00C 00E 010 012 014 016 018 01A 01C 01E - // 001 003 005 007 009 00B 00D 00F 011 013 015 017 019 01B 01D 01F - const uint8x16x2_t s0 = vld2q_u8(src0); - // 100 102 104 106 108 10A 10C 10E 110 112 114 116 118 11A 11C 11E - // 101 103 105 107 109 10B 10D 10F 111 113 115 117 119 11B 11D 11F - const uint8x16x2_t s1 = vld2q_u8(src1); - scale_plane_bilinear_kernel(s0.val[0], s0.val[1], s1.val[0], s1.val[1], - coef0, coef1, dst); - src0 += 32; - src1 += 32; - dst += 16; - x -= 16; - } while (x); - src0 += 2 * (src_stride - max_width); - src1 += 2 * (src_stride - max_width); - dst += dst_stride - max_width; - } while (--y); -} - -static INLINE void scale_plane_4_to_1_bilinear( - const uint8_t *const src, const int src_stride, uint8_t *dst, - const int dst_stride, const int w, const int h, const int16_t c0, - const int16_t c1) { - const int max_width = (w + 15) & ~15; - const uint8_t *src0 = src; - const uint8_t *src1 = src + src_stride; - const uint8x8_t coef0 = vdup_n_u8(c0); - const uint8x8_t coef1 = vdup_n_u8(c1); - int y = h; - - assert(w && h); - - do { - int x = max_width; - do { - // (*) -- useless - // 000 004 008 00C 010 014 018 01C 020 024 028 02C 030 034 038 03C - // 001 005 009 00D 011 015 019 01D 021 025 029 02D 031 035 039 03D - // 002 006 00A 00E 012 016 01A 01E 022 026 02A 02E 032 036 03A 03E (*) - // 003 007 00B 00F 013 017 01B 01F 023 027 02B 02F 033 037 03B 03F (*) - const uint8x16x4_t s0 = vld4q_u8(src0); - // 100 104 108 10C 110 114 118 11C 120 124 128 12C 130 134 138 13C - // 101 105 109 10D 111 115 119 11D 121 125 129 12D 131 135 139 13D - // 102 106 10A 10E 112 116 11A 11E 122 126 12A 12E 132 136 13A 13E (*) - // 103 107 10B 10F 113 117 11B 11F 123 127 12B 12F 133 137 13B 13F (*) - const uint8x16x4_t s1 = vld4q_u8(src1); - scale_plane_bilinear_kernel(s0.val[0], s0.val[1], s1.val[0], s1.val[1], - coef0, coef1, dst); - src0 += 64; - src1 += 64; - dst += 16; - x -= 16; - } while (x); - src0 += 4 * (src_stride - max_width); - src1 += 4 * (src_stride - max_width); - dst += dst_stride - max_width; - } while (--y); -} - -static INLINE uint8x8_t scale_filter_bilinear(const uint8x8_t *const s, - const uint8x8_t *const coef) { - const uint16x8_t h0 = vmull_u8(s[0], coef[0]); - const uint16x8_t h1 = vmlal_u8(h0, s[1], coef[1]); - - return vrshrn_n_u16(h1, 7); -} - -static void scale_plane_2_to_1_general(const uint8_t *src, const int src_stride, - uint8_t *dst, const int dst_stride, - const int w, const int h, - const int16_t *const coef, - uint8_t *const temp_buffer) { - const int width_hor = (w + 3) & ~3; - const int width_ver = (w + 7) & ~7; - const int height_hor = (2 * h + SUBPEL_TAPS - 2 + 7) & ~7; - const int height_ver = (h + 3) & ~3; - const int16x8_t filters = vld1q_s16(coef); - int x, y = height_hor; - uint8_t *t = temp_buffer; - uint8x8_t s[14], d[4]; - - assert(w && h); - - src -= (SUBPEL_TAPS / 2 - 1) * src_stride + SUBPEL_TAPS / 2 + 1; - - // horizontal 4x8 - // Note: processing 4x8 is about 20% faster than processing row by row using - // vld4_u8(). - do { - load_u8_8x8(src + 2, src_stride, &s[0], &s[1], &s[2], &s[3], &s[4], &s[5], - &s[6], &s[7]); - transpose_u8_8x8(&s[0], &s[1], &s[2], &s[3], &s[4], &s[5], &s[6], &s[7]); - x = width_hor; - - do { - src += 8; - load_u8_8x8(src, src_stride, &s[6], &s[7], &s[8], &s[9], &s[10], &s[11], - &s[12], &s[13]); - transpose_u8_8x8(&s[6], &s[7], &s[8], &s[9], &s[10], &s[11], &s[12], - &s[13]); - - d[0] = scale_filter_8(&s[0], filters); // 00 10 20 30 40 50 60 70 - d[1] = scale_filter_8(&s[2], filters); // 01 11 21 31 41 51 61 71 - d[2] = scale_filter_8(&s[4], filters); // 02 12 22 32 42 52 62 72 - d[3] = scale_filter_8(&s[6], filters); // 03 13 23 33 43 53 63 73 - // 00 01 02 03 40 41 42 43 - // 10 11 12 13 50 51 52 53 - // 20 21 22 23 60 61 62 63 - // 30 31 32 33 70 71 72 73 - transpose_u8_8x4(&d[0], &d[1], &d[2], &d[3]); - vst1_lane_u32((uint32_t *)(t + 0 * width_hor), vreinterpret_u32_u8(d[0]), - 0); - vst1_lane_u32((uint32_t *)(t + 1 * width_hor), vreinterpret_u32_u8(d[1]), - 0); - vst1_lane_u32((uint32_t *)(t + 2 * width_hor), vreinterpret_u32_u8(d[2]), - 0); - vst1_lane_u32((uint32_t *)(t + 3 * width_hor), vreinterpret_u32_u8(d[3]), - 0); - vst1_lane_u32((uint32_t *)(t + 4 * width_hor), vreinterpret_u32_u8(d[0]), - 1); - vst1_lane_u32((uint32_t *)(t + 5 * width_hor), vreinterpret_u32_u8(d[1]), - 1); - vst1_lane_u32((uint32_t *)(t + 6 * width_hor), vreinterpret_u32_u8(d[2]), - 1); - vst1_lane_u32((uint32_t *)(t + 7 * width_hor), vreinterpret_u32_u8(d[3]), - 1); - - s[0] = s[8]; - s[1] = s[9]; - s[2] = s[10]; - s[3] = s[11]; - s[4] = s[12]; - s[5] = s[13]; - - t += 4; - x -= 4; - } while (x); - src += 8 * src_stride - 2 * width_hor; - t += 7 * width_hor; - y -= 8; - } while (y); - - // vertical 8x4 - x = width_ver; - t = temp_buffer; - do { - load_u8_8x8(t, width_hor, &s[0], &s[1], &s[2], &s[3], &s[4], &s[5], &s[6], - &s[7]); - t += 6 * width_hor; - y = height_ver; - - do { - load_u8_8x8(t, width_hor, &s[6], &s[7], &s[8], &s[9], &s[10], &s[11], - &s[12], &s[13]); - t += 8 * width_hor; - - d[0] = scale_filter_8(&s[0], filters); // 00 01 02 03 04 05 06 07 - d[1] = scale_filter_8(&s[2], filters); // 10 11 12 13 14 15 16 17 - d[2] = scale_filter_8(&s[4], filters); // 20 21 22 23 24 25 26 27 - d[3] = scale_filter_8(&s[6], filters); // 30 31 32 33 34 35 36 37 - vst1_u8(dst + 0 * dst_stride, d[0]); - vst1_u8(dst + 1 * dst_stride, d[1]); - vst1_u8(dst + 2 * dst_stride, d[2]); - vst1_u8(dst + 3 * dst_stride, d[3]); - - s[0] = s[8]; - s[1] = s[9]; - s[2] = s[10]; - s[3] = s[11]; - s[4] = s[12]; - s[5] = s[13]; - - dst += 4 * dst_stride; - y -= 4; - } while (y); - t -= width_hor * (2 * height_ver + 6); - t += 8; - dst -= height_ver * dst_stride; - dst += 8; - x -= 8; - } while (x); -} - -static void scale_plane_4_to_1_general(const uint8_t *src, const int src_stride, - uint8_t *dst, const int dst_stride, - const int w, const int h, - const int16_t *const coef, - uint8_t *const temp_buffer) { - const int width_hor = (w + 1) & ~1; - const int width_ver = (w + 7) & ~7; - const int height_hor = (4 * h + SUBPEL_TAPS - 2 + 7) & ~7; - const int height_ver = (h + 1) & ~1; - const int16x8_t filters = vld1q_s16(coef); - int x, y = height_hor; - uint8_t *t = temp_buffer; - uint8x8_t s[12], d[2]; - - assert(w && h); - - src -= (SUBPEL_TAPS / 2 - 1) * src_stride + SUBPEL_TAPS / 2 + 3; - - // horizontal 2x8 - // Note: processing 2x8 is about 20% faster than processing row by row using - // vld4_u8(). - do { - load_u8_8x8(src + 4, src_stride, &s[0], &s[1], &s[2], &s[3], &s[4], &s[5], - &s[6], &s[7]); - transpose_u8_4x8(&s[0], &s[1], &s[2], &s[3], s[4], s[5], s[6], s[7]); - x = width_hor; - - do { - uint8x8x2_t dd; - src += 8; - load_u8_8x8(src, src_stride, &s[4], &s[5], &s[6], &s[7], &s[8], &s[9], - &s[10], &s[11]); - transpose_u8_8x8(&s[4], &s[5], &s[6], &s[7], &s[8], &s[9], &s[10], - &s[11]); - - d[0] = scale_filter_8(&s[0], filters); // 00 10 20 30 40 50 60 70 - d[1] = scale_filter_8(&s[4], filters); // 01 11 21 31 41 51 61 71 - // dd.val[0]: 00 01 20 21 40 41 60 61 - // dd.val[1]: 10 11 30 31 50 51 70 71 - dd = vtrn_u8(d[0], d[1]); - vst1_lane_u16((uint16_t *)(t + 0 * width_hor), - vreinterpret_u16_u8(dd.val[0]), 0); - vst1_lane_u16((uint16_t *)(t + 1 * width_hor), - vreinterpret_u16_u8(dd.val[1]), 0); - vst1_lane_u16((uint16_t *)(t + 2 * width_hor), - vreinterpret_u16_u8(dd.val[0]), 1); - vst1_lane_u16((uint16_t *)(t + 3 * width_hor), - vreinterpret_u16_u8(dd.val[1]), 1); - vst1_lane_u16((uint16_t *)(t + 4 * width_hor), - vreinterpret_u16_u8(dd.val[0]), 2); - vst1_lane_u16((uint16_t *)(t + 5 * width_hor), - vreinterpret_u16_u8(dd.val[1]), 2); - vst1_lane_u16((uint16_t *)(t + 6 * width_hor), - vreinterpret_u16_u8(dd.val[0]), 3); - vst1_lane_u16((uint16_t *)(t + 7 * width_hor), - vreinterpret_u16_u8(dd.val[1]), 3); - - s[0] = s[8]; - s[1] = s[9]; - s[2] = s[10]; - s[3] = s[11]; - - t += 2; - x -= 2; - } while (x); - src += 8 * src_stride - 4 * width_hor; - t += 7 * width_hor; - y -= 8; - } while (y); - - // vertical 8x2 - x = width_ver; - t = temp_buffer; - do { - load_u8_8x4(t, width_hor, &s[0], &s[1], &s[2], &s[3]); - t += 4 * width_hor; - y = height_ver; - - do { - load_u8_8x8(t, width_hor, &s[4], &s[5], &s[6], &s[7], &s[8], &s[9], - &s[10], &s[11]); - t += 8 * width_hor; - - d[0] = scale_filter_8(&s[0], filters); // 00 01 02 03 04 05 06 07 - d[1] = scale_filter_8(&s[4], filters); // 10 11 12 13 14 15 16 17 - vst1_u8(dst + 0 * dst_stride, d[0]); - vst1_u8(dst + 1 * dst_stride, d[1]); - - s[0] = s[8]; - s[1] = s[9]; - s[2] = s[10]; - s[3] = s[11]; - - dst += 2 * dst_stride; - y -= 2; - } while (y); - t -= width_hor * (4 * height_ver + 4); - t += 8; - dst -= height_ver * dst_stride; - dst += 8; - x -= 8; - } while (x); -} - -// Notes for 4 to 3 scaling: -// -// 1. 6 rows are calculated in each horizontal inner loop, so width_hor must be -// multiple of 6, and no less than w. -// -// 2. 8 rows are calculated in each vertical inner loop, so width_ver must be -// multiple of 8, and no less than w. -// -// 3. 8 columns are calculated in each horizontal inner loop for further -// vertical scaling, so height_hor must be multiple of 8, and no less than -// 4 * h / 3. -// -// 4. 6 columns are calculated in each vertical inner loop, so height_ver must -// be multiple of 6, and no less than h. -// -// 5. The physical location of the last row of the 4 to 3 scaled frame is -// decided by phase_scaler, and are always less than 1 pixel below the last row -// of the original image. - -static void scale_plane_4_to_3_bilinear(const uint8_t *src, - const int src_stride, uint8_t *dst, - const int dst_stride, const int w, - const int h, const int phase_scaler, - uint8_t *const temp_buffer) { - static const int step_q4 = 16 * 4 / 3; - const int width_hor = (w + 5) - ((w + 5) % 6); - const int stride_hor = width_hor + 2; // store 2 extra pixels - const int width_ver = (w + 7) & ~7; - // We only need 1 extra row below because there are only 2 bilinear - // coefficients. - const int height_hor = (4 * h / 3 + 1 + 7) & ~7; - const int height_ver = (h + 5) - ((h + 5) % 6); - int x, y = height_hor; - uint8_t *t = temp_buffer; - uint8x8_t s[9], d[8], c[6]; - - assert(w && h); - - c[0] = vdup_n_u8((uint8_t)vp9_filter_kernels[BILINEAR][phase_scaler][3]); - c[1] = vdup_n_u8((uint8_t)vp9_filter_kernels[BILINEAR][phase_scaler][4]); - c[2] = vdup_n_u8( - (uint8_t)vp9_filter_kernels[BILINEAR][(phase_scaler + 1 * step_q4) & - SUBPEL_MASK][3]); - c[3] = vdup_n_u8( - (uint8_t)vp9_filter_kernels[BILINEAR][(phase_scaler + 1 * step_q4) & - SUBPEL_MASK][4]); - c[4] = vdup_n_u8( - (uint8_t)vp9_filter_kernels[BILINEAR][(phase_scaler + 2 * step_q4) & - SUBPEL_MASK][3]); - c[5] = vdup_n_u8( - (uint8_t)vp9_filter_kernels[BILINEAR][(phase_scaler + 2 * step_q4) & - SUBPEL_MASK][4]); - - d[6] = vdup_n_u8(0); - d[7] = vdup_n_u8(0); - - // horizontal 6x8 - do { - load_u8_8x8(src, src_stride, &s[0], &s[1], &s[2], &s[3], &s[4], &s[5], - &s[6], &s[7]); - src += 1; - transpose_u8_8x8(&s[0], &s[1], &s[2], &s[3], &s[4], &s[5], &s[6], &s[7]); - x = width_hor; - - do { - load_u8_8x8(src, src_stride, &s[1], &s[2], &s[3], &s[4], &s[5], &s[6], - &s[7], &s[8]); - src += 8; - transpose_u8_8x8(&s[1], &s[2], &s[3], &s[4], &s[5], &s[6], &s[7], &s[8]); - - // 00 10 20 30 40 50 60 70 - // 01 11 21 31 41 51 61 71 - // 02 12 22 32 42 52 62 72 - // 03 13 23 33 43 53 63 73 - // 04 14 24 34 44 54 64 74 - // 05 15 25 35 45 55 65 75 - d[0] = scale_filter_bilinear(&s[0], &c[0]); - d[1] = - scale_filter_bilinear(&s[(phase_scaler + 1 * step_q4) >> 4], &c[2]); - d[2] = - scale_filter_bilinear(&s[(phase_scaler + 2 * step_q4) >> 4], &c[4]); - d[3] = scale_filter_bilinear(&s[4], &c[0]); - d[4] = scale_filter_bilinear(&s[4 + ((phase_scaler + 1 * step_q4) >> 4)], - &c[2]); - d[5] = scale_filter_bilinear(&s[4 + ((phase_scaler + 2 * step_q4) >> 4)], - &c[4]); - - // 00 01 02 03 04 05 xx xx - // 10 11 12 13 14 15 xx xx - // 20 21 22 23 24 25 xx xx - // 30 31 32 33 34 35 xx xx - // 40 41 42 43 44 45 xx xx - // 50 51 52 53 54 55 xx xx - // 60 61 62 63 64 65 xx xx - // 70 71 72 73 74 75 xx xx - transpose_u8_8x8(&d[0], &d[1], &d[2], &d[3], &d[4], &d[5], &d[6], &d[7]); - // store 2 extra pixels - vst1_u8(t + 0 * stride_hor, d[0]); - vst1_u8(t + 1 * stride_hor, d[1]); - vst1_u8(t + 2 * stride_hor, d[2]); - vst1_u8(t + 3 * stride_hor, d[3]); - vst1_u8(t + 4 * stride_hor, d[4]); - vst1_u8(t + 5 * stride_hor, d[5]); - vst1_u8(t + 6 * stride_hor, d[6]); - vst1_u8(t + 7 * stride_hor, d[7]); - - s[0] = s[8]; - - t += 6; - x -= 6; - } while (x); - src += 8 * src_stride - 4 * width_hor / 3 - 1; - t += 7 * stride_hor + 2; - y -= 8; - } while (y); - - // vertical 8x6 - x = width_ver; - t = temp_buffer; - do { - load_u8_8x8(t, stride_hor, &s[0], &s[1], &s[2], &s[3], &s[4], &s[5], &s[6], - &s[7]); - t += stride_hor; - y = height_ver; - - do { - load_u8_8x8(t, stride_hor, &s[1], &s[2], &s[3], &s[4], &s[5], &s[6], - &s[7], &s[8]); - t += 8 * stride_hor; - - d[0] = scale_filter_bilinear(&s[0], &c[0]); - d[1] = - scale_filter_bilinear(&s[(phase_scaler + 1 * step_q4) >> 4], &c[2]); - d[2] = - scale_filter_bilinear(&s[(phase_scaler + 2 * step_q4) >> 4], &c[4]); - d[3] = scale_filter_bilinear(&s[4], &c[0]); - d[4] = scale_filter_bilinear(&s[4 + ((phase_scaler + 1 * step_q4) >> 4)], - &c[2]); - d[5] = scale_filter_bilinear(&s[4 + ((phase_scaler + 2 * step_q4) >> 4)], - &c[4]); - vst1_u8(dst + 0 * dst_stride, d[0]); - vst1_u8(dst + 1 * dst_stride, d[1]); - vst1_u8(dst + 2 * dst_stride, d[2]); - vst1_u8(dst + 3 * dst_stride, d[3]); - vst1_u8(dst + 4 * dst_stride, d[4]); - vst1_u8(dst + 5 * dst_stride, d[5]); - - s[0] = s[8]; - - dst += 6 * dst_stride; - y -= 6; - } while (y); - t -= stride_hor * (4 * height_ver / 3 + 1); - t += 8; - dst -= height_ver * dst_stride; - dst += 8; - x -= 8; - } while (x); -} - -static void scale_plane_4_to_3_general(const uint8_t *src, const int src_stride, - uint8_t *dst, const int dst_stride, - const int w, const int h, - const InterpKernel *const coef, - const int phase_scaler, - uint8_t *const temp_buffer) { - static const int step_q4 = 16 * 4 / 3; - const int width_hor = (w + 5) - ((w + 5) % 6); - const int stride_hor = width_hor + 2; // store 2 extra pixels - const int width_ver = (w + 7) & ~7; - // We need (SUBPEL_TAPS - 1) extra rows: (SUBPEL_TAPS / 2 - 1) extra rows - // above and (SUBPEL_TAPS / 2) extra rows below. - const int height_hor = (4 * h / 3 + SUBPEL_TAPS - 1 + 7) & ~7; - const int height_ver = (h + 5) - ((h + 5) % 6); - const int16x8_t filters0 = - vld1q_s16(coef[(phase_scaler + 0 * step_q4) & SUBPEL_MASK]); - const int16x8_t filters1 = - vld1q_s16(coef[(phase_scaler + 1 * step_q4) & SUBPEL_MASK]); - const int16x8_t filters2 = - vld1q_s16(coef[(phase_scaler + 2 * step_q4) & SUBPEL_MASK]); - int x, y = height_hor; - uint8_t *t = temp_buffer; - uint8x8_t s[15], d[8]; - - assert(w && h); - - src -= (SUBPEL_TAPS / 2 - 1) * src_stride + SUBPEL_TAPS / 2; - d[6] = vdup_n_u8(0); - d[7] = vdup_n_u8(0); - - // horizontal 6x8 - do { - load_u8_8x8(src + 1, src_stride, &s[0], &s[1], &s[2], &s[3], &s[4], &s[5], - &s[6], &s[7]); - transpose_u8_8x8(&s[0], &s[1], &s[2], &s[3], &s[4], &s[5], &s[6], &s[7]); - x = width_hor; - - do { - src += 8; - load_u8_8x8(src, src_stride, &s[7], &s[8], &s[9], &s[10], &s[11], &s[12], - &s[13], &s[14]); - transpose_u8_8x8(&s[7], &s[8], &s[9], &s[10], &s[11], &s[12], &s[13], - &s[14]); - - // 00 10 20 30 40 50 60 70 - // 01 11 21 31 41 51 61 71 - // 02 12 22 32 42 52 62 72 - // 03 13 23 33 43 53 63 73 - // 04 14 24 34 44 54 64 74 - // 05 15 25 35 45 55 65 75 - d[0] = scale_filter_8(&s[0], filters0); - d[1] = scale_filter_8(&s[(phase_scaler + 1 * step_q4) >> 4], filters1); - d[2] = scale_filter_8(&s[(phase_scaler + 2 * step_q4) >> 4], filters2); - d[3] = scale_filter_8(&s[4], filters0); - d[4] = - scale_filter_8(&s[4 + ((phase_scaler + 1 * step_q4) >> 4)], filters1); - d[5] = - scale_filter_8(&s[4 + ((phase_scaler + 2 * step_q4) >> 4)], filters2); - - // 00 01 02 03 04 05 xx xx - // 10 11 12 13 14 15 xx xx - // 20 21 22 23 24 25 xx xx - // 30 31 32 33 34 35 xx xx - // 40 41 42 43 44 45 xx xx - // 50 51 52 53 54 55 xx xx - // 60 61 62 63 64 65 xx xx - // 70 71 72 73 74 75 xx xx - transpose_u8_8x8(&d[0], &d[1], &d[2], &d[3], &d[4], &d[5], &d[6], &d[7]); - // store 2 extra pixels - vst1_u8(t + 0 * stride_hor, d[0]); - vst1_u8(t + 1 * stride_hor, d[1]); - vst1_u8(t + 2 * stride_hor, d[2]); - vst1_u8(t + 3 * stride_hor, d[3]); - vst1_u8(t + 4 * stride_hor, d[4]); - vst1_u8(t + 5 * stride_hor, d[5]); - vst1_u8(t + 6 * stride_hor, d[6]); - vst1_u8(t + 7 * stride_hor, d[7]); - - s[0] = s[8]; - s[1] = s[9]; - s[2] = s[10]; - s[3] = s[11]; - s[4] = s[12]; - s[5] = s[13]; - s[6] = s[14]; - - t += 6; - x -= 6; - } while (x); - src += 8 * src_stride - 4 * width_hor / 3; - t += 7 * stride_hor + 2; - y -= 8; - } while (y); - - // vertical 8x6 - x = width_ver; - t = temp_buffer; - do { - load_u8_8x8(t, stride_hor, &s[0], &s[1], &s[2], &s[3], &s[4], &s[5], &s[6], - &s[7]); - t += 7 * stride_hor; - y = height_ver; - - do { - load_u8_8x8(t, stride_hor, &s[7], &s[8], &s[9], &s[10], &s[11], &s[12], - &s[13], &s[14]); - t += 8 * stride_hor; - - d[0] = scale_filter_8(&s[0], filters0); - d[1] = scale_filter_8(&s[(phase_scaler + 1 * step_q4) >> 4], filters1); - d[2] = scale_filter_8(&s[(phase_scaler + 2 * step_q4) >> 4], filters2); - d[3] = scale_filter_8(&s[4], filters0); - d[4] = - scale_filter_8(&s[4 + ((phase_scaler + 1 * step_q4) >> 4)], filters1); - d[5] = - scale_filter_8(&s[4 + ((phase_scaler + 2 * step_q4) >> 4)], filters2); - vst1_u8(dst + 0 * dst_stride, d[0]); - vst1_u8(dst + 1 * dst_stride, d[1]); - vst1_u8(dst + 2 * dst_stride, d[2]); - vst1_u8(dst + 3 * dst_stride, d[3]); - vst1_u8(dst + 4 * dst_stride, d[4]); - vst1_u8(dst + 5 * dst_stride, d[5]); - - s[0] = s[8]; - s[1] = s[9]; - s[2] = s[10]; - s[3] = s[11]; - s[4] = s[12]; - s[5] = s[13]; - s[6] = s[14]; - - dst += 6 * dst_stride; - y -= 6; - } while (y); - t -= stride_hor * (4 * height_ver / 3 + 7); - t += 8; - dst -= height_ver * dst_stride; - dst += 8; - x -= 8; - } while (x); -} - -void vp9_scale_and_extend_frame_neon(const YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst, - INTERP_FILTER filter_type, - int phase_scaler) { - const int src_w = src->y_crop_width; - const int src_h = src->y_crop_height; - const int dst_w = dst->y_crop_width; - const int dst_h = dst->y_crop_height; - const int dst_uv_w = dst->uv_crop_width; - const int dst_uv_h = dst->uv_crop_height; - int scaled = 0; - - // phase_scaler is usually 0 or 8. - assert(phase_scaler >= 0 && phase_scaler < 16); - - if (2 * dst_w == src_w && 2 * dst_h == src_h) { - // 2 to 1 - scaled = 1; - if (phase_scaler == 0) { - scale_plane_2_to_1_phase_0(src->y_buffer, src->y_stride, dst->y_buffer, - dst->y_stride, dst_w, dst_h); - scale_plane_2_to_1_phase_0(src->u_buffer, src->uv_stride, dst->u_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h); - scale_plane_2_to_1_phase_0(src->v_buffer, src->uv_stride, dst->v_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h); - } else if (filter_type == BILINEAR) { - const int16_t c0 = vp9_filter_kernels[BILINEAR][phase_scaler][3]; - const int16_t c1 = vp9_filter_kernels[BILINEAR][phase_scaler][4]; - scale_plane_2_to_1_bilinear(src->y_buffer, src->y_stride, dst->y_buffer, - dst->y_stride, dst_w, dst_h, c0, c1); - scale_plane_2_to_1_bilinear(src->u_buffer, src->uv_stride, dst->u_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h, c0, c1); - scale_plane_2_to_1_bilinear(src->v_buffer, src->uv_stride, dst->v_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h, c0, c1); - } else { - const int buffer_stride = (dst_w + 3) & ~3; - const int buffer_height = (2 * dst_h + SUBPEL_TAPS - 2 + 7) & ~7; - uint8_t *const temp_buffer = - (uint8_t *)malloc(buffer_stride * buffer_height); - if (temp_buffer) { - scale_plane_2_to_1_general( - src->y_buffer, src->y_stride, dst->y_buffer, dst->y_stride, dst_w, - dst_h, vp9_filter_kernels[filter_type][phase_scaler], temp_buffer); - scale_plane_2_to_1_general( - src->u_buffer, src->uv_stride, dst->u_buffer, dst->uv_stride, - dst_uv_w, dst_uv_h, vp9_filter_kernels[filter_type][phase_scaler], - temp_buffer); - scale_plane_2_to_1_general( - src->v_buffer, src->uv_stride, dst->v_buffer, dst->uv_stride, - dst_uv_w, dst_uv_h, vp9_filter_kernels[filter_type][phase_scaler], - temp_buffer); - free(temp_buffer); - } else { - scaled = 0; - } - } - } else if (4 * dst_w == src_w && 4 * dst_h == src_h) { - // 4 to 1 - scaled = 1; - if (phase_scaler == 0) { - scale_plane_4_to_1_phase_0(src->y_buffer, src->y_stride, dst->y_buffer, - dst->y_stride, dst_w, dst_h); - scale_plane_4_to_1_phase_0(src->u_buffer, src->uv_stride, dst->u_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h); - scale_plane_4_to_1_phase_0(src->v_buffer, src->uv_stride, dst->v_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h); - } else if (filter_type == BILINEAR) { - const int16_t c0 = vp9_filter_kernels[BILINEAR][phase_scaler][3]; - const int16_t c1 = vp9_filter_kernels[BILINEAR][phase_scaler][4]; - scale_plane_4_to_1_bilinear(src->y_buffer, src->y_stride, dst->y_buffer, - dst->y_stride, dst_w, dst_h, c0, c1); - scale_plane_4_to_1_bilinear(src->u_buffer, src->uv_stride, dst->u_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h, c0, c1); - scale_plane_4_to_1_bilinear(src->v_buffer, src->uv_stride, dst->v_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h, c0, c1); - } else { - const int buffer_stride = (dst_w + 1) & ~1; - const int buffer_height = (4 * dst_h + SUBPEL_TAPS - 2 + 7) & ~7; - uint8_t *const temp_buffer = - (uint8_t *)malloc(buffer_stride * buffer_height); - if (temp_buffer) { - scale_plane_4_to_1_general( - src->y_buffer, src->y_stride, dst->y_buffer, dst->y_stride, dst_w, - dst_h, vp9_filter_kernels[filter_type][phase_scaler], temp_buffer); - scale_plane_4_to_1_general( - src->u_buffer, src->uv_stride, dst->u_buffer, dst->uv_stride, - dst_uv_w, dst_uv_h, vp9_filter_kernels[filter_type][phase_scaler], - temp_buffer); - scale_plane_4_to_1_general( - src->v_buffer, src->uv_stride, dst->v_buffer, dst->uv_stride, - dst_uv_w, dst_uv_h, vp9_filter_kernels[filter_type][phase_scaler], - temp_buffer); - free(temp_buffer); - } else { - scaled = 0; - } - } - } else if (4 * dst_w == 3 * src_w && 4 * dst_h == 3 * src_h) { - // 4 to 3 - const int buffer_stride = (dst_w + 5) - ((dst_w + 5) % 6) + 2; - const int buffer_height = (4 * dst_h / 3 + SUBPEL_TAPS - 1 + 7) & ~7; - uint8_t *const temp_buffer = - (uint8_t *)malloc(buffer_stride * buffer_height); - if (temp_buffer) { - scaled = 1; - if (filter_type == BILINEAR) { - scale_plane_4_to_3_bilinear(src->y_buffer, src->y_stride, dst->y_buffer, - dst->y_stride, dst_w, dst_h, phase_scaler, - temp_buffer); - scale_plane_4_to_3_bilinear(src->u_buffer, src->uv_stride, - dst->u_buffer, dst->uv_stride, dst_uv_w, - dst_uv_h, phase_scaler, temp_buffer); - scale_plane_4_to_3_bilinear(src->v_buffer, src->uv_stride, - dst->v_buffer, dst->uv_stride, dst_uv_w, - dst_uv_h, phase_scaler, temp_buffer); - } else { - scale_plane_4_to_3_general( - src->y_buffer, src->y_stride, dst->y_buffer, dst->y_stride, dst_w, - dst_h, vp9_filter_kernels[filter_type], phase_scaler, temp_buffer); - scale_plane_4_to_3_general(src->u_buffer, src->uv_stride, dst->u_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h, - vp9_filter_kernels[filter_type], - phase_scaler, temp_buffer); - scale_plane_4_to_3_general(src->v_buffer, src->uv_stride, dst->v_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h, - vp9_filter_kernels[filter_type], - phase_scaler, temp_buffer); - } - free(temp_buffer); - } - } - - if (scaled) { - vpx_extend_frame_borders(dst); - } else { - // Call c version for all other scaling ratios. - vp9_scale_and_extend_frame_c(src, dst, filter_type, phase_scaler); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_highbd_error_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_highbd_error_neon.c deleted file mode 100644 index d9b18347..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_highbd_error_neon.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vp9_rtcd.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" - -int64_t vp9_highbd_block_error_neon(const tran_low_t *coeff, - const tran_low_t *dqcoeff, - intptr_t block_size, int64_t *ssz, int bd) { - uint64x2_t err_u64 = vdupq_n_u64(0); - int64x2_t ssz_s64 = vdupq_n_s64(0); - - const int shift = 2 * (bd - 8); - const int rounding = shift > 0 ? 1 << (shift - 1) : 0; - - assert(block_size >= 16); - assert((block_size % 16) == 0); - - do { - const int32x4_t c = load_tran_low_to_s32q(coeff); - const int32x4_t d = load_tran_low_to_s32q(dqcoeff); - - const uint32x4_t diff = vreinterpretq_u32_s32(vabdq_s32(c, d)); - - err_u64 = vmlal_u32(err_u64, vget_low_u32(diff), vget_low_u32(diff)); - err_u64 = vmlal_u32(err_u64, vget_high_u32(diff), vget_high_u32(diff)); - - ssz_s64 = vmlal_s32(ssz_s64, vget_low_s32(c), vget_low_s32(c)); - ssz_s64 = vmlal_s32(ssz_s64, vget_high_s32(c), vget_high_s32(c)); - - coeff += 4; - dqcoeff += 4; - block_size -= 4; - } while (block_size != 0); - - *ssz = (horizontal_add_int64x2(ssz_s64) + rounding) >> shift; - return ((int64_t)horizontal_add_uint64x2(err_u64) + rounding) >> shift; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_highbd_temporal_filter_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_highbd_temporal_filter_neon.c deleted file mode 100644 index c3aef3c8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_highbd_temporal_filter_neon.c +++ /dev/null @@ -1,872 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_temporal_filter.h" -#include "vp9/encoder/vp9_temporal_filter_constants.h" - -// Compute (a-b)**2 for 8 pixels with size 16-bit -static INLINE void highbd_store_dist_8(const uint16_t *a, const uint16_t *b, - uint32_t *dst) { - const uint16x8_t a_reg = vld1q_u16(a); - const uint16x8_t b_reg = vld1q_u16(b); - - uint16x8_t dist = vabdq_u16(a_reg, b_reg); - uint32x4_t dist_first = vmull_u16(vget_low_u16(dist), vget_low_u16(dist)); - uint32x4_t dist_second = vmull_u16(vget_high_u16(dist), vget_high_u16(dist)); - - vst1q_u32(dst, dist_first); - vst1q_u32(dst + 4, dist_second); -} - -// Sum up three neighboring distortions for the pixels -static INLINE void highbd_get_sum_4(const uint32_t *dist, uint32x4_t *sum) { - uint32x4_t dist_reg, dist_left, dist_right; - - dist_reg = vld1q_u32(dist); - dist_left = vld1q_u32(dist - 1); - dist_right = vld1q_u32(dist + 1); - - *sum = vaddq_u32(dist_reg, dist_left); - *sum = vaddq_u32(*sum, dist_right); -} - -static INLINE void highbd_get_sum_8(const uint32_t *dist, uint32x4_t *sum_first, - uint32x4_t *sum_second) { - highbd_get_sum_4(dist, sum_first); - highbd_get_sum_4(dist + 4, sum_second); -} - -// Average the value based on the number of values summed (9 for pixels away -// from the border, 4 for pixels in corners, and 6 for other edge values, plus -// however many values from y/uv plane are). -// -// Add in the rounding factor and shift, clamp to 16, invert and shift. Multiply -// by weight. -static INLINE void highbd_average_4(uint32x4_t *output, const uint32x4_t sum, - const uint32x4_t *mul_constants, - const int strength, const int rounding, - const int weight) { - const int64x2_t strength_s64 = vdupq_n_s64(-strength - 32); - const uint64x2_t rounding_u64 = vdupq_n_u64((uint64_t)rounding << 32); - const uint32x4_t weight_u32 = vdupq_n_u32(weight); - const uint32x4_t sixteen = vdupq_n_u32(16); - uint32x4_t sum2; - - // modifier * 3 / index; - uint64x2_t sum_lo = - vmlal_u32(rounding_u64, vget_low_u32(sum), vget_low_u32(*mul_constants)); - uint64x2_t sum_hi = vmlal_u32(rounding_u64, vget_high_u32(sum), - vget_high_u32(*mul_constants)); - - // we cannot use vshrn_n_u64 as strength is not known at compile time. - sum_lo = vshlq_u64(sum_lo, strength_s64); - sum_hi = vshlq_u64(sum_hi, strength_s64); - - sum2 = vcombine_u32(vmovn_u64(sum_lo), vmovn_u64(sum_hi)); - - // Multiply with the weight - sum2 = vminq_u32(sum2, sixteen); - sum2 = vsubq_u32(sixteen, sum2); - *output = vmulq_u32(sum2, weight_u32); -} - -static INLINE void highbd_average_8(uint32x4_t *output_0, uint32x4_t *output_1, - const uint32x4_t sum_0_u32, - const uint32x4_t sum_1_u32, - const uint32x4_t *mul_constants_0, - const uint32x4_t *mul_constants_1, - const int strength, const int rounding, - const int weight) { - highbd_average_4(output_0, sum_0_u32, mul_constants_0, strength, rounding, - weight); - highbd_average_4(output_1, sum_1_u32, mul_constants_1, strength, rounding, - weight); -} - -// Add 'sum_u32' to 'count'. Multiply by 'pred' and add to 'accumulator.' -static INLINE void highbd_accumulate_and_store_8( - const uint32x4_t sum_first_u32, const uint32x4_t sum_second_u32, - const uint16_t *pred, uint16_t *count, uint32_t *accumulator) { - const uint16x8_t sum_u16 = - vcombine_u16(vqmovn_u32(sum_first_u32), vqmovn_u32(sum_second_u32)); - uint16x8_t pred_u16 = vld1q_u16(pred); - uint16x8_t count_u16 = vld1q_u16(count); - uint32x4_t pred_0_u32, pred_1_u32; - uint32x4_t accum_0_u32, accum_1_u32; - - count_u16 = vqaddq_u16(count_u16, sum_u16); - vst1q_u16(count, count_u16); - - accum_0_u32 = vld1q_u32(accumulator); - accum_1_u32 = vld1q_u32(accumulator + 4); - - pred_0_u32 = vmovl_u16(vget_low_u16(pred_u16)); - pred_1_u32 = vmovl_u16(vget_high_u16(pred_u16)); - - // Don't use sum_u16 as that produces different results to the C version - accum_0_u32 = vmlaq_u32(accum_0_u32, sum_first_u32, pred_0_u32); - accum_1_u32 = vmlaq_u32(accum_1_u32, sum_second_u32, pred_1_u32); - - vst1q_u32(accumulator, accum_0_u32); - vst1q_u32(accumulator + 4, accum_1_u32); -} - -static INLINE void highbd_read_dist_4(const uint32_t *dist, - uint32x4_t *dist_reg) { - *dist_reg = vld1q_u32(dist); -} - -static INLINE void highbd_read_dist_8(const uint32_t *dist, - uint32x4_t *reg_first, - uint32x4_t *reg_second) { - highbd_read_dist_4(dist, reg_first); - highbd_read_dist_4(dist + 4, reg_second); -} - -static INLINE void highbd_read_chroma_dist_row_8( - int ss_x, const uint32_t *u_dist, const uint32_t *v_dist, - uint32x4_t *u_first, uint32x4_t *u_second, uint32x4_t *v_first, - uint32x4_t *v_second) { - if (!ss_x) { - // If there is no chroma subsampling in the horizontal direction, then we - // need to load 8 entries from chroma. - highbd_read_dist_8(u_dist, u_first, u_second); - highbd_read_dist_8(v_dist, v_first, v_second); - } else { // ss_x == 1 - // Otherwise, we only need to load 8 entries - uint32x4_t u_reg, v_reg; - uint32x4x2_t pair; - - highbd_read_dist_4(u_dist, &u_reg); - - pair = vzipq_u32(u_reg, u_reg); - *u_first = pair.val[0]; - *u_second = pair.val[1]; - - highbd_read_dist_4(v_dist, &v_reg); - - pair = vzipq_u32(v_reg, v_reg); - *v_first = pair.val[0]; - *v_second = pair.val[1]; - } -} - -static void highbd_apply_temporal_filter_luma_8( - const uint16_t *y_pre, int y_pre_stride, unsigned int block_width, - unsigned int block_height, int ss_x, int ss_y, int strength, - int use_whole_blk, uint32_t *y_accum, uint16_t *y_count, - const uint32_t *y_dist, const uint32_t *u_dist, const uint32_t *v_dist, - const uint32_t *const *neighbors_first, - const uint32_t *const *neighbors_second, int top_weight, - int bottom_weight) { - const int rounding = (1 << strength) >> 1; - int weight = top_weight; - - uint32x4_t mul_first, mul_second; - - uint32x4_t sum_row_1_first, sum_row_1_second; - uint32x4_t sum_row_2_first, sum_row_2_second; - uint32x4_t sum_row_3_first, sum_row_3_second; - - uint32x4_t u_first, u_second; - uint32x4_t v_first, v_second; - - uint32x4_t sum_row_first; - uint32x4_t sum_row_second; - - // Loop variables - unsigned int h; - - assert(strength >= 4 && strength <= 14 && - "invalid adjusted temporal filter strength"); - assert(block_width == 8); - - (void)block_width; - - // First row - mul_first = vld1q_u32(neighbors_first[0]); - mul_second = vld1q_u32(neighbors_second[0]); - - // Add luma values - highbd_get_sum_8(y_dist, &sum_row_2_first, &sum_row_2_second); - highbd_get_sum_8(y_dist + DIST_STRIDE, &sum_row_3_first, &sum_row_3_second); - - // We don't need to saturate here because the maximum value is UINT12_MAX ** 2 - // * 9 ~= 2**24 * 9 < 2 ** 28 < INT32_MAX - sum_row_first = vaddq_u32(sum_row_2_first, sum_row_3_first); - sum_row_second = vaddq_u32(sum_row_2_second, sum_row_3_second); - - // Add chroma values - highbd_read_chroma_dist_row_8(ss_x, u_dist, v_dist, &u_first, &u_second, - &v_first, &v_second); - - // Max value here is 2 ** 24 * (9 + 2), so no saturation is needed - sum_row_first = vaddq_u32(sum_row_first, u_first); - sum_row_second = vaddq_u32(sum_row_second, u_second); - - sum_row_first = vaddq_u32(sum_row_first, v_first); - sum_row_second = vaddq_u32(sum_row_second, v_second); - - // Get modifier and store result - highbd_average_8(&sum_row_first, &sum_row_second, sum_row_first, - sum_row_second, &mul_first, &mul_second, strength, rounding, - weight); - - highbd_accumulate_and_store_8(sum_row_first, sum_row_second, y_pre, y_count, - y_accum); - - y_pre += y_pre_stride; - y_count += y_pre_stride; - y_accum += y_pre_stride; - y_dist += DIST_STRIDE; - - u_dist += DIST_STRIDE; - v_dist += DIST_STRIDE; - - // Then all the rows except the last one - mul_first = vld1q_u32(neighbors_first[1]); - mul_second = vld1q_u32(neighbors_second[1]); - - for (h = 1; h < block_height - 1; ++h) { - // Move the weight to bottom half - if (!use_whole_blk && h == block_height / 2) { - weight = bottom_weight; - } - // Shift the rows up - sum_row_1_first = sum_row_2_first; - sum_row_1_second = sum_row_2_second; - sum_row_2_first = sum_row_3_first; - sum_row_2_second = sum_row_3_second; - - // Add luma values to the modifier - sum_row_first = vaddq_u32(sum_row_1_first, sum_row_2_first); - sum_row_second = vaddq_u32(sum_row_1_second, sum_row_2_second); - - highbd_get_sum_8(y_dist + DIST_STRIDE, &sum_row_3_first, &sum_row_3_second); - - sum_row_first = vaddq_u32(sum_row_first, sum_row_3_first); - sum_row_second = vaddq_u32(sum_row_second, sum_row_3_second); - - // Add chroma values to the modifier - if (ss_y == 0 || h % 2 == 0) { - // Only calculate the new chroma distortion if we are at a pixel that - // corresponds to a new chroma row - highbd_read_chroma_dist_row_8(ss_x, u_dist, v_dist, &u_first, &u_second, - &v_first, &v_second); - - u_dist += DIST_STRIDE; - v_dist += DIST_STRIDE; - } - - sum_row_first = vaddq_u32(sum_row_first, u_first); - sum_row_second = vaddq_u32(sum_row_second, u_second); - sum_row_first = vaddq_u32(sum_row_first, v_first); - sum_row_second = vaddq_u32(sum_row_second, v_second); - - // Get modifier and store result - highbd_average_8(&sum_row_first, &sum_row_second, sum_row_first, - sum_row_second, &mul_first, &mul_second, strength, - rounding, weight); - highbd_accumulate_and_store_8(sum_row_first, sum_row_second, y_pre, y_count, - y_accum); - - y_pre += y_pre_stride; - y_count += y_pre_stride; - y_accum += y_pre_stride; - y_dist += DIST_STRIDE; - } - - // The last row - mul_first = vld1q_u32(neighbors_first[0]); - mul_second = vld1q_u32(neighbors_second[0]); - - // Shift the rows up - sum_row_1_first = sum_row_2_first; - sum_row_1_second = sum_row_2_second; - sum_row_2_first = sum_row_3_first; - sum_row_2_second = sum_row_3_second; - - // Add luma values to the modifier - sum_row_first = vaddq_u32(sum_row_1_first, sum_row_2_first); - sum_row_second = vaddq_u32(sum_row_1_second, sum_row_2_second); - - // Add chroma values to the modifier - if (ss_y == 0) { - // Only calculate the new chroma distortion if we are at a pixel that - // corresponds to a new chroma row - highbd_read_chroma_dist_row_8(ss_x, u_dist, v_dist, &u_first, &u_second, - &v_first, &v_second); - } - - sum_row_first = vaddq_u32(sum_row_first, u_first); - sum_row_second = vaddq_u32(sum_row_second, u_second); - sum_row_first = vaddq_u32(sum_row_first, v_first); - sum_row_second = vaddq_u32(sum_row_second, v_second); - - // Get modifier and store result - highbd_average_8(&sum_row_first, &sum_row_second, sum_row_first, - sum_row_second, &mul_first, &mul_second, strength, rounding, - weight); - highbd_accumulate_and_store_8(sum_row_first, sum_row_second, y_pre, y_count, - y_accum); -} - -// Perform temporal filter for the luma component. -static void highbd_apply_temporal_filter_luma( - const uint16_t *y_pre, int y_pre_stride, unsigned int block_width, - unsigned int block_height, int ss_x, int ss_y, int strength, - const int *blk_fw, int use_whole_blk, uint32_t *y_accum, uint16_t *y_count, - const uint32_t *y_dist, const uint32_t *u_dist, const uint32_t *v_dist) { - unsigned int blk_col = 0, uv_blk_col = 0; - const unsigned int blk_col_step = 8, uv_blk_col_step = 8 >> ss_x; - const unsigned int mid_width = block_width >> 1, - last_width = block_width - blk_col_step; - int top_weight = blk_fw[0], - bottom_weight = use_whole_blk ? blk_fw[0] : blk_fw[2]; - const uint32_t *const *neighbors_first; - const uint32_t *const *neighbors_second; - - // Left - neighbors_first = HIGHBD_LUMA_LEFT_COLUMN_NEIGHBORS; - neighbors_second = HIGHBD_LUMA_MIDDLE_COLUMN_NEIGHBORS; - highbd_apply_temporal_filter_luma_8( - y_pre + blk_col, y_pre_stride, blk_col_step, block_height, ss_x, ss_y, - strength, use_whole_blk, y_accum + blk_col, y_count + blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, - neighbors_first, neighbors_second, top_weight, bottom_weight); - - blk_col += blk_col_step; - uv_blk_col += uv_blk_col_step; - - // Middle First - neighbors_first = HIGHBD_LUMA_MIDDLE_COLUMN_NEIGHBORS; - for (; blk_col < mid_width; - blk_col += blk_col_step, uv_blk_col += uv_blk_col_step) { - highbd_apply_temporal_filter_luma_8( - y_pre + blk_col, y_pre_stride, blk_col_step, block_height, ss_x, ss_y, - strength, use_whole_blk, y_accum + blk_col, y_count + blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, - neighbors_first, neighbors_second, top_weight, bottom_weight); - } - - if (!use_whole_blk) { - top_weight = blk_fw[1]; - bottom_weight = blk_fw[3]; - } - - // Middle Second - for (; blk_col < last_width; - blk_col += blk_col_step, uv_blk_col += uv_blk_col_step) { - highbd_apply_temporal_filter_luma_8( - y_pre + blk_col, y_pre_stride, blk_col_step, block_height, ss_x, ss_y, - strength, use_whole_blk, y_accum + blk_col, y_count + blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, - neighbors_first, neighbors_second, top_weight, bottom_weight); - } - - // Right - neighbors_second = HIGHBD_LUMA_RIGHT_COLUMN_NEIGHBORS; - highbd_apply_temporal_filter_luma_8( - y_pre + blk_col, y_pre_stride, blk_col_step, block_height, ss_x, ss_y, - strength, use_whole_blk, y_accum + blk_col, y_count + blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, - neighbors_first, neighbors_second, top_weight, bottom_weight); -} - -// Add a row of luma distortion that corresponds to 8 chroma mods. If we are -// subsampling in x direction, then we have 16 lumas, else we have 8. -static INLINE void highbd_add_luma_dist_to_8_chroma_mod( - const uint32_t *y_dist, int ss_x, int ss_y, uint32x4_t *u_mod_fst, - uint32x4_t *u_mod_snd, uint32x4_t *v_mod_fst, uint32x4_t *v_mod_snd) { - uint32x4_t y_reg_fst, y_reg_snd; - if (!ss_x) { - highbd_read_dist_8(y_dist, &y_reg_fst, &y_reg_snd); - if (ss_y == 1) { - uint32x4_t y_tmp_fst, y_tmp_snd; - highbd_read_dist_8(y_dist + DIST_STRIDE, &y_tmp_fst, &y_tmp_snd); - y_reg_fst = vaddq_u32(y_reg_fst, y_tmp_fst); - y_reg_snd = vaddq_u32(y_reg_snd, y_tmp_snd); - } - } else { - // Temporary - uint32x4_t y_fst, y_snd; - uint64x2_t y_fst64, y_snd64; - - // First 8 - highbd_read_dist_8(y_dist, &y_fst, &y_snd); - if (ss_y == 1) { - uint32x4_t y_tmp_fst, y_tmp_snd; - highbd_read_dist_8(y_dist + DIST_STRIDE, &y_tmp_fst, &y_tmp_snd); - - y_fst = vaddq_u32(y_fst, y_tmp_fst); - y_snd = vaddq_u32(y_snd, y_tmp_snd); - } - - y_fst64 = vpaddlq_u32(y_fst); - y_snd64 = vpaddlq_u32(y_snd); - y_reg_fst = vcombine_u32(vqmovn_u64(y_fst64), vqmovn_u64(y_snd64)); - - // Second 8 - highbd_read_dist_8(y_dist + 8, &y_fst, &y_snd); - if (ss_y == 1) { - uint32x4_t y_tmp_fst, y_tmp_snd; - highbd_read_dist_8(y_dist + 8 + DIST_STRIDE, &y_tmp_fst, &y_tmp_snd); - - y_fst = vaddq_u32(y_fst, y_tmp_fst); - y_snd = vaddq_u32(y_snd, y_tmp_snd); - } - - y_fst64 = vpaddlq_u32(y_fst); - y_snd64 = vpaddlq_u32(y_snd); - y_reg_snd = vcombine_u32(vqmovn_u64(y_fst64), vqmovn_u64(y_snd64)); - } - - *u_mod_fst = vaddq_u32(*u_mod_fst, y_reg_fst); - *u_mod_snd = vaddq_u32(*u_mod_snd, y_reg_snd); - *v_mod_fst = vaddq_u32(*v_mod_fst, y_reg_fst); - *v_mod_snd = vaddq_u32(*v_mod_snd, y_reg_snd); -} - -// Apply temporal filter to the chroma components. This performs temporal -// filtering on a chroma block of 8 X uv_height. If blk_fw is not NULL, use -// blk_fw as an array of size 4 for the weights for each of the 4 subblocks, -// else use top_weight for top half, and bottom weight for bottom half. -static void highbd_apply_temporal_filter_chroma_8( - const uint16_t *u_pre, const uint16_t *v_pre, int uv_pre_stride, - unsigned int uv_block_width, unsigned int uv_block_height, int ss_x, - int ss_y, int strength, uint32_t *u_accum, uint16_t *u_count, - uint32_t *v_accum, uint16_t *v_count, const uint32_t *y_dist, - const uint32_t *u_dist, const uint32_t *v_dist, - const uint32_t *const *neighbors_fst, const uint32_t *const *neighbors_snd, - int top_weight, int bottom_weight, const int *blk_fw) { - const int rounding = (1 << strength) >> 1; - int weight = top_weight; - - uint32x4_t mul_fst, mul_snd; - - uint32x4_t u_sum_row_1_fst, u_sum_row_2_fst, u_sum_row_3_fst; - uint32x4_t v_sum_row_1_fst, v_sum_row_2_fst, v_sum_row_3_fst; - uint32x4_t u_sum_row_1_snd, u_sum_row_2_snd, u_sum_row_3_snd; - uint32x4_t v_sum_row_1_snd, v_sum_row_2_snd, v_sum_row_3_snd; - - uint32x4_t u_sum_row_fst, v_sum_row_fst; - uint32x4_t u_sum_row_snd, v_sum_row_snd; - - // Loop variable - unsigned int h; - - (void)uv_block_width; - - // First row - mul_fst = vld1q_u32(neighbors_fst[0]); - mul_snd = vld1q_u32(neighbors_snd[0]); - - // Add chroma values - highbd_get_sum_8(u_dist, &u_sum_row_2_fst, &u_sum_row_2_snd); - highbd_get_sum_8(u_dist + DIST_STRIDE, &u_sum_row_3_fst, &u_sum_row_3_snd); - - u_sum_row_fst = vaddq_u32(u_sum_row_2_fst, u_sum_row_3_fst); - u_sum_row_snd = vaddq_u32(u_sum_row_2_snd, u_sum_row_3_snd); - - highbd_get_sum_8(v_dist, &v_sum_row_2_fst, &v_sum_row_2_snd); - highbd_get_sum_8(v_dist + DIST_STRIDE, &v_sum_row_3_fst, &v_sum_row_3_snd); - - v_sum_row_fst = vaddq_u32(v_sum_row_2_fst, v_sum_row_3_fst); - v_sum_row_snd = vaddq_u32(v_sum_row_2_snd, v_sum_row_3_snd); - - // Add luma values - highbd_add_luma_dist_to_8_chroma_mod(y_dist, ss_x, ss_y, &u_sum_row_fst, - &u_sum_row_snd, &v_sum_row_fst, - &v_sum_row_snd); - - // Get modifier and store result - if (blk_fw) { - highbd_average_4(&u_sum_row_fst, u_sum_row_fst, &mul_fst, strength, - rounding, blk_fw[0]); - highbd_average_4(&u_sum_row_snd, u_sum_row_snd, &mul_snd, strength, - rounding, blk_fw[1]); - - highbd_average_4(&v_sum_row_fst, v_sum_row_fst, &mul_fst, strength, - rounding, blk_fw[0]); - highbd_average_4(&v_sum_row_snd, v_sum_row_snd, &mul_snd, strength, - rounding, blk_fw[1]); - - } else { - highbd_average_8(&u_sum_row_fst, &u_sum_row_snd, u_sum_row_fst, - u_sum_row_snd, &mul_fst, &mul_snd, strength, rounding, - weight); - highbd_average_8(&v_sum_row_fst, &v_sum_row_snd, v_sum_row_fst, - v_sum_row_snd, &mul_fst, &mul_snd, strength, rounding, - weight); - } - highbd_accumulate_and_store_8(u_sum_row_fst, u_sum_row_snd, u_pre, u_count, - u_accum); - highbd_accumulate_and_store_8(v_sum_row_fst, v_sum_row_snd, v_pre, v_count, - v_accum); - - u_pre += uv_pre_stride; - u_dist += DIST_STRIDE; - v_pre += uv_pre_stride; - v_dist += DIST_STRIDE; - u_count += uv_pre_stride; - u_accum += uv_pre_stride; - v_count += uv_pre_stride; - v_accum += uv_pre_stride; - - y_dist += DIST_STRIDE * (1 + ss_y); - - // Then all the rows except the last one - mul_fst = vld1q_u32(neighbors_fst[1]); - mul_snd = vld1q_u32(neighbors_snd[1]); - - for (h = 1; h < uv_block_height - 1; ++h) { - // Move the weight pointer to the bottom half of the blocks - if (h == uv_block_height / 2) { - if (blk_fw) { - blk_fw += 2; - } else { - weight = bottom_weight; - } - } - - // Shift the rows up - u_sum_row_1_fst = u_sum_row_2_fst; - u_sum_row_2_fst = u_sum_row_3_fst; - u_sum_row_1_snd = u_sum_row_2_snd; - u_sum_row_2_snd = u_sum_row_3_snd; - - v_sum_row_1_fst = v_sum_row_2_fst; - v_sum_row_2_fst = v_sum_row_3_fst; - v_sum_row_1_snd = v_sum_row_2_snd; - v_sum_row_2_snd = v_sum_row_3_snd; - - // Add chroma values - u_sum_row_fst = vaddq_u32(u_sum_row_1_fst, u_sum_row_2_fst); - u_sum_row_snd = vaddq_u32(u_sum_row_1_snd, u_sum_row_2_snd); - highbd_get_sum_8(u_dist + DIST_STRIDE, &u_sum_row_3_fst, &u_sum_row_3_snd); - u_sum_row_fst = vaddq_u32(u_sum_row_fst, u_sum_row_3_fst); - u_sum_row_snd = vaddq_u32(u_sum_row_snd, u_sum_row_3_snd); - - v_sum_row_fst = vaddq_u32(v_sum_row_1_fst, v_sum_row_2_fst); - v_sum_row_snd = vaddq_u32(v_sum_row_1_snd, v_sum_row_2_snd); - highbd_get_sum_8(v_dist + DIST_STRIDE, &v_sum_row_3_fst, &v_sum_row_3_snd); - v_sum_row_fst = vaddq_u32(v_sum_row_fst, v_sum_row_3_fst); - v_sum_row_snd = vaddq_u32(v_sum_row_snd, v_sum_row_3_snd); - - // Add luma values - highbd_add_luma_dist_to_8_chroma_mod(y_dist, ss_x, ss_y, &u_sum_row_fst, - &u_sum_row_snd, &v_sum_row_fst, - &v_sum_row_snd); - - // Get modifier and store result - if (blk_fw) { - highbd_average_4(&u_sum_row_fst, u_sum_row_fst, &mul_fst, strength, - rounding, blk_fw[0]); - highbd_average_4(&u_sum_row_snd, u_sum_row_snd, &mul_snd, strength, - rounding, blk_fw[1]); - - highbd_average_4(&v_sum_row_fst, v_sum_row_fst, &mul_fst, strength, - rounding, blk_fw[0]); - highbd_average_4(&v_sum_row_snd, v_sum_row_snd, &mul_snd, strength, - rounding, blk_fw[1]); - - } else { - highbd_average_8(&u_sum_row_fst, &u_sum_row_snd, u_sum_row_fst, - u_sum_row_snd, &mul_fst, &mul_snd, strength, rounding, - weight); - highbd_average_8(&v_sum_row_fst, &v_sum_row_snd, v_sum_row_fst, - v_sum_row_snd, &mul_fst, &mul_snd, strength, rounding, - weight); - } - - highbd_accumulate_and_store_8(u_sum_row_fst, u_sum_row_snd, u_pre, u_count, - u_accum); - highbd_accumulate_and_store_8(v_sum_row_fst, v_sum_row_snd, v_pre, v_count, - v_accum); - - u_pre += uv_pre_stride; - u_dist += DIST_STRIDE; - v_pre += uv_pre_stride; - v_dist += DIST_STRIDE; - u_count += uv_pre_stride; - u_accum += uv_pre_stride; - v_count += uv_pre_stride; - v_accum += uv_pre_stride; - - y_dist += DIST_STRIDE * (1 + ss_y); - } - - // The last row - mul_fst = vld1q_u32(neighbors_fst[0]); - mul_snd = vld1q_u32(neighbors_snd[0]); - - // Shift the rows up - u_sum_row_1_fst = u_sum_row_2_fst; - u_sum_row_2_fst = u_sum_row_3_fst; - u_sum_row_1_snd = u_sum_row_2_snd; - u_sum_row_2_snd = u_sum_row_3_snd; - - v_sum_row_1_fst = v_sum_row_2_fst; - v_sum_row_2_fst = v_sum_row_3_fst; - v_sum_row_1_snd = v_sum_row_2_snd; - v_sum_row_2_snd = v_sum_row_3_snd; - - // Add chroma values - u_sum_row_fst = vaddq_u32(u_sum_row_1_fst, u_sum_row_2_fst); - v_sum_row_fst = vaddq_u32(v_sum_row_1_fst, v_sum_row_2_fst); - u_sum_row_snd = vaddq_u32(u_sum_row_1_snd, u_sum_row_2_snd); - v_sum_row_snd = vaddq_u32(v_sum_row_1_snd, v_sum_row_2_snd); - - // Add luma values - highbd_add_luma_dist_to_8_chroma_mod(y_dist, ss_x, ss_y, &u_sum_row_fst, - &u_sum_row_snd, &v_sum_row_fst, - &v_sum_row_snd); - - // Get modifier and store result - if (blk_fw) { - highbd_average_4(&u_sum_row_fst, u_sum_row_fst, &mul_fst, strength, - rounding, blk_fw[0]); - highbd_average_4(&u_sum_row_snd, u_sum_row_snd, &mul_snd, strength, - rounding, blk_fw[1]); - - highbd_average_4(&v_sum_row_fst, v_sum_row_fst, &mul_fst, strength, - rounding, blk_fw[0]); - highbd_average_4(&v_sum_row_snd, v_sum_row_snd, &mul_snd, strength, - rounding, blk_fw[1]); - - } else { - highbd_average_8(&u_sum_row_fst, &u_sum_row_snd, u_sum_row_fst, - u_sum_row_snd, &mul_fst, &mul_snd, strength, rounding, - weight); - highbd_average_8(&v_sum_row_fst, &v_sum_row_snd, v_sum_row_fst, - v_sum_row_snd, &mul_fst, &mul_snd, strength, rounding, - weight); - } - - highbd_accumulate_and_store_8(u_sum_row_fst, u_sum_row_snd, u_pre, u_count, - u_accum); - highbd_accumulate_and_store_8(v_sum_row_fst, v_sum_row_snd, v_pre, v_count, - v_accum); -} - -// Perform temporal filter for the chroma components. -static void highbd_apply_temporal_filter_chroma( - const uint16_t *u_pre, const uint16_t *v_pre, int uv_pre_stride, - unsigned int block_width, unsigned int block_height, int ss_x, int ss_y, - int strength, const int *blk_fw, int use_whole_blk, uint32_t *u_accum, - uint16_t *u_count, uint32_t *v_accum, uint16_t *v_count, - const uint32_t *y_dist, const uint32_t *u_dist, const uint32_t *v_dist) { - const unsigned int uv_width = block_width >> ss_x, - uv_height = block_height >> ss_y; - - unsigned int blk_col = 0, uv_blk_col = 0; - const unsigned int uv_blk_col_step = 8, blk_col_step = 8 << ss_x; - const unsigned int uv_mid_width = uv_width >> 1, - uv_last_width = uv_width - uv_blk_col_step; - int top_weight = blk_fw[0], - bottom_weight = use_whole_blk ? blk_fw[0] : blk_fw[2]; - const uint32_t *const *neighbors_fst; - const uint32_t *const *neighbors_snd; - - if (uv_width == 8) { - // Special Case: We are subsampling in x direction on a 16x16 block. Since - // we are operating on a row of 8 chroma pixels, we can't use the usual - // left-middle-right pattern. - assert(ss_x); - - if (ss_y) { - neighbors_fst = HIGHBD_CHROMA_DOUBLE_SS_LEFT_COLUMN_NEIGHBORS; - neighbors_snd = HIGHBD_CHROMA_DOUBLE_SS_RIGHT_COLUMN_NEIGHBORS; - } else { - neighbors_fst = HIGHBD_CHROMA_SINGLE_SS_LEFT_COLUMN_NEIGHBORS; - neighbors_snd = HIGHBD_CHROMA_SINGLE_SS_RIGHT_COLUMN_NEIGHBORS; - } - - if (use_whole_blk) { - highbd_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_width, - uv_height, ss_x, ss_y, strength, u_accum + uv_blk_col, - u_count + uv_blk_col, v_accum + uv_blk_col, v_count + uv_blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, - neighbors_fst, neighbors_snd, top_weight, bottom_weight, NULL); - } else { - highbd_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_width, - uv_height, ss_x, ss_y, strength, u_accum + uv_blk_col, - u_count + uv_blk_col, v_accum + uv_blk_col, v_count + uv_blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, - neighbors_fst, neighbors_snd, 0, 0, blk_fw); - } - - return; - } - - // Left - if (ss_x && ss_y) { - neighbors_fst = HIGHBD_CHROMA_DOUBLE_SS_LEFT_COLUMN_NEIGHBORS; - neighbors_snd = HIGHBD_CHROMA_DOUBLE_SS_MIDDLE_COLUMN_NEIGHBORS; - } else if (ss_x || ss_y) { - neighbors_fst = HIGHBD_CHROMA_SINGLE_SS_LEFT_COLUMN_NEIGHBORS; - neighbors_snd = HIGHBD_CHROMA_SINGLE_SS_MIDDLE_COLUMN_NEIGHBORS; - } else { - neighbors_fst = HIGHBD_CHROMA_NO_SS_LEFT_COLUMN_NEIGHBORS; - neighbors_snd = HIGHBD_CHROMA_NO_SS_MIDDLE_COLUMN_NEIGHBORS; - } - - highbd_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_width, - uv_height, ss_x, ss_y, strength, u_accum + uv_blk_col, - u_count + uv_blk_col, v_accum + uv_blk_col, v_count + uv_blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors_fst, - neighbors_snd, top_weight, bottom_weight, NULL); - - blk_col += blk_col_step; - uv_blk_col += uv_blk_col_step; - - // Middle First - if (ss_x && ss_y) { - neighbors_fst = HIGHBD_CHROMA_DOUBLE_SS_MIDDLE_COLUMN_NEIGHBORS; - } else if (ss_x || ss_y) { - neighbors_fst = HIGHBD_CHROMA_SINGLE_SS_MIDDLE_COLUMN_NEIGHBORS; - } else { - neighbors_fst = HIGHBD_CHROMA_NO_SS_MIDDLE_COLUMN_NEIGHBORS; - } - - for (; uv_blk_col < uv_mid_width; - blk_col += blk_col_step, uv_blk_col += uv_blk_col_step) { - highbd_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_width, - uv_height, ss_x, ss_y, strength, u_accum + uv_blk_col, - u_count + uv_blk_col, v_accum + uv_blk_col, v_count + uv_blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, - neighbors_fst, neighbors_snd, top_weight, bottom_weight, NULL); - } - - if (!use_whole_blk) { - top_weight = blk_fw[1]; - bottom_weight = blk_fw[3]; - } - - // Middle Second - for (; uv_blk_col < uv_last_width; - blk_col += blk_col_step, uv_blk_col += uv_blk_col_step) { - highbd_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_width, - uv_height, ss_x, ss_y, strength, u_accum + uv_blk_col, - u_count + uv_blk_col, v_accum + uv_blk_col, v_count + uv_blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, - neighbors_fst, neighbors_snd, top_weight, bottom_weight, NULL); - } - - // Right - if (ss_x && ss_y) { - neighbors_snd = HIGHBD_CHROMA_DOUBLE_SS_RIGHT_COLUMN_NEIGHBORS; - } else if (ss_x || ss_y) { - neighbors_snd = HIGHBD_CHROMA_SINGLE_SS_RIGHT_COLUMN_NEIGHBORS; - } else { - neighbors_snd = HIGHBD_CHROMA_NO_SS_RIGHT_COLUMN_NEIGHBORS; - } - - highbd_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_width, - uv_height, ss_x, ss_y, strength, u_accum + uv_blk_col, - u_count + uv_blk_col, v_accum + uv_blk_col, v_count + uv_blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors_fst, - neighbors_snd, top_weight, bottom_weight, NULL); -} - -void vp9_highbd_apply_temporal_filter_neon( - const uint16_t *y_src, int y_src_stride, const uint16_t *y_pre, - int y_pre_stride, const uint16_t *u_src, const uint16_t *v_src, - int uv_src_stride, const uint16_t *u_pre, const uint16_t *v_pre, - int uv_pre_stride, unsigned int block_width, unsigned int block_height, - int ss_x, int ss_y, int strength, const int *const blk_fw, - int use_whole_blk, uint32_t *y_accum, uint16_t *y_count, uint32_t *u_accum, - uint16_t *u_count, uint32_t *v_accum, uint16_t *v_count) { - const unsigned int chroma_height = block_height >> ss_y, - chroma_width = block_width >> ss_x; - - DECLARE_ALIGNED(16, uint32_t, y_dist[BH * DIST_STRIDE]) = { 0 }; - DECLARE_ALIGNED(16, uint32_t, u_dist[BH * DIST_STRIDE]) = { 0 }; - DECLARE_ALIGNED(16, uint32_t, v_dist[BH * DIST_STRIDE]) = { 0 }; - - uint32_t *y_dist_ptr = y_dist + 1, *u_dist_ptr = u_dist + 1, - *v_dist_ptr = v_dist + 1; - const uint16_t *y_src_ptr = y_src, *u_src_ptr = u_src, *v_src_ptr = v_src; - const uint16_t *y_pre_ptr = y_pre, *u_pre_ptr = u_pre, *v_pre_ptr = v_pre; - - // Loop variables - unsigned int row, blk_col; - - assert(block_width <= BW && "block width too large"); - assert(block_height <= BH && "block height too large"); - assert(block_width % 16 == 0 && "block width must be multiple of 16"); - assert(block_height % 2 == 0 && "block height must be even"); - assert((ss_x == 0 || ss_x == 1) && (ss_y == 0 || ss_y == 1) && - "invalid chroma subsampling"); - assert(strength >= 4 && strength <= 14 && - "invalid adjusted temporal filter strength"); - assert(blk_fw[0] >= 0 && "filter weight must be positive"); - assert( - (use_whole_blk || (blk_fw[1] >= 0 && blk_fw[2] >= 0 && blk_fw[3] >= 0)) && - "subblock filter weight must be positive"); - assert(blk_fw[0] <= 2 && "subblock filter weight must be less than 2"); - assert( - (use_whole_blk || (blk_fw[1] <= 2 && blk_fw[2] <= 2 && blk_fw[3] <= 2)) && - "subblock filter weight must be less than 2"); - - // Precompute the difference squared - for (row = 0; row < block_height; row++) { - for (blk_col = 0; blk_col < block_width; blk_col += 8) { - highbd_store_dist_8(y_src_ptr + blk_col, y_pre_ptr + blk_col, - y_dist_ptr + blk_col); - } - y_src_ptr += y_src_stride; - y_pre_ptr += y_pre_stride; - y_dist_ptr += DIST_STRIDE; - } - - for (row = 0; row < chroma_height; row++) { - for (blk_col = 0; blk_col < chroma_width; blk_col += 8) { - highbd_store_dist_8(u_src_ptr + blk_col, u_pre_ptr + blk_col, - u_dist_ptr + blk_col); - highbd_store_dist_8(v_src_ptr + blk_col, v_pre_ptr + blk_col, - v_dist_ptr + blk_col); - } - - u_src_ptr += uv_src_stride; - u_pre_ptr += uv_pre_stride; - u_dist_ptr += DIST_STRIDE; - v_src_ptr += uv_src_stride; - v_pre_ptr += uv_pre_stride; - v_dist_ptr += DIST_STRIDE; - } - - y_dist_ptr = y_dist + 1; - u_dist_ptr = u_dist + 1; - v_dist_ptr = v_dist + 1; - - highbd_apply_temporal_filter_luma(y_pre, y_pre_stride, block_width, - block_height, ss_x, ss_y, strength, blk_fw, - use_whole_blk, y_accum, y_count, y_dist_ptr, - u_dist_ptr, v_dist_ptr); - - highbd_apply_temporal_filter_chroma( - u_pre, v_pre, uv_pre_stride, block_width, block_height, ss_x, ss_y, - strength, blk_fw, use_whole_blk, u_accum, u_count, v_accum, v_count, - y_dist_ptr, u_dist_ptr, v_dist_ptr); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_quantize_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_quantize_neon.c deleted file mode 100644 index 96d06143..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_quantize_neon.c +++ /dev/null @@ -1,403 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "./vpx_config.h" -#include "vpx_mem/vpx_mem.h" - -#include "vp9/common/vp9_quant_common.h" -#include "vp9/common/vp9_scan.h" -#include "vp9/common/vp9_seg_common.h" - -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_quantize.h" -#include "vp9/encoder/vp9_rd.h" - -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/vpx_dsp_common.h" - -static VPX_FORCE_INLINE void calculate_dqcoeff_and_store( - const int16x8_t qcoeff, const int16x8_t dequant, tran_low_t *dqcoeff) { - const int32x4_t dqcoeff_0 = - vmull_s16(vget_low_s16(qcoeff), vget_low_s16(dequant)); - const int32x4_t dqcoeff_1 = - vmull_s16(vget_high_s16(qcoeff), vget_high_s16(dequant)); - -#if CONFIG_VP9_HIGHBITDEPTH - vst1q_s32(dqcoeff, dqcoeff_0); - vst1q_s32(dqcoeff + 4, dqcoeff_1); -#else - vst1q_s16(dqcoeff, vcombine_s16(vmovn_s32(dqcoeff_0), vmovn_s32(dqcoeff_1))); -#endif // CONFIG_VP9_HIGHBITDEPTH -} - -static VPX_FORCE_INLINE int16x8_t get_max_lane_eob(const int16_t *iscan_ptr, - int16x8_t v_eobmax, - uint16x8_t v_nz_mask) { - const int16x8_t v_iscan = vld1q_s16(&iscan_ptr[0]); - const int16x8_t v_nz_iscan = vbslq_s16(v_nz_mask, vdupq_n_s16(0), v_iscan); - return vmaxq_s16(v_eobmax, v_nz_iscan); -} - -static VPX_FORCE_INLINE uint16_t get_max_eob(int16x8_t v_eobmax) { -#if VPX_ARCH_AARCH64 - return (uint16_t)vmaxvq_s16(v_eobmax); -#else - const int16x4_t v_eobmax_3210 = - vmax_s16(vget_low_s16(v_eobmax), vget_high_s16(v_eobmax)); - const int64x1_t v_eobmax_xx32 = - vshr_n_s64(vreinterpret_s64_s16(v_eobmax_3210), 32); - const int16x4_t v_eobmax_tmp = - vmax_s16(v_eobmax_3210, vreinterpret_s16_s64(v_eobmax_xx32)); - const int64x1_t v_eobmax_xxx3 = - vshr_n_s64(vreinterpret_s64_s16(v_eobmax_tmp), 16); - const int16x4_t v_eobmax_final = - vmax_s16(v_eobmax_tmp, vreinterpret_s16_s64(v_eobmax_xxx3)); - - return (uint16_t)vget_lane_s16(v_eobmax_final, 0); -#endif // VPX_ARCH_AARCH64 -} - -static VPX_FORCE_INLINE void load_fp_values( - const struct macroblock_plane *mb_plane, const int16_t *dequant_ptr, - int16x8_t *round, int16x8_t *quant, int16x8_t *dequant) { - *round = vld1q_s16(mb_plane->round_fp); - *quant = vld1q_s16(mb_plane->quant_fp); - *dequant = vld1q_s16(dequant_ptr); -} - -static VPX_FORCE_INLINE void update_fp_values(int16x8_t *v_round, - int16x8_t *v_quant, - int16x8_t *v_dequant) { -#if VPX_ARCH_AARCH64 - *v_round = vdupq_laneq_s16(*v_round, 1); - *v_quant = vdupq_laneq_s16(*v_quant, 1); - *v_dequant = vdupq_laneq_s16(*v_dequant, 1); -#else - *v_round = vdupq_lane_s16(vget_low_s16(*v_round), 1); - *v_quant = vdupq_lane_s16(vget_low_s16(*v_quant), 1); - *v_dequant = vdupq_lane_s16(vget_low_s16(*v_dequant), 1); -#endif -} - -static VPX_FORCE_INLINE void quantize_fp_8( - const int16x8_t *v_round, const int16x8_t *v_quant, - const int16x8_t *v_dequant, const tran_low_t *coeff_ptr, - const int16_t *iscan_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - int16x8_t *v_eobmax) { - const int16x8_t v_zero = vdupq_n_s16(0); - const int16x8_t v_coeff = load_tran_low_to_s16q(coeff_ptr); - const int16x8_t v_coeff_sign = vshrq_n_s16(v_coeff, 15); - const int16x8_t v_abs = vabsq_s16(v_coeff); - const int16x8_t v_tmp = vqaddq_s16(v_abs, *v_round); - const int32x4_t v_tmp_lo = - vmull_s16(vget_low_s16(v_tmp), vget_low_s16(*v_quant)); - const int32x4_t v_tmp_hi = - vmull_s16(vget_high_s16(v_tmp), vget_high_s16(*v_quant)); - const int16x8_t v_tmp2 = - vcombine_s16(vshrn_n_s32(v_tmp_lo, 16), vshrn_n_s32(v_tmp_hi, 16)); - const uint16x8_t v_nz_mask = vceqq_s16(v_tmp2, v_zero); - const int16x8_t v_qcoeff_a = veorq_s16(v_tmp2, v_coeff_sign); - const int16x8_t v_qcoeff = vsubq_s16(v_qcoeff_a, v_coeff_sign); - calculate_dqcoeff_and_store(v_qcoeff, *v_dequant, dqcoeff_ptr); - store_s16q_to_tran_low(qcoeff_ptr, v_qcoeff); - - *v_eobmax = get_max_lane_eob(iscan_ptr, *v_eobmax, v_nz_mask); -} - -void vp9_quantize_fp_neon(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - // Quantization pass: All coefficients with index >= zero_flag are - // skippable. Note: zero_flag can be zero. - int i; - int16x8_t v_eobmax = vdupq_n_s16(-1); - int16x8_t v_round, v_quant, v_dequant; - const int16_t *iscan = scan_order->iscan; - - load_fp_values(mb_plane, dequant_ptr, &v_round, &v_quant, &v_dequant); - // process dc and the first seven ac coeffs - quantize_fp_8(&v_round, &v_quant, &v_dequant, coeff_ptr, iscan, qcoeff_ptr, - dqcoeff_ptr, &v_eobmax); - - // now process the rest of the ac coeffs - update_fp_values(&v_round, &v_quant, &v_dequant); - for (i = 8; i < n_coeffs; i += 8) { - quantize_fp_8(&v_round, &v_quant, &v_dequant, coeff_ptr + i, iscan + i, - qcoeff_ptr + i, dqcoeff_ptr + i, &v_eobmax); - } - - *eob_ptr = get_max_eob(v_eobmax); -} - -static INLINE int32x4_t extract_sign_bit(int32x4_t a) { - return vreinterpretq_s32_u32(vshrq_n_u32(vreinterpretq_u32_s32(a), 31)); -} - -static VPX_FORCE_INLINE void quantize_fp_32x32_8( - const int16x8_t *v_round, const int16x8_t *v_quant, - const int16x8_t *v_dequant, const int16x8_t *dequant_thresh, - const tran_low_t *coeff_ptr, const int16_t *iscan_ptr, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, int16x8_t *v_eobmax) { - const int16x8_t v_coeff = load_tran_low_to_s16q(coeff_ptr); - const int16x8_t v_coeff_sign = vshrq_n_s16(v_coeff, 15); - const int16x8_t v_coeff_abs = vabsq_s16(v_coeff); - const int16x8_t v_thr_mask = - vreinterpretq_s16_u16(vcgeq_s16(v_coeff_abs, *dequant_thresh)); - const int16x8_t v_tmp_rnd = - vandq_s16(vqaddq_s16(v_coeff_abs, *v_round), v_thr_mask); - const int16x8_t v_abs_qcoeff = vqdmulhq_s16(v_tmp_rnd, *v_quant); - const int16x8_t v_qcoeff = - vsubq_s16(veorq_s16(v_abs_qcoeff, v_coeff_sign), v_coeff_sign); - const uint16x8_t v_nz_mask = vceqq_s16(v_abs_qcoeff, vdupq_n_s16(0)); - - int32x4_t dqcoeff_0, dqcoeff_1; - dqcoeff_0 = vmull_s16(vget_low_s16(v_qcoeff), vget_low_s16(*v_dequant)); - dqcoeff_1 = vmull_s16(vget_high_s16(v_qcoeff), vget_high_s16(*v_dequant)); - // Add 1 if negative to round towards zero because the C uses division. - dqcoeff_0 = vaddq_s32(dqcoeff_0, extract_sign_bit(dqcoeff_0)); - dqcoeff_1 = vaddq_s32(dqcoeff_1, extract_sign_bit(dqcoeff_1)); - -#if CONFIG_VP9_HIGHBITDEPTH - vst1q_s32(dqcoeff_ptr, vshrq_n_s32(dqcoeff_0, 1)); - vst1q_s32(dqcoeff_ptr + 4, vshrq_n_s32(dqcoeff_1, 1)); -#else - store_s16q_to_tran_low(dqcoeff_ptr, vcombine_s16(vshrn_n_s32(dqcoeff_0, 1), - vshrn_n_s32(dqcoeff_1, 1))); -#endif - - store_s16q_to_tran_low(qcoeff_ptr, v_qcoeff); - - *v_eobmax = get_max_lane_eob(iscan_ptr, *v_eobmax, v_nz_mask); -} - -void vp9_quantize_fp_32x32_neon(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - int16x8_t eob_max = vdupq_n_s16(-1); - // ROUND_POWER_OF_TWO(round_ptr[], 1) - int16x8_t round = vrshrq_n_s16(vld1q_s16(mb_plane->round_fp), 1); - int16x8_t quant = vld1q_s16(mb_plane->quant_fp); - int16x8_t dequant = vld1q_s16(dequant_ptr); - // dequant >> 2 is used similar to zbin as a threshold. - int16x8_t dequant_thresh = vshrq_n_s16(vld1q_s16(dequant_ptr), 2); - int i; - const int16_t *iscan = scan_order->iscan; - - (void)n_coeffs; - - // Process dc and the first seven ac coeffs. - quantize_fp_32x32_8(&round, &quant, &dequant, &dequant_thresh, coeff_ptr, - iscan, qcoeff_ptr, dqcoeff_ptr, &eob_max); - - update_fp_values(&round, &quant, &dequant); - dequant_thresh = vdupq_lane_s16(vget_low_s16(dequant_thresh), 1); - - iscan += 8; - coeff_ptr += 8; - qcoeff_ptr += 8; - dqcoeff_ptr += 8; - - // Process the rest of the ac coeffs. - for (i = 8; i < 32 * 32; i += 8) { - quantize_fp_32x32_8(&round, &quant, &dequant, &dequant_thresh, coeff_ptr, - iscan, qcoeff_ptr, dqcoeff_ptr, &eob_max); - - iscan += 8; - coeff_ptr += 8; - qcoeff_ptr += 8; - dqcoeff_ptr += 8; - } - - *eob_ptr = get_max_eob(eob_max); -} - -#if CONFIG_VP9_HIGHBITDEPTH -static VPX_FORCE_INLINE uint16x4_t -highbd_quantize_fp_4(const tran_low_t *coeff_ptr, tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, int32x4_t v_quant_s32, - int32x4_t v_dequant_s32, int32x4_t v_round_s32) { - const int32x4_t v_coeff = vld1q_s32(coeff_ptr); - const int32x4_t v_coeff_sign = - vreinterpretq_s32_u32(vcltq_s32(v_coeff, vdupq_n_s32(0))); - const int32x4_t v_abs_coeff = vabsq_s32(v_coeff); - const int32x4_t v_tmp = vaddq_s32(v_abs_coeff, v_round_s32); - // const int abs_qcoeff = (int)((tmp * quant) >> 16); - const int32x4_t v_abs_qcoeff = vqdmulhq_s32(v_tmp, v_quant_s32); - // qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign); - const int32x4_t v_qcoeff = - vsubq_s32(veorq_s32(v_abs_qcoeff, v_coeff_sign), v_coeff_sign); - const int32x4_t v_abs_dqcoeff = vmulq_s32(v_abs_qcoeff, v_dequant_s32); - // dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign); - const int32x4_t v_dqcoeff = - vsubq_s32(veorq_s32(v_abs_dqcoeff, v_coeff_sign), v_coeff_sign); - - vst1q_s32(qcoeff_ptr, v_qcoeff); - vst1q_s32(dqcoeff_ptr, v_dqcoeff); - - // Packed nz_qcoeff_mask. Used to find eob. - return vmovn_u32(vceqq_s32(v_abs_qcoeff, vdupq_n_s32(0))); -} - -void vp9_highbd_quantize_fp_neon(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *mb_plane, - tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - const int16x4_t v_zero = vdup_n_s16(0); - const int16x4_t v_quant = vld1_s16(mb_plane->quant_fp); - const int16x4_t v_dequant = vld1_s16(dequant_ptr); - const int16x4_t v_round = vld1_s16(mb_plane->round_fp); - int32x4_t v_round_s32 = vaddl_s16(v_round, v_zero); - int32x4_t v_quant_s32 = vshlq_n_s32(vaddl_s16(v_quant, v_zero), 15); - int32x4_t v_dequant_s32 = vaddl_s16(v_dequant, v_zero); - uint16x4_t v_mask_lo, v_mask_hi; - int16x8_t v_eobmax = vdupq_n_s16(-1); - const int16_t *iscan = scan_order->iscan; - - // DC and first 3 AC - v_mask_lo = highbd_quantize_fp_4(coeff_ptr, qcoeff_ptr, dqcoeff_ptr, - v_quant_s32, v_dequant_s32, v_round_s32); - - // overwrite the DC constants with AC constants - v_round_s32 = vdupq_lane_s32(vget_low_s32(v_round_s32), 1); - v_quant_s32 = vdupq_lane_s32(vget_low_s32(v_quant_s32), 1); - v_dequant_s32 = vdupq_lane_s32(vget_low_s32(v_dequant_s32), 1); - - // 4 more AC - v_mask_hi = - highbd_quantize_fp_4(coeff_ptr + 4, qcoeff_ptr + 4, dqcoeff_ptr + 4, - v_quant_s32, v_dequant_s32, v_round_s32); - - // Find the max lane eob for the first 8 coeffs. - v_eobmax = - get_max_lane_eob(iscan, v_eobmax, vcombine_u16(v_mask_lo, v_mask_hi)); - - n_coeffs -= 8; - do { - coeff_ptr += 8; - qcoeff_ptr += 8; - dqcoeff_ptr += 8; - iscan += 8; - v_mask_lo = highbd_quantize_fp_4(coeff_ptr, qcoeff_ptr, dqcoeff_ptr, - v_quant_s32, v_dequant_s32, v_round_s32); - v_mask_hi = - highbd_quantize_fp_4(coeff_ptr + 4, qcoeff_ptr + 4, dqcoeff_ptr + 4, - v_quant_s32, v_dequant_s32, v_round_s32); - // Find the max lane eob for 8 coeffs. - v_eobmax = - get_max_lane_eob(iscan, v_eobmax, vcombine_u16(v_mask_lo, v_mask_hi)); - n_coeffs -= 8; - } while (n_coeffs); - - *eob_ptr = get_max_eob(v_eobmax); -} - -static VPX_FORCE_INLINE uint16x4_t -highbd_quantize_fp_32x32_4(const tran_low_t *coeff_ptr, tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, int32x4_t v_quant_s32, - int32x4_t v_dequant_s32, int32x4_t v_round_s32) { - const int32x4_t v_coeff = vld1q_s32(coeff_ptr); - const int32x4_t v_coeff_sign = - vreinterpretq_s32_u32(vcltq_s32(v_coeff, vdupq_n_s32(0))); - const int32x4_t v_abs_coeff = vabsq_s32(v_coeff); - // ((abs_coeff << (1 + log_scale)) >= dequant_ptr[rc01]) - const int32x4_t v_abs_coeff_scaled = vshlq_n_s32(v_abs_coeff, 2); - const uint32x4_t v_mask = vcgeq_s32(v_abs_coeff_scaled, v_dequant_s32); - // const int64_t tmp = vmask ? (int64_t)abs_coeff + log_scaled_round : 0 - const int32x4_t v_tmp = vandq_s32(vaddq_s32(v_abs_coeff, v_round_s32), - vreinterpretq_s32_u32(v_mask)); - // const int abs_qcoeff = (int)((tmp * quant) >> (16 - log_scale)); - const int32x4_t v_abs_qcoeff = - vqdmulhq_s32(vshlq_n_s32(v_tmp, 1), v_quant_s32); - // qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign); - const int32x4_t v_qcoeff = - vsubq_s32(veorq_s32(v_abs_qcoeff, v_coeff_sign), v_coeff_sign); - // vshlq_s32 will shift right if shift value is negative. - const int32x4_t v_abs_dqcoeff = - vshrq_n_s32(vmulq_s32(v_abs_qcoeff, v_dequant_s32), 1); - // dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign); - const int32x4_t v_dqcoeff = - vsubq_s32(veorq_s32(v_abs_dqcoeff, v_coeff_sign), v_coeff_sign); - - vst1q_s32(qcoeff_ptr, v_qcoeff); - vst1q_s32(dqcoeff_ptr, v_dqcoeff); - - // Packed nz_qcoeff_mask. Used to find eob. - return vmovn_u32(vceqq_s32(v_abs_qcoeff, vdupq_n_s32(0))); -} - -void vp9_highbd_quantize_fp_32x32_neon( - const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *mb_plane, tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - const int16x4_t v_quant = vld1_s16(mb_plane->quant_fp); - const int16x4_t v_dequant = vld1_s16(dequant_ptr); - const int16x4_t v_zero = vdup_n_s16(0); - const int16x4_t v_round = - vqrdmulh_n_s16(vld1_s16(mb_plane->round_fp), (int16_t)(1 << 14)); - int32x4_t v_round_s32 = vaddl_s16(v_round, v_zero); - int32x4_t v_quant_s32 = vshlq_n_s32(vaddl_s16(v_quant, v_zero), 15); - int32x4_t v_dequant_s32 = vaddl_s16(v_dequant, v_zero); - uint16x4_t v_mask_lo, v_mask_hi; - int16x8_t v_eobmax = vdupq_n_s16(-1); - const int16_t *iscan = scan_order->iscan; - - // DC and first 3 AC - v_mask_lo = - highbd_quantize_fp_32x32_4(coeff_ptr, qcoeff_ptr, dqcoeff_ptr, - v_quant_s32, v_dequant_s32, v_round_s32); - - // overwrite the DC constants with AC constants - v_round_s32 = vdupq_lane_s32(vget_low_s32(v_round_s32), 1); - v_quant_s32 = vdupq_lane_s32(vget_low_s32(v_quant_s32), 1); - v_dequant_s32 = vdupq_lane_s32(vget_low_s32(v_dequant_s32), 1); - - // 4 more AC - v_mask_hi = - highbd_quantize_fp_32x32_4(coeff_ptr + 4, qcoeff_ptr + 4, dqcoeff_ptr + 4, - v_quant_s32, v_dequant_s32, v_round_s32); - - // Find the max lane eob for the first 8 coeffs. - v_eobmax = - get_max_lane_eob(iscan, v_eobmax, vcombine_u16(v_mask_lo, v_mask_hi)); - - n_coeffs -= 8; - do { - coeff_ptr += 8; - qcoeff_ptr += 8; - dqcoeff_ptr += 8; - iscan += 8; - v_mask_lo = - highbd_quantize_fp_32x32_4(coeff_ptr, qcoeff_ptr, dqcoeff_ptr, - v_quant_s32, v_dequant_s32, v_round_s32); - v_mask_hi = highbd_quantize_fp_32x32_4(coeff_ptr + 4, qcoeff_ptr + 4, - dqcoeff_ptr + 4, v_quant_s32, - v_dequant_s32, v_round_s32); - // Find the max lane eob for 8 coeffs. - v_eobmax = - get_max_lane_eob(iscan, v_eobmax, vcombine_u16(v_mask_lo, v_mask_hi)); - n_coeffs -= 8; - } while (n_coeffs); - - *eob_ptr = get_max_eob(v_eobmax); -} -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_temporal_filter_neon.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_temporal_filter_neon.c deleted file mode 100644 index a651a15d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/arm/neon/vp9_temporal_filter_neon.c +++ /dev/null @@ -1,849 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_temporal_filter.h" -#include "vp9/encoder/vp9_temporal_filter_constants.h" - -// Read in 8 pixels from a and b as 8-bit unsigned integers, compute the -// difference squared, and store as unsigned 16-bit integer to dst. -static INLINE void store_dist_8(const uint8_t *a, const uint8_t *b, - uint16_t *dst) { - const uint8x8_t a_reg = vld1_u8(a); - const uint8x8_t b_reg = vld1_u8(b); - - uint16x8_t dist_first = vabdl_u8(a_reg, b_reg); - dist_first = vmulq_u16(dist_first, dist_first); - - vst1q_u16(dst, dist_first); -} - -static INLINE void store_dist_16(const uint8_t *a, const uint8_t *b, - uint16_t *dst) { - const uint8x16_t a_reg = vld1q_u8(a); - const uint8x16_t b_reg = vld1q_u8(b); - - uint16x8_t dist_first = vabdl_u8(vget_low_u8(a_reg), vget_low_u8(b_reg)); - uint16x8_t dist_second = vabdl_u8(vget_high_u8(a_reg), vget_high_u8(b_reg)); - dist_first = vmulq_u16(dist_first, dist_first); - dist_second = vmulq_u16(dist_second, dist_second); - - vst1q_u16(dst, dist_first); - vst1q_u16(dst + 8, dist_second); -} - -static INLINE void read_dist_8(const uint16_t *dist, uint16x8_t *dist_reg) { - *dist_reg = vld1q_u16(dist); -} - -static INLINE void read_dist_16(const uint16_t *dist, uint16x8_t *reg_first, - uint16x8_t *reg_second) { - read_dist_8(dist, reg_first); - read_dist_8(dist + 8, reg_second); -} - -// Average the value based on the number of values summed (9 for pixels away -// from the border, 4 for pixels in corners, and 6 for other edge values). -// -// Add in the rounding factor and shift, clamp to 16, invert and shift. Multiply -// by weight. -static INLINE uint16x8_t average_8(uint16x8_t sum, - const uint16x8_t *mul_constants, - const int strength, const int rounding, - const uint16x8_t *weight) { - const uint32x4_t rounding_u32 = vdupq_n_u32(rounding << 16); - const uint16x8_t weight_u16 = *weight; - const uint16x8_t sixteen = vdupq_n_u16(16); - const int32x4_t strength_u32 = vdupq_n_s32(-strength - 16); - - // modifier * 3 / index; - uint32x4_t sum_hi = - vmull_u16(vget_low_u16(sum), vget_low_u16(*mul_constants)); - uint32x4_t sum_lo = - vmull_u16(vget_high_u16(sum), vget_high_u16(*mul_constants)); - - sum_lo = vqaddq_u32(sum_lo, rounding_u32); - sum_hi = vqaddq_u32(sum_hi, rounding_u32); - - // we cannot use vshrn_n_u32 as strength is not known at compile time. - sum_lo = vshlq_u32(sum_lo, strength_u32); - sum_hi = vshlq_u32(sum_hi, strength_u32); - - sum = vcombine_u16(vmovn_u32(sum_hi), vmovn_u32(sum_lo)); - - // The maximum input to this comparison is UINT16_MAX * NEIGHBOR_CONSTANT_4 - // >> 16 (also NEIGHBOR_CONSTANT_4 -1) which is 49151 / 0xbfff / -16385 - // So this needs to use the epu16 version which did not come until SSE4. - sum = vminq_u16(sum, sixteen); - sum = vsubq_u16(sixteen, sum); - return vmulq_u16(sum, weight_u16); -} - -// Add 'sum_u16' to 'count'. Multiply by 'pred' and add to 'accumulator.' -static void accumulate_and_store_8(const uint16x8_t sum_u16, - const uint8_t *pred, uint16_t *count, - uint32_t *accumulator) { - uint16x8_t pred_u16 = vmovl_u8(vld1_u8(pred)); - uint16x8_t count_u16 = vld1q_u16(count); - uint32x4_t accum_0_u32, accum_1_u32; - - count_u16 = vqaddq_u16(count_u16, sum_u16); - vst1q_u16(count, count_u16); - - accum_0_u32 = vld1q_u32(accumulator); - accum_1_u32 = vld1q_u32(accumulator + 4); - - accum_0_u32 = - vmlal_u16(accum_0_u32, vget_low_u16(sum_u16), vget_low_u16(pred_u16)); - accum_1_u32 = - vmlal_u16(accum_1_u32, vget_high_u16(sum_u16), vget_high_u16(pred_u16)); - - vst1q_u32(accumulator, accum_0_u32); - vst1q_u32(accumulator + 4, accum_1_u32); -} - -static INLINE void accumulate_and_store_16(const uint16x8_t sum_0_u16, - const uint16x8_t sum_1_u16, - const uint8_t *pred, uint16_t *count, - uint32_t *accumulator) { - uint8x16_t pred_u8 = vld1q_u8(pred); - uint16x8_t pred_0_u16 = vmovl_u8(vget_low_u8(pred_u8)); - uint16x8_t pred_1_u16 = vmovl_u8(vget_high_u8(pred_u8)); - uint16x8_t count_0_u16 = vld1q_u16(count); - uint16x8_t count_1_u16 = vld1q_u16(count + 8); - uint32x4_t accum_0_u32, accum_1_u32, accum_2_u32, accum_3_u32; - - count_0_u16 = vqaddq_u16(count_0_u16, sum_0_u16); - vst1q_u16(count, count_0_u16); - count_1_u16 = vqaddq_u16(count_1_u16, sum_1_u16); - vst1q_u16(count + 8, count_1_u16); - - accum_0_u32 = vld1q_u32(accumulator); - accum_1_u32 = vld1q_u32(accumulator + 4); - accum_2_u32 = vld1q_u32(accumulator + 8); - accum_3_u32 = vld1q_u32(accumulator + 12); - - accum_0_u32 = - vmlal_u16(accum_0_u32, vget_low_u16(sum_0_u16), vget_low_u16(pred_0_u16)); - accum_1_u32 = vmlal_u16(accum_1_u32, vget_high_u16(sum_0_u16), - vget_high_u16(pred_0_u16)); - accum_2_u32 = - vmlal_u16(accum_2_u32, vget_low_u16(sum_1_u16), vget_low_u16(pred_1_u16)); - accum_3_u32 = vmlal_u16(accum_3_u32, vget_high_u16(sum_1_u16), - vget_high_u16(pred_1_u16)); - - vst1q_u32(accumulator, accum_0_u32); - vst1q_u32(accumulator + 4, accum_1_u32); - vst1q_u32(accumulator + 8, accum_2_u32); - vst1q_u32(accumulator + 12, accum_3_u32); -} - -// Read in 8 pixels from y_dist. For each index i, compute y_dist[i-1] + -// y_dist[i] + y_dist[i+1] and store in sum as 16-bit unsigned int. -static INLINE void get_sum_8(const uint16_t *y_dist, uint16x8_t *sum) { - uint16x8_t dist_reg, dist_left, dist_right; - - dist_reg = vld1q_u16(y_dist); - dist_left = vld1q_u16(y_dist - 1); - dist_right = vld1q_u16(y_dist + 1); - - *sum = vqaddq_u16(dist_reg, dist_left); - *sum = vqaddq_u16(*sum, dist_right); -} - -// Read in 16 pixels from y_dist. For each index i, compute y_dist[i-1] + -// y_dist[i] + y_dist[i+1]. Store the result for first 8 pixels in sum_first and -// the rest in sum_second. -static INLINE void get_sum_16(const uint16_t *y_dist, uint16x8_t *sum_first, - uint16x8_t *sum_second) { - get_sum_8(y_dist, sum_first); - get_sum_8(y_dist + 8, sum_second); -} - -// Read in a row of chroma values corresponds to a row of 16 luma values. -static INLINE void read_chroma_dist_row_16(int ss_x, const uint16_t *u_dist, - const uint16_t *v_dist, - uint16x8_t *u_first, - uint16x8_t *u_second, - uint16x8_t *v_first, - uint16x8_t *v_second) { - if (!ss_x) { - // If there is no chroma subsampling in the horizontal direction, then we - // need to load 16 entries from chroma. - read_dist_16(u_dist, u_first, u_second); - read_dist_16(v_dist, v_first, v_second); - } else { // ss_x == 1 - // Otherwise, we only need to load 8 entries - uint16x8_t u_reg, v_reg; - uint16x8x2_t pair; - - read_dist_8(u_dist, &u_reg); - - pair = vzipq_u16(u_reg, u_reg); - *u_first = pair.val[0]; - *u_second = pair.val[1]; - - read_dist_8(v_dist, &v_reg); - - pair = vzipq_u16(v_reg, v_reg); - *v_first = pair.val[0]; - *v_second = pair.val[1]; - } -} - -// Add a row of luma distortion to 8 corresponding chroma mods. -static INLINE void add_luma_dist_to_8_chroma_mod(const uint16_t *y_dist, - int ss_x, int ss_y, - uint16x8_t *u_mod, - uint16x8_t *v_mod) { - uint16x8_t y_reg; - if (!ss_x) { - read_dist_8(y_dist, &y_reg); - if (ss_y == 1) { - uint16x8_t y_tmp; - read_dist_8(y_dist + DIST_STRIDE, &y_tmp); - - y_reg = vqaddq_u16(y_reg, y_tmp); - } - } else { - uint16x8_t y_first, y_second; - uint32x4_t y_first32, y_second32; - - read_dist_16(y_dist, &y_first, &y_second); - if (ss_y == 1) { - uint16x8_t y_tmp_0, y_tmp_1; - read_dist_16(y_dist + DIST_STRIDE, &y_tmp_0, &y_tmp_1); - - y_first = vqaddq_u16(y_first, y_tmp_0); - y_second = vqaddq_u16(y_second, y_tmp_1); - } - - y_first32 = vpaddlq_u16(y_first); - y_second32 = vpaddlq_u16(y_second); - - y_reg = vcombine_u16(vqmovn_u32(y_first32), vqmovn_u32(y_second32)); - } - - *u_mod = vqaddq_u16(*u_mod, y_reg); - *v_mod = vqaddq_u16(*v_mod, y_reg); -} - -// Apply temporal filter to the luma components. This performs temporal -// filtering on a luma block of 16 X block_height. Use blk_fw as an array of -// size 4 for the weights for each of the 4 subblocks if blk_fw is not NULL, -// else use top_weight for top half, and bottom weight for bottom half. -static void apply_temporal_filter_luma_16( - const uint8_t *y_pre, int y_pre_stride, unsigned int block_width, - unsigned int block_height, int ss_x, int ss_y, int strength, - int use_whole_blk, uint32_t *y_accum, uint16_t *y_count, - const uint16_t *y_dist, const uint16_t *u_dist, const uint16_t *v_dist, - const int16_t *const *neighbors_first, - const int16_t *const *neighbors_second, int top_weight, int bottom_weight, - const int *blk_fw) { - const int rounding = (1 << strength) >> 1; - uint16x8_t weight_first, weight_second; - - uint16x8_t mul_first, mul_second; - - uint16x8_t sum_row_1_first, sum_row_1_second; - uint16x8_t sum_row_2_first, sum_row_2_second; - uint16x8_t sum_row_3_first, sum_row_3_second; - - uint16x8_t u_first, u_second; - uint16x8_t v_first, v_second; - - uint16x8_t sum_row_first; - uint16x8_t sum_row_second; - - // Loop variables - unsigned int h; - - assert(strength >= 0); - assert(strength <= 6); - - assert(block_width == 16); - (void)block_width; - - // Initialize the weights - if (blk_fw) { - weight_first = vdupq_n_u16(blk_fw[0]); - weight_second = vdupq_n_u16(blk_fw[1]); - } else { - weight_first = vdupq_n_u16(top_weight); - weight_second = weight_first; - } - - // First row - mul_first = vld1q_u16((const uint16_t *)neighbors_first[0]); - mul_second = vld1q_u16((const uint16_t *)neighbors_second[0]); - - // Add luma values - get_sum_16(y_dist, &sum_row_2_first, &sum_row_2_second); - get_sum_16(y_dist + DIST_STRIDE, &sum_row_3_first, &sum_row_3_second); - - sum_row_first = vqaddq_u16(sum_row_2_first, sum_row_3_first); - sum_row_second = vqaddq_u16(sum_row_2_second, sum_row_3_second); - - // Add chroma values - read_chroma_dist_row_16(ss_x, u_dist, v_dist, &u_first, &u_second, &v_first, - &v_second); - - sum_row_first = vqaddq_u16(sum_row_first, u_first); - sum_row_second = vqaddq_u16(sum_row_second, u_second); - - sum_row_first = vqaddq_u16(sum_row_first, v_first); - sum_row_second = vqaddq_u16(sum_row_second, v_second); - - // Get modifier and store result - sum_row_first = - average_8(sum_row_first, &mul_first, strength, rounding, &weight_first); - - sum_row_second = average_8(sum_row_second, &mul_second, strength, rounding, - &weight_second); - - accumulate_and_store_16(sum_row_first, sum_row_second, y_pre, y_count, - y_accum); - - y_pre += y_pre_stride; - y_count += y_pre_stride; - y_accum += y_pre_stride; - y_dist += DIST_STRIDE; - - u_dist += DIST_STRIDE; - v_dist += DIST_STRIDE; - - // Then all the rows except the last one - mul_first = vld1q_u16((const uint16_t *)neighbors_first[1]); - mul_second = vld1q_u16((const uint16_t *)neighbors_second[1]); - - for (h = 1; h < block_height - 1; ++h) { - // Move the weight to bottom half - if (!use_whole_blk && h == block_height / 2) { - if (blk_fw) { - weight_first = vdupq_n_u16(blk_fw[2]); - weight_second = vdupq_n_u16(blk_fw[3]); - } else { - weight_first = vdupq_n_u16(bottom_weight); - weight_second = weight_first; - } - } - // Shift the rows up - sum_row_1_first = sum_row_2_first; - sum_row_1_second = sum_row_2_second; - sum_row_2_first = sum_row_3_first; - sum_row_2_second = sum_row_3_second; - - // Add luma values to the modifier - sum_row_first = vqaddq_u16(sum_row_1_first, sum_row_2_first); - sum_row_second = vqaddq_u16(sum_row_1_second, sum_row_2_second); - - get_sum_16(y_dist + DIST_STRIDE, &sum_row_3_first, &sum_row_3_second); - - sum_row_first = vqaddq_u16(sum_row_first, sum_row_3_first); - sum_row_second = vqaddq_u16(sum_row_second, sum_row_3_second); - - // Add chroma values to the modifier - if (ss_y == 0 || h % 2 == 0) { - // Only calculate the new chroma distortion if we are at a pixel that - // corresponds to a new chroma row - read_chroma_dist_row_16(ss_x, u_dist, v_dist, &u_first, &u_second, - &v_first, &v_second); - u_dist += DIST_STRIDE; - v_dist += DIST_STRIDE; - } - - sum_row_first = vqaddq_u16(sum_row_first, u_first); - sum_row_second = vqaddq_u16(sum_row_second, u_second); - sum_row_first = vqaddq_u16(sum_row_first, v_first); - sum_row_second = vqaddq_u16(sum_row_second, v_second); - - // Get modifier and store result - sum_row_first = - average_8(sum_row_first, &mul_first, strength, rounding, &weight_first); - sum_row_second = average_8(sum_row_second, &mul_second, strength, rounding, - &weight_second); - accumulate_and_store_16(sum_row_first, sum_row_second, y_pre, y_count, - y_accum); - y_pre += y_pre_stride; - y_count += y_pre_stride; - y_accum += y_pre_stride; - y_dist += DIST_STRIDE; - } - - // The last row - mul_first = vld1q_u16((const uint16_t *)neighbors_first[0]); - mul_second = vld1q_u16((const uint16_t *)neighbors_second[0]); - - // Shift the rows up - sum_row_1_first = sum_row_2_first; - sum_row_1_second = sum_row_2_second; - sum_row_2_first = sum_row_3_first; - sum_row_2_second = sum_row_3_second; - - // Add luma values to the modifier - sum_row_first = vqaddq_u16(sum_row_1_first, sum_row_2_first); - sum_row_second = vqaddq_u16(sum_row_1_second, sum_row_2_second); - - // Add chroma values to the modifier - if (ss_y == 0) { - // Only calculate the new chroma distortion if we are at a pixel that - // corresponds to a new chroma row - read_chroma_dist_row_16(ss_x, u_dist, v_dist, &u_first, &u_second, &v_first, - &v_second); - } - - sum_row_first = vqaddq_u16(sum_row_first, u_first); - sum_row_second = vqaddq_u16(sum_row_second, u_second); - sum_row_first = vqaddq_u16(sum_row_first, v_first); - sum_row_second = vqaddq_u16(sum_row_second, v_second); - - // Get modifier and store result - sum_row_first = - average_8(sum_row_first, &mul_first, strength, rounding, &weight_first); - sum_row_second = average_8(sum_row_second, &mul_second, strength, rounding, - &weight_second); - accumulate_and_store_16(sum_row_first, sum_row_second, y_pre, y_count, - y_accum); -} - -// Perform temporal filter for the luma component. -static void apply_temporal_filter_luma( - const uint8_t *y_pre, int y_pre_stride, unsigned int block_width, - unsigned int block_height, int ss_x, int ss_y, int strength, - const int *blk_fw, int use_whole_blk, uint32_t *y_accum, uint16_t *y_count, - const uint16_t *y_dist, const uint16_t *u_dist, const uint16_t *v_dist) { - unsigned int blk_col = 0, uv_blk_col = 0; - const unsigned int blk_col_step = 16, uv_blk_col_step = 16 >> ss_x; - const unsigned int mid_width = block_width >> 1, - last_width = block_width - blk_col_step; - int top_weight = blk_fw[0], - bottom_weight = use_whole_blk ? blk_fw[0] : blk_fw[2]; - const int16_t *const *neighbors_first; - const int16_t *const *neighbors_second; - - if (block_width == 16) { - // Special Case: The block width is 16 and we are operating on a row of 16 - // chroma pixels. In this case, we can't use the usual left-middle-right - // pattern. We also don't support splitting now. - neighbors_first = LUMA_LEFT_COLUMN_NEIGHBORS; - neighbors_second = LUMA_RIGHT_COLUMN_NEIGHBORS; - if (use_whole_blk) { - apply_temporal_filter_luma_16( - y_pre + blk_col, y_pre_stride, 16, block_height, ss_x, ss_y, strength, - use_whole_blk, y_accum + blk_col, y_count + blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors_first, - neighbors_second, top_weight, bottom_weight, NULL); - } else { - apply_temporal_filter_luma_16( - y_pre + blk_col, y_pre_stride, 16, block_height, ss_x, ss_y, strength, - use_whole_blk, y_accum + blk_col, y_count + blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors_first, - neighbors_second, 0, 0, blk_fw); - } - - return; - } - - // Left - neighbors_first = LUMA_LEFT_COLUMN_NEIGHBORS; - neighbors_second = LUMA_MIDDLE_COLUMN_NEIGHBORS; - apply_temporal_filter_luma_16( - y_pre + blk_col, y_pre_stride, 16, block_height, ss_x, ss_y, strength, - use_whole_blk, y_accum + blk_col, y_count + blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors_first, - neighbors_second, top_weight, bottom_weight, NULL); - - blk_col += blk_col_step; - uv_blk_col += uv_blk_col_step; - - // Middle First - neighbors_first = LUMA_MIDDLE_COLUMN_NEIGHBORS; - for (; blk_col < mid_width; - blk_col += blk_col_step, uv_blk_col += uv_blk_col_step) { - apply_temporal_filter_luma_16( - y_pre + blk_col, y_pre_stride, 16, block_height, ss_x, ss_y, strength, - use_whole_blk, y_accum + blk_col, y_count + blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors_first, - neighbors_second, top_weight, bottom_weight, NULL); - } - - if (!use_whole_blk) { - top_weight = blk_fw[1]; - bottom_weight = blk_fw[3]; - } - - // Middle Second - for (; blk_col < last_width; - blk_col += blk_col_step, uv_blk_col += uv_blk_col_step) { - apply_temporal_filter_luma_16( - y_pre + blk_col, y_pre_stride, 16, block_height, ss_x, ss_y, strength, - use_whole_blk, y_accum + blk_col, y_count + blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors_first, - neighbors_second, top_weight, bottom_weight, NULL); - } - - // Right - neighbors_second = LUMA_RIGHT_COLUMN_NEIGHBORS; - apply_temporal_filter_luma_16( - y_pre + blk_col, y_pre_stride, 16, block_height, ss_x, ss_y, strength, - use_whole_blk, y_accum + blk_col, y_count + blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors_first, - neighbors_second, top_weight, bottom_weight, NULL); -} - -// Apply temporal filter to the chroma components. This performs temporal -// filtering on a chroma block of 8 X uv_height. If blk_fw is not NULL, use -// blk_fw as an array of size 4 for the weights for each of the 4 subblocks, -// else use top_weight for top half, and bottom weight for bottom half. -static void apply_temporal_filter_chroma_8( - const uint8_t *u_pre, const uint8_t *v_pre, int uv_pre_stride, - unsigned int uv_block_height, int ss_x, int ss_y, int strength, - uint32_t *u_accum, uint16_t *u_count, uint32_t *v_accum, uint16_t *v_count, - const uint16_t *y_dist, const uint16_t *u_dist, const uint16_t *v_dist, - const int16_t *const *neighbors, int top_weight, int bottom_weight, - const int *blk_fw) { - const int rounding = (1 << strength) >> 1; - - uint16x8_t weight; - - uint16x8_t mul; - - uint16x8_t u_sum_row_1, u_sum_row_2, u_sum_row_3; - uint16x8_t v_sum_row_1, v_sum_row_2, v_sum_row_3; - - uint16x8_t u_sum_row, v_sum_row; - - // Loop variable - unsigned int h; - - // Initialize weight - if (blk_fw) { - weight = vcombine_u16(vdup_n_u16(blk_fw[0]), vdup_n_u16(blk_fw[1])); - } else { - weight = vdupq_n_u16(top_weight); - } - - // First row - mul = vld1q_u16((const uint16_t *)neighbors[0]); - - // Add chroma values - get_sum_8(u_dist, &u_sum_row_2); - get_sum_8(u_dist + DIST_STRIDE, &u_sum_row_3); - - u_sum_row = vqaddq_u16(u_sum_row_2, u_sum_row_3); - - get_sum_8(v_dist, &v_sum_row_2); - get_sum_8(v_dist + DIST_STRIDE, &v_sum_row_3); - - v_sum_row = vqaddq_u16(v_sum_row_2, v_sum_row_3); - - // Add luma values - add_luma_dist_to_8_chroma_mod(y_dist, ss_x, ss_y, &u_sum_row, &v_sum_row); - - // Get modifier and store result - u_sum_row = average_8(u_sum_row, &mul, strength, rounding, &weight); - v_sum_row = average_8(v_sum_row, &mul, strength, rounding, &weight); - - accumulate_and_store_8(u_sum_row, u_pre, u_count, u_accum); - accumulate_and_store_8(v_sum_row, v_pre, v_count, v_accum); - - u_pre += uv_pre_stride; - u_dist += DIST_STRIDE; - v_pre += uv_pre_stride; - v_dist += DIST_STRIDE; - u_count += uv_pre_stride; - u_accum += uv_pre_stride; - v_count += uv_pre_stride; - v_accum += uv_pre_stride; - - y_dist += DIST_STRIDE * (1 + ss_y); - - // Then all the rows except the last one - mul = vld1q_u16((const uint16_t *)neighbors[1]); - - for (h = 1; h < uv_block_height - 1; ++h) { - // Move the weight pointer to the bottom half of the blocks - if (h == uv_block_height / 2) { - if (blk_fw) { - weight = vcombine_u16(vdup_n_u16(blk_fw[2]), vdup_n_u16(blk_fw[3])); - } else { - weight = vdupq_n_u16(bottom_weight); - } - } - - // Shift the rows up - u_sum_row_1 = u_sum_row_2; - u_sum_row_2 = u_sum_row_3; - - v_sum_row_1 = v_sum_row_2; - v_sum_row_2 = v_sum_row_3; - - // Add chroma values - u_sum_row = vqaddq_u16(u_sum_row_1, u_sum_row_2); - get_sum_8(u_dist + DIST_STRIDE, &u_sum_row_3); - u_sum_row = vqaddq_u16(u_sum_row, u_sum_row_3); - - v_sum_row = vqaddq_u16(v_sum_row_1, v_sum_row_2); - get_sum_8(v_dist + DIST_STRIDE, &v_sum_row_3); - v_sum_row = vqaddq_u16(v_sum_row, v_sum_row_3); - - // Add luma values - add_luma_dist_to_8_chroma_mod(y_dist, ss_x, ss_y, &u_sum_row, &v_sum_row); - - // Get modifier and store result - u_sum_row = average_8(u_sum_row, &mul, strength, rounding, &weight); - v_sum_row = average_8(v_sum_row, &mul, strength, rounding, &weight); - - accumulate_and_store_8(u_sum_row, u_pre, u_count, u_accum); - accumulate_and_store_8(v_sum_row, v_pre, v_count, v_accum); - - u_pre += uv_pre_stride; - u_dist += DIST_STRIDE; - v_pre += uv_pre_stride; - v_dist += DIST_STRIDE; - u_count += uv_pre_stride; - u_accum += uv_pre_stride; - v_count += uv_pre_stride; - v_accum += uv_pre_stride; - - y_dist += DIST_STRIDE * (1 + ss_y); - } - - // The last row - mul = vld1q_u16((const uint16_t *)neighbors[0]); - - // Shift the rows up - u_sum_row_1 = u_sum_row_2; - u_sum_row_2 = u_sum_row_3; - - v_sum_row_1 = v_sum_row_2; - v_sum_row_2 = v_sum_row_3; - - // Add chroma values - u_sum_row = vqaddq_u16(u_sum_row_1, u_sum_row_2); - v_sum_row = vqaddq_u16(v_sum_row_1, v_sum_row_2); - - // Add luma values - add_luma_dist_to_8_chroma_mod(y_dist, ss_x, ss_y, &u_sum_row, &v_sum_row); - - // Get modifier and store result - u_sum_row = average_8(u_sum_row, &mul, strength, rounding, &weight); - v_sum_row = average_8(v_sum_row, &mul, strength, rounding, &weight); - - accumulate_and_store_8(u_sum_row, u_pre, u_count, u_accum); - accumulate_and_store_8(v_sum_row, v_pre, v_count, v_accum); -} - -// Perform temporal filter for the chroma components. -static void apply_temporal_filter_chroma( - const uint8_t *u_pre, const uint8_t *v_pre, int uv_pre_stride, - unsigned int block_width, unsigned int block_height, int ss_x, int ss_y, - int strength, const int *blk_fw, int use_whole_blk, uint32_t *u_accum, - uint16_t *u_count, uint32_t *v_accum, uint16_t *v_count, - const uint16_t *y_dist, const uint16_t *u_dist, const uint16_t *v_dist) { - const unsigned int uv_width = block_width >> ss_x, - uv_height = block_height >> ss_y; - - unsigned int blk_col = 0, uv_blk_col = 0; - const unsigned int uv_blk_col_step = 8, blk_col_step = 8 << ss_x; - const unsigned int uv_mid_width = uv_width >> 1, - uv_last_width = uv_width - uv_blk_col_step; - int top_weight = blk_fw[0], - bottom_weight = use_whole_blk ? blk_fw[0] : blk_fw[2]; - const int16_t *const *neighbors; - - if (uv_width == 8) { - // Special Case: We are subsampling in x direction on a 16x16 block. Since - // we are operating on a row of 8 chroma pixels, we can't use the usual - // left-middle-right pattern. - assert(ss_x); - - if (ss_y) { - neighbors = CHROMA_DOUBLE_SS_SINGLE_COLUMN_NEIGHBORS; - } else { - neighbors = CHROMA_SINGLE_SS_SINGLE_COLUMN_NEIGHBORS; - } - - if (use_whole_blk) { - apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_height, - ss_x, ss_y, strength, u_accum + uv_blk_col, u_count + uv_blk_col, - v_accum + uv_blk_col, v_count + uv_blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors, top_weight, - bottom_weight, NULL); - } else { - apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_height, - ss_x, ss_y, strength, u_accum + uv_blk_col, u_count + uv_blk_col, - v_accum + uv_blk_col, v_count + uv_blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors, 0, 0, blk_fw); - } - - return; - } - - // Left - if (ss_x && ss_y) { - neighbors = CHROMA_DOUBLE_SS_LEFT_COLUMN_NEIGHBORS; - } else if (ss_x || ss_y) { - neighbors = CHROMA_SINGLE_SS_LEFT_COLUMN_NEIGHBORS; - } else { - neighbors = CHROMA_NO_SS_LEFT_COLUMN_NEIGHBORS; - } - - apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_height, ss_x, - ss_y, strength, u_accum + uv_blk_col, u_count + uv_blk_col, - v_accum + uv_blk_col, v_count + uv_blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors, top_weight, - bottom_weight, NULL); - - blk_col += blk_col_step; - uv_blk_col += uv_blk_col_step; - - // Middle First - if (ss_x && ss_y) { - neighbors = CHROMA_DOUBLE_SS_MIDDLE_COLUMN_NEIGHBORS; - } else if (ss_x || ss_y) { - neighbors = CHROMA_SINGLE_SS_MIDDLE_COLUMN_NEIGHBORS; - } else { - neighbors = CHROMA_NO_SS_MIDDLE_COLUMN_NEIGHBORS; - } - - for (; uv_blk_col < uv_mid_width; - blk_col += blk_col_step, uv_blk_col += uv_blk_col_step) { - apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_height, ss_x, - ss_y, strength, u_accum + uv_blk_col, u_count + uv_blk_col, - v_accum + uv_blk_col, v_count + uv_blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors, top_weight, - bottom_weight, NULL); - } - - if (!use_whole_blk) { - top_weight = blk_fw[1]; - bottom_weight = blk_fw[3]; - } - - // Middle Second - for (; uv_blk_col < uv_last_width; - blk_col += blk_col_step, uv_blk_col += uv_blk_col_step) { - apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_height, ss_x, - ss_y, strength, u_accum + uv_blk_col, u_count + uv_blk_col, - v_accum + uv_blk_col, v_count + uv_blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors, top_weight, - bottom_weight, NULL); - } - - // Right - if (ss_x && ss_y) { - neighbors = CHROMA_DOUBLE_SS_RIGHT_COLUMN_NEIGHBORS; - } else if (ss_x || ss_y) { - neighbors = CHROMA_SINGLE_SS_RIGHT_COLUMN_NEIGHBORS; - } else { - neighbors = CHROMA_NO_SS_RIGHT_COLUMN_NEIGHBORS; - } - - apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_height, ss_x, - ss_y, strength, u_accum + uv_blk_col, u_count + uv_blk_col, - v_accum + uv_blk_col, v_count + uv_blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors, top_weight, - bottom_weight, NULL); -} - -void vp9_apply_temporal_filter_neon( - const uint8_t *y_src, int y_src_stride, const uint8_t *y_pre, - int y_pre_stride, const uint8_t *u_src, const uint8_t *v_src, - int uv_src_stride, const uint8_t *u_pre, const uint8_t *v_pre, - int uv_pre_stride, unsigned int block_width, unsigned int block_height, - int ss_x, int ss_y, int strength, const int *const blk_fw, - int use_whole_blk, uint32_t *y_accum, uint16_t *y_count, uint32_t *u_accum, - uint16_t *u_count, uint32_t *v_accum, uint16_t *v_count) { - const unsigned int chroma_height = block_height >> ss_y, - chroma_width = block_width >> ss_x; - - DECLARE_ALIGNED(16, uint16_t, y_dist[BH * DIST_STRIDE]) = { 0 }; - DECLARE_ALIGNED(16, uint16_t, u_dist[BH * DIST_STRIDE]) = { 0 }; - DECLARE_ALIGNED(16, uint16_t, v_dist[BH * DIST_STRIDE]) = { 0 }; - const int *blk_fw_ptr = blk_fw; - - uint16_t *y_dist_ptr = y_dist + 1, *u_dist_ptr = u_dist + 1, - *v_dist_ptr = v_dist + 1; - const uint8_t *y_src_ptr = y_src, *u_src_ptr = u_src, *v_src_ptr = v_src; - const uint8_t *y_pre_ptr = y_pre, *u_pre_ptr = u_pre, *v_pre_ptr = v_pre; - - // Loop variables - unsigned int row, blk_col; - - assert(block_width <= BW && "block width too large"); - assert(block_height <= BH && "block height too large"); - assert(block_width % 16 == 0 && "block width must be multiple of 16"); - assert(block_height % 2 == 0 && "block height must be even"); - assert((ss_x == 0 || ss_x == 1) && (ss_y == 0 || ss_y == 1) && - "invalid chroma subsampling"); - assert(strength >= 0 && strength <= 6 && "invalid temporal filter strength"); - assert(blk_fw[0] >= 0 && "filter weight must be positive"); - assert( - (use_whole_blk || (blk_fw[1] >= 0 && blk_fw[2] >= 0 && blk_fw[3] >= 0)) && - "subblock filter weight must be positive"); - assert(blk_fw[0] <= 2 && "subblock filter weight must be less than 2"); - assert( - (use_whole_blk || (blk_fw[1] <= 2 && blk_fw[2] <= 2 && blk_fw[3] <= 2)) && - "subblock filter weight must be less than 2"); - - // Precompute the difference squared - for (row = 0; row < block_height; row++) { - for (blk_col = 0; blk_col < block_width; blk_col += 16) { - store_dist_16(y_src_ptr + blk_col, y_pre_ptr + blk_col, - y_dist_ptr + blk_col); - } - y_src_ptr += y_src_stride; - y_pre_ptr += y_pre_stride; - y_dist_ptr += DIST_STRIDE; - } - - for (row = 0; row < chroma_height; row++) { - for (blk_col = 0; blk_col < chroma_width; blk_col += 8) { - store_dist_8(u_src_ptr + blk_col, u_pre_ptr + blk_col, - u_dist_ptr + blk_col); - store_dist_8(v_src_ptr + blk_col, v_pre_ptr + blk_col, - v_dist_ptr + blk_col); - } - - u_src_ptr += uv_src_stride; - u_pre_ptr += uv_pre_stride; - u_dist_ptr += DIST_STRIDE; - v_src_ptr += uv_src_stride; - v_pre_ptr += uv_pre_stride; - v_dist_ptr += DIST_STRIDE; - } - - y_dist_ptr = y_dist + 1; - u_dist_ptr = u_dist + 1; - v_dist_ptr = v_dist + 1; - - apply_temporal_filter_luma(y_pre, y_pre_stride, block_width, block_height, - ss_x, ss_y, strength, blk_fw_ptr, use_whole_blk, - y_accum, y_count, y_dist_ptr, u_dist_ptr, - v_dist_ptr); - - apply_temporal_filter_chroma(u_pre, v_pre, uv_pre_stride, block_width, - block_height, ss_x, ss_y, strength, blk_fw_ptr, - use_whole_blk, u_accum, u_count, v_accum, - v_count, y_dist_ptr, u_dist_ptr, v_dist_ptr); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/mips/msa/vp9_error_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/mips/msa/vp9_error_msa.c deleted file mode 100644 index 61786d8f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/mips/msa/vp9_error_msa.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "./vp9_rtcd.h" -#include "vpx_dsp/mips/macros_msa.h" - -#define BLOCK_ERROR_BLOCKSIZE_MSA(BSize) \ - static int64_t block_error_##BSize##size_msa( \ - const int16_t *coeff_ptr, const int16_t *dq_coeff_ptr, int64_t *ssz) { \ - int64_t err = 0; \ - uint32_t loop_cnt; \ - v8i16 coeff, dq_coeff, coeff_r_h, coeff_l_h; \ - v4i32 diff_r, diff_l, coeff_r_w, coeff_l_w; \ - v2i64 sq_coeff_r, sq_coeff_l; \ - v2i64 err0, err_dup0, err1, err_dup1; \ - \ - coeff = LD_SH(coeff_ptr); \ - dq_coeff = LD_SH(dq_coeff_ptr); \ - UNPCK_SH_SW(coeff, coeff_r_w, coeff_l_w); \ - ILVRL_H2_SH(coeff, dq_coeff, coeff_r_h, coeff_l_h); \ - HSUB_UH2_SW(coeff_r_h, coeff_l_h, diff_r, diff_l); \ - DOTP_SW2_SD(coeff_r_w, coeff_l_w, coeff_r_w, coeff_l_w, sq_coeff_r, \ - sq_coeff_l); \ - DOTP_SW2_SD(diff_r, diff_l, diff_r, diff_l, err0, err1); \ - \ - coeff = LD_SH(coeff_ptr + 8); \ - dq_coeff = LD_SH(dq_coeff_ptr + 8); \ - UNPCK_SH_SW(coeff, coeff_r_w, coeff_l_w); \ - ILVRL_H2_SH(coeff, dq_coeff, coeff_r_h, coeff_l_h); \ - HSUB_UH2_SW(coeff_r_h, coeff_l_h, diff_r, diff_l); \ - DPADD_SD2_SD(coeff_r_w, coeff_l_w, sq_coeff_r, sq_coeff_l); \ - DPADD_SD2_SD(diff_r, diff_l, err0, err1); \ - \ - coeff_ptr += 16; \ - dq_coeff_ptr += 16; \ - \ - for (loop_cnt = ((BSize >> 4) - 1); loop_cnt--;) { \ - coeff = LD_SH(coeff_ptr); \ - dq_coeff = LD_SH(dq_coeff_ptr); \ - UNPCK_SH_SW(coeff, coeff_r_w, coeff_l_w); \ - ILVRL_H2_SH(coeff, dq_coeff, coeff_r_h, coeff_l_h); \ - HSUB_UH2_SW(coeff_r_h, coeff_l_h, diff_r, diff_l); \ - DPADD_SD2_SD(coeff_r_w, coeff_l_w, sq_coeff_r, sq_coeff_l); \ - DPADD_SD2_SD(diff_r, diff_l, err0, err1); \ - \ - coeff = LD_SH(coeff_ptr + 8); \ - dq_coeff = LD_SH(dq_coeff_ptr + 8); \ - UNPCK_SH_SW(coeff, coeff_r_w, coeff_l_w); \ - ILVRL_H2_SH(coeff, dq_coeff, coeff_r_h, coeff_l_h); \ - HSUB_UH2_SW(coeff_r_h, coeff_l_h, diff_r, diff_l); \ - DPADD_SD2_SD(coeff_r_w, coeff_l_w, sq_coeff_r, sq_coeff_l); \ - DPADD_SD2_SD(diff_r, diff_l, err0, err1); \ - \ - coeff_ptr += 16; \ - dq_coeff_ptr += 16; \ - } \ - \ - err_dup0 = __msa_splati_d(sq_coeff_r, 1); \ - err_dup1 = __msa_splati_d(sq_coeff_l, 1); \ - sq_coeff_r += err_dup0; \ - sq_coeff_l += err_dup1; \ - *ssz = __msa_copy_s_d(sq_coeff_r, 0); \ - *ssz += __msa_copy_s_d(sq_coeff_l, 0); \ - \ - err_dup0 = __msa_splati_d(err0, 1); \ - err_dup1 = __msa_splati_d(err1, 1); \ - err0 += err_dup0; \ - err1 += err_dup1; \ - err = __msa_copy_s_d(err0, 0); \ - err += __msa_copy_s_d(err1, 0); \ - \ - return err; \ - } - -#if !CONFIG_VP9_HIGHBITDEPTH -BLOCK_ERROR_BLOCKSIZE_MSA(16); -BLOCK_ERROR_BLOCKSIZE_MSA(64); -BLOCK_ERROR_BLOCKSIZE_MSA(256); -BLOCK_ERROR_BLOCKSIZE_MSA(1024); - -int64_t vp9_block_error_msa(const tran_low_t *coeff_ptr, - const tran_low_t *dq_coeff_ptr, intptr_t blk_size, - int64_t *ssz) { - int64_t err; - const int16_t *coeff = (const int16_t *)coeff_ptr; - const int16_t *dq_coeff = (const int16_t *)dq_coeff_ptr; - - switch (blk_size) { - case 16: err = block_error_16size_msa(coeff, dq_coeff, ssz); break; - case 64: err = block_error_64size_msa(coeff, dq_coeff, ssz); break; - case 256: err = block_error_256size_msa(coeff, dq_coeff, ssz); break; - case 1024: err = block_error_1024size_msa(coeff, dq_coeff, ssz); break; - default: - err = vp9_block_error_c(coeff_ptr, dq_coeff_ptr, blk_size, ssz); - break; - } - - return err; -} -#endif // !CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/mips/msa/vp9_fdct16x16_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/mips/msa/vp9_fdct16x16_msa.c deleted file mode 100644 index efbbe830..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/mips/msa/vp9_fdct16x16_msa.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp9_rtcd.h" -#include "vp9/common/vp9_enums.h" -#include "vp9/encoder/mips/msa/vp9_fdct_msa.h" -#include "vpx_dsp/mips/fwd_txfm_msa.h" - -static void fadst16_cols_step1_msa(const int16_t *input, int32_t stride, - const int32_t *const0, int16_t *int_buf) { - v8i16 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15; - v8i16 tp0, tp1, tp2, tp3, g0, g1, g2, g3, g8, g9, g10, g11, h0, h1, h2, h3; - v4i32 k0, k1, k2, k3; - - /* load input data */ - r0 = LD_SH(input); - r15 = LD_SH(input + 15 * stride); - r7 = LD_SH(input + 7 * stride); - r8 = LD_SH(input + 8 * stride); - SLLI_4V(r0, r15, r7, r8, 2); - - /* stage 1 */ - LD_SW2(const0, 4, k0, k1); - LD_SW2(const0 + 8, 4, k2, k3); - MADD_BF(r15, r0, r7, r8, k0, k1, k2, k3, g0, g1, g2, g3); - - r3 = LD_SH(input + 3 * stride); - r4 = LD_SH(input + 4 * stride); - r11 = LD_SH(input + 11 * stride); - r12 = LD_SH(input + 12 * stride); - SLLI_4V(r3, r4, r11, r12, 2); - - LD_SW2(const0 + 4 * 4, 4, k0, k1); - LD_SW2(const0 + 4 * 6, 4, k2, k3); - MADD_BF(r11, r4, r3, r12, k0, k1, k2, k3, g8, g9, g10, g11); - - /* stage 2 */ - BUTTERFLY_4(g0, g2, g10, g8, tp0, tp2, tp3, tp1); - ST_SH2(tp0, tp2, int_buf, 8); - ST_SH2(tp1, tp3, int_buf + 4 * 8, 8); - - LD_SW2(const0 + 4 * 8, 4, k0, k1); - k2 = LD_SW(const0 + 4 * 10); - MADD_BF(g1, g3, g9, g11, k0, k1, k2, k0, h0, h1, h2, h3); - - ST_SH2(h0, h1, int_buf + 8 * 8, 8); - ST_SH2(h3, h2, int_buf + 12 * 8, 8); - - r9 = LD_SH(input + 9 * stride); - r6 = LD_SH(input + 6 * stride); - r1 = LD_SH(input + stride); - r14 = LD_SH(input + 14 * stride); - SLLI_4V(r9, r6, r1, r14, 2); - - LD_SW2(const0 + 4 * 11, 4, k0, k1); - LD_SW2(const0 + 4 * 13, 4, k2, k3); - MADD_BF(r9, r6, r1, r14, k0, k1, k2, k3, g0, g1, g2, g3); - - ST_SH2(g1, g3, int_buf + 3 * 8, 4 * 8); - - r13 = LD_SH(input + 13 * stride); - r2 = LD_SH(input + 2 * stride); - r5 = LD_SH(input + 5 * stride); - r10 = LD_SH(input + 10 * stride); - SLLI_4V(r13, r2, r5, r10, 2); - - LD_SW2(const0 + 4 * 15, 4, k0, k1); - LD_SW2(const0 + 4 * 17, 4, k2, k3); - MADD_BF(r13, r2, r5, r10, k0, k1, k2, k3, h0, h1, h2, h3); - - ST_SH2(h1, h3, int_buf + 11 * 8, 4 * 8); - - BUTTERFLY_4(h0, h2, g2, g0, tp0, tp1, tp2, tp3); - ST_SH4(tp0, tp1, tp2, tp3, int_buf + 2 * 8, 4 * 8); -} - -static void fadst16_cols_step2_msa(int16_t *int_buf, const int32_t *const0, - int16_t *out) { - int16_t *out_ptr = out + 128; - v8i16 tp0, tp1, tp2, tp3, g5, g7, g13, g15; - v8i16 h0, h1, h2, h3, h4, h5, h6, h7, h10, h11; - v8i16 out0, out1, out2, out3, out4, out5, out6, out7; - v8i16 out8, out9, out10, out11, out12, out13, out14, out15; - v4i32 k0, k1, k2, k3; - - LD_SH2(int_buf + 3 * 8, 4 * 8, g13, g15); - LD_SH2(int_buf + 11 * 8, 4 * 8, g5, g7); - LD_SW2(const0 + 4 * 19, 4, k0, k1); - k2 = LD_SW(const0 + 4 * 21); - MADD_BF(g7, g5, g15, g13, k0, k1, k2, k0, h4, h5, h6, h7); - - tp0 = LD_SH(int_buf + 4 * 8); - tp1 = LD_SH(int_buf + 5 * 8); - tp3 = LD_SH(int_buf + 10 * 8); - tp2 = LD_SH(int_buf + 14 * 8); - LD_SW2(const0 + 4 * 22, 4, k0, k1); - k2 = LD_SW(const0 + 4 * 24); - MADD_BF(tp0, tp1, tp2, tp3, k0, k1, k2, k0, out4, out6, out5, out7); - out4 = -out4; - ST_SH(out4, (out + 3 * 16)); - ST_SH(out5, (out_ptr + 4 * 16)); - - h1 = LD_SH(int_buf + 9 * 8); - h3 = LD_SH(int_buf + 12 * 8); - MADD_BF(h1, h3, h5, h7, k0, k1, k2, k0, out12, out14, out13, out15); - out13 = -out13; - ST_SH(out12, (out + 2 * 16)); - ST_SH(out13, (out_ptr + 5 * 16)); - - tp0 = LD_SH(int_buf); - tp1 = LD_SH(int_buf + 8); - tp2 = LD_SH(int_buf + 2 * 8); - tp3 = LD_SH(int_buf + 6 * 8); - - BUTTERFLY_4(tp0, tp1, tp3, tp2, out0, out1, h11, h10); - out1 = -out1; - ST_SH(out0, (out)); - ST_SH(out1, (out_ptr + 7 * 16)); - - h0 = LD_SH(int_buf + 8 * 8); - h2 = LD_SH(int_buf + 13 * 8); - - BUTTERFLY_4(h0, h2, h6, h4, out8, out9, out11, out10); - out8 = -out8; - ST_SH(out8, (out + 16)); - ST_SH(out9, (out_ptr + 6 * 16)); - - /* stage 4 */ - LD_SW2(const0 + 4 * 25, 4, k0, k1); - LD_SW2(const0 + 4 * 27, 4, k2, k3); - MADD_SHORT(h10, h11, k1, k2, out2, out3); - ST_SH(out2, (out + 7 * 16)); - ST_SH(out3, (out_ptr)); - - MADD_SHORT(out6, out7, k0, k3, out6, out7); - ST_SH(out6, (out + 4 * 16)); - ST_SH(out7, (out_ptr + 3 * 16)); - - MADD_SHORT(out10, out11, k0, k3, out10, out11); - ST_SH(out10, (out + 6 * 16)); - ST_SH(out11, (out_ptr + 16)); - - MADD_SHORT(out14, out15, k1, k2, out14, out15); - ST_SH(out14, (out + 5 * 16)); - ST_SH(out15, (out_ptr + 2 * 16)); -} - -static void fadst16_transpose_postproc_msa(int16_t *input, int16_t *out) { - v8i16 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15; - v8i16 l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15; - - /* load input data */ - LD_SH8(input, 16, l0, l1, l2, l3, l4, l5, l6, l7); - TRANSPOSE8x8_SH_SH(l0, l1, l2, l3, l4, l5, l6, l7, r0, r1, r2, r3, r4, r5, r6, - r7); - FDCT_POSTPROC_2V_NEG_H(r0, r1); - FDCT_POSTPROC_2V_NEG_H(r2, r3); - FDCT_POSTPROC_2V_NEG_H(r4, r5); - FDCT_POSTPROC_2V_NEG_H(r6, r7); - ST_SH8(r0, r1, r2, r3, r4, r5, r6, r7, out, 8); - out += 64; - - LD_SH8(input + 8, 16, l8, l9, l10, l11, l12, l13, l14, l15); - TRANSPOSE8x8_SH_SH(l8, l9, l10, l11, l12, l13, l14, l15, r8, r9, r10, r11, - r12, r13, r14, r15); - FDCT_POSTPROC_2V_NEG_H(r8, r9); - FDCT_POSTPROC_2V_NEG_H(r10, r11); - FDCT_POSTPROC_2V_NEG_H(r12, r13); - FDCT_POSTPROC_2V_NEG_H(r14, r15); - ST_SH8(r8, r9, r10, r11, r12, r13, r14, r15, out, 8); - out += 64; - - /* load input data */ - input += 128; - LD_SH8(input, 16, l0, l1, l2, l3, l4, l5, l6, l7); - TRANSPOSE8x8_SH_SH(l0, l1, l2, l3, l4, l5, l6, l7, r0, r1, r2, r3, r4, r5, r6, - r7); - FDCT_POSTPROC_2V_NEG_H(r0, r1); - FDCT_POSTPROC_2V_NEG_H(r2, r3); - FDCT_POSTPROC_2V_NEG_H(r4, r5); - FDCT_POSTPROC_2V_NEG_H(r6, r7); - ST_SH8(r0, r1, r2, r3, r4, r5, r6, r7, out, 8); - out += 64; - - LD_SH8(input + 8, 16, l8, l9, l10, l11, l12, l13, l14, l15); - TRANSPOSE8x8_SH_SH(l8, l9, l10, l11, l12, l13, l14, l15, r8, r9, r10, r11, - r12, r13, r14, r15); - FDCT_POSTPROC_2V_NEG_H(r8, r9); - FDCT_POSTPROC_2V_NEG_H(r10, r11); - FDCT_POSTPROC_2V_NEG_H(r12, r13); - FDCT_POSTPROC_2V_NEG_H(r14, r15); - ST_SH8(r8, r9, r10, r11, r12, r13, r14, r15, out, 8); -} - -static void fadst16_rows_step1_msa(int16_t *input, const int32_t *const0, - int16_t *int_buf) { - v8i16 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15; - v8i16 tp0, tp1, tp2, tp3, g0, g1, g2, g3, g8, g9, g10, g11, h0, h1, h2, h3; - v4i32 k0, k1, k2, k3; - - /* load input data */ - r0 = LD_SH(input); - r7 = LD_SH(input + 7 * 8); - r8 = LD_SH(input + 8 * 8); - r15 = LD_SH(input + 15 * 8); - - /* stage 1 */ - LD_SW2(const0, 4, k0, k1); - LD_SW2(const0 + 4 * 2, 4, k2, k3); - MADD_BF(r15, r0, r7, r8, k0, k1, k2, k3, g0, g1, g2, g3); - - r3 = LD_SH(input + 3 * 8); - r4 = LD_SH(input + 4 * 8); - r11 = LD_SH(input + 11 * 8); - r12 = LD_SH(input + 12 * 8); - - LD_SW2(const0 + 4 * 4, 4, k0, k1); - LD_SW2(const0 + 4 * 6, 4, k2, k3); - MADD_BF(r11, r4, r3, r12, k0, k1, k2, k3, g8, g9, g10, g11); - - /* stage 2 */ - BUTTERFLY_4(g0, g2, g10, g8, tp0, tp2, tp3, tp1); - ST_SH2(tp0, tp1, int_buf, 4 * 8); - ST_SH2(tp2, tp3, int_buf + 8, 4 * 8); - - LD_SW2(const0 + 4 * 8, 4, k0, k1); - k2 = LD_SW(const0 + 4 * 10); - MADD_BF(g1, g3, g9, g11, k0, k1, k2, k0, h0, h1, h2, h3); - ST_SH2(h0, h3, int_buf + 8 * 8, 4 * 8); - ST_SH2(h1, h2, int_buf + 9 * 8, 4 * 8); - - r1 = LD_SH(input + 8); - r6 = LD_SH(input + 6 * 8); - r9 = LD_SH(input + 9 * 8); - r14 = LD_SH(input + 14 * 8); - - LD_SW2(const0 + 4 * 11, 4, k0, k1); - LD_SW2(const0 + 4 * 13, 4, k2, k3); - MADD_BF(r9, r6, r1, r14, k0, k1, k2, k3, g0, g1, g2, g3); - ST_SH2(g1, g3, int_buf + 3 * 8, 4 * 8); - - r2 = LD_SH(input + 2 * 8); - r5 = LD_SH(input + 5 * 8); - r10 = LD_SH(input + 10 * 8); - r13 = LD_SH(input + 13 * 8); - - LD_SW2(const0 + 4 * 15, 4, k0, k1); - LD_SW2(const0 + 4 * 17, 4, k2, k3); - MADD_BF(r13, r2, r5, r10, k0, k1, k2, k3, h0, h1, h2, h3); - ST_SH2(h1, h3, int_buf + 11 * 8, 4 * 8); - BUTTERFLY_4(h0, h2, g2, g0, tp0, tp1, tp2, tp3); - ST_SH4(tp0, tp1, tp2, tp3, int_buf + 2 * 8, 4 * 8); -} - -static void fadst16_rows_step2_msa(int16_t *int_buf, const int32_t *const0, - int16_t *out) { - int16_t *out_ptr = out + 8; - v8i16 tp0, tp1, tp2, tp3, g5, g7, g13, g15; - v8i16 h0, h1, h2, h3, h4, h5, h6, h7, h10, h11; - v8i16 out0, out1, out2, out3, out4, out5, out6, out7; - v8i16 out8, out9, out10, out11, out12, out13, out14, out15; - v4i32 k0, k1, k2, k3; - - g13 = LD_SH(int_buf + 3 * 8); - g15 = LD_SH(int_buf + 7 * 8); - g5 = LD_SH(int_buf + 11 * 8); - g7 = LD_SH(int_buf + 15 * 8); - - LD_SW2(const0 + 4 * 19, 4, k0, k1); - k2 = LD_SW(const0 + 4 * 21); - MADD_BF(g7, g5, g15, g13, k0, k1, k2, k0, h4, h5, h6, h7); - - tp0 = LD_SH(int_buf + 4 * 8); - tp1 = LD_SH(int_buf + 5 * 8); - tp3 = LD_SH(int_buf + 10 * 8); - tp2 = LD_SH(int_buf + 14 * 8); - - LD_SW2(const0 + 4 * 22, 4, k0, k1); - k2 = LD_SW(const0 + 4 * 24); - MADD_BF(tp0, tp1, tp2, tp3, k0, k1, k2, k0, out4, out6, out5, out7); - out4 = -out4; - ST_SH(out4, (out + 3 * 16)); - ST_SH(out5, (out_ptr + 4 * 16)); - - h1 = LD_SH(int_buf + 9 * 8); - h3 = LD_SH(int_buf + 12 * 8); - MADD_BF(h1, h3, h5, h7, k0, k1, k2, k0, out12, out14, out13, out15); - out13 = -out13; - ST_SH(out12, (out + 2 * 16)); - ST_SH(out13, (out_ptr + 5 * 16)); - - tp0 = LD_SH(int_buf); - tp1 = LD_SH(int_buf + 8); - tp2 = LD_SH(int_buf + 2 * 8); - tp3 = LD_SH(int_buf + 6 * 8); - - BUTTERFLY_4(tp0, tp1, tp3, tp2, out0, out1, h11, h10); - out1 = -out1; - ST_SH(out0, (out)); - ST_SH(out1, (out_ptr + 7 * 16)); - - h0 = LD_SH(int_buf + 8 * 8); - h2 = LD_SH(int_buf + 13 * 8); - BUTTERFLY_4(h0, h2, h6, h4, out8, out9, out11, out10); - out8 = -out8; - ST_SH(out8, (out + 16)); - ST_SH(out9, (out_ptr + 6 * 16)); - - /* stage 4 */ - LD_SW2(const0 + 4 * 25, 4, k0, k1); - LD_SW2(const0 + 4 * 27, 4, k2, k3); - MADD_SHORT(h10, h11, k1, k2, out2, out3); - ST_SH(out2, (out + 7 * 16)); - ST_SH(out3, (out_ptr)); - - MADD_SHORT(out6, out7, k0, k3, out6, out7); - ST_SH(out6, (out + 4 * 16)); - ST_SH(out7, (out_ptr + 3 * 16)); - - MADD_SHORT(out10, out11, k0, k3, out10, out11); - ST_SH(out10, (out + 6 * 16)); - ST_SH(out11, (out_ptr + 16)); - - MADD_SHORT(out14, out15, k1, k2, out14, out15); - ST_SH(out14, (out + 5 * 16)); - ST_SH(out15, (out_ptr + 2 * 16)); -} - -static void fadst16_transpose_msa(int16_t *input, int16_t *out) { - v8i16 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15; - v8i16 l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15; - - /* load input data */ - LD_SH16(input, 8, l0, l8, l1, l9, l2, l10, l3, l11, l4, l12, l5, l13, l6, l14, - l7, l15); - TRANSPOSE8x8_SH_SH(l0, l1, l2, l3, l4, l5, l6, l7, r0, r1, r2, r3, r4, r5, r6, - r7); - TRANSPOSE8x8_SH_SH(l8, l9, l10, l11, l12, l13, l14, l15, r8, r9, r10, r11, - r12, r13, r14, r15); - ST_SH8(r0, r8, r1, r9, r2, r10, r3, r11, out, 8); - ST_SH8(r4, r12, r5, r13, r6, r14, r7, r15, (out + 64), 8); - out += 16 * 8; - - /* load input data */ - input += 128; - LD_SH16(input, 8, l0, l8, l1, l9, l2, l10, l3, l11, l4, l12, l5, l13, l6, l14, - l7, l15); - TRANSPOSE8x8_SH_SH(l0, l1, l2, l3, l4, l5, l6, l7, r0, r1, r2, r3, r4, r5, r6, - r7); - TRANSPOSE8x8_SH_SH(l8, l9, l10, l11, l12, l13, l14, l15, r8, r9, r10, r11, - r12, r13, r14, r15); - ST_SH8(r0, r8, r1, r9, r2, r10, r3, r11, out, 8); - ST_SH8(r4, r12, r5, r13, r6, r14, r7, r15, (out + 64), 8); -} - -static void postproc_fdct16x8_1d_row(int16_t *intermediate, int16_t *output) { - int16_t *temp = intermediate; - int16_t *out = output; - v8i16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - v8i16 in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, in11; - v8i16 in12, in13, in14, in15; - - LD_SH8(temp, 16, in0, in1, in2, in3, in4, in5, in6, in7); - temp = intermediate + 8; - LD_SH8(temp, 16, in8, in9, in10, in11, in12, in13, in14, in15); - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - TRANSPOSE8x8_SH_SH(in8, in9, in10, in11, in12, in13, in14, in15, in8, in9, - in10, in11, in12, in13, in14, in15); - FDCT_POSTPROC_2V_NEG_H(in0, in1); - FDCT_POSTPROC_2V_NEG_H(in2, in3); - FDCT_POSTPROC_2V_NEG_H(in4, in5); - FDCT_POSTPROC_2V_NEG_H(in6, in7); - FDCT_POSTPROC_2V_NEG_H(in8, in9); - FDCT_POSTPROC_2V_NEG_H(in10, in11); - FDCT_POSTPROC_2V_NEG_H(in12, in13); - FDCT_POSTPROC_2V_NEG_H(in14, in15); - BUTTERFLY_16(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, in11, - in12, in13, in14, in15, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, - tmp7, in8, in9, in10, in11, in12, in13, in14, in15); - temp = intermediate; - ST_SH8(in8, in9, in10, in11, in12, in13, in14, in15, temp, 16); - FDCT8x16_EVEN(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp0, tmp1, - tmp2, tmp3, tmp4, tmp5, tmp6, tmp7); - temp = intermediate; - LD_SH8(temp, 16, in8, in9, in10, in11, in12, in13, in14, in15); - FDCT8x16_ODD(in8, in9, in10, in11, in12, in13, in14, in15, in0, in1, in2, in3, - in4, in5, in6, in7); - TRANSPOSE8x8_SH_SH(tmp0, in0, tmp1, in1, tmp2, in2, tmp3, in3, tmp0, in0, - tmp1, in1, tmp2, in2, tmp3, in3); - ST_SH8(tmp0, in0, tmp1, in1, tmp2, in2, tmp3, in3, out, 16); - TRANSPOSE8x8_SH_SH(tmp4, in4, tmp5, in5, tmp6, in6, tmp7, in7, tmp4, in4, - tmp5, in5, tmp6, in6, tmp7, in7); - out = output + 8; - ST_SH8(tmp4, in4, tmp5, in5, tmp6, in6, tmp7, in7, out, 16); -} - -void vp9_fht16x16_msa(const int16_t *input, int16_t *output, int32_t stride, - int32_t tx_type) { - DECLARE_ALIGNED(32, int16_t, tmp[256]); - DECLARE_ALIGNED(32, int16_t, trans_buf[256]); - DECLARE_ALIGNED(32, int16_t, tmp_buf[128]); - int32_t i; - int16_t *ptmpbuf = &tmp_buf[0]; - int16_t *trans = &trans_buf[0]; - const int32_t const_arr[29 * 4] = { - 52707308, 52707308, 52707308, 52707308, -1072430300, - -1072430300, -1072430300, -1072430300, 795618043, 795618043, - 795618043, 795618043, -721080468, -721080468, -721080468, - -721080468, 459094491, 459094491, 459094491, 459094491, - -970646691, -970646691, -970646691, -970646691, 1010963856, - 1010963856, 1010963856, 1010963856, -361743294, -361743294, - -361743294, -361743294, 209469125, 209469125, 209469125, - 209469125, -1053094788, -1053094788, -1053094788, -1053094788, - 1053160324, 1053160324, 1053160324, 1053160324, 639644520, - 639644520, 639644520, 639644520, -862444000, -862444000, - -862444000, -862444000, 1062144356, 1062144356, 1062144356, - 1062144356, -157532337, -157532337, -157532337, -157532337, - 260914709, 260914709, 260914709, 260914709, -1041559667, - -1041559667, -1041559667, -1041559667, 920985831, 920985831, - 920985831, 920985831, -551995675, -551995675, -551995675, - -551995675, 596522295, 596522295, 596522295, 596522295, - 892853362, 892853362, 892853362, 892853362, -892787826, - -892787826, -892787826, -892787826, 410925857, 410925857, - 410925857, 410925857, -992012162, -992012162, -992012162, - -992012162, 992077698, 992077698, 992077698, 992077698, - 759246145, 759246145, 759246145, 759246145, -759180609, - -759180609, -759180609, -759180609, -759222975, -759222975, - -759222975, -759222975, 759288511, 759288511, 759288511, - 759288511 - }; - - switch (tx_type) { - case DCT_DCT: - /* column transform */ - for (i = 0; i < 2; ++i) { - fdct8x16_1d_column(input + 8 * i, tmp + 8 * i, stride); - } - - /* row transform */ - for (i = 0; i < 2; ++i) { - fdct16x8_1d_row(tmp + (128 * i), output + (128 * i)); - } - break; - case ADST_DCT: - /* column transform */ - for (i = 0; i < 2; ++i) { - fadst16_cols_step1_msa(input + (i << 3), stride, const_arr, ptmpbuf); - fadst16_cols_step2_msa(ptmpbuf, const_arr, tmp + (i << 3)); - } - - /* row transform */ - for (i = 0; i < 2; ++i) { - postproc_fdct16x8_1d_row(tmp + (128 * i), output + (128 * i)); - } - break; - case DCT_ADST: - /* column transform */ - for (i = 0; i < 2; ++i) { - fdct8x16_1d_column(input + 8 * i, tmp + 8 * i, stride); - } - - fadst16_transpose_postproc_msa(tmp, trans); - - /* row transform */ - for (i = 0; i < 2; ++i) { - fadst16_rows_step1_msa(trans + (i << 7), const_arr, ptmpbuf); - fadst16_rows_step2_msa(ptmpbuf, const_arr, tmp + (i << 7)); - } - - fadst16_transpose_msa(tmp, output); - break; - case ADST_ADST: - /* column transform */ - for (i = 0; i < 2; ++i) { - fadst16_cols_step1_msa(input + (i << 3), stride, const_arr, ptmpbuf); - fadst16_cols_step2_msa(ptmpbuf, const_arr, tmp + (i << 3)); - } - - fadst16_transpose_postproc_msa(tmp, trans); - - /* row transform */ - for (i = 0; i < 2; ++i) { - fadst16_rows_step1_msa(trans + (i << 7), const_arr, ptmpbuf); - fadst16_rows_step2_msa(ptmpbuf, const_arr, tmp + (i << 7)); - } - - fadst16_transpose_msa(tmp, output); - break; - default: assert(0); break; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/mips/msa/vp9_fdct4x4_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/mips/msa/vp9_fdct4x4_msa.c deleted file mode 100644 index 9c5cc12e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/mips/msa/vp9_fdct4x4_msa.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp9_rtcd.h" -#include "vp9/common/vp9_enums.h" -#include "vp9/encoder/mips/msa/vp9_fdct_msa.h" - -void vp9_fwht4x4_msa(const int16_t *input, int16_t *output, - int32_t src_stride) { - v8i16 in0, in1, in2, in3, in4; - - LD_SH4(input, src_stride, in0, in1, in2, in3); - - in0 += in1; - in3 -= in2; - in4 = (in0 - in3) >> 1; - SUB2(in4, in1, in4, in2, in1, in2); - in0 -= in2; - in3 += in1; - - TRANSPOSE4x4_SH_SH(in0, in2, in3, in1, in0, in2, in3, in1); - - in0 += in2; - in1 -= in3; - in4 = (in0 - in1) >> 1; - SUB2(in4, in2, in4, in3, in2, in3); - in0 -= in3; - in1 += in2; - - SLLI_4V(in0, in1, in2, in3, 2); - - TRANSPOSE4x4_SH_SH(in0, in3, in1, in2, in0, in3, in1, in2); - - ST4x2_UB(in0, output, 4); - ST4x2_UB(in3, output + 4, 4); - ST4x2_UB(in1, output + 8, 4); - ST4x2_UB(in2, output + 12, 4); -} - -void vp9_fht4x4_msa(const int16_t *input, int16_t *output, int32_t stride, - int32_t tx_type) { - v8i16 in0, in1, in2, in3; - - LD_SH4(input, stride, in0, in1, in2, in3); - - /* fdct4 pre-process */ - { - v8i16 temp, mask; - v16i8 zero = { 0 }; - v16i8 one = __msa_ldi_b(1); - - mask = (v8i16)__msa_sldi_b(zero, one, 15); - SLLI_4V(in0, in1, in2, in3, 4); - temp = __msa_ceqi_h(in0, 0); - temp = (v8i16)__msa_xori_b((v16u8)temp, 255); - temp = mask & temp; - in0 += temp; - } - - switch (tx_type) { - case DCT_DCT: - VP9_FDCT4(in0, in1, in2, in3, in0, in1, in2, in3); - TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); - VP9_FDCT4(in0, in1, in2, in3, in0, in1, in2, in3); - break; - case ADST_DCT: - VP9_FADST4(in0, in1, in2, in3, in0, in1, in2, in3); - TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); - VP9_FDCT4(in0, in1, in2, in3, in0, in1, in2, in3); - break; - case DCT_ADST: - VP9_FDCT4(in0, in1, in2, in3, in0, in1, in2, in3); - TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); - VP9_FADST4(in0, in1, in2, in3, in0, in1, in2, in3); - break; - case ADST_ADST: - VP9_FADST4(in0, in1, in2, in3, in0, in1, in2, in3); - TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); - VP9_FADST4(in0, in1, in2, in3, in0, in1, in2, in3); - break; - default: assert(0); break; - } - - TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); - ADD4(in0, 1, in1, 1, in2, 1, in3, 1, in0, in1, in2, in3); - SRA_4V(in0, in1, in2, in3, 2); - PCKEV_D2_SH(in1, in0, in3, in2, in0, in2); - ST_SH2(in0, in2, output, 8); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/mips/msa/vp9_fdct8x8_msa.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/mips/msa/vp9_fdct8x8_msa.c deleted file mode 100644 index 26d81aa9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/mips/msa/vp9_fdct8x8_msa.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp9_rtcd.h" -#include "vp9/common/vp9_enums.h" -#include "vp9/encoder/mips/msa/vp9_fdct_msa.h" - -void vp9_fht8x8_msa(const int16_t *input, int16_t *output, int32_t stride, - int32_t tx_type) { - v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - - LD_SH8(input, stride, in0, in1, in2, in3, in4, in5, in6, in7); - SLLI_4V(in0, in1, in2, in3, 2); - SLLI_4V(in4, in5, in6, in7, 2); - - switch (tx_type) { - case DCT_DCT: - VP9_FDCT8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, - in5, in6, in7); - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, - in3, in4, in5, in6, in7); - VP9_FDCT8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, - in5, in6, in7); - break; - case ADST_DCT: - VP9_ADST8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, - in5, in6, in7); - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, - in3, in4, in5, in6, in7); - VP9_FDCT8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, - in5, in6, in7); - break; - case DCT_ADST: - VP9_FDCT8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, - in5, in6, in7); - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, - in3, in4, in5, in6, in7); - VP9_ADST8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, - in5, in6, in7); - break; - case ADST_ADST: - VP9_ADST8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, - in5, in6, in7); - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, - in3, in4, in5, in6, in7); - VP9_ADST8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, - in5, in6, in7); - break; - default: assert(0); break; - } - - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - SRLI_AVE_S_4V_H(in0, in1, in2, in3, in4, in5, in6, in7); - ST_SH8(in0, in1, in2, in3, in4, in5, in6, in7, output, 8); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/mips/msa/vp9_fdct_msa.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/mips/msa/vp9_fdct_msa.h deleted file mode 100644 index fa1af2fc..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/mips/msa/vp9_fdct_msa.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_MIPS_MSA_VP9_FDCT_MSA_H_ -#define VPX_VP9_ENCODER_MIPS_MSA_VP9_FDCT_MSA_H_ - -#include "vpx_dsp/mips/fwd_txfm_msa.h" -#include "vpx_dsp/mips/txfm_macros_msa.h" -#include "vpx_ports/mem.h" - -#define VP9_ADST8(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, \ - out3, out4, out5, out6, out7) \ - { \ - v8i16 cnst0_m, cnst1_m, cnst2_m, cnst3_m, cnst4_m; \ - v8i16 vec0_m, vec1_m, vec2_m, vec3_m, s0_m, s1_m; \ - v8i16 coeff0_m = { cospi_2_64, cospi_6_64, cospi_10_64, cospi_14_64, \ - cospi_18_64, cospi_22_64, cospi_26_64, cospi_30_64 }; \ - v8i16 coeff1_m = { cospi_8_64, -cospi_8_64, cospi_16_64, -cospi_16_64, \ - cospi_24_64, -cospi_24_64, 0, 0 }; \ - \ - SPLATI_H2_SH(coeff0_m, 0, 7, cnst0_m, cnst1_m); \ - cnst2_m = -cnst0_m; \ - ILVEV_H2_SH(cnst0_m, cnst1_m, cnst1_m, cnst2_m, cnst0_m, cnst1_m); \ - SPLATI_H2_SH(coeff0_m, 4, 3, cnst2_m, cnst3_m); \ - cnst4_m = -cnst2_m; \ - ILVEV_H2_SH(cnst2_m, cnst3_m, cnst3_m, cnst4_m, cnst2_m, cnst3_m); \ - \ - ILVRL_H2_SH(in0, in7, vec1_m, vec0_m); \ - ILVRL_H2_SH(in4, in3, vec3_m, vec2_m); \ - DOT_ADD_SUB_SRARI_PCK(vec0_m, vec1_m, vec2_m, vec3_m, cnst0_m, cnst1_m, \ - cnst2_m, cnst3_m, in7, in0, in4, in3); \ - \ - SPLATI_H2_SH(coeff0_m, 2, 5, cnst0_m, cnst1_m); \ - cnst2_m = -cnst0_m; \ - ILVEV_H2_SH(cnst0_m, cnst1_m, cnst1_m, cnst2_m, cnst0_m, cnst1_m); \ - SPLATI_H2_SH(coeff0_m, 6, 1, cnst2_m, cnst3_m); \ - cnst4_m = -cnst2_m; \ - ILVEV_H2_SH(cnst2_m, cnst3_m, cnst3_m, cnst4_m, cnst2_m, cnst3_m); \ - \ - ILVRL_H2_SH(in2, in5, vec1_m, vec0_m); \ - ILVRL_H2_SH(in6, in1, vec3_m, vec2_m); \ - \ - DOT_ADD_SUB_SRARI_PCK(vec0_m, vec1_m, vec2_m, vec3_m, cnst0_m, cnst1_m, \ - cnst2_m, cnst3_m, in5, in2, in6, in1); \ - BUTTERFLY_4(in7, in0, in2, in5, s1_m, s0_m, in2, in5); \ - out7 = -s0_m; \ - out0 = s1_m; \ - \ - SPLATI_H4_SH(coeff1_m, 0, 4, 1, 5, cnst0_m, cnst1_m, cnst2_m, cnst3_m); \ - \ - ILVEV_H2_SH(cnst3_m, cnst0_m, cnst1_m, cnst2_m, cnst3_m, cnst2_m); \ - cnst0_m = __msa_ilvev_h(cnst1_m, cnst0_m); \ - cnst1_m = cnst0_m; \ - \ - ILVRL_H2_SH(in4, in3, vec1_m, vec0_m); \ - ILVRL_H2_SH(in6, in1, vec3_m, vec2_m); \ - DOT_ADD_SUB_SRARI_PCK(vec0_m, vec1_m, vec2_m, vec3_m, cnst0_m, cnst2_m, \ - cnst3_m, cnst1_m, out1, out6, s0_m, s1_m); \ - \ - SPLATI_H2_SH(coeff1_m, 2, 3, cnst0_m, cnst1_m); \ - cnst1_m = __msa_ilvev_h(cnst1_m, cnst0_m); \ - \ - ILVRL_H2_SH(in2, in5, vec1_m, vec0_m); \ - ILVRL_H2_SH(s0_m, s1_m, vec3_m, vec2_m); \ - out3 = DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst0_m); \ - out4 = DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst1_m); \ - out2 = DOT_SHIFT_RIGHT_PCK_H(vec2_m, vec3_m, cnst0_m); \ - out5 = DOT_SHIFT_RIGHT_PCK_H(vec2_m, vec3_m, cnst1_m); \ - \ - out1 = -out1; \ - out3 = -out3; \ - out5 = -out5; \ - } - -#define VP9_FADST4(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - v4i32 s0_m, s1_m, s2_m, s3_m, constant_m; \ - v4i32 in0_r_m, in1_r_m, in2_r_m, in3_r_m; \ - \ - UNPCK_R_SH_SW(in0, in0_r_m); \ - UNPCK_R_SH_SW(in1, in1_r_m); \ - UNPCK_R_SH_SW(in2, in2_r_m); \ - UNPCK_R_SH_SW(in3, in3_r_m); \ - \ - constant_m = __msa_fill_w(sinpi_4_9); \ - MUL2(in0_r_m, constant_m, in3_r_m, constant_m, s1_m, s0_m); \ - \ - constant_m = __msa_fill_w(sinpi_1_9); \ - s0_m += in0_r_m * constant_m; \ - s1_m -= in1_r_m * constant_m; \ - \ - constant_m = __msa_fill_w(sinpi_2_9); \ - s0_m += in1_r_m * constant_m; \ - s1_m += in3_r_m * constant_m; \ - \ - s2_m = in0_r_m + in1_r_m - in3_r_m; \ - \ - constant_m = __msa_fill_w(sinpi_3_9); \ - MUL2(in2_r_m, constant_m, s2_m, constant_m, s3_m, in1_r_m); \ - \ - in0_r_m = s0_m + s3_m; \ - s2_m = s1_m - s3_m; \ - s3_m = s1_m - s0_m + s3_m; \ - \ - SRARI_W4_SW(in0_r_m, in1_r_m, s2_m, s3_m, DCT_CONST_BITS); \ - PCKEV_H4_SH(in0_r_m, in0_r_m, in1_r_m, in1_r_m, s2_m, s2_m, s3_m, s3_m, \ - out0, out1, out2, out3); \ - } -#endif // VPX_VP9_ENCODER_MIPS_MSA_VP9_FDCT_MSA_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/ppc/vp9_quantize_vsx.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/ppc/vp9_quantize_vsx.c deleted file mode 100644 index 4d315584..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/ppc/vp9_quantize_vsx.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" - -#include "./vp9_rtcd.h" -#include "vpx_dsp/ppc/types_vsx.h" - -// Multiply the packed 16-bit integers in a and b, producing intermediate 32-bit -// integers, and return the high 16 bits of the intermediate integers. -// (a * b) >> 16 -// Note: Because this is done in 2 operations, a and b cannot both be UINT16_MIN -static INLINE int16x8_t vec_mulhi(int16x8_t a, int16x8_t b) { - // madds does ((A * B) >> 15) + C, we need >> 16, so we perform an extra right - // shift. - return vec_sra(vec_madds(a, b, vec_zeros_s16), vec_ones_u16); -} - -// Negate 16-bit integers in a when the corresponding signed 16-bit -// integer in b is negative. -static INLINE int16x8_t vec_sign(int16x8_t a, int16x8_t b) { - const int16x8_t mask = vec_sra(b, vec_shift_sign_s16); - return vec_xor(vec_add(a, mask), mask); -} - -// Compare packed 16-bit integers across a, and return the maximum value in -// every element. Returns a vector containing the biggest value across vector a. -static INLINE int16x8_t vec_max_across(int16x8_t a) { - a = vec_max(a, vec_perm(a, a, vec_perm64)); - a = vec_max(a, vec_perm(a, a, vec_perm32)); - return vec_max(a, vec_perm(a, a, vec_perm16)); -} - -void vp9_quantize_fp_vsx(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const int16_t *round_ptr, const int16_t *quant_ptr, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const int16_t *scan, const int16_t *iscan) { - int16x8_t qcoeff0, qcoeff1, dqcoeff0, dqcoeff1, eob; - bool16x8_t zero_coeff0, zero_coeff1; - - int16x8_t round = vec_vsx_ld(0, round_ptr); - int16x8_t quant = vec_vsx_ld(0, quant_ptr); - int16x8_t dequant = vec_vsx_ld(0, dequant_ptr); - int16x8_t coeff0 = vec_vsx_ld(0, coeff_ptr); - int16x8_t coeff1 = vec_vsx_ld(16, coeff_ptr); - int16x8_t scan0 = vec_vsx_ld(0, iscan); - int16x8_t scan1 = vec_vsx_ld(16, iscan); - - (void)scan; - - // First set of 8 coeff starts with DC + 7 AC - qcoeff0 = vec_mulhi(vec_vaddshs(vec_abs(coeff0), round), quant); - zero_coeff0 = vec_cmpeq(qcoeff0, vec_zeros_s16); - qcoeff0 = vec_sign(qcoeff0, coeff0); - vec_vsx_st(qcoeff0, 0, qcoeff_ptr); - - dqcoeff0 = vec_mladd(qcoeff0, dequant, vec_zeros_s16); - vec_vsx_st(dqcoeff0, 0, dqcoeff_ptr); - - // Remove DC value from round and quant - round = vec_splat(round, 1); - quant = vec_splat(quant, 1); - - // Remove DC value from dequant - dequant = vec_splat(dequant, 1); - - // Second set of 8 coeff starts with (all AC) - qcoeff1 = vec_mulhi(vec_vaddshs(vec_abs(coeff1), round), quant); - zero_coeff1 = vec_cmpeq(qcoeff1, vec_zeros_s16); - qcoeff1 = vec_sign(qcoeff1, coeff1); - vec_vsx_st(qcoeff1, 16, qcoeff_ptr); - - dqcoeff1 = vec_mladd(qcoeff1, dequant, vec_zeros_s16); - vec_vsx_st(dqcoeff1, 16, dqcoeff_ptr); - - eob = vec_max(vec_or(scan0, zero_coeff0), vec_or(scan1, zero_coeff1)); - - // We quantize 16 coeff up front (enough for a 4x4) and process 24 coeff per - // loop iteration. - // for 8x8: 16 + 2 x 24 = 64 - // for 16x16: 16 + 10 x 24 = 256 - if (n_coeffs > 16) { - int16x8_t coeff2, qcoeff2, dqcoeff2, eob2, scan2; - bool16x8_t zero_coeff2; - - int index = 16; - int off0 = 32; - int off1 = 48; - int off2 = 64; - - do { - coeff0 = vec_vsx_ld(off0, coeff_ptr); - coeff1 = vec_vsx_ld(off1, coeff_ptr); - coeff2 = vec_vsx_ld(off2, coeff_ptr); - scan0 = vec_vsx_ld(off0, iscan); - scan1 = vec_vsx_ld(off1, iscan); - scan2 = vec_vsx_ld(off2, iscan); - - qcoeff0 = vec_mulhi(vec_vaddshs(vec_abs(coeff0), round), quant); - zero_coeff0 = vec_cmpeq(qcoeff0, vec_zeros_s16); - qcoeff0 = vec_sign(qcoeff0, coeff0); - vec_vsx_st(qcoeff0, off0, qcoeff_ptr); - dqcoeff0 = vec_mladd(qcoeff0, dequant, vec_zeros_s16); - vec_vsx_st(dqcoeff0, off0, dqcoeff_ptr); - - qcoeff1 = vec_mulhi(vec_vaddshs(vec_abs(coeff1), round), quant); - zero_coeff1 = vec_cmpeq(qcoeff1, vec_zeros_s16); - qcoeff1 = vec_sign(qcoeff1, coeff1); - vec_vsx_st(qcoeff1, off1, qcoeff_ptr); - dqcoeff1 = vec_mladd(qcoeff1, dequant, vec_zeros_s16); - vec_vsx_st(dqcoeff1, off1, dqcoeff_ptr); - - qcoeff2 = vec_mulhi(vec_vaddshs(vec_abs(coeff2), round), quant); - zero_coeff2 = vec_cmpeq(qcoeff2, vec_zeros_s16); - qcoeff2 = vec_sign(qcoeff2, coeff2); - vec_vsx_st(qcoeff2, off2, qcoeff_ptr); - dqcoeff2 = vec_mladd(qcoeff2, dequant, vec_zeros_s16); - vec_vsx_st(dqcoeff2, off2, dqcoeff_ptr); - - eob = vec_max(eob, vec_or(scan0, zero_coeff0)); - eob2 = vec_max(vec_or(scan1, zero_coeff1), vec_or(scan2, zero_coeff2)); - eob = vec_max(eob, eob2); - - index += 24; - off0 += 48; - off1 += 48; - off2 += 48; - } while (index < n_coeffs); - } - - eob = vec_max_across(eob); - *eob_ptr = eob[0] + 1; -} - -// Sets the value of a 32-bit integers to 1 when the corresponding value in a is -// negative. -static INLINE int32x4_t vec_is_neg(int32x4_t a) { - return vec_sr(a, vec_shift_sign_s32); -} - -// DeQuantization function used for 32x32 blocks. Quantized coeff of 32x32 -// blocks are twice as big as for other block sizes. As such, using -// vec_mladd results in overflow. -static INLINE int16x8_t dequantize_coeff_32(int16x8_t qcoeff, - int16x8_t dequant) { - int32x4_t dqcoeffe = vec_mule(qcoeff, dequant); - int32x4_t dqcoeffo = vec_mulo(qcoeff, dequant); - // Add 1 if negative to round towards zero because the C uses division. - dqcoeffe = vec_add(dqcoeffe, vec_is_neg(dqcoeffe)); - dqcoeffo = vec_add(dqcoeffo, vec_is_neg(dqcoeffo)); - dqcoeffe = vec_sra(dqcoeffe, vec_ones_u32); - dqcoeffo = vec_sra(dqcoeffo, vec_ones_u32); - return (int16x8_t)vec_perm(dqcoeffe, dqcoeffo, vec_perm_odd_even_pack); -} - -void vp9_quantize_fp_32x32_vsx(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const int16_t *round_ptr, - const int16_t *quant_ptr, tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const int16_t *scan, const int16_t *iscan) { - // In stage 1, we quantize 16 coeffs (DC + 15 AC) - // In stage 2, we loop 42 times and quantize 24 coeffs per iteration - // (32 * 32 - 16) / 24 = 42 - int num_itr = 42; - // Offsets are in bytes, 16 coeffs = 32 bytes - int off0 = 32; - int off1 = 48; - int off2 = 64; - - int16x8_t qcoeff0, qcoeff1, dqcoeff0, dqcoeff1, eob; - bool16x8_t mask0, mask1, zero_coeff0, zero_coeff1; - - int16x8_t round = vec_vsx_ld(0, round_ptr); - int16x8_t quant = vec_vsx_ld(0, quant_ptr); - int16x8_t dequant = vec_vsx_ld(0, dequant_ptr); - int16x8_t coeff0 = vec_vsx_ld(0, coeff_ptr); - int16x8_t coeff1 = vec_vsx_ld(16, coeff_ptr); - int16x8_t scan0 = vec_vsx_ld(0, iscan); - int16x8_t scan1 = vec_vsx_ld(16, iscan); - int16x8_t thres = vec_sra(dequant, vec_splats((uint16_t)2)); - int16x8_t abs_coeff0 = vec_abs(coeff0); - int16x8_t abs_coeff1 = vec_abs(coeff1); - - (void)scan; - (void)n_coeffs; - - mask0 = vec_cmpge(abs_coeff0, thres); - round = vec_sra(vec_add(round, vec_ones_s16), vec_ones_u16); - // First set of 8 coeff starts with DC + 7 AC - qcoeff0 = vec_madds(vec_vaddshs(abs_coeff0, round), quant, vec_zeros_s16); - qcoeff0 = vec_and(qcoeff0, mask0); - zero_coeff0 = vec_cmpeq(qcoeff0, vec_zeros_s16); - qcoeff0 = vec_sign(qcoeff0, coeff0); - vec_vsx_st(qcoeff0, 0, qcoeff_ptr); - - dqcoeff0 = dequantize_coeff_32(qcoeff0, dequant); - vec_vsx_st(dqcoeff0, 0, dqcoeff_ptr); - - // Remove DC value from thres, round, quant and dequant - thres = vec_splat(thres, 1); - round = vec_splat(round, 1); - quant = vec_splat(quant, 1); - dequant = vec_splat(dequant, 1); - - mask1 = vec_cmpge(abs_coeff1, thres); - - // Second set of 8 coeff starts with (all AC) - qcoeff1 = - vec_madds(vec_vaddshs(vec_abs(coeff1), round), quant, vec_zeros_s16); - qcoeff1 = vec_and(qcoeff1, mask1); - zero_coeff1 = vec_cmpeq(qcoeff1, vec_zeros_s16); - qcoeff1 = vec_sign(qcoeff1, coeff1); - vec_vsx_st(qcoeff1, 16, qcoeff_ptr); - - dqcoeff1 = dequantize_coeff_32(qcoeff1, dequant); - vec_vsx_st(dqcoeff1, 16, dqcoeff_ptr); - - eob = vec_max(vec_or(scan0, zero_coeff0), vec_or(scan1, zero_coeff1)); - - do { - int16x8_t coeff2, abs_coeff2, qcoeff2, dqcoeff2, eob2, scan2; - bool16x8_t zero_coeff2, mask2; - coeff0 = vec_vsx_ld(off0, coeff_ptr); - coeff1 = vec_vsx_ld(off1, coeff_ptr); - coeff2 = vec_vsx_ld(off2, coeff_ptr); - scan0 = vec_vsx_ld(off0, iscan); - scan1 = vec_vsx_ld(off1, iscan); - scan2 = vec_vsx_ld(off2, iscan); - - abs_coeff0 = vec_abs(coeff0); - abs_coeff1 = vec_abs(coeff1); - abs_coeff2 = vec_abs(coeff2); - - qcoeff0 = vec_madds(vec_vaddshs(abs_coeff0, round), quant, vec_zeros_s16); - qcoeff1 = vec_madds(vec_vaddshs(abs_coeff1, round), quant, vec_zeros_s16); - qcoeff2 = vec_madds(vec_vaddshs(abs_coeff2, round), quant, vec_zeros_s16); - - mask0 = vec_cmpge(abs_coeff0, thres); - mask1 = vec_cmpge(abs_coeff1, thres); - mask2 = vec_cmpge(abs_coeff2, thres); - - qcoeff0 = vec_and(qcoeff0, mask0); - qcoeff1 = vec_and(qcoeff1, mask1); - qcoeff2 = vec_and(qcoeff2, mask2); - - zero_coeff0 = vec_cmpeq(qcoeff0, vec_zeros_s16); - zero_coeff1 = vec_cmpeq(qcoeff1, vec_zeros_s16); - zero_coeff2 = vec_cmpeq(qcoeff2, vec_zeros_s16); - - qcoeff0 = vec_sign(qcoeff0, coeff0); - qcoeff1 = vec_sign(qcoeff1, coeff1); - qcoeff2 = vec_sign(qcoeff2, coeff2); - - vec_vsx_st(qcoeff0, off0, qcoeff_ptr); - vec_vsx_st(qcoeff1, off1, qcoeff_ptr); - vec_vsx_st(qcoeff2, off2, qcoeff_ptr); - - dqcoeff0 = dequantize_coeff_32(qcoeff0, dequant); - dqcoeff1 = dequantize_coeff_32(qcoeff1, dequant); - dqcoeff2 = dequantize_coeff_32(qcoeff2, dequant); - - vec_vsx_st(dqcoeff0, off0, dqcoeff_ptr); - vec_vsx_st(dqcoeff1, off1, dqcoeff_ptr); - vec_vsx_st(dqcoeff2, off2, dqcoeff_ptr); - - eob = vec_max(eob, vec_or(scan0, zero_coeff0)); - eob2 = vec_max(vec_or(scan1, zero_coeff1), vec_or(scan2, zero_coeff2)); - eob = vec_max(eob, eob2); - - off0 += 48; - off1 += 48; - off2 += 48; - num_itr--; - } while (num_itr != 0); - - eob = vec_max_across(eob); - *eob_ptr = eob[0] + 1; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_alt_ref_aq.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_alt_ref_aq.c deleted file mode 100644 index acc3764c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_alt_ref_aq.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file in the root of the source tree. An additional - * intellectual property rights grant can be found in the file PATENTS. - * All contributing project authors may be found in the AUTHORS file in - * the root of the source tree. - */ - -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_alt_ref_aq.h" - -struct ALT_REF_AQ { - int dummy; -}; - -struct ALT_REF_AQ *vp9_alt_ref_aq_create(void) { - return (struct ALT_REF_AQ *)vpx_malloc(sizeof(struct ALT_REF_AQ)); -} - -void vp9_alt_ref_aq_destroy(struct ALT_REF_AQ *const self) { vpx_free(self); } - -void vp9_alt_ref_aq_upload_map(struct ALT_REF_AQ *const self, - const struct MATX_8U *segmentation_map) { - (void)self; - (void)segmentation_map; -} - -void vp9_alt_ref_aq_set_nsegments(struct ALT_REF_AQ *const self, - int nsegments) { - (void)self; - (void)nsegments; -} - -void vp9_alt_ref_aq_setup_mode(struct ALT_REF_AQ *const self, - struct VP9_COMP *const cpi) { - (void)cpi; - (void)self; -} - -// set basic segmentation to the altref's one -void vp9_alt_ref_aq_setup_map(struct ALT_REF_AQ *const self, - struct VP9_COMP *const cpi) { - (void)cpi; - (void)self; -} - -// restore cpi->aq_mode -void vp9_alt_ref_aq_unset_all(struct ALT_REF_AQ *const self, - struct VP9_COMP *const cpi) { - (void)cpi; - (void)self; -} - -int vp9_alt_ref_aq_disable_if(const struct ALT_REF_AQ *self, - int segmentation_overhead, int bandwidth) { - (void)bandwidth; - (void)self; - (void)segmentation_overhead; - - return 0; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_alt_ref_aq.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_alt_ref_aq.h deleted file mode 100644 index 22a657e0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_alt_ref_aq.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file in the root of the source tree. An additional - * intellectual property rights grant can be found in the file PATENTS. - * All contributing project authors may be found in the AUTHORS file in - * the root of the source tree. - */ - -/* - * \file vp9_alt_ref_aq.h - * - * This file contains public interface for setting up adaptive segmentation - * for altref frames. Go to alt_ref_aq_private.h for implmentation details. - */ - -#ifndef VPX_VP9_ENCODER_VP9_ALT_REF_AQ_H_ -#define VPX_VP9_ENCODER_VP9_ALT_REF_AQ_H_ - -#include "vpx/vpx_integer.h" - -// Where to disable segmentation -#define ALT_REF_AQ_LOW_BITRATE_BOUNDARY 150 - -// Last frame always has overall quality = 0, -// so it is questionable if I can process it -#define ALT_REF_AQ_APPLY_TO_LAST_FRAME 1 - -// If I should try to compare gain -// against segmentation overhead -#define ALT_REF_AQ_PROTECT_GAIN 0 - -// Threshold to disable segmentation -#define ALT_REF_AQ_PROTECT_GAIN_THRESH 0.5 - -#ifdef __cplusplus -extern "C" { -#endif - -// Simple structure for storing images -struct MATX_8U { - int rows; - int cols; - int stride; - - uint8_t *data; -}; - -struct VP9_COMP; -struct ALT_REF_AQ; - -/*!\brief Constructor - * - * \return Instance of the class - */ -struct ALT_REF_AQ *vp9_alt_ref_aq_create(void); - -/*!\brief Upload segmentation_map to self object - * - * \param self Instance of the class - * \param segmentation_map Segmentation map to upload - */ -void vp9_alt_ref_aq_upload_map(struct ALT_REF_AQ *const self, - const struct MATX_8U *segmentation_map); - -/*!\brief Return pointer to the altref segmentation map - * - * \param self Instance of the class - * \param segmentation_overhead Segmentation overhead in bytes - * \param bandwidth Current frame bandwidth in bytes - * - * \return Boolean value to disable segmentation - */ -int vp9_alt_ref_aq_disable_if(const struct ALT_REF_AQ *self, - int segmentation_overhead, int bandwidth); - -/*!\brief Set number of segments - * - * It is used for delta quantizer computations - * and thus it can be larger than - * maximum value of the segmentation map - * - * \param self Instance of the class - * \param nsegments Maximum number of segments - */ -void vp9_alt_ref_aq_set_nsegments(struct ALT_REF_AQ *const self, int nsegments); - -/*!\brief Set up LOOKAHEAD_AQ segmentation mode - * - * Set up segmentation mode to LOOKAHEAD_AQ - * (expected future frames prediction - * quality refering to the current frame). - * - * \param self Instance of the class - * \param cpi Encoder context - */ -void vp9_alt_ref_aq_setup_mode(struct ALT_REF_AQ *const self, - struct VP9_COMP *const cpi); - -/*!\brief Set up LOOKAHEAD_AQ segmentation map and delta quantizers - * - * \param self Instance of the class - * \param cpi Encoder context - */ -void vp9_alt_ref_aq_setup_map(struct ALT_REF_AQ *const self, - struct VP9_COMP *const cpi); - -/*!\brief Restore main segmentation map mode and reset the class variables - * - * \param self Instance of the class - * \param cpi Encoder context - */ -void vp9_alt_ref_aq_unset_all(struct ALT_REF_AQ *const self, - struct VP9_COMP *const cpi); - -/*!\brief Destructor - * - * \param self Instance of the class - */ -void vp9_alt_ref_aq_destroy(struct ALT_REF_AQ *const self); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_ALT_REF_AQ_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_360.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_360.c deleted file mode 100644 index dba017ff..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_360.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "vpx_ports/mem.h" -#include "vpx_ports/system_state.h" - -#include "vp9/encoder/vp9_aq_360.h" -#include "vp9/encoder/vp9_aq_variance.h" - -#include "vp9/common/vp9_seg_common.h" - -#include "vp9/encoder/vp9_ratectrl.h" -#include "vp9/encoder/vp9_rd.h" -#include "vp9/encoder/vp9_segmentation.h" - -static const double rate_ratio[MAX_SEGMENTS] = { 1.0, 0.75, 0.6, 0.5, - 0.4, 0.3, 0.25 }; - -// Sets segment id 0 for the equatorial region, 1 for temperate region -// and 2 for the polar regions -unsigned int vp9_360aq_segment_id(int mi_row, int mi_rows) { - if (mi_row < mi_rows / 8 || mi_row > mi_rows - mi_rows / 8) - return 2; - else if (mi_row < mi_rows / 4 || mi_row > mi_rows - mi_rows / 4) - return 1; - else - return 0; -} - -void vp9_360aq_frame_setup(VP9_COMP *cpi) { - VP9_COMMON *cm = &cpi->common; - struct segmentation *seg = &cm->seg; - int i; - - if (frame_is_intra_only(cm) || cpi->force_update_segmentation || - cm->error_resilient_mode) { - vp9_enable_segmentation(seg); - vp9_clearall_segfeatures(seg); - - seg->abs_delta = SEGMENT_DELTADATA; - - vpx_clear_system_state(); - - for (i = 0; i < MAX_SEGMENTS; ++i) { - int qindex_delta = - vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, cm->base_qindex, - rate_ratio[i], cm->bit_depth); - - // We don't allow qindex 0 in a segment if the base value is not 0. - // Q index 0 (lossless) implies 4x4 encoding only and in AQ mode a segment - // Q delta is sometimes applied without going back around the rd loop. - // This could lead to an illegal combination of partition size and q. - if ((cm->base_qindex != 0) && ((cm->base_qindex + qindex_delta) == 0)) { - qindex_delta = -cm->base_qindex + 1; - } - - // No need to enable SEG_LVL_ALT_Q for this segment. - if (rate_ratio[i] == 1.0) { - continue; - } - - vp9_set_segdata(seg, i, SEG_LVL_ALT_Q, qindex_delta); - vp9_enable_segfeature(seg, i, SEG_LVL_ALT_Q); - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_360.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_360.h deleted file mode 100644 index 749d3c19..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_360.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_AQ_360_H_ -#define VPX_VP9_ENCODER_VP9_AQ_360_H_ - -#include "vp9/encoder/vp9_encoder.h" - -#ifdef __cplusplus -extern "C" { -#endif - -unsigned int vp9_360aq_segment_id(int mi_row, int mi_rows); -void vp9_360aq_frame_setup(VP9_COMP *cpi); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_AQ_360_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_complexity.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_complexity.c deleted file mode 100644 index ef3423f8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_complexity.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_ports/system_state.h" - -#include "vp9/encoder/vp9_aq_complexity.h" -#include "vp9/encoder/vp9_aq_variance.h" -#include "vp9/encoder/vp9_encodeframe.h" -#include "vp9/common/vp9_seg_common.h" -#include "vp9/encoder/vp9_segmentation.h" - -#define AQ_C_SEGMENTS 5 -#define DEFAULT_AQ2_SEG 3 // Neutral Q segment -#define AQ_C_STRENGTHS 3 -static const double aq_c_q_adj_factor[AQ_C_STRENGTHS][AQ_C_SEGMENTS] = { - { 1.75, 1.25, 1.05, 1.00, 0.90 }, - { 2.00, 1.50, 1.15, 1.00, 0.85 }, - { 2.50, 1.75, 1.25, 1.00, 0.80 } -}; -static const double aq_c_transitions[AQ_C_STRENGTHS][AQ_C_SEGMENTS] = { - { 0.15, 0.30, 0.55, 2.00, 100.0 }, - { 0.20, 0.40, 0.65, 2.00, 100.0 }, - { 0.25, 0.50, 0.75, 2.00, 100.0 } -}; -static const double aq_c_var_thresholds[AQ_C_STRENGTHS][AQ_C_SEGMENTS] = { - { -4.0, -3.0, -2.0, 100.00, 100.0 }, - { -3.5, -2.5, -1.5, 100.00, 100.0 }, - { -3.0, -2.0, -1.0, 100.00, 100.0 } -}; - -static int get_aq_c_strength(int q_index, vpx_bit_depth_t bit_depth) { - // Approximate base quatizer (truncated to int) - const int base_quant = vp9_ac_quant(q_index, 0, bit_depth) / 4; - return (base_quant > 10) + (base_quant > 25); -} - -void vp9_setup_in_frame_q_adj(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - struct segmentation *const seg = &cm->seg; - - // Make SURE use of floating point in this function is safe. - vpx_clear_system_state(); - - if (frame_is_intra_only(cm) || cm->error_resilient_mode || - cpi->refresh_alt_ref_frame || cpi->force_update_segmentation || - (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref)) { - int segment; - const int aq_strength = get_aq_c_strength(cm->base_qindex, cm->bit_depth); - - // Clear down the segment map. - memset(cpi->segmentation_map, DEFAULT_AQ2_SEG, cm->mi_rows * cm->mi_cols); - - vp9_clearall_segfeatures(seg); - - // Segmentation only makes sense if the target bits per SB is above a - // threshold. Below this the overheads will usually outweigh any benefit. - if (cpi->rc.sb64_target_rate < 256) { - vp9_disable_segmentation(seg); - return; - } - - vp9_enable_segmentation(seg); - - // Select delta coding method. - seg->abs_delta = SEGMENT_DELTADATA; - - // Default segment "Q" feature is disabled so it defaults to the baseline Q. - vp9_disable_segfeature(seg, DEFAULT_AQ2_SEG, SEG_LVL_ALT_Q); - - // Use some of the segments for in frame Q adjustment. - for (segment = 0; segment < AQ_C_SEGMENTS; ++segment) { - int qindex_delta; - - if (segment == DEFAULT_AQ2_SEG) continue; - - qindex_delta = vp9_compute_qdelta_by_rate( - &cpi->rc, cm->frame_type, cm->base_qindex, - aq_c_q_adj_factor[aq_strength][segment], cm->bit_depth); - - // For AQ complexity mode, we don't allow Q0 in a segment if the base - // Q is not 0. Q0 (lossless) implies 4x4 only and in AQ mode 2 a segment - // Q delta is sometimes applied without going back around the rd loop. - // This could lead to an illegal combination of partition size and q. - if ((cm->base_qindex != 0) && ((cm->base_qindex + qindex_delta) == 0)) { - qindex_delta = -cm->base_qindex + 1; - } - if ((cm->base_qindex + qindex_delta) > 0) { - vp9_enable_segfeature(seg, segment, SEG_LVL_ALT_Q); - vp9_set_segdata(seg, segment, SEG_LVL_ALT_Q, qindex_delta); - } - } - } -} - -#define DEFAULT_LV_THRESH 10.0 -#define MIN_DEFAULT_LV_THRESH 8.0 -// Select a segment for the current block. -// The choice of segment for a block depends on the ratio of the projected -// bits for the block vs a target average and its spatial complexity. -void vp9_caq_select_segment(VP9_COMP *cpi, MACROBLOCK *mb, BLOCK_SIZE bs, - int mi_row, int mi_col, int projected_rate) { - VP9_COMMON *const cm = &cpi->common; - - const int mi_offset = mi_row * cm->mi_cols + mi_col; - const int bw = num_8x8_blocks_wide_lookup[BLOCK_64X64]; - const int bh = num_8x8_blocks_high_lookup[BLOCK_64X64]; - const int xmis = VPXMIN(cm->mi_cols - mi_col, num_8x8_blocks_wide_lookup[bs]); - const int ymis = VPXMIN(cm->mi_rows - mi_row, num_8x8_blocks_high_lookup[bs]); - int x, y; - int i; - unsigned char segment; - - if (0) { - segment = DEFAULT_AQ2_SEG; - } else { - // Rate depends on fraction of a SB64 in frame (xmis * ymis / bw * bh). - // It is converted to bits * 256 units. - const int target_rate = - (cpi->rc.sb64_target_rate * xmis * ymis * 256) / (bw * bh); - double logvar; - double low_var_thresh; - const int aq_strength = get_aq_c_strength(cm->base_qindex, cm->bit_depth); - - vpx_clear_system_state(); - low_var_thresh = (cpi->oxcf.pass == 2) ? VPXMAX(cpi->twopass.mb_av_energy, - MIN_DEFAULT_LV_THRESH) - : DEFAULT_LV_THRESH; - - vp9_setup_src_planes(mb, cpi->Source, mi_row, mi_col); - logvar = vp9_log_block_var(cpi, mb, bs); - - segment = AQ_C_SEGMENTS - 1; // Just in case no break out below. - for (i = 0; i < AQ_C_SEGMENTS; ++i) { - // Test rate against a threshold value and variance against a threshold. - // Increasing segment number (higher variance and complexity) = higher Q. - if ((projected_rate < target_rate * aq_c_transitions[aq_strength][i]) && - (logvar < (low_var_thresh + aq_c_var_thresholds[aq_strength][i]))) { - segment = i; - break; - } - } - } - - // Fill in the entires in the segment map corresponding to this SB64. - for (y = 0; y < ymis; y++) { - for (x = 0; x < xmis; x++) { - cpi->segmentation_map[mi_offset + y * cm->mi_cols + x] = segment; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_complexity.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_complexity.h deleted file mode 100644 index d3cb34c0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_complexity.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_AQ_COMPLEXITY_H_ -#define VPX_VP9_ENCODER_VP9_AQ_COMPLEXITY_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "vp9/common/vp9_enums.h" - -struct VP9_COMP; -struct macroblock; - -// Select a segment for the current Block. -void vp9_caq_select_segment(struct VP9_COMP *cpi, struct macroblock *, - BLOCK_SIZE bs, int mi_row, int mi_col, - int projected_rate); - -// This function sets up a set of segments with delta Q values around -// the baseline frame quantizer. -void vp9_setup_in_frame_q_adj(struct VP9_COMP *cpi); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_AQ_COMPLEXITY_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_cyclicrefresh.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_cyclicrefresh.c deleted file mode 100644 index 109ba0c6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_cyclicrefresh.c +++ /dev/null @@ -1,703 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_ports/system_state.h" - -#include "vp9/encoder/vp9_aq_cyclicrefresh.h" - -#include "vp9/common/vp9_seg_common.h" - -#include "vp9/encoder/vp9_ratectrl.h" -#include "vp9/encoder/vp9_segmentation.h" - -static const uint8_t VP9_VAR_OFFS[64] = { - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 -}; - -CYCLIC_REFRESH *vp9_cyclic_refresh_alloc(int mi_rows, int mi_cols) { - size_t last_coded_q_map_size; - CYCLIC_REFRESH *const cr = vpx_calloc(1, sizeof(*cr)); - if (cr == NULL) return NULL; - - cr->map = vpx_calloc(mi_rows * mi_cols, sizeof(*cr->map)); - if (cr->map == NULL) { - vp9_cyclic_refresh_free(cr); - return NULL; - } - last_coded_q_map_size = mi_rows * mi_cols * sizeof(*cr->last_coded_q_map); - cr->last_coded_q_map = vpx_malloc(last_coded_q_map_size); - if (cr->last_coded_q_map == NULL) { - vp9_cyclic_refresh_free(cr); - return NULL; - } - assert(MAXQ <= 255); - memset(cr->last_coded_q_map, MAXQ, last_coded_q_map_size); - cr->counter_encode_maxq_scene_change = 0; - cr->content_mode = 1; - return cr; -} - -void vp9_cyclic_refresh_free(CYCLIC_REFRESH *cr) { - if (cr != NULL) { - vpx_free(cr->map); - vpx_free(cr->last_coded_q_map); - vpx_free(cr); - } -} - -// Check if this coding block, of size bsize, should be considered for refresh -// (lower-qp coding). Decision can be based on various factors, such as -// size of the coding block (i.e., below min_block size rejected), coding -// mode, and rate/distortion. -static int candidate_refresh_aq(const CYCLIC_REFRESH *cr, const MODE_INFO *mi, - int64_t rate, int64_t dist, int bsize) { - MV mv = mi->mv[0].as_mv; - // Reject the block for lower-qp coding if projected distortion - // is above the threshold, and any of the following is true: - // 1) mode uses large mv - // 2) mode is an intra-mode - // Otherwise accept for refresh. - if (dist > cr->thresh_dist_sb && - (mv.row > cr->motion_thresh || mv.row < -cr->motion_thresh || - mv.col > cr->motion_thresh || mv.col < -cr->motion_thresh || - !is_inter_block(mi))) - return CR_SEGMENT_ID_BASE; - else if (bsize >= BLOCK_16X16 && rate < cr->thresh_rate_sb && - is_inter_block(mi) && mi->mv[0].as_int == 0 && - cr->rate_boost_fac > 10) - // More aggressive delta-q for bigger blocks with zero motion. - return CR_SEGMENT_ID_BOOST2; - else - return CR_SEGMENT_ID_BOOST1; -} - -// Compute delta-q for the segment. -static int compute_deltaq(const VP9_COMP *cpi, int q, double rate_factor) { - const CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; - const RATE_CONTROL *const rc = &cpi->rc; - int deltaq = vp9_compute_qdelta_by_rate(rc, cpi->common.frame_type, q, - rate_factor, cpi->common.bit_depth); - if ((-deltaq) > cr->max_qdelta_perc * q / 100) { - deltaq = -cr->max_qdelta_perc * q / 100; - } - return deltaq; -} - -// For the just encoded frame, estimate the bits, incorporating the delta-q -// from non-base segment. For now ignore effect of multiple segments -// (with different delta-q). Note this function is called in the postencode -// (called from rc_update_rate_correction_factors()). -int vp9_cyclic_refresh_estimate_bits_at_q(const VP9_COMP *cpi, - double correction_factor) { - const VP9_COMMON *const cm = &cpi->common; - const CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; - int estimated_bits; - int mbs = cm->MBs; - int num8x8bl = mbs << 2; - // Weight for non-base segments: use actual number of blocks refreshed in - // previous/just encoded frame. Note number of blocks here is in 8x8 units. - double weight_segment1 = (double)cr->actual_num_seg1_blocks / num8x8bl; - double weight_segment2 = (double)cr->actual_num_seg2_blocks / num8x8bl; - // Take segment weighted average for estimated bits. - estimated_bits = (int)round( - (1.0 - weight_segment1 - weight_segment2) * - vp9_estimate_bits_at_q(cm->frame_type, cm->base_qindex, mbs, - correction_factor, cm->bit_depth) + - weight_segment1 * - vp9_estimate_bits_at_q(cm->frame_type, - cm->base_qindex + cr->qindex_delta[1], mbs, - correction_factor, cm->bit_depth) + - weight_segment2 * - vp9_estimate_bits_at_q(cm->frame_type, - cm->base_qindex + cr->qindex_delta[2], mbs, - correction_factor, cm->bit_depth)); - return estimated_bits; -} - -// Prior to encoding the frame, estimate the bits per mb, for a given q = i and -// a corresponding delta-q (for segment 1). This function is called in the -// rc_regulate_q() to set the base qp index. -// Note: the segment map is set to either 0/CR_SEGMENT_ID_BASE (no refresh) or -// to 1/CR_SEGMENT_ID_BOOST1 (refresh) for each superblock, prior to encoding. -int vp9_cyclic_refresh_rc_bits_per_mb(const VP9_COMP *cpi, int i, - double correction_factor) { - const VP9_COMMON *const cm = &cpi->common; - CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; - int bits_per_mb; - int deltaq = 0; - if (cpi->oxcf.speed < 8) - deltaq = compute_deltaq(cpi, i, cr->rate_ratio_qdelta); - else - deltaq = -(cr->max_qdelta_perc * i) / 200; - // Take segment weighted average for bits per mb. - bits_per_mb = - (int)round((1.0 - cr->weight_segment) * - vp9_rc_bits_per_mb(cm->frame_type, i, correction_factor, - cm->bit_depth) + - cr->weight_segment * - vp9_rc_bits_per_mb(cm->frame_type, i + deltaq, - correction_factor, cm->bit_depth)); - return bits_per_mb; -} - -// Prior to coding a given prediction block, of size bsize at (mi_row, mi_col), -// check if we should reset the segment_id, and update the cyclic_refresh map -// and segmentation map. -void vp9_cyclic_refresh_update_segment(VP9_COMP *const cpi, MODE_INFO *const mi, - int mi_row, int mi_col, BLOCK_SIZE bsize, - int64_t rate, int64_t dist, int skip, - struct macroblock_plane *const p) { - const VP9_COMMON *const cm = &cpi->common; - CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; - const int bw = num_8x8_blocks_wide_lookup[bsize]; - const int bh = num_8x8_blocks_high_lookup[bsize]; - const int xmis = VPXMIN(cm->mi_cols - mi_col, bw); - const int ymis = VPXMIN(cm->mi_rows - mi_row, bh); - const int block_index = mi_row * cm->mi_cols + mi_col; - int refresh_this_block = candidate_refresh_aq(cr, mi, rate, dist, bsize); - // Default is to not update the refresh map. - int new_map_value = cr->map[block_index]; - int x = 0; - int y = 0; - - int is_skin = 0; - if (refresh_this_block == 0 && bsize <= BLOCK_16X16 && - cpi->use_skin_detection) { - is_skin = - vp9_compute_skin_block(p[0].src.buf, p[1].src.buf, p[2].src.buf, - p[0].src.stride, p[1].src.stride, bsize, 0, 0); - if (is_skin) refresh_this_block = 1; - } - - if (cpi->oxcf.rc_mode == VPX_VBR && mi->ref_frame[0] == GOLDEN_FRAME) - refresh_this_block = 0; - - // If this block is labeled for refresh, check if we should reset the - // segment_id. - if (cpi->sf.use_nonrd_pick_mode && - cyclic_refresh_segment_id_boosted(mi->segment_id)) { - mi->segment_id = refresh_this_block; - // Reset segment_id if it will be skipped. - if (skip) mi->segment_id = CR_SEGMENT_ID_BASE; - } - - // Update the cyclic refresh map, to be used for setting segmentation map - // for the next frame. If the block will be refreshed this frame, mark it - // as clean. The magnitude of the -ve influences how long before we consider - // it for refresh again. - if (cyclic_refresh_segment_id_boosted(mi->segment_id)) { - new_map_value = -cr->time_for_refresh; - } else if (refresh_this_block) { - // Else if it is accepted as candidate for refresh, and has not already - // been refreshed (marked as 1) then mark it as a candidate for cleanup - // for future time (marked as 0), otherwise don't update it. - if (cr->map[block_index] == 1) new_map_value = 0; - } else { - // Leave it marked as block that is not candidate for refresh. - new_map_value = 1; - } - - // Update entries in the cyclic refresh map with new_map_value, and - // copy mbmi->segment_id into global segmentation map. - for (y = 0; y < ymis; y++) - for (x = 0; x < xmis; x++) { - int map_offset = block_index + y * cm->mi_cols + x; - cr->map[map_offset] = new_map_value; - cpi->segmentation_map[map_offset] = mi->segment_id; - } -} - -void vp9_cyclic_refresh_update_sb_postencode(VP9_COMP *const cpi, - const MODE_INFO *const mi, - int mi_row, int mi_col, - BLOCK_SIZE bsize) { - const VP9_COMMON *const cm = &cpi->common; - CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; - const int bw = num_8x8_blocks_wide_lookup[bsize]; - const int bh = num_8x8_blocks_high_lookup[bsize]; - const int xmis = VPXMIN(cm->mi_cols - mi_col, bw); - const int ymis = VPXMIN(cm->mi_rows - mi_row, bh); - const int block_index = mi_row * cm->mi_cols + mi_col; - int x, y; - for (y = 0; y < ymis; y++) - for (x = 0; x < xmis; x++) { - int map_offset = block_index + y * cm->mi_cols + x; - // Inter skip blocks were clearly not coded at the current qindex, so - // don't update the map for them. For cases where motion is non-zero or - // the reference frame isn't the previous frame, the previous value in - // the map for this spatial location is not entirely correct. - if ((!is_inter_block(mi) || !mi->skip) && - mi->segment_id <= CR_SEGMENT_ID_BOOST2) { - cr->last_coded_q_map[map_offset] = - clamp(cm->base_qindex + cr->qindex_delta[mi->segment_id], 0, MAXQ); - } else if (is_inter_block(mi) && mi->skip && - mi->segment_id <= CR_SEGMENT_ID_BOOST2) { - cr->last_coded_q_map[map_offset] = VPXMIN( - clamp(cm->base_qindex + cr->qindex_delta[mi->segment_id], 0, MAXQ), - cr->last_coded_q_map[map_offset]); - } - } -} - -// From the just encoded frame: update the actual number of blocks that were -// applied the segment delta q, and the amount of low motion in the frame. -// Also check conditions for forcing golden update, or preventing golden -// update if the period is up. -void vp9_cyclic_refresh_postencode(VP9_COMP *const cpi) { - VP9_COMMON *const cm = &cpi->common; - MODE_INFO **mi = cm->mi_grid_visible; - CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; - RATE_CONTROL *const rc = &cpi->rc; - unsigned char *const seg_map = cpi->segmentation_map; - double fraction_low = 0.0; - int force_gf_refresh = 0; - int low_content_frame = 0; - int mi_row, mi_col; - cr->actual_num_seg1_blocks = 0; - cr->actual_num_seg2_blocks = 0; - for (mi_row = 0; mi_row < cm->mi_rows; mi_row++) { - for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) { - MV mv = mi[0]->mv[0].as_mv; - int map_index = mi_row * cm->mi_cols + mi_col; - if (cyclic_refresh_segment_id(seg_map[map_index]) == CR_SEGMENT_ID_BOOST1) - cr->actual_num_seg1_blocks++; - else if (cyclic_refresh_segment_id(seg_map[map_index]) == - CR_SEGMENT_ID_BOOST2) - cr->actual_num_seg2_blocks++; - // Accumulate low_content_frame. - if (is_inter_block(mi[0]) && abs(mv.row) < 16 && abs(mv.col) < 16) - low_content_frame++; - mi++; - } - mi += 8; - } - // Check for golden frame update: only for non-SVC and non-golden boost. - if (!cpi->use_svc && cpi->ext_refresh_frame_flags_pending == 0 && - !cpi->oxcf.gf_cbr_boost_pct) { - // Force this frame as a golden update frame if this frame changes the - // resolution (resize_pending != 0). - if (cpi->resize_pending != 0) { - vp9_cyclic_refresh_set_golden_update(cpi); - rc->frames_till_gf_update_due = rc->baseline_gf_interval; - if (rc->frames_till_gf_update_due > rc->frames_to_key) - rc->frames_till_gf_update_due = rc->frames_to_key; - cpi->refresh_golden_frame = 1; - force_gf_refresh = 1; - } - // Update average of low content/motion in the frame. - fraction_low = (double)low_content_frame / (cm->mi_rows * cm->mi_cols); - cr->low_content_avg = (fraction_low + 3 * cr->low_content_avg) / 4; - if (!force_gf_refresh && cpi->refresh_golden_frame == 1 && - rc->frames_since_key > rc->frames_since_golden + 1) { - // Don't update golden reference if the amount of low_content for the - // current encoded frame is small, or if the recursive average of the - // low_content over the update interval window falls below threshold. - if (fraction_low < 0.65 || cr->low_content_avg < 0.6) { - cpi->refresh_golden_frame = 0; - } - // Reset for next internal. - cr->low_content_avg = fraction_low; - } - } -} - -// Set golden frame update interval, for non-svc 1 pass CBR mode. -void vp9_cyclic_refresh_set_golden_update(VP9_COMP *const cpi) { - RATE_CONTROL *const rc = &cpi->rc; - CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; - // Set minimum gf_interval for GF update to a multiple of the refresh period, - // with some max limit. Depending on past encoding stats, GF flag may be - // reset and update may not occur until next baseline_gf_interval. - if (cr->percent_refresh > 0) - rc->baseline_gf_interval = VPXMIN(4 * (100 / cr->percent_refresh), 40); - else - rc->baseline_gf_interval = 40; - if (cpi->oxcf.rc_mode == VPX_VBR) rc->baseline_gf_interval = 20; - if (rc->avg_frame_low_motion < 50 && rc->frames_since_key > 40 && - cr->content_mode) - rc->baseline_gf_interval = 10; -} - -static int is_superblock_flat_static(VP9_COMP *const cpi, int sb_row_index, - int sb_col_index) { - unsigned int source_variance; - const uint8_t *src_y = cpi->Source->y_buffer; - const int ystride = cpi->Source->y_stride; - unsigned int sse; - const BLOCK_SIZE bsize = BLOCK_64X64; - src_y += (sb_row_index << 6) * ystride + (sb_col_index << 6); - source_variance = - cpi->fn_ptr[bsize].vf(src_y, ystride, VP9_VAR_OFFS, 0, &sse); - if (source_variance == 0) { - uint64_t block_sad; - const uint8_t *last_src_y = cpi->Last_Source->y_buffer; - const int last_ystride = cpi->Last_Source->y_stride; - last_src_y += (sb_row_index << 6) * ystride + (sb_col_index << 6); - block_sad = - cpi->fn_ptr[bsize].sdf(src_y, ystride, last_src_y, last_ystride); - if (block_sad == 0) return 1; - } - return 0; -} - -// Update the segmentation map, and related quantities: cyclic refresh map, -// refresh sb_index, and target number of blocks to be refreshed. -// The map is set to either 0/CR_SEGMENT_ID_BASE (no refresh) or to -// 1/CR_SEGMENT_ID_BOOST1 (refresh) for each superblock. -// Blocks labeled as BOOST1 may later get set to BOOST2 (during the -// encoding of the superblock). -static void cyclic_refresh_update_map(VP9_COMP *const cpi) { - VP9_COMMON *const cm = &cpi->common; - CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; - unsigned char *const seg_map = cpi->segmentation_map; - int i, block_count, bl_index, sb_rows, sb_cols, sbs_in_frame; - int xmis, ymis, x, y; - int consec_zero_mv_thresh = 0; - int qindex_thresh = 0; - int count_sel = 0; - int count_tot = 0; - memset(seg_map, CR_SEGMENT_ID_BASE, cm->mi_rows * cm->mi_cols); - sb_cols = (cm->mi_cols + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE; - sb_rows = (cm->mi_rows + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE; - sbs_in_frame = sb_cols * sb_rows; - // Number of target blocks to get the q delta (segment 1). - block_count = cr->percent_refresh * cm->mi_rows * cm->mi_cols / 100; - // Set the segmentation map: cycle through the superblocks, starting at - // cr->mb_index, and stopping when either block_count blocks have been found - // to be refreshed, or we have passed through whole frame. - assert(cr->sb_index < sbs_in_frame); - i = cr->sb_index; - cr->target_num_seg_blocks = 0; - if (cpi->oxcf.content != VP9E_CONTENT_SCREEN) { - consec_zero_mv_thresh = 100; - } - qindex_thresh = - cpi->oxcf.content == VP9E_CONTENT_SCREEN - ? vp9_get_qindex(&cm->seg, CR_SEGMENT_ID_BOOST2, cm->base_qindex) - : vp9_get_qindex(&cm->seg, CR_SEGMENT_ID_BOOST1, cm->base_qindex); - // More aggressive settings for noisy content. - if (cpi->noise_estimate.enabled && cpi->noise_estimate.level >= kMedium && - cr->content_mode) { - consec_zero_mv_thresh = 60; - qindex_thresh = - VPXMAX(vp9_get_qindex(&cm->seg, CR_SEGMENT_ID_BOOST1, cm->base_qindex), - cm->base_qindex); - } - do { - int sum_map = 0; - int consec_zero_mv_thresh_block = consec_zero_mv_thresh; - // Get the mi_row/mi_col corresponding to superblock index i. - int sb_row_index = (i / sb_cols); - int sb_col_index = i - sb_row_index * sb_cols; - int mi_row = sb_row_index * MI_BLOCK_SIZE; - int mi_col = sb_col_index * MI_BLOCK_SIZE; - int flat_static_blocks = 0; - int compute_content = 1; - assert(mi_row >= 0 && mi_row < cm->mi_rows); - assert(mi_col >= 0 && mi_col < cm->mi_cols); -#if CONFIG_VP9_HIGHBITDEPTH - if (cpi->common.use_highbitdepth) compute_content = 0; -#endif - if (cr->content_mode == 0 || cpi->Last_Source == NULL || - cpi->Last_Source->y_width != cpi->Source->y_width || - cpi->Last_Source->y_height != cpi->Source->y_height) - compute_content = 0; - bl_index = mi_row * cm->mi_cols + mi_col; - // Loop through all 8x8 blocks in superblock and update map. - xmis = - VPXMIN(cm->mi_cols - mi_col, num_8x8_blocks_wide_lookup[BLOCK_64X64]); - ymis = - VPXMIN(cm->mi_rows - mi_row, num_8x8_blocks_high_lookup[BLOCK_64X64]); - if (cpi->noise_estimate.enabled && cpi->noise_estimate.level >= kMedium && - (xmis <= 2 || ymis <= 2)) - consec_zero_mv_thresh_block = 4; - for (y = 0; y < ymis; y++) { - for (x = 0; x < xmis; x++) { - const int bl_index2 = bl_index + y * cm->mi_cols + x; - // If the block is as a candidate for clean up then mark it - // for possible boost/refresh (segment 1). The segment id may get - // reset to 0 later depending on the coding mode. - if (cr->map[bl_index2] == 0) { - count_tot++; - if (cr->content_mode == 0 || - cr->last_coded_q_map[bl_index2] > qindex_thresh || - cpi->consec_zero_mv[bl_index2] < consec_zero_mv_thresh_block) { - sum_map++; - count_sel++; - } - } else if (cr->map[bl_index2] < 0) { - cr->map[bl_index2]++; - } - } - } - // Enforce constant segment over superblock. - // If segment is at least half of superblock, set to 1. - if (sum_map >= xmis * ymis / 2) { - // This superblock is a candidate for refresh: - // compute spatial variance and exclude blocks that are spatially flat - // and stationary. Note: this is currently only done for screne content - // mode. - if (compute_content && cr->skip_flat_static_blocks) - flat_static_blocks = - is_superblock_flat_static(cpi, sb_row_index, sb_col_index); - if (!flat_static_blocks) { - // Label this superblock as segment 1. - for (y = 0; y < ymis; y++) - for (x = 0; x < xmis; x++) { - seg_map[bl_index + y * cm->mi_cols + x] = CR_SEGMENT_ID_BOOST1; - } - cr->target_num_seg_blocks += xmis * ymis; - } - } - i++; - if (i == sbs_in_frame) { - i = 0; - } - } while (cr->target_num_seg_blocks < block_count && i != cr->sb_index); - cr->sb_index = i; - cr->reduce_refresh = 0; - if (cpi->oxcf.content != VP9E_CONTENT_SCREEN) - if (count_sel < (3 * count_tot) >> 2) cr->reduce_refresh = 1; -} - -// Set cyclic refresh parameters. -void vp9_cyclic_refresh_update_parameters(VP9_COMP *const cpi) { - const RATE_CONTROL *const rc = &cpi->rc; - const VP9_COMMON *const cm = &cpi->common; - CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; - int num8x8bl = cm->MBs << 2; - int target_refresh = 0; - double weight_segment_target = 0; - double weight_segment = 0; - int thresh_low_motion = 20; - int qp_thresh = VPXMIN((cpi->oxcf.content == VP9E_CONTENT_SCREEN) ? 35 : 20, - rc->best_quality << 1); - int qp_max_thresh = 117 * MAXQ >> 7; - cr->apply_cyclic_refresh = 1; - if (frame_is_intra_only(cm) || cpi->svc.temporal_layer_id > 0 || - is_lossless_requested(&cpi->oxcf) || - rc->avg_frame_qindex[INTER_FRAME] < qp_thresh || - (cpi->use_svc && - cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame) || - (!cpi->use_svc && cr->content_mode && - rc->avg_frame_low_motion < thresh_low_motion && - rc->frames_since_key > 40) || - (!cpi->use_svc && rc->avg_frame_qindex[INTER_FRAME] > qp_max_thresh && - rc->frames_since_key > 20) || - (cpi->roi.enabled && cpi->roi.skip[BACKGROUND_SEG_SKIP_ID] && - rc->frames_since_key > FRAMES_NO_SKIPPING_AFTER_KEY)) { - cr->apply_cyclic_refresh = 0; - return; - } - cr->percent_refresh = 10; - if (cr->reduce_refresh) cr->percent_refresh = 5; - cr->max_qdelta_perc = 60; - cr->time_for_refresh = 0; - cr->motion_thresh = 32; - cr->rate_boost_fac = 15; - // Use larger delta-qp (increase rate_ratio_qdelta) for first few (~4) - // periods of the refresh cycle, after a key frame. - // Account for larger interval on base layer for temporal layers. - if (cr->percent_refresh > 0 && - rc->frames_since_key < - (4 * cpi->svc.number_temporal_layers) * (100 / cr->percent_refresh)) { - cr->rate_ratio_qdelta = 3.0; - } else { - cr->rate_ratio_qdelta = 2.0; - if (cr->content_mode && cpi->noise_estimate.enabled && - cpi->noise_estimate.level >= kMedium) { - // Reduce the delta-qp if the estimated source noise is above threshold. - cr->rate_ratio_qdelta = 1.7; - cr->rate_boost_fac = 13; - } - } - // For screen-content: keep rate_ratio_qdelta to 2.0 (segment#1 boost) and - // percent_refresh (refresh rate) to 10. But reduce rate boost for segment#2 - // (rate_boost_fac = 10 disables segment#2). - if (cpi->oxcf.content == VP9E_CONTENT_SCREEN) { - // Only enable feature of skipping flat_static blocks for top layer - // under screen content mode. - if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) - cr->skip_flat_static_blocks = 1; - cr->percent_refresh = (cr->skip_flat_static_blocks) ? 5 : 10; - // Increase the amount of refresh on scene change that is encoded at max Q, - // increase for a few cycles of the refresh period (~100 / percent_refresh). - if (cr->content_mode && cr->counter_encode_maxq_scene_change < 30) - cr->percent_refresh = (cr->skip_flat_static_blocks) ? 10 : 15; - cr->rate_ratio_qdelta = 2.0; - cr->rate_boost_fac = 10; - } - // Adjust some parameters for low resolutions. - if (cm->width * cm->height <= 352 * 288) { - if (rc->avg_frame_bandwidth < 3000) { - cr->motion_thresh = 64; - cr->rate_boost_fac = 13; - } else { - cr->max_qdelta_perc = 70; - cr->rate_ratio_qdelta = VPXMAX(cr->rate_ratio_qdelta, 2.5); - } - } - if (cpi->oxcf.rc_mode == VPX_VBR) { - // To be adjusted for VBR mode, e.g., based on gf period and boost. - // For now use smaller qp-delta (than CBR), no second boosted seg, and - // turn-off (no refresh) on golden refresh (since it's already boosted). - cr->percent_refresh = 10; - cr->rate_ratio_qdelta = 1.5; - cr->rate_boost_fac = 10; - if (cpi->refresh_golden_frame == 1 && !cpi->use_svc) { - cr->percent_refresh = 0; - cr->rate_ratio_qdelta = 1.0; - } - } - // Weight for segment prior to encoding: take the average of the target - // number for the frame to be encoded and the actual from the previous frame. - // Use the target if its less. To be used for setting the base qp for the - // frame in vp9_rc_regulate_q. - target_refresh = cr->percent_refresh * cm->mi_rows * cm->mi_cols / 100; - weight_segment_target = (double)(target_refresh) / num8x8bl; - weight_segment = (double)((target_refresh + cr->actual_num_seg1_blocks + - cr->actual_num_seg2_blocks) >> - 1) / - num8x8bl; - if (weight_segment_target < 7 * weight_segment / 8) - weight_segment = weight_segment_target; - // For screen-content: don't include target for the weight segment, - // since for all flat areas the segment is reset, so its more accurate - // to just use the previous actual number of seg blocks for the weight. - if (cpi->oxcf.content == VP9E_CONTENT_SCREEN) - weight_segment = - (double)(cr->actual_num_seg1_blocks + cr->actual_num_seg2_blocks) / - num8x8bl; - cr->weight_segment = weight_segment; - if (cr->content_mode == 0) { - cr->actual_num_seg1_blocks = - cr->percent_refresh * cm->mi_rows * cm->mi_cols / 100; - cr->actual_num_seg2_blocks = 0; - cr->weight_segment = (double)(cr->actual_num_seg1_blocks) / num8x8bl; - } -} - -// Setup cyclic background refresh: set delta q and segmentation map. -void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) { - VP9_COMMON *const cm = &cpi->common; - const RATE_CONTROL *const rc = &cpi->rc; - CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; - struct segmentation *const seg = &cm->seg; - int scene_change_detected = - cpi->rc.high_source_sad || - (cpi->use_svc && cpi->svc.high_source_sad_superframe); - if (cm->current_video_frame == 0) cr->low_content_avg = 0.0; - // Reset if resoluton change has occurred. - if (cpi->resize_pending != 0) vp9_cyclic_refresh_reset_resize(cpi); - if (!cr->apply_cyclic_refresh || (cpi->force_update_segmentation) || - scene_change_detected) { - // Set segmentation map to 0 and disable. - unsigned char *const seg_map = cpi->segmentation_map; - memset(seg_map, 0, cm->mi_rows * cm->mi_cols); - vp9_disable_segmentation(&cm->seg); - if (cm->frame_type == KEY_FRAME || scene_change_detected) { - memset(cr->last_coded_q_map, MAXQ, - cm->mi_rows * cm->mi_cols * sizeof(*cr->last_coded_q_map)); - cr->sb_index = 0; - cr->reduce_refresh = 0; - cr->counter_encode_maxq_scene_change = 0; - } - return; - } else { - int qindex_delta = 0; - int qindex2; - const double q = vp9_convert_qindex_to_q(cm->base_qindex, cm->bit_depth); - cr->counter_encode_maxq_scene_change++; - vpx_clear_system_state(); - // Set rate threshold to some multiple (set to 2 for now) of the target - // rate (target is given by sb64_target_rate and scaled by 256). - cr->thresh_rate_sb = ((int64_t)(rc->sb64_target_rate) << 8) << 2; - // Distortion threshold, quadratic in Q, scale factor to be adjusted. - // q will not exceed 457, so (q * q) is within 32bit; see: - // vp9_convert_qindex_to_q(), vp9_ac_quant(), ac_qlookup*[]. - cr->thresh_dist_sb = ((int64_t)(q * q)) << 2; - - // Set up segmentation. - // Clear down the segment map. - vp9_enable_segmentation(&cm->seg); - vp9_clearall_segfeatures(seg); - // Select delta coding method. - seg->abs_delta = SEGMENT_DELTADATA; - - // Note: setting temporal_update has no effect, as the seg-map coding method - // (temporal or spatial) is determined in vp9_choose_segmap_coding_method(), - // based on the coding cost of each method. For error_resilient mode on the - // last_frame_seg_map is set to 0, so if temporal coding is used, it is - // relative to 0 previous map. - // seg->temporal_update = 0; - - // Segment BASE "Q" feature is disabled so it defaults to the baseline Q. - vp9_disable_segfeature(seg, CR_SEGMENT_ID_BASE, SEG_LVL_ALT_Q); - // Use segment BOOST1 for in-frame Q adjustment. - vp9_enable_segfeature(seg, CR_SEGMENT_ID_BOOST1, SEG_LVL_ALT_Q); - // Use segment BOOST2 for more aggressive in-frame Q adjustment. - vp9_enable_segfeature(seg, CR_SEGMENT_ID_BOOST2, SEG_LVL_ALT_Q); - - // Set the q delta for segment BOOST1. - qindex_delta = compute_deltaq(cpi, cm->base_qindex, cr->rate_ratio_qdelta); - cr->qindex_delta[1] = qindex_delta; - - // Compute rd-mult for segment BOOST1. - qindex2 = clamp(cm->base_qindex + cm->y_dc_delta_q + qindex_delta, 0, MAXQ); - - cr->rdmult = vp9_compute_rd_mult(cpi, qindex2); - - vp9_set_segdata(seg, CR_SEGMENT_ID_BOOST1, SEG_LVL_ALT_Q, qindex_delta); - - // Set a more aggressive (higher) q delta for segment BOOST2. - qindex_delta = compute_deltaq( - cpi, cm->base_qindex, - VPXMIN(CR_MAX_RATE_TARGET_RATIO, - 0.1 * cr->rate_boost_fac * cr->rate_ratio_qdelta)); - cr->qindex_delta[2] = qindex_delta; - vp9_set_segdata(seg, CR_SEGMENT_ID_BOOST2, SEG_LVL_ALT_Q, qindex_delta); - - // Update the segmentation and refresh map. - cyclic_refresh_update_map(cpi); - } -} - -int vp9_cyclic_refresh_get_rdmult(const CYCLIC_REFRESH *cr) { - return cr->rdmult; -} - -void vp9_cyclic_refresh_reset_resize(VP9_COMP *const cpi) { - const VP9_COMMON *const cm = &cpi->common; - CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; - memset(cr->map, 0, cm->mi_rows * cm->mi_cols); - memset(cr->last_coded_q_map, MAXQ, - cm->mi_rows * cm->mi_cols * sizeof(*cr->last_coded_q_map)); - cr->sb_index = 0; - cpi->refresh_golden_frame = 1; - cpi->refresh_alt_ref_frame = 1; - cr->counter_encode_maxq_scene_change = 0; -} - -void vp9_cyclic_refresh_limit_q(const VP9_COMP *cpi, int *q) { - CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; - // For now apply hard limit to frame-level decrease in q, if the cyclic - // refresh is active (percent_refresh > 0). - if (cr->percent_refresh > 0 && cpi->rc.q_1_frame - *q > 8) { - *q = cpi->rc.q_1_frame - 8; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_cyclicrefresh.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_cyclicrefresh.h deleted file mode 100644 index c74cee47..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_cyclicrefresh.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_AQ_CYCLICREFRESH_H_ -#define VPX_VP9_ENCODER_VP9_AQ_CYCLICREFRESH_H_ - -#include "vpx/vpx_integer.h" -#include "vp9/common/vp9_blockd.h" -#include "vp9/encoder/vp9_block.h" -#include "vp9/encoder/vp9_skin_detection.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// The segment ids used in cyclic refresh: from base (no boost) to increasing -// boost (higher delta-qp). -#define CR_SEGMENT_ID_BASE 0 -#define CR_SEGMENT_ID_BOOST1 1 -#define CR_SEGMENT_ID_BOOST2 2 - -// Maximum rate target ratio for setting segment delta-qp. -#define CR_MAX_RATE_TARGET_RATIO 4.0 - -struct CYCLIC_REFRESH { - // Percentage of blocks per frame that are targeted as candidates - // for cyclic refresh. - int percent_refresh; - // Maximum q-delta as percentage of base q. - int max_qdelta_perc; - // Superblock starting index for cycling through the frame. - int sb_index; - // Controls how long block will need to wait to be refreshed again, in - // excess of the cycle time, i.e., in the case of all zero motion, block - // will be refreshed every (100/percent_refresh + time_for_refresh) frames. - int time_for_refresh; - // Target number of (8x8) blocks that are set for delta-q. - int target_num_seg_blocks; - // Actual number of (8x8) blocks that were applied delta-q. - int actual_num_seg1_blocks; - int actual_num_seg2_blocks; - // RD mult. parameters for segment 1. - int rdmult; - // Cyclic refresh map. - signed char *map; - // Map of the last q a block was coded at. - uint8_t *last_coded_q_map; - // Thresholds applied to the projected rate/distortion of the coding block, - // when deciding whether block should be refreshed. - int64_t thresh_rate_sb; - int64_t thresh_dist_sb; - // Threshold applied to the motion vector (in units of 1/8 pel) of the - // coding block, when deciding whether block should be refreshed. - int16_t motion_thresh; - // Rate target ratio to set q delta. - double rate_ratio_qdelta; - // Boost factor for rate target ratio, for segment CR_SEGMENT_ID_BOOST2. - int rate_boost_fac; - double low_content_avg; - int qindex_delta[3]; - int reduce_refresh; - double weight_segment; - int apply_cyclic_refresh; - int counter_encode_maxq_scene_change; - int skip_flat_static_blocks; - int content_mode; -}; - -struct VP9_COMP; - -typedef struct CYCLIC_REFRESH CYCLIC_REFRESH; - -CYCLIC_REFRESH *vp9_cyclic_refresh_alloc(int mi_rows, int mi_cols); - -void vp9_cyclic_refresh_free(CYCLIC_REFRESH *cr); - -// Estimate the bits, incorporating the delta-q from segment 1, after encoding -// the frame. -int vp9_cyclic_refresh_estimate_bits_at_q(const struct VP9_COMP *cpi, - double correction_factor); - -// Estimate the bits per mb, for a given q = i and a corresponding delta-q -// (for segment 1), prior to encoding the frame. -int vp9_cyclic_refresh_rc_bits_per_mb(const struct VP9_COMP *cpi, int i, - double correction_factor); - -// Prior to coding a given prediction block, of size bsize at (mi_row, mi_col), -// check if we should reset the segment_id, and update the cyclic_refresh map -// and segmentation map. -void vp9_cyclic_refresh_update_segment(struct VP9_COMP *const cpi, - MODE_INFO *const mi, int mi_row, - int mi_col, BLOCK_SIZE bsize, - int64_t rate, int64_t dist, int skip, - struct macroblock_plane *const p); - -void vp9_cyclic_refresh_update_sb_postencode(struct VP9_COMP *const cpi, - const MODE_INFO *const mi, - int mi_row, int mi_col, - BLOCK_SIZE bsize); - -// From the just encoded frame: update the actual number of blocks that were -// applied the segment delta q, and the amount of low motion in the frame. -// Also check conditions for forcing golden update, or preventing golden -// update if the period is up. -void vp9_cyclic_refresh_postencode(struct VP9_COMP *const cpi); - -// Set golden frame update interval, for non-svc 1 pass CBR mode. -void vp9_cyclic_refresh_set_golden_update(struct VP9_COMP *const cpi); - -// Set/update global/frame level refresh parameters. -void vp9_cyclic_refresh_update_parameters(struct VP9_COMP *const cpi); - -// Setup cyclic background refresh: set delta q and segmentation map. -void vp9_cyclic_refresh_setup(struct VP9_COMP *const cpi); - -int vp9_cyclic_refresh_get_rdmult(const CYCLIC_REFRESH *cr); - -void vp9_cyclic_refresh_reset_resize(struct VP9_COMP *const cpi); - -static INLINE int cyclic_refresh_segment_id_boosted(int segment_id) { - return segment_id == CR_SEGMENT_ID_BOOST1 || - segment_id == CR_SEGMENT_ID_BOOST2; -} - -static INLINE int cyclic_refresh_segment_id(int segment_id) { - if (segment_id == CR_SEGMENT_ID_BOOST1) - return CR_SEGMENT_ID_BOOST1; - else if (segment_id == CR_SEGMENT_ID_BOOST2) - return CR_SEGMENT_ID_BOOST2; - else - return CR_SEGMENT_ID_BASE; -} - -void vp9_cyclic_refresh_limit_q(const struct VP9_COMP *cpi, int *q); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_AQ_CYCLICREFRESH_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_variance.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_variance.c deleted file mode 100644 index 9e5f3bfb..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_variance.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "vpx_ports/mem.h" -#include "vpx_ports/system_state.h" - -#include "vp9/encoder/vp9_aq_variance.h" - -#include "vp9/common/vp9_seg_common.h" - -#include "vp9/encoder/vp9_ratectrl.h" -#include "vp9/encoder/vp9_rd.h" -#include "vp9/encoder/vp9_encodeframe.h" -#include "vp9/encoder/vp9_segmentation.h" - -#define ENERGY_MIN (-4) -#define ENERGY_MAX (1) -#define ENERGY_SPAN (ENERGY_MAX - ENERGY_MIN + 1) -#define ENERGY_IN_BOUNDS(energy) \ - assert((energy) >= ENERGY_MIN && (energy) <= ENERGY_MAX) - -static const double rate_ratio[MAX_SEGMENTS] = { 2.5, 2.0, 1.5, 1.0, - 0.75, 1.0, 1.0, 1.0 }; -static const int segment_id[ENERGY_SPAN] = { 0, 1, 1, 2, 3, 4 }; - -#define SEGMENT_ID(i) segment_id[(i)-ENERGY_MIN] - -DECLARE_ALIGNED(16, static const uint8_t, vp9_64_zeros[64]) = { 0 }; -#if CONFIG_VP9_HIGHBITDEPTH -DECLARE_ALIGNED(16, static const uint16_t, vp9_highbd_64_zeros[64]) = { 0 }; -#endif - -unsigned int vp9_vaq_segment_id(int energy) { - ENERGY_IN_BOUNDS(energy); - return SEGMENT_ID(energy); -} - -void vp9_vaq_frame_setup(VP9_COMP *cpi) { - VP9_COMMON *cm = &cpi->common; - struct segmentation *seg = &cm->seg; - int i; - - if (frame_is_intra_only(cm) || cm->error_resilient_mode || - cpi->refresh_alt_ref_frame || cpi->force_update_segmentation || - (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref)) { - vp9_enable_segmentation(seg); - vp9_clearall_segfeatures(seg); - - seg->abs_delta = SEGMENT_DELTADATA; - - vpx_clear_system_state(); - - for (i = 0; i < MAX_SEGMENTS; ++i) { - int qindex_delta = - vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, cm->base_qindex, - rate_ratio[i], cm->bit_depth); - - // We don't allow qindex 0 in a segment if the base value is not 0. - // Q index 0 (lossless) implies 4x4 encoding only and in AQ mode a segment - // Q delta is sometimes applied without going back around the rd loop. - // This could lead to an illegal combination of partition size and q. - if ((cm->base_qindex != 0) && ((cm->base_qindex + qindex_delta) == 0)) { - qindex_delta = -cm->base_qindex + 1; - } - - // No need to enable SEG_LVL_ALT_Q for this segment. - if (rate_ratio[i] == 1.0) { - continue; - } - - vp9_set_segdata(seg, i, SEG_LVL_ALT_Q, qindex_delta); - vp9_enable_segfeature(seg, i, SEG_LVL_ALT_Q); - } - } -} - -/* TODO(agrange, paulwilkins): The block_variance calls the unoptimized versions - * of variance() and highbd_8_variance(). It should not. - */ -static void aq_variance(const uint8_t *a, int a_stride, const uint8_t *b, - int b_stride, int w, int h, unsigned int *sse, - int *sum) { - int i, j; - - *sum = 0; - *sse = 0; - - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - const int diff = a[j] - b[j]; - *sum += diff; - *sse += diff * diff; - } - - a += a_stride; - b += b_stride; - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -static void aq_highbd_variance64(const uint8_t *a8, int a_stride, - const uint8_t *b8, int b_stride, int w, int h, - uint64_t *sse, int64_t *sum) { - int i, j; - - uint16_t *a = CONVERT_TO_SHORTPTR(a8); - uint16_t *b = CONVERT_TO_SHORTPTR(b8); - *sum = 0; - *sse = 0; - - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - const int diff = a[j] - b[j]; - *sum += diff; - *sse += diff * diff; - } - a += a_stride; - b += b_stride; - } -} - -#endif // CONFIG_VP9_HIGHBITDEPTH - -static unsigned int block_variance(VP9_COMP *cpi, MACROBLOCK *x, - BLOCK_SIZE bs) { - MACROBLOCKD *xd = &x->e_mbd; - unsigned int var, sse; - int right_overflow = - (xd->mb_to_right_edge < 0) ? ((-xd->mb_to_right_edge) >> 3) : 0; - int bottom_overflow = - (xd->mb_to_bottom_edge < 0) ? ((-xd->mb_to_bottom_edge) >> 3) : 0; - - if (right_overflow || bottom_overflow) { - const int bw = 8 * num_8x8_blocks_wide_lookup[bs] - right_overflow; - const int bh = 8 * num_8x8_blocks_high_lookup[bs] - bottom_overflow; - int avg; -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - uint64_t sse64 = 0; - int64_t sum64 = 0; - aq_highbd_variance64(x->plane[0].src.buf, x->plane[0].src.stride, - CONVERT_TO_BYTEPTR(vp9_highbd_64_zeros), 0, bw, bh, - &sse64, &sum64); - sse = (unsigned int)(sse64 >> (2 * (xd->bd - 8))); - avg = (int)(sum64 >> (xd->bd - 8)); - } else { - aq_variance(x->plane[0].src.buf, x->plane[0].src.stride, vp9_64_zeros, 0, - bw, bh, &sse, &avg); - } -#else - aq_variance(x->plane[0].src.buf, x->plane[0].src.stride, vp9_64_zeros, 0, - bw, bh, &sse, &avg); -#endif // CONFIG_VP9_HIGHBITDEPTH - var = sse - (unsigned int)(((int64_t)avg * avg) / (bw * bh)); - return (unsigned int)(((uint64_t)256 * var) / (bw * bh)); - } else { -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - var = - cpi->fn_ptr[bs].vf(x->plane[0].src.buf, x->plane[0].src.stride, - CONVERT_TO_BYTEPTR(vp9_highbd_64_zeros), 0, &sse); - } else { - var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf, x->plane[0].src.stride, - vp9_64_zeros, 0, &sse); - } -#else - var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf, x->plane[0].src.stride, - vp9_64_zeros, 0, &sse); -#endif // CONFIG_VP9_HIGHBITDEPTH - return (unsigned int)(((uint64_t)256 * var) >> num_pels_log2_lookup[bs]); - } -} - -double vp9_log_block_var(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs) { - unsigned int var = block_variance(cpi, x, bs); - vpx_clear_system_state(); - return log(var + 1.0); -} - -#define DEFAULT_E_MIDPOINT 10.0 -static int scale_block_energy(VP9_COMP *cpi, unsigned int block_var) { - double energy; - double energy_midpoint; - energy_midpoint = - (cpi->oxcf.pass == 2) ? cpi->twopass.mb_av_energy : DEFAULT_E_MIDPOINT; - energy = log(block_var + 1.0) - energy_midpoint; - return clamp((int)round(energy), ENERGY_MIN, ENERGY_MAX); -} -#undef DEFAULT_E_MIDPOINT - -// Get the range of sub block energy values; -void vp9_get_sub_block_energy(VP9_COMP *cpi, MACROBLOCK *mb, int mi_row, - int mi_col, BLOCK_SIZE bsize, int *min_e, - int *max_e) { - VP9_COMMON *const cm = &cpi->common; - const int bw = num_8x8_blocks_wide_lookup[bsize]; - const int bh = num_8x8_blocks_high_lookup[bsize]; - const int xmis = VPXMIN(cm->mi_cols - mi_col, bw); - const int ymis = VPXMIN(cm->mi_rows - mi_row, bh); - int x, y; - - if (xmis < bw || ymis < bh) { - vp9_setup_src_planes(mb, cpi->Source, mi_row, mi_col); - *min_e = vp9_block_energy(cpi, mb, bsize); - *max_e = *min_e; - } else { - unsigned int var; - // Because scale_block_energy is non-decreasing, we can find the min/max - // block variance and scale afterwards. This avoids a costly scaling at - // every iteration. - unsigned int min_var = UINT_MAX; - unsigned int max_var = 0; - - for (y = 0; y < ymis; ++y) { - for (x = 0; x < xmis; ++x) { - vp9_setup_src_planes(mb, cpi->Source, mi_row + y, mi_col + x); - vpx_clear_system_state(); - var = block_variance(cpi, mb, BLOCK_8X8); - vpx_clear_system_state(); - min_var = VPXMIN(min_var, var); - max_var = VPXMAX(max_var, var); - } - } - *min_e = scale_block_energy(cpi, min_var); - *max_e = scale_block_energy(cpi, max_var); - } - - // Re-instate source pointers back to what they should have been on entry. - vp9_setup_src_planes(mb, cpi->Source, mi_row, mi_col); -} - -int vp9_block_energy(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs) { - unsigned int var; - vpx_clear_system_state(); - var = block_variance(cpi, x, bs); - vpx_clear_system_state(); - return scale_block_energy(cpi, var); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_variance.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_variance.h deleted file mode 100644 index a4f87287..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_aq_variance.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_AQ_VARIANCE_H_ -#define VPX_VP9_ENCODER_VP9_AQ_VARIANCE_H_ - -#include "vp9/encoder/vp9_encoder.h" - -#ifdef __cplusplus -extern "C" { -#endif - -unsigned int vp9_vaq_segment_id(int energy); -void vp9_vaq_frame_setup(VP9_COMP *cpi); - -void vp9_get_sub_block_energy(VP9_COMP *cpi, MACROBLOCK *mb, int mi_row, - int mi_col, BLOCK_SIZE bsize, int *min_e, - int *max_e); -int vp9_block_energy(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs); - -double vp9_log_block_var(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_AQ_VARIANCE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_bitstream.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_bitstream.c deleted file mode 100644 index be342712..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_bitstream.c +++ /dev/null @@ -1,1464 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "vpx/vpx_encoder.h" -#include "vpx_dsp/bitwriter_buffer.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem_ops.h" -#include "vpx_ports/system_state.h" -#if CONFIG_BITSTREAM_DEBUG -#include "vpx_util/vpx_debug_util.h" -#endif // CONFIG_BITSTREAM_DEBUG - -#include "vp9/common/vp9_entropy.h" -#include "vp9/common/vp9_entropymode.h" -#include "vp9/common/vp9_entropymv.h" -#include "vp9/common/vp9_mvref_common.h" -#include "vp9/common/vp9_pred_common.h" -#include "vp9/common/vp9_seg_common.h" -#include "vp9/common/vp9_tile_common.h" - -#include "vp9/encoder/vp9_cost.h" -#include "vp9/encoder/vp9_bitstream.h" -#include "vp9/encoder/vp9_encodemv.h" -#include "vp9/encoder/vp9_mcomp.h" -#include "vp9/encoder/vp9_segmentation.h" -#include "vp9/encoder/vp9_subexp.h" -#include "vp9/encoder/vp9_tokenize.h" - -static const struct vp9_token intra_mode_encodings[INTRA_MODES] = { - { 0, 1 }, { 6, 3 }, { 28, 5 }, { 30, 5 }, { 58, 6 }, - { 59, 6 }, { 126, 7 }, { 127, 7 }, { 62, 6 }, { 2, 2 } -}; -static const struct vp9_token - switchable_interp_encodings[SWITCHABLE_FILTERS] = { { 0, 1 }, - { 2, 2 }, - { 3, 2 } }; -static const struct vp9_token partition_encodings[PARTITION_TYPES] = { - { 0, 1 }, { 2, 2 }, { 6, 3 }, { 7, 3 } -}; -static const struct vp9_token inter_mode_encodings[INTER_MODES] = { - { 2, 2 }, { 6, 3 }, { 0, 1 }, { 7, 3 } -}; - -static void write_intra_mode(vpx_writer *w, PREDICTION_MODE mode, - const vpx_prob *probs) { - vp9_write_token(w, vp9_intra_mode_tree, probs, &intra_mode_encodings[mode]); -} - -static void write_inter_mode(vpx_writer *w, PREDICTION_MODE mode, - const vpx_prob *probs) { - assert(is_inter_mode(mode)); - vp9_write_token(w, vp9_inter_mode_tree, probs, - &inter_mode_encodings[INTER_OFFSET(mode)]); -} - -static void encode_unsigned_max(struct vpx_write_bit_buffer *wb, int data, - int max) { - vpx_wb_write_literal(wb, data, get_unsigned_bits(max)); -} - -static void prob_diff_update(const vpx_tree_index *tree, - vpx_prob probs[/*n - 1*/], - const unsigned int counts[/*n - 1*/], int n, - vpx_writer *w) { - int i; - unsigned int branch_ct[32][2]; - - // Assuming max number of probabilities <= 32 - assert(n <= 32); - - vp9_tree_probs_from_distribution(tree, branch_ct, counts); - for (i = 0; i < n - 1; ++i) - vp9_cond_prob_diff_update(w, &probs[i], branch_ct[i]); -} - -static void write_selected_tx_size(const VP9_COMMON *cm, - const MACROBLOCKD *const xd, vpx_writer *w) { - TX_SIZE tx_size = xd->mi[0]->tx_size; - BLOCK_SIZE bsize = xd->mi[0]->sb_type; - const TX_SIZE max_tx_size = max_txsize_lookup[bsize]; - const vpx_prob *const tx_probs = - get_tx_probs(max_tx_size, get_tx_size_context(xd), &cm->fc->tx_probs); - vpx_write(w, tx_size != TX_4X4, tx_probs[0]); - if (tx_size != TX_4X4 && max_tx_size >= TX_16X16) { - vpx_write(w, tx_size != TX_8X8, tx_probs[1]); - if (tx_size != TX_8X8 && max_tx_size >= TX_32X32) - vpx_write(w, tx_size != TX_16X16, tx_probs[2]); - } -} - -static int write_skip(const VP9_COMMON *cm, const MACROBLOCKD *const xd, - int segment_id, const MODE_INFO *mi, vpx_writer *w) { - if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) { - return 1; - } else { - const int skip = mi->skip; - vpx_write(w, skip, vp9_get_skip_prob(cm, xd)); - return skip; - } -} - -static void update_skip_probs(VP9_COMMON *cm, vpx_writer *w, - FRAME_COUNTS *counts) { - int k; - - for (k = 0; k < SKIP_CONTEXTS; ++k) - vp9_cond_prob_diff_update(w, &cm->fc->skip_probs[k], counts->skip[k]); -} - -static void update_switchable_interp_probs(VP9_COMMON *cm, vpx_writer *w, - FRAME_COUNTS *counts) { - int j; - for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) - prob_diff_update(vp9_switchable_interp_tree, - cm->fc->switchable_interp_prob[j], - counts->switchable_interp[j], SWITCHABLE_FILTERS, w); -} - -static void pack_mb_tokens(vpx_writer *w, TOKENEXTRA **tp, - const TOKENEXTRA *const stop, - vpx_bit_depth_t bit_depth) { - const TOKENEXTRA *p; - const vp9_extra_bit *const extra_bits = -#if CONFIG_VP9_HIGHBITDEPTH - (bit_depth == VPX_BITS_12) ? vp9_extra_bits_high12 - : (bit_depth == VPX_BITS_10) ? vp9_extra_bits_high10 - : vp9_extra_bits; -#else - vp9_extra_bits; - (void)bit_depth; -#endif // CONFIG_VP9_HIGHBITDEPTH - - for (p = *tp; p < stop && p->token != EOSB_TOKEN; ++p) { - if (p->token == EOB_TOKEN) { - vpx_write(w, 0, p->context_tree[0]); - continue; - } - vpx_write(w, 1, p->context_tree[0]); - while (p->token == ZERO_TOKEN) { - vpx_write(w, 0, p->context_tree[1]); - ++p; - if (p == stop || p->token == EOSB_TOKEN) { - *tp = (TOKENEXTRA *)(uintptr_t)p + (p->token == EOSB_TOKEN); - return; - } - } - - { - const int t = p->token; - const vpx_prob *const context_tree = p->context_tree; - assert(t != ZERO_TOKEN); - assert(t != EOB_TOKEN); - assert(t != EOSB_TOKEN); - vpx_write(w, 1, context_tree[1]); - if (t == ONE_TOKEN) { - vpx_write(w, 0, context_tree[2]); - vpx_write_bit(w, p->extra & 1); - } else { // t >= TWO_TOKEN && t < EOB_TOKEN - const struct vp9_token *const a = &vp9_coef_encodings[t]; - int v = a->value; - int n = a->len; - const int e = p->extra; - vpx_write(w, 1, context_tree[2]); - vp9_write_tree(w, vp9_coef_con_tree, - vp9_pareto8_full[context_tree[PIVOT_NODE] - 1], v, - n - UNCONSTRAINED_NODES, 0); - if (t >= CATEGORY1_TOKEN) { - const vp9_extra_bit *const b = &extra_bits[t]; - const unsigned char *pb = b->prob; - v = e >> 1; - n = b->len; // number of bits in v, assumed nonzero - do { - const int bb = (v >> --n) & 1; - vpx_write(w, bb, *pb++); - } while (n); - } - vpx_write_bit(w, e & 1); - } - } - } - *tp = (TOKENEXTRA *)(uintptr_t)p + (p->token == EOSB_TOKEN); -} - -static void write_segment_id(vpx_writer *w, const struct segmentation *seg, - int segment_id) { - if (seg->enabled && seg->update_map) - vp9_write_tree(w, vp9_segment_tree, seg->tree_probs, segment_id, 3, 0); -} - -// This function encodes the reference frame -static void write_ref_frames(const VP9_COMMON *cm, const MACROBLOCKD *const xd, - vpx_writer *w) { - const MODE_INFO *const mi = xd->mi[0]; - const int is_compound = has_second_ref(mi); - const int segment_id = mi->segment_id; - - // If segment level coding of this signal is disabled... - // or the segment allows multiple reference frame options - if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) { - assert(!is_compound); - assert(mi->ref_frame[0] == - get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME)); - } else { - // does the feature use compound prediction or not - // (if not specified at the frame/segment level) - if (cm->reference_mode == REFERENCE_MODE_SELECT) { - vpx_write(w, is_compound, vp9_get_reference_mode_prob(cm, xd)); - } else { - assert((!is_compound) == (cm->reference_mode == SINGLE_REFERENCE)); - } - - if (is_compound) { - const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref]; - vpx_write(w, mi->ref_frame[!idx] == cm->comp_var_ref[1], - vp9_get_pred_prob_comp_ref_p(cm, xd)); - } else { - const int bit0 = mi->ref_frame[0] != LAST_FRAME; - vpx_write(w, bit0, vp9_get_pred_prob_single_ref_p1(cm, xd)); - if (bit0) { - const int bit1 = mi->ref_frame[0] != GOLDEN_FRAME; - vpx_write(w, bit1, vp9_get_pred_prob_single_ref_p2(cm, xd)); - } - } - } -} - -static void pack_inter_mode_mvs(VP9_COMP *cpi, const MACROBLOCKD *const xd, - const MB_MODE_INFO_EXT *const mbmi_ext, - vpx_writer *w, - unsigned int *const max_mv_magnitude, - int interp_filter_selected[][SWITCHABLE]) { - VP9_COMMON *const cm = &cpi->common; - const nmv_context *nmvc = &cm->fc->nmvc; - const struct segmentation *const seg = &cm->seg; - const MODE_INFO *const mi = xd->mi[0]; - const PREDICTION_MODE mode = mi->mode; - const int segment_id = mi->segment_id; - const BLOCK_SIZE bsize = mi->sb_type; - const int allow_hp = cm->allow_high_precision_mv; - const int is_inter = is_inter_block(mi); - const int is_compound = has_second_ref(mi); - int skip, ref; - - if (seg->update_map) { - if (seg->temporal_update) { - const int pred_flag = mi->seg_id_predicted; - vpx_prob pred_prob = vp9_get_pred_prob_seg_id(seg, xd); - vpx_write(w, pred_flag, pred_prob); - if (!pred_flag) write_segment_id(w, seg, segment_id); - } else { - write_segment_id(w, seg, segment_id); - } - } - - skip = write_skip(cm, xd, segment_id, mi, w); - - if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) - vpx_write(w, is_inter, vp9_get_intra_inter_prob(cm, xd)); - - if (bsize >= BLOCK_8X8 && cm->tx_mode == TX_MODE_SELECT && - !(is_inter && skip)) { - write_selected_tx_size(cm, xd, w); - } - - if (!is_inter) { - if (bsize >= BLOCK_8X8) { - write_intra_mode(w, mode, cm->fc->y_mode_prob[size_group_lookup[bsize]]); - } else { - int idx, idy; - const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; - const int num_4x4_h = num_4x4_blocks_high_lookup[bsize]; - for (idy = 0; idy < 2; idy += num_4x4_h) { - for (idx = 0; idx < 2; idx += num_4x4_w) { - const PREDICTION_MODE b_mode = mi->bmi[idy * 2 + idx].as_mode; - write_intra_mode(w, b_mode, cm->fc->y_mode_prob[0]); - } - } - } - write_intra_mode(w, mi->uv_mode, cm->fc->uv_mode_prob[mode]); - } else { - const int mode_ctx = mbmi_ext->mode_context[mi->ref_frame[0]]; - const vpx_prob *const inter_probs = cm->fc->inter_mode_probs[mode_ctx]; - write_ref_frames(cm, xd, w); - - // If segment skip is not enabled code the mode. - if (!segfeature_active(seg, segment_id, SEG_LVL_SKIP)) { - if (bsize >= BLOCK_8X8) { - write_inter_mode(w, mode, inter_probs); - } - } - - if (cm->interp_filter == SWITCHABLE) { - const int ctx = get_pred_context_switchable_interp(xd); - vp9_write_token(w, vp9_switchable_interp_tree, - cm->fc->switchable_interp_prob[ctx], - &switchable_interp_encodings[mi->interp_filter]); - ++interp_filter_selected[0][mi->interp_filter]; - } else { - assert(mi->interp_filter == cm->interp_filter); - } - - if (bsize < BLOCK_8X8) { - const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; - const int num_4x4_h = num_4x4_blocks_high_lookup[bsize]; - int idx, idy; - for (idy = 0; idy < 2; idy += num_4x4_h) { - for (idx = 0; idx < 2; idx += num_4x4_w) { - const int j = idy * 2 + idx; - const PREDICTION_MODE b_mode = mi->bmi[j].as_mode; - write_inter_mode(w, b_mode, inter_probs); - if (b_mode == NEWMV) { - for (ref = 0; ref < 1 + is_compound; ++ref) - vp9_encode_mv(cpi, w, &mi->bmi[j].as_mv[ref].as_mv, - &mbmi_ext->ref_mvs[mi->ref_frame[ref]][0].as_mv, - nmvc, allow_hp, max_mv_magnitude); - } - } - } - } else { - if (mode == NEWMV) { - for (ref = 0; ref < 1 + is_compound; ++ref) - vp9_encode_mv(cpi, w, &mi->mv[ref].as_mv, - &mbmi_ext->ref_mvs[mi->ref_frame[ref]][0].as_mv, nmvc, - allow_hp, max_mv_magnitude); - } - } - } -} - -static void write_mb_modes_kf(const VP9_COMMON *cm, const MACROBLOCKD *xd, - vpx_writer *w) { - const struct segmentation *const seg = &cm->seg; - const MODE_INFO *const mi = xd->mi[0]; - const MODE_INFO *const above_mi = xd->above_mi; - const MODE_INFO *const left_mi = xd->left_mi; - const BLOCK_SIZE bsize = mi->sb_type; - - if (seg->update_map) write_segment_id(w, seg, mi->segment_id); - - write_skip(cm, xd, mi->segment_id, mi, w); - - if (bsize >= BLOCK_8X8 && cm->tx_mode == TX_MODE_SELECT) - write_selected_tx_size(cm, xd, w); - - if (bsize >= BLOCK_8X8) { - write_intra_mode(w, mi->mode, get_y_mode_probs(mi, above_mi, left_mi, 0)); - } else { - const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; - const int num_4x4_h = num_4x4_blocks_high_lookup[bsize]; - int idx, idy; - - for (idy = 0; idy < 2; idy += num_4x4_h) { - for (idx = 0; idx < 2; idx += num_4x4_w) { - const int block = idy * 2 + idx; - write_intra_mode(w, mi->bmi[block].as_mode, - get_y_mode_probs(mi, above_mi, left_mi, block)); - } - } - } - - write_intra_mode(w, mi->uv_mode, vp9_kf_uv_mode_prob[mi->mode]); -} - -static void write_modes_b(VP9_COMP *cpi, MACROBLOCKD *const xd, - const TileInfo *const tile, vpx_writer *w, - TOKENEXTRA **tok, const TOKENEXTRA *const tok_end, - int mi_row, int mi_col, - unsigned int *const max_mv_magnitude, - int interp_filter_selected[][SWITCHABLE]) { - const VP9_COMMON *const cm = &cpi->common; - const MB_MODE_INFO_EXT *const mbmi_ext = - cpi->td.mb.mbmi_ext_base + (mi_row * cm->mi_cols + mi_col); - MODE_INFO *m; - - xd->mi = cm->mi_grid_visible + (mi_row * cm->mi_stride + mi_col); - m = xd->mi[0]; - - set_mi_row_col(xd, tile, mi_row, num_8x8_blocks_high_lookup[m->sb_type], - mi_col, num_8x8_blocks_wide_lookup[m->sb_type], cm->mi_rows, - cm->mi_cols); - if (frame_is_intra_only(cm)) { - write_mb_modes_kf(cm, xd, w); - } else { - pack_inter_mode_mvs(cpi, xd, mbmi_ext, w, max_mv_magnitude, - interp_filter_selected); - } - - assert(*tok < tok_end); - pack_mb_tokens(w, tok, tok_end, cm->bit_depth); -} - -static void write_partition(const VP9_COMMON *const cm, - const MACROBLOCKD *const xd, int hbs, int mi_row, - int mi_col, PARTITION_TYPE p, BLOCK_SIZE bsize, - vpx_writer *w) { - const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize); - const vpx_prob *const probs = xd->partition_probs[ctx]; - const int has_rows = (mi_row + hbs) < cm->mi_rows; - const int has_cols = (mi_col + hbs) < cm->mi_cols; - - if (has_rows && has_cols) { - vp9_write_token(w, vp9_partition_tree, probs, &partition_encodings[p]); - } else if (!has_rows && has_cols) { - assert(p == PARTITION_SPLIT || p == PARTITION_HORZ); - vpx_write(w, p == PARTITION_SPLIT, probs[1]); - } else if (has_rows && !has_cols) { - assert(p == PARTITION_SPLIT || p == PARTITION_VERT); - vpx_write(w, p == PARTITION_SPLIT, probs[2]); - } else { - assert(p == PARTITION_SPLIT); - } -} - -static void write_modes_sb(VP9_COMP *cpi, MACROBLOCKD *const xd, - const TileInfo *const tile, vpx_writer *w, - TOKENEXTRA **tok, const TOKENEXTRA *const tok_end, - int mi_row, int mi_col, BLOCK_SIZE bsize, - unsigned int *const max_mv_magnitude, - int interp_filter_selected[][SWITCHABLE]) { - const VP9_COMMON *const cm = &cpi->common; - const int bsl = b_width_log2_lookup[bsize]; - const int bs = (1 << bsl) / 4; - PARTITION_TYPE partition; - BLOCK_SIZE subsize; - const MODE_INFO *m = NULL; - - if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - - m = cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col]; - - partition = partition_lookup[bsl][m->sb_type]; - write_partition(cm, xd, bs, mi_row, mi_col, partition, bsize, w); - subsize = get_subsize(bsize, partition); - if (subsize < BLOCK_8X8) { - write_modes_b(cpi, xd, tile, w, tok, tok_end, mi_row, mi_col, - max_mv_magnitude, interp_filter_selected); - } else { - switch (partition) { - case PARTITION_NONE: - write_modes_b(cpi, xd, tile, w, tok, tok_end, mi_row, mi_col, - max_mv_magnitude, interp_filter_selected); - break; - case PARTITION_HORZ: - write_modes_b(cpi, xd, tile, w, tok, tok_end, mi_row, mi_col, - max_mv_magnitude, interp_filter_selected); - if (mi_row + bs < cm->mi_rows) - write_modes_b(cpi, xd, tile, w, tok, tok_end, mi_row + bs, mi_col, - max_mv_magnitude, interp_filter_selected); - break; - case PARTITION_VERT: - write_modes_b(cpi, xd, tile, w, tok, tok_end, mi_row, mi_col, - max_mv_magnitude, interp_filter_selected); - if (mi_col + bs < cm->mi_cols) - write_modes_b(cpi, xd, tile, w, tok, tok_end, mi_row, mi_col + bs, - max_mv_magnitude, interp_filter_selected); - break; - default: - assert(partition == PARTITION_SPLIT); - write_modes_sb(cpi, xd, tile, w, tok, tok_end, mi_row, mi_col, subsize, - max_mv_magnitude, interp_filter_selected); - write_modes_sb(cpi, xd, tile, w, tok, tok_end, mi_row, mi_col + bs, - subsize, max_mv_magnitude, interp_filter_selected); - write_modes_sb(cpi, xd, tile, w, tok, tok_end, mi_row + bs, mi_col, - subsize, max_mv_magnitude, interp_filter_selected); - write_modes_sb(cpi, xd, tile, w, tok, tok_end, mi_row + bs, mi_col + bs, - subsize, max_mv_magnitude, interp_filter_selected); - break; - } - } - - // update partition context - if (bsize >= BLOCK_8X8 && - (bsize == BLOCK_8X8 || partition != PARTITION_SPLIT)) - update_partition_context(xd, mi_row, mi_col, subsize, bsize); -} - -static void write_modes(VP9_COMP *cpi, MACROBLOCKD *const xd, - const TileInfo *const tile, vpx_writer *w, int tile_row, - int tile_col, unsigned int *const max_mv_magnitude, - int interp_filter_selected[][SWITCHABLE]) { - const VP9_COMMON *const cm = &cpi->common; - int mi_row, mi_col, tile_sb_row; - TOKENEXTRA *tok = NULL; - TOKENEXTRA *tok_end = NULL; - - set_partition_probs(cm, xd); - - for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end; - mi_row += MI_BLOCK_SIZE) { - tile_sb_row = mi_cols_aligned_to_sb(mi_row - tile->mi_row_start) >> - MI_BLOCK_SIZE_LOG2; - tok = cpi->tplist[tile_row][tile_col][tile_sb_row].start; - tok_end = tok + cpi->tplist[tile_row][tile_col][tile_sb_row].count; - - vp9_zero(xd->left_seg_context); - for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end; - mi_col += MI_BLOCK_SIZE) - write_modes_sb(cpi, xd, tile, w, &tok, tok_end, mi_row, mi_col, - BLOCK_64X64, max_mv_magnitude, interp_filter_selected); - - assert(tok == cpi->tplist[tile_row][tile_col][tile_sb_row].stop); - } -} - -static void build_tree_distribution(VP9_COMP *cpi, TX_SIZE tx_size, - vp9_coeff_stats *coef_branch_ct, - vp9_coeff_probs_model *coef_probs) { - vp9_coeff_count *coef_counts = cpi->td.rd_counts.coef_counts[tx_size]; - unsigned int(*eob_branch_ct)[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS] = - cpi->common.counts.eob_branch[tx_size]; - int i, j, k, l, m; - - for (i = 0; i < PLANE_TYPES; ++i) { - for (j = 0; j < REF_TYPES; ++j) { - for (k = 0; k < COEF_BANDS; ++k) { - for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { - vp9_tree_probs_from_distribution(vp9_coef_tree, - coef_branch_ct[i][j][k][l], - coef_counts[i][j][k][l]); - coef_branch_ct[i][j][k][l][0][1] = - eob_branch_ct[i][j][k][l] - coef_branch_ct[i][j][k][l][0][0]; - for (m = 0; m < UNCONSTRAINED_NODES; ++m) - coef_probs[i][j][k][l][m] = - get_binary_prob(coef_branch_ct[i][j][k][l][m][0], - coef_branch_ct[i][j][k][l][m][1]); - } - } - } - } -} - -static void update_coef_probs_common(vpx_writer *const bc, VP9_COMP *cpi, - TX_SIZE tx_size, - vp9_coeff_stats *frame_branch_ct, - vp9_coeff_probs_model *new_coef_probs) { - vp9_coeff_probs_model *old_coef_probs = cpi->common.fc->coef_probs[tx_size]; - const vpx_prob upd = DIFF_UPDATE_PROB; - const int entropy_nodes_update = UNCONSTRAINED_NODES; - int i, j, k, l, t; - int stepsize = cpi->sf.coeff_prob_appx_step; - - switch (cpi->sf.use_fast_coef_updates) { - case TWO_LOOP: { - /* dry run to see if there is any update at all needed */ - int64_t savings = 0; - int update[2] = { 0, 0 }; - for (i = 0; i < PLANE_TYPES; ++i) { - for (j = 0; j < REF_TYPES; ++j) { - for (k = 0; k < COEF_BANDS; ++k) { - for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { - for (t = 0; t < entropy_nodes_update; ++t) { - vpx_prob newp = new_coef_probs[i][j][k][l][t]; - const vpx_prob oldp = old_coef_probs[i][j][k][l][t]; - int64_t s; - int u = 0; - if (t == PIVOT_NODE) - s = vp9_prob_diff_update_savings_search_model( - frame_branch_ct[i][j][k][l][0], oldp, &newp, upd, - stepsize); - else - s = vp9_prob_diff_update_savings_search( - frame_branch_ct[i][j][k][l][t], oldp, &newp, upd); - if (s > 0 && newp != oldp) u = 1; - if (u) - savings += s - (int)(vp9_cost_zero(upd)); - else - savings -= (int)(vp9_cost_zero(upd)); - update[u]++; - } - } - } - } - } - - // printf("Update %d %d, savings %d\n", update[0], update[1], savings); - /* Is coef updated at all */ - if (update[1] == 0 || savings < 0) { - vpx_write_bit(bc, 0); - return; - } - vpx_write_bit(bc, 1); - for (i = 0; i < PLANE_TYPES; ++i) { - for (j = 0; j < REF_TYPES; ++j) { - for (k = 0; k < COEF_BANDS; ++k) { - for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { - // calc probs and branch cts for this frame only - for (t = 0; t < entropy_nodes_update; ++t) { - vpx_prob newp = new_coef_probs[i][j][k][l][t]; - vpx_prob *oldp = old_coef_probs[i][j][k][l] + t; - int64_t s; - int u = 0; - if (t == PIVOT_NODE) - s = vp9_prob_diff_update_savings_search_model( - frame_branch_ct[i][j][k][l][0], *oldp, &newp, upd, - stepsize); - else - s = vp9_prob_diff_update_savings_search( - frame_branch_ct[i][j][k][l][t], *oldp, &newp, upd); - if (s > 0 && newp != *oldp) u = 1; - vpx_write(bc, u, upd); - if (u) { - /* send/use new probability */ - vp9_write_prob_diff_update(bc, newp, *oldp); - *oldp = newp; - } - } - } - } - } - } - return; - } - - default: { - int updates = 0; - int noupdates_before_first = 0; - assert(cpi->sf.use_fast_coef_updates == ONE_LOOP_REDUCED); - for (i = 0; i < PLANE_TYPES; ++i) { - for (j = 0; j < REF_TYPES; ++j) { - for (k = 0; k < COEF_BANDS; ++k) { - for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { - // calc probs and branch cts for this frame only - for (t = 0; t < entropy_nodes_update; ++t) { - vpx_prob newp = new_coef_probs[i][j][k][l][t]; - vpx_prob *oldp = old_coef_probs[i][j][k][l] + t; - int64_t s; - int u = 0; - - if (t == PIVOT_NODE) { - s = vp9_prob_diff_update_savings_search_model( - frame_branch_ct[i][j][k][l][0], *oldp, &newp, upd, - stepsize); - } else { - s = vp9_prob_diff_update_savings_search( - frame_branch_ct[i][j][k][l][t], *oldp, &newp, upd); - } - - if (s > 0 && newp != *oldp) u = 1; - updates += u; - if (u == 0 && updates == 0) { - noupdates_before_first++; - continue; - } - if (u == 1 && updates == 1) { - int v; - // first update - vpx_write_bit(bc, 1); - for (v = 0; v < noupdates_before_first; ++v) - vpx_write(bc, 0, upd); - } - vpx_write(bc, u, upd); - if (u) { - /* send/use new probability */ - vp9_write_prob_diff_update(bc, newp, *oldp); - *oldp = newp; - } - } - } - } - } - } - if (updates == 0) { - vpx_write_bit(bc, 0); // no updates - } - return; - } - } -} - -static void update_coef_probs(VP9_COMP *cpi, vpx_writer *w) { - const TX_MODE tx_mode = cpi->common.tx_mode; - const TX_SIZE max_tx_size = tx_mode_to_biggest_tx_size[tx_mode]; - TX_SIZE tx_size; - for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size) { - vp9_coeff_stats frame_branch_ct[PLANE_TYPES]; - vp9_coeff_probs_model frame_coef_probs[PLANE_TYPES]; - if (cpi->td.counts->tx.tx_totals[tx_size] <= 20 || - (tx_size >= TX_16X16 && cpi->sf.tx_size_search_method == USE_TX_8X8)) { - vpx_write_bit(w, 0); - } else { - build_tree_distribution(cpi, tx_size, frame_branch_ct, frame_coef_probs); - update_coef_probs_common(w, cpi, tx_size, frame_branch_ct, - frame_coef_probs); - } - } -} - -static void encode_loopfilter(struct loopfilter *lf, - struct vpx_write_bit_buffer *wb) { - int i; - - // Encode the loop filter level and type - vpx_wb_write_literal(wb, lf->filter_level, 6); - vpx_wb_write_literal(wb, lf->sharpness_level, 3); - - // Write out loop filter deltas applied at the MB level based on mode or - // ref frame (if they are enabled). - vpx_wb_write_bit(wb, lf->mode_ref_delta_enabled); - - if (lf->mode_ref_delta_enabled) { - vpx_wb_write_bit(wb, lf->mode_ref_delta_update); - if (lf->mode_ref_delta_update) { - for (i = 0; i < MAX_REF_LF_DELTAS; i++) { - const int delta = lf->ref_deltas[i]; - const int changed = delta != lf->last_ref_deltas[i]; - vpx_wb_write_bit(wb, changed); - if (changed) { - lf->last_ref_deltas[i] = delta; - vpx_wb_write_literal(wb, abs(delta) & 0x3F, 6); - vpx_wb_write_bit(wb, delta < 0); - } - } - - for (i = 0; i < MAX_MODE_LF_DELTAS; i++) { - const int delta = lf->mode_deltas[i]; - const int changed = delta != lf->last_mode_deltas[i]; - vpx_wb_write_bit(wb, changed); - if (changed) { - lf->last_mode_deltas[i] = delta; - vpx_wb_write_literal(wb, abs(delta) & 0x3F, 6); - vpx_wb_write_bit(wb, delta < 0); - } - } - } - } -} - -static void write_delta_q(struct vpx_write_bit_buffer *wb, int delta_q) { - if (delta_q != 0) { - vpx_wb_write_bit(wb, 1); - vpx_wb_write_literal(wb, abs(delta_q), 4); - vpx_wb_write_bit(wb, delta_q < 0); - } else { - vpx_wb_write_bit(wb, 0); - } -} - -static void encode_quantization(const VP9_COMMON *const cm, - struct vpx_write_bit_buffer *wb) { - vpx_wb_write_literal(wb, cm->base_qindex, QINDEX_BITS); - write_delta_q(wb, cm->y_dc_delta_q); - write_delta_q(wb, cm->uv_dc_delta_q); - write_delta_q(wb, cm->uv_ac_delta_q); -} - -static void encode_segmentation(VP9_COMMON *cm, MACROBLOCKD *xd, - struct vpx_write_bit_buffer *wb) { - int i, j; - - const struct segmentation *seg = &cm->seg; - - vpx_wb_write_bit(wb, seg->enabled); - if (!seg->enabled) return; - - // Segmentation map - vpx_wb_write_bit(wb, seg->update_map); - if (seg->update_map) { - // Select the coding strategy (temporal or spatial) - vp9_choose_segmap_coding_method(cm, xd); - // Write out probabilities used to decode unpredicted macro-block segments - for (i = 0; i < SEG_TREE_PROBS; i++) { - const int prob = seg->tree_probs[i]; - const int update = prob != MAX_PROB; - vpx_wb_write_bit(wb, update); - if (update) vpx_wb_write_literal(wb, prob, 8); - } - - // Write out the chosen coding method. - vpx_wb_write_bit(wb, seg->temporal_update); - if (seg->temporal_update) { - for (i = 0; i < PREDICTION_PROBS; i++) { - const int prob = seg->pred_probs[i]; - const int update = prob != MAX_PROB; - vpx_wb_write_bit(wb, update); - if (update) vpx_wb_write_literal(wb, prob, 8); - } - } - } - - // Segmentation data - vpx_wb_write_bit(wb, seg->update_data); - if (seg->update_data) { - vpx_wb_write_bit(wb, seg->abs_delta); - - for (i = 0; i < MAX_SEGMENTS; i++) { - for (j = 0; j < SEG_LVL_MAX; j++) { - const int active = segfeature_active(seg, i, j); - vpx_wb_write_bit(wb, active); - if (active) { - const int data = get_segdata(seg, i, j); - const int data_max = vp9_seg_feature_data_max(j); - - if (vp9_is_segfeature_signed(j)) { - encode_unsigned_max(wb, abs(data), data_max); - vpx_wb_write_bit(wb, data < 0); - } else { - encode_unsigned_max(wb, data, data_max); - } - } - } - } - } -} - -static void encode_txfm_probs(VP9_COMMON *cm, vpx_writer *w, - FRAME_COUNTS *counts) { - // Mode - vpx_write_literal(w, VPXMIN(cm->tx_mode, ALLOW_32X32), 2); - if (cm->tx_mode >= ALLOW_32X32) - vpx_write_bit(w, cm->tx_mode == TX_MODE_SELECT); - - // Probabilities - if (cm->tx_mode == TX_MODE_SELECT) { - int i, j; - unsigned int ct_8x8p[TX_SIZES - 3][2]; - unsigned int ct_16x16p[TX_SIZES - 2][2]; - unsigned int ct_32x32p[TX_SIZES - 1][2]; - - for (i = 0; i < TX_SIZE_CONTEXTS; i++) { - tx_counts_to_branch_counts_8x8(counts->tx.p8x8[i], ct_8x8p); - for (j = 0; j < TX_SIZES - 3; j++) - vp9_cond_prob_diff_update(w, &cm->fc->tx_probs.p8x8[i][j], ct_8x8p[j]); - } - - for (i = 0; i < TX_SIZE_CONTEXTS; i++) { - tx_counts_to_branch_counts_16x16(counts->tx.p16x16[i], ct_16x16p); - for (j = 0; j < TX_SIZES - 2; j++) - vp9_cond_prob_diff_update(w, &cm->fc->tx_probs.p16x16[i][j], - ct_16x16p[j]); - } - - for (i = 0; i < TX_SIZE_CONTEXTS; i++) { - tx_counts_to_branch_counts_32x32(counts->tx.p32x32[i], ct_32x32p); - for (j = 0; j < TX_SIZES - 1; j++) - vp9_cond_prob_diff_update(w, &cm->fc->tx_probs.p32x32[i][j], - ct_32x32p[j]); - } - } -} - -static void write_interp_filter(INTERP_FILTER filter, - struct vpx_write_bit_buffer *wb) { - const int filter_to_literal[] = { 1, 0, 2, 3 }; - - vpx_wb_write_bit(wb, filter == SWITCHABLE); - if (filter != SWITCHABLE) - vpx_wb_write_literal(wb, filter_to_literal[filter], 2); -} - -static void fix_interp_filter(VP9_COMMON *cm, FRAME_COUNTS *counts) { - if (cm->interp_filter == SWITCHABLE) { - // Check to see if only one of the filters is actually used - int count[SWITCHABLE_FILTERS]; - int i, j, c = 0; - for (i = 0; i < SWITCHABLE_FILTERS; ++i) { - count[i] = 0; - for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) - count[i] += counts->switchable_interp[j][i]; - c += (count[i] > 0); - } - if (c == 1) { - // Only one filter is used. So set the filter at frame level - for (i = 0; i < SWITCHABLE_FILTERS; ++i) { - if (count[i]) { - cm->interp_filter = i; - break; - } - } - } - } -} - -static void write_tile_info(const VP9_COMMON *const cm, - struct vpx_write_bit_buffer *wb) { - int min_log2_tile_cols, max_log2_tile_cols, ones; - vp9_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols); - - // columns - ones = cm->log2_tile_cols - min_log2_tile_cols; - while (ones--) vpx_wb_write_bit(wb, 1); - - if (cm->log2_tile_cols < max_log2_tile_cols) vpx_wb_write_bit(wb, 0); - - // rows - vpx_wb_write_bit(wb, cm->log2_tile_rows != 0); - if (cm->log2_tile_rows != 0) vpx_wb_write_bit(wb, cm->log2_tile_rows != 1); -} - -int vp9_get_refresh_mask(VP9_COMP *cpi) { - if (cpi->ext_ratectrl.ready && - (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_GOP) != 0 && - cpi->ext_ratectrl.funcs.get_gop_decision != NULL) { - GF_GROUP *const gf_group = &cpi->twopass.gf_group; - const int this_gf_index = gf_group->index; - const int update_ref_idx = gf_group->update_ref_idx[this_gf_index]; - - if (update_ref_idx != INVALID_IDX) { - return (1 << update_ref_idx); - } else { - return 0; - } - } - if (vp9_preserve_existing_gf(cpi)) { - // We have decided to preserve the previously existing golden frame as our - // new ARF frame. However, in the short term we leave it in the GF slot and, - // if we're updating the GF with the current decoded frame, we save it - // instead to the ARF slot. - // Later, in the function vp9_encoder.c:vp9_update_reference_frames() we - // will swap gld_fb_idx and alt_fb_idx to achieve our objective. We do it - // there so that it can be done outside of the recode loop. - // Note: This is highly specific to the use of ARF as a forward reference, - // and this needs to be generalized as other uses are implemented - // (like RTC/temporal scalability). - return (cpi->refresh_last_frame << cpi->lst_fb_idx) | - (cpi->refresh_golden_frame << cpi->alt_fb_idx); - } else { - int arf_idx = cpi->alt_fb_idx; - GF_GROUP *const gf_group = &cpi->twopass.gf_group; - - if (cpi->multi_layer_arf) { - for (arf_idx = 0; arf_idx < REF_FRAMES; ++arf_idx) { - if (arf_idx != cpi->alt_fb_idx && arf_idx != cpi->lst_fb_idx && - arf_idx != cpi->gld_fb_idx) { - int idx; - for (idx = 0; idx < gf_group->stack_size; ++idx) - if (arf_idx == gf_group->arf_index_stack[idx]) break; - if (idx == gf_group->stack_size) break; - } - } - } - cpi->twopass.gf_group.top_arf_idx = arf_idx; - - if (cpi->use_svc && cpi->svc.use_set_ref_frame_config && - cpi->svc.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) - return cpi->svc.update_buffer_slot[cpi->svc.spatial_layer_id]; - return (cpi->refresh_last_frame << cpi->lst_fb_idx) | - (cpi->refresh_golden_frame << cpi->gld_fb_idx) | - (cpi->refresh_alt_ref_frame << arf_idx); - } -} - -static int encode_tile_worker(void *arg1, void *arg2) { - VP9_COMP *cpi = (VP9_COMP *)arg1; - VP9BitstreamWorkerData *data = (VP9BitstreamWorkerData *)arg2; - MACROBLOCKD *const xd = &data->xd; - const int tile_row = 0; - vpx_start_encode(&data->bit_writer, data->dest, data->dest_size); - write_modes(cpi, xd, &cpi->tile_data[data->tile_idx].tile_info, - &data->bit_writer, tile_row, data->tile_idx, - &data->max_mv_magnitude, data->interp_filter_selected); - return vpx_stop_encode(&data->bit_writer) == 0; -} - -void vp9_bitstream_encode_tiles_buffer_dealloc(VP9_COMP *const cpi) { - if (cpi->vp9_bitstream_worker_data) { - int i; - for (i = 1; i < cpi->num_workers; ++i) { - vpx_free(cpi->vp9_bitstream_worker_data[i].dest); - } - vpx_free(cpi->vp9_bitstream_worker_data); - cpi->vp9_bitstream_worker_data = NULL; - } -} - -static size_t encode_tiles_buffer_alloc_size(const VP9_COMP *cpi) { - const VP9_COMMON *cm = &cpi->common; - const int image_bps = - (8 + 2 * (8 >> (cm->subsampling_x + cm->subsampling_y))) * - (1 + (cm->bit_depth > 8)); - const int64_t size = - (int64_t)cpi->oxcf.width * cpi->oxcf.height * image_bps / 8; - return (size_t)size; -} - -static void encode_tiles_buffer_alloc(VP9_COMP *const cpi, - size_t buffer_alloc_size) { - VP9_COMMON *const cm = &cpi->common; - int i; - const size_t worker_data_size = - cpi->num_workers * sizeof(*cpi->vp9_bitstream_worker_data); - CHECK_MEM_ERROR(&cm->error, cpi->vp9_bitstream_worker_data, - vpx_memalign(16, worker_data_size)); - memset(cpi->vp9_bitstream_worker_data, 0, worker_data_size); - for (i = 1; i < cpi->num_workers; ++i) { - CHECK_MEM_ERROR(&cm->error, cpi->vp9_bitstream_worker_data[i].dest, - vpx_malloc(buffer_alloc_size)); - cpi->vp9_bitstream_worker_data[i].dest_size = buffer_alloc_size; - } -} - -static size_t encode_tiles_mt(VP9_COMP *cpi, uint8_t *data_ptr, - size_t data_size) { - const VPxWorkerInterface *const winterface = vpx_get_worker_interface(); - VP9_COMMON *const cm = &cpi->common; - const int tile_cols = 1 << cm->log2_tile_cols; - const int num_workers = cpi->num_workers; - size_t total_size = 0; - int tile_col = 0; - int error = 0; - - const size_t buffer_alloc_size = encode_tiles_buffer_alloc_size(cpi); - if (!cpi->vp9_bitstream_worker_data || - cpi->vp9_bitstream_worker_data[1].dest_size != buffer_alloc_size) { - vp9_bitstream_encode_tiles_buffer_dealloc(cpi); - encode_tiles_buffer_alloc(cpi, buffer_alloc_size); - } - - while (tile_col < tile_cols) { - int i, j; - for (i = 0; i < num_workers && tile_col < tile_cols; ++i) { - VPxWorker *const worker = &cpi->workers[i]; - VP9BitstreamWorkerData *const data = &cpi->vp9_bitstream_worker_data[i]; - - // Populate the worker data. - data->xd = cpi->td.mb.e_mbd; - data->tile_idx = tile_col; - data->max_mv_magnitude = cpi->max_mv_magnitude; - memset(data->interp_filter_selected, 0, - sizeof(data->interp_filter_selected[0][0]) * SWITCHABLE); - - // First thread can directly write into the output buffer. - if (i == 0) { - // If this worker happens to be for the last tile, then do not offset it - // by 4 for the tile size. - const size_t offset = total_size + (tile_col == tile_cols - 1 ? 0 : 4); - if (data_size < offset) { - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "encode_tiles_mt: output buffer full"); - } - data->dest = data_ptr + offset; - data->dest_size = data_size - offset; - } - worker->data1 = cpi; - worker->data2 = data; - worker->hook = encode_tile_worker; - worker->had_error = 0; - - if (i < num_workers - 1) { - winterface->launch(worker); - } else { - winterface->execute(worker); - } - ++tile_col; - } - for (j = 0; j < i; ++j) { - VPxWorker *const worker = &cpi->workers[j]; - VP9BitstreamWorkerData *const data = - (VP9BitstreamWorkerData *)worker->data2; - uint32_t tile_size; - int k; - - if (!winterface->sync(worker)) { - error = 1; - continue; - } - - tile_size = data->bit_writer.pos; - - // Aggregate per-thread bitstream stats. - cpi->max_mv_magnitude = - VPXMAX(cpi->max_mv_magnitude, data->max_mv_magnitude); - for (k = 0; k < SWITCHABLE; ++k) { - cpi->interp_filter_selected[0][k] += data->interp_filter_selected[0][k]; - } - - // Prefix the size of the tile on all but the last. - if (tile_col != tile_cols || j < i - 1) { - if (data_size - total_size < 4) { - error = 1; - continue; - } - mem_put_be32(data_ptr + total_size, tile_size); - total_size += 4; - } - if (j > 0) { - if (data_size - total_size < tile_size) { - error = 1; - continue; - } - memcpy(data_ptr + total_size, data->dest, tile_size); - } - total_size += tile_size; - } - if (error) { - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "encode_tiles_mt: output buffer full"); - } - } - return total_size; -} - -static size_t encode_tiles(VP9_COMP *cpi, uint8_t *data_ptr, size_t data_size) { - VP9_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; - vpx_writer residual_bc; - int tile_row, tile_col; - size_t total_size = 0; - const int tile_cols = 1 << cm->log2_tile_cols; - const int tile_rows = 1 << cm->log2_tile_rows; - - memset(cm->above_seg_context, 0, - sizeof(*cm->above_seg_context) * mi_cols_aligned_to_sb(cm->mi_cols)); - - // Encoding tiles in parallel is done only for realtime mode now. In other - // modes the speed up is insignificant and requires further testing to ensure - // that it does not make the overall process worse in any case. - if (cpi->oxcf.mode == REALTIME && cpi->num_workers > 1 && tile_rows == 1 && - tile_cols > 1) { - return encode_tiles_mt(cpi, data_ptr, data_size); - } - - for (tile_row = 0; tile_row < tile_rows; tile_row++) { - for (tile_col = 0; tile_col < tile_cols; tile_col++) { - int tile_idx = tile_row * tile_cols + tile_col; - - size_t offset; - if (tile_col < tile_cols - 1 || tile_row < tile_rows - 1) - offset = total_size + 4; - else - offset = total_size; - if (data_size < offset) { - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "encode_tiles: output buffer full"); - } - vpx_start_encode(&residual_bc, data_ptr + offset, data_size - offset); - - write_modes(cpi, xd, &cpi->tile_data[tile_idx].tile_info, &residual_bc, - tile_row, tile_col, &cpi->max_mv_magnitude, - cpi->interp_filter_selected); - - if (vpx_stop_encode(&residual_bc)) { - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "encode_tiles: output buffer full"); - } - if (tile_col < tile_cols - 1 || tile_row < tile_rows - 1) { - // size of this tile - mem_put_be32(data_ptr + total_size, residual_bc.pos); - total_size += 4; - } - - total_size += residual_bc.pos; - } - } - return total_size; -} - -static void write_render_size(const VP9_COMMON *cm, - struct vpx_write_bit_buffer *wb) { - const int scaling_active = - cm->width != cm->render_width || cm->height != cm->render_height; - vpx_wb_write_bit(wb, scaling_active); - if (scaling_active) { - vpx_wb_write_literal(wb, cm->render_width - 1, 16); - vpx_wb_write_literal(wb, cm->render_height - 1, 16); - } -} - -static void write_frame_size(const VP9_COMMON *cm, - struct vpx_write_bit_buffer *wb) { - vpx_wb_write_literal(wb, cm->width - 1, 16); - vpx_wb_write_literal(wb, cm->height - 1, 16); - - write_render_size(cm, wb); -} - -static void write_frame_size_with_refs(VP9_COMP *cpi, - struct vpx_write_bit_buffer *wb) { - VP9_COMMON *const cm = &cpi->common; - int found = 0; - - MV_REFERENCE_FRAME ref_frame; - for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { - YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, ref_frame); - - // Set "found" to 0 for temporal svc and for spatial svc key frame - if (cpi->use_svc && - ((cpi->svc.number_temporal_layers > 1 && - cpi->oxcf.rc_mode == VPX_CBR) || - (cpi->svc.number_spatial_layers > 1 && - cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame))) { - found = 0; - } else if (cfg != NULL) { - found = - cm->width == cfg->y_crop_width && cm->height == cfg->y_crop_height; - } - vpx_wb_write_bit(wb, found); - if (found) { - break; - } - } - - if (!found) { - vpx_wb_write_literal(wb, cm->width - 1, 16); - vpx_wb_write_literal(wb, cm->height - 1, 16); - } - - write_render_size(cm, wb); -} - -static void write_sync_code(struct vpx_write_bit_buffer *wb) { - vpx_wb_write_literal(wb, VP9_SYNC_CODE_0, 8); - vpx_wb_write_literal(wb, VP9_SYNC_CODE_1, 8); - vpx_wb_write_literal(wb, VP9_SYNC_CODE_2, 8); -} - -static void write_profile(BITSTREAM_PROFILE profile, - struct vpx_write_bit_buffer *wb) { - switch (profile) { - case PROFILE_0: vpx_wb_write_literal(wb, 0, 2); break; - case PROFILE_1: vpx_wb_write_literal(wb, 2, 2); break; - case PROFILE_2: vpx_wb_write_literal(wb, 1, 2); break; - default: - assert(profile == PROFILE_3); - vpx_wb_write_literal(wb, 6, 3); - break; - } -} - -static void write_bitdepth_colorspace_sampling( - VP9_COMMON *const cm, struct vpx_write_bit_buffer *wb) { - if (cm->profile >= PROFILE_2) { - assert(cm->bit_depth > VPX_BITS_8); - vpx_wb_write_bit(wb, cm->bit_depth == VPX_BITS_10 ? 0 : 1); - } - vpx_wb_write_literal(wb, cm->color_space, 3); - if (cm->color_space != VPX_CS_SRGB) { - // 0: [16, 235] (i.e. xvYCC), 1: [0, 255] - vpx_wb_write_bit(wb, cm->color_range); - if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) { - assert(cm->subsampling_x != 1 || cm->subsampling_y != 1); - vpx_wb_write_bit(wb, cm->subsampling_x); - vpx_wb_write_bit(wb, cm->subsampling_y); - vpx_wb_write_bit(wb, 0); // unused - } else { - assert(cm->subsampling_x == 1 && cm->subsampling_y == 1); - } - } else { - assert(cm->profile == PROFILE_1 || cm->profile == PROFILE_3); - vpx_wb_write_bit(wb, 0); // unused - } -} - -static void write_uncompressed_header(VP9_COMP *cpi, - struct vpx_write_bit_buffer *wb) { - VP9_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; - - vpx_wb_write_literal(wb, VP9_FRAME_MARKER, 2); - - write_profile(cm->profile, wb); - - // If to use show existing frame. - vpx_wb_write_bit(wb, cm->show_existing_frame); - if (cm->show_existing_frame) { - vpx_wb_write_literal(wb, cpi->alt_fb_idx, 3); - return; - } - - vpx_wb_write_bit(wb, cm->frame_type); - vpx_wb_write_bit(wb, cm->show_frame); - vpx_wb_write_bit(wb, cm->error_resilient_mode); - - if (cm->frame_type == KEY_FRAME) { - write_sync_code(wb); - write_bitdepth_colorspace_sampling(cm, wb); - write_frame_size(cm, wb); - } else { - if (!cm->show_frame) vpx_wb_write_bit(wb, cm->intra_only); - - if (!cm->error_resilient_mode) - vpx_wb_write_literal(wb, cm->reset_frame_context, 2); - - if (cm->intra_only) { - write_sync_code(wb); - - // Note for profile 0, 420 8bpp is assumed. - if (cm->profile > PROFILE_0) { - write_bitdepth_colorspace_sampling(cm, wb); - } - - vpx_wb_write_literal(wb, vp9_get_refresh_mask(cpi), REF_FRAMES); - write_frame_size(cm, wb); - } else { - MV_REFERENCE_FRAME ref_frame; - vpx_wb_write_literal(wb, vp9_get_refresh_mask(cpi), REF_FRAMES); - for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { - assert(get_ref_frame_map_idx(cpi, ref_frame) != INVALID_IDX); - vpx_wb_write_literal(wb, get_ref_frame_map_idx(cpi, ref_frame), - REF_FRAMES_LOG2); - vpx_wb_write_bit(wb, cm->ref_frame_sign_bias[ref_frame]); - } - - write_frame_size_with_refs(cpi, wb); - - vpx_wb_write_bit(wb, cm->allow_high_precision_mv); - - fix_interp_filter(cm, cpi->td.counts); - write_interp_filter(cm->interp_filter, wb); - } - } - - if (!cm->error_resilient_mode) { - vpx_wb_write_bit(wb, cm->refresh_frame_context); - vpx_wb_write_bit(wb, cm->frame_parallel_decoding_mode); - } - - vpx_wb_write_literal(wb, cm->frame_context_idx, FRAME_CONTEXTS_LOG2); - - encode_loopfilter(&cm->lf, wb); - encode_quantization(cm, wb); - encode_segmentation(cm, xd, wb); - - write_tile_info(cm, wb); -} - -static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data, - size_t data_size) { - VP9_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; - FRAME_CONTEXT *const fc = cm->fc; - FRAME_COUNTS *counts = cpi->td.counts; - vpx_writer header_bc; - - vpx_start_encode(&header_bc, data, data_size); - - if (xd->lossless) - cm->tx_mode = ONLY_4X4; - else - encode_txfm_probs(cm, &header_bc, counts); - - update_coef_probs(cpi, &header_bc); - update_skip_probs(cm, &header_bc, counts); - - if (!frame_is_intra_only(cm)) { - int i; - - for (i = 0; i < INTER_MODE_CONTEXTS; ++i) - prob_diff_update(vp9_inter_mode_tree, cm->fc->inter_mode_probs[i], - counts->inter_mode[i], INTER_MODES, &header_bc); - - if (cm->interp_filter == SWITCHABLE) - update_switchable_interp_probs(cm, &header_bc, counts); - - for (i = 0; i < INTRA_INTER_CONTEXTS; i++) - vp9_cond_prob_diff_update(&header_bc, &fc->intra_inter_prob[i], - counts->intra_inter[i]); - - if (cpi->allow_comp_inter_inter) { - const int use_compound_pred = cm->reference_mode != SINGLE_REFERENCE; - const int use_hybrid_pred = cm->reference_mode == REFERENCE_MODE_SELECT; - - vpx_write_bit(&header_bc, use_compound_pred); - if (use_compound_pred) { - vpx_write_bit(&header_bc, use_hybrid_pred); - if (use_hybrid_pred) - for (i = 0; i < COMP_INTER_CONTEXTS; i++) - vp9_cond_prob_diff_update(&header_bc, &fc->comp_inter_prob[i], - counts->comp_inter[i]); - } - } - - if (cm->reference_mode != COMPOUND_REFERENCE) { - for (i = 0; i < REF_CONTEXTS; i++) { - vp9_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][0], - counts->single_ref[i][0]); - vp9_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][1], - counts->single_ref[i][1]); - } - } - - if (cm->reference_mode != SINGLE_REFERENCE) - for (i = 0; i < REF_CONTEXTS; i++) - vp9_cond_prob_diff_update(&header_bc, &fc->comp_ref_prob[i], - counts->comp_ref[i]); - - for (i = 0; i < BLOCK_SIZE_GROUPS; ++i) - prob_diff_update(vp9_intra_mode_tree, cm->fc->y_mode_prob[i], - counts->y_mode[i], INTRA_MODES, &header_bc); - - for (i = 0; i < PARTITION_CONTEXTS; ++i) - prob_diff_update(vp9_partition_tree, fc->partition_prob[i], - counts->partition[i], PARTITION_TYPES, &header_bc); - - vp9_write_nmv_probs(cm, cm->allow_high_precision_mv, &header_bc, - &counts->mv); - } - - if (vpx_stop_encode(&header_bc)) { - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "write_compressed_header: output buffer full"); - } - - return header_bc.pos; -} - -void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, size_t dest_size, - size_t *size) { - VP9_COMMON *const cm = &cpi->common; - uint8_t *data = dest; - size_t data_size = dest_size; - size_t uncompressed_hdr_size, compressed_hdr_size; - struct vpx_write_bit_buffer wb; - struct vpx_write_bit_buffer saved_wb; - -#if CONFIG_BITSTREAM_DEBUG - bitstream_queue_reset_write(); -#endif - - vpx_wb_init(&wb, data, data_size); - write_uncompressed_header(cpi, &wb); - if (vpx_wb_has_error(&wb)) { - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "vp9_pack_bitstream: output buffer full"); - } - - // Skip the rest coding process if use show existing frame. - if (cm->show_existing_frame) { - uncompressed_hdr_size = vpx_wb_bytes_written(&wb); - data += uncompressed_hdr_size; - *size = data - dest; - return; - } - - saved_wb = wb; - // don't know in advance compressed header size - vpx_wb_write_literal(&wb, 0, 16); - if (vpx_wb_has_error(&wb)) { - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "vp9_pack_bitstream: output buffer full"); - } - - uncompressed_hdr_size = vpx_wb_bytes_written(&wb); - data += uncompressed_hdr_size; - data_size -= uncompressed_hdr_size; - - vpx_clear_system_state(); - - compressed_hdr_size = write_compressed_header(cpi, data, data_size); - data += compressed_hdr_size; - data_size -= compressed_hdr_size; - if (compressed_hdr_size > UINT16_MAX) { - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "compressed_hdr_size > 16 bits"); - } - vpx_wb_write_literal(&saved_wb, (int)compressed_hdr_size, 16); - assert(!vpx_wb_has_error(&saved_wb)); - - data += encode_tiles(cpi, data, data_size); - - *size = data - dest; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_bitstream.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_bitstream.h deleted file mode 100644 index 1120841e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_bitstream.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_BITSTREAM_H_ -#define VPX_VP9_ENCODER_VP9_BITSTREAM_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "vp9/encoder/vp9_encoder.h" - -typedef struct VP9BitstreamWorkerData { - uint8_t *dest; - size_t dest_size; - vpx_writer bit_writer; - int tile_idx; - unsigned int max_mv_magnitude; - // The size of interp_filter_selected in VP9_COMP is actually - // MAX_REFERENCE_FRAMES x SWITCHABLE. But when encoding tiles, all we ever do - // is increment the very first index (index 0) for the first dimension. Hence - // this is sufficient. - int interp_filter_selected[1][SWITCHABLE]; - DECLARE_ALIGNED(16, MACROBLOCKD, xd); -} VP9BitstreamWorkerData; - -int vp9_get_refresh_mask(VP9_COMP *cpi); - -void vp9_bitstream_encode_tiles_buffer_dealloc(VP9_COMP *const cpi); - -void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, size_t dest_size, - size_t *size); - -static INLINE int vp9_preserve_existing_gf(VP9_COMP *cpi) { - return cpi->refresh_golden_frame && cpi->rc.is_src_frame_alt_ref && - !cpi->use_svc; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_BITSTREAM_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_block.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_block.h deleted file mode 100644 index 65427946..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_block.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_BLOCK_H_ -#define VPX_VP9_ENCODER_VP9_BLOCK_H_ - -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_entropymv.h" -#include "vp9/common/vp9_entropy.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - unsigned int sse; - int sum; - unsigned int var; -} Diff; - -struct macroblock_plane { - DECLARE_ALIGNED(16, int16_t, src_diff[64 * 64]); - tran_low_t *qcoeff; - tran_low_t *coeff; - uint16_t *eobs; - struct buf_2d src; - - // Quantizer settings - int16_t *round_fp; - int16_t *quant_fp; - int16_t *quant; - int16_t *quant_shift; - int16_t *zbin; - int16_t *round; - - int64_t quant_thred[2]; -}; - -/* The [2] dimension is for whether we skip the EOB node (i.e. if previous - * coefficient in this block was zero) or not. */ -typedef unsigned int vp9_coeff_cost[PLANE_TYPES][REF_TYPES][COEF_BANDS][2] - [COEFF_CONTEXTS][ENTROPY_TOKENS]; - -typedef struct { - int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES]; - uint8_t mode_context[MAX_REF_FRAMES]; -} MB_MODE_INFO_EXT; - -typedef struct { - int col_min; - int col_max; - int row_min; - int row_max; -} MvLimits; - -typedef struct macroblock MACROBLOCK; -struct macroblock { -// cf. https://bugs.chromium.org/p/webm/issues/detail?id=1054 -#if defined(_MSC_VER) && _MSC_VER < 1900 - int64_t bsse[MAX_MB_PLANE << 2]; -#endif - - struct macroblock_plane plane[MAX_MB_PLANE]; - - MACROBLOCKD e_mbd; - MB_MODE_INFO_EXT *mbmi_ext; - MB_MODE_INFO_EXT *mbmi_ext_base; - int skip_block; - int select_tx_size; - int skip_recode; - int skip_optimize; - int q_index; - double log_block_src_var; - int block_tx_domain; - - // The equivalent error at the current rdmult of one whole bit (not one - // bitcost unit). - int errorperbit; - // The equivalent SAD error of one (whole) bit at the current quantizer - // for large blocks. - int sadperbit16; - // The equivalent SAD error of one (whole) bit at the current quantizer - // for sub-8x8 blocks. - int sadperbit4; - int rddiv; - int rdmult; - int cb_rdmult; - int segment_id; - int mb_energy; - - // These are set to their default values at the beginning, and then adjusted - // further in the encoding process. - BLOCK_SIZE min_partition_size; - BLOCK_SIZE max_partition_size; - - int mv_best_ref_index[MAX_REF_FRAMES]; - unsigned int max_mv_context[MAX_REF_FRAMES]; - unsigned int source_variance; - unsigned int pred_sse[MAX_REF_FRAMES]; - int pred_mv_sad[MAX_REF_FRAMES]; - - int nmvjointcost[MV_JOINTS]; - int *nmvcost[2]; - int *nmvcost_hp[2]; - int **mvcost; - - int nmvjointsadcost[MV_JOINTS]; - int *nmvsadcost[2]; - int *nmvsadcost_hp[2]; - int **mvsadcost; - - // sharpness is used to disable skip mode and change rd_mult - int sharpness; - - // aq mode is used to adjust rd based on segment. - int adjust_rdmult_by_segment; - - // These define limits to motion vector components to prevent them - // from extending outside the UMV borders - MvLimits mv_limits; - - // Notes transform blocks where no coefficients are coded. - // Set during mode selection. Read during block encoding. - uint8_t zcoeff_blk[TX_SIZES][256]; - - // Accumulate the tx block eobs in a partition block. - int32_t sum_y_eobs[TX_SIZES]; - - int skip; - - int encode_breakout; - - // note that token_costs is the cost when eob node is skipped - vp9_coeff_cost token_costs[TX_SIZES]; - - int optimize; - - // indicate if it is in the rd search loop or encoding process - int use_lp32x32fdct; - int skip_encode; - - // In first pass, intra prediction is done based on source pixels - // at tile boundaries - int fp_src_pred; - - // use fast quantization process - int quant_fp; - - // skip forward transform and quantization - uint8_t skip_txfm[MAX_MB_PLANE << 2]; -#define SKIP_TXFM_NONE 0 -// TODO(chengchen): consider remove SKIP_TXFM_AC_DC from vp9 completely -// since it increases risks of bad perceptual quality. -// https://crbug.com/webm/1729 -#define SKIP_TXFM_AC_DC 1 -#define SKIP_TXFM_AC_ONLY 2 - -// cf. https://bugs.chromium.org/p/webm/issues/detail?id=1054 -#if !defined(_MSC_VER) || _MSC_VER >= 1900 - int64_t bsse[MAX_MB_PLANE << 2]; -#endif - - // Used to store sub partition's choices. - MV pred_mv[MAX_REF_FRAMES]; - - // Strong color activity detection. Used in RTC coding mode to enhance - // the visual quality at the boundary of moving color objects. - uint8_t color_sensitivity[2]; - - uint8_t sb_is_skin; - - uint8_t skip_low_source_sad; - - uint8_t lowvar_highsumdiff; - - uint8_t last_sb_high_content; - - int sb_use_mv_part; - - int sb_mvcol_part; - - int sb_mvrow_part; - - int sb_pickmode_part; - - int zero_temp_sad_source; - - // For each superblock: saves the content value (e.g., low/high sad/sumdiff) - // based on source sad, prior to encoding the frame. - uint8_t content_state_sb; - - // Used to save the status of whether a block has a low variance in - // choose_partitioning. 0 for 64x64, 1~2 for 64x32, 3~4 for 32x64, 5~8 for - // 32x32, 9~24 for 16x16. - uint8_t variance_low[25]; - - uint8_t arf_frame_usage; - uint8_t lastgolden_frame_usage; - - void (*fwd_txfm4x4)(const int16_t *input, tran_low_t *output, int stride); - void (*inv_txfm_add)(const tran_low_t *input, uint8_t *dest, int stride, - int eob); -#if CONFIG_VP9_HIGHBITDEPTH - void (*highbd_inv_txfm_add)(const tran_low_t *input, uint16_t *dest, - int stride, int eob, int bd); -#endif - DECLARE_ALIGNED(16, uint8_t, est_pred[64 * 64]); - - struct scale_factors *me_sf; -}; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_BLOCK_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_blockiness.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_blockiness.c deleted file mode 100644 index da68a3c3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_blockiness.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include - -#include "vpx/vpx_integer.h" -#include "vpx_ports/system_state.h" -#include "vp9/encoder/vp9_blockiness.h" - -static int horizontal_filter(const uint8_t *s) { - return (s[1] - s[-2]) * 2 + (s[-1] - s[0]) * 6; -} - -static int vertical_filter(const uint8_t *s, int p) { - return (s[p] - s[-2 * p]) * 2 + (s[-p] - s[0]) * 6; -} - -static int variance(int sum, int sum_squared, int size) { - return sum_squared / size - (sum / size) * (sum / size); -} -// Calculate a blockiness level for a vertical block edge. -// This function returns a new blockiness metric that's defined as - -// p0 p1 p2 p3 -// q0 q1 q2 q3 -// block edge -> -// r0 r1 r2 r3 -// s0 s1 s2 s3 - -// blockiness = p0*-2+q0*6+r0*-6+s0*2 + -// p1*-2+q1*6+r1*-6+s1*2 + -// p2*-2+q2*6+r2*-6+s2*2 + -// p3*-2+q3*6+r3*-6+s3*2 ; - -// reconstructed_blockiness = abs(blockiness from reconstructed buffer - -// blockiness from source buffer,0) -// -// I make the assumption that flat blocks are much more visible than high -// contrast blocks. As such, I scale the result of the blockiness calc -// by dividing the blockiness by the variance of the pixels on either side -// of the edge as follows: -// var_0 = (q0^2+q1^2+q2^2+q3^2) - ((q0 + q1 + q2 + q3) / 4 )^2 -// var_1 = (r0^2+r1^2+r2^2+r3^2) - ((r0 + r1 + r2 + r3) / 4 )^2 -// The returned blockiness is the scaled value -// Reconstructed blockiness / ( 1 + var_0 + var_1 ) ; -static int blockiness_vertical(const uint8_t *s, int sp, const uint8_t *r, - int rp, int size) { - int s_blockiness = 0; - int r_blockiness = 0; - int sum_0 = 0; - int sum_sq_0 = 0; - int sum_1 = 0; - int sum_sq_1 = 0; - int i; - int var_0; - int var_1; - for (i = 0; i < size; ++i, s += sp, r += rp) { - s_blockiness += horizontal_filter(s); - r_blockiness += horizontal_filter(r); - sum_0 += s[0]; - sum_sq_0 += s[0] * s[0]; - sum_1 += s[-1]; - sum_sq_1 += s[-1] * s[-1]; - } - var_0 = variance(sum_0, sum_sq_0, size); - var_1 = variance(sum_1, sum_sq_1, size); - r_blockiness = abs(r_blockiness); - s_blockiness = abs(s_blockiness); - - if (r_blockiness > s_blockiness) - return (r_blockiness - s_blockiness) / (1 + var_0 + var_1); - else - return 0; -} - -// Calculate a blockiness level for a horizontal block edge -// same as above. -static int blockiness_horizontal(const uint8_t *s, int sp, const uint8_t *r, - int rp, int size) { - int s_blockiness = 0; - int r_blockiness = 0; - int sum_0 = 0; - int sum_sq_0 = 0; - int sum_1 = 0; - int sum_sq_1 = 0; - int i; - int var_0; - int var_1; - for (i = 0; i < size; ++i, ++s, ++r) { - s_blockiness += vertical_filter(s, sp); - r_blockiness += vertical_filter(r, rp); - sum_0 += s[0]; - sum_sq_0 += s[0] * s[0]; - sum_1 += s[-sp]; - sum_sq_1 += s[-sp] * s[-sp]; - } - var_0 = variance(sum_0, sum_sq_0, size); - var_1 = variance(sum_1, sum_sq_1, size); - r_blockiness = abs(r_blockiness); - s_blockiness = abs(s_blockiness); - - if (r_blockiness > s_blockiness) - return (r_blockiness - s_blockiness) / (1 + var_0 + var_1); - else - return 0; -} - -// This function returns the blockiness for the entire frame currently by -// looking at all borders in steps of 4. -double vp9_get_blockiness(const uint8_t *img1, int img1_pitch, - const uint8_t *img2, int img2_pitch, int width, - int height) { - double blockiness = 0; - int i, j; - vpx_clear_system_state(); - for (i = 0; i < height; - i += 4, img1 += img1_pitch * 4, img2 += img2_pitch * 4) { - for (j = 0; j < width; j += 4) { - if (i > 0 && i < height && j > 0 && j < width) { - blockiness += - blockiness_vertical(img1 + j, img1_pitch, img2 + j, img2_pitch, 4); - blockiness += blockiness_horizontal(img1 + j, img1_pitch, img2 + j, - img2_pitch, 4); - } - } - } - blockiness /= width * height / 16; - return blockiness; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_blockiness.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_blockiness.h deleted file mode 100644 index e840cb25..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_blockiness.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2019 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_BLOCKINESS_H_ -#define VPX_VP9_ENCODER_VP9_BLOCKINESS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -double vp9_get_blockiness(const uint8_t *img1, int img1_pitch, - const uint8_t *img2, int img2_pitch, int width, - int height); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_BLOCKINESS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_context_tree.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_context_tree.c deleted file mode 100644 index ee0fcd87..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_context_tree.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp9/encoder/vp9_context_tree.h" -#include "vp9/encoder/vp9_encoder.h" - -static const BLOCK_SIZE square[] = { - BLOCK_8X8, - BLOCK_16X16, - BLOCK_32X32, - BLOCK_64X64, -}; - -static void alloc_mode_context(VP9_COMMON *cm, int num_4x4_blk, - PICK_MODE_CONTEXT *ctx) { - const int num_blk = (num_4x4_blk < 4 ? 4 : num_4x4_blk); - const int num_pix = num_blk << 4; - int i, k; - ctx->num_4x4_blk = num_blk; - - CHECK_MEM_ERROR(&cm->error, ctx->zcoeff_blk, - vpx_calloc(num_blk, sizeof(uint8_t))); - for (i = 0; i < MAX_MB_PLANE; ++i) { - for (k = 0; k < 3; ++k) { - CHECK_MEM_ERROR(&cm->error, ctx->coeff[i][k], - vpx_memalign(32, num_pix * sizeof(*ctx->coeff[i][k]))); - CHECK_MEM_ERROR(&cm->error, ctx->qcoeff[i][k], - vpx_memalign(32, num_pix * sizeof(*ctx->qcoeff[i][k]))); - CHECK_MEM_ERROR(&cm->error, ctx->dqcoeff[i][k], - vpx_memalign(32, num_pix * sizeof(*ctx->dqcoeff[i][k]))); - CHECK_MEM_ERROR(&cm->error, ctx->eobs[i][k], - vpx_memalign(32, num_blk * sizeof(*ctx->eobs[i][k]))); - ctx->coeff_pbuf[i][k] = ctx->coeff[i][k]; - ctx->qcoeff_pbuf[i][k] = ctx->qcoeff[i][k]; - ctx->dqcoeff_pbuf[i][k] = ctx->dqcoeff[i][k]; - ctx->eobs_pbuf[i][k] = ctx->eobs[i][k]; - } - } -} - -static void free_mode_context(PICK_MODE_CONTEXT *ctx) { - int i, k; - vpx_free(ctx->zcoeff_blk); - ctx->zcoeff_blk = 0; - for (i = 0; i < MAX_MB_PLANE; ++i) { - for (k = 0; k < 3; ++k) { - vpx_free(ctx->coeff[i][k]); - ctx->coeff[i][k] = 0; - vpx_free(ctx->qcoeff[i][k]); - ctx->qcoeff[i][k] = 0; - vpx_free(ctx->dqcoeff[i][k]); - ctx->dqcoeff[i][k] = 0; - vpx_free(ctx->eobs[i][k]); - ctx->eobs[i][k] = 0; - } - } -} - -static void alloc_tree_contexts(VP9_COMMON *cm, PC_TREE *tree, - int num_4x4_blk) { - alloc_mode_context(cm, num_4x4_blk, &tree->none); - alloc_mode_context(cm, num_4x4_blk / 2, &tree->horizontal[0]); - alloc_mode_context(cm, num_4x4_blk / 2, &tree->vertical[0]); - - if (num_4x4_blk > 4) { - alloc_mode_context(cm, num_4x4_blk / 2, &tree->horizontal[1]); - alloc_mode_context(cm, num_4x4_blk / 2, &tree->vertical[1]); - } else { - memset(&tree->horizontal[1], 0, sizeof(tree->horizontal[1])); - memset(&tree->vertical[1], 0, sizeof(tree->vertical[1])); - } -} - -static void free_tree_contexts(PC_TREE *tree) { - free_mode_context(&tree->none); - free_mode_context(&tree->horizontal[0]); - free_mode_context(&tree->horizontal[1]); - free_mode_context(&tree->vertical[0]); - free_mode_context(&tree->vertical[1]); -} - -// This function sets up a tree of contexts such that at each square -// partition level. There are contexts for none, horizontal, vertical, and -// split. Along with a block_size value and a selected block_size which -// represents the state of our search. -void vp9_setup_pc_tree(VP9_COMMON *cm, ThreadData *td) { - int i, j; - const int leaf_nodes = 64; - const int tree_nodes = 64 + 16 + 4 + 1; - int pc_tree_index = 0; - PC_TREE *this_pc; - PICK_MODE_CONTEXT *this_leaf; - int square_index = 1; - int nodes; - - vpx_free(td->leaf_tree); - CHECK_MEM_ERROR(&cm->error, td->leaf_tree, - vpx_calloc(leaf_nodes, sizeof(*td->leaf_tree))); - vpx_free(td->pc_tree); - CHECK_MEM_ERROR(&cm->error, td->pc_tree, - vpx_calloc(tree_nodes, sizeof(*td->pc_tree))); - - this_pc = &td->pc_tree[0]; - this_leaf = &td->leaf_tree[0]; - - // 4x4 blocks smaller than 8x8 but in the same 8x8 block share the same - // context so we only need to allocate 1 for each 8x8 block. - for (i = 0; i < leaf_nodes; ++i) alloc_mode_context(cm, 1, &td->leaf_tree[i]); - - // Sets up all the leaf nodes in the tree. - for (pc_tree_index = 0; pc_tree_index < leaf_nodes; ++pc_tree_index) { - PC_TREE *const tree = &td->pc_tree[pc_tree_index]; - tree->block_size = square[0]; - alloc_tree_contexts(cm, tree, 4); - tree->u.leaf_split[0] = this_leaf++; - for (j = 1; j < 4; j++) tree->u.leaf_split[j] = tree->u.leaf_split[0]; - } - - // Each node has 4 leaf nodes, fill each block_size level of the tree - // from leafs to the root. - for (nodes = 16; nodes > 0; nodes >>= 2) { - for (i = 0; i < nodes; ++i) { - PC_TREE *const tree = &td->pc_tree[pc_tree_index]; - alloc_tree_contexts(cm, tree, 4 << (2 * square_index)); - tree->block_size = square[square_index]; - for (j = 0; j < 4; j++) tree->u.split[j] = this_pc++; - ++pc_tree_index; - } - ++square_index; - } - td->pc_root = &td->pc_tree[tree_nodes - 1]; - td->pc_root[0].none.best_mode_index = 2; -} - -void vp9_free_pc_tree(ThreadData *td) { - int i; - - if (td == NULL) return; - - if (td->leaf_tree != NULL) { - // Set up all 4x4 mode contexts - for (i = 0; i < 64; ++i) free_mode_context(&td->leaf_tree[i]); - vpx_free(td->leaf_tree); - td->leaf_tree = NULL; - } - - if (td->pc_tree != NULL) { - const int tree_nodes = 64 + 16 + 4 + 1; - // Sets up all the leaf nodes in the tree. - for (i = 0; i < tree_nodes; ++i) free_tree_contexts(&td->pc_tree[i]); - vpx_free(td->pc_tree); - td->pc_tree = NULL; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_context_tree.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_context_tree.h deleted file mode 100644 index 51e13ba6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_context_tree.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_CONTEXT_TREE_H_ -#define VPX_VP9_ENCODER_VP9_CONTEXT_TREE_H_ - -#include "vp9/common/vp9_blockd.h" -#include "vp9/encoder/vp9_block.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct VP9_COMP; -struct VP9Common; -struct ThreadData; - -// Structure to hold snapshot of coding context during the mode picking process -typedef struct { - MODE_INFO mic; - MB_MODE_INFO_EXT mbmi_ext; - uint8_t *zcoeff_blk; - tran_low_t *coeff[MAX_MB_PLANE][3]; - tran_low_t *qcoeff[MAX_MB_PLANE][3]; - tran_low_t *dqcoeff[MAX_MB_PLANE][3]; - uint16_t *eobs[MAX_MB_PLANE][3]; - - // dual buffer pointers, 0: in use, 1: best in store - tran_low_t *coeff_pbuf[MAX_MB_PLANE][3]; - tran_low_t *qcoeff_pbuf[MAX_MB_PLANE][3]; - tran_low_t *dqcoeff_pbuf[MAX_MB_PLANE][3]; - uint16_t *eobs_pbuf[MAX_MB_PLANE][3]; - - int is_coded; - int num_4x4_blk; - int skip; - int pred_pixel_ready; - // For current partition, only if all Y, U, and V transform blocks' - // coefficients are quantized to 0, skippable is set to 0. - int skippable; - uint8_t skip_txfm[MAX_MB_PLANE << 2]; - int best_mode_index; - int hybrid_pred_diff; - int comp_pred_diff; - int single_pred_diff; - int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS]; - - // TODO(jingning) Use RD_COST struct here instead. This involves a boarder - // scope of refactoring. - int rate; - int64_t dist; - int64_t rdcost; - -#if CONFIG_VP9_TEMPORAL_DENOISING - unsigned int newmv_sse; - unsigned int zeromv_sse; - unsigned int zeromv_lastref_sse; - PREDICTION_MODE best_sse_inter_mode; - int_mv best_sse_mv; - MV_REFERENCE_FRAME best_reference_frame; - MV_REFERENCE_FRAME best_zeromv_reference_frame; - int sb_skip_denoising; -#endif - - // motion vector cache for adaptive motion search control in partition - // search loop - MV pred_mv[MAX_REF_FRAMES]; - INTERP_FILTER pred_interp_filter; - - // Used for the machine learning-based early termination - int32_t sum_y_eobs; - // Skip certain ref frames during RD search of rectangular partitions. - uint8_t skip_ref_frame_mask; -} PICK_MODE_CONTEXT; - -typedef struct PC_TREE { - int index; - PARTITION_TYPE partitioning; - BLOCK_SIZE block_size; - PICK_MODE_CONTEXT none; - PICK_MODE_CONTEXT horizontal[2]; - PICK_MODE_CONTEXT vertical[2]; - union { - struct PC_TREE *split[4]; - PICK_MODE_CONTEXT *leaf_split[4]; - } u; - // Obtained from a simple motion search. Used by the ML based partition search - // speed feature. - MV mv; -} PC_TREE; - -void vp9_setup_pc_tree(struct VP9Common *cm, struct ThreadData *td); -void vp9_free_pc_tree(struct ThreadData *td); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_CONTEXT_TREE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_cost.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_cost.c deleted file mode 100644 index 81581a80..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_cost.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include - -#include "vp9/encoder/vp9_cost.h" - -/* round(-log2(i/256.) * (1 << VP9_PROB_COST_SHIFT)) - Begins with a bogus entry for simpler addressing. */ -const uint16_t vp9_prob_cost[256] = { - 4096, 4096, 3584, 3284, 3072, 2907, 2772, 2659, 2560, 2473, 2395, 2325, 2260, - 2201, 2147, 2096, 2048, 2003, 1961, 1921, 1883, 1847, 1813, 1780, 1748, 1718, - 1689, 1661, 1635, 1609, 1584, 1559, 1536, 1513, 1491, 1470, 1449, 1429, 1409, - 1390, 1371, 1353, 1335, 1318, 1301, 1284, 1268, 1252, 1236, 1221, 1206, 1192, - 1177, 1163, 1149, 1136, 1123, 1110, 1097, 1084, 1072, 1059, 1047, 1036, 1024, - 1013, 1001, 990, 979, 968, 958, 947, 937, 927, 917, 907, 897, 887, - 878, 868, 859, 850, 841, 832, 823, 814, 806, 797, 789, 780, 772, - 764, 756, 748, 740, 732, 724, 717, 709, 702, 694, 687, 680, 673, - 665, 658, 651, 644, 637, 631, 624, 617, 611, 604, 598, 591, 585, - 578, 572, 566, 560, 554, 547, 541, 535, 530, 524, 518, 512, 506, - 501, 495, 489, 484, 478, 473, 467, 462, 456, 451, 446, 441, 435, - 430, 425, 420, 415, 410, 405, 400, 395, 390, 385, 380, 375, 371, - 366, 361, 356, 352, 347, 343, 338, 333, 329, 324, 320, 316, 311, - 307, 302, 298, 294, 289, 285, 281, 277, 273, 268, 264, 260, 256, - 252, 248, 244, 240, 236, 232, 228, 224, 220, 216, 212, 209, 205, - 201, 197, 194, 190, 186, 182, 179, 175, 171, 168, 164, 161, 157, - 153, 150, 146, 143, 139, 136, 132, 129, 125, 122, 119, 115, 112, - 109, 105, 102, 99, 95, 92, 89, 86, 82, 79, 76, 73, 70, - 66, 63, 60, 57, 54, 51, 48, 45, 42, 38, 35, 32, 29, - 26, 23, 20, 18, 15, 12, 9, 6, 3 -}; - -static void cost(int *costs, vpx_tree tree, const vpx_prob *probs, int i, - int c) { - const vpx_prob prob = probs[i / 2]; - int b; - - assert(prob != 0); - for (b = 0; b <= 1; ++b) { - const int cc = c + vp9_cost_bit(prob, b); - const vpx_tree_index ii = tree[i + b]; - - if (ii <= 0) - costs[-ii] = cc; - else - cost(costs, tree, probs, ii, cc); - } -} - -void vp9_cost_tokens(int *costs, const vpx_prob *probs, vpx_tree tree) { - cost(costs, tree, probs, 0, 0); -} - -void vp9_cost_tokens_skip(int *costs, const vpx_prob *probs, vpx_tree tree) { - assert(tree[0] <= 0 && tree[1] > 0); - - costs[-tree[0]] = vp9_cost_bit(probs[0], 0); - cost(costs, tree, probs, 2, 0); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_cost.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_cost.h deleted file mode 100644 index ee0033fa..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_cost.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_COST_H_ -#define VPX_VP9_ENCODER_VP9_COST_H_ - -#include "vpx_dsp/prob.h" -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const uint16_t vp9_prob_cost[256]; - -// The factor to scale from cost in bits to cost in vp9_prob_cost units. -#define VP9_PROB_COST_SHIFT 9 - -#define vp9_cost_zero(prob) (vp9_prob_cost[prob]) - -#define vp9_cost_one(prob) vp9_cost_zero(256 - (prob)) - -#define vp9_cost_bit(prob, bit) vp9_cost_zero((bit) ? 256 - (prob) : (prob)) - -static INLINE uint64_t cost_branch256(const unsigned int ct[2], vpx_prob p) { - return (uint64_t)ct[0] * vp9_cost_zero(p) + (uint64_t)ct[1] * vp9_cost_one(p); -} - -static INLINE int treed_cost(vpx_tree tree, const vpx_prob *probs, int bits, - int len) { - int cost = 0; - vpx_tree_index i = 0; - - do { - const int bit = (bits >> --len) & 1; - cost += vp9_cost_bit(probs[i >> 1], bit); - i = tree[i + bit]; - } while (len); - - return cost; -} - -void vp9_cost_tokens(int *costs, const vpx_prob *probs, vpx_tree tree); -void vp9_cost_tokens_skip(int *costs, const vpx_prob *probs, vpx_tree tree); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_COST_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_dct.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_dct.c deleted file mode 100644 index 2f42c6af..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_dct.c +++ /dev/null @@ -1,687 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_idct.h" -#include "vpx_dsp/fwd_txfm.h" -#include "vpx_ports/mem.h" - -static void fdct4(const tran_low_t *input, tran_low_t *output) { - tran_high_t step[4]; - tran_high_t temp1, temp2; - - step[0] = input[0] + input[3]; - step[1] = input[1] + input[2]; - step[2] = input[1] - input[2]; - step[3] = input[0] - input[3]; - - temp1 = (step[0] + step[1]) * cospi_16_64; - temp2 = (step[0] - step[1]) * cospi_16_64; - output[0] = (tran_low_t)fdct_round_shift(temp1); - output[2] = (tran_low_t)fdct_round_shift(temp2); - temp1 = step[2] * cospi_24_64 + step[3] * cospi_8_64; - temp2 = -step[2] * cospi_8_64 + step[3] * cospi_24_64; - output[1] = (tran_low_t)fdct_round_shift(temp1); - output[3] = (tran_low_t)fdct_round_shift(temp2); -} - -static void fdct8(const tran_low_t *input, tran_low_t *output) { - tran_high_t s0, s1, s2, s3, s4, s5, s6, s7; // canbe16 - tran_high_t t0, t1, t2, t3; // needs32 - tran_high_t x0, x1, x2, x3; // canbe16 - - // stage 1 - s0 = input[0] + input[7]; - s1 = input[1] + input[6]; - s2 = input[2] + input[5]; - s3 = input[3] + input[4]; - s4 = input[3] - input[4]; - s5 = input[2] - input[5]; - s6 = input[1] - input[6]; - s7 = input[0] - input[7]; - - // fdct4(step, step); - x0 = s0 + s3; - x1 = s1 + s2; - x2 = s1 - s2; - x3 = s0 - s3; - t0 = (x0 + x1) * cospi_16_64; - t1 = (x0 - x1) * cospi_16_64; - t2 = x2 * cospi_24_64 + x3 * cospi_8_64; - t3 = -x2 * cospi_8_64 + x3 * cospi_24_64; - output[0] = (tran_low_t)fdct_round_shift(t0); - output[2] = (tran_low_t)fdct_round_shift(t2); - output[4] = (tran_low_t)fdct_round_shift(t1); - output[6] = (tran_low_t)fdct_round_shift(t3); - - // Stage 2 - t0 = (s6 - s5) * cospi_16_64; - t1 = (s6 + s5) * cospi_16_64; - t2 = (tran_low_t)fdct_round_shift(t0); - t3 = (tran_low_t)fdct_round_shift(t1); - - // Stage 3 - x0 = s4 + t2; - x1 = s4 - t2; - x2 = s7 - t3; - x3 = s7 + t3; - - // Stage 4 - t0 = x0 * cospi_28_64 + x3 * cospi_4_64; - t1 = x1 * cospi_12_64 + x2 * cospi_20_64; - t2 = x2 * cospi_12_64 + x1 * -cospi_20_64; - t3 = x3 * cospi_28_64 + x0 * -cospi_4_64; - output[1] = (tran_low_t)fdct_round_shift(t0); - output[3] = (tran_low_t)fdct_round_shift(t2); - output[5] = (tran_low_t)fdct_round_shift(t1); - output[7] = (tran_low_t)fdct_round_shift(t3); -} - -static void fdct16(const tran_low_t in[16], tran_low_t out[16]) { - tran_high_t step1[8]; // canbe16 - tran_high_t step2[8]; // canbe16 - tran_high_t step3[8]; // canbe16 - tran_high_t input[8]; // canbe16 - tran_high_t temp1, temp2; // needs32 - - // step 1 - input[0] = in[0] + in[15]; - input[1] = in[1] + in[14]; - input[2] = in[2] + in[13]; - input[3] = in[3] + in[12]; - input[4] = in[4] + in[11]; - input[5] = in[5] + in[10]; - input[6] = in[6] + in[9]; - input[7] = in[7] + in[8]; - - step1[0] = in[7] - in[8]; - step1[1] = in[6] - in[9]; - step1[2] = in[5] - in[10]; - step1[3] = in[4] - in[11]; - step1[4] = in[3] - in[12]; - step1[5] = in[2] - in[13]; - step1[6] = in[1] - in[14]; - step1[7] = in[0] - in[15]; - - // fdct8(step, step); - { - tran_high_t s0, s1, s2, s3, s4, s5, s6, s7; // canbe16 - tran_high_t t0, t1, t2, t3; // needs32 - tran_high_t x0, x1, x2, x3; // canbe16 - - // stage 1 - s0 = input[0] + input[7]; - s1 = input[1] + input[6]; - s2 = input[2] + input[5]; - s3 = input[3] + input[4]; - s4 = input[3] - input[4]; - s5 = input[2] - input[5]; - s6 = input[1] - input[6]; - s7 = input[0] - input[7]; - - // fdct4(step, step); - x0 = s0 + s3; - x1 = s1 + s2; - x2 = s1 - s2; - x3 = s0 - s3; - t0 = (x0 + x1) * cospi_16_64; - t1 = (x0 - x1) * cospi_16_64; - t2 = x3 * cospi_8_64 + x2 * cospi_24_64; - t3 = x3 * cospi_24_64 - x2 * cospi_8_64; - out[0] = (tran_low_t)fdct_round_shift(t0); - out[4] = (tran_low_t)fdct_round_shift(t2); - out[8] = (tran_low_t)fdct_round_shift(t1); - out[12] = (tran_low_t)fdct_round_shift(t3); - - // Stage 2 - t0 = (s6 - s5) * cospi_16_64; - t1 = (s6 + s5) * cospi_16_64; - t2 = fdct_round_shift(t0); - t3 = fdct_round_shift(t1); - - // Stage 3 - x0 = s4 + t2; - x1 = s4 - t2; - x2 = s7 - t3; - x3 = s7 + t3; - - // Stage 4 - t0 = x0 * cospi_28_64 + x3 * cospi_4_64; - t1 = x1 * cospi_12_64 + x2 * cospi_20_64; - t2 = x2 * cospi_12_64 + x1 * -cospi_20_64; - t3 = x3 * cospi_28_64 + x0 * -cospi_4_64; - out[2] = (tran_low_t)fdct_round_shift(t0); - out[6] = (tran_low_t)fdct_round_shift(t2); - out[10] = (tran_low_t)fdct_round_shift(t1); - out[14] = (tran_low_t)fdct_round_shift(t3); - } - - // step 2 - temp1 = (step1[5] - step1[2]) * cospi_16_64; - temp2 = (step1[4] - step1[3]) * cospi_16_64; - step2[2] = fdct_round_shift(temp1); - step2[3] = fdct_round_shift(temp2); - temp1 = (step1[4] + step1[3]) * cospi_16_64; - temp2 = (step1[5] + step1[2]) * cospi_16_64; - step2[4] = fdct_round_shift(temp1); - step2[5] = fdct_round_shift(temp2); - - // step 3 - step3[0] = step1[0] + step2[3]; - step3[1] = step1[1] + step2[2]; - step3[2] = step1[1] - step2[2]; - step3[3] = step1[0] - step2[3]; - step3[4] = step1[7] - step2[4]; - step3[5] = step1[6] - step2[5]; - step3[6] = step1[6] + step2[5]; - step3[7] = step1[7] + step2[4]; - - // step 4 - temp1 = step3[1] * -cospi_8_64 + step3[6] * cospi_24_64; - temp2 = step3[2] * cospi_24_64 + step3[5] * cospi_8_64; - step2[1] = fdct_round_shift(temp1); - step2[2] = fdct_round_shift(temp2); - temp1 = step3[2] * cospi_8_64 - step3[5] * cospi_24_64; - temp2 = step3[1] * cospi_24_64 + step3[6] * cospi_8_64; - step2[5] = fdct_round_shift(temp1); - step2[6] = fdct_round_shift(temp2); - - // step 5 - step1[0] = step3[0] + step2[1]; - step1[1] = step3[0] - step2[1]; - step1[2] = step3[3] + step2[2]; - step1[3] = step3[3] - step2[2]; - step1[4] = step3[4] - step2[5]; - step1[5] = step3[4] + step2[5]; - step1[6] = step3[7] - step2[6]; - step1[7] = step3[7] + step2[6]; - - // step 6 - temp1 = step1[0] * cospi_30_64 + step1[7] * cospi_2_64; - temp2 = step1[1] * cospi_14_64 + step1[6] * cospi_18_64; - out[1] = (tran_low_t)fdct_round_shift(temp1); - out[9] = (tran_low_t)fdct_round_shift(temp2); - - temp1 = step1[2] * cospi_22_64 + step1[5] * cospi_10_64; - temp2 = step1[3] * cospi_6_64 + step1[4] * cospi_26_64; - out[5] = (tran_low_t)fdct_round_shift(temp1); - out[13] = (tran_low_t)fdct_round_shift(temp2); - - temp1 = step1[3] * -cospi_26_64 + step1[4] * cospi_6_64; - temp2 = step1[2] * -cospi_10_64 + step1[5] * cospi_22_64; - out[3] = (tran_low_t)fdct_round_shift(temp1); - out[11] = (tran_low_t)fdct_round_shift(temp2); - - temp1 = step1[1] * -cospi_18_64 + step1[6] * cospi_14_64; - temp2 = step1[0] * -cospi_2_64 + step1[7] * cospi_30_64; - out[7] = (tran_low_t)fdct_round_shift(temp1); - out[15] = (tran_low_t)fdct_round_shift(temp2); -} - -static void fadst4(const tran_low_t *input, tran_low_t *output) { - tran_high_t x0, x1, x2, x3; - tran_high_t s0, s1, s2, s3, s4, s5, s6, s7; - - x0 = input[0]; - x1 = input[1]; - x2 = input[2]; - x3 = input[3]; - - if (!(x0 | x1 | x2 | x3)) { - output[0] = output[1] = output[2] = output[3] = 0; - return; - } - - s0 = sinpi_1_9 * x0; - s1 = sinpi_4_9 * x0; - s2 = sinpi_2_9 * x1; - s3 = sinpi_1_9 * x1; - s4 = sinpi_3_9 * x2; - s5 = sinpi_4_9 * x3; - s6 = sinpi_2_9 * x3; - s7 = x0 + x1 - x3; - - x0 = s0 + s2 + s5; - x1 = sinpi_3_9 * s7; - x2 = s1 - s3 + s6; - x3 = s4; - - s0 = x0 + x3; - s1 = x1; - s2 = x2 - x3; - s3 = x2 - x0 + x3; - - // 1-D transform scaling factor is sqrt(2). - output[0] = (tran_low_t)fdct_round_shift(s0); - output[1] = (tran_low_t)fdct_round_shift(s1); - output[2] = (tran_low_t)fdct_round_shift(s2); - output[3] = (tran_low_t)fdct_round_shift(s3); -} - -static void fadst8(const tran_low_t *input, tran_low_t *output) { - tran_high_t s0, s1, s2, s3, s4, s5, s6, s7; - - tran_high_t x0 = input[7]; - tran_high_t x1 = input[0]; - tran_high_t x2 = input[5]; - tran_high_t x3 = input[2]; - tran_high_t x4 = input[3]; - tran_high_t x5 = input[4]; - tran_high_t x6 = input[1]; - tran_high_t x7 = input[6]; - - // stage 1 - s0 = cospi_2_64 * x0 + cospi_30_64 * x1; - s1 = cospi_30_64 * x0 - cospi_2_64 * x1; - s2 = cospi_10_64 * x2 + cospi_22_64 * x3; - s3 = cospi_22_64 * x2 - cospi_10_64 * x3; - s4 = cospi_18_64 * x4 + cospi_14_64 * x5; - s5 = cospi_14_64 * x4 - cospi_18_64 * x5; - s6 = cospi_26_64 * x6 + cospi_6_64 * x7; - s7 = cospi_6_64 * x6 - cospi_26_64 * x7; - - x0 = fdct_round_shift(s0 + s4); - x1 = fdct_round_shift(s1 + s5); - x2 = fdct_round_shift(s2 + s6); - x3 = fdct_round_shift(s3 + s7); - x4 = fdct_round_shift(s0 - s4); - x5 = fdct_round_shift(s1 - s5); - x6 = fdct_round_shift(s2 - s6); - x7 = fdct_round_shift(s3 - s7); - - // stage 2 - s0 = x0; - s1 = x1; - s2 = x2; - s3 = x3; - s4 = cospi_8_64 * x4 + cospi_24_64 * x5; - s5 = cospi_24_64 * x4 - cospi_8_64 * x5; - s6 = -cospi_24_64 * x6 + cospi_8_64 * x7; - s7 = cospi_8_64 * x6 + cospi_24_64 * x7; - - x0 = s0 + s2; - x1 = s1 + s3; - x2 = s0 - s2; - x3 = s1 - s3; - x4 = fdct_round_shift(s4 + s6); - x5 = fdct_round_shift(s5 + s7); - x6 = fdct_round_shift(s4 - s6); - x7 = fdct_round_shift(s5 - s7); - - // stage 3 - s2 = cospi_16_64 * (x2 + x3); - s3 = cospi_16_64 * (x2 - x3); - s6 = cospi_16_64 * (x6 + x7); - s7 = cospi_16_64 * (x6 - x7); - - x2 = fdct_round_shift(s2); - x3 = fdct_round_shift(s3); - x6 = fdct_round_shift(s6); - x7 = fdct_round_shift(s7); - - output[0] = (tran_low_t)x0; - output[1] = (tran_low_t)-x4; - output[2] = (tran_low_t)x6; - output[3] = (tran_low_t)-x2; - output[4] = (tran_low_t)x3; - output[5] = (tran_low_t)-x7; - output[6] = (tran_low_t)x5; - output[7] = (tran_low_t)-x1; -} - -static void fadst16(const tran_low_t *input, tran_low_t *output) { - tran_high_t s0, s1, s2, s3, s4, s5, s6, s7, s8; - tran_high_t s9, s10, s11, s12, s13, s14, s15; - - tran_high_t x0 = input[15]; - tran_high_t x1 = input[0]; - tran_high_t x2 = input[13]; - tran_high_t x3 = input[2]; - tran_high_t x4 = input[11]; - tran_high_t x5 = input[4]; - tran_high_t x6 = input[9]; - tran_high_t x7 = input[6]; - tran_high_t x8 = input[7]; - tran_high_t x9 = input[8]; - tran_high_t x10 = input[5]; - tran_high_t x11 = input[10]; - tran_high_t x12 = input[3]; - tran_high_t x13 = input[12]; - tran_high_t x14 = input[1]; - tran_high_t x15 = input[14]; - - // stage 1 - s0 = x0 * cospi_1_64 + x1 * cospi_31_64; - s1 = x0 * cospi_31_64 - x1 * cospi_1_64; - s2 = x2 * cospi_5_64 + x3 * cospi_27_64; - s3 = x2 * cospi_27_64 - x3 * cospi_5_64; - s4 = x4 * cospi_9_64 + x5 * cospi_23_64; - s5 = x4 * cospi_23_64 - x5 * cospi_9_64; - s6 = x6 * cospi_13_64 + x7 * cospi_19_64; - s7 = x6 * cospi_19_64 - x7 * cospi_13_64; - s8 = x8 * cospi_17_64 + x9 * cospi_15_64; - s9 = x8 * cospi_15_64 - x9 * cospi_17_64; - s10 = x10 * cospi_21_64 + x11 * cospi_11_64; - s11 = x10 * cospi_11_64 - x11 * cospi_21_64; - s12 = x12 * cospi_25_64 + x13 * cospi_7_64; - s13 = x12 * cospi_7_64 - x13 * cospi_25_64; - s14 = x14 * cospi_29_64 + x15 * cospi_3_64; - s15 = x14 * cospi_3_64 - x15 * cospi_29_64; - - x0 = fdct_round_shift(s0 + s8); - x1 = fdct_round_shift(s1 + s9); - x2 = fdct_round_shift(s2 + s10); - x3 = fdct_round_shift(s3 + s11); - x4 = fdct_round_shift(s4 + s12); - x5 = fdct_round_shift(s5 + s13); - x6 = fdct_round_shift(s6 + s14); - x7 = fdct_round_shift(s7 + s15); - x8 = fdct_round_shift(s0 - s8); - x9 = fdct_round_shift(s1 - s9); - x10 = fdct_round_shift(s2 - s10); - x11 = fdct_round_shift(s3 - s11); - x12 = fdct_round_shift(s4 - s12); - x13 = fdct_round_shift(s5 - s13); - x14 = fdct_round_shift(s6 - s14); - x15 = fdct_round_shift(s7 - s15); - - // stage 2 - s0 = x0; - s1 = x1; - s2 = x2; - s3 = x3; - s4 = x4; - s5 = x5; - s6 = x6; - s7 = x7; - s8 = x8 * cospi_4_64 + x9 * cospi_28_64; - s9 = x8 * cospi_28_64 - x9 * cospi_4_64; - s10 = x10 * cospi_20_64 + x11 * cospi_12_64; - s11 = x10 * cospi_12_64 - x11 * cospi_20_64; - s12 = -x12 * cospi_28_64 + x13 * cospi_4_64; - s13 = x12 * cospi_4_64 + x13 * cospi_28_64; - s14 = -x14 * cospi_12_64 + x15 * cospi_20_64; - s15 = x14 * cospi_20_64 + x15 * cospi_12_64; - - x0 = s0 + s4; - x1 = s1 + s5; - x2 = s2 + s6; - x3 = s3 + s7; - x4 = s0 - s4; - x5 = s1 - s5; - x6 = s2 - s6; - x7 = s3 - s7; - x8 = fdct_round_shift(s8 + s12); - x9 = fdct_round_shift(s9 + s13); - x10 = fdct_round_shift(s10 + s14); - x11 = fdct_round_shift(s11 + s15); - x12 = fdct_round_shift(s8 - s12); - x13 = fdct_round_shift(s9 - s13); - x14 = fdct_round_shift(s10 - s14); - x15 = fdct_round_shift(s11 - s15); - - // stage 3 - s0 = x0; - s1 = x1; - s2 = x2; - s3 = x3; - s4 = x4 * cospi_8_64 + x5 * cospi_24_64; - s5 = x4 * cospi_24_64 - x5 * cospi_8_64; - s6 = -x6 * cospi_24_64 + x7 * cospi_8_64; - s7 = x6 * cospi_8_64 + x7 * cospi_24_64; - s8 = x8; - s9 = x9; - s10 = x10; - s11 = x11; - s12 = x12 * cospi_8_64 + x13 * cospi_24_64; - s13 = x12 * cospi_24_64 - x13 * cospi_8_64; - s14 = -x14 * cospi_24_64 + x15 * cospi_8_64; - s15 = x14 * cospi_8_64 + x15 * cospi_24_64; - - x0 = s0 + s2; - x1 = s1 + s3; - x2 = s0 - s2; - x3 = s1 - s3; - x4 = fdct_round_shift(s4 + s6); - x5 = fdct_round_shift(s5 + s7); - x6 = fdct_round_shift(s4 - s6); - x7 = fdct_round_shift(s5 - s7); - x8 = s8 + s10; - x9 = s9 + s11; - x10 = s8 - s10; - x11 = s9 - s11; - x12 = fdct_round_shift(s12 + s14); - x13 = fdct_round_shift(s13 + s15); - x14 = fdct_round_shift(s12 - s14); - x15 = fdct_round_shift(s13 - s15); - - // stage 4 - s2 = (-cospi_16_64) * (x2 + x3); - s3 = cospi_16_64 * (x2 - x3); - s6 = cospi_16_64 * (x6 + x7); - s7 = cospi_16_64 * (-x6 + x7); - s10 = cospi_16_64 * (x10 + x11); - s11 = cospi_16_64 * (-x10 + x11); - s14 = (-cospi_16_64) * (x14 + x15); - s15 = cospi_16_64 * (x14 - x15); - - x2 = fdct_round_shift(s2); - x3 = fdct_round_shift(s3); - x6 = fdct_round_shift(s6); - x7 = fdct_round_shift(s7); - x10 = fdct_round_shift(s10); - x11 = fdct_round_shift(s11); - x14 = fdct_round_shift(s14); - x15 = fdct_round_shift(s15); - - output[0] = (tran_low_t)x0; - output[1] = (tran_low_t)-x8; - output[2] = (tran_low_t)x12; - output[3] = (tran_low_t)-x4; - output[4] = (tran_low_t)x6; - output[5] = (tran_low_t)x14; - output[6] = (tran_low_t)x10; - output[7] = (tran_low_t)x2; - output[8] = (tran_low_t)x3; - output[9] = (tran_low_t)x11; - output[10] = (tran_low_t)x15; - output[11] = (tran_low_t)x7; - output[12] = (tran_low_t)x5; - output[13] = (tran_low_t)-x13; - output[14] = (tran_low_t)x9; - output[15] = (tran_low_t)-x1; -} - -static const transform_2d FHT_4[] = { - { fdct4, fdct4 }, // DCT_DCT = 0 - { fadst4, fdct4 }, // ADST_DCT = 1 - { fdct4, fadst4 }, // DCT_ADST = 2 - { fadst4, fadst4 } // ADST_ADST = 3 -}; - -static const transform_2d FHT_8[] = { - { fdct8, fdct8 }, // DCT_DCT = 0 - { fadst8, fdct8 }, // ADST_DCT = 1 - { fdct8, fadst8 }, // DCT_ADST = 2 - { fadst8, fadst8 } // ADST_ADST = 3 -}; - -static const transform_2d FHT_16[] = { - { fdct16, fdct16 }, // DCT_DCT = 0 - { fadst16, fdct16 }, // ADST_DCT = 1 - { fdct16, fadst16 }, // DCT_ADST = 2 - { fadst16, fadst16 } // ADST_ADST = 3 -}; - -void vp9_fht4x4_c(const int16_t *input, tran_low_t *output, int stride, - int tx_type) { - if (tx_type == DCT_DCT) { - vpx_fdct4x4_c(input, output, stride); - } else { - tran_low_t out[4 * 4]; - int i, j; - tran_low_t temp_in[4], temp_out[4]; - const transform_2d ht = FHT_4[tx_type]; - - // Columns - for (i = 0; i < 4; ++i) { - for (j = 0; j < 4; ++j) temp_in[j] = input[j * stride + i] * 16; - if (i == 0 && temp_in[0]) temp_in[0] += 1; - ht.cols(temp_in, temp_out); - for (j = 0; j < 4; ++j) out[j * 4 + i] = temp_out[j]; - } - - // Rows - for (i = 0; i < 4; ++i) { - for (j = 0; j < 4; ++j) temp_in[j] = out[j + i * 4]; - ht.rows(temp_in, temp_out); - for (j = 0; j < 4; ++j) output[j + i * 4] = (temp_out[j] + 1) >> 2; - } - } -} - -void vp9_fht8x8_c(const int16_t *input, tran_low_t *output, int stride, - int tx_type) { - if (tx_type == DCT_DCT) { - vpx_fdct8x8_c(input, output, stride); - } else { - tran_low_t out[64]; - int i, j; - tran_low_t temp_in[8], temp_out[8]; - const transform_2d ht = FHT_8[tx_type]; - - // Columns - for (i = 0; i < 8; ++i) { - for (j = 0; j < 8; ++j) temp_in[j] = input[j * stride + i] * 4; - ht.cols(temp_in, temp_out); - for (j = 0; j < 8; ++j) out[j * 8 + i] = temp_out[j]; - } - - // Rows - for (i = 0; i < 8; ++i) { - for (j = 0; j < 8; ++j) temp_in[j] = out[j + i * 8]; - ht.rows(temp_in, temp_out); - for (j = 0; j < 8; ++j) - output[j + i * 8] = (temp_out[j] + (temp_out[j] < 0)) >> 1; - } - } -} - -/* 4-point reversible, orthonormal Walsh-Hadamard in 3.5 adds, 0.5 shifts per - pixel. */ -void vp9_fwht4x4_c(const int16_t *input, tran_low_t *output, int stride) { - int i; - tran_high_t a1, b1, c1, d1, e1; - const int16_t *ip_pass0 = input; - const tran_low_t *ip = NULL; - tran_low_t *op = output; - - for (i = 0; i < 4; i++) { - a1 = ip_pass0[0 * stride]; - b1 = ip_pass0[1 * stride]; - c1 = ip_pass0[2 * stride]; - d1 = ip_pass0[3 * stride]; - - a1 += b1; - d1 = d1 - c1; - e1 = (a1 - d1) >> 1; - b1 = e1 - b1; - c1 = e1 - c1; - a1 -= c1; - d1 += b1; - op[0] = (tran_low_t)a1; - op[4] = (tran_low_t)c1; - op[8] = (tran_low_t)d1; - op[12] = (tran_low_t)b1; - - ip_pass0++; - op++; - } - ip = output; - op = output; - - for (i = 0; i < 4; i++) { - a1 = ip[0]; - b1 = ip[1]; - c1 = ip[2]; - d1 = ip[3]; - - a1 += b1; - d1 -= c1; - e1 = (a1 - d1) >> 1; - b1 = e1 - b1; - c1 = e1 - c1; - a1 -= c1; - d1 += b1; - op[0] = (tran_low_t)(a1 * UNIT_QUANT_FACTOR); - op[1] = (tran_low_t)(c1 * UNIT_QUANT_FACTOR); - op[2] = (tran_low_t)(d1 * UNIT_QUANT_FACTOR); - op[3] = (tran_low_t)(b1 * UNIT_QUANT_FACTOR); - - ip += 4; - op += 4; - } -} - -void vp9_fht16x16_c(const int16_t *input, tran_low_t *output, int stride, - int tx_type) { - if (tx_type == DCT_DCT) { - vpx_fdct16x16_c(input, output, stride); - } else { - tran_low_t out[256]; - int i, j; - tran_low_t temp_in[16], temp_out[16]; - const transform_2d ht = FHT_16[tx_type]; - - // Columns - for (i = 0; i < 16; ++i) { - for (j = 0; j < 16; ++j) temp_in[j] = input[j * stride + i] * 4; - ht.cols(temp_in, temp_out); - for (j = 0; j < 16; ++j) - out[j * 16 + i] = (temp_out[j] + 1 + (temp_out[j] < 0)) >> 2; - } - - // Rows - for (i = 0; i < 16; ++i) { - for (j = 0; j < 16; ++j) temp_in[j] = out[j + i * 16]; - ht.rows(temp_in, temp_out); - for (j = 0; j < 16; ++j) output[j + i * 16] = temp_out[j]; - } - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -void vp9_highbd_fht4x4_c(const int16_t *input, tran_low_t *output, int stride, - int tx_type) { - vp9_fht4x4_c(input, output, stride, tx_type); -} - -void vp9_highbd_fht8x8_c(const int16_t *input, tran_low_t *output, int stride, - int tx_type) { - vp9_fht8x8_c(input, output, stride, tx_type); -} - -void vp9_highbd_fwht4x4_c(const int16_t *input, tran_low_t *output, - int stride) { - vp9_fwht4x4_c(input, output, stride); -} - -void vp9_highbd_fht16x16_c(const int16_t *input, tran_low_t *output, int stride, - int tx_type) { - vp9_fht16x16_c(input, output, stride, tx_type); -} -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_denoiser.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_denoiser.c deleted file mode 100644 index e5dffa90..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_denoiser.c +++ /dev/null @@ -1,839 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_scale/yv12config.h" -#include "vpx/vpx_integer.h" -#include "vp9/common/vp9_reconinter.h" -#include "vp9/encoder/vp9_context_tree.h" -#include "vp9/encoder/vp9_denoiser.h" -#include "vp9/encoder/vp9_encoder.h" - -#ifdef OUTPUT_YUV_DENOISED -static void make_grayscale(YV12_BUFFER_CONFIG *yuv); -#endif - -static int absdiff_thresh(BLOCK_SIZE bs, int increase_denoising) { - (void)bs; - return 3 + (increase_denoising ? 1 : 0); -} - -static int delta_thresh(BLOCK_SIZE bs, int increase_denoising) { - (void)bs; - (void)increase_denoising; - return 4; -} - -static int noise_motion_thresh(BLOCK_SIZE bs, int increase_denoising) { - (void)bs; - (void)increase_denoising; - return 625; -} - -static unsigned int sse_thresh(BLOCK_SIZE bs, int increase_denoising) { - return (1 << num_pels_log2_lookup[bs]) * (increase_denoising ? 80 : 40); -} - -static int sse_diff_thresh(BLOCK_SIZE bs, int increase_denoising, - int motion_magnitude) { - if (motion_magnitude > noise_motion_thresh(bs, increase_denoising)) { - if (increase_denoising) - return (1 << num_pels_log2_lookup[bs]) << 2; - else - return 0; - } else { - return (1 << num_pels_log2_lookup[bs]) << 4; - } -} - -static int total_adj_weak_thresh(BLOCK_SIZE bs, int increase_denoising) { - return (1 << num_pels_log2_lookup[bs]) * (increase_denoising ? 3 : 2); -} - -// TODO(jackychen): If increase_denoising is enabled in the future, -// we might need to update the code for calculating 'total_adj' in -// case the C code is not bit-exact with corresponding sse2 code. -int vp9_denoiser_filter_c(const uint8_t *sig, int sig_stride, - const uint8_t *mc_avg, int mc_avg_stride, - uint8_t *avg, int avg_stride, int increase_denoising, - BLOCK_SIZE bs, int motion_magnitude) { - int r, c; - const uint8_t *sig_start = sig; - const uint8_t *mc_avg_start = mc_avg; - uint8_t *avg_start = avg; - int diff, adj, absdiff, delta; - int adj_val[] = { 3, 4, 6 }; - int total_adj = 0; - int shift_inc = 1; - - // If motion_magnitude is small, making the denoiser more aggressive by - // increasing the adjustment for each level. Add another increment for - // blocks that are labeled for increase denoising. - if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) { - if (increase_denoising) { - shift_inc = 2; - } - adj_val[0] += shift_inc; - adj_val[1] += shift_inc; - adj_val[2] += shift_inc; - } - - // First attempt to apply a strong temporal denoising filter. - for (r = 0; r < (4 << b_height_log2_lookup[bs]); ++r) { - for (c = 0; c < (4 << b_width_log2_lookup[bs]); ++c) { - diff = mc_avg[c] - sig[c]; - absdiff = abs(diff); - - if (absdiff <= absdiff_thresh(bs, increase_denoising)) { - avg[c] = mc_avg[c]; - total_adj += diff; - } else { - switch (absdiff) { - case 4: - case 5: - case 6: - case 7: adj = adj_val[0]; break; - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: adj = adj_val[1]; break; - default: adj = adj_val[2]; - } - if (diff > 0) { - avg[c] = VPXMIN(UINT8_MAX, sig[c] + adj); - total_adj += adj; - } else { - avg[c] = VPXMAX(0, sig[c] - adj); - total_adj -= adj; - } - } - } - sig += sig_stride; - avg += avg_stride; - mc_avg += mc_avg_stride; - } - - // If the strong filter did not modify the signal too much, we're all set. - if (abs(total_adj) <= total_adj_strong_thresh(bs, increase_denoising)) { - return FILTER_BLOCK; - } - - // Otherwise, we try to dampen the filter if the delta is not too high. - delta = ((abs(total_adj) - total_adj_strong_thresh(bs, increase_denoising)) >> - num_pels_log2_lookup[bs]) + - 1; - - if (delta >= delta_thresh(bs, increase_denoising)) { - return COPY_BLOCK; - } - - mc_avg = mc_avg_start; - avg = avg_start; - sig = sig_start; - for (r = 0; r < (4 << b_height_log2_lookup[bs]); ++r) { - for (c = 0; c < (4 << b_width_log2_lookup[bs]); ++c) { - diff = mc_avg[c] - sig[c]; - adj = abs(diff); - if (adj > delta) { - adj = delta; - } - if (diff > 0) { - // Diff positive means we made positive adjustment above - // (in first try/attempt), so now make negative adjustment to bring - // denoised signal down. - avg[c] = VPXMAX(0, avg[c] - adj); - total_adj -= adj; - } else { - // Diff negative means we made negative adjustment above - // (in first try/attempt), so now make positive adjustment to bring - // denoised signal up. - avg[c] = VPXMIN(UINT8_MAX, avg[c] + adj); - total_adj += adj; - } - } - sig += sig_stride; - avg += avg_stride; - mc_avg += mc_avg_stride; - } - - // We can use the filter if it has been sufficiently dampened - if (abs(total_adj) <= total_adj_weak_thresh(bs, increase_denoising)) { - return FILTER_BLOCK; - } - return COPY_BLOCK; -} - -static uint8_t *block_start(uint8_t *framebuf, int stride, int mi_row, - int mi_col) { - return framebuf + (stride * mi_row << 3) + (mi_col << 3); -} - -static VP9_DENOISER_DECISION perform_motion_compensation( - VP9_COMMON *const cm, VP9_DENOISER *denoiser, MACROBLOCK *mb, BLOCK_SIZE bs, - int increase_denoising, int mi_row, int mi_col, PICK_MODE_CONTEXT *ctx, - int motion_magnitude, int is_skin, int *zeromv_filter, int consec_zeromv, - int num_spatial_layers, int width, int lst_fb_idx, int gld_fb_idx, - int use_svc, int spatial_layer, int use_gf_temporal_ref) { - const int sse_diff = (ctx->newmv_sse == UINT_MAX) - ? 0 - : ((int)ctx->zeromv_sse - (int)ctx->newmv_sse); - int frame; - int denoise_layer_idx = 0; - MACROBLOCKD *filter_mbd = &mb->e_mbd; - MODE_INFO *mi = filter_mbd->mi[0]; - MODE_INFO saved_mi; - int i; - struct buf_2d saved_dst[MAX_MB_PLANE]; - struct buf_2d saved_pre[MAX_MB_PLANE]; - const RefBuffer *saved_block_refs[2]; - MV_REFERENCE_FRAME saved_frame; - - frame = ctx->best_reference_frame; - - saved_mi = *mi; - - if (is_skin && (motion_magnitude > 0 || consec_zeromv < 4)) return COPY_BLOCK; - - // Avoid denoising small blocks. When noise > kDenLow or frame width > 480, - // denoise 16x16 blocks. - if (bs == BLOCK_8X8 || bs == BLOCK_8X16 || bs == BLOCK_16X8 || - (bs == BLOCK_16X16 && width > 480 && - denoiser->denoising_level <= kDenLow)) - return COPY_BLOCK; - - // If the best reference frame uses inter-prediction and there is enough of a - // difference in sum-squared-error, use it. - if (frame != INTRA_FRAME && frame != ALTREF_FRAME && frame != GOLDEN_FRAME && - sse_diff > sse_diff_thresh(bs, increase_denoising, motion_magnitude)) { - mi->ref_frame[0] = ctx->best_reference_frame; - mi->mode = ctx->best_sse_inter_mode; - mi->mv[0] = ctx->best_sse_mv; - } else { - // Otherwise, use the zero reference frame. - frame = ctx->best_zeromv_reference_frame; - ctx->newmv_sse = ctx->zeromv_sse; - // Bias to last reference. - if ((num_spatial_layers > 1 && !use_gf_temporal_ref) || - frame == ALTREF_FRAME || - (frame == GOLDEN_FRAME && use_gf_temporal_ref) || - (frame != LAST_FRAME && - ((ctx->zeromv_lastref_sse < (5 * ctx->zeromv_sse) >> 2) || - denoiser->denoising_level >= kDenHigh))) { - frame = LAST_FRAME; - ctx->newmv_sse = ctx->zeromv_lastref_sse; - } - mi->ref_frame[0] = frame; - mi->mode = ZEROMV; - mi->mv[0].as_int = 0; - ctx->best_sse_inter_mode = ZEROMV; - ctx->best_sse_mv.as_int = 0; - *zeromv_filter = 1; - if (denoiser->denoising_level > kDenMedium) { - motion_magnitude = 0; - } - } - - saved_frame = frame; - // When using SVC, we need to map REF_FRAME to the frame buffer index. - if (use_svc) { - if (frame == LAST_FRAME) - frame = lst_fb_idx + 1; - else if (frame == GOLDEN_FRAME) - frame = gld_fb_idx + 1; - // Shift for the second spatial layer. - if (num_spatial_layers - spatial_layer == 2) - frame = frame + denoiser->num_ref_frames; - denoise_layer_idx = num_spatial_layers - spatial_layer - 1; - } - - // Force copy (no denoise, copy source in denoised buffer) if - // running_avg_y[frame] is NULL. - if (denoiser->running_avg_y[frame].buffer_alloc == NULL) { - // Restore everything to its original state - *mi = saved_mi; - return COPY_BLOCK; - } - - if (ctx->newmv_sse > sse_thresh(bs, increase_denoising)) { - // Restore everything to its original state - *mi = saved_mi; - return COPY_BLOCK; - } - if (motion_magnitude > (noise_motion_thresh(bs, increase_denoising) << 3)) { - // Restore everything to its original state - *mi = saved_mi; - return COPY_BLOCK; - } - - // We will restore these after motion compensation. - for (i = 0; i < MAX_MB_PLANE; ++i) { - saved_pre[i] = filter_mbd->plane[i].pre[0]; - saved_dst[i] = filter_mbd->plane[i].dst; - } - saved_block_refs[0] = filter_mbd->block_refs[0]; - - // Set the pointers in the MACROBLOCKD to point to the buffers in the denoiser - // struct. - filter_mbd->plane[0].pre[0].buf = - block_start(denoiser->running_avg_y[frame].y_buffer, - denoiser->running_avg_y[frame].y_stride, mi_row, mi_col); - filter_mbd->plane[0].pre[0].stride = denoiser->running_avg_y[frame].y_stride; - filter_mbd->plane[1].pre[0].buf = - block_start(denoiser->running_avg_y[frame].u_buffer, - denoiser->running_avg_y[frame].uv_stride, mi_row, mi_col); - filter_mbd->plane[1].pre[0].stride = denoiser->running_avg_y[frame].uv_stride; - filter_mbd->plane[2].pre[0].buf = - block_start(denoiser->running_avg_y[frame].v_buffer, - denoiser->running_avg_y[frame].uv_stride, mi_row, mi_col); - filter_mbd->plane[2].pre[0].stride = denoiser->running_avg_y[frame].uv_stride; - - filter_mbd->plane[0].dst.buf = block_start( - denoiser->mc_running_avg_y[denoise_layer_idx].y_buffer, - denoiser->mc_running_avg_y[denoise_layer_idx].y_stride, mi_row, mi_col); - filter_mbd->plane[0].dst.stride = - denoiser->mc_running_avg_y[denoise_layer_idx].y_stride; - filter_mbd->plane[1].dst.buf = block_start( - denoiser->mc_running_avg_y[denoise_layer_idx].u_buffer, - denoiser->mc_running_avg_y[denoise_layer_idx].uv_stride, mi_row, mi_col); - filter_mbd->plane[1].dst.stride = - denoiser->mc_running_avg_y[denoise_layer_idx].uv_stride; - filter_mbd->plane[2].dst.buf = block_start( - denoiser->mc_running_avg_y[denoise_layer_idx].v_buffer, - denoiser->mc_running_avg_y[denoise_layer_idx].uv_stride, mi_row, mi_col); - filter_mbd->plane[2].dst.stride = - denoiser->mc_running_avg_y[denoise_layer_idx].uv_stride; - - set_ref_ptrs(cm, filter_mbd, saved_frame, NO_REF_FRAME); - vp9_build_inter_predictors_sby(filter_mbd, mi_row, mi_col, bs); - - // Restore everything to its original state - *mi = saved_mi; - filter_mbd->block_refs[0] = saved_block_refs[0]; - for (i = 0; i < MAX_MB_PLANE; ++i) { - filter_mbd->plane[i].pre[0] = saved_pre[i]; - filter_mbd->plane[i].dst = saved_dst[i]; - } - - return FILTER_BLOCK; -} - -void vp9_denoiser_denoise(VP9_COMP *cpi, MACROBLOCK *mb, int mi_row, int mi_col, - BLOCK_SIZE bs, PICK_MODE_CONTEXT *ctx, - VP9_DENOISER_DECISION *denoiser_decision, - int use_gf_temporal_ref) { - int mv_col, mv_row; - int motion_magnitude = 0; - int zeromv_filter = 0; - VP9_DENOISER *denoiser = &cpi->denoiser; - VP9_DENOISER_DECISION decision = COPY_BLOCK; - - const int shift = - cpi->svc.number_spatial_layers - cpi->svc.spatial_layer_id == 2 - ? denoiser->num_ref_frames - : 0; - YV12_BUFFER_CONFIG avg = denoiser->running_avg_y[INTRA_FRAME + shift]; - const int denoise_layer_index = - cpi->svc.number_spatial_layers - cpi->svc.spatial_layer_id - 1; - YV12_BUFFER_CONFIG mc_avg = denoiser->mc_running_avg_y[denoise_layer_index]; - uint8_t *avg_start = block_start(avg.y_buffer, avg.y_stride, mi_row, mi_col); - - uint8_t *mc_avg_start = - block_start(mc_avg.y_buffer, mc_avg.y_stride, mi_row, mi_col); - struct buf_2d src = mb->plane[0].src; - int is_skin = 0; - int increase_denoising = 0; - int consec_zeromv = 0; - int last_is_reference = cpi->ref_frame_flags & VP9_LAST_FLAG; - mv_col = ctx->best_sse_mv.as_mv.col; - mv_row = ctx->best_sse_mv.as_mv.row; - motion_magnitude = mv_row * mv_row + mv_col * mv_col; - - if (cpi->use_skin_detection && bs <= BLOCK_32X32 && - denoiser->denoising_level < kDenHigh) { - int motion_level = (motion_magnitude < 16) ? 0 : 1; - // If motion for current block is small/zero, compute consec_zeromv for - // skin detection (early exit in skin detection is done for large - // consec_zeromv when current block has small/zero motion). - consec_zeromv = 0; - if (motion_level == 0) { - VP9_COMMON *const cm = &cpi->common; - int j, i; - // Loop through the 8x8 sub-blocks. - const int bw = num_8x8_blocks_wide_lookup[bs]; - const int bh = num_8x8_blocks_high_lookup[bs]; - const int xmis = VPXMIN(cm->mi_cols - mi_col, bw); - const int ymis = VPXMIN(cm->mi_rows - mi_row, bh); - const int block_index = mi_row * cm->mi_cols + mi_col; - consec_zeromv = 100; - for (i = 0; i < ymis; i++) { - for (j = 0; j < xmis; j++) { - int bl_index = block_index + i * cm->mi_cols + j; - consec_zeromv = VPXMIN(cpi->consec_zero_mv[bl_index], consec_zeromv); - // No need to keep checking 8x8 blocks if any of the sub-blocks - // has small consec_zeromv (since threshold for no_skin based on - // zero/small motion in skin detection is high, i.e., > 4). - if (consec_zeromv < 4) { - i = ymis; - break; - } - } - } - } - // TODO(marpan): Compute skin detection over sub-blocks. - is_skin = vp9_compute_skin_block( - mb->plane[0].src.buf, mb->plane[1].src.buf, mb->plane[2].src.buf, - mb->plane[0].src.stride, mb->plane[1].src.stride, bs, consec_zeromv, - motion_level); - } - if (!is_skin && denoiser->denoising_level == kDenHigh) increase_denoising = 1; - - // Copy block if LAST_FRAME is not a reference. - // Last doesn't always exist when SVC layers are dynamically changed, e.g. top - // spatial layer doesn't have last reference when it's brought up for the - // first time on the fly. - if (last_is_reference && denoiser->denoising_level >= kDenLow && - !ctx->sb_skip_denoising) - decision = perform_motion_compensation( - &cpi->common, denoiser, mb, bs, increase_denoising, mi_row, mi_col, ctx, - motion_magnitude, is_skin, &zeromv_filter, consec_zeromv, - cpi->svc.number_spatial_layers, cpi->Source->y_width, cpi->lst_fb_idx, - cpi->gld_fb_idx, cpi->use_svc, cpi->svc.spatial_layer_id, - use_gf_temporal_ref); - - if (decision == FILTER_BLOCK) { - decision = vp9_denoiser_filter(src.buf, src.stride, mc_avg_start, - mc_avg.y_stride, avg_start, avg.y_stride, - increase_denoising, bs, motion_magnitude); - } - - if (decision == FILTER_BLOCK) { - vpx_convolve_copy(avg_start, avg.y_stride, src.buf, src.stride, NULL, 0, 0, - 0, 0, num_4x4_blocks_wide_lookup[bs] << 2, - num_4x4_blocks_high_lookup[bs] << 2); - } else { // COPY_BLOCK - vpx_convolve_copy(src.buf, src.stride, avg_start, avg.y_stride, NULL, 0, 0, - 0, 0, num_4x4_blocks_wide_lookup[bs] << 2, - num_4x4_blocks_high_lookup[bs] << 2); - } - *denoiser_decision = decision; - if (decision == FILTER_BLOCK && zeromv_filter == 1) - *denoiser_decision = FILTER_ZEROMV_BLOCK; -} - -static void copy_frame(YV12_BUFFER_CONFIG *const dest, - const YV12_BUFFER_CONFIG *const src) { - int r; - const uint8_t *srcbuf = src->y_buffer; - uint8_t *destbuf = dest->y_buffer; - - assert(dest->y_width == src->y_width); - assert(dest->y_height == src->y_height); - - for (r = 0; r < dest->y_height; ++r) { - memcpy(destbuf, srcbuf, dest->y_width); - destbuf += dest->y_stride; - srcbuf += src->y_stride; - } -} - -static void swap_frame_buffer(YV12_BUFFER_CONFIG *const dest, - YV12_BUFFER_CONFIG *const src) { - uint8_t *tmp_buf = dest->y_buffer; - assert(dest->y_width == src->y_width); - assert(dest->y_height == src->y_height); - dest->y_buffer = src->y_buffer; - src->y_buffer = tmp_buf; -} - -void vp9_denoiser_update_frame_info( - VP9_DENOISER *denoiser, YV12_BUFFER_CONFIG src, struct SVC *svc, - FRAME_TYPE frame_type, int refresh_alt_ref_frame, int refresh_golden_frame, - int refresh_last_frame, int alt_fb_idx, int gld_fb_idx, int lst_fb_idx, - int resized, int svc_refresh_denoiser_buffers, int second_spatial_layer) { - const int shift = second_spatial_layer ? denoiser->num_ref_frames : 0; - // Copy source into denoised reference buffers on KEY_FRAME or - // if the just encoded frame was resized. For SVC, copy source if the base - // spatial layer was key frame. - if (frame_type == KEY_FRAME || resized != 0 || denoiser->reset || - svc_refresh_denoiser_buffers) { - int i; - // Start at 1 so as not to overwrite the INTRA_FRAME - for (i = 1; i < denoiser->num_ref_frames; ++i) { - if (denoiser->running_avg_y[i + shift].buffer_alloc != NULL) - copy_frame(&denoiser->running_avg_y[i + shift], &src); - } - denoiser->reset = 0; - return; - } - - if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS && - svc->use_set_ref_frame_config) { - int i; - for (i = 0; i < REF_FRAMES; i++) { - if (svc->update_buffer_slot[svc->spatial_layer_id] & (1 << i)) - copy_frame(&denoiser->running_avg_y[i + 1 + shift], - &denoiser->running_avg_y[INTRA_FRAME + shift]); - } - } else { - // If more than one refresh occurs, must copy frame buffer. - if ((refresh_alt_ref_frame + refresh_golden_frame + refresh_last_frame) > - 1) { - if (refresh_alt_ref_frame) { - copy_frame(&denoiser->running_avg_y[alt_fb_idx + 1 + shift], - &denoiser->running_avg_y[INTRA_FRAME + shift]); - } - if (refresh_golden_frame) { - copy_frame(&denoiser->running_avg_y[gld_fb_idx + 1 + shift], - &denoiser->running_avg_y[INTRA_FRAME + shift]); - } - if (refresh_last_frame) { - copy_frame(&denoiser->running_avg_y[lst_fb_idx + 1 + shift], - &denoiser->running_avg_y[INTRA_FRAME + shift]); - } - } else { - if (refresh_alt_ref_frame) { - swap_frame_buffer(&denoiser->running_avg_y[alt_fb_idx + 1 + shift], - &denoiser->running_avg_y[INTRA_FRAME + shift]); - } - if (refresh_golden_frame) { - swap_frame_buffer(&denoiser->running_avg_y[gld_fb_idx + 1 + shift], - &denoiser->running_avg_y[INTRA_FRAME + shift]); - } - if (refresh_last_frame) { - swap_frame_buffer(&denoiser->running_avg_y[lst_fb_idx + 1 + shift], - &denoiser->running_avg_y[INTRA_FRAME + shift]); - } - } - } -} - -void vp9_denoiser_reset_frame_stats(PICK_MODE_CONTEXT *ctx) { - ctx->zeromv_sse = UINT_MAX; - ctx->newmv_sse = UINT_MAX; - ctx->zeromv_lastref_sse = UINT_MAX; - ctx->best_sse_mv.as_int = 0; -} - -void vp9_denoiser_update_frame_stats(MODE_INFO *mi, unsigned int sse, - PREDICTION_MODE mode, - PICK_MODE_CONTEXT *ctx) { - if (mi->mv[0].as_int == 0 && sse < ctx->zeromv_sse) { - ctx->zeromv_sse = sse; - ctx->best_zeromv_reference_frame = mi->ref_frame[0]; - if (mi->ref_frame[0] == LAST_FRAME) ctx->zeromv_lastref_sse = sse; - } - - if (mi->mv[0].as_int != 0 && sse < ctx->newmv_sse) { - ctx->newmv_sse = sse; - ctx->best_sse_inter_mode = mode; - ctx->best_sse_mv = mi->mv[0]; - ctx->best_reference_frame = mi->ref_frame[0]; - } -} - -static int vp9_denoiser_realloc_svc_helper(VP9_COMMON *cm, - VP9_DENOISER *denoiser, int fb_idx) { - int fail = 0; - if (denoiser->running_avg_y[fb_idx].buffer_alloc == NULL) { - fail = - vpx_alloc_frame_buffer(&denoiser->running_avg_y[fb_idx], cm->width, - cm->height, cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS, 0); - if (fail) { - vp9_denoiser_free(denoiser); - return 1; - } - } - return 0; -} - -int vp9_denoiser_realloc_svc(VP9_COMMON *cm, VP9_DENOISER *denoiser, - struct SVC *svc, int svc_buf_shift, - int refresh_alt, int refresh_gld, int refresh_lst, - int alt_fb_idx, int gld_fb_idx, int lst_fb_idx) { - int fail = 0; - if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS && - svc->use_set_ref_frame_config) { - int i; - for (i = 0; i < REF_FRAMES; i++) { - if (cm->frame_type == KEY_FRAME || - svc->update_buffer_slot[svc->spatial_layer_id] & (1 << i)) { - fail = vp9_denoiser_realloc_svc_helper(cm, denoiser, - i + 1 + svc_buf_shift); - } - } - } else { - if (refresh_alt) { - // Increase the frame buffer index by 1 to map it to the buffer index in - // the denoiser. - fail = vp9_denoiser_realloc_svc_helper(cm, denoiser, - alt_fb_idx + 1 + svc_buf_shift); - if (fail) return 1; - } - if (refresh_gld) { - fail = vp9_denoiser_realloc_svc_helper(cm, denoiser, - gld_fb_idx + 1 + svc_buf_shift); - if (fail) return 1; - } - if (refresh_lst) { - fail = vp9_denoiser_realloc_svc_helper(cm, denoiser, - lst_fb_idx + 1 + svc_buf_shift); - if (fail) return 1; - } - } - return 0; -} - -int vp9_denoiser_alloc(VP9_COMMON *cm, struct SVC *svc, VP9_DENOISER *denoiser, - int use_svc, int noise_sen, int width, int height, - int ssx, int ssy, -#if CONFIG_VP9_HIGHBITDEPTH - int use_highbitdepth, -#endif - int border) { - int i, layer, fail, init_num_ref_frames; - const int legacy_byte_alignment = 0; - int num_layers = 1; - int scaled_width = width; - int scaled_height = height; - if (use_svc) { - LAYER_CONTEXT *lc = &svc->layer_context[svc->spatial_layer_id * - svc->number_temporal_layers + - svc->temporal_layer_id]; - get_layer_resolution(width, height, lc->scaling_factor_num, - lc->scaling_factor_den, &scaled_width, &scaled_height); - // For SVC: only denoise at most 2 spatial (highest) layers. - if (noise_sen >= 2) - // Denoise from one spatial layer below the top. - svc->first_layer_denoise = VPXMAX(svc->number_spatial_layers - 2, 0); - else - // Only denoise the top spatial layer. - svc->first_layer_denoise = VPXMAX(svc->number_spatial_layers - 1, 0); - num_layers = svc->number_spatial_layers - svc->first_layer_denoise; - } - assert(denoiser != NULL); - denoiser->num_ref_frames = use_svc ? SVC_REF_FRAMES : NONSVC_REF_FRAMES; - init_num_ref_frames = use_svc ? MAX_REF_FRAMES : NONSVC_REF_FRAMES; - denoiser->num_layers = num_layers; - CHECK_MEM_ERROR(&cm->error, denoiser->running_avg_y, - vpx_calloc(denoiser->num_ref_frames * num_layers, - sizeof(denoiser->running_avg_y[0]))); - CHECK_MEM_ERROR( - &cm->error, denoiser->mc_running_avg_y, - vpx_calloc(num_layers, sizeof(denoiser->mc_running_avg_y[0]))); - - for (layer = 0; layer < num_layers; ++layer) { - const int denoise_width = (layer == 0) ? width : scaled_width; - const int denoise_height = (layer == 0) ? height : scaled_height; - for (i = 0; i < init_num_ref_frames; ++i) { - fail = vpx_alloc_frame_buffer( - &denoiser->running_avg_y[i + denoiser->num_ref_frames * layer], - denoise_width, denoise_height, ssx, ssy, -#if CONFIG_VP9_HIGHBITDEPTH - use_highbitdepth, -#endif - border, legacy_byte_alignment); - if (fail) { - vp9_denoiser_free(denoiser); - return 1; - } -#ifdef OUTPUT_YUV_DENOISED - make_grayscale(&denoiser->running_avg_y[i]); -#endif - } - - fail = vpx_alloc_frame_buffer(&denoiser->mc_running_avg_y[layer], - denoise_width, denoise_height, ssx, ssy, -#if CONFIG_VP9_HIGHBITDEPTH - use_highbitdepth, -#endif - border, legacy_byte_alignment); - if (fail) { - vp9_denoiser_free(denoiser); - return 1; - } - } - - // denoiser->last_source only used for noise_estimation, so only for top - // layer. - fail = vpx_alloc_frame_buffer(&denoiser->last_source, width, height, ssx, ssy, -#if CONFIG_VP9_HIGHBITDEPTH - use_highbitdepth, -#endif - border, legacy_byte_alignment); - if (fail) { - vp9_denoiser_free(denoiser); - return 1; - } -#ifdef OUTPUT_YUV_DENOISED - make_grayscale(&denoiser->running_avg_y[i]); -#endif - denoiser->frame_buffer_initialized = 1; - denoiser->denoising_level = kDenMedium; - denoiser->prev_denoising_level = kDenMedium; - denoiser->reset = 0; - denoiser->current_denoiser_frame = 0; - return 0; -} - -void vp9_denoiser_free(VP9_DENOISER *denoiser) { - int i; - if (denoiser == NULL) { - return; - } - denoiser->frame_buffer_initialized = 0; - for (i = 0; i < denoiser->num_ref_frames * denoiser->num_layers; ++i) { - vpx_free_frame_buffer(&denoiser->running_avg_y[i]); - } - vpx_free(denoiser->running_avg_y); - denoiser->running_avg_y = NULL; - - for (i = 0; i < denoiser->num_layers; ++i) { - vpx_free_frame_buffer(&denoiser->mc_running_avg_y[i]); - } - - vpx_free(denoiser->mc_running_avg_y); - denoiser->mc_running_avg_y = NULL; - vpx_free_frame_buffer(&denoiser->last_source); -} - -static void force_refresh_longterm_ref(VP9_COMP *const cpi) { - SVC *const svc = &cpi->svc; - // If long term reference is used, force refresh of that slot, so - // denoiser buffer for long term reference stays in sync. - if (svc->use_gf_temporal_ref_current_layer) { - int index = svc->spatial_layer_id; - if (svc->number_spatial_layers == 3) index = svc->spatial_layer_id - 1; - assert(index >= 0); - cpi->alt_fb_idx = svc->buffer_gf_temporal_ref[index].idx; - cpi->refresh_alt_ref_frame = 1; - } -} - -void vp9_denoiser_set_noise_level(VP9_COMP *const cpi, int noise_level) { - VP9_DENOISER *const denoiser = &cpi->denoiser; - denoiser->denoising_level = noise_level; - if (denoiser->denoising_level > kDenLowLow && - denoiser->prev_denoising_level == kDenLowLow) { - denoiser->reset = 1; - force_refresh_longterm_ref(cpi); - } else { - denoiser->reset = 0; - } - denoiser->prev_denoising_level = denoiser->denoising_level; -} - -// Scale/increase the partition threshold -// for denoiser speed-up. -int64_t vp9_scale_part_thresh(int64_t threshold, VP9_DENOISER_LEVEL noise_level, - int content_state, int temporal_layer_id) { - if ((content_state == kLowSadLowSumdiff) || - (content_state == kHighSadLowSumdiff) || - (content_state == kLowVarHighSumdiff) || (noise_level == kDenHigh) || - (temporal_layer_id != 0)) { - int64_t scaled_thr = - (temporal_layer_id < 2) ? (3 * threshold) >> 1 : (7 * threshold) >> 2; - return scaled_thr; - } else { - return (5 * threshold) >> 2; - } -} - -// Scale/increase the ac skip threshold for -// denoiser speed-up. -int64_t vp9_scale_acskip_thresh(int64_t threshold, - VP9_DENOISER_LEVEL noise_level, int abs_sumdiff, - int temporal_layer_id) { - if (noise_level >= kDenLow && abs_sumdiff < 5) - return threshold *= (noise_level == kDenLow) ? 2 - : (temporal_layer_id == 2) ? 10 - : 6; - else - return threshold; -} - -void vp9_denoiser_reset_on_first_frame(VP9_COMP *const cpi) { - if (vp9_denoise_svc_non_key(cpi) && - cpi->denoiser.current_denoiser_frame == 0) { - cpi->denoiser.reset = 1; - force_refresh_longterm_ref(cpi); - } -} - -void vp9_denoiser_update_ref_frame(VP9_COMP *const cpi) { - VP9_COMMON *const cm = &cpi->common; - SVC *const svc = &cpi->svc; - - if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc(cpi) && - cpi->denoiser.denoising_level > kDenLowLow) { - int svc_refresh_denoiser_buffers = 0; - int denoise_svc_second_layer = 0; - FRAME_TYPE frame_type = cm->intra_only ? KEY_FRAME : cm->frame_type; - cpi->denoiser.current_denoiser_frame++; - if (cpi->use_svc) { - const int svc_buf_shift = - svc->number_spatial_layers - svc->spatial_layer_id == 2 - ? cpi->denoiser.num_ref_frames - : 0; - int layer = - LAYER_IDS_TO_IDX(svc->spatial_layer_id, svc->temporal_layer_id, - svc->number_temporal_layers); - LAYER_CONTEXT *const lc = &svc->layer_context[layer]; - svc_refresh_denoiser_buffers = - lc->is_key_frame || svc->spatial_layer_sync[svc->spatial_layer_id]; - denoise_svc_second_layer = - svc->number_spatial_layers - svc->spatial_layer_id == 2 ? 1 : 0; - // Check if we need to allocate extra buffers in the denoiser - // for refreshed frames. - if (vp9_denoiser_realloc_svc(cm, &cpi->denoiser, svc, svc_buf_shift, - cpi->refresh_alt_ref_frame, - cpi->refresh_golden_frame, - cpi->refresh_last_frame, cpi->alt_fb_idx, - cpi->gld_fb_idx, cpi->lst_fb_idx)) - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to re-allocate denoiser for SVC"); - } - vp9_denoiser_update_frame_info( - &cpi->denoiser, *cpi->Source, svc, frame_type, - cpi->refresh_alt_ref_frame, cpi->refresh_golden_frame, - cpi->refresh_last_frame, cpi->alt_fb_idx, cpi->gld_fb_idx, - cpi->lst_fb_idx, cpi->resize_pending, svc_refresh_denoiser_buffers, - denoise_svc_second_layer); - } -} - -#ifdef OUTPUT_YUV_DENOISED -static void make_grayscale(YV12_BUFFER_CONFIG *yuv) { - int r, c; - uint8_t *u = yuv->u_buffer; - uint8_t *v = yuv->v_buffer; - - for (r = 0; r < yuv->uv_height; ++r) { - for (c = 0; c < yuv->uv_width; ++c) { - u[c] = UINT8_MAX / 2; - v[c] = UINT8_MAX / 2; - } - u += yuv->uv_stride; - v += yuv->uv_stride; - } -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_denoiser.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_denoiser.h deleted file mode 100644 index 1973e989..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_denoiser.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_DENOISER_H_ -#define VPX_VP9_ENCODER_VP9_DENOISER_H_ - -#include "vp9/encoder/vp9_block.h" -#include "vp9/encoder/vp9_skin_detection.h" -#include "vpx_scale/yv12config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MOTION_MAGNITUDE_THRESHOLD (8 * 3) - -// Denoiser is used in non svc real-time mode which does not use alt-ref, so no -// need to allocate for it, and hence we need MAX_REF_FRAME - 1 -#define NONSVC_REF_FRAMES MAX_REF_FRAMES - 1 - -// Number of frame buffers when SVC is used. [0] for current denoised buffer and -// [1..8] for REF_FRAMES -#define SVC_REF_FRAMES 9 - -typedef enum vp9_denoiser_decision { - COPY_BLOCK, - FILTER_BLOCK, - FILTER_ZEROMV_BLOCK -} VP9_DENOISER_DECISION; - -typedef enum vp9_denoiser_level { - kDenLowLow, - kDenLow, - kDenMedium, - kDenHigh -} VP9_DENOISER_LEVEL; - -typedef struct vp9_denoiser { - YV12_BUFFER_CONFIG *running_avg_y; - YV12_BUFFER_CONFIG *mc_running_avg_y; - YV12_BUFFER_CONFIG last_source; - int frame_buffer_initialized; - int reset; - int num_ref_frames; - int num_layers; - unsigned int current_denoiser_frame; - VP9_DENOISER_LEVEL denoising_level; - VP9_DENOISER_LEVEL prev_denoising_level; -} VP9_DENOISER; - -typedef struct { - int64_t zero_last_cost_orig; - int *ref_frame_cost; - int_mv (*frame_mv)[MAX_REF_FRAMES]; - int reuse_inter_pred; - TX_SIZE best_tx_size; - PREDICTION_MODE best_mode; - MV_REFERENCE_FRAME best_ref_frame; - INTERP_FILTER best_pred_filter; - uint8_t best_mode_skip_txfm; -} VP9_PICKMODE_CTX_DEN; - -struct VP9_COMP; -struct SVC; - -void vp9_denoiser_update_frame_info( - VP9_DENOISER *denoiser, YV12_BUFFER_CONFIG src, struct SVC *svc, - FRAME_TYPE frame_type, int refresh_alt_ref_frame, int refresh_golden_frame, - int refresh_last_frame, int alt_fb_idx, int gld_fb_idx, int lst_fb_idx, - int resized, int svc_refresh_denoiser_buffers, int second_spatial_layer); - -void vp9_denoiser_denoise(struct VP9_COMP *cpi, MACROBLOCK *mb, int mi_row, - int mi_col, BLOCK_SIZE bs, PICK_MODE_CONTEXT *ctx, - VP9_DENOISER_DECISION *denoiser_decision, - int use_gf_temporal_ref); - -void vp9_denoiser_reset_frame_stats(PICK_MODE_CONTEXT *ctx); - -void vp9_denoiser_update_frame_stats(MODE_INFO *mi, unsigned int sse, - PREDICTION_MODE mode, - PICK_MODE_CONTEXT *ctx); - -int vp9_denoiser_realloc_svc(VP9_COMMON *cm, VP9_DENOISER *denoiser, - struct SVC *svc, int svc_buf_shift, - int refresh_alt, int refresh_gld, int refresh_lst, - int alt_fb_idx, int gld_fb_idx, int lst_fb_idx); - -int vp9_denoiser_alloc(VP9_COMMON *cm, struct SVC *svc, VP9_DENOISER *denoiser, - int use_svc, int noise_sen, int width, int height, - int ssx, int ssy, -#if CONFIG_VP9_HIGHBITDEPTH - int use_highbitdepth, -#endif - int border); - -#if CONFIG_VP9_TEMPORAL_DENOISING -// This function is used by both c and sse2 denoiser implementations. -// Define it as a static function within the scope where vp9_denoiser.h -// is referenced. -static INLINE int total_adj_strong_thresh(BLOCK_SIZE bs, - int increase_denoising) { - return (1 << num_pels_log2_lookup[bs]) * (increase_denoising ? 3 : 2); -} -#endif - -void vp9_denoiser_free(VP9_DENOISER *denoiser); - -void vp9_denoiser_set_noise_level(struct VP9_COMP *const cpi, int noise_level); - -void vp9_denoiser_reset_on_first_frame(struct VP9_COMP *const cpi); - -int64_t vp9_scale_part_thresh(int64_t threshold, VP9_DENOISER_LEVEL noise_level, - int content_state, int temporal_layer_id); - -int64_t vp9_scale_acskip_thresh(int64_t threshold, - VP9_DENOISER_LEVEL noise_level, int abs_sumdiff, - int temporal_layer_id); - -void vp9_denoiser_update_ref_frame(struct VP9_COMP *const cpi); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_DENOISER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodeframe.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodeframe.c deleted file mode 100644 index 937f22e8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodeframe.c +++ /dev/null @@ -1,6587 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "./vp9_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "./vpx_config.h" - -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/vpx_timer.h" -#include "vpx_ports/system_state.h" -#include "vpx_util/vpx_pthread.h" -#if CONFIG_MISMATCH_DEBUG -#include "vpx_util/vpx_debug_util.h" -#endif // CONFIG_MISMATCH_DEBUG - -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_entropy.h" -#include "vp9/common/vp9_entropymode.h" -#include "vp9/common/vp9_idct.h" -#include "vp9/common/vp9_mvref_common.h" -#include "vp9/common/vp9_pred_common.h" -#include "vp9/common/vp9_quant_common.h" -#include "vp9/common/vp9_reconintra.h" -#include "vp9/common/vp9_reconinter.h" -#include "vp9/common/vp9_seg_common.h" -#include "vp9/common/vp9_tile_common.h" -#if !CONFIG_REALTIME_ONLY -#include "vp9/encoder/vp9_aq_360.h" -#include "vp9/encoder/vp9_aq_complexity.h" -#endif -#include "vp9/encoder/vp9_aq_cyclicrefresh.h" -#if !CONFIG_REALTIME_ONLY -#include "vp9/encoder/vp9_aq_variance.h" -#endif -#include "vp9/encoder/vp9_encodeframe.h" -#include "vp9/encoder/vp9_encodemb.h" -#include "vp9/encoder/vp9_encodemv.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_ethread.h" -#include "vp9/encoder/vp9_extend.h" -#include "vp9/encoder/vp9_multi_thread.h" -#include "vp9/encoder/vp9_partition_models.h" -#include "vp9/encoder/vp9_pickmode.h" -#include "vp9/encoder/vp9_rd.h" -#include "vp9/encoder/vp9_rdopt.h" -#include "vp9/encoder/vp9_segmentation.h" -#include "vp9/encoder/vp9_tokenize.h" - -static void encode_superblock(VP9_COMP *cpi, ThreadData *td, TOKENEXTRA **t, - int output_enabled, int mi_row, int mi_col, - BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx); - -// This is used as a reference when computing the source variance for the -// purpose of activity masking. -// Eventually this should be replaced by custom no-reference routines, -// which will be faster. -static const uint8_t VP9_VAR_OFFS[64] = { - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 -}; - -#if CONFIG_VP9_HIGHBITDEPTH -static const uint16_t VP9_HIGH_VAR_OFFS_8[64] = { - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 -}; - -static const uint16_t VP9_HIGH_VAR_OFFS_10[64] = { - 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, - 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, - 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, - 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, - 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, - 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, - 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, - 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4 -}; - -static const uint16_t VP9_HIGH_VAR_OFFS_12[64] = { - 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, - 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, - 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, - 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, - 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, - 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, - 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, - 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, - 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, - 128 * 16 -}; -#endif // CONFIG_VP9_HIGHBITDEPTH - -unsigned int vp9_get_sby_variance(VP9_COMP *cpi, const struct buf_2d *ref, - BLOCK_SIZE bs) { - unsigned int sse; - const unsigned int var = - cpi->fn_ptr[bs].vf(ref->buf, ref->stride, VP9_VAR_OFFS, 0, &sse); - return var; -} - -#if CONFIG_VP9_HIGHBITDEPTH -unsigned int vp9_high_get_sby_variance(VP9_COMP *cpi, const struct buf_2d *ref, - BLOCK_SIZE bs, int bd) { - unsigned int var, sse; - switch (bd) { - case 10: - var = - cpi->fn_ptr[bs].vf(ref->buf, ref->stride, - CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_10), 0, &sse); - break; - case 12: - var = - cpi->fn_ptr[bs].vf(ref->buf, ref->stride, - CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_12), 0, &sse); - break; - case 8: - default: - var = - cpi->fn_ptr[bs].vf(ref->buf, ref->stride, - CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_8), 0, &sse); - break; - } - return var; -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -unsigned int vp9_get_sby_perpixel_variance(VP9_COMP *cpi, - const struct buf_2d *ref, - BLOCK_SIZE bs) { - return ROUND_POWER_OF_TWO(vp9_get_sby_variance(cpi, ref, bs), - num_pels_log2_lookup[bs]); -} - -#if CONFIG_VP9_HIGHBITDEPTH -unsigned int vp9_high_get_sby_perpixel_variance(VP9_COMP *cpi, - const struct buf_2d *ref, - BLOCK_SIZE bs, int bd) { - return (unsigned int)ROUND64_POWER_OF_TWO( - (int64_t)vp9_high_get_sby_variance(cpi, ref, bs, bd), - num_pels_log2_lookup[bs]); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static void set_segment_index(VP9_COMP *cpi, MACROBLOCK *const x, int mi_row, - int mi_col, BLOCK_SIZE bsize, int segment_index) { - VP9_COMMON *const cm = &cpi->common; - const struct segmentation *const seg = &cm->seg; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *mi = xd->mi[0]; - - const AQ_MODE aq_mode = cpi->oxcf.aq_mode; - const uint8_t *const map = - seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map; - - // Initialize the segmentation index as 0. - mi->segment_id = 0; - - // Skip the rest if AQ mode is disabled. - if (!seg->enabled) return; - - switch (aq_mode) { - case CYCLIC_REFRESH_AQ: - mi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col); - break; -#if !CONFIG_REALTIME_ONLY - case VARIANCE_AQ: - if (cm->frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame || - cpi->force_update_segmentation || - (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref)) { - int min_energy; - int max_energy; - // Get sub block energy range - if (bsize >= BLOCK_32X32) { - vp9_get_sub_block_energy(cpi, x, mi_row, mi_col, bsize, &min_energy, - &max_energy); - } else { - min_energy = bsize <= BLOCK_16X16 ? x->mb_energy - : vp9_block_energy(cpi, x, bsize); - } - mi->segment_id = vp9_vaq_segment_id(min_energy); - } else { - mi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col); - } - break; - case EQUATOR360_AQ: - if (cm->frame_type == KEY_FRAME || cpi->force_update_segmentation) - mi->segment_id = vp9_360aq_segment_id(mi_row, cm->mi_rows); - else - mi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col); - break; -#endif - case LOOKAHEAD_AQ: - mi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col); - break; - case PSNR_AQ: mi->segment_id = segment_index; break; - case PERCEPTUAL_AQ: mi->segment_id = x->segment_id; break; - default: - // NO_AQ or PSNR_AQ - break; - } - - // Set segment index if ROI map or active_map is enabled. - if (cpi->roi.enabled || cpi->active_map.enabled) - mi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col); - - vp9_init_plane_quantizers(cpi, x); -} - -// Lighter version of set_offsets that only sets the mode info -// pointers. -static INLINE void set_mode_info_offsets(VP9_COMMON *const cm, - MACROBLOCK *const x, - MACROBLOCKD *const xd, int mi_row, - int mi_col) { - const int idx_str = xd->mi_stride * mi_row + mi_col; - xd->mi = cm->mi_grid_visible + idx_str; - xd->mi[0] = cm->mi + idx_str; - x->mbmi_ext = x->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col); -} - -static void set_ssim_rdmult(VP9_COMP *const cpi, MACROBLOCK *const x, - const BLOCK_SIZE bsize, const int mi_row, - const int mi_col, int *const rdmult) { - const VP9_COMMON *const cm = &cpi->common; - - const int bsize_base = BLOCK_16X16; - const int num_8x8_w = num_8x8_blocks_wide_lookup[bsize_base]; - const int num_8x8_h = num_8x8_blocks_high_lookup[bsize_base]; - const int num_cols = (cm->mi_cols + num_8x8_w - 1) / num_8x8_w; - const int num_rows = (cm->mi_rows + num_8x8_h - 1) / num_8x8_h; - const int num_bcols = - (num_8x8_blocks_wide_lookup[bsize] + num_8x8_w - 1) / num_8x8_w; - const int num_brows = - (num_8x8_blocks_high_lookup[bsize] + num_8x8_h - 1) / num_8x8_h; - int row, col; - double num_of_mi = 0.0; - double geom_mean_of_scale = 0.0; - - assert(cpi->oxcf.tuning == VP8_TUNE_SSIM); - - for (row = mi_row / num_8x8_w; - row < num_rows && row < mi_row / num_8x8_w + num_brows; ++row) { - for (col = mi_col / num_8x8_h; - col < num_cols && col < mi_col / num_8x8_h + num_bcols; ++col) { - const int index = row * num_cols + col; - geom_mean_of_scale += log(cpi->mi_ssim_rdmult_scaling_factors[index]); - num_of_mi += 1.0; - } - } - geom_mean_of_scale = exp(geom_mean_of_scale / num_of_mi); - - *rdmult = (int)((double)(*rdmult) * geom_mean_of_scale); - *rdmult = VPXMAX(*rdmult, 0); - set_error_per_bit(x, *rdmult); - vpx_clear_system_state(); -} - -static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile, - MACROBLOCK *const x, int mi_row, int mi_col, - BLOCK_SIZE bsize) { - VP9_COMMON *const cm = &cpi->common; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - MACROBLOCKD *const xd = &x->e_mbd; - const int mi_width = num_8x8_blocks_wide_lookup[bsize]; - const int mi_height = num_8x8_blocks_high_lookup[bsize]; - MvLimits *const mv_limits = &x->mv_limits; - - set_skip_context(xd, mi_row, mi_col); - - set_mode_info_offsets(cm, x, xd, mi_row, mi_col); - - // Set up destination pointers. - vp9_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col); - - // Set up limit values for MV components. - // Mv beyond the range do not produce new/different prediction block. - mv_limits->row_min = -(((mi_row + mi_height) * MI_SIZE) + VP9_INTERP_EXTEND); - mv_limits->col_min = -(((mi_col + mi_width) * MI_SIZE) + VP9_INTERP_EXTEND); - mv_limits->row_max = (cm->mi_rows - mi_row) * MI_SIZE + VP9_INTERP_EXTEND; - mv_limits->col_max = (cm->mi_cols - mi_col) * MI_SIZE + VP9_INTERP_EXTEND; - - // Set up distance of MB to edge of frame in 1/8th pel units. - assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1))); - set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows, - cm->mi_cols); - - // Set up source buffers. - vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col); - - // R/D setup. - x->rddiv = cpi->rd.RDDIV; - x->rdmult = cpi->rd.RDMULT; - if (oxcf->tuning == VP8_TUNE_SSIM) { - set_ssim_rdmult(cpi, x, bsize, mi_row, mi_col, &x->rdmult); - } - - // required by vp9_append_sub8x8_mvs_for_idx() and vp9_find_best_ref_mvs() - xd->tile = *tile; -} - -static void duplicate_mode_info_in_sb(VP9_COMMON *cm, MACROBLOCKD *xd, - int mi_row, int mi_col, - BLOCK_SIZE bsize) { - const int block_width = - VPXMIN(num_8x8_blocks_wide_lookup[bsize], cm->mi_cols - mi_col); - const int block_height = - VPXMIN(num_8x8_blocks_high_lookup[bsize], cm->mi_rows - mi_row); - const int mi_stride = xd->mi_stride; - MODE_INFO *const src_mi = xd->mi[0]; - int i, j; - - for (j = 0; j < block_height; ++j) - for (i = 0; i < block_width; ++i) xd->mi[j * mi_stride + i] = src_mi; -} - -static void set_block_size(VP9_COMP *const cpi, MACROBLOCK *const x, - MACROBLOCKD *const xd, int mi_row, int mi_col, - BLOCK_SIZE bsize) { - if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) { - set_mode_info_offsets(&cpi->common, x, xd, mi_row, mi_col); - xd->mi[0]->sb_type = bsize; - } -} - -typedef struct { - // This struct is used for computing variance in choose_partitioning(), where - // the max number of samples within a superblock is 16x16 (with 4x4 avg). Even - // in high bitdepth, uint32_t is enough for sum_square_error (2^12 * 2^12 * 16 - // * 16 = 2^32). - uint32_t sum_square_error; - int32_t sum_error; - int log2_count; - int variance; -} Var; - -typedef struct { - Var none; - Var horz[2]; - Var vert[2]; -} partition_variance; - -typedef struct { - partition_variance part_variances; - Var split[4]; -} v4x4; - -typedef struct { - partition_variance part_variances; - v4x4 split[4]; -} v8x8; - -typedef struct { - partition_variance part_variances; - v8x8 split[4]; -} v16x16; - -typedef struct { - partition_variance part_variances; - v16x16 split[4]; -} v32x32; - -typedef struct { - partition_variance part_variances; - v32x32 split[4]; -} v64x64; - -typedef struct { - partition_variance *part_variances; - Var *split[4]; -} variance_node; - -typedef enum { - V16X16, - V32X32, - V64X64, -} TREE_LEVEL; - -static void tree_to_node(void *data, BLOCK_SIZE bsize, variance_node *node) { - int i; - node->part_variances = NULL; - switch (bsize) { - case BLOCK_64X64: { - v64x64 *vt = (v64x64 *)data; - node->part_variances = &vt->part_variances; - for (i = 0; i < 4; i++) - node->split[i] = &vt->split[i].part_variances.none; - break; - } - case BLOCK_32X32: { - v32x32 *vt = (v32x32 *)data; - node->part_variances = &vt->part_variances; - for (i = 0; i < 4; i++) - node->split[i] = &vt->split[i].part_variances.none; - break; - } - case BLOCK_16X16: { - v16x16 *vt = (v16x16 *)data; - node->part_variances = &vt->part_variances; - for (i = 0; i < 4; i++) - node->split[i] = &vt->split[i].part_variances.none; - break; - } - case BLOCK_8X8: { - v8x8 *vt = (v8x8 *)data; - node->part_variances = &vt->part_variances; - for (i = 0; i < 4; i++) - node->split[i] = &vt->split[i].part_variances.none; - break; - } - default: { - v4x4 *vt = (v4x4 *)data; - assert(bsize == BLOCK_4X4); - node->part_variances = &vt->part_variances; - for (i = 0; i < 4; i++) node->split[i] = &vt->split[i]; - break; - } - } -} - -// Set variance values given sum square error, sum error, count. -static void fill_variance(uint32_t s2, int32_t s, int c, Var *v) { - v->sum_square_error = s2; - v->sum_error = s; - v->log2_count = c; -} - -static void get_variance(Var *v) { - v->variance = - (int)(256 * (v->sum_square_error - - (uint32_t)(((int64_t)v->sum_error * v->sum_error) >> - v->log2_count)) >> - v->log2_count); -} - -static void sum_2_variances(const Var *a, const Var *b, Var *r) { - assert(a->log2_count == b->log2_count); - fill_variance(a->sum_square_error + b->sum_square_error, - a->sum_error + b->sum_error, a->log2_count + 1, r); -} - -static void fill_variance_tree(void *data, BLOCK_SIZE bsize) { - variance_node node; - memset(&node, 0, sizeof(node)); - tree_to_node(data, bsize, &node); - sum_2_variances(node.split[0], node.split[1], &node.part_variances->horz[0]); - sum_2_variances(node.split[2], node.split[3], &node.part_variances->horz[1]); - sum_2_variances(node.split[0], node.split[2], &node.part_variances->vert[0]); - sum_2_variances(node.split[1], node.split[3], &node.part_variances->vert[1]); - sum_2_variances(&node.part_variances->vert[0], &node.part_variances->vert[1], - &node.part_variances->none); -} - -static int set_vt_partitioning(VP9_COMP *cpi, MACROBLOCK *const x, - MACROBLOCKD *const xd, void *data, - BLOCK_SIZE bsize, int mi_row, int mi_col, - int64_t threshold, BLOCK_SIZE bsize_min, - int force_split) { - VP9_COMMON *const cm = &cpi->common; - variance_node vt; - const int block_width = num_8x8_blocks_wide_lookup[bsize]; - const int block_height = num_8x8_blocks_high_lookup[bsize]; - - assert(block_height == block_width); - tree_to_node(data, bsize, &vt); - - if (force_split == 1) return 0; - - // For bsize=bsize_min (16x16/8x8 for 8x8/4x4 downsampling), select if - // variance is below threshold, otherwise split will be selected. - // No check for vert/horiz split as too few samples for variance. - if (bsize == bsize_min) { - // Variance already computed to set the force_split. - if (frame_is_intra_only(cm)) get_variance(&vt.part_variances->none); - if (mi_col + block_width / 2 < cm->mi_cols && - mi_row + block_height / 2 < cm->mi_rows && - vt.part_variances->none.variance < threshold) { - set_block_size(cpi, x, xd, mi_row, mi_col, bsize); - return 1; - } - return 0; - } else if (bsize > bsize_min) { - // Variance already computed to set the force_split. - if (frame_is_intra_only(cm)) get_variance(&vt.part_variances->none); - // For key frame: take split for bsize above 32X32 or very high variance. - if (frame_is_intra_only(cm) && - (bsize > BLOCK_32X32 || - vt.part_variances->none.variance > (threshold << 4))) { - return 0; - } - // If variance is low, take the bsize (no split). - if (mi_col + block_width / 2 < cm->mi_cols && - mi_row + block_height / 2 < cm->mi_rows && - vt.part_variances->none.variance < threshold) { - set_block_size(cpi, x, xd, mi_row, mi_col, bsize); - return 1; - } - - // Check vertical split. - if (mi_row + block_height / 2 < cm->mi_rows) { - BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT); - get_variance(&vt.part_variances->vert[0]); - get_variance(&vt.part_variances->vert[1]); - if (vt.part_variances->vert[0].variance < threshold && - vt.part_variances->vert[1].variance < threshold && - get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) { - set_block_size(cpi, x, xd, mi_row, mi_col, subsize); - set_block_size(cpi, x, xd, mi_row, mi_col + block_width / 2, subsize); - return 1; - } - } - // Check horizontal split. - if (mi_col + block_width / 2 < cm->mi_cols) { - BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ); - get_variance(&vt.part_variances->horz[0]); - get_variance(&vt.part_variances->horz[1]); - if (vt.part_variances->horz[0].variance < threshold && - vt.part_variances->horz[1].variance < threshold && - get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) { - set_block_size(cpi, x, xd, mi_row, mi_col, subsize); - set_block_size(cpi, x, xd, mi_row + block_height / 2, mi_col, subsize); - return 1; - } - } - - return 0; - } - return 0; -} - -static int64_t scale_part_thresh_sumdiff(int64_t threshold_base, int speed, - int width, int height, - int content_state) { - if (speed >= 8) { - if (width <= 640 && height <= 480) - return (5 * threshold_base) >> 2; - else if ((content_state == kLowSadLowSumdiff) || - (content_state == kHighSadLowSumdiff) || - (content_state == kLowVarHighSumdiff)) - return (5 * threshold_base) >> 2; - } else if (speed == 7) { - if ((content_state == kLowSadLowSumdiff) || - (content_state == kHighSadLowSumdiff) || - (content_state == kLowVarHighSumdiff)) { - return (5 * threshold_base) >> 2; - } - } - return threshold_base; -} - -// Set the variance split thresholds for following the block sizes: -// 0 - threshold_64x64, 1 - threshold_32x32, 2 - threshold_16x16, -// 3 - vbp_threshold_8x8. vbp_threshold_8x8 (to split to 4x4 partition) is -// currently only used on key frame. -static void set_vbp_thresholds(VP9_COMP *cpi, int64_t thresholds[], int q, - int content_state) { - VP9_COMMON *const cm = &cpi->common; - const int is_key_frame = frame_is_intra_only(cm); - const int threshold_multiplier = - is_key_frame ? 20 : cpi->sf.variance_part_thresh_mult; - int64_t threshold_base = - (int64_t)(threshold_multiplier * cpi->y_dequant[q][1]); - - if (is_key_frame) { - thresholds[0] = threshold_base; - thresholds[1] = threshold_base >> 2; - thresholds[2] = threshold_base >> 2; - thresholds[3] = threshold_base << 2; - } else { - // Increase base variance threshold based on estimated noise level. - if (cpi->noise_estimate.enabled && cm->width >= 640 && cm->height >= 480) { - NOISE_LEVEL noise_level = - vp9_noise_estimate_extract_level(&cpi->noise_estimate); - if (noise_level == kHigh) - threshold_base = 3 * threshold_base; - else if (noise_level == kMedium) - threshold_base = threshold_base << 1; - else if (noise_level < kLow) - threshold_base = (7 * threshold_base) >> 3; - } -#if CONFIG_VP9_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc(cpi) && - cpi->oxcf.speed > 5 && cpi->denoiser.denoising_level >= kDenLow) - threshold_base = - vp9_scale_part_thresh(threshold_base, cpi->denoiser.denoising_level, - content_state, cpi->svc.temporal_layer_id); - else - threshold_base = - scale_part_thresh_sumdiff(threshold_base, cpi->oxcf.speed, cm->width, - cm->height, content_state); -#else - // Increase base variance threshold based on content_state/sum_diff level. - threshold_base = scale_part_thresh_sumdiff( - threshold_base, cpi->oxcf.speed, cm->width, cm->height, content_state); -#endif - thresholds[0] = threshold_base; - thresholds[2] = threshold_base << cpi->oxcf.speed; - if (cm->width >= 1280 && cm->height >= 720 && cpi->oxcf.speed < 7) - thresholds[2] = thresholds[2] << 1; - if (cm->width <= 352 && cm->height <= 288) { - thresholds[0] = threshold_base >> 3; - thresholds[1] = threshold_base >> 1; - thresholds[2] = threshold_base << 3; - if (cpi->rc.avg_frame_qindex[INTER_FRAME] > 220) - thresholds[2] = thresholds[2] << 2; - else if (cpi->rc.avg_frame_qindex[INTER_FRAME] > 200) - thresholds[2] = thresholds[2] << 1; - } else if (cm->width < 1280 && cm->height < 720) { - thresholds[1] = (5 * threshold_base) >> 2; - } else if (cm->width < 1920 && cm->height < 1080) { - thresholds[1] = threshold_base << 1; - } else { - thresholds[1] = (5 * threshold_base) >> 1; - } - if (cpi->sf.disable_16x16part_nonkey) thresholds[2] = INT64_MAX; - } -} - -void vp9_set_variance_partition_thresholds(VP9_COMP *cpi, int q, - int content_state) { - VP9_COMMON *const cm = &cpi->common; - SPEED_FEATURES *const sf = &cpi->sf; - const int is_key_frame = frame_is_intra_only(cm); - if (sf->partition_search_type != VAR_BASED_PARTITION && - sf->partition_search_type != REFERENCE_PARTITION) { - return; - } else { - set_vbp_thresholds(cpi, cpi->vbp_thresholds, q, content_state); - // The thresholds below are not changed locally. - if (is_key_frame) { - cpi->vbp_threshold_sad = 0; - cpi->vbp_threshold_copy = 0; - cpi->vbp_bsize_min = BLOCK_8X8; - } else { - if (cm->width <= 352 && cm->height <= 288) - cpi->vbp_threshold_sad = 10; - else - cpi->vbp_threshold_sad = (cpi->y_dequant[q][1] << 1) > 1000 - ? (cpi->y_dequant[q][1] << 1) - : 1000; - cpi->vbp_bsize_min = BLOCK_16X16; - if (cm->width <= 352 && cm->height <= 288) - cpi->vbp_threshold_copy = 4000; - else if (cm->width <= 640 && cm->height <= 360) - cpi->vbp_threshold_copy = 8000; - else - cpi->vbp_threshold_copy = (cpi->y_dequant[q][1] << 3) > 8000 - ? (cpi->y_dequant[q][1] << 3) - : 8000; - if (cpi->rc.high_source_sad || - (cpi->use_svc && cpi->svc.high_source_sad_superframe)) { - cpi->vbp_threshold_sad = 0; - cpi->vbp_threshold_copy = 0; - } - } - cpi->vbp_threshold_minmax = 15 + (q >> 3); - } -} - -// Compute the minmax over the 8x8 subblocks. -static int compute_minmax_8x8(const uint8_t *s, int sp, const uint8_t *d, - int dp, int x16_idx, int y16_idx, -#if CONFIG_VP9_HIGHBITDEPTH - int highbd_flag, -#endif - int pixels_wide, int pixels_high) { - int k; - int minmax_max = 0; - int minmax_min = 255; - // Loop over the 4 8x8 subblocks. - for (k = 0; k < 4; k++) { - int x8_idx = x16_idx + ((k & 1) << 3); - int y8_idx = y16_idx + ((k >> 1) << 3); - int min = 0; - int max = 0; - if (x8_idx < pixels_wide && y8_idx < pixels_high) { -#if CONFIG_VP9_HIGHBITDEPTH - if (highbd_flag & YV12_FLAG_HIGHBITDEPTH) { - vpx_highbd_minmax_8x8(s + y8_idx * sp + x8_idx, sp, - d + y8_idx * dp + x8_idx, dp, &min, &max); - } else { - vpx_minmax_8x8(s + y8_idx * sp + x8_idx, sp, d + y8_idx * dp + x8_idx, - dp, &min, &max); - } -#else - vpx_minmax_8x8(s + y8_idx * sp + x8_idx, sp, d + y8_idx * dp + x8_idx, dp, - &min, &max); -#endif - if ((max - min) > minmax_max) minmax_max = (max - min); - if ((max - min) < minmax_min) minmax_min = (max - min); - } - } - return (minmax_max - minmax_min); -} - -static void fill_variance_4x4avg(const uint8_t *s, int sp, const uint8_t *d, - int dp, int x8_idx, int y8_idx, v8x8 *vst, -#if CONFIG_VP9_HIGHBITDEPTH - int highbd_flag, -#endif - int pixels_wide, int pixels_high, - int is_key_frame) { - int k; - for (k = 0; k < 4; k++) { - int x4_idx = x8_idx + ((k & 1) << 2); - int y4_idx = y8_idx + ((k >> 1) << 2); - unsigned int sse = 0; - int sum = 0; - if (x4_idx < pixels_wide && y4_idx < pixels_high) { - int s_avg; - int d_avg = 128; -#if CONFIG_VP9_HIGHBITDEPTH - if (highbd_flag & YV12_FLAG_HIGHBITDEPTH) { - s_avg = vpx_highbd_avg_4x4(s + y4_idx * sp + x4_idx, sp); - if (!is_key_frame) - d_avg = vpx_highbd_avg_4x4(d + y4_idx * dp + x4_idx, dp); - } else { - s_avg = vpx_avg_4x4(s + y4_idx * sp + x4_idx, sp); - if (!is_key_frame) d_avg = vpx_avg_4x4(d + y4_idx * dp + x4_idx, dp); - } -#else - s_avg = vpx_avg_4x4(s + y4_idx * sp + x4_idx, sp); - if (!is_key_frame) d_avg = vpx_avg_4x4(d + y4_idx * dp + x4_idx, dp); -#endif - sum = s_avg - d_avg; - sse = sum * sum; - } - fill_variance(sse, sum, 0, &vst->split[k].part_variances.none); - } -} - -static void fill_variance_8x8avg(const uint8_t *s, int sp, const uint8_t *d, - int dp, int x16_idx, int y16_idx, v16x16 *vst, -#if CONFIG_VP9_HIGHBITDEPTH - int highbd_flag, -#endif - int pixels_wide, int pixels_high, - int is_key_frame) { - int k; - for (k = 0; k < 4; k++) { - int x8_idx = x16_idx + ((k & 1) << 3); - int y8_idx = y16_idx + ((k >> 1) << 3); - unsigned int sse = 0; - int sum = 0; - if (x8_idx < pixels_wide && y8_idx < pixels_high) { - int s_avg; - int d_avg = 128; -#if CONFIG_VP9_HIGHBITDEPTH - if (highbd_flag & YV12_FLAG_HIGHBITDEPTH) { - s_avg = vpx_highbd_avg_8x8(s + y8_idx * sp + x8_idx, sp); - if (!is_key_frame) - d_avg = vpx_highbd_avg_8x8(d + y8_idx * dp + x8_idx, dp); - } else { - s_avg = vpx_avg_8x8(s + y8_idx * sp + x8_idx, sp); - if (!is_key_frame) d_avg = vpx_avg_8x8(d + y8_idx * dp + x8_idx, dp); - } -#else - s_avg = vpx_avg_8x8(s + y8_idx * sp + x8_idx, sp); - if (!is_key_frame) d_avg = vpx_avg_8x8(d + y8_idx * dp + x8_idx, dp); -#endif - sum = s_avg - d_avg; - sse = sum * sum; - } - fill_variance(sse, sum, 0, &vst->split[k].part_variances.none); - } -} - -// Check if most of the superblock is skin content, and if so, force split to -// 32x32, and set x->sb_is_skin for use in mode selection. -static int skin_sb_split(VP9_COMP *cpi, const int low_res, int mi_row, - int mi_col, int *force_split) { - VP9_COMMON *const cm = &cpi->common; -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) return 0; -#endif - // Avoid checking superblocks on/near boundary and avoid low resolutions. - // Note superblock may still pick 64X64 if y_sad is very small - // (i.e., y_sad < cpi->vbp_threshold_sad) below. For now leave this as is. - if (!low_res && (mi_col >= 8 && mi_col + 8 < cm->mi_cols && mi_row >= 8 && - mi_row + 8 < cm->mi_rows)) { - int num_16x16_skin = 0; - int num_16x16_nonskin = 0; - const int block_index = mi_row * cm->mi_cols + mi_col; - const int bw = num_8x8_blocks_wide_lookup[BLOCK_64X64]; - const int bh = num_8x8_blocks_high_lookup[BLOCK_64X64]; - const int xmis = VPXMIN(cm->mi_cols - mi_col, bw); - const int ymis = VPXMIN(cm->mi_rows - mi_row, bh); - // Loop through the 16x16 sub-blocks. - int i, j; - for (i = 0; i < ymis; i += 2) { - for (j = 0; j < xmis; j += 2) { - int bl_index = block_index + i * cm->mi_cols + j; - int is_skin = cpi->skin_map[bl_index]; - num_16x16_skin += is_skin; - num_16x16_nonskin += (1 - is_skin); - if (num_16x16_nonskin > 3) { - // Exit loop if at least 4 of the 16x16 blocks are not skin. - i = ymis; - break; - } - } - } - if (num_16x16_skin > 12) { - *force_split = 1; - return 1; - } - } - return 0; -} - -static void set_low_temp_var_flag(VP9_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd, - v64x64 *vt, int64_t thresholds[], - MV_REFERENCE_FRAME ref_frame_partition, - int mi_col, int mi_row) { - int i, j; - VP9_COMMON *const cm = &cpi->common; - const int mv_thr = cm->width > 640 ? 8 : 4; - // Check temporal variance for bsize >= 16x16, if LAST_FRAME was selected and - // int_pro mv is small. If the temporal variance is small set the flag - // variance_low for the block. The variance threshold can be adjusted, the - // higher the more aggressive. - if (ref_frame_partition == LAST_FRAME && - (cpi->sf.short_circuit_low_temp_var == 1 || - (xd->mi[0]->mv[0].as_mv.col < mv_thr && - xd->mi[0]->mv[0].as_mv.col > -mv_thr && - xd->mi[0]->mv[0].as_mv.row < mv_thr && - xd->mi[0]->mv[0].as_mv.row > -mv_thr))) { - if (xd->mi[0]->sb_type == BLOCK_64X64) { - if ((vt->part_variances).none.variance < (thresholds[0] >> 1)) - x->variance_low[0] = 1; - } else if (xd->mi[0]->sb_type == BLOCK_64X32) { - for (i = 0; i < 2; i++) { - if (vt->part_variances.horz[i].variance < (thresholds[0] >> 2)) - x->variance_low[i + 1] = 1; - } - } else if (xd->mi[0]->sb_type == BLOCK_32X64) { - for (i = 0; i < 2; i++) { - if (vt->part_variances.vert[i].variance < (thresholds[0] >> 2)) - x->variance_low[i + 3] = 1; - } - } else { - for (i = 0; i < 4; i++) { - const int idx[4][2] = { { 0, 0 }, { 0, 4 }, { 4, 0 }, { 4, 4 } }; - const int idx_str = - cm->mi_stride * (mi_row + idx[i][0]) + mi_col + idx[i][1]; - MODE_INFO **this_mi = cm->mi_grid_visible + idx_str; - - if (cm->mi_cols <= mi_col + idx[i][1] || - cm->mi_rows <= mi_row + idx[i][0]) - continue; - - if ((*this_mi)->sb_type == BLOCK_32X32) { - int64_t threshold_32x32 = (cpi->sf.short_circuit_low_temp_var == 1 || - cpi->sf.short_circuit_low_temp_var == 3) - ? ((5 * thresholds[1]) >> 3) - : (thresholds[1] >> 1); - if (vt->split[i].part_variances.none.variance < threshold_32x32) - x->variance_low[i + 5] = 1; - } else if (cpi->sf.short_circuit_low_temp_var >= 2) { - // For 32x16 and 16x32 blocks, the flag is set on each 16x16 block - // inside. - if ((*this_mi)->sb_type == BLOCK_16X16 || - (*this_mi)->sb_type == BLOCK_32X16 || - (*this_mi)->sb_type == BLOCK_16X32) { - for (j = 0; j < 4; j++) { - if (vt->split[i].split[j].part_variances.none.variance < - (thresholds[2] >> 8)) - x->variance_low[(i << 2) + j + 9] = 1; - } - } - } - } - } - } -} - -static void copy_partitioning_helper(VP9_COMP *cpi, MACROBLOCK *x, - MACROBLOCKD *xd, BLOCK_SIZE bsize, - int mi_row, int mi_col) { - VP9_COMMON *const cm = &cpi->common; - BLOCK_SIZE *prev_part = cpi->prev_partition; - int start_pos = mi_row * cm->mi_stride + mi_col; - - const int bsl = b_width_log2_lookup[bsize]; - const int bs = (1 << bsl) >> 2; - BLOCK_SIZE subsize; - PARTITION_TYPE partition; - - if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - - partition = partition_lookup[bsl][prev_part[start_pos]]; - subsize = get_subsize(bsize, partition); - - if (subsize < BLOCK_8X8) { - set_block_size(cpi, x, xd, mi_row, mi_col, bsize); - } else { - switch (partition) { - case PARTITION_NONE: - set_block_size(cpi, x, xd, mi_row, mi_col, bsize); - break; - case PARTITION_HORZ: - set_block_size(cpi, x, xd, mi_row, mi_col, subsize); - set_block_size(cpi, x, xd, mi_row + bs, mi_col, subsize); - break; - case PARTITION_VERT: - set_block_size(cpi, x, xd, mi_row, mi_col, subsize); - set_block_size(cpi, x, xd, mi_row, mi_col + bs, subsize); - break; - default: - assert(partition == PARTITION_SPLIT); - copy_partitioning_helper(cpi, x, xd, subsize, mi_row, mi_col); - copy_partitioning_helper(cpi, x, xd, subsize, mi_row + bs, mi_col); - copy_partitioning_helper(cpi, x, xd, subsize, mi_row, mi_col + bs); - copy_partitioning_helper(cpi, x, xd, subsize, mi_row + bs, mi_col + bs); - break; - } - } -} - -static int copy_partitioning(VP9_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd, - int mi_row, int mi_col, int segment_id, - int sb_offset) { - int svc_copy_allowed = 1; - int frames_since_key_thresh = 1; - if (cpi->use_svc) { - // For SVC, don't allow copy if base spatial layer is key frame, or if - // frame is not a temporal enhancement layer frame. - int layer = LAYER_IDS_TO_IDX(0, cpi->svc.temporal_layer_id, - cpi->svc.number_temporal_layers); - const LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer]; - if (lc->is_key_frame || !cpi->svc.non_reference_frame) svc_copy_allowed = 0; - frames_since_key_thresh = cpi->svc.number_spatial_layers << 1; - } - if (cpi->rc.frames_since_key > frames_since_key_thresh && svc_copy_allowed && - !cpi->resize_pending && segment_id == CR_SEGMENT_ID_BASE && - cpi->prev_segment_id[sb_offset] == CR_SEGMENT_ID_BASE && - cpi->copied_frame_cnt[sb_offset] < cpi->max_copied_frame) { - if (cpi->prev_partition != NULL) { - copy_partitioning_helper(cpi, x, xd, BLOCK_64X64, mi_row, mi_col); - cpi->copied_frame_cnt[sb_offset] += 1; - memcpy(x->variance_low, &(cpi->prev_variance_low[sb_offset * 25]), - sizeof(x->variance_low)); - return 1; - } - } - - return 0; -} - -static int scale_partitioning_svc(VP9_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd, - BLOCK_SIZE bsize, int mi_row, int mi_col, - int mi_row_high, int mi_col_high) { - VP9_COMMON *const cm = &cpi->common; - SVC *const svc = &cpi->svc; - BLOCK_SIZE *prev_part = svc->prev_partition_svc; - // Variables with _high are for higher resolution. - int bsize_high = 0; - int subsize_high = 0; - const int bsl_high = b_width_log2_lookup[bsize]; - const int bs_high = (1 << bsl_high) >> 2; - const int has_rows = (mi_row_high + bs_high) < cm->mi_rows; - const int has_cols = (mi_col_high + bs_high) < cm->mi_cols; - - const int row_boundary_block_scale_factor[BLOCK_SIZES] = { 13, 13, 13, 1, 0, - 1, 1, 0, 1, 1, - 0, 1, 0 }; - const int col_boundary_block_scale_factor[BLOCK_SIZES] = { 13, 13, 13, 2, 2, - 0, 2, 2, 0, 2, - 2, 0, 0 }; - int start_pos; - BLOCK_SIZE bsize_low; - PARTITION_TYPE partition_high; - - if (mi_row_high >= cm->mi_rows || mi_col_high >= cm->mi_cols) return 0; - if (mi_row >= svc->mi_rows[svc->spatial_layer_id - 1] || - mi_col >= svc->mi_cols[svc->spatial_layer_id - 1]) - return 0; - - // Find corresponding (mi_col/mi_row) block down-scaled by 2x2. - start_pos = mi_row * (svc->mi_stride[svc->spatial_layer_id - 1]) + mi_col; - bsize_low = prev_part[start_pos]; - // The block size is too big for boundaries. Do variance based partitioning. - if ((!has_rows || !has_cols) && bsize_low > BLOCK_16X16) return 1; - - // For reference frames: return 1 (do variance-based partitioning) if the - // superblock is not low source sad and lower-resoln bsize is below 32x32. - if (!cpi->svc.non_reference_frame && !x->skip_low_source_sad && - bsize_low < BLOCK_32X32) - return 1; - - // Scale up block size by 2x2. Force 64x64 for size larger than 32x32. - if (bsize_low < BLOCK_32X32) { - bsize_high = bsize_low + 3; - } else if (bsize_low >= BLOCK_32X32) { - bsize_high = BLOCK_64X64; - } - // Scale up blocks on boundary. - if (!has_cols && has_rows) { - bsize_high = bsize_low + row_boundary_block_scale_factor[bsize_low]; - } else if (has_cols && !has_rows) { - bsize_high = bsize_low + col_boundary_block_scale_factor[bsize_low]; - } else if (!has_cols && !has_rows) { - bsize_high = bsize_low; - } - - partition_high = partition_lookup[bsl_high][bsize_high]; - subsize_high = get_subsize(bsize, partition_high); - - if (subsize_high < BLOCK_8X8) { - set_block_size(cpi, x, xd, mi_row_high, mi_col_high, bsize_high); - } else { - const int bsl = b_width_log2_lookup[bsize]; - const int bs = (1 << bsl) >> 2; - switch (partition_high) { - case PARTITION_NONE: - set_block_size(cpi, x, xd, mi_row_high, mi_col_high, bsize_high); - break; - case PARTITION_HORZ: - set_block_size(cpi, x, xd, mi_row_high, mi_col_high, subsize_high); - if (subsize_high < BLOCK_64X64) - set_block_size(cpi, x, xd, mi_row_high + bs_high, mi_col_high, - subsize_high); - break; - case PARTITION_VERT: - set_block_size(cpi, x, xd, mi_row_high, mi_col_high, subsize_high); - if (subsize_high < BLOCK_64X64) - set_block_size(cpi, x, xd, mi_row_high, mi_col_high + bs_high, - subsize_high); - break; - default: - assert(partition_high == PARTITION_SPLIT); - if (scale_partitioning_svc(cpi, x, xd, subsize_high, mi_row, mi_col, - mi_row_high, mi_col_high)) - return 1; - if (scale_partitioning_svc(cpi, x, xd, subsize_high, mi_row + (bs >> 1), - mi_col, mi_row_high + bs_high, mi_col_high)) - return 1; - if (scale_partitioning_svc(cpi, x, xd, subsize_high, mi_row, - mi_col + (bs >> 1), mi_row_high, - mi_col_high + bs_high)) - return 1; - if (scale_partitioning_svc(cpi, x, xd, subsize_high, mi_row + (bs >> 1), - mi_col + (bs >> 1), mi_row_high + bs_high, - mi_col_high + bs_high)) - return 1; - break; - } - } - - return 0; -} - -static void update_partition_svc(VP9_COMP *cpi, BLOCK_SIZE bsize, int mi_row, - int mi_col) { - VP9_COMMON *const cm = &cpi->common; - BLOCK_SIZE *prev_part = cpi->svc.prev_partition_svc; - int start_pos = mi_row * cm->mi_stride + mi_col; - const int bsl = b_width_log2_lookup[bsize]; - const int bs = (1 << bsl) >> 2; - BLOCK_SIZE subsize; - PARTITION_TYPE partition; - const MODE_INFO *mi = NULL; - int xx, yy; - - if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - - mi = cm->mi_grid_visible[start_pos]; - partition = partition_lookup[bsl][mi->sb_type]; - subsize = get_subsize(bsize, partition); - if (subsize < BLOCK_8X8) { - prev_part[start_pos] = bsize; - } else { - switch (partition) { - case PARTITION_NONE: - prev_part[start_pos] = bsize; - if (bsize == BLOCK_64X64) { - for (xx = 0; xx < 8; xx += 4) - for (yy = 0; yy < 8; yy += 4) { - if ((mi_row + xx < cm->mi_rows) && (mi_col + yy < cm->mi_cols)) - prev_part[start_pos + xx * cm->mi_stride + yy] = bsize; - } - } - break; - case PARTITION_HORZ: - prev_part[start_pos] = subsize; - if (mi_row + bs < cm->mi_rows) - prev_part[start_pos + bs * cm->mi_stride] = subsize; - break; - case PARTITION_VERT: - prev_part[start_pos] = subsize; - if (mi_col + bs < cm->mi_cols) prev_part[start_pos + bs] = subsize; - break; - default: - assert(partition == PARTITION_SPLIT); - update_partition_svc(cpi, subsize, mi_row, mi_col); - update_partition_svc(cpi, subsize, mi_row + bs, mi_col); - update_partition_svc(cpi, subsize, mi_row, mi_col + bs); - update_partition_svc(cpi, subsize, mi_row + bs, mi_col + bs); - break; - } - } -} - -static void update_prev_partition_helper(VP9_COMP *cpi, BLOCK_SIZE bsize, - int mi_row, int mi_col) { - VP9_COMMON *const cm = &cpi->common; - BLOCK_SIZE *prev_part = cpi->prev_partition; - int start_pos = mi_row * cm->mi_stride + mi_col; - const int bsl = b_width_log2_lookup[bsize]; - const int bs = (1 << bsl) >> 2; - BLOCK_SIZE subsize; - PARTITION_TYPE partition; - const MODE_INFO *mi = NULL; - - if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - - mi = cm->mi_grid_visible[start_pos]; - partition = partition_lookup[bsl][mi->sb_type]; - subsize = get_subsize(bsize, partition); - if (subsize < BLOCK_8X8) { - prev_part[start_pos] = bsize; - } else { - switch (partition) { - case PARTITION_NONE: prev_part[start_pos] = bsize; break; - case PARTITION_HORZ: - prev_part[start_pos] = subsize; - if (mi_row + bs < cm->mi_rows) - prev_part[start_pos + bs * cm->mi_stride] = subsize; - break; - case PARTITION_VERT: - prev_part[start_pos] = subsize; - if (mi_col + bs < cm->mi_cols) prev_part[start_pos + bs] = subsize; - break; - default: - assert(partition == PARTITION_SPLIT); - update_prev_partition_helper(cpi, subsize, mi_row, mi_col); - update_prev_partition_helper(cpi, subsize, mi_row + bs, mi_col); - update_prev_partition_helper(cpi, subsize, mi_row, mi_col + bs); - update_prev_partition_helper(cpi, subsize, mi_row + bs, mi_col + bs); - break; - } - } -} - -static void update_prev_partition(VP9_COMP *cpi, MACROBLOCK *x, int segment_id, - int mi_row, int mi_col, int sb_offset) { - update_prev_partition_helper(cpi, BLOCK_64X64, mi_row, mi_col); - cpi->prev_segment_id[sb_offset] = segment_id; - memcpy(&(cpi->prev_variance_low[sb_offset * 25]), x->variance_low, - sizeof(x->variance_low)); - // Reset the counter for copy partitioning - cpi->copied_frame_cnt[sb_offset] = 0; -} - -static void chroma_check(VP9_COMP *cpi, MACROBLOCK *x, int bsize, - unsigned int y_sad, int is_key_frame, - int scene_change_detected) { - int i; - MACROBLOCKD *xd = &x->e_mbd; - int shift = 2; - - if (is_key_frame) return; - - // For speed > 8, avoid the chroma check if y_sad is above threshold. - if (cpi->oxcf.speed > 8) { - if (y_sad > cpi->vbp_thresholds[1] && - (!cpi->noise_estimate.enabled || - vp9_noise_estimate_extract_level(&cpi->noise_estimate) < kMedium)) - return; - } - - if (cpi->oxcf.content == VP9E_CONTENT_SCREEN && scene_change_detected) - shift = 5; - - for (i = 1; i <= 2; ++i) { - unsigned int uv_sad = UINT_MAX; - struct macroblock_plane *p = &x->plane[i]; - struct macroblockd_plane *pd = &xd->plane[i]; - const BLOCK_SIZE bs = get_plane_block_size(bsize, pd); - - if (bs != BLOCK_INVALID) - uv_sad = cpi->fn_ptr[bs].sdf(p->src.buf, p->src.stride, pd->dst.buf, - pd->dst.stride); - - // TODO(marpan): Investigate if we should lower this threshold if - // superblock is detected as skin. - x->color_sensitivity[i - 1] = uv_sad > (y_sad >> shift); - } -} - -static uint64_t avg_source_sad(VP9_COMP *cpi, MACROBLOCK *x, int shift, - int sb_offset) { - unsigned int tmp_sse; - uint64_t tmp_sad; - unsigned int tmp_variance; - const BLOCK_SIZE bsize = BLOCK_64X64; - uint8_t *src_y = cpi->Source->y_buffer; - int src_ystride = cpi->Source->y_stride; - uint8_t *last_src_y = cpi->Last_Source->y_buffer; - int last_src_ystride = cpi->Last_Source->y_stride; - uint64_t avg_source_sad_threshold = 10000; - uint64_t avg_source_sad_threshold2 = 12000; -#if CONFIG_VP9_HIGHBITDEPTH - if (cpi->common.use_highbitdepth) return 0; -#endif - src_y += shift; - last_src_y += shift; - tmp_sad = - cpi->fn_ptr[bsize].sdf(src_y, src_ystride, last_src_y, last_src_ystride); - tmp_variance = vpx_variance64x64(src_y, src_ystride, last_src_y, - last_src_ystride, &tmp_sse); - // Note: tmp_sse - tmp_variance = ((sum * sum) >> 12) - if (tmp_sad < avg_source_sad_threshold) - x->content_state_sb = ((tmp_sse - tmp_variance) < 25) ? kLowSadLowSumdiff - : kLowSadHighSumdiff; - else - x->content_state_sb = ((tmp_sse - tmp_variance) < 25) ? kHighSadLowSumdiff - : kHighSadHighSumdiff; - - // Detect large lighting change. - if (cpi->oxcf.content != VP9E_CONTENT_SCREEN && - cpi->oxcf.rc_mode == VPX_CBR && tmp_variance < (tmp_sse >> 3) && - (tmp_sse - tmp_variance) > 10000) - x->content_state_sb = kLowVarHighSumdiff; - else if (tmp_sad > (avg_source_sad_threshold << 1)) - x->content_state_sb = kVeryHighSad; - - if (cpi->content_state_sb_fd != NULL) { - if (tmp_sad < avg_source_sad_threshold2) { - // Cap the increment to 255. - if (cpi->content_state_sb_fd[sb_offset] < 255) - cpi->content_state_sb_fd[sb_offset]++; - } else { - cpi->content_state_sb_fd[sb_offset] = 0; - } - } - if (tmp_sad == 0) x->zero_temp_sad_source = 1; - return tmp_sad; -} - -// This function chooses partitioning based on the variance between source and -// reconstructed last, where variance is computed for down-sampled inputs. -static int choose_partitioning(VP9_COMP *cpi, const TileInfo *const tile, - MACROBLOCK *x, int mi_row, int mi_col) { - VP9_COMMON *const cm = &cpi->common; - MACROBLOCKD *xd = &x->e_mbd; - int i, j, k, m; - v64x64 vt; - v16x16 *vt2 = NULL; - int force_split[21]; - int avg_32x32; - int max_var_32x32 = 0; - int min_var_32x32 = INT_MAX; - int var_32x32; - int avg_16x16[4]; - int maxvar_16x16[4]; - int minvar_16x16[4]; - int64_t threshold_4x4avg; - NOISE_LEVEL noise_level = kLow; - int content_state = 0; - uint8_t *s; - const uint8_t *d; - int sp; - int dp; - int compute_minmax_variance = 1; - unsigned int y_sad = UINT_MAX; - BLOCK_SIZE bsize = BLOCK_64X64; - // Ref frame used in partitioning. - MV_REFERENCE_FRAME ref_frame_partition = LAST_FRAME; - int pixels_wide = 64, pixels_high = 64; - int64_t thresholds[4] = { cpi->vbp_thresholds[0], cpi->vbp_thresholds[1], - cpi->vbp_thresholds[2], cpi->vbp_thresholds[3] }; - int scene_change_detected = - cpi->rc.high_source_sad || - (cpi->use_svc && cpi->svc.high_source_sad_superframe); - int force_64_split = scene_change_detected || - (cpi->oxcf.content == VP9E_CONTENT_SCREEN && - cpi->compute_source_sad_onepass && - cpi->sf.use_source_sad && !x->zero_temp_sad_source); - - // For the variance computation under SVC mode, we treat the frame as key if - // the reference (base layer frame) is key frame (i.e., is_key_frame == 1). - int is_key_frame = - (frame_is_intra_only(cm) || - (is_one_pass_svc(cpi) && - cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame)); - - if (!is_key_frame) { - if (cm->frame_refs[LAST_FRAME - 1].sf.x_scale_fp == REF_INVALID_SCALE || - cm->frame_refs[LAST_FRAME - 1].sf.y_scale_fp == REF_INVALID_SCALE) - is_key_frame = 1; - } - - // Always use 4x4 partition for key frame. - const int use_4x4_partition = frame_is_intra_only(cm); - const int low_res = (cm->width <= 352 && cm->height <= 288); - int variance4x4downsample[16]; - int segment_id; - int sb_offset = (cm->mi_stride >> 3) * (mi_row >> 3) + (mi_col >> 3); - - // For SVC: check if LAST frame is NULL or if the resolution of LAST is - // different than the current frame resolution, and if so, treat this frame - // as a key frame, for the purpose of the superblock partitioning. - // LAST == NULL can happen in some cases where enhancement spatial layers are - // enabled dyanmically in the stream and the only reference is the spatial - // reference (GOLDEN). - if (cpi->use_svc) { - const YV12_BUFFER_CONFIG *const ref = get_ref_frame_buffer(cpi, LAST_FRAME); - if (ref == NULL || ref->y_crop_height != cm->height || - ref->y_crop_width != cm->width) - is_key_frame = 1; - } - - set_offsets(cpi, tile, x, mi_row, mi_col, BLOCK_64X64); - set_segment_index(cpi, x, mi_row, mi_col, BLOCK_64X64, 0); - segment_id = xd->mi[0]->segment_id; - - if (cpi->oxcf.speed >= 8 || (cpi->use_svc && cpi->svc.non_reference_frame)) - compute_minmax_variance = 0; - - memset(x->variance_low, 0, sizeof(x->variance_low)); - - if (cpi->sf.use_source_sad && !is_key_frame) { - int sb_offset2 = ((cm->mi_cols + 7) >> 3) * (mi_row >> 3) + (mi_col >> 3); - content_state = x->content_state_sb; - x->skip_low_source_sad = (content_state == kLowSadLowSumdiff || - content_state == kLowSadHighSumdiff) - ? 1 - : 0; - x->lowvar_highsumdiff = (content_state == kLowVarHighSumdiff) ? 1 : 0; - if (cpi->content_state_sb_fd != NULL) - x->last_sb_high_content = cpi->content_state_sb_fd[sb_offset2]; - - // For SVC on top spatial layer: use/scale the partition from - // the lower spatial resolution if svc_use_lowres_part is enabled. - if (cpi->sf.svc_use_lowres_part && - cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1 && - cpi->svc.prev_partition_svc != NULL && content_state != kVeryHighSad) { - if (!scale_partitioning_svc(cpi, x, xd, BLOCK_64X64, mi_row >> 1, - mi_col >> 1, mi_row, mi_col)) { - if (cpi->sf.copy_partition_flag) { - update_prev_partition(cpi, x, segment_id, mi_row, mi_col, sb_offset); - } - return 0; - } - } - // If source_sad is low copy the partition without computing the y_sad. - if (x->skip_low_source_sad && cpi->sf.copy_partition_flag && - !force_64_split && - copy_partitioning(cpi, x, xd, mi_row, mi_col, segment_id, sb_offset)) { - x->sb_use_mv_part = 1; - if (cpi->sf.svc_use_lowres_part && - cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 2) - update_partition_svc(cpi, BLOCK_64X64, mi_row, mi_col); - return 0; - } - } - - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled && - cyclic_refresh_segment_id_boosted(segment_id)) { - int q = vp9_get_qindex(&cm->seg, segment_id, cm->base_qindex); - set_vbp_thresholds(cpi, thresholds, q, content_state); - } else { - set_vbp_thresholds(cpi, thresholds, cm->base_qindex, content_state); - } - // Decrease 32x32 split threshold for screen on base layer, for scene - // change/high motion frames. - if (cpi->oxcf.content == VP9E_CONTENT_SCREEN && - cpi->svc.spatial_layer_id == 0 && force_64_split) - thresholds[1] = 3 * thresholds[1] >> 2; - - // For non keyframes, disable 4x4 average for low resolution when speed = 8 - threshold_4x4avg = (cpi->oxcf.speed < 8) ? thresholds[1] << 1 : INT64_MAX; - - if (xd->mb_to_right_edge < 0) pixels_wide += (xd->mb_to_right_edge >> 3); - if (xd->mb_to_bottom_edge < 0) pixels_high += (xd->mb_to_bottom_edge >> 3); - - s = x->plane[0].src.buf; - sp = x->plane[0].src.stride; - - // Index for force_split: 0 for 64x64, 1-4 for 32x32 blocks, - // 5-20 for the 16x16 blocks. - force_split[0] = force_64_split; - - if (!is_key_frame) { - // In the case of spatial/temporal scalable coding, the assumption here is - // that the temporal reference frame will always be of type LAST_FRAME. - // TODO(marpan): If that assumption is broken, we need to revisit this code. - MODE_INFO *mi = xd->mi[0]; - YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME); - - const YV12_BUFFER_CONFIG *yv12_g = NULL; - unsigned int y_sad_g, y_sad_thr, y_sad_last; - bsize = BLOCK_32X32 + (mi_col + 4 < cm->mi_cols) * 2 + - (mi_row + 4 < cm->mi_rows); - - assert(yv12 != NULL); - - if (!(is_one_pass_svc(cpi) && cpi->svc.spatial_layer_id) || - cpi->svc.use_gf_temporal_ref_current_layer) { - // For now, GOLDEN will not be used for non-zero spatial layers, since - // it may not be a temporal reference. - yv12_g = get_ref_frame_buffer(cpi, GOLDEN_FRAME); - } - - // Only compute y_sad_g (sad for golden reference) for speed < 8. - if (cpi->oxcf.speed < 8 && yv12_g && yv12_g != yv12 && - (cpi->ref_frame_flags & VP9_GOLD_FLAG)) { - vp9_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col, - &cm->frame_refs[GOLDEN_FRAME - 1].sf); - y_sad_g = cpi->fn_ptr[bsize].sdf( - x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].pre[0].buf, - xd->plane[0].pre[0].stride); - } else { - y_sad_g = UINT_MAX; - } - - if (cpi->oxcf.lag_in_frames > 0 && cpi->oxcf.rc_mode == VPX_VBR && - cpi->rc.is_src_frame_alt_ref) { - yv12 = get_ref_frame_buffer(cpi, ALTREF_FRAME); - vp9_setup_pre_planes(xd, 0, yv12, mi_row, mi_col, - &cm->frame_refs[ALTREF_FRAME - 1].sf); - mi->ref_frame[0] = ALTREF_FRAME; - y_sad_g = UINT_MAX; - } else { - vp9_setup_pre_planes(xd, 0, yv12, mi_row, mi_col, - &cm->frame_refs[LAST_FRAME - 1].sf); - mi->ref_frame[0] = LAST_FRAME; - } - mi->ref_frame[1] = NO_REF_FRAME; - mi->sb_type = BLOCK_64X64; - mi->mv[0].as_int = 0; - mi->interp_filter = BILINEAR; - - if (cpi->oxcf.speed >= 8 && !low_res && - x->content_state_sb != kVeryHighSad) { - y_sad = cpi->fn_ptr[bsize].sdf( - x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].pre[0].buf, - xd->plane[0].pre[0].stride); - } else { - const MV dummy_mv = { 0, 0 }; - y_sad = vp9_int_pro_motion_estimation(cpi, x, bsize, mi_row, mi_col, - &dummy_mv); - x->sb_use_mv_part = 1; - x->sb_mvcol_part = mi->mv[0].as_mv.col; - x->sb_mvrow_part = mi->mv[0].as_mv.row; - if (cpi->oxcf.content == VP9E_CONTENT_SCREEN && - cpi->svc.spatial_layer_id == cpi->svc.first_spatial_layer_to_encode && - cpi->svc.high_num_blocks_with_motion && !x->zero_temp_sad_source && - cm->width > 640 && cm->height > 480) { - // Disable split below 16x16 block size when scroll motion (horz or - // vert) is detected. - // TODO(marpan/jianj): Improve this condition: issue is that search - // range is hard-coded/limited in vp9_int_pro_motion_estimation() so - // scroll motion may not be detected here. - if (((abs(x->sb_mvrow_part) >= 48 && abs(x->sb_mvcol_part) <= 8) || - (abs(x->sb_mvcol_part) >= 48 && abs(x->sb_mvrow_part) <= 8)) && - y_sad < 100000) { - compute_minmax_variance = 0; - thresholds[2] = INT64_MAX; - } - } - } - - y_sad_last = y_sad; - // Pick ref frame for partitioning, bias last frame when y_sad_g and y_sad - // are close if short_circuit_low_temp_var is on. - y_sad_thr = cpi->sf.short_circuit_low_temp_var ? (y_sad * 7) >> 3 : y_sad; - if (y_sad_g < y_sad_thr) { - vp9_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col, - &cm->frame_refs[GOLDEN_FRAME - 1].sf); - mi->ref_frame[0] = GOLDEN_FRAME; - mi->mv[0].as_int = 0; - y_sad = y_sad_g; - ref_frame_partition = GOLDEN_FRAME; - } else { - x->pred_mv[LAST_FRAME] = mi->mv[0].as_mv; - ref_frame_partition = LAST_FRAME; - } - - set_ref_ptrs(cm, xd, mi->ref_frame[0], mi->ref_frame[1]); - vp9_build_inter_predictors_sb(xd, mi_row, mi_col, BLOCK_64X64); - - if (cpi->use_skin_detection) - x->sb_is_skin = skin_sb_split(cpi, low_res, mi_row, mi_col, force_split); - - d = xd->plane[0].dst.buf; - dp = xd->plane[0].dst.stride; - - // If the y_sad is very small, take 64x64 as partition and exit. - // Don't check on boosted segment for now, as 64x64 is suppressed there. - if (segment_id == CR_SEGMENT_ID_BASE && y_sad < cpi->vbp_threshold_sad) { - const int block_width = num_8x8_blocks_wide_lookup[BLOCK_64X64]; - const int block_height = num_8x8_blocks_high_lookup[BLOCK_64X64]; - if (mi_col + block_width / 2 < cm->mi_cols && - mi_row + block_height / 2 < cm->mi_rows) { - set_block_size(cpi, x, xd, mi_row, mi_col, BLOCK_64X64); - x->variance_low[0] = 1; - chroma_check(cpi, x, bsize, y_sad, is_key_frame, scene_change_detected); - if (cpi->sf.svc_use_lowres_part && - cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 2) - update_partition_svc(cpi, BLOCK_64X64, mi_row, mi_col); - if (cpi->sf.copy_partition_flag) { - update_prev_partition(cpi, x, segment_id, mi_row, mi_col, sb_offset); - } - return 0; - } - } - - // If the y_sad is small enough, copy the partition of the superblock in the - // last frame to current frame only if the last frame is not a keyframe. - // Stop the copy every cpi->max_copied_frame to refresh the partition. - // TODO(jianj) : tune the threshold. - if (cpi->sf.copy_partition_flag && y_sad_last < cpi->vbp_threshold_copy && - copy_partitioning(cpi, x, xd, mi_row, mi_col, segment_id, sb_offset)) { - chroma_check(cpi, x, bsize, y_sad, is_key_frame, scene_change_detected); - if (cpi->sf.svc_use_lowres_part && - cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 2) - update_partition_svc(cpi, BLOCK_64X64, mi_row, mi_col); - return 0; - } - } else { - d = VP9_VAR_OFFS; - dp = 0; -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - switch (xd->bd) { - case 10: d = CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_10); break; - case 12: d = CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_12); break; - case 8: - default: d = CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_8); break; - } - } -#endif // CONFIG_VP9_HIGHBITDEPTH - } - - if (low_res && threshold_4x4avg < INT64_MAX) - CHECK_MEM_ERROR(&cm->error, vt2, vpx_calloc(16, sizeof(*vt2))); - // Fill in the entire tree of 8x8 (or 4x4 under some conditions) variances - // for splits. - for (i = 0; i < 4; i++) { - const int x32_idx = ((i & 1) << 5); - const int y32_idx = ((i >> 1) << 5); - const int i2 = i << 2; - force_split[i + 1] = 0; - avg_16x16[i] = 0; - maxvar_16x16[i] = 0; - minvar_16x16[i] = INT_MAX; - for (j = 0; j < 4; j++) { - const int x16_idx = x32_idx + ((j & 1) << 4); - const int y16_idx = y32_idx + ((j >> 1) << 4); - const int split_index = 5 + i2 + j; - v16x16 *vst = &vt.split[i].split[j]; - force_split[split_index] = 0; - variance4x4downsample[i2 + j] = 0; - if (!is_key_frame) { - fill_variance_8x8avg(s, sp, d, dp, x16_idx, y16_idx, vst, -#if CONFIG_VP9_HIGHBITDEPTH - xd->cur_buf->flags, -#endif - pixels_wide, pixels_high, is_key_frame); - fill_variance_tree(&vt.split[i].split[j], BLOCK_16X16); - get_variance(&vt.split[i].split[j].part_variances.none); - avg_16x16[i] += vt.split[i].split[j].part_variances.none.variance; - if (vt.split[i].split[j].part_variances.none.variance < minvar_16x16[i]) - minvar_16x16[i] = vt.split[i].split[j].part_variances.none.variance; - if (vt.split[i].split[j].part_variances.none.variance > maxvar_16x16[i]) - maxvar_16x16[i] = vt.split[i].split[j].part_variances.none.variance; - if (vt.split[i].split[j].part_variances.none.variance > thresholds[2]) { - // 16X16 variance is above threshold for split, so force split to 8x8 - // for this 16x16 block (this also forces splits for upper levels). - force_split[split_index] = 1; - force_split[i + 1] = 1; - force_split[0] = 1; - } else if (compute_minmax_variance && - vt.split[i].split[j].part_variances.none.variance > - thresholds[1] && - !cyclic_refresh_segment_id_boosted(segment_id)) { - // We have some nominal amount of 16x16 variance (based on average), - // compute the minmax over the 8x8 sub-blocks, and if above threshold, - // force split to 8x8 block for this 16x16 block. - int minmax = compute_minmax_8x8(s, sp, d, dp, x16_idx, y16_idx, -#if CONFIG_VP9_HIGHBITDEPTH - xd->cur_buf->flags, -#endif - pixels_wide, pixels_high); - int thresh_minmax = (int)cpi->vbp_threshold_minmax; - if (x->content_state_sb == kVeryHighSad) - thresh_minmax = thresh_minmax << 1; - if (minmax > thresh_minmax) { - force_split[split_index] = 1; - force_split[i + 1] = 1; - force_split[0] = 1; - } - } - } - if (is_key_frame || - (low_res && vt.split[i].split[j].part_variances.none.variance > - threshold_4x4avg)) { - force_split[split_index] = 0; - // Go down to 4x4 down-sampling for variance. - variance4x4downsample[i2 + j] = 1; - for (k = 0; k < 4; k++) { - int x8_idx = x16_idx + ((k & 1) << 3); - int y8_idx = y16_idx + ((k >> 1) << 3); - v8x8 *vst2 = is_key_frame ? &vst->split[k] : &vt2[i2 + j].split[k]; - fill_variance_4x4avg(s, sp, d, dp, x8_idx, y8_idx, vst2, -#if CONFIG_VP9_HIGHBITDEPTH - xd->cur_buf->flags, -#endif - pixels_wide, pixels_high, is_key_frame); - } - } - } - } - if (cpi->noise_estimate.enabled) - noise_level = vp9_noise_estimate_extract_level(&cpi->noise_estimate); - // Fill the rest of the variance tree by summing split partition values. - avg_32x32 = 0; - for (i = 0; i < 4; i++) { - const int i2 = i << 2; - for (j = 0; j < 4; j++) { - if (variance4x4downsample[i2 + j] == 1) { - v16x16 *vtemp = (!is_key_frame) ? &vt2[i2 + j] : &vt.split[i].split[j]; - for (m = 0; m < 4; m++) fill_variance_tree(&vtemp->split[m], BLOCK_8X8); - fill_variance_tree(vtemp, BLOCK_16X16); - // If variance of this 16x16 block is above the threshold, force block - // to split. This also forces a split on the upper levels. - get_variance(&vtemp->part_variances.none); - if (vtemp->part_variances.none.variance > thresholds[2]) { - force_split[5 + i2 + j] = 1; - force_split[i + 1] = 1; - force_split[0] = 1; - } - } - } - fill_variance_tree(&vt.split[i], BLOCK_32X32); - // If variance of this 32x32 block is above the threshold, or if its above - // (some threshold of) the average variance over the sub-16x16 blocks, then - // force this block to split. This also forces a split on the upper - // (64x64) level. - if (!force_split[i + 1]) { - get_variance(&vt.split[i].part_variances.none); - var_32x32 = vt.split[i].part_variances.none.variance; - max_var_32x32 = VPXMAX(var_32x32, max_var_32x32); - min_var_32x32 = VPXMIN(var_32x32, min_var_32x32); - if (vt.split[i].part_variances.none.variance > thresholds[1] || - (!is_key_frame && - vt.split[i].part_variances.none.variance > (thresholds[1] >> 1) && - vt.split[i].part_variances.none.variance > (avg_16x16[i] >> 1))) { - force_split[i + 1] = 1; - force_split[0] = 1; - } else if (!is_key_frame && noise_level < kLow && cm->height <= 360 && - (maxvar_16x16[i] - minvar_16x16[i]) > (thresholds[1] >> 1) && - maxvar_16x16[i] > thresholds[1]) { - force_split[i + 1] = 1; - force_split[0] = 1; - } - avg_32x32 += var_32x32; - } - } - if (!force_split[0]) { - fill_variance_tree(&vt, BLOCK_64X64); - get_variance(&vt.part_variances.none); - // If variance of this 64x64 block is above (some threshold of) the average - // variance over the sub-32x32 blocks, then force this block to split. - // Only checking this for noise level >= medium for now. - if (!is_key_frame && noise_level >= kMedium && - vt.part_variances.none.variance > (9 * avg_32x32) >> 5) - force_split[0] = 1; - // Else if the maximum 32x32 variance minus the miniumum 32x32 variance in - // a 64x64 block is greater than threshold and the maximum 32x32 variance is - // above a miniumum threshold, then force the split of a 64x64 block - // Only check this for low noise. - else if (!is_key_frame && noise_level < kMedium && - (max_var_32x32 - min_var_32x32) > 3 * (thresholds[0] >> 3) && - max_var_32x32 > thresholds[0] >> 1) - force_split[0] = 1; - } - - // Now go through the entire structure, splitting every block size until - // we get to one that's got a variance lower than our threshold. - if (mi_col + 8 > cm->mi_cols || mi_row + 8 > cm->mi_rows || - !set_vt_partitioning(cpi, x, xd, &vt, BLOCK_64X64, mi_row, mi_col, - thresholds[0], BLOCK_16X16, force_split[0])) { - for (i = 0; i < 4; ++i) { - const int x32_idx = ((i & 1) << 2); - const int y32_idx = ((i >> 1) << 2); - const int i2 = i << 2; - if (!set_vt_partitioning(cpi, x, xd, &vt.split[i], BLOCK_32X32, - (mi_row + y32_idx), (mi_col + x32_idx), - thresholds[1], BLOCK_16X16, - force_split[i + 1])) { - for (j = 0; j < 4; ++j) { - const int x16_idx = ((j & 1) << 1); - const int y16_idx = ((j >> 1) << 1); - // For inter frames: if variance4x4downsample[] == 1 for this 16x16 - // block, then the variance is based on 4x4 down-sampling, so use vt2 - // in set_vt_partitioning(), otherwise use vt. - v16x16 *vtemp = (!is_key_frame && variance4x4downsample[i2 + j] == 1) - ? &vt2[i2 + j] - : &vt.split[i].split[j]; - if (!set_vt_partitioning( - cpi, x, xd, vtemp, BLOCK_16X16, mi_row + y32_idx + y16_idx, - mi_col + x32_idx + x16_idx, thresholds[2], cpi->vbp_bsize_min, - force_split[5 + i2 + j])) { - for (k = 0; k < 4; ++k) { - const int x8_idx = (k & 1); - const int y8_idx = (k >> 1); - if (use_4x4_partition) { - if (!set_vt_partitioning(cpi, x, xd, &vtemp->split[k], - BLOCK_8X8, - mi_row + y32_idx + y16_idx + y8_idx, - mi_col + x32_idx + x16_idx + x8_idx, - thresholds[3], BLOCK_8X8, 0)) { - set_block_size( - cpi, x, xd, (mi_row + y32_idx + y16_idx + y8_idx), - (mi_col + x32_idx + x16_idx + x8_idx), BLOCK_4X4); - } - } else { - set_block_size( - cpi, x, xd, (mi_row + y32_idx + y16_idx + y8_idx), - (mi_col + x32_idx + x16_idx + x8_idx), BLOCK_8X8); - } - } - } - } - } - } - } - - if (!frame_is_intra_only(cm) && cpi->sf.copy_partition_flag) { - update_prev_partition(cpi, x, segment_id, mi_row, mi_col, sb_offset); - } - - if (!frame_is_intra_only(cm) && cpi->sf.svc_use_lowres_part && - cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 2) - update_partition_svc(cpi, BLOCK_64X64, mi_row, mi_col); - - if (cpi->sf.short_circuit_low_temp_var) { - set_low_temp_var_flag(cpi, x, xd, &vt, thresholds, ref_frame_partition, - mi_col, mi_row); - } - - chroma_check(cpi, x, bsize, y_sad, is_key_frame, scene_change_detected); - if (vt2) vpx_free(vt2); - return 0; -} - -#if !CONFIG_REALTIME_ONLY -static void update_state(VP9_COMP *cpi, ThreadData *td, PICK_MODE_CONTEXT *ctx, - int mi_row, int mi_col, BLOCK_SIZE bsize, - int output_enabled) { - int i, x_idx, y; - VP9_COMMON *const cm = &cpi->common; - RD_COUNTS *const rdc = &td->rd_counts; - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - struct macroblock_plane *const p = x->plane; - struct macroblockd_plane *const pd = xd->plane; - MODE_INFO *mi = &ctx->mic; - MODE_INFO *const xdmi = xd->mi[0]; - MODE_INFO *mi_addr = xd->mi[0]; - const struct segmentation *const seg = &cm->seg; - const int bw = num_8x8_blocks_wide_lookup[mi->sb_type]; - const int bh = num_8x8_blocks_high_lookup[mi->sb_type]; - const int x_mis = VPXMIN(bw, cm->mi_cols - mi_col); - const int y_mis = VPXMIN(bh, cm->mi_rows - mi_row); - MV_REF *const frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col; - int w, h; - - const int mis = cm->mi_stride; - const int mi_width = num_8x8_blocks_wide_lookup[bsize]; - const int mi_height = num_8x8_blocks_high_lookup[bsize]; - int max_plane; - - assert(mi->sb_type == bsize); - - *mi_addr = *mi; - *x->mbmi_ext = ctx->mbmi_ext; - - // If segmentation in use - if (seg->enabled) { - // For in frame complexity AQ copy the segment id from the segment map. - if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) { - const uint8_t *const map = - seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map; - mi_addr->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col); - } - // Else for cyclic refresh mode update the segment map, set the segment id - // and then update the quantizer. - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && - cpi->cyclic_refresh->content_mode) { - vp9_cyclic_refresh_update_segment(cpi, xd->mi[0], mi_row, mi_col, bsize, - ctx->rate, ctx->dist, x->skip, p); - } - } - - max_plane = is_inter_block(xdmi) ? MAX_MB_PLANE : 1; - for (i = 0; i < max_plane; ++i) { - p[i].coeff = ctx->coeff_pbuf[i][1]; - p[i].qcoeff = ctx->qcoeff_pbuf[i][1]; - pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1]; - p[i].eobs = ctx->eobs_pbuf[i][1]; - } - - for (i = max_plane; i < MAX_MB_PLANE; ++i) { - p[i].coeff = ctx->coeff_pbuf[i][2]; - p[i].qcoeff = ctx->qcoeff_pbuf[i][2]; - pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][2]; - p[i].eobs = ctx->eobs_pbuf[i][2]; - } - - // Restore the coding context of the MB to that that was in place - // when the mode was picked for it - for (y = 0; y < mi_height; y++) - for (x_idx = 0; x_idx < mi_width; x_idx++) - if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx && - (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) { - xd->mi[x_idx + y * mis] = mi_addr; - } - - if (cpi->oxcf.aq_mode != NO_AQ) vp9_init_plane_quantizers(cpi, x); - - if (is_inter_block(xdmi) && xdmi->sb_type < BLOCK_8X8) { - xdmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int; - xdmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int; - } - - x->skip = ctx->skip; - memcpy(x->zcoeff_blk[xdmi->tx_size], ctx->zcoeff_blk, - sizeof(ctx->zcoeff_blk[0]) * ctx->num_4x4_blk); - - if (!output_enabled) return; - -#if CONFIG_INTERNAL_STATS - if (frame_is_intra_only(cm)) { - static const int kf_mode_index[] = { - THR_DC /*DC_PRED*/, THR_V_PRED /*V_PRED*/, - THR_H_PRED /*H_PRED*/, THR_D45_PRED /*D45_PRED*/, - THR_D135_PRED /*D135_PRED*/, THR_D117_PRED /*D117_PRED*/, - THR_D153_PRED /*D153_PRED*/, THR_D207_PRED /*D207_PRED*/, - THR_D63_PRED /*D63_PRED*/, THR_TM /*TM_PRED*/, - }; - ++cpi->mode_chosen_counts[kf_mode_index[xdmi->mode]]; - } else { - // Note how often each mode chosen as best - ++cpi->mode_chosen_counts[ctx->best_mode_index]; - } -#endif - if (!frame_is_intra_only(cm)) { - if (is_inter_block(xdmi)) { - vp9_update_mv_count(td); - - if (cm->interp_filter == SWITCHABLE) { - const int ctx_interp = get_pred_context_switchable_interp(xd); - ++td->counts->switchable_interp[ctx_interp][xdmi->interp_filter]; - } - } - - rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff; - rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff; - rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff; - - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) - rdc->filter_diff[i] += ctx->best_filter_diff[i]; - } - - for (h = 0; h < y_mis; ++h) { - MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols; - for (w = 0; w < x_mis; ++w) { - MV_REF *const mv = frame_mv + w; - mv->ref_frame[0] = mi->ref_frame[0]; - mv->ref_frame[1] = mi->ref_frame[1]; - mv->mv[0].as_int = mi->mv[0].as_int; - mv->mv[1].as_int = mi->mv[1].as_int; - } - } -} -#endif // !CONFIG_REALTIME_ONLY - -void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src, - int mi_row, int mi_col) { - uint8_t *const buffers[3] = { src->y_buffer, src->u_buffer, src->v_buffer }; - const int strides[3] = { src->y_stride, src->uv_stride, src->uv_stride }; - int i; - - // Set current frame pointer. - x->e_mbd.cur_buf = src; - - for (i = 0; i < MAX_MB_PLANE; i++) - setup_pred_plane(&x->plane[i].src, buffers[i], strides[i], mi_row, mi_col, - NULL, x->e_mbd.plane[i].subsampling_x, - x->e_mbd.plane[i].subsampling_y); -} - -static void set_mode_info_seg_skip(MACROBLOCK *x, TX_MODE tx_mode, - INTERP_FILTER interp_filter, - RD_COST *rd_cost, BLOCK_SIZE bsize) { - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - INTERP_FILTER filter_ref; - - filter_ref = get_pred_context_switchable_interp(xd); - if (interp_filter == BILINEAR) - filter_ref = BILINEAR; - else if (filter_ref == SWITCHABLE_FILTERS) - filter_ref = EIGHTTAP; - - mi->sb_type = bsize; - mi->mode = ZEROMV; - mi->tx_size = - VPXMIN(max_txsize_lookup[bsize], tx_mode_to_biggest_tx_size[tx_mode]); - mi->skip = 1; - mi->uv_mode = DC_PRED; - mi->ref_frame[0] = LAST_FRAME; - mi->ref_frame[1] = NO_REF_FRAME; - mi->mv[0].as_int = 0; - mi->interp_filter = filter_ref; - - xd->mi[0]->bmi[0].as_mv[0].as_int = 0; - x->skip = 1; - - vp9_rd_cost_init(rd_cost); -} - -#if !CONFIG_REALTIME_ONLY -static void set_segment_rdmult(VP9_COMP *const cpi, MACROBLOCK *const x, - int mi_row, int mi_col, BLOCK_SIZE bsize, - AQ_MODE aq_mode) { - VP9_COMMON *const cm = &cpi->common; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - const uint8_t *const map = - cm->seg.update_map ? cpi->segmentation_map : cm->last_frame_seg_map; - - vp9_init_plane_quantizers(cpi, x); - vpx_clear_system_state(); - - if (aq_mode == NO_AQ || aq_mode == PSNR_AQ) { - if (cpi->sf.enable_tpl_model) x->rdmult = x->cb_rdmult; - } else if (aq_mode == PERCEPTUAL_AQ) { - x->rdmult = x->cb_rdmult; - } else if (aq_mode == CYCLIC_REFRESH_AQ) { - // If segment is boosted, use rdmult for that segment. - if (cyclic_refresh_segment_id_boosted( - get_segment_id(cm, map, bsize, mi_row, mi_col))) - x->rdmult = vp9_cyclic_refresh_get_rdmult(cpi->cyclic_refresh); - } else { - x->rdmult = vp9_compute_rd_mult(cpi, cm->base_qindex + cm->y_dc_delta_q); - } - - if (oxcf->tuning == VP8_TUNE_SSIM) { - set_ssim_rdmult(cpi, x, bsize, mi_row, mi_col, &x->rdmult); - } -} - -static void rd_pick_sb_modes(VP9_COMP *cpi, TileDataEnc *tile_data, - MACROBLOCK *const x, int mi_row, int mi_col, - RD_COST *rd_cost, BLOCK_SIZE bsize, - PICK_MODE_CONTEXT *ctx, int rate_in_best_rd, - int64_t dist_in_best_rd) { - VP9_COMMON *const cm = &cpi->common; - TileInfo *const tile_info = &tile_data->tile_info; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *mi; - struct macroblock_plane *const p = x->plane; - struct macroblockd_plane *const pd = xd->plane; - const AQ_MODE aq_mode = cpi->oxcf.aq_mode; - int i, orig_rdmult; - int64_t best_rd = INT64_MAX; - - vpx_clear_system_state(); -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, rd_pick_sb_modes_time); -#endif - - // Use the lower precision, but faster, 32x32 fdct for mode selection. - x->use_lp32x32fdct = 1; - - set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize); - mi = xd->mi[0]; - mi->sb_type = bsize; - - for (i = 0; i < MAX_MB_PLANE; ++i) { - p[i].coeff = ctx->coeff_pbuf[i][0]; - p[i].qcoeff = ctx->qcoeff_pbuf[i][0]; - pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][0]; - p[i].eobs = ctx->eobs_pbuf[i][0]; - } - ctx->is_coded = 0; - ctx->skippable = 0; - ctx->pred_pixel_ready = 0; - x->skip_recode = 0; - - // Set to zero to make sure we do not use the previous encoded frame stats - mi->skip = 0; - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - x->source_variance = vp9_high_get_sby_perpixel_variance( - cpi, &x->plane[0].src, bsize, xd->bd); - } else { - x->source_variance = - vp9_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize); - } -#else - x->source_variance = - vp9_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize); -#endif // CONFIG_VP9_HIGHBITDEPTH - - // Save rdmult before it might be changed, so it can be restored later. - orig_rdmult = x->rdmult; - - if ((cpi->sf.tx_domain_thresh > 0.0) || - (cpi->sf.trellis_opt_tx_rd.thresh > 0.0)) { - double logvar = vp9_log_block_var(cpi, x, bsize); - // Check block complexity as part of decision on using pixel or transform - // domain distortion in rd tests. - x->block_tx_domain = cpi->sf.allow_txfm_domain_distortion && - (logvar >= cpi->sf.tx_domain_thresh); - - // Store block complexity to decide on using quantized coefficient - // optimization inside the rd loop. - x->log_block_src_var = logvar; - } else { - x->block_tx_domain = cpi->sf.allow_txfm_domain_distortion; - x->log_block_src_var = 0.0; - } - - set_segment_index(cpi, x, mi_row, mi_col, bsize, 0); - set_segment_rdmult(cpi, x, mi_row, mi_col, bsize, aq_mode); - if (rate_in_best_rd < INT_MAX && dist_in_best_rd < INT64_MAX) { - best_rd = vp9_calculate_rd_cost(x->rdmult, x->rddiv, rate_in_best_rd, - dist_in_best_rd); - } - - // Find best coding mode & reconstruct the MB so it is available - // as a predictor for MBs that follow in the SB - if (frame_is_intra_only(cm)) { - vp9_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, best_rd); - } else { - if (bsize >= BLOCK_8X8) { -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, vp9_rd_pick_inter_mode_sb_time); -#endif - if (segfeature_active(&cm->seg, mi->segment_id, SEG_LVL_SKIP)) - vp9_rd_pick_inter_mode_sb_seg_skip(cpi, tile_data, x, rd_cost, bsize, - ctx, best_rd); - else - vp9_rd_pick_inter_mode_sb(cpi, tile_data, x, mi_row, mi_col, rd_cost, - bsize, ctx, best_rd); -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, vp9_rd_pick_inter_mode_sb_time); -#endif - } else { -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, vp9_rd_pick_inter_mode_sub8x8_time); -#endif - vp9_rd_pick_inter_mode_sub8x8(cpi, tile_data, x, mi_row, mi_col, rd_cost, - bsize, ctx, best_rd); -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, vp9_rd_pick_inter_mode_sub8x8_time); -#endif - } - } - - // Examine the resulting rate and for AQ mode 2 make a segment choice. - if ((rd_cost->rate != INT_MAX) && (aq_mode == COMPLEXITY_AQ) && - (bsize >= BLOCK_16X16) && - (cm->frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame || - (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) { - vp9_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate); - } - - // TODO(jingning) The rate-distortion optimization flow needs to be - // refactored to provide proper exit/return handle. - if (rd_cost->rate == INT_MAX || rd_cost->dist == INT64_MAX) - rd_cost->rdcost = INT64_MAX; - else - rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist); - - x->rdmult = orig_rdmult; - - ctx->rate = rd_cost->rate; - ctx->dist = rd_cost->dist; -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, rd_pick_sb_modes_time); -#endif -} -#endif // !CONFIG_REALTIME_ONLY - -static void update_stats(VP9_COMMON *cm, ThreadData *td) { - const MACROBLOCK *x = &td->mb; - const MACROBLOCKD *const xd = &x->e_mbd; - const MODE_INFO *const mi = xd->mi[0]; - const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext; - const BLOCK_SIZE bsize = mi->sb_type; - - if (!frame_is_intra_only(cm)) { - FRAME_COUNTS *const counts = td->counts; - const int inter_block = is_inter_block(mi); - const int seg_ref_active = - segfeature_active(&cm->seg, mi->segment_id, SEG_LVL_REF_FRAME); - if (!seg_ref_active) { - counts->intra_inter[get_intra_inter_context(xd)][inter_block]++; - // If the segment reference feature is enabled we have only a single - // reference frame allowed for the segment so exclude it from - // the reference frame counts used to work out probabilities. - if (inter_block) { - const MV_REFERENCE_FRAME ref0 = mi->ref_frame[0]; - if (cm->reference_mode == REFERENCE_MODE_SELECT) - counts->comp_inter[vp9_get_reference_mode_context(cm, xd)] - [has_second_ref(mi)]++; - - if (has_second_ref(mi)) { - const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref]; - const int ctx = vp9_get_pred_context_comp_ref_p(cm, xd); - const int bit = mi->ref_frame[!idx] == cm->comp_var_ref[1]; - counts->comp_ref[ctx][bit]++; - } else { - counts->single_ref[vp9_get_pred_context_single_ref_p1(xd)][0] - [ref0 != LAST_FRAME]++; - if (ref0 != LAST_FRAME) - counts->single_ref[vp9_get_pred_context_single_ref_p2(xd)][1] - [ref0 != GOLDEN_FRAME]++; - } - } - } - if (inter_block && - !segfeature_active(&cm->seg, mi->segment_id, SEG_LVL_SKIP)) { - const int mode_ctx = mbmi_ext->mode_context[mi->ref_frame[0]]; - if (bsize >= BLOCK_8X8) { - const PREDICTION_MODE mode = mi->mode; - ++counts->inter_mode[mode_ctx][INTER_OFFSET(mode)]; - } else { - const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; - const int num_4x4_h = num_4x4_blocks_high_lookup[bsize]; - int idx, idy; - for (idy = 0; idy < 2; idy += num_4x4_h) { - for (idx = 0; idx < 2; idx += num_4x4_w) { - const int j = idy * 2 + idx; - const PREDICTION_MODE b_mode = mi->bmi[j].as_mode; - ++counts->inter_mode[mode_ctx][INTER_OFFSET(b_mode)]; - } - } - } - } - } -} - -#if !CONFIG_REALTIME_ONLY -static void restore_context(MACROBLOCK *const x, int mi_row, int mi_col, - ENTROPY_CONTEXT a[16 * MAX_MB_PLANE], - ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], - PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8], - BLOCK_SIZE bsize) { - MACROBLOCKD *const xd = &x->e_mbd; - int p; - const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; - const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; - int mi_width = num_8x8_blocks_wide_lookup[bsize]; - int mi_height = num_8x8_blocks_high_lookup[bsize]; - for (p = 0; p < MAX_MB_PLANE; p++) { - memcpy(xd->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x), - a + num_4x4_blocks_wide * p, - (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >> - xd->plane[p].subsampling_x); - memcpy(xd->left_context[p] + - ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y), - l + num_4x4_blocks_high * p, - (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >> - xd->plane[p].subsampling_y); - } - memcpy(xd->above_seg_context + mi_col, sa, - sizeof(*xd->above_seg_context) * mi_width); - memcpy(xd->left_seg_context + (mi_row & MI_MASK), sl, - sizeof(xd->left_seg_context[0]) * mi_height); -} - -static void save_context(MACROBLOCK *const x, int mi_row, int mi_col, - ENTROPY_CONTEXT a[16 * MAX_MB_PLANE], - ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], - PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8], - BLOCK_SIZE bsize) { - const MACROBLOCKD *const xd = &x->e_mbd; - int p; - const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; - const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; - int mi_width = num_8x8_blocks_wide_lookup[bsize]; - int mi_height = num_8x8_blocks_high_lookup[bsize]; - - // buffer the above/left context information of the block in search. - for (p = 0; p < MAX_MB_PLANE; ++p) { - memcpy(a + num_4x4_blocks_wide * p, - xd->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x), - (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >> - xd->plane[p].subsampling_x); - memcpy(l + num_4x4_blocks_high * p, - xd->left_context[p] + - ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y), - (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >> - xd->plane[p].subsampling_y); - } - memcpy(sa, xd->above_seg_context + mi_col, - sizeof(*xd->above_seg_context) * mi_width); - memcpy(sl, xd->left_seg_context + (mi_row & MI_MASK), - sizeof(xd->left_seg_context[0]) * mi_height); -} - -static void encode_b(VP9_COMP *cpi, const TileInfo *const tile, ThreadData *td, - TOKENEXTRA **tp, int mi_row, int mi_col, - int output_enabled, BLOCK_SIZE bsize, - PICK_MODE_CONTEXT *ctx) { - MACROBLOCK *const x = &td->mb; - set_offsets(cpi, tile, x, mi_row, mi_col, bsize); - - if (cpi->sf.enable_tpl_model && - (cpi->oxcf.aq_mode == NO_AQ || cpi->oxcf.aq_mode == PERCEPTUAL_AQ)) { - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - x->rdmult = x->cb_rdmult; - if (oxcf->tuning == VP8_TUNE_SSIM) { - set_ssim_rdmult(cpi, x, bsize, mi_row, mi_col, &x->rdmult); - } - } - - update_state(cpi, td, ctx, mi_row, mi_col, bsize, output_enabled); - encode_superblock(cpi, td, tp, output_enabled, mi_row, mi_col, bsize, ctx); - - if (output_enabled) { - update_stats(&cpi->common, td); - - (*tp)->token = EOSB_TOKEN; - (*tp)++; - } -} - -static void encode_sb(VP9_COMP *cpi, ThreadData *td, const TileInfo *const tile, - TOKENEXTRA **tp, int mi_row, int mi_col, - int output_enabled, BLOCK_SIZE bsize, PC_TREE *pc_tree) { - VP9_COMMON *const cm = &cpi->common; - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - - const int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4; - int ctx; - PARTITION_TYPE partition; - BLOCK_SIZE subsize = bsize; - - if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - - if (bsize >= BLOCK_8X8) { - ctx = partition_plane_context(xd, mi_row, mi_col, bsize); - subsize = get_subsize(bsize, pc_tree->partitioning); - } else { - ctx = 0; - subsize = BLOCK_4X4; - } - - partition = partition_lookup[bsl][subsize]; - if (output_enabled && bsize != BLOCK_4X4) - td->counts->partition[ctx][partition]++; - - switch (partition) { - case PARTITION_NONE: - encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize, - &pc_tree->none); - break; - case PARTITION_VERT: - encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize, - &pc_tree->vertical[0]); - if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) { - encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, output_enabled, - subsize, &pc_tree->vertical[1]); - } - break; - case PARTITION_HORZ: - encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize, - &pc_tree->horizontal[0]); - if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) { - encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, output_enabled, - subsize, &pc_tree->horizontal[1]); - } - break; - default: - assert(partition == PARTITION_SPLIT); - if (bsize == BLOCK_8X8) { - encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize, - pc_tree->u.leaf_split[0]); - } else { - encode_sb(cpi, td, tile, tp, mi_row, mi_col, output_enabled, subsize, - pc_tree->u.split[0]); - encode_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, output_enabled, - subsize, pc_tree->u.split[1]); - encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, output_enabled, - subsize, pc_tree->u.split[2]); - encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, output_enabled, - subsize, pc_tree->u.split[3]); - } - break; - } - - if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8) - update_partition_context(xd, mi_row, mi_col, subsize, bsize); -} -#endif // !CONFIG_REALTIME_ONLY - -// Check to see if the given partition size is allowed for a specified number -// of 8x8 block rows and columns remaining in the image. -// If not then return the largest allowed partition size -static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize, int rows_left, - int cols_left, int *bh, int *bw) { - if (rows_left <= 0 || cols_left <= 0) { - return VPXMIN(bsize, BLOCK_8X8); - } else { - for (; bsize > 0; bsize -= 3) { - *bh = num_8x8_blocks_high_lookup[bsize]; - *bw = num_8x8_blocks_wide_lookup[bsize]; - if ((*bh <= rows_left) && (*bw <= cols_left)) { - break; - } - } - } - return bsize; -} - -static void set_partial_b64x64_partition(MODE_INFO *mi, int mis, int bh_in, - int bw_in, int row8x8_remaining, - int col8x8_remaining, BLOCK_SIZE bsize, - MODE_INFO **mi_8x8) { - int bh = bh_in; - int r, c; - for (r = 0; r < MI_BLOCK_SIZE; r += bh) { - int bw = bw_in; - for (c = 0; c < MI_BLOCK_SIZE; c += bw) { - const int index = r * mis + c; - mi_8x8[index] = mi + index; - mi_8x8[index]->sb_type = find_partition_size( - bsize, row8x8_remaining - r, col8x8_remaining - c, &bh, &bw); - } - } -} - -// This function attempts to set all mode info entries in a given SB64 -// to the same block partition size. -// However, at the bottom and right borders of the image the requested size -// may not be allowed in which case this code attempts to choose the largest -// allowable partition. -static void set_fixed_partitioning(VP9_COMP *cpi, const TileInfo *const tile, - MODE_INFO **mi_8x8, int mi_row, int mi_col, - BLOCK_SIZE bsize) { - VP9_COMMON *const cm = &cpi->common; - const int mis = cm->mi_stride; - const int row8x8_remaining = tile->mi_row_end - mi_row; - const int col8x8_remaining = tile->mi_col_end - mi_col; - int block_row, block_col; - MODE_INFO *mi_upper_left = cm->mi + mi_row * mis + mi_col; - int bh = num_8x8_blocks_high_lookup[bsize]; - int bw = num_8x8_blocks_wide_lookup[bsize]; - - assert((row8x8_remaining > 0) && (col8x8_remaining > 0)); - - // Apply the requested partition size to the SB64 if it is all "in image" - if ((col8x8_remaining >= MI_BLOCK_SIZE) && - (row8x8_remaining >= MI_BLOCK_SIZE)) { - for (block_row = 0; block_row < MI_BLOCK_SIZE; block_row += bh) { - for (block_col = 0; block_col < MI_BLOCK_SIZE; block_col += bw) { - int index = block_row * mis + block_col; - mi_8x8[index] = mi_upper_left + index; - mi_8x8[index]->sb_type = bsize; - } - } - } else { - // Else this is a partial SB64. - set_partial_b64x64_partition(mi_upper_left, mis, bh, bw, row8x8_remaining, - col8x8_remaining, bsize, mi_8x8); - } -} - -static const struct { - int row; - int col; -} coord_lookup[16] = { - // 32x32 index = 0 - { 0, 0 }, - { 0, 2 }, - { 2, 0 }, - { 2, 2 }, - // 32x32 index = 1 - { 0, 4 }, - { 0, 6 }, - { 2, 4 }, - { 2, 6 }, - // 32x32 index = 2 - { 4, 0 }, - { 4, 2 }, - { 6, 0 }, - { 6, 2 }, - // 32x32 index = 3 - { 4, 4 }, - { 4, 6 }, - { 6, 4 }, - { 6, 6 }, -}; - -static void set_source_var_based_partition(VP9_COMP *cpi, - const TileInfo *const tile, - MACROBLOCK *const x, - MODE_INFO **mi_8x8, int mi_row, - int mi_col) { - VP9_COMMON *const cm = &cpi->common; - const int mis = cm->mi_stride; - const int row8x8_remaining = tile->mi_row_end - mi_row; - const int col8x8_remaining = tile->mi_col_end - mi_col; - MODE_INFO *mi_upper_left = cm->mi + mi_row * mis + mi_col; - - vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col); - - assert((row8x8_remaining > 0) && (col8x8_remaining > 0)); - - // In-image SB64 - if ((col8x8_remaining >= MI_BLOCK_SIZE) && - (row8x8_remaining >= MI_BLOCK_SIZE)) { - int i, j; - int index; - Diff d32[4]; - const int offset = (mi_row >> 1) * cm->mb_cols + (mi_col >> 1); - int is_larger_better = 0; - int use32x32 = 0; - unsigned int thr = cpi->source_var_thresh; - - memset(d32, 0, sizeof(d32)); - - for (i = 0; i < 4; i++) { - Diff *d16[4]; - - for (j = 0; j < 4; j++) { - int b_mi_row = coord_lookup[i * 4 + j].row; - int b_mi_col = coord_lookup[i * 4 + j].col; - int boffset = b_mi_row / 2 * cm->mb_cols + b_mi_col / 2; - - d16[j] = cpi->source_diff_var + offset + boffset; - - index = b_mi_row * mis + b_mi_col; - mi_8x8[index] = mi_upper_left + index; - mi_8x8[index]->sb_type = BLOCK_16X16; - - // TODO(yunqingwang): If d16[j].var is very large, use 8x8 partition - // size to further improve quality. - } - - is_larger_better = (d16[0]->var < thr) && (d16[1]->var < thr) && - (d16[2]->var < thr) && (d16[3]->var < thr); - - // Use 32x32 partition - if (is_larger_better) { - use32x32 += 1; - - for (j = 0; j < 4; j++) { - d32[i].sse += d16[j]->sse; - d32[i].sum += d16[j]->sum; - } - - d32[i].var = - (unsigned int)(d32[i].sse - - (unsigned int)(((int64_t)d32[i].sum * d32[i].sum) >> - 10)); - - index = coord_lookup[i * 4].row * mis + coord_lookup[i * 4].col; - mi_8x8[index] = mi_upper_left + index; - mi_8x8[index]->sb_type = BLOCK_32X32; - } - } - - if (use32x32 == 4) { - thr <<= 1; - is_larger_better = (d32[0].var < thr) && (d32[1].var < thr) && - (d32[2].var < thr) && (d32[3].var < thr); - - // Use 64x64 partition - if (is_larger_better) { - mi_8x8[0] = mi_upper_left; - mi_8x8[0]->sb_type = BLOCK_64X64; - } - } - } else { // partial in-image SB64 - int bh = num_8x8_blocks_high_lookup[BLOCK_16X16]; - int bw = num_8x8_blocks_wide_lookup[BLOCK_16X16]; - set_partial_b64x64_partition(mi_upper_left, mis, bh, bw, row8x8_remaining, - col8x8_remaining, BLOCK_16X16, mi_8x8); - } -} - -static void update_state_rt(VP9_COMP *cpi, ThreadData *td, - PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col, - int bsize) { - VP9_COMMON *const cm = &cpi->common; - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - struct macroblock_plane *const p = x->plane; - const struct segmentation *const seg = &cm->seg; - const int bw = num_8x8_blocks_wide_lookup[mi->sb_type]; - const int bh = num_8x8_blocks_high_lookup[mi->sb_type]; - const int x_mis = VPXMIN(bw, cm->mi_cols - mi_col); - const int y_mis = VPXMIN(bh, cm->mi_rows - mi_row); - - *(xd->mi[0]) = ctx->mic; - *(x->mbmi_ext) = ctx->mbmi_ext; - - if (seg->enabled && (cpi->oxcf.aq_mode != NO_AQ || cpi->roi.enabled || - cpi->active_map.enabled)) { - // Setting segmentation map for cyclic_refresh. - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && - cpi->cyclic_refresh->content_mode) { - vp9_cyclic_refresh_update_segment(cpi, mi, mi_row, mi_col, bsize, - ctx->rate, ctx->dist, x->skip, p); - } else { - const uint8_t *const map = - seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map; - mi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col); - } - vp9_init_plane_quantizers(cpi, x); - } - - if (is_inter_block(mi)) { - vp9_update_mv_count(td); - if (cm->interp_filter == SWITCHABLE) { - const int pred_ctx = get_pred_context_switchable_interp(xd); - ++td->counts->switchable_interp[pred_ctx][mi->interp_filter]; - } - - if (mi->sb_type < BLOCK_8X8) { - mi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int; - mi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int; - } - } - - if (cm->use_prev_frame_mvs || !cm->error_resilient_mode || - (cpi->svc.use_base_mv && cpi->svc.number_spatial_layers > 1 && - cpi->svc.spatial_layer_id != cpi->svc.number_spatial_layers - 1)) { - MV_REF *const frame_mvs = - cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col; - int w, h; - - for (h = 0; h < y_mis; ++h) { - MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols; - for (w = 0; w < x_mis; ++w) { - MV_REF *const mv = frame_mv + w; - mv->ref_frame[0] = mi->ref_frame[0]; - mv->ref_frame[1] = mi->ref_frame[1]; - mv->mv[0].as_int = mi->mv[0].as_int; - mv->mv[1].as_int = mi->mv[1].as_int; - } - } - } - - x->skip = ctx->skip; - x->skip_txfm[0] = (mi->segment_id || xd->lossless) ? 0 : ctx->skip_txfm[0]; -} - -static void encode_b_rt(VP9_COMP *cpi, ThreadData *td, - const TileInfo *const tile, TOKENEXTRA **tp, int mi_row, - int mi_col, int output_enabled, BLOCK_SIZE bsize, - PICK_MODE_CONTEXT *ctx) { - MACROBLOCK *const x = &td->mb; - set_offsets(cpi, tile, x, mi_row, mi_col, bsize); - update_state_rt(cpi, td, ctx, mi_row, mi_col, bsize); - - encode_superblock(cpi, td, tp, output_enabled, mi_row, mi_col, bsize, ctx); - update_stats(&cpi->common, td); - - (*tp)->token = EOSB_TOKEN; - (*tp)++; -} - -static void encode_sb_rt(VP9_COMP *cpi, ThreadData *td, - const TileInfo *const tile, TOKENEXTRA **tp, - int mi_row, int mi_col, int output_enabled, - BLOCK_SIZE bsize, PC_TREE *pc_tree) { - VP9_COMMON *const cm = &cpi->common; - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - - const int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4; - int ctx; - PARTITION_TYPE partition; - BLOCK_SIZE subsize; - - if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - - if (bsize >= BLOCK_8X8) { - const int idx_str = xd->mi_stride * mi_row + mi_col; - MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str; - ctx = partition_plane_context(xd, mi_row, mi_col, bsize); - subsize = mi_8x8[0]->sb_type; - } else { - ctx = 0; - subsize = BLOCK_4X4; - } - - partition = partition_lookup[bsl][subsize]; - if (output_enabled && bsize != BLOCK_4X4) - td->counts->partition[ctx][partition]++; - - switch (partition) { - case PARTITION_NONE: - encode_b_rt(cpi, td, tile, tp, mi_row, mi_col, output_enabled, subsize, - &pc_tree->none); - break; - case PARTITION_VERT: - encode_b_rt(cpi, td, tile, tp, mi_row, mi_col, output_enabled, subsize, - &pc_tree->vertical[0]); - if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) { - encode_b_rt(cpi, td, tile, tp, mi_row, mi_col + hbs, output_enabled, - subsize, &pc_tree->vertical[1]); - } - break; - case PARTITION_HORZ: - encode_b_rt(cpi, td, tile, tp, mi_row, mi_col, output_enabled, subsize, - &pc_tree->horizontal[0]); - if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) { - encode_b_rt(cpi, td, tile, tp, mi_row + hbs, mi_col, output_enabled, - subsize, &pc_tree->horizontal[1]); - } - break; - default: - assert(partition == PARTITION_SPLIT); - subsize = get_subsize(bsize, PARTITION_SPLIT); - encode_sb_rt(cpi, td, tile, tp, mi_row, mi_col, output_enabled, subsize, - pc_tree->u.split[0]); - encode_sb_rt(cpi, td, tile, tp, mi_row, mi_col + hbs, output_enabled, - subsize, pc_tree->u.split[1]); - encode_sb_rt(cpi, td, tile, tp, mi_row + hbs, mi_col, output_enabled, - subsize, pc_tree->u.split[2]); - encode_sb_rt(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, - output_enabled, subsize, pc_tree->u.split[3]); - break; - } - - if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8) - update_partition_context(xd, mi_row, mi_col, subsize, bsize); -} - -#if !CONFIG_REALTIME_ONLY -static void rd_use_partition(VP9_COMP *cpi, ThreadData *td, - TileDataEnc *tile_data, MODE_INFO **mi_8x8, - TOKENEXTRA **tp, int mi_row, int mi_col, - BLOCK_SIZE bsize, int *rate, int64_t *dist, - int do_recon, PC_TREE *pc_tree) { - VP9_COMMON *const cm = &cpi->common; - TileInfo *const tile_info = &tile_data->tile_info; - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - const int mis = cm->mi_stride; - const int bsl = b_width_log2_lookup[bsize]; - const int mi_step = num_4x4_blocks_wide_lookup[bsize] / 2; - const int bss = (1 << bsl) / 4; - int i, pl; - PARTITION_TYPE partition = PARTITION_NONE; - BLOCK_SIZE subsize; - ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE]; - PARTITION_CONTEXT sl[8], sa[8]; - RD_COST last_part_rdc, none_rdc, chosen_rdc; - BLOCK_SIZE sub_subsize = BLOCK_4X4; - int splits_below = 0; - BLOCK_SIZE bs_type = mi_8x8[0]->sb_type; - int do_partition_search = 1; - PICK_MODE_CONTEXT *ctx = &pc_tree->none; - - if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - - assert(num_4x4_blocks_wide_lookup[bsize] == - num_4x4_blocks_high_lookup[bsize]); - - vp9_rd_cost_reset(&last_part_rdc); - vp9_rd_cost_reset(&none_rdc); - vp9_rd_cost_reset(&chosen_rdc); - - partition = partition_lookup[bsl][bs_type]; - subsize = get_subsize(bsize, partition); - - pc_tree->partitioning = partition; - save_context(x, mi_row, mi_col, a, l, sa, sl, bsize); - - if (bsize == BLOCK_16X16 && cpi->oxcf.aq_mode != NO_AQ) { - set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize); - x->mb_energy = vp9_block_energy(cpi, x, bsize); - } - - if (do_partition_search && - cpi->sf.partition_search_type == SEARCH_PARTITION && - cpi->sf.adjust_partitioning_from_last_frame) { - // Check if any of the sub blocks are further split. - if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) { - sub_subsize = get_subsize(subsize, PARTITION_SPLIT); - splits_below = 1; - for (i = 0; i < 4; i++) { - int jj = i >> 1, ii = i & 0x01; - MODE_INFO *this_mi = mi_8x8[jj * bss * mis + ii * bss]; - if (this_mi && this_mi->sb_type >= sub_subsize) { - splits_below = 0; - } - } - } - - // If partition is not none try none unless each of the 4 splits are split - // even further.. - if (partition != PARTITION_NONE && !splits_below && - mi_row + (mi_step >> 1) < cm->mi_rows && - mi_col + (mi_step >> 1) < cm->mi_cols) { - pc_tree->partitioning = PARTITION_NONE; - rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &none_rdc, bsize, ctx, - INT_MAX, INT64_MAX); - - pl = partition_plane_context(xd, mi_row, mi_col, bsize); - - if (none_rdc.rate < INT_MAX) { - none_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE]; - none_rdc.rdcost = - RDCOST(x->rdmult, x->rddiv, none_rdc.rate, none_rdc.dist); - } - - restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize); - mi_8x8[0]->sb_type = bs_type; - pc_tree->partitioning = partition; - } - } - - switch (partition) { - case PARTITION_NONE: - rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc, bsize, - ctx, INT_MAX, INT64_MAX); - break; - case PARTITION_HORZ: - pc_tree->horizontal[0].skip_ref_frame_mask = 0; - rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc, - subsize, &pc_tree->horizontal[0], INT_MAX, INT64_MAX); - if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 && - mi_row + (mi_step >> 1) < cm->mi_rows) { - RD_COST tmp_rdc; - PICK_MODE_CONTEXT *hctx = &pc_tree->horizontal[0]; - vp9_rd_cost_init(&tmp_rdc); - update_state(cpi, td, hctx, mi_row, mi_col, subsize, 0); - encode_superblock(cpi, td, tp, 0, mi_row, mi_col, subsize, hctx); - pc_tree->horizontal[1].skip_ref_frame_mask = 0; - rd_pick_sb_modes(cpi, tile_data, x, mi_row + (mi_step >> 1), mi_col, - &tmp_rdc, subsize, &pc_tree->horizontal[1], INT_MAX, - INT64_MAX); - if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) { - vp9_rd_cost_reset(&last_part_rdc); - break; - } - last_part_rdc.rate += tmp_rdc.rate; - last_part_rdc.dist += tmp_rdc.dist; - last_part_rdc.rdcost += tmp_rdc.rdcost; - } - break; - case PARTITION_VERT: - pc_tree->vertical[0].skip_ref_frame_mask = 0; - rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc, - subsize, &pc_tree->vertical[0], INT_MAX, INT64_MAX); - if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 && - mi_col + (mi_step >> 1) < cm->mi_cols) { - RD_COST tmp_rdc; - PICK_MODE_CONTEXT *vctx = &pc_tree->vertical[0]; - vp9_rd_cost_init(&tmp_rdc); - update_state(cpi, td, vctx, mi_row, mi_col, subsize, 0); - encode_superblock(cpi, td, tp, 0, mi_row, mi_col, subsize, vctx); - pc_tree->vertical[bsize > BLOCK_8X8].skip_ref_frame_mask = 0; - rd_pick_sb_modes( - cpi, tile_data, x, mi_row, mi_col + (mi_step >> 1), &tmp_rdc, - subsize, &pc_tree->vertical[bsize > BLOCK_8X8], INT_MAX, INT64_MAX); - if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) { - vp9_rd_cost_reset(&last_part_rdc); - break; - } - last_part_rdc.rate += tmp_rdc.rate; - last_part_rdc.dist += tmp_rdc.dist; - last_part_rdc.rdcost += tmp_rdc.rdcost; - } - break; - default: - assert(partition == PARTITION_SPLIT); - if (bsize == BLOCK_8X8) { - rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc, - subsize, pc_tree->u.leaf_split[0], INT_MAX, INT64_MAX); - break; - } - last_part_rdc.rate = 0; - last_part_rdc.dist = 0; - last_part_rdc.rdcost = 0; - for (i = 0; i < 4; i++) { - int x_idx = (i & 1) * (mi_step >> 1); - int y_idx = (i >> 1) * (mi_step >> 1); - int jj = i >> 1, ii = i & 0x01; - RD_COST tmp_rdc; - if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols)) - continue; - - vp9_rd_cost_init(&tmp_rdc); - rd_use_partition(cpi, td, tile_data, mi_8x8 + jj * bss * mis + ii * bss, - tp, mi_row + y_idx, mi_col + x_idx, subsize, - &tmp_rdc.rate, &tmp_rdc.dist, i != 3, - pc_tree->u.split[i]); - if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) { - vp9_rd_cost_reset(&last_part_rdc); - break; - } - last_part_rdc.rate += tmp_rdc.rate; - last_part_rdc.dist += tmp_rdc.dist; - } - break; - } - - pl = partition_plane_context(xd, mi_row, mi_col, bsize); - if (last_part_rdc.rate < INT_MAX) { - last_part_rdc.rate += cpi->partition_cost[pl][partition]; - last_part_rdc.rdcost = - RDCOST(x->rdmult, x->rddiv, last_part_rdc.rate, last_part_rdc.dist); - } - - if (do_partition_search && cpi->sf.adjust_partitioning_from_last_frame && - cpi->sf.partition_search_type == SEARCH_PARTITION && - partition != PARTITION_SPLIT && bsize > BLOCK_8X8 && - (mi_row + mi_step < cm->mi_rows || - mi_row + (mi_step >> 1) == cm->mi_rows) && - (mi_col + mi_step < cm->mi_cols || - mi_col + (mi_step >> 1) == cm->mi_cols)) { - BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT); - chosen_rdc.rate = 0; - chosen_rdc.dist = 0; - restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize); - pc_tree->partitioning = PARTITION_SPLIT; - - // Split partition. - for (i = 0; i < 4; i++) { - int x_idx = (i & 1) * (mi_step >> 1); - int y_idx = (i >> 1) * (mi_step >> 1); - RD_COST tmp_rdc; - - if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols)) - continue; - - save_context(x, mi_row, mi_col, a, l, sa, sl, bsize); - pc_tree->u.split[i]->partitioning = PARTITION_NONE; - rd_pick_sb_modes(cpi, tile_data, x, mi_row + y_idx, mi_col + x_idx, - &tmp_rdc, split_subsize, &pc_tree->u.split[i]->none, - INT_MAX, INT64_MAX); - - restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize); - - if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) { - vp9_rd_cost_reset(&chosen_rdc); - break; - } - - chosen_rdc.rate += tmp_rdc.rate; - chosen_rdc.dist += tmp_rdc.dist; - - if (i != 3) - encode_sb(cpi, td, tile_info, tp, mi_row + y_idx, mi_col + x_idx, 0, - split_subsize, pc_tree->u.split[i]); - - pl = partition_plane_context(xd, mi_row + y_idx, mi_col + x_idx, - split_subsize); - chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE]; - } - pl = partition_plane_context(xd, mi_row, mi_col, bsize); - if (chosen_rdc.rate < INT_MAX) { - chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT]; - chosen_rdc.rdcost = - RDCOST(x->rdmult, x->rddiv, chosen_rdc.rate, chosen_rdc.dist); - } - } - - // If last_part is better set the partitioning to that. - if (last_part_rdc.rdcost < chosen_rdc.rdcost) { - mi_8x8[0]->sb_type = bsize; - if (bsize >= BLOCK_8X8) pc_tree->partitioning = partition; - chosen_rdc = last_part_rdc; - } - // If none was better set the partitioning to that. - if (none_rdc.rdcost < chosen_rdc.rdcost) { - if (bsize >= BLOCK_8X8) pc_tree->partitioning = PARTITION_NONE; - chosen_rdc = none_rdc; - } - - restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize); - - // We must have chosen a partitioning and encoding or we'll fail later on. - // No other opportunities for success. - if (bsize == BLOCK_64X64) - assert(chosen_rdc.rate < INT_MAX && chosen_rdc.dist < INT64_MAX); - - if (do_recon) { - int output_enabled = (bsize == BLOCK_64X64); - encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, bsize, - pc_tree); - } - - *rate = chosen_rdc.rate; - *dist = chosen_rdc.dist; -} - -static const BLOCK_SIZE min_partition_size[BLOCK_SIZES] = { - BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, - BLOCK_4X4, BLOCK_8X8, BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, - BLOCK_16X16, BLOCK_16X16, BLOCK_16X16 -}; - -static const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = { - BLOCK_8X8, BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, BLOCK_32X32, - BLOCK_32X32, BLOCK_32X32, BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, - BLOCK_64X64, BLOCK_64X64, BLOCK_64X64 -}; - -// Look at all the mode_info entries for blocks that are part of this -// partition and find the min and max values for sb_type. -// At the moment this is designed to work on a 64x64 SB but could be -// adjusted to use a size parameter. -// -// The min and max are assumed to have been initialized prior to calling this -// function so repeat calls can accumulate a min and max of more than one sb64. -static void get_sb_partition_size_range(MACROBLOCKD *xd, MODE_INFO **mi_8x8, - BLOCK_SIZE *min_block_size, - BLOCK_SIZE *max_block_size, - int bs_hist[BLOCK_SIZES]) { - int sb_width_in_blocks = MI_BLOCK_SIZE; - int sb_height_in_blocks = MI_BLOCK_SIZE; - int i, j; - int index = 0; - - // Check the sb_type for each block that belongs to this region. - for (i = 0; i < sb_height_in_blocks; ++i) { - for (j = 0; j < sb_width_in_blocks; ++j) { - MODE_INFO *mi = mi_8x8[index + j]; - BLOCK_SIZE sb_type = mi ? mi->sb_type : 0; - bs_hist[sb_type]++; - *min_block_size = VPXMIN(*min_block_size, sb_type); - *max_block_size = VPXMAX(*max_block_size, sb_type); - } - index += xd->mi_stride; - } -} - -// Next square block size less or equal than current block size. -static const BLOCK_SIZE next_square_size[BLOCK_SIZES] = { - BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, BLOCK_8X8, - BLOCK_8X8, BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, BLOCK_32X32, - BLOCK_32X32, BLOCK_32X32, BLOCK_64X64 -}; - -// Look at neighboring blocks and set a min and max partition size based on -// what they chose. -static void rd_auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile, - MACROBLOCKD *const xd, int mi_row, - int mi_col, BLOCK_SIZE *min_block_size, - BLOCK_SIZE *max_block_size) { - VP9_COMMON *const cm = &cpi->common; - MODE_INFO **mi = xd->mi; - const int left_in_image = !!xd->left_mi; - const int above_in_image = !!xd->above_mi; - const int row8x8_remaining = tile->mi_row_end - mi_row; - const int col8x8_remaining = tile->mi_col_end - mi_col; - int bh, bw; - BLOCK_SIZE min_size = BLOCK_4X4; - BLOCK_SIZE max_size = BLOCK_64X64; - int bs_hist[BLOCK_SIZES] = { 0 }; - - // Trap case where we do not have a prediction. - if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) { - // Default "min to max" and "max to min" - min_size = BLOCK_64X64; - max_size = BLOCK_4X4; - - // NOTE: each call to get_sb_partition_size_range() uses the previous - // passed in values for min and max as a starting point. - // Find the min and max partition used in previous frame at this location - if (cm->frame_type != KEY_FRAME) { - MODE_INFO **prev_mi = - &cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col]; - get_sb_partition_size_range(xd, prev_mi, &min_size, &max_size, bs_hist); - } - // Find the min and max partition sizes used in the left SB64 - if (left_in_image) { - MODE_INFO **left_sb64_mi = &mi[-MI_BLOCK_SIZE]; - get_sb_partition_size_range(xd, left_sb64_mi, &min_size, &max_size, - bs_hist); - } - // Find the min and max partition sizes used in the above SB64. - if (above_in_image) { - MODE_INFO **above_sb64_mi = &mi[-xd->mi_stride * MI_BLOCK_SIZE]; - get_sb_partition_size_range(xd, above_sb64_mi, &min_size, &max_size, - bs_hist); - } - - // Adjust observed min and max for "relaxed" auto partition case. - if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) { - min_size = min_partition_size[min_size]; - max_size = max_partition_size[max_size]; - } - } - - // Check border cases where max and min from neighbors may not be legal. - max_size = find_partition_size(max_size, row8x8_remaining, col8x8_remaining, - &bh, &bw); - // Test for blocks at the edge of the active image. - // This may be the actual edge of the image or where there are formatting - // bars. - if (vp9_active_edge_sb(cpi, mi_row, mi_col)) { - min_size = BLOCK_4X4; - } else { - min_size = - VPXMIN(cpi->sf.rd_auto_partition_min_limit, VPXMIN(min_size, max_size)); - } - - // When use_square_partition_only is true, make sure at least one square - // partition is allowed by selecting the next smaller square size as - // *min_block_size. - if (cpi->sf.use_square_partition_only && - next_square_size[max_size] < min_size) { - min_size = next_square_size[max_size]; - } - - *min_block_size = min_size; - *max_block_size = max_size; -} - -// TODO(jingning) refactor functions setting partition search range -static void set_partition_range(VP9_COMMON *cm, MACROBLOCKD *xd, int mi_row, - int mi_col, BLOCK_SIZE bsize, - BLOCK_SIZE *min_bs, BLOCK_SIZE *max_bs) { - int mi_width = num_8x8_blocks_wide_lookup[bsize]; - int mi_height = num_8x8_blocks_high_lookup[bsize]; - int idx, idy; - - MODE_INFO *mi; - const int idx_str = cm->mi_stride * mi_row + mi_col; - MODE_INFO **prev_mi = &cm->prev_mi_grid_visible[idx_str]; - BLOCK_SIZE bs, min_size, max_size; - - min_size = BLOCK_64X64; - max_size = BLOCK_4X4; - - for (idy = 0; idy < mi_height; ++idy) { - for (idx = 0; idx < mi_width; ++idx) { - mi = prev_mi[idy * cm->mi_stride + idx]; - bs = mi ? mi->sb_type : bsize; - min_size = VPXMIN(min_size, bs); - max_size = VPXMAX(max_size, bs); - } - } - - if (xd->left_mi) { - for (idy = 0; idy < mi_height; ++idy) { - mi = xd->mi[idy * cm->mi_stride - 1]; - bs = mi ? mi->sb_type : bsize; - min_size = VPXMIN(min_size, bs); - max_size = VPXMAX(max_size, bs); - } - } - - if (xd->above_mi) { - for (idx = 0; idx < mi_width; ++idx) { - mi = xd->mi[idx - cm->mi_stride]; - bs = mi ? mi->sb_type : bsize; - min_size = VPXMIN(min_size, bs); - max_size = VPXMAX(max_size, bs); - } - } - - if (min_size == max_size) { - min_size = min_partition_size[min_size]; - max_size = max_partition_size[max_size]; - } - - *min_bs = min_size; - *max_bs = max_size; -} -#endif // !CONFIG_REALTIME_ONLY - -static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) { - memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv)); -} - -static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) { - memcpy(x->pred_mv, ctx->pred_mv, sizeof(x->pred_mv)); -} - -// Calculate prediction based on the given input features and neural net config. -// Assume there are no more than NN_MAX_NODES_PER_LAYER nodes in each hidden -// layer. -static void nn_predict(const float *features, const NN_CONFIG *nn_config, - float *output) { - int num_input_nodes = nn_config->num_inputs; - int buf_index = 0; - float buf[2][NN_MAX_NODES_PER_LAYER]; - const float *input_nodes = features; - - // Propagate hidden layers. - const int num_layers = nn_config->num_hidden_layers; - int layer, node, i; - assert(num_layers <= NN_MAX_HIDDEN_LAYERS); - for (layer = 0; layer < num_layers; ++layer) { - const float *weights = nn_config->weights[layer]; - const float *bias = nn_config->bias[layer]; - float *output_nodes = buf[buf_index]; - const int num_output_nodes = nn_config->num_hidden_nodes[layer]; - assert(num_output_nodes < NN_MAX_NODES_PER_LAYER); - for (node = 0; node < num_output_nodes; ++node) { - float val = 0.0f; - for (i = 0; i < num_input_nodes; ++i) val += weights[i] * input_nodes[i]; - val += bias[node]; - // ReLU as activation function. - val = VPXMAX(val, 0.0f); - output_nodes[node] = val; - weights += num_input_nodes; - } - num_input_nodes = num_output_nodes; - input_nodes = output_nodes; - buf_index = 1 - buf_index; - } - - // Final output layer. - { - const float *weights = nn_config->weights[num_layers]; - for (node = 0; node < nn_config->num_outputs; ++node) { - const float *bias = nn_config->bias[num_layers]; - float val = 0.0f; - for (i = 0; i < num_input_nodes; ++i) val += weights[i] * input_nodes[i]; - output[node] = val + bias[node]; - weights += num_input_nodes; - } - } -} - -#if !CONFIG_REALTIME_ONLY -#define FEATURES 7 -// Machine-learning based partition search early termination. -// Return 1 to skip split and rect partitions. -static int ml_pruning_partition(VP9_COMMON *const cm, MACROBLOCKD *const xd, - PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col, - BLOCK_SIZE bsize) { - const int mag_mv = - abs(ctx->mic.mv[0].as_mv.col) + abs(ctx->mic.mv[0].as_mv.row); - const int left_in_image = !!xd->left_mi; - const int above_in_image = !!xd->above_mi; - MODE_INFO **prev_mi = - &cm->prev_mi_grid_visible[mi_col + cm->mi_stride * mi_row]; - int above_par = 0; // above_partitioning - int left_par = 0; // left_partitioning - int last_par = 0; // last_partitioning - int offset = 0; - int i; - BLOCK_SIZE context_size; - const NN_CONFIG *nn_config = NULL; - const float *mean, *sd, *linear_weights; - float nn_score, linear_score; - float features[FEATURES]; - - assert(b_width_log2_lookup[bsize] == b_height_log2_lookup[bsize]); - vpx_clear_system_state(); - - switch (bsize) { - case BLOCK_64X64: - offset = 0; - nn_config = &vp9_partition_nnconfig_64x64; - break; - case BLOCK_32X32: - offset = 8; - nn_config = &vp9_partition_nnconfig_32x32; - break; - case BLOCK_16X16: - offset = 16; - nn_config = &vp9_partition_nnconfig_16x16; - break; - default: assert(0 && "Unexpected block size."); return 0; - } - - if (above_in_image) { - context_size = xd->above_mi->sb_type; - if (context_size < bsize) - above_par = 2; - else if (context_size == bsize) - above_par = 1; - } - - if (left_in_image) { - context_size = xd->left_mi->sb_type; - if (context_size < bsize) - left_par = 2; - else if (context_size == bsize) - left_par = 1; - } - - if (prev_mi[0]) { - context_size = prev_mi[0]->sb_type; - if (context_size < bsize) - last_par = 2; - else if (context_size == bsize) - last_par = 1; - } - - mean = &vp9_partition_feature_mean[offset]; - sd = &vp9_partition_feature_std[offset]; - features[0] = ((float)ctx->rate - mean[0]) / sd[0]; - features[1] = ((float)ctx->dist - mean[1]) / sd[1]; - features[2] = ((float)mag_mv / 2 - mean[2]) * sd[2]; - features[3] = ((float)(left_par + above_par) / 2 - mean[3]) * sd[3]; - features[4] = ((float)ctx->sum_y_eobs - mean[4]) / sd[4]; - features[5] = ((float)cm->base_qindex - mean[5]) * sd[5]; - features[6] = ((float)last_par - mean[6]) * sd[6]; - - // Predict using linear model. - linear_weights = &vp9_partition_linear_weights[offset]; - linear_score = linear_weights[FEATURES]; - for (i = 0; i < FEATURES; ++i) - linear_score += linear_weights[i] * features[i]; - if (linear_score > 0.1f) return 0; - - // Predict using neural net model. - nn_predict(features, nn_config, &nn_score); - - if (linear_score < -0.0f && nn_score < 0.1f) return 1; - if (nn_score < -0.0f && linear_score < 0.1f) return 1; - return 0; -} -#undef FEATURES - -#define FEATURES 4 -// ML-based partition search breakout. -static int ml_predict_breakout(VP9_COMP *const cpi, BLOCK_SIZE bsize, - const MACROBLOCK *const x, - const RD_COST *const rd_cost) { - DECLARE_ALIGNED(16, static const uint8_t, vp9_64_zeros[64]) = { 0 }; - const VP9_COMMON *const cm = &cpi->common; - float features[FEATURES]; - const float *linear_weights = NULL; // Linear model weights. - float linear_score = 0.0f; - const int qindex = cm->base_qindex; - const int q_ctx = qindex >= 200 ? 0 : (qindex >= 150 ? 1 : 2); - const int is_720p_or_larger = VPXMIN(cm->width, cm->height) >= 720; - const int resolution_ctx = is_720p_or_larger ? 1 : 0; - - switch (bsize) { - case BLOCK_64X64: - linear_weights = vp9_partition_breakout_weights_64[resolution_ctx][q_ctx]; - break; - case BLOCK_32X32: - linear_weights = vp9_partition_breakout_weights_32[resolution_ctx][q_ctx]; - break; - case BLOCK_16X16: - linear_weights = vp9_partition_breakout_weights_16[resolution_ctx][q_ctx]; - break; - case BLOCK_8X8: - linear_weights = vp9_partition_breakout_weights_8[resolution_ctx][q_ctx]; - break; - default: assert(0 && "Unexpected block size."); return 0; - } - if (!linear_weights) return 0; - - { // Generate feature values. -#if CONFIG_VP9_HIGHBITDEPTH - const int ac_q = - vp9_ac_quant(cm->base_qindex, 0, cm->bit_depth) >> (x->e_mbd.bd - 8); -#else - const int ac_q = vp9_ac_quant(qindex, 0, cm->bit_depth); -#endif // CONFIG_VP9_HIGHBITDEPTH - const int num_pels_log2 = num_pels_log2_lookup[bsize]; - int feature_index = 0; - unsigned int var, sse; - float rate_f, dist_f; - -#if CONFIG_VP9_HIGHBITDEPTH - if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - var = - vp9_high_get_sby_variance(cpi, &x->plane[0].src, bsize, x->e_mbd.bd); - } else { - var = cpi->fn_ptr[bsize].vf(x->plane[0].src.buf, x->plane[0].src.stride, - vp9_64_zeros, 0, &sse); - } -#else - var = cpi->fn_ptr[bsize].vf(x->plane[0].src.buf, x->plane[0].src.stride, - vp9_64_zeros, 0, &sse); -#endif - var = var >> num_pels_log2; - - vpx_clear_system_state(); - - rate_f = (float)VPXMIN(rd_cost->rate, INT_MAX); - dist_f = (float)(VPXMIN(rd_cost->dist, INT_MAX) >> num_pels_log2); - rate_f = - ((float)x->rdmult / 128.0f / 512.0f / (float)(1 << num_pels_log2)) * - rate_f; - - features[feature_index++] = rate_f; - features[feature_index++] = dist_f; - features[feature_index++] = (float)var; - features[feature_index++] = (float)ac_q; - assert(feature_index == FEATURES); - } - - { // Calculate the output score. - int i; - linear_score = linear_weights[FEATURES]; - for (i = 0; i < FEATURES; ++i) - linear_score += linear_weights[i] * features[i]; - } - - return linear_score >= cpi->sf.rd_ml_partition.search_breakout_thresh[q_ctx]; -} -#undef FEATURES - -#define FEATURES 8 -#define LABELS 4 -static void ml_prune_rect_partition(VP9_COMP *const cpi, MACROBLOCK *const x, - BLOCK_SIZE bsize, - const PC_TREE *const pc_tree, - int *allow_horz, int *allow_vert, - int64_t ref_rd) { - const NN_CONFIG *nn_config = NULL; - float score[LABELS] = { - 0.0f, - }; - int thresh = -1; - int i; - (void)x; - - if (ref_rd <= 0 || ref_rd > 1000000000) return; - - switch (bsize) { - case BLOCK_8X8: break; - case BLOCK_16X16: - nn_config = &vp9_rect_part_nnconfig_16; - thresh = cpi->sf.rd_ml_partition.prune_rect_thresh[1]; - break; - case BLOCK_32X32: - nn_config = &vp9_rect_part_nnconfig_32; - thresh = cpi->sf.rd_ml_partition.prune_rect_thresh[2]; - break; - case BLOCK_64X64: - nn_config = &vp9_rect_part_nnconfig_64; - thresh = cpi->sf.rd_ml_partition.prune_rect_thresh[3]; - break; - default: assert(0 && "Unexpected block size."); return; - } - if (!nn_config || thresh < 0) return; - - // Feature extraction and model score calculation. - { - const VP9_COMMON *const cm = &cpi->common; -#if CONFIG_VP9_HIGHBITDEPTH - const int dc_q = - vp9_dc_quant(cm->base_qindex, 0, cm->bit_depth) >> (x->e_mbd.bd - 8); -#else - const int dc_q = vp9_dc_quant(cm->base_qindex, 0, cm->bit_depth); -#endif // CONFIG_VP9_HIGHBITDEPTH - const int bs = 4 * num_4x4_blocks_wide_lookup[bsize]; - int feature_index = 0; - float features[FEATURES]; - - features[feature_index++] = logf((float)dc_q + 1.0f); - features[feature_index++] = - (float)(pc_tree->partitioning == PARTITION_NONE); - features[feature_index++] = logf((float)ref_rd / bs / bs + 1.0f); - - { - const float norm_factor = 1.0f / ((float)ref_rd + 1.0f); - const int64_t none_rdcost = pc_tree->none.rdcost; - float rd_ratio = 2.0f; - if (none_rdcost > 0 && none_rdcost < 1000000000) - rd_ratio = (float)none_rdcost * norm_factor; - features[feature_index++] = VPXMIN(rd_ratio, 2.0f); - - for (i = 0; i < 4; ++i) { - const int64_t this_rd = pc_tree->u.split[i]->none.rdcost; - const int rd_valid = this_rd > 0 && this_rd < 1000000000; - // Ratio between sub-block RD and whole block RD. - features[feature_index++] = - rd_valid ? (float)this_rd * norm_factor : 1.0f; - } - } - - assert(feature_index == FEATURES); - nn_predict(features, nn_config, score); - } - - // Make decisions based on the model score. - { - int max_score = -1000; - int horz = 0, vert = 0; - int int_score[LABELS]; - for (i = 0; i < LABELS; ++i) { - int_score[i] = (int)(100 * score[i]); - max_score = VPXMAX(int_score[i], max_score); - } - thresh = max_score - thresh; - for (i = 0; i < LABELS; ++i) { - if (int_score[i] >= thresh) { - if ((i >> 0) & 1) horz = 1; - if ((i >> 1) & 1) vert = 1; - } - } - *allow_horz = *allow_horz && horz; - *allow_vert = *allow_vert && vert; - } -} -#undef FEATURES -#undef LABELS - -// Perform fast and coarse motion search for the given block. This is a -// pre-processing step for the ML based partition search speedup. -static void simple_motion_search(const VP9_COMP *const cpi, MACROBLOCK *const x, - BLOCK_SIZE bsize, int mi_row, int mi_col, - MV ref_mv, MV_REFERENCE_FRAME ref, - uint8_t *const pred_buf) { - const VP9_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - YV12_BUFFER_CONFIG *yv12; - YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi, ref); - const int step_param = 1; - const MvLimits tmp_mv_limits = x->mv_limits; - const SEARCH_METHODS search_method = NSTEP; - const int sadpb = x->sadperbit16; - MV ref_mv_full = { ref_mv.row >> 3, ref_mv.col >> 3 }; - MV best_mv = { 0, 0 }; - int cost_list[5]; - struct buf_2d backup_pre[MAX_MB_PLANE] = { { 0, 0 } }; - - if (scaled_ref_frame) { - yv12 = scaled_ref_frame; - // As reported in b/311294795, the reference buffer pointer needs to be - // saved and restored after the search. Otherwise, it causes problems while - // the reference frame scaling happens. - for (int i = 0; i < MAX_MB_PLANE; i++) backup_pre[i] = xd->plane[i].pre[0]; - } else { - yv12 = get_ref_frame_buffer(cpi, ref); - } - - assert(yv12 != NULL); - if (!yv12) return; - vp9_setup_pre_planes(xd, 0, yv12, mi_row, mi_col, NULL); - mi->ref_frame[0] = ref; - mi->ref_frame[1] = NO_REF_FRAME; - mi->sb_type = bsize; - vp9_set_mv_search_range(&x->mv_limits, &ref_mv); - vp9_full_pixel_search(cpi, x, bsize, &ref_mv_full, step_param, search_method, - sadpb, cond_cost_list(cpi, cost_list), &ref_mv, - &best_mv, 0, 0); - best_mv.row *= 8; - best_mv.col *= 8; - x->mv_limits = tmp_mv_limits; - mi->mv[0].as_mv = best_mv; - - // Restore reference buffer pointer. - if (scaled_ref_frame) { - for (int i = 0; i < MAX_MB_PLANE; i++) xd->plane[i].pre[0] = backup_pre[i]; - } - - set_ref_ptrs(cm, xd, mi->ref_frame[0], mi->ref_frame[1]); - xd->plane[0].dst.buf = pred_buf; - xd->plane[0].dst.stride = 64; - vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize); -} - -// Use a neural net model to prune partition-none and partition-split search. -// Features used: QP; spatial block size contexts; variance of prediction -// residue after simple_motion_search. -#define FEATURES 12 -static void ml_predict_var_rd_partitioning(const VP9_COMP *const cpi, - MACROBLOCK *const x, - PC_TREE *const pc_tree, - BLOCK_SIZE bsize, int mi_row, - int mi_col, int *none, int *split) { - const VP9_COMMON *const cm = &cpi->common; - const NN_CONFIG *nn_config = NULL; - const MACROBLOCKD *const xd = &x->e_mbd; -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint8_t, pred_buffer[64 * 64 * 2]); - uint8_t *const pred_buf = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) - ? (CONVERT_TO_BYTEPTR(pred_buffer)) - : pred_buffer; -#else - DECLARE_ALIGNED(16, uint8_t, pred_buffer[64 * 64]); - uint8_t *const pred_buf = pred_buffer; -#endif // CONFIG_VP9_HIGHBITDEPTH - const int speed = cpi->oxcf.speed; - float thresh = 0.0f; - - switch (bsize) { - case BLOCK_64X64: - nn_config = &vp9_part_split_nnconfig_64; - thresh = speed > 0 ? 2.8f : 3.0f; - break; - case BLOCK_32X32: - nn_config = &vp9_part_split_nnconfig_32; - thresh = speed > 0 ? 3.5f : 3.0f; - break; - case BLOCK_16X16: - nn_config = &vp9_part_split_nnconfig_16; - thresh = speed > 0 ? 3.8f : 4.0f; - break; - case BLOCK_8X8: - nn_config = &vp9_part_split_nnconfig_8; - if (cm->width >= 720 && cm->height >= 720) - thresh = speed > 0 ? 2.5f : 2.0f; - else - thresh = speed > 0 ? 3.8f : 2.0f; - break; - default: assert(0 && "Unexpected block size."); return; - } - - if (!nn_config) return; - - // Do a simple single motion search to find a prediction for current block. - // The variance of the residue will be used as input features. - { - MV ref_mv; - const MV_REFERENCE_FRAME ref = - cpi->rc.is_src_frame_alt_ref ? ALTREF_FRAME : LAST_FRAME; - // If bsize is 64x64, use zero MV as reference; otherwise, use MV result - // of previous(larger) block as reference. - if (bsize == BLOCK_64X64) - ref_mv.row = ref_mv.col = 0; - else - ref_mv = pc_tree->mv; - vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col); - simple_motion_search(cpi, x, bsize, mi_row, mi_col, ref_mv, ref, pred_buf); - pc_tree->mv = x->e_mbd.mi[0]->mv[0].as_mv; - } - - vpx_clear_system_state(); - - { - float features[FEATURES] = { 0.0f }; -#if CONFIG_VP9_HIGHBITDEPTH - const int dc_q = - vp9_dc_quant(cm->base_qindex, 0, cm->bit_depth) >> (xd->bd - 8); -#else - const int dc_q = vp9_dc_quant(cm->base_qindex, 0, cm->bit_depth); -#endif // CONFIG_VP9_HIGHBITDEPTH - int feature_idx = 0; - float score; - - // Generate model input features. - features[feature_idx++] = logf((float)dc_q + 1.0f); - - // Get the variance of the residue as input features. - { - const int bs = 4 * num_4x4_blocks_wide_lookup[bsize]; - const BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_SPLIT); - const uint8_t *pred = pred_buf; - const uint8_t *src = x->plane[0].src.buf; - const int src_stride = x->plane[0].src.stride; - const int pred_stride = 64; - unsigned int sse; - // Variance of whole block. - const unsigned int var = - cpi->fn_ptr[bsize].vf(src, src_stride, pred, pred_stride, &sse); - const float factor = (var == 0) ? 1.0f : (1.0f / (float)var); - const int has_above = !!xd->above_mi; - const int has_left = !!xd->left_mi; - const BLOCK_SIZE above_bsize = has_above ? xd->above_mi->sb_type : bsize; - const BLOCK_SIZE left_bsize = has_left ? xd->left_mi->sb_type : bsize; - int i; - - features[feature_idx++] = (float)has_above; - features[feature_idx++] = (float)b_width_log2_lookup[above_bsize]; - features[feature_idx++] = (float)b_height_log2_lookup[above_bsize]; - features[feature_idx++] = (float)has_left; - features[feature_idx++] = (float)b_width_log2_lookup[left_bsize]; - features[feature_idx++] = (float)b_height_log2_lookup[left_bsize]; - features[feature_idx++] = logf((float)var + 1.0f); - for (i = 0; i < 4; ++i) { - const int x_idx = (i & 1) * bs / 2; - const int y_idx = (i >> 1) * bs / 2; - const int src_offset = y_idx * src_stride + x_idx; - const int pred_offset = y_idx * pred_stride + x_idx; - // Variance of quarter block. - const unsigned int sub_var = - cpi->fn_ptr[subsize].vf(src + src_offset, src_stride, - pred + pred_offset, pred_stride, &sse); - const float var_ratio = (var == 0) ? 1.0f : factor * (float)sub_var; - features[feature_idx++] = var_ratio; - } - } - assert(feature_idx == FEATURES); - - // Feed the features into the model to get the confidence score. - nn_predict(features, nn_config, &score); - - // Higher score means that the model has higher confidence that the split - // partition is better than the non-split partition. So if the score is - // high enough, we skip the none-split partition search; if the score is - // low enough, we skip the split partition search. - if (score > thresh) *none = 0; - if (score < -thresh) *split = 0; - } -} -#undef FEATURES -#endif // !CONFIG_REALTIME_ONLY - -static double log_wiener_var(int64_t wiener_variance) { - return log(1.0 + wiener_variance) / log(2.0); -} - -static void build_kmeans_segmentation(VP9_COMP *cpi) { - VP9_COMMON *cm = &cpi->common; - BLOCK_SIZE bsize = BLOCK_64X64; - KMEANS_DATA *kmeans_data; - - vp9_disable_segmentation(&cm->seg); - if (cm->show_frame) { - int mi_row, mi_col; - cpi->kmeans_data_size = 0; - cpi->kmeans_ctr_num = 8; - - for (mi_row = 0; mi_row < cm->mi_rows; mi_row += MI_BLOCK_SIZE) { - for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MI_BLOCK_SIZE) { - int mb_row_start = mi_row >> 1; - int mb_col_start = mi_col >> 1; - int mb_row_end = VPXMIN( - (mi_row + num_8x8_blocks_high_lookup[bsize]) >> 1, cm->mb_rows); - int mb_col_end = VPXMIN( - (mi_col + num_8x8_blocks_wide_lookup[bsize]) >> 1, cm->mb_cols); - int row, col; - int64_t wiener_variance = 0; - - for (row = mb_row_start; row < mb_row_end; ++row) - for (col = mb_col_start; col < mb_col_end; ++col) - wiener_variance += cpi->mb_wiener_variance[row * cm->mb_cols + col]; - - wiener_variance /= - (mb_row_end - mb_row_start) * (mb_col_end - mb_col_start); - -#if CONFIG_MULTITHREAD - pthread_mutex_lock(&cpi->kmeans_mutex); -#endif // CONFIG_MULTITHREAD - - kmeans_data = &cpi->kmeans_data_arr[cpi->kmeans_data_size++]; - kmeans_data->value = log_wiener_var(wiener_variance); - kmeans_data->pos = mi_row * cpi->kmeans_data_stride + mi_col; -#if CONFIG_MULTITHREAD - pthread_mutex_unlock(&cpi->kmeans_mutex); -#endif // CONFIG_MULTITHREAD - } - } - - vp9_kmeans(cpi->kmeans_ctr_ls, cpi->kmeans_boundary_ls, - cpi->kmeans_count_ls, cpi->kmeans_ctr_num, cpi->kmeans_data_arr, - cpi->kmeans_data_size); - - vp9_perceptual_aq_mode_setup(cpi, &cm->seg); - } -} - -#if !CONFIG_REALTIME_ONLY -static int wiener_var_segment(VP9_COMP *cpi, BLOCK_SIZE bsize, int mi_row, - int mi_col) { - VP9_COMMON *cm = &cpi->common; - int mb_row_start = mi_row >> 1; - int mb_col_start = mi_col >> 1; - int mb_row_end = - VPXMIN((mi_row + num_8x8_blocks_high_lookup[bsize]) >> 1, cm->mb_rows); - int mb_col_end = - VPXMIN((mi_col + num_8x8_blocks_wide_lookup[bsize]) >> 1, cm->mb_cols); - int row, col, idx; - int64_t wiener_variance = 0; - int segment_id; - int8_t seg_hist[MAX_SEGMENTS] = { 0 }; - int8_t max_count = 0, max_index = -1; - - vpx_clear_system_state(); - - assert(cpi->norm_wiener_variance > 0); - - for (row = mb_row_start; row < mb_row_end; ++row) { - for (col = mb_col_start; col < mb_col_end; ++col) { - wiener_variance = cpi->mb_wiener_variance[row * cm->mb_cols + col]; - segment_id = - vp9_get_group_idx(log_wiener_var(wiener_variance), - cpi->kmeans_boundary_ls, cpi->kmeans_ctr_num); - ++seg_hist[segment_id]; - } - } - - for (idx = 0; idx < cpi->kmeans_ctr_num; ++idx) { - if (seg_hist[idx] > max_count) { - max_count = seg_hist[idx]; - max_index = idx; - } - } - - assert(max_index >= 0); - segment_id = max_index; - - return segment_id; -} - -static int get_rdmult_delta(VP9_COMP *cpi, BLOCK_SIZE bsize, int mi_row, - int mi_col, int orig_rdmult) { - const int gf_group_index = cpi->twopass.gf_group.index; - int64_t intra_cost = 0; - int64_t mc_dep_cost = 0; - int mi_wide = num_8x8_blocks_wide_lookup[bsize]; - int mi_high = num_8x8_blocks_high_lookup[bsize]; - int row, col; - - int dr = 0; - double r0, rk, beta; - - TplDepFrame *tpl_frame; - TplDepStats *tpl_stats; - int tpl_stride; - - if (gf_group_index >= MAX_ARF_GOP_SIZE) return orig_rdmult; - tpl_frame = &cpi->tpl_stats[gf_group_index]; - - if (tpl_frame->is_valid == 0) return orig_rdmult; - tpl_stats = tpl_frame->tpl_stats_ptr; - tpl_stride = tpl_frame->stride; - - if (cpi->twopass.gf_group.layer_depth[gf_group_index] > 1) return orig_rdmult; - - for (row = mi_row; row < mi_row + mi_high; ++row) { - for (col = mi_col; col < mi_col + mi_wide; ++col) { - TplDepStats *this_stats = &tpl_stats[row * tpl_stride + col]; - - if (row >= cpi->common.mi_rows || col >= cpi->common.mi_cols) continue; - - intra_cost += this_stats->intra_cost; - mc_dep_cost += this_stats->mc_dep_cost; - } - } - - vpx_clear_system_state(); - - r0 = cpi->rd.r0; - rk = (double)intra_cost / mc_dep_cost; - beta = r0 / rk; - dr = vp9_get_adaptive_rdmult(cpi, beta); - - dr = VPXMIN(dr, orig_rdmult * 3 / 2); - dr = VPXMAX(dr, orig_rdmult * 1 / 2); - - dr = VPXMAX(1, dr); - - return dr; -} -#endif // !CONFIG_REALTIME_ONLY - -#if CONFIG_RATE_CTRL -static void assign_partition_info( - const int row_start_4x4, const int col_start_4x4, const int block_width_4x4, - const int block_height_4x4, const int num_unit_rows, - const int num_unit_cols, PARTITION_INFO *partition_info) { - int i, j; - for (i = 0; i < block_height_4x4; ++i) { - for (j = 0; j < block_width_4x4; ++j) { - const int row_4x4 = row_start_4x4 + i; - const int col_4x4 = col_start_4x4 + j; - const int unit_index = row_4x4 * num_unit_cols + col_4x4; - if (row_4x4 >= num_unit_rows || col_4x4 >= num_unit_cols) continue; - partition_info[unit_index].row = row_4x4 << 2; - partition_info[unit_index].column = col_4x4 << 2; - partition_info[unit_index].row_start = row_start_4x4 << 2; - partition_info[unit_index].column_start = col_start_4x4 << 2; - partition_info[unit_index].width = block_width_4x4 << 2; - partition_info[unit_index].height = block_height_4x4 << 2; - } - } -} - -static void assign_motion_vector_info(const int block_width_4x4, - const int block_height_4x4, - const int row_start_4x4, - const int col_start_4x4, - const int num_unit_rows, - const int num_unit_cols, MV *source_mv[2], - MV_REFERENCE_FRAME source_ref_frame[2], - MOTION_VECTOR_INFO *motion_vector_info) { - int i, j; - for (i = 0; i < block_height_4x4; ++i) { - for (j = 0; j < block_width_4x4; ++j) { - const int row_4x4 = row_start_4x4 + i; - const int col_4x4 = col_start_4x4 + j; - const int unit_index = row_4x4 * num_unit_cols + col_4x4; - if (row_4x4 >= num_unit_rows || col_4x4 >= num_unit_cols) continue; - if (source_ref_frame[1] == NO_REF_FRAME) { - assert(source_mv[1]->row == 0 && source_mv[1]->col == 0); - } - motion_vector_info[unit_index].ref_frame[0] = source_ref_frame[0]; - motion_vector_info[unit_index].ref_frame[1] = source_ref_frame[1]; - motion_vector_info[unit_index].mv[0].as_mv.row = source_mv[0]->row; - motion_vector_info[unit_index].mv[0].as_mv.col = source_mv[0]->col; - motion_vector_info[unit_index].mv[1].as_mv.row = source_mv[1]->row; - motion_vector_info[unit_index].mv[1].as_mv.col = source_mv[1]->col; - } - } -} - -static void store_superblock_info( - const PC_TREE *const pc_tree, MODE_INFO **mi_grid_visible, - const int mi_stride, const int square_size_4x4, const int num_unit_rows, - const int num_unit_cols, const int row_start_4x4, const int col_start_4x4, - PARTITION_INFO *partition_info, MOTION_VECTOR_INFO *motion_vector_info) { - const int subblock_square_size_4x4 = square_size_4x4 >> 1; - if (row_start_4x4 >= num_unit_rows || col_start_4x4 >= num_unit_cols) return; - assert(pc_tree->partitioning != PARTITION_INVALID); - // End node, no split. - if (pc_tree->partitioning == PARTITION_NONE || - pc_tree->partitioning == PARTITION_HORZ || - pc_tree->partitioning == PARTITION_VERT || square_size_4x4 == 1) { - const int mi_row = row_start_4x4 >> 1; - const int mi_col = col_start_4x4 >> 1; - const int mi_idx = mi_stride * mi_row + mi_col; - MODE_INFO **mi = mi_grid_visible + mi_idx; - MV *source_mv[2]; - MV_REFERENCE_FRAME source_ref_frame[2]; - - // partition info - const int block_width_4x4 = (pc_tree->partitioning == PARTITION_VERT) - ? square_size_4x4 >> 1 - : square_size_4x4; - const int block_height_4x4 = (pc_tree->partitioning == PARTITION_HORZ) - ? square_size_4x4 >> 1 - : square_size_4x4; - assign_partition_info(row_start_4x4, col_start_4x4, block_width_4x4, - block_height_4x4, num_unit_rows, num_unit_cols, - partition_info); - if (pc_tree->partitioning == PARTITION_VERT) { - assign_partition_info(row_start_4x4, col_start_4x4 + block_width_4x4, - block_width_4x4, block_height_4x4, num_unit_rows, - num_unit_cols, partition_info); - } else if (pc_tree->partitioning == PARTITION_HORZ) { - assign_partition_info(row_start_4x4 + block_height_4x4, col_start_4x4, - block_width_4x4, block_height_4x4, num_unit_rows, - num_unit_cols, partition_info); - } - - // motion vector info - if (pc_tree->partitioning == PARTITION_HORZ) { - int is_valid_second_rectangle = 0; - assert(square_size_4x4 > 1); - // First rectangle. - source_ref_frame[0] = mi[0]->ref_frame[0]; - source_ref_frame[1] = mi[0]->ref_frame[1]; - source_mv[0] = &mi[0]->mv[0].as_mv; - source_mv[1] = &mi[0]->mv[1].as_mv; - assign_motion_vector_info(block_width_4x4, block_height_4x4, - row_start_4x4, col_start_4x4, num_unit_rows, - num_unit_cols, source_mv, source_ref_frame, - motion_vector_info); - // Second rectangle. - if (square_size_4x4 == 2) { - is_valid_second_rectangle = 1; - source_ref_frame[0] = mi[0]->ref_frame[0]; - source_ref_frame[1] = mi[0]->ref_frame[1]; - source_mv[0] = &mi[0]->bmi[2].as_mv[0].as_mv; - source_mv[1] = &mi[0]->bmi[2].as_mv[1].as_mv; - } else { - const int mi_row_2 = mi_row + (block_height_4x4 >> 1); - const int mi_col_2 = mi_col; - if (mi_row_2 * 2 < num_unit_rows && mi_col_2 * 2 < num_unit_cols) { - const int mi_idx_2 = mi_stride * mi_row_2 + mi_col_2; - is_valid_second_rectangle = 1; - mi = mi_grid_visible + mi_idx_2; - source_ref_frame[0] = mi[0]->ref_frame[0]; - source_ref_frame[1] = mi[0]->ref_frame[1]; - source_mv[0] = &mi[0]->mv[0].as_mv; - source_mv[1] = &mi[0]->mv[1].as_mv; - } - } - if (is_valid_second_rectangle) { - assign_motion_vector_info( - block_width_4x4, block_height_4x4, row_start_4x4 + block_height_4x4, - col_start_4x4, num_unit_rows, num_unit_cols, source_mv, - source_ref_frame, motion_vector_info); - } - } else if (pc_tree->partitioning == PARTITION_VERT) { - int is_valid_second_rectangle = 0; - assert(square_size_4x4 > 1); - // First rectangle. - source_ref_frame[0] = mi[0]->ref_frame[0]; - source_ref_frame[1] = mi[0]->ref_frame[1]; - source_mv[0] = &mi[0]->mv[0].as_mv; - source_mv[1] = &mi[0]->mv[1].as_mv; - assign_motion_vector_info(block_width_4x4, block_height_4x4, - row_start_4x4, col_start_4x4, num_unit_rows, - num_unit_cols, source_mv, source_ref_frame, - motion_vector_info); - // Second rectangle. - if (square_size_4x4 == 2) { - is_valid_second_rectangle = 1; - source_ref_frame[0] = mi[0]->ref_frame[0]; - source_ref_frame[1] = mi[0]->ref_frame[1]; - source_mv[0] = &mi[0]->bmi[1].as_mv[0].as_mv; - source_mv[1] = &mi[0]->bmi[1].as_mv[1].as_mv; - } else { - const int mi_row_2 = mi_row; - const int mi_col_2 = mi_col + (block_width_4x4 >> 1); - if (mi_row_2 * 2 < num_unit_rows && mi_col_2 * 2 < num_unit_cols) { - const int mi_idx_2 = mi_stride * mi_row_2 + mi_col_2; - is_valid_second_rectangle = 1; - mi = mi_grid_visible + mi_idx_2; - source_ref_frame[0] = mi[0]->ref_frame[0]; - source_ref_frame[1] = mi[0]->ref_frame[1]; - source_mv[0] = &mi[0]->mv[0].as_mv; - source_mv[1] = &mi[0]->mv[1].as_mv; - } - } - if (is_valid_second_rectangle) { - assign_motion_vector_info( - block_width_4x4, block_height_4x4, row_start_4x4, - col_start_4x4 + block_width_4x4, num_unit_rows, num_unit_cols, - source_mv, source_ref_frame, motion_vector_info); - } - } else { - assert(pc_tree->partitioning == PARTITION_NONE || square_size_4x4 == 1); - source_ref_frame[0] = mi[0]->ref_frame[0]; - source_ref_frame[1] = mi[0]->ref_frame[1]; - if (square_size_4x4 == 1) { - const int sub8x8_row = row_start_4x4 % 2; - const int sub8x8_col = col_start_4x4 % 2; - const int sub8x8_idx = sub8x8_row * 2 + sub8x8_col; - source_mv[0] = &mi[0]->bmi[sub8x8_idx].as_mv[0].as_mv; - source_mv[1] = &mi[0]->bmi[sub8x8_idx].as_mv[1].as_mv; - } else { - source_mv[0] = &mi[0]->mv[0].as_mv; - source_mv[1] = &mi[0]->mv[1].as_mv; - } - assign_motion_vector_info(block_width_4x4, block_height_4x4, - row_start_4x4, col_start_4x4, num_unit_rows, - num_unit_cols, source_mv, source_ref_frame, - motion_vector_info); - } - - return; - } - // recursively traverse partition tree when partition is split. - assert(pc_tree->partitioning == PARTITION_SPLIT); - store_superblock_info(pc_tree->u.split[0], mi_grid_visible, mi_stride, - subblock_square_size_4x4, num_unit_rows, num_unit_cols, - row_start_4x4, col_start_4x4, partition_info, - motion_vector_info); - store_superblock_info(pc_tree->u.split[1], mi_grid_visible, mi_stride, - subblock_square_size_4x4, num_unit_rows, num_unit_cols, - row_start_4x4, col_start_4x4 + subblock_square_size_4x4, - partition_info, motion_vector_info); - store_superblock_info(pc_tree->u.split[2], mi_grid_visible, mi_stride, - subblock_square_size_4x4, num_unit_rows, num_unit_cols, - row_start_4x4 + subblock_square_size_4x4, col_start_4x4, - partition_info, motion_vector_info); - store_superblock_info(pc_tree->u.split[3], mi_grid_visible, mi_stride, - subblock_square_size_4x4, num_unit_rows, num_unit_cols, - row_start_4x4 + subblock_square_size_4x4, - col_start_4x4 + subblock_square_size_4x4, - partition_info, motion_vector_info); -} -#endif // CONFIG_RATE_CTRL - -#if !CONFIG_REALTIME_ONLY -// TODO(jingning,jimbankoski,rbultje): properly skip partition types that are -// unlikely to be selected depending on previous rate-distortion optimization -// results, for encoding speed-up. -static int rd_pick_partition(VP9_COMP *cpi, ThreadData *td, - TileDataEnc *tile_data, TOKENEXTRA **tp, - int mi_row, int mi_col, BLOCK_SIZE bsize, - RD_COST *rd_cost, RD_COST best_rdc, - PC_TREE *pc_tree) { - VP9_COMMON *const cm = &cpi->common; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - TileInfo *const tile_info = &tile_data->tile_info; - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - const int mi_step = num_8x8_blocks_wide_lookup[bsize] / 2; - ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE]; - PARTITION_CONTEXT sl[8], sa[8]; - TOKENEXTRA *tp_orig = *tp; - PICK_MODE_CONTEXT *const ctx = &pc_tree->none; - int i; - const int pl = partition_plane_context(xd, mi_row, mi_col, bsize); - BLOCK_SIZE subsize; - RD_COST this_rdc, sum_rdc; - int do_split = bsize >= BLOCK_8X8; - int do_rect = 1; - INTERP_FILTER pred_interp_filter; - - // Override skipping rectangular partition operations for edge blocks - const int force_horz_split = (mi_row + mi_step >= cm->mi_rows); - const int force_vert_split = (mi_col + mi_step >= cm->mi_cols); - const int xss = x->e_mbd.plane[1].subsampling_x; - const int yss = x->e_mbd.plane[1].subsampling_y; - - BLOCK_SIZE min_size = x->min_partition_size; - BLOCK_SIZE max_size = x->max_partition_size; - - int partition_none_allowed = !force_horz_split && !force_vert_split; - int partition_horz_allowed = - !force_vert_split && yss <= xss && bsize >= BLOCK_8X8; - int partition_vert_allowed = - !force_horz_split && xss <= yss && bsize >= BLOCK_8X8; - - int64_t dist_breakout_thr = cpi->sf.partition_search_breakout_thr.dist; - int rate_breakout_thr = cpi->sf.partition_search_breakout_thr.rate; - int must_split = 0; - int should_encode_sb = 0; - - // Ref frames picked in the [i_th] quarter subblock during square partition - // RD search. It may be used to prune ref frame selection of rect partitions. - uint8_t ref_frames_used[4] = { 0, 0, 0, 0 }; - - int partition_mul = x->cb_rdmult; - - (void)*tp_orig; - - assert(num_8x8_blocks_wide_lookup[bsize] == - num_8x8_blocks_high_lookup[bsize]); - - dist_breakout_thr >>= - 8 - (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]); - - rate_breakout_thr *= num_pels_log2_lookup[bsize]; - - vp9_rd_cost_init(&this_rdc); - vp9_rd_cost_init(&sum_rdc); - - set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize); - - if (oxcf->tuning == VP8_TUNE_SSIM) { - set_ssim_rdmult(cpi, x, bsize, mi_row, mi_col, &partition_mul); - } - vp9_rd_cost_update(partition_mul, x->rddiv, &best_rdc); - - if (bsize == BLOCK_16X16 && cpi->oxcf.aq_mode != NO_AQ && - cpi->oxcf.aq_mode != LOOKAHEAD_AQ) - x->mb_energy = vp9_block_energy(cpi, x, bsize); - - if (cpi->sf.cb_partition_search && bsize == BLOCK_16X16) { - int cb_partition_search_ctrl = - ((pc_tree->index == 0 || pc_tree->index == 3) + - get_chessboard_index(cm->current_video_frame)) & - 0x1; - - if (cb_partition_search_ctrl && bsize > min_size && bsize < max_size) - set_partition_range(cm, xd, mi_row, mi_col, bsize, &min_size, &max_size); - } - - // Get sub block energy range - if (bsize >= BLOCK_16X16) { - int min_energy, max_energy; - vp9_get_sub_block_energy(cpi, x, mi_row, mi_col, bsize, &min_energy, - &max_energy); - must_split = (min_energy < -3) && (max_energy - min_energy > 2); - } - - // Determine partition types in search according to the speed features. - // The threshold set here has to be of square block size. - if (cpi->sf.auto_min_max_partition_size) { - partition_none_allowed &= (bsize <= max_size); - partition_horz_allowed &= - ((bsize <= max_size && bsize > min_size) || force_horz_split); - partition_vert_allowed &= - ((bsize <= max_size && bsize > min_size) || force_vert_split); - do_split &= bsize > min_size; - } - - if (cpi->sf.use_square_partition_only && - (bsize > cpi->sf.use_square_only_thresh_high || - bsize < cpi->sf.use_square_only_thresh_low)) { - if (cpi->use_svc) { - if (!vp9_active_h_edge(cpi, mi_row, mi_step) || x->e_mbd.lossless) - partition_horz_allowed &= force_horz_split; - if (!vp9_active_v_edge(cpi, mi_row, mi_step) || x->e_mbd.lossless) - partition_vert_allowed &= force_vert_split; - } else { - partition_horz_allowed &= force_horz_split; - partition_vert_allowed &= force_vert_split; - } - } - - save_context(x, mi_row, mi_col, a, l, sa, sl, bsize); - - pc_tree->partitioning = PARTITION_NONE; - - if (cpi->sf.rd_ml_partition.var_pruning && !frame_is_intra_only(cm)) { - const int do_rd_ml_partition_var_pruning = - partition_none_allowed && do_split && - mi_row + num_8x8_blocks_high_lookup[bsize] <= cm->mi_rows && - mi_col + num_8x8_blocks_wide_lookup[bsize] <= cm->mi_cols; - if (do_rd_ml_partition_var_pruning) { - ml_predict_var_rd_partitioning(cpi, x, pc_tree, bsize, mi_row, mi_col, - &partition_none_allowed, &do_split); - } else { - vp9_zero(pc_tree->mv); - } - if (bsize > BLOCK_8X8) { // Store MV result as reference for subblocks. - for (i = 0; i < 4; ++i) pc_tree->u.split[i]->mv = pc_tree->mv; - } - } - - // PARTITION_NONE - if (partition_none_allowed) { - rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc, bsize, ctx, - best_rdc.rate, best_rdc.dist); - ctx->rdcost = this_rdc.rdcost; - if (this_rdc.rate != INT_MAX) { - if (cpi->sf.prune_ref_frame_for_rect_partitions) { - const int ref1 = ctx->mic.ref_frame[0]; - const int ref2 = ctx->mic.ref_frame[1]; - for (i = 0; i < 4; ++i) { - ref_frames_used[i] |= (1 << ref1); - if (ref2 > 0) ref_frames_used[i] |= (1 << ref2); - } - } - if (bsize >= BLOCK_8X8) { - this_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE]; - vp9_rd_cost_update(partition_mul, x->rddiv, &this_rdc); - } - - if (this_rdc.rdcost < best_rdc.rdcost) { - MODE_INFO *mi = xd->mi[0]; - - best_rdc = this_rdc; - should_encode_sb = 1; - if (bsize >= BLOCK_8X8) pc_tree->partitioning = PARTITION_NONE; - - if (cpi->sf.rd_ml_partition.search_early_termination) { - // Currently, the machine-learning based partition search early - // termination is only used while bsize is 16x16, 32x32 or 64x64, - // VPXMIN(cm->width, cm->height) >= 480, and speed = 0. - if (!x->e_mbd.lossless && - !segfeature_active(&cm->seg, mi->segment_id, SEG_LVL_SKIP) && - ctx->mic.mode >= INTRA_MODES && bsize >= BLOCK_16X16) { - if (ml_pruning_partition(cm, xd, ctx, mi_row, mi_col, bsize)) { - do_split = 0; - do_rect = 0; - } - } - } - - if ((do_split || do_rect) && !x->e_mbd.lossless && ctx->skippable) { - const int use_ml_based_breakout = - cpi->sf.rd_ml_partition.search_breakout && cm->base_qindex >= 100; - if (use_ml_based_breakout) { - if (ml_predict_breakout(cpi, bsize, x, &this_rdc)) { - do_split = 0; - do_rect = 0; - } - } else { - if (!cpi->sf.rd_ml_partition.search_early_termination) { - if ((best_rdc.dist < (dist_breakout_thr >> 2)) || - (best_rdc.dist < dist_breakout_thr && - best_rdc.rate < rate_breakout_thr)) { - do_split = 0; - do_rect = 0; - } - } - } - } - } - } - restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize); - } else { - vp9_zero(ctx->pred_mv); - ctx->mic.interp_filter = EIGHTTAP; - } - - // store estimated motion vector - store_pred_mv(x, ctx); - - // If the interp_filter is marked as SWITCHABLE_FILTERS, it was for an - // intra block and used for context purposes. - if (ctx->mic.interp_filter == SWITCHABLE_FILTERS) { - pred_interp_filter = EIGHTTAP; - } else { - pred_interp_filter = ctx->mic.interp_filter; - } - - // PARTITION_SPLIT - // TODO(jingning): use the motion vectors given by the above search as - // the starting point of motion search in the following partition type check. - pc_tree->u.split[0]->none.rdcost = 0; - pc_tree->u.split[1]->none.rdcost = 0; - pc_tree->u.split[2]->none.rdcost = 0; - pc_tree->u.split[3]->none.rdcost = 0; - if (do_split || must_split) { - subsize = get_subsize(bsize, PARTITION_SPLIT); - load_pred_mv(x, ctx); - if (bsize == BLOCK_8X8) { - i = 4; - if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed) - pc_tree->u.leaf_split[0]->pred_interp_filter = pred_interp_filter; - rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc, subsize, - pc_tree->u.leaf_split[0], best_rdc.rate, best_rdc.dist); - if (sum_rdc.rate == INT_MAX) { - sum_rdc.rdcost = INT64_MAX; - } else { - if (cpi->sf.prune_ref_frame_for_rect_partitions) { - const int ref1 = pc_tree->u.leaf_split[0]->mic.ref_frame[0]; - const int ref2 = pc_tree->u.leaf_split[0]->mic.ref_frame[1]; - for (i = 0; i < 4; ++i) { - ref_frames_used[i] |= (1 << ref1); - if (ref2 > 0) ref_frames_used[i] |= (1 << ref2); - } - } - } - } else { - for (i = 0; (i < 4) && ((sum_rdc.rdcost < best_rdc.rdcost) || must_split); - ++i) { - const int x_idx = (i & 1) * mi_step; - const int y_idx = (i >> 1) * mi_step; - int found_best_rd = 0; - RD_COST best_rdc_split; - vp9_rd_cost_reset(&best_rdc_split); - - if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX) { - // A must split test here increases the number of sub - // partitions but hurts metrics results quite a bit, - // so this extra test is commented out pending - // further tests on whether it adds much in terms of - // visual quality. - // (must_split) ? best_rdc.rate - // : best_rdc.rate - sum_rdc.rate, - // (must_split) ? best_rdc.dist - // : best_rdc.dist - sum_rdc.dist, - best_rdc_split.rate = best_rdc.rate - sum_rdc.rate; - best_rdc_split.dist = best_rdc.dist - sum_rdc.dist; - } - - if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols) - continue; - - pc_tree->u.split[i]->index = i; - if (cpi->sf.prune_ref_frame_for_rect_partitions) - pc_tree->u.split[i]->none.rate = INT_MAX; - found_best_rd = rd_pick_partition( - cpi, td, tile_data, tp, mi_row + y_idx, mi_col + x_idx, subsize, - &this_rdc, best_rdc_split, pc_tree->u.split[i]); - - if (found_best_rd == 0) { - sum_rdc.rdcost = INT64_MAX; - break; - } else { - if (cpi->sf.prune_ref_frame_for_rect_partitions && - pc_tree->u.split[i]->none.rate != INT_MAX) { - const int ref1 = pc_tree->u.split[i]->none.mic.ref_frame[0]; - const int ref2 = pc_tree->u.split[i]->none.mic.ref_frame[1]; - ref_frames_used[i] |= (1 << ref1); - if (ref2 > 0) ref_frames_used[i] |= (1 << ref2); - } - sum_rdc.rate += this_rdc.rate; - sum_rdc.dist += this_rdc.dist; - vp9_rd_cost_update(partition_mul, x->rddiv, &sum_rdc); - } - } - } - - if (((sum_rdc.rdcost < best_rdc.rdcost) || must_split) && i == 4) { - sum_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT]; - vp9_rd_cost_update(partition_mul, x->rddiv, &sum_rdc); - - if ((sum_rdc.rdcost < best_rdc.rdcost) || - (must_split && (sum_rdc.dist < best_rdc.dist))) { - best_rdc = sum_rdc; - should_encode_sb = 1; - pc_tree->partitioning = PARTITION_SPLIT; - - // Rate and distortion based partition search termination clause. - if (!cpi->sf.rd_ml_partition.search_early_termination && - !x->e_mbd.lossless && - ((best_rdc.dist < (dist_breakout_thr >> 2)) || - (best_rdc.dist < dist_breakout_thr && - best_rdc.rate < rate_breakout_thr))) { - do_rect = 0; - } - } - } else { - // skip rectangular partition test when larger block size - // gives better rd cost - if (cpi->sf.less_rectangular_check && - (bsize > cpi->sf.use_square_only_thresh_high || - best_rdc.dist < dist_breakout_thr)) - do_rect &= !partition_none_allowed; - } - restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize); - } - - pc_tree->horizontal[0].skip_ref_frame_mask = 0; - pc_tree->horizontal[1].skip_ref_frame_mask = 0; - pc_tree->vertical[0].skip_ref_frame_mask = 0; - pc_tree->vertical[1].skip_ref_frame_mask = 0; - if (cpi->sf.prune_ref_frame_for_rect_partitions) { - uint8_t used_frames; - used_frames = ref_frames_used[0] | ref_frames_used[1]; - if (used_frames) { - pc_tree->horizontal[0].skip_ref_frame_mask = ~used_frames & 0xff; - } - used_frames = ref_frames_used[2] | ref_frames_used[3]; - if (used_frames) { - pc_tree->horizontal[1].skip_ref_frame_mask = ~used_frames & 0xff; - } - used_frames = ref_frames_used[0] | ref_frames_used[2]; - if (used_frames) { - pc_tree->vertical[0].skip_ref_frame_mask = ~used_frames & 0xff; - } - used_frames = ref_frames_used[1] | ref_frames_used[3]; - if (used_frames) { - pc_tree->vertical[1].skip_ref_frame_mask = ~used_frames & 0xff; - } - } - - { - const int do_ml_rect_partition_pruning = - !frame_is_intra_only(cm) && !force_horz_split && !force_vert_split && - (partition_horz_allowed || partition_vert_allowed) && bsize > BLOCK_8X8; - if (do_ml_rect_partition_pruning) { - ml_prune_rect_partition(cpi, x, bsize, pc_tree, &partition_horz_allowed, - &partition_vert_allowed, best_rdc.rdcost); - } - } - - // PARTITION_HORZ - if (partition_horz_allowed && - (do_rect || vp9_active_h_edge(cpi, mi_row, mi_step))) { - const int part_mode_rate = cpi->partition_cost[pl][PARTITION_HORZ]; - subsize = get_subsize(bsize, PARTITION_HORZ); - load_pred_mv(x, ctx); - if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 && - partition_none_allowed) - pc_tree->horizontal[0].pred_interp_filter = pred_interp_filter; - rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc, subsize, - &pc_tree->horizontal[0], best_rdc.rate - part_mode_rate, - best_rdc.dist); - if (sum_rdc.rdcost < INT64_MAX) { - sum_rdc.rate += part_mode_rate; - vp9_rd_cost_update(partition_mul, x->rddiv, &sum_rdc); - } - - if (sum_rdc.rdcost < best_rdc.rdcost && mi_row + mi_step < cm->mi_rows && - bsize > BLOCK_8X8) { - PICK_MODE_CONTEXT *hctx = &pc_tree->horizontal[0]; - update_state(cpi, td, hctx, mi_row, mi_col, subsize, 0); - encode_superblock(cpi, td, tp, 0, mi_row, mi_col, subsize, hctx); - if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 && - partition_none_allowed) - pc_tree->horizontal[1].pred_interp_filter = pred_interp_filter; - rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc, - subsize, &pc_tree->horizontal[1], - best_rdc.rate - sum_rdc.rate, - best_rdc.dist - sum_rdc.dist); - if (this_rdc.rate == INT_MAX) { - sum_rdc.rdcost = INT64_MAX; - } else { - sum_rdc.rate += this_rdc.rate; - sum_rdc.dist += this_rdc.dist; - vp9_rd_cost_update(partition_mul, x->rddiv, &sum_rdc); - } - } - - if (sum_rdc.rdcost < best_rdc.rdcost) { - best_rdc = sum_rdc; - should_encode_sb = 1; - pc_tree->partitioning = PARTITION_HORZ; - - if (cpi->sf.less_rectangular_check && - bsize > cpi->sf.use_square_only_thresh_high) - do_rect = 0; - } - restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize); - } - - // PARTITION_VERT - if (partition_vert_allowed && - (do_rect || vp9_active_v_edge(cpi, mi_col, mi_step))) { - const int part_mode_rate = cpi->partition_cost[pl][PARTITION_VERT]; - subsize = get_subsize(bsize, PARTITION_VERT); - load_pred_mv(x, ctx); - if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 && - partition_none_allowed) - pc_tree->vertical[0].pred_interp_filter = pred_interp_filter; - rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc, subsize, - &pc_tree->vertical[0], best_rdc.rate - part_mode_rate, - best_rdc.dist); - if (sum_rdc.rdcost < INT64_MAX) { - sum_rdc.rate += part_mode_rate; - vp9_rd_cost_update(partition_mul, x->rddiv, &sum_rdc); - } - - if (sum_rdc.rdcost < best_rdc.rdcost && mi_col + mi_step < cm->mi_cols && - bsize > BLOCK_8X8) { - update_state(cpi, td, &pc_tree->vertical[0], mi_row, mi_col, subsize, 0); - encode_superblock(cpi, td, tp, 0, mi_row, mi_col, subsize, - &pc_tree->vertical[0]); - if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 && - partition_none_allowed) - pc_tree->vertical[1].pred_interp_filter = pred_interp_filter; - rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc, - subsize, &pc_tree->vertical[1], - best_rdc.rate - sum_rdc.rate, - best_rdc.dist - sum_rdc.dist); - if (this_rdc.rate == INT_MAX) { - sum_rdc.rdcost = INT64_MAX; - } else { - sum_rdc.rate += this_rdc.rate; - sum_rdc.dist += this_rdc.dist; - vp9_rd_cost_update(partition_mul, x->rddiv, &sum_rdc); - } - } - - if (sum_rdc.rdcost < best_rdc.rdcost) { - best_rdc = sum_rdc; - should_encode_sb = 1; - pc_tree->partitioning = PARTITION_VERT; - } - restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize); - } - - if (bsize == BLOCK_64X64 && best_rdc.rdcost == INT64_MAX) { - vp9_rd_cost_reset(&this_rdc); - rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc, BLOCK_64X64, - ctx, INT_MAX, INT64_MAX); - ctx->rdcost = this_rdc.rdcost; - vp9_rd_cost_update(partition_mul, x->rddiv, &this_rdc); - if (this_rdc.rdcost < best_rdc.rdcost) { - best_rdc = this_rdc; - should_encode_sb = 1; - pc_tree->partitioning = PARTITION_NONE; - } - } - - *rd_cost = best_rdc; - - if (should_encode_sb && pc_tree->index != 3) { - int output_enabled = (bsize == BLOCK_64X64); -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, encode_sb_time); -#endif - encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, bsize, - pc_tree); -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, encode_sb_time); -#endif -#if CONFIG_RATE_CTRL - if (oxcf->use_simple_encode_api) { - // Store partition, motion vector of the superblock. - if (output_enabled) { - const int num_unit_rows = - get_num_unit_4x4(cpi->frame_info.frame_height); - const int num_unit_cols = get_num_unit_4x4(cpi->frame_info.frame_width); - store_superblock_info(pc_tree, cm->mi_grid_visible, cm->mi_stride, - num_4x4_blocks_wide_lookup[BLOCK_64X64], - num_unit_rows, num_unit_cols, mi_row << 1, - mi_col << 1, cpi->partition_info, - cpi->motion_vector_info); - } - } -#endif // CONFIG_RATE_CTRL - } - - if (bsize == BLOCK_64X64) { - assert(tp_orig < *tp); - assert(best_rdc.rate < INT_MAX); - assert(best_rdc.dist < INT64_MAX); - } else { - assert(tp_orig == *tp); - } - - return should_encode_sb; -} - -static void encode_rd_sb_row(VP9_COMP *cpi, ThreadData *td, - TileDataEnc *tile_data, int mi_row, - TOKENEXTRA **tp) { - VP9_COMMON *const cm = &cpi->common; - TileInfo *const tile_info = &tile_data->tile_info; - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - SPEED_FEATURES *const sf = &cpi->sf; - const int mi_col_start = tile_info->mi_col_start; - const int mi_col_end = tile_info->mi_col_end; - int mi_col; - const int sb_row = mi_row >> MI_BLOCK_SIZE_LOG2; - const int num_sb_cols = - get_num_cols(tile_data->tile_info, MI_BLOCK_SIZE_LOG2); - int sb_col_in_tile; - - // Initialize the left context for the new SB row - memset(&xd->left_context, 0, sizeof(xd->left_context)); - memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context)); - - // Code each SB in the row - for (mi_col = mi_col_start, sb_col_in_tile = 0; mi_col < mi_col_end; - mi_col += MI_BLOCK_SIZE, sb_col_in_tile++) { - const struct segmentation *const seg = &cm->seg; - int dummy_rate; - int64_t dummy_dist; - RD_COST dummy_rdc; - int i; - int seg_skip = 0; - int orig_rdmult = cpi->rd.RDMULT; - - const int idx_str = cm->mi_stride * mi_row + mi_col; - MODE_INFO **mi = cm->mi_grid_visible + idx_str; - - vp9_rd_cost_reset(&dummy_rdc); - (*(cpi->row_mt_sync_read_ptr))(&tile_data->row_mt_sync, sb_row, - sb_col_in_tile); - - if (sf->adaptive_pred_interp_filter) { - for (i = 0; i < 64; ++i) td->leaf_tree[i].pred_interp_filter = SWITCHABLE; - - for (i = 0; i < 64; ++i) { - td->pc_tree[i].vertical[0].pred_interp_filter = SWITCHABLE; - td->pc_tree[i].vertical[1].pred_interp_filter = SWITCHABLE; - td->pc_tree[i].horizontal[0].pred_interp_filter = SWITCHABLE; - td->pc_tree[i].horizontal[1].pred_interp_filter = SWITCHABLE; - } - } - - for (i = 0; i < MAX_REF_FRAMES; ++i) { - x->pred_mv[i].row = INT16_MAX; - x->pred_mv[i].col = INT16_MAX; - } - td->pc_root->index = 0; - - if (seg->enabled) { - const uint8_t *const map = - seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map; - int segment_id = get_segment_id(cm, map, BLOCK_64X64, mi_row, mi_col); - seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP); - } - - x->source_variance = UINT_MAX; - - x->cb_rdmult = orig_rdmult; - - if (sf->partition_search_type == FIXED_PARTITION || seg_skip) { - const BLOCK_SIZE bsize = - seg_skip ? BLOCK_64X64 : sf->always_this_block_size; - set_offsets(cpi, tile_info, x, mi_row, mi_col, BLOCK_64X64); - set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize); - rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, BLOCK_64X64, - &dummy_rate, &dummy_dist, 1, td->pc_root); - } else if (sf->partition_search_type == VAR_BASED_PARTITION && - cm->frame_type != KEY_FRAME) { - choose_partitioning(cpi, tile_info, x, mi_row, mi_col); - rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, BLOCK_64X64, - &dummy_rate, &dummy_dist, 1, td->pc_root); - } else { - if (cpi->twopass.gf_group.index > 0 && cpi->sf.enable_tpl_model) { - int dr = - get_rdmult_delta(cpi, BLOCK_64X64, mi_row, mi_col, orig_rdmult); - x->cb_rdmult = dr; - } - - if (cpi->oxcf.aq_mode == PERCEPTUAL_AQ && cm->show_frame) { - x->segment_id = wiener_var_segment(cpi, BLOCK_64X64, mi_row, mi_col); - x->cb_rdmult = vp9_compute_rd_mult( - cpi, vp9_get_qindex(&cm->seg, x->segment_id, cm->base_qindex)); - } - - // If required set upper and lower partition size limits - if (sf->auto_min_max_partition_size) { - set_offsets(cpi, tile_info, x, mi_row, mi_col, BLOCK_64X64); - rd_auto_partition_range(cpi, tile_info, xd, mi_row, mi_col, - &x->min_partition_size, &x->max_partition_size); - } - td->pc_root->none.rdcost = 0; - -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, rd_pick_partition_time); -#endif - rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, BLOCK_64X64, - &dummy_rdc, dummy_rdc, td->pc_root); -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, rd_pick_partition_time); -#endif - } - (*(cpi->row_mt_sync_write_ptr))(&tile_data->row_mt_sync, sb_row, - sb_col_in_tile, num_sb_cols); - } -} -#endif // !CONFIG_REALTIME_ONLY - -static void init_encode_frame_mb_context(VP9_COMP *cpi) { - MACROBLOCK *const x = &cpi->td.mb; - VP9_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &x->e_mbd; - const int aligned_mi_cols = mi_cols_aligned_to_sb(cm->mi_cols); - - // Copy data over into macro block data structures. - vp9_setup_src_planes(x, cpi->Source, 0, 0); - - vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y); - - // Note: this memset assumes above_context[0], [1] and [2] - // are allocated as part of the same buffer. - memset(xd->above_context[0], 0, - sizeof(*xd->above_context[0]) * 2 * aligned_mi_cols * MAX_MB_PLANE); - memset(xd->above_seg_context, 0, - sizeof(*xd->above_seg_context) * aligned_mi_cols); -} - -static int check_dual_ref_flags(VP9_COMP *cpi) { - const int ref_flags = cpi->ref_frame_flags; - - if (segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) { - return 0; - } else { - return (!!(ref_flags & VP9_GOLD_FLAG) + !!(ref_flags & VP9_LAST_FLAG) + - !!(ref_flags & VP9_ALT_FLAG)) >= 2; - } -} - -static void reset_skip_tx_size(VP9_COMMON *cm, TX_SIZE max_tx_size) { - int mi_row, mi_col; - const int mis = cm->mi_stride; - MODE_INFO **mi_ptr = cm->mi_grid_visible; - - for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row, mi_ptr += mis) { - for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) { - if (mi_ptr[mi_col]->tx_size > max_tx_size) - mi_ptr[mi_col]->tx_size = max_tx_size; - } - } -} - -static MV_REFERENCE_FRAME get_frame_type(const VP9_COMP *cpi) { - if (frame_is_intra_only(&cpi->common)) - return INTRA_FRAME; - else if (cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame) - return ALTREF_FRAME; - else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) - return GOLDEN_FRAME; - else - return LAST_FRAME; -} - -static TX_MODE select_tx_mode(const VP9_COMP *cpi, MACROBLOCKD *const xd) { - if (xd->lossless) return ONLY_4X4; - if (cpi->common.frame_type == KEY_FRAME && cpi->sf.use_nonrd_pick_mode) - return ALLOW_16X16; - if (cpi->sf.tx_size_search_method == USE_LARGESTALL) - return ALLOW_32X32; - else if (cpi->sf.tx_size_search_method == USE_FULL_RD || - cpi->sf.tx_size_search_method == USE_TX_8X8) - return TX_MODE_SELECT; - else - return cpi->common.tx_mode; -} - -static void hybrid_intra_mode_search(VP9_COMP *cpi, MACROBLOCK *const x, - RD_COST *rd_cost, BLOCK_SIZE bsize, - PICK_MODE_CONTEXT *ctx) { - if (!cpi->sf.nonrd_keyframe && bsize < BLOCK_16X16) - vp9_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, INT64_MAX); - else - vp9_pick_intra_mode(cpi, x, rd_cost, bsize, ctx); -} - -static void hybrid_search_svc_baseiskey(VP9_COMP *cpi, MACROBLOCK *const x, - RD_COST *rd_cost, BLOCK_SIZE bsize, - PICK_MODE_CONTEXT *ctx, - TileDataEnc *tile_data, int mi_row, - int mi_col) { - if (!cpi->sf.nonrd_keyframe && bsize <= BLOCK_8X8) { - vp9_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, INT64_MAX); - } else { - if (cpi->svc.disable_inter_layer_pred == INTER_LAYER_PRED_OFF) - vp9_pick_intra_mode(cpi, x, rd_cost, bsize, ctx); - else if (bsize >= BLOCK_8X8) - vp9_pick_inter_mode(cpi, x, tile_data, mi_row, mi_col, rd_cost, bsize, - ctx); - else - vp9_pick_inter_mode_sub8x8(cpi, x, mi_row, mi_col, rd_cost, bsize, ctx); - } -} - -static void hybrid_search_scene_change(VP9_COMP *cpi, MACROBLOCK *const x, - RD_COST *rd_cost, BLOCK_SIZE bsize, - PICK_MODE_CONTEXT *ctx, - TileDataEnc *tile_data, int mi_row, - int mi_col) { - if (!cpi->sf.nonrd_keyframe && bsize <= BLOCK_8X8) { - vp9_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, INT64_MAX); - } else { - vp9_pick_inter_mode(cpi, x, tile_data, mi_row, mi_col, rd_cost, bsize, ctx); - } -} - -static void nonrd_pick_sb_modes(VP9_COMP *cpi, TileDataEnc *tile_data, - MACROBLOCK *const x, int mi_row, int mi_col, - RD_COST *rd_cost, BLOCK_SIZE bsize, - PICK_MODE_CONTEXT *ctx) { - VP9_COMMON *const cm = &cpi->common; - TileInfo *const tile_info = &tile_data->tile_info; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *mi; - ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE]; - BLOCK_SIZE bs = VPXMAX(bsize, BLOCK_8X8); // processing unit block size - const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bs]; - const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bs]; - int plane; - - set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize); - - set_segment_index(cpi, x, mi_row, mi_col, bsize, 0); - - x->skip_recode = 0; - - mi = xd->mi[0]; - mi->sb_type = bsize; - - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { - struct macroblockd_plane *pd = &xd->plane[plane]; - memcpy(a + num_4x4_blocks_wide * plane, pd->above_context, - (sizeof(a[0]) * num_4x4_blocks_wide) >> pd->subsampling_x); - memcpy(l + num_4x4_blocks_high * plane, pd->left_context, - (sizeof(l[0]) * num_4x4_blocks_high) >> pd->subsampling_y); - } - - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled) - if (cyclic_refresh_segment_id_boosted(mi->segment_id)) - x->rdmult = vp9_cyclic_refresh_get_rdmult(cpi->cyclic_refresh); - - if (frame_is_intra_only(cm)) - hybrid_intra_mode_search(cpi, x, rd_cost, bsize, ctx); - else if (cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame) - hybrid_search_svc_baseiskey(cpi, x, rd_cost, bsize, ctx, tile_data, mi_row, - mi_col); - else if (segfeature_active(&cm->seg, mi->segment_id, SEG_LVL_SKIP)) - set_mode_info_seg_skip(x, cm->tx_mode, cm->interp_filter, rd_cost, bsize); - else if (bsize >= BLOCK_8X8) { - if (cpi->rc.hybrid_intra_scene_change) - hybrid_search_scene_change(cpi, x, rd_cost, bsize, ctx, tile_data, mi_row, - mi_col); - else - vp9_pick_inter_mode(cpi, x, tile_data, mi_row, mi_col, rd_cost, bsize, - ctx); - } else { - vp9_pick_inter_mode_sub8x8(cpi, x, mi_row, mi_col, rd_cost, bsize, ctx); - } - - duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize); - - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { - struct macroblockd_plane *pd = &xd->plane[plane]; - memcpy(pd->above_context, a + num_4x4_blocks_wide * plane, - (sizeof(a[0]) * num_4x4_blocks_wide) >> pd->subsampling_x); - memcpy(pd->left_context, l + num_4x4_blocks_high * plane, - (sizeof(l[0]) * num_4x4_blocks_high) >> pd->subsampling_y); - } - - if (rd_cost->rate == INT_MAX) vp9_rd_cost_reset(rd_cost); - - ctx->rate = rd_cost->rate; - ctx->dist = rd_cost->dist; -} - -static void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x, int mi_row, - int mi_col, BLOCK_SIZE bsize, PC_TREE *pc_tree) { - MACROBLOCKD *xd = &x->e_mbd; - int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4; - PARTITION_TYPE partition = pc_tree->partitioning; - BLOCK_SIZE subsize = get_subsize(bsize, partition); - - assert(bsize >= BLOCK_8X8); - - if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - - switch (partition) { - case PARTITION_NONE: - set_mode_info_offsets(cm, x, xd, mi_row, mi_col); - *(xd->mi[0]) = pc_tree->none.mic; - *(x->mbmi_ext) = pc_tree->none.mbmi_ext; - duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize); - break; - case PARTITION_VERT: - set_mode_info_offsets(cm, x, xd, mi_row, mi_col); - *(xd->mi[0]) = pc_tree->vertical[0].mic; - *(x->mbmi_ext) = pc_tree->vertical[0].mbmi_ext; - duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, subsize); - - if (mi_col + hbs < cm->mi_cols) { - set_mode_info_offsets(cm, x, xd, mi_row, mi_col + hbs); - *(xd->mi[0]) = pc_tree->vertical[1].mic; - *(x->mbmi_ext) = pc_tree->vertical[1].mbmi_ext; - duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col + hbs, subsize); - } - break; - case PARTITION_HORZ: - set_mode_info_offsets(cm, x, xd, mi_row, mi_col); - *(xd->mi[0]) = pc_tree->horizontal[0].mic; - *(x->mbmi_ext) = pc_tree->horizontal[0].mbmi_ext; - duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, subsize); - if (mi_row + hbs < cm->mi_rows) { - set_mode_info_offsets(cm, x, xd, mi_row + hbs, mi_col); - *(xd->mi[0]) = pc_tree->horizontal[1].mic; - *(x->mbmi_ext) = pc_tree->horizontal[1].mbmi_ext; - duplicate_mode_info_in_sb(cm, xd, mi_row + hbs, mi_col, subsize); - } - break; - case PARTITION_SPLIT: { - fill_mode_info_sb(cm, x, mi_row, mi_col, subsize, pc_tree->u.split[0]); - fill_mode_info_sb(cm, x, mi_row, mi_col + hbs, subsize, - pc_tree->u.split[1]); - fill_mode_info_sb(cm, x, mi_row + hbs, mi_col, subsize, - pc_tree->u.split[2]); - fill_mode_info_sb(cm, x, mi_row + hbs, mi_col + hbs, subsize, - pc_tree->u.split[3]); - break; - } - default: break; - } -} - -// Reset the prediction pixel ready flag recursively. -static void pred_pixel_ready_reset(PC_TREE *pc_tree, BLOCK_SIZE bsize) { - pc_tree->none.pred_pixel_ready = 0; - pc_tree->horizontal[0].pred_pixel_ready = 0; - pc_tree->horizontal[1].pred_pixel_ready = 0; - pc_tree->vertical[0].pred_pixel_ready = 0; - pc_tree->vertical[1].pred_pixel_ready = 0; - - if (bsize > BLOCK_8X8) { - BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_SPLIT); - int i; - for (i = 0; i < 4; ++i) - pred_pixel_ready_reset(pc_tree->u.split[i], subsize); - } -} - -#define FEATURES 6 -#define LABELS 2 -static int ml_predict_var_partitioning(VP9_COMP *cpi, MACROBLOCK *x, - BLOCK_SIZE bsize, int mi_row, - int mi_col) { - VP9_COMMON *const cm = &cpi->common; - const NN_CONFIG *nn_config = NULL; - - switch (bsize) { - case BLOCK_64X64: nn_config = &vp9_var_part_nnconfig_64; break; - case BLOCK_32X32: nn_config = &vp9_var_part_nnconfig_32; break; - case BLOCK_16X16: nn_config = &vp9_var_part_nnconfig_16; break; - case BLOCK_8X8: break; - default: assert(0 && "Unexpected block size."); return -1; - } - - if (!nn_config) return -1; - - vpx_clear_system_state(); - - { - const float thresh = cpi->oxcf.speed <= 5 ? 1.25f : 0.0f; - float features[FEATURES] = { 0.0f }; - const int dc_q = vp9_dc_quant(cm->base_qindex, 0, cm->bit_depth); - int feature_idx = 0; - float score[LABELS]; - - features[feature_idx++] = logf((float)(dc_q * dc_q) / 256.0f + 1.0f); - vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col); - { - const int bs = 4 * num_4x4_blocks_wide_lookup[bsize]; - const BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_SPLIT); - const int sb_offset_row = 8 * (mi_row & 7); - const int sb_offset_col = 8 * (mi_col & 7); - const uint8_t *pred = x->est_pred + sb_offset_row * 64 + sb_offset_col; - const uint8_t *src = x->plane[0].src.buf; - const int src_stride = x->plane[0].src.stride; - const int pred_stride = 64; - unsigned int sse; - int i; - // Variance of whole block. - const unsigned int var = - cpi->fn_ptr[bsize].vf(src, src_stride, pred, pred_stride, &sse); - const float factor = (var == 0) ? 1.0f : (1.0f / (float)var); - - features[feature_idx++] = logf((float)var + 1.0f); - for (i = 0; i < 4; ++i) { - const int x_idx = (i & 1) * bs / 2; - const int y_idx = (i >> 1) * bs / 2; - const int src_offset = y_idx * src_stride + x_idx; - const int pred_offset = y_idx * pred_stride + x_idx; - // Variance of quarter block. - const unsigned int sub_var = - cpi->fn_ptr[subsize].vf(src + src_offset, src_stride, - pred + pred_offset, pred_stride, &sse); - const float var_ratio = (var == 0) ? 1.0f : factor * (float)sub_var; - features[feature_idx++] = var_ratio; - } - } - - assert(feature_idx == FEATURES); - nn_predict(features, nn_config, score); - if (score[0] > thresh) return PARTITION_SPLIT; - if (score[0] < -thresh) return PARTITION_NONE; - return -1; - } -} -#undef FEATURES -#undef LABELS - -static void nonrd_pick_partition(VP9_COMP *cpi, ThreadData *td, - TileDataEnc *tile_data, TOKENEXTRA **tp, - int mi_row, int mi_col, BLOCK_SIZE bsize, - RD_COST *rd_cost, int do_recon, - int64_t best_rd, PC_TREE *pc_tree) { - const SPEED_FEATURES *const sf = &cpi->sf; - VP9_COMMON *const cm = &cpi->common; - TileInfo *const tile_info = &tile_data->tile_info; - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - const int ms = num_8x8_blocks_wide_lookup[bsize] / 2; - TOKENEXTRA *tp_orig = *tp; - PICK_MODE_CONTEXT *ctx = &pc_tree->none; - int i; - BLOCK_SIZE subsize = bsize; - RD_COST this_rdc, sum_rdc, best_rdc; - int do_split = bsize >= BLOCK_8X8; - int do_rect = 1; - // Override skipping rectangular partition operations for edge blocks - const int force_horz_split = (mi_row + ms >= cm->mi_rows); - const int force_vert_split = (mi_col + ms >= cm->mi_cols); - const int xss = x->e_mbd.plane[1].subsampling_x; - const int yss = x->e_mbd.plane[1].subsampling_y; - - int partition_none_allowed = !force_horz_split && !force_vert_split; - int partition_horz_allowed = - !force_vert_split && yss <= xss && bsize >= BLOCK_8X8; - int partition_vert_allowed = - !force_horz_split && xss <= yss && bsize >= BLOCK_8X8; - const int use_ml_based_partitioning = - sf->partition_search_type == ML_BASED_PARTITION; - - (void)*tp_orig; - - // Avoid checking for rectangular partitions for speed >= 5. - if (cpi->oxcf.speed >= 5) do_rect = 0; - - assert(num_8x8_blocks_wide_lookup[bsize] == - num_8x8_blocks_high_lookup[bsize]); - - vp9_rd_cost_init(&sum_rdc); - vp9_rd_cost_reset(&best_rdc); - best_rdc.rdcost = best_rd; - - // Determine partition types in search according to the speed features. - // The threshold set here has to be of square block size. - if (sf->auto_min_max_partition_size) { - partition_none_allowed &= - (bsize <= x->max_partition_size && bsize >= x->min_partition_size); - partition_horz_allowed &= - ((bsize <= x->max_partition_size && bsize > x->min_partition_size) || - force_horz_split); - partition_vert_allowed &= - ((bsize <= x->max_partition_size && bsize > x->min_partition_size) || - force_vert_split); - do_split &= bsize > x->min_partition_size; - } - if (sf->use_square_partition_only) { - partition_horz_allowed &= force_horz_split; - partition_vert_allowed &= force_vert_split; - } - - if (use_ml_based_partitioning) { - if (partition_none_allowed || do_split) do_rect = 0; - if (partition_none_allowed && do_split) { - const int ml_predicted_partition = - ml_predict_var_partitioning(cpi, x, bsize, mi_row, mi_col); - if (ml_predicted_partition == PARTITION_NONE) do_split = 0; - if (ml_predicted_partition == PARTITION_SPLIT) partition_none_allowed = 0; - } - } - - if (!partition_none_allowed && !do_split) do_rect = 1; - - ctx->pred_pixel_ready = - !(partition_vert_allowed || partition_horz_allowed || do_split); - - // PARTITION_NONE - if (partition_none_allowed) { - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc, bsize, - ctx); - ctx->mic = *xd->mi[0]; - ctx->mbmi_ext = *x->mbmi_ext; - ctx->skip_txfm[0] = x->skip_txfm[0]; - ctx->skip = x->skip; - - if (this_rdc.rate != INT_MAX) { - const int pl = partition_plane_context(xd, mi_row, mi_col, bsize); - this_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE]; - this_rdc.rdcost = - RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist); - if (this_rdc.rdcost < best_rdc.rdcost) { - best_rdc = this_rdc; - if (bsize >= BLOCK_8X8) pc_tree->partitioning = PARTITION_NONE; - - if (!use_ml_based_partitioning) { - int64_t dist_breakout_thr = sf->partition_search_breakout_thr.dist; - int64_t rate_breakout_thr = sf->partition_search_breakout_thr.rate; - dist_breakout_thr >>= - 8 - (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]); - rate_breakout_thr *= num_pels_log2_lookup[bsize]; - if (!x->e_mbd.lossless && this_rdc.rate < rate_breakout_thr && - this_rdc.dist < dist_breakout_thr) { - do_split = 0; - do_rect = 0; - } - } - } - } - } - - // store estimated motion vector - store_pred_mv(x, ctx); - - // PARTITION_SPLIT - if (do_split) { - int pl = partition_plane_context(xd, mi_row, mi_col, bsize); - sum_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT]; - sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist); - subsize = get_subsize(bsize, PARTITION_SPLIT); - for (i = 0; i < 4 && sum_rdc.rdcost < best_rdc.rdcost; ++i) { - const int x_idx = (i & 1) * ms; - const int y_idx = (i >> 1) * ms; - - if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols) - continue; - load_pred_mv(x, ctx); - nonrd_pick_partition( - cpi, td, tile_data, tp, mi_row + y_idx, mi_col + x_idx, subsize, - &this_rdc, 0, best_rdc.rdcost - sum_rdc.rdcost, pc_tree->u.split[i]); - - if (this_rdc.rate == INT_MAX) { - vp9_rd_cost_reset(&sum_rdc); - } else { - sum_rdc.rate += this_rdc.rate; - sum_rdc.dist += this_rdc.dist; - sum_rdc.rdcost += this_rdc.rdcost; - } - } - - if (sum_rdc.rdcost < best_rdc.rdcost) { - best_rdc = sum_rdc; - pc_tree->partitioning = PARTITION_SPLIT; - } else { - // skip rectangular partition test when larger block size - // gives better rd cost - if (sf->less_rectangular_check) do_rect &= !partition_none_allowed; - } - } - - // PARTITION_HORZ - if (partition_horz_allowed && do_rect) { - subsize = get_subsize(bsize, PARTITION_HORZ); - load_pred_mv(x, ctx); - pc_tree->horizontal[0].pred_pixel_ready = 1; - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc, subsize, - &pc_tree->horizontal[0]); - - pc_tree->horizontal[0].mic = *xd->mi[0]; - pc_tree->horizontal[0].mbmi_ext = *x->mbmi_ext; - pc_tree->horizontal[0].skip_txfm[0] = x->skip_txfm[0]; - pc_tree->horizontal[0].skip = x->skip; - - if (sum_rdc.rdcost < best_rdc.rdcost && mi_row + ms < cm->mi_rows) { - load_pred_mv(x, ctx); - pc_tree->horizontal[1].pred_pixel_ready = 1; - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row + ms, mi_col, &this_rdc, - subsize, &pc_tree->horizontal[1]); - - pc_tree->horizontal[1].mic = *xd->mi[0]; - pc_tree->horizontal[1].mbmi_ext = *x->mbmi_ext; - pc_tree->horizontal[1].skip_txfm[0] = x->skip_txfm[0]; - pc_tree->horizontal[1].skip = x->skip; - - if (this_rdc.rate == INT_MAX) { - vp9_rd_cost_reset(&sum_rdc); - } else { - int pl = partition_plane_context(xd, mi_row, mi_col, bsize); - this_rdc.rate += cpi->partition_cost[pl][PARTITION_HORZ]; - sum_rdc.rate += this_rdc.rate; - sum_rdc.dist += this_rdc.dist; - sum_rdc.rdcost = - RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist); - } - } - - if (sum_rdc.rdcost < best_rdc.rdcost) { - best_rdc = sum_rdc; - pc_tree->partitioning = PARTITION_HORZ; - } else { - pred_pixel_ready_reset(pc_tree, bsize); - } - } - - // PARTITION_VERT - if (partition_vert_allowed && do_rect) { - subsize = get_subsize(bsize, PARTITION_VERT); - load_pred_mv(x, ctx); - pc_tree->vertical[0].pred_pixel_ready = 1; - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc, subsize, - &pc_tree->vertical[0]); - pc_tree->vertical[0].mic = *xd->mi[0]; - pc_tree->vertical[0].mbmi_ext = *x->mbmi_ext; - pc_tree->vertical[0].skip_txfm[0] = x->skip_txfm[0]; - pc_tree->vertical[0].skip = x->skip; - - if (sum_rdc.rdcost < best_rdc.rdcost && mi_col + ms < cm->mi_cols) { - load_pred_mv(x, ctx); - pc_tree->vertical[1].pred_pixel_ready = 1; - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + ms, &this_rdc, - subsize, &pc_tree->vertical[1]); - pc_tree->vertical[1].mic = *xd->mi[0]; - pc_tree->vertical[1].mbmi_ext = *x->mbmi_ext; - pc_tree->vertical[1].skip_txfm[0] = x->skip_txfm[0]; - pc_tree->vertical[1].skip = x->skip; - - if (this_rdc.rate == INT_MAX) { - vp9_rd_cost_reset(&sum_rdc); - } else { - int pl = partition_plane_context(xd, mi_row, mi_col, bsize); - sum_rdc.rate += cpi->partition_cost[pl][PARTITION_VERT]; - sum_rdc.rate += this_rdc.rate; - sum_rdc.dist += this_rdc.dist; - sum_rdc.rdcost = - RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist); - } - } - - if (sum_rdc.rdcost < best_rdc.rdcost) { - best_rdc = sum_rdc; - pc_tree->partitioning = PARTITION_VERT; - } else { - pred_pixel_ready_reset(pc_tree, bsize); - } - } - - *rd_cost = best_rdc; - - if (best_rdc.rate == INT_MAX) { - vp9_rd_cost_reset(rd_cost); - return; - } - - // update mode info array - fill_mode_info_sb(cm, x, mi_row, mi_col, bsize, pc_tree); - - if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX && do_recon) { - int output_enabled = (bsize == BLOCK_64X64); - encode_sb_rt(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, bsize, - pc_tree); - } - - if (bsize == BLOCK_64X64 && do_recon) { - assert(tp_orig < *tp); - assert(best_rdc.rate < INT_MAX); - assert(best_rdc.dist < INT64_MAX); - } else { - assert(tp_orig == *tp); - } -} - -static void nonrd_select_partition(VP9_COMP *cpi, ThreadData *td, - TileDataEnc *tile_data, MODE_INFO **mi, - TOKENEXTRA **tp, int mi_row, int mi_col, - BLOCK_SIZE bsize, int output_enabled, - RD_COST *rd_cost, PC_TREE *pc_tree) { - VP9_COMMON *const cm = &cpi->common; - TileInfo *const tile_info = &tile_data->tile_info; - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - const int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4; - const int mis = cm->mi_stride; - PARTITION_TYPE partition; - BLOCK_SIZE subsize; - RD_COST this_rdc; - BLOCK_SIZE subsize_ref = - (cpi->sf.adapt_partition_source_sad) ? BLOCK_8X8 : BLOCK_16X16; - - vp9_rd_cost_reset(&this_rdc); - if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - - subsize = (bsize >= BLOCK_8X8) ? mi[0]->sb_type : BLOCK_4X4; - partition = partition_lookup[bsl][subsize]; - - if (bsize == BLOCK_32X32 && subsize == BLOCK_32X32) { - x->max_partition_size = BLOCK_32X32; - x->min_partition_size = BLOCK_16X16; - nonrd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, bsize, rd_cost, - 0, INT64_MAX, pc_tree); - } else if (bsize == BLOCK_32X32 && partition != PARTITION_NONE && - subsize >= subsize_ref) { - x->max_partition_size = BLOCK_32X32; - x->min_partition_size = BLOCK_8X8; - nonrd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, bsize, rd_cost, - 0, INT64_MAX, pc_tree); - } else if (bsize == BLOCK_16X16 && partition != PARTITION_NONE) { - x->max_partition_size = BLOCK_16X16; - x->min_partition_size = BLOCK_8X8; - nonrd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, bsize, rd_cost, - 0, INT64_MAX, pc_tree); - } else { - switch (partition) { - case PARTITION_NONE: - pc_tree->none.pred_pixel_ready = 1; - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, rd_cost, subsize, - &pc_tree->none); - pc_tree->none.mic = *xd->mi[0]; - pc_tree->none.mbmi_ext = *x->mbmi_ext; - pc_tree->none.skip_txfm[0] = x->skip_txfm[0]; - pc_tree->none.skip = x->skip; - break; - case PARTITION_VERT: - pc_tree->vertical[0].pred_pixel_ready = 1; - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, rd_cost, subsize, - &pc_tree->vertical[0]); - pc_tree->vertical[0].mic = *xd->mi[0]; - pc_tree->vertical[0].mbmi_ext = *x->mbmi_ext; - pc_tree->vertical[0].skip_txfm[0] = x->skip_txfm[0]; - pc_tree->vertical[0].skip = x->skip; - if (mi_col + hbs < cm->mi_cols) { - pc_tree->vertical[1].pred_pixel_ready = 1; - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs, - &this_rdc, subsize, &pc_tree->vertical[1]); - pc_tree->vertical[1].mic = *xd->mi[0]; - pc_tree->vertical[1].mbmi_ext = *x->mbmi_ext; - pc_tree->vertical[1].skip_txfm[0] = x->skip_txfm[0]; - pc_tree->vertical[1].skip = x->skip; - if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX && - rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) { - rd_cost->rate += this_rdc.rate; - rd_cost->dist += this_rdc.dist; - } - } - break; - case PARTITION_HORZ: - pc_tree->horizontal[0].pred_pixel_ready = 1; - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, rd_cost, subsize, - &pc_tree->horizontal[0]); - pc_tree->horizontal[0].mic = *xd->mi[0]; - pc_tree->horizontal[0].mbmi_ext = *x->mbmi_ext; - pc_tree->horizontal[0].skip_txfm[0] = x->skip_txfm[0]; - pc_tree->horizontal[0].skip = x->skip; - if (mi_row + hbs < cm->mi_rows) { - pc_tree->horizontal[1].pred_pixel_ready = 1; - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col, - &this_rdc, subsize, &pc_tree->horizontal[1]); - pc_tree->horizontal[1].mic = *xd->mi[0]; - pc_tree->horizontal[1].mbmi_ext = *x->mbmi_ext; - pc_tree->horizontal[1].skip_txfm[0] = x->skip_txfm[0]; - pc_tree->horizontal[1].skip = x->skip; - if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX && - rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) { - rd_cost->rate += this_rdc.rate; - rd_cost->dist += this_rdc.dist; - } - } - break; - default: - assert(partition == PARTITION_SPLIT); - subsize = get_subsize(bsize, PARTITION_SPLIT); - nonrd_select_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, - subsize, output_enabled, rd_cost, - pc_tree->u.split[0]); - nonrd_select_partition(cpi, td, tile_data, mi + hbs, tp, mi_row, - mi_col + hbs, subsize, output_enabled, &this_rdc, - pc_tree->u.split[1]); - if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX && - rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) { - rd_cost->rate += this_rdc.rate; - rd_cost->dist += this_rdc.dist; - } - nonrd_select_partition(cpi, td, tile_data, mi + hbs * mis, tp, - mi_row + hbs, mi_col, subsize, output_enabled, - &this_rdc, pc_tree->u.split[2]); - if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX && - rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) { - rd_cost->rate += this_rdc.rate; - rd_cost->dist += this_rdc.dist; - } - nonrd_select_partition(cpi, td, tile_data, mi + hbs * mis + hbs, tp, - mi_row + hbs, mi_col + hbs, subsize, - output_enabled, &this_rdc, pc_tree->u.split[3]); - if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX && - rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) { - rd_cost->rate += this_rdc.rate; - rd_cost->dist += this_rdc.dist; - } - break; - } - } - - if (bsize == BLOCK_64X64 && output_enabled) - encode_sb_rt(cpi, td, tile_info, tp, mi_row, mi_col, 1, bsize, pc_tree); -} - -static void nonrd_use_partition(VP9_COMP *cpi, ThreadData *td, - TileDataEnc *tile_data, MODE_INFO **mi, - TOKENEXTRA **tp, int mi_row, int mi_col, - BLOCK_SIZE bsize, int output_enabled, - RD_COST *dummy_cost, PC_TREE *pc_tree) { - VP9_COMMON *const cm = &cpi->common; - TileInfo *tile_info = &tile_data->tile_info; - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - const int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4; - const int mis = cm->mi_stride; - PARTITION_TYPE partition; - BLOCK_SIZE subsize; - - if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - - subsize = (bsize >= BLOCK_8X8) ? mi[0]->sb_type : BLOCK_4X4; - partition = partition_lookup[bsl][subsize]; - - if (output_enabled && bsize != BLOCK_4X4) { - int ctx = partition_plane_context(xd, mi_row, mi_col, bsize); - td->counts->partition[ctx][partition]++; - } - - switch (partition) { - case PARTITION_NONE: - pc_tree->none.pred_pixel_ready = 1; - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, dummy_cost, - subsize, &pc_tree->none); - pc_tree->none.mic = *xd->mi[0]; - pc_tree->none.mbmi_ext = *x->mbmi_ext; - pc_tree->none.skip_txfm[0] = x->skip_txfm[0]; - pc_tree->none.skip = x->skip; - encode_b_rt(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, - subsize, &pc_tree->none); - break; - case PARTITION_VERT: - pc_tree->vertical[0].pred_pixel_ready = 1; - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, dummy_cost, - subsize, &pc_tree->vertical[0]); - pc_tree->vertical[0].mic = *xd->mi[0]; - pc_tree->vertical[0].mbmi_ext = *x->mbmi_ext; - pc_tree->vertical[0].skip_txfm[0] = x->skip_txfm[0]; - pc_tree->vertical[0].skip = x->skip; - encode_b_rt(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, - subsize, &pc_tree->vertical[0]); - if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) { - pc_tree->vertical[1].pred_pixel_ready = 1; - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs, dummy_cost, - subsize, &pc_tree->vertical[1]); - pc_tree->vertical[1].mic = *xd->mi[0]; - pc_tree->vertical[1].mbmi_ext = *x->mbmi_ext; - pc_tree->vertical[1].skip_txfm[0] = x->skip_txfm[0]; - pc_tree->vertical[1].skip = x->skip; - encode_b_rt(cpi, td, tile_info, tp, mi_row, mi_col + hbs, - output_enabled, subsize, &pc_tree->vertical[1]); - } - break; - case PARTITION_HORZ: - pc_tree->horizontal[0].pred_pixel_ready = 1; - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, dummy_cost, - subsize, &pc_tree->horizontal[0]); - pc_tree->horizontal[0].mic = *xd->mi[0]; - pc_tree->horizontal[0].mbmi_ext = *x->mbmi_ext; - pc_tree->horizontal[0].skip_txfm[0] = x->skip_txfm[0]; - pc_tree->horizontal[0].skip = x->skip; - encode_b_rt(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, - subsize, &pc_tree->horizontal[0]); - - if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) { - pc_tree->horizontal[1].pred_pixel_ready = 1; - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col, dummy_cost, - subsize, &pc_tree->horizontal[1]); - pc_tree->horizontal[1].mic = *xd->mi[0]; - pc_tree->horizontal[1].mbmi_ext = *x->mbmi_ext; - pc_tree->horizontal[1].skip_txfm[0] = x->skip_txfm[0]; - pc_tree->horizontal[1].skip = x->skip; - encode_b_rt(cpi, td, tile_info, tp, mi_row + hbs, mi_col, - output_enabled, subsize, &pc_tree->horizontal[1]); - } - break; - default: - assert(partition == PARTITION_SPLIT); - subsize = get_subsize(bsize, PARTITION_SPLIT); - if (bsize == BLOCK_8X8) { - nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, dummy_cost, - subsize, pc_tree->u.leaf_split[0]); - encode_b_rt(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, - subsize, pc_tree->u.leaf_split[0]); - } else { - nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, subsize, - output_enabled, dummy_cost, pc_tree->u.split[0]); - nonrd_use_partition(cpi, td, tile_data, mi + hbs, tp, mi_row, - mi_col + hbs, subsize, output_enabled, dummy_cost, - pc_tree->u.split[1]); - nonrd_use_partition(cpi, td, tile_data, mi + hbs * mis, tp, - mi_row + hbs, mi_col, subsize, output_enabled, - dummy_cost, pc_tree->u.split[2]); - nonrd_use_partition(cpi, td, tile_data, mi + hbs * mis + hbs, tp, - mi_row + hbs, mi_col + hbs, subsize, output_enabled, - dummy_cost, pc_tree->u.split[3]); - } - break; - } - - if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8) - update_partition_context(xd, mi_row, mi_col, subsize, bsize); -} - -// Get a prediction(stored in x->est_pred) for the whole 64x64 superblock. -static void get_estimated_pred(VP9_COMP *cpi, const TileInfo *const tile, - MACROBLOCK *x, int mi_row, int mi_col) { - VP9_COMMON *const cm = &cpi->common; - const int is_key_frame = frame_is_intra_only(cm); - MACROBLOCKD *xd = &x->e_mbd; - - set_offsets(cpi, tile, x, mi_row, mi_col, BLOCK_64X64); - - if (!is_key_frame) { - MODE_INFO *mi = xd->mi[0]; - YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME); - const YV12_BUFFER_CONFIG *yv12_g = NULL; - const BLOCK_SIZE bsize = BLOCK_32X32 + (mi_col + 4 < cm->mi_cols) * 2 + - (mi_row + 4 < cm->mi_rows); - unsigned int y_sad_g, y_sad_thr; - unsigned int y_sad = UINT_MAX; - - assert(yv12 != NULL); - - if (!(is_one_pass_svc(cpi) && cpi->svc.spatial_layer_id) || - cpi->svc.use_gf_temporal_ref_current_layer) { - // For now, GOLDEN will not be used for non-zero spatial layers, since - // it may not be a temporal reference. - yv12_g = get_ref_frame_buffer(cpi, GOLDEN_FRAME); - } - - // Only compute y_sad_g (sad for golden reference) for speed < 8. - if (cpi->oxcf.speed < 8 && yv12_g && yv12_g != yv12 && - (cpi->ref_frame_flags & VP9_GOLD_FLAG)) { - vp9_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col, - &cm->frame_refs[GOLDEN_FRAME - 1].sf); - y_sad_g = cpi->fn_ptr[bsize].sdf( - x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].pre[0].buf, - xd->plane[0].pre[0].stride); - } else { - y_sad_g = UINT_MAX; - } - - if (cpi->oxcf.lag_in_frames > 0 && cpi->oxcf.rc_mode == VPX_VBR && - cpi->rc.is_src_frame_alt_ref) { - yv12 = get_ref_frame_buffer(cpi, ALTREF_FRAME); - vp9_setup_pre_planes(xd, 0, yv12, mi_row, mi_col, - &cm->frame_refs[ALTREF_FRAME - 1].sf); - mi->ref_frame[0] = ALTREF_FRAME; - y_sad_g = UINT_MAX; - } else { - vp9_setup_pre_planes(xd, 0, yv12, mi_row, mi_col, - &cm->frame_refs[LAST_FRAME - 1].sf); - mi->ref_frame[0] = LAST_FRAME; - } - mi->ref_frame[1] = NO_REF_FRAME; - mi->sb_type = BLOCK_64X64; - mi->mv[0].as_int = 0; - mi->interp_filter = BILINEAR; - - { - const MV dummy_mv = { 0, 0 }; - y_sad = vp9_int_pro_motion_estimation(cpi, x, bsize, mi_row, mi_col, - &dummy_mv); - x->sb_use_mv_part = 1; - x->sb_mvcol_part = mi->mv[0].as_mv.col; - x->sb_mvrow_part = mi->mv[0].as_mv.row; - } - - // Pick ref frame for partitioning, bias last frame when y_sad_g and y_sad - // are close if short_circuit_low_temp_var is on. - y_sad_thr = cpi->sf.short_circuit_low_temp_var ? (y_sad * 7) >> 3 : y_sad; - if (y_sad_g < y_sad_thr) { - vp9_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col, - &cm->frame_refs[GOLDEN_FRAME - 1].sf); - mi->ref_frame[0] = GOLDEN_FRAME; - mi->mv[0].as_int = 0; - } else { - x->pred_mv[LAST_FRAME] = mi->mv[0].as_mv; - } - - set_ref_ptrs(cm, xd, mi->ref_frame[0], mi->ref_frame[1]); - xd->plane[0].dst.buf = x->est_pred; - xd->plane[0].dst.stride = 64; - vp9_build_inter_predictors_sb(xd, mi_row, mi_col, BLOCK_64X64); - } else { -#if CONFIG_VP9_HIGHBITDEPTH - switch (xd->bd) { - case 8: memset(x->est_pred, 128, 64 * 64 * sizeof(x->est_pred[0])); break; - case 10: - memset(x->est_pred, 128 * 4, 64 * 64 * sizeof(x->est_pred[0])); - break; - case 12: - memset(x->est_pred, 128 * 16, 64 * 64 * sizeof(x->est_pred[0])); - break; - } -#else - memset(x->est_pred, 128, 64 * 64 * sizeof(x->est_pred[0])); -#endif // CONFIG_VP9_HIGHBITDEPTH - } -} - -static void encode_nonrd_sb_row(VP9_COMP *cpi, ThreadData *td, - TileDataEnc *tile_data, int mi_row, - TOKENEXTRA **tp) { - SPEED_FEATURES *const sf = &cpi->sf; - VP9_COMMON *const cm = &cpi->common; - TileInfo *const tile_info = &tile_data->tile_info; - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - const int mi_col_start = tile_info->mi_col_start; - const int mi_col_end = tile_info->mi_col_end; - int mi_col; - const int sb_row = mi_row >> MI_BLOCK_SIZE_LOG2; - const int num_sb_cols = - get_num_cols(tile_data->tile_info, MI_BLOCK_SIZE_LOG2); - int sb_col_in_tile; - - // Initialize the left context for the new SB row - memset(&xd->left_context, 0, sizeof(xd->left_context)); - memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context)); - - // Code each SB in the row - for (mi_col = mi_col_start, sb_col_in_tile = 0; mi_col < mi_col_end; - mi_col += MI_BLOCK_SIZE, ++sb_col_in_tile) { - const struct segmentation *const seg = &cm->seg; - RD_COST dummy_rdc; - const int idx_str = cm->mi_stride * mi_row + mi_col; - MODE_INFO **mi = cm->mi_grid_visible + idx_str; - PARTITION_SEARCH_TYPE partition_search_type = sf->partition_search_type; - BLOCK_SIZE bsize = BLOCK_64X64; - int seg_skip = 0; - int i; - - (*(cpi->row_mt_sync_read_ptr))(&tile_data->row_mt_sync, sb_row, - sb_col_in_tile); - - if (cpi->use_skin_detection) { - vp9_compute_skin_sb(cpi, BLOCK_16X16, mi_row, mi_col); - } - - x->source_variance = UINT_MAX; - for (i = 0; i < MAX_REF_FRAMES; ++i) { - x->pred_mv[i].row = INT16_MAX; - x->pred_mv[i].col = INT16_MAX; - } - vp9_rd_cost_init(&dummy_rdc); - x->color_sensitivity[0] = 0; - x->color_sensitivity[1] = 0; - x->sb_is_skin = 0; - x->skip_low_source_sad = 0; - x->lowvar_highsumdiff = 0; - x->content_state_sb = 0; - x->zero_temp_sad_source = 0; - x->sb_use_mv_part = 0; - x->sb_mvcol_part = 0; - x->sb_mvrow_part = 0; - x->sb_pickmode_part = 0; - x->arf_frame_usage = 0; - x->lastgolden_frame_usage = 0; - - if (cpi->compute_source_sad_onepass && cpi->sf.use_source_sad) { - int shift = cpi->Source->y_stride * (mi_row << 3) + (mi_col << 3); - int sb_offset2 = ((cm->mi_cols + 7) >> 3) * (mi_row >> 3) + (mi_col >> 3); - int64_t source_sad = avg_source_sad(cpi, x, shift, sb_offset2); - if (sf->adapt_partition_source_sad && - (cpi->oxcf.rc_mode == VPX_VBR && !cpi->rc.is_src_frame_alt_ref && - source_sad > sf->adapt_partition_thresh && - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame))) - partition_search_type = REFERENCE_PARTITION; - } - - if (seg->enabled) { - const uint8_t *const map = - seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map; - int segment_id = get_segment_id(cm, map, BLOCK_64X64, mi_row, mi_col); - seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP); - - if (cpi->roi.enabled && cpi->roi.skip[BACKGROUND_SEG_SKIP_ID] && - cpi->rc.frames_since_key > FRAMES_NO_SKIPPING_AFTER_KEY && - x->content_state_sb > kLowSadLowSumdiff) { - // For ROI with skip, force segment = 0 (no skip) over whole - // superblock to avoid artifacts if temporal change in source_sad is - // not 0. - int xi, yi; - const int bw = num_8x8_blocks_wide_lookup[BLOCK_64X64]; - const int bh = num_8x8_blocks_high_lookup[BLOCK_64X64]; - const int xmis = VPXMIN(cm->mi_cols - mi_col, bw); - const int ymis = VPXMIN(cm->mi_rows - mi_row, bh); - const int block_index = mi_row * cm->mi_cols + mi_col; - set_mode_info_offsets(cm, x, xd, mi_row, mi_col); - for (yi = 0; yi < ymis; yi++) - for (xi = 0; xi < xmis; xi++) { - int map_offset = block_index + yi * cm->mi_cols + xi; - cpi->segmentation_map[map_offset] = 0; - } - set_segment_index(cpi, x, mi_row, mi_col, BLOCK_64X64, 0); - seg_skip = 0; - } - if (seg_skip) { - partition_search_type = FIXED_PARTITION; - } - } - - // Set the partition type of the 64X64 block - switch (partition_search_type) { - case VAR_BASED_PARTITION: - // TODO(jingning, marpan): The mode decision and encoding process - // support both intra and inter sub8x8 block coding for RTC mode. - // Tune the thresholds accordingly to use sub8x8 block coding for - // coding performance improvement. - choose_partitioning(cpi, tile_info, x, mi_row, mi_col); - nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, - BLOCK_64X64, 1, &dummy_rdc, td->pc_root); - break; - case ML_BASED_PARTITION: - get_estimated_pred(cpi, tile_info, x, mi_row, mi_col); - x->max_partition_size = BLOCK_64X64; - x->min_partition_size = BLOCK_8X8; - x->sb_pickmode_part = 1; - nonrd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, - BLOCK_64X64, &dummy_rdc, 1, INT64_MAX, - td->pc_root); - break; - case SOURCE_VAR_BASED_PARTITION: - set_source_var_based_partition(cpi, tile_info, x, mi, mi_row, mi_col); - nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, - BLOCK_64X64, 1, &dummy_rdc, td->pc_root); - break; - case FIXED_PARTITION: - if (!seg_skip) bsize = sf->always_this_block_size; - set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize); - nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, - BLOCK_64X64, 1, &dummy_rdc, td->pc_root); - break; - default: - assert(partition_search_type == REFERENCE_PARTITION); - x->sb_pickmode_part = 1; - set_offsets(cpi, tile_info, x, mi_row, mi_col, BLOCK_64X64); - // Use nonrd_pick_partition on scene-cut for VBR mode. - // nonrd_pick_partition does not support 4x4 partition, so avoid it - // on key frame for now. - if ((cpi->oxcf.rc_mode == VPX_VBR && cpi->rc.high_source_sad && - cpi->oxcf.speed < 6 && !frame_is_intra_only(cm) && - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame))) { - // Use lower max_partition_size for low resolutions. - if (cm->width <= 352 && cm->height <= 288) - x->max_partition_size = BLOCK_32X32; - else - x->max_partition_size = BLOCK_64X64; - x->min_partition_size = BLOCK_8X8; - nonrd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, - BLOCK_64X64, &dummy_rdc, 1, INT64_MAX, - td->pc_root); - } else { - choose_partitioning(cpi, tile_info, x, mi_row, mi_col); - // TODO(marpan): Seems like nonrd_select_partition does not support - // 4x4 partition. Since 4x4 is used on key frame, use this switch - // for now. - if (frame_is_intra_only(cm)) - nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, - BLOCK_64X64, 1, &dummy_rdc, td->pc_root); - else - nonrd_select_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, - BLOCK_64X64, 1, &dummy_rdc, td->pc_root); - } - - break; - } - - // Update ref_frame usage for inter frame if this group is ARF group. - if (!cpi->rc.is_src_frame_alt_ref && !cpi->refresh_golden_frame && - !cpi->refresh_alt_ref_frame && cpi->rc.alt_ref_gf_group && - cpi->sf.use_altref_onepass) { - int sboffset = ((cm->mi_cols + 7) >> 3) * (mi_row >> 3) + (mi_col >> 3); - if (cpi->count_arf_frame_usage != NULL) - cpi->count_arf_frame_usage[sboffset] = x->arf_frame_usage; - if (cpi->count_lastgolden_frame_usage != NULL) - cpi->count_lastgolden_frame_usage[sboffset] = x->lastgolden_frame_usage; - } - - (*(cpi->row_mt_sync_write_ptr))(&tile_data->row_mt_sync, sb_row, - sb_col_in_tile, num_sb_cols); - } -} -// end RTC play code - -static INLINE uint32_t variance(const Diff *const d) { - return d->sse - (uint32_t)(((int64_t)d->sum * d->sum) >> 8); -} - -#if CONFIG_VP9_HIGHBITDEPTH -static INLINE uint32_t variance_highbd(Diff *const d) { - const int64_t var = (int64_t)d->sse - (((int64_t)d->sum * d->sum) >> 8); - return (var >= 0) ? (uint32_t)var : 0; -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static int set_var_thresh_from_histogram(VP9_COMP *cpi) { - const SPEED_FEATURES *const sf = &cpi->sf; - const VP9_COMMON *const cm = &cpi->common; - - const uint8_t *src = cpi->Source->y_buffer; - const uint8_t *last_src = cpi->Last_Source->y_buffer; - const int src_stride = cpi->Source->y_stride; - const int last_stride = cpi->Last_Source->y_stride; - - // Pick cutoff threshold - const int cutoff = (VPXMIN(cm->width, cm->height) >= 720) - ? (cm->MBs * VAR_HIST_LARGE_CUT_OFF / 100) - : (cm->MBs * VAR_HIST_SMALL_CUT_OFF / 100); - DECLARE_ALIGNED(16, int, hist[VAR_HIST_BINS]); - Diff *var16 = cpi->source_diff_var; - - int sum = 0; - int i, j; - - memset(hist, 0, VAR_HIST_BINS * sizeof(hist[0])); - - for (i = 0; i < cm->mb_rows; i++) { - for (j = 0; j < cm->mb_cols; j++) { -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - switch (cm->bit_depth) { - case VPX_BITS_8: - vpx_highbd_8_get16x16var(src, src_stride, last_src, last_stride, - &var16->sse, &var16->sum); - var16->var = variance(var16); - break; - case VPX_BITS_10: - vpx_highbd_10_get16x16var(src, src_stride, last_src, last_stride, - &var16->sse, &var16->sum); - var16->var = variance_highbd(var16); - break; - default: - assert(cm->bit_depth == VPX_BITS_12); - vpx_highbd_12_get16x16var(src, src_stride, last_src, last_stride, - &var16->sse, &var16->sum); - var16->var = variance_highbd(var16); - break; - } - } else { - vpx_get16x16var(src, src_stride, last_src, last_stride, &var16->sse, - &var16->sum); - var16->var = variance(var16); - } -#else - vpx_get16x16var(src, src_stride, last_src, last_stride, &var16->sse, - &var16->sum); - var16->var = variance(var16); -#endif // CONFIG_VP9_HIGHBITDEPTH - - if (var16->var >= VAR_HIST_MAX_BG_VAR) - hist[VAR_HIST_BINS - 1]++; - else - hist[var16->var / VAR_HIST_FACTOR]++; - - src += 16; - last_src += 16; - var16++; - } - - src = src - cm->mb_cols * 16 + 16 * src_stride; - last_src = last_src - cm->mb_cols * 16 + 16 * last_stride; - } - - cpi->source_var_thresh = 0; - - if (hist[VAR_HIST_BINS - 1] < cutoff) { - for (i = 0; i < VAR_HIST_BINS - 1; i++) { - sum += hist[i]; - - if (sum > cutoff) { - cpi->source_var_thresh = (i + 1) * VAR_HIST_FACTOR; - return 0; - } - } - } - - return sf->search_type_check_frequency; -} - -static void source_var_based_partition_search_method(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - SPEED_FEATURES *const sf = &cpi->sf; - - if (cm->frame_type == KEY_FRAME) { - // For key frame, use SEARCH_PARTITION. - sf->partition_search_type = SEARCH_PARTITION; - } else if (cm->intra_only) { - sf->partition_search_type = FIXED_PARTITION; - } else { - if (cm->last_width != cm->width || cm->last_height != cm->height) { - if (cpi->source_diff_var) vpx_free(cpi->source_diff_var); - - CHECK_MEM_ERROR(&cm->error, cpi->source_diff_var, - vpx_calloc(cm->MBs, sizeof(cpi->source_diff_var))); - } - - if (!cpi->frames_till_next_var_check) - cpi->frames_till_next_var_check = set_var_thresh_from_histogram(cpi); - - if (cpi->frames_till_next_var_check > 0) { - sf->partition_search_type = FIXED_PARTITION; - cpi->frames_till_next_var_check--; - } - } -} - -static int get_skip_encode_frame(const VP9_COMMON *cm, ThreadData *const td) { - unsigned int intra_count = 0, inter_count = 0; - int j; - - for (j = 0; j < INTRA_INTER_CONTEXTS; ++j) { - intra_count += td->counts->intra_inter[j][0]; - inter_count += td->counts->intra_inter[j][1]; - } - - return (intra_count << 2) < inter_count && cm->frame_type != KEY_FRAME && - cm->show_frame; -} - -void vp9_init_tile_data(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - const int tile_cols = 1 << cm->log2_tile_cols; - const int tile_rows = 1 << cm->log2_tile_rows; - int tile_col, tile_row; - TOKENEXTRA *pre_tok = cpi->tile_tok[0][0]; - TOKENLIST *tplist = cpi->tplist[0][0]; - int tile_tok = 0; - int tplist_count = 0; - - if (cpi->tile_data == NULL || cpi->allocated_tiles < tile_cols * tile_rows) { - if (cpi->tile_data != NULL) { - // Free the row mt memory in cpi->tile_data first. - vp9_row_mt_mem_dealloc(cpi); - vpx_free(cpi->tile_data); - } - cpi->allocated_tiles = 0; - CHECK_MEM_ERROR( - &cm->error, cpi->tile_data, - vpx_malloc(tile_cols * tile_rows * sizeof(*cpi->tile_data))); - cpi->allocated_tiles = tile_cols * tile_rows; - - for (tile_row = 0; tile_row < tile_rows; ++tile_row) - for (tile_col = 0; tile_col < tile_cols; ++tile_col) { - TileDataEnc *tile_data = - &cpi->tile_data[tile_row * tile_cols + tile_col]; - int i, j; - const MV zero_mv = { 0, 0 }; - for (i = 0; i < BLOCK_SIZES; ++i) { - for (j = 0; j < MAX_MODES; ++j) { - tile_data->thresh_freq_fact[i][j] = RD_THRESH_INIT_FACT; - tile_data->thresh_freq_fact_prev[i][j] = RD_THRESH_INIT_FACT; - tile_data->mode_map[i][j] = j; - } - } - tile_data->firstpass_top_mv = zero_mv; -#if CONFIG_MULTITHREAD - tile_data->row_base_thresh_freq_fact = NULL; -#endif - } - } - - for (tile_row = 0; tile_row < tile_rows; ++tile_row) { - for (tile_col = 0; tile_col < tile_cols; ++tile_col) { - TileDataEnc *this_tile = &cpi->tile_data[tile_row * tile_cols + tile_col]; - TileInfo *tile_info = &this_tile->tile_info; - if (cpi->sf.adaptive_rd_thresh_row_mt) { - vp9_row_mt_alloc_rd_thresh(cpi, this_tile); - } - vp9_tile_init(tile_info, cm, tile_row, tile_col); - - cpi->tile_tok[tile_row][tile_col] = pre_tok + tile_tok; - pre_tok = cpi->tile_tok[tile_row][tile_col]; - tile_tok = allocated_tokens(*tile_info); - - cpi->tplist[tile_row][tile_col] = tplist + tplist_count; - tplist = cpi->tplist[tile_row][tile_col]; - tplist_count = get_num_vert_units(*tile_info, MI_BLOCK_SIZE_LOG2); - } - } -} - -void vp9_encode_sb_row(VP9_COMP *cpi, ThreadData *td, int tile_row, - int tile_col, int mi_row) { - VP9_COMMON *const cm = &cpi->common; - const int tile_cols = 1 << cm->log2_tile_cols; - TileDataEnc *this_tile = &cpi->tile_data[tile_row * tile_cols + tile_col]; - const TileInfo *const tile_info = &this_tile->tile_info; - TOKENEXTRA *tok = NULL; - int tile_sb_row; - int tile_mb_cols = (tile_info->mi_col_end - tile_info->mi_col_start + 1) >> 1; - - tile_sb_row = mi_cols_aligned_to_sb(mi_row - tile_info->mi_row_start) >> - MI_BLOCK_SIZE_LOG2; - get_start_tok(cpi, tile_row, tile_col, mi_row, &tok); - cpi->tplist[tile_row][tile_col][tile_sb_row].start = tok; - -#if CONFIG_REALTIME_ONLY - assert(cpi->sf.use_nonrd_pick_mode); - encode_nonrd_sb_row(cpi, td, this_tile, mi_row, &tok); -#else - if (cpi->sf.use_nonrd_pick_mode) - encode_nonrd_sb_row(cpi, td, this_tile, mi_row, &tok); - else - encode_rd_sb_row(cpi, td, this_tile, mi_row, &tok); -#endif - - cpi->tplist[tile_row][tile_col][tile_sb_row].stop = tok; - cpi->tplist[tile_row][tile_col][tile_sb_row].count = - (unsigned int)(cpi->tplist[tile_row][tile_col][tile_sb_row].stop - - cpi->tplist[tile_row][tile_col][tile_sb_row].start); - assert(tok - cpi->tplist[tile_row][tile_col][tile_sb_row].start <= - get_token_alloc(MI_BLOCK_SIZE >> 1, tile_mb_cols)); - - (void)tile_mb_cols; -} - -void vp9_encode_tile(VP9_COMP *cpi, ThreadData *td, int tile_row, - int tile_col) { - VP9_COMMON *const cm = &cpi->common; - const int tile_cols = 1 << cm->log2_tile_cols; - TileDataEnc *this_tile = &cpi->tile_data[tile_row * tile_cols + tile_col]; - const TileInfo *const tile_info = &this_tile->tile_info; - const int mi_row_start = tile_info->mi_row_start; - const int mi_row_end = tile_info->mi_row_end; - int mi_row; - - for (mi_row = mi_row_start; mi_row < mi_row_end; mi_row += MI_BLOCK_SIZE) - vp9_encode_sb_row(cpi, td, tile_row, tile_col, mi_row); -} - -static void encode_tiles(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - const int tile_cols = 1 << cm->log2_tile_cols; - const int tile_rows = 1 << cm->log2_tile_rows; - int tile_col, tile_row; - - vp9_init_tile_data(cpi); - - for (tile_row = 0; tile_row < tile_rows; ++tile_row) - for (tile_col = 0; tile_col < tile_cols; ++tile_col) - vp9_encode_tile(cpi, &cpi->td, tile_row, tile_col); -} - -static int compare_kmeans_data(const void *a, const void *b) { - if (((const KMEANS_DATA *)a)->value > ((const KMEANS_DATA *)b)->value) { - return 1; - } else if (((const KMEANS_DATA *)a)->value < - ((const KMEANS_DATA *)b)->value) { - return -1; - } else { - return 0; - } -} - -static void compute_boundary_ls(const double *ctr_ls, int k, - double *boundary_ls) { - // boundary_ls[j] is the upper bound of data centered at ctr_ls[j] - int j; - for (j = 0; j < k - 1; ++j) { - boundary_ls[j] = (ctr_ls[j] + ctr_ls[j + 1]) / 2.; - } - boundary_ls[k - 1] = DBL_MAX; -} - -int vp9_get_group_idx(double value, double *boundary_ls, int k) { - int group_idx = 0; - while (value >= boundary_ls[group_idx]) { - ++group_idx; - if (group_idx == k - 1) { - break; - } - } - return group_idx; -} - -void vp9_kmeans(double *ctr_ls, double *boundary_ls, int *count_ls, int k, - KMEANS_DATA *arr, int size) { - int i, j; - int itr; - int group_idx; - double sum[MAX_KMEANS_GROUPS]; - int count[MAX_KMEANS_GROUPS]; - - vpx_clear_system_state(); - - assert(k >= 2 && k <= MAX_KMEANS_GROUPS); - - qsort(arr, size, sizeof(*arr), compare_kmeans_data); - - // initialize the center points - for (j = 0; j < k; ++j) { - ctr_ls[j] = arr[(size * (2 * j + 1)) / (2 * k)].value; - } - - for (itr = 0; itr < 10; ++itr) { - compute_boundary_ls(ctr_ls, k, boundary_ls); - for (i = 0; i < MAX_KMEANS_GROUPS; ++i) { - sum[i] = 0; - count[i] = 0; - } - - // Both the data and centers are sorted in ascending order. - // As each data point is processed in order, its corresponding group index - // can only increase. So we only need to reset the group index to zero here. - group_idx = 0; - for (i = 0; i < size; ++i) { - while (arr[i].value >= boundary_ls[group_idx]) { - // place samples into clusters - ++group_idx; - if (group_idx == k - 1) { - break; - } - } - sum[group_idx] += arr[i].value; - ++count[group_idx]; - } - - for (group_idx = 0; group_idx < k; ++group_idx) { - if (count[group_idx] > 0) - ctr_ls[group_idx] = sum[group_idx] / count[group_idx]; - - sum[group_idx] = 0; - count[group_idx] = 0; - } - } - - // compute group_idx, boundary_ls and count_ls - for (j = 0; j < k; ++j) { - count_ls[j] = 0; - } - compute_boundary_ls(ctr_ls, k, boundary_ls); - group_idx = 0; - for (i = 0; i < size; ++i) { - while (arr[i].value >= boundary_ls[group_idx]) { - ++group_idx; - if (group_idx == k - 1) { - break; - } - } - arr[i].group_idx = group_idx; - ++count_ls[group_idx]; - } -} - -static void encode_frame_internal(VP9_COMP *cpi) { - SPEED_FEATURES *const sf = &cpi->sf; - ThreadData *const td = &cpi->td; - MACROBLOCK *const x = &td->mb; - VP9_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &x->e_mbd; - const int gf_group_index = cpi->twopass.gf_group.index; - - xd->mi = cm->mi_grid_visible; - xd->mi[0] = cm->mi; - vp9_zero(*td->counts); - vp9_zero(cpi->td.rd_counts); - - xd->lossless = cm->base_qindex == 0 && cm->y_dc_delta_q == 0 && - cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0; - -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) - x->fwd_txfm4x4 = xd->lossless ? vp9_highbd_fwht4x4 : vpx_highbd_fdct4x4; - else - x->fwd_txfm4x4 = xd->lossless ? vp9_fwht4x4 : vpx_fdct4x4; - x->highbd_inv_txfm_add = - xd->lossless ? vp9_highbd_iwht4x4_add : vp9_highbd_idct4x4_add; -#else - x->fwd_txfm4x4 = xd->lossless ? vp9_fwht4x4 : vpx_fdct4x4; -#endif // CONFIG_VP9_HIGHBITDEPTH - x->inv_txfm_add = xd->lossless ? vp9_iwht4x4_add : vp9_idct4x4_add; - x->optimize = sf->optimize_coefficients == 1 && cpi->oxcf.pass != 1; - if (xd->lossless) x->optimize = 0; - x->sharpness = cpi->oxcf.sharpness; - x->adjust_rdmult_by_segment = (cpi->oxcf.aq_mode == VARIANCE_AQ); - - cm->tx_mode = select_tx_mode(cpi, xd); - - vp9_frame_init_quantizer(cpi); - - vp9_initialize_rd_consts(cpi); - vp9_initialize_me_consts(cpi, x, cm->base_qindex); - init_encode_frame_mb_context(cpi); - cm->use_prev_frame_mvs = - !cm->error_resilient_mode && cm->width == cm->last_width && - cm->height == cm->last_height && !cm->intra_only && cm->last_show_frame; - // Special case: set prev_mi to NULL when the previous mode info - // context cannot be used. - cm->prev_mi = - cm->use_prev_frame_mvs ? cm->prev_mip + cm->mi_stride + 1 : NULL; - - x->quant_fp = cpi->sf.use_quant_fp; - vp9_zero(x->skip_txfm); - if (sf->use_nonrd_pick_mode) { - // Initialize internal buffer pointers for rtc coding, where non-RD - // mode decision is used and hence no buffer pointer swap needed. - int i; - struct macroblock_plane *const p = x->plane; - struct macroblockd_plane *const pd = xd->plane; - PICK_MODE_CONTEXT *ctx = &cpi->td.pc_root->none; - - for (i = 0; i < MAX_MB_PLANE; ++i) { - p[i].coeff = ctx->coeff_pbuf[i][0]; - p[i].qcoeff = ctx->qcoeff_pbuf[i][0]; - pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][0]; - p[i].eobs = ctx->eobs_pbuf[i][0]; - } - vp9_zero(x->zcoeff_blk); - - if (cm->frame_type != KEY_FRAME && cpi->rc.frames_since_golden == 0 && - !(cpi->oxcf.lag_in_frames > 0 && cpi->oxcf.rc_mode == VPX_VBR) && - !cpi->use_svc) - cpi->ref_frame_flags &= (~VP9_GOLD_FLAG); - - if (sf->partition_search_type == SOURCE_VAR_BASED_PARTITION) - source_var_based_partition_search_method(cpi); - } else if (gf_group_index && gf_group_index < MAX_ARF_GOP_SIZE && - cpi->sf.enable_tpl_model) { - TplDepFrame *tpl_frame = &cpi->tpl_stats[cpi->twopass.gf_group.index]; - TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr; - - int tpl_stride = tpl_frame->stride; - int64_t intra_cost_base = 0; - int64_t mc_dep_cost_base = 0; - int row, col; - - for (row = 0; row < cm->mi_rows && tpl_frame->is_valid; ++row) { - for (col = 0; col < cm->mi_cols; ++col) { - TplDepStats *this_stats = &tpl_stats[row * tpl_stride + col]; - intra_cost_base += this_stats->intra_cost; - mc_dep_cost_base += this_stats->mc_dep_cost; - } - } - - vpx_clear_system_state(); - - if (tpl_frame->is_valid) - cpi->rd.r0 = (double)intra_cost_base / mc_dep_cost_base; - } - - for (MV_REFERENCE_FRAME ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; - ++ref_frame) { - if (cpi->ref_frame_flags & ref_frame_to_flag(ref_frame)) { - if (cm->frame_refs[ref_frame - 1].sf.x_scale_fp == REF_INVALID_SCALE || - cm->frame_refs[ref_frame - 1].sf.y_scale_fp == REF_INVALID_SCALE) - cpi->ref_frame_flags &= ~ref_frame_to_flag(ref_frame); - } - } - - // Frame segmentation - if (cpi->oxcf.aq_mode == PERCEPTUAL_AQ) build_kmeans_segmentation(cpi); - - { - struct vpx_usec_timer emr_timer; - vpx_usec_timer_start(&emr_timer); - - if (!cpi->row_mt) { - cpi->row_mt_sync_read_ptr = vp9_row_mt_sync_read_dummy; - cpi->row_mt_sync_write_ptr = vp9_row_mt_sync_write_dummy; - // If allowed, encoding tiles in parallel with one thread handling one - // tile when row based multi-threading is disabled. - if (VPXMIN(cpi->oxcf.max_threads, 1 << cm->log2_tile_cols) > 1) - vp9_encode_tiles_mt(cpi); - else - encode_tiles(cpi); - } else { - cpi->row_mt_sync_read_ptr = vp9_row_mt_sync_read; - cpi->row_mt_sync_write_ptr = vp9_row_mt_sync_write; - vp9_encode_tiles_row_mt(cpi); - } - - vpx_usec_timer_mark(&emr_timer); - cpi->time_encode_sb_row += vpx_usec_timer_elapsed(&emr_timer); - } - - sf->skip_encode_frame = - sf->skip_encode_sb ? get_skip_encode_frame(cm, td) : 0; - -#if 0 - // Keep record of the total distortion this time around for future use - cpi->last_frame_distortion = cpi->frame_distortion; -#endif -} - -static INTERP_FILTER get_interp_filter( - const int64_t threshes[SWITCHABLE_FILTER_CONTEXTS], int is_alt_ref) { - if (!is_alt_ref && threshes[EIGHTTAP_SMOOTH] > threshes[EIGHTTAP] && - threshes[EIGHTTAP_SMOOTH] > threshes[EIGHTTAP_SHARP] && - threshes[EIGHTTAP_SMOOTH] > threshes[SWITCHABLE - 1]) { - return EIGHTTAP_SMOOTH; - } else if (threshes[EIGHTTAP_SHARP] > threshes[EIGHTTAP] && - threshes[EIGHTTAP_SHARP] > threshes[SWITCHABLE - 1]) { - return EIGHTTAP_SHARP; - } else if (threshes[EIGHTTAP] > threshes[SWITCHABLE - 1]) { - return EIGHTTAP; - } else { - return SWITCHABLE; - } -} - -static int compute_frame_aq_offset(struct VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - MODE_INFO **mi_8x8_ptr = cm->mi_grid_visible; - struct segmentation *const seg = &cm->seg; - - int mi_row, mi_col; - int sum_delta = 0; - int qdelta_index; - int segment_id; - - for (mi_row = 0; mi_row < cm->mi_rows; mi_row++) { - MODE_INFO **mi_8x8 = mi_8x8_ptr; - for (mi_col = 0; mi_col < cm->mi_cols; mi_col++, mi_8x8++) { - segment_id = mi_8x8[0]->segment_id; - qdelta_index = get_segdata(seg, segment_id, SEG_LVL_ALT_Q); - sum_delta += qdelta_index; - } - mi_8x8_ptr += cm->mi_stride; - } - - return sum_delta / (cm->mi_rows * cm->mi_cols); -} - -static void restore_encode_params(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - int tile_idx; - int i, j; - TileDataEnc *tile_data; - RD_OPT *rd_opt = &cpi->rd; - for (i = 0; i < MAX_REF_FRAMES; i++) { - for (j = 0; j < REFERENCE_MODES; j++) - rd_opt->prediction_type_threshes[i][j] = - rd_opt->prediction_type_threshes_prev[i][j]; - - for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; j++) - rd_opt->filter_threshes[i][j] = rd_opt->filter_threshes_prev[i][j]; - } - - for (tile_idx = 0; tile_idx < cpi->allocated_tiles; tile_idx++) { - assert(cpi->tile_data); - tile_data = &cpi->tile_data[tile_idx]; - vp9_copy(tile_data->thresh_freq_fact, tile_data->thresh_freq_fact_prev); - } - - cm->interp_filter = cpi->sf.default_interp_filter; -} - -void vp9_encode_frame(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - - restore_encode_params(cpi); - -#if CONFIG_MISMATCH_DEBUG - mismatch_reset_frame(MAX_MB_PLANE); -#endif - - // In the longer term the encoder should be generalized to match the - // decoder such that we allow compound where one of the 3 buffers has a - // different sign bias and that buffer is then the fixed ref. However, this - // requires further work in the rd loop. For now the only supported encoder - // side behavior is where the ALT ref buffer has opposite sign bias to - // the other two. - if (!frame_is_intra_only(cm)) { - if (vp9_compound_reference_allowed(cm)) { - cpi->allow_comp_inter_inter = 1; - vp9_setup_compound_reference_mode(cm); - } else { - cpi->allow_comp_inter_inter = 0; - } - } - - if (cpi->sf.frame_parameter_update) { - int i; - RD_OPT *const rd_opt = &cpi->rd; - FRAME_COUNTS *counts = cpi->td.counts; - RD_COUNTS *const rdc = &cpi->td.rd_counts; - - // This code does a single RD pass over the whole frame assuming - // either compound, single or hybrid prediction as per whatever has - // worked best for that type of frame in the past. - // It also predicts whether another coding mode would have worked - // better than this coding mode. If that is the case, it remembers - // that for subsequent frames. - // It also does the same analysis for transform size selection. - const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi); - int64_t *const mode_thrs = rd_opt->prediction_type_threshes[frame_type]; - int64_t *const filter_thrs = rd_opt->filter_threshes[frame_type]; - const int is_alt_ref = frame_type == ALTREF_FRAME; - - /* prediction (compound, single or hybrid) mode selection */ - if (is_alt_ref || !cpi->allow_comp_inter_inter) - cm->reference_mode = SINGLE_REFERENCE; - else if (mode_thrs[COMPOUND_REFERENCE] > mode_thrs[SINGLE_REFERENCE] && - mode_thrs[COMPOUND_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT] && - check_dual_ref_flags(cpi) && cpi->static_mb_pct == 100) - cm->reference_mode = COMPOUND_REFERENCE; - else if (mode_thrs[SINGLE_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT]) - cm->reference_mode = SINGLE_REFERENCE; - else - cm->reference_mode = REFERENCE_MODE_SELECT; - - if (cm->interp_filter == SWITCHABLE) - cm->interp_filter = get_interp_filter(filter_thrs, is_alt_ref); - -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, encode_frame_internal_time); -#endif - encode_frame_internal(cpi); -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, encode_frame_internal_time); -#endif - - for (i = 0; i < REFERENCE_MODES; ++i) - mode_thrs[i] = (mode_thrs[i] + rdc->comp_pred_diff[i] / cm->MBs) / 2; - - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) - filter_thrs[i] = (filter_thrs[i] + rdc->filter_diff[i] / cm->MBs) / 2; - - if (cm->reference_mode == REFERENCE_MODE_SELECT) { - int single_count_zero = 0; - int comp_count_zero = 0; - - for (i = 0; i < COMP_INTER_CONTEXTS; i++) { - single_count_zero += counts->comp_inter[i][0]; - comp_count_zero += counts->comp_inter[i][1]; - } - - if (comp_count_zero == 0) { - cm->reference_mode = SINGLE_REFERENCE; - vp9_zero(counts->comp_inter); - } else if (single_count_zero == 0) { - cm->reference_mode = COMPOUND_REFERENCE; - vp9_zero(counts->comp_inter); - } - } - - if (cm->tx_mode == TX_MODE_SELECT) { - int count4x4 = 0; - int count8x8_lp = 0, count8x8_8x8p = 0; - int count16x16_16x16p = 0, count16x16_lp = 0; - int count32x32 = 0; - - for (i = 0; i < TX_SIZE_CONTEXTS; ++i) { - count4x4 += counts->tx.p32x32[i][TX_4X4]; - count4x4 += counts->tx.p16x16[i][TX_4X4]; - count4x4 += counts->tx.p8x8[i][TX_4X4]; - - count8x8_lp += counts->tx.p32x32[i][TX_8X8]; - count8x8_lp += counts->tx.p16x16[i][TX_8X8]; - count8x8_8x8p += counts->tx.p8x8[i][TX_8X8]; - - count16x16_16x16p += counts->tx.p16x16[i][TX_16X16]; - count16x16_lp += counts->tx.p32x32[i][TX_16X16]; - count32x32 += counts->tx.p32x32[i][TX_32X32]; - } - if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 && - count32x32 == 0) { - cm->tx_mode = ALLOW_8X8; - reset_skip_tx_size(cm, TX_8X8); - } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 && - count8x8_lp == 0 && count16x16_lp == 0 && count32x32 == 0) { - cm->tx_mode = ONLY_4X4; - reset_skip_tx_size(cm, TX_4X4); - } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) { - cm->tx_mode = ALLOW_32X32; - } else if (count32x32 == 0 && count8x8_lp == 0 && count4x4 == 0) { - cm->tx_mode = ALLOW_16X16; - reset_skip_tx_size(cm, TX_16X16); - } - } - } else { - FRAME_COUNTS *counts = cpi->td.counts; - cm->reference_mode = SINGLE_REFERENCE; - if (cpi->allow_comp_inter_inter && cpi->sf.use_compound_nonrd_pickmode && - cpi->rc.alt_ref_gf_group && !cpi->rc.is_src_frame_alt_ref && - cm->frame_type != KEY_FRAME) - cm->reference_mode = REFERENCE_MODE_SELECT; - - encode_frame_internal(cpi); - - if (cm->reference_mode == REFERENCE_MODE_SELECT) { - int single_count_zero = 0; - int comp_count_zero = 0; - int i; - for (i = 0; i < COMP_INTER_CONTEXTS; i++) { - single_count_zero += counts->comp_inter[i][0]; - comp_count_zero += counts->comp_inter[i][1]; - } - if (comp_count_zero == 0) { - cm->reference_mode = SINGLE_REFERENCE; - vp9_zero(counts->comp_inter); - } else if (single_count_zero == 0) { - cm->reference_mode = COMPOUND_REFERENCE; - vp9_zero(counts->comp_inter); - } - } - } - - // If segmented AQ is enabled compute the average AQ weighting. - if (cm->seg.enabled && (cpi->oxcf.aq_mode != NO_AQ) && - (cm->seg.update_map || cm->seg.update_data)) { - cm->seg.aq_av_offset = compute_frame_aq_offset(cpi); - } -} - -static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi) { - const PREDICTION_MODE y_mode = mi->mode; - const PREDICTION_MODE uv_mode = mi->uv_mode; - const BLOCK_SIZE bsize = mi->sb_type; - - if (bsize < BLOCK_8X8) { - int idx, idy; - const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; - const int num_4x4_h = num_4x4_blocks_high_lookup[bsize]; - for (idy = 0; idy < 2; idy += num_4x4_h) - for (idx = 0; idx < 2; idx += num_4x4_w) - ++counts->y_mode[0][mi->bmi[idy * 2 + idx].as_mode]; - } else { - ++counts->y_mode[size_group_lookup[bsize]][y_mode]; - } - - ++counts->uv_mode[y_mode][uv_mode]; -} - -static void update_zeromv_cnt(VP9_COMP *const cpi, const MODE_INFO *const mi, - int mi_row, int mi_col, BLOCK_SIZE bsize) { - const VP9_COMMON *const cm = &cpi->common; - MV mv = mi->mv[0].as_mv; - const int bw = num_8x8_blocks_wide_lookup[bsize]; - const int bh = num_8x8_blocks_high_lookup[bsize]; - const int xmis = VPXMIN(cm->mi_cols - mi_col, bw); - const int ymis = VPXMIN(cm->mi_rows - mi_row, bh); - const int block_index = mi_row * cm->mi_cols + mi_col; - int x, y; - for (y = 0; y < ymis; y++) - for (x = 0; x < xmis; x++) { - int map_offset = block_index + y * cm->mi_cols + x; - if (mi->ref_frame[0] == LAST_FRAME && is_inter_block(mi) && - mi->segment_id <= CR_SEGMENT_ID_BOOST2) { - if (abs(mv.row) < 8 && abs(mv.col) < 8) { - if (cpi->consec_zero_mv[map_offset] < 255) - cpi->consec_zero_mv[map_offset]++; - } else { - cpi->consec_zero_mv[map_offset] = 0; - } - } - } -} - -static void encode_superblock(VP9_COMP *cpi, ThreadData *td, TOKENEXTRA **t, - int output_enabled, int mi_row, int mi_col, - BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx) { - VP9_COMMON *const cm = &cpi->common; - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *mi = xd->mi[0]; - const int seg_skip = - segfeature_active(&cm->seg, mi->segment_id, SEG_LVL_SKIP); - x->skip_recode = !x->select_tx_size && mi->sb_type >= BLOCK_8X8 && - cpi->oxcf.aq_mode != COMPLEXITY_AQ && - cpi->oxcf.aq_mode != CYCLIC_REFRESH_AQ && - cpi->sf.allow_skip_recode; - - if (!x->skip_recode && !cpi->sf.use_nonrd_pick_mode) - memset(x->skip_txfm, 0, sizeof(x->skip_txfm)); - - x->skip_optimize = ctx->is_coded; - ctx->is_coded = 1; - x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct; - x->skip_encode = (!output_enabled && cpi->sf.skip_encode_frame && - x->q_index < QIDX_SKIP_THRESH); - - if (x->skip_encode) return; - - if (!is_inter_block(mi)) { - int plane; -#if CONFIG_BETTER_HW_COMPATIBILITY && CONFIG_VP9_HIGHBITDEPTH - if ((xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) && - (xd->above_mi == NULL || xd->left_mi == NULL) && - need_top_left[mi->uv_mode]) - assert(0); -#endif // CONFIG_BETTER_HW_COMPATIBILITY && CONFIG_VP9_HIGHBITDEPTH - mi->skip = 1; - for (plane = 0; plane < MAX_MB_PLANE; ++plane) - vp9_encode_intra_block_plane(x, VPXMAX(bsize, BLOCK_8X8), plane, 1); - if (output_enabled) sum_intra_stats(td->counts, mi); - vp9_tokenize_sb(cpi, td, t, !output_enabled, seg_skip, - VPXMAX(bsize, BLOCK_8X8)); - } else { - int ref; - const int is_compound = has_second_ref(mi); - set_ref_ptrs(cm, xd, mi->ref_frame[0], mi->ref_frame[1]); - for (ref = 0; ref < 1 + is_compound; ++ref) { - YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mi->ref_frame[ref]); - assert(cfg != NULL); - vp9_setup_pre_planes(xd, ref, cfg, mi_row, mi_col, - &xd->block_refs[ref]->sf); - } - if (!(cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready) || seg_skip) - vp9_build_inter_predictors_sby(xd, mi_row, mi_col, - VPXMAX(bsize, BLOCK_8X8)); - - vp9_build_inter_predictors_sbuv(xd, mi_row, mi_col, - VPXMAX(bsize, BLOCK_8X8)); - -#if CONFIG_MISMATCH_DEBUG - if (output_enabled) { - int plane; - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { - const struct macroblockd_plane *pd = &xd->plane[plane]; - int pixel_c, pixel_r; - const BLOCK_SIZE plane_bsize = - get_plane_block_size(VPXMAX(bsize, BLOCK_8X8), &xd->plane[plane]); - const int bw = get_block_width(plane_bsize); - const int bh = get_block_height(plane_bsize); - mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, 0, 0, - pd->subsampling_x, pd->subsampling_y); - - mismatch_record_block_pre(pd->dst.buf, pd->dst.stride, plane, pixel_c, - pixel_r, bw, bh, - xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH); - } - } -#endif - - vp9_encode_sb(x, VPXMAX(bsize, BLOCK_8X8), mi_row, mi_col, output_enabled); - vp9_tokenize_sb(cpi, td, t, !output_enabled, seg_skip, - VPXMAX(bsize, BLOCK_8X8)); - } - - if (seg_skip) { - assert(mi->skip); - } - - if (output_enabled) { - if (cm->tx_mode == TX_MODE_SELECT && mi->sb_type >= BLOCK_8X8 && - !(is_inter_block(mi) && mi->skip)) { - ++get_tx_counts(max_txsize_lookup[bsize], get_tx_size_context(xd), - &td->counts->tx)[mi->tx_size]; - } else { - // The new intra coding scheme requires no change of transform size - if (is_inter_block(mi)) { - mi->tx_size = VPXMIN(tx_mode_to_biggest_tx_size[cm->tx_mode], - max_txsize_lookup[bsize]); - } else { - mi->tx_size = (bsize >= BLOCK_8X8) ? mi->tx_size : TX_4X4; - } - } - - ++td->counts->tx.tx_totals[mi->tx_size]; - ++td->counts->tx.tx_totals[get_uv_tx_size(mi, &xd->plane[1])]; - if (cm->seg.enabled && cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && - cpi->cyclic_refresh->content_mode) - vp9_cyclic_refresh_update_sb_postencode(cpi, mi, mi_row, mi_col, bsize); - if (cpi->oxcf.pass == 0 && cpi->svc.temporal_layer_id == 0 && - (!cpi->use_svc || - (cpi->use_svc && - !cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame && - cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1))) - update_zeromv_cnt(cpi, mi, mi_row, mi_col, bsize); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodeframe.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodeframe.h deleted file mode 100644 index fd0a9c51..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodeframe.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_ENCODEFRAME_H_ -#define VPX_VP9_ENCODER_VP9_ENCODEFRAME_H_ - -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct macroblock; -struct yv12_buffer_config; -struct VP9_COMP; -struct ThreadData; - -// Constants used in SOURCE_VAR_BASED_PARTITION -#define VAR_HIST_MAX_BG_VAR 1000 -#define VAR_HIST_FACTOR 10 -#define VAR_HIST_BINS (VAR_HIST_MAX_BG_VAR / VAR_HIST_FACTOR + 1) -#define VAR_HIST_LARGE_CUT_OFF 75 -#define VAR_HIST_SMALL_CUT_OFF 45 - -void vp9_setup_src_planes(struct macroblock *x, - const struct yv12_buffer_config *src, int mi_row, - int mi_col); - -void vp9_encode_frame(struct VP9_COMP *cpi); - -void vp9_init_tile_data(struct VP9_COMP *cpi); -void vp9_encode_tile(struct VP9_COMP *cpi, struct ThreadData *td, int tile_row, - int tile_col); - -void vp9_encode_sb_row(struct VP9_COMP *cpi, struct ThreadData *td, - int tile_row, int tile_col, int mi_row); - -void vp9_set_variance_partition_thresholds(struct VP9_COMP *cpi, int q, - int content_state); - -struct KMEANS_DATA; -void vp9_kmeans(double *ctr_ls, double *boundary_ls, int *count_ls, int k, - struct KMEANS_DATA *arr, int size); -int vp9_get_group_idx(double value, double *boundary_ls, int k); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_ENCODEFRAME_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodemb.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodemb.c deleted file mode 100644 index eded9f5c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodemb.c +++ /dev/null @@ -1,1061 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx_dsp/quantize.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" - -#if CONFIG_MISMATCH_DEBUG -#include "vpx_util/vpx_debug_util.h" -#endif - -#include "vp9/common/vp9_idct.h" -#include "vp9/common/vp9_reconinter.h" -#include "vp9/common/vp9_reconintra.h" -#include "vp9/common/vp9_scan.h" - -#include "vp9/encoder/vp9_encodemb.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_rd.h" -#include "vp9/encoder/vp9_tokenize.h" - -struct optimize_ctx { - ENTROPY_CONTEXT ta[MAX_MB_PLANE][16]; - ENTROPY_CONTEXT tl[MAX_MB_PLANE][16]; -}; - -void vp9_subtract_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) { - struct macroblock_plane *const p = &x->plane[plane]; - const struct macroblockd_plane *const pd = &x->e_mbd.plane[plane]; - const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd); - const int bw = 4 * num_4x4_blocks_wide_lookup[plane_bsize]; - const int bh = 4 * num_4x4_blocks_high_lookup[plane_bsize]; - -#if CONFIG_VP9_HIGHBITDEPTH - if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - vpx_highbd_subtract_block(bh, bw, p->src_diff, bw, p->src.buf, - p->src.stride, pd->dst.buf, pd->dst.stride, - x->e_mbd.bd); - return; - } -#endif // CONFIG_VP9_HIGHBITDEPTH - vpx_subtract_block(bh, bw, p->src_diff, bw, p->src.buf, p->src.stride, - pd->dst.buf, pd->dst.stride); -} - -static const int plane_rd_mult[REF_TYPES][PLANE_TYPES] = { - { 10, 6 }, - { 8, 5 }, -}; - -// 'num' can be negative, but 'shift' must be non-negative. -#define RIGHT_SHIFT_POSSIBLY_NEGATIVE(num, shift) \ - (((num) >= 0) ? (num) >> (shift) : -((-(num)) >> (shift))) - -int vp9_optimize_b(MACROBLOCK *mb, int plane, int block, TX_SIZE tx_size, - int ctx) { - MACROBLOCKD *const xd = &mb->e_mbd; - struct macroblock_plane *const p = &mb->plane[plane]; - struct macroblockd_plane *const pd = &xd->plane[plane]; - const int ref = is_inter_block(xd->mi[0]); - uint8_t token_cache[1024]; - const tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block); - tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block); - tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); - const int eob = p->eobs[block]; - const PLANE_TYPE plane_type = get_plane_type(plane); - const int default_eob = 16 << (tx_size << 1); - const int shift = (tx_size == TX_32X32); - const int16_t *const dequant_ptr = pd->dequant; - const uint8_t *const band_translate = get_band_translate(tx_size); - const ScanOrder *const so = get_scan(xd, tx_size, plane_type, block); - const int16_t *const scan = so->scan; - const int16_t *const nb = so->neighbors; - const MODE_INFO *mbmi = xd->mi[0]; - const int sharpness = mb->sharpness; - const int64_t rdadj = (int64_t)mb->rdmult * plane_rd_mult[ref][plane_type]; - const int64_t rdmult = - (sharpness == 0 ? rdadj >> 1 - : (rdadj * (8 - sharpness + mbmi->segment_id)) >> 4); - - const int64_t rddiv = mb->rddiv; - int64_t rd_cost0, rd_cost1; - int64_t rate0, rate1; - int16_t t0, t1; - int i, final_eob; - int count_high_values_after_eob = 0; -#if CONFIG_VP9_HIGHBITDEPTH - const uint16_t *cat6_high_cost = vp9_get_high_cost_table(xd->bd); -#else - const uint16_t *cat6_high_cost = vp9_get_high_cost_table(8); -#endif - unsigned int(*const token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] = - mb->token_costs[tx_size][plane_type][ref]; - unsigned int(*token_costs_cur)[2][COEFF_CONTEXTS][ENTROPY_TOKENS]; - int64_t eob_cost0, eob_cost1; - const int ctx0 = ctx; - int64_t accu_rate = 0; - // Initialized to the worst possible error for the largest transform size. - // This ensures that it never goes negative. - int64_t accu_error = ((int64_t)1) << 50; - int64_t best_block_rd_cost = INT64_MAX; - int x_prev = 1; - tran_low_t before_best_eob_qc = 0; - tran_low_t before_best_eob_dqc = 0; - - assert((!plane_type && !plane) || (plane_type && plane)); - assert(eob <= default_eob); - - for (i = 0; i < eob; i++) { - const int rc = scan[i]; - token_cache[rc] = vp9_pt_energy_class[vp9_get_token(qcoeff[rc])]; - } - final_eob = 0; - - // Initial RD cost. - token_costs_cur = token_costs + band_translate[0]; - rate0 = (*token_costs_cur)[0][ctx0][EOB_TOKEN]; - best_block_rd_cost = RDCOST(rdmult, rddiv, rate0, accu_error); - - // For each token, pick one of two choices greedily: - // (i) First candidate: Keep current quantized value, OR - // (ii) Second candidate: Reduce quantized value by 1. - for (i = 0; i < eob; i++) { - const int rc = scan[i]; - const int x = qcoeff[rc]; - const int band_cur = band_translate[i]; - const int ctx_cur = (i == 0) ? ctx : get_coef_context(nb, token_cache, i); - const int token_tree_sel_cur = (x_prev == 0); - token_costs_cur = token_costs + band_cur; - if (x == 0) { // No need to search - const int token = vp9_get_token(x); - rate0 = (*token_costs_cur)[token_tree_sel_cur][ctx_cur][token]; - accu_rate += rate0; - x_prev = 0; - // Note: accu_error does not change. - } else { - const int dqv = dequant_ptr[rc != 0]; - // Compute the distortion for quantizing to 0. - const int diff_for_zero_raw = (0 - coeff[rc]) * (1 << shift); - const int diff_for_zero = -#if CONFIG_VP9_HIGHBITDEPTH - (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) - ? RIGHT_SHIFT_POSSIBLY_NEGATIVE(diff_for_zero_raw, xd->bd - 8) - : -#endif - diff_for_zero_raw; - const int64_t distortion_for_zero = - (int64_t)diff_for_zero * diff_for_zero; - - // Compute the distortion for the first candidate - const int diff0_raw = (dqcoeff[rc] - coeff[rc]) * (1 << shift); - const int diff0 = -#if CONFIG_VP9_HIGHBITDEPTH - (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) - ? RIGHT_SHIFT_POSSIBLY_NEGATIVE(diff0_raw, xd->bd - 8) - : -#endif // CONFIG_VP9_HIGHBITDEPTH - diff0_raw; - const int64_t distortion0 = (int64_t)diff0 * diff0; - - // Compute the distortion for the second candidate - const int sign = -(x < 0); // -1 if x is negative and 0 otherwise. - const int x1 = x - 2 * sign - 1; // abs(x1) = abs(x) - 1. - int64_t distortion1; - if (x1 != 0) { - const int dqv_step = -#if CONFIG_VP9_HIGHBITDEPTH - (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? dqv >> (xd->bd - 8) - : -#endif // CONFIG_VP9_HIGHBITDEPTH - dqv; - const int diff_step = (dqv_step + sign) ^ sign; - const int diff1 = diff0 - diff_step; - assert(dqv > 0); // We aren't right shifting a negative number above. - distortion1 = (int64_t)diff1 * diff1; - } else { - distortion1 = distortion_for_zero; - } - { - // Calculate RDCost for current coeff for the two candidates. - const int64_t base_bits0 = vp9_get_token_cost(x, &t0, cat6_high_cost); - const int64_t base_bits1 = vp9_get_token_cost(x1, &t1, cat6_high_cost); - rate0 = - base_bits0 + (*token_costs_cur)[token_tree_sel_cur][ctx_cur][t0]; - rate1 = - base_bits1 + (*token_costs_cur)[token_tree_sel_cur][ctx_cur][t1]; - } - { - int rdcost_better_for_x1, eob_rdcost_better_for_x1; - int dqc0, dqc1; - int64_t best_eob_cost_cur; - int use_x1; - - // Calculate RD Cost effect on the next coeff for the two candidates. - int64_t next_bits0 = 0; - int64_t next_bits1 = 0; - int64_t next_eob_bits0 = 0; - int64_t next_eob_bits1 = 0; - if (i < default_eob - 1) { - int ctx_next, token_tree_sel_next; - const int band_next = band_translate[i + 1]; - const int token_next = - (i + 1 != eob) ? vp9_get_token(qcoeff[scan[i + 1]]) : EOB_TOKEN; - unsigned int(*const token_costs_next)[2][COEFF_CONTEXTS] - [ENTROPY_TOKENS] = - token_costs + band_next; - token_cache[rc] = vp9_pt_energy_class[t0]; - ctx_next = get_coef_context(nb, token_cache, i + 1); - token_tree_sel_next = (x == 0); - next_bits0 = - (*token_costs_next)[token_tree_sel_next][ctx_next][token_next]; - next_eob_bits0 = - (*token_costs_next)[token_tree_sel_next][ctx_next][EOB_TOKEN]; - token_cache[rc] = vp9_pt_energy_class[t1]; - ctx_next = get_coef_context(nb, token_cache, i + 1); - token_tree_sel_next = (x1 == 0); - next_bits1 = - (*token_costs_next)[token_tree_sel_next][ctx_next][token_next]; - if (x1 != 0) { - next_eob_bits1 = - (*token_costs_next)[token_tree_sel_next][ctx_next][EOB_TOKEN]; - } - } - - // Compare the total RD costs for two candidates. - rd_cost0 = RDCOST(rdmult, rddiv, (rate0 + next_bits0), distortion0); - rd_cost1 = RDCOST(rdmult, rddiv, (rate1 + next_bits1), distortion1); - rdcost_better_for_x1 = (rd_cost1 < rd_cost0); - eob_cost0 = RDCOST(rdmult, rddiv, (accu_rate + rate0 + next_eob_bits0), - (accu_error + distortion0 - distortion_for_zero)); - eob_cost1 = eob_cost0; - if (x1 != 0) { - eob_cost1 = - RDCOST(rdmult, rddiv, (accu_rate + rate1 + next_eob_bits1), - (accu_error + distortion1 - distortion_for_zero)); - eob_rdcost_better_for_x1 = (eob_cost1 < eob_cost0); - } else { - eob_rdcost_better_for_x1 = 0; - } - - // Calculate the two candidate de-quantized values. - dqc0 = dqcoeff[rc]; - dqc1 = 0; - if (rdcost_better_for_x1 + eob_rdcost_better_for_x1) { - if (x1 != 0) { - dqc1 = RIGHT_SHIFT_POSSIBLY_NEGATIVE(x1 * dqv, shift); - } else { - dqc1 = 0; - } - } - - // Pick and record the better quantized and de-quantized values. - if (rdcost_better_for_x1) { - qcoeff[rc] = x1; - dqcoeff[rc] = dqc1; - accu_rate += rate1; - accu_error += distortion1 - distortion_for_zero; - assert(distortion1 <= distortion_for_zero); - token_cache[rc] = vp9_pt_energy_class[t1]; - } else { - accu_rate += rate0; - accu_error += distortion0 - distortion_for_zero; - assert(distortion0 <= distortion_for_zero); - token_cache[rc] = vp9_pt_energy_class[t0]; - } - if (sharpness > 0 && abs(qcoeff[rc]) > 1) count_high_values_after_eob++; - assert(accu_error >= 0); - x_prev = qcoeff[rc]; // Update based on selected quantized value. - - use_x1 = (x1 != 0) && eob_rdcost_better_for_x1; - best_eob_cost_cur = use_x1 ? eob_cost1 : eob_cost0; - - // Determine whether to move the eob position to i+1 - if (best_eob_cost_cur < best_block_rd_cost) { - best_block_rd_cost = best_eob_cost_cur; - final_eob = i + 1; - count_high_values_after_eob = 0; - if (use_x1) { - before_best_eob_qc = x1; - before_best_eob_dqc = dqc1; - } else { - before_best_eob_qc = x; - before_best_eob_dqc = dqc0; - } - } - } - } - } - if (count_high_values_after_eob > 0) { - final_eob = eob - 1; - for (; final_eob >= 0; final_eob--) { - const int rc = scan[final_eob]; - const int x = qcoeff[rc]; - if (x) { - break; - } - } - final_eob++; - } else { - assert(final_eob <= eob); - if (final_eob > 0) { - int rc; - assert(before_best_eob_qc != 0); - i = final_eob - 1; - rc = scan[i]; - qcoeff[rc] = before_best_eob_qc; - dqcoeff[rc] = before_best_eob_dqc; - } - for (i = final_eob; i < eob; i++) { - int rc = scan[i]; - qcoeff[rc] = 0; - dqcoeff[rc] = 0; - } - } - mb->plane[plane].eobs[block] = final_eob; - return final_eob; -} -#undef RIGHT_SHIFT_POSSIBLY_NEGATIVE - -static INLINE void fdct32x32(int rd_transform, const int16_t *src, - tran_low_t *dst, int src_stride) { - if (rd_transform) - vpx_fdct32x32_rd(src, dst, src_stride); - else - vpx_fdct32x32(src, dst, src_stride); -} - -#if CONFIG_VP9_HIGHBITDEPTH -static INLINE void highbd_fdct32x32(int rd_transform, const int16_t *src, - tran_low_t *dst, int src_stride) { - if (rd_transform) - vpx_highbd_fdct32x32_rd(src, dst, src_stride); - else - vpx_highbd_fdct32x32(src, dst, src_stride); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -void vp9_xform_quant_fp(MACROBLOCK *x, int plane, int block, int row, int col, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size) { - MACROBLOCKD *const xd = &x->e_mbd; - const struct macroblock_plane *const p = &x->plane[plane]; - const struct macroblockd_plane *const pd = &xd->plane[plane]; - const ScanOrder *const scan_order = &vp9_default_scan_orders[tx_size]; - tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block); - tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block); - tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); - uint16_t *const eob = &p->eobs[block]; - const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize]; - const int16_t *src_diff; - src_diff = &p->src_diff[4 * (row * diff_stride + col)]; - // skip block condition should be handled before this is called. - assert(!x->skip_block); - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - switch (tx_size) { - case TX_32X32: - highbd_fdct32x32(x->use_lp32x32fdct, src_diff, coeff, diff_stride); - vp9_highbd_quantize_fp_32x32(coeff, 1024, p, qcoeff, dqcoeff, - pd->dequant, eob, scan_order); - break; - case TX_16X16: - vpx_highbd_fdct16x16(src_diff, coeff, diff_stride); - vp9_highbd_quantize_fp(coeff, 256, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - break; - case TX_8X8: - vpx_highbd_fdct8x8(src_diff, coeff, diff_stride); - vp9_highbd_quantize_fp(coeff, 64, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - break; - default: - assert(tx_size == TX_4X4); - x->fwd_txfm4x4(src_diff, coeff, diff_stride); - vp9_highbd_quantize_fp(coeff, 16, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - break; - } - return; - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - switch (tx_size) { - case TX_32X32: - fdct32x32(x->use_lp32x32fdct, src_diff, coeff, diff_stride); - vp9_quantize_fp_32x32(coeff, 1024, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - break; - case TX_16X16: - vpx_fdct16x16(src_diff, coeff, diff_stride); - vp9_quantize_fp(coeff, 256, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - break; - case TX_8X8: - vpx_fdct8x8(src_diff, coeff, diff_stride); - vp9_quantize_fp(coeff, 64, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - - break; - default: - assert(tx_size == TX_4X4); - x->fwd_txfm4x4(src_diff, coeff, diff_stride); - vp9_quantize_fp(coeff, 16, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - break; - } -} - -void vp9_xform_quant_dc(MACROBLOCK *x, int plane, int block, int row, int col, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size) { - MACROBLOCKD *const xd = &x->e_mbd; - const struct macroblock_plane *const p = &x->plane[plane]; - const struct macroblockd_plane *const pd = &xd->plane[plane]; - tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block); - tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block); - tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); - uint16_t *const eob = &p->eobs[block]; - const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize]; - const int16_t *src_diff; - src_diff = &p->src_diff[4 * (row * diff_stride + col)]; - // skip block condition should be handled before this is called. - assert(!x->skip_block); - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - switch (tx_size) { - case TX_32X32: - vpx_highbd_fdct32x32_1(src_diff, coeff, diff_stride); - vpx_highbd_quantize_dc_32x32(coeff, p->round, p->quant_fp[0], qcoeff, - dqcoeff, pd->dequant[0], eob); - break; - case TX_16X16: - vpx_highbd_fdct16x16_1(src_diff, coeff, diff_stride); - vpx_highbd_quantize_dc(coeff, 256, p->round, p->quant_fp[0], qcoeff, - dqcoeff, pd->dequant[0], eob); - break; - case TX_8X8: - vpx_highbd_fdct8x8_1(src_diff, coeff, diff_stride); - vpx_highbd_quantize_dc(coeff, 64, p->round, p->quant_fp[0], qcoeff, - dqcoeff, pd->dequant[0], eob); - break; - default: - assert(tx_size == TX_4X4); - x->fwd_txfm4x4(src_diff, coeff, diff_stride); - vpx_highbd_quantize_dc(coeff, 16, p->round, p->quant_fp[0], qcoeff, - dqcoeff, pd->dequant[0], eob); - break; - } - return; - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - switch (tx_size) { - case TX_32X32: - vpx_fdct32x32_1(src_diff, coeff, diff_stride); - vpx_quantize_dc_32x32(coeff, p->round, p->quant_fp[0], qcoeff, dqcoeff, - pd->dequant[0], eob); - break; - case TX_16X16: - vpx_fdct16x16_1(src_diff, coeff, diff_stride); - vpx_quantize_dc(coeff, 256, p->round, p->quant_fp[0], qcoeff, dqcoeff, - pd->dequant[0], eob); - break; - case TX_8X8: - vpx_fdct8x8_1(src_diff, coeff, diff_stride); - vpx_quantize_dc(coeff, 64, p->round, p->quant_fp[0], qcoeff, dqcoeff, - pd->dequant[0], eob); - break; - default: - assert(tx_size == TX_4X4); - x->fwd_txfm4x4(src_diff, coeff, diff_stride); - vpx_quantize_dc(coeff, 16, p->round, p->quant_fp[0], qcoeff, dqcoeff, - pd->dequant[0], eob); - break; - } -} - -void vp9_xform_quant(MACROBLOCK *x, int plane, int block, int row, int col, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size) { - MACROBLOCKD *const xd = &x->e_mbd; - const struct macroblock_plane *const p = &x->plane[plane]; - const struct macroblockd_plane *const pd = &xd->plane[plane]; - const ScanOrder *const scan_order = &vp9_default_scan_orders[tx_size]; - tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block); - tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block); - tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); - uint16_t *const eob = &p->eobs[block]; - const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize]; - const int16_t *src_diff; - src_diff = &p->src_diff[4 * (row * diff_stride + col)]; - // skip block condition should be handled before this is called. - assert(!x->skip_block); - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - switch (tx_size) { - case TX_32X32: - highbd_fdct32x32(x->use_lp32x32fdct, src_diff, coeff, diff_stride); - vpx_highbd_quantize_b_32x32(coeff, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - break; - case TX_16X16: - vpx_highbd_fdct16x16(src_diff, coeff, diff_stride); - vpx_highbd_quantize_b(coeff, 256, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - break; - case TX_8X8: - vpx_highbd_fdct8x8(src_diff, coeff, diff_stride); - vpx_highbd_quantize_b(coeff, 64, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - break; - default: - assert(tx_size == TX_4X4); - x->fwd_txfm4x4(src_diff, coeff, diff_stride); - vpx_highbd_quantize_b(coeff, 16, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - break; - } - return; - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - switch (tx_size) { - case TX_32X32: - fdct32x32(x->use_lp32x32fdct, src_diff, coeff, diff_stride); - vpx_quantize_b_32x32(coeff, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - break; - case TX_16X16: - vpx_fdct16x16(src_diff, coeff, diff_stride); - vpx_quantize_b(coeff, 256, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - break; - case TX_8X8: - vpx_fdct8x8(src_diff, coeff, diff_stride); - vpx_quantize_b(coeff, 64, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - break; - default: - assert(tx_size == TX_4X4); - x->fwd_txfm4x4(src_diff, coeff, diff_stride); - vpx_quantize_b(coeff, 16, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - break; - } -} - -static void encode_block(int plane, int block, int row, int col, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) { - struct encode_b_args *const args = arg; -#if CONFIG_MISMATCH_DEBUG - int mi_row = args->mi_row; - int mi_col = args->mi_col; - int output_enabled = args->output_enabled; -#endif - MACROBLOCK *const x = args->x; - MACROBLOCKD *const xd = &x->e_mbd; - struct macroblock_plane *const p = &x->plane[plane]; - struct macroblockd_plane *const pd = &xd->plane[plane]; - tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); - uint8_t *dst; - ENTROPY_CONTEXT *a, *l; - dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col]; - a = &args->ta[col]; - l = &args->tl[row]; - - // TODO(jingning): per transformed block zero forcing only enabled for - // luma component. will integrate chroma components as well. - if (x->zcoeff_blk[tx_size][block] && plane == 0) { - p->eobs[block] = 0; - *a = *l = 0; -#if CONFIG_MISMATCH_DEBUG - goto encode_block_end; -#else - return; -#endif - } - - if (!x->skip_recode) { - if (x->quant_fp) { - // Encoding process for rtc mode - if (x->skip_txfm[0] == SKIP_TXFM_AC_DC && plane == 0) { - // skip forward transform - p->eobs[block] = 0; - *a = *l = 0; -#if CONFIG_MISMATCH_DEBUG - goto encode_block_end; -#else - return; -#endif - } else { - vp9_xform_quant_fp(x, plane, block, row, col, plane_bsize, tx_size); - } - } else { - if (max_txsize_lookup[plane_bsize] == tx_size) { - int txfm_blk_index = (plane << 2) + (block >> (tx_size << 1)); - if (x->skip_txfm[txfm_blk_index] == SKIP_TXFM_NONE) { - // full forward transform and quantization - vp9_xform_quant(x, plane, block, row, col, plane_bsize, tx_size); - } else if (x->skip_txfm[txfm_blk_index] == SKIP_TXFM_AC_ONLY) { - // fast path forward transform and quantization - vp9_xform_quant_dc(x, plane, block, row, col, plane_bsize, tx_size); - } else { - // skip forward transform - p->eobs[block] = 0; - *a = *l = 0; -#if CONFIG_MISMATCH_DEBUG - goto encode_block_end; -#else - return; -#endif - } - } else { - vp9_xform_quant(x, plane, block, row, col, plane_bsize, tx_size); - } - } - } - - if (x->optimize && (!x->skip_recode || !x->skip_optimize)) { - const int ctx = combine_entropy_contexts(*a, *l); - *a = *l = vp9_optimize_b(x, plane, block, tx_size, ctx) > 0; - } else { - *a = *l = p->eobs[block] > 0; - } - - if (p->eobs[block]) *(args->skip) = 0; - - if (x->skip_encode || p->eobs[block] == 0) { -#if CONFIG_MISMATCH_DEBUG - goto encode_block_end; -#else - return; -#endif - } -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - uint16_t *const dst16 = CONVERT_TO_SHORTPTR(dst); - switch (tx_size) { - case TX_32X32: - vp9_highbd_idct32x32_add(dqcoeff, dst16, pd->dst.stride, p->eobs[block], - xd->bd); - break; - case TX_16X16: - vp9_highbd_idct16x16_add(dqcoeff, dst16, pd->dst.stride, p->eobs[block], - xd->bd); - break; - case TX_8X8: - vp9_highbd_idct8x8_add(dqcoeff, dst16, pd->dst.stride, p->eobs[block], - xd->bd); - break; - default: - assert(tx_size == TX_4X4); - // this is like vp9_short_idct4x4 but has a special case around eob<=1 - // which is significant (not just an optimization) for the lossless - // case. - x->highbd_inv_txfm_add(dqcoeff, dst16, pd->dst.stride, p->eobs[block], - xd->bd); - break; - } -#if CONFIG_MISMATCH_DEBUG - goto encode_block_end; -#else - return; -#endif - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - switch (tx_size) { - case TX_32X32: - vp9_idct32x32_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]); - break; - case TX_16X16: - vp9_idct16x16_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]); - break; - case TX_8X8: - vp9_idct8x8_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]); - break; - default: - assert(tx_size == TX_4X4); - // this is like vp9_short_idct4x4 but has a special case around eob<=1 - // which is significant (not just an optimization) for the lossless - // case. - x->inv_txfm_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]); - break; - } -#if CONFIG_MISMATCH_DEBUG -encode_block_end: - if (output_enabled) { - int pixel_c, pixel_r; - int blk_w = 1 << (tx_size + TX_UNIT_SIZE_LOG2); - int blk_h = 1 << (tx_size + TX_UNIT_SIZE_LOG2); - mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, col, row, - pd->subsampling_x, pd->subsampling_y); - mismatch_record_block_tx(dst, pd->dst.stride, plane, pixel_c, pixel_r, - blk_w, blk_h, - xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH); - } -#endif -} - -static void encode_block_pass1(int plane, int block, int row, int col, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size, - void *arg) { - MACROBLOCK *const x = (MACROBLOCK *)arg; - MACROBLOCKD *const xd = &x->e_mbd; - struct macroblock_plane *const p = &x->plane[plane]; - struct macroblockd_plane *const pd = &xd->plane[plane]; - tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); - uint8_t *dst; - dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col]; - - vp9_xform_quant(x, plane, block, row, col, plane_bsize, tx_size); - - if (p->eobs[block] > 0) { -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - x->highbd_inv_txfm_add(dqcoeff, CONVERT_TO_SHORTPTR(dst), pd->dst.stride, - p->eobs[block], xd->bd); - return; - } -#endif // CONFIG_VP9_HIGHBITDEPTH - x->inv_txfm_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]); - } -} - -void vp9_encode_sby_pass1(MACROBLOCK *x, BLOCK_SIZE bsize) { - vp9_subtract_plane(x, bsize, 0); - vp9_foreach_transformed_block_in_plane(&x->e_mbd, bsize, 0, - encode_block_pass1, x); -} - -void vp9_encode_sb(MACROBLOCK *x, BLOCK_SIZE bsize, int mi_row, int mi_col, - int output_enabled) { - MACROBLOCKD *const xd = &x->e_mbd; - struct optimize_ctx ctx; - MODE_INFO *mi = xd->mi[0]; - int plane; -#if CONFIG_MISMATCH_DEBUG - struct encode_b_args arg = { x, - 1, // enable_trellis_opt - 0.0, // trellis_opt_thresh - NULL, // &sse_calc_done - NULL, // &sse - NULL, // above entropy context - NULL, // left entropy context - &mi->skip, mi_row, mi_col, output_enabled }; -#else - struct encode_b_args arg = { x, - 1, // enable_trellis_opt - 0.0, // trellis_opt_thresh - NULL, // &sse_calc_done - NULL, // &sse - NULL, // above entropy context - NULL, // left entropy context - &mi->skip }; - (void)mi_row; - (void)mi_col; - (void)output_enabled; -#endif - - mi->skip = 1; - - if (x->skip) return; - - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { - if (!x->skip_recode) vp9_subtract_plane(x, bsize, plane); - - if (x->optimize && (!x->skip_recode || !x->skip_optimize)) { - const struct macroblockd_plane *const pd = &xd->plane[plane]; - const TX_SIZE tx_size = plane ? get_uv_tx_size(mi, pd) : mi->tx_size; - vp9_get_entropy_contexts(bsize, tx_size, pd, ctx.ta[plane], - ctx.tl[plane]); - arg.enable_trellis_opt = 1; - } else { - arg.enable_trellis_opt = 0; - } - arg.ta = ctx.ta[plane]; - arg.tl = ctx.tl[plane]; - - vp9_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block, - &arg); - } -} - -void vp9_encode_block_intra(int plane, int block, int row, int col, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size, - void *arg) { - struct encode_b_args *const args = arg; - MACROBLOCK *const x = args->x; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *mi = xd->mi[0]; - struct macroblock_plane *const p = &x->plane[plane]; - struct macroblockd_plane *const pd = &xd->plane[plane]; - tran_low_t *coeff = BLOCK_OFFSET(p->coeff, block); - tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block); - tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); - const ScanOrder *scan_order; - TX_TYPE tx_type = DCT_DCT; - PREDICTION_MODE mode; - const int bwl = b_width_log2_lookup[plane_bsize]; - const int diff_stride = 4 * (1 << bwl); - uint8_t *src, *dst; - int16_t *src_diff; - uint16_t *eob = &p->eobs[block]; - const int src_stride = p->src.stride; - const int dst_stride = pd->dst.stride; - int enable_trellis_opt = !x->skip_recode; - ENTROPY_CONTEXT *a = NULL; - ENTROPY_CONTEXT *l = NULL; - int entropy_ctx = 0; - dst = &pd->dst.buf[4 * (row * dst_stride + col)]; - src = &p->src.buf[4 * (row * src_stride + col)]; - src_diff = &p->src_diff[4 * (row * diff_stride + col)]; - - if (tx_size == TX_4X4) { - tx_type = get_tx_type_4x4(get_plane_type(plane), xd, block); - scan_order = &vp9_scan_orders[TX_4X4][tx_type]; - mode = plane == 0 ? get_y_mode(xd->mi[0], block) : mi->uv_mode; - } else { - mode = plane == 0 ? mi->mode : mi->uv_mode; - if (tx_size == TX_32X32) { - scan_order = &vp9_default_scan_orders[TX_32X32]; - } else { - tx_type = get_tx_type(get_plane_type(plane), xd); - scan_order = &vp9_scan_orders[tx_size][tx_type]; - } - } - - vp9_predict_intra_block( - xd, bwl, tx_size, mode, (x->skip_encode || x->fp_src_pred) ? src : dst, - (x->skip_encode || x->fp_src_pred) ? src_stride : dst_stride, dst, - dst_stride, col, row, plane); - - // skip block condition should be handled before this is called. - assert(!x->skip_block); - - if (!x->skip_recode) { - const int tx_size_in_pixels = (1 << tx_size) << 2; -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - vpx_highbd_subtract_block(tx_size_in_pixels, tx_size_in_pixels, src_diff, - diff_stride, src, src_stride, dst, dst_stride, - xd->bd); - } else { - vpx_subtract_block(tx_size_in_pixels, tx_size_in_pixels, src_diff, - diff_stride, src, src_stride, dst, dst_stride); - } -#else - vpx_subtract_block(tx_size_in_pixels, tx_size_in_pixels, src_diff, - diff_stride, src, src_stride, dst, dst_stride); -#endif - enable_trellis_opt = do_trellis_opt(pd, src_diff, diff_stride, row, col, - plane_bsize, tx_size, args); - } - - if (enable_trellis_opt) { - a = &args->ta[col]; - l = &args->tl[row]; - entropy_ctx = combine_entropy_contexts(*a, *l); - } - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - uint16_t *const dst16 = CONVERT_TO_SHORTPTR(dst); - switch (tx_size) { - case TX_32X32: - if (!x->skip_recode) { - highbd_fdct32x32(x->use_lp32x32fdct, src_diff, coeff, diff_stride); - vpx_highbd_quantize_b_32x32(coeff, p, qcoeff, dqcoeff, pd->dequant, - eob, scan_order); - } - if (enable_trellis_opt) { - *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0; - } - if (!x->skip_encode && *eob) { - vp9_highbd_idct32x32_add(dqcoeff, dst16, dst_stride, *eob, xd->bd); - } - break; - case TX_16X16: - if (!x->skip_recode) { - if (tx_type == DCT_DCT) - vpx_highbd_fdct16x16(src_diff, coeff, diff_stride); - else - vp9_highbd_fht16x16(src_diff, coeff, diff_stride, tx_type); - vpx_highbd_quantize_b(coeff, 256, p, qcoeff, dqcoeff, pd->dequant, - eob, scan_order); - } - if (enable_trellis_opt) { - *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0; - } - if (!x->skip_encode && *eob) { - vp9_highbd_iht16x16_add(tx_type, dqcoeff, dst16, dst_stride, *eob, - xd->bd); - } - break; - case TX_8X8: - if (!x->skip_recode) { - if (tx_type == DCT_DCT) - vpx_highbd_fdct8x8(src_diff, coeff, diff_stride); - else - vp9_highbd_fht8x8(src_diff, coeff, diff_stride, tx_type); - vpx_highbd_quantize_b(coeff, 64, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - } - if (enable_trellis_opt) { - *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0; - } - if (!x->skip_encode && *eob) { - vp9_highbd_iht8x8_add(tx_type, dqcoeff, dst16, dst_stride, *eob, - xd->bd); - } - break; - default: - assert(tx_size == TX_4X4); - if (!x->skip_recode) { - if (tx_type != DCT_DCT) - vp9_highbd_fht4x4(src_diff, coeff, diff_stride, tx_type); - else - x->fwd_txfm4x4(src_diff, coeff, diff_stride); - vpx_highbd_quantize_b(coeff, 16, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - } - if (enable_trellis_opt) { - *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0; - } - if (!x->skip_encode && *eob) { - if (tx_type == DCT_DCT) { - // this is like vp9_short_idct4x4 but has a special case around - // eob<=1 which is significant (not just an optimization) for the - // lossless case. - x->highbd_inv_txfm_add(dqcoeff, dst16, dst_stride, *eob, xd->bd); - } else { - vp9_highbd_iht4x4_16_add(dqcoeff, dst16, dst_stride, tx_type, - xd->bd); - } - } - break; - } - if (*eob) *(args->skip) = 0; - return; - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - switch (tx_size) { - case TX_32X32: - if (!x->skip_recode) { - fdct32x32(x->use_lp32x32fdct, src_diff, coeff, diff_stride); - vpx_quantize_b_32x32(coeff, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - } - if (enable_trellis_opt) { - *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0; - } - if (!x->skip_encode && *eob) - vp9_idct32x32_add(dqcoeff, dst, dst_stride, *eob); - break; - case TX_16X16: - if (!x->skip_recode) { - vp9_fht16x16(src_diff, coeff, diff_stride, tx_type); - vpx_quantize_b(coeff, 256, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - } - if (enable_trellis_opt) { - *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0; - } - if (!x->skip_encode && *eob) - vp9_iht16x16_add(tx_type, dqcoeff, dst, dst_stride, *eob); - break; - case TX_8X8: - if (!x->skip_recode) { - vp9_fht8x8(src_diff, coeff, diff_stride, tx_type); - vpx_quantize_b(coeff, 64, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - } - if (enable_trellis_opt) { - *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0; - } - if (!x->skip_encode && *eob) - vp9_iht8x8_add(tx_type, dqcoeff, dst, dst_stride, *eob); - break; - default: - assert(tx_size == TX_4X4); - if (!x->skip_recode) { - if (tx_type != DCT_DCT) - vp9_fht4x4(src_diff, coeff, diff_stride, tx_type); - else - x->fwd_txfm4x4(src_diff, coeff, diff_stride); - vpx_quantize_b(coeff, 16, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - } - if (enable_trellis_opt) { - *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0; - } - if (!x->skip_encode && *eob) { - if (tx_type == DCT_DCT) - // this is like vp9_short_idct4x4 but has a special case around eob<=1 - // which is significant (not just an optimization) for the lossless - // case. - x->inv_txfm_add(dqcoeff, dst, dst_stride, *eob); - else - vp9_iht4x4_16_add(dqcoeff, dst, dst_stride, tx_type); - } - break; - } - if (*eob) *(args->skip) = 0; -} - -void vp9_encode_intra_block_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane, - int enable_trellis_opt) { - const MACROBLOCKD *const xd = &x->e_mbd; - struct optimize_ctx ctx; -#if CONFIG_MISMATCH_DEBUG - // TODO(angiebird): make mismatch_debug support intra mode - struct encode_b_args arg = { - x, - enable_trellis_opt, - 0.0, // trellis_opt_thresh - NULL, // &sse_calc_done - NULL, // &sse - ctx.ta[plane], - ctx.tl[plane], - &xd->mi[0]->skip, - 0, // mi_row - 0, // mi_col - 0 // output_enabled - }; -#else - struct encode_b_args arg = { x, - enable_trellis_opt, - 0.0, // trellis_opt_thresh - NULL, // &sse_calc_done - NULL, // &sse - ctx.ta[plane], - ctx.tl[plane], - &xd->mi[0]->skip }; -#endif - - if (enable_trellis_opt && x->optimize && - (!x->skip_recode || !x->skip_optimize)) { - const struct macroblockd_plane *const pd = &xd->plane[plane]; - const TX_SIZE tx_size = - plane ? get_uv_tx_size(xd->mi[0], pd) : xd->mi[0]->tx_size; - vp9_get_entropy_contexts(bsize, tx_size, pd, ctx.ta[plane], ctx.tl[plane]); - } else { - arg.enable_trellis_opt = 0; - } - - vp9_foreach_transformed_block_in_plane(xd, bsize, plane, - vp9_encode_block_intra, &arg); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodemb.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodemb.h deleted file mode 100644 index 1391446b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodemb.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_ENCODEMB_H_ -#define VPX_VP9_ENCODER_VP9_ENCODEMB_H_ - -#include "./vpx_config.h" -#include "vp9/encoder/vp9_block.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct encode_b_args { - MACROBLOCK *x; - int enable_trellis_opt; - double trellis_opt_thresh; - int *sse_calc_done; - int64_t *sse; - ENTROPY_CONTEXT *ta; - ENTROPY_CONTEXT *tl; - int8_t *skip; -#if CONFIG_MISMATCH_DEBUG - int mi_row; - int mi_col; - int output_enabled; -#endif -}; -int vp9_optimize_b(MACROBLOCK *mb, int plane, int block, TX_SIZE tx_size, - int ctx); -void vp9_encode_sb(MACROBLOCK *x, BLOCK_SIZE bsize, int mi_row, int mi_col, - int output_enabled); -void vp9_encode_sby_pass1(MACROBLOCK *x, BLOCK_SIZE bsize); -void vp9_xform_quant_fp(MACROBLOCK *x, int plane, int block, int row, int col, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size); -void vp9_xform_quant_dc(MACROBLOCK *x, int plane, int block, int row, int col, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size); -void vp9_xform_quant(MACROBLOCK *x, int plane, int block, int row, int col, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size); - -void vp9_subtract_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane); - -void vp9_encode_block_intra(int plane, int block, int row, int col, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg); - -void vp9_encode_intra_block_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane, - int enable_trellis_opt); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_ENCODEMB_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodemv.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodemv.c deleted file mode 100644 index 023d087c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodemv.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_entropymode.h" - -#include "vp9/encoder/vp9_cost.h" -#include "vp9/encoder/vp9_encodemv.h" - -#include "vpx_dsp/vpx_dsp_common.h" - -static struct vp9_token mv_joint_encodings[MV_JOINTS]; -static struct vp9_token mv_class_encodings[MV_CLASSES]; -static struct vp9_token mv_fp_encodings[MV_FP_SIZE]; - -void vp9_entropy_mv_init(void) { - vp9_tokens_from_tree(mv_joint_encodings, vp9_mv_joint_tree); - vp9_tokens_from_tree(mv_class_encodings, vp9_mv_class_tree); - vp9_tokens_from_tree(mv_fp_encodings, vp9_mv_fp_tree); -} - -static void encode_mv_component(vpx_writer *w, int comp, - const nmv_component *mvcomp, int usehp) { - int offset; - const int sign = comp < 0; - const int mag = sign ? -comp : comp; - const int mv_class = vp9_get_mv_class(mag - 1, &offset); - const int d = offset >> 3; // int mv data - const int fr = (offset >> 1) & 3; // fractional mv data - const int hp = offset & 1; // high precision mv data - - assert(comp != 0); - - // Sign - vpx_write(w, sign, mvcomp->sign); - - // Class - vp9_write_token(w, vp9_mv_class_tree, mvcomp->classes, - &mv_class_encodings[mv_class]); - - // Integer bits - if (mv_class == MV_CLASS_0) { - vpx_write(w, d, mvcomp->class0[0]); - } else { - int i; - const int n = mv_class + CLASS0_BITS - 1; // number of bits - for (i = 0; i < n; ++i) vpx_write(w, (d >> i) & 1, mvcomp->bits[i]); - } - - // Fractional bits - vp9_write_token(w, vp9_mv_fp_tree, - mv_class == MV_CLASS_0 ? mvcomp->class0_fp[d] : mvcomp->fp, - &mv_fp_encodings[fr]); - - // High precision bit - if (usehp) - vpx_write(w, hp, mv_class == MV_CLASS_0 ? mvcomp->class0_hp : mvcomp->hp); -} - -static void build_nmv_component_cost_table(int *mvcost, - const nmv_component *const mvcomp, - int usehp) { - int sign_cost[2], class_cost[MV_CLASSES], class0_cost[CLASS0_SIZE]; - int bits_cost[MV_OFFSET_BITS][2]; - int class0_fp_cost[CLASS0_SIZE][MV_FP_SIZE], fp_cost[MV_FP_SIZE]; - int class0_hp_cost[2], hp_cost[2]; - int i; - int c, o; - - sign_cost[0] = vp9_cost_zero(mvcomp->sign); - sign_cost[1] = vp9_cost_one(mvcomp->sign); - vp9_cost_tokens(class_cost, mvcomp->classes, vp9_mv_class_tree); - vp9_cost_tokens(class0_cost, mvcomp->class0, vp9_mv_class0_tree); - for (i = 0; i < MV_OFFSET_BITS; ++i) { - bits_cost[i][0] = vp9_cost_zero(mvcomp->bits[i]); - bits_cost[i][1] = vp9_cost_one(mvcomp->bits[i]); - } - - for (i = 0; i < CLASS0_SIZE; ++i) - vp9_cost_tokens(class0_fp_cost[i], mvcomp->class0_fp[i], vp9_mv_fp_tree); - vp9_cost_tokens(fp_cost, mvcomp->fp, vp9_mv_fp_tree); - - // Always build the hp costs to avoid an uninitialized warning from gcc - class0_hp_cost[0] = vp9_cost_zero(mvcomp->class0_hp); - class0_hp_cost[1] = vp9_cost_one(mvcomp->class0_hp); - hp_cost[0] = vp9_cost_zero(mvcomp->hp); - hp_cost[1] = vp9_cost_one(mvcomp->hp); - - mvcost[0] = 0; - // MV_CLASS_0 - for (o = 0; o < (CLASS0_SIZE << 3); ++o) { - int d, e, f; - int cost = class_cost[MV_CLASS_0]; - int v = o + 1; - d = (o >> 3); /* int mv data */ - f = (o >> 1) & 3; /* fractional pel mv data */ - cost += class0_cost[d]; - cost += class0_fp_cost[d][f]; - if (usehp) { - e = (o & 1); /* high precision mv data */ - cost += class0_hp_cost[e]; - } - mvcost[v] = cost + sign_cost[0]; - mvcost[-v] = cost + sign_cost[1]; - } - for (c = MV_CLASS_1; c < MV_CLASSES; ++c) { - int d; - for (d = 0; d < (1 << c); ++d) { - int f; - int whole_cost = class_cost[c]; - int b = c + CLASS0_BITS - 1; /* number of bits */ - for (i = 0; i < b; ++i) whole_cost += bits_cost[i][((d >> i) & 1)]; - for (f = 0; f < 4; ++f) { - int cost = whole_cost + fp_cost[f]; - int v = (CLASS0_SIZE << (c + 2)) + d * 8 + f * 2 /* + e */ + 1; - if (usehp) { - mvcost[v] = cost + hp_cost[0] + sign_cost[0]; - mvcost[-v] = cost + hp_cost[0] + sign_cost[1]; - if (v + 1 > MV_MAX) break; - mvcost[v + 1] = cost + hp_cost[1] + sign_cost[0]; - mvcost[-v - 1] = cost + hp_cost[1] + sign_cost[1]; - } else { - mvcost[v] = cost + sign_cost[0]; - mvcost[-v] = cost + sign_cost[1]; - if (v + 1 > MV_MAX) break; - mvcost[v + 1] = cost + sign_cost[0]; - mvcost[-v - 1] = cost + sign_cost[1]; - } - } - } - } -} - -static int update_mv(vpx_writer *w, const unsigned int ct[2], vpx_prob *cur_p, - vpx_prob upd_p) { - const vpx_prob new_p = get_binary_prob(ct[0], ct[1]) | 1; - const int update = cost_branch256(ct, *cur_p) + vp9_cost_zero(upd_p) > - cost_branch256(ct, new_p) + vp9_cost_one(upd_p) + - (7 << VP9_PROB_COST_SHIFT); - vpx_write(w, update, upd_p); - if (update) { - *cur_p = new_p; - vpx_write_literal(w, new_p >> 1, 7); - } - return update; -} - -static void write_mv_update(const vpx_tree_index *tree, - vpx_prob probs[/*n - 1*/], - const unsigned int counts[/*n - 1*/], int n, - vpx_writer *w) { - int i; - unsigned int branch_ct[32][2]; - - // Assuming max number of probabilities <= 32 - assert(n <= 32); - - vp9_tree_probs_from_distribution(tree, branch_ct, counts); - for (i = 0; i < n - 1; ++i) - update_mv(w, branch_ct[i], &probs[i], MV_UPDATE_PROB); -} - -void vp9_write_nmv_probs(VP9_COMMON *cm, int usehp, vpx_writer *w, - nmv_context_counts *const counts) { - int i, j; - nmv_context *const mvc = &cm->fc->nmvc; - - write_mv_update(vp9_mv_joint_tree, mvc->joints, counts->joints, MV_JOINTS, w); - - for (i = 0; i < 2; ++i) { - nmv_component *comp = &mvc->comps[i]; - nmv_component_counts *comp_counts = &counts->comps[i]; - - update_mv(w, comp_counts->sign, &comp->sign, MV_UPDATE_PROB); - write_mv_update(vp9_mv_class_tree, comp->classes, comp_counts->classes, - MV_CLASSES, w); - write_mv_update(vp9_mv_class0_tree, comp->class0, comp_counts->class0, - CLASS0_SIZE, w); - for (j = 0; j < MV_OFFSET_BITS; ++j) - update_mv(w, comp_counts->bits[j], &comp->bits[j], MV_UPDATE_PROB); - } - - for (i = 0; i < 2; ++i) { - for (j = 0; j < CLASS0_SIZE; ++j) - write_mv_update(vp9_mv_fp_tree, mvc->comps[i].class0_fp[j], - counts->comps[i].class0_fp[j], MV_FP_SIZE, w); - - write_mv_update(vp9_mv_fp_tree, mvc->comps[i].fp, counts->comps[i].fp, - MV_FP_SIZE, w); - } - - if (usehp) { - for (i = 0; i < 2; ++i) { - update_mv(w, counts->comps[i].class0_hp, &mvc->comps[i].class0_hp, - MV_UPDATE_PROB); - update_mv(w, counts->comps[i].hp, &mvc->comps[i].hp, MV_UPDATE_PROB); - } - } -} - -void vp9_encode_mv(VP9_COMP *cpi, vpx_writer *w, const MV *mv, const MV *ref, - const nmv_context *mvctx, int usehp, - unsigned int *const max_mv_magnitude) { - const MV diff = { mv->row - ref->row, mv->col - ref->col }; - const MV_JOINT_TYPE j = vp9_get_mv_joint(&diff); - usehp = usehp && use_mv_hp(ref); - - vp9_write_token(w, vp9_mv_joint_tree, mvctx->joints, &mv_joint_encodings[j]); - if (mv_joint_vertical(j)) - encode_mv_component(w, diff.row, &mvctx->comps[0], usehp); - - if (mv_joint_horizontal(j)) - encode_mv_component(w, diff.col, &mvctx->comps[1], usehp); - - // If auto_mv_step_size is enabled then keep track of the largest - // motion vector component used. - if (cpi->sf.mv.auto_mv_step_size) { - const unsigned int maxv = VPXMAX(abs(mv->row), abs(mv->col)) >> 3; - *max_mv_magnitude = VPXMAX(maxv, *max_mv_magnitude); - } -} - -void vp9_build_nmv_cost_table(int *mvjoint, int *mvcost[2], - const nmv_context *ctx, int usehp) { - vp9_cost_tokens(mvjoint, ctx->joints, vp9_mv_joint_tree); - build_nmv_component_cost_table(mvcost[0], &ctx->comps[0], usehp); - build_nmv_component_cost_table(mvcost[1], &ctx->comps[1], usehp); -} - -static void inc_mvs(const MODE_INFO *mi, const MB_MODE_INFO_EXT *mbmi_ext, - const int_mv mvs[2], nmv_context_counts *counts) { - int i; - - for (i = 0; i < 1 + has_second_ref(mi); ++i) { - const MV *ref = &mbmi_ext->ref_mvs[mi->ref_frame[i]][0].as_mv; - const MV diff = { mvs[i].as_mv.row - ref->row, - mvs[i].as_mv.col - ref->col }; - vp9_inc_mv(&diff, counts); - } -} - -void vp9_update_mv_count(ThreadData *td) { - const MACROBLOCKD *xd = &td->mb.e_mbd; - const MODE_INFO *mi = xd->mi[0]; - const MB_MODE_INFO_EXT *mbmi_ext = td->mb.mbmi_ext; - - if (mi->sb_type < BLOCK_8X8) { - const int num_4x4_w = num_4x4_blocks_wide_lookup[mi->sb_type]; - const int num_4x4_h = num_4x4_blocks_high_lookup[mi->sb_type]; - int idx, idy; - - for (idy = 0; idy < 2; idy += num_4x4_h) { - for (idx = 0; idx < 2; idx += num_4x4_w) { - const int i = idy * 2 + idx; - if (mi->bmi[i].as_mode == NEWMV) - inc_mvs(mi, mbmi_ext, mi->bmi[i].as_mv, &td->counts->mv); - } - } - } else { - if (mi->mode == NEWMV) inc_mvs(mi, mbmi_ext, mi->mv, &td->counts->mv); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodemv.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodemv.h deleted file mode 100644 index 2f1be4b2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encodemv.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_ENCODEMV_H_ -#define VPX_VP9_ENCODER_VP9_ENCODEMV_H_ - -#include "vp9/encoder/vp9_encoder.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vp9_entropy_mv_init(void); - -void vp9_write_nmv_probs(VP9_COMMON *cm, int usehp, vpx_writer *w, - nmv_context_counts *const counts); - -void vp9_encode_mv(VP9_COMP *cpi, vpx_writer *w, const MV *mv, const MV *ref, - const nmv_context *mvctx, int usehp, - unsigned int *const max_mv_magnitude); - -void vp9_build_nmv_cost_table(int *mvjoint, int *mvcost[2], - const nmv_context *ctx, int usehp); - -void vp9_update_mv_count(ThreadData *td); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_ENCODEMV_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encoder.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encoder.c deleted file mode 100644 index 59179faa..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encoder.c +++ /dev/null @@ -1,7110 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include -#include - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "./vpx_scale_rtcd.h" -#include "vpx/vpx_codec.h" -#include "vpx/vpx_ext_ratectrl.h" -#include "vpx_dsp/psnr.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/vpx_filter.h" -#if CONFIG_INTERNAL_STATS -#include "vpx_dsp/ssim.h" -#endif -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/system_state.h" -#include "vpx_ports/vpx_once.h" -#include "vpx_ports/vpx_timer.h" -#include "vpx_util/vpx_pthread.h" -#if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG -#include "vpx_util/vpx_debug_util.h" -#endif // CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG - -#include "vp9/common/vp9_alloccommon.h" -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_enums.h" -#include "vp9/common/vp9_filter.h" -#include "vp9/common/vp9_idct.h" -#if CONFIG_VP9_POSTPROC -#include "vp9/common/vp9_postproc.h" -#endif -#include "vp9/common/vp9_reconinter.h" -#include "vp9/common/vp9_reconintra.h" -#include "vp9/common/vp9_scale.h" -#include "vp9/common/vp9_tile_common.h" - -#if !CONFIG_REALTIME_ONLY -#include "vp9/encoder/vp9_alt_ref_aq.h" -#include "vp9/encoder/vp9_aq_360.h" -#include "vp9/encoder/vp9_aq_complexity.h" -#endif -#include "vp9/encoder/vp9_aq_cyclicrefresh.h" -#if !CONFIG_REALTIME_ONLY -#include "vp9/encoder/vp9_aq_variance.h" -#endif -#include "vp9/encoder/vp9_bitstream.h" -#if CONFIG_INTERNAL_STATS -#include "vp9/encoder/vp9_blockiness.h" -#endif -#include "vp9/encoder/vp9_context_tree.h" -#include "vp9/encoder/vp9_encodeframe.h" -#include "vp9/encoder/vp9_encodemb.h" -#include "vp9/encoder/vp9_encodemv.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_ethread.h" -#include "vp9/encoder/vp9_extend.h" -#include "vp9/encoder/vp9_firstpass.h" -#include "vp9/encoder/vp9_mbgraph.h" -#if CONFIG_NON_GREEDY_MV -#include "vp9/encoder/vp9_mcomp.h" -#endif -#include "vp9/encoder/vp9_multi_thread.h" -#include "vp9/encoder/vp9_noise_estimate.h" -#include "vp9/encoder/vp9_picklpf.h" -#include "vp9/encoder/vp9_ratectrl.h" -#include "vp9/encoder/vp9_rd.h" -#include "vp9/encoder/vp9_resize.h" -#include "vp9/encoder/vp9_segmentation.h" -#include "vp9/encoder/vp9_skin_detection.h" -#include "vp9/encoder/vp9_speed_features.h" -#include "vp9/encoder/vp9_svc_layercontext.h" -#include "vp9/encoder/vp9_temporal_filter.h" -#include "vp9/encoder/vp9_tpl_model.h" -#include "vp9/vp9_cx_iface.h" - -#define AM_SEGMENT_ID_INACTIVE 7 -#define AM_SEGMENT_ID_ACTIVE 0 - -// Whether to use high precision mv for altref computation. -#define ALTREF_HIGH_PRECISION_MV 1 - -// Q threshold for high precision mv. Choose a very high value for now so that -// HIGH_PRECISION is always chosen. -#define HIGH_PRECISION_MV_QTHRESH 200 - -#define FRAME_SIZE_FACTOR 128 // empirical params for context model threshold -#define FRAME_RATE_FACTOR 8 - -#ifdef OUTPUT_YUV_DENOISED -FILE *yuv_denoised_file = NULL; -#endif -#ifdef OUTPUT_YUV_SKINMAP -static FILE *yuv_skinmap_file = NULL; -#endif -#ifdef OUTPUT_YUV_REC -FILE *yuv_rec_file; -#endif -#ifdef OUTPUT_YUV_SVC_SRC -FILE *yuv_svc_src[3] = { NULL, NULL, NULL }; -#endif - -#if 0 -FILE *framepsnr; -FILE *kf_list; -FILE *keyfile; -#endif - -#ifdef ENABLE_KF_DENOISE -// Test condition for spatial denoise of source. -static int is_spatial_denoise_enabled(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - - return (oxcf->pass != 1) && !is_lossless_requested(&cpi->oxcf) && - frame_is_intra_only(cm); -} -#endif - -#if !CONFIG_REALTIME_ONLY -// compute adaptive threshold for skip recoding -static int compute_context_model_thresh(const VP9_COMP *const cpi) { - const VP9_COMMON *const cm = &cpi->common; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - const int frame_size = (cm->width * cm->height) >> 10; - const int bitrate = (int)(oxcf->target_bandwidth >> 10); - const int qindex_factor = cm->base_qindex + (MAXQ >> 1); - - // This equation makes the threshold adaptive to frame size. - // Coding gain obtained by recoding comes from alternate frames of large - // content change. We skip recoding if the difference of previous and current - // frame context probability model is less than a certain threshold. - // The first component is the most critical part to guarantee adaptivity. - // Other parameters are estimated based on normal setting of hd resolution - // parameters. e.g. frame_size = 1920x1080, bitrate = 8000, qindex_factor < 50 - const int thresh = - ((FRAME_SIZE_FACTOR * frame_size - FRAME_RATE_FACTOR * bitrate) * - qindex_factor) >> - 9; - - return thresh; -} - -// compute the total cost difference between current -// and previous frame context prob model. -static int compute_context_model_diff(const VP9_COMMON *const cm) { - const FRAME_CONTEXT *const pre_fc = - &cm->frame_contexts[cm->frame_context_idx]; - const FRAME_CONTEXT *const cur_fc = cm->fc; - const FRAME_COUNTS *counts = &cm->counts; - vpx_prob pre_last_prob, cur_last_prob; - int diff = 0; - int i, j, k, l, m, n; - - // y_mode_prob - for (i = 0; i < BLOCK_SIZE_GROUPS; ++i) { - for (j = 0; j < INTRA_MODES - 1; ++j) { - diff += (int)counts->y_mode[i][j] * - (pre_fc->y_mode_prob[i][j] - cur_fc->y_mode_prob[i][j]); - } - pre_last_prob = MAX_PROB - pre_fc->y_mode_prob[i][INTRA_MODES - 2]; - cur_last_prob = MAX_PROB - cur_fc->y_mode_prob[i][INTRA_MODES - 2]; - - diff += (int)counts->y_mode[i][INTRA_MODES - 1] * - (pre_last_prob - cur_last_prob); - } - - // uv_mode_prob - for (i = 0; i < INTRA_MODES; ++i) { - for (j = 0; j < INTRA_MODES - 1; ++j) { - diff += (int)counts->uv_mode[i][j] * - (pre_fc->uv_mode_prob[i][j] - cur_fc->uv_mode_prob[i][j]); - } - pre_last_prob = MAX_PROB - pre_fc->uv_mode_prob[i][INTRA_MODES - 2]; - cur_last_prob = MAX_PROB - cur_fc->uv_mode_prob[i][INTRA_MODES - 2]; - - diff += (int)counts->uv_mode[i][INTRA_MODES - 1] * - (pre_last_prob - cur_last_prob); - } - - // partition_prob - for (i = 0; i < PARTITION_CONTEXTS; ++i) { - for (j = 0; j < PARTITION_TYPES - 1; ++j) { - diff += (int)counts->partition[i][j] * - (pre_fc->partition_prob[i][j] - cur_fc->partition_prob[i][j]); - } - pre_last_prob = MAX_PROB - pre_fc->partition_prob[i][PARTITION_TYPES - 2]; - cur_last_prob = MAX_PROB - cur_fc->partition_prob[i][PARTITION_TYPES - 2]; - - diff += (int)counts->partition[i][PARTITION_TYPES - 1] * - (pre_last_prob - cur_last_prob); - } - - // coef_probs - for (i = 0; i < TX_SIZES; ++i) { - for (j = 0; j < PLANE_TYPES; ++j) { - for (k = 0; k < REF_TYPES; ++k) { - for (l = 0; l < COEF_BANDS; ++l) { - for (m = 0; m < BAND_COEFF_CONTEXTS(l); ++m) { - for (n = 0; n < UNCONSTRAINED_NODES; ++n) { - diff += (int)counts->coef[i][j][k][l][m][n] * - (pre_fc->coef_probs[i][j][k][l][m][n] - - cur_fc->coef_probs[i][j][k][l][m][n]); - } - - pre_last_prob = - MAX_PROB - - pre_fc->coef_probs[i][j][k][l][m][UNCONSTRAINED_NODES - 1]; - cur_last_prob = - MAX_PROB - - cur_fc->coef_probs[i][j][k][l][m][UNCONSTRAINED_NODES - 1]; - - diff += (int)counts->coef[i][j][k][l][m][UNCONSTRAINED_NODES] * - (pre_last_prob - cur_last_prob); - } - } - } - } - } - - // switchable_interp_prob - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) { - for (j = 0; j < SWITCHABLE_FILTERS - 1; ++j) { - diff += (int)counts->switchable_interp[i][j] * - (pre_fc->switchable_interp_prob[i][j] - - cur_fc->switchable_interp_prob[i][j]); - } - pre_last_prob = - MAX_PROB - pre_fc->switchable_interp_prob[i][SWITCHABLE_FILTERS - 2]; - cur_last_prob = - MAX_PROB - cur_fc->switchable_interp_prob[i][SWITCHABLE_FILTERS - 2]; - - diff += (int)counts->switchable_interp[i][SWITCHABLE_FILTERS - 1] * - (pre_last_prob - cur_last_prob); - } - - // inter_mode_probs - for (i = 0; i < INTER_MODE_CONTEXTS; ++i) { - for (j = 0; j < INTER_MODES - 1; ++j) { - diff += (int)counts->inter_mode[i][j] * - (pre_fc->inter_mode_probs[i][j] - cur_fc->inter_mode_probs[i][j]); - } - pre_last_prob = MAX_PROB - pre_fc->inter_mode_probs[i][INTER_MODES - 2]; - cur_last_prob = MAX_PROB - cur_fc->inter_mode_probs[i][INTER_MODES - 2]; - - diff += (int)counts->inter_mode[i][INTER_MODES - 1] * - (pre_last_prob - cur_last_prob); - } - - // intra_inter_prob - for (i = 0; i < INTRA_INTER_CONTEXTS; ++i) { - diff += (int)counts->intra_inter[i][0] * - (pre_fc->intra_inter_prob[i] - cur_fc->intra_inter_prob[i]); - - pre_last_prob = MAX_PROB - pre_fc->intra_inter_prob[i]; - cur_last_prob = MAX_PROB - cur_fc->intra_inter_prob[i]; - - diff += (int)counts->intra_inter[i][1] * (pre_last_prob - cur_last_prob); - } - - // comp_inter_prob - for (i = 0; i < COMP_INTER_CONTEXTS; ++i) { - diff += (int)counts->comp_inter[i][0] * - (pre_fc->comp_inter_prob[i] - cur_fc->comp_inter_prob[i]); - - pre_last_prob = MAX_PROB - pre_fc->comp_inter_prob[i]; - cur_last_prob = MAX_PROB - cur_fc->comp_inter_prob[i]; - - diff += (int)counts->comp_inter[i][1] * (pre_last_prob - cur_last_prob); - } - - // single_ref_prob - for (i = 0; i < REF_CONTEXTS; ++i) { - for (j = 0; j < 2; ++j) { - diff += (int)counts->single_ref[i][j][0] * - (pre_fc->single_ref_prob[i][j] - cur_fc->single_ref_prob[i][j]); - - pre_last_prob = MAX_PROB - pre_fc->single_ref_prob[i][j]; - cur_last_prob = MAX_PROB - cur_fc->single_ref_prob[i][j]; - - diff += - (int)counts->single_ref[i][j][1] * (pre_last_prob - cur_last_prob); - } - } - - // comp_ref_prob - for (i = 0; i < REF_CONTEXTS; ++i) { - diff += (int)counts->comp_ref[i][0] * - (pre_fc->comp_ref_prob[i] - cur_fc->comp_ref_prob[i]); - - pre_last_prob = MAX_PROB - pre_fc->comp_ref_prob[i]; - cur_last_prob = MAX_PROB - cur_fc->comp_ref_prob[i]; - - diff += (int)counts->comp_ref[i][1] * (pre_last_prob - cur_last_prob); - } - - // tx_probs - for (i = 0; i < TX_SIZE_CONTEXTS; ++i) { - // p32x32 - for (j = 0; j < TX_SIZES - 1; ++j) { - diff += (int)counts->tx.p32x32[i][j] * - (pre_fc->tx_probs.p32x32[i][j] - cur_fc->tx_probs.p32x32[i][j]); - } - pre_last_prob = MAX_PROB - pre_fc->tx_probs.p32x32[i][TX_SIZES - 2]; - cur_last_prob = MAX_PROB - cur_fc->tx_probs.p32x32[i][TX_SIZES - 2]; - - diff += (int)counts->tx.p32x32[i][TX_SIZES - 1] * - (pre_last_prob - cur_last_prob); - - // p16x16 - for (j = 0; j < TX_SIZES - 2; ++j) { - diff += (int)counts->tx.p16x16[i][j] * - (pre_fc->tx_probs.p16x16[i][j] - cur_fc->tx_probs.p16x16[i][j]); - } - pre_last_prob = MAX_PROB - pre_fc->tx_probs.p16x16[i][TX_SIZES - 3]; - cur_last_prob = MAX_PROB - cur_fc->tx_probs.p16x16[i][TX_SIZES - 3]; - - diff += (int)counts->tx.p16x16[i][TX_SIZES - 2] * - (pre_last_prob - cur_last_prob); - - // p8x8 - for (j = 0; j < TX_SIZES - 3; ++j) { - diff += (int)counts->tx.p8x8[i][j] * - (pre_fc->tx_probs.p8x8[i][j] - cur_fc->tx_probs.p8x8[i][j]); - } - pre_last_prob = MAX_PROB - pre_fc->tx_probs.p8x8[i][TX_SIZES - 4]; - cur_last_prob = MAX_PROB - cur_fc->tx_probs.p8x8[i][TX_SIZES - 4]; - - diff += - (int)counts->tx.p8x8[i][TX_SIZES - 3] * (pre_last_prob - cur_last_prob); - } - - // skip_probs - for (i = 0; i < SKIP_CONTEXTS; ++i) { - diff += (int)counts->skip[i][0] * - (pre_fc->skip_probs[i] - cur_fc->skip_probs[i]); - - pre_last_prob = MAX_PROB - pre_fc->skip_probs[i]; - cur_last_prob = MAX_PROB - cur_fc->skip_probs[i]; - - diff += (int)counts->skip[i][1] * (pre_last_prob - cur_last_prob); - } - - // mv - for (i = 0; i < MV_JOINTS - 1; ++i) { - diff += (int)counts->mv.joints[i] * - (pre_fc->nmvc.joints[i] - cur_fc->nmvc.joints[i]); - } - pre_last_prob = MAX_PROB - pre_fc->nmvc.joints[MV_JOINTS - 2]; - cur_last_prob = MAX_PROB - cur_fc->nmvc.joints[MV_JOINTS - 2]; - - diff += - (int)counts->mv.joints[MV_JOINTS - 1] * (pre_last_prob - cur_last_prob); - - for (i = 0; i < 2; ++i) { - const nmv_component_counts *nmv_count = &counts->mv.comps[i]; - const nmv_component *pre_nmv_prob = &pre_fc->nmvc.comps[i]; - const nmv_component *cur_nmv_prob = &cur_fc->nmvc.comps[i]; - - // sign - diff += (int)nmv_count->sign[0] * (pre_nmv_prob->sign - cur_nmv_prob->sign); - - pre_last_prob = MAX_PROB - pre_nmv_prob->sign; - cur_last_prob = MAX_PROB - cur_nmv_prob->sign; - - diff += (int)nmv_count->sign[1] * (pre_last_prob - cur_last_prob); - - // classes - for (j = 0; j < MV_CLASSES - 1; ++j) { - diff += (int)nmv_count->classes[j] * - (pre_nmv_prob->classes[j] - cur_nmv_prob->classes[j]); - } - pre_last_prob = MAX_PROB - pre_nmv_prob->classes[MV_CLASSES - 2]; - cur_last_prob = MAX_PROB - cur_nmv_prob->classes[MV_CLASSES - 2]; - - diff += (int)nmv_count->classes[MV_CLASSES - 1] * - (pre_last_prob - cur_last_prob); - - // class0 - for (j = 0; j < CLASS0_SIZE - 1; ++j) { - diff += (int)nmv_count->class0[j] * - (pre_nmv_prob->class0[j] - cur_nmv_prob->class0[j]); - } - pre_last_prob = MAX_PROB - pre_nmv_prob->class0[CLASS0_SIZE - 2]; - cur_last_prob = MAX_PROB - cur_nmv_prob->class0[CLASS0_SIZE - 2]; - - diff += (int)nmv_count->class0[CLASS0_SIZE - 1] * - (pre_last_prob - cur_last_prob); - - // bits - for (j = 0; j < MV_OFFSET_BITS; ++j) { - diff += (int)nmv_count->bits[j][0] * - (pre_nmv_prob->bits[j] - cur_nmv_prob->bits[j]); - - pre_last_prob = MAX_PROB - pre_nmv_prob->bits[j]; - cur_last_prob = MAX_PROB - cur_nmv_prob->bits[j]; - - diff += (int)nmv_count->bits[j][1] * (pre_last_prob - cur_last_prob); - } - - // class0_fp - for (j = 0; j < CLASS0_SIZE; ++j) { - for (k = 0; k < MV_FP_SIZE - 1; ++k) { - diff += (int)nmv_count->class0_fp[j][k] * - (pre_nmv_prob->class0_fp[j][k] - cur_nmv_prob->class0_fp[j][k]); - } - pre_last_prob = MAX_PROB - pre_nmv_prob->class0_fp[j][MV_FP_SIZE - 2]; - cur_last_prob = MAX_PROB - cur_nmv_prob->class0_fp[j][MV_FP_SIZE - 2]; - - diff += (int)nmv_count->class0_fp[j][MV_FP_SIZE - 1] * - (pre_last_prob - cur_last_prob); - } - - // fp - for (j = 0; j < MV_FP_SIZE - 1; ++j) { - diff += - (int)nmv_count->fp[j] * (pre_nmv_prob->fp[j] - cur_nmv_prob->fp[j]); - } - pre_last_prob = MAX_PROB - pre_nmv_prob->fp[MV_FP_SIZE - 2]; - cur_last_prob = MAX_PROB - cur_nmv_prob->fp[MV_FP_SIZE - 2]; - - diff += - (int)nmv_count->fp[MV_FP_SIZE - 1] * (pre_last_prob - cur_last_prob); - - // class0_hp - diff += (int)nmv_count->class0_hp[0] * - (pre_nmv_prob->class0_hp - cur_nmv_prob->class0_hp); - - pre_last_prob = MAX_PROB - pre_nmv_prob->class0_hp; - cur_last_prob = MAX_PROB - cur_nmv_prob->class0_hp; - - diff += (int)nmv_count->class0_hp[1] * (pre_last_prob - cur_last_prob); - - // hp - diff += (int)nmv_count->hp[0] * (pre_nmv_prob->hp - cur_nmv_prob->hp); - - pre_last_prob = MAX_PROB - pre_nmv_prob->hp; - cur_last_prob = MAX_PROB - cur_nmv_prob->hp; - - diff += (int)nmv_count->hp[1] * (pre_last_prob - cur_last_prob); - } - - return -diff; -} -#endif // !CONFIG_REALTIME_ONLY - -// Test for whether to calculate metrics for the frame. -static int is_psnr_calc_enabled(const VP9_COMP *cpi) { - const VP9_COMMON *const cm = &cpi->common; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - - return cpi->b_calculate_psnr && (oxcf->pass != 1) && cm->show_frame; -} - -/* clang-format off */ -const Vp9LevelSpec vp9_level_defs[VP9_LEVELS] = { - // sample rate size breadth bitrate cpb - { LEVEL_1, 829440, 36864, 512, 200, 400, 2, 1, 4, 8 }, - { LEVEL_1_1, 2764800, 73728, 768, 800, 1000, 2, 1, 4, 8 }, - { LEVEL_2, 4608000, 122880, 960, 1800, 1500, 2, 1, 4, 8 }, - { LEVEL_2_1, 9216000, 245760, 1344, 3600, 2800, 2, 2, 4, 8 }, - { LEVEL_3, 20736000, 552960, 2048, 7200, 6000, 2, 4, 4, 8 }, - { LEVEL_3_1, 36864000, 983040, 2752, 12000, 10000, 2, 4, 4, 8 }, - { LEVEL_4, 83558400, 2228224, 4160, 18000, 16000, 4, 4, 4, 8 }, - { LEVEL_4_1, 160432128, 2228224, 4160, 30000, 18000, 4, 4, 5, 6 }, - { LEVEL_5, 311951360, 8912896, 8384, 60000, 36000, 6, 8, 6, 4 }, - { LEVEL_5_1, 588251136, 8912896, 8384, 120000, 46000, 8, 8, 10, 4 }, - // TODO(huisu): update max_cpb_size for level 5_2 ~ 6_2 when - // they are finalized (currently tentative). - { LEVEL_5_2, 1176502272, 8912896, 8384, 180000, 90000, 8, 8, 10, 4 }, - { LEVEL_6, 1176502272, 35651584, 16832, 180000, 90000, 8, 16, 10, 4 }, - { LEVEL_6_1, 2353004544u, 35651584, 16832, 240000, 180000, 8, 16, 10, 4 }, - { LEVEL_6_2, 4706009088u, 35651584, 16832, 480000, 360000, 8, 16, 10, 4 }, -}; -/* clang-format on */ - -static const char *level_fail_messages[TARGET_LEVEL_FAIL_IDS] = { - "The average bit-rate is too high.", - "The picture size is too large.", - "The picture width/height is too large.", - "The luma sample rate is too large.", - "The CPB size is too large.", - "The compression ratio is too small", - "Too many column tiles are used.", - "The alt-ref distance is too small.", - "Too many reference buffers are used." -}; - -static INLINE void Scale2Ratio(VPX_SCALING_MODE mode, int *hr, int *hs) { - switch (mode) { - case VP8E_NORMAL: - *hr = 1; - *hs = 1; - break; - case VP8E_FOURFIVE: - *hr = 4; - *hs = 5; - break; - case VP8E_THREEFIVE: - *hr = 3; - *hs = 5; - break; - default: - assert(mode == VP8E_ONETWO); - *hr = 1; - *hs = 2; - break; - } -} - -// Mark all inactive blocks as active. Other segmentation features may be set -// so memset cannot be used, instead only inactive blocks should be reset. -static void suppress_active_map(VP9_COMP *cpi) { - unsigned char *const seg_map = cpi->segmentation_map; - - if (cpi->active_map.enabled || cpi->active_map.update) { - const int rows = cpi->common.mi_rows; - const int cols = cpi->common.mi_cols; - int i; - - for (i = 0; i < rows * cols; ++i) - if (seg_map[i] == AM_SEGMENT_ID_INACTIVE) - seg_map[i] = AM_SEGMENT_ID_ACTIVE; - } -} - -static void apply_active_map(VP9_COMP *cpi) { - struct segmentation *const seg = &cpi->common.seg; - unsigned char *const seg_map = cpi->segmentation_map; - const unsigned char *const active_map = cpi->active_map.map; - int i; - - assert(AM_SEGMENT_ID_ACTIVE == CR_SEGMENT_ID_BASE); - - if (frame_is_intra_only(&cpi->common)) { - cpi->active_map.enabled = 0; - cpi->active_map.update = 1; - } - - if (cpi->active_map.update) { - if (cpi->active_map.enabled) { - for (i = 0; i < cpi->common.mi_rows * cpi->common.mi_cols; ++i) - if (seg_map[i] == AM_SEGMENT_ID_ACTIVE) seg_map[i] = active_map[i]; - vp9_enable_segmentation(seg); - vp9_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP); - vp9_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF); - // Setting the data to -MAX_LOOP_FILTER will result in the computed loop - // filter level being zero regardless of the value of seg->abs_delta. - vp9_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF, - -MAX_LOOP_FILTER); - } else { - vp9_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP); - vp9_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF); - if (seg->enabled) { - seg->update_data = 1; - seg->update_map = 1; - } - } - cpi->active_map.update = 0; - } -} - -static void apply_roi_map(VP9_COMP *cpi) { - VP9_COMMON *cm = &cpi->common; - struct segmentation *const seg = &cm->seg; - vpx_roi_map_t *roi = &cpi->roi; - const int *delta_q = roi->delta_q; - const int *delta_lf = roi->delta_lf; - const int *skip = roi->skip; - int ref_frame[8]; - int internal_delta_q[MAX_SEGMENTS]; - int i; - - // TODO(jianj): Investigate why ROI not working in speed < 5 or in non - // realtime mode. - if (cpi->oxcf.mode != REALTIME || cpi->oxcf.speed < 5) return; - if (!roi->enabled) return; - - memcpy(&ref_frame, roi->ref_frame, sizeof(ref_frame)); - - vp9_enable_segmentation(seg); - vp9_clearall_segfeatures(seg); - // Select delta coding method; - seg->abs_delta = SEGMENT_DELTADATA; - - memcpy(cpi->segmentation_map, roi->roi_map, (cm->mi_rows * cm->mi_cols)); - - for (i = 0; i < MAX_SEGMENTS; ++i) { - // Translate the external delta q values to internal values. - internal_delta_q[i] = vp9_quantizer_to_qindex(abs(delta_q[i])); - if (delta_q[i] < 0) internal_delta_q[i] = -internal_delta_q[i]; - vp9_disable_segfeature(seg, i, SEG_LVL_ALT_Q); - vp9_disable_segfeature(seg, i, SEG_LVL_ALT_LF); - if (internal_delta_q[i] != 0) { - vp9_enable_segfeature(seg, i, SEG_LVL_ALT_Q); - vp9_set_segdata(seg, i, SEG_LVL_ALT_Q, internal_delta_q[i]); - } - if (delta_lf[i] != 0) { - vp9_enable_segfeature(seg, i, SEG_LVL_ALT_LF); - vp9_set_segdata(seg, i, SEG_LVL_ALT_LF, delta_lf[i]); - } - if (skip[i] != 0) { - vp9_enable_segfeature(seg, i, SEG_LVL_SKIP); - vp9_set_segdata(seg, i, SEG_LVL_SKIP, 0); - } - if (ref_frame[i] >= 0) { - int valid_ref = 1; - // ALTREF is not used as reference for nonrd_pickmode with 0 lag. - if (ref_frame[i] == ALTREF_FRAME && cpi->sf.use_nonrd_pick_mode) - valid_ref = 0; - // If GOLDEN is selected, make sure it's set as reference. - if (ref_frame[i] == GOLDEN_FRAME && - !(cpi->ref_frame_flags & ref_frame_to_flag(ref_frame[i]))) { - valid_ref = 0; - } - // GOLDEN was updated in previous encoded frame, so GOLDEN and LAST are - // same reference. - if (ref_frame[i] == GOLDEN_FRAME && cpi->rc.frames_since_golden == 0) - ref_frame[i] = LAST_FRAME; - if (valid_ref) { - vp9_enable_segfeature(seg, i, SEG_LVL_REF_FRAME); - vp9_set_segdata(seg, i, SEG_LVL_REF_FRAME, ref_frame[i]); - } - } - } - roi->enabled = 1; -} - -static void init_level_info(Vp9LevelInfo *level_info) { - Vp9LevelStats *const level_stats = &level_info->level_stats; - Vp9LevelSpec *const level_spec = &level_info->level_spec; - - memset(level_stats, 0, sizeof(*level_stats)); - memset(level_spec, 0, sizeof(*level_spec)); - level_spec->level = LEVEL_UNKNOWN; - level_spec->min_altref_distance = INT_MAX; -} - -static int check_seg_range(int seg_data[8], int range) { - int i; - for (i = 0; i < 8; ++i) { - // Note abs() alone can't be used as the behavior of abs(INT_MIN) is - // undefined. - if (seg_data[i] > range || seg_data[i] < -range) { - return 0; - } - } - return 1; -} - -VP9_LEVEL vp9_get_level(const Vp9LevelSpec *const level_spec) { - int i; - const Vp9LevelSpec *this_level; - - vpx_clear_system_state(); - - for (i = 0; i < VP9_LEVELS; ++i) { - this_level = &vp9_level_defs[i]; - if ((double)level_spec->max_luma_sample_rate > - (double)this_level->max_luma_sample_rate * - (1 + SAMPLE_RATE_GRACE_P) || - level_spec->max_luma_picture_size > this_level->max_luma_picture_size || - level_spec->max_luma_picture_breadth > - this_level->max_luma_picture_breadth || - level_spec->average_bitrate > this_level->average_bitrate || - level_spec->max_cpb_size > this_level->max_cpb_size || - level_spec->compression_ratio < this_level->compression_ratio || - level_spec->max_col_tiles > this_level->max_col_tiles || - level_spec->min_altref_distance < this_level->min_altref_distance || - level_spec->max_ref_frame_buffers > this_level->max_ref_frame_buffers) - continue; - break; - } - return (i == VP9_LEVELS) ? LEVEL_UNKNOWN : vp9_level_defs[i].level; -} - -vpx_codec_err_t vp9_set_roi_map(VP9_COMP *cpi, unsigned char *map, - unsigned int rows, unsigned int cols, - int delta_q[8], int delta_lf[8], int skip[8], - int ref_frame[8]) { - VP9_COMMON *cm = &cpi->common; - vpx_roi_map_t *roi = &cpi->roi; - const int range = 63; - const int ref_frame_range = 3; // Alt-ref - const int skip_range = 1; - const int frame_rows = cpi->common.mi_rows; - const int frame_cols = cpi->common.mi_cols; - - // Check number of rows and columns match - if (frame_rows != (int)rows || frame_cols != (int)cols) { - return VPX_CODEC_INVALID_PARAM; - } - - if (!check_seg_range(delta_q, range) || !check_seg_range(delta_lf, range) || - !check_seg_range(ref_frame, ref_frame_range) || - !check_seg_range(skip, skip_range)) - return VPX_CODEC_INVALID_PARAM; - - // Also disable segmentation if no deltas are specified. - if (!map || - (!(delta_q[0] | delta_q[1] | delta_q[2] | delta_q[3] | delta_q[4] | - delta_q[5] | delta_q[6] | delta_q[7] | delta_lf[0] | delta_lf[1] | - delta_lf[2] | delta_lf[3] | delta_lf[4] | delta_lf[5] | delta_lf[6] | - delta_lf[7] | skip[0] | skip[1] | skip[2] | skip[3] | skip[4] | - skip[5] | skip[6] | skip[7]) && - (ref_frame[0] == -1 && ref_frame[1] == -1 && ref_frame[2] == -1 && - ref_frame[3] == -1 && ref_frame[4] == -1 && ref_frame[5] == -1 && - ref_frame[6] == -1 && ref_frame[7] == -1))) { - vp9_disable_segmentation(&cm->seg); - cpi->roi.enabled = 0; - return VPX_CODEC_OK; - } - - if (roi->roi_map) { - vpx_free(roi->roi_map); - roi->roi_map = NULL; - } - roi->roi_map = vpx_malloc(rows * cols); - if (!roi->roi_map) return VPX_CODEC_MEM_ERROR; - - // Copy to ROI structure in the compressor. - memcpy(roi->roi_map, map, rows * cols); - memcpy(&roi->delta_q, delta_q, MAX_SEGMENTS * sizeof(delta_q[0])); - memcpy(&roi->delta_lf, delta_lf, MAX_SEGMENTS * sizeof(delta_lf[0])); - memcpy(&roi->skip, skip, MAX_SEGMENTS * sizeof(skip[0])); - memcpy(&roi->ref_frame, ref_frame, MAX_SEGMENTS * sizeof(ref_frame[0])); - roi->enabled = 1; - roi->rows = rows; - roi->cols = cols; - - return VPX_CODEC_OK; -} - -int vp9_set_active_map(VP9_COMP *cpi, unsigned char *new_map_16x16, int rows, - int cols) { - if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols) { - unsigned char *const active_map_8x8 = cpi->active_map.map; - const int mi_rows = cpi->common.mi_rows; - const int mi_cols = cpi->common.mi_cols; - cpi->active_map.update = 1; - if (new_map_16x16) { - int r, c; - for (r = 0; r < mi_rows; ++r) { - for (c = 0; c < mi_cols; ++c) { - active_map_8x8[r * mi_cols + c] = - new_map_16x16[(r >> 1) * cols + (c >> 1)] - ? AM_SEGMENT_ID_ACTIVE - : AM_SEGMENT_ID_INACTIVE; - } - } - cpi->active_map.enabled = 1; - } else { - cpi->active_map.enabled = 0; - } - return 0; - } else { - return -1; - } -} - -int vp9_get_active_map(VP9_COMP *cpi, unsigned char *new_map_16x16, int rows, - int cols) { - if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols && - new_map_16x16) { - unsigned char *const seg_map_8x8 = cpi->segmentation_map; - const int mi_rows = cpi->common.mi_rows; - const int mi_cols = cpi->common.mi_cols; - memset(new_map_16x16, !cpi->active_map.enabled, rows * cols); - if (cpi->active_map.enabled) { - int r, c; - for (r = 0; r < mi_rows; ++r) { - for (c = 0; c < mi_cols; ++c) { - // Cyclic refresh segments are considered active despite not having - // AM_SEGMENT_ID_ACTIVE - new_map_16x16[(r >> 1) * cols + (c >> 1)] |= - seg_map_8x8[r * mi_cols + c] != AM_SEGMENT_ID_INACTIVE; - } - } - } - return 0; - } else { - return -1; - } -} - -void vp9_set_high_precision_mv(VP9_COMP *cpi, int allow_high_precision_mv) { - MACROBLOCK *const mb = &cpi->td.mb; - cpi->common.allow_high_precision_mv = allow_high_precision_mv; - if (cpi->common.allow_high_precision_mv) { - mb->mvcost = mb->nmvcost_hp; - mb->mvsadcost = mb->nmvsadcost_hp; - } else { - mb->mvcost = mb->nmvcost; - mb->mvsadcost = mb->nmvsadcost; - } -} - -static void setup_frame(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - // Set up entropy context depending on frame type. The decoder mandates - // the use of the default context, index 0, for keyframes and inter - // frames where the error_resilient_mode or intra_only flag is set. For - // other inter-frames the encoder currently uses only two contexts; - // context 1 for ALTREF frames and context 0 for the others. - if (frame_is_intra_only(cm) || cm->error_resilient_mode) { - vp9_setup_past_independence(cm); - } else { - if (!cpi->use_svc) cm->frame_context_idx = cpi->refresh_alt_ref_frame; - } - - // TODO(jingning): Overwrite the frame_context_idx index in multi-layer ARF - // case. Need some further investigation on if we could apply this to single - // layer ARF case as well. - if (cpi->multi_layer_arf && !cpi->use_svc) { - GF_GROUP *const gf_group = &cpi->twopass.gf_group; - const int gf_group_index = gf_group->index; - const int boost_frame = - !cpi->rc.is_src_frame_alt_ref && - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame); - - // frame_context_idx Frame Type - // 0 Intra only frame, base layer ARF - // 1 ARFs with layer depth = 2,3 - // 2 ARFs with layer depth > 3 - // 3 Non-boosted frames - if (frame_is_intra_only(cm)) { - cm->frame_context_idx = 0; - } else if (boost_frame) { - if (gf_group->rf_level[gf_group_index] == GF_ARF_STD) - cm->frame_context_idx = 0; - else if (gf_group->layer_depth[gf_group_index] <= 3) - cm->frame_context_idx = 1; - else - cm->frame_context_idx = 2; - } else { - cm->frame_context_idx = 3; - } - } - - if (cm->frame_type == KEY_FRAME) { - cpi->refresh_golden_frame = 1; - cpi->refresh_alt_ref_frame = 1; - vp9_zero(cpi->interp_filter_selected); - } else { - *cm->fc = cm->frame_contexts[cm->frame_context_idx]; - vp9_zero(cpi->interp_filter_selected[0]); - } -} - -static void vp9_enc_setup_mi(VP9_COMMON *cm) { - int i; - cm->mi = cm->mip + cm->mi_stride + 1; - memset(cm->mip, 0, cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mip)); - cm->prev_mi = cm->prev_mip + cm->mi_stride + 1; - // Clear top border row - memset(cm->prev_mip, 0, sizeof(*cm->prev_mip) * cm->mi_stride); - // Clear left border column - for (i = 1; i < cm->mi_rows + 1; ++i) - memset(&cm->prev_mip[i * cm->mi_stride], 0, sizeof(*cm->prev_mip)); - - cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1; - cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1; - - memset(cm->mi_grid_base, 0, - cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mi_grid_base)); -} - -static int vp9_enc_alloc_mi(VP9_COMMON *cm, int mi_size) { - cm->mip = vpx_calloc(mi_size, sizeof(*cm->mip)); - if (!cm->mip) return 1; - cm->prev_mip = vpx_calloc(mi_size, sizeof(*cm->prev_mip)); - if (!cm->prev_mip) return 1; - cm->mi_alloc_size = mi_size; - - cm->mi_grid_base = - (MODE_INFO **)vpx_calloc(mi_size, sizeof(*cm->mi_grid_base)); - if (!cm->mi_grid_base) return 1; - cm->prev_mi_grid_base = - (MODE_INFO **)vpx_calloc(mi_size, sizeof(*cm->prev_mi_grid_base)); - if (!cm->prev_mi_grid_base) return 1; - - return 0; -} - -static void vp9_enc_free_mi(VP9_COMMON *cm) { - vpx_free(cm->mip); - cm->mip = NULL; - vpx_free(cm->prev_mip); - cm->prev_mip = NULL; - vpx_free(cm->mi_grid_base); - cm->mi_grid_base = NULL; - vpx_free(cm->prev_mi_grid_base); - cm->prev_mi_grid_base = NULL; - cm->mi_alloc_size = 0; -} - -static void vp9_swap_mi_and_prev_mi(VP9_COMMON *cm) { - // Current mip will be the prev_mip for the next frame. - MODE_INFO **temp_base = cm->prev_mi_grid_base; - MODE_INFO *temp = cm->prev_mip; - - // Skip update prev_mi frame in show_existing_frame mode. - if (cm->show_existing_frame) return; - - cm->prev_mip = cm->mip; - cm->mip = temp; - - // Update the upper left visible macroblock ptrs. - cm->mi = cm->mip + cm->mi_stride + 1; - cm->prev_mi = cm->prev_mip + cm->mi_stride + 1; - - cm->prev_mi_grid_base = cm->mi_grid_base; - cm->mi_grid_base = temp_base; - cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1; - cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1; -} - -static void initialize_enc(void) { - vp9_rtcd(); - vpx_dsp_rtcd(); - vpx_scale_rtcd(); - vp9_init_intra_predictors(); - vp9_init_me_luts(); - vp9_rc_init_minq_luts(); - vp9_entropy_mv_init(); -#if !CONFIG_REALTIME_ONLY - vp9_temporal_filter_init(); -#endif -} - -void vp9_initialize_enc(void) { once(initialize_enc); } - -static void dealloc_compressor_data(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - int i; - - vpx_free(cpi->mbmi_ext_base); - cpi->mbmi_ext_base = NULL; - - vpx_free(cpi->tile_data); - cpi->tile_data = NULL; - - vpx_free(cpi->segmentation_map); - cpi->segmentation_map = NULL; - vpx_free(cpi->coding_context.last_frame_seg_map_copy); - cpi->coding_context.last_frame_seg_map_copy = NULL; - - vpx_free(cpi->nmvcosts[0]); - vpx_free(cpi->nmvcosts[1]); - cpi->nmvcosts[0] = NULL; - cpi->nmvcosts[1] = NULL; - - vpx_free(cpi->nmvcosts_hp[0]); - vpx_free(cpi->nmvcosts_hp[1]); - cpi->nmvcosts_hp[0] = NULL; - cpi->nmvcosts_hp[1] = NULL; - - vpx_free(cpi->nmvsadcosts[0]); - vpx_free(cpi->nmvsadcosts[1]); - cpi->nmvsadcosts[0] = NULL; - cpi->nmvsadcosts[1] = NULL; - - vpx_free(cpi->nmvsadcosts_hp[0]); - vpx_free(cpi->nmvsadcosts_hp[1]); - cpi->nmvsadcosts_hp[0] = NULL; - cpi->nmvsadcosts_hp[1] = NULL; - - vpx_free(cpi->skin_map); - cpi->skin_map = NULL; - - vpx_free(cpi->prev_partition); - cpi->prev_partition = NULL; - - vpx_free(cpi->svc.prev_partition_svc); - cpi->svc.prev_partition_svc = NULL; - - vpx_free(cpi->prev_segment_id); - cpi->prev_segment_id = NULL; - - vpx_free(cpi->prev_variance_low); - cpi->prev_variance_low = NULL; - - vpx_free(cpi->copied_frame_cnt); - cpi->copied_frame_cnt = NULL; - - vpx_free(cpi->content_state_sb_fd); - cpi->content_state_sb_fd = NULL; - - vpx_free(cpi->count_arf_frame_usage); - cpi->count_arf_frame_usage = NULL; - vpx_free(cpi->count_lastgolden_frame_usage); - cpi->count_lastgolden_frame_usage = NULL; - - vp9_cyclic_refresh_free(cpi->cyclic_refresh); - cpi->cyclic_refresh = NULL; - - vpx_free(cpi->active_map.map); - cpi->active_map.map = NULL; - - vpx_free(cpi->roi.roi_map); - cpi->roi.roi_map = NULL; - - vpx_free(cpi->consec_zero_mv); - cpi->consec_zero_mv = NULL; - - vpx_free(cpi->mb_wiener_variance); - cpi->mb_wiener_variance = NULL; - - vpx_free(cpi->mi_ssim_rdmult_scaling_factors); - cpi->mi_ssim_rdmult_scaling_factors = NULL; - -#if CONFIG_RATE_CTRL - if (cpi->oxcf.use_simple_encode_api) { - free_partition_info(cpi); - free_motion_vector_info(cpi); - free_fp_motion_vector_info(cpi); - free_tpl_stats_info(cpi); - } -#endif - - vp9_free_ref_frame_buffers(cm->buffer_pool); -#if CONFIG_VP9_POSTPROC - vp9_free_postproc_buffers(cm); -#endif - vp9_free_context_buffers(cm); - - vpx_free_frame_buffer(&cpi->last_frame_uf); - vpx_free_frame_buffer(&cpi->scaled_source); - vpx_free_frame_buffer(&cpi->scaled_last_source); - vpx_free_frame_buffer(&cpi->tf_buffer); -#ifdef ENABLE_KF_DENOISE - vpx_free_frame_buffer(&cpi->raw_unscaled_source); - vpx_free_frame_buffer(&cpi->raw_scaled_source); -#endif - - vp9_lookahead_destroy(cpi->lookahead); - - vpx_free(cpi->tile_tok[0][0]); - cpi->tile_tok[0][0] = 0; - - vpx_free(cpi->tplist[0][0]); - cpi->tplist[0][0] = NULL; - - vp9_free_pc_tree(&cpi->td); - - for (i = 0; i < cpi->svc.number_spatial_layers; ++i) { - LAYER_CONTEXT *const lc = &cpi->svc.layer_context[i]; - vpx_free(lc->rc_twopass_stats_in.buf); - lc->rc_twopass_stats_in.buf = NULL; - lc->rc_twopass_stats_in.sz = 0; - } - - if (cpi->source_diff_var != NULL) { - vpx_free(cpi->source_diff_var); - cpi->source_diff_var = NULL; - } - - for (i = 0; i < MAX_LAG_BUFFERS; ++i) { - vpx_free_frame_buffer(&cpi->svc.scaled_frames[i]); - } - memset(&cpi->svc.scaled_frames[0], 0, - MAX_LAG_BUFFERS * sizeof(cpi->svc.scaled_frames[0])); - - vpx_free_frame_buffer(&cpi->svc.scaled_temp); - memset(&cpi->svc.scaled_temp, 0, sizeof(cpi->svc.scaled_temp)); - - vpx_free_frame_buffer(&cpi->svc.empty_frame.img); - memset(&cpi->svc.empty_frame, 0, sizeof(cpi->svc.empty_frame)); - - vp9_free_svc_cyclic_refresh(cpi); -} - -static void save_coding_context(VP9_COMP *cpi) { - CODING_CONTEXT *const cc = &cpi->coding_context; - VP9_COMMON *cm = &cpi->common; - - // Stores a snapshot of key state variables which can subsequently be - // restored with a call to vp9_restore_coding_context. These functions are - // intended for use in a re-code loop in vp9_compress_frame where the - // quantizer value is adjusted between loop iterations. - vp9_copy(cc->nmvjointcost, cpi->td.mb.nmvjointcost); - - memcpy(cc->nmvcosts[0], cpi->nmvcosts[0], - MV_VALS * sizeof(*cpi->nmvcosts[0])); - memcpy(cc->nmvcosts[1], cpi->nmvcosts[1], - MV_VALS * sizeof(*cpi->nmvcosts[1])); - memcpy(cc->nmvcosts_hp[0], cpi->nmvcosts_hp[0], - MV_VALS * sizeof(*cpi->nmvcosts_hp[0])); - memcpy(cc->nmvcosts_hp[1], cpi->nmvcosts_hp[1], - MV_VALS * sizeof(*cpi->nmvcosts_hp[1])); - - vp9_copy(cc->segment_pred_probs, cm->seg.pred_probs); - - memcpy(cpi->coding_context.last_frame_seg_map_copy, cm->last_frame_seg_map, - (cm->mi_rows * cm->mi_cols)); - - vp9_copy(cc->last_ref_lf_deltas, cm->lf.last_ref_deltas); - vp9_copy(cc->last_mode_lf_deltas, cm->lf.last_mode_deltas); - - cc->fc = *cm->fc; -} - -static void restore_coding_context(VP9_COMP *cpi) { - CODING_CONTEXT *const cc = &cpi->coding_context; - VP9_COMMON *cm = &cpi->common; - - // Restore key state variables to the snapshot state stored in the - // previous call to vp9_save_coding_context. - vp9_copy(cpi->td.mb.nmvjointcost, cc->nmvjointcost); - - memcpy(cpi->nmvcosts[0], cc->nmvcosts[0], MV_VALS * sizeof(*cc->nmvcosts[0])); - memcpy(cpi->nmvcosts[1], cc->nmvcosts[1], MV_VALS * sizeof(*cc->nmvcosts[1])); - memcpy(cpi->nmvcosts_hp[0], cc->nmvcosts_hp[0], - MV_VALS * sizeof(*cc->nmvcosts_hp[0])); - memcpy(cpi->nmvcosts_hp[1], cc->nmvcosts_hp[1], - MV_VALS * sizeof(*cc->nmvcosts_hp[1])); - - vp9_copy(cm->seg.pred_probs, cc->segment_pred_probs); - - memcpy(cm->last_frame_seg_map, cpi->coding_context.last_frame_seg_map_copy, - (cm->mi_rows * cm->mi_cols)); - - vp9_copy(cm->lf.last_ref_deltas, cc->last_ref_lf_deltas); - vp9_copy(cm->lf.last_mode_deltas, cc->last_mode_lf_deltas); - - *cm->fc = cc->fc; -} - -#if !CONFIG_REALTIME_ONLY -static void configure_static_seg_features(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - const RATE_CONTROL *const rc = &cpi->rc; - struct segmentation *const seg = &cm->seg; - - int high_q = (int)(rc->avg_q > 48.0); - int qi_delta; - - // Disable and clear down for KF - if (cm->frame_type == KEY_FRAME) { - // Clear down the global segmentation map - memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols); - seg->update_map = 0; - seg->update_data = 0; - cpi->static_mb_pct = 0; - - // Disable segmentation - vp9_disable_segmentation(seg); - - // Clear down the segment features. - vp9_clearall_segfeatures(seg); - } else if (cpi->refresh_alt_ref_frame) { - // If this is an alt ref frame - // Clear down the global segmentation map - memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols); - seg->update_map = 0; - seg->update_data = 0; - cpi->static_mb_pct = 0; - - // Disable segmentation and individual segment features by default - vp9_disable_segmentation(seg); - vp9_clearall_segfeatures(seg); - - // Scan frames from current to arf frame. - // This function re-enables segmentation if appropriate. - vp9_update_mbgraph_stats(cpi); - - // If segmentation was enabled set those features needed for the - // arf itself. - if (seg->enabled) { - seg->update_map = 1; - seg->update_data = 1; - - qi_delta = - vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 0.875, cm->bit_depth); - vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta - 2); - vp9_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2); - - vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q); - vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_LF); - - // Where relevant assume segment data is delta data - seg->abs_delta = SEGMENT_DELTADATA; - } - } else if (seg->enabled) { - // All other frames if segmentation has been enabled - - // First normal frame in a valid gf or alt ref group - if (rc->frames_since_golden == 0) { - // Set up segment features for normal frames in an arf group - if (rc->source_alt_ref_active) { - seg->update_map = 0; - seg->update_data = 1; - seg->abs_delta = SEGMENT_DELTADATA; - - qi_delta = - vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 1.125, cm->bit_depth); - vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta + 2); - vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q); - - vp9_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2); - vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_LF); - - // Segment coding disabled for compred testing - if (high_q || (cpi->static_mb_pct == 100)) { - vp9_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME); - vp9_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME); - vp9_enable_segfeature(seg, 1, SEG_LVL_SKIP); - } - } else { - // Disable segmentation and clear down features if alt ref - // is not active for this group - - vp9_disable_segmentation(seg); - - memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols); - - seg->update_map = 0; - seg->update_data = 0; - - vp9_clearall_segfeatures(seg); - } - } else if (rc->is_src_frame_alt_ref) { - // Special case where we are coding over the top of a previous - // alt ref frame. - // Segment coding disabled for compred testing - - // Enable ref frame features for segment 0 as well - vp9_enable_segfeature(seg, 0, SEG_LVL_REF_FRAME); - vp9_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME); - - // All mbs should use ALTREF_FRAME - vp9_clear_segdata(seg, 0, SEG_LVL_REF_FRAME); - vp9_set_segdata(seg, 0, SEG_LVL_REF_FRAME, ALTREF_FRAME); - vp9_clear_segdata(seg, 1, SEG_LVL_REF_FRAME); - vp9_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME); - - // Skip all MBs if high Q (0,0 mv and skip coeffs) - if (high_q) { - vp9_enable_segfeature(seg, 0, SEG_LVL_SKIP); - vp9_enable_segfeature(seg, 1, SEG_LVL_SKIP); - } - // Enable data update - seg->update_data = 1; - } else { - // All other frames. - - // No updates.. leave things as they are. - seg->update_map = 0; - seg->update_data = 0; - } - } -} -#endif // !CONFIG_REALTIME_ONLY - -static void update_reference_segmentation_map(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - MODE_INFO **mi_8x8_ptr = cm->mi_grid_visible; - uint8_t *cache_ptr = cm->last_frame_seg_map; - int row, col; - - for (row = 0; row < cm->mi_rows; row++) { - MODE_INFO **mi_8x8 = mi_8x8_ptr; - uint8_t *cache = cache_ptr; - for (col = 0; col < cm->mi_cols; col++, mi_8x8++, cache++) - cache[0] = mi_8x8[0]->segment_id; - mi_8x8_ptr += cm->mi_stride; - cache_ptr += cm->mi_cols; - } -} - -static void alloc_raw_frame_buffers(VP9_COMP *cpi) { - VP9_COMMON *cm = &cpi->common; - const VP9EncoderConfig *oxcf = &cpi->oxcf; - - if (!cpi->lookahead) - cpi->lookahead = vp9_lookahead_init(oxcf->width, oxcf->height, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - oxcf->lag_in_frames); - if (!cpi->lookahead) - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate lag buffers"); - - // TODO(agrange) Check if ARF is enabled and skip allocation if not. - if (vpx_realloc_frame_buffer(&cpi->tf_buffer, oxcf->width, oxcf->height, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment, - NULL, NULL, NULL)) - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate temporal filter buffer"); -} - -static void alloc_util_frame_buffers(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - if (vpx_realloc_frame_buffer(&cpi->last_frame_uf, cm->width, cm->height, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment, - NULL, NULL, NULL)) - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate last frame buffer"); - - if (vpx_realloc_frame_buffer(&cpi->scaled_source, cm->width, cm->height, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment, - NULL, NULL, NULL)) - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate scaled source buffer"); - - // For 1 pass cbr: allocate scaled_frame that may be used as an intermediate - // buffer for a 2 stage down-sampling: two stages of 1:2 down-sampling for a - // target of 1/4x1/4. number_spatial_layers must be greater than 2. - if (is_one_pass_svc(cpi) && !cpi->svc.scaled_temp_is_alloc && - cpi->svc.number_spatial_layers > 2) { - cpi->svc.scaled_temp_is_alloc = 1; - if (vpx_realloc_frame_buffer( - &cpi->svc.scaled_temp, cm->width >> 1, cm->height >> 1, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment, NULL, NULL, NULL)) - vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, - "Failed to allocate scaled_frame for svc "); - } - - if (vpx_realloc_frame_buffer(&cpi->scaled_last_source, cm->width, cm->height, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment, - NULL, NULL, NULL)) - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate scaled last source buffer"); -#ifdef ENABLE_KF_DENOISE - if (vpx_realloc_frame_buffer(&cpi->raw_unscaled_source, cm->width, cm->height, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment, - NULL, NULL, NULL)) - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate unscaled raw source frame buffer"); - - if (vpx_realloc_frame_buffer(&cpi->raw_scaled_source, cm->width, cm->height, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment, - NULL, NULL, NULL)) - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate scaled raw source frame buffer"); -#endif -} - -static void alloc_context_buffers_ext(VP9_COMP *cpi) { - VP9_COMMON *cm = &cpi->common; - int mi_size = cm->mi_cols * cm->mi_rows; - - CHECK_MEM_ERROR(&cm->error, cpi->mbmi_ext_base, - vpx_calloc(mi_size, sizeof(*cpi->mbmi_ext_base))); -} - -static void alloc_compressor_data(VP9_COMP *cpi) { - VP9_COMMON *cm = &cpi->common; - int sb_rows; - - if (vp9_alloc_context_buffers(cm, cm->width, cm->height)) { - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate context buffers"); - } - - alloc_context_buffers_ext(cpi); - - vpx_free(cpi->tile_tok[0][0]); - - { - unsigned int tokens = get_token_alloc(cm->mb_rows, cm->mb_cols); - CHECK_MEM_ERROR(&cm->error, cpi->tile_tok[0][0], - vpx_calloc(tokens, sizeof(*cpi->tile_tok[0][0]))); - } - - sb_rows = mi_cols_aligned_to_sb(cm->mi_rows) >> MI_BLOCK_SIZE_LOG2; - vpx_free(cpi->tplist[0][0]); - CHECK_MEM_ERROR( - &cm->error, cpi->tplist[0][0], - vpx_calloc(sb_rows * 4 * (1 << 6), sizeof(*cpi->tplist[0][0]))); - - vp9_setup_pc_tree(&cpi->common, &cpi->td); -} - -void vp9_new_framerate(VP9_COMP *cpi, double framerate) { - cpi->framerate = framerate < 0.1 ? 30 : framerate; - vp9_rc_update_framerate(cpi); -} - -static void set_tile_limits(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - - int min_log2_tile_cols, max_log2_tile_cols; - vp9_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols); - - cm->log2_tile_cols = - clamp(cpi->oxcf.tile_columns, min_log2_tile_cols, max_log2_tile_cols); - cm->log2_tile_rows = cpi->oxcf.tile_rows; - - if (cpi->oxcf.target_level == LEVEL_AUTO) { - const int level_tile_cols = - log_tile_cols_from_picsize_level(cpi->common.width, cpi->common.height); - if (cm->log2_tile_cols > level_tile_cols) { - cm->log2_tile_cols = VPXMAX(level_tile_cols, min_log2_tile_cols); - } - } -} - -static void update_frame_size(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; - - vp9_set_mb_mi(cm, cm->width, cm->height); - vp9_init_context_buffers(cm); - vp9_init_macroblockd(cm, xd, NULL); - cpi->td.mb.mbmi_ext_base = cpi->mbmi_ext_base; - memset(cpi->mbmi_ext_base, 0, - cm->mi_rows * cm->mi_cols * sizeof(*cpi->mbmi_ext_base)); - - set_tile_limits(cpi); -} - -static void init_buffer_indices(VP9_COMP *cpi) { - int ref_frame; - - for (ref_frame = 0; ref_frame < REF_FRAMES; ++ref_frame) - cpi->ref_fb_idx[ref_frame] = ref_frame; - - cpi->lst_fb_idx = cpi->ref_fb_idx[LAST_FRAME - 1]; - cpi->gld_fb_idx = cpi->ref_fb_idx[GOLDEN_FRAME - 1]; - cpi->alt_fb_idx = cpi->ref_fb_idx[ALTREF_FRAME - 1]; -} - -static void init_level_constraint(LevelConstraint *lc) { - lc->level_index = -1; - lc->max_cpb_size = INT_MAX; - lc->max_frame_size = INT_MAX; - lc->fail_flag = 0; -} - -static void set_level_constraint(LevelConstraint *ls, int8_t level_index) { - vpx_clear_system_state(); - ls->level_index = level_index; - if (level_index >= 0) { - ls->max_cpb_size = vp9_level_defs[level_index].max_cpb_size * (double)1000; - } -} - -static void init_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) { - VP9_COMMON *const cm = &cpi->common; - - cpi->oxcf = *oxcf; - cpi->framerate = oxcf->init_framerate; - cm->profile = oxcf->profile; - cm->bit_depth = oxcf->bit_depth; -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth = oxcf->use_highbitdepth; -#endif - cm->color_space = oxcf->color_space; - cm->color_range = oxcf->color_range; - - cpi->target_level = oxcf->target_level; - cpi->keep_level_stats = oxcf->target_level != LEVEL_MAX; - set_level_constraint(&cpi->level_constraint, - get_level_index(cpi->target_level)); - - cm->width = oxcf->width; - cm->height = oxcf->height; - alloc_compressor_data(cpi); - - cpi->svc.temporal_layering_mode = oxcf->temporal_layering_mode; - - // Single thread case: use counts in common. - cpi->td.counts = &cm->counts; - - // Spatial scalability. - cpi->svc.number_spatial_layers = oxcf->ss_number_layers; - // Temporal scalability. - cpi->svc.number_temporal_layers = oxcf->ts_number_layers; - - if ((cpi->svc.number_temporal_layers > 1) || - ((cpi->svc.number_temporal_layers > 1 || - cpi->svc.number_spatial_layers > 1) && - cpi->oxcf.pass != 1)) { - vp9_init_layer_context(cpi); - } - - // change includes all joint functionality - vp9_change_config(cpi, oxcf); - - cpi->static_mb_pct = 0; - cpi->ref_frame_flags = 0; - - init_buffer_indices(cpi); - - vp9_noise_estimate_init(&cpi->noise_estimate, cm->width, cm->height); - cpi->fixed_qp_onepass = 0; -} - -void vp9_check_reset_rc_flag(VP9_COMP *cpi) { - RATE_CONTROL *rc = &cpi->rc; - - if (cpi->common.current_video_frame > - (unsigned int)cpi->svc.number_spatial_layers) { - if (cpi->use_svc) { - vp9_svc_check_reset_layer_rc_flag(cpi); - } else { - if (rc->avg_frame_bandwidth / 3 > (rc->last_avg_frame_bandwidth >> 1) || - rc->avg_frame_bandwidth < (rc->last_avg_frame_bandwidth >> 1)) { - rc->rc_1_frame = 0; - rc->rc_2_frame = 0; - rc->bits_off_target = rc->optimal_buffer_level; - rc->buffer_level = rc->optimal_buffer_level; - } - } - } -} - -void vp9_set_rc_buffer_sizes(VP9_COMP *cpi) { - RATE_CONTROL *rc = &cpi->rc; - const VP9EncoderConfig *oxcf = &cpi->oxcf; - - const int64_t bandwidth = oxcf->target_bandwidth; - const int64_t starting = oxcf->starting_buffer_level_ms; - const int64_t optimal = oxcf->optimal_buffer_level_ms; - const int64_t maximum = oxcf->maximum_buffer_size_ms; - - rc->starting_buffer_level = starting * bandwidth / 1000; - rc->optimal_buffer_level = - (optimal == 0) ? bandwidth / 8 : optimal * bandwidth / 1000; - rc->maximum_buffer_size = - (maximum == 0) ? bandwidth / 8 : maximum * bandwidth / 1000; - - // Under a configuration change, where maximum_buffer_size may change, - // keep buffer level clipped to the maximum allowed buffer size. - rc->bits_off_target = VPXMIN(rc->bits_off_target, rc->maximum_buffer_size); - rc->buffer_level = VPXMIN(rc->buffer_level, rc->maximum_buffer_size); -} - -#if CONFIG_VP9_HIGHBITDEPTH -#define HIGHBD_BFP(BT, SDF, SDSF, SDAF, VF, SVF, SVAF, SDX4DF, SDSX4DF) \ - cpi->fn_ptr[BT].sdf = SDF; \ - cpi->fn_ptr[BT].sdsf = SDSF; \ - cpi->fn_ptr[BT].sdaf = SDAF; \ - cpi->fn_ptr[BT].vf = VF; \ - cpi->fn_ptr[BT].svf = SVF; \ - cpi->fn_ptr[BT].svaf = SVAF; \ - cpi->fn_ptr[BT].sdx4df = SDX4DF; \ - cpi->fn_ptr[BT].sdsx4df = SDSX4DF; - -#define MAKE_BFP_SAD_WRAPPER(fnname) \ - static unsigned int fnname##_bits8(const uint8_t *src_ptr, \ - int source_stride, \ - const uint8_t *ref_ptr, int ref_stride) { \ - return fnname(src_ptr, source_stride, ref_ptr, ref_stride); \ - } \ - static unsigned int fnname##_bits10( \ - const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \ - int ref_stride) { \ - return fnname(src_ptr, source_stride, ref_ptr, ref_stride) >> 2; \ - } \ - static unsigned int fnname##_bits12( \ - const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \ - int ref_stride) { \ - return fnname(src_ptr, source_stride, ref_ptr, ref_stride) >> 4; \ - } - -#define MAKE_BFP_SADAVG_WRAPPER(fnname) \ - static unsigned int fnname##_bits8( \ - const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \ - int ref_stride, const uint8_t *second_pred) { \ - return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred); \ - } \ - static unsigned int fnname##_bits10( \ - const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \ - int ref_stride, const uint8_t *second_pred) { \ - return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred) >> \ - 2; \ - } \ - static unsigned int fnname##_bits12( \ - const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \ - int ref_stride, const uint8_t *second_pred) { \ - return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred) >> \ - 4; \ - } - -#define MAKE_BFP_SAD4D_WRAPPER(fnname) \ - static void fnname##_bits8(const uint8_t *src_ptr, int source_stride, \ - const uint8_t *const ref_ptr[], int ref_stride, \ - unsigned int *sad_array) { \ - fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \ - } \ - static void fnname##_bits10(const uint8_t *src_ptr, int source_stride, \ - const uint8_t *const ref_ptr[], int ref_stride, \ - unsigned int *sad_array) { \ - int i; \ - fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \ - for (i = 0; i < 4; i++) sad_array[i] >>= 2; \ - } \ - static void fnname##_bits12(const uint8_t *src_ptr, int source_stride, \ - const uint8_t *const ref_ptr[], int ref_stride, \ - unsigned int *sad_array) { \ - int i; \ - fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \ - for (i = 0; i < 4; i++) sad_array[i] >>= 4; \ - } - -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad32x16) -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_32x16) -MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad32x16_avg) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad32x16x4d) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_32x16x4d) - -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad16x32) -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_16x32) -MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad16x32_avg) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad16x32x4d) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_16x32x4d) - -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad64x32) -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_64x32) -MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad64x32_avg) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad64x32x4d) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_64x32x4d) - -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad32x64) -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_32x64) -MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad32x64_avg) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad32x64x4d) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_32x64x4d) - -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad32x32) -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_32x32) -MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad32x32_avg) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad32x32x4d) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_32x32x4d) - -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad64x64) -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_64x64) -MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad64x64_avg) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad64x64x4d) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_64x64x4d) - -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad16x16) -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_16x16) -MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad16x16_avg) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad16x16x4d) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_16x16x4d) - -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad16x8) -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_16x8) -MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad16x8_avg) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad16x8x4d) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_16x8x4d) - -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad8x16) -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_8x16) -MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad8x16_avg) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad8x16x4d) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_8x16x4d) - -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad8x8) -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_8x8) -MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad8x8_avg) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad8x8x4d) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_8x8x4d) - -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad8x4) -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_8x4) -MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad8x4_avg) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad8x4x4d) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_8x4x4d) - -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad4x8) -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_4x8) -MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad4x8_avg) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad4x8x4d) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_4x8x4d) - -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad4x4) -MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_4x4) -MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad4x4_avg) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad4x4x4d) -MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_4x4x4d) - -static void highbd_set_var_fns(VP9_COMP *const cpi) { - VP9_COMMON *const cm = &cpi->common; - if (cm->use_highbitdepth) { - switch (cm->bit_depth) { - case VPX_BITS_8: - HIGHBD_BFP( - BLOCK_32X16, vpx_highbd_sad32x16_bits8, - vpx_highbd_sad_skip_32x16_bits8, vpx_highbd_sad32x16_avg_bits8, - vpx_highbd_8_variance32x16, vpx_highbd_8_sub_pixel_variance32x16, - vpx_highbd_8_sub_pixel_avg_variance32x16, - vpx_highbd_sad32x16x4d_bits8, vpx_highbd_sad_skip_32x16x4d_bits8) - - HIGHBD_BFP( - BLOCK_16X32, vpx_highbd_sad16x32_bits8, - vpx_highbd_sad_skip_16x32_bits8, vpx_highbd_sad16x32_avg_bits8, - vpx_highbd_8_variance16x32, vpx_highbd_8_sub_pixel_variance16x32, - vpx_highbd_8_sub_pixel_avg_variance16x32, - vpx_highbd_sad16x32x4d_bits8, vpx_highbd_sad_skip_16x32x4d_bits8) - - HIGHBD_BFP( - BLOCK_64X32, vpx_highbd_sad64x32_bits8, - vpx_highbd_sad_skip_64x32_bits8, vpx_highbd_sad64x32_avg_bits8, - vpx_highbd_8_variance64x32, vpx_highbd_8_sub_pixel_variance64x32, - vpx_highbd_8_sub_pixel_avg_variance64x32, - vpx_highbd_sad64x32x4d_bits8, vpx_highbd_sad_skip_64x32x4d_bits8) - - HIGHBD_BFP( - BLOCK_32X64, vpx_highbd_sad32x64_bits8, - vpx_highbd_sad_skip_32x64_bits8, vpx_highbd_sad32x64_avg_bits8, - vpx_highbd_8_variance32x64, vpx_highbd_8_sub_pixel_variance32x64, - vpx_highbd_8_sub_pixel_avg_variance32x64, - vpx_highbd_sad32x64x4d_bits8, vpx_highbd_sad_skip_32x64x4d_bits8) - - HIGHBD_BFP( - BLOCK_32X32, vpx_highbd_sad32x32_bits8, - vpx_highbd_sad_skip_32x32_bits8, vpx_highbd_sad32x32_avg_bits8, - vpx_highbd_8_variance32x32, vpx_highbd_8_sub_pixel_variance32x32, - vpx_highbd_8_sub_pixel_avg_variance32x32, - vpx_highbd_sad32x32x4d_bits8, vpx_highbd_sad_skip_32x32x4d_bits8) - - HIGHBD_BFP( - BLOCK_64X64, vpx_highbd_sad64x64_bits8, - vpx_highbd_sad_skip_64x64_bits8, vpx_highbd_sad64x64_avg_bits8, - vpx_highbd_8_variance64x64, vpx_highbd_8_sub_pixel_variance64x64, - vpx_highbd_8_sub_pixel_avg_variance64x64, - vpx_highbd_sad64x64x4d_bits8, vpx_highbd_sad_skip_64x64x4d_bits8) - - HIGHBD_BFP( - BLOCK_16X16, vpx_highbd_sad16x16_bits8, - vpx_highbd_sad_skip_16x16_bits8, vpx_highbd_sad16x16_avg_bits8, - vpx_highbd_8_variance16x16, vpx_highbd_8_sub_pixel_variance16x16, - vpx_highbd_8_sub_pixel_avg_variance16x16, - vpx_highbd_sad16x16x4d_bits8, vpx_highbd_sad_skip_16x16x4d_bits8) - - HIGHBD_BFP( - BLOCK_16X8, vpx_highbd_sad16x8_bits8, - vpx_highbd_sad_skip_16x8_bits8, vpx_highbd_sad16x8_avg_bits8, - vpx_highbd_8_variance16x8, vpx_highbd_8_sub_pixel_variance16x8, - vpx_highbd_8_sub_pixel_avg_variance16x8, - vpx_highbd_sad16x8x4d_bits8, vpx_highbd_sad_skip_16x8x4d_bits8) - - HIGHBD_BFP( - BLOCK_8X16, vpx_highbd_sad8x16_bits8, - vpx_highbd_sad_skip_8x16_bits8, vpx_highbd_sad8x16_avg_bits8, - vpx_highbd_8_variance8x16, vpx_highbd_8_sub_pixel_variance8x16, - vpx_highbd_8_sub_pixel_avg_variance8x16, - vpx_highbd_sad8x16x4d_bits8, vpx_highbd_sad_skip_8x16x4d_bits8) - - HIGHBD_BFP(BLOCK_8X8, vpx_highbd_sad8x8_bits8, - vpx_highbd_sad_skip_8x8_bits8, vpx_highbd_sad8x8_avg_bits8, - vpx_highbd_8_variance8x8, vpx_highbd_8_sub_pixel_variance8x8, - vpx_highbd_8_sub_pixel_avg_variance8x8, - vpx_highbd_sad8x8x4d_bits8, vpx_highbd_sad_skip_8x8x4d_bits8) - - HIGHBD_BFP(BLOCK_8X4, vpx_highbd_sad8x4_bits8, - vpx_highbd_sad_skip_8x4_bits8, vpx_highbd_sad8x4_avg_bits8, - vpx_highbd_8_variance8x4, vpx_highbd_8_sub_pixel_variance8x4, - vpx_highbd_8_sub_pixel_avg_variance8x4, - vpx_highbd_sad8x4x4d_bits8, vpx_highbd_sad_skip_8x4x4d_bits8) - - HIGHBD_BFP(BLOCK_4X8, vpx_highbd_sad4x8_bits8, - vpx_highbd_sad_skip_4x8_bits8, vpx_highbd_sad4x8_avg_bits8, - vpx_highbd_8_variance4x8, vpx_highbd_8_sub_pixel_variance4x8, - vpx_highbd_8_sub_pixel_avg_variance4x8, - vpx_highbd_sad4x8x4d_bits8, vpx_highbd_sad_skip_4x8x4d_bits8) - - HIGHBD_BFP(BLOCK_4X4, vpx_highbd_sad4x4_bits8, - vpx_highbd_sad_skip_4x4_bits8, vpx_highbd_sad4x4_avg_bits8, - vpx_highbd_8_variance4x4, vpx_highbd_8_sub_pixel_variance4x4, - vpx_highbd_8_sub_pixel_avg_variance4x4, - vpx_highbd_sad4x4x4d_bits8, vpx_highbd_sad_skip_4x4x4d_bits8) - break; - - case VPX_BITS_10: - HIGHBD_BFP( - BLOCK_32X16, vpx_highbd_sad32x16_bits10, - vpx_highbd_sad_skip_32x16_bits10, vpx_highbd_sad32x16_avg_bits10, - vpx_highbd_10_variance32x16, vpx_highbd_10_sub_pixel_variance32x16, - vpx_highbd_10_sub_pixel_avg_variance32x16, - vpx_highbd_sad32x16x4d_bits10, vpx_highbd_sad_skip_32x16x4d_bits10) - - HIGHBD_BFP( - BLOCK_16X32, vpx_highbd_sad16x32_bits10, - vpx_highbd_sad_skip_16x32_bits10, vpx_highbd_sad16x32_avg_bits10, - vpx_highbd_10_variance16x32, vpx_highbd_10_sub_pixel_variance16x32, - vpx_highbd_10_sub_pixel_avg_variance16x32, - vpx_highbd_sad16x32x4d_bits10, vpx_highbd_sad_skip_16x32x4d_bits10) - - HIGHBD_BFP( - BLOCK_64X32, vpx_highbd_sad64x32_bits10, - vpx_highbd_sad_skip_64x32_bits10, vpx_highbd_sad64x32_avg_bits10, - vpx_highbd_10_variance64x32, vpx_highbd_10_sub_pixel_variance64x32, - vpx_highbd_10_sub_pixel_avg_variance64x32, - vpx_highbd_sad64x32x4d_bits10, vpx_highbd_sad_skip_64x32x4d_bits10) - - HIGHBD_BFP( - BLOCK_32X64, vpx_highbd_sad32x64_bits10, - vpx_highbd_sad_skip_32x64_bits10, vpx_highbd_sad32x64_avg_bits10, - vpx_highbd_10_variance32x64, vpx_highbd_10_sub_pixel_variance32x64, - vpx_highbd_10_sub_pixel_avg_variance32x64, - vpx_highbd_sad32x64x4d_bits10, vpx_highbd_sad_skip_32x64x4d_bits10) - - HIGHBD_BFP( - BLOCK_32X32, vpx_highbd_sad32x32_bits10, - vpx_highbd_sad_skip_32x32_bits10, vpx_highbd_sad32x32_avg_bits10, - vpx_highbd_10_variance32x32, vpx_highbd_10_sub_pixel_variance32x32, - vpx_highbd_10_sub_pixel_avg_variance32x32, - vpx_highbd_sad32x32x4d_bits10, vpx_highbd_sad_skip_32x32x4d_bits10) - - HIGHBD_BFP( - BLOCK_64X64, vpx_highbd_sad64x64_bits10, - vpx_highbd_sad_skip_64x64_bits10, vpx_highbd_sad64x64_avg_bits10, - vpx_highbd_10_variance64x64, vpx_highbd_10_sub_pixel_variance64x64, - vpx_highbd_10_sub_pixel_avg_variance64x64, - vpx_highbd_sad64x64x4d_bits10, vpx_highbd_sad_skip_64x64x4d_bits10) - - HIGHBD_BFP( - BLOCK_16X16, vpx_highbd_sad16x16_bits10, - vpx_highbd_sad_skip_16x16_bits10, vpx_highbd_sad16x16_avg_bits10, - vpx_highbd_10_variance16x16, vpx_highbd_10_sub_pixel_variance16x16, - vpx_highbd_10_sub_pixel_avg_variance16x16, - vpx_highbd_sad16x16x4d_bits10, vpx_highbd_sad_skip_16x16x4d_bits10) - - HIGHBD_BFP( - BLOCK_16X8, vpx_highbd_sad16x8_bits10, - vpx_highbd_sad_skip_16x8_bits10, vpx_highbd_sad16x8_avg_bits10, - vpx_highbd_10_variance16x8, vpx_highbd_10_sub_pixel_variance16x8, - vpx_highbd_10_sub_pixel_avg_variance16x8, - vpx_highbd_sad16x8x4d_bits10, vpx_highbd_sad_skip_16x8x4d_bits10) - - HIGHBD_BFP( - BLOCK_8X16, vpx_highbd_sad8x16_bits10, - vpx_highbd_sad_skip_8x16_bits10, vpx_highbd_sad8x16_avg_bits10, - vpx_highbd_10_variance8x16, vpx_highbd_10_sub_pixel_variance8x16, - vpx_highbd_10_sub_pixel_avg_variance8x16, - vpx_highbd_sad8x16x4d_bits10, vpx_highbd_sad_skip_8x16x4d_bits10) - - HIGHBD_BFP( - BLOCK_8X8, vpx_highbd_sad8x8_bits10, vpx_highbd_sad_skip_8x8_bits10, - vpx_highbd_sad8x8_avg_bits10, vpx_highbd_10_variance8x8, - vpx_highbd_10_sub_pixel_variance8x8, - vpx_highbd_10_sub_pixel_avg_variance8x8, - vpx_highbd_sad8x8x4d_bits10, vpx_highbd_sad_skip_8x8x4d_bits10) - - HIGHBD_BFP( - BLOCK_8X4, vpx_highbd_sad8x4_bits10, vpx_highbd_sad_skip_8x4_bits10, - vpx_highbd_sad8x4_avg_bits10, vpx_highbd_10_variance8x4, - vpx_highbd_10_sub_pixel_variance8x4, - vpx_highbd_10_sub_pixel_avg_variance8x4, - vpx_highbd_sad8x4x4d_bits10, vpx_highbd_sad_skip_8x4x4d_bits10) - - HIGHBD_BFP( - BLOCK_4X8, vpx_highbd_sad4x8_bits10, vpx_highbd_sad_skip_4x8_bits10, - vpx_highbd_sad4x8_avg_bits10, vpx_highbd_10_variance4x8, - vpx_highbd_10_sub_pixel_variance4x8, - vpx_highbd_10_sub_pixel_avg_variance4x8, - vpx_highbd_sad4x8x4d_bits10, vpx_highbd_sad_skip_4x8x4d_bits10) - - HIGHBD_BFP( - BLOCK_4X4, vpx_highbd_sad4x4_bits10, vpx_highbd_sad_skip_4x4_bits10, - vpx_highbd_sad4x4_avg_bits10, vpx_highbd_10_variance4x4, - vpx_highbd_10_sub_pixel_variance4x4, - vpx_highbd_10_sub_pixel_avg_variance4x4, - vpx_highbd_sad4x4x4d_bits10, vpx_highbd_sad_skip_4x4x4d_bits10) - break; - - default: - assert(cm->bit_depth == VPX_BITS_12); - HIGHBD_BFP( - BLOCK_32X16, vpx_highbd_sad32x16_bits12, - vpx_highbd_sad_skip_32x16_bits12, vpx_highbd_sad32x16_avg_bits12, - vpx_highbd_12_variance32x16, vpx_highbd_12_sub_pixel_variance32x16, - vpx_highbd_12_sub_pixel_avg_variance32x16, - vpx_highbd_sad32x16x4d_bits12, vpx_highbd_sad_skip_32x16x4d_bits12) - - HIGHBD_BFP( - BLOCK_16X32, vpx_highbd_sad16x32_bits12, - vpx_highbd_sad_skip_16x32_bits12, vpx_highbd_sad16x32_avg_bits12, - vpx_highbd_12_variance16x32, vpx_highbd_12_sub_pixel_variance16x32, - vpx_highbd_12_sub_pixel_avg_variance16x32, - vpx_highbd_sad16x32x4d_bits12, vpx_highbd_sad_skip_16x32x4d_bits12) - - HIGHBD_BFP( - BLOCK_64X32, vpx_highbd_sad64x32_bits12, - vpx_highbd_sad_skip_64x32_bits12, vpx_highbd_sad64x32_avg_bits12, - vpx_highbd_12_variance64x32, vpx_highbd_12_sub_pixel_variance64x32, - vpx_highbd_12_sub_pixel_avg_variance64x32, - vpx_highbd_sad64x32x4d_bits12, vpx_highbd_sad_skip_64x32x4d_bits12) - - HIGHBD_BFP( - BLOCK_32X64, vpx_highbd_sad32x64_bits12, - vpx_highbd_sad_skip_32x64_bits12, vpx_highbd_sad32x64_avg_bits12, - vpx_highbd_12_variance32x64, vpx_highbd_12_sub_pixel_variance32x64, - vpx_highbd_12_sub_pixel_avg_variance32x64, - vpx_highbd_sad32x64x4d_bits12, vpx_highbd_sad_skip_32x64x4d_bits12) - - HIGHBD_BFP( - BLOCK_32X32, vpx_highbd_sad32x32_bits12, - vpx_highbd_sad_skip_32x32_bits12, vpx_highbd_sad32x32_avg_bits12, - vpx_highbd_12_variance32x32, vpx_highbd_12_sub_pixel_variance32x32, - vpx_highbd_12_sub_pixel_avg_variance32x32, - vpx_highbd_sad32x32x4d_bits12, vpx_highbd_sad_skip_32x32x4d_bits12) - - HIGHBD_BFP( - BLOCK_64X64, vpx_highbd_sad64x64_bits12, - vpx_highbd_sad_skip_64x64_bits12, vpx_highbd_sad64x64_avg_bits12, - vpx_highbd_12_variance64x64, vpx_highbd_12_sub_pixel_variance64x64, - vpx_highbd_12_sub_pixel_avg_variance64x64, - vpx_highbd_sad64x64x4d_bits12, vpx_highbd_sad_skip_64x64x4d_bits12) - - HIGHBD_BFP( - BLOCK_16X16, vpx_highbd_sad16x16_bits12, - vpx_highbd_sad_skip_16x16_bits12, vpx_highbd_sad16x16_avg_bits12, - vpx_highbd_12_variance16x16, vpx_highbd_12_sub_pixel_variance16x16, - vpx_highbd_12_sub_pixel_avg_variance16x16, - vpx_highbd_sad16x16x4d_bits12, vpx_highbd_sad_skip_16x16x4d_bits12) - - HIGHBD_BFP( - BLOCK_16X8, vpx_highbd_sad16x8_bits12, - vpx_highbd_sad_skip_16x8_bits12, vpx_highbd_sad16x8_avg_bits12, - vpx_highbd_12_variance16x8, vpx_highbd_12_sub_pixel_variance16x8, - vpx_highbd_12_sub_pixel_avg_variance16x8, - vpx_highbd_sad16x8x4d_bits12, vpx_highbd_sad_skip_16x8x4d_bits12) - - HIGHBD_BFP( - BLOCK_8X16, vpx_highbd_sad8x16_bits12, - vpx_highbd_sad_skip_8x16_bits12, vpx_highbd_sad8x16_avg_bits12, - vpx_highbd_12_variance8x16, vpx_highbd_12_sub_pixel_variance8x16, - vpx_highbd_12_sub_pixel_avg_variance8x16, - vpx_highbd_sad8x16x4d_bits12, vpx_highbd_sad_skip_8x16x4d_bits12) - - HIGHBD_BFP( - BLOCK_8X8, vpx_highbd_sad8x8_bits12, vpx_highbd_sad_skip_8x8_bits12, - vpx_highbd_sad8x8_avg_bits12, vpx_highbd_12_variance8x8, - vpx_highbd_12_sub_pixel_variance8x8, - vpx_highbd_12_sub_pixel_avg_variance8x8, - vpx_highbd_sad8x8x4d_bits12, vpx_highbd_sad_skip_8x8x4d_bits12) - - HIGHBD_BFP( - BLOCK_8X4, vpx_highbd_sad8x4_bits12, vpx_highbd_sad_skip_8x4_bits12, - vpx_highbd_sad8x4_avg_bits12, vpx_highbd_12_variance8x4, - vpx_highbd_12_sub_pixel_variance8x4, - vpx_highbd_12_sub_pixel_avg_variance8x4, - vpx_highbd_sad8x4x4d_bits12, vpx_highbd_sad_skip_8x4x4d_bits12) - - HIGHBD_BFP( - BLOCK_4X8, vpx_highbd_sad4x8_bits12, vpx_highbd_sad_skip_4x8_bits12, - vpx_highbd_sad4x8_avg_bits12, vpx_highbd_12_variance4x8, - vpx_highbd_12_sub_pixel_variance4x8, - vpx_highbd_12_sub_pixel_avg_variance4x8, - vpx_highbd_sad4x8x4d_bits12, vpx_highbd_sad_skip_4x8x4d_bits12) - - HIGHBD_BFP( - BLOCK_4X4, vpx_highbd_sad4x4_bits12, vpx_highbd_sad_skip_4x4_bits12, - vpx_highbd_sad4x4_avg_bits12, vpx_highbd_12_variance4x4, - vpx_highbd_12_sub_pixel_variance4x4, - vpx_highbd_12_sub_pixel_avg_variance4x4, - vpx_highbd_sad4x4x4d_bits12, vpx_highbd_sad_skip_4x4x4d_bits12) - break; - } - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static void realloc_segmentation_maps(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - - // Create the encoder segmentation map and set all entries to 0 - vpx_free(cpi->segmentation_map); - CHECK_MEM_ERROR(&cm->error, cpi->segmentation_map, - vpx_calloc(cm->mi_rows * cm->mi_cols, 1)); - - // Create a map used for cyclic background refresh. - if (cpi->cyclic_refresh) vp9_cyclic_refresh_free(cpi->cyclic_refresh); - CHECK_MEM_ERROR(&cm->error, cpi->cyclic_refresh, - vp9_cyclic_refresh_alloc(cm->mi_rows, cm->mi_cols)); - - // Create a map used to mark inactive areas. - vpx_free(cpi->active_map.map); - CHECK_MEM_ERROR(&cm->error, cpi->active_map.map, - vpx_calloc(cm->mi_rows * cm->mi_cols, 1)); - - // And a place holder structure is the coding context - // for use if we want to save and restore it - vpx_free(cpi->coding_context.last_frame_seg_map_copy); - CHECK_MEM_ERROR(&cm->error, cpi->coding_context.last_frame_seg_map_copy, - vpx_calloc(cm->mi_rows * cm->mi_cols, 1)); -} - -static void alloc_copy_partition_data(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - if (cpi->prev_partition == NULL) { - CHECK_MEM_ERROR(&cm->error, cpi->prev_partition, - (BLOCK_SIZE *)vpx_calloc(cm->mi_stride * cm->mi_rows, - sizeof(*cpi->prev_partition))); - } - if (cpi->prev_segment_id == NULL) { - CHECK_MEM_ERROR( - &cm->error, cpi->prev_segment_id, - (int8_t *)vpx_calloc((cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1), - sizeof(*cpi->prev_segment_id))); - } - if (cpi->prev_variance_low == NULL) { - CHECK_MEM_ERROR(&cm->error, cpi->prev_variance_low, - (uint8_t *)vpx_calloc( - (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1) * 25, - sizeof(*cpi->prev_variance_low))); - } - if (cpi->copied_frame_cnt == NULL) { - CHECK_MEM_ERROR( - &cm->error, cpi->copied_frame_cnt, - (uint8_t *)vpx_calloc((cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1), - sizeof(*cpi->copied_frame_cnt))); - } -} - -static void free_copy_partition_data(VP9_COMP *cpi) { - vpx_free(cpi->prev_partition); - cpi->prev_partition = NULL; - vpx_free(cpi->prev_segment_id); - cpi->prev_segment_id = NULL; - vpx_free(cpi->prev_variance_low); - cpi->prev_variance_low = NULL; - vpx_free(cpi->copied_frame_cnt); - cpi->copied_frame_cnt = NULL; -} - -void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) { - VP9_COMMON *const cm = &cpi->common; - RATE_CONTROL *const rc = &cpi->rc; - int last_w = cpi->oxcf.width; - int last_h = cpi->oxcf.height; - - vp9_init_quantizer(cpi); - if (cm->profile != oxcf->profile) cm->profile = oxcf->profile; - cm->bit_depth = oxcf->bit_depth; - cm->color_space = oxcf->color_space; - cm->color_range = oxcf->color_range; - - cpi->target_level = oxcf->target_level; - cpi->keep_level_stats = oxcf->target_level != LEVEL_MAX; - set_level_constraint(&cpi->level_constraint, - get_level_index(cpi->target_level)); - - if (cm->profile <= PROFILE_1) - assert(cm->bit_depth == VPX_BITS_8); - else - assert(cm->bit_depth > VPX_BITS_8); - - cpi->oxcf = *oxcf; -#if CONFIG_VP9_HIGHBITDEPTH - cpi->td.mb.e_mbd.bd = (int)cm->bit_depth; -#endif // CONFIG_VP9_HIGHBITDEPTH - - if ((oxcf->pass == 0) && (oxcf->rc_mode == VPX_Q)) { - rc->baseline_gf_interval = FIXED_GF_INTERVAL; - } else { - rc->baseline_gf_interval = (MIN_GF_INTERVAL + MAX_GF_INTERVAL) / 2; - } - - cpi->refresh_golden_frame = 0; - cpi->refresh_last_frame = 1; - cm->refresh_frame_context = 1; - cm->reset_frame_context = 0; - - vp9_reset_segment_features(&cm->seg); - vp9_set_high_precision_mv(cpi, 0); - - { - int i; - - for (i = 0; i < MAX_SEGMENTS; i++) - cpi->segment_encode_breakout[i] = cpi->oxcf.encode_breakout; - } - cpi->encode_breakout = cpi->oxcf.encode_breakout; - - vp9_set_rc_buffer_sizes(cpi); - - // Set up frame rate and related parameters rate control values. - vp9_new_framerate(cpi, cpi->framerate); - - // Set absolute upper and lower quality limits - rc->worst_quality = cpi->oxcf.worst_allowed_q; - rc->best_quality = cpi->oxcf.best_allowed_q; - - cm->interp_filter = cpi->sf.default_interp_filter; - - if (cpi->oxcf.render_width > 0 && cpi->oxcf.render_height > 0) { - cm->render_width = cpi->oxcf.render_width; - cm->render_height = cpi->oxcf.render_height; - } else { - cm->render_width = cpi->oxcf.width; - cm->render_height = cpi->oxcf.height; - } - if (last_w != cpi->oxcf.width || last_h != cpi->oxcf.height) { - cm->width = cpi->oxcf.width; - cm->height = cpi->oxcf.height; - cpi->external_resize = 1; - } - - int new_mi_size = 0; - vp9_set_mb_mi(cm, cm->width, cm->height); - new_mi_size = cm->mi_stride * calc_mi_size(cm->mi_rows); - if (cm->mi_alloc_size < new_mi_size) { - vp9_free_context_buffers(cm); - vp9_free_pc_tree(&cpi->td); - vpx_free(cpi->mbmi_ext_base); - alloc_compressor_data(cpi); - realloc_segmentation_maps(cpi); - cpi->initial_width = cpi->initial_height = 0; - cpi->external_resize = 0; - } else if (cm->mi_alloc_size == new_mi_size && - (cpi->oxcf.width > last_w || cpi->oxcf.height > last_h)) { - if (vp9_alloc_loop_filter(cm)) { - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate loop filter data"); - } - } - - if (cm->current_video_frame == 0 || last_w != cpi->oxcf.width || - last_h != cpi->oxcf.height) - update_frame_size(cpi); - - if (last_w != cpi->oxcf.width || last_h != cpi->oxcf.height) { - vpx_free(cpi->consec_zero_mv); - CHECK_MEM_ERROR( - &cm->error, cpi->consec_zero_mv, - vpx_calloc(cm->mi_rows * cm->mi_cols, sizeof(*cpi->consec_zero_mv))); - - vpx_free(cpi->skin_map); - CHECK_MEM_ERROR( - &cm->error, cpi->skin_map, - vpx_calloc(cm->mi_rows * cm->mi_cols, sizeof(*cpi->skin_map))); - - free_copy_partition_data(cpi); - alloc_copy_partition_data(cpi); - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) - vp9_cyclic_refresh_reset_resize(cpi); - rc->rc_1_frame = 0; - rc->rc_2_frame = 0; - } - - if ((cpi->svc.number_temporal_layers > 1) || - ((cpi->svc.number_temporal_layers > 1 || - cpi->svc.number_spatial_layers > 1) && - cpi->oxcf.pass != 1)) { - vp9_update_layer_context_change_config(cpi, - (int)cpi->oxcf.target_bandwidth); - } - - vp9_check_reset_rc_flag(cpi); - - cpi->alt_ref_source = NULL; - rc->is_src_frame_alt_ref = 0; - -#if 0 - // Experimental RD Code - cpi->frame_distortion = 0; - cpi->last_frame_distortion = 0; -#endif - - set_tile_limits(cpi); - - cpi->ext_refresh_frame_flags_pending = 0; - cpi->ext_refresh_frame_context_pending = 0; - -#if CONFIG_VP9_HIGHBITDEPTH - highbd_set_var_fns(cpi); -#endif - - vp9_set_row_mt(cpi); -} - -/*********************************************************************** - * Read before modifying 'cal_nmvjointsadcost' or 'cal_nmvsadcosts' * - *********************************************************************** - * The following 2 functions ('cal_nmvjointsadcost' and * - * 'cal_nmvsadcosts') are used to calculate cost lookup tables * - * used by 'vp9_diamond_search_sad'. The C implementation of the * - * function is generic, but the NEON intrinsics optimised version * - * relies on the following properties of the computed tables: * - * For cal_nmvjointsadcost: * - * - mvjointsadcost[1] == mvjointsadcost[2] == mvjointsadcost[3] * - * For cal_nmvsadcosts: * - * - For all i: mvsadcost[0][i] == mvsadcost[1][i] * - * (Equal costs for both components) * - * - For all i: mvsadcost[0][i] == mvsadcost[0][-i] * - * (Cost function is even) * - * If these do not hold, then the NEON optimised version of the * - * 'vp9_diamond_search_sad' function cannot be used as it is, in which * - * case you can revert to using the C function instead. * - ***********************************************************************/ - -static void cal_nmvjointsadcost(int *mvjointsadcost) { - /********************************************************************* - * Warning: Read the comments above before modifying this function * - *********************************************************************/ - mvjointsadcost[0] = 600; - mvjointsadcost[1] = 300; - mvjointsadcost[2] = 300; - mvjointsadcost[3] = 300; -} - -static void cal_nmvsadcosts(int *mvsadcost[2]) { - /********************************************************************* - * Warning: Read the comments above before modifying this function * - *********************************************************************/ - int i = 1; - - mvsadcost[0][0] = 0; - mvsadcost[1][0] = 0; - - do { - double z = 256 * (2 * (log2f(8 * i) + .6)); - mvsadcost[0][i] = (int)z; - mvsadcost[1][i] = (int)z; - mvsadcost[0][-i] = (int)z; - mvsadcost[1][-i] = (int)z; - } while (++i <= MV_MAX); -} - -static void cal_nmvsadcosts_hp(int *mvsadcost[2]) { - int i = 1; - - mvsadcost[0][0] = 0; - mvsadcost[1][0] = 0; - - do { - double z = 256 * (2 * (log2f(8 * i) + .6)); - mvsadcost[0][i] = (int)z; - mvsadcost[1][i] = (int)z; - mvsadcost[0][-i] = (int)z; - mvsadcost[1][-i] = (int)z; - } while (++i <= MV_MAX); -} - -static void init_ref_frame_bufs(VP9_COMMON *cm) { - int i; - BufferPool *const pool = cm->buffer_pool; - cm->new_fb_idx = INVALID_IDX; - for (i = 0; i < REF_FRAMES; ++i) { - cm->ref_frame_map[i] = INVALID_IDX; - } - for (i = 0; i < FRAME_BUFFERS; ++i) { - pool->frame_bufs[i].ref_count = 0; - } -} - -static void update_initial_width(VP9_COMP *cpi, int use_highbitdepth, - int subsampling_x, int subsampling_y) { - VP9_COMMON *const cm = &cpi->common; -#if !CONFIG_VP9_HIGHBITDEPTH - (void)use_highbitdepth; - assert(use_highbitdepth == 0); -#endif - - if (!cpi->initial_width || -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth != use_highbitdepth || -#endif - cm->subsampling_x != subsampling_x || - cm->subsampling_y != subsampling_y) { - cm->subsampling_x = subsampling_x; - cm->subsampling_y = subsampling_y; -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth = use_highbitdepth; -#endif - alloc_util_frame_buffers(cpi); - cpi->initial_width = cm->width; - cpi->initial_height = cm->height; - cpi->initial_mbs = cm->MBs; - } -} - -// TODO(angiebird): Check whether we can move this function to vpx_image.c -static INLINE void vpx_img_chroma_subsampling(vpx_img_fmt_t fmt, - unsigned int *subsampling_x, - unsigned int *subsampling_y) { - switch (fmt) { - case VPX_IMG_FMT_I420: - case VPX_IMG_FMT_YV12: - case VPX_IMG_FMT_NV12: - case VPX_IMG_FMT_I422: - case VPX_IMG_FMT_I42016: - case VPX_IMG_FMT_I42216: *subsampling_x = 1; break; - default: *subsampling_x = 0; break; - } - - switch (fmt) { - case VPX_IMG_FMT_I420: - case VPX_IMG_FMT_I440: - case VPX_IMG_FMT_YV12: - case VPX_IMG_FMT_NV12: - case VPX_IMG_FMT_I42016: - case VPX_IMG_FMT_I44016: *subsampling_y = 1; break; - default: *subsampling_y = 0; break; - } -} - -// TODO(angiebird): Check whether we can move this function to vpx_image.c -static INLINE int vpx_img_use_highbitdepth(vpx_img_fmt_t fmt) { - return fmt & VPX_IMG_FMT_HIGHBITDEPTH; -} - -#if CONFIG_VP9_TEMPORAL_DENOISING -static void setup_denoiser_buffer(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - if (cpi->oxcf.noise_sensitivity > 0 && - !cpi->denoiser.frame_buffer_initialized) { - if (vp9_denoiser_alloc(cm, &cpi->svc, &cpi->denoiser, cpi->use_svc, - cpi->oxcf.noise_sensitivity, cm->width, cm->height, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS)) - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate denoiser"); - } -} -#endif - -void vp9_update_compressor_with_img_fmt(VP9_COMP *cpi, vpx_img_fmt_t img_fmt) { - const VP9EncoderConfig *oxcf = &cpi->oxcf; - unsigned int subsampling_x, subsampling_y; - const int use_highbitdepth = vpx_img_use_highbitdepth(img_fmt); - vpx_img_chroma_subsampling(img_fmt, &subsampling_x, &subsampling_y); - - update_initial_width(cpi, use_highbitdepth, subsampling_x, subsampling_y); -#if CONFIG_VP9_TEMPORAL_DENOISING - setup_denoiser_buffer(cpi); -#endif - - assert(cpi->lookahead == NULL); - cpi->lookahead = vp9_lookahead_init(oxcf->width, oxcf->height, subsampling_x, - subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - use_highbitdepth, -#endif - oxcf->lag_in_frames); - alloc_raw_frame_buffers(cpi); -} - -VP9_COMP *vp9_create_compressor(const VP9EncoderConfig *oxcf, - BufferPool *const pool) { - unsigned int i; - VP9_COMP *volatile const cpi = vpx_memalign(32, sizeof(*cpi)); - VP9_COMMON *volatile const cm = cpi != NULL ? &cpi->common : NULL; - - if (!cm) return NULL; - - vp9_zero(*cpi); - - if (setjmp(cm->error.jmp)) { - cm->error.setjmp = 0; - vp9_remove_compressor(cpi); - return 0; - } - - cm->error.setjmp = 1; - cm->alloc_mi = vp9_enc_alloc_mi; - cm->free_mi = vp9_enc_free_mi; - cm->setup_mi = vp9_enc_setup_mi; - - CHECK_MEM_ERROR(&cm->error, cm->fc, - (FRAME_CONTEXT *)vpx_calloc(1, sizeof(*cm->fc))); - CHECK_MEM_ERROR( - &cm->error, cm->frame_contexts, - (FRAME_CONTEXT *)vpx_calloc(FRAME_CONTEXTS, sizeof(*cm->frame_contexts))); - - cpi->compute_frame_low_motion_onepass = 1; - cpi->use_svc = 0; - cpi->resize_state = ORIG; - cpi->external_resize = 0; - cpi->resize_avg_qp = 0; - cpi->resize_buffer_underflow = 0; - cpi->use_skin_detection = 0; - cpi->common.buffer_pool = pool; - init_ref_frame_bufs(cm); - - cpi->force_update_segmentation = 0; - - init_config(cpi, oxcf); - cpi->frame_info = vp9_get_frame_info(oxcf); - - vp9_rc_init(&cpi->oxcf, oxcf->pass, &cpi->rc); - vp9_init_rd_parameters(cpi); - - init_frame_indexes(cm); - cpi->tile_data = NULL; - - realloc_segmentation_maps(cpi); - - CHECK_MEM_ERROR( - &cm->error, cpi->skin_map, - vpx_calloc(cm->mi_rows * cm->mi_cols, sizeof(*cpi->skin_map))); - -#if !CONFIG_REALTIME_ONLY - CHECK_MEM_ERROR(&cm->error, cpi->alt_ref_aq, vp9_alt_ref_aq_create()); -#endif - - CHECK_MEM_ERROR( - &cm->error, cpi->consec_zero_mv, - vpx_calloc(cm->mi_rows * cm->mi_cols, sizeof(*cpi->consec_zero_mv))); - - CHECK_MEM_ERROR(&cm->error, cpi->nmvcosts[0], - vpx_calloc(MV_VALS, sizeof(*cpi->nmvcosts[0]))); - CHECK_MEM_ERROR(&cm->error, cpi->nmvcosts[1], - vpx_calloc(MV_VALS, sizeof(*cpi->nmvcosts[1]))); - CHECK_MEM_ERROR(&cm->error, cpi->nmvcosts_hp[0], - vpx_calloc(MV_VALS, sizeof(*cpi->nmvcosts_hp[0]))); - CHECK_MEM_ERROR(&cm->error, cpi->nmvcosts_hp[1], - vpx_calloc(MV_VALS, sizeof(*cpi->nmvcosts_hp[1]))); - CHECK_MEM_ERROR(&cm->error, cpi->nmvsadcosts[0], - vpx_calloc(MV_VALS, sizeof(*cpi->nmvsadcosts[0]))); - CHECK_MEM_ERROR(&cm->error, cpi->nmvsadcosts[1], - vpx_calloc(MV_VALS, sizeof(*cpi->nmvsadcosts[1]))); - CHECK_MEM_ERROR(&cm->error, cpi->nmvsadcosts_hp[0], - vpx_calloc(MV_VALS, sizeof(*cpi->nmvsadcosts_hp[0]))); - CHECK_MEM_ERROR(&cm->error, cpi->nmvsadcosts_hp[1], - vpx_calloc(MV_VALS, sizeof(*cpi->nmvsadcosts_hp[1]))); - - for (i = 0; i < (sizeof(cpi->mbgraph_stats) / sizeof(cpi->mbgraph_stats[0])); - i++) { - CHECK_MEM_ERROR( - &cm->error, cpi->mbgraph_stats[i].mb_stats, - vpx_calloc(cm->MBs * sizeof(*cpi->mbgraph_stats[i].mb_stats), 1)); - } - - cpi->refresh_alt_ref_frame = 0; - cpi->b_calculate_psnr = CONFIG_INTERNAL_STATS; - - init_level_info(&cpi->level_info); - init_level_constraint(&cpi->level_constraint); - -#if CONFIG_INTERNAL_STATS - cpi->b_calculate_blockiness = 1; - cpi->b_calculate_consistency = 1; - cpi->total_inconsistency = 0; - cpi->psnr.worst = 100.0; - cpi->worst_ssim = 100.0; - - cpi->count = 0; - cpi->bytes = 0; - - if (cpi->b_calculate_psnr) { - cpi->total_sq_error = 0; - cpi->total_samples = 0; - - cpi->totalp_sq_error = 0; - cpi->totalp_samples = 0; - - cpi->tot_recode_hits = 0; - cpi->summed_quality = 0; - cpi->summed_weights = 0; - cpi->summedp_quality = 0; - cpi->summedp_weights = 0; - } - - cpi->fastssim.worst = 100.0; - - cpi->psnrhvs.worst = 100.0; - - if (cpi->b_calculate_blockiness) { - cpi->total_blockiness = 0; - cpi->worst_blockiness = 0.0; - } - - if (cpi->b_calculate_consistency) { - CHECK_MEM_ERROR(&cm->error, cpi->ssim_vars, - vpx_calloc(cpi->common.mi_rows * cpi->common.mi_cols, - sizeof(*cpi->ssim_vars) * 4)); - cpi->worst_consistency = 100.0; - } else { - cpi->ssim_vars = NULL; - } - -#endif - - cpi->first_time_stamp_ever = INT64_MAX; - - /********************************************************************* - * Warning: Read the comments around 'cal_nmvjointsadcost' and * - * 'cal_nmvsadcosts' before modifying how these tables are computed. * - *********************************************************************/ - cal_nmvjointsadcost(cpi->td.mb.nmvjointsadcost); - cpi->td.mb.nmvcost[0] = &cpi->nmvcosts[0][MV_MAX]; - cpi->td.mb.nmvcost[1] = &cpi->nmvcosts[1][MV_MAX]; - cpi->td.mb.nmvsadcost[0] = &cpi->nmvsadcosts[0][MV_MAX]; - cpi->td.mb.nmvsadcost[1] = &cpi->nmvsadcosts[1][MV_MAX]; - cal_nmvsadcosts(cpi->td.mb.nmvsadcost); - - cpi->td.mb.nmvcost_hp[0] = &cpi->nmvcosts_hp[0][MV_MAX]; - cpi->td.mb.nmvcost_hp[1] = &cpi->nmvcosts_hp[1][MV_MAX]; - cpi->td.mb.nmvsadcost_hp[0] = &cpi->nmvsadcosts_hp[0][MV_MAX]; - cpi->td.mb.nmvsadcost_hp[1] = &cpi->nmvsadcosts_hp[1][MV_MAX]; - cal_nmvsadcosts_hp(cpi->td.mb.nmvsadcost_hp); - -#if CONFIG_VP9_TEMPORAL_DENOISING -#ifdef OUTPUT_YUV_DENOISED - yuv_denoised_file = fopen("denoised.yuv", "ab"); -#endif -#endif -#ifdef OUTPUT_YUV_SKINMAP - yuv_skinmap_file = fopen("skinmap.yuv", "wb"); -#endif -#ifdef OUTPUT_YUV_REC - yuv_rec_file = fopen("rec.yuv", "wb"); -#endif -#ifdef OUTPUT_YUV_SVC_SRC - yuv_svc_src[0] = fopen("svc_src_0.yuv", "wb"); - yuv_svc_src[1] = fopen("svc_src_1.yuv", "wb"); - yuv_svc_src[2] = fopen("svc_src_2.yuv", "wb"); -#endif - -#if 0 - framepsnr = fopen("framepsnr.stt", "a"); - kf_list = fopen("kf_list.stt", "w"); -#endif - - cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED; - - { - vpx_codec_err_t codec_status = vp9_extrc_init(&cpi->ext_ratectrl); - if (codec_status != VPX_CODEC_OK) { - vpx_internal_error(&cm->error, codec_status, "vp9_extrc_init() failed"); - } - } - -#if !CONFIG_REALTIME_ONLY - if (oxcf->pass == 1) { - vp9_init_first_pass(cpi); - } else if (oxcf->pass == 2) { - const size_t packet_sz = sizeof(FIRSTPASS_STATS); - const int packets = (int)(oxcf->two_pass_stats_in.sz / packet_sz); - - if (cpi->svc.number_spatial_layers > 1 || - cpi->svc.number_temporal_layers > 1) { - FIRSTPASS_STATS *const stats = oxcf->two_pass_stats_in.buf; - FIRSTPASS_STATS *stats_copy[VPX_SS_MAX_LAYERS] = { 0 }; - int n; - - for (n = 0; n < oxcf->ss_number_layers; ++n) { - FIRSTPASS_STATS *const last_packet_for_layer = - &stats[packets - oxcf->ss_number_layers + n]; - const int layer_id = (int)last_packet_for_layer->spatial_layer_id; - const int packets_in_layer = (int)last_packet_for_layer->count + 1; - if (layer_id >= 0 && layer_id < oxcf->ss_number_layers) { - int num_frames; - LAYER_CONTEXT *const lc = &cpi->svc.layer_context[layer_id]; - - vpx_free(lc->rc_twopass_stats_in.buf); - - lc->rc_twopass_stats_in.sz = packets_in_layer * packet_sz; - CHECK_MEM_ERROR(&cm->error, lc->rc_twopass_stats_in.buf, - vpx_malloc(lc->rc_twopass_stats_in.sz)); - lc->twopass.stats_in_start = lc->rc_twopass_stats_in.buf; - lc->twopass.stats_in = lc->twopass.stats_in_start; - lc->twopass.stats_in_end = - lc->twopass.stats_in_start + packets_in_layer - 1; - // Note the last packet is cumulative first pass stats. - // So the number of frames is packet number minus one - num_frames = packets_in_layer - 1; - fps_init_first_pass_info(&lc->twopass.first_pass_info, - lc->rc_twopass_stats_in.buf, num_frames); - stats_copy[layer_id] = lc->rc_twopass_stats_in.buf; - } - } - - for (n = 0; n < packets; ++n) { - const int layer_id = (int)stats[n].spatial_layer_id; - if (layer_id >= 0 && layer_id < oxcf->ss_number_layers && - stats_copy[layer_id] != NULL) { - *stats_copy[layer_id] = stats[n]; - ++stats_copy[layer_id]; - } - } - - vp9_init_second_pass_spatial_svc(cpi); - } else { - int num_frames; - - cpi->twopass.stats_in_start = oxcf->two_pass_stats_in.buf; - cpi->twopass.stats_in = cpi->twopass.stats_in_start; - cpi->twopass.stats_in_end = &cpi->twopass.stats_in[packets - 1]; - // Note the last packet is cumulative first pass stats. - // So the number of frames is packet number minus one - num_frames = packets - 1; - fps_init_first_pass_info(&cpi->twopass.first_pass_info, - oxcf->two_pass_stats_in.buf, num_frames); - - vp9_init_second_pass(cpi); - } - } -#endif // !CONFIG_REALTIME_ONLY - - cpi->mb_wiener_var_cols = 0; - cpi->mb_wiener_var_rows = 0; - cpi->mb_wiener_variance = NULL; - - vp9_set_speed_features_framesize_independent(cpi, oxcf->speed); - vp9_set_speed_features_framesize_dependent(cpi, oxcf->speed); - - { - const int bsize = BLOCK_16X16; - const int w = num_8x8_blocks_wide_lookup[bsize]; - const int h = num_8x8_blocks_high_lookup[bsize]; - const int num_cols = (cm->mi_cols + w - 1) / w; - const int num_rows = (cm->mi_rows + h - 1) / h; - CHECK_MEM_ERROR(&cm->error, cpi->mi_ssim_rdmult_scaling_factors, - vpx_calloc(num_rows * num_cols, - sizeof(*cpi->mi_ssim_rdmult_scaling_factors))); - } - - cpi->kmeans_data_arr_alloc = 0; -#if CONFIG_NON_GREEDY_MV - cpi->tpl_ready = 0; -#endif // CONFIG_NON_GREEDY_MV - for (i = 0; i < MAX_ARF_GOP_SIZE; ++i) { - cpi->tpl_stats[i].tpl_stats_ptr = NULL; - } - - // Allocate memory to store variances for a frame. - CHECK_MEM_ERROR(&cm->error, cpi->source_diff_var, - vpx_calloc(cm->MBs, sizeof(cpi->source_diff_var))); - cpi->source_var_thresh = 0; - cpi->frames_till_next_var_check = 0; -#define BFP(BT, SDF, SDSF, SDAF, VF, SVF, SVAF, SDX4DF, SDSX4DF) \ - cpi->fn_ptr[BT].sdf = SDF; \ - cpi->fn_ptr[BT].sdsf = SDSF; \ - cpi->fn_ptr[BT].sdaf = SDAF; \ - cpi->fn_ptr[BT].vf = VF; \ - cpi->fn_ptr[BT].svf = SVF; \ - cpi->fn_ptr[BT].svaf = SVAF; \ - cpi->fn_ptr[BT].sdx4df = SDX4DF; \ - cpi->fn_ptr[BT].sdsx4df = SDSX4DF; - - BFP(BLOCK_32X16, vpx_sad32x16, vpx_sad_skip_32x16, vpx_sad32x16_avg, - vpx_variance32x16, vpx_sub_pixel_variance32x16, - vpx_sub_pixel_avg_variance32x16, vpx_sad32x16x4d, vpx_sad_skip_32x16x4d) - - BFP(BLOCK_16X32, vpx_sad16x32, vpx_sad_skip_16x32, vpx_sad16x32_avg, - vpx_variance16x32, vpx_sub_pixel_variance16x32, - vpx_sub_pixel_avg_variance16x32, vpx_sad16x32x4d, vpx_sad_skip_16x32x4d) - - BFP(BLOCK_64X32, vpx_sad64x32, vpx_sad_skip_64x32, vpx_sad64x32_avg, - vpx_variance64x32, vpx_sub_pixel_variance64x32, - vpx_sub_pixel_avg_variance64x32, vpx_sad64x32x4d, vpx_sad_skip_64x32x4d) - - BFP(BLOCK_32X64, vpx_sad32x64, vpx_sad_skip_32x64, vpx_sad32x64_avg, - vpx_variance32x64, vpx_sub_pixel_variance32x64, - vpx_sub_pixel_avg_variance32x64, vpx_sad32x64x4d, vpx_sad_skip_32x64x4d) - - BFP(BLOCK_32X32, vpx_sad32x32, vpx_sad_skip_32x32, vpx_sad32x32_avg, - vpx_variance32x32, vpx_sub_pixel_variance32x32, - vpx_sub_pixel_avg_variance32x32, vpx_sad32x32x4d, vpx_sad_skip_32x32x4d) - - BFP(BLOCK_64X64, vpx_sad64x64, vpx_sad_skip_64x64, vpx_sad64x64_avg, - vpx_variance64x64, vpx_sub_pixel_variance64x64, - vpx_sub_pixel_avg_variance64x64, vpx_sad64x64x4d, vpx_sad_skip_64x64x4d) - - BFP(BLOCK_16X16, vpx_sad16x16, vpx_sad_skip_16x16, vpx_sad16x16_avg, - vpx_variance16x16, vpx_sub_pixel_variance16x16, - vpx_sub_pixel_avg_variance16x16, vpx_sad16x16x4d, vpx_sad_skip_16x16x4d) - - BFP(BLOCK_16X8, vpx_sad16x8, vpx_sad_skip_16x8, vpx_sad16x8_avg, - vpx_variance16x8, vpx_sub_pixel_variance16x8, - vpx_sub_pixel_avg_variance16x8, vpx_sad16x8x4d, vpx_sad_skip_16x8x4d) - - BFP(BLOCK_8X16, vpx_sad8x16, vpx_sad_skip_8x16, vpx_sad8x16_avg, - vpx_variance8x16, vpx_sub_pixel_variance8x16, - vpx_sub_pixel_avg_variance8x16, vpx_sad8x16x4d, vpx_sad_skip_8x16x4d) - - BFP(BLOCK_8X8, vpx_sad8x8, vpx_sad_skip_8x8, vpx_sad8x8_avg, vpx_variance8x8, - vpx_sub_pixel_variance8x8, vpx_sub_pixel_avg_variance8x8, vpx_sad8x8x4d, - vpx_sad_skip_8x8x4d) - - BFP(BLOCK_8X4, vpx_sad8x4, vpx_sad_skip_8x4, vpx_sad8x4_avg, vpx_variance8x4, - vpx_sub_pixel_variance8x4, vpx_sub_pixel_avg_variance8x4, vpx_sad8x4x4d, - vpx_sad_skip_8x4x4d) - - BFP(BLOCK_4X8, vpx_sad4x8, vpx_sad_skip_4x8, vpx_sad4x8_avg, vpx_variance4x8, - vpx_sub_pixel_variance4x8, vpx_sub_pixel_avg_variance4x8, vpx_sad4x8x4d, - vpx_sad_skip_4x8x4d) - - BFP(BLOCK_4X4, vpx_sad4x4, vpx_sad_skip_4x4, vpx_sad4x4_avg, vpx_variance4x4, - vpx_sub_pixel_variance4x4, vpx_sub_pixel_avg_variance4x4, vpx_sad4x4x4d, - vpx_sad_skip_4x4x4d) - -#if CONFIG_VP9_HIGHBITDEPTH - highbd_set_var_fns(cpi); -#endif - - /* vp9_init_quantizer() is first called here. Add check in - * vp9_frame_init_quantizer() so that vp9_init_quantizer is only - * called later when needed. This will avoid unnecessary calls of - * vp9_init_quantizer() for every frame. - */ - vp9_init_quantizer(cpi); - - vp9_loop_filter_init(cm); - - // Set up the unit scaling factor used during motion search. -#if CONFIG_VP9_HIGHBITDEPTH - vp9_setup_scale_factors_for_frame(&cpi->me_sf, cm->width, cm->height, - cm->width, cm->height, - cm->use_highbitdepth); -#else - vp9_setup_scale_factors_for_frame(&cpi->me_sf, cm->width, cm->height, - cm->width, cm->height); -#endif // CONFIG_VP9_HIGHBITDEPTH - cpi->td.mb.me_sf = &cpi->me_sf; - - cm->error.setjmp = 0; - -#if CONFIG_RATE_CTRL - encode_command_init(&cpi->encode_command); - if (oxcf->use_simple_encode_api) { - partition_info_init(cpi); - motion_vector_info_init(cpi); - fp_motion_vector_info_init(cpi); - tpl_stats_info_init(cpi); - } -#endif - - return cpi; -} - -#if CONFIG_INTERNAL_STATS -#define SNPRINT(H, T) snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T)) - -#define SNPRINT2(H, T, V) \ - snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T), (V)) -#endif // CONFIG_INTERNAL_STATS - -void vp9_remove_compressor(VP9_COMP *cpi) { - VP9_COMMON *cm; - unsigned int i; - - if (!cpi) return; - -#if CONFIG_INTERNAL_STATS - vpx_free(cpi->ssim_vars); -#endif - - cm = &cpi->common; - if (cm->current_video_frame > 0) { -#if CONFIG_INTERNAL_STATS - vpx_clear_system_state(); - - if (cpi->oxcf.pass != 1) { - char headings[512] = { 0 }; - char results[512] = { 0 }; - FILE *f = fopen("opsnr.stt", "a"); - double time_encoded = - (cpi->last_end_time_stamp_seen - cpi->first_time_stamp_ever) / - 10000000.000; - double total_encode_time = - (cpi->time_receive_data + cpi->time_compress_data) / 1000.000; - const double dr = - (double)cpi->bytes * (double)8 / (double)1000 / time_encoded; - const double peak = (double)((1 << cpi->oxcf.input_bit_depth) - 1); - const double target_rate = (double)cpi->oxcf.target_bandwidth / 1000; - const double rate_err = ((100.0 * (dr - target_rate)) / target_rate); - - if (cpi->b_calculate_psnr) { - const double total_psnr = vpx_sse_to_psnr( - (double)cpi->total_samples, peak, (double)cpi->total_sq_error); - const double totalp_psnr = vpx_sse_to_psnr( - (double)cpi->totalp_samples, peak, (double)cpi->totalp_sq_error); - const double total_ssim = - 100 * pow(cpi->summed_quality / cpi->summed_weights, 8.0); - const double totalp_ssim = - 100 * pow(cpi->summedp_quality / cpi->summedp_weights, 8.0); - - snprintf(headings, sizeof(headings), - "Bitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\tGLPsnrP\t" - "VPXSSIM\tVPSSIMP\tFASTSIM\tPSNRHVS\t" - "WstPsnr\tWstSsim\tWstFast\tWstHVS\t" - "AVPsnrY\tAPsnrCb\tAPsnrCr"); - snprintf(results, sizeof(results), - "%7.2f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t" - "%7.3f\t%7.3f\t%7.3f\t%7.3f\t" - "%7.3f\t%7.3f\t%7.3f\t%7.3f\t" - "%7.3f\t%7.3f\t%7.3f", - dr, cpi->psnr.stat[ALL] / cpi->count, total_psnr, - cpi->psnrp.stat[ALL] / cpi->count, totalp_psnr, total_ssim, - totalp_ssim, cpi->fastssim.stat[ALL] / cpi->count, - cpi->psnrhvs.stat[ALL] / cpi->count, cpi->psnr.worst, - cpi->worst_ssim, cpi->fastssim.worst, cpi->psnrhvs.worst, - cpi->psnr.stat[Y] / cpi->count, cpi->psnr.stat[U] / cpi->count, - cpi->psnr.stat[V] / cpi->count); - - if (cpi->b_calculate_blockiness) { - SNPRINT(headings, "\t Block\tWstBlck"); - SNPRINT2(results, "\t%7.3f", cpi->total_blockiness / cpi->count); - SNPRINT2(results, "\t%7.3f", cpi->worst_blockiness); - } - - if (cpi->b_calculate_consistency) { - double consistency = - vpx_sse_to_psnr((double)cpi->totalp_samples, peak, - (double)cpi->total_inconsistency); - - SNPRINT(headings, "\tConsist\tWstCons"); - SNPRINT2(results, "\t%7.3f", consistency); - SNPRINT2(results, "\t%7.3f", cpi->worst_consistency); - } - - SNPRINT(headings, "\t Time\tRcErr\tAbsErr"); - SNPRINT2(results, "\t%8.0f", total_encode_time); - SNPRINT2(results, "\t%7.2f", rate_err); - SNPRINT2(results, "\t%7.2f", fabs(rate_err)); - - fprintf(f, "%s\tAPsnr611\n", headings); - fprintf( - f, "%s\t%7.3f\n", results, - (6 * cpi->psnr.stat[Y] + cpi->psnr.stat[U] + cpi->psnr.stat[V]) / - (cpi->count * 8)); - } - - fclose(f); - } -#endif - -#if 0 - { - printf("\n_pick_loop_filter_level:%d\n", cpi->time_pick_lpf / 1000); - printf("\n_frames receive_data encod_mb_row compress_frame Total\n"); - printf("%6d %10ld %10ld %10ld %10ld\n", cpi->common.current_video_frame, - cpi->time_receive_data / 1000, cpi->time_encode_sb_row / 1000, - cpi->time_compress_data / 1000, - (cpi->time_receive_data + cpi->time_compress_data) / 1000); - } -#endif - } - -#if CONFIG_VP9_TEMPORAL_DENOISING - vp9_denoiser_free(&(cpi->denoiser)); -#endif - - if (cpi->kmeans_data_arr_alloc) { -#if CONFIG_MULTITHREAD - pthread_mutex_destroy(&cpi->kmeans_mutex); -#endif - vpx_free(cpi->kmeans_data_arr); - } - - vp9_free_tpl_buffer(cpi); - - vp9_loop_filter_dealloc(&cpi->lf_row_sync); - vp9_bitstream_encode_tiles_buffer_dealloc(cpi); - vp9_row_mt_mem_dealloc(cpi); - vp9_encode_free_mt_data(cpi); - -#if !CONFIG_REALTIME_ONLY - vp9_alt_ref_aq_destroy(cpi->alt_ref_aq); -#endif - - dealloc_compressor_data(cpi); - - for (i = 0; i < sizeof(cpi->mbgraph_stats) / sizeof(cpi->mbgraph_stats[0]); - ++i) { - vpx_free(cpi->mbgraph_stats[i].mb_stats); - } - - vp9_extrc_delete(&cpi->ext_ratectrl); - - // Help detect use after free of the error detail string. - memset(cm->error.detail, 'A', sizeof(cm->error.detail) - 1); - cm->error.detail[sizeof(cm->error.detail) - 1] = '\0'; - - vp9_remove_common(cm); - vp9_free_ref_frame_buffers(cm->buffer_pool); -#if CONFIG_VP9_POSTPROC - vp9_free_postproc_buffers(cm); -#endif - vpx_free(cpi); - -#if CONFIG_VP9_TEMPORAL_DENOISING -#ifdef OUTPUT_YUV_DENOISED - fclose(yuv_denoised_file); -#endif -#endif -#ifdef OUTPUT_YUV_SKINMAP - fclose(yuv_skinmap_file); -#endif -#ifdef OUTPUT_YUV_REC - fclose(yuv_rec_file); -#endif -#ifdef OUTPUT_YUV_SVC_SRC - fclose(yuv_svc_src[0]); - fclose(yuv_svc_src[1]); - fclose(yuv_svc_src[2]); -#endif - -#if 0 - - if (keyfile) - fclose(keyfile); - - if (framepsnr) - fclose(framepsnr); - - if (kf_list) - fclose(kf_list); - -#endif -} - -int vp9_get_psnr(const VP9_COMP *cpi, PSNR_STATS *psnr) { - if (is_psnr_calc_enabled(cpi)) { -#if CONFIG_VP9_HIGHBITDEPTH - vpx_calc_highbd_psnr(cpi->raw_source_frame, cpi->common.frame_to_show, psnr, - cpi->td.mb.e_mbd.bd, cpi->oxcf.input_bit_depth); -#else - vpx_calc_psnr(cpi->raw_source_frame, cpi->common.frame_to_show, psnr); -#endif - return 1; - } else { - vp9_zero(*psnr); - return 0; - } -} - -int vp9_use_as_reference(VP9_COMP *cpi, int ref_frame_flags) { - if (ref_frame_flags > 7) return -1; - - cpi->ref_frame_flags = ref_frame_flags; - return 0; -} - -void vp9_update_reference(VP9_COMP *cpi, int ref_frame_flags) { - cpi->ext_refresh_golden_frame = (ref_frame_flags & VP9_GOLD_FLAG) != 0; - cpi->ext_refresh_alt_ref_frame = (ref_frame_flags & VP9_ALT_FLAG) != 0; - cpi->ext_refresh_last_frame = (ref_frame_flags & VP9_LAST_FLAG) != 0; - cpi->ext_refresh_frame_flags_pending = 1; -} - -static YV12_BUFFER_CONFIG *get_vp9_ref_frame_buffer( - VP9_COMP *cpi, VP9_REFFRAME ref_frame_flag) { - MV_REFERENCE_FRAME ref_frame = NO_REF_FRAME; - if (ref_frame_flag == VP9_LAST_FLAG) - ref_frame = LAST_FRAME; - else if (ref_frame_flag == VP9_GOLD_FLAG) - ref_frame = GOLDEN_FRAME; - else if (ref_frame_flag == VP9_ALT_FLAG) - ref_frame = ALTREF_FRAME; - - return ref_frame == NO_REF_FRAME ? NULL - : get_ref_frame_buffer(cpi, ref_frame); -} - -int vp9_copy_reference_enc(VP9_COMP *cpi, VP9_REFFRAME ref_frame_flag, - YV12_BUFFER_CONFIG *sd) { - YV12_BUFFER_CONFIG *cfg = get_vp9_ref_frame_buffer(cpi, ref_frame_flag); - if (cfg) { - vpx_yv12_copy_frame(cfg, sd); - return 0; - } else { - return -1; - } -} - -int vp9_set_reference_enc(VP9_COMP *cpi, VP9_REFFRAME ref_frame_flag, - YV12_BUFFER_CONFIG *sd) { - YV12_BUFFER_CONFIG *cfg = get_vp9_ref_frame_buffer(cpi, ref_frame_flag); - if (cfg) { - vpx_yv12_copy_frame(sd, cfg); - return 0; - } else { - return -1; - } -} - -int vp9_update_entropy(VP9_COMP *cpi, int update) { - cpi->ext_refresh_frame_context = update; - cpi->ext_refresh_frame_context_pending = 1; - return 0; -} - -#ifdef OUTPUT_YUV_REC -void vp9_write_yuv_rec_frame(VP9_COMMON *cm) { - YV12_BUFFER_CONFIG *s = cm->frame_to_show; - uint8_t *src = s->y_buffer; - int h = cm->height; - -#if CONFIG_VP9_HIGHBITDEPTH - if (s->flags & YV12_FLAG_HIGHBITDEPTH) { - uint16_t *src16 = CONVERT_TO_SHORTPTR(s->y_buffer); - - do { - fwrite(src16, s->y_width, 2, yuv_rec_file); - src16 += s->y_stride; - } while (--h); - - src16 = CONVERT_TO_SHORTPTR(s->u_buffer); - h = s->uv_height; - - do { - fwrite(src16, s->uv_width, 2, yuv_rec_file); - src16 += s->uv_stride; - } while (--h); - - src16 = CONVERT_TO_SHORTPTR(s->v_buffer); - h = s->uv_height; - - do { - fwrite(src16, s->uv_width, 2, yuv_rec_file); - src16 += s->uv_stride; - } while (--h); - - fflush(yuv_rec_file); - return; - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - do { - fwrite(src, s->y_width, 1, yuv_rec_file); - src += s->y_stride; - } while (--h); - - src = s->u_buffer; - h = s->uv_height; - - do { - fwrite(src, s->uv_width, 1, yuv_rec_file); - src += s->uv_stride; - } while (--h); - - src = s->v_buffer; - h = s->uv_height; - - do { - fwrite(src, s->uv_width, 1, yuv_rec_file); - src += s->uv_stride; - } while (--h); - - fflush(yuv_rec_file); -} -#endif - -#if CONFIG_VP9_HIGHBITDEPTH -void vp9_scale_and_extend_frame_nonnormative(const YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst, int bd) { -#else -void vp9_scale_and_extend_frame_nonnormative(const YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst) { -#endif // CONFIG_VP9_HIGHBITDEPTH - // TODO(dkovalev): replace YV12_BUFFER_CONFIG with vpx_image_t - int i; - const uint8_t *const srcs[3] = { src->y_buffer, src->u_buffer, - src->v_buffer }; - const int src_strides[3] = { src->y_stride, src->uv_stride, src->uv_stride }; - const int src_widths[3] = { src->y_crop_width, src->uv_crop_width, - src->uv_crop_width }; - const int src_heights[3] = { src->y_crop_height, src->uv_crop_height, - src->uv_crop_height }; - uint8_t *const dsts[3] = { dst->y_buffer, dst->u_buffer, dst->v_buffer }; - const int dst_strides[3] = { dst->y_stride, dst->uv_stride, dst->uv_stride }; - const int dst_widths[3] = { dst->y_crop_width, dst->uv_crop_width, - dst->uv_crop_width }; - const int dst_heights[3] = { dst->y_crop_height, dst->uv_crop_height, - dst->uv_crop_height }; - - for (i = 0; i < MAX_MB_PLANE; ++i) { -#if CONFIG_VP9_HIGHBITDEPTH - if (src->flags & YV12_FLAG_HIGHBITDEPTH) { - vp9_highbd_resize_plane(srcs[i], src_heights[i], src_widths[i], - src_strides[i], dsts[i], dst_heights[i], - dst_widths[i], dst_strides[i], bd); - } else { - vp9_resize_plane(srcs[i], src_heights[i], src_widths[i], src_strides[i], - dsts[i], dst_heights[i], dst_widths[i], dst_strides[i]); - } -#else - vp9_resize_plane(srcs[i], src_heights[i], src_widths[i], src_strides[i], - dsts[i], dst_heights[i], dst_widths[i], dst_strides[i]); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - vpx_extend_frame_borders(dst); -} - -#if CONFIG_VP9_HIGHBITDEPTH -static void scale_and_extend_frame(const YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst, int bd, - INTERP_FILTER filter_type, - int phase_scaler) { - const int src_w = src->y_crop_width; - const int src_h = src->y_crop_height; - const int dst_w = dst->y_crop_width; - const int dst_h = dst->y_crop_height; - - // The issue b/311394513 reveals a corner case bug. - // For bd = 8, vpx_scaled_2d() requires both x_step_q4 and y_step_q4 are less - // than or equal to 64. For bd >= 10, vpx_highbd_convolve8() requires both - // x_step_q4 and y_step_q4 are less than or equal to 32. If this condition - // isn't met, it needs to call vp9_scale_and_extend_frame_nonnormative() that - // supports arbitrary scaling. - const int x_step_q4 = 16 * src_w / dst_w; - const int y_step_q4 = 16 * src_h / dst_h; - const int is_arbitrary_scaling = - (bd == 8 && (x_step_q4 > 64 || y_step_q4 > 64)) || - (bd >= 10 && (x_step_q4 > 32 || y_step_q4 > 32)); - if (is_arbitrary_scaling) { - vp9_scale_and_extend_frame_nonnormative(src, dst, bd); - return; - } - - const uint8_t *const srcs[3] = { src->y_buffer, src->u_buffer, - src->v_buffer }; - const int src_strides[3] = { src->y_stride, src->uv_stride, src->uv_stride }; - uint8_t *const dsts[3] = { dst->y_buffer, dst->u_buffer, dst->v_buffer }; - const int dst_strides[3] = { dst->y_stride, dst->uv_stride, dst->uv_stride }; - const InterpKernel *const kernel = vp9_filter_kernels[filter_type]; - int x, y, i; - - for (i = 0; i < MAX_MB_PLANE; ++i) { - const int factor = (i == 0 || i == 3 ? 1 : 2); - const int src_stride = src_strides[i]; - const int dst_stride = dst_strides[i]; - for (y = 0; y < dst_h; y += 16) { - const int y_q4 = y * (16 / factor) * src_h / dst_h + phase_scaler; - for (x = 0; x < dst_w; x += 16) { - const int x_q4 = x * (16 / factor) * src_w / dst_w + phase_scaler; - const uint8_t *src_ptr = srcs[i] + - (y / factor) * src_h / dst_h * src_stride + - (x / factor) * src_w / dst_w; - uint8_t *dst_ptr = dsts[i] + (y / factor) * dst_stride + (x / factor); - - if (src->flags & YV12_FLAG_HIGHBITDEPTH) { - vpx_highbd_convolve8(CONVERT_TO_SHORTPTR(src_ptr), src_stride, - CONVERT_TO_SHORTPTR(dst_ptr), dst_stride, kernel, - x_q4 & 0xf, 16 * src_w / dst_w, y_q4 & 0xf, - 16 * src_h / dst_h, 16 / factor, 16 / factor, - bd); - } else { - vpx_scaled_2d(src_ptr, src_stride, dst_ptr, dst_stride, kernel, - x_q4 & 0xf, 16 * src_w / dst_w, y_q4 & 0xf, - 16 * src_h / dst_h, 16 / factor, 16 / factor); - } - } - } - } - - vpx_extend_frame_borders(dst); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -#if !CONFIG_REALTIME_ONLY -static int scale_down(VP9_COMP *cpi, int q) { - RATE_CONTROL *const rc = &cpi->rc; - GF_GROUP *const gf_group = &cpi->twopass.gf_group; - int scale = 0; - assert(frame_is_kf_gf_arf(cpi)); - - if (rc->frame_size_selector == UNSCALED && - q >= rc->rf_level_maxq[gf_group->rf_level[gf_group->index]]) { - const int max_size_thresh = - (int)(rate_thresh_mult[SCALE_STEP1] * - VPXMAX(rc->this_frame_target, rc->avg_frame_bandwidth)); - scale = rc->projected_frame_size > max_size_thresh ? 1 : 0; - } - return scale; -} - -static int big_rate_miss_high_threshold(VP9_COMP *cpi) { - const RATE_CONTROL *const rc = &cpi->rc; - int big_miss_high; - - if (frame_is_kf_gf_arf(cpi)) - big_miss_high = rc->this_frame_target * 3 / 2; - else - big_miss_high = rc->this_frame_target * 2; - - return big_miss_high; -} - -static int big_rate_miss(VP9_COMP *cpi) { - const RATE_CONTROL *const rc = &cpi->rc; - int big_miss_high; - int big_miss_low; - - // Ignore for overlay frames - if (rc->is_src_frame_alt_ref) { - return 0; - } else { - big_miss_low = (rc->this_frame_target / 2); - big_miss_high = big_rate_miss_high_threshold(cpi); - - return (rc->projected_frame_size > big_miss_high) || - (rc->projected_frame_size < big_miss_low); - } -} - -// test in two pass for the first -static int two_pass_first_group_inter(VP9_COMP *cpi) { - if (cpi->oxcf.pass == 2) { - TWO_PASS *const twopass = &cpi->twopass; - GF_GROUP *const gf_group = &twopass->gf_group; - const int gfg_index = gf_group->index; - - if (gfg_index == 0) return gf_group->update_type[gfg_index] == LF_UPDATE; - return gf_group->update_type[gfg_index - 1] != LF_UPDATE && - gf_group->update_type[gfg_index] == LF_UPDATE; - } else { - return 0; - } -} - -// Function to test for conditions that indicate we should loop -// back and recode a frame. -static int recode_loop_test(VP9_COMP *cpi, int high_limit, int low_limit, int q, - int maxq, int minq) { - const RATE_CONTROL *const rc = &cpi->rc; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - const int frame_is_kfgfarf = frame_is_kf_gf_arf(cpi); - int force_recode = 0; - - if ((rc->projected_frame_size >= rc->max_frame_bandwidth) || - big_rate_miss(cpi) || (cpi->sf.recode_loop == ALLOW_RECODE) || - (two_pass_first_group_inter(cpi) && - (cpi->sf.recode_loop == ALLOW_RECODE_FIRST)) || - (frame_is_kfgfarf && (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF))) { - if (frame_is_kfgfarf && (oxcf->resize_mode == RESIZE_DYNAMIC) && - scale_down(cpi, q)) { - // Code this group at a lower resolution. - cpi->resize_pending = 1; - return 1; - } - - // Force recode for extreme overshoot. - if ((rc->projected_frame_size >= rc->max_frame_bandwidth) || - (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF && - rc->projected_frame_size >= big_rate_miss_high_threshold(cpi))) { - return 1; - } - - // TODO(agrange) high_limit could be greater than the scale-down threshold. - if ((rc->projected_frame_size > high_limit && q < maxq) || - (rc->projected_frame_size < low_limit && q > minq)) { - force_recode = 1; - } else if (cpi->oxcf.rc_mode == VPX_CQ) { - // Deal with frame undershoot and whether or not we are - // below the automatically set cq level. - if (q > oxcf->cq_level && - rc->projected_frame_size < ((rc->this_frame_target * 7) >> 3)) { - force_recode = 1; - } - } - } - return force_recode; -} -#endif // !CONFIG_REALTIME_ONLY - -static void update_ref_frames(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - BufferPool *const pool = cm->buffer_pool; - GF_GROUP *const gf_group = &cpi->twopass.gf_group; - - if (cpi->ext_ratectrl.ready && - (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_GOP) != 0 && - cpi->ext_ratectrl.funcs.get_gop_decision != NULL) { - const int this_gf_index = gf_group->index; - const int update_ref_idx = gf_group->update_ref_idx[this_gf_index]; - if (gf_group->update_type[this_gf_index] == KF_UPDATE) { - ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[0], cm->new_fb_idx); - ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[1], cm->new_fb_idx); - ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[2], cm->new_fb_idx); - } else if (update_ref_idx != INVALID_IDX) { - ref_cnt_fb(pool->frame_bufs, - &cm->ref_frame_map[gf_group->update_ref_idx[this_gf_index]], - cm->new_fb_idx); - } - - const int next_gf_index = gf_group->index + 1; - - // Overlay frame should ideally look at the colocated ref frame from rc lib. - // Here temporarily just don't update the indices. - if (next_gf_index < gf_group->gf_group_size) { - cpi->lst_fb_idx = gf_group->ext_rc_ref[next_gf_index].last_index; - cpi->gld_fb_idx = gf_group->ext_rc_ref[next_gf_index].golden_index; - cpi->alt_fb_idx = gf_group->ext_rc_ref[next_gf_index].altref_index; - } - - return; - } - - if (cpi->rc.show_arf_as_gld) { - int tmp = cpi->alt_fb_idx; - cpi->alt_fb_idx = cpi->gld_fb_idx; - cpi->gld_fb_idx = tmp; - } else if (cm->show_existing_frame) { - // Pop ARF. - cpi->lst_fb_idx = cpi->alt_fb_idx; - cpi->alt_fb_idx = - stack_pop(gf_group->arf_index_stack, gf_group->stack_size); - --gf_group->stack_size; - } - - // At this point the new frame has been encoded. - // If any buffer copy / swapping is signaled it should be done here. - if (cm->frame_type == KEY_FRAME) { - ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx], - cm->new_fb_idx); - ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->alt_fb_idx], - cm->new_fb_idx); - } else if (vp9_preserve_existing_gf(cpi)) { - // We have decided to preserve the previously existing golden frame as our - // new ARF frame. However, in the short term in function - // vp9_get_refresh_mask() we left it in the GF slot and, if - // we're updating the GF with the current decoded frame, we save it to the - // ARF slot instead. - // We now have to update the ARF with the current frame and swap gld_fb_idx - // and alt_fb_idx so that, overall, we've stored the old GF in the new ARF - // slot and, if we're updating the GF, the current frame becomes the new GF. - int tmp; - - ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->alt_fb_idx], - cm->new_fb_idx); - - tmp = cpi->alt_fb_idx; - cpi->alt_fb_idx = cpi->gld_fb_idx; - cpi->gld_fb_idx = tmp; - } else { /* For non key/golden frames */ - if (cpi->refresh_alt_ref_frame) { - int arf_idx = gf_group->top_arf_idx; - - // Push new ARF into stack. - stack_push(gf_group->arf_index_stack, cpi->alt_fb_idx, - gf_group->stack_size); - ++gf_group->stack_size; - - assert(arf_idx < REF_FRAMES); - - ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[arf_idx], cm->new_fb_idx); - memcpy(cpi->interp_filter_selected[ALTREF_FRAME], - cpi->interp_filter_selected[0], - sizeof(cpi->interp_filter_selected[0])); - - cpi->alt_fb_idx = arf_idx; - } - - if (cpi->refresh_golden_frame) { - ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx], - cm->new_fb_idx); - if (!cpi->rc.is_src_frame_alt_ref) - memcpy(cpi->interp_filter_selected[GOLDEN_FRAME], - cpi->interp_filter_selected[0], - sizeof(cpi->interp_filter_selected[0])); - else - memcpy(cpi->interp_filter_selected[GOLDEN_FRAME], - cpi->interp_filter_selected[ALTREF_FRAME], - sizeof(cpi->interp_filter_selected[ALTREF_FRAME])); - } - } - - if (cpi->refresh_last_frame) { - ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->lst_fb_idx], - cm->new_fb_idx); - if (!cpi->rc.is_src_frame_alt_ref) - memcpy(cpi->interp_filter_selected[LAST_FRAME], - cpi->interp_filter_selected[0], - sizeof(cpi->interp_filter_selected[0])); - } - - if (gf_group->update_type[gf_group->index] == MID_OVERLAY_UPDATE) { - cpi->alt_fb_idx = - stack_pop(gf_group->arf_index_stack, gf_group->stack_size); - --gf_group->stack_size; - } -} - -void vp9_update_reference_frames(VP9_COMP *cpi) { - update_ref_frames(cpi); - -#if CONFIG_VP9_TEMPORAL_DENOISING - vp9_denoiser_update_ref_frame(cpi); -#endif - - if (is_one_pass_svc(cpi)) vp9_svc_update_ref_frame(cpi); -} - -static void loopfilter_frame(VP9_COMP *cpi, VP9_COMMON *cm) { - MACROBLOCKD *xd = &cpi->td.mb.e_mbd; - struct loopfilter *lf = &cm->lf; - int is_reference_frame = - (cm->frame_type == KEY_FRAME || cpi->refresh_last_frame || - cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame); - if (cpi->use_svc && - cpi->svc.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) - is_reference_frame = !cpi->svc.non_reference_frame; - - // Skip loop filter in show_existing_frame mode. - if (cm->show_existing_frame) { - lf->filter_level = 0; - return; - } - - if (cpi->loopfilter_ctrl == NO_LOOPFILTER || - (!is_reference_frame && cpi->loopfilter_ctrl == LOOPFILTER_REFERENCE)) { - lf->filter_level = 0; - vpx_extend_frame_inner_borders(cm->frame_to_show); - return; - } - - if (xd->lossless) { - lf->filter_level = 0; - lf->last_filt_level = 0; - } else { - struct vpx_usec_timer timer; - - vpx_clear_system_state(); - - vpx_usec_timer_start(&timer); - - if (!cpi->rc.is_src_frame_alt_ref) { - if ((cpi->common.frame_type == KEY_FRAME) && - (!cpi->rc.this_key_frame_forced)) { - lf->last_filt_level = 0; - } - vp9_pick_filter_level(cpi->Source, cpi, cpi->sf.lpf_pick); - lf->last_filt_level = lf->filter_level; - } else { - lf->filter_level = 0; - } - - vpx_usec_timer_mark(&timer); - cpi->time_pick_lpf += vpx_usec_timer_elapsed(&timer); - } - - if (lf->filter_level > 0 && is_reference_frame) { - vp9_build_mask_frame(cm, lf->filter_level, 0); - - if (cpi->num_workers > 1) - vp9_loop_filter_frame_mt(cm->frame_to_show, cm, xd->plane, - lf->filter_level, 0, 0, cpi->workers, - cpi->num_workers, &cpi->lf_row_sync); - else - vp9_loop_filter_frame(cm->frame_to_show, cm, xd, lf->filter_level, 0, 0); - } - - vpx_extend_frame_inner_borders(cm->frame_to_show); -} - -void vp9_scale_references(VP9_COMP *cpi) { - VP9_COMMON *cm = &cpi->common; - MV_REFERENCE_FRAME ref_frame; - const VP9_REFFRAME ref_mask[3] = { VP9_LAST_FLAG, VP9_GOLD_FLAG, - VP9_ALT_FLAG }; - - for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { - // Need to convert from VP9_REFFRAME to index into ref_mask (subtract 1). - if (cpi->ref_frame_flags & ref_mask[ref_frame - 1]) { - BufferPool *const pool = cm->buffer_pool; - const YV12_BUFFER_CONFIG *const ref = - get_ref_frame_buffer(cpi, ref_frame); - - if (ref == NULL) { - cpi->scaled_ref_idx[ref_frame - 1] = INVALID_IDX; - continue; - } - - if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) { - RefCntBuffer *new_fb_ptr = NULL; - int force_scaling = 0; - int new_fb = cpi->scaled_ref_idx[ref_frame - 1]; - if (new_fb == INVALID_IDX) { - new_fb = get_free_fb(cm); - force_scaling = 1; - } - if (new_fb == INVALID_IDX) return; - new_fb_ptr = &pool->frame_bufs[new_fb]; - if (force_scaling || new_fb_ptr->buf.y_crop_width != cm->width || - new_fb_ptr->buf.y_crop_height != cm->height) { -#if CONFIG_VP9_HIGHBITDEPTH - if (vpx_realloc_frame_buffer(&new_fb_ptr->buf, cm->width, cm->height, - cm->subsampling_x, cm->subsampling_y, - cm->use_highbitdepth, - VP9_ENC_BORDER_IN_PIXELS, - cm->byte_alignment, NULL, NULL, NULL)) - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate frame buffer"); - scale_and_extend_frame(ref, &new_fb_ptr->buf, (int)cm->bit_depth, - EIGHTTAP, 0); -#else - if (vpx_realloc_frame_buffer(&new_fb_ptr->buf, cm->width, cm->height, - cm->subsampling_x, cm->subsampling_y, - VP9_ENC_BORDER_IN_PIXELS, - cm->byte_alignment, NULL, NULL, NULL)) - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate frame buffer"); - vp9_scale_and_extend_frame(ref, &new_fb_ptr->buf, EIGHTTAP, 0); -#endif // CONFIG_VP9_HIGHBITDEPTH - cpi->scaled_ref_idx[ref_frame - 1] = new_fb; - alloc_frame_mvs(cm, new_fb); - } - } else { - int buf_idx; - RefCntBuffer *buf = NULL; - if (cpi->oxcf.pass == 0 && !cpi->use_svc) { - // Check for release of scaled reference. - buf_idx = cpi->scaled_ref_idx[ref_frame - 1]; - if (buf_idx != INVALID_IDX) { - buf = &pool->frame_bufs[buf_idx]; - --buf->ref_count; - cpi->scaled_ref_idx[ref_frame - 1] = INVALID_IDX; - } - } - buf_idx = get_ref_frame_buf_idx(cpi, ref_frame); - buf = &pool->frame_bufs[buf_idx]; - buf->buf.y_crop_width = ref->y_crop_width; - buf->buf.y_crop_height = ref->y_crop_height; - cpi->scaled_ref_idx[ref_frame - 1] = buf_idx; - ++buf->ref_count; - } - } else { - if (cpi->oxcf.pass != 0 || cpi->use_svc) - cpi->scaled_ref_idx[ref_frame - 1] = INVALID_IDX; - } - } -} - -static void release_scaled_references(VP9_COMP *cpi) { - VP9_COMMON *cm = &cpi->common; - int i; - if (cpi->oxcf.pass == 0 && !cpi->use_svc) { - // Only release scaled references under certain conditions: - // if reference will be updated, or if scaled reference has same resolution. - int refresh[3]; - refresh[0] = (cpi->refresh_last_frame) ? 1 : 0; - refresh[1] = (cpi->refresh_golden_frame) ? 1 : 0; - refresh[2] = (cpi->refresh_alt_ref_frame) ? 1 : 0; - for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) { - const int idx = cpi->scaled_ref_idx[i - 1]; - if (idx != INVALID_IDX) { - RefCntBuffer *const buf = &cm->buffer_pool->frame_bufs[idx]; - const YV12_BUFFER_CONFIG *const ref = get_ref_frame_buffer(cpi, i); - if (refresh[i - 1] || (buf->buf.y_crop_width == ref->y_crop_width && - buf->buf.y_crop_height == ref->y_crop_height)) { - --buf->ref_count; - cpi->scaled_ref_idx[i - 1] = INVALID_IDX; - } - } - } - } else { - for (i = 0; i < REFS_PER_FRAME; ++i) { - const int idx = cpi->scaled_ref_idx[i]; - if (idx != INVALID_IDX) { - RefCntBuffer *const buf = &cm->buffer_pool->frame_bufs[idx]; - --buf->ref_count; - cpi->scaled_ref_idx[i] = INVALID_IDX; - } - } - } -} - -static void full_to_model_count(unsigned int *model_count, - unsigned int *full_count) { - int n; - model_count[ZERO_TOKEN] = full_count[ZERO_TOKEN]; - model_count[ONE_TOKEN] = full_count[ONE_TOKEN]; - model_count[TWO_TOKEN] = full_count[TWO_TOKEN]; - for (n = THREE_TOKEN; n < EOB_TOKEN; ++n) - model_count[TWO_TOKEN] += full_count[n]; - model_count[EOB_MODEL_TOKEN] = full_count[EOB_TOKEN]; -} - -static void full_to_model_counts(vp9_coeff_count_model *model_count, - vp9_coeff_count *full_count) { - int i, j, k, l; - - for (i = 0; i < PLANE_TYPES; ++i) - for (j = 0; j < REF_TYPES; ++j) - for (k = 0; k < COEF_BANDS; ++k) - for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) - full_to_model_count(model_count[i][j][k][l], full_count[i][j][k][l]); -} - -#if 0 && CONFIG_INTERNAL_STATS -static void output_frame_level_debug_stats(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - FILE *const f = fopen("tmp.stt", cm->current_video_frame ? "a" : "w"); - int64_t recon_err; - - vpx_clear_system_state(); - -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - recon_err = vpx_highbd_get_y_sse(cpi->Source, get_frame_new_buffer(cm)); - } else { - recon_err = vpx_get_y_sse(cpi->Source, get_frame_new_buffer(cm)); - } -#else - recon_err = vpx_get_y_sse(cpi->Source, get_frame_new_buffer(cm)); -#endif // CONFIG_VP9_HIGHBITDEPTH - - - if (cpi->twopass.total_left_stats.coded_error != 0.0) { - double dc_quant_devisor; -#if CONFIG_VP9_HIGHBITDEPTH - switch (cm->bit_depth) { - case VPX_BITS_8: - dc_quant_devisor = 4.0; - break; - case VPX_BITS_10: - dc_quant_devisor = 16.0; - break; - default: - assert(cm->bit_depth == VPX_BITS_12); - dc_quant_devisor = 64.0; - break; - } -#else - dc_quant_devisor = 4.0; -#endif - - if (!cm->current_video_frame) { - fprintf(f, "frame, width, height, last ts, last end ts, " - "source_alt_ref_pending, source_alt_ref_active, " - "this_frame_target, projected_frame_size, " - "projected_frame_size / MBs, " - "projected_frame_size - this_frame_target, " - "vbr_bits_off_target, vbr_bits_off_target_fast, " - "twopass.extend_minq, twopass.extend_minq_fast, " - "total_target_vs_actual, " - "starting_buffer_level - bits_off_target, " - "total_actual_bits, base_qindex, q for base_qindex, " - "dc quant, q for active_worst_quality, avg_q, q for oxcf.cq_level, " - "refresh_last_frame, refresh_golden_frame, refresh_alt_ref_frame, " - "frame_type, gfu_boost, " - "twopass.bits_left, " - "twopass.total_left_stats.coded_error, " - "twopass.bits_left / (1 + twopass.total_left_stats.coded_error), " - "tot_recode_hits, recon_err, kf_boost, " - "twopass.kf_zeromotion_pct, twopass.fr_content_type, " - "filter_level, seg.aq_av_offset\n"); - } - - fprintf(f, "%10u, %d, %d, %10"PRId64", %10"PRId64", %d, %d, %10d, %10d, " - "%10d, %10d, %10"PRId64", %10"PRId64", %5d, %5d, %10"PRId64", " - "%10"PRId64", %10"PRId64", %10d, %7.2lf, %7.2lf, %7.2lf, %7.2lf, " - "%7.2lf, %6d, %6d, %5d, %5d, %5d, %10"PRId64", %10.3lf, %10lf, %8u, " - "%10"PRId64", %10d, %10d, %10d, %10d, %10d\n", - cpi->common.current_video_frame, - cm->width, cm->height, - cpi->last_time_stamp_seen, - cpi->last_end_time_stamp_seen, - cpi->rc.source_alt_ref_pending, - cpi->rc.source_alt_ref_active, - cpi->rc.this_frame_target, - cpi->rc.projected_frame_size, - cpi->rc.projected_frame_size / cpi->common.MBs, - (cpi->rc.projected_frame_size - cpi->rc.this_frame_target), - cpi->rc.vbr_bits_off_target, - cpi->rc.vbr_bits_off_target_fast, - cpi->twopass.extend_minq, - cpi->twopass.extend_minq_fast, - cpi->rc.total_target_vs_actual, - (cpi->rc.starting_buffer_level - cpi->rc.bits_off_target), - cpi->rc.total_actual_bits, cm->base_qindex, - vp9_convert_qindex_to_q(cm->base_qindex, cm->bit_depth), - (double)vp9_dc_quant(cm->base_qindex, 0, cm->bit_depth) / - dc_quant_devisor, - vp9_convert_qindex_to_q(cpi->twopass.active_worst_quality, - cm->bit_depth), - cpi->rc.avg_q, - vp9_convert_qindex_to_q(cpi->oxcf.cq_level, cm->bit_depth), - cpi->refresh_last_frame, cpi->refresh_golden_frame, - cpi->refresh_alt_ref_frame, cm->frame_type, cpi->rc.gfu_boost, - cpi->twopass.bits_left, - cpi->twopass.total_left_stats.coded_error, - cpi->twopass.bits_left / - (1 + cpi->twopass.total_left_stats.coded_error), - cpi->tot_recode_hits, recon_err, cpi->rc.kf_boost, - cpi->twopass.kf_zeromotion_pct, - cpi->twopass.fr_content_type, - cm->lf.filter_level, - cm->seg.aq_av_offset); - } - fclose(f); - - if (0) { - FILE *const fmodes = fopen("Modes.stt", "a"); - int i; - - fprintf(fmodes, "%6d:%1d:%1d:%1d ", cpi->common.current_video_frame, - cm->frame_type, cpi->refresh_golden_frame, - cpi->refresh_alt_ref_frame); - - for (i = 0; i < MAX_MODES; ++i) - fprintf(fmodes, "%5d ", cpi->mode_chosen_counts[i]); - - fprintf(fmodes, "\n"); - - fclose(fmodes); - } -} -#endif - -static void set_mv_search_params(VP9_COMP *cpi) { - const VP9_COMMON *const cm = &cpi->common; - const unsigned int max_mv_def = VPXMIN(cm->width, cm->height); - - // Default based on max resolution. - cpi->mv_step_param = vp9_init_search_range(max_mv_def); - - if (cpi->sf.mv.auto_mv_step_size) { - if (frame_is_intra_only(cm)) { - // Initialize max_mv_magnitude for use in the first INTER frame - // after a key/intra-only frame. - cpi->max_mv_magnitude = max_mv_def; - } else { - if (cm->show_frame) { - // Allow mv_steps to correspond to twice the max mv magnitude found - // in the previous frame, capped by the default max_mv_magnitude based - // on resolution. - cpi->mv_step_param = vp9_init_search_range( - VPXMIN(max_mv_def, 2 * cpi->max_mv_magnitude)); - } - cpi->max_mv_magnitude = 0; - } - } -} - -static void set_size_independent_vars(VP9_COMP *cpi) { - vp9_set_speed_features_framesize_independent(cpi, cpi->oxcf.speed); - vp9_set_rd_speed_thresholds(cpi); - vp9_set_rd_speed_thresholds_sub8x8(cpi); - cpi->common.interp_filter = cpi->sf.default_interp_filter; -} - -static void set_size_dependent_vars(VP9_COMP *cpi, int *q, int *bottom_index, - int *top_index) { - VP9_COMMON *const cm = &cpi->common; - - // Setup variables that depend on the dimensions of the frame. - vp9_set_speed_features_framesize_dependent(cpi, cpi->oxcf.speed); - - // Decide q and q bounds. - *q = vp9_rc_pick_q_and_bounds(cpi, bottom_index, top_index); - - if (cpi->oxcf.rc_mode == VPX_CBR && cpi->rc.force_max_q) { - *q = cpi->rc.worst_quality; - cpi->rc.force_max_q = 0; - } - - if (cpi->use_svc) { - cpi->svc.base_qindex[cpi->svc.spatial_layer_id] = *q; - } - - if (!frame_is_intra_only(cm)) { - vp9_set_high_precision_mv(cpi, (*q) < HIGH_PRECISION_MV_QTHRESH); - } - -#if !CONFIG_REALTIME_ONLY - // Configure experimental use of segmentation for enhanced coding of - // static regions if indicated. - // Only allowed in the second pass of a two pass encode, as it requires - // lagged coding, and if the relevant speed feature flag is set. - if (cpi->oxcf.pass == 2 && cpi->sf.static_segmentation) - configure_static_seg_features(cpi); -#endif // !CONFIG_REALTIME_ONLY - -#if CONFIG_VP9_POSTPROC && !(CONFIG_VP9_TEMPORAL_DENOISING) - if (cpi->oxcf.noise_sensitivity > 0) { - int l = 0; - switch (cpi->oxcf.noise_sensitivity) { - case 1: l = 20; break; - case 2: l = 40; break; - case 3: l = 60; break; - case 4: - case 5: l = 100; break; - case 6: l = 150; break; - } - if (!cpi->common.postproc_state.limits) { - CHECK_MEM_ERROR(&cm->error, cpi->common.postproc_state.limits, - vpx_calloc(cpi->un_scaled_source->y_width, - sizeof(*cpi->common.postproc_state.limits))); - } - vp9_denoise(&cpi->common, cpi->Source, cpi->Source, l, - cpi->common.postproc_state.limits); - } -#endif // CONFIG_VP9_POSTPROC -} - -static void init_motion_estimation(VP9_COMP *cpi) { - int y_stride = cpi->scaled_source.y_stride; - - if (cpi->sf.mv.search_method == NSTEP) { - vp9_init3smotion_compensation(&cpi->ss_cfg, y_stride); - } else if (cpi->sf.mv.search_method == DIAMOND) { - vp9_init_dsmotion_compensation(&cpi->ss_cfg, y_stride); - } -} - -static void set_frame_size(VP9_COMP *cpi) { - int ref_frame; - VP9_COMMON *const cm = &cpi->common; - VP9EncoderConfig *const oxcf = &cpi->oxcf; - MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; - -#if !CONFIG_REALTIME_ONLY - if (oxcf->pass == 2 && oxcf->rc_mode == VPX_VBR && - ((oxcf->resize_mode == RESIZE_FIXED && cm->current_video_frame == 0) || - (oxcf->resize_mode == RESIZE_DYNAMIC && cpi->resize_pending))) { - calculate_coded_size(cpi, &oxcf->scaled_frame_width, - &oxcf->scaled_frame_height); - - // There has been a change in frame size. - vp9_set_size_literal(cpi, oxcf->scaled_frame_width, - oxcf->scaled_frame_height); - } -#endif // !CONFIG_REALTIME_ONLY - - if (oxcf->pass == 0 && oxcf->rc_mode == VPX_CBR && - oxcf->resize_mode == RESIZE_DYNAMIC && cpi->resize_pending != 0) { - // For SVC scaled width/height will have been set (svc->resize_set=1) - // in get_svc_params based on the layer width/height. - if (!cpi->use_svc || !cpi->svc.resize_set) { - oxcf->scaled_frame_width = - (oxcf->width * cpi->resize_scale_num) / cpi->resize_scale_den; - oxcf->scaled_frame_height = - (oxcf->height * cpi->resize_scale_num) / cpi->resize_scale_den; - // There has been a change in frame size. - vp9_set_size_literal(cpi, oxcf->scaled_frame_width, - oxcf->scaled_frame_height); - } - - // TODO(agrange) Scale cpi->max_mv_magnitude if frame-size has changed. - set_mv_search_params(cpi); - - vp9_noise_estimate_init(&cpi->noise_estimate, cm->width, cm->height); -#if CONFIG_VP9_TEMPORAL_DENOISING - // Reset the denoiser on the resized frame. - if (cpi->oxcf.noise_sensitivity > 0) { - vp9_denoiser_free(&(cpi->denoiser)); - setup_denoiser_buffer(cpi); - // Dynamic resize is only triggered for non-SVC, so we can force - // golden frame update here as temporary fix to denoiser. - cpi->refresh_golden_frame = 1; - } -#endif - } - - if ((oxcf->pass == 2) && !cpi->use_svc) { - vp9_set_target_rate(cpi); - } - - alloc_frame_mvs(cm, cm->new_fb_idx); - - // Reset the frame pointers to the current frame size. - if (vpx_realloc_frame_buffer(get_frame_new_buffer(cm), cm->width, cm->height, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment, - NULL, NULL, NULL)) - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate frame buffer"); - - alloc_util_frame_buffers(cpi); - init_motion_estimation(cpi); - - int has_valid_ref_frame = 0; - for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { - RefBuffer *const ref_buf = &cm->frame_refs[ref_frame - 1]; - const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame); - - ref_buf->idx = buf_idx; - - if (buf_idx != INVALID_IDX) { - YV12_BUFFER_CONFIG *const buf = &cm->buffer_pool->frame_bufs[buf_idx].buf; - ref_buf->buf = buf; -#if CONFIG_VP9_HIGHBITDEPTH - vp9_setup_scale_factors_for_frame( - &ref_buf->sf, buf->y_crop_width, buf->y_crop_height, cm->width, - cm->height, (buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0); -#else - vp9_setup_scale_factors_for_frame(&ref_buf->sf, buf->y_crop_width, - buf->y_crop_height, cm->width, - cm->height); -#endif // CONFIG_VP9_HIGHBITDEPTH - has_valid_ref_frame |= vp9_is_valid_scale(&ref_buf->sf); - if (vp9_is_scaled(&ref_buf->sf)) vpx_extend_frame_borders(buf); - } else { - ref_buf->buf = NULL; - } - } - if (!frame_is_intra_only(cm) && !has_valid_ref_frame) { - vpx_internal_error( - &cm->error, VPX_CODEC_ERROR, - "Can't find at least one reference frame with valid size"); - } - - set_ref_ptrs(cm, xd, LAST_FRAME, LAST_FRAME); -} - -static void save_encode_params(VP9_COMP *cpi) { - int tile_idx; - int i, j; - TileDataEnc *tile_data; - RD_OPT *rd_opt = &cpi->rd; - for (i = 0; i < MAX_REF_FRAMES; i++) { - for (j = 0; j < REFERENCE_MODES; j++) - rd_opt->prediction_type_threshes_prev[i][j] = - rd_opt->prediction_type_threshes[i][j]; - - for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; j++) - rd_opt->filter_threshes_prev[i][j] = rd_opt->filter_threshes[i][j]; - } - - for (tile_idx = 0; tile_idx < cpi->allocated_tiles; tile_idx++) { - assert(cpi->tile_data); - tile_data = &cpi->tile_data[tile_idx]; - vp9_copy(tile_data->thresh_freq_fact_prev, tile_data->thresh_freq_fact); - } -} - -static INLINE void set_raw_source_frame(VP9_COMP *cpi) { -#ifdef ENABLE_KF_DENOISE - if (is_spatial_denoise_enabled(cpi)) { - cpi->raw_source_frame = vp9_scale_if_required( - cm, &cpi->raw_unscaled_source, &cpi->raw_scaled_source, - (oxcf->pass == 0), EIGHTTAP, 0); - } else { - cpi->raw_source_frame = cpi->Source; - } -#else - cpi->raw_source_frame = cpi->Source; -#endif -} - -static YV12_BUFFER_CONFIG *svc_twostage_scale( - VP9_COMMON *cm, YV12_BUFFER_CONFIG *unscaled, YV12_BUFFER_CONFIG *scaled, - YV12_BUFFER_CONFIG *scaled_temp, INTERP_FILTER filter_type, - int phase_scaler, INTERP_FILTER filter_type2, int phase_scaler2) { - if (cm->mi_cols * MI_SIZE != unscaled->y_width || - cm->mi_rows * MI_SIZE != unscaled->y_height) { -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->bit_depth == VPX_BITS_8) { - vp9_scale_and_extend_frame(unscaled, scaled_temp, filter_type2, - phase_scaler2); - vp9_scale_and_extend_frame(scaled_temp, scaled, filter_type, - phase_scaler); - } else { - scale_and_extend_frame(unscaled, scaled_temp, (int)cm->bit_depth, - filter_type2, phase_scaler2); - scale_and_extend_frame(scaled_temp, scaled, (int)cm->bit_depth, - filter_type, phase_scaler); - } -#else - vp9_scale_and_extend_frame(unscaled, scaled_temp, filter_type2, - phase_scaler2); - vp9_scale_and_extend_frame(scaled_temp, scaled, filter_type, phase_scaler); -#endif // CONFIG_VP9_HIGHBITDEPTH - return scaled; - } else { - return unscaled; - } -} - -static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size, - uint8_t *dest, size_t dest_size) { - VP9_COMMON *const cm = &cpi->common; - SVC *const svc = &cpi->svc; - int q = 0, bottom_index = 0, top_index = 0; - int no_drop_scene_change = 0; - const INTERP_FILTER filter_scaler = - (is_one_pass_svc(cpi)) - ? svc->downsample_filter_type[svc->spatial_layer_id] - : EIGHTTAP; - const int phase_scaler = - (is_one_pass_svc(cpi)) - ? svc->downsample_filter_phase[svc->spatial_layer_id] - : 0; - - if (cm->show_existing_frame) { - cpi->rc.this_frame_target = 0; - if (is_psnr_calc_enabled(cpi)) set_raw_source_frame(cpi); - return 1; - } - - svc->time_stamp_prev[svc->spatial_layer_id] = svc->time_stamp_superframe; - - // Flag to check if its valid to compute the source sad (used for - // scene detection and for superblock content state in CBR mode). - // The flag may get reset below based on SVC or resizing state. - cpi->compute_source_sad_onepass = cpi->oxcf.mode == REALTIME; - - vpx_clear_system_state(); - - set_frame_size(cpi); - - if (is_one_pass_svc(cpi) && - cpi->un_scaled_source->y_width == cm->width << 2 && - cpi->un_scaled_source->y_height == cm->height << 2 && - svc->scaled_temp.y_width == cm->width << 1 && - svc->scaled_temp.y_height == cm->height << 1) { - // For svc, if it is a 1/4x1/4 downscaling, do a two-stage scaling to take - // advantage of the 1:2 optimized scaler. In the process, the 1/2x1/2 - // result will be saved in scaled_temp and might be used later. - const INTERP_FILTER filter_scaler2 = svc->downsample_filter_type[1]; - const int phase_scaler2 = svc->downsample_filter_phase[1]; - cpi->Source = svc_twostage_scale( - cm, cpi->un_scaled_source, &cpi->scaled_source, &svc->scaled_temp, - filter_scaler, phase_scaler, filter_scaler2, phase_scaler2); - svc->scaled_one_half = 1; - } else if (is_one_pass_svc(cpi) && - cpi->un_scaled_source->y_width == cm->width << 1 && - cpi->un_scaled_source->y_height == cm->height << 1 && - svc->scaled_one_half) { - // If the spatial layer is 1/2x1/2 and the scaling is already done in the - // two-stage scaling, use the result directly. - cpi->Source = &svc->scaled_temp; - svc->scaled_one_half = 0; - } else { - cpi->Source = vp9_scale_if_required( - cm, cpi->un_scaled_source, &cpi->scaled_source, (cpi->oxcf.pass == 0), - filter_scaler, phase_scaler); - } -#ifdef OUTPUT_YUV_SVC_SRC - // Write out at most 3 spatial layers. - if (is_one_pass_svc(cpi) && svc->spatial_layer_id < 3) { - vpx_write_yuv_frame(yuv_svc_src[svc->spatial_layer_id], cpi->Source); - } -#endif - // Unfiltered raw source used in metrics calculation if the source - // has been filtered. - if (is_psnr_calc_enabled(cpi)) { -#ifdef ENABLE_KF_DENOISE - if (is_spatial_denoise_enabled(cpi)) { - cpi->raw_source_frame = vp9_scale_if_required( - cm, &cpi->raw_unscaled_source, &cpi->raw_scaled_source, - (cpi->oxcf.pass == 0), EIGHTTAP, phase_scaler); - } else { - cpi->raw_source_frame = cpi->Source; - } -#else - cpi->raw_source_frame = cpi->Source; -#endif - } - - if ((cpi->use_svc && - (svc->spatial_layer_id < svc->number_spatial_layers - 1 || - svc->temporal_layer_id < svc->number_temporal_layers - 1 || - svc->current_superframe < 1)) || - cpi->resize_pending || cpi->resize_state || cpi->external_resize || - cpi->resize_state != ORIG) { - cpi->compute_source_sad_onepass = 0; - if (cpi->content_state_sb_fd != NULL) - memset(cpi->content_state_sb_fd, 0, - (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1) * - sizeof(*cpi->content_state_sb_fd)); - } - - // Avoid scaling last_source unless its needed. - // Last source is needed if avg_source_sad() is used, or if - // partition_search_type == SOURCE_VAR_BASED_PARTITION, or if noise - // estimation is enabled. - if (cpi->unscaled_last_source != NULL && - (cpi->oxcf.content == VP9E_CONTENT_SCREEN || - (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_VBR && - cpi->oxcf.mode == REALTIME && cpi->oxcf.speed >= 5) || - cpi->sf.partition_search_type == SOURCE_VAR_BASED_PARTITION || - (cpi->noise_estimate.enabled && !cpi->oxcf.noise_sensitivity) || - cpi->compute_source_sad_onepass)) - cpi->Last_Source = vp9_scale_if_required( - cm, cpi->unscaled_last_source, &cpi->scaled_last_source, - (cpi->oxcf.pass == 0), EIGHTTAP, 0); - - if (cpi->Last_Source == NULL || - cpi->Last_Source->y_width != cpi->Source->y_width || - cpi->Last_Source->y_height != cpi->Source->y_height) - cpi->compute_source_sad_onepass = 0; - - if (frame_is_intra_only(cm) || cpi->resize_pending != 0) { - memset(cpi->consec_zero_mv, 0, - cm->mi_rows * cm->mi_cols * sizeof(*cpi->consec_zero_mv)); - } - -#if CONFIG_VP9_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity > 0 && cpi->use_svc) - vp9_denoiser_reset_on_first_frame(cpi); -#endif - - // Scene detection is always used for VBR mode or screen-content case. - // For other cases (e.g., CBR mode) use it for 5 <= speed. - cpi->rc.high_source_sad = 0; - cpi->rc.hybrid_intra_scene_change = 0; - cpi->rc.re_encode_maxq_scene_change = 0; - if (cm->show_frame && cpi->oxcf.mode == REALTIME && - !cpi->disable_scene_detection_rtc_ratectrl && - (cpi->oxcf.rc_mode == VPX_VBR || - cpi->oxcf.content == VP9E_CONTENT_SCREEN || cpi->oxcf.speed >= 5)) - vp9_scene_detection_onepass(cpi); - - if (svc->spatial_layer_id == svc->first_spatial_layer_to_encode) { - svc->high_source_sad_superframe = cpi->rc.high_source_sad; - svc->high_num_blocks_with_motion = cpi->rc.high_num_blocks_with_motion; - // On scene change reset temporal layer pattern to TL0. - // Note that if the base/lower spatial layers are skipped: instead of - // inserting base layer here, we force max-q for the next superframe - // with lower spatial layers: this is done in vp9_encodedframe_overshoot() - // when max-q is decided for the current layer. - // Only do this reset for bypass/flexible mode. - if (svc->high_source_sad_superframe && svc->temporal_layer_id > 0 && - svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) { - // rc->high_source_sad will get reset so copy it to restore it. - int tmp_high_source_sad = cpi->rc.high_source_sad; - vp9_svc_reset_temporal_layers(cpi, cm->frame_type == KEY_FRAME); - cpi->rc.high_source_sad = tmp_high_source_sad; - } - } - - vp9_update_noise_estimate(cpi); - - // For 1 pass CBR, check if we are dropping this frame. - // Never drop on key frame, if base layer is key for svc, - // on scene change, or if superframe has layer sync. - if ((cpi->rc.high_source_sad || svc->high_source_sad_superframe) && - !(cpi->rc.use_post_encode_drop && svc->last_layer_dropped[0])) - no_drop_scene_change = 1; - if (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_CBR && - !frame_is_intra_only(cm) && !no_drop_scene_change && - !svc->superframe_has_layer_sync && - (!cpi->use_svc || - !svc->layer_context[svc->temporal_layer_id].is_key_frame)) { - if (vp9_rc_drop_frame(cpi)) return 0; - } - - // For 1 pass SVC, only ZEROMV is allowed for spatial reference frame - // when svc->force_zero_mode_spatial_ref = 1. Under those conditions we can - // avoid this frame-level upsampling (for non intra_only frames). - // For SVC single_layer mode, dynamic resize is allowed and we need to - // scale references for this case. - if (frame_is_intra_only(cm) == 0 && - ((svc->single_layer_svc && cpi->oxcf.resize_mode == RESIZE_DYNAMIC) || - !(is_one_pass_svc(cpi) && svc->force_zero_mode_spatial_ref))) { - vp9_scale_references(cpi); - } - - set_size_independent_vars(cpi); - set_size_dependent_vars(cpi, &q, &bottom_index, &top_index); - - // search method and step parameter might be changed in speed settings. - init_motion_estimation(cpi); - - if (cpi->sf.copy_partition_flag) alloc_copy_partition_data(cpi); - - if (cpi->sf.svc_use_lowres_part && - svc->spatial_layer_id == svc->number_spatial_layers - 2) { - if (svc->prev_partition_svc == NULL) { - CHECK_MEM_ERROR( - &cm->error, svc->prev_partition_svc, - (BLOCK_SIZE *)vpx_calloc(cm->mi_stride * cm->mi_rows, - sizeof(*svc->prev_partition_svc))); - } - } - - // TODO(jianj): Look into issue of skin detection with high bitdepth. - if (cm->bit_depth == 8 && cpi->oxcf.speed >= 5 && cpi->oxcf.pass == 0 && - cpi->oxcf.rc_mode == VPX_CBR && - cpi->oxcf.content != VP9E_CONTENT_SCREEN && - cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) { - cpi->use_skin_detection = 1; - } - - // Enable post encode frame dropping for CBR on non key frame, when - // ext_use_post_encode_drop is specified by user. - cpi->rc.use_post_encode_drop = cpi->rc.ext_use_post_encode_drop && - cpi->oxcf.rc_mode == VPX_CBR && - cm->frame_type != KEY_FRAME; - - vp9_set_quantizer(cpi, q); - vp9_set_variance_partition_thresholds(cpi, q, 0); - - setup_frame(cpi); - - suppress_active_map(cpi); - - if (cpi->use_svc) { - // On non-zero spatial layer, check for disabling inter-layer - // prediction. - if (svc->spatial_layer_id > 0) vp9_svc_constrain_inter_layer_pred(cpi); - vp9_svc_assert_constraints_pattern(cpi); - } - - if (cpi->rc.last_post_encode_dropped_scene_change) { - cpi->rc.high_source_sad = 1; - svc->high_source_sad_superframe = 1; - // For now disable use_source_sad since Last_Source will not be the previous - // encoded but the dropped one. - cpi->sf.use_source_sad = 0; - cpi->rc.last_post_encode_dropped_scene_change = 0; - } - // Check if this high_source_sad (scene/slide change) frame should be - // encoded at high/max QP, and if so, set the q and adjust some rate - // control parameters. - if (cpi->sf.overshoot_detection_cbr_rt == FAST_DETECTION_MAXQ && - (cpi->rc.high_source_sad || - (cpi->use_svc && svc->high_source_sad_superframe))) { - if (vp9_encodedframe_overshoot(cpi, -1, &q)) { - vp9_set_quantizer(cpi, q); - vp9_set_variance_partition_thresholds(cpi, q, 0); - } - } - -#if !CONFIG_REALTIME_ONLY - // Variance adaptive and in frame q adjustment experiments are mutually - // exclusive. - if (cpi->oxcf.aq_mode == VARIANCE_AQ) { - vp9_vaq_frame_setup(cpi); - } else if (cpi->oxcf.aq_mode == EQUATOR360_AQ) { - vp9_360aq_frame_setup(cpi); - } else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) { - vp9_setup_in_frame_q_adj(cpi); - } else if (cpi->oxcf.aq_mode == LOOKAHEAD_AQ) { - // it may be pretty bad for rate-control, - // and I should handle it somehow - vp9_alt_ref_aq_setup_map(cpi->alt_ref_aq, cpi); - } else { -#endif - // If ROI is enabled and skip feature is used for segmentation, apply cyclic - // refresh but not apply ROI for skip for the first 20 frames (defined by - // FRAMES_NO_SKIPPING_AFTER_KEY) after key frame to improve quality. - if (cpi->roi.enabled && !frame_is_intra_only(cm)) { - if (cpi->roi.skip[BACKGROUND_SEG_SKIP_ID]) { - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) - vp9_cyclic_refresh_setup(cpi); - if (cpi->rc.frames_since_key > FRAMES_NO_SKIPPING_AFTER_KEY) - apply_roi_map(cpi); - } else { - apply_roi_map(cpi); - } - } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) { - vp9_cyclic_refresh_setup(cpi); - } - -#if !CONFIG_REALTIME_ONLY - } -#endif - - apply_active_map(cpi); - - vp9_encode_frame(cpi); - - // Check if we should re-encode this frame at high Q because of high - // overshoot based on the encoded frame size. Only for frames where - // high temporal-source SAD is detected. - // For SVC: all spatial layers are checked for re-encoding. - if (cpi->sf.overshoot_detection_cbr_rt == RE_ENCODE_MAXQ && - (cpi->rc.high_source_sad || - (cpi->use_svc && svc->high_source_sad_superframe))) { - int frame_size = 0; - // Get an estimate of the encoded frame size. - save_coding_context(cpi); - vp9_pack_bitstream(cpi, dest, dest_size, size); - restore_coding_context(cpi); - frame_size = (int)(*size) << 3; - // Check if encoded frame will overshoot too much, and if so, set the q and - // adjust some rate control parameters, and return to re-encode the frame. - if (vp9_encodedframe_overshoot(cpi, frame_size, &q)) { - vpx_clear_system_state(); - vp9_set_quantizer(cpi, q); - vp9_set_variance_partition_thresholds(cpi, q, 0); - suppress_active_map(cpi); - // Turn-off cyclic refresh for re-encoded frame. - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) { - CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; - unsigned char *const seg_map = cpi->segmentation_map; - memset(seg_map, 0, cm->mi_rows * cm->mi_cols); - memset(cr->last_coded_q_map, MAXQ, - cm->mi_rows * cm->mi_cols * sizeof(*cr->last_coded_q_map)); - cr->sb_index = 0; - vp9_disable_segmentation(&cm->seg); - } - apply_active_map(cpi); - vp9_encode_frame(cpi); - } - } - - // Update some stats from cyclic refresh, and check for golden frame update. - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled && - !frame_is_intra_only(cm) && cpi->cyclic_refresh->content_mode) - vp9_cyclic_refresh_postencode(cpi); - - // Update the skip mb flag probabilities based on the distribution - // seen in the last encoder iteration. - // update_base_skip_probs(cpi); - vpx_clear_system_state(); - return 1; -} - -static int get_ref_frame_flags(const VP9_COMP *cpi) { - const int *const map = cpi->common.ref_frame_map; - const int gold_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idx]; - const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idx]; - const int gold_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx]; - int flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG; - - if (gold_is_last) flags &= ~VP9_GOLD_FLAG; - - if (cpi->rc.frames_till_gf_update_due == INT_MAX && - (cpi->svc.number_temporal_layers == 1 && - cpi->svc.number_spatial_layers == 1)) - flags &= ~VP9_GOLD_FLAG; - - if (alt_is_last) flags &= ~VP9_ALT_FLAG; - - if (gold_is_alt) flags &= ~VP9_ALT_FLAG; - - return flags; -} - -#if !CONFIG_REALTIME_ONLY -#define MAX_QSTEP_ADJ 4 -static int get_qstep_adj(int rate_excess, int rate_limit) { - int qstep = - rate_limit ? ((rate_excess + rate_limit / 2) / rate_limit) : INT_MAX; - return VPXMIN(qstep, MAX_QSTEP_ADJ); -} - -#if CONFIG_RATE_CTRL -static void init_rq_history(RATE_QINDEX_HISTORY *rq_history) { - rq_history->recode_count = 0; - rq_history->q_index_high = 255; - rq_history->q_index_low = 0; -} - -static void update_rq_history(RATE_QINDEX_HISTORY *rq_history, int target_bits, - int actual_bits, int q_index) { - rq_history->q_index_history[rq_history->recode_count] = q_index; - rq_history->rate_history[rq_history->recode_count] = actual_bits; - if (actual_bits <= target_bits) { - rq_history->q_index_high = q_index; - } - if (actual_bits >= target_bits) { - rq_history->q_index_low = q_index; - } - rq_history->recode_count += 1; -} - -static int guess_q_index_from_model(const RATE_QSTEP_MODEL *rq_model, - int target_bits) { - // The model predicts bits as follows. - // target_bits = bias - ratio * log2(q_step) - // Given the target_bits, we compute the q_step as follows. - double q_step; - assert(rq_model->ratio > 0); - q_step = pow(2.0, (rq_model->bias - target_bits) / rq_model->ratio); - // TODO(angiebird): Make this function support highbitdepth. - return vp9_convert_q_to_qindex(q_step, VPX_BITS_8); -} - -static int guess_q_index_linear(int prev_q_index, int target_bits, - int actual_bits, int gap) { - int q_index = prev_q_index; - if (actual_bits < target_bits) { - q_index -= gap; - q_index = VPXMAX(q_index, 0); - } else { - q_index += gap; - q_index = VPXMIN(q_index, 255); - } - return q_index; -} - -static double get_bits_percent_diff(int target_bits, int actual_bits) { - double diff; - target_bits = VPXMAX(target_bits, 1); - diff = abs(target_bits - actual_bits) * 1. / target_bits; - return diff * 100; -} - -static int rq_model_predict_q_index(const RATE_QSTEP_MODEL *rq_model, - const RATE_QINDEX_HISTORY *rq_history, - int target_bits) { - int q_index = 128; - if (rq_history->recode_count > 0) { - const int actual_bits = - rq_history->rate_history[rq_history->recode_count - 1]; - const int prev_q_index = - rq_history->q_index_history[rq_history->recode_count - 1]; - const double percent_diff = get_bits_percent_diff(target_bits, actual_bits); - if (percent_diff > 50) { - // Binary search. - // When the actual_bits and target_bits are far apart, binary search - // q_index is faster. - q_index = (rq_history->q_index_low + rq_history->q_index_high) / 2; - } else { - if (rq_model->ready) { - q_index = guess_q_index_from_model(rq_model, target_bits); - } else { - // TODO(angiebird): Find a better way to set the gap. - q_index = - guess_q_index_linear(prev_q_index, target_bits, actual_bits, 20); - } - } - } else { - if (rq_model->ready) { - q_index = guess_q_index_from_model(rq_model, target_bits); - } - } - - assert(rq_history->q_index_low <= rq_history->q_index_high); - if (q_index <= rq_history->q_index_low) { - q_index = rq_history->q_index_low + 1; - } - if (q_index >= rq_history->q_index_high) { - q_index = rq_history->q_index_high - 1; - } - return q_index; -} - -static void rq_model_update(const RATE_QINDEX_HISTORY *rq_history, - int target_bits, RATE_QSTEP_MODEL *rq_model) { - const int recode_count = rq_history->recode_count; - const double delta = 0.00001; - if (recode_count >= 2) { - const int q_index1 = rq_history->q_index_history[recode_count - 2]; - const int q_index2 = rq_history->q_index_history[recode_count - 1]; - const int r1 = rq_history->rate_history[recode_count - 2]; - const int r2 = rq_history->rate_history[recode_count - 1]; - int valid = 0; - // lower q_index should yield higher bit rate - if (q_index1 < q_index2) { - valid = r1 > r2; - } else if (q_index1 > q_index2) { - valid = r1 < r2; - } - // Only update the model when the q_index and rate behave normally. - if (valid) { - // Fit the ratio and bias of rq_model based on last two recode histories. - const double s1 = vp9_convert_qindex_to_q(q_index1, VPX_BITS_8); - const double s2 = vp9_convert_qindex_to_q(q_index2, VPX_BITS_8); - if (fabs(log2(s1) - log2(s2)) > delta) { - rq_model->ratio = (r2 - r1) / (log2(s1) - log2(s2)); - rq_model->bias = r1 + (rq_model->ratio) * log2(s1); - if (rq_model->ratio > delta && rq_model->bias > delta) { - rq_model->ready = 1; - } - } - } - } else if (recode_count == 1) { - if (rq_model->ready) { - // Update the ratio only when the initial model exists and we only have - // one recode history. - const int prev_q = rq_history->q_index_history[recode_count - 1]; - const double prev_q_step = vp9_convert_qindex_to_q(prev_q, VPX_BITS_8); - if (fabs(log2(prev_q_step)) > delta) { - const int actual_bits = rq_history->rate_history[recode_count - 1]; - rq_model->ratio = - rq_model->ratio + (target_bits - actual_bits) / log2(prev_q_step); - } - } - } -} -#endif // CONFIG_RATE_CTRL - -static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, uint8_t *dest, - size_t dest_size -#if CONFIG_RATE_CTRL - , - RATE_QINDEX_HISTORY *rq_history -#endif // CONFIG_RATE_CTRL -) { - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - VP9_COMMON *const cm = &cpi->common; - RATE_CONTROL *const rc = &cpi->rc; - int bottom_index, top_index; - int loop_count = 0; - int loop_at_this_size = 0; - int loop = 0; - int overshoot_seen = 0; - int undershoot_seen = 0; - int frame_over_shoot_limit; - int frame_under_shoot_limit; - int q = 0, q_low = 0, q_high = 0; - int enable_acl; -#ifdef AGGRESSIVE_VBR - int qrange_adj = 1; -#endif - - const int orig_rc_max_frame_bandwidth = rc->max_frame_bandwidth; - -#if CONFIG_RATE_CTRL - RATE_QSTEP_MODEL *rq_model; - { - const FRAME_UPDATE_TYPE update_type = - cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index]; - const ENCODE_FRAME_TYPE frame_type = get_encode_frame_type(update_type); - rq_model = &cpi->rq_model[frame_type]; - } - init_rq_history(rq_history); -#endif // CONFIG_RATE_CTRL - - if (cm->show_existing_frame) { - rc->this_frame_target = 0; - if (is_psnr_calc_enabled(cpi)) set_raw_source_frame(cpi); - return; - } - - set_size_independent_vars(cpi); - - enable_acl = cpi->sf.allow_acl ? (cm->frame_type == KEY_FRAME) || - (cpi->twopass.gf_group.index == 1) - : 0; - -#if CONFIG_COLLECT_COMPONENT_TIMING - printf("\n Encoding a frame: \n"); -#endif - do { - vpx_clear_system_state(); - - set_frame_size(cpi); - - if (loop_count == 0 || cpi->resize_pending != 0) { - set_size_dependent_vars(cpi, &q, &bottom_index, &top_index); - -#ifdef AGGRESSIVE_VBR - if (two_pass_first_group_inter(cpi)) { - // Adjustment limits for min and max q - qrange_adj = VPXMAX(1, (top_index - bottom_index) / 2); - - bottom_index = - VPXMAX(bottom_index - qrange_adj / 2, oxcf->best_allowed_q); - top_index = VPXMIN(oxcf->worst_allowed_q, top_index + qrange_adj / 2); - } -#endif - // TODO(agrange) Scale cpi->max_mv_magnitude if frame-size has changed. - set_mv_search_params(cpi); - - // Reset the loop state for new frame size. - overshoot_seen = 0; - undershoot_seen = 0; - - // Reconfiguration for change in frame size has concluded. - cpi->resize_pending = 0; - - q_low = bottom_index; - q_high = top_index; - - loop_at_this_size = 0; - } - - // Decide frame size bounds first time through. - if (loop_count == 0) { - vp9_rc_compute_frame_size_bounds(cpi, rc->this_frame_target, - &frame_under_shoot_limit, - &frame_over_shoot_limit); - } - - cpi->Source = - vp9_scale_if_required(cm, cpi->un_scaled_source, &cpi->scaled_source, - (oxcf->pass == 0), EIGHTTAP, 0); - - // Unfiltered raw source used in metrics calculation if the source - // has been filtered. - if (is_psnr_calc_enabled(cpi)) { -#ifdef ENABLE_KF_DENOISE - if (is_spatial_denoise_enabled(cpi)) { - cpi->raw_source_frame = vp9_scale_if_required( - cm, &cpi->raw_unscaled_source, &cpi->raw_scaled_source, - (oxcf->pass == 0), EIGHTTAP, 0); - } else { - cpi->raw_source_frame = cpi->Source; - } -#else - cpi->raw_source_frame = cpi->Source; -#endif - } - - if (cpi->unscaled_last_source != NULL) - cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source, - &cpi->scaled_last_source, - (oxcf->pass == 0), EIGHTTAP, 0); - - if (frame_is_intra_only(cm) == 0) { - if (loop_count > 0) { - release_scaled_references(cpi); - } - vp9_scale_references(cpi); - } - -#if CONFIG_RATE_CTRL - // TODO(angiebird): This is a hack for making sure the encoder use the - // external_quantize_index exactly. Avoid this kind of hack later. - if (cpi->oxcf.use_simple_encode_api) { - if (cpi->encode_command.use_external_target_frame_bits) { - q = rq_model_predict_q_index(rq_model, rq_history, - rc->this_frame_target); - } - if (cpi->encode_command.use_external_quantize_index) { - q = cpi->encode_command.external_quantize_index; - } - } -#endif // CONFIG_RATE_CTRL - const GF_GROUP *gf_group = &cpi->twopass.gf_group; - if (cpi->ext_ratectrl.ready && - (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_QP) != 0 && - cpi->ext_ratectrl.funcs.get_encodeframe_decision != NULL) { - vpx_codec_err_t codec_status; - vpx_rc_encodeframe_decision_t encode_frame_decision; - codec_status = vp9_extrc_get_encodeframe_decision( - &cpi->ext_ratectrl, gf_group->index, &encode_frame_decision); - if (codec_status != VPX_CODEC_OK) { - vpx_internal_error(&cm->error, codec_status, - "vp9_extrc_get_encodeframe_decision() failed"); - } - // If the external model recommends a reserved value, we use - // libvpx's default q. - if (encode_frame_decision.q_index != VPX_DEFAULT_Q) { - q = encode_frame_decision.q_index; - } - } - - if (cpi->ext_ratectrl.ready && cpi->ext_ratectrl.log_file) { - fprintf(cpi->ext_ratectrl.log_file, - "ENCODE_FRAME_INFO gop_index %d update_type %d q %d\n", - gf_group->index, gf_group->update_type[gf_group->index], q); - } - - vp9_set_quantizer(cpi, q); - - if (loop_count == 0) setup_frame(cpi); - - // Variance adaptive and in frame q adjustment experiments are mutually - // exclusive. - if (oxcf->aq_mode == VARIANCE_AQ) { - vp9_vaq_frame_setup(cpi); - } else if (oxcf->aq_mode == EQUATOR360_AQ) { - vp9_360aq_frame_setup(cpi); - } else if (oxcf->aq_mode == COMPLEXITY_AQ) { - vp9_setup_in_frame_q_adj(cpi); - } else if (oxcf->aq_mode == LOOKAHEAD_AQ) { - vp9_alt_ref_aq_setup_map(cpi->alt_ref_aq, cpi); - } else if (oxcf->aq_mode == PSNR_AQ) { - vp9_psnr_aq_mode_setup(&cm->seg); - } - - vp9_encode_frame(cpi); - - // Update the skip mb flag probabilities based on the distribution - // seen in the last encoder iteration. - // update_base_skip_probs(cpi); - - vpx_clear_system_state(); - - // Dummy pack of the bitstream using up to date stats to get an - // accurate estimate of output frame size to determine if we need - // to recode. - if (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF) { - save_coding_context(cpi); - if (!cpi->sf.use_nonrd_pick_mode) - vp9_pack_bitstream(cpi, dest, dest_size, size); - - rc->projected_frame_size = (int)(*size) << 3; - - if (frame_over_shoot_limit == 0) frame_over_shoot_limit = 1; - } - - if (cpi->ext_ratectrl.ready && - (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_QP) != 0) { - break; - } -#if CONFIG_RATE_CTRL - if (cpi->oxcf.use_simple_encode_api) { - // This part needs to be after save_coding_context() because - // restore_coding_context will be called in the end of this function. - // TODO(angiebird): This is a hack for making sure the encoder use the - // external_quantize_index exactly. Avoid this kind of hack later. - if (cpi->encode_command.use_external_quantize_index) { - break; - } - - if (cpi->encode_command.use_external_target_frame_bits) { - const double percent_diff = get_bits_percent_diff( - rc->this_frame_target, rc->projected_frame_size); - update_rq_history(rq_history, rc->this_frame_target, - rc->projected_frame_size, q); - loop_count += 1; - - rq_model_update(rq_history, rc->this_frame_target, rq_model); - - // Check if we hit the target bitrate. - if (percent_diff <= - cpi->encode_command.target_frame_bits_error_percent || - rq_history->recode_count >= RATE_CTRL_MAX_RECODE_NUM || - rq_history->q_index_low >= rq_history->q_index_high) { - break; - } - - loop = 1; - restore_coding_context(cpi); - continue; - } - } -#endif // CONFIG_RATE_CTRL - - if (oxcf->rc_mode == VPX_Q) { - loop = 0; - } else { - if ((cm->frame_type == KEY_FRAME) && rc->this_key_frame_forced && - (rc->projected_frame_size < rc->max_frame_bandwidth)) { - int last_q = q; - int64_t kf_err; - - int64_t high_err_target = cpi->ambient_err; - int64_t low_err_target = cpi->ambient_err >> 1; - -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - kf_err = vpx_highbd_get_y_sse(cpi->Source, get_frame_new_buffer(cm)); - } else { - kf_err = vpx_get_y_sse(cpi->Source, get_frame_new_buffer(cm)); - } -#else - kf_err = vpx_get_y_sse(cpi->Source, get_frame_new_buffer(cm)); -#endif // CONFIG_VP9_HIGHBITDEPTH - - // Prevent possible divide by zero error below for perfect KF - kf_err += !kf_err; - - // The key frame is not good enough or we can afford - // to make it better without undue risk of popping. - if ((kf_err > high_err_target && - rc->projected_frame_size <= frame_over_shoot_limit) || - (kf_err > low_err_target && - rc->projected_frame_size <= frame_under_shoot_limit)) { - // Lower q_high - q_high = q > q_low ? q - 1 : q_low; - - // Adjust Q - q = (int)((q * high_err_target) / kf_err); - q = VPXMIN(q, (q_high + q_low) >> 1); - } else if (kf_err < low_err_target && - rc->projected_frame_size >= frame_under_shoot_limit) { - // The key frame is much better than the previous frame - // Raise q_low - q_low = q < q_high ? q + 1 : q_high; - - // Adjust Q - q = (int)((q * low_err_target) / kf_err); - q = VPXMIN(q, (q_high + q_low + 1) >> 1); - } - - // Clamp Q to upper and lower limits: - q = clamp(q, q_low, q_high); - - loop = q != last_q; - } else if (recode_loop_test(cpi, frame_over_shoot_limit, - frame_under_shoot_limit, q, - VPXMAX(q_high, top_index), bottom_index)) { - // Is the projected frame size out of range and are we allowed - // to attempt to recode. - int last_q = q; - int retries = 0; - int qstep; - - if (cpi->resize_pending == 1) { - // Change in frame size so go back around the recode loop. - cpi->rc.frame_size_selector = - SCALE_STEP1 - cpi->rc.frame_size_selector; - cpi->rc.next_frame_size_selector = cpi->rc.frame_size_selector; - -#if CONFIG_INTERNAL_STATS - ++cpi->tot_recode_hits; -#endif - ++loop_count; - loop = 1; - continue; - } - - // Frame size out of permitted range: - // Update correction factor & compute new Q to try... - - // Frame is too large - if (rc->projected_frame_size > rc->this_frame_target) { - // Special case if the projected size is > the max allowed. - if ((q == q_high) && - ((rc->projected_frame_size >= rc->max_frame_bandwidth) || - (!rc->is_src_frame_alt_ref && - (rc->projected_frame_size >= - big_rate_miss_high_threshold(cpi))))) { - int max_rate = VPXMAX(1, VPXMIN(rc->max_frame_bandwidth, - big_rate_miss_high_threshold(cpi))); - double q_val_high; - q_val_high = vp9_convert_qindex_to_q(q_high, cm->bit_depth); - q_val_high = - q_val_high * ((double)rc->projected_frame_size / max_rate); - q_high = vp9_convert_q_to_qindex(q_val_high, cm->bit_depth); - q_high = clamp(q_high, rc->best_quality, rc->worst_quality); - } - - // Raise Qlow as to at least the current value - qstep = - get_qstep_adj(rc->projected_frame_size, rc->this_frame_target); - q_low = VPXMIN(q + qstep, q_high); - - if (undershoot_seen || loop_at_this_size > 1) { - // Update rate_correction_factor unless - vp9_rc_update_rate_correction_factors(cpi); - - q = (q_high + q_low + 1) / 2; - } else { - // Update rate_correction_factor unless - vp9_rc_update_rate_correction_factors(cpi); - - q = vp9_rc_regulate_q(cpi, rc->this_frame_target, bottom_index, - VPXMAX(q_high, top_index)); - - while (q < q_low && retries < 10) { - vp9_rc_update_rate_correction_factors(cpi); - q = vp9_rc_regulate_q(cpi, rc->this_frame_target, bottom_index, - VPXMAX(q_high, top_index)); - retries++; - } - } - - overshoot_seen = 1; - } else { - // Frame is too small - qstep = - get_qstep_adj(rc->this_frame_target, rc->projected_frame_size); - q_high = VPXMAX(q - qstep, q_low); - - if (overshoot_seen || loop_at_this_size > 1) { - vp9_rc_update_rate_correction_factors(cpi); - q = (q_high + q_low) / 2; - } else { - vp9_rc_update_rate_correction_factors(cpi); - q = vp9_rc_regulate_q(cpi, rc->this_frame_target, - VPXMIN(q_low, bottom_index), top_index); - // Special case reset for qlow for constrained quality. - // This should only trigger where there is very substantial - // undershoot on a frame and the auto cq level is above - // the user passed in value. - if (oxcf->rc_mode == VPX_CQ && q < q_low) { - q_low = q; - } - - while (q > q_high && retries < 10) { - vp9_rc_update_rate_correction_factors(cpi); - q = vp9_rc_regulate_q(cpi, rc->this_frame_target, - VPXMIN(q_low, bottom_index), top_index); - retries++; - } - } - undershoot_seen = 1; - } - - // Clamp Q to upper and lower limits: - q = clamp(q, q_low, q_high); - - loop = (q != last_q); - } else { - loop = 0; - } - } - - // Special case for overlay frame. - if (rc->is_src_frame_alt_ref && - rc->projected_frame_size < rc->max_frame_bandwidth) - loop = 0; - - if (loop) { - ++loop_count; - ++loop_at_this_size; - -#if CONFIG_INTERNAL_STATS - ++cpi->tot_recode_hits; -#endif - } - - if (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF) - if (loop) restore_coding_context(cpi); -#if CONFIG_COLLECT_COMPONENT_TIMING - if (loop) printf("\n Recoding:"); -#endif - } while (loop); - - rc->max_frame_bandwidth = orig_rc_max_frame_bandwidth; - -#ifdef AGGRESSIVE_VBR - if (two_pass_first_group_inter(cpi)) { - cpi->twopass.active_worst_quality = - VPXMIN(q + qrange_adj, oxcf->worst_allowed_q); - } else if (!frame_is_kf_gf_arf(cpi)) { -#else - if (!frame_is_kf_gf_arf(cpi)) { -#endif - // Have we been forced to adapt Q outside the expected range by an extreme - // rate miss. If so adjust the active maxQ for the subsequent frames. - if (!rc->is_src_frame_alt_ref && (q > cpi->twopass.active_worst_quality)) { - cpi->twopass.active_worst_quality = q; - } else if (oxcf->vbr_corpus_complexity && q == q_low && - rc->projected_frame_size < rc->this_frame_target) { - cpi->twopass.active_worst_quality = - VPXMAX(q, cpi->twopass.active_worst_quality - 1); - } - } - - if (enable_acl) { - // Skip recoding, if model diff is below threshold - const int thresh = compute_context_model_thresh(cpi); - const int diff = compute_context_model_diff(cm); - if (diff >= thresh) { - vp9_encode_frame(cpi); - } - } - if (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF) { - vpx_clear_system_state(); - restore_coding_context(cpi); - } -} -#endif // !CONFIG_REALTIME_ONLY - -static void set_ext_overrides(VP9_COMP *cpi) { - // Overrides the defaults with the externally supplied values with - // vp9_update_reference() and vp9_update_entropy() calls - // Note: The overrides are valid only for the next frame passed - // to encode_frame_to_data_rate() function - if (cpi->ext_refresh_frame_context_pending) { - cpi->common.refresh_frame_context = cpi->ext_refresh_frame_context; - cpi->ext_refresh_frame_context_pending = 0; - } - if (cpi->ext_refresh_frame_flags_pending) { - cpi->refresh_last_frame = cpi->ext_refresh_last_frame; - cpi->refresh_golden_frame = cpi->ext_refresh_golden_frame; - cpi->refresh_alt_ref_frame = cpi->ext_refresh_alt_ref_frame; - } -} - -YV12_BUFFER_CONFIG *vp9_scale_if_required( - VP9_COMMON *cm, YV12_BUFFER_CONFIG *unscaled, YV12_BUFFER_CONFIG *scaled, - int use_normative_scaler, INTERP_FILTER filter_type, int phase_scaler) { - if (cm->mi_cols * MI_SIZE != unscaled->y_width || - cm->mi_rows * MI_SIZE != unscaled->y_height) { -#if CONFIG_VP9_HIGHBITDEPTH - if (use_normative_scaler && unscaled->y_width <= (scaled->y_width << 1) && - unscaled->y_height <= (scaled->y_height << 1)) - if (cm->bit_depth == VPX_BITS_8) - vp9_scale_and_extend_frame(unscaled, scaled, filter_type, phase_scaler); - else - scale_and_extend_frame(unscaled, scaled, (int)cm->bit_depth, - filter_type, phase_scaler); - else - vp9_scale_and_extend_frame_nonnormative(unscaled, scaled, - (int)cm->bit_depth); -#else - if (use_normative_scaler && unscaled->y_width <= (scaled->y_width << 1) && - unscaled->y_height <= (scaled->y_height << 1)) - vp9_scale_and_extend_frame(unscaled, scaled, filter_type, phase_scaler); - else - vp9_scale_and_extend_frame_nonnormative(unscaled, scaled); -#endif // CONFIG_VP9_HIGHBITDEPTH - return scaled; - } else { - return unscaled; - } -} - -static void set_ref_sign_bias(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - RefCntBuffer *const ref_buffer = get_ref_cnt_buffer(cm, cm->new_fb_idx); - const int cur_frame_index = ref_buffer->frame_index; - MV_REFERENCE_FRAME ref_frame; - - for (ref_frame = LAST_FRAME; ref_frame < MAX_REF_FRAMES; ++ref_frame) { - const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame); - const RefCntBuffer *const ref_cnt_buf = - get_ref_cnt_buffer(&cpi->common, buf_idx); - if (ref_cnt_buf) { - cm->ref_frame_sign_bias[ref_frame] = - cur_frame_index < ref_cnt_buf->frame_index; - } - } -} - -static int setup_interp_filter_search_mask(VP9_COMP *cpi) { - INTERP_FILTER ifilter; - int ref_total[MAX_REF_FRAMES] = { 0 }; - MV_REFERENCE_FRAME ref; - int mask = 0; - if (cpi->common.last_frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame) - return mask; - for (ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref) - for (ifilter = EIGHTTAP; ifilter <= EIGHTTAP_SHARP; ++ifilter) - ref_total[ref] += cpi->interp_filter_selected[ref][ifilter]; - - for (ifilter = EIGHTTAP; ifilter <= EIGHTTAP_SHARP; ++ifilter) { - if ((ref_total[LAST_FRAME] && - cpi->interp_filter_selected[LAST_FRAME][ifilter] == 0) && - (ref_total[GOLDEN_FRAME] == 0 || - cpi->interp_filter_selected[GOLDEN_FRAME][ifilter] * 50 < - ref_total[GOLDEN_FRAME]) && - (ref_total[ALTREF_FRAME] == 0 || - cpi->interp_filter_selected[ALTREF_FRAME][ifilter] * 50 < - ref_total[ALTREF_FRAME])) - mask |= 1 << ifilter; - } - return mask; -} - -#ifdef ENABLE_KF_DENOISE -// Baseline kernel weights for denoise -static uint8_t dn_kernel_3[9] = { 1, 2, 1, 2, 4, 2, 1, 2, 1 }; -static uint8_t dn_kernel_5[25] = { 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 4, - 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1 }; - -static INLINE void add_denoise_point(int centre_val, int data_val, int thresh, - uint8_t point_weight, int *sum_val, - int *sum_weight) { - if (abs(centre_val - data_val) <= thresh) { - *sum_weight += point_weight; - *sum_val += (int)data_val * (int)point_weight; - } -} - -static void spatial_denoise_point(uint8_t *src_ptr, const int stride, - const int strength) { - int sum_weight = 0; - int sum_val = 0; - int thresh = strength; - int kernel_size = 5; - int half_k_size = 2; - int i, j; - int max_diff = 0; - uint8_t *tmp_ptr; - uint8_t *kernel_ptr; - - // Find the maximum deviation from the source point in the locale. - tmp_ptr = src_ptr - (stride * (half_k_size + 1)) - (half_k_size + 1); - for (i = 0; i < kernel_size + 2; ++i) { - for (j = 0; j < kernel_size + 2; ++j) { - max_diff = VPXMAX(max_diff, abs((int)*src_ptr - (int)tmp_ptr[j])); - } - tmp_ptr += stride; - } - - // Select the kernel size. - if (max_diff > (strength + (strength >> 1))) { - kernel_size = 3; - half_k_size = 1; - thresh = thresh >> 1; - } - kernel_ptr = (kernel_size == 3) ? dn_kernel_3 : dn_kernel_5; - - // Apply the kernel - tmp_ptr = src_ptr - (stride * half_k_size) - half_k_size; - for (i = 0; i < kernel_size; ++i) { - for (j = 0; j < kernel_size; ++j) { - add_denoise_point((int)*src_ptr, (int)tmp_ptr[j], thresh, *kernel_ptr, - &sum_val, &sum_weight); - ++kernel_ptr; - } - tmp_ptr += stride; - } - - // Update the source value with the new filtered value - *src_ptr = (uint8_t)((sum_val + (sum_weight >> 1)) / sum_weight); -} - -#if CONFIG_VP9_HIGHBITDEPTH -static void highbd_spatial_denoise_point(uint16_t *src_ptr, const int stride, - const int strength) { - int sum_weight = 0; - int sum_val = 0; - int thresh = strength; - int kernel_size = 5; - int half_k_size = 2; - int i, j; - int max_diff = 0; - uint16_t *tmp_ptr; - uint8_t *kernel_ptr; - - // Find the maximum deviation from the source point in the locale. - tmp_ptr = src_ptr - (stride * (half_k_size + 1)) - (half_k_size + 1); - for (i = 0; i < kernel_size + 2; ++i) { - for (j = 0; j < kernel_size + 2; ++j) { - max_diff = VPXMAX(max_diff, abs((int)src_ptr - (int)tmp_ptr[j])); - } - tmp_ptr += stride; - } - - // Select the kernel size. - if (max_diff > (strength + (strength >> 1))) { - kernel_size = 3; - half_k_size = 1; - thresh = thresh >> 1; - } - kernel_ptr = (kernel_size == 3) ? dn_kernel_3 : dn_kernel_5; - - // Apply the kernel - tmp_ptr = src_ptr - (stride * half_k_size) - half_k_size; - for (i = 0; i < kernel_size; ++i) { - for (j = 0; j < kernel_size; ++j) { - add_denoise_point((int)*src_ptr, (int)tmp_ptr[j], thresh, *kernel_ptr, - &sum_val, &sum_weight); - ++kernel_ptr; - } - tmp_ptr += stride; - } - - // Update the source value with the new filtered value - *src_ptr = (uint16_t)((sum_val + (sum_weight >> 1)) / sum_weight); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -// Apply thresholded spatial noise suppression to a given buffer. -static void spatial_denoise_buffer(VP9_COMP *cpi, uint8_t *buffer, - const int stride, const int width, - const int height, const int strength) { - VP9_COMMON *const cm = &cpi->common; - uint8_t *src_ptr = buffer; - int row; - int col; - - for (row = 0; row < height; ++row) { - for (col = 0; col < width; ++col) { -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) - highbd_spatial_denoise_point(CONVERT_TO_SHORTPTR(&src_ptr[col]), stride, - strength); - else - spatial_denoise_point(&src_ptr[col], stride, strength); -#else - spatial_denoise_point(&src_ptr[col], stride, strength); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - src_ptr += stride; - } -} - -// Apply thresholded spatial noise suppression to source. -static void spatial_denoise_frame(VP9_COMP *cpi) { - YV12_BUFFER_CONFIG *src = cpi->Source; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - TWO_PASS *const twopass = &cpi->twopass; - VP9_COMMON *const cm = &cpi->common; - - // Base the filter strength on the current active max Q. - const int q = (int)(vp9_convert_qindex_to_q(twopass->active_worst_quality, - cm->bit_depth)); - int strength = - VPXMAX(oxcf->arnr_strength >> 2, VPXMIN(oxcf->arnr_strength, (q >> 4))); - - // Denoise each of Y,U and V buffers. - spatial_denoise_buffer(cpi, src->y_buffer, src->y_stride, src->y_width, - src->y_height, strength); - - strength += (strength >> 1); - spatial_denoise_buffer(cpi, src->u_buffer, src->uv_stride, src->uv_width, - src->uv_height, strength << 1); - - spatial_denoise_buffer(cpi, src->v_buffer, src->uv_stride, src->uv_width, - src->uv_height, strength << 1); -} -#endif // ENABLE_KF_DENOISE - -#if !CONFIG_REALTIME_ONLY -static void vp9_try_disable_lookahead_aq(VP9_COMP *cpi, size_t *size, - uint8_t *dest, size_t dest_size) { - if (cpi->common.seg.enabled) - if (ALT_REF_AQ_PROTECT_GAIN) { - size_t nsize = *size; - int overhead; - - // TODO(yuryg): optimize this, as - // we don't really need to repack - - save_coding_context(cpi); - vp9_disable_segmentation(&cpi->common.seg); - vp9_pack_bitstream(cpi, dest, dest_size, &nsize); - restore_coding_context(cpi); - - overhead = (int)*size - (int)nsize; - - if (vp9_alt_ref_aq_disable_if(cpi->alt_ref_aq, overhead, (int)*size)) - vp9_encode_frame(cpi); - else - vp9_enable_segmentation(&cpi->common.seg); - } -} -#endif - -static void set_frame_index(VP9_COMP *cpi, VP9_COMMON *cm) { - RefCntBuffer *const ref_buffer = get_ref_cnt_buffer(cm, cm->new_fb_idx); - - if (ref_buffer) { - const GF_GROUP *const gf_group = &cpi->twopass.gf_group; - ref_buffer->frame_index = - cm->current_video_frame + gf_group->arf_src_offset[gf_group->index]; - ref_buffer->frame_coding_index = cm->current_frame_coding_index; - } -} - -static void set_mb_ssim_rdmult_scaling(VP9_COMP *cpi) { - VP9_COMMON *cm = &cpi->common; - ThreadData *td = &cpi->td; - MACROBLOCK *x = &td->mb; - MACROBLOCKD *xd = &x->e_mbd; - uint8_t *y_buffer = cpi->Source->y_buffer; - const int y_stride = cpi->Source->y_stride; - const int block_size = BLOCK_16X16; - - const int num_8x8_w = num_8x8_blocks_wide_lookup[block_size]; - const int num_8x8_h = num_8x8_blocks_high_lookup[block_size]; - const int num_cols = (cm->mi_cols + num_8x8_w - 1) / num_8x8_w; - const int num_rows = (cm->mi_rows + num_8x8_h - 1) / num_8x8_h; - double log_sum = 0.0; - int row, col; - - // Loop through each 64x64 block. - for (row = 0; row < num_rows; ++row) { - for (col = 0; col < num_cols; ++col) { - int mi_row, mi_col; - double var = 0.0, num_of_var = 0.0; - const int index = row * num_cols + col; - - for (mi_row = row * num_8x8_h; - mi_row < cm->mi_rows && mi_row < (row + 1) * num_8x8_h; ++mi_row) { - for (mi_col = col * num_8x8_w; - mi_col < cm->mi_cols && mi_col < (col + 1) * num_8x8_w; ++mi_col) { - struct buf_2d buf; - const int row_offset_y = mi_row << 3; - const int col_offset_y = mi_col << 3; - - buf.buf = y_buffer + row_offset_y * y_stride + col_offset_y; - buf.stride = y_stride; - - // In order to make SSIM_VAR_SCALE in a same scale for both 8 bit - // and high bit videos, the variance needs to be divided by 2.0 or - // 64.0 separately. - // TODO(sdeng): need to tune for 12bit videos. -#if CONFIG_VP9_HIGHBITDEPTH - if (cpi->Source->flags & YV12_FLAG_HIGHBITDEPTH) - var += vp9_high_get_sby_variance(cpi, &buf, BLOCK_8X8, xd->bd); - else -#endif - var += vp9_get_sby_variance(cpi, &buf, BLOCK_8X8); - - num_of_var += 1.0; - } - } - var = var / num_of_var / 64.0; - - // Curve fitting with an exponential model on all 16x16 blocks from the - // Midres dataset. - var = 67.035434 * (1 - exp(-0.0021489 * var)) + 17.492222; - cpi->mi_ssim_rdmult_scaling_factors[index] = var; - log_sum += log(var); - } - } - log_sum = exp(log_sum / (double)(num_rows * num_cols)); - - for (row = 0; row < num_rows; ++row) { - for (col = 0; col < num_cols; ++col) { - const int index = row * num_cols + col; - cpi->mi_ssim_rdmult_scaling_factors[index] /= log_sum; - } - } - - (void)xd; -} - -// Process the wiener variance in 16x16 block basis. -static int qsort_comp(const void *elem1, const void *elem2) { - int a = *((const int *)elem1); - int b = *((const int *)elem2); - if (a > b) return 1; - if (a < b) return -1; - return 0; -} - -static void init_mb_wiener_var_buffer(VP9_COMP *cpi) { - VP9_COMMON *cm = &cpi->common; - - if (cpi->mb_wiener_variance && cpi->mb_wiener_var_rows >= cm->mb_rows && - cpi->mb_wiener_var_cols >= cm->mb_cols) - return; - - vpx_free(cpi->mb_wiener_variance); - cpi->mb_wiener_variance = NULL; - - CHECK_MEM_ERROR( - &cm->error, cpi->mb_wiener_variance, - vpx_calloc(cm->mb_rows * cm->mb_cols, sizeof(*cpi->mb_wiener_variance))); - cpi->mb_wiener_var_rows = cm->mb_rows; - cpi->mb_wiener_var_cols = cm->mb_cols; -} - -static void set_mb_wiener_variance(VP9_COMP *cpi) { - VP9_COMMON *cm = &cpi->common; - uint8_t *buffer = cpi->Source->y_buffer; - int buf_stride = cpi->Source->y_stride; - -#if CONFIG_VP9_HIGHBITDEPTH - ThreadData *td = &cpi->td; - MACROBLOCK *x = &td->mb; - MACROBLOCKD *xd = &x->e_mbd; - DECLARE_ALIGNED(16, uint16_t, zero_pred16[32 * 32]); - DECLARE_ALIGNED(16, uint8_t, zero_pred8[32 * 32]); - uint8_t *zero_pred; -#else - DECLARE_ALIGNED(16, uint8_t, zero_pred[32 * 32]); -#endif - - DECLARE_ALIGNED(16, int16_t, src_diff[32 * 32]); - DECLARE_ALIGNED(16, tran_low_t, coeff[32 * 32]); - - int mb_row, mb_col, count = 0; - // Hard coded operating block size - const int block_size = 16; - const int coeff_count = block_size * block_size; - const TX_SIZE tx_size = TX_16X16; - -#if CONFIG_VP9_HIGHBITDEPTH - xd->cur_buf = cpi->Source; - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - zero_pred = CONVERT_TO_BYTEPTR(zero_pred16); - memset(zero_pred16, 0, sizeof(*zero_pred16) * coeff_count); - } else { - zero_pred = zero_pred8; - memset(zero_pred8, 0, sizeof(*zero_pred8) * coeff_count); - } -#else - memset(zero_pred, 0, sizeof(*zero_pred) * coeff_count); -#endif - - cpi->norm_wiener_variance = 0; - - for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) { - for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) { - int idx; - int16_t median_val = 0; - uint8_t *mb_buffer = - buffer + mb_row * block_size * buf_stride + mb_col * block_size; - int64_t wiener_variance = 0; - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - vpx_highbd_subtract_block(block_size, block_size, src_diff, block_size, - mb_buffer, buf_stride, zero_pred, block_size, - xd->bd); - vp9_highbd_wht_fwd_txfm(src_diff, block_size, coeff, tx_size); - } else { - vpx_subtract_block(block_size, block_size, src_diff, block_size, - mb_buffer, buf_stride, zero_pred, block_size); - vp9_wht_fwd_txfm(src_diff, block_size, coeff, tx_size); - } -#else - vpx_subtract_block(block_size, block_size, src_diff, block_size, - mb_buffer, buf_stride, zero_pred, block_size); - vp9_wht_fwd_txfm(src_diff, block_size, coeff, tx_size); -#endif // CONFIG_VP9_HIGHBITDEPTH - - coeff[0] = 0; - for (idx = 1; idx < coeff_count; ++idx) coeff[idx] = abs(coeff[idx]); - - qsort(coeff, coeff_count - 1, sizeof(*coeff), qsort_comp); - - // Noise level estimation - median_val = coeff[coeff_count / 2]; - - // Wiener filter - for (idx = 1; idx < coeff_count; ++idx) { - int64_t sqr_coeff = (int64_t)coeff[idx] * coeff[idx]; - int64_t tmp_coeff = (int64_t)coeff[idx]; - if (median_val) { - tmp_coeff = (sqr_coeff * coeff[idx]) / - (sqr_coeff + (int64_t)median_val * median_val); - } - wiener_variance += tmp_coeff * tmp_coeff; - } - cpi->mb_wiener_variance[mb_row * cm->mb_cols + mb_col] = - wiener_variance / coeff_count; - cpi->norm_wiener_variance += - cpi->mb_wiener_variance[mb_row * cm->mb_cols + mb_col]; - ++count; - } - } - - if (count) cpi->norm_wiener_variance /= count; - cpi->norm_wiener_variance = VPXMAX(1, cpi->norm_wiener_variance); -} - -#if !CONFIG_REALTIME_ONLY -static PSNR_STATS compute_psnr_stats(const YV12_BUFFER_CONFIG *source_frame, - const YV12_BUFFER_CONFIG *coded_frame, - uint32_t bit_depth, - uint32_t input_bit_depth) { - PSNR_STATS psnr; -#if CONFIG_VP9_HIGHBITDEPTH - vpx_calc_highbd_psnr(source_frame, coded_frame, &psnr, bit_depth, - input_bit_depth); -#else // CONFIG_VP9_HIGHBITDEPTH - (void)bit_depth; - (void)input_bit_depth; - vpx_calc_psnr(source_frame, coded_frame, &psnr); -#endif // CONFIG_VP9_HIGHBITDEPTH - return psnr; -} - -static void update_encode_frame_result_basic( - FRAME_UPDATE_TYPE update_type, int show_idx, int quantize_index, - ENCODE_FRAME_RESULT *encode_frame_result) { - encode_frame_result->show_idx = show_idx; - encode_frame_result->update_type = update_type; - encode_frame_result->quantize_index = quantize_index; -} - -#if CONFIG_RATE_CTRL -static void yv12_buffer_to_image_buffer(const YV12_BUFFER_CONFIG *yv12_buffer, - IMAGE_BUFFER *image_buffer) { - const uint8_t *src_buf_ls[3] = { yv12_buffer->y_buffer, yv12_buffer->u_buffer, - yv12_buffer->v_buffer }; - const int src_stride_ls[3] = { yv12_buffer->y_stride, yv12_buffer->uv_stride, - yv12_buffer->uv_stride }; - const int w_ls[3] = { yv12_buffer->y_crop_width, yv12_buffer->uv_crop_width, - yv12_buffer->uv_crop_width }; - const int h_ls[3] = { yv12_buffer->y_crop_height, yv12_buffer->uv_crop_height, - yv12_buffer->uv_crop_height }; - int plane; - for (plane = 0; plane < 3; ++plane) { - const int src_stride = src_stride_ls[plane]; - const int w = w_ls[plane]; - const int h = h_ls[plane]; - const uint8_t *src_buf = src_buf_ls[plane]; - uint8_t *dst_buf = image_buffer->plane_buffer[plane]; - int r; - assert(image_buffer->plane_width[plane] == w); - assert(image_buffer->plane_height[plane] == h); - for (r = 0; r < h; ++r) { - memcpy(dst_buf, src_buf, sizeof(*src_buf) * w); - src_buf += src_stride; - dst_buf += w; - } - } -} - -// This function will update extra information specific for simple_encode APIs -static void update_encode_frame_result_simple_encode( - int ref_frame_flags, FRAME_UPDATE_TYPE update_type, - const YV12_BUFFER_CONFIG *source_frame, const RefCntBuffer *coded_frame_buf, - RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], int quantize_index, - uint32_t bit_depth, uint32_t input_bit_depth, const FRAME_COUNTS *counts, - const PARTITION_INFO *partition_info, - const MOTION_VECTOR_INFO *motion_vector_info, - const TplDepStats *tpl_stats_info, - ENCODE_FRAME_RESULT *encode_frame_result) { - PSNR_STATS psnr; - update_encode_frame_result_basic(update_type, coded_frame_buf->frame_index, - quantize_index, encode_frame_result); - compute_psnr_stats(source_frame, &coded_frame_buf->buf, bit_depth, - input_bit_depth); - encode_frame_result->frame_coding_index = coded_frame_buf->frame_coding_index; - - vp9_get_ref_frame_info(update_type, ref_frame_flags, ref_frame_bufs, - encode_frame_result->ref_frame_coding_indexes, - encode_frame_result->ref_frame_valid_list); - - encode_frame_result->psnr = psnr.psnr[0]; - encode_frame_result->sse = psnr.sse[0]; - encode_frame_result->frame_counts = *counts; - encode_frame_result->partition_info = partition_info; - encode_frame_result->motion_vector_info = motion_vector_info; - encode_frame_result->tpl_stats_info = tpl_stats_info; - if (encode_frame_result->coded_frame.allocated) { - yv12_buffer_to_image_buffer(&coded_frame_buf->buf, - &encode_frame_result->coded_frame); - } -} -#endif // CONFIG_RATE_CTRL -#endif // !CONFIG_REALTIME_ONLY - -static void encode_frame_to_data_rate( - VP9_COMP *cpi, size_t *size, uint8_t *dest, size_t dest_size, - unsigned int *frame_flags, ENCODE_FRAME_RESULT *encode_frame_result) { - VP9_COMMON *const cm = &cpi->common; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - struct segmentation *const seg = &cm->seg; - TX_SIZE t; - - if (vp9_svc_check_skip_enhancement_layer(cpi)) return; - - set_ext_overrides(cpi); - vpx_clear_system_state(); - -#ifdef ENABLE_KF_DENOISE - // Spatial denoise of key frame. - if (is_spatial_denoise_enabled(cpi)) spatial_denoise_frame(cpi); -#endif - - if (cm->show_existing_frame == 0) { - // Update frame index - set_frame_index(cpi, cm); - - // Set the arf sign bias for this frame. - set_ref_sign_bias(cpi); - } - - // On the very first frame set the deadline_mode_previous_frame to - // the current mode. - if (cpi->common.current_video_frame == 0) - cpi->deadline_mode_previous_frame = cpi->oxcf.mode; - - // Set default state for segment based loop filter update flags. - cm->lf.mode_ref_delta_update = 0; - - if (cpi->oxcf.pass == 2 && cpi->sf.adaptive_interp_filter_search) - cpi->sf.interp_filter_search_mask = setup_interp_filter_search_mask(cpi); - - // Set various flags etc to special state if it is a key frame. - if (frame_is_intra_only(cm)) { - // Reset the loop filter deltas and segmentation map. - vp9_reset_segment_features(&cm->seg); - - // If segmentation is enabled force a map update for key frames. - if (seg->enabled) { - seg->update_map = 1; - seg->update_data = 1; - } - - // The alternate reference frame cannot be active for a key frame. - cpi->rc.source_alt_ref_active = 0; - - cm->error_resilient_mode = oxcf->error_resilient_mode; - cm->frame_parallel_decoding_mode = oxcf->frame_parallel_decoding_mode; - - // By default, encoder assumes decoder can use prev_mi. - if (cm->error_resilient_mode) { - cm->frame_parallel_decoding_mode = 1; - cm->reset_frame_context = 0; - cm->refresh_frame_context = 0; - } else if (cm->intra_only) { - // Only reset the current context. - cm->reset_frame_context = 2; - } - } - - if (oxcf->tuning == VP8_TUNE_SSIM) set_mb_ssim_rdmult_scaling(cpi); - - if (oxcf->aq_mode == PERCEPTUAL_AQ) { - init_mb_wiener_var_buffer(cpi); - set_mb_wiener_variance(cpi); - } - - vpx_clear_system_state(); - -#if CONFIG_INTERNAL_STATS - memset(cpi->mode_chosen_counts, 0, - MAX_MODES * sizeof(*cpi->mode_chosen_counts)); -#endif - // Backup to ensure consistency between recodes - save_encode_params(cpi); - if (cpi->ext_ratectrl.ready && - (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_RDMULT) != 0 && - cpi->ext_ratectrl.funcs.get_frame_rdmult != NULL) { - vpx_codec_err_t codec_status; - const GF_GROUP *gf_group = &cpi->twopass.gf_group; - FRAME_UPDATE_TYPE update_type = gf_group->update_type[gf_group->index]; - const int ref_frame_flags = get_ref_frame_flags(cpi); - RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES]; - const RefCntBuffer *curr_frame_buf = get_ref_cnt_buffer(cm, cm->new_fb_idx); - // index 0 of a gf group is always KEY/OVERLAY/GOLDEN. - // index 1 refers to the first encoding frame in a gf group. - // Therefore if it is ARF_UPDATE, it means this gf group uses alt ref. - // See function define_gf_group_structure(). - const int use_alt_ref = gf_group->update_type[1] == ARF_UPDATE; - int ext_rdmult = VPX_DEFAULT_RDMULT; - get_ref_frame_bufs(cpi, ref_frame_bufs); - codec_status = vp9_extrc_get_frame_rdmult( - &cpi->ext_ratectrl, curr_frame_buf->frame_index, - cm->current_frame_coding_index, gf_group->index, update_type, - gf_group->gf_group_size, use_alt_ref, ref_frame_bufs, ref_frame_flags, - &ext_rdmult); - if (codec_status != VPX_CODEC_OK) { - vpx_internal_error(&cm->error, codec_status, - "vp9_extrc_get_frame_rdmult() failed"); - } - cpi->ext_ratectrl.ext_rdmult = ext_rdmult; - } - - if (cpi->sf.recode_loop == DISALLOW_RECODE) { - if (!encode_without_recode_loop(cpi, size, dest, dest_size)) return; - } else { -#if !CONFIG_REALTIME_ONLY -#if CONFIG_RATE_CTRL - encode_with_recode_loop(cpi, size, dest, dest_size, - &encode_frame_result->rq_history); -#else // CONFIG_RATE_CTRL -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, encode_with_recode_loop_time); -#endif - encode_with_recode_loop(cpi, size, dest, dest_size); -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, encode_with_recode_loop_time); -#endif -#endif // CONFIG_RATE_CTRL -#endif // !CONFIG_REALTIME_ONLY - } - - // TODO(jingning): When using show existing frame mode, we assume that the - // current ARF will be directly used as the final reconstructed frame. This is - // an encoder control scheme. One could in principle explore other - // possibilities to arrange the reference frame buffer and their coding order. - if (cm->show_existing_frame) { - ref_cnt_fb(cm->buffer_pool->frame_bufs, &cm->new_fb_idx, - cm->ref_frame_map[cpi->alt_fb_idx]); - } - -#if !CONFIG_REALTIME_ONLY - // Disable segmentation if it decrease rate/distortion ratio - if (cpi->oxcf.aq_mode == LOOKAHEAD_AQ) - vp9_try_disable_lookahead_aq(cpi, size, dest, dest_size); -#endif - -#if CONFIG_VP9_TEMPORAL_DENOISING -#ifdef OUTPUT_YUV_DENOISED - if (oxcf->noise_sensitivity > 0 && denoise_svc(cpi)) { - vpx_write_yuv_frame(yuv_denoised_file, - &cpi->denoiser.running_avg_y[INTRA_FRAME]); - } -#endif -#endif -#ifdef OUTPUT_YUV_SKINMAP - if (cpi->common.current_video_frame > 1) { - vp9_output_skin_map(cpi, yuv_skinmap_file); - } -#endif - - // Special case code to reduce pulsing when key frames are forced at a - // fixed interval. Note the reconstruction error if it is the frame before - // the force key frame - if (cpi->rc.next_key_frame_forced && cpi->rc.frames_to_key == 1) { -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - cpi->ambient_err = - vpx_highbd_get_y_sse(cpi->Source, get_frame_new_buffer(cm)); - } else { - cpi->ambient_err = vpx_get_y_sse(cpi->Source, get_frame_new_buffer(cm)); - } -#else - cpi->ambient_err = vpx_get_y_sse(cpi->Source, get_frame_new_buffer(cm)); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - - // If the encoder forced a KEY_FRAME decision - if (cm->frame_type == KEY_FRAME) cpi->refresh_last_frame = 1; - - cm->frame_to_show = get_frame_new_buffer(cm); - cm->frame_to_show->color_space = cm->color_space; - cm->frame_to_show->color_range = cm->color_range; - cm->frame_to_show->render_width = cm->render_width; - cm->frame_to_show->render_height = cm->render_height; - -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, loopfilter_frame_time); -#endif - // Pick the loop filter level for the frame. - loopfilter_frame(cpi, cm); -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, loopfilter_frame_time); -#endif - - if (cpi->rc.use_post_encode_drop) save_coding_context(cpi); - -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, vp9_pack_bitstream_time); -#endif - // build the bitstream - vp9_pack_bitstream(cpi, dest, dest_size, size); -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, vp9_pack_bitstream_time); -#endif - - if (cpi->ext_ratectrl.ready && - cpi->ext_ratectrl.funcs.update_encodeframe_result != NULL) { - vpx_codec_err_t codec_status = vp9_extrc_update_encodeframe_result( - &cpi->ext_ratectrl, (*size) << 3, cm->base_qindex); - if (codec_status != VPX_CODEC_OK) { - vpx_internal_error(&cm->error, codec_status, - "vp9_extrc_update_encodeframe_result() failed"); - } - } -#if CONFIG_REALTIME_ONLY - (void)encode_frame_result; - assert(encode_frame_result == NULL); -#else // CONFIG_REALTIME_ONLY - if (encode_frame_result != NULL) { - const RefCntBuffer *coded_frame_buf = - get_ref_cnt_buffer(cm, cm->new_fb_idx); - RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES]; - FRAME_UPDATE_TYPE update_type = - cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index]; - int quantize_index = vp9_get_quantizer(cpi); - get_ref_frame_bufs(cpi, ref_frame_bufs); - // update_encode_frame_result() depends on twopass.gf_group.index and - // cm->new_fb_idx, cpi->Source, cpi->lst_fb_idx, cpi->gld_fb_idx and - // cpi->alt_fb_idx are updated for current frame and have - // not been updated for the next frame yet. - // The update locations are as follows. - // 1) twopass.gf_group.index is initialized at define_gf_group by vp9_zero() - // for the first frame in the gf_group and is updated for the next frame at - // vp9_twopass_postencode_update(). - // 2) cpi->Source is updated at the beginning of vp9_get_compressed_data() - // 3) cm->new_fb_idx is updated at the beginning of - // vp9_get_compressed_data() by get_free_fb(cm). - // 4) cpi->lst_fb_idx/gld_fb_idx/alt_fb_idx will be updated for the next - // frame at vp9_update_reference_frames(). - // This function needs to be called before vp9_update_reference_frames(). - // TODO(angiebird): Improve the codebase to make the update of frame - // dependent variables more robust. - - update_encode_frame_result_basic(update_type, coded_frame_buf->frame_index, - quantize_index, encode_frame_result); - if (cpi->ext_ratectrl.ready && cpi->ext_ratectrl.log_file) { - PSNR_STATS psnr = - compute_psnr_stats(cpi->Source, &coded_frame_buf->buf, cm->bit_depth, - cpi->oxcf.input_bit_depth); - fprintf(cpi->ext_ratectrl.log_file, - "ENCODE_FRAME_RESULT gop_index %d psnr %f bits %zu\n", - cpi->twopass.gf_group.index, psnr.psnr[0], (*size) << 3); - } - -#if CONFIG_RATE_CTRL - if (cpi->oxcf.use_simple_encode_api) { - const int ref_frame_flags = get_ref_frame_flags(cpi); - update_encode_frame_result_simple_encode( - ref_frame_flags, - cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index], - cpi->Source, coded_frame_buf, ref_frame_bufs, quantize_index, - cm->bit_depth, cpi->oxcf.input_bit_depth, cpi->td.counts, - cpi->partition_info, cpi->motion_vector_info, cpi->tpl_stats_info, - encode_frame_result); - } -#endif // CONFIG_RATE_CTRL - } -#endif // CONFIG_REALTIME_ONLY - - if (cpi->rc.use_post_encode_drop && cm->base_qindex < cpi->rc.worst_quality && - cpi->svc.spatial_layer_id == 0 && post_encode_drop_cbr(cpi, size)) { - restore_coding_context(cpi); - return; - } - - cpi->last_frame_dropped = 0; - cpi->svc.last_layer_dropped[cpi->svc.spatial_layer_id] = 0; - if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) - cpi->svc.num_encoded_top_layer++; - - // Keep track of the frame buffer index updated/refreshed for the - // current encoded TL0 superframe. - if (cpi->svc.temporal_layer_id == 0) { - if (cpi->refresh_last_frame) - cpi->svc.fb_idx_upd_tl0[cpi->svc.spatial_layer_id] = cpi->lst_fb_idx; - else if (cpi->refresh_golden_frame) - cpi->svc.fb_idx_upd_tl0[cpi->svc.spatial_layer_id] = cpi->gld_fb_idx; - else if (cpi->refresh_alt_ref_frame) - cpi->svc.fb_idx_upd_tl0[cpi->svc.spatial_layer_id] = cpi->alt_fb_idx; - } - - if (cm->seg.update_map) update_reference_segmentation_map(cpi); - - if (frame_is_intra_only(cm) == 0) { - release_scaled_references(cpi); - } - vp9_update_reference_frames(cpi); - - if (!cm->show_existing_frame) { - for (t = TX_4X4; t <= TX_32X32; ++t) { - full_to_model_counts(cpi->td.counts->coef[t], - cpi->td.rd_counts.coef_counts[t]); - } - - if (!cm->error_resilient_mode && !cm->frame_parallel_decoding_mode) { - if (!frame_is_intra_only(cm)) { - vp9_adapt_mode_probs(cm); - vp9_adapt_mv_probs(cm, cm->allow_high_precision_mv); - } - vp9_adapt_coef_probs(cm); - } - } - - cpi->ext_refresh_frame_flags_pending = 0; - - if (cpi->refresh_golden_frame == 1) - cpi->frame_flags |= FRAMEFLAGS_GOLDEN; - else - cpi->frame_flags &= ~FRAMEFLAGS_GOLDEN; - - if (cpi->refresh_alt_ref_frame == 1) - cpi->frame_flags |= FRAMEFLAGS_ALTREF; - else - cpi->frame_flags &= ~FRAMEFLAGS_ALTREF; - - cpi->ref_frame_flags = get_ref_frame_flags(cpi); - - cm->last_frame_type = cm->frame_type; - - vp9_rc_postencode_update(cpi, *size); - - if (cpi->compute_frame_low_motion_onepass && oxcf->pass == 0 && - !frame_is_intra_only(cm) && - (!cpi->use_svc || - (cpi->use_svc && - !cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame && - cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1))) { - vp9_compute_frame_low_motion(cpi); - } - - *size = VPXMAX(1, *size); - -#if 0 - output_frame_level_debug_stats(cpi); -#endif - - if (cm->frame_type == KEY_FRAME) { - // Tell the caller that the frame was coded as a key frame - *frame_flags = cpi->frame_flags | FRAMEFLAGS_KEY; - } else { - *frame_flags = cpi->frame_flags & ~FRAMEFLAGS_KEY; - } - - // Clear the one shot update flags for segmentation map and mode/ref loop - // filter deltas. - cm->seg.update_map = 0; - cm->seg.update_data = 0; - cm->lf.mode_ref_delta_update = 0; - - // keep track of the last coded dimensions - cm->last_width = cm->width; - cm->last_height = cm->height; - - // reset to normal state now that we are done. - if (!cm->show_existing_frame) { - cm->last_show_frame = cm->show_frame; - cm->prev_frame = cm->cur_frame; - } - - if (cm->show_frame) { - vp9_swap_mi_and_prev_mi(cm); - if (cpi->use_svc) vp9_inc_frame_in_layer(cpi); - } - update_frame_indexes(cm, cm->show_frame); - - if (cpi->use_svc) { - cpi->svc - .layer_context[cpi->svc.spatial_layer_id * - cpi->svc.number_temporal_layers + - cpi->svc.temporal_layer_id] - .last_frame_type = cm->frame_type; - // Reset layer_sync back to 0 for next frame. - cpi->svc.spatial_layer_sync[cpi->svc.spatial_layer_id] = 0; - } - - cpi->force_update_segmentation = 0; - -#if !CONFIG_REALTIME_ONLY - if (cpi->oxcf.aq_mode == LOOKAHEAD_AQ) - vp9_alt_ref_aq_unset_all(cpi->alt_ref_aq, cpi); -#endif - - cpi->svc.previous_frame_is_intra_only = cm->intra_only; - cpi->svc.set_intra_only_frame = 0; -} - -static void SvcEncode(VP9_COMP *cpi, size_t *size, uint8_t *dest, - size_t dest_size, unsigned int *frame_flags) { - vp9_rc_get_svc_params(cpi); - encode_frame_to_data_rate(cpi, size, dest, dest_size, frame_flags, - /*encode_frame_result = */ NULL); -} - -static void Pass0Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, - size_t dest_size, unsigned int *frame_flags) { - if (cpi->oxcf.rc_mode == VPX_CBR) { - vp9_rc_get_one_pass_cbr_params(cpi); - } else { - vp9_rc_get_one_pass_vbr_params(cpi); - } - encode_frame_to_data_rate(cpi, size, dest, dest_size, frame_flags, - /*encode_frame_result = */ NULL); -} - -#if !CONFIG_REALTIME_ONLY -static void Pass2Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, - size_t dest_size, unsigned int *frame_flags, - ENCODE_FRAME_RESULT *encode_frame_result) { - cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED; -#if CONFIG_MISMATCH_DEBUG - mismatch_move_frame_idx_w(); -#endif - encode_frame_to_data_rate(cpi, size, dest, dest_size, frame_flags, - encode_frame_result); -} -#endif // !CONFIG_REALTIME_ONLY - -int vp9_receive_raw_frame(VP9_COMP *cpi, vpx_enc_frame_flags_t frame_flags, - YV12_BUFFER_CONFIG *sd, int64_t time_stamp, - int64_t end_time) { - VP9_COMMON *const cm = &cpi->common; - struct vpx_usec_timer timer; - int res = 0; - const int subsampling_x = sd->subsampling_x; - const int subsampling_y = sd->subsampling_y; -#if CONFIG_VP9_HIGHBITDEPTH - const int use_highbitdepth = (sd->flags & YV12_FLAG_HIGHBITDEPTH) != 0; -#else - const int use_highbitdepth = 0; -#endif - - update_initial_width(cpi, use_highbitdepth, subsampling_x, subsampling_y); -#if CONFIG_VP9_TEMPORAL_DENOISING - setup_denoiser_buffer(cpi); -#endif - - alloc_raw_frame_buffers(cpi); - - vpx_usec_timer_start(&timer); - - if (vp9_lookahead_push(cpi->lookahead, sd, time_stamp, end_time, - use_highbitdepth, frame_flags)) - res = -1; - vpx_usec_timer_mark(&timer); - cpi->time_receive_data += vpx_usec_timer_elapsed(&timer); - - if ((cm->profile == PROFILE_0 || cm->profile == PROFILE_2) && - (subsampling_x != 1 || subsampling_y != 1)) { - vpx_internal_error(&cm->error, VPX_CODEC_INVALID_PARAM, - "Non-4:2:0 color format requires profile 1 or 3"); - res = -1; - } - if ((cm->profile == PROFILE_1 || cm->profile == PROFILE_3) && - (subsampling_x == 1 && subsampling_y == 1)) { - vpx_internal_error(&cm->error, VPX_CODEC_INVALID_PARAM, - "4:2:0 color format requires profile 0 or 2"); - res = -1; - } - - return res; -} - -static int frame_is_reference(const VP9_COMP *cpi) { - const VP9_COMMON *cm = &cpi->common; - - return cm->frame_type == KEY_FRAME || cpi->refresh_last_frame || - cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame || - cm->refresh_frame_context || cm->lf.mode_ref_delta_update || - cm->seg.update_map || cm->seg.update_data; -} - -static void adjust_frame_rate(VP9_COMP *cpi, - const struct lookahead_entry *source) { - int64_t this_duration; - int step = 0; - - if (source->ts_start == cpi->first_time_stamp_ever) { - this_duration = source->ts_end - source->ts_start; - step = 1; - } else { - int64_t last_duration = - cpi->last_end_time_stamp_seen - cpi->last_time_stamp_seen; - - this_duration = source->ts_end - cpi->last_end_time_stamp_seen; - - // do a step update if the duration changes by 10% - if (last_duration) - step = (int)((this_duration - last_duration) * 10 / last_duration); - } - - if (this_duration) { - if (step) { - vp9_new_framerate(cpi, 10000000.0 / this_duration); - } else { - // Average this frame's rate into the last second's average - // frame rate. If we haven't seen 1 second yet, then average - // over the whole interval seen. - const double interval = VPXMIN( - (double)(source->ts_end - cpi->first_time_stamp_ever), 10000000.0); - double avg_duration = 10000000.0 / cpi->framerate; - avg_duration *= (interval - avg_duration + this_duration); - avg_duration /= interval; - - vp9_new_framerate(cpi, 10000000.0 / avg_duration); - } - } - cpi->last_time_stamp_seen = source->ts_start; - cpi->last_end_time_stamp_seen = source->ts_end; -} - -// Returns 0 if this is not an alt ref else the offset of the source frame -// used as the arf midpoint. -static int get_arf_src_index(VP9_COMP *cpi) { - RATE_CONTROL *const rc = &cpi->rc; - int arf_src_index = 0; - if (is_altref_enabled(cpi)) { - if (cpi->oxcf.pass == 2) { - const GF_GROUP *const gf_group = &cpi->twopass.gf_group; - if (gf_group->update_type[gf_group->index] == ARF_UPDATE) { - arf_src_index = gf_group->arf_src_offset[gf_group->index]; - } - } else if (rc->source_alt_ref_pending) { - arf_src_index = rc->frames_till_gf_update_due; - } - } - return arf_src_index; -} - -static void check_src_altref(VP9_COMP *cpi, - const struct lookahead_entry *source) { - RATE_CONTROL *const rc = &cpi->rc; - - if (cpi->oxcf.pass == 2) { - const GF_GROUP *const gf_group = &cpi->twopass.gf_group; - rc->is_src_frame_alt_ref = - (gf_group->update_type[gf_group->index] == OVERLAY_UPDATE); - } else { - rc->is_src_frame_alt_ref = - cpi->alt_ref_source && (source == cpi->alt_ref_source); - } - - if (rc->is_src_frame_alt_ref) { - // Current frame is an ARF overlay frame. - cpi->alt_ref_source = NULL; - - // Don't refresh the last buffer for an ARF overlay frame. It will - // become the GF so preserve last as an alternative prediction option. - cpi->refresh_last_frame = 0; - } -} - -#if CONFIG_INTERNAL_STATS -static void adjust_image_stat(double y, double u, double v, double all, - ImageStat *s) { - s->stat[Y] += y; - s->stat[U] += u; - s->stat[V] += v; - s->stat[ALL] += all; - s->worst = VPXMIN(s->worst, all); -} -#endif // CONFIG_INTERNAL_STATS - -// Adjust the maximum allowable frame size for the target level. -static void level_rc_framerate(VP9_COMP *cpi, int arf_src_index) { - RATE_CONTROL *const rc = &cpi->rc; - LevelConstraint *const ls = &cpi->level_constraint; - VP9_COMMON *const cm = &cpi->common; - const double max_cpb_size = ls->max_cpb_size; - vpx_clear_system_state(); - rc->max_frame_bandwidth = VPXMIN(rc->max_frame_bandwidth, ls->max_frame_size); - if (frame_is_intra_only(cm)) { - rc->max_frame_bandwidth = - VPXMIN(rc->max_frame_bandwidth, (int)(max_cpb_size * 0.5)); - } else if (arf_src_index > 0) { - rc->max_frame_bandwidth = - VPXMIN(rc->max_frame_bandwidth, (int)(max_cpb_size * 0.4)); - } else { - rc->max_frame_bandwidth = - VPXMIN(rc->max_frame_bandwidth, (int)(max_cpb_size * 0.2)); - } -} - -static void update_level_info(VP9_COMP *cpi, size_t *size, int arf_src_index) { - VP9_COMMON *const cm = &cpi->common; - Vp9LevelInfo *const level_info = &cpi->level_info; - Vp9LevelSpec *const level_spec = &level_info->level_spec; - Vp9LevelStats *const level_stats = &level_info->level_stats; - int i, idx; - uint64_t luma_samples, dur_end; - const uint32_t luma_pic_size = cm->width * cm->height; - const uint32_t luma_pic_breadth = VPXMAX(cm->width, cm->height); - LevelConstraint *const level_constraint = &cpi->level_constraint; - const int8_t level_index = level_constraint->level_index; - double cpb_data_size; - - vpx_clear_system_state(); - - // update level_stats - level_stats->total_compressed_size += *size; - if (cm->show_frame) { - level_stats->total_uncompressed_size += - luma_pic_size + - 2 * (luma_pic_size >> (cm->subsampling_x + cm->subsampling_y)); - level_stats->time_encoded = - (cpi->last_end_time_stamp_seen - cpi->first_time_stamp_ever) / - (double)TICKS_PER_SEC; - } - - if (arf_src_index > 0) { - if (!level_stats->seen_first_altref) { - level_stats->seen_first_altref = 1; - } else if (level_stats->frames_since_last_altref < - level_spec->min_altref_distance) { - level_spec->min_altref_distance = level_stats->frames_since_last_altref; - } - level_stats->frames_since_last_altref = 0; - } else { - ++level_stats->frames_since_last_altref; - } - - if (level_stats->frame_window_buffer.len < FRAME_WINDOW_SIZE - 1) { - idx = (level_stats->frame_window_buffer.start + - level_stats->frame_window_buffer.len++) % - FRAME_WINDOW_SIZE; - } else { - idx = level_stats->frame_window_buffer.start; - level_stats->frame_window_buffer.start = (idx + 1) % FRAME_WINDOW_SIZE; - } - level_stats->frame_window_buffer.buf[idx].ts = cpi->last_time_stamp_seen; - level_stats->frame_window_buffer.buf[idx].size = (uint32_t)(*size); - level_stats->frame_window_buffer.buf[idx].luma_samples = luma_pic_size; - - if (cm->frame_type == KEY_FRAME) { - level_stats->ref_refresh_map = 0; - } else { - int count = 0; - level_stats->ref_refresh_map |= vp9_get_refresh_mask(cpi); - // Also need to consider the case where the encoder refers to a buffer - // that has been implicitly refreshed after encoding a keyframe. - if (!cm->intra_only) { - level_stats->ref_refresh_map |= (1 << cpi->lst_fb_idx); - level_stats->ref_refresh_map |= (1 << cpi->gld_fb_idx); - level_stats->ref_refresh_map |= (1 << cpi->alt_fb_idx); - } - for (i = 0; i < REF_FRAMES; ++i) { - count += (level_stats->ref_refresh_map >> i) & 1; - } - if (count > level_spec->max_ref_frame_buffers) { - level_spec->max_ref_frame_buffers = count; - } - } - - // update average_bitrate - level_spec->average_bitrate = (double)level_stats->total_compressed_size / - 125.0 / level_stats->time_encoded; - - // update max_luma_sample_rate - luma_samples = 0; - for (i = 0; i < level_stats->frame_window_buffer.len; ++i) { - idx = (level_stats->frame_window_buffer.start + - level_stats->frame_window_buffer.len - 1 - i) % - FRAME_WINDOW_SIZE; - if (i == 0) { - dur_end = level_stats->frame_window_buffer.buf[idx].ts; - } - if (dur_end - level_stats->frame_window_buffer.buf[idx].ts >= - TICKS_PER_SEC) { - break; - } - luma_samples += level_stats->frame_window_buffer.buf[idx].luma_samples; - } - if (luma_samples > level_spec->max_luma_sample_rate) { - level_spec->max_luma_sample_rate = luma_samples; - } - - // update max_cpb_size - cpb_data_size = 0; - for (i = 0; i < CPB_WINDOW_SIZE; ++i) { - if (i >= level_stats->frame_window_buffer.len) break; - idx = (level_stats->frame_window_buffer.start + - level_stats->frame_window_buffer.len - 1 - i) % - FRAME_WINDOW_SIZE; - cpb_data_size += level_stats->frame_window_buffer.buf[idx].size; - } - cpb_data_size = cpb_data_size / 125.0; - if (cpb_data_size > level_spec->max_cpb_size) { - level_spec->max_cpb_size = cpb_data_size; - } - - // update max_luma_picture_size - if (luma_pic_size > level_spec->max_luma_picture_size) { - level_spec->max_luma_picture_size = luma_pic_size; - } - - // update max_luma_picture_breadth - if (luma_pic_breadth > level_spec->max_luma_picture_breadth) { - level_spec->max_luma_picture_breadth = luma_pic_breadth; - } - - // update compression_ratio - level_spec->compression_ratio = (double)level_stats->total_uncompressed_size * - cm->bit_depth / - level_stats->total_compressed_size / 8.0; - - // update max_col_tiles - if (level_spec->max_col_tiles < (1 << cm->log2_tile_cols)) { - level_spec->max_col_tiles = (1 << cm->log2_tile_cols); - } - - if (level_index >= 0 && level_constraint->fail_flag == 0) { - if (level_spec->max_luma_picture_size > - vp9_level_defs[level_index].max_luma_picture_size) { - level_constraint->fail_flag |= (1 << LUMA_PIC_SIZE_TOO_LARGE); - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "Failed to encode to the target level %d. %s", - vp9_level_defs[level_index].level, - level_fail_messages[LUMA_PIC_SIZE_TOO_LARGE]); - } - - if (level_spec->max_luma_picture_breadth > - vp9_level_defs[level_index].max_luma_picture_breadth) { - level_constraint->fail_flag |= (1 << LUMA_PIC_BREADTH_TOO_LARGE); - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "Failed to encode to the target level %d. %s", - vp9_level_defs[level_index].level, - level_fail_messages[LUMA_PIC_BREADTH_TOO_LARGE]); - } - - if ((double)level_spec->max_luma_sample_rate > - (double)vp9_level_defs[level_index].max_luma_sample_rate * - (1 + SAMPLE_RATE_GRACE_P)) { - level_constraint->fail_flag |= (1 << LUMA_SAMPLE_RATE_TOO_LARGE); - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "Failed to encode to the target level %d. %s", - vp9_level_defs[level_index].level, - level_fail_messages[LUMA_SAMPLE_RATE_TOO_LARGE]); - } - - if (level_spec->max_col_tiles > vp9_level_defs[level_index].max_col_tiles) { - level_constraint->fail_flag |= (1 << TOO_MANY_COLUMN_TILE); - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "Failed to encode to the target level %d. %s", - vp9_level_defs[level_index].level, - level_fail_messages[TOO_MANY_COLUMN_TILE]); - } - - if (level_spec->min_altref_distance < - vp9_level_defs[level_index].min_altref_distance) { - level_constraint->fail_flag |= (1 << ALTREF_DIST_TOO_SMALL); - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "Failed to encode to the target level %d. %s", - vp9_level_defs[level_index].level, - level_fail_messages[ALTREF_DIST_TOO_SMALL]); - } - - if (level_spec->max_ref_frame_buffers > - vp9_level_defs[level_index].max_ref_frame_buffers) { - level_constraint->fail_flag |= (1 << TOO_MANY_REF_BUFFER); - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "Failed to encode to the target level %d. %s", - vp9_level_defs[level_index].level, - level_fail_messages[TOO_MANY_REF_BUFFER]); - } - - if (level_spec->max_cpb_size > vp9_level_defs[level_index].max_cpb_size) { - level_constraint->fail_flag |= (1 << CPB_TOO_LARGE); - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "Failed to encode to the target level %d. %s", - vp9_level_defs[level_index].level, - level_fail_messages[CPB_TOO_LARGE]); - } - - // Set an upper bound for the next frame size. It will be used in - // level_rc_framerate() before encoding the next frame. - cpb_data_size = 0; - for (i = 0; i < CPB_WINDOW_SIZE - 1; ++i) { - if (i >= level_stats->frame_window_buffer.len) break; - idx = (level_stats->frame_window_buffer.start + - level_stats->frame_window_buffer.len - 1 - i) % - FRAME_WINDOW_SIZE; - cpb_data_size += level_stats->frame_window_buffer.buf[idx].size; - } - cpb_data_size = cpb_data_size / 125.0; - level_constraint->max_frame_size = - (int)((vp9_level_defs[level_index].max_cpb_size - cpb_data_size) * - 1000.0); - if (level_stats->frame_window_buffer.len < CPB_WINDOW_SIZE - 1) - level_constraint->max_frame_size >>= 1; - } -} - -void vp9_get_ref_frame_info(FRAME_UPDATE_TYPE update_type, int ref_frame_flags, - RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], - int *ref_frame_coding_indexes, - int *ref_frame_valid_list) { - if (update_type != KF_UPDATE) { - const VP9_REFFRAME inter_ref_flags[MAX_INTER_REF_FRAMES] = { VP9_LAST_FLAG, - VP9_GOLD_FLAG, - VP9_ALT_FLAG }; - int i; - for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) { - assert(ref_frame_bufs[i] != NULL); - ref_frame_coding_indexes[i] = ref_frame_bufs[i]->frame_coding_index; - ref_frame_valid_list[i] = (ref_frame_flags & inter_ref_flags[i]) != 0; - } - } else { - // No reference frame is available when this is a key frame. - int i; - for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) { - ref_frame_coding_indexes[i] = -1; - ref_frame_valid_list[i] = 0; - } - } -} - -void vp9_init_encode_frame_result(ENCODE_FRAME_RESULT *encode_frame_result) { - encode_frame_result->show_idx = -1; // Actual encoding doesn't happen. -#if CONFIG_RATE_CTRL - encode_frame_result->frame_coding_index = -1; - vp9_zero(encode_frame_result->coded_frame); - encode_frame_result->coded_frame.allocated = 0; - init_rq_history(&encode_frame_result->rq_history); -#endif // CONFIG_RATE_CTRL -} - -// Returns if TPL stats need to be calculated. -static INLINE int should_run_tpl(VP9_COMP *cpi, int gf_group_index) { - RATE_CONTROL *const rc = &cpi->rc; - if (!cpi->sf.enable_tpl_model) return 0; - // If there is an ARF for this GOP, TPL stats is always calculated. - if (gf_group_index == 1 && - cpi->twopass.gf_group.update_type[gf_group_index] == ARF_UPDATE) - return 1; - // If this GOP doesn't have an ARF, TPL stats is still calculated, only when - // external rate control is used. - if (cpi->ext_ratectrl.ready && - cpi->ext_ratectrl.funcs.send_tpl_gop_stats != NULL && - rc->frames_till_gf_update_due == rc->baseline_gf_interval && - cpi->twopass.gf_group.update_type[1] != ARF_UPDATE) { - return 1; - } - return 0; -} - -int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, - size_t *size, uint8_t *dest, size_t dest_size, - int64_t *time_stamp, int64_t *time_end, int flush, - ENCODE_FRAME_RESULT *encode_frame_result) { - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - VP9_COMMON *const cm = &cpi->common; - BufferPool *const pool = cm->buffer_pool; - RATE_CONTROL *const rc = &cpi->rc; - struct vpx_usec_timer cmptimer; - YV12_BUFFER_CONFIG *force_src_buffer = NULL; - struct lookahead_entry *last_source = NULL; - struct lookahead_entry *source = NULL; - int arf_src_index; - const int gf_group_index = cpi->twopass.gf_group.index; - int i; - -#if CONFIG_COLLECT_COMPONENT_TIMING - if (oxcf->pass == 2) start_timing(cpi, vp9_get_compressed_data_time); -#endif - - if (is_one_pass_svc(cpi)) { - vp9_one_pass_svc_start_layer(cpi); - } - - vpx_usec_timer_start(&cmptimer); - - vp9_set_high_precision_mv(cpi, ALTREF_HIGH_PRECISION_MV); - - // Is multi-arf enabled. - // Note that at the moment multi_arf is only configured for 2 pass VBR and - // will not work properly with svc. - // Enable the Jingning's new "multi_layer_arf" code if "enable_auto_arf" - // is greater than or equal to 2. - if ((oxcf->pass == 2) && !cpi->use_svc && (cpi->oxcf.enable_auto_arf >= 2)) - cpi->multi_layer_arf = 1; - else - cpi->multi_layer_arf = 0; - - // Normal defaults - cm->reset_frame_context = 0; - cm->refresh_frame_context = 1; - if (!is_one_pass_svc(cpi)) { - cpi->refresh_last_frame = 1; - cpi->refresh_golden_frame = 0; - cpi->refresh_alt_ref_frame = 0; - } - - // Should we encode an arf frame. - arf_src_index = get_arf_src_index(cpi); - - if (arf_src_index) { - for (i = 0; i <= arf_src_index; ++i) { - struct lookahead_entry *e = vp9_lookahead_peek(cpi->lookahead, i); - // Avoid creating an alt-ref if there's a forced keyframe pending. - if (e == NULL) { - break; - } else if (e->flags == VPX_EFLAG_FORCE_KF) { - arf_src_index = 0; - flush = 1; - break; - } - } - } - - // Clear arf index stack before group of pictures processing starts. - if (gf_group_index == 1) { - stack_init(cpi->twopass.gf_group.arf_index_stack, MAX_LAG_BUFFERS * 2); - cpi->twopass.gf_group.stack_size = 0; - } - - if (arf_src_index) { - if (!(cpi->ext_ratectrl.ready && - (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_GOP) != 0 && - cpi->ext_ratectrl.funcs.get_gop_decision != NULL)) { - // This assert only makes sense when not using external RC. - assert(arf_src_index <= rc->frames_to_key); - } - if ((source = vp9_lookahead_peek(cpi->lookahead, arf_src_index)) != NULL) { - cpi->alt_ref_source = source; - -#if !CONFIG_REALTIME_ONLY - if ((oxcf->mode != REALTIME) && (oxcf->arnr_max_frames > 0) && - (oxcf->arnr_strength > 0)) { - int bitrate = cpi->rc.avg_frame_bandwidth / 40; - int not_low_bitrate = bitrate > ALT_REF_AQ_LOW_BITRATE_BOUNDARY; - - int not_last_frame = (cpi->lookahead->sz - arf_src_index > 1); - not_last_frame |= ALT_REF_AQ_APPLY_TO_LAST_FRAME; - -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, vp9_temporal_filter_time); -#endif - // Produce the filtered ARF frame. - vp9_temporal_filter(cpi, arf_src_index); - vpx_extend_frame_borders(&cpi->tf_buffer); -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, vp9_temporal_filter_time); -#endif - - // for small bitrates segmentation overhead usually - // eats all bitrate gain from enabling delta quantizers - if (cpi->oxcf.alt_ref_aq != 0 && not_low_bitrate && not_last_frame) - vp9_alt_ref_aq_setup_mode(cpi->alt_ref_aq, cpi); - - force_src_buffer = &cpi->tf_buffer; - } -#endif - cm->show_frame = 0; - cm->intra_only = 0; - cpi->refresh_alt_ref_frame = 1; - cpi->refresh_golden_frame = 0; - cpi->refresh_last_frame = 0; - rc->is_src_frame_alt_ref = 0; - rc->source_alt_ref_pending = 0; - } else { - rc->source_alt_ref_pending = 0; - } - } - - if (!source) { - // Get last frame source. - if (cm->current_video_frame > 0) { - if ((last_source = vp9_lookahead_peek(cpi->lookahead, -1)) == NULL) - return -1; - } - - // Read in the source frame. - if (cpi->use_svc || cpi->svc.set_intra_only_frame) - source = vp9_svc_lookahead_pop(cpi, cpi->lookahead, flush); - else - source = vp9_lookahead_pop(cpi->lookahead, flush); - - if (source != NULL) { - cm->show_frame = 1; - cm->intra_only = 0; - // If the flags indicate intra frame, but if the current picture is for - // spatial layer above first_spatial_layer_to_encode, it should not be an - // intra picture. - if ((source->flags & VPX_EFLAG_FORCE_KF) && cpi->use_svc && - cpi->svc.spatial_layer_id > cpi->svc.first_spatial_layer_to_encode) { - source->flags &= ~(unsigned int)(VPX_EFLAG_FORCE_KF); - } - - // Check to see if the frame should be encoded as an arf overlay. - check_src_altref(cpi, source); - } - } - - if (source) { - cpi->un_scaled_source = cpi->Source = - force_src_buffer ? force_src_buffer : &source->img; - -#ifdef ENABLE_KF_DENOISE - // Copy of raw source for metrics calculation. - if (is_psnr_calc_enabled(cpi)) - vp9_copy_and_extend_frame(cpi->Source, &cpi->raw_unscaled_source); -#endif - - cpi->unscaled_last_source = last_source != NULL ? &last_source->img : NULL; - - *time_stamp = source->ts_start; - *time_end = source->ts_end; - *frame_flags = (source->flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0; - } else { - *size = 0; - return -1; - } - - if (source->ts_start < cpi->first_time_stamp_ever) { - cpi->first_time_stamp_ever = source->ts_start; - cpi->last_end_time_stamp_seen = source->ts_start; - } - - // Clear down mmx registers - vpx_clear_system_state(); - - // adjust frame rates based on timestamps given - if (cm->show_frame) { - if (cpi->use_svc && cpi->svc.use_set_ref_frame_config && - cpi->svc.duration[cpi->svc.spatial_layer_id] > 0) - vp9_svc_adjust_frame_rate(cpi); - else - adjust_frame_rate(cpi, source); - } - - if (is_one_pass_svc(cpi)) { - vp9_update_temporal_layer_framerate(cpi); - vp9_restore_layer_context(cpi); - } - - // Find a free buffer for the new frame, releasing the reference previously - // held. - if (cm->new_fb_idx != INVALID_IDX) { - --pool->frame_bufs[cm->new_fb_idx].ref_count; - } - cm->new_fb_idx = get_free_fb(cm); - - if (cm->new_fb_idx == INVALID_IDX) return -1; - cm->cur_frame = &pool->frame_bufs[cm->new_fb_idx]; - // If the frame buffer for current frame is the same as previous frame, MV in - // the base layer shouldn't be used as it'll cause data race. - if (cpi->svc.spatial_layer_id > 0 && cm->cur_frame == cm->prev_frame) { - cpi->svc.use_base_mv = 0; - } - // Start with a 0 size frame. - *size = 0; - - cpi->frame_flags = *frame_flags; - -#if !CONFIG_REALTIME_ONLY - if ((oxcf->pass == 2) && !cpi->use_svc) { -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, vp9_rc_get_second_pass_params_time); -#endif - vp9_rc_get_second_pass_params(cpi); -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, vp9_rc_get_second_pass_params_time); -#endif - } else if (oxcf->pass == 1) { - set_frame_size(cpi); - } - - // Key frame temporal filtering - const int is_key_temporal_filter_enabled = - oxcf->enable_keyframe_filtering && cpi->oxcf.mode != REALTIME && - (oxcf->pass != 1) && !cpi->use_svc && - !is_lossless_requested(&cpi->oxcf) && cm->frame_type == KEY_FRAME && - (oxcf->arnr_max_frames > 0) && (oxcf->arnr_strength > 0) && - cpi->oxcf.speed < 2; - // Save the pointer to the original source image. - YV12_BUFFER_CONFIG *source_buffer = cpi->un_scaled_source; - - if (is_key_temporal_filter_enabled && source != NULL) { - // Produce the filtered Key frame. Set distance to -1 since the key frame - // is already popped out. - vp9_temporal_filter(cpi, -1); - vpx_extend_frame_borders(&cpi->tf_buffer); - force_src_buffer = &cpi->tf_buffer; - cpi->un_scaled_source = cpi->Source = - force_src_buffer ? force_src_buffer : &source->img; - } -#endif // !CONFIG_REALTIME_ONLY - - if (oxcf->pass != 1 && cpi->level_constraint.level_index >= 0 && - cpi->level_constraint.fail_flag == 0) - level_rc_framerate(cpi, arf_src_index); - - if (cpi->oxcf.pass != 0 || cpi->use_svc || frame_is_intra_only(cm) == 1) { - for (i = 0; i < REFS_PER_FRAME; ++i) cpi->scaled_ref_idx[i] = INVALID_IDX; - } - - if (cpi->kmeans_data_arr_alloc == 0) { - const int mi_cols = mi_cols_aligned_to_sb(cm->mi_cols); - const int mi_rows = mi_cols_aligned_to_sb(cm->mi_rows); -#if CONFIG_MULTITHREAD - pthread_mutex_init(&cpi->kmeans_mutex, NULL); -#endif - CHECK_MEM_ERROR( - &cm->error, cpi->kmeans_data_arr, - vpx_calloc(mi_rows * mi_cols, sizeof(*cpi->kmeans_data_arr))); - cpi->kmeans_data_stride = mi_cols; - cpi->kmeans_data_arr_alloc = 1; - } - -#if CONFIG_NON_GREEDY_MV - { - const int mi_cols = mi_cols_aligned_to_sb(cm->mi_cols); - const int mi_rows = mi_cols_aligned_to_sb(cm->mi_rows); - Status status = vp9_alloc_motion_field_info( - &cpi->motion_field_info, MAX_ARF_GOP_SIZE, mi_rows, mi_cols); - if (status == STATUS_FAILED) { - vpx_internal_error(&(cm)->error, VPX_CODEC_MEM_ERROR, - "vp9_alloc_motion_field_info failed"); - } - } -#endif // CONFIG_NON_GREEDY_MV - -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, setup_tpl_stats_time); -#endif - if (should_run_tpl(cpi, cpi->twopass.gf_group.index)) { - vp9_init_tpl_buffer(cpi); - vp9_estimate_tpl_qp_gop(cpi); - vp9_setup_tpl_stats(cpi); - } -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, setup_tpl_stats_time); -#endif - -#if CONFIG_BITSTREAM_DEBUG - assert(cpi->oxcf.max_threads == 0 && - "bitstream debug tool does not support multithreading"); - bitstream_queue_record_write(); -#endif -#if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG - bitstream_queue_set_frame_write(cm->current_video_frame * 2 + cm->show_frame); -#endif - - cpi->td.mb.fp_src_pred = 0; -#if CONFIG_REALTIME_ONLY - (void)encode_frame_result; - if (cpi->use_svc) { - SvcEncode(cpi, size, dest, dest_size, frame_flags); - } else { - // One pass encode - Pass0Encode(cpi, size, dest, dest_size, frame_flags); - } -#else // !CONFIG_REALTIME_ONLY - if (oxcf->pass == 1 && !cpi->use_svc) { - const int lossless = is_lossless_requested(oxcf); -#if CONFIG_VP9_HIGHBITDEPTH - if (cpi->oxcf.use_highbitdepth) - cpi->td.mb.fwd_txfm4x4 = - lossless ? vp9_highbd_fwht4x4 : vpx_highbd_fdct4x4; - else - cpi->td.mb.fwd_txfm4x4 = lossless ? vp9_fwht4x4 : vpx_fdct4x4; - cpi->td.mb.highbd_inv_txfm_add = - lossless ? vp9_highbd_iwht4x4_add : vp9_highbd_idct4x4_add; -#else - cpi->td.mb.fwd_txfm4x4 = lossless ? vp9_fwht4x4 : vpx_fdct4x4; -#endif // CONFIG_VP9_HIGHBITDEPTH - cpi->td.mb.inv_txfm_add = lossless ? vp9_iwht4x4_add : vp9_idct4x4_add; - vp9_first_pass(cpi, source); - } else if (oxcf->pass == 2 && !cpi->use_svc) { -#if CONFIG_COLLECT_COMPONENT_TIMING - // Accumulate 2nd pass time in 2-pass case. - start_timing(cpi, Pass2Encode_time); -#endif - Pass2Encode(cpi, size, dest, dest_size, frame_flags, encode_frame_result); - vp9_twopass_postencode_update(cpi); -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, Pass2Encode_time); -#endif - } else if (cpi->use_svc) { - SvcEncode(cpi, size, dest, dest_size, frame_flags); - } else { - // One pass encode - Pass0Encode(cpi, size, dest, dest_size, frame_flags); - } -#endif // CONFIG_REALTIME_ONLY - - if (cm->show_frame) cm->cur_show_frame_fb_idx = cm->new_fb_idx; - - if (cm->refresh_frame_context) - cm->frame_contexts[cm->frame_context_idx] = *cm->fc; - - // No frame encoded, or frame was dropped, release scaled references. - if ((*size == 0) && (frame_is_intra_only(cm) == 0)) { - release_scaled_references(cpi); - } - - if (*size > 0) { - cpi->droppable = !frame_is_reference(cpi); - } - - // Save layer specific state. - if (is_one_pass_svc(cpi) || ((cpi->svc.number_temporal_layers > 1 || - cpi->svc.number_spatial_layers > 1) && - oxcf->pass == 2)) { - vp9_save_layer_context(cpi); - } - - if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) - cpi->fixed_qp_onepass = 0; - - vpx_usec_timer_mark(&cmptimer); - cpi->time_compress_data += vpx_usec_timer_elapsed(&cmptimer); - - if (cpi->keep_level_stats && oxcf->pass != 1) - update_level_info(cpi, size, arf_src_index); - -#if !CONFIG_REALTIME_ONLY - if (is_key_temporal_filter_enabled && cpi->b_calculate_psnr) { - cpi->raw_source_frame = vp9_scale_if_required( - cm, source_buffer, &cpi->scaled_source, (oxcf->pass == 0), EIGHTTAP, 0); - } -#endif // !CONFIG_REALTIME_ONLY - -#if CONFIG_INTERNAL_STATS - - if (oxcf->pass != 1 && !cpi->last_frame_dropped) { - double samples = 0.0; - cpi->bytes += *size; - - if (cm->show_frame) { - uint32_t bit_depth = 8; - uint32_t in_bit_depth = 8; - cpi->count++; -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - in_bit_depth = cpi->oxcf.input_bit_depth; - bit_depth = cm->bit_depth; - } -#endif - - if (cpi->b_calculate_psnr) { - YV12_BUFFER_CONFIG *orig = cpi->raw_source_frame; - YV12_BUFFER_CONFIG *recon = cpi->common.frame_to_show; - YV12_BUFFER_CONFIG *pp = &cm->post_proc_buffer; - PSNR_STATS psnr; -#if CONFIG_VP9_HIGHBITDEPTH - vpx_calc_highbd_psnr(orig, recon, &psnr, cpi->td.mb.e_mbd.bd, - in_bit_depth); -#else - vpx_calc_psnr(orig, recon, &psnr); -#endif // CONFIG_VP9_HIGHBITDEPTH - - adjust_image_stat(psnr.psnr[1], psnr.psnr[2], psnr.psnr[3], - psnr.psnr[0], &cpi->psnr); - cpi->total_sq_error += psnr.sse[0]; - cpi->total_samples += psnr.samples[0]; - samples = psnr.samples[0]; - - { - PSNR_STATS psnr2; - double frame_ssim2 = 0, weight = 0; -#if CONFIG_VP9_POSTPROC - if (vpx_alloc_frame_buffer( - pp, recon->y_crop_width, recon->y_crop_height, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment) < 0) { - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate post processing buffer"); - } - { - vp9_ppflags_t ppflags; - ppflags.post_proc_flag = VP9D_DEBLOCK; - ppflags.deblocking_level = 0; // not used in vp9_post_proc_frame() - ppflags.noise_level = 0; // not used in vp9_post_proc_frame() - vp9_post_proc_frame(cm, pp, &ppflags, - cpi->un_scaled_source->y_width); - } -#endif - vpx_clear_system_state(); - -#if CONFIG_VP9_HIGHBITDEPTH - vpx_calc_highbd_psnr(orig, pp, &psnr2, cpi->td.mb.e_mbd.bd, - cpi->oxcf.input_bit_depth); -#else - vpx_calc_psnr(orig, pp, &psnr2); -#endif // CONFIG_VP9_HIGHBITDEPTH - - cpi->totalp_sq_error += psnr2.sse[0]; - cpi->totalp_samples += psnr2.samples[0]; - adjust_image_stat(psnr2.psnr[1], psnr2.psnr[2], psnr2.psnr[3], - psnr2.psnr[0], &cpi->psnrp); - -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - frame_ssim2 = vpx_highbd_calc_ssim(orig, recon, &weight, bit_depth, - in_bit_depth); - } else { - frame_ssim2 = vpx_calc_ssim(orig, recon, &weight); - } -#else - frame_ssim2 = vpx_calc_ssim(orig, recon, &weight); -#endif // CONFIG_VP9_HIGHBITDEPTH - - cpi->worst_ssim = VPXMIN(cpi->worst_ssim, frame_ssim2); - cpi->summed_quality += frame_ssim2 * weight; - cpi->summed_weights += weight; - -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - frame_ssim2 = vpx_highbd_calc_ssim(orig, pp, &weight, bit_depth, - in_bit_depth); - } else { - frame_ssim2 = vpx_calc_ssim(orig, pp, &weight); - } -#else - frame_ssim2 = vpx_calc_ssim(orig, pp, &weight); -#endif // CONFIG_VP9_HIGHBITDEPTH - - cpi->summedp_quality += frame_ssim2 * weight; - cpi->summedp_weights += weight; -#if 0 - if (cm->show_frame) { - FILE *f = fopen("q_used.stt", "a"); - fprintf(f, "%5d : Y%f7.3:U%f7.3:V%f7.3:F%f7.3:S%7.3f\n", - cpi->common.current_video_frame, psnr2.psnr[1], - psnr2.psnr[2], psnr2.psnr[3], psnr2.psnr[0], frame_ssim2); - fclose(f); - } -#endif - } - } - if (cpi->b_calculate_blockiness) { -#if CONFIG_VP9_HIGHBITDEPTH - if (!cm->use_highbitdepth) -#endif - { - double frame_blockiness = vp9_get_blockiness( - cpi->Source->y_buffer, cpi->Source->y_stride, - cm->frame_to_show->y_buffer, cm->frame_to_show->y_stride, - cpi->Source->y_width, cpi->Source->y_height); - cpi->worst_blockiness = - VPXMAX(cpi->worst_blockiness, frame_blockiness); - cpi->total_blockiness += frame_blockiness; - } - } - - if (cpi->b_calculate_consistency) { -#if CONFIG_VP9_HIGHBITDEPTH - if (!cm->use_highbitdepth) -#endif - { - double this_inconsistency = vpx_get_ssim_metrics( - cpi->Source->y_buffer, cpi->Source->y_stride, - cm->frame_to_show->y_buffer, cm->frame_to_show->y_stride, - cpi->Source->y_width, cpi->Source->y_height, cpi->ssim_vars, - &cpi->metrics, 1); - - const double peak = (double)((1 << cpi->oxcf.input_bit_depth) - 1); - double consistency = - vpx_sse_to_psnr(samples, peak, (double)cpi->total_inconsistency); - if (consistency > 0.0) - cpi->worst_consistency = - VPXMIN(cpi->worst_consistency, consistency); - cpi->total_inconsistency += this_inconsistency; - } - } - - { - double y, u, v, frame_all; - frame_all = vpx_calc_fastssim(cpi->Source, cm->frame_to_show, &y, &u, - &v, bit_depth, in_bit_depth); - adjust_image_stat(y, u, v, frame_all, &cpi->fastssim); - } - { - double y, u, v, frame_all; - frame_all = vpx_psnrhvs(cpi->Source, cm->frame_to_show, &y, &u, &v, - bit_depth, in_bit_depth); - adjust_image_stat(y, u, v, frame_all, &cpi->psnrhvs); - } - } - } - -#endif - -#if CONFIG_COLLECT_COMPONENT_TIMING - if (oxcf->pass == 2) end_timing(cpi, vp9_get_compressed_data_time); - - // Print out timing information. - // Note: Use "cpi->frame_component_time[0] > 100 us" to avoid showing of - // show_existing_frame and lag-in-frames. - // if (cpi->frame_component_time[0] > 100) - if (oxcf->pass == 2) { - uint64_t frame_total = 0, total = 0; - int i; - - fprintf(stderr, - "\n Frame number: %d, Frame type: %s, Show Frame: %d, Q: %d\n", - cm->current_video_frame, get_frame_type_enum(cm->frame_type), - cm->show_frame, cm->base_qindex); - for (i = 0; i < kTimingComponents; i++) { - cpi->component_time[i] += cpi->frame_component_time[i]; - // Use vp9_get_compressed_data_time (i = 0) as the total time. - if (i == 0) { - frame_total = cpi->frame_component_time[0]; - total = cpi->component_time[0]; - } - fprintf(stderr, - " %50s: %15" PRId64 " us [%6.2f%%] (total: %15" PRId64 - " us [%6.2f%%])\n", - get_component_name(i), cpi->frame_component_time[i], - (float)((float)cpi->frame_component_time[i] * 100.0 / - (float)frame_total), - cpi->component_time[i], - (float)((float)cpi->component_time[i] * 100.0 / (float)total)); - cpi->frame_component_time[i] = 0; - } - } -#endif - - if (is_one_pass_svc(cpi)) { - if (cm->show_frame) { - ++cpi->svc.spatial_layer_to_encode; - if (cpi->svc.spatial_layer_to_encode >= cpi->svc.number_spatial_layers) - cpi->svc.spatial_layer_to_encode = 0; - } - } - - vpx_clear_system_state(); - return 0; -} - -int vp9_get_preview_raw_frame(VP9_COMP *cpi, YV12_BUFFER_CONFIG *dest, - vp9_ppflags_t *flags) { - VP9_COMMON *cm = &cpi->common; -#if !CONFIG_VP9_POSTPROC - (void)flags; -#endif - - if (!cm->show_frame) { - return -1; - } else { - int ret; -#if CONFIG_VP9_POSTPROC - ret = vp9_post_proc_frame(cm, dest, flags, cpi->un_scaled_source->y_width); -#else - if (cm->frame_to_show) { - *dest = *cm->frame_to_show; - dest->y_width = cm->width; - dest->y_height = cm->height; - dest->uv_width = cm->width >> cm->subsampling_x; - dest->uv_height = cm->height >> cm->subsampling_y; - ret = 0; - } else { - ret = -1; - } -#endif // !CONFIG_VP9_POSTPROC - vpx_clear_system_state(); - return ret; - } -} - -int vp9_set_internal_size(VP9_COMP *cpi, VPX_SCALING_MODE horiz_mode, - VPX_SCALING_MODE vert_mode) { - VP9_COMMON *cm = &cpi->common; - int hr = 0, hs = 0, vr = 0, vs = 0; - - if (horiz_mode > VP8E_ONETWO || vert_mode > VP8E_ONETWO) return -1; - - Scale2Ratio(horiz_mode, &hr, &hs); - Scale2Ratio(vert_mode, &vr, &vs); - - // always go to the next whole number - cm->width = (hs - 1 + cpi->oxcf.width * hr) / hs; - cm->height = (vs - 1 + cpi->oxcf.height * vr) / vs; - if (cm->current_video_frame) { - assert(cm->width <= cpi->initial_width); - assert(cm->height <= cpi->initial_height); - } - - update_frame_size(cpi); - - return 0; -} - -int vp9_set_size_literal(VP9_COMP *cpi, unsigned int width, - unsigned int height) { - VP9_COMMON *cm = &cpi->common; -#if CONFIG_VP9_HIGHBITDEPTH - update_initial_width(cpi, cm->use_highbitdepth, cpi->common.subsampling_x, - cpi->common.subsampling_y); -#else - update_initial_width(cpi, 0, cpi->common.subsampling_x, - cpi->common.subsampling_y); -#endif // CONFIG_VP9_HIGHBITDEPTH - -#if CONFIG_VP9_TEMPORAL_DENOISING - setup_denoiser_buffer(cpi); -#endif - alloc_raw_frame_buffers(cpi); - if (width) { - cm->width = width; - if (cm->width > cpi->initial_width) { - cm->width = cpi->initial_width; - } - } - - if (height) { - cm->height = height; - if (cm->height > cpi->initial_height) { - cm->height = cpi->initial_height; - } - } - assert(cm->width <= cpi->initial_width); - assert(cm->height <= cpi->initial_height); - - update_frame_size(cpi); - - return 0; -} - -void vp9_set_svc(VP9_COMP *cpi, int use_svc) { - cpi->use_svc = use_svc; - return; -} - -int vp9_get_quantizer(const VP9_COMP *cpi) { return cpi->common.base_qindex; } - -void vp9_apply_encoding_flags(VP9_COMP *cpi, vpx_enc_frame_flags_t flags) { - if (flags & - (VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF)) { - int ref = 7; - - if (flags & VP8_EFLAG_NO_REF_LAST) ref ^= VP9_LAST_FLAG; - - if (flags & VP8_EFLAG_NO_REF_GF) ref ^= VP9_GOLD_FLAG; - - if (flags & VP8_EFLAG_NO_REF_ARF) ref ^= VP9_ALT_FLAG; - - vp9_use_as_reference(cpi, ref); - } - - if (flags & - (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | - VP8_EFLAG_FORCE_GF | VP8_EFLAG_FORCE_ARF)) { - int upd = 7; - - if (flags & VP8_EFLAG_NO_UPD_LAST) upd ^= VP9_LAST_FLAG; - - if (flags & VP8_EFLAG_NO_UPD_GF) upd ^= VP9_GOLD_FLAG; - - if (flags & VP8_EFLAG_NO_UPD_ARF) upd ^= VP9_ALT_FLAG; - - vp9_update_reference(cpi, upd); - } - - if (flags & VP8_EFLAG_NO_UPD_ENTROPY) { - vp9_update_entropy(cpi, 0); - } -} - -void vp9_set_row_mt(VP9_COMP *cpi) { - // Enable row based multi-threading for supported modes of encoding - cpi->row_mt = 0; - if (((cpi->oxcf.mode == GOOD || cpi->oxcf.mode == BEST) && - cpi->oxcf.speed < 5 && cpi->oxcf.pass == 1) && - cpi->oxcf.row_mt && !cpi->use_svc) - cpi->row_mt = 1; - - if (cpi->oxcf.mode == GOOD && cpi->oxcf.speed < 5 && - (cpi->oxcf.pass == 0 || cpi->oxcf.pass == 2) && cpi->oxcf.row_mt && - !cpi->use_svc) - cpi->row_mt = 1; - - // In realtime mode, enable row based multi-threading for all the speed levels - // where non-rd path is used. - if (cpi->oxcf.mode == REALTIME && cpi->oxcf.speed >= 5 && cpi->oxcf.row_mt) { - cpi->row_mt = 1; - } - - if (cpi->row_mt) - cpi->row_mt_bit_exact = 1; - else - cpi->row_mt_bit_exact = 0; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encoder.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encoder.h deleted file mode 100644 index 8afea3ad..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_encoder.h +++ /dev/null @@ -1,1671 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_ENCODER_H_ -#define VPX_VP9_ENCODER_VP9_ENCODER_H_ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx/internal/vpx_codec_internal.h" -#include "vpx/vpx_ext_ratectrl.h" -#include "vpx/vp8cx.h" -#include "vpx/vpx_tpl.h" -#if CONFIG_INTERNAL_STATS -#include "vpx_dsp/ssim.h" -#endif -#include "vpx_dsp/variance.h" -#include "vpx_dsp/psnr.h" -#include "vpx_ports/system_state.h" -#include "vpx_util/vpx_pthread.h" -#include "vpx_util/vpx_thread.h" -#include "vpx_util/vpx_timestamp.h" - -#include "vp9/common/vp9_alloccommon.h" -#include "vp9/common/vp9_ppflags.h" -#include "vp9/common/vp9_entropymode.h" -#include "vp9/common/vp9_thread_common.h" -#include "vp9/common/vp9_onyxc_int.h" - -#if !CONFIG_REALTIME_ONLY -#include "vp9/encoder/vp9_alt_ref_aq.h" -#endif -#include "vp9/encoder/vp9_aq_cyclicrefresh.h" -#include "vp9/encoder/vp9_context_tree.h" -#include "vp9/encoder/vp9_encodemb.h" -#include "vp9/encoder/vp9_ethread.h" -#include "vp9/encoder/vp9_ext_ratectrl.h" -#include "vp9/encoder/vp9_firstpass.h" -#include "vp9/encoder/vp9_job_queue.h" -#include "vp9/encoder/vp9_lookahead.h" -#include "vp9/encoder/vp9_mbgraph.h" -#include "vp9/encoder/vp9_mcomp.h" -#include "vp9/encoder/vp9_noise_estimate.h" -#include "vp9/encoder/vp9_quantize.h" -#include "vp9/encoder/vp9_ratectrl.h" -#include "vp9/encoder/vp9_rd.h" -#include "vp9/encoder/vp9_speed_features.h" -#include "vp9/encoder/vp9_svc_layercontext.h" -#include "vp9/encoder/vp9_tokenize.h" - -#if CONFIG_VP9_TEMPORAL_DENOISING -#include "vp9/encoder/vp9_denoiser.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -// vp9 uses 10,000,000 ticks/second as time stamp -#define TICKS_PER_SEC 10000000 - -typedef struct { - int nmvjointcost[MV_JOINTS]; - int nmvcosts[2][MV_VALS]; - int nmvcosts_hp[2][MV_VALS]; - - vpx_prob segment_pred_probs[PREDICTION_PROBS]; - - unsigned char *last_frame_seg_map_copy; - - // 0 = Intra, Last, GF, ARF - signed char last_ref_lf_deltas[MAX_REF_LF_DELTAS]; - // 0 = ZERO_MV, MV - signed char last_mode_lf_deltas[MAX_MODE_LF_DELTAS]; - - FRAME_CONTEXT fc; -} CODING_CONTEXT; - -typedef enum { - // encode_breakout is disabled. - ENCODE_BREAKOUT_DISABLED = 0, - // encode_breakout is enabled. - ENCODE_BREAKOUT_ENABLED = 1, - // encode_breakout is enabled with small max_thresh limit. - ENCODE_BREAKOUT_LIMITED = 2 -} ENCODE_BREAKOUT_TYPE; - -typedef enum { - // Good Quality Fast Encoding. The encoder balances quality with the amount of - // time it takes to encode the output. Speed setting controls how fast. - GOOD, - - // The encoder places priority on the quality of the output over encoding - // speed. The output is compressed at the highest possible quality. This - // option takes the longest amount of time to encode. Speed setting ignored. - BEST, - - // Realtime/Live Encoding. This mode is optimized for realtime encoding (for - // example, capturing a television signal or feed from a live camera). Speed - // setting controls how fast. - REALTIME -} MODE; - -typedef enum { - FRAMEFLAGS_KEY = 1 << 0, - FRAMEFLAGS_GOLDEN = 1 << 1, - FRAMEFLAGS_ALTREF = 1 << 2, -} FRAMETYPE_FLAGS; - -typedef enum { - NO_AQ = 0, - VARIANCE_AQ = 1, - COMPLEXITY_AQ = 2, - CYCLIC_REFRESH_AQ = 3, - EQUATOR360_AQ = 4, - PERCEPTUAL_AQ = 5, - PSNR_AQ = 6, - // AQ based on lookahead temporal - // variance (only valid for altref frames) - LOOKAHEAD_AQ = 7, - AQ_MODE_COUNT // This should always be the last member of the enum -} AQ_MODE; - -typedef enum { - RESIZE_NONE = 0, // No frame resizing allowed (except for SVC). - RESIZE_FIXED = 1, // All frames are coded at the specified dimension. - RESIZE_DYNAMIC = 2 // Coded size of each frame is determined by the codec. -} RESIZE_TYPE; - -typedef enum { - kInvalid = 0, - kLowSadLowSumdiff = 1, - kLowSadHighSumdiff = 2, - kHighSadLowSumdiff = 3, - kHighSadHighSumdiff = 4, - kLowVarHighSumdiff = 5, - kVeryHighSad = 6, -} CONTENT_STATE_SB; - -typedef enum { - LOOPFILTER_ALL = 0, - LOOPFILTER_REFERENCE = 1, // Disable loopfilter on non reference frames. - NO_LOOPFILTER = 2, // Disable loopfilter on all frames. -} LOOPFILTER_CONTROL; - -typedef struct VP9EncoderConfig { - BITSTREAM_PROFILE profile; - vpx_bit_depth_t bit_depth; // Codec bit-depth. - int width; // width of data passed to the compressor - int height; // height of data passed to the compressor - unsigned int input_bit_depth; // Input bit depth. - double init_framerate; // set to passed in framerate - vpx_rational_t g_timebase; // equivalent to g_timebase in vpx_codec_enc_cfg_t - vpx_rational64_t g_timebase_in_ts; // g_timebase * TICKS_PER_SEC - - int64_t target_bandwidth; // bandwidth to be used in bits per second - - int noise_sensitivity; // pre processing blur: recommendation 0 - int sharpness; // sharpening output: recommendation 0: - int speed; - // maximum allowed bitrate for any intra frame in % of bitrate target. - unsigned int rc_max_intra_bitrate_pct; - // maximum allowed bitrate for any inter frame in % of bitrate target. - unsigned int rc_max_inter_bitrate_pct; - // percent of rate boost for golden frame in CBR mode. - unsigned int gf_cbr_boost_pct; - - MODE mode; - int pass; - - // Key Framing Operations - int auto_key; // autodetect cut scenes and set the keyframes - int key_freq; // maximum distance to key frame. - - int lag_in_frames; // how many frames lag before we start encoding - - // ---------------------------------------------------------------- - // DATARATE CONTROL OPTIONS - - // vbr, cbr, constrained quality or constant quality - enum vpx_rc_mode rc_mode; - - // buffer targeting aggressiveness - int under_shoot_pct; - int over_shoot_pct; - - // buffering parameters - int64_t starting_buffer_level_ms; - int64_t optimal_buffer_level_ms; - int64_t maximum_buffer_size_ms; - - // Frame drop threshold. - int drop_frames_water_mark; - - // controlling quality - int fixed_q; - int worst_allowed_q; - int best_allowed_q; - int cq_level; - AQ_MODE aq_mode; // Adaptive Quantization mode - - // Special handling of Adaptive Quantization for AltRef frames - int alt_ref_aq; - - // Internal frame size scaling. - RESIZE_TYPE resize_mode; - int scaled_frame_width; - int scaled_frame_height; - - // Enable feature to reduce the frame quantization every x frames. - int frame_periodic_boost; - - // two pass datarate control - int two_pass_vbrbias; // two pass datarate control tweaks - int two_pass_vbrmin_section; - int two_pass_vbrmax_section; - int vbr_corpus_complexity; // 0 indicates corpus vbr disabled - // END DATARATE CONTROL OPTIONS - // ---------------------------------------------------------------- - - // Spatial and temporal scalability. - int ss_number_layers; // Number of spatial layers. - int ts_number_layers; // Number of temporal layers. - // Bitrate allocation for spatial layers. - int layer_target_bitrate[VPX_MAX_LAYERS]; - int ss_target_bitrate[VPX_SS_MAX_LAYERS]; - int ss_enable_auto_arf[VPX_SS_MAX_LAYERS]; - // Bitrate allocation (CBR mode) and framerate factor, for temporal layers. - int ts_rate_decimator[VPX_TS_MAX_LAYERS]; - - int enable_auto_arf; - - int encode_breakout; // early breakout : for video conf recommend 800 - - /* Bitfield defining the error resiliency features to enable. - * Can provide decodable frames after losses in previous - * frames and decodable partitions after losses in the same frame. - */ - unsigned int error_resilient_mode; - - /* Bitfield defining the parallel decoding mode where the - * decoding in successive frames may be conducted in parallel - * just by decoding the frame headers. - */ - unsigned int frame_parallel_decoding_mode; - - int arnr_max_frames; - int arnr_strength; - - int min_gf_interval; - int max_gf_interval; - - int tile_columns; - int tile_rows; - - int enable_tpl_model; - - int enable_keyframe_filtering; - - int max_threads; - - unsigned int target_level; - - vpx_fixed_buf_t two_pass_stats_in; - - vp8e_tuning tuning; - vp9e_tune_content content; -#if CONFIG_VP9_HIGHBITDEPTH - int use_highbitdepth; -#endif - vpx_color_space_t color_space; - vpx_color_range_t color_range; - int render_width; - int render_height; - VP9E_TEMPORAL_LAYERING_MODE temporal_layering_mode; - - int row_mt; - unsigned int motion_vector_unit_test; - int delta_q_uv; - int use_simple_encode_api; // Use SimpleEncode APIs or not -} VP9EncoderConfig; - -static INLINE int is_lossless_requested(const VP9EncoderConfig *cfg) { - return cfg->best_allowed_q == 0 && cfg->worst_allowed_q == 0; -} - -typedef struct TplDepStats { - int64_t intra_cost; - int64_t inter_cost; - int64_t mc_flow; - int64_t mc_dep_cost; - int64_t mc_ref_cost; - - int ref_frame_index; - int_mv mv; -} TplDepStats; - -#if CONFIG_NON_GREEDY_MV - -#define ZERO_MV_MODE 0 -#define NEW_MV_MODE 1 -#define NEAREST_MV_MODE 2 -#define NEAR_MV_MODE 3 -#define MAX_MV_MODE 4 -#endif - -typedef struct TplDepFrame { - uint8_t is_valid; - TplDepStats *tpl_stats_ptr; - int stride; - int width; - int height; - int mi_rows; - int mi_cols; - int base_qindex; -#if CONFIG_NON_GREEDY_MV - int lambda; - int *mv_mode_arr[3]; - double *rd_diff_arr[3]; -#endif -} TplDepFrame; - -#define TPL_DEP_COST_SCALE_LOG2 4 - -// TODO(jingning) All spatially adaptive variables should go to TileDataEnc. -typedef struct TileDataEnc { - TileInfo tile_info; - int thresh_freq_fact[BLOCK_SIZES][MAX_MODES]; - int thresh_freq_fact_prev[BLOCK_SIZES][MAX_MODES]; - int8_t mode_map[BLOCK_SIZES][MAX_MODES]; - FIRSTPASS_DATA fp_data; - VP9RowMTSync row_mt_sync; - - // Used for adaptive_rd_thresh with row multithreading - int *row_base_thresh_freq_fact; - // The value of sb_rows when row_base_thresh_freq_fact is allocated. - // The row_base_thresh_freq_fact array has sb_rows * BLOCK_SIZES * MAX_MODES - // elements. - int sb_rows; - MV firstpass_top_mv; -} TileDataEnc; - -typedef struct RowMTInfo { - JobQueueHandle job_queue_hdl; -#if CONFIG_MULTITHREAD - pthread_mutex_t job_mutex; -#endif -} RowMTInfo; - -typedef struct { - TOKENEXTRA *start; - TOKENEXTRA *stop; - unsigned int count; -} TOKENLIST; - -typedef struct MultiThreadHandle { - int allocated_tile_rows; - int allocated_tile_cols; - int allocated_vert_unit_rows; - - // Frame level params - int num_tile_vert_sbs[MAX_NUM_TILE_ROWS]; - - // Job Queue structure and handles - JobQueue *job_queue; - - int jobs_per_tile_col; - - RowMTInfo row_mt_info[MAX_NUM_TILE_COLS]; - int thread_id_to_tile_id[MAX_NUM_THREADS]; // Mapping of threads to tiles -} MultiThreadHandle; - -typedef struct RD_COUNTS { - vp9_coeff_count coef_counts[TX_SIZES][PLANE_TYPES]; - int64_t comp_pred_diff[REFERENCE_MODES]; - int64_t filter_diff[SWITCHABLE_FILTER_CONTEXTS]; -} RD_COUNTS; - -typedef struct ThreadData { - MACROBLOCK mb; - RD_COUNTS rd_counts; - FRAME_COUNTS *counts; - - PICK_MODE_CONTEXT *leaf_tree; - PC_TREE *pc_tree; - PC_TREE *pc_root; -} ThreadData; - -struct EncWorkerData; - -typedef struct ActiveMap { - int enabled; - int update; - unsigned char *map; -} ActiveMap; - -typedef enum { Y, U, V, ALL } STAT_TYPE; - -typedef struct IMAGE_STAT { - double stat[ALL + 1]; - double worst; -} ImageStat; - -// Kf noise filtering currently disabled by default in build. -// #define ENABLE_KF_DENOISE 1 - -#define CPB_WINDOW_SIZE 4 -#define FRAME_WINDOW_SIZE 128 -#define SAMPLE_RATE_GRACE_P 0.015 -#define VP9_LEVELS 14 - -typedef enum { - LEVEL_UNKNOWN = 0, - LEVEL_AUTO = 1, - LEVEL_1 = 10, - LEVEL_1_1 = 11, - LEVEL_2 = 20, - LEVEL_2_1 = 21, - LEVEL_3 = 30, - LEVEL_3_1 = 31, - LEVEL_4 = 40, - LEVEL_4_1 = 41, - LEVEL_5 = 50, - LEVEL_5_1 = 51, - LEVEL_5_2 = 52, - LEVEL_6 = 60, - LEVEL_6_1 = 61, - LEVEL_6_2 = 62, - LEVEL_MAX = 255 -} VP9_LEVEL; - -typedef struct { - VP9_LEVEL level; - uint64_t max_luma_sample_rate; - uint32_t max_luma_picture_size; - uint32_t max_luma_picture_breadth; - double average_bitrate; // in kilobits per second - double max_cpb_size; // in kilobits - double compression_ratio; - uint8_t max_col_tiles; - uint32_t min_altref_distance; - uint8_t max_ref_frame_buffers; -} Vp9LevelSpec; - -extern const Vp9LevelSpec vp9_level_defs[VP9_LEVELS]; - -typedef struct { - int64_t ts; // timestamp - uint32_t luma_samples; - uint32_t size; // in bytes -} FrameRecord; - -typedef struct { - FrameRecord buf[FRAME_WINDOW_SIZE]; - uint8_t start; - uint8_t len; -} FrameWindowBuffer; - -typedef struct { - uint8_t seen_first_altref; - uint32_t frames_since_last_altref; - uint64_t total_compressed_size; - uint64_t total_uncompressed_size; - double time_encoded; // in seconds - FrameWindowBuffer frame_window_buffer; - int ref_refresh_map; -} Vp9LevelStats; - -typedef struct { - Vp9LevelStats level_stats; - Vp9LevelSpec level_spec; -} Vp9LevelInfo; - -typedef enum { - BITRATE_TOO_LARGE = 0, - LUMA_PIC_SIZE_TOO_LARGE, - LUMA_PIC_BREADTH_TOO_LARGE, - LUMA_SAMPLE_RATE_TOO_LARGE, - CPB_TOO_LARGE, - COMPRESSION_RATIO_TOO_SMALL, - TOO_MANY_COLUMN_TILE, - ALTREF_DIST_TOO_SMALL, - TOO_MANY_REF_BUFFER, - TARGET_LEVEL_FAIL_IDS -} TARGET_LEVEL_FAIL_ID; - -typedef struct { - int8_t level_index; - uint8_t fail_flag; - int max_frame_size; // in bits - double max_cpb_size; // in bits -} LevelConstraint; - -typedef struct ARNRFilterData { - YV12_BUFFER_CONFIG *frames[MAX_LAG_BUFFERS]; - int strength; - int frame_count; - int alt_ref_index; - struct scale_factors sf; - YV12_BUFFER_CONFIG *dst; -} ARNRFilterData; - -typedef struct EncFrameBuf { - int mem_valid; - int released; - YV12_BUFFER_CONFIG frame; -} EncFrameBuf; - -// Maximum operating frame buffer size needed for a GOP using ARF reference. -// This is used to allocate the memory for TPL stats for a GOP. -#define MAX_ARF_GOP_SIZE (2 * MAX_LAG_BUFFERS) -#define MAX_KMEANS_GROUPS 8 - -typedef struct KMEANS_DATA { - double value; - int pos; - int group_idx; -} KMEANS_DATA; - -#if CONFIG_RATE_CTRL -typedef struct PARTITION_INFO { - int row; // row pixel offset of current 4x4 block - int column; // column pixel offset of current 4x4 block - int row_start; // row pixel offset of the start of the prediction block - int column_start; // column pixel offset of the start of the prediction block - int width; // prediction block width - int height; // prediction block height -} PARTITION_INFO; - -typedef struct MOTION_VECTOR_INFO { - MV_REFERENCE_FRAME ref_frame[2]; - int_mv mv[2]; -} MOTION_VECTOR_INFO; - -typedef struct GOP_COMMAND { - int use; // use this command to set gop or not. If not, use vp9's decision. - int show_frame_count; - int use_alt_ref; -} GOP_COMMAND; - -static INLINE void gop_command_on(GOP_COMMAND *gop_command, - int show_frame_count, int use_alt_ref) { - gop_command->use = 1; - gop_command->show_frame_count = show_frame_count; - gop_command->use_alt_ref = use_alt_ref; -} - -static INLINE void gop_command_off(GOP_COMMAND *gop_command) { - gop_command->use = 0; - gop_command->show_frame_count = 0; - gop_command->use_alt_ref = 0; -} - -static INLINE int gop_command_coding_frame_count( - const GOP_COMMAND *gop_command) { - if (gop_command->use == 0) { - assert(0); - return -1; - } - return gop_command->show_frame_count + gop_command->use_alt_ref; -} - -// TODO(angiebird): See if we can merge this one with FrameType in -// simple_encode.h -typedef enum ENCODE_FRAME_TYPE { - ENCODE_FRAME_TYPE_KEY, - ENCODE_FRAME_TYPE_INTER, - ENCODE_FRAME_TYPE_ALTREF, - ENCODE_FRAME_TYPE_OVERLAY, - ENCODE_FRAME_TYPE_GOLDEN, - ENCODE_FRAME_TYPES, -} ENCODE_FRAME_TYPE; - -// TODO(angiebird): Merge this function with get_frame_type_from_update_type() -static INLINE ENCODE_FRAME_TYPE -get_encode_frame_type(FRAME_UPDATE_TYPE update_type) { - switch (update_type) { - case KF_UPDATE: return ENCODE_FRAME_TYPE_KEY; - case ARF_UPDATE: return ENCODE_FRAME_TYPE_ALTREF; - case GF_UPDATE: return ENCODE_FRAME_TYPE_GOLDEN; - case OVERLAY_UPDATE: return ENCODE_FRAME_TYPE_OVERLAY; - case LF_UPDATE: return ENCODE_FRAME_TYPE_INTER; - default: - fprintf(stderr, "Unsupported update_type %d\n", update_type); - abort(); - return ENCODE_FRAME_TYPE_INTER; - } -} - -typedef struct RATE_QSTEP_MODEL { - // The rq model predicts the bit usage as follows. - // rate = bias - ratio * log2(q_step) - int ready; - double bias; - double ratio; -} RATE_QSTEP_MODEL; - -typedef struct ENCODE_COMMAND { - int use_external_quantize_index; - int external_quantize_index; - - int use_external_target_frame_bits; - int target_frame_bits; - double target_frame_bits_error_percent; - - GOP_COMMAND gop_command; -} ENCODE_COMMAND; - -static INLINE void encode_command_set_gop_command( - ENCODE_COMMAND *encode_command, GOP_COMMAND gop_command) { - encode_command->gop_command = gop_command; -} - -static INLINE void encode_command_set_external_quantize_index( - ENCODE_COMMAND *encode_command, int quantize_index) { - encode_command->use_external_quantize_index = 1; - encode_command->external_quantize_index = quantize_index; -} - -static INLINE void encode_command_reset_external_quantize_index( - ENCODE_COMMAND *encode_command) { - encode_command->use_external_quantize_index = 0; - encode_command->external_quantize_index = -1; -} - -static INLINE void encode_command_set_target_frame_bits( - ENCODE_COMMAND *encode_command, int target_frame_bits, - double target_frame_bits_error_percent) { - encode_command->use_external_target_frame_bits = 1; - encode_command->target_frame_bits = target_frame_bits; - encode_command->target_frame_bits_error_percent = - target_frame_bits_error_percent; -} - -static INLINE void encode_command_reset_target_frame_bits( - ENCODE_COMMAND *encode_command) { - encode_command->use_external_target_frame_bits = 0; - encode_command->target_frame_bits = -1; - encode_command->target_frame_bits_error_percent = 0; -} - -static INLINE void encode_command_init(ENCODE_COMMAND *encode_command) { - vp9_zero(*encode_command); - encode_command_reset_external_quantize_index(encode_command); - encode_command_reset_target_frame_bits(encode_command); - gop_command_off(&encode_command->gop_command); -} - -// Returns number of units in size of 4, if not multiple not a multiple of 4, -// round it up. For example, size is 7, return 2. -static INLINE int get_num_unit_4x4(int size) { return (size + 3) >> 2; } -// Returns number of units in size of 16, if not multiple not a multiple of 16, -// round it up. For example, size is 17, return 2. -static INLINE int get_num_unit_16x16(int size) { return (size + 15) >> 4; } -#endif // CONFIG_RATE_CTRL - -#if CONFIG_COLLECT_COMPONENT_TIMING -#include "vpx_ports/vpx_timer.h" -// Adjust the following to add new components. -typedef enum { - vp9_get_compressed_data_time, - vp9_temporal_filter_time, - vp9_rc_get_second_pass_params_time, - setup_tpl_stats_time, - Pass2Encode_time, - - encode_with_recode_loop_time, - loopfilter_frame_time, - vp9_pack_bitstream_time, - - encode_frame_internal_time, - rd_pick_partition_time, - rd_pick_sb_modes_time, - encode_sb_time, - - vp9_rd_pick_inter_mode_sb_time, - vp9_rd_pick_inter_mode_sub8x8_time, - - intra_mode_search_time, - handle_inter_mode_time, - single_motion_search_time, - joint_motion_search_time, - interp_filter_time, - - kTimingComponents, -} TIMING_COMPONENT; - -static INLINE char const *get_component_name(int index) { - switch (index) { - case vp9_get_compressed_data_time: return "vp9_get_compressed_data_time"; - case vp9_temporal_filter_time: return "vp9_temporal_filter_time"; - case vp9_rc_get_second_pass_params_time: - return "vp9_rc_get_second_pass_params_time"; - case setup_tpl_stats_time: return "setup_tpl_stats_time"; - case Pass2Encode_time: return "Pass2Encode_time"; - - case encode_with_recode_loop_time: return "encode_with_recode_loop_time"; - case loopfilter_frame_time: return "loopfilter_frame_time"; - case vp9_pack_bitstream_time: return "vp9_pack_bitstream_time"; - - case encode_frame_internal_time: return "encode_frame_internal_time"; - case rd_pick_partition_time: return "rd_pick_partition_time"; - case rd_pick_sb_modes_time: return "rd_pick_sb_modes_time"; - case encode_sb_time: return "encode_sb_time"; - - case vp9_rd_pick_inter_mode_sb_time: - return "vp9_rd_pick_inter_mode_sb_time"; - case vp9_rd_pick_inter_mode_sub8x8_time: - return "vp9_rd_pick_inter_mode_sub8x8_time"; - - case intra_mode_search_time: return "intra_mode_search_time"; - case handle_inter_mode_time: return "handle_inter_mode_time"; - case single_motion_search_time: return "single_motion_search_time"; - case joint_motion_search_time: return "joint_motion_search_time"; - case interp_filter_time: return "interp_filter_time"; - - default: assert(0); - } - return "error"; -} -#endif - -typedef struct VP9_COMP { - FRAME_INFO frame_info; - QUANTS quants; - ThreadData td; - MB_MODE_INFO_EXT *mbmi_ext_base; - DECLARE_ALIGNED(16, int16_t, y_dequant[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, uv_dequant[QINDEX_RANGE][8]); - VP9_COMMON common; - VP9EncoderConfig oxcf; - struct lookahead_ctx *lookahead; - struct lookahead_entry *alt_ref_source; - - YV12_BUFFER_CONFIG *Source; - YV12_BUFFER_CONFIG *Last_Source; // NULL for first frame and alt_ref frames - YV12_BUFFER_CONFIG *un_scaled_source; - YV12_BUFFER_CONFIG scaled_source; - YV12_BUFFER_CONFIG *unscaled_last_source; - YV12_BUFFER_CONFIG scaled_last_source; -#ifdef ENABLE_KF_DENOISE - YV12_BUFFER_CONFIG raw_unscaled_source; - YV12_BUFFER_CONFIG raw_scaled_source; -#endif - YV12_BUFFER_CONFIG *raw_source_frame; - - BLOCK_SIZE tpl_bsize; - TplDepFrame tpl_stats[MAX_ARF_GOP_SIZE]; - // Used to store TPL stats before propagation - VpxTplGopStats tpl_gop_stats; - YV12_BUFFER_CONFIG *tpl_recon_frames[REF_FRAMES]; - EncFrameBuf enc_frame_buf[REF_FRAMES]; -#if CONFIG_MULTITHREAD - pthread_mutex_t kmeans_mutex; -#endif - int kmeans_data_arr_alloc; - KMEANS_DATA *kmeans_data_arr; - int kmeans_data_size; - int kmeans_data_stride; - double kmeans_ctr_ls[MAX_KMEANS_GROUPS]; - double kmeans_boundary_ls[MAX_KMEANS_GROUPS]; - int kmeans_count_ls[MAX_KMEANS_GROUPS]; - int kmeans_ctr_num; -#if CONFIG_NON_GREEDY_MV - MotionFieldInfo motion_field_info; - int tpl_ready; - int_mv *select_mv_arr; -#endif - - TileDataEnc *tile_data; - int allocated_tiles; // Keep track of memory allocated for tiles. - - int scaled_ref_idx[REFS_PER_FRAME]; - int lst_fb_idx; - int gld_fb_idx; - int alt_fb_idx; - - int ref_fb_idx[REF_FRAMES]; - - int refresh_last_frame; - int refresh_golden_frame; - int refresh_alt_ref_frame; - - int ext_refresh_frame_flags_pending; - int ext_refresh_last_frame; - int ext_refresh_golden_frame; - int ext_refresh_alt_ref_frame; - - int ext_refresh_frame_context_pending; - int ext_refresh_frame_context; - - int64_t norm_wiener_variance; - int64_t *mb_wiener_variance; - int mb_wiener_var_rows; - int mb_wiener_var_cols; - double *mi_ssim_rdmult_scaling_factors; - - YV12_BUFFER_CONFIG last_frame_uf; - - TOKENEXTRA *tile_tok[4][1 << 6]; - TOKENLIST *tplist[4][1 << 6]; - - // Ambient reconstruction err target for force key frames - int64_t ambient_err; - - RD_CONTROL rd_ctrl; - RD_OPT rd; - - CODING_CONTEXT coding_context; - - int *nmvcosts[2]; - int *nmvcosts_hp[2]; - int *nmvsadcosts[2]; - int *nmvsadcosts_hp[2]; - - int64_t last_time_stamp_seen; - int64_t last_end_time_stamp_seen; - int64_t first_time_stamp_ever; - - RATE_CONTROL rc; - double framerate; - - int interp_filter_selected[REF_FRAMES][SWITCHABLE]; - - struct vpx_codec_pkt_list *output_pkt_list; - - MBGRAPH_FRAME_STATS mbgraph_stats[MAX_LAG_BUFFERS]; - int mbgraph_n_frames; // number of frames filled in the above - int static_mb_pct; // % forced skip mbs by segmentation - int ref_frame_flags; - - SPEED_FEATURES sf; - - uint32_t max_mv_magnitude; - int mv_step_param; - - int allow_comp_inter_inter; - - // Default value is 1. From first pass stats, encode_breakout may be disabled. - ENCODE_BREAKOUT_TYPE allow_encode_breakout; - - // Get threshold from external input. A suggested threshold is 800 for HD - // clips, and 300 for < HD clips. - int encode_breakout; - - uint8_t *segmentation_map; - - uint8_t *skin_map; - - // segment threshold for encode breakout - int segment_encode_breakout[MAX_SEGMENTS]; - - CYCLIC_REFRESH *cyclic_refresh; - ActiveMap active_map; - - fractional_mv_step_fp *find_fractional_mv_step; - struct scale_factors me_sf; - vp9_diamond_search_fn_t diamond_search_sad; - vp9_variance_fn_ptr_t fn_ptr[BLOCK_SIZES]; - uint64_t time_receive_data; - uint64_t time_compress_data; - uint64_t time_pick_lpf; - uint64_t time_encode_sb_row; - - TWO_PASS twopass; - - // Force recalculation of segment_ids for each mode info - uint8_t force_update_segmentation; - - YV12_BUFFER_CONFIG tf_buffer; - - // class responsible for adaptive - // quantization of altref frames - struct ALT_REF_AQ *alt_ref_aq; - -#if CONFIG_INTERNAL_STATS - unsigned int mode_chosen_counts[MAX_MODES]; - - int count; - uint64_t total_sq_error; - uint64_t total_samples; - ImageStat psnr; - - uint64_t totalp_sq_error; - uint64_t totalp_samples; - ImageStat psnrp; - - double total_blockiness; - double worst_blockiness; - - uint64_t bytes; - double summed_quality; - double summed_weights; - double summedp_quality; - double summedp_weights; - unsigned int tot_recode_hits; - double worst_ssim; - - ImageStat ssimg; - ImageStat fastssim; - ImageStat psnrhvs; - - int b_calculate_ssimg; - int b_calculate_blockiness; - - int b_calculate_consistency; - - double total_inconsistency; - double worst_consistency; - Ssimv *ssim_vars; - Metrics metrics; -#endif - int b_calculate_psnr; - - int droppable; - - int initial_width; - int initial_height; - int initial_mbs; // Number of MBs in the full-size frame; to be used to - // normalize the firstpass stats. This will differ from the - // number of MBs in the current frame when the frame is - // scaled. - - int last_coded_width; - int last_coded_height; - - int use_svc; - - SVC svc; - - // Store frame variance info in SOURCE_VAR_BASED_PARTITION search type. - Diff *source_diff_var; - // The threshold used in SOURCE_VAR_BASED_PARTITION search type. - unsigned int source_var_thresh; - int frames_till_next_var_check; - - int frame_flags; - - search_site_config ss_cfg; - - int mbmode_cost[INTRA_MODES]; - unsigned int inter_mode_cost[INTER_MODE_CONTEXTS][INTER_MODES]; - int intra_uv_mode_cost[FRAME_TYPES][INTRA_MODES][INTRA_MODES]; - int y_mode_costs[INTRA_MODES][INTRA_MODES][INTRA_MODES]; - int switchable_interp_costs[SWITCHABLE_FILTER_CONTEXTS][SWITCHABLE_FILTERS]; - int partition_cost[PARTITION_CONTEXTS][PARTITION_TYPES]; - // Indices are: max_tx_size-1, tx_size_ctx, tx_size - int tx_size_cost[TX_SIZES - 1][TX_SIZE_CONTEXTS][TX_SIZES]; - -#if CONFIG_VP9_TEMPORAL_DENOISING - VP9_DENOISER denoiser; -#endif - - int resize_pending; - RESIZE_STATE resize_state; - int external_resize; - int resize_scale_num; - int resize_scale_den; - int resize_avg_qp; - int resize_buffer_underflow; - int resize_count; - - int use_skin_detection; - - int target_level; - - NOISE_ESTIMATE noise_estimate; - - // Count on how many consecutive times a block uses small/zeromv for encoding. - uint8_t *consec_zero_mv; - - // VAR_BASED_PARTITION thresholds - // 0 - threshold_64x64; 1 - threshold_32x32; - // 2 - threshold_16x16; 3 - vbp_threshold_8x8; - int64_t vbp_thresholds[4]; - int64_t vbp_threshold_minmax; - int64_t vbp_threshold_sad; - // Threshold used for partition copy - int64_t vbp_threshold_copy; - BLOCK_SIZE vbp_bsize_min; - - // Multi-threading - int num_workers; - VPxWorker *workers; - struct EncWorkerData *tile_thr_data; - VP9LfSync lf_row_sync; - struct VP9BitstreamWorkerData *vp9_bitstream_worker_data; - - int keep_level_stats; - Vp9LevelInfo level_info; - MultiThreadHandle multi_thread_ctxt; - void (*row_mt_sync_read_ptr)(VP9RowMTSync *const, int, int); - void (*row_mt_sync_write_ptr)(VP9RowMTSync *const, int, int, const int); - ARNRFilterData arnr_filter_data; - - int row_mt; - unsigned int row_mt_bit_exact; - - // Previous Partition Info - BLOCK_SIZE *prev_partition; - int8_t *prev_segment_id; - // Used to save the status of whether a block has a low variance in - // choose_partitioning. 0 for 64x64, 1~2 for 64x32, 3~4 for 32x64, 5~8 for - // 32x32, 9~24 for 16x16. - // This is for the last frame and is copied to the current frame - // when partition copy happens. - uint8_t *prev_variance_low; - uint8_t *copied_frame_cnt; - uint8_t max_copied_frame; - // If the last frame is dropped, we don't copy partition. - uint8_t last_frame_dropped; - - // For each superblock: keeps track of the last time (in frame distance) the - // the superblock did not have low source sad. - uint8_t *content_state_sb_fd; - - int compute_source_sad_onepass; - - int compute_frame_low_motion_onepass; - - LevelConstraint level_constraint; - - uint8_t *count_arf_frame_usage; - uint8_t *count_lastgolden_frame_usage; - - int multi_layer_arf; - vpx_roi_map_t roi; - - LOOPFILTER_CONTROL loopfilter_ctrl; -#if CONFIG_RATE_CTRL - ENCODE_COMMAND encode_command; - PARTITION_INFO *partition_info; - MOTION_VECTOR_INFO *motion_vector_info; - MOTION_VECTOR_INFO *fp_motion_vector_info; - TplDepStats *tpl_stats_info; - - RATE_QSTEP_MODEL rq_model[ENCODE_FRAME_TYPES]; -#endif - EXT_RATECTRL ext_ratectrl; - - int fixed_qp_onepass; - - // Flag to keep track of dynamic change in deadline mode - // (good/best/realtime). - MODE deadline_mode_previous_frame; - - // Flag to disable scene detection when rtc rate control library is used. - int disable_scene_detection_rtc_ratectrl; - -#if CONFIG_COLLECT_COMPONENT_TIMING - /*! - * component_time[] are initialized to zero while encoder starts. - */ - uint64_t component_time[kTimingComponents]; - /*! - * Stores timing for individual components between calls of start_timing() - * and end_timing(). - */ - struct vpx_usec_timer component_timer[kTimingComponents]; - /*! - * frame_component_time[] are initialized to zero at beginning of each frame. - */ - uint64_t frame_component_time[kTimingComponents]; -#endif -} VP9_COMP; - -#if CONFIG_RATE_CTRL -// Allocates memory for the partition information. -// The unit size is each 4x4 block. -// Only called once in vp9_create_compressor(). -static INLINE void partition_info_init(struct VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - const int unit_width = get_num_unit_4x4(cpi->frame_info.frame_width); - const int unit_height = get_num_unit_4x4(cpi->frame_info.frame_height); - CHECK_MEM_ERROR(&cm->error, cpi->partition_info, - (PARTITION_INFO *)vpx_calloc(unit_width * unit_height, - sizeof(PARTITION_INFO))); - memset(cpi->partition_info, 0, - unit_width * unit_height * sizeof(PARTITION_INFO)); -} - -// Frees memory of the partition information. -// Only called once in dealloc_compressor_data(). -static INLINE void free_partition_info(struct VP9_COMP *cpi) { - vpx_free(cpi->partition_info); - cpi->partition_info = NULL; -} - -static INLINE void reset_mv_info(MOTION_VECTOR_INFO *mv_info) { - mv_info->ref_frame[0] = NO_REF_FRAME; - mv_info->ref_frame[1] = NO_REF_FRAME; - mv_info->mv[0].as_int = INVALID_MV; - mv_info->mv[1].as_int = INVALID_MV; -} - -// Allocates memory for the motion vector information. -// The unit size is each 4x4 block. -// Only called once in vp9_create_compressor(). -static INLINE void motion_vector_info_init(struct VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - const int unit_width = get_num_unit_4x4(cpi->frame_info.frame_width); - const int unit_height = get_num_unit_4x4(cpi->frame_info.frame_height); - CHECK_MEM_ERROR(&cm->error, cpi->motion_vector_info, - (MOTION_VECTOR_INFO *)vpx_calloc(unit_width * unit_height, - sizeof(MOTION_VECTOR_INFO))); - memset(cpi->motion_vector_info, 0, - unit_width * unit_height * sizeof(MOTION_VECTOR_INFO)); -} - -// Frees memory of the motion vector information. -// Only called once in dealloc_compressor_data(). -static INLINE void free_motion_vector_info(struct VP9_COMP *cpi) { - vpx_free(cpi->motion_vector_info); - cpi->motion_vector_info = NULL; -} - -// Allocates memory for the tpl stats information. -// Only called once in vp9_create_compressor(). -static INLINE void tpl_stats_info_init(struct VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - CHECK_MEM_ERROR( - &cm->error, cpi->tpl_stats_info, - (TplDepStats *)vpx_calloc(MAX_LAG_BUFFERS, sizeof(TplDepStats))); - memset(cpi->tpl_stats_info, 0, MAX_LAG_BUFFERS * sizeof(TplDepStats)); -} - -// Frees memory of the tpl stats information. -// Only called once in dealloc_compressor_data(). -static INLINE void free_tpl_stats_info(struct VP9_COMP *cpi) { - vpx_free(cpi->tpl_stats_info); - cpi->tpl_stats_info = NULL; -} - -// Allocates memory for the first pass motion vector information. -// The unit size is each 16x16 block. -// Only called once in vp9_create_compressor(). -static INLINE void fp_motion_vector_info_init(struct VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - const int unit_width = get_num_unit_16x16(cpi->frame_info.frame_width); - const int unit_height = get_num_unit_16x16(cpi->frame_info.frame_height); - CHECK_MEM_ERROR(&cm->error, cpi->fp_motion_vector_info, - (MOTION_VECTOR_INFO *)vpx_calloc(unit_width * unit_height, - sizeof(MOTION_VECTOR_INFO))); -} - -static INLINE void fp_motion_vector_info_reset( - int frame_width, int frame_height, - MOTION_VECTOR_INFO *fp_motion_vector_info) { - const int unit_width = get_num_unit_16x16(frame_width); - const int unit_height = get_num_unit_16x16(frame_height); - int i; - for (i = 0; i < unit_width * unit_height; ++i) { - reset_mv_info(fp_motion_vector_info + i); - } -} - -// Frees memory of the first pass motion vector information. -// Only called once in dealloc_compressor_data(). -static INLINE void free_fp_motion_vector_info(struct VP9_COMP *cpi) { - vpx_free(cpi->fp_motion_vector_info); - cpi->fp_motion_vector_info = NULL; -} - -// This is the c-version counter part of ImageBuffer -typedef struct IMAGE_BUFFER { - int allocated; - int plane_width[3]; - int plane_height[3]; - uint8_t *plane_buffer[3]; -} IMAGE_BUFFER; - -#define RATE_CTRL_MAX_RECODE_NUM 7 - -typedef struct RATE_QINDEX_HISTORY { - int recode_count; - int q_index_history[RATE_CTRL_MAX_RECODE_NUM]; - int rate_history[RATE_CTRL_MAX_RECODE_NUM]; - int q_index_high; - int q_index_low; -} RATE_QINDEX_HISTORY; - -#endif // CONFIG_RATE_CTRL - -typedef struct ENCODE_FRAME_RESULT { - int show_idx; - FRAME_UPDATE_TYPE update_type; -#if CONFIG_RATE_CTRL - int frame_coding_index; - int ref_frame_coding_indexes[MAX_INTER_REF_FRAMES]; - int ref_frame_valid_list[MAX_INTER_REF_FRAMES]; - double psnr; - uint64_t sse; - FRAME_COUNTS frame_counts; - const PARTITION_INFO *partition_info; - const MOTION_VECTOR_INFO *motion_vector_info; - const TplDepStats *tpl_stats_info; - IMAGE_BUFFER coded_frame; - RATE_QINDEX_HISTORY rq_history; -#endif // CONFIG_RATE_CTRL - int quantize_index; -} ENCODE_FRAME_RESULT; - -void vp9_init_encode_frame_result(ENCODE_FRAME_RESULT *encode_frame_result); - -void vp9_initialize_enc(void); - -void vp9_update_compressor_with_img_fmt(VP9_COMP *cpi, vpx_img_fmt_t img_fmt); -struct VP9_COMP *vp9_create_compressor(const VP9EncoderConfig *oxcf, - BufferPool *const pool); -void vp9_remove_compressor(VP9_COMP *cpi); - -void vp9_change_config(VP9_COMP *cpi, const VP9EncoderConfig *oxcf); - -// receive a frames worth of data. caller can assume that a copy of this -// frame is made and not just a copy of the pointer.. -int vp9_receive_raw_frame(VP9_COMP *cpi, vpx_enc_frame_flags_t frame_flags, - YV12_BUFFER_CONFIG *sd, int64_t time_stamp, - int64_t end_time); - -int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, - size_t *size, uint8_t *dest, size_t dest_size, - int64_t *time_stamp, int64_t *time_end, int flush, - ENCODE_FRAME_RESULT *encode_frame_result); - -int vp9_get_preview_raw_frame(VP9_COMP *cpi, YV12_BUFFER_CONFIG *dest, - vp9_ppflags_t *flags); - -int vp9_use_as_reference(VP9_COMP *cpi, int ref_frame_flags); - -void vp9_update_reference(VP9_COMP *cpi, int ref_frame_flags); - -int vp9_copy_reference_enc(VP9_COMP *cpi, VP9_REFFRAME ref_frame_flag, - YV12_BUFFER_CONFIG *sd); - -int vp9_set_reference_enc(VP9_COMP *cpi, VP9_REFFRAME ref_frame_flag, - YV12_BUFFER_CONFIG *sd); - -int vp9_update_entropy(VP9_COMP *cpi, int update); - -int vp9_set_active_map(VP9_COMP *cpi, unsigned char *new_map_16x16, int rows, - int cols); - -int vp9_get_active_map(VP9_COMP *cpi, unsigned char *new_map_16x16, int rows, - int cols); - -int vp9_set_internal_size(VP9_COMP *cpi, VPX_SCALING_MODE horiz_mode, - VPX_SCALING_MODE vert_mode); - -int vp9_set_size_literal(VP9_COMP *cpi, unsigned int width, - unsigned int height); - -void vp9_set_svc(VP9_COMP *cpi, int use_svc); - -// Check for resetting the rc flags (rc_1_frame, rc_2_frame) if the -// configuration change has a large change in avg_frame_bandwidth. -// For SVC check for resetting based on spatial layer average bandwidth. -// Also reset buffer level to optimal level. -void vp9_check_reset_rc_flag(VP9_COMP *cpi); - -void vp9_set_rc_buffer_sizes(VP9_COMP *cpi); - -static INLINE int stack_pop(int *stack, int stack_size) { - int idx; - const int r = stack[0]; - for (idx = 1; idx < stack_size; ++idx) stack[idx - 1] = stack[idx]; - - return r; -} - -static INLINE int stack_top(const int *stack) { return stack[0]; } - -static INLINE void stack_push(int *stack, int new_item, int stack_size) { - int idx; - for (idx = stack_size; idx > 0; --idx) stack[idx] = stack[idx - 1]; - stack[0] = new_item; -} - -static INLINE void stack_init(int *stack, int length) { - int idx; - for (idx = 0; idx < length; ++idx) stack[idx] = -1; -} - -int vp9_get_quantizer(const VP9_COMP *cpi); - -static INLINE int frame_is_kf_gf_arf(const VP9_COMP *cpi) { - return frame_is_intra_only(&cpi->common) || cpi->refresh_alt_ref_frame || - (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref); -} - -static INLINE int ref_frame_to_flag(int8_t ref_frame) { - static const int kVp9RefFlagList[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG, - VP9_ALT_FLAG }; - assert(ref_frame >= LAST_FRAME && ref_frame <= ALTREF_FRAME); - return kVp9RefFlagList[ref_frame]; -} - -static INLINE int get_ref_frame_map_idx(const VP9_COMP *cpi, - MV_REFERENCE_FRAME ref_frame) { - if (ref_frame == LAST_FRAME) { - return cpi->lst_fb_idx; - } else if (ref_frame == GOLDEN_FRAME) { - return cpi->gld_fb_idx; - } else { - return cpi->alt_fb_idx; - } -} - -static INLINE int get_ref_frame_buf_idx(const VP9_COMP *const cpi, - int ref_frame) { - const VP9_COMMON *const cm = &cpi->common; - const int map_idx = get_ref_frame_map_idx(cpi, ref_frame); - return (map_idx != INVALID_IDX) ? cm->ref_frame_map[map_idx] : INVALID_IDX; -} - -static INLINE RefCntBuffer *get_ref_cnt_buffer(const VP9_COMMON *cm, - int fb_idx) { - return fb_idx != INVALID_IDX ? &cm->buffer_pool->frame_bufs[fb_idx] : NULL; -} - -static INLINE void get_ref_frame_bufs( - const VP9_COMP *cpi, RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES]) { - const VP9_COMMON *const cm = &cpi->common; - MV_REFERENCE_FRAME ref_frame; - for (ref_frame = LAST_FRAME; ref_frame < MAX_REF_FRAMES; ++ref_frame) { - int ref_frame_buf_idx = get_ref_frame_buf_idx(cpi, ref_frame); - int inter_ref_idx = mv_ref_frame_to_inter_ref_idx(ref_frame); - ref_frame_bufs[inter_ref_idx] = get_ref_cnt_buffer(cm, ref_frame_buf_idx); - } -} - -static INLINE YV12_BUFFER_CONFIG *get_ref_frame_buffer( - const VP9_COMP *const cpi, MV_REFERENCE_FRAME ref_frame) { - const VP9_COMMON *const cm = &cpi->common; - const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame); - return buf_idx != INVALID_IDX ? &cm->buffer_pool->frame_bufs[buf_idx].buf - : NULL; -} - -static INLINE int get_token_alloc(int mb_rows, int mb_cols) { - // TODO(JBB): double check we can't exceed this token count if we have a - // 32x32 transform crossing a boundary at a multiple of 16. - // mb_rows, cols are in units of 16 pixels. We assume 3 planes all at full - // resolution. We assume up to 1 token per pixel, and then allow - // a head room of 4. - - // Use aligned mb_rows and mb_cols to better align with actual token sizes. - const int aligned_mb_rows = - ALIGN_POWER_OF_TWO(mb_rows, MI_BLOCK_SIZE_LOG2 - 1); - const int aligned_mb_cols = - ALIGN_POWER_OF_TWO(mb_cols, MI_BLOCK_SIZE_LOG2 - 1); - return aligned_mb_rows * aligned_mb_cols * (16 * 16 * 3 + 4); -} - -// Get the allocated token size for a tile. It does the same calculation as in -// the frame token allocation. -static INLINE int allocated_tokens(TileInfo tile) { - int tile_mb_rows = (tile.mi_row_end - tile.mi_row_start + 1) >> 1; - int tile_mb_cols = (tile.mi_col_end - tile.mi_col_start + 1) >> 1; - - return get_token_alloc(tile_mb_rows, tile_mb_cols); -} - -static INLINE void get_start_tok(VP9_COMP *cpi, int tile_row, int tile_col, - int mi_row, TOKENEXTRA **tok) { - VP9_COMMON *const cm = &cpi->common; - const int tile_cols = 1 << cm->log2_tile_cols; - TileDataEnc *this_tile = &cpi->tile_data[tile_row * tile_cols + tile_col]; - const TileInfo *const tile_info = &this_tile->tile_info; - - int tile_mb_cols = (tile_info->mi_col_end - tile_info->mi_col_start + 1) >> 1; - const int mb_row = (mi_row - tile_info->mi_row_start) >> 1; - - *tok = - cpi->tile_tok[tile_row][tile_col] + get_token_alloc(mb_row, tile_mb_cols); -} - -int64_t vp9_get_y_sse(const YV12_BUFFER_CONFIG *a, const YV12_BUFFER_CONFIG *b); -#if CONFIG_VP9_HIGHBITDEPTH -int64_t vp9_highbd_get_y_sse(const YV12_BUFFER_CONFIG *a, - const YV12_BUFFER_CONFIG *b); -#endif // CONFIG_VP9_HIGHBITDEPTH - -void vp9_scale_references(VP9_COMP *cpi); - -void vp9_update_reference_frames(VP9_COMP *cpi); - -void vp9_get_ref_frame_info(FRAME_UPDATE_TYPE update_type, int ref_frame_flags, - RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], - int *ref_frame_coding_indexes, - int *ref_frame_valid_list); - -void vp9_set_high_precision_mv(VP9_COMP *cpi, int allow_high_precision_mv); - -#if CONFIG_VP9_HIGHBITDEPTH -void vp9_scale_and_extend_frame_nonnormative(const YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst, int bd); -#else -void vp9_scale_and_extend_frame_nonnormative(const YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst); -#endif // CONFIG_VP9_HIGHBITDEPTH - -YV12_BUFFER_CONFIG *vp9_scale_if_required( - VP9_COMMON *cm, YV12_BUFFER_CONFIG *unscaled, YV12_BUFFER_CONFIG *scaled, - int use_normative_scaler, INTERP_FILTER filter_type, int phase_scaler); - -void vp9_apply_encoding_flags(VP9_COMP *cpi, vpx_enc_frame_flags_t flags); - -static INLINE int is_one_pass_svc(const struct VP9_COMP *const cpi) { - return (cpi->use_svc && cpi->oxcf.pass == 0); -} - -#if CONFIG_VP9_TEMPORAL_DENOISING -static INLINE int denoise_svc(const struct VP9_COMP *const cpi) { - return (!cpi->use_svc || (cpi->use_svc && cpi->svc.spatial_layer_id >= - cpi->svc.first_layer_denoise)); -} -#endif - -#define MIN_LOOKAHEAD_FOR_ARFS 4 -static INLINE int is_altref_enabled(const VP9_COMP *const cpi) { - return !(cpi->oxcf.mode == REALTIME && cpi->oxcf.rc_mode == VPX_CBR) && - cpi->oxcf.lag_in_frames >= MIN_LOOKAHEAD_FOR_ARFS && - cpi->oxcf.enable_auto_arf; -} - -static INLINE void set_ref_ptrs(const VP9_COMMON *const cm, MACROBLOCKD *xd, - MV_REFERENCE_FRAME ref0, - MV_REFERENCE_FRAME ref1) { - xd->block_refs[0] = - &cm->frame_refs[ref0 >= LAST_FRAME ? ref0 - LAST_FRAME : 0]; - xd->block_refs[1] = - &cm->frame_refs[ref1 >= LAST_FRAME ? ref1 - LAST_FRAME : 0]; -} - -static INLINE int get_chessboard_index(const int frame_index) { - return frame_index & 0x1; -} - -static INLINE int *cond_cost_list(const struct VP9_COMP *cpi, int *cost_list) { - return cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL; -} - -static INLINE int get_num_vert_units(TileInfo tile, int shift) { - int num_vert_units = - (tile.mi_row_end - tile.mi_row_start + (1 << shift) - 1) >> shift; - return num_vert_units; -} - -static INLINE int get_num_cols(TileInfo tile, int shift) { - int num_cols = - (tile.mi_col_end - tile.mi_col_start + (1 << shift) - 1) >> shift; - return num_cols; -} - -static INLINE int get_level_index(VP9_LEVEL level) { - int i; - for (i = 0; i < VP9_LEVELS; ++i) { - if (level == vp9_level_defs[i].level) return i; - } - return -1; -} - -// Return the log2 value of max column tiles corresponding to the level that -// the picture size fits into. -static INLINE int log_tile_cols_from_picsize_level(uint32_t width, - uint32_t height) { - int i; - const uint32_t pic_size = width * height; - const uint32_t pic_breadth = VPXMAX(width, height); - for (i = LEVEL_1; i < LEVEL_MAX; ++i) { - if (vp9_level_defs[i].max_luma_picture_size >= pic_size && - vp9_level_defs[i].max_luma_picture_breadth >= pic_breadth) { - return get_msb(vp9_level_defs[i].max_col_tiles); - } - } - return INT_MAX; -} - -VP9_LEVEL vp9_get_level(const Vp9LevelSpec *const level_spec); - -vpx_codec_err_t vp9_set_roi_map(VP9_COMP *cpi, unsigned char *map, - unsigned int rows, unsigned int cols, - int delta_q[8], int delta_lf[8], int skip[8], - int ref_frame[8]); - -void vp9_new_framerate(VP9_COMP *cpi, double framerate); - -void vp9_set_row_mt(VP9_COMP *cpi); - -int vp9_get_psnr(const VP9_COMP *cpi, PSNR_STATS *psnr); - -#define LAYER_IDS_TO_IDX(sl, tl, num_tl) ((sl) * (num_tl) + (tl)) - -static INLINE void alloc_frame_mvs(VP9_COMMON *const cm, int buffer_idx) { - RefCntBuffer *const new_fb_ptr = &cm->buffer_pool->frame_bufs[buffer_idx]; - if (new_fb_ptr->mvs == NULL || new_fb_ptr->mi_rows < cm->mi_rows || - new_fb_ptr->mi_cols < cm->mi_cols) { - vpx_free(new_fb_ptr->mvs); - CHECK_MEM_ERROR(&cm->error, new_fb_ptr->mvs, - (MV_REF *)vpx_calloc(cm->mi_rows * cm->mi_cols, - sizeof(*new_fb_ptr->mvs))); - new_fb_ptr->mi_rows = cm->mi_rows; - new_fb_ptr->mi_cols = cm->mi_cols; - } -} - -static INLINE int mv_cost(const MV *mv, const int *joint_cost, - int *const comp_cost[2]) { - assert(mv->row >= -MV_MAX && mv->row < MV_MAX); - assert(mv->col >= -MV_MAX && mv->col < MV_MAX); - return joint_cost[vp9_get_mv_joint(mv)] + comp_cost[0][mv->row] + - comp_cost[1][mv->col]; -} - -static INLINE int mvsad_err_cost(const MACROBLOCK *x, const MV *mv, - const MV *ref, int sad_per_bit) { - MV diff; - diff.row = mv->row - ref->row; - diff.col = mv->col - ref->col; - return ROUND_POWER_OF_TWO( - (unsigned)mv_cost(&diff, x->nmvjointsadcost, x->nmvsadcost) * sad_per_bit, - VP9_PROB_COST_SHIFT); -} - -static INLINE uint32_t get_start_mv_sad(const MACROBLOCK *x, const MV *mvp_full, - const MV *ref_mv_full, - vpx_sad_fn_t sad_fn_ptr, int sadpb) { - const int src_buf_stride = x->plane[0].src.stride; - const uint8_t *const src_buf = x->plane[0].src.buf; - const MACROBLOCKD *const xd = &x->e_mbd; - const int pred_buf_stride = xd->plane[0].pre[0].stride; - const uint8_t *const pred_buf = - xd->plane[0].pre[0].buf + mvp_full->row * pred_buf_stride + mvp_full->col; - uint32_t start_mv_sad = - sad_fn_ptr(src_buf, src_buf_stride, pred_buf, pred_buf_stride); - start_mv_sad += mvsad_err_cost(x, mvp_full, ref_mv_full, sadpb); - - return start_mv_sad; -} - -static INLINE int num_4x4_to_edge(int plane_4x4_dim, int mb_to_edge_dim, - int subsampling_dim, int blk_dim) { - return plane_4x4_dim + (mb_to_edge_dim >> (5 + subsampling_dim)) - blk_dim; -} - -// Compute the sum of squares on all visible 4x4s in the transform block. -static int64_t sum_squares_visible(const MACROBLOCKD *xd, - const struct macroblockd_plane *const pd, - const int16_t *diff, const int diff_stride, - int blk_row, int blk_col, - const BLOCK_SIZE plane_bsize, - const BLOCK_SIZE tx_bsize, - int *visible_width, int *visible_height) { - int64_t sse; - const int plane_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize]; - const int plane_4x4_h = num_4x4_blocks_high_lookup[plane_bsize]; - const int tx_4x4_w = num_4x4_blocks_wide_lookup[tx_bsize]; - const int tx_4x4_h = num_4x4_blocks_high_lookup[tx_bsize]; - const int b4x4s_to_right_edge = num_4x4_to_edge( - plane_4x4_w, xd->mb_to_right_edge, pd->subsampling_x, blk_col); - const int b4x4s_to_bottom_edge = num_4x4_to_edge( - plane_4x4_h, xd->mb_to_bottom_edge, pd->subsampling_y, blk_row); - if (tx_bsize == BLOCK_4X4 || - (b4x4s_to_right_edge >= tx_4x4_w && b4x4s_to_bottom_edge >= tx_4x4_h)) { - assert(tx_4x4_w == tx_4x4_h); - sse = (int64_t)vpx_sum_squares_2d_i16(diff, diff_stride, tx_4x4_w << 2); - *visible_width = tx_4x4_w << 2; - *visible_height = tx_4x4_h << 2; - } else { - int r, c; - const int max_r = VPXMIN(b4x4s_to_bottom_edge, tx_4x4_h); - const int max_c = VPXMIN(b4x4s_to_right_edge, tx_4x4_w); - sse = 0; - // if we are in the unrestricted motion border. - for (r = 0; r < max_r; ++r) { - // Skip visiting the sub blocks that are wholly within the UMV. - for (c = 0; c < max_c; ++c) { - sse += (int64_t)vpx_sum_squares_2d_i16( - diff + r * diff_stride * 4 + c * 4, diff_stride, 4); - } - } - *visible_width = max_c << 2; - *visible_height = max_r << 2; - } - return sse; -} - -// Check if trellis coefficient optimization of the transform block is enabled. -static INLINE int do_trellis_opt(const struct macroblockd_plane *pd, - const int16_t *src_diff, int diff_stride, - int blk_row, int blk_col, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size, - void *arg) { - const struct encode_b_args *const args = (struct encode_b_args *)arg; - const MACROBLOCK *const x = args->x; - - switch (args->enable_trellis_opt) { - case DISABLE_TRELLIS_OPT: return 0; - case ENABLE_TRELLIS_OPT: return 1; - case ENABLE_TRELLIS_OPT_TX_RD_SRC_VAR: { - vpx_clear_system_state(); - - return (args->trellis_opt_thresh > 0.0) - ? (x->log_block_src_var <= args->trellis_opt_thresh) - : 1; - } - case ENABLE_TRELLIS_OPT_TX_RD_RESIDUAL_MSE: { - const MACROBLOCKD *const xd = &x->e_mbd; - const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size]; -#if CONFIG_VP9_HIGHBITDEPTH - const int dequant_shift = - (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd - 5 : 3; -#else - const int dequant_shift = 3; -#endif // CONFIG_VP9_HIGHBITDEPTH - const int qstep = pd->dequant[1] >> dequant_shift; - int *sse_calc_done = args->sse_calc_done; - int64_t *sse = args->sse; - int visible_width = 0, visible_height = 0; - - // TODO: Enable the sf for high bit-depth case - if ((xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) || !sse || - !sse_calc_done) - return 1; - - *sse = sum_squares_visible(xd, pd, src_diff, diff_stride, blk_row, - blk_col, plane_bsize, tx_bsize, &visible_width, - &visible_height); - *sse_calc_done = 1; - - vpx_clear_system_state(); - - return (*(sse) <= (int64_t)visible_width * visible_height * qstep * - qstep * args->trellis_opt_thresh); - } - default: assert(0 && "Invalid trellis optimization method."); return 1; - } -} - -#if CONFIG_COLLECT_COMPONENT_TIMING -static INLINE void start_timing(VP9_COMP *cpi, int component) { - vpx_usec_timer_start(&cpi->component_timer[component]); -} -static INLINE void end_timing(VP9_COMP *cpi, int component) { - vpx_usec_timer_mark(&cpi->component_timer[component]); - cpi->frame_component_time[component] += - vpx_usec_timer_elapsed(&cpi->component_timer[component]); -} -static INLINE char const *get_frame_type_enum(int type) { - switch (type) { - case 0: return "KEY_FRAME"; - case 1: return "INTER_FRAME"; - default: assert(0); - } - return "error"; -} -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_ENCODER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ethread.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ethread.c deleted file mode 100644 index c3b79507..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ethread.c +++ /dev/null @@ -1,693 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp9/common/vp9_thread_common.h" -#include "vp9/encoder/vp9_bitstream.h" -#include "vp9/encoder/vp9_encodeframe.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_ethread.h" -#include "vp9/encoder/vp9_firstpass.h" -#include "vp9/encoder/vp9_multi_thread.h" -#include "vp9/encoder/vp9_temporal_filter.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_util/vpx_pthread.h" - -static void accumulate_rd_opt(ThreadData *td, ThreadData *td_t) { - int i, j, k, l, m, n; - - for (i = 0; i < REFERENCE_MODES; i++) - td->rd_counts.comp_pred_diff[i] += td_t->rd_counts.comp_pred_diff[i]; - - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) - td->rd_counts.filter_diff[i] += td_t->rd_counts.filter_diff[i]; - - for (i = 0; i < TX_SIZES; i++) - for (j = 0; j < PLANE_TYPES; j++) - for (k = 0; k < REF_TYPES; k++) - for (l = 0; l < COEF_BANDS; l++) - for (m = 0; m < COEFF_CONTEXTS; m++) - for (n = 0; n < ENTROPY_TOKENS; n++) - td->rd_counts.coef_counts[i][j][k][l][m][n] += - td_t->rd_counts.coef_counts[i][j][k][l][m][n]; -} - -static int enc_worker_hook(void *arg1, void *unused) { - EncWorkerData *const thread_data = (EncWorkerData *)arg1; - VP9_COMP *const cpi = thread_data->cpi; - const VP9_COMMON *const cm = &cpi->common; - const int tile_cols = 1 << cm->log2_tile_cols; - const int tile_rows = 1 << cm->log2_tile_rows; - int t; - - (void)unused; - - for (t = thread_data->start; t < tile_rows * tile_cols; - t += cpi->num_workers) { - int tile_row = t / tile_cols; - int tile_col = t % tile_cols; - - vp9_encode_tile(cpi, thread_data->td, tile_row, tile_col); - } - - return 1; -} - -static int get_max_tile_cols(VP9_COMP *cpi) { - const int aligned_width = ALIGN_POWER_OF_TWO(cpi->oxcf.width, MI_SIZE_LOG2); - int mi_cols = aligned_width >> MI_SIZE_LOG2; - int min_log2_tile_cols, max_log2_tile_cols; - int log2_tile_cols; - - vp9_get_tile_n_bits(mi_cols, &min_log2_tile_cols, &max_log2_tile_cols); - log2_tile_cols = - clamp(cpi->oxcf.tile_columns, min_log2_tile_cols, max_log2_tile_cols); - if (cpi->oxcf.target_level == LEVEL_AUTO) { - const int level_tile_cols = - log_tile_cols_from_picsize_level(cpi->common.width, cpi->common.height); - if (log2_tile_cols > level_tile_cols) { - log2_tile_cols = VPXMAX(level_tile_cols, min_log2_tile_cols); - } - } - return (1 << log2_tile_cols); -} - -static void create_enc_workers(VP9_COMP *cpi, int num_workers) { - VP9_COMMON *const cm = &cpi->common; - const VPxWorkerInterface *const winterface = vpx_get_worker_interface(); - int i; - // While using SVC, we need to allocate threads according to the highest - // resolution. When row based multithreading is enabled, it is OK to - // allocate more threads than the number of max tile columns. - if (cpi->use_svc && !cpi->row_mt) { - int max_tile_cols = get_max_tile_cols(cpi); - num_workers = VPXMIN(cpi->oxcf.max_threads, max_tile_cols); - } - assert(num_workers > 0); - if (num_workers == cpi->num_workers) return; - vp9_loop_filter_dealloc(&cpi->lf_row_sync); - vp9_bitstream_encode_tiles_buffer_dealloc(cpi); - vp9_encode_free_mt_data(cpi); - - CHECK_MEM_ERROR(&cm->error, cpi->workers, - vpx_malloc(num_workers * sizeof(*cpi->workers))); - - CHECK_MEM_ERROR(&cm->error, cpi->tile_thr_data, - vpx_calloc(num_workers, sizeof(*cpi->tile_thr_data))); - - for (i = 0; i < num_workers; i++) { - VPxWorker *const worker = &cpi->workers[i]; - EncWorkerData *thread_data = &cpi->tile_thr_data[i]; - - ++cpi->num_workers; - winterface->init(worker); - worker->thread_name = "vpx enc worker"; - - if (i < num_workers - 1) { - thread_data->cpi = cpi; - - // Allocate thread data. - CHECK_MEM_ERROR(&cm->error, thread_data->td, - vpx_memalign(32, sizeof(*thread_data->td))); - vp9_zero(*thread_data->td); - - // Set up pc_tree. - thread_data->td->leaf_tree = NULL; - thread_data->td->pc_tree = NULL; - vp9_setup_pc_tree(cm, thread_data->td); - - // Allocate frame counters in thread data. - CHECK_MEM_ERROR(&cm->error, thread_data->td->counts, - vpx_calloc(1, sizeof(*thread_data->td->counts))); - - // Create threads - if (!winterface->reset(worker)) - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "Tile encoder thread creation failed"); - } else { - // Main thread acts as a worker and uses the thread data in cpi. - thread_data->cpi = cpi; - thread_data->td = &cpi->td; - } - winterface->sync(worker); - } -} - -static void launch_enc_workers(VP9_COMP *cpi, VPxWorkerHook hook, void *data2, - int num_workers) { - const VPxWorkerInterface *const winterface = vpx_get_worker_interface(); - int i; - - for (i = 0; i < num_workers; i++) { - VPxWorker *const worker = &cpi->workers[i]; - worker->hook = hook; - worker->data1 = &cpi->tile_thr_data[i]; - worker->data2 = data2; - } - - // Encode a frame - for (i = 0; i < num_workers; i++) { - VPxWorker *const worker = &cpi->workers[i]; - EncWorkerData *const thread_data = (EncWorkerData *)worker->data1; - - // Set the starting tile for each thread. - thread_data->start = i; - - if (i == cpi->num_workers - 1) - winterface->execute(worker); - else - winterface->launch(worker); - } - - // Encoding ends. - for (i = 0; i < num_workers; i++) { - VPxWorker *const worker = &cpi->workers[i]; - winterface->sync(worker); - } -} - -void vp9_encode_free_mt_data(struct VP9_COMP *cpi) { - int t; - for (t = 0; t < cpi->num_workers; ++t) { - VPxWorker *const worker = &cpi->workers[t]; - EncWorkerData *const thread_data = &cpi->tile_thr_data[t]; - - // Deallocate allocated threads. - vpx_get_worker_interface()->end(worker); - - // Deallocate allocated thread data. - if (t < cpi->num_workers - 1) { - vpx_free(thread_data->td->counts); - vp9_free_pc_tree(thread_data->td); - vpx_free(thread_data->td); - } - } - vpx_free(cpi->tile_thr_data); - cpi->tile_thr_data = NULL; - vpx_free(cpi->workers); - cpi->workers = NULL; - cpi->num_workers = 0; -} - -void vp9_encode_tiles_mt(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - const int tile_cols = 1 << cm->log2_tile_cols; - const int num_workers = VPXMIN(cpi->oxcf.max_threads, tile_cols); - int i; - - vp9_init_tile_data(cpi); - - create_enc_workers(cpi, num_workers); - - for (i = 0; i < num_workers; i++) { - EncWorkerData *const thread_data = &cpi->tile_thr_data[i]; - - // Before encoding a frame, copy the thread data from cpi. - if (thread_data->td != &cpi->td) { - thread_data->td->mb = cpi->td.mb; - thread_data->td->rd_counts = cpi->td.rd_counts; - } - if (thread_data->td->counts != &cpi->common.counts) { - memcpy(thread_data->td->counts, &cpi->common.counts, - sizeof(cpi->common.counts)); - } - - // Handle use_nonrd_pick_mode case. - if (cpi->sf.use_nonrd_pick_mode) { - MACROBLOCK *const x = &thread_data->td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - struct macroblock_plane *const p = x->plane; - struct macroblockd_plane *const pd = xd->plane; - PICK_MODE_CONTEXT *ctx = &thread_data->td->pc_root->none; - int j; - - for (j = 0; j < MAX_MB_PLANE; ++j) { - p[j].coeff = ctx->coeff_pbuf[j][0]; - p[j].qcoeff = ctx->qcoeff_pbuf[j][0]; - pd[j].dqcoeff = ctx->dqcoeff_pbuf[j][0]; - p[j].eobs = ctx->eobs_pbuf[j][0]; - } - } - } - - launch_enc_workers(cpi, enc_worker_hook, NULL, num_workers); - - for (i = 0; i < num_workers; i++) { - VPxWorker *const worker = &cpi->workers[i]; - EncWorkerData *const thread_data = (EncWorkerData *)worker->data1; - - // Accumulate counters. - if (i < cpi->num_workers - 1) { - vp9_accumulate_frame_counts(&cm->counts, thread_data->td->counts, 0); - accumulate_rd_opt(&cpi->td, thread_data->td); - } - } -} - -#if !CONFIG_REALTIME_ONLY -static void accumulate_fp_tile_stat(TileDataEnc *tile_data, - TileDataEnc *tile_data_t) { - tile_data->fp_data.intra_factor += tile_data_t->fp_data.intra_factor; - tile_data->fp_data.brightness_factor += - tile_data_t->fp_data.brightness_factor; - tile_data->fp_data.coded_error += tile_data_t->fp_data.coded_error; - tile_data->fp_data.sr_coded_error += tile_data_t->fp_data.sr_coded_error; - tile_data->fp_data.frame_noise_energy += - tile_data_t->fp_data.frame_noise_energy; - tile_data->fp_data.intra_error += tile_data_t->fp_data.intra_error; - tile_data->fp_data.intercount += tile_data_t->fp_data.intercount; - tile_data->fp_data.second_ref_count += tile_data_t->fp_data.second_ref_count; - tile_data->fp_data.neutral_count += tile_data_t->fp_data.neutral_count; - tile_data->fp_data.intra_count_low += tile_data_t->fp_data.intra_count_low; - tile_data->fp_data.intra_count_high += tile_data_t->fp_data.intra_count_high; - tile_data->fp_data.intra_skip_count += tile_data_t->fp_data.intra_skip_count; - tile_data->fp_data.mvcount += tile_data_t->fp_data.mvcount; - tile_data->fp_data.new_mv_count += tile_data_t->fp_data.new_mv_count; - tile_data->fp_data.sum_mvr += tile_data_t->fp_data.sum_mvr; - tile_data->fp_data.sum_mvr_abs += tile_data_t->fp_data.sum_mvr_abs; - tile_data->fp_data.sum_mvc += tile_data_t->fp_data.sum_mvc; - tile_data->fp_data.sum_mvc_abs += tile_data_t->fp_data.sum_mvc_abs; - tile_data->fp_data.sum_mvrs += tile_data_t->fp_data.sum_mvrs; - tile_data->fp_data.sum_mvcs += tile_data_t->fp_data.sum_mvcs; - tile_data->fp_data.sum_in_vectors += tile_data_t->fp_data.sum_in_vectors; - tile_data->fp_data.intra_smooth_count += - tile_data_t->fp_data.intra_smooth_count; - tile_data->fp_data.image_data_start_row = - VPXMIN(tile_data->fp_data.image_data_start_row, - tile_data_t->fp_data.image_data_start_row) == INVALID_ROW - ? VPXMAX(tile_data->fp_data.image_data_start_row, - tile_data_t->fp_data.image_data_start_row) - : VPXMIN(tile_data->fp_data.image_data_start_row, - tile_data_t->fp_data.image_data_start_row); -} -#endif // !CONFIG_REALTIME_ONLY - -// Allocate memory for row synchronization -void vp9_row_mt_sync_mem_alloc(VP9RowMTSync *row_mt_sync, VP9_COMMON *cm, - int rows) { - row_mt_sync->rows = rows; -#if CONFIG_MULTITHREAD - { - int i; - - CHECK_MEM_ERROR(&cm->error, row_mt_sync->mutex, - vpx_malloc(sizeof(*row_mt_sync->mutex) * rows)); - if (row_mt_sync->mutex) { - for (i = 0; i < rows; ++i) { - pthread_mutex_init(&row_mt_sync->mutex[i], NULL); - } - } - - CHECK_MEM_ERROR(&cm->error, row_mt_sync->cond, - vpx_malloc(sizeof(*row_mt_sync->cond) * rows)); - if (row_mt_sync->cond) { - for (i = 0; i < rows; ++i) { - pthread_cond_init(&row_mt_sync->cond[i], NULL); - } - } - } -#endif // CONFIG_MULTITHREAD - - CHECK_MEM_ERROR(&cm->error, row_mt_sync->cur_col, - vpx_malloc(sizeof(*row_mt_sync->cur_col) * rows)); - - // Set up nsync. - row_mt_sync->sync_range = 1; -} - -// Deallocate row based multi-threading synchronization related mutex and data -void vp9_row_mt_sync_mem_dealloc(VP9RowMTSync *row_mt_sync) { - if (row_mt_sync != NULL) { -#if CONFIG_MULTITHREAD - int i; - - if (row_mt_sync->mutex != NULL) { - for (i = 0; i < row_mt_sync->rows; ++i) { - pthread_mutex_destroy(&row_mt_sync->mutex[i]); - } - vpx_free(row_mt_sync->mutex); - } - if (row_mt_sync->cond != NULL) { - for (i = 0; i < row_mt_sync->rows; ++i) { - pthread_cond_destroy(&row_mt_sync->cond[i]); - } - vpx_free(row_mt_sync->cond); - } -#endif // CONFIG_MULTITHREAD - vpx_free(row_mt_sync->cur_col); - // clear the structure as the source of this call may be dynamic change - // in tiles in which case this call will be followed by an _alloc() - // which may fail. - vp9_zero(*row_mt_sync); - } -} - -void vp9_row_mt_sync_read(VP9RowMTSync *const row_mt_sync, int r, int c) { -#if CONFIG_MULTITHREAD - const int nsync = row_mt_sync->sync_range; - - if (r && !(c & (nsync - 1))) { - pthread_mutex_t *const mutex = &row_mt_sync->mutex[r - 1]; - pthread_mutex_lock(mutex); - - while (c > row_mt_sync->cur_col[r - 1] - nsync + 1) { - pthread_cond_wait(&row_mt_sync->cond[r - 1], mutex); - } - pthread_mutex_unlock(mutex); - } -#else - (void)row_mt_sync; - (void)r; - (void)c; -#endif // CONFIG_MULTITHREAD -} - -void vp9_row_mt_sync_read_dummy(VP9RowMTSync *const row_mt_sync, int r, int c) { - (void)row_mt_sync; - (void)r; - (void)c; - return; -} - -void vp9_row_mt_sync_write(VP9RowMTSync *const row_mt_sync, int r, int c, - const int cols) { -#if CONFIG_MULTITHREAD - const int nsync = row_mt_sync->sync_range; - int cur; - // Only signal when there are enough encoded blocks for next row to run. - int sig = 1; - - if (c < cols - 1) { - cur = c; - if (c % nsync != nsync - 1) sig = 0; - } else { - cur = cols + nsync; - } - - if (sig) { - pthread_mutex_lock(&row_mt_sync->mutex[r]); - - row_mt_sync->cur_col[r] = cur; - - pthread_cond_signal(&row_mt_sync->cond[r]); - pthread_mutex_unlock(&row_mt_sync->mutex[r]); - } -#else - (void)row_mt_sync; - (void)r; - (void)c; - (void)cols; -#endif // CONFIG_MULTITHREAD -} - -void vp9_row_mt_sync_write_dummy(VP9RowMTSync *const row_mt_sync, int r, int c, - const int cols) { - (void)row_mt_sync; - (void)r; - (void)c; - (void)cols; - return; -} - -#if !CONFIG_REALTIME_ONLY -static int first_pass_worker_hook(void *arg1, void *arg2) { - EncWorkerData *const thread_data = (EncWorkerData *)arg1; - MultiThreadHandle *multi_thread_ctxt = (MultiThreadHandle *)arg2; - VP9_COMP *const cpi = thread_data->cpi; - const VP9_COMMON *const cm = &cpi->common; - const int tile_cols = 1 << cm->log2_tile_cols; - int tile_row, tile_col; - TileDataEnc *this_tile; - int end_of_frame; - int thread_id = thread_data->thread_id; - int cur_tile_id = multi_thread_ctxt->thread_id_to_tile_id[thread_id]; - JobNode *proc_job = NULL; - FIRSTPASS_DATA fp_acc_data; - MV zero_mv = { 0, 0 }; - MV best_ref_mv; - int mb_row; - - end_of_frame = 0; - while (0 == end_of_frame) { - // Get the next job in the queue - proc_job = - (JobNode *)vp9_enc_grp_get_next_job(multi_thread_ctxt, cur_tile_id); - if (NULL == proc_job) { - // Query for the status of other tiles - end_of_frame = vp9_get_tiles_proc_status( - multi_thread_ctxt, thread_data->tile_completion_status, &cur_tile_id, - tile_cols); - } else { - tile_col = proc_job->tile_col_id; - tile_row = proc_job->tile_row_id; - - this_tile = &cpi->tile_data[tile_row * tile_cols + tile_col]; - mb_row = proc_job->vert_unit_row_num; - - best_ref_mv = zero_mv; - vp9_zero(fp_acc_data); - fp_acc_data.image_data_start_row = INVALID_ROW; - vp9_first_pass_encode_tile_mb_row(cpi, thread_data->td, &fp_acc_data, - this_tile, &best_ref_mv, mb_row); - } - } - return 1; -} - -void vp9_encode_fp_row_mt(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - const int tile_cols = 1 << cm->log2_tile_cols; - const int tile_rows = 1 << cm->log2_tile_rows; - MultiThreadHandle *multi_thread_ctxt = &cpi->multi_thread_ctxt; - TileDataEnc *first_tile_col; - int num_workers = VPXMAX(cpi->oxcf.max_threads, 1); - int i; - - if (multi_thread_ctxt->allocated_tile_cols < tile_cols || - multi_thread_ctxt->allocated_tile_rows < tile_rows || - multi_thread_ctxt->allocated_vert_unit_rows < cm->mb_rows) { - vp9_row_mt_mem_dealloc(cpi); - vp9_init_tile_data(cpi); - vp9_row_mt_mem_alloc(cpi); - } else { - vp9_init_tile_data(cpi); - } - - create_enc_workers(cpi, num_workers); - - vp9_assign_tile_to_thread(multi_thread_ctxt, tile_cols, cpi->num_workers); - - vp9_prepare_job_queue(cpi, FIRST_PASS_JOB); - - vp9_multi_thread_tile_init(cpi); - - for (i = 0; i < num_workers; i++) { - EncWorkerData *thread_data; - thread_data = &cpi->tile_thr_data[i]; - - // Before encoding a frame, copy the thread data from cpi. - if (thread_data->td != &cpi->td) { - thread_data->td->mb = cpi->td.mb; - } - } - - launch_enc_workers(cpi, first_pass_worker_hook, multi_thread_ctxt, - num_workers); - - first_tile_col = &cpi->tile_data[0]; - for (i = 1; i < tile_cols; i++) { - TileDataEnc *this_tile = &cpi->tile_data[i]; - accumulate_fp_tile_stat(first_tile_col, this_tile); - } -} - -static int temporal_filter_worker_hook(void *arg1, void *arg2) { - EncWorkerData *const thread_data = (EncWorkerData *)arg1; - MultiThreadHandle *multi_thread_ctxt = (MultiThreadHandle *)arg2; - VP9_COMP *const cpi = thread_data->cpi; - const VP9_COMMON *const cm = &cpi->common; - const int tile_cols = 1 << cm->log2_tile_cols; - int tile_row, tile_col; - int mb_col_start, mb_col_end; - TileDataEnc *this_tile; - int end_of_frame; - int thread_id = thread_data->thread_id; - int cur_tile_id = multi_thread_ctxt->thread_id_to_tile_id[thread_id]; - JobNode *proc_job = NULL; - int mb_row; - - end_of_frame = 0; - while (0 == end_of_frame) { - // Get the next job in the queue - proc_job = - (JobNode *)vp9_enc_grp_get_next_job(multi_thread_ctxt, cur_tile_id); - if (NULL == proc_job) { - // Query for the status of other tiles - end_of_frame = vp9_get_tiles_proc_status( - multi_thread_ctxt, thread_data->tile_completion_status, &cur_tile_id, - tile_cols); - } else { - tile_col = proc_job->tile_col_id; - tile_row = proc_job->tile_row_id; - this_tile = &cpi->tile_data[tile_row * tile_cols + tile_col]; - mb_col_start = (this_tile->tile_info.mi_col_start) >> TF_SHIFT; - mb_col_end = (this_tile->tile_info.mi_col_end + TF_ROUND) >> TF_SHIFT; - mb_row = proc_job->vert_unit_row_num; - - vp9_temporal_filter_iterate_row_c(cpi, thread_data->td, mb_row, - mb_col_start, mb_col_end); - } - } - return 1; -} - -void vp9_temporal_filter_row_mt(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - const int tile_cols = 1 << cm->log2_tile_cols; - const int tile_rows = 1 << cm->log2_tile_rows; - MultiThreadHandle *multi_thread_ctxt = &cpi->multi_thread_ctxt; - int num_workers = cpi->num_workers ? cpi->num_workers : 1; - int i; - - if (multi_thread_ctxt->allocated_tile_cols < tile_cols || - multi_thread_ctxt->allocated_tile_rows < tile_rows || - multi_thread_ctxt->allocated_vert_unit_rows < cm->mb_rows) { - vp9_row_mt_mem_dealloc(cpi); - vp9_init_tile_data(cpi); - vp9_row_mt_mem_alloc(cpi); - } else { - vp9_init_tile_data(cpi); - } - - create_enc_workers(cpi, num_workers); - - vp9_assign_tile_to_thread(multi_thread_ctxt, tile_cols, cpi->num_workers); - - vp9_prepare_job_queue(cpi, ARNR_JOB); - - for (i = 0; i < num_workers; i++) { - EncWorkerData *thread_data; - thread_data = &cpi->tile_thr_data[i]; - - // Before encoding a frame, copy the thread data from cpi. - if (thread_data->td != &cpi->td) { - thread_data->td->mb = cpi->td.mb; - } - } - - launch_enc_workers(cpi, temporal_filter_worker_hook, multi_thread_ctxt, - num_workers); -} -#endif // !CONFIG_REALTIME_ONLY - -static int enc_row_mt_worker_hook(void *arg1, void *arg2) { - EncWorkerData *const thread_data = (EncWorkerData *)arg1; - MultiThreadHandle *multi_thread_ctxt = (MultiThreadHandle *)arg2; - VP9_COMP *const cpi = thread_data->cpi; - const VP9_COMMON *const cm = &cpi->common; - const int tile_cols = 1 << cm->log2_tile_cols; - int tile_row, tile_col; - int end_of_frame; - int thread_id = thread_data->thread_id; - int cur_tile_id = multi_thread_ctxt->thread_id_to_tile_id[thread_id]; - JobNode *proc_job = NULL; - int mi_row; - - end_of_frame = 0; - while (0 == end_of_frame) { - // Get the next job in the queue - proc_job = - (JobNode *)vp9_enc_grp_get_next_job(multi_thread_ctxt, cur_tile_id); - if (NULL == proc_job) { - // Query for the status of other tiles - end_of_frame = vp9_get_tiles_proc_status( - multi_thread_ctxt, thread_data->tile_completion_status, &cur_tile_id, - tile_cols); - } else { - tile_col = proc_job->tile_col_id; - tile_row = proc_job->tile_row_id; - mi_row = proc_job->vert_unit_row_num * MI_BLOCK_SIZE; - - vp9_encode_sb_row(cpi, thread_data->td, tile_row, tile_col, mi_row); - } - } - return 1; -} - -void vp9_encode_tiles_row_mt(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - const int tile_cols = 1 << cm->log2_tile_cols; - const int tile_rows = 1 << cm->log2_tile_rows; - MultiThreadHandle *multi_thread_ctxt = &cpi->multi_thread_ctxt; - int num_workers = VPXMAX(cpi->oxcf.max_threads, 1); - int i; - - if (multi_thread_ctxt->allocated_tile_cols < tile_cols || - multi_thread_ctxt->allocated_tile_rows < tile_rows || - multi_thread_ctxt->allocated_vert_unit_rows < cm->mb_rows) { - vp9_row_mt_mem_dealloc(cpi); - vp9_init_tile_data(cpi); - vp9_row_mt_mem_alloc(cpi); - } else { - vp9_init_tile_data(cpi); - } - - create_enc_workers(cpi, num_workers); - - vp9_assign_tile_to_thread(multi_thread_ctxt, tile_cols, cpi->num_workers); - - vp9_prepare_job_queue(cpi, ENCODE_JOB); - - vp9_multi_thread_tile_init(cpi); - - for (i = 0; i < num_workers; i++) { - EncWorkerData *thread_data; - thread_data = &cpi->tile_thr_data[i]; - // Before encoding a frame, copy the thread data from cpi. - if (thread_data->td != &cpi->td) { - thread_data->td->mb = cpi->td.mb; - thread_data->td->rd_counts = cpi->td.rd_counts; - } - if (thread_data->td->counts != &cpi->common.counts) { - memcpy(thread_data->td->counts, &cpi->common.counts, - sizeof(cpi->common.counts)); - } - - // Handle use_nonrd_pick_mode case. - if (cpi->sf.use_nonrd_pick_mode) { - MACROBLOCK *const x = &thread_data->td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - struct macroblock_plane *const p = x->plane; - struct macroblockd_plane *const pd = xd->plane; - PICK_MODE_CONTEXT *ctx = &thread_data->td->pc_root->none; - int j; - - for (j = 0; j < MAX_MB_PLANE; ++j) { - p[j].coeff = ctx->coeff_pbuf[j][0]; - p[j].qcoeff = ctx->qcoeff_pbuf[j][0]; - pd[j].dqcoeff = ctx->dqcoeff_pbuf[j][0]; - p[j].eobs = ctx->eobs_pbuf[j][0]; - } - } - } - - launch_enc_workers(cpi, enc_row_mt_worker_hook, multi_thread_ctxt, - num_workers); - - for (i = 0; i < num_workers; i++) { - VPxWorker *const worker = &cpi->workers[i]; - EncWorkerData *const thread_data = (EncWorkerData *)worker->data1; - - // Accumulate counters. - if (i < cpi->num_workers - 1) { - vp9_accumulate_frame_counts(&cm->counts, thread_data->td->counts, 0); - accumulate_rd_opt(&cpi->td, thread_data->td); - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ethread.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ethread.h deleted file mode 100644 index 46478bef..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ethread.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_ETHREAD_H_ -#define VPX_VP9_ENCODER_VP9_ETHREAD_H_ - -#include "vpx_util/vpx_pthread.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_NUM_TILE_COLS (1 << 6) -#define MAX_NUM_TILE_ROWS 4 -#define MAX_NUM_THREADS 64 - -struct VP9_COMP; -struct ThreadData; - -typedef struct EncWorkerData { - struct VP9_COMP *cpi; - struct ThreadData *td; - int start; - int thread_id; - int tile_completion_status[MAX_NUM_TILE_COLS]; -} EncWorkerData; - -// Encoder row synchronization -typedef struct VP9RowMTSyncData { -#if CONFIG_MULTITHREAD - pthread_mutex_t *mutex; - pthread_cond_t *cond; -#endif - // Allocate memory to store the sb/mb block index in each row. - int *cur_col; - int sync_range; - int rows; -} VP9RowMTSync; - -// Frees EncWorkerData related allocations made by vp9_encode_*_mt(). -// row_mt specific data is freed with vp9_row_mt_mem_dealloc() and is not -// called by this function. -void vp9_encode_free_mt_data(struct VP9_COMP *cpi); - -void vp9_encode_tiles_mt(struct VP9_COMP *cpi); - -void vp9_encode_tiles_row_mt(struct VP9_COMP *cpi); - -void vp9_encode_fp_row_mt(struct VP9_COMP *cpi); - -void vp9_row_mt_sync_read(VP9RowMTSync *const row_mt_sync, int r, int c); -void vp9_row_mt_sync_write(VP9RowMTSync *const row_mt_sync, int r, int c, - const int cols); - -void vp9_row_mt_sync_read_dummy(VP9RowMTSync *const row_mt_sync, int r, int c); -void vp9_row_mt_sync_write_dummy(VP9RowMTSync *const row_mt_sync, int r, int c, - const int cols); - -// Allocate memory for row based multi-threading synchronization. -void vp9_row_mt_sync_mem_alloc(VP9RowMTSync *row_mt_sync, struct VP9Common *cm, - int rows); - -// Deallocate row based multi-threading synchronization related mutex and data. -void vp9_row_mt_sync_mem_dealloc(VP9RowMTSync *row_mt_sync); - -void vp9_temporal_filter_row_mt(struct VP9_COMP *cpi); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_ETHREAD_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ext_ratectrl.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ext_ratectrl.c deleted file mode 100644 index e8cc006b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ext_ratectrl.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (c) 2020 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "vp9/encoder/vp9_ext_ratectrl.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/common/vp9_common.h" -#include "vpx_dsp/psnr.h" -#include "vpx/vpx_codec.h" -#include "vpx/vpx_ext_ratectrl.h" -#include "vpx/vpx_tpl.h" - -vpx_codec_err_t vp9_extrc_init(EXT_RATECTRL *ext_ratectrl) { - if (ext_ratectrl == NULL) { - return VPX_CODEC_INVALID_PARAM; - } - vp9_zero(*ext_ratectrl); - return VPX_CODEC_OK; -} - -vpx_codec_err_t vp9_extrc_create(vpx_rc_funcs_t funcs, - vpx_rc_config_t ratectrl_config, - EXT_RATECTRL *ext_ratectrl) { - vpx_rc_status_t rc_status; - vpx_rc_firstpass_stats_t *rc_firstpass_stats; - if (ext_ratectrl == NULL) { - return VPX_CODEC_INVALID_PARAM; - } - vp9_extrc_delete(ext_ratectrl); - ext_ratectrl->funcs = funcs; - ext_ratectrl->ratectrl_config = ratectrl_config; - rc_status = ext_ratectrl->funcs.create_model(ext_ratectrl->funcs.priv, - &ext_ratectrl->ratectrl_config, - &ext_ratectrl->model); - if (rc_status == VPX_RC_ERROR) { - return VPX_CODEC_ERROR; - } - rc_firstpass_stats = &ext_ratectrl->rc_firstpass_stats; - rc_firstpass_stats->num_frames = ratectrl_config.show_frame_count; - rc_firstpass_stats->frame_stats = - vpx_malloc(sizeof(*rc_firstpass_stats->frame_stats) * - rc_firstpass_stats->num_frames); - if (rc_firstpass_stats->frame_stats == NULL) { - return VPX_CODEC_MEM_ERROR; - } - if (funcs.rate_ctrl_log_path != NULL) { - ext_ratectrl->log_file = fopen(funcs.rate_ctrl_log_path, "w"); - if (!ext_ratectrl->log_file) { - return VPX_CODEC_ERROR; - } - } else { - ext_ratectrl->log_file = NULL; - } - ext_ratectrl->ready = 1; - return VPX_CODEC_OK; -} - -vpx_codec_err_t vp9_extrc_delete(EXT_RATECTRL *ext_ratectrl) { - if (ext_ratectrl == NULL) { - return VPX_CODEC_INVALID_PARAM; - } - if (ext_ratectrl->ready) { - if (ext_ratectrl->log_file) { - fclose(ext_ratectrl->log_file); - } - vpx_rc_status_t rc_status = - ext_ratectrl->funcs.delete_model(ext_ratectrl->model); - if (rc_status == VPX_RC_ERROR) { - return VPX_CODEC_ERROR; - } - vpx_free(ext_ratectrl->rc_firstpass_stats.frame_stats); - } - return vp9_extrc_init(ext_ratectrl); -} - -static void gen_rc_firstpass_stats(const FIRSTPASS_STATS *stats, - vpx_rc_frame_stats_t *rc_frame_stats) { - rc_frame_stats->frame = stats->frame; - rc_frame_stats->weight = stats->weight; - rc_frame_stats->intra_error = stats->intra_error; - rc_frame_stats->coded_error = stats->coded_error; - rc_frame_stats->sr_coded_error = stats->sr_coded_error; - rc_frame_stats->frame_noise_energy = stats->frame_noise_energy; - rc_frame_stats->pcnt_inter = stats->pcnt_inter; - rc_frame_stats->pcnt_motion = stats->pcnt_motion; - rc_frame_stats->pcnt_second_ref = stats->pcnt_second_ref; - rc_frame_stats->pcnt_neutral = stats->pcnt_neutral; - rc_frame_stats->pcnt_intra_low = stats->pcnt_intra_low; - rc_frame_stats->pcnt_intra_high = stats->pcnt_intra_high; - rc_frame_stats->intra_skip_pct = stats->intra_skip_pct; - rc_frame_stats->intra_smooth_pct = stats->intra_smooth_pct; - rc_frame_stats->inactive_zone_rows = stats->inactive_zone_rows; - rc_frame_stats->inactive_zone_cols = stats->inactive_zone_cols; - rc_frame_stats->MVr = stats->MVr; - rc_frame_stats->mvr_abs = stats->mvr_abs; - rc_frame_stats->MVc = stats->MVc; - rc_frame_stats->mvc_abs = stats->mvc_abs; - rc_frame_stats->MVrv = stats->MVrv; - rc_frame_stats->MVcv = stats->MVcv; - rc_frame_stats->mv_in_out_count = stats->mv_in_out_count; - rc_frame_stats->duration = stats->duration; - rc_frame_stats->count = stats->count; - rc_frame_stats->new_mv_count = stats->new_mv_count; -} - -vpx_codec_err_t vp9_extrc_send_firstpass_stats( - EXT_RATECTRL *ext_ratectrl, const FIRST_PASS_INFO *first_pass_info) { - if (ext_ratectrl == NULL) { - return VPX_CODEC_INVALID_PARAM; - } - if (ext_ratectrl->ready) { - vpx_rc_status_t rc_status; - vpx_rc_firstpass_stats_t *rc_firstpass_stats = - &ext_ratectrl->rc_firstpass_stats; - int i; - assert(rc_firstpass_stats->num_frames == first_pass_info->num_frames); - for (i = 0; i < rc_firstpass_stats->num_frames; ++i) { - gen_rc_firstpass_stats(&first_pass_info->stats[i], - &rc_firstpass_stats->frame_stats[i]); - } - rc_status = ext_ratectrl->funcs.send_firstpass_stats(ext_ratectrl->model, - rc_firstpass_stats); - if (rc_status == VPX_RC_ERROR) { - return VPX_CODEC_ERROR; - } - } - return VPX_CODEC_OK; -} - -vpx_codec_err_t vp9_extrc_send_tpl_stats(EXT_RATECTRL *ext_ratectrl, - const VpxTplGopStats *tpl_gop_stats) { - if (ext_ratectrl == NULL) { - return VPX_CODEC_INVALID_PARAM; - } - if (ext_ratectrl->ready && ext_ratectrl->funcs.send_tpl_gop_stats != NULL) { - vpx_rc_status_t rc_status = ext_ratectrl->funcs.send_tpl_gop_stats( - ext_ratectrl->model, tpl_gop_stats); - if (rc_status == VPX_RC_ERROR) { - return VPX_CODEC_ERROR; - } - } - return VPX_CODEC_OK; -} - -static int extrc_get_frame_type(FRAME_UPDATE_TYPE update_type) { - // TODO(angiebird): Add unit test to make sure this function behaves like - // get_frame_type_from_update_type() - // TODO(angiebird): Merge this function with get_frame_type_from_update_type() - switch (update_type) { - case KF_UPDATE: return 0; // kFrameTypeKey; - case ARF_UPDATE: return 2; // kFrameTypeAltRef; - case GF_UPDATE: return 4; // kFrameTypeGolden; - case OVERLAY_UPDATE: return 3; // kFrameTypeOverlay; - case LF_UPDATE: return 1; // kFrameTypeInter; - default: - fprintf(stderr, "Unsupported update_type %d\n", update_type); - abort(); - } -} - -vpx_codec_err_t vp9_extrc_get_encodeframe_decision( - EXT_RATECTRL *ext_ratectrl, int gop_index, - vpx_rc_encodeframe_decision_t *encode_frame_decision) { - assert(ext_ratectrl != NULL); - assert(ext_ratectrl->ready && (ext_ratectrl->funcs.rc_type & VPX_RC_QP) != 0); - - vpx_rc_status_t rc_status = ext_ratectrl->funcs.get_encodeframe_decision( - ext_ratectrl->model, gop_index, encode_frame_decision); - if (rc_status == VPX_RC_ERROR) { - return VPX_CODEC_ERROR; - } - return VPX_CODEC_OK; -} - -vpx_codec_err_t vp9_extrc_update_encodeframe_result( - EXT_RATECTRL *ext_ratectrl, int64_t bit_count, int actual_encoding_qindex) { - if (ext_ratectrl == NULL) { - return VPX_CODEC_INVALID_PARAM; - } - if (ext_ratectrl->ready) { - vpx_rc_status_t rc_status; - vpx_rc_encodeframe_result_t encode_frame_result; - encode_frame_result.bit_count = bit_count; - encode_frame_result.actual_encoding_qindex = actual_encoding_qindex; - rc_status = ext_ratectrl->funcs.update_encodeframe_result( - ext_ratectrl->model, &encode_frame_result); - if (rc_status == VPX_RC_ERROR) { - return VPX_CODEC_ERROR; - } - } - return VPX_CODEC_OK; -} - -vpx_codec_err_t vp9_extrc_get_gop_decision( - EXT_RATECTRL *ext_ratectrl, vpx_rc_gop_decision_t *gop_decision) { - vpx_rc_status_t rc_status; - if (ext_ratectrl == NULL || !ext_ratectrl->ready || - (ext_ratectrl->funcs.rc_type & VPX_RC_GOP) == 0) { - return VPX_CODEC_INVALID_PARAM; - } - rc_status = - ext_ratectrl->funcs.get_gop_decision(ext_ratectrl->model, gop_decision); - if (rc_status == VPX_RC_ERROR) { - return VPX_CODEC_ERROR; - } - return VPX_CODEC_OK; -} - -vpx_codec_err_t vp9_extrc_get_key_frame_decision( - EXT_RATECTRL *ext_ratectrl, - vpx_rc_key_frame_decision_t *key_frame_decision) { - if (ext_ratectrl == NULL || !ext_ratectrl->ready || - (ext_ratectrl->funcs.rc_type & VPX_RC_GOP) == 0) { - return VPX_CODEC_INVALID_PARAM; - } - vpx_rc_status_t rc_status = ext_ratectrl->funcs.get_key_frame_decision( - ext_ratectrl->model, key_frame_decision); - return rc_status == VPX_RC_OK ? VPX_CODEC_OK : VPX_CODEC_ERROR; -} - -vpx_codec_err_t vp9_extrc_get_frame_rdmult( - EXT_RATECTRL *ext_ratectrl, int show_index, int coding_index, int gop_index, - FRAME_UPDATE_TYPE update_type, int gop_size, int use_alt_ref, - RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], int ref_frame_flags, - int *rdmult) { - vpx_rc_status_t rc_status; - vpx_rc_encodeframe_info_t encode_frame_info; - if (ext_ratectrl == NULL || !ext_ratectrl->ready || - (ext_ratectrl->funcs.rc_type & VPX_RC_RDMULT) == 0) { - return VPX_CODEC_INVALID_PARAM; - } - encode_frame_info.show_index = show_index; - encode_frame_info.coding_index = coding_index; - encode_frame_info.gop_index = gop_index; - encode_frame_info.frame_type = extrc_get_frame_type(update_type); - encode_frame_info.gop_size = gop_size; - encode_frame_info.use_alt_ref = use_alt_ref; - - vp9_get_ref_frame_info(update_type, ref_frame_flags, ref_frame_bufs, - encode_frame_info.ref_frame_coding_indexes, - encode_frame_info.ref_frame_valid_list); - rc_status = ext_ratectrl->funcs.get_frame_rdmult(ext_ratectrl->model, - &encode_frame_info, rdmult); - if (rc_status == VPX_RC_ERROR) { - return VPX_CODEC_ERROR; - } - return VPX_CODEC_OK; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ext_ratectrl.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ext_ratectrl.h deleted file mode 100644 index 4ea1b246..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ext_ratectrl.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2020 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_EXT_RATECTRL_H_ -#define VPX_VP9_ENCODER_VP9_EXT_RATECTRL_H_ - -#include "vpx/vpx_ext_ratectrl.h" -#include "vpx/vpx_tpl.h" -#include "vp9/encoder/vp9_firstpass.h" - -typedef struct EXT_RATECTRL { - int ready; - int ext_rdmult; - vpx_rc_model_t model; - vpx_rc_funcs_t funcs; - vpx_rc_config_t ratectrl_config; - vpx_rc_firstpass_stats_t rc_firstpass_stats; - FILE *log_file; -} EXT_RATECTRL; - -vpx_codec_err_t vp9_extrc_init(EXT_RATECTRL *ext_ratectrl); - -vpx_codec_err_t vp9_extrc_create(vpx_rc_funcs_t funcs, - vpx_rc_config_t ratectrl_config, - EXT_RATECTRL *ext_ratectrl); - -vpx_codec_err_t vp9_extrc_delete(EXT_RATECTRL *ext_ratectrl); - -vpx_codec_err_t vp9_extrc_send_firstpass_stats( - EXT_RATECTRL *ext_ratectrl, const FIRST_PASS_INFO *first_pass_info); - -vpx_codec_err_t vp9_extrc_send_tpl_stats(EXT_RATECTRL *ext_ratectrl, - const VpxTplGopStats *tpl_gop_stats); - -vpx_codec_err_t vp9_extrc_get_encodeframe_decision( - EXT_RATECTRL *ext_ratectrl, int gop_index, - vpx_rc_encodeframe_decision_t *encode_frame_decision); - -vpx_codec_err_t vp9_extrc_update_encodeframe_result(EXT_RATECTRL *ext_ratectrl, - int64_t bit_count, - int actual_encoding_qindex); - -vpx_codec_err_t vp9_extrc_get_key_frame_decision( - EXT_RATECTRL *ext_ratectrl, - vpx_rc_key_frame_decision_t *key_frame_decision); - -vpx_codec_err_t vp9_extrc_get_gop_decision(EXT_RATECTRL *ext_ratectrl, - vpx_rc_gop_decision_t *gop_decision); - -vpx_codec_err_t vp9_extrc_get_frame_rdmult( - EXT_RATECTRL *ext_ratectrl, int show_index, int coding_index, int gop_index, - FRAME_UPDATE_TYPE update_type, int gop_size, int use_alt_ref, - RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], int ref_frame_flags, - int *rdmult); - -#endif // VPX_VP9_ENCODER_VP9_EXT_RATECTRL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_extend.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_extend.c deleted file mode 100644 index 69261ac6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_extend.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" - -#include "vp9/common/vp9_common.h" -#include "vp9/encoder/vp9_extend.h" - -static void copy_and_extend_plane(const uint8_t *src, int src_pitch, - uint8_t *dst, int dst_pitch, int w, int h, - int extend_top, int extend_left, - int extend_bottom, int extend_right, - int interleave_step) { - int i, j, linesize; - const int step = interleave_step < 1 ? 1 : interleave_step; - - // copy the left and right most columns out - const uint8_t *src_ptr1 = src; - const uint8_t *src_ptr2 = src + (w - 1) * step; - uint8_t *dst_ptr1 = dst - extend_left; - uint8_t *dst_ptr2 = dst + w; - - for (i = 0; i < h; i++) { - memset(dst_ptr1, src_ptr1[0], extend_left); - if (step == 1) { - memcpy(dst_ptr1 + extend_left, src_ptr1, w); - } else { - for (j = 0; j < w; j++) { - dst_ptr1[extend_left + j] = src_ptr1[step * j]; - } - } - memset(dst_ptr2, src_ptr2[0], extend_right); - src_ptr1 += src_pitch; - src_ptr2 += src_pitch; - dst_ptr1 += dst_pitch; - dst_ptr2 += dst_pitch; - } - - // Now copy the top and bottom lines into each line of the respective - // borders - src_ptr1 = dst - extend_left; - src_ptr2 = dst + dst_pitch * (h - 1) - extend_left; - dst_ptr1 = dst + dst_pitch * (-extend_top) - extend_left; - dst_ptr2 = dst + dst_pitch * (h)-extend_left; - linesize = extend_left + extend_right + w; - - for (i = 0; i < extend_top; i++) { - memcpy(dst_ptr1, src_ptr1, linesize); - dst_ptr1 += dst_pitch; - } - - for (i = 0; i < extend_bottom; i++) { - memcpy(dst_ptr2, src_ptr2, linesize); - dst_ptr2 += dst_pitch; - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -static void highbd_copy_and_extend_plane(const uint8_t *src8, int src_pitch, - uint8_t *dst8, int dst_pitch, int w, - int h, int extend_top, int extend_left, - int extend_bottom, int extend_right) { - int i, linesize; - uint16_t *src = CONVERT_TO_SHORTPTR(src8); - uint16_t *dst = CONVERT_TO_SHORTPTR(dst8); - - // copy the left and right most columns out - const uint16_t *src_ptr1 = src; - const uint16_t *src_ptr2 = src + w - 1; - uint16_t *dst_ptr1 = dst - extend_left; - uint16_t *dst_ptr2 = dst + w; - - for (i = 0; i < h; i++) { - vpx_memset16(dst_ptr1, src_ptr1[0], extend_left); - memcpy(dst_ptr1 + extend_left, src_ptr1, w * sizeof(src_ptr1[0])); - vpx_memset16(dst_ptr2, src_ptr2[0], extend_right); - src_ptr1 += src_pitch; - src_ptr2 += src_pitch; - dst_ptr1 += dst_pitch; - dst_ptr2 += dst_pitch; - } - - // Now copy the top and bottom lines into each line of the respective - // borders - src_ptr1 = dst - extend_left; - src_ptr2 = dst + dst_pitch * (h - 1) - extend_left; - dst_ptr1 = dst + dst_pitch * (-extend_top) - extend_left; - dst_ptr2 = dst + dst_pitch * (h)-extend_left; - linesize = extend_left + extend_right + w; - - for (i = 0; i < extend_top; i++) { - memcpy(dst_ptr1, src_ptr1, linesize * sizeof(src_ptr1[0])); - dst_ptr1 += dst_pitch; - } - - for (i = 0; i < extend_bottom; i++) { - memcpy(dst_ptr2, src_ptr2, linesize * sizeof(src_ptr2[0])); - dst_ptr2 += dst_pitch; - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -void vp9_copy_and_extend_frame(const YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst) { - // Extend src frame in buffer - // Altref filtering assumes 16 pixel extension - const int et_y = 16; - const int el_y = 16; - // Motion estimation may use src block variance with the block size up - // to 64x64, so the right and bottom need to be extended to 64 multiple - // or up to 16, whichever is greater. - const int er_y = - VPXMAX(src->y_width + 16, ALIGN_POWER_OF_TWO(src->y_width, 6)) - - src->y_crop_width; - const int eb_y = - VPXMAX(src->y_height + 16, ALIGN_POWER_OF_TWO(src->y_height, 6)) - - src->y_crop_height; - const int uv_width_subsampling = (src->uv_width != src->y_width); - const int uv_height_subsampling = (src->uv_height != src->y_height); - const int et_uv = et_y >> uv_height_subsampling; - const int el_uv = el_y >> uv_width_subsampling; - const int eb_uv = eb_y >> uv_height_subsampling; - const int er_uv = er_y >> uv_width_subsampling; - // detect nv12 colorspace - const int chroma_step = src->v_buffer - src->u_buffer == 1 ? 2 : 1; - -#if CONFIG_VP9_HIGHBITDEPTH - if (src->flags & YV12_FLAG_HIGHBITDEPTH) { - highbd_copy_and_extend_plane(src->y_buffer, src->y_stride, dst->y_buffer, - dst->y_stride, src->y_crop_width, - src->y_crop_height, et_y, el_y, eb_y, er_y); - - highbd_copy_and_extend_plane( - src->u_buffer, src->uv_stride, dst->u_buffer, dst->uv_stride, - src->uv_crop_width, src->uv_crop_height, et_uv, el_uv, eb_uv, er_uv); - - highbd_copy_and_extend_plane( - src->v_buffer, src->uv_stride, dst->v_buffer, dst->uv_stride, - src->uv_crop_width, src->uv_crop_height, et_uv, el_uv, eb_uv, er_uv); - return; - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - copy_and_extend_plane(src->y_buffer, src->y_stride, dst->y_buffer, - dst->y_stride, src->y_crop_width, src->y_crop_height, - et_y, el_y, eb_y, er_y, 1); - - copy_and_extend_plane(src->u_buffer, src->uv_stride, dst->u_buffer, - dst->uv_stride, src->uv_crop_width, src->uv_crop_height, - et_uv, el_uv, eb_uv, er_uv, chroma_step); - - copy_and_extend_plane(src->v_buffer, src->uv_stride, dst->v_buffer, - dst->uv_stride, src->uv_crop_width, src->uv_crop_height, - et_uv, el_uv, eb_uv, er_uv, chroma_step); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_extend.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_extend.h deleted file mode 100644 index 21d7e68b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_extend.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_EXTEND_H_ -#define VPX_VP9_ENCODER_VP9_EXTEND_H_ - -#include "vpx_scale/yv12config.h" -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vp9_copy_and_extend_frame(const YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_EXTEND_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_firstpass.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_firstpass.c deleted file mode 100644 index a41eca92..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_firstpass.c +++ /dev/null @@ -1,4084 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "./vpx_scale_rtcd.h" - -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/system_state.h" -#include "vpx_scale/vpx_scale.h" -#include "vpx_scale/yv12config.h" - -#include "vp9/common/vp9_entropymv.h" -#include "vp9/common/vp9_quant_common.h" -#include "vp9/common/vp9_reconinter.h" // vp9_setup_dst_planes() -#include "vp9/encoder/vp9_aq_variance.h" -#include "vp9/encoder/vp9_block.h" -#include "vp9/encoder/vp9_encodeframe.h" -#include "vp9/encoder/vp9_encodemb.h" -#include "vp9/encoder/vp9_encodemv.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_ethread.h" -#include "vp9/encoder/vp9_extend.h" -#include "vp9/encoder/vp9_ext_ratectrl.h" -#include "vp9/encoder/vp9_firstpass.h" -#include "vp9/encoder/vp9_mcomp.h" -#include "vp9/encoder/vp9_quantize.h" -#include "vp9/encoder/vp9_ratectrl.h" -#include "vp9/encoder/vp9_rd.h" -#include "vpx/internal/vpx_codec_internal.h" -#include "vpx/vpx_codec.h" -#include "vpx/vpx_ext_ratectrl.h" -#include "vpx_dsp/variance.h" - -#define OUTPUT_FPF 0 -#define ARF_STATS_OUTPUT 0 -#define COMPLEXITY_STATS_OUTPUT 0 - -#define FIRST_PASS_Q 10.0 -#define NORMAL_BOOST 100 -#define MIN_ARF_GF_BOOST 250 -#define MIN_DECAY_FACTOR 0.01 -#define NEW_MV_MODE_PENALTY 32 -#define DARK_THRESH 64 -#define LOW_I_THRESH 24000 - -#define NCOUNT_INTRA_THRESH 8192 -#define NCOUNT_INTRA_FACTOR 3 - -#define INTRA_PART 0.005 -#define DEFAULT_DECAY_LIMIT 0.75 -#define LOW_SR_DIFF_TRHESH 0.1 -#define LOW_CODED_ERR_PER_MB 10.0 -#define NCOUNT_FRAME_II_THRESH 6.0 -#define BASELINE_ERR_PER_MB 12500.0 -#define GF_MAX_FRAME_BOOST 96.0 - -#ifdef AGGRESSIVE_VBR -#define KF_MIN_FRAME_BOOST 40.0 -#define KF_MAX_FRAME_BOOST 80.0 -#define MAX_KF_TOT_BOOST 4800 -#else -#define KF_MIN_FRAME_BOOST 40.0 -#define KF_MAX_FRAME_BOOST 96.0 -#define MAX_KF_TOT_BOOST 5400 -#endif - -#define DEFAULT_ZM_FACTOR 0.5 -#define MINQ_ADJ_LIMIT 48 -#define MINQ_ADJ_LIMIT_CQ 20 -#define HIGH_UNDERSHOOT_RATIO 2 -#define AV_WQ_FACTOR 4.0 - -#define DOUBLE_DIVIDE_CHECK(x) ((x) < 0 ? (x)-0.000001 : (x) + 0.000001) - -#if ARF_STATS_OUTPUT -unsigned int arf_count = 0; -#endif - -// Resets the first pass file to the given position using a relative seek from -// the current position. -static void reset_fpf_position(TWO_PASS *p, const FIRSTPASS_STATS *position) { - p->stats_in = position; -} - -// Read frame stats at an offset from the current position. -static const FIRSTPASS_STATS *read_frame_stats(const TWO_PASS *p, int offset) { - if ((offset >= 0 && p->stats_in + offset >= p->stats_in_end) || - (offset < 0 && p->stats_in + offset < p->stats_in_start)) { - return NULL; - } - - return &p->stats_in[offset]; -} - -static int input_stats(TWO_PASS *p, FIRSTPASS_STATS *fps) { - if (p->stats_in >= p->stats_in_end) return EOF; - - *fps = *p->stats_in; - ++p->stats_in; - return 1; -} - -static void output_stats(FIRSTPASS_STATS *stats) { - (void)stats; -// TEMP debug code -#if OUTPUT_FPF - { - FILE *fpfile; - fpfile = fopen("firstpass.stt", "a"); - - fprintf(fpfile, - "%12.0lf %12.4lf %12.2lf %12.2lf %12.2lf %12.0lf %12.4lf %12.4lf" - "%12.4lf %12.4lf %12.4lf %12.4lf %12.4lf %12.4lf %12.4lf %12.4lf" - "%12.4lf %12.4lf %12.4lf %12.4lf %12.4lf %12.0lf %12.4lf %12.0lf" - "%12.4lf" - "\n", - stats->frame, stats->weight, stats->intra_error, stats->coded_error, - stats->sr_coded_error, stats->frame_noise_energy, stats->pcnt_inter, - stats->pcnt_motion, stats->pcnt_second_ref, stats->pcnt_neutral, - stats->pcnt_intra_low, stats->pcnt_intra_high, - stats->intra_skip_pct, stats->intra_smooth_pct, - stats->inactive_zone_rows, stats->inactive_zone_cols, stats->MVr, - stats->mvr_abs, stats->MVc, stats->mvc_abs, stats->MVrv, - stats->MVcv, stats->mv_in_out_count, stats->count, stats->duration); - fclose(fpfile); - } -#endif -} - -static void zero_stats(FIRSTPASS_STATS *section) { - section->frame = 0.0; - section->weight = 0.0; - section->intra_error = 0.0; - section->coded_error = 0.0; - section->sr_coded_error = 0.0; - section->frame_noise_energy = 0.0; - section->pcnt_inter = 0.0; - section->pcnt_motion = 0.0; - section->pcnt_second_ref = 0.0; - section->pcnt_neutral = 0.0; - section->intra_skip_pct = 0.0; - section->intra_smooth_pct = 0.0; - section->pcnt_intra_low = 0.0; - section->pcnt_intra_high = 0.0; - section->inactive_zone_rows = 0.0; - section->inactive_zone_cols = 0.0; - section->new_mv_count = 0.0; - section->MVr = 0.0; - section->mvr_abs = 0.0; - section->MVc = 0.0; - section->mvc_abs = 0.0; - section->MVrv = 0.0; - section->MVcv = 0.0; - section->mv_in_out_count = 0.0; - section->count = 0.0; - section->duration = 1.0; - section->spatial_layer_id = 0; -} - -static void accumulate_stats(FIRSTPASS_STATS *section, - const FIRSTPASS_STATS *frame) { - section->frame += frame->frame; - section->weight += frame->weight; - section->spatial_layer_id = frame->spatial_layer_id; - section->intra_error += frame->intra_error; - section->coded_error += frame->coded_error; - section->sr_coded_error += frame->sr_coded_error; - section->frame_noise_energy += frame->frame_noise_energy; - section->pcnt_inter += frame->pcnt_inter; - section->pcnt_motion += frame->pcnt_motion; - section->pcnt_second_ref += frame->pcnt_second_ref; - section->pcnt_neutral += frame->pcnt_neutral; - section->intra_skip_pct += frame->intra_skip_pct; - section->intra_smooth_pct += frame->intra_smooth_pct; - section->pcnt_intra_low += frame->pcnt_intra_low; - section->pcnt_intra_high += frame->pcnt_intra_high; - section->inactive_zone_rows += frame->inactive_zone_rows; - section->inactive_zone_cols += frame->inactive_zone_cols; - section->new_mv_count += frame->new_mv_count; - section->MVr += frame->MVr; - section->mvr_abs += frame->mvr_abs; - section->MVc += frame->MVc; - section->mvc_abs += frame->mvc_abs; - section->MVrv += frame->MVrv; - section->MVcv += frame->MVcv; - section->mv_in_out_count += frame->mv_in_out_count; - section->count += frame->count; - section->duration += frame->duration; -} - -static void subtract_stats(FIRSTPASS_STATS *section, - const FIRSTPASS_STATS *frame) { - section->frame -= frame->frame; - section->weight -= frame->weight; - section->intra_error -= frame->intra_error; - section->coded_error -= frame->coded_error; - section->sr_coded_error -= frame->sr_coded_error; - section->frame_noise_energy -= frame->frame_noise_energy; - section->pcnt_inter -= frame->pcnt_inter; - section->pcnt_motion -= frame->pcnt_motion; - section->pcnt_second_ref -= frame->pcnt_second_ref; - section->pcnt_neutral -= frame->pcnt_neutral; - section->intra_skip_pct -= frame->intra_skip_pct; - section->intra_smooth_pct -= frame->intra_smooth_pct; - section->pcnt_intra_low -= frame->pcnt_intra_low; - section->pcnt_intra_high -= frame->pcnt_intra_high; - section->inactive_zone_rows -= frame->inactive_zone_rows; - section->inactive_zone_cols -= frame->inactive_zone_cols; - section->new_mv_count -= frame->new_mv_count; - section->MVr -= frame->MVr; - section->mvr_abs -= frame->mvr_abs; - section->MVc -= frame->MVc; - section->mvc_abs -= frame->mvc_abs; - section->MVrv -= frame->MVrv; - section->MVcv -= frame->MVcv; - section->mv_in_out_count -= frame->mv_in_out_count; - section->count -= frame->count; - section->duration -= frame->duration; -} - -// Calculate an active area of the image that discounts formatting -// bars and partially discounts other 0 energy areas. -#define MIN_ACTIVE_AREA 0.5 -#define MAX_ACTIVE_AREA 1.0 -static double calculate_active_area(const FRAME_INFO *frame_info, - const FIRSTPASS_STATS *this_frame) { - double active_pct; - - active_pct = - 1.0 - - ((this_frame->intra_skip_pct / 2) + - ((this_frame->inactive_zone_rows * 2) / (double)frame_info->mb_rows)); - return fclamp(active_pct, MIN_ACTIVE_AREA, MAX_ACTIVE_AREA); -} - -// Get the average weighted error for the clip (or corpus) -static double get_distribution_av_err(VP9_COMP *cpi, TWO_PASS *const twopass) { - const double av_weight = - twopass->total_stats.weight / twopass->total_stats.count; - - if (cpi->oxcf.vbr_corpus_complexity) - return av_weight * twopass->mean_mod_score; - else - return (twopass->total_stats.coded_error * av_weight) / - twopass->total_stats.count; -} - -#define ACT_AREA_CORRECTION 0.5 -// Calculate a modified Error used in distributing bits between easier and -// harder frames. -static double calculate_mod_frame_score(const VP9_COMP *cpi, - const VP9EncoderConfig *oxcf, - const FIRSTPASS_STATS *this_frame, - const double av_err) { - double modified_score = - av_err * pow(this_frame->coded_error * this_frame->weight / - DOUBLE_DIVIDE_CHECK(av_err), - oxcf->two_pass_vbrbias / 100.0); - - // Correction for active area. Frames with a reduced active area - // (eg due to formatting bars) have a higher error per mb for the - // remaining active MBs. The correction here assumes that coding - // 0.5N blocks of complexity 2X is a little easier than coding N - // blocks of complexity X. - modified_score *= pow(calculate_active_area(&cpi->frame_info, this_frame), - ACT_AREA_CORRECTION); - - return modified_score; -} - -static double calc_norm_frame_score(const VP9EncoderConfig *oxcf, - const FRAME_INFO *frame_info, - const FIRSTPASS_STATS *this_frame, - double mean_mod_score, double av_err) { - double modified_score = - av_err * pow(this_frame->coded_error * this_frame->weight / - DOUBLE_DIVIDE_CHECK(av_err), - oxcf->two_pass_vbrbias / 100.0); - - const double min_score = (double)(oxcf->two_pass_vbrmin_section) / 100.0; - const double max_score = (double)(oxcf->two_pass_vbrmax_section) / 100.0; - - // Correction for active area. Frames with a reduced active area - // (eg due to formatting bars) have a higher error per mb for the - // remaining active MBs. The correction here assumes that coding - // 0.5N blocks of complexity 2X is a little easier than coding N - // blocks of complexity X. - modified_score *= - pow(calculate_active_area(frame_info, this_frame), ACT_AREA_CORRECTION); - - // Normalize to a midpoint score. - modified_score /= DOUBLE_DIVIDE_CHECK(mean_mod_score); - return fclamp(modified_score, min_score, max_score); -} - -static double calculate_norm_frame_score(const VP9_COMP *cpi, - const TWO_PASS *twopass, - const VP9EncoderConfig *oxcf, - const FIRSTPASS_STATS *this_frame, - const double av_err) { - return calc_norm_frame_score(oxcf, &cpi->frame_info, this_frame, - twopass->mean_mod_score, av_err); -} - -// This function returns the maximum target rate per frame. -static int frame_max_bits(const RATE_CONTROL *rc, - const VP9EncoderConfig *oxcf) { - int64_t max_bits = ((int64_t)rc->avg_frame_bandwidth * - (int64_t)oxcf->two_pass_vbrmax_section) / - 100; - if (max_bits < 0) - max_bits = 0; - else if (max_bits > rc->max_frame_bandwidth) - max_bits = rc->max_frame_bandwidth; - - return (int)max_bits; -} - -void vp9_init_first_pass(VP9_COMP *cpi) { - zero_stats(&cpi->twopass.total_stats); -} - -void vp9_end_first_pass(VP9_COMP *cpi) { - output_stats(&cpi->twopass.total_stats); - cpi->twopass.first_pass_done = 1; - vpx_free(cpi->twopass.fp_mb_float_stats); - cpi->twopass.fp_mb_float_stats = NULL; -} - -static vpx_variance_fn_t get_block_variance_fn(BLOCK_SIZE bsize) { - switch (bsize) { - case BLOCK_8X8: return vpx_mse8x8; - case BLOCK_16X8: return vpx_mse16x8; - case BLOCK_8X16: return vpx_mse8x16; - default: return vpx_mse16x16; - } -} - -static unsigned int get_prediction_error(BLOCK_SIZE bsize, - const struct buf_2d *src, - const struct buf_2d *ref) { - unsigned int sse; - const vpx_variance_fn_t fn = get_block_variance_fn(bsize); - fn(src->buf, src->stride, ref->buf, ref->stride, &sse); - return sse; -} - -#if CONFIG_VP9_HIGHBITDEPTH -static vpx_variance_fn_t highbd_get_block_variance_fn(BLOCK_SIZE bsize, - int bd) { - switch (bd) { - default: - switch (bsize) { - case BLOCK_8X8: return vpx_highbd_8_mse8x8; - case BLOCK_16X8: return vpx_highbd_8_mse16x8; - case BLOCK_8X16: return vpx_highbd_8_mse8x16; - default: return vpx_highbd_8_mse16x16; - } - case 10: - switch (bsize) { - case BLOCK_8X8: return vpx_highbd_10_mse8x8; - case BLOCK_16X8: return vpx_highbd_10_mse16x8; - case BLOCK_8X16: return vpx_highbd_10_mse8x16; - default: return vpx_highbd_10_mse16x16; - } - case 12: - switch (bsize) { - case BLOCK_8X8: return vpx_highbd_12_mse8x8; - case BLOCK_16X8: return vpx_highbd_12_mse16x8; - case BLOCK_8X16: return vpx_highbd_12_mse8x16; - default: return vpx_highbd_12_mse16x16; - } - } -} - -static unsigned int highbd_get_prediction_error(BLOCK_SIZE bsize, - const struct buf_2d *src, - const struct buf_2d *ref, - int bd) { - unsigned int sse; - const vpx_variance_fn_t fn = highbd_get_block_variance_fn(bsize, bd); - fn(src->buf, src->stride, ref->buf, ref->stride, &sse); - return sse; -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -// Refine the motion search range according to the frame dimension -// for first pass test. -static int get_search_range(const VP9_COMP *cpi) { - int sr = 0; - const int dim = VPXMIN(cpi->initial_width, cpi->initial_height); - - while ((dim << sr) < MAX_FULL_PEL_VAL) ++sr; - return sr; -} - -// Reduce limits to keep the motion search within MV_MAX of ref_mv. Not doing -// this can be problematic for big videos (8K) and may cause assert failure -// (or memory violation) in mv_cost. Limits are only modified if they would -// be non-empty. Returns 1 if limits are non-empty. -static int intersect_limits_with_mv_max(MvLimits *mv_limits, const MV *ref_mv) { - const int row_min = - VPXMAX(mv_limits->row_min, (ref_mv->row + 7 - MV_MAX) >> 3); - const int row_max = - VPXMIN(mv_limits->row_max, (ref_mv->row - 1 + MV_MAX) >> 3); - const int col_min = - VPXMAX(mv_limits->col_min, (ref_mv->col + 7 - MV_MAX) >> 3); - const int col_max = - VPXMIN(mv_limits->col_max, (ref_mv->col - 1 + MV_MAX) >> 3); - if (row_min > row_max || col_min > col_max) { - return 0; - } - mv_limits->row_min = row_min; - mv_limits->row_max = row_max; - mv_limits->col_min = col_min; - mv_limits->col_max = col_max; - return 1; -} - -static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x, - const MV *ref_mv, MV *best_mv, - int *best_motion_err) { - MACROBLOCKD *const xd = &x->e_mbd; - MV tmp_mv = { 0, 0 }; - MV ref_mv_full = { ref_mv->row >> 3, ref_mv->col >> 3 }; - int num00, tmp_err, n; - const BLOCK_SIZE bsize = xd->mi[0]->sb_type; - vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize]; - const int new_mv_mode_penalty = NEW_MV_MODE_PENALTY; - MV center_mv_full = ref_mv_full; - unsigned int start_mv_sad; - vp9_sad_fn_ptr_t sad_fn_ptr; - - int step_param = 3; - int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param; - const int sr = get_search_range(cpi); - const MvLimits tmp_mv_limits = x->mv_limits; - step_param += sr; - further_steps -= sr; - - if (!intersect_limits_with_mv_max(&x->mv_limits, ref_mv)) { - return; - } - - // Override the default variance function to use MSE. - v_fn_ptr.vf = get_block_variance_fn(bsize); -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - v_fn_ptr.vf = highbd_get_block_variance_fn(bsize, xd->bd); - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - // Calculate SAD of the start mv - clamp_mv(&ref_mv_full, x->mv_limits.col_min, x->mv_limits.col_max, - x->mv_limits.row_min, x->mv_limits.row_max); - start_mv_sad = get_start_mv_sad(x, &ref_mv_full, ¢er_mv_full, - cpi->fn_ptr[bsize].sdf, x->sadperbit16); - sad_fn_ptr.sdf = cpi->fn_ptr[bsize].sdf; - sad_fn_ptr.sdx4df = cpi->fn_ptr[bsize].sdx4df; - - // Center the initial step/diamond search on best mv. - tmp_err = cpi->diamond_search_sad(x, &cpi->ss_cfg, &ref_mv_full, start_mv_sad, - &tmp_mv, step_param, x->sadperbit16, &num00, - &sad_fn_ptr, ref_mv); - if (tmp_err < INT_MAX) - tmp_err = vp9_get_mvpred_var(x, &tmp_mv, ref_mv, &v_fn_ptr, 1); - if (tmp_err < INT_MAX - new_mv_mode_penalty) tmp_err += new_mv_mode_penalty; - - if (tmp_err < *best_motion_err) { - *best_motion_err = tmp_err; - *best_mv = tmp_mv; - } - - // Carry out further step/diamond searches as necessary. - n = num00; - num00 = 0; - - while (n < further_steps) { - ++n; - - if (num00) { - --num00; - } else { - tmp_err = cpi->diamond_search_sad( - x, &cpi->ss_cfg, &ref_mv_full, start_mv_sad, &tmp_mv, step_param + n, - x->sadperbit16, &num00, &sad_fn_ptr, ref_mv); - if (tmp_err < INT_MAX) - tmp_err = vp9_get_mvpred_var(x, &tmp_mv, ref_mv, &v_fn_ptr, 1); - if (tmp_err < INT_MAX - new_mv_mode_penalty) - tmp_err += new_mv_mode_penalty; - - if (tmp_err < *best_motion_err) { - *best_motion_err = tmp_err; - *best_mv = tmp_mv; - } - } - } - x->mv_limits = tmp_mv_limits; -} - -static BLOCK_SIZE get_bsize(const VP9_COMMON *cm, int mb_row, int mb_col) { - if (2 * mb_col + 1 < cm->mi_cols) { - return 2 * mb_row + 1 < cm->mi_rows ? BLOCK_16X16 : BLOCK_16X8; - } else { - return 2 * mb_row + 1 < cm->mi_rows ? BLOCK_8X16 : BLOCK_8X8; - } -} - -static int find_fp_qindex(vpx_bit_depth_t bit_depth) { - int i; - - for (i = 0; i < QINDEX_RANGE; ++i) - if (vp9_convert_qindex_to_q(i, bit_depth) >= FIRST_PASS_Q) break; - - if (i == QINDEX_RANGE) i--; - - return i; -} - -static void set_first_pass_params(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - if (!cpi->refresh_alt_ref_frame && - (cm->current_video_frame == 0 || (cpi->frame_flags & FRAMEFLAGS_KEY))) { - cm->frame_type = KEY_FRAME; - } else { - cm->frame_type = INTER_FRAME; - } - // Do not use periodic key frames. - cpi->rc.frames_to_key = INT_MAX; -} - -// Scale an sse threshold to account for 8/10/12 bit. -static int scale_sse_threshold(VP9_COMMON *cm, int thresh) { - int ret_val = thresh; -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - switch (cm->bit_depth) { - case VPX_BITS_8: ret_val = thresh; break; - case VPX_BITS_10: ret_val = thresh << 4; break; - default: - assert(cm->bit_depth == VPX_BITS_12); - ret_val = thresh << 8; - break; - } - } -#else - (void)cm; -#endif // CONFIG_VP9_HIGHBITDEPTH - return ret_val; -} - -// This threshold is used to track blocks where to all intents and purposes -// the intra prediction error 0. Though the metric we test against -// is technically a sse we are mainly interested in blocks where all the pixels -// in the 8 bit domain have an error of <= 1 (where error = sse) so a -// linear scaling for 10 and 12 bit gives similar results. -#define UL_INTRA_THRESH 50 -static int get_ul_intra_threshold(VP9_COMMON *cm) { - int ret_val = UL_INTRA_THRESH; -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - switch (cm->bit_depth) { - case VPX_BITS_8: ret_val = UL_INTRA_THRESH; break; - case VPX_BITS_10: ret_val = UL_INTRA_THRESH << 2; break; - default: - assert(cm->bit_depth == VPX_BITS_12); - ret_val = UL_INTRA_THRESH << 4; - break; - } - } -#else - (void)cm; -#endif // CONFIG_VP9_HIGHBITDEPTH - return ret_val; -} - -#define SMOOTH_INTRA_THRESH 4000 -static int get_smooth_intra_threshold(VP9_COMMON *cm) { - int ret_val = SMOOTH_INTRA_THRESH; -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - switch (cm->bit_depth) { - case VPX_BITS_8: ret_val = SMOOTH_INTRA_THRESH; break; - case VPX_BITS_10: ret_val = SMOOTH_INTRA_THRESH << 4; break; - default: - assert(cm->bit_depth == VPX_BITS_12); - ret_val = SMOOTH_INTRA_THRESH << 8; - break; - } - } -#else - (void)cm; -#endif // CONFIG_VP9_HIGHBITDEPTH - return ret_val; -} - -#define FP_DN_THRESH 8 -#define FP_MAX_DN_THRESH 24 -#define KERNEL_SIZE 3 - -// Baseline Kernel weights for first pass noise metric -static uint8_t fp_dn_kernel_3[KERNEL_SIZE * KERNEL_SIZE] = { 1, 2, 1, 2, 4, - 2, 1, 2, 1 }; - -// Estimate noise at a single point based on the impact of a spatial kernel -// on the point value -static int fp_estimate_point_noise(uint8_t *src_ptr, const int stride) { - int sum_weight = 0; - int sum_val = 0; - int i, j; - int max_diff = 0; - int diff; - int dn_diff; - uint8_t *tmp_ptr; - uint8_t *kernel_ptr; - uint8_t dn_val; - uint8_t centre_val = *src_ptr; - - kernel_ptr = fp_dn_kernel_3; - - // Apply the kernel - tmp_ptr = src_ptr - stride - 1; - for (i = 0; i < KERNEL_SIZE; ++i) { - for (j = 0; j < KERNEL_SIZE; ++j) { - diff = abs((int)centre_val - (int)tmp_ptr[j]); - max_diff = VPXMAX(max_diff, diff); - if (diff <= FP_DN_THRESH) { - sum_weight += *kernel_ptr; - sum_val += (int)tmp_ptr[j] * (int)*kernel_ptr; - } - ++kernel_ptr; - } - tmp_ptr += stride; - } - - if (max_diff < FP_MAX_DN_THRESH) - // Update the source value with the new filtered value - dn_val = (sum_val + (sum_weight >> 1)) / sum_weight; - else - dn_val = *src_ptr; - - // return the noise energy as the square of the difference between the - // denoised and raw value. - dn_diff = (int)*src_ptr - (int)dn_val; - return dn_diff * dn_diff; -} -#if CONFIG_VP9_HIGHBITDEPTH -static int fp_highbd_estimate_point_noise(uint8_t *src_ptr, const int stride) { - int sum_weight = 0; - int sum_val = 0; - int i, j; - int max_diff = 0; - int diff; - int dn_diff; - uint8_t *tmp_ptr; - uint16_t *tmp_ptr16; - uint8_t *kernel_ptr; - uint16_t dn_val; - uint16_t centre_val = *CONVERT_TO_SHORTPTR(src_ptr); - - kernel_ptr = fp_dn_kernel_3; - - // Apply the kernel - tmp_ptr = src_ptr - stride - 1; - for (i = 0; i < KERNEL_SIZE; ++i) { - tmp_ptr16 = CONVERT_TO_SHORTPTR(tmp_ptr); - for (j = 0; j < KERNEL_SIZE; ++j) { - diff = abs((int)centre_val - (int)tmp_ptr16[j]); - max_diff = VPXMAX(max_diff, diff); - if (diff <= FP_DN_THRESH) { - sum_weight += *kernel_ptr; - sum_val += (int)tmp_ptr16[j] * (int)*kernel_ptr; - } - ++kernel_ptr; - } - tmp_ptr += stride; - } - - if (max_diff < FP_MAX_DN_THRESH) - // Update the source value with the new filtered value - dn_val = (sum_val + (sum_weight >> 1)) / sum_weight; - else - dn_val = *CONVERT_TO_SHORTPTR(src_ptr); - - // return the noise energy as the square of the difference between the - // denoised and raw value. - dn_diff = (int)(*CONVERT_TO_SHORTPTR(src_ptr)) - (int)dn_val; - return dn_diff * dn_diff; -} -#endif - -// Estimate noise for a block. -static int fp_estimate_block_noise(MACROBLOCK *x, BLOCK_SIZE bsize) { -#if CONFIG_VP9_HIGHBITDEPTH - MACROBLOCKD *xd = &x->e_mbd; -#endif - uint8_t *src_ptr = &x->plane[0].src.buf[0]; - const int width = num_4x4_blocks_wide_lookup[bsize] * 4; - const int height = num_4x4_blocks_high_lookup[bsize] * 4; - int w, h; - int stride = x->plane[0].src.stride; - int block_noise = 0; - - // Sampled points to reduce cost overhead. - for (h = 0; h < height; h += 2) { - for (w = 0; w < width; w += 2) { -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) - block_noise += fp_highbd_estimate_point_noise(src_ptr, stride); - else - block_noise += fp_estimate_point_noise(src_ptr, stride); -#else - block_noise += fp_estimate_point_noise(src_ptr, stride); -#endif - ++src_ptr; - } - src_ptr += (stride - width); - } - return block_noise << 2; // Scale << 2 to account for sampling. -} - -// This function is called to test the functionality of row based -// multi-threading in unit tests for bit-exactness -static void accumulate_floating_point_stats(VP9_COMP *cpi, - TileDataEnc *first_tile_col) { - VP9_COMMON *const cm = &cpi->common; - int mb_row, mb_col; - first_tile_col->fp_data.intra_factor = 0; - first_tile_col->fp_data.brightness_factor = 0; - first_tile_col->fp_data.neutral_count = 0; - for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) { - for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) { - const int mb_index = mb_row * cm->mb_cols + mb_col; - first_tile_col->fp_data.intra_factor += - cpi->twopass.fp_mb_float_stats[mb_index].frame_mb_intra_factor; - first_tile_col->fp_data.brightness_factor += - cpi->twopass.fp_mb_float_stats[mb_index].frame_mb_brightness_factor; - first_tile_col->fp_data.neutral_count += - cpi->twopass.fp_mb_float_stats[mb_index].frame_mb_neutral_count; - } - } -} - -static void first_pass_stat_calc(VP9_COMP *cpi, FIRSTPASS_STATS *fps, - FIRSTPASS_DATA *fp_acc_data) { - VP9_COMMON *const cm = &cpi->common; - // The minimum error here insures some bit allocation to frames even - // in static regions. The allocation per MB declines for larger formats - // where the typical "real" energy per MB also falls. - // Initial estimate here uses sqrt(mbs) to define the min_err, where the - // number of mbs is proportional to the image area. - const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE) ? cpi->initial_mbs - : cpi->common.MBs; - const double min_err = 200 * sqrt(num_mbs); - - // Clamp the image start to rows/2. This number of rows is discarded top - // and bottom as dead data so rows / 2 means the frame is blank. - if ((fp_acc_data->image_data_start_row > cm->mb_rows / 2) || - (fp_acc_data->image_data_start_row == INVALID_ROW)) { - fp_acc_data->image_data_start_row = cm->mb_rows / 2; - } - // Exclude any image dead zone - if (fp_acc_data->image_data_start_row > 0) { - fp_acc_data->intra_skip_count = - VPXMAX(0, fp_acc_data->intra_skip_count - - (fp_acc_data->image_data_start_row * cm->mb_cols * 2)); - } - - fp_acc_data->intra_factor = fp_acc_data->intra_factor / (double)num_mbs; - fp_acc_data->brightness_factor = - fp_acc_data->brightness_factor / (double)num_mbs; - fps->weight = fp_acc_data->intra_factor * fp_acc_data->brightness_factor; - - fps->frame = cm->current_video_frame; - fps->spatial_layer_id = cpi->svc.spatial_layer_id; - - fps->coded_error = - ((double)(fp_acc_data->coded_error >> 8) + min_err) / num_mbs; - fps->sr_coded_error = - ((double)(fp_acc_data->sr_coded_error >> 8) + min_err) / num_mbs; - fps->intra_error = - ((double)(fp_acc_data->intra_error >> 8) + min_err) / num_mbs; - - fps->frame_noise_energy = - (double)(fp_acc_data->frame_noise_energy) / (double)num_mbs; - fps->count = 1.0; - fps->pcnt_inter = (double)(fp_acc_data->intercount) / num_mbs; - fps->pcnt_second_ref = (double)(fp_acc_data->second_ref_count) / num_mbs; - fps->pcnt_neutral = (double)(fp_acc_data->neutral_count) / num_mbs; - fps->pcnt_intra_low = (double)(fp_acc_data->intra_count_low) / num_mbs; - fps->pcnt_intra_high = (double)(fp_acc_data->intra_count_high) / num_mbs; - fps->intra_skip_pct = (double)(fp_acc_data->intra_skip_count) / num_mbs; - fps->intra_smooth_pct = (double)(fp_acc_data->intra_smooth_count) / num_mbs; - fps->inactive_zone_rows = (double)(fp_acc_data->image_data_start_row); - // Currently set to 0 as most issues relate to letter boxing. - fps->inactive_zone_cols = (double)0; - - if (fp_acc_data->mvcount > 0) { - fps->new_mv_count = (double)(fp_acc_data->new_mv_count) / num_mbs; - fps->MVr = (double)(fp_acc_data->sum_mvr) / fp_acc_data->mvcount; - fps->mvr_abs = (double)(fp_acc_data->sum_mvr_abs) / fp_acc_data->mvcount; - fps->MVc = (double)(fp_acc_data->sum_mvc) / fp_acc_data->mvcount; - fps->mvc_abs = (double)(fp_acc_data->sum_mvc_abs) / fp_acc_data->mvcount; - fps->MVrv = ((double)(fp_acc_data->sum_mvrs) - - ((double)(fp_acc_data->sum_mvr) * (fp_acc_data->sum_mvr) / - fp_acc_data->mvcount)) / - fp_acc_data->mvcount; - fps->MVcv = ((double)(fp_acc_data->sum_mvcs) - - ((double)(fp_acc_data->sum_mvc) * (fp_acc_data->sum_mvc) / - fp_acc_data->mvcount)) / - fp_acc_data->mvcount; - fps->mv_in_out_count = - (double)(fp_acc_data->sum_in_vectors) / (fp_acc_data->mvcount * 2); - fps->pcnt_motion = (double)(fp_acc_data->mvcount) / num_mbs; - } else { - fps->new_mv_count = 0.0; - fps->MVr = 0.0; - fps->mvr_abs = 0.0; - fps->MVc = 0.0; - fps->mvc_abs = 0.0; - fps->MVrv = 0.0; - fps->MVcv = 0.0; - fps->mv_in_out_count = 0.0; - fps->pcnt_motion = 0.0; - } -} - -static void accumulate_fp_mb_row_stat(TileDataEnc *this_tile, - FIRSTPASS_DATA *fp_acc_data) { - this_tile->fp_data.intra_factor += fp_acc_data->intra_factor; - this_tile->fp_data.brightness_factor += fp_acc_data->brightness_factor; - this_tile->fp_data.coded_error += fp_acc_data->coded_error; - this_tile->fp_data.sr_coded_error += fp_acc_data->sr_coded_error; - this_tile->fp_data.frame_noise_energy += fp_acc_data->frame_noise_energy; - this_tile->fp_data.intra_error += fp_acc_data->intra_error; - this_tile->fp_data.intercount += fp_acc_data->intercount; - this_tile->fp_data.second_ref_count += fp_acc_data->second_ref_count; - this_tile->fp_data.neutral_count += fp_acc_data->neutral_count; - this_tile->fp_data.intra_count_low += fp_acc_data->intra_count_low; - this_tile->fp_data.intra_count_high += fp_acc_data->intra_count_high; - this_tile->fp_data.intra_skip_count += fp_acc_data->intra_skip_count; - this_tile->fp_data.new_mv_count += fp_acc_data->new_mv_count; - this_tile->fp_data.mvcount += fp_acc_data->mvcount; - this_tile->fp_data.sum_mvr += fp_acc_data->sum_mvr; - this_tile->fp_data.sum_mvr_abs += fp_acc_data->sum_mvr_abs; - this_tile->fp_data.sum_mvc += fp_acc_data->sum_mvc; - this_tile->fp_data.sum_mvc_abs += fp_acc_data->sum_mvc_abs; - this_tile->fp_data.sum_mvrs += fp_acc_data->sum_mvrs; - this_tile->fp_data.sum_mvcs += fp_acc_data->sum_mvcs; - this_tile->fp_data.sum_in_vectors += fp_acc_data->sum_in_vectors; - this_tile->fp_data.intra_smooth_count += fp_acc_data->intra_smooth_count; - this_tile->fp_data.image_data_start_row = - VPXMIN(this_tile->fp_data.image_data_start_row, - fp_acc_data->image_data_start_row) == INVALID_ROW - ? VPXMAX(this_tile->fp_data.image_data_start_row, - fp_acc_data->image_data_start_row) - : VPXMIN(this_tile->fp_data.image_data_start_row, - fp_acc_data->image_data_start_row); -} - -#if CONFIG_RATE_CTRL -static void store_fp_motion_vector(VP9_COMP *cpi, const MV *mv, - const int mb_row, const int mb_col, - MV_REFERENCE_FRAME frame_type, - const int mv_idx) { - VP9_COMMON *const cm = &cpi->common; - const int mb_index = mb_row * cm->mb_cols + mb_col; - MOTION_VECTOR_INFO *this_motion_vector_info = - &cpi->fp_motion_vector_info[mb_index]; - this_motion_vector_info->ref_frame[mv_idx] = frame_type; - if (frame_type != INTRA_FRAME) { - this_motion_vector_info->mv[mv_idx].as_mv = *mv; - } -} -#endif // CONFIG_RATE_CTRL - -#define NZ_MOTION_PENALTY 128 -#define INTRA_MODE_PENALTY 1024 -void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td, - FIRSTPASS_DATA *fp_acc_data, - TileDataEnc *tile_data, MV *best_ref_mv, - int mb_row) { - int mb_col; - MACROBLOCK *const x = &td->mb; - VP9_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &x->e_mbd; - TileInfo tile = tile_data->tile_info; - const int mb_col_start = ROUND_POWER_OF_TWO(tile.mi_col_start, 1); - const int mb_col_end = ROUND_POWER_OF_TWO(tile.mi_col_end, 1); - struct macroblock_plane *const p = x->plane; - struct macroblockd_plane *const pd = xd->plane; - const PICK_MODE_CONTEXT *ctx = &td->pc_root->none; - int i, c; - int num_mb_cols = get_num_cols(tile_data->tile_info, 1); - - int recon_yoffset, recon_uvoffset; - const int intrapenalty = INTRA_MODE_PENALTY; - const MV zero_mv = { 0, 0 }; - int recon_y_stride, recon_uv_stride, uv_mb_height; - - YV12_BUFFER_CONFIG *const lst_yv12 = get_ref_frame_buffer(cpi, LAST_FRAME); - YV12_BUFFER_CONFIG *gld_yv12 = get_ref_frame_buffer(cpi, GOLDEN_FRAME); - YV12_BUFFER_CONFIG *const new_yv12 = get_frame_new_buffer(cm); - const YV12_BUFFER_CONFIG *first_ref_buf = lst_yv12; - - MODE_INFO mi_above, mi_left; - - double mb_intra_factor; - double mb_brightness_factor; - double mb_neutral_count; - int scaled_low_intra_thresh = scale_sse_threshold(cm, LOW_I_THRESH); - - MV *first_top_mv = &tile_data->firstpass_top_mv; - MV last_nonzero_mv = { 0, 0 }; - - // First pass code requires valid last and new frame buffers. - assert(new_yv12 != NULL); - assert(frame_is_intra_only(cm) || (lst_yv12 != NULL)); - - xd->mi = cm->mi_grid_visible + xd->mi_stride * (mb_row << 1) + mb_col_start; - xd->mi[0] = cm->mi + xd->mi_stride * (mb_row << 1) + mb_col_start; - - for (i = 0; i < MAX_MB_PLANE; ++i) { - p[i].coeff = ctx->coeff_pbuf[i][1]; - p[i].qcoeff = ctx->qcoeff_pbuf[i][1]; - pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1]; - p[i].eobs = ctx->eobs_pbuf[i][1]; - } - - recon_y_stride = new_yv12->y_stride; - recon_uv_stride = new_yv12->uv_stride; - uv_mb_height = 16 >> (new_yv12->y_height > new_yv12->uv_height); - - // Reset above block coeffs. - recon_yoffset = (mb_row * recon_y_stride * 16) + mb_col_start * 16; - recon_uvoffset = - (mb_row * recon_uv_stride * uv_mb_height) + mb_col_start * uv_mb_height; - - // Set up limit values for motion vectors to prevent them extending - // outside the UMV borders. - x->mv_limits.row_min = -((mb_row * 16) + BORDER_MV_PIXELS_B16); - x->mv_limits.row_max = - ((cm->mb_rows - 1 - mb_row) * 16) + BORDER_MV_PIXELS_B16; - - for (mb_col = mb_col_start, c = 0; mb_col < mb_col_end; ++mb_col, c++) { - int this_error; - int this_intra_error; - const int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row); - const BLOCK_SIZE bsize = get_bsize(cm, mb_row, mb_col); - double log_intra; - int level_sample; - const int mb_index = mb_row * cm->mb_cols + mb_col; - - (*(cpi->row_mt_sync_read_ptr))(&tile_data->row_mt_sync, mb_row, c); - - if (mb_col == mb_col_start) { - last_nonzero_mv = *first_top_mv; - } - - // Adjust to the next column of MBs. - x->plane[0].src.buf = cpi->Source->y_buffer + - mb_row * 16 * x->plane[0].src.stride + mb_col * 16; - x->plane[1].src.buf = cpi->Source->u_buffer + - mb_row * uv_mb_height * x->plane[1].src.stride + - mb_col * uv_mb_height; - x->plane[2].src.buf = cpi->Source->v_buffer + - mb_row * uv_mb_height * x->plane[1].src.stride + - mb_col * uv_mb_height; - - vpx_clear_system_state(); - - xd->plane[0].dst.buf = new_yv12->y_buffer + recon_yoffset; - xd->plane[1].dst.buf = new_yv12->u_buffer + recon_uvoffset; - xd->plane[2].dst.buf = new_yv12->v_buffer + recon_uvoffset; - xd->mi[0]->sb_type = bsize; - xd->mi[0]->ref_frame[0] = INTRA_FRAME; - set_mi_row_col(xd, &tile, mb_row << 1, num_8x8_blocks_high_lookup[bsize], - mb_col << 1, num_8x8_blocks_wide_lookup[bsize], cm->mi_rows, - cm->mi_cols); - // Are edges available for intra prediction? - // Since the firstpass does not populate the mi_grid_visible, - // above_mi/left_mi must be overwritten with a nonzero value when edges - // are available. Required by vp9_predict_intra_block(). - xd->above_mi = (mb_row != 0) ? &mi_above : NULL; - xd->left_mi = ((mb_col << 1) > tile.mi_col_start) ? &mi_left : NULL; - - // Do intra 16x16 prediction. - x->skip_encode = 0; - x->fp_src_pred = 0; - // Do intra prediction based on source pixels for tile boundaries - if (mb_col == mb_col_start && mb_col != 0) { - xd->left_mi = &mi_left; - x->fp_src_pred = 1; - } - xd->mi[0]->mode = DC_PRED; - xd->mi[0]->tx_size = - use_dc_pred ? (bsize >= BLOCK_16X16 ? TX_16X16 : TX_8X8) : TX_4X4; - // Fix - zero the 16x16 block first. This ensures correct this_error for - // block sizes smaller than 16x16. - vp9_zero_array(x->plane[0].src_diff, 256); - vp9_encode_intra_block_plane(x, bsize, 0, 0); - this_error = vpx_get_mb_ss(x->plane[0].src_diff); - this_intra_error = this_error; - - // Keep a record of blocks that have very low intra error residual - // (i.e. are in effect completely flat and untextured in the intra - // domain). In natural videos this is uncommon, but it is much more - // common in animations, graphics and screen content, so may be used - // as a signal to detect these types of content. - if (this_error < get_ul_intra_threshold(cm)) { - ++(fp_acc_data->intra_skip_count); - } else if ((mb_col > 0) && - (fp_acc_data->image_data_start_row == INVALID_ROW)) { - fp_acc_data->image_data_start_row = mb_row; - } - - // Blocks that are mainly smooth in the intra domain. - // Some special accounting for CQ but also these are better for testing - // noise levels. - if (this_error < get_smooth_intra_threshold(cm)) { - ++(fp_acc_data->intra_smooth_count); - } - - // Special case noise measurement for first frame. - if (cm->current_video_frame == 0) { - if (this_intra_error < scale_sse_threshold(cm, LOW_I_THRESH)) { - fp_acc_data->frame_noise_energy += fp_estimate_block_noise(x, bsize); - } else { - fp_acc_data->frame_noise_energy += (int64_t)SECTION_NOISE_DEF; - } - } - -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - switch (cm->bit_depth) { - case VPX_BITS_8: break; - case VPX_BITS_10: this_error >>= 4; break; - default: - assert(cm->bit_depth == VPX_BITS_12); - this_error >>= 8; - break; - } - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - vpx_clear_system_state(); - log_intra = log(this_error + 1.0); - if (log_intra < 10.0) { - mb_intra_factor = 1.0 + ((10.0 - log_intra) * 0.05); - fp_acc_data->intra_factor += mb_intra_factor; - if (cpi->row_mt_bit_exact) - cpi->twopass.fp_mb_float_stats[mb_index].frame_mb_intra_factor = - mb_intra_factor; - } else { - fp_acc_data->intra_factor += 1.0; - if (cpi->row_mt_bit_exact) - cpi->twopass.fp_mb_float_stats[mb_index].frame_mb_intra_factor = 1.0; - } - -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) - level_sample = CONVERT_TO_SHORTPTR(x->plane[0].src.buf)[0]; - else - level_sample = x->plane[0].src.buf[0]; -#else - level_sample = x->plane[0].src.buf[0]; -#endif - if ((level_sample < DARK_THRESH) && (log_intra < 9.0)) { - mb_brightness_factor = 1.0 + (0.01 * (DARK_THRESH - level_sample)); - fp_acc_data->brightness_factor += mb_brightness_factor; - if (cpi->row_mt_bit_exact) - cpi->twopass.fp_mb_float_stats[mb_index].frame_mb_brightness_factor = - mb_brightness_factor; - } else { - fp_acc_data->brightness_factor += 1.0; - if (cpi->row_mt_bit_exact) - cpi->twopass.fp_mb_float_stats[mb_index].frame_mb_brightness_factor = - 1.0; - } - - // Intrapenalty below deals with situations where the intra and inter - // error scores are very low (e.g. a plain black frame). - // We do not have special cases in first pass for 0,0 and nearest etc so - // all inter modes carry an overhead cost estimate for the mv. - // When the error score is very low this causes us to pick all or lots of - // INTRA modes and throw lots of key frames. - // This penalty adds a cost matching that of a 0,0 mv to the intra case. - this_error += intrapenalty; - - // Accumulate the intra error. - fp_acc_data->intra_error += (int64_t)this_error; - - // Set up limit values for motion vectors to prevent them extending - // outside the UMV borders. - x->mv_limits.col_min = -((mb_col * 16) + BORDER_MV_PIXELS_B16); - x->mv_limits.col_max = - ((cm->mb_cols - 1 - mb_col) * 16) + BORDER_MV_PIXELS_B16; - - // Other than for intra-only frame do a motion search. - if (!frame_is_intra_only(cm)) { - int tmp_err, motion_error, this_motion_error, raw_motion_error; - // Assume 0,0 motion with no mv overhead. - MV mv = { 0, 0 }, tmp_mv = { 0, 0 }; - struct buf_2d unscaled_last_source_buf_2d; - vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize]; - -#if CONFIG_RATE_CTRL - if (cpi->oxcf.use_simple_encode_api) { - // Store zero mv as default - store_fp_motion_vector(cpi, &mv, mb_row, mb_col, LAST_FRAME, 0); - } -#endif // CONFIG_RAGE_CTRL - - xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset; -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - motion_error = highbd_get_prediction_error( - bsize, &x->plane[0].src, &xd->plane[0].pre[0], xd->bd); - this_motion_error = highbd_get_prediction_error( - bsize, &x->plane[0].src, &xd->plane[0].pre[0], 8); - } else { - motion_error = - get_prediction_error(bsize, &x->plane[0].src, &xd->plane[0].pre[0]); - this_motion_error = motion_error; - } -#else - motion_error = - get_prediction_error(bsize, &x->plane[0].src, &xd->plane[0].pre[0]); - this_motion_error = motion_error; -#endif // CONFIG_VP9_HIGHBITDEPTH - - // Compute the motion error of the 0,0 motion using the last source - // frame as the reference. Skip the further motion search on - // reconstructed frame if this error is very small. - unscaled_last_source_buf_2d.buf = - cpi->unscaled_last_source->y_buffer + recon_yoffset; - unscaled_last_source_buf_2d.stride = cpi->unscaled_last_source->y_stride; -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - raw_motion_error = highbd_get_prediction_error( - bsize, &x->plane[0].src, &unscaled_last_source_buf_2d, xd->bd); - } else { - raw_motion_error = get_prediction_error(bsize, &x->plane[0].src, - &unscaled_last_source_buf_2d); - } -#else - raw_motion_error = get_prediction_error(bsize, &x->plane[0].src, - &unscaled_last_source_buf_2d); -#endif // CONFIG_VP9_HIGHBITDEPTH - - if (raw_motion_error > NZ_MOTION_PENALTY) { - // Test last reference frame using the previous best mv as the - // starting point (best reference) for the search. - first_pass_motion_search(cpi, x, best_ref_mv, &mv, &motion_error); - - v_fn_ptr.vf = get_block_variance_fn(bsize); -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - v_fn_ptr.vf = highbd_get_block_variance_fn(bsize, xd->bd); - } -#endif // CONFIG_VP9_HIGHBITDEPTH - this_motion_error = - vp9_get_mvpred_var(x, &mv, best_ref_mv, &v_fn_ptr, 0); - - // If the current best reference mv is not centered on 0,0 then do a - // 0,0 based search as well. - if (!is_zero_mv(best_ref_mv)) { - tmp_err = INT_MAX; - first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv, &tmp_err); - - if (tmp_err < motion_error) { - motion_error = tmp_err; - mv = tmp_mv; - this_motion_error = - vp9_get_mvpred_var(x, &tmp_mv, &zero_mv, &v_fn_ptr, 0); - } - } -#if CONFIG_RATE_CTRL - if (cpi->oxcf.use_simple_encode_api) { - store_fp_motion_vector(cpi, &mv, mb_row, mb_col, LAST_FRAME, 0); - } -#endif // CONFIG_RAGE_CTRL - - // Search in an older reference frame. - if ((cm->current_video_frame > 1) && gld_yv12 != NULL) { - // Assume 0,0 motion with no mv overhead. - int gf_motion_error; - - xd->plane[0].pre[0].buf = gld_yv12->y_buffer + recon_yoffset; -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - gf_motion_error = highbd_get_prediction_error( - bsize, &x->plane[0].src, &xd->plane[0].pre[0], xd->bd); - } else { - gf_motion_error = get_prediction_error(bsize, &x->plane[0].src, - &xd->plane[0].pre[0]); - } -#else - gf_motion_error = get_prediction_error(bsize, &x->plane[0].src, - &xd->plane[0].pre[0]); -#endif // CONFIG_VP9_HIGHBITDEPTH - - first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv, &gf_motion_error); -#if CONFIG_RATE_CTRL - if (cpi->oxcf.use_simple_encode_api) { - store_fp_motion_vector(cpi, &tmp_mv, mb_row, mb_col, GOLDEN_FRAME, - 1); - } -#endif // CONFIG_RAGE_CTRL - - if (gf_motion_error < motion_error && gf_motion_error < this_error) - ++(fp_acc_data->second_ref_count); - - // Reset to last frame as reference buffer. - xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset; - xd->plane[1].pre[0].buf = first_ref_buf->u_buffer + recon_uvoffset; - xd->plane[2].pre[0].buf = first_ref_buf->v_buffer + recon_uvoffset; - - // In accumulating a score for the older reference frame take the - // best of the motion predicted score and the intra coded error - // (just as will be done for) accumulation of "coded_error" for - // the last frame. - if (gf_motion_error < this_error) - fp_acc_data->sr_coded_error += gf_motion_error; - else - fp_acc_data->sr_coded_error += this_error; - } else { - fp_acc_data->sr_coded_error += motion_error; - } - } else { - fp_acc_data->sr_coded_error += motion_error; - } - - // Start by assuming that intra mode is best. - best_ref_mv->row = 0; - best_ref_mv->col = 0; - - if (motion_error <= this_error) { - vpx_clear_system_state(); - - // Keep a count of cases where the inter and intra were very close - // and very low. This helps with scene cut detection for example in - // cropped clips with black bars at the sides or top and bottom. - if (((this_error - intrapenalty) * 9 <= motion_error * 10) && - (this_error < (2 * intrapenalty))) { - fp_acc_data->neutral_count += 1.0; - if (cpi->row_mt_bit_exact) - cpi->twopass.fp_mb_float_stats[mb_index].frame_mb_neutral_count = - 1.0; - // Also track cases where the intra is not much worse than the inter - // and use this in limiting the GF/arf group length. - } else if ((this_error > NCOUNT_INTRA_THRESH) && - (this_error < (NCOUNT_INTRA_FACTOR * motion_error))) { - mb_neutral_count = - (double)motion_error / DOUBLE_DIVIDE_CHECK((double)this_error); - fp_acc_data->neutral_count += mb_neutral_count; - if (cpi->row_mt_bit_exact) - cpi->twopass.fp_mb_float_stats[mb_index].frame_mb_neutral_count = - mb_neutral_count; - } - - mv.row *= 8; - mv.col *= 8; - this_error = motion_error; - xd->mi[0]->mode = NEWMV; - xd->mi[0]->mv[0].as_mv = mv; - xd->mi[0]->tx_size = TX_4X4; - xd->mi[0]->ref_frame[0] = LAST_FRAME; - xd->mi[0]->ref_frame[1] = NO_REF_FRAME; - vp9_build_inter_predictors_sby(xd, mb_row << 1, mb_col << 1, bsize); - vp9_encode_sby_pass1(x, bsize); - fp_acc_data->sum_mvr += mv.row; - fp_acc_data->sum_mvr_abs += abs(mv.row); - fp_acc_data->sum_mvc += mv.col; - fp_acc_data->sum_mvc_abs += abs(mv.col); - fp_acc_data->sum_mvrs += mv.row * mv.row; - fp_acc_data->sum_mvcs += mv.col * mv.col; - ++(fp_acc_data->intercount); - - *best_ref_mv = mv; - - if (!is_zero_mv(&mv)) { - ++(fp_acc_data->mvcount); - if (!is_equal_mv(&mv, &last_nonzero_mv)) { - ++(fp_acc_data->new_mv_count); - } - last_nonzero_mv = mv; - - // Does the row vector point inwards or outwards? - if (mb_row < cm->mb_rows / 2) { - if (mv.row > 0) - --(fp_acc_data->sum_in_vectors); - else if (mv.row < 0) - ++(fp_acc_data->sum_in_vectors); - } else if (mb_row > cm->mb_rows / 2) { - if (mv.row > 0) - ++(fp_acc_data->sum_in_vectors); - else if (mv.row < 0) - --(fp_acc_data->sum_in_vectors); - } - - // Does the col vector point inwards or outwards? - if (mb_col < cm->mb_cols / 2) { - if (mv.col > 0) - --(fp_acc_data->sum_in_vectors); - else if (mv.col < 0) - ++(fp_acc_data->sum_in_vectors); - } else if (mb_col > cm->mb_cols / 2) { - if (mv.col > 0) - ++(fp_acc_data->sum_in_vectors); - else if (mv.col < 0) - --(fp_acc_data->sum_in_vectors); - } - } - if (this_intra_error < scaled_low_intra_thresh) { - fp_acc_data->frame_noise_energy += fp_estimate_block_noise(x, bsize); - } else { - fp_acc_data->frame_noise_energy += (int64_t)SECTION_NOISE_DEF; - } - } else { // Intra < inter error - if (this_intra_error < scaled_low_intra_thresh) { - fp_acc_data->frame_noise_energy += fp_estimate_block_noise(x, bsize); - if (this_motion_error < scaled_low_intra_thresh) { - fp_acc_data->intra_count_low += 1.0; - } else { - fp_acc_data->intra_count_high += 1.0; - } - } else { - fp_acc_data->frame_noise_energy += (int64_t)SECTION_NOISE_DEF; - fp_acc_data->intra_count_high += 1.0; - } - } - } else { - fp_acc_data->sr_coded_error += (int64_t)this_error; -#if CONFIG_RATE_CTRL - if (cpi->oxcf.use_simple_encode_api) { - store_fp_motion_vector(cpi, NULL, mb_row, mb_col, INTRA_FRAME, 0); - } -#endif // CONFIG_RAGE_CTRL - } - fp_acc_data->coded_error += (int64_t)this_error; - - if (mb_col == mb_col_start) { - *first_top_mv = last_nonzero_mv; - } - recon_yoffset += 16; - recon_uvoffset += uv_mb_height; - - // Accumulate row level stats to the corresponding tile stats - if (cpi->row_mt && mb_col == mb_col_end - 1) - accumulate_fp_mb_row_stat(tile_data, fp_acc_data); - - (*(cpi->row_mt_sync_write_ptr))(&tile_data->row_mt_sync, mb_row, c, - num_mb_cols); - } - vpx_clear_system_state(); -} - -static void first_pass_encode(VP9_COMP *cpi, FIRSTPASS_DATA *fp_acc_data) { - VP9_COMMON *const cm = &cpi->common; - int mb_row; - TileDataEnc tile_data; - TileInfo *tile = &tile_data.tile_info; - MV zero_mv = { 0, 0 }; - MV best_ref_mv; - // Tiling is ignored in the first pass. - vp9_tile_init(tile, cm, 0, 0); - tile_data.firstpass_top_mv = zero_mv; -#if CONFIG_RATE_CTRL - if (cpi->oxcf.use_simple_encode_api) { - fp_motion_vector_info_reset(cpi->frame_info.frame_width, - cpi->frame_info.frame_height, - cpi->fp_motion_vector_info); - } -#endif - - for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) { - best_ref_mv = zero_mv; - vp9_first_pass_encode_tile_mb_row(cpi, &cpi->td, fp_acc_data, &tile_data, - &best_ref_mv, mb_row); - } -} - -void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) { - MACROBLOCK *const x = &cpi->td.mb; - VP9_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &x->e_mbd; - TWO_PASS *twopass = &cpi->twopass; - - YV12_BUFFER_CONFIG *const lst_yv12 = get_ref_frame_buffer(cpi, LAST_FRAME); - YV12_BUFFER_CONFIG *gld_yv12 = get_ref_frame_buffer(cpi, GOLDEN_FRAME); - YV12_BUFFER_CONFIG *const new_yv12 = get_frame_new_buffer(cm); - const YV12_BUFFER_CONFIG *first_ref_buf = lst_yv12; - - BufferPool *const pool = cm->buffer_pool; - - FIRSTPASS_DATA fp_temp_data; - FIRSTPASS_DATA *fp_acc_data = &fp_temp_data; - - vpx_clear_system_state(); - vp9_zero(fp_temp_data); - fp_acc_data->image_data_start_row = INVALID_ROW; - - // First pass code requires valid last and new frame buffers. - assert(new_yv12 != NULL); - assert(frame_is_intra_only(cm) || (lst_yv12 != NULL)); - - set_first_pass_params(cpi); - vp9_set_quantizer(cpi, find_fp_qindex(cm->bit_depth)); - - vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y); - - vp9_setup_src_planes(x, cpi->Source, 0, 0); - vp9_setup_dst_planes(xd->plane, new_yv12, 0, 0); - - if (!frame_is_intra_only(cm)) { - vp9_setup_pre_planes(xd, 0, first_ref_buf, 0, 0, NULL); - } - - xd->mi = cm->mi_grid_visible; - xd->mi[0] = cm->mi; - - vp9_frame_init_quantizer(cpi); - - x->skip_recode = 0; - - vp9_init_mv_probs(cm); - vp9_initialize_rd_consts(cpi); - - cm->log2_tile_rows = 0; - - if (cpi->row_mt_bit_exact && cpi->twopass.fp_mb_float_stats == NULL) - CHECK_MEM_ERROR( - &cm->error, cpi->twopass.fp_mb_float_stats, - vpx_calloc(cm->MBs * sizeof(*cpi->twopass.fp_mb_float_stats), 1)); - - { - FIRSTPASS_STATS fps; - TileDataEnc *first_tile_col; - if (!cpi->row_mt) { - cm->log2_tile_cols = 0; - cpi->row_mt_sync_read_ptr = vp9_row_mt_sync_read_dummy; - cpi->row_mt_sync_write_ptr = vp9_row_mt_sync_write_dummy; - first_pass_encode(cpi, fp_acc_data); - first_pass_stat_calc(cpi, &fps, fp_acc_data); - } else { - cpi->row_mt_sync_read_ptr = vp9_row_mt_sync_read; - cpi->row_mt_sync_write_ptr = vp9_row_mt_sync_write; - if (cpi->row_mt_bit_exact) { - cm->log2_tile_cols = 0; - vp9_zero_array(cpi->twopass.fp_mb_float_stats, cm->MBs); - } - vp9_encode_fp_row_mt(cpi); - first_tile_col = &cpi->tile_data[0]; - if (cpi->row_mt_bit_exact) - accumulate_floating_point_stats(cpi, first_tile_col); - first_pass_stat_calc(cpi, &fps, &(first_tile_col->fp_data)); - } - - // Don't allow a value of 0 for duration. - // (Section duration is also defaulted to minimum of 1.0). - fps.duration = VPXMAX(1.0, (double)(source->ts_end - source->ts_start)); - - // Don't want to do output stats with a stack variable! - twopass->this_frame_stats = fps; - output_stats(&twopass->this_frame_stats); - accumulate_stats(&twopass->total_stats, &fps); - } - - // Copy the previous Last Frame back into gf and arf buffers if - // the prediction is good enough... but also don't allow it to lag too far. - if ((twopass->sr_update_lag > 3) || - ((cm->current_video_frame > 0) && - (twopass->this_frame_stats.pcnt_inter > 0.20) && - ((twopass->this_frame_stats.intra_error / - DOUBLE_DIVIDE_CHECK(twopass->this_frame_stats.coded_error)) > 2.0))) { - if (gld_yv12 != NULL) { - ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx], - cm->ref_frame_map[cpi->lst_fb_idx]); - } - twopass->sr_update_lag = 1; - } else { - ++twopass->sr_update_lag; - } - - vpx_extend_frame_borders(new_yv12); - - // The frame we just compressed now becomes the last frame. - ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->lst_fb_idx], - cm->new_fb_idx); - - // Special case for the first frame. Copy into the GF buffer as a second - // reference. - if (cm->current_video_frame == 0 && cpi->gld_fb_idx != INVALID_IDX) { - ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx], - cm->ref_frame_map[cpi->lst_fb_idx]); - } - - // In the first pass, every frame is considered as a show frame. - update_frame_indexes(cm, /*show_frame=*/1); - if (cpi->use_svc) vp9_inc_frame_in_layer(cpi); -} - -static const double q_pow_term[(QINDEX_RANGE >> 5) + 1] = { 0.65, 0.70, 0.75, - 0.85, 0.90, 0.90, - 0.90, 1.00, 1.25 }; - -static double calc_correction_factor(double err_per_mb, double err_divisor, - int q) { - const double error_term = err_per_mb / DOUBLE_DIVIDE_CHECK(err_divisor); - const int index = q >> 5; - double power_term; - - assert((index >= 0) && (index < (QINDEX_RANGE >> 5))); - - // Adjustment based on quantizer to the power term. - power_term = - q_pow_term[index] + - (((q_pow_term[index + 1] - q_pow_term[index]) * (q % 32)) / 32.0); - - // Calculate correction factor. - if (power_term < 1.0) assert(error_term >= 0.0); - - return fclamp(pow(error_term, power_term), 0.05, 5.0); -} - -static double wq_err_divisor(VP9_COMP *cpi) { - const VP9_COMMON *const cm = &cpi->common; - unsigned int screen_area = (cm->width * cm->height); - - // Use a different error per mb factor for calculating boost for - // different formats. - if (screen_area <= 640 * 360) { - return 115.0; - } else if (screen_area < 1280 * 720) { - return 125.0; - } else if (screen_area <= 1920 * 1080) { - return 130.0; - } else if (screen_area < 3840 * 2160) { - return 150.0; - } - - // Fall through to here only for 4K and above. - return 200.0; -} - -#define NOISE_FACTOR_MIN 0.9 -#define NOISE_FACTOR_MAX 1.1 -static int get_twopass_worst_quality(VP9_COMP *cpi, const double section_err, - double inactive_zone, double section_noise, - int section_target_bandwidth) { - const RATE_CONTROL *const rc = &cpi->rc; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - TWO_PASS *const twopass = &cpi->twopass; - double last_group_rate_err; - - // Clamp the target rate to VBR min / max limts. - const int target_rate = - vp9_rc_clamp_pframe_target_size(cpi, section_target_bandwidth); - double noise_factor = pow((section_noise / SECTION_NOISE_DEF), 0.5); - noise_factor = fclamp(noise_factor, NOISE_FACTOR_MIN, NOISE_FACTOR_MAX); - inactive_zone = fclamp(inactive_zone, 0.0, 1.0); - -// TODO(jimbankoski): remove #if here or below when this has been -// well tested. -#if CONFIG_ALWAYS_ADJUST_BPM - // based on recent history adjust expectations of bits per macroblock. - last_group_rate_err = - (double)twopass->rolling_arf_group_actual_bits / - DOUBLE_DIVIDE_CHECK((double)twopass->rolling_arf_group_target_bits); - last_group_rate_err = VPXMAX(0.25, VPXMIN(4.0, last_group_rate_err)); - twopass->bpm_factor *= (3.0 + last_group_rate_err) / 4.0; - twopass->bpm_factor = VPXMAX(0.25, VPXMIN(4.0, twopass->bpm_factor)); -#endif - - if (target_rate <= 0) { - return rc->worst_quality; // Highest value allowed - } else { - const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE) - ? cpi->initial_mbs - : cpi->common.MBs; - const double active_pct = VPXMAX(0.01, 1.0 - inactive_zone); - const int active_mbs = (int)VPXMAX(1, (double)num_mbs * active_pct); - const double av_err_per_mb = section_err / active_pct; - const double speed_term = 1.0 + 0.04 * oxcf->speed; - const uint64_t target_norm_bits_per_mb = - ((uint64_t)target_rate << BPER_MB_NORMBITS) / active_mbs; - int q; - -// TODO(jimbankoski): remove #if here or above when this has been -// well tested. -#if !CONFIG_ALWAYS_ADJUST_BPM - // based on recent history adjust expectations of bits per macroblock. - last_group_rate_err = - (double)twopass->rolling_arf_group_actual_bits / - DOUBLE_DIVIDE_CHECK((double)twopass->rolling_arf_group_target_bits); - last_group_rate_err = VPXMAX(0.25, VPXMIN(4.0, last_group_rate_err)); - twopass->bpm_factor *= (3.0 + last_group_rate_err) / 4.0; - twopass->bpm_factor = VPXMAX(0.25, VPXMIN(4.0, twopass->bpm_factor)); -#endif - - // Try and pick a max Q that will be high enough to encode the - // content at the given rate. - for (q = rc->best_quality; q < rc->worst_quality; ++q) { - const double factor = - calc_correction_factor(av_err_per_mb, wq_err_divisor(cpi), q); - const int bits_per_mb = vp9_rc_bits_per_mb( - INTER_FRAME, q, - factor * speed_term * cpi->twopass.bpm_factor * noise_factor, - cpi->common.bit_depth); - if ((uint64_t)bits_per_mb <= target_norm_bits_per_mb) break; - } - - // Restriction on active max q for constrained quality mode. - if (cpi->oxcf.rc_mode == VPX_CQ) q = VPXMAX(q, oxcf->cq_level); - return q; - } -} - -static void setup_rf_level_maxq(VP9_COMP *cpi) { - int i; - RATE_CONTROL *const rc = &cpi->rc; - for (i = INTER_NORMAL; i < RATE_FACTOR_LEVELS; ++i) { - int qdelta = vp9_frame_type_qdelta(cpi, i, rc->worst_quality); - rc->rf_level_maxq[i] = VPXMAX(rc->worst_quality + qdelta, rc->best_quality); - } -} - -static void init_subsampling(VP9_COMP *cpi) { - const VP9_COMMON *const cm = &cpi->common; - RATE_CONTROL *const rc = &cpi->rc; - const int w = cm->width; - const int h = cm->height; - int i; - - for (i = 0; i < FRAME_SCALE_STEPS; ++i) { - // Note: Frames with odd-sized dimensions may result from this scaling. - rc->frame_width[i] = (w * 16) / frame_scale_factor[i]; - rc->frame_height[i] = (h * 16) / frame_scale_factor[i]; - } - - setup_rf_level_maxq(cpi); -} - -void calculate_coded_size(VP9_COMP *cpi, int *scaled_frame_width, - int *scaled_frame_height) { - RATE_CONTROL *const rc = &cpi->rc; - *scaled_frame_width = rc->frame_width[rc->frame_size_selector]; - *scaled_frame_height = rc->frame_height[rc->frame_size_selector]; -} - -void vp9_init_second_pass(VP9_COMP *cpi) { - VP9EncoderConfig *const oxcf = &cpi->oxcf; - RATE_CONTROL *const rc = &cpi->rc; - TWO_PASS *const twopass = &cpi->twopass; - double frame_rate; - FIRSTPASS_STATS *stats; - - zero_stats(&twopass->total_stats); - zero_stats(&twopass->total_left_stats); - - if (!twopass->stats_in_end) return; - - stats = &twopass->total_stats; - - *stats = *twopass->stats_in_end; - twopass->total_left_stats = *stats; - - // Scan the first pass file and calculate a modified score for each - // frame that is used to distribute bits. The modified score is assumed - // to provide a linear basis for bit allocation. I.e., a frame A with a score - // that is double that of frame B will be allocated 2x as many bits. - { - double modified_score_total = 0.0; - const FIRSTPASS_STATS *s = twopass->stats_in; - double av_err; - - if (oxcf->vbr_corpus_complexity) { - twopass->mean_mod_score = (double)oxcf->vbr_corpus_complexity / 10.0; - av_err = get_distribution_av_err(cpi, twopass); - } else { - av_err = get_distribution_av_err(cpi, twopass); - // The first scan is unclamped and gives a raw average. - while (s < twopass->stats_in_end) { - modified_score_total += calculate_mod_frame_score(cpi, oxcf, s, av_err); - ++s; - } - - // The average error from this first scan is used to define the midpoint - // error for the rate distribution function. - twopass->mean_mod_score = - modified_score_total / DOUBLE_DIVIDE_CHECK(stats->count); - } - - // Second scan using clamps based on the previous cycle average. - // This may modify the total and average somewhat but we don't bother with - // further iterations. - modified_score_total = 0.0; - s = twopass->stats_in; - while (s < twopass->stats_in_end) { - modified_score_total += - calculate_norm_frame_score(cpi, twopass, oxcf, s, av_err); - ++s; - } - twopass->normalized_score_left = modified_score_total; - - // If using Corpus wide VBR mode then update the clip target bandwidth to - // reflect how the clip compares to the rest of the corpus. - if (oxcf->vbr_corpus_complexity) { - oxcf->target_bandwidth = - (int64_t)((double)oxcf->target_bandwidth * - (twopass->normalized_score_left / stats->count)); - } - -#if COMPLEXITY_STATS_OUTPUT - { - FILE *compstats; - compstats = fopen("complexity_stats.stt", "a"); - fprintf(compstats, "%10.3lf\n", - twopass->normalized_score_left / stats->count); - fclose(compstats); - } -#endif - } - - frame_rate = 10000000.0 * stats->count / stats->duration; - // Each frame can have a different duration, as the frame rate in the source - // isn't guaranteed to be constant. The frame rate prior to the first frame - // encoded in the second pass is a guess. However, the sum duration is not. - // It is calculated based on the actual durations of all frames from the - // first pass. - vp9_new_framerate(cpi, frame_rate); - twopass->bits_left = - (int64_t)(stats->duration * oxcf->target_bandwidth / 10000000.0); - - // This variable monitors how far behind the second ref update is lagging. - twopass->sr_update_lag = 1; - - // Reset the vbr bits off target counters - rc->vbr_bits_off_target = 0; - rc->vbr_bits_off_target_fast = 0; - rc->rate_error_estimate = 0; - - // Static sequence monitor variables. - twopass->kf_zeromotion_pct = 100; - twopass->last_kfgroup_zeromotion_pct = 100; - - // Initialize bits per macro_block estimate correction factor. - twopass->bpm_factor = 1.0; - // Initialize actual and target bits counters for ARF groups so that - // at the start we have a neutral bpm adjustment. - twopass->rolling_arf_group_target_bits = 1; - twopass->rolling_arf_group_actual_bits = 1; - - if (oxcf->resize_mode != RESIZE_NONE) { - init_subsampling(cpi); - } - - // Initialize the arnr strangth adjustment to 0 - twopass->arnr_strength_adjustment = 0; -} - -/* This function considers how the quality of prediction may be deteriorating - * with distance. It compares the coded error for the last frame and the - * second reference frame (usually two frames old) and also applies a factor - * based on the extent of INTRA coding. - * - * The decay factor is then used to reduce the contribution of frames further - * from the alt-ref or golden frame, to the bitrate boost calculation for that - * alt-ref or golden frame. - */ -static double get_sr_decay_rate(const TWO_PASS *const twopass, - const FIRSTPASS_STATS *frame) { - double sr_diff = (frame->sr_coded_error - frame->coded_error); - double sr_decay = 1.0; - - // Do nothing if the second ref to last frame error difference is - // very small or even negative. - if ((sr_diff > LOW_SR_DIFF_TRHESH)) { - const double sr_diff_part = - twopass->sr_diff_factor * ((sr_diff * 0.25) / frame->intra_error); - double modified_pct_inter = frame->pcnt_inter; - double modified_pcnt_intra; - - if ((frame->coded_error > LOW_CODED_ERR_PER_MB) && - ((frame->intra_error / DOUBLE_DIVIDE_CHECK(frame->coded_error)) < - (double)NCOUNT_FRAME_II_THRESH)) { - modified_pct_inter = - frame->pcnt_inter + frame->pcnt_intra_low - frame->pcnt_neutral; - } - modified_pcnt_intra = 100 * (1.0 - modified_pct_inter); - - sr_decay = 1.0 - sr_diff_part - (INTRA_PART * modified_pcnt_intra); - } - return VPXMAX(sr_decay, twopass->sr_default_decay_limit); -} - -// This function gives an estimate of how badly we believe the prediction -// quality is decaying from frame to frame. -static double get_zero_motion_factor(const TWO_PASS *const twopass, - const FIRSTPASS_STATS *frame_stats) { - const double zero_motion_pct = - frame_stats->pcnt_inter - frame_stats->pcnt_motion; - double sr_decay = get_sr_decay_rate(twopass, frame_stats); - return VPXMIN(sr_decay, zero_motion_pct); -} - -static double get_prediction_decay_rate(const TWO_PASS *const twopass, - const FIRSTPASS_STATS *frame_stats) { - const double sr_decay_rate = get_sr_decay_rate(twopass, frame_stats); - double zero_motion_factor = - twopass->zm_factor * (frame_stats->pcnt_inter - frame_stats->pcnt_motion); - - // Check that the zero motion factor is valid - assert(zero_motion_factor >= 0.0 && zero_motion_factor <= 1.0); - - return VPXMAX(zero_motion_factor, - (sr_decay_rate + ((1.0 - sr_decay_rate) * zero_motion_factor))); -} - -static int get_show_idx(const TWO_PASS *twopass) { - return (int)(twopass->stats_in - twopass->stats_in_start); -} -// Function to test for a condition where a complex transition is followed -// by a static section. For example in slide shows where there is a fade -// between slides. This is to help with more optimal kf and gf positioning. -static int check_transition_to_still(const FIRST_PASS_INFO *first_pass_info, - int show_idx, int still_interval) { - int j; - int num_frames = fps_get_num_frames(first_pass_info); - if (show_idx + still_interval > num_frames) { - return 0; - } - - // Look ahead a few frames to see if static condition persists... - for (j = 0; j < still_interval; ++j) { - const FIRSTPASS_STATS *stats = - fps_get_frame_stats(first_pass_info, show_idx + j); - if (stats->pcnt_inter - stats->pcnt_motion < 0.999) break; - } - - // Only if it does do we signal a transition to still. - return j == still_interval; -} - -// This function detects a flash through the high relative pcnt_second_ref -// score in the frame following a flash frame. The offset passed in should -// reflect this. -static int detect_flash_from_frame_stats(const FIRSTPASS_STATS *frame_stats) { - // What we are looking for here is a situation where there is a - // brief break in prediction (such as a flash) but subsequent frames - // are reasonably well predicted by an earlier (pre flash) frame. - // The recovery after a flash is indicated by a high pcnt_second_ref - // usage or a second ref coded error notabley lower than the last - // frame coded error. - if (frame_stats == NULL) { - return 0; - } - return (frame_stats->sr_coded_error < frame_stats->coded_error) || - ((frame_stats->pcnt_second_ref > frame_stats->pcnt_inter) && - (frame_stats->pcnt_second_ref >= 0.5)); -} - -static int detect_flash(const TWO_PASS *twopass, int offset) { - const FIRSTPASS_STATS *const next_frame = read_frame_stats(twopass, offset); - return detect_flash_from_frame_stats(next_frame); -} - -// Update the motion related elements to the GF arf boost calculation. -static void accumulate_frame_motion_stats(const FIRSTPASS_STATS *stats, - double *mv_in_out, - double *mv_in_out_accumulator, - double *abs_mv_in_out_accumulator, - double *mv_ratio_accumulator) { - const double pct = stats->pcnt_motion; - - // Accumulate Motion In/Out of frame stats. - *mv_in_out = stats->mv_in_out_count * pct; - *mv_in_out_accumulator += *mv_in_out; - *abs_mv_in_out_accumulator += fabs(*mv_in_out); - - // Accumulate a measure of how uniform (or conversely how random) the motion - // field is (a ratio of abs(mv) / mv). - if (pct > 0.05) { - const double mvr_ratio = - fabs(stats->mvr_abs) / DOUBLE_DIVIDE_CHECK(fabs(stats->MVr)); - const double mvc_ratio = - fabs(stats->mvc_abs) / DOUBLE_DIVIDE_CHECK(fabs(stats->MVc)); - - *mv_ratio_accumulator += - pct * (mvr_ratio < stats->mvr_abs ? mvr_ratio : stats->mvr_abs); - *mv_ratio_accumulator += - pct * (mvc_ratio < stats->mvc_abs ? mvc_ratio : stats->mvc_abs); - } -} - -static double calc_frame_boost(const FRAME_INFO *frame_info, - const FIRSTPASS_STATS *this_frame, - const TWO_PASS *const twopass, - int avg_frame_qindex, - double this_frame_mv_in_out) { - double frame_boost; - const double lq = - vp9_convert_qindex_to_q(avg_frame_qindex, frame_info->bit_depth); - const double boost_q_correction = VPXMIN((0.5 + (lq * 0.015)), 1.5); - const double active_area = calculate_active_area(frame_info, this_frame); - - // Frame booost is based on inter error. - frame_boost = (twopass->err_per_mb * active_area) / - DOUBLE_DIVIDE_CHECK(this_frame->coded_error); - - // Small adjustment for cases where there is a zoom out - if (this_frame_mv_in_out > 0.0) - frame_boost += frame_boost * (this_frame_mv_in_out * 2.0); - - // Q correction and scalling - frame_boost = frame_boost * boost_q_correction; - - return VPXMIN(frame_boost, twopass->gf_frame_max_boost * boost_q_correction); -} - -static double calc_kf_frame_boost(VP9_COMP *cpi, - const FIRSTPASS_STATS *this_frame, - double *sr_accumulator, - double this_frame_mv_in_out, - double zm_factor) { - TWO_PASS *const twopass = &cpi->twopass; - double frame_boost; - const double lq = vp9_convert_qindex_to_q( - cpi->rc.avg_frame_qindex[INTER_FRAME], cpi->common.bit_depth); - const double boost_q_correction = VPXMIN((0.50 + (lq * 0.015)), 2.00); - const double active_area = - calculate_active_area(&cpi->frame_info, this_frame); - double max_boost; - - // Frame booost is based on inter error. - frame_boost = (twopass->kf_err_per_mb * active_area) / - DOUBLE_DIVIDE_CHECK(this_frame->coded_error + *sr_accumulator); - - // Update the accumulator for second ref error difference. - // This is intended to give an indication of how much the coded error is - // increasing over time. - *sr_accumulator += (this_frame->sr_coded_error - this_frame->coded_error); - *sr_accumulator = VPXMAX(0.0, *sr_accumulator); - - // Small adjustment for cases where there is a zoom out - if (this_frame_mv_in_out > 0.0) - frame_boost += frame_boost * (this_frame_mv_in_out * 2.0); - - // Q correction and scaling - // The 40.0 value here is an experimentally derived baseline minimum. - // This value is in line with the minimum per frame boost in the alt_ref - // boost calculation. - frame_boost = - (frame_boost + twopass->kf_frame_min_boost) * boost_q_correction; - - // Maximum allowed boost this frame. May be different for first vs subsequent - // key frames. - max_boost = (cpi->common.current_video_frame == 0) - ? twopass->kf_frame_max_boost_first - : twopass->kf_frame_max_boost_subs; - max_boost *= zm_factor * boost_q_correction; - - return VPXMIN(frame_boost, max_boost); -} - -static int compute_arf_boost(const FRAME_INFO *frame_info, - TWO_PASS *const twopass, int arf_show_idx, - int f_frames, int b_frames, int avg_frame_qindex) { - const FIRST_PASS_INFO *first_pass_info = &twopass->first_pass_info; - int i; - double boost_score = 0.0; - double mv_ratio_accumulator = 0.0; - double decay_accumulator = 1.0; - double this_frame_mv_in_out = 0.0; - double mv_in_out_accumulator = 0.0; - double abs_mv_in_out_accumulator = 0.0; - int arf_boost; - int flash_detected = 0; - - // Search forward from the proposed arf/next gf position. - for (i = 0; i < f_frames; ++i) { - const FIRSTPASS_STATS *this_frame = - fps_get_frame_stats(first_pass_info, arf_show_idx + i); - const FIRSTPASS_STATS *next_frame = - fps_get_frame_stats(first_pass_info, arf_show_idx + i + 1); - if (this_frame == NULL) break; - - // Update the motion related elements to the boost calculation. - accumulate_frame_motion_stats( - this_frame, &this_frame_mv_in_out, &mv_in_out_accumulator, - &abs_mv_in_out_accumulator, &mv_ratio_accumulator); - - // We want to discount the flash frame itself and the recovery - // frame that follows as both will have poor scores. - flash_detected = detect_flash_from_frame_stats(this_frame) || - detect_flash_from_frame_stats(next_frame); - - // Accumulate the effect of prediction quality decay. - if (!flash_detected) { - decay_accumulator *= get_prediction_decay_rate(twopass, this_frame); - decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR - ? MIN_DECAY_FACTOR - : decay_accumulator; - } - boost_score += decay_accumulator * - calc_frame_boost(frame_info, this_frame, twopass, - avg_frame_qindex, this_frame_mv_in_out); - } - - arf_boost = (int)boost_score; - - // Reset for backward looking loop. - boost_score = 0.0; - mv_ratio_accumulator = 0.0; - decay_accumulator = 1.0; - this_frame_mv_in_out = 0.0; - mv_in_out_accumulator = 0.0; - abs_mv_in_out_accumulator = 0.0; - - // Search backward towards last gf position. - for (i = -1; i >= -b_frames; --i) { - const FIRSTPASS_STATS *this_frame = - fps_get_frame_stats(first_pass_info, arf_show_idx + i); - const FIRSTPASS_STATS *next_frame = - fps_get_frame_stats(first_pass_info, arf_show_idx + i + 1); - if (this_frame == NULL) break; - - // Update the motion related elements to the boost calculation. - accumulate_frame_motion_stats( - this_frame, &this_frame_mv_in_out, &mv_in_out_accumulator, - &abs_mv_in_out_accumulator, &mv_ratio_accumulator); - - // We want to discount the flash frame itself and the recovery - // frame that follows as both will have poor scores. - flash_detected = detect_flash_from_frame_stats(this_frame) || - detect_flash_from_frame_stats(next_frame); - - // Cumulative effect of prediction quality decay. - if (!flash_detected) { - decay_accumulator *= get_prediction_decay_rate(twopass, this_frame); - decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR - ? MIN_DECAY_FACTOR - : decay_accumulator; - } - boost_score += decay_accumulator * - calc_frame_boost(frame_info, this_frame, twopass, - avg_frame_qindex, this_frame_mv_in_out); - } - arf_boost += (int)boost_score; - - if (arf_boost < ((b_frames + f_frames) * 40)) - arf_boost = ((b_frames + f_frames) * 40); - arf_boost = VPXMAX(arf_boost, MIN_ARF_GF_BOOST); - - return arf_boost; -} - -static int calc_arf_boost(VP9_COMP *cpi, int f_frames, int b_frames) { - const FRAME_INFO *frame_info = &cpi->frame_info; - TWO_PASS *const twopass = &cpi->twopass; - const int avg_inter_frame_qindex = cpi->rc.avg_frame_qindex[INTER_FRAME]; - int arf_show_idx = get_show_idx(twopass); - return compute_arf_boost(frame_info, twopass, arf_show_idx, f_frames, - b_frames, avg_inter_frame_qindex); -} - -// Calculate a section intra ratio used in setting max loop filter. -static int calculate_section_intra_ratio(const FIRSTPASS_STATS *begin, - const FIRSTPASS_STATS *end, - int section_length) { - const FIRSTPASS_STATS *s = begin; - double intra_error = 0.0; - double coded_error = 0.0; - int i = 0; - - while (s < end && i < section_length) { - intra_error += s->intra_error; - coded_error += s->coded_error; - ++s; - ++i; - } - - return (int)(intra_error / DOUBLE_DIVIDE_CHECK(coded_error)); -} - -// Calculate the total bits to allocate in this GF/ARF group. -static int64_t calculate_total_gf_group_bits(VP9_COMP *cpi, - double gf_group_err) { - VP9_COMMON *const cm = &cpi->common; - const RATE_CONTROL *const rc = &cpi->rc; - const TWO_PASS *const twopass = &cpi->twopass; - const int max_bits = frame_max_bits(rc, &cpi->oxcf); - int64_t total_group_bits; - const int is_key_frame = frame_is_intra_only(cm); - const int arf_active_or_kf = is_key_frame || rc->source_alt_ref_active; - int gop_frames = - rc->baseline_gf_interval + rc->source_alt_ref_pending - arf_active_or_kf; - - // Calculate the bits to be allocated to the group as a whole. - if ((twopass->kf_group_bits > 0) && (twopass->kf_group_error_left > 0.0)) { - int key_frame_interval = rc->frames_since_key + rc->frames_to_key; - int distance_from_next_key_frame = - rc->frames_to_key - - (rc->baseline_gf_interval + rc->source_alt_ref_pending); - int max_gf_bits_bias = rc->avg_frame_bandwidth; - double gf_interval_bias_bits_normalize_factor = - (double)rc->baseline_gf_interval / 16; - total_group_bits = (int64_t)(twopass->kf_group_bits * - (gf_group_err / twopass->kf_group_error_left)); - // TODO(ravi): Experiment with different values of max_gf_bits_bias - total_group_bits += - (int64_t)((double)distance_from_next_key_frame / key_frame_interval * - max_gf_bits_bias * gf_interval_bias_bits_normalize_factor); - } else { - total_group_bits = 0; - } - - // Clamp odd edge cases. - total_group_bits = (total_group_bits < 0) ? 0 - : (total_group_bits > twopass->kf_group_bits) - ? twopass->kf_group_bits - : total_group_bits; - - // Clip based on user supplied data rate variability limit. - if (total_group_bits > (int64_t)max_bits * gop_frames) - total_group_bits = (int64_t)max_bits * gop_frames; - - return total_group_bits; -} - -// Calculate the number bits extra to assign to boosted frames in a group. -static int calculate_boost_bits(int frame_count, int boost, - int64_t total_group_bits) { - int allocation_chunks; - - // return 0 for invalid inputs (could arise e.g. through rounding errors) - if (!boost || (total_group_bits <= 0) || (frame_count < 0)) return 0; - - allocation_chunks = (frame_count * NORMAL_BOOST) + boost; - - // Prevent overflow. - if (boost > 1023) { - int divisor = boost >> 10; - boost /= divisor; - allocation_chunks /= divisor; - } - - // Calculate the number of extra bits for use in the boosted frame or frames. - return VPXMAX((int)(((int64_t)boost * total_group_bits) / allocation_chunks), - 0); -} - -// Used in corpus vbr: Calculates the total normalized group complexity score -// for a given number of frames starting at the current position in the stats -// file. -static double calculate_group_score(VP9_COMP *cpi, double av_score, - int frame_count) { - VP9EncoderConfig *const oxcf = &cpi->oxcf; - TWO_PASS *const twopass = &cpi->twopass; - const FIRSTPASS_STATS *s = twopass->stats_in; - double score_total = 0.0; - int i = 0; - - // We don't ever want to return a 0 score here. - if (frame_count == 0) return 1.0; - - while ((i < frame_count) && (s < twopass->stats_in_end)) { - score_total += calculate_norm_frame_score(cpi, twopass, oxcf, s, av_score); - ++s; - ++i; - } - - return score_total; -} - -static void find_arf_order(VP9_COMP *cpi, GF_GROUP *gf_group, - int *index_counter, int depth, int start, int end) { - TWO_PASS *twopass = &cpi->twopass; - const FIRSTPASS_STATS *const start_pos = twopass->stats_in; - FIRSTPASS_STATS fpf_frame; - const int mid = (start + end + 1) >> 1; - const int min_frame_interval = 2; - int idx; - - // Process regular P frames - if ((end - start < min_frame_interval) || - (depth > gf_group->allowed_max_layer_depth)) { - for (idx = start; idx <= end; ++idx) { - gf_group->update_type[*index_counter] = LF_UPDATE; - gf_group->arf_src_offset[*index_counter] = 0; - gf_group->frame_gop_index[*index_counter] = idx; - gf_group->rf_level[*index_counter] = INTER_NORMAL; - gf_group->layer_depth[*index_counter] = depth; - gf_group->gfu_boost[*index_counter] = NORMAL_BOOST; - ++(*index_counter); - } - gf_group->max_layer_depth = VPXMAX(gf_group->max_layer_depth, depth); - return; - } - - assert(abs(mid - start) >= 1 && abs(mid - end) >= 1); - - // Process ARF frame - gf_group->layer_depth[*index_counter] = depth; - gf_group->update_type[*index_counter] = ARF_UPDATE; - gf_group->arf_src_offset[*index_counter] = mid - start; - gf_group->frame_gop_index[*index_counter] = mid; - gf_group->rf_level[*index_counter] = GF_ARF_LOW; - - for (idx = 0; idx <= mid; ++idx) - if (EOF == input_stats(twopass, &fpf_frame)) break; - - gf_group->gfu_boost[*index_counter] = - VPXMAX(MIN_ARF_GF_BOOST, - calc_arf_boost(cpi, end - mid + 1, mid - start) >> depth); - - reset_fpf_position(twopass, start_pos); - - ++(*index_counter); - - find_arf_order(cpi, gf_group, index_counter, depth + 1, start, mid - 1); - - gf_group->update_type[*index_counter] = USE_BUF_FRAME; - gf_group->arf_src_offset[*index_counter] = 0; - gf_group->frame_gop_index[*index_counter] = mid; - gf_group->rf_level[*index_counter] = INTER_NORMAL; - gf_group->layer_depth[*index_counter] = depth; - ++(*index_counter); - - find_arf_order(cpi, gf_group, index_counter, depth + 1, mid + 1, end); -} - -static INLINE void set_gf_overlay_frame_type(GF_GROUP *gf_group, - int frame_index, - int source_alt_ref_active) { - if (source_alt_ref_active) { - gf_group->update_type[frame_index] = OVERLAY_UPDATE; - gf_group->rf_level[frame_index] = INTER_NORMAL; - gf_group->layer_depth[frame_index] = MAX_ARF_LAYERS - 1; - gf_group->gfu_boost[frame_index] = NORMAL_BOOST; - } else { - gf_group->update_type[frame_index] = GF_UPDATE; - gf_group->rf_level[frame_index] = GF_ARF_STD; - gf_group->layer_depth[frame_index] = 0; - } -} - -static void define_gf_group_structure(VP9_COMP *cpi) { - RATE_CONTROL *const rc = &cpi->rc; - TWO_PASS *const twopass = &cpi->twopass; - GF_GROUP *const gf_group = &twopass->gf_group; - int frame_index = 0; - int key_frame = cpi->common.frame_type == KEY_FRAME; - int layer_depth = 1; - int gop_frames = - rc->baseline_gf_interval - (key_frame || rc->source_alt_ref_pending); - - gf_group->frame_start = cpi->common.current_video_frame; - gf_group->frame_end = gf_group->frame_start + rc->baseline_gf_interval; - gf_group->max_layer_depth = 0; - gf_group->allowed_max_layer_depth = 0; - - // For key frames the frame target rate is already set and it - // is also the golden frame. - // === [frame_index == 0] === - if (!key_frame) - set_gf_overlay_frame_type(gf_group, frame_index, rc->source_alt_ref_active); - - ++frame_index; - - // === [frame_index == 1] === - if (rc->source_alt_ref_pending) { - gf_group->update_type[frame_index] = ARF_UPDATE; - gf_group->rf_level[frame_index] = GF_ARF_STD; - gf_group->layer_depth[frame_index] = layer_depth; - gf_group->arf_src_offset[frame_index] = - (unsigned char)(rc->baseline_gf_interval - 1); - gf_group->frame_gop_index[frame_index] = rc->baseline_gf_interval; - gf_group->max_layer_depth = 1; - ++frame_index; - ++layer_depth; - gf_group->allowed_max_layer_depth = cpi->oxcf.enable_auto_arf; - } - - find_arf_order(cpi, gf_group, &frame_index, layer_depth, 1, gop_frames); - - // TODO(b/345523905): Why do we need to set an overlay frame in the end? - set_gf_overlay_frame_type(gf_group, frame_index, rc->source_alt_ref_pending); - gf_group->arf_src_offset[frame_index] = 0; - gf_group->frame_gop_index[frame_index] = rc->baseline_gf_interval; - - // Set the frame ops number. - gf_group->gf_group_size = frame_index; -} - -static INLINE void gf_group_set_overlay_frame(GF_GROUP *gf_group, - int frame_index, - int show_frame_index) { - gf_group->update_type[frame_index] = OVERLAY_UPDATE; - gf_group->arf_src_offset[frame_index] = 0; - gf_group->frame_gop_index[frame_index] = show_frame_index; - gf_group->rf_level[frame_index] = INTER_NORMAL; - gf_group->layer_depth[frame_index] = MAX_ARF_LAYERS - 1; -} - -static INLINE void gf_group_set_key_frame(GF_GROUP *gf_group, int frame_index, - int show_frame_index) { - gf_group->update_type[frame_index] = KF_UPDATE; - gf_group->arf_src_offset[frame_index] = 0; - gf_group->frame_gop_index[frame_index] = show_frame_index; - gf_group->rf_level[frame_index] = KF_STD; - gf_group->layer_depth[frame_index] = 0; -} - -static INLINE void gf_group_set_arf_frame(GF_GROUP *gf_group, int frame_index, - int show_frame_index) { - gf_group->update_type[frame_index] = ARF_UPDATE; - gf_group->arf_src_offset[frame_index] = - (unsigned char)(show_frame_index - frame_index); - gf_group->frame_gop_index[frame_index] = show_frame_index; - gf_group->rf_level[frame_index] = GF_ARF_STD; - gf_group->layer_depth[frame_index] = 1; -} - -static INLINE void gf_group_set_inter_normal_frame(GF_GROUP *gf_group, - int frame_index, - int show_frame_index) { - gf_group->update_type[frame_index] = LF_UPDATE; - gf_group->arf_src_offset[frame_index] = 0; - gf_group->frame_gop_index[frame_index] = show_frame_index; - gf_group->rf_level[frame_index] = INTER_NORMAL; - gf_group->layer_depth[frame_index] = 2; -} - -static INLINE void set_gf_frame_type(vpx_rc_frame_update_type_t update_type, - int show_frame_count, GF_GROUP *gf_group, - int *frame_index, int *show_frame_index) { - if (update_type == VPX_RC_KF_UPDATE) { - gf_group_set_key_frame(gf_group, *frame_index, *show_frame_index); - ++(*frame_index); - ++(*show_frame_index); - } else if (update_type == VPX_RC_OVERLAY_UPDATE) { - gf_group_set_overlay_frame(gf_group, *frame_index, *show_frame_index); - ++(*frame_index); - ++(*show_frame_index); - } else if (update_type == VPX_RC_ARF_UPDATE) { - gf_group_set_arf_frame(gf_group, *frame_index, show_frame_count); - ++(*frame_index); - } else if (update_type == VPX_RC_LF_UPDATE) { - gf_group_set_inter_normal_frame(gf_group, *frame_index, *show_frame_index); - ++(*frame_index); - ++(*show_frame_index); - } else { - assert(0); - } -} - -static void ext_rc_define_gf_group_structure( - const vpx_rc_gop_decision_t *gop_decision, GF_GROUP *gf_group) { - const int gop_coding_frames = gop_decision->gop_coding_frames; - - const int show_frame_count = gop_coding_frames - gop_decision->use_alt_ref; - int frame_index = 0; - int show_frame_index = 0; - - for (int i = frame_index; i < gop_coding_frames; i++) { - set_gf_frame_type(gop_decision->update_type[i], show_frame_count, gf_group, - &frame_index, &show_frame_index); - - gf_group->update_ref_idx[i] = gop_decision->update_ref_index[i]; - - gf_group->ext_rc_ref[i].last_index = 0; - gf_group->ext_rc_ref[i].golden_index = 0; - gf_group->ext_rc_ref[i].altref_index = 0; - for (int ref_frame = 0; ref_frame < 3; ref_frame++) { - const vpx_rc_ref_frame_t *const ext_ref_frame = - &gop_decision->ref_frame_list[i]; - const int ref_index = ext_ref_frame->index[ref_frame]; - gf_group->ref_frame_list[i][ref_frame] = ext_ref_frame->index[ref_frame]; - switch (ext_ref_frame->name[ref_frame]) { - case VPX_RC_LAST_FRAME: - gf_group->ext_rc_ref[i].last_index = ref_index; - break; - case VPX_RC_GOLDEN_FRAME: - gf_group->ext_rc_ref[i].golden_index = ref_index; - break; - case VPX_RC_ALTREF_FRAME: - gf_group->ext_rc_ref[i].altref_index = ref_index; - break; - default: break; - } - } - if (gf_group->update_type[i] == OVERLAY_UPDATE) { - // From ext_rc, overlay may not update any ref. But here we force it to - // update its arf's slot. This is probably OK since the arf and this - // overlay frame should be very similar. - gf_group->update_ref_idx[i] = gf_group->ext_rc_ref[i].altref_index; - } - } - // max_layer_depth is hardcoded to match the behavior of - // define_gf_group_structure() - // TODO(angiebird): Check whether max_layer_depth has performance impact. - gf_group->max_layer_depth = 2; - gf_group->allowed_max_layer_depth = 1; - gf_group->gf_group_size = gop_coding_frames; - - // TODO(b/345523905): Why do we need to set an overlay frame in the end? - assert(show_frame_count == show_frame_index); - if (gop_decision->use_alt_ref) { - gf_group_set_overlay_frame(gf_group, gf_group->gf_group_size, - show_frame_index); - } else { - gf_group_set_inter_normal_frame(gf_group, gf_group->gf_group_size, - show_frame_index); - } - - gf_group->frame_start = 0; - gf_group->frame_end = gf_group->gf_group_size - gop_decision->use_alt_ref; -} - -static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits, - int gf_arf_bits) { - VP9EncoderConfig *const oxcf = &cpi->oxcf; - RATE_CONTROL *const rc = &cpi->rc; - TWO_PASS *const twopass = &cpi->twopass; - GF_GROUP *const gf_group = &twopass->gf_group; - FIRSTPASS_STATS frame_stats; - int i; - int frame_index = 0; - int target_frame_size; - int key_frame; - const int max_bits = frame_max_bits(&cpi->rc, oxcf); - int64_t total_group_bits = gf_group_bits; - int mid_frame_idx; - int normal_frames; - int normal_frame_bits; - int last_frame_reduction = 0; - double av_score = 1.0; - double tot_norm_frame_score = 1.0; - double this_frame_score = 1.0; - - // Define the GF structure and specify - int gop_frames = gf_group->gf_group_size; - - key_frame = cpi->common.frame_type == KEY_FRAME; - - // For key frames the frame target rate is already set and it - // is also the golden frame. - // === [frame_index == 0] === - if (!key_frame) { - gf_group->bit_allocation[frame_index] = - rc->source_alt_ref_active ? 0 : gf_arf_bits; - } - - // Deduct the boost bits for arf (or gf if it is not a key frame) - // from the group total. - if (rc->source_alt_ref_pending || !key_frame) total_group_bits -= gf_arf_bits; - - ++frame_index; - - // === [frame_index == 1] === - // Store the bits to spend on the ARF if there is one. - if (rc->source_alt_ref_pending) { - gf_group->bit_allocation[frame_index] = gf_arf_bits; - - ++frame_index; - } - - // Define middle frame - mid_frame_idx = frame_index + (rc->baseline_gf_interval >> 1) - 1; - - normal_frames = (rc->baseline_gf_interval - 1); - if (normal_frames > 1) - normal_frame_bits = (int)(total_group_bits / normal_frames); - else - normal_frame_bits = (int)total_group_bits; - - gf_group->gfu_boost[1] = rc->gfu_boost; - - if (cpi->multi_layer_arf) { - int idx; - int arf_depth_bits[MAX_ARF_LAYERS] = { 0 }; - int arf_depth_count[MAX_ARF_LAYERS] = { 0 }; - int arf_depth_boost[MAX_ARF_LAYERS] = { 0 }; - int total_arfs = 1; // Account for the base layer ARF. - - for (idx = 0; idx < gop_frames; ++idx) { - if (gf_group->update_type[idx] == ARF_UPDATE) { - arf_depth_boost[gf_group->layer_depth[idx]] += gf_group->gfu_boost[idx]; - ++arf_depth_count[gf_group->layer_depth[idx]]; - } - } - - for (idx = 2; idx < MAX_ARF_LAYERS; ++idx) { - if (arf_depth_boost[idx] == 0) break; - arf_depth_bits[idx] = calculate_boost_bits( - rc->baseline_gf_interval - total_arfs - arf_depth_count[idx], - arf_depth_boost[idx], total_group_bits); - - total_group_bits -= arf_depth_bits[idx]; - total_arfs += arf_depth_count[idx]; - } - - // offset the base layer arf - normal_frames -= (total_arfs - 1); - if (normal_frames > 1) - normal_frame_bits = (int)(total_group_bits / normal_frames); - else - normal_frame_bits = (int)total_group_bits; - - target_frame_size = normal_frame_bits; - target_frame_size = - clamp(target_frame_size, 0, VPXMIN(max_bits, (int)total_group_bits)); - - // The first layer ARF has its bit allocation assigned. - for (idx = frame_index; idx < gop_frames; ++idx) { - switch (gf_group->update_type[idx]) { - case ARF_UPDATE: - gf_group->bit_allocation[idx] = - (int)(((int64_t)arf_depth_bits[gf_group->layer_depth[idx]] * - gf_group->gfu_boost[idx]) / - arf_depth_boost[gf_group->layer_depth[idx]]); - break; - case USE_BUF_FRAME: gf_group->bit_allocation[idx] = 0; break; - default: gf_group->bit_allocation[idx] = target_frame_size; break; - } - } - gf_group->bit_allocation[idx] = 0; - - return; - } - - if (oxcf->vbr_corpus_complexity) { - av_score = get_distribution_av_err(cpi, twopass); - tot_norm_frame_score = calculate_group_score(cpi, av_score, normal_frames); - } - - // Allocate bits to the other frames in the group. - for (i = 0; i < normal_frames; ++i) { - if (EOF == input_stats(twopass, &frame_stats)) break; - if (oxcf->vbr_corpus_complexity) { - this_frame_score = calculate_norm_frame_score(cpi, twopass, oxcf, - &frame_stats, av_score); - normal_frame_bits = (int)((double)total_group_bits * - (this_frame_score / tot_norm_frame_score)); - } - - target_frame_size = normal_frame_bits; - if ((i == (normal_frames - 1)) && (i >= 1)) { - last_frame_reduction = normal_frame_bits / 16; - target_frame_size -= last_frame_reduction; - } - - target_frame_size = - clamp(target_frame_size, 0, VPXMIN(max_bits, (int)total_group_bits)); - - gf_group->bit_allocation[frame_index] = target_frame_size; - ++frame_index; - } - - // Add in some extra bits for the middle frame in the group. - gf_group->bit_allocation[mid_frame_idx] += last_frame_reduction; - - // Note: - // We need to configure the frame at the end of the sequence + 1 that will be - // the start frame for the next group. Otherwise prior to the call to - // vp9_rc_get_second_pass_params() the data will be undefined. -} - -// Adjusts the ARNF filter for a GF group. -static void adjust_group_arnr_filter(VP9_COMP *cpi, double section_noise, - double section_inter, - double section_motion) { - TWO_PASS *const twopass = &cpi->twopass; - double section_zeromv = section_inter - section_motion; - - twopass->arnr_strength_adjustment = 0; - - if (section_noise < 150) { - twopass->arnr_strength_adjustment -= 1; - if (section_noise < 75) twopass->arnr_strength_adjustment -= 1; - } else if (section_noise > 250) - twopass->arnr_strength_adjustment += 1; - - if (section_zeromv > 0.50) twopass->arnr_strength_adjustment += 1; -} - -// Analyse and define a gf/arf group. -#define ARF_ABS_ZOOM_THRESH 4.0 - -#define MAX_GF_BOOST 5400 - -typedef struct RANGE { - int min; - int max; -} RANGE; - -/* get_gop_coding_frame_num() depends on several fields in RATE_CONTROL *rc as - * follows. - * Static fields: - * (The following fields will remain unchanged after initialization of encoder.) - * rc->static_scene_max_gf_interval - * rc->min_gf_interval - * twopass->sr_diff_factor - * twopass->sr_default_decay_limit - * twopass->zm_factor - * - * Dynamic fields: - * (The following fields will be updated before or after coding each frame.) - * rc->frames_to_key - * rc->frames_since_key - * rc->source_alt_ref_active - * - * Special case: if CONFIG_RATE_CTRL is true, the external arf indexes will - * determine the arf position. - * - * TODO(angiebird): Separate the dynamic fields and static fields into two - * structs. - */ -static int get_gop_coding_frame_num( - int *use_alt_ref, const FRAME_INFO *frame_info, - const TWO_PASS *const twopass, const RATE_CONTROL *rc, - int gf_start_show_idx, const RANGE *active_gf_interval, - double gop_intra_factor, int lag_in_frames, int *end_of_sequence) { - const FIRST_PASS_INFO *first_pass_info = &twopass->first_pass_info; - double loop_decay_rate = 1.00; - double mv_ratio_accumulator = 0.0; - double this_frame_mv_in_out = 0.0; - double mv_in_out_accumulator = 0.0; - double abs_mv_in_out_accumulator = 0.0; - double sr_accumulator = 0.0; - // Motion breakout threshold for loop below depends on image size. - double mv_ratio_accumulator_thresh = - (frame_info->frame_height + frame_info->frame_width) / 4.0; - double zero_motion_accumulator = 1.0; - int gop_coding_frames; - - *use_alt_ref = 1; - gop_coding_frames = 0; - while (gop_coding_frames < rc->static_scene_max_gf_interval && - gop_coding_frames < rc->frames_to_key) { - const FIRSTPASS_STATS *next_next_frame; - const FIRSTPASS_STATS *next_frame; - int flash_detected; - ++gop_coding_frames; - - next_frame = fps_get_frame_stats(first_pass_info, - gf_start_show_idx + gop_coding_frames); - if (next_frame == NULL) { - *end_of_sequence = gop_coding_frames == 1 && rc->source_alt_ref_active; - break; - } - - // Test for the case where there is a brief flash but the prediction - // quality back to an earlier frame is then restored. - next_next_frame = fps_get_frame_stats( - first_pass_info, gf_start_show_idx + gop_coding_frames + 1); - flash_detected = detect_flash_from_frame_stats(next_next_frame); - - // Update the motion related elements to the boost calculation. - accumulate_frame_motion_stats( - next_frame, &this_frame_mv_in_out, &mv_in_out_accumulator, - &abs_mv_in_out_accumulator, &mv_ratio_accumulator); - - // Monitor for static sections. - if ((rc->frames_since_key + gop_coding_frames - 1) > 1) { - zero_motion_accumulator = VPXMIN( - zero_motion_accumulator, get_zero_motion_factor(twopass, next_frame)); - } - - // Accumulate the effect of prediction quality decay. - if (!flash_detected) { - double last_loop_decay_rate = loop_decay_rate; - loop_decay_rate = get_prediction_decay_rate(twopass, next_frame); - - // Break clause to detect very still sections after motion. For example, - // a static image after a fade or other transition. - if (gop_coding_frames > rc->min_gf_interval && loop_decay_rate >= 0.999 && - last_loop_decay_rate < 0.9) { - int still_interval = 5; - if (check_transition_to_still(first_pass_info, - gf_start_show_idx + gop_coding_frames, - still_interval)) { - *use_alt_ref = 0; - break; - } - } - - // Update the accumulator for second ref error difference. - // This is intended to give an indication of how much the coded error is - // increasing over time. - if (gop_coding_frames == 1) { - sr_accumulator += next_frame->coded_error; - } else { - sr_accumulator += - (next_frame->sr_coded_error - next_frame->coded_error); - } - } - - // Break out conditions. - // Break at maximum of active_gf_interval->max unless almost totally - // static. - // - // Note that the addition of a test of rc->source_alt_ref_active is - // deliberate. The effect of this is that after a normal altref group even - // if the material is static there will be one normal length GF group - // before allowing longer GF groups. The reason for this is that in cases - // such as slide shows where slides are separated by a complex transition - // such as a fade, the arf group spanning the transition may not be coded - // at a very high quality and hence this frame (with its overlay) is a - // poor golden frame to use for an extended group. - if ((gop_coding_frames >= active_gf_interval->max) && - ((zero_motion_accumulator < 0.995) || (rc->source_alt_ref_active))) { - break; - } - if ( - // Don't break out with a very short interval. - (gop_coding_frames >= active_gf_interval->min) && - // If possible don't break very close to a kf - ((rc->frames_to_key - gop_coding_frames) >= rc->min_gf_interval) && - (gop_coding_frames & 0x01) && (!flash_detected) && - ((mv_ratio_accumulator > mv_ratio_accumulator_thresh) || - (abs_mv_in_out_accumulator > ARF_ABS_ZOOM_THRESH) || - (sr_accumulator > gop_intra_factor * next_frame->intra_error))) { - break; - } - } - *use_alt_ref &= zero_motion_accumulator < 0.995; - *use_alt_ref &= gop_coding_frames < lag_in_frames; - *use_alt_ref &= gop_coding_frames >= rc->min_gf_interval; - return gop_coding_frames; -} - -static RANGE get_active_gf_inverval_range_simple(int min_gf_interval, - int arf_active_or_kf, - int frames_to_key) { - RANGE active_gf_interval; - active_gf_interval.min = min_gf_interval + arf_active_or_kf + 2; - active_gf_interval.max = 16 + arf_active_or_kf; - - if ((active_gf_interval.max <= frames_to_key) && - (active_gf_interval.max >= (frames_to_key - min_gf_interval))) { - active_gf_interval.min = frames_to_key / 2; - active_gf_interval.max = frames_to_key / 2; - } - return active_gf_interval; -} - -static RANGE get_active_gf_inverval_range( - const FRAME_INFO *frame_info, const RATE_CONTROL *rc, int arf_active_or_kf, - int gf_start_show_idx, int active_worst_quality, int last_boosted_qindex) { - RANGE active_gf_interval; - int int_max_q = (int)(vp9_convert_qindex_to_q(active_worst_quality, - frame_info->bit_depth)); - int q_term = (gf_start_show_idx == 0) - ? int_max_q / 32 - : (int)(vp9_convert_qindex_to_q(last_boosted_qindex, - frame_info->bit_depth) / - 6); - active_gf_interval.min = - rc->min_gf_interval + arf_active_or_kf + VPXMIN(2, int_max_q / 200); - active_gf_interval.min = - VPXMIN(active_gf_interval.min, rc->max_gf_interval + arf_active_or_kf); - - // The value chosen depends on the active Q range. At low Q we have - // bits to spare and are better with a smaller interval and smaller boost. - // At high Q when there are few bits to spare we are better with a longer - // interval to spread the cost of the GF. - active_gf_interval.max = 11 + arf_active_or_kf + VPXMIN(5, q_term); - - // Force max GF interval to be odd. - active_gf_interval.max = active_gf_interval.max | 0x01; - - // We have: active_gf_interval.min <= - // rc->max_gf_interval + arf_active_or_kf. - if (active_gf_interval.max < active_gf_interval.min) { - active_gf_interval.max = active_gf_interval.min; - } else { - active_gf_interval.max = - VPXMIN(active_gf_interval.max, rc->max_gf_interval + arf_active_or_kf); - } - - // Would the active max drop us out just before the near the next kf? - if ((active_gf_interval.max <= rc->frames_to_key) && - (active_gf_interval.max >= (rc->frames_to_key - rc->min_gf_interval))) { - active_gf_interval.max = rc->frames_to_key / 2; - } - active_gf_interval.max = - VPXMAX(active_gf_interval.max, active_gf_interval.min); - return active_gf_interval; -} - -static int get_arf_layers(int multi_layer_arf, int max_layers, - int coding_frame_num) { - assert(max_layers <= MAX_ARF_LAYERS); - if (multi_layer_arf) { - int layers = 0; - int i; - for (i = coding_frame_num; i > 0; i >>= 1) { - ++layers; - } - layers = VPXMIN(max_layers, layers); - return layers; - } else { - return 1; - } -} - -static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) { - VP9_COMMON *const cm = &cpi->common; - RATE_CONTROL *const rc = &cpi->rc; - VP9EncoderConfig *const oxcf = &cpi->oxcf; - TWO_PASS *const twopass = &cpi->twopass; - const FRAME_INFO *frame_info = &cpi->frame_info; - const FIRST_PASS_INFO *first_pass_info = &twopass->first_pass_info; - const FIRSTPASS_STATS *const start_pos = twopass->stats_in; - int gop_coding_frames; - - double gf_group_err = 0.0; - double gf_group_raw_error = 0.0; - double gf_group_noise = 0.0; - double gf_group_skip_pct = 0.0; - double gf_group_inactive_zone_rows = 0.0; - double gf_group_inter = 0.0; - double gf_group_motion = 0.0; - - int allow_alt_ref = is_altref_enabled(cpi); - int use_alt_ref; - - int64_t gf_group_bits; - int gf_arf_bits; - int is_key_frame = frame_is_intra_only(cm); - - vpx_rc_gop_decision_t gop_decision; - int gop_decision_ready = 0; - if (cpi->ext_ratectrl.ready && - (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_GOP) != 0 && - cpi->ext_ratectrl.funcs.get_gop_decision != NULL) { - vpx_codec_err_t codec_status = - vp9_extrc_get_gop_decision(&cpi->ext_ratectrl, &gop_decision); - if (codec_status != VPX_CODEC_OK) { - vpx_internal_error(&cm->error, codec_status, - "vp9_extrc_get_gop_decision() failed"); - } - is_key_frame = gop_decision.use_key_frame; - gop_decision_ready = 1; - } - - // If this is a key frame or the overlay from a previous arf then - // the error score / cost of this frame has already been accounted for. - const int arf_active_or_kf = is_key_frame || rc->source_alt_ref_active; - int is_alt_ref_flash = 0; - - double gop_intra_factor; - int gop_frames; - RANGE active_gf_interval; - // Whether this is at the end of last GOP of this sequence. - int end_of_sequence = 0; - - // Reset the GF group data structures unless this is a key - // frame in which case it will already have been done. - if (is_key_frame == 0) { - vp9_zero(twopass->gf_group); - ++rc->gop_global_index; - } else { - rc->gop_global_index = 0; - } - - vpx_clear_system_state(); - - if (oxcf->use_simple_encode_api) { - active_gf_interval = get_active_gf_inverval_range_simple( - rc->min_gf_interval, arf_active_or_kf, rc->frames_to_key); - } else { - active_gf_interval = get_active_gf_inverval_range( - frame_info, rc, arf_active_or_kf, gf_start_show_idx, - twopass->active_worst_quality, rc->last_boosted_qindex); - } - - if (cpi->multi_layer_arf) { - int arf_layers = get_arf_layers(cpi->multi_layer_arf, oxcf->enable_auto_arf, - active_gf_interval.max); - gop_intra_factor = 1.0 + 0.25 * arf_layers; - } else { - gop_intra_factor = 1.0; - } - - gop_coding_frames = get_gop_coding_frame_num( - &use_alt_ref, frame_info, twopass, rc, gf_start_show_idx, - &active_gf_interval, gop_intra_factor, cpi->oxcf.lag_in_frames, - &end_of_sequence); - use_alt_ref &= allow_alt_ref; - - if (gop_decision_ready) { - gop_coding_frames = gop_decision.gop_coding_frames; - use_alt_ref = gop_decision.use_alt_ref; - } - -#if CONFIG_RATE_CTRL - // If the external gop_command is on, we will override the decisions - // of gop_coding_frames and use_alt_ref. - if (cpi->oxcf.use_simple_encode_api) { - const GOP_COMMAND *gop_command = &cpi->encode_command.gop_command; - assert(allow_alt_ref == 1); - if (gop_command->use) { - gop_coding_frames = gop_command_coding_frame_count(gop_command); - use_alt_ref = gop_command->use_alt_ref; - } - } -#endif - - // Was the group length constrained by the requirement for a new KF? - rc->constrained_gf_group = (gop_coding_frames >= rc->frames_to_key) ? 1 : 0; - - // Should we use the alternate reference frame. - if (use_alt_ref) { - const int f_frames = - (rc->frames_to_key - gop_coding_frames >= gop_coding_frames - 1) - ? gop_coding_frames - 1 - : VPXMAX(0, rc->frames_to_key - gop_coding_frames); - const int b_frames = gop_coding_frames - 1; - const int avg_inter_frame_qindex = rc->avg_frame_qindex[INTER_FRAME]; - // TODO(angiebird): figure out why arf's location is assigned this way - const int arf_show_idx = VPXMIN(gf_start_show_idx + gop_coding_frames + 1, - fps_get_num_frames(first_pass_info)); - - // Calculate the boost for alt ref. - rc->gfu_boost = - compute_arf_boost(frame_info, twopass, arf_show_idx, f_frames, b_frames, - avg_inter_frame_qindex); - rc->source_alt_ref_pending = 1; - } else { - const int f_frames = gop_coding_frames - 1; - const int b_frames = 0; - const int avg_inter_frame_qindex = rc->avg_frame_qindex[INTER_FRAME]; - // TODO(angiebird): figure out why arf's location is assigned this way - const int gld_show_idx = - VPXMIN(gf_start_show_idx + 1, fps_get_num_frames(first_pass_info)); - const int arf_boost = - compute_arf_boost(frame_info, twopass, gld_show_idx, f_frames, b_frames, - avg_inter_frame_qindex); - rc->gfu_boost = VPXMIN((int)twopass->gf_max_total_boost, arf_boost); - rc->source_alt_ref_pending = 0; - } - -#define LAST_ALR_ACTIVE_BEST_QUALITY_ADJUSTMENT_FACTOR 0.2 - rc->arf_active_best_quality_adjustment_factor = 1.0; - rc->arf_increase_active_best_quality = 0; - - if (!is_lossless_requested(&cpi->oxcf)) { - if (rc->frames_since_key >= rc->frames_to_key) { - // Increase the active best quality in the second half of key frame - // interval. - rc->arf_active_best_quality_adjustment_factor = - LAST_ALR_ACTIVE_BEST_QUALITY_ADJUSTMENT_FACTOR + - (1.0 - LAST_ALR_ACTIVE_BEST_QUALITY_ADJUSTMENT_FACTOR) * - (rc->frames_to_key - gop_coding_frames) / - (VPXMAX(1, ((rc->frames_to_key + rc->frames_since_key) / 2 - - gop_coding_frames))); - rc->arf_increase_active_best_quality = 1; - } else if ((rc->frames_to_key - gop_coding_frames) > 0) { - // Reduce the active best quality in the first half of key frame interval. - rc->arf_active_best_quality_adjustment_factor = - LAST_ALR_ACTIVE_BEST_QUALITY_ADJUSTMENT_FACTOR + - (1.0 - LAST_ALR_ACTIVE_BEST_QUALITY_ADJUSTMENT_FACTOR) * - (rc->frames_since_key + gop_coding_frames) / - (VPXMAX(1, (rc->frames_to_key + rc->frames_since_key) / 2 + - gop_coding_frames)); - rc->arf_increase_active_best_quality = -1; - } - } - -#ifdef AGGRESSIVE_VBR - // Limit maximum boost based on interval length. - rc->gfu_boost = VPXMIN((int)rc->gfu_boost, gop_coding_frames * 140); -#else - rc->gfu_boost = VPXMIN((int)rc->gfu_boost, gop_coding_frames * 200); -#endif - - // Cap the ARF boost when perceptual quality AQ mode is enabled. This is - // designed to improve the perceptual quality of high value content and to - // make consistent quality across consecutive frames. It will hurt objective - // quality. - if (oxcf->aq_mode == PERCEPTUAL_AQ) - rc->gfu_boost = VPXMIN(rc->gfu_boost, MIN_ARF_GF_BOOST); - - rc->baseline_gf_interval = gop_coding_frames - rc->source_alt_ref_pending; - - if (rc->source_alt_ref_pending) - is_alt_ref_flash = detect_flash(twopass, rc->baseline_gf_interval); - - { - const double av_err = get_distribution_av_err(cpi, twopass); - const double mean_mod_score = twopass->mean_mod_score; - // If the first frame is a key frame or the overlay from a previous arf then - // the error score / cost of this frame has already been accounted for. - int start_idx = arf_active_or_kf ? 1 : 0; - int j; - for (j = start_idx; j < gop_coding_frames; ++j) { - int show_idx = gf_start_show_idx + j; - const FIRSTPASS_STATS *frame_stats = - fps_get_frame_stats(first_pass_info, show_idx); - // TODO(b/345831640): Why do we set gop_coding_frames as the upperbound of - // the for loop here? gop_coding_frames does not reflect the "show frame - // count" in a GOP. Therefore, it's possible to get a NULL pointer from - // fps_get_frame_stats(). Here we mitigate the issue using break whenever - // frame_stats == NULL. Show we set the upperbound to show frame count? - if (frame_stats == NULL) { - if (cpi->ext_ratectrl.ready && - (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_GOP) != 0 && - cpi->ext_ratectrl.funcs.get_gop_decision != NULL) { - // Since in ext_ratectrl, gop_coding_frames means the count of both - // show and no show frames. Using this variable to access - // first_pass_info will trigger out-of-range error because - // first_pass_info only contains show frames. This part is used for - // computing gf_group_err which will be used to compute gf_group_bits - // for libvpx internal rate control. Since ext_ratectrl is using - // external rate control module, this part becomes non-critical. - // Hence, we can safely turn off this error reporting. In the future, - // we should refactor the code so that this part is not used by - // ext_ratectrl. - break; - } - vpx_internal_error(&cm->error, VPX_CODEC_ERROR, - "In define_gf_group(), frame_stats is NULL when " - "calculating gf_group_err."); - break; - } - // Accumulate error score of frames in this gf group. - gf_group_err += calc_norm_frame_score(oxcf, frame_info, frame_stats, - mean_mod_score, av_err); - gf_group_raw_error += frame_stats->coded_error; - gf_group_noise += frame_stats->frame_noise_energy; - gf_group_skip_pct += frame_stats->intra_skip_pct; - gf_group_inactive_zone_rows += frame_stats->inactive_zone_rows; - gf_group_inter += frame_stats->pcnt_inter; - gf_group_motion += frame_stats->pcnt_motion; - } - } - - // Calculate the bits to be allocated to the gf/arf group as a whole - gf_group_bits = calculate_total_gf_group_bits(cpi, gf_group_err); - - gop_frames = - rc->baseline_gf_interval + rc->source_alt_ref_pending - arf_active_or_kf; - - // Store the average moise level measured for the group - // TODO(any): Experiment with removal of else condition (gop_frames = 0) so - // that consumption of group noise energy is based on previous gf group - if (gop_frames > 0) - twopass->gf_group.group_noise_energy = (int)(gf_group_noise / gop_frames); - else - twopass->gf_group.group_noise_energy = 0; - - // Calculate an estimate of the maxq needed for the group. - // We are more aggressive about correcting for sections - // where there could be significant overshoot than for easier - // sections where we do not wish to risk creating an overshoot - // of the allocated bit budget. - if ((cpi->oxcf.rc_mode != VPX_Q) && (rc->baseline_gf_interval > 1)) { - const int vbr_group_bits_per_frame = (int)(gf_group_bits / gop_frames); - const double group_av_err = gf_group_raw_error / gop_frames; - const double group_av_noise = gf_group_noise / gop_frames; - const double group_av_skip_pct = gf_group_skip_pct / gop_frames; - const double group_av_inactive_zone = ((gf_group_inactive_zone_rows * 2) / - (gop_frames * (double)cm->mb_rows)); - int tmp_q = get_twopass_worst_quality( - cpi, group_av_err, (group_av_skip_pct + group_av_inactive_zone), - group_av_noise, vbr_group_bits_per_frame); - twopass->active_worst_quality = - (int)((tmp_q + (twopass->active_worst_quality * - (twopass->active_wq_factor - 1))) / - twopass->active_wq_factor); - -#if CONFIG_ALWAYS_ADJUST_BPM - // Reset rolling actual and target bits counters for ARF groups. - twopass->rolling_arf_group_target_bits = 0; - twopass->rolling_arf_group_actual_bits = 0; -#endif - } - - // Context Adjustment of ARNR filter strength - if (rc->baseline_gf_interval > 1) { - adjust_group_arnr_filter(cpi, (gf_group_noise / gop_frames), - (gf_group_inter / gop_frames), - (gf_group_motion / gop_frames)); - } else { - twopass->arnr_strength_adjustment = 0; - } - - // Calculate the extra bits to be used for boosted frame(s) - gf_arf_bits = calculate_boost_bits((rc->baseline_gf_interval - 1), - rc->gfu_boost, gf_group_bits); - - // Adjust KF group bits and error remaining. - twopass->kf_group_error_left -= gf_group_err; - - // Decide GOP structure. - if (gop_decision_ready) { - ext_rc_define_gf_group_structure(&gop_decision, &twopass->gf_group); - // Set the fb idx for the first frame in this GOP. - cpi->lst_fb_idx = twopass->gf_group.ext_rc_ref[0].last_index; - cpi->gld_fb_idx = twopass->gf_group.ext_rc_ref[0].golden_index; - cpi->alt_fb_idx = twopass->gf_group.ext_rc_ref[0].altref_index; - } else { - define_gf_group_structure(cpi); - } - - // Allocate bits to each of the frames in the GF group. - allocate_gf_group_bits(cpi, gf_group_bits, gf_arf_bits); - - // Reset the file position. - reset_fpf_position(twopass, start_pos); - - // Calculate a section intra ratio used in setting max loop filter. - twopass->section_intra_rating = calculate_section_intra_ratio( - start_pos, twopass->stats_in_end, rc->baseline_gf_interval); - - if (oxcf->resize_mode == RESIZE_DYNAMIC) { - // Default to starting GF groups at normal frame size. - cpi->rc.next_frame_size_selector = UNSCALED; - } -#if !CONFIG_ALWAYS_ADJUST_BPM - // Reset rolling actual and target bits counters for ARF groups. - twopass->rolling_arf_group_target_bits = 0; - twopass->rolling_arf_group_actual_bits = 0; -#endif - rc->preserve_arf_as_gld = rc->preserve_next_arf_as_gld; - rc->preserve_next_arf_as_gld = 0; - // If alt ref frame is flash do not set preserve_arf_as_gld - if (!is_lossless_requested(&cpi->oxcf) && !cpi->use_svc && - cpi->oxcf.aq_mode == NO_AQ && cpi->multi_layer_arf && !is_alt_ref_flash) - rc->preserve_next_arf_as_gld = 1; -} - -// Intra / Inter threshold very low -#define VERY_LOW_II 1.5 -// Clean slide transitions we expect a sharp single frame spike in error. -#define ERROR_SPIKE 5.0 - -// Slide show transition detection. -// Tests for case where there is very low error either side of the current frame -// but much higher just for this frame. This can help detect key frames in -// slide shows even where the slides are pictures of different sizes. -// Also requires that intra and inter errors are very similar to help eliminate -// harmful false positives. -// It will not help if the transition is a fade or other multi-frame effect. -static int slide_transition(const FIRSTPASS_STATS *this_frame, - const FIRSTPASS_STATS *last_frame, - const FIRSTPASS_STATS *next_frame) { - return (this_frame->intra_error < (this_frame->coded_error * VERY_LOW_II)) && - (this_frame->coded_error > (last_frame->coded_error * ERROR_SPIKE)) && - (this_frame->coded_error > (next_frame->coded_error * ERROR_SPIKE)); -} - -// This test looks for anomalous changes in the nature of the intra signal -// related to the previous and next frame as an indicator for coding a key -// frame. This test serves to detect some additional scene cuts, -// especially in lowish motion and low contrast sections, that are missed -// by the other tests. -static int intra_step_transition(const FIRSTPASS_STATS *this_frame, - const FIRSTPASS_STATS *last_frame, - const FIRSTPASS_STATS *next_frame) { - double last_ii_ratio; - double this_ii_ratio; - double next_ii_ratio; - double last_pcnt_intra = 1.0 - last_frame->pcnt_inter; - double this_pcnt_intra = 1.0 - this_frame->pcnt_inter; - double next_pcnt_intra = 1.0 - next_frame->pcnt_inter; - double mod_this_intra = this_pcnt_intra + this_frame->pcnt_neutral; - - // Calculate ii ratio for this frame last frame and next frame. - last_ii_ratio = - last_frame->intra_error / DOUBLE_DIVIDE_CHECK(last_frame->coded_error); - this_ii_ratio = - this_frame->intra_error / DOUBLE_DIVIDE_CHECK(this_frame->coded_error); - next_ii_ratio = - next_frame->intra_error / DOUBLE_DIVIDE_CHECK(next_frame->coded_error); - - // Return true the intra/inter ratio for the current frame is - // low but better in the next and previous frame and the relative usage of - // intra in the current frame is markedly higher than the last and next frame. - if ((this_ii_ratio < 2.0) && (last_ii_ratio > 2.25) && - (next_ii_ratio > 2.25) && (this_pcnt_intra > (3 * last_pcnt_intra)) && - (this_pcnt_intra > (3 * next_pcnt_intra)) && - ((this_pcnt_intra > 0.075) || (mod_this_intra > 0.85))) { - return 1; - // Very low inter intra ratio (i.e. not much gain from inter coding), most - // blocks neutral on coding method and better inter prediction either side - } else if ((this_ii_ratio < 1.25) && (mod_this_intra > 0.85) && - (this_ii_ratio < last_ii_ratio * 0.9) && - (this_ii_ratio < next_ii_ratio * 0.9)) { - return 1; - } else { - return 0; - } -} - -// Minimum % intra coding observed in first pass (1.0 = 100%) -#define MIN_INTRA_LEVEL 0.25 -// Threshold for use of the lagging second reference frame. Scene cuts do not -// usually have a high second ref usage. -#define SECOND_REF_USAGE_THRESH 0.2 -// Hard threshold where the first pass chooses intra for almost all blocks. -// In such a case even if the frame is not a scene cut coding a key frame -// may be a good option. -#define VERY_LOW_INTER_THRESH 0.05 -// Maximum threshold for the relative ratio of intra error score vs best -// inter error score. -#define KF_II_ERR_THRESHOLD 2.5 -#define KF_II_MAX 128.0 -#define II_FACTOR 12.5 -// Test for very low intra complexity which could cause false key frames -#define V_LOW_INTRA 0.5 - -static int test_candidate_kf(const FIRST_PASS_INFO *first_pass_info, - int show_idx) { - const FIRSTPASS_STATS *last_frame = - fps_get_frame_stats(first_pass_info, show_idx - 1); - const FIRSTPASS_STATS *this_frame = - fps_get_frame_stats(first_pass_info, show_idx); - const FIRSTPASS_STATS *next_frame = - fps_get_frame_stats(first_pass_info, show_idx + 1); - int is_viable_kf = 0; - double pcnt_intra = 1.0 - this_frame->pcnt_inter; - - // Does the frame satisfy the primary criteria of a key frame? - // See above for an explanation of the test criteria. - // If so, then examine how well it predicts subsequent frames. - detect_flash_from_frame_stats(next_frame); - if (!detect_flash_from_frame_stats(this_frame) && - !detect_flash_from_frame_stats(next_frame) && - (this_frame->pcnt_second_ref < SECOND_REF_USAGE_THRESH) && - ((this_frame->pcnt_inter < VERY_LOW_INTER_THRESH) || - (slide_transition(this_frame, last_frame, next_frame)) || - (intra_step_transition(this_frame, last_frame, next_frame)) || - (((this_frame->coded_error > (next_frame->coded_error * 1.2)) && - (this_frame->coded_error > (last_frame->coded_error * 1.2))) && - (pcnt_intra > MIN_INTRA_LEVEL) && - ((pcnt_intra + this_frame->pcnt_neutral) > 0.5) && - ((this_frame->intra_error / - DOUBLE_DIVIDE_CHECK(this_frame->coded_error)) < - KF_II_ERR_THRESHOLD)))) { - int i; - double boost_score = 0.0; - double old_boost_score = 0.0; - double decay_accumulator = 1.0; - - // Examine how well the key frame predicts subsequent frames. - for (i = 0; i < 16; ++i) { - const FIRSTPASS_STATS *frame_stats = - fps_get_frame_stats(first_pass_info, show_idx + 1 + i); - double next_iiratio = (II_FACTOR * frame_stats->intra_error / - DOUBLE_DIVIDE_CHECK(frame_stats->coded_error)); - - if (next_iiratio > KF_II_MAX) next_iiratio = KF_II_MAX; - - // Cumulative effect of decay in prediction quality. - if (frame_stats->pcnt_inter > 0.85) - decay_accumulator *= frame_stats->pcnt_inter; - else - decay_accumulator *= (0.85 + frame_stats->pcnt_inter) / 2.0; - - // Keep a running total. - boost_score += (decay_accumulator * next_iiratio); - - // Test various breakout clauses. - if ((frame_stats->pcnt_inter < 0.05) || (next_iiratio < 1.5) || - (((frame_stats->pcnt_inter - frame_stats->pcnt_neutral) < 0.20) && - (next_iiratio < 3.0)) || - ((boost_score - old_boost_score) < 3.0) || - (frame_stats->intra_error < V_LOW_INTRA)) { - break; - } - - old_boost_score = boost_score; - - // Get the next frame details - if (show_idx + 1 + i == fps_get_num_frames(first_pass_info) - 1) break; - } - - // If there is tolerable prediction for at least the next 3 frames then - // break out else discard this potential key frame and move on - if (boost_score > 30.0 && (i > 3)) { - is_viable_kf = 1; - } else { - is_viable_kf = 0; - } - } - - return is_viable_kf; -} - -#define FRAMES_TO_CHECK_DECAY 8 -#define MIN_KF_TOT_BOOST 300 -#define DEFAULT_SCAN_FRAMES_FOR_KF_BOOST 32 -#define MAX_SCAN_FRAMES_FOR_KF_BOOST 48 -#define MIN_SCAN_FRAMES_FOR_KF_BOOST 32 -#define KF_ABS_ZOOM_THRESH 6.0 - -int vp9_get_frames_to_next_key(const VP9EncoderConfig *oxcf, - const TWO_PASS *const twopass, int kf_show_idx, - int min_gf_interval) { - const FIRST_PASS_INFO *first_pass_info = &twopass->first_pass_info; - double recent_loop_decay[FRAMES_TO_CHECK_DECAY]; - int j; - int frames_to_key; - int max_frames_to_key = first_pass_info->num_frames - kf_show_idx; - max_frames_to_key = VPXMIN(max_frames_to_key, oxcf->key_freq); - - // Initialize the decay rates for the recent frames to check - for (j = 0; j < FRAMES_TO_CHECK_DECAY; ++j) recent_loop_decay[j] = 1.0; - // Find the next keyframe. - if (!oxcf->auto_key) { - frames_to_key = max_frames_to_key; - } else { - frames_to_key = 1; - while (frames_to_key < max_frames_to_key) { - // Provided that we are not at the end of the file... - if (kf_show_idx + frames_to_key + 1 < first_pass_info->num_frames) { - double loop_decay_rate; - double decay_accumulator; - const FIRSTPASS_STATS *next_frame = fps_get_frame_stats( - first_pass_info, kf_show_idx + frames_to_key + 1); - - // Check for a scene cut. - if (test_candidate_kf(first_pass_info, kf_show_idx + frames_to_key)) - break; - - // How fast is the prediction quality decaying? - loop_decay_rate = get_prediction_decay_rate(twopass, next_frame); - - // We want to know something about the recent past... rather than - // as used elsewhere where we are concerned with decay in prediction - // quality since the last GF or KF. - recent_loop_decay[(frames_to_key - 1) % FRAMES_TO_CHECK_DECAY] = - loop_decay_rate; - decay_accumulator = 1.0; - for (j = 0; j < FRAMES_TO_CHECK_DECAY; ++j) - decay_accumulator *= recent_loop_decay[j]; - - // Special check for transition or high motion followed by a - // static scene. - if ((frames_to_key - 1) > min_gf_interval && loop_decay_rate >= 0.999 && - decay_accumulator < 0.9) { - int still_interval = oxcf->key_freq - (frames_to_key - 1); - // TODO(angiebird): Figure out why we use "+1" here - int show_idx = kf_show_idx + frames_to_key; - if (check_transition_to_still(first_pass_info, show_idx, - still_interval)) { - break; - } - } - } - ++frames_to_key; - } - } - return frames_to_key; -} - -static void find_next_key_frame(VP9_COMP *cpi, int kf_show_idx) { - int i; - RATE_CONTROL *const rc = &cpi->rc; - TWO_PASS *const twopass = &cpi->twopass; - GF_GROUP *const gf_group = &twopass->gf_group; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - const FIRST_PASS_INFO *first_pass_info = &twopass->first_pass_info; - const FRAME_INFO *frame_info = &cpi->frame_info; - const FIRSTPASS_STATS *const start_position = twopass->stats_in; - const FIRSTPASS_STATS *keyframe_stats = - fps_get_frame_stats(first_pass_info, kf_show_idx); - FIRSTPASS_STATS next_frame; - int kf_bits = 0; - int64_t max_kf_bits; - double zero_motion_accumulator = 1.0; - double zero_motion_sum = 0.0; - double zero_motion_avg; - double motion_compensable_sum = 0.0; - double motion_compensable_avg; - int num_frames = 0; - int kf_boost_scan_frames = DEFAULT_SCAN_FRAMES_FOR_KF_BOOST; - double boost_score = 0.0; - double kf_mod_err = 0.0; - double kf_raw_err = 0.0; - double kf_group_err = 0.0; - double sr_accumulator = 0.0; - double abs_mv_in_out_accumulator = 0.0; - const double av_err = get_distribution_av_err(cpi, twopass); - const double mean_mod_score = twopass->mean_mod_score; - vp9_zero(next_frame); - - cpi->common.frame_type = KEY_FRAME; - rc->frames_since_key = 0; - - // Reset the GF group data structures. - vp9_zero(*gf_group); - - // Is this a forced key frame by interval. - rc->this_key_frame_forced = rc->next_key_frame_forced; - - // Clear the alt ref active flag and last group multi arf flags as they - // can never be set for a key frame. - rc->source_alt_ref_active = 0; - - // KF is always a GF so clear frames till next gf counter. - rc->frames_till_gf_update_due = 0; - - rc->frames_to_key = 1; - - twopass->kf_group_bits = 0; // Total bits available to kf group - twopass->kf_group_error_left = 0.0; // Group modified error score. - - kf_raw_err = keyframe_stats->intra_error; - kf_mod_err = calc_norm_frame_score(oxcf, frame_info, keyframe_stats, - mean_mod_score, av_err); - - if (cpi->ext_ratectrl.ready && - (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_GOP) != 0 && - cpi->ext_ratectrl.funcs.get_key_frame_decision != NULL) { - vpx_rc_key_frame_decision_t key_frame_decision; - vpx_codec_err_t codec_status = vp9_extrc_get_key_frame_decision( - &cpi->ext_ratectrl, &key_frame_decision); - if (codec_status == VPX_CODEC_OK) { - rc->frames_to_key = key_frame_decision.key_frame_group_size; - } else { - vpx_internal_error(&cpi->common.error, codec_status, - "vp9_extrc_get_key_frame_decision() failed"); - } - } else { - rc->frames_to_key = vp9_get_frames_to_next_key(oxcf, twopass, kf_show_idx, - rc->min_gf_interval); - } - - // If there is a max kf interval set by the user we must obey it. - // We already breakout of the loop above at 2x max. - // This code centers the extra kf if the actual natural interval - // is between 1x and 2x. - if (rc->frames_to_key >= cpi->oxcf.key_freq) { - rc->next_key_frame_forced = 1; - } else { - rc->next_key_frame_forced = 0; - } - - for (i = 0; i < rc->frames_to_key; ++i) { - const FIRSTPASS_STATS *frame_stats = - fps_get_frame_stats(first_pass_info, kf_show_idx + i); - // Accumulate kf group error. - kf_group_err += calc_norm_frame_score(oxcf, frame_info, frame_stats, - mean_mod_score, av_err); - } - - // Calculate the number of bits that should be assigned to the kf group. - if (twopass->bits_left > 0 && twopass->normalized_score_left > 0.0) { - // Maximum number of bits for a single normal frame (not key frame). - const int max_bits = frame_max_bits(rc, &cpi->oxcf); - - // Maximum number of bits allocated to the key frame group. - int64_t max_grp_bits; - - // Default allocation based on bits left and relative - // complexity of the section. - twopass->kf_group_bits = - (int64_t)(twopass->bits_left * - (kf_group_err / twopass->normalized_score_left)); - - // Clip based on maximum per frame rate defined by the user. - max_grp_bits = (int64_t)max_bits * (int64_t)rc->frames_to_key; - if (twopass->kf_group_bits > max_grp_bits) - twopass->kf_group_bits = max_grp_bits; - } else { - twopass->kf_group_bits = 0; - } - twopass->kf_group_bits = VPXMAX(0, twopass->kf_group_bits); - - // Scan through the kf group collating various stats used to determine - // how many bits to spend on it. - boost_score = 0.0; - - for (i = 0; i < VPXMIN(MAX_SCAN_FRAMES_FOR_KF_BOOST, (rc->frames_to_key - 1)); - ++i) { - if (EOF == input_stats(twopass, &next_frame)) break; - - zero_motion_sum += next_frame.pcnt_inter - next_frame.pcnt_motion; - motion_compensable_sum += - 1 - (double)next_frame.coded_error / next_frame.intra_error; - num_frames++; - } - - if (num_frames >= MIN_SCAN_FRAMES_FOR_KF_BOOST) { - zero_motion_avg = zero_motion_sum / num_frames; - motion_compensable_avg = motion_compensable_sum / num_frames; - kf_boost_scan_frames = (int)(VPXMAX(64 * zero_motion_avg - 16, - 160 * motion_compensable_avg - 112)); - kf_boost_scan_frames = - VPXMAX(VPXMIN(kf_boost_scan_frames, MAX_SCAN_FRAMES_FOR_KF_BOOST), - MIN_SCAN_FRAMES_FOR_KF_BOOST); - } - reset_fpf_position(twopass, start_position); - - for (i = 0; i < (rc->frames_to_key - 1); ++i) { - if (EOF == input_stats(twopass, &next_frame)) break; - - // The zero motion test here insures that if we mark a kf group as static - // it is static throughout not just the first KF_BOOST_SCAN_MAX_FRAMES. - // It also allows for a larger boost on long static groups. - if ((i <= kf_boost_scan_frames) || (zero_motion_accumulator >= 0.99)) { - double frame_boost; - double zm_factor; - - // Monitor for static sections. - // First frame in kf group the second ref indicator is invalid. - if (i > 0) { - zero_motion_accumulator = - VPXMIN(zero_motion_accumulator, - get_zero_motion_factor(twopass, &next_frame)); - } else { - zero_motion_accumulator = - next_frame.pcnt_inter - next_frame.pcnt_motion; - } - - // Factor 0.75-1.25 based on how much of frame is static. - zm_factor = (0.75 + (zero_motion_accumulator / 2.0)); - - // The second (lagging) ref error is not valid immediately after - // a key frame because either the lag has not built up (in the case of - // the first key frame or it points to a reference before the new key - // frame. - if (i < 2) sr_accumulator = 0.0; - frame_boost = - calc_kf_frame_boost(cpi, &next_frame, &sr_accumulator, 0, zm_factor); - - boost_score += frame_boost; - - // Measure of zoom. Large zoom tends to indicate reduced boost. - abs_mv_in_out_accumulator += - fabs(next_frame.mv_in_out_count * next_frame.pcnt_motion); - - if ((frame_boost < 25.00) || - (abs_mv_in_out_accumulator > KF_ABS_ZOOM_THRESH) || - (sr_accumulator > (kf_raw_err * 1.50))) - break; - } else { - break; - } - } - - reset_fpf_position(twopass, start_position); - - // Store the zero motion percentage - twopass->kf_zeromotion_pct = (int)(zero_motion_accumulator * 100.0); - - // Calculate a section intra ratio used in setting max loop filter. - twopass->key_frame_section_intra_rating = calculate_section_intra_ratio( - start_position, twopass->stats_in_end, rc->frames_to_key); - - // Special case for static / slide show content but don't apply - // if the kf group is very short. - if ((zero_motion_accumulator > 0.99) && (rc->frames_to_key > 8)) { - rc->kf_boost = (int)(twopass->kf_max_total_boost); - } else { - // Apply various clamps for min and max oost - rc->kf_boost = VPXMAX((int)boost_score, (rc->frames_to_key * 3)); - rc->kf_boost = VPXMAX(rc->kf_boost, MIN_KF_TOT_BOOST); - rc->kf_boost = VPXMIN(rc->kf_boost, (int)(twopass->kf_max_total_boost)); - } - - // Work out how many bits to allocate for the key frame itself. - kf_bits = calculate_boost_bits((rc->frames_to_key - 1), rc->kf_boost, - twopass->kf_group_bits); - // Based on the spatial complexity, increase the bits allocated to key frame. - kf_bits += - (int)((twopass->kf_group_bits - kf_bits) * (kf_mod_err / kf_group_err)); - max_kf_bits = - twopass->kf_group_bits - (rc->frames_to_key - 1) * FRAME_OVERHEAD_BITS; - max_kf_bits = lclamp(max_kf_bits, 0, INT_MAX); - kf_bits = VPXMIN(kf_bits, (int)max_kf_bits); - - twopass->kf_group_bits -= kf_bits; - - // Save the bits to spend on the key frame. - gf_group->bit_allocation[0] = kf_bits; - gf_group->update_type[0] = KF_UPDATE; - gf_group->rf_level[0] = KF_STD; - gf_group->layer_depth[0] = 0; - - // Note the total error score of the kf group minus the key frame itself. - twopass->kf_group_error_left = (kf_group_err - kf_mod_err); - - // Adjust the count of total modified error left. - // The count of bits left is adjusted elsewhere based on real coded frame - // sizes. - twopass->normalized_score_left -= kf_group_err; - - if (oxcf->resize_mode == RESIZE_DYNAMIC) { - // Default to normal-sized frame on keyframes. - cpi->rc.next_frame_size_selector = UNSCALED; - } -} - -// Configure image size specific vizier parameters. -// Later these will be set via additional command line options -void vp9_init_vizier_params(TWO_PASS *const twopass, int screen_area) { - // When |use_vizier_rc_params| is 1, we expect the rc parameters below to - // have been initialised on the command line as adjustment factors such - // that a factor of 1.0 will match the default behavior when - // |use_vizier_rc_params| is 0 - if (twopass->use_vizier_rc_params) { - twopass->active_wq_factor *= AV_WQ_FACTOR; - twopass->err_per_mb *= BASELINE_ERR_PER_MB; - twopass->sr_default_decay_limit *= DEFAULT_DECAY_LIMIT; - if (twopass->sr_default_decay_limit > 1.0) // > 1.0 here makes no sense - twopass->sr_default_decay_limit = 1.0; - twopass->sr_diff_factor *= 1.0; - twopass->gf_frame_max_boost *= GF_MAX_FRAME_BOOST; - twopass->gf_max_total_boost *= MAX_GF_BOOST; - // NOTE: In use max boost has precedence over min boost. So even if min is - // somehow set higher than max the final boost value will be clamped to the - // appropriate maximum. - twopass->kf_frame_min_boost *= KF_MIN_FRAME_BOOST; - twopass->kf_frame_max_boost_first *= KF_MAX_FRAME_BOOST; - twopass->kf_frame_max_boost_subs *= KF_MAX_FRAME_BOOST; - twopass->kf_max_total_boost *= MAX_KF_TOT_BOOST; - twopass->zm_factor *= DEFAULT_ZM_FACTOR; - if (twopass->zm_factor > 1.0) // > 1.0 here makes no sense - twopass->zm_factor = 1.0; - - // Correction for the fact that the kf_err_per_mb_factor default is - // already different for different video formats and ensures that a passed - // in value of 1.0 on the vizier command line will still match the current - // default. - if (screen_area < 1280 * 720) { - twopass->kf_err_per_mb *= 2000.0; - } else if (screen_area < 1920 * 1080) { - twopass->kf_err_per_mb *= 500.0; - } else { - twopass->kf_err_per_mb *= 250.0; - } - } else { - // When |use_vizier_rc_params| is 0, use defaults. - twopass->active_wq_factor = AV_WQ_FACTOR; - twopass->err_per_mb = BASELINE_ERR_PER_MB; - twopass->sr_default_decay_limit = DEFAULT_DECAY_LIMIT; - twopass->sr_diff_factor = 1.0; - twopass->gf_frame_max_boost = GF_MAX_FRAME_BOOST; - twopass->gf_max_total_boost = MAX_GF_BOOST; - twopass->kf_frame_min_boost = KF_MIN_FRAME_BOOST; - twopass->kf_frame_max_boost_first = KF_MAX_FRAME_BOOST; - twopass->kf_frame_max_boost_subs = KF_MAX_FRAME_BOOST; - twopass->kf_max_total_boost = MAX_KF_TOT_BOOST; - twopass->zm_factor = DEFAULT_ZM_FACTOR; - - if (screen_area < 1280 * 720) { - twopass->kf_err_per_mb = 2000.0; - } else if (screen_area < 1920 * 1080) { - twopass->kf_err_per_mb = 500.0; - } else { - twopass->kf_err_per_mb = 250.0; - } - } -} - -void vp9_rc_get_second_pass_params(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - RATE_CONTROL *const rc = &cpi->rc; - TWO_PASS *const twopass = &cpi->twopass; - GF_GROUP *const gf_group = &twopass->gf_group; - FIRSTPASS_STATS this_frame; - const int show_idx = cm->current_video_frame; - - if (cpi->common.current_frame_coding_index == 0 && - cpi->ext_ratectrl.funcs.send_firstpass_stats != NULL) { - const vpx_codec_err_t codec_status = vp9_extrc_send_firstpass_stats( - &cpi->ext_ratectrl, &cpi->twopass.first_pass_info); - if (codec_status != VPX_CODEC_OK) { - vpx_internal_error(&cm->error, codec_status, - "vp9_extrc_send_firstpass_stats() failed"); - } - } - - if (!twopass->stats_in) return; - - // Configure image size specific vizier parameters - if (cm->current_video_frame == 0) { - unsigned int screen_area = (cm->width * cm->height); - - vp9_init_vizier_params(twopass, screen_area); - } - - // If this is an arf frame then we don't want to read the stats file or - // advance the input pointer as we already have what we need. - if (gf_group->update_type[gf_group->index] == ARF_UPDATE) { - int target_rate; - - vp9_zero(this_frame); - this_frame = - cpi->twopass.stats_in_start[cm->current_video_frame + - gf_group->arf_src_offset[gf_group->index]]; - - vp9_configure_buffer_updates(cpi, gf_group->index); - - target_rate = gf_group->bit_allocation[gf_group->index]; - target_rate = vp9_rc_clamp_pframe_target_size(cpi, target_rate); - rc->base_frame_target = target_rate; - - cm->frame_type = INTER_FRAME; - - // The multiplication by 256 reverses a scaling factor of (>> 8) - // applied when combining MB error values for the frame. - twopass->mb_av_energy = log((this_frame.intra_error * 256.0) + 1.0); - twopass->mb_smooth_pct = this_frame.intra_smooth_pct; - - return; - } - - vpx_clear_system_state(); - - if (cpi->oxcf.rc_mode == VPX_Q) { - twopass->active_worst_quality = cpi->oxcf.cq_level; - } else if (cm->current_video_frame == 0) { - const int frames_left = - (int)(twopass->total_stats.count - cm->current_video_frame); - // Special case code for first frame. - int64_t section_target_bandwidth = twopass->bits_left / frames_left; - section_target_bandwidth = VPXMIN(section_target_bandwidth, INT_MAX); - const double section_length = twopass->total_left_stats.count; - const double section_error = - twopass->total_left_stats.coded_error / section_length; - const double section_intra_skip = - twopass->total_left_stats.intra_skip_pct / section_length; - const double section_inactive_zone = - (twopass->total_left_stats.inactive_zone_rows * 2) / - ((double)cm->mb_rows * section_length); - const double section_noise = - twopass->total_left_stats.frame_noise_energy / section_length; - int tmp_q; - - tmp_q = get_twopass_worst_quality( - cpi, section_error, section_intra_skip + section_inactive_zone, - section_noise, (int)section_target_bandwidth); - - twopass->active_worst_quality = tmp_q; - twopass->baseline_active_worst_quality = tmp_q; - rc->ni_av_qi = tmp_q; - rc->last_q[INTER_FRAME] = tmp_q; - rc->avg_q = vp9_convert_qindex_to_q(tmp_q, cm->bit_depth); - rc->avg_frame_qindex[INTER_FRAME] = tmp_q; - rc->last_q[KEY_FRAME] = (tmp_q + cpi->oxcf.best_allowed_q) / 2; - rc->avg_frame_qindex[KEY_FRAME] = rc->last_q[KEY_FRAME]; - } - vp9_zero(this_frame); - if (EOF == input_stats(twopass, &this_frame)) return; - - // Set the frame content type flag. - if (this_frame.intra_skip_pct >= FC_ANIMATION_THRESH) - twopass->fr_content_type = FC_GRAPHICS_ANIMATION; - else - twopass->fr_content_type = FC_NORMAL; - - // Keyframe and section processing. - if (rc->frames_to_key == 0 || (cpi->frame_flags & FRAMEFLAGS_KEY)) { - // Define next KF group and assign bits to it. - find_next_key_frame(cpi, show_idx); - } else { - cm->frame_type = INTER_FRAME; - } - - // Define a new GF/ARF group. (Should always enter here for key frames). - if (rc->frames_till_gf_update_due == 0) { - define_gf_group(cpi, show_idx); - -#if ARF_STATS_OUTPUT - { - FILE *fpfile; - fpfile = fopen("arf.stt", "a"); - ++arf_count; - fprintf(fpfile, "%10d %10ld %10d %10d %10ld %10ld\n", - cm->current_video_frame, rc->baseline_gf_interval, rc->kf_boost, - arf_count, rc->gfu_boost, cm->frame_type); - - fclose(fpfile); - } -#endif - } - - if (rc->frames_till_gf_update_due == 0) { - if (cpi->ext_ratectrl.ready && cpi->ext_ratectrl.log_file) { - fprintf(cpi->ext_ratectrl.log_file, "GOP_INFO show_frame_count %d\n", - rc->baseline_gf_interval); - } - rc->frames_till_gf_update_due = rc->baseline_gf_interval; - } - - vp9_configure_buffer_updates(cpi, gf_group->index); - - rc->base_frame_target = gf_group->bit_allocation[gf_group->index]; - - // The multiplication by 256 reverses a scaling factor of (>> 8) - // applied when combining MB error values for the frame. - twopass->mb_av_energy = log((this_frame.intra_error * 256.0) + 1.0); - twopass->mb_smooth_pct = this_frame.intra_smooth_pct; - - // Update the total stats remaining structure. - subtract_stats(&twopass->total_left_stats, &this_frame); -} - -void vp9_twopass_postencode_update(VP9_COMP *cpi) { - TWO_PASS *const twopass = &cpi->twopass; - RATE_CONTROL *const rc = &cpi->rc; - VP9_COMMON *const cm = &cpi->common; - const int bits_used = rc->base_frame_target; - - // VBR correction is done through rc->vbr_bits_off_target. Based on the - // sign of this value, a limited % adjustment is made to the target rate - // of subsequent frames, to try and push it back towards 0. This method - // is designed to prevent extreme behaviour at the end of a clip - // or group of frames. - rc->vbr_bits_off_target += rc->base_frame_target - rc->projected_frame_size; - twopass->bits_left = VPXMAX(twopass->bits_left - bits_used, 0); - - // Target vs actual bits for this arf group. - twopass->rolling_arf_group_target_bits += rc->this_frame_target; - twopass->rolling_arf_group_actual_bits += rc->projected_frame_size; - - // Calculate the pct rc error. - if (rc->total_actual_bits) { - rc->rate_error_estimate = - (int)((rc->vbr_bits_off_target * 100) / rc->total_actual_bits); - rc->rate_error_estimate = clamp(rc->rate_error_estimate, -100, 100); - } else { - rc->rate_error_estimate = 0; - } - - if (cpi->common.frame_type != KEY_FRAME) { - twopass->kf_group_bits -= bits_used; - twopass->last_kfgroup_zeromotion_pct = twopass->kf_zeromotion_pct; - } - twopass->kf_group_bits = VPXMAX(twopass->kf_group_bits, 0); - - // Increment the gf group index ready for the next frame. - ++twopass->gf_group.index; - - // If the rate control is drifting consider adjustment to min or maxq. - if ((cpi->oxcf.rc_mode != VPX_Q) && !cpi->rc.is_src_frame_alt_ref) { - const int maxq_adj_limit = - rc->worst_quality - twopass->active_worst_quality; - const int minq_adj_limit = - (cpi->oxcf.rc_mode == VPX_CQ ? MINQ_ADJ_LIMIT_CQ : MINQ_ADJ_LIMIT); - int aq_extend_min = 0; - int aq_extend_max = 0; - - // Extend min or Max Q range to account for imbalance from the base - // value when using AQ. - if (cpi->oxcf.aq_mode != NO_AQ && cpi->oxcf.aq_mode != PSNR_AQ && - cpi->oxcf.aq_mode != PERCEPTUAL_AQ) { - if (cm->seg.aq_av_offset < 0) { - // The balance of the AQ map tends towarda lowering the average Q. - aq_extend_min = 0; - aq_extend_max = VPXMIN(maxq_adj_limit, -cm->seg.aq_av_offset); - } else { - // The balance of the AQ map tends towards raising the average Q. - aq_extend_min = VPXMIN(minq_adj_limit, cm->seg.aq_av_offset); - aq_extend_max = 0; - } - } - - // Undershoot. - if (rc->rate_error_estimate > cpi->oxcf.under_shoot_pct) { - --twopass->extend_maxq; - if (rc->rolling_target_bits >= rc->rolling_actual_bits) - ++twopass->extend_minq; - // Overshoot. - } else if (rc->rate_error_estimate < -cpi->oxcf.over_shoot_pct) { - --twopass->extend_minq; - if (rc->rolling_target_bits < rc->rolling_actual_bits) - ++twopass->extend_maxq; - } else { - // Adjustment for extreme local overshoot. - if (rc->projected_frame_size > (2 * rc->base_frame_target) && - rc->projected_frame_size > (2 * rc->avg_frame_bandwidth)) - ++twopass->extend_maxq; - - // Unwind undershoot or overshoot adjustment. - if (rc->rolling_target_bits < rc->rolling_actual_bits) - --twopass->extend_minq; - else if (rc->rolling_target_bits > rc->rolling_actual_bits) - --twopass->extend_maxq; - } - - twopass->extend_minq = - clamp(twopass->extend_minq, aq_extend_min, minq_adj_limit); - twopass->extend_maxq = - clamp(twopass->extend_maxq, aq_extend_max, maxq_adj_limit); - - // If there is a big and undexpected undershoot then feed the extra - // bits back in quickly. One situation where this may happen is if a - // frame is unexpectedly almost perfectly predicted by the ARF or GF - // but not very well predcited by the previous frame. - if (!frame_is_kf_gf_arf(cpi) && !cpi->rc.is_src_frame_alt_ref) { - int fast_extra_thresh = rc->base_frame_target / HIGH_UNDERSHOOT_RATIO; - if (rc->projected_frame_size < fast_extra_thresh) { - rc->vbr_bits_off_target_fast += - fast_extra_thresh - rc->projected_frame_size; - rc->vbr_bits_off_target_fast = - VPXMIN(rc->vbr_bits_off_target_fast, - (4 * (int64_t)rc->avg_frame_bandwidth)); - - // Fast adaptation of minQ if necessary to use up the extra bits. - if (rc->avg_frame_bandwidth) { - twopass->extend_minq_fast = - (int)(rc->vbr_bits_off_target_fast * 8 / rc->avg_frame_bandwidth); - } - twopass->extend_minq_fast = VPXMIN( - twopass->extend_minq_fast, minq_adj_limit - twopass->extend_minq); - } else if (rc->vbr_bits_off_target_fast) { - twopass->extend_minq_fast = VPXMIN( - twopass->extend_minq_fast, minq_adj_limit - twopass->extend_minq); - } else { - twopass->extend_minq_fast = 0; - } - } - } -} - -#if CONFIG_RATE_CTRL -void vp9_get_next_group_of_picture(const VP9_COMP *cpi, int *first_is_key_frame, - int *use_alt_ref, int *coding_frame_count, - int *first_show_idx, - int *last_gop_use_alt_ref) { - const GOP_COMMAND *gop_command = &cpi->encode_command.gop_command; - // We make a copy of rc here because we want to get information from the - // encoder without changing its state. - // TODO(angiebird): Avoid copying rc here. - RATE_CONTROL rc = cpi->rc; - const int multi_layer_arf = 0; - const int allow_alt_ref = 1; - // We assume that current_video_frame is updated to the show index of the - // frame we are about to called. Note that current_video_frame is updated at - // the end of encode_frame_to_data_rate(). - // TODO(angiebird): Avoid this kind of fragile style. - *first_show_idx = cpi->common.current_video_frame; - *last_gop_use_alt_ref = rc.source_alt_ref_active; - - *first_is_key_frame = 0; - if (rc.frames_to_key == 0) { - rc.frames_to_key = vp9_get_frames_to_next_key( - &cpi->oxcf, &cpi->twopass, *first_show_idx, rc.min_gf_interval); - rc.frames_since_key = 0; - *first_is_key_frame = 1; - } - - if (gop_command->use) { - *coding_frame_count = gop_command_coding_frame_count(gop_command); - *use_alt_ref = gop_command->use_alt_ref; - assert(gop_command->show_frame_count <= rc.frames_to_key); - } else { - *coding_frame_count = vp9_get_gop_coding_frame_count( - &cpi->oxcf, &cpi->twopass, &cpi->frame_info, &rc, *first_show_idx, - multi_layer_arf, allow_alt_ref, *first_is_key_frame, - *last_gop_use_alt_ref, use_alt_ref); - } -} - -int vp9_get_gop_coding_frame_count(const VP9EncoderConfig *oxcf, - const TWO_PASS *const twopass, - const FRAME_INFO *frame_info, - const RATE_CONTROL *rc, int show_idx, - int multi_layer_arf, int allow_alt_ref, - int first_is_key_frame, - int last_gop_use_alt_ref, int *use_alt_ref) { - int frame_count; - double gop_intra_factor; - const int arf_active_or_kf = last_gop_use_alt_ref || first_is_key_frame; - RANGE active_gf_interval; - int arf_layers; - int end_of_sequence = 0; - if (oxcf->use_simple_encode_api) { - active_gf_interval = get_active_gf_inverval_range_simple( - rc->min_gf_interval, arf_active_or_kf, rc->frames_to_key); - } else { - active_gf_interval = get_active_gf_inverval_range( - frame_info, rc, arf_active_or_kf, show_idx, /*active_worst_quality=*/0, - /*last_boosted_qindex=*/0); - } - - arf_layers = get_arf_layers(multi_layer_arf, oxcf->enable_auto_arf, - active_gf_interval.max); - if (multi_layer_arf) { - gop_intra_factor = 1.0 + 0.25 * arf_layers; - } else { - gop_intra_factor = 1.0; - } - - frame_count = get_gop_coding_frame_num( - use_alt_ref, frame_info, twopass, rc, show_idx, &active_gf_interval, - gop_intra_factor, oxcf->lag_in_frames, &end_of_sequence); - *use_alt_ref &= allow_alt_ref; - return frame_count; -} - -// Under CONFIG_RATE_CTRL, once the first_pass_info is ready, the number of -// coding frames (including show frame and alt ref) can be determined. -int vp9_get_coding_frame_num(const VP9EncoderConfig *oxcf, - const TWO_PASS *const twopass, - const FRAME_INFO *frame_info, int multi_layer_arf, - int allow_alt_ref) { - const FIRST_PASS_INFO *first_pass_info = &twopass->first_pass_info; - int coding_frame_num = 0; - RATE_CONTROL rc; - int gop_coding_frame_count; - int gop_show_frames; - int show_idx = 0; - int last_gop_use_alt_ref = 0; - vp9_rc_init(oxcf, 1, &rc); - - while (show_idx < first_pass_info->num_frames) { - int use_alt_ref; - int first_is_key_frame = 0; - if (rc.frames_to_key == 0) { - rc.frames_to_key = vp9_get_frames_to_next_key(oxcf, twopass, show_idx, - rc.min_gf_interval); - rc.frames_since_key = 0; - first_is_key_frame = 1; - } - - gop_coding_frame_count = vp9_get_gop_coding_frame_count( - oxcf, twopass, frame_info, &rc, show_idx, multi_layer_arf, - allow_alt_ref, first_is_key_frame, last_gop_use_alt_ref, &use_alt_ref); - - rc.source_alt_ref_active = use_alt_ref; - last_gop_use_alt_ref = use_alt_ref; - gop_show_frames = gop_coding_frame_count - use_alt_ref; - rc.frames_to_key -= gop_show_frames; - rc.frames_since_key += gop_show_frames; - show_idx += gop_show_frames; - coding_frame_num += gop_show_frames + use_alt_ref; - } - return coding_frame_num; -} - -void vp9_get_key_frame_map(const VP9EncoderConfig *oxcf, - const TWO_PASS *const twopass, int *key_frame_map) { - const FIRST_PASS_INFO *first_pass_info = &twopass->first_pass_info; - int show_idx = 0; - RATE_CONTROL rc; - vp9_rc_init(oxcf, 1, &rc); - - // key_frame_map points to an int array with size equal to - // first_pass_info->num_frames, which is also the number of show frames in the - // video. - memset(key_frame_map, 0, - sizeof(*key_frame_map) * first_pass_info->num_frames); - while (show_idx < first_pass_info->num_frames) { - int key_frame_group_size; - key_frame_map[show_idx] = 1; - key_frame_group_size = - vp9_get_frames_to_next_key(oxcf, twopass, show_idx, rc.min_gf_interval); - assert(key_frame_group_size > 0); - show_idx += key_frame_group_size; - } - assert(show_idx == first_pass_info->num_frames); -} -#endif // CONFIG_RATE_CTRL - -FIRSTPASS_STATS vp9_get_frame_stats(const TWO_PASS *twopass) { - return twopass->this_frame_stats; -} -FIRSTPASS_STATS vp9_get_total_stats(const TWO_PASS *twopass) { - return twopass->total_stats; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_firstpass.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_firstpass.h deleted file mode 100644 index 94b08374..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_firstpass.h +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_FIRSTPASS_H_ -#define VPX_VP9_ENCODER_VP9_FIRSTPASS_H_ - -#include - -#include "vp9/common/vp9_onyxc_int.h" -#include "vp9/encoder/vp9_firstpass_stats.h" -#include "vp9/encoder/vp9_lookahead.h" -#include "vp9/encoder/vp9_ratectrl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define INVALID_ROW (-1) - -#define MAX_ARF_LAYERS 6 -#define SECTION_NOISE_DEF 250.0 - -typedef struct { - double frame_mb_intra_factor; - double frame_mb_brightness_factor; - double frame_mb_neutral_count; -} FP_MB_FLOAT_STATS; - -typedef struct { - double intra_factor; - double brightness_factor; - int64_t coded_error; - int64_t sr_coded_error; - int64_t frame_noise_energy; - int64_t intra_error; - int intercount; - int second_ref_count; - double neutral_count; - double intra_count_low; // Coded intra but low variance - double intra_count_high; // Coded intra high variance - int intra_skip_count; - int image_data_start_row; - int mvcount; - int sum_mvr; - int sum_mvr_abs; - int sum_mvc; - int sum_mvc_abs; - int64_t sum_mvrs; - int64_t sum_mvcs; - int sum_in_vectors; - int intra_smooth_count; - int new_mv_count; -} FIRSTPASS_DATA; - -typedef enum { - KF_UPDATE = 0, - LF_UPDATE = 1, - GF_UPDATE = 2, - ARF_UPDATE = 3, - OVERLAY_UPDATE = 4, - MID_OVERLAY_UPDATE = 5, - USE_BUF_FRAME = 6, // Use show existing frame, no ref buffer update - FRAME_UPDATE_TYPES = 7 -} FRAME_UPDATE_TYPE; - -#define FC_ANIMATION_THRESH 0.15 -typedef enum { - FC_NORMAL = 0, - FC_GRAPHICS_ANIMATION = 1, - FRAME_CONTENT_TYPES = 2 -} FRAME_CONTENT_TYPE; - -typedef struct ExternalRcReference { - int last_index; - int golden_index; - int altref_index; -} ExternalRcReference; - -typedef struct { - unsigned char index; - RATE_FACTOR_LEVEL rf_level[MAX_STATIC_GF_GROUP_LENGTH + 2]; - FRAME_UPDATE_TYPE update_type[MAX_STATIC_GF_GROUP_LENGTH + 2]; - unsigned char arf_src_offset[MAX_STATIC_GF_GROUP_LENGTH + 2]; - unsigned char layer_depth[MAX_STATIC_GF_GROUP_LENGTH + 2]; - unsigned char frame_gop_index[MAX_STATIC_GF_GROUP_LENGTH + 2]; - int bit_allocation[MAX_STATIC_GF_GROUP_LENGTH + 2]; - int gfu_boost[MAX_STATIC_GF_GROUP_LENGTH + 2]; - int update_ref_idx[MAX_STATIC_GF_GROUP_LENGTH + 2]; - - int frame_start; - int frame_end; - // TODO(jingning): The array size of arf_stack could be reduced. - int arf_index_stack[MAX_LAG_BUFFERS * 2]; - int top_arf_idx; - int stack_size; - int gf_group_size; - int max_layer_depth; - int allowed_max_layer_depth; - int group_noise_energy; - - // Structure to store the reference information from external RC. - // Used to override reference frame decisions in libvpx. - ExternalRcReference ext_rc_ref[MAX_STATIC_GF_GROUP_LENGTH + 2]; - int ref_frame_list[MAX_STATIC_GF_GROUP_LENGTH + 2][REFS_PER_FRAME]; -} GF_GROUP; - -typedef struct { - const FIRSTPASS_STATS *stats; - int num_frames; -} FIRST_PASS_INFO; - -static INLINE void fps_init_first_pass_info(FIRST_PASS_INFO *first_pass_info, - const FIRSTPASS_STATS *stats, - int num_frames) { - first_pass_info->stats = stats; - first_pass_info->num_frames = num_frames; -} - -static INLINE int fps_get_num_frames(const FIRST_PASS_INFO *first_pass_info) { - return first_pass_info->num_frames; -} - -static INLINE const FIRSTPASS_STATS *fps_get_frame_stats( - const FIRST_PASS_INFO *first_pass_info, int show_idx) { - if (show_idx < 0 || show_idx >= first_pass_info->num_frames) { - return NULL; - } - return &first_pass_info->stats[show_idx]; -} - -typedef struct { - unsigned int section_intra_rating; - unsigned int key_frame_section_intra_rating; - FIRSTPASS_STATS total_stats; - FIRSTPASS_STATS this_frame_stats; - const FIRSTPASS_STATS *stats_in; - const FIRSTPASS_STATS *stats_in_start; - const FIRSTPASS_STATS *stats_in_end; - FIRST_PASS_INFO first_pass_info; - FIRSTPASS_STATS total_left_stats; - int first_pass_done; - int64_t bits_left; - double mean_mod_score; - double normalized_score_left; - double mb_av_energy; - double mb_smooth_pct; - - FP_MB_FLOAT_STATS *fp_mb_float_stats; - - // An indication of the content type of the current frame - FRAME_CONTENT_TYPE fr_content_type; - - // Projected total bits available for a key frame group of frames - int64_t kf_group_bits; - - // Error score of frames still to be coded in kf group - double kf_group_error_left; - - double bpm_factor; - int rolling_arf_group_target_bits; - int rolling_arf_group_actual_bits; - - int sr_update_lag; - int kf_zeromotion_pct; - int last_kfgroup_zeromotion_pct; - int active_worst_quality; - int baseline_active_worst_quality; - int extend_minq; - int extend_maxq; - int extend_minq_fast; - int arnr_strength_adjustment; - int last_qindex_of_arf_layer[MAX_ARF_LAYERS]; - - GF_GROUP gf_group; - - // Vizeir project experimental two pass rate control parameters. - // When |use_vizier_rc_params| is 1, the following parameters will - // be overwritten by pass in values. Otherwise, they are initialized - // by default values. - int use_vizier_rc_params; - double active_wq_factor; - double err_per_mb; - double sr_default_decay_limit; - double sr_diff_factor; - double kf_err_per_mb; - double kf_frame_min_boost; - double kf_frame_max_boost_first; // Max for first kf in a chunk. - double kf_frame_max_boost_subs; // Max for subsequent mid chunk kfs. - double kf_max_total_boost; - double gf_max_total_boost; - double gf_frame_max_boost; - double zm_factor; -} TWO_PASS; - -struct VP9_COMP; -struct ThreadData; -struct TileDataEnc; - -void vp9_init_first_pass(struct VP9_COMP *cpi); -void vp9_first_pass(struct VP9_COMP *cpi, const struct lookahead_entry *source); -void vp9_end_first_pass(struct VP9_COMP *cpi); - -void vp9_first_pass_encode_tile_mb_row(struct VP9_COMP *cpi, - struct ThreadData *td, - FIRSTPASS_DATA *fp_acc_data, - struct TileDataEnc *tile_data, - MV *best_ref_mv, int mb_row); - -void vp9_init_second_pass(struct VP9_COMP *cpi); -void vp9_rc_get_second_pass_params(struct VP9_COMP *cpi); -void vp9_init_vizier_params(TWO_PASS *const twopass, int screen_area); - -// Post encode update of the rate control parameters for 2-pass -void vp9_twopass_postencode_update(struct VP9_COMP *cpi); - -void calculate_coded_size(struct VP9_COMP *cpi, int *scaled_frame_width, - int *scaled_frame_height); - -struct VP9EncoderConfig; -int vp9_get_frames_to_next_key(const struct VP9EncoderConfig *oxcf, - const TWO_PASS *const twopass, int kf_show_idx, - int min_gf_interval); -#if CONFIG_RATE_CTRL -/* Call this function to get info about the next group of pictures. - * This function should be called after vp9_create_compressor() when encoding - * starts or after vp9_get_compressed_data() when the encoding process of - * the last group of pictures is just finished. - */ -void vp9_get_next_group_of_picture(const struct VP9_COMP *cpi, - int *first_is_key_frame, int *use_alt_ref, - int *coding_frame_count, int *first_show_idx, - int *last_gop_use_alt_ref); - -/*!\brief Call this function before coding a new group of pictures to get - * information about it. - * \param[in] oxcf Encoder config - * \param[in] twopass Twopass info - * \param[in] frame_info Frame info - * \param[in] rc Rate control state - * \param[in] show_idx Show index of the first frame in the group - * \param[in] multi_layer_arf Is multi-layer alternate reference used - * \param[in] allow_alt_ref Is alternate reference allowed - * \param[in] first_is_key_frame Is the first frame in the group a key frame - * \param[in] last_gop_use_alt_ref Does the last group use alternate reference - * - * \param[out] use_alt_ref Does this group use alternate reference - * - * \return Returns coding frame count - */ -int vp9_get_gop_coding_frame_count(const struct VP9EncoderConfig *oxcf, - const TWO_PASS *const twopass, - const FRAME_INFO *frame_info, - const RATE_CONTROL *rc, int show_idx, - int multi_layer_arf, int allow_alt_ref, - int first_is_key_frame, - int last_gop_use_alt_ref, int *use_alt_ref); - -int vp9_get_coding_frame_num(const struct VP9EncoderConfig *oxcf, - const TWO_PASS *const twopass, - const FRAME_INFO *frame_info, int multi_layer_arf, - int allow_alt_ref); - -/*!\brief Compute a key frame binary map indicates whether key frames appear - * in the corresponding positions. The passed in key_frame_map must point to an - * integer array with length equal to twopass->first_pass_info.num_frames, - * which is the number of show frames in the video. - */ -void vp9_get_key_frame_map(const struct VP9EncoderConfig *oxcf, - const TWO_PASS *const twopass, int *key_frame_map); -#endif // CONFIG_RATE_CTRL - -FIRSTPASS_STATS vp9_get_frame_stats(const TWO_PASS *twopass); -FIRSTPASS_STATS vp9_get_total_stats(const TWO_PASS *twopass); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_FIRSTPASS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_firstpass_stats.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_firstpass_stats.h deleted file mode 100644 index 01928e78..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_firstpass_stats.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_FIRSTPASS_STATS_H_ -#define VPX_VP9_ENCODER_VP9_FIRSTPASS_STATS_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - double frame; - double weight; - double intra_error; - double coded_error; - double sr_coded_error; - double frame_noise_energy; - double pcnt_inter; - double pcnt_motion; - double pcnt_second_ref; - double pcnt_neutral; - double pcnt_intra_low; // Coded intra but low variance - double pcnt_intra_high; // Coded intra high variance - double intra_skip_pct; - double intra_smooth_pct; // % of blocks that are smooth - double inactive_zone_rows; // Image mask rows top and bottom. - double inactive_zone_cols; // Image mask columns at left and right edges. - double MVr; - double mvr_abs; - double MVc; - double mvc_abs; - double MVrv; - double MVcv; - double mv_in_out_count; - double duration; - double count; - double new_mv_count; - int64_t spatial_layer_id; -} FIRSTPASS_STATS; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_FIRSTPASS_STATS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_frame_scale.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_frame_scale.c deleted file mode 100644 index c74d5232..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_frame_scale.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "./vpx_scale_rtcd.h" -#include "vp9/common/vp9_blockd.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vpx/vpx_codec.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_scale/yv12config.h" - -void vp9_scale_and_extend_frame_c(const YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst, - INTERP_FILTER filter_type, int phase_scaler) { - const int src_w = src->y_crop_width; - const int src_h = src->y_crop_height; - const uint8_t *const srcs[3] = { src->y_buffer, src->u_buffer, - src->v_buffer }; - const int src_strides[3] = { src->y_stride, src->uv_stride, src->uv_stride }; - uint8_t *const dsts[3] = { dst->y_buffer, dst->u_buffer, dst->v_buffer }; - const int dst_strides[3] = { dst->y_stride, dst->uv_stride, dst->uv_stride }; - const InterpKernel *const kernel = vp9_filter_kernels[filter_type]; - int x, y, i; - -#if HAVE_SSSE3 || HAVE_NEON - // TODO(linfengz): The 4:3 specialized C code is disabled by default since - // it's much slower than the general version which calls vpx_scaled_2d() even - // if vpx_scaled_2d() is not optimized. It will only be enabled as a reference - // for the platforms which have faster optimization. - if (4 * dst->y_crop_width == 3 * src_w && - 4 * dst->y_crop_height == 3 * src_h) { - // Specialize 4 to 3 scaling. - // Example pixel locations. - // (O: Original pixel. S: Scaled pixel. X: Overlapped pixel.) - // phase_scaler = 0 | phase_scaler = 8 - // | - // X O S O S O X | O O O O O - // | - // | - // | S S S - // | - // | - // O O O O O | O O O O O - // | - // S S S S | - // | - // | - // | S S S - // O O O O O | O O O O O - // | - // | - // | - // S S S S | - // | - // O O O O O | O O O O O - // | S S S - // | - // | - // | - // | - // X O S O S O X | O O O O O - - const int dst_ws[3] = { dst->y_crop_width, dst->uv_crop_width, - dst->uv_crop_width }; - const int dst_hs[3] = { dst->y_crop_height, dst->uv_crop_height, - dst->uv_crop_height }; - for (i = 0; i < MAX_MB_PLANE; ++i) { - const int dst_w = dst_ws[i]; - const int dst_h = dst_hs[i]; - const int src_stride = src_strides[i]; - const int dst_stride = dst_strides[i]; - for (y = 0; y < dst_h; y += 3) { - for (x = 0; x < dst_w; x += 3) { - const uint8_t *src_ptr = srcs[i] + 4 * y / 3 * src_stride + 4 * x / 3; - uint8_t *dst_ptr = dsts[i] + y * dst_stride + x; - - // Must call c function because its optimization doesn't support 3x3. - vpx_scaled_2d_c(src_ptr, src_stride, dst_ptr, dst_stride, kernel, - phase_scaler, 64 / 3, phase_scaler, 64 / 3, 3, 3); - } - } - } - } else -#endif - { - const int dst_w = dst->y_crop_width; - const int dst_h = dst->y_crop_height; - - // The issue b/311394513 reveals a corner case bug. vpx_scaled_2d() requires - // both x_step_q4 and y_step_q4 are less than or equal to 64. Otherwise, it - // needs to call vp9_scale_and_extend_frame_nonnormative() that supports - // arbitrary scaling. - const int x_step_q4 = 16 * src_w / dst_w; - const int y_step_q4 = 16 * src_h / dst_h; - if (x_step_q4 > 64 || y_step_q4 > 64) { - // This function is only called while cm->bit_depth is VPX_BITS_8. -#if CONFIG_VP9_HIGHBITDEPTH - vp9_scale_and_extend_frame_nonnormative(src, dst, (int)VPX_BITS_8); -#else - vp9_scale_and_extend_frame_nonnormative(src, dst); -#endif // CONFIG_VP9_HIGHBITDEPTH - return; - } - - for (i = 0; i < MAX_MB_PLANE; ++i) { - const int factor = (i == 0 || i == 3 ? 1 : 2); - const int src_stride = src_strides[i]; - const int dst_stride = dst_strides[i]; - for (y = 0; y < dst_h; y += 16) { - const int y_q4 = y * (16 / factor) * src_h / dst_h + phase_scaler; - for (x = 0; x < dst_w; x += 16) { - const int x_q4 = x * (16 / factor) * src_w / dst_w + phase_scaler; - const uint8_t *src_ptr = srcs[i] + - (y / factor) * src_h / dst_h * src_stride + - (x / factor) * src_w / dst_w; - uint8_t *dst_ptr = dsts[i] + (y / factor) * dst_stride + (x / factor); - - vpx_scaled_2d(src_ptr, src_stride, dst_ptr, dst_stride, kernel, - x_q4 & 0xf, 16 * src_w / dst_w, y_q4 & 0xf, - 16 * src_h / dst_h, 16 / factor, 16 / factor); - } - } - } - } - - vpx_extend_frame_borders(dst); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_job_queue.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_job_queue.h deleted file mode 100644 index ad09c111..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_job_queue.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_JOB_QUEUE_H_ -#define VPX_VP9_ENCODER_VP9_JOB_QUEUE_H_ - -typedef enum { - FIRST_PASS_JOB, - ENCODE_JOB, - ARNR_JOB, - NUM_JOB_TYPES, -} JOB_TYPE; - -// Encode job parameters -typedef struct { - int vert_unit_row_num; // Index of the vertical unit row - int tile_col_id; // tile col id within a tile - int tile_row_id; // tile col id within a tile -} JobNode; - -// Job queue element parameters -typedef struct { - // Pointer to the next link in the job queue - void *next; - - // Job information context of the module - JobNode job_info; -} JobQueue; - -// Job queue handle -typedef struct { - // Pointer to the next link in the job queue - void *next; - - // Counter to store the number of jobs picked up for processing - int num_jobs_acquired; -} JobQueueHandle; - -#endif // VPX_VP9_ENCODER_VP9_JOB_QUEUE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_lookahead.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_lookahead.c deleted file mode 100644 index b6be4f88..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_lookahead.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2011 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include -#include - -#include "./vpx_config.h" - -#include "vp9/common/vp9_common.h" - -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_extend.h" -#include "vp9/encoder/vp9_lookahead.h" - -/* Return the buffer at the given absolute index and increment the index */ -static struct lookahead_entry *pop(struct lookahead_ctx *ctx, int *idx) { - int index = *idx; - struct lookahead_entry *buf = ctx->buf + index; - - assert(index < ctx->max_sz); - if (++index >= ctx->max_sz) index -= ctx->max_sz; - *idx = index; - return buf; -} - -void vp9_lookahead_destroy(struct lookahead_ctx *ctx) { - if (ctx) { - if (ctx->buf) { - int i; - - for (i = 0; i < ctx->max_sz; i++) vpx_free_frame_buffer(&ctx->buf[i].img); - free(ctx->buf); - } - free(ctx); - } -} - -struct lookahead_ctx *vp9_lookahead_init(unsigned int width, - unsigned int height, - unsigned int subsampling_x, - unsigned int subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - int use_highbitdepth, -#endif - unsigned int depth) { - struct lookahead_ctx *ctx = NULL; - - // Clamp the lookahead queue depth - depth = clamp(depth, 1, MAX_LAG_BUFFERS); - - // Allocate memory to keep previous source frames available. - depth += MAX_PRE_FRAMES; - - // Allocate the lookahead structures - ctx = calloc(1, sizeof(*ctx)); - if (ctx) { - const int legacy_byte_alignment = 0; - unsigned int i; - ctx->max_sz = depth; - ctx->buf = calloc(depth, sizeof(*ctx->buf)); - ctx->next_show_idx = 0; - if (!ctx->buf) goto bail; - for (i = 0; i < depth; i++) - if (vpx_alloc_frame_buffer( - &ctx->buf[i].img, width, height, subsampling_x, subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS, legacy_byte_alignment)) - goto bail; - } - return ctx; -bail: - vp9_lookahead_destroy(ctx); - return NULL; -} - -int vp9_lookahead_full(const struct lookahead_ctx *ctx) { - return ctx->sz + 1 + MAX_PRE_FRAMES > ctx->max_sz; -} - -int vp9_lookahead_next_show_idx(const struct lookahead_ctx *ctx) { - return ctx->next_show_idx; -} - -int vp9_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src, - int64_t ts_start, int64_t ts_end, int use_highbitdepth, - vpx_enc_frame_flags_t flags) { - struct lookahead_entry *buf; - int width = src->y_crop_width; - int height = src->y_crop_height; - int uv_width = src->uv_crop_width; - int uv_height = src->uv_crop_height; - int subsampling_x = src->subsampling_x; - int subsampling_y = src->subsampling_y; - int larger_dimensions, new_dimensions; -#if !CONFIG_VP9_HIGHBITDEPTH - (void)use_highbitdepth; - assert(use_highbitdepth == 0); -#endif - - if (vp9_lookahead_full(ctx)) return 1; - ctx->sz++; - buf = pop(ctx, &ctx->write_idx); - - new_dimensions = width != buf->img.y_crop_width || - height != buf->img.y_crop_height || - uv_width != buf->img.uv_crop_width || - uv_height != buf->img.uv_crop_height; - larger_dimensions = - width > buf->img.y_crop_width || height > buf->img.y_crop_height || - uv_width > buf->img.uv_crop_width || uv_height > buf->img.uv_crop_height; - assert(!larger_dimensions || new_dimensions); - - if (larger_dimensions) { - YV12_BUFFER_CONFIG new_img; - memset(&new_img, 0, sizeof(new_img)); - if (vpx_alloc_frame_buffer(&new_img, width, height, subsampling_x, - subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS, 0)) - return 1; - vpx_free_frame_buffer(&buf->img); - buf->img = new_img; - } else if (new_dimensions) { - buf->img.y_width = src->y_width; - buf->img.y_height = src->y_height; - buf->img.uv_width = src->uv_width; - buf->img.uv_height = src->uv_height; - buf->img.y_crop_width = src->y_crop_width; - buf->img.y_crop_height = src->y_crop_height; - buf->img.uv_crop_width = src->uv_crop_width; - buf->img.uv_crop_height = src->uv_crop_height; - buf->img.subsampling_x = src->subsampling_x; - buf->img.subsampling_y = src->subsampling_y; - } - vp9_copy_and_extend_frame(src, &buf->img); - - buf->ts_start = ts_start; - buf->ts_end = ts_end; - buf->flags = flags; - buf->show_idx = ctx->next_show_idx; - ++ctx->next_show_idx; - return 0; -} - -struct lookahead_entry *vp9_lookahead_pop(struct lookahead_ctx *ctx, - int drain) { - struct lookahead_entry *buf = NULL; - - if (ctx && ctx->sz && (drain || ctx->sz == ctx->max_sz - MAX_PRE_FRAMES)) { - buf = pop(ctx, &ctx->read_idx); - ctx->sz--; - } - return buf; -} - -struct lookahead_entry *vp9_lookahead_peek(struct lookahead_ctx *ctx, - int index) { - struct lookahead_entry *buf = NULL; - - if (index >= 0) { - // Forward peek - if (index < ctx->sz) { - index += ctx->read_idx; - if (index >= ctx->max_sz) index -= ctx->max_sz; - buf = ctx->buf + index; - } - } else if (index < 0) { - // Backward peek - if (-index <= MAX_PRE_FRAMES) { - index += ctx->read_idx; - if (index < 0) index += ctx->max_sz; - buf = ctx->buf + index; - } - } - - return buf; -} - -unsigned int vp9_lookahead_depth(struct lookahead_ctx *ctx) { return ctx->sz; } diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_lookahead.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_lookahead.h deleted file mode 100644 index 6ac67366..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_lookahead.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2011 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_LOOKAHEAD_H_ -#define VPX_VP9_ENCODER_VP9_LOOKAHEAD_H_ - -#include "vpx_scale/yv12config.h" -#include "vpx/vpx_encoder.h" -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_LAG_BUFFERS 25 - -struct lookahead_entry { - YV12_BUFFER_CONFIG img; - int64_t ts_start; - int64_t ts_end; - int show_idx; /*The show_idx of this frame*/ - vpx_enc_frame_flags_t flags; -}; - -// The max of past frames we want to keep in the queue. -#define MAX_PRE_FRAMES 1 - -struct lookahead_ctx { - int max_sz; /* Absolute size of the queue */ - int sz; /* Number of buffers currently in the queue */ - int read_idx; /* Read index */ - int write_idx; /* Write index */ - int next_show_idx; /* The show_idx that will be assigned to the next frame - being pushed in the queue*/ - struct lookahead_entry *buf; /* Buffer list */ -}; - -/**\brief Initializes the lookahead stage - * - * The lookahead stage is a queue of frame buffers on which some analysis - * may be done when buffers are enqueued. - */ -struct lookahead_ctx *vp9_lookahead_init(unsigned int width, - unsigned int height, - unsigned int subsampling_x, - unsigned int subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - int use_highbitdepth, -#endif - unsigned int depth); - -/**\brief Destroys the lookahead stage - */ -void vp9_lookahead_destroy(struct lookahead_ctx *ctx); - -/**\brief Check if lookahead is full - * - * \param[in] ctx Pointer to the lookahead context - * - * Return 1 if lookahead is full, otherwise return 0. - */ -int vp9_lookahead_full(const struct lookahead_ctx *ctx); - -/**\brief Return the next_show_idx - * - * \param[in] ctx Pointer to the lookahead context - * - * Return the show_idx that will be assigned to the next - * frame pushed by vp9_lookahead_push() - */ -int vp9_lookahead_next_show_idx(const struct lookahead_ctx *ctx); - -/**\brief Enqueue a source buffer - * - * This function will copy the source image into a new framebuffer with - * the expected stride/border. - * - * \param[in] ctx Pointer to the lookahead context - * \param[in] src Pointer to the image to enqueue - * \param[in] ts_start Timestamp for the start of this frame - * \param[in] ts_end Timestamp for the end of this frame - * \param[in] flags Flags set on this frame - */ -int vp9_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src, - int64_t ts_start, int64_t ts_end, int use_highbitdepth, - vpx_enc_frame_flags_t flags); - -/**\brief Get the next source buffer to encode - * - * - * \param[in] ctx Pointer to the lookahead context - * \param[in] drain Flag indicating the buffer should be drained - * (return a buffer regardless of the current queue depth) - * - * \retval NULL, if drain set and queue is empty - * \retval NULL, if drain not set and queue not of the configured depth - */ -struct lookahead_entry *vp9_lookahead_pop(struct lookahead_ctx *ctx, int drain); - -/**\brief Get a future source buffer to encode - * - * \param[in] ctx Pointer to the lookahead context - * \param[in] index Index of the frame to be returned, 0 == next frame - * - * \retval NULL, if no buffer exists at the specified index - */ -struct lookahead_entry *vp9_lookahead_peek(struct lookahead_ctx *ctx, - int index); - -/**\brief Get the number of frames currently in the lookahead queue - * - * \param[in] ctx Pointer to the lookahead context - */ -unsigned int vp9_lookahead_depth(struct lookahead_ctx *ctx); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_LOOKAHEAD_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_mbgraph.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_mbgraph.c deleted file mode 100644 index 2f20a8fe..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_mbgraph.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vp9_rtcd.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/system_state.h" -#include "vp9/encoder/vp9_segmentation.h" -#include "vp9/encoder/vp9_mcomp.h" -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_reconinter.h" -#include "vp9/common/vp9_reconintra.h" - -static unsigned int do_16x16_motion_iteration(VP9_COMP *cpi, const MV *ref_mv, - MV *dst_mv, int mb_row, - int mb_col) { - MACROBLOCK *const x = &cpi->td.mb; - MACROBLOCKD *const xd = &x->e_mbd; - MV_SPEED_FEATURES *const mv_sf = &cpi->sf.mv; - const SEARCH_METHODS old_search_method = mv_sf->search_method; - const vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[BLOCK_16X16]; - const MvLimits tmp_mv_limits = x->mv_limits; - MV ref_full; - int cost_list[5]; - - // Further step/diamond searches as necessary - int step_param = mv_sf->reduce_first_step_size; - step_param = VPXMIN(step_param, MAX_MVSEARCH_STEPS - 2); - - vp9_set_mv_search_range(&x->mv_limits, ref_mv); - - ref_full.col = ref_mv->col >> 3; - ref_full.row = ref_mv->row >> 3; - - mv_sf->search_method = HEX; - vp9_full_pixel_search(cpi, x, BLOCK_16X16, &ref_full, step_param, - cpi->sf.mv.search_method, x->errorperbit, - cond_cost_list(cpi, cost_list), ref_mv, dst_mv, 0, 0); - mv_sf->search_method = old_search_method; - - /* restore UMV window */ - x->mv_limits = tmp_mv_limits; - - // Try sub-pixel MC - // if (bestsme > error_thresh && bestsme < INT_MAX) - { - uint32_t distortion; - uint32_t sse; - // TODO(yunqing): may use higher tap interp filter than 2 taps if needed. - cpi->find_fractional_mv_step( - x, dst_mv, ref_mv, cpi->common.allow_high_precision_mv, x->errorperbit, - &v_fn_ptr, 0, mv_sf->subpel_search_level, - cond_cost_list(cpi, cost_list), NULL, NULL, &distortion, &sse, NULL, 0, - 0, USE_2_TAPS); - } - - xd->mi[0]->mode = NEWMV; - xd->mi[0]->mv[0].as_mv = *dst_mv; - - vp9_build_inter_predictors_sby(xd, mb_row, mb_col, BLOCK_16X16); - - return vpx_sad16x16(x->plane[0].src.buf, x->plane[0].src.stride, - xd->plane[0].dst.buf, xd->plane[0].dst.stride); -} - -static int do_16x16_motion_search(VP9_COMP *cpi, const MV *ref_mv, - int_mv *dst_mv, int mb_row, int mb_col) { - MACROBLOCK *const x = &cpi->td.mb; - MACROBLOCKD *const xd = &x->e_mbd; - unsigned int err, tmp_err; - MV tmp_mv; - - // Try zero MV first - // FIXME should really use something like near/nearest MV and/or MV prediction - err = vpx_sad16x16(x->plane[0].src.buf, x->plane[0].src.stride, - xd->plane[0].pre[0].buf, xd->plane[0].pre[0].stride); - dst_mv->as_int = 0; - - // Test last reference frame using the previous best mv as the - // starting point (best reference) for the search - tmp_err = do_16x16_motion_iteration(cpi, ref_mv, &tmp_mv, mb_row, mb_col); - if (tmp_err < err) { - err = tmp_err; - dst_mv->as_mv = tmp_mv; - } - - // If the current best reference mv is not centered on 0,0 then do a 0,0 - // based search as well. - if (ref_mv->row != 0 || ref_mv->col != 0) { - MV zero_ref_mv = { 0, 0 }; - - tmp_err = - do_16x16_motion_iteration(cpi, &zero_ref_mv, &tmp_mv, mb_row, mb_col); - if (tmp_err < err) { - dst_mv->as_mv = tmp_mv; - err = tmp_err; - } - } - - return err; -} - -static int do_16x16_zerozero_search(VP9_COMP *cpi, int_mv *dst_mv) { - MACROBLOCK *const x = &cpi->td.mb; - MACROBLOCKD *const xd = &x->e_mbd; - unsigned int err; - - // Try zero MV first - // FIXME should really use something like near/nearest MV and/or MV prediction - err = vpx_sad16x16(x->plane[0].src.buf, x->plane[0].src.stride, - xd->plane[0].pre[0].buf, xd->plane[0].pre[0].stride); - - dst_mv->as_int = 0; - - return err; -} -static int find_best_16x16_intra(VP9_COMP *cpi, PREDICTION_MODE *pbest_mode) { - MACROBLOCK *const x = &cpi->td.mb; - MACROBLOCKD *const xd = &x->e_mbd; - PREDICTION_MODE best_mode = -1, mode; - unsigned int best_err = INT_MAX; - - // calculate SATD for each intra prediction mode; - // we're intentionally not doing 4x4, we just want a rough estimate - for (mode = DC_PRED; mode <= TM_PRED; mode++) { - unsigned int err; - - xd->mi[0]->mode = mode; - vp9_predict_intra_block(xd, 2, TX_16X16, mode, x->plane[0].src.buf, - x->plane[0].src.stride, xd->plane[0].dst.buf, - xd->plane[0].dst.stride, 0, 0, 0); - err = vpx_sad16x16(x->plane[0].src.buf, x->plane[0].src.stride, - xd->plane[0].dst.buf, xd->plane[0].dst.stride); - - // find best - if (err < best_err) { - best_err = err; - best_mode = mode; - } - } - - if (pbest_mode) *pbest_mode = best_mode; - - return best_err; -} - -static void update_mbgraph_mb_stats(VP9_COMP *cpi, MBGRAPH_MB_STATS *stats, - YV12_BUFFER_CONFIG *buf, int mb_y_offset, - YV12_BUFFER_CONFIG *golden_ref, - const MV *prev_golden_ref_mv, - YV12_BUFFER_CONFIG *alt_ref, int mb_row, - int mb_col) { - MACROBLOCK *const x = &cpi->td.mb; - MACROBLOCKD *const xd = &x->e_mbd; - int intra_error; - VP9_COMMON *cm = &cpi->common; - - // FIXME in practice we're completely ignoring chroma here - x->plane[0].src.buf = buf->y_buffer + mb_y_offset; - x->plane[0].src.stride = buf->y_stride; - - xd->plane[0].dst.buf = get_frame_new_buffer(cm)->y_buffer + mb_y_offset; - xd->plane[0].dst.stride = get_frame_new_buffer(cm)->y_stride; - - // do intra 16x16 prediction - intra_error = find_best_16x16_intra(cpi, &stats->ref[INTRA_FRAME].m.mode); - if (intra_error <= 0) intra_error = 1; - stats->ref[INTRA_FRAME].err = intra_error; - - // Golden frame MV search, if it exists and is different than last frame - if (golden_ref) { - int g_motion_error; - xd->plane[0].pre[0].buf = golden_ref->y_buffer + mb_y_offset; - xd->plane[0].pre[0].stride = golden_ref->y_stride; - g_motion_error = - do_16x16_motion_search(cpi, prev_golden_ref_mv, - &stats->ref[GOLDEN_FRAME].m.mv, mb_row, mb_col); - stats->ref[GOLDEN_FRAME].err = g_motion_error; - } else { - stats->ref[GOLDEN_FRAME].err = INT_MAX; - stats->ref[GOLDEN_FRAME].m.mv.as_int = 0; - } - - // Do an Alt-ref frame MV search, if it exists and is different than - // last/golden frame. - if (alt_ref) { - int a_motion_error; - xd->plane[0].pre[0].buf = alt_ref->y_buffer + mb_y_offset; - xd->plane[0].pre[0].stride = alt_ref->y_stride; - a_motion_error = - do_16x16_zerozero_search(cpi, &stats->ref[ALTREF_FRAME].m.mv); - - stats->ref[ALTREF_FRAME].err = a_motion_error; - } else { - stats->ref[ALTREF_FRAME].err = INT_MAX; - stats->ref[ALTREF_FRAME].m.mv.as_int = 0; - } -} - -static void update_mbgraph_frame_stats(VP9_COMP *cpi, - MBGRAPH_FRAME_STATS *stats, - YV12_BUFFER_CONFIG *buf, - YV12_BUFFER_CONFIG *golden_ref, - YV12_BUFFER_CONFIG *alt_ref) { - MACROBLOCK *const x = &cpi->td.mb; - MACROBLOCKD *const xd = &x->e_mbd; - VP9_COMMON *const cm = &cpi->common; - - int mb_col, mb_row, offset = 0; - int mb_y_offset = 0; - MV gld_top_mv = { 0, 0 }; - MODE_INFO mi_local; - MODE_INFO mi_above, mi_left; - - vp9_zero(mi_local); - // Set up limit values for motion vectors to prevent them extending outside - // the UMV borders. - x->mv_limits.row_min = -BORDER_MV_PIXELS_B16; - x->mv_limits.row_max = (cm->mb_rows - 1) * 8 + BORDER_MV_PIXELS_B16; - // Signal to vp9_predict_intra_block() that above is not available - xd->above_mi = NULL; - - xd->plane[0].dst.stride = buf->y_stride; - xd->plane[0].pre[0].stride = buf->y_stride; - xd->plane[1].dst.stride = buf->uv_stride; - xd->mi[0] = &mi_local; - mi_local.sb_type = BLOCK_16X16; - mi_local.ref_frame[0] = LAST_FRAME; - mi_local.ref_frame[1] = NO_REF_FRAME; - - for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) { - MV gld_left_mv = gld_top_mv; - int mb_y_in_offset = mb_y_offset; - - // Set up limit values for motion vectors to prevent them extending outside - // the UMV borders. - x->mv_limits.col_min = -BORDER_MV_PIXELS_B16; - x->mv_limits.col_max = (cm->mb_cols - 1) * 8 + BORDER_MV_PIXELS_B16; - // Signal to vp9_predict_intra_block() that left is not available - xd->left_mi = NULL; - - for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { - MBGRAPH_MB_STATS *mb_stats = &stats->mb_stats[offset + mb_col]; - - update_mbgraph_mb_stats(cpi, mb_stats, buf, mb_y_in_offset, golden_ref, - &gld_left_mv, alt_ref, mb_row, mb_col); - gld_left_mv = mb_stats->ref[GOLDEN_FRAME].m.mv.as_mv; - if (mb_col == 0) { - gld_top_mv = gld_left_mv; - } - // Signal to vp9_predict_intra_block() that left is available - xd->left_mi = &mi_left; - - mb_y_in_offset += 16; - x->mv_limits.col_min -= 16; - x->mv_limits.col_max -= 16; - } - - // Signal to vp9_predict_intra_block() that above is available - xd->above_mi = &mi_above; - - mb_y_offset += buf->y_stride * 16; - x->mv_limits.row_min -= 16; - x->mv_limits.row_max -= 16; - offset += cm->mb_cols; - } -} - -// void separate_arf_mbs_byzz -static void separate_arf_mbs(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - int mb_col, mb_row, offset, i; - int mi_row, mi_col; - int ncnt[4] = { 0 }; - int n_frames = cpi->mbgraph_n_frames; - - int *arf_not_zz; - - CHECK_MEM_ERROR( - &cm->error, arf_not_zz, - vpx_calloc(cm->mb_rows * cm->mb_cols * sizeof(*arf_not_zz), 1)); - - // We are not interested in results beyond the alt ref itself. - if (n_frames > cpi->rc.frames_till_gf_update_due) - n_frames = cpi->rc.frames_till_gf_update_due; - - // defer cost to reference frames - for (i = n_frames - 1; i >= 0; i--) { - MBGRAPH_FRAME_STATS *frame_stats = &cpi->mbgraph_stats[i]; - - for (offset = 0, mb_row = 0; mb_row < cm->mb_rows; - offset += cm->mb_cols, mb_row++) { - for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { - MBGRAPH_MB_STATS *mb_stats = &frame_stats->mb_stats[offset + mb_col]; - - int altref_err = mb_stats->ref[ALTREF_FRAME].err; - int intra_err = mb_stats->ref[INTRA_FRAME].err; - int golden_err = mb_stats->ref[GOLDEN_FRAME].err; - - // Test for altref vs intra and gf and that its mv was 0,0. - if (altref_err > 1000 || altref_err > intra_err || - altref_err > golden_err) { - arf_not_zz[offset + mb_col]++; - } - } - } - } - - // arf_not_zz is indexed by MB, but this loop is indexed by MI to avoid out - // of bound access in segmentation_map - for (mi_row = 0; mi_row < cm->mi_rows; mi_row++) { - for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) { - // If any of the blocks in the sequence failed then the MB - // goes in segment 0 - if (arf_not_zz[mi_row / 2 * cm->mb_cols + mi_col / 2]) { - ncnt[0]++; - cpi->segmentation_map[mi_row * cm->mi_cols + mi_col] = 0; - } else { - cpi->segmentation_map[mi_row * cm->mi_cols + mi_col] = 1; - ncnt[1]++; - } - } - } - - // Note % of blocks that are marked as static - if (cm->MBs) - cpi->static_mb_pct = (ncnt[1] * 100) / (cm->mi_rows * cm->mi_cols); - - // This error case should not be reachable as this function should - // never be called with the common data structure uninitialized. - else - cpi->static_mb_pct = 0; - - vp9_enable_segmentation(&cm->seg); - - // Free localy allocated storage - vpx_free(arf_not_zz); -} - -void vp9_update_mbgraph_stats(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - int i, n_frames = vp9_lookahead_depth(cpi->lookahead); - YV12_BUFFER_CONFIG *golden_ref = get_ref_frame_buffer(cpi, GOLDEN_FRAME); - - assert(golden_ref != NULL); - - // we need to look ahead beyond where the ARF transitions into - // being a GF - so exit if we don't look ahead beyond that - if (n_frames <= cpi->rc.frames_till_gf_update_due) return; - - if (n_frames > MAX_LAG_BUFFERS) n_frames = MAX_LAG_BUFFERS; - - cpi->mbgraph_n_frames = n_frames; - for (i = 0; i < n_frames; i++) { - MBGRAPH_FRAME_STATS *frame_stats = &cpi->mbgraph_stats[i]; - memset(frame_stats->mb_stats, 0, - cm->mb_rows * cm->mb_cols * sizeof(*cpi->mbgraph_stats[i].mb_stats)); - } - - // do motion search to find contribution of each reference to data - // later on in this GF group - // FIXME really, the GF/last MC search should be done forward, and - // the ARF MC search backwards, to get optimal results for MV caching - for (i = 0; i < n_frames; i++) { - MBGRAPH_FRAME_STATS *frame_stats = &cpi->mbgraph_stats[i]; - struct lookahead_entry *q_cur = vp9_lookahead_peek(cpi->lookahead, i); - - assert(q_cur != NULL); - - update_mbgraph_frame_stats(cpi, frame_stats, &q_cur->img, golden_ref, - cpi->Source); - } - - vpx_clear_system_state(); - - separate_arf_mbs(cpi); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_mbgraph.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_mbgraph.h deleted file mode 100644 index 7b629861..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_mbgraph.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_MBGRAPH_H_ -#define VPX_VP9_ENCODER_VP9_MBGRAPH_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - struct { - int err; - union { - int_mv mv; - PREDICTION_MODE mode; - } m; - } ref[MAX_REF_FRAMES]; -} MBGRAPH_MB_STATS; - -typedef struct { - MBGRAPH_MB_STATS *mb_stats; -} MBGRAPH_FRAME_STATS; - -struct VP9_COMP; - -void vp9_update_mbgraph_stats(struct VP9_COMP *cpi); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_MBGRAPH_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_mcomp.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_mcomp.c deleted file mode 100644 index cbe1c402..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_mcomp.c +++ /dev/null @@ -1,3035 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" - -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_mvref_common.h" -#include "vp9/common/vp9_reconinter.h" - -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_mcomp.h" - -// #define NEW_DIAMOND_SEARCH - -void vp9_set_mv_search_range(MvLimits *mv_limits, const MV *mv) { - int col_min = (mv->col >> 3) - MAX_FULL_PEL_VAL + (mv->col & 7 ? 1 : 0); - int row_min = (mv->row >> 3) - MAX_FULL_PEL_VAL + (mv->row & 7 ? 1 : 0); - int col_max = (mv->col >> 3) + MAX_FULL_PEL_VAL; - int row_max = (mv->row >> 3) + MAX_FULL_PEL_VAL; - - col_min = VPXMAX(col_min, (MV_LOW >> 3) + 1); - row_min = VPXMAX(row_min, (MV_LOW >> 3) + 1); - col_max = VPXMIN(col_max, (MV_UPP >> 3) - 1); - row_max = VPXMIN(row_max, (MV_UPP >> 3) - 1); - - // Get intersection of UMV window and valid MV window to reduce # of checks - // in diamond search. - if (mv_limits->col_min < col_min) mv_limits->col_min = col_min; - if (mv_limits->col_max > col_max) mv_limits->col_max = col_max; - if (mv_limits->row_min < row_min) mv_limits->row_min = row_min; - if (mv_limits->row_max > row_max) mv_limits->row_max = row_max; -} - -void vp9_set_subpel_mv_search_range(MvLimits *subpel_mv_limits, - const MvLimits *umv_window_limits, - const MV *ref_mv) { - subpel_mv_limits->col_min = VPXMAX(umv_window_limits->col_min * 8, - ref_mv->col - MAX_FULL_PEL_VAL * 8); - subpel_mv_limits->col_max = VPXMIN(umv_window_limits->col_max * 8, - ref_mv->col + MAX_FULL_PEL_VAL * 8); - subpel_mv_limits->row_min = VPXMAX(umv_window_limits->row_min * 8, - ref_mv->row - MAX_FULL_PEL_VAL * 8); - subpel_mv_limits->row_max = VPXMIN(umv_window_limits->row_max * 8, - ref_mv->row + MAX_FULL_PEL_VAL * 8); - - subpel_mv_limits->col_min = VPXMAX(MV_LOW + 1, subpel_mv_limits->col_min); - subpel_mv_limits->col_max = VPXMIN(MV_UPP - 1, subpel_mv_limits->col_max); - subpel_mv_limits->row_min = VPXMAX(MV_LOW + 1, subpel_mv_limits->row_min); - subpel_mv_limits->row_max = VPXMIN(MV_UPP - 1, subpel_mv_limits->row_max); -} - -int vp9_init_search_range(int size) { - int sr = 0; - // Minimum search size no matter what the passed in value. - size = VPXMAX(16, size); - - while ((size << sr) < MAX_FULL_PEL_VAL) sr++; - - sr = VPXMIN(sr, MAX_MVSEARCH_STEPS - 2); - return sr; -} - -int vp9_mv_bit_cost(const MV *mv, const MV *ref, const int *mvjcost, - int *mvcost[2], int weight) { - const MV diff = { mv->row - ref->row, mv->col - ref->col }; - return ROUND_POWER_OF_TWO(mv_cost(&diff, mvjcost, mvcost) * weight, 7); -} - -#define PIXEL_TRANSFORM_ERROR_SCALE 4 -static int mv_err_cost(const MV *mv, const MV *ref, const int *mvjcost, - int *mvcost[2], int error_per_bit) { - if (mvcost) { - const MV diff = { mv->row - ref->row, mv->col - ref->col }; - return (int)ROUND64_POWER_OF_TWO( - (int64_t)mv_cost(&diff, mvjcost, mvcost) * error_per_bit, - RDDIV_BITS + VP9_PROB_COST_SHIFT - RD_EPB_SHIFT + - PIXEL_TRANSFORM_ERROR_SCALE); - } - return 0; -} -void vp9_init_dsmotion_compensation(search_site_config *cfg, int stride) { - int len; - int ss_count = 0; - - for (len = MAX_FIRST_STEP; len > 0; len /= 2) { - // Generate offsets for 4 search sites per step. - const MV ss_mvs[] = { { -len, 0 }, { len, 0 }, { 0, -len }, { 0, len } }; - int i; - for (i = 0; i < 4; ++i, ++ss_count) { - cfg->ss_mv[ss_count] = ss_mvs[i]; - cfg->ss_os[ss_count] = ss_mvs[i].row * stride + ss_mvs[i].col; - } - } - - cfg->searches_per_step = 4; - cfg->total_steps = ss_count / cfg->searches_per_step; -} - -void vp9_init3smotion_compensation(search_site_config *cfg, int stride) { - int len; - int ss_count = 0; - - for (len = MAX_FIRST_STEP; len > 0; len /= 2) { - // Generate offsets for 8 search sites per step. - const MV ss_mvs[8] = { { -len, 0 }, { len, 0 }, { 0, -len }, - { 0, len }, { -len, -len }, { -len, len }, - { len, -len }, { len, len } }; - int i; - for (i = 0; i < 8; ++i, ++ss_count) { - cfg->ss_mv[ss_count] = ss_mvs[i]; - cfg->ss_os[ss_count] = ss_mvs[i].row * stride + ss_mvs[i].col; - } - } - - cfg->searches_per_step = 8; - cfg->total_steps = ss_count / cfg->searches_per_step; -} - -// convert motion vector component to offset for sv[a]f calc -static INLINE int sp(int x) { return x & 7; } - -static INLINE const uint8_t *pre(const uint8_t *buf, int stride, int r, int c) { - return &buf[(r >> 3) * stride + (c >> 3)]; -} - -#if CONFIG_VP9_HIGHBITDEPTH -/* checks if (r, c) has better score than previous best */ -#define CHECK_BETTER(v, r, c) \ - do { \ - if (c >= minc && c <= maxc && r >= minr && r <= maxr) { \ - int64_t tmpmse; \ - const MV cb_mv = { r, c }; \ - const MV cb_ref_mv = { rr, rc }; \ - if (second_pred == NULL) { \ - thismse = vfp->svf(pre(y, y_stride, r, c), y_stride, sp(c), sp(r), z, \ - src_stride, &sse); \ - } else { \ - thismse = vfp->svaf(pre(y, y_stride, r, c), y_stride, sp(c), sp(r), z, \ - src_stride, &sse, second_pred); \ - } \ - tmpmse = thismse; \ - tmpmse += \ - mv_err_cost(&cb_mv, &cb_ref_mv, mvjcost, mvcost, error_per_bit); \ - if (tmpmse >= INT_MAX) { \ - v = INT_MAX; \ - } else if ((v = (uint32_t)tmpmse) < besterr) { \ - besterr = v; \ - br = r; \ - bc = c; \ - *distortion = thismse; \ - *sse1 = sse; \ - } \ - } else { \ - v = INT_MAX; \ - } \ - } while (0) -#else -/* checks if (r, c) has better score than previous best */ -#define CHECK_BETTER(v, r, c) \ - do { \ - if (c >= minc && c <= maxc && r >= minr && r <= maxr) { \ - const MV cb_mv = { r, c }; \ - const MV cb_ref_mv = { rr, rc }; \ - if (second_pred == NULL) \ - thismse = vfp->svf(pre(y, y_stride, r, c), y_stride, sp(c), sp(r), z, \ - src_stride, &sse); \ - else \ - thismse = vfp->svaf(pre(y, y_stride, r, c), y_stride, sp(c), sp(r), z, \ - src_stride, &sse, second_pred); \ - if ((v = mv_err_cost(&cb_mv, &cb_ref_mv, mvjcost, mvcost, \ - error_per_bit) + \ - thismse) < besterr) { \ - besterr = v; \ - br = r; \ - bc = c; \ - *distortion = thismse; \ - *sse1 = sse; \ - } \ - } else { \ - v = INT_MAX; \ - } \ - } while (0) - -#endif -#define FIRST_LEVEL_CHECKS \ - do { \ - unsigned int left, right, up, down, diag; \ - CHECK_BETTER(left, tr, tc - hstep); \ - CHECK_BETTER(right, tr, tc + hstep); \ - CHECK_BETTER(up, tr - hstep, tc); \ - CHECK_BETTER(down, tr + hstep, tc); \ - whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2); \ - switch (whichdir) { \ - case 0: CHECK_BETTER(diag, tr - hstep, tc - hstep); break; \ - case 1: CHECK_BETTER(diag, tr - hstep, tc + hstep); break; \ - case 2: CHECK_BETTER(diag, tr + hstep, tc - hstep); break; \ - case 3: CHECK_BETTER(diag, tr + hstep, tc + hstep); break; \ - } \ - } while (0) - -#define SECOND_LEVEL_CHECKS \ - do { \ - int kr, kc; \ - unsigned int second; \ - if (tr != br && tc != bc) { \ - kr = br - tr; \ - kc = bc - tc; \ - CHECK_BETTER(second, tr + kr, tc + 2 * kc); \ - CHECK_BETTER(second, tr + 2 * kr, tc + kc); \ - } else if (tr == br && tc != bc) { \ - kc = bc - tc; \ - CHECK_BETTER(second, tr + hstep, tc + 2 * kc); \ - CHECK_BETTER(second, tr - hstep, tc + 2 * kc); \ - switch (whichdir) { \ - case 0: \ - case 1: CHECK_BETTER(second, tr + hstep, tc + kc); break; \ - case 2: \ - case 3: CHECK_BETTER(second, tr - hstep, tc + kc); break; \ - } \ - } else if (tr != br && tc == bc) { \ - kr = br - tr; \ - CHECK_BETTER(second, tr + 2 * kr, tc + hstep); \ - CHECK_BETTER(second, tr + 2 * kr, tc - hstep); \ - switch (whichdir) { \ - case 0: \ - case 2: CHECK_BETTER(second, tr + kr, tc + hstep); break; \ - case 1: \ - case 3: CHECK_BETTER(second, tr + kr, tc - hstep); break; \ - } \ - } \ - } while (0) - -#define SETUP_SUBPEL_SEARCH \ - const uint8_t *const z = x->plane[0].src.buf; \ - const int src_stride = x->plane[0].src.stride; \ - const MACROBLOCKD *xd = &x->e_mbd; \ - unsigned int besterr = UINT_MAX; \ - unsigned int sse; \ - unsigned int whichdir; \ - int thismse; \ - const unsigned int halfiters = iters_per_step; \ - const unsigned int quarteriters = iters_per_step; \ - const unsigned int eighthiters = iters_per_step; \ - const int y_stride = xd->plane[0].pre[0].stride; \ - const int offset = bestmv->row * y_stride + bestmv->col; \ - const uint8_t *const y = xd->plane[0].pre[0].buf; \ - \ - int rr = ref_mv->row; \ - int rc = ref_mv->col; \ - int br = bestmv->row * 8; \ - int bc = bestmv->col * 8; \ - int hstep = 4; \ - int minc, maxc, minr, maxr; \ - int tr = br; \ - int tc = bc; \ - MvLimits subpel_mv_limits; \ - \ - vp9_set_subpel_mv_search_range(&subpel_mv_limits, &x->mv_limits, ref_mv); \ - minc = subpel_mv_limits.col_min; \ - maxc = subpel_mv_limits.col_max; \ - minr = subpel_mv_limits.row_min; \ - maxr = subpel_mv_limits.row_max; \ - \ - bestmv->row *= 8; \ - bestmv->col *= 8 - -static unsigned int setup_center_error( - const MACROBLOCKD *xd, const MV *bestmv, const MV *ref_mv, - int error_per_bit, const vp9_variance_fn_ptr_t *vfp, - const uint8_t *const src, const int src_stride, const uint8_t *const y, - int y_stride, const uint8_t *second_pred, int w, int h, int offset, - int *mvjcost, int *mvcost[2], uint32_t *sse1, uint32_t *distortion) { -#if CONFIG_VP9_HIGHBITDEPTH - uint64_t besterr; - if (second_pred != NULL) { - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - DECLARE_ALIGNED(16, uint16_t, comp_pred16[64 * 64]); - vpx_highbd_comp_avg_pred(comp_pred16, CONVERT_TO_SHORTPTR(second_pred), w, - h, CONVERT_TO_SHORTPTR(y + offset), y_stride); - besterr = - vfp->vf(CONVERT_TO_BYTEPTR(comp_pred16), w, src, src_stride, sse1); - } else { - DECLARE_ALIGNED(32, uint8_t, comp_pred[64 * 64]); - vpx_comp_avg_pred(comp_pred, second_pred, w, h, y + offset, y_stride); - besterr = vfp->vf(comp_pred, w, src, src_stride, sse1); - } - } else { - besterr = vfp->vf(y + offset, y_stride, src, src_stride, sse1); - } - *distortion = (uint32_t)besterr; - besterr += mv_err_cost(bestmv, ref_mv, mvjcost, mvcost, error_per_bit); - if (besterr >= UINT_MAX) return UINT_MAX; - return (uint32_t)besterr; -#else - uint32_t besterr; - (void)xd; - if (second_pred != NULL) { - DECLARE_ALIGNED(32, uint8_t, comp_pred[64 * 64]); - vpx_comp_avg_pred(comp_pred, second_pred, w, h, y + offset, y_stride); - besterr = vfp->vf(comp_pred, w, src, src_stride, sse1); - } else { - besterr = vfp->vf(y + offset, y_stride, src, src_stride, sse1); - } - *distortion = besterr; - besterr += mv_err_cost(bestmv, ref_mv, mvjcost, mvcost, error_per_bit); - return besterr; -#endif // CONFIG_VP9_HIGHBITDEPTH -} - -static INLINE int64_t divide_and_round(const int64_t n, const int64_t d) { - return ((n < 0) ^ (d < 0)) ? ((n - d / 2) / d) : ((n + d / 2) / d); -} - -static INLINE int is_cost_list_wellbehaved(int *cost_list) { - return cost_list[0] < cost_list[1] && cost_list[0] < cost_list[2] && - cost_list[0] < cost_list[3] && cost_list[0] < cost_list[4]; -} - -// Returns surface minima estimate at given precision in 1/2^n bits. -// Assume a model for the cost surface: S = A(x - x0)^2 + B(y - y0)^2 + C -// For a given set of costs S0, S1, S2, S3, S4 at points -// (y, x) = (0, 0), (0, -1), (1, 0), (0, 1) and (-1, 0) respectively, -// the solution for the location of the minima (x0, y0) is given by: -// x0 = 1/2 (S1 - S3)/(S1 + S3 - 2*S0), -// y0 = 1/2 (S4 - S2)/(S4 + S2 - 2*S0). -// The code below is an integerized version of that. -static void get_cost_surf_min(int *cost_list, int *ir, int *ic, int bits) { - const int64_t x0 = (int64_t)cost_list[1] - cost_list[3]; - const int64_t y0 = cost_list[1] - 2 * (int64_t)cost_list[0] + cost_list[3]; - const int64_t x1 = (int64_t)cost_list[4] - cost_list[2]; - const int64_t y1 = cost_list[4] - 2 * (int64_t)cost_list[0] + cost_list[2]; - const int b = 1 << (bits - 1); - *ic = (int)divide_and_round(x0 * b, y0); - *ir = (int)divide_and_round(x1 * b, y1); -} - -uint32_t vp9_skip_sub_pixel_tree( - const MACROBLOCK *x, MV *bestmv, const MV *ref_mv, int allow_hp, - int error_per_bit, const vp9_variance_fn_ptr_t *vfp, int forced_stop, - int iters_per_step, int *cost_list, int *mvjcost, int *mvcost[2], - uint32_t *distortion, uint32_t *sse1, const uint8_t *second_pred, int w, - int h, int use_accurate_subpel_search) { - SETUP_SUBPEL_SEARCH; - besterr = setup_center_error(xd, bestmv, ref_mv, error_per_bit, vfp, z, - src_stride, y, y_stride, second_pred, w, h, - offset, mvjcost, mvcost, sse1, distortion); - (void)halfiters; - (void)quarteriters; - (void)eighthiters; - (void)whichdir; - (void)allow_hp; - (void)forced_stop; - (void)hstep; - (void)rr; - (void)rc; - (void)minr; - (void)minc; - (void)maxr; - (void)maxc; - (void)tr; - (void)tc; - (void)sse; - (void)thismse; - (void)cost_list; - (void)use_accurate_subpel_search; - - return besterr; -} - -uint32_t vp9_find_best_sub_pixel_tree_pruned_evenmore( - const MACROBLOCK *x, MV *bestmv, const MV *ref_mv, int allow_hp, - int error_per_bit, const vp9_variance_fn_ptr_t *vfp, int forced_stop, - int iters_per_step, int *cost_list, int *mvjcost, int *mvcost[2], - uint32_t *distortion, uint32_t *sse1, const uint8_t *second_pred, int w, - int h, int use_accurate_subpel_search) { - SETUP_SUBPEL_SEARCH; - besterr = setup_center_error(xd, bestmv, ref_mv, error_per_bit, vfp, z, - src_stride, y, y_stride, second_pred, w, h, - offset, mvjcost, mvcost, sse1, distortion); - (void)halfiters; - (void)quarteriters; - (void)eighthiters; - (void)whichdir; - (void)allow_hp; - (void)forced_stop; - (void)hstep; - (void)use_accurate_subpel_search; - - if (cost_list && cost_list[0] != INT_MAX && cost_list[1] != INT_MAX && - cost_list[2] != INT_MAX && cost_list[3] != INT_MAX && - cost_list[4] != INT_MAX && is_cost_list_wellbehaved(cost_list)) { - int ir, ic; - unsigned int minpt = INT_MAX; - get_cost_surf_min(cost_list, &ir, &ic, 2); - if (ir != 0 || ic != 0) { - CHECK_BETTER(minpt, tr + 2 * ir, tc + 2 * ic); - } - } else { - FIRST_LEVEL_CHECKS; - if (halfiters > 1) { - SECOND_LEVEL_CHECKS; - } - - tr = br; - tc = bc; - - // Each subsequent iteration checks at least one point in common with - // the last iteration could be 2 ( if diag selected) 1/4 pel - // Note forced_stop: 0 - full, 1 - qtr only, 2 - half only - if (forced_stop != 2) { - hstep >>= 1; - FIRST_LEVEL_CHECKS; - if (quarteriters > 1) { - SECOND_LEVEL_CHECKS; - } - } - } - - tr = br; - tc = bc; - - if (allow_hp && use_mv_hp(ref_mv) && forced_stop == 0) { - hstep >>= 1; - FIRST_LEVEL_CHECKS; - if (eighthiters > 1) { - SECOND_LEVEL_CHECKS; - } - } - - bestmv->row = br; - bestmv->col = bc; - - return besterr; -} - -uint32_t vp9_find_best_sub_pixel_tree_pruned_more( - const MACROBLOCK *x, MV *bestmv, const MV *ref_mv, int allow_hp, - int error_per_bit, const vp9_variance_fn_ptr_t *vfp, int forced_stop, - int iters_per_step, int *cost_list, int *mvjcost, int *mvcost[2], - uint32_t *distortion, uint32_t *sse1, const uint8_t *second_pred, int w, - int h, int use_accurate_subpel_search) { - SETUP_SUBPEL_SEARCH; - (void)use_accurate_subpel_search; - - besterr = setup_center_error(xd, bestmv, ref_mv, error_per_bit, vfp, z, - src_stride, y, y_stride, second_pred, w, h, - offset, mvjcost, mvcost, sse1, distortion); - if (cost_list && cost_list[0] != INT_MAX && cost_list[1] != INT_MAX && - cost_list[2] != INT_MAX && cost_list[3] != INT_MAX && - cost_list[4] != INT_MAX && is_cost_list_wellbehaved(cost_list)) { - unsigned int minpt; - int ir, ic; - get_cost_surf_min(cost_list, &ir, &ic, 1); - if (ir != 0 || ic != 0) { - CHECK_BETTER(minpt, tr + ir * hstep, tc + ic * hstep); - } - } else { - FIRST_LEVEL_CHECKS; - if (halfiters > 1) { - SECOND_LEVEL_CHECKS; - } - } - - // Each subsequent iteration checks at least one point in common with - // the last iteration could be 2 ( if diag selected) 1/4 pel - - // Note forced_stop: 0 - full, 1 - qtr only, 2 - half only - if (forced_stop != 2) { - tr = br; - tc = bc; - hstep >>= 1; - FIRST_LEVEL_CHECKS; - if (quarteriters > 1) { - SECOND_LEVEL_CHECKS; - } - } - - if (allow_hp && use_mv_hp(ref_mv) && forced_stop == 0) { - tr = br; - tc = bc; - hstep >>= 1; - FIRST_LEVEL_CHECKS; - if (eighthiters > 1) { - SECOND_LEVEL_CHECKS; - } - } - // These lines insure static analysis doesn't warn that - // tr and tc aren't used after the above point. - (void)tr; - (void)tc; - - bestmv->row = br; - bestmv->col = bc; - - return besterr; -} - -uint32_t vp9_find_best_sub_pixel_tree_pruned( - const MACROBLOCK *x, MV *bestmv, const MV *ref_mv, int allow_hp, - int error_per_bit, const vp9_variance_fn_ptr_t *vfp, int forced_stop, - int iters_per_step, int *cost_list, int *mvjcost, int *mvcost[2], - uint32_t *distortion, uint32_t *sse1, const uint8_t *second_pred, int w, - int h, int use_accurate_subpel_search) { - SETUP_SUBPEL_SEARCH; - (void)use_accurate_subpel_search; - - besterr = setup_center_error(xd, bestmv, ref_mv, error_per_bit, vfp, z, - src_stride, y, y_stride, second_pred, w, h, - offset, mvjcost, mvcost, sse1, distortion); - if (cost_list && cost_list[0] != INT_MAX && cost_list[1] != INT_MAX && - cost_list[2] != INT_MAX && cost_list[3] != INT_MAX && - cost_list[4] != INT_MAX) { - unsigned int left, right, up, down, diag; - whichdir = (cost_list[1] < cost_list[3] ? 0 : 1) + - (cost_list[2] < cost_list[4] ? 0 : 2); - switch (whichdir) { - case 0: - CHECK_BETTER(left, tr, tc - hstep); - CHECK_BETTER(down, tr + hstep, tc); - CHECK_BETTER(diag, tr + hstep, tc - hstep); - break; - case 1: - CHECK_BETTER(right, tr, tc + hstep); - CHECK_BETTER(down, tr + hstep, tc); - CHECK_BETTER(diag, tr + hstep, tc + hstep); - break; - case 2: - CHECK_BETTER(left, tr, tc - hstep); - CHECK_BETTER(up, tr - hstep, tc); - CHECK_BETTER(diag, tr - hstep, tc - hstep); - break; - case 3: - CHECK_BETTER(right, tr, tc + hstep); - CHECK_BETTER(up, tr - hstep, tc); - CHECK_BETTER(diag, tr - hstep, tc + hstep); - break; - } - } else { - FIRST_LEVEL_CHECKS; - if (halfiters > 1) { - SECOND_LEVEL_CHECKS; - } - } - - tr = br; - tc = bc; - - // Each subsequent iteration checks at least one point in common with - // the last iteration could be 2 ( if diag selected) 1/4 pel - - // Note forced_stop: 0 - full, 1 - qtr only, 2 - half only - if (forced_stop != 2) { - hstep >>= 1; - FIRST_LEVEL_CHECKS; - if (quarteriters > 1) { - SECOND_LEVEL_CHECKS; - } - tr = br; - tc = bc; - } - - if (allow_hp && use_mv_hp(ref_mv) && forced_stop == 0) { - hstep >>= 1; - FIRST_LEVEL_CHECKS; - if (eighthiters > 1) { - SECOND_LEVEL_CHECKS; - } - tr = br; - tc = bc; - } - // These lines insure static analysis doesn't warn that - // tr and tc aren't used after the above point. - (void)tr; - (void)tc; - - bestmv->row = br; - bestmv->col = bc; - - return besterr; -} - -/* clang-format off */ -static const MV search_step_table[12] = { - // left, right, up, down - { 0, -4 }, { 0, 4 }, { -4, 0 }, { 4, 0 }, - { 0, -2 }, { 0, 2 }, { -2, 0 }, { 2, 0 }, - { 0, -1 }, { 0, 1 }, { -1, 0 }, { 1, 0 } -}; -/* clang-format on */ - -static int accurate_sub_pel_search( - const MACROBLOCKD *xd, const MV *this_mv, const struct scale_factors *sf, - const InterpKernel *kernel, const vp9_variance_fn_ptr_t *vfp, - const uint8_t *const src_address, const int src_stride, - const uint8_t *const pre_address, int y_stride, const uint8_t *second_pred, - int w, int h, uint32_t *sse) { -#if CONFIG_VP9_HIGHBITDEPTH - uint64_t besterr; - assert(sf->x_step_q4 == 16 && sf->y_step_q4 == 16); - assert(w != 0 && h != 0); - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - DECLARE_ALIGNED(16, uint16_t, pred16[64 * 64]); - vp9_highbd_build_inter_predictor(CONVERT_TO_SHORTPTR(pre_address), y_stride, - pred16, w, this_mv, sf, w, h, 0, kernel, - MV_PRECISION_Q3, 0, 0, xd->bd); - if (second_pred != NULL) { - DECLARE_ALIGNED(16, uint16_t, comp_pred16[64 * 64]); - vpx_highbd_comp_avg_pred(comp_pred16, CONVERT_TO_SHORTPTR(second_pred), w, - h, pred16, w); - besterr = vfp->vf(CONVERT_TO_BYTEPTR(comp_pred16), w, src_address, - src_stride, sse); - } else { - besterr = - vfp->vf(CONVERT_TO_BYTEPTR(pred16), w, src_address, src_stride, sse); - } - } else { - DECLARE_ALIGNED(16, uint8_t, pred[64 * 64]); - vp9_build_inter_predictor(pre_address, y_stride, pred, w, this_mv, sf, w, h, - 0, kernel, MV_PRECISION_Q3, 0, 0); - if (second_pred != NULL) { - DECLARE_ALIGNED(32, uint8_t, comp_pred[64 * 64]); - vpx_comp_avg_pred(comp_pred, second_pred, w, h, pred, w); - besterr = vfp->vf(comp_pred, w, src_address, src_stride, sse); - } else { - besterr = vfp->vf(pred, w, src_address, src_stride, sse); - } - } - if (besterr >= UINT_MAX) return UINT_MAX; - return (int)besterr; -#else - int besterr; - DECLARE_ALIGNED(16, uint8_t, pred[64 * 64]); - assert(sf->x_step_q4 == 16 && sf->y_step_q4 == 16); - assert(w != 0 && h != 0); - (void)xd; - - vp9_build_inter_predictor(pre_address, y_stride, pred, w, this_mv, sf, w, h, - 0, kernel, MV_PRECISION_Q3, 0, 0); - if (second_pred != NULL) { - DECLARE_ALIGNED(32, uint8_t, comp_pred[64 * 64]); - vpx_comp_avg_pred(comp_pred, second_pred, w, h, pred, w); - besterr = vfp->vf(comp_pred, w, src_address, src_stride, sse); - } else { - besterr = vfp->vf(pred, w, src_address, src_stride, sse); - } - return besterr; -#endif // CONFIG_VP9_HIGHBITDEPTH -} - -// TODO(yunqing): this part can be further refactored. -#if CONFIG_VP9_HIGHBITDEPTH -/* checks if (r, c) has better score than previous best */ -#define CHECK_BETTER1(v, r, c) \ - do { \ - if (c >= minc && c <= maxc && r >= minr && r <= maxr) { \ - int64_t tmpmse; \ - const MV cb_mv = { r, c }; \ - const MV cb_ref_mv = { rr, rc }; \ - thismse = accurate_sub_pel_search(xd, &cb_mv, x->me_sf, kernel, vfp, z, \ - src_stride, y, y_stride, second_pred, \ - w, h, &sse); \ - tmpmse = thismse; \ - tmpmse += \ - mv_err_cost(&cb_mv, &cb_ref_mv, mvjcost, mvcost, error_per_bit); \ - if (tmpmse >= INT_MAX) { \ - v = INT_MAX; \ - } else if ((v = (uint32_t)tmpmse) < besterr) { \ - besterr = v; \ - br = r; \ - bc = c; \ - *distortion = thismse; \ - *sse1 = sse; \ - } \ - } else { \ - v = INT_MAX; \ - } \ - } while (0) -#else -/* checks if (r, c) has better score than previous best */ -#define CHECK_BETTER1(v, r, c) \ - do { \ - if (c >= minc && c <= maxc && r >= minr && r <= maxr) { \ - const MV cb_mv = { r, c }; \ - const MV cb_ref_mv = { rr, rc }; \ - thismse = accurate_sub_pel_search(xd, &cb_mv, x->me_sf, kernel, vfp, z, \ - src_stride, y, y_stride, second_pred, \ - w, h, &sse); \ - if ((v = mv_err_cost(&cb_mv, &cb_ref_mv, mvjcost, mvcost, \ - error_per_bit) + \ - thismse) < besterr) { \ - besterr = v; \ - br = r; \ - bc = c; \ - *distortion = thismse; \ - *sse1 = sse; \ - } \ - } else { \ - v = INT_MAX; \ - } \ - } while (0) - -#endif - -uint32_t vp9_find_best_sub_pixel_tree( - const MACROBLOCK *x, MV *bestmv, const MV *ref_mv, int allow_hp, - int error_per_bit, const vp9_variance_fn_ptr_t *vfp, int forced_stop, - int iters_per_step, int *cost_list, int *mvjcost, int *mvcost[2], - uint32_t *distortion, uint32_t *sse1, const uint8_t *second_pred, int w, - int h, int use_accurate_subpel_search) { - const uint8_t *const z = x->plane[0].src.buf; - const uint8_t *const src_address = z; - const int src_stride = x->plane[0].src.stride; - const MACROBLOCKD *xd = &x->e_mbd; - unsigned int besterr = UINT_MAX; - unsigned int sse; - int thismse; - const int y_stride = xd->plane[0].pre[0].stride; - const int offset = bestmv->row * y_stride + bestmv->col; - const uint8_t *const y = xd->plane[0].pre[0].buf; - - int rr = ref_mv->row; - int rc = ref_mv->col; - int br = bestmv->row * 8; - int bc = bestmv->col * 8; - int hstep = 4; - int iter, round = 3 - forced_stop; - - int minc, maxc, minr, maxr; - int tr = br; - int tc = bc; - const MV *search_step = search_step_table; - int idx, best_idx = -1; - unsigned int cost_array[5]; - int kr, kc; - MvLimits subpel_mv_limits; - - // TODO(yunqing): need to add 4-tap filter optimization to speed up the - // encoder. - const InterpKernel *kernel = - (use_accurate_subpel_search > 0) - ? ((use_accurate_subpel_search == USE_4_TAPS) - ? vp9_filter_kernels[FOURTAP] - : ((use_accurate_subpel_search == USE_8_TAPS) - ? vp9_filter_kernels[EIGHTTAP] - : vp9_filter_kernels[EIGHTTAP_SHARP])) - : vp9_filter_kernels[BILINEAR]; - - vp9_set_subpel_mv_search_range(&subpel_mv_limits, &x->mv_limits, ref_mv); - minc = subpel_mv_limits.col_min; - maxc = subpel_mv_limits.col_max; - minr = subpel_mv_limits.row_min; - maxr = subpel_mv_limits.row_max; - - if (!(allow_hp && use_mv_hp(ref_mv))) - if (round == 3) round = 2; - - bestmv->row *= 8; - bestmv->col *= 8; - - besterr = setup_center_error(xd, bestmv, ref_mv, error_per_bit, vfp, z, - src_stride, y, y_stride, second_pred, w, h, - offset, mvjcost, mvcost, sse1, distortion); - - (void)cost_list; // to silence compiler warning - - for (iter = 0; iter < round; ++iter) { - // Check vertical and horizontal sub-pixel positions. - for (idx = 0; idx < 4; ++idx) { - tr = br + search_step[idx].row; - tc = bc + search_step[idx].col; - if (tc >= minc && tc <= maxc && tr >= minr && tr <= maxr) { - MV this_mv; - this_mv.row = tr; - this_mv.col = tc; - - if (use_accurate_subpel_search) { - thismse = accurate_sub_pel_search(xd, &this_mv, x->me_sf, kernel, vfp, - src_address, src_stride, y, - y_stride, second_pred, w, h, &sse); - } else { - const uint8_t *const pre_address = - y + (tr >> 3) * y_stride + (tc >> 3); - if (second_pred == NULL) - thismse = vfp->svf(pre_address, y_stride, sp(tc), sp(tr), - src_address, src_stride, &sse); - else - thismse = vfp->svaf(pre_address, y_stride, sp(tc), sp(tr), - src_address, src_stride, &sse, second_pred); - } - - cost_array[idx] = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, - mvcost, error_per_bit); - - if (cost_array[idx] < besterr) { - best_idx = idx; - besterr = cost_array[idx]; - *distortion = thismse; - *sse1 = sse; - } - } else { - cost_array[idx] = UINT_MAX; - } - } - - // Check diagonal sub-pixel position - kc = (cost_array[0] <= cost_array[1] ? -hstep : hstep); - kr = (cost_array[2] <= cost_array[3] ? -hstep : hstep); - - tc = bc + kc; - tr = br + kr; - if (tc >= minc && tc <= maxc && tr >= minr && tr <= maxr) { - MV this_mv = { tr, tc }; - if (use_accurate_subpel_search) { - thismse = accurate_sub_pel_search(xd, &this_mv, x->me_sf, kernel, vfp, - src_address, src_stride, y, y_stride, - second_pred, w, h, &sse); - } else { - const uint8_t *const pre_address = y + (tr >> 3) * y_stride + (tc >> 3); - if (second_pred == NULL) - thismse = vfp->svf(pre_address, y_stride, sp(tc), sp(tr), src_address, - src_stride, &sse); - else - thismse = vfp->svaf(pre_address, y_stride, sp(tc), sp(tr), - src_address, src_stride, &sse, second_pred); - } - - cost_array[4] = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, - error_per_bit); - - if (cost_array[4] < besterr) { - best_idx = 4; - besterr = cost_array[4]; - *distortion = thismse; - *sse1 = sse; - } - } else { - cost_array[idx] = UINT_MAX; - } - - if (best_idx < 4 && best_idx >= 0) { - br += search_step[best_idx].row; - bc += search_step[best_idx].col; - } else if (best_idx == 4) { - br = tr; - bc = tc; - } - - if (iters_per_step > 0 && best_idx != -1) { - unsigned int second; - const int br0 = br; - const int bc0 = bc; - assert(tr == br || tc == bc); - - if (tr == br && tc != bc) { - kc = bc - tc; - if (iters_per_step == 1) { - if (use_accurate_subpel_search) { - CHECK_BETTER1(second, br0, bc0 + kc); - } else { - CHECK_BETTER(second, br0, bc0 + kc); - } - } - } else if (tr != br && tc == bc) { - kr = br - tr; - if (iters_per_step == 1) { - if (use_accurate_subpel_search) { - CHECK_BETTER1(second, br0 + kr, bc0); - } else { - CHECK_BETTER(second, br0 + kr, bc0); - } - } - } - - if (iters_per_step > 1) { - if (use_accurate_subpel_search) { - CHECK_BETTER1(second, br0 + kr, bc0); - CHECK_BETTER1(second, br0, bc0 + kc); - if (br0 != br || bc0 != bc) { - CHECK_BETTER1(second, br0 + kr, bc0 + kc); - } - } else { - CHECK_BETTER(second, br0 + kr, bc0); - CHECK_BETTER(second, br0, bc0 + kc); - if (br0 != br || bc0 != bc) { - CHECK_BETTER(second, br0 + kr, bc0 + kc); - } - } - } - } - - search_step += 4; - hstep >>= 1; - best_idx = -1; - } - - // Each subsequent iteration checks at least one point in common with - // the last iteration could be 2 ( if diag selected) 1/4 pel - - // These lines insure static analysis doesn't warn that - // tr and tc aren't used after the above point. - (void)tr; - (void)tc; - - bestmv->row = br; - bestmv->col = bc; - - return besterr; -} - -#undef CHECK_BETTER -#undef CHECK_BETTER1 - -static INLINE int check_bounds(const MvLimits *mv_limits, int row, int col, - int range) { - return ((row - range) >= mv_limits->row_min) & - ((row + range) <= mv_limits->row_max) & - ((col - range) >= mv_limits->col_min) & - ((col + range) <= mv_limits->col_max); -} - -static INLINE int is_mv_in(const MvLimits *mv_limits, const MV *mv) { - return (mv->col >= mv_limits->col_min) && (mv->col <= mv_limits->col_max) && - (mv->row >= mv_limits->row_min) && (mv->row <= mv_limits->row_max); -} - -#define CHECK_BETTER \ - { \ - if (thissad < bestsad) { \ - if (use_mvcost) \ - thissad += mvsad_err_cost(x, &this_mv, &fcenter_mv, sad_per_bit); \ - if (thissad < bestsad) { \ - bestsad = thissad; \ - best_site = i; \ - } \ - } \ - } - -#define MAX_PATTERN_SCALES 11 -#define MAX_PATTERN_CANDIDATES 8 // max number of candidates per scale -#define PATTERN_CANDIDATES_REF 3 // number of refinement candidates - -// Calculate and return a sad+mvcost list around an integer best pel. -static INLINE void calc_int_cost_list(const MACROBLOCK *x, const MV *ref_mv, - int sadpb, - const vp9_variance_fn_ptr_t *fn_ptr, - const MV *best_mv, int *cost_list) { - static const MV neighbors[4] = { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 } }; - const struct buf_2d *const what = &x->plane[0].src; - const struct buf_2d *const in_what = &x->e_mbd.plane[0].pre[0]; - const MV fcenter_mv = { ref_mv->row >> 3, ref_mv->col >> 3 }; - int br = best_mv->row; - int bc = best_mv->col; - const MV mv = { br, bc }; - int i; - unsigned int sse; - - cost_list[0] = - fn_ptr->vf(what->buf, what->stride, get_buf_from_mv(in_what, &mv), - in_what->stride, &sse) + - mvsad_err_cost(x, &mv, &fcenter_mv, sadpb); - if (check_bounds(&x->mv_limits, br, bc, 1)) { - for (i = 0; i < 4; i++) { - const MV this_mv = { br + neighbors[i].row, bc + neighbors[i].col }; - cost_list[i + 1] = fn_ptr->vf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), - in_what->stride, &sse) + - mv_err_cost(&this_mv, &fcenter_mv, x->nmvjointcost, - x->mvcost, x->errorperbit); - } - } else { - for (i = 0; i < 4; i++) { - const MV this_mv = { br + neighbors[i].row, bc + neighbors[i].col }; - if (!is_mv_in(&x->mv_limits, &this_mv)) - cost_list[i + 1] = INT_MAX; - else - cost_list[i + 1] = fn_ptr->vf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), - in_what->stride, &sse) + - mv_err_cost(&this_mv, &fcenter_mv, x->nmvjointcost, - x->mvcost, x->errorperbit); - } - } -} - -// Generic pattern search function that searches over multiple scales. -// Each scale can have a different number of candidates and shape of -// candidates as indicated in the num_candidates and candidates arrays -// passed into this function -// -static int vp9_pattern_search( - const MACROBLOCK *x, MV *ref_mv, int search_param, int sad_per_bit, - int do_init_search, int *cost_list, const vp9_variance_fn_ptr_t *vfp, - int use_mvcost, const MV *center_mv, MV *best_mv, - const int num_candidates[MAX_PATTERN_SCALES], - const MV candidates[MAX_PATTERN_SCALES][MAX_PATTERN_CANDIDATES]) { - const MACROBLOCKD *const xd = &x->e_mbd; - static const int search_param_to_steps[MAX_MVSEARCH_STEPS] = { - 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, - }; - int i, s, t; - const struct buf_2d *const what = &x->plane[0].src; - const struct buf_2d *const in_what = &xd->plane[0].pre[0]; - int br, bc; - int bestsad = INT_MAX; - int thissad; - int k = -1; - const MV fcenter_mv = { center_mv->row >> 3, center_mv->col >> 3 }; - int best_init_s = search_param_to_steps[search_param]; - // adjust ref_mv to make sure it is within MV range - clamp_mv(ref_mv, x->mv_limits.col_min, x->mv_limits.col_max, - x->mv_limits.row_min, x->mv_limits.row_max); - br = ref_mv->row; - bc = ref_mv->col; - - // Work out the start point for the search - bestsad = vfp->sdf(what->buf, what->stride, get_buf_from_mv(in_what, ref_mv), - in_what->stride) + - mvsad_err_cost(x, ref_mv, &fcenter_mv, sad_per_bit); - - // Search all possible scales up to the search param around the center point - // pick the scale of the point that is best as the starting scale of - // further steps around it. - if (do_init_search) { - s = best_init_s; - best_init_s = -1; - for (t = 0; t <= s; ++t) { - int best_site = -1; - if (check_bounds(&x->mv_limits, br, bc, 1 << t)) { - for (i = 0; i < num_candidates[t]; i++) { - const MV this_mv = { br + candidates[t][i].row, - bc + candidates[t][i].col }; - thissad = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - CHECK_BETTER - } - } else { - for (i = 0; i < num_candidates[t]; i++) { - const MV this_mv = { br + candidates[t][i].row, - bc + candidates[t][i].col }; - if (!is_mv_in(&x->mv_limits, &this_mv)) continue; - thissad = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - CHECK_BETTER - } - } - if (best_site == -1) { - continue; - } else { - best_init_s = t; - k = best_site; - } - } - if (best_init_s != -1) { - br += candidates[best_init_s][k].row; - bc += candidates[best_init_s][k].col; - } - } - - // If the center point is still the best, just skip this and move to - // the refinement step. - if (best_init_s != -1) { - int best_site = -1; - s = best_init_s; - - do { - // No need to search all 6 points the 1st time if initial search was used - if (!do_init_search || s != best_init_s) { - if (check_bounds(&x->mv_limits, br, bc, 1 << s)) { - for (i = 0; i < num_candidates[s]; i++) { - const MV this_mv = { br + candidates[s][i].row, - bc + candidates[s][i].col }; - thissad = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - CHECK_BETTER - } - } else { - for (i = 0; i < num_candidates[s]; i++) { - const MV this_mv = { br + candidates[s][i].row, - bc + candidates[s][i].col }; - if (!is_mv_in(&x->mv_limits, &this_mv)) continue; - thissad = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - CHECK_BETTER - } - } - - if (best_site == -1) { - continue; - } else { - br += candidates[s][best_site].row; - bc += candidates[s][best_site].col; - k = best_site; - } - } - - do { - int next_chkpts_indices[PATTERN_CANDIDATES_REF]; - best_site = -1; - next_chkpts_indices[0] = (k == 0) ? num_candidates[s] - 1 : k - 1; - next_chkpts_indices[1] = k; - next_chkpts_indices[2] = (k == num_candidates[s] - 1) ? 0 : k + 1; - - if (check_bounds(&x->mv_limits, br, bc, 1 << s)) { - for (i = 0; i < PATTERN_CANDIDATES_REF; i++) { - const MV this_mv = { - br + candidates[s][next_chkpts_indices[i]].row, - bc + candidates[s][next_chkpts_indices[i]].col - }; - thissad = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - CHECK_BETTER - } - } else { - for (i = 0; i < PATTERN_CANDIDATES_REF; i++) { - const MV this_mv = { - br + candidates[s][next_chkpts_indices[i]].row, - bc + candidates[s][next_chkpts_indices[i]].col - }; - if (!is_mv_in(&x->mv_limits, &this_mv)) continue; - thissad = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - CHECK_BETTER - } - } - - if (best_site != -1) { - k = next_chkpts_indices[best_site]; - br += candidates[s][k].row; - bc += candidates[s][k].col; - } - } while (best_site != -1); - } while (s--); - } - - best_mv->row = br; - best_mv->col = bc; - - // Returns the one-away integer pel sad values around the best as follows: - // cost_list[0]: cost at the best integer pel - // cost_list[1]: cost at delta {0, -1} (left) from the best integer pel - // cost_list[2]: cost at delta { 1, 0} (bottom) from the best integer pel - // cost_list[3]: cost at delta { 0, 1} (right) from the best integer pel - // cost_list[4]: cost at delta {-1, 0} (top) from the best integer pel - if (cost_list) { - calc_int_cost_list(x, &fcenter_mv, sad_per_bit, vfp, best_mv, cost_list); - } - return bestsad; -} - -// A specialized function where the smallest scale search candidates -// are 4 1-away neighbors, and cost_list is non-null -// TODO(debargha): Merge this function with the one above. Also remove -// use_mvcost option since it is always 1, to save unnecessary branches. -static int vp9_pattern_search_sad( - const MACROBLOCK *x, MV *ref_mv, int search_param, int sad_per_bit, - int do_init_search, int *cost_list, const vp9_variance_fn_ptr_t *vfp, - int use_mvcost, const MV *center_mv, MV *best_mv, - const int num_candidates[MAX_PATTERN_SCALES], - const MV candidates[MAX_PATTERN_SCALES][MAX_PATTERN_CANDIDATES]) { - const MACROBLOCKD *const xd = &x->e_mbd; - static const int search_param_to_steps[MAX_MVSEARCH_STEPS] = { - 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, - }; - int i, s, t; - const struct buf_2d *const what = &x->plane[0].src; - const struct buf_2d *const in_what = &xd->plane[0].pre[0]; - int br, bc; - int bestsad = INT_MAX; - int thissad; - int k = -1; - const MV fcenter_mv = { center_mv->row >> 3, center_mv->col >> 3 }; - int best_init_s = search_param_to_steps[search_param]; - // adjust ref_mv to make sure it is within MV range - clamp_mv(ref_mv, x->mv_limits.col_min, x->mv_limits.col_max, - x->mv_limits.row_min, x->mv_limits.row_max); - br = ref_mv->row; - bc = ref_mv->col; - if (cost_list != NULL) { - cost_list[0] = cost_list[1] = cost_list[2] = cost_list[3] = cost_list[4] = - INT_MAX; - } - - // Work out the start point for the search - bestsad = vfp->sdf(what->buf, what->stride, get_buf_from_mv(in_what, ref_mv), - in_what->stride) + - mvsad_err_cost(x, ref_mv, &fcenter_mv, sad_per_bit); - - // Search all possible scales up to the search param around the center point - // pick the scale of the point that is best as the starting scale of - // further steps around it. - if (do_init_search) { - s = best_init_s; - best_init_s = -1; - for (t = 0; t <= s; ++t) { - int best_site = -1; - if (check_bounds(&x->mv_limits, br, bc, 1 << t)) { - for (i = 0; i < num_candidates[t]; i++) { - const MV this_mv = { br + candidates[t][i].row, - bc + candidates[t][i].col }; - thissad = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - CHECK_BETTER - } - } else { - for (i = 0; i < num_candidates[t]; i++) { - const MV this_mv = { br + candidates[t][i].row, - bc + candidates[t][i].col }; - if (!is_mv_in(&x->mv_limits, &this_mv)) continue; - thissad = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - CHECK_BETTER - } - } - if (best_site == -1) { - continue; - } else { - best_init_s = t; - k = best_site; - } - } - if (best_init_s != -1) { - br += candidates[best_init_s][k].row; - bc += candidates[best_init_s][k].col; - } - } - - // If the center point is still the best, just skip this and move to - // the refinement step. - if (best_init_s != -1) { - int do_sad = (num_candidates[0] == 4 && cost_list != NULL); - int best_site = -1; - s = best_init_s; - - for (; s >= do_sad; s--) { - if (!do_init_search || s != best_init_s) { - if (check_bounds(&x->mv_limits, br, bc, 1 << s)) { - for (i = 0; i < num_candidates[s]; i++) { - const MV this_mv = { br + candidates[s][i].row, - bc + candidates[s][i].col }; - thissad = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - CHECK_BETTER - } - } else { - for (i = 0; i < num_candidates[s]; i++) { - const MV this_mv = { br + candidates[s][i].row, - bc + candidates[s][i].col }; - if (!is_mv_in(&x->mv_limits, &this_mv)) continue; - thissad = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - CHECK_BETTER - } - } - - if (best_site == -1) { - continue; - } else { - br += candidates[s][best_site].row; - bc += candidates[s][best_site].col; - k = best_site; - } - } - - do { - int next_chkpts_indices[PATTERN_CANDIDATES_REF]; - best_site = -1; - next_chkpts_indices[0] = (k == 0) ? num_candidates[s] - 1 : k - 1; - next_chkpts_indices[1] = k; - next_chkpts_indices[2] = (k == num_candidates[s] - 1) ? 0 : k + 1; - - if (check_bounds(&x->mv_limits, br, bc, 1 << s)) { - for (i = 0; i < PATTERN_CANDIDATES_REF; i++) { - const MV this_mv = { - br + candidates[s][next_chkpts_indices[i]].row, - bc + candidates[s][next_chkpts_indices[i]].col - }; - thissad = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - CHECK_BETTER - } - } else { - for (i = 0; i < PATTERN_CANDIDATES_REF; i++) { - const MV this_mv = { - br + candidates[s][next_chkpts_indices[i]].row, - bc + candidates[s][next_chkpts_indices[i]].col - }; - if (!is_mv_in(&x->mv_limits, &this_mv)) continue; - thissad = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - CHECK_BETTER - } - } - - if (best_site != -1) { - k = next_chkpts_indices[best_site]; - br += candidates[s][k].row; - bc += candidates[s][k].col; - } - } while (best_site != -1); - } - - // Note: If we enter the if below, then cost_list must be non-NULL. - if (s == 0) { - cost_list[0] = bestsad; - if (!do_init_search || s != best_init_s) { - if (check_bounds(&x->mv_limits, br, bc, 1 << s)) { - for (i = 0; i < num_candidates[s]; i++) { - const MV this_mv = { br + candidates[s][i].row, - bc + candidates[s][i].col }; - cost_list[i + 1] = thissad = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - CHECK_BETTER - } - } else { - for (i = 0; i < num_candidates[s]; i++) { - const MV this_mv = { br + candidates[s][i].row, - bc + candidates[s][i].col }; - if (!is_mv_in(&x->mv_limits, &this_mv)) continue; - cost_list[i + 1] = thissad = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - CHECK_BETTER - } - } - - if (best_site != -1) { - br += candidates[s][best_site].row; - bc += candidates[s][best_site].col; - k = best_site; - } - } - while (best_site != -1) { - int next_chkpts_indices[PATTERN_CANDIDATES_REF]; - best_site = -1; - next_chkpts_indices[0] = (k == 0) ? num_candidates[s] - 1 : k - 1; - next_chkpts_indices[1] = k; - next_chkpts_indices[2] = (k == num_candidates[s] - 1) ? 0 : k + 1; - cost_list[1] = cost_list[2] = cost_list[3] = cost_list[4] = INT_MAX; - cost_list[((k + 2) % 4) + 1] = cost_list[0]; - cost_list[0] = bestsad; - - if (check_bounds(&x->mv_limits, br, bc, 1 << s)) { - for (i = 0; i < PATTERN_CANDIDATES_REF; i++) { - const MV this_mv = { - br + candidates[s][next_chkpts_indices[i]].row, - bc + candidates[s][next_chkpts_indices[i]].col - }; - cost_list[next_chkpts_indices[i] + 1] = thissad = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - CHECK_BETTER - } - } else { - for (i = 0; i < PATTERN_CANDIDATES_REF; i++) { - const MV this_mv = { - br + candidates[s][next_chkpts_indices[i]].row, - bc + candidates[s][next_chkpts_indices[i]].col - }; - if (!is_mv_in(&x->mv_limits, &this_mv)) { - cost_list[next_chkpts_indices[i] + 1] = INT_MAX; - continue; - } - cost_list[next_chkpts_indices[i] + 1] = thissad = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - CHECK_BETTER - } - } - - if (best_site != -1) { - k = next_chkpts_indices[best_site]; - br += candidates[s][k].row; - bc += candidates[s][k].col; - } - } - } - } - - // Returns the one-away integer pel sad values around the best as follows: - // cost_list[0]: sad at the best integer pel - // cost_list[1]: sad at delta {0, -1} (left) from the best integer pel - // cost_list[2]: sad at delta { 1, 0} (bottom) from the best integer pel - // cost_list[3]: sad at delta { 0, 1} (right) from the best integer pel - // cost_list[4]: sad at delta {-1, 0} (top) from the best integer pel - if (cost_list) { - static const MV neighbors[4] = { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 } }; - if (cost_list[0] == INT_MAX) { - cost_list[0] = bestsad; - if (check_bounds(&x->mv_limits, br, bc, 1)) { - for (i = 0; i < 4; i++) { - const MV this_mv = { br + neighbors[i].row, bc + neighbors[i].col }; - cost_list[i + 1] = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - } - } else { - for (i = 0; i < 4; i++) { - const MV this_mv = { br + neighbors[i].row, bc + neighbors[i].col }; - if (!is_mv_in(&x->mv_limits, &this_mv)) - cost_list[i + 1] = INT_MAX; - else - cost_list[i + 1] = - vfp->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &this_mv), in_what->stride); - } - } - } else { - if (use_mvcost) { - for (i = 0; i < 4; i++) { - const MV this_mv = { br + neighbors[i].row, bc + neighbors[i].col }; - if (cost_list[i + 1] != INT_MAX) { - cost_list[i + 1] += - mvsad_err_cost(x, &this_mv, &fcenter_mv, sad_per_bit); - } - } - } - } - } - best_mv->row = br; - best_mv->col = bc; - return bestsad; -} - -int vp9_get_mvpred_var(const MACROBLOCK *x, const MV *best_mv, - const MV *center_mv, const vp9_variance_fn_ptr_t *vfp, - int use_mvcost) { - const MACROBLOCKD *const xd = &x->e_mbd; - const struct buf_2d *const what = &x->plane[0].src; - const struct buf_2d *const in_what = &xd->plane[0].pre[0]; - const MV mv = { best_mv->row * 8, best_mv->col * 8 }; - uint32_t unused; -#if CONFIG_VP9_HIGHBITDEPTH - uint64_t err = - vfp->vf(what->buf, what->stride, get_buf_from_mv(in_what, best_mv), - in_what->stride, &unused); - err += (use_mvcost ? mv_err_cost(&mv, center_mv, x->nmvjointcost, x->mvcost, - x->errorperbit) - : 0); - if (err >= INT_MAX) return INT_MAX; - return (int)err; -#else - return vfp->vf(what->buf, what->stride, get_buf_from_mv(in_what, best_mv), - in_what->stride, &unused) + - (use_mvcost ? mv_err_cost(&mv, center_mv, x->nmvjointcost, x->mvcost, - x->errorperbit) - : 0); -#endif -} - -int vp9_get_mvpred_av_var(const MACROBLOCK *x, const MV *best_mv, - const MV *center_mv, const uint8_t *second_pred, - const vp9_variance_fn_ptr_t *vfp, int use_mvcost) { - const MACROBLOCKD *const xd = &x->e_mbd; - const struct buf_2d *const what = &x->plane[0].src; - const struct buf_2d *const in_what = &xd->plane[0].pre[0]; - const MV mv = { best_mv->row * 8, best_mv->col * 8 }; - unsigned int unused; - - return vfp->svaf(get_buf_from_mv(in_what, best_mv), in_what->stride, 0, 0, - what->buf, what->stride, &unused, second_pred) + - (use_mvcost ? mv_err_cost(&mv, center_mv, x->nmvjointcost, x->mvcost, - x->errorperbit) - : 0); -} - -static int hex_search(const MACROBLOCK *x, MV *ref_mv, int search_param, - int sad_per_bit, int do_init_search, int *cost_list, - const vp9_variance_fn_ptr_t *vfp, int use_mvcost, - const MV *center_mv, MV *best_mv) { - // First scale has 8-closest points, the rest have 6 points in hex shape - // at increasing scales - static const int hex_num_candidates[MAX_PATTERN_SCALES] = { 8, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6 }; - // Note that the largest candidate step at each scale is 2^scale - /* clang-format off */ - static const MV hex_candidates[MAX_PATTERN_SCALES][MAX_PATTERN_CANDIDATES] = { - { { -1, -1 }, { 0, -1 }, { 1, -1 }, { 1, 0 }, { 1, 1 }, { 0, 1 }, { -1, 1 }, - { -1, 0 } }, - { { -1, -2 }, { 1, -2 }, { 2, 0 }, { 1, 2 }, { -1, 2 }, { -2, 0 } }, - { { -2, -4 }, { 2, -4 }, { 4, 0 }, { 2, 4 }, { -2, 4 }, { -4, 0 } }, - { { -4, -8 }, { 4, -8 }, { 8, 0 }, { 4, 8 }, { -4, 8 }, { -8, 0 } }, - { { -8, -16 }, { 8, -16 }, { 16, 0 }, { 8, 16 }, { -8, 16 }, { -16, 0 } }, - { { -16, -32 }, { 16, -32 }, { 32, 0 }, { 16, 32 }, { -16, 32 }, - { -32, 0 } }, - { { -32, -64 }, { 32, -64 }, { 64, 0 }, { 32, 64 }, { -32, 64 }, - { -64, 0 } }, - { { -64, -128 }, { 64, -128 }, { 128, 0 }, { 64, 128 }, { -64, 128 }, - { -128, 0 } }, - { { -128, -256 }, { 128, -256 }, { 256, 0 }, { 128, 256 }, { -128, 256 }, - { -256, 0 } }, - { { -256, -512 }, { 256, -512 }, { 512, 0 }, { 256, 512 }, { -256, 512 }, - { -512, 0 } }, - { { -512, -1024 }, { 512, -1024 }, { 1024, 0 }, { 512, 1024 }, - { -512, 1024 }, { -1024, 0 } } - }; - /* clang-format on */ - return vp9_pattern_search( - x, ref_mv, search_param, sad_per_bit, do_init_search, cost_list, vfp, - use_mvcost, center_mv, best_mv, hex_num_candidates, hex_candidates); -} - -static int bigdia_search(const MACROBLOCK *x, MV *ref_mv, int search_param, - int sad_per_bit, int do_init_search, int *cost_list, - const vp9_variance_fn_ptr_t *vfp, int use_mvcost, - const MV *center_mv, MV *best_mv) { - // First scale has 4-closest points, the rest have 8 points in diamond - // shape at increasing scales - static const int bigdia_num_candidates[MAX_PATTERN_SCALES] = { - 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - }; - // Note that the largest candidate step at each scale is 2^scale - /* clang-format off */ - static const MV - bigdia_candidates[MAX_PATTERN_SCALES][MAX_PATTERN_CANDIDATES] = { - { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 } }, - { { -1, -1 }, { 0, -2 }, { 1, -1 }, { 2, 0 }, { 1, 1 }, { 0, 2 }, - { -1, 1 }, { -2, 0 } }, - { { -2, -2 }, { 0, -4 }, { 2, -2 }, { 4, 0 }, { 2, 2 }, { 0, 4 }, - { -2, 2 }, { -4, 0 } }, - { { -4, -4 }, { 0, -8 }, { 4, -4 }, { 8, 0 }, { 4, 4 }, { 0, 8 }, - { -4, 4 }, { -8, 0 } }, - { { -8, -8 }, { 0, -16 }, { 8, -8 }, { 16, 0 }, { 8, 8 }, { 0, 16 }, - { -8, 8 }, { -16, 0 } }, - { { -16, -16 }, { 0, -32 }, { 16, -16 }, { 32, 0 }, { 16, 16 }, - { 0, 32 }, { -16, 16 }, { -32, 0 } }, - { { -32, -32 }, { 0, -64 }, { 32, -32 }, { 64, 0 }, { 32, 32 }, - { 0, 64 }, { -32, 32 }, { -64, 0 } }, - { { -64, -64 }, { 0, -128 }, { 64, -64 }, { 128, 0 }, { 64, 64 }, - { 0, 128 }, { -64, 64 }, { -128, 0 } }, - { { -128, -128 }, { 0, -256 }, { 128, -128 }, { 256, 0 }, { 128, 128 }, - { 0, 256 }, { -128, 128 }, { -256, 0 } }, - { { -256, -256 }, { 0, -512 }, { 256, -256 }, { 512, 0 }, { 256, 256 }, - { 0, 512 }, { -256, 256 }, { -512, 0 } }, - { { -512, -512 }, { 0, -1024 }, { 512, -512 }, { 1024, 0 }, - { 512, 512 }, { 0, 1024 }, { -512, 512 }, { -1024, 0 } } - }; - /* clang-format on */ - return vp9_pattern_search_sad( - x, ref_mv, search_param, sad_per_bit, do_init_search, cost_list, vfp, - use_mvcost, center_mv, best_mv, bigdia_num_candidates, bigdia_candidates); -} - -static int square_search(const MACROBLOCK *x, MV *ref_mv, int search_param, - int sad_per_bit, int do_init_search, int *cost_list, - const vp9_variance_fn_ptr_t *vfp, int use_mvcost, - const MV *center_mv, MV *best_mv) { - // All scales have 8 closest points in square shape - static const int square_num_candidates[MAX_PATTERN_SCALES] = { - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - }; - // Note that the largest candidate step at each scale is 2^scale - /* clang-format off */ - static const MV - square_candidates[MAX_PATTERN_SCALES][MAX_PATTERN_CANDIDATES] = { - { { -1, -1 }, { 0, -1 }, { 1, -1 }, { 1, 0 }, { 1, 1 }, { 0, 1 }, - { -1, 1 }, { -1, 0 } }, - { { -2, -2 }, { 0, -2 }, { 2, -2 }, { 2, 0 }, { 2, 2 }, { 0, 2 }, - { -2, 2 }, { -2, 0 } }, - { { -4, -4 }, { 0, -4 }, { 4, -4 }, { 4, 0 }, { 4, 4 }, { 0, 4 }, - { -4, 4 }, { -4, 0 } }, - { { -8, -8 }, { 0, -8 }, { 8, -8 }, { 8, 0 }, { 8, 8 }, { 0, 8 }, - { -8, 8 }, { -8, 0 } }, - { { -16, -16 }, { 0, -16 }, { 16, -16 }, { 16, 0 }, { 16, 16 }, - { 0, 16 }, { -16, 16 }, { -16, 0 } }, - { { -32, -32 }, { 0, -32 }, { 32, -32 }, { 32, 0 }, { 32, 32 }, - { 0, 32 }, { -32, 32 }, { -32, 0 } }, - { { -64, -64 }, { 0, -64 }, { 64, -64 }, { 64, 0 }, { 64, 64 }, - { 0, 64 }, { -64, 64 }, { -64, 0 } }, - { { -128, -128 }, { 0, -128 }, { 128, -128 }, { 128, 0 }, { 128, 128 }, - { 0, 128 }, { -128, 128 }, { -128, 0 } }, - { { -256, -256 }, { 0, -256 }, { 256, -256 }, { 256, 0 }, { 256, 256 }, - { 0, 256 }, { -256, 256 }, { -256, 0 } }, - { { -512, -512 }, { 0, -512 }, { 512, -512 }, { 512, 0 }, { 512, 512 }, - { 0, 512 }, { -512, 512 }, { -512, 0 } }, - { { -1024, -1024 }, { 0, -1024 }, { 1024, -1024 }, { 1024, 0 }, - { 1024, 1024 }, { 0, 1024 }, { -1024, 1024 }, { -1024, 0 } } - }; - /* clang-format on */ - return vp9_pattern_search( - x, ref_mv, search_param, sad_per_bit, do_init_search, cost_list, vfp, - use_mvcost, center_mv, best_mv, square_num_candidates, square_candidates); -} - -static int fast_hex_search(const MACROBLOCK *x, MV *ref_mv, int search_param, - int sad_per_bit, - int do_init_search, // must be zero for fast_hex - int *cost_list, const vp9_variance_fn_ptr_t *vfp, - int use_mvcost, const MV *center_mv, MV *best_mv) { - return hex_search(x, ref_mv, VPXMAX(MAX_MVSEARCH_STEPS - 2, search_param), - sad_per_bit, do_init_search, cost_list, vfp, use_mvcost, - center_mv, best_mv); -} - -static int fast_dia_search(const MACROBLOCK *x, MV *ref_mv, int search_param, - int sad_per_bit, int do_init_search, int *cost_list, - const vp9_variance_fn_ptr_t *vfp, int use_mvcost, - const MV *center_mv, MV *best_mv) { - return bigdia_search(x, ref_mv, VPXMAX(MAX_MVSEARCH_STEPS - 2, search_param), - sad_per_bit, do_init_search, cost_list, vfp, use_mvcost, - center_mv, best_mv); -} - -#undef CHECK_BETTER - -// Exhuastive motion search around a given centre position with a given -// step size. -static int exhaustive_mesh_search(const MACROBLOCK *x, MV *ref_mv, MV *best_mv, - int range, int step, int sad_per_bit, - const vp9_variance_fn_ptr_t *fn_ptr, - const MV *center_mv) { - const MACROBLOCKD *const xd = &x->e_mbd; - const struct buf_2d *const what = &x->plane[0].src; - const struct buf_2d *const in_what = &xd->plane[0].pre[0]; - MV fcenter_mv = { center_mv->row, center_mv->col }; - unsigned int best_sad = INT_MAX; - int r, c, i; - int start_col, end_col, start_row, end_row; - int col_step = (step > 1) ? step : 4; - - assert(step >= 1); - - clamp_mv(&fcenter_mv, x->mv_limits.col_min, x->mv_limits.col_max, - x->mv_limits.row_min, x->mv_limits.row_max); - *best_mv = fcenter_mv; - best_sad = - fn_ptr->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &fcenter_mv), in_what->stride) + - mvsad_err_cost(x, &fcenter_mv, ref_mv, sad_per_bit); - start_row = VPXMAX(-range, x->mv_limits.row_min - fcenter_mv.row); - start_col = VPXMAX(-range, x->mv_limits.col_min - fcenter_mv.col); - end_row = VPXMIN(range, x->mv_limits.row_max - fcenter_mv.row); - end_col = VPXMIN(range, x->mv_limits.col_max - fcenter_mv.col); - - for (r = start_row; r <= end_row; r += step) { - for (c = start_col; c <= end_col; c += col_step) { - // Step > 1 means we are not checking every location in this pass. - if (step > 1) { - const MV mv = { fcenter_mv.row + r, fcenter_mv.col + c }; - unsigned int sad = - fn_ptr->sdf(what->buf, what->stride, get_buf_from_mv(in_what, &mv), - in_what->stride); - if (sad < best_sad) { - sad += mvsad_err_cost(x, &mv, ref_mv, sad_per_bit); - if (sad < best_sad) { - best_sad = sad; - *best_mv = mv; - } - } - } else { - // 4 sads in a single call if we are checking every location - if (c + 3 <= end_col) { - unsigned int sads[4]; - const uint8_t *addrs[4]; - for (i = 0; i < 4; ++i) { - const MV mv = { fcenter_mv.row + r, fcenter_mv.col + c + i }; - addrs[i] = get_buf_from_mv(in_what, &mv); - } - fn_ptr->sdx4df(what->buf, what->stride, addrs, in_what->stride, sads); - - for (i = 0; i < 4; ++i) { - if (sads[i] < best_sad) { - const MV mv = { fcenter_mv.row + r, fcenter_mv.col + c + i }; - const unsigned int sad = - sads[i] + mvsad_err_cost(x, &mv, ref_mv, sad_per_bit); - if (sad < best_sad) { - best_sad = sad; - *best_mv = mv; - } - } - } - } else { - for (i = 0; i < end_col - c; ++i) { - const MV mv = { fcenter_mv.row + r, fcenter_mv.col + c + i }; - unsigned int sad = - fn_ptr->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &mv), in_what->stride); - if (sad < best_sad) { - sad += mvsad_err_cost(x, &mv, ref_mv, sad_per_bit); - if (sad < best_sad) { - best_sad = sad; - *best_mv = mv; - } - } - } - } - } - } - } - - return best_sad; -} - -#define MIN_RANGE 7 -#define MAX_RANGE 256 -#define MIN_INTERVAL 1 -#if CONFIG_NON_GREEDY_MV -static int64_t exhaustive_mesh_search_multi_step( - MV *best_mv, const MV *center_mv, int range, int step, - const struct buf_2d *src, const struct buf_2d *pre, int lambda, - const int_mv *nb_full_mvs, int full_mv_num, const MvLimits *mv_limits, - const vp9_variance_fn_ptr_t *fn_ptr) { - int64_t best_sad; - int r, c; - int start_col, end_col, start_row, end_row; - *best_mv = *center_mv; - best_sad = - ((int64_t)fn_ptr->sdf(src->buf, src->stride, - get_buf_from_mv(pre, center_mv), pre->stride) - << LOG2_PRECISION) + - lambda * vp9_nb_mvs_inconsistency(best_mv, nb_full_mvs, full_mv_num); - start_row = VPXMAX(center_mv->row - range, mv_limits->row_min); - start_col = VPXMAX(center_mv->col - range, mv_limits->col_min); - end_row = VPXMIN(center_mv->row + range, mv_limits->row_max); - end_col = VPXMIN(center_mv->col + range, mv_limits->col_max); - for (r = start_row; r <= end_row; r += step) { - for (c = start_col; c <= end_col; c += step) { - const MV mv = { r, c }; - int64_t sad = (int64_t)fn_ptr->sdf(src->buf, src->stride, - get_buf_from_mv(pre, &mv), pre->stride) - << LOG2_PRECISION; - if (sad < best_sad) { - sad += lambda * vp9_nb_mvs_inconsistency(&mv, nb_full_mvs, full_mv_num); - if (sad < best_sad) { - best_sad = sad; - *best_mv = mv; - } - } - } - } - return best_sad; -} - -static int64_t exhaustive_mesh_search_single_step( - MV *best_mv, const MV *center_mv, int range, const struct buf_2d *src, - const struct buf_2d *pre, int lambda, const int_mv *nb_full_mvs, - int full_mv_num, const MvLimits *mv_limits, - const vp9_variance_fn_ptr_t *fn_ptr) { - int64_t best_sad; - int r, c, i; - int start_col, end_col, start_row, end_row; - - *best_mv = *center_mv; - best_sad = - ((int64_t)fn_ptr->sdf(src->buf, src->stride, - get_buf_from_mv(pre, center_mv), pre->stride) - << LOG2_PRECISION) + - lambda * vp9_nb_mvs_inconsistency(best_mv, nb_full_mvs, full_mv_num); - start_row = VPXMAX(center_mv->row - range, mv_limits->row_min); - start_col = VPXMAX(center_mv->col - range, mv_limits->col_min); - end_row = VPXMIN(center_mv->row + range, mv_limits->row_max); - end_col = VPXMIN(center_mv->col + range, mv_limits->col_max); - for (r = start_row; r <= end_row; r += 1) { - c = start_col; - while (c + 3 <= end_col) { - unsigned int sads[4]; - const uint8_t *addrs[4]; - for (i = 0; i < 4; ++i) { - const MV mv = { r, c + i }; - addrs[i] = get_buf_from_mv(pre, &mv); - } - fn_ptr->sdx4df(src->buf, src->stride, addrs, pre->stride, sads); - - for (i = 0; i < 4; ++i) { - int64_t sad = (int64_t)sads[i] << LOG2_PRECISION; - if (sad < best_sad) { - const MV mv = { r, c + i }; - sad += - lambda * vp9_nb_mvs_inconsistency(&mv, nb_full_mvs, full_mv_num); - if (sad < best_sad) { - best_sad = sad; - *best_mv = mv; - } - } - } - c += 4; - } - while (c <= end_col) { - const MV mv = { r, c }; - int64_t sad = (int64_t)fn_ptr->sdf(src->buf, src->stride, - get_buf_from_mv(pre, &mv), pre->stride) - << LOG2_PRECISION; - if (sad < best_sad) { - sad += lambda * vp9_nb_mvs_inconsistency(&mv, nb_full_mvs, full_mv_num); - if (sad < best_sad) { - best_sad = sad; - *best_mv = mv; - } - } - c += 1; - } - } - return best_sad; -} - -static int64_t exhaustive_mesh_search_new(const MACROBLOCK *x, MV *best_mv, - int range, int step, - const vp9_variance_fn_ptr_t *fn_ptr, - const MV *center_mv, int lambda, - const int_mv *nb_full_mvs, - int full_mv_num) { - const MACROBLOCKD *const xd = &x->e_mbd; - const struct buf_2d *src = &x->plane[0].src; - const struct buf_2d *pre = &xd->plane[0].pre[0]; - assert(step >= 1); - assert(is_mv_in(&x->mv_limits, center_mv)); - if (step == 1) { - return exhaustive_mesh_search_single_step( - best_mv, center_mv, range, src, pre, lambda, nb_full_mvs, full_mv_num, - &x->mv_limits, fn_ptr); - } - return exhaustive_mesh_search_multi_step(best_mv, center_mv, range, step, src, - pre, lambda, nb_full_mvs, - full_mv_num, &x->mv_limits, fn_ptr); -} - -static int64_t full_pixel_exhaustive_new(const VP9_COMP *cpi, MACROBLOCK *x, - MV *centre_mv_full, - const vp9_variance_fn_ptr_t *fn_ptr, - MV *dst_mv, int lambda, - const int_mv *nb_full_mvs, - int full_mv_num) { - const SPEED_FEATURES *const sf = &cpi->sf; - MV temp_mv = { centre_mv_full->row, centre_mv_full->col }; - int64_t bestsme; - int i; - int interval = sf->mesh_patterns[0].interval; - int range = sf->mesh_patterns[0].range; - int baseline_interval_divisor; - - // Trap illegal values for interval and range for this function. - if ((range < MIN_RANGE) || (range > MAX_RANGE) || (interval < MIN_INTERVAL) || - (interval > range)) { - printf("ERROR: invalid range\n"); - assert(0); - } - - baseline_interval_divisor = range / interval; - - // Check size of proposed first range against magnitude of the centre - // value used as a starting point. - range = VPXMAX(range, (5 * VPXMAX(abs(temp_mv.row), abs(temp_mv.col))) / 4); - range = VPXMIN(range, MAX_RANGE); - interval = VPXMAX(interval, range / baseline_interval_divisor); - - // initial search - bestsme = - exhaustive_mesh_search_new(x, &temp_mv, range, interval, fn_ptr, &temp_mv, - lambda, nb_full_mvs, full_mv_num); - - if ((interval > MIN_INTERVAL) && (range > MIN_RANGE)) { - // Progressive searches with range and step size decreasing each time - // till we reach a step size of 1. Then break out. - for (i = 1; i < MAX_MESH_STEP; ++i) { - // First pass with coarser step and longer range - bestsme = exhaustive_mesh_search_new( - x, &temp_mv, sf->mesh_patterns[i].range, - sf->mesh_patterns[i].interval, fn_ptr, &temp_mv, lambda, nb_full_mvs, - full_mv_num); - - if (sf->mesh_patterns[i].interval == 1) break; - } - } - - *dst_mv = temp_mv; - - return bestsme; -} - -static int64_t diamond_search_sad_new(const MACROBLOCK *x, - const search_site_config *cfg, - const MV *init_full_mv, MV *best_full_mv, - int search_param, int lambda, int *num00, - const vp9_variance_fn_ptr_t *fn_ptr, - const int_mv *nb_full_mvs, - int full_mv_num) { - int i, j, step; - - const MACROBLOCKD *const xd = &x->e_mbd; - uint8_t *what = x->plane[0].src.buf; - const int what_stride = x->plane[0].src.stride; - const uint8_t *in_what; - const int in_what_stride = xd->plane[0].pre[0].stride; - const uint8_t *best_address; - - int64_t bestsad; - int best_site = -1; - int last_site = -1; - - // search_param determines the length of the initial step and hence the number - // of iterations. - // 0 = initial step (MAX_FIRST_STEP) pel - // 1 = (MAX_FIRST_STEP/2) pel, - // 2 = (MAX_FIRST_STEP/4) pel... - // const search_site *ss = &cfg->ss[search_param * cfg->searches_per_step]; - const MV *ss_mv = &cfg->ss_mv[search_param * cfg->searches_per_step]; - const intptr_t *ss_os = &cfg->ss_os[search_param * cfg->searches_per_step]; - const int tot_steps = cfg->total_steps - search_param; - vpx_clear_system_state(); - - *best_full_mv = *init_full_mv; - clamp_mv(best_full_mv, x->mv_limits.col_min, x->mv_limits.col_max, - x->mv_limits.row_min, x->mv_limits.row_max); - *num00 = 0; - - // Work out the start point for the search - in_what = xd->plane[0].pre[0].buf + best_full_mv->row * in_what_stride + - best_full_mv->col; - best_address = in_what; - - // Check the starting position - { - const int64_t mv_dist = - (int64_t)fn_ptr->sdf(what, what_stride, in_what, in_what_stride) - << LOG2_PRECISION; - const int64_t mv_cost = - vp9_nb_mvs_inconsistency(best_full_mv, nb_full_mvs, full_mv_num); - bestsad = mv_dist + lambda * mv_cost; - } - - i = 0; - - for (step = 0; step < tot_steps; step++) { - int all_in = 1, t; - - // All_in is true if every one of the points we are checking are within - // the bounds of the image. - all_in &= ((best_full_mv->row + ss_mv[i].row) > x->mv_limits.row_min); - all_in &= ((best_full_mv->row + ss_mv[i + 1].row) < x->mv_limits.row_max); - all_in &= ((best_full_mv->col + ss_mv[i + 2].col) > x->mv_limits.col_min); - all_in &= ((best_full_mv->col + ss_mv[i + 3].col) < x->mv_limits.col_max); - - // If all the pixels are within the bounds we don't check whether the - // search point is valid in this loop, otherwise we check each point - // for validity.. - if (all_in) { - unsigned int sad_array[4]; - - for (j = 0; j < cfg->searches_per_step; j += 4) { - unsigned char const *block_offset[4]; - - for (t = 0; t < 4; t++) block_offset[t] = ss_os[i + t] + best_address; - - fn_ptr->sdx4df(what, what_stride, block_offset, in_what_stride, - sad_array); - - for (t = 0; t < 4; t++, i++) { - const int64_t mv_dist = (int64_t)sad_array[t] << LOG2_PRECISION; - if (mv_dist < bestsad) { - const MV this_mv = { best_full_mv->row + ss_mv[i].row, - best_full_mv->col + ss_mv[i].col }; - const int64_t mv_cost = - vp9_nb_mvs_inconsistency(&this_mv, nb_full_mvs, full_mv_num); - const int64_t thissad = mv_dist + lambda * mv_cost; - if (thissad < bestsad) { - bestsad = thissad; - best_site = i; - } - } - } - } - } else { - for (j = 0; j < cfg->searches_per_step; j++) { - // Trap illegal vectors - const MV this_mv = { best_full_mv->row + ss_mv[i].row, - best_full_mv->col + ss_mv[i].col }; - - if (is_mv_in(&x->mv_limits, &this_mv)) { - const uint8_t *const check_here = ss_os[i] + best_address; - const int64_t mv_dist = - (int64_t)fn_ptr->sdf(what, what_stride, check_here, - in_what_stride) - << LOG2_PRECISION; - if (mv_dist < bestsad) { - const int64_t mv_cost = - vp9_nb_mvs_inconsistency(&this_mv, nb_full_mvs, full_mv_num); - const int64_t thissad = mv_dist + lambda * mv_cost; - if (thissad < bestsad) { - bestsad = thissad; - best_site = i; - } - } - } - i++; - } - } - if (best_site != last_site) { - best_full_mv->row += ss_mv[best_site].row; - best_full_mv->col += ss_mv[best_site].col; - best_address += ss_os[best_site]; - last_site = best_site; - } else if (best_address == in_what) { - (*num00)++; - } - } - return bestsad; -} - -int vp9_prepare_nb_full_mvs(const MotionField *motion_field, int mi_row, - int mi_col, int_mv *nb_full_mvs) { - const int mi_width = num_8x8_blocks_wide_lookup[motion_field->bsize]; - const int mi_height = num_8x8_blocks_high_lookup[motion_field->bsize]; - const int dirs[NB_MVS_NUM][2] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } }; - int nb_full_mv_num = 0; - int i; - assert(mi_row % mi_height == 0); - assert(mi_col % mi_width == 0); - for (i = 0; i < NB_MVS_NUM; ++i) { - int r = dirs[i][0]; - int c = dirs[i][1]; - int brow = mi_row / mi_height + r; - int bcol = mi_col / mi_width + c; - if (brow >= 0 && brow < motion_field->block_rows && bcol >= 0 && - bcol < motion_field->block_cols) { - if (vp9_motion_field_is_mv_set(motion_field, brow, bcol)) { - int_mv mv = vp9_motion_field_get_mv(motion_field, brow, bcol); - nb_full_mvs[nb_full_mv_num].as_mv = get_full_mv(&mv.as_mv); - ++nb_full_mv_num; - } - } - } - return nb_full_mv_num; -} -#endif // CONFIG_NON_GREEDY_MV - -int vp9_diamond_search_sad_c(const MACROBLOCK *x, const search_site_config *cfg, - MV *ref_mv, uint32_t start_mv_sad, MV *best_mv, - int search_param, int sad_per_bit, int *num00, - const vp9_sad_fn_ptr_t *sad_fn_ptr, - const MV *center_mv) { - int i, j, step; - - const MACROBLOCKD *const xd = &x->e_mbd; - uint8_t *what = x->plane[0].src.buf; - const int what_stride = x->plane[0].src.stride; - const uint8_t *in_what; - const int in_what_stride = xd->plane[0].pre[0].stride; - const uint8_t *best_address; - - unsigned int bestsad = start_mv_sad; - int best_site = -1; - int last_site = -1; - - int ref_row; - int ref_col; - - // search_param determines the length of the initial step and hence the number - // of iterations. - // 0 = initial step (MAX_FIRST_STEP) pel - // 1 = (MAX_FIRST_STEP/2) pel, - // 2 = (MAX_FIRST_STEP/4) pel... - // const search_site *ss = &cfg->ss[search_param * cfg->searches_per_step]; - const MV *ss_mv = &cfg->ss_mv[search_param * cfg->searches_per_step]; - const intptr_t *ss_os = &cfg->ss_os[search_param * cfg->searches_per_step]; - const int tot_steps = cfg->total_steps - search_param; - - const MV fcenter_mv = { center_mv->row >> 3, center_mv->col >> 3 }; - ref_row = ref_mv->row; - ref_col = ref_mv->col; - *num00 = 0; - best_mv->row = ref_row; - best_mv->col = ref_col; - - // Work out the start point for the search - in_what = xd->plane[0].pre[0].buf + ref_row * in_what_stride + ref_col; - best_address = in_what; - - i = 0; - - for (step = 0; step < tot_steps; step++) { - int all_in = 1, t; - - // All_in is true if every one of the points we are checking are within - // the bounds of the image. - all_in &= ((best_mv->row + ss_mv[i].row) > x->mv_limits.row_min); - all_in &= ((best_mv->row + ss_mv[i + 1].row) < x->mv_limits.row_max); - all_in &= ((best_mv->col + ss_mv[i + 2].col) > x->mv_limits.col_min); - all_in &= ((best_mv->col + ss_mv[i + 3].col) < x->mv_limits.col_max); - - // If all the pixels are within the bounds we don't check whether the - // search point is valid in this loop, otherwise we check each point - // for validity.. - if (all_in) { - unsigned int sad_array[4]; - - for (j = 0; j < cfg->searches_per_step; j += 4) { - unsigned char const *block_offset[4]; - - for (t = 0; t < 4; t++) block_offset[t] = ss_os[i + t] + best_address; - - sad_fn_ptr->sdx4df(what, what_stride, block_offset, in_what_stride, - sad_array); - - for (t = 0; t < 4; t++, i++) { - if (sad_array[t] < bestsad) { - const MV this_mv = { best_mv->row + ss_mv[i].row, - best_mv->col + ss_mv[i].col }; - sad_array[t] += - mvsad_err_cost(x, &this_mv, &fcenter_mv, sad_per_bit); - if (sad_array[t] < bestsad) { - bestsad = sad_array[t]; - best_site = i; - } - } - } - } - } else { - for (j = 0; j < cfg->searches_per_step; j++) { - // Trap illegal vectors - const MV this_mv = { best_mv->row + ss_mv[i].row, - best_mv->col + ss_mv[i].col }; - - if (is_mv_in(&x->mv_limits, &this_mv)) { - const uint8_t *const check_here = ss_os[i] + best_address; - unsigned int thissad = - sad_fn_ptr->sdf(what, what_stride, check_here, in_what_stride); - - if (thissad < bestsad) { - thissad += mvsad_err_cost(x, &this_mv, &fcenter_mv, sad_per_bit); - if (thissad < bestsad) { - bestsad = thissad; - best_site = i; - } - } - } - i++; - } - } - if (best_site != last_site) { - best_mv->row += ss_mv[best_site].row; - best_mv->col += ss_mv[best_site].col; - best_address += ss_os[best_site]; - last_site = best_site; -#if defined(NEW_DIAMOND_SEARCH) - while (1) { - const MV this_mv = { best_mv->row + ss_mv[best_site].row, - best_mv->col + ss_mv[best_site].col }; - if (is_mv_in(&x->mv_limits, &this_mv)) { - const uint8_t *const check_here = ss_os[best_site] + best_address; - unsigned int thissad = - fn_ptr->sdf(what, what_stride, check_here, in_what_stride); - if (thissad < bestsad) { - thissad += mvsad_err_cost(x, &this_mv, &fcenter_mv, sad_per_bit); - if (thissad < bestsad) { - bestsad = thissad; - best_mv->row += ss_mv[best_site].row; - best_mv->col += ss_mv[best_site].col; - best_address += ss_os[best_site]; - continue; - } - } - } - break; - } -#endif - } else if (best_address == in_what) { - (*num00)++; - } - } - return bestsad; -} - -static int vector_match(int16_t *ref, int16_t *src, int bwl) { - int best_sad = INT_MAX; - int this_sad; - int d; - int center, offset = 0; - int bw = 4 << bwl; // redundant variable, to be changed in the experiments. - for (d = 0; d <= bw; d += 16) { - this_sad = vpx_vector_var(&ref[d], src, bwl); - if (this_sad < best_sad) { - best_sad = this_sad; - offset = d; - } - } - center = offset; - - for (d = -8; d <= 8; d += 16) { - int this_pos = offset + d; - // check limit - if (this_pos < 0 || this_pos > bw) continue; - this_sad = vpx_vector_var(&ref[this_pos], src, bwl); - if (this_sad < best_sad) { - best_sad = this_sad; - center = this_pos; - } - } - offset = center; - - for (d = -4; d <= 4; d += 8) { - int this_pos = offset + d; - // check limit - if (this_pos < 0 || this_pos > bw) continue; - this_sad = vpx_vector_var(&ref[this_pos], src, bwl); - if (this_sad < best_sad) { - best_sad = this_sad; - center = this_pos; - } - } - offset = center; - - for (d = -2; d <= 2; d += 4) { - int this_pos = offset + d; - // check limit - if (this_pos < 0 || this_pos > bw) continue; - this_sad = vpx_vector_var(&ref[this_pos], src, bwl); - if (this_sad < best_sad) { - best_sad = this_sad; - center = this_pos; - } - } - offset = center; - - for (d = -1; d <= 1; d += 2) { - int this_pos = offset + d; - // check limit - if (this_pos < 0 || this_pos > bw) continue; - this_sad = vpx_vector_var(&ref[this_pos], src, bwl); - if (this_sad < best_sad) { - best_sad = this_sad; - center = this_pos; - } - } - - return (center - (bw >> 1)); -} - -static const MV search_pos[4] = { - { -1, 0 }, - { 0, -1 }, - { 0, 1 }, - { 1, 0 }, -}; - -unsigned int vp9_int_pro_motion_estimation(const VP9_COMP *cpi, MACROBLOCK *x, - BLOCK_SIZE bsize, int mi_row, - int mi_col, const MV *ref_mv) { - MACROBLOCKD *xd = &x->e_mbd; - MODE_INFO *mi = xd->mi[0]; - struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0 } }; - DECLARE_ALIGNED(16, int16_t, hbuf[128]); - DECLARE_ALIGNED(16, int16_t, vbuf[128]); - DECLARE_ALIGNED(16, int16_t, src_hbuf[64]); - DECLARE_ALIGNED(16, int16_t, src_vbuf[64]); - int idx; - const int bw = 4 << b_width_log2_lookup[bsize]; - const int bh = 4 << b_height_log2_lookup[bsize]; - const int search_width = bw << 1; - const int search_height = bh << 1; - const int src_stride = x->plane[0].src.stride; - const int ref_stride = xd->plane[0].pre[0].stride; - uint8_t const *ref_buf, *src_buf; - MV *tmp_mv = &xd->mi[0]->mv[0].as_mv; - unsigned int best_sad, tmp_sad, this_sad[4]; - MV this_mv; - const int norm_factor = 3 + (bw >> 5); - const YV12_BUFFER_CONFIG *scaled_ref_frame = - vp9_get_scaled_ref_frame(cpi, mi->ref_frame[0]); - MvLimits subpel_mv_limits; - - if (scaled_ref_frame) { - int i; - // Swap out the reference frame for a version that's been scaled to - // match the resolution of the current frame, allowing the existing - // motion search code to be used without additional modifications. - for (i = 0; i < MAX_MB_PLANE; i++) backup_yv12[i] = xd->plane[i].pre[0]; - vp9_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL); - } - -#if CONFIG_VP9_HIGHBITDEPTH - // TODO(jingning): Implement integral projection functions for high bit-depth - // setting and remove this part of code. - if (xd->bd != 8) { - const unsigned int sad = cpi->fn_ptr[bsize].sdf( - x->plane[0].src.buf, src_stride, xd->plane[0].pre[0].buf, ref_stride); - tmp_mv->row = 0; - tmp_mv->col = 0; - - if (scaled_ref_frame) { - int i; - for (i = 0; i < MAX_MB_PLANE; i++) xd->plane[i].pre[0] = backup_yv12[i]; - } - return sad; - } -#endif - - // Set up prediction 1-D reference set - ref_buf = xd->plane[0].pre[0].buf - (bw >> 1); - for (idx = 0; idx < search_width; idx += 16) { - vpx_int_pro_row(&hbuf[idx], ref_buf, ref_stride, bh); - ref_buf += 16; - } - - ref_buf = xd->plane[0].pre[0].buf - (bh >> 1) * ref_stride; - for (idx = 0; idx < search_height; ++idx) { - vbuf[idx] = vpx_int_pro_col(ref_buf, bw) >> norm_factor; - ref_buf += ref_stride; - } - - // Set up src 1-D reference set - for (idx = 0; idx < bw; idx += 16) { - src_buf = x->plane[0].src.buf + idx; - vpx_int_pro_row(&src_hbuf[idx], src_buf, src_stride, bh); - } - - src_buf = x->plane[0].src.buf; - for (idx = 0; idx < bh; ++idx) { - src_vbuf[idx] = vpx_int_pro_col(src_buf, bw) >> norm_factor; - src_buf += src_stride; - } - - // Find the best match per 1-D search - tmp_mv->col = vector_match(hbuf, src_hbuf, b_width_log2_lookup[bsize]); - tmp_mv->row = vector_match(vbuf, src_vbuf, b_height_log2_lookup[bsize]); - - this_mv = *tmp_mv; - src_buf = x->plane[0].src.buf; - ref_buf = xd->plane[0].pre[0].buf + this_mv.row * ref_stride + this_mv.col; - best_sad = cpi->fn_ptr[bsize].sdf(src_buf, src_stride, ref_buf, ref_stride); - - { - const uint8_t *const pos[4] = { - ref_buf - ref_stride, - ref_buf - 1, - ref_buf + 1, - ref_buf + ref_stride, - }; - - cpi->fn_ptr[bsize].sdx4df(src_buf, src_stride, pos, ref_stride, this_sad); - } - - for (idx = 0; idx < 4; ++idx) { - if (this_sad[idx] < best_sad) { - best_sad = this_sad[idx]; - tmp_mv->row = search_pos[idx].row + this_mv.row; - tmp_mv->col = search_pos[idx].col + this_mv.col; - } - } - - if (this_sad[0] < this_sad[3]) - this_mv.row -= 1; - else - this_mv.row += 1; - - if (this_sad[1] < this_sad[2]) - this_mv.col -= 1; - else - this_mv.col += 1; - - ref_buf = xd->plane[0].pre[0].buf + this_mv.row * ref_stride + this_mv.col; - - tmp_sad = cpi->fn_ptr[bsize].sdf(src_buf, src_stride, ref_buf, ref_stride); - if (best_sad > tmp_sad) { - *tmp_mv = this_mv; - best_sad = tmp_sad; - } - - tmp_mv->row *= 8; - tmp_mv->col *= 8; - - vp9_set_subpel_mv_search_range(&subpel_mv_limits, &x->mv_limits, ref_mv); - clamp_mv(tmp_mv, subpel_mv_limits.col_min, subpel_mv_limits.col_max, - subpel_mv_limits.row_min, subpel_mv_limits.row_max); - - if (scaled_ref_frame) { - int i; - for (i = 0; i < MAX_MB_PLANE; i++) xd->plane[i].pre[0] = backup_yv12[i]; - } - - return best_sad; -} - -static int get_exhaustive_threshold(int exhaustive_searches_thresh, - BLOCK_SIZE bsize) { - return exhaustive_searches_thresh >> - (8 - (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize])); -} - -#if CONFIG_NON_GREEDY_MV -// Runs sequence of diamond searches in smaller steps for RD. -/* do_refine: If last step (1-away) of n-step search doesn't pick the center - point as the best match, we will do a final 1-away diamond - refining search */ -int vp9_full_pixel_diamond_new(const VP9_COMP *cpi, MACROBLOCK *x, - BLOCK_SIZE bsize, MV *mvp_full, int step_param, - int lambda, int do_refine, - const int_mv *nb_full_mvs, int full_mv_num, - MV *best_mv) { - const vp9_variance_fn_ptr_t *fn_ptr = &cpi->fn_ptr[bsize]; - const SPEED_FEATURES *const sf = &cpi->sf; - int n, num00 = 0; - int thissme; - int bestsme; - const int further_steps = MAX_MVSEARCH_STEPS - 1 - step_param; - const MV center_mv = { 0, 0 }; - vpx_clear_system_state(); - diamond_search_sad_new(x, &cpi->ss_cfg, mvp_full, best_mv, step_param, lambda, - &n, fn_ptr, nb_full_mvs, full_mv_num); - - bestsme = vp9_get_mvpred_var(x, best_mv, ¢er_mv, fn_ptr, 0); - - // If there won't be more n-step search, check to see if refining search is - // needed. - if (n > further_steps) do_refine = 0; - - while (n < further_steps) { - ++n; - if (num00) { - num00--; - } else { - MV temp_mv; - diamond_search_sad_new(x, &cpi->ss_cfg, mvp_full, &temp_mv, - step_param + n, lambda, &num00, fn_ptr, - nb_full_mvs, full_mv_num); - thissme = vp9_get_mvpred_var(x, &temp_mv, ¢er_mv, fn_ptr, 0); - // check to see if refining search is needed. - if (num00 > further_steps - n) do_refine = 0; - - if (thissme < bestsme) { - bestsme = thissme; - *best_mv = temp_mv; - } - } - } - - // final 1-away diamond refining search - if (do_refine) { - const int search_range = 8; - MV temp_mv = *best_mv; - vp9_refining_search_sad_new(x, &temp_mv, lambda, search_range, fn_ptr, - nb_full_mvs, full_mv_num); - thissme = vp9_get_mvpred_var(x, &temp_mv, ¢er_mv, fn_ptr, 0); - if (thissme < bestsme) { - bestsme = thissme; - *best_mv = temp_mv; - } - } - - if (sf->exhaustive_searches_thresh < INT_MAX && - !cpi->rc.is_src_frame_alt_ref) { - const int64_t exhaustive_thr = - get_exhaustive_threshold(sf->exhaustive_searches_thresh, bsize); - if (bestsme > exhaustive_thr) { - full_pixel_exhaustive_new(cpi, x, best_mv, fn_ptr, best_mv, lambda, - nb_full_mvs, full_mv_num); - bestsme = vp9_get_mvpred_var(x, best_mv, ¢er_mv, fn_ptr, 0); - } - } - return bestsme; -} -#endif // CONFIG_NON_GREEDY_MV - -// Runs sequence of diamond searches in smaller steps for RD. -/* do_refine: If last step (1-away) of n-step search doesn't pick the center - point as the best match, we will do a final 1-away diamond - refining search */ -static int full_pixel_diamond(const VP9_COMP *const cpi, - const MACROBLOCK *const x, BLOCK_SIZE bsize, - MV *mvp_full, int step_param, int sadpb, - int further_steps, int do_refine, - int use_downsampled_sad, int *cost_list, - const vp9_variance_fn_ptr_t *fn_ptr, - const MV *ref_mv, MV *dst_mv) { - MV temp_mv; - int thissme, n, num00 = 0; - int bestsme; - const int src_buf_stride = x->plane[0].src.stride; - const uint8_t *const src_buf = x->plane[0].src.buf; - const MACROBLOCKD *const xd = &x->e_mbd; - const int pred_buf_stride = xd->plane[0].pre[0].stride; - uint8_t *pred_buf; - vp9_sad_fn_ptr_t sad_fn_ptr; - unsigned int start_mv_sad, start_mv_sad_even_rows, start_mv_sad_odd_rows; - const MV ref_mv_full = { ref_mv->row >> 3, ref_mv->col >> 3 }; - clamp_mv(mvp_full, x->mv_limits.col_min, x->mv_limits.col_max, - x->mv_limits.row_min, x->mv_limits.row_max); - - pred_buf = - xd->plane[0].pre[0].buf + mvp_full->row * pred_buf_stride + mvp_full->col; - start_mv_sad_even_rows = - fn_ptr->sdsf(src_buf, src_buf_stride, pred_buf, pred_buf_stride); - start_mv_sad_odd_rows = - fn_ptr->sdsf(src_buf + src_buf_stride, src_buf_stride, - pred_buf + pred_buf_stride, pred_buf_stride); - start_mv_sad = (start_mv_sad_even_rows + start_mv_sad_odd_rows) >> 1; - start_mv_sad += mvsad_err_cost(x, mvp_full, &ref_mv_full, sadpb); - - sad_fn_ptr.sdf = fn_ptr->sdf; - sad_fn_ptr.sdx4df = fn_ptr->sdx4df; - if (use_downsampled_sad && num_4x4_blocks_high_lookup[bsize] >= 2) { - // If the absolute difference between the pred-to-src SAD of even rows and - // the pred-to-src SAD of odd rows is small, skip every other row in sad - // computation. - const int odd_to_even_diff_sad = - abs((int)start_mv_sad_even_rows - (int)start_mv_sad_odd_rows); - const int mult_thresh = 10; - if (odd_to_even_diff_sad * mult_thresh < (int)start_mv_sad_even_rows) { - sad_fn_ptr.sdf = fn_ptr->sdsf; - sad_fn_ptr.sdx4df = fn_ptr->sdsx4df; - } - } - - bestsme = - cpi->diamond_search_sad(x, &cpi->ss_cfg, mvp_full, start_mv_sad, &temp_mv, - step_param, sadpb, &n, &sad_fn_ptr, ref_mv); - if (bestsme < INT_MAX) - bestsme = vp9_get_mvpred_var(x, &temp_mv, ref_mv, fn_ptr, 1); - *dst_mv = temp_mv; - - // If there won't be more n-step search, check to see if refining search is - // needed. - if (n > further_steps) do_refine = 0; - - while (n < further_steps) { - ++n; - - if (num00) { - num00--; - } else { - thissme = cpi->diamond_search_sad(x, &cpi->ss_cfg, mvp_full, start_mv_sad, - &temp_mv, step_param + n, sadpb, &num00, - &sad_fn_ptr, ref_mv); - if (thissme < INT_MAX) - thissme = vp9_get_mvpred_var(x, &temp_mv, ref_mv, fn_ptr, 1); - - // check to see if refining search is needed. - if (num00 > further_steps - n) do_refine = 0; - - if (thissme < bestsme) { - bestsme = thissme; - *dst_mv = temp_mv; - } - } - } - - // final 1-away diamond refining search - if (do_refine) { - const int search_range = 8; - MV best_mv = *dst_mv; - thissme = vp9_refining_search_sad(x, &best_mv, sadpb, search_range, - &sad_fn_ptr, ref_mv); - if (thissme < INT_MAX) - thissme = vp9_get_mvpred_var(x, &best_mv, ref_mv, fn_ptr, 1); - if (thissme < bestsme) { - bestsme = thissme; - *dst_mv = best_mv; - } - } - - if (sad_fn_ptr.sdf != fn_ptr->sdf) { - // If we are skipping rows when we perform the motion search, we need to - // check the quality of skipping. If it's bad, then we run search with - // skip row features off. - const uint8_t *best_address = get_buf_from_mv(&xd->plane[0].pre[0], dst_mv); - const int sad = - fn_ptr->sdf(src_buf, src_buf_stride, best_address, pred_buf_stride); - const int skip_sad = - fn_ptr->sdsf(src_buf, src_buf_stride, best_address, pred_buf_stride); - // We will keep the result of skipping rows if it's good enough. - const int kSADThresh = - 1 << (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]); - if (sad > kSADThresh && abs(skip_sad - sad) * 10 >= VPXMAX(sad, 1) * 9) { - // There is a large discrepancy between skipping and not skipping, so we - // need to redo the motion search. - return full_pixel_diamond(cpi, x, bsize, mvp_full, step_param, sadpb, - further_steps, do_refine, 0, cost_list, fn_ptr, - ref_mv, dst_mv); - } - } - - // Return cost list. - if (cost_list) { - calc_int_cost_list(x, ref_mv, sadpb, fn_ptr, dst_mv, cost_list); - } - return bestsme; -} - -// Runs an limited range exhaustive mesh search using a pattern set -// according to the encode speed profile. -static int full_pixel_exhaustive(const VP9_COMP *const cpi, - const MACROBLOCK *const x, MV *centre_mv_full, - int sadpb, int *cost_list, - const vp9_variance_fn_ptr_t *fn_ptr, - const MV *ref_mv, MV *dst_mv) { - const SPEED_FEATURES *const sf = &cpi->sf; - MV temp_mv = { centre_mv_full->row, centre_mv_full->col }; - MV f_ref_mv = { ref_mv->row >> 3, ref_mv->col >> 3 }; - int bestsme; - int i; - int interval = sf->mesh_patterns[0].interval; - int range = sf->mesh_patterns[0].range; - int baseline_interval_divisor; - - // Trap illegal values for interval and range for this function. - if ((range < MIN_RANGE) || (range > MAX_RANGE) || (interval < MIN_INTERVAL) || - (interval > range)) - return INT_MAX; - - baseline_interval_divisor = range / interval; - - // Check size of proposed first range against magnitude of the centre - // value used as a starting point. - range = VPXMAX(range, (5 * VPXMAX(abs(temp_mv.row), abs(temp_mv.col))) / 4); - range = VPXMIN(range, MAX_RANGE); - interval = VPXMAX(interval, range / baseline_interval_divisor); - - // initial search - bestsme = exhaustive_mesh_search(x, &f_ref_mv, &temp_mv, range, interval, - sadpb, fn_ptr, &temp_mv); - - if ((interval > MIN_INTERVAL) && (range > MIN_RANGE)) { - // Progressive searches with range and step size decreasing each time - // till we reach a step size of 1. Then break out. - for (i = 1; i < MAX_MESH_STEP; ++i) { - // First pass with coarser step and longer range - bestsme = exhaustive_mesh_search( - x, &f_ref_mv, &temp_mv, sf->mesh_patterns[i].range, - sf->mesh_patterns[i].interval, sadpb, fn_ptr, &temp_mv); - - if (sf->mesh_patterns[i].interval == 1) break; - } - } - - if (bestsme < INT_MAX) - bestsme = vp9_get_mvpred_var(x, &temp_mv, ref_mv, fn_ptr, 1); - *dst_mv = temp_mv; - - // Return cost list. - if (cost_list) { - calc_int_cost_list(x, ref_mv, sadpb, fn_ptr, dst_mv, cost_list); - } - return bestsme; -} - -#if CONFIG_NON_GREEDY_MV -int64_t vp9_refining_search_sad_new(const MACROBLOCK *x, MV *best_full_mv, - int lambda, int search_range, - const vp9_variance_fn_ptr_t *fn_ptr, - const int_mv *nb_full_mvs, - int full_mv_num) { - const MACROBLOCKD *const xd = &x->e_mbd; - const MV neighbors[4] = { { -1, 0 }, { 0, -1 }, { 0, 1 }, { 1, 0 } }; - const struct buf_2d *const what = &x->plane[0].src; - const struct buf_2d *const in_what = &xd->plane[0].pre[0]; - const uint8_t *best_address = get_buf_from_mv(in_what, best_full_mv); - int64_t best_sad; - int i, j; - vpx_clear_system_state(); - { - const int64_t mv_dist = (int64_t)fn_ptr->sdf(what->buf, what->stride, - best_address, in_what->stride) - << LOG2_PRECISION; - const int64_t mv_cost = - vp9_nb_mvs_inconsistency(best_full_mv, nb_full_mvs, full_mv_num); - best_sad = mv_dist + lambda * mv_cost; - } - - for (i = 0; i < search_range; i++) { - int best_site = -1; - const int all_in = ((best_full_mv->row - 1) > x->mv_limits.row_min) & - ((best_full_mv->row + 1) < x->mv_limits.row_max) & - ((best_full_mv->col - 1) > x->mv_limits.col_min) & - ((best_full_mv->col + 1) < x->mv_limits.col_max); - - if (all_in) { - unsigned int sads[4]; - const uint8_t *const positions[4] = { best_address - in_what->stride, - best_address - 1, best_address + 1, - best_address + in_what->stride }; - - fn_ptr->sdx4df(what->buf, what->stride, positions, in_what->stride, sads); - - for (j = 0; j < 4; ++j) { - const MV mv = { best_full_mv->row + neighbors[j].row, - best_full_mv->col + neighbors[j].col }; - const int64_t mv_dist = (int64_t)sads[j] << LOG2_PRECISION; - const int64_t mv_cost = - vp9_nb_mvs_inconsistency(&mv, nb_full_mvs, full_mv_num); - const int64_t thissad = mv_dist + lambda * mv_cost; - if (thissad < best_sad) { - best_sad = thissad; - best_site = j; - } - } - } else { - for (j = 0; j < 4; ++j) { - const MV mv = { best_full_mv->row + neighbors[j].row, - best_full_mv->col + neighbors[j].col }; - - if (is_mv_in(&x->mv_limits, &mv)) { - const int64_t mv_dist = - (int64_t)fn_ptr->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &mv), - in_what->stride) - << LOG2_PRECISION; - const int64_t mv_cost = - vp9_nb_mvs_inconsistency(&mv, nb_full_mvs, full_mv_num); - const int64_t thissad = mv_dist + lambda * mv_cost; - if (thissad < best_sad) { - best_sad = thissad; - best_site = j; - } - } - } - } - - if (best_site == -1) { - break; - } else { - best_full_mv->row += neighbors[best_site].row; - best_full_mv->col += neighbors[best_site].col; - best_address = get_buf_from_mv(in_what, best_full_mv); - } - } - - return best_sad; -} -#endif // CONFIG_NON_GREEDY_MV - -int vp9_refining_search_sad(const MACROBLOCK *x, MV *ref_mv, int error_per_bit, - int search_range, - const vp9_sad_fn_ptr_t *sad_fn_ptr, - const MV *center_mv) { - const MACROBLOCKD *const xd = &x->e_mbd; - const MV neighbors[4] = { { -1, 0 }, { 0, -1 }, { 0, 1 }, { 1, 0 } }; - const struct buf_2d *const what = &x->plane[0].src; - const struct buf_2d *const in_what = &xd->plane[0].pre[0]; - const MV fcenter_mv = { center_mv->row >> 3, center_mv->col >> 3 }; - const uint8_t *best_address = get_buf_from_mv(in_what, ref_mv); - unsigned int best_sad = - sad_fn_ptr->sdf(what->buf, what->stride, best_address, in_what->stride) + - mvsad_err_cost(x, ref_mv, &fcenter_mv, error_per_bit); - int i, j; - - for (i = 0; i < search_range; i++) { - int best_site = -1; - const int all_in = ((ref_mv->row - 1) > x->mv_limits.row_min) & - ((ref_mv->row + 1) < x->mv_limits.row_max) & - ((ref_mv->col - 1) > x->mv_limits.col_min) & - ((ref_mv->col + 1) < x->mv_limits.col_max); - - if (all_in) { - unsigned int sads[4]; - const uint8_t *const positions[4] = { best_address - in_what->stride, - best_address - 1, best_address + 1, - best_address + in_what->stride }; - - sad_fn_ptr->sdx4df(what->buf, what->stride, positions, in_what->stride, - sads); - - for (j = 0; j < 4; ++j) { - if (sads[j] < best_sad) { - const MV mv = { ref_mv->row + neighbors[j].row, - ref_mv->col + neighbors[j].col }; - sads[j] += mvsad_err_cost(x, &mv, &fcenter_mv, error_per_bit); - if (sads[j] < best_sad) { - best_sad = sads[j]; - best_site = j; - } - } - } - } else { - for (j = 0; j < 4; ++j) { - const MV mv = { ref_mv->row + neighbors[j].row, - ref_mv->col + neighbors[j].col }; - - if (is_mv_in(&x->mv_limits, &mv)) { - unsigned int sad = - sad_fn_ptr->sdf(what->buf, what->stride, - get_buf_from_mv(in_what, &mv), in_what->stride); - if (sad < best_sad) { - sad += mvsad_err_cost(x, &mv, &fcenter_mv, error_per_bit); - if (sad < best_sad) { - best_sad = sad; - best_site = j; - } - } - } - } - } - - if (best_site == -1) { - break; - } else { - ref_mv->row += neighbors[best_site].row; - ref_mv->col += neighbors[best_site].col; - best_address = get_buf_from_mv(in_what, ref_mv); - } - } - - return best_sad; -} - -// This function is called when we do joint motion search in comp_inter_inter -// mode. -int vp9_refining_search_8p_c(const MACROBLOCK *x, MV *ref_mv, int error_per_bit, - int search_range, - const vp9_variance_fn_ptr_t *fn_ptr, - const MV *center_mv, const uint8_t *second_pred) { - const MV neighbors[8] = { { -1, 0 }, { 0, -1 }, { 0, 1 }, { 1, 0 }, - { -1, -1 }, { 1, -1 }, { -1, 1 }, { 1, 1 } }; - const MACROBLOCKD *const xd = &x->e_mbd; - const struct buf_2d *const what = &x->plane[0].src; - const struct buf_2d *const in_what = &xd->plane[0].pre[0]; - const MV fcenter_mv = { center_mv->row >> 3, center_mv->col >> 3 }; - unsigned int best_sad = INT_MAX; - int i, j; - clamp_mv(ref_mv, x->mv_limits.col_min, x->mv_limits.col_max, - x->mv_limits.row_min, x->mv_limits.row_max); - best_sad = - fn_ptr->sdaf(what->buf, what->stride, get_buf_from_mv(in_what, ref_mv), - in_what->stride, second_pred) + - mvsad_err_cost(x, ref_mv, &fcenter_mv, error_per_bit); - - for (i = 0; i < search_range; ++i) { - int best_site = -1; - - for (j = 0; j < 8; ++j) { - const MV mv = { ref_mv->row + neighbors[j].row, - ref_mv->col + neighbors[j].col }; - - if (is_mv_in(&x->mv_limits, &mv)) { - unsigned int sad = - fn_ptr->sdaf(what->buf, what->stride, get_buf_from_mv(in_what, &mv), - in_what->stride, second_pred); - if (sad < best_sad) { - sad += mvsad_err_cost(x, &mv, &fcenter_mv, error_per_bit); - if (sad < best_sad) { - best_sad = sad; - best_site = j; - } - } - } - } - - if (best_site == -1) { - break; - } else { - ref_mv->row += neighbors[best_site].row; - ref_mv->col += neighbors[best_site].col; - } - } - return best_sad; -} - -int vp9_full_pixel_search(const VP9_COMP *const cpi, const MACROBLOCK *const x, - BLOCK_SIZE bsize, MV *mvp_full, int step_param, - int search_method, int error_per_bit, int *cost_list, - const MV *ref_mv, MV *tmp_mv, int var_max, int rd) { - const SPEED_FEATURES *const sf = &cpi->sf; - const SEARCH_METHODS method = (SEARCH_METHODS)search_method; - const vp9_variance_fn_ptr_t *fn_ptr = &cpi->fn_ptr[bsize]; - int var = 0; - int run_exhaustive_search = 0; - - if (cost_list) { - cost_list[0] = INT_MAX; - cost_list[1] = INT_MAX; - cost_list[2] = INT_MAX; - cost_list[3] = INT_MAX; - cost_list[4] = INT_MAX; - } - - switch (method) { - case FAST_DIAMOND: - var = fast_dia_search(x, mvp_full, step_param, error_per_bit, 0, - cost_list, fn_ptr, 1, ref_mv, tmp_mv); - break; - case FAST_HEX: - var = fast_hex_search(x, mvp_full, step_param, error_per_bit, 0, - cost_list, fn_ptr, 1, ref_mv, tmp_mv); - break; - case HEX: - var = hex_search(x, mvp_full, step_param, error_per_bit, 1, cost_list, - fn_ptr, 1, ref_mv, tmp_mv); - break; - case SQUARE: - var = square_search(x, mvp_full, step_param, error_per_bit, 1, cost_list, - fn_ptr, 1, ref_mv, tmp_mv); - break; - case BIGDIA: - var = bigdia_search(x, mvp_full, step_param, error_per_bit, 1, cost_list, - fn_ptr, 1, ref_mv, tmp_mv); - break; - case NSTEP: - case MESH: - var = full_pixel_diamond( - cpi, x, bsize, mvp_full, step_param, error_per_bit, - MAX_MVSEARCH_STEPS - 1 - step_param, 1, - cpi->sf.mv.use_downsampled_sad, cost_list, fn_ptr, ref_mv, tmp_mv); - break; - default: assert(0 && "Unknown search method"); - } - - if (method == NSTEP) { - if (sf->exhaustive_searches_thresh < INT_MAX && - !cpi->rc.is_src_frame_alt_ref) { - const int64_t exhaustive_thr = - get_exhaustive_threshold(sf->exhaustive_searches_thresh, bsize); - if (var > exhaustive_thr) { - run_exhaustive_search = 1; - } - } - } else if (method == MESH) { - run_exhaustive_search = 1; - } - - if (run_exhaustive_search) { - int var_ex; - MV tmp_mv_ex; - var_ex = full_pixel_exhaustive(cpi, x, tmp_mv, error_per_bit, cost_list, - fn_ptr, ref_mv, &tmp_mv_ex); - if (var_ex < var) { - var = var_ex; - *tmp_mv = tmp_mv_ex; - } - } - - if (method != NSTEP && method != MESH && rd && var < var_max) - var = vp9_get_mvpred_var(x, tmp_mv, ref_mv, fn_ptr, 1); - - return var; -} - -// Note(yunqingwang): The following 2 functions are only used in the motion -// vector unit test, which return extreme motion vectors allowed by the MV -// limits. -#define COMMON_MV_TEST \ - SETUP_SUBPEL_SEARCH; \ - \ - (void)error_per_bit; \ - (void)vfp; \ - (void)z; \ - (void)src_stride; \ - (void)y; \ - (void)y_stride; \ - (void)second_pred; \ - (void)w; \ - (void)h; \ - (void)offset; \ - (void)mvjcost; \ - (void)mvcost; \ - (void)sse1; \ - (void)distortion; \ - \ - (void)halfiters; \ - (void)quarteriters; \ - (void)eighthiters; \ - (void)whichdir; \ - (void)allow_hp; \ - (void)forced_stop; \ - (void)hstep; \ - (void)rr; \ - (void)rc; \ - \ - (void)tr; \ - (void)tc; \ - (void)sse; \ - (void)thismse; \ - (void)cost_list; \ - (void)use_accurate_subpel_search - -// Return the maximum MV. -uint32_t vp9_return_max_sub_pixel_mv( - const MACROBLOCK *x, MV *bestmv, const MV *ref_mv, int allow_hp, - int error_per_bit, const vp9_variance_fn_ptr_t *vfp, int forced_stop, - int iters_per_step, int *cost_list, int *mvjcost, int *mvcost[2], - uint32_t *distortion, uint32_t *sse1, const uint8_t *second_pred, int w, - int h, int use_accurate_subpel_search) { - COMMON_MV_TEST; - - (void)minr; - (void)minc; - - bestmv->row = maxr; - bestmv->col = maxc; - besterr = 0; - - // In the sub-pel motion search, if hp is not used, then the last bit of mv - // has to be 0. - lower_mv_precision(bestmv, allow_hp && use_mv_hp(ref_mv)); - - return besterr; -} -// Return the minimum MV. -uint32_t vp9_return_min_sub_pixel_mv( - const MACROBLOCK *x, MV *bestmv, const MV *ref_mv, int allow_hp, - int error_per_bit, const vp9_variance_fn_ptr_t *vfp, int forced_stop, - int iters_per_step, int *cost_list, int *mvjcost, int *mvcost[2], - uint32_t *distortion, uint32_t *sse1, const uint8_t *second_pred, int w, - int h, int use_accurate_subpel_search) { - COMMON_MV_TEST; - - (void)maxr; - (void)maxc; - - bestmv->row = minr; - bestmv->col = minc; - besterr = 0; - - // In the sub-pel motion search, if hp is not used, then the last bit of mv - // has to be 0. - lower_mv_precision(bestmv, allow_hp && use_mv_hp(ref_mv)); - - return besterr; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_mcomp.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_mcomp.h deleted file mode 100644 index fd6a8b9a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_mcomp.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_MCOMP_H_ -#define VPX_VP9_ENCODER_VP9_MCOMP_H_ - -#include "vp9/encoder/vp9_block.h" -#if CONFIG_NON_GREEDY_MV -#include "vp9/encoder/vp9_non_greedy_mv.h" -#endif // CONFIG_NON_GREEDY_MV -#include "vpx_dsp/variance.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// The maximum number of steps in a step search given the largest -// allowed initial step -#define MAX_MVSEARCH_STEPS 11 -// Max full pel mv specified in the unit of full pixel -// Enable the use of motion vector in range [-1023, 1023]. -#define MAX_FULL_PEL_VAL ((1 << (MAX_MVSEARCH_STEPS - 1)) - 1) -// Maximum size of the first step in full pel units -#define MAX_FIRST_STEP (1 << (MAX_MVSEARCH_STEPS - 1)) -// Allowed motion vector pixel distance outside image border -// for Block_16x16 -#define BORDER_MV_PIXELS_B16 (16 + VP9_INTERP_EXTEND) - -typedef struct search_site_config { - // motion search sites - MV ss_mv[8 * MAX_MVSEARCH_STEPS]; // Motion vector - intptr_t ss_os[8 * MAX_MVSEARCH_STEPS]; // Offset - int searches_per_step; - int total_steps; -} search_site_config; - -typedef struct vp9_sad_table { - vpx_sad_fn_t sdf; - vpx_sad_multi_d_fn_t sdx4df; -} vp9_sad_fn_ptr_t; - -static INLINE const uint8_t *get_buf_from_mv(const struct buf_2d *buf, - const MV *mv) { - return &buf->buf[mv->row * buf->stride + mv->col]; -} - -void vp9_init_dsmotion_compensation(search_site_config *cfg, int stride); -void vp9_init3smotion_compensation(search_site_config *cfg, int stride); - -void vp9_set_mv_search_range(MvLimits *mv_limits, const MV *mv); -int vp9_mv_bit_cost(const MV *mv, const MV *ref, const int *mvjcost, - int *mvcost[2], int weight); - -// Utility to compute variance + MV rate cost for a given MV -int vp9_get_mvpred_var(const MACROBLOCK *x, const MV *best_mv, - const MV *center_mv, const vp9_variance_fn_ptr_t *vfp, - int use_mvcost); -int vp9_get_mvpred_av_var(const MACROBLOCK *x, const MV *best_mv, - const MV *center_mv, const uint8_t *second_pred, - const vp9_variance_fn_ptr_t *vfp, int use_mvcost); - -struct VP9_COMP; -struct SPEED_FEATURES; -struct vp9_sad_table; - -int vp9_init_search_range(int size); - -int vp9_refining_search_sad(const struct macroblock *x, struct mv *ref_mv, - int error_per_bit, int search_range, - const struct vp9_sad_table *sad_fn_ptr, - const struct mv *center_mv); - -// Perform integral projection based motion estimation. -unsigned int vp9_int_pro_motion_estimation(const struct VP9_COMP *cpi, - MACROBLOCK *x, BLOCK_SIZE bsize, - int mi_row, int mi_col, - const MV *ref_mv); - -typedef uint32_t(fractional_mv_step_fp)( - const MACROBLOCK *x, MV *bestmv, const MV *ref_mv, int allow_hp, - int error_per_bit, const vp9_variance_fn_ptr_t *vfp, - int forced_stop, // 0 - full, 1 - qtr only, 2 - half only - int iters_per_step, int *cost_list, int *mvjcost, int *mvcost[2], - uint32_t *distortion, uint32_t *sse1, const uint8_t *second_pred, int w, - int h, int use_accurate_subpel_search); - -extern fractional_mv_step_fp vp9_find_best_sub_pixel_tree; -extern fractional_mv_step_fp vp9_find_best_sub_pixel_tree_pruned; -extern fractional_mv_step_fp vp9_find_best_sub_pixel_tree_pruned_more; -extern fractional_mv_step_fp vp9_find_best_sub_pixel_tree_pruned_evenmore; -extern fractional_mv_step_fp vp9_skip_sub_pixel_tree; -extern fractional_mv_step_fp vp9_return_max_sub_pixel_mv; -extern fractional_mv_step_fp vp9_return_min_sub_pixel_mv; - -typedef int (*vp9_diamond_search_fn_t)( - const MACROBLOCK *x, const search_site_config *cfg, MV *ref_mv, - uint32_t start_mv_sad, MV *best_mv, int search_param, int sad_per_bit, - int *num00, const vp9_sad_fn_ptr_t *sad_fn_ptr, const MV *center_mv); - -int vp9_refining_search_8p_c(const MACROBLOCK *x, MV *ref_mv, int error_per_bit, - int search_range, - const vp9_variance_fn_ptr_t *fn_ptr, - const MV *center_mv, const uint8_t *second_pred); - -struct VP9_COMP; - -// "mvp_full" is the MV search starting point; -// "ref_mv" is the context reference MV; -// "tmp_mv" is the searched best MV. -int vp9_full_pixel_search(const struct VP9_COMP *const cpi, - const MACROBLOCK *const x, BLOCK_SIZE bsize, - MV *mvp_full, int step_param, int search_method, - int error_per_bit, int *cost_list, const MV *ref_mv, - MV *tmp_mv, int var_max, int rd); - -void vp9_set_subpel_mv_search_range(MvLimits *subpel_mv_limits, - const MvLimits *umv_window_limits, - const MV *ref_mv); - -#if CONFIG_NON_GREEDY_MV -struct TplDepStats; -int64_t vp9_refining_search_sad_new(const MACROBLOCK *x, MV *best_full_mv, - int lambda, int search_range, - const vp9_variance_fn_ptr_t *fn_ptr, - const int_mv *nb_full_mvs, int full_mv_num); - -int vp9_full_pixel_diamond_new(const struct VP9_COMP *cpi, MACROBLOCK *x, - BLOCK_SIZE bsize, MV *mvp_full, int step_param, - int lambda, int do_refine, - const int_mv *nb_full_mvs, int full_mv_num, - MV *best_mv); - -static INLINE MV get_full_mv(const MV *mv) { - MV out_mv; - out_mv.row = mv->row >> 3; - out_mv.col = mv->col >> 3; - return out_mv; -} -struct TplDepFrame; -int vp9_prepare_nb_full_mvs(const struct MotionField *motion_field, int mi_row, - int mi_col, int_mv *nb_full_mvs); - -static INLINE BLOCK_SIZE get_square_block_size(BLOCK_SIZE bsize) { - BLOCK_SIZE square_bsize; - switch (bsize) { - case BLOCK_4X4: - case BLOCK_4X8: - case BLOCK_8X4: square_bsize = BLOCK_4X4; break; - case BLOCK_8X8: - case BLOCK_8X16: - case BLOCK_16X8: square_bsize = BLOCK_8X8; break; - case BLOCK_16X16: - case BLOCK_16X32: - case BLOCK_32X16: square_bsize = BLOCK_16X16; break; - case BLOCK_32X32: - case BLOCK_32X64: - case BLOCK_64X32: - case BLOCK_64X64: square_bsize = BLOCK_32X32; break; - default: - square_bsize = BLOCK_INVALID; - assert(0 && "ERROR: invalid block size"); - break; - } - return square_bsize; -} -#endif // CONFIG_NON_GREEDY_MV -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_MCOMP_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_multi_thread.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_multi_thread.c deleted file mode 100644 index 8437ce75..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_multi_thread.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "vpx_util/vpx_pthread.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_ethread.h" -#include "vp9/encoder/vp9_multi_thread.h" -#include "vp9/encoder/vp9_temporal_filter.h" - -void *vp9_enc_grp_get_next_job(MultiThreadHandle *multi_thread_ctxt, - int tile_id) { - RowMTInfo *row_mt_info; - JobQueueHandle *job_queue_hdl = NULL; - void *next = NULL; - JobNode *job_info = NULL; -#if CONFIG_MULTITHREAD - pthread_mutex_t *mutex_handle = NULL; -#endif - - row_mt_info = (RowMTInfo *)(&multi_thread_ctxt->row_mt_info[tile_id]); - job_queue_hdl = (JobQueueHandle *)&row_mt_info->job_queue_hdl; -#if CONFIG_MULTITHREAD - mutex_handle = &row_mt_info->job_mutex; -#endif - -// lock the mutex for queue access -#if CONFIG_MULTITHREAD - pthread_mutex_lock(mutex_handle); -#endif - next = job_queue_hdl->next; - if (next != NULL) { - JobQueue *job_queue = (JobQueue *)next; - job_info = &job_queue->job_info; - // Update the next job in the queue - job_queue_hdl->next = job_queue->next; - job_queue_hdl->num_jobs_acquired++; - } - -#if CONFIG_MULTITHREAD - pthread_mutex_unlock(mutex_handle); -#endif - - return job_info; -} - -void vp9_row_mt_alloc_rd_thresh(VP9_COMP *const cpi, - TileDataEnc *const this_tile) { - VP9_COMMON *const cm = &cpi->common; - const int sb_rows = mi_cols_aligned_to_sb(cm->mi_rows) >> MI_BLOCK_SIZE_LOG2; - int i; - - if (this_tile->row_base_thresh_freq_fact != NULL) { - if (sb_rows <= this_tile->sb_rows) { - return; - } - vpx_free(this_tile->row_base_thresh_freq_fact); - this_tile->row_base_thresh_freq_fact = NULL; - } - CHECK_MEM_ERROR( - &cm->error, this_tile->row_base_thresh_freq_fact, - (int *)vpx_calloc(sb_rows * BLOCK_SIZES * MAX_MODES, - sizeof(*(this_tile->row_base_thresh_freq_fact)))); - for (i = 0; i < sb_rows * BLOCK_SIZES * MAX_MODES; i++) - this_tile->row_base_thresh_freq_fact[i] = RD_THRESH_INIT_FACT; - this_tile->sb_rows = sb_rows; -} - -void vp9_row_mt_mem_alloc(VP9_COMP *cpi) { - struct VP9Common *cm = &cpi->common; - MultiThreadHandle *multi_thread_ctxt = &cpi->multi_thread_ctxt; - int tile_row, tile_col; - const int tile_cols = 1 << cm->log2_tile_cols; - const int tile_rows = 1 << cm->log2_tile_rows; - const int sb_rows = mi_cols_aligned_to_sb(cm->mi_rows) >> MI_BLOCK_SIZE_LOG2; - int jobs_per_tile_col, total_jobs; - - // Allocate memory that is large enough for all row_mt stages. First pass - // uses 16x16 block size. - jobs_per_tile_col = VPXMAX(cm->mb_rows, sb_rows); - // Calculate the total number of jobs - total_jobs = jobs_per_tile_col * tile_cols; - - multi_thread_ctxt->allocated_tile_cols = tile_cols; - multi_thread_ctxt->allocated_tile_rows = tile_rows; - multi_thread_ctxt->allocated_vert_unit_rows = jobs_per_tile_col; - - CHECK_MEM_ERROR(&cm->error, multi_thread_ctxt->job_queue, - (JobQueue *)vpx_memalign(32, total_jobs * sizeof(JobQueue))); - -#if CONFIG_MULTITHREAD - // Create mutex for each tile - for (tile_col = 0; tile_col < tile_cols; tile_col++) { - RowMTInfo *row_mt_info = &multi_thread_ctxt->row_mt_info[tile_col]; - pthread_mutex_init(&row_mt_info->job_mutex, NULL); - } -#endif - - // Allocate memory for row based multi-threading - for (tile_col = 0; tile_col < tile_cols; tile_col++) { - TileDataEnc *this_tile = &cpi->tile_data[tile_col]; - vp9_row_mt_sync_mem_alloc(&this_tile->row_mt_sync, cm, jobs_per_tile_col); - } - - // Assign the sync pointer of tile row zero for every tile row > 0 - for (tile_row = 1; tile_row < tile_rows; tile_row++) { - for (tile_col = 0; tile_col < tile_cols; tile_col++) { - TileDataEnc *this_tile = &cpi->tile_data[tile_row * tile_cols + tile_col]; - TileDataEnc *this_col_tile = &cpi->tile_data[tile_col]; - this_tile->row_mt_sync = this_col_tile->row_mt_sync; - } - } - - // Calculate the number of vertical units in the given tile row - for (tile_row = 0; tile_row < tile_rows; tile_row++) { - TileDataEnc *this_tile = &cpi->tile_data[tile_row * tile_cols]; - TileInfo *tile_info = &this_tile->tile_info; - multi_thread_ctxt->num_tile_vert_sbs[tile_row] = - get_num_vert_units(*tile_info, MI_BLOCK_SIZE_LOG2); - } -} - -void vp9_row_mt_mem_dealloc(VP9_COMP *cpi) { - MultiThreadHandle *multi_thread_ctxt = &cpi->multi_thread_ctxt; - int tile_col; -#if CONFIG_MULTITHREAD - int tile_row; -#endif - - // Deallocate memory for job queue - if (multi_thread_ctxt->job_queue) { - vpx_free(multi_thread_ctxt->job_queue); - multi_thread_ctxt->job_queue = NULL; - } - -#if CONFIG_MULTITHREAD - // Destroy mutex for each tile - for (tile_col = 0; tile_col < multi_thread_ctxt->allocated_tile_cols; - tile_col++) { - RowMTInfo *row_mt_info = &multi_thread_ctxt->row_mt_info[tile_col]; - pthread_mutex_destroy(&row_mt_info->job_mutex); - } -#endif - - // Free row based multi-threading sync memory - for (tile_col = 0; tile_col < multi_thread_ctxt->allocated_tile_cols; - tile_col++) { - TileDataEnc *this_tile = &cpi->tile_data[tile_col]; - vp9_row_mt_sync_mem_dealloc(&this_tile->row_mt_sync); - } - -#if CONFIG_MULTITHREAD - for (tile_row = 0; tile_row < multi_thread_ctxt->allocated_tile_rows; - tile_row++) { - for (tile_col = 0; tile_col < multi_thread_ctxt->allocated_tile_cols; - tile_col++) { - TileDataEnc *this_tile = - &cpi->tile_data[tile_row * multi_thread_ctxt->allocated_tile_cols + - tile_col]; - if (this_tile->row_base_thresh_freq_fact != NULL) { - vpx_free(this_tile->row_base_thresh_freq_fact); - this_tile->row_base_thresh_freq_fact = NULL; - } - } - } -#endif - - multi_thread_ctxt->allocated_tile_cols = 0; - multi_thread_ctxt->allocated_tile_rows = 0; - multi_thread_ctxt->allocated_vert_unit_rows = 0; -} - -void vp9_multi_thread_tile_init(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - const int tile_cols = 1 << cm->log2_tile_cols; - const int sb_rows = mi_cols_aligned_to_sb(cm->mi_rows) >> MI_BLOCK_SIZE_LOG2; - int i; - - for (i = 0; i < tile_cols; i++) { - TileDataEnc *this_tile = &cpi->tile_data[i]; - int jobs_per_tile_col = cpi->oxcf.pass == 1 ? cm->mb_rows : sb_rows; - - // Initialize cur_col to -1 for all rows. - memset(this_tile->row_mt_sync.cur_col, -1, - sizeof(*this_tile->row_mt_sync.cur_col) * jobs_per_tile_col); - vp9_zero(this_tile->fp_data); - this_tile->fp_data.image_data_start_row = INVALID_ROW; - } -} - -void vp9_assign_tile_to_thread(MultiThreadHandle *multi_thread_ctxt, - int tile_cols, int num_workers) { - int tile_id = 0; - int i; - - // Allocating the threads for the tiles - for (i = 0; i < num_workers; i++) { - multi_thread_ctxt->thread_id_to_tile_id[i] = tile_id++; - if (tile_id == tile_cols) tile_id = 0; - } -} - -int vp9_get_job_queue_status(MultiThreadHandle *multi_thread_ctxt, - int cur_tile_id) { - RowMTInfo *row_mt_info; - JobQueueHandle *job_queue_hndl; -#if CONFIG_MULTITHREAD - pthread_mutex_t *mutex; -#endif - int num_jobs_remaining; - - row_mt_info = &multi_thread_ctxt->row_mt_info[cur_tile_id]; - job_queue_hndl = &row_mt_info->job_queue_hdl; -#if CONFIG_MULTITHREAD - mutex = &row_mt_info->job_mutex; -#endif - -#if CONFIG_MULTITHREAD - pthread_mutex_lock(mutex); -#endif - num_jobs_remaining = - multi_thread_ctxt->jobs_per_tile_col - job_queue_hndl->num_jobs_acquired; -#if CONFIG_MULTITHREAD - pthread_mutex_unlock(mutex); -#endif - - return (num_jobs_remaining); -} - -void vp9_prepare_job_queue(VP9_COMP *cpi, JOB_TYPE job_type) { - VP9_COMMON *const cm = &cpi->common; - MultiThreadHandle *multi_thread_ctxt = &cpi->multi_thread_ctxt; - JobQueue *job_queue = multi_thread_ctxt->job_queue; - const int tile_cols = 1 << cm->log2_tile_cols; - int job_row_num, jobs_per_tile, jobs_per_tile_col = 0, total_jobs; - const int sb_rows = mi_cols_aligned_to_sb(cm->mi_rows) >> MI_BLOCK_SIZE_LOG2; - int tile_col, i; - - switch (job_type) { - case ENCODE_JOB: jobs_per_tile_col = sb_rows; break; - case FIRST_PASS_JOB: jobs_per_tile_col = cm->mb_rows; break; - case ARNR_JOB: - jobs_per_tile_col = ((cm->mi_rows + TF_ROUND) >> TF_SHIFT); - break; - default: assert(0); - } - - total_jobs = jobs_per_tile_col * tile_cols; - - multi_thread_ctxt->jobs_per_tile_col = jobs_per_tile_col; - // memset the entire job queue buffer to zero - memset(job_queue, 0, total_jobs * sizeof(JobQueue)); - - // Job queue preparation - for (tile_col = 0; tile_col < tile_cols; tile_col++) { - RowMTInfo *tile_ctxt = &multi_thread_ctxt->row_mt_info[tile_col]; - JobQueue *job_queue_curr, *job_queue_temp; - int tile_row = 0; - - tile_ctxt->job_queue_hdl.next = (void *)job_queue; - tile_ctxt->job_queue_hdl.num_jobs_acquired = 0; - - job_queue_curr = job_queue; - job_queue_temp = job_queue; - - // loop over all the vertical rows - for (job_row_num = 0, jobs_per_tile = 0; job_row_num < jobs_per_tile_col; - job_row_num++, jobs_per_tile++) { - job_queue_curr->job_info.vert_unit_row_num = job_row_num; - job_queue_curr->job_info.tile_col_id = tile_col; - job_queue_curr->job_info.tile_row_id = tile_row; - job_queue_curr->next = (void *)(job_queue_temp + 1); - job_queue_curr = ++job_queue_temp; - - if (ENCODE_JOB == job_type) { - if (jobs_per_tile >= - multi_thread_ctxt->num_tile_vert_sbs[tile_row] - 1) { - tile_row++; - jobs_per_tile = -1; - } - } - } - - // Set the last pointer to NULL - job_queue_curr += -1; - job_queue_curr->next = (void *)NULL; - - // Move to the next tile - job_queue += jobs_per_tile_col; - } - - for (i = 0; i < cpi->num_workers; i++) { - EncWorkerData *thread_data; - thread_data = &cpi->tile_thr_data[i]; - thread_data->thread_id = i; - - for (tile_col = 0; tile_col < tile_cols; tile_col++) - thread_data->tile_completion_status[tile_col] = 0; - } -} - -int vp9_get_tiles_proc_status(MultiThreadHandle *multi_thread_ctxt, - int *tile_completion_status, int *cur_tile_id, - int tile_cols) { - int tile_col; - int tile_id = -1; // Stores the tile ID with minimum proc done - int max_num_jobs_remaining = 0; - int num_jobs_remaining; - - // Mark the completion to avoid check in the loop - tile_completion_status[*cur_tile_id] = 1; - // Check for the status of all the tiles - for (tile_col = 0; tile_col < tile_cols; tile_col++) { - if (tile_completion_status[tile_col] == 0) { - num_jobs_remaining = - vp9_get_job_queue_status(multi_thread_ctxt, tile_col); - // Mark the completion to avoid checks during future switches across tiles - if (num_jobs_remaining == 0) tile_completion_status[tile_col] = 1; - if (num_jobs_remaining > max_num_jobs_remaining) { - max_num_jobs_remaining = num_jobs_remaining; - tile_id = tile_col; - } - } - } - - if (-1 == tile_id) { - return 1; - } else { - // Update the cur ID to the next tile ID that will be processed, - // which will be the least processed tile - *cur_tile_id = tile_id; - return 0; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_multi_thread.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_multi_thread.h deleted file mode 100644 index a2276f4f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_multi_thread.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_MULTI_THREAD_H_ -#define VPX_VP9_ENCODER_VP9_MULTI_THREAD_H_ - -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_job_queue.h" - -void *vp9_enc_grp_get_next_job(MultiThreadHandle *multi_thread_ctxt, - int tile_id); - -void vp9_prepare_job_queue(VP9_COMP *cpi, JOB_TYPE job_type); - -int vp9_get_job_queue_status(MultiThreadHandle *multi_thread_ctxt, - int cur_tile_id); - -void vp9_assign_tile_to_thread(MultiThreadHandle *multi_thread_ctxt, - int tile_cols, int num_workers); - -void vp9_multi_thread_tile_init(VP9_COMP *cpi); - -void vp9_row_mt_mem_alloc(VP9_COMP *cpi); - -void vp9_row_mt_alloc_rd_thresh(VP9_COMP *const cpi, - TileDataEnc *const this_tile); - -void vp9_row_mt_mem_dealloc(VP9_COMP *cpi); - -int vp9_get_tiles_proc_status(MultiThreadHandle *multi_thread_ctxt, - int *tile_completion_status, int *cur_tile_id, - int tile_cols); - -#endif // VPX_VP9_ENCODER_VP9_MULTI_THREAD_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_noise_estimate.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_noise_estimate.c deleted file mode 100644 index 4ee6e51b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_noise_estimate.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_scale/yv12config.h" -#include "vpx/vpx_integer.h" -#include "vp9/common/vp9_reconinter.h" -#include "vp9/encoder/vp9_context_tree.h" -#include "vp9/encoder/vp9_noise_estimate.h" -#include "vp9/encoder/vp9_encoder.h" - -#if CONFIG_VP9_TEMPORAL_DENOISING -// For SVC: only do noise estimation on top spatial layer. -static INLINE int noise_est_svc(const struct VP9_COMP *const cpi) { - return (!cpi->use_svc || - (cpi->use_svc && - cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1)); -} -#endif - -void vp9_noise_estimate_init(NOISE_ESTIMATE *const ne, int width, int height) { - ne->enabled = 0; - ne->level = (width * height < 1280 * 720) ? kLowLow : kLow; - ne->value = 0; - ne->count = 0; - ne->thresh = 90; - ne->last_w = 0; - ne->last_h = 0; - if (width * height >= 1920 * 1080) { - ne->thresh = 200; - } else if (width * height >= 1280 * 720) { - ne->thresh = 140; - } else if (width * height >= 640 * 360) { - ne->thresh = 115; - } - ne->num_frames_estimate = 15; - ne->adapt_thresh = (3 * ne->thresh) >> 1; -} - -static int enable_noise_estimation(VP9_COMP *const cpi) { -#if CONFIG_VP9_HIGHBITDEPTH - if (cpi->common.use_highbitdepth) return 0; -#endif -// Enable noise estimation if denoising is on. -#if CONFIG_VP9_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity > 0 && noise_est_svc(cpi) && - cpi->common.width >= 320 && cpi->common.height >= 180) - return 1; -#endif - // Only allow noise estimate under certain encoding mode. - // Enabled for 1 pass CBR, speed >=5, and if resolution is same as original. - // Not enabled for SVC mode and screen_content_mode. - // Not enabled for low resolutions. - if (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_CBR && - cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cpi->oxcf.speed >= 5 && - cpi->resize_state == ORIG && cpi->resize_pending == 0 && !cpi->use_svc && - cpi->oxcf.content != VP9E_CONTENT_SCREEN && - cpi->common.width * cpi->common.height >= 640 * 360) - return 1; - else - return 0; -} - -#if CONFIG_VP9_TEMPORAL_DENOISING -static void copy_frame(YV12_BUFFER_CONFIG *const dest, - const YV12_BUFFER_CONFIG *const src) { - int r; - const uint8_t *srcbuf = src->y_buffer; - uint8_t *destbuf = dest->y_buffer; - - assert(dest->y_width == src->y_width); - assert(dest->y_height == src->y_height); - - for (r = 0; r < dest->y_height; ++r) { - memcpy(destbuf, srcbuf, dest->y_width); - destbuf += dest->y_stride; - srcbuf += src->y_stride; - } -} -#endif // CONFIG_VP9_TEMPORAL_DENOISING - -NOISE_LEVEL vp9_noise_estimate_extract_level(NOISE_ESTIMATE *const ne) { - int noise_level = kLowLow; - if (ne->value > (ne->thresh << 1)) { - noise_level = kHigh; - } else { - if (ne->value > ne->thresh) - noise_level = kMedium; - else if (ne->value > (ne->thresh >> 1)) - noise_level = kLow; - else - noise_level = kLowLow; - } - return noise_level; -} - -void vp9_update_noise_estimate(VP9_COMP *const cpi) { - const VP9_COMMON *const cm = &cpi->common; - NOISE_ESTIMATE *const ne = &cpi->noise_estimate; - const int low_res = (cm->width <= 352 && cm->height <= 288); - // Estimate of noise level every frame_period frames. - int frame_period = 8; - int thresh_consec_zeromv = 6; - int frame_counter = cm->current_video_frame; - // Estimate is between current source and last source. - YV12_BUFFER_CONFIG *last_source = cpi->Last_Source; -#if CONFIG_VP9_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity > 0 && noise_est_svc(cpi)) { - last_source = &cpi->denoiser.last_source; - // Tune these thresholds for different resolutions when denoising is - // enabled. - if (cm->width > 640 && cm->width <= 1920) { - thresh_consec_zeromv = 2; - } - } -#endif - ne->enabled = enable_noise_estimation(cpi); - if (cpi->svc.number_spatial_layers > 1) - frame_counter = cpi->svc.current_superframe; - if (!ne->enabled || frame_counter % frame_period != 0 || - last_source == NULL || - (cpi->svc.number_spatial_layers == 1 && - (ne->last_w != cm->width || ne->last_h != cm->height))) { -#if CONFIG_VP9_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity > 0 && noise_est_svc(cpi)) - copy_frame(&cpi->denoiser.last_source, cpi->Source); -#endif - if (last_source != NULL) { - ne->last_w = cm->width; - ne->last_h = cm->height; - } - return; - } else if (frame_counter > 60 && cpi->svc.num_encoded_top_layer > 1 && - cpi->rc.frames_since_key > cpi->svc.number_spatial_layers && - cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1 && - cpi->rc.avg_frame_low_motion < (low_res ? 60 : 40)) { - // Force noise estimation to 0 and denoiser off if content has high motion. - ne->level = kLowLow; - ne->count = 0; - ne->num_frames_estimate = 10; -#if CONFIG_VP9_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity > 0 && noise_est_svc(cpi) && - cpi->svc.current_superframe > 1) { - vp9_denoiser_set_noise_level(cpi, ne->level); - copy_frame(&cpi->denoiser.last_source, cpi->Source); - } -#endif - return; - } else { - unsigned int bin_size = 100; - unsigned int hist[MAX_VAR_HIST_BINS] = { 0 }; - unsigned int hist_avg[MAX_VAR_HIST_BINS]; - unsigned int max_bin = 0; - unsigned int max_bin_count = 0; - unsigned int bin_cnt; - int bsize = BLOCK_16X16; - // Loop over sub-sample of 16x16 blocks of frame, and for blocks that have - // been encoded as zero/small mv at least x consecutive frames, compute - // the variance to update estimate of noise in the source. - const uint8_t *src_y = cpi->Source->y_buffer; - const int src_ystride = cpi->Source->y_stride; - const uint8_t *last_src_y = last_source->y_buffer; - const int last_src_ystride = last_source->y_stride; - const uint8_t *src_u = cpi->Source->u_buffer; - const uint8_t *src_v = cpi->Source->v_buffer; - const int src_uvstride = cpi->Source->uv_stride; - int mi_row, mi_col; - int num_low_motion = 0; - int frame_low_motion = 1; - for (mi_row = 0; mi_row < cm->mi_rows; mi_row++) { - for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) { - int bl_index = mi_row * cm->mi_cols + mi_col; - if (cpi->consec_zero_mv[bl_index] > thresh_consec_zeromv) - num_low_motion++; - } - } - if (num_low_motion < ((3 * cm->mi_rows * cm->mi_cols) >> 3)) - frame_low_motion = 0; - for (mi_row = 0; mi_row < cm->mi_rows; mi_row++) { - for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) { - // 16x16 blocks, 1/4 sample of frame. - if (mi_row % 4 == 0 && mi_col % 4 == 0 && mi_row < cm->mi_rows - 1 && - mi_col < cm->mi_cols - 1) { - int bl_index = mi_row * cm->mi_cols + mi_col; - int bl_index1 = bl_index + 1; - int bl_index2 = bl_index + cm->mi_cols; - int bl_index3 = bl_index2 + 1; - int consec_zeromv = - VPXMIN(cpi->consec_zero_mv[bl_index], - VPXMIN(cpi->consec_zero_mv[bl_index1], - VPXMIN(cpi->consec_zero_mv[bl_index2], - cpi->consec_zero_mv[bl_index3]))); - // Only consider blocks that are likely steady background. i.e., have - // been encoded as zero/low motion x (= thresh_consec_zeromv) frames - // in a row. consec_zero_mv[] defined for 8x8 blocks, so consider all - // 4 sub-blocks for 16x16 block. And exclude this frame if - // high_source_sad is true (i.e., scene/content change). - if (frame_low_motion && consec_zeromv > thresh_consec_zeromv && - !cpi->rc.high_source_sad && - !cpi->svc.high_source_sad_superframe) { - int is_skin = 0; - if (cpi->use_skin_detection) { - is_skin = - vp9_compute_skin_block(src_y, src_u, src_v, src_ystride, - src_uvstride, bsize, consec_zeromv, 0); - } - if (!is_skin) { - unsigned int sse; - // Compute variance between co-located blocks from current and - // last input frames. - unsigned int variance = cpi->fn_ptr[bsize].vf( - src_y, src_ystride, last_src_y, last_src_ystride, &sse); - unsigned int hist_index = variance / bin_size; - if (hist_index < MAX_VAR_HIST_BINS) - hist[hist_index]++; - else if (hist_index < 3 * (MAX_VAR_HIST_BINS >> 1)) - hist[MAX_VAR_HIST_BINS - 1]++; // Account for the tail - } - } - } - src_y += 8; - last_src_y += 8; - src_u += 4; - src_v += 4; - } - src_y += (src_ystride << 3) - (cm->mi_cols << 3); - last_src_y += (last_src_ystride << 3) - (cm->mi_cols << 3); - src_u += (src_uvstride << 2) - (cm->mi_cols << 2); - src_v += (src_uvstride << 2) - (cm->mi_cols << 2); - } - ne->last_w = cm->width; - ne->last_h = cm->height; - // Adjust histogram to account for effect that histogram flattens - // and shifts to zero as scene darkens. - if (hist[0] > 10 && (hist[MAX_VAR_HIST_BINS - 1] > hist[0] >> 2)) { - hist[0] = 0; - hist[1] >>= 2; - hist[2] >>= 2; - hist[3] >>= 2; - hist[4] >>= 1; - hist[5] >>= 1; - hist[6] = 3 * hist[6] >> 1; - hist[MAX_VAR_HIST_BINS - 1] >>= 1; - } - - // Average hist[] and find largest bin - for (bin_cnt = 0; bin_cnt < MAX_VAR_HIST_BINS; bin_cnt++) { - if (bin_cnt == 0) - hist_avg[bin_cnt] = (hist[0] + hist[1] + hist[2]) / 3; - else if (bin_cnt == MAX_VAR_HIST_BINS - 1) - hist_avg[bin_cnt] = hist[MAX_VAR_HIST_BINS - 1] >> 2; - else if (bin_cnt == MAX_VAR_HIST_BINS - 2) - hist_avg[bin_cnt] = (hist[bin_cnt - 1] + 2 * hist[bin_cnt] + - (hist[bin_cnt + 1] >> 1) + 2) >> - 2; - else - hist_avg[bin_cnt] = - (hist[bin_cnt - 1] + 2 * hist[bin_cnt] + hist[bin_cnt + 1] + 2) >> - 2; - - if (hist_avg[bin_cnt] > max_bin_count) { - max_bin_count = hist_avg[bin_cnt]; - max_bin = bin_cnt; - } - } - - // Scale by 40 to work with existing thresholds - ne->value = (int)((3 * ne->value + max_bin * 40) >> 2); - // Quickly increase VNR strength when the noise level increases suddenly. - if (ne->level < kMedium && ne->value > ne->adapt_thresh) { - ne->count = ne->num_frames_estimate; - } else { - ne->count++; - } - if (ne->count == ne->num_frames_estimate) { - // Reset counter and check noise level condition. - ne->num_frames_estimate = 30; - ne->count = 0; - ne->level = vp9_noise_estimate_extract_level(ne); -#if CONFIG_VP9_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity > 0 && noise_est_svc(cpi)) - vp9_denoiser_set_noise_level(cpi, ne->level); -#endif - } - } -#if CONFIG_VP9_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity > 0 && noise_est_svc(cpi)) - copy_frame(&cpi->denoiser.last_source, cpi->Source); -#endif -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_noise_estimate.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_noise_estimate.h deleted file mode 100644 index 7fc94ff8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_noise_estimate.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_NOISE_ESTIMATE_H_ -#define VPX_VP9_ENCODER_VP9_NOISE_ESTIMATE_H_ - -#include "vp9/encoder/vp9_block.h" -#include "vp9/encoder/vp9_skin_detection.h" -#include "vpx_scale/yv12config.h" - -#if CONFIG_VP9_TEMPORAL_DENOISING -#include "vp9/encoder/vp9_denoiser.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_VAR_HIST_BINS 20 - -typedef enum noise_level { kLowLow, kLow, kMedium, kHigh } NOISE_LEVEL; - -typedef struct noise_estimate { - int enabled; - NOISE_LEVEL level; - int value; - int thresh; - int adapt_thresh; - int count; - int last_w; - int last_h; - int num_frames_estimate; -} NOISE_ESTIMATE; - -struct VP9_COMP; - -void vp9_noise_estimate_init(NOISE_ESTIMATE *const ne, int width, int height); - -NOISE_LEVEL vp9_noise_estimate_extract_level(NOISE_ESTIMATE *const ne); - -void vp9_update_noise_estimate(struct VP9_COMP *const cpi); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_NOISE_ESTIMATE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_non_greedy_mv.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_non_greedy_mv.c deleted file mode 100644 index d52801c8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_non_greedy_mv.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Copyright (c) 2019 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp9/common/vp9_mv.h" -#include "vp9/encoder/vp9_non_greedy_mv.h" -// TODO(angiebird): move non_greedy_mv related functions to this file - -#define LOG2_TABLE_SIZE 1024 -static const int log2_table[LOG2_TABLE_SIZE] = { - 0, // This is a dummy value - 0, 1048576, 1661954, 2097152, 2434718, 2710530, 2943725, - 3145728, 3323907, 3483294, 3627477, 3759106, 3880192, 3992301, - 4096672, 4194304, 4286015, 4372483, 4454275, 4531870, 4605679, - 4676053, 4743299, 4807682, 4869436, 4928768, 4985861, 5040877, - 5093962, 5145248, 5194851, 5242880, 5289431, 5334591, 5378443, - 5421059, 5462508, 5502851, 5542146, 5580446, 5617800, 5654255, - 5689851, 5724629, 5758625, 5791875, 5824409, 5856258, 5887450, - 5918012, 5947969, 5977344, 6006160, 6034437, 6062195, 6089453, - 6116228, 6142538, 6168398, 6193824, 6218829, 6243427, 6267632, - 6291456, 6314910, 6338007, 6360756, 6383167, 6405252, 6427019, - 6448477, 6469635, 6490501, 6511084, 6531390, 6551427, 6571202, - 6590722, 6609993, 6629022, 6647815, 6666376, 6684713, 6702831, - 6720734, 6738427, 6755916, 6773205, 6790299, 6807201, 6823917, - 6840451, 6856805, 6872985, 6888993, 6904834, 6920510, 6936026, - 6951384, 6966588, 6981641, 6996545, 7011304, 7025920, 7040397, - 7054736, 7068940, 7083013, 7096956, 7110771, 7124461, 7138029, - 7151476, 7164804, 7178017, 7191114, 7204100, 7216974, 7229740, - 7242400, 7254954, 7267405, 7279754, 7292003, 7304154, 7316208, - 7328167, 7340032, 7351805, 7363486, 7375079, 7386583, 7398000, - 7409332, 7420579, 7431743, 7442826, 7453828, 7464751, 7475595, - 7486362, 7497053, 7507669, 7518211, 7528680, 7539077, 7549404, - 7559660, 7569847, 7579966, 7590017, 7600003, 7609923, 7619778, - 7629569, 7639298, 7648964, 7658569, 7668114, 7677598, 7687023, - 7696391, 7705700, 7714952, 7724149, 7733289, 7742375, 7751407, - 7760385, 7769310, 7778182, 7787003, 7795773, 7804492, 7813161, - 7821781, 7830352, 7838875, 7847350, 7855777, 7864158, 7872493, - 7880782, 7889027, 7897226, 7905381, 7913492, 7921561, 7929586, - 7937569, 7945510, 7953410, 7961268, 7969086, 7976864, 7984602, - 7992301, 7999960, 8007581, 8015164, 8022709, 8030217, 8037687, - 8045121, 8052519, 8059880, 8067206, 8074496, 8081752, 8088973, - 8096159, 8103312, 8110431, 8117516, 8124569, 8131589, 8138576, - 8145532, 8152455, 8159347, 8166208, 8173037, 8179836, 8186605, - 8193343, 8200052, 8206731, 8213380, 8220001, 8226593, 8233156, - 8239690, 8246197, 8252676, 8259127, 8265550, 8271947, 8278316, - 8284659, 8290976, 8297266, 8303530, 8309768, 8315981, 8322168, - 8328330, 8334467, 8340579, 8346667, 8352730, 8358769, 8364784, - 8370775, 8376743, 8382687, 8388608, 8394506, 8400381, 8406233, - 8412062, 8417870, 8423655, 8429418, 8435159, 8440878, 8446576, - 8452252, 8457908, 8463542, 8469155, 8474748, 8480319, 8485871, - 8491402, 8496913, 8502404, 8507875, 8513327, 8518759, 8524171, - 8529564, 8534938, 8540293, 8545629, 8550947, 8556245, 8561525, - 8566787, 8572031, 8577256, 8582464, 8587653, 8592825, 8597980, - 8603116, 8608236, 8613338, 8618423, 8623491, 8628542, 8633576, - 8638593, 8643594, 8648579, 8653547, 8658499, 8663434, 8668354, - 8673258, 8678145, 8683017, 8687874, 8692715, 8697540, 8702350, - 8707145, 8711925, 8716690, 8721439, 8726174, 8730894, 8735599, - 8740290, 8744967, 8749628, 8754276, 8758909, 8763528, 8768134, - 8772725, 8777302, 8781865, 8786415, 8790951, 8795474, 8799983, - 8804478, 8808961, 8813430, 8817886, 8822328, 8826758, 8831175, - 8835579, 8839970, 8844349, 8848715, 8853068, 8857409, 8861737, - 8866053, 8870357, 8874649, 8878928, 8883195, 8887451, 8891694, - 8895926, 8900145, 8904353, 8908550, 8912734, 8916908, 8921069, - 8925220, 8929358, 8933486, 8937603, 8941708, 8945802, 8949885, - 8953957, 8958018, 8962068, 8966108, 8970137, 8974155, 8978162, - 8982159, 8986145, 8990121, 8994086, 8998041, 9001986, 9005920, - 9009844, 9013758, 9017662, 9021556, 9025440, 9029314, 9033178, - 9037032, 9040877, 9044711, 9048536, 9052352, 9056157, 9059953, - 9063740, 9067517, 9071285, 9075044, 9078793, 9082533, 9086263, - 9089985, 9093697, 9097400, 9101095, 9104780, 9108456, 9112123, - 9115782, 9119431, 9123072, 9126704, 9130328, 9133943, 9137549, - 9141146, 9144735, 9148316, 9151888, 9155452, 9159007, 9162554, - 9166092, 9169623, 9173145, 9176659, 9180165, 9183663, 9187152, - 9190634, 9194108, 9197573, 9201031, 9204481, 9207923, 9211357, - 9214784, 9218202, 9221613, 9225017, 9228412, 9231800, 9235181, - 9238554, 9241919, 9245277, 9248628, 9251971, 9255307, 9258635, - 9261956, 9265270, 9268577, 9271876, 9275169, 9278454, 9281732, - 9285002, 9288266, 9291523, 9294773, 9298016, 9301252, 9304481, - 9307703, 9310918, 9314126, 9317328, 9320523, 9323711, 9326892, - 9330067, 9333235, 9336397, 9339552, 9342700, 9345842, 9348977, - 9352106, 9355228, 9358344, 9361454, 9364557, 9367654, 9370744, - 9373828, 9376906, 9379978, 9383043, 9386102, 9389155, 9392202, - 9395243, 9398278, 9401306, 9404329, 9407345, 9410356, 9413360, - 9416359, 9419351, 9422338, 9425319, 9428294, 9431263, 9434226, - 9437184, 9440136, 9443082, 9446022, 9448957, 9451886, 9454809, - 9457726, 9460638, 9463545, 9466446, 9469341, 9472231, 9475115, - 9477994, 9480867, 9483735, 9486597, 9489454, 9492306, 9495152, - 9497993, 9500828, 9503659, 9506484, 9509303, 9512118, 9514927, - 9517731, 9520530, 9523324, 9526112, 9528895, 9531674, 9534447, - 9537215, 9539978, 9542736, 9545489, 9548237, 9550980, 9553718, - 9556451, 9559179, 9561903, 9564621, 9567335, 9570043, 9572747, - 9575446, 9578140, 9580830, 9583514, 9586194, 9588869, 9591540, - 9594205, 9596866, 9599523, 9602174, 9604821, 9607464, 9610101, - 9612735, 9615363, 9617987, 9620607, 9623222, 9625832, 9628438, - 9631040, 9633637, 9636229, 9638818, 9641401, 9643981, 9646556, - 9649126, 9651692, 9654254, 9656812, 9659365, 9661914, 9664459, - 9666999, 9669535, 9672067, 9674594, 9677118, 9679637, 9682152, - 9684663, 9687169, 9689672, 9692170, 9694665, 9697155, 9699641, - 9702123, 9704601, 9707075, 9709545, 9712010, 9714472, 9716930, - 9719384, 9721834, 9724279, 9726721, 9729159, 9731593, 9734024, - 9736450, 9738872, 9741291, 9743705, 9746116, 9748523, 9750926, - 9753326, 9755721, 9758113, 9760501, 9762885, 9765266, 9767642, - 9770015, 9772385, 9774750, 9777112, 9779470, 9781825, 9784175, - 9786523, 9788866, 9791206, 9793543, 9795875, 9798204, 9800530, - 9802852, 9805170, 9807485, 9809797, 9812104, 9814409, 9816710, - 9819007, 9821301, 9823591, 9825878, 9828161, 9830441, 9832718, - 9834991, 9837261, 9839527, 9841790, 9844050, 9846306, 9848559, - 9850808, 9853054, 9855297, 9857537, 9859773, 9862006, 9864235, - 9866462, 9868685, 9870904, 9873121, 9875334, 9877544, 9879751, - 9881955, 9884155, 9886352, 9888546, 9890737, 9892925, 9895109, - 9897291, 9899469, 9901644, 9903816, 9905985, 9908150, 9910313, - 9912473, 9914629, 9916783, 9918933, 9921080, 9923225, 9925366, - 9927504, 9929639, 9931771, 9933900, 9936027, 9938150, 9940270, - 9942387, 9944502, 9946613, 9948721, 9950827, 9952929, 9955029, - 9957126, 9959219, 9961310, 9963398, 9965484, 9967566, 9969645, - 9971722, 9973796, 9975866, 9977934, 9980000, 9982062, 9984122, - 9986179, 9988233, 9990284, 9992332, 9994378, 9996421, 9998461, - 10000498, 10002533, 10004565, 10006594, 10008621, 10010644, 10012665, - 10014684, 10016700, 10018713, 10020723, 10022731, 10024736, 10026738, - 10028738, 10030735, 10032729, 10034721, 10036710, 10038697, 10040681, - 10042662, 10044641, 10046617, 10048591, 10050562, 10052530, 10054496, - 10056459, 10058420, 10060379, 10062334, 10064287, 10066238, 10068186, - 10070132, 10072075, 10074016, 10075954, 10077890, 10079823, 10081754, - 10083682, 10085608, 10087532, 10089453, 10091371, 10093287, 10095201, - 10097112, 10099021, 10100928, 10102832, 10104733, 10106633, 10108529, - 10110424, 10112316, 10114206, 10116093, 10117978, 10119861, 10121742, - 10123620, 10125495, 10127369, 10129240, 10131109, 10132975, 10134839, - 10136701, 10138561, 10140418, 10142273, 10144126, 10145976, 10147825, - 10149671, 10151514, 10153356, 10155195, 10157032, 10158867, 10160699, - 10162530, 10164358, 10166184, 10168007, 10169829, 10171648, 10173465, - 10175280, 10177093, 10178904, 10180712, 10182519, 10184323, 10186125, - 10187925, 10189722, 10191518, 10193311, 10195103, 10196892, 10198679, - 10200464, 10202247, 10204028, 10205806, 10207583, 10209357, 10211130, - 10212900, 10214668, 10216435, 10218199, 10219961, 10221721, 10223479, - 10225235, 10226989, 10228741, 10230491, 10232239, 10233985, 10235728, - 10237470, 10239210, 10240948, 10242684, 10244417, 10246149, 10247879, - 10249607, 10251333, 10253057, 10254779, 10256499, 10258217, 10259933, - 10261647, 10263360, 10265070, 10266778, 10268485, 10270189, 10271892, - 10273593, 10275292, 10276988, 10278683, 10280376, 10282068, 10283757, - 10285444, 10287130, 10288814, 10290495, 10292175, 10293853, 10295530, - 10297204, 10298876, 10300547, 10302216, 10303883, 10305548, 10307211, - 10308873, 10310532, 10312190, 10313846, 10315501, 10317153, 10318804, - 10320452, 10322099, 10323745, 10325388, 10327030, 10328670, 10330308, - 10331944, 10333578, 10335211, 10336842, 10338472, 10340099, 10341725, - 10343349, 10344971, 10346592, 10348210, 10349828, 10351443, 10353057, - 10354668, 10356279, 10357887, 10359494, 10361099, 10362702, 10364304, - 10365904, 10367502, 10369099, 10370694, 10372287, 10373879, 10375468, - 10377057, 10378643, 10380228, 10381811, 10383393, 10384973, 10386551, - 10388128, 10389703, 10391276, 10392848, 10394418, 10395986, 10397553, - 10399118, 10400682, 10402244, 10403804, 10405363, 10406920, 10408476, - 10410030, 10411582, 10413133, 10414682, 10416230, 10417776, 10419320, - 10420863, 10422404, 10423944, 10425482, 10427019, 10428554, 10430087, - 10431619, 10433149, 10434678, 10436206, 10437731, 10439256, 10440778, - 10442299, 10443819, 10445337, 10446854, 10448369, 10449882, 10451394, - 10452905, 10454414, 10455921, 10457427, 10458932, 10460435, 10461936, - 10463436, 10464935, 10466432, 10467927, 10469422, 10470914, 10472405, - 10473895, 10475383, 10476870, 10478355, 10479839, 10481322, 10482802, - 10484282, -}; - -static int mi_size_to_block_size(int mi_bsize, int mi_num) { - return (mi_num % mi_bsize) ? mi_num / mi_bsize + 1 : mi_num / mi_bsize; -} - -Status vp9_alloc_motion_field_info(MotionFieldInfo *motion_field_info, - int frame_num, int mi_rows, int mi_cols) { - int frame_idx, rf_idx, square_block_idx; - if (motion_field_info->allocated) { - // TODO(angiebird): Avoid re-allocate buffer if possible - vp9_free_motion_field_info(motion_field_info); - } - motion_field_info->frame_num = frame_num; - motion_field_info->motion_field_array = - vpx_calloc(frame_num, sizeof(*motion_field_info->motion_field_array)); - if (!motion_field_info->motion_field_array) return STATUS_FAILED; - for (frame_idx = 0; frame_idx < frame_num; ++frame_idx) { - for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) { - for (square_block_idx = 0; square_block_idx < SQUARE_BLOCK_SIZES; - ++square_block_idx) { - BLOCK_SIZE bsize = square_block_idx_to_bsize(square_block_idx); - const int mi_height = num_8x8_blocks_high_lookup[bsize]; - const int mi_width = num_8x8_blocks_wide_lookup[bsize]; - const int block_rows = mi_size_to_block_size(mi_height, mi_rows); - const int block_cols = mi_size_to_block_size(mi_width, mi_cols); - MotionField *motion_field = - &motion_field_info - ->motion_field_array[frame_idx][rf_idx][square_block_idx]; - Status status = - vp9_alloc_motion_field(motion_field, bsize, block_rows, block_cols); - if (status == STATUS_FAILED) { - return STATUS_FAILED; - } - } - } - } - motion_field_info->allocated = 1; - return STATUS_OK; -} - -Status vp9_alloc_motion_field(MotionField *motion_field, BLOCK_SIZE bsize, - int block_rows, int block_cols) { - Status status = STATUS_OK; - motion_field->ready = 0; - motion_field->bsize = bsize; - motion_field->block_rows = block_rows; - motion_field->block_cols = block_cols; - motion_field->block_num = block_rows * block_cols; - motion_field->mf = - vpx_calloc(motion_field->block_num, sizeof(*motion_field->mf)); - if (motion_field->mf == NULL) { - status = STATUS_FAILED; - } - motion_field->set_mv = - vpx_calloc(motion_field->block_num, sizeof(*motion_field->set_mv)); - if (motion_field->set_mv == NULL) { - vpx_free(motion_field->mf); - motion_field->mf = NULL; - status = STATUS_FAILED; - } - motion_field->local_structure = vpx_calloc( - motion_field->block_num, sizeof(*motion_field->local_structure)); - if (motion_field->local_structure == NULL) { - vpx_free(motion_field->mf); - motion_field->mf = NULL; - vpx_free(motion_field->set_mv); - motion_field->set_mv = NULL; - status = STATUS_FAILED; - } - return status; -} - -void vp9_free_motion_field(MotionField *motion_field) { - vpx_free(motion_field->mf); - vpx_free(motion_field->set_mv); - vpx_free(motion_field->local_structure); - vp9_zero(*motion_field); -} - -void vp9_free_motion_field_info(MotionFieldInfo *motion_field_info) { - if (motion_field_info->allocated) { - int frame_idx, rf_idx, square_block_idx; - for (frame_idx = 0; frame_idx < motion_field_info->frame_num; ++frame_idx) { - for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) { - for (square_block_idx = 0; square_block_idx < SQUARE_BLOCK_SIZES; - ++square_block_idx) { - MotionField *motion_field = - &motion_field_info - ->motion_field_array[frame_idx][rf_idx][square_block_idx]; - vp9_free_motion_field(motion_field); - } - } - } - vpx_free(motion_field_info->motion_field_array); - motion_field_info->motion_field_array = NULL; - motion_field_info->frame_num = 0; - motion_field_info->allocated = 0; - } -} - -MotionField *vp9_motion_field_info_get_motion_field( - MotionFieldInfo *motion_field_info, int frame_idx, int rf_idx, - BLOCK_SIZE bsize) { - int square_block_idx = get_square_block_idx(bsize); - assert(frame_idx < motion_field_info->frame_num); - assert(motion_field_info->allocated == 1); - return &motion_field_info - ->motion_field_array[frame_idx][rf_idx][square_block_idx]; -} - -int vp9_motion_field_is_mv_set(const MotionField *motion_field, int brow, - int bcol) { - assert(brow >= 0 && brow < motion_field->block_rows); - assert(bcol >= 0 && bcol < motion_field->block_cols); - return motion_field->set_mv[brow * motion_field->block_cols + bcol]; -} - -int_mv vp9_motion_field_get_mv(const MotionField *motion_field, int brow, - int bcol) { - assert(brow >= 0 && brow < motion_field->block_rows); - assert(bcol >= 0 && bcol < motion_field->block_cols); - return motion_field->mf[brow * motion_field->block_cols + bcol]; -} - -int_mv vp9_motion_field_mi_get_mv(const MotionField *motion_field, int mi_row, - int mi_col) { - const int mi_height = num_8x8_blocks_high_lookup[motion_field->bsize]; - const int mi_width = num_8x8_blocks_wide_lookup[motion_field->bsize]; - const int brow = mi_row / mi_height; - const int bcol = mi_col / mi_width; - assert(mi_row % mi_height == 0); - assert(mi_col % mi_width == 0); - return vp9_motion_field_get_mv(motion_field, brow, bcol); -} - -void vp9_motion_field_mi_set_mv(MotionField *motion_field, int mi_row, - int mi_col, int_mv mv) { - const int mi_height = num_8x8_blocks_high_lookup[motion_field->bsize]; - const int mi_width = num_8x8_blocks_wide_lookup[motion_field->bsize]; - const int brow = mi_row / mi_height; - const int bcol = mi_col / mi_width; - assert(mi_row % mi_height == 0); - assert(mi_col % mi_width == 0); - assert(brow >= 0 && brow < motion_field->block_rows); - assert(bcol >= 0 && bcol < motion_field->block_cols); - motion_field->mf[brow * motion_field->block_cols + bcol] = mv; - motion_field->set_mv[brow * motion_field->block_cols + bcol] = 1; -} - -void vp9_motion_field_reset_mvs(MotionField *motion_field) { - memset(motion_field->set_mv, 0, - motion_field->block_num * sizeof(*motion_field->set_mv)); -} - -static int64_t log2_approximation(int64_t v) { - assert(v > 0); - if (v < LOG2_TABLE_SIZE) { - return log2_table[v]; - } else { - // use linear approximation when v >= 2^10 - const int slope = - 1477; // slope = 1 / (log(2) * 1024) * (1 << LOG2_PRECISION) - assert(LOG2_TABLE_SIZE == 1 << 10); - - return slope * (v - LOG2_TABLE_SIZE) + (10 << LOG2_PRECISION); - } -} - -int64_t vp9_nb_mvs_inconsistency(const MV *mv, const int_mv *nb_full_mvs, - int mv_num) { - // The behavior of this function is to compute log2 of mv difference, - // i.e. min log2(1 + row_diff * row_diff + col_diff * col_diff) - // against available neighbor mvs. - // Since the log2 is monotonically increasing, we can compute - // min row_diff * row_diff + col_diff * col_diff first - // then apply log2 in the end. - int i; - int64_t min_abs_diff = INT64_MAX; - int cnt = 0; - assert(mv_num <= NB_MVS_NUM); - for (i = 0; i < mv_num; ++i) { - MV nb_mv = nb_full_mvs[i].as_mv; - const int64_t row_diff = abs(mv->row - nb_mv.row); - const int64_t col_diff = abs(mv->col - nb_mv.col); - const int64_t abs_diff = row_diff * row_diff + col_diff * col_diff; - assert(nb_full_mvs[i].as_int != INVALID_MV); - min_abs_diff = VPXMIN(abs_diff, min_abs_diff); - ++cnt; - } - if (cnt) { - return log2_approximation(1 + min_abs_diff); - } - return 0; -} - -static FloatMV get_smooth_motion_vector(const FloatMV scaled_search_mv, - const FloatMV *tmp_mf, - const int (*M)[MF_LOCAL_STRUCTURE_SIZE], - int rows, int cols, int row, int col, - float alpha) { - const FloatMV tmp_mv = tmp_mf[row * cols + col]; - int idx_row, idx_col; - FloatMV avg_nb_mv = { 0.0f, 0.0f }; - FloatMV mv = { 0.0f, 0.0f }; - float filter[3][3] = { { 1.0f / 12.0f, 1.0f / 6.0f, 1.0f / 12.0f }, - { 1.0f / 6.0f, 0.0f, 1.0f / 6.0f }, - { 1.0f / 12.0f, 1.0f / 6.0f, 1.0f / 12.0f } }; - for (idx_row = 0; idx_row < 3; ++idx_row) { - int nb_row = row + idx_row - 1; - for (idx_col = 0; idx_col < 3; ++idx_col) { - int nb_col = col + idx_col - 1; - if (nb_row < 0 || nb_col < 0 || nb_row >= rows || nb_col >= cols) { - avg_nb_mv.row += (tmp_mv.row) * filter[idx_row][idx_col]; - avg_nb_mv.col += (tmp_mv.col) * filter[idx_row][idx_col]; - } else { - const FloatMV nb_mv = tmp_mf[nb_row * cols + nb_col]; - avg_nb_mv.row += (nb_mv.row) * filter[idx_row][idx_col]; - avg_nb_mv.col += (nb_mv.col) * filter[idx_row][idx_col]; - } - } - } - { - // M is the local variance of reference frame - float M00 = M[row * cols + col][0]; - float M01 = M[row * cols + col][1]; - float M10 = M[row * cols + col][2]; - float M11 = M[row * cols + col][3]; - - float det = (M00 + alpha) * (M11 + alpha) - M01 * M10; - - float inv_M00 = (M11 + alpha) / det; - float inv_M01 = -M01 / det; - float inv_M10 = -M10 / det; - float inv_M11 = (M00 + alpha) / det; - - float inv_MM00 = inv_M00 * M00 + inv_M01 * M10; - float inv_MM01 = inv_M00 * M01 + inv_M01 * M11; - float inv_MM10 = inv_M10 * M00 + inv_M11 * M10; - float inv_MM11 = inv_M10 * M01 + inv_M11 * M11; - - mv.row = inv_M00 * avg_nb_mv.row * alpha + inv_M01 * avg_nb_mv.col * alpha + - inv_MM00 * scaled_search_mv.row + inv_MM01 * scaled_search_mv.col; - mv.col = inv_M10 * avg_nb_mv.row * alpha + inv_M11 * avg_nb_mv.col * alpha + - inv_MM10 * scaled_search_mv.row + inv_MM11 * scaled_search_mv.col; - } - return mv; -} - -void vp9_get_smooth_motion_field(const MV *search_mf, - const int (*M)[MF_LOCAL_STRUCTURE_SIZE], - int rows, int cols, BLOCK_SIZE bsize, - float alpha, int num_iters, MV *smooth_mf) { - // M is the local variation of reference frame - // build two buffers - FloatMV *input = (FloatMV *)malloc(rows * cols * sizeof(FloatMV)); - FloatMV *output = (FloatMV *)malloc(rows * cols * sizeof(FloatMV)); - int idx; - int row, col; - int bw = 4 << b_width_log2_lookup[bsize]; - int bh = 4 << b_height_log2_lookup[bsize]; - if (!(input && output)) goto fail; - // copy search results to input buffer - for (idx = 0; idx < rows * cols; ++idx) { - input[idx].row = (float)search_mf[idx].row / bh; - input[idx].col = (float)search_mf[idx].col / bw; - } - for (idx = 0; idx < num_iters; ++idx) { - FloatMV *tmp; - for (row = 0; row < rows; ++row) { - for (col = 0; col < cols; ++col) { - // note: the scaled_search_mf and smooth_mf are all scaled by macroblock - // size - const MV search_mv = search_mf[row * cols + col]; - FloatMV scaled_search_mv = { (float)search_mv.row / bh, - (float)search_mv.col / bw }; - output[row * cols + col] = get_smooth_motion_vector( - scaled_search_mv, input, M, rows, cols, row, col, alpha); - } - } - // swap buffers - tmp = input; - input = output; - output = tmp; - } - // copy smoothed results to output - for (idx = 0; idx < rows * cols; ++idx) { - smooth_mf[idx].row = (int)(input[idx].row * bh); - smooth_mf[idx].col = (int)(input[idx].col * bw); - } -fail: - free(input); - free(output); -} - -void vp9_get_local_structure(const YV12_BUFFER_CONFIG *cur_frame, - const YV12_BUFFER_CONFIG *ref_frame, - const MV *search_mf, - const vp9_variance_fn_ptr_t *fn_ptr, int rows, - int cols, BLOCK_SIZE bsize, - int (*M)[MF_LOCAL_STRUCTURE_SIZE]) { - const int bw = 4 << b_width_log2_lookup[bsize]; - const int bh = 4 << b_height_log2_lookup[bsize]; - const int cur_stride = cur_frame->y_stride; - const int ref_stride = ref_frame->y_stride; - const int width = ref_frame->y_width; - const int height = ref_frame->y_height; - int row, col; - for (row = 0; row < rows; ++row) { - for (col = 0; col < cols; ++col) { - int cur_offset = row * bh * cur_stride + col * bw; - uint8_t *center = cur_frame->y_buffer + cur_offset; - int ref_h = row * bh + search_mf[row * cols + col].row; - int ref_w = col * bw + search_mf[row * cols + col].col; - int ref_offset; - uint8_t *target; - uint8_t *nb; - int search_dist; - int nb_dist; - int I_row = 0, I_col = 0; - // TODO(Dan): handle the case that when reference frame block beyond the - // boundary - ref_h = ref_h < 0 ? 0 : (ref_h >= height - bh ? height - bh - 1 : ref_h); - ref_w = ref_w < 0 ? 0 : (ref_w >= width - bw ? width - bw - 1 : ref_w); - // compute search results distortion - // TODO(Dan): maybe need to use vp9 function to find the reference block, - // to compare with the results of my python code, I first use my way to - // compute the reference block - ref_offset = ref_h * ref_stride + ref_w; - target = ref_frame->y_buffer + ref_offset; - search_dist = fn_ptr->sdf(center, cur_stride, target, ref_stride); - // compute target's neighbors' distortions - // TODO(Dan): if using padding, the boundary condition may vary - // up - if (ref_h - bh >= 0) { - nb = target - ref_stride * bh; - nb_dist = fn_ptr->sdf(center, cur_stride, nb, ref_stride); - I_row += nb_dist - search_dist; - } - // down - if (ref_h + bh < height - bh) { - nb = target + ref_stride * bh; - nb_dist = fn_ptr->sdf(center, cur_stride, nb, ref_stride); - I_row += nb_dist - search_dist; - } - if (ref_h - bh >= 0 && ref_h + bh < height - bh) { - I_row /= 2; - } - I_row /= (bw * bh); - // left - if (ref_w - bw >= 0) { - nb = target - bw; - nb_dist = fn_ptr->sdf(center, cur_stride, nb, ref_stride); - I_col += nb_dist - search_dist; - } - // down - if (ref_w + bw < width - bw) { - nb = target + bw; - nb_dist = fn_ptr->sdf(center, cur_stride, nb, ref_stride); - I_col += nb_dist - search_dist; - } - if (ref_w - bw >= 0 && ref_w + bw < width - bw) { - I_col /= 2; - } - I_col /= (bw * bh); - M[row * cols + col][0] = I_row * I_row; - M[row * cols + col][1] = I_row * I_col; - M[row * cols + col][2] = I_col * I_row; - M[row * cols + col][3] = I_col * I_col; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_non_greedy_mv.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_non_greedy_mv.h deleted file mode 100644 index c2bd6972..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_non_greedy_mv.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2019 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_NON_GREEDY_MV_H_ -#define VPX_VP9_ENCODER_VP9_NON_GREEDY_MV_H_ - -#include "vp9/common/vp9_enums.h" -#include "vp9/common/vp9_blockd.h" -#include "vpx_scale/yv12config.h" -#include "vpx_dsp/variance.h" - -#ifdef __cplusplus -extern "C" { -#endif -#define NB_MVS_NUM 4 -#define LOG2_PRECISION 20 -#define MF_LOCAL_STRUCTURE_SIZE 4 -#define SQUARE_BLOCK_SIZES 4 - -typedef enum Status { STATUS_OK = 0, STATUS_FAILED = 1 } Status; - -typedef struct MotionField { - int ready; - BLOCK_SIZE bsize; - int block_rows; - int block_cols; - int block_num; // block_num == block_rows * block_cols - int (*local_structure)[MF_LOCAL_STRUCTURE_SIZE]; - int_mv *mf; - int *set_mv; - int mv_log_scale; -} MotionField; - -typedef struct MotionFieldInfo { - int frame_num; - int allocated; - MotionField (*motion_field_array)[MAX_INTER_REF_FRAMES][SQUARE_BLOCK_SIZES]; -} MotionFieldInfo; - -typedef struct { - float row, col; -} FloatMV; - -static INLINE int get_square_block_idx(BLOCK_SIZE bsize) { - if (bsize == BLOCK_4X4) { - return 0; - } - if (bsize == BLOCK_8X8) { - return 1; - } - if (bsize == BLOCK_16X16) { - return 2; - } - if (bsize == BLOCK_32X32) { - return 3; - } - assert(0 && "ERROR: non-square block size"); - return -1; -} - -static INLINE BLOCK_SIZE square_block_idx_to_bsize(int square_block_idx) { - if (square_block_idx == 0) { - return BLOCK_4X4; - } - if (square_block_idx == 1) { - return BLOCK_8X8; - } - if (square_block_idx == 2) { - return BLOCK_16X16; - } - if (square_block_idx == 3) { - return BLOCK_32X32; - } - assert(0 && "ERROR: invalid square_block_idx"); - return BLOCK_INVALID; -} - -Status vp9_alloc_motion_field_info(MotionFieldInfo *motion_field_info, - int frame_num, int mi_rows, int mi_cols); - -Status vp9_alloc_motion_field(MotionField *motion_field, BLOCK_SIZE bsize, - int block_rows, int block_cols); - -void vp9_free_motion_field(MotionField *motion_field); - -void vp9_free_motion_field_info(MotionFieldInfo *motion_field_info); - -int64_t vp9_nb_mvs_inconsistency(const MV *mv, const int_mv *nb_full_mvs, - int mv_num); - -void vp9_get_smooth_motion_field(const MV *search_mf, - const int (*M)[MF_LOCAL_STRUCTURE_SIZE], - int rows, int cols, BLOCK_SIZE bize, - float alpha, int num_iters, MV *smooth_mf); - -void vp9_get_local_structure(const YV12_BUFFER_CONFIG *cur_frame, - const YV12_BUFFER_CONFIG *ref_frame, - const MV *search_mf, - const vp9_variance_fn_ptr_t *fn_ptr, int rows, - int cols, BLOCK_SIZE bsize, - int (*M)[MF_LOCAL_STRUCTURE_SIZE]); - -MotionField *vp9_motion_field_info_get_motion_field( - MotionFieldInfo *motion_field_info, int frame_idx, int rf_idx, - BLOCK_SIZE bsize); - -void vp9_motion_field_mi_set_mv(MotionField *motion_field, int mi_row, - int mi_col, int_mv mv); - -void vp9_motion_field_reset_mvs(MotionField *motion_field); - -int_mv vp9_motion_field_get_mv(const MotionField *motion_field, int brow, - int bcol); -int_mv vp9_motion_field_mi_get_mv(const MotionField *motion_field, int mi_row, - int mi_col); -int vp9_motion_field_is_mv_set(const MotionField *motion_field, int brow, - int bcol); - -#ifdef __cplusplus -} // extern "C" -#endif -#endif // VPX_VP9_ENCODER_VP9_NON_GREEDY_MV_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_partition_models.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_partition_models.h deleted file mode 100644 index 09c0e30a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_partition_models.h +++ /dev/null @@ -1,975 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_PARTITION_MODELS_H_ -#define VPX_VP9_ENCODER_VP9_PARTITION_MODELS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define NN_MAX_HIDDEN_LAYERS 10 -#define NN_MAX_NODES_PER_LAYER 128 - -// Neural net model config. It defines the layout of a neural net model, such as -// the number of inputs/outputs, number of layers, the number of nodes in each -// layer, as well as the weights and bias of each node. -typedef struct { - int num_inputs; // Number of input nodes, i.e. features. - int num_outputs; // Number of output nodes. - int num_hidden_layers; // Number of hidden layers, maximum 10. - // Number of nodes for each hidden layer. - int num_hidden_nodes[NN_MAX_HIDDEN_LAYERS]; - // Weight parameters, indexed by layer. - const float *weights[NN_MAX_HIDDEN_LAYERS + 1]; - // Bias parameters, indexed by layer. - const float *bias[NN_MAX_HIDDEN_LAYERS + 1]; -} NN_CONFIG; - -// Partition search breakout model. -#define FEATURES 4 -#define Q_CTX 3 -#define RESOLUTION_CTX 2 -static const float - vp9_partition_breakout_weights_64[RESOLUTION_CTX][Q_CTX][FEATURES + 1] = { - { - { - -0.016673f, - -0.001025f, - -0.000032f, - 0.000833f, - 1.94261885f - 2.1f, - }, - { - -0.160867f, - -0.002101f, - 0.000011f, - 0.002448f, - 1.65738142f - 2.5f, - }, - { - -0.628934f, - -0.011459f, - -0.000009f, - 0.013833f, - 1.47982645f - 1.6f, - }, - }, - { - { - -0.064309f, - -0.006121f, - 0.000232f, - 0.005778f, - 0.7989465f - 5.0f, - }, - { - -0.314957f, - -0.009346f, - -0.000225f, - 0.010072f, - 2.80695581f - 5.5f, - }, - { - -0.635535f, - -0.015135f, - 0.000091f, - 0.015247f, - 2.90381241f - 5.0f, - }, - }, - }; - -static const float - vp9_partition_breakout_weights_32[RESOLUTION_CTX][Q_CTX][FEATURES + 1] = { - { - { - -0.010554f, - -0.003081f, - -0.000134f, - 0.004491f, - 1.68445992f - 3.5f, - }, - { - -0.051489f, - -0.007609f, - 0.000016f, - 0.009792f, - 1.28089404f - 2.5f, - }, - { - -0.163097f, - -0.013081f, - 0.000022f, - 0.019006f, - 1.36129403f - 3.2f, - }, - }, - { - { - -0.024629f, - -0.006492f, - -0.000254f, - 0.004895f, - 1.27919173f - 4.5f, - }, - { - -0.083936f, - -0.009827f, - -0.000200f, - 0.010399f, - 2.73731065f - 4.5f, - }, - { - -0.279052f, - -0.013334f, - 0.000289f, - 0.023203f, - 2.43595719f - 3.5f, - }, - }, - }; - -static const float - vp9_partition_breakout_weights_16[RESOLUTION_CTX][Q_CTX][FEATURES + 1] = { - { - { - -0.013154f, - -0.002404f, - -0.000977f, - 0.008450f, - 2.57404566f - 5.5f, - }, - { - -0.019146f, - -0.004018f, - 0.000064f, - 0.008187f, - 2.15043926f - 2.5f, - }, - { - -0.075755f, - -0.010858f, - 0.000030f, - 0.024505f, - 2.06848121f - 2.5f, - }, - }, - { - { - -0.007636f, - -0.002751f, - -0.000682f, - 0.005968f, - 0.19225763f - 4.5f, - }, - { - -0.047306f, - -0.009113f, - -0.000518f, - 0.016007f, - 2.61068869f - 4.0f, - }, - { - -0.069336f, - -0.010448f, - -0.001120f, - 0.023083f, - 1.47591054f - 5.5f, - }, - }, - }; - -static const float vp9_partition_breakout_weights_8[RESOLUTION_CTX][Q_CTX] - [FEATURES + 1] = { - { - { - -0.011807f, - -0.009873f, - -0.000931f, - 0.034768f, - 1.32254851f - 2.0f, - }, - { - -0.003861f, - -0.002701f, - 0.000100f, - 0.013876f, - 1.96755111f - 1.5f, - }, - { - -0.013522f, - -0.008677f, - -0.000562f, - 0.034468f, - 1.53440356f - 1.5f, - }, - }, - { - { - -0.003221f, - -0.002125f, - 0.000993f, - 0.012768f, - 0.03541421f - 2.0f, - }, - { - -0.006069f, - -0.007335f, - 0.000229f, - 0.026104f, - 0.17135315f - 1.5f, - }, - { - -0.039894f, - -0.011419f, - 0.000070f, - 0.061817f, - 0.6739977f - 1.5f, - }, - }, - }; -#undef FEATURES -#undef Q_CTX -#undef RESOLUTION_CTX - -// Rectangular partition search pruning model. -#define FEATURES 8 -#define LABELS 4 -#define NODES 16 -static const float vp9_rect_part_nn_weights_16_layer0[FEATURES * NODES] = { - -0.432522f, 0.133070f, -0.169187f, 0.768340f, 0.891228f, 0.554458f, - 0.356000f, 0.403621f, 0.809165f, 0.778214f, -0.520357f, 0.301451f, - -0.386972f, -0.314402f, 0.021878f, 1.148746f, -0.462258f, -0.175524f, - -0.344589f, -0.475159f, -0.232322f, 0.471147f, -0.489948f, 0.467740f, - -0.391550f, 0.208601f, 0.054138f, 0.076859f, -0.309497f, -0.095927f, - 0.225917f, 0.011582f, -0.520730f, -0.585497f, 0.174036f, 0.072521f, - 0.120771f, -0.517234f, -0.581908f, -0.034003f, -0.694722f, -0.364368f, - 0.290584f, 0.038373f, 0.685654f, 0.394019f, 0.759667f, 1.257502f, - -0.610516f, -0.185434f, 0.211997f, -0.172458f, 0.044605f, 0.145316f, - -0.182525f, -0.147376f, 0.578742f, 0.312412f, -0.446135f, -0.389112f, - 0.454033f, 0.260490f, 0.664285f, 0.395856f, -0.231827f, 0.215228f, - 0.014856f, -0.395462f, 0.479646f, -0.391445f, -0.357788f, 0.166238f, - -0.056818f, -0.027783f, 0.060880f, -1.604710f, 0.531268f, 0.282184f, - 0.714944f, 0.093523f, -0.218312f, -0.095546f, -0.285621f, -0.190871f, - -0.448340f, -0.016611f, 0.413913f, -0.286720f, -0.158828f, -0.092635f, - -0.279551f, 0.166509f, -0.088162f, 0.446543f, -0.276830f, -0.065642f, - -0.176346f, -0.984754f, 0.338738f, 0.403809f, 0.738065f, 1.154439f, - 0.750764f, 0.770959f, -0.269403f, 0.295651f, -0.331858f, 0.367144f, - 0.279279f, 0.157419f, -0.348227f, -0.168608f, -0.956000f, -0.647136f, - 0.250516f, 0.858084f, 0.809802f, 0.492408f, 0.804841f, 0.282802f, - 0.079395f, -0.291771f, -0.024382f, -1.615880f, -0.445166f, -0.407335f, - -0.483044f, 0.141126f, -}; - -static const float vp9_rect_part_nn_bias_16_layer0[NODES] = { - 0.275384f, -0.053745f, 0.000000f, 0.000000f, -0.178103f, 0.513965f, - -0.161352f, 0.228551f, 0.000000f, 1.013712f, 0.000000f, 0.000000f, - -1.144009f, -0.000006f, -0.241727f, 2.048764f, -}; - -static const float vp9_rect_part_nn_weights_16_layer1[NODES * LABELS] = { - -1.435278f, 2.204691f, -0.410718f, 0.202708f, 0.109208f, 1.059142f, - -0.306360f, 0.845906f, 0.489654f, -1.121915f, -0.169133f, -0.003385f, - 0.660590f, -0.018711f, 1.227158f, -2.967504f, 1.407345f, -1.293243f, - -0.386921f, 0.300492f, 0.338824f, -0.083250f, -0.069454f, -1.001827f, - -0.327891f, 0.899353f, 0.367397f, -0.118601f, -0.171936f, -0.420646f, - -0.803319f, 2.029634f, 0.940268f, -0.664484f, 0.339916f, 0.315944f, - 0.157374f, -0.402482f, -0.491695f, 0.595827f, 0.015031f, 0.255887f, - -0.466327f, -0.212598f, 0.136485f, 0.033363f, -0.796921f, 1.414304f, - -0.282185f, -2.673571f, -0.280994f, 0.382658f, -0.350902f, 0.227926f, - 0.062602f, -1.000199f, 0.433731f, 1.176439f, -0.163216f, -0.229015f, - -0.640098f, -0.438852f, -0.947700f, 2.203434f, -}; - -static const float vp9_rect_part_nn_bias_16_layer1[LABELS] = { - -0.875510f, - 0.982408f, - 0.560854f, - -0.415209f, -}; - -static const NN_CONFIG vp9_rect_part_nnconfig_16 = { - FEATURES, // num_inputs - LABELS, // num_outputs - 1, // num_hidden_layers - { - NODES, - }, // num_hidden_nodes - { - vp9_rect_part_nn_weights_16_layer0, - vp9_rect_part_nn_weights_16_layer1, - }, - { - vp9_rect_part_nn_bias_16_layer0, - vp9_rect_part_nn_bias_16_layer1, - }, -}; - -static const float vp9_rect_part_nn_weights_32_layer0[FEATURES * NODES] = { - -0.147312f, -0.753248f, 0.540206f, 0.661415f, 0.484117f, -0.341609f, - 0.016183f, 0.064177f, 0.781580f, 0.902232f, -0.505342f, 0.325183f, - -0.231072f, -0.120107f, -0.076216f, 0.120038f, 0.403695f, -0.463301f, - -0.192158f, 0.407442f, 0.106633f, 1.072371f, -0.446779f, 0.467353f, - 0.318812f, -0.505996f, -0.008768f, -0.239598f, 0.085480f, 0.284640f, - -0.365045f, -0.048083f, -0.112090f, -0.067089f, 0.304138f, -0.228809f, - 0.383651f, -0.196882f, 0.477039f, -0.217978f, -0.506931f, -0.125675f, - 0.050456f, 1.086598f, 0.732128f, 0.326941f, 0.103952f, 0.121769f, - -0.154487f, -0.255514f, 0.030591f, -0.382797f, -0.019981f, -0.326570f, - 0.149691f, -0.435633f, -0.070795f, 0.167691f, 0.251413f, -0.153405f, - 0.160347f, 0.455107f, -0.968580f, -0.575879f, 0.623115f, -0.069793f, - -0.379768f, -0.965807f, -0.062057f, 0.071312f, 0.457098f, 0.350372f, - -0.460659f, -0.985393f, 0.359963f, -0.093677f, 0.404272f, -0.326896f, - -0.277752f, 0.609322f, -0.114193f, -0.230701f, 0.089208f, 0.645381f, - 0.494485f, 0.467876f, -0.166187f, 0.251044f, -0.394661f, 0.192895f, - -0.344777f, -0.041893f, -0.111163f, 0.066347f, 0.378158f, -0.455465f, - 0.339839f, -0.418207f, -0.356515f, -0.227536f, -0.211091f, -0.122945f, - 0.361772f, -0.338095f, 0.004564f, -0.398510f, 0.060876f, -2.132504f, - -0.086776f, -0.029166f, 0.039241f, 0.222534f, -0.188565f, -0.288792f, - -0.160789f, -0.123905f, 0.397916f, -0.063779f, 0.167210f, -0.445004f, - 0.056889f, 0.207280f, 0.000101f, 0.384507f, -1.721239f, -2.036402f, - -2.084403f, -2.060483f, -}; - -static const float vp9_rect_part_nn_bias_32_layer0[NODES] = { - -0.859251f, -0.109938f, 0.091838f, 0.187817f, -0.728265f, 0.253080f, - 0.000000f, -0.357195f, -0.031290f, -1.373237f, -0.761086f, 0.000000f, - -0.024504f, 1.765711f, 0.000000f, 1.505390f, -}; - -static const float vp9_rect_part_nn_weights_32_layer1[NODES * LABELS] = { - 0.680940f, 1.367178f, 0.403075f, 0.029957f, 0.500917f, 1.407776f, - -0.354002f, 0.011667f, 1.663767f, 0.959155f, 0.428323f, -0.205345f, - -0.081850f, -3.920103f, -0.243802f, -4.253933f, -0.034020f, -1.361057f, - 0.128236f, -0.138422f, -0.025790f, -0.563518f, -0.148715f, -0.344381f, - -1.677389f, -0.868332f, -0.063792f, 0.052052f, 0.359591f, 2.739808f, - -0.414304f, 3.036597f, -0.075368f, -1.019680f, 0.642501f, 0.209779f, - -0.374539f, -0.718294f, -0.116616f, -0.043212f, -1.787809f, -0.773262f, - 0.068734f, 0.508309f, 0.099334f, 1.802239f, -0.333538f, 2.708645f, - -0.447682f, -2.355555f, -0.506674f, -0.061028f, -0.310305f, -0.375475f, - 0.194572f, 0.431788f, -0.789624f, -0.031962f, 0.358353f, 0.382937f, - 0.232002f, 2.321813f, -0.037523f, 2.104652f, -}; - -static const float vp9_rect_part_nn_bias_32_layer1[LABELS] = { - -0.693383f, - 0.773661f, - 0.426878f, - -0.070619f, -}; - -static const NN_CONFIG vp9_rect_part_nnconfig_32 = { - FEATURES, // num_inputs - LABELS, // num_outputs - 1, // num_hidden_layers - { - NODES, - }, // num_hidden_nodes - { - vp9_rect_part_nn_weights_32_layer0, - vp9_rect_part_nn_weights_32_layer1, - }, - { - vp9_rect_part_nn_bias_32_layer0, - vp9_rect_part_nn_bias_32_layer1, - }, -}; -#undef NODES - -#define NODES 24 -static const float vp9_rect_part_nn_weights_64_layer0[FEATURES * NODES] = { - 0.024671f, -0.220610f, -0.284362f, -0.069556f, -0.315700f, 0.187861f, - 0.139782f, 0.063110f, 0.796561f, 0.172868f, -0.662194f, -1.393074f, - 0.085003f, 0.393381f, 0.358477f, -0.187268f, -0.370745f, 0.218287f, - 0.027271f, -0.254089f, -0.048236f, -0.459137f, 0.253171f, 0.122598f, - -0.550107f, -0.568456f, 0.159866f, -0.246534f, 0.096384f, -0.255460f, - 0.077864f, -0.334837f, 0.026921f, -0.697252f, 0.345262f, 1.343578f, - 0.815984f, 1.118211f, 1.574016f, 0.578476f, -0.285967f, -0.508672f, - 0.118137f, 0.037695f, 1.540510f, 1.256648f, 1.163819f, 1.172027f, - 0.661551f, -0.111980f, -0.434204f, -0.894217f, 0.570524f, 0.050292f, - -0.113680f, 0.000784f, -0.211554f, -0.369394f, 0.158306f, -0.512505f, - -0.238696f, 0.091498f, -0.448490f, -0.491268f, -0.353112f, -0.303315f, - -0.428438f, 0.127998f, -0.406790f, -0.401786f, -0.279888f, -0.384223f, - 0.026100f, 0.041621f, -0.315818f, -0.087888f, 0.353497f, 0.163123f, - -0.380128f, -0.090334f, -0.216647f, -0.117849f, -0.173502f, 0.301871f, - 0.070854f, 0.114627f, -0.050545f, -0.160381f, 0.595294f, 0.492696f, - -0.453858f, -1.154139f, 0.126000f, 0.034550f, 0.456665f, -0.236618f, - -0.112640f, 0.050759f, -0.449162f, 0.110059f, 0.147116f, 0.249358f, - -0.049894f, 0.063351f, -0.004467f, 0.057242f, -0.482015f, -0.174335f, - -0.085617f, -0.333808f, -0.358440f, -0.069006f, 0.099260f, -1.243430f, - -0.052963f, 0.112088f, -2.661115f, -2.445893f, -2.688174f, -2.624232f, - 0.030494f, 0.161311f, 0.012136f, 0.207564f, -2.776856f, -2.791940f, - -2.623962f, -2.918820f, 1.231619f, -0.376692f, -0.698078f, 0.110336f, - -0.285378f, 0.258367f, -0.180159f, -0.376608f, -0.034348f, -0.130206f, - 0.160020f, 0.852977f, 0.580573f, 1.450782f, 1.357596f, 0.787382f, - -0.544004f, -0.014795f, 0.032121f, -0.557696f, 0.159994f, -0.540908f, - 0.180380f, -0.398045f, 0.705095f, 0.515103f, -0.511521f, -1.271374f, - -0.231019f, 0.423647f, 0.064907f, -0.255338f, -0.877748f, -0.667205f, - 0.267847f, 0.135229f, 0.617844f, 1.349849f, 1.012623f, 0.730506f, - -0.078571f, 0.058401f, 0.053221f, -2.426146f, -0.098808f, -0.138508f, - -0.153299f, 0.149116f, -0.444243f, 0.301807f, 0.065066f, 0.092929f, - -0.372784f, -0.095540f, 0.192269f, 0.237894f, 0.080228f, -0.214074f, - -0.011426f, -2.352367f, -0.085394f, -0.190361f, -0.001177f, 0.089197f, -}; - -static const float vp9_rect_part_nn_bias_64_layer0[NODES] = { - 0.000000f, -0.057652f, -0.175413f, -0.175389f, -1.084097f, -1.423801f, - -0.076307f, -0.193803f, 0.000000f, -0.066474f, -0.050318f, -0.019832f, - -0.038814f, -0.144184f, 2.652451f, 2.415006f, 0.197464f, -0.729842f, - -0.173774f, 0.239171f, 0.486425f, 2.463304f, -0.175279f, 2.352637f, -}; - -static const float vp9_rect_part_nn_weights_64_layer1[NODES * LABELS] = { - -0.063237f, 1.925696f, -0.182145f, -0.226687f, 0.602941f, -0.941140f, - 0.814598f, -0.117063f, 0.282988f, 0.066369f, 0.096951f, 1.049735f, - -0.188188f, -0.281227f, -4.836746f, -5.047797f, 0.892358f, 0.417145f, - -0.279849f, 1.335945f, 0.660338f, -2.757938f, -0.115714f, -1.862183f, - -0.045980f, -1.597624f, -0.586822f, -0.615589f, -0.330537f, 1.068496f, - -0.167290f, 0.141290f, -0.112100f, 0.232761f, 0.252307f, -0.399653f, - 0.353118f, 0.241583f, 2.635241f, 4.026119f, -1.137327f, -0.052446f, - -0.139814f, -1.104256f, -0.759391f, 2.508457f, -0.526297f, 2.095348f, - -0.444473f, -1.090452f, 0.584122f, 0.468729f, -0.368865f, 1.041425f, - -1.079504f, 0.348837f, 0.390091f, 0.416191f, 0.212906f, -0.660255f, - 0.053630f, 0.209476f, 3.595525f, 2.257293f, -0.514030f, 0.074203f, - -0.375862f, -1.998307f, -0.930310f, 1.866686f, -0.247137f, 1.087789f, - 0.100186f, 0.298150f, 0.165265f, 0.050478f, 0.249167f, 0.371789f, - -0.294497f, 0.202954f, 0.037310f, 0.193159f, 0.161551f, 0.301597f, - 0.299286f, 0.185946f, 0.822976f, 2.066130f, -1.724588f, 0.055977f, - -0.330747f, -0.067747f, -0.475801f, 1.555958f, -0.025808f, -0.081516f, -}; - -static const float vp9_rect_part_nn_bias_64_layer1[LABELS] = { - -0.090723f, - 0.894968f, - 0.844754f, - -3.496194f, -}; - -static const NN_CONFIG vp9_rect_part_nnconfig_64 = { - FEATURES, // num_inputs - LABELS, // num_outputs - 1, // num_hidden_layers - { - NODES, - }, // num_hidden_nodes - { - vp9_rect_part_nn_weights_64_layer0, - vp9_rect_part_nn_weights_64_layer1, - }, - { - vp9_rect_part_nn_bias_64_layer0, - vp9_rect_part_nn_bias_64_layer1, - }, -}; -#undef FEATURES -#undef LABELS -#undef NODES - -#define FEATURES 7 -// Partition pruning model(neural nets). -static const float vp9_partition_nn_weights_64x64_layer0[FEATURES * 8] = { - -3.571348f, 0.014835f, -3.255393f, -0.098090f, -0.013120f, 0.000221f, - 0.056273f, 0.190179f, -0.268130f, -1.828242f, -0.010655f, 0.937244f, - -0.435120f, 0.512125f, 1.610679f, 0.190816f, -0.799075f, -0.377348f, - -0.144232f, 0.614383f, -0.980388f, 1.754150f, -0.185603f, -0.061854f, - -0.807172f, 1.240177f, 1.419531f, -0.438544f, -5.980774f, 0.139045f, - -0.032359f, -0.068887f, -1.237918f, 0.115706f, 0.003164f, 2.924212f, - 1.246838f, -0.035833f, 0.810011f, -0.805894f, 0.010966f, 0.076463f, - -4.226380f, -2.437764f, -0.010619f, -0.020935f, -0.451494f, 0.300079f, - -0.168961f, -3.326450f, -2.731094f, 0.002518f, 0.018840f, -1.656815f, - 0.068039f, 0.010586f, -}; - -static const float vp9_partition_nn_bias_64x64_layer0[8] = { - -3.469882f, 0.683989f, 0.194010f, 0.313782f, - -3.153335f, 2.245849f, -1.946190f, -3.740020f, -}; - -static const float vp9_partition_nn_weights_64x64_layer1[8] = { - -8.058566f, 0.108306f, -0.280620f, -0.818823f, - -6.445117f, 0.865364f, -1.127127f, -8.808660f, -}; - -static const float vp9_partition_nn_bias_64x64_layer1[1] = { - 6.46909416f, -}; - -static const NN_CONFIG vp9_partition_nnconfig_64x64 = { - FEATURES, // num_inputs - 1, // num_outputs - 1, // num_hidden_layers - { - 8, - }, // num_hidden_nodes - { - vp9_partition_nn_weights_64x64_layer0, - vp9_partition_nn_weights_64x64_layer1, - }, - { - vp9_partition_nn_bias_64x64_layer0, - vp9_partition_nn_bias_64x64_layer1, - }, -}; - -static const float vp9_partition_nn_weights_32x32_layer0[FEATURES * 8] = { - -0.295437f, -4.002648f, -0.205399f, -0.060919f, 0.708037f, 0.027221f, - -0.039137f, -0.907724f, -3.151662f, 0.007106f, 0.018726f, -0.534928f, - 0.022744f, 0.000159f, -1.717189f, -3.229031f, -0.027311f, 0.269863f, - -0.400747f, -0.394366f, -0.108878f, 0.603027f, 0.455369f, -0.197170f, - 1.241746f, -1.347820f, -0.575636f, -0.462879f, -2.296426f, 0.196696f, - -0.138347f, -0.030754f, -0.200774f, 0.453795f, 0.055625f, -3.163116f, - -0.091003f, -0.027028f, -0.042984f, -0.605185f, 0.143240f, -0.036439f, - -0.801228f, 0.313409f, -0.159942f, 0.031267f, 0.886454f, -1.531644f, - -0.089655f, 0.037683f, -0.163441f, -0.130454f, -0.058344f, 0.060011f, - 0.275387f, 1.552226f, -}; - -static const float vp9_partition_nn_bias_32x32_layer0[8] = { - -0.838372f, -2.609089f, -0.055763f, 1.329485f, - -1.297638f, -2.636622f, -0.826909f, 1.012644f, -}; - -static const float vp9_partition_nn_weights_32x32_layer1[8] = { - -1.792632f, -7.322353f, -0.683386f, 0.676564f, - -1.488118f, -7.527719f, 1.240163f, 0.614309f, -}; - -static const float vp9_partition_nn_bias_32x32_layer1[1] = { - 4.97422546f, -}; - -static const NN_CONFIG vp9_partition_nnconfig_32x32 = { - FEATURES, // num_inputs - 1, // num_outputs - 1, // num_hidden_layers - { - 8, - }, // num_hidden_nodes - { - vp9_partition_nn_weights_32x32_layer0, - vp9_partition_nn_weights_32x32_layer1, - }, - { - vp9_partition_nn_bias_32x32_layer0, - vp9_partition_nn_bias_32x32_layer1, - }, -}; - -static const float vp9_partition_nn_weights_16x16_layer0[FEATURES * 8] = { - -1.717673f, -4.718130f, -0.125725f, -0.183427f, -0.511764f, 0.035328f, - 0.130891f, -3.096753f, 0.174968f, -0.188769f, -0.640796f, 1.305661f, - 1.700638f, -0.073806f, -4.006781f, -1.630999f, -0.064863f, -0.086410f, - -0.148617f, 0.172733f, -0.018619f, 2.152595f, 0.778405f, -0.156455f, - 0.612995f, -0.467878f, 0.152022f, -0.236183f, 0.339635f, -0.087119f, - -3.196610f, -1.080401f, -0.637704f, -0.059974f, 1.706298f, -0.793705f, - -6.399260f, 0.010624f, -0.064199f, -0.650621f, 0.338087f, -0.001531f, - 1.023655f, -3.700272f, -0.055281f, -0.386884f, 0.375504f, -0.898678f, - 0.281156f, -0.314611f, 0.863354f, -0.040582f, -0.145019f, 0.029329f, - -2.197880f, -0.108733f, -}; - -static const float vp9_partition_nn_bias_16x16_layer0[8] = { - 0.411516f, -2.143737f, -3.693192f, 2.123142f, - -1.356910f, -3.561016f, -0.765045f, -2.417082f, -}; - -static const float vp9_partition_nn_weights_16x16_layer1[8] = { - -0.619755f, -2.202391f, -4.337171f, 0.611319f, - 0.377677f, -4.998723f, -1.052235f, 1.949922f, -}; - -static const float vp9_partition_nn_bias_16x16_layer1[1] = { - 3.20981717f, -}; - -static const NN_CONFIG vp9_partition_nnconfig_16x16 = { - FEATURES, // num_inputs - 1, // num_outputs - 1, // num_hidden_layers - { - 8, - }, // num_hidden_nodes - { - vp9_partition_nn_weights_16x16_layer0, - vp9_partition_nn_weights_16x16_layer1, - }, - { - vp9_partition_nn_bias_16x16_layer0, - vp9_partition_nn_bias_16x16_layer1, - }, -}; -#undef FEATURES - -#define FEATURES 6 -static const float vp9_var_part_nn_weights_64_layer0[FEATURES * 8] = { - -0.249572f, 0.205532f, -2.175608f, 1.094836f, -2.986370f, 0.193160f, - -0.143823f, 0.378511f, -1.997788f, -2.166866f, -1.930158f, -1.202127f, - -0.611875f, -0.506422f, -0.432487f, 0.071205f, 0.578172f, -0.154285f, - -0.051830f, 0.331681f, -1.457177f, -2.443546f, -2.000302f, -1.389283f, - 0.372084f, -0.464917f, 2.265235f, 2.385787f, 2.312722f, 2.127868f, - -0.403963f, -0.177860f, -0.436751f, -0.560539f, 0.254903f, 0.193976f, - -0.305611f, 0.256632f, 0.309388f, -0.437439f, 1.702640f, -5.007069f, - -0.323450f, 0.294227f, 1.267193f, 1.056601f, 0.387181f, -0.191215f, -}; - -static const float vp9_var_part_nn_bias_64_layer0[8] = { - -0.044396f, -0.938166f, 0.000000f, -0.916375f, - 1.242299f, 0.000000f, -0.405734f, 0.014206f, -}; - -static const float vp9_var_part_nn_weights_64_layer1[8] = { - 1.635945f, 0.979557f, 0.455315f, 1.197199f, - -2.251024f, -0.464953f, 1.378676f, -0.111927f, -}; - -static const float vp9_var_part_nn_bias_64_layer1[1] = { - -0.37972447f, -}; - -static const NN_CONFIG vp9_var_part_nnconfig_64 = { - FEATURES, // num_inputs - 1, // num_outputs - 1, // num_hidden_layers - { - 8, - }, // num_hidden_nodes - { - vp9_var_part_nn_weights_64_layer0, - vp9_var_part_nn_weights_64_layer1, - }, - { - vp9_var_part_nn_bias_64_layer0, - vp9_var_part_nn_bias_64_layer1, - }, -}; - -static const float vp9_var_part_nn_weights_32_layer0[FEATURES * 8] = { - 0.067243f, -0.083598f, -2.191159f, 2.726434f, -3.324013f, 3.477977f, - 0.323736f, -0.510199f, 2.960693f, 2.937661f, 2.888476f, 2.938315f, - -0.307602f, -0.503353f, -0.080725f, -0.473909f, -0.417162f, 0.457089f, - 0.665153f, -0.273210f, 0.028279f, 0.972220f, -0.445596f, 1.756611f, - -0.177892f, -0.091758f, 0.436661f, -0.521506f, 0.133786f, 0.266743f, - 0.637367f, -0.160084f, -1.396269f, 1.020841f, -1.112971f, 0.919496f, - -0.235883f, 0.651954f, 0.109061f, -0.429463f, 0.740839f, -0.962060f, - 0.299519f, -0.386298f, 1.550231f, 2.464915f, 1.311969f, 2.561612f, -}; - -static const float vp9_var_part_nn_bias_32_layer0[8] = { - 0.368242f, 0.736617f, 0.000000f, 0.757287f, - 0.000000f, 0.613248f, -0.776390f, 0.928497f, -}; - -static const float vp9_var_part_nn_weights_32_layer1[8] = { - 0.939884f, -2.420850f, -0.410489f, -0.186690f, - 0.063287f, -0.522011f, 0.484527f, -0.639625f, -}; - -static const float vp9_var_part_nn_bias_32_layer1[1] = { - -0.6455006f, -}; - -static const NN_CONFIG vp9_var_part_nnconfig_32 = { - FEATURES, // num_inputs - 1, // num_outputs - 1, // num_hidden_layers - { - 8, - }, // num_hidden_nodes - { - vp9_var_part_nn_weights_32_layer0, - vp9_var_part_nn_weights_32_layer1, - }, - { - vp9_var_part_nn_bias_32_layer0, - vp9_var_part_nn_bias_32_layer1, - }, -}; - -static const float vp9_var_part_nn_weights_16_layer0[FEATURES * 8] = { - 0.742567f, -0.580624f, -0.244528f, 0.331661f, -0.113949f, -0.559295f, - -0.386061f, 0.438653f, 1.467463f, 0.211589f, 0.513972f, 1.067855f, - -0.876679f, 0.088560f, -0.687483f, -0.380304f, -0.016412f, 0.146380f, - 0.015318f, 0.000351f, -2.764887f, 3.269717f, 2.752428f, -2.236754f, - 0.561539f, -0.852050f, -0.084667f, 0.202057f, 0.197049f, 0.364922f, - -0.463801f, 0.431790f, 1.872096f, -0.091887f, -0.055034f, 2.443492f, - -0.156958f, -0.189571f, -0.542424f, -0.589804f, -0.354422f, 0.401605f, - 0.642021f, -0.875117f, 2.040794f, 1.921070f, 1.792413f, 1.839727f, -}; - -static const float vp9_var_part_nn_bias_16_layer0[8] = { - 2.901234f, -1.940932f, -0.198970f, -0.406524f, - 0.059422f, -1.879207f, -0.232340f, 2.979821f, -}; - -static const float vp9_var_part_nn_weights_16_layer1[8] = { - -0.528731f, 0.375234f, -0.088422f, 0.668629f, - 0.870449f, 0.578735f, 0.546103f, -1.957207f, -}; - -static const float vp9_var_part_nn_bias_16_layer1[1] = { - -1.95769405f, -}; - -static const NN_CONFIG vp9_var_part_nnconfig_16 = { - FEATURES, // num_inputs - 1, // num_outputs - 1, // num_hidden_layers - { - 8, - }, // num_hidden_nodes - { - vp9_var_part_nn_weights_16_layer0, - vp9_var_part_nn_weights_16_layer1, - }, - { - vp9_var_part_nn_bias_16_layer0, - vp9_var_part_nn_bias_16_layer1, - }, -}; -#undef FEATURES - -#define FEATURES 12 -#define LABELS 1 -#define NODES 8 -static const float vp9_part_split_nn_weights_64_layer0[FEATURES * NODES] = { - -0.609728f, -0.409099f, -0.472449f, 0.183769f, -0.457740f, 0.081089f, - 0.171003f, 0.578696f, -0.019043f, -0.856142f, 0.557369f, -1.779424f, - -0.274044f, -0.320632f, -0.392531f, -0.359462f, -0.404106f, -0.288357f, - 0.200620f, 0.038013f, -0.430093f, 0.235083f, -0.487442f, 0.424814f, - -0.232758f, -0.442943f, 0.229397f, -0.540301f, -0.648421f, -0.649747f, - -0.171638f, 0.603824f, 0.468497f, -0.421580f, 0.178840f, -0.533838f, - -0.029471f, -0.076296f, 0.197426f, -0.187908f, -0.003950f, -0.065740f, - 0.085165f, -0.039674f, -5.640702f, 1.909538f, -1.434604f, 3.294606f, - -0.788812f, 0.196864f, 0.057012f, -0.019757f, 0.336233f, 0.075378f, - 0.081503f, 0.491864f, -1.899470f, -1.764173f, -1.888137f, -1.762343f, - 0.845542f, 0.202285f, 0.381948f, -0.150996f, 0.556893f, -0.305354f, - 0.561482f, -0.021974f, -0.703117f, 0.268638f, -0.665736f, 1.191005f, - -0.081568f, -0.115653f, 0.272029f, -0.140074f, 0.072683f, 0.092651f, - -0.472287f, -0.055790f, -0.434425f, 0.352055f, 0.048246f, 0.372865f, - 0.111499f, -0.338304f, 0.739133f, 0.156519f, -0.594644f, 0.137295f, - 0.613350f, -0.165102f, -1.003731f, 0.043070f, -0.887896f, -0.174202f, -}; - -static const float vp9_part_split_nn_bias_64_layer0[NODES] = { - 1.182714f, 0.000000f, 0.902019f, 0.953115f, - -1.372486f, -1.288740f, -0.155144f, -3.041362f, -}; - -static const float vp9_part_split_nn_weights_64_layer1[NODES * LABELS] = { - 0.841214f, 0.456016f, 0.869270f, 1.692999f, - -1.700494f, -0.911761f, 0.030111f, -1.447548f, -}; - -static const float vp9_part_split_nn_bias_64_layer1[LABELS] = { - 1.17782545f, -}; - -static const NN_CONFIG vp9_part_split_nnconfig_64 = { - FEATURES, // num_inputs - LABELS, // num_outputs - 1, // num_hidden_layers - { - NODES, - }, // num_hidden_nodes - { - vp9_part_split_nn_weights_64_layer0, - vp9_part_split_nn_weights_64_layer1, - }, - { - vp9_part_split_nn_bias_64_layer0, - vp9_part_split_nn_bias_64_layer1, - }, -}; - -static const float vp9_part_split_nn_weights_32_layer0[FEATURES * NODES] = { - -0.105488f, -0.218662f, 0.010980f, -0.226979f, 0.028076f, 0.743430f, - 0.789266f, 0.031907f, -1.464200f, 0.222336f, -1.068493f, -0.052712f, - -0.176181f, -0.102654f, -0.973932f, -0.182637f, -0.198000f, 0.335977f, - 0.271346f, 0.133005f, 1.674203f, 0.689567f, 0.657133f, 0.283524f, - 0.115529f, 0.738327f, 0.317184f, -0.179736f, 0.403691f, 0.679350f, - 0.048925f, 0.271338f, -1.538921f, -0.900737f, -1.377845f, 0.084245f, - 0.803122f, -0.107806f, 0.103045f, -0.023335f, -0.098116f, -0.127809f, - 0.037665f, -0.523225f, 1.622185f, 1.903999f, 1.358889f, 1.680785f, - 0.027743f, 0.117906f, -0.158810f, 0.057775f, 0.168257f, 0.062414f, - 0.086228f, -0.087381f, -3.066082f, 3.021855f, -4.092155f, 2.550104f, - -0.230022f, -0.207445f, -0.000347f, 0.034042f, 0.097057f, 0.220088f, - -0.228841f, -0.029405f, -1.507174f, -1.455184f, 2.624904f, 2.643355f, - 0.319912f, 0.585531f, -1.018225f, -0.699606f, 1.026490f, 0.169952f, - -0.093579f, -0.142352f, -0.107256f, 0.059598f, 0.043190f, 0.507543f, - -0.138617f, 0.030197f, 0.059574f, -0.634051f, -0.586724f, -0.148020f, - -0.334380f, 0.459547f, 1.620600f, 0.496850f, 0.639480f, -0.465715f, -}; - -static const float vp9_part_split_nn_bias_32_layer0[NODES] = { - -1.125885f, 0.753197f, -0.825808f, 0.004839f, - 0.583920f, 0.718062f, 0.976741f, 0.796188f, -}; - -static const float vp9_part_split_nn_weights_32_layer1[NODES * LABELS] = { - -0.458745f, 0.724624f, -0.479720f, -2.199872f, - 1.162661f, 1.194153f, -0.716896f, 0.824080f, -}; - -static const float vp9_part_split_nn_bias_32_layer1[LABELS] = { - 0.71644074f, -}; - -static const NN_CONFIG vp9_part_split_nnconfig_32 = { - FEATURES, // num_inputs - LABELS, // num_outputs - 1, // num_hidden_layers - { - NODES, - }, // num_hidden_nodes - { - vp9_part_split_nn_weights_32_layer0, - vp9_part_split_nn_weights_32_layer1, - }, - { - vp9_part_split_nn_bias_32_layer0, - vp9_part_split_nn_bias_32_layer1, - }, -}; - -static const float vp9_part_split_nn_weights_16_layer0[FEATURES * NODES] = { - -0.003629f, -0.046852f, 0.220428f, -0.033042f, 0.049365f, 0.112818f, - -0.306149f, -0.005872f, 1.066947f, -2.290226f, 2.159505f, -0.618714f, - -0.213294f, 0.451372f, -0.199459f, 0.223730f, -0.321709f, 0.063364f, - 0.148704f, -0.293371f, 0.077225f, -0.421947f, -0.515543f, -0.240975f, - -0.418516f, 1.036523f, -0.009165f, 0.032484f, 1.086549f, 0.220322f, - -0.247585f, -0.221232f, -0.225050f, 0.993051f, 0.285907f, 1.308846f, - 0.707456f, 0.335152f, 0.234556f, 0.264590f, -0.078033f, 0.542226f, - 0.057777f, 0.163471f, 0.039245f, -0.725960f, 0.963780f, -0.972001f, - 0.252237f, -0.192745f, -0.836571f, -0.460539f, -0.528713f, -0.160198f, - -0.621108f, 0.486405f, -0.221923f, 1.519426f, -0.857871f, 0.411595f, - 0.947188f, 0.203339f, 0.174526f, 0.016382f, 0.256879f, 0.049818f, - 0.057836f, -0.659096f, 0.459894f, 0.174695f, 0.379359f, 0.062530f, - -0.210201f, -0.355788f, -0.208432f, -0.401723f, -0.115373f, 0.191336f, - -0.109342f, 0.002455f, -0.078746f, -0.391871f, 0.149892f, -0.239615f, - -0.520709f, 0.118568f, -0.437975f, 0.118116f, -0.565426f, -0.206446f, - 0.113407f, 0.558894f, 0.534627f, 1.154350f, -0.116833f, 1.723311f, -}; - -static const float vp9_part_split_nn_bias_16_layer0[NODES] = { - 0.013109f, -0.034341f, 0.679845f, -0.035781f, - -0.104183f, 0.098055f, -0.041130f, 0.160107f, -}; - -static const float vp9_part_split_nn_weights_16_layer1[NODES * LABELS] = { - 1.499564f, -0.403259f, 1.366532f, -0.469868f, - 0.482227f, -2.076697f, 0.527691f, 0.540495f, -}; - -static const float vp9_part_split_nn_bias_16_layer1[LABELS] = { - 0.01134653f, -}; - -static const NN_CONFIG vp9_part_split_nnconfig_16 = { - FEATURES, // num_inputs - LABELS, // num_outputs - 1, // num_hidden_layers - { - NODES, - }, // num_hidden_nodes - { - vp9_part_split_nn_weights_16_layer0, - vp9_part_split_nn_weights_16_layer1, - }, - { - vp9_part_split_nn_bias_16_layer0, - vp9_part_split_nn_bias_16_layer1, - }, -}; - -static const float vp9_part_split_nn_weights_8_layer0[FEATURES * NODES] = { - -0.668875f, -0.159078f, -0.062663f, -0.483785f, -0.146814f, -0.608975f, - -0.589145f, 0.203704f, -0.051007f, -0.113769f, -0.477511f, -0.122603f, - -1.329890f, 1.403386f, 0.199636f, -0.161139f, 2.182090f, -0.014307f, - 0.015755f, -0.208468f, 0.884353f, 0.815920f, 0.632464f, 0.838225f, - 1.369483f, -0.029068f, 0.570213f, -0.573546f, 0.029617f, 0.562054f, - -0.653093f, -0.211910f, -0.661013f, -0.384418f, -0.574038f, -0.510069f, - 0.173047f, -0.274231f, -1.044008f, -0.422040f, -0.810296f, 0.144069f, - -0.406704f, 0.411230f, -0.144023f, 0.745651f, -0.595091f, 0.111787f, - 0.840651f, 0.030123f, -0.242155f, 0.101486f, -0.017889f, -0.254467f, - -0.285407f, -0.076675f, -0.549542f, -0.013544f, -0.686566f, -0.755150f, - 1.623949f, -0.286369f, 0.170976f, 0.016442f, -0.598353f, -0.038540f, - 0.202597f, -0.933582f, 0.599510f, 0.362273f, 0.577722f, 0.477603f, - 0.767097f, 0.431532f, 0.457034f, 0.223279f, 0.381349f, 0.033777f, - 0.423923f, -0.664762f, 0.385662f, 0.075744f, 0.182681f, 0.024118f, - 0.319408f, -0.528864f, 0.976537f, -0.305971f, -0.189380f, -0.241689f, - -1.318092f, 0.088647f, -0.109030f, -0.945654f, 1.082797f, 0.184564f, -}; - -static const float vp9_part_split_nn_bias_8_layer0[NODES] = { - -0.237472f, 2.051396f, 0.297062f, -0.730194f, - 0.060472f, -0.565959f, 0.560869f, -0.395448f, -}; - -static const float vp9_part_split_nn_weights_8_layer1[NODES * LABELS] = { - 0.568121f, 1.575915f, -0.544309f, 0.751595f, - -0.117911f, -1.340730f, -0.739671f, 0.661216f, -}; - -static const float vp9_part_split_nn_bias_8_layer1[LABELS] = { - -0.63375306f, -}; - -static const NN_CONFIG vp9_part_split_nnconfig_8 = { - FEATURES, // num_inputs - LABELS, // num_outputs - 1, // num_hidden_layers - { - NODES, - }, // num_hidden_nodes - { - vp9_part_split_nn_weights_8_layer0, - vp9_part_split_nn_weights_8_layer1, - }, - { - vp9_part_split_nn_bias_8_layer0, - vp9_part_split_nn_bias_8_layer1, - }, -}; -#undef NODES -#undef FEATURES -#undef LABELS - -// Partition pruning model(linear). -static const float vp9_partition_feature_mean[24] = { - 303501.697372f, 3042630.372158f, 24.694696f, 1.392182f, - 689.413511f, 162.027012f, 1.478213f, 0.0, - 135382.260230f, 912738.513263f, 28.845217f, 1.515230f, - 544.158492f, 131.807995f, 1.436863f, 0.0f, - 43682.377587f, 208131.711766f, 28.084737f, 1.356677f, - 138.254122f, 119.522553f, 1.252322f, 0.0f, -}; - -static const float vp9_partition_feature_std[24] = { - 673689.212982f, 5996652.516628f, 0.024449f, 1.989792f, - 985.880847f, 0.014638f, 2.001898f, 0.0f, - 208798.775332f, 1812548.443284f, 0.018693f, 1.838009f, - 396.986910f, 0.015657f, 1.332541f, 0.0f, - 55888.847031f, 448587.962714f, 0.017900f, 1.904776f, - 98.652832f, 0.016598f, 1.320992f, 0.0f, -}; - -// Error tolerance: 0.01%-0.0.05%-0.1% -static const float vp9_partition_linear_weights[24] = { - 0.111736f, 0.289977f, 0.042219f, 0.204765f, 0.120410f, -0.143863f, - 0.282376f, 0.847811f, 0.637161f, 0.131570f, 0.018636f, 0.202134f, - 0.112797f, 0.028162f, 0.182450f, 1.124367f, 0.386133f, 0.083700f, - 0.050028f, 0.150873f, 0.061119f, 0.109318f, 0.127255f, 0.625211f, -}; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_PARTITION_MODELS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_picklpf.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_picklpf.c deleted file mode 100644 index 3a620df6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_picklpf.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_scale_rtcd.h" -#include "vpx_dsp/psnr.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" - -#include "vp9/common/vp9_loopfilter.h" -#include "vp9/common/vp9_onyxc_int.h" -#include "vp9/common/vp9_quant_common.h" - -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_picklpf.h" -#include "vp9/encoder/vp9_quantize.h" - -static unsigned int get_section_intra_rating(const VP9_COMP *cpi) { - unsigned int section_intra_rating; - - section_intra_rating = (cpi->common.frame_type == KEY_FRAME) - ? cpi->twopass.key_frame_section_intra_rating - : cpi->twopass.section_intra_rating; - - return section_intra_rating; -} - -static int get_max_filter_level(const VP9_COMP *cpi) { - if (cpi->oxcf.pass == 2) { - unsigned int section_intra_rating = get_section_intra_rating(cpi); - return section_intra_rating > 8 ? MAX_LOOP_FILTER * 3 / 4 : MAX_LOOP_FILTER; - } else { - return MAX_LOOP_FILTER; - } -} - -static int64_t try_filter_frame(const YV12_BUFFER_CONFIG *sd, - VP9_COMP *const cpi, int filt_level, - int partial_frame) { - VP9_COMMON *const cm = &cpi->common; - int64_t filt_err; - - vp9_build_mask_frame(cm, filt_level, partial_frame); - - if (cpi->num_workers > 1) - vp9_loop_filter_frame_mt(cm->frame_to_show, cm, cpi->td.mb.e_mbd.plane, - filt_level, 1, partial_frame, cpi->workers, - cpi->num_workers, &cpi->lf_row_sync); - else - vp9_loop_filter_frame(cm->frame_to_show, cm, &cpi->td.mb.e_mbd, filt_level, - 1, partial_frame); - -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - filt_err = vpx_highbd_get_y_sse(sd, cm->frame_to_show); - } else { - filt_err = vpx_get_y_sse(sd, cm->frame_to_show); - } -#else - filt_err = vpx_get_y_sse(sd, cm->frame_to_show); -#endif // CONFIG_VP9_HIGHBITDEPTH - - // Re-instate the unfiltered frame - vpx_yv12_copy_y(&cpi->last_frame_uf, cm->frame_to_show); - - return filt_err; -} - -static int search_filter_level(const YV12_BUFFER_CONFIG *sd, VP9_COMP *cpi, - int partial_frame) { - const VP9_COMMON *const cm = &cpi->common; - const struct loopfilter *const lf = &cm->lf; - const int min_filter_level = 0; - const int max_filter_level = get_max_filter_level(cpi); - int filt_direction = 0; - int64_t best_err; - int filt_best; - - // Start the search at the previous frame filter level unless it is now out of - // range. - int filt_mid = clamp(lf->last_filt_level, min_filter_level, max_filter_level); - int filter_step = filt_mid < 16 ? 4 : filt_mid / 4; - // Sum squared error at each filter level - int64_t ss_err[MAX_LOOP_FILTER + 1]; - unsigned int section_intra_rating = get_section_intra_rating(cpi); - - // Set each entry to -1 - memset(ss_err, 0xFF, sizeof(ss_err)); - - // Make a copy of the unfiltered / processed recon buffer - vpx_yv12_copy_y(cm->frame_to_show, &cpi->last_frame_uf); - - best_err = try_filter_frame(sd, cpi, filt_mid, partial_frame); - filt_best = filt_mid; - ss_err[filt_mid] = best_err; - - while (filter_step > 0) { - const int filt_high = VPXMIN(filt_mid + filter_step, max_filter_level); - const int filt_low = VPXMAX(filt_mid - filter_step, min_filter_level); - - // Bias against raising loop filter in favor of lowering it. - int64_t bias = (best_err >> (15 - (filt_mid / 8))) * filter_step; - - if ((cpi->oxcf.pass == 2) && (section_intra_rating < 20)) - bias = (bias * section_intra_rating) / 20; - - // yx, bias less for large block size - if (cm->tx_mode != ONLY_4X4) bias >>= 1; - - if (filt_direction <= 0 && filt_low != filt_mid) { - // Get Low filter error score - if (ss_err[filt_low] < 0) { - ss_err[filt_low] = try_filter_frame(sd, cpi, filt_low, partial_frame); - } - // If value is close to the best so far then bias towards a lower loop - // filter value. - if ((ss_err[filt_low] - bias) < best_err) { - // Was it actually better than the previous best? - if (ss_err[filt_low] < best_err) best_err = ss_err[filt_low]; - - filt_best = filt_low; - } - } - - // Now look at filt_high - if (filt_direction >= 0 && filt_high != filt_mid) { - if (ss_err[filt_high] < 0) { - ss_err[filt_high] = try_filter_frame(sd, cpi, filt_high, partial_frame); - } - // Was it better than the previous best? - if (ss_err[filt_high] < (best_err - bias)) { - best_err = ss_err[filt_high]; - filt_best = filt_high; - } - } - - // Half the step distance if the best filter value was the same as last time - if (filt_best == filt_mid) { - filter_step /= 2; - filt_direction = 0; - } else { - filt_direction = (filt_best < filt_mid) ? -1 : 1; - filt_mid = filt_best; - } - } - - return filt_best; -} - -void vp9_pick_filter_level(const YV12_BUFFER_CONFIG *sd, VP9_COMP *cpi, - LPF_PICK_METHOD method) { - VP9_COMMON *const cm = &cpi->common; - struct loopfilter *const lf = &cm->lf; - - lf->sharpness_level = 0; - - if (method == LPF_PICK_MINIMAL_LPF && lf->filter_level) { - lf->filter_level = 0; - } else if (method >= LPF_PICK_FROM_Q) { - const int min_filter_level = 0; - const int max_filter_level = get_max_filter_level(cpi); - const int q = vp9_ac_quant(cm->base_qindex, 0, cm->bit_depth); -// These values were determined by linear fitting the result of the -// searched level, filt_guess = q * 0.316206 + 3.87252 -#if CONFIG_VP9_HIGHBITDEPTH - int filt_guess; - switch (cm->bit_depth) { - case VPX_BITS_8: - filt_guess = ROUND_POWER_OF_TWO(q * 20723 + 1015158, 18); - break; - case VPX_BITS_10: - filt_guess = ROUND_POWER_OF_TWO(q * 20723 + 4060632, 20); - break; - default: - assert(cm->bit_depth == VPX_BITS_12); - filt_guess = ROUND_POWER_OF_TWO(q * 20723 + 16242526, 22); - break; - } -#else - int filt_guess = ROUND_POWER_OF_TWO(q * 20723 + 1015158, 18); -#endif // CONFIG_VP9_HIGHBITDEPTH - if (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_CBR && - cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled && - (cm->base_qindex < 200 || cm->width * cm->height > 320 * 240) && - cpi->oxcf.content != VP9E_CONTENT_SCREEN && cm->frame_type != KEY_FRAME) - filt_guess = 5 * filt_guess >> 3; - - if (cm->frame_type == KEY_FRAME) filt_guess -= 4; - lf->filter_level = clamp(filt_guess, min_filter_level, max_filter_level); - } else { - lf->filter_level = - search_filter_level(sd, cpi, method == LPF_PICK_FROM_SUBIMAGE); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_picklpf.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_picklpf.h deleted file mode 100644 index 8881b44d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_picklpf.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_PICKLPF_H_ -#define VPX_VP9_ENCODER_VP9_PICKLPF_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "vp9/encoder/vp9_encoder.h" - -struct yv12_buffer_config; -struct VP9_COMP; - -void vp9_pick_filter_level(const struct yv12_buffer_config *sd, - struct VP9_COMP *cpi, LPF_PICK_METHOD method); -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_PICKLPF_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_pickmode.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_pickmode.c deleted file mode 100644 index d561b506..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_pickmode.c +++ /dev/null @@ -1,2992 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "./vp9_rtcd.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx/vpx_codec.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/compiler_attributes.h" - -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_mvref_common.h" -#include "vp9/common/vp9_pred_common.h" -#include "vp9/common/vp9_reconinter.h" -#include "vp9/common/vp9_reconintra.h" -#include "vp9/common/vp9_scan.h" - -#include "vp9/encoder/vp9_cost.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_pickmode.h" -#include "vp9/encoder/vp9_ratectrl.h" -#include "vp9/encoder/vp9_rd.h" - -typedef struct { - uint8_t *data; - int stride; - int in_use; -} PRED_BUFFER; - -typedef struct { - PRED_BUFFER *best_pred; - PREDICTION_MODE best_mode; - TX_SIZE best_tx_size; - TX_SIZE best_intra_tx_size; - MV_REFERENCE_FRAME best_ref_frame; - MV_REFERENCE_FRAME best_second_ref_frame; - uint8_t best_mode_skip_txfm; - INTERP_FILTER best_pred_filter; -} BEST_PICKMODE; - -static const int pos_shift_16x16[4][4] = { - { 9, 10, 13, 14 }, { 11, 12, 15, 16 }, { 17, 18, 21, 22 }, { 19, 20, 23, 24 } -}; - -static int mv_refs_rt(VP9_COMP *cpi, const VP9_COMMON *cm, const MACROBLOCK *x, - const MACROBLOCKD *xd, const TileInfo *const tile, - MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame, - int_mv *mv_ref_list, int_mv *base_mv, int mi_row, - int mi_col, int use_base_mv) { - const int *ref_sign_bias = cm->ref_frame_sign_bias; - int i, refmv_count = 0; - - const POSITION *const mv_ref_search = mv_ref_blocks[mi->sb_type]; - - int different_ref_found = 0; - int context_counter = 0; - int const_motion = 0; - - // Blank the reference vector list - memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES); - - // The nearest 2 blocks are treated differently - // if the size < 8x8 we get the mv from the bmi substructure, - // and we also need to keep a mode count. - for (i = 0; i < 2; ++i) { - const POSITION *const mv_ref = &mv_ref_search[i]; - if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { - const MODE_INFO *const candidate_mi = - xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; - // Keep counts for entropy encoding. - context_counter += mode_2_counter[candidate_mi->mode]; - different_ref_found = 1; - - if (candidate_mi->ref_frame[0] == ref_frame) - ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 0, mv_ref->col, -1), - refmv_count, mv_ref_list, Done); - } - } - - const_motion = 1; - - // Check the rest of the neighbors in much the same way - // as before except we don't need to keep track of sub blocks or - // mode counts. - for (; i < MVREF_NEIGHBOURS && !refmv_count; ++i) { - const POSITION *const mv_ref = &mv_ref_search[i]; - if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { - const MODE_INFO *const candidate_mi = - xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; - different_ref_found = 1; - - if (candidate_mi->ref_frame[0] == ref_frame) - ADD_MV_REF_LIST(candidate_mi->mv[0], refmv_count, mv_ref_list, Done); - } - } - - // Since we couldn't find 2 mvs from the same reference frame - // go back through the neighbors and find motion vectors from - // different reference frames. - if (different_ref_found && !refmv_count) { - for (i = 0; i < MVREF_NEIGHBOURS; ++i) { - const POSITION *mv_ref = &mv_ref_search[i]; - if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { - const MODE_INFO *const candidate_mi = - xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]; - - // If the candidate is INTRA we don't want to consider its mv. - IF_DIFF_REF_FRAME_ADD_MV(candidate_mi, ref_frame, ref_sign_bias, - refmv_count, mv_ref_list, Done); - } - } - } - if (use_base_mv && - !cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame && - ref_frame == LAST_FRAME) { - // Get base layer mv. - MV_REF *candidate = - &cm->prev_frame - ->mvs[(mi_col >> 1) + (mi_row >> 1) * (cm->mi_cols >> 1)]; - if (candidate->mv[0].as_int != INVALID_MV) { - base_mv->as_mv.row = (candidate->mv[0].as_mv.row * 2); - base_mv->as_mv.col = (candidate->mv[0].as_mv.col * 2); - clamp_mv_ref(&base_mv->as_mv, xd); - } else { - base_mv->as_int = INVALID_MV; - } - } - -Done: - - x->mbmi_ext->mode_context[ref_frame] = counter_to_context[context_counter]; - - // Clamp vectors - for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) - clamp_mv_ref(&mv_ref_list[i].as_mv, xd); - - return const_motion; -} - -static int combined_motion_search(VP9_COMP *cpi, MACROBLOCK *x, - BLOCK_SIZE bsize, int mi_row, int mi_col, - int_mv *tmp_mv, int *rate_mv, - int64_t best_rd_sofar, int use_base_mv) { - MACROBLOCKD *xd = &x->e_mbd; - MODE_INFO *mi = xd->mi[0]; - struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0 } }; - const int step_param = cpi->sf.mv.fullpel_search_step_param; - const int sadpb = x->sadperbit16; - MV mvp_full; - const int ref = mi->ref_frame[0]; - const MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv; - MV center_mv; - uint32_t dis; - int rate_mode; - const MvLimits tmp_mv_limits = x->mv_limits; - int rv = 0; - int cost_list[5]; - int search_subpel = 1; - const YV12_BUFFER_CONFIG *scaled_ref_frame = - vp9_get_scaled_ref_frame(cpi, ref); - if (scaled_ref_frame) { - int i; - // Swap out the reference frame for a version that's been scaled to - // match the resolution of the current frame, allowing the existing - // motion search code to be used without additional modifications. - for (i = 0; i < MAX_MB_PLANE; i++) backup_yv12[i] = xd->plane[i].pre[0]; - vp9_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL); - } - vp9_set_mv_search_range(&x->mv_limits, &ref_mv); - - // Limit motion vector for large lightning change. - if (cpi->oxcf.speed > 5 && x->lowvar_highsumdiff) { - x->mv_limits.col_min = VPXMAX(x->mv_limits.col_min, -10); - x->mv_limits.row_min = VPXMAX(x->mv_limits.row_min, -10); - x->mv_limits.col_max = VPXMIN(x->mv_limits.col_max, 10); - x->mv_limits.row_max = VPXMIN(x->mv_limits.row_max, 10); - } - - assert(x->mv_best_ref_index[ref] <= 2); - if (x->mv_best_ref_index[ref] < 2) - mvp_full = x->mbmi_ext->ref_mvs[ref][x->mv_best_ref_index[ref]].as_mv; - else - mvp_full = x->pred_mv[ref]; - - mvp_full.col >>= 3; - mvp_full.row >>= 3; - - if (!use_base_mv) - center_mv = ref_mv; - else - center_mv = tmp_mv->as_mv; - - if (x->sb_use_mv_part) { - tmp_mv->as_mv.row = x->sb_mvrow_part >> 3; - tmp_mv->as_mv.col = x->sb_mvcol_part >> 3; - } else { - vp9_full_pixel_search( - cpi, x, bsize, &mvp_full, step_param, cpi->sf.mv.search_method, sadpb, - cond_cost_list(cpi, cost_list), ¢er_mv, &tmp_mv->as_mv, INT_MAX, 0); - } - - x->mv_limits = tmp_mv_limits; - - // calculate the bit cost on motion vector - mvp_full.row = tmp_mv->as_mv.row * 8; - mvp_full.col = tmp_mv->as_mv.col * 8; - - *rate_mv = vp9_mv_bit_cost(&mvp_full, &ref_mv, x->nmvjointcost, x->mvcost, - MV_COST_WEIGHT); - - rate_mode = - cpi->inter_mode_cost[x->mbmi_ext->mode_context[ref]][INTER_OFFSET(NEWMV)]; - rv = - !(RDCOST(x->rdmult, x->rddiv, (*rate_mv + rate_mode), 0) > best_rd_sofar); - - // For SVC on non-reference frame, avoid subpel for (0, 0) motion. - if (cpi->use_svc && cpi->svc.non_reference_frame) { - if (mvp_full.row == 0 && mvp_full.col == 0) search_subpel = 0; - } - - if (rv && search_subpel) { - SUBPEL_FORCE_STOP subpel_force_stop = cpi->sf.mv.subpel_force_stop; - if (use_base_mv && cpi->sf.base_mv_aggressive) subpel_force_stop = HALF_PEL; - if (cpi->sf.mv.enable_adaptive_subpel_force_stop) { - const int mv_thresh = cpi->sf.mv.adapt_subpel_force_stop.mv_thresh; - if (abs(tmp_mv->as_mv.row) >= mv_thresh || - abs(tmp_mv->as_mv.col) >= mv_thresh) - subpel_force_stop = cpi->sf.mv.adapt_subpel_force_stop.force_stop_above; - else - subpel_force_stop = cpi->sf.mv.adapt_subpel_force_stop.force_stop_below; - } - cpi->find_fractional_mv_step( - x, &tmp_mv->as_mv, &ref_mv, cpi->common.allow_high_precision_mv, - x->errorperbit, &cpi->fn_ptr[bsize], subpel_force_stop, - cpi->sf.mv.subpel_search_level, cond_cost_list(cpi, cost_list), - x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, 0, 0, - cpi->sf.use_accurate_subpel_search); - *rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost, - x->mvcost, MV_COST_WEIGHT); - } - - if (scaled_ref_frame) { - int i; - for (i = 0; i < MAX_MB_PLANE; i++) xd->plane[i].pre[0] = backup_yv12[i]; - } - return rv; -} - -static void block_variance(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, int w, int h, - unsigned int *sse, int *sum, int block_size, -#if CONFIG_VP9_HIGHBITDEPTH - int use_highbitdepth, vpx_bit_depth_t bd, -#endif - uint32_t *sse8x8, int *sum8x8, uint32_t *var8x8) { - int i, j, k = 0; - uint32_t k_sqr = 0; - - *sse = 0; - *sum = 0; - - for (i = 0; i < h; i += block_size) { - for (j = 0; j < w; j += block_size) { -#if CONFIG_VP9_HIGHBITDEPTH - if (use_highbitdepth) { - switch (bd) { - case VPX_BITS_8: - vpx_highbd_8_get8x8var(src + src_stride * i + j, src_stride, - ref + ref_stride * i + j, ref_stride, - &sse8x8[k], &sum8x8[k]); - break; - case VPX_BITS_10: - vpx_highbd_10_get8x8var(src + src_stride * i + j, src_stride, - ref + ref_stride * i + j, ref_stride, - &sse8x8[k], &sum8x8[k]); - break; - case VPX_BITS_12: - vpx_highbd_12_get8x8var(src + src_stride * i + j, src_stride, - ref + ref_stride * i + j, ref_stride, - &sse8x8[k], &sum8x8[k]); - break; - } - } else { - vpx_get8x8var(src + src_stride * i + j, src_stride, - ref + ref_stride * i + j, ref_stride, &sse8x8[k], - &sum8x8[k]); - } -#else - vpx_get8x8var(src + src_stride * i + j, src_stride, - ref + ref_stride * i + j, ref_stride, &sse8x8[k], - &sum8x8[k]); -#endif - *sse += sse8x8[k]; - *sum += sum8x8[k]; - k_sqr = (uint32_t)(((int64_t)sum8x8[k] * sum8x8[k]) >> 6); - var8x8[k] = sse8x8[k] > k_sqr ? sse8x8[k] - k_sqr : k_sqr - sse8x8[k]; - k++; - } - } -} - -static void calculate_variance(int bw, int bh, TX_SIZE tx_size, - unsigned int *sse_i, int *sum_i, - unsigned int *var_o, unsigned int *sse_o, - int *sum_o) { - const BLOCK_SIZE unit_size = txsize_to_bsize[tx_size]; - const int nw = 1 << (bw - b_width_log2_lookup[unit_size]); - const int nh = 1 << (bh - b_height_log2_lookup[unit_size]); - int i, j, k = 0; - uint32_t k_sqr = 0; - - for (i = 0; i < nh; i += 2) { - for (j = 0; j < nw; j += 2) { - sse_o[k] = sse_i[i * nw + j] + sse_i[i * nw + j + 1] + - sse_i[(i + 1) * nw + j] + sse_i[(i + 1) * nw + j + 1]; - sum_o[k] = sum_i[i * nw + j] + sum_i[i * nw + j + 1] + - sum_i[(i + 1) * nw + j] + sum_i[(i + 1) * nw + j + 1]; - k_sqr = (uint32_t)(((int64_t)sum_o[k] * sum_o[k]) >> - (b_width_log2_lookup[unit_size] + - b_height_log2_lookup[unit_size] + 6)); - var_o[k] = sse_o[k] > k_sqr ? sse_o[k] - k_sqr : k_sqr - sse_o[k]; - k++; - } - } -} - -// Adjust the ac_thr according to speed, width, height and normalized sum -static int ac_thr_factor(const int speed, const int width, const int height, - const int norm_sum) { - if (speed >= 8 && norm_sum < 5) { - if (width <= 640 && height <= 480) - return 4; - else - return 2; - } - return 1; -} - -static TX_SIZE calculate_tx_size(VP9_COMP *const cpi, BLOCK_SIZE bsize, - MACROBLOCKD *const xd, unsigned int var, - unsigned int sse, int64_t ac_thr, - unsigned int source_variance, int is_intra) { - // TODO(marpan): Tune selection for intra-modes, screen content, etc. - TX_SIZE tx_size; - unsigned int var_thresh = is_intra ? (unsigned int)ac_thr : 1; - int limit_tx = 1; - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && - (source_variance == 0 || var < var_thresh)) - limit_tx = 0; - if (cpi->common.tx_mode == TX_MODE_SELECT) { - if (sse > (var << 2)) - tx_size = VPXMIN(max_txsize_lookup[bsize], - tx_mode_to_biggest_tx_size[cpi->common.tx_mode]); - else - tx_size = TX_8X8; - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && limit_tx && - cyclic_refresh_segment_id_boosted(xd->mi[0]->segment_id)) - tx_size = TX_8X8; - else if (tx_size > TX_16X16 && limit_tx) - tx_size = TX_16X16; - // For screen-content force 4X4 tx_size over 8X8, for large variance. - if (cpi->oxcf.content == VP9E_CONTENT_SCREEN && tx_size == TX_8X8 && - bsize <= BLOCK_16X16 && ((var >> 5) > (unsigned int)ac_thr)) - tx_size = TX_4X4; - } else { - tx_size = VPXMIN(max_txsize_lookup[bsize], - tx_mode_to_biggest_tx_size[cpi->common.tx_mode]); - } - return tx_size; -} - -static void compute_intra_yprediction(PREDICTION_MODE mode, BLOCK_SIZE bsize, - MACROBLOCK *x, MACROBLOCKD *xd) { - struct macroblockd_plane *const pd = &xd->plane[0]; - struct macroblock_plane *const p = &x->plane[0]; - uint8_t *const src_buf_base = p->src.buf; - uint8_t *const dst_buf_base = pd->dst.buf; - const int src_stride = p->src.stride; - const int dst_stride = pd->dst.stride; - // block and transform sizes, in number of 4x4 blocks log 2 ("*_b") - // 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8 - const TX_SIZE tx_size = max_txsize_lookup[bsize]; - const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; - const int num_4x4_h = num_4x4_blocks_high_lookup[bsize]; - int row, col; - // If mb_to_right_edge is < 0 we are in a situation in which - // the current block size extends into the UMV and we won't - // visit the sub blocks that are wholly within the UMV. - const int max_blocks_wide = - num_4x4_w + (xd->mb_to_right_edge >= 0 - ? 0 - : xd->mb_to_right_edge >> (5 + pd->subsampling_x)); - const int max_blocks_high = - num_4x4_h + (xd->mb_to_bottom_edge >= 0 - ? 0 - : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y)); - - // Keep track of the row and column of the blocks we use so that we know - // if we are in the unrestricted motion border. - for (row = 0; row < max_blocks_high; row += (1 << tx_size)) { - // Skip visiting the sub blocks that are wholly within the UMV. - for (col = 0; col < max_blocks_wide; col += (1 << tx_size)) { - p->src.buf = &src_buf_base[4 * (row * (int64_t)src_stride + col)]; - pd->dst.buf = &dst_buf_base[4 * (row * (int64_t)dst_stride + col)]; - vp9_predict_intra_block(xd, b_width_log2_lookup[bsize], tx_size, mode, - x->skip_encode ? p->src.buf : pd->dst.buf, - x->skip_encode ? src_stride : dst_stride, - pd->dst.buf, dst_stride, col, row, 0); - } - } - p->src.buf = src_buf_base; - pd->dst.buf = dst_buf_base; -} - -static void model_rd_for_sb_y_large(VP9_COMP *cpi, BLOCK_SIZE bsize, - MACROBLOCK *x, MACROBLOCKD *xd, - int *out_rate_sum, int64_t *out_dist_sum, - unsigned int *var_y, unsigned int *sse_y, - int mi_row, int mi_col, int *early_term, - int *flag_preduv_computed) { - // Note our transform coeffs are 8 times an orthogonal transform. - // Hence quantizer step is also 8 times. To get effective quantizer - // we need to divide by 8 before sending to modeling function. - unsigned int sse; - int rate; - int64_t dist; - struct macroblock_plane *const p = &x->plane[0]; - struct macroblockd_plane *const pd = &xd->plane[0]; - const uint32_t dc_quant = pd->dequant[0]; - const uint32_t ac_quant = pd->dequant[1]; - int64_t dc_thr = dc_quant * dc_quant >> 6; - int64_t ac_thr = ac_quant * ac_quant >> 6; - unsigned int var; - int sum; - int skip_dc = 0; - - const int bw = b_width_log2_lookup[bsize]; - const int bh = b_height_log2_lookup[bsize]; - const int num8x8 = 1 << (bw + bh - 2); - unsigned int sse8x8[64] = { 0 }; - int sum8x8[64] = { 0 }; - unsigned int var8x8[64] = { 0 }; - TX_SIZE tx_size; - int i, k; - uint32_t sum_sqr; -#if CONFIG_VP9_HIGHBITDEPTH - const vpx_bit_depth_t bd = cpi->common.bit_depth; -#endif - // Calculate variance for whole partition, and also save 8x8 blocks' variance - // to be used in following transform skipping test. - block_variance(p->src.buf, p->src.stride, pd->dst.buf, pd->dst.stride, - 4 << bw, 4 << bh, &sse, &sum, 8, -#if CONFIG_VP9_HIGHBITDEPTH - cpi->common.use_highbitdepth, bd, -#endif - sse8x8, sum8x8, var8x8); - sum_sqr = (uint32_t)((int64_t)sum * sum) >> (bw + bh + 4); - var = sse > sum_sqr ? sse - sum_sqr : sum_sqr - sse; - - *var_y = var; - *sse_y = sse; - -#if CONFIG_VP9_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc(cpi) && - cpi->oxcf.speed > 5) - ac_thr = vp9_scale_acskip_thresh(ac_thr, cpi->denoiser.denoising_level, - (abs(sum) >> (bw + bh)), - cpi->svc.temporal_layer_id); - else - ac_thr *= ac_thr_factor(cpi->oxcf.speed, cpi->common.width, - cpi->common.height, abs(sum) >> (bw + bh)); -#else - ac_thr *= ac_thr_factor(cpi->oxcf.speed, cpi->common.width, - cpi->common.height, abs(sum) >> (bw + bh)); -#endif - - tx_size = calculate_tx_size(cpi, bsize, xd, var, sse, ac_thr, - x->source_variance, 0); - // The code below for setting skip flag assumes tranform size of at least 8x8, - // so force this lower limit on transform. - if (tx_size < TX_8X8) tx_size = TX_8X8; - xd->mi[0]->tx_size = tx_size; - - if (cpi->oxcf.content == VP9E_CONTENT_SCREEN && x->zero_temp_sad_source && - x->source_variance == 0) - dc_thr = dc_thr << 1; - - // Evaluate if the partition block is a skippable block in Y plane. - { - unsigned int sse16x16[16] = { 0 }; - int sum16x16[16] = { 0 }; - unsigned int var16x16[16] = { 0 }; - const int num16x16 = num8x8 >> 2; - - unsigned int sse32x32[4] = { 0 }; - int sum32x32[4] = { 0 }; - unsigned int var32x32[4] = { 0 }; - const int num32x32 = num8x8 >> 4; - - int ac_test = 1; - int dc_test = 1; - const int num = (tx_size == TX_8X8) - ? num8x8 - : ((tx_size == TX_16X16) ? num16x16 : num32x32); - const unsigned int *sse_tx = - (tx_size == TX_8X8) ? sse8x8 - : ((tx_size == TX_16X16) ? sse16x16 : sse32x32); - const unsigned int *var_tx = - (tx_size == TX_8X8) ? var8x8 - : ((tx_size == TX_16X16) ? var16x16 : var32x32); - - // Calculate variance if tx_size > TX_8X8 - if (tx_size >= TX_16X16) - calculate_variance(bw, bh, TX_8X8, sse8x8, sum8x8, var16x16, sse16x16, - sum16x16); - if (tx_size == TX_32X32) - calculate_variance(bw, bh, TX_16X16, sse16x16, sum16x16, var32x32, - sse32x32, sum32x32); - - // Skipping test - x->skip_txfm[0] = SKIP_TXFM_NONE; - for (k = 0; k < num; k++) - // Check if all ac coefficients can be quantized to zero. - if (!(var_tx[k] < ac_thr || var == 0)) { - ac_test = 0; - break; - } - - for (k = 0; k < num; k++) - // Check if dc coefficient can be quantized to zero. - if (!(sse_tx[k] - var_tx[k] < dc_thr || sse == var)) { - dc_test = 0; - break; - } - - if (ac_test) { - x->skip_txfm[0] = SKIP_TXFM_AC_ONLY; - - if (dc_test) x->skip_txfm[0] = SKIP_TXFM_AC_DC; - } else if (dc_test) { - skip_dc = 1; - } - } - - if (x->skip_txfm[0] == SKIP_TXFM_AC_DC) { - int skip_uv[2] = { 0 }; - unsigned int var_uv[2]; - unsigned int sse_uv[2]; - - *out_rate_sum = 0; - *out_dist_sum = sse << 4; - - // Transform skipping test in UV planes. - for (i = 1; i <= 2; i++) { - struct macroblock_plane *const p_uv = &x->plane[i]; - struct macroblockd_plane *const pd_uv = &xd->plane[i]; - const TX_SIZE uv_tx_size = get_uv_tx_size(xd->mi[0], pd_uv); - const BLOCK_SIZE unit_size = txsize_to_bsize[uv_tx_size]; - const BLOCK_SIZE uv_bsize = get_plane_block_size(bsize, pd_uv); - const int uv_bw = b_width_log2_lookup[uv_bsize]; - const int uv_bh = b_height_log2_lookup[uv_bsize]; - const int sf = (uv_bw - b_width_log2_lookup[unit_size]) + - (uv_bh - b_height_log2_lookup[unit_size]); - const uint32_t uv_dc_thr = - pd_uv->dequant[0] * pd_uv->dequant[0] >> (6 - sf); - const uint32_t uv_ac_thr = - pd_uv->dequant[1] * pd_uv->dequant[1] >> (6 - sf); - int j = i - 1; - - vp9_build_inter_predictors_sbp(xd, mi_row, mi_col, bsize, i); - flag_preduv_computed[i - 1] = 1; - var_uv[j] = cpi->fn_ptr[uv_bsize].vf(p_uv->src.buf, p_uv->src.stride, - pd_uv->dst.buf, pd_uv->dst.stride, - &sse_uv[j]); - - if ((var_uv[j] < uv_ac_thr || var_uv[j] == 0) && - (sse_uv[j] - var_uv[j] < uv_dc_thr || sse_uv[j] == var_uv[j])) - skip_uv[j] = 1; - else - break; - } - - // If the transform in YUV planes are skippable, the mode search checks - // fewer inter modes and doesn't check intra modes. - if (skip_uv[0] & skip_uv[1]) { - *early_term = 1; - } - return; - } - - if (!skip_dc) { -#if CONFIG_VP9_HIGHBITDEPTH - vp9_model_rd_from_var_lapndz(sse - var, num_pels_log2_lookup[bsize], - dc_quant >> (xd->bd - 5), &rate, &dist); -#else - vp9_model_rd_from_var_lapndz(sse - var, num_pels_log2_lookup[bsize], - dc_quant >> 3, &rate, &dist); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - - if (!skip_dc) { - *out_rate_sum = rate >> 1; - *out_dist_sum = dist << 3; - } else { - *out_rate_sum = 0; - *out_dist_sum = (sse - var) << 4; - } - -#if CONFIG_VP9_HIGHBITDEPTH - vp9_model_rd_from_var_lapndz(var, num_pels_log2_lookup[bsize], - ac_quant >> (xd->bd - 5), &rate, &dist); -#else - vp9_model_rd_from_var_lapndz(var, num_pels_log2_lookup[bsize], ac_quant >> 3, - &rate, &dist); -#endif // CONFIG_VP9_HIGHBITDEPTH - - *out_rate_sum += rate; - *out_dist_sum += dist << 4; -} - -static void model_rd_for_sb_y(VP9_COMP *cpi, BLOCK_SIZE bsize, MACROBLOCK *x, - MACROBLOCKD *xd, int *out_rate_sum, - int64_t *out_dist_sum, unsigned int *var_y, - unsigned int *sse_y, int is_intra) { - // Note our transform coeffs are 8 times an orthogonal transform. - // Hence quantizer step is also 8 times. To get effective quantizer - // we need to divide by 8 before sending to modeling function. - unsigned int sse; - int rate; - int64_t dist; - struct macroblock_plane *const p = &x->plane[0]; - struct macroblockd_plane *const pd = &xd->plane[0]; - const int64_t dc_thr = p->quant_thred[0] >> 6; - const int64_t ac_thr = p->quant_thred[1] >> 6; - const uint32_t dc_quant = pd->dequant[0]; - const uint32_t ac_quant = pd->dequant[1]; - unsigned int var = cpi->fn_ptr[bsize].vf(p->src.buf, p->src.stride, - pd->dst.buf, pd->dst.stride, &sse); - int skip_dc = 0; - - *var_y = var; - *sse_y = sse; - - xd->mi[0]->tx_size = calculate_tx_size(cpi, bsize, xd, var, sse, ac_thr, - x->source_variance, is_intra); - - // Evaluate if the partition block is a skippable block in Y plane. - { - const BLOCK_SIZE unit_size = txsize_to_bsize[xd->mi[0]->tx_size]; - const unsigned int num_blk_log2 = - (b_width_log2_lookup[bsize] - b_width_log2_lookup[unit_size]) + - (b_height_log2_lookup[bsize] - b_height_log2_lookup[unit_size]); - const unsigned int sse_tx = sse >> num_blk_log2; - const unsigned int var_tx = var >> num_blk_log2; - - x->skip_txfm[0] = SKIP_TXFM_NONE; - // Check if all ac coefficients can be quantized to zero. - if (var_tx < ac_thr || var == 0) { - x->skip_txfm[0] = SKIP_TXFM_AC_ONLY; - // Check if dc coefficient can be quantized to zero. - if (sse_tx - var_tx < dc_thr || sse == var) - x->skip_txfm[0] = SKIP_TXFM_AC_DC; - } else { - if (sse_tx - var_tx < dc_thr || sse == var) skip_dc = 1; - } - } - - if (x->skip_txfm[0] == SKIP_TXFM_AC_DC) { - *out_rate_sum = 0; - *out_dist_sum = sse << 4; - return; - } - - if (!skip_dc) { -#if CONFIG_VP9_HIGHBITDEPTH - vp9_model_rd_from_var_lapndz(sse - var, num_pels_log2_lookup[bsize], - dc_quant >> (xd->bd - 5), &rate, &dist); -#else - vp9_model_rd_from_var_lapndz(sse - var, num_pels_log2_lookup[bsize], - dc_quant >> 3, &rate, &dist); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - - if (!skip_dc) { - *out_rate_sum = rate >> 1; - *out_dist_sum = dist << 3; - } else { - *out_rate_sum = 0; - *out_dist_sum = (sse - var) << 4; - } - -#if CONFIG_VP9_HIGHBITDEPTH - vp9_model_rd_from_var_lapndz(var, num_pels_log2_lookup[bsize], - ac_quant >> (xd->bd - 5), &rate, &dist); -#else - vp9_model_rd_from_var_lapndz(var, num_pels_log2_lookup[bsize], ac_quant >> 3, - &rate, &dist); -#endif // CONFIG_VP9_HIGHBITDEPTH - - *out_rate_sum += rate; - *out_dist_sum += dist << 4; -} - -static void block_yrd(VP9_COMP *cpi, MACROBLOCK *x, RD_COST *this_rdc, - int *skippable, int64_t *sse, BLOCK_SIZE bsize, - TX_SIZE tx_size, int rd_computed, int is_intra) { - MACROBLOCKD *xd = &x->e_mbd; - const struct macroblockd_plane *pd = &xd->plane[0]; - struct macroblock_plane *const p = &x->plane[0]; - const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; - const int num_4x4_h = num_4x4_blocks_high_lookup[bsize]; - const int step = 1 << (tx_size << 1); - const int block_step = (1 << tx_size); - int block = 0, r, c; - const int max_blocks_wide = - num_4x4_w + (xd->mb_to_right_edge >= 0 ? 0 : xd->mb_to_right_edge >> 5); - const int max_blocks_high = - num_4x4_h + (xd->mb_to_bottom_edge >= 0 ? 0 : xd->mb_to_bottom_edge >> 5); - int eob_cost = 0; - const int bw = 4 * num_4x4_w; - const int bh = 4 * num_4x4_h; - - if (cpi->sf.use_simple_block_yrd && cpi->common.frame_type != KEY_FRAME && - (bsize < BLOCK_32X32 || - (cpi->use_svc && - (bsize < BLOCK_32X32 || cpi->svc.temporal_layer_id > 0)))) { - unsigned int var_y, sse_y; - (void)tx_size; - if (!rd_computed) - model_rd_for_sb_y(cpi, bsize, x, xd, &this_rdc->rate, &this_rdc->dist, - &var_y, &sse_y, is_intra); - *sse = INT_MAX; - *skippable = 0; - return; - } - - (void)cpi; - - // The max tx_size passed in is TX_16X16. - assert(tx_size != TX_32X32); -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - vpx_highbd_subtract_block(bh, bw, p->src_diff, bw, p->src.buf, - p->src.stride, pd->dst.buf, pd->dst.stride, - x->e_mbd.bd); - } else { - vpx_subtract_block(bh, bw, p->src_diff, bw, p->src.buf, p->src.stride, - pd->dst.buf, pd->dst.stride); - } -#else - vpx_subtract_block(bh, bw, p->src_diff, bw, p->src.buf, p->src.stride, - pd->dst.buf, pd->dst.stride); -#endif - *skippable = 1; - // Keep track of the row and column of the blocks we use so that we know - // if we are in the unrestricted motion border. - for (r = 0; r < max_blocks_high; r += block_step) { - for (c = 0; c < num_4x4_w; c += block_step) { - if (c < max_blocks_wide) { - const ScanOrder *const scan_order = &vp9_default_scan_orders[tx_size]; - tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block); - tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block); - tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); - uint16_t *const eob = &p->eobs[block]; - const int diff_stride = bw; - const int16_t *src_diff; - src_diff = &p->src_diff[(r * diff_stride + c) << 2]; - - // skip block condition should be handled before this is called. - assert(!x->skip_block); - - switch (tx_size) { - case TX_16X16: - vpx_hadamard_16x16(src_diff, diff_stride, coeff); - vp9_quantize_fp(coeff, 256, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - break; - case TX_8X8: - vpx_hadamard_8x8(src_diff, diff_stride, coeff); - vp9_quantize_fp(coeff, 64, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - break; - default: - assert(tx_size == TX_4X4); - x->fwd_txfm4x4(src_diff, coeff, diff_stride); - vp9_quantize_fp(coeff, 16, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - break; - } - *skippable &= (*eob == 0); - eob_cost += 1; - } - block += step; - } - } - - this_rdc->rate = 0; - if (*sse < INT64_MAX) { - *sse = (*sse << 6) >> 2; - if (*skippable) { - this_rdc->dist = *sse; - return; - } - } - - block = 0; - this_rdc->dist = 0; - for (r = 0; r < max_blocks_high; r += block_step) { - for (c = 0; c < num_4x4_w; c += block_step) { - if (c < max_blocks_wide) { - tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block); - tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block); - tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); - uint16_t *const eob = &p->eobs[block]; - - if (*eob == 1) - this_rdc->rate += (int)abs(qcoeff[0]); - else if (*eob > 1) - this_rdc->rate += vpx_satd(qcoeff, step << 4); - - this_rdc->dist += vp9_block_error_fp(coeff, dqcoeff, step << 4) >> 2; - } - block += step; - } - } - - // If skippable is set, rate gets clobbered later. - this_rdc->rate <<= (2 + VP9_PROB_COST_SHIFT); - this_rdc->rate += (eob_cost << VP9_PROB_COST_SHIFT); -} - -static void model_rd_for_sb_uv(VP9_COMP *cpi, BLOCK_SIZE plane_bsize, - MACROBLOCK *x, MACROBLOCKD *xd, - RD_COST *this_rdc, unsigned int *var_y, - unsigned int *sse_y, int start_plane, - int stop_plane) { - // Note our transform coeffs are 8 times an orthogonal transform. - // Hence quantizer step is also 8 times. To get effective quantizer - // we need to divide by 8 before sending to modeling function. - unsigned int sse; - int rate; - int64_t dist; - int i; -#if CONFIG_VP9_HIGHBITDEPTH - uint64_t tot_var = *var_y; - uint64_t tot_sse = *sse_y; -#else - uint32_t tot_var = *var_y; - uint32_t tot_sse = *sse_y; -#endif - - this_rdc->rate = 0; - this_rdc->dist = 0; - - for (i = start_plane; i <= stop_plane; ++i) { - struct macroblock_plane *const p = &x->plane[i]; - struct macroblockd_plane *const pd = &xd->plane[i]; - const uint32_t dc_quant = pd->dequant[0]; - const uint32_t ac_quant = pd->dequant[1]; - const BLOCK_SIZE bs = plane_bsize; - unsigned int var; - if (!x->color_sensitivity[i - 1]) continue; - - var = cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride, pd->dst.buf, - pd->dst.stride, &sse); - assert(sse >= var); - tot_var += var; - tot_sse += sse; - -#if CONFIG_VP9_HIGHBITDEPTH - vp9_model_rd_from_var_lapndz(sse - var, num_pels_log2_lookup[bs], - dc_quant >> (xd->bd - 5), &rate, &dist); -#else - vp9_model_rd_from_var_lapndz(sse - var, num_pels_log2_lookup[bs], - dc_quant >> 3, &rate, &dist); -#endif // CONFIG_VP9_HIGHBITDEPTH - - this_rdc->rate += rate >> 1; - this_rdc->dist += dist << 3; - -#if CONFIG_VP9_HIGHBITDEPTH - vp9_model_rd_from_var_lapndz(var, num_pels_log2_lookup[bs], - ac_quant >> (xd->bd - 5), &rate, &dist); -#else - vp9_model_rd_from_var_lapndz(var, num_pels_log2_lookup[bs], ac_quant >> 3, - &rate, &dist); -#endif // CONFIG_VP9_HIGHBITDEPTH - - this_rdc->rate += rate; - this_rdc->dist += dist << 4; - } - -#if CONFIG_VP9_HIGHBITDEPTH - *var_y = tot_var > UINT32_MAX ? UINT32_MAX : (uint32_t)tot_var; - *sse_y = tot_sse > UINT32_MAX ? UINT32_MAX : (uint32_t)tot_sse; -#else - *var_y = tot_var; - *sse_y = tot_sse; -#endif -} - -static int get_pred_buffer(PRED_BUFFER *p, int len) { - int i; - - for (i = 0; i < len; i++) { - if (!p[i].in_use) { - p[i].in_use = 1; - return i; - } - } - return -1; -} - -static void free_pred_buffer(PRED_BUFFER *p) { - if (p != NULL) p->in_use = 0; -} - -static void encode_breakout_test( - VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mi_row, int mi_col, - MV_REFERENCE_FRAME ref_frame, PREDICTION_MODE this_mode, unsigned int var_y, - unsigned int sse_y, struct buf_2d yv12_mb[][MAX_MB_PLANE], int *rate, - int64_t *dist, int *flag_preduv_computed) { - MACROBLOCKD *xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - const BLOCK_SIZE uv_size = get_plane_block_size(bsize, &xd->plane[1]); - unsigned int var = var_y, sse = sse_y; - // Skipping threshold for ac. - unsigned int thresh_ac; - // Skipping threshold for dc. - unsigned int thresh_dc; - int motion_low = 1; - - if (cpi->use_svc && ref_frame == GOLDEN_FRAME) return; - if (mi->mv[0].as_mv.row > 64 || mi->mv[0].as_mv.row < -64 || - mi->mv[0].as_mv.col > 64 || mi->mv[0].as_mv.col < -64) - motion_low = 0; - if (x->encode_breakout > 0 && motion_low == 1) { - // Set a maximum for threshold to avoid big PSNR loss in low bit rate - // case. Use extreme low threshold for static frames to limit - // skipping. - const unsigned int max_thresh = 36000; - // The encode_breakout input - const unsigned int min_thresh = - VPXMIN(((unsigned int)x->encode_breakout << 4), max_thresh); -#if CONFIG_VP9_HIGHBITDEPTH - const int shift = (xd->bd << 1) - 16; -#endif - - // Calculate threshold according to dequant value. - thresh_ac = (xd->plane[0].dequant[1] * xd->plane[0].dequant[1]) >> 3; -#if CONFIG_VP9_HIGHBITDEPTH - if ((xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) && shift > 0) { - thresh_ac = ROUND_POWER_OF_TWO(thresh_ac, shift); - } -#endif // CONFIG_VP9_HIGHBITDEPTH - thresh_ac = clamp(thresh_ac, min_thresh, max_thresh); - - // Adjust ac threshold according to partition size. - thresh_ac >>= - 8 - (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]); - - thresh_dc = (xd->plane[0].dequant[0] * xd->plane[0].dequant[0] >> 6); -#if CONFIG_VP9_HIGHBITDEPTH - if ((xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) && shift > 0) { - thresh_dc = ROUND_POWER_OF_TWO(thresh_dc, shift); - } -#endif // CONFIG_VP9_HIGHBITDEPTH - } else { - thresh_ac = 0; - thresh_dc = 0; - } - - // Y skipping condition checking for ac and dc. - if (var <= thresh_ac && (sse - var) <= thresh_dc) { - unsigned int sse_u, sse_v; - unsigned int var_u, var_v; - unsigned int thresh_ac_uv = thresh_ac; - unsigned int thresh_dc_uv = thresh_dc; - if (x->sb_is_skin) { - thresh_ac_uv = 0; - thresh_dc_uv = 0; - } - - if (!flag_preduv_computed[0] || !flag_preduv_computed[1]) { - xd->plane[1].pre[0] = yv12_mb[ref_frame][1]; - xd->plane[2].pre[0] = yv12_mb[ref_frame][2]; - vp9_build_inter_predictors_sbuv(xd, mi_row, mi_col, bsize); - } - - var_u = cpi->fn_ptr[uv_size].vf(x->plane[1].src.buf, x->plane[1].src.stride, - xd->plane[1].dst.buf, - xd->plane[1].dst.stride, &sse_u); - - // U skipping condition checking - if (((var_u << 2) <= thresh_ac_uv) && (sse_u - var_u <= thresh_dc_uv)) { - var_v = cpi->fn_ptr[uv_size].vf( - x->plane[2].src.buf, x->plane[2].src.stride, xd->plane[2].dst.buf, - xd->plane[2].dst.stride, &sse_v); - - // V skipping condition checking - if (((var_v << 2) <= thresh_ac_uv) && (sse_v - var_v <= thresh_dc_uv)) { - x->skip = 1; - - // The cost of skip bit needs to be added. - *rate = cpi->inter_mode_cost[x->mbmi_ext->mode_context[ref_frame]] - [INTER_OFFSET(this_mode)]; - - // More on this part of rate - // rate += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1); - - // Scaling factor for SSE from spatial domain to frequency - // domain is 16. Adjust distortion accordingly. - // TODO(yunqingwang): In this function, only y-plane dist is - // calculated. - *dist = (sse << 4); // + ((sse_u + sse_v) << 4); - - // *disable_skip = 1; - } - } - } -} - -struct estimate_block_intra_args { - VP9_COMP *cpi; - MACROBLOCK *x; - PREDICTION_MODE mode; - int skippable; - RD_COST *rdc; -}; - -static void estimate_block_intra(int plane, int block, int row, int col, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size, - void *arg) { - struct estimate_block_intra_args *const args = arg; - VP9_COMP *const cpi = args->cpi; - MACROBLOCK *const x = args->x; - MACROBLOCKD *const xd = &x->e_mbd; - struct macroblock_plane *const p = &x->plane[plane]; - struct macroblockd_plane *const pd = &xd->plane[plane]; - const BLOCK_SIZE bsize_tx = txsize_to_bsize[tx_size]; - uint8_t *const src_buf_base = p->src.buf; - uint8_t *const dst_buf_base = pd->dst.buf; - const int src_stride = p->src.stride; - const int dst_stride = pd->dst.stride; - RD_COST this_rdc; - - (void)block; - - p->src.buf = &src_buf_base[4 * (row * (int64_t)src_stride + col)]; - pd->dst.buf = &dst_buf_base[4 * (row * (int64_t)dst_stride + col)]; - // Use source buffer as an approximation for the fully reconstructed buffer. - vp9_predict_intra_block(xd, b_width_log2_lookup[plane_bsize], tx_size, - args->mode, x->skip_encode ? p->src.buf : pd->dst.buf, - x->skip_encode ? src_stride : dst_stride, pd->dst.buf, - dst_stride, col, row, plane); - - if (plane == 0) { - int64_t this_sse = INT64_MAX; - block_yrd(cpi, x, &this_rdc, &args->skippable, &this_sse, bsize_tx, - VPXMIN(tx_size, TX_16X16), 0, 1); - } else { - unsigned int var = 0; - unsigned int sse = 0; - model_rd_for_sb_uv(cpi, bsize_tx, x, xd, &this_rdc, &var, &sse, plane, - plane); - } - - p->src.buf = src_buf_base; - pd->dst.buf = dst_buf_base; - args->rdc->rate += this_rdc.rate; - args->rdc->dist += this_rdc.dist; -} - -static const THR_MODES mode_idx[MAX_REF_FRAMES][4] = { - { THR_DC, THR_V_PRED, THR_H_PRED, THR_TM }, - { THR_NEARESTMV, THR_NEARMV, THR_ZEROMV, THR_NEWMV }, - { THR_NEARESTG, THR_NEARG, THR_ZEROG, THR_NEWG }, - { THR_NEARESTA, THR_NEARA, THR_ZEROA, THR_NEWA }, -}; - -static const PREDICTION_MODE intra_mode_list[] = { DC_PRED, V_PRED, H_PRED, - TM_PRED }; - -static int mode_offset(const PREDICTION_MODE mode) { - if (mode >= NEARESTMV) { - return INTER_OFFSET(mode); - } else { - switch (mode) { - case DC_PRED: return 0; - case V_PRED: return 1; - case H_PRED: return 2; - case TM_PRED: return 3; - default: return -1; - } - } -} - -static INLINE int rd_less_than_thresh_row_mt(int64_t best_rd, int thresh, - const int *const thresh_fact) { - int is_rd_less_than_thresh; - is_rd_less_than_thresh = - best_rd < ((int64_t)thresh * (*thresh_fact) >> 5) || thresh == INT_MAX; - return is_rd_less_than_thresh; -} - -static INLINE void update_thresh_freq_fact_row_mt( - VP9_COMP *cpi, TileDataEnc *tile_data, unsigned int source_variance, - int thresh_freq_fact_idx, MV_REFERENCE_FRAME ref_frame, - THR_MODES best_mode_idx, PREDICTION_MODE mode) { - THR_MODES thr_mode_idx = mode_idx[ref_frame][mode_offset(mode)]; - int freq_fact_idx = thresh_freq_fact_idx + thr_mode_idx; - int *freq_fact = &tile_data->row_base_thresh_freq_fact[freq_fact_idx]; - if (thr_mode_idx == best_mode_idx) - *freq_fact -= (*freq_fact >> 4); - else if (cpi->sf.limit_newmv_early_exit && mode == NEWMV && - ref_frame == LAST_FRAME && source_variance < 5) { - *freq_fact = VPXMIN(*freq_fact + RD_THRESH_INC, 32); - } else { - *freq_fact = VPXMIN(*freq_fact + RD_THRESH_INC, - cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT); - } -} - -static INLINE void update_thresh_freq_fact( - VP9_COMP *cpi, TileDataEnc *tile_data, unsigned int source_variance, - BLOCK_SIZE bsize, MV_REFERENCE_FRAME ref_frame, THR_MODES best_mode_idx, - PREDICTION_MODE mode) { - THR_MODES thr_mode_idx = mode_idx[ref_frame][mode_offset(mode)]; - int *freq_fact = &tile_data->thresh_freq_fact[bsize][thr_mode_idx]; - if (thr_mode_idx == best_mode_idx) - *freq_fact -= (*freq_fact >> 4); - else if (cpi->sf.limit_newmv_early_exit && mode == NEWMV && - ref_frame == LAST_FRAME && source_variance < 5) { - *freq_fact = VPXMIN(*freq_fact + RD_THRESH_INC, 32); - } else { - *freq_fact = VPXMIN(*freq_fact + RD_THRESH_INC, - cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT); - } -} - -void vp9_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x, RD_COST *rd_cost, - BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx) { - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - RD_COST this_rdc, best_rdc; - PREDICTION_MODE this_mode; - struct estimate_block_intra_args args = { cpi, x, DC_PRED, 1, 0 }; - const TX_SIZE intra_tx_size = - VPXMIN(max_txsize_lookup[bsize], - tx_mode_to_biggest_tx_size[cpi->common.tx_mode]); - MODE_INFO *const mic = xd->mi[0]; - int *bmode_costs; - const MODE_INFO *above_mi = xd->above_mi; - const MODE_INFO *left_mi = xd->left_mi; - const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0); - const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0); - bmode_costs = cpi->y_mode_costs[A][L]; - - (void)ctx; - vp9_rd_cost_reset(&best_rdc); - vp9_rd_cost_reset(&this_rdc); - - mi->ref_frame[0] = INTRA_FRAME; - // Initialize interp_filter here so we do not have to check for inter block - // modes in get_pred_context_switchable_interp() - mi->interp_filter = SWITCHABLE_FILTERS; - - mi->mv[0].as_int = INVALID_MV; - mi->uv_mode = DC_PRED; - memset(x->skip_txfm, 0, sizeof(x->skip_txfm)); - - // Change the limit of this loop to add other intra prediction - // mode tests. - for (this_mode = DC_PRED; this_mode <= H_PRED; ++this_mode) { - this_rdc.dist = this_rdc.rate = 0; - args.mode = this_mode; - args.skippable = 1; - args.rdc = &this_rdc; - mi->tx_size = intra_tx_size; - vp9_foreach_transformed_block_in_plane(xd, bsize, 0, estimate_block_intra, - &args); - if (args.skippable) { - x->skip_txfm[0] = SKIP_TXFM_AC_DC; - this_rdc.rate = vp9_cost_bit(vp9_get_skip_prob(&cpi->common, xd), 1); - } else { - x->skip_txfm[0] = SKIP_TXFM_NONE; - this_rdc.rate += vp9_cost_bit(vp9_get_skip_prob(&cpi->common, xd), 0); - } - this_rdc.rate += bmode_costs[this_mode]; - this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist); - - if (this_rdc.rdcost < best_rdc.rdcost) { - best_rdc = this_rdc; - mi->mode = this_mode; - } - } - - *rd_cost = best_rdc; -} - -static void init_ref_frame_cost(VP9_COMMON *const cm, MACROBLOCKD *const xd, - int ref_frame_cost[MAX_REF_FRAMES]) { - vpx_prob intra_inter_p = vp9_get_intra_inter_prob(cm, xd); - vpx_prob ref_single_p1 = vp9_get_pred_prob_single_ref_p1(cm, xd); - vpx_prob ref_single_p2 = vp9_get_pred_prob_single_ref_p2(cm, xd); - - ref_frame_cost[INTRA_FRAME] = vp9_cost_bit(intra_inter_p, 0); - ref_frame_cost[LAST_FRAME] = ref_frame_cost[GOLDEN_FRAME] = - ref_frame_cost[ALTREF_FRAME] = vp9_cost_bit(intra_inter_p, 1); - - ref_frame_cost[LAST_FRAME] += vp9_cost_bit(ref_single_p1, 0); - ref_frame_cost[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p1, 1); - ref_frame_cost[ALTREF_FRAME] += vp9_cost_bit(ref_single_p1, 1); - ref_frame_cost[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p2, 0); - ref_frame_cost[ALTREF_FRAME] += vp9_cost_bit(ref_single_p2, 1); -} - -typedef struct { - MV_REFERENCE_FRAME ref_frame; - PREDICTION_MODE pred_mode; -} REF_MODE; - -#define RT_INTER_MODES 12 -static const REF_MODE ref_mode_set[RT_INTER_MODES] = { - { LAST_FRAME, ZEROMV }, { LAST_FRAME, NEARESTMV }, - { GOLDEN_FRAME, ZEROMV }, { LAST_FRAME, NEARMV }, - { LAST_FRAME, NEWMV }, { GOLDEN_FRAME, NEARESTMV }, - { GOLDEN_FRAME, NEARMV }, { GOLDEN_FRAME, NEWMV }, - { ALTREF_FRAME, ZEROMV }, { ALTREF_FRAME, NEARESTMV }, - { ALTREF_FRAME, NEARMV }, { ALTREF_FRAME, NEWMV } -}; - -#define RT_INTER_MODES_SVC 8 -static const REF_MODE ref_mode_set_svc[RT_INTER_MODES_SVC] = { - { LAST_FRAME, ZEROMV }, { LAST_FRAME, NEARESTMV }, - { LAST_FRAME, NEARMV }, { GOLDEN_FRAME, ZEROMV }, - { GOLDEN_FRAME, NEARESTMV }, { GOLDEN_FRAME, NEARMV }, - { LAST_FRAME, NEWMV }, { GOLDEN_FRAME, NEWMV } -}; - -static INLINE void find_predictors( - VP9_COMP *cpi, MACROBLOCK *x, MV_REFERENCE_FRAME ref_frame, - int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES], - int const_motion[MAX_REF_FRAMES], int *ref_frame_skip_mask, - TileDataEnc *tile_data, int mi_row, int mi_col, - struct buf_2d yv12_mb[4][MAX_MB_PLANE], BLOCK_SIZE bsize, - int force_skip_low_temp_var, int comp_pred_allowed) { - VP9_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &x->e_mbd; - const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame); - TileInfo *const tile_info = &tile_data->tile_info; - // TODO(jingning) placeholder for inter-frame non-RD mode decision. - x->pred_mv_sad[ref_frame] = INT_MAX; - frame_mv[NEWMV][ref_frame].as_int = INVALID_MV; - frame_mv[ZEROMV][ref_frame].as_int = 0; - // this needs various further optimizations. to be continued.. - if ((cpi->ref_frame_flags & ref_frame_to_flag(ref_frame)) && (yv12 != NULL)) { - int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame]; - const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf; - vp9_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf); - if (cm->use_prev_frame_mvs || comp_pred_allowed) { - vp9_find_mv_refs(cm, xd, xd->mi[0], ref_frame, candidates, mi_row, mi_col, - x->mbmi_ext->mode_context); - } else { - const_motion[ref_frame] = - mv_refs_rt(cpi, cm, x, xd, tile_info, xd->mi[0], ref_frame, - candidates, &frame_mv[NEWMV][ref_frame], mi_row, mi_col, - (int)(cpi->svc.use_base_mv && cpi->svc.spatial_layer_id)); - } - vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv, candidates, - &frame_mv[NEARESTMV][ref_frame], - &frame_mv[NEARMV][ref_frame]); - // Early exit for golden frame if force_skip_low_temp_var is set. - if (!vp9_is_scaled(sf) && bsize >= BLOCK_8X8 && - !(force_skip_low_temp_var && ref_frame == GOLDEN_FRAME)) { - vp9_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame, - bsize); - } - } else { - *ref_frame_skip_mask |= (1 << ref_frame); - } -} - -static void vp9_NEWMV_diff_bias(const NOISE_ESTIMATE *ne, MACROBLOCKD *xd, - PREDICTION_MODE this_mode, RD_COST *this_rdc, - BLOCK_SIZE bsize, int mv_row, int mv_col, - int is_last_frame, int lowvar_highsumdiff, - int is_skin) { - // Bias against MVs associated with NEWMV mode that are very different from - // top/left neighbors. - if (this_mode == NEWMV) { - int al_mv_average_row; - int al_mv_average_col; - int left_row, left_col; - int row_diff, col_diff; - int above_mv_valid = 0; - int left_mv_valid = 0; - int above_row = 0; - int above_col = 0; - - if (xd->above_mi) { - above_mv_valid = xd->above_mi->mv[0].as_int != INVALID_MV; - above_row = xd->above_mi->mv[0].as_mv.row; - above_col = xd->above_mi->mv[0].as_mv.col; - } - if (xd->left_mi) { - left_mv_valid = xd->left_mi->mv[0].as_int != INVALID_MV; - left_row = xd->left_mi->mv[0].as_mv.row; - left_col = xd->left_mi->mv[0].as_mv.col; - } - if (above_mv_valid && left_mv_valid) { - al_mv_average_row = (above_row + left_row + 1) >> 1; - al_mv_average_col = (above_col + left_col + 1) >> 1; - } else if (above_mv_valid) { - al_mv_average_row = above_row; - al_mv_average_col = above_col; - } else if (left_mv_valid) { - al_mv_average_row = left_row; - al_mv_average_col = left_col; - } else { - al_mv_average_row = al_mv_average_col = 0; - } - row_diff = (al_mv_average_row - mv_row); - col_diff = (al_mv_average_col - mv_col); - if (row_diff > 48 || row_diff < -48 || col_diff > 48 || col_diff < -48) { - if (bsize > BLOCK_32X32) - this_rdc->rdcost = this_rdc->rdcost << 1; - else - this_rdc->rdcost = 3 * this_rdc->rdcost >> 1; - } - } - // If noise estimation is enabled, and estimated level is above threshold, - // add a bias to LAST reference with small motion, for large blocks. - if (ne->enabled && ne->level >= kMedium && bsize >= BLOCK_32X32 && - is_last_frame && mv_row < 8 && mv_row > -8 && mv_col < 8 && mv_col > -8) - this_rdc->rdcost = 7 * (this_rdc->rdcost >> 3); - else if (lowvar_highsumdiff && !is_skin && bsize >= BLOCK_16X16 && - is_last_frame && mv_row < 16 && mv_row > -16 && mv_col < 16 && - mv_col > -16) - this_rdc->rdcost = 7 * (this_rdc->rdcost >> 3); -} - -#if CONFIG_VP9_TEMPORAL_DENOISING -static void vp9_pickmode_ctx_den_update( - VP9_PICKMODE_CTX_DEN *ctx_den, int64_t zero_last_cost_orig, - int ref_frame_cost[MAX_REF_FRAMES], - int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES], int reuse_inter_pred, - BEST_PICKMODE *bp) { - ctx_den->zero_last_cost_orig = zero_last_cost_orig; - ctx_den->ref_frame_cost = ref_frame_cost; - ctx_den->frame_mv = frame_mv; - ctx_den->reuse_inter_pred = reuse_inter_pred; - ctx_den->best_tx_size = bp->best_tx_size; - ctx_den->best_mode = bp->best_mode; - ctx_den->best_ref_frame = bp->best_ref_frame; - ctx_den->best_pred_filter = bp->best_pred_filter; - ctx_den->best_mode_skip_txfm = bp->best_mode_skip_txfm; -} - -static void recheck_zeromv_after_denoising( - VP9_COMP *cpi, MODE_INFO *const mi, MACROBLOCK *x, MACROBLOCKD *const xd, - VP9_DENOISER_DECISION decision, VP9_PICKMODE_CTX_DEN *ctx_den, - struct buf_2d yv12_mb[4][MAX_MB_PLANE], RD_COST *best_rdc, BLOCK_SIZE bsize, - int mi_row, int mi_col) { - // If INTRA or GOLDEN reference was selected, re-evaluate ZEROMV on - // denoised result. Only do this under noise conditions, and if rdcost of - // ZEROMV onoriginal source is not significantly higher than rdcost of best - // mode. - if (cpi->noise_estimate.enabled && cpi->noise_estimate.level > kLow && - ctx_den->zero_last_cost_orig < (best_rdc->rdcost << 3) && - ((ctx_den->best_ref_frame == INTRA_FRAME && decision >= FILTER_BLOCK) || - (ctx_den->best_ref_frame == GOLDEN_FRAME && - cpi->svc.number_spatial_layers == 1 && - decision == FILTER_ZEROMV_BLOCK))) { - // Check if we should pick ZEROMV on denoised signal. - VP9_COMMON *const cm = &cpi->common; - int rate = 0; - int64_t dist = 0; - uint32_t var_y = UINT_MAX; - uint32_t sse_y = UINT_MAX; - RD_COST this_rdc; - mi->mode = ZEROMV; - mi->ref_frame[0] = LAST_FRAME; - mi->ref_frame[1] = NO_REF_FRAME; - set_ref_ptrs(cm, xd, mi->ref_frame[0], NO_REF_FRAME); - mi->mv[0].as_int = 0; - mi->interp_filter = EIGHTTAP; - if (cpi->sf.default_interp_filter == BILINEAR) mi->interp_filter = BILINEAR; - xd->plane[0].pre[0] = yv12_mb[LAST_FRAME][0]; - vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize); - model_rd_for_sb_y(cpi, bsize, x, xd, &rate, &dist, &var_y, &sse_y, 0); - this_rdc.rate = rate + ctx_den->ref_frame_cost[LAST_FRAME] + - cpi->inter_mode_cost[x->mbmi_ext->mode_context[LAST_FRAME]] - [INTER_OFFSET(ZEROMV)]; - this_rdc.dist = dist; - this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, rate, dist); - // Don't switch to ZEROMV if the rdcost for ZEROMV on denoised source - // is higher than best_ref mode (on original source). - if (this_rdc.rdcost > best_rdc->rdcost) { - this_rdc = *best_rdc; - mi->mode = ctx_den->best_mode; - mi->ref_frame[0] = ctx_den->best_ref_frame; - set_ref_ptrs(cm, xd, mi->ref_frame[0], NO_REF_FRAME); - mi->interp_filter = ctx_den->best_pred_filter; - if (ctx_den->best_ref_frame == INTRA_FRAME) { - mi->mv[0].as_int = INVALID_MV; - mi->interp_filter = SWITCHABLE_FILTERS; - } else if (ctx_den->best_ref_frame == GOLDEN_FRAME) { - mi->mv[0].as_int = - ctx_den->frame_mv[ctx_den->best_mode][ctx_den->best_ref_frame] - .as_int; - if (ctx_den->reuse_inter_pred) { - xd->plane[0].pre[0] = yv12_mb[GOLDEN_FRAME][0]; - vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize); - } - } - mi->tx_size = ctx_den->best_tx_size; - x->skip_txfm[0] = ctx_den->best_mode_skip_txfm; - } else { - ctx_den->best_ref_frame = LAST_FRAME; - *best_rdc = this_rdc; - } - } -} -#endif // CONFIG_VP9_TEMPORAL_DENOISING - -static INLINE int get_force_skip_low_temp_var(uint8_t *variance_low, int mi_row, - int mi_col, BLOCK_SIZE bsize) { - const int i = (mi_row & 0x7) >> 1; - const int j = (mi_col & 0x7) >> 1; - int force_skip_low_temp_var = 0; - // Set force_skip_low_temp_var based on the block size and block offset. - if (bsize == BLOCK_64X64) { - force_skip_low_temp_var = variance_low[0]; - } else if (bsize == BLOCK_64X32) { - if (!(mi_col & 0x7) && !(mi_row & 0x7)) { - force_skip_low_temp_var = variance_low[1]; - } else if (!(mi_col & 0x7) && (mi_row & 0x7)) { - force_skip_low_temp_var = variance_low[2]; - } - } else if (bsize == BLOCK_32X64) { - if (!(mi_col & 0x7) && !(mi_row & 0x7)) { - force_skip_low_temp_var = variance_low[3]; - } else if ((mi_col & 0x7) && !(mi_row & 0x7)) { - force_skip_low_temp_var = variance_low[4]; - } - } else if (bsize == BLOCK_32X32) { - if (!(mi_col & 0x7) && !(mi_row & 0x7)) { - force_skip_low_temp_var = variance_low[5]; - } else if ((mi_col & 0x7) && !(mi_row & 0x7)) { - force_skip_low_temp_var = variance_low[6]; - } else if (!(mi_col & 0x7) && (mi_row & 0x7)) { - force_skip_low_temp_var = variance_low[7]; - } else if ((mi_col & 0x7) && (mi_row & 0x7)) { - force_skip_low_temp_var = variance_low[8]; - } - } else if (bsize == BLOCK_16X16) { - force_skip_low_temp_var = variance_low[pos_shift_16x16[i][j]]; - } else if (bsize == BLOCK_32X16) { - // The col shift index for the second 16x16 block. - const int j2 = ((mi_col + 2) & 0x7) >> 1; - // Only if each 16x16 block inside has low temporal variance. - force_skip_low_temp_var = variance_low[pos_shift_16x16[i][j]] && - variance_low[pos_shift_16x16[i][j2]]; - } else if (bsize == BLOCK_16X32) { - // The row shift index for the second 16x16 block. - const int i2 = ((mi_row + 2) & 0x7) >> 1; - force_skip_low_temp_var = variance_low[pos_shift_16x16[i][j]] && - variance_low[pos_shift_16x16[i2][j]]; - } - return force_skip_low_temp_var; -} - -static void search_filter_ref(VP9_COMP *cpi, MACROBLOCK *x, RD_COST *this_rdc, - int mi_row, int mi_col, PRED_BUFFER *tmp, - BLOCK_SIZE bsize, int reuse_inter_pred, - PRED_BUFFER **this_mode_pred, unsigned int *var_y, - unsigned int *sse_y, int force_smooth_filter, - int *this_early_term, int *flag_preduv_computed, - int use_model_yrd_large) { - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - struct macroblockd_plane *const pd = &xd->plane[0]; - const int bw = num_4x4_blocks_wide_lookup[bsize] << 2; - - int pf_rate[3] = { 0 }; - int64_t pf_dist[3] = { 0 }; - int curr_rate[3] = { 0 }; - unsigned int pf_var[3] = { 0 }; - unsigned int pf_sse[3] = { 0 }; - TX_SIZE pf_tx_size[3] = { 0 }; - int64_t best_cost = INT64_MAX; - INTERP_FILTER best_filter = SWITCHABLE, filter; - PRED_BUFFER *current_pred = *this_mode_pred; - uint8_t skip_txfm = SKIP_TXFM_NONE; - int best_early_term = 0; - int best_flag_preduv_computed[2] = { 0 }; - INTERP_FILTER filter_start = force_smooth_filter ? EIGHTTAP_SMOOTH : EIGHTTAP; - INTERP_FILTER filter_end = EIGHTTAP_SMOOTH; - for (filter = filter_start; filter <= filter_end; ++filter) { - int64_t cost; - mi->interp_filter = filter; - vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize); - // For large partition blocks, extra testing is done. - if (use_model_yrd_large) - model_rd_for_sb_y_large(cpi, bsize, x, xd, &pf_rate[filter], - &pf_dist[filter], &pf_var[filter], - &pf_sse[filter], mi_row, mi_col, this_early_term, - flag_preduv_computed); - else - model_rd_for_sb_y(cpi, bsize, x, xd, &pf_rate[filter], &pf_dist[filter], - &pf_var[filter], &pf_sse[filter], 0); - curr_rate[filter] = pf_rate[filter]; - pf_rate[filter] += vp9_get_switchable_rate(cpi, xd); - cost = RDCOST(x->rdmult, x->rddiv, pf_rate[filter], pf_dist[filter]); - pf_tx_size[filter] = mi->tx_size; - if (cost < best_cost) { - best_filter = filter; - best_cost = cost; - skip_txfm = x->skip_txfm[0]; - best_early_term = *this_early_term; - best_flag_preduv_computed[0] = flag_preduv_computed[0]; - best_flag_preduv_computed[1] = flag_preduv_computed[1]; - - if (reuse_inter_pred) { - if (*this_mode_pred != current_pred) { - free_pred_buffer(*this_mode_pred); - *this_mode_pred = current_pred; - } - if (filter != filter_end) { - current_pred = &tmp[get_pred_buffer(tmp, 3)]; - pd->dst.buf = current_pred->data; - pd->dst.stride = bw; - } - } - } - } - - if (reuse_inter_pred && *this_mode_pred != current_pred) - free_pred_buffer(current_pred); - - mi->interp_filter = best_filter; - mi->tx_size = pf_tx_size[best_filter]; - this_rdc->rate = curr_rate[best_filter]; - this_rdc->dist = pf_dist[best_filter]; - *var_y = pf_var[best_filter]; - *sse_y = pf_sse[best_filter]; - x->skip_txfm[0] = skip_txfm; - *this_early_term = best_early_term; - flag_preduv_computed[0] = best_flag_preduv_computed[0]; - flag_preduv_computed[1] = best_flag_preduv_computed[1]; - if (reuse_inter_pred) { - pd->dst.buf = (*this_mode_pred)->data; - pd->dst.stride = (*this_mode_pred)->stride; - } else if (best_filter < filter_end) { - mi->interp_filter = best_filter; - vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize); - } -} - -static int search_new_mv(VP9_COMP *cpi, MACROBLOCK *x, - int_mv frame_mv[][MAX_REF_FRAMES], - MV_REFERENCE_FRAME ref_frame, int gf_temporal_ref, - BLOCK_SIZE bsize, int mi_row, int mi_col, - int best_pred_sad, int *rate_mv, - unsigned int best_sse_sofar, RD_COST *best_rdc) { - SVC *const svc = &cpi->svc; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - SPEED_FEATURES *const sf = &cpi->sf; - - if (ref_frame > LAST_FRAME && gf_temporal_ref && - cpi->oxcf.rc_mode == VPX_CBR) { - int tmp_sad; - uint32_t dis; - int cost_list[5] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX }; - - if (bsize < BLOCK_16X16) return -1; - - tmp_sad = vp9_int_pro_motion_estimation( - cpi, x, bsize, mi_row, mi_col, - &x->mbmi_ext->ref_mvs[ref_frame][0].as_mv); - - if (tmp_sad > x->pred_mv_sad[LAST_FRAME]) return -1; - if (tmp_sad + (num_pels_log2_lookup[bsize] << 4) > best_pred_sad) return -1; - - frame_mv[NEWMV][ref_frame].as_int = mi->mv[0].as_int; - *rate_mv = vp9_mv_bit_cost(&frame_mv[NEWMV][ref_frame].as_mv, - &x->mbmi_ext->ref_mvs[ref_frame][0].as_mv, - x->nmvjointcost, x->mvcost, MV_COST_WEIGHT); - frame_mv[NEWMV][ref_frame].as_mv.row >>= 3; - frame_mv[NEWMV][ref_frame].as_mv.col >>= 3; - - cpi->find_fractional_mv_step( - x, &frame_mv[NEWMV][ref_frame].as_mv, - &x->mbmi_ext->ref_mvs[ref_frame][0].as_mv, - cpi->common.allow_high_precision_mv, x->errorperbit, - &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop, - cpi->sf.mv.subpel_search_level, cond_cost_list(cpi, cost_list), - x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref_frame], NULL, 0, 0, - cpi->sf.use_accurate_subpel_search); - } else if (svc->use_base_mv && svc->spatial_layer_id) { - if (frame_mv[NEWMV][ref_frame].as_int != INVALID_MV) { - const int pre_stride = xd->plane[0].pre[0].stride; - unsigned int base_mv_sse = UINT_MAX; - int scale = (cpi->rc.avg_frame_low_motion > 60) ? 2 : 4; - const uint8_t *const pre_buf = - xd->plane[0].pre[0].buf + - (frame_mv[NEWMV][ref_frame].as_mv.row >> 3) * pre_stride + - (frame_mv[NEWMV][ref_frame].as_mv.col >> 3); - cpi->fn_ptr[bsize].vf(x->plane[0].src.buf, x->plane[0].src.stride, - pre_buf, pre_stride, &base_mv_sse); - - // Exit NEWMV search if base_mv is (0,0) && bsize < BLOCK_16x16, - // for SVC encoding. - if (cpi->use_svc && svc->use_base_mv && bsize < BLOCK_16X16 && - frame_mv[NEWMV][ref_frame].as_mv.row == 0 && - frame_mv[NEWMV][ref_frame].as_mv.col == 0) - return -1; - - // Exit NEWMV search if base_mv_sse is large. - if (sf->base_mv_aggressive && (base_mv_sse >> scale) > best_sse_sofar) - return -1; - if ((base_mv_sse >> 1) < best_sse_sofar) { - // Base layer mv is good. - // Exit NEWMV search if the base_mv is (0, 0) and sse is low, since - // (0, 0) mode is already tested. - unsigned int base_mv_sse_normalized = - base_mv_sse >> - (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]); - if (sf->base_mv_aggressive && base_mv_sse <= best_sse_sofar && - base_mv_sse_normalized < 400 && - frame_mv[NEWMV][ref_frame].as_mv.row == 0 && - frame_mv[NEWMV][ref_frame].as_mv.col == 0) - return -1; - if (!combined_motion_search(cpi, x, bsize, mi_row, mi_col, - &frame_mv[NEWMV][ref_frame], rate_mv, - best_rdc->rdcost, 1)) { - return -1; - } - } else if (!combined_motion_search(cpi, x, bsize, mi_row, mi_col, - &frame_mv[NEWMV][ref_frame], rate_mv, - best_rdc->rdcost, 0)) { - return -1; - } - } else if (!combined_motion_search(cpi, x, bsize, mi_row, mi_col, - &frame_mv[NEWMV][ref_frame], rate_mv, - best_rdc->rdcost, 0)) { - return -1; - } - } else if (!combined_motion_search(cpi, x, bsize, mi_row, mi_col, - &frame_mv[NEWMV][ref_frame], rate_mv, - best_rdc->rdcost, 0)) { - return -1; - } - - return 0; -} - -static INLINE void init_best_pickmode(BEST_PICKMODE *bp) { - bp->best_mode = ZEROMV; - bp->best_ref_frame = LAST_FRAME; - bp->best_tx_size = TX_SIZES; - bp->best_intra_tx_size = TX_SIZES; - bp->best_pred_filter = EIGHTTAP; - bp->best_mode_skip_txfm = SKIP_TXFM_NONE; - bp->best_second_ref_frame = NO_REF_FRAME; - bp->best_pred = NULL; -} - -void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, - int mi_row, int mi_col, RD_COST *rd_cost, - BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx) { - VP9_COMMON *const cm = &cpi->common; - SPEED_FEATURES *const sf = &cpi->sf; - SVC *const svc = &cpi->svc; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - struct macroblockd_plane *const pd = &xd->plane[0]; - - BEST_PICKMODE best_pickmode; - - MV_REFERENCE_FRAME ref_frame; - MV_REFERENCE_FRAME usable_ref_frame, second_ref_frame; - int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES]; - uint8_t mode_checked[MB_MODE_COUNT][MAX_REF_FRAMES]; - struct buf_2d yv12_mb[4][MAX_MB_PLANE] = { 0 }; - RD_COST this_rdc, best_rdc; - // var_y and sse_y are saved to be used in skipping checking - unsigned int var_y = UINT_MAX; - unsigned int sse_y = UINT_MAX; - const int intra_cost_penalty = - vp9_get_intra_cost_penalty(cpi, bsize, cm->base_qindex, cm->y_dc_delta_q); - int64_t inter_mode_thresh = - RDCOST(x->rdmult, x->rddiv, intra_cost_penalty, 0); - const int *const rd_threshes = cpi->rd.threshes[mi->segment_id][bsize]; - const int sb_row = mi_row >> MI_BLOCK_SIZE_LOG2; - int thresh_freq_fact_idx = (sb_row * BLOCK_SIZES + bsize) * MAX_MODES; - const int *const rd_thresh_freq_fact = - (cpi->sf.adaptive_rd_thresh_row_mt) - ? &(tile_data->row_base_thresh_freq_fact[thresh_freq_fact_idx]) - : tile_data->thresh_freq_fact[bsize]; -#if CONFIG_VP9_TEMPORAL_DENOISING - const int denoise_recheck_zeromv = 1; -#endif - INTERP_FILTER filter_ref; - int pred_filter_search = cm->interp_filter == SWITCHABLE; - int const_motion[MAX_REF_FRAMES] = { 0 }; - const int bh = num_4x4_blocks_high_lookup[bsize] << 2; - const int bw = num_4x4_blocks_wide_lookup[bsize] << 2; - // For speed 6, the result of interp filter is reused later in actual encoding - // process. - // tmp[3] points to dst buffer, and the other 3 point to allocated buffers. - PRED_BUFFER tmp[4]; - DECLARE_ALIGNED(16, uint8_t, pred_buf[3 * 64 * 64] VPX_UNINITIALIZED); -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, pred_buf_16[3 * 64 * 64] VPX_UNINITIALIZED); -#endif - struct buf_2d orig_dst = pd->dst; - PRED_BUFFER *this_mode_pred = NULL; - const int pixels_in_block = bh * bw; - int reuse_inter_pred = cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready; - int ref_frame_skip_mask = 0; - int idx; - int best_pred_sad = INT_MAX; - int best_early_term = 0; - int ref_frame_cost[MAX_REF_FRAMES]; - int svc_force_zero_mode[3] = { 0 }; - int perform_intra_pred = 1; - int use_golden_nonzeromv = 1; - int force_skip_low_temp_var = 0; - int skip_ref_find_pred[4] = { 0 }; - unsigned int sse_zeromv_normalized = UINT_MAX; - unsigned int best_sse_sofar = UINT_MAX; - int gf_temporal_ref = 0; - int force_test_gf_zeromv = 0; -#if CONFIG_VP9_TEMPORAL_DENOISING - VP9_PICKMODE_CTX_DEN ctx_den; - int64_t zero_last_cost_orig = INT64_MAX; - int denoise_svc_pickmode = 1; -#endif - INTERP_FILTER filter_gf_svc = EIGHTTAP; - MV_REFERENCE_FRAME inter_layer_ref = GOLDEN_FRAME; - const struct segmentation *const seg = &cm->seg; - int comp_modes = 0; - int num_inter_modes = (cpi->use_svc) ? RT_INTER_MODES_SVC : RT_INTER_MODES; - int flag_svc_subpel = 0; - int svc_mv_col = 0; - int svc_mv_row = 0; - int no_scaling = 0; - int large_block = 0; - int use_model_yrd_large = 0; - unsigned int thresh_svc_skip_golden = 500; - unsigned int thresh_skip_golden = 500; - int force_smooth_filter = cpi->sf.force_smooth_interpol; - int scene_change_detected = - cpi->rc.high_source_sad || - (cpi->use_svc && cpi->svc.high_source_sad_superframe); - - init_best_pickmode(&best_pickmode); - - x->encode_breakout = seg->enabled - ? cpi->segment_encode_breakout[mi->segment_id] - : cpi->encode_breakout; - - x->source_variance = UINT_MAX; - if (cpi->sf.default_interp_filter == BILINEAR) { - best_pickmode.best_pred_filter = BILINEAR; - filter_gf_svc = BILINEAR; - } - if (cpi->use_svc && svc->spatial_layer_id > 0) { - int layer = - LAYER_IDS_TO_IDX(svc->spatial_layer_id - 1, svc->temporal_layer_id, - svc->number_temporal_layers); - LAYER_CONTEXT *const lc = &svc->layer_context[layer]; - if (lc->scaling_factor_num == lc->scaling_factor_den) no_scaling = 1; - } - if (svc->spatial_layer_id > 0 && - (svc->high_source_sad_superframe || no_scaling)) - thresh_svc_skip_golden = 0; - // Lower the skip threshold if lower spatial layer is better quality relative - // to current layer. - else if (svc->spatial_layer_id > 0 && cm->base_qindex > 150 && - cm->base_qindex > svc->lower_layer_qindex + 15) - thresh_svc_skip_golden = 100; - // Increase skip threshold if lower spatial layer is lower quality relative - // to current layer. - else if (svc->spatial_layer_id > 0 && cm->base_qindex < 140 && - cm->base_qindex < svc->lower_layer_qindex - 20) - thresh_svc_skip_golden = 1000; - - if (!cpi->use_svc || - (svc->use_gf_temporal_ref_current_layer && - !svc->layer_context[svc->temporal_layer_id].is_key_frame)) { - struct scale_factors *const sf_last = &cm->frame_refs[LAST_FRAME - 1].sf; - struct scale_factors *const sf_golden = - &cm->frame_refs[GOLDEN_FRAME - 1].sf; - gf_temporal_ref = 1; - // For temporal long term prediction, check that the golden reference - // is same scale as last reference, otherwise disable. - if ((sf_last->x_scale_fp != sf_golden->x_scale_fp) || - (sf_last->y_scale_fp != sf_golden->y_scale_fp)) { - gf_temporal_ref = 0; - } else { - if (cpi->rc.avg_frame_low_motion > 70) - thresh_svc_skip_golden = 500; - else - thresh_svc_skip_golden = 0; - } - } - - init_ref_frame_cost(cm, xd, ref_frame_cost); - memset(&mode_checked[0][0], 0, MB_MODE_COUNT * MAX_REF_FRAMES); - - if (reuse_inter_pred) { - int i; - for (i = 0; i < 3; i++) { -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) - tmp[i].data = CONVERT_TO_BYTEPTR(&pred_buf_16[pixels_in_block * i]); - else - tmp[i].data = &pred_buf[pixels_in_block * i]; -#else - tmp[i].data = &pred_buf[pixels_in_block * i]; -#endif // CONFIG_VP9_HIGHBITDEPTH - tmp[i].stride = bw; - tmp[i].in_use = 0; - } - tmp[3].data = pd->dst.buf; - tmp[3].stride = pd->dst.stride; - tmp[3].in_use = 0; - } - - x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH; - x->skip = 0; - - if (cpi->sf.cb_pred_filter_search) { - const int bsl = mi_width_log2_lookup[bsize]; - pred_filter_search = cm->interp_filter == SWITCHABLE - ? (((mi_row + mi_col) >> bsl) + - get_chessboard_index(cm->current_video_frame)) & - 0x1 - : 0; - } - // Instead of using vp9_get_pred_context_switchable_interp(xd) to assign - // filter_ref, we use a less strict condition on assigning filter_ref. - // This is to reduce the probabily of entering the flow of not assigning - // filter_ref and then skip filter search. - filter_ref = cm->interp_filter; - if (cpi->sf.default_interp_filter != BILINEAR) { - if (xd->above_mi && is_inter_block(xd->above_mi)) - filter_ref = xd->above_mi->interp_filter; - else if (xd->left_mi && is_inter_block(xd->left_mi)) - filter_ref = xd->left_mi->interp_filter; - } - - // initialize mode decisions - vp9_rd_cost_reset(&best_rdc); - vp9_rd_cost_reset(rd_cost); - mi->sb_type = bsize; - mi->ref_frame[0] = NO_REF_FRAME; - mi->ref_frame[1] = NO_REF_FRAME; - - mi->tx_size = - VPXMIN(max_txsize_lookup[bsize], tx_mode_to_biggest_tx_size[cm->tx_mode]); - - if (sf->short_circuit_flat_blocks || sf->limit_newmv_early_exit) { -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) - x->source_variance = vp9_high_get_sby_perpixel_variance( - cpi, &x->plane[0].src, bsize, xd->bd); - else -#endif // CONFIG_VP9_HIGHBITDEPTH - x->source_variance = - vp9_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize); - - if (cpi->oxcf.content == VP9E_CONTENT_SCREEN && - cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && mi->segment_id > 0 && - x->zero_temp_sad_source && x->source_variance == 0) { - mi->segment_id = 0; - vp9_init_plane_quantizers(cpi, x); - } - } - -#if CONFIG_VP9_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity > 0) { - if (cpi->use_svc) denoise_svc_pickmode = vp9_denoise_svc_non_key(cpi); - if (cpi->denoiser.denoising_level > kDenLowLow && denoise_svc_pickmode) - vp9_denoiser_reset_frame_stats(ctx); - } -#endif - - if (cpi->rc.frames_since_golden == 0 && gf_temporal_ref && - !cpi->rc.alt_ref_gf_group && !cpi->rc.last_frame_is_src_altref) { - usable_ref_frame = LAST_FRAME; - } else { - usable_ref_frame = GOLDEN_FRAME; - } - - if (cpi->oxcf.lag_in_frames > 0 && cpi->oxcf.rc_mode == VPX_VBR) { - if (cpi->rc.alt_ref_gf_group || cpi->rc.is_src_frame_alt_ref) - usable_ref_frame = ALTREF_FRAME; - - if (cpi->rc.is_src_frame_alt_ref) { - skip_ref_find_pred[LAST_FRAME] = 1; - skip_ref_find_pred[GOLDEN_FRAME] = 1; - } - if (!cm->show_frame) { - if (cpi->rc.frames_since_key == 1) { - usable_ref_frame = LAST_FRAME; - skip_ref_find_pred[GOLDEN_FRAME] = 1; - skip_ref_find_pred[ALTREF_FRAME] = 1; - } - } - } - - // For svc mode, on spatial_layer_id > 0: if the reference has different scale - // constrain the inter mode to only test zero motion. - if (cpi->use_svc && svc->force_zero_mode_spatial_ref && - svc->spatial_layer_id > 0 && !gf_temporal_ref) { - if (cpi->ref_frame_flags & VP9_LAST_FLAG) { - struct scale_factors *const ref_sf = &cm->frame_refs[LAST_FRAME - 1].sf; - if (vp9_is_scaled(ref_sf)) { - svc_force_zero_mode[LAST_FRAME - 1] = 1; - inter_layer_ref = LAST_FRAME; - } - } - if (cpi->ref_frame_flags & VP9_GOLD_FLAG) { - struct scale_factors *const ref_sf = &cm->frame_refs[GOLDEN_FRAME - 1].sf; - if (vp9_is_scaled(ref_sf)) { - svc_force_zero_mode[GOLDEN_FRAME - 1] = 1; - inter_layer_ref = GOLDEN_FRAME; - } - } - } - - if (cpi->sf.short_circuit_low_temp_var) { - force_skip_low_temp_var = - get_force_skip_low_temp_var(&x->variance_low[0], mi_row, mi_col, bsize); - // If force_skip_low_temp_var is set, and for short circuit mode = 1 and 3, - // skip golden reference. - if ((cpi->sf.short_circuit_low_temp_var == 1 || - cpi->sf.short_circuit_low_temp_var == 3) && - force_skip_low_temp_var) { - usable_ref_frame = LAST_FRAME; - } - } - - if (sf->disable_golden_ref && (x->content_state_sb != kVeryHighSad || - cpi->rc.avg_frame_low_motion < 60)) - usable_ref_frame = LAST_FRAME; - - if (!((cpi->ref_frame_flags & VP9_GOLD_FLAG) && - !svc_force_zero_mode[GOLDEN_FRAME - 1] && !force_skip_low_temp_var)) - use_golden_nonzeromv = 0; - - if (cpi->oxcf.speed >= 8 && !cpi->use_svc && - ((cpi->rc.frames_since_golden + 1) < x->last_sb_high_content || - x->last_sb_high_content > 40 || cpi->rc.frames_since_golden > 120)) - usable_ref_frame = LAST_FRAME; - - // Compound prediction modes: (0,0) on LAST/GOLDEN and ARF. - if (cm->reference_mode == REFERENCE_MODE_SELECT && - cpi->sf.use_compound_nonrd_pickmode && usable_ref_frame == ALTREF_FRAME) - comp_modes = 2; - - // If the segment reference frame feature is enabled and it's set to GOLDEN - // reference, then make sure we don't skip checking GOLDEN, this is to - // prevent possibility of not picking any mode. - if (segfeature_active(seg, mi->segment_id, SEG_LVL_REF_FRAME) && - get_segdata(seg, mi->segment_id, SEG_LVL_REF_FRAME) == GOLDEN_FRAME) { - usable_ref_frame = GOLDEN_FRAME; - skip_ref_find_pred[GOLDEN_FRAME] = 0; - thresh_svc_skip_golden = 0; - } - - for (ref_frame = LAST_FRAME; ref_frame <= usable_ref_frame; ++ref_frame) { - // Skip find_predictor if the reference frame is not in the - // ref_frame_flags (i.e., not used as a reference for this frame). - skip_ref_find_pred[ref_frame] = - !(cpi->ref_frame_flags & ref_frame_to_flag(ref_frame)); - if (!skip_ref_find_pred[ref_frame]) { - find_predictors(cpi, x, ref_frame, frame_mv, const_motion, - &ref_frame_skip_mask, tile_data, mi_row, mi_col, yv12_mb, - bsize, force_skip_low_temp_var, comp_modes > 0); - } - } - - if (cpi->use_svc || cpi->oxcf.speed <= 7 || bsize < BLOCK_32X32) - x->sb_use_mv_part = 0; - - // Set the flag_svc_subpel to 1 for SVC if the lower spatial layer used - // an averaging filter for downsampling (phase = 8). If so, we will test - // a nonzero motion mode on the spatial reference. - // The nonzero motion is half pixel shifted to left and top (-4, -4). - if (cpi->use_svc && svc->spatial_layer_id > 0 && - svc_force_zero_mode[inter_layer_ref - 1] && - svc->downsample_filter_phase[svc->spatial_layer_id - 1] == 8 && - !gf_temporal_ref) { - svc_mv_col = -4; - svc_mv_row = -4; - flag_svc_subpel = 1; - } - - // For SVC with quality layers, when QP of lower layer is lower - // than current layer: force check of GF-ZEROMV before early exit - // due to skip flag. - if (svc->spatial_layer_id > 0 && no_scaling && - (cpi->ref_frame_flags & VP9_GOLD_FLAG) && - cm->base_qindex > svc->lower_layer_qindex + 10) - force_test_gf_zeromv = 1; - - // For low motion content use x->sb_is_skin in addition to VeryHighSad - // for setting large_block. - large_block = (x->content_state_sb == kVeryHighSad || - (x->sb_is_skin && cpi->rc.avg_frame_low_motion > 70) || - cpi->oxcf.speed < 7) - ? bsize > BLOCK_32X32 - : bsize >= BLOCK_32X32; - use_model_yrd_large = - cpi->oxcf.rc_mode == VPX_CBR && large_block && - !cyclic_refresh_segment_id_boosted(xd->mi[0]->segment_id) && - cm->base_qindex; - - for (idx = 0; idx < num_inter_modes + comp_modes; ++idx) { - int rate_mv = 0; - int mode_rd_thresh; - int mode_index; - int i; - int64_t this_sse; - int is_skippable; - int this_early_term = 0; - int rd_computed = 0; - int flag_preduv_computed[2] = { 0 }; - int inter_mv_mode = 0; - int skip_this_mv = 0; - int comp_pred = 0; - int force_mv_inter_layer = 0; - PREDICTION_MODE this_mode; - second_ref_frame = NO_REF_FRAME; - - if (idx < num_inter_modes) { - this_mode = ref_mode_set[idx].pred_mode; - ref_frame = ref_mode_set[idx].ref_frame; - - if (cpi->use_svc) { - this_mode = ref_mode_set_svc[idx].pred_mode; - ref_frame = ref_mode_set_svc[idx].ref_frame; - } - } else { - // Add (0,0) compound modes. - this_mode = ZEROMV; - ref_frame = LAST_FRAME; - if (idx == num_inter_modes + comp_modes - 1) ref_frame = GOLDEN_FRAME; - second_ref_frame = ALTREF_FRAME; - comp_pred = 1; - } - - if (ref_frame > usable_ref_frame) continue; - if (skip_ref_find_pred[ref_frame]) continue; - - if (svc->previous_frame_is_intra_only) { - if (ref_frame != LAST_FRAME || frame_mv[this_mode][ref_frame].as_int != 0) - continue; - } - - // If the segment reference frame feature is enabled then do nothing if the - // current ref frame is not allowed. - if (segfeature_active(seg, mi->segment_id, SEG_LVL_REF_FRAME) && - get_segdata(seg, mi->segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) - continue; - - if (flag_svc_subpel && ref_frame == inter_layer_ref) { - force_mv_inter_layer = 1; - // Only test mode if NEARESTMV/NEARMV is (svc_mv_col, svc_mv_row), - // otherwise set NEWMV to (svc_mv_col, svc_mv_row). - if (this_mode == NEWMV) { - frame_mv[this_mode][ref_frame].as_mv.col = svc_mv_col; - frame_mv[this_mode][ref_frame].as_mv.row = svc_mv_row; - } else if (frame_mv[this_mode][ref_frame].as_mv.col != svc_mv_col || - frame_mv[this_mode][ref_frame].as_mv.row != svc_mv_row) { - continue; - } - } - - if (comp_pred) { - if (!cpi->allow_comp_inter_inter) continue; - // Skip compound inter modes if ARF is not available. - if (!(cpi->ref_frame_flags & ref_frame_to_flag(second_ref_frame))) - continue; - // Do not allow compound prediction if the segment level reference frame - // feature is in use as in this case there can only be one reference. - if (segfeature_active(seg, mi->segment_id, SEG_LVL_REF_FRAME)) continue; - } - - // For CBR mode: skip the golden reference search if sse of zeromv_last is - // below threshold. - if (ref_frame == GOLDEN_FRAME && cpi->oxcf.rc_mode == VPX_CBR && - ((cpi->use_svc && sse_zeromv_normalized < thresh_svc_skip_golden) || - (!cpi->use_svc && sse_zeromv_normalized < thresh_skip_golden))) - continue; - - if (!(cpi->ref_frame_flags & ref_frame_to_flag(ref_frame))) continue; - - // For screen content. If zero_temp_sad source is computed: skip - // non-zero motion check for stationary blocks. If the superblock is - // non-stationary then for flat blocks skip the zero last check (keep golden - // as it may be inter-layer reference). Otherwise (if zero_temp_sad_source - // is not computed) skip non-zero motion check for flat blocks. - // TODO(marpan): Compute zero_temp_sad_source per coding block. - if (cpi->oxcf.content == VP9E_CONTENT_SCREEN) { - if (cpi->compute_source_sad_onepass && cpi->sf.use_source_sad) { - if ((frame_mv[this_mode][ref_frame].as_int != 0 && - x->zero_temp_sad_source) || - (frame_mv[this_mode][ref_frame].as_int == 0 && - x->source_variance == 0 && ref_frame == LAST_FRAME && - !x->zero_temp_sad_source)) - continue; - } else if (frame_mv[this_mode][ref_frame].as_int != 0 && - x->source_variance == 0) { - continue; - } - } - - if (!(cpi->sf.inter_mode_mask[bsize] & (1 << this_mode))) continue; - - if (cpi->oxcf.lag_in_frames > 0 && cpi->oxcf.rc_mode == VPX_VBR) { - if (cpi->rc.is_src_frame_alt_ref && - (ref_frame != ALTREF_FRAME || - frame_mv[this_mode][ref_frame].as_int != 0)) - continue; - - if (!cm->show_frame && ref_frame == ALTREF_FRAME && - frame_mv[this_mode][ref_frame].as_int != 0) - continue; - - if (cpi->rc.alt_ref_gf_group && cm->show_frame && - cpi->rc.frames_since_golden > (cpi->rc.baseline_gf_interval >> 1) && - ref_frame == GOLDEN_FRAME && - frame_mv[this_mode][ref_frame].as_int != 0) - continue; - - if (cpi->rc.alt_ref_gf_group && cm->show_frame && - cpi->rc.frames_since_golden > 0 && - cpi->rc.frames_since_golden < (cpi->rc.baseline_gf_interval >> 1) && - ref_frame == ALTREF_FRAME && - frame_mv[this_mode][ref_frame].as_int != 0) - continue; - } - - if (const_motion[ref_frame] && this_mode == NEARMV) continue; - - // Skip non-zeromv mode search for golden frame if force_skip_low_temp_var - // is set. If nearestmv for golden frame is 0, zeromv mode will be skipped - // later. - if (!force_mv_inter_layer && force_skip_low_temp_var && - ref_frame == GOLDEN_FRAME && - frame_mv[this_mode][ref_frame].as_int != 0) { - continue; - } - - if (x->content_state_sb != kVeryHighSad && - (cpi->sf.short_circuit_low_temp_var >= 2 || - (cpi->sf.short_circuit_low_temp_var == 1 && bsize == BLOCK_64X64)) && - force_skip_low_temp_var && ref_frame == LAST_FRAME && - this_mode == NEWMV) { - continue; - } - - if (cpi->use_svc) { - if (!force_mv_inter_layer && svc_force_zero_mode[ref_frame - 1] && - frame_mv[this_mode][ref_frame].as_int != 0) - continue; - } - - // Disable this drop out case if the ref frame segment level feature is - // enabled for this segment. This is to prevent the possibility that we end - // up unable to pick any mode. - if (!segfeature_active(seg, mi->segment_id, SEG_LVL_REF_FRAME)) { - if (sf->reference_masking && - !(frame_mv[this_mode][ref_frame].as_int == 0 && - ref_frame == LAST_FRAME)) { - if (usable_ref_frame < ALTREF_FRAME) { - if (!force_skip_low_temp_var && usable_ref_frame > LAST_FRAME) { - i = (ref_frame == LAST_FRAME) ? GOLDEN_FRAME : LAST_FRAME; - if ((cpi->ref_frame_flags & ref_frame_to_flag(i))) - if (x->pred_mv_sad[ref_frame] > (x->pred_mv_sad[i] << 1)) - ref_frame_skip_mask |= (1 << ref_frame); - } - } else if (!cpi->rc.is_src_frame_alt_ref && - !(frame_mv[this_mode][ref_frame].as_int == 0 && - ref_frame == ALTREF_FRAME)) { - int ref1 = (ref_frame == GOLDEN_FRAME) ? LAST_FRAME : GOLDEN_FRAME; - int ref2 = (ref_frame == ALTREF_FRAME) ? LAST_FRAME : ALTREF_FRAME; - if (((cpi->ref_frame_flags & ref_frame_to_flag(ref1)) && - (x->pred_mv_sad[ref_frame] > (x->pred_mv_sad[ref1] << 1))) || - ((cpi->ref_frame_flags & ref_frame_to_flag(ref2)) && - (x->pred_mv_sad[ref_frame] > (x->pred_mv_sad[ref2] << 1)))) - ref_frame_skip_mask |= (1 << ref_frame); - } - } - if (ref_frame_skip_mask & (1 << ref_frame)) continue; - } - - // Select prediction reference frames. - for (i = 0; i < MAX_MB_PLANE; i++) { - xd->plane[i].pre[0] = yv12_mb[ref_frame][i]; - if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i]; - } - - mi->ref_frame[0] = ref_frame; - mi->ref_frame[1] = second_ref_frame; - set_ref_ptrs(cm, xd, ref_frame, second_ref_frame); - - mode_index = mode_idx[ref_frame][INTER_OFFSET(this_mode)]; - mode_rd_thresh = best_pickmode.best_mode_skip_txfm - ? rd_threshes[mode_index] << 1 - : rd_threshes[mode_index]; - - // Increase mode_rd_thresh value for GOLDEN_FRAME for improved encoding - // speed with little/no subjective quality loss. - if (cpi->sf.bias_golden && ref_frame == GOLDEN_FRAME && - cpi->rc.frames_since_golden > 4) - mode_rd_thresh = mode_rd_thresh << 3; - - if ((cpi->sf.adaptive_rd_thresh_row_mt && - rd_less_than_thresh_row_mt(best_rdc.rdcost, mode_rd_thresh, - &rd_thresh_freq_fact[mode_index])) || - (!cpi->sf.adaptive_rd_thresh_row_mt && - rd_less_than_thresh(best_rdc.rdcost, mode_rd_thresh, - &rd_thresh_freq_fact[mode_index]))) - if (frame_mv[this_mode][ref_frame].as_int != 0) continue; - - if (this_mode == NEWMV && !force_mv_inter_layer) { - if (search_new_mv(cpi, x, frame_mv, ref_frame, gf_temporal_ref, bsize, - mi_row, mi_col, best_pred_sad, &rate_mv, best_sse_sofar, - &best_rdc)) - continue; - } - - // TODO(jianj): Skipping the testing of (duplicate) non-zero motion vector - // causes some regression, leave it for duplicate zero-mv for now, until - // regression issue is resolved. - for (inter_mv_mode = NEARESTMV; inter_mv_mode <= NEWMV; inter_mv_mode++) { - if (inter_mv_mode == this_mode || comp_pred) continue; - if (mode_checked[inter_mv_mode][ref_frame] && - frame_mv[this_mode][ref_frame].as_int == - frame_mv[inter_mv_mode][ref_frame].as_int && - frame_mv[inter_mv_mode][ref_frame].as_int == 0) { - skip_this_mv = 1; - break; - } - } - - if (skip_this_mv) continue; - - // If use_golden_nonzeromv is false, NEWMV mode is skipped for golden, no - // need to compute best_pred_sad which is only used to skip golden NEWMV. - if (use_golden_nonzeromv && this_mode == NEWMV && ref_frame == LAST_FRAME && - frame_mv[NEWMV][LAST_FRAME].as_int != INVALID_MV) { - const int pre_stride = xd->plane[0].pre[0].stride; - const uint8_t *const pre_buf = - xd->plane[0].pre[0].buf + - (frame_mv[NEWMV][LAST_FRAME].as_mv.row >> 3) * pre_stride + - (frame_mv[NEWMV][LAST_FRAME].as_mv.col >> 3); - best_pred_sad = cpi->fn_ptr[bsize].sdf( - x->plane[0].src.buf, x->plane[0].src.stride, pre_buf, pre_stride); - x->pred_mv_sad[LAST_FRAME] = best_pred_sad; - } - - if (this_mode != NEARESTMV && !comp_pred && - frame_mv[this_mode][ref_frame].as_int == - frame_mv[NEARESTMV][ref_frame].as_int) - continue; - - mi->mode = this_mode; - mi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int; - mi->mv[1].as_int = 0; - - // Search for the best prediction filter type, when the resulting - // motion vector is at sub-pixel accuracy level for luma component, i.e., - // the last three bits are all zeros. - if (reuse_inter_pred) { - if (!this_mode_pred) { - this_mode_pred = &tmp[3]; - } else { - this_mode_pred = &tmp[get_pred_buffer(tmp, 3)]; - pd->dst.buf = this_mode_pred->data; - pd->dst.stride = bw; - } - } - - if ((this_mode == NEWMV || filter_ref == SWITCHABLE) && - pred_filter_search && - (ref_frame == LAST_FRAME || - (ref_frame == GOLDEN_FRAME && !force_mv_inter_layer && - (cpi->use_svc || cpi->oxcf.rc_mode == VPX_VBR))) && - (((mi->mv[0].as_mv.row | mi->mv[0].as_mv.col) & 0x07) != 0)) { - rd_computed = 1; - search_filter_ref(cpi, x, &this_rdc, mi_row, mi_col, tmp, bsize, - reuse_inter_pred, &this_mode_pred, &var_y, &sse_y, - force_smooth_filter, &this_early_term, - flag_preduv_computed, use_model_yrd_large); - } else { - mi->interp_filter = (filter_ref == SWITCHABLE) ? EIGHTTAP : filter_ref; - - if (cpi->use_svc && ref_frame == GOLDEN_FRAME && - svc_force_zero_mode[ref_frame - 1]) - mi->interp_filter = filter_gf_svc; - - vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize); - - // For large partition blocks, extra testing is done. - if (use_model_yrd_large) { - rd_computed = 1; - model_rd_for_sb_y_large(cpi, bsize, x, xd, &this_rdc.rate, - &this_rdc.dist, &var_y, &sse_y, mi_row, mi_col, - &this_early_term, flag_preduv_computed); - } else { - rd_computed = 1; - model_rd_for_sb_y(cpi, bsize, x, xd, &this_rdc.rate, &this_rdc.dist, - &var_y, &sse_y, 0); - } - // Save normalized sse (between current and last frame) for (0, 0) motion. - if (ref_frame == LAST_FRAME && - frame_mv[this_mode][ref_frame].as_int == 0) { - sse_zeromv_normalized = - sse_y >> (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]); - } - if (sse_y < best_sse_sofar) best_sse_sofar = sse_y; - } - - if (!this_early_term) { - this_sse = (int64_t)sse_y; - block_yrd(cpi, x, &this_rdc, &is_skippable, &this_sse, bsize, - VPXMIN(mi->tx_size, TX_16X16), rd_computed, 0); - x->skip_txfm[0] = is_skippable; - if (is_skippable) { - this_rdc.rate = vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1); - } else { - if (RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist) < - RDCOST(x->rdmult, x->rddiv, 0, this_sse)) { - this_rdc.rate += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0); - } else { - this_rdc.rate = vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1); - this_rdc.dist = this_sse; - x->skip_txfm[0] = SKIP_TXFM_AC_DC; - } - } - - if (cm->interp_filter == SWITCHABLE) { - if ((mi->mv[0].as_mv.row | mi->mv[0].as_mv.col) & 0x07) - this_rdc.rate += vp9_get_switchable_rate(cpi, xd); - } - } else { - if (cm->interp_filter == SWITCHABLE) { - if ((mi->mv[0].as_mv.row | mi->mv[0].as_mv.col) & 0x07) - this_rdc.rate += vp9_get_switchable_rate(cpi, xd); - } - this_rdc.rate += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1); - } - - if (!this_early_term && - (x->color_sensitivity[0] || x->color_sensitivity[1])) { - RD_COST rdc_uv; - const BLOCK_SIZE uv_bsize = get_plane_block_size(bsize, &xd->plane[1]); - if (x->color_sensitivity[0] && !flag_preduv_computed[0]) { - vp9_build_inter_predictors_sbp(xd, mi_row, mi_col, bsize, 1); - flag_preduv_computed[0] = 1; - } - if (x->color_sensitivity[1] && !flag_preduv_computed[1]) { - vp9_build_inter_predictors_sbp(xd, mi_row, mi_col, bsize, 2); - flag_preduv_computed[1] = 1; - } - model_rd_for_sb_uv(cpi, uv_bsize, x, xd, &rdc_uv, &var_y, &sse_y, 1, 2); - this_rdc.rate += rdc_uv.rate; - this_rdc.dist += rdc_uv.dist; - } - - this_rdc.rate += rate_mv; - this_rdc.rate += cpi->inter_mode_cost[x->mbmi_ext->mode_context[ref_frame]] - [INTER_OFFSET(this_mode)]; - // TODO(marpan): Add costing for compound mode. - this_rdc.rate += ref_frame_cost[ref_frame]; - this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist); - - // Bias against NEWMV that is very different from its neighbors, and bias - // to small motion-lastref for noisy input. - if (cpi->oxcf.rc_mode == VPX_CBR && cpi->oxcf.speed >= 5 && - cpi->oxcf.content != VP9E_CONTENT_SCREEN) { - vp9_NEWMV_diff_bias(&cpi->noise_estimate, xd, this_mode, &this_rdc, bsize, - frame_mv[this_mode][ref_frame].as_mv.row, - frame_mv[this_mode][ref_frame].as_mv.col, - ref_frame == LAST_FRAME, x->lowvar_highsumdiff, - x->sb_is_skin); - } - - // Skipping checking: test to see if this block can be reconstructed by - // prediction only. - if (cpi->allow_encode_breakout && !xd->lossless && !scene_change_detected && - !svc->high_num_blocks_with_motion) { - encode_breakout_test(cpi, x, bsize, mi_row, mi_col, ref_frame, this_mode, - var_y, sse_y, yv12_mb, &this_rdc.rate, - &this_rdc.dist, flag_preduv_computed); - if (x->skip) { - this_rdc.rate += rate_mv; - this_rdc.rdcost = - RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist); - } - } - - // On spatially flat blocks for screne content: bias against zero-last - // if the sse_y is non-zero. Only on scene change or high motion frames. - if (cpi->oxcf.content == VP9E_CONTENT_SCREEN && - (scene_change_detected || svc->high_num_blocks_with_motion) && - ref_frame == LAST_FRAME && frame_mv[this_mode][ref_frame].as_int == 0 && - svc->spatial_layer_id == 0 && x->source_variance == 0 && sse_y > 0) { - this_rdc.rdcost = this_rdc.rdcost << 2; - } - -#if CONFIG_VP9_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc_pickmode && - cpi->denoiser.denoising_level > kDenLowLow) { - vp9_denoiser_update_frame_stats(mi, sse_y, this_mode, ctx); - // Keep track of zero_last cost. - if (ref_frame == LAST_FRAME && frame_mv[this_mode][ref_frame].as_int == 0) - zero_last_cost_orig = this_rdc.rdcost; - } -#else - (void)ctx; -#endif - - mode_checked[this_mode][ref_frame] = 1; - - if (this_rdc.rdcost < best_rdc.rdcost || x->skip) { - best_rdc = this_rdc; - best_early_term = this_early_term; - best_pickmode.best_mode = this_mode; - best_pickmode.best_pred_filter = mi->interp_filter; - best_pickmode.best_tx_size = mi->tx_size; - best_pickmode.best_ref_frame = ref_frame; - best_pickmode.best_mode_skip_txfm = x->skip_txfm[0]; - best_pickmode.best_second_ref_frame = second_ref_frame; - - if (reuse_inter_pred) { - free_pred_buffer(best_pickmode.best_pred); - best_pickmode.best_pred = this_mode_pred; - } - } else { - if (reuse_inter_pred) free_pred_buffer(this_mode_pred); - } - - if (x->skip && - (!force_test_gf_zeromv || mode_checked[ZEROMV][GOLDEN_FRAME])) - break; - - // If early termination flag is 1 and at least 2 modes are checked, - // the mode search is terminated. - if (best_early_term && idx > 0 && !scene_change_detected && - (!force_test_gf_zeromv || mode_checked[ZEROMV][GOLDEN_FRAME])) { - x->skip = 1; - break; - } - } - - mi->mode = best_pickmode.best_mode; - mi->interp_filter = best_pickmode.best_pred_filter; - mi->tx_size = best_pickmode.best_tx_size; - mi->ref_frame[0] = best_pickmode.best_ref_frame; - mi->mv[0].as_int = - frame_mv[best_pickmode.best_mode][best_pickmode.best_ref_frame].as_int; - xd->mi[0]->bmi[0].as_mv[0].as_int = mi->mv[0].as_int; - x->skip_txfm[0] = best_pickmode.best_mode_skip_txfm; - mi->ref_frame[1] = best_pickmode.best_second_ref_frame; - - // For spatial enhancemanent layer: perform intra prediction only if base - // layer is chosen as the reference. Always perform intra prediction if - // LAST is the only reference, or is_key_frame is set, or on base - // temporal layer. - if (svc->spatial_layer_id && !gf_temporal_ref) { - perform_intra_pred = - svc->temporal_layer_id == 0 || - svc->layer_context[svc->temporal_layer_id].is_key_frame || - !(cpi->ref_frame_flags & VP9_GOLD_FLAG) || - (!svc->layer_context[svc->temporal_layer_id].is_key_frame && - svc_force_zero_mode[best_pickmode.best_ref_frame - 1]); - inter_mode_thresh = (inter_mode_thresh << 1) + inter_mode_thresh; - } - if ((cpi->oxcf.lag_in_frames > 0 && cpi->oxcf.rc_mode == VPX_VBR && - cpi->rc.is_src_frame_alt_ref) || - svc->previous_frame_is_intra_only) - perform_intra_pred = 0; - - // If the segment reference frame feature is enabled and set then - // skip the intra prediction. - if (segfeature_active(seg, mi->segment_id, SEG_LVL_REF_FRAME) && - get_segdata(seg, mi->segment_id, SEG_LVL_REF_FRAME) > 0) - perform_intra_pred = 0; - - // Perform intra prediction search, if the best SAD is above a certain - // threshold. - if (best_rdc.rdcost == INT64_MAX || - (cpi->oxcf.content == VP9E_CONTENT_SCREEN && x->source_variance == 0) || - (scene_change_detected && perform_intra_pred) || - ((!force_skip_low_temp_var || bsize < BLOCK_32X32 || - x->content_state_sb == kVeryHighSad) && - perform_intra_pred && !x->skip && best_rdc.rdcost > inter_mode_thresh && - bsize <= cpi->sf.max_intra_bsize && !x->skip_low_source_sad && - !x->lowvar_highsumdiff)) { - struct estimate_block_intra_args args = { cpi, x, DC_PRED, 1, 0 }; - int64_t this_sse = INT64_MAX; - int i; - PRED_BUFFER *const best_pred = best_pickmode.best_pred; - TX_SIZE intra_tx_size = - VPXMIN(max_txsize_lookup[bsize], - tx_mode_to_biggest_tx_size[cpi->common.tx_mode]); - - if (reuse_inter_pred && best_pred != NULL) { - if (best_pred->data == orig_dst.buf) { - this_mode_pred = &tmp[get_pred_buffer(tmp, 3)]; -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) - vpx_highbd_convolve_copy( - CONVERT_TO_SHORTPTR(best_pred->data), best_pred->stride, - CONVERT_TO_SHORTPTR(this_mode_pred->data), this_mode_pred->stride, - NULL, 0, 0, 0, 0, bw, bh, xd->bd); - else - vpx_convolve_copy(best_pred->data, best_pred->stride, - this_mode_pred->data, this_mode_pred->stride, NULL, - 0, 0, 0, 0, bw, bh); -#else - vpx_convolve_copy(best_pred->data, best_pred->stride, - this_mode_pred->data, this_mode_pred->stride, NULL, 0, - 0, 0, 0, bw, bh); -#endif // CONFIG_VP9_HIGHBITDEPTH - best_pickmode.best_pred = this_mode_pred; - } - } - pd->dst = orig_dst; - - for (i = 0; i < 4; ++i) { - const PREDICTION_MODE this_mode = intra_mode_list[i]; - THR_MODES mode_index = mode_idx[INTRA_FRAME][mode_offset(this_mode)]; - int mode_rd_thresh = rd_threshes[mode_index]; - // For spatially flat blocks, under short_circuit_flat_blocks flag: - // only check DC mode for stationary blocks, otherwise also check - // H and V mode. - if (sf->short_circuit_flat_blocks && x->source_variance == 0 && - ((x->zero_temp_sad_source && this_mode != DC_PRED) || i > 2)) { - continue; - } - - if (!((1 << this_mode) & cpi->sf.intra_y_mode_bsize_mask[bsize])) - continue; - - if (cpi->sf.rt_intra_dc_only_low_content && this_mode != DC_PRED && - x->content_state_sb != kVeryHighSad) - continue; - - if ((cpi->sf.adaptive_rd_thresh_row_mt && - rd_less_than_thresh_row_mt(best_rdc.rdcost, mode_rd_thresh, - &rd_thresh_freq_fact[mode_index])) || - (!cpi->sf.adaptive_rd_thresh_row_mt && - rd_less_than_thresh(best_rdc.rdcost, mode_rd_thresh, - &rd_thresh_freq_fact[mode_index]))) { - // Avoid this early exit for screen on base layer, for scene - // changes or high motion frames. - if (cpi->oxcf.content != VP9E_CONTENT_SCREEN || - svc->spatial_layer_id > 0 || - (!scene_change_detected && !svc->high_num_blocks_with_motion)) - continue; - } - - mi->mode = this_mode; - mi->ref_frame[0] = INTRA_FRAME; - this_rdc.dist = this_rdc.rate = 0; - args.mode = this_mode; - args.skippable = 1; - args.rdc = &this_rdc; - mi->tx_size = intra_tx_size; - - compute_intra_yprediction(this_mode, bsize, x, xd); - model_rd_for_sb_y(cpi, bsize, x, xd, &this_rdc.rate, &this_rdc.dist, - &var_y, &sse_y, 1); - block_yrd(cpi, x, &this_rdc, &args.skippable, &this_sse, bsize, - VPXMIN(mi->tx_size, TX_16X16), 1, 1); - - // Check skip cost here since skippable is not set for for uv, this - // mirrors the behavior used by inter - if (args.skippable) { - x->skip_txfm[0] = SKIP_TXFM_AC_DC; - this_rdc.rate = vp9_cost_bit(vp9_get_skip_prob(&cpi->common, xd), 1); - } else { - x->skip_txfm[0] = SKIP_TXFM_NONE; - this_rdc.rate += vp9_cost_bit(vp9_get_skip_prob(&cpi->common, xd), 0); - } - // Inter and intra RD will mismatch in scale for non-screen content. - if (cpi->oxcf.content == VP9E_CONTENT_SCREEN) { - if (x->color_sensitivity[0]) - vp9_foreach_transformed_block_in_plane(xd, bsize, 1, - estimate_block_intra, &args); - if (x->color_sensitivity[1]) - vp9_foreach_transformed_block_in_plane(xd, bsize, 2, - estimate_block_intra, &args); - } - this_rdc.rate += cpi->mbmode_cost[this_mode]; - this_rdc.rate += ref_frame_cost[INTRA_FRAME]; - this_rdc.rate += intra_cost_penalty; - this_rdc.rdcost = - RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist); - - if (this_rdc.rdcost < best_rdc.rdcost) { - best_rdc = this_rdc; - best_pickmode.best_mode = this_mode; - best_pickmode.best_intra_tx_size = mi->tx_size; - best_pickmode.best_ref_frame = INTRA_FRAME; - best_pickmode.best_second_ref_frame = NO_REF_FRAME; - mi->uv_mode = this_mode; - mi->mv[0].as_int = INVALID_MV; - mi->mv[1].as_int = INVALID_MV; - best_pickmode.best_mode_skip_txfm = x->skip_txfm[0]; - } - } - - // Reset mb_mode_info to the best inter mode. - if (best_pickmode.best_ref_frame != INTRA_FRAME) { - mi->tx_size = best_pickmode.best_tx_size; - } else { - mi->tx_size = best_pickmode.best_intra_tx_size; - } - } - - pd->dst = orig_dst; - mi->mode = best_pickmode.best_mode; - mi->ref_frame[0] = best_pickmode.best_ref_frame; - mi->ref_frame[1] = best_pickmode.best_second_ref_frame; - x->skip_txfm[0] = best_pickmode.best_mode_skip_txfm; - - if (!is_inter_block(mi)) { - mi->interp_filter = SWITCHABLE_FILTERS; - } - - if (reuse_inter_pred && best_pickmode.best_pred != NULL) { - PRED_BUFFER *const best_pred = best_pickmode.best_pred; - if (best_pred->data != orig_dst.buf && is_inter_mode(mi->mode)) { -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) - vpx_highbd_convolve_copy( - CONVERT_TO_SHORTPTR(best_pred->data), best_pred->stride, - CONVERT_TO_SHORTPTR(pd->dst.buf), pd->dst.stride, NULL, 0, 0, 0, 0, - bw, bh, xd->bd); - else - vpx_convolve_copy(best_pred->data, best_pred->stride, pd->dst.buf, - pd->dst.stride, NULL, 0, 0, 0, 0, bw, bh); -#else - vpx_convolve_copy(best_pred->data, best_pred->stride, pd->dst.buf, - pd->dst.stride, NULL, 0, 0, 0, 0, bw, bh); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - -#if CONFIG_VP9_TEMPORAL_DENOISING - if (cpi->oxcf.noise_sensitivity > 0 && cpi->resize_pending == 0 && - denoise_svc_pickmode && cpi->denoiser.denoising_level > kDenLowLow && - cpi->denoiser.reset == 0) { - VP9_DENOISER_DECISION decision = COPY_BLOCK; - ctx->sb_skip_denoising = 0; - // TODO(marpan): There is an issue with denoising when the - // superblock partitioning scheme is based on the pickmode. - // Remove this condition when the issue is resolved. - if (x->sb_pickmode_part) ctx->sb_skip_denoising = 1; - vp9_pickmode_ctx_den_update(&ctx_den, zero_last_cost_orig, ref_frame_cost, - frame_mv, reuse_inter_pred, &best_pickmode); - vp9_denoiser_denoise(cpi, x, mi_row, mi_col, bsize, ctx, &decision, - gf_temporal_ref); - if (denoise_recheck_zeromv) - recheck_zeromv_after_denoising(cpi, mi, x, xd, decision, &ctx_den, - yv12_mb, &best_rdc, bsize, mi_row, mi_col); - best_pickmode.best_ref_frame = ctx_den.best_ref_frame; - } -#endif - - if (best_pickmode.best_ref_frame == ALTREF_FRAME || - best_pickmode.best_second_ref_frame == ALTREF_FRAME) - x->arf_frame_usage++; - else if (best_pickmode.best_ref_frame != INTRA_FRAME) - x->lastgolden_frame_usage++; - - if (cpi->sf.adaptive_rd_thresh) { - THR_MODES best_mode_idx = - mode_idx[best_pickmode.best_ref_frame][mode_offset(mi->mode)]; - - if (best_pickmode.best_ref_frame == INTRA_FRAME) { - // Only consider the modes that are included in the intra_mode_list. - int intra_modes = sizeof(intra_mode_list) / sizeof(PREDICTION_MODE); - int i; - - // TODO(yunqingwang): Check intra mode mask and only update freq_fact - // for those valid modes. - for (i = 0; i < intra_modes; i++) { - if (cpi->sf.adaptive_rd_thresh_row_mt) - update_thresh_freq_fact_row_mt(cpi, tile_data, x->source_variance, - thresh_freq_fact_idx, INTRA_FRAME, - best_mode_idx, intra_mode_list[i]); - else - update_thresh_freq_fact(cpi, tile_data, x->source_variance, bsize, - INTRA_FRAME, best_mode_idx, - intra_mode_list[i]); - } - } else { - for (ref_frame = LAST_FRAME; ref_frame <= GOLDEN_FRAME; ++ref_frame) { - PREDICTION_MODE this_mode; - if (best_pickmode.best_ref_frame != ref_frame) continue; - for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) { - if (cpi->sf.adaptive_rd_thresh_row_mt) - update_thresh_freq_fact_row_mt(cpi, tile_data, x->source_variance, - thresh_freq_fact_idx, ref_frame, - best_mode_idx, this_mode); - else - update_thresh_freq_fact(cpi, tile_data, x->source_variance, bsize, - ref_frame, best_mode_idx, this_mode); - } - } - } - } - - *rd_cost = best_rdc; -} - -void vp9_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, int mi_row, - int mi_col, RD_COST *rd_cost, BLOCK_SIZE bsize, - PICK_MODE_CONTEXT *ctx) { - VP9_COMMON *const cm = &cpi->common; - SPEED_FEATURES *const sf = &cpi->sf; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext; - const struct segmentation *const seg = &cm->seg; - MV_REFERENCE_FRAME ref_frame, second_ref_frame = NO_REF_FRAME; - MV_REFERENCE_FRAME best_ref_frame = NO_REF_FRAME; - unsigned char segment_id = mi->segment_id; - struct buf_2d yv12_mb[4][MAX_MB_PLANE]; - int64_t best_rd = INT64_MAX; - b_mode_info bsi[MAX_REF_FRAMES][4]; - int ref_frame_skip_mask = 0; - const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; - const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; - int idx, idy; - - x->skip_encode = sf->skip_encode_frame && x->q_index < QIDX_SKIP_THRESH; - ctx->pred_pixel_ready = 0; - - for (ref_frame = LAST_FRAME; ref_frame <= GOLDEN_FRAME; ++ref_frame) { - const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame); - int_mv dummy_mv[2]; - x->pred_mv_sad[ref_frame] = INT_MAX; - - if ((cpi->ref_frame_flags & ref_frame_to_flag(ref_frame)) && - (yv12 != NULL)) { - int_mv *const candidates = mbmi_ext->ref_mvs[ref_frame]; - const struct scale_factors *const ref_sf = - &cm->frame_refs[ref_frame - 1].sf; - vp9_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, ref_sf, - ref_sf); - vp9_find_mv_refs(cm, xd, xd->mi[0], ref_frame, candidates, mi_row, mi_col, - mbmi_ext->mode_context); - - vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv, candidates, - &dummy_mv[0], &dummy_mv[1]); - } else { - ref_frame_skip_mask |= (1 << ref_frame); - } - } - - mi->sb_type = bsize; - mi->tx_size = TX_4X4; - mi->uv_mode = DC_PRED; - mi->ref_frame[0] = LAST_FRAME; - mi->ref_frame[1] = NO_REF_FRAME; - mi->interp_filter = - cm->interp_filter == SWITCHABLE ? EIGHTTAP : cm->interp_filter; - - for (ref_frame = LAST_FRAME; ref_frame <= GOLDEN_FRAME; ++ref_frame) { - int64_t this_rd = 0; - int plane; - - if (ref_frame_skip_mask & (1 << ref_frame)) continue; - -#if CONFIG_BETTER_HW_COMPATIBILITY - if ((bsize == BLOCK_8X4 || bsize == BLOCK_4X8) && ref_frame > INTRA_FRAME && - vp9_is_scaled(&cm->frame_refs[ref_frame - 1].sf)) - continue; -#endif - - // TODO(jingning, agrange): Scaling reference frame not supported for - // sub8x8 blocks. Is this supported now? - if (ref_frame > INTRA_FRAME && - vp9_is_scaled(&cm->frame_refs[ref_frame - 1].sf)) - continue; - - // If the segment reference frame feature is enabled.... - // then do nothing if the current ref frame is not allowed.. - if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) && - get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) - continue; - - mi->ref_frame[0] = ref_frame; - x->skip = 0; - set_ref_ptrs(cm, xd, ref_frame, second_ref_frame); - - // Select prediction reference frames. - for (plane = 0; plane < MAX_MB_PLANE; plane++) - xd->plane[plane].pre[0] = yv12_mb[ref_frame][plane]; - - for (idy = 0; idy < 2; idy += num_4x4_blocks_high) { - for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) { - int_mv b_mv[MB_MODE_COUNT]; - int64_t b_best_rd = INT64_MAX; - const int i = idy * 2 + idx; - PREDICTION_MODE this_mode; - RD_COST this_rdc; - unsigned int var_y, sse_y; - - struct macroblock_plane *p = &x->plane[0]; - struct macroblockd_plane *pd = &xd->plane[0]; - - const struct buf_2d orig_src = p->src; - const struct buf_2d orig_dst = pd->dst; - struct buf_2d orig_pre[2]; - memcpy(orig_pre, xd->plane[0].pre, sizeof(orig_pre)); - - // set buffer pointers for sub8x8 motion search. - p->src.buf = - &p->src.buf[vp9_raster_block_offset(BLOCK_8X8, i, p->src.stride)]; - pd->dst.buf = - &pd->dst.buf[vp9_raster_block_offset(BLOCK_8X8, i, pd->dst.stride)]; - pd->pre[0].buf = - &pd->pre[0] - .buf[vp9_raster_block_offset(BLOCK_8X8, i, pd->pre[0].stride)]; - - b_mv[ZEROMV].as_int = 0; - b_mv[NEWMV].as_int = INVALID_MV; - vp9_append_sub8x8_mvs_for_idx(cm, xd, i, 0, mi_row, mi_col, - &b_mv[NEARESTMV], &b_mv[NEARMV], - mbmi_ext->mode_context); - - for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) { - int b_rate = 0; - xd->mi[0]->bmi[i].as_mv[0].as_int = b_mv[this_mode].as_int; - - if (this_mode == NEWMV) { - const int step_param = cpi->sf.mv.fullpel_search_step_param; - MV mvp_full; - MV tmp_mv; - int cost_list[5]; - const MvLimits tmp_mv_limits = x->mv_limits; - uint32_t dummy_dist; - - if (i == 0) { - mvp_full.row = b_mv[NEARESTMV].as_mv.row >> 3; - mvp_full.col = b_mv[NEARESTMV].as_mv.col >> 3; - } else { - mvp_full.row = xd->mi[0]->bmi[0].as_mv[0].as_mv.row >> 3; - mvp_full.col = xd->mi[0]->bmi[0].as_mv[0].as_mv.col >> 3; - } - - vp9_set_mv_search_range(&x->mv_limits, - &mbmi_ext->ref_mvs[ref_frame][0].as_mv); - - vp9_full_pixel_search( - cpi, x, bsize, &mvp_full, step_param, cpi->sf.mv.search_method, - x->sadperbit4, cond_cost_list(cpi, cost_list), - &mbmi_ext->ref_mvs[ref_frame][0].as_mv, &tmp_mv, INT_MAX, 0); - - x->mv_limits = tmp_mv_limits; - - // calculate the bit cost on motion vector - mvp_full.row = tmp_mv.row * 8; - mvp_full.col = tmp_mv.col * 8; - - b_rate += vp9_mv_bit_cost( - &mvp_full, &mbmi_ext->ref_mvs[ref_frame][0].as_mv, - x->nmvjointcost, x->mvcost, MV_COST_WEIGHT); - - b_rate += cpi->inter_mode_cost[x->mbmi_ext->mode_context[ref_frame]] - [INTER_OFFSET(NEWMV)]; - if (RDCOST(x->rdmult, x->rddiv, b_rate, 0) > b_best_rd) continue; - - cpi->find_fractional_mv_step( - x, &tmp_mv, &mbmi_ext->ref_mvs[ref_frame][0].as_mv, - cpi->common.allow_high_precision_mv, x->errorperbit, - &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop, - cpi->sf.mv.subpel_search_level, cond_cost_list(cpi, cost_list), - x->nmvjointcost, x->mvcost, &dummy_dist, - &x->pred_sse[ref_frame], NULL, 0, 0, - cpi->sf.use_accurate_subpel_search); - - xd->mi[0]->bmi[i].as_mv[0].as_mv = tmp_mv; - } else { - b_rate += cpi->inter_mode_cost[x->mbmi_ext->mode_context[ref_frame]] - [INTER_OFFSET(this_mode)]; - } - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - vp9_highbd_build_inter_predictor( - CONVERT_TO_SHORTPTR(pd->pre[0].buf), pd->pre[0].stride, - CONVERT_TO_SHORTPTR(pd->dst.buf), pd->dst.stride, - &xd->mi[0]->bmi[i].as_mv[0].as_mv, &xd->block_refs[0]->sf, - 4 * num_4x4_blocks_wide, 4 * num_4x4_blocks_high, 0, - vp9_filter_kernels[mi->interp_filter], MV_PRECISION_Q3, - mi_col * MI_SIZE + 4 * (i & 0x01), - mi_row * MI_SIZE + 4 * (i >> 1), xd->bd); - } else { -#endif - vp9_build_inter_predictor( - pd->pre[0].buf, pd->pre[0].stride, pd->dst.buf, pd->dst.stride, - &xd->mi[0]->bmi[i].as_mv[0].as_mv, &xd->block_refs[0]->sf, - 4 * num_4x4_blocks_wide, 4 * num_4x4_blocks_high, 0, - vp9_filter_kernels[mi->interp_filter], MV_PRECISION_Q3, - mi_col * MI_SIZE + 4 * (i & 0x01), - mi_row * MI_SIZE + 4 * (i >> 1)); - -#if CONFIG_VP9_HIGHBITDEPTH - } -#endif - - model_rd_for_sb_y(cpi, bsize, x, xd, &this_rdc.rate, &this_rdc.dist, - &var_y, &sse_y, 0); - - this_rdc.rate += b_rate; - this_rdc.rdcost = - RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist); - if (this_rdc.rdcost < b_best_rd) { - b_best_rd = this_rdc.rdcost; - bsi[ref_frame][i].as_mode = this_mode; - bsi[ref_frame][i].as_mv[0].as_mv = xd->mi[0]->bmi[i].as_mv[0].as_mv; - } - } // mode search - - // restore source and prediction buffer pointers. - p->src = orig_src; - pd->pre[0] = orig_pre[0]; - pd->dst = orig_dst; - this_rd += b_best_rd; - - xd->mi[0]->bmi[i] = bsi[ref_frame][i]; - if (num_4x4_blocks_wide > 1) xd->mi[0]->bmi[i + 1] = xd->mi[0]->bmi[i]; - if (num_4x4_blocks_high > 1) xd->mi[0]->bmi[i + 2] = xd->mi[0]->bmi[i]; - } - } // loop through sub8x8 blocks - - if (this_rd < best_rd) { - best_rd = this_rd; - best_ref_frame = ref_frame; - } - } // reference frames - - mi->tx_size = TX_4X4; - mi->ref_frame[0] = best_ref_frame; - for (idy = 0; idy < 2; idy += num_4x4_blocks_high) { - for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) { - const int block = idy * 2 + idx; - xd->mi[0]->bmi[block] = bsi[best_ref_frame][block]; - if (num_4x4_blocks_wide > 1) - xd->mi[0]->bmi[block + 1] = bsi[best_ref_frame][block]; - if (num_4x4_blocks_high > 1) - xd->mi[0]->bmi[block + 2] = bsi[best_ref_frame][block]; - } - } - mi->mode = xd->mi[0]->bmi[3].as_mode; - ctx->mic = *(xd->mi[0]); - ctx->mbmi_ext = *x->mbmi_ext; - ctx->skip_txfm[0] = SKIP_TXFM_NONE; - ctx->skip = 0; - // Dummy assignment for speed -5. No effect in speed -6. - rd_cost->rdcost = best_rd; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_pickmode.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_pickmode.h deleted file mode 100644 index 15207e6c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_pickmode.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_PICKMODE_H_ -#define VPX_VP9_ENCODER_VP9_PICKMODE_H_ - -#include "vp9/encoder/vp9_encoder.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vp9_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x, RD_COST *rd_cost, - BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx); - -void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, - int mi_row, int mi_col, RD_COST *rd_cost, - BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx); - -void vp9_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, int mi_row, - int mi_col, RD_COST *rd_cost, BLOCK_SIZE bsize, - PICK_MODE_CONTEXT *ctx); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_PICKMODE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_quantize.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_quantize.c deleted file mode 100644 index d37e020b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_quantize.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/bitops.h" -#include "vpx_ports/mem.h" - -#include "vp9/common/vp9_quant_common.h" -#include "vp9/common/vp9_scan.h" -#include "vp9/common/vp9_seg_common.h" - -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_quantize.h" -#include "vp9/encoder/vp9_rd.h" - -void vp9_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - int i, eob = -1; - const int16_t *round_ptr = mb_plane->round_fp; - const int16_t *quant_ptr = mb_plane->quant_fp; - const int16_t *scan = scan_order->scan; - - memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); - memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); - - // Quantization pass: All coefficients with index >= zero_flag are - // skippable. Note: zero_flag can be zero. - for (i = 0; i < n_coeffs; i++) { - const int rc = scan[i]; - const int coeff = coeff_ptr[rc]; - const int coeff_sign = (coeff >> 31); - const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; - - int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX); - tmp = (tmp * quant_ptr[rc != 0]) >> 16; - - qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; - dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0]; - - if (tmp) eob = i; - } - *eob_ptr = eob + 1; -} - -#if CONFIG_VP9_HIGHBITDEPTH -void vp9_highbd_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - int i; - int eob = -1; - const int16_t *round_ptr = mb_plane->round_fp; - const int16_t *quant_ptr = mb_plane->quant_fp; - const int16_t *scan = scan_order->scan; - - memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); - memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); - - // Quantization pass: All coefficients with index >= zero_flag are - // skippable. Note: zero_flag can be zero. - for (i = 0; i < n_coeffs; i++) { - const int rc = scan[i]; - const int coeff = coeff_ptr[rc]; - const int coeff_sign = (coeff >> 31); - const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; - const int64_t tmp = abs_coeff + round_ptr[rc != 0]; - const int abs_qcoeff = (int)((tmp * quant_ptr[rc != 0]) >> 16); - qcoeff_ptr[rc] = (tran_low_t)(abs_qcoeff ^ coeff_sign) - coeff_sign; - dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0]; - if (abs_qcoeff) eob = i; - } - *eob_ptr = eob + 1; -} -#endif - -// TODO(jingning) Refactor this file and combine functions with similar -// operations. -void vp9_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - int i, eob = -1; - const int16_t *round_ptr = mb_plane->round_fp; - const int16_t *quant_ptr = mb_plane->quant_fp; - const int16_t *scan = scan_order->scan; - - memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); - memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); - - for (i = 0; i < n_coeffs; i++) { - const int rc = scan[i]; - const int coeff = coeff_ptr[rc]; - const int coeff_sign = (coeff >> 31); - int tmp = 0; - int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; - - if (abs_coeff >= (dequant_ptr[rc != 0] >> 2)) { - abs_coeff += ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1); - abs_coeff = clamp(abs_coeff, INT16_MIN, INT16_MAX); - tmp = (abs_coeff * quant_ptr[rc != 0]) >> 15; - qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; - dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2; - } - - if (tmp) eob = i; - } - *eob_ptr = eob + 1; -} - -#if CONFIG_VP9_HIGHBITDEPTH -void vp9_highbd_quantize_fp_32x32_c( - const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - int i, eob = -1; - const int16_t *round_ptr = mb_plane->round_fp; - const int16_t *quant_ptr = mb_plane->quant_fp; - const int16_t *scan = scan_order->scan; - - memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); - memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); - - for (i = 0; i < n_coeffs; i++) { - int abs_qcoeff = 0; - const int rc = scan[i]; - const int coeff = coeff_ptr[rc]; - const int coeff_sign = (coeff >> 31); - const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; - - if (abs_coeff >= (dequant_ptr[rc != 0] >> 2)) { - const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1); - abs_qcoeff = (int)((tmp * quant_ptr[rc != 0]) >> 15); - qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign); - dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2; - } - - if (abs_qcoeff) eob = i; - } - *eob_ptr = eob + 1; -} -#endif - -static void invert_quant(int16_t *quant, int16_t *shift, int d) { - unsigned int t; - int l, m; - t = (unsigned int)d; - l = get_msb(t); - m = 1 + (1 << (16 + l)) / d; - *quant = (int16_t)(m - (1 << 16)); - *shift = 1 << (16 - l); -} - -static int get_qzbin_factor(int q, vpx_bit_depth_t bit_depth) { - const int quant = vp9_dc_quant(q, 0, bit_depth); -#if CONFIG_VP9_HIGHBITDEPTH - switch (bit_depth) { - case VPX_BITS_8: return q == 0 ? 64 : (quant < 148 ? 84 : 80); - case VPX_BITS_10: return q == 0 ? 64 : (quant < 592 ? 84 : 80); - default: - assert(bit_depth == VPX_BITS_12); - return q == 0 ? 64 : (quant < 2368 ? 84 : 80); - } -#else - (void)bit_depth; - return q == 0 ? 64 : (quant < 148 ? 84 : 80); -#endif -} - -void vp9_init_quantizer(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - QUANTS *const quants = &cpi->quants; - int i, q, quant; - - for (q = 0; q < QINDEX_RANGE; q++) { - int qzbin_factor = get_qzbin_factor(q, cm->bit_depth); - int qrounding_factor = q == 0 ? 64 : 48; - const int sharpness_adjustment = 16 * (7 - cpi->oxcf.sharpness) / 7; - - if (cpi->oxcf.sharpness > 0 && q > 0) { - qzbin_factor = 64 + sharpness_adjustment; - qrounding_factor = 64 - sharpness_adjustment; - } - - for (i = 0; i < 2; ++i) { - int qrounding_factor_fp = i == 0 ? 48 : 42; - if (q == 0) qrounding_factor_fp = 64; - if (cpi->oxcf.sharpness > 0) - qrounding_factor_fp = 64 - sharpness_adjustment; - // y - quant = i == 0 ? vp9_dc_quant(q, cm->y_dc_delta_q, cm->bit_depth) - : vp9_ac_quant(q, 0, cm->bit_depth); - invert_quant(&quants->y_quant[q][i], &quants->y_quant_shift[q][i], quant); - quants->y_quant_fp[q][i] = (1 << 16) / quant; - quants->y_round_fp[q][i] = (qrounding_factor_fp * quant) >> 7; - quants->y_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7); - quants->y_round[q][i] = (qrounding_factor * quant) >> 7; - cpi->y_dequant[q][i] = quant; - - // uv - quant = i == 0 ? vp9_dc_quant(q, cm->uv_dc_delta_q, cm->bit_depth) - : vp9_ac_quant(q, cm->uv_ac_delta_q, cm->bit_depth); - invert_quant(&quants->uv_quant[q][i], &quants->uv_quant_shift[q][i], - quant); - quants->uv_quant_fp[q][i] = (1 << 16) / quant; - quants->uv_round_fp[q][i] = (qrounding_factor_fp * quant) >> 7; - quants->uv_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7); - quants->uv_round[q][i] = (qrounding_factor * quant) >> 7; - cpi->uv_dequant[q][i] = quant; - } - - for (i = 2; i < 8; i++) { - quants->y_quant[q][i] = quants->y_quant[q][1]; - quants->y_quant_fp[q][i] = quants->y_quant_fp[q][1]; - quants->y_round_fp[q][i] = quants->y_round_fp[q][1]; - quants->y_quant_shift[q][i] = quants->y_quant_shift[q][1]; - quants->y_zbin[q][i] = quants->y_zbin[q][1]; - quants->y_round[q][i] = quants->y_round[q][1]; - cpi->y_dequant[q][i] = cpi->y_dequant[q][1]; - - quants->uv_quant[q][i] = quants->uv_quant[q][1]; - quants->uv_quant_fp[q][i] = quants->uv_quant_fp[q][1]; - quants->uv_round_fp[q][i] = quants->uv_round_fp[q][1]; - quants->uv_quant_shift[q][i] = quants->uv_quant_shift[q][1]; - quants->uv_zbin[q][i] = quants->uv_zbin[q][1]; - quants->uv_round[q][i] = quants->uv_round[q][1]; - cpi->uv_dequant[q][i] = cpi->uv_dequant[q][1]; - } - } -} - -void vp9_init_plane_quantizers(VP9_COMP *cpi, MACROBLOCK *x) { - const VP9_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &x->e_mbd; - QUANTS *const quants = &cpi->quants; - const int segment_id = xd->mi[0]->segment_id; - const int qindex = vp9_get_qindex(&cm->seg, segment_id, cm->base_qindex); - const int rdmult = vp9_compute_rd_mult(cpi, qindex + cm->y_dc_delta_q); - int i; - - // Y - x->plane[0].quant = quants->y_quant[qindex]; - x->plane[0].quant_fp = quants->y_quant_fp[qindex]; - x->plane[0].round_fp = quants->y_round_fp[qindex]; - x->plane[0].quant_shift = quants->y_quant_shift[qindex]; - x->plane[0].zbin = quants->y_zbin[qindex]; - x->plane[0].round = quants->y_round[qindex]; - xd->plane[0].dequant = cpi->y_dequant[qindex]; - x->plane[0].quant_thred[0] = x->plane[0].zbin[0] * x->plane[0].zbin[0]; - x->plane[0].quant_thred[1] = x->plane[0].zbin[1] * x->plane[0].zbin[1]; - - // UV - for (i = 1; i < 3; i++) { - x->plane[i].quant = quants->uv_quant[qindex]; - x->plane[i].quant_fp = quants->uv_quant_fp[qindex]; - x->plane[i].round_fp = quants->uv_round_fp[qindex]; - x->plane[i].quant_shift = quants->uv_quant_shift[qindex]; - x->plane[i].zbin = quants->uv_zbin[qindex]; - x->plane[i].round = quants->uv_round[qindex]; - xd->plane[i].dequant = cpi->uv_dequant[qindex]; - x->plane[i].quant_thred[0] = x->plane[i].zbin[0] * x->plane[i].zbin[0]; - x->plane[i].quant_thred[1] = x->plane[i].zbin[1] * x->plane[i].zbin[1]; - } - - x->skip_block = segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP); - x->q_index = qindex; - - set_error_per_bit(x, rdmult); - - vp9_initialize_me_consts(cpi, x, x->q_index); -} - -void vp9_frame_init_quantizer(VP9_COMP *cpi) { - vp9_init_plane_quantizers(cpi, &cpi->td.mb); -} - -void vp9_set_quantizer(VP9_COMP *cpi, int q) { - VP9_COMMON *cm = &cpi->common; - // quantizer has to be reinitialized with vp9_init_quantizer() if any - // delta_q changes. - cm->base_qindex = q; - cm->y_dc_delta_q = 0; - cm->uv_dc_delta_q = 0; - cm->uv_ac_delta_q = 0; - if (cpi->oxcf.delta_q_uv != 0) { - cm->uv_dc_delta_q = cm->uv_ac_delta_q = cpi->oxcf.delta_q_uv; - vp9_init_quantizer(cpi); - } -} - -// Table that converts 0-63 Q-range values passed in outside to the Qindex -// range used internally. -static const int quantizer_to_qindex[] = { - 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, - 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, - 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, - 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, - 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 249, 255, -}; - -int vp9_quantizer_to_qindex(int quantizer) { - return quantizer_to_qindex[quantizer]; -} - -int vp9_qindex_to_quantizer(int qindex) { - int quantizer; - - for (quantizer = 0; quantizer < 64; ++quantizer) - if (quantizer_to_qindex[quantizer] >= qindex) return quantizer; - - return 63; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_quantize.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_quantize.h deleted file mode 100644 index f626f065..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_quantize.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_QUANTIZE_H_ -#define VPX_VP9_ENCODER_VP9_QUANTIZE_H_ - -#include "./vpx_config.h" -#include "vp9/encoder/vp9_block.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - DECLARE_ALIGNED(16, int16_t, y_quant[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, y_quant_shift[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, y_zbin[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, y_round[QINDEX_RANGE][8]); - - // TODO(jingning): in progress of re-working the quantization. will decide - // if we want to deprecate the current use of y_quant. - DECLARE_ALIGNED(16, int16_t, y_quant_fp[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, uv_quant_fp[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, y_round_fp[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, uv_round_fp[QINDEX_RANGE][8]); - - DECLARE_ALIGNED(16, int16_t, uv_quant[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, uv_quant_shift[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, uv_zbin[QINDEX_RANGE][8]); - DECLARE_ALIGNED(16, int16_t, uv_round[QINDEX_RANGE][8]); -} QUANTS; - -struct VP9_COMP; -struct VP9Common; - -void vp9_frame_init_quantizer(struct VP9_COMP *cpi); - -void vp9_init_plane_quantizers(struct VP9_COMP *cpi, MACROBLOCK *x); - -void vp9_init_quantizer(struct VP9_COMP *cpi); - -void vp9_set_quantizer(struct VP9_COMP *cm, int q); - -int vp9_quantizer_to_qindex(int quantizer); - -int vp9_qindex_to_quantizer(int qindex); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_QUANTIZE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ratectrl.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ratectrl.c deleted file mode 100644 index e95bcc83..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ratectrl.c +++ /dev/null @@ -1,3344 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/system_state.h" - -#include "vp9/common/vp9_alloccommon.h" -#include "vp9/common/vp9_blockd.h" -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_entropymode.h" -#include "vp9/common/vp9_onyxc_int.h" -#include "vp9/common/vp9_quant_common.h" -#include "vp9/common/vp9_seg_common.h" - -#include "vp9/encoder/vp9_aq_cyclicrefresh.h" -#include "vp9/encoder/vp9_encodemv.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_ext_ratectrl.h" -#include "vp9/encoder/vp9_firstpass.h" -#include "vp9/encoder/vp9_ratectrl.h" -#include "vp9/encoder/vp9_svc_layercontext.h" - -#include "vpx/vpx_codec.h" -#include "vpx/vpx_ext_ratectrl.h" -#include "vpx/internal/vpx_codec_internal.h" - -// Max rate per frame for 1080P and below encodes if no level requirement given. -// For larger formats limit to MAX_MB_RATE bits per MB -// 4Mbits is derived from the level requirement for level 4 (1080P 30) which -// requires that HW can sustain a rate of 16Mbits over a 4 frame group. -// If a lower level requirement is specified then this may over ride this value. -#define MAX_MB_RATE 250 -#define MAXRATE_1080P 4000000 - -#define LIMIT_QRANGE_FOR_ALTREF_AND_KEY 1 - -#define MIN_BPB_FACTOR 0.005 -#define MAX_BPB_FACTOR 50 - -#if CONFIG_VP9_HIGHBITDEPTH -#define ASSIGN_MINQ_TABLE(bit_depth, name) \ - do { \ - switch (bit_depth) { \ - case VPX_BITS_8: name = name##_8; break; \ - case VPX_BITS_10: name = name##_10; break; \ - default: \ - assert(bit_depth == VPX_BITS_12); \ - name = name##_12; \ - break; \ - } \ - } while (0) -#else -#define ASSIGN_MINQ_TABLE(bit_depth, name) \ - do { \ - (void)bit_depth; \ - name = name##_8; \ - } while (0) -#endif - -// Tables relating active max Q to active min Q -static int kf_low_motion_minq_8[QINDEX_RANGE]; -static int kf_high_motion_minq_8[QINDEX_RANGE]; -static int arfgf_low_motion_minq_8[QINDEX_RANGE]; -static int arfgf_high_motion_minq_8[QINDEX_RANGE]; -static int inter_minq_8[QINDEX_RANGE]; -static int rtc_minq_8[QINDEX_RANGE]; - -#if CONFIG_VP9_HIGHBITDEPTH -static int kf_low_motion_minq_10[QINDEX_RANGE]; -static int kf_high_motion_minq_10[QINDEX_RANGE]; -static int arfgf_low_motion_minq_10[QINDEX_RANGE]; -static int arfgf_high_motion_minq_10[QINDEX_RANGE]; -static int inter_minq_10[QINDEX_RANGE]; -static int rtc_minq_10[QINDEX_RANGE]; -static int kf_low_motion_minq_12[QINDEX_RANGE]; -static int kf_high_motion_minq_12[QINDEX_RANGE]; -static int arfgf_low_motion_minq_12[QINDEX_RANGE]; -static int arfgf_high_motion_minq_12[QINDEX_RANGE]; -static int inter_minq_12[QINDEX_RANGE]; -static int rtc_minq_12[QINDEX_RANGE]; -#endif - -#ifdef AGGRESSIVE_VBR -static int gf_high = 2400; -static int gf_low = 400; -static int kf_high = 4000; -static int kf_low = 400; -#else -static int gf_high = 2000; -static int gf_low = 400; -static int kf_high = 4800; -static int kf_low = 300; -#endif - -// Functions to compute the active minq lookup table entries based on a -// formulaic approach to facilitate easier adjustment of the Q tables. -// The formulae were derived from computing a 3rd order polynomial best -// fit to the original data (after plotting real maxq vs minq (not q index)) -static int get_minq_index(double maxq, double x3, double x2, double x1, - vpx_bit_depth_t bit_depth) { - int i; - const double minqtarget = VPXMIN(((x3 * maxq + x2) * maxq + x1) * maxq, maxq); - - // Special case handling to deal with the step from q2.0 - // down to lossless mode represented by q 1.0. - if (minqtarget <= 2.0) return 0; - - for (i = 0; i < QINDEX_RANGE; i++) { - if (minqtarget <= vp9_convert_qindex_to_q(i, bit_depth)) return i; - } - - return QINDEX_RANGE - 1; -} - -static void init_minq_luts(int *kf_low_m, int *kf_high_m, int *arfgf_low, - int *arfgf_high, int *inter, int *rtc, - vpx_bit_depth_t bit_depth) { - int i; - for (i = 0; i < QINDEX_RANGE; i++) { - const double maxq = vp9_convert_qindex_to_q(i, bit_depth); - kf_low_m[i] = get_minq_index(maxq, 0.000001, -0.0004, 0.150, bit_depth); - kf_high_m[i] = get_minq_index(maxq, 0.0000021, -0.00125, 0.45, bit_depth); -#ifdef AGGRESSIVE_VBR - arfgf_low[i] = get_minq_index(maxq, 0.0000015, -0.0009, 0.275, bit_depth); - inter[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.80, bit_depth); -#else - arfgf_low[i] = get_minq_index(maxq, 0.0000015, -0.0009, 0.30, bit_depth); - inter[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.70, bit_depth); -#endif - arfgf_high[i] = get_minq_index(maxq, 0.0000021, -0.00125, 0.55, bit_depth); - rtc[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.70, bit_depth); - } -} - -void vp9_rc_init_minq_luts(void) { - init_minq_luts(kf_low_motion_minq_8, kf_high_motion_minq_8, - arfgf_low_motion_minq_8, arfgf_high_motion_minq_8, - inter_minq_8, rtc_minq_8, VPX_BITS_8); -#if CONFIG_VP9_HIGHBITDEPTH - init_minq_luts(kf_low_motion_minq_10, kf_high_motion_minq_10, - arfgf_low_motion_minq_10, arfgf_high_motion_minq_10, - inter_minq_10, rtc_minq_10, VPX_BITS_10); - init_minq_luts(kf_low_motion_minq_12, kf_high_motion_minq_12, - arfgf_low_motion_minq_12, arfgf_high_motion_minq_12, - inter_minq_12, rtc_minq_12, VPX_BITS_12); -#endif -} - -// These functions use formulaic calculations to make playing with the -// quantizer tables easier. If necessary they can be replaced by lookup -// tables if and when things settle down in the experimental bitstream -double vp9_convert_qindex_to_q(int qindex, vpx_bit_depth_t bit_depth) { -// Convert the index to a real Q value (scaled down to match old Q values) -#if CONFIG_VP9_HIGHBITDEPTH - switch (bit_depth) { - case VPX_BITS_8: return vp9_ac_quant(qindex, 0, bit_depth) / 4.0; - case VPX_BITS_10: return vp9_ac_quant(qindex, 0, bit_depth) / 16.0; - default: - assert(bit_depth == VPX_BITS_12); - return vp9_ac_quant(qindex, 0, bit_depth) / 64.0; - } -#else - return vp9_ac_quant(qindex, 0, bit_depth) / 4.0; -#endif -} - -int vp9_convert_q_to_qindex(double q_val, vpx_bit_depth_t bit_depth) { - int i; - - for (i = 0; i < QINDEX_RANGE; ++i) - if (vp9_convert_qindex_to_q(i, bit_depth) >= q_val) break; - - if (i == QINDEX_RANGE) i--; - - return i; -} - -int vp9_rc_bits_per_mb(FRAME_TYPE frame_type, int qindex, - double correction_factor, vpx_bit_depth_t bit_depth) { - const double q = vp9_convert_qindex_to_q(qindex, bit_depth); - int enumerator = frame_type == KEY_FRAME ? 2700000 : 1800000; - - assert(correction_factor <= MAX_BPB_FACTOR && - correction_factor >= MIN_BPB_FACTOR); - - // q based adjustment to baseline enumerator - enumerator += (int)(enumerator * q) >> 12; - return (int)(enumerator * correction_factor / q); -} - -int vp9_estimate_bits_at_q(FRAME_TYPE frame_type, int q, int mbs, - double correction_factor, - vpx_bit_depth_t bit_depth) { - const int bpm = - (int)(vp9_rc_bits_per_mb(frame_type, q, correction_factor, bit_depth)); - return VPXMAX(FRAME_OVERHEAD_BITS, - (int)(((uint64_t)bpm * mbs) >> BPER_MB_NORMBITS)); -} - -int vp9_rc_clamp_pframe_target_size(const VP9_COMP *const cpi, int target) { - const RATE_CONTROL *rc = &cpi->rc; - const VP9EncoderConfig *oxcf = &cpi->oxcf; - - const int min_frame_target = - VPXMAX(rc->min_frame_bandwidth, rc->avg_frame_bandwidth >> 5); - if (target < min_frame_target) target = min_frame_target; - if (cpi->refresh_golden_frame && rc->is_src_frame_alt_ref) { - // If there is an active ARF at this location use the minimum - // bits on this frame even if it is a constructed arf. - // The active maximum quantizer insures that an appropriate - // number of bits will be spent if needed for constructed ARFs. - target = min_frame_target; - } - - // Clip the frame target to the maximum allowed value. - if (target > rc->max_frame_bandwidth) target = rc->max_frame_bandwidth; - - if (oxcf->rc_max_inter_bitrate_pct) { - const int64_t max_rate = - (int64_t)rc->avg_frame_bandwidth * oxcf->rc_max_inter_bitrate_pct / 100; - // target is of type int and VPXMIN cannot evaluate to larger than target - target = (int)VPXMIN(target, max_rate); - } - return target; -} - -int vp9_rc_clamp_iframe_target_size(const VP9_COMP *const cpi, int target) { - const RATE_CONTROL *rc = &cpi->rc; - const VP9EncoderConfig *oxcf = &cpi->oxcf; - if (oxcf->rc_max_intra_bitrate_pct) { - const int64_t max_rate = - (int64_t)rc->avg_frame_bandwidth * oxcf->rc_max_intra_bitrate_pct / 100; - target = (int)VPXMIN(target, max_rate); - } - if (target > rc->max_frame_bandwidth) target = rc->max_frame_bandwidth; - return target; -} - -// TODO(marpan/jianj): bits_off_target and buffer_level are used in the same -// way for CBR mode, for the buffering updates below. Look into removing one -// of these (i.e., bits_off_target). -// Update the buffer level before encoding with the per-frame-bandwidth, -void vp9_update_buffer_level_preencode(VP9_COMP *cpi) { - RATE_CONTROL *const rc = &cpi->rc; - rc->bits_off_target += rc->avg_frame_bandwidth; - // Clip the buffer level to the maximum specified buffer size. - rc->bits_off_target = VPXMIN(rc->bits_off_target, rc->maximum_buffer_size); - rc->buffer_level = rc->bits_off_target; -} - -// Update the buffer level before encoding with the per-frame-bandwidth -// for SVC. The current and all upper temporal layers are updated, needed -// for the layered rate control which involves cumulative buffer levels for -// the temporal layers. Allow for using the timestamp(pts) delta for the -// framerate when the set_ref_frame_config is used. -void vp9_update_buffer_level_svc_preencode(VP9_COMP *cpi) { - SVC *const svc = &cpi->svc; - int i; - // Set this to 1 to use timestamp delta for "framerate" under - // ref_frame_config usage. - int use_timestamp = 1; - const int64_t ts_delta = - svc->time_stamp_superframe - svc->time_stamp_prev[svc->spatial_layer_id]; - for (i = svc->temporal_layer_id; i < svc->number_temporal_layers; ++i) { - const int layer = - LAYER_IDS_TO_IDX(svc->spatial_layer_id, i, svc->number_temporal_layers); - LAYER_CONTEXT *const lc = &svc->layer_context[layer]; - RATE_CONTROL *const lrc = &lc->rc; - if (use_timestamp && cpi->svc.use_set_ref_frame_config && - svc->number_temporal_layers == 1 && ts_delta > 0 && - svc->current_superframe > 0) { - // TODO(marpan): This may need to be modified for temporal layers. - const double framerate_pts = 10000000.0 / ts_delta; - lrc->bits_off_target += saturate_cast_double_to_int( - round(lc->target_bandwidth / framerate_pts)); - } else { - lrc->bits_off_target += saturate_cast_double_to_int( - round(lc->target_bandwidth / lc->framerate)); - } - // Clip buffer level to maximum buffer size for the layer. - lrc->bits_off_target = - VPXMIN(lrc->bits_off_target, lrc->maximum_buffer_size); - lrc->buffer_level = lrc->bits_off_target; - if (i == svc->temporal_layer_id) { - cpi->rc.bits_off_target = lrc->bits_off_target; - cpi->rc.buffer_level = lrc->buffer_level; - } - } -} - -// Update the buffer level for higher temporal layers, given the encoded current -// temporal layer. -static void update_layer_buffer_level_postencode(SVC *svc, - int encoded_frame_size) { - int i = 0; - const int current_temporal_layer = svc->temporal_layer_id; - for (i = current_temporal_layer + 1; i < svc->number_temporal_layers; ++i) { - const int layer = - LAYER_IDS_TO_IDX(svc->spatial_layer_id, i, svc->number_temporal_layers); - LAYER_CONTEXT *lc = &svc->layer_context[layer]; - RATE_CONTROL *lrc = &lc->rc; - lrc->bits_off_target -= encoded_frame_size; - // Clip buffer level to maximum buffer size for the layer. - lrc->bits_off_target = - VPXMIN(lrc->bits_off_target, lrc->maximum_buffer_size); - lrc->buffer_level = lrc->bits_off_target; - } -} - -// Update the buffer level after encoding with encoded frame size. -static void update_buffer_level_postencode(VP9_COMP *cpi, - int encoded_frame_size) { - RATE_CONTROL *const rc = &cpi->rc; - rc->bits_off_target -= encoded_frame_size; - // Clip the buffer level to the maximum specified buffer size. - rc->bits_off_target = VPXMIN(rc->bits_off_target, rc->maximum_buffer_size); - // For screen-content mode, and if frame-dropper is off, don't let buffer - // level go below threshold, given here as -rc->maximum_ buffer_size. - if (cpi->oxcf.content == VP9E_CONTENT_SCREEN && - cpi->oxcf.drop_frames_water_mark == 0) - rc->bits_off_target = VPXMAX(rc->bits_off_target, -rc->maximum_buffer_size); - - rc->buffer_level = rc->bits_off_target; - - if (is_one_pass_svc(cpi)) { - update_layer_buffer_level_postencode(&cpi->svc, encoded_frame_size); - } -} - -int vp9_rc_get_default_min_gf_interval(int width, int height, - double framerate) { - // Assume we do not need any constraint lower than 4K 20 fps - static const double factor_safe = 3840 * 2160 * 20.0; - const double factor = width * height * framerate; - const int default_interval = - clamp((int)round(framerate * 0.125), MIN_GF_INTERVAL, MAX_GF_INTERVAL); - - if (factor <= factor_safe) - return default_interval; - else - return VPXMAX(default_interval, - (int)round(MIN_GF_INTERVAL * factor / factor_safe)); - // Note this logic makes: - // 4K24: 5 - // 4K30: 6 - // 4K60: 12 -} - -int vp9_rc_get_default_max_gf_interval(double framerate, int min_gf_interval) { - int interval = VPXMIN(MAX_GF_INTERVAL, (int)round(framerate * 0.75)); - interval += (interval & 0x01); // Round to even value - return VPXMAX(interval, min_gf_interval); -} - -void vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) { - int i; - - if (pass == 0 && oxcf->rc_mode == VPX_CBR) { - rc->avg_frame_qindex[KEY_FRAME] = oxcf->worst_allowed_q; - rc->avg_frame_qindex[INTER_FRAME] = oxcf->worst_allowed_q; - } else { - rc->avg_frame_qindex[KEY_FRAME] = - (oxcf->worst_allowed_q + oxcf->best_allowed_q) / 2; - rc->avg_frame_qindex[INTER_FRAME] = - (oxcf->worst_allowed_q + oxcf->best_allowed_q) / 2; - } - - rc->last_q[KEY_FRAME] = oxcf->best_allowed_q; - rc->last_q[INTER_FRAME] = oxcf->worst_allowed_q; - - rc->buffer_level = rc->starting_buffer_level; - rc->bits_off_target = rc->starting_buffer_level; - - rc->rolling_target_bits = rc->avg_frame_bandwidth; - rc->rolling_actual_bits = rc->avg_frame_bandwidth; - rc->long_rolling_target_bits = rc->avg_frame_bandwidth; - rc->long_rolling_actual_bits = rc->avg_frame_bandwidth; - - rc->total_actual_bits = 0; - rc->total_target_bits = 0; - rc->total_target_vs_actual = 0; - rc->avg_frame_low_motion = 0; - rc->count_last_scene_change = 0; - rc->af_ratio_onepass_vbr = 10; - rc->prev_avg_source_sad_lag = 0; - rc->high_source_sad = 0; - rc->reset_high_source_sad = 0; - rc->high_source_sad_lagindex = -1; - rc->high_num_blocks_with_motion = 0; - rc->hybrid_intra_scene_change = 0; - rc->re_encode_maxq_scene_change = 0; - rc->alt_ref_gf_group = 0; - rc->last_frame_is_src_altref = 0; - rc->fac_active_worst_inter = 150; - rc->fac_active_worst_gf = 100; - rc->force_qpmin = 0; - for (i = 0; i < MAX_LAG_BUFFERS; ++i) rc->avg_source_sad[i] = 0; - rc->frames_to_key = 0; - rc->frames_since_key = 8; // Sensible default for first frame. - rc->this_key_frame_forced = 0; - rc->next_key_frame_forced = 0; - rc->source_alt_ref_pending = 0; - rc->source_alt_ref_active = 0; - - rc->frames_till_gf_update_due = 0; - rc->constrain_gf_key_freq_onepass_vbr = 1; - rc->ni_av_qi = oxcf->worst_allowed_q; - rc->ni_tot_qi = 0; - rc->ni_frames = 0; - - rc->tot_q = 0.0; - rc->avg_q = vp9_convert_qindex_to_q(oxcf->worst_allowed_q, oxcf->bit_depth); - - for (i = 0; i < RATE_FACTOR_LEVELS; ++i) { - rc->rate_correction_factors[i] = 1.0; - rc->damped_adjustment[i] = 0; - } - - rc->min_gf_interval = oxcf->min_gf_interval; - rc->max_gf_interval = oxcf->max_gf_interval; - if (rc->min_gf_interval == 0) - rc->min_gf_interval = vp9_rc_get_default_min_gf_interval( - oxcf->width, oxcf->height, oxcf->init_framerate); - if (rc->max_gf_interval == 0) - rc->max_gf_interval = vp9_rc_get_default_max_gf_interval( - oxcf->init_framerate, rc->min_gf_interval); - rc->baseline_gf_interval = (rc->min_gf_interval + rc->max_gf_interval) / 2; - if ((oxcf->pass == 0) && (oxcf->rc_mode == VPX_Q)) { - rc->static_scene_max_gf_interval = FIXED_GF_INTERVAL; - } else { - rc->static_scene_max_gf_interval = MAX_STATIC_GF_GROUP_LENGTH; - } - - rc->force_max_q = 0; - rc->last_post_encode_dropped_scene_change = 0; - rc->use_post_encode_drop = 0; - rc->ext_use_post_encode_drop = 0; - rc->disable_overshoot_maxq_cbr = 0; - rc->arf_active_best_quality_adjustment_factor = 1.0; - rc->arf_increase_active_best_quality = 0; - rc->preserve_arf_as_gld = 0; - rc->preserve_next_arf_as_gld = 0; - rc->show_arf_as_gld = 0; -} - -static int check_buffer_above_thresh(VP9_COMP *cpi, int drop_mark) { - SVC *svc = &cpi->svc; - if (!cpi->use_svc || cpi->svc.framedrop_mode != FULL_SUPERFRAME_DROP) { - RATE_CONTROL *const rc = &cpi->rc; - return (rc->buffer_level > drop_mark); - } else { - int i; - // For SVC in the FULL_SUPERFRAME_DROP): the condition on - // buffer (if its above threshold, so no drop) is checked on current and - // upper spatial layers. If any spatial layer is not above threshold then - // we return 0. - for (i = svc->spatial_layer_id; i < svc->number_spatial_layers; ++i) { - const int layer = LAYER_IDS_TO_IDX(i, svc->temporal_layer_id, - svc->number_temporal_layers); - LAYER_CONTEXT *lc = &svc->layer_context[layer]; - RATE_CONTROL *lrc = &lc->rc; - // Exclude check for layer whose bitrate is 0. - if (lc->target_bandwidth > 0) { - const int drop_mark_layer = (int)(cpi->svc.framedrop_thresh[i] * - lrc->optimal_buffer_level / 100); - if (!(lrc->buffer_level > drop_mark_layer)) return 0; - } - } - return 1; - } -} - -static int check_buffer_below_thresh(VP9_COMP *cpi, int drop_mark) { - SVC *svc = &cpi->svc; - if (!cpi->use_svc || cpi->svc.framedrop_mode == LAYER_DROP) { - RATE_CONTROL *const rc = &cpi->rc; - return (rc->buffer_level <= drop_mark); - } else { - int i; - // For SVC in the constrained framedrop mode (svc->framedrop_mode = - // CONSTRAINED_LAYER_DROP or FULL_SUPERFRAME_DROP): the condition on - // buffer (if its below threshold, so drop frame) is checked on current - // and upper spatial layers. For FULL_SUPERFRAME_DROP mode if any - // spatial layer is <= threshold, then we return 1 (drop). - for (i = svc->spatial_layer_id; i < svc->number_spatial_layers; ++i) { - const int layer = LAYER_IDS_TO_IDX(i, svc->temporal_layer_id, - svc->number_temporal_layers); - LAYER_CONTEXT *lc = &svc->layer_context[layer]; - RATE_CONTROL *lrc = &lc->rc; - // Exclude check for layer whose bitrate is 0. - if (lc->target_bandwidth > 0) { - const int drop_mark_layer = (int)(cpi->svc.framedrop_thresh[i] * - lrc->optimal_buffer_level / 100); - if (cpi->svc.framedrop_mode == FULL_SUPERFRAME_DROP) { - if (lrc->buffer_level <= drop_mark_layer) return 1; - } else { - if (!(lrc->buffer_level <= drop_mark_layer)) return 0; - } - } - } - if (cpi->svc.framedrop_mode == FULL_SUPERFRAME_DROP) - return 0; - else - return 1; - } -} - -int vp9_test_drop(VP9_COMP *cpi) { - const VP9EncoderConfig *oxcf = &cpi->oxcf; - RATE_CONTROL *const rc = &cpi->rc; - SVC *svc = &cpi->svc; - int drop_frames_water_mark = oxcf->drop_frames_water_mark; - if (cpi->use_svc) { - // If we have dropped max_consec_drop frames, then we don't - // drop this spatial layer, and reset counter to 0. - if (svc->drop_count[svc->spatial_layer_id] == svc->max_consec_drop) { - svc->drop_count[svc->spatial_layer_id] = 0; - return 0; - } else { - drop_frames_water_mark = svc->framedrop_thresh[svc->spatial_layer_id]; - } - } - if (!drop_frames_water_mark || - (svc->spatial_layer_id > 0 && - svc->framedrop_mode == FULL_SUPERFRAME_DROP)) { - return 0; - } else { - if ((rc->buffer_level < 0 && svc->framedrop_mode != FULL_SUPERFRAME_DROP) || - (check_buffer_below_thresh(cpi, -1) && - svc->framedrop_mode == FULL_SUPERFRAME_DROP)) { - // Always drop if buffer is below 0. - return 1; - } else { - // If buffer is below drop_mark, for now just drop every other frame - // (starting with the next frame) until it increases back over drop_mark. - int drop_mark = - (int)(drop_frames_water_mark * rc->optimal_buffer_level / 100); - if (check_buffer_above_thresh(cpi, drop_mark) && - (rc->decimation_factor > 0)) { - --rc->decimation_factor; - } else if (check_buffer_below_thresh(cpi, drop_mark) && - rc->decimation_factor == 0) { - rc->decimation_factor = 1; - } - if (rc->decimation_factor > 0) { - if (rc->decimation_count > 0) { - --rc->decimation_count; - return 1; - } else { - rc->decimation_count = rc->decimation_factor; - return 0; - } - } else { - rc->decimation_count = 0; - return 0; - } - } - } -} - -int post_encode_drop_cbr(VP9_COMP *cpi, size_t *size) { - size_t frame_size = *size << 3; - int64_t new_buffer_level = - cpi->rc.buffer_level + cpi->rc.avg_frame_bandwidth - (int64_t)frame_size; - - // For now we drop if new buffer level (given the encoded frame size) goes - // below 0. - if (new_buffer_level < 0) { - *size = 0; - vp9_rc_postencode_update_drop_frame(cpi); - // Update flag to use for next frame. - if (cpi->rc.high_source_sad || - (cpi->use_svc && cpi->svc.high_source_sad_superframe)) - cpi->rc.last_post_encode_dropped_scene_change = 1; - // Force max_q on next fame. - cpi->rc.force_max_q = 1; - cpi->rc.avg_frame_qindex[INTER_FRAME] = cpi->rc.worst_quality; - cpi->last_frame_dropped = 1; - cpi->ext_refresh_frame_flags_pending = 0; - if (cpi->use_svc) { - SVC *svc = &cpi->svc; - int sl = 0; - int tl = 0; - svc->last_layer_dropped[svc->spatial_layer_id] = 1; - svc->drop_spatial_layer[svc->spatial_layer_id] = 1; - svc->drop_count[svc->spatial_layer_id]++; - svc->skip_enhancement_layer = 1; - // Postencode drop is only checked on base spatial layer, - // for now if max-q is set on base we force it on all layers. - for (sl = 0; sl < svc->number_spatial_layers; ++sl) { - for (tl = 0; tl < svc->number_temporal_layers; ++tl) { - const int layer = - LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers); - LAYER_CONTEXT *lc = &svc->layer_context[layer]; - RATE_CONTROL *lrc = &lc->rc; - lrc->force_max_q = 1; - lrc->avg_frame_qindex[INTER_FRAME] = cpi->rc.worst_quality; - } - } - } - return 1; - } - - cpi->rc.force_max_q = 0; - cpi->rc.last_post_encode_dropped_scene_change = 0; - return 0; -} - -int vp9_rc_drop_frame(VP9_COMP *cpi) { - SVC *svc = &cpi->svc; - int svc_prev_layer_dropped = 0; - // In the constrained or full_superframe framedrop mode for svc - // (framedrop_mode != (LAYER_DROP && CONSTRAINED_FROM_ABOVE)), - // if the previous spatial layer was dropped, drop the current spatial layer. - if (cpi->use_svc && svc->spatial_layer_id > 0 && - svc->drop_spatial_layer[svc->spatial_layer_id - 1]) - svc_prev_layer_dropped = 1; - if ((svc_prev_layer_dropped && svc->framedrop_mode != LAYER_DROP && - svc->framedrop_mode != CONSTRAINED_FROM_ABOVE_DROP) || - svc->force_drop_constrained_from_above[svc->spatial_layer_id] || - vp9_test_drop(cpi)) { - vp9_rc_postencode_update_drop_frame(cpi); - cpi->ext_refresh_frame_flags_pending = 0; - cpi->last_frame_dropped = 1; - if (cpi->use_svc) { - svc->last_layer_dropped[svc->spatial_layer_id] = 1; - svc->drop_spatial_layer[svc->spatial_layer_id] = 1; - svc->drop_count[svc->spatial_layer_id]++; - svc->skip_enhancement_layer = 1; - if (svc->framedrop_mode == LAYER_DROP || - (svc->framedrop_mode == CONSTRAINED_FROM_ABOVE_DROP && - svc->force_drop_constrained_from_above[svc->number_spatial_layers - - 1] == 0) || - svc->drop_spatial_layer[0] == 0) { - // For the case of constrained drop mode where full superframe is - // dropped, we don't increment the svc frame counters. - // In particular temporal layer counter (which is incremented in - // vp9_inc_frame_in_layer()) won't be incremented, so on a dropped - // frame we try the same temporal_layer_id on next incoming frame. - // This is to avoid an issue with temporal alignment with full - // superframe dropping. - vp9_inc_frame_in_layer(cpi); - } - if (svc->spatial_layer_id == svc->number_spatial_layers - 1) { - int i; - int all_layers_drop = 1; - for (i = 0; i < svc->spatial_layer_id; i++) { - if (svc->drop_spatial_layer[i] == 0) { - all_layers_drop = 0; - break; - } - } - if (all_layers_drop == 1) svc->skip_enhancement_layer = 0; - } - } - return 1; - } - return 0; -} - -static int adjust_q_cbr(const VP9_COMP *cpi, int q) { - // This makes sure q is between oscillating Qs to prevent resonance. - if (!cpi->rc.reset_high_source_sad && - (!cpi->oxcf.gf_cbr_boost_pct || - !(cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame)) && - (cpi->rc.rc_1_frame * cpi->rc.rc_2_frame == -1) && - cpi->rc.q_1_frame != cpi->rc.q_2_frame) { - int qclamp = clamp(q, VPXMIN(cpi->rc.q_1_frame, cpi->rc.q_2_frame), - VPXMAX(cpi->rc.q_1_frame, cpi->rc.q_2_frame)); - // If the previous frame had overshoot and the current q needs to increase - // above the clamped value, reduce the clamp for faster reaction to - // overshoot. - if (cpi->rc.rc_1_frame == -1 && q > qclamp) - q = (q + qclamp) >> 1; - else - q = qclamp; - } - if (cpi->oxcf.content == VP9E_CONTENT_SCREEN && - cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) - vp9_cyclic_refresh_limit_q(cpi, &q); - return VPXMAX(VPXMIN(q, cpi->rc.worst_quality), cpi->rc.best_quality); -} - -static double get_rate_correction_factor(const VP9_COMP *cpi) { - const RATE_CONTROL *const rc = &cpi->rc; - const VP9_COMMON *const cm = &cpi->common; - double rcf; - - if (frame_is_intra_only(cm)) { - rcf = rc->rate_correction_factors[KF_STD]; - } else if (cpi->oxcf.pass == 2) { - RATE_FACTOR_LEVEL rf_lvl = - cpi->twopass.gf_group.rf_level[cpi->twopass.gf_group.index]; - rcf = rc->rate_correction_factors[rf_lvl]; - } else { - if ((cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) && - !rc->is_src_frame_alt_ref && !cpi->use_svc && - (cpi->oxcf.rc_mode != VPX_CBR || cpi->oxcf.gf_cbr_boost_pct > 100)) - rcf = rc->rate_correction_factors[GF_ARF_STD]; - else - rcf = rc->rate_correction_factors[INTER_NORMAL]; - } - rcf *= rcf_mult[rc->frame_size_selector]; - return fclamp(rcf, MIN_BPB_FACTOR, MAX_BPB_FACTOR); -} - -static void set_rate_correction_factor(VP9_COMP *cpi, double factor) { - RATE_CONTROL *const rc = &cpi->rc; - const VP9_COMMON *const cm = &cpi->common; - - // Normalize RCF to account for the size-dependent scaling factor. - factor /= rcf_mult[cpi->rc.frame_size_selector]; - - factor = fclamp(factor, MIN_BPB_FACTOR, MAX_BPB_FACTOR); - - if (frame_is_intra_only(cm)) { - rc->rate_correction_factors[KF_STD] = factor; - } else if (cpi->oxcf.pass == 2) { - RATE_FACTOR_LEVEL rf_lvl = - cpi->twopass.gf_group.rf_level[cpi->twopass.gf_group.index]; - rc->rate_correction_factors[rf_lvl] = factor; - } else { - if ((cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) && - !rc->is_src_frame_alt_ref && !cpi->use_svc && - (cpi->oxcf.rc_mode != VPX_CBR || cpi->oxcf.gf_cbr_boost_pct > 100)) - rc->rate_correction_factors[GF_ARF_STD] = factor; - else - rc->rate_correction_factors[INTER_NORMAL] = factor; - } -} - -void vp9_rc_update_rate_correction_factors(VP9_COMP *cpi) { - const VP9_COMMON *const cm = &cpi->common; - int correction_factor = 100; - double rate_correction_factor = get_rate_correction_factor(cpi); - double adjustment_limit; - RATE_FACTOR_LEVEL rf_lvl = - cpi->twopass.gf_group.rf_level[cpi->twopass.gf_group.index]; - - int projected_size_based_on_q = 0; - - // Do not update the rate factors for arf overlay frames. - if (cpi->rc.is_src_frame_alt_ref) return; - - // Clear down mmx registers to allow floating point in what follows - vpx_clear_system_state(); - - // Work out how big we would have expected the frame to be at this Q given - // the current correction factor. - // Stay in double to avoid int overflow when values are large - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cpi->common.seg.enabled) { - projected_size_based_on_q = - vp9_cyclic_refresh_estimate_bits_at_q(cpi, rate_correction_factor); - } else { - FRAME_TYPE frame_type = cm->intra_only ? KEY_FRAME : cm->frame_type; - projected_size_based_on_q = - vp9_estimate_bits_at_q(frame_type, cm->base_qindex, cm->MBs, - rate_correction_factor, cm->bit_depth); - } - // Work out a size correction factor. - if (projected_size_based_on_q > FRAME_OVERHEAD_BITS) - correction_factor = (int)((100 * (int64_t)cpi->rc.projected_frame_size) / - projected_size_based_on_q); - - // Do not use damped adjustment for the first frame of each frame type - if (!cpi->rc.damped_adjustment[rf_lvl]) { - adjustment_limit = 1.0; - cpi->rc.damped_adjustment[rf_lvl] = 1; - } else { - // More heavily damped adjustment used if we have been oscillating either - // side of target. - adjustment_limit = - 0.25 + 0.5 * VPXMIN(1, fabs(log10(0.01 * correction_factor))); - } - - cpi->rc.q_2_frame = cpi->rc.q_1_frame; - cpi->rc.q_1_frame = cm->base_qindex; - cpi->rc.rc_2_frame = cpi->rc.rc_1_frame; - if (correction_factor > 110) - cpi->rc.rc_1_frame = -1; - else if (correction_factor < 90) - cpi->rc.rc_1_frame = 1; - else - cpi->rc.rc_1_frame = 0; - - // Turn off oscilation detection in the case of massive overshoot. - if (cpi->rc.rc_1_frame == -1 && cpi->rc.rc_2_frame == 1 && - correction_factor > 1000) { - cpi->rc.rc_2_frame = 0; - } - - if (correction_factor > 102) { - // We are not already at the worst allowable quality - correction_factor = - (int)(100 + ((correction_factor - 100) * adjustment_limit)); - rate_correction_factor = (rate_correction_factor * correction_factor) / 100; - // Keep rate_correction_factor within limits - if (rate_correction_factor > MAX_BPB_FACTOR) - rate_correction_factor = MAX_BPB_FACTOR; - } else if (correction_factor < 99) { - // We are not already at the best allowable quality - correction_factor = - (int)(100 - ((100 - correction_factor) * adjustment_limit)); - rate_correction_factor = (rate_correction_factor * correction_factor) / 100; - - // Keep rate_correction_factor within limits - if (rate_correction_factor < MIN_BPB_FACTOR) - rate_correction_factor = MIN_BPB_FACTOR; - } - - set_rate_correction_factor(cpi, rate_correction_factor); -} - -int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame, - int active_best_quality, int active_worst_quality) { - const VP9_COMMON *const cm = &cpi->common; - CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; - int q = active_worst_quality; - int last_error = INT_MAX; - int i, target_bits_per_mb, bits_per_mb_at_this_q; - const double correction_factor = get_rate_correction_factor(cpi); - - // Calculate required scaling factor based on target frame size and size of - // frame produced using previous Q. - target_bits_per_mb = - (int)(((uint64_t)target_bits_per_frame << BPER_MB_NORMBITS) / cm->MBs); - - i = active_best_quality; - - do { - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cr->apply_cyclic_refresh && - (!cpi->oxcf.gf_cbr_boost_pct || !cpi->refresh_golden_frame)) { - bits_per_mb_at_this_q = - (int)vp9_cyclic_refresh_rc_bits_per_mb(cpi, i, correction_factor); - } else { - FRAME_TYPE frame_type = cm->intra_only ? KEY_FRAME : cm->frame_type; - bits_per_mb_at_this_q = (int)vp9_rc_bits_per_mb( - frame_type, i, correction_factor, cm->bit_depth); - } - - if (bits_per_mb_at_this_q <= target_bits_per_mb) { - if ((target_bits_per_mb - bits_per_mb_at_this_q) <= last_error) - q = i; - else - q = i - 1; - - break; - } else { - last_error = bits_per_mb_at_this_q - target_bits_per_mb; - } - } while (++i <= active_worst_quality); - - // Adjustment to q for CBR mode. - if (cpi->oxcf.rc_mode == VPX_CBR) return adjust_q_cbr(cpi, q); - - return q; -} - -static int get_active_quality(int q, int gfu_boost, int low, int high, - int *low_motion_minq, int *high_motion_minq) { - if (gfu_boost > high) { - return low_motion_minq[q]; - } else if (gfu_boost < low) { - return high_motion_minq[q]; - } else { - const int gap = high - low; - const int offset = high - gfu_boost; - const int qdiff = high_motion_minq[q] - low_motion_minq[q]; - const int adjustment = ((offset * qdiff) + (gap >> 1)) / gap; - return low_motion_minq[q] + adjustment; - } -} - -static int get_kf_active_quality(const RATE_CONTROL *const rc, int q, - vpx_bit_depth_t bit_depth) { - int *kf_low_motion_minq; - int *kf_high_motion_minq; - ASSIGN_MINQ_TABLE(bit_depth, kf_low_motion_minq); - ASSIGN_MINQ_TABLE(bit_depth, kf_high_motion_minq); - return get_active_quality(q, rc->kf_boost, kf_low, kf_high, - kf_low_motion_minq, kf_high_motion_minq); -} - -static int get_gf_active_quality(const VP9_COMP *const cpi, int q, - vpx_bit_depth_t bit_depth) { - const GF_GROUP *const gf_group = &cpi->twopass.gf_group; - const RATE_CONTROL *const rc = &cpi->rc; - - int *arfgf_low_motion_minq; - int *arfgf_high_motion_minq; - const int gfu_boost = cpi->multi_layer_arf - ? gf_group->gfu_boost[gf_group->index] - : rc->gfu_boost; - ASSIGN_MINQ_TABLE(bit_depth, arfgf_low_motion_minq); - ASSIGN_MINQ_TABLE(bit_depth, arfgf_high_motion_minq); - return get_active_quality(q, gfu_boost, gf_low, gf_high, - arfgf_low_motion_minq, arfgf_high_motion_minq); -} - -static int calc_active_worst_quality_one_pass_vbr(const VP9_COMP *cpi) { - const RATE_CONTROL *const rc = &cpi->rc; - const unsigned int curr_frame = cpi->common.current_video_frame; - int active_worst_quality; - - if (cpi->common.frame_type == KEY_FRAME) { - active_worst_quality = - curr_frame == 0 ? rc->worst_quality : rc->last_q[KEY_FRAME] << 1; - } else { - if (!rc->is_src_frame_alt_ref && !cpi->use_svc && - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { - active_worst_quality = - curr_frame == 1 - ? rc->last_q[KEY_FRAME] * 5 >> 2 - : rc->last_q[INTER_FRAME] * rc->fac_active_worst_gf / 100; - } else { - active_worst_quality = curr_frame == 1 - ? rc->last_q[KEY_FRAME] << 1 - : rc->avg_frame_qindex[INTER_FRAME] * - rc->fac_active_worst_inter / 100; - } - } - return VPXMIN(active_worst_quality, rc->worst_quality); -} - -// Adjust active_worst_quality level based on buffer level. -static int calc_active_worst_quality_one_pass_cbr(const VP9_COMP *cpi) { - // Adjust active_worst_quality: If buffer is above the optimal/target level, - // bring active_worst_quality down depending on fullness of buffer. - // If buffer is below the optimal level, let the active_worst_quality go from - // ambient Q (at buffer = optimal level) to worst_quality level - // (at buffer = critical level). - const VP9_COMMON *const cm = &cpi->common; - const RATE_CONTROL *rc = &cpi->rc; - // Buffer level below which we push active_worst to worst_quality. - int64_t critical_level = rc->optimal_buffer_level >> 3; - int64_t buff_lvl_step = 0; - int adjustment = 0; - int active_worst_quality; - int ambient_qp; - unsigned int num_frames_weight_key = 5 * cpi->svc.number_temporal_layers; - if (frame_is_intra_only(cm) || rc->reset_high_source_sad || rc->force_max_q) - return rc->worst_quality; - // For ambient_qp we use minimum of avg_frame_qindex[KEY_FRAME/INTER_FRAME] - // for the first few frames following key frame. These are both initialized - // to worst_quality and updated with (3/4, 1/4) average in postencode_update. - // So for first few frames following key, the qp of that key frame is weighted - // into the active_worst_quality setting. - ambient_qp = (cm->current_video_frame < num_frames_weight_key) - ? VPXMIN(rc->avg_frame_qindex[INTER_FRAME], - rc->avg_frame_qindex[KEY_FRAME]) - : rc->avg_frame_qindex[INTER_FRAME]; - active_worst_quality = VPXMIN(rc->worst_quality, (ambient_qp * 5) >> 2); - // For SVC if the current base spatial layer was key frame, use the QP from - // that base layer for ambient_qp. - if (cpi->use_svc && cpi->svc.spatial_layer_id > 0) { - int layer = LAYER_IDS_TO_IDX(0, cpi->svc.temporal_layer_id, - cpi->svc.number_temporal_layers); - const LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer]; - if (lc->is_key_frame) { - const RATE_CONTROL *lrc = &lc->rc; - ambient_qp = VPXMIN(ambient_qp, lrc->last_q[KEY_FRAME]); - active_worst_quality = VPXMIN(rc->worst_quality, (ambient_qp * 9) >> 3); - } - } - if (rc->buffer_level > rc->optimal_buffer_level) { - // Adjust down. - // Maximum limit for down adjustment ~30%; make it lower for screen content. - int max_adjustment_down = active_worst_quality / 3; - if (cpi->oxcf.content == VP9E_CONTENT_SCREEN) - max_adjustment_down = active_worst_quality >> 3; - if (max_adjustment_down) { - buff_lvl_step = ((rc->maximum_buffer_size - rc->optimal_buffer_level) / - max_adjustment_down); - if (buff_lvl_step) - adjustment = (int)((rc->buffer_level - rc->optimal_buffer_level) / - buff_lvl_step); - active_worst_quality -= adjustment; - } - } else if (rc->buffer_level > critical_level) { - // Adjust up from ambient Q. - if (critical_level) { - buff_lvl_step = (rc->optimal_buffer_level - critical_level); - if (buff_lvl_step) { - adjustment = (int)((rc->worst_quality - ambient_qp) * - (rc->optimal_buffer_level - rc->buffer_level) / - buff_lvl_step); - } - active_worst_quality = ambient_qp + adjustment; - } - } else { - // Set to worst_quality if buffer is below critical level. - active_worst_quality = rc->worst_quality; - } - return active_worst_quality; -} - -static int rc_pick_q_and_bounds_one_pass_cbr(const VP9_COMP *cpi, - int *bottom_index, - int *top_index) { - const VP9_COMMON *const cm = &cpi->common; - const RATE_CONTROL *const rc = &cpi->rc; - int active_best_quality; - int active_worst_quality = calc_active_worst_quality_one_pass_cbr(cpi); - int q; - int *rtc_minq; - ASSIGN_MINQ_TABLE(cm->bit_depth, rtc_minq); - - if (frame_is_intra_only(cm)) { - active_best_quality = rc->best_quality; - // Handle the special case for key frames forced when we have reached - // the maximum key frame interval. Here force the Q to a range - // based on the ambient Q to reduce the risk of popping. - if (rc->this_key_frame_forced) { - int qindex = rc->last_boosted_qindex; - double last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth); - int delta_qindex = vp9_compute_qdelta( - rc, last_boosted_q, (last_boosted_q * 0.75), cm->bit_depth); - active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality); - } else if (cm->current_video_frame > 0) { - // not first frame of one pass and kf_boost is set - double q_adj_factor = 1.0; - double q_val; - - active_best_quality = get_kf_active_quality( - rc, rc->avg_frame_qindex[KEY_FRAME], cm->bit_depth); - - // Allow somewhat lower kf minq with small image formats. - if ((cm->width * cm->height) <= (352 * 288)) { - q_adj_factor -= 0.25; - } - - // Convert the adjustment factor to a qindex delta - // on active_best_quality. - q_val = vp9_convert_qindex_to_q(active_best_quality, cm->bit_depth); - active_best_quality += - vp9_compute_qdelta(rc, q_val, q_val * q_adj_factor, cm->bit_depth); - } - } else if (!rc->is_src_frame_alt_ref && !cpi->use_svc && - cpi->oxcf.gf_cbr_boost_pct && - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { - // Use the lower of active_worst_quality and recent - // average Q as basis for GF/ARF best Q limit unless last frame was - // a key frame. - if (rc->frames_since_key > 1 && - rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) { - q = rc->avg_frame_qindex[INTER_FRAME]; - } else { - q = active_worst_quality; - } - active_best_quality = get_gf_active_quality(cpi, q, cm->bit_depth); - } else { - // Use the lower of active_worst_quality and recent/average Q. - if (cm->current_video_frame > 1) { - if (rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) - active_best_quality = rtc_minq[rc->avg_frame_qindex[INTER_FRAME]]; - else - active_best_quality = rtc_minq[active_worst_quality]; - } else { - if (rc->avg_frame_qindex[KEY_FRAME] < active_worst_quality) - active_best_quality = rtc_minq[rc->avg_frame_qindex[KEY_FRAME]]; - else - active_best_quality = rtc_minq[active_worst_quality]; - } - } - - // Clip the active best and worst quality values to limits - active_best_quality = - clamp(active_best_quality, rc->best_quality, rc->worst_quality); - active_worst_quality = - clamp(active_worst_quality, active_best_quality, rc->worst_quality); - - *top_index = active_worst_quality; - *bottom_index = active_best_quality; - - // Special case code to try and match quality with forced key frames - if (frame_is_intra_only(cm) && rc->this_key_frame_forced) { - q = rc->last_boosted_qindex; - } else { - q = vp9_rc_regulate_q(cpi, rc->this_frame_target, active_best_quality, - active_worst_quality); - if (q > *top_index) { - // Special case when we are targeting the max allowed rate - if (rc->this_frame_target >= rc->max_frame_bandwidth) - *top_index = q; - else - q = *top_index; - } - } - - assert(*top_index <= rc->worst_quality && *top_index >= rc->best_quality); - assert(*bottom_index <= rc->worst_quality && - *bottom_index >= rc->best_quality); - assert(q <= rc->worst_quality && q >= rc->best_quality); - return q; -} - -static int get_active_cq_level_one_pass(const RATE_CONTROL *rc, - const VP9EncoderConfig *const oxcf) { - static const double cq_adjust_threshold = 0.1; - int active_cq_level = oxcf->cq_level; - if (oxcf->rc_mode == VPX_CQ && rc->total_target_bits > 0) { - const double x = (double)rc->total_actual_bits / rc->total_target_bits; - if (x < cq_adjust_threshold) { - active_cq_level = (int)(active_cq_level * x / cq_adjust_threshold); - } - } - return active_cq_level; -} - -#define SMOOTH_PCT_MIN 0.1 -#define SMOOTH_PCT_DIV 0.05 -static int get_active_cq_level_two_pass(const TWO_PASS *twopass, - const RATE_CONTROL *rc, - const VP9EncoderConfig *const oxcf) { - static const double cq_adjust_threshold = 0.1; - int active_cq_level = oxcf->cq_level; - if (oxcf->rc_mode == VPX_CQ) { - if (twopass->mb_smooth_pct > SMOOTH_PCT_MIN) { - active_cq_level -= - (int)((twopass->mb_smooth_pct - SMOOTH_PCT_MIN) / SMOOTH_PCT_DIV); - active_cq_level = VPXMAX(active_cq_level, 0); - } - if (rc->total_target_bits > 0) { - const double x = (double)rc->total_actual_bits / rc->total_target_bits; - if (x < cq_adjust_threshold) { - active_cq_level = (int)(active_cq_level * x / cq_adjust_threshold); - } - } - } - return active_cq_level; -} - -static int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi, - int *bottom_index, - int *top_index) { - const VP9_COMMON *const cm = &cpi->common; - const RATE_CONTROL *const rc = &cpi->rc; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - const int cq_level = get_active_cq_level_one_pass(rc, oxcf); - int active_best_quality; - int active_worst_quality = calc_active_worst_quality_one_pass_vbr(cpi); - int q; - int *inter_minq; - ASSIGN_MINQ_TABLE(cm->bit_depth, inter_minq); - - if (frame_is_intra_only(cm)) { - if (oxcf->rc_mode == VPX_Q) { - int qindex = cq_level; - double qstart = vp9_convert_qindex_to_q(qindex, cm->bit_depth); - int delta_qindex = - vp9_compute_qdelta(rc, qstart, qstart * 0.25, cm->bit_depth); - active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality); - } else if (rc->this_key_frame_forced) { - // Handle the special case for key frames forced when we have reached - // the maximum key frame interval. Here force the Q to a range - // based on the ambient Q to reduce the risk of popping. - int qindex = rc->last_boosted_qindex; - double last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth); - int delta_qindex = vp9_compute_qdelta( - rc, last_boosted_q, last_boosted_q * 0.75, cm->bit_depth); - active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality); - } else { - // not first frame of one pass and kf_boost is set - double q_adj_factor = 1.0; - double q_val; - - active_best_quality = get_kf_active_quality( - rc, rc->avg_frame_qindex[KEY_FRAME], cm->bit_depth); - - // Allow somewhat lower kf minq with small image formats. - if ((cm->width * cm->height) <= (352 * 288)) { - q_adj_factor -= 0.25; - } - - // Convert the adjustment factor to a qindex delta - // on active_best_quality. - q_val = vp9_convert_qindex_to_q(active_best_quality, cm->bit_depth); - active_best_quality += - vp9_compute_qdelta(rc, q_val, q_val * q_adj_factor, cm->bit_depth); - } - } else if (!rc->is_src_frame_alt_ref && - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { - // Use the lower of active_worst_quality and recent - // average Q as basis for GF/ARF best Q limit unless last frame was - // a key frame. - if (rc->frames_since_key > 1) { - if (rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) { - q = rc->avg_frame_qindex[INTER_FRAME]; - } else { - q = active_worst_quality; - } - } else { - q = rc->avg_frame_qindex[KEY_FRAME]; - } - // For constrained quality don't allow Q less than the cq level - if (oxcf->rc_mode == VPX_CQ) { - if (q < cq_level) q = cq_level; - - active_best_quality = get_gf_active_quality(cpi, q, cm->bit_depth); - - // Constrained quality use slightly lower active best. - active_best_quality = active_best_quality * 15 / 16; - - } else if (oxcf->rc_mode == VPX_Q) { - int qindex = cq_level; - double qstart = vp9_convert_qindex_to_q(qindex, cm->bit_depth); - int delta_qindex; - if (cpi->refresh_alt_ref_frame) - delta_qindex = - vp9_compute_qdelta(rc, qstart, qstart * 0.40, cm->bit_depth); - else - delta_qindex = - vp9_compute_qdelta(rc, qstart, qstart * 0.50, cm->bit_depth); - active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality); - } else { - active_best_quality = get_gf_active_quality(cpi, q, cm->bit_depth); - } - } else { - if (oxcf->rc_mode == VPX_Q) { - int qindex = cq_level; - double qstart = vp9_convert_qindex_to_q(qindex, cm->bit_depth); - double delta_rate[FIXED_GF_INTERVAL] = { 0.50, 1.0, 0.85, 1.0, - 0.70, 1.0, 0.85, 1.0 }; - int delta_qindex = vp9_compute_qdelta( - rc, qstart, - qstart * delta_rate[cm->current_video_frame % FIXED_GF_INTERVAL], - cm->bit_depth); - active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality); - } else { - // Use the min of the average Q and active_worst_quality as basis for - // active_best. - if (cm->current_video_frame > 1) { - q = VPXMIN(rc->avg_frame_qindex[INTER_FRAME], active_worst_quality); - active_best_quality = inter_minq[q]; - } else { - active_best_quality = inter_minq[rc->avg_frame_qindex[KEY_FRAME]]; - } - // For the constrained quality mode we don't want - // q to fall below the cq level. - if ((oxcf->rc_mode == VPX_CQ) && (active_best_quality < cq_level)) { - active_best_quality = cq_level; - } - } - } - - // Clip the active best and worst quality values to limits - active_best_quality = - clamp(active_best_quality, rc->best_quality, rc->worst_quality); - active_worst_quality = - clamp(active_worst_quality, active_best_quality, rc->worst_quality); - - *top_index = active_worst_quality; - *bottom_index = active_best_quality; - -#if LIMIT_QRANGE_FOR_ALTREF_AND_KEY - { - int qdelta = 0; - vpx_clear_system_state(); - - // Limit Q range for the adaptive loop. - if (cm->frame_type == KEY_FRAME && !rc->this_key_frame_forced && - !(cm->current_video_frame == 0)) { - qdelta = vp9_compute_qdelta_by_rate( - &cpi->rc, cm->frame_type, active_worst_quality, 2.0, cm->bit_depth); - } else if (!rc->is_src_frame_alt_ref && - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { - qdelta = vp9_compute_qdelta_by_rate( - &cpi->rc, cm->frame_type, active_worst_quality, 1.75, cm->bit_depth); - } - if (rc->high_source_sad && cpi->sf.use_altref_onepass) qdelta = 0; - *top_index = active_worst_quality + qdelta; - *top_index = (*top_index > *bottom_index) ? *top_index : *bottom_index; - } -#endif - - if (oxcf->rc_mode == VPX_Q) { - q = active_best_quality; - // Special case code to try and match quality with forced key frames - } else if ((cm->frame_type == KEY_FRAME) && rc->this_key_frame_forced) { - q = rc->last_boosted_qindex; - } else { - q = vp9_rc_regulate_q(cpi, rc->this_frame_target, active_best_quality, - active_worst_quality); - if (q > *top_index) { - // Special case when we are targeting the max allowed rate - if (rc->this_frame_target >= rc->max_frame_bandwidth) - *top_index = q; - else - q = *top_index; - } - } - - assert(*top_index <= rc->worst_quality && *top_index >= rc->best_quality); - assert(*bottom_index <= rc->worst_quality && - *bottom_index >= rc->best_quality); - assert(q <= rc->worst_quality && q >= rc->best_quality); - return q; -} - -int vp9_frame_type_qdelta(const VP9_COMP *cpi, int rf_level, int q) { - static const double rate_factor_deltas[RATE_FACTOR_LEVELS] = { - 1.00, // INTER_NORMAL - 1.00, // INTER_HIGH - 1.50, // GF_ARF_LOW - 1.75, // GF_ARF_STD - 2.00, // KF_STD - }; - const VP9_COMMON *const cm = &cpi->common; - - int qdelta = vp9_compute_qdelta_by_rate( - &cpi->rc, cm->frame_type, q, rate_factor_deltas[rf_level], cm->bit_depth); - return qdelta; -} - -#define STATIC_MOTION_THRESH 95 - -static void pick_kf_q_bound_two_pass(const VP9_COMP *cpi, int *bottom_index, - int *top_index) { - const VP9_COMMON *const cm = &cpi->common; - const RATE_CONTROL *const rc = &cpi->rc; - int active_best_quality; - int active_worst_quality = cpi->twopass.active_worst_quality; - - if (rc->this_key_frame_forced) { - // Handle the special case for key frames forced when we have reached - // the maximum key frame interval. Here force the Q to a range - // based on the ambient Q to reduce the risk of popping. - double last_boosted_q; - int delta_qindex; - int qindex; - - if (cpi->twopass.last_kfgroup_zeromotion_pct >= STATIC_MOTION_THRESH) { - qindex = VPXMIN(rc->last_kf_qindex, rc->last_boosted_qindex); - active_best_quality = qindex; - last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth); - delta_qindex = vp9_compute_qdelta(rc, last_boosted_q, - last_boosted_q * 1.25, cm->bit_depth); - active_worst_quality = - VPXMIN(qindex + delta_qindex, active_worst_quality); - } else { - qindex = rc->last_boosted_qindex; - last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth); - delta_qindex = vp9_compute_qdelta(rc, last_boosted_q, - last_boosted_q * 0.75, cm->bit_depth); - active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality); - } - } else { - // Not forced keyframe. - double q_adj_factor = 1.0; - double q_val; - // Baseline value derived from cpi->active_worst_quality and kf boost. - active_best_quality = - get_kf_active_quality(rc, active_worst_quality, cm->bit_depth); - if (cpi->twopass.kf_zeromotion_pct >= STATIC_KF_GROUP_THRESH) { - active_best_quality /= 4; - } - - // Don't allow the active min to be lossless (q0) unlesss the max q - // already indicates lossless. - active_best_quality = - VPXMIN(active_worst_quality, VPXMAX(1, active_best_quality)); - - // Allow somewhat lower kf minq with small image formats. - if ((cm->width * cm->height) <= (352 * 288)) { - q_adj_factor -= 0.25; - } - - // Make a further adjustment based on the kf zero motion measure. - q_adj_factor += 0.05 - (0.001 * (double)cpi->twopass.kf_zeromotion_pct); - - // Convert the adjustment factor to a qindex delta - // on active_best_quality. - q_val = vp9_convert_qindex_to_q(active_best_quality, cm->bit_depth); - active_best_quality += - vp9_compute_qdelta(rc, q_val, q_val * q_adj_factor, cm->bit_depth); - } - *top_index = active_worst_quality; - *bottom_index = active_best_quality; -} - -static int rc_constant_q(const VP9_COMP *cpi, int *bottom_index, int *top_index, - int gf_group_index) { - const VP9_COMMON *const cm = &cpi->common; - const RATE_CONTROL *const rc = &cpi->rc; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - const GF_GROUP *gf_group = &cpi->twopass.gf_group; - const int is_intra_frame = frame_is_intra_only(cm); - - const int cq_level = get_active_cq_level_two_pass(&cpi->twopass, rc, oxcf); - - int q = cq_level; - int active_best_quality = cq_level; - int active_worst_quality = cq_level; - - // Key frame qp decision - if (is_intra_frame && rc->frames_to_key > 1) - pick_kf_q_bound_two_pass(cpi, &active_best_quality, &active_worst_quality); - - // ARF / GF qp decision - if (!is_intra_frame && !rc->is_src_frame_alt_ref && - cpi->refresh_alt_ref_frame) { - active_best_quality = get_gf_active_quality(cpi, q, cm->bit_depth); - - // Modify best quality for second level arfs. For mode VPX_Q this - // becomes the baseline frame q. - if (gf_group->rf_level[gf_group_index] == GF_ARF_LOW) { - const int layer_depth = gf_group->layer_depth[gf_group_index]; - // linearly fit the frame q depending on the layer depth index from - // the base layer ARF. - active_best_quality = ((layer_depth - 1) * cq_level + - active_best_quality + layer_depth / 2) / - layer_depth; - } - } - - q = active_best_quality; - *top_index = active_worst_quality; - *bottom_index = active_best_quality; - return q; -} - -int vp9_rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, int *bottom_index, - int *top_index, int gf_group_index) { - const VP9_COMMON *const cm = &cpi->common; - const RATE_CONTROL *const rc = &cpi->rc; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - const GF_GROUP *gf_group = &cpi->twopass.gf_group; - const int cq_level = get_active_cq_level_two_pass(&cpi->twopass, rc, oxcf); - int active_best_quality; - int active_worst_quality = cpi->twopass.active_worst_quality; - int q; - int *inter_minq; - int arf_active_best_quality_hl; - int *arfgf_high_motion_minq, *arfgf_low_motion_minq; - const int boost_frame = - !rc->is_src_frame_alt_ref && - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame); - - ASSIGN_MINQ_TABLE(cm->bit_depth, inter_minq); - - if (oxcf->rc_mode == VPX_Q) - return rc_constant_q(cpi, bottom_index, top_index, gf_group_index); - - if (frame_is_intra_only(cm)) { - pick_kf_q_bound_two_pass(cpi, &active_best_quality, &active_worst_quality); - } else if (boost_frame) { - // Use the lower of active_worst_quality and recent - // average Q as basis for GF/ARF best Q limit unless last frame was - // a key frame. - if (rc->frames_since_key > 1 && - rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) { - q = rc->avg_frame_qindex[INTER_FRAME]; - } else { - q = active_worst_quality; - } - // For constrained quality don't allow Q less than the cq level - if (oxcf->rc_mode == VPX_CQ) { - if (q < cq_level) q = cq_level; - } - active_best_quality = get_gf_active_quality(cpi, q, cm->bit_depth); - arf_active_best_quality_hl = active_best_quality; - - if (rc->arf_increase_active_best_quality == 1) { - ASSIGN_MINQ_TABLE(cm->bit_depth, arfgf_high_motion_minq); - arf_active_best_quality_hl = arfgf_high_motion_minq[q]; - } else if (rc->arf_increase_active_best_quality == -1) { - ASSIGN_MINQ_TABLE(cm->bit_depth, arfgf_low_motion_minq); - arf_active_best_quality_hl = arfgf_low_motion_minq[q]; - } - active_best_quality = - (int)((double)active_best_quality * - rc->arf_active_best_quality_adjustment_factor + - (double)arf_active_best_quality_hl * - (1.0 - rc->arf_active_best_quality_adjustment_factor)); - - // Modify best quality for second level arfs. For mode VPX_Q this - // becomes the baseline frame q. - if (gf_group->rf_level[gf_group_index] == GF_ARF_LOW) { - const int layer_depth = gf_group->layer_depth[gf_group_index]; - // linearly fit the frame q depending on the layer depth index from - // the base layer ARF. - active_best_quality = - ((layer_depth - 1) * q + active_best_quality + layer_depth / 2) / - layer_depth; - } - } else { - active_best_quality = inter_minq[active_worst_quality]; - - // For the constrained quality mode we don't want - // q to fall below the cq level. - if ((oxcf->rc_mode == VPX_CQ) && (active_best_quality < cq_level)) { - active_best_quality = cq_level; - } - } - - // Extension to max or min Q if undershoot or overshoot is outside - // the permitted range. - if (frame_is_intra_only(cm) || boost_frame) { - const int layer_depth = gf_group->layer_depth[gf_group_index]; - active_best_quality -= - (cpi->twopass.extend_minq + cpi->twopass.extend_minq_fast); - active_worst_quality += (cpi->twopass.extend_maxq / 2); - - if (gf_group->rf_level[gf_group_index] == GF_ARF_LOW) { - assert(layer_depth > 1); - active_best_quality = - VPXMAX(active_best_quality, - cpi->twopass.last_qindex_of_arf_layer[layer_depth - 1]); - } - } else { - const int max_layer_depth = gf_group->max_layer_depth; - assert(max_layer_depth > 0); - - active_best_quality -= - (cpi->twopass.extend_minq + cpi->twopass.extend_minq_fast) / 2; - active_worst_quality += cpi->twopass.extend_maxq; - - // For normal frames do not allow an active minq lower than the q used for - // the last boosted frame. - active_best_quality = - VPXMAX(active_best_quality, - cpi->twopass.last_qindex_of_arf_layer[max_layer_depth - 1]); - } - -#if LIMIT_QRANGE_FOR_ALTREF_AND_KEY - vpx_clear_system_state(); - // Static forced key frames Q restrictions dealt with elsewhere. - if (!frame_is_intra_only(cm) || !rc->this_key_frame_forced || - cpi->twopass.last_kfgroup_zeromotion_pct < STATIC_MOTION_THRESH) { - int qdelta = vp9_frame_type_qdelta(cpi, gf_group->rf_level[gf_group_index], - active_worst_quality); - active_worst_quality = - VPXMAX(active_worst_quality + qdelta, active_best_quality); - } -#endif - - // Modify active_best_quality for downscaled normal frames. - if (rc->frame_size_selector != UNSCALED && !frame_is_kf_gf_arf(cpi)) { - int qdelta = vp9_compute_qdelta_by_rate( - rc, cm->frame_type, active_best_quality, 2.0, cm->bit_depth); - active_best_quality = - VPXMAX(active_best_quality + qdelta, rc->best_quality); - } - - active_best_quality = - clamp(active_best_quality, rc->best_quality, rc->worst_quality); - active_worst_quality = - clamp(active_worst_quality, active_best_quality, rc->worst_quality); - - if (frame_is_intra_only(cm) && rc->this_key_frame_forced) { - // If static since last kf use better of last boosted and last kf q. - if (cpi->twopass.last_kfgroup_zeromotion_pct >= STATIC_MOTION_THRESH) { - q = VPXMIN(rc->last_kf_qindex, rc->last_boosted_qindex); - } else { - q = rc->last_boosted_qindex; - } - } else if (frame_is_intra_only(cm) && !rc->this_key_frame_forced) { - q = active_best_quality; - } else { - q = vp9_rc_regulate_q(cpi, rc->this_frame_target, active_best_quality, - active_worst_quality); - if (q > active_worst_quality) { - // Special case when we are targeting the max allowed rate. - if (rc->this_frame_target >= rc->max_frame_bandwidth) - active_worst_quality = q; - else - q = active_worst_quality; - } - } - - *top_index = active_worst_quality; - *bottom_index = active_best_quality; - - assert(*top_index <= rc->worst_quality && *top_index >= rc->best_quality); - assert(*bottom_index <= rc->worst_quality && - *bottom_index >= rc->best_quality); - assert(q <= rc->worst_quality && q >= rc->best_quality); - return q; -} - -int vp9_rc_pick_q_and_bounds(const VP9_COMP *cpi, int *bottom_index, - int *top_index) { - int q; - const int gf_group_index = cpi->twopass.gf_group.index; - if (cpi->oxcf.pass == 0) { - if (cpi->oxcf.rc_mode == VPX_CBR) - q = rc_pick_q_and_bounds_one_pass_cbr(cpi, bottom_index, top_index); - else - q = rc_pick_q_and_bounds_one_pass_vbr(cpi, bottom_index, top_index); - } else { - q = vp9_rc_pick_q_and_bounds_two_pass(cpi, bottom_index, top_index, - gf_group_index); - } - if (cpi->sf.use_nonrd_pick_mode) { - if (cpi->sf.force_frame_boost == 1) q -= cpi->sf.max_delta_qindex; - - if (q < *bottom_index) - *bottom_index = q; - else if (q > *top_index) - *top_index = q; - } - return q; -} - -void vp9_configure_buffer_updates(VP9_COMP *cpi, int gf_group_index) { - VP9_COMMON *cm = &cpi->common; - TWO_PASS *const twopass = &cpi->twopass; - - cpi->rc.is_src_frame_alt_ref = 0; - cm->show_existing_frame = 0; - cpi->rc.show_arf_as_gld = 0; - switch (twopass->gf_group.update_type[gf_group_index]) { - case KF_UPDATE: - cpi->refresh_last_frame = 1; - cpi->refresh_golden_frame = 1; - cpi->refresh_alt_ref_frame = 1; - break; - case LF_UPDATE: - cpi->refresh_last_frame = 1; - cpi->refresh_golden_frame = 0; - cpi->refresh_alt_ref_frame = 0; - break; - case GF_UPDATE: - cpi->refresh_last_frame = 1; - cpi->refresh_golden_frame = 1; - cpi->refresh_alt_ref_frame = 0; - break; - case OVERLAY_UPDATE: - cpi->refresh_last_frame = 0; - cpi->refresh_golden_frame = 1; - cpi->refresh_alt_ref_frame = 0; - cpi->rc.is_src_frame_alt_ref = 1; - if (cpi->rc.preserve_arf_as_gld) { - cpi->rc.show_arf_as_gld = 1; - cpi->refresh_golden_frame = 0; - cm->show_existing_frame = 1; - cm->refresh_frame_context = 0; - } - break; - case MID_OVERLAY_UPDATE: - cpi->refresh_last_frame = 1; - cpi->refresh_golden_frame = 0; - cpi->refresh_alt_ref_frame = 0; - cpi->rc.is_src_frame_alt_ref = 1; - break; - case USE_BUF_FRAME: - cpi->refresh_last_frame = 0; - cpi->refresh_golden_frame = 0; - cpi->refresh_alt_ref_frame = 0; - cpi->rc.is_src_frame_alt_ref = 1; - cm->show_existing_frame = 1; - cm->refresh_frame_context = 0; - break; - default: - assert(twopass->gf_group.update_type[gf_group_index] == ARF_UPDATE); - cpi->refresh_last_frame = 0; - cpi->refresh_golden_frame = 0; - cpi->refresh_alt_ref_frame = 1; - break; - } -} - -void vp9_rc_compute_frame_size_bounds(const VP9_COMP *cpi, int frame_target, - int *frame_under_shoot_limit, - int *frame_over_shoot_limit) { - if (cpi->oxcf.rc_mode == VPX_Q) { - *frame_under_shoot_limit = 0; - *frame_over_shoot_limit = INT_MAX; - } else { - // For very small rate targets where the fractional adjustment - // may be tiny make sure there is at least a minimum range. - const int tol_low = - (int)(((int64_t)cpi->sf.recode_tolerance_low * frame_target) / 100); - const int tol_high = - (int)(((int64_t)cpi->sf.recode_tolerance_high * frame_target) / 100); - *frame_under_shoot_limit = VPXMAX(frame_target - tol_low - 100, 0); - *frame_over_shoot_limit = - VPXMIN(frame_target + tol_high + 100, cpi->rc.max_frame_bandwidth); - } -} - -void vp9_rc_set_frame_target(VP9_COMP *cpi, int target) { - const VP9_COMMON *const cm = &cpi->common; - RATE_CONTROL *const rc = &cpi->rc; - - rc->this_frame_target = target; - - // Modify frame size target when down-scaling. - if (cpi->oxcf.resize_mode == RESIZE_DYNAMIC && - rc->frame_size_selector != UNSCALED) { - rc->this_frame_target = (int)(rc->this_frame_target * - rate_thresh_mult[rc->frame_size_selector]); - } - -#if CONFIG_RATE_CTRL - if (cpi->oxcf.use_simple_encode_api) { - if (cpi->encode_command.use_external_target_frame_bits) { - rc->this_frame_target = cpi->encode_command.target_frame_bits; - } - } -#endif // CONFIG_RATE_CTRL - - // Target rate per SB64 (including partial SB64s. - const int64_t sb64_target_rate = - ((int64_t)rc->this_frame_target * 64 * 64) / (cm->width * cm->height); - rc->sb64_target_rate = (int)VPXMIN(sb64_target_rate, INT_MAX); -} - -static void update_alt_ref_frame_stats(VP9_COMP *cpi) { - // this frame refreshes means next frames don't unless specified by user - RATE_CONTROL *const rc = &cpi->rc; - rc->frames_since_golden = 0; - - // Mark the alt ref as done (setting to 0 means no further alt refs pending). - rc->source_alt_ref_pending = 0; - - // Set the alternate reference frame active flag - rc->source_alt_ref_active = 1; -} - -static void update_golden_frame_stats(VP9_COMP *cpi) { - RATE_CONTROL *const rc = &cpi->rc; - - // Update the Golden frame usage counts. - if (cpi->refresh_golden_frame) { - // this frame refreshes means next frames don't unless specified by user - rc->frames_since_golden = 0; - - // If we are not using alt ref in the up and coming group clear the arf - // active flag. In multi arf group case, if the index is not 0 then - // we are overlaying a mid group arf so should not reset the flag. - if (cpi->oxcf.pass == 2) { - if (!rc->source_alt_ref_pending && (cpi->twopass.gf_group.index == 0)) - rc->source_alt_ref_active = 0; - } else if (!rc->source_alt_ref_pending) { - rc->source_alt_ref_active = 0; - } - - // Decrement count down till next gf - if (rc->frames_till_gf_update_due > 0) rc->frames_till_gf_update_due--; - - } else if (!cpi->refresh_alt_ref_frame) { - // Decrement count down till next gf - if (rc->frames_till_gf_update_due > 0) rc->frames_till_gf_update_due--; - - rc->frames_since_golden++; - - if (rc->show_arf_as_gld) { - rc->frames_since_golden = 0; - // If we are not using alt ref in the up and coming group clear the arf - // active flag. In multi arf group case, if the index is not 0 then - // we are overlaying a mid group arf so should not reset the flag. - if (!rc->source_alt_ref_pending && (cpi->twopass.gf_group.index == 0)) - rc->source_alt_ref_active = 0; - } - } -} - -static void update_altref_usage(VP9_COMP *const cpi) { - VP9_COMMON *const cm = &cpi->common; - int sum_ref_frame_usage = 0; - int arf_frame_usage = 0; - int mi_row, mi_col; - if (cpi->rc.alt_ref_gf_group && !cpi->rc.is_src_frame_alt_ref && - !cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame) - for (mi_row = 0; mi_row < cm->mi_rows; mi_row += 8) { - for (mi_col = 0; mi_col < cm->mi_cols; mi_col += 8) { - int sboffset = ((cm->mi_cols + 7) >> 3) * (mi_row >> 3) + (mi_col >> 3); - sum_ref_frame_usage += cpi->count_arf_frame_usage[sboffset] + - cpi->count_lastgolden_frame_usage[sboffset]; - arf_frame_usage += cpi->count_arf_frame_usage[sboffset]; - } - } - if (sum_ref_frame_usage > 0) { - double altref_count = 100.0 * arf_frame_usage / sum_ref_frame_usage; - cpi->rc.perc_arf_usage = - 0.75 * cpi->rc.perc_arf_usage + 0.25 * altref_count; - } -} - -void vp9_compute_frame_low_motion(VP9_COMP *const cpi) { - VP9_COMMON *const cm = &cpi->common; - SVC *const svc = &cpi->svc; - int mi_row, mi_col; - MODE_INFO **mi = cm->mi_grid_visible; - RATE_CONTROL *const rc = &cpi->rc; - const int rows = cm->mi_rows, cols = cm->mi_cols; - int cnt_zeromv = 0; - for (mi_row = 0; mi_row < rows; mi_row++) { - for (mi_col = 0; mi_col < cols; mi_col++) { - if (mi[0]->ref_frame[0] == LAST_FRAME && - abs(mi[0]->mv[0].as_mv.row) < 16 && abs(mi[0]->mv[0].as_mv.col) < 16) - cnt_zeromv++; - mi++; - } - mi += 8; - } - cnt_zeromv = 100 * cnt_zeromv / (rows * cols); - rc->avg_frame_low_motion = (3 * rc->avg_frame_low_motion + cnt_zeromv) >> 2; - - // For SVC: set avg_frame_low_motion (only computed on top spatial layer) - // to all lower spatial layers. - if (cpi->use_svc && svc->spatial_layer_id == svc->number_spatial_layers - 1) { - int i; - for (i = 0; i < svc->number_spatial_layers - 1; ++i) { - const int layer = LAYER_IDS_TO_IDX(i, svc->temporal_layer_id, - svc->number_temporal_layers); - LAYER_CONTEXT *const lc = &svc->layer_context[layer]; - RATE_CONTROL *const lrc = &lc->rc; - lrc->avg_frame_low_motion = rc->avg_frame_low_motion; - } - } -} - -void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) { - const VP9_COMMON *const cm = &cpi->common; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - RATE_CONTROL *const rc = &cpi->rc; - SVC *const svc = &cpi->svc; - const int qindex = cm->base_qindex; - const GF_GROUP *gf_group = &cpi->twopass.gf_group; - const int gf_group_index = cpi->twopass.gf_group.index; - const int layer_depth = gf_group->layer_depth[gf_group_index]; - - // Update rate control heuristics - rc->projected_frame_size = (int)(bytes_used << 3); - - // Post encode loop adjustment of Q prediction. - vp9_rc_update_rate_correction_factors(cpi); - - // Keep a record of last Q and ambient average Q. - if (frame_is_intra_only(cm)) { - rc->last_q[KEY_FRAME] = qindex; - rc->avg_frame_qindex[KEY_FRAME] = - ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[KEY_FRAME] + qindex, 2); - if (cpi->use_svc) { - int i; - for (i = 0; i < svc->number_temporal_layers; ++i) { - const int layer = LAYER_IDS_TO_IDX(svc->spatial_layer_id, i, - svc->number_temporal_layers); - LAYER_CONTEXT *lc = &svc->layer_context[layer]; - RATE_CONTROL *lrc = &lc->rc; - lrc->last_q[KEY_FRAME] = rc->last_q[KEY_FRAME]; - lrc->avg_frame_qindex[KEY_FRAME] = rc->avg_frame_qindex[KEY_FRAME]; - } - } - } else { - if ((cpi->use_svc) || - (!rc->is_src_frame_alt_ref && - !(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame))) { - rc->last_q[INTER_FRAME] = qindex; - rc->avg_frame_qindex[INTER_FRAME] = - ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[INTER_FRAME] + qindex, 2); - rc->ni_frames++; - rc->tot_q += vp9_convert_qindex_to_q(qindex, cm->bit_depth); - rc->avg_q = rc->tot_q / rc->ni_frames; - // Calculate the average Q for normal inter frames (not key or GFU - // frames). - rc->ni_tot_qi += qindex; - rc->ni_av_qi = rc->ni_tot_qi / rc->ni_frames; - } - } - - if (cpi->use_svc) vp9_svc_adjust_avg_frame_qindex(cpi); - - // Keep record of last boosted (KF/KF/ARF) Q value. - // If the current frame is coded at a lower Q then we also update it. - // If all mbs in this group are skipped only update if the Q value is - // better than that already stored. - // This is used to help set quality in forced key frames to reduce popping - if ((qindex < rc->last_boosted_qindex) || (cm->frame_type == KEY_FRAME) || - (!rc->constrained_gf_group && - (cpi->refresh_alt_ref_frame || - (cpi->refresh_golden_frame && !rc->is_src_frame_alt_ref)))) { - rc->last_boosted_qindex = qindex; - } - - if ((qindex < cpi->twopass.last_qindex_of_arf_layer[layer_depth]) || - (cm->frame_type == KEY_FRAME) || - (!rc->constrained_gf_group && - (cpi->refresh_alt_ref_frame || - (cpi->refresh_golden_frame && !rc->is_src_frame_alt_ref)))) { - cpi->twopass.last_qindex_of_arf_layer[layer_depth] = qindex; - } - - if (frame_is_intra_only(cm)) rc->last_kf_qindex = qindex; - - update_buffer_level_postencode(cpi, rc->projected_frame_size); - - // Rolling monitors of whether we are over or underspending used to help - // regulate min and Max Q in two pass. - if (!frame_is_intra_only(cm)) { - rc->rolling_target_bits = (int)ROUND64_POWER_OF_TWO( - (int64_t)rc->rolling_target_bits * 3 + rc->this_frame_target, 2); - rc->rolling_actual_bits = (int)ROUND64_POWER_OF_TWO( - (int64_t)rc->rolling_actual_bits * 3 + rc->projected_frame_size, 2); - rc->long_rolling_target_bits = (int)ROUND64_POWER_OF_TWO( - (int64_t)rc->long_rolling_target_bits * 31 + rc->this_frame_target, 5); - rc->long_rolling_actual_bits = (int)ROUND64_POWER_OF_TWO( - (int64_t)rc->long_rolling_actual_bits * 31 + rc->projected_frame_size, - 5); - } - - // Actual bits spent - rc->total_actual_bits += rc->projected_frame_size; - rc->total_target_bits += cm->show_frame ? rc->avg_frame_bandwidth : 0; - - rc->total_target_vs_actual = rc->total_actual_bits - rc->total_target_bits; - - if (!cpi->use_svc) { - if (is_altref_enabled(cpi) && cpi->refresh_alt_ref_frame && - (!frame_is_intra_only(cm))) - // Update the alternate reference frame stats as appropriate. - update_alt_ref_frame_stats(cpi); - else - // Update the Golden frame stats as appropriate. - update_golden_frame_stats(cpi); - } - - // If second (long term) temporal reference is used for SVC, - // update the golden frame counter, only for base temporal layer. - if (cpi->use_svc && svc->use_gf_temporal_ref_current_layer && - svc->temporal_layer_id == 0) { - int i = 0; - if (cpi->refresh_golden_frame) - rc->frames_since_golden = 0; - else - rc->frames_since_golden++; - // Decrement count down till next gf - if (rc->frames_till_gf_update_due > 0) rc->frames_till_gf_update_due--; - // Update the frames_since_golden for all upper temporal layers. - for (i = 1; i < svc->number_temporal_layers; ++i) { - const int layer = LAYER_IDS_TO_IDX(svc->spatial_layer_id, i, - svc->number_temporal_layers); - LAYER_CONTEXT *const lc = &svc->layer_context[layer]; - RATE_CONTROL *const lrc = &lc->rc; - lrc->frames_since_golden = rc->frames_since_golden; - } - } - - if (frame_is_intra_only(cm)) rc->frames_since_key = 0; - if (cm->show_frame) { - rc->frames_since_key++; - rc->frames_to_key--; - } - - // Trigger the resizing of the next frame if it is scaled. - if (oxcf->pass != 0) { - cpi->resize_pending = - rc->next_frame_size_selector != rc->frame_size_selector; - rc->frame_size_selector = rc->next_frame_size_selector; - } - - if (oxcf->pass == 0) { - if (!frame_is_intra_only(cm)) - if (cpi->sf.use_altref_onepass) update_altref_usage(cpi); - cpi->rc.last_frame_is_src_altref = cpi->rc.is_src_frame_alt_ref; - } - - if (!frame_is_intra_only(cm)) rc->reset_high_source_sad = 0; - - rc->last_avg_frame_bandwidth = rc->avg_frame_bandwidth; - if (cpi->use_svc && svc->spatial_layer_id < svc->number_spatial_layers - 1) - svc->lower_layer_qindex = cm->base_qindex; - cpi->deadline_mode_previous_frame = cpi->oxcf.mode; -} - -void vp9_rc_postencode_update_drop_frame(VP9_COMP *cpi) { - cpi->common.current_video_frame++; - cpi->rc.frames_since_key++; - cpi->rc.frames_to_key--; - cpi->rc.rc_2_frame = 0; - cpi->rc.rc_1_frame = 0; - cpi->rc.last_avg_frame_bandwidth = cpi->rc.avg_frame_bandwidth; - cpi->rc.last_q[INTER_FRAME] = cpi->common.base_qindex; - // For SVC on dropped frame when framedrop_mode != LAYER_DROP: - // in this mode the whole superframe may be dropped if only a single layer - // has buffer underflow (below threshold). Since this can then lead to - // increasing buffer levels/overflow for certain layers even though whole - // superframe is dropped, we cap buffer level if its already stable. - if (cpi->use_svc && cpi->svc.framedrop_mode != LAYER_DROP && - cpi->rc.buffer_level > cpi->rc.optimal_buffer_level) { - cpi->rc.buffer_level = cpi->rc.optimal_buffer_level; - cpi->rc.bits_off_target = cpi->rc.optimal_buffer_level; - } - cpi->deadline_mode_previous_frame = cpi->oxcf.mode; -} - -int vp9_calc_pframe_target_size_one_pass_vbr(const VP9_COMP *cpi) { - const RATE_CONTROL *const rc = &cpi->rc; - const int af_ratio = rc->af_ratio_onepass_vbr; - int64_t target = - (!rc->is_src_frame_alt_ref && - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) - ? ((int64_t)rc->avg_frame_bandwidth * rc->baseline_gf_interval * - af_ratio) / - (rc->baseline_gf_interval + af_ratio - 1) - : ((int64_t)rc->avg_frame_bandwidth * rc->baseline_gf_interval) / - (rc->baseline_gf_interval + af_ratio - 1); - // For SVC: refresh flags are used to define the pattern, so we can't - // use that for boosting the target size here. - // TODO(marpan): Consider adding internal boost on TL0 for VBR-SVC. - // For now just use the CBR logic for setting target size. - if (cpi->use_svc) target = vp9_calc_pframe_target_size_one_pass_cbr(cpi); - if (target > INT_MAX) target = INT_MAX; - return vp9_rc_clamp_pframe_target_size(cpi, (int)target); -} - -int vp9_calc_iframe_target_size_one_pass_vbr(const VP9_COMP *cpi) { - static const int kf_ratio = 25; - const RATE_CONTROL *rc = &cpi->rc; - int target = rc->avg_frame_bandwidth; - if (target > INT_MAX / kf_ratio) - target = INT_MAX; - else - target = rc->avg_frame_bandwidth * kf_ratio; - return vp9_rc_clamp_iframe_target_size(cpi, target); -} - -static void adjust_gfint_frame_constraint(VP9_COMP *cpi, int frame_constraint) { - RATE_CONTROL *const rc = &cpi->rc; - rc->constrained_gf_group = 0; - // Reset gf interval to make more equal spacing for frame_constraint. - if ((frame_constraint <= 7 * rc->baseline_gf_interval >> 2) && - (frame_constraint > rc->baseline_gf_interval)) { - rc->baseline_gf_interval = frame_constraint >> 1; - if (rc->baseline_gf_interval < 5) - rc->baseline_gf_interval = frame_constraint; - rc->constrained_gf_group = 1; - } else { - // Reset to keep gf_interval <= frame_constraint. - if (rc->baseline_gf_interval > frame_constraint) { - rc->baseline_gf_interval = frame_constraint; - rc->constrained_gf_group = 1; - } - } -} - -void vp9_set_gf_update_one_pass_vbr(VP9_COMP *const cpi) { - RATE_CONTROL *const rc = &cpi->rc; - VP9_COMMON *const cm = &cpi->common; - if (rc->frames_till_gf_update_due == 0) { - double rate_err = 1.0; - rc->gfu_boost = DEFAULT_GF_BOOST; - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cpi->oxcf.pass == 0) { - vp9_cyclic_refresh_set_golden_update(cpi); - } else { - rc->baseline_gf_interval = VPXMIN( - 20, VPXMAX(10, (rc->min_gf_interval + rc->max_gf_interval) / 2)); - } - rc->af_ratio_onepass_vbr = 10; - if (rc->rolling_target_bits > 0) - rate_err = - (double)rc->rolling_actual_bits / (double)rc->rolling_target_bits; - if (cm->current_video_frame > 30) { - if (rc->avg_frame_qindex[INTER_FRAME] > (7 * rc->worst_quality) >> 3 && - rate_err > 3.5) { - rc->baseline_gf_interval = - VPXMIN(15, (3 * rc->baseline_gf_interval) >> 1); - } else if (rc->avg_frame_low_motion > 0 && - rc->avg_frame_low_motion < 20) { - // Decrease gf interval for high motion case. - rc->baseline_gf_interval = VPXMAX(6, rc->baseline_gf_interval >> 1); - } - // Adjust boost and af_ratio based on avg_frame_low_motion, which - // varies between 0 and 100 (stationary, 100% zero/small motion). - if (rc->avg_frame_low_motion > 0) - rc->gfu_boost = - VPXMAX(500, DEFAULT_GF_BOOST * (rc->avg_frame_low_motion << 1) / - (rc->avg_frame_low_motion + 100)); - else if (rc->avg_frame_low_motion == 0 && rate_err > 1.0) - rc->gfu_boost = DEFAULT_GF_BOOST >> 1; - rc->af_ratio_onepass_vbr = VPXMIN(15, VPXMAX(5, 3 * rc->gfu_boost / 400)); - } - if (rc->constrain_gf_key_freq_onepass_vbr) - adjust_gfint_frame_constraint(cpi, rc->frames_to_key); - rc->frames_till_gf_update_due = rc->baseline_gf_interval; - cpi->refresh_golden_frame = 1; - rc->source_alt_ref_pending = 0; - rc->alt_ref_gf_group = 0; - if (cpi->sf.use_altref_onepass && cpi->oxcf.enable_auto_arf) { - rc->source_alt_ref_pending = 1; - rc->alt_ref_gf_group = 1; - } - } -} - -void vp9_rc_get_one_pass_vbr_params(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - RATE_CONTROL *const rc = &cpi->rc; - int target; - if (!cpi->refresh_alt_ref_frame && - (cm->current_video_frame == 0 || (cpi->frame_flags & FRAMEFLAGS_KEY) || - rc->frames_to_key == 0 || - (cpi->oxcf.mode != cpi->deadline_mode_previous_frame))) { - cm->frame_type = KEY_FRAME; - rc->this_key_frame_forced = - cm->current_video_frame != 0 && rc->frames_to_key == 0; - rc->frames_to_key = cpi->oxcf.key_freq; - rc->kf_boost = DEFAULT_KF_BOOST; - rc->source_alt_ref_active = 0; - } else { - cm->frame_type = INTER_FRAME; - } - vp9_set_gf_update_one_pass_vbr(cpi); - if (cm->frame_type == KEY_FRAME) - target = vp9_calc_iframe_target_size_one_pass_vbr(cpi); - else - target = vp9_calc_pframe_target_size_one_pass_vbr(cpi); - vp9_rc_set_frame_target(cpi, target); - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cpi->oxcf.pass == 0) - vp9_cyclic_refresh_update_parameters(cpi); -} - -int vp9_calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { - const VP9EncoderConfig *oxcf = &cpi->oxcf; - const RATE_CONTROL *rc = &cpi->rc; - const SVC *const svc = &cpi->svc; - const int64_t diff = rc->optimal_buffer_level - rc->buffer_level; - const int64_t one_pct_bits = 1 + rc->optimal_buffer_level / 100; - int min_frame_target = - VPXMAX(rc->avg_frame_bandwidth >> 4, FRAME_OVERHEAD_BITS); - int target; - - if (oxcf->gf_cbr_boost_pct) { - const int af_ratio_pct = oxcf->gf_cbr_boost_pct + 100; - target = cpi->refresh_golden_frame - ? (rc->avg_frame_bandwidth * rc->baseline_gf_interval * - af_ratio_pct) / - (rc->baseline_gf_interval * 100 + af_ratio_pct - 100) - : (rc->avg_frame_bandwidth * rc->baseline_gf_interval * 100) / - (rc->baseline_gf_interval * 100 + af_ratio_pct - 100); - } else { - target = rc->avg_frame_bandwidth; - } - if (is_one_pass_svc(cpi)) { - // Note that for layers, avg_frame_bandwidth is the cumulative - // per-frame-bandwidth. For the target size of this frame, use the - // layer average frame size (i.e., non-cumulative per-frame-bw). - int layer = LAYER_IDS_TO_IDX(svc->spatial_layer_id, svc->temporal_layer_id, - svc->number_temporal_layers); - const LAYER_CONTEXT *lc = &svc->layer_context[layer]; - target = lc->avg_frame_size; - min_frame_target = VPXMAX(lc->avg_frame_size >> 4, FRAME_OVERHEAD_BITS); - } - if (diff > 0) { - // Lower the target bandwidth for this frame. - const int pct_low = (int)VPXMIN(diff / one_pct_bits, oxcf->under_shoot_pct); - target -= (int)(((int64_t)target * pct_low) / 200); - } else if (diff < 0) { - // Increase the target bandwidth for this frame. - const int pct_high = - (int)VPXMIN(-diff / one_pct_bits, oxcf->over_shoot_pct); - target += (int)(((int64_t)target * pct_high) / 200); - } - if (oxcf->rc_max_inter_bitrate_pct) { - const int max_rate = - rc->avg_frame_bandwidth * oxcf->rc_max_inter_bitrate_pct / 100; - target = VPXMIN(target, max_rate); - } - return VPXMAX(min_frame_target, target); -} - -int vp9_calc_iframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { - const RATE_CONTROL *rc = &cpi->rc; - const VP9EncoderConfig *oxcf = &cpi->oxcf; - const SVC *const svc = &cpi->svc; - int64_t target; - if (cpi->common.current_video_frame == 0) { - target = rc->starting_buffer_level / 2; - } else { - int kf_boost = 32; - double framerate = cpi->framerate; - if (svc->number_temporal_layers > 1 && oxcf->rc_mode == VPX_CBR) { - // Use the layer framerate for temporal layers CBR mode. - const int layer = - LAYER_IDS_TO_IDX(svc->spatial_layer_id, svc->temporal_layer_id, - svc->number_temporal_layers); - const LAYER_CONTEXT *lc = &svc->layer_context[layer]; - framerate = lc->framerate; - } - kf_boost = VPXMAX(kf_boost, (int)round(2 * framerate - 16)); - if (rc->frames_since_key < framerate / 2) { - kf_boost = (int)round(kf_boost * rc->frames_since_key / (framerate / 2)); - } - - target = ((int64_t)(16 + kf_boost) * rc->avg_frame_bandwidth) >> 4; - } - target = VPXMIN(INT_MAX, target); - return vp9_rc_clamp_iframe_target_size(cpi, (int)target); -} - -static void set_intra_only_frame(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - SVC *const svc = &cpi->svc; - // Don't allow intra_only frame for bypass/flexible SVC mode, or if number - // of spatial layers is 1 or if number of spatial or temporal layers > 3. - // Also if intra-only is inserted on very first frame, don't allow if - // if number of temporal layers > 1. This is because on intra-only frame - // only 3 reference buffers can be updated, but for temporal layers > 1 - // we generally need to use buffer slots 4 and 5. - if ((cm->current_video_frame == 0 && svc->number_temporal_layers > 1) || - svc->number_spatial_layers > 3 || svc->number_temporal_layers > 3 || - svc->number_spatial_layers == 1) - return; - cm->show_frame = 0; - cm->intra_only = 1; - cm->frame_type = INTER_FRAME; - cpi->ext_refresh_frame_flags_pending = 1; - cpi->ext_refresh_last_frame = 1; - cpi->ext_refresh_golden_frame = 1; - cpi->ext_refresh_alt_ref_frame = 1; - if (cm->current_video_frame == 0) { - cpi->lst_fb_idx = 0; - cpi->gld_fb_idx = 1; - cpi->alt_fb_idx = 2; - } else { - int i; - int count = 0; - cpi->lst_fb_idx = -1; - cpi->gld_fb_idx = -1; - cpi->alt_fb_idx = -1; - svc->update_buffer_slot[0] = 0; - // For intra-only frame we need to refresh all slots that were - // being used for the base layer (fb_idx_base[i] == 1). - // Start with assigning last first, then golden and then alt. - for (i = 0; i < REF_FRAMES; ++i) { - if (svc->fb_idx_base[i] == 1) { - svc->update_buffer_slot[0] |= 1 << i; - count++; - } - if (count == 1 && cpi->lst_fb_idx == -1) cpi->lst_fb_idx = i; - if (count == 2 && cpi->gld_fb_idx == -1) cpi->gld_fb_idx = i; - if (count == 3 && cpi->alt_fb_idx == -1) cpi->alt_fb_idx = i; - } - // If golden or alt is not being used for base layer, then set them - // to the lst_fb_idx. - if (cpi->gld_fb_idx == -1) cpi->gld_fb_idx = cpi->lst_fb_idx; - if (cpi->alt_fb_idx == -1) cpi->alt_fb_idx = cpi->lst_fb_idx; - if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) { - cpi->ext_refresh_last_frame = 0; - cpi->ext_refresh_golden_frame = 0; - cpi->ext_refresh_alt_ref_frame = 0; - cpi->ref_frame_flags = 0; - } - } -} - -void vp9_rc_get_svc_params(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - RATE_CONTROL *const rc = &cpi->rc; - SVC *const svc = &cpi->svc; - int target = rc->avg_frame_bandwidth; - int layer = LAYER_IDS_TO_IDX(svc->spatial_layer_id, svc->temporal_layer_id, - svc->number_temporal_layers); - if (svc->first_spatial_layer_to_encode) - svc->layer_context[svc->temporal_layer_id].is_key_frame = 0; - // Periodic key frames is based on the super-frame counter - // (svc.current_superframe), also only base spatial layer is key frame. - // Key frame is set for any of the following: very first frame, frame flags - // indicates key, superframe counter hits key frequency,(non-intra) sync - // flag is set for spatial layer 0, or deadline mode changes. - if ((cm->current_video_frame == 0 && !svc->previous_frame_is_intra_only) || - (cpi->frame_flags & FRAMEFLAGS_KEY) || - (cpi->oxcf.auto_key && - (svc->current_superframe % cpi->oxcf.key_freq == 0) && - !svc->previous_frame_is_intra_only && svc->spatial_layer_id == 0) || - (svc->spatial_layer_sync[0] == 1 && svc->spatial_layer_id == 0) || - (cpi->oxcf.mode != cpi->deadline_mode_previous_frame)) { - cm->frame_type = KEY_FRAME; - rc->source_alt_ref_active = 0; - if (is_one_pass_svc(cpi)) { - if (cm->current_video_frame > 0) vp9_svc_reset_temporal_layers(cpi, 1); - layer = LAYER_IDS_TO_IDX(svc->spatial_layer_id, svc->temporal_layer_id, - svc->number_temporal_layers); - svc->layer_context[layer].is_key_frame = 1; - cpi->ref_frame_flags &= (~VP9_LAST_FLAG & ~VP9_GOLD_FLAG & ~VP9_ALT_FLAG); - // Assumption here is that LAST_FRAME is being updated for a keyframe. - // Thus no change in update flags. - if (cpi->oxcf.rc_mode == VPX_CBR) - target = vp9_calc_iframe_target_size_one_pass_cbr(cpi); - else - target = vp9_calc_iframe_target_size_one_pass_vbr(cpi); - } - } else { - cm->frame_type = INTER_FRAME; - if (is_one_pass_svc(cpi)) { - LAYER_CONTEXT *lc = &svc->layer_context[layer]; - // Add condition current_video_frame > 0 for the case where first frame - // is intra only followed by overlay/copy frame. In this case we don't - // want to reset is_key_frame to 0 on overlay/copy frame. - lc->is_key_frame = - (svc->spatial_layer_id == 0 && cm->current_video_frame > 0) - ? 0 - : svc->layer_context[svc->temporal_layer_id].is_key_frame; - if (cpi->oxcf.rc_mode == VPX_CBR) { - target = vp9_calc_pframe_target_size_one_pass_cbr(cpi); - } else { - double rate_err = 0.0; - rc->fac_active_worst_inter = 140; - rc->fac_active_worst_gf = 100; - if (rc->rolling_target_bits > 0) { - rate_err = - (double)rc->rolling_actual_bits / (double)rc->rolling_target_bits; - if (rate_err < 1.0) - rc->fac_active_worst_inter = 120; - else if (rate_err > 2.0) - // Increase active_worst faster if rate fluctuation is high. - rc->fac_active_worst_inter = 160; - } - target = vp9_calc_pframe_target_size_one_pass_vbr(cpi); - } - } - } - - if (svc->simulcast_mode) { - if (svc->spatial_layer_id > 0 && - svc->layer_context[layer].is_key_frame == 1) { - cm->frame_type = KEY_FRAME; - cpi->ref_frame_flags &= (~VP9_LAST_FLAG & ~VP9_GOLD_FLAG & ~VP9_ALT_FLAG); - if (cpi->oxcf.rc_mode == VPX_CBR) - target = vp9_calc_iframe_target_size_one_pass_cbr(cpi); - else - target = vp9_calc_iframe_target_size_one_pass_vbr(cpi); - } - // Set the buffer idx and refresh flags for key frames in simulcast mode. - // Note the buffer slot for long-term reference is set below (line 2255), - // and alt_ref is used for that on key frame. So use last and golden for - // the other two normal slots. - if (cm->frame_type == KEY_FRAME) { - if (svc->number_spatial_layers == 2) { - if (svc->spatial_layer_id == 0) { - cpi->lst_fb_idx = 0; - cpi->gld_fb_idx = 2; - cpi->alt_fb_idx = 6; - } else if (svc->spatial_layer_id == 1) { - cpi->lst_fb_idx = 1; - cpi->gld_fb_idx = 3; - cpi->alt_fb_idx = 6; - } - } else if (svc->number_spatial_layers == 3) { - if (svc->spatial_layer_id == 0) { - cpi->lst_fb_idx = 0; - cpi->gld_fb_idx = 3; - cpi->alt_fb_idx = 6; - } else if (svc->spatial_layer_id == 1) { - cpi->lst_fb_idx = 1; - cpi->gld_fb_idx = 4; - cpi->alt_fb_idx = 6; - } else if (svc->spatial_layer_id == 2) { - cpi->lst_fb_idx = 2; - cpi->gld_fb_idx = 5; - cpi->alt_fb_idx = 7; - } - } - cpi->ext_refresh_last_frame = 1; - cpi->ext_refresh_golden_frame = 1; - cpi->ext_refresh_alt_ref_frame = 1; - } - } - - // Check if superframe contains a sync layer request. - vp9_svc_check_spatial_layer_sync(cpi); - - // If long term termporal feature is enabled, set the period of the update. - // The update/refresh of this reference frame is always on base temporal - // layer frame. - if (svc->use_gf_temporal_ref_current_layer) { - // Only use gf long-term prediction on non-key superframes. - if (!svc->layer_context[svc->temporal_layer_id].is_key_frame) { - // Use golden for this reference, which will be used for prediction. - int index = svc->spatial_layer_id; - if (svc->number_spatial_layers == 3) index = svc->spatial_layer_id - 1; - assert(index >= 0); - cpi->gld_fb_idx = svc->buffer_gf_temporal_ref[index].idx; - // Enable prediction off LAST (last reference) and golden (which will - // generally be further behind/long-term reference). - cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; - } - // Check for update/refresh of reference: only refresh on base temporal - // layer. - if (svc->temporal_layer_id == 0) { - if (svc->layer_context[svc->temporal_layer_id].is_key_frame) { - // On key frame we update the buffer index used for long term reference. - // Use the alt_ref since it is not used or updated on key frames. - int index = svc->spatial_layer_id; - if (svc->number_spatial_layers == 3) index = svc->spatial_layer_id - 1; - assert(index >= 0); - cpi->alt_fb_idx = svc->buffer_gf_temporal_ref[index].idx; - cpi->ext_refresh_alt_ref_frame = 1; - } else if (rc->frames_till_gf_update_due == 0) { - // Set perdiod of next update. Make it a multiple of 10, as the cyclic - // refresh is typically ~10%, and we'd like the update to happen after - // a few cylces of the refresh (so it better quality frame). Note the - // cyclic refresh for SVC only operates on base temporal layer frames. - // Choose 20 as perdiod for now (2 cycles). - rc->baseline_gf_interval = 20; - rc->frames_till_gf_update_due = rc->baseline_gf_interval; - cpi->ext_refresh_golden_frame = 1; - rc->gfu_boost = DEFAULT_GF_BOOST; - } - } - } else if (!svc->use_gf_temporal_ref) { - rc->frames_till_gf_update_due = INT_MAX; - rc->baseline_gf_interval = INT_MAX; - } - if (svc->set_intra_only_frame) { - set_intra_only_frame(cpi); - if (cpi->oxcf.rc_mode == VPX_CBR) - target = vp9_calc_iframe_target_size_one_pass_cbr(cpi); - else - target = vp9_calc_iframe_target_size_one_pass_vbr(cpi); - } - // Overlay frame predicts from LAST (intra-only) - if (svc->previous_frame_is_intra_only) cpi->ref_frame_flags |= VP9_LAST_FLAG; - - // Any update/change of global cyclic refresh parameters (amount/delta-qp) - // should be done here, before the frame qp is selected. - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) - vp9_cyclic_refresh_update_parameters(cpi); - - vp9_rc_set_frame_target(cpi, target); - if (cm->show_frame) vp9_update_buffer_level_svc_preencode(cpi); - - if (cpi->oxcf.resize_mode == RESIZE_DYNAMIC && svc->single_layer_svc == 1 && - svc->spatial_layer_id == svc->first_spatial_layer_to_encode && - svc->temporal_layer_id == 0) { - LAYER_CONTEXT *lc = NULL; - cpi->resize_pending = vp9_resize_one_pass_cbr(cpi); - if (cpi->resize_pending) { - int tl, width, height; - // Apply the same scale to all temporal layers. - for (tl = 0; tl < svc->number_temporal_layers; tl++) { - lc = &svc->layer_context[svc->spatial_layer_id * - svc->number_temporal_layers + - tl]; - lc->scaling_factor_num_resize = - cpi->resize_scale_num * lc->scaling_factor_num; - lc->scaling_factor_den_resize = - cpi->resize_scale_den * lc->scaling_factor_den; - // Reset rate control for all temporal layers. - lc->rc.buffer_level = lc->rc.optimal_buffer_level; - lc->rc.bits_off_target = lc->rc.optimal_buffer_level; - lc->rc.rate_correction_factors[INTER_FRAME] = - rc->rate_correction_factors[INTER_FRAME]; - } - // Set the size for this current temporal layer. - lc = &svc->layer_context[svc->spatial_layer_id * - svc->number_temporal_layers + - svc->temporal_layer_id]; - get_layer_resolution(cpi->oxcf.width, cpi->oxcf.height, - lc->scaling_factor_num_resize, - lc->scaling_factor_den_resize, &width, &height); - vp9_set_size_literal(cpi, width, height); - svc->resize_set = 1; - } - } else { - cpi->resize_pending = 0; - svc->resize_set = 0; - } -} - -void vp9_rc_get_one_pass_cbr_params(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - RATE_CONTROL *const rc = &cpi->rc; - int target; - if ((cm->current_video_frame == 0) || (cpi->frame_flags & FRAMEFLAGS_KEY) || - (cpi->oxcf.auto_key && rc->frames_to_key == 0) || - (cpi->oxcf.mode != cpi->deadline_mode_previous_frame)) { - cm->frame_type = KEY_FRAME; - rc->frames_to_key = cpi->oxcf.key_freq; - rc->kf_boost = DEFAULT_KF_BOOST; - rc->source_alt_ref_active = 0; - } else { - cm->frame_type = INTER_FRAME; - } - if (rc->frames_till_gf_update_due == 0) { - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) - vp9_cyclic_refresh_set_golden_update(cpi); - else - rc->baseline_gf_interval = - (rc->min_gf_interval + rc->max_gf_interval) / 2; - rc->frames_till_gf_update_due = rc->baseline_gf_interval; - // NOTE: frames_till_gf_update_due must be <= frames_to_key. - if (rc->frames_till_gf_update_due > rc->frames_to_key) - rc->frames_till_gf_update_due = rc->frames_to_key; - cpi->refresh_golden_frame = 1; - rc->gfu_boost = DEFAULT_GF_BOOST; - } - - // Any update/change of global cyclic refresh parameters (amount/delta-qp) - // should be done here, before the frame qp is selected. - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) - vp9_cyclic_refresh_update_parameters(cpi); - - if (frame_is_intra_only(cm)) - target = vp9_calc_iframe_target_size_one_pass_cbr(cpi); - else - target = vp9_calc_pframe_target_size_one_pass_cbr(cpi); - - vp9_rc_set_frame_target(cpi, target); - - if (cm->show_frame) vp9_update_buffer_level_preencode(cpi); - - if (cpi->oxcf.resize_mode == RESIZE_DYNAMIC) - cpi->resize_pending = vp9_resize_one_pass_cbr(cpi); - else - cpi->resize_pending = 0; -} - -int vp9_compute_qdelta(const RATE_CONTROL *rc, double qstart, double qtarget, - vpx_bit_depth_t bit_depth) { - int start_index = rc->worst_quality; - int target_index = rc->worst_quality; - int i; - - // Convert the average q value to an index. - for (i = rc->best_quality; i < rc->worst_quality; ++i) { - start_index = i; - if (vp9_convert_qindex_to_q(i, bit_depth) >= qstart) break; - } - - // Convert the q target to an index - for (i = rc->best_quality; i < rc->worst_quality; ++i) { - target_index = i; - if (vp9_convert_qindex_to_q(i, bit_depth) >= qtarget) break; - } - - return target_index - start_index; -} - -int vp9_compute_qdelta_by_rate(const RATE_CONTROL *rc, FRAME_TYPE frame_type, - int qindex, double rate_target_ratio, - vpx_bit_depth_t bit_depth) { - int target_index = rc->worst_quality; - int i; - - // Look up the current projected bits per block for the base index - const int base_bits_per_mb = - vp9_rc_bits_per_mb(frame_type, qindex, 1.0, bit_depth); - - // Find the target bits per mb based on the base value and given ratio. - const int target_bits_per_mb = (int)(rate_target_ratio * base_bits_per_mb); - - // Convert the q target to an index - for (i = rc->best_quality; i < rc->worst_quality; ++i) { - if (vp9_rc_bits_per_mb(frame_type, i, 1.0, bit_depth) <= - target_bits_per_mb) { - target_index = i; - break; - } - } - return target_index - qindex; -} - -void vp9_rc_set_gf_interval_range(const VP9_COMP *const cpi, - RATE_CONTROL *const rc) { - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - - // Special case code for 1 pass fixed Q mode tests - if ((oxcf->pass == 0) && (oxcf->rc_mode == VPX_Q)) { - rc->max_gf_interval = FIXED_GF_INTERVAL; - rc->min_gf_interval = FIXED_GF_INTERVAL; - rc->static_scene_max_gf_interval = FIXED_GF_INTERVAL; - } else { - double framerate = cpi->framerate; - // Set Maximum gf/arf interval - rc->max_gf_interval = oxcf->max_gf_interval; - rc->min_gf_interval = oxcf->min_gf_interval; -#if CONFIG_RATE_CTRL - if (oxcf->use_simple_encode_api) { - // In this experiment, we avoid framerate being changed dynamically during - // encoding. - framerate = oxcf->init_framerate; - } -#endif // CONFIG_RATE_CTRL - if (rc->min_gf_interval == 0) { - rc->min_gf_interval = vp9_rc_get_default_min_gf_interval( - oxcf->width, oxcf->height, framerate); - } - if (rc->max_gf_interval == 0) { - rc->max_gf_interval = - vp9_rc_get_default_max_gf_interval(framerate, rc->min_gf_interval); - } - - // Extended max interval for genuinely static scenes like slide shows. - rc->static_scene_max_gf_interval = MAX_STATIC_GF_GROUP_LENGTH; - - if (rc->max_gf_interval > rc->static_scene_max_gf_interval) - rc->max_gf_interval = rc->static_scene_max_gf_interval; - - // Clamp min to max - rc->min_gf_interval = VPXMIN(rc->min_gf_interval, rc->max_gf_interval); - - if (oxcf->target_level == LEVEL_AUTO) { - const uint32_t pic_size = cpi->common.width * cpi->common.height; - const uint32_t pic_breadth = - VPXMAX(cpi->common.width, cpi->common.height); - int i; - for (i = 0; i < VP9_LEVELS; ++i) { - if (vp9_level_defs[i].max_luma_picture_size >= pic_size && - vp9_level_defs[i].max_luma_picture_breadth >= pic_breadth) { - if (rc->min_gf_interval <= - (int)vp9_level_defs[i].min_altref_distance) { - rc->min_gf_interval = (int)vp9_level_defs[i].min_altref_distance; - rc->max_gf_interval = - VPXMAX(rc->max_gf_interval, rc->min_gf_interval); - } - break; - } - } - } - } -} - -void vp9_rc_update_framerate(VP9_COMP *cpi) { - const VP9_COMMON *const cm = &cpi->common; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - RATE_CONTROL *const rc = &cpi->rc; - - rc->avg_frame_bandwidth = saturate_cast_double_to_int( - round(oxcf->target_bandwidth / cpi->framerate)); - - int64_t vbr_min_bits = - (int64_t)rc->avg_frame_bandwidth * oxcf->two_pass_vbrmin_section / 100; - vbr_min_bits = VPXMIN(vbr_min_bits, INT_MAX); - - rc->min_frame_bandwidth = VPXMAX((int)vbr_min_bits, FRAME_OVERHEAD_BITS); - - // A maximum bitrate for a frame is defined. - // However this limit is extended if a very high rate is given on the command - // line or the rate can not be achieved because of a user specified max q - // (e.g. when the user specifies lossless encode). - // - // If a level is specified that requires a lower maximum rate then the level - // value take precedence. - int64_t vbr_max_bits = - (int64_t)rc->avg_frame_bandwidth * oxcf->two_pass_vbrmax_section / 100; - vbr_max_bits = VPXMIN(vbr_max_bits, INT_MAX); - - rc->max_frame_bandwidth = - VPXMAX(VPXMAX((cm->MBs * MAX_MB_RATE), MAXRATE_1080P), (int)vbr_max_bits); - - vp9_rc_set_gf_interval_range(cpi, rc); -} - -#define VBR_PCT_ADJUSTMENT_LIMIT 50 -// For VBR...adjustment to the frame target based on error from previous frames -static void vbr_rate_correction(VP9_COMP *cpi, int *this_frame_target) { - RATE_CONTROL *const rc = &cpi->rc; - int64_t vbr_bits_off_target = rc->vbr_bits_off_target; - int64_t frame_target = *this_frame_target; - int frame_window = (int)VPXMIN( - 16, cpi->twopass.total_stats.count - cpi->common.current_video_frame); - - // Calcluate the adjustment to rate for this frame. - if (frame_window > 0) { - int64_t max_delta = (vbr_bits_off_target > 0) - ? (vbr_bits_off_target / frame_window) - : (-vbr_bits_off_target / frame_window); - - max_delta = - VPXMIN(max_delta, ((frame_target * VBR_PCT_ADJUSTMENT_LIMIT) / 100)); - - // vbr_bits_off_target > 0 means we have extra bits to spend - if (vbr_bits_off_target > 0) { - frame_target += VPXMIN(vbr_bits_off_target, max_delta); - } else { - frame_target -= VPXMIN(-vbr_bits_off_target, max_delta); - } - } - - // Fast redistribution of bits arising from massive local undershoot. - // Don't do it for kf,arf,gf or overlay frames. - if (!frame_is_kf_gf_arf(cpi) && !rc->is_src_frame_alt_ref && - rc->vbr_bits_off_target_fast) { - int64_t one_frame_bits = VPXMAX(rc->avg_frame_bandwidth, frame_target); - int64_t fast_extra_bits = - VPXMIN(rc->vbr_bits_off_target_fast, one_frame_bits); - fast_extra_bits = - VPXMIN(fast_extra_bits, - VPXMAX(one_frame_bits / 8, rc->vbr_bits_off_target_fast / 8)); - frame_target += fast_extra_bits; - rc->vbr_bits_off_target_fast -= fast_extra_bits; - } - - // Clamp the target for the frame to the maximum allowed for one frame. - *this_frame_target = (int)VPXMIN(frame_target, INT_MAX); -} - -void vp9_set_target_rate(VP9_COMP *cpi) { - RATE_CONTROL *const rc = &cpi->rc; - int target_rate = rc->base_frame_target; - - if (cpi->common.frame_type == KEY_FRAME) - target_rate = vp9_rc_clamp_iframe_target_size(cpi, target_rate); - else - target_rate = vp9_rc_clamp_pframe_target_size(cpi, target_rate); - - if (!cpi->oxcf.vbr_corpus_complexity) { - // Correction to rate target based on prior over or under shoot. - if (cpi->oxcf.rc_mode == VPX_VBR || cpi->oxcf.rc_mode == VPX_CQ) - vbr_rate_correction(cpi, &target_rate); - } - vp9_rc_set_frame_target(cpi, target_rate); -} - -// Check if we should resize, based on average QP from past x frames. -// Only allow for resize at most one scale down for now, scaling factor is 2. -int vp9_resize_one_pass_cbr(VP9_COMP *cpi) { - const VP9_COMMON *const cm = &cpi->common; - RATE_CONTROL *const rc = &cpi->rc; - RESIZE_ACTION resize_action = NO_RESIZE; - int avg_qp_thr1 = 70; - int avg_qp_thr2 = 50; - // Don't allow for resized frame to go below 320x180, resize in steps of 3/4. - int min_width = (320 * 4) / 3; - int min_height = (180 * 4) / 3; - int down_size_on = 1; - int force_downsize_rate = 0; - cpi->resize_scale_num = 1; - cpi->resize_scale_den = 1; - // Don't resize on key frame; reset the counters on key frame. - if (cm->frame_type == KEY_FRAME) { - cpi->resize_avg_qp = 0; - cpi->resize_count = 0; - return 0; - } - - // No resizing down if frame size is below some limit. - if ((cm->width * cm->height) < min_width * min_height) down_size_on = 0; - -#if CONFIG_VP9_TEMPORAL_DENOISING - // If denoiser is on, apply a smaller qp threshold. - if (cpi->oxcf.noise_sensitivity > 0) { - avg_qp_thr1 = 60; - avg_qp_thr2 = 40; - } -#endif - - // Force downsize based on per-frame-bandwidth, for extreme case, - // for HD input. - if (cpi->resize_state == ORIG && cm->width * cm->height >= 1280 * 720) { - if (rc->avg_frame_bandwidth < 300000 / 30) { - resize_action = DOWN_ONEHALF; - cpi->resize_state = ONE_HALF; - force_downsize_rate = 1; - } else if (rc->avg_frame_bandwidth < 400000 / 30) { - resize_action = ONEHALFONLY_RESIZE ? DOWN_ONEHALF : DOWN_THREEFOUR; - cpi->resize_state = ONEHALFONLY_RESIZE ? ONE_HALF : THREE_QUARTER; - force_downsize_rate = 1; - } - } else if (cpi->resize_state == THREE_QUARTER && - cm->width * cm->height >= 960 * 540) { - if (rc->avg_frame_bandwidth < 300000 / 30) { - resize_action = DOWN_ONEHALF; - cpi->resize_state = ONE_HALF; - force_downsize_rate = 1; - } - } - - // Resize based on average buffer underflow and QP over some window. - // Ignore samples close to key frame, since QP is usually high after key. - if (!force_downsize_rate && cpi->rc.frames_since_key > cpi->framerate) { - const int window = VPXMIN(30, (int)round(2 * cpi->framerate)); - cpi->resize_avg_qp += rc->last_q[INTER_FRAME]; - if (cpi->rc.buffer_level < (int)(30 * rc->optimal_buffer_level / 100)) - ++cpi->resize_buffer_underflow; - ++cpi->resize_count; - // Check for resize action every "window" frames. - if (cpi->resize_count >= window) { - int avg_qp = cpi->resize_avg_qp / cpi->resize_count; - // Resize down if buffer level has underflowed sufficient amount in past - // window, and we are at original or 3/4 of original resolution. - // Resize back up if average QP is low, and we are currently in a resized - // down state, i.e. 1/2 or 3/4 of original resolution. - // Currently, use a flag to turn 3/4 resizing feature on/off. - if (cpi->resize_buffer_underflow > (cpi->resize_count >> 2) && - down_size_on) { - if (cpi->resize_state == THREE_QUARTER) { - resize_action = DOWN_ONEHALF; - cpi->resize_state = ONE_HALF; - } else if (cpi->resize_state == ORIG) { - resize_action = ONEHALFONLY_RESIZE ? DOWN_ONEHALF : DOWN_THREEFOUR; - cpi->resize_state = ONEHALFONLY_RESIZE ? ONE_HALF : THREE_QUARTER; - } - } else if (cpi->resize_state != ORIG && - avg_qp < avg_qp_thr1 * cpi->rc.worst_quality / 100) { - if (cpi->resize_state == THREE_QUARTER || - avg_qp < avg_qp_thr2 * cpi->rc.worst_quality / 100 || - ONEHALFONLY_RESIZE) { - resize_action = UP_ORIG; - cpi->resize_state = ORIG; - } else if (cpi->resize_state == ONE_HALF) { - resize_action = UP_THREEFOUR; - cpi->resize_state = THREE_QUARTER; - } - } - // Reset for next window measurement. - cpi->resize_avg_qp = 0; - cpi->resize_count = 0; - cpi->resize_buffer_underflow = 0; - } - } - // If decision is to resize, reset some quantities, and check is we should - // reduce rate correction factor, - if (resize_action != NO_RESIZE) { - int target_bits_per_frame; - int active_worst_quality; - int qindex; - int tot_scale_change; - if (resize_action == DOWN_THREEFOUR || resize_action == UP_THREEFOUR) { - cpi->resize_scale_num = 3; - cpi->resize_scale_den = 4; - } else if (resize_action == DOWN_ONEHALF) { - cpi->resize_scale_num = 1; - cpi->resize_scale_den = 2; - } else { // UP_ORIG or anything else - cpi->resize_scale_num = 1; - cpi->resize_scale_den = 1; - } - tot_scale_change = (cpi->resize_scale_den * cpi->resize_scale_den) / - (cpi->resize_scale_num * cpi->resize_scale_num); - // Reset buffer level to optimal, update target size. - rc->buffer_level = rc->optimal_buffer_level; - rc->bits_off_target = rc->optimal_buffer_level; - rc->this_frame_target = vp9_calc_pframe_target_size_one_pass_cbr(cpi); - // Get the projected qindex, based on the scaled target frame size (scaled - // so target_bits_per_mb in vp9_rc_regulate_q will be correct target). - target_bits_per_frame = (resize_action >= 0) - ? rc->this_frame_target * tot_scale_change - : rc->this_frame_target / tot_scale_change; - active_worst_quality = calc_active_worst_quality_one_pass_cbr(cpi); - qindex = vp9_rc_regulate_q(cpi, target_bits_per_frame, rc->best_quality, - active_worst_quality); - // If resize is down, check if projected q index is close to worst_quality, - // and if so, reduce the rate correction factor (since likely can afford - // lower q for resized frame). - if (resize_action > 0 && qindex > 90 * cpi->rc.worst_quality / 100) { - rc->rate_correction_factors[INTER_NORMAL] *= 0.85; - } - // If resize is back up, check if projected q index is too much above the - // current base_qindex, and if so, reduce the rate correction factor - // (since prefer to keep q for resized frame at least close to previous q). - if (resize_action < 0 && qindex > 130 * cm->base_qindex / 100) { - rc->rate_correction_factors[INTER_NORMAL] *= 0.9; - } - } - return resize_action; -} - -static void adjust_gf_boost_lag_one_pass_vbr(VP9_COMP *cpi, - uint64_t avg_sad_current) { - VP9_COMMON *const cm = &cpi->common; - RATE_CONTROL *const rc = &cpi->rc; - int target; - int found = 0; - int found2 = 0; - int frame; - int i; - uint64_t avg_source_sad_lag = avg_sad_current; - int high_source_sad_lagindex = -1; - int steady_sad_lagindex = -1; - uint32_t sad_thresh1 = 70000; - uint32_t sad_thresh2 = 120000; - int low_content = 0; - int high_content = 0; - double rate_err = 1.0; - // Get measure of complexity over the future frames, and get the first - // future frame with high_source_sad/scene-change. - int tot_frames = (int)vp9_lookahead_depth(cpi->lookahead) - 1; - for (frame = tot_frames; frame >= 1; --frame) { - const int lagframe_idx = tot_frames - frame + 1; - uint64_t reference_sad = rc->avg_source_sad[0]; - for (i = 1; i < lagframe_idx; ++i) { - if (rc->avg_source_sad[i] > 0) - reference_sad = (3 * reference_sad + rc->avg_source_sad[i]) >> 2; - } - // Detect up-coming scene change. - if (!found && - (rc->avg_source_sad[lagframe_idx] > - VPXMAX(sad_thresh1, (unsigned int)(reference_sad << 1)) || - rc->avg_source_sad[lagframe_idx] > - VPXMAX(3 * sad_thresh1 >> 2, - (unsigned int)(reference_sad << 2)))) { - high_source_sad_lagindex = lagframe_idx; - found = 1; - } - // Detect change from motion to steady. - if (!found2 && lagframe_idx > 1 && lagframe_idx < tot_frames && - rc->avg_source_sad[lagframe_idx - 1] > (sad_thresh1 >> 2)) { - found2 = 1; - for (i = lagframe_idx; i < tot_frames; ++i) { - if (!(rc->avg_source_sad[i] > 0 && - rc->avg_source_sad[i] < (sad_thresh1 >> 2) && - rc->avg_source_sad[i] < - (rc->avg_source_sad[lagframe_idx - 1] >> 1))) { - found2 = 0; - i = tot_frames; - } - } - if (found2) steady_sad_lagindex = lagframe_idx; - } - avg_source_sad_lag += rc->avg_source_sad[lagframe_idx]; - } - if (tot_frames > 0) avg_source_sad_lag = avg_source_sad_lag / tot_frames; - // Constrain distance between detected scene cuts. - if (high_source_sad_lagindex != -1 && - high_source_sad_lagindex != rc->high_source_sad_lagindex - 1 && - abs(high_source_sad_lagindex - rc->high_source_sad_lagindex) < 4) - rc->high_source_sad_lagindex = -1; - else - rc->high_source_sad_lagindex = high_source_sad_lagindex; - // Adjust some factors for the next GF group, ignore initial key frame, - // and only for lag_in_frames not too small. - if (cpi->refresh_golden_frame == 1 && cm->current_video_frame > 30 && - cpi->oxcf.lag_in_frames > 8) { - int frame_constraint; - if (rc->rolling_target_bits > 0) - rate_err = - (double)rc->rolling_actual_bits / (double)rc->rolling_target_bits; - high_content = high_source_sad_lagindex != -1 || - avg_source_sad_lag > (rc->prev_avg_source_sad_lag << 1) || - avg_source_sad_lag > sad_thresh2; - low_content = high_source_sad_lagindex == -1 && - ((avg_source_sad_lag < (rc->prev_avg_source_sad_lag >> 1)) || - (avg_source_sad_lag < sad_thresh1)); - if (low_content) { - rc->gfu_boost = DEFAULT_GF_BOOST; - rc->baseline_gf_interval = - VPXMIN(15, (3 * rc->baseline_gf_interval) >> 1); - } else if (high_content) { - rc->gfu_boost = DEFAULT_GF_BOOST >> 1; - rc->baseline_gf_interval = (rate_err > 3.0) - ? VPXMAX(10, rc->baseline_gf_interval >> 1) - : VPXMAX(6, rc->baseline_gf_interval >> 1); - } - if (rc->baseline_gf_interval > cpi->oxcf.lag_in_frames - 1) - rc->baseline_gf_interval = cpi->oxcf.lag_in_frames - 1; - // Check for constraining gf_interval for up-coming scene/content changes, - // or for up-coming key frame, whichever is closer. - frame_constraint = rc->frames_to_key; - if (rc->high_source_sad_lagindex > 0 && - frame_constraint > rc->high_source_sad_lagindex) - frame_constraint = rc->high_source_sad_lagindex; - if (steady_sad_lagindex > 3 && frame_constraint > steady_sad_lagindex) - frame_constraint = steady_sad_lagindex; - adjust_gfint_frame_constraint(cpi, frame_constraint); - rc->frames_till_gf_update_due = rc->baseline_gf_interval; - // Adjust factors for active_worst setting & af_ratio for next gf interval. - rc->fac_active_worst_inter = 150; // corresponds to 3/2 (= 150 /100). - rc->fac_active_worst_gf = 100; - if (rate_err < 2.0 && !high_content) { - rc->fac_active_worst_inter = 120; - rc->fac_active_worst_gf = 90; - } else if (rate_err > 8.0 && rc->avg_frame_qindex[INTER_FRAME] < 16) { - // Increase active_worst faster at low Q if rate fluctuation is high. - rc->fac_active_worst_inter = 200; - if (rc->avg_frame_qindex[INTER_FRAME] < 8) - rc->fac_active_worst_inter = 400; - } - if (low_content && rc->avg_frame_low_motion > 80) { - rc->af_ratio_onepass_vbr = 15; - } else if (high_content || rc->avg_frame_low_motion < 30) { - rc->af_ratio_onepass_vbr = 5; - rc->gfu_boost = DEFAULT_GF_BOOST >> 2; - } - if (cpi->sf.use_altref_onepass && cpi->oxcf.enable_auto_arf) { - // Flag to disable usage of ARF based on past usage, only allow this - // disabling if current frame/group does not start with key frame or - // scene cut. Note perc_arf_usage is only computed for speed >= 5. - int arf_usage_low = - (cm->frame_type != KEY_FRAME && !rc->high_source_sad && - cpi->rc.perc_arf_usage < 15 && cpi->oxcf.speed >= 5); - // Don't use alt-ref for this group under certain conditions. - if (arf_usage_low || - (rc->high_source_sad_lagindex > 0 && - rc->high_source_sad_lagindex <= rc->frames_till_gf_update_due) || - (avg_source_sad_lag > 3 * sad_thresh1 >> 3)) { - rc->source_alt_ref_pending = 0; - rc->alt_ref_gf_group = 0; - } else { - rc->source_alt_ref_pending = 1; - rc->alt_ref_gf_group = 1; - // If alt-ref is used for this gf group, limit the interval. - if (rc->baseline_gf_interval > 12) { - rc->baseline_gf_interval = 12; - rc->frames_till_gf_update_due = rc->baseline_gf_interval; - } - } - } - target = vp9_calc_pframe_target_size_one_pass_vbr(cpi); - vp9_rc_set_frame_target(cpi, target); - } - rc->prev_avg_source_sad_lag = avg_source_sad_lag; -} - -// Compute average source sad (temporal sad: between current source and -// previous source) over a subset of superblocks. Use this is detect big changes -// in content and allow rate control to react. -// This function also handles special case of lag_in_frames, to measure content -// level in #future frames set by the lag_in_frames. -void vp9_scene_detection_onepass(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - RATE_CONTROL *const rc = &cpi->rc; - YV12_BUFFER_CONFIG const *unscaled_src = cpi->un_scaled_source; - YV12_BUFFER_CONFIG const *unscaled_last_src = cpi->unscaled_last_source; - uint8_t *src_y; - int src_ystride; - int src_width; - int src_height; - uint8_t *last_src_y; - int last_src_ystride; - int last_src_width; - int last_src_height; - if (cpi->un_scaled_source == NULL || cpi->unscaled_last_source == NULL || - (cpi->use_svc && cpi->svc.current_superframe == 0)) - return; - src_y = unscaled_src->y_buffer; - src_ystride = unscaled_src->y_stride; - src_width = unscaled_src->y_width; - src_height = unscaled_src->y_height; - last_src_y = unscaled_last_src->y_buffer; - last_src_ystride = unscaled_last_src->y_stride; - last_src_width = unscaled_last_src->y_width; - last_src_height = unscaled_last_src->y_height; -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) return; -#endif - rc->high_source_sad = 0; - rc->high_num_blocks_with_motion = 0; - // For SVC: scene detection is only checked on first spatial layer of - // the superframe using the original/unscaled resolutions. - if (cpi->svc.spatial_layer_id == cpi->svc.first_spatial_layer_to_encode && - src_width == last_src_width && src_height == last_src_height) { - YV12_BUFFER_CONFIG *frames[MAX_LAG_BUFFERS] = { NULL }; - int num_mi_cols = cm->mi_cols; - int num_mi_rows = cm->mi_rows; - int start_frame = 0; - int frames_to_buffer = 1; - int frame = 0; - int scene_cut_force_key_frame = 0; - int num_zero_temp_sad = 0; - uint64_t avg_sad_current = 0; - uint32_t min_thresh = 20000; // ~5 * 64 * 64 - float thresh = 8.0f; - uint32_t thresh_key = 140000; - if (cpi->oxcf.speed <= 5) thresh_key = 240000; - if (cpi->oxcf.content != VP9E_CONTENT_SCREEN) min_thresh = 65000; - if (cpi->oxcf.rc_mode == VPX_VBR) thresh = 2.1f; - if (cpi->use_svc && cpi->svc.number_spatial_layers > 1) { - const int aligned_width = ALIGN_POWER_OF_TWO(src_width, MI_SIZE_LOG2); - const int aligned_height = ALIGN_POWER_OF_TWO(src_height, MI_SIZE_LOG2); - num_mi_cols = aligned_width >> MI_SIZE_LOG2; - num_mi_rows = aligned_height >> MI_SIZE_LOG2; - } - if (cpi->oxcf.lag_in_frames > 0) { - frames_to_buffer = (cm->current_video_frame == 1) - ? (int)vp9_lookahead_depth(cpi->lookahead) - 1 - : 2; - start_frame = (int)vp9_lookahead_depth(cpi->lookahead) - 1; - for (frame = 0; frame < frames_to_buffer; ++frame) { - const int lagframe_idx = start_frame - frame; - if (lagframe_idx >= 0) { - struct lookahead_entry *buf = - vp9_lookahead_peek(cpi->lookahead, lagframe_idx); - frames[frame] = &buf->img; - } - } - // The avg_sad for this current frame is the value of frame#1 - // (first future frame) from previous frame. - avg_sad_current = rc->avg_source_sad[1]; - if (avg_sad_current > - VPXMAX(min_thresh, - (unsigned int)(rc->avg_source_sad[0] * thresh)) && - cm->current_video_frame > (unsigned int)cpi->oxcf.lag_in_frames) - rc->high_source_sad = 1; - else - rc->high_source_sad = 0; - if (rc->high_source_sad && avg_sad_current > thresh_key) - scene_cut_force_key_frame = 1; - // Update recursive average for current frame. - if (avg_sad_current > 0) - rc->avg_source_sad[0] = - (3 * rc->avg_source_sad[0] + avg_sad_current) >> 2; - // Shift back data, starting at frame#1. - for (frame = 1; frame < cpi->oxcf.lag_in_frames - 1; ++frame) - rc->avg_source_sad[frame] = rc->avg_source_sad[frame + 1]; - } - for (frame = 0; frame < frames_to_buffer; ++frame) { - if (cpi->oxcf.lag_in_frames == 0 || - (frames[frame] != NULL && frames[frame + 1] != NULL && - frames[frame]->y_width == frames[frame + 1]->y_width && - frames[frame]->y_height == frames[frame + 1]->y_height)) { - int sbi_row, sbi_col; - const int lagframe_idx = - (cpi->oxcf.lag_in_frames == 0) ? 0 : start_frame - frame + 1; - const BLOCK_SIZE bsize = BLOCK_64X64; - // Loop over sub-sample of frame, compute average sad over 64x64 blocks. - uint64_t avg_sad = 0; - uint64_t tmp_sad = 0; - int num_samples = 0; - int sb_cols = (num_mi_cols + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE; - int sb_rows = (num_mi_rows + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE; - if (cpi->oxcf.lag_in_frames > 0) { - src_y = frames[frame]->y_buffer; - src_ystride = frames[frame]->y_stride; - last_src_y = frames[frame + 1]->y_buffer; - last_src_ystride = frames[frame + 1]->y_stride; - } - num_zero_temp_sad = 0; - for (sbi_row = 0; sbi_row < sb_rows; ++sbi_row) { - for (sbi_col = 0; sbi_col < sb_cols; ++sbi_col) { - // Checker-board pattern, ignore boundary. - if (((sbi_row > 0 && sbi_col > 0) && - (sbi_row < sb_rows - 1 && sbi_col < sb_cols - 1) && - ((sbi_row % 2 == 0 && sbi_col % 2 == 0) || - (sbi_row % 2 != 0 && sbi_col % 2 != 0)))) { - tmp_sad = cpi->fn_ptr[bsize].sdf(src_y, src_ystride, last_src_y, - last_src_ystride); - avg_sad += tmp_sad; - num_samples++; - if (tmp_sad == 0) num_zero_temp_sad++; - } - src_y += 64; - last_src_y += 64; - } - src_y += (src_ystride << 6) - (sb_cols << 6); - last_src_y += (last_src_ystride << 6) - (sb_cols << 6); - } - if (num_samples > 0) avg_sad = avg_sad / num_samples; - // Set high_source_sad flag if we detect very high increase in avg_sad - // between current and previous frame value(s). Use minimum threshold - // for cases where there is small change from content that is completely - // static. - if (lagframe_idx == 0) { - if (avg_sad > - VPXMAX(min_thresh, - (unsigned int)(rc->avg_source_sad[0] * thresh)) && - rc->frames_since_key > 1 + cpi->svc.number_spatial_layers && - num_zero_temp_sad < 3 * (num_samples >> 2)) - rc->high_source_sad = 1; - else - rc->high_source_sad = 0; - if (rc->high_source_sad && avg_sad > thresh_key) - scene_cut_force_key_frame = 1; - if (avg_sad > 0 || cpi->oxcf.rc_mode == VPX_CBR) - rc->avg_source_sad[0] = (3 * rc->avg_source_sad[0] + avg_sad) >> 2; - } else { - rc->avg_source_sad[lagframe_idx] = avg_sad; - } - if (num_zero_temp_sad < (3 * num_samples >> 2)) - rc->high_num_blocks_with_motion = 1; - } - } - // For CBR non-screen content mode, check if we should reset the rate - // control. Reset is done if high_source_sad is detected and the rate - // control is at very low QP with rate correction factor at min level. - if (cpi->oxcf.rc_mode == VPX_CBR && - cpi->oxcf.content != VP9E_CONTENT_SCREEN && !cpi->use_svc) { - if (rc->high_source_sad && rc->last_q[INTER_FRAME] == rc->best_quality && - rc->avg_frame_qindex[INTER_FRAME] < (rc->best_quality << 1) && - rc->rate_correction_factors[INTER_NORMAL] == MIN_BPB_FACTOR) { - rc->rate_correction_factors[INTER_NORMAL] = 0.5; - rc->avg_frame_qindex[INTER_FRAME] = rc->worst_quality; - rc->buffer_level = rc->optimal_buffer_level; - rc->bits_off_target = rc->optimal_buffer_level; - rc->reset_high_source_sad = 1; - } - if (cm->frame_type != KEY_FRAME && rc->reset_high_source_sad) - rc->this_frame_target = rc->avg_frame_bandwidth; - } - // For SVC the new (updated) avg_source_sad[0] for the current superframe - // updates the setting for all layers. - if (cpi->use_svc) { - int sl, tl; - SVC *const svc = &cpi->svc; - for (sl = 0; sl < svc->number_spatial_layers; ++sl) - for (tl = 0; tl < svc->number_temporal_layers; ++tl) { - int layer = LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers); - LAYER_CONTEXT *const lc = &svc->layer_context[layer]; - RATE_CONTROL *const lrc = &lc->rc; - lrc->avg_source_sad[0] = rc->avg_source_sad[0]; - } - } - // For VBR, under scene change/high content change, force golden refresh. - if (cpi->oxcf.rc_mode == VPX_VBR && cm->frame_type != KEY_FRAME && - rc->high_source_sad && rc->frames_to_key > 3 && - rc->count_last_scene_change > 4 && - cpi->ext_refresh_frame_flags_pending == 0) { - int target; - cpi->refresh_golden_frame = 1; - if (scene_cut_force_key_frame) cm->frame_type = KEY_FRAME; - rc->source_alt_ref_pending = 0; - if (cpi->sf.use_altref_onepass && cpi->oxcf.enable_auto_arf) - rc->source_alt_ref_pending = 1; - rc->gfu_boost = DEFAULT_GF_BOOST >> 1; - rc->baseline_gf_interval = - VPXMIN(20, VPXMAX(10, rc->baseline_gf_interval)); - adjust_gfint_frame_constraint(cpi, rc->frames_to_key); - rc->frames_till_gf_update_due = rc->baseline_gf_interval; - target = vp9_calc_pframe_target_size_one_pass_vbr(cpi); - vp9_rc_set_frame_target(cpi, target); - rc->count_last_scene_change = 0; - } else { - rc->count_last_scene_change++; - } - // If lag_in_frame is used, set the gf boost and interval. - if (cpi->oxcf.lag_in_frames > 0) - adjust_gf_boost_lag_one_pass_vbr(cpi, avg_sad_current); - } -} - -// Test if encoded frame will significantly overshoot the target bitrate, and -// if so, set the QP, reset/adjust some rate control parameters, and return 1. -// frame_size = -1 means frame has not been encoded. -int vp9_encodedframe_overshoot(VP9_COMP *cpi, int frame_size, int *q) { - VP9_COMMON *const cm = &cpi->common; - RATE_CONTROL *const rc = &cpi->rc; - SPEED_FEATURES *const sf = &cpi->sf; - int thresh_qp = 7 * (rc->worst_quality >> 3); - int thresh_rate = rc->avg_frame_bandwidth << 3; - // Lower thresh_qp for video (more overshoot at lower Q) to be - // more conservative for video. - if (cpi->oxcf.content != VP9E_CONTENT_SCREEN) - thresh_qp = 3 * (rc->worst_quality >> 2); - // If this decision is not based on an encoded frame size but just on - // scene/slide change detection (i.e., re_encode_overshoot_cbr_rt == - // FAST_DETECTION_MAXQ), for now skip the (frame_size > thresh_rate) - // condition in this case. - // TODO(marpan): Use a better size/rate condition for this case and - // adjust thresholds. - if ((sf->overshoot_detection_cbr_rt == FAST_DETECTION_MAXQ || - frame_size > thresh_rate) && - cm->base_qindex < thresh_qp) { - double rate_correction_factor = - cpi->rc.rate_correction_factors[INTER_NORMAL]; - const int target_size = cpi->rc.avg_frame_bandwidth; - double new_correction_factor; - int target_bits_per_mb; - double q2; - int enumerator; - // Force a re-encode, and for now use max-QP. - *q = cpi->rc.worst_quality; - cpi->cyclic_refresh->counter_encode_maxq_scene_change = 0; - cpi->rc.re_encode_maxq_scene_change = 1; - // If the frame_size is much larger than the threshold (big content change) - // and the encoded frame used alot of Intra modes, then force hybrid_intra - // encoding for the re-encode on this scene change. hybrid_intra will - // use rd-based intra mode selection for small blocks. - if (sf->overshoot_detection_cbr_rt == RE_ENCODE_MAXQ && - frame_size > (thresh_rate << 1) && cpi->svc.spatial_layer_id == 0) { - MODE_INFO **mi = cm->mi_grid_visible; - int sum_intra_usage = 0; - int mi_row, mi_col; - for (mi_row = 0; mi_row < cm->mi_rows; mi_row++) { - for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) { - if (mi[0]->ref_frame[0] == INTRA_FRAME) sum_intra_usage++; - mi++; - } - mi += 8; - } - sum_intra_usage = 100 * sum_intra_usage / (cm->mi_rows * cm->mi_cols); - if (sum_intra_usage > 60) cpi->rc.hybrid_intra_scene_change = 1; - } - // Adjust avg_frame_qindex, buffer_level, and rate correction factors, as - // these parameters will affect QP selection for subsequent frames. If they - // have settled down to a very different (low QP) state, then not adjusting - // them may cause next frame to select low QP and overshoot again. - cpi->rc.avg_frame_qindex[INTER_FRAME] = *q; - rc->buffer_level = rc->optimal_buffer_level; - rc->bits_off_target = rc->optimal_buffer_level; - // Reset rate under/over-shoot flags. - cpi->rc.rc_1_frame = 0; - cpi->rc.rc_2_frame = 0; - // Adjust rate correction factor. - target_bits_per_mb = - (int)(((uint64_t)target_size << BPER_MB_NORMBITS) / cm->MBs); - // Rate correction factor based on target_bits_per_mb and qp (==max_QP). - // This comes from the inverse computation of vp9_rc_bits_per_mb(). - q2 = vp9_convert_qindex_to_q(*q, cm->bit_depth); - enumerator = 1800000; // Factor for inter frame. - enumerator += (int)(enumerator * q2) >> 12; - new_correction_factor = (double)target_bits_per_mb * q2 / enumerator; - if (new_correction_factor > rate_correction_factor) { - rate_correction_factor = - VPXMIN(2.0 * rate_correction_factor, new_correction_factor); - if (rate_correction_factor > MAX_BPB_FACTOR) - rate_correction_factor = MAX_BPB_FACTOR; - cpi->rc.rate_correction_factors[INTER_NORMAL] = rate_correction_factor; - } - // For temporal layers, reset the rate control parametes across all - // temporal layers. - // If the first_spatial_layer_to_encode > 0, then this superframe has - // skipped lower base layers. So in this case we should also reset and - // force max-q for spatial layers < first_spatial_layer_to_encode. - // For the case of no inter-layer prediction on delta frames: reset and - // force max-q for all spatial layers, to avoid excessive frame drops. - if (cpi->use_svc) { - int tl = 0; - int sl = 0; - SVC *svc = &cpi->svc; - int num_spatial_layers = VPXMAX(1, svc->first_spatial_layer_to_encode); - if (svc->disable_inter_layer_pred != INTER_LAYER_PRED_ON) - num_spatial_layers = svc->number_spatial_layers; - for (sl = 0; sl < num_spatial_layers; ++sl) { - for (tl = 0; tl < svc->number_temporal_layers; ++tl) { - const int layer = - LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers); - LAYER_CONTEXT *lc = &svc->layer_context[layer]; - RATE_CONTROL *lrc = &lc->rc; - lrc->avg_frame_qindex[INTER_FRAME] = *q; - lrc->buffer_level = lrc->optimal_buffer_level; - lrc->bits_off_target = lrc->optimal_buffer_level; - lrc->rc_1_frame = 0; - lrc->rc_2_frame = 0; - lrc->rate_correction_factors[INTER_NORMAL] = rate_correction_factor; - lrc->force_max_q = 1; - } - } - } - return 1; - } else { - return 0; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ratectrl.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ratectrl.h deleted file mode 100644 index 0c61ad34..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_ratectrl.h +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_RATECTRL_H_ -#define VPX_VP9_ENCODER_VP9_RATECTRL_H_ - -#include "vpx/vpx_codec.h" -#include "vpx/vpx_integer.h" - -#include "vp9/common/vp9_blockd.h" -#include "vp9/encoder/vp9_lookahead.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// Used to control aggressive VBR mode. -// #define AGGRESSIVE_VBR 1 - -// Bits Per MB at different Q (Multiplied by 512) -#define BPER_MB_NORMBITS 9 - -#define DEFAULT_KF_BOOST 2000 -#define DEFAULT_GF_BOOST 2000 - -#define MIN_GF_INTERVAL 4 -#define MAX_GF_INTERVAL 16 -#define FIXED_GF_INTERVAL 8 // Used in some testing modes only -#define ONEHALFONLY_RESIZE 0 - -#define FRAME_OVERHEAD_BITS 200 - -// Threshold used to define a KF group as static (e.g. a slide show). -// Essentially this means that no frame in the group has more than 1% of MBs -// that are not marked as coded with 0,0 motion in the first pass. -#define STATIC_KF_GROUP_THRESH 99 - -// The maximum duration of a GF group that is static (for example a slide show). -#define MAX_STATIC_GF_GROUP_LENGTH 250 - -typedef enum { - INTER_NORMAL = 0, - INTER_HIGH = 1, - GF_ARF_LOW = 2, - GF_ARF_STD = 3, - KF_STD = 4, - RATE_FACTOR_LEVELS = 5 -} RATE_FACTOR_LEVEL; - -// Internal frame scaling level. -typedef enum { - UNSCALED = 0, // Frame is unscaled. - SCALE_STEP1 = 1, // First-level down-scaling. - FRAME_SCALE_STEPS -} FRAME_SCALE_LEVEL; - -typedef enum { - NO_RESIZE = 0, - DOWN_THREEFOUR = 1, // From orig to 3/4. - DOWN_ONEHALF = 2, // From orig or 3/4 to 1/2. - UP_THREEFOUR = -1, // From 1/2 to 3/4. - UP_ORIG = -2, // From 1/2 or 3/4 to orig. -} RESIZE_ACTION; - -typedef enum { ORIG = 0, THREE_QUARTER = 1, ONE_HALF = 2 } RESIZE_STATE; - -// Frame dimensions multiplier wrt the native frame size, in 1/16ths, -// specified for the scale-up case. -// e.g. 24 => 16/24 = 2/3 of native size. The restriction to 1/16th is -// intended to match the capabilities of the normative scaling filters, -// giving precedence to the up-scaling accuracy. -static const int frame_scale_factor[FRAME_SCALE_STEPS] = { 16, 24 }; - -// Multiplier of the target rate to be used as threshold for triggering scaling. -static const double rate_thresh_mult[FRAME_SCALE_STEPS] = { 1.0, 2.0 }; - -// Scale dependent Rate Correction Factor multipliers. Compensates for the -// greater number of bits per pixel generated in down-scaled frames. -static const double rcf_mult[FRAME_SCALE_STEPS] = { 1.0, 2.0 }; - -typedef struct { - // Rate targeting variables - int base_frame_target; // A baseline frame target before adjustment - // for previous under or over shoot. - int this_frame_target; // Actual frame target after rc adjustment. - int projected_frame_size; - int sb64_target_rate; - int last_q[FRAME_TYPES]; // Separate values for Intra/Inter - int last_boosted_qindex; // Last boosted GF/KF/ARF q - int last_kf_qindex; // Q index of the last key frame coded. - - int gfu_boost; - int last_boost; - int kf_boost; - - double rate_correction_factors[RATE_FACTOR_LEVELS]; - - int frames_since_golden; - int frames_till_gf_update_due; - int min_gf_interval; - int max_gf_interval; - int static_scene_max_gf_interval; - int baseline_gf_interval; - int constrained_gf_group; - int frames_to_key; - int frames_since_key; - int this_key_frame_forced; - int next_key_frame_forced; - int source_alt_ref_pending; - int source_alt_ref_active; - int is_src_frame_alt_ref; - - int avg_frame_bandwidth; // Average frame size target for clip - int min_frame_bandwidth; // Minimum allocation used for any frame - int max_frame_bandwidth; // Maximum burst rate allowed for a frame. - - int ni_av_qi; - int ni_tot_qi; - int ni_frames; - int avg_frame_qindex[FRAME_TYPES]; - double tot_q; - double avg_q; - - int64_t buffer_level; - int64_t bits_off_target; - int64_t vbr_bits_off_target; - int64_t vbr_bits_off_target_fast; - - int decimation_factor; - int decimation_count; - - int rolling_target_bits; - int rolling_actual_bits; - - int long_rolling_target_bits; - int long_rolling_actual_bits; - - int rate_error_estimate; - - int64_t total_actual_bits; - int64_t total_target_bits; - int64_t total_target_vs_actual; - - int worst_quality; - int best_quality; - - int64_t starting_buffer_level; - int64_t optimal_buffer_level; - int64_t maximum_buffer_size; - - // rate control history for last frame(1) and the frame before(2). - // -1: undershot - // 1: overshoot - // 0: not initialized. - int rc_1_frame; - int rc_2_frame; - int q_1_frame; - int q_2_frame; - // Keep track of the last target average frame bandwidth. - int last_avg_frame_bandwidth; - - // Auto frame-scaling variables. - FRAME_SCALE_LEVEL frame_size_selector; - FRAME_SCALE_LEVEL next_frame_size_selector; - int frame_width[FRAME_SCALE_STEPS]; - int frame_height[FRAME_SCALE_STEPS]; - int rf_level_maxq[RATE_FACTOR_LEVELS]; - - int fac_active_worst_inter; - int fac_active_worst_gf; - uint64_t avg_source_sad[MAX_LAG_BUFFERS]; - uint64_t prev_avg_source_sad_lag; - int high_source_sad_lagindex; - int high_num_blocks_with_motion; - int alt_ref_gf_group; - int last_frame_is_src_altref; - int high_source_sad; - int count_last_scene_change; - int hybrid_intra_scene_change; - int re_encode_maxq_scene_change; - int avg_frame_low_motion; - int af_ratio_onepass_vbr; - int force_qpmin; - int reset_high_source_sad; - double perc_arf_usage; - int force_max_q; - // Last frame was dropped post encode on scene change. - int last_post_encode_dropped_scene_change; - // Enable post encode frame dropping for screen content. Only enabled when - // ext_use_post_encode_drop is enabled by user. - int use_post_encode_drop; - // External flag to enable post encode frame dropping, controlled by user. - int ext_use_post_encode_drop; - // Flag to disable CBR feature to increase Q on overshoot detection. - int disable_overshoot_maxq_cbr; - int damped_adjustment[RATE_FACTOR_LEVELS]; - double arf_active_best_quality_adjustment_factor; - int arf_increase_active_best_quality; - - int preserve_arf_as_gld; - int preserve_next_arf_as_gld; - int show_arf_as_gld; - - // Flag to constrain golden frame interval on key frame frequency for 1 pass - // VBR. - int constrain_gf_key_freq_onepass_vbr; - - // The index of the current GOP. Start from zero. - // When a key frame is inserted, it resets to zero. - int gop_global_index; -} RATE_CONTROL; - -struct VP9_COMP; -struct VP9EncoderConfig; - -void vp9_rc_init(const struct VP9EncoderConfig *oxcf, int pass, - RATE_CONTROL *rc); - -int vp9_estimate_bits_at_q(FRAME_TYPE frame_type, int q, int mbs, - double correction_factor, vpx_bit_depth_t bit_depth); - -double vp9_convert_qindex_to_q(int qindex, vpx_bit_depth_t bit_depth); - -int vp9_convert_q_to_qindex(double q_val, vpx_bit_depth_t bit_depth); - -void vp9_rc_init_minq_luts(void); - -int vp9_rc_get_default_min_gf_interval(int width, int height, double framerate); -// Note vp9_rc_get_default_max_gf_interval() requires the min_gf_interval to -// be passed in to ensure that the max_gf_interval returned is at least as big -// as that. -int vp9_rc_get_default_max_gf_interval(double framerate, int min_gf_interval); - -// Generally at the high level, the following flow is expected -// to be enforced for rate control: -// First call per frame, one of: -// vp9_rc_get_one_pass_vbr_params() -// vp9_rc_get_one_pass_cbr_params() -// vp9_rc_get_svc_params() -// vp9_rc_get_first_pass_params() -// vp9_rc_get_second_pass_params() -// depending on the usage to set the rate control encode parameters desired. -// -// Then, call encode_frame_to_data_rate() to perform the -// actual encode. This function will in turn call encode_frame() -// one or more times, followed by one of: -// vp9_rc_postencode_update() -// vp9_rc_postencode_update_drop_frame() -// -// The majority of rate control parameters are only expected -// to be set in the vp9_rc_get_..._params() functions and -// updated during the vp9_rc_postencode_update...() functions. -// The only exceptions are vp9_rc_drop_frame() and -// vp9_rc_update_rate_correction_factors() functions. - -// Functions to set parameters for encoding before the actual -// encode_frame_to_data_rate() function. -void vp9_rc_get_one_pass_vbr_params(struct VP9_COMP *cpi); -void vp9_rc_get_one_pass_cbr_params(struct VP9_COMP *cpi); -int vp9_calc_pframe_target_size_one_pass_cbr(const struct VP9_COMP *cpi); -int vp9_calc_iframe_target_size_one_pass_cbr(const struct VP9_COMP *cpi); -int vp9_calc_pframe_target_size_one_pass_vbr(const struct VP9_COMP *cpi); -int vp9_calc_iframe_target_size_one_pass_vbr(const struct VP9_COMP *cpi); -void vp9_set_gf_update_one_pass_vbr(struct VP9_COMP *const cpi); -void vp9_update_buffer_level_preencode(struct VP9_COMP *cpi); -void vp9_rc_get_svc_params(struct VP9_COMP *cpi); - -// Post encode update of the rate control parameters based -// on bytes used -void vp9_rc_postencode_update(struct VP9_COMP *cpi, uint64_t bytes_used); -// Post encode update of the rate control parameters for dropped frames -void vp9_rc_postencode_update_drop_frame(struct VP9_COMP *cpi); - -// Updates rate correction factors -// Changes only the rate correction factors in the rate control structure. -void vp9_rc_update_rate_correction_factors(struct VP9_COMP *cpi); - -// Post encode drop for CBR mode. -int post_encode_drop_cbr(struct VP9_COMP *cpi, size_t *size); - -int vp9_test_drop(struct VP9_COMP *cpi); - -// Decide if we should drop this frame: For 1-pass CBR. -// Changes only the decimation count in the rate control structure -int vp9_rc_drop_frame(struct VP9_COMP *cpi); - -// Computes frame size bounds. -void vp9_rc_compute_frame_size_bounds(const struct VP9_COMP *cpi, - int frame_target, - int *frame_under_shoot_limit, - int *frame_over_shoot_limit); - -// Picks q and q bounds given the target for bits -int vp9_rc_pick_q_and_bounds(const struct VP9_COMP *cpi, int *bottom_index, - int *top_index); - -// Estimates q to achieve a target bits per frame -int vp9_rc_regulate_q(const struct VP9_COMP *cpi, int target_bits_per_frame, - int active_best_quality, int active_worst_quality); - -// Estimates bits per mb for a given qindex and correction factor. -int vp9_rc_bits_per_mb(FRAME_TYPE frame_type, int qindex, - double correction_factor, vpx_bit_depth_t bit_depth); - -// Clamping utilities for bitrate targets for iframes and pframes. -int vp9_rc_clamp_iframe_target_size(const struct VP9_COMP *const cpi, - int target); -int vp9_rc_clamp_pframe_target_size(const struct VP9_COMP *const cpi, - int target); -// Utility to set frame_target into the RATE_CONTROL structure -// This function is called only from the vp9_rc_get_..._params() functions. -void vp9_rc_set_frame_target(struct VP9_COMP *cpi, int target); - -// Computes a q delta (in "q index" terms) to get from a starting q value -// to a target q value -int vp9_compute_qdelta(const RATE_CONTROL *rc, double qstart, double qtarget, - vpx_bit_depth_t bit_depth); - -// Computes a q delta (in "q index" terms) to get from a starting q value -// to a value that should equate to the given rate ratio. -int vp9_compute_qdelta_by_rate(const RATE_CONTROL *rc, FRAME_TYPE frame_type, - int qindex, double rate_target_ratio, - vpx_bit_depth_t bit_depth); - -int vp9_frame_type_qdelta(const struct VP9_COMP *cpi, int rf_level, int q); - -void vp9_rc_update_framerate(struct VP9_COMP *cpi); - -void vp9_rc_set_gf_interval_range(const struct VP9_COMP *const cpi, - RATE_CONTROL *const rc); - -void vp9_set_target_rate(struct VP9_COMP *cpi); - -int vp9_resize_one_pass_cbr(struct VP9_COMP *cpi); - -void vp9_scene_detection_onepass(struct VP9_COMP *cpi); - -int vp9_encodedframe_overshoot(struct VP9_COMP *cpi, int frame_size, int *q); - -void vp9_configure_buffer_updates(struct VP9_COMP *cpi, int gf_group_index); - -void vp9_compute_frame_low_motion(struct VP9_COMP *const cpi); - -void vp9_update_buffer_level_svc_preencode(struct VP9_COMP *cpi); - -int vp9_rc_pick_q_and_bounds_two_pass(const struct VP9_COMP *cpi, - int *bottom_index, int *top_index, - int gf_group_index); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_RATECTRL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_rd.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_rd.c deleted file mode 100644 index 95c95971..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_rd.c +++ /dev/null @@ -1,795 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "./vp9_rtcd.h" - -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/bitops.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/system_state.h" - -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_entropy.h" -#include "vp9/common/vp9_entropymode.h" -#include "vp9/common/vp9_mvref_common.h" -#include "vp9/common/vp9_pred_common.h" -#include "vp9/common/vp9_quant_common.h" -#include "vp9/common/vp9_reconinter.h" -#include "vp9/common/vp9_reconintra.h" -#include "vp9/common/vp9_seg_common.h" - -#include "vp9/encoder/vp9_cost.h" -#include "vp9/encoder/vp9_encodemb.h" -#include "vp9/encoder/vp9_encodemv.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_mcomp.h" -#include "vp9/encoder/vp9_quantize.h" -#include "vp9/encoder/vp9_ratectrl.h" -#include "vp9/encoder/vp9_rd.h" -#include "vp9/encoder/vp9_tokenize.h" - -#define RD_THRESH_POW 1.25 - -// Factor to weigh the rate for switchable interp filters. -#define SWITCHABLE_INTERP_RATE_FACTOR 1 - -void vp9_rd_cost_reset(RD_COST *rd_cost) { - rd_cost->rate = INT_MAX; - rd_cost->dist = INT64_MAX; - rd_cost->rdcost = INT64_MAX; -} - -void vp9_rd_cost_init(RD_COST *rd_cost) { - rd_cost->rate = 0; - rd_cost->dist = 0; - rd_cost->rdcost = 0; -} - -int64_t vp9_calculate_rd_cost(int mult, int div, int rate, int64_t dist) { - assert(mult >= 0); - assert(div > 0); - if (rate >= 0 && dist >= 0) { - return RDCOST(mult, div, rate, dist); - } - if (rate >= 0 && dist < 0) { - return RDCOST_NEG_D(mult, div, rate, -dist); - } - if (rate < 0 && dist >= 0) { - return RDCOST_NEG_R(mult, div, -rate, dist); - } - return -RDCOST(mult, div, -rate, -dist); -} - -void vp9_rd_cost_update(int mult, int div, RD_COST *rd_cost) { - if (rd_cost->rate < INT_MAX && rd_cost->dist < INT64_MAX) { - rd_cost->rdcost = - vp9_calculate_rd_cost(mult, div, rd_cost->rate, rd_cost->dist); - } else { - vp9_rd_cost_reset(rd_cost); - } -} - -// The baseline rd thresholds for breaking out of the rd loop for -// certain modes are assumed to be based on 8x8 blocks. -// This table is used to correct for block size. -// The factors here are << 2 (2 = x0.5, 32 = x8 etc). -static const uint8_t rd_thresh_block_size_factor[BLOCK_SIZES] = { - 2, 3, 3, 4, 6, 6, 8, 12, 12, 16, 24, 24, 32 -}; - -static void fill_mode_costs(VP9_COMP *cpi) { - const FRAME_CONTEXT *const fc = cpi->common.fc; - int i, j; - - for (i = 0; i < INTRA_MODES; ++i) { - for (j = 0; j < INTRA_MODES; ++j) { - vp9_cost_tokens(cpi->y_mode_costs[i][j], vp9_kf_y_mode_prob[i][j], - vp9_intra_mode_tree); - } - } - - vp9_cost_tokens(cpi->mbmode_cost, fc->y_mode_prob[1], vp9_intra_mode_tree); - for (i = 0; i < INTRA_MODES; ++i) { - vp9_cost_tokens(cpi->intra_uv_mode_cost[KEY_FRAME][i], - vp9_kf_uv_mode_prob[i], vp9_intra_mode_tree); - vp9_cost_tokens(cpi->intra_uv_mode_cost[INTER_FRAME][i], - fc->uv_mode_prob[i], vp9_intra_mode_tree); - } - - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) { - vp9_cost_tokens(cpi->switchable_interp_costs[i], - fc->switchable_interp_prob[i], vp9_switchable_interp_tree); - } - - for (i = TX_8X8; i < TX_SIZES; ++i) { - for (j = 0; j < TX_SIZE_CONTEXTS; ++j) { - const vpx_prob *tx_probs = get_tx_probs(i, j, &fc->tx_probs); - int k; - for (k = 0; k <= i; ++k) { - int cost = 0; - int m; - for (m = 0; m <= k - (k == i); ++m) { - if (m == k) - cost += vp9_cost_zero(tx_probs[m]); - else - cost += vp9_cost_one(tx_probs[m]); - } - cpi->tx_size_cost[i - 1][j][k] = cost; - } - } - } -} - -static void fill_token_costs(vp9_coeff_cost *c, - vp9_coeff_probs_model (*p)[PLANE_TYPES]) { - int i, j, k, l; - TX_SIZE t; - for (t = TX_4X4; t <= TX_32X32; ++t) - for (i = 0; i < PLANE_TYPES; ++i) - for (j = 0; j < REF_TYPES; ++j) - for (k = 0; k < COEF_BANDS; ++k) - for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) { - vpx_prob probs[ENTROPY_NODES]; - vp9_model_to_full_probs(p[t][i][j][k][l], probs); - vp9_cost_tokens((int *)c[t][i][j][k][0][l], probs, vp9_coef_tree); - vp9_cost_tokens_skip((int *)c[t][i][j][k][1][l], probs, - vp9_coef_tree); - assert(c[t][i][j][k][0][l][EOB_TOKEN] == - c[t][i][j][k][1][l][EOB_TOKEN]); - } -} - -// Values are now correlated to quantizer. -static int sad_per_bit16lut_8[QINDEX_RANGE]; -static int sad_per_bit4lut_8[QINDEX_RANGE]; - -#if CONFIG_VP9_HIGHBITDEPTH -static int sad_per_bit16lut_10[QINDEX_RANGE]; -static int sad_per_bit4lut_10[QINDEX_RANGE]; -static int sad_per_bit16lut_12[QINDEX_RANGE]; -static int sad_per_bit4lut_12[QINDEX_RANGE]; -#endif - -static void init_me_luts_bd(int *bit16lut, int *bit4lut, int range, - vpx_bit_depth_t bit_depth) { - int i; - // Initialize the sad lut tables using a formulaic calculation for now. - // This is to make it easier to resolve the impact of experimental changes - // to the quantizer tables. - for (i = 0; i < range; i++) { - const double q = vp9_convert_qindex_to_q(i, bit_depth); - bit16lut[i] = (int)(0.0418 * q + 2.4107); - bit4lut[i] = (int)(0.063 * q + 2.742); - } -} - -void vp9_init_me_luts(void) { - init_me_luts_bd(sad_per_bit16lut_8, sad_per_bit4lut_8, QINDEX_RANGE, - VPX_BITS_8); -#if CONFIG_VP9_HIGHBITDEPTH - init_me_luts_bd(sad_per_bit16lut_10, sad_per_bit4lut_10, QINDEX_RANGE, - VPX_BITS_10); - init_me_luts_bd(sad_per_bit16lut_12, sad_per_bit4lut_12, QINDEX_RANGE, - VPX_BITS_12); -#endif -} - -static const int rd_boost_factor[16] = { 64, 32, 32, 32, 24, 16, 12, 12, - 8, 8, 4, 4, 2, 2, 1, 0 }; - -// Note that the element below for frame type "USE_BUF_FRAME", which indicates -// that the show frame flag is set, should not be used as no real frame -// is encoded so we should not reach here. However, a dummy value -// is inserted here to make sure the data structure has the right number -// of values assigned. -static const int rd_frame_type_factor[FRAME_UPDATE_TYPES] = { 128, 144, 128, - 128, 144, 144 }; - -// Configure Vizier RD parameters. -// Later this function will use passed in command line values. -void vp9_init_rd_parameters(VP9_COMP *cpi) { - RD_CONTROL *const rdc = &cpi->rd_ctrl; - - // When |use_vizier_rc_params| is 1, we expect the rd parameters have been - // initialized by the pass in values. - // Be careful that parameters below are only initialized to 1, if we do not - // pass values to them. It is desired to take care of each parameter when - // using |use_vizier_rc_params|. - if (cpi->twopass.use_vizier_rc_params) return; - - // Make sure this function is floating point safe. - vpx_clear_system_state(); - - rdc->rd_mult_inter_qp_fac = 1.0; - rdc->rd_mult_arf_qp_fac = 1.0; - rdc->rd_mult_key_qp_fac = 1.0; -} - -// Returns the default rd multiplier for inter frames for a given qindex. -// The function here is a first pass estimate based on data from -// a previous Vizer run -static double def_inter_rd_multiplier(int qindex) { - return 4.15 + (0.001 * (double)qindex); -} - -// Returns the default rd multiplier for ARF/Golden Frames for a given qindex. -// The function here is a first pass estimate based on data from -// a previous Vizer run -static double def_arf_rd_multiplier(int qindex) { - return 4.25 + (0.001 * (double)qindex); -} - -// Returns the default rd multiplier for key frames for a given qindex. -// The function here is a first pass estimate based on data from -// a previous Vizer run -static double def_kf_rd_multiplier(int qindex) { - return 4.35 + (0.001 * (double)qindex); -} - -int vp9_compute_rd_mult_based_on_qindex(const VP9_COMP *cpi, int qindex) { - const RD_CONTROL *rdc = &cpi->rd_ctrl; - const int q = vp9_dc_quant(qindex, 0, cpi->common.bit_depth); - // largest dc_quant is 21387, therefore rdmult should fit in int32_t - int rdmult = q * q; - - if (cpi->ext_ratectrl.ready && - (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_RDMULT) != 0 && - cpi->ext_ratectrl.ext_rdmult != VPX_DEFAULT_RDMULT) { - return cpi->ext_ratectrl.ext_rdmult; - } - - // Make sure this function is floating point safe. - vpx_clear_system_state(); - - if (cpi->common.frame_type == KEY_FRAME) { - double def_rd_q_mult = def_kf_rd_multiplier(qindex); - rdmult = (int)((double)rdmult * def_rd_q_mult * rdc->rd_mult_key_qp_fac); - } else if (!cpi->rc.is_src_frame_alt_ref && - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { - double def_rd_q_mult = def_arf_rd_multiplier(qindex); - rdmult = (int)((double)rdmult * def_rd_q_mult * rdc->rd_mult_arf_qp_fac); - } else { - double def_rd_q_mult = def_inter_rd_multiplier(qindex); - rdmult = (int)((double)rdmult * def_rd_q_mult * rdc->rd_mult_inter_qp_fac); - } - -#if CONFIG_VP9_HIGHBITDEPTH - switch (cpi->common.bit_depth) { - case VPX_BITS_10: rdmult = ROUND_POWER_OF_TWO(rdmult, 4); break; - case VPX_BITS_12: rdmult = ROUND_POWER_OF_TWO(rdmult, 8); break; - default: break; - } -#endif // CONFIG_VP9_HIGHBITDEPTH - return rdmult > 0 ? rdmult : 1; -} - -static int modulate_rdmult(const VP9_COMP *cpi, int rdmult) { - int64_t rdmult_64 = rdmult; - if (cpi->oxcf.pass == 2 && (cpi->common.frame_type != KEY_FRAME)) { - const GF_GROUP *const gf_group = &cpi->twopass.gf_group; - const FRAME_UPDATE_TYPE frame_type = gf_group->update_type[gf_group->index]; - const int gfu_boost = cpi->multi_layer_arf - ? gf_group->gfu_boost[gf_group->index] - : cpi->rc.gfu_boost; - const int boost_index = VPXMIN(15, (gfu_boost / 100)); - - rdmult_64 = (rdmult_64 * rd_frame_type_factor[frame_type]) >> 7; - rdmult_64 += ((rdmult_64 * rd_boost_factor[boost_index]) >> 7); - } - return (int)rdmult_64; -} - -int vp9_compute_rd_mult(const VP9_COMP *cpi, int qindex) { - int rdmult = vp9_compute_rd_mult_based_on_qindex(cpi, qindex); - if (cpi->ext_ratectrl.ready && - (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_RDMULT) != 0 && - cpi->ext_ratectrl.ext_rdmult != VPX_DEFAULT_RDMULT) { - return cpi->ext_ratectrl.ext_rdmult; - } - return modulate_rdmult(cpi, rdmult); -} - -int vp9_get_adaptive_rdmult(const VP9_COMP *cpi, double beta) { - int rdmult = - vp9_compute_rd_mult_based_on_qindex(cpi, cpi->common.base_qindex); - rdmult = (int)((double)rdmult / beta); - rdmult = rdmult > 0 ? rdmult : 1; - return modulate_rdmult(cpi, rdmult); -} - -static int compute_rd_thresh_factor(int qindex, vpx_bit_depth_t bit_depth) { - double q; -#if CONFIG_VP9_HIGHBITDEPTH - switch (bit_depth) { - case VPX_BITS_8: q = vp9_dc_quant(qindex, 0, VPX_BITS_8) / 4.0; break; - case VPX_BITS_10: q = vp9_dc_quant(qindex, 0, VPX_BITS_10) / 16.0; break; - default: - assert(bit_depth == VPX_BITS_12); - q = vp9_dc_quant(qindex, 0, VPX_BITS_12) / 64.0; - break; - } -#else - (void)bit_depth; - q = vp9_dc_quant(qindex, 0, VPX_BITS_8) / 4.0; -#endif // CONFIG_VP9_HIGHBITDEPTH - // TODO(debargha): Adjust the function below. - return VPXMAX((int)(pow(q, RD_THRESH_POW) * 5.12), 8); -} - -void vp9_initialize_me_consts(VP9_COMP *cpi, MACROBLOCK *x, int qindex) { -#if CONFIG_VP9_HIGHBITDEPTH - switch (cpi->common.bit_depth) { - case VPX_BITS_8: - x->sadperbit16 = sad_per_bit16lut_8[qindex]; - x->sadperbit4 = sad_per_bit4lut_8[qindex]; - break; - case VPX_BITS_10: - x->sadperbit16 = sad_per_bit16lut_10[qindex]; - x->sadperbit4 = sad_per_bit4lut_10[qindex]; - break; - default: - assert(cpi->common.bit_depth == VPX_BITS_12); - x->sadperbit16 = sad_per_bit16lut_12[qindex]; - x->sadperbit4 = sad_per_bit4lut_12[qindex]; - break; - } -#else - (void)cpi; - x->sadperbit16 = sad_per_bit16lut_8[qindex]; - x->sadperbit4 = sad_per_bit4lut_8[qindex]; -#endif // CONFIG_VP9_HIGHBITDEPTH -} - -static void set_block_thresholds(const VP9_COMMON *cm, RD_OPT *rd) { - int i, bsize, segment_id; - - for (segment_id = 0; segment_id < MAX_SEGMENTS; ++segment_id) { - const int qindex = - clamp(vp9_get_qindex(&cm->seg, segment_id, cm->base_qindex) + - cm->y_dc_delta_q, - 0, MAXQ); - const int q = compute_rd_thresh_factor(qindex, cm->bit_depth); - - for (bsize = 0; bsize < BLOCK_SIZES; ++bsize) { - // Threshold here seems unnecessarily harsh but fine given actual - // range of values used for cpi->sf.thresh_mult[]. - const int t = q * rd_thresh_block_size_factor[bsize]; - const int thresh_max = INT_MAX / t; - - if (bsize >= BLOCK_8X8) { - for (i = 0; i < MAX_MODES; ++i) - rd->threshes[segment_id][bsize][i] = rd->thresh_mult[i] < thresh_max - ? rd->thresh_mult[i] * t / 4 - : INT_MAX; - } else { - for (i = 0; i < MAX_REFS; ++i) - rd->threshes[segment_id][bsize][i] = - rd->thresh_mult_sub8x8[i] < thresh_max - ? rd->thresh_mult_sub8x8[i] * t / 4 - : INT_MAX; - } - } - } -} - -void vp9_build_inter_mode_cost(VP9_COMP *cpi) { - const VP9_COMMON *const cm = &cpi->common; - int i; - for (i = 0; i < INTER_MODE_CONTEXTS; ++i) { - vp9_cost_tokens((int *)cpi->inter_mode_cost[i], cm->fc->inter_mode_probs[i], - vp9_inter_mode_tree); - } -} - -void vp9_initialize_rd_consts(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - MACROBLOCK *const x = &cpi->td.mb; - MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; - RD_OPT *const rd = &cpi->rd; - int i; - - vpx_clear_system_state(); - - rd->RDDIV = RDDIV_BITS; // In bits (to multiply D by 128). - rd->RDMULT = vp9_compute_rd_mult(cpi, cm->base_qindex + cm->y_dc_delta_q); - - set_error_per_bit(x, rd->RDMULT); - - x->select_tx_size = (cpi->sf.tx_size_search_method == USE_LARGESTALL && - cm->frame_type != KEY_FRAME) - ? 0 - : 1; - - set_block_thresholds(cm, rd); - set_partition_probs(cm, xd); - - if (cpi->oxcf.pass == 1) { - if (!frame_is_intra_only(cm)) - vp9_build_nmv_cost_table( - x->nmvjointcost, - cm->allow_high_precision_mv ? x->nmvcost_hp : x->nmvcost, - &cm->fc->nmvc, cm->allow_high_precision_mv); - } else { - if (!cpi->sf.use_nonrd_pick_mode || cm->frame_type == KEY_FRAME) - fill_token_costs(x->token_costs, cm->fc->coef_probs); - - if (cpi->sf.partition_search_type != VAR_BASED_PARTITION || - cm->frame_type == KEY_FRAME) { - for (i = 0; i < PARTITION_CONTEXTS; ++i) - vp9_cost_tokens(cpi->partition_cost[i], get_partition_probs(xd, i), - vp9_partition_tree); - } - - if (!cpi->sf.use_nonrd_pick_mode || (cm->current_video_frame & 0x07) == 1 || - cm->frame_type == KEY_FRAME) { - fill_mode_costs(cpi); - - if (!frame_is_intra_only(cm)) { - vp9_build_nmv_cost_table( - x->nmvjointcost, - cm->allow_high_precision_mv ? x->nmvcost_hp : x->nmvcost, - &cm->fc->nmvc, cm->allow_high_precision_mv); - vp9_build_inter_mode_cost(cpi); - } - } - } -} - -// NOTE: The tables below must be of the same size. - -// The functions described below are sampled at the four most significant -// bits of x^2 + 8 / 256. - -// Normalized rate: -// This table models the rate for a Laplacian source with given variance -// when quantized with a uniform quantizer with given stepsize. The -// closed form expression is: -// Rn(x) = H(sqrt(r)) + sqrt(r)*[1 + H(r)/(1 - r)], -// where r = exp(-sqrt(2) * x) and x = qpstep / sqrt(variance), -// and H(x) is the binary entropy function. -static const int rate_tab_q10[] = { - 65536, 6086, 5574, 5275, 5063, 4899, 4764, 4651, 4553, 4389, 4255, 4142, 4044, - 3958, 3881, 3811, 3748, 3635, 3538, 3453, 3376, 3307, 3244, 3186, 3133, 3037, - 2952, 2877, 2809, 2747, 2690, 2638, 2589, 2501, 2423, 2353, 2290, 2232, 2179, - 2130, 2084, 2001, 1928, 1862, 1802, 1748, 1698, 1651, 1608, 1530, 1460, 1398, - 1342, 1290, 1243, 1199, 1159, 1086, 1021, 963, 911, 864, 821, 781, 745, - 680, 623, 574, 530, 490, 455, 424, 395, 345, 304, 269, 239, 213, - 190, 171, 154, 126, 104, 87, 73, 61, 52, 44, 38, 28, 21, - 16, 12, 10, 8, 6, 5, 3, 2, 1, 1, 1, 0, 0, -}; - -// Normalized distortion: -// This table models the normalized distortion for a Laplacian source -// with given variance when quantized with a uniform quantizer -// with given stepsize. The closed form expression is: -// Dn(x) = 1 - 1/sqrt(2) * x / sinh(x/sqrt(2)) -// where x = qpstep / sqrt(variance). -// Note the actual distortion is Dn * variance. -static const int dist_tab_q10[] = { - 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5, 5, - 6, 7, 7, 8, 9, 11, 12, 13, 15, 16, 17, 18, 21, - 24, 26, 29, 31, 34, 36, 39, 44, 49, 54, 59, 64, 69, - 73, 78, 88, 97, 106, 115, 124, 133, 142, 151, 167, 184, 200, - 215, 231, 245, 260, 274, 301, 327, 351, 375, 397, 418, 439, 458, - 495, 528, 559, 587, 613, 637, 659, 680, 717, 749, 777, 801, 823, - 842, 859, 874, 899, 919, 936, 949, 960, 969, 977, 983, 994, 1001, - 1006, 1010, 1013, 1015, 1017, 1018, 1020, 1022, 1022, 1023, 1023, 1023, 1024, -}; -static const int xsq_iq_q10[] = { - 0, 4, 8, 12, 16, 20, 24, 28, 32, - 40, 48, 56, 64, 72, 80, 88, 96, 112, - 128, 144, 160, 176, 192, 208, 224, 256, 288, - 320, 352, 384, 416, 448, 480, 544, 608, 672, - 736, 800, 864, 928, 992, 1120, 1248, 1376, 1504, - 1632, 1760, 1888, 2016, 2272, 2528, 2784, 3040, 3296, - 3552, 3808, 4064, 4576, 5088, 5600, 6112, 6624, 7136, - 7648, 8160, 9184, 10208, 11232, 12256, 13280, 14304, 15328, - 16352, 18400, 20448, 22496, 24544, 26592, 28640, 30688, 32736, - 36832, 40928, 45024, 49120, 53216, 57312, 61408, 65504, 73696, - 81888, 90080, 98272, 106464, 114656, 122848, 131040, 147424, 163808, - 180192, 196576, 212960, 229344, 245728, -}; - -static void model_rd_norm(int xsq_q10, int *r_q10, int *d_q10) { - const int tmp = (xsq_q10 >> 2) + 8; - const int k = get_msb(tmp) - 3; - const int xq = (k << 3) + ((tmp >> k) & 0x7); - const int one_q10 = 1 << 10; - const int a_q10 = ((xsq_q10 - xsq_iq_q10[xq]) << 10) >> (2 + k); - const int b_q10 = one_q10 - a_q10; - *r_q10 = (rate_tab_q10[xq] * b_q10 + rate_tab_q10[xq + 1] * a_q10) >> 10; - *d_q10 = (dist_tab_q10[xq] * b_q10 + dist_tab_q10[xq + 1] * a_q10) >> 10; -} - -static const uint32_t MAX_XSQ_Q10 = 245727; - -void vp9_model_rd_from_var_lapndz(unsigned int var, unsigned int n_log2, - unsigned int qstep, int *rate, - int64_t *dist) { - // This function models the rate and distortion for a Laplacian - // source with given variance when quantized with a uniform quantizer - // with given stepsize. The closed form expressions are in: - // Hang and Chen, "Source Model for transform video coder and its - // application - Part I: Fundamental Theory", IEEE Trans. Circ. - // Sys. for Video Tech., April 1997. - if (var == 0) { - *rate = 0; - *dist = 0; - } else { - int d_q10, r_q10; - const uint64_t xsq_q10_64 = - (((uint64_t)qstep * qstep << (n_log2 + 10)) + (var >> 1)) / var; - const int xsq_q10 = (int)VPXMIN(xsq_q10_64, MAX_XSQ_Q10); - model_rd_norm(xsq_q10, &r_q10, &d_q10); - *rate = ROUND_POWER_OF_TWO(r_q10 << n_log2, 10 - VP9_PROB_COST_SHIFT); - *dist = (var * (int64_t)d_q10 + 512) >> 10; - } -} - -// Disable gcc 12.2 false positive warning. -// warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wstringop-overflow" -#endif -void vp9_get_entropy_contexts(BLOCK_SIZE bsize, TX_SIZE tx_size, - const struct macroblockd_plane *pd, - ENTROPY_CONTEXT t_above[16], - ENTROPY_CONTEXT t_left[16]) { - const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd); - const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize]; - const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize]; - const ENTROPY_CONTEXT *const above = pd->above_context; - const ENTROPY_CONTEXT *const left = pd->left_context; - - int i; - switch (tx_size) { - case TX_4X4: - memcpy(t_above, above, sizeof(ENTROPY_CONTEXT) * num_4x4_w); - memcpy(t_left, left, sizeof(ENTROPY_CONTEXT) * num_4x4_h); - break; - case TX_8X8: - for (i = 0; i < num_4x4_w; i += 2) - t_above[i] = !!*(const uint16_t *)&above[i]; - for (i = 0; i < num_4x4_h; i += 2) - t_left[i] = !!*(const uint16_t *)&left[i]; - break; - case TX_16X16: - for (i = 0; i < num_4x4_w; i += 4) - t_above[i] = !!*(const uint32_t *)&above[i]; - for (i = 0; i < num_4x4_h; i += 4) - t_left[i] = !!*(const uint32_t *)&left[i]; - break; - default: - assert(tx_size == TX_32X32); - for (i = 0; i < num_4x4_w; i += 8) - t_above[i] = !!*(const uint64_t *)&above[i]; - for (i = 0; i < num_4x4_h; i += 8) - t_left[i] = !!*(const uint64_t *)&left[i]; - break; - } -} -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif - -void vp9_mv_pred(VP9_COMP *cpi, MACROBLOCK *x, uint8_t *ref_y_buffer, - int ref_y_stride, int ref_frame, BLOCK_SIZE block_size) { - int i; - int zero_seen = 0; - int best_index = 0; - int best_sad = INT_MAX; - int this_sad = INT_MAX; - int max_mv = 0; - int near_same_nearest; - uint8_t *src_y_ptr = x->plane[0].src.buf; - uint8_t *ref_y_ptr; - const int num_mv_refs = - MAX_MV_REF_CANDIDATES + (block_size < x->max_partition_size); - - MV pred_mv[3]; - pred_mv[0] = x->mbmi_ext->ref_mvs[ref_frame][0].as_mv; - pred_mv[1] = x->mbmi_ext->ref_mvs[ref_frame][1].as_mv; - pred_mv[2] = x->pred_mv[ref_frame]; - assert(num_mv_refs <= (int)(sizeof(pred_mv) / sizeof(pred_mv[0]))); - - near_same_nearest = x->mbmi_ext->ref_mvs[ref_frame][0].as_int == - x->mbmi_ext->ref_mvs[ref_frame][1].as_int; - - // Get the sad for each candidate reference mv. - for (i = 0; i < num_mv_refs; ++i) { - const MV *this_mv = &pred_mv[i]; - int fp_row, fp_col; - if (this_mv->row == INT16_MAX || this_mv->col == INT16_MAX) continue; - if (i == 1 && near_same_nearest) continue; - fp_row = (this_mv->row + 3 + (this_mv->row >= 0)) >> 3; - fp_col = (this_mv->col + 3 + (this_mv->col >= 0)) >> 3; - max_mv = VPXMAX(max_mv, VPXMAX(abs(this_mv->row), abs(this_mv->col)) >> 3); - - if (fp_row == 0 && fp_col == 0 && zero_seen) continue; - zero_seen |= (fp_row == 0 && fp_col == 0); - - ref_y_ptr = &ref_y_buffer[ref_y_stride * fp_row + fp_col]; - // Find sad for current vector. - this_sad = cpi->fn_ptr[block_size].sdf(src_y_ptr, x->plane[0].src.stride, - ref_y_ptr, ref_y_stride); - // Note if it is the best so far. - if (this_sad < best_sad) { - best_sad = this_sad; - best_index = i; - } - } - - // Note the index of the mv that worked best in the reference list. - x->mv_best_ref_index[ref_frame] = best_index; - x->max_mv_context[ref_frame] = max_mv; - x->pred_mv_sad[ref_frame] = best_sad; -} - -void vp9_setup_pred_block(const MACROBLOCKD *xd, - struct buf_2d dst[MAX_MB_PLANE], - const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col, - const struct scale_factors *scale, - const struct scale_factors *scale_uv) { - int i; - - dst[0].buf = src->y_buffer; - dst[0].stride = src->y_stride; - dst[1].buf = src->u_buffer; - dst[2].buf = src->v_buffer; - dst[1].stride = dst[2].stride = src->uv_stride; - - for (i = 0; i < MAX_MB_PLANE; ++i) { - setup_pred_plane(dst + i, dst[i].buf, dst[i].stride, mi_row, mi_col, - i ? scale_uv : scale, xd->plane[i].subsampling_x, - xd->plane[i].subsampling_y); - } -} - -int vp9_raster_block_offset(BLOCK_SIZE plane_bsize, int raster_block, - int stride) { - const int bw = b_width_log2_lookup[plane_bsize]; - const int y = 4 * (raster_block >> bw); - const int x = 4 * (raster_block & ((1 << bw) - 1)); - return y * stride + x; -} - -int16_t *vp9_raster_block_offset_int16(BLOCK_SIZE plane_bsize, int raster_block, - int16_t *base) { - const int stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize]; - return base + vp9_raster_block_offset(plane_bsize, raster_block, stride); -} - -YV12_BUFFER_CONFIG *vp9_get_scaled_ref_frame(const VP9_COMP *cpi, - int ref_frame) { - const VP9_COMMON *const cm = &cpi->common; - const int scaled_idx = cpi->scaled_ref_idx[ref_frame - 1]; - const int ref_idx = get_ref_frame_buf_idx(cpi, ref_frame); - assert(ref_frame >= LAST_FRAME && ref_frame <= ALTREF_FRAME); - return (scaled_idx != ref_idx && scaled_idx != INVALID_IDX) - ? &cm->buffer_pool->frame_bufs[scaled_idx].buf - : NULL; -} - -int vp9_get_switchable_rate(const VP9_COMP *cpi, const MACROBLOCKD *const xd) { - const MODE_INFO *const mi = xd->mi[0]; - const int ctx = get_pred_context_switchable_interp(xd); - return SWITCHABLE_INTERP_RATE_FACTOR * - cpi->switchable_interp_costs[ctx][mi->interp_filter]; -} - -void vp9_set_rd_speed_thresholds(VP9_COMP *cpi) { - int i; - RD_OPT *const rd = &cpi->rd; - SPEED_FEATURES *const sf = &cpi->sf; - - // Set baseline threshold values. - for (i = 0; i < MAX_MODES; ++i) - rd->thresh_mult[i] = cpi->oxcf.mode == BEST ? -500 : 0; - - if (sf->adaptive_rd_thresh) { - rd->thresh_mult[THR_NEARESTMV] = 300; - rd->thresh_mult[THR_NEARESTG] = 300; - rd->thresh_mult[THR_NEARESTA] = 300; - } else { - rd->thresh_mult[THR_NEARESTMV] = 0; - rd->thresh_mult[THR_NEARESTG] = 0; - rd->thresh_mult[THR_NEARESTA] = 0; - } - - rd->thresh_mult[THR_DC] += 1000; - - rd->thresh_mult[THR_NEWMV] += 1000; - rd->thresh_mult[THR_NEWA] += 1000; - rd->thresh_mult[THR_NEWG] += 1000; - - rd->thresh_mult[THR_NEARMV] += 1000; - rd->thresh_mult[THR_NEARA] += 1000; - rd->thresh_mult[THR_COMP_NEARESTLA] += 1000; - rd->thresh_mult[THR_COMP_NEARESTGA] += 1000; - - rd->thresh_mult[THR_TM] += 1000; - - rd->thresh_mult[THR_COMP_NEARLA] += 1500; - rd->thresh_mult[THR_COMP_NEWLA] += 2000; - rd->thresh_mult[THR_NEARG] += 1000; - rd->thresh_mult[THR_COMP_NEARGA] += 1500; - rd->thresh_mult[THR_COMP_NEWGA] += 2000; - - rd->thresh_mult[THR_ZEROMV] += 2000; - rd->thresh_mult[THR_ZEROG] += 2000; - rd->thresh_mult[THR_ZEROA] += 2000; - rd->thresh_mult[THR_COMP_ZEROLA] += 2500; - rd->thresh_mult[THR_COMP_ZEROGA] += 2500; - - rd->thresh_mult[THR_H_PRED] += 2000; - rd->thresh_mult[THR_V_PRED] += 2000; - rd->thresh_mult[THR_D45_PRED] += 2500; - rd->thresh_mult[THR_D135_PRED] += 2500; - rd->thresh_mult[THR_D117_PRED] += 2500; - rd->thresh_mult[THR_D153_PRED] += 2500; - rd->thresh_mult[THR_D207_PRED] += 2500; - rd->thresh_mult[THR_D63_PRED] += 2500; -} - -void vp9_set_rd_speed_thresholds_sub8x8(VP9_COMP *cpi) { - static const int thresh_mult[2][MAX_REFS] = { - { 2500, 2500, 2500, 4500, 4500, 2500 }, - { 2000, 2000, 2000, 4000, 4000, 2000 } - }; - RD_OPT *const rd = &cpi->rd; - const int idx = cpi->oxcf.mode == BEST; - memcpy(rd->thresh_mult_sub8x8, thresh_mult[idx], sizeof(thresh_mult[idx])); -} - -void vp9_update_rd_thresh_fact(int (*factor_buf)[MAX_MODES], int rd_thresh, - int bsize, int best_mode_index) { - if (rd_thresh > 0) { - const int top_mode = bsize < BLOCK_8X8 ? MAX_REFS : MAX_MODES; - int mode; - for (mode = 0; mode < top_mode; ++mode) { - const BLOCK_SIZE min_size = VPXMAX(bsize - 1, BLOCK_4X4); - const BLOCK_SIZE max_size = VPXMIN(bsize + 2, BLOCK_64X64); - BLOCK_SIZE bs; - for (bs = min_size; bs <= max_size; ++bs) { - int *const fact = &factor_buf[bs][mode]; - if (mode == best_mode_index) { - *fact -= (*fact >> 4); - } else { - *fact = VPXMIN(*fact + RD_THRESH_INC, rd_thresh * RD_THRESH_MAX_FACT); - } - } - } - } -} - -int vp9_get_intra_cost_penalty(const VP9_COMP *const cpi, BLOCK_SIZE bsize, - int qindex, int qdelta) { - // Reduce the intra cost penalty for small blocks (<=16x16). - int reduction_fac = - (bsize <= BLOCK_16X16) ? ((bsize <= BLOCK_8X8) ? 4 : 2) : 0; - - if (cpi->noise_estimate.enabled && cpi->noise_estimate.level == kHigh) - // Don't reduce intra cost penalty if estimated noise level is high. - reduction_fac = 0; - - // Always use VPX_BITS_8 as input here because the penalty is applied - // to rate not distortion so we want a consistent penalty for all bit - // depths. If the actual bit depth were passed in here then the value - // retured by vp9_dc_quant() would scale with the bit depth and we would - // then need to apply inverse scaling to correct back to a bit depth - // independent rate penalty. - return (20 * vp9_dc_quant(qindex, qdelta, VPX_BITS_8)) >> reduction_fac; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_rd.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_rd.h deleted file mode 100644 index 6c61ae51..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_rd.h +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_RD_H_ -#define VPX_VP9_ENCODER_VP9_RD_H_ - -#include - -#include "vp9/common/vp9_blockd.h" - -#include "vp9/encoder/vp9_block.h" -#include "vp9/encoder/vp9_context_tree.h" -#include "vp9/encoder/vp9_cost.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define RDDIV_BITS 7 -#define RD_EPB_SHIFT 6 - -#define RDCOST(RM, DM, R, D) \ - ROUND_POWER_OF_TWO(((int64_t)(R)) * (RM), VP9_PROB_COST_SHIFT) + ((D) << (DM)) -#define RDCOST_NEG_R(RM, DM, R, D) \ - ((D) << (DM)) - ROUND_POWER_OF_TWO(((int64_t)(R)) * (RM), VP9_PROB_COST_SHIFT) -#define RDCOST_NEG_D(RM, DM, R, D) \ - ROUND_POWER_OF_TWO(((int64_t)(R)) * (RM), VP9_PROB_COST_SHIFT) - ((D) << (DM)) - -#define QIDX_SKIP_THRESH 115 - -#define MV_COST_WEIGHT 108 -#define MV_COST_WEIGHT_SUB 120 - -#define MAX_MODES 30 -#define MAX_REFS 6 - -#define RD_THRESH_INIT_FACT 32 -#define RD_THRESH_MAX_FACT 64 -#define RD_THRESH_INC 1 - -#define VP9_DIST_SCALE_LOG2 4 -#define VP9_DIST_SCALE (1 << VP9_DIST_SCALE_LOG2) - -// This enumerator type needs to be kept aligned with the mode order in -// const MODE_DEFINITION vp9_mode_order[MAX_MODES] used in the rd code. -typedef enum { - THR_NEARESTMV, - THR_NEARESTA, - THR_NEARESTG, - - THR_DC, - - THR_NEWMV, - THR_NEWA, - THR_NEWG, - - THR_NEARMV, - THR_NEARA, - THR_NEARG, - - THR_ZEROMV, - THR_ZEROG, - THR_ZEROA, - - THR_COMP_NEARESTLA, - THR_COMP_NEARESTGA, - - THR_TM, - - THR_COMP_NEARLA, - THR_COMP_NEWLA, - THR_COMP_NEARGA, - THR_COMP_NEWGA, - - THR_COMP_ZEROLA, - THR_COMP_ZEROGA, - - THR_H_PRED, - THR_V_PRED, - THR_D135_PRED, - THR_D207_PRED, - THR_D153_PRED, - THR_D63_PRED, - THR_D117_PRED, - THR_D45_PRED, -} THR_MODES; - -typedef enum { - THR_LAST, - THR_GOLD, - THR_ALTR, - THR_COMP_LA, - THR_COMP_GA, - THR_INTRA, -} THR_MODES_SUB8X8; - -typedef struct { - // RD multiplier control factors added for Vizier project. - double rd_mult_inter_qp_fac; - double rd_mult_arf_qp_fac; - double rd_mult_key_qp_fac; -} RD_CONTROL; - -typedef struct RD_OPT { - // Thresh_mult is used to set a threshold for the rd score. A higher value - // means that we will accept the best mode so far more often. This number - // is used in combination with the current block size, and thresh_freq_fact to - // pick a threshold. - int thresh_mult[MAX_MODES]; - int thresh_mult_sub8x8[MAX_REFS]; - - int threshes[MAX_SEGMENTS][BLOCK_SIZES][MAX_MODES]; - - int64_t prediction_type_threshes[MAX_REF_FRAMES][REFERENCE_MODES]; - - int64_t filter_threshes[MAX_REF_FRAMES][SWITCHABLE_FILTER_CONTEXTS]; - int64_t prediction_type_threshes_prev[MAX_REF_FRAMES][REFERENCE_MODES]; - - int64_t filter_threshes_prev[MAX_REF_FRAMES][SWITCHABLE_FILTER_CONTEXTS]; - int RDMULT; - int RDDIV; - double r0; -} RD_OPT; - -typedef struct RD_COST { - int rate; - int64_t dist; - int64_t rdcost; -} RD_COST; - -// Reset the rate distortion cost values to maximum (invalid) value. -void vp9_rd_cost_reset(RD_COST *rd_cost); -// Initialize the rate distortion cost values to zero. -void vp9_rd_cost_init(RD_COST *rd_cost); -// It supports negative rate and dist, which is different from RDCOST(). -int64_t vp9_calculate_rd_cost(int mult, int div, int rate, int64_t dist); -// Update the cost value based on its rate and distortion. -void vp9_rd_cost_update(int mult, int div, RD_COST *rd_cost); - -struct TileInfo; -struct TileDataEnc; -struct VP9_COMP; -struct macroblock; - -void vp9_init_rd_parameters(struct VP9_COMP *cpi); - -int vp9_compute_rd_mult_based_on_qindex(const struct VP9_COMP *cpi, int qindex); - -int vp9_compute_rd_mult(const struct VP9_COMP *cpi, int qindex); - -int vp9_get_adaptive_rdmult(const struct VP9_COMP *cpi, double beta); - -void vp9_initialize_rd_consts(struct VP9_COMP *cpi); - -void vp9_initialize_me_consts(struct VP9_COMP *cpi, MACROBLOCK *x, int qindex); - -void vp9_model_rd_from_var_lapndz(unsigned int var, unsigned int n_log2, - unsigned int qstep, int *rate, int64_t *dist); - -int vp9_get_switchable_rate(const struct VP9_COMP *cpi, - const MACROBLOCKD *const xd); - -int vp9_raster_block_offset(BLOCK_SIZE plane_bsize, int raster_block, - int stride); - -int16_t *vp9_raster_block_offset_int16(BLOCK_SIZE plane_bsize, int raster_block, - int16_t *base); - -YV12_BUFFER_CONFIG *vp9_get_scaled_ref_frame(const struct VP9_COMP *cpi, - int ref_frame); - -void vp9_init_me_luts(void); - -void vp9_get_entropy_contexts(BLOCK_SIZE bsize, TX_SIZE tx_size, - const struct macroblockd_plane *pd, - ENTROPY_CONTEXT t_above[16], - ENTROPY_CONTEXT t_left[16]); - -void vp9_set_rd_speed_thresholds(struct VP9_COMP *cpi); - -void vp9_set_rd_speed_thresholds_sub8x8(struct VP9_COMP *cpi); - -void vp9_update_rd_thresh_fact(int (*factor_buf)[MAX_MODES], int rd_thresh, - int bsize, int best_mode_index); - -static INLINE int rd_less_than_thresh(int64_t best_rd, int thresh, - const int *const thresh_fact) { - return best_rd < ((int64_t)thresh * (*thresh_fact) >> 5) || thresh == INT_MAX; -} - -static INLINE void set_error_per_bit(MACROBLOCK *x, int rdmult) { - x->errorperbit = rdmult >> RD_EPB_SHIFT; - x->errorperbit += (x->errorperbit == 0); -} - -void vp9_mv_pred(struct VP9_COMP *cpi, MACROBLOCK *x, uint8_t *ref_y_buffer, - int ref_y_stride, int ref_frame, BLOCK_SIZE block_size); - -void vp9_setup_pred_block(const MACROBLOCKD *xd, - struct buf_2d dst[MAX_MB_PLANE], - const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col, - const struct scale_factors *scale, - const struct scale_factors *scale_uv); - -int vp9_get_intra_cost_penalty(const struct VP9_COMP *const cpi, - BLOCK_SIZE bsize, int qindex, int qdelta); - -unsigned int vp9_get_sby_variance(struct VP9_COMP *cpi, - const struct buf_2d *ref, BLOCK_SIZE bs); -unsigned int vp9_get_sby_perpixel_variance(struct VP9_COMP *cpi, - const struct buf_2d *ref, - BLOCK_SIZE bs); -#if CONFIG_VP9_HIGHBITDEPTH -unsigned int vp9_high_get_sby_variance(struct VP9_COMP *cpi, - const struct buf_2d *ref, BLOCK_SIZE bs, - int bd); -unsigned int vp9_high_get_sby_perpixel_variance(struct VP9_COMP *cpi, - const struct buf_2d *ref, - BLOCK_SIZE bs, int bd); -#endif - -void vp9_build_inter_mode_cost(struct VP9_COMP *cpi); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_RD_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_rdopt.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_rdopt.c deleted file mode 100644 index 260aa0a5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_rdopt.c +++ /dev/null @@ -1,4933 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vp9_rtcd.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/system_state.h" - -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_entropy.h" -#include "vp9/common/vp9_entropymode.h" -#include "vp9/common/vp9_idct.h" -#include "vp9/common/vp9_mvref_common.h" -#include "vp9/common/vp9_pred_common.h" -#include "vp9/common/vp9_quant_common.h" -#include "vp9/common/vp9_reconinter.h" -#include "vp9/common/vp9_reconintra.h" -#include "vp9/common/vp9_scan.h" -#include "vp9/common/vp9_seg_common.h" - -#if !CONFIG_REALTIME_ONLY -#include "vp9/encoder/vp9_aq_variance.h" -#endif -#include "vp9/encoder/vp9_cost.h" -#include "vp9/encoder/vp9_encodemb.h" -#include "vp9/encoder/vp9_encodemv.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_mcomp.h" -#include "vp9/encoder/vp9_quantize.h" -#include "vp9/encoder/vp9_ratectrl.h" -#include "vp9/encoder/vp9_rd.h" -#include "vp9/encoder/vp9_rdopt.h" - -#define LAST_FRAME_MODE_MASK \ - ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | (1 << INTRA_FRAME)) -#define GOLDEN_FRAME_MODE_MASK \ - ((1 << LAST_FRAME) | (1 << ALTREF_FRAME) | (1 << INTRA_FRAME)) -#define ALT_REF_MODE_MASK \ - ((1 << LAST_FRAME) | (1 << GOLDEN_FRAME) | (1 << INTRA_FRAME)) - -#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | 0x01) - -#define MIN_EARLY_TERM_INDEX 3 -#define NEW_MV_DISCOUNT_FACTOR 8 - -typedef struct { - PREDICTION_MODE mode; - MV_REFERENCE_FRAME ref_frame[2]; -} MODE_DEFINITION; - -typedef struct { - MV_REFERENCE_FRAME ref_frame[2]; -} REF_DEFINITION; - -struct rdcost_block_args { - const VP9_COMP *cpi; - MACROBLOCK *x; - ENTROPY_CONTEXT t_above[16]; - ENTROPY_CONTEXT t_left[16]; - int this_rate; - int64_t this_dist; - int64_t this_sse; - int64_t this_rd; - int64_t best_rd; - int exit_early; - int use_fast_coef_costing; - const ScanOrder *so; - uint8_t skippable; - struct buf_2d *this_recon; -}; - -#define LAST_NEW_MV_INDEX 6 - -#if !CONFIG_REALTIME_ONLY -static const MODE_DEFINITION vp9_mode_order[MAX_MODES] = { - { NEARESTMV, { LAST_FRAME, NO_REF_FRAME } }, - { NEARESTMV, { ALTREF_FRAME, NO_REF_FRAME } }, - { NEARESTMV, { GOLDEN_FRAME, NO_REF_FRAME } }, - - { DC_PRED, { INTRA_FRAME, NO_REF_FRAME } }, - - { NEWMV, { LAST_FRAME, NO_REF_FRAME } }, - { NEWMV, { ALTREF_FRAME, NO_REF_FRAME } }, - { NEWMV, { GOLDEN_FRAME, NO_REF_FRAME } }, - - { NEARMV, { LAST_FRAME, NO_REF_FRAME } }, - { NEARMV, { ALTREF_FRAME, NO_REF_FRAME } }, - { NEARMV, { GOLDEN_FRAME, NO_REF_FRAME } }, - - { ZEROMV, { LAST_FRAME, NO_REF_FRAME } }, - { ZEROMV, { GOLDEN_FRAME, NO_REF_FRAME } }, - { ZEROMV, { ALTREF_FRAME, NO_REF_FRAME } }, - - { NEARESTMV, { LAST_FRAME, ALTREF_FRAME } }, - { NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } }, - - { TM_PRED, { INTRA_FRAME, NO_REF_FRAME } }, - - { NEARMV, { LAST_FRAME, ALTREF_FRAME } }, - { NEWMV, { LAST_FRAME, ALTREF_FRAME } }, - { NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } }, - { NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } }, - - { ZEROMV, { LAST_FRAME, ALTREF_FRAME } }, - { ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } }, - - { H_PRED, { INTRA_FRAME, NO_REF_FRAME } }, - { V_PRED, { INTRA_FRAME, NO_REF_FRAME } }, - { D135_PRED, { INTRA_FRAME, NO_REF_FRAME } }, - { D207_PRED, { INTRA_FRAME, NO_REF_FRAME } }, - { D153_PRED, { INTRA_FRAME, NO_REF_FRAME } }, - { D63_PRED, { INTRA_FRAME, NO_REF_FRAME } }, - { D117_PRED, { INTRA_FRAME, NO_REF_FRAME } }, - { D45_PRED, { INTRA_FRAME, NO_REF_FRAME } }, -}; - -static const REF_DEFINITION vp9_ref_order[MAX_REFS] = { - { { LAST_FRAME, NO_REF_FRAME } }, { { GOLDEN_FRAME, NO_REF_FRAME } }, - { { ALTREF_FRAME, NO_REF_FRAME } }, { { LAST_FRAME, ALTREF_FRAME } }, - { { GOLDEN_FRAME, ALTREF_FRAME } }, { { INTRA_FRAME, NO_REF_FRAME } }, -}; -#endif // !CONFIG_REALTIME_ONLY - -static void swap_block_ptr(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx, int m, int n, - int min_plane, int max_plane) { - int i; - - for (i = min_plane; i < max_plane; ++i) { - struct macroblock_plane *const p = &x->plane[i]; - struct macroblockd_plane *const pd = &x->e_mbd.plane[i]; - - p->coeff = ctx->coeff_pbuf[i][m]; - p->qcoeff = ctx->qcoeff_pbuf[i][m]; - pd->dqcoeff = ctx->dqcoeff_pbuf[i][m]; - p->eobs = ctx->eobs_pbuf[i][m]; - - ctx->coeff_pbuf[i][m] = ctx->coeff_pbuf[i][n]; - ctx->qcoeff_pbuf[i][m] = ctx->qcoeff_pbuf[i][n]; - ctx->dqcoeff_pbuf[i][m] = ctx->dqcoeff_pbuf[i][n]; - ctx->eobs_pbuf[i][m] = ctx->eobs_pbuf[i][n]; - - ctx->coeff_pbuf[i][n] = p->coeff; - ctx->qcoeff_pbuf[i][n] = p->qcoeff; - ctx->dqcoeff_pbuf[i][n] = pd->dqcoeff; - ctx->eobs_pbuf[i][n] = p->eobs; - } -} - -#if !CONFIG_REALTIME_ONLY -// Planewise build inter prediction and compute rdcost with early termination -// option -static int build_inter_pred_model_rd_earlyterm( - VP9_COMP *cpi, int mi_row, int mi_col, BLOCK_SIZE bsize, MACROBLOCK *x, - MACROBLOCKD *xd, int *out_rate_sum, int64_t *out_dist_sum, - int *skip_txfm_sb, int64_t *skip_sse_sb, int do_earlyterm, - int64_t best_rd) { - // Note our transform coeffs are 8 times an orthogonal transform. - // Hence quantizer step is also 8 times. To get effective quantizer - // we need to divide by 8 before sending to modeling function. - int i; - int64_t rate_sum = 0; - int64_t dist_sum = 0; - const int ref = xd->mi[0]->ref_frame[0]; - unsigned int sse; - unsigned int var = 0; - int64_t total_sse = 0; - int skip_flag = 1; - const int shift = 6; - const int dequant_shift = -#if CONFIG_VP9_HIGHBITDEPTH - (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd - 5 : -#endif // CONFIG_VP9_HIGHBITDEPTH - 3; - - x->pred_sse[ref] = 0; - - // Build prediction signal, compute stats and RD cost on per-plane basis - for (i = 0; i < MAX_MB_PLANE; ++i) { - struct macroblock_plane *const p = &x->plane[i]; - struct macroblockd_plane *const pd = &xd->plane[i]; - const BLOCK_SIZE bs = get_plane_block_size(bsize, pd); - const TX_SIZE max_tx_size = max_txsize_lookup[bs]; - const BLOCK_SIZE unit_size = txsize_to_bsize[max_tx_size]; - const int64_t dc_thr = p->quant_thred[0] >> shift; - const int64_t ac_thr = p->quant_thred[1] >> shift; - unsigned int sum_sse = 0; - // The low thresholds are used to measure if the prediction errors are - // low enough so that we can skip the mode search. - const int64_t low_dc_thr = VPXMIN(50, dc_thr >> 2); - const int64_t low_ac_thr = VPXMIN(80, ac_thr >> 2); - int bw = 1 << (b_width_log2_lookup[bs] - b_width_log2_lookup[unit_size]); - int bh = 1 << (b_height_log2_lookup[bs] - b_width_log2_lookup[unit_size]); - int idx, idy; - int lw = b_width_log2_lookup[unit_size] + 2; - int lh = b_height_log2_lookup[unit_size] + 2; - unsigned int qstep; - unsigned int nlog2; - int64_t dist = 0; - - // Build inter predictor - vp9_build_inter_predictors_sbp(xd, mi_row, mi_col, bsize, i); - - // Compute useful stats - for (idy = 0; idy < bh; ++idy) { - for (idx = 0; idx < bw; ++idx) { - uint8_t *src = p->src.buf + (idy * p->src.stride << lh) + (idx << lw); - uint8_t *dst = pd->dst.buf + (idy * pd->dst.stride << lh) + (idx << lh); - int block_idx = (idy << 1) + idx; - int low_err_skip = 0; - - var = cpi->fn_ptr[unit_size].vf(src, p->src.stride, dst, pd->dst.stride, - &sse); - x->bsse[(i << 2) + block_idx] = sse; - sum_sse += sse; - - x->skip_txfm[(i << 2) + block_idx] = SKIP_TXFM_NONE; - if (!x->select_tx_size) { - // Check if all ac coefficients can be quantized to zero. - if (var < ac_thr || var == 0) { - x->skip_txfm[(i << 2) + block_idx] = SKIP_TXFM_AC_ONLY; - - // Check if dc coefficient can be quantized to zero. - if (sse - var < dc_thr || sse == var) { - x->skip_txfm[(i << 2) + block_idx] = SKIP_TXFM_AC_DC; - - if (!sse || (var < low_ac_thr && sse - var < low_dc_thr)) - low_err_skip = 1; - } - } - } - - if (skip_flag && !low_err_skip) skip_flag = 0; - - if (i == 0) x->pred_sse[ref] += sse; - } - } - - total_sse += sum_sse; - qstep = pd->dequant[1] >> dequant_shift; - nlog2 = num_pels_log2_lookup[bs]; - - // Fast approximate the modelling function. - if (cpi->sf.simple_model_rd_from_var) { - int64_t rate; - if (qstep < 120) - rate = ((int64_t)sum_sse * (280 - qstep)) >> (16 - VP9_PROB_COST_SHIFT); - else - rate = 0; - dist = ((int64_t)sum_sse * qstep) >> 8; - rate_sum += rate; - } else { - int rate; - vp9_model_rd_from_var_lapndz(sum_sse, nlog2, qstep, &rate, &dist); - rate_sum += rate; - } - dist_sum += dist; - if (do_earlyterm) { - if (RDCOST(x->rdmult, x->rddiv, rate_sum, - dist_sum << VP9_DIST_SCALE_LOG2) >= best_rd) - return 1; - } - } - *skip_txfm_sb = skip_flag; - *skip_sse_sb = total_sse << VP9_DIST_SCALE_LOG2; - *out_rate_sum = (int)rate_sum; - *out_dist_sum = dist_sum << VP9_DIST_SCALE_LOG2; - - return 0; -} -#endif // !CONFIG_REALTIME_ONLY - -#if CONFIG_VP9_HIGHBITDEPTH -int64_t vp9_highbd_block_error_c(const tran_low_t *coeff, - const tran_low_t *dqcoeff, intptr_t block_size, - int64_t *ssz, int bd) { - int i; - int64_t error = 0, sqcoeff = 0; - int shift = 2 * (bd - 8); - int rounding = shift > 0 ? 1 << (shift - 1) : 0; - - for (i = 0; i < block_size; i++) { - const int64_t diff = coeff[i] - dqcoeff[i]; - error += diff * diff; - sqcoeff += (int64_t)coeff[i] * (int64_t)coeff[i]; - } - assert(error >= 0 && sqcoeff >= 0); - error = (error + rounding) >> shift; - sqcoeff = (sqcoeff + rounding) >> shift; - - *ssz = sqcoeff; - return error; -} - -static int64_t vp9_highbd_block_error_dispatch(const tran_low_t *coeff, - const tran_low_t *dqcoeff, - intptr_t block_size, - int64_t *ssz, int bd) { - if (bd == 8) { - return vp9_block_error(coeff, dqcoeff, block_size, ssz); - } else { - return vp9_highbd_block_error(coeff, dqcoeff, block_size, ssz, bd); - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -int64_t vp9_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, - intptr_t block_size, int64_t *ssz) { - int i; - int64_t error = 0, sqcoeff = 0; - - for (i = 0; i < block_size; i++) { - const int diff = coeff[i] - dqcoeff[i]; - error += diff * diff; - sqcoeff += coeff[i] * coeff[i]; - } - - *ssz = sqcoeff; - return error; -} - -int64_t vp9_block_error_fp_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, - int block_size) { - int i; - int64_t error = 0; - - for (i = 0; i < block_size; i++) { - const int diff = coeff[i] - dqcoeff[i]; - error += diff * diff; - } - - return error; -} - -/* The trailing '0' is a terminator which is used inside cost_coeffs() to - * decide whether to include cost of a trailing EOB node or not (i.e. we - * can skip this if the last coefficient in this transform block, e.g. the - * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block, - * were non-zero). */ -static const int16_t band_counts[TX_SIZES][8] = { - { 1, 2, 3, 4, 3, 16 - 13, 0 }, - { 1, 2, 3, 4, 11, 64 - 21, 0 }, - { 1, 2, 3, 4, 11, 256 - 21, 0 }, - { 1, 2, 3, 4, 11, 1024 - 21, 0 }, -}; -static int cost_coeffs(MACROBLOCK *x, int plane, int block, TX_SIZE tx_size, - int pt, const int16_t *scan, const int16_t *nb, - int use_fast_coef_costing) { - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *mi = xd->mi[0]; - const struct macroblock_plane *p = &x->plane[plane]; - const PLANE_TYPE type = get_plane_type(plane); - const int16_t *band_count = &band_counts[tx_size][1]; - const int eob = p->eobs[block]; - const tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block); - unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] = - x->token_costs[tx_size][type][is_inter_block(mi)]; - uint8_t token_cache[32 * 32]; - int cost; -#if CONFIG_VP9_HIGHBITDEPTH - const uint16_t *cat6_high_cost = vp9_get_high_cost_table(xd->bd); -#else - const uint16_t *cat6_high_cost = vp9_get_high_cost_table(8); -#endif - - // Check for consistency of tx_size with mode info - assert(type == PLANE_TYPE_Y - ? mi->tx_size == tx_size - : get_uv_tx_size(mi, &xd->plane[plane]) == tx_size); - - if (eob == 0) { - // single eob token - cost = token_costs[0][0][pt][EOB_TOKEN]; - } else { - if (use_fast_coef_costing) { - int band_left = *band_count++; - int c; - - // dc token - int v = qcoeff[0]; - int16_t prev_t; - cost = vp9_get_token_cost(v, &prev_t, cat6_high_cost); - cost += (*token_costs)[0][pt][prev_t]; - - token_cache[0] = vp9_pt_energy_class[prev_t]; - ++token_costs; - - // ac tokens - for (c = 1; c < eob; c++) { - const int rc = scan[c]; - int16_t t; - - v = qcoeff[rc]; - cost += vp9_get_token_cost(v, &t, cat6_high_cost); - cost += (*token_costs)[!prev_t][!prev_t][t]; - prev_t = t; - if (!--band_left) { - band_left = *band_count++; - ++token_costs; - } - } - - // eob token - if (band_left) cost += (*token_costs)[0][!prev_t][EOB_TOKEN]; - - } else { // !use_fast_coef_costing - int band_left = *band_count++; - int c; - - // dc token - int v = qcoeff[0]; - int16_t tok; - unsigned int(*tok_cost_ptr)[COEFF_CONTEXTS][ENTROPY_TOKENS]; - cost = vp9_get_token_cost(v, &tok, cat6_high_cost); - cost += (*token_costs)[0][pt][tok]; - - token_cache[0] = vp9_pt_energy_class[tok]; - ++token_costs; - - tok_cost_ptr = &((*token_costs)[!tok]); - - // ac tokens - for (c = 1; c < eob; c++) { - const int rc = scan[c]; - - v = qcoeff[rc]; - cost += vp9_get_token_cost(v, &tok, cat6_high_cost); - pt = get_coef_context(nb, token_cache, c); - cost += (*tok_cost_ptr)[pt][tok]; - token_cache[rc] = vp9_pt_energy_class[tok]; - if (!--band_left) { - band_left = *band_count++; - ++token_costs; - } - tok_cost_ptr = &((*token_costs)[!tok]); - } - - // eob token - if (band_left) { - pt = get_coef_context(nb, token_cache, c); - cost += (*token_costs)[0][pt][EOB_TOKEN]; - } - } - } - - return cost; -} - -// Copy all visible 4x4s in the transform block. -static void copy_block_visible(const MACROBLOCKD *xd, - const struct macroblockd_plane *const pd, - const uint8_t *src, const int src_stride, - uint8_t *dst, const int dst_stride, int blk_row, - int blk_col, const BLOCK_SIZE plane_bsize, - const BLOCK_SIZE tx_bsize) { - const int plane_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize]; - const int plane_4x4_h = num_4x4_blocks_high_lookup[plane_bsize]; - const int tx_4x4_w = num_4x4_blocks_wide_lookup[tx_bsize]; - const int tx_4x4_h = num_4x4_blocks_high_lookup[tx_bsize]; - int b4x4s_to_right_edge = num_4x4_to_edge(plane_4x4_w, xd->mb_to_right_edge, - pd->subsampling_x, blk_col); - int b4x4s_to_bottom_edge = num_4x4_to_edge(plane_4x4_h, xd->mb_to_bottom_edge, - pd->subsampling_y, blk_row); - const int is_highbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH; - if (tx_bsize == BLOCK_4X4 || - (b4x4s_to_right_edge >= tx_4x4_w && b4x4s_to_bottom_edge >= tx_4x4_h)) { - const int w = tx_4x4_w << 2; - const int h = tx_4x4_h << 2; -#if CONFIG_VP9_HIGHBITDEPTH - if (is_highbd) { - vpx_highbd_convolve_copy(CONVERT_TO_SHORTPTR(src), src_stride, - CONVERT_TO_SHORTPTR(dst), dst_stride, NULL, 0, 0, - 0, 0, w, h, xd->bd); - } else { -#endif - vpx_convolve_copy(src, src_stride, dst, dst_stride, NULL, 0, 0, 0, 0, w, - h); -#if CONFIG_VP9_HIGHBITDEPTH - } -#endif - } else { - int r, c; - int max_r = VPXMIN(b4x4s_to_bottom_edge, tx_4x4_h); - int max_c = VPXMIN(b4x4s_to_right_edge, tx_4x4_w); - // if we are in the unrestricted motion border. - for (r = 0; r < max_r; ++r) { - // Skip visiting the sub blocks that are wholly within the UMV. - for (c = 0; c < max_c; ++c) { - const uint8_t *src_ptr = src + r * src_stride * 4 + c * 4; - uint8_t *dst_ptr = dst + r * dst_stride * 4 + c * 4; -#if CONFIG_VP9_HIGHBITDEPTH - if (is_highbd) { - vpx_highbd_convolve_copy(CONVERT_TO_SHORTPTR(src_ptr), src_stride, - CONVERT_TO_SHORTPTR(dst_ptr), dst_stride, - NULL, 0, 0, 0, 0, 4, 4, xd->bd); - } else { -#endif - vpx_convolve_copy(src_ptr, src_stride, dst_ptr, dst_stride, NULL, 0, - 0, 0, 0, 4, 4); -#if CONFIG_VP9_HIGHBITDEPTH - } -#endif - } - } - } - (void)is_highbd; -} - -// Compute the pixel domain sum square error on all visible 4x4s in the -// transform block. -static unsigned pixel_sse(const VP9_COMP *const cpi, const MACROBLOCKD *xd, - const struct macroblockd_plane *const pd, - const uint8_t *src, const int src_stride, - const uint8_t *dst, const int dst_stride, int blk_row, - int blk_col, const BLOCK_SIZE plane_bsize, - const BLOCK_SIZE tx_bsize) { - unsigned int sse = 0; - const int plane_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize]; - const int plane_4x4_h = num_4x4_blocks_high_lookup[plane_bsize]; - const int tx_4x4_w = num_4x4_blocks_wide_lookup[tx_bsize]; - const int tx_4x4_h = num_4x4_blocks_high_lookup[tx_bsize]; - int b4x4s_to_right_edge = num_4x4_to_edge(plane_4x4_w, xd->mb_to_right_edge, - pd->subsampling_x, blk_col); - int b4x4s_to_bottom_edge = num_4x4_to_edge(plane_4x4_h, xd->mb_to_bottom_edge, - pd->subsampling_y, blk_row); - if (tx_bsize == BLOCK_4X4 || - (b4x4s_to_right_edge >= tx_4x4_w && b4x4s_to_bottom_edge >= tx_4x4_h)) { - cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &sse); - } else { - const vpx_variance_fn_t vf_4x4 = cpi->fn_ptr[BLOCK_4X4].vf; - int r, c; - unsigned this_sse = 0; - int max_r = VPXMIN(b4x4s_to_bottom_edge, tx_4x4_h); - int max_c = VPXMIN(b4x4s_to_right_edge, tx_4x4_w); - sse = 0; - // if we are in the unrestricted motion border. - for (r = 0; r < max_r; ++r) { - // Skip visiting the sub blocks that are wholly within the UMV. - for (c = 0; c < max_c; ++c) { - vf_4x4(src + r * src_stride * 4 + c * 4, src_stride, - dst + r * dst_stride * 4 + c * 4, dst_stride, &this_sse); - sse += this_sse; - } - } - } - return sse; -} - -static void dist_block(const VP9_COMP *cpi, MACROBLOCK *x, int plane, - BLOCK_SIZE plane_bsize, int block, int blk_row, - int blk_col, TX_SIZE tx_size, int64_t *out_dist, - int64_t *out_sse, struct buf_2d *out_recon, - int sse_calc_done) { - MACROBLOCKD *const xd = &x->e_mbd; - const struct macroblock_plane *const p = &x->plane[plane]; - const struct macroblockd_plane *const pd = &xd->plane[plane]; - const int eob = p->eobs[block]; - - if (!out_recon && x->block_tx_domain && eob) { - const int ss_txfrm_size = tx_size << 1; - int64_t this_sse; - const int shift = tx_size == TX_32X32 ? 0 : 2; - const tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block); - const tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); -#if CONFIG_VP9_HIGHBITDEPTH - const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8; - *out_dist = vp9_highbd_block_error_dispatch( - coeff, dqcoeff, 16 << ss_txfrm_size, &this_sse, bd) >> - shift; -#else - *out_dist = - vp9_block_error(coeff, dqcoeff, 16 << ss_txfrm_size, &this_sse) >> - shift; -#endif // CONFIG_VP9_HIGHBITDEPTH - *out_sse = this_sse >> shift; - - if (x->skip_encode && !is_inter_block(xd->mi[0])) { - // TODO(jingning): tune the model to better capture the distortion. - const int64_t mean_quant_error = - (pd->dequant[1] * pd->dequant[1] * (1 << ss_txfrm_size)) >> -#if CONFIG_VP9_HIGHBITDEPTH - (shift + 2 + (bd - 8) * 2); -#else - (shift + 2); -#endif // CONFIG_VP9_HIGHBITDEPTH - *out_dist += (mean_quant_error >> 4); - *out_sse += mean_quant_error; - } - } else { - const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size]; - const int bs = 4 * num_4x4_blocks_wide_lookup[tx_bsize]; - const int src_stride = p->src.stride; - const int dst_stride = pd->dst.stride; - const int src_idx = 4 * (blk_row * src_stride + blk_col); - const int dst_idx = 4 * (blk_row * dst_stride + blk_col); - const uint8_t *src = &p->src.buf[src_idx]; - const uint8_t *dst = &pd->dst.buf[dst_idx]; - uint8_t *out_recon_ptr = 0; - - const tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); - unsigned int tmp; - - if (sse_calc_done) { - tmp = (unsigned int)(*out_sse); - } else { - tmp = pixel_sse(cpi, xd, pd, src, src_stride, dst, dst_stride, blk_row, - blk_col, plane_bsize, tx_bsize); - } - *out_sse = (int64_t)tmp * 16; - if (out_recon) { - const int out_recon_idx = 4 * (blk_row * out_recon->stride + blk_col); - out_recon_ptr = &out_recon->buf[out_recon_idx]; - copy_block_visible(xd, pd, dst, dst_stride, out_recon_ptr, - out_recon->stride, blk_row, blk_col, plane_bsize, - tx_bsize); - } - - if (eob) { -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, recon16[1024]); - uint8_t *recon = (uint8_t *)recon16; -#else - DECLARE_ALIGNED(16, uint8_t, recon[1024]); -#endif // CONFIG_VP9_HIGHBITDEPTH - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - vpx_highbd_convolve_copy(CONVERT_TO_SHORTPTR(dst), dst_stride, recon16, - 32, NULL, 0, 0, 0, 0, bs, bs, xd->bd); - if (xd->lossless) { - vp9_highbd_iwht4x4_add(dqcoeff, recon16, 32, eob, xd->bd); - } else { - switch (tx_size) { - case TX_4X4: - vp9_highbd_idct4x4_add(dqcoeff, recon16, 32, eob, xd->bd); - break; - case TX_8X8: - vp9_highbd_idct8x8_add(dqcoeff, recon16, 32, eob, xd->bd); - break; - case TX_16X16: - vp9_highbd_idct16x16_add(dqcoeff, recon16, 32, eob, xd->bd); - break; - default: - assert(tx_size == TX_32X32); - vp9_highbd_idct32x32_add(dqcoeff, recon16, 32, eob, xd->bd); - break; - } - } - recon = CONVERT_TO_BYTEPTR(recon16); - } else { -#endif // CONFIG_VP9_HIGHBITDEPTH - vpx_convolve_copy(dst, dst_stride, recon, 32, NULL, 0, 0, 0, 0, bs, bs); - switch (tx_size) { - case TX_32X32: vp9_idct32x32_add(dqcoeff, recon, 32, eob); break; - case TX_16X16: vp9_idct16x16_add(dqcoeff, recon, 32, eob); break; - case TX_8X8: vp9_idct8x8_add(dqcoeff, recon, 32, eob); break; - default: - assert(tx_size == TX_4X4); - // this is like vp9_short_idct4x4 but has a special case around - // eob<=1, which is significant (not just an optimization) for - // the lossless case. - x->inv_txfm_add(dqcoeff, recon, 32, eob); - break; - } -#if CONFIG_VP9_HIGHBITDEPTH - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - tmp = pixel_sse(cpi, xd, pd, src, src_stride, recon, 32, blk_row, blk_col, - plane_bsize, tx_bsize); - if (out_recon) { - copy_block_visible(xd, pd, recon, 32, out_recon_ptr, out_recon->stride, - blk_row, blk_col, plane_bsize, tx_bsize); - } - } - - *out_dist = (int64_t)tmp * 16; - } -} - -static int rate_block(int plane, int block, TX_SIZE tx_size, int coeff_ctx, - struct rdcost_block_args *args) { - return cost_coeffs(args->x, plane, block, tx_size, coeff_ctx, args->so->scan, - args->so->neighbors, args->use_fast_coef_costing); -} - -static void block_rd_txfm(int plane, int block, int blk_row, int blk_col, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) { - struct rdcost_block_args *args = arg; - MACROBLOCK *const x = args->x; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - int64_t rd1, rd2, rd; - int rate; - int64_t dist = INT64_MAX; - int64_t sse = INT64_MAX; - const int coeff_ctx = - combine_entropy_contexts(args->t_left[blk_row], args->t_above[blk_col]); - struct buf_2d *recon = args->this_recon; - const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size]; - const struct macroblockd_plane *const pd = &xd->plane[plane]; - const int dst_stride = pd->dst.stride; - const uint8_t *dst = &pd->dst.buf[4 * (blk_row * dst_stride + blk_col)]; - const int enable_trellis_opt = args->cpi->sf.trellis_opt_tx_rd.method; - const double trellis_opt_thresh = args->cpi->sf.trellis_opt_tx_rd.thresh; - int sse_calc_done = 0; -#if CONFIG_MISMATCH_DEBUG - struct encode_b_args encode_b_arg = { - x, enable_trellis_opt, trellis_opt_thresh, &sse_calc_done, - &sse, args->t_above, args->t_left, &mi->skip, - 0, // mi_row - 0, // mi_col - 0 // output_enabled - }; -#else - struct encode_b_args encode_b_arg = { - x, enable_trellis_opt, trellis_opt_thresh, &sse_calc_done, - &sse, args->t_above, args->t_left, &mi->skip - }; -#endif - - if (args->exit_early) return; - - if (!is_inter_block(mi)) { - vp9_encode_block_intra(plane, block, blk_row, blk_col, plane_bsize, tx_size, - &encode_b_arg); - if (recon) { - uint8_t *rec_ptr = &recon->buf[4 * (blk_row * recon->stride + blk_col)]; - copy_block_visible(xd, pd, dst, dst_stride, rec_ptr, recon->stride, - blk_row, blk_col, plane_bsize, tx_bsize); - } - if (x->block_tx_domain) { - dist_block(args->cpi, x, plane, plane_bsize, block, blk_row, blk_col, - tx_size, &dist, &sse, /*out_recon=*/NULL, sse_calc_done); - } else { - const struct macroblock_plane *const p = &x->plane[plane]; - const int src_stride = p->src.stride; - const uint8_t *src = &p->src.buf[4 * (blk_row * src_stride + blk_col)]; - unsigned int tmp; - if (!sse_calc_done) { - const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize]; - const int16_t *diff = - &p->src_diff[4 * (blk_row * diff_stride + blk_col)]; - int visible_width, visible_height; - sse = sum_squares_visible(xd, pd, diff, diff_stride, blk_row, blk_col, - plane_bsize, tx_bsize, &visible_width, - &visible_height); - } -#if CONFIG_VP9_HIGHBITDEPTH - if ((xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) && (xd->bd > 8)) - sse = ROUND64_POWER_OF_TWO(sse, (xd->bd - 8) * 2); -#endif // CONFIG_VP9_HIGHBITDEPTH - sse = sse * 16; - tmp = pixel_sse(args->cpi, xd, pd, src, src_stride, dst, dst_stride, - blk_row, blk_col, plane_bsize, tx_bsize); - dist = (int64_t)tmp * 16; - } - } else { - int skip_txfm_flag = SKIP_TXFM_NONE; - if (max_txsize_lookup[plane_bsize] == tx_size) - skip_txfm_flag = x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))]; - - // This reduces the risk of bad perceptual quality due to bad prediction. - // We always force the encoder to perform transform and quantization. - if (!args->cpi->sf.allow_skip_txfm_ac_dc && - skip_txfm_flag == SKIP_TXFM_AC_DC) { - skip_txfm_flag = SKIP_TXFM_NONE; - } - - if (skip_txfm_flag == SKIP_TXFM_NONE || - (recon && skip_txfm_flag == SKIP_TXFM_AC_ONLY)) { - const struct macroblock_plane *const p = &x->plane[plane]; - const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize]; - const int16_t *const diff = - &p->src_diff[4 * (blk_row * diff_stride + blk_col)]; - const int use_trellis_opt = - do_trellis_opt(pd, diff, diff_stride, blk_row, blk_col, plane_bsize, - tx_size, &encode_b_arg); - // full forward transform and quantization - vp9_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize, tx_size); - if (use_trellis_opt) vp9_optimize_b(x, plane, block, tx_size, coeff_ctx); - dist_block(args->cpi, x, plane, plane_bsize, block, blk_row, blk_col, - tx_size, &dist, &sse, recon, sse_calc_done); - } else if (skip_txfm_flag == SKIP_TXFM_AC_ONLY) { - // compute DC coefficient - tran_low_t *const coeff = BLOCK_OFFSET(x->plane[plane].coeff, block); - tran_low_t *const dqcoeff = BLOCK_OFFSET(xd->plane[plane].dqcoeff, block); - vp9_xform_quant_dc(x, plane, block, blk_row, blk_col, plane_bsize, - tx_size); - sse = x->bsse[(plane << 2) + (block >> (tx_size << 1))] << 4; - dist = sse; - if (x->plane[plane].eobs[block]) { - const int64_t orig_sse = (int64_t)coeff[0] * coeff[0]; - const int64_t resd_sse = coeff[0] - dqcoeff[0]; - int64_t dc_correct = orig_sse - resd_sse * resd_sse; -#if CONFIG_VP9_HIGHBITDEPTH - dc_correct >>= ((xd->bd - 8) * 2); -#endif - if (tx_size != TX_32X32) dc_correct >>= 2; - - dist = VPXMAX(0, sse - dc_correct); - } - } else { - assert(0 && "allow_skip_txfm_ac_dc does not allow SKIP_TXFM_AC_DC."); - } - } - - rd = RDCOST(x->rdmult, x->rddiv, 0, dist); - if (args->this_rd + rd > args->best_rd) { - args->exit_early = 1; - return; - } - - rate = rate_block(plane, block, tx_size, coeff_ctx, args); - args->t_above[blk_col] = (x->plane[plane].eobs[block] > 0) ? 1 : 0; - args->t_left[blk_row] = (x->plane[plane].eobs[block] > 0) ? 1 : 0; - rd1 = RDCOST(x->rdmult, x->rddiv, rate, dist); - rd2 = RDCOST(x->rdmult, x->rddiv, 0, sse); - - // TODO(jingning): temporarily enabled only for luma component - rd = VPXMIN(rd1, rd2); - if (plane == 0) { - x->zcoeff_blk[tx_size][block] = - !x->plane[plane].eobs[block] || - (x->sharpness == 0 && rd1 > rd2 && !xd->lossless); - x->sum_y_eobs[tx_size] += x->plane[plane].eobs[block]; - } - - args->this_rate += rate; - args->this_dist += dist; - args->this_sse += sse; - args->this_rd += rd; - - if (args->this_rd > args->best_rd) { - args->exit_early = 1; - return; - } - - args->skippable &= !x->plane[plane].eobs[block]; -} - -static void txfm_rd_in_plane(const VP9_COMP *cpi, MACROBLOCK *x, int *rate, - int64_t *distortion, int *skippable, int64_t *sse, - int64_t ref_best_rd, int plane, BLOCK_SIZE bsize, - TX_SIZE tx_size, int use_fast_coef_costing, - struct buf_2d *recon) { - MACROBLOCKD *const xd = &x->e_mbd; - const struct macroblockd_plane *const pd = &xd->plane[plane]; - struct rdcost_block_args args; - vp9_zero(args); - args.cpi = cpi; - args.x = x; - args.best_rd = ref_best_rd; - args.use_fast_coef_costing = use_fast_coef_costing; - args.skippable = 1; - args.this_recon = recon; - - if (plane == 0) xd->mi[0]->tx_size = tx_size; - - vp9_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left); - - args.so = get_scan(xd, tx_size, get_plane_type(plane), 0); - - vp9_foreach_transformed_block_in_plane(xd, bsize, plane, block_rd_txfm, - &args); - if (args.exit_early) { - *rate = INT_MAX; - *distortion = INT64_MAX; - *sse = INT64_MAX; - *skippable = 0; - } else { - *distortion = args.this_dist; - *rate = args.this_rate; - *sse = args.this_sse; - *skippable = args.skippable; - } -} - -static void choose_largest_tx_size(VP9_COMP *cpi, MACROBLOCK *x, int *rate, - int64_t *distortion, int *skip, int64_t *sse, - int64_t ref_best_rd, BLOCK_SIZE bs, - struct buf_2d *recon) { - const TX_SIZE max_tx_size = max_txsize_lookup[bs]; - VP9_COMMON *const cm = &cpi->common; - const TX_SIZE largest_tx_size = tx_mode_to_biggest_tx_size[cm->tx_mode]; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - - mi->tx_size = VPXMIN(max_tx_size, largest_tx_size); - - txfm_rd_in_plane(cpi, x, rate, distortion, skip, sse, ref_best_rd, 0, bs, - mi->tx_size, cpi->sf.use_fast_coef_costing, recon); -} - -static void choose_tx_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x, int *rate, - int64_t *distortion, int *skip, - int64_t *psse, int64_t ref_best_rd, - BLOCK_SIZE bs, struct buf_2d *recon) { - const TX_SIZE max_tx_size = max_txsize_lookup[bs]; - VP9_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - vpx_prob skip_prob = vp9_get_skip_prob(cm, xd); - int r[TX_SIZES][2], s[TX_SIZES]; - int64_t d[TX_SIZES], sse[TX_SIZES]; - int64_t rd[TX_SIZES][2] = { { INT64_MAX, INT64_MAX }, - { INT64_MAX, INT64_MAX }, - { INT64_MAX, INT64_MAX }, - { INT64_MAX, INT64_MAX } }; - int n; - int s0, s1; - int64_t best_rd = ref_best_rd; - TX_SIZE best_tx = max_tx_size; - int start_tx, end_tx; - const int tx_size_ctx = get_tx_size_context(xd); -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, recon_buf16[TX_SIZES][64 * 64]); - uint8_t *recon_buf[TX_SIZES]; - for (n = 0; n < TX_SIZES; ++n) { - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - recon_buf[n] = CONVERT_TO_BYTEPTR(recon_buf16[n]); - } else { - recon_buf[n] = (uint8_t *)recon_buf16[n]; - } - } -#else - DECLARE_ALIGNED(16, uint8_t, recon_buf[TX_SIZES][64 * 64]); -#endif // CONFIG_VP9_HIGHBITDEPTH - - assert(skip_prob > 0); - s0 = vp9_cost_bit(skip_prob, 0); - s1 = vp9_cost_bit(skip_prob, 1); - - if (cm->tx_mode == TX_MODE_SELECT) { - start_tx = max_tx_size; - end_tx = VPXMAX(start_tx - cpi->sf.tx_size_search_depth, 0); - if (bs > BLOCK_32X32) end_tx = VPXMIN(end_tx + 1, start_tx); - } else { - TX_SIZE chosen_tx_size = - VPXMIN(max_tx_size, tx_mode_to_biggest_tx_size[cm->tx_mode]); - start_tx = chosen_tx_size; - end_tx = chosen_tx_size; - } - - for (n = start_tx; n >= end_tx; n--) { - const int r_tx_size = cpi->tx_size_cost[max_tx_size - 1][tx_size_ctx][n]; - if (recon) { - struct buf_2d this_recon; - this_recon.buf = recon_buf[n]; - this_recon.stride = recon->stride; - txfm_rd_in_plane(cpi, x, &r[n][0], &d[n], &s[n], &sse[n], best_rd, 0, bs, - n, cpi->sf.use_fast_coef_costing, &this_recon); - } else { - txfm_rd_in_plane(cpi, x, &r[n][0], &d[n], &s[n], &sse[n], best_rd, 0, bs, - n, cpi->sf.use_fast_coef_costing, 0); - } - r[n][1] = r[n][0]; - if (r[n][0] < INT_MAX) { - r[n][1] += r_tx_size; - } - if (d[n] == INT64_MAX || r[n][0] == INT_MAX) { - rd[n][0] = rd[n][1] = INT64_MAX; - } else if (s[n]) { - if (is_inter_block(mi)) { - rd[n][0] = rd[n][1] = RDCOST(x->rdmult, x->rddiv, s1, sse[n]); - r[n][1] -= r_tx_size; - } else { - rd[n][0] = RDCOST(x->rdmult, x->rddiv, s1, sse[n]); - rd[n][1] = RDCOST(x->rdmult, x->rddiv, s1 + r_tx_size, sse[n]); - } - } else { - rd[n][0] = RDCOST(x->rdmult, x->rddiv, r[n][0] + s0, d[n]); - rd[n][1] = RDCOST(x->rdmult, x->rddiv, r[n][1] + s0, d[n]); - } - - if (is_inter_block(mi) && !xd->lossless && !s[n] && sse[n] != INT64_MAX) { - rd[n][0] = VPXMIN(rd[n][0], RDCOST(x->rdmult, x->rddiv, s1, sse[n])); - rd[n][1] = VPXMIN(rd[n][1], RDCOST(x->rdmult, x->rddiv, s1, sse[n])); - } - - // Early termination in transform size search. - if (cpi->sf.tx_size_search_breakout && - (rd[n][1] == INT64_MAX || - (n < (int)max_tx_size && rd[n][1] > rd[n + 1][1]) || s[n] == 1)) - break; - - if (rd[n][1] < best_rd) { - best_tx = n; - best_rd = rd[n][1]; - } - } - mi->tx_size = best_tx; - - *distortion = d[mi->tx_size]; - *rate = r[mi->tx_size][cm->tx_mode == TX_MODE_SELECT]; - *skip = s[mi->tx_size]; - *psse = sse[mi->tx_size]; - if (recon) { -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - memcpy(CONVERT_TO_SHORTPTR(recon->buf), - CONVERT_TO_SHORTPTR(recon_buf[mi->tx_size]), - 64 * 64 * sizeof(uint16_t)); - } else { -#endif - memcpy(recon->buf, recon_buf[mi->tx_size], 64 * 64); -#if CONFIG_VP9_HIGHBITDEPTH - } -#endif - } -} - -static void super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate, - int64_t *distortion, int *skip, int64_t *psse, - BLOCK_SIZE bs, int64_t ref_best_rd, - struct buf_2d *recon) { - MACROBLOCKD *xd = &x->e_mbd; - int64_t sse; - int64_t *ret_sse = psse ? psse : &sse; - - assert(bs == xd->mi[0]->sb_type); - - if (cpi->sf.tx_size_search_method == USE_LARGESTALL || xd->lossless) { - choose_largest_tx_size(cpi, x, rate, distortion, skip, ret_sse, ref_best_rd, - bs, recon); - } else { - choose_tx_size_from_rd(cpi, x, rate, distortion, skip, ret_sse, ref_best_rd, - bs, recon); - } -} - -static int conditional_skipintra(PREDICTION_MODE mode, - PREDICTION_MODE best_intra_mode) { - if (mode == D117_PRED && best_intra_mode != V_PRED && - best_intra_mode != D135_PRED) - return 1; - if (mode == D63_PRED && best_intra_mode != V_PRED && - best_intra_mode != D45_PRED) - return 1; - if (mode == D207_PRED && best_intra_mode != H_PRED && - best_intra_mode != D45_PRED) - return 1; - if (mode == D153_PRED && best_intra_mode != H_PRED && - best_intra_mode != D135_PRED) - return 1; - return 0; -} - -static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int row, - int col, PREDICTION_MODE *best_mode, - const int *bmode_costs, ENTROPY_CONTEXT *a, - ENTROPY_CONTEXT *l, int *bestrate, - int *bestratey, int64_t *bestdistortion, - BLOCK_SIZE bsize, int64_t rd_thresh) { - PREDICTION_MODE mode; - MACROBLOCKD *const xd = &x->e_mbd; - int64_t best_rd = rd_thresh; - struct macroblock_plane *p = &x->plane[0]; - struct macroblockd_plane *pd = &xd->plane[0]; - const int src_stride = p->src.stride; - const int dst_stride = pd->dst.stride; - const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4]; - uint8_t *dst_init = &pd->dst.buf[row * 4 * src_stride + col * 4]; - ENTROPY_CONTEXT ta[2], tempa[2]; - ENTROPY_CONTEXT tl[2], templ[2]; - const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; - const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; - int idx, idy; - uint8_t best_dst[8 * 8]; -#if CONFIG_VP9_HIGHBITDEPTH - uint16_t best_dst16[8 * 8]; -#endif - memcpy(ta, a, num_4x4_blocks_wide * sizeof(a[0])); - memcpy(tl, l, num_4x4_blocks_high * sizeof(l[0])); - - xd->mi[0]->tx_size = TX_4X4; - - assert(!x->skip_block); - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - for (mode = DC_PRED; mode <= TM_PRED; ++mode) { - int64_t this_rd; - int ratey = 0; - int64_t distortion = 0; - int rate = bmode_costs[mode]; - - if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode))) continue; - - // Only do the oblique modes if the best so far is - // one of the neighboring directional modes - if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) { - if (conditional_skipintra(mode, *best_mode)) continue; - } - - memcpy(tempa, ta, num_4x4_blocks_wide * sizeof(ta[0])); - memcpy(templ, tl, num_4x4_blocks_high * sizeof(tl[0])); - - for (idy = 0; idy < num_4x4_blocks_high; ++idy) { - for (idx = 0; idx < num_4x4_blocks_wide; ++idx) { - const int block = (row + idy) * 2 + (col + idx); - const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride]; - uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride]; - uint16_t *const dst16 = CONVERT_TO_SHORTPTR(dst); - int16_t *const src_diff = - vp9_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff); - tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block); - tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block); - tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); - uint16_t *const eob = &p->eobs[block]; - xd->mi[0]->bmi[block].as_mode = mode; - vp9_predict_intra_block(xd, 1, TX_4X4, mode, - x->skip_encode ? src : dst, - x->skip_encode ? src_stride : dst_stride, dst, - dst_stride, col + idx, row + idy, 0); - vpx_highbd_subtract_block(4, 4, src_diff, 8, src, src_stride, dst, - dst_stride, xd->bd); - if (xd->lossless) { - const ScanOrder *so = &vp9_default_scan_orders[TX_4X4]; - const int coeff_ctx = - combine_entropy_contexts(tempa[idx], templ[idy]); - vp9_highbd_fwht4x4(src_diff, coeff, 8); - vpx_highbd_quantize_b(coeff, 4 * 4, p, qcoeff, dqcoeff, pd->dequant, - eob, so); - ratey += cost_coeffs(x, 0, block, TX_4X4, coeff_ctx, so->scan, - so->neighbors, cpi->sf.use_fast_coef_costing); - tempa[idx] = templ[idy] = (x->plane[0].eobs[block] > 0 ? 1 : 0); - if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd) - goto next_highbd; - vp9_highbd_iwht4x4_add(BLOCK_OFFSET(pd->dqcoeff, block), dst16, - dst_stride, p->eobs[block], xd->bd); - } else { - int64_t unused; - const TX_TYPE tx_type = get_tx_type_4x4(PLANE_TYPE_Y, xd, block); - const ScanOrder *so = &vp9_scan_orders[TX_4X4][tx_type]; - const int coeff_ctx = - combine_entropy_contexts(tempa[idx], templ[idy]); - if (tx_type == DCT_DCT) - vpx_highbd_fdct4x4(src_diff, coeff, 8); - else - vp9_highbd_fht4x4(src_diff, coeff, 8, tx_type); - vpx_highbd_quantize_b(coeff, 4 * 4, p, qcoeff, dqcoeff, pd->dequant, - eob, so); - ratey += cost_coeffs(x, 0, block, TX_4X4, coeff_ctx, so->scan, - so->neighbors, cpi->sf.use_fast_coef_costing); - distortion += vp9_highbd_block_error_dispatch( - coeff, BLOCK_OFFSET(pd->dqcoeff, block), 16, - &unused, xd->bd) >> - 2; - tempa[idx] = templ[idy] = (x->plane[0].eobs[block] > 0 ? 1 : 0); - if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd) - goto next_highbd; - vp9_highbd_iht4x4_add(tx_type, BLOCK_OFFSET(pd->dqcoeff, block), - dst16, dst_stride, p->eobs[block], xd->bd); - } - } - } - - rate += ratey; - this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion); - - if (this_rd < best_rd) { - *bestrate = rate; - *bestratey = ratey; - *bestdistortion = distortion; - best_rd = this_rd; - *best_mode = mode; - memcpy(a, tempa, num_4x4_blocks_wide * sizeof(tempa[0])); - memcpy(l, templ, num_4x4_blocks_high * sizeof(templ[0])); - for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) { - memcpy(best_dst16 + idy * 8, - CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride), - num_4x4_blocks_wide * 4 * sizeof(uint16_t)); - } - } - next_highbd : {} - } - if (best_rd >= rd_thresh || x->skip_encode) return best_rd; - - for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) { - memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride), - best_dst16 + idy * 8, num_4x4_blocks_wide * 4 * sizeof(uint16_t)); - } - - return best_rd; - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - for (mode = DC_PRED; mode <= TM_PRED; ++mode) { - int64_t this_rd; - int ratey = 0; - int64_t distortion = 0; - int rate = bmode_costs[mode]; - - if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode))) continue; - - // Only do the oblique modes if the best so far is - // one of the neighboring directional modes - if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) { - if (conditional_skipintra(mode, *best_mode)) continue; - } - - memcpy(tempa, ta, num_4x4_blocks_wide * sizeof(ta[0])); - memcpy(templ, tl, num_4x4_blocks_high * sizeof(tl[0])); - - for (idy = 0; idy < num_4x4_blocks_high; ++idy) { - for (idx = 0; idx < num_4x4_blocks_wide; ++idx) { - const int block = (row + idy) * 2 + (col + idx); - const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride]; - uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride]; - int16_t *const src_diff = - vp9_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff); - tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block); - tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block); - tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); - uint16_t *const eob = &p->eobs[block]; - xd->mi[0]->bmi[block].as_mode = mode; - vp9_predict_intra_block(xd, 1, TX_4X4, mode, x->skip_encode ? src : dst, - x->skip_encode ? src_stride : dst_stride, dst, - dst_stride, col + idx, row + idy, 0); - vpx_subtract_block(4, 4, src_diff, 8, src, src_stride, dst, dst_stride); - - if (xd->lossless) { - const ScanOrder *so = &vp9_default_scan_orders[TX_4X4]; - const int coeff_ctx = - combine_entropy_contexts(tempa[idx], templ[idy]); - vp9_fwht4x4(src_diff, coeff, 8); - vpx_quantize_b(coeff, 4 * 4, p, qcoeff, dqcoeff, pd->dequant, eob, - so); - ratey += cost_coeffs(x, 0, block, TX_4X4, coeff_ctx, so->scan, - so->neighbors, cpi->sf.use_fast_coef_costing); - tempa[idx] = templ[idy] = (x->plane[0].eobs[block] > 0) ? 1 : 0; - if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd) - goto next; - vp9_iwht4x4_add(BLOCK_OFFSET(pd->dqcoeff, block), dst, dst_stride, - p->eobs[block]); - } else { - int64_t unused; - const TX_TYPE tx_type = get_tx_type_4x4(PLANE_TYPE_Y, xd, block); - const ScanOrder *so = &vp9_scan_orders[TX_4X4][tx_type]; - const int coeff_ctx = - combine_entropy_contexts(tempa[idx], templ[idy]); - vp9_fht4x4(src_diff, coeff, 8, tx_type); - vpx_quantize_b(coeff, 4 * 4, p, qcoeff, dqcoeff, pd->dequant, eob, - so); - ratey += cost_coeffs(x, 0, block, TX_4X4, coeff_ctx, so->scan, - so->neighbors, cpi->sf.use_fast_coef_costing); - tempa[idx] = templ[idy] = (x->plane[0].eobs[block] > 0) ? 1 : 0; - distortion += vp9_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, block), - 16, &unused) >> - 2; - if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd) - goto next; - vp9_iht4x4_add(tx_type, BLOCK_OFFSET(pd->dqcoeff, block), dst, - dst_stride, p->eobs[block]); - } - } - } - - rate += ratey; - this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion); - - if (this_rd < best_rd) { - *bestrate = rate; - *bestratey = ratey; - *bestdistortion = distortion; - best_rd = this_rd; - *best_mode = mode; - memcpy(a, tempa, num_4x4_blocks_wide * sizeof(tempa[0])); - memcpy(l, templ, num_4x4_blocks_high * sizeof(templ[0])); - for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) - memcpy(best_dst + idy * 8, dst_init + idy * dst_stride, - num_4x4_blocks_wide * 4); - } - next : {} - } - - if (best_rd >= rd_thresh || x->skip_encode) return best_rd; - - for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) - memcpy(dst_init + idy * dst_stride, best_dst + idy * 8, - num_4x4_blocks_wide * 4); - - return best_rd; -} - -static int64_t rd_pick_intra_sub_8x8_y_mode(VP9_COMP *cpi, MACROBLOCK *mb, - int *rate, int *rate_y, - int64_t *distortion, - int64_t best_rd) { - int i, j; - const MACROBLOCKD *const xd = &mb->e_mbd; - MODE_INFO *const mic = xd->mi[0]; - const MODE_INFO *above_mi = xd->above_mi; - const MODE_INFO *left_mi = xd->left_mi; - const BLOCK_SIZE bsize = xd->mi[0]->sb_type; - const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; - const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; - int idx, idy; - int cost = 0; - int64_t total_distortion = 0; - int tot_rate_y = 0; - int64_t total_rd = 0; - const int *bmode_costs = cpi->mbmode_cost; - - // Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block. - for (idy = 0; idy < 2; idy += num_4x4_blocks_high) { - for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) { - PREDICTION_MODE best_mode = DC_PRED; - int r = INT_MAX, ry = INT_MAX; - int64_t d = INT64_MAX, this_rd = INT64_MAX; - i = idy * 2 + idx; - if (cpi->common.frame_type == KEY_FRAME) { - const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, i); - const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, i); - - bmode_costs = cpi->y_mode_costs[A][L]; - } - - this_rd = rd_pick_intra4x4block( - cpi, mb, idy, idx, &best_mode, bmode_costs, - xd->plane[0].above_context + idx, xd->plane[0].left_context + idy, &r, - &ry, &d, bsize, best_rd - total_rd); - - if (this_rd >= best_rd - total_rd) return INT64_MAX; - - total_rd += this_rd; - cost += r; - total_distortion += d; - tot_rate_y += ry; - - mic->bmi[i].as_mode = best_mode; - for (j = 1; j < num_4x4_blocks_high; ++j) - mic->bmi[i + j * 2].as_mode = best_mode; - for (j = 1; j < num_4x4_blocks_wide; ++j) - mic->bmi[i + j].as_mode = best_mode; - - if (total_rd >= best_rd) return INT64_MAX; - } - } - - *rate = cost; - *rate_y = tot_rate_y; - *distortion = total_distortion; - mic->mode = mic->bmi[3].as_mode; - - return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion); -} - -// This function is used only for intra_only frames -static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x, int *rate, - int *rate_tokenonly, int64_t *distortion, - int *skippable, BLOCK_SIZE bsize, - int64_t best_rd) { - PREDICTION_MODE mode; - PREDICTION_MODE mode_selected = DC_PRED; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mic = xd->mi[0]; - int this_rate, this_rate_tokenonly, s; - int64_t this_distortion, this_rd; - TX_SIZE best_tx = TX_4X4; - int *bmode_costs; - const MODE_INFO *above_mi = xd->above_mi; - const MODE_INFO *left_mi = xd->left_mi; - const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0); - const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0); - bmode_costs = cpi->y_mode_costs[A][L]; - - memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm)); - /* Y Search for intra prediction mode */ - for (mode = DC_PRED; mode <= TM_PRED; mode++) { - if (cpi->sf.use_nonrd_pick_mode) { - // These speed features are turned on in hybrid non-RD and RD mode - // for key frame coding in the context of real-time setting. - if (conditional_skipintra(mode, mode_selected)) continue; - if (*skippable) break; - } - - mic->mode = mode; - - super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, NULL, - bsize, best_rd, /*recon=*/NULL); - - if (this_rate_tokenonly == INT_MAX) continue; - - this_rate = this_rate_tokenonly + bmode_costs[mode]; - this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion); - - if (this_rd < best_rd) { - mode_selected = mode; - best_rd = this_rd; - best_tx = mic->tx_size; - *rate = this_rate; - *rate_tokenonly = this_rate_tokenonly; - *distortion = this_distortion; - *skippable = s; - } - } - - mic->mode = mode_selected; - mic->tx_size = best_tx; - - return best_rd; -} - -// Return value 0: early termination triggered, no valid rd cost available; -// 1: rd cost values are valid. -static int super_block_uvrd(const VP9_COMP *cpi, MACROBLOCK *x, int *rate, - int64_t *distortion, int *skippable, int64_t *sse, - BLOCK_SIZE bsize, int64_t ref_best_rd) { - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - const TX_SIZE uv_tx_size = get_uv_tx_size(mi, &xd->plane[1]); - int plane; - int pnrate = 0, pnskip = 1; - int64_t pndist = 0, pnsse = 0; - int is_cost_valid = 1; - - if (ref_best_rd < 0) is_cost_valid = 0; - - if (is_inter_block(mi) && is_cost_valid) { - for (plane = 1; plane < MAX_MB_PLANE; ++plane) - vp9_subtract_plane(x, bsize, plane); - } - - *rate = 0; - *distortion = 0; - *sse = 0; - *skippable = 1; - - for (plane = 1; plane < MAX_MB_PLANE; ++plane) { - txfm_rd_in_plane(cpi, x, &pnrate, &pndist, &pnskip, &pnsse, ref_best_rd, - plane, bsize, uv_tx_size, cpi->sf.use_fast_coef_costing, - /*recon=*/NULL); - if (pnrate == INT_MAX) { - is_cost_valid = 0; - break; - } - *rate += pnrate; - *distortion += pndist; - *sse += pnsse; - *skippable &= pnskip; - } - - if (!is_cost_valid) { - // reset cost value - *rate = INT_MAX; - *distortion = INT64_MAX; - *sse = INT64_MAX; - *skippable = 0; - } - - return is_cost_valid; -} - -static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x, - PICK_MODE_CONTEXT *ctx, int *rate, - int *rate_tokenonly, int64_t *distortion, - int *skippable, BLOCK_SIZE bsize, - TX_SIZE max_tx_size) { - MACROBLOCKD *xd = &x->e_mbd; - PREDICTION_MODE mode; - PREDICTION_MODE mode_selected = DC_PRED; - int64_t best_rd = INT64_MAX, this_rd; - int this_rate_tokenonly, this_rate, s; - int64_t this_distortion, this_sse; - - memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm)); - for (mode = DC_PRED; mode <= TM_PRED; ++mode) { - if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode))) continue; -#if CONFIG_BETTER_HW_COMPATIBILITY && CONFIG_VP9_HIGHBITDEPTH - if ((xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) && - (xd->above_mi == NULL || xd->left_mi == NULL) && need_top_left[mode]) - continue; -#endif // CONFIG_BETTER_HW_COMPATIBILITY && CONFIG_VP9_HIGHBITDEPTH - - xd->mi[0]->uv_mode = mode; - - if (!super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, - &this_sse, bsize, best_rd)) - continue; - this_rate = - this_rate_tokenonly + - cpi->intra_uv_mode_cost[cpi->common.frame_type][xd->mi[0]->mode][mode]; - this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion); - - if (this_rd < best_rd) { - mode_selected = mode; - best_rd = this_rd; - *rate = this_rate; - *rate_tokenonly = this_rate_tokenonly; - *distortion = this_distortion; - *skippable = s; - if (!x->select_tx_size) swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE); - } - } - - xd->mi[0]->uv_mode = mode_selected; - return best_rd; -} - -#if !CONFIG_REALTIME_ONLY -static int64_t rd_sbuv_dcpred(const VP9_COMP *cpi, MACROBLOCK *x, int *rate, - int *rate_tokenonly, int64_t *distortion, - int *skippable, BLOCK_SIZE bsize) { - const VP9_COMMON *cm = &cpi->common; - int64_t unused; - - x->e_mbd.mi[0]->uv_mode = DC_PRED; - memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm)); - super_block_uvrd(cpi, x, rate_tokenonly, distortion, skippable, &unused, - bsize, INT64_MAX); - *rate = - *rate_tokenonly + - cpi->intra_uv_mode_cost[cm->frame_type][x->e_mbd.mi[0]->mode][DC_PRED]; - return RDCOST(x->rdmult, x->rddiv, *rate, *distortion); -} - -static void choose_intra_uv_mode(VP9_COMP *cpi, MACROBLOCK *const x, - PICK_MODE_CONTEXT *ctx, BLOCK_SIZE bsize, - TX_SIZE max_tx_size, int *rate_uv, - int *rate_uv_tokenonly, int64_t *dist_uv, - int *skip_uv, PREDICTION_MODE *mode_uv) { - // Use an estimated rd for uv_intra based on DC_PRED if the - // appropriate speed flag is set. - if (cpi->sf.use_uv_intra_rd_estimate) { - rd_sbuv_dcpred(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv, - bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize); - // Else do a proper rd search for each possible transform size that may - // be considered in the main rd loop. - } else { - rd_pick_intra_sbuv_mode(cpi, x, ctx, rate_uv, rate_uv_tokenonly, dist_uv, - skip_uv, bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, - max_tx_size); - } - *mode_uv = x->e_mbd.mi[0]->uv_mode; -} - -static int cost_mv_ref(const VP9_COMP *cpi, PREDICTION_MODE mode, - int mode_context) { - assert(is_inter_mode(mode)); - return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)]; -} - -static int set_and_cost_bmi_mvs(VP9_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd, - int i, PREDICTION_MODE mode, int_mv this_mv[2], - int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES], - int_mv seg_mvs[MAX_REF_FRAMES], - int_mv *best_ref_mv[2], const int *mvjcost, - int *mvcost[2]) { - MODE_INFO *const mi = xd->mi[0]; - const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext; - int thismvcost = 0; - int idx, idy; - const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mi->sb_type]; - const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mi->sb_type]; - const int is_compound = has_second_ref(mi); - - switch (mode) { - case NEWMV: - this_mv[0].as_int = seg_mvs[mi->ref_frame[0]].as_int; - thismvcost += vp9_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv, - mvjcost, mvcost, MV_COST_WEIGHT_SUB); - if (is_compound) { - this_mv[1].as_int = seg_mvs[mi->ref_frame[1]].as_int; - thismvcost += vp9_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv, - mvjcost, mvcost, MV_COST_WEIGHT_SUB); - } - break; - case NEARMV: - case NEARESTMV: - this_mv[0].as_int = frame_mv[mode][mi->ref_frame[0]].as_int; - if (is_compound) - this_mv[1].as_int = frame_mv[mode][mi->ref_frame[1]].as_int; - break; - default: - assert(mode == ZEROMV); - this_mv[0].as_int = 0; - if (is_compound) this_mv[1].as_int = 0; - break; - } - - mi->bmi[i].as_mv[0].as_int = this_mv[0].as_int; - if (is_compound) mi->bmi[i].as_mv[1].as_int = this_mv[1].as_int; - - mi->bmi[i].as_mode = mode; - - for (idy = 0; idy < num_4x4_blocks_high; ++idy) - for (idx = 0; idx < num_4x4_blocks_wide; ++idx) - memmove(&mi->bmi[i + idy * 2 + idx], &mi->bmi[i], sizeof(mi->bmi[i])); - - return cost_mv_ref(cpi, mode, mbmi_ext->mode_context[mi->ref_frame[0]]) + - thismvcost; -} - -static int64_t encode_inter_mb_segment(VP9_COMP *cpi, MACROBLOCK *x, - int64_t best_yrd, int i, int *labelyrate, - int64_t *distortion, int64_t *sse, - ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl, - int mi_row, int mi_col) { - int k; - MACROBLOCKD *xd = &x->e_mbd; - struct macroblockd_plane *const pd = &xd->plane[0]; - struct macroblock_plane *const p = &x->plane[0]; - MODE_INFO *const mi = xd->mi[0]; - const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->sb_type, pd); - const int width = 4 * num_4x4_blocks_wide_lookup[plane_bsize]; - const int height = 4 * num_4x4_blocks_high_lookup[plane_bsize]; - int idx, idy; - - const uint8_t *const src = - &p->src.buf[vp9_raster_block_offset(BLOCK_8X8, i, p->src.stride)]; - uint8_t *const dst = - &pd->dst.buf[vp9_raster_block_offset(BLOCK_8X8, i, pd->dst.stride)]; - int64_t thisdistortion = 0, thissse = 0; - int thisrate = 0, ref; - const ScanOrder *so = &vp9_default_scan_orders[TX_4X4]; - const int is_compound = has_second_ref(mi); - const InterpKernel *kernel = vp9_filter_kernels[mi->interp_filter]; - - assert(!x->skip_block); - - for (ref = 0; ref < 1 + is_compound; ++ref) { - const int bw = b_width_log2_lookup[BLOCK_8X8]; - const int h = 4 * (i >> bw); - const int w = 4 * (i & ((1 << bw) - 1)); - const struct scale_factors *sf = &xd->block_refs[ref]->sf; - int y_stride = pd->pre[ref].stride; - uint8_t *pre = pd->pre[ref].buf + (h * pd->pre[ref].stride + w); - - if (vp9_is_scaled(sf)) { - const int x_start = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)); - const int y_start = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)); - - y_stride = xd->block_refs[ref]->buf->y_stride; - pre = xd->block_refs[ref]->buf->y_buffer; - pre += scaled_buffer_offset(x_start + w, y_start + h, y_stride, sf); - } -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - vp9_highbd_build_inter_predictor( - CONVERT_TO_SHORTPTR(pre), y_stride, CONVERT_TO_SHORTPTR(dst), - pd->dst.stride, &mi->bmi[i].as_mv[ref].as_mv, - &xd->block_refs[ref]->sf, width, height, ref, kernel, MV_PRECISION_Q3, - mi_col * MI_SIZE + 4 * (i % 2), mi_row * MI_SIZE + 4 * (i / 2), - xd->bd); - } else { - vp9_build_inter_predictor( - pre, y_stride, dst, pd->dst.stride, &mi->bmi[i].as_mv[ref].as_mv, - &xd->block_refs[ref]->sf, width, height, ref, kernel, MV_PRECISION_Q3, - mi_col * MI_SIZE + 4 * (i % 2), mi_row * MI_SIZE + 4 * (i / 2)); - } -#else - vp9_build_inter_predictor( - pre, y_stride, dst, pd->dst.stride, &mi->bmi[i].as_mv[ref].as_mv, - &xd->block_refs[ref]->sf, width, height, ref, kernel, MV_PRECISION_Q3, - mi_col * MI_SIZE + 4 * (i % 2), mi_row * MI_SIZE + 4 * (i / 2)); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - vpx_highbd_subtract_block( - height, width, vp9_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), - 8, src, p->src.stride, dst, pd->dst.stride, xd->bd); - } else { - vpx_subtract_block(height, width, - vp9_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), - 8, src, p->src.stride, dst, pd->dst.stride); - } -#else - vpx_subtract_block(height, width, - vp9_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), - 8, src, p->src.stride, dst, pd->dst.stride); -#endif // CONFIG_VP9_HIGHBITDEPTH - - k = i; - for (idy = 0; idy < height / 4; ++idy) { - for (idx = 0; idx < width / 4; ++idx) { -#if CONFIG_VP9_HIGHBITDEPTH - const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8; -#endif - int64_t ssz, rd, rd1, rd2; - tran_low_t *coeff, *qcoeff, *dqcoeff; - uint16_t *eob; - int coeff_ctx; - k += (idy * 2 + idx); - coeff_ctx = combine_entropy_contexts(ta[k & 1], tl[k >> 1]); - coeff = BLOCK_OFFSET(p->coeff, k); - qcoeff = BLOCK_OFFSET(p->qcoeff, k); - dqcoeff = BLOCK_OFFSET(pd->dqcoeff, k); - eob = &p->eobs[k]; - - x->fwd_txfm4x4(vp9_raster_block_offset_int16(BLOCK_8X8, k, p->src_diff), - coeff, 8); -#if CONFIG_VP9_HIGHBITDEPTH - vpx_highbd_quantize_b(coeff, 4 * 4, p, qcoeff, dqcoeff, pd->dequant, eob, - so); - thisdistortion += vp9_highbd_block_error_dispatch( - coeff, BLOCK_OFFSET(pd->dqcoeff, k), 16, &ssz, bd); -#else - vpx_quantize_b(coeff, 4 * 4, p, qcoeff, dqcoeff, pd->dequant, eob, so); - thisdistortion += - vp9_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, k), 16, &ssz); -#endif // CONFIG_VP9_HIGHBITDEPTH - thissse += ssz; - thisrate += cost_coeffs(x, 0, k, TX_4X4, coeff_ctx, so->scan, - so->neighbors, cpi->sf.use_fast_coef_costing); - ta[k & 1] = tl[k >> 1] = (x->plane[0].eobs[k] > 0) ? 1 : 0; - rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion >> 2); - rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse >> 2); - rd = VPXMIN(rd1, rd2); - if (rd >= best_yrd) return INT64_MAX; - } - } - - *distortion = thisdistortion >> 2; - *labelyrate = thisrate; - *sse = thissse >> 2; - - return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion); -} -#endif // !CONFIG_REALTIME_ONLY - -typedef struct { - int eobs; - int brate; - int byrate; - int64_t bdist; - int64_t bsse; - int64_t brdcost; - int_mv mvs[2]; - ENTROPY_CONTEXT ta[2]; - ENTROPY_CONTEXT tl[2]; -} SEG_RDSTAT; - -typedef struct { - int_mv *ref_mv[2]; - int_mv mvp; - - int64_t segment_rd; - int r; - int64_t d; - int64_t sse; - int segment_yrate; - PREDICTION_MODE modes[4]; - SEG_RDSTAT rdstat[4][INTER_MODES]; - int mvthresh; -} BEST_SEG_INFO; - -#if !CONFIG_REALTIME_ONLY -static INLINE int mv_check_bounds(const MvLimits *mv_limits, const MV *mv) { - return (mv->row >> 3) < mv_limits->row_min || - (mv->row >> 3) > mv_limits->row_max || - (mv->col >> 3) < mv_limits->col_min || - (mv->col >> 3) > mv_limits->col_max; -} - -static INLINE void mi_buf_shift(MACROBLOCK *x, int i) { - MODE_INFO *const mi = x->e_mbd.mi[0]; - struct macroblock_plane *const p = &x->plane[0]; - struct macroblockd_plane *const pd = &x->e_mbd.plane[0]; - - p->src.buf = - &p->src.buf[vp9_raster_block_offset(BLOCK_8X8, i, p->src.stride)]; - assert(((intptr_t)pd->pre[0].buf & 0x7) == 0); - pd->pre[0].buf = - &pd->pre[0].buf[vp9_raster_block_offset(BLOCK_8X8, i, pd->pre[0].stride)]; - if (has_second_ref(mi)) - pd->pre[1].buf = - &pd->pre[1] - .buf[vp9_raster_block_offset(BLOCK_8X8, i, pd->pre[1].stride)]; -} - -static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src, - struct buf_2d orig_pre[2]) { - MODE_INFO *mi = x->e_mbd.mi[0]; - x->plane[0].src = orig_src; - x->e_mbd.plane[0].pre[0] = orig_pre[0]; - if (has_second_ref(mi)) x->e_mbd.plane[0].pre[1] = orig_pre[1]; -} - -static INLINE int mv_has_subpel(const MV *mv) { - return (mv->row & 0x0F) || (mv->col & 0x0F); -} - -// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion. -// TODO(aconverse): Find out if this is still productive then clean up or remove -static int check_best_zero_mv(const VP9_COMP *cpi, - const uint8_t mode_context[MAX_REF_FRAMES], - int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES], - int this_mode, - const MV_REFERENCE_FRAME ref_frames[2]) { - if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) && - frame_mv[this_mode][ref_frames[0]].as_int == 0 && - (ref_frames[1] == NO_REF_FRAME || - frame_mv[this_mode][ref_frames[1]].as_int == 0)) { - int rfc = mode_context[ref_frames[0]]; - int c1 = cost_mv_ref(cpi, NEARMV, rfc); - int c2 = cost_mv_ref(cpi, NEARESTMV, rfc); - int c3 = cost_mv_ref(cpi, ZEROMV, rfc); - - if (this_mode == NEARMV) { - if (c1 > c3) return 0; - } else if (this_mode == NEARESTMV) { - if (c2 > c3) return 0; - } else { - assert(this_mode == ZEROMV); - if (ref_frames[1] == NO_REF_FRAME) { - if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) || - (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0)) - return 0; - } else { - if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 && - frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) || - (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 && - frame_mv[NEARMV][ref_frames[1]].as_int == 0)) - return 0; - } - } - } - return 1; -} - -static INLINE int skip_iters(int_mv iter_mvs[][2], int ite, int id) { - if (ite >= 2 && iter_mvs[ite - 2][!id].as_int == iter_mvs[ite][!id].as_int) { - int_mv cur_fullpel_mv, prev_fullpel_mv; - cur_fullpel_mv.as_mv.row = iter_mvs[ite][id].as_mv.row >> 3; - cur_fullpel_mv.as_mv.col = iter_mvs[ite][id].as_mv.col >> 3; - prev_fullpel_mv.as_mv.row = iter_mvs[ite - 2][id].as_mv.row >> 3; - prev_fullpel_mv.as_mv.col = iter_mvs[ite - 2][id].as_mv.col >> 3; - if (cur_fullpel_mv.as_int == prev_fullpel_mv.as_int) return 1; - } - return 0; -} - -// Compares motion vector and mode rate of current mode and given mode. -static INLINE int compare_mv_mode_rate(MV this_mv, MV mode_mv, - int this_mode_rate, int mode_rate, - int mv_thresh) { - const int mv_diff = - abs(mode_mv.col - this_mv.col) + abs(mode_mv.row - this_mv.row); - if (mv_diff <= mv_thresh && mode_rate < this_mode_rate) return 1; - return 0; -} - -// Skips single reference inter modes NEARMV and ZEROMV based on motion vector -// difference and mode rate. -static INLINE int skip_single_mode_based_on_mode_rate( - int_mv (*mode_mv)[MAX_REF_FRAMES], int *single_mode_rate, int this_mode, - int ref0, int this_mode_rate, int best_mode_index) { - MV this_mv = mode_mv[this_mode][ref0].as_mv; - const int mv_thresh = 3; - - // Pruning is not applicable for NEARESTMV or NEWMV modes. - if (this_mode == NEARESTMV || this_mode == NEWMV) return 0; - // Pruning is not done when reference frame of the mode is same as best - // reference so far. - if (best_mode_index > 0 && - ref0 == vp9_mode_order[best_mode_index].ref_frame[0]) - return 0; - - // Check absolute mv difference and mode rate of current mode w.r.t NEARESTMV - if (compare_mv_mode_rate( - this_mv, mode_mv[NEARESTMV][ref0].as_mv, this_mode_rate, - single_mode_rate[INTER_OFFSET(NEARESTMV)], mv_thresh)) - return 1; - - // Check absolute mv difference and mode rate of current mode w.r.t NEWMV - if (compare_mv_mode_rate(this_mv, mode_mv[NEWMV][ref0].as_mv, this_mode_rate, - single_mode_rate[INTER_OFFSET(NEWMV)], mv_thresh)) - return 1; - - // Pruning w.r.t NEARMV is applicable only for ZEROMV mode - if (this_mode == NEARMV) return 0; - // Check absolute mv difference and mode rate of current mode w.r.t NEARMV - if (compare_mv_mode_rate(this_mv, mode_mv[NEARMV][ref0].as_mv, this_mode_rate, - single_mode_rate[INTER_OFFSET(NEARMV)], mv_thresh)) - return 1; - return 0; -} - -#define MAX_JOINT_MV_SEARCH_ITERS 4 -static INLINE int get_joint_search_iters(int sf_level, BLOCK_SIZE bsize) { - int num_iters = MAX_JOINT_MV_SEARCH_ITERS; // sf_level = 0 - if (sf_level >= 2) - num_iters = 0; - else if (sf_level >= 1) - num_iters = bsize < BLOCK_8X8 - ? 0 - : (bsize <= BLOCK_16X16 ? 2 : MAX_JOINT_MV_SEARCH_ITERS); - return num_iters; -} - -static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, - int_mv *frame_mv, int mi_row, int mi_col, - int_mv single_newmv[MAX_REF_FRAMES], - int *rate_mv, int num_iters) { - const VP9_COMMON *const cm = &cpi->common; - const int pw = 4 * num_4x4_blocks_wide_lookup[bsize]; - const int ph = 4 * num_4x4_blocks_high_lookup[bsize]; - MACROBLOCKD *xd = &x->e_mbd; - MODE_INFO *mi = xd->mi[0]; - const int refs[2] = { mi->ref_frame[0], - mi->ref_frame[1] < 0 ? 0 : mi->ref_frame[1] }; - int_mv ref_mv[2]; - int_mv iter_mvs[MAX_JOINT_MV_SEARCH_ITERS][2]; - int ite, ref; - const InterpKernel *kernel = vp9_filter_kernels[mi->interp_filter]; - struct scale_factors sf; - - // Do joint motion search in compound mode to get more accurate mv. - struct buf_2d backup_yv12[2][MAX_MB_PLANE]; - uint32_t last_besterr[2] = { UINT_MAX, UINT_MAX }; - const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = { - vp9_get_scaled_ref_frame(cpi, mi->ref_frame[0]), - vp9_get_scaled_ref_frame(cpi, mi->ref_frame[1]) - }; - -// Prediction buffer from second frame. -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(32, uint16_t, second_pred_alloc_16[64 * 64]); - uint8_t *second_pred; -#else - DECLARE_ALIGNED(32, uint8_t, second_pred[64 * 64]); -#endif // CONFIG_VP9_HIGHBITDEPTH - - // Check number of iterations do not exceed the max - assert(num_iters <= MAX_JOINT_MV_SEARCH_ITERS); - - for (ref = 0; ref < 2; ++ref) { - ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0]; - - if (scaled_ref_frame[ref]) { - int i; - // Swap out the reference frame for a version that's been scaled to - // match the resolution of the current frame, allowing the existing - // motion search code to be used without additional modifications. - for (i = 0; i < MAX_MB_PLANE; i++) - backup_yv12[ref][i] = xd->plane[i].pre[ref]; - vp9_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col, - NULL); - } - - frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int; - iter_mvs[0][ref].as_int = single_newmv[refs[ref]].as_int; - } - -// Since we have scaled the reference frames to match the size of the current -// frame we must use a unit scaling factor during mode selection. -#if CONFIG_VP9_HIGHBITDEPTH - vp9_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width, - cm->height, cm->use_highbitdepth); -#else - vp9_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width, - cm->height); -#endif // CONFIG_VP9_HIGHBITDEPTH - - // Allow joint search multiple times iteratively for each reference frame - // and break out of the search loop if it couldn't find a better mv. - for (ite = 0; ite < num_iters; ite++) { - struct buf_2d ref_yv12[2]; - uint32_t bestsme = UINT_MAX; - int sadpb = x->sadperbit16; - MV tmp_mv; - int search_range = 3; - - const MvLimits tmp_mv_limits = x->mv_limits; - int id = ite % 2; // Even iterations search in the first reference frame, - // odd iterations search in the second. The predictor - // found for the 'other' reference frame is factored in. - - // Skip further iterations of search if in the previous iteration, the - // motion vector of the searched ref frame is unchanged, and the other ref - // frame's full-pixel mv is unchanged. - if (skip_iters(iter_mvs, ite, id)) break; - - // Initialized here because of compiler problem in Visual Studio. - ref_yv12[0] = xd->plane[0].pre[0]; - ref_yv12[1] = xd->plane[0].pre[1]; - -// Get the prediction block from the 'other' reference frame. -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16); - vp9_highbd_build_inter_predictor( - CONVERT_TO_SHORTPTR(ref_yv12[!id].buf), ref_yv12[!id].stride, - second_pred_alloc_16, pw, &frame_mv[refs[!id]].as_mv, &sf, pw, ph, 0, - kernel, MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd->bd); - } else { - second_pred = (uint8_t *)second_pred_alloc_16; - vp9_build_inter_predictor(ref_yv12[!id].buf, ref_yv12[!id].stride, - second_pred, pw, &frame_mv[refs[!id]].as_mv, - &sf, pw, ph, 0, kernel, MV_PRECISION_Q3, - mi_col * MI_SIZE, mi_row * MI_SIZE); - } -#else - vp9_build_inter_predictor(ref_yv12[!id].buf, ref_yv12[!id].stride, - second_pred, pw, &frame_mv[refs[!id]].as_mv, &sf, - pw, ph, 0, kernel, MV_PRECISION_Q3, - mi_col * MI_SIZE, mi_row * MI_SIZE); -#endif // CONFIG_VP9_HIGHBITDEPTH - - // Do compound motion search on the current reference frame. - if (id) xd->plane[0].pre[0] = ref_yv12[id]; - vp9_set_mv_search_range(&x->mv_limits, &ref_mv[id].as_mv); - - // Use the mv result from the single mode as mv predictor. - tmp_mv = frame_mv[refs[id]].as_mv; - - tmp_mv.col >>= 3; - tmp_mv.row >>= 3; - - // Small-range full-pixel motion search. - bestsme = vp9_refining_search_8p_c(x, &tmp_mv, sadpb, search_range, - &cpi->fn_ptr[bsize], &ref_mv[id].as_mv, - second_pred); - if (bestsme < UINT_MAX) - bestsme = vp9_get_mvpred_av_var(x, &tmp_mv, &ref_mv[id].as_mv, - second_pred, &cpi->fn_ptr[bsize], 1); - - x->mv_limits = tmp_mv_limits; - - if (bestsme < UINT_MAX) { - uint32_t dis; /* TODO: use dis in distortion calculation later. */ - uint32_t sse; - bestsme = cpi->find_fractional_mv_step( - x, &tmp_mv, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv, - x->errorperbit, &cpi->fn_ptr[bsize], 0, - cpi->sf.mv.subpel_search_level, NULL, x->nmvjointcost, x->mvcost, - &dis, &sse, second_pred, pw, ph, cpi->sf.use_accurate_subpel_search); - } - - // Restore the pointer to the first (possibly scaled) prediction buffer. - if (id) xd->plane[0].pre[0] = ref_yv12[0]; - - if (bestsme < last_besterr[id]) { - frame_mv[refs[id]].as_mv = tmp_mv; - last_besterr[id] = bestsme; - } else { - break; - } - if (ite < num_iters - 1) { - iter_mvs[ite + 1][0].as_int = frame_mv[refs[0]].as_int; - iter_mvs[ite + 1][1].as_int = frame_mv[refs[1]].as_int; - } - } - - *rate_mv = 0; - - for (ref = 0; ref < 2; ++ref) { - if (scaled_ref_frame[ref]) { - // Restore the prediction frame pointers to their unscaled versions. - int i; - for (i = 0; i < MAX_MB_PLANE; i++) - xd->plane[i].pre[ref] = backup_yv12[ref][i]; - } - - *rate_mv += vp9_mv_bit_cost(&frame_mv[refs[ref]].as_mv, - &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv, - x->nmvjointcost, x->mvcost, MV_COST_WEIGHT); - } -} - -static int64_t rd_pick_best_sub8x8_mode( - VP9_COMP *cpi, MACROBLOCK *x, int_mv *best_ref_mv, - int_mv *second_best_ref_mv, int64_t best_rd_so_far, int *returntotrate, - int *returnyrate, int64_t *returndistortion, int *skippable, int64_t *psse, - int mvthresh, int_mv seg_mvs[4][MAX_REF_FRAMES], BEST_SEG_INFO *bsi_buf, - int filter_idx, int mi_row, int mi_col) { - int i; - BEST_SEG_INFO *bsi = bsi_buf + filter_idx; - MACROBLOCKD *xd = &x->e_mbd; - MODE_INFO *mi = xd->mi[0]; - int mode_idx; - int k, br = 0, idx, idy; - int64_t bd = 0, block_sse = 0; - PREDICTION_MODE this_mode; - VP9_COMMON *cm = &cpi->common; - struct macroblock_plane *const p = &x->plane[0]; - struct macroblockd_plane *const pd = &xd->plane[0]; - const int label_count = 4; - int64_t this_segment_rd = 0; - int label_mv_thresh; - int segmentyrate = 0; - const BLOCK_SIZE bsize = mi->sb_type; - const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; - const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; - const int pw = num_4x4_blocks_wide << 2; - const int ph = num_4x4_blocks_high << 2; - ENTROPY_CONTEXT t_above[2], t_left[2]; - int subpelmv = 1, have_ref = 0; - SPEED_FEATURES *const sf = &cpi->sf; - const int has_second_rf = has_second_ref(mi); - const int inter_mode_mask = sf->inter_mode_mask[bsize]; - MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext; - - vp9_zero(*bsi); - - bsi->segment_rd = best_rd_so_far; - bsi->ref_mv[0] = best_ref_mv; - bsi->ref_mv[1] = second_best_ref_mv; - bsi->mvp.as_int = best_ref_mv->as_int; - bsi->mvthresh = mvthresh; - - for (i = 0; i < 4; i++) bsi->modes[i] = ZEROMV; - - memcpy(t_above, pd->above_context, sizeof(t_above)); - memcpy(t_left, pd->left_context, sizeof(t_left)); - - // 64 makes this threshold really big effectively - // making it so that we very rarely check mvs on - // segments. setting this to 1 would make mv thresh - // roughly equal to what it is for macroblocks - label_mv_thresh = 1 * bsi->mvthresh / label_count; - - // Segmentation method overheads - for (idy = 0; idy < 2; idy += num_4x4_blocks_high) { - for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) { - // TODO(jingning,rbultje): rewrite the rate-distortion optimization - // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop - int_mv mode_mv[MB_MODE_COUNT][2]; - int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES]; - PREDICTION_MODE mode_selected = ZEROMV; - int64_t best_rd = INT64_MAX; - const int block = idy * 2 + idx; - int ref; - - for (ref = 0; ref < 1 + has_second_rf; ++ref) { - const MV_REFERENCE_FRAME frame = mi->ref_frame[ref]; - frame_mv[ZEROMV][frame].as_int = 0; - vp9_append_sub8x8_mvs_for_idx( - cm, xd, block, ref, mi_row, mi_col, &frame_mv[NEARESTMV][frame], - &frame_mv[NEARMV][frame], mbmi_ext->mode_context); - } - - // search for the best motion vector on this segment - for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) { - const struct buf_2d orig_src = x->plane[0].src; - struct buf_2d orig_pre[2]; - - mode_idx = INTER_OFFSET(this_mode); - bsi->rdstat[block][mode_idx].brdcost = INT64_MAX; - if (!(inter_mode_mask & (1 << this_mode))) continue; - - if (!check_best_zero_mv(cpi, mbmi_ext->mode_context, frame_mv, - this_mode, mi->ref_frame)) - continue; - - memcpy(orig_pre, pd->pre, sizeof(orig_pre)); - memcpy(bsi->rdstat[block][mode_idx].ta, t_above, - sizeof(bsi->rdstat[block][mode_idx].ta)); - memcpy(bsi->rdstat[block][mode_idx].tl, t_left, - sizeof(bsi->rdstat[block][mode_idx].tl)); - - // motion search for newmv (single predictor case only) - if (!has_second_rf && this_mode == NEWMV && - seg_mvs[block][mi->ref_frame[0]].as_int == INVALID_MV) { - MV *const new_mv = &mode_mv[NEWMV][0].as_mv; - int step_param = 0; - uint32_t bestsme = UINT_MAX; - int sadpb = x->sadperbit4; - MV mvp_full; - int max_mv; - int cost_list[5]; - const MvLimits tmp_mv_limits = x->mv_limits; - - /* Is the best so far sufficiently good that we can't justify doing - * and new motion search. */ - if (best_rd < label_mv_thresh) break; - - if (cpi->oxcf.mode != BEST) { - // use previous block's result as next block's MV predictor. - if (block > 0) { - bsi->mvp.as_int = mi->bmi[block - 1].as_mv[0].as_int; - if (block == 2) - bsi->mvp.as_int = mi->bmi[block - 2].as_mv[0].as_int; - } - } - if (block == 0) - max_mv = x->max_mv_context[mi->ref_frame[0]]; - else - max_mv = - VPXMAX(abs(bsi->mvp.as_mv.row), abs(bsi->mvp.as_mv.col)) >> 3; - - if (sf->mv.auto_mv_step_size && cm->show_frame) { - // Take wtd average of the step_params based on the last frame's - // max mv magnitude and the best ref mvs of the current block for - // the given reference. - step_param = - (vp9_init_search_range(max_mv) + cpi->mv_step_param) / 2; - } else { - step_param = cpi->mv_step_param; - } - - mvp_full.row = bsi->mvp.as_mv.row >> 3; - mvp_full.col = bsi->mvp.as_mv.col >> 3; - - if (sf->adaptive_motion_search) { - if (x->pred_mv[mi->ref_frame[0]].row != INT16_MAX && - x->pred_mv[mi->ref_frame[0]].col != INT16_MAX) { - mvp_full.row = x->pred_mv[mi->ref_frame[0]].row >> 3; - mvp_full.col = x->pred_mv[mi->ref_frame[0]].col >> 3; - } - step_param = VPXMAX(step_param, 8); - } - - // adjust src pointer for this block - mi_buf_shift(x, block); - - vp9_set_mv_search_range(&x->mv_limits, &bsi->ref_mv[0]->as_mv); - - bestsme = vp9_full_pixel_search( - cpi, x, bsize, &mvp_full, step_param, cpi->sf.mv.search_method, - sadpb, - sf->mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL, - &bsi->ref_mv[0]->as_mv, new_mv, INT_MAX, 1); - - x->mv_limits = tmp_mv_limits; - - if (bestsme < UINT_MAX) { - uint32_t distortion; - cpi->find_fractional_mv_step( - x, new_mv, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv, - x->errorperbit, &cpi->fn_ptr[bsize], sf->mv.subpel_force_stop, - sf->mv.subpel_search_level, cond_cost_list(cpi, cost_list), - x->nmvjointcost, x->mvcost, &distortion, - &x->pred_sse[mi->ref_frame[0]], NULL, pw, ph, - cpi->sf.use_accurate_subpel_search); - - // save motion search result for use in compound prediction - seg_mvs[block][mi->ref_frame[0]].as_mv = *new_mv; - } - - x->pred_mv[mi->ref_frame[0]] = *new_mv; - - // restore src pointers - mi_buf_restore(x, orig_src, orig_pre); - } - - if (has_second_rf) { - if (seg_mvs[block][mi->ref_frame[1]].as_int == INVALID_MV || - seg_mvs[block][mi->ref_frame[0]].as_int == INVALID_MV) - continue; - } - - if (has_second_rf && this_mode == NEWMV && - mi->interp_filter == EIGHTTAP) { - // Decide number of joint motion search iterations - const int num_joint_search_iters = get_joint_search_iters( - cpi->sf.comp_inter_joint_search_iter_level, bsize); - // adjust src pointers - mi_buf_shift(x, block); - if (num_joint_search_iters) { - int rate_mv; - joint_motion_search(cpi, x, bsize, frame_mv[this_mode], mi_row, - mi_col, seg_mvs[block], &rate_mv, - num_joint_search_iters); - seg_mvs[block][mi->ref_frame[0]].as_int = - frame_mv[this_mode][mi->ref_frame[0]].as_int; - seg_mvs[block][mi->ref_frame[1]].as_int = - frame_mv[this_mode][mi->ref_frame[1]].as_int; - } - // restore src pointers - mi_buf_restore(x, orig_src, orig_pre); - } - - bsi->rdstat[block][mode_idx].brate = set_and_cost_bmi_mvs( - cpi, x, xd, block, this_mode, mode_mv[this_mode], frame_mv, - seg_mvs[block], bsi->ref_mv, x->nmvjointcost, x->mvcost); - - for (ref = 0; ref < 1 + has_second_rf; ++ref) { - bsi->rdstat[block][mode_idx].mvs[ref].as_int = - mode_mv[this_mode][ref].as_int; - if (num_4x4_blocks_wide > 1) - bsi->rdstat[block + 1][mode_idx].mvs[ref].as_int = - mode_mv[this_mode][ref].as_int; - if (num_4x4_blocks_high > 1) - bsi->rdstat[block + 2][mode_idx].mvs[ref].as_int = - mode_mv[this_mode][ref].as_int; - } - - // Trap vectors that reach beyond the UMV borders - if (mv_check_bounds(&x->mv_limits, &mode_mv[this_mode][0].as_mv) || - (has_second_rf && - mv_check_bounds(&x->mv_limits, &mode_mv[this_mode][1].as_mv))) - continue; - - if (filter_idx > 0) { - BEST_SEG_INFO *ref_bsi = bsi_buf; - subpelmv = 0; - have_ref = 1; - - for (ref = 0; ref < 1 + has_second_rf; ++ref) { - subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv); - have_ref &= mode_mv[this_mode][ref].as_int == - ref_bsi->rdstat[block][mode_idx].mvs[ref].as_int; - } - - if (filter_idx > 1 && !subpelmv && !have_ref) { - ref_bsi = bsi_buf + 1; - have_ref = 1; - for (ref = 0; ref < 1 + has_second_rf; ++ref) - have_ref &= mode_mv[this_mode][ref].as_int == - ref_bsi->rdstat[block][mode_idx].mvs[ref].as_int; - } - - if (!subpelmv && have_ref && - ref_bsi->rdstat[block][mode_idx].brdcost < INT64_MAX) { - memcpy(&bsi->rdstat[block][mode_idx], - &ref_bsi->rdstat[block][mode_idx], sizeof(SEG_RDSTAT)); - if (num_4x4_blocks_wide > 1) - bsi->rdstat[block + 1][mode_idx].eobs = - ref_bsi->rdstat[block + 1][mode_idx].eobs; - if (num_4x4_blocks_high > 1) - bsi->rdstat[block + 2][mode_idx].eobs = - ref_bsi->rdstat[block + 2][mode_idx].eobs; - - if (bsi->rdstat[block][mode_idx].brdcost < best_rd) { - mode_selected = this_mode; - best_rd = bsi->rdstat[block][mode_idx].brdcost; - } - continue; - } - } - - bsi->rdstat[block][mode_idx].brdcost = encode_inter_mb_segment( - cpi, x, bsi->segment_rd - this_segment_rd, block, - &bsi->rdstat[block][mode_idx].byrate, - &bsi->rdstat[block][mode_idx].bdist, - &bsi->rdstat[block][mode_idx].bsse, bsi->rdstat[block][mode_idx].ta, - bsi->rdstat[block][mode_idx].tl, mi_row, mi_col); - if (bsi->rdstat[block][mode_idx].brdcost < INT64_MAX) { - bsi->rdstat[block][mode_idx].brdcost += RDCOST( - x->rdmult, x->rddiv, bsi->rdstat[block][mode_idx].brate, 0); - bsi->rdstat[block][mode_idx].brate += - bsi->rdstat[block][mode_idx].byrate; - bsi->rdstat[block][mode_idx].eobs = p->eobs[block]; - if (num_4x4_blocks_wide > 1) - bsi->rdstat[block + 1][mode_idx].eobs = p->eobs[block + 1]; - if (num_4x4_blocks_high > 1) - bsi->rdstat[block + 2][mode_idx].eobs = p->eobs[block + 2]; - } - - if (bsi->rdstat[block][mode_idx].brdcost < best_rd) { - mode_selected = this_mode; - best_rd = bsi->rdstat[block][mode_idx].brdcost; - } - } /*for each 4x4 mode*/ - - if (best_rd == INT64_MAX) { - int iy, midx; - for (iy = block + 1; iy < 4; ++iy) - for (midx = 0; midx < INTER_MODES; ++midx) - bsi->rdstat[iy][midx].brdcost = INT64_MAX; - bsi->segment_rd = INT64_MAX; - return INT64_MAX; - } - - mode_idx = INTER_OFFSET(mode_selected); - memcpy(t_above, bsi->rdstat[block][mode_idx].ta, sizeof(t_above)); - memcpy(t_left, bsi->rdstat[block][mode_idx].tl, sizeof(t_left)); - - set_and_cost_bmi_mvs(cpi, x, xd, block, mode_selected, - mode_mv[mode_selected], frame_mv, seg_mvs[block], - bsi->ref_mv, x->nmvjointcost, x->mvcost); - - br += bsi->rdstat[block][mode_idx].brate; - bd += bsi->rdstat[block][mode_idx].bdist; - block_sse += bsi->rdstat[block][mode_idx].bsse; - segmentyrate += bsi->rdstat[block][mode_idx].byrate; - this_segment_rd += bsi->rdstat[block][mode_idx].brdcost; - - if (this_segment_rd > bsi->segment_rd) { - int iy, midx; - for (iy = block + 1; iy < 4; ++iy) - for (midx = 0; midx < INTER_MODES; ++midx) - bsi->rdstat[iy][midx].brdcost = INT64_MAX; - bsi->segment_rd = INT64_MAX; - return INT64_MAX; - } - } - } /* for each label */ - - bsi->r = br; - bsi->d = bd; - bsi->segment_yrate = segmentyrate; - bsi->segment_rd = this_segment_rd; - bsi->sse = block_sse; - - // update the coding decisions - for (k = 0; k < 4; ++k) bsi->modes[k] = mi->bmi[k].as_mode; - - if (bsi->segment_rd > best_rd_so_far) return INT64_MAX; - /* set it to the best */ - for (i = 0; i < 4; i++) { - mode_idx = INTER_OFFSET(bsi->modes[i]); - mi->bmi[i].as_mv[0].as_int = bsi->rdstat[i][mode_idx].mvs[0].as_int; - if (has_second_ref(mi)) - mi->bmi[i].as_mv[1].as_int = bsi->rdstat[i][mode_idx].mvs[1].as_int; - x->plane[0].eobs[i] = bsi->rdstat[i][mode_idx].eobs; - mi->bmi[i].as_mode = bsi->modes[i]; - } - - /* - * used to set mbmi->mv.as_int - */ - *returntotrate = bsi->r; - *returndistortion = bsi->d; - *returnyrate = bsi->segment_yrate; - *skippable = vp9_is_skippable_in_plane(x, BLOCK_8X8, 0); - *psse = bsi->sse; - mi->mode = bsi->modes[3]; - - return bsi->segment_rd; -} - -static void estimate_ref_frame_costs(const VP9_COMMON *cm, - const MACROBLOCKD *xd, int segment_id, - unsigned int *ref_costs_single, - unsigned int *ref_costs_comp, - vpx_prob *comp_mode_p) { - int seg_ref_active = - segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME); - if (seg_ref_active) { - memset(ref_costs_single, 0, MAX_REF_FRAMES * sizeof(*ref_costs_single)); - memset(ref_costs_comp, 0, MAX_REF_FRAMES * sizeof(*ref_costs_comp)); - *comp_mode_p = 128; - } else { - vpx_prob intra_inter_p = vp9_get_intra_inter_prob(cm, xd); - vpx_prob comp_inter_p = 128; - - if (cm->reference_mode == REFERENCE_MODE_SELECT) { - comp_inter_p = vp9_get_reference_mode_prob(cm, xd); - *comp_mode_p = comp_inter_p; - } else { - *comp_mode_p = 128; - } - - ref_costs_single[INTRA_FRAME] = vp9_cost_bit(intra_inter_p, 0); - - if (cm->reference_mode != COMPOUND_REFERENCE) { - vpx_prob ref_single_p1 = vp9_get_pred_prob_single_ref_p1(cm, xd); - vpx_prob ref_single_p2 = vp9_get_pred_prob_single_ref_p2(cm, xd); - unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1); - - if (cm->reference_mode == REFERENCE_MODE_SELECT) - base_cost += vp9_cost_bit(comp_inter_p, 0); - - ref_costs_single[LAST_FRAME] = ref_costs_single[GOLDEN_FRAME] = - ref_costs_single[ALTREF_FRAME] = base_cost; - ref_costs_single[LAST_FRAME] += vp9_cost_bit(ref_single_p1, 0); - ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p1, 1); - ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p1, 1); - ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p2, 0); - ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p2, 1); - } else { - ref_costs_single[LAST_FRAME] = 512; - ref_costs_single[GOLDEN_FRAME] = 512; - ref_costs_single[ALTREF_FRAME] = 512; - } - if (cm->reference_mode != SINGLE_REFERENCE) { - vpx_prob ref_comp_p = vp9_get_pred_prob_comp_ref_p(cm, xd); - unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1); - - if (cm->reference_mode == REFERENCE_MODE_SELECT) - base_cost += vp9_cost_bit(comp_inter_p, 1); - - ref_costs_comp[LAST_FRAME] = base_cost + vp9_cost_bit(ref_comp_p, 0); - ref_costs_comp[GOLDEN_FRAME] = base_cost + vp9_cost_bit(ref_comp_p, 1); - } else { - ref_costs_comp[LAST_FRAME] = 512; - ref_costs_comp[GOLDEN_FRAME] = 512; - } - } -} - -static void store_coding_context( - MACROBLOCK *x, PICK_MODE_CONTEXT *ctx, int mode_index, - int64_t comp_pred_diff[REFERENCE_MODES], - int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS], int skippable) { - MACROBLOCKD *const xd = &x->e_mbd; - - // Take a snapshot of the coding context so it can be - // restored if we decide to encode this way - ctx->skip = x->skip; - ctx->skippable = skippable; - ctx->best_mode_index = mode_index; - ctx->mic = *xd->mi[0]; - ctx->mbmi_ext = *x->mbmi_ext; - ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE]; - ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE]; - ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT]; - - memcpy(ctx->best_filter_diff, best_filter_diff, - sizeof(*best_filter_diff) * SWITCHABLE_FILTER_CONTEXTS); -} - -static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x, - MV_REFERENCE_FRAME ref_frame, - BLOCK_SIZE block_size, int mi_row, int mi_col, - int_mv frame_nearest_mv[MAX_REF_FRAMES], - int_mv frame_near_mv[MAX_REF_FRAMES], - struct buf_2d yv12_mb[4][MAX_MB_PLANE]) { - const VP9_COMMON *cm = &cpi->common; - const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame); - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame]; - const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf; - MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext; - - assert(yv12 != NULL); - - // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this - // use the UV scaling factors. - vp9_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf); - - // Gets an initial list of candidate vectors from neighbours and orders them - vp9_find_mv_refs(cm, xd, mi, ref_frame, candidates, mi_row, mi_col, - mbmi_ext->mode_context); - - // Candidate refinement carried out at encoder and decoder - vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv, candidates, - &frame_nearest_mv[ref_frame], - &frame_near_mv[ref_frame]); - - // Further refinement that is encode side only to test the top few candidates - // in full and choose the best as the centre point for subsequent searches. - // The current implementation doesn't support scaling. - if (!vp9_is_scaled(sf) && block_size >= BLOCK_8X8) - vp9_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame, - block_size); -} - -#if CONFIG_NON_GREEDY_MV -static int ref_frame_to_gf_rf_idx(int ref_frame) { - if (ref_frame == GOLDEN_FRAME) { - return 0; - } - if (ref_frame == LAST_FRAME) { - return 1; - } - if (ref_frame == ALTREF_FRAME) { - return 2; - } - assert(0); - return -1; -} -#endif - -static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, - int mi_row, int mi_col, int_mv *tmp_mv, - int *rate_mv) { - MACROBLOCKD *xd = &x->e_mbd; - const VP9_COMMON *cm = &cpi->common; - MODE_INFO *mi = xd->mi[0]; - struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0 } }; - int step_param; - MV mvp_full; - int ref = mi->ref_frame[0]; - MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv; - const MvLimits tmp_mv_limits = x->mv_limits; - int cost_list[5]; - const int best_predmv_idx = x->mv_best_ref_index[ref]; - const YV12_BUFFER_CONFIG *scaled_ref_frame = - vp9_get_scaled_ref_frame(cpi, ref); - const int pw = num_4x4_blocks_wide_lookup[bsize] << 2; - const int ph = num_4x4_blocks_high_lookup[bsize] << 2; - MV pred_mv[3]; - - int bestsme = INT_MAX; -#if CONFIG_NON_GREEDY_MV - int gf_group_idx = cpi->twopass.gf_group.index; - int gf_rf_idx = ref_frame_to_gf_rf_idx(ref); - BLOCK_SIZE square_bsize = get_square_block_size(bsize); - int_mv nb_full_mvs[NB_MVS_NUM] = { 0 }; - MotionField *motion_field = vp9_motion_field_info_get_motion_field( - &cpi->motion_field_info, gf_group_idx, gf_rf_idx, square_bsize); - const int nb_full_mv_num = - vp9_prepare_nb_full_mvs(motion_field, mi_row, mi_col, nb_full_mvs); - const int lambda = (pw * ph) / 4; - assert(pw * ph == lambda << 2); -#else // CONFIG_NON_GREEDY_MV - int sadpb = x->sadperbit16; -#endif // CONFIG_NON_GREEDY_MV - - pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv; - pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv; - pred_mv[2] = x->pred_mv[ref]; - - if (scaled_ref_frame) { - int i; - // Swap out the reference frame for a version that's been scaled to - // match the resolution of the current frame, allowing the existing - // motion search code to be used without additional modifications. - for (i = 0; i < MAX_MB_PLANE; i++) backup_yv12[i] = xd->plane[i].pre[0]; - - vp9_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL); - } - - // Work out the size of the first step in the mv step search. - // 0 here is maximum length first step. 1 is VPXMAX >> 1 etc. - if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) { - // Take wtd average of the step_params based on the last frame's - // max mv magnitude and that based on the best ref mvs of the current - // block for the given reference. - step_param = - (vp9_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) / - 2; - } else { - step_param = cpi->mv_step_param; - } - - if (cpi->sf.adaptive_motion_search && bsize < BLOCK_64X64) { - const int boffset = - 2 * (b_width_log2_lookup[BLOCK_64X64] - - VPXMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize])); - step_param = VPXMAX(step_param, boffset); - } - - if (cpi->sf.adaptive_motion_search) { - int bwl = b_width_log2_lookup[bsize]; - int bhl = b_height_log2_lookup[bsize]; - int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4); - - if (tlevel < 5) step_param += 2; - - // prev_mv_sad is not setup for dynamically scaled frames. - if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) { - int i; - for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) { - if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) { - x->pred_mv[ref].row = INT16_MAX; - x->pred_mv[ref].col = INT16_MAX; - tmp_mv->as_int = INVALID_MV; - - if (scaled_ref_frame) { - int j; - for (j = 0; j < MAX_MB_PLANE; ++j) - xd->plane[j].pre[0] = backup_yv12[j]; - } - return; - } - } - } - } - - // Note: MV limits are modified here. Always restore the original values - // after full-pixel motion search. - vp9_set_mv_search_range(&x->mv_limits, &ref_mv); - - mvp_full = pred_mv[best_predmv_idx]; - mvp_full.col >>= 3; - mvp_full.row >>= 3; - -#if CONFIG_NON_GREEDY_MV - bestsme = vp9_full_pixel_diamond_new(cpi, x, bsize, &mvp_full, step_param, - lambda, 1, nb_full_mvs, nb_full_mv_num, - &tmp_mv->as_mv); -#else // CONFIG_NON_GREEDY_MV - bestsme = vp9_full_pixel_search( - cpi, x, bsize, &mvp_full, step_param, cpi->sf.mv.search_method, sadpb, - cond_cost_list(cpi, cost_list), &ref_mv, &tmp_mv->as_mv, INT_MAX, 1); -#endif // CONFIG_NON_GREEDY_MV - - if (cpi->sf.enhanced_full_pixel_motion_search) { - int i; - for (i = 0; i < 3; ++i) { - int this_me; - MV this_mv; - int diff_row; - int diff_col; - int step; - - if (pred_mv[i].row == INT16_MAX || pred_mv[i].col == INT16_MAX) continue; - if (i == best_predmv_idx) continue; - - diff_row = ((int)pred_mv[i].row - - pred_mv[i > 0 ? (i - 1) : best_predmv_idx].row) >> - 3; - diff_col = ((int)pred_mv[i].col - - pred_mv[i > 0 ? (i - 1) : best_predmv_idx].col) >> - 3; - if (diff_row == 0 && diff_col == 0) continue; - if (diff_row < 0) diff_row = -diff_row; - if (diff_col < 0) diff_col = -diff_col; - step = get_msb((diff_row + diff_col + 1) >> 1); - if (step <= 0) continue; - - mvp_full = pred_mv[i]; - mvp_full.col >>= 3; - mvp_full.row >>= 3; -#if CONFIG_NON_GREEDY_MV - this_me = vp9_full_pixel_diamond_new( - cpi, x, bsize, &mvp_full, - VPXMAX(step_param, MAX_MVSEARCH_STEPS - step), lambda, 1, nb_full_mvs, - nb_full_mv_num, &this_mv); -#else // CONFIG_NON_GREEDY_MV - this_me = vp9_full_pixel_search( - cpi, x, bsize, &mvp_full, - VPXMAX(step_param, MAX_MVSEARCH_STEPS - step), - cpi->sf.mv.search_method, sadpb, cond_cost_list(cpi, cost_list), - &ref_mv, &this_mv, INT_MAX, 1); -#endif // CONFIG_NON_GREEDY_MV - if (this_me < bestsme) { - tmp_mv->as_mv = this_mv; - bestsme = this_me; - } - } - } - - x->mv_limits = tmp_mv_limits; - - if (bestsme < INT_MAX) { - uint32_t dis; /* TODO: use dis in distortion calculation later. */ - cpi->find_fractional_mv_step( - x, &tmp_mv->as_mv, &ref_mv, cm->allow_high_precision_mv, x->errorperbit, - &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop, - cpi->sf.mv.subpel_search_level, cond_cost_list(cpi, cost_list), - x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, pw, ph, - cpi->sf.use_accurate_subpel_search); - } - *rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost, - x->mvcost, MV_COST_WEIGHT); - - x->pred_mv[ref] = tmp_mv->as_mv; - - if (scaled_ref_frame) { - int i; - for (i = 0; i < MAX_MB_PLANE; i++) xd->plane[i].pre[0] = backup_yv12[i]; - } -} - -static INLINE void restore_dst_buf(MACROBLOCKD *xd, - uint8_t *orig_dst[MAX_MB_PLANE], - int orig_dst_stride[MAX_MB_PLANE]) { - int i; - for (i = 0; i < MAX_MB_PLANE; i++) { - xd->plane[i].dst.buf = orig_dst[i]; - xd->plane[i].dst.stride = orig_dst_stride[i]; - } -} - -// In some situations we want to discount tha pparent cost of a new motion -// vector. Where there is a subtle motion field and especially where there is -// low spatial complexity then it can be hard to cover the cost of a new motion -// vector in a single block, even if that motion vector reduces distortion. -// However, once established that vector may be usable through the nearest and -// near mv modes to reduce distortion in subsequent blocks and also improve -// visual quality. -static int discount_newmv_test(VP9_COMP *cpi, int this_mode, int_mv this_mv, - int_mv (*mode_mv)[MAX_REF_FRAMES], int ref_frame, - int mi_row, int mi_col, BLOCK_SIZE bsize) { -#if CONFIG_NON_GREEDY_MV - (void)mode_mv; - (void)this_mv; - if (this_mode == NEWMV && bsize >= BLOCK_8X8 && cpi->tpl_ready) { - const int gf_group_idx = cpi->twopass.gf_group.index; - const int gf_rf_idx = ref_frame_to_gf_rf_idx(ref_frame); - const TplDepFrame tpl_frame = cpi->tpl_stats[gf_group_idx]; - const MotionField *motion_field = vp9_motion_field_info_get_motion_field( - &cpi->motion_field_info, gf_group_idx, gf_rf_idx, cpi->tpl_bsize); - const int tpl_block_mi_h = num_8x8_blocks_high_lookup[cpi->tpl_bsize]; - const int tpl_block_mi_w = num_8x8_blocks_wide_lookup[cpi->tpl_bsize]; - const int tpl_mi_row = mi_row - (mi_row % tpl_block_mi_h); - const int tpl_mi_col = mi_col - (mi_col % tpl_block_mi_w); - const int mv_mode = - tpl_frame - .mv_mode_arr[gf_rf_idx][tpl_mi_row * tpl_frame.stride + tpl_mi_col]; - if (mv_mode == NEW_MV_MODE) { - int_mv tpl_new_mv = - vp9_motion_field_mi_get_mv(motion_field, tpl_mi_row, tpl_mi_col); - int row_diff = abs(tpl_new_mv.as_mv.row - this_mv.as_mv.row); - int col_diff = abs(tpl_new_mv.as_mv.col - this_mv.as_mv.col); - if (VPXMAX(row_diff, col_diff) <= 8) { - return 1; - } else { - return 0; - } - } else { - return 0; - } - } else { - return 0; - } -#else - (void)mi_row; - (void)mi_col; - (void)bsize; - return (!cpi->rc.is_src_frame_alt_ref && (this_mode == NEWMV) && - (this_mv.as_int != 0) && - ((mode_mv[NEARESTMV][ref_frame].as_int == 0) || - (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) && - ((mode_mv[NEARMV][ref_frame].as_int == 0) || - (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV))); -#endif -} - -static int64_t handle_inter_mode( - VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int *rate2, - int64_t *distortion, int *skippable, int *rate_y, int *rate_uv, - struct buf_2d *recon, int *disable_skip, int_mv (*mode_mv)[MAX_REF_FRAMES], - int mi_row, int mi_col, int_mv single_newmv[MAX_REF_FRAMES], - INTERP_FILTER (*single_filter)[MAX_REF_FRAMES], - int (*single_skippable)[MAX_REF_FRAMES], int *single_mode_rate, - int64_t *psse, const int64_t ref_best_rd, int64_t *mask_filter, - int64_t filter_cache[], int best_mode_index) { - VP9_COMMON *cm = &cpi->common; - MACROBLOCKD *xd = &x->e_mbd; - MODE_INFO *mi = xd->mi[0]; - MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext; - const int is_comp_pred = has_second_ref(mi); - const int this_mode = mi->mode; - int_mv *frame_mv = mode_mv[this_mode]; - int i; - int refs[2] = { mi->ref_frame[0], - (mi->ref_frame[1] < 0 ? 0 : mi->ref_frame[1]) }; - int_mv cur_mv[2]; -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, tmp_buf16[MAX_MB_PLANE * 64 * 64]); - uint8_t *tmp_buf; -#else - DECLARE_ALIGNED(16, uint8_t, tmp_buf[MAX_MB_PLANE * 64 * 64]); -#endif // CONFIG_VP9_HIGHBITDEPTH - int intpel_mv; - int64_t rd, tmp_rd = INT64_MAX, best_rd = INT64_MAX; - int best_needs_copy = 0; - uint8_t *orig_dst[MAX_MB_PLANE]; - int orig_dst_stride[MAX_MB_PLANE]; - int rs = 0; - INTERP_FILTER best_filter = SWITCHABLE; - uint8_t skip_txfm[MAX_MB_PLANE << 2] = { 0 }; - int64_t bsse[MAX_MB_PLANE << 2] = { 0 }; - - const int bsl = mi_width_log2_lookup[bsize]; - const int blk_parity = (((mi_row + mi_col) >> bsl) + - get_chessboard_index(cm->current_video_frame)) & - 0x1; - const int pred_filter_search = - (cpi->sf.cb_pred_filter_search >= 2) && blk_parity; - - int skip_txfm_sb = 0; - int64_t skip_sse_sb = INT64_MAX; - int64_t distortion_y = 0, distortion_uv = 0; - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf16); - } else { - tmp_buf = (uint8_t *)tmp_buf16; - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - if (pred_filter_search) { - INTERP_FILTER af = SWITCHABLE, lf = SWITCHABLE; - if (xd->above_mi && is_inter_block(xd->above_mi)) - af = xd->above_mi->interp_filter; - if (xd->left_mi && is_inter_block(xd->left_mi)) - lf = xd->left_mi->interp_filter; - - if ((this_mode != NEWMV) || (af == lf)) best_filter = af; - } - - if (is_comp_pred) { - if (frame_mv[refs[0]].as_int == INVALID_MV || - frame_mv[refs[1]].as_int == INVALID_MV) - return INT64_MAX; - - if (cpi->sf.adaptive_mode_search) { - if (single_filter[this_mode][refs[0]] == - single_filter[this_mode][refs[1]]) - best_filter = single_filter[this_mode][refs[0]]; - } - } - - if (this_mode == NEWMV) { - int rate_mv; - if (is_comp_pred) { - // Decide number of joint motion search iterations - const int num_joint_search_iters = get_joint_search_iters( - cpi->sf.comp_inter_joint_search_iter_level, bsize); - - // Initialize mv using single prediction mode result. - frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int; - frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int; - - if (num_joint_search_iters) { -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, joint_motion_search_time); -#endif - joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, - single_newmv, &rate_mv, num_joint_search_iters); -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, joint_motion_search_time); -#endif - } else { - rate_mv = vp9_mv_bit_cost(&frame_mv[refs[0]].as_mv, - &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv, - x->nmvjointcost, x->mvcost, MV_COST_WEIGHT); - rate_mv += vp9_mv_bit_cost(&frame_mv[refs[1]].as_mv, - &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv, - x->nmvjointcost, x->mvcost, MV_COST_WEIGHT); - } - *rate2 += rate_mv; - } else { - int_mv tmp_mv; -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, single_motion_search_time); -#endif - single_motion_search(cpi, x, bsize, mi_row, mi_col, &tmp_mv, &rate_mv); -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, single_motion_search_time); -#endif - if (tmp_mv.as_int == INVALID_MV) return INT64_MAX; - - frame_mv[refs[0]].as_int = xd->mi[0]->bmi[0].as_mv[0].as_int = - tmp_mv.as_int; - single_newmv[refs[0]].as_int = tmp_mv.as_int; - - // Estimate the rate implications of a new mv but discount this - // under certain circumstances where we want to help initiate a weak - // motion field, where the distortion gain for a single block may not - // be enough to overcome the cost of a new mv. - if (discount_newmv_test(cpi, this_mode, tmp_mv, mode_mv, refs[0], mi_row, - mi_col, bsize)) { - *rate2 += VPXMAX((rate_mv / NEW_MV_DISCOUNT_FACTOR), 1); - } else { - *rate2 += rate_mv; - } - } - } - - for (i = 0; i < is_comp_pred + 1; ++i) { - cur_mv[i] = frame_mv[refs[i]]; - // Clip "next_nearest" so that it does not extend to far out of image - if (this_mode != NEWMV) clamp_mv2(&cur_mv[i].as_mv, xd); - - if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX; - mi->mv[i].as_int = cur_mv[i].as_int; - } - - // do first prediction into the destination buffer. Do the next - // prediction into a temporary buffer. Then keep track of which one - // of these currently holds the best predictor, and use the other - // one for future predictions. In the end, copy from tmp_buf to - // dst if necessary. - for (i = 0; i < MAX_MB_PLANE; i++) { - orig_dst[i] = xd->plane[i].dst.buf; - orig_dst_stride[i] = xd->plane[i].dst.stride; - } - - // We don't include the cost of the second reference here, because there - // are only two options: Last/ARF or Golden/ARF; The second one is always - // known, which is ARF. - // - // Under some circumstances we discount the cost of new mv mode to encourage - // initiation of a motion field. - if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]], mode_mv, refs[0], - mi_row, mi_col, bsize)) { - *rate2 += - VPXMIN(cost_mv_ref(cpi, this_mode, mbmi_ext->mode_context[refs[0]]), - cost_mv_ref(cpi, NEARESTMV, mbmi_ext->mode_context[refs[0]])); - } else { - *rate2 += cost_mv_ref(cpi, this_mode, mbmi_ext->mode_context[refs[0]]); - } - - if (!is_comp_pred && cpi->sf.prune_single_mode_based_on_mv_diff_mode_rate) { - single_mode_rate[INTER_OFFSET(this_mode)] = *rate2; - // Prune NEARMV and ZEROMV modes based on motion vector difference and mode - // rate. - if (skip_single_mode_based_on_mode_rate(mode_mv, single_mode_rate, - this_mode, refs[0], *rate2, - best_mode_index)) { - // Check when the single inter mode is pruned, NEARESTMV or NEWMV modes - // are not early terminated. This ensures all single modes are not getting - // skipped when the speed feature is enabled. - assert(single_mode_rate[INTER_OFFSET(NEARESTMV)] != INT_MAX || - single_mode_rate[INTER_OFFSET(NEWMV)] != INT_MAX); - return INT64_MAX; - } - } - if (RDCOST(x->rdmult, x->rddiv, *rate2, 0) > ref_best_rd && - mi->mode != NEARESTMV) - return INT64_MAX; - - // Are all MVs integer pel for Y and UV - intpel_mv = !mv_has_subpel(&mi->mv[0].as_mv); - if (is_comp_pred) intpel_mv &= !mv_has_subpel(&mi->mv[1].as_mv); - -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, interp_filter_time); -#endif - // Search for best switchable filter by checking the variance of - // pred error irrespective of whether the filter will be used - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) filter_cache[i] = INT64_MAX; - - if (cm->interp_filter != BILINEAR) { - // Use cb pattern for filter eval when filter is not switchable - const int enable_interp_search = - (cpi->sf.cb_pred_filter_search && cm->interp_filter != SWITCHABLE) - ? blk_parity - : 1; - if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) { - best_filter = EIGHTTAP; - } else if (best_filter == SWITCHABLE && enable_interp_search) { - int newbest; - int tmp_rate_sum = 0; - int64_t tmp_dist_sum = 0; - - for (i = 0; i < SWITCHABLE_FILTERS; ++i) { - int j; - int64_t rs_rd; - int tmp_skip_sb = 0; - int64_t tmp_skip_sse = INT64_MAX; - const int enable_earlyterm = - cpi->sf.early_term_interp_search_plane_rd && cm->interp_filter != i; - int64_t filt_best_rd; - - mi->interp_filter = i; - rs = vp9_get_switchable_rate(cpi, xd); - rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0); - - if (i > 0 && intpel_mv) { - rd = RDCOST(x->rdmult, x->rddiv, tmp_rate_sum, tmp_dist_sum); - filter_cache[i] = rd; - filter_cache[SWITCHABLE_FILTERS] = - VPXMIN(filter_cache[SWITCHABLE_FILTERS], rd + rs_rd); - if (cm->interp_filter == SWITCHABLE) rd += rs_rd; - *mask_filter = VPXMAX(*mask_filter, rd); - } else { - int rate_sum = 0; - int64_t dist_sum = 0; - if (i > 0 && cpi->sf.adaptive_interp_filter_search && - (cpi->sf.interp_filter_search_mask & (1 << i))) { - rate_sum = INT_MAX; - dist_sum = INT64_MAX; - continue; - } - - if ((cm->interp_filter == SWITCHABLE && (!i || best_needs_copy)) || - (cm->interp_filter != SWITCHABLE && - (cm->interp_filter == mi->interp_filter || - (i == 0 && intpel_mv)))) { - restore_dst_buf(xd, orig_dst, orig_dst_stride); - } else { - for (j = 0; j < MAX_MB_PLANE; j++) { - xd->plane[j].dst.buf = tmp_buf + j * 64 * 64; - xd->plane[j].dst.stride = 64; - } - } - - filt_best_rd = - cm->interp_filter == SWITCHABLE ? (best_rd - rs_rd) : best_rd; - if (build_inter_pred_model_rd_earlyterm( - cpi, mi_row, mi_col, bsize, x, xd, &rate_sum, &dist_sum, - &tmp_skip_sb, &tmp_skip_sse, enable_earlyterm, - filt_best_rd)) { - filter_cache[i] = INT64_MAX; - continue; - } - - rd = RDCOST(x->rdmult, x->rddiv, rate_sum, dist_sum); - filter_cache[i] = rd; - filter_cache[SWITCHABLE_FILTERS] = - VPXMIN(filter_cache[SWITCHABLE_FILTERS], rd + rs_rd); - if (cm->interp_filter == SWITCHABLE) rd += rs_rd; - *mask_filter = VPXMAX(*mask_filter, rd); - - if (i == 0 && intpel_mv) { - tmp_rate_sum = rate_sum; - tmp_dist_sum = dist_sum; - } - } - - if (i == 0 && cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) { - if (rd / 2 > ref_best_rd) { - restore_dst_buf(xd, orig_dst, orig_dst_stride); - return INT64_MAX; - } - } - newbest = i == 0 || rd < best_rd; - - if (newbest) { - best_rd = rd; - best_filter = mi->interp_filter; - if (cm->interp_filter == SWITCHABLE && i && !intpel_mv) - best_needs_copy = !best_needs_copy; - } - - if ((cm->interp_filter == SWITCHABLE && newbest) || - (cm->interp_filter != SWITCHABLE && - cm->interp_filter == mi->interp_filter)) { - tmp_rd = best_rd; - - skip_txfm_sb = tmp_skip_sb; - skip_sse_sb = tmp_skip_sse; - memcpy(skip_txfm, x->skip_txfm, sizeof(skip_txfm)); - memcpy(bsse, x->bsse, sizeof(bsse)); - } - } - restore_dst_buf(xd, orig_dst, orig_dst_stride); - } - } -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, interp_filter_time); -#endif - // Set the appropriate filter - mi->interp_filter = - cm->interp_filter != SWITCHABLE ? cm->interp_filter : best_filter; - rs = cm->interp_filter == SWITCHABLE ? vp9_get_switchable_rate(cpi, xd) : 0; - - if (tmp_rd != INT64_MAX) { - if (best_needs_copy) { - // again temporarily set the buffers to local memory to prevent a memcpy - for (i = 0; i < MAX_MB_PLANE; i++) { - xd->plane[i].dst.buf = tmp_buf + i * 64 * 64; - xd->plane[i].dst.stride = 64; - } - } - rd = tmp_rd + RDCOST(x->rdmult, x->rddiv, rs, 0); - } else { - int tmp_rate; - int64_t tmp_dist; - // Handles the special case when a filter that is not in the - // switchable list (ex. bilinear) is indicated at the frame level, or - // skip condition holds. - build_inter_pred_model_rd_earlyterm( - cpi, mi_row, mi_col, bsize, x, xd, &tmp_rate, &tmp_dist, &skip_txfm_sb, - &skip_sse_sb, 0 /*do_earlyterm*/, INT64_MAX); - rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist); - memcpy(skip_txfm, x->skip_txfm, sizeof(skip_txfm)); - memcpy(bsse, x->bsse, sizeof(bsse)); - } - - if (!is_comp_pred) single_filter[this_mode][refs[0]] = mi->interp_filter; - - if (cpi->sf.adaptive_mode_search) - if (is_comp_pred) - if (single_skippable[this_mode][refs[0]] && - single_skippable[this_mode][refs[1]]) - memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm)); - - if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) { - // if current pred_error modeled rd is substantially more than the best - // so far, do not bother doing full rd - if (rd / 2 > ref_best_rd) { - restore_dst_buf(xd, orig_dst, orig_dst_stride); - return INT64_MAX; - } - } - - if (cm->interp_filter == SWITCHABLE) *rate2 += rs; - - memcpy(x->skip_txfm, skip_txfm, sizeof(skip_txfm)); - memcpy(x->bsse, bsse, sizeof(bsse)); - - if (!skip_txfm_sb || xd->lossless) { - int skippable_y, skippable_uv; - int64_t sseuv = INT64_MAX; - int64_t rdcosty = INT64_MAX; - - // Y cost and distortion - vp9_subtract_plane(x, bsize, 0); - super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse, bsize, - ref_best_rd, recon); - - if (*rate_y == INT_MAX) { - *rate2 = INT_MAX; - *distortion = INT64_MAX; - restore_dst_buf(xd, orig_dst, orig_dst_stride); - return INT64_MAX; - } - - *rate2 += *rate_y; - *distortion += distortion_y; - - rdcosty = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion); - rdcosty = VPXMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, *psse)); - - if (!super_block_uvrd(cpi, x, rate_uv, &distortion_uv, &skippable_uv, - &sseuv, bsize, ref_best_rd - rdcosty)) { - *rate2 = INT_MAX; - *distortion = INT64_MAX; - restore_dst_buf(xd, orig_dst, orig_dst_stride); - return INT64_MAX; - } - - *psse += sseuv; - *rate2 += *rate_uv; - *distortion += distortion_uv; - *skippable = skippable_y && skippable_uv; - } else { - x->skip = 1; - *disable_skip = 1; - - // The cost of skip bit needs to be added. - *rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1); - - *distortion = skip_sse_sb; - } - - if (!is_comp_pred) single_skippable[this_mode][refs[0]] = *skippable; - - restore_dst_buf(xd, orig_dst, orig_dst_stride); - return 0; // The rate-distortion cost will be re-calculated by caller. -} -#endif // !CONFIG_REALTIME_ONLY - -void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, RD_COST *rd_cost, - BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx, - int64_t best_rd) { - VP9_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &x->e_mbd; - struct macroblockd_plane *const pd = xd->plane; - int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0; - int y_skip = 0, uv_skip = 0; - int64_t dist_y = 0, dist_uv = 0; - TX_SIZE max_uv_tx_size; - x->skip_encode = 0; - ctx->skip = 0; - xd->mi[0]->ref_frame[0] = INTRA_FRAME; - xd->mi[0]->ref_frame[1] = NO_REF_FRAME; - // Initialize interp_filter here so we do not have to check for inter block - // modes in get_pred_context_switchable_interp() - xd->mi[0]->interp_filter = SWITCHABLE_FILTERS; - - if (bsize >= BLOCK_8X8) { - if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y, - &y_skip, bsize, best_rd) >= best_rd) { - rd_cost->rate = INT_MAX; - return; - } - } else { - y_skip = 0; - if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly, - &dist_y, best_rd) >= best_rd) { - rd_cost->rate = INT_MAX; - return; - } - } - max_uv_tx_size = uv_txsize_lookup[bsize][xd->mi[0]->tx_size] - [pd[1].subsampling_x][pd[1].subsampling_y]; - rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly, &dist_uv, - &uv_skip, VPXMAX(BLOCK_8X8, bsize), max_uv_tx_size); - - if (y_skip && uv_skip) { - rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly + - vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1); - rd_cost->dist = dist_y + dist_uv; - } else { - rd_cost->rate = - rate_y + rate_uv + vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0); - rd_cost->dist = dist_y + dist_uv; - } - - ctx->mic = *xd->mi[0]; - ctx->mbmi_ext = *x->mbmi_ext; - rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist); -} - -#if !CONFIG_REALTIME_ONLY -// This function is designed to apply a bias or adjustment to an rd value based -// on the relative variance of the source and reconstruction. -#define LOW_VAR_THRESH 250 -#define VAR_MULT 250 -static unsigned int max_var_adjust[VP9E_CONTENT_INVALID] = { 16, 16, 250 }; - -static void rd_variance_adjustment(VP9_COMP *cpi, MACROBLOCK *x, - BLOCK_SIZE bsize, int64_t *this_rd, - struct buf_2d *recon, - MV_REFERENCE_FRAME ref_frame, - MV_REFERENCE_FRAME second_ref_frame, - PREDICTION_MODE this_mode) { - MACROBLOCKD *const xd = &x->e_mbd; - unsigned int rec_variance; - unsigned int src_variance; - unsigned int src_rec_min; - unsigned int var_diff = 0; - unsigned int var_factor = 0; - unsigned int adj_max; - unsigned int low_var_thresh = LOW_VAR_THRESH; - const int bw = num_8x8_blocks_wide_lookup[bsize]; - const int bh = num_8x8_blocks_high_lookup[bsize]; - vp9e_tune_content content_type = cpi->oxcf.content; - - if (*this_rd == INT64_MAX) return; - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - rec_variance = vp9_high_get_sby_variance(cpi, recon, bsize, xd->bd); - src_variance = - vp9_high_get_sby_variance(cpi, &x->plane[0].src, bsize, xd->bd); - } else { - rec_variance = vp9_get_sby_variance(cpi, recon, bsize); - src_variance = vp9_get_sby_variance(cpi, &x->plane[0].src, bsize); - } -#else - rec_variance = vp9_get_sby_variance(cpi, recon, bsize); - src_variance = vp9_get_sby_variance(cpi, &x->plane[0].src, bsize); -#endif // CONFIG_VP9_HIGHBITDEPTH - - // Scale based on area in 8x8 blocks - rec_variance /= (bw * bh); - src_variance /= (bw * bh); - - if (content_type == VP9E_CONTENT_FILM) { - if (cpi->oxcf.pass == 2) { - // Adjust low variance threshold based on estimated group noise enegry. - double noise_factor = - (double)cpi->twopass.gf_group.group_noise_energy / SECTION_NOISE_DEF; - low_var_thresh = (unsigned int)(low_var_thresh * noise_factor); - - if (ref_frame == INTRA_FRAME) { - low_var_thresh *= 2; - if (this_mode == DC_PRED) low_var_thresh *= 5; - } else if (second_ref_frame > INTRA_FRAME) { - low_var_thresh *= 2; - } - } - } else { - low_var_thresh = LOW_VAR_THRESH / 2; - } - - // Lower of source (raw per pixel value) and recon variance. Note that - // if the source per pixel is 0 then the recon value here will not be per - // pixel (see above) so will likely be much larger. - src_rec_min = VPXMIN(src_variance, rec_variance); - - if (src_rec_min > low_var_thresh) return; - - // We care more when the reconstruction has lower variance so give this case - // a stronger weighting. - var_diff = (src_variance > rec_variance) ? (src_variance - rec_variance) * 2 - : (rec_variance - src_variance) / 2; - - adj_max = max_var_adjust[content_type]; - - var_factor = - (unsigned int)((int64_t)VAR_MULT * var_diff) / VPXMAX(1, src_variance); - var_factor = VPXMIN(adj_max, var_factor); - - if ((content_type == VP9E_CONTENT_FILM) && - ((ref_frame == INTRA_FRAME) || (second_ref_frame > INTRA_FRAME))) { - var_factor *= 2; - } - - *this_rd += (*this_rd * var_factor) / 100; - - (void)xd; -} -#endif // !CONFIG_REALTIME_ONLY - -// Do we have an internal image edge (e.g. formatting bars). -int vp9_internal_image_edge(VP9_COMP *cpi) { - return (cpi->oxcf.pass == 2) && - ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) || - (cpi->twopass.this_frame_stats.inactive_zone_cols > 0)); -} - -// Checks to see if a super block is on a horizontal image edge. -// In most cases this is the "real" edge unless there are formatting -// bars embedded in the stream. -int vp9_active_h_edge(VP9_COMP *cpi, int mi_row, int mi_step) { - int top_edge = 0; - int bottom_edge = cpi->common.mi_rows; - int is_active_h_edge = 0; - - // For two pass account for any formatting bars detected. - if (cpi->oxcf.pass == 2) { - TWO_PASS *twopass = &cpi->twopass; - vpx_clear_system_state(); - - // The inactive region is specified in MBs not mi units. - // The image edge is in the following MB row. - top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2); - - bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2); - bottom_edge = VPXMAX(top_edge, bottom_edge); - } - - if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) || - ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) { - is_active_h_edge = 1; - } - return is_active_h_edge; -} - -// Checks to see if a super block is on a vertical image edge. -// In most cases this is the "real" edge unless there are formatting -// bars embedded in the stream. -int vp9_active_v_edge(VP9_COMP *cpi, int mi_col, int mi_step) { - int left_edge = 0; - int right_edge = cpi->common.mi_cols; - int is_active_v_edge = 0; - - // For two pass account for any formatting bars detected. - if (cpi->oxcf.pass == 2) { - TWO_PASS *twopass = &cpi->twopass; - vpx_clear_system_state(); - - // The inactive region is specified in MBs not mi units. - // The image edge is in the following MB row. - left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2); - - right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2); - right_edge = VPXMAX(left_edge, right_edge); - } - - if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) || - ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) { - is_active_v_edge = 1; - } - return is_active_v_edge; -} - -// Checks to see if a super block is at the edge of the active image. -// In most cases this is the "real" edge unless there are formatting -// bars embedded in the stream. -int vp9_active_edge_sb(VP9_COMP *cpi, int mi_row, int mi_col) { - return vp9_active_h_edge(cpi, mi_row, MI_BLOCK_SIZE) || - vp9_active_v_edge(cpi, mi_col, MI_BLOCK_SIZE); -} - -#if !CONFIG_REALTIME_ONLY -static void init_frame_mv(int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES]) { - for (int mode = 0; mode < MB_MODE_COUNT; ++mode) { - for (int ref_frame = 0; ref_frame < MAX_REF_FRAMES; ++ref_frame) { - frame_mv[mode][ref_frame].as_int = INVALID_MV; - } - } -} - -void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, TileDataEnc *tile_data, - MACROBLOCK *x, int mi_row, int mi_col, - RD_COST *rd_cost, BLOCK_SIZE bsize, - PICK_MODE_CONTEXT *ctx, int64_t best_rd_so_far) { - VP9_COMMON *const cm = &cpi->common; - TileInfo *const tile_info = &tile_data->tile_info; - RD_OPT *const rd_opt = &cpi->rd; - SPEED_FEATURES *const sf = &cpi->sf; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext; - const struct segmentation *const seg = &cm->seg; - PREDICTION_MODE this_mode; - MV_REFERENCE_FRAME ref_frame, second_ref_frame; - unsigned char segment_id = mi->segment_id; - int comp_pred, i, k; - int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES]; - struct buf_2d yv12_mb[4][MAX_MB_PLANE] = { 0 }; - int_mv single_newmv[MAX_REF_FRAMES] = { { 0 } }; - INTERP_FILTER single_inter_filter[MB_MODE_COUNT][MAX_REF_FRAMES]; - int single_skippable[MB_MODE_COUNT][MAX_REF_FRAMES]; - int single_mode_rate[MAX_REF_FRAMES][INTER_MODES]; - int64_t best_rd = best_rd_so_far; - int64_t best_pred_diff[REFERENCE_MODES]; - int64_t best_pred_rd[REFERENCE_MODES]; - int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS]; - int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS]; - MODE_INFO best_mbmode; - int best_mode_skippable = 0; - int midx, best_mode_index = -1; - unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES]; - vpx_prob comp_mode_p; - int64_t best_intra_rd = INT64_MAX; - unsigned int best_pred_sse = UINT_MAX; - PREDICTION_MODE best_intra_mode = DC_PRED; - int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES]; - int64_t dist_uv[TX_SIZES]; - int skip_uv[TX_SIZES]; - PREDICTION_MODE mode_uv[TX_SIZES]; - const int intra_cost_penalty = - vp9_get_intra_cost_penalty(cpi, bsize, cm->base_qindex, cm->y_dc_delta_q); - int best_skip2 = 0; - uint8_t ref_frame_skip_mask[2] = { 0, 1 }; - uint16_t mode_skip_mask[MAX_REF_FRAMES] = { 0 }; - int mode_skip_start = sf->mode_skip_start + 1; - const int *const rd_threshes = rd_opt->threshes[segment_id][bsize]; - const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize]; - int64_t mode_threshold[MAX_MODES]; - int8_t *tile_mode_map = tile_data->mode_map[bsize]; - int8_t mode_map[MAX_MODES]; // Maintain mode_map information locally to avoid - // lock mechanism involved with reads from - // tile_mode_map - const int mode_search_skip_flags = sf->mode_search_skip_flags; - const int is_rect_partition = - num_4x4_blocks_wide_lookup[bsize] != num_4x4_blocks_high_lookup[bsize]; - int64_t mask_filter = 0; - int64_t filter_cache[SWITCHABLE_FILTER_CONTEXTS]; - - struct buf_2d *recon; - struct buf_2d recon_buf; -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, recon16[64 * 64]); - recon_buf.buf = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH - ? CONVERT_TO_BYTEPTR(recon16) - : (uint8_t *)recon16; -#else - DECLARE_ALIGNED(16, uint8_t, recon8[64 * 64]); - recon_buf.buf = recon8; -#endif // CONFIG_VP9_HIGHBITDEPTH - recon_buf.stride = 64; - recon = cpi->oxcf.content == VP9E_CONTENT_FILM ? &recon_buf : 0; - - vp9_zero(best_mbmode); - - x->skip_encode = sf->skip_encode_frame && x->q_index < QIDX_SKIP_THRESH; - - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) filter_cache[i] = INT64_MAX; - - estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp, - &comp_mode_p); - - for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX; - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) - best_filter_rd[i] = INT64_MAX; - for (i = 0; i < TX_SIZES; i++) rate_uv_intra[i] = INT_MAX; - for (i = 0; i < MAX_REF_FRAMES; ++i) x->pred_sse[i] = INT_MAX; - for (i = 0; i < MB_MODE_COUNT; ++i) { - for (k = 0; k < MAX_REF_FRAMES; ++k) { - single_inter_filter[i][k] = SWITCHABLE; - single_skippable[i][k] = 0; - } - } - - rd_cost->rate = INT_MAX; - - init_frame_mv(frame_mv); - - for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { - x->pred_mv_sad[ref_frame] = INT_MAX; - if ((cpi->ref_frame_flags & ref_frame_to_flag(ref_frame)) && - !(is_rect_partition && (ctx->skip_ref_frame_mask & (1 << ref_frame)))) { - assert(get_ref_frame_buffer(cpi, ref_frame) != NULL); - setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col, - frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb); - } - frame_mv[NEWMV][ref_frame].as_int = INVALID_MV; - frame_mv[ZEROMV][ref_frame].as_int = 0; - } - - for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { - if (!(cpi->ref_frame_flags & ref_frame_to_flag(ref_frame))) { - // Skip checking missing references in both single and compound reference - // modes. Note that a mode will be skipped if both reference frames - // are masked out. - ref_frame_skip_mask[0] |= (1 << ref_frame); - ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK; - } else if (sf->reference_masking) { - for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) { - // Skip fixed mv modes for poor references - if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) { - mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO; - break; - } - } - } - // If the segment reference frame feature is enabled.... - // then do nothing if the current ref frame is not allowed.. - if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) && - get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) { - ref_frame_skip_mask[0] |= (1 << ref_frame); - ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK; - } - } - - // Disable this drop out case if the ref frame - // segment level feature is enabled for this segment. This is to - // prevent the possibility that we end up unable to pick any mode. - if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) { - // Only consider ZEROMV/ALTREF_FRAME for alt ref frame, - // unless ARNR filtering is enabled in which case we want - // an unfiltered alternative. We allow near/nearest as well - // because they may result in zero-zero MVs but be cheaper. - if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) { - ref_frame_skip_mask[0] = (1 << LAST_FRAME) | (1 << GOLDEN_FRAME); - ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK; - mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO; - if (frame_mv[NEARMV][ALTREF_FRAME].as_int != 0) - mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV); - if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != 0) - mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV); - } - } - - if (cpi->rc.is_src_frame_alt_ref) { - if (sf->alt_ref_search_fp) { - mode_skip_mask[ALTREF_FRAME] = 0; - ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME) & 0xff; - ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK; - } - } - - if (sf->alt_ref_search_fp) - if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX) - if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1)) - mode_skip_mask[ALTREF_FRAME] |= INTER_ALL; - - if (sf->adaptive_mode_search) { - if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref && - cpi->rc.frames_since_golden >= 3) - if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1)) - mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL; - } - - if (bsize > sf->max_intra_bsize && cpi->ref_frame_flags != 0) { - ref_frame_skip_mask[0] |= (1 << INTRA_FRAME); - ref_frame_skip_mask[1] |= (1 << INTRA_FRAME); - } - - mode_skip_mask[INTRA_FRAME] |= - (uint16_t) ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]); - - for (i = 0; i <= LAST_NEW_MV_INDEX; ++i) mode_threshold[i] = 0; - - for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i) - mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5; - - midx = sf->schedule_mode_search ? mode_skip_start : 0; - - while (midx > 4) { - uint8_t end_pos = 0; - for (i = 5; i < midx; ++i) { - if (mode_threshold[tile_mode_map[i - 1]] > - mode_threshold[tile_mode_map[i]]) { - uint8_t tmp = tile_mode_map[i]; - tile_mode_map[i] = tile_mode_map[i - 1]; - tile_mode_map[i - 1] = tmp; - end_pos = i; - } - } - midx = end_pos; - } - - memcpy(mode_map, tile_mode_map, sizeof(mode_map)); - - for (midx = 0; midx < MAX_MODES; ++midx) { - int mode_index = mode_map[midx]; - int mode_excluded = 0; - int64_t this_rd = INT64_MAX; - int disable_skip = 0; - int compmode_cost = 0; - int rate2 = 0, rate_y = 0, rate_uv = 0; - int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0; - int skippable = 0; - int this_skip2 = 0; - int64_t total_sse = INT64_MAX; - int early_term = 0; - - this_mode = vp9_mode_order[mode_index].mode; - ref_frame = vp9_mode_order[mode_index].ref_frame[0]; - second_ref_frame = vp9_mode_order[mode_index].ref_frame[1]; - - vp9_zero(x->sum_y_eobs); - comp_pred = second_ref_frame > INTRA_FRAME; - if (!comp_pred && ref_frame != INTRA_FRAME && - sf->prune_single_mode_based_on_mv_diff_mode_rate) - single_mode_rate[ref_frame][INTER_OFFSET(this_mode)] = INT_MAX; - - if (is_rect_partition) { - if (ctx->skip_ref_frame_mask & (1 << ref_frame)) continue; - if (second_ref_frame > 0 && - (ctx->skip_ref_frame_mask & (1 << second_ref_frame))) - continue; - } - - // Look at the reference frame of the best mode so far and set the - // skip mask to look at a subset of the remaining modes. - if (midx == mode_skip_start && best_mode_index >= 0) { - switch (best_mbmode.ref_frame[0]) { - case INTRA_FRAME: break; - case LAST_FRAME: ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK; break; - case GOLDEN_FRAME: - ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK; - break; - case ALTREF_FRAME: ref_frame_skip_mask[0] |= ALT_REF_MODE_MASK; break; - case NO_REF_FRAME: - case MAX_REF_FRAMES: assert(0 && "Invalid Reference frame"); break; - } - } - - if ((ref_frame_skip_mask[0] & (1 << ref_frame)) && - (ref_frame_skip_mask[1] & (1 << VPXMAX(0, second_ref_frame)))) - continue; - - if (mode_skip_mask[ref_frame] & (1 << this_mode)) continue; - - // Test best rd so far against threshold for trying this mode. - if (best_mode_skippable && sf->schedule_mode_search) - mode_threshold[mode_index] <<= 1; - - if (best_rd < mode_threshold[mode_index]) continue; - - // This is only used in motion vector unit test. - if (cpi->oxcf.motion_vector_unit_test && ref_frame == INTRA_FRAME) continue; - - if (sf->motion_field_mode_search) { - const int mi_width = VPXMIN(num_8x8_blocks_wide_lookup[bsize], - tile_info->mi_col_end - mi_col); - const int mi_height = VPXMIN(num_8x8_blocks_high_lookup[bsize], - tile_info->mi_row_end - mi_row); - const int bsl = mi_width_log2_lookup[bsize]; - int cb_partition_search_ctrl = - (((mi_row + mi_col) >> bsl) + - get_chessboard_index(cm->current_video_frame)) & - 0x1; - MODE_INFO *ref_mi; - int const_motion = 1; - int skip_ref_frame = !cb_partition_search_ctrl; - MV_REFERENCE_FRAME rf = NO_REF_FRAME; - int_mv ref_mv; - ref_mv.as_int = INVALID_MV; - - if ((mi_row - 1) >= tile_info->mi_row_start) { - ref_mv = xd->mi[-xd->mi_stride]->mv[0]; - rf = xd->mi[-xd->mi_stride]->ref_frame[0]; - for (i = 0; i < mi_width; ++i) { - ref_mi = xd->mi[-xd->mi_stride + i]; - const_motion &= (ref_mv.as_int == ref_mi->mv[0].as_int) && - (ref_frame == ref_mi->ref_frame[0]); - skip_ref_frame &= (rf == ref_mi->ref_frame[0]); - } - } - - if ((mi_col - 1) >= tile_info->mi_col_start) { - if (ref_mv.as_int == INVALID_MV) ref_mv = xd->mi[-1]->mv[0]; - if (rf == NO_REF_FRAME) rf = xd->mi[-1]->ref_frame[0]; - for (i = 0; i < mi_height; ++i) { - ref_mi = xd->mi[i * xd->mi_stride - 1]; - const_motion &= (ref_mv.as_int == ref_mi->mv[0].as_int) && - (ref_frame == ref_mi->ref_frame[0]); - skip_ref_frame &= (rf == ref_mi->ref_frame[0]); - } - } - - if (skip_ref_frame && this_mode != NEARESTMV && this_mode != NEWMV) - if (rf > INTRA_FRAME) - if (ref_frame != rf) continue; - - if (const_motion) - if (this_mode == NEARMV || this_mode == ZEROMV) continue; - } - - if (comp_pred) { - if (!cpi->allow_comp_inter_inter) continue; - - if (cm->ref_frame_sign_bias[ref_frame] == - cm->ref_frame_sign_bias[second_ref_frame]) - continue; - - // Skip compound inter modes if ARF is not available. - if (!(cpi->ref_frame_flags & ref_frame_to_flag(second_ref_frame))) - continue; - - // Do not allow compound prediction if the segment level reference frame - // feature is in use as in this case there can only be one reference. - if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue; - - if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) && - best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME) - continue; - - mode_excluded = cm->reference_mode == SINGLE_REFERENCE; - } else { - if (ref_frame != INTRA_FRAME) - mode_excluded = cm->reference_mode == COMPOUND_REFERENCE; - } - - if (ref_frame == INTRA_FRAME) { - if (sf->adaptive_mode_search) - if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse) - continue; - - if (this_mode != DC_PRED) { - // Disable intra modes other than DC_PRED for blocks with low variance - // Threshold for intra skipping based on source variance - // TODO(debargha): Specialize the threshold for super block sizes - const unsigned int skip_intra_var_thresh = - (cpi->oxcf.content == VP9E_CONTENT_FILM) ? 0 : 64; - if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) && - x->source_variance < skip_intra_var_thresh) - continue; - // Only search the oblique modes if the best so far is - // one of the neighboring directional modes - if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) && - (this_mode >= D45_PRED && this_mode <= TM_PRED)) { - if (best_mode_index >= 0 && best_mbmode.ref_frame[0] > INTRA_FRAME) - continue; - } - if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) { - if (conditional_skipintra(this_mode, best_intra_mode)) continue; - } - } - } else { - const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame }; - if (!check_best_zero_mv(cpi, mbmi_ext->mode_context, frame_mv, this_mode, - ref_frames)) - continue; - } - - mi->mode = this_mode; - mi->uv_mode = DC_PRED; - mi->ref_frame[0] = ref_frame; - mi->ref_frame[1] = second_ref_frame; - // Evaluate all sub-pel filters irrespective of whether we can use - // them for this frame. - mi->interp_filter = - cm->interp_filter == SWITCHABLE ? EIGHTTAP : cm->interp_filter; - mi->mv[0].as_int = mi->mv[1].as_int = 0; - - x->skip = 0; - set_ref_ptrs(cm, xd, ref_frame, second_ref_frame); - - // Select prediction reference frames. - for (i = 0; i < MAX_MB_PLANE; i++) { - xd->plane[i].pre[0] = yv12_mb[ref_frame][i]; - if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i]; - } - - if (ref_frame == INTRA_FRAME) { - TX_SIZE uv_tx; - struct macroblockd_plane *const pd = &xd->plane[1]; -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, intra_mode_search_time); -#endif - memset(x->skip_txfm, 0, sizeof(x->skip_txfm)); - super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable, NULL, bsize, - best_rd, recon); -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, intra_mode_search_time); -#endif - if (rate_y == INT_MAX) continue; - - uv_tx = uv_txsize_lookup[bsize][mi->tx_size][pd->subsampling_x] - [pd->subsampling_y]; -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, intra_mode_search_time); -#endif - if (rate_uv_intra[uv_tx] == INT_MAX) { - choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx], - &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx], - &skip_uv[uv_tx], &mode_uv[uv_tx]); - } -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, intra_mode_search_time); -#endif - rate_uv = rate_uv_tokenonly[uv_tx]; - distortion_uv = dist_uv[uv_tx]; - skippable = skippable && skip_uv[uv_tx]; - mi->uv_mode = mode_uv[uv_tx]; - - rate2 = rate_y + cpi->mbmode_cost[mi->mode] + rate_uv_intra[uv_tx]; - if (this_mode != DC_PRED && this_mode != TM_PRED) - rate2 += intra_cost_penalty; - distortion2 = distortion_y + distortion_uv; - } else { -#if CONFIG_COLLECT_COMPONENT_TIMING - start_timing(cpi, handle_inter_mode_time); -#endif - this_rd = handle_inter_mode( - cpi, x, bsize, &rate2, &distortion2, &skippable, &rate_y, &rate_uv, - recon, &disable_skip, frame_mv, mi_row, mi_col, single_newmv, - single_inter_filter, single_skippable, - &single_mode_rate[ref_frame][0], &total_sse, best_rd, &mask_filter, - filter_cache, best_mode_index); -#if CONFIG_COLLECT_COMPONENT_TIMING - end_timing(cpi, handle_inter_mode_time); -#endif - if (this_rd == INT64_MAX) continue; - - compmode_cost = vp9_cost_bit(comp_mode_p, comp_pred); - - if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost; - } - - // Estimate the reference frame signaling cost and add it - // to the rolling cost variable. - if (comp_pred) { - rate2 += ref_costs_comp[ref_frame]; - } else { - rate2 += ref_costs_single[ref_frame]; - } - - if (!disable_skip) { - const vpx_prob skip_prob = vp9_get_skip_prob(cm, xd); - const int skip_cost0 = vp9_cost_bit(skip_prob, 0); - const int skip_cost1 = vp9_cost_bit(skip_prob, 1); - - if (skippable) { - // Back out the coefficient coding costs - rate2 -= (rate_y + rate_uv); - - // Cost the skip mb case - rate2 += skip_cost1; - } else if (ref_frame != INTRA_FRAME && !xd->lossless && - !cpi->oxcf.sharpness) { - if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv + skip_cost0, - distortion2) < - RDCOST(x->rdmult, x->rddiv, skip_cost1, total_sse)) { - // Add in the cost of the no skip flag. - rate2 += skip_cost0; - } else { - // FIXME(rbultje) make this work for splitmv also - assert(total_sse >= 0); - - rate2 += skip_cost1; - distortion2 = total_sse; - rate2 -= (rate_y + rate_uv); - this_skip2 = 1; - } - } else { - // Add in the cost of the no skip flag. - rate2 += skip_cost0; - } - - // Calculate the final RD estimate for this mode. - this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2); - } - - if (recon) { - // In film mode bias against DC pred and other intra if there is a - // significant difference between the variance of the sub blocks in the - // the source. Also apply some bias against compound modes which also - // tend to blur fine texture such as film grain over time. - // - // The sub block test here acts in the case where one or more sub - // blocks have high relatively variance but others relatively low - // variance. Here the high variance sub blocks may push the - // total variance for the current block size over the thresholds - // used in rd_variance_adjustment() below. - if (cpi->oxcf.content == VP9E_CONTENT_FILM) { - if (bsize >= BLOCK_16X16) { - int min_energy, max_energy; - vp9_get_sub_block_energy(cpi, x, mi_row, mi_col, bsize, &min_energy, - &max_energy); - if (max_energy > min_energy) { - if (ref_frame == INTRA_FRAME) { - if (this_mode == DC_PRED) - this_rd += (this_rd * (max_energy - min_energy)); - else - this_rd += (this_rd * (max_energy - min_energy)) / 4; - } else if (second_ref_frame > INTRA_FRAME) { - this_rd += this_rd / 4; - } - } - } - } - // Apply an adjustment to the rd value based on the similarity of the - // source variance and reconstructed variance. - rd_variance_adjustment(cpi, x, bsize, &this_rd, recon, ref_frame, - second_ref_frame, this_mode); - } - - if (ref_frame == INTRA_FRAME) { - // Keep record of best intra rd - if (this_rd < best_intra_rd) { - best_intra_rd = this_rd; - best_intra_mode = mi->mode; - } - } - - if (!disable_skip && ref_frame == INTRA_FRAME) { - for (i = 0; i < REFERENCE_MODES; ++i) - best_pred_rd[i] = VPXMIN(best_pred_rd[i], this_rd); - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) - best_filter_rd[i] = VPXMIN(best_filter_rd[i], this_rd); - } - - // Did this mode help.. i.e. is it the new best mode - if (this_rd < best_rd || x->skip) { - int max_plane = MAX_MB_PLANE; - if (!mode_excluded) { - // Note index of best mode so far - best_mode_index = mode_index; - - if (ref_frame == INTRA_FRAME) { - /* required for left and above block mv */ - mi->mv[0].as_int = 0; - max_plane = 1; - // Initialize interp_filter here so we do not have to check for - // inter block modes in get_pred_context_switchable_interp() - mi->interp_filter = SWITCHABLE_FILTERS; - } else { - best_pred_sse = x->pred_sse[ref_frame]; - } - - rd_cost->rate = rate2; - rd_cost->dist = distortion2; - rd_cost->rdcost = this_rd; - best_rd = this_rd; - best_mbmode = *mi; - best_skip2 = this_skip2; - best_mode_skippable = skippable; - - if (!x->select_tx_size) swap_block_ptr(x, ctx, 1, 0, 0, max_plane); - memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mi->tx_size], - sizeof(ctx->zcoeff_blk[0]) * ctx->num_4x4_blk); - ctx->sum_y_eobs = x->sum_y_eobs[mi->tx_size]; - - // TODO(debargha): enhance this test with a better distortion prediction - // based on qp, activity mask and history - if ((mode_search_skip_flags & FLAG_EARLY_TERMINATE) && - (mode_index > MIN_EARLY_TERM_INDEX)) { - int qstep = xd->plane[0].dequant[1]; - // TODO(debargha): Enhance this by specializing for each mode_index - int scale = 4; -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - qstep >>= (xd->bd - 8); - } -#endif // CONFIG_VP9_HIGHBITDEPTH - if (x->source_variance < UINT_MAX) { - const int var_adjust = (x->source_variance < 16); - scale -= var_adjust; - } - if (ref_frame > INTRA_FRAME && distortion2 * scale < qstep * qstep) { - early_term = 1; - } - } - } - } - - /* keep record of best compound/single-only prediction */ - if (!disable_skip && ref_frame != INTRA_FRAME) { - int64_t single_rd, hybrid_rd, single_rate, hybrid_rate; - - if (cm->reference_mode == REFERENCE_MODE_SELECT) { - single_rate = rate2 - compmode_cost; - hybrid_rate = rate2; - } else { - single_rate = rate2; - hybrid_rate = rate2 + compmode_cost; - } - - single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2); - hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2); - - if (!comp_pred) { - if (single_rd < best_pred_rd[SINGLE_REFERENCE]) - best_pred_rd[SINGLE_REFERENCE] = single_rd; - } else { - if (single_rd < best_pred_rd[COMPOUND_REFERENCE]) - best_pred_rd[COMPOUND_REFERENCE] = single_rd; - } - if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT]) - best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd; - - /* keep record of best filter type */ - if (!mode_excluded && cm->interp_filter != BILINEAR) { - int64_t ref = - filter_cache[cm->interp_filter == SWITCHABLE ? SWITCHABLE_FILTERS - : cm->interp_filter]; - - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) { - int64_t adj_rd; - if (ref == INT64_MAX) - adj_rd = 0; - else if (filter_cache[i] == INT64_MAX) - // when early termination is triggered, the encoder does not have - // access to the rate-distortion cost. it only knows that the cost - // should be above the maximum valid value. hence it takes the known - // maximum plus an arbitrary constant as the rate-distortion cost. - adj_rd = mask_filter - ref + 10; - else - adj_rd = filter_cache[i] - ref; - - adj_rd += this_rd; - best_filter_rd[i] = VPXMIN(best_filter_rd[i], adj_rd); - } - } - } - - if (early_term) break; - - if (x->skip && !comp_pred) break; - } - - // The inter modes' rate costs are not calculated precisely in some cases. - // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and - // ZEROMV. Here, checks are added for those cases, and the mode decisions - // are corrected. - if (best_mbmode.mode == NEWMV) { - const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0], - best_mbmode.ref_frame[1] }; - int comp_pred_mode = refs[1] > INTRA_FRAME; - - if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int && - ((comp_pred_mode && - frame_mv[NEARESTMV][refs[1]].as_int == best_mbmode.mv[1].as_int) || - !comp_pred_mode)) - best_mbmode.mode = NEARESTMV; - else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int && - ((comp_pred_mode && - frame_mv[NEARMV][refs[1]].as_int == best_mbmode.mv[1].as_int) || - !comp_pred_mode)) - best_mbmode.mode = NEARMV; - else if (best_mbmode.mv[0].as_int == 0 && - ((comp_pred_mode && best_mbmode.mv[1].as_int == 0) || - !comp_pred_mode)) - best_mbmode.mode = ZEROMV; - } - - if (best_mode_index < 0 || best_rd >= best_rd_so_far) { - // If adaptive interp filter is enabled, then the current leaf node of 8x8 - // data is needed for sub8x8. Hence preserve the context. - if (bsize == BLOCK_8X8) ctx->mic = *xd->mi[0]; - rd_cost->rate = INT_MAX; - rd_cost->rdcost = INT64_MAX; - return; - } - - // If we used an estimate for the uv intra rd in the loop above... - if (sf->use_uv_intra_rd_estimate) { - // Do Intra UV best rd mode selection if best mode choice above was intra. - if (best_mbmode.ref_frame[0] == INTRA_FRAME) { - TX_SIZE uv_tx_size; - *mi = best_mbmode; - uv_tx_size = get_uv_tx_size(mi, &xd->plane[1]); - rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra[uv_tx_size], - &rate_uv_tokenonly[uv_tx_size], - &dist_uv[uv_tx_size], &skip_uv[uv_tx_size], - bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, - uv_tx_size); - } - } - - assert((cm->interp_filter == SWITCHABLE) || - (cm->interp_filter == best_mbmode.interp_filter) || - !is_inter_block(&best_mbmode)); - - if (!cpi->rc.is_src_frame_alt_ref) - vp9_update_rd_thresh_fact(tile_data->thresh_freq_fact, - sf->adaptive_rd_thresh, bsize, best_mode_index); - - // macroblock modes - *mi = best_mbmode; - x->skip |= best_skip2; - - for (i = 0; i < REFERENCE_MODES; ++i) { - if (best_pred_rd[i] == INT64_MAX) - best_pred_diff[i] = INT_MIN; - else - best_pred_diff[i] = best_rd - best_pred_rd[i]; - } - - if (!x->skip) { - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) { - if (best_filter_rd[i] == INT64_MAX) - best_filter_diff[i] = 0; - else - best_filter_diff[i] = best_rd - best_filter_rd[i]; - } - if (cm->interp_filter == SWITCHABLE) - assert(best_filter_diff[SWITCHABLE_FILTERS] == 0); - } else { - vp9_zero(best_filter_diff); - } - - // TODO(yunqingwang): Moving this line in front of the above best_filter_diff - // updating code causes PSNR loss. Need to figure out the confliction. - x->skip |= best_mode_skippable; - - if (!x->skip && !x->select_tx_size) { - int has_high_freq_coeff = 0; - int plane; - int max_plane = is_inter_block(xd->mi[0]) ? MAX_MB_PLANE : 1; - for (plane = 0; plane < max_plane; ++plane) { - x->plane[plane].eobs = ctx->eobs_pbuf[plane][1]; - has_high_freq_coeff |= vp9_has_high_freq_in_plane(x, bsize, plane); - } - - for (plane = max_plane; plane < MAX_MB_PLANE; ++plane) { - x->plane[plane].eobs = ctx->eobs_pbuf[plane][2]; - has_high_freq_coeff |= vp9_has_high_freq_in_plane(x, bsize, plane); - } - - best_mode_skippable |= !has_high_freq_coeff; - } - - assert(best_mode_index >= 0); - - store_coding_context(x, ctx, best_mode_index, best_pred_diff, - best_filter_diff, best_mode_skippable); -} - -void vp9_rd_pick_inter_mode_sb_seg_skip(VP9_COMP *cpi, TileDataEnc *tile_data, - MACROBLOCK *x, RD_COST *rd_cost, - BLOCK_SIZE bsize, - PICK_MODE_CONTEXT *ctx, - int64_t best_rd_so_far) { - VP9_COMMON *const cm = &cpi->common; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - unsigned char segment_id = mi->segment_id; - const int comp_pred = 0; - int i; - int64_t best_pred_diff[REFERENCE_MODES]; - int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS]; - unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES]; - vpx_prob comp_mode_p; - INTERP_FILTER best_filter = SWITCHABLE; - int64_t this_rd = INT64_MAX; - int rate2 = 0; - const int64_t distortion2 = 0; - - x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH; - - estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp, - &comp_mode_p); - - for (i = 0; i < MAX_REF_FRAMES; ++i) x->pred_sse[i] = INT_MAX; - for (i = LAST_FRAME; i < MAX_REF_FRAMES; ++i) x->pred_mv_sad[i] = INT_MAX; - - rd_cost->rate = INT_MAX; - - assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)); - - mi->mode = ZEROMV; - mi->uv_mode = DC_PRED; - mi->ref_frame[0] = LAST_FRAME; - mi->ref_frame[1] = NO_REF_FRAME; - mi->mv[0].as_int = 0; - x->skip = 1; - - ctx->sum_y_eobs = 0; - - if (cm->interp_filter != BILINEAR) { - best_filter = EIGHTTAP; - if (cm->interp_filter == SWITCHABLE && - x->source_variance >= cpi->sf.disable_filter_search_var_thresh) { - int rs; - int best_rs = INT_MAX; - for (i = 0; i < SWITCHABLE_FILTERS; ++i) { - mi->interp_filter = i; - rs = vp9_get_switchable_rate(cpi, xd); - if (rs < best_rs) { - best_rs = rs; - best_filter = mi->interp_filter; - } - } - } - } - // Set the appropriate filter - if (cm->interp_filter == SWITCHABLE) { - mi->interp_filter = best_filter; - rate2 += vp9_get_switchable_rate(cpi, xd); - } else { - mi->interp_filter = cm->interp_filter; - } - - if (cm->reference_mode == REFERENCE_MODE_SELECT) - rate2 += vp9_cost_bit(comp_mode_p, comp_pred); - - // Estimate the reference frame signaling cost and add it - // to the rolling cost variable. - rate2 += ref_costs_single[LAST_FRAME]; - this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2); - - rd_cost->rate = rate2; - rd_cost->dist = distortion2; - rd_cost->rdcost = this_rd; - - if (this_rd >= best_rd_so_far) { - rd_cost->rate = INT_MAX; - rd_cost->rdcost = INT64_MAX; - return; - } - - assert((cm->interp_filter == SWITCHABLE) || - (cm->interp_filter == mi->interp_filter)); - - vp9_update_rd_thresh_fact(tile_data->thresh_freq_fact, - cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV); - - vp9_zero(best_pred_diff); - vp9_zero(best_filter_diff); - - if (!x->select_tx_size) swap_block_ptr(x, ctx, 1, 0, 0, MAX_MB_PLANE); - store_coding_context(x, ctx, THR_ZEROMV, best_pred_diff, best_filter_diff, 0); -} - -void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, TileDataEnc *tile_data, - MACROBLOCK *x, int mi_row, int mi_col, - RD_COST *rd_cost, BLOCK_SIZE bsize, - PICK_MODE_CONTEXT *ctx, - int64_t best_rd_so_far) { - VP9_COMMON *const cm = &cpi->common; - RD_OPT *const rd_opt = &cpi->rd; - SPEED_FEATURES *const sf = &cpi->sf; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - const struct segmentation *const seg = &cm->seg; - MV_REFERENCE_FRAME ref_frame, second_ref_frame; - unsigned char segment_id = mi->segment_id; - int comp_pred, i; - int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES]; - struct buf_2d yv12_mb[4][MAX_MB_PLANE] = { 0 }; - int64_t best_rd = best_rd_so_far; - int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise - int64_t best_pred_diff[REFERENCE_MODES]; - int64_t best_pred_rd[REFERENCE_MODES]; - int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS]; - int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS]; - MODE_INFO best_mbmode; - int ref_index, best_ref_index = 0; - unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES]; - vpx_prob comp_mode_p; - INTERP_FILTER tmp_best_filter = SWITCHABLE; - int rate_uv_intra, rate_uv_tokenonly; - int64_t dist_uv; - int skip_uv; - PREDICTION_MODE mode_uv = DC_PRED; - const int intra_cost_penalty = - vp9_get_intra_cost_penalty(cpi, bsize, cm->base_qindex, cm->y_dc_delta_q); - int_mv seg_mvs[4][MAX_REF_FRAMES]; - b_mode_info best_bmodes[4]; - int best_skip2 = 0; - int ref_frame_skip_mask[2] = { 0 }; - int64_t mask_filter = 0; - int64_t filter_cache[SWITCHABLE_FILTER_CONTEXTS]; - int internal_active_edge = - vp9_active_edge_sb(cpi, mi_row, mi_col) && vp9_internal_image_edge(cpi); - const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize]; - - x->skip_encode = sf->skip_encode_frame && x->q_index < QIDX_SKIP_THRESH; - memset(x->zcoeff_blk[TX_4X4], 0, 4); - vp9_zero(best_mbmode); - - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) filter_cache[i] = INT64_MAX; - - for (i = 0; i < 4; i++) { - int j; - for (j = 0; j < MAX_REF_FRAMES; j++) seg_mvs[i][j].as_int = INVALID_MV; - } - - estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp, - &comp_mode_p); - - for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX; - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) - best_filter_rd[i] = INT64_MAX; - rate_uv_intra = INT_MAX; - - rd_cost->rate = INT_MAX; - - for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) { - if (cpi->ref_frame_flags & ref_frame_to_flag(ref_frame)) { - setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col, - frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb); - } else { - ref_frame_skip_mask[0] |= (1 << ref_frame); - ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK; - } - frame_mv[NEWMV][ref_frame].as_int = INVALID_MV; - frame_mv[ZEROMV][ref_frame].as_int = 0; - } - - for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) { - int mode_excluded = 0; - int64_t this_rd = INT64_MAX; - int disable_skip = 0; - int compmode_cost = 0; - int rate2 = 0, rate_y = 0, rate_uv = 0; - int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0; - int skippable = 0; - int this_skip2 = 0; - int64_t total_sse = INT_MAX; - int early_term = 0; - struct buf_2d backup_yv12[2][MAX_MB_PLANE]; - - ref_frame = vp9_ref_order[ref_index].ref_frame[0]; - second_ref_frame = vp9_ref_order[ref_index].ref_frame[1]; - - vp9_zero(x->sum_y_eobs); - -#if CONFIG_BETTER_HW_COMPATIBILITY - // forbid 8X4 and 4X8 partitions if any reference frame is scaled. - if (bsize == BLOCK_8X4 || bsize == BLOCK_4X8) { - int ref_scaled = ref_frame > INTRA_FRAME && - vp9_is_scaled(&cm->frame_refs[ref_frame - 1].sf); - if (second_ref_frame > INTRA_FRAME) - ref_scaled += vp9_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf); - if (ref_scaled) continue; - } -#endif - // Look at the reference frame of the best mode so far and set the - // skip mask to look at a subset of the remaining modes. - if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) { - if (ref_index == 3) { - switch (best_mbmode.ref_frame[0]) { - case INTRA_FRAME: break; - case LAST_FRAME: - ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME); - ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK; - break; - case GOLDEN_FRAME: - ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << ALTREF_FRAME); - ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK; - break; - case ALTREF_FRAME: - ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) | (1 << LAST_FRAME); - break; - case NO_REF_FRAME: - case MAX_REF_FRAMES: assert(0 && "Invalid Reference frame"); break; - } - } - } - - if ((ref_frame_skip_mask[0] & (1 << ref_frame)) && - (ref_frame_skip_mask[1] & (1 << VPXMAX(0, second_ref_frame)))) - continue; - - // Test best rd so far against threshold for trying this mode. - if (!internal_active_edge && - rd_less_than_thresh(best_rd, - rd_opt->threshes[segment_id][bsize][ref_index], - &rd_thresh_freq_fact[ref_index])) - continue; - - // This is only used in motion vector unit test. - if (cpi->oxcf.motion_vector_unit_test && ref_frame == INTRA_FRAME) continue; - - comp_pred = second_ref_frame > INTRA_FRAME; - if (comp_pred) { - if (!cpi->allow_comp_inter_inter) continue; - - if (cm->ref_frame_sign_bias[ref_frame] == - cm->ref_frame_sign_bias[second_ref_frame]) - continue; - - if (!(cpi->ref_frame_flags & ref_frame_to_flag(second_ref_frame))) - continue; - // Do not allow compound prediction if the segment level reference frame - // feature is in use as in this case there can only be one reference. - if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue; - - if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) && - best_mbmode.ref_frame[0] == INTRA_FRAME) - continue; - } - - if (comp_pred) - mode_excluded = cm->reference_mode == SINGLE_REFERENCE; - else if (ref_frame != INTRA_FRAME) - mode_excluded = cm->reference_mode == COMPOUND_REFERENCE; - - // If the segment reference frame feature is enabled.... - // then do nothing if the current ref frame is not allowed.. - if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) && - get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) { - continue; - // Disable this drop out case if the ref frame - // segment level feature is enabled for this segment. This is to - // prevent the possibility that we end up unable to pick any mode. - } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) { - // Only consider ZEROMV/ALTREF_FRAME for alt ref frame, - // unless ARNR filtering is enabled in which case we want - // an unfiltered alternative. We allow near/nearest as well - // because they may result in zero-zero MVs but be cheaper. - if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) - continue; - } - - mi->tx_size = TX_4X4; - mi->uv_mode = DC_PRED; - mi->ref_frame[0] = ref_frame; - mi->ref_frame[1] = second_ref_frame; - // Evaluate all sub-pel filters irrespective of whether we can use - // them for this frame. - mi->interp_filter = - cm->interp_filter == SWITCHABLE ? EIGHTTAP : cm->interp_filter; - x->skip = 0; - set_ref_ptrs(cm, xd, ref_frame, second_ref_frame); - - // Select prediction reference frames. - for (i = 0; i < MAX_MB_PLANE; i++) { - xd->plane[i].pre[0] = yv12_mb[ref_frame][i]; - if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i]; - } - - if (ref_frame == INTRA_FRAME) { - int rate; - if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y, &distortion_y, - best_rd) >= best_rd) - continue; - rate2 += rate; - rate2 += intra_cost_penalty; - distortion2 += distortion_y; - - if (rate_uv_intra == INT_MAX) { - choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4, &rate_uv_intra, - &rate_uv_tokenonly, &dist_uv, &skip_uv, &mode_uv); - } - rate2 += rate_uv_intra; - rate_uv = rate_uv_tokenonly; - distortion2 += dist_uv; - distortion_uv = dist_uv; - mi->uv_mode = mode_uv; - } else { - int rate; - int64_t distortion; - int64_t this_rd_thresh; - int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX; - int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX; - int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse; - int tmp_best_skippable = 0; - int switchable_filter_index; - int_mv *second_ref = - comp_pred ? &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL; - b_mode_info tmp_best_bmodes[16]; - MODE_INFO tmp_best_mbmode; - BEST_SEG_INFO bsi[SWITCHABLE_FILTERS]; - int pred_exists = 0; - int uv_skippable; - - YV12_BUFFER_CONFIG *scaled_ref_frame[2] = { NULL, NULL }; - int ref; - - for (ref = 0; ref < 2; ++ref) { - scaled_ref_frame[ref] = - mi->ref_frame[ref] > INTRA_FRAME - ? vp9_get_scaled_ref_frame(cpi, mi->ref_frame[ref]) - : NULL; - - if (scaled_ref_frame[ref]) { - // Swap out the reference frame for a version that's been scaled to - // match the resolution of the current frame, allowing the existing - // motion search code to be used without additional modifications. - for (i = 0; i < MAX_MB_PLANE; i++) - backup_yv12[ref][i] = xd->plane[i].pre[ref]; - vp9_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col, - NULL); - } - } - - this_rd_thresh = (ref_frame == LAST_FRAME) - ? rd_opt->threshes[segment_id][bsize][THR_LAST] - : rd_opt->threshes[segment_id][bsize][THR_ALTR]; - this_rd_thresh = (ref_frame == GOLDEN_FRAME) - ? rd_opt->threshes[segment_id][bsize][THR_GOLD] - : this_rd_thresh; - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) - filter_cache[i] = INT64_MAX; - - if (cm->interp_filter != BILINEAR) { - tmp_best_filter = EIGHTTAP; - if (x->source_variance < sf->disable_filter_search_var_thresh) { - tmp_best_filter = EIGHTTAP; - } else if (sf->adaptive_pred_interp_filter == 1 && - ctx->pred_interp_filter < SWITCHABLE) { - tmp_best_filter = ctx->pred_interp_filter; - } else if (sf->adaptive_pred_interp_filter == 2) { - tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE - ? ctx->pred_interp_filter - : 0; - } else { - for (switchable_filter_index = 0; - switchable_filter_index < SWITCHABLE_FILTERS; - ++switchable_filter_index) { - int newbest, rs; - int64_t rs_rd; - MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext; - mi->interp_filter = switchable_filter_index; - tmp_rd = rd_pick_best_sub8x8_mode( - cpi, x, &mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd, - &rate, &rate_y, &distortion, &skippable, &total_sse, - (int)this_rd_thresh, seg_mvs, bsi, switchable_filter_index, - mi_row, mi_col); - - if (tmp_rd == INT64_MAX) continue; - rs = vp9_get_switchable_rate(cpi, xd); - rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0); - filter_cache[switchable_filter_index] = tmp_rd; - filter_cache[SWITCHABLE_FILTERS] = - VPXMIN(filter_cache[SWITCHABLE_FILTERS], tmp_rd + rs_rd); - if (cm->interp_filter == SWITCHABLE) tmp_rd += rs_rd; - - mask_filter = VPXMAX(mask_filter, tmp_rd); - - newbest = (tmp_rd < tmp_best_rd); - if (newbest) { - tmp_best_filter = mi->interp_filter; - tmp_best_rd = tmp_rd; - } - if ((newbest && cm->interp_filter == SWITCHABLE) || - (mi->interp_filter == cm->interp_filter && - cm->interp_filter != SWITCHABLE)) { - tmp_best_rdu = tmp_rd; - tmp_best_rate = rate; - tmp_best_ratey = rate_y; - tmp_best_distortion = distortion; - tmp_best_sse = total_sse; - tmp_best_skippable = skippable; - tmp_best_mbmode = *mi; - x->sum_y_eobs[TX_4X4] = 0; - for (i = 0; i < 4; i++) { - tmp_best_bmodes[i] = xd->mi[0]->bmi[i]; - x->zcoeff_blk[TX_4X4][i] = !x->plane[0].eobs[i]; - x->sum_y_eobs[TX_4X4] += x->plane[0].eobs[i]; - } - pred_exists = 1; - if (switchable_filter_index == 0 && sf->use_rd_breakout && - best_rd < INT64_MAX) { - if (tmp_best_rdu / 2 > best_rd) { - // skip searching the other filters if the first is - // already substantially larger than the best so far - tmp_best_filter = mi->interp_filter; - tmp_best_rdu = INT64_MAX; - break; - } - } - } - } // switchable_filter_index loop - } - } - - if (tmp_best_rdu == INT64_MAX && pred_exists) continue; - - mi->interp_filter = (cm->interp_filter == SWITCHABLE ? tmp_best_filter - : cm->interp_filter); - if (!pred_exists) { - // Handles the special case when a filter that is not in the - // switchable list (bilinear, 6-tap) is indicated at the frame level - tmp_rd = rd_pick_best_sub8x8_mode( - cpi, x, &x->mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd, - &rate, &rate_y, &distortion, &skippable, &total_sse, - (int)this_rd_thresh, seg_mvs, bsi, 0, mi_row, mi_col); - if (tmp_rd == INT64_MAX) continue; - x->sum_y_eobs[TX_4X4] = 0; - for (i = 0; i < 4; i++) { - x->zcoeff_blk[TX_4X4][i] = !x->plane[0].eobs[i]; - x->sum_y_eobs[TX_4X4] += x->plane[0].eobs[i]; - } - } else { - total_sse = tmp_best_sse; - rate = tmp_best_rate; - rate_y = tmp_best_ratey; - distortion = tmp_best_distortion; - skippable = tmp_best_skippable; - *mi = tmp_best_mbmode; - for (i = 0; i < 4; i++) xd->mi[0]->bmi[i] = tmp_best_bmodes[i]; - } - - rate2 += rate; - distortion2 += distortion; - - if (cm->interp_filter == SWITCHABLE) - rate2 += vp9_get_switchable_rate(cpi, xd); - - if (!mode_excluded) - mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE - : cm->reference_mode == COMPOUND_REFERENCE; - - compmode_cost = vp9_cost_bit(comp_mode_p, comp_pred); - - tmp_best_rdu = - best_rd - VPXMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2), - RDCOST(x->rdmult, x->rddiv, 0, total_sse)); - - if (tmp_best_rdu > 0) { - // If even the 'Y' rd value of split is higher than best so far - // then don't bother looking at UV - vp9_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col, BLOCK_8X8); - memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm)); - if (!super_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable, - &uv_sse, BLOCK_8X8, tmp_best_rdu)) { - for (ref = 0; ref < 2; ++ref) { - if (scaled_ref_frame[ref]) { - for (i = 0; i < MAX_MB_PLANE; ++i) - xd->plane[i].pre[ref] = backup_yv12[ref][i]; - } - } - continue; - } - - rate2 += rate_uv; - distortion2 += distortion_uv; - skippable = skippable && uv_skippable; - total_sse += uv_sse; - } - - for (ref = 0; ref < 2; ++ref) { - if (scaled_ref_frame[ref]) { - // Restore the prediction frame pointers to their unscaled versions. - for (i = 0; i < MAX_MB_PLANE; ++i) - xd->plane[i].pre[ref] = backup_yv12[ref][i]; - } - } - } - - if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost; - - // Estimate the reference frame signaling cost and add it - // to the rolling cost variable. - if (second_ref_frame > INTRA_FRAME) { - rate2 += ref_costs_comp[ref_frame]; - } else { - rate2 += ref_costs_single[ref_frame]; - } - - if (!disable_skip) { - const vpx_prob skip_prob = vp9_get_skip_prob(cm, xd); - const int skip_cost0 = vp9_cost_bit(skip_prob, 0); - const int skip_cost1 = vp9_cost_bit(skip_prob, 1); - - // Skip is never coded at the segment level for sub8x8 blocks and instead - // always coded in the bitstream at the mode info level. - if (ref_frame != INTRA_FRAME && !xd->lossless) { - if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv + skip_cost0, - distortion2) < - RDCOST(x->rdmult, x->rddiv, skip_cost1, total_sse)) { - // Add in the cost of the no skip flag. - rate2 += skip_cost0; - } else { - // FIXME(rbultje) make this work for splitmv also - rate2 += skip_cost1; - distortion2 = total_sse; - assert(total_sse >= 0); - rate2 -= (rate_y + rate_uv); - rate_y = 0; - rate_uv = 0; - this_skip2 = 1; - } - } else { - // Add in the cost of the no skip flag. - rate2 += skip_cost0; - } - - // Calculate the final RD estimate for this mode. - this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2); - } - - if (!disable_skip && ref_frame == INTRA_FRAME) { - for (i = 0; i < REFERENCE_MODES; ++i) - best_pred_rd[i] = VPXMIN(best_pred_rd[i], this_rd); - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) - best_filter_rd[i] = VPXMIN(best_filter_rd[i], this_rd); - } - - // Did this mode help.. i.e. is it the new best mode - if (this_rd < best_rd || x->skip) { - if (!mode_excluded) { - int max_plane = MAX_MB_PLANE; - // Note index of best mode so far - best_ref_index = ref_index; - - if (ref_frame == INTRA_FRAME) { - /* required for left and above block mv */ - mi->mv[0].as_int = 0; - max_plane = 1; - // Initialize interp_filter here so we do not have to check for - // inter block modes in get_pred_context_switchable_interp() - mi->interp_filter = SWITCHABLE_FILTERS; - } - - rd_cost->rate = rate2; - rd_cost->dist = distortion2; - rd_cost->rdcost = this_rd; - best_rd = this_rd; - best_yrd = - best_rd - RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv); - best_mbmode = *mi; - best_skip2 = this_skip2; - if (!x->select_tx_size) swap_block_ptr(x, ctx, 1, 0, 0, max_plane); - memcpy(ctx->zcoeff_blk, x->zcoeff_blk[TX_4X4], - sizeof(ctx->zcoeff_blk[0]) * ctx->num_4x4_blk); - ctx->sum_y_eobs = x->sum_y_eobs[TX_4X4]; - - for (i = 0; i < 4; i++) best_bmodes[i] = xd->mi[0]->bmi[i]; - - // TODO(debargha): enhance this test with a better distortion prediction - // based on qp, activity mask and history - if ((sf->mode_search_skip_flags & FLAG_EARLY_TERMINATE) && - (ref_index > MIN_EARLY_TERM_INDEX)) { - int qstep = xd->plane[0].dequant[1]; - // TODO(debargha): Enhance this by specializing for each mode_index - int scale = 4; -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - qstep >>= (xd->bd - 8); - } -#endif // CONFIG_VP9_HIGHBITDEPTH - if (x->source_variance < UINT_MAX) { - const int var_adjust = (x->source_variance < 16); - scale -= var_adjust; - } - if (ref_frame > INTRA_FRAME && distortion2 * scale < qstep * qstep) { - early_term = 1; - } - } - } - } - - /* keep record of best compound/single-only prediction */ - if (!disable_skip && ref_frame != INTRA_FRAME) { - int64_t single_rd, hybrid_rd, single_rate, hybrid_rate; - - if (cm->reference_mode == REFERENCE_MODE_SELECT) { - single_rate = rate2 - compmode_cost; - hybrid_rate = rate2; - } else { - single_rate = rate2; - hybrid_rate = rate2 + compmode_cost; - } - - single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2); - hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2); - - if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE]) - best_pred_rd[SINGLE_REFERENCE] = single_rd; - else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE]) - best_pred_rd[COMPOUND_REFERENCE] = single_rd; - - if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT]) - best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd; - } - - /* keep record of best filter type */ - if (!mode_excluded && !disable_skip && ref_frame != INTRA_FRAME && - cm->interp_filter != BILINEAR) { - int64_t ref = - filter_cache[cm->interp_filter == SWITCHABLE ? SWITCHABLE_FILTERS - : cm->interp_filter]; - int64_t adj_rd; - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) { - if (ref == INT64_MAX) - adj_rd = 0; - else if (filter_cache[i] == INT64_MAX) - // when early termination is triggered, the encoder does not have - // access to the rate-distortion cost. it only knows that the cost - // should be above the maximum valid value. hence it takes the known - // maximum plus an arbitrary constant as the rate-distortion cost. - adj_rd = mask_filter - ref + 10; - else - adj_rd = filter_cache[i] - ref; - - adj_rd += this_rd; - best_filter_rd[i] = VPXMIN(best_filter_rd[i], adj_rd); - } - } - - if (early_term) break; - - if (x->skip && !comp_pred) break; - } - - if (best_rd >= best_rd_so_far) { - rd_cost->rate = INT_MAX; - rd_cost->rdcost = INT64_MAX; - return; - } - - // If we used an estimate for the uv intra rd in the loop above... - if (sf->use_uv_intra_rd_estimate) { - // Do Intra UV best rd mode selection if best mode choice above was intra. - if (best_mbmode.ref_frame[0] == INTRA_FRAME) { - *mi = best_mbmode; - rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra, &rate_uv_tokenonly, - &dist_uv, &skip_uv, BLOCK_8X8, TX_4X4); - } - } - - if (best_rd == INT64_MAX) { - rd_cost->rate = INT_MAX; - rd_cost->dist = INT64_MAX; - rd_cost->rdcost = INT64_MAX; - return; - } - - assert((cm->interp_filter == SWITCHABLE) || - (cm->interp_filter == best_mbmode.interp_filter) || - !is_inter_block(&best_mbmode)); - - vp9_update_rd_thresh_fact(tile_data->thresh_freq_fact, sf->adaptive_rd_thresh, - bsize, best_ref_index); - - // macroblock modes - *mi = best_mbmode; - x->skip |= best_skip2; - if (!is_inter_block(&best_mbmode)) { - for (i = 0; i < 4; i++) xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode; - } else { - for (i = 0; i < 4; ++i) - memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info)); - - mi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int; - mi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int; - } - // If the second reference does not exist, set the corresponding mv to zero. - if (mi->ref_frame[1] == NO_REF_FRAME) { - mi->mv[1].as_int = 0; - for (i = 0; i < 4; ++i) { - mi->bmi[i].as_mv[1].as_int = 0; - } - } - - for (i = 0; i < REFERENCE_MODES; ++i) { - if (best_pred_rd[i] == INT64_MAX) - best_pred_diff[i] = INT_MIN; - else - best_pred_diff[i] = best_rd - best_pred_rd[i]; - } - - if (!x->skip) { - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) { - if (best_filter_rd[i] == INT64_MAX) - best_filter_diff[i] = 0; - else - best_filter_diff[i] = best_rd - best_filter_rd[i]; - } - if (cm->interp_filter == SWITCHABLE) - assert(best_filter_diff[SWITCHABLE_FILTERS] == 0); - } else { - vp9_zero(best_filter_diff); - } - - store_coding_context(x, ctx, best_ref_index, best_pred_diff, best_filter_diff, - 0); -} -#endif // !CONFIG_REALTIME_ONLY diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_rdopt.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_rdopt.h deleted file mode 100644 index e1147ff9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_rdopt.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_RDOPT_H_ -#define VPX_VP9_ENCODER_VP9_RDOPT_H_ - -#include "vp9/common/vp9_blockd.h" - -#include "vp9/encoder/vp9_block.h" -#include "vp9/encoder/vp9_context_tree.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct TileInfo; -struct VP9_COMP; -struct macroblock; -struct RD_COST; - -void vp9_rd_pick_intra_mode_sb(struct VP9_COMP *cpi, struct macroblock *x, - struct RD_COST *rd_cost, BLOCK_SIZE bsize, - PICK_MODE_CONTEXT *ctx, int64_t best_rd); - -#if !CONFIG_REALTIME_ONLY -void vp9_rd_pick_inter_mode_sb(struct VP9_COMP *cpi, - struct TileDataEnc *tile_data, - struct macroblock *x, int mi_row, int mi_col, - struct RD_COST *rd_cost, BLOCK_SIZE bsize, - PICK_MODE_CONTEXT *ctx, int64_t best_rd_so_far); - -void vp9_rd_pick_inter_mode_sb_seg_skip( - struct VP9_COMP *cpi, struct TileDataEnc *tile_data, struct macroblock *x, - struct RD_COST *rd_cost, BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx, - int64_t best_rd_so_far); -#endif - -int vp9_internal_image_edge(struct VP9_COMP *cpi); -int vp9_active_h_edge(struct VP9_COMP *cpi, int mi_row, int mi_step); -int vp9_active_v_edge(struct VP9_COMP *cpi, int mi_col, int mi_step); -int vp9_active_edge_sb(struct VP9_COMP *cpi, int mi_row, int mi_col); - -#if !CONFIG_REALTIME_ONLY -void vp9_rd_pick_inter_mode_sub8x8(struct VP9_COMP *cpi, - struct TileDataEnc *tile_data, - struct macroblock *x, int mi_row, int mi_col, - struct RD_COST *rd_cost, BLOCK_SIZE bsize, - PICK_MODE_CONTEXT *ctx, - int64_t best_rd_so_far); -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_RDOPT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_resize.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_resize.c deleted file mode 100644 index 352d8f12..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_resize.c +++ /dev/null @@ -1,752 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include -#include - -#include "./vpx_config.h" -#if CONFIG_VP9_HIGHBITDEPTH -#include "vpx_dsp/vpx_dsp_common.h" -#endif // CONFIG_VP9_HIGHBITDEPTH -#include "vpx_ports/mem.h" -#include "vp9/common/vp9_common.h" -#include "vp9/encoder/vp9_resize.h" - -#define FILTER_BITS 7 - -#define INTERP_TAPS 8 -#define SUBPEL_BITS 5 -#define SUBPEL_MASK ((1 << SUBPEL_BITS) - 1) -#define INTERP_PRECISION_BITS 32 - -typedef int16_t interp_kernel[INTERP_TAPS]; - -// Filters for interpolation (0.5-band) - note this also filters integer pels. -static const interp_kernel filteredinterp_filters500[(1 << SUBPEL_BITS)] = { - { -3, 0, 35, 64, 35, 0, -3, 0 }, { -3, -1, 34, 64, 36, 1, -3, 0 }, - { -3, -1, 32, 64, 38, 1, -3, 0 }, { -2, -2, 31, 63, 39, 2, -3, 0 }, - { -2, -2, 29, 63, 41, 2, -3, 0 }, { -2, -2, 28, 63, 42, 3, -4, 0 }, - { -2, -3, 27, 63, 43, 4, -4, 0 }, { -2, -3, 25, 62, 45, 5, -4, 0 }, - { -2, -3, 24, 62, 46, 5, -4, 0 }, { -2, -3, 23, 61, 47, 6, -4, 0 }, - { -2, -3, 21, 60, 49, 7, -4, 0 }, { -1, -4, 20, 60, 50, 8, -4, -1 }, - { -1, -4, 19, 59, 51, 9, -4, -1 }, { -1, -4, 17, 58, 52, 10, -4, 0 }, - { -1, -4, 16, 57, 53, 12, -4, -1 }, { -1, -4, 15, 56, 54, 13, -4, -1 }, - { -1, -4, 14, 55, 55, 14, -4, -1 }, { -1, -4, 13, 54, 56, 15, -4, -1 }, - { -1, -4, 12, 53, 57, 16, -4, -1 }, { 0, -4, 10, 52, 58, 17, -4, -1 }, - { -1, -4, 9, 51, 59, 19, -4, -1 }, { -1, -4, 8, 50, 60, 20, -4, -1 }, - { 0, -4, 7, 49, 60, 21, -3, -2 }, { 0, -4, 6, 47, 61, 23, -3, -2 }, - { 0, -4, 5, 46, 62, 24, -3, -2 }, { 0, -4, 5, 45, 62, 25, -3, -2 }, - { 0, -4, 4, 43, 63, 27, -3, -2 }, { 0, -4, 3, 42, 63, 28, -2, -2 }, - { 0, -3, 2, 41, 63, 29, -2, -2 }, { 0, -3, 2, 39, 63, 31, -2, -2 }, - { 0, -3, 1, 38, 64, 32, -1, -3 }, { 0, -3, 1, 36, 64, 34, -1, -3 } -}; - -// Filters for interpolation (0.625-band) - note this also filters integer pels. -static const interp_kernel filteredinterp_filters625[(1 << SUBPEL_BITS)] = { - { -1, -8, 33, 80, 33, -8, -1, 0 }, { -1, -8, 30, 80, 35, -8, -1, 1 }, - { -1, -8, 28, 80, 37, -7, -2, 1 }, { 0, -8, 26, 79, 39, -7, -2, 1 }, - { 0, -8, 24, 79, 41, -7, -2, 1 }, { 0, -8, 22, 78, 43, -6, -2, 1 }, - { 0, -8, 20, 78, 45, -5, -3, 1 }, { 0, -8, 18, 77, 48, -5, -3, 1 }, - { 0, -8, 16, 76, 50, -4, -3, 1 }, { 0, -8, 15, 75, 52, -3, -4, 1 }, - { 0, -7, 13, 74, 54, -3, -4, 1 }, { 0, -7, 11, 73, 56, -2, -4, 1 }, - { 0, -7, 10, 71, 58, -1, -4, 1 }, { 1, -7, 8, 70, 60, 0, -5, 1 }, - { 1, -6, 6, 68, 62, 1, -5, 1 }, { 1, -6, 5, 67, 63, 2, -5, 1 }, - { 1, -6, 4, 65, 65, 4, -6, 1 }, { 1, -5, 2, 63, 67, 5, -6, 1 }, - { 1, -5, 1, 62, 68, 6, -6, 1 }, { 1, -5, 0, 60, 70, 8, -7, 1 }, - { 1, -4, -1, 58, 71, 10, -7, 0 }, { 1, -4, -2, 56, 73, 11, -7, 0 }, - { 1, -4, -3, 54, 74, 13, -7, 0 }, { 1, -4, -3, 52, 75, 15, -8, 0 }, - { 1, -3, -4, 50, 76, 16, -8, 0 }, { 1, -3, -5, 48, 77, 18, -8, 0 }, - { 1, -3, -5, 45, 78, 20, -8, 0 }, { 1, -2, -6, 43, 78, 22, -8, 0 }, - { 1, -2, -7, 41, 79, 24, -8, 0 }, { 1, -2, -7, 39, 79, 26, -8, 0 }, - { 1, -2, -7, 37, 80, 28, -8, -1 }, { 1, -1, -8, 35, 80, 30, -8, -1 }, -}; - -// Filters for interpolation (0.75-band) - note this also filters integer pels. -static const interp_kernel filteredinterp_filters750[(1 << SUBPEL_BITS)] = { - { 2, -11, 25, 96, 25, -11, 2, 0 }, { 2, -11, 22, 96, 28, -11, 2, 0 }, - { 2, -10, 19, 95, 31, -11, 2, 0 }, { 2, -10, 17, 95, 34, -12, 2, 0 }, - { 2, -9, 14, 94, 37, -12, 2, 0 }, { 2, -8, 12, 93, 40, -12, 1, 0 }, - { 2, -8, 9, 92, 43, -12, 1, 1 }, { 2, -7, 7, 91, 46, -12, 1, 0 }, - { 2, -7, 5, 90, 49, -12, 1, 0 }, { 2, -6, 3, 88, 52, -12, 0, 1 }, - { 2, -5, 1, 86, 55, -12, 0, 1 }, { 2, -5, -1, 84, 58, -11, 0, 1 }, - { 2, -4, -2, 82, 61, -11, -1, 1 }, { 2, -4, -4, 80, 64, -10, -1, 1 }, - { 1, -3, -5, 77, 67, -9, -1, 1 }, { 1, -3, -6, 75, 70, -8, -2, 1 }, - { 1, -2, -7, 72, 72, -7, -2, 1 }, { 1, -2, -8, 70, 75, -6, -3, 1 }, - { 1, -1, -9, 67, 77, -5, -3, 1 }, { 1, -1, -10, 64, 80, -4, -4, 2 }, - { 1, -1, -11, 61, 82, -2, -4, 2 }, { 1, 0, -11, 58, 84, -1, -5, 2 }, - { 1, 0, -12, 55, 86, 1, -5, 2 }, { 1, 0, -12, 52, 88, 3, -6, 2 }, - { 0, 1, -12, 49, 90, 5, -7, 2 }, { 0, 1, -12, 46, 91, 7, -7, 2 }, - { 1, 1, -12, 43, 92, 9, -8, 2 }, { 0, 1, -12, 40, 93, 12, -8, 2 }, - { 0, 2, -12, 37, 94, 14, -9, 2 }, { 0, 2, -12, 34, 95, 17, -10, 2 }, - { 0, 2, -11, 31, 95, 19, -10, 2 }, { 0, 2, -11, 28, 96, 22, -11, 2 } -}; - -// Filters for interpolation (0.875-band) - note this also filters integer pels. -static const interp_kernel filteredinterp_filters875[(1 << SUBPEL_BITS)] = { - { 3, -8, 13, 112, 13, -8, 3, 0 }, { 3, -7, 10, 112, 17, -9, 3, -1 }, - { 2, -6, 7, 111, 21, -9, 3, -1 }, { 2, -5, 4, 111, 24, -10, 3, -1 }, - { 2, -4, 1, 110, 28, -11, 3, -1 }, { 1, -3, -1, 108, 32, -12, 4, -1 }, - { 1, -2, -3, 106, 36, -13, 4, -1 }, { 1, -1, -6, 105, 40, -14, 4, -1 }, - { 1, -1, -7, 102, 44, -14, 4, -1 }, { 1, 0, -9, 100, 48, -15, 4, -1 }, - { 1, 1, -11, 97, 53, -16, 4, -1 }, { 0, 1, -12, 95, 57, -16, 4, -1 }, - { 0, 2, -13, 91, 61, -16, 4, -1 }, { 0, 2, -14, 88, 65, -16, 4, -1 }, - { 0, 3, -15, 84, 69, -17, 4, 0 }, { 0, 3, -16, 81, 73, -16, 3, 0 }, - { 0, 3, -16, 77, 77, -16, 3, 0 }, { 0, 3, -16, 73, 81, -16, 3, 0 }, - { 0, 4, -17, 69, 84, -15, 3, 0 }, { -1, 4, -16, 65, 88, -14, 2, 0 }, - { -1, 4, -16, 61, 91, -13, 2, 0 }, { -1, 4, -16, 57, 95, -12, 1, 0 }, - { -1, 4, -16, 53, 97, -11, 1, 1 }, { -1, 4, -15, 48, 100, -9, 0, 1 }, - { -1, 4, -14, 44, 102, -7, -1, 1 }, { -1, 4, -14, 40, 105, -6, -1, 1 }, - { -1, 4, -13, 36, 106, -3, -2, 1 }, { -1, 4, -12, 32, 108, -1, -3, 1 }, - { -1, 3, -11, 28, 110, 1, -4, 2 }, { -1, 3, -10, 24, 111, 4, -5, 2 }, - { -1, 3, -9, 21, 111, 7, -6, 2 }, { -1, 3, -9, 17, 112, 10, -7, 3 } -}; - -// Filters for interpolation (full-band) - no filtering for integer pixels -static const interp_kernel filteredinterp_filters1000[(1 << SUBPEL_BITS)] = { - { 0, 0, 0, 128, 0, 0, 0, 0 }, { 0, 1, -3, 128, 3, -1, 0, 0 }, - { -1, 2, -6, 127, 7, -2, 1, 0 }, { -1, 3, -9, 126, 12, -4, 1, 0 }, - { -1, 4, -12, 125, 16, -5, 1, 0 }, { -1, 4, -14, 123, 20, -6, 2, 0 }, - { -1, 5, -15, 120, 25, -8, 2, 0 }, { -1, 5, -17, 118, 30, -9, 3, -1 }, - { -1, 6, -18, 114, 35, -10, 3, -1 }, { -1, 6, -19, 111, 41, -12, 3, -1 }, - { -1, 6, -20, 107, 46, -13, 4, -1 }, { -1, 6, -21, 103, 52, -14, 4, -1 }, - { -1, 6, -21, 99, 57, -16, 5, -1 }, { -1, 6, -21, 94, 63, -17, 5, -1 }, - { -1, 6, -20, 89, 68, -18, 5, -1 }, { -1, 6, -20, 84, 73, -19, 6, -1 }, - { -1, 6, -20, 79, 79, -20, 6, -1 }, { -1, 6, -19, 73, 84, -20, 6, -1 }, - { -1, 5, -18, 68, 89, -20, 6, -1 }, { -1, 5, -17, 63, 94, -21, 6, -1 }, - { -1, 5, -16, 57, 99, -21, 6, -1 }, { -1, 4, -14, 52, 103, -21, 6, -1 }, - { -1, 4, -13, 46, 107, -20, 6, -1 }, { -1, 3, -12, 41, 111, -19, 6, -1 }, - { -1, 3, -10, 35, 114, -18, 6, -1 }, { -1, 3, -9, 30, 118, -17, 5, -1 }, - { 0, 2, -8, 25, 120, -15, 5, -1 }, { 0, 2, -6, 20, 123, -14, 4, -1 }, - { 0, 1, -5, 16, 125, -12, 4, -1 }, { 0, 1, -4, 12, 126, -9, 3, -1 }, - { 0, 1, -2, 7, 127, -6, 2, -1 }, { 0, 0, -1, 3, 128, -3, 1, 0 } -}; - -// Filters for factor of 2 downsampling. -static const int16_t vp9_down2_symeven_half_filter[] = { 56, 12, -3, -1 }; -static const int16_t vp9_down2_symodd_half_filter[] = { 64, 35, 0, -3 }; - -static const interp_kernel *choose_interp_filter(int inlength, int outlength) { - int outlength16 = outlength * 16; - if (outlength16 >= inlength * 16) - return filteredinterp_filters1000; - else if (outlength16 >= inlength * 13) - return filteredinterp_filters875; - else if (outlength16 >= inlength * 11) - return filteredinterp_filters750; - else if (outlength16 >= inlength * 9) - return filteredinterp_filters625; - else - return filteredinterp_filters500; -} - -static void interpolate(const uint8_t *const input, int inlength, - uint8_t *output, int outlength) { - const int64_t delta = - (((uint64_t)inlength << 32) + outlength / 2) / outlength; - const int64_t offset = - inlength > outlength - ? (((int64_t)(inlength - outlength) << 31) + outlength / 2) / - outlength - : -(((int64_t)(outlength - inlength) << 31) + outlength / 2) / - outlength; - uint8_t *optr = output; - int x, x1, x2, sum, k, int_pel, sub_pel; - int64_t y; - - const interp_kernel *interp_filters = - choose_interp_filter(inlength, outlength); - - x = 0; - y = offset; - while ((y >> INTERP_PRECISION_BITS) < (INTERP_TAPS / 2 - 1)) { - x++; - y += delta; - } - x1 = x; - x = outlength - 1; - y = delta * x + offset; - while ((y >> INTERP_PRECISION_BITS) + (int64_t)(INTERP_TAPS / 2) >= - inlength) { - x--; - y -= delta; - } - x2 = x; - if (x1 > x2) { - for (x = 0, y = offset; x < outlength; ++x, y += delta) { - const int16_t *filter; - int_pel = y >> INTERP_PRECISION_BITS; - sub_pel = (y >> (INTERP_PRECISION_BITS - SUBPEL_BITS)) & SUBPEL_MASK; - filter = interp_filters[sub_pel]; - sum = 0; - for (k = 0; k < INTERP_TAPS; ++k) { - const int pk = int_pel - INTERP_TAPS / 2 + 1 + k; - sum += filter[k] * - input[(pk < 0 ? 0 : (pk >= inlength ? inlength - 1 : pk))]; - } - *optr++ = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)); - } - } else { - // Initial part. - for (x = 0, y = offset; x < x1; ++x, y += delta) { - const int16_t *filter; - int_pel = y >> INTERP_PRECISION_BITS; - sub_pel = (y >> (INTERP_PRECISION_BITS - SUBPEL_BITS)) & SUBPEL_MASK; - filter = interp_filters[sub_pel]; - sum = 0; - for (k = 0; k < INTERP_TAPS; ++k) - sum += filter[k] * input[(int_pel - INTERP_TAPS / 2 + 1 + k < 0 - ? 0 - : int_pel - INTERP_TAPS / 2 + 1 + k)]; - *optr++ = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)); - } - // Middle part. - for (; x <= x2; ++x, y += delta) { - const int16_t *filter; - int_pel = y >> INTERP_PRECISION_BITS; - sub_pel = (y >> (INTERP_PRECISION_BITS - SUBPEL_BITS)) & SUBPEL_MASK; - filter = interp_filters[sub_pel]; - sum = 0; - for (k = 0; k < INTERP_TAPS; ++k) - sum += filter[k] * input[int_pel - INTERP_TAPS / 2 + 1 + k]; - *optr++ = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)); - } - // End part. - for (; x < outlength; ++x, y += delta) { - const int16_t *filter; - int_pel = y >> INTERP_PRECISION_BITS; - sub_pel = (y >> (INTERP_PRECISION_BITS - SUBPEL_BITS)) & SUBPEL_MASK; - filter = interp_filters[sub_pel]; - sum = 0; - for (k = 0; k < INTERP_TAPS; ++k) - sum += filter[k] * input[(int_pel - INTERP_TAPS / 2 + 1 + k >= inlength - ? inlength - 1 - : int_pel - INTERP_TAPS / 2 + 1 + k)]; - *optr++ = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)); - } - } -} - -static void down2_symeven(const uint8_t *const input, int length, - uint8_t *output) { - // Actual filter len = 2 * filter_len_half. - const int16_t *filter = vp9_down2_symeven_half_filter; - const int filter_len_half = sizeof(vp9_down2_symeven_half_filter) / 2; - int i, j; - uint8_t *optr = output; - int l1 = filter_len_half; - int l2 = (length - filter_len_half); - l1 += (l1 & 1); - l2 += (l2 & 1); - if (l1 > l2) { - // Short input length. - for (i = 0; i < length; i += 2) { - int sum = (1 << (FILTER_BITS - 1)); - for (j = 0; j < filter_len_half; ++j) { - sum += (input[(i - j < 0 ? 0 : i - j)] + - input[(i + 1 + j >= length ? length - 1 : i + 1 + j)]) * - filter[j]; - } - sum >>= FILTER_BITS; - *optr++ = clip_pixel(sum); - } - } else { - // Initial part. - for (i = 0; i < l1; i += 2) { - int sum = (1 << (FILTER_BITS - 1)); - for (j = 0; j < filter_len_half; ++j) { - sum += (input[(i - j < 0 ? 0 : i - j)] + input[i + 1 + j]) * filter[j]; - } - sum >>= FILTER_BITS; - *optr++ = clip_pixel(sum); - } - // Middle part. - for (; i < l2; i += 2) { - int sum = (1 << (FILTER_BITS - 1)); - for (j = 0; j < filter_len_half; ++j) { - sum += (input[i - j] + input[i + 1 + j]) * filter[j]; - } - sum >>= FILTER_BITS; - *optr++ = clip_pixel(sum); - } - // End part. - for (; i < length; i += 2) { - int sum = (1 << (FILTER_BITS - 1)); - for (j = 0; j < filter_len_half; ++j) { - sum += (input[i - j] + - input[(i + 1 + j >= length ? length - 1 : i + 1 + j)]) * - filter[j]; - } - sum >>= FILTER_BITS; - *optr++ = clip_pixel(sum); - } - } -} - -static void down2_symodd(const uint8_t *const input, int length, - uint8_t *output) { - // Actual filter len = 2 * filter_len_half - 1. - const int16_t *filter = vp9_down2_symodd_half_filter; - const int filter_len_half = sizeof(vp9_down2_symodd_half_filter) / 2; - int i, j; - uint8_t *optr = output; - int l1 = filter_len_half - 1; - int l2 = (length - filter_len_half + 1); - l1 += (l1 & 1); - l2 += (l2 & 1); - if (l1 > l2) { - // Short input length. - for (i = 0; i < length; i += 2) { - int sum = (1 << (FILTER_BITS - 1)) + input[i] * filter[0]; - for (j = 1; j < filter_len_half; ++j) { - sum += (input[(i - j < 0 ? 0 : i - j)] + - input[(i + j >= length ? length - 1 : i + j)]) * - filter[j]; - } - sum >>= FILTER_BITS; - *optr++ = clip_pixel(sum); - } - } else { - // Initial part. - for (i = 0; i < l1; i += 2) { - int sum = (1 << (FILTER_BITS - 1)) + input[i] * filter[0]; - for (j = 1; j < filter_len_half; ++j) { - sum += (input[(i - j < 0 ? 0 : i - j)] + input[i + j]) * filter[j]; - } - sum >>= FILTER_BITS; - *optr++ = clip_pixel(sum); - } - // Middle part. - for (; i < l2; i += 2) { - int sum = (1 << (FILTER_BITS - 1)) + input[i] * filter[0]; - for (j = 1; j < filter_len_half; ++j) { - sum += (input[i - j] + input[i + j]) * filter[j]; - } - sum >>= FILTER_BITS; - *optr++ = clip_pixel(sum); - } - // End part. - for (; i < length; i += 2) { - int sum = (1 << (FILTER_BITS - 1)) + input[i] * filter[0]; - for (j = 1; j < filter_len_half; ++j) { - sum += (input[i - j] + input[(i + j >= length ? length - 1 : i + j)]) * - filter[j]; - } - sum >>= FILTER_BITS; - *optr++ = clip_pixel(sum); - } - } -} - -static int get_down2_length(int length, int steps) { - int s; - for (s = 0; s < steps; ++s) length = (length + 1) >> 1; - return length; -} - -static int get_down2_steps(int in_length, int out_length) { - int steps = 0; - int proj_in_length; - while ((proj_in_length = get_down2_length(in_length, 1)) >= out_length) { - ++steps; - in_length = proj_in_length; - if (in_length == 1) { - // Special case: we break because any further calls to get_down2_length() - // with be with length == 1, which return 1, resulting in an infinite - // loop. - break; - } - } - return steps; -} - -static void resize_multistep(const uint8_t *const input, int length, - uint8_t *output, int olength, uint8_t *otmp) { - int steps; - if (length == olength) { - memcpy(output, input, sizeof(output[0]) * length); - return; - } - steps = get_down2_steps(length, olength); - - if (steps > 0) { - int s; - uint8_t *out = NULL; - uint8_t *otmp2; - int filteredlength = length; - - assert(otmp != NULL); - otmp2 = otmp + get_down2_length(length, 1); - for (s = 0; s < steps; ++s) { - const int proj_filteredlength = get_down2_length(filteredlength, 1); - const uint8_t *const in = (s == 0 ? input : out); - if (s == steps - 1 && proj_filteredlength == olength) - out = output; - else - out = (s & 1 ? otmp2 : otmp); - if (filteredlength & 1) - down2_symodd(in, filteredlength, out); - else - down2_symeven(in, filteredlength, out); - filteredlength = proj_filteredlength; - } - if (filteredlength != olength) { - interpolate(out, filteredlength, output, olength); - } - } else { - interpolate(input, length, output, olength); - } -} - -static void fill_col_to_arr(uint8_t *img, int stride, int len, uint8_t *arr) { - int i; - uint8_t *iptr = img; - uint8_t *aptr = arr; - for (i = 0; i < len; ++i, iptr += stride) { - *aptr++ = *iptr; - } -} - -static void fill_arr_to_col(uint8_t *img, int stride, int len, uint8_t *arr) { - int i; - uint8_t *iptr = img; - uint8_t *aptr = arr; - for (i = 0; i < len; ++i, iptr += stride) { - *iptr = *aptr++; - } -} - -void vp9_resize_plane(const uint8_t *const input, int height, int width, - int in_stride, uint8_t *output, int height2, int width2, - int out_stride) { - int i; - uint8_t *intbuf = (uint8_t *)calloc(width2 * height, sizeof(*intbuf)); - uint8_t *tmpbuf = - (uint8_t *)calloc(width < height ? height : width, sizeof(*tmpbuf)); - uint8_t *arrbuf = (uint8_t *)calloc(height, sizeof(*arrbuf)); - uint8_t *arrbuf2 = (uint8_t *)calloc(height2, sizeof(*arrbuf2)); - if (intbuf == NULL || tmpbuf == NULL || arrbuf == NULL || arrbuf2 == NULL) - goto Error; - assert(width > 0); - assert(height > 0); - assert(width2 > 0); - assert(height2 > 0); - for (i = 0; i < height; ++i) - resize_multistep(input + in_stride * i, width, intbuf + width2 * i, width2, - tmpbuf); - for (i = 0; i < width2; ++i) { - fill_col_to_arr(intbuf + i, width2, height, arrbuf); - resize_multistep(arrbuf, height, arrbuf2, height2, tmpbuf); - fill_arr_to_col(output + i, out_stride, height2, arrbuf2); - } - -Error: - free(intbuf); - free(tmpbuf); - free(arrbuf); - free(arrbuf2); -} - -#if CONFIG_VP9_HIGHBITDEPTH -static void highbd_interpolate(const uint16_t *const input, int inlength, - uint16_t *output, int outlength, int bd) { - const int64_t delta = - (((uint64_t)inlength << 32) + outlength / 2) / outlength; - const int64_t offset = - inlength > outlength - ? (((int64_t)(inlength - outlength) << 31) + outlength / 2) / - outlength - : -(((int64_t)(outlength - inlength) << 31) + outlength / 2) / - outlength; - uint16_t *optr = output; - int x, x1, x2, sum, k, int_pel, sub_pel; - int64_t y; - - const interp_kernel *interp_filters = - choose_interp_filter(inlength, outlength); - - x = 0; - y = offset; - while ((y >> INTERP_PRECISION_BITS) < (INTERP_TAPS / 2 - 1)) { - x++; - y += delta; - } - x1 = x; - x = outlength - 1; - y = delta * x + offset; - while ((y >> INTERP_PRECISION_BITS) + (int64_t)(INTERP_TAPS / 2) >= - inlength) { - x--; - y -= delta; - } - x2 = x; - if (x1 > x2) { - for (x = 0, y = offset; x < outlength; ++x, y += delta) { - const int16_t *filter; - int_pel = y >> INTERP_PRECISION_BITS; - sub_pel = (y >> (INTERP_PRECISION_BITS - SUBPEL_BITS)) & SUBPEL_MASK; - filter = interp_filters[sub_pel]; - sum = 0; - for (k = 0; k < INTERP_TAPS; ++k) { - const int pk = int_pel - INTERP_TAPS / 2 + 1 + k; - sum += filter[k] * - input[(pk < 0 ? 0 : (pk >= inlength ? inlength - 1 : pk))]; - } - *optr++ = clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd); - } - } else { - // Initial part. - for (x = 0, y = offset; x < x1; ++x, y += delta) { - const int16_t *filter; - int_pel = y >> INTERP_PRECISION_BITS; - sub_pel = (y >> (INTERP_PRECISION_BITS - SUBPEL_BITS)) & SUBPEL_MASK; - filter = interp_filters[sub_pel]; - sum = 0; - for (k = 0; k < INTERP_TAPS; ++k) { - assert(int_pel - INTERP_TAPS / 2 + 1 + k < inlength); - sum += filter[k] * input[(int_pel - INTERP_TAPS / 2 + 1 + k < 0 - ? 0 - : int_pel - INTERP_TAPS / 2 + 1 + k)]; - } - *optr++ = clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd); - } - // Middle part. - for (; x <= x2; ++x, y += delta) { - const int16_t *filter; - int_pel = y >> INTERP_PRECISION_BITS; - sub_pel = (y >> (INTERP_PRECISION_BITS - SUBPEL_BITS)) & SUBPEL_MASK; - filter = interp_filters[sub_pel]; - sum = 0; - for (k = 0; k < INTERP_TAPS; ++k) - sum += filter[k] * input[int_pel - INTERP_TAPS / 2 + 1 + k]; - *optr++ = clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd); - } - // End part. - for (; x < outlength; ++x, y += delta) { - const int16_t *filter; - int_pel = y >> INTERP_PRECISION_BITS; - sub_pel = (y >> (INTERP_PRECISION_BITS - SUBPEL_BITS)) & SUBPEL_MASK; - filter = interp_filters[sub_pel]; - sum = 0; - for (k = 0; k < INTERP_TAPS; ++k) - sum += filter[k] * input[(int_pel - INTERP_TAPS / 2 + 1 + k >= inlength - ? inlength - 1 - : int_pel - INTERP_TAPS / 2 + 1 + k)]; - *optr++ = clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd); - } - } -} - -static void highbd_down2_symeven(const uint16_t *const input, int length, - uint16_t *output, int bd) { - // Actual filter len = 2 * filter_len_half. - static const int16_t *filter = vp9_down2_symeven_half_filter; - const int filter_len_half = sizeof(vp9_down2_symeven_half_filter) / 2; - int i, j; - uint16_t *optr = output; - int l1 = filter_len_half; - int l2 = (length - filter_len_half); - l1 += (l1 & 1); - l2 += (l2 & 1); - if (l1 > l2) { - // Short input length. - for (i = 0; i < length; i += 2) { - int sum = (1 << (FILTER_BITS - 1)); - for (j = 0; j < filter_len_half; ++j) { - sum += (input[(i - j < 0 ? 0 : i - j)] + - input[(i + 1 + j >= length ? length - 1 : i + 1 + j)]) * - filter[j]; - } - sum >>= FILTER_BITS; - *optr++ = clip_pixel_highbd(sum, bd); - } - } else { - // Initial part. - for (i = 0; i < l1; i += 2) { - int sum = (1 << (FILTER_BITS - 1)); - for (j = 0; j < filter_len_half; ++j) { - sum += (input[(i - j < 0 ? 0 : i - j)] + input[i + 1 + j]) * filter[j]; - } - sum >>= FILTER_BITS; - *optr++ = clip_pixel_highbd(sum, bd); - } - // Middle part. - for (; i < l2; i += 2) { - int sum = (1 << (FILTER_BITS - 1)); - for (j = 0; j < filter_len_half; ++j) { - sum += (input[i - j] + input[i + 1 + j]) * filter[j]; - } - sum >>= FILTER_BITS; - *optr++ = clip_pixel_highbd(sum, bd); - } - // End part. - for (; i < length; i += 2) { - int sum = (1 << (FILTER_BITS - 1)); - for (j = 0; j < filter_len_half; ++j) { - sum += (input[i - j] + - input[(i + 1 + j >= length ? length - 1 : i + 1 + j)]) * - filter[j]; - } - sum >>= FILTER_BITS; - *optr++ = clip_pixel_highbd(sum, bd); - } - } -} - -static void highbd_down2_symodd(const uint16_t *const input, int length, - uint16_t *output, int bd) { - // Actual filter len = 2 * filter_len_half - 1. - static const int16_t *filter = vp9_down2_symodd_half_filter; - const int filter_len_half = sizeof(vp9_down2_symodd_half_filter) / 2; - int i, j; - uint16_t *optr = output; - int l1 = filter_len_half - 1; - int l2 = (length - filter_len_half + 1); - l1 += (l1 & 1); - l2 += (l2 & 1); - if (l1 > l2) { - // Short input length. - for (i = 0; i < length; i += 2) { - int sum = (1 << (FILTER_BITS - 1)) + input[i] * filter[0]; - for (j = 1; j < filter_len_half; ++j) { - sum += (input[(i - j < 0 ? 0 : i - j)] + - input[(i + j >= length ? length - 1 : i + j)]) * - filter[j]; - } - sum >>= FILTER_BITS; - *optr++ = clip_pixel_highbd(sum, bd); - } - } else { - // Initial part. - for (i = 0; i < l1; i += 2) { - int sum = (1 << (FILTER_BITS - 1)) + input[i] * filter[0]; - for (j = 1; j < filter_len_half; ++j) { - sum += (input[(i - j < 0 ? 0 : i - j)] + input[i + j]) * filter[j]; - } - sum >>= FILTER_BITS; - *optr++ = clip_pixel_highbd(sum, bd); - } - // Middle part. - for (; i < l2; i += 2) { - int sum = (1 << (FILTER_BITS - 1)) + input[i] * filter[0]; - for (j = 1; j < filter_len_half; ++j) { - sum += (input[i - j] + input[i + j]) * filter[j]; - } - sum >>= FILTER_BITS; - *optr++ = clip_pixel_highbd(sum, bd); - } - // End part. - for (; i < length; i += 2) { - int sum = (1 << (FILTER_BITS - 1)) + input[i] * filter[0]; - for (j = 1; j < filter_len_half; ++j) { - sum += (input[i - j] + input[(i + j >= length ? length - 1 : i + j)]) * - filter[j]; - } - sum >>= FILTER_BITS; - *optr++ = clip_pixel_highbd(sum, bd); - } - } -} - -static void highbd_resize_multistep(const uint16_t *const input, int length, - uint16_t *output, int olength, - uint16_t *otmp, int bd) { - int steps; - if (length == olength) { - memcpy(output, input, sizeof(output[0]) * length); - return; - } - steps = get_down2_steps(length, olength); - - if (steps > 0) { - int s; - uint16_t *out = NULL; - uint16_t *otmp2; - int filteredlength = length; - - assert(otmp != NULL); - otmp2 = otmp + get_down2_length(length, 1); - for (s = 0; s < steps; ++s) { - const int proj_filteredlength = get_down2_length(filteredlength, 1); - const uint16_t *const in = (s == 0 ? input : out); - if (s == steps - 1 && proj_filteredlength == olength) - out = output; - else - out = (s & 1 ? otmp2 : otmp); - if (filteredlength & 1) - highbd_down2_symodd(in, filteredlength, out, bd); - else - highbd_down2_symeven(in, filteredlength, out, bd); - filteredlength = proj_filteredlength; - } - if (filteredlength != olength) { - highbd_interpolate(out, filteredlength, output, olength, bd); - } - } else { - highbd_interpolate(input, length, output, olength, bd); - } -} - -static void highbd_fill_col_to_arr(uint16_t *img, int stride, int len, - uint16_t *arr) { - int i; - uint16_t *iptr = img; - uint16_t *aptr = arr; - for (i = 0; i < len; ++i, iptr += stride) { - *aptr++ = *iptr; - } -} - -static void highbd_fill_arr_to_col(uint16_t *img, int stride, int len, - uint16_t *arr) { - int i; - uint16_t *iptr = img; - uint16_t *aptr = arr; - for (i = 0; i < len; ++i, iptr += stride) { - *iptr = *aptr++; - } -} - -void vp9_highbd_resize_plane(const uint8_t *const input, int height, int width, - int in_stride, uint8_t *output, int height2, - int width2, int out_stride, int bd) { - int i; - uint16_t *intbuf = (uint16_t *)malloc(sizeof(uint16_t) * width2 * height); - uint16_t *tmpbuf = - (uint16_t *)malloc(sizeof(uint16_t) * (width < height ? height : width)); - uint16_t *arrbuf = (uint16_t *)malloc(sizeof(uint16_t) * height); - uint16_t *arrbuf2 = (uint16_t *)malloc(sizeof(uint16_t) * height2); - if (intbuf == NULL || tmpbuf == NULL || arrbuf == NULL || arrbuf2 == NULL) - goto Error; - assert(width > 0); - assert(height > 0); - assert(width2 > 0); - assert(height2 > 0); - for (i = 0; i < height; ++i) { - highbd_resize_multistep(CONVERT_TO_SHORTPTR(input + in_stride * i), width, - intbuf + width2 * i, width2, tmpbuf, bd); - } - for (i = 0; i < width2; ++i) { - highbd_fill_col_to_arr(intbuf + i, width2, height, arrbuf); - highbd_resize_multistep(arrbuf, height, arrbuf2, height2, tmpbuf, bd); - highbd_fill_arr_to_col(CONVERT_TO_SHORTPTR(output + i), out_stride, height2, - arrbuf2); - } - -Error: - free(intbuf); - free(tmpbuf); - free(arrbuf); - free(arrbuf2); -} -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_resize.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_resize.h deleted file mode 100644 index 7a984dbc..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_resize.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_RESIZE_H_ -#define VPX_VP9_ENCODER_VP9_RESIZE_H_ - -#include -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vp9_resize_plane(const uint8_t *const input, int height, int width, - int in_stride, uint8_t *output, int height2, int width2, - int out_stride); - -#if CONFIG_VP9_HIGHBITDEPTH -void vp9_highbd_resize_plane(const uint8_t *const input, int height, int width, - int in_stride, uint8_t *output, int height2, - int width2, int out_stride, int bd); -#endif // CONFIG_VP9_HIGHBITDEPTH - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_RESIZE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_segmentation.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_segmentation.c deleted file mode 100644 index d75488a8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_segmentation.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "vpx_mem/vpx_mem.h" - -#include "vp9/common/vp9_pred_common.h" -#include "vp9/common/vp9_tile_common.h" - -#include "vp9/encoder/vp9_cost.h" -#include "vp9/encoder/vp9_segmentation.h" - -void vp9_enable_segmentation(struct segmentation *seg) { - seg->enabled = 1; - seg->update_map = 1; - seg->update_data = 1; -} - -void vp9_disable_segmentation(struct segmentation *seg) { - seg->enabled = 0; - seg->update_map = 0; - seg->update_data = 0; -} - -void vp9_set_segment_data(struct segmentation *seg, signed char *feature_data, - unsigned char abs_delta) { - seg->abs_delta = abs_delta; - - memcpy(seg->feature_data, feature_data, sizeof(seg->feature_data)); -} -void vp9_disable_segfeature(struct segmentation *seg, int segment_id, - SEG_LVL_FEATURES feature_id) { - seg->feature_mask[segment_id] &= ~(1u << feature_id); -} - -void vp9_clear_segdata(struct segmentation *seg, int segment_id, - SEG_LVL_FEATURES feature_id) { - seg->feature_data[segment_id][feature_id] = 0; -} - -void vp9_psnr_aq_mode_setup(struct segmentation *seg) { - int i; - - vp9_enable_segmentation(seg); - vp9_clearall_segfeatures(seg); - seg->abs_delta = SEGMENT_DELTADATA; - - for (i = 0; i < MAX_SEGMENTS; ++i) { - vp9_set_segdata(seg, i, SEG_LVL_ALT_Q, 2 * (i - (MAX_SEGMENTS / 2))); - vp9_enable_segfeature(seg, i, SEG_LVL_ALT_Q); - } -} - -void vp9_perceptual_aq_mode_setup(struct VP9_COMP *cpi, - struct segmentation *seg) { - const VP9_COMMON *cm = &cpi->common; - const int seg_counts = cpi->kmeans_ctr_num; - const int base_qindex = cm->base_qindex; - const double base_qstep = vp9_convert_qindex_to_q(base_qindex, cm->bit_depth); - const double mid_ctr = cpi->kmeans_ctr_ls[seg_counts / 2]; - const double var_diff_scale = 4.0; - int i; - - assert(seg_counts <= MAX_SEGMENTS); - - vp9_enable_segmentation(seg); - vp9_clearall_segfeatures(seg); - seg->abs_delta = SEGMENT_DELTADATA; - - for (i = 0; i < seg_counts / 2; ++i) { - double wiener_var_diff = mid_ctr - cpi->kmeans_ctr_ls[i]; - double target_qstep = base_qstep / (1.0 + wiener_var_diff / var_diff_scale); - int target_qindex = vp9_convert_q_to_qindex(target_qstep, cm->bit_depth); - assert(wiener_var_diff >= 0.0); - - vp9_set_segdata(seg, i, SEG_LVL_ALT_Q, target_qindex - base_qindex); - vp9_enable_segfeature(seg, i, SEG_LVL_ALT_Q); - } - - vp9_set_segdata(seg, i, SEG_LVL_ALT_Q, 0); - vp9_enable_segfeature(seg, i, SEG_LVL_ALT_Q); - - for (; i < seg_counts; ++i) { - double wiener_var_diff = cpi->kmeans_ctr_ls[i] - mid_ctr; - double target_qstep = base_qstep * (1.0 + wiener_var_diff / var_diff_scale); - int target_qindex = vp9_convert_q_to_qindex(target_qstep, cm->bit_depth); - assert(wiener_var_diff >= 0.0); - - vp9_set_segdata(seg, i, SEG_LVL_ALT_Q, target_qindex - base_qindex); - vp9_enable_segfeature(seg, i, SEG_LVL_ALT_Q); - } -} - -// Based on set of segment counts calculate a probability tree -static void calc_segtree_probs(int *segcounts, vpx_prob *segment_tree_probs) { - // Work out probabilities of each segment - const int c01 = segcounts[0] + segcounts[1]; - const int c23 = segcounts[2] + segcounts[3]; - const int c45 = segcounts[4] + segcounts[5]; - const int c67 = segcounts[6] + segcounts[7]; - - segment_tree_probs[0] = get_binary_prob(c01 + c23, c45 + c67); - segment_tree_probs[1] = get_binary_prob(c01, c23); - segment_tree_probs[2] = get_binary_prob(c45, c67); - segment_tree_probs[3] = get_binary_prob(segcounts[0], segcounts[1]); - segment_tree_probs[4] = get_binary_prob(segcounts[2], segcounts[3]); - segment_tree_probs[5] = get_binary_prob(segcounts[4], segcounts[5]); - segment_tree_probs[6] = get_binary_prob(segcounts[6], segcounts[7]); -} - -// Based on set of segment counts and probabilities calculate a cost estimate -static int cost_segmap(int *segcounts, vpx_prob *probs) { - const int c01 = segcounts[0] + segcounts[1]; - const int c23 = segcounts[2] + segcounts[3]; - const int c45 = segcounts[4] + segcounts[5]; - const int c67 = segcounts[6] + segcounts[7]; - const int c0123 = c01 + c23; - const int c4567 = c45 + c67; - - // Cost the top node of the tree - int cost = c0123 * vp9_cost_zero(probs[0]) + c4567 * vp9_cost_one(probs[0]); - - // Cost subsequent levels - if (c0123 > 0) { - cost += c01 * vp9_cost_zero(probs[1]) + c23 * vp9_cost_one(probs[1]); - - if (c01 > 0) - cost += segcounts[0] * vp9_cost_zero(probs[3]) + - segcounts[1] * vp9_cost_one(probs[3]); - if (c23 > 0) - cost += segcounts[2] * vp9_cost_zero(probs[4]) + - segcounts[3] * vp9_cost_one(probs[4]); - } - - if (c4567 > 0) { - cost += c45 * vp9_cost_zero(probs[2]) + c67 * vp9_cost_one(probs[2]); - - if (c45 > 0) - cost += segcounts[4] * vp9_cost_zero(probs[5]) + - segcounts[5] * vp9_cost_one(probs[5]); - if (c67 > 0) - cost += segcounts[6] * vp9_cost_zero(probs[6]) + - segcounts[7] * vp9_cost_one(probs[6]); - } - - return cost; -} - -static void count_segs(const VP9_COMMON *cm, MACROBLOCKD *xd, - const TileInfo *tile, MODE_INFO **mi, - int *no_pred_segcounts, - int (*temporal_predictor_count)[2], - int *t_unpred_seg_counts, int bw, int bh, int mi_row, - int mi_col) { - int segment_id; - - if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - - xd->mi = mi; - segment_id = xd->mi[0]->segment_id; - - set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); - - // Count the number of hits on each segment with no prediction - no_pred_segcounts[segment_id]++; - - // Temporal prediction not allowed on key frames - if (cm->frame_type != KEY_FRAME) { - const BLOCK_SIZE bsize = xd->mi[0]->sb_type; - // Test to see if the segment id matches the predicted value. - const int pred_segment_id = - get_segment_id(cm, cm->last_frame_seg_map, bsize, mi_row, mi_col); - const int pred_flag = pred_segment_id == segment_id; - const int pred_context = vp9_get_pred_context_seg_id(xd); - - // Store the prediction status for this mb and update counts - // as appropriate - xd->mi[0]->seg_id_predicted = pred_flag; - temporal_predictor_count[pred_context][pred_flag]++; - - // Update the "unpredicted" segment count - if (!pred_flag) t_unpred_seg_counts[segment_id]++; - } -} - -static void count_segs_sb(const VP9_COMMON *cm, MACROBLOCKD *xd, - const TileInfo *tile, MODE_INFO **mi, - int *no_pred_segcounts, - int (*temporal_predictor_count)[2], - int *t_unpred_seg_counts, int mi_row, int mi_col, - BLOCK_SIZE bsize) { - const int mis = cm->mi_stride; - int bw, bh; - const int bs = num_8x8_blocks_wide_lookup[bsize], hbs = bs / 2; - - if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - - bw = num_8x8_blocks_wide_lookup[mi[0]->sb_type]; - bh = num_8x8_blocks_high_lookup[mi[0]->sb_type]; - - if (bw == bs && bh == bs) { - count_segs(cm, xd, tile, mi, no_pred_segcounts, temporal_predictor_count, - t_unpred_seg_counts, bs, bs, mi_row, mi_col); - } else if (bw == bs && bh < bs) { - count_segs(cm, xd, tile, mi, no_pred_segcounts, temporal_predictor_count, - t_unpred_seg_counts, bs, hbs, mi_row, mi_col); - count_segs(cm, xd, tile, mi + hbs * mis, no_pred_segcounts, - temporal_predictor_count, t_unpred_seg_counts, bs, hbs, - mi_row + hbs, mi_col); - } else if (bw < bs && bh == bs) { - count_segs(cm, xd, tile, mi, no_pred_segcounts, temporal_predictor_count, - t_unpred_seg_counts, hbs, bs, mi_row, mi_col); - count_segs(cm, xd, tile, mi + hbs, no_pred_segcounts, - temporal_predictor_count, t_unpred_seg_counts, hbs, bs, mi_row, - mi_col + hbs); - } else { - const BLOCK_SIZE subsize = subsize_lookup[PARTITION_SPLIT][bsize]; - int n; - - assert(bw < bs && bh < bs); - - for (n = 0; n < 4; n++) { - const int mi_dc = hbs * (n & 1); - const int mi_dr = hbs * (n >> 1); - - count_segs_sb(cm, xd, tile, &mi[mi_dr * mis + mi_dc], no_pred_segcounts, - temporal_predictor_count, t_unpred_seg_counts, - mi_row + mi_dr, mi_col + mi_dc, subsize); - } - } -} - -void vp9_choose_segmap_coding_method(VP9_COMMON *cm, MACROBLOCKD *xd) { - struct segmentation *seg = &cm->seg; - - int no_pred_cost; - int t_pred_cost = INT_MAX; - - int i, tile_col, mi_row, mi_col; - - int temporal_predictor_count[PREDICTION_PROBS][2] = { { 0 } }; - int no_pred_segcounts[MAX_SEGMENTS] = { 0 }; - int t_unpred_seg_counts[MAX_SEGMENTS] = { 0 }; - - vpx_prob no_pred_tree[SEG_TREE_PROBS]; - vpx_prob t_pred_tree[SEG_TREE_PROBS]; - vpx_prob t_nopred_prob[PREDICTION_PROBS]; - - // Set default state for the segment tree probabilities and the - // temporal coding probabilities - memset(seg->tree_probs, 255, sizeof(seg->tree_probs)); - memset(seg->pred_probs, 255, sizeof(seg->pred_probs)); - - // First of all generate stats regarding how well the last segment map - // predicts this one - for (tile_col = 0; tile_col < 1 << cm->log2_tile_cols; tile_col++) { - TileInfo tile; - MODE_INFO **mi_ptr; - vp9_tile_init(&tile, cm, 0, tile_col); - - mi_ptr = cm->mi_grid_visible + tile.mi_col_start; - for (mi_row = 0; mi_row < cm->mi_rows; - mi_row += 8, mi_ptr += 8 * cm->mi_stride) { - MODE_INFO **mi = mi_ptr; - for (mi_col = tile.mi_col_start; mi_col < tile.mi_col_end; - mi_col += 8, mi += 8) - count_segs_sb(cm, xd, &tile, mi, no_pred_segcounts, - temporal_predictor_count, t_unpred_seg_counts, mi_row, - mi_col, BLOCK_64X64); - } - } - - // Work out probability tree for coding segments without prediction - // and the cost. - calc_segtree_probs(no_pred_segcounts, no_pred_tree); - no_pred_cost = cost_segmap(no_pred_segcounts, no_pred_tree); - - // Key frames cannot use temporal prediction - if (!frame_is_intra_only(cm)) { - // Work out probability tree for coding those segments not - // predicted using the temporal method and the cost. - calc_segtree_probs(t_unpred_seg_counts, t_pred_tree); - t_pred_cost = cost_segmap(t_unpred_seg_counts, t_pred_tree); - - // Add in the cost of the signaling for each prediction context. - for (i = 0; i < PREDICTION_PROBS; i++) { - const int count0 = temporal_predictor_count[i][0]; - const int count1 = temporal_predictor_count[i][1]; - - t_nopred_prob[i] = get_binary_prob(count0, count1); - - // Add in the predictor signaling cost - t_pred_cost += count0 * vp9_cost_zero(t_nopred_prob[i]) + - count1 * vp9_cost_one(t_nopred_prob[i]); - } - } - - // Now choose which coding method to use. - if (t_pred_cost < no_pred_cost) { - seg->temporal_update = 1; - memcpy(seg->tree_probs, t_pred_tree, sizeof(t_pred_tree)); - memcpy(seg->pred_probs, t_nopred_prob, sizeof(t_nopred_prob)); - } else { - seg->temporal_update = 0; - memcpy(seg->tree_probs, no_pred_tree, sizeof(no_pred_tree)); - } -} - -void vp9_reset_segment_features(struct segmentation *seg) { - // Set up default state for MB feature flags - seg->enabled = 0; - seg->update_map = 0; - seg->update_data = 0; - memset(seg->tree_probs, 255, sizeof(seg->tree_probs)); - vp9_clearall_segfeatures(seg); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_segmentation.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_segmentation.h deleted file mode 100644 index 9404c38b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_segmentation.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_SEGMENTATION_H_ -#define VPX_VP9_ENCODER_VP9_SEGMENTATION_H_ - -#include "vp9/common/vp9_blockd.h" -#include "vp9/encoder/vp9_encoder.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vp9_enable_segmentation(struct segmentation *seg); -void vp9_disable_segmentation(struct segmentation *seg); - -void vp9_disable_segfeature(struct segmentation *seg, int segment_id, - SEG_LVL_FEATURES feature_id); -void vp9_clear_segdata(struct segmentation *seg, int segment_id, - SEG_LVL_FEATURES feature_id); - -void vp9_psnr_aq_mode_setup(struct segmentation *seg); - -void vp9_perceptual_aq_mode_setup(struct VP9_COMP *cpi, - struct segmentation *seg); - -// The values given for each segment can be either deltas (from the default -// value chosen for the frame) or absolute values. -// -// Valid range for abs values is (0-127 for MB_LVL_ALT_Q), (0-63 for -// SEGMENT_ALT_LF) -// Valid range for delta values are (+/-127 for MB_LVL_ALT_Q), (+/-63 for -// SEGMENT_ALT_LF) -// -// abs_delta = SEGMENT_DELTADATA (deltas) abs_delta = SEGMENT_ABSDATA (use -// the absolute values given). -void vp9_set_segment_data(struct segmentation *seg, signed char *feature_data, - unsigned char abs_delta); - -void vp9_choose_segmap_coding_method(VP9_COMMON *cm, MACROBLOCKD *xd); - -void vp9_reset_segment_features(struct segmentation *seg); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_SEGMENTATION_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_skin_detection.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_skin_detection.c deleted file mode 100644 index cc6c9677..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_skin_detection.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "vp9/common/vp9_blockd.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_skin_detection.h" - -int vp9_compute_skin_block(const uint8_t *y, const uint8_t *u, const uint8_t *v, - int stride, int strideuv, int bsize, - int consec_zeromv, int curr_motion_magn) { - // No skin if block has been zero/small motion for long consecutive time. - if (consec_zeromv > 60 && curr_motion_magn == 0) { - return 0; - } else { - int motion = 1; - // Take center pixel in block to determine is_skin. - const int y_width_shift = (4 << b_width_log2_lookup[bsize]) >> 1; - const int y_height_shift = (4 << b_height_log2_lookup[bsize]) >> 1; - const int uv_width_shift = y_width_shift >> 1; - const int uv_height_shift = y_height_shift >> 1; - const uint8_t ysource = y[y_height_shift * stride + y_width_shift]; - const uint8_t usource = u[uv_height_shift * strideuv + uv_width_shift]; - const uint8_t vsource = v[uv_height_shift * strideuv + uv_width_shift]; - - if (consec_zeromv > 25 && curr_motion_magn == 0) motion = 0; - return vpx_skin_pixel(ysource, usource, vsource, motion); - } -} - -void vp9_compute_skin_sb(VP9_COMP *const cpi, BLOCK_SIZE bsize, int mi_row, - int mi_col) { - int i, j, num_bl; - VP9_COMMON *const cm = &cpi->common; - const uint8_t *src_y = cpi->Source->y_buffer; - const uint8_t *src_u = cpi->Source->u_buffer; - const uint8_t *src_v = cpi->Source->v_buffer; - const int src_ystride = cpi->Source->y_stride; - const int src_uvstride = cpi->Source->uv_stride; - const int y_bsize = 4 << b_width_log2_lookup[bsize]; - const int uv_bsize = y_bsize >> 1; - const int shy = (y_bsize == 8) ? 3 : 4; - const int shuv = shy - 1; - const int fac = y_bsize / 8; - const int y_shift = src_ystride * (mi_row << 3) + (mi_col << 3); - const int uv_shift = src_uvstride * (mi_row << 2) + (mi_col << 2); - const int mi_row_limit = VPXMIN(mi_row + 8, cm->mi_rows - 2); - const int mi_col_limit = VPXMIN(mi_col + 8, cm->mi_cols - 2); - src_y += y_shift; - src_u += uv_shift; - src_v += uv_shift; - - for (i = mi_row; i < mi_row_limit; i += fac) { - num_bl = 0; - for (j = mi_col; j < mi_col_limit; j += fac) { - int consec_zeromv = 0; - int bl_index = i * cm->mi_cols + j; - int bl_index1 = bl_index + 1; - int bl_index2 = bl_index + cm->mi_cols; - int bl_index3 = bl_index2 + 1; - // Don't detect skin on the boundary. - if (i == 0 || j == 0) continue; - if (bsize == BLOCK_8X8) - consec_zeromv = cpi->consec_zero_mv[bl_index]; - else - consec_zeromv = VPXMIN(cpi->consec_zero_mv[bl_index], - VPXMIN(cpi->consec_zero_mv[bl_index1], - VPXMIN(cpi->consec_zero_mv[bl_index2], - cpi->consec_zero_mv[bl_index3]))); - cpi->skin_map[bl_index] = - vp9_compute_skin_block(src_y, src_u, src_v, src_ystride, src_uvstride, - bsize, consec_zeromv, 0); - num_bl++; - src_y += y_bsize; - src_u += uv_bsize; - src_v += uv_bsize; - } - src_y += (src_ystride << shy) - (num_bl << shy); - src_u += (src_uvstride << shuv) - (num_bl << shuv); - src_v += (src_uvstride << shuv) - (num_bl << shuv); - } - - // Remove isolated skin blocks (none of its neighbors are skin) and isolated - // non-skin blocks (all of its neighbors are skin). - // Skip 4 corner blocks which have only 3 neighbors to remove isolated skin - // blocks. Skip superblock borders to remove isolated non-skin blocks. - for (i = mi_row; i < mi_row_limit; i += fac) { - for (j = mi_col; j < mi_col_limit; j += fac) { - int bl_index = i * cm->mi_cols + j; - int num_neighbor = 0; - int mi, mj; - int non_skin_threshold = 8; - // Skip 4 corners. - if ((i == mi_row && (j == mi_col || j == mi_col_limit - fac)) || - (i == mi_row_limit - fac && (j == mi_col || j == mi_col_limit - fac))) - continue; - // There are only 5 neighbors for non-skin blocks on the border. - if (i == mi_row || i == mi_row_limit - fac || j == mi_col || - j == mi_col_limit - fac) - non_skin_threshold = 5; - - for (mi = -fac; mi <= fac; mi += fac) { - for (mj = -fac; mj <= fac; mj += fac) { - if (i + mi >= mi_row && i + mi < mi_row_limit && j + mj >= mi_col && - j + mj < mi_col_limit) { - int bl_neighbor_index = (i + mi) * cm->mi_cols + j + mj; - if (cpi->skin_map[bl_neighbor_index]) num_neighbor++; - } - } - } - - if (cpi->skin_map[bl_index] && num_neighbor < 2) - cpi->skin_map[bl_index] = 0; - if (!cpi->skin_map[bl_index] && num_neighbor == non_skin_threshold) - cpi->skin_map[bl_index] = 1; - } - } -} - -#ifdef OUTPUT_YUV_SKINMAP -// For viewing skin map on input source. -void vp9_output_skin_map(VP9_COMP *const cpi, FILE *yuv_skinmap_file) { - int i, j, mi_row, mi_col, num_bl; - VP9_COMMON *const cm = &cpi->common; - uint8_t *y; - const uint8_t *src_y = cpi->Source->y_buffer; - const int src_ystride = cpi->Source->y_stride; - const int y_bsize = 16; // Use 8x8 or 16x16. - const int shy = (y_bsize == 8) ? 3 : 4; - const int fac = y_bsize / 8; - - YV12_BUFFER_CONFIG skinmap; - memset(&skinmap, 0, sizeof(YV12_BUFFER_CONFIG)); - if (vpx_alloc_frame_buffer(&skinmap, cm->width, cm->height, cm->subsampling_x, - cm->subsampling_y, VP9_ENC_BORDER_IN_PIXELS, - cm->byte_alignment)) { - vpx_free_frame_buffer(&skinmap); - return; - } - memset(skinmap.buffer_alloc, 128, skinmap.frame_size); - y = skinmap.y_buffer; - // Loop through blocks and set skin map based on center pixel of block. - // Set y to white for skin block, otherwise set to source with gray scale. - // Ignore rightmost/bottom boundary blocks. - for (mi_row = 0; mi_row < cm->mi_rows - 1; mi_row += fac) { - num_bl = 0; - for (mi_col = 0; mi_col < cm->mi_cols - 1; mi_col += fac) { - const int block_index = mi_row * cm->mi_cols + mi_col; - const int is_skin = cpi->skin_map[block_index]; - for (i = 0; i < y_bsize; i++) { - for (j = 0; j < y_bsize; j++) { - y[i * src_ystride + j] = is_skin ? 255 : src_y[i * src_ystride + j]; - } - } - num_bl++; - y += y_bsize; - src_y += y_bsize; - } - y += (src_ystride << shy) - (num_bl << shy); - src_y += (src_ystride << shy) - (num_bl << shy); - } - vpx_write_yuv_frame(yuv_skinmap_file, &skinmap); - vpx_free_frame_buffer(&skinmap); -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_skin_detection.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_skin_detection.h deleted file mode 100644 index 46a722af..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_skin_detection.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_SKIN_DETECTION_H_ -#define VPX_VP9_ENCODER_VP9_SKIN_DETECTION_H_ - -#include "vp9/common/vp9_blockd.h" -#include "vpx_dsp/skin_detection.h" -#include "vpx_util/vpx_write_yuv_frame.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct VP9_COMP; - -int vp9_compute_skin_block(const uint8_t *y, const uint8_t *u, const uint8_t *v, - int stride, int strideuv, int bsize, - int consec_zeromv, int curr_motion_magn); - -void vp9_compute_skin_sb(struct VP9_COMP *const cpi, BLOCK_SIZE bsize, - int mi_row, int mi_col); - -#ifdef OUTPUT_YUV_SKINMAP -// For viewing skin map on input source. -void vp9_output_skin_map(struct VP9_COMP *const cpi, FILE *yuv_skinmap_file); -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_SKIN_DETECTION_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_speed_features.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_speed_features.c deleted file mode 100644 index fb65c28c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_speed_features.c +++ /dev/null @@ -1,1097 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_speed_features.h" -#include "vp9/encoder/vp9_rdopt.h" -#include "vpx_dsp/vpx_dsp_common.h" - -// Mesh search patters for various speed settings -// Define 2 mesh density levels for FC_GRAPHICS_ANIMATION content type and non -// FC_GRAPHICS_ANIMATION content type. -static MESH_PATTERN best_quality_mesh_pattern[2][MAX_MESH_STEP] = { - { { 64, 4 }, { 28, 2 }, { 15, 1 }, { 7, 1 } }, - { { 64, 8 }, { 28, 4 }, { 15, 1 }, { 7, 1 } }, -}; - -#if !CONFIG_REALTIME_ONLY -// Define 3 mesh density levels to control the number of searches. -#define MESH_DENSITY_LEVELS 3 -static MESH_PATTERN - good_quality_mesh_patterns[MESH_DENSITY_LEVELS][MAX_MESH_STEP] = { - { { 64, 8 }, { 28, 4 }, { 15, 1 }, { 7, 1 } }, - { { 64, 8 }, { 14, 2 }, { 7, 1 }, { 7, 1 } }, - { { 64, 16 }, { 24, 8 }, { 12, 4 }, { 7, 1 } }, - }; - -// Intra only frames, golden frames (except alt ref overlays) and -// alt ref frames tend to be coded at a higher than ambient quality -static int frame_is_boosted(const VP9_COMP *cpi) { - return frame_is_kf_gf_arf(cpi); -} - -// Sets a partition size down to which the auto partition code will always -// search (can go lower), based on the image dimensions. The logic here -// is that the extent to which ringing artefacts are offensive, depends -// partly on the screen area that over which they propagate. Propagation is -// limited by transform block size but the screen area take up by a given block -// size will be larger for a small image format stretched to full screen. -static BLOCK_SIZE set_partition_min_limit(VP9_COMMON *const cm) { - unsigned int screen_area = (cm->width * cm->height); - - // Select block size based on image format size. - if (screen_area < 1280 * 720) { - // Formats smaller in area than 720P - return BLOCK_4X4; - } else if (screen_area < 1920 * 1080) { - // Format >= 720P and < 1080P - return BLOCK_8X8; - } else { - // Formats 1080P and up - return BLOCK_16X16; - } -} - -static void set_good_speed_feature_framesize_dependent(VP9_COMP *cpi, - SPEED_FEATURES *sf, - int speed) { - VP9_COMMON *const cm = &cpi->common; - const int min_frame_size = VPXMIN(cm->width, cm->height); - const int is_480p_or_larger = min_frame_size >= 480; - const int is_720p_or_larger = min_frame_size >= 720; - const int is_1080p_or_larger = min_frame_size >= 1080; - const int is_2160p_or_larger = min_frame_size >= 2160; - const int boosted = frame_is_boosted(cpi); - - // speed 0 features - sf->partition_search_breakout_thr.dist = (1 << 20); - sf->partition_search_breakout_thr.rate = 80; - sf->use_square_only_thresh_high = BLOCK_SIZES; - sf->use_square_only_thresh_low = BLOCK_4X4; - - if (is_480p_or_larger) { - // Currently, the machine-learning based partition search early termination - // is only used while VPXMIN(cm->width, cm->height) >= 480 and speed = 0. - sf->rd_ml_partition.search_early_termination = 1; - sf->recode_tolerance_high = 45; - } else { - sf->use_square_only_thresh_high = BLOCK_32X32; - } - if (is_720p_or_larger) { - sf->alt_ref_search_fp = 1; - } - - if (!is_1080p_or_larger) { - sf->rd_ml_partition.search_breakout = 1; - if (is_720p_or_larger) { - sf->rd_ml_partition.search_breakout_thresh[0] = 0.0f; - sf->rd_ml_partition.search_breakout_thresh[1] = 0.0f; - sf->rd_ml_partition.search_breakout_thresh[2] = 0.0f; - } else { - sf->rd_ml_partition.search_breakout_thresh[0] = 2.5f; - sf->rd_ml_partition.search_breakout_thresh[1] = 1.5f; - sf->rd_ml_partition.search_breakout_thresh[2] = 1.5f; - } - } - - if (!is_720p_or_larger) { - if (is_480p_or_larger) - sf->prune_single_mode_based_on_mv_diff_mode_rate = boosted ? 0 : 1; - else - sf->prune_single_mode_based_on_mv_diff_mode_rate = 1; - } - - if (speed >= 1) { - sf->rd_ml_partition.search_early_termination = 0; - sf->rd_ml_partition.search_breakout = 1; - if (is_480p_or_larger) - sf->use_square_only_thresh_high = BLOCK_64X64; - else - sf->use_square_only_thresh_high = BLOCK_32X32; - sf->use_square_only_thresh_low = BLOCK_16X16; - if (is_720p_or_larger) { - sf->disable_split_mask = - cm->show_frame ? DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT; - sf->partition_search_breakout_thr.dist = (1 << 22); - sf->rd_ml_partition.search_breakout_thresh[0] = -5.0f; - sf->rd_ml_partition.search_breakout_thresh[1] = -5.0f; - sf->rd_ml_partition.search_breakout_thresh[2] = -9.0f; - } else { - sf->disable_split_mask = DISABLE_COMPOUND_SPLIT; - sf->partition_search_breakout_thr.dist = (1 << 21); - sf->rd_ml_partition.search_breakout_thresh[0] = -1.0f; - sf->rd_ml_partition.search_breakout_thresh[1] = -1.0f; - sf->rd_ml_partition.search_breakout_thresh[2] = -1.0f; - } -#if CONFIG_VP9_HIGHBITDEPTH - if (cpi->Source->flags & YV12_FLAG_HIGHBITDEPTH) { - sf->rd_ml_partition.search_breakout_thresh[0] -= 1.0f; - sf->rd_ml_partition.search_breakout_thresh[1] -= 1.0f; - sf->rd_ml_partition.search_breakout_thresh[2] -= 1.0f; - } -#endif // CONFIG_VP9_HIGHBITDEPTH - } - - if (speed >= 2) { - sf->use_square_only_thresh_high = BLOCK_4X4; - sf->use_square_only_thresh_low = BLOCK_SIZES; - if (is_720p_or_larger) { - sf->disable_split_mask = - cm->show_frame ? DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT; - sf->adaptive_pred_interp_filter = 0; - sf->partition_search_breakout_thr.dist = (1 << 24); - sf->partition_search_breakout_thr.rate = 120; - sf->rd_ml_partition.search_breakout = 0; - } else { - sf->disable_split_mask = LAST_AND_INTRA_SPLIT_ONLY; - sf->partition_search_breakout_thr.dist = (1 << 22); - sf->partition_search_breakout_thr.rate = 100; - sf->rd_ml_partition.search_breakout_thresh[0] = 0.0f; - sf->rd_ml_partition.search_breakout_thresh[1] = -1.0f; - sf->rd_ml_partition.search_breakout_thresh[2] = -4.0f; - } - sf->rd_auto_partition_min_limit = set_partition_min_limit(cm); - - // Use a set of speed features for 4k videos. - if (is_2160p_or_larger) { - sf->use_square_partition_only = 1; - sf->intra_y_mode_mask[TX_32X32] = INTRA_DC; - sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC; - sf->alt_ref_search_fp = 1; - sf->cb_pred_filter_search = 2; - sf->adaptive_interp_filter_search = 1; - sf->disable_split_mask = DISABLE_ALL_SPLIT; - } - } - - if (speed >= 3) { - sf->rd_ml_partition.search_breakout = 0; - if (is_720p_or_larger) { - sf->disable_split_mask = DISABLE_ALL_SPLIT; - sf->schedule_mode_search = cm->base_qindex < 220 ? 1 : 0; - sf->partition_search_breakout_thr.dist = (1 << 25); - sf->partition_search_breakout_thr.rate = 200; - } else { - sf->max_intra_bsize = BLOCK_32X32; - sf->disable_split_mask = DISABLE_ALL_INTER_SPLIT; - sf->schedule_mode_search = cm->base_qindex < 175 ? 1 : 0; - sf->partition_search_breakout_thr.dist = (1 << 23); - sf->partition_search_breakout_thr.rate = 120; - } - } - - // If this is a two pass clip that fits the criteria for animated or - // graphics content then reset disable_split_mask for speeds 1-4. - // Also if the image edge is internal to the coded area. - if ((speed >= 1) && (cpi->oxcf.pass == 2) && - ((cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) || - (vp9_internal_image_edge(cpi)))) { - sf->disable_split_mask = DISABLE_COMPOUND_SPLIT; - } - - if (speed >= 4) { - sf->partition_search_breakout_thr.rate = 300; - if (is_720p_or_larger) { - sf->partition_search_breakout_thr.dist = (1 << 26); - } else { - sf->partition_search_breakout_thr.dist = (1 << 24); - } - sf->disable_split_mask = DISABLE_ALL_SPLIT; - } - - if (speed >= 5) { - sf->partition_search_breakout_thr.rate = 500; - } -} - -static double tx_dom_thresholds[6] = { 99.0, 14.0, 12.0, 8.0, 4.0, 0.0 }; -static double qopt_thresholds[6] = { 99.0, 12.0, 10.0, 4.0, 2.0, 0.0 }; - -static void set_good_speed_feature_framesize_independent(VP9_COMP *cpi, - VP9_COMMON *cm, - SPEED_FEATURES *sf, - int speed) { - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - const int boosted = frame_is_boosted(cpi); - int i; - - sf->adaptive_interp_filter_search = 1; - sf->adaptive_pred_interp_filter = 1; - sf->adaptive_rd_thresh = 1; - sf->adaptive_rd_thresh_row_mt = 0; - sf->allow_skip_recode = 1; - sf->less_rectangular_check = 1; - sf->mv.auto_mv_step_size = 1; - sf->mv.use_downsampled_sad = 1; - sf->prune_ref_frame_for_rect_partitions = 1; - sf->temporal_filter_search_method = NSTEP; - sf->tx_size_search_breakout = 1; - sf->use_square_partition_only = !boosted; - sf->early_term_interp_search_plane_rd = 1; - sf->cb_pred_filter_search = 1; - sf->trellis_opt_tx_rd.method = sf->optimize_coefficients - ? ENABLE_TRELLIS_OPT_TX_RD_RESIDUAL_MSE - : DISABLE_TRELLIS_OPT; - sf->trellis_opt_tx_rd.thresh = boosted ? 4.0 : 3.0; - - sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V; - sf->comp_inter_joint_search_iter_level = 1; - - // Reference masking is not supported in dynamic scaling mode. - sf->reference_masking = oxcf->resize_mode != RESIZE_DYNAMIC; - - sf->rd_ml_partition.var_pruning = 1; - sf->rd_ml_partition.prune_rect_thresh[0] = -1; - sf->rd_ml_partition.prune_rect_thresh[1] = 350; - sf->rd_ml_partition.prune_rect_thresh[2] = 325; - sf->rd_ml_partition.prune_rect_thresh[3] = 250; - - if (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) { - sf->exhaustive_searches_thresh = (1 << 22); - } else { - sf->exhaustive_searches_thresh = INT_MAX; - } - - for (i = 0; i < MAX_MESH_STEP; ++i) { - const int mesh_density_level = 0; - sf->mesh_patterns[i].range = - good_quality_mesh_patterns[mesh_density_level][i].range; - sf->mesh_patterns[i].interval = - good_quality_mesh_patterns[mesh_density_level][i].interval; - } - - if (speed >= 1) { - sf->rd_ml_partition.var_pruning = !boosted; - sf->rd_ml_partition.prune_rect_thresh[1] = 225; - sf->rd_ml_partition.prune_rect_thresh[2] = 225; - sf->rd_ml_partition.prune_rect_thresh[3] = 225; - - if (oxcf->pass == 2) { - TWO_PASS *const twopass = &cpi->twopass; - if ((twopass->fr_content_type == FC_GRAPHICS_ANIMATION) || - vp9_internal_image_edge(cpi)) { - sf->use_square_partition_only = !boosted; - } else { - sf->use_square_partition_only = !frame_is_intra_only(cm); - } - } else { - sf->use_square_partition_only = !frame_is_intra_only(cm); - } - - sf->allow_txfm_domain_distortion = 1; - sf->tx_domain_thresh = tx_dom_thresholds[(speed < 6) ? speed : 5]; - sf->trellis_opt_tx_rd.method = sf->optimize_coefficients - ? ENABLE_TRELLIS_OPT_TX_RD_SRC_VAR - : DISABLE_TRELLIS_OPT; - sf->trellis_opt_tx_rd.thresh = qopt_thresholds[(speed < 6) ? speed : 5]; - sf->less_rectangular_check = 1; - sf->use_rd_breakout = 1; - sf->adaptive_motion_search = 1; - sf->adaptive_rd_thresh = 2; - sf->mv.subpel_search_level = 1; - if (cpi->oxcf.content != VP9E_CONTENT_FILM) sf->mode_skip_start = 10; - sf->allow_acl = 0; - - sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V; - if (cpi->oxcf.content != VP9E_CONTENT_FILM) { - sf->intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V; - sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V; - } - - sf->recode_tolerance_low = 15; - sf->recode_tolerance_high = 30; - - sf->exhaustive_searches_thresh = - (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) ? (1 << 23) - : INT_MAX; - sf->use_accurate_subpel_search = USE_4_TAPS; - } - - if (speed >= 2) { - sf->rd_ml_partition.var_pruning = 0; - if (oxcf->vbr_corpus_complexity) - sf->recode_loop = ALLOW_RECODE_FIRST; - else - sf->recode_loop = ALLOW_RECODE_KFARFGF; - - sf->tx_size_search_method = - frame_is_boosted(cpi) ? USE_FULL_RD : USE_LARGESTALL; - - sf->mode_search_skip_flags = - (cm->frame_type == KEY_FRAME) - ? 0 - : FLAG_SKIP_INTRA_DIRMISMATCH | FLAG_SKIP_INTRA_BESTINTER | - FLAG_SKIP_COMP_BESTINTRA | FLAG_SKIP_INTRA_LOWVAR; - sf->disable_filter_search_var_thresh = 100; - sf->comp_inter_joint_search_iter_level = 2; - sf->auto_min_max_partition_size = RELAXED_NEIGHBORING_MIN_MAX; - sf->recode_tolerance_high = 45; - sf->enhanced_full_pixel_motion_search = 0; - sf->prune_ref_frame_for_rect_partitions = 0; - sf->rd_ml_partition.prune_rect_thresh[1] = -1; - sf->rd_ml_partition.prune_rect_thresh[2] = -1; - sf->rd_ml_partition.prune_rect_thresh[3] = -1; - sf->mv.subpel_search_level = 0; - - if (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) { - for (i = 0; i < MAX_MESH_STEP; ++i) { - int mesh_density_level = 1; - sf->mesh_patterns[i].range = - good_quality_mesh_patterns[mesh_density_level][i].range; - sf->mesh_patterns[i].interval = - good_quality_mesh_patterns[mesh_density_level][i].interval; - } - } - - sf->use_accurate_subpel_search = USE_2_TAPS; - } - - if (speed >= 3) { - sf->use_square_partition_only = !frame_is_intra_only(cm); - sf->tx_size_search_method = - frame_is_intra_only(cm) ? USE_FULL_RD : USE_LARGESTALL; - sf->mv.subpel_search_method = SUBPEL_TREE_PRUNED; - sf->adaptive_pred_interp_filter = 0; - sf->adaptive_mode_search = 1; - sf->cb_partition_search = !boosted; - sf->cb_pred_filter_search = 2; - sf->alt_ref_search_fp = 1; - sf->recode_loop = ALLOW_RECODE_KFMAXBW; - sf->adaptive_rd_thresh = 3; - sf->mode_skip_start = 6; - sf->intra_y_mode_mask[TX_32X32] = INTRA_DC; - sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC; - - if (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) { - for (i = 0; i < MAX_MESH_STEP; ++i) { - int mesh_density_level = 2; - sf->mesh_patterns[i].range = - good_quality_mesh_patterns[mesh_density_level][i].range; - sf->mesh_patterns[i].interval = - good_quality_mesh_patterns[mesh_density_level][i].interval; - } - } - } - - if (speed >= 4) { - sf->use_square_partition_only = 1; - sf->tx_size_search_method = USE_LARGESTALL; - sf->mv.search_method = BIGDIA; - sf->mv.subpel_search_method = SUBPEL_TREE_PRUNED_MORE; - sf->adaptive_rd_thresh = 4; - if (cm->frame_type != KEY_FRAME) - sf->mode_search_skip_flags |= FLAG_EARLY_TERMINATE; - sf->disable_filter_search_var_thresh = 200; - sf->use_lp32x32fdct = 1; - sf->use_fast_coef_updates = ONE_LOOP_REDUCED; - sf->use_fast_coef_costing = 1; - sf->motion_field_mode_search = !boosted; - } - - if (speed >= 5) { - sf->optimize_coefficients = 0; - sf->mv.search_method = HEX; - sf->disable_filter_search_var_thresh = 500; - for (i = 0; i < TX_SIZES; ++i) { - sf->intra_y_mode_mask[i] = INTRA_DC; - sf->intra_uv_mode_mask[i] = INTRA_DC; - } - sf->mv.reduce_first_step_size = 1; - sf->simple_model_rd_from_var = 1; - } -} -#endif // !CONFIG_REALTIME_ONLY - -static void set_rt_speed_feature_framesize_dependent(VP9_COMP *cpi, - SPEED_FEATURES *sf, - int speed) { - VP9_COMMON *const cm = &cpi->common; - - if (speed >= 1) { - if (VPXMIN(cm->width, cm->height) >= 720) { - sf->disable_split_mask = - cm->show_frame ? DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT; - } else { - sf->disable_split_mask = DISABLE_COMPOUND_SPLIT; - } - } - - if (speed >= 2) { - if (VPXMIN(cm->width, cm->height) >= 720) { - sf->disable_split_mask = - cm->show_frame ? DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT; - } else { - sf->disable_split_mask = LAST_AND_INTRA_SPLIT_ONLY; - } - } - - if (speed >= 5) { - sf->partition_search_breakout_thr.rate = 200; - if (VPXMIN(cm->width, cm->height) >= 720) { - sf->partition_search_breakout_thr.dist = (1 << 25); - } else { - sf->partition_search_breakout_thr.dist = (1 << 23); - } - } - - if (speed >= 7) { - sf->encode_breakout_thresh = - (VPXMIN(cm->width, cm->height) >= 720) ? 800 : 300; - } -} - -static void set_rt_speed_feature_framesize_independent( - VP9_COMP *cpi, SPEED_FEATURES *sf, int speed, vp9e_tune_content content) { - VP9_COMMON *const cm = &cpi->common; - SVC *const svc = &cpi->svc; - const int is_keyframe = cm->frame_type == KEY_FRAME; - const int frames_since_key = is_keyframe ? 0 : cpi->rc.frames_since_key; - sf->static_segmentation = 0; - sf->adaptive_rd_thresh = 1; - sf->adaptive_rd_thresh_row_mt = 0; - sf->use_fast_coef_costing = 1; - sf->exhaustive_searches_thresh = INT_MAX; - sf->allow_acl = 0; - sf->copy_partition_flag = 0; - sf->use_source_sad = 0; - sf->use_simple_block_yrd = 0; - sf->adapt_partition_source_sad = 0; - sf->use_altref_onepass = 0; - sf->use_compound_nonrd_pickmode = 0; - sf->nonrd_keyframe = 0; - sf->svc_use_lowres_part = 0; - sf->overshoot_detection_cbr_rt = NO_DETECTION; - sf->disable_16x16part_nonkey = 0; - sf->disable_golden_ref = 0; - sf->enable_tpl_model = 0; - sf->enhanced_full_pixel_motion_search = 0; - sf->use_accurate_subpel_search = USE_2_TAPS; - sf->nonrd_use_ml_partition = 0; - sf->variance_part_thresh_mult = 1; - sf->cb_pred_filter_search = 0; - sf->force_smooth_interpol = 0; - sf->rt_intra_dc_only_low_content = 0; - sf->mv.enable_adaptive_subpel_force_stop = 0; - - if (speed >= 1) { - sf->allow_txfm_domain_distortion = 1; - sf->tx_domain_thresh = 0.0; - sf->trellis_opt_tx_rd.method = DISABLE_TRELLIS_OPT; - sf->trellis_opt_tx_rd.thresh = 0.0; - sf->use_square_partition_only = !frame_is_intra_only(cm); - sf->less_rectangular_check = 1; - sf->tx_size_search_method = - frame_is_intra_only(cm) ? USE_FULL_RD : USE_LARGESTALL; - - sf->use_rd_breakout = 1; - - sf->adaptive_motion_search = 1; - sf->adaptive_pred_interp_filter = 1; - sf->mv.auto_mv_step_size = 1; - sf->adaptive_rd_thresh = 2; - sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V; - sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V; - sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V; - } - - if (speed >= 2) { - sf->mode_search_skip_flags = - (cm->frame_type == KEY_FRAME) - ? 0 - : FLAG_SKIP_INTRA_DIRMISMATCH | FLAG_SKIP_INTRA_BESTINTER | - FLAG_SKIP_COMP_BESTINTRA | FLAG_SKIP_INTRA_LOWVAR; - sf->adaptive_pred_interp_filter = 2; - - // Reference masking only enabled for 1 spatial layer, and if none of the - // references have been scaled. The latter condition needs to be checked - // for external or internal dynamic resize. - sf->reference_masking = (svc->number_spatial_layers == 1); - if (sf->reference_masking == 1 && - (cpi->external_resize == 1 || - cpi->oxcf.resize_mode == RESIZE_DYNAMIC)) { - MV_REFERENCE_FRAME ref_frame; - for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { - const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame); - if (yv12 != NULL && - (cpi->ref_frame_flags & ref_frame_to_flag(ref_frame))) { - const struct scale_factors *const scale_fac = - &cm->frame_refs[ref_frame - 1].sf; - if (vp9_is_scaled(scale_fac)) sf->reference_masking = 0; - } - } - } - - sf->disable_filter_search_var_thresh = 50; - sf->comp_inter_joint_search_iter_level = 2; - sf->auto_min_max_partition_size = RELAXED_NEIGHBORING_MIN_MAX; - sf->lf_motion_threshold = LOW_MOTION_THRESHOLD; - sf->adjust_partitioning_from_last_frame = 1; - sf->last_partitioning_redo_frequency = 3; - sf->use_lp32x32fdct = 1; - sf->mode_skip_start = 11; - sf->intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V; - } - - if (speed >= 3) { - sf->use_square_partition_only = 1; - sf->disable_filter_search_var_thresh = 100; - sf->use_uv_intra_rd_estimate = 1; - sf->skip_encode_sb = 1; - sf->mv.subpel_search_level = 0; - sf->adaptive_rd_thresh = 4; - sf->mode_skip_start = 6; - sf->allow_skip_recode = 0; - sf->optimize_coefficients = 0; - sf->disable_split_mask = DISABLE_ALL_SPLIT; - sf->lpf_pick = LPF_PICK_FROM_Q; - } - - if (speed >= 4) { - int i; - if (cpi->oxcf.rc_mode == VPX_VBR && cpi->oxcf.lag_in_frames > 0) - sf->use_altref_onepass = 1; - sf->mv.subpel_force_stop = QUARTER_PEL; - for (i = 0; i < TX_SIZES; i++) { - sf->intra_y_mode_mask[i] = INTRA_DC_H_V; - sf->intra_uv_mode_mask[i] = INTRA_DC; - } - sf->intra_y_mode_mask[TX_32X32] = INTRA_DC; - sf->frame_parameter_update = 0; - sf->mv.search_method = FAST_HEX; - sf->allow_skip_recode = 0; - sf->max_intra_bsize = BLOCK_32X32; - sf->use_fast_coef_costing = 0; - sf->use_quant_fp = !is_keyframe; - sf->inter_mode_mask[BLOCK_32X32] = INTER_NEAREST_NEW_ZERO; - sf->inter_mode_mask[BLOCK_32X64] = INTER_NEAREST_NEW_ZERO; - sf->inter_mode_mask[BLOCK_64X32] = INTER_NEAREST_NEW_ZERO; - sf->inter_mode_mask[BLOCK_64X64] = INTER_NEAREST_NEW_ZERO; - sf->adaptive_rd_thresh = 2; - sf->use_fast_coef_updates = is_keyframe ? TWO_LOOP : ONE_LOOP_REDUCED; - sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH; - sf->tx_size_search_method = is_keyframe ? USE_LARGESTALL : USE_TX_8X8; - sf->partition_search_type = VAR_BASED_PARTITION; - } - - if (speed >= 5) { - sf->use_altref_onepass = 0; - sf->use_quant_fp = !is_keyframe; - sf->auto_min_max_partition_size = - is_keyframe ? RELAXED_NEIGHBORING_MIN_MAX : STRICT_NEIGHBORING_MIN_MAX; - sf->default_max_partition_size = BLOCK_32X32; - sf->default_min_partition_size = BLOCK_8X8; - sf->force_frame_boost = - is_keyframe || - (frames_since_key % (sf->last_partitioning_redo_frequency << 1) == 1); - sf->max_delta_qindex = is_keyframe ? 20 : 15; - sf->partition_search_type = REFERENCE_PARTITION; - if (cpi->oxcf.rc_mode == VPX_VBR && cpi->oxcf.lag_in_frames > 0 && - cpi->rc.is_src_frame_alt_ref) { - sf->partition_search_type = VAR_BASED_PARTITION; - } - sf->use_nonrd_pick_mode = 1; - sf->allow_skip_recode = 0; - sf->inter_mode_mask[BLOCK_32X32] = INTER_NEAREST_NEW_ZERO; - sf->inter_mode_mask[BLOCK_32X64] = INTER_NEAREST_NEW_ZERO; - sf->inter_mode_mask[BLOCK_64X32] = INTER_NEAREST_NEW_ZERO; - sf->inter_mode_mask[BLOCK_64X64] = INTER_NEAREST_NEW_ZERO; - sf->adaptive_rd_thresh = 2; - // This feature is only enabled when partition search is disabled. - sf->reuse_inter_pred_sby = 1; - sf->coeff_prob_appx_step = 4; - sf->use_fast_coef_updates = is_keyframe ? TWO_LOOP : ONE_LOOP_REDUCED; - sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH; - sf->tx_size_search_method = is_keyframe ? USE_LARGESTALL : USE_TX_8X8; - sf->simple_model_rd_from_var = 1; - if (cpi->oxcf.rc_mode == VPX_VBR) sf->mv.search_method = NSTEP; - - if (!is_keyframe) { - int i; - if (content == VP9E_CONTENT_SCREEN) { - for (i = 0; i < BLOCK_SIZES; ++i) - if (i >= BLOCK_32X32) - sf->intra_y_mode_bsize_mask[i] = INTRA_DC_H_V; - else - sf->intra_y_mode_bsize_mask[i] = INTRA_DC_TM_H_V; - } else { - for (i = 0; i < BLOCK_SIZES; ++i) - if (i > BLOCK_16X16) - sf->intra_y_mode_bsize_mask[i] = INTRA_DC; - else - // Use H and V intra mode for block sizes <= 16X16. - sf->intra_y_mode_bsize_mask[i] = INTRA_DC_H_V; - } - } - if (content == VP9E_CONTENT_SCREEN) { - sf->short_circuit_flat_blocks = 1; - } - if (cpi->oxcf.rc_mode == VPX_CBR && - cpi->oxcf.content != VP9E_CONTENT_SCREEN) { - sf->limit_newmv_early_exit = 1; - if (!cpi->use_svc) sf->bias_golden = 1; - } - // Keep nonrd_keyframe = 1 for non-base spatial layers to prevent - // increase in encoding time. - if (cpi->use_svc && svc->spatial_layer_id > 0) sf->nonrd_keyframe = 1; - if (cm->frame_type != KEY_FRAME && cpi->resize_state == ORIG && - cpi->oxcf.rc_mode == VPX_CBR && !cpi->rc.disable_overshoot_maxq_cbr) { - if (cm->width * cm->height <= 352 * 288 && !cpi->use_svc && - cpi->oxcf.content != VP9E_CONTENT_SCREEN) - sf->overshoot_detection_cbr_rt = RE_ENCODE_MAXQ; - else - sf->overshoot_detection_cbr_rt = FAST_DETECTION_MAXQ; - } - if (cpi->oxcf.rc_mode == VPX_VBR && cpi->oxcf.lag_in_frames > 0 && - cm->width <= 1280 && cm->height <= 720) { - sf->use_altref_onepass = 1; - sf->use_compound_nonrd_pickmode = 1; - } - if (cm->width * cm->height > 1280 * 720) sf->cb_pred_filter_search = 2; - if (!cpi->external_resize) sf->use_source_sad = 1; - } - - if (speed >= 6) { - if (cpi->oxcf.rc_mode == VPX_VBR && cpi->oxcf.lag_in_frames > 0) { - sf->use_altref_onepass = 1; - sf->use_compound_nonrd_pickmode = 1; - } - sf->partition_search_type = VAR_BASED_PARTITION; - sf->mv.search_method = NSTEP; - sf->mv.reduce_first_step_size = 1; - sf->skip_encode_sb = 0; - - if (sf->use_source_sad) { - sf->adapt_partition_source_sad = 1; - sf->adapt_partition_thresh = - (cm->width * cm->height <= 640 * 360) ? 40000 : 60000; - if (cpi->content_state_sb_fd == NULL && - (!cpi->use_svc || - svc->spatial_layer_id == svc->number_spatial_layers - 1)) { - CHECK_MEM_ERROR(&cm->error, cpi->content_state_sb_fd, - (uint8_t *)vpx_calloc( - (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1), - sizeof(uint8_t))); - } - } - if (cpi->oxcf.rc_mode == VPX_CBR && content != VP9E_CONTENT_SCREEN) { - // Enable short circuit for low temporal variance. - sf->short_circuit_low_temp_var = 1; - } - if (svc->temporal_layer_id > 0) { - sf->adaptive_rd_thresh = 4; - sf->limit_newmv_early_exit = 0; - sf->base_mv_aggressive = 1; - } - if (cm->frame_type != KEY_FRAME && cpi->resize_state == ORIG && - cpi->oxcf.rc_mode == VPX_CBR && !cpi->rc.disable_overshoot_maxq_cbr) - sf->overshoot_detection_cbr_rt = FAST_DETECTION_MAXQ; - } - - if (speed >= 7) { - sf->adapt_partition_source_sad = 0; - sf->adaptive_rd_thresh = 3; - sf->mv.search_method = FAST_DIAMOND; - sf->mv.fullpel_search_step_param = 10; - // For SVC: use better mv search on base temporal layer, and only - // on base spatial layer if highest resolution is above 640x360. - if (svc->number_temporal_layers > 2 && svc->temporal_layer_id == 0 && - (svc->spatial_layer_id == 0 || - cpi->oxcf.width * cpi->oxcf.height <= 640 * 360)) { - sf->mv.search_method = NSTEP; - sf->mv.fullpel_search_step_param = 6; - } - if (svc->temporal_layer_id > 0 || svc->spatial_layer_id > 1) { - sf->use_simple_block_yrd = 1; - if (svc->non_reference_frame) - sf->mv.subpel_search_method = SUBPEL_TREE_PRUNED_EVENMORE; - } - if (cpi->use_svc && cpi->row_mt && cpi->oxcf.max_threads > 1) - sf->adaptive_rd_thresh_row_mt = 1; - // Enable partition copy. For SVC only enabled for top spatial resolution - // layer. - cpi->max_copied_frame = 0; - if (!cpi->last_frame_dropped && cpi->resize_state == ORIG && - !cpi->external_resize && - (!cpi->use_svc || - (svc->spatial_layer_id == svc->number_spatial_layers - 1 && - !svc->last_layer_dropped[svc->number_spatial_layers - 1]))) { - sf->copy_partition_flag = 1; - cpi->max_copied_frame = 2; - // The top temporal enhancement layer (for number of temporal layers > 1) - // are non-reference frames, so use large/max value for max_copied_frame. - if (svc->number_temporal_layers > 1 && - svc->temporal_layer_id == svc->number_temporal_layers - 1) - cpi->max_copied_frame = 255; - } - // For SVC: enable use of lower resolution partition for higher resolution, - // only for 3 spatial layers and when config/top resolution is above VGA. - // Enable only for non-base temporal layer frames. - if (cpi->use_svc && svc->use_partition_reuse && - svc->number_spatial_layers == 3 && svc->temporal_layer_id > 0 && - cpi->oxcf.width * cpi->oxcf.height > 640 * 480) - sf->svc_use_lowres_part = 1; - // For SVC when golden is used as second temporal reference: to avoid - // encode time increase only use this feature on base temporal layer. - // (i.e remove golden flag from frame_flags for temporal_layer_id > 0). - if (cpi->use_svc && svc->use_gf_temporal_ref_current_layer && - svc->temporal_layer_id > 0) - cpi->ref_frame_flags &= (~VP9_GOLD_FLAG); - if (cm->width * cm->height > 640 * 480) sf->cb_pred_filter_search = 2; - } - - if (speed >= 8) { - sf->adaptive_rd_thresh = 4; - sf->skip_encode_sb = 1; - if (cpi->svc.number_spatial_layers > 1 && !cpi->svc.simulcast_mode) - sf->nonrd_keyframe = 0; - else - sf->nonrd_keyframe = 1; - if (!cpi->use_svc) cpi->max_copied_frame = 4; - if (cpi->row_mt && cpi->oxcf.max_threads > 1) - sf->adaptive_rd_thresh_row_mt = 1; - // Enable ML based partition for low res. - if (!frame_is_intra_only(cm) && cm->width * cm->height <= 352 * 288) { - sf->nonrd_use_ml_partition = 1; - } -#if CONFIG_VP9_HIGHBITDEPTH - if (cpi->Source->flags & YV12_FLAG_HIGHBITDEPTH) - sf->nonrd_use_ml_partition = 0; -#endif - if (content == VP9E_CONTENT_SCREEN) sf->mv.subpel_force_stop = HALF_PEL; - sf->rt_intra_dc_only_low_content = 1; - if (!cpi->use_svc && cpi->oxcf.rc_mode == VPX_CBR && - content != VP9E_CONTENT_SCREEN) { - // More aggressive short circuit for speed 8. - sf->short_circuit_low_temp_var = 3; - // Use level 2 for noisey cases as there is a regression in some - // noisy clips with level 3. - if (cpi->noise_estimate.enabled && cm->width >= 1280 && - cm->height >= 720) { - NOISE_LEVEL noise_level = - vp9_noise_estimate_extract_level(&cpi->noise_estimate); - if (noise_level >= kMedium) sf->short_circuit_low_temp_var = 2; - } - // Since the short_circuit_low_temp_var is used, reduce the - // adaptive_rd_thresh level. - if (cm->width * cm->height > 352 * 288) - sf->adaptive_rd_thresh = 1; - else - sf->adaptive_rd_thresh = 2; - } - sf->limit_newmv_early_exit = 0; - sf->use_simple_block_yrd = 1; - if (cm->width * cm->height > 352 * 288) sf->cb_pred_filter_search = 2; - } - - if (speed >= 9) { - // Only keep INTRA_DC mode for speed 9. - if (!is_keyframe) { - int i = 0; - for (i = 0; i < BLOCK_SIZES; ++i) - sf->intra_y_mode_bsize_mask[i] = INTRA_DC; - } - sf->cb_pred_filter_search = 2; - sf->mv.enable_adaptive_subpel_force_stop = 1; - sf->mv.adapt_subpel_force_stop.mv_thresh = 1; - sf->mv.adapt_subpel_force_stop.force_stop_below = QUARTER_PEL; - sf->mv.adapt_subpel_force_stop.force_stop_above = HALF_PEL; - // Disable partition blocks below 16x16, except for low-resolutions. - if (cm->frame_type != KEY_FRAME && cm->width >= 320 && cm->height >= 240) - sf->disable_16x16part_nonkey = 1; - // Allow for disabling GOLDEN reference, for CBR mode. - if (cpi->oxcf.rc_mode == VPX_CBR) sf->disable_golden_ref = 1; - if (cpi->rc.avg_frame_low_motion < 70) sf->default_interp_filter = BILINEAR; - if (cm->width * cm->height >= 640 * 360) sf->variance_part_thresh_mult = 2; - } - - // Disable split to 8x8 for low-resolution at very high Q. - // For variance partition (speed >= 6). Ignore the first few frames - // as avg_frame_qindex starts at max_q (worst_quality). - if (cm->frame_type != KEY_FRAME && cm->width * cm->height <= 320 * 240 && - sf->partition_search_type == VAR_BASED_PARTITION && - cpi->rc.avg_frame_qindex[INTER_FRAME] > 208 && - cpi->common.current_video_frame > 8) - sf->disable_16x16part_nonkey = 1; - - if (sf->nonrd_use_ml_partition) - sf->partition_search_type = ML_BASED_PARTITION; - - if (sf->use_altref_onepass) { - if (cpi->rc.is_src_frame_alt_ref && cm->frame_type != KEY_FRAME) { - sf->partition_search_type = FIXED_PARTITION; - sf->always_this_block_size = BLOCK_64X64; - } - if (cpi->count_arf_frame_usage == NULL) { - CHECK_MEM_ERROR( - &cm->error, cpi->count_arf_frame_usage, - (uint8_t *)vpx_calloc((cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1), - sizeof(*cpi->count_arf_frame_usage))); - } - if (cpi->count_lastgolden_frame_usage == NULL) - CHECK_MEM_ERROR( - &cm->error, cpi->count_lastgolden_frame_usage, - (uint8_t *)vpx_calloc((cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1), - sizeof(*cpi->count_lastgolden_frame_usage))); - } - if (svc->previous_frame_is_intra_only) { - sf->partition_search_type = FIXED_PARTITION; - sf->always_this_block_size = BLOCK_64X64; - } - // Special case for screen content: increase motion search on base spatial - // layer when high motion is detected or previous SL0 frame was dropped. - if (cpi->oxcf.content == VP9E_CONTENT_SCREEN && cpi->oxcf.speed >= 5 && - (svc->high_num_blocks_with_motion || svc->last_layer_dropped[0])) { - sf->mv.search_method = NSTEP; - // TODO(marpan/jianj): Tune this setting for screensharing. For now use - // small step_param for all spatial layers. - sf->mv.fullpel_search_step_param = 2; - } - // TODO(marpan): There is regression for aq-mode=3 speed <= 4, force it - // off for now. - if (speed <= 3 && cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) - cpi->oxcf.aq_mode = 0; - // For all speeds for rt mode: if the deadline mode changed (was good/best - // quality on previous frame and now is realtime) set nonrd_keyframe to 1 to - // avoid entering rd pickmode. This causes issues, such as: b/310663186. - if (cpi->oxcf.mode != cpi->deadline_mode_previous_frame) - sf->nonrd_keyframe = 1; - - // TODO(marpan): Force this feature off always, for the issue: 366146260 - // Remove this disabling when underlying issue is resolved. - sf->svc_use_lowres_part = 0; -} - -void vp9_set_speed_features_framesize_dependent(VP9_COMP *cpi, int speed) { - SPEED_FEATURES *const sf = &cpi->sf; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - RD_OPT *const rd = &cpi->rd; - int i; - - // best quality defaults - // Some speed-up features even for best quality as minimal impact on quality. - sf->partition_search_breakout_thr.dist = (1 << 19); - sf->partition_search_breakout_thr.rate = 80; - sf->rd_ml_partition.search_early_termination = 0; - sf->rd_ml_partition.search_breakout = 0; - - if (oxcf->mode == REALTIME) - set_rt_speed_feature_framesize_dependent(cpi, sf, speed); -#if !CONFIG_REALTIME_ONLY - else if (oxcf->mode == GOOD) - set_good_speed_feature_framesize_dependent(cpi, sf, speed); -#endif - - if (sf->disable_split_mask == DISABLE_ALL_SPLIT) { - sf->adaptive_pred_interp_filter = 0; - } - - if (cpi->encode_breakout && oxcf->mode == REALTIME && - sf->encode_breakout_thresh > cpi->encode_breakout) { - cpi->encode_breakout = sf->encode_breakout_thresh; - } - - // Check for masked out split cases. - for (i = 0; i < MAX_REFS; ++i) { - if (sf->disable_split_mask & (1 << i)) { - rd->thresh_mult_sub8x8[i] = INT_MAX; - } - } - - // With row based multi-threading, the following speed features - // have to be disabled to guarantee that bitstreams encoded with single thread - // and multiple threads match. - // It can be used in realtime when adaptive_rd_thresh_row_mt is enabled since - // adaptive_rd_thresh is defined per-row for non-rd pickmode. - if (!sf->adaptive_rd_thresh_row_mt && cpi->row_mt_bit_exact && - oxcf->max_threads > 1) - sf->adaptive_rd_thresh = 0; -} - -void vp9_set_speed_features_framesize_independent(VP9_COMP *cpi, int speed) { - SPEED_FEATURES *const sf = &cpi->sf; -#if !CONFIG_REALTIME_ONLY - VP9_COMMON *const cm = &cpi->common; -#endif - MACROBLOCK *const x = &cpi->td.mb; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - int i; - - // best quality defaults - sf->frame_parameter_update = 1; - sf->mv.search_method = NSTEP; - sf->recode_loop = ALLOW_RECODE_FIRST; - sf->mv.subpel_search_method = SUBPEL_TREE; - sf->mv.subpel_search_level = 2; - sf->mv.subpel_force_stop = EIGHTH_PEL; - sf->optimize_coefficients = !is_lossless_requested(&cpi->oxcf); - sf->mv.reduce_first_step_size = 0; - sf->coeff_prob_appx_step = 1; - sf->mv.auto_mv_step_size = 0; - sf->mv.fullpel_search_step_param = 6; - sf->mv.use_downsampled_sad = 0; - sf->comp_inter_joint_search_iter_level = 0; - sf->tx_size_search_method = USE_FULL_RD; - sf->use_lp32x32fdct = 0; - sf->adaptive_motion_search = 0; - sf->enhanced_full_pixel_motion_search = 1; - sf->adaptive_pred_interp_filter = 0; - sf->adaptive_mode_search = 0; - sf->prune_single_mode_based_on_mv_diff_mode_rate = 0; - sf->cb_pred_filter_search = 0; - sf->early_term_interp_search_plane_rd = 0; - sf->cb_partition_search = 0; - sf->motion_field_mode_search = 0; - sf->alt_ref_search_fp = 0; - sf->use_quant_fp = 0; - sf->reference_masking = 0; - sf->partition_search_type = SEARCH_PARTITION; - sf->less_rectangular_check = 0; - sf->use_square_partition_only = 0; - sf->use_square_only_thresh_high = BLOCK_SIZES; - sf->use_square_only_thresh_low = BLOCK_4X4; - sf->auto_min_max_partition_size = NOT_IN_USE; - sf->rd_auto_partition_min_limit = BLOCK_4X4; - sf->default_max_partition_size = BLOCK_64X64; - sf->default_min_partition_size = BLOCK_4X4; - sf->adjust_partitioning_from_last_frame = 0; - sf->last_partitioning_redo_frequency = 4; - sf->disable_split_mask = 0; - sf->mode_search_skip_flags = 0; - sf->force_frame_boost = 0; - sf->max_delta_qindex = 0; - sf->disable_filter_search_var_thresh = 0; - sf->adaptive_interp_filter_search = 0; - sf->allow_txfm_domain_distortion = 0; - sf->tx_domain_thresh = 99.0; - sf->trellis_opt_tx_rd.method = - sf->optimize_coefficients ? ENABLE_TRELLIS_OPT : DISABLE_TRELLIS_OPT; - sf->trellis_opt_tx_rd.thresh = 99.0; - sf->allow_acl = 1; - sf->enable_tpl_model = oxcf->enable_tpl_model; - sf->prune_ref_frame_for_rect_partitions = 0; - sf->temporal_filter_search_method = MESH; - sf->allow_skip_txfm_ac_dc = 0; - - for (i = 0; i < TX_SIZES; i++) { - sf->intra_y_mode_mask[i] = INTRA_ALL; - sf->intra_uv_mode_mask[i] = INTRA_ALL; - } - sf->use_rd_breakout = 0; - sf->skip_encode_sb = 0; - sf->use_uv_intra_rd_estimate = 0; - sf->allow_skip_recode = 0; - sf->lpf_pick = LPF_PICK_FROM_FULL_IMAGE; - sf->use_fast_coef_updates = TWO_LOOP; - sf->use_fast_coef_costing = 0; - sf->mode_skip_start = MAX_MODES; // Mode index at which mode skip mask set - sf->schedule_mode_search = 0; - sf->use_nonrd_pick_mode = 0; - for (i = 0; i < BLOCK_SIZES; ++i) sf->inter_mode_mask[i] = INTER_ALL; - sf->max_intra_bsize = BLOCK_64X64; - sf->reuse_inter_pred_sby = 0; - // This setting only takes effect when partition_search_type is set - // to FIXED_PARTITION. - sf->always_this_block_size = BLOCK_16X16; - sf->search_type_check_frequency = 50; - sf->encode_breakout_thresh = 0; - // Recode loop tolerance %. - sf->recode_tolerance_low = 12; - sf->recode_tolerance_high = 25; - sf->default_interp_filter = SWITCHABLE; - sf->simple_model_rd_from_var = 0; - sf->short_circuit_flat_blocks = 0; - sf->short_circuit_low_temp_var = 0; - sf->limit_newmv_early_exit = 0; - sf->bias_golden = 0; - sf->base_mv_aggressive = 0; - sf->rd_ml_partition.prune_rect_thresh[0] = -1; - sf->rd_ml_partition.prune_rect_thresh[1] = -1; - sf->rd_ml_partition.prune_rect_thresh[2] = -1; - sf->rd_ml_partition.prune_rect_thresh[3] = -1; - sf->rd_ml_partition.var_pruning = 0; - sf->use_accurate_subpel_search = USE_8_TAPS; - - // Some speed-up features even for best quality as minimal impact on quality. - sf->adaptive_rd_thresh = 1; - sf->tx_size_search_breakout = 1; - sf->tx_size_search_depth = 2; - - sf->exhaustive_searches_thresh = - (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) ? (1 << 20) - : INT_MAX; - { - const int mesh_density_level = - (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) ? 0 : 1; - for (i = 0; i < MAX_MESH_STEP; ++i) { - sf->mesh_patterns[i].range = - best_quality_mesh_pattern[mesh_density_level][i].range; - sf->mesh_patterns[i].interval = - best_quality_mesh_pattern[mesh_density_level][i].interval; - } - } - - if (oxcf->mode == REALTIME) - set_rt_speed_feature_framesize_independent(cpi, sf, speed, oxcf->content); -#if !CONFIG_REALTIME_ONLY - else if (oxcf->mode == GOOD) - set_good_speed_feature_framesize_independent(cpi, cm, sf, speed); -#endif - - cpi->diamond_search_sad = vp9_diamond_search_sad; - - // Slow quant, dct and trellis not worthwhile for first pass - // so make sure they are always turned off. - if (oxcf->pass == 1) sf->optimize_coefficients = 0; - - // No recode for 1 pass. - if (oxcf->pass == 0) { - sf->recode_loop = DISALLOW_RECODE; - sf->optimize_coefficients = 0; - } - - if (sf->mv.subpel_force_stop == FULL_PEL) { - // Whole pel only - cpi->find_fractional_mv_step = vp9_skip_sub_pixel_tree; - } else if (sf->mv.subpel_search_method == SUBPEL_TREE) { - cpi->find_fractional_mv_step = vp9_find_best_sub_pixel_tree; - } else if (sf->mv.subpel_search_method == SUBPEL_TREE_PRUNED) { - cpi->find_fractional_mv_step = vp9_find_best_sub_pixel_tree_pruned; - } else if (sf->mv.subpel_search_method == SUBPEL_TREE_PRUNED_MORE) { - cpi->find_fractional_mv_step = vp9_find_best_sub_pixel_tree_pruned_more; - } else if (sf->mv.subpel_search_method == SUBPEL_TREE_PRUNED_EVENMORE) { - cpi->find_fractional_mv_step = vp9_find_best_sub_pixel_tree_pruned_evenmore; - } - - // This is only used in motion vector unit test. - if (cpi->oxcf.motion_vector_unit_test == 1) - cpi->find_fractional_mv_step = vp9_return_max_sub_pixel_mv; - else if (cpi->oxcf.motion_vector_unit_test == 2) - cpi->find_fractional_mv_step = vp9_return_min_sub_pixel_mv; - - x->optimize = sf->optimize_coefficients == 1 && oxcf->pass != 1; - - x->min_partition_size = sf->default_min_partition_size; - x->max_partition_size = sf->default_max_partition_size; - - if (!cpi->oxcf.frame_periodic_boost) { - sf->max_delta_qindex = 0; - } - - // With row based multi-threading, the following speed features - // have to be disabled to guarantee that bitstreams encoded with single thread - // and multiple threads match. - // It can be used in realtime when adaptive_rd_thresh_row_mt is enabled since - // adaptive_rd_thresh is defined per-row for non-rd pickmode. - if (!sf->adaptive_rd_thresh_row_mt && cpi->row_mt_bit_exact && - oxcf->max_threads > 1) - sf->adaptive_rd_thresh = 0; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_speed_features.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_speed_features.h deleted file mode 100644 index d61ba979..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_speed_features.h +++ /dev/null @@ -1,674 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_SPEED_FEATURES_H_ -#define VPX_VP9_ENCODER_VP9_SPEED_FEATURES_H_ - -#include "vp9/common/vp9_enums.h" - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - INTRA_ALL = (1 << DC_PRED) | (1 << V_PRED) | (1 << H_PRED) | (1 << D45_PRED) | - (1 << D135_PRED) | (1 << D117_PRED) | (1 << D153_PRED) | - (1 << D207_PRED) | (1 << D63_PRED) | (1 << TM_PRED), - INTRA_DC = (1 << DC_PRED), - INTRA_DC_TM = (1 << DC_PRED) | (1 << TM_PRED), - INTRA_DC_H_V = (1 << DC_PRED) | (1 << V_PRED) | (1 << H_PRED), - INTRA_DC_TM_H_V = - (1 << DC_PRED) | (1 << TM_PRED) | (1 << V_PRED) | (1 << H_PRED) -}; - -enum { - INTER_ALL = (1 << NEARESTMV) | (1 << NEARMV) | (1 << ZEROMV) | (1 << NEWMV), - INTER_NEAREST = (1 << NEARESTMV), - INTER_NEAREST_NEW = (1 << NEARESTMV) | (1 << NEWMV), - INTER_NEAREST_ZERO = (1 << NEARESTMV) | (1 << ZEROMV), - INTER_NEAREST_NEW_ZERO = (1 << NEARESTMV) | (1 << ZEROMV) | (1 << NEWMV), - INTER_NEAREST_NEAR_NEW = (1 << NEARESTMV) | (1 << NEARMV) | (1 << NEWMV), - INTER_NEAREST_NEAR_ZERO = (1 << NEARESTMV) | (1 << NEARMV) | (1 << ZEROMV), -}; - -enum { - DISABLE_ALL_INTER_SPLIT = (1 << THR_COMP_GA) | (1 << THR_COMP_LA) | - (1 << THR_ALTR) | (1 << THR_GOLD) | (1 << THR_LAST), - - DISABLE_ALL_SPLIT = (1 << THR_INTRA) | DISABLE_ALL_INTER_SPLIT, - - DISABLE_COMPOUND_SPLIT = (1 << THR_COMP_GA) | (1 << THR_COMP_LA), - - LAST_AND_INTRA_SPLIT_ONLY = (1 << THR_COMP_GA) | (1 << THR_COMP_LA) | - (1 << THR_ALTR) | (1 << THR_GOLD) -}; - -typedef enum { - DIAMOND = 0, - NSTEP = 1, - HEX = 2, - BIGDIA = 3, - SQUARE = 4, - FAST_HEX = 5, - FAST_DIAMOND = 6, - MESH = 7 -} SEARCH_METHODS; - -typedef enum { - // No recode. - DISALLOW_RECODE = 0, - // Allow recode for KF and exceeding maximum frame bandwidth. - ALLOW_RECODE_KFMAXBW = 1, - // Allow recode only for KF/ARF/GF frames. - ALLOW_RECODE_KFARFGF = 2, - // Allow recode for ARF/GF/KF and first normal frame in each group. - ALLOW_RECODE_FIRST = 3, - // Allow recode for all frames based on bitrate constraints. - ALLOW_RECODE = 4, -} RECODE_LOOP_TYPE; - -typedef enum { - SUBPEL_TREE = 0, - SUBPEL_TREE_PRUNED = 1, // Prunes 1/2-pel searches - SUBPEL_TREE_PRUNED_MORE = 2, // Prunes 1/2-pel searches more aggressively - SUBPEL_TREE_PRUNED_EVENMORE = 3, // Prunes 1/2- and 1/4-pel searches - // Other methods to come -} SUBPEL_SEARCH_METHODS; - -typedef enum { - NO_MOTION_THRESHOLD = 0, - LOW_MOTION_THRESHOLD = 7 -} MOTION_THRESHOLD; - -typedef enum { - USE_FULL_RD = 0, - USE_LARGESTALL, - USE_TX_8X8 -} TX_SIZE_SEARCH_METHOD; - -typedef enum { - NOT_IN_USE = 0, - RELAXED_NEIGHBORING_MIN_MAX = 1, - STRICT_NEIGHBORING_MIN_MAX = 2 -} AUTO_MIN_MAX_MODE; - -typedef enum { - // Try the full image with different values. - LPF_PICK_FROM_FULL_IMAGE, - // Try a small portion of the image with different values. - LPF_PICK_FROM_SUBIMAGE, - // Estimate the level based on quantizer and frame type - LPF_PICK_FROM_Q, - // Pick 0 to disable LPF if LPF was enabled last frame - LPF_PICK_MINIMAL_LPF -} LPF_PICK_METHOD; - -typedef enum { - // Terminate search early based on distortion so far compared to - // qp step, distortion in the neighborhood of the frame, etc. - FLAG_EARLY_TERMINATE = 1 << 0, - - // Skips comp inter modes if the best so far is an intra mode. - FLAG_SKIP_COMP_BESTINTRA = 1 << 1, - - // Skips oblique intra modes if the best so far is an inter mode. - FLAG_SKIP_INTRA_BESTINTER = 1 << 3, - - // Skips oblique intra modes at angles 27, 63, 117, 153 if the best - // intra so far is not one of the neighboring directions. - FLAG_SKIP_INTRA_DIRMISMATCH = 1 << 4, - - // Skips intra modes other than DC_PRED if the source variance is small - FLAG_SKIP_INTRA_LOWVAR = 1 << 5, -} MODE_SEARCH_SKIP_LOGIC; - -typedef enum { - FLAG_SKIP_EIGHTTAP = 1 << EIGHTTAP, - FLAG_SKIP_EIGHTTAP_SMOOTH = 1 << EIGHTTAP_SMOOTH, - FLAG_SKIP_EIGHTTAP_SHARP = 1 << EIGHTTAP_SHARP, -} INTERP_FILTER_MASK; - -typedef enum { - // Search partitions using RD/NONRD criterion. - SEARCH_PARTITION, - - // Always use a fixed size partition. - FIXED_PARTITION, - - REFERENCE_PARTITION, - - // Use an arbitrary partitioning scheme based on source variance within - // a 64X64 SB. - VAR_BASED_PARTITION, - - // Use non-fixed partitions based on source variance. - SOURCE_VAR_BASED_PARTITION, - - // Make partition decisions with machine learning models. - ML_BASED_PARTITION -} PARTITION_SEARCH_TYPE; - -typedef enum { - // Does a dry run to see if any of the contexts need to be updated or not, - // before the final run. - TWO_LOOP = 0, - - // No dry run, also only half the coef contexts and bands are updated. - // The rest are not updated at all. - ONE_LOOP_REDUCED = 1 -} FAST_COEFF_UPDATE; - -typedef enum { EIGHTH_PEL, QUARTER_PEL, HALF_PEL, FULL_PEL } SUBPEL_FORCE_STOP; - -typedef struct ADAPT_SUBPEL_FORCE_STOP { - // Threshold for full pixel motion vector; - int mv_thresh; - - // subpel_force_stop if full pixel MV is below the threshold. - SUBPEL_FORCE_STOP force_stop_below; - - // subpel_force_stop if full pixel MV is equal to or above the threshold. - SUBPEL_FORCE_STOP force_stop_above; -} ADAPT_SUBPEL_FORCE_STOP; - -typedef struct MV_SPEED_FEATURES { - // Motion search method (Diamond, NSTEP, Hex, Big Diamond, Square, etc). - SEARCH_METHODS search_method; - - // This parameter controls which step in the n-step process we start at. - // It's changed adaptively based on circumstances. - int reduce_first_step_size; - - // If this is set to 1, we limit the motion search range to 2 times the - // largest motion vector found in the last frame. - int auto_mv_step_size; - - // Subpel_search_method can only be subpel_tree which does a subpixel - // logarithmic search that keeps stepping at 1/2 pixel units until - // you stop getting a gain, and then goes on to 1/4 and repeats - // the same process. Along the way it skips many diagonals. - SUBPEL_SEARCH_METHODS subpel_search_method; - - // Subpel MV search level. Can take values 0 - 2. Higher values mean more - // extensive subpel search. - int subpel_search_level; - - // When to stop subpel motion search. - SUBPEL_FORCE_STOP subpel_force_stop; - - // If it's enabled, different subpel_force_stop will be used for different MV. - int enable_adaptive_subpel_force_stop; - - ADAPT_SUBPEL_FORCE_STOP adapt_subpel_force_stop; - - // This variable sets the step_param used in full pel motion search. - int fullpel_search_step_param; - - // Whether to downsample the rows in sad calculation during motion search. - // This is only active when there are at least 8 rows. - int use_downsampled_sad; -} MV_SPEED_FEATURES; - -typedef struct PARTITION_SEARCH_BREAKOUT_THR { - int64_t dist; - int rate; -} PARTITION_SEARCH_BREAKOUT_THR; - -#define MAX_MESH_STEP 4 - -typedef struct MESH_PATTERN { - int range; - int interval; -} MESH_PATTERN; - -typedef enum { - // No reaction to rate control on a detected slide/scene change. - NO_DETECTION = 0, - - // Set to larger Q (max_q set by user) based only on the - // detected slide/scene change and current/past Q. - FAST_DETECTION_MAXQ = 1, - - // Based on (first pass) encoded frame, if large frame size is detected - // then set to higher Q for the second re-encode. This involves 2 pass - // encoding on slide change, so slower than 1, but more accurate for - // detecting overshoot. - RE_ENCODE_MAXQ = 2 -} OVERSHOOT_DETECTION_CBR_RT; - -typedef enum { - USE_2_TAPS = 0, - USE_4_TAPS, - USE_8_TAPS, - USE_8_TAPS_SHARP, -} SUBPEL_SEARCH_TYPE; - -typedef enum { - // Disable trellis coefficient optimization - DISABLE_TRELLIS_OPT, - // Enable trellis coefficient optimization - ENABLE_TRELLIS_OPT, - // Enable trellis coefficient optimization based on source variance of the - // prediction block during transform RD - ENABLE_TRELLIS_OPT_TX_RD_SRC_VAR, - // Enable trellis coefficient optimization based on residual mse of the - // transform block during transform RD - ENABLE_TRELLIS_OPT_TX_RD_RESIDUAL_MSE, -} ENABLE_TRELLIS_OPT_METHOD; - -typedef struct TRELLIS_OPT_CONTROL { - ENABLE_TRELLIS_OPT_METHOD method; - double thresh; -} TRELLIS_OPT_CONTROL; - -typedef struct SPEED_FEATURES { - MV_SPEED_FEATURES mv; - - // Frame level coding parameter update - int frame_parameter_update; - - RECODE_LOOP_TYPE recode_loop; - - // Trellis (dynamic programming) optimization of quantized values (+1, 0). - int optimize_coefficients; - - // Always set to 0. If on it enables 0 cost background transmission - // (except for the initial transmission of the segmentation). The feature is - // disabled because the addition of very large block sizes make the - // backgrounds very to cheap to encode, and the segmentation we have - // adds overhead. - int static_segmentation; - - // The best compound predictor is found using an iterative log search process - // that searches for best ref0 mv using error of combined predictor and then - // searches for best ref1 mv. This sf determines the number of iterations of - // this process based on block size. The sf becomes more aggressive from level - // 0 to 2. The following table indicates the number of iterations w.r.t bsize: - // ----------------------------------------------- - // |sf (level)|bsize < 8X8| [8X8, 16X16] | > 16X16 | - // | 0 | 4 | 4 | 4 | - // | 1 | 0 | 2 | 4 | - // | 2 | 0 | 0 | 0 | - // ----------------------------------------------- - // Here, 0 iterations indicate using the best single motion vector selected - // for each ref frame without any iterative refinement. - int comp_inter_joint_search_iter_level; - - // This variable is used to cap the maximum number of times we skip testing a - // mode to be evaluated. A high value means we will be faster. - // Turned off when (row_mt_bit_exact == 1 && adaptive_rd_thresh_row_mt == 0). - int adaptive_rd_thresh; - - // Flag to use adaptive_rd_thresh when row-mt is enabled, only for non-rd - // pickmode. - int adaptive_rd_thresh_row_mt; - - // Enables skipping the reconstruction step (idct, recon) in the - // intermediate steps assuming the last frame didn't have too many intra - // blocks and the q is less than a threshold. - int skip_encode_sb; - int skip_encode_frame; - // Speed feature to allow or disallow skipping of recode at block - // level within a frame. - int allow_skip_recode; - - // Coefficient probability model approximation step size - int coeff_prob_appx_step; - - // Enable uniform quantizer followed by trellis coefficient optimization - // during transform RD - TRELLIS_OPT_CONTROL trellis_opt_tx_rd; - - // Enable asymptotic closed-loop encoding decision for key frame and - // alternate reference frames. - int allow_acl; - - // Temporal dependency model based encoding mode optimization - int enable_tpl_model; - - // Use transform domain distortion. Use pixel domain distortion in speed 0 - // and certain situations in higher speed to improve the RD model precision. - int allow_txfm_domain_distortion; - double tx_domain_thresh; - - // The threshold is to determine how slow the motino is, it is used when - // use_lastframe_partitioning is set to LAST_FRAME_PARTITION_LOW_MOTION - MOTION_THRESHOLD lf_motion_threshold; - - // Determine which method we use to determine transform size. We can choose - // between options like full rd, largest for prediction size, largest - // for intra and model coefs for the rest. - TX_SIZE_SEARCH_METHOD tx_size_search_method; - - // How many levels of tx size to search, starting from the largest. - int tx_size_search_depth; - - // Low precision 32x32 fdct keeps everything in 16 bits and thus is less - // precise but significantly faster than the non lp version. - int use_lp32x32fdct; - - // After looking at the first set of modes (set by index here), skip - // checking modes for reference frames that don't match the reference frame - // of the best so far. - int mode_skip_start; - - // TODO(JBB): Remove this. - int reference_masking; - - PARTITION_SEARCH_TYPE partition_search_type; - - // Used if partition_search_type = FIXED_PARTITION - BLOCK_SIZE always_this_block_size; - - // Skip rectangular partition test when partition type none gives better - // rd than partition type split. - int less_rectangular_check; - - // Disable testing non square partitions(eg 16x32) for block sizes larger than - // use_square_only_thresh_high or smaller than use_square_only_thresh_low. - int use_square_partition_only; - BLOCK_SIZE use_square_only_thresh_high; - BLOCK_SIZE use_square_only_thresh_low; - - // Prune reference frames for rectangular partitions. - int prune_ref_frame_for_rect_partitions; - - // Sets min and max partition sizes for this 64x64 region based on the - // same 64x64 in last encoded frame, and the left and above neighbor. - AUTO_MIN_MAX_MODE auto_min_max_partition_size; - // Ensures the rd based auto partition search will always - // go down at least to the specified level. - BLOCK_SIZE rd_auto_partition_min_limit; - - // Min and max partition size we enable (block_size) as per auto - // min max, but also used by adjust partitioning, and pick_partitioning. - BLOCK_SIZE default_min_partition_size; - BLOCK_SIZE default_max_partition_size; - - // Whether or not we allow partitions one smaller or one greater than the last - // frame's partitioning. Only used if use_lastframe_partitioning is set. - int adjust_partitioning_from_last_frame; - - // How frequently we re do the partitioning from scratch. Only used if - // use_lastframe_partitioning is set. - int last_partitioning_redo_frequency; - - // Disables sub 8x8 blocksizes in different scenarios: Choices are to disable - // it always, to allow it for only Last frame and Intra, disable it for all - // inter modes or to enable it always. - int disable_split_mask; - - // TODO(jingning): combine the related motion search speed features - // This allows us to use motion search at other sizes as a starting - // point for this motion search and limits the search range around it. - int adaptive_motion_search; - - // Do extra full pixel motion search to obtain better motion vector. - int enhanced_full_pixel_motion_search; - - // Threshold for allowing exhaistive motion search. - int exhaustive_searches_thresh; - - // Pattern to be used for any exhaustive mesh searches. - MESH_PATTERN mesh_patterns[MAX_MESH_STEP]; - - int schedule_mode_search; - - // Allows sub 8x8 modes to use the prediction filter that was determined - // best for 8x8 mode. If set to 0 we always re check all the filters for - // sizes less than 8x8, 1 means we check all filter modes if no 8x8 filter - // was selected, and 2 means we use 8 tap if no 8x8 filter mode was selected. - int adaptive_pred_interp_filter; - - // Adaptive prediction mode search - int adaptive_mode_search; - - // Prune NEAREST and ZEROMV single reference modes based on motion vector - // difference and mode rate - int prune_single_mode_based_on_mv_diff_mode_rate; - - // Chessboard pattern prediction for interp filter. Aggressiveness increases - // with levels. - // 0: disable - // 1: cb pattern in eval when filter is not switchable - // 2: cb pattern prediction for filter search - int cb_pred_filter_search; - - // This variable enables an early termination of interpolation filter eval - // based on the current rd cost after processing each plane - int early_term_interp_search_plane_rd; - - int cb_partition_search; - - int motion_field_mode_search; - - int alt_ref_search_fp; - - // Fast quantization process path - int use_quant_fp; - - // Use finer quantizer in every other few frames that run variable block - // partition type search. - int force_frame_boost; - - // Maximally allowed base quantization index fluctuation. - int max_delta_qindex; - - // Implements various heuristics to skip searching modes - // The heuristics selected are based on flags - // defined in the MODE_SEARCH_SKIP_HEURISTICS enum - unsigned int mode_search_skip_flags; - - // A source variance threshold below which filter search is disabled - // Choose a very large value (UINT_MAX) to use 8-tap always - unsigned int disable_filter_search_var_thresh; - - // These bit masks allow you to enable or disable intra modes for each - // transform size separately. - int intra_y_mode_mask[TX_SIZES]; - int intra_uv_mode_mask[TX_SIZES]; - - // These bit masks allow you to enable or disable intra modes for each - // prediction block size separately. - int intra_y_mode_bsize_mask[BLOCK_SIZES]; - - // This variable enables an early break out of mode testing if the model for - // rd built from the prediction signal indicates a value that's much - // higher than the best rd we've seen so far. - int use_rd_breakout; - - // This enables us to use an estimate for intra rd based on dc mode rather - // than choosing an actual uv mode in the stage of encoding before the actual - // final encode. - int use_uv_intra_rd_estimate; - - // This feature controls how the loop filter level is determined. - LPF_PICK_METHOD lpf_pick; - - // This feature limits the number of coefficients updates we actually do - // by only looking at counts from 1/2 the bands. - FAST_COEFF_UPDATE use_fast_coef_updates; - - // This flag controls the use of non-RD mode decision. - int use_nonrd_pick_mode; - - // A binary mask indicating if NEARESTMV, NEARMV, ZEROMV, NEWMV - // modes are used in order from LSB to MSB for each BLOCK_SIZE. - int inter_mode_mask[BLOCK_SIZES]; - - // This feature controls whether we do the expensive context update and - // calculation in the rd coefficient costing loop. - int use_fast_coef_costing; - - // This feature controls the tolerence vs target used in deciding whether to - // recode a frame. It has no meaning if recode is disabled. - int recode_tolerance_low; - int recode_tolerance_high; - - // This variable controls the maximum block size where intra blocks can be - // used in inter frames. - // TODO(aconverse): Fold this into one of the other many mode skips - BLOCK_SIZE max_intra_bsize; - - // The frequency that we check if SOURCE_VAR_BASED_PARTITION or - // FIXED_PARTITION search type should be used. - int search_type_check_frequency; - - // When partition is pre-set, the inter prediction result from pick_inter_mode - // can be reused in final block encoding process. It is enabled only for real- - // time mode speed 6. - int reuse_inter_pred_sby; - - // This variable sets the encode_breakout threshold. Currently, it is only - // enabled in real time mode. - int encode_breakout_thresh; - - // default interp filter choice - INTERP_FILTER default_interp_filter; - - // Early termination in transform size search, which only applies while - // tx_size_search_method is USE_FULL_RD. - int tx_size_search_breakout; - - // adaptive interp_filter search to allow skip of certain filter types. - int adaptive_interp_filter_search; - - // mask for skip evaluation of certain interp_filter type. - INTERP_FILTER_MASK interp_filter_search_mask; - - // Partition search early breakout thresholds. - PARTITION_SEARCH_BREAKOUT_THR partition_search_breakout_thr; - - struct { - // Use ML-based partition search early breakout. - int search_breakout; - // Higher values mean more aggressiveness for partition search breakout that - // results in better encoding speed but worse compression performance. - float search_breakout_thresh[3]; - - // Machine-learning based partition search early termination - int search_early_termination; - - // Machine-learning based partition search pruning using prediction residue - // variance. - int var_pruning; - - // Threshold values used for ML based rectangular partition search pruning. - // If < 0, the feature is turned off. - // Higher values mean more aggressiveness to skip rectangular partition - // search that results in better encoding speed but worse coding - // performance. - int prune_rect_thresh[4]; - } rd_ml_partition; - - // Fast approximation of vp9_model_rd_from_var_lapndz - int simple_model_rd_from_var; - - // Skip a number of expensive mode evaluations for blocks with zero source - // variance. - int short_circuit_flat_blocks; - - // Skip a number of expensive mode evaluations for blocks with very low - // temporal variance. If the low temporal variance flag is set for a block, - // do the following: - // 1: Skip all golden modes and ALL INTRA for bsize >= 32x32. - // 2: Skip golden non-zeromv and newmv-last for bsize >= 16x16, skip ALL - // INTRA for bsize >= 32x32 and vert/horz INTRA for bsize 16x16, 16x32 and - // 32x16. - // 3: Same as (2), but also skip golden zeromv. - int short_circuit_low_temp_var; - - // Limits the rd-threshold update for early exit for the newmv-last mode, - // for non-rd mode. - int limit_newmv_early_exit; - - // Adds a bias against golden reference, for non-rd mode. - int bias_golden; - - // Bias to use base mv and skip 1/4 subpel search when use base mv in - // enhancement layer. - int base_mv_aggressive; - - // Global flag to enable partition copy from the previous frame. - int copy_partition_flag; - - // Compute the source sad for every superblock of the frame, - // prior to encoding the frame, to be used to bypass some encoder decisions. - int use_source_sad; - - int use_simple_block_yrd; - - // If source sad of superblock is high (> adapt_partition_thresh), will switch - // from VARIANCE_PARTITION to REFERENCE_PARTITION (which selects partition - // based on the nonrd-pickmode). - int adapt_partition_source_sad; - int adapt_partition_thresh; - - // Enable use of alt-refs in 1 pass VBR. - int use_altref_onepass; - - // Enable use of compound prediction, for nonrd_pickmode with nonzero lag. - int use_compound_nonrd_pickmode; - - // Always use nonrd_pick_intra for all block sizes on keyframes. - int nonrd_keyframe; - - // For SVC: enables use of partition from lower spatial resolution. - int svc_use_lowres_part; - - // Flag to indicate process for handling overshoot on slide/scene change, - // for real-time CBR mode. - OVERSHOOT_DETECTION_CBR_RT overshoot_detection_cbr_rt; - - // Disable partitioning of 16x16 blocks. - int disable_16x16part_nonkey; - - // Allow for disabling golden reference. - int disable_golden_ref; - - // Allow sub-pixel search to use interpolation filters with different taps in - // order to achieve accurate motion search result. - SUBPEL_SEARCH_TYPE use_accurate_subpel_search; - - // Search method used by temporal filtering in full_pixel_motion_search. - SEARCH_METHODS temporal_filter_search_method; - - // Use machine learning based partition search. - int nonrd_use_ml_partition; - - // Multiplier for base threshold for variance partitioning. - int variance_part_thresh_mult; - - // Force subpel motion filter to always use SMOOTH_FILTER. - int force_smooth_interpol; - - // For real-time mode: force DC only under intra search when content - // does not have high souce SAD. - int rt_intra_dc_only_low_content; - - // The encoder has a feature that skips forward transform and quantization - // based on a model rd estimation to reduce encoding time. - // However, this feature is dangerous since it could lead to bad perceptual - // quality. This flag is added to guard the feature. - int allow_skip_txfm_ac_dc; -} SPEED_FEATURES; - -struct VP9_COMP; - -void vp9_set_speed_features_framesize_independent(struct VP9_COMP *cpi, - int speed); -void vp9_set_speed_features_framesize_dependent(struct VP9_COMP *cpi, - int speed); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_SPEED_FEATURES_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_subexp.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_subexp.c deleted file mode 100644 index 2e1810b0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_subexp.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "vpx_dsp/bitwriter.h" - -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_entropy.h" -#include "vp9/encoder/vp9_cost.h" -#include "vp9/encoder/vp9_subexp.h" - -static const uint8_t update_bits[255] = { - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 0, -}; -#define MIN_DELP_BITS 5 - -static int recenter_nonneg(int v, int m) { - if (v > (m << 1)) - return v; - else if (v >= m) - return ((v - m) << 1); - else - return ((m - v) << 1) - 1; -} - -static int remap_prob(int v, int m) { - int i; - static const uint8_t map_table[MAX_PROB - 1] = { - // generated by: - // map_table[j] = split_index(j, MAX_PROB - 1, MODULUS_PARAM); - 20, 21, 22, 23, 24, 25, 0, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 1, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 2, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 3, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 4, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 5, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 6, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 7, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 8, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 9, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 10, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 11, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 12, 170, 171, - 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 13, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 14, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 15, 206, 207, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, 16, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, - 228, 229, 17, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, - 18, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 19, - }; - v--; - m--; - assert(m >= 0); - if ((m << 1) <= MAX_PROB) - i = recenter_nonneg(v, m) - 1; - else - i = recenter_nonneg(MAX_PROB - 1 - v, MAX_PROB - 1 - m) - 1; - - assert(i >= 0 && (size_t)i < sizeof(map_table)); - i = map_table[i]; - return i; -} - -static int prob_diff_update_cost(vpx_prob newp, vpx_prob oldp) { - int delp = remap_prob(newp, oldp); - return update_bits[delp] << VP9_PROB_COST_SHIFT; -} - -static void encode_uniform(vpx_writer *w, int v) { - const int l = 8; - const int m = (1 << l) - 191; - if (v < m) { - vpx_write_literal(w, v, l - 1); - } else { - vpx_write_literal(w, m + ((v - m) >> 1), l - 1); - vpx_write_literal(w, (v - m) & 1, 1); - } -} - -static INLINE int write_bit_gte(vpx_writer *w, int word, int test) { - vpx_write_literal(w, word >= test, 1); - return word >= test; -} - -static void encode_term_subexp(vpx_writer *w, int word) { - if (!write_bit_gte(w, word, 16)) { - vpx_write_literal(w, word, 4); - } else if (!write_bit_gte(w, word, 32)) { - vpx_write_literal(w, word - 16, 4); - } else if (!write_bit_gte(w, word, 64)) { - vpx_write_literal(w, word - 32, 5); - } else { - encode_uniform(w, word - 64); - } -} - -void vp9_write_prob_diff_update(vpx_writer *w, vpx_prob newp, vpx_prob oldp) { - const int delp = remap_prob(newp, oldp); - encode_term_subexp(w, delp); -} - -int64_t vp9_prob_diff_update_savings_search(const unsigned int *ct, - vpx_prob oldp, vpx_prob *bestp, - vpx_prob upd) { - const int64_t old_b = cost_branch256(ct, oldp); - int64_t bestsavings = 0; - vpx_prob newp, bestnewp = oldp; - const int step = *bestp > oldp ? -1 : 1; - const int upd_cost = vp9_cost_one(upd) - vp9_cost_zero(upd); - - if (old_b > upd_cost + (MIN_DELP_BITS << VP9_PROB_COST_SHIFT)) { - for (newp = *bestp; newp != oldp; newp += step) { - const int64_t new_b = cost_branch256(ct, newp); - const int64_t update_b = prob_diff_update_cost(newp, oldp) + upd_cost; - const int64_t savings = old_b - new_b - update_b; - if (savings > bestsavings) { - bestsavings = savings; - bestnewp = newp; - } - } - } - *bestp = bestnewp; - return bestsavings; -} - -int64_t vp9_prob_diff_update_savings_search_model(const unsigned int *ct, - const vpx_prob oldp, - vpx_prob *bestp, vpx_prob upd, - int stepsize) { - int64_t i, old_b, new_b, update_b, savings, bestsavings; - int64_t newp; - const int64_t step_sign = *bestp > oldp ? -1 : 1; - const int64_t step = stepsize * step_sign; - const int64_t upd_cost = vp9_cost_one(upd) - vp9_cost_zero(upd); - const vpx_prob *newplist, *oldplist; - vpx_prob bestnewp; - oldplist = vp9_pareto8_full[oldp - 1]; - old_b = cost_branch256(ct + 2 * PIVOT_NODE, oldp); - for (i = UNCONSTRAINED_NODES; i < ENTROPY_NODES; ++i) - old_b += cost_branch256(ct + 2 * i, oldplist[i - UNCONSTRAINED_NODES]); - - bestsavings = 0; - bestnewp = oldp; - - assert(stepsize > 0); - - if (old_b > upd_cost + (MIN_DELP_BITS << VP9_PROB_COST_SHIFT)) { - for (newp = *bestp; (newp - oldp) * step_sign < 0; newp += step) { - if (newp < 1 || newp > 255) continue; - newplist = vp9_pareto8_full[newp - 1]; - new_b = cost_branch256(ct + 2 * PIVOT_NODE, (vpx_prob)newp); - for (i = UNCONSTRAINED_NODES; i < ENTROPY_NODES; ++i) - new_b += cost_branch256(ct + 2 * i, newplist[i - UNCONSTRAINED_NODES]); - update_b = prob_diff_update_cost((vpx_prob)newp, oldp) + upd_cost; - savings = old_b - new_b - update_b; - if (savings > bestsavings) { - bestsavings = savings; - bestnewp = (vpx_prob)newp; - } - } - } - - *bestp = bestnewp; - return bestsavings; -} - -void vp9_cond_prob_diff_update(vpx_writer *w, vpx_prob *oldp, - const unsigned int ct[2]) { - const vpx_prob upd = DIFF_UPDATE_PROB; - vpx_prob newp = get_binary_prob(ct[0], ct[1]); - const int64_t savings = - vp9_prob_diff_update_savings_search(ct, *oldp, &newp, upd); - assert(newp >= 1); - if (savings > 0) { - vpx_write(w, 1, upd); - vp9_write_prob_diff_update(w, newp, *oldp); - *oldp = newp; - } else { - vpx_write(w, 0, upd); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_subexp.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_subexp.h deleted file mode 100644 index 2d016d24..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_subexp.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_SUBEXP_H_ -#define VPX_VP9_ENCODER_VP9_SUBEXP_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "vpx_dsp/prob.h" - -struct vpx_writer; - -void vp9_write_prob_diff_update(struct vpx_writer *w, vpx_prob newp, - vpx_prob oldp); - -void vp9_cond_prob_diff_update(struct vpx_writer *w, vpx_prob *oldp, - const unsigned int ct[2]); - -int64_t vp9_prob_diff_update_savings_search(const unsigned int *ct, - vpx_prob oldp, vpx_prob *bestp, - vpx_prob upd); - -int64_t vp9_prob_diff_update_savings_search_model(const unsigned int *ct, - const vpx_prob oldp, - vpx_prob *bestp, vpx_prob upd, - int stepsize); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_SUBEXP_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_svc_layercontext.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_svc_layercontext.c deleted file mode 100644 index 6bc329a2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_svc_layercontext.c +++ /dev/null @@ -1,1377 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "vp9/encoder/vp9_aq_cyclicrefresh.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_svc_layercontext.h" -#include "vp9/encoder/vp9_extend.h" -#include "vpx_dsp/vpx_dsp_common.h" - -#define SMALL_FRAME_WIDTH 32 -#define SMALL_FRAME_HEIGHT 16 - -static void swap_ptr(void *a, void *b) { - void **a_p = (void **)a; - void **b_p = (void **)b; - void *c = *a_p; - *a_p = *b_p; - *b_p = c; -} - -void vp9_init_layer_context(VP9_COMP *const cpi) { - SVC *const svc = &cpi->svc; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - int mi_rows = cpi->common.mi_rows; - int mi_cols = cpi->common.mi_cols; - int sl, tl, i; - int alt_ref_idx = svc->number_spatial_layers; - - svc->spatial_layer_id = 0; - svc->temporal_layer_id = 0; - svc->force_zero_mode_spatial_ref = 0; - svc->use_base_mv = 0; - svc->use_partition_reuse = 0; - svc->use_gf_temporal_ref = 1; - svc->use_gf_temporal_ref_current_layer = 0; - svc->scaled_temp_is_alloc = 0; - svc->scaled_one_half = 0; - svc->current_superframe = 0; - svc->non_reference_frame = 0; - svc->skip_enhancement_layer = 0; - svc->disable_inter_layer_pred = INTER_LAYER_PRED_ON; - svc->framedrop_mode = CONSTRAINED_LAYER_DROP; - svc->set_intra_only_frame = 0; - svc->previous_frame_is_intra_only = 0; - svc->superframe_has_layer_sync = 0; - svc->use_set_ref_frame_config = 0; - svc->num_encoded_top_layer = 0; - svc->simulcast_mode = 0; - svc->single_layer_svc = 0; - svc->resize_set = 0; - - for (i = 0; i < REF_FRAMES; ++i) { - svc->fb_idx_spatial_layer_id[i] = 0xff; - svc->fb_idx_temporal_layer_id[i] = 0xff; - svc->fb_idx_base[i] = 0; - } - for (sl = 0; sl < oxcf->ss_number_layers; ++sl) { - svc->last_layer_dropped[sl] = 0; - svc->drop_spatial_layer[sl] = 0; - svc->ext_frame_flags[sl] = 0; - svc->lst_fb_idx[sl] = 0; - svc->gld_fb_idx[sl] = 1; - svc->alt_fb_idx[sl] = 2; - svc->downsample_filter_type[sl] = BILINEAR; - svc->downsample_filter_phase[sl] = 8; // Set to 8 for averaging filter. - svc->framedrop_thresh[sl] = oxcf->drop_frames_water_mark; - svc->fb_idx_upd_tl0[sl] = -1; - svc->drop_count[sl] = 0; - svc->spatial_layer_sync[sl] = 0; - svc->force_drop_constrained_from_above[sl] = 0; - } - svc->max_consec_drop = INT_MAX; - - svc->buffer_gf_temporal_ref[1].idx = 7; - svc->buffer_gf_temporal_ref[0].idx = 6; - svc->buffer_gf_temporal_ref[1].is_used = 0; - svc->buffer_gf_temporal_ref[0].is_used = 0; - - if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2) { - if (vpx_realloc_frame_buffer(&cpi->svc.empty_frame.img, SMALL_FRAME_WIDTH, - SMALL_FRAME_HEIGHT, cpi->common.subsampling_x, - cpi->common.subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cpi->common.use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS, - cpi->common.byte_alignment, NULL, NULL, NULL)) - vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, - "Failed to allocate empty frame for multiple frame " - "contexts"); - - memset(cpi->svc.empty_frame.img.buffer_alloc, 0x80, - cpi->svc.empty_frame.img.buffer_alloc_sz); - } - - for (sl = 0; sl < oxcf->ss_number_layers; ++sl) { - for (tl = 0; tl < oxcf->ts_number_layers; ++tl) { - int layer = LAYER_IDS_TO_IDX(sl, tl, oxcf->ts_number_layers); - LAYER_CONTEXT *const lc = &svc->layer_context[layer]; - RATE_CONTROL *const lrc = &lc->rc; - lc->current_video_frame_in_layer = 0; - lc->layer_size = 0; - lc->frames_from_key_frame = 0; - lc->last_frame_type = FRAME_TYPES; - lrc->ni_av_qi = oxcf->worst_allowed_q; - lrc->total_actual_bits = 0; - lrc->total_target_vs_actual = 0; - lrc->ni_tot_qi = 0; - lrc->tot_q = 0.0; - lrc->avg_q = 0.0; - lrc->ni_frames = 0; - lrc->decimation_count = 0; - lrc->decimation_factor = 0; - lrc->worst_quality = oxcf->worst_allowed_q; - lrc->best_quality = oxcf->best_allowed_q; - - for (i = 0; i < RATE_FACTOR_LEVELS; ++i) { - lrc->rate_correction_factors[i] = 1.0; - } - - if (cpi->oxcf.rc_mode == VPX_CBR) { - lc->target_bandwidth = oxcf->layer_target_bitrate[layer]; - lrc->last_q[INTER_FRAME] = oxcf->worst_allowed_q; - lrc->avg_frame_qindex[INTER_FRAME] = oxcf->worst_allowed_q; - lrc->avg_frame_qindex[KEY_FRAME] = oxcf->worst_allowed_q; - } else { - lc->target_bandwidth = oxcf->layer_target_bitrate[layer]; - lrc->last_q[KEY_FRAME] = oxcf->best_allowed_q; - lrc->last_q[INTER_FRAME] = oxcf->best_allowed_q; - lrc->avg_frame_qindex[KEY_FRAME] = - (oxcf->worst_allowed_q + oxcf->best_allowed_q) / 2; - lrc->avg_frame_qindex[INTER_FRAME] = - (oxcf->worst_allowed_q + oxcf->best_allowed_q) / 2; - if (oxcf->ss_enable_auto_arf[sl]) - lc->alt_ref_idx = alt_ref_idx++; - else - lc->alt_ref_idx = INVALID_IDX; - lc->gold_ref_idx = INVALID_IDX; - } - - lrc->buffer_level = - oxcf->starting_buffer_level_ms * lc->target_bandwidth / 1000; - lrc->bits_off_target = lrc->buffer_level; - - // Initialize the cyclic refresh parameters. If spatial layers are used - // (i.e., ss_number_layers > 1), these need to be updated per spatial - // layer. - // Cyclic refresh is only applied on base temporal layer. - if (oxcf->ss_number_layers > 1 && tl == 0) { - size_t last_coded_q_map_size; - size_t consec_zero_mv_size; - VP9_COMMON *const cm = &cpi->common; - lc->sb_index = 0; - lc->actual_num_seg1_blocks = 0; - lc->actual_num_seg2_blocks = 0; - lc->counter_encode_maxq_scene_change = 0; - CHECK_MEM_ERROR(&cm->error, lc->map, - vpx_malloc(mi_rows * mi_cols * sizeof(*lc->map))); - memset(lc->map, 0, mi_rows * mi_cols); - last_coded_q_map_size = - mi_rows * mi_cols * sizeof(*lc->last_coded_q_map); - CHECK_MEM_ERROR(&cm->error, lc->last_coded_q_map, - vpx_malloc(last_coded_q_map_size)); - assert(MAXQ <= 255); - memset(lc->last_coded_q_map, MAXQ, last_coded_q_map_size); - consec_zero_mv_size = mi_rows * mi_cols * sizeof(*lc->consec_zero_mv); - CHECK_MEM_ERROR(&cm->error, lc->consec_zero_mv, - vpx_malloc(consec_zero_mv_size)); - memset(lc->consec_zero_mv, 0, consec_zero_mv_size); - } - } - } - - // Still have extra buffer for base layer golden frame - if (!(svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) && - alt_ref_idx < REF_FRAMES) - svc->layer_context[0].gold_ref_idx = alt_ref_idx; -} - -// Update the layer context from a change_config() call. -void vp9_update_layer_context_change_config(VP9_COMP *const cpi, - const int target_bandwidth) { - SVC *const svc = &cpi->svc; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - const RATE_CONTROL *const rc = &cpi->rc; - int sl, tl, layer = 0, spatial_layer_target; - float bitrate_alloc = 1.0; - int num_spatial_layers_nonzero_rate = 0; - - cpi->svc.temporal_layering_mode = oxcf->temporal_layering_mode; - - if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING) { - for (sl = 0; sl < oxcf->ss_number_layers; ++sl) { - for (tl = 0; tl < oxcf->ts_number_layers; ++tl) { - layer = LAYER_IDS_TO_IDX(sl, tl, oxcf->ts_number_layers); - svc->layer_context[layer].target_bandwidth = - oxcf->layer_target_bitrate[layer]; - } - - layer = LAYER_IDS_TO_IDX( - sl, - ((oxcf->ts_number_layers - 1) < 0 ? 0 : (oxcf->ts_number_layers - 1)), - oxcf->ts_number_layers); - spatial_layer_target = svc->layer_context[layer].target_bandwidth = - oxcf->layer_target_bitrate[layer]; - - for (tl = 0; tl < oxcf->ts_number_layers; ++tl) { - LAYER_CONTEXT *const lc = - &svc->layer_context[sl * oxcf->ts_number_layers + tl]; - RATE_CONTROL *const lrc = &lc->rc; - - lc->spatial_layer_target_bandwidth = spatial_layer_target; - if (target_bandwidth != 0) { - bitrate_alloc = (float)lc->target_bandwidth / target_bandwidth; - } - lrc->starting_buffer_level = - (int64_t)(rc->starting_buffer_level * bitrate_alloc + 0.5); - lrc->optimal_buffer_level = - (int64_t)(rc->optimal_buffer_level * bitrate_alloc + 0.5); - lrc->maximum_buffer_size = - (int64_t)(rc->maximum_buffer_size * bitrate_alloc + 0.5); - lrc->bits_off_target = - VPXMIN(lrc->bits_off_target, lrc->maximum_buffer_size); - lrc->buffer_level = VPXMIN(lrc->buffer_level, lrc->maximum_buffer_size); - lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[tl]; - lrc->avg_frame_bandwidth = saturate_cast_double_to_int( - round(lc->target_bandwidth / lc->framerate)); - lrc->max_frame_bandwidth = rc->max_frame_bandwidth; - lrc->worst_quality = rc->worst_quality; - lrc->best_quality = rc->best_quality; - } - } - } else { - int layer_end; - - if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) { - layer_end = svc->number_temporal_layers; - } else { - layer_end = svc->number_spatial_layers; - } - - for (layer = 0; layer < layer_end; ++layer) { - LAYER_CONTEXT *const lc = &svc->layer_context[layer]; - RATE_CONTROL *const lrc = &lc->rc; - - lc->target_bandwidth = oxcf->layer_target_bitrate[layer]; - - if (target_bandwidth != 0) { - bitrate_alloc = (float)lc->target_bandwidth / target_bandwidth; - } - // Update buffer-related quantities. - lrc->starting_buffer_level = - (int64_t)(rc->starting_buffer_level * bitrate_alloc); - lrc->optimal_buffer_level = - (int64_t)(rc->optimal_buffer_level * bitrate_alloc); - lrc->maximum_buffer_size = - (int64_t)(rc->maximum_buffer_size * bitrate_alloc); - lrc->bits_off_target = - VPXMIN(lrc->bits_off_target, lrc->maximum_buffer_size); - lrc->buffer_level = VPXMIN(lrc->buffer_level, lrc->maximum_buffer_size); - // Update framerate-related quantities. - if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) { - lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[layer]; - } else { - lc->framerate = cpi->framerate; - } - lrc->avg_frame_bandwidth = saturate_cast_double_to_int( - round(lc->target_bandwidth / lc->framerate)); - lrc->max_frame_bandwidth = rc->max_frame_bandwidth; - // Update qp-related quantities. - lrc->worst_quality = rc->worst_quality; - lrc->best_quality = rc->best_quality; - } - } - for (sl = 0; sl < oxcf->ss_number_layers; ++sl) { - // Check bitrate of spatia layer. - layer = LAYER_IDS_TO_IDX(sl, oxcf->ts_number_layers - 1, - oxcf->ts_number_layers); - if (oxcf->layer_target_bitrate[layer] > 0) - num_spatial_layers_nonzero_rate += 1; - } - if (num_spatial_layers_nonzero_rate == 1) - svc->single_layer_svc = 1; - else - svc->single_layer_svc = 0; -} - -static LAYER_CONTEXT *get_layer_context(VP9_COMP *const cpi) { - if (is_one_pass_svc(cpi)) - return &cpi->svc.layer_context[cpi->svc.spatial_layer_id * - cpi->svc.number_temporal_layers + - cpi->svc.temporal_layer_id]; - else - return (cpi->svc.number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) - ? &cpi->svc.layer_context[cpi->svc.temporal_layer_id] - : &cpi->svc.layer_context[cpi->svc.spatial_layer_id]; -} - -void vp9_update_temporal_layer_framerate(VP9_COMP *const cpi) { - SVC *const svc = &cpi->svc; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - LAYER_CONTEXT *const lc = get_layer_context(cpi); - RATE_CONTROL *const lrc = &lc->rc; - // Index into spatial+temporal arrays. - const int st_idx = svc->spatial_layer_id * svc->number_temporal_layers + - svc->temporal_layer_id; - const int tl = svc->temporal_layer_id; - - lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[tl]; - lrc->avg_frame_bandwidth = - saturate_cast_double_to_int(round(lc->target_bandwidth / lc->framerate)); - lrc->max_frame_bandwidth = cpi->rc.max_frame_bandwidth; - // Update the average layer frame size (non-cumulative per-frame-bw). - if (tl == 0) { - lc->avg_frame_size = lrc->avg_frame_bandwidth; - } else { - const double prev_layer_framerate = - cpi->framerate / oxcf->ts_rate_decimator[tl - 1]; - const int prev_layer_target_bandwidth = - oxcf->layer_target_bitrate[st_idx - 1]; - lc->avg_frame_size = - (int)round((lc->target_bandwidth - prev_layer_target_bandwidth) / - (lc->framerate - prev_layer_framerate)); - } -} - -void vp9_update_spatial_layer_framerate(VP9_COMP *const cpi, double framerate) { - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - LAYER_CONTEXT *const lc = get_layer_context(cpi); - RATE_CONTROL *const lrc = &lc->rc; - - lc->framerate = framerate; - lrc->avg_frame_bandwidth = - saturate_cast_double_to_int(round(lc->target_bandwidth / lc->framerate)); - const int64_t vbr_min_bits = - (int64_t)lrc->avg_frame_bandwidth * oxcf->two_pass_vbrmin_section / 100; - lrc->min_frame_bandwidth = (int)VPXMIN(vbr_min_bits, INT_MAX); - const int64_t vbr_max_bits = - (int64_t)lrc->avg_frame_bandwidth * oxcf->two_pass_vbrmax_section / 100; - lrc->max_frame_bandwidth = (int)VPXMIN(vbr_max_bits, INT_MAX); - vp9_rc_set_gf_interval_range(cpi, lrc); -} - -void vp9_restore_layer_context(VP9_COMP *const cpi) { - LAYER_CONTEXT *const lc = get_layer_context(cpi); - const int old_frame_since_key = cpi->rc.frames_since_key; - const int old_frame_to_key = cpi->rc.frames_to_key; - const int old_ext_use_post_encode_drop = cpi->rc.ext_use_post_encode_drop; - - cpi->rc = lc->rc; - cpi->twopass = lc->twopass; - cpi->oxcf.target_bandwidth = lc->target_bandwidth; - cpi->alt_ref_source = lc->alt_ref_source; - // Check if it is one_pass_cbr_svc mode and lc->speed > 0 (real-time mode - // does not use speed = 0). - if (is_one_pass_svc(cpi) && lc->speed > 0) { - cpi->oxcf.speed = lc->speed; - } - cpi->loopfilter_ctrl = lc->loopfilter_ctrl; - // Reset the frames_since_key and frames_to_key counters to their values - // before the layer restore. Keep these defined for the stream (not layer). - if (cpi->svc.number_temporal_layers > 1 || - cpi->svc.number_spatial_layers > 1) { - cpi->rc.frames_since_key = old_frame_since_key; - cpi->rc.frames_to_key = old_frame_to_key; - } - cpi->rc.ext_use_post_encode_drop = old_ext_use_post_encode_drop; - // For spatial-svc, allow cyclic-refresh to be applied on the spatial layers, - // for the base temporal layer. - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && - cpi->svc.number_spatial_layers > 1 && cpi->svc.temporal_layer_id == 0) { - CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; - swap_ptr(&cr->map, &lc->map); - swap_ptr(&cr->last_coded_q_map, &lc->last_coded_q_map); - swap_ptr(&cpi->consec_zero_mv, &lc->consec_zero_mv); - cr->sb_index = lc->sb_index; - cr->actual_num_seg1_blocks = lc->actual_num_seg1_blocks; - cr->actual_num_seg2_blocks = lc->actual_num_seg2_blocks; - cr->counter_encode_maxq_scene_change = lc->counter_encode_maxq_scene_change; - } -} - -void vp9_save_layer_context(VP9_COMP *const cpi) { - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - LAYER_CONTEXT *const lc = get_layer_context(cpi); - - lc->rc = cpi->rc; - lc->twopass = cpi->twopass; - lc->target_bandwidth = (int)oxcf->target_bandwidth; - lc->alt_ref_source = cpi->alt_ref_source; - lc->frame_qp = cpi->common.base_qindex; - lc->MBs = cpi->common.MBs; - - // For spatial-svc, allow cyclic-refresh to be applied on the spatial layers, - // for the base temporal layer. - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && - cpi->svc.number_spatial_layers > 1 && cpi->svc.temporal_layer_id == 0) { - CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; - signed char *temp = lc->map; - uint8_t *temp2 = lc->last_coded_q_map; - uint8_t *temp3 = lc->consec_zero_mv; - lc->map = cr->map; - cr->map = temp; - lc->last_coded_q_map = cr->last_coded_q_map; - cr->last_coded_q_map = temp2; - lc->consec_zero_mv = cpi->consec_zero_mv; - cpi->consec_zero_mv = temp3; - lc->sb_index = cr->sb_index; - lc->actual_num_seg1_blocks = cr->actual_num_seg1_blocks; - lc->actual_num_seg2_blocks = cr->actual_num_seg2_blocks; - lc->counter_encode_maxq_scene_change = cr->counter_encode_maxq_scene_change; - lc->qindex_delta[0] = cr->qindex_delta[0]; - lc->qindex_delta[1] = cr->qindex_delta[1]; - lc->qindex_delta[2] = cr->qindex_delta[2]; - } -} - -#if !CONFIG_REALTIME_ONLY -void vp9_init_second_pass_spatial_svc(VP9_COMP *cpi) { - SVC *const svc = &cpi->svc; - int i; - - for (i = 0; i < svc->number_spatial_layers; ++i) { - TWO_PASS *const twopass = &svc->layer_context[i].twopass; - - svc->spatial_layer_id = i; - vp9_init_second_pass(cpi); - - twopass->total_stats.spatial_layer_id = i; - twopass->total_left_stats.spatial_layer_id = i; - } - svc->spatial_layer_id = 0; -} -#endif // !CONFIG_REALTIME_ONLY - -void vp9_inc_frame_in_layer(VP9_COMP *const cpi) { - LAYER_CONTEXT *const lc = - &cpi->svc.layer_context[cpi->svc.spatial_layer_id * - cpi->svc.number_temporal_layers]; - ++lc->current_video_frame_in_layer; - ++lc->frames_from_key_frame; - if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) - ++cpi->svc.current_superframe; -} - -void get_layer_resolution(const int width_org, const int height_org, - const int num, const int den, int *width_out, - int *height_out) { - int w, h; - - if (width_out == NULL || height_out == NULL || den == 0) return; - - w = width_org * num / den; - h = height_org * num / den; - - // make height and width even to make chrome player happy - w += w % 2; - h += h % 2; - - *width_out = w; - *height_out = h; -} - -static void reset_fb_idx_unused(VP9_COMP *const cpi) { - // If a reference frame is not referenced or refreshed, then set the - // fb_idx for that reference to the first one used/referenced. - // This is to avoid setting fb_idx for a reference to a slot that is not - // used/needed (i.e., since that reference is not referenced or refreshed). - MV_REFERENCE_FRAME ref_frame; - MV_REFERENCE_FRAME first_ref = 0; - int first_fb_idx = 0; - int fb_idx[3] = { cpi->lst_fb_idx, cpi->gld_fb_idx, cpi->alt_fb_idx }; - for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) { - if (cpi->ref_frame_flags & ref_frame_to_flag(ref_frame)) { - first_ref = ref_frame; - first_fb_idx = fb_idx[ref_frame - 1]; - break; - } - } - if (first_ref > 0) { - if (first_ref != LAST_FRAME && !(cpi->ref_frame_flags & VP9_LAST_FLAG) && - !cpi->ext_refresh_last_frame) - cpi->lst_fb_idx = first_fb_idx; - else if (first_ref != GOLDEN_FRAME && - !(cpi->ref_frame_flags & VP9_GOLD_FLAG) && - !cpi->ext_refresh_golden_frame) - cpi->gld_fb_idx = first_fb_idx; - else if (first_ref != ALTREF_FRAME && - !(cpi->ref_frame_flags & VP9_ALT_FLAG) && - !cpi->ext_refresh_alt_ref_frame) - cpi->alt_fb_idx = first_fb_idx; - } -} - -// Never refresh any reference frame buffers on top temporal layers in -// simulcast mode, which has interlayer prediction disabled. -static void non_reference_frame_simulcast(VP9_COMP *const cpi) { - if (cpi->svc.temporal_layer_id == cpi->svc.number_temporal_layers - 1 && - cpi->svc.temporal_layer_id > 0) { - cpi->ext_refresh_last_frame = 0; - cpi->ext_refresh_golden_frame = 0; - cpi->ext_refresh_alt_ref_frame = 0; - } -} - -// The function sets proper ref_frame_flags, buffer indices, and buffer update -// variables for temporal layering mode 3 - that does 0-2-1-2 temporal layering -// scheme. -static void set_flags_and_fb_idx_for_temporal_mode3(VP9_COMP *const cpi) { - int frame_num_within_temporal_struct = 0; - int spatial_id, temporal_id; - spatial_id = cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode; - frame_num_within_temporal_struct = - cpi->svc - .layer_context[cpi->svc.spatial_layer_id * - cpi->svc.number_temporal_layers] - .current_video_frame_in_layer % - 4; - temporal_id = cpi->svc.temporal_layer_id = - (frame_num_within_temporal_struct & 1) - ? 2 - : (frame_num_within_temporal_struct >> 1); - cpi->ext_refresh_last_frame = cpi->ext_refresh_golden_frame = - cpi->ext_refresh_alt_ref_frame = 0; - if (!temporal_id) { - cpi->ext_refresh_frame_flags_pending = 1; - cpi->ext_refresh_last_frame = 1; - if (!spatial_id) { - cpi->ref_frame_flags = VP9_LAST_FLAG; - } else if (cpi->svc.layer_context[temporal_id].is_key_frame) { - // base layer is a key frame. - cpi->ref_frame_flags = VP9_LAST_FLAG; - cpi->ext_refresh_last_frame = 0; - cpi->ext_refresh_golden_frame = 1; - } else { - cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; - } - } else if (temporal_id == 1) { - cpi->ext_refresh_frame_flags_pending = 1; - cpi->ext_refresh_alt_ref_frame = 1; - if (!spatial_id) { - cpi->ref_frame_flags = VP9_LAST_FLAG; - } else { - cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; - } - } else { - if (frame_num_within_temporal_struct == 1) { - // the first tl2 picture - if (spatial_id == cpi->svc.number_spatial_layers - 1) { // top layer - cpi->ext_refresh_frame_flags_pending = 1; - if (!spatial_id) - cpi->ref_frame_flags = VP9_LAST_FLAG; - else - cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; - } else if (!spatial_id) { - cpi->ext_refresh_frame_flags_pending = 1; - cpi->ext_refresh_alt_ref_frame = 1; - cpi->ref_frame_flags = VP9_LAST_FLAG; - } else if (spatial_id < cpi->svc.number_spatial_layers - 1) { - cpi->ext_refresh_frame_flags_pending = 1; - cpi->ext_refresh_alt_ref_frame = 1; - cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; - } - } else { - // The second tl2 picture - if (spatial_id == cpi->svc.number_spatial_layers - 1) { // top layer - cpi->ext_refresh_frame_flags_pending = 1; - if (!spatial_id) - cpi->ref_frame_flags = VP9_LAST_FLAG; - else - cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; - } else if (!spatial_id) { - cpi->ext_refresh_frame_flags_pending = 1; - cpi->ref_frame_flags = VP9_LAST_FLAG; - cpi->ext_refresh_alt_ref_frame = 1; - } else { // top layer - cpi->ext_refresh_frame_flags_pending = 1; - cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; - cpi->ext_refresh_alt_ref_frame = 1; - } - } - } - if (temporal_id == 0) { - cpi->lst_fb_idx = spatial_id; - if (spatial_id) { - if (cpi->svc.layer_context[temporal_id].is_key_frame) { - cpi->lst_fb_idx = spatial_id - 1; - cpi->gld_fb_idx = spatial_id; - } else { - cpi->gld_fb_idx = spatial_id - 1; - } - } else { - cpi->gld_fb_idx = 0; - } - cpi->alt_fb_idx = 0; - } else if (temporal_id == 1) { - cpi->lst_fb_idx = spatial_id; - cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1; - cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id; - } else if (frame_num_within_temporal_struct == 1) { - cpi->lst_fb_idx = spatial_id; - cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1; - cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id; - } else { - cpi->lst_fb_idx = cpi->svc.number_spatial_layers + spatial_id; - cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1; - cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id; - } - - if (cpi->svc.simulcast_mode) non_reference_frame_simulcast(cpi); - - reset_fb_idx_unused(cpi); -} - -// The function sets proper ref_frame_flags, buffer indices, and buffer update -// variables for temporal layering mode 2 - that does 0-1-0-1 temporal layering -// scheme. -static void set_flags_and_fb_idx_for_temporal_mode2(VP9_COMP *const cpi) { - int spatial_id, temporal_id; - spatial_id = cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode; - temporal_id = cpi->svc.temporal_layer_id = - cpi->svc - .layer_context[cpi->svc.spatial_layer_id * - cpi->svc.number_temporal_layers] - .current_video_frame_in_layer & - 1; - cpi->ext_refresh_last_frame = cpi->ext_refresh_golden_frame = - cpi->ext_refresh_alt_ref_frame = 0; - if (!temporal_id) { - cpi->ext_refresh_frame_flags_pending = 1; - cpi->ext_refresh_last_frame = 1; - if (!spatial_id) { - cpi->ref_frame_flags = VP9_LAST_FLAG; - } else if (cpi->svc.layer_context[temporal_id].is_key_frame) { - // base layer is a key frame. - cpi->ref_frame_flags = VP9_LAST_FLAG; - cpi->ext_refresh_last_frame = 0; - cpi->ext_refresh_golden_frame = 1; - } else { - cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; - } - } else if (temporal_id == 1) { - cpi->ext_refresh_frame_flags_pending = 1; - cpi->ext_refresh_alt_ref_frame = 1; - if (!spatial_id) { - cpi->ref_frame_flags = VP9_LAST_FLAG; - } else { - if (spatial_id == cpi->svc.number_spatial_layers - 1) - cpi->ext_refresh_alt_ref_frame = 0; - cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; - } - } - - if (temporal_id == 0) { - cpi->lst_fb_idx = spatial_id; - if (spatial_id) { - if (cpi->svc.layer_context[temporal_id].is_key_frame) { - cpi->lst_fb_idx = spatial_id - 1; - cpi->gld_fb_idx = spatial_id; - } else { - cpi->gld_fb_idx = spatial_id - 1; - } - } else { - cpi->gld_fb_idx = 0; - } - cpi->alt_fb_idx = 0; - } else if (temporal_id == 1) { - cpi->lst_fb_idx = spatial_id; - cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1; - cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id; - } - - if (cpi->svc.simulcast_mode) non_reference_frame_simulcast(cpi); - - reset_fb_idx_unused(cpi); -} - -// The function sets proper ref_frame_flags, buffer indices, and buffer update -// variables for temporal layering mode 0 - that has no temporal layering. -static void set_flags_and_fb_idx_for_temporal_mode_noLayering( - VP9_COMP *const cpi) { - int spatial_id; - spatial_id = cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode; - cpi->ext_refresh_last_frame = cpi->ext_refresh_golden_frame = - cpi->ext_refresh_alt_ref_frame = 0; - cpi->ext_refresh_frame_flags_pending = 1; - cpi->ext_refresh_last_frame = 1; - if (!spatial_id) { - cpi->ref_frame_flags = VP9_LAST_FLAG; - } else if (cpi->svc.layer_context[0].is_key_frame) { - cpi->ref_frame_flags = VP9_LAST_FLAG; - cpi->ext_refresh_last_frame = 0; - cpi->ext_refresh_golden_frame = 1; - } else { - cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG; - } - cpi->lst_fb_idx = spatial_id; - if (spatial_id) { - if (cpi->svc.layer_context[0].is_key_frame) { - cpi->lst_fb_idx = spatial_id - 1; - cpi->gld_fb_idx = spatial_id; - } else { - cpi->gld_fb_idx = spatial_id - 1; - } - } else { - cpi->gld_fb_idx = 0; - } - - if (cpi->svc.simulcast_mode) non_reference_frame_simulcast(cpi); - - reset_fb_idx_unused(cpi); -} - -static void set_flags_and_fb_idx_bypass_via_set_ref_frame_config( - VP9_COMP *const cpi) { - SVC *const svc = &cpi->svc; - int sl = svc->spatial_layer_id = svc->spatial_layer_to_encode; - cpi->svc.temporal_layer_id = cpi->svc.temporal_layer_id_per_spatial[sl]; - cpi->ext_refresh_frame_flags_pending = 1; - cpi->lst_fb_idx = svc->lst_fb_idx[sl]; - cpi->gld_fb_idx = svc->gld_fb_idx[sl]; - cpi->alt_fb_idx = svc->alt_fb_idx[sl]; - cpi->ext_refresh_last_frame = 0; - cpi->ext_refresh_golden_frame = 0; - cpi->ext_refresh_alt_ref_frame = 0; - cpi->ref_frame_flags = 0; - if (svc->reference_last[sl]) cpi->ref_frame_flags |= VP9_LAST_FLAG; - if (svc->reference_golden[sl]) cpi->ref_frame_flags |= VP9_GOLD_FLAG; - if (svc->reference_altref[sl]) cpi->ref_frame_flags |= VP9_ALT_FLAG; -} - -void vp9_copy_flags_ref_update_idx(VP9_COMP *const cpi) { - SVC *const svc = &cpi->svc; - int sl = svc->spatial_layer_id; - svc->lst_fb_idx[sl] = cpi->lst_fb_idx; - svc->gld_fb_idx[sl] = cpi->gld_fb_idx; - svc->alt_fb_idx[sl] = cpi->alt_fb_idx; - // For the fixed SVC mode: pass the refresh_lst/gld/alt_frame flags to the - // update_buffer_slot, this is needed for the GET_SVC_REF_FRAME_CONFIG api. - if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS) { - int ref; - for (ref = 0; ref < REF_FRAMES; ++ref) { - svc->update_buffer_slot[sl] &= ~(1 << ref); - if ((ref == svc->lst_fb_idx[sl] && cpi->refresh_last_frame) || - (ref == svc->gld_fb_idx[sl] && cpi->refresh_golden_frame) || - (ref == svc->alt_fb_idx[sl] && cpi->refresh_alt_ref_frame)) - svc->update_buffer_slot[sl] |= (1 << ref); - } - } - - // TODO(jianj): Remove these 3, deprecated. - svc->update_last[sl] = (uint8_t)cpi->refresh_last_frame; - svc->update_golden[sl] = (uint8_t)cpi->refresh_golden_frame; - svc->update_altref[sl] = (uint8_t)cpi->refresh_alt_ref_frame; - - svc->reference_last[sl] = (uint8_t)(cpi->ref_frame_flags & VP9_LAST_FLAG); - svc->reference_golden[sl] = (uint8_t)(cpi->ref_frame_flags & VP9_GOLD_FLAG); - svc->reference_altref[sl] = (uint8_t)(cpi->ref_frame_flags & VP9_ALT_FLAG); -} - -int vp9_one_pass_svc_start_layer(VP9_COMP *const cpi) { - int width = 0, height = 0; - SVC *const svc = &cpi->svc; - LAYER_CONTEXT *lc = NULL; - int scaling_factor_num = 1; - int scaling_factor_den = 1; - svc->skip_enhancement_layer = 0; - - if (svc->disable_inter_layer_pred == INTER_LAYER_PRED_OFF && - svc->number_spatial_layers > 1 && svc->number_spatial_layers <= 3 && - svc->number_temporal_layers <= 3) - svc->simulcast_mode = 1; - else - svc->simulcast_mode = 0; - - if (svc->number_spatial_layers > 1) { - svc->use_base_mv = 1; - svc->use_partition_reuse = 1; - } - svc->force_zero_mode_spatial_ref = 1; - svc->mi_stride[svc->spatial_layer_id] = cpi->common.mi_stride; - svc->mi_rows[svc->spatial_layer_id] = cpi->common.mi_rows; - svc->mi_cols[svc->spatial_layer_id] = cpi->common.mi_cols; - - // For constrained_from_above drop mode: before encoding superframe (i.e., - // at SL0 frame) check all spatial layers (starting from top) for possible - // drop, and if so, set a flag to force drop of that layer and all its lower - // layers. - if (svc->spatial_layer_to_encode == svc->first_spatial_layer_to_encode) { - int sl; - for (sl = 0; sl < svc->number_spatial_layers; sl++) - svc->force_drop_constrained_from_above[sl] = 0; - if (svc->framedrop_mode == CONSTRAINED_FROM_ABOVE_DROP) { - for (sl = svc->number_spatial_layers - 1; - sl >= svc->first_spatial_layer_to_encode; sl--) { - int layer = sl * svc->number_temporal_layers + svc->temporal_layer_id; - LAYER_CONTEXT *const sl_lc = &svc->layer_context[layer]; - cpi->rc = sl_lc->rc; - cpi->oxcf.target_bandwidth = sl_lc->target_bandwidth; - if (vp9_test_drop(cpi)) { - int sl2; - // Set flag to force drop in encoding for this mode. - for (sl2 = sl; sl2 >= svc->first_spatial_layer_to_encode; sl2--) - svc->force_drop_constrained_from_above[sl2] = 1; - break; - } - } - } - } - - if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_0212) { - set_flags_and_fb_idx_for_temporal_mode3(cpi); - } else if (svc->temporal_layering_mode == - VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING) { - set_flags_and_fb_idx_for_temporal_mode_noLayering(cpi); - } else if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_0101) { - set_flags_and_fb_idx_for_temporal_mode2(cpi); - } else if (svc->temporal_layering_mode == - VP9E_TEMPORAL_LAYERING_MODE_BYPASS && - svc->use_set_ref_frame_config) { - set_flags_and_fb_idx_bypass_via_set_ref_frame_config(cpi); - } - - if (cpi->lst_fb_idx == svc->buffer_gf_temporal_ref[0].idx || - cpi->gld_fb_idx == svc->buffer_gf_temporal_ref[0].idx || - cpi->alt_fb_idx == svc->buffer_gf_temporal_ref[0].idx) - svc->buffer_gf_temporal_ref[0].is_used = 1; - if (cpi->lst_fb_idx == svc->buffer_gf_temporal_ref[1].idx || - cpi->gld_fb_idx == svc->buffer_gf_temporal_ref[1].idx || - cpi->alt_fb_idx == svc->buffer_gf_temporal_ref[1].idx) - svc->buffer_gf_temporal_ref[1].is_used = 1; - - // For the fixed (non-flexible/bypass) SVC mode: - // If long term temporal reference is enabled at the sequence level - // (use_gf_temporal_ref == 1), and inter_layer is disabled (on inter-frames), - // we can use golden as a second temporal reference - // (since the spatial/inter-layer reference is disabled). - // We check that the fb_idx for this reference (buffer_gf_temporal_ref.idx) is - // unused (slot 7 and 6 should be available for 3-3 layer system). - // For now usage of this second temporal reference will only be used for - // highest and next to highest spatial layer (i.e., top and middle layer for - // 3 spatial layers). - svc->use_gf_temporal_ref_current_layer = 0; - if (svc->use_gf_temporal_ref && !svc->buffer_gf_temporal_ref[0].is_used && - !svc->buffer_gf_temporal_ref[1].is_used && - svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS && - svc->disable_inter_layer_pred != INTER_LAYER_PRED_ON && - svc->number_spatial_layers <= 3 && svc->number_temporal_layers <= 3 && - svc->spatial_layer_id >= svc->number_spatial_layers - 2) { - // Enable the second (long-term) temporal reference at the frame-level. - svc->use_gf_temporal_ref_current_layer = 1; - } - - // Check if current superframe has any layer sync, only check once on - // base layer. - if (svc->spatial_layer_id == 0) { - int sl = 0; - // Default is no sync. - svc->superframe_has_layer_sync = 0; - for (sl = 0; sl < svc->number_spatial_layers; ++sl) { - if (cpi->svc.spatial_layer_sync[sl]) svc->superframe_has_layer_sync = 1; - } - } - - // Reset the drop flags for all spatial layers, on the - // first_spatial_layer_to_encode. - if (svc->spatial_layer_id == svc->first_spatial_layer_to_encode) { - vp9_zero(svc->drop_spatial_layer); - // TODO(jianj/marpan): Investigate why setting svc->lst/gld/alt_fb_idx - // causes an issue with frame dropping and temporal layers, when the frame - // flags are passed via the encode call (bypass mode). Issue is that we're - // resetting ext_refresh_frame_flags_pending to 0 on frame drops. - if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS) { - memset(&svc->lst_fb_idx, -1, sizeof(svc->lst_fb_idx)); - memset(&svc->gld_fb_idx, -1, sizeof(svc->lst_fb_idx)); - memset(&svc->alt_fb_idx, -1, sizeof(svc->lst_fb_idx)); - // These are set by API before the superframe is encoded and they are - // passed to encoder layer by layer. Don't reset them on layer 0 in bypass - // mode. - vp9_zero(svc->update_buffer_slot); - vp9_zero(svc->reference_last); - vp9_zero(svc->reference_golden); - vp9_zero(svc->reference_altref); - // TODO(jianj): Remove these 3, deprecated. - vp9_zero(svc->update_last); - vp9_zero(svc->update_golden); - vp9_zero(svc->update_altref); - } - } - - lc = &svc->layer_context[svc->spatial_layer_id * svc->number_temporal_layers + - svc->temporal_layer_id]; - - // Setting the worst/best_quality via the encoder control: SET_SVC_PARAMETERS, - // only for non-BYPASS mode for now. - if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS || - svc->use_set_ref_frame_config) { - RATE_CONTROL *const lrc = &lc->rc; - lrc->worst_quality = vp9_quantizer_to_qindex(lc->max_q); - lrc->best_quality = vp9_quantizer_to_qindex(lc->min_q); - if (cpi->fixed_qp_onepass) { - lrc->worst_quality = cpi->rc.worst_quality; - lrc->best_quality = cpi->rc.best_quality; - } - } - - if (cpi->oxcf.resize_mode == RESIZE_DYNAMIC && svc->single_layer_svc == 1 && - svc->spatial_layer_id == svc->first_spatial_layer_to_encode && - cpi->resize_state != ORIG) { - scaling_factor_num = lc->scaling_factor_num_resize; - scaling_factor_den = lc->scaling_factor_den_resize; - } else { - scaling_factor_num = lc->scaling_factor_num; - scaling_factor_den = lc->scaling_factor_den; - } - - get_layer_resolution(cpi->oxcf.width, cpi->oxcf.height, scaling_factor_num, - scaling_factor_den, &width, &height); - - // Use Eightap_smooth for low resolutions. - if (width * height <= 320 * 240) - svc->downsample_filter_type[svc->spatial_layer_id] = EIGHTTAP_SMOOTH; - // For scale factors > 0.75, set the phase to 0 (aligns decimated pixel - // to source pixel). - if (scaling_factor_num > (3 * scaling_factor_den) >> 2) - svc->downsample_filter_phase[svc->spatial_layer_id] = 0; - - // The usage of use_base_mv or partition_reuse assumes down-scale of 2x2. - // For now, turn off use of base motion vectors and partition reuse if the - // spatial scale factors for any layers are not 2, - // keep the case of 3 spatial layers with scale factor of 4x4 for base layer. - // TODO(marpan): Fix this to allow for use_base_mv for scale factors != 2. - if (svc->number_spatial_layers > 1) { - int sl; - for (sl = 0; sl < svc->number_spatial_layers - 1; ++sl) { - lc = &svc->layer_context[sl * svc->number_temporal_layers + - svc->temporal_layer_id]; - if ((lc->scaling_factor_num != lc->scaling_factor_den >> 1) && - !(lc->scaling_factor_num == lc->scaling_factor_den >> 2 && sl == 0 && - svc->number_spatial_layers == 3)) { - svc->use_base_mv = 0; - svc->use_partition_reuse = 0; - break; - } - } - // For non-zero spatial layers: if the previous spatial layer was dropped - // disable the base_mv and partition_reuse features. - if (svc->spatial_layer_id > 0 && - svc->drop_spatial_layer[svc->spatial_layer_id - 1]) { - svc->use_base_mv = 0; - svc->use_partition_reuse = 0; - } - } - - svc->non_reference_frame = 0; - if (cpi->common.frame_type != KEY_FRAME && !cpi->ext_refresh_last_frame && - !cpi->ext_refresh_golden_frame && !cpi->ext_refresh_alt_ref_frame) - svc->non_reference_frame = 1; - // For flexible mode, where update_buffer_slot is used, need to check if - // all buffer slots are not refreshed. - if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) { - if (svc->update_buffer_slot[svc->spatial_layer_id] != 0) - svc->non_reference_frame = 0; - } - - if (svc->spatial_layer_id == 0) { - svc->high_source_sad_superframe = 0; - svc->high_num_blocks_with_motion = 0; - } - - if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS && - svc->last_layer_dropped[svc->spatial_layer_id] && - svc->fb_idx_upd_tl0[svc->spatial_layer_id] != -1 && - !svc->layer_context[svc->temporal_layer_id].is_key_frame) { - // For fixed/non-flexible mode, if the previous frame (same spatial layer - // from previous superframe) was dropped, make sure the lst_fb_idx - // for this frame corresponds to the buffer index updated on (last) encoded - // TL0 frame (with same spatial layer). - cpi->lst_fb_idx = svc->fb_idx_upd_tl0[svc->spatial_layer_id]; - } - - if (vp9_set_size_literal(cpi, width, height) != 0) - return VPX_CODEC_INVALID_PARAM; - - return 0; -} - -struct lookahead_entry *vp9_svc_lookahead_pop(VP9_COMP *const cpi, - struct lookahead_ctx *ctx, - int drain) { - struct lookahead_entry *buf = NULL; - if (ctx->sz && (drain || ctx->sz == ctx->max_sz - MAX_PRE_FRAMES)) { - buf = vp9_lookahead_peek(ctx, 0); - if (buf != NULL) { - // Only remove the buffer when pop the highest layer. - if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) { - vp9_lookahead_pop(ctx, drain); - } - } - } - return buf; -} - -void vp9_free_svc_cyclic_refresh(VP9_COMP *const cpi) { - int sl, tl; - SVC *const svc = &cpi->svc; - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - for (sl = 0; sl < oxcf->ss_number_layers; ++sl) { - for (tl = 0; tl < oxcf->ts_number_layers; ++tl) { - int layer = LAYER_IDS_TO_IDX(sl, tl, oxcf->ts_number_layers); - LAYER_CONTEXT *const lc = &svc->layer_context[layer]; - if (lc->map) vpx_free(lc->map); - if (lc->last_coded_q_map) vpx_free(lc->last_coded_q_map); - if (lc->consec_zero_mv) vpx_free(lc->consec_zero_mv); - } - } -} - -// Reset on key frame: reset counters, references and buffer updates. -void vp9_svc_reset_temporal_layers(VP9_COMP *const cpi, int is_key) { - int sl, tl; - SVC *const svc = &cpi->svc; - LAYER_CONTEXT *lc = NULL; - for (sl = 0; sl < svc->number_spatial_layers; ++sl) { - for (tl = 0; tl < svc->number_temporal_layers; ++tl) { - lc = &cpi->svc.layer_context[sl * svc->number_temporal_layers + tl]; - lc->current_video_frame_in_layer = 0; - if (is_key) lc->frames_from_key_frame = 0; - } - } - if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_0212) { - set_flags_and_fb_idx_for_temporal_mode3(cpi); - } else if (svc->temporal_layering_mode == - VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING) { - set_flags_and_fb_idx_for_temporal_mode_noLayering(cpi); - } else if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_0101) { - set_flags_and_fb_idx_for_temporal_mode2(cpi); - } - vp9_update_temporal_layer_framerate(cpi); - vp9_restore_layer_context(cpi); -} - -void vp9_svc_check_reset_layer_rc_flag(VP9_COMP *const cpi) { - SVC *svc = &cpi->svc; - int sl, tl; - for (sl = 0; sl < svc->number_spatial_layers; ++sl) { - // Check for reset based on avg_frame_bandwidth for spatial layer sl. - const int spatial_layer_idx = LAYER_IDS_TO_IDX( - sl, svc->number_temporal_layers - 1, svc->number_temporal_layers); - LAYER_CONTEXT *lc = &svc->layer_context[spatial_layer_idx]; - RATE_CONTROL *lrc = &lc->rc; - if (lrc->avg_frame_bandwidth / 3 > (lrc->last_avg_frame_bandwidth >> 1) || - lrc->avg_frame_bandwidth < (lrc->last_avg_frame_bandwidth >> 1)) { - // Reset for all temporal layers with spatial layer sl. - for (tl = 0; tl < svc->number_temporal_layers; ++tl) { - int temporal_layer_idx = - LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers); - lrc = &svc->layer_context[temporal_layer_idx].rc; - lrc->rc_1_frame = 0; - lrc->rc_2_frame = 0; - lrc->bits_off_target = lrc->optimal_buffer_level; - lrc->buffer_level = lrc->optimal_buffer_level; - } - } - } -} - -void vp9_svc_constrain_inter_layer_pred(VP9_COMP *const cpi) { - VP9_COMMON *const cm = &cpi->common; - SVC *const svc = &cpi->svc; - const int sl = svc->spatial_layer_id; - // Check for disabling inter-layer (spatial) prediction, if - // svc.disable_inter_layer_pred is set. If the previous spatial layer was - // dropped then disable the prediction from this (scaled) reference. - // For INTER_LAYER_PRED_OFF_NONKEY: inter-layer prediction is disabled - // on key frames or if any spatial layer is a sync layer. - if ((svc->disable_inter_layer_pred == INTER_LAYER_PRED_OFF_NONKEY && - !svc->layer_context[svc->temporal_layer_id].is_key_frame && - !svc->superframe_has_layer_sync) || - svc->disable_inter_layer_pred == INTER_LAYER_PRED_OFF || - svc->drop_spatial_layer[sl - 1]) { - MV_REFERENCE_FRAME ref_frame; - for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { - const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame); - if (yv12 != NULL && - (cpi->ref_frame_flags & ref_frame_to_flag(ref_frame))) { - const struct scale_factors *const scale_fac = - &cm->frame_refs[ref_frame - 1].sf; - if (vp9_is_scaled(scale_fac)) { - cpi->ref_frame_flags &= (~ref_frame_to_flag(ref_frame)); - // Point golden/altref frame buffer index to last. - if (!svc->simulcast_mode) { - if (ref_frame == GOLDEN_FRAME) - cpi->gld_fb_idx = cpi->lst_fb_idx; - else if (ref_frame == ALTREF_FRAME) - cpi->alt_fb_idx = cpi->lst_fb_idx; - } - } - } - } - } - // For fixed/non-flexible SVC: check for disabling inter-layer prediction. - // If the reference for inter-layer prediction (the reference that is scaled) - // is not the previous spatial layer from the same superframe, then we disable - // inter-layer prediction. Only need to check when inter_layer prediction is - // not set to OFF mode. - if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS && - svc->disable_inter_layer_pred != INTER_LAYER_PRED_OFF) { - // We only use LAST and GOLDEN for prediction in real-time mode, so we - // check both here. - MV_REFERENCE_FRAME ref_frame; - for (ref_frame = LAST_FRAME; ref_frame <= GOLDEN_FRAME; ref_frame++) { - struct scale_factors *scale_fac = &cm->frame_refs[ref_frame - 1].sf; - if (vp9_is_scaled(scale_fac)) { - // If this reference was updated on the previous spatial layer of the - // current superframe, then we keep this reference (don't disable). - // Otherwise we disable the inter-layer prediction. - // This condition is verified by checking if the current frame buffer - // index is equal to any of the slots for the previous spatial layer, - // and if so, check if that slot was updated/refreshed. If that is the - // case, then this reference is valid for inter-layer prediction under - // the mode INTER_LAYER_PRED_ON_CONSTRAINED. - int fb_idx = - ref_frame == LAST_FRAME ? cpi->lst_fb_idx : cpi->gld_fb_idx; - int ref_flag = ref_frame == LAST_FRAME ? VP9_LAST_FLAG : VP9_GOLD_FLAG; - int disable = 1; - if (fb_idx < 0) continue; - if ((fb_idx == svc->lst_fb_idx[sl - 1] && - (svc->update_buffer_slot[sl - 1] & (1 << fb_idx))) || - (fb_idx == svc->gld_fb_idx[sl - 1] && - (svc->update_buffer_slot[sl - 1] & (1 << fb_idx))) || - (fb_idx == svc->alt_fb_idx[sl - 1] && - (svc->update_buffer_slot[sl - 1] & (1 << fb_idx)))) - disable = 0; - if (disable) cpi->ref_frame_flags &= (~ref_flag); - } - } - } -} - -void vp9_svc_assert_constraints_pattern(VP9_COMP *const cpi) { - SVC *const svc = &cpi->svc; - // For fixed/non-flexible mode, the following constraint are expected, - // when inter-layer prediction is on (default). - if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS && - svc->disable_inter_layer_pred == INTER_LAYER_PRED_ON && - svc->framedrop_mode != LAYER_DROP) { - if (!svc->layer_context[svc->temporal_layer_id].is_key_frame) { - // On non-key frames: LAST is always temporal reference, GOLDEN is - // spatial reference. - if (svc->temporal_layer_id == 0) - // Base temporal only predicts from base temporal. - assert(svc->fb_idx_temporal_layer_id[cpi->lst_fb_idx] == 0); - else - // Non-base temporal only predicts from lower temporal layer. - assert(svc->fb_idx_temporal_layer_id[cpi->lst_fb_idx] < - svc->temporal_layer_id); - if (svc->spatial_layer_id > 0 && cpi->ref_frame_flags & VP9_GOLD_FLAG && - svc->spatial_layer_id > svc->first_spatial_layer_to_encode) { - // Non-base spatial only predicts from lower spatial layer with same - // temporal_id. - assert(svc->fb_idx_spatial_layer_id[cpi->gld_fb_idx] == - svc->spatial_layer_id - 1); - assert(svc->fb_idx_temporal_layer_id[cpi->gld_fb_idx] == - svc->temporal_layer_id); - } - } else if (svc->spatial_layer_id > 0 && - svc->spatial_layer_id > svc->first_spatial_layer_to_encode) { - // Only 1 reference for frame whose base is key; reference may be LAST - // or GOLDEN, so we check both. - if (cpi->ref_frame_flags & VP9_LAST_FLAG) { - assert(svc->fb_idx_spatial_layer_id[cpi->lst_fb_idx] == - svc->spatial_layer_id - 1); - assert(svc->fb_idx_temporal_layer_id[cpi->lst_fb_idx] == - svc->temporal_layer_id); - } else if (cpi->ref_frame_flags & VP9_GOLD_FLAG) { - assert(svc->fb_idx_spatial_layer_id[cpi->gld_fb_idx] == - svc->spatial_layer_id - 1); - assert(svc->fb_idx_temporal_layer_id[cpi->gld_fb_idx] == - svc->temporal_layer_id); - } - } - } else if (svc->use_gf_temporal_ref_current_layer && - !svc->layer_context[svc->temporal_layer_id].is_key_frame) { - // For the usage of golden as second long term reference: the - // temporal_layer_id of that reference must be base temporal layer 0, and - // spatial_layer_id of that reference must be same as current - // spatial_layer_id. If not, disable feature. - // TODO(marpan): Investigate when this can happen, and maybe put this check - // and reset in a different place. - if (svc->fb_idx_spatial_layer_id[cpi->gld_fb_idx] != - svc->spatial_layer_id || - svc->fb_idx_temporal_layer_id[cpi->gld_fb_idx] != 0) - svc->use_gf_temporal_ref_current_layer = 0; - } -} - -#if CONFIG_VP9_TEMPORAL_DENOISING -int vp9_denoise_svc_non_key(VP9_COMP *const cpi) { - int layer = - LAYER_IDS_TO_IDX(cpi->svc.spatial_layer_id, cpi->svc.temporal_layer_id, - cpi->svc.number_temporal_layers); - LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer]; - return denoise_svc(cpi) && !lc->is_key_frame; -} -#endif - -void vp9_svc_check_spatial_layer_sync(VP9_COMP *const cpi) { - SVC *const svc = &cpi->svc; - // Only for superframes whose base is not key, as those are - // already sync frames. - if (!svc->layer_context[svc->temporal_layer_id].is_key_frame) { - if (svc->spatial_layer_id == 0) { - // On base spatial layer: if the current superframe has a layer sync then - // reset the pattern counters and reset to base temporal layer. - if (svc->superframe_has_layer_sync) - vp9_svc_reset_temporal_layers(cpi, cpi->common.frame_type == KEY_FRAME); - } - // If the layer sync is set for this current spatial layer then - // disable the temporal reference. - if (svc->spatial_layer_id > 0 && - svc->spatial_layer_sync[svc->spatial_layer_id]) { - cpi->ref_frame_flags &= (~VP9_LAST_FLAG); - if (svc->use_gf_temporal_ref_current_layer) { - int index = svc->spatial_layer_id; - // If golden is used as second reference: need to remove it from - // prediction, reset refresh period to 0, and update the reference. - svc->use_gf_temporal_ref_current_layer = 0; - cpi->rc.baseline_gf_interval = 0; - cpi->rc.frames_till_gf_update_due = 0; - // On layer sync frame we must update the buffer index used for long - // term reference. Use the alt_ref since it is not used or updated on - // sync frames. - if (svc->number_spatial_layers == 3) index = svc->spatial_layer_id - 1; - assert(index >= 0); - cpi->alt_fb_idx = svc->buffer_gf_temporal_ref[index].idx; - cpi->ext_refresh_alt_ref_frame = 1; - } - } - } -} - -void vp9_svc_update_ref_frame_buffer_idx(VP9_COMP *const cpi) { - SVC *const svc = &cpi->svc; - int i = 0; - // Update the usage of frame buffer index for base spatial layers. - if (svc->spatial_layer_id == 0) { - if ((cpi->ref_frame_flags & VP9_LAST_FLAG) || cpi->refresh_last_frame) - svc->fb_idx_base[cpi->lst_fb_idx] = 1; - if ((cpi->ref_frame_flags & VP9_GOLD_FLAG) || cpi->refresh_golden_frame) - svc->fb_idx_base[cpi->gld_fb_idx] = 1; - if ((cpi->ref_frame_flags & VP9_ALT_FLAG) || cpi->refresh_alt_ref_frame) - svc->fb_idx_base[cpi->alt_fb_idx] = 1; - // For bypass/flexible mode: check for refresh slots. - if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) { - for (i = 0; i < REF_FRAMES; ++i) - if (svc->update_buffer_slot[0] & (1 << i)) svc->fb_idx_base[i] = 1; - } - } -} - -static void vp9_svc_update_ref_frame_bypass_mode(VP9_COMP *const cpi) { - // For non-flexible/bypass SVC mode: check for refreshing other buffer - // slots. - SVC *const svc = &cpi->svc; - VP9_COMMON *const cm = &cpi->common; - BufferPool *const pool = cm->buffer_pool; - int i; - for (i = 0; i < REF_FRAMES; i++) { - if ((cm->frame_type == KEY_FRAME && !svc->simulcast_mode) || - svc->update_buffer_slot[svc->spatial_layer_id] & (1 << i)) { - ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[i], cm->new_fb_idx); - svc->fb_idx_spatial_layer_id[i] = svc->spatial_layer_id; - svc->fb_idx_temporal_layer_id[i] = svc->temporal_layer_id; - } - } -} - -void vp9_svc_update_ref_frame(VP9_COMP *const cpi) { - VP9_COMMON *const cm = &cpi->common; - SVC *const svc = &cpi->svc; - BufferPool *const pool = cm->buffer_pool; - - if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS && - svc->use_set_ref_frame_config) { - vp9_svc_update_ref_frame_bypass_mode(cpi); - } else if (cm->frame_type == KEY_FRAME && !svc->simulcast_mode) { - // Keep track of frame index for each reference frame. - int i; - // On key frame update all reference frame slots. - for (i = 0; i < REF_FRAMES; i++) { - svc->fb_idx_spatial_layer_id[i] = svc->spatial_layer_id; - svc->fb_idx_temporal_layer_id[i] = svc->temporal_layer_id; - // LAST/GOLDEN/ALTREF is already updated above. - if (i != cpi->lst_fb_idx && i != cpi->gld_fb_idx && i != cpi->alt_fb_idx) - ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[i], cm->new_fb_idx); - } - } else { - if (cpi->refresh_last_frame) { - svc->fb_idx_spatial_layer_id[cpi->lst_fb_idx] = svc->spatial_layer_id; - svc->fb_idx_temporal_layer_id[cpi->lst_fb_idx] = svc->temporal_layer_id; - } - if (cpi->refresh_golden_frame) { - svc->fb_idx_spatial_layer_id[cpi->gld_fb_idx] = svc->spatial_layer_id; - svc->fb_idx_temporal_layer_id[cpi->gld_fb_idx] = svc->temporal_layer_id; - } - if (cpi->refresh_alt_ref_frame) { - svc->fb_idx_spatial_layer_id[cpi->alt_fb_idx] = svc->spatial_layer_id; - svc->fb_idx_temporal_layer_id[cpi->alt_fb_idx] = svc->temporal_layer_id; - } - } - // Copy flags from encoder to SVC struct. - vp9_copy_flags_ref_update_idx(cpi); - vp9_svc_update_ref_frame_buffer_idx(cpi); -} - -void vp9_svc_adjust_frame_rate(VP9_COMP *const cpi) { - int64_t this_duration = - cpi->svc.timebase_fac * cpi->svc.duration[cpi->svc.spatial_layer_id]; - vp9_new_framerate(cpi, 10000000.0 / this_duration); -} - -void vp9_svc_adjust_avg_frame_qindex(VP9_COMP *const cpi) { - VP9_COMMON *const cm = &cpi->common; - SVC *const svc = &cpi->svc; - RATE_CONTROL *const rc = &cpi->rc; - // On key frames in CBR mode: reset the avg_frame_qindex for base layer - // (to level closer to worst_quality) if the overshoot is significant. - // Reset it for all temporal layers on base spatial layer. - if (cm->frame_type == KEY_FRAME && cpi->oxcf.rc_mode == VPX_CBR && - !svc->simulcast_mode && - rc->projected_frame_size / 3 > rc->avg_frame_bandwidth) { - int tl; - rc->avg_frame_qindex[INTER_FRAME] = - VPXMAX(rc->avg_frame_qindex[INTER_FRAME], - (cm->base_qindex + rc->worst_quality) >> 1); - for (tl = 0; tl < svc->number_temporal_layers; ++tl) { - const int layer = LAYER_IDS_TO_IDX(0, tl, svc->number_temporal_layers); - LAYER_CONTEXT *lc = &svc->layer_context[layer]; - RATE_CONTROL *lrc = &lc->rc; - lrc->avg_frame_qindex[INTER_FRAME] = rc->avg_frame_qindex[INTER_FRAME]; - } - } -} - -// SVC: skip encoding of enhancement layer if the layer target bandwidth = 0. -// No need to set svc.skip_enhancement_layer if whole superframe will be -// dropped. -int vp9_svc_check_skip_enhancement_layer(VP9_COMP *const cpi) { - if (cpi->use_svc && cpi->svc.spatial_layer_id > 0 && - cpi->oxcf.target_bandwidth == 0 && - !(cpi->svc.framedrop_mode != LAYER_DROP && - (cpi->svc.framedrop_mode != CONSTRAINED_FROM_ABOVE_DROP || - cpi->svc - .force_drop_constrained_from_above[cpi->svc.number_spatial_layers - - 1]) && - cpi->svc.drop_spatial_layer[0])) { - cpi->svc.skip_enhancement_layer = 1; - vp9_rc_postencode_update_drop_frame(cpi); - cpi->ext_refresh_frame_flags_pending = 0; - cpi->last_frame_dropped = 1; - cpi->svc.last_layer_dropped[cpi->svc.spatial_layer_id] = 1; - cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id] = 1; - vp9_inc_frame_in_layer(cpi); - return 1; - } - return 0; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_svc_layercontext.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_svc_layercontext.h deleted file mode 100644 index 388a0278..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_svc_layercontext.h +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_SVC_LAYERCONTEXT_H_ -#define VPX_VP9_ENCODER_VP9_SVC_LAYERCONTEXT_H_ - -#include "vpx/vpx_encoder.h" - -#include "vp9/encoder/vp9_ratectrl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - // Inter-layer prediction is on on all frames. - INTER_LAYER_PRED_ON, - // Inter-layer prediction is off on all frames. - INTER_LAYER_PRED_OFF, - // Inter-layer prediction is off on non-key frames and non-sync frames. - INTER_LAYER_PRED_OFF_NONKEY, - // Inter-layer prediction is on on all frames, but constrained such - // that any layer S (> 0) can only predict from previous spatial - // layer S-1, from the same superframe. - INTER_LAYER_PRED_ON_CONSTRAINED -} INTER_LAYER_PRED; - -typedef struct BUFFER_LONGTERM_REF { - int idx; - int is_used; -} BUFFER_LONGTERM_REF; - -typedef struct { - RATE_CONTROL rc; - int target_bandwidth; - int spatial_layer_target_bandwidth; // Target for the spatial layer. - double framerate; - int avg_frame_size; - int max_q; - int min_q; - int scaling_factor_num; - int scaling_factor_den; - // Scaling factors used for internal resize scaling for single layer SVC. - int scaling_factor_num_resize; - int scaling_factor_den_resize; - TWO_PASS twopass; - vpx_fixed_buf_t rc_twopass_stats_in; - unsigned int current_video_frame_in_layer; - int is_key_frame; - int frames_from_key_frame; - FRAME_TYPE last_frame_type; - struct lookahead_entry *alt_ref_source; - int alt_ref_idx; - int gold_ref_idx; - int has_alt_frame; - size_t layer_size; - // Cyclic refresh parameters (aq-mode=3), that need to be updated per-frame. - // TODO(jianj/marpan): Is it better to use the full cyclic refresh struct. - int sb_index; - signed char *map; - uint8_t *last_coded_q_map; - uint8_t *consec_zero_mv; - int actual_num_seg1_blocks; - int actual_num_seg2_blocks; - int counter_encode_maxq_scene_change; - int qindex_delta[3]; - uint8_t speed; - int loopfilter_ctrl; - int frame_qp; - int MBs; -} LAYER_CONTEXT; - -typedef struct SVC { - int spatial_layer_id; - int temporal_layer_id; - int number_spatial_layers; - int number_temporal_layers; - - int spatial_layer_to_encode; - - // Workaround for multiple frame contexts - enum { ENCODED = 0, ENCODING, NEED_TO_ENCODE } encode_empty_frame_state; - struct lookahead_entry empty_frame; - int encode_intra_empty_frame; - - // Store scaled source frames to be used for temporal filter to generate - // a alt ref frame. - YV12_BUFFER_CONFIG scaled_frames[MAX_LAG_BUFFERS]; - // Temp buffer used for 2-stage down-sampling, for real-time mode. - YV12_BUFFER_CONFIG scaled_temp; - int scaled_one_half; - int scaled_temp_is_alloc; - - // Layer context used for rate control in one pass temporal CBR mode or - // two pass spatial mode. - LAYER_CONTEXT layer_context[VPX_MAX_LAYERS]; - // Indicates what sort of temporal layering is used. - // Currently, this only works for CBR mode. - VP9E_TEMPORAL_LAYERING_MODE temporal_layering_mode; - // Frame flags and buffer indexes for each spatial layer, set by the - // application (external settings). - int ext_frame_flags[VPX_MAX_LAYERS]; - int lst_fb_idx[VPX_MAX_LAYERS]; - int gld_fb_idx[VPX_MAX_LAYERS]; - int alt_fb_idx[VPX_MAX_LAYERS]; - int force_zero_mode_spatial_ref; - // Sequence level flag to enable second (long term) temporal reference. - int use_gf_temporal_ref; - // Frame level flag to enable second (long term) temporal reference. - int use_gf_temporal_ref_current_layer; - // Allow second reference for at most 2 top highest resolution layers. - BUFFER_LONGTERM_REF buffer_gf_temporal_ref[2]; - int current_superframe; - int non_reference_frame; - int use_base_mv; - int use_partition_reuse; - // Used to control the downscaling filter for source scaling, for 1 pass CBR. - // downsample_filter_phase: = 0 will do sub-sampling (no weighted average), - // = 8 will center the target pixel and get a symmetric averaging filter. - // downsample_filter_type: 4 filters may be used: eighttap_regular, - // eighttap_smooth, eighttap_sharp, and bilinear. - INTERP_FILTER downsample_filter_type[VPX_SS_MAX_LAYERS]; - int downsample_filter_phase[VPX_SS_MAX_LAYERS]; - - BLOCK_SIZE *prev_partition_svc; - int mi_stride[VPX_MAX_LAYERS]; - int mi_rows[VPX_MAX_LAYERS]; - int mi_cols[VPX_MAX_LAYERS]; - - int first_layer_denoise; - - int skip_enhancement_layer; - - int lower_layer_qindex; - - int last_layer_dropped[VPX_MAX_LAYERS]; - int drop_spatial_layer[VPX_MAX_LAYERS]; - int framedrop_thresh[VPX_MAX_LAYERS]; - int drop_count[VPX_MAX_LAYERS]; - int force_drop_constrained_from_above[VPX_MAX_LAYERS]; - int max_consec_drop; - SVC_LAYER_DROP_MODE framedrop_mode; - - INTER_LAYER_PRED disable_inter_layer_pred; - - // Flag to indicate scene change and high num of motion blocks at current - // superframe, scene detection is currently checked for each superframe prior - // to encoding, on the full resolution source. - int high_source_sad_superframe; - int high_num_blocks_with_motion; - - // Flags used to get SVC pattern info. - int update_buffer_slot[VPX_SS_MAX_LAYERS]; - uint8_t reference_last[VPX_SS_MAX_LAYERS]; - uint8_t reference_golden[VPX_SS_MAX_LAYERS]; - uint8_t reference_altref[VPX_SS_MAX_LAYERS]; - // TODO(jianj): Remove these last 3, deprecated. - uint8_t update_last[VPX_SS_MAX_LAYERS]; - uint8_t update_golden[VPX_SS_MAX_LAYERS]; - uint8_t update_altref[VPX_SS_MAX_LAYERS]; - - // Keep track of the frame buffer index updated/refreshed on the base - // temporal superframe. - int fb_idx_upd_tl0[VPX_SS_MAX_LAYERS]; - - // Keep track of the spatial and temporal layer id of the frame that last - // updated the frame buffer index. - uint8_t fb_idx_spatial_layer_id[REF_FRAMES]; - uint8_t fb_idx_temporal_layer_id[REF_FRAMES]; - - int spatial_layer_sync[VPX_SS_MAX_LAYERS]; - // Quantizer for each spatial layer. - int base_qindex[VPX_SS_MAX_LAYERS]; - uint8_t set_intra_only_frame; - uint8_t previous_frame_is_intra_only; - uint8_t superframe_has_layer_sync; - - uint8_t fb_idx_base[REF_FRAMES]; - - int use_set_ref_frame_config; - - int temporal_layer_id_per_spatial[VPX_SS_MAX_LAYERS]; - - int first_spatial_layer_to_encode; - - // Parameters for allowing framerate per spatial layer, and buffer - // update based on timestamps. - int64_t duration[VPX_SS_MAX_LAYERS]; - int64_t timebase_fac; - int64_t time_stamp_superframe; - int64_t time_stamp_prev[VPX_SS_MAX_LAYERS]; - - int num_encoded_top_layer; - - // Every spatial layer on a superframe whose base is key is key too. - int simulcast_mode; - - // Flag to indicate SVC is dynamically switched to a single layer. - int single_layer_svc; - int resize_set; -} SVC; - -struct VP9_COMP; - -// Initialize layer context data from init_config(). -void vp9_init_layer_context(struct VP9_COMP *const cpi); - -// Update the layer context from a change_config() call. -void vp9_update_layer_context_change_config(struct VP9_COMP *const cpi, - const int target_bandwidth); - -// Prior to encoding the frame, update framerate-related quantities -// for the current temporal layer. -void vp9_update_temporal_layer_framerate(struct VP9_COMP *const cpi); - -// Update framerate-related quantities for the current spatial layer. -void vp9_update_spatial_layer_framerate(struct VP9_COMP *const cpi, - double framerate); - -// Prior to encoding the frame, set the layer context, for the current layer -// to be encoded, to the cpi struct. -void vp9_restore_layer_context(struct VP9_COMP *const cpi); - -// Save the layer context after encoding the frame. -void vp9_save_layer_context(struct VP9_COMP *const cpi); - -// Initialize second pass rc for spatial svc. -void vp9_init_second_pass_spatial_svc(struct VP9_COMP *cpi); - -void get_layer_resolution(const int width_org, const int height_org, - const int num, const int den, int *width_out, - int *height_out); - -// Increment number of video frames in layer -void vp9_inc_frame_in_layer(struct VP9_COMP *const cpi); - -// Check if current layer is key frame in spatial upper layer -int vp9_is_upper_layer_key_frame(const struct VP9_COMP *const cpi); - -// Get the next source buffer to encode -struct lookahead_entry *vp9_svc_lookahead_pop(struct VP9_COMP *const cpi, - struct lookahead_ctx *ctx, - int drain); - -// Start a frame and initialize svc parameters -int vp9_svc_start_frame(struct VP9_COMP *const cpi); - -#if CONFIG_VP9_TEMPORAL_DENOISING -int vp9_denoise_svc_non_key(struct VP9_COMP *const cpi); -#endif - -void vp9_copy_flags_ref_update_idx(struct VP9_COMP *const cpi); - -int vp9_one_pass_svc_start_layer(struct VP9_COMP *const cpi); - -void vp9_free_svc_cyclic_refresh(struct VP9_COMP *const cpi); - -void vp9_svc_reset_temporal_layers(struct VP9_COMP *const cpi, int is_key); - -void vp9_svc_check_reset_layer_rc_flag(struct VP9_COMP *const cpi); - -void vp9_svc_constrain_inter_layer_pred(struct VP9_COMP *const cpi); - -void vp9_svc_assert_constraints_pattern(struct VP9_COMP *const cpi); - -void vp9_svc_check_spatial_layer_sync(struct VP9_COMP *const cpi); - -void vp9_svc_update_ref_frame_buffer_idx(struct VP9_COMP *const cpi); - -void vp9_svc_update_ref_frame_key_simulcast(struct VP9_COMP *const cpi); - -void vp9_svc_update_ref_frame(struct VP9_COMP *const cpi); - -void vp9_svc_adjust_frame_rate(struct VP9_COMP *const cpi); - -void vp9_svc_adjust_avg_frame_qindex(struct VP9_COMP *const cpi); - -int vp9_svc_check_skip_enhancement_layer(struct VP9_COMP *const cpi); -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_SVC_LAYERCONTEXT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_temporal_filter.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_temporal_filter.c deleted file mode 100644 index 2d696f40..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_temporal_filter.c +++ /dev/null @@ -1,1417 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "vp9/common/vp9_alloccommon.h" -#include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_onyxc_int.h" -#include "vp9/common/vp9_quant_common.h" -#include "vp9/common/vp9_reconinter.h" -#include "vp9/encoder/vp9_encodeframe.h" -#include "vp9/encoder/vp9_ethread.h" -#include "vp9/encoder/vp9_extend.h" -#include "vp9/encoder/vp9_firstpass.h" -#include "vp9/encoder/vp9_mcomp.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_quantize.h" -#include "vp9/encoder/vp9_ratectrl.h" -#include "vp9/encoder/vp9_segmentation.h" -#include "vp9/encoder/vp9_temporal_filter.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/vpx_timer.h" -#include "vpx_scale/vpx_scale.h" - -static int fixed_divide[512]; -static unsigned int index_mult[14] = { 0, 0, 0, 0, 49152, - 39322, 32768, 28087, 24576, 21846, - 19661, 17874, 0, 15124 }; -#if CONFIG_VP9_HIGHBITDEPTH -static int64_t highbd_index_mult[14] = { 0U, 0U, 0U, - 0U, 3221225472U, 2576980378U, - 2147483648U, 1840700270U, 1610612736U, - 1431655766U, 1288490189U, 1171354718U, - 0U, 991146300U }; -#endif // CONFIG_VP9_HIGHBITDEPTH - -// Prediction function using 12-tap interpolation filter. -// TODO(yunqingwang@google.com): add SIMD optimization. -#define MAX_FILTER_TAP 12 -#define TF_INTERP_EXTEND 6 -typedef int16_t InterpKernel12[MAX_FILTER_TAP]; -// 12-tap filter (used by the encoder only). -DECLARE_ALIGNED(256, static const InterpKernel12, - sub_pel_filters_12[SUBPEL_SHIFTS]) = { - { 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0 }, - { 0, 1, -2, 3, -7, 127, 8, -4, 2, -1, 1, 0 }, - { -1, 2, -3, 6, -13, 124, 18, -8, 4, -2, 2, -1 }, - { -1, 3, -4, 8, -18, 120, 28, -12, 7, -4, 2, -1 }, - { -1, 3, -6, 10, -21, 115, 38, -15, 8, -5, 3, -1 }, - { -2, 4, -6, 12, -24, 108, 49, -18, 10, -6, 3, -2 }, - { -2, 4, -7, 13, -25, 100, 60, -21, 11, -7, 4, -2 }, - { -2, 4, -7, 13, -26, 91, 71, -24, 13, -7, 4, -2 }, - { -2, 4, -7, 13, -25, 81, 81, -25, 13, -7, 4, -2 }, - { -2, 4, -7, 13, -24, 71, 91, -26, 13, -7, 4, -2 }, - { -2, 4, -7, 11, -21, 60, 100, -25, 13, -7, 4, -2 }, - { -2, 3, -6, 10, -18, 49, 108, -24, 12, -6, 4, -2 }, - { -1, 3, -5, 8, -15, 38, 115, -21, 10, -6, 3, -1 }, - { -1, 2, -4, 7, -12, 28, 120, -18, 8, -4, 3, -1 }, - { -1, 2, -2, 4, -8, 18, 124, -13, 6, -3, 2, -1 }, - { 0, 1, -1, 2, -4, 8, 127, -7, 3, -2, 1, 0 } -}; - -static void convolve_horiz_12(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel12 *x_filters, int x0_q4, - int x_step_q4, int w, int h) { - int x, y; - src -= MAX_FILTER_TAP / 2 - 1; - - for (y = 0; y < h; ++y) { - int x_q4 = x0_q4; - for (x = 0; x < w; ++x) { - const uint8_t *const src_x = &src[x_q4 >> SUBPEL_BITS]; - const int16_t *const x_filter = x_filters[x_q4 & SUBPEL_MASK]; - int k, sum = 0; - for (k = 0; k < MAX_FILTER_TAP; ++k) sum += src_x[k] * x_filter[k]; - dst[x] = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)); - x_q4 += x_step_q4; - } - src += src_stride; - dst += dst_stride; - } -} - -static void convolve_vert_12(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel12 *y_filters, int y0_q4, - int y_step_q4, int w, int h) { - int x, y; - src -= src_stride * (MAX_FILTER_TAP / 2 - 1); - - for (x = 0; x < w; ++x) { - int y_q4 = y0_q4; - for (y = 0; y < h; ++y) { - const uint8_t *src_y = &src[(y_q4 >> SUBPEL_BITS) * src_stride]; - const int16_t *const y_filter = y_filters[y_q4 & SUBPEL_MASK]; - int k, sum = 0; - for (k = 0; k < MAX_FILTER_TAP; ++k) - sum += src_y[k * src_stride] * y_filter[k]; - dst[y * dst_stride] = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)); - y_q4 += y_step_q4; - } - ++src; - ++dst; - } -} - -// Copied from vpx_convolve8_c(). Possible block sizes are 32x32, 16x16, 8x8. -static void vpx_convolve8_12_c(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel12 *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - uint8_t temp[BW * (BH + MAX_FILTER_TAP - 1)]; - const int temp_stride = BW; - const int intermediate_height = - (((h - 1) * y_step_q4 + y0_q4) >> SUBPEL_BITS) + MAX_FILTER_TAP; - - convolve_horiz_12(src - src_stride * (MAX_FILTER_TAP / 2 - 1), src_stride, - temp, temp_stride, filter, x0_q4, x_step_q4, w, - intermediate_height); - convolve_vert_12(temp + temp_stride * (MAX_FILTER_TAP / 2 - 1), temp_stride, - dst, dst_stride, filter, y0_q4, y_step_q4, w, h); -} - -static void vp9_build_inter_predictor_12( - const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, - const MV *src_mv, const struct scale_factors *sf, int w, int h, int ref, - const InterpKernel12 *kernel, enum mv_precision precision, int x, int y) { - (void)ref; - const int is_q4 = precision == MV_PRECISION_Q4; - const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2, - is_q4 ? src_mv->col : src_mv->col * 2 }; - MV32 mv = vp9_scale_mv(&mv_q4, x, y, sf); - const int subpel_x = mv.col & SUBPEL_MASK; - const int subpel_y = mv.row & SUBPEL_MASK; - - src += (mv.row >> SUBPEL_BITS) * src_stride + (mv.col >> SUBPEL_BITS); - - vpx_convolve8_12_c(src, src_stride, dst, dst_stride, kernel, subpel_x, - sf->x_step_q4, subpel_y, sf->y_step_q4, w, h); -} - -#if CONFIG_VP9_HIGHBITDEPTH -static void highbd_convolve_horiz_12(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel12 *x_filters, int x0_q4, - int x_step_q4, int w, int h, int bd) { - int x, y; - src -= MAX_FILTER_TAP / 2 - 1; - - for (y = 0; y < h; ++y) { - int x_q4 = x0_q4; - for (x = 0; x < w; ++x) { - const uint16_t *const src_x = &src[x_q4 >> SUBPEL_BITS]; - const int16_t *const x_filter = x_filters[x_q4 & SUBPEL_MASK]; - int k, sum = 0; - for (k = 0; k < MAX_FILTER_TAP; ++k) sum += src_x[k] * x_filter[k]; - dst[x] = clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd); - x_q4 += x_step_q4; - } - src += src_stride; - dst += dst_stride; - } -} - -static void highbd_convolve_vert_12(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel12 *y_filters, int y0_q4, - int y_step_q4, int w, int h, int bd) { - int x, y; - src -= src_stride * (MAX_FILTER_TAP / 2 - 1); - - for (x = 0; x < w; ++x) { - int y_q4 = y0_q4; - for (y = 0; y < h; ++y) { - const uint16_t *src_y = &src[(y_q4 >> SUBPEL_BITS) * src_stride]; - const int16_t *const y_filter = y_filters[y_q4 & SUBPEL_MASK]; - int k, sum = 0; - for (k = 0; k < MAX_FILTER_TAP; ++k) - sum += src_y[k * src_stride] * y_filter[k]; - dst[y * dst_stride] = - clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd); - y_q4 += y_step_q4; - } - ++src; - ++dst; - } -} - -static void highbd_convolve_12(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel12 *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h, int bd) { - uint16_t temp[BW * (BH + MAX_FILTER_TAP - 1)]; - const int temp_stride = BW; - const int intermediate_height = - (((h - 1) * y_step_q4 + y0_q4) >> SUBPEL_BITS) + MAX_FILTER_TAP; - - highbd_convolve_horiz_12(src - src_stride * (MAX_FILTER_TAP / 2 - 1), - src_stride, temp, temp_stride, filter, x0_q4, - x_step_q4, w, intermediate_height, bd); - highbd_convolve_vert_12(temp + temp_stride * (MAX_FILTER_TAP / 2 - 1), - temp_stride, dst, dst_stride, filter, y0_q4, - y_step_q4, w, h, bd); -} - -// Copied from vpx_highbd_convolve8_c() -static void vpx_highbd_convolve8_12_c(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel12 *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd) { - highbd_convolve_12(src, src_stride, dst, dst_stride, filter, x0_q4, x_step_q4, - y0_q4, y_step_q4, w, h, bd); -} - -static void vp9_highbd_build_inter_predictor_12( - const uint16_t *src, int src_stride, uint16_t *dst, int dst_stride, - const MV *src_mv, const struct scale_factors *sf, int w, int h, int ref, - const InterpKernel12 *kernel, enum mv_precision precision, int x, int y, - int bd) { - (void)ref; - const int is_q4 = precision == MV_PRECISION_Q4; - const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2, - is_q4 ? src_mv->col : src_mv->col * 2 }; - MV32 mv = vp9_scale_mv(&mv_q4, x, y, sf); - const int subpel_x = mv.col & SUBPEL_MASK; - const int subpel_y = mv.row & SUBPEL_MASK; - - src += (mv.row >> SUBPEL_BITS) * src_stride + (mv.col >> SUBPEL_BITS); - - vpx_highbd_convolve8_12_c(src, src_stride, dst, dst_stride, kernel, subpel_x, - sf->x_step_q4, subpel_y, sf->y_step_q4, w, h, bd); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static void temporal_filter_predictors_mb_c( - MACROBLOCKD *xd, uint8_t *y_mb_ptr, uint8_t *u_mb_ptr, uint8_t *v_mb_ptr, - int stride, int uv_block_width, int uv_block_height, int mv_row, int mv_col, - uint8_t *pred, struct scale_factors *scale, int x, int y, MV *blk_mvs, - int use_32x32) { - const int which_mv = 0; - const InterpKernel12 *const kernel = sub_pel_filters_12; - int i, j, k = 0, ys = (BH >> 1), xs = (BW >> 1); - - enum mv_precision mv_precision_uv; - int uv_stride; - if (uv_block_width == (BW >> 1)) { - uv_stride = (stride + 1) >> 1; - mv_precision_uv = MV_PRECISION_Q4; - } else { - uv_stride = stride; - mv_precision_uv = MV_PRECISION_Q3; - } -#if !CONFIG_VP9_HIGHBITDEPTH - (void)xd; -#endif - - if (use_32x32) { - const MV mv = { mv_row, mv_col }; -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - vp9_highbd_build_inter_predictor_12(CONVERT_TO_SHORTPTR(y_mb_ptr), stride, - CONVERT_TO_SHORTPTR(&pred[0]), BW, - &mv, scale, BW, BH, which_mv, kernel, - MV_PRECISION_Q3, x, y, xd->bd); - - vp9_highbd_build_inter_predictor_12( - CONVERT_TO_SHORTPTR(u_mb_ptr), uv_stride, - CONVERT_TO_SHORTPTR(&pred[BLK_PELS]), uv_block_width, &mv, scale, - uv_block_width, uv_block_height, which_mv, kernel, mv_precision_uv, x, - y, xd->bd); - - vp9_highbd_build_inter_predictor_12( - CONVERT_TO_SHORTPTR(v_mb_ptr), uv_stride, - CONVERT_TO_SHORTPTR(&pred[(BLK_PELS << 1)]), uv_block_width, &mv, - scale, uv_block_width, uv_block_height, which_mv, kernel, - mv_precision_uv, x, y, xd->bd); - return; - } -#endif // CONFIG_VP9_HIGHBITDEPTH - vp9_build_inter_predictor_12(y_mb_ptr, stride, &pred[0], BW, &mv, scale, BW, - BH, which_mv, kernel, MV_PRECISION_Q3, x, y); - - vp9_build_inter_predictor_12(u_mb_ptr, uv_stride, &pred[BLK_PELS], - uv_block_width, &mv, scale, uv_block_width, - uv_block_height, which_mv, kernel, - mv_precision_uv, x, y); - - vp9_build_inter_predictor_12(v_mb_ptr, uv_stride, &pred[(BLK_PELS << 1)], - uv_block_width, &mv, scale, uv_block_width, - uv_block_height, which_mv, kernel, - mv_precision_uv, x, y); - return; - } - - // While use_32x32 = 0, construct the 32x32 predictor using 4 16x16 - // predictors. - // Y predictor - for (i = 0; i < BH; i += ys) { - for (j = 0; j < BW; j += xs) { - const MV mv = blk_mvs[k]; - const int y_offset = i * stride + j; - const int p_offset = i * BW + j; - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - vp9_highbd_build_inter_predictor_12( - CONVERT_TO_SHORTPTR(y_mb_ptr + y_offset), stride, - CONVERT_TO_SHORTPTR(&pred[p_offset]), BW, &mv, scale, xs, ys, - which_mv, kernel, MV_PRECISION_Q3, x, y, xd->bd); - } else { - vp9_build_inter_predictor_12(y_mb_ptr + y_offset, stride, - &pred[p_offset], BW, &mv, scale, xs, ys, - which_mv, kernel, MV_PRECISION_Q3, x, y); - } -#else - vp9_build_inter_predictor_12(y_mb_ptr + y_offset, stride, &pred[p_offset], - BW, &mv, scale, xs, ys, which_mv, kernel, - MV_PRECISION_Q3, x, y); -#endif // CONFIG_VP9_HIGHBITDEPTH - k++; - } - } - - // U and V predictors - ys = (uv_block_height >> 1); - xs = (uv_block_width >> 1); - k = 0; - - for (i = 0; i < uv_block_height; i += ys) { - for (j = 0; j < uv_block_width; j += xs) { - const MV mv = blk_mvs[k]; - const int uv_offset = i * uv_stride + j; - const int p_offset = i * uv_block_width + j; - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - vp9_highbd_build_inter_predictor_12( - CONVERT_TO_SHORTPTR(u_mb_ptr + uv_offset), uv_stride, - CONVERT_TO_SHORTPTR(&pred[BLK_PELS + p_offset]), uv_block_width, - &mv, scale, xs, ys, which_mv, kernel, mv_precision_uv, x, y, - xd->bd); - - vp9_highbd_build_inter_predictor_12( - CONVERT_TO_SHORTPTR(v_mb_ptr + uv_offset), uv_stride, - CONVERT_TO_SHORTPTR(&pred[(BLK_PELS << 1) + p_offset]), - uv_block_width, &mv, scale, xs, ys, which_mv, kernel, - mv_precision_uv, x, y, xd->bd); - } else { - vp9_build_inter_predictor_12(u_mb_ptr + uv_offset, uv_stride, - &pred[BLK_PELS + p_offset], uv_block_width, - &mv, scale, xs, ys, which_mv, kernel, - mv_precision_uv, x, y); - - vp9_build_inter_predictor_12(v_mb_ptr + uv_offset, uv_stride, - &pred[(BLK_PELS << 1) + p_offset], - uv_block_width, &mv, scale, xs, ys, - which_mv, kernel, mv_precision_uv, x, y); - } -#else - vp9_build_inter_predictor_12(u_mb_ptr + uv_offset, uv_stride, - &pred[BLK_PELS + p_offset], uv_block_width, - &mv, scale, xs, ys, which_mv, kernel, - mv_precision_uv, x, y); - - vp9_build_inter_predictor_12(v_mb_ptr + uv_offset, uv_stride, - &pred[(BLK_PELS << 1) + p_offset], - uv_block_width, &mv, scale, xs, ys, which_mv, - kernel, mv_precision_uv, x, y); -#endif // CONFIG_VP9_HIGHBITDEPTH - k++; - } - } -} - -void vp9_temporal_filter_init(void) { - int i; - - fixed_divide[0] = 0; - for (i = 1; i < 512; ++i) fixed_divide[i] = 0x80000 / i; -} - -static INLINE int mod_index(int sum_dist, int index, int rounding, int strength, - int filter_weight) { - int mod; - - assert(index >= 0 && index <= 13); - assert(index_mult[index] != 0); - - mod = - ((unsigned int)clamp(sum_dist, 0, UINT16_MAX) * index_mult[index]) >> 16; - mod += rounding; - mod >>= strength; - - mod = VPXMIN(16, mod); - - mod = 16 - mod; - mod *= filter_weight; - - return mod; -} - -#if CONFIG_VP9_HIGHBITDEPTH -static INLINE int highbd_mod_index(int sum_dist, int index, int rounding, - int strength, int filter_weight) { - int mod; - - assert(index >= 0 && index <= 13); - assert(highbd_index_mult[index] != 0); - - mod = (int)((clamp(sum_dist, 0, INT32_MAX) * highbd_index_mult[index]) >> 32); - mod += rounding; - mod >>= strength; - - mod = VPXMIN(16, mod); - - mod = 16 - mod; - mod *= filter_weight; - - return mod; -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static INLINE int get_filter_weight(unsigned int i, unsigned int j, - unsigned int block_height, - unsigned int block_width, - const int *const blk_fw, int use_32x32) { - // blk_fw[0] ~ blk_fw[3] are the same. - if (use_32x32) { - return blk_fw[0]; - } - - if (i < block_height / 2) { - if (j < block_width / 2) { - return blk_fw[0]; - } - - return blk_fw[1]; - } - - if (j < block_width / 2) { - return blk_fw[2]; - } - - return blk_fw[3]; -} - -void vp9_apply_temporal_filter_c( - const uint8_t *y_frame1, int y_stride, const uint8_t *y_pred, - int y_buf_stride, const uint8_t *u_frame1, const uint8_t *v_frame1, - int uv_stride, const uint8_t *u_pred, const uint8_t *v_pred, - int uv_buf_stride, unsigned int block_width, unsigned int block_height, - int ss_x, int ss_y, int strength, const int *const blk_fw, int use_32x32, - uint32_t *y_accumulator, uint16_t *y_count, uint32_t *u_accumulator, - uint16_t *u_count, uint32_t *v_accumulator, uint16_t *v_count) { - unsigned int i, j, k, m; - int modifier; - const int rounding = (1 << strength) >> 1; - const unsigned int uv_block_width = block_width >> ss_x; - const unsigned int uv_block_height = block_height >> ss_y; - DECLARE_ALIGNED(16, uint16_t, y_diff_sse[BLK_PELS]); - DECLARE_ALIGNED(16, uint16_t, u_diff_sse[BLK_PELS]); - DECLARE_ALIGNED(16, uint16_t, v_diff_sse[BLK_PELS]); - - int idx = 0, idy; - - assert(strength >= 0); - assert(strength <= 6); - - memset(y_diff_sse, 0, BLK_PELS * sizeof(uint16_t)); - memset(u_diff_sse, 0, BLK_PELS * sizeof(uint16_t)); - memset(v_diff_sse, 0, BLK_PELS * sizeof(uint16_t)); - - // Calculate diff^2 for each pixel of the 16x16 block. - // TODO(yunqing): the following code needs to be optimized. - for (i = 0; i < block_height; i++) { - for (j = 0; j < block_width; j++) { - const int16_t diff = - y_frame1[i * (int)y_stride + j] - y_pred[i * (int)block_width + j]; - y_diff_sse[idx++] = diff * diff; - } - } - idx = 0; - for (i = 0; i < uv_block_height; i++) { - for (j = 0; j < uv_block_width; j++) { - const int16_t diffu = - u_frame1[i * uv_stride + j] - u_pred[i * uv_buf_stride + j]; - const int16_t diffv = - v_frame1[i * uv_stride + j] - v_pred[i * uv_buf_stride + j]; - u_diff_sse[idx] = diffu * diffu; - v_diff_sse[idx] = diffv * diffv; - idx++; - } - } - - for (i = 0, k = 0, m = 0; i < block_height; i++) { - for (j = 0; j < block_width; j++) { - const int pixel_value = y_pred[i * y_buf_stride + j]; - const int filter_weight = - get_filter_weight(i, j, block_height, block_width, blk_fw, use_32x32); - - // non-local mean approach - int y_index = 0; - - const int uv_r = i >> ss_y; - const int uv_c = j >> ss_x; - modifier = 0; - - for (idy = -1; idy <= 1; ++idy) { - for (idx = -1; idx <= 1; ++idx) { - const int row = (int)i + idy; - const int col = (int)j + idx; - - if (row >= 0 && row < (int)block_height && col >= 0 && - col < (int)block_width) { - modifier += y_diff_sse[row * (int)block_width + col]; - ++y_index; - } - } - } - - assert(y_index > 0); - - modifier += u_diff_sse[uv_r * uv_block_width + uv_c]; - modifier += v_diff_sse[uv_r * uv_block_width + uv_c]; - - y_index += 2; - - modifier = - mod_index(modifier, y_index, rounding, strength, filter_weight); - - y_count[k] += modifier; - y_accumulator[k] += modifier * pixel_value; - - ++k; - - // Process chroma component - if (!(i & ss_y) && !(j & ss_x)) { - const int u_pixel_value = u_pred[uv_r * uv_buf_stride + uv_c]; - const int v_pixel_value = v_pred[uv_r * uv_buf_stride + uv_c]; - - // non-local mean approach - int cr_index = 0; - int u_mod = 0, v_mod = 0; - int y_diff = 0; - - for (idy = -1; idy <= 1; ++idy) { - for (idx = -1; idx <= 1; ++idx) { - const int row = uv_r + idy; - const int col = uv_c + idx; - - if (row >= 0 && row < (int)uv_block_height && col >= 0 && - col < (int)uv_block_width) { - u_mod += u_diff_sse[row * uv_block_width + col]; - v_mod += v_diff_sse[row * uv_block_width + col]; - ++cr_index; - } - } - } - - assert(cr_index > 0); - - for (idy = 0; idy < 1 + ss_y; ++idy) { - for (idx = 0; idx < 1 + ss_x; ++idx) { - const int row = (uv_r << ss_y) + idy; - const int col = (uv_c << ss_x) + idx; - y_diff += y_diff_sse[row * (int)block_width + col]; - ++cr_index; - } - } - - u_mod += y_diff; - v_mod += y_diff; - - u_mod = mod_index(u_mod, cr_index, rounding, strength, filter_weight); - v_mod = mod_index(v_mod, cr_index, rounding, strength, filter_weight); - - u_count[m] += u_mod; - u_accumulator[m] += u_mod * u_pixel_value; - v_count[m] += v_mod; - v_accumulator[m] += v_mod * v_pixel_value; - - ++m; - } // Complete YUV pixel - } - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -void vp9_highbd_apply_temporal_filter_c( - const uint16_t *y_src, int y_src_stride, const uint16_t *y_pre, - int y_pre_stride, const uint16_t *u_src, const uint16_t *v_src, - int uv_src_stride, const uint16_t *u_pre, const uint16_t *v_pre, - int uv_pre_stride, unsigned int block_width, unsigned int block_height, - int ss_x, int ss_y, int strength, const int *const blk_fw, int use_32x32, - uint32_t *y_accum, uint16_t *y_count, uint32_t *u_accum, uint16_t *u_count, - uint32_t *v_accum, uint16_t *v_count) { - const int uv_block_width = block_width >> ss_x; - const int uv_block_height = block_height >> ss_y; - const int y_diff_stride = BW; - const int uv_diff_stride = BW; - - DECLARE_ALIGNED(16, uint32_t, y_diff_sse[BLK_PELS]); - DECLARE_ALIGNED(16, uint32_t, u_diff_sse[BLK_PELS]); - DECLARE_ALIGNED(16, uint32_t, v_diff_sse[BLK_PELS]); - - const int rounding = (1 << strength) >> 1; - - // Loop variables - int row, col; - int uv_row, uv_col; - int row_step, col_step; - - memset(y_diff_sse, 0, BLK_PELS * sizeof(uint32_t)); - memset(u_diff_sse, 0, BLK_PELS * sizeof(uint32_t)); - memset(v_diff_sse, 0, BLK_PELS * sizeof(uint32_t)); - - // Get the square diffs - for (row = 0; row < (int)block_height; row++) { - for (col = 0; col < (int)block_width; col++) { - const int diff = - y_src[row * y_src_stride + col] - y_pre[row * y_pre_stride + col]; - y_diff_sse[row * y_diff_stride + col] = diff * diff; - } - } - - for (row = 0; row < uv_block_height; row++) { - for (col = 0; col < uv_block_width; col++) { - const int u_diff = - u_src[row * uv_src_stride + col] - u_pre[row * uv_pre_stride + col]; - const int v_diff = - v_src[row * uv_src_stride + col] - v_pre[row * uv_pre_stride + col]; - u_diff_sse[row * uv_diff_stride + col] = u_diff * u_diff; - v_diff_sse[row * uv_diff_stride + col] = v_diff * v_diff; - } - } - - // Apply the filter to luma - for (row = 0; row < (int)block_height; row++) { - for (col = 0; col < (int)block_width; col++) { - const int filter_weight = get_filter_weight( - row, col, block_height, block_width, blk_fw, use_32x32); - - // First we get the modifier for the current y pixel - const int y_pixel = y_pre[row * y_pre_stride + col]; - int y_num_used = 0; - int y_mod = 0; - - // Sum the neighboring 3x3 y pixels - for (row_step = -1; row_step <= 1; row_step++) { - for (col_step = -1; col_step <= 1; col_step++) { - const int sub_row = row + row_step; - const int sub_col = col + col_step; - - if (sub_row >= 0 && sub_row < (int)block_height && sub_col >= 0 && - sub_col < (int)block_width) { - y_mod += y_diff_sse[sub_row * y_diff_stride + sub_col]; - y_num_used++; - } - } - } - - // Sum the corresponding uv pixels to the current y modifier - // Note we are rounding down instead of rounding to the nearest pixel. - uv_row = row >> ss_y; - uv_col = col >> ss_x; - y_mod += u_diff_sse[uv_row * uv_diff_stride + uv_col]; - y_mod += v_diff_sse[uv_row * uv_diff_stride + uv_col]; - - y_num_used += 2; - - // Set the modifier - y_mod = highbd_mod_index(y_mod, y_num_used, rounding, strength, - filter_weight); - - // Accumulate the result - y_count[row * block_width + col] += y_mod; - y_accum[row * block_width + col] += y_mod * y_pixel; - } - } - - // Apply the filter to chroma - for (uv_row = 0; uv_row < uv_block_height; uv_row++) { - for (uv_col = 0; uv_col < uv_block_width; uv_col++) { - const int y_row = uv_row << ss_y; - const int y_col = uv_col << ss_x; - const int filter_weight = get_filter_weight( - uv_row, uv_col, uv_block_height, uv_block_width, blk_fw, use_32x32); - - const int u_pixel = u_pre[uv_row * uv_pre_stride + uv_col]; - const int v_pixel = v_pre[uv_row * uv_pre_stride + uv_col]; - - int uv_num_used = 0; - int u_mod = 0, v_mod = 0; - - // Sum the neighboring 3x3 chromal pixels to the chroma modifier - for (row_step = -1; row_step <= 1; row_step++) { - for (col_step = -1; col_step <= 1; col_step++) { - const int sub_row = uv_row + row_step; - const int sub_col = uv_col + col_step; - - if (sub_row >= 0 && sub_row < uv_block_height && sub_col >= 0 && - sub_col < uv_block_width) { - u_mod += u_diff_sse[sub_row * uv_diff_stride + sub_col]; - v_mod += v_diff_sse[sub_row * uv_diff_stride + sub_col]; - uv_num_used++; - } - } - } - - // Sum all the luma pixels associated with the current luma pixel - for (row_step = 0; row_step < 1 + ss_y; row_step++) { - for (col_step = 0; col_step < 1 + ss_x; col_step++) { - const int sub_row = y_row + row_step; - const int sub_col = y_col + col_step; - const int y_diff = y_diff_sse[sub_row * y_diff_stride + sub_col]; - - u_mod += y_diff; - v_mod += y_diff; - uv_num_used++; - } - } - - // Set the modifier - u_mod = highbd_mod_index(u_mod, uv_num_used, rounding, strength, - filter_weight); - v_mod = highbd_mod_index(v_mod, uv_num_used, rounding, strength, - filter_weight); - - // Accumulate the result - u_count[uv_row * uv_block_width + uv_col] += u_mod; - u_accum[uv_row * uv_block_width + uv_col] += u_mod * u_pixel; - v_count[uv_row * uv_block_width + uv_col] += v_mod; - v_accum[uv_row * uv_block_width + uv_col] += v_mod * v_pixel; - } - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static uint32_t temporal_filter_find_matching_mb_c( - VP9_COMP *cpi, ThreadData *td, uint8_t *arf_frame_buf, - uint8_t *frame_ptr_buf, int stride, MV *ref_mv, MV *blk_mvs, - int *blk_bestsme) { - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - MV_SPEED_FEATURES *const mv_sf = &cpi->sf.mv; - const SEARCH_METHODS search_method = MESH; - const SEARCH_METHODS search_method_16 = cpi->sf.temporal_filter_search_method; - int step_param; - int sadpb = x->sadperbit16; - uint32_t bestsme = UINT_MAX; - uint32_t distortion; - uint32_t sse; - int cost_list[5]; - const MvLimits tmp_mv_limits = x->mv_limits; - - MV best_ref_mv1 = { 0, 0 }; - MV best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */ - - // Save input state - struct buf_2d src = x->plane[0].src; - struct buf_2d pre = xd->plane[0].pre[0]; - int i, j, k = 0; - - best_ref_mv1_full.col = best_ref_mv1.col >> 3; - best_ref_mv1_full.row = best_ref_mv1.row >> 3; - - // Setup frame pointers - x->plane[0].src.buf = arf_frame_buf; - x->plane[0].src.stride = stride; - xd->plane[0].pre[0].buf = frame_ptr_buf; - xd->plane[0].pre[0].stride = stride; - - step_param = mv_sf->reduce_first_step_size; - step_param = VPXMIN(step_param, MAX_MVSEARCH_STEPS - 2); - - vp9_set_mv_search_range(&x->mv_limits, &best_ref_mv1); - - vp9_full_pixel_search(cpi, x, TF_BLOCK, &best_ref_mv1_full, step_param, - search_method, sadpb, cond_cost_list(cpi, cost_list), - &best_ref_mv1, ref_mv, 0, 0); - - /* restore UMV window */ - x->mv_limits = tmp_mv_limits; - - // find_fractional_mv_step parameters: best_ref_mv1 is for mv rate cost - // calculation. The start full mv and the search result are stored in - // ref_mv. - bestsme = cpi->find_fractional_mv_step( - x, ref_mv, &best_ref_mv1, cpi->common.allow_high_precision_mv, - x->errorperbit, &cpi->fn_ptr[TF_BLOCK], 0, mv_sf->subpel_search_level, - cond_cost_list(cpi, cost_list), NULL, NULL, &distortion, &sse, NULL, BW, - BH, USE_8_TAPS_SHARP); - - // DO motion search on 4 16x16 sub_blocks. - best_ref_mv1.row = ref_mv->row; - best_ref_mv1.col = ref_mv->col; - best_ref_mv1_full.col = best_ref_mv1.col >> 3; - best_ref_mv1_full.row = best_ref_mv1.row >> 3; - - for (i = 0; i < BH; i += SUB_BH) { - for (j = 0; j < BW; j += SUB_BW) { - // Setup frame pointers - x->plane[0].src.buf = arf_frame_buf + i * stride + j; - x->plane[0].src.stride = stride; - xd->plane[0].pre[0].buf = frame_ptr_buf + i * stride + j; - xd->plane[0].pre[0].stride = stride; - - vp9_set_mv_search_range(&x->mv_limits, &best_ref_mv1); - vp9_full_pixel_search(cpi, x, TF_SUB_BLOCK, &best_ref_mv1_full, - step_param, search_method_16, sadpb, - cond_cost_list(cpi, cost_list), &best_ref_mv1, - &blk_mvs[k], 0, 0); - /* restore UMV window */ - x->mv_limits = tmp_mv_limits; - - blk_bestsme[k] = cpi->find_fractional_mv_step( - x, &blk_mvs[k], &best_ref_mv1, cpi->common.allow_high_precision_mv, - x->errorperbit, &cpi->fn_ptr[TF_SUB_BLOCK], 0, - mv_sf->subpel_search_level, cond_cost_list(cpi, cost_list), NULL, - NULL, &distortion, &sse, NULL, SUB_BW, SUB_BH, USE_8_TAPS_SHARP); - k++; - } - } - - // Restore input state - x->plane[0].src = src; - xd->plane[0].pre[0] = pre; - - return bestsme; -} - -void vp9_temporal_filter_iterate_row_c(VP9_COMP *cpi, ThreadData *td, - int mb_row, int mb_col_start, - int mb_col_end) { - ARNRFilterData *arnr_filter_data = &cpi->arnr_filter_data; - YV12_BUFFER_CONFIG **frames = arnr_filter_data->frames; - int frame_count = arnr_filter_data->frame_count; - int alt_ref_index = arnr_filter_data->alt_ref_index; - int strength = arnr_filter_data->strength; - struct scale_factors *scale = &arnr_filter_data->sf; - int byte; - int frame; - int mb_col; - int mb_cols = (frames[alt_ref_index]->y_crop_width + BW - 1) >> BW_LOG2; - int mb_rows = (frames[alt_ref_index]->y_crop_height + BH - 1) >> BH_LOG2; - DECLARE_ALIGNED(16, uint32_t, accumulator[BLK_PELS * 3]); - DECLARE_ALIGNED(16, uint16_t, count[BLK_PELS * 3]); - MACROBLOCKD *mbd = &td->mb.e_mbd; - YV12_BUFFER_CONFIG *f = frames[alt_ref_index]; - YV12_BUFFER_CONFIG *dst = arnr_filter_data->dst; - uint8_t *dst1, *dst2; -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, predictor16[BLK_PELS * 3]); - DECLARE_ALIGNED(16, uint8_t, predictor8[BLK_PELS * 3]); - uint8_t *predictor; -#else - DECLARE_ALIGNED(16, uint8_t, predictor[BLK_PELS * 3]); -#endif - const int mb_uv_height = BH >> mbd->plane[1].subsampling_y; - const int mb_uv_width = BW >> mbd->plane[1].subsampling_x; - // Addition of the tile col level offsets - int mb_y_offset = mb_row * BH * (f->y_stride) + BW * mb_col_start; - int mb_uv_offset = - mb_row * mb_uv_height * f->uv_stride + mb_uv_width * mb_col_start; - -#if CONFIG_VP9_HIGHBITDEPTH - if (mbd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - predictor = CONVERT_TO_BYTEPTR(predictor16); - } else { - predictor = predictor8; - } -#endif - - // Source frames are extended to 16 pixels. This is different than - // L/A/G reference frames that have a border of 32 (VP9ENCBORDERINPIXELS) - // A 6/8/12 tap filter is used for motion search and prediction. So the - // largest Y mv on a border would then be 16 - TF_INTERP_EXTEND. The UV - // blocks are half the size of the Y and therefore only extended by 8. - // The largest mv that a UV block can support is 8 - TF_INTERP_EXTEND. - // A UV mv is half of a Y mv. (16 - TF_INTERP_EXTEND) >> 1 is greater than - // 8 - TF_INTERP_EXTEND. To keep the mv in play for both Y and UV planes, - // the max that it can be on a border is therefore 16 - (2 * TF_INTERP_EXTEND - // + 1). - td->mb.mv_limits.row_min = -((mb_row * BH) + (17 - 2 * TF_INTERP_EXTEND)); - td->mb.mv_limits.row_max = - ((mb_rows - 1 - mb_row) * BH) + (17 - 2 * TF_INTERP_EXTEND); - - for (mb_col = mb_col_start; mb_col < mb_col_end; mb_col++) { - int i, j, k; - int stride; - MV ref_mv; - - vp9_zero_array(accumulator, BLK_PELS * 3); - vp9_zero_array(count, BLK_PELS * 3); - - td->mb.mv_limits.col_min = -((mb_col * BW) + (17 - 2 * TF_INTERP_EXTEND)); - td->mb.mv_limits.col_max = - ((mb_cols - 1 - mb_col) * BW) + (17 - 2 * TF_INTERP_EXTEND); - - if (cpi->oxcf.content == VP9E_CONTENT_FILM) { - unsigned int src_variance; - struct buf_2d src; - - src.buf = f->y_buffer + mb_y_offset; - src.stride = f->y_stride; - -#if CONFIG_VP9_HIGHBITDEPTH - if (mbd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - src_variance = - vp9_high_get_sby_perpixel_variance(cpi, &src, TF_BLOCK, mbd->bd); - } else { - src_variance = vp9_get_sby_perpixel_variance(cpi, &src, TF_BLOCK); - } -#else - src_variance = vp9_get_sby_perpixel_variance(cpi, &src, TF_BLOCK); -#endif // CONFIG_VP9_HIGHBITDEPTH - - if (src_variance <= 2) { - strength = VPXMAX(0, arnr_filter_data->strength - 2); - } - } - - for (frame = 0; frame < frame_count; frame++) { - // MVs for 4 16x16 sub blocks. - MV blk_mvs[4]; - // Filter weights for 4 16x16 sub blocks. - int blk_fw[4] = { 0, 0, 0, 0 }; - int use_32x32 = 0; - - if (frames[frame] == NULL) continue; - - ref_mv.row = 0; - ref_mv.col = 0; - blk_mvs[0] = kZeroMv; - blk_mvs[1] = kZeroMv; - blk_mvs[2] = kZeroMv; - blk_mvs[3] = kZeroMv; - - if (frame == alt_ref_index) { - blk_fw[0] = blk_fw[1] = blk_fw[2] = blk_fw[3] = 2; - use_32x32 = 1; - } else { - const int thresh_low = 10000; - const int thresh_high = 20000; - int blk_bestsme[4] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX }; - - // Find best match in this frame by MC - int err = temporal_filter_find_matching_mb_c( - cpi, td, frames[alt_ref_index]->y_buffer + mb_y_offset, - frames[frame]->y_buffer + mb_y_offset, frames[frame]->y_stride, - &ref_mv, blk_mvs, blk_bestsme); - - int err16 = - blk_bestsme[0] + blk_bestsme[1] + blk_bestsme[2] + blk_bestsme[3]; - int max_err = INT_MIN, min_err = INT_MAX; - for (k = 0; k < 4; k++) { - if (min_err > blk_bestsme[k]) min_err = blk_bestsme[k]; - if (max_err < blk_bestsme[k]) max_err = blk_bestsme[k]; - } - - if (((err * 15 < (err16 << 4)) && max_err - min_err < 10000) || - ((err * 14 < (err16 << 4)) && max_err - min_err < 5000)) { - use_32x32 = 1; - // Assign higher weight to matching MB if it's error - // score is lower. If not applying MC default behavior - // is to weight all MBs equal. - blk_fw[0] = err < (thresh_low << THR_SHIFT) ? 2 - : err < (thresh_high << THR_SHIFT) ? 1 - : 0; - blk_fw[1] = blk_fw[2] = blk_fw[3] = blk_fw[0]; - } else { - use_32x32 = 0; - for (k = 0; k < 4; k++) - blk_fw[k] = blk_bestsme[k] < thresh_low ? 2 - : blk_bestsme[k] < thresh_high ? 1 - : 0; - } - - for (k = 0; k < 4; k++) { - switch (abs(frame - alt_ref_index)) { - case 1: blk_fw[k] = VPXMIN(blk_fw[k], 2); break; - case 2: - case 3: blk_fw[k] = VPXMIN(blk_fw[k], 1); break; - default: break; - } - } - } - - if (blk_fw[0] | blk_fw[1] | blk_fw[2] | blk_fw[3]) { - // Construct the predictors - temporal_filter_predictors_mb_c( - mbd, frames[frame]->y_buffer + mb_y_offset, - frames[frame]->u_buffer + mb_uv_offset, - frames[frame]->v_buffer + mb_uv_offset, frames[frame]->y_stride, - mb_uv_width, mb_uv_height, ref_mv.row, ref_mv.col, predictor, scale, - mb_col * BW, mb_row * BH, blk_mvs, use_32x32); - -#if CONFIG_VP9_HIGHBITDEPTH - if (mbd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - int adj_strength = strength + 2 * (mbd->bd - 8); - // Apply the filter (YUV) - vp9_highbd_apply_temporal_filter( - CONVERT_TO_SHORTPTR(f->y_buffer + mb_y_offset), f->y_stride, - CONVERT_TO_SHORTPTR(predictor), BW, - CONVERT_TO_SHORTPTR(f->u_buffer + mb_uv_offset), - CONVERT_TO_SHORTPTR(f->v_buffer + mb_uv_offset), f->uv_stride, - CONVERT_TO_SHORTPTR(predictor + BLK_PELS), - CONVERT_TO_SHORTPTR(predictor + (BLK_PELS << 1)), mb_uv_width, BW, - BH, mbd->plane[1].subsampling_x, mbd->plane[1].subsampling_y, - adj_strength, blk_fw, use_32x32, accumulator, count, - accumulator + BLK_PELS, count + BLK_PELS, - accumulator + (BLK_PELS << 1), count + (BLK_PELS << 1)); - } else { - // Apply the filter (YUV) - vp9_apply_temporal_filter( - f->y_buffer + mb_y_offset, f->y_stride, predictor, BW, - f->u_buffer + mb_uv_offset, f->v_buffer + mb_uv_offset, - f->uv_stride, predictor + BLK_PELS, predictor + (BLK_PELS << 1), - mb_uv_width, BW, BH, mbd->plane[1].subsampling_x, - mbd->plane[1].subsampling_y, strength, blk_fw, use_32x32, - accumulator, count, accumulator + BLK_PELS, count + BLK_PELS, - accumulator + (BLK_PELS << 1), count + (BLK_PELS << 1)); - } -#else - // Apply the filter (YUV) - vp9_apply_temporal_filter( - f->y_buffer + mb_y_offset, f->y_stride, predictor, BW, - f->u_buffer + mb_uv_offset, f->v_buffer + mb_uv_offset, - f->uv_stride, predictor + BLK_PELS, predictor + (BLK_PELS << 1), - mb_uv_width, BW, BH, mbd->plane[1].subsampling_x, - mbd->plane[1].subsampling_y, strength, blk_fw, use_32x32, - accumulator, count, accumulator + BLK_PELS, count + BLK_PELS, - accumulator + (BLK_PELS << 1), count + (BLK_PELS << 1)); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - -#if CONFIG_VP9_HIGHBITDEPTH - if (mbd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - uint16_t *dst1_16; - uint16_t *dst2_16; - // Normalize filter output to produce AltRef frame - dst1 = dst->y_buffer; - dst1_16 = CONVERT_TO_SHORTPTR(dst1); - stride = dst->y_stride; - byte = mb_y_offset; - for (i = 0, k = 0; i < BH; i++) { - for (j = 0; j < BW; j++, k++) { - unsigned int pval = accumulator[k] + (count[k] >> 1); - pval *= fixed_divide[count[k]]; - pval >>= 19; - - dst1_16[byte] = (uint16_t)pval; - - // move to next pixel - byte++; - } - - byte += stride - BW; - } - - dst1 = dst->u_buffer; - dst2 = dst->v_buffer; - dst1_16 = CONVERT_TO_SHORTPTR(dst1); - dst2_16 = CONVERT_TO_SHORTPTR(dst2); - stride = dst->uv_stride; - byte = mb_uv_offset; - for (i = 0, k = BLK_PELS; i < mb_uv_height; i++) { - for (j = 0; j < mb_uv_width; j++, k++) { - int m = k + BLK_PELS; - - // U - unsigned int pval = accumulator[k] + (count[k] >> 1); - pval *= fixed_divide[count[k]]; - pval >>= 19; - dst1_16[byte] = (uint16_t)pval; - - // V - pval = accumulator[m] + (count[m] >> 1); - pval *= fixed_divide[count[m]]; - pval >>= 19; - dst2_16[byte] = (uint16_t)pval; - - // move to next pixel - byte++; - } - - byte += stride - mb_uv_width; - } - } else { - // Normalize filter output to produce AltRef frame - dst1 = dst->y_buffer; - stride = dst->y_stride; - byte = mb_y_offset; - for (i = 0, k = 0; i < BH; i++) { - for (j = 0; j < BW; j++, k++) { - unsigned int pval = accumulator[k] + (count[k] >> 1); - pval *= fixed_divide[count[k]]; - pval >>= 19; - - dst1[byte] = (uint8_t)pval; - - // move to next pixel - byte++; - } - byte += stride - BW; - } - - dst1 = dst->u_buffer; - dst2 = dst->v_buffer; - stride = dst->uv_stride; - byte = mb_uv_offset; - for (i = 0, k = BLK_PELS; i < mb_uv_height; i++) { - for (j = 0; j < mb_uv_width; j++, k++) { - int m = k + BLK_PELS; - - // U - unsigned int pval = accumulator[k] + (count[k] >> 1); - pval *= fixed_divide[count[k]]; - pval >>= 19; - dst1[byte] = (uint8_t)pval; - - // V - pval = accumulator[m] + (count[m] >> 1); - pval *= fixed_divide[count[m]]; - pval >>= 19; - dst2[byte] = (uint8_t)pval; - - // move to next pixel - byte++; - } - byte += stride - mb_uv_width; - } - } -#else - // Normalize filter output to produce AltRef frame - dst1 = dst->y_buffer; - stride = dst->y_stride; - byte = mb_y_offset; - for (i = 0, k = 0; i < BH; i++) { - for (j = 0; j < BW; j++, k++) { - unsigned int pval = accumulator[k] + (count[k] >> 1); - pval *= fixed_divide[count[k]]; - pval >>= 19; - - dst1[byte] = (uint8_t)pval; - - // move to next pixel - byte++; - } - byte += stride - BW; - } - - dst1 = dst->u_buffer; - dst2 = dst->v_buffer; - stride = dst->uv_stride; - byte = mb_uv_offset; - for (i = 0, k = BLK_PELS; i < mb_uv_height; i++) { - for (j = 0; j < mb_uv_width; j++, k++) { - int m = k + BLK_PELS; - - // U - unsigned int pval = accumulator[k] + (count[k] >> 1); - pval *= fixed_divide[count[k]]; - pval >>= 19; - dst1[byte] = (uint8_t)pval; - - // V - pval = accumulator[m] + (count[m] >> 1); - pval *= fixed_divide[count[m]]; - pval >>= 19; - dst2[byte] = (uint8_t)pval; - - // move to next pixel - byte++; - } - byte += stride - mb_uv_width; - } -#endif // CONFIG_VP9_HIGHBITDEPTH - mb_y_offset += BW; - mb_uv_offset += mb_uv_width; - } -} - -static void temporal_filter_iterate_tile_c(VP9_COMP *cpi, int tile_row, - int tile_col) { - VP9_COMMON *const cm = &cpi->common; - const int tile_cols = 1 << cm->log2_tile_cols; - TileInfo *tile_info = - &cpi->tile_data[tile_row * tile_cols + tile_col].tile_info; - const int mb_row_start = (tile_info->mi_row_start) >> TF_SHIFT; - const int mb_row_end = (tile_info->mi_row_end + TF_ROUND) >> TF_SHIFT; - const int mb_col_start = (tile_info->mi_col_start) >> TF_SHIFT; - const int mb_col_end = (tile_info->mi_col_end + TF_ROUND) >> TF_SHIFT; - int mb_row; - - for (mb_row = mb_row_start; mb_row < mb_row_end; mb_row++) { - vp9_temporal_filter_iterate_row_c(cpi, &cpi->td, mb_row, mb_col_start, - mb_col_end); - } -} - -static void temporal_filter_iterate_c(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - const int tile_cols = 1 << cm->log2_tile_cols; - const int tile_rows = 1 << cm->log2_tile_rows; - int tile_row, tile_col; - vp9_init_tile_data(cpi); - - for (tile_row = 0; tile_row < tile_rows; ++tile_row) { - for (tile_col = 0; tile_col < tile_cols; ++tile_col) { - temporal_filter_iterate_tile_c(cpi, tile_row, tile_col); - } - } -} - -// Apply buffer limits and context specific adjustments to arnr filter. -static void adjust_arnr_filter(VP9_COMP *cpi, int distance, int group_boost, - int *arnr_frames, int *frames_backward, - int *frames_forward, int *arnr_strength) { - const VP9EncoderConfig *const oxcf = &cpi->oxcf; - - int max_fwd = - VPXMAX((int)vp9_lookahead_depth(cpi->lookahead) - distance - 1, 0); - int max_bwd = VPXMAX(distance, 0); - int frames = VPXMAX(oxcf->arnr_max_frames, 1); - int q, base_strength, strength; - - // Context dependent two pass adjustment to strength. - if (oxcf->pass == 2) { - base_strength = oxcf->arnr_strength + cpi->twopass.arnr_strength_adjustment; - // Clip to allowed range. - base_strength = VPXMIN(6, VPXMAX(0, base_strength)); - } else { - base_strength = oxcf->arnr_strength; - } - - // Adjust the strength based on active max q. - if (cpi->common.current_video_frame > 1) - q = ((int)vp9_convert_qindex_to_q(cpi->rc.avg_frame_qindex[INTER_FRAME], - cpi->common.bit_depth)); - else - q = ((int)vp9_convert_qindex_to_q(cpi->rc.avg_frame_qindex[KEY_FRAME], - cpi->common.bit_depth)); - if (q > 16) { - strength = base_strength; - } else { - strength = base_strength - ((16 - q) / 2); - if (strength < 0) strength = 0; - } - - // Adjust number of frames in filter and strength based on gf boost level. - frames = VPXMIN(frames, group_boost / 150); - - if (strength > group_boost / 300) { - strength = group_boost / 300; - } - - if (VPXMIN(max_fwd, max_bwd) >= frames / 2) { - // Handle the even/odd case. - *frames_backward = frames / 2; - *frames_forward = (frames - 1) / 2; - } else { - if (max_fwd < frames / 2) { - *frames_forward = max_fwd; - *frames_backward = VPXMIN(frames - 1 - *frames_forward, max_bwd); - } else { - *frames_backward = max_bwd; - *frames_forward = VPXMIN(frames - 1 - *frames_backward, max_fwd); - } - } - - // Set the baseline active filter size. - frames = *frames_backward + 1 + *frames_forward; - - // Adjustments for second level arf in multi arf case. - // Leave commented out place holder for possible filtering adjustment with - // new multi-layer arf code. - // if (cpi->oxcf.pass == 2 && cpi->multi_arf_allowed) - // if (gf_group->rf_level[gf_group->index] != GF_ARF_STD) strength >>= 1; - - // TODO(jingning): Skip temporal filtering for intermediate frames that will - // be used as show_existing_frame. Need to further explore the possibility to - // apply certain filter. - if (frames <= 1) { - frames = 1; - *frames_backward = 0; - *frames_forward = 0; - } - - *arnr_frames = frames; - *arnr_strength = strength; -} - -void vp9_temporal_filter(VP9_COMP *cpi, int distance) { - VP9_COMMON *const cm = &cpi->common; - RATE_CONTROL *const rc = &cpi->rc; - MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; - ARNRFilterData *arnr_filter_data = &cpi->arnr_filter_data; - int frame; - int frames_to_blur; - int start_frame; - int strength; - int frames_to_blur_backward; - int frames_to_blur_forward; - struct scale_factors *sf = &arnr_filter_data->sf; - YV12_BUFFER_CONFIG **frames = arnr_filter_data->frames; - int rdmult; - - // Apply context specific adjustments to the arnr filter parameters. - adjust_arnr_filter(cpi, distance, rc->gfu_boost, &frames_to_blur, - &frames_to_blur_backward, &frames_to_blur_forward, - &strength); - start_frame = distance + frames_to_blur_forward; - - arnr_filter_data->strength = strength; - arnr_filter_data->frame_count = frames_to_blur; - arnr_filter_data->alt_ref_index = frames_to_blur_backward; - arnr_filter_data->dst = &cpi->tf_buffer; - - // Setup frame pointers, NULL indicates frame not included in filter. - for (frame = 0; frame < frames_to_blur; ++frame) { - const int which_buffer = start_frame - frame; - struct lookahead_entry *buf = - vp9_lookahead_peek(cpi->lookahead, which_buffer); - frames[frames_to_blur - 1 - frame] = &buf->img; - } - - YV12_BUFFER_CONFIG *f = frames[arnr_filter_data->alt_ref_index]; - xd->cur_buf = f; - xd->plane[1].subsampling_y = f->subsampling_y; - xd->plane[1].subsampling_x = f->subsampling_x; - - if (frames_to_blur > 0) { - // Setup scaling factors. Scaling on each of the arnr frames is not - // supported. - if (cpi->use_svc) { - // In spatial svc the scaling factors might be less then 1/2. - // So we will use non-normative scaling. - int frame_used = 0; -#if CONFIG_VP9_HIGHBITDEPTH - vp9_setup_scale_factors_for_frame( - sf, get_frame_new_buffer(cm)->y_crop_width, - get_frame_new_buffer(cm)->y_crop_height, - get_frame_new_buffer(cm)->y_crop_width, - get_frame_new_buffer(cm)->y_crop_height, cm->use_highbitdepth); -#else - vp9_setup_scale_factors_for_frame( - sf, get_frame_new_buffer(cm)->y_crop_width, - get_frame_new_buffer(cm)->y_crop_height, - get_frame_new_buffer(cm)->y_crop_width, - get_frame_new_buffer(cm)->y_crop_height); -#endif // CONFIG_VP9_HIGHBITDEPTH - - for (frame = 0; frame < frames_to_blur; ++frame) { - if (cm->mi_cols * MI_SIZE != frames[frame]->y_width || - cm->mi_rows * MI_SIZE != frames[frame]->y_height) { - if (vpx_realloc_frame_buffer(&cpi->svc.scaled_frames[frame_used], - cm->width, cm->height, cm->subsampling_x, - cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS, - cm->byte_alignment, NULL, NULL, NULL)) { - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to reallocate alt_ref_buffer"); - } - frames[frame] = vp9_scale_if_required( - cm, frames[frame], &cpi->svc.scaled_frames[frame_used], 0, - EIGHTTAP, 0); - ++frame_used; - } - } - cm->mi = cm->mip + cm->mi_stride + 1; - xd->mi = cm->mi_grid_visible; - xd->mi[0] = cm->mi; - } else { -// ARF is produced at the native frame size and resized when coded. -#if CONFIG_VP9_HIGHBITDEPTH - vp9_setup_scale_factors_for_frame( - sf, frames[0]->y_crop_width, frames[0]->y_crop_height, - frames[0]->y_crop_width, frames[0]->y_crop_height, - cm->use_highbitdepth); -#else - vp9_setup_scale_factors_for_frame( - sf, frames[0]->y_crop_width, frames[0]->y_crop_height, - frames[0]->y_crop_width, frames[0]->y_crop_height); -#endif // CONFIG_VP9_HIGHBITDEPTH - } - } - - // Initialize errorperbit and sabperbit. - rdmult = vp9_compute_rd_mult_based_on_qindex(cpi, ARNR_FILT_QINDEX); - set_error_per_bit(&cpi->td.mb, rdmult); - vp9_initialize_me_consts(cpi, &cpi->td.mb, ARNR_FILT_QINDEX); - - if (!cpi->row_mt) - temporal_filter_iterate_c(cpi); - else - vp9_temporal_filter_row_mt(cpi); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_temporal_filter.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_temporal_filter.h deleted file mode 100644 index 553a4682..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_temporal_filter.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_TEMPORAL_FILTER_H_ -#define VPX_VP9_ENCODER_VP9_TEMPORAL_FILTER_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define ARNR_FILT_QINDEX 128 -static const MV kZeroMv = { 0, 0 }; - -// Block size used in temporal filtering -#define TF_BLOCK BLOCK_32X32 -#define BH 32 -#define BH_LOG2 5 -#define BW 32 -#define BW_LOG2 5 -#define BLK_PELS ((BH) * (BW)) // Pixels in the block -#define TF_SHIFT 2 -#define TF_ROUND 3 -#define THR_SHIFT 2 -#define TF_SUB_BLOCK BLOCK_16X16 -#define SUB_BH 16 -#define SUB_BW 16 - -void vp9_temporal_filter_init(void); -void vp9_temporal_filter(VP9_COMP *cpi, int distance); - -void vp9_temporal_filter_iterate_row_c(VP9_COMP *cpi, ThreadData *td, - int mb_row, int mb_col_start, - int mb_col_end); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_TEMPORAL_FILTER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_temporal_filter_constants.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_temporal_filter_constants.h deleted file mode 100644 index 8776dfc0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_temporal_filter_constants.h +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_TEMPORAL_FILTER_CONSTANTS_H_ -#define VPX_VP9_ENCODER_TEMPORAL_FILTER_CONSTANTS_H_ -#include "./vpx_config.h" - -// Division using multiplication and shifting. The C implementation does: -// modifier *= 3; -// modifier /= index; -// where 'modifier' is a set of summed values and 'index' is the number of -// summed values. -// -// This equation works out to (m * 3) / i which reduces to: -// m * 3/4 -// m * 1/2 -// m * 1/3 -// -// By pairing the multiply with a down shift by 16 (_mm_mulhi_epu16): -// m * C / 65536 -// we can create a C to replicate the division. -// -// m * 49152 / 65536 = m * 3/4 -// m * 32758 / 65536 = m * 1/2 -// m * 21846 / 65536 = m * 0.3333 -// -// These are loaded using an instruction expecting int16_t values but are used -// with _mm_mulhi_epu16(), which treats them as unsigned. -#define NEIGHBOR_CONSTANT_4 (int16_t)49152 -#define NEIGHBOR_CONSTANT_5 (int16_t)39322 -#define NEIGHBOR_CONSTANT_6 (int16_t)32768 -#define NEIGHBOR_CONSTANT_7 (int16_t)28087 -#define NEIGHBOR_CONSTANT_8 (int16_t)24576 -#define NEIGHBOR_CONSTANT_9 (int16_t)21846 -#define NEIGHBOR_CONSTANT_10 (int16_t)19661 -#define NEIGHBOR_CONSTANT_11 (int16_t)17874 -#define NEIGHBOR_CONSTANT_13 (int16_t)15124 - -DECLARE_ALIGNED(16, static const int16_t, LEFT_CORNER_NEIGHBORS_PLUS_1[8]) = { - NEIGHBOR_CONSTANT_5, NEIGHBOR_CONSTANT_7, NEIGHBOR_CONSTANT_7, - NEIGHBOR_CONSTANT_7, NEIGHBOR_CONSTANT_7, NEIGHBOR_CONSTANT_7, - NEIGHBOR_CONSTANT_7, NEIGHBOR_CONSTANT_7 -}; - -DECLARE_ALIGNED(16, static const int16_t, RIGHT_CORNER_NEIGHBORS_PLUS_1[8]) = { - NEIGHBOR_CONSTANT_7, NEIGHBOR_CONSTANT_7, NEIGHBOR_CONSTANT_7, - NEIGHBOR_CONSTANT_7, NEIGHBOR_CONSTANT_7, NEIGHBOR_CONSTANT_7, - NEIGHBOR_CONSTANT_7, NEIGHBOR_CONSTANT_5 -}; - -DECLARE_ALIGNED(16, static const int16_t, LEFT_EDGE_NEIGHBORS_PLUS_1[8]) = { - NEIGHBOR_CONSTANT_7, NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10 -}; - -DECLARE_ALIGNED(16, static const int16_t, RIGHT_EDGE_NEIGHBORS_PLUS_1[8]) = { - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_7 -}; - -DECLARE_ALIGNED(16, static const int16_t, MIDDLE_EDGE_NEIGHBORS_PLUS_1[8]) = { - NEIGHBOR_CONSTANT_7, NEIGHBOR_CONSTANT_7, NEIGHBOR_CONSTANT_7, - NEIGHBOR_CONSTANT_7, NEIGHBOR_CONSTANT_7, NEIGHBOR_CONSTANT_7, - NEIGHBOR_CONSTANT_7, NEIGHBOR_CONSTANT_7 -}; - -DECLARE_ALIGNED(16, static const int16_t, MIDDLE_CENTER_NEIGHBORS_PLUS_1[8]) = { - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10 -}; - -DECLARE_ALIGNED(16, static const int16_t, LEFT_CORNER_NEIGHBORS_PLUS_2[8]) = { - NEIGHBOR_CONSTANT_6, NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_8, - NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_8, - NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_8 -}; - -DECLARE_ALIGNED(16, static const int16_t, RIGHT_CORNER_NEIGHBORS_PLUS_2[8]) = { - NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_8, - NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_8, - NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_6 -}; - -DECLARE_ALIGNED(16, static const int16_t, LEFT_EDGE_NEIGHBORS_PLUS_2[8]) = { - NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_11, - NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_11, - NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_11 -}; - -DECLARE_ALIGNED(16, static const int16_t, RIGHT_EDGE_NEIGHBORS_PLUS_2[8]) = { - NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_11, - NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_11, - NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_8 -}; - -DECLARE_ALIGNED(16, static const int16_t, MIDDLE_EDGE_NEIGHBORS_PLUS_2[8]) = { - NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_8, - NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_8, - NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_8 -}; - -DECLARE_ALIGNED(16, static const int16_t, MIDDLE_CENTER_NEIGHBORS_PLUS_2[8]) = { - NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_11, - NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_11, - NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_11 -}; - -DECLARE_ALIGNED(16, static const int16_t, TWO_CORNER_NEIGHBORS_PLUS_2[8]) = { - NEIGHBOR_CONSTANT_6, NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_8, - NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_8, - NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_6 -}; - -DECLARE_ALIGNED(16, static const int16_t, TWO_EDGE_NEIGHBORS_PLUS_2[8]) = { - NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_11, - NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_11, - NEIGHBOR_CONSTANT_11, NEIGHBOR_CONSTANT_8 -}; - -DECLARE_ALIGNED(16, static const int16_t, LEFT_CORNER_NEIGHBORS_PLUS_4[8]) = { - NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10 -}; - -DECLARE_ALIGNED(16, static const int16_t, RIGHT_CORNER_NEIGHBORS_PLUS_4[8]) = { - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_8 -}; - -DECLARE_ALIGNED(16, static const int16_t, LEFT_EDGE_NEIGHBORS_PLUS_4[8]) = { - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_13, - NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_13, - NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_13 -}; - -DECLARE_ALIGNED(16, static const int16_t, RIGHT_EDGE_NEIGHBORS_PLUS_4[8]) = { - NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_13, - NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_13, - NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_10 -}; - -DECLARE_ALIGNED(16, static const int16_t, MIDDLE_EDGE_NEIGHBORS_PLUS_4[8]) = { - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10 -}; - -DECLARE_ALIGNED(16, static const int16_t, MIDDLE_CENTER_NEIGHBORS_PLUS_4[8]) = { - NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_13, - NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_13, - NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_13 -}; - -DECLARE_ALIGNED(16, static const int16_t, TWO_CORNER_NEIGHBORS_PLUS_4[8]) = { - NEIGHBOR_CONSTANT_8, NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_10, - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_8 -}; - -DECLARE_ALIGNED(16, static const int16_t, TWO_EDGE_NEIGHBORS_PLUS_4[8]) = { - NEIGHBOR_CONSTANT_10, NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_13, - NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_13, - NEIGHBOR_CONSTANT_13, NEIGHBOR_CONSTANT_10 -}; - -static const int16_t *const LUMA_LEFT_COLUMN_NEIGHBORS[2] = { - LEFT_CORNER_NEIGHBORS_PLUS_2, LEFT_EDGE_NEIGHBORS_PLUS_2 -}; - -static const int16_t *const LUMA_MIDDLE_COLUMN_NEIGHBORS[2] = { - MIDDLE_EDGE_NEIGHBORS_PLUS_2, MIDDLE_CENTER_NEIGHBORS_PLUS_2 -}; - -static const int16_t *const LUMA_RIGHT_COLUMN_NEIGHBORS[2] = { - RIGHT_CORNER_NEIGHBORS_PLUS_2, RIGHT_EDGE_NEIGHBORS_PLUS_2 -}; - -static const int16_t *const CHROMA_NO_SS_LEFT_COLUMN_NEIGHBORS[2] = { - LEFT_CORNER_NEIGHBORS_PLUS_1, LEFT_EDGE_NEIGHBORS_PLUS_1 -}; - -static const int16_t *const CHROMA_NO_SS_MIDDLE_COLUMN_NEIGHBORS[2] = { - MIDDLE_EDGE_NEIGHBORS_PLUS_1, MIDDLE_CENTER_NEIGHBORS_PLUS_1 -}; - -static const int16_t *const CHROMA_NO_SS_RIGHT_COLUMN_NEIGHBORS[2] = { - RIGHT_CORNER_NEIGHBORS_PLUS_1, RIGHT_EDGE_NEIGHBORS_PLUS_1 -}; - -static const int16_t *const CHROMA_SINGLE_SS_LEFT_COLUMN_NEIGHBORS[2] = { - LEFT_CORNER_NEIGHBORS_PLUS_2, LEFT_EDGE_NEIGHBORS_PLUS_2 -}; - -static const int16_t *const CHROMA_SINGLE_SS_MIDDLE_COLUMN_NEIGHBORS[2] = { - MIDDLE_EDGE_NEIGHBORS_PLUS_2, MIDDLE_CENTER_NEIGHBORS_PLUS_2 -}; - -static const int16_t *const CHROMA_SINGLE_SS_RIGHT_COLUMN_NEIGHBORS[2] = { - RIGHT_CORNER_NEIGHBORS_PLUS_2, RIGHT_EDGE_NEIGHBORS_PLUS_2 -}; - -static const int16_t *const CHROMA_SINGLE_SS_SINGLE_COLUMN_NEIGHBORS[2] = { - TWO_CORNER_NEIGHBORS_PLUS_2, TWO_EDGE_NEIGHBORS_PLUS_2 -}; - -static const int16_t *const CHROMA_DOUBLE_SS_LEFT_COLUMN_NEIGHBORS[2] = { - LEFT_CORNER_NEIGHBORS_PLUS_4, LEFT_EDGE_NEIGHBORS_PLUS_4 -}; - -static const int16_t *const CHROMA_DOUBLE_SS_MIDDLE_COLUMN_NEIGHBORS[2] = { - MIDDLE_EDGE_NEIGHBORS_PLUS_4, MIDDLE_CENTER_NEIGHBORS_PLUS_4 -}; - -static const int16_t *const CHROMA_DOUBLE_SS_RIGHT_COLUMN_NEIGHBORS[2] = { - RIGHT_CORNER_NEIGHBORS_PLUS_4, RIGHT_EDGE_NEIGHBORS_PLUS_4 -}; - -static const int16_t *const CHROMA_DOUBLE_SS_SINGLE_COLUMN_NEIGHBORS[2] = { - TWO_CORNER_NEIGHBORS_PLUS_4, TWO_EDGE_NEIGHBORS_PLUS_4 -}; - -#if CONFIG_VP9_HIGHBITDEPTH -#define HIGHBD_NEIGHBOR_CONSTANT_4 (uint32_t)3221225472U -#define HIGHBD_NEIGHBOR_CONSTANT_5 (uint32_t)2576980378U -#define HIGHBD_NEIGHBOR_CONSTANT_6 (uint32_t)2147483648U -#define HIGHBD_NEIGHBOR_CONSTANT_7 (uint32_t)1840700270U -#define HIGHBD_NEIGHBOR_CONSTANT_8 (uint32_t)1610612736U -#define HIGHBD_NEIGHBOR_CONSTANT_9 (uint32_t)1431655766U -#define HIGHBD_NEIGHBOR_CONSTANT_10 (uint32_t)1288490189U -#define HIGHBD_NEIGHBOR_CONSTANT_11 (uint32_t)1171354718U -#define HIGHBD_NEIGHBOR_CONSTANT_13 (uint32_t)991146300U - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_LEFT_CORNER_NEIGHBORS_PLUS_1[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_5, HIGHBD_NEIGHBOR_CONSTANT_7, - HIGHBD_NEIGHBOR_CONSTANT_7, HIGHBD_NEIGHBOR_CONSTANT_7 -}; - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_RIGHT_CORNER_NEIGHBORS_PLUS_1[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_7, HIGHBD_NEIGHBOR_CONSTANT_7, - HIGHBD_NEIGHBOR_CONSTANT_7, HIGHBD_NEIGHBOR_CONSTANT_5 -}; - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_LEFT_EDGE_NEIGHBORS_PLUS_1[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_7, HIGHBD_NEIGHBOR_CONSTANT_10, - HIGHBD_NEIGHBOR_CONSTANT_10, HIGHBD_NEIGHBOR_CONSTANT_10 -}; - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_RIGHT_EDGE_NEIGHBORS_PLUS_1[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_10, HIGHBD_NEIGHBOR_CONSTANT_10, - HIGHBD_NEIGHBOR_CONSTANT_10, HIGHBD_NEIGHBOR_CONSTANT_7 -}; - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_MIDDLE_EDGE_NEIGHBORS_PLUS_1[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_7, HIGHBD_NEIGHBOR_CONSTANT_7, - HIGHBD_NEIGHBOR_CONSTANT_7, HIGHBD_NEIGHBOR_CONSTANT_7 -}; - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_MIDDLE_CENTER_NEIGHBORS_PLUS_1[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_10, HIGHBD_NEIGHBOR_CONSTANT_10, - HIGHBD_NEIGHBOR_CONSTANT_10, HIGHBD_NEIGHBOR_CONSTANT_10 -}; - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_LEFT_CORNER_NEIGHBORS_PLUS_2[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_6, HIGHBD_NEIGHBOR_CONSTANT_8, - HIGHBD_NEIGHBOR_CONSTANT_8, HIGHBD_NEIGHBOR_CONSTANT_8 -}; - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_RIGHT_CORNER_NEIGHBORS_PLUS_2[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_8, HIGHBD_NEIGHBOR_CONSTANT_8, - HIGHBD_NEIGHBOR_CONSTANT_8, HIGHBD_NEIGHBOR_CONSTANT_6 -}; - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_LEFT_EDGE_NEIGHBORS_PLUS_2[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_8, HIGHBD_NEIGHBOR_CONSTANT_11, - HIGHBD_NEIGHBOR_CONSTANT_11, HIGHBD_NEIGHBOR_CONSTANT_11 -}; - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_RIGHT_EDGE_NEIGHBORS_PLUS_2[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_11, HIGHBD_NEIGHBOR_CONSTANT_11, - HIGHBD_NEIGHBOR_CONSTANT_11, HIGHBD_NEIGHBOR_CONSTANT_8 -}; - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_MIDDLE_EDGE_NEIGHBORS_PLUS_2[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_8, HIGHBD_NEIGHBOR_CONSTANT_8, - HIGHBD_NEIGHBOR_CONSTANT_8, HIGHBD_NEIGHBOR_CONSTANT_8 -}; - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_MIDDLE_CENTER_NEIGHBORS_PLUS_2[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_11, HIGHBD_NEIGHBOR_CONSTANT_11, - HIGHBD_NEIGHBOR_CONSTANT_11, HIGHBD_NEIGHBOR_CONSTANT_11 -}; - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_LEFT_CORNER_NEIGHBORS_PLUS_4[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_8, HIGHBD_NEIGHBOR_CONSTANT_10, - HIGHBD_NEIGHBOR_CONSTANT_10, HIGHBD_NEIGHBOR_CONSTANT_10 -}; - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_RIGHT_CORNER_NEIGHBORS_PLUS_4[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_10, HIGHBD_NEIGHBOR_CONSTANT_10, - HIGHBD_NEIGHBOR_CONSTANT_10, HIGHBD_NEIGHBOR_CONSTANT_8 -}; - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_LEFT_EDGE_NEIGHBORS_PLUS_4[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_10, HIGHBD_NEIGHBOR_CONSTANT_13, - HIGHBD_NEIGHBOR_CONSTANT_13, HIGHBD_NEIGHBOR_CONSTANT_13 -}; - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_RIGHT_EDGE_NEIGHBORS_PLUS_4[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_13, HIGHBD_NEIGHBOR_CONSTANT_13, - HIGHBD_NEIGHBOR_CONSTANT_13, HIGHBD_NEIGHBOR_CONSTANT_10 -}; - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_MIDDLE_EDGE_NEIGHBORS_PLUS_4[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_10, HIGHBD_NEIGHBOR_CONSTANT_10, - HIGHBD_NEIGHBOR_CONSTANT_10, HIGHBD_NEIGHBOR_CONSTANT_10 -}; - -DECLARE_ALIGNED(16, static const uint32_t, - HIGHBD_MIDDLE_CENTER_NEIGHBORS_PLUS_4[4]) = { - HIGHBD_NEIGHBOR_CONSTANT_13, HIGHBD_NEIGHBOR_CONSTANT_13, - HIGHBD_NEIGHBOR_CONSTANT_13, HIGHBD_NEIGHBOR_CONSTANT_13 -}; - -static const uint32_t *const HIGHBD_LUMA_LEFT_COLUMN_NEIGHBORS[2] = { - HIGHBD_LEFT_CORNER_NEIGHBORS_PLUS_2, HIGHBD_LEFT_EDGE_NEIGHBORS_PLUS_2 -}; - -static const uint32_t *const HIGHBD_LUMA_MIDDLE_COLUMN_NEIGHBORS[2] = { - HIGHBD_MIDDLE_EDGE_NEIGHBORS_PLUS_2, HIGHBD_MIDDLE_CENTER_NEIGHBORS_PLUS_2 -}; - -static const uint32_t *const HIGHBD_LUMA_RIGHT_COLUMN_NEIGHBORS[2] = { - HIGHBD_RIGHT_CORNER_NEIGHBORS_PLUS_2, HIGHBD_RIGHT_EDGE_NEIGHBORS_PLUS_2 -}; - -static const uint32_t *const HIGHBD_CHROMA_NO_SS_LEFT_COLUMN_NEIGHBORS[2] = { - HIGHBD_LEFT_CORNER_NEIGHBORS_PLUS_1, HIGHBD_LEFT_EDGE_NEIGHBORS_PLUS_1 -}; - -static const uint32_t *const HIGHBD_CHROMA_NO_SS_MIDDLE_COLUMN_NEIGHBORS[2] = { - HIGHBD_MIDDLE_EDGE_NEIGHBORS_PLUS_1, HIGHBD_MIDDLE_CENTER_NEIGHBORS_PLUS_1 -}; - -static const uint32_t *const HIGHBD_CHROMA_NO_SS_RIGHT_COLUMN_NEIGHBORS[2] = { - HIGHBD_RIGHT_CORNER_NEIGHBORS_PLUS_1, HIGHBD_RIGHT_EDGE_NEIGHBORS_PLUS_1 -}; - -static const uint32_t - *const HIGHBD_CHROMA_SINGLE_SS_LEFT_COLUMN_NEIGHBORS[2] = { - HIGHBD_LEFT_CORNER_NEIGHBORS_PLUS_2, HIGHBD_LEFT_EDGE_NEIGHBORS_PLUS_2 - }; - -static const uint32_t - *const HIGHBD_CHROMA_SINGLE_SS_MIDDLE_COLUMN_NEIGHBORS[2] = { - HIGHBD_MIDDLE_EDGE_NEIGHBORS_PLUS_2, HIGHBD_MIDDLE_CENTER_NEIGHBORS_PLUS_2 - }; - -static const uint32_t - *const HIGHBD_CHROMA_SINGLE_SS_RIGHT_COLUMN_NEIGHBORS[2] = { - HIGHBD_RIGHT_CORNER_NEIGHBORS_PLUS_2, HIGHBD_RIGHT_EDGE_NEIGHBORS_PLUS_2 - }; - -static const uint32_t - *const HIGHBD_CHROMA_DOUBLE_SS_LEFT_COLUMN_NEIGHBORS[2] = { - HIGHBD_LEFT_CORNER_NEIGHBORS_PLUS_4, HIGHBD_LEFT_EDGE_NEIGHBORS_PLUS_4 - }; - -static const uint32_t - *const HIGHBD_CHROMA_DOUBLE_SS_MIDDLE_COLUMN_NEIGHBORS[2] = { - HIGHBD_MIDDLE_EDGE_NEIGHBORS_PLUS_4, HIGHBD_MIDDLE_CENTER_NEIGHBORS_PLUS_4 - }; - -static const uint32_t - *const HIGHBD_CHROMA_DOUBLE_SS_RIGHT_COLUMN_NEIGHBORS[2] = { - HIGHBD_RIGHT_CORNER_NEIGHBORS_PLUS_4, HIGHBD_RIGHT_EDGE_NEIGHBORS_PLUS_4 - }; -#endif // CONFIG_VP9_HIGHBITDEPTH - -#define DIST_STRIDE ((BW) + 2) - -#endif // VPX_VP9_ENCODER_TEMPORAL_FILTER_CONSTANTS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_tokenize.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_tokenize.c deleted file mode 100644 index 6c6c0449..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_tokenize.c +++ /dev/null @@ -1,490 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "vpx_mem/vpx_mem.h" - -#include "vp9/common/vp9_entropy.h" -#include "vp9/common/vp9_pred_common.h" -#include "vp9/common/vp9_scan.h" - -#include "vp9/encoder/vp9_cost.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_tokenize.h" - -static const TOKENVALUE dct_cat_lt_10_value_tokens[] = { - { 9, 63 }, { 9, 61 }, { 9, 59 }, { 9, 57 }, { 9, 55 }, { 9, 53 }, { 9, 51 }, - { 9, 49 }, { 9, 47 }, { 9, 45 }, { 9, 43 }, { 9, 41 }, { 9, 39 }, { 9, 37 }, - { 9, 35 }, { 9, 33 }, { 9, 31 }, { 9, 29 }, { 9, 27 }, { 9, 25 }, { 9, 23 }, - { 9, 21 }, { 9, 19 }, { 9, 17 }, { 9, 15 }, { 9, 13 }, { 9, 11 }, { 9, 9 }, - { 9, 7 }, { 9, 5 }, { 9, 3 }, { 9, 1 }, { 8, 31 }, { 8, 29 }, { 8, 27 }, - { 8, 25 }, { 8, 23 }, { 8, 21 }, { 8, 19 }, { 8, 17 }, { 8, 15 }, { 8, 13 }, - { 8, 11 }, { 8, 9 }, { 8, 7 }, { 8, 5 }, { 8, 3 }, { 8, 1 }, { 7, 15 }, - { 7, 13 }, { 7, 11 }, { 7, 9 }, { 7, 7 }, { 7, 5 }, { 7, 3 }, { 7, 1 }, - { 6, 7 }, { 6, 5 }, { 6, 3 }, { 6, 1 }, { 5, 3 }, { 5, 1 }, { 4, 1 }, - { 3, 1 }, { 2, 1 }, { 1, 1 }, { 0, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 }, - { 4, 0 }, { 5, 0 }, { 5, 2 }, { 6, 0 }, { 6, 2 }, { 6, 4 }, { 6, 6 }, - { 7, 0 }, { 7, 2 }, { 7, 4 }, { 7, 6 }, { 7, 8 }, { 7, 10 }, { 7, 12 }, - { 7, 14 }, { 8, 0 }, { 8, 2 }, { 8, 4 }, { 8, 6 }, { 8, 8 }, { 8, 10 }, - { 8, 12 }, { 8, 14 }, { 8, 16 }, { 8, 18 }, { 8, 20 }, { 8, 22 }, { 8, 24 }, - { 8, 26 }, { 8, 28 }, { 8, 30 }, { 9, 0 }, { 9, 2 }, { 9, 4 }, { 9, 6 }, - { 9, 8 }, { 9, 10 }, { 9, 12 }, { 9, 14 }, { 9, 16 }, { 9, 18 }, { 9, 20 }, - { 9, 22 }, { 9, 24 }, { 9, 26 }, { 9, 28 }, { 9, 30 }, { 9, 32 }, { 9, 34 }, - { 9, 36 }, { 9, 38 }, { 9, 40 }, { 9, 42 }, { 9, 44 }, { 9, 46 }, { 9, 48 }, - { 9, 50 }, { 9, 52 }, { 9, 54 }, { 9, 56 }, { 9, 58 }, { 9, 60 }, { 9, 62 } -}; -const TOKENVALUE *vp9_dct_cat_lt_10_value_tokens = - dct_cat_lt_10_value_tokens + - (sizeof(dct_cat_lt_10_value_tokens) / sizeof(*dct_cat_lt_10_value_tokens)) / - 2; -// The corresponding costs of the extrabits for the tokens in the above table -// are stored in the table below. The values are obtained from looking up the -// entry for the specified extrabits in the table corresponding to the token -// (as defined in cost element vp9_extra_bits) -// e.g. {9, 63} maps to cat5_cost[63 >> 1], {1, 1} maps to sign_cost[1 >> 1] -static const int dct_cat_lt_10_value_cost[] = { - 3773, 3750, 3704, 3681, 3623, 3600, 3554, 3531, 3432, 3409, 3363, 3340, 3282, - 3259, 3213, 3190, 3136, 3113, 3067, 3044, 2986, 2963, 2917, 2894, 2795, 2772, - 2726, 2703, 2645, 2622, 2576, 2553, 3197, 3116, 3058, 2977, 2881, 2800, 2742, - 2661, 2615, 2534, 2476, 2395, 2299, 2218, 2160, 2079, 2566, 2427, 2334, 2195, - 2023, 1884, 1791, 1652, 1893, 1696, 1453, 1256, 1229, 864, 512, 512, 512, - 512, 0, 512, 512, 512, 512, 864, 1229, 1256, 1453, 1696, 1893, 1652, - 1791, 1884, 2023, 2195, 2334, 2427, 2566, 2079, 2160, 2218, 2299, 2395, 2476, - 2534, 2615, 2661, 2742, 2800, 2881, 2977, 3058, 3116, 3197, 2553, 2576, 2622, - 2645, 2703, 2726, 2772, 2795, 2894, 2917, 2963, 2986, 3044, 3067, 3113, 3136, - 3190, 3213, 3259, 3282, 3340, 3363, 3409, 3432, 3531, 3554, 3600, 3623, 3681, - 3704, 3750, 3773, -}; -const int *vp9_dct_cat_lt_10_value_cost = - dct_cat_lt_10_value_cost + - (sizeof(dct_cat_lt_10_value_cost) / sizeof(*dct_cat_lt_10_value_cost)) / 2; - -// Array indices are identical to previously-existing CONTEXT_NODE indices -/* clang-format off */ -const vpx_tree_index vp9_coef_tree[TREE_SIZE(ENTROPY_TOKENS)] = { - -EOB_TOKEN, 2, // 0 = EOB - -ZERO_TOKEN, 4, // 1 = ZERO - -ONE_TOKEN, 6, // 2 = ONE - 8, 12, // 3 = LOW_VAL - -TWO_TOKEN, 10, // 4 = TWO - -THREE_TOKEN, -FOUR_TOKEN, // 5 = THREE - 14, 16, // 6 = HIGH_LOW - -CATEGORY1_TOKEN, -CATEGORY2_TOKEN, // 7 = CAT_ONE - 18, 20, // 8 = CAT_THREEFOUR - -CATEGORY3_TOKEN, -CATEGORY4_TOKEN, // 9 = CAT_THREE - -CATEGORY5_TOKEN, -CATEGORY6_TOKEN // 10 = CAT_FIVE -}; -/* clang-format on */ - -static const int16_t zero_cost[] = { 0 }; -static const int16_t sign_cost[1] = { 512 }; -static const int16_t cat1_cost[1 << 1] = { 864, 1229 }; -static const int16_t cat2_cost[1 << 2] = { 1256, 1453, 1696, 1893 }; -static const int16_t cat3_cost[1 << 3] = { 1652, 1791, 1884, 2023, - 2195, 2334, 2427, 2566 }; -static const int16_t cat4_cost[1 << 4] = { 2079, 2160, 2218, 2299, 2395, 2476, - 2534, 2615, 2661, 2742, 2800, 2881, - 2977, 3058, 3116, 3197 }; -static const int16_t cat5_cost[1 << 5] = { - 2553, 2576, 2622, 2645, 2703, 2726, 2772, 2795, 2894, 2917, 2963, - 2986, 3044, 3067, 3113, 3136, 3190, 3213, 3259, 3282, 3340, 3363, - 3409, 3432, 3531, 3554, 3600, 3623, 3681, 3704, 3750, 3773 -}; -const int16_t vp9_cat6_low_cost[256] = { - 3378, 3390, 3401, 3413, 3435, 3447, 3458, 3470, 3517, 3529, 3540, 3552, 3574, - 3586, 3597, 3609, 3671, 3683, 3694, 3706, 3728, 3740, 3751, 3763, 3810, 3822, - 3833, 3845, 3867, 3879, 3890, 3902, 3973, 3985, 3996, 4008, 4030, 4042, 4053, - 4065, 4112, 4124, 4135, 4147, 4169, 4181, 4192, 4204, 4266, 4278, 4289, 4301, - 4323, 4335, 4346, 4358, 4405, 4417, 4428, 4440, 4462, 4474, 4485, 4497, 4253, - 4265, 4276, 4288, 4310, 4322, 4333, 4345, 4392, 4404, 4415, 4427, 4449, 4461, - 4472, 4484, 4546, 4558, 4569, 4581, 4603, 4615, 4626, 4638, 4685, 4697, 4708, - 4720, 4742, 4754, 4765, 4777, 4848, 4860, 4871, 4883, 4905, 4917, 4928, 4940, - 4987, 4999, 5010, 5022, 5044, 5056, 5067, 5079, 5141, 5153, 5164, 5176, 5198, - 5210, 5221, 5233, 5280, 5292, 5303, 5315, 5337, 5349, 5360, 5372, 4988, 5000, - 5011, 5023, 5045, 5057, 5068, 5080, 5127, 5139, 5150, 5162, 5184, 5196, 5207, - 5219, 5281, 5293, 5304, 5316, 5338, 5350, 5361, 5373, 5420, 5432, 5443, 5455, - 5477, 5489, 5500, 5512, 5583, 5595, 5606, 5618, 5640, 5652, 5663, 5675, 5722, - 5734, 5745, 5757, 5779, 5791, 5802, 5814, 5876, 5888, 5899, 5911, 5933, 5945, - 5956, 5968, 6015, 6027, 6038, 6050, 6072, 6084, 6095, 6107, 5863, 5875, 5886, - 5898, 5920, 5932, 5943, 5955, 6002, 6014, 6025, 6037, 6059, 6071, 6082, 6094, - 6156, 6168, 6179, 6191, 6213, 6225, 6236, 6248, 6295, 6307, 6318, 6330, 6352, - 6364, 6375, 6387, 6458, 6470, 6481, 6493, 6515, 6527, 6538, 6550, 6597, 6609, - 6620, 6632, 6654, 6666, 6677, 6689, 6751, 6763, 6774, 6786, 6808, 6820, 6831, - 6843, 6890, 6902, 6913, 6925, 6947, 6959, 6970, 6982 -}; -const uint16_t vp9_cat6_high_cost[64] = { - 88, 2251, 2727, 4890, 3148, 5311, 5787, 7950, 3666, 5829, 6305, - 8468, 6726, 8889, 9365, 11528, 3666, 5829, 6305, 8468, 6726, 8889, - 9365, 11528, 7244, 9407, 9883, 12046, 10304, 12467, 12943, 15106, 3666, - 5829, 6305, 8468, 6726, 8889, 9365, 11528, 7244, 9407, 9883, 12046, - 10304, 12467, 12943, 15106, 7244, 9407, 9883, 12046, 10304, 12467, 12943, - 15106, 10822, 12985, 13461, 15624, 13882, 16045, 16521, 18684 -}; - -#if CONFIG_VP9_HIGHBITDEPTH -const uint16_t vp9_cat6_high10_high_cost[256] = { - 94, 2257, 2733, 4896, 3154, 5317, 5793, 7956, 3672, 5835, 6311, - 8474, 6732, 8895, 9371, 11534, 3672, 5835, 6311, 8474, 6732, 8895, - 9371, 11534, 7250, 9413, 9889, 12052, 10310, 12473, 12949, 15112, 3672, - 5835, 6311, 8474, 6732, 8895, 9371, 11534, 7250, 9413, 9889, 12052, - 10310, 12473, 12949, 15112, 7250, 9413, 9889, 12052, 10310, 12473, 12949, - 15112, 10828, 12991, 13467, 15630, 13888, 16051, 16527, 18690, 4187, 6350, - 6826, 8989, 7247, 9410, 9886, 12049, 7765, 9928, 10404, 12567, 10825, - 12988, 13464, 15627, 7765, 9928, 10404, 12567, 10825, 12988, 13464, 15627, - 11343, 13506, 13982, 16145, 14403, 16566, 17042, 19205, 7765, 9928, 10404, - 12567, 10825, 12988, 13464, 15627, 11343, 13506, 13982, 16145, 14403, 16566, - 17042, 19205, 11343, 13506, 13982, 16145, 14403, 16566, 17042, 19205, 14921, - 17084, 17560, 19723, 17981, 20144, 20620, 22783, 4187, 6350, 6826, 8989, - 7247, 9410, 9886, 12049, 7765, 9928, 10404, 12567, 10825, 12988, 13464, - 15627, 7765, 9928, 10404, 12567, 10825, 12988, 13464, 15627, 11343, 13506, - 13982, 16145, 14403, 16566, 17042, 19205, 7765, 9928, 10404, 12567, 10825, - 12988, 13464, 15627, 11343, 13506, 13982, 16145, 14403, 16566, 17042, 19205, - 11343, 13506, 13982, 16145, 14403, 16566, 17042, 19205, 14921, 17084, 17560, - 19723, 17981, 20144, 20620, 22783, 8280, 10443, 10919, 13082, 11340, 13503, - 13979, 16142, 11858, 14021, 14497, 16660, 14918, 17081, 17557, 19720, 11858, - 14021, 14497, 16660, 14918, 17081, 17557, 19720, 15436, 17599, 18075, 20238, - 18496, 20659, 21135, 23298, 11858, 14021, 14497, 16660, 14918, 17081, 17557, - 19720, 15436, 17599, 18075, 20238, 18496, 20659, 21135, 23298, 15436, 17599, - 18075, 20238, 18496, 20659, 21135, 23298, 19014, 21177, 21653, 23816, 22074, - 24237, 24713, 26876 -}; -const uint16_t vp9_cat6_high12_high_cost[1024] = { - 100, 2263, 2739, 4902, 3160, 5323, 5799, 7962, 3678, 5841, 6317, - 8480, 6738, 8901, 9377, 11540, 3678, 5841, 6317, 8480, 6738, 8901, - 9377, 11540, 7256, 9419, 9895, 12058, 10316, 12479, 12955, 15118, 3678, - 5841, 6317, 8480, 6738, 8901, 9377, 11540, 7256, 9419, 9895, 12058, - 10316, 12479, 12955, 15118, 7256, 9419, 9895, 12058, 10316, 12479, 12955, - 15118, 10834, 12997, 13473, 15636, 13894, 16057, 16533, 18696, 4193, 6356, - 6832, 8995, 7253, 9416, 9892, 12055, 7771, 9934, 10410, 12573, 10831, - 12994, 13470, 15633, 7771, 9934, 10410, 12573, 10831, 12994, 13470, 15633, - 11349, 13512, 13988, 16151, 14409, 16572, 17048, 19211, 7771, 9934, 10410, - 12573, 10831, 12994, 13470, 15633, 11349, 13512, 13988, 16151, 14409, 16572, - 17048, 19211, 11349, 13512, 13988, 16151, 14409, 16572, 17048, 19211, 14927, - 17090, 17566, 19729, 17987, 20150, 20626, 22789, 4193, 6356, 6832, 8995, - 7253, 9416, 9892, 12055, 7771, 9934, 10410, 12573, 10831, 12994, 13470, - 15633, 7771, 9934, 10410, 12573, 10831, 12994, 13470, 15633, 11349, 13512, - 13988, 16151, 14409, 16572, 17048, 19211, 7771, 9934, 10410, 12573, 10831, - 12994, 13470, 15633, 11349, 13512, 13988, 16151, 14409, 16572, 17048, 19211, - 11349, 13512, 13988, 16151, 14409, 16572, 17048, 19211, 14927, 17090, 17566, - 19729, 17987, 20150, 20626, 22789, 8286, 10449, 10925, 13088, 11346, 13509, - 13985, 16148, 11864, 14027, 14503, 16666, 14924, 17087, 17563, 19726, 11864, - 14027, 14503, 16666, 14924, 17087, 17563, 19726, 15442, 17605, 18081, 20244, - 18502, 20665, 21141, 23304, 11864, 14027, 14503, 16666, 14924, 17087, 17563, - 19726, 15442, 17605, 18081, 20244, 18502, 20665, 21141, 23304, 15442, 17605, - 18081, 20244, 18502, 20665, 21141, 23304, 19020, 21183, 21659, 23822, 22080, - 24243, 24719, 26882, 4193, 6356, 6832, 8995, 7253, 9416, 9892, 12055, - 7771, 9934, 10410, 12573, 10831, 12994, 13470, 15633, 7771, 9934, 10410, - 12573, 10831, 12994, 13470, 15633, 11349, 13512, 13988, 16151, 14409, 16572, - 17048, 19211, 7771, 9934, 10410, 12573, 10831, 12994, 13470, 15633, 11349, - 13512, 13988, 16151, 14409, 16572, 17048, 19211, 11349, 13512, 13988, 16151, - 14409, 16572, 17048, 19211, 14927, 17090, 17566, 19729, 17987, 20150, 20626, - 22789, 8286, 10449, 10925, 13088, 11346, 13509, 13985, 16148, 11864, 14027, - 14503, 16666, 14924, 17087, 17563, 19726, 11864, 14027, 14503, 16666, 14924, - 17087, 17563, 19726, 15442, 17605, 18081, 20244, 18502, 20665, 21141, 23304, - 11864, 14027, 14503, 16666, 14924, 17087, 17563, 19726, 15442, 17605, 18081, - 20244, 18502, 20665, 21141, 23304, 15442, 17605, 18081, 20244, 18502, 20665, - 21141, 23304, 19020, 21183, 21659, 23822, 22080, 24243, 24719, 26882, 8286, - 10449, 10925, 13088, 11346, 13509, 13985, 16148, 11864, 14027, 14503, 16666, - 14924, 17087, 17563, 19726, 11864, 14027, 14503, 16666, 14924, 17087, 17563, - 19726, 15442, 17605, 18081, 20244, 18502, 20665, 21141, 23304, 11864, 14027, - 14503, 16666, 14924, 17087, 17563, 19726, 15442, 17605, 18081, 20244, 18502, - 20665, 21141, 23304, 15442, 17605, 18081, 20244, 18502, 20665, 21141, 23304, - 19020, 21183, 21659, 23822, 22080, 24243, 24719, 26882, 12379, 14542, 15018, - 17181, 15439, 17602, 18078, 20241, 15957, 18120, 18596, 20759, 19017, 21180, - 21656, 23819, 15957, 18120, 18596, 20759, 19017, 21180, 21656, 23819, 19535, - 21698, 22174, 24337, 22595, 24758, 25234, 27397, 15957, 18120, 18596, 20759, - 19017, 21180, 21656, 23819, 19535, 21698, 22174, 24337, 22595, 24758, 25234, - 27397, 19535, 21698, 22174, 24337, 22595, 24758, 25234, 27397, 23113, 25276, - 25752, 27915, 26173, 28336, 28812, 30975, 4193, 6356, 6832, 8995, 7253, - 9416, 9892, 12055, 7771, 9934, 10410, 12573, 10831, 12994, 13470, 15633, - 7771, 9934, 10410, 12573, 10831, 12994, 13470, 15633, 11349, 13512, 13988, - 16151, 14409, 16572, 17048, 19211, 7771, 9934, 10410, 12573, 10831, 12994, - 13470, 15633, 11349, 13512, 13988, 16151, 14409, 16572, 17048, 19211, 11349, - 13512, 13988, 16151, 14409, 16572, 17048, 19211, 14927, 17090, 17566, 19729, - 17987, 20150, 20626, 22789, 8286, 10449, 10925, 13088, 11346, 13509, 13985, - 16148, 11864, 14027, 14503, 16666, 14924, 17087, 17563, 19726, 11864, 14027, - 14503, 16666, 14924, 17087, 17563, 19726, 15442, 17605, 18081, 20244, 18502, - 20665, 21141, 23304, 11864, 14027, 14503, 16666, 14924, 17087, 17563, 19726, - 15442, 17605, 18081, 20244, 18502, 20665, 21141, 23304, 15442, 17605, 18081, - 20244, 18502, 20665, 21141, 23304, 19020, 21183, 21659, 23822, 22080, 24243, - 24719, 26882, 8286, 10449, 10925, 13088, 11346, 13509, 13985, 16148, 11864, - 14027, 14503, 16666, 14924, 17087, 17563, 19726, 11864, 14027, 14503, 16666, - 14924, 17087, 17563, 19726, 15442, 17605, 18081, 20244, 18502, 20665, 21141, - 23304, 11864, 14027, 14503, 16666, 14924, 17087, 17563, 19726, 15442, 17605, - 18081, 20244, 18502, 20665, 21141, 23304, 15442, 17605, 18081, 20244, 18502, - 20665, 21141, 23304, 19020, 21183, 21659, 23822, 22080, 24243, 24719, 26882, - 12379, 14542, 15018, 17181, 15439, 17602, 18078, 20241, 15957, 18120, 18596, - 20759, 19017, 21180, 21656, 23819, 15957, 18120, 18596, 20759, 19017, 21180, - 21656, 23819, 19535, 21698, 22174, 24337, 22595, 24758, 25234, 27397, 15957, - 18120, 18596, 20759, 19017, 21180, 21656, 23819, 19535, 21698, 22174, 24337, - 22595, 24758, 25234, 27397, 19535, 21698, 22174, 24337, 22595, 24758, 25234, - 27397, 23113, 25276, 25752, 27915, 26173, 28336, 28812, 30975, 8286, 10449, - 10925, 13088, 11346, 13509, 13985, 16148, 11864, 14027, 14503, 16666, 14924, - 17087, 17563, 19726, 11864, 14027, 14503, 16666, 14924, 17087, 17563, 19726, - 15442, 17605, 18081, 20244, 18502, 20665, 21141, 23304, 11864, 14027, 14503, - 16666, 14924, 17087, 17563, 19726, 15442, 17605, 18081, 20244, 18502, 20665, - 21141, 23304, 15442, 17605, 18081, 20244, 18502, 20665, 21141, 23304, 19020, - 21183, 21659, 23822, 22080, 24243, 24719, 26882, 12379, 14542, 15018, 17181, - 15439, 17602, 18078, 20241, 15957, 18120, 18596, 20759, 19017, 21180, 21656, - 23819, 15957, 18120, 18596, 20759, 19017, 21180, 21656, 23819, 19535, 21698, - 22174, 24337, 22595, 24758, 25234, 27397, 15957, 18120, 18596, 20759, 19017, - 21180, 21656, 23819, 19535, 21698, 22174, 24337, 22595, 24758, 25234, 27397, - 19535, 21698, 22174, 24337, 22595, 24758, 25234, 27397, 23113, 25276, 25752, - 27915, 26173, 28336, 28812, 30975, 12379, 14542, 15018, 17181, 15439, 17602, - 18078, 20241, 15957, 18120, 18596, 20759, 19017, 21180, 21656, 23819, 15957, - 18120, 18596, 20759, 19017, 21180, 21656, 23819, 19535, 21698, 22174, 24337, - 22595, 24758, 25234, 27397, 15957, 18120, 18596, 20759, 19017, 21180, 21656, - 23819, 19535, 21698, 22174, 24337, 22595, 24758, 25234, 27397, 19535, 21698, - 22174, 24337, 22595, 24758, 25234, 27397, 23113, 25276, 25752, 27915, 26173, - 28336, 28812, 30975, 16472, 18635, 19111, 21274, 19532, 21695, 22171, 24334, - 20050, 22213, 22689, 24852, 23110, 25273, 25749, 27912, 20050, 22213, 22689, - 24852, 23110, 25273, 25749, 27912, 23628, 25791, 26267, 28430, 26688, 28851, - 29327, 31490, 20050, 22213, 22689, 24852, 23110, 25273, 25749, 27912, 23628, - 25791, 26267, 28430, 26688, 28851, 29327, 31490, 23628, 25791, 26267, 28430, - 26688, 28851, 29327, 31490, 27206, 29369, 29845, 32008, 30266, 32429, 32905, - 35068 -}; -#endif - -const vp9_extra_bit vp9_extra_bits[ENTROPY_TOKENS] = { - { 0, 0, 0, zero_cost }, // ZERO_TOKEN - { 0, 0, 1, sign_cost }, // ONE_TOKEN - { 0, 0, 2, sign_cost }, // TWO_TOKEN - { 0, 0, 3, sign_cost }, // THREE_TOKEN - { 0, 0, 4, sign_cost }, // FOUR_TOKEN - { vp9_cat1_prob, 1, CAT1_MIN_VAL, cat1_cost }, // CATEGORY1_TOKEN - { vp9_cat2_prob, 2, CAT2_MIN_VAL, cat2_cost }, // CATEGORY2_TOKEN - { vp9_cat3_prob, 3, CAT3_MIN_VAL, cat3_cost }, // CATEGORY3_TOKEN - { vp9_cat4_prob, 4, CAT4_MIN_VAL, cat4_cost }, // CATEGORY4_TOKEN - { vp9_cat5_prob, 5, CAT5_MIN_VAL, cat5_cost }, // CATEGORY5_TOKEN - { vp9_cat6_prob, 14, CAT6_MIN_VAL, 0 }, // CATEGORY6_TOKEN - { 0, 0, 0, zero_cost } // EOB_TOKEN -}; - -#if CONFIG_VP9_HIGHBITDEPTH -const vp9_extra_bit vp9_extra_bits_high10[ENTROPY_TOKENS] = { - { 0, 0, 0, zero_cost }, // ZERO - { 0, 0, 1, sign_cost }, // ONE - { 0, 0, 2, sign_cost }, // TWO - { 0, 0, 3, sign_cost }, // THREE - { 0, 0, 4, sign_cost }, // FOUR - { vp9_cat1_prob, 1, CAT1_MIN_VAL, cat1_cost }, // CAT1 - { vp9_cat2_prob, 2, CAT2_MIN_VAL, cat2_cost }, // CAT2 - { vp9_cat3_prob, 3, CAT3_MIN_VAL, cat3_cost }, // CAT3 - { vp9_cat4_prob, 4, CAT4_MIN_VAL, cat4_cost }, // CAT4 - { vp9_cat5_prob, 5, CAT5_MIN_VAL, cat5_cost }, // CAT5 - { vp9_cat6_prob_high12 + 2, 16, CAT6_MIN_VAL, 0 }, // CAT6 - { 0, 0, 0, zero_cost } // EOB -}; -const vp9_extra_bit vp9_extra_bits_high12[ENTROPY_TOKENS] = { - { 0, 0, 0, zero_cost }, // ZERO - { 0, 0, 1, sign_cost }, // ONE - { 0, 0, 2, sign_cost }, // TWO - { 0, 0, 3, sign_cost }, // THREE - { 0, 0, 4, sign_cost }, // FOUR - { vp9_cat1_prob, 1, CAT1_MIN_VAL, cat1_cost }, // CAT1 - { vp9_cat2_prob, 2, CAT2_MIN_VAL, cat2_cost }, // CAT2 - { vp9_cat3_prob, 3, CAT3_MIN_VAL, cat3_cost }, // CAT3 - { vp9_cat4_prob, 4, CAT4_MIN_VAL, cat4_cost }, // CAT4 - { vp9_cat5_prob, 5, CAT5_MIN_VAL, cat5_cost }, // CAT5 - { vp9_cat6_prob_high12, 18, CAT6_MIN_VAL, 0 }, // CAT6 - { 0, 0, 0, zero_cost } // EOB -}; -#endif - -const struct vp9_token vp9_coef_encodings[ENTROPY_TOKENS] = { - { 2, 2 }, { 6, 3 }, { 28, 5 }, { 58, 6 }, { 59, 6 }, { 60, 6 }, - { 61, 6 }, { 124, 7 }, { 125, 7 }, { 126, 7 }, { 127, 7 }, { 0, 1 } -}; - -struct tokenize_b_args { - VP9_COMP *cpi; - ThreadData *td; - TOKENEXTRA **tp; -}; - -static void set_entropy_context_b(int plane, int block, int row, int col, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size, - void *arg) { - struct tokenize_b_args *const args = arg; - ThreadData *const td = args->td; - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - struct macroblock_plane *p = &x->plane[plane]; - struct macroblockd_plane *pd = &xd->plane[plane]; - vp9_set_contexts(xd, pd, plane_bsize, tx_size, p->eobs[block] > 0, col, row); -} - -static INLINE void add_token(TOKENEXTRA **t, const vpx_prob *context_tree, - int16_t token, EXTRABIT extra, - unsigned int *counts) { - (*t)->context_tree = context_tree; - (*t)->token = token; - (*t)->extra = extra; - (*t)++; - ++counts[token]; -} - -static INLINE void add_token_no_extra(TOKENEXTRA **t, - const vpx_prob *context_tree, - int16_t token, unsigned int *counts) { - (*t)->context_tree = context_tree; - (*t)->token = token; - (*t)++; - ++counts[token]; -} - -static void tokenize_b(int plane, int block, int row, int col, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) { - struct tokenize_b_args *const args = arg; - VP9_COMP *cpi = args->cpi; - ThreadData *const td = args->td; - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - TOKENEXTRA **tp = args->tp; - uint8_t token_cache[32 * 32]; - struct macroblock_plane *p = &x->plane[plane]; - struct macroblockd_plane *pd = &xd->plane[plane]; - MODE_INFO *mi = xd->mi[0]; - int pt; /* near block/prev token context index */ - int c; - TOKENEXTRA *t = *tp; /* store tokens starting here */ - int eob = p->eobs[block]; - const PLANE_TYPE type = get_plane_type(plane); - const tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block); - const int16_t *scan, *nb; - const ScanOrder *so; - const int ref = is_inter_block(mi); - unsigned int(*const counts)[COEFF_CONTEXTS][ENTROPY_TOKENS] = - td->rd_counts.coef_counts[tx_size][type][ref]; - vpx_prob(*const coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] = - cpi->common.fc->coef_probs[tx_size][type][ref]; - unsigned int(*const eob_branch)[COEFF_CONTEXTS] = - td->counts->eob_branch[tx_size][type][ref]; - const uint8_t *const band = get_band_translate(tx_size); - const int tx_eob = 16 << (tx_size << 1); - int16_t token; - EXTRABIT extra; - pt = get_entropy_context(tx_size, pd->above_context + col, - pd->left_context + row); - so = get_scan(xd, tx_size, type, block); - scan = so->scan; - nb = so->neighbors; - c = 0; - - while (c < eob) { - int v = 0; - v = qcoeff[scan[c]]; - ++eob_branch[band[c]][pt]; - - while (!v) { - add_token_no_extra(&t, coef_probs[band[c]][pt], ZERO_TOKEN, - counts[band[c]][pt]); - - token_cache[scan[c]] = 0; - ++c; - pt = get_coef_context(nb, token_cache, c); - v = qcoeff[scan[c]]; - } - - vp9_get_token_extra(v, &token, &extra); - - add_token(&t, coef_probs[band[c]][pt], token, extra, counts[band[c]][pt]); - - token_cache[scan[c]] = vp9_pt_energy_class[token]; - ++c; - pt = get_coef_context(nb, token_cache, c); - } - if (c < tx_eob) { - ++eob_branch[band[c]][pt]; - add_token_no_extra(&t, coef_probs[band[c]][pt], EOB_TOKEN, - counts[band[c]][pt]); - } - - *tp = t; - - vp9_set_contexts(xd, pd, plane_bsize, tx_size, c > 0, col, row); -} - -struct is_skippable_args { - uint16_t *eobs; - int *skippable; -}; - -static void is_skippable(int plane, int block, int row, int col, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *argv) { - struct is_skippable_args *args = argv; - (void)plane; - (void)plane_bsize; - (void)tx_size; - (void)row; - (void)col; - args->skippable[0] &= (!args->eobs[block]); -} - -// TODO(yaowu): rewrite and optimize this function to remove the usage of -// vp9_foreach_transform_block() and simplify is_skippable(). -int vp9_is_skippable_in_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) { - int result = 1; - struct is_skippable_args args = { x->plane[plane].eobs, &result }; - vp9_foreach_transformed_block_in_plane(&x->e_mbd, bsize, plane, is_skippable, - &args); - return result; -} - -static void has_high_freq_coeff(int plane, int block, int row, int col, - BLOCK_SIZE plane_bsize, TX_SIZE tx_size, - void *argv) { - struct is_skippable_args *args = argv; - int eobs = (tx_size == TX_4X4) ? 3 : 10; - (void)plane; - (void)plane_bsize; - (void)row; - (void)col; - *(args->skippable) |= (args->eobs[block] > eobs); -} - -int vp9_has_high_freq_in_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) { - int result = 0; - struct is_skippable_args args = { x->plane[plane].eobs, &result }; - vp9_foreach_transformed_block_in_plane(&x->e_mbd, bsize, plane, - has_high_freq_coeff, &args); - return result; -} - -void vp9_tokenize_sb(VP9_COMP *cpi, ThreadData *td, TOKENEXTRA **t, int dry_run, - int seg_skip, BLOCK_SIZE bsize) { - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - MODE_INFO *const mi = xd->mi[0]; - const int ctx = vp9_get_skip_context(xd); - struct tokenize_b_args arg = { cpi, td, t }; - - if (seg_skip) { - assert(mi->skip); - } - - if (mi->skip) { - if (!dry_run && !seg_skip) ++td->counts->skip[ctx][1]; - reset_skip_context(xd, bsize); - return; - } - - if (!dry_run) { - ++td->counts->skip[ctx][0]; - vp9_foreach_transformed_block(xd, bsize, tokenize_b, &arg); - } else { - vp9_foreach_transformed_block(xd, bsize, set_entropy_context_b, &arg); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_tokenize.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_tokenize.h deleted file mode 100644 index 6407ff92..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_tokenize.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_TOKENIZE_H_ -#define VPX_VP9_ENCODER_VP9_TOKENIZE_H_ - -#include "vp9/common/vp9_entropy.h" - -#include "vp9/encoder/vp9_block.h" -#include "vp9/encoder/vp9_treewriter.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define EOSB_TOKEN 127 // Not signalled, encoder only - -#if CONFIG_VP9_HIGHBITDEPTH -typedef int32_t EXTRABIT; -#else -typedef int16_t EXTRABIT; -#endif - -typedef struct { - int16_t token; - EXTRABIT extra; -} TOKENVALUE; - -typedef struct { - const vpx_prob *context_tree; - int16_t token; - EXTRABIT extra; -} TOKENEXTRA; - -extern const vpx_tree_index vp9_coef_tree[]; -extern const vpx_tree_index vp9_coef_con_tree[]; -extern const struct vp9_token vp9_coef_encodings[]; - -int vp9_is_skippable_in_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane); -int vp9_has_high_freq_in_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane); - -struct VP9_COMP; -struct ThreadData; - -void vp9_tokenize_sb(struct VP9_COMP *cpi, struct ThreadData *td, - TOKENEXTRA **t, int dry_run, int seg_skip, - BLOCK_SIZE bsize); - -typedef struct { - const vpx_prob *prob; - int len; - int base_val; - const int16_t *cost; -} vp9_extra_bit; - -// indexed by token value -extern const vp9_extra_bit vp9_extra_bits[ENTROPY_TOKENS]; -#if CONFIG_VP9_HIGHBITDEPTH -extern const vp9_extra_bit vp9_extra_bits_high10[ENTROPY_TOKENS]; -extern const vp9_extra_bit vp9_extra_bits_high12[ENTROPY_TOKENS]; -#endif // CONFIG_VP9_HIGHBITDEPTH - -extern const int16_t *vp9_dct_value_cost_ptr; -/* TODO: The Token field should be broken out into a separate char array to - * improve cache locality, since it's needed for costing when the rest of the - * fields are not. - */ -extern const TOKENVALUE *vp9_dct_value_tokens_ptr; -extern const TOKENVALUE *vp9_dct_cat_lt_10_value_tokens; -extern const int *vp9_dct_cat_lt_10_value_cost; -extern const int16_t vp9_cat6_low_cost[256]; -extern const uint16_t vp9_cat6_high_cost[64]; -extern const uint16_t vp9_cat6_high10_high_cost[256]; -extern const uint16_t vp9_cat6_high12_high_cost[1024]; - -#if CONFIG_VP9_HIGHBITDEPTH -static INLINE const uint16_t *vp9_get_high_cost_table(int bit_depth) { - return bit_depth == 8 ? vp9_cat6_high_cost - : (bit_depth == 10 ? vp9_cat6_high10_high_cost - : vp9_cat6_high12_high_cost); -} -#else -static INLINE const uint16_t *vp9_get_high_cost_table(int bit_depth) { - (void)bit_depth; - return vp9_cat6_high_cost; -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static INLINE void vp9_get_token_extra(int v, int16_t *token, EXTRABIT *extra) { - if (v >= CAT6_MIN_VAL || v <= -CAT6_MIN_VAL) { - *token = CATEGORY6_TOKEN; - if (v >= CAT6_MIN_VAL) - *extra = 2 * v - 2 * CAT6_MIN_VAL; - else - *extra = -2 * v - 2 * CAT6_MIN_VAL + 1; - return; - } - *token = vp9_dct_cat_lt_10_value_tokens[v].token; - *extra = vp9_dct_cat_lt_10_value_tokens[v].extra; -} -static INLINE int16_t vp9_get_token(int v) { - if (v >= CAT6_MIN_VAL || v <= -CAT6_MIN_VAL) return 10; - return vp9_dct_cat_lt_10_value_tokens[v].token; -} - -static INLINE int vp9_get_token_cost(int v, int16_t *token, - const uint16_t *cat6_high_table) { - if (v >= CAT6_MIN_VAL || v <= -CAT6_MIN_VAL) { - EXTRABIT extrabits; - *token = CATEGORY6_TOKEN; - extrabits = abs(v) - CAT6_MIN_VAL; - return vp9_cat6_low_cost[extrabits & 0xff] + - cat6_high_table[extrabits >> 8]; - } - *token = vp9_dct_cat_lt_10_value_tokens[v].token; - return vp9_dct_cat_lt_10_value_cost[v]; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_TOKENIZE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_tpl_model.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_tpl_model.c deleted file mode 100644 index c40d71e3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_tpl_model.c +++ /dev/null @@ -1,1813 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#if CONFIG_NON_GREEDY_MV -#include "vp9/common/vp9_mvref_common.h" -#endif -#include "vp9/common/vp9_reconinter.h" -#include "vp9/common/vp9_reconintra.h" -#include "vp9/common/vp9_scan.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_ext_ratectrl.h" -#include "vp9/encoder/vp9_firstpass.h" -#include "vp9/encoder/vp9_ratectrl.h" -#include "vp9/encoder/vp9_tpl_model.h" -#include "vpx/internal/vpx_codec_internal.h" -#include "vpx/vpx_codec.h" -#include "vpx/vpx_ext_ratectrl.h" - -static int init_gop_frames_rc(VP9_COMP *cpi, GF_PICTURE *gf_picture, - const GF_GROUP *gf_group, int *tpl_group_frames) { - VP9_COMMON *cm = &cpi->common; - int frame_idx = 0; - int i; - int extend_frame_count = 0; - int pframe_qindex = cpi->tpl_stats[2].base_qindex; - int frame_gop_offset = 0; - - int added_overlay = 0; - - RefCntBuffer *frame_bufs = cm->buffer_pool->frame_bufs; - int8_t recon_frame_index[REFS_PER_FRAME + MAX_ARF_LAYERS]; - - memset(recon_frame_index, -1, sizeof(recon_frame_index)); - - for (i = 0; i < FRAME_BUFFERS; ++i) { - if (frame_bufs[i].ref_count == 0) { - alloc_frame_mvs(cm, i); - if (vpx_realloc_frame_buffer(&frame_bufs[i].buf, cm->width, cm->height, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment, - NULL, NULL, NULL)) - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate frame buffer"); - - recon_frame_index[frame_idx] = i; - ++frame_idx; - - if (frame_idx >= REFS_PER_FRAME + cpi->oxcf.enable_auto_arf) break; - } - } - - for (i = 0; i < REFS_PER_FRAME + 1; ++i) { - assert(recon_frame_index[i] >= 0); - cpi->tpl_recon_frames[i] = &frame_bufs[recon_frame_index[i]].buf; - } - - *tpl_group_frames = 0; - - int ref_table[3]; - - if (gf_group->index == 1 && gf_group->update_type[1] == ARF_UPDATE) { - if (gf_group->update_type[0] == KF_UPDATE) { - // This is the only frame in ref buffer. We need it to be on - // gf_picture[0]. - for (i = 0; i < 3; ++i) ref_table[i] = -REFS_PER_FRAME; - - gf_picture[0].frame = - &cm->buffer_pool->frame_bufs[gf_group->update_ref_idx[0]].buf; - ref_table[gf_group->update_ref_idx[0]] = 0; - - for (i = 0; i < 3; ++i) gf_picture[0].ref_frame[i] = -REFS_PER_FRAME; - gf_picture[0].update_type = gf_group->update_type[0]; - } else { - for (i = 0; i < REFS_PER_FRAME; i++) { - if (cm->ref_frame_map[i] != -1) { - gf_picture[-i].frame = - &cm->buffer_pool->frame_bufs[cm->ref_frame_map[i]].buf; - ref_table[i] = -i; - } else { - ref_table[i] = -REFS_PER_FRAME; - } - } - for (i = 0; i < 3; ++i) { - gf_picture[0].ref_frame[i] = ref_table[i]; - } - } - ++*tpl_group_frames; - - // Initialize base layer ARF frame - gf_picture[1].frame = cpi->Source; - for (i = 0; i < 3; ++i) gf_picture[1].ref_frame[i] = ref_table[i]; - gf_picture[1].update_type = gf_group->update_type[1]; - ref_table[gf_group->update_ref_idx[1]] = 1; - - ++*tpl_group_frames; - } else { - assert(gf_group->index == 0); - if (gf_group->update_type[0] == KF_UPDATE) { - // This is the only frame in ref buffer. We need it to be on - // gf_picture[0]. - gf_picture[0].frame = cpi->Source; - for (i = 0; i < 3; ++i) gf_picture[0].ref_frame[i] = -REFS_PER_FRAME; - gf_picture[0].update_type = gf_group->update_type[0]; - - for (i = 0; i < 3; ++i) ref_table[i] = -REFS_PER_FRAME; - ref_table[gf_group->update_ref_idx[0]] = 0; - } else { - // Initialize ref table - for (i = 0; i < REFS_PER_FRAME; i++) { - if (cm->ref_frame_map[i] != -1) { - gf_picture[-i].frame = - &cm->buffer_pool->frame_bufs[cm->ref_frame_map[i]].buf; - ref_table[i] = -i; - } else { - ref_table[i] = -REFS_PER_FRAME; - } - } - for (i = 0; i < 3; ++i) { - gf_picture[0].ref_frame[i] = ref_table[i]; - } - gf_picture[0].update_type = gf_group->update_type[0]; - if (gf_group->update_type[0] != OVERLAY_UPDATE && - gf_group->update_ref_idx[0] != -1) { - ref_table[gf_group->update_ref_idx[0]] = 0; - } - } - ++*tpl_group_frames; - } - - int has_arf = - gf_group->gf_group_size > 1 && gf_group->update_type[1] == ARF_UPDATE && - gf_group->update_type[gf_group->gf_group_size] == OVERLAY_UPDATE; - - // Initialize P frames - for (frame_idx = *tpl_group_frames; frame_idx < MAX_ARF_GOP_SIZE; - ++frame_idx) { - if (frame_idx >= gf_group->gf_group_size && !has_arf) break; - struct lookahead_entry *buf; - frame_gop_offset = gf_group->frame_gop_index[frame_idx]; - buf = vp9_lookahead_peek(cpi->lookahead, frame_gop_offset - 1); - - if (buf == NULL) break; - - gf_picture[frame_idx].frame = &buf->img; - for (i = 0; i < 3; ++i) { - gf_picture[frame_idx].ref_frame[i] = ref_table[i]; - } - - if (gf_group->update_type[frame_idx] != OVERLAY_UPDATE && - gf_group->update_ref_idx[frame_idx] != -1) { - ref_table[gf_group->update_ref_idx[frame_idx]] = frame_idx; - } - - gf_picture[frame_idx].update_type = gf_group->update_type[frame_idx]; - - ++*tpl_group_frames; - - // The length of group of pictures is baseline_gf_interval, plus the - // beginning golden frame from last GOP, plus the last overlay frame in - // the same GOP. - if (frame_idx == gf_group->gf_group_size) { - added_overlay = 1; - - ++frame_idx; - ++frame_gop_offset; - break; - } - - if (frame_idx == gf_group->gf_group_size - 1 && - gf_group->update_type[gf_group->gf_group_size] != OVERLAY_UPDATE) { - ++frame_idx; - ++frame_gop_offset; - break; - } - } - - int lst_index = frame_idx - 1; - // Extend two frames outside the current gf group. - for (; has_arf && frame_idx < MAX_LAG_BUFFERS && extend_frame_count < 2; - ++frame_idx) { - struct lookahead_entry *buf = - vp9_lookahead_peek(cpi->lookahead, frame_gop_offset - 1); - - if (buf == NULL) break; - - cpi->tpl_stats[frame_idx].base_qindex = pframe_qindex; - - gf_picture[frame_idx].frame = &buf->img; - gf_picture[frame_idx].ref_frame[0] = gf_picture[lst_index].ref_frame[0]; - gf_picture[frame_idx].ref_frame[1] = gf_picture[lst_index].ref_frame[1]; - gf_picture[frame_idx].ref_frame[2] = gf_picture[lst_index].ref_frame[2]; - - if (gf_picture[frame_idx].ref_frame[0] > - gf_picture[frame_idx].ref_frame[1] && - gf_picture[frame_idx].ref_frame[0] > - gf_picture[frame_idx].ref_frame[2]) { - gf_picture[frame_idx].ref_frame[0] = lst_index; - } else if (gf_picture[frame_idx].ref_frame[1] > - gf_picture[frame_idx].ref_frame[0] && - gf_picture[frame_idx].ref_frame[1] > - gf_picture[frame_idx].ref_frame[2]) { - gf_picture[frame_idx].ref_frame[1] = lst_index; - } else { - gf_picture[frame_idx].ref_frame[2] = lst_index; - } - - gf_picture[frame_idx].update_type = LF_UPDATE; - lst_index = frame_idx; - ++*tpl_group_frames; - ++extend_frame_count; - ++frame_gop_offset; - } - - return extend_frame_count + added_overlay; -} - -static int init_gop_frames(VP9_COMP *cpi, GF_PICTURE *gf_picture, - const GF_GROUP *gf_group, int *tpl_group_frames) { - if (cpi->ext_ratectrl.ready && - (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_GOP) != 0) { - return init_gop_frames_rc(cpi, gf_picture, gf_group, tpl_group_frames); - } - - VP9_COMMON *cm = &cpi->common; - int frame_idx = 0; - int i; - int gld_index = -1; - int alt_index = -2; - int lst_index = -1; - int arf_index_stack[MAX_ARF_LAYERS]; - int arf_stack_size = 0; - int extend_frame_count = 0; - int pframe_qindex = cpi->tpl_stats[2].base_qindex; - int frame_gop_offset = 0; - - RefCntBuffer *frame_bufs = cm->buffer_pool->frame_bufs; - int8_t recon_frame_index[REFS_PER_FRAME + MAX_ARF_LAYERS]; - - memset(recon_frame_index, -1, sizeof(recon_frame_index)); - stack_init(arf_index_stack, MAX_ARF_LAYERS); - - for (i = 0; i < FRAME_BUFFERS; ++i) { - if (frame_bufs[i].ref_count == 0) { - alloc_frame_mvs(cm, i); - if (vpx_realloc_frame_buffer(&frame_bufs[i].buf, cm->width, cm->height, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment, - NULL, NULL, NULL)) - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate frame buffer"); - - recon_frame_index[frame_idx] = i; - ++frame_idx; - - if (frame_idx >= REFS_PER_FRAME + cpi->oxcf.enable_auto_arf) break; - } - } - - for (i = 0; i < REFS_PER_FRAME + 1; ++i) { - assert(recon_frame_index[i] >= 0); - cpi->tpl_recon_frames[i] = &frame_bufs[recon_frame_index[i]].buf; - } - - *tpl_group_frames = 0; - - // Initialize Golden reference frame. - gf_picture[0].frame = get_ref_frame_buffer(cpi, GOLDEN_FRAME); - for (i = 0; i < 3; ++i) gf_picture[0].ref_frame[i] = -REFS_PER_FRAME; - gf_picture[0].update_type = gf_group->update_type[0]; - gld_index = 0; - ++*tpl_group_frames; - - gf_picture[-1].frame = get_ref_frame_buffer(cpi, LAST_FRAME); - gf_picture[-2].frame = get_ref_frame_buffer(cpi, ALTREF_FRAME); - - // Initialize base layer ARF frame - gf_picture[1].frame = cpi->Source; - gf_picture[1].ref_frame[0] = gld_index; - gf_picture[1].ref_frame[1] = lst_index; - gf_picture[1].ref_frame[2] = alt_index; - gf_picture[1].update_type = gf_group->update_type[1]; - alt_index = 1; - ++*tpl_group_frames; - - // Initialize P frames - for (frame_idx = 2; frame_idx < MAX_ARF_GOP_SIZE; ++frame_idx) { - struct lookahead_entry *buf; - frame_gop_offset = gf_group->frame_gop_index[frame_idx]; - buf = vp9_lookahead_peek(cpi->lookahead, frame_gop_offset - 1); - - if (buf == NULL) break; - - gf_picture[frame_idx].frame = &buf->img; - gf_picture[frame_idx].ref_frame[0] = gld_index; - gf_picture[frame_idx].ref_frame[1] = lst_index; - gf_picture[frame_idx].ref_frame[2] = alt_index; - gf_picture[frame_idx].update_type = gf_group->update_type[frame_idx]; - - switch (gf_group->update_type[frame_idx]) { - case ARF_UPDATE: - stack_push(arf_index_stack, alt_index, arf_stack_size); - ++arf_stack_size; - alt_index = frame_idx; - break; - case LF_UPDATE: lst_index = frame_idx; break; - case OVERLAY_UPDATE: - gld_index = frame_idx; - alt_index = stack_pop(arf_index_stack, arf_stack_size); - --arf_stack_size; - break; - case USE_BUF_FRAME: - lst_index = alt_index; - alt_index = stack_pop(arf_index_stack, arf_stack_size); - --arf_stack_size; - break; - default: break; - } - - ++*tpl_group_frames; - - // The length of group of pictures is baseline_gf_interval, plus the - // beginning golden frame from last GOP, plus the last overlay frame in - // the same GOP. - if (frame_idx == gf_group->gf_group_size) break; - } - - alt_index = -1; - ++frame_idx; - ++frame_gop_offset; - - // Extend two frames outside the current gf group. - for (; frame_idx < MAX_LAG_BUFFERS && extend_frame_count < 2; ++frame_idx) { - struct lookahead_entry *buf = - vp9_lookahead_peek(cpi->lookahead, frame_gop_offset - 1); - - if (buf == NULL) break; - - cpi->tpl_stats[frame_idx].base_qindex = pframe_qindex; - - gf_picture[frame_idx].frame = &buf->img; - gf_picture[frame_idx].ref_frame[0] = gld_index; - gf_picture[frame_idx].ref_frame[1] = lst_index; - gf_picture[frame_idx].ref_frame[2] = alt_index; - gf_picture[frame_idx].update_type = LF_UPDATE; - lst_index = frame_idx; - ++*tpl_group_frames; - ++extend_frame_count; - ++frame_gop_offset; - } - - return extend_frame_count; -} - -static void init_tpl_stats(VP9_COMP *cpi) { - int frame_idx; - for (frame_idx = 0; frame_idx < MAX_ARF_GOP_SIZE; ++frame_idx) { - TplDepFrame *tpl_frame = &cpi->tpl_stats[frame_idx]; - memset(tpl_frame->tpl_stats_ptr, 0, - tpl_frame->height * tpl_frame->width * - sizeof(*tpl_frame->tpl_stats_ptr)); - tpl_frame->is_valid = 0; - } -} - -static void free_tpl_frame_stats_list(VpxTplGopStats *tpl_gop_stats) { - int frame_idx; - for (frame_idx = 0; frame_idx < tpl_gop_stats->size; ++frame_idx) { - vpx_free(tpl_gop_stats->frame_stats_list[frame_idx].block_stats_list); - } - vpx_free(tpl_gop_stats->frame_stats_list); -} - -static void init_tpl_stats_before_propagation( - struct vpx_internal_error_info *error_info, VpxTplGopStats *tpl_gop_stats, - TplDepFrame *tpl_stats, int tpl_gop_frames, int frame_width, - int frame_height) { - int frame_idx; - free_tpl_frame_stats_list(tpl_gop_stats); - CHECK_MEM_ERROR( - error_info, tpl_gop_stats->frame_stats_list, - vpx_calloc(tpl_gop_frames, sizeof(*tpl_gop_stats->frame_stats_list))); - tpl_gop_stats->size = tpl_gop_frames; - for (frame_idx = 0; frame_idx < tpl_gop_frames; ++frame_idx) { - const int mi_rows = tpl_stats[frame_idx].mi_rows; - const int mi_cols = tpl_stats[frame_idx].mi_cols; - CHECK_MEM_ERROR( - error_info, tpl_gop_stats->frame_stats_list[frame_idx].block_stats_list, - vpx_calloc( - mi_rows * mi_cols, - sizeof( - *tpl_gop_stats->frame_stats_list[frame_idx].block_stats_list))); - tpl_gop_stats->frame_stats_list[frame_idx].num_blocks = mi_rows * mi_cols; - tpl_gop_stats->frame_stats_list[frame_idx].frame_width = frame_width; - tpl_gop_stats->frame_stats_list[frame_idx].frame_height = frame_height; - } -} - -#if CONFIG_NON_GREEDY_MV -static uint32_t full_pixel_motion_search(VP9_COMP *cpi, ThreadData *td, - MotionField *motion_field, - int frame_idx, uint8_t *cur_frame_buf, - uint8_t *ref_frame_buf, int stride, - BLOCK_SIZE bsize, int mi_row, - int mi_col, MV *mv) { - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - MV_SPEED_FEATURES *const mv_sf = &cpi->sf.mv; - int step_param; - uint32_t bestsme = UINT_MAX; - const MvLimits tmp_mv_limits = x->mv_limits; - // lambda is used to adjust the importance of motion vector consistency. - // TODO(angiebird): Figure out lambda's proper value. - const int lambda = cpi->tpl_stats[frame_idx].lambda; - int_mv nb_full_mvs[NB_MVS_NUM]; - int nb_full_mv_num; - - MV best_ref_mv1 = { 0, 0 }; - MV best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */ - - best_ref_mv1_full.col = best_ref_mv1.col >> 3; - best_ref_mv1_full.row = best_ref_mv1.row >> 3; - - // Setup frame pointers - x->plane[0].src.buf = cur_frame_buf; - x->plane[0].src.stride = stride; - xd->plane[0].pre[0].buf = ref_frame_buf; - xd->plane[0].pre[0].stride = stride; - - step_param = mv_sf->reduce_first_step_size; - step_param = VPXMIN(step_param, MAX_MVSEARCH_STEPS - 2); - - vp9_set_mv_search_range(&x->mv_limits, &best_ref_mv1); - - nb_full_mv_num = - vp9_prepare_nb_full_mvs(motion_field, mi_row, mi_col, nb_full_mvs); - vp9_full_pixel_diamond_new(cpi, x, bsize, &best_ref_mv1_full, step_param, - lambda, 1, nb_full_mvs, nb_full_mv_num, mv); - - /* restore UMV window */ - x->mv_limits = tmp_mv_limits; - - return bestsme; -} - -static uint32_t sub_pixel_motion_search(VP9_COMP *cpi, ThreadData *td, - uint8_t *cur_frame_buf, - uint8_t *ref_frame_buf, int stride, - BLOCK_SIZE bsize, MV *mv) { - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - MV_SPEED_FEATURES *const mv_sf = &cpi->sf.mv; - uint32_t bestsme = UINT_MAX; - uint32_t distortion; - uint32_t sse; - int cost_list[5]; - - MV best_ref_mv1 = { 0, 0 }; - - // Setup frame pointers - x->plane[0].src.buf = cur_frame_buf; - x->plane[0].src.stride = stride; - xd->plane[0].pre[0].buf = ref_frame_buf; - xd->plane[0].pre[0].stride = stride; - - // TODO(yunqing): may use higher tap interp filter than 2 taps. - // Ignore mv costing by sending NULL pointer instead of cost array - bestsme = cpi->find_fractional_mv_step( - x, mv, &best_ref_mv1, cpi->common.allow_high_precision_mv, x->errorperbit, - &cpi->fn_ptr[bsize], 0, mv_sf->subpel_search_level, - cond_cost_list(cpi, cost_list), NULL, NULL, &distortion, &sse, NULL, 0, 0, - USE_2_TAPS); - - return bestsme; -} - -#else // CONFIG_NON_GREEDY_MV -static uint32_t motion_compensated_prediction(VP9_COMP *cpi, ThreadData *td, - uint8_t *cur_frame_buf, - uint8_t *ref_frame_buf, - int stride, BLOCK_SIZE bsize, - MV *mv) { - MACROBLOCK *const x = &td->mb; - MACROBLOCKD *const xd = &x->e_mbd; - MV_SPEED_FEATURES *const mv_sf = &cpi->sf.mv; - const SEARCH_METHODS search_method = NSTEP; - int step_param; - int sadpb = x->sadperbit16; - uint32_t bestsme = UINT_MAX; - uint32_t distortion; - uint32_t sse; - int cost_list[5]; - const MvLimits tmp_mv_limits = x->mv_limits; - - MV best_ref_mv1 = { 0, 0 }; - MV best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */ - - best_ref_mv1_full.col = best_ref_mv1.col >> 3; - best_ref_mv1_full.row = best_ref_mv1.row >> 3; - - // Setup frame pointers - x->plane[0].src.buf = cur_frame_buf; - x->plane[0].src.stride = stride; - xd->plane[0].pre[0].buf = ref_frame_buf; - xd->plane[0].pre[0].stride = stride; - - step_param = mv_sf->reduce_first_step_size; - step_param = VPXMIN(step_param, MAX_MVSEARCH_STEPS - 2); - - vp9_set_mv_search_range(&x->mv_limits, &best_ref_mv1); - - vp9_full_pixel_search(cpi, x, bsize, &best_ref_mv1_full, step_param, - search_method, sadpb, cond_cost_list(cpi, cost_list), - &best_ref_mv1, mv, 0, 0); - - /* restore UMV window */ - x->mv_limits = tmp_mv_limits; - - // TODO(yunqing): may use higher tap interp filter than 2 taps. - // Ignore mv costing by sending NULL pointer instead of cost array - bestsme = cpi->find_fractional_mv_step( - x, mv, &best_ref_mv1, cpi->common.allow_high_precision_mv, x->errorperbit, - &cpi->fn_ptr[bsize], 0, mv_sf->subpel_search_level, - cond_cost_list(cpi, cost_list), NULL, NULL, &distortion, &sse, NULL, 0, 0, - USE_2_TAPS); - - return bestsme; -} -#endif - -static int get_overlap_area(int grid_pos_row, int grid_pos_col, int ref_pos_row, - int ref_pos_col, int block, BLOCK_SIZE bsize) { - int width = 0, height = 0; - int bw = 4 << b_width_log2_lookup[bsize]; - int bh = 4 << b_height_log2_lookup[bsize]; - - switch (block) { - case 0: - width = grid_pos_col + bw - ref_pos_col; - height = grid_pos_row + bh - ref_pos_row; - break; - case 1: - width = ref_pos_col + bw - grid_pos_col; - height = grid_pos_row + bh - ref_pos_row; - break; - case 2: - width = grid_pos_col + bw - ref_pos_col; - height = ref_pos_row + bh - grid_pos_row; - break; - case 3: - width = ref_pos_col + bw - grid_pos_col; - height = ref_pos_row + bh - grid_pos_row; - break; - default: assert(0); - } - - return width * height; -} - -static int round_floor(int ref_pos, int bsize_pix) { - int round; - if (ref_pos < 0) - round = -(1 + (-ref_pos - 1) / bsize_pix); - else - round = ref_pos / bsize_pix; - - return round; -} - -static void tpl_model_store(TplDepStats *tpl_stats, int mi_row, int mi_col, - BLOCK_SIZE bsize, int stride) { - const int mi_height = num_8x8_blocks_high_lookup[bsize]; - const int mi_width = num_8x8_blocks_wide_lookup[bsize]; - const TplDepStats *src_stats = &tpl_stats[mi_row * stride + mi_col]; - int idx, idy; - - for (idy = 0; idy < mi_height; ++idy) { - for (idx = 0; idx < mi_width; ++idx) { - TplDepStats *tpl_ptr = &tpl_stats[(mi_row + idy) * stride + mi_col + idx]; - const int64_t mc_flow = tpl_ptr->mc_flow; - const int64_t mc_ref_cost = tpl_ptr->mc_ref_cost; - *tpl_ptr = *src_stats; - tpl_ptr->mc_flow = mc_flow; - tpl_ptr->mc_ref_cost = mc_ref_cost; - tpl_ptr->mc_dep_cost = tpl_ptr->intra_cost + tpl_ptr->mc_flow; - } - } -} - -static void tpl_store_before_propagation(VpxTplBlockStats *tpl_block_stats, - TplDepStats *tpl_stats, int mi_row, - int mi_col, BLOCK_SIZE bsize, - int src_stride, int64_t recon_error, - int64_t rate_cost, int ref_frame_idx, - int mi_rows, int mi_cols) { - const int mi_height = num_8x8_blocks_high_lookup[bsize]; - const int mi_width = num_8x8_blocks_wide_lookup[bsize]; - const TplDepStats *src_stats = &tpl_stats[mi_row * src_stride + mi_col]; - int idx, idy; - - for (idy = 0; idy < mi_height; ++idy) { - for (idx = 0; idx < mi_width; ++idx) { - if (mi_row + idy >= mi_rows || mi_col + idx >= mi_cols) continue; - VpxTplBlockStats *tpl_block_stats_ptr = - &tpl_block_stats[(mi_row + idy) * mi_cols + mi_col + idx]; - tpl_block_stats_ptr->row = mi_row * 8 + idy * 8; - tpl_block_stats_ptr->col = mi_col * 8 + idx * 8; - tpl_block_stats_ptr->inter_cost = src_stats->inter_cost; - tpl_block_stats_ptr->intra_cost = src_stats->intra_cost; - // inter/intra_cost here is calculated with SATD which should be close - // enough to be used as inter/intra_pred_error - tpl_block_stats_ptr->inter_pred_err = src_stats->inter_cost; - tpl_block_stats_ptr->intra_pred_err = src_stats->intra_cost; - tpl_block_stats_ptr->srcrf_dist = recon_error << TPL_DEP_COST_SCALE_LOG2; - tpl_block_stats_ptr->srcrf_rate = rate_cost << TPL_DEP_COST_SCALE_LOG2; - tpl_block_stats_ptr->mv_r = src_stats->mv.as_mv.row; - tpl_block_stats_ptr->mv_c = src_stats->mv.as_mv.col; - tpl_block_stats_ptr->ref_frame_index = ref_frame_idx; - } - } -} - -static void tpl_model_update_b(TplDepFrame *tpl_frame, TplDepStats *tpl_stats, - int mi_row, int mi_col, const BLOCK_SIZE bsize) { - if (tpl_stats->ref_frame_index < 0) return; - - TplDepFrame *ref_tpl_frame = &tpl_frame[tpl_stats->ref_frame_index]; - TplDepStats *ref_stats = ref_tpl_frame->tpl_stats_ptr; - MV mv = tpl_stats->mv.as_mv; - int mv_row = mv.row >> 3; - int mv_col = mv.col >> 3; - - int ref_pos_row = mi_row * MI_SIZE + mv_row; - int ref_pos_col = mi_col * MI_SIZE + mv_col; - - const int bw = 4 << b_width_log2_lookup[bsize]; - const int bh = 4 << b_height_log2_lookup[bsize]; - const int mi_height = num_8x8_blocks_high_lookup[bsize]; - const int mi_width = num_8x8_blocks_wide_lookup[bsize]; - const int pix_num = bw * bh; - - // top-left on grid block location in pixel - int grid_pos_row_base = round_floor(ref_pos_row, bh) * bh; - int grid_pos_col_base = round_floor(ref_pos_col, bw) * bw; - int block; - - for (block = 0; block < 4; ++block) { - int grid_pos_row = grid_pos_row_base + bh * (block >> 1); - int grid_pos_col = grid_pos_col_base + bw * (block & 0x01); - - if (grid_pos_row >= 0 && grid_pos_row < ref_tpl_frame->mi_rows * MI_SIZE && - grid_pos_col >= 0 && grid_pos_col < ref_tpl_frame->mi_cols * MI_SIZE) { - int overlap_area = get_overlap_area( - grid_pos_row, grid_pos_col, ref_pos_row, ref_pos_col, block, bsize); - int ref_mi_row = round_floor(grid_pos_row, bh) * mi_height; - int ref_mi_col = round_floor(grid_pos_col, bw) * mi_width; - - int64_t mc_flow = tpl_stats->mc_dep_cost - - (tpl_stats->mc_dep_cost * tpl_stats->inter_cost) / - tpl_stats->intra_cost; - - int idx, idy; - - for (idy = 0; idy < mi_height; ++idy) { - for (idx = 0; idx < mi_width; ++idx) { - TplDepStats *des_stats = - &ref_stats[(ref_mi_row + idy) * ref_tpl_frame->stride + - (ref_mi_col + idx)]; - - des_stats->mc_flow += (mc_flow * overlap_area) / pix_num; - des_stats->mc_ref_cost += - ((tpl_stats->intra_cost - tpl_stats->inter_cost) * overlap_area) / - pix_num; - assert(overlap_area >= 0); - } - } - } - } -} - -static void tpl_model_update(TplDepFrame *tpl_frame, TplDepStats *tpl_stats, - int mi_row, int mi_col, const BLOCK_SIZE bsize) { - int idx, idy; - const int mi_height = num_8x8_blocks_high_lookup[bsize]; - const int mi_width = num_8x8_blocks_wide_lookup[bsize]; - - for (idy = 0; idy < mi_height; ++idy) { - for (idx = 0; idx < mi_width; ++idx) { - TplDepStats *tpl_ptr = - &tpl_stats[(mi_row + idy) * tpl_frame->stride + (mi_col + idx)]; - tpl_model_update_b(tpl_frame, tpl_ptr, mi_row + idy, mi_col + idx, - BLOCK_8X8); - } - } -} - -static void get_quantize_error(MACROBLOCK *x, int plane, tran_low_t *coeff, - tran_low_t *qcoeff, tran_low_t *dqcoeff, - TX_SIZE tx_size, int64_t *recon_error, - int64_t *sse, uint16_t *eob) { - MACROBLOCKD *const xd = &x->e_mbd; - const struct macroblock_plane *const p = &x->plane[plane]; - const struct macroblockd_plane *const pd = &xd->plane[plane]; - const ScanOrder *const scan_order = &vp9_default_scan_orders[tx_size]; - int pix_num = 1 << num_pels_log2_lookup[txsize_to_bsize[tx_size]]; - const int shift = tx_size == TX_32X32 ? 0 : 2; - - // skip block condition should be handled before this is called. - assert(!x->skip_block); - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - vp9_highbd_quantize_fp_32x32(coeff, pix_num, p, qcoeff, dqcoeff, - pd->dequant, eob, scan_order); - } else { - vp9_quantize_fp_32x32(coeff, pix_num, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); - } -#else - vp9_quantize_fp_32x32(coeff, pix_num, p, qcoeff, dqcoeff, pd->dequant, eob, - scan_order); -#endif // CONFIG_VP9_HIGHBITDEPTH - - *recon_error = vp9_block_error(coeff, dqcoeff, pix_num, sse) >> shift; - *recon_error = VPXMAX(*recon_error, 1); - - *sse = (*sse) >> shift; - *sse = VPXMAX(*sse, 1); -} - -#if CONFIG_VP9_HIGHBITDEPTH -void vp9_highbd_wht_fwd_txfm(int16_t *src_diff, int bw, tran_low_t *coeff, - TX_SIZE tx_size) { - // TODO(sdeng): Implement SIMD based high bit-depth Hadamard transforms. - switch (tx_size) { - case TX_8X8: vpx_highbd_hadamard_8x8(src_diff, bw, coeff); break; - case TX_16X16: vpx_highbd_hadamard_16x16(src_diff, bw, coeff); break; - case TX_32X32: vpx_highbd_hadamard_32x32(src_diff, bw, coeff); break; - default: assert(0); - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -void vp9_wht_fwd_txfm(int16_t *src_diff, int bw, tran_low_t *coeff, - TX_SIZE tx_size) { - switch (tx_size) { - case TX_8X8: vpx_hadamard_8x8(src_diff, bw, coeff); break; - case TX_16X16: vpx_hadamard_16x16(src_diff, bw, coeff); break; - case TX_32X32: vpx_hadamard_32x32(src_diff, bw, coeff); break; - default: assert(0); - } -} - -static void set_mv_limits(const VP9_COMMON *cm, MACROBLOCK *x, int mi_row, - int mi_col) { - x->mv_limits.row_min = -((mi_row * MI_SIZE) + (17 - 2 * VP9_INTERP_EXTEND)); - x->mv_limits.row_max = - (cm->mi_rows - 1 - mi_row) * MI_SIZE + (17 - 2 * VP9_INTERP_EXTEND); - x->mv_limits.col_min = -((mi_col * MI_SIZE) + (17 - 2 * VP9_INTERP_EXTEND)); - x->mv_limits.col_max = - ((cm->mi_cols - 1 - mi_col) * MI_SIZE) + (17 - 2 * VP9_INTERP_EXTEND); -} - -static int rate_estimator(const tran_low_t *qcoeff, int eob, TX_SIZE tx_size) { - const ScanOrder *const scan_order = &vp9_scan_orders[tx_size][DCT_DCT]; - int rate_cost = 1; - int idx; - assert((1 << num_pels_log2_lookup[txsize_to_bsize[tx_size]]) >= eob); - for (idx = 0; idx < eob; ++idx) { - unsigned int abs_level = abs(qcoeff[scan_order->scan[idx]]); - rate_cost += get_msb(abs_level + 1) + 1 + (abs_level > 0); - } - - return (rate_cost << VP9_PROB_COST_SHIFT); -} - -static void mode_estimation(VP9_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd, - struct scale_factors *sf, GF_PICTURE *gf_picture, - int frame_idx, TplDepFrame *tpl_frame, - int16_t *src_diff, tran_low_t *coeff, - tran_low_t *qcoeff, tran_low_t *dqcoeff, int mi_row, - int mi_col, BLOCK_SIZE bsize, TX_SIZE tx_size, - YV12_BUFFER_CONFIG *ref_frame[], uint8_t *predictor, - int64_t *recon_error, int64_t *rate_cost, - int64_t *sse, int *ref_frame_idx) { - VP9_COMMON *cm = &cpi->common; - ThreadData *td = &cpi->td; - - const int bw = 4 << b_width_log2_lookup[bsize]; - const int bh = 4 << b_height_log2_lookup[bsize]; - const int pix_num = bw * bh; - int best_rf_idx = -1; - int_mv best_mv; - int64_t best_inter_cost = INT64_MAX; - int64_t inter_cost; - int rf_idx; - const InterpKernel *const kernel = vp9_filter_kernels[EIGHTTAP]; - - int64_t best_intra_cost = INT64_MAX; - int64_t intra_cost; - PREDICTION_MODE mode; - int mb_y_offset = mi_row * MI_SIZE * xd->cur_buf->y_stride + mi_col * MI_SIZE; - MODE_INFO mi_above, mi_left; - const int mi_height = num_8x8_blocks_high_lookup[bsize]; - const int mi_width = num_8x8_blocks_wide_lookup[bsize]; - TplDepStats *tpl_stats = - &tpl_frame->tpl_stats_ptr[mi_row * tpl_frame->stride + mi_col]; - - xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8); - xd->mb_to_bottom_edge = ((cm->mi_rows - 1 - mi_row) * MI_SIZE) * 8; - xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8); - xd->mb_to_right_edge = ((cm->mi_cols - 1 - mi_col) * MI_SIZE) * 8; - xd->above_mi = (mi_row > 0) ? &mi_above : NULL; - xd->left_mi = (mi_col > 0) ? &mi_left : NULL; - - // Intra prediction search - for (mode = DC_PRED; mode <= TM_PRED; ++mode) { - uint8_t *src, *dst; - int src_stride, dst_stride; - - src = xd->cur_buf->y_buffer + mb_y_offset; - src_stride = xd->cur_buf->y_stride; - - dst = &predictor[0]; - dst_stride = bw; - - xd->mi[0]->sb_type = bsize; - xd->mi[0]->ref_frame[0] = INTRA_FRAME; - - vp9_predict_intra_block(xd, b_width_log2_lookup[bsize], tx_size, mode, src, - src_stride, dst, dst_stride, 0, 0, 0); - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - vpx_highbd_subtract_block(bh, bw, src_diff, bw, src, src_stride, dst, - dst_stride, xd->bd); - vp9_highbd_wht_fwd_txfm(src_diff, bw, coeff, tx_size); - intra_cost = vpx_highbd_satd(coeff, pix_num); - } else { - vpx_subtract_block(bh, bw, src_diff, bw, src, src_stride, dst, - dst_stride); - vp9_wht_fwd_txfm(src_diff, bw, coeff, tx_size); - intra_cost = vpx_satd(coeff, pix_num); - } -#else - vpx_subtract_block(bh, bw, src_diff, bw, src, src_stride, dst, dst_stride); - vp9_wht_fwd_txfm(src_diff, bw, coeff, tx_size); - intra_cost = vpx_satd(coeff, pix_num); -#endif // CONFIG_VP9_HIGHBITDEPTH - - if (intra_cost < best_intra_cost) best_intra_cost = intra_cost; - } - - // Motion compensated prediction - best_mv.as_int = 0; - - set_mv_limits(cm, x, mi_row, mi_col); - - for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) { - int_mv mv; -#if CONFIG_NON_GREEDY_MV - MotionField *motion_field; -#endif - if (ref_frame[rf_idx] == NULL) continue; - -#if CONFIG_NON_GREEDY_MV - (void)td; - motion_field = vp9_motion_field_info_get_motion_field( - &cpi->motion_field_info, frame_idx, rf_idx, bsize); - mv = vp9_motion_field_mi_get_mv(motion_field, mi_row, mi_col); -#else - motion_compensated_prediction(cpi, td, xd->cur_buf->y_buffer + mb_y_offset, - ref_frame[rf_idx]->y_buffer + mb_y_offset, - xd->cur_buf->y_stride, bsize, &mv.as_mv); -#endif - -#if CONFIG_VP9_HIGHBITDEPTH - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { - vp9_highbd_build_inter_predictor( - CONVERT_TO_SHORTPTR(ref_frame[rf_idx]->y_buffer + mb_y_offset), - ref_frame[rf_idx]->y_stride, CONVERT_TO_SHORTPTR(&predictor[0]), bw, - &mv.as_mv, sf, bw, bh, 0, kernel, MV_PRECISION_Q3, mi_col * MI_SIZE, - mi_row * MI_SIZE, xd->bd); - vpx_highbd_subtract_block( - bh, bw, src_diff, bw, xd->cur_buf->y_buffer + mb_y_offset, - xd->cur_buf->y_stride, &predictor[0], bw, xd->bd); - vp9_highbd_wht_fwd_txfm(src_diff, bw, coeff, tx_size); - inter_cost = vpx_highbd_satd(coeff, pix_num); - } else { - vp9_build_inter_predictor( - ref_frame[rf_idx]->y_buffer + mb_y_offset, - ref_frame[rf_idx]->y_stride, &predictor[0], bw, &mv.as_mv, sf, bw, bh, - 0, kernel, MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE); - vpx_subtract_block(bh, bw, src_diff, bw, - xd->cur_buf->y_buffer + mb_y_offset, - xd->cur_buf->y_stride, &predictor[0], bw); - vp9_wht_fwd_txfm(src_diff, bw, coeff, tx_size); - inter_cost = vpx_satd(coeff, pix_num); - } -#else - vp9_build_inter_predictor(ref_frame[rf_idx]->y_buffer + mb_y_offset, - ref_frame[rf_idx]->y_stride, &predictor[0], bw, - &mv.as_mv, sf, bw, bh, 0, kernel, MV_PRECISION_Q3, - mi_col * MI_SIZE, mi_row * MI_SIZE); - vpx_subtract_block(bh, bw, src_diff, bw, - xd->cur_buf->y_buffer + mb_y_offset, - xd->cur_buf->y_stride, &predictor[0], bw); - vp9_wht_fwd_txfm(src_diff, bw, coeff, tx_size); - inter_cost = vpx_satd(coeff, pix_num); -#endif - - if (inter_cost < best_inter_cost) { - uint16_t eob = 0; - best_rf_idx = rf_idx; - best_inter_cost = inter_cost; - best_mv.as_int = mv.as_int; - // Since best_inter_cost is initialized as INT64_MAX, recon_error and - // rate_cost will be calculated with the best reference frame. - get_quantize_error(x, 0, coeff, qcoeff, dqcoeff, tx_size, recon_error, - sse, &eob); - *rate_cost = rate_estimator(qcoeff, eob, tx_size); - } - } - best_intra_cost = VPXMAX(best_intra_cost, 1); - best_inter_cost = VPXMIN(best_intra_cost, best_inter_cost); - tpl_stats->inter_cost = VPXMAX( - 1, (best_inter_cost << TPL_DEP_COST_SCALE_LOG2) / (mi_height * mi_width)); - tpl_stats->intra_cost = VPXMAX( - 1, (best_intra_cost << TPL_DEP_COST_SCALE_LOG2) / (mi_height * mi_width)); - if (best_rf_idx >= 0) { - tpl_stats->ref_frame_index = gf_picture[frame_idx].ref_frame[best_rf_idx]; - } - tpl_stats->mv.as_int = best_mv.as_int; - *ref_frame_idx = best_rf_idx; -} - -#if CONFIG_NON_GREEDY_MV -static int get_block_src_pred_buf(MACROBLOCKD *xd, GF_PICTURE *gf_picture, - int frame_idx, int rf_idx, int mi_row, - int mi_col, struct buf_2d *src, - struct buf_2d *pre) { - const int mb_y_offset = - mi_row * MI_SIZE * xd->cur_buf->y_stride + mi_col * MI_SIZE; - YV12_BUFFER_CONFIG *ref_frame = NULL; - int ref_frame_idx = gf_picture[frame_idx].ref_frame[rf_idx]; - if (ref_frame_idx != -1) { - ref_frame = gf_picture[ref_frame_idx].frame; - src->buf = xd->cur_buf->y_buffer + mb_y_offset; - src->stride = xd->cur_buf->y_stride; - pre->buf = ref_frame->y_buffer + mb_y_offset; - pre->stride = ref_frame->y_stride; - assert(src->stride == pre->stride); - return 1; - } else { - printf("invalid ref_frame_idx"); - assert(ref_frame_idx != -1); - return 0; - } -} - -#define kMvPreCheckLines 5 -#define kMvPreCheckSize 15 - -#define MV_REF_POS_NUM 3 -POSITION mv_ref_pos[MV_REF_POS_NUM] = { - { -1, 0 }, - { 0, -1 }, - { -1, -1 }, -}; - -static int_mv *get_select_mv(VP9_COMP *cpi, TplDepFrame *tpl_frame, int mi_row, - int mi_col) { - return &cpi->select_mv_arr[mi_row * tpl_frame->stride + mi_col]; -} - -static int_mv find_ref_mv(int mv_mode, VP9_COMP *cpi, TplDepFrame *tpl_frame, - BLOCK_SIZE bsize, int mi_row, int mi_col) { - int i; - const int mi_height = num_8x8_blocks_high_lookup[bsize]; - const int mi_width = num_8x8_blocks_wide_lookup[bsize]; - int_mv nearest_mv, near_mv, invalid_mv; - nearest_mv.as_int = INVALID_MV; - near_mv.as_int = INVALID_MV; - invalid_mv.as_int = INVALID_MV; - for (i = 0; i < MV_REF_POS_NUM; ++i) { - int nb_row = mi_row + mv_ref_pos[i].row * mi_height; - int nb_col = mi_col + mv_ref_pos[i].col * mi_width; - assert(mv_ref_pos[i].row <= 0); - assert(mv_ref_pos[i].col <= 0); - if (nb_row >= 0 && nb_col >= 0) { - if (nearest_mv.as_int == INVALID_MV) { - nearest_mv = *get_select_mv(cpi, tpl_frame, nb_row, nb_col); - } else { - int_mv mv = *get_select_mv(cpi, tpl_frame, nb_row, nb_col); - if (mv.as_int == nearest_mv.as_int) { - continue; - } else { - near_mv = mv; - break; - } - } - } - } - if (nearest_mv.as_int == INVALID_MV) { - nearest_mv.as_mv.row = 0; - nearest_mv.as_mv.col = 0; - } - if (near_mv.as_int == INVALID_MV) { - near_mv.as_mv.row = 0; - near_mv.as_mv.col = 0; - } - if (mv_mode == NEAREST_MV_MODE) { - return nearest_mv; - } - if (mv_mode == NEAR_MV_MODE) { - return near_mv; - } - assert(0); - return invalid_mv; -} - -static int_mv get_mv_from_mv_mode(int mv_mode, VP9_COMP *cpi, - MotionField *motion_field, - TplDepFrame *tpl_frame, BLOCK_SIZE bsize, - int mi_row, int mi_col) { - int_mv mv; - switch (mv_mode) { - case ZERO_MV_MODE: - mv.as_mv.row = 0; - mv.as_mv.col = 0; - break; - case NEW_MV_MODE: - mv = vp9_motion_field_mi_get_mv(motion_field, mi_row, mi_col); - break; - case NEAREST_MV_MODE: - mv = find_ref_mv(mv_mode, cpi, tpl_frame, bsize, mi_row, mi_col); - break; - case NEAR_MV_MODE: - mv = find_ref_mv(mv_mode, cpi, tpl_frame, bsize, mi_row, mi_col); - break; - default: - mv.as_int = INVALID_MV; - assert(0); - break; - } - return mv; -} - -static double get_mv_dist(int mv_mode, VP9_COMP *cpi, MACROBLOCKD *xd, - GF_PICTURE *gf_picture, MotionField *motion_field, - int frame_idx, TplDepFrame *tpl_frame, int rf_idx, - BLOCK_SIZE bsize, int mi_row, int mi_col, - int_mv *mv) { - uint32_t sse; - struct buf_2d src; - struct buf_2d pre; - MV full_mv; - *mv = get_mv_from_mv_mode(mv_mode, cpi, motion_field, tpl_frame, bsize, - mi_row, mi_col); - full_mv = get_full_mv(&mv->as_mv); - if (get_block_src_pred_buf(xd, gf_picture, frame_idx, rf_idx, mi_row, mi_col, - &src, &pre)) { - // TODO(angiebird): Consider subpixel when computing the sse. - cpi->fn_ptr[bsize].vf(src.buf, src.stride, get_buf_from_mv(&pre, &full_mv), - pre.stride, &sse); - return (double)(sse << VP9_DIST_SCALE_LOG2); - } else { - assert(0); - return 0; - } -} - -static int get_mv_mode_cost(int mv_mode) { - // TODO(angiebird): The probabilities are roughly inferred from - // default_inter_mode_probs. Check if there is a better way to set the - // probabilities. - const int zero_mv_prob = 16; - const int new_mv_prob = 24 * 1; - const int ref_mv_prob = 256 - zero_mv_prob - new_mv_prob; - assert(zero_mv_prob + new_mv_prob + ref_mv_prob == 256); - switch (mv_mode) { - case ZERO_MV_MODE: return vp9_prob_cost[zero_mv_prob]; break; - case NEW_MV_MODE: return vp9_prob_cost[new_mv_prob]; break; - case NEAREST_MV_MODE: return vp9_prob_cost[ref_mv_prob]; break; - case NEAR_MV_MODE: return vp9_prob_cost[ref_mv_prob]; break; - default: assert(0); return -1; - } -} - -static INLINE double get_mv_diff_cost(MV *new_mv, MV *ref_mv) { - double mv_diff_cost = log2(1 + abs(new_mv->row - ref_mv->row)) + - log2(1 + abs(new_mv->col - ref_mv->col)); - mv_diff_cost *= (1 << VP9_PROB_COST_SHIFT); - return mv_diff_cost; -} -static double get_mv_cost(int mv_mode, VP9_COMP *cpi, MotionField *motion_field, - TplDepFrame *tpl_frame, BLOCK_SIZE bsize, int mi_row, - int mi_col) { - double mv_cost = get_mv_mode_cost(mv_mode); - if (mv_mode == NEW_MV_MODE) { - MV new_mv = get_mv_from_mv_mode(mv_mode, cpi, motion_field, tpl_frame, - bsize, mi_row, mi_col) - .as_mv; - MV nearest_mv = get_mv_from_mv_mode(NEAREST_MV_MODE, cpi, motion_field, - tpl_frame, bsize, mi_row, mi_col) - .as_mv; - MV near_mv = get_mv_from_mv_mode(NEAR_MV_MODE, cpi, motion_field, tpl_frame, - bsize, mi_row, mi_col) - .as_mv; - double nearest_cost = get_mv_diff_cost(&new_mv, &nearest_mv); - double near_cost = get_mv_diff_cost(&new_mv, &near_mv); - mv_cost += nearest_cost < near_cost ? nearest_cost : near_cost; - } - return mv_cost; -} - -static double eval_mv_mode(int mv_mode, VP9_COMP *cpi, MACROBLOCK *x, - GF_PICTURE *gf_picture, MotionField *motion_field, - int frame_idx, TplDepFrame *tpl_frame, int rf_idx, - BLOCK_SIZE bsize, int mi_row, int mi_col, - int_mv *mv) { - MACROBLOCKD *xd = &x->e_mbd; - double mv_dist = - get_mv_dist(mv_mode, cpi, xd, gf_picture, motion_field, frame_idx, - tpl_frame, rf_idx, bsize, mi_row, mi_col, mv); - double mv_cost = - get_mv_cost(mv_mode, cpi, motion_field, tpl_frame, bsize, mi_row, mi_col); - double mult = 180; - - return mv_cost + mult * log2f(1 + mv_dist); -} - -static int find_best_ref_mv_mode(VP9_COMP *cpi, MACROBLOCK *x, - GF_PICTURE *gf_picture, - MotionField *motion_field, int frame_idx, - TplDepFrame *tpl_frame, int rf_idx, - BLOCK_SIZE bsize, int mi_row, int mi_col, - double *rd, int_mv *mv) { - int best_mv_mode = ZERO_MV_MODE; - int update = 0; - int mv_mode; - *rd = 0; - for (mv_mode = 0; mv_mode < MAX_MV_MODE; ++mv_mode) { - double this_rd; - int_mv this_mv; - if (mv_mode == NEW_MV_MODE) { - continue; - } - this_rd = eval_mv_mode(mv_mode, cpi, x, gf_picture, motion_field, frame_idx, - tpl_frame, rf_idx, bsize, mi_row, mi_col, &this_mv); - if (update == 0) { - *rd = this_rd; - *mv = this_mv; - best_mv_mode = mv_mode; - update = 1; - } else { - if (this_rd < *rd) { - *rd = this_rd; - *mv = this_mv; - best_mv_mode = mv_mode; - } - } - } - return best_mv_mode; -} - -static void predict_mv_mode(VP9_COMP *cpi, MACROBLOCK *x, - GF_PICTURE *gf_picture, MotionField *motion_field, - int frame_idx, TplDepFrame *tpl_frame, int rf_idx, - BLOCK_SIZE bsize, int mi_row, int mi_col) { - const int mi_height = num_8x8_blocks_high_lookup[bsize]; - const int mi_width = num_8x8_blocks_wide_lookup[bsize]; - int tmp_mv_mode_arr[kMvPreCheckSize]; - int *mv_mode_arr = tpl_frame->mv_mode_arr[rf_idx]; - double *rd_diff_arr = tpl_frame->rd_diff_arr[rf_idx]; - int_mv *select_mv_arr = cpi->select_mv_arr; - int_mv tmp_select_mv_arr[kMvPreCheckSize]; - int stride = tpl_frame->stride; - double new_mv_rd = 0; - double no_new_mv_rd = 0; - double this_new_mv_rd = 0; - double this_no_new_mv_rd = 0; - int idx; - int tmp_idx; - assert(kMvPreCheckSize == (kMvPreCheckLines * (kMvPreCheckLines + 1)) >> 1); - - // no new mv - // diagonal scan order - tmp_idx = 0; - for (idx = 0; idx < kMvPreCheckLines; ++idx) { - int r; - for (r = 0; r <= idx; ++r) { - int c = idx - r; - int nb_row = mi_row + r * mi_height; - int nb_col = mi_col + c * mi_width; - if (nb_row < tpl_frame->mi_rows && nb_col < tpl_frame->mi_cols) { - double this_rd; - int_mv *mv = &select_mv_arr[nb_row * stride + nb_col]; - mv_mode_arr[nb_row * stride + nb_col] = find_best_ref_mv_mode( - cpi, x, gf_picture, motion_field, frame_idx, tpl_frame, rf_idx, - bsize, nb_row, nb_col, &this_rd, mv); - if (r == 0 && c == 0) { - this_no_new_mv_rd = this_rd; - } - no_new_mv_rd += this_rd; - tmp_mv_mode_arr[tmp_idx] = mv_mode_arr[nb_row * stride + nb_col]; - tmp_select_mv_arr[tmp_idx] = select_mv_arr[nb_row * stride + nb_col]; - ++tmp_idx; - } - } - } - - // new mv - mv_mode_arr[mi_row * stride + mi_col] = NEW_MV_MODE; - this_new_mv_rd = eval_mv_mode( - NEW_MV_MODE, cpi, x, gf_picture, motion_field, frame_idx, tpl_frame, - rf_idx, bsize, mi_row, mi_col, &select_mv_arr[mi_row * stride + mi_col]); - new_mv_rd = this_new_mv_rd; - // We start from idx = 1 because idx = 0 is evaluated as NEW_MV_MODE - // beforehand. - for (idx = 1; idx < kMvPreCheckLines; ++idx) { - int r; - for (r = 0; r <= idx; ++r) { - int c = idx - r; - int nb_row = mi_row + r * mi_height; - int nb_col = mi_col + c * mi_width; - if (nb_row < tpl_frame->mi_rows && nb_col < tpl_frame->mi_cols) { - double this_rd; - int_mv *mv = &select_mv_arr[nb_row * stride + nb_col]; - mv_mode_arr[nb_row * stride + nb_col] = find_best_ref_mv_mode( - cpi, x, gf_picture, motion_field, frame_idx, tpl_frame, rf_idx, - bsize, nb_row, nb_col, &this_rd, mv); - new_mv_rd += this_rd; - } - } - } - - // update best_mv_mode - tmp_idx = 0; - if (no_new_mv_rd < new_mv_rd) { - for (idx = 0; idx < kMvPreCheckLines; ++idx) { - int r; - for (r = 0; r <= idx; ++r) { - int c = idx - r; - int nb_row = mi_row + r * mi_height; - int nb_col = mi_col + c * mi_width; - if (nb_row < tpl_frame->mi_rows && nb_col < tpl_frame->mi_cols) { - mv_mode_arr[nb_row * stride + nb_col] = tmp_mv_mode_arr[tmp_idx]; - select_mv_arr[nb_row * stride + nb_col] = tmp_select_mv_arr[tmp_idx]; - ++tmp_idx; - } - } - } - rd_diff_arr[mi_row * stride + mi_col] = 0; - } else { - rd_diff_arr[mi_row * stride + mi_col] = - (no_new_mv_rd - this_no_new_mv_rd) - (new_mv_rd - this_new_mv_rd); - } -} - -static void predict_mv_mode_arr(VP9_COMP *cpi, MACROBLOCK *x, - GF_PICTURE *gf_picture, - MotionField *motion_field, int frame_idx, - TplDepFrame *tpl_frame, int rf_idx, - BLOCK_SIZE bsize) { - const int mi_height = num_8x8_blocks_high_lookup[bsize]; - const int mi_width = num_8x8_blocks_wide_lookup[bsize]; - const int unit_rows = tpl_frame->mi_rows / mi_height; - const int unit_cols = tpl_frame->mi_cols / mi_width; - const int max_diagonal_lines = unit_rows + unit_cols - 1; - int idx; - for (idx = 0; idx < max_diagonal_lines; ++idx) { - int r; - for (r = VPXMAX(idx - unit_cols + 1, 0); r <= VPXMIN(idx, unit_rows - 1); - ++r) { - int c = idx - r; - int mi_row = r * mi_height; - int mi_col = c * mi_width; - assert(c >= 0 && c < unit_cols); - assert(mi_row >= 0 && mi_row < tpl_frame->mi_rows); - assert(mi_col >= 0 && mi_col < tpl_frame->mi_cols); - predict_mv_mode(cpi, x, gf_picture, motion_field, frame_idx, tpl_frame, - rf_idx, bsize, mi_row, mi_col); - } - } -} - -static void do_motion_search(VP9_COMP *cpi, ThreadData *td, - MotionField *motion_field, int frame_idx, - YV12_BUFFER_CONFIG *ref_frame, BLOCK_SIZE bsize, - int mi_row, int mi_col) { - VP9_COMMON *cm = &cpi->common; - MACROBLOCK *x = &td->mb; - MACROBLOCKD *xd = &x->e_mbd; - const int mb_y_offset = - mi_row * MI_SIZE * xd->cur_buf->y_stride + mi_col * MI_SIZE; - assert(ref_frame != NULL); - set_mv_limits(cm, x, mi_row, mi_col); - { - int_mv mv = vp9_motion_field_mi_get_mv(motion_field, mi_row, mi_col); - uint8_t *cur_frame_buf = xd->cur_buf->y_buffer + mb_y_offset; - uint8_t *ref_frame_buf = ref_frame->y_buffer + mb_y_offset; - const int stride = xd->cur_buf->y_stride; - full_pixel_motion_search(cpi, td, motion_field, frame_idx, cur_frame_buf, - ref_frame_buf, stride, bsize, mi_row, mi_col, - &mv.as_mv); - sub_pixel_motion_search(cpi, td, cur_frame_buf, ref_frame_buf, stride, - bsize, &mv.as_mv); - vp9_motion_field_mi_set_mv(motion_field, mi_row, mi_col, mv); - } -} - -static void build_motion_field( - VP9_COMP *cpi, int frame_idx, - YV12_BUFFER_CONFIG *ref_frame[MAX_INTER_REF_FRAMES], BLOCK_SIZE bsize) { - VP9_COMMON *cm = &cpi->common; - ThreadData *td = &cpi->td; - TplDepFrame *tpl_frame = &cpi->tpl_stats[frame_idx]; - const int mi_height = num_8x8_blocks_high_lookup[bsize]; - const int mi_width = num_8x8_blocks_wide_lookup[bsize]; - const int pw = num_4x4_blocks_wide_lookup[bsize] << 2; - const int ph = num_4x4_blocks_high_lookup[bsize] << 2; - int mi_row, mi_col; - int rf_idx; - - tpl_frame->lambda = (pw * ph) >> 2; - assert(pw * ph == tpl_frame->lambda << 2); - - for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) { - MotionField *motion_field = vp9_motion_field_info_get_motion_field( - &cpi->motion_field_info, frame_idx, rf_idx, bsize); - if (ref_frame[rf_idx] == NULL) { - continue; - } - vp9_motion_field_reset_mvs(motion_field); - for (mi_row = 0; mi_row < cm->mi_rows; mi_row += mi_height) { - for (mi_col = 0; mi_col < cm->mi_cols; mi_col += mi_width) { - do_motion_search(cpi, td, motion_field, frame_idx, ref_frame[rf_idx], - bsize, mi_row, mi_col); - } - } - } -} -#endif // CONFIG_NON_GREEDY_MV - -static void mc_flow_dispenser(VP9_COMP *cpi, GF_PICTURE *gf_picture, - int frame_idx, BLOCK_SIZE bsize) { - TplDepFrame *tpl_frame = &cpi->tpl_stats[frame_idx]; - VpxTplFrameStats *tpl_frame_stats_before_propagation = - &cpi->tpl_gop_stats.frame_stats_list[frame_idx]; - YV12_BUFFER_CONFIG *this_frame = gf_picture[frame_idx].frame; - YV12_BUFFER_CONFIG *ref_frame[MAX_INTER_REF_FRAMES] = { NULL, NULL, NULL }; - - VP9_COMMON *cm = &cpi->common; - struct scale_factors sf; - int rdmult, idx; - ThreadData *td = &cpi->td; - MACROBLOCK *x = &td->mb; - MACROBLOCKD *xd = &x->e_mbd; - int mi_row, mi_col; - -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(16, uint16_t, predictor16[32 * 32 * 3]); - DECLARE_ALIGNED(16, uint8_t, predictor8[32 * 32 * 3]); - uint8_t *predictor; -#else - DECLARE_ALIGNED(16, uint8_t, predictor[32 * 32 * 3]); -#endif - DECLARE_ALIGNED(16, int16_t, src_diff[32 * 32]); - DECLARE_ALIGNED(16, tran_low_t, coeff[32 * 32]); - DECLARE_ALIGNED(16, tran_low_t, qcoeff[32 * 32]); - DECLARE_ALIGNED(16, tran_low_t, dqcoeff[32 * 32]); - - const TX_SIZE tx_size = max_txsize_lookup[bsize]; - const int mi_height = num_8x8_blocks_high_lookup[bsize]; - const int mi_width = num_8x8_blocks_wide_lookup[bsize]; - - tpl_frame_stats_before_propagation->frame_width = cm->width; - tpl_frame_stats_before_propagation->frame_height = cm->height; - // Setup scaling factor -#if CONFIG_VP9_HIGHBITDEPTH - vp9_setup_scale_factors_for_frame( - &sf, this_frame->y_crop_width, this_frame->y_crop_height, - this_frame->y_crop_width, this_frame->y_crop_height, - cpi->common.use_highbitdepth); - - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) - predictor = CONVERT_TO_BYTEPTR(predictor16); - else - predictor = predictor8; -#else - vp9_setup_scale_factors_for_frame( - &sf, this_frame->y_crop_width, this_frame->y_crop_height, - this_frame->y_crop_width, this_frame->y_crop_height); -#endif // CONFIG_VP9_HIGHBITDEPTH - - // Prepare reference frame pointers. If any reference frame slot is - // unavailable, the pointer will be set to Null. - for (idx = 0; idx < MAX_INTER_REF_FRAMES; ++idx) { - int rf_idx = gf_picture[frame_idx].ref_frame[idx]; - if (rf_idx != -REFS_PER_FRAME) ref_frame[idx] = gf_picture[rf_idx].frame; - } - - xd->mi = cm->mi_grid_visible; - xd->mi[0] = cm->mi; - xd->cur_buf = this_frame; - - // Get rd multiplier set up. - rdmult = vp9_compute_rd_mult_based_on_qindex(cpi, tpl_frame->base_qindex); - set_error_per_bit(&cpi->td.mb, rdmult); - vp9_initialize_me_consts(cpi, &cpi->td.mb, tpl_frame->base_qindex); - - tpl_frame->is_valid = 1; - - cm->base_qindex = tpl_frame->base_qindex; - vp9_frame_init_quantizer(cpi); - -#if CONFIG_NON_GREEDY_MV - { - int square_block_idx; - int rf_idx; - for (square_block_idx = 0; square_block_idx < SQUARE_BLOCK_SIZES; - ++square_block_idx) { - BLOCK_SIZE square_bsize = square_block_idx_to_bsize(square_block_idx); - build_motion_field(cpi, frame_idx, ref_frame, square_bsize); - } - for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) { - int ref_frame_idx = gf_picture[frame_idx].ref_frame[rf_idx]; - if (ref_frame_idx != -1) { - MotionField *motion_field = vp9_motion_field_info_get_motion_field( - &cpi->motion_field_info, frame_idx, rf_idx, bsize); - predict_mv_mode_arr(cpi, x, gf_picture, motion_field, frame_idx, - tpl_frame, rf_idx, bsize); - } - } - } -#endif // CONFIG_NON_GREEDY_MV - - for (mi_row = 0; mi_row < cm->mi_rows; mi_row += mi_height) { - for (mi_col = 0; mi_col < cm->mi_cols; mi_col += mi_width) { - int64_t recon_error = 0; - int64_t rate_cost = 0; - int64_t sse = 0; - // Ref frame index in the ref frame buffer. - int ref_frame_idx = -1; - mode_estimation(cpi, x, xd, &sf, gf_picture, frame_idx, tpl_frame, - src_diff, coeff, qcoeff, dqcoeff, mi_row, mi_col, bsize, - tx_size, ref_frame, predictor, &recon_error, &rate_cost, - &sse, &ref_frame_idx); - // Motion flow dependency dispenser. - tpl_model_store(tpl_frame->tpl_stats_ptr, mi_row, mi_col, bsize, - tpl_frame->stride); - - tpl_store_before_propagation( - tpl_frame_stats_before_propagation->block_stats_list, - tpl_frame->tpl_stats_ptr, mi_row, mi_col, bsize, tpl_frame->stride, - recon_error, rate_cost, ref_frame_idx, tpl_frame->mi_rows, - tpl_frame->mi_cols); - - tpl_model_update(cpi->tpl_stats, tpl_frame->tpl_stats_ptr, mi_row, mi_col, - bsize); - } - } -} - -static void trim_tpl_stats(struct vpx_internal_error_info *error_info, - VpxTplGopStats *tpl_gop_stats, int extra_frames) { - int i; - VpxTplFrameStats *new_frame_stats; - const int new_size = tpl_gop_stats->size - extra_frames; - if (tpl_gop_stats->size <= extra_frames) - vpx_internal_error( - error_info, VPX_CODEC_ERROR, - "The number of frames in VpxTplGopStats is fewer than expected."); - CHECK_MEM_ERROR(error_info, new_frame_stats, - vpx_calloc(new_size, sizeof(*new_frame_stats))); - for (i = 0; i < new_size; i++) { - VpxTplFrameStats *frame_stats = &tpl_gop_stats->frame_stats_list[i]; - const int num_blocks = frame_stats->num_blocks; - new_frame_stats[i].num_blocks = frame_stats->num_blocks; - new_frame_stats[i].frame_width = frame_stats->frame_width; - new_frame_stats[i].frame_height = frame_stats->frame_height; - new_frame_stats[i].num_blocks = num_blocks; - CHECK_MEM_ERROR( - error_info, new_frame_stats[i].block_stats_list, - vpx_calloc(num_blocks, sizeof(*new_frame_stats[i].block_stats_list))); - memcpy(new_frame_stats[i].block_stats_list, frame_stats->block_stats_list, - num_blocks * sizeof(*new_frame_stats[i].block_stats_list)); - } - free_tpl_frame_stats_list(tpl_gop_stats); - tpl_gop_stats->size = new_size; - tpl_gop_stats->frame_stats_list = new_frame_stats; -} - -#if CONFIG_NON_GREEDY_MV -#define DUMP_TPL_STATS 0 -#if DUMP_TPL_STATS -static void dump_buf(uint8_t *buf, int stride, int row, int col, int h, int w) { - int i, j; - printf("%d %d\n", h, w); - for (i = 0; i < h; ++i) { - for (j = 0; j < w; ++j) { - printf("%d ", buf[(row + i) * stride + col + j]); - } - } - printf("\n"); -} - -static void dump_frame_buf(const YV12_BUFFER_CONFIG *frame_buf) { - dump_buf(frame_buf->y_buffer, frame_buf->y_stride, 0, 0, frame_buf->y_height, - frame_buf->y_width); - dump_buf(frame_buf->u_buffer, frame_buf->uv_stride, 0, 0, - frame_buf->uv_height, frame_buf->uv_width); - dump_buf(frame_buf->v_buffer, frame_buf->uv_stride, 0, 0, - frame_buf->uv_height, frame_buf->uv_width); -} - -static void dump_tpl_stats(const VP9_COMP *cpi, int tpl_group_frames, - const GF_GROUP *gf_group, - const GF_PICTURE *gf_picture, BLOCK_SIZE bsize) { - int frame_idx; - const VP9_COMMON *cm = &cpi->common; - int rf_idx; - for (frame_idx = 1; frame_idx < tpl_group_frames; ++frame_idx) { - for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) { - const TplDepFrame *tpl_frame = &cpi->tpl_stats[frame_idx]; - int mi_row, mi_col; - int ref_frame_idx; - const int mi_height = num_8x8_blocks_high_lookup[bsize]; - const int mi_width = num_8x8_blocks_wide_lookup[bsize]; - ref_frame_idx = gf_picture[frame_idx].ref_frame[rf_idx]; - if (ref_frame_idx != -1) { - YV12_BUFFER_CONFIG *ref_frame_buf = gf_picture[ref_frame_idx].frame; - const int gf_frame_offset = gf_group->frame_gop_index[frame_idx]; - const int ref_gf_frame_offset = - gf_group->frame_gop_index[ref_frame_idx]; - printf("=\n"); - printf( - "frame_idx %d mi_rows %d mi_cols %d bsize %d ref_frame_idx %d " - "rf_idx %d gf_frame_offset %d ref_gf_frame_offset %d\n", - frame_idx, cm->mi_rows, cm->mi_cols, mi_width * MI_SIZE, - ref_frame_idx, rf_idx, gf_frame_offset, ref_gf_frame_offset); - for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row) { - for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) { - if ((mi_row % mi_height) == 0 && (mi_col % mi_width) == 0) { - int_mv mv = vp9_motion_field_info_get_mv(&cpi->motion_field_info, - frame_idx, rf_idx, bsize, - mi_row, mi_col); - printf("%d %d %d %d\n", mi_row, mi_col, mv.as_mv.row, - mv.as_mv.col); - } - } - } - for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row) { - for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) { - if ((mi_row % mi_height) == 0 && (mi_col % mi_width) == 0) { - const TplDepStats *tpl_ptr = - &tpl_frame - ->tpl_stats_ptr[mi_row * tpl_frame->stride + mi_col]; - printf("%f ", tpl_ptr->feature_score); - } - } - } - printf("\n"); - - for (mi_row = 0; mi_row < cm->mi_rows; mi_row += mi_height) { - for (mi_col = 0; mi_col < cm->mi_cols; mi_col += mi_width) { - const int mv_mode = - tpl_frame - ->mv_mode_arr[rf_idx][mi_row * tpl_frame->stride + mi_col]; - printf("%d ", mv_mode); - } - } - printf("\n"); - - dump_frame_buf(gf_picture[frame_idx].frame); - dump_frame_buf(ref_frame_buf); - } - } - } -} -#endif // DUMP_TPL_STATS -#endif // CONFIG_NON_GREEDY_MV - -void vp9_init_tpl_buffer(VP9_COMP *cpi) { - VP9_COMMON *cm = &cpi->common; - int frame; - - const int mi_cols = mi_cols_aligned_to_sb(cm->mi_cols); - const int mi_rows = mi_cols_aligned_to_sb(cm->mi_rows); -#if CONFIG_NON_GREEDY_MV - int rf_idx; - - vpx_free(cpi->select_mv_arr); - CHECK_MEM_ERROR( - &cm->error, cpi->select_mv_arr, - vpx_calloc(mi_rows * mi_cols * 4, sizeof(*cpi->select_mv_arr))); -#endif - - // TODO(jingning): Reduce the actual memory use for tpl model build up. - for (frame = 0; frame < MAX_ARF_GOP_SIZE; ++frame) { - if (cpi->tpl_stats[frame].width >= mi_cols && - cpi->tpl_stats[frame].height >= mi_rows && - cpi->tpl_stats[frame].tpl_stats_ptr) - continue; - -#if CONFIG_NON_GREEDY_MV - for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) { - vpx_free(cpi->tpl_stats[frame].mv_mode_arr[rf_idx]); - CHECK_MEM_ERROR( - &cm->error, cpi->tpl_stats[frame].mv_mode_arr[rf_idx], - vpx_calloc(mi_rows * mi_cols * 4, - sizeof(*cpi->tpl_stats[frame].mv_mode_arr[rf_idx]))); - vpx_free(cpi->tpl_stats[frame].rd_diff_arr[rf_idx]); - CHECK_MEM_ERROR( - &cm->error, cpi->tpl_stats[frame].rd_diff_arr[rf_idx], - vpx_calloc(mi_rows * mi_cols * 4, - sizeof(*cpi->tpl_stats[frame].rd_diff_arr[rf_idx]))); - } -#endif - vpx_free(cpi->tpl_stats[frame].tpl_stats_ptr); - CHECK_MEM_ERROR(&cm->error, cpi->tpl_stats[frame].tpl_stats_ptr, - vpx_calloc(mi_rows * mi_cols, - sizeof(*cpi->tpl_stats[frame].tpl_stats_ptr))); - cpi->tpl_stats[frame].is_valid = 0; - cpi->tpl_stats[frame].width = mi_cols; - cpi->tpl_stats[frame].height = mi_rows; - cpi->tpl_stats[frame].stride = mi_cols; - cpi->tpl_stats[frame].mi_rows = cm->mi_rows; - cpi->tpl_stats[frame].mi_cols = cm->mi_cols; - } - - for (frame = 0; frame < REF_FRAMES; ++frame) { - cpi->enc_frame_buf[frame].mem_valid = 0; - cpi->enc_frame_buf[frame].released = 1; - } -} - -void vp9_free_tpl_buffer(VP9_COMP *cpi) { - int frame; -#if CONFIG_NON_GREEDY_MV - vp9_free_motion_field_info(&cpi->motion_field_info); - vpx_free(cpi->select_mv_arr); -#endif - for (frame = 0; frame < MAX_ARF_GOP_SIZE; ++frame) { -#if CONFIG_NON_GREEDY_MV - int rf_idx; - for (rf_idx = 0; rf_idx < MAX_INTER_REF_FRAMES; ++rf_idx) { - vpx_free(cpi->tpl_stats[frame].mv_mode_arr[rf_idx]); - vpx_free(cpi->tpl_stats[frame].rd_diff_arr[rf_idx]); - } -#endif - vpx_free(cpi->tpl_stats[frame].tpl_stats_ptr); - cpi->tpl_stats[frame].is_valid = 0; - } - free_tpl_frame_stats_list(&cpi->tpl_gop_stats); -} - -#if CONFIG_RATE_CTRL -static void accumulate_frame_tpl_stats(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - const GF_GROUP *gf_group = &cpi->twopass.gf_group; - int show_frame_count = 0; - int frame_idx; - // Accumulate tpl stats for each frame in the current group of picture. - for (frame_idx = 1; frame_idx < gf_group->gf_group_size; ++frame_idx) { - TplDepFrame *tpl_frame = &cpi->tpl_stats[frame_idx]; - TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr; - const int tpl_stride = tpl_frame->stride; - int64_t intra_cost_base = 0; - int64_t inter_cost_base = 0; - int64_t mc_dep_cost_base = 0; - int64_t mc_ref_cost_base = 0; - int64_t mc_flow_base = 0; - int row, col; - - if (!tpl_frame->is_valid) continue; - - for (row = 0; row < cm->mi_rows && tpl_frame->is_valid; ++row) { - for (col = 0; col < cm->mi_cols; ++col) { - TplDepStats *this_stats = &tpl_stats[row * tpl_stride + col]; - intra_cost_base += this_stats->intra_cost; - inter_cost_base += this_stats->inter_cost; - mc_dep_cost_base += this_stats->mc_dep_cost; - mc_ref_cost_base += this_stats->mc_ref_cost; - mc_flow_base += this_stats->mc_flow; - } - } - - cpi->tpl_stats_info[show_frame_count].intra_cost = intra_cost_base; - cpi->tpl_stats_info[show_frame_count].inter_cost = inter_cost_base; - cpi->tpl_stats_info[show_frame_count].mc_dep_cost = mc_dep_cost_base; - cpi->tpl_stats_info[show_frame_count].mc_ref_cost = mc_ref_cost_base; - cpi->tpl_stats_info[show_frame_count].mc_flow = mc_flow_base; - - ++show_frame_count; - } -} -#endif // CONFIG_RATE_CTRL - -void vp9_estimate_tpl_qp_gop(VP9_COMP *cpi) { - int gop_length = cpi->twopass.gf_group.gf_group_size; - int bottom_index, top_index; - int idx; - const int gf_index = cpi->twopass.gf_group.index; - const int is_src_frame_alt_ref = cpi->rc.is_src_frame_alt_ref; - const int refresh_frame_context = cpi->common.refresh_frame_context; - - for (idx = gf_index; idx <= gop_length; ++idx) { - TplDepFrame *tpl_frame = &cpi->tpl_stats[idx]; - int target_rate = cpi->twopass.gf_group.bit_allocation[idx]; - cpi->twopass.gf_group.index = idx; - vp9_rc_set_frame_target(cpi, target_rate); - vp9_configure_buffer_updates(cpi, idx); - if (cpi->ext_ratectrl.ready && - (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_QP) != 0 && - cpi->ext_ratectrl.funcs.get_encodeframe_decision != NULL) { - VP9_COMMON *cm = &cpi->common; - vpx_codec_err_t codec_status; - const GF_GROUP *gf_group = &cpi->twopass.gf_group; - vpx_rc_encodeframe_decision_t encode_frame_decision; - if (idx == gop_length) break; - codec_status = vp9_extrc_get_encodeframe_decision( - &cpi->ext_ratectrl, gf_group->index, &encode_frame_decision); - if (codec_status != VPX_CODEC_OK) { - vpx_internal_error(&cm->error, codec_status, - "vp9_extrc_get_encodeframe_decision() failed"); - } - tpl_frame->base_qindex = encode_frame_decision.q_index; - } else { - tpl_frame->base_qindex = vp9_rc_pick_q_and_bounds_two_pass( - cpi, &bottom_index, &top_index, idx); - tpl_frame->base_qindex = VPXMAX(tpl_frame->base_qindex, 1); - } - } - // Reset the actual index and frame update - cpi->twopass.gf_group.index = gf_index; - cpi->rc.is_src_frame_alt_ref = is_src_frame_alt_ref; - cpi->common.refresh_frame_context = refresh_frame_context; - vp9_configure_buffer_updates(cpi, gf_index); -} - -void vp9_setup_tpl_stats(VP9_COMP *cpi) { - GF_PICTURE gf_picture_buf[MAX_ARF_GOP_SIZE + REFS_PER_FRAME]; - GF_PICTURE *gf_picture = &gf_picture_buf[REFS_PER_FRAME]; - const GF_GROUP *gf_group = &cpi->twopass.gf_group; - int tpl_group_frames = 0; - int frame_idx; - int extended_frame_count; - cpi->tpl_bsize = BLOCK_32X32; - - memset(gf_picture_buf, 0, sizeof(gf_picture_buf)); - extended_frame_count = - init_gop_frames(cpi, gf_picture, gf_group, &tpl_group_frames); - - init_tpl_stats(cpi); - - init_tpl_stats_before_propagation(&cpi->common.error, &cpi->tpl_gop_stats, - cpi->tpl_stats, tpl_group_frames, - cpi->common.width, cpi->common.height); - - // Backward propagation from tpl_group_frames to 1. - for (frame_idx = tpl_group_frames - 1; frame_idx > 0; --frame_idx) { - if (gf_picture[frame_idx].update_type == USE_BUF_FRAME) continue; - mc_flow_dispenser(cpi, gf_picture, frame_idx, cpi->tpl_bsize); - } - - if (cpi->ext_ratectrl.ready && - cpi->ext_ratectrl.funcs.send_tpl_gop_stats != NULL) { - // Intra search on key frame - if (gf_picture[0].update_type != OVERLAY_UPDATE) { - mc_flow_dispenser(cpi, gf_picture, 0, cpi->tpl_bsize); - } - // TPL stats has extra frames from next GOP. Trim those extra frames for - // Qmode. - trim_tpl_stats(&cpi->common.error, &cpi->tpl_gop_stats, - extended_frame_count); - const vpx_codec_err_t codec_status = - vp9_extrc_send_tpl_stats(&cpi->ext_ratectrl, &cpi->tpl_gop_stats); - if (codec_status != VPX_CODEC_OK) { - vpx_internal_error(&cpi->common.error, codec_status, - "vp9_extrc_send_tpl_stats() failed"); - } - } - -#if CONFIG_NON_GREEDY_MV - cpi->tpl_ready = 1; -#if DUMP_TPL_STATS - dump_tpl_stats(cpi, tpl_group_frames, gf_group, gf_picture, cpi->tpl_bsize); -#endif // DUMP_TPL_STATS -#endif // CONFIG_NON_GREEDY_MV - -#if CONFIG_RATE_CTRL - if (cpi->oxcf.use_simple_encode_api) { - accumulate_frame_tpl_stats(cpi); - } -#endif // CONFIG_RATE_CTRL -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_tpl_model.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_tpl_model.h deleted file mode 100644 index de0ac39a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_tpl_model.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_TPL_MODEL_H_ -#define VPX_VP9_ENCODER_VP9_TPL_MODEL_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef M_LOG2_E -#define M_LOG2_E 0.693147180559945309417 -#endif -#define log2f(x) (log(x) / (float)M_LOG2_E) - -#define TPL_DEP_COST_SCALE_LOG2 4 - -typedef struct GF_PICTURE { - YV12_BUFFER_CONFIG *frame; - int ref_frame[3]; - FRAME_UPDATE_TYPE update_type; -} GF_PICTURE; - -void vp9_init_tpl_buffer(VP9_COMP *cpi); -void vp9_setup_tpl_stats(VP9_COMP *cpi); -void vp9_free_tpl_buffer(VP9_COMP *cpi); -void vp9_estimate_tpl_qp_gop(VP9_COMP *cpi); - -void vp9_wht_fwd_txfm(int16_t *src_diff, int bw, tran_low_t *coeff, - TX_SIZE tx_size); -#if CONFIG_VP9_HIGHBITDEPTH -void vp9_highbd_wht_fwd_txfm(int16_t *src_diff, int bw, tran_low_t *coeff, - TX_SIZE tx_size); -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_TPL_MODEL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_treewriter.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_treewriter.c deleted file mode 100644 index 0fc078e0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_treewriter.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vp9/encoder/vp9_treewriter.h" - -static void tree2tok(struct vp9_token *tokens, const vpx_tree_index *tree, - int i, int v, int l) { - v += v; - ++l; - - do { - const vpx_tree_index j = tree[i++]; - if (j <= 0) { - tokens[-j].value = v; - tokens[-j].len = l; - } else { - tree2tok(tokens, tree, j, v, l); - } - } while (++v & 1); -} - -void vp9_tokens_from_tree(struct vp9_token *tokens, - const vpx_tree_index *tree) { - tree2tok(tokens, tree, 0, 0, 0); -} - -static unsigned int convert_distribution(unsigned int i, vpx_tree tree, - unsigned int branch_ct[][2], - const unsigned int num_events[]) { - unsigned int left, right; - - if (tree[i] <= 0) - left = num_events[-tree[i]]; - else - left = convert_distribution(tree[i], tree, branch_ct, num_events); - - if (tree[i + 1] <= 0) - right = num_events[-tree[i + 1]]; - else - right = convert_distribution(tree[i + 1], tree, branch_ct, num_events); - - branch_ct[i >> 1][0] = left; - branch_ct[i >> 1][1] = right; - return left + right; -} - -void vp9_tree_probs_from_distribution(vpx_tree tree, - unsigned int branch_ct[/* n-1 */][2], - const unsigned int num_events[/* n */]) { - convert_distribution(0, tree, branch_ct, num_events); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_treewriter.h b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_treewriter.h deleted file mode 100644 index 86c5fa22..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/vp9_treewriter.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_ENCODER_VP9_TREEWRITER_H_ -#define VPX_VP9_ENCODER_VP9_TREEWRITER_H_ - -#include "vpx_dsp/bitwriter.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vp9_tree_probs_from_distribution(vpx_tree tree, - unsigned int branch_ct[/* n - 1 */][2], - const unsigned int num_events[/* n */]); - -struct vp9_token { - int value; - int len; -}; - -void vp9_tokens_from_tree(struct vp9_token *, const vpx_tree_index *); - -static INLINE void vp9_write_tree(vpx_writer *w, const vpx_tree_index *tree, - const vpx_prob *probs, int bits, int len, - vpx_tree_index i) { - do { - const int bit = (bits >> --len) & 1; - vpx_write(w, bit, probs[i >> 1]); - i = tree[i + bit]; - } while (len); -} - -static INLINE void vp9_write_token(vpx_writer *w, const vpx_tree_index *tree, - const vpx_prob *probs, - const struct vp9_token *token) { - vp9_write_tree(w, tree, probs, token->value, token->len, 0); -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_ENCODER_VP9_TREEWRITER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/highbd_temporal_filter_sse4.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/highbd_temporal_filter_sse4.c deleted file mode 100644 index 97f182c6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/highbd_temporal_filter_sse4.c +++ /dev/null @@ -1,893 +0,0 @@ -/* - * Copyright (c) 2019 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_temporal_filter.h" -#include "vp9/encoder/vp9_temporal_filter_constants.h" - -// Compute (a-b)**2 for 8 pixels with size 16-bit -static INLINE void highbd_store_dist_8(const uint16_t *a, const uint16_t *b, - uint32_t *dst) { - const __m128i zero = _mm_setzero_si128(); - const __m128i a_reg = _mm_loadu_si128((const __m128i *)a); - const __m128i b_reg = _mm_loadu_si128((const __m128i *)b); - - const __m128i a_first = _mm_cvtepu16_epi32(a_reg); - const __m128i a_second = _mm_unpackhi_epi16(a_reg, zero); - const __m128i b_first = _mm_cvtepu16_epi32(b_reg); - const __m128i b_second = _mm_unpackhi_epi16(b_reg, zero); - - __m128i dist_first, dist_second; - - dist_first = _mm_sub_epi32(a_first, b_first); - dist_second = _mm_sub_epi32(a_second, b_second); - dist_first = _mm_mullo_epi32(dist_first, dist_first); - dist_second = _mm_mullo_epi32(dist_second, dist_second); - - _mm_storeu_si128((__m128i *)dst, dist_first); - _mm_storeu_si128((__m128i *)(dst + 4), dist_second); -} - -// Sum up three neighboring distortions for the pixels -static INLINE void highbd_get_sum_4(const uint32_t *dist, __m128i *sum) { - __m128i dist_reg, dist_left, dist_right; - - dist_reg = _mm_loadu_si128((const __m128i *)dist); - dist_left = _mm_loadu_si128((const __m128i *)(dist - 1)); - dist_right = _mm_loadu_si128((const __m128i *)(dist + 1)); - - *sum = _mm_add_epi32(dist_reg, dist_left); - *sum = _mm_add_epi32(*sum, dist_right); -} - -static INLINE void highbd_get_sum_8(const uint32_t *dist, __m128i *sum_first, - __m128i *sum_second) { - highbd_get_sum_4(dist, sum_first); - highbd_get_sum_4(dist + 4, sum_second); -} - -// Average the value based on the number of values summed (9 for pixels away -// from the border, 4 for pixels in corners, and 6 for other edge values, plus -// however many values from y/uv plane are). -// -// Add in the rounding factor and shift, clamp to 16, invert and shift. Multiply -// by weight. -static INLINE void highbd_average_4(__m128i *output, const __m128i *sum, - const __m128i *mul_constants, - const int strength, const int rounding, - const int weight) { - // _mm_srl_epi16 uses the lower 64 bit value for the shift. - const __m128i strength_u128 = _mm_set_epi32(0, 0, 0, strength); - const __m128i rounding_u32 = _mm_set1_epi32(rounding); - const __m128i weight_u32 = _mm_set1_epi32(weight); - const __m128i sixteen = _mm_set1_epi32(16); - const __m128i zero = _mm_setzero_si128(); - - // modifier * 3 / index; - const __m128i sum_lo = _mm_unpacklo_epi32(*sum, zero); - const __m128i sum_hi = _mm_unpackhi_epi32(*sum, zero); - const __m128i const_lo = _mm_unpacklo_epi32(*mul_constants, zero); - const __m128i const_hi = _mm_unpackhi_epi32(*mul_constants, zero); - - const __m128i mul_lo = _mm_mul_epu32(sum_lo, const_lo); - const __m128i mul_lo_div = _mm_srli_epi64(mul_lo, 32); - const __m128i mul_hi = _mm_mul_epu32(sum_hi, const_hi); - const __m128i mul_hi_div = _mm_srli_epi64(mul_hi, 32); - - // Now we have - // mul_lo: 00 a1 00 a0 - // mul_hi: 00 a3 00 a2 - // Unpack as 64 bit words to get even and odd elements - // unpack_lo: 00 a2 00 a0 - // unpack_hi: 00 a3 00 a1 - // Then we can shift and OR the results to get everything in 32-bits - const __m128i mul_even = _mm_unpacklo_epi64(mul_lo_div, mul_hi_div); - const __m128i mul_odd = _mm_unpackhi_epi64(mul_lo_div, mul_hi_div); - const __m128i mul_odd_shift = _mm_slli_si128(mul_odd, 4); - const __m128i mul = _mm_or_si128(mul_even, mul_odd_shift); - - // Round - *output = _mm_add_epi32(mul, rounding_u32); - *output = _mm_srl_epi32(*output, strength_u128); - - // Multiply with the weight - *output = _mm_min_epu32(*output, sixteen); - *output = _mm_sub_epi32(sixteen, *output); - *output = _mm_mullo_epi32(*output, weight_u32); -} - -static INLINE void highbd_average_8(__m128i *output_0, __m128i *output_1, - const __m128i *sum_0_u32, - const __m128i *sum_1_u32, - const __m128i *mul_constants_0, - const __m128i *mul_constants_1, - const int strength, const int rounding, - const int weight) { - highbd_average_4(output_0, sum_0_u32, mul_constants_0, strength, rounding, - weight); - highbd_average_4(output_1, sum_1_u32, mul_constants_1, strength, rounding, - weight); -} - -// Add 'sum_u32' to 'count'. Multiply by 'pred' and add to 'accumulator.' -static INLINE void highbd_accumulate_and_store_8(const __m128i sum_first_u32, - const __m128i sum_second_u32, - const uint16_t *pred, - uint16_t *count, - uint32_t *accumulator) { - // Cast down to 16-bit ints - const __m128i sum_u16 = _mm_packus_epi32(sum_first_u32, sum_second_u32); - const __m128i zero = _mm_setzero_si128(); - - __m128i pred_u16 = _mm_loadu_si128((const __m128i *)pred); - __m128i count_u16 = _mm_loadu_si128((const __m128i *)count); - - __m128i pred_0_u32, pred_1_u32; - __m128i accum_0_u32, accum_1_u32; - - count_u16 = _mm_adds_epu16(count_u16, sum_u16); - _mm_storeu_si128((__m128i *)count, count_u16); - - pred_0_u32 = _mm_cvtepu16_epi32(pred_u16); - pred_1_u32 = _mm_unpackhi_epi16(pred_u16, zero); - - pred_0_u32 = _mm_mullo_epi32(sum_first_u32, pred_0_u32); - pred_1_u32 = _mm_mullo_epi32(sum_second_u32, pred_1_u32); - - accum_0_u32 = _mm_loadu_si128((const __m128i *)accumulator); - accum_1_u32 = _mm_loadu_si128((const __m128i *)(accumulator + 4)); - - accum_0_u32 = _mm_add_epi32(pred_0_u32, accum_0_u32); - accum_1_u32 = _mm_add_epi32(pred_1_u32, accum_1_u32); - - _mm_storeu_si128((__m128i *)accumulator, accum_0_u32); - _mm_storeu_si128((__m128i *)(accumulator + 4), accum_1_u32); -} - -static INLINE void highbd_read_dist_4(const uint32_t *dist, __m128i *dist_reg) { - *dist_reg = _mm_loadu_si128((const __m128i *)dist); -} - -static INLINE void highbd_read_dist_8(const uint32_t *dist, __m128i *reg_first, - __m128i *reg_second) { - highbd_read_dist_4(dist, reg_first); - highbd_read_dist_4(dist + 4, reg_second); -} - -static INLINE void highbd_read_chroma_dist_row_8( - int ss_x, const uint32_t *u_dist, const uint32_t *v_dist, __m128i *u_first, - __m128i *u_second, __m128i *v_first, __m128i *v_second) { - if (!ss_x) { - // If there is no chroma subsampling in the horizontal direction, then we - // need to load 8 entries from chroma. - highbd_read_dist_8(u_dist, u_first, u_second); - highbd_read_dist_8(v_dist, v_first, v_second); - } else { // ss_x == 1 - // Otherwise, we only need to load 8 entries - __m128i u_reg, v_reg; - - highbd_read_dist_4(u_dist, &u_reg); - - *u_first = _mm_unpacklo_epi32(u_reg, u_reg); - *u_second = _mm_unpackhi_epi32(u_reg, u_reg); - - highbd_read_dist_4(v_dist, &v_reg); - - *v_first = _mm_unpacklo_epi32(v_reg, v_reg); - *v_second = _mm_unpackhi_epi32(v_reg, v_reg); - } -} - -static void vp9_highbd_apply_temporal_filter_luma_8( - const uint16_t *y_pre, int y_pre_stride, unsigned int block_width, - unsigned int block_height, int ss_x, int ss_y, int strength, - int use_whole_blk, uint32_t *y_accum, uint16_t *y_count, - const uint32_t *y_dist, const uint32_t *u_dist, const uint32_t *v_dist, - const uint32_t *const *neighbors_first, - const uint32_t *const *neighbors_second, int top_weight, - int bottom_weight) { - const int rounding = (1 << strength) >> 1; - int weight = top_weight; - - __m128i mul_first, mul_second; - - __m128i sum_row_1_first, sum_row_1_second; - __m128i sum_row_2_first, sum_row_2_second; - __m128i sum_row_3_first, sum_row_3_second; - - __m128i u_first, u_second; - __m128i v_first, v_second; - - __m128i sum_row_first; - __m128i sum_row_second; - - // Loop variables - unsigned int h; - - assert(strength >= 4 && strength <= 14 && - "invalid adjusted temporal filter strength"); - assert(block_width == 8); - - (void)block_width; - - // First row - mul_first = _mm_load_si128((const __m128i *)neighbors_first[0]); - mul_second = _mm_load_si128((const __m128i *)neighbors_second[0]); - - // Add luma values - highbd_get_sum_8(y_dist, &sum_row_2_first, &sum_row_2_second); - highbd_get_sum_8(y_dist + DIST_STRIDE, &sum_row_3_first, &sum_row_3_second); - - // We don't need to saturate here because the maximum value is UINT12_MAX ** 2 - // * 9 ~= 2**24 * 9 < 2 ** 28 < INT32_MAX - sum_row_first = _mm_add_epi32(sum_row_2_first, sum_row_3_first); - sum_row_second = _mm_add_epi32(sum_row_2_second, sum_row_3_second); - - // Add chroma values - highbd_read_chroma_dist_row_8(ss_x, u_dist, v_dist, &u_first, &u_second, - &v_first, &v_second); - - // Max value here is 2 ** 24 * (9 + 2), so no saturation is needed - sum_row_first = _mm_add_epi32(sum_row_first, u_first); - sum_row_second = _mm_add_epi32(sum_row_second, u_second); - - sum_row_first = _mm_add_epi32(sum_row_first, v_first); - sum_row_second = _mm_add_epi32(sum_row_second, v_second); - - // Get modifier and store result - highbd_average_8(&sum_row_first, &sum_row_second, &sum_row_first, - &sum_row_second, &mul_first, &mul_second, strength, rounding, - weight); - - highbd_accumulate_and_store_8(sum_row_first, sum_row_second, y_pre, y_count, - y_accum); - - y_pre += y_pre_stride; - y_count += y_pre_stride; - y_accum += y_pre_stride; - y_dist += DIST_STRIDE; - - u_dist += DIST_STRIDE; - v_dist += DIST_STRIDE; - - // Then all the rows except the last one - mul_first = _mm_load_si128((const __m128i *)neighbors_first[1]); - mul_second = _mm_load_si128((const __m128i *)neighbors_second[1]); - - for (h = 1; h < block_height - 1; ++h) { - // Move the weight to bottom half - if (!use_whole_blk && h == block_height / 2) { - weight = bottom_weight; - } - // Shift the rows up - sum_row_1_first = sum_row_2_first; - sum_row_1_second = sum_row_2_second; - sum_row_2_first = sum_row_3_first; - sum_row_2_second = sum_row_3_second; - - // Add luma values to the modifier - sum_row_first = _mm_add_epi32(sum_row_1_first, sum_row_2_first); - sum_row_second = _mm_add_epi32(sum_row_1_second, sum_row_2_second); - - highbd_get_sum_8(y_dist + DIST_STRIDE, &sum_row_3_first, &sum_row_3_second); - - sum_row_first = _mm_add_epi32(sum_row_first, sum_row_3_first); - sum_row_second = _mm_add_epi32(sum_row_second, sum_row_3_second); - - // Add chroma values to the modifier - if (ss_y == 0 || h % 2 == 0) { - // Only calculate the new chroma distortion if we are at a pixel that - // corresponds to a new chroma row - highbd_read_chroma_dist_row_8(ss_x, u_dist, v_dist, &u_first, &u_second, - &v_first, &v_second); - - u_dist += DIST_STRIDE; - v_dist += DIST_STRIDE; - } - - sum_row_first = _mm_add_epi32(sum_row_first, u_first); - sum_row_second = _mm_add_epi32(sum_row_second, u_second); - sum_row_first = _mm_add_epi32(sum_row_first, v_first); - sum_row_second = _mm_add_epi32(sum_row_second, v_second); - - // Get modifier and store result - highbd_average_8(&sum_row_first, &sum_row_second, &sum_row_first, - &sum_row_second, &mul_first, &mul_second, strength, - rounding, weight); - highbd_accumulate_and_store_8(sum_row_first, sum_row_second, y_pre, y_count, - y_accum); - - y_pre += y_pre_stride; - y_count += y_pre_stride; - y_accum += y_pre_stride; - y_dist += DIST_STRIDE; - } - - // The last row - mul_first = _mm_load_si128((const __m128i *)neighbors_first[0]); - mul_second = _mm_load_si128((const __m128i *)neighbors_second[0]); - - // Shift the rows up - sum_row_1_first = sum_row_2_first; - sum_row_1_second = sum_row_2_second; - sum_row_2_first = sum_row_3_first; - sum_row_2_second = sum_row_3_second; - - // Add luma values to the modifier - sum_row_first = _mm_add_epi32(sum_row_1_first, sum_row_2_first); - sum_row_second = _mm_add_epi32(sum_row_1_second, sum_row_2_second); - - // Add chroma values to the modifier - if (ss_y == 0) { - // Only calculate the new chroma distortion if we are at a pixel that - // corresponds to a new chroma row - highbd_read_chroma_dist_row_8(ss_x, u_dist, v_dist, &u_first, &u_second, - &v_first, &v_second); - } - - sum_row_first = _mm_add_epi32(sum_row_first, u_first); - sum_row_second = _mm_add_epi32(sum_row_second, u_second); - sum_row_first = _mm_add_epi32(sum_row_first, v_first); - sum_row_second = _mm_add_epi32(sum_row_second, v_second); - - // Get modifier and store result - highbd_average_8(&sum_row_first, &sum_row_second, &sum_row_first, - &sum_row_second, &mul_first, &mul_second, strength, rounding, - weight); - highbd_accumulate_and_store_8(sum_row_first, sum_row_second, y_pre, y_count, - y_accum); -} - -// Perform temporal filter for the luma component. -static void vp9_highbd_apply_temporal_filter_luma( - const uint16_t *y_pre, int y_pre_stride, unsigned int block_width, - unsigned int block_height, int ss_x, int ss_y, int strength, - const int *blk_fw, int use_whole_blk, uint32_t *y_accum, uint16_t *y_count, - const uint32_t *y_dist, const uint32_t *u_dist, const uint32_t *v_dist) { - unsigned int blk_col = 0, uv_blk_col = 0; - const unsigned int blk_col_step = 8, uv_blk_col_step = 8 >> ss_x; - const unsigned int mid_width = block_width >> 1, - last_width = block_width - blk_col_step; - int top_weight = blk_fw[0], - bottom_weight = use_whole_blk ? blk_fw[0] : blk_fw[2]; - const uint32_t *const *neighbors_first; - const uint32_t *const *neighbors_second; - - // Left - neighbors_first = HIGHBD_LUMA_LEFT_COLUMN_NEIGHBORS; - neighbors_second = HIGHBD_LUMA_MIDDLE_COLUMN_NEIGHBORS; - vp9_highbd_apply_temporal_filter_luma_8( - y_pre + blk_col, y_pre_stride, blk_col_step, block_height, ss_x, ss_y, - strength, use_whole_blk, y_accum + blk_col, y_count + blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, - neighbors_first, neighbors_second, top_weight, bottom_weight); - - blk_col += blk_col_step; - uv_blk_col += uv_blk_col_step; - - // Middle First - neighbors_first = HIGHBD_LUMA_MIDDLE_COLUMN_NEIGHBORS; - for (; blk_col < mid_width; - blk_col += blk_col_step, uv_blk_col += uv_blk_col_step) { - vp9_highbd_apply_temporal_filter_luma_8( - y_pre + blk_col, y_pre_stride, blk_col_step, block_height, ss_x, ss_y, - strength, use_whole_blk, y_accum + blk_col, y_count + blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, - neighbors_first, neighbors_second, top_weight, bottom_weight); - } - - if (!use_whole_blk) { - top_weight = blk_fw[1]; - bottom_weight = blk_fw[3]; - } - - // Middle Second - for (; blk_col < last_width; - blk_col += blk_col_step, uv_blk_col += uv_blk_col_step) { - vp9_highbd_apply_temporal_filter_luma_8( - y_pre + blk_col, y_pre_stride, blk_col_step, block_height, ss_x, ss_y, - strength, use_whole_blk, y_accum + blk_col, y_count + blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, - neighbors_first, neighbors_second, top_weight, bottom_weight); - } - - // Right - neighbors_second = HIGHBD_LUMA_RIGHT_COLUMN_NEIGHBORS; - vp9_highbd_apply_temporal_filter_luma_8( - y_pre + blk_col, y_pre_stride, blk_col_step, block_height, ss_x, ss_y, - strength, use_whole_blk, y_accum + blk_col, y_count + blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, - neighbors_first, neighbors_second, top_weight, bottom_weight); -} - -// Add a row of luma distortion that corresponds to 8 chroma mods. If we are -// subsampling in x direction, then we have 16 lumas, else we have 8. -static INLINE void highbd_add_luma_dist_to_8_chroma_mod( - const uint32_t *y_dist, int ss_x, int ss_y, __m128i *u_mod_fst, - __m128i *u_mod_snd, __m128i *v_mod_fst, __m128i *v_mod_snd) { - __m128i y_reg_fst, y_reg_snd; - if (!ss_x) { - highbd_read_dist_8(y_dist, &y_reg_fst, &y_reg_snd); - if (ss_y == 1) { - __m128i y_tmp_fst, y_tmp_snd; - highbd_read_dist_8(y_dist + DIST_STRIDE, &y_tmp_fst, &y_tmp_snd); - y_reg_fst = _mm_add_epi32(y_reg_fst, y_tmp_fst); - y_reg_snd = _mm_add_epi32(y_reg_snd, y_tmp_snd); - } - } else { - // Temporary - __m128i y_fst, y_snd; - - // First 8 - highbd_read_dist_8(y_dist, &y_fst, &y_snd); - if (ss_y == 1) { - __m128i y_tmp_fst, y_tmp_snd; - highbd_read_dist_8(y_dist + DIST_STRIDE, &y_tmp_fst, &y_tmp_snd); - - y_fst = _mm_add_epi32(y_fst, y_tmp_fst); - y_snd = _mm_add_epi32(y_snd, y_tmp_snd); - } - - y_reg_fst = _mm_hadd_epi32(y_fst, y_snd); - - // Second 8 - highbd_read_dist_8(y_dist + 8, &y_fst, &y_snd); - if (ss_y == 1) { - __m128i y_tmp_fst, y_tmp_snd; - highbd_read_dist_8(y_dist + 8 + DIST_STRIDE, &y_tmp_fst, &y_tmp_snd); - - y_fst = _mm_add_epi32(y_fst, y_tmp_fst); - y_snd = _mm_add_epi32(y_snd, y_tmp_snd); - } - - y_reg_snd = _mm_hadd_epi32(y_fst, y_snd); - } - - *u_mod_fst = _mm_add_epi32(*u_mod_fst, y_reg_fst); - *u_mod_snd = _mm_add_epi32(*u_mod_snd, y_reg_snd); - *v_mod_fst = _mm_add_epi32(*v_mod_fst, y_reg_fst); - *v_mod_snd = _mm_add_epi32(*v_mod_snd, y_reg_snd); -} - -// Apply temporal filter to the chroma components. This performs temporal -// filtering on a chroma block of 8 X uv_height. If blk_fw is not NULL, use -// blk_fw as an array of size 4 for the weights for each of the 4 subblocks, -// else use top_weight for top half, and bottom weight for bottom half. -static void vp9_highbd_apply_temporal_filter_chroma_8( - const uint16_t *u_pre, const uint16_t *v_pre, int uv_pre_stride, - unsigned int uv_block_width, unsigned int uv_block_height, int ss_x, - int ss_y, int strength, uint32_t *u_accum, uint16_t *u_count, - uint32_t *v_accum, uint16_t *v_count, const uint32_t *y_dist, - const uint32_t *u_dist, const uint32_t *v_dist, - const uint32_t *const *neighbors_fst, const uint32_t *const *neighbors_snd, - int top_weight, int bottom_weight, const int *blk_fw) { - const int rounding = (1 << strength) >> 1; - int weight = top_weight; - - __m128i mul_fst, mul_snd; - - __m128i u_sum_row_1_fst, u_sum_row_2_fst, u_sum_row_3_fst; - __m128i v_sum_row_1_fst, v_sum_row_2_fst, v_sum_row_3_fst; - __m128i u_sum_row_1_snd, u_sum_row_2_snd, u_sum_row_3_snd; - __m128i v_sum_row_1_snd, v_sum_row_2_snd, v_sum_row_3_snd; - - __m128i u_sum_row_fst, v_sum_row_fst; - __m128i u_sum_row_snd, v_sum_row_snd; - - // Loop variable - unsigned int h; - - (void)uv_block_width; - - // First row - mul_fst = _mm_load_si128((const __m128i *)neighbors_fst[0]); - mul_snd = _mm_load_si128((const __m128i *)neighbors_snd[0]); - - // Add chroma values - highbd_get_sum_8(u_dist, &u_sum_row_2_fst, &u_sum_row_2_snd); - highbd_get_sum_8(u_dist + DIST_STRIDE, &u_sum_row_3_fst, &u_sum_row_3_snd); - - u_sum_row_fst = _mm_add_epi32(u_sum_row_2_fst, u_sum_row_3_fst); - u_sum_row_snd = _mm_add_epi32(u_sum_row_2_snd, u_sum_row_3_snd); - - highbd_get_sum_8(v_dist, &v_sum_row_2_fst, &v_sum_row_2_snd); - highbd_get_sum_8(v_dist + DIST_STRIDE, &v_sum_row_3_fst, &v_sum_row_3_snd); - - v_sum_row_fst = _mm_add_epi32(v_sum_row_2_fst, v_sum_row_3_fst); - v_sum_row_snd = _mm_add_epi32(v_sum_row_2_snd, v_sum_row_3_snd); - - // Add luma values - highbd_add_luma_dist_to_8_chroma_mod(y_dist, ss_x, ss_y, &u_sum_row_fst, - &u_sum_row_snd, &v_sum_row_fst, - &v_sum_row_snd); - - // Get modifier and store result - if (blk_fw) { - highbd_average_4(&u_sum_row_fst, &u_sum_row_fst, &mul_fst, strength, - rounding, blk_fw[0]); - highbd_average_4(&u_sum_row_snd, &u_sum_row_snd, &mul_snd, strength, - rounding, blk_fw[1]); - - highbd_average_4(&v_sum_row_fst, &v_sum_row_fst, &mul_fst, strength, - rounding, blk_fw[0]); - highbd_average_4(&v_sum_row_snd, &v_sum_row_snd, &mul_snd, strength, - rounding, blk_fw[1]); - - } else { - highbd_average_8(&u_sum_row_fst, &u_sum_row_snd, &u_sum_row_fst, - &u_sum_row_snd, &mul_fst, &mul_snd, strength, rounding, - weight); - highbd_average_8(&v_sum_row_fst, &v_sum_row_snd, &v_sum_row_fst, - &v_sum_row_snd, &mul_fst, &mul_snd, strength, rounding, - weight); - } - highbd_accumulate_and_store_8(u_sum_row_fst, u_sum_row_snd, u_pre, u_count, - u_accum); - highbd_accumulate_and_store_8(v_sum_row_fst, v_sum_row_snd, v_pre, v_count, - v_accum); - - u_pre += uv_pre_stride; - u_dist += DIST_STRIDE; - v_pre += uv_pre_stride; - v_dist += DIST_STRIDE; - u_count += uv_pre_stride; - u_accum += uv_pre_stride; - v_count += uv_pre_stride; - v_accum += uv_pre_stride; - - y_dist += DIST_STRIDE * (1 + ss_y); - - // Then all the rows except the last one - mul_fst = _mm_load_si128((const __m128i *)neighbors_fst[1]); - mul_snd = _mm_load_si128((const __m128i *)neighbors_snd[1]); - - for (h = 1; h < uv_block_height - 1; ++h) { - // Move the weight pointer to the bottom half of the blocks - if (h == uv_block_height / 2) { - if (blk_fw) { - blk_fw += 2; - } else { - weight = bottom_weight; - } - } - - // Shift the rows up - u_sum_row_1_fst = u_sum_row_2_fst; - u_sum_row_2_fst = u_sum_row_3_fst; - u_sum_row_1_snd = u_sum_row_2_snd; - u_sum_row_2_snd = u_sum_row_3_snd; - - v_sum_row_1_fst = v_sum_row_2_fst; - v_sum_row_2_fst = v_sum_row_3_fst; - v_sum_row_1_snd = v_sum_row_2_snd; - v_sum_row_2_snd = v_sum_row_3_snd; - - // Add chroma values - u_sum_row_fst = _mm_add_epi32(u_sum_row_1_fst, u_sum_row_2_fst); - u_sum_row_snd = _mm_add_epi32(u_sum_row_1_snd, u_sum_row_2_snd); - highbd_get_sum_8(u_dist + DIST_STRIDE, &u_sum_row_3_fst, &u_sum_row_3_snd); - u_sum_row_fst = _mm_add_epi32(u_sum_row_fst, u_sum_row_3_fst); - u_sum_row_snd = _mm_add_epi32(u_sum_row_snd, u_sum_row_3_snd); - - v_sum_row_fst = _mm_add_epi32(v_sum_row_1_fst, v_sum_row_2_fst); - v_sum_row_snd = _mm_add_epi32(v_sum_row_1_snd, v_sum_row_2_snd); - highbd_get_sum_8(v_dist + DIST_STRIDE, &v_sum_row_3_fst, &v_sum_row_3_snd); - v_sum_row_fst = _mm_add_epi32(v_sum_row_fst, v_sum_row_3_fst); - v_sum_row_snd = _mm_add_epi32(v_sum_row_snd, v_sum_row_3_snd); - - // Add luma values - highbd_add_luma_dist_to_8_chroma_mod(y_dist, ss_x, ss_y, &u_sum_row_fst, - &u_sum_row_snd, &v_sum_row_fst, - &v_sum_row_snd); - - // Get modifier and store result - if (blk_fw) { - highbd_average_4(&u_sum_row_fst, &u_sum_row_fst, &mul_fst, strength, - rounding, blk_fw[0]); - highbd_average_4(&u_sum_row_snd, &u_sum_row_snd, &mul_snd, strength, - rounding, blk_fw[1]); - - highbd_average_4(&v_sum_row_fst, &v_sum_row_fst, &mul_fst, strength, - rounding, blk_fw[0]); - highbd_average_4(&v_sum_row_snd, &v_sum_row_snd, &mul_snd, strength, - rounding, blk_fw[1]); - - } else { - highbd_average_8(&u_sum_row_fst, &u_sum_row_snd, &u_sum_row_fst, - &u_sum_row_snd, &mul_fst, &mul_snd, strength, rounding, - weight); - highbd_average_8(&v_sum_row_fst, &v_sum_row_snd, &v_sum_row_fst, - &v_sum_row_snd, &mul_fst, &mul_snd, strength, rounding, - weight); - } - - highbd_accumulate_and_store_8(u_sum_row_fst, u_sum_row_snd, u_pre, u_count, - u_accum); - highbd_accumulate_and_store_8(v_sum_row_fst, v_sum_row_snd, v_pre, v_count, - v_accum); - - u_pre += uv_pre_stride; - u_dist += DIST_STRIDE; - v_pre += uv_pre_stride; - v_dist += DIST_STRIDE; - u_count += uv_pre_stride; - u_accum += uv_pre_stride; - v_count += uv_pre_stride; - v_accum += uv_pre_stride; - - y_dist += DIST_STRIDE * (1 + ss_y); - } - - // The last row - mul_fst = _mm_load_si128((const __m128i *)neighbors_fst[0]); - mul_snd = _mm_load_si128((const __m128i *)neighbors_snd[0]); - - // Shift the rows up - u_sum_row_1_fst = u_sum_row_2_fst; - u_sum_row_2_fst = u_sum_row_3_fst; - u_sum_row_1_snd = u_sum_row_2_snd; - u_sum_row_2_snd = u_sum_row_3_snd; - - v_sum_row_1_fst = v_sum_row_2_fst; - v_sum_row_2_fst = v_sum_row_3_fst; - v_sum_row_1_snd = v_sum_row_2_snd; - v_sum_row_2_snd = v_sum_row_3_snd; - - // Add chroma values - u_sum_row_fst = _mm_add_epi32(u_sum_row_1_fst, u_sum_row_2_fst); - v_sum_row_fst = _mm_add_epi32(v_sum_row_1_fst, v_sum_row_2_fst); - u_sum_row_snd = _mm_add_epi32(u_sum_row_1_snd, u_sum_row_2_snd); - v_sum_row_snd = _mm_add_epi32(v_sum_row_1_snd, v_sum_row_2_snd); - - // Add luma values - highbd_add_luma_dist_to_8_chroma_mod(y_dist, ss_x, ss_y, &u_sum_row_fst, - &u_sum_row_snd, &v_sum_row_fst, - &v_sum_row_snd); - - // Get modifier and store result - if (blk_fw) { - highbd_average_4(&u_sum_row_fst, &u_sum_row_fst, &mul_fst, strength, - rounding, blk_fw[0]); - highbd_average_4(&u_sum_row_snd, &u_sum_row_snd, &mul_snd, strength, - rounding, blk_fw[1]); - - highbd_average_4(&v_sum_row_fst, &v_sum_row_fst, &mul_fst, strength, - rounding, blk_fw[0]); - highbd_average_4(&v_sum_row_snd, &v_sum_row_snd, &mul_snd, strength, - rounding, blk_fw[1]); - - } else { - highbd_average_8(&u_sum_row_fst, &u_sum_row_snd, &u_sum_row_fst, - &u_sum_row_snd, &mul_fst, &mul_snd, strength, rounding, - weight); - highbd_average_8(&v_sum_row_fst, &v_sum_row_snd, &v_sum_row_fst, - &v_sum_row_snd, &mul_fst, &mul_snd, strength, rounding, - weight); - } - - highbd_accumulate_and_store_8(u_sum_row_fst, u_sum_row_snd, u_pre, u_count, - u_accum); - highbd_accumulate_and_store_8(v_sum_row_fst, v_sum_row_snd, v_pre, v_count, - v_accum); -} - -// Perform temporal filter for the chroma components. -static void vp9_highbd_apply_temporal_filter_chroma( - const uint16_t *u_pre, const uint16_t *v_pre, int uv_pre_stride, - unsigned int block_width, unsigned int block_height, int ss_x, int ss_y, - int strength, const int *blk_fw, int use_whole_blk, uint32_t *u_accum, - uint16_t *u_count, uint32_t *v_accum, uint16_t *v_count, - const uint32_t *y_dist, const uint32_t *u_dist, const uint32_t *v_dist) { - const unsigned int uv_width = block_width >> ss_x, - uv_height = block_height >> ss_y; - - unsigned int blk_col = 0, uv_blk_col = 0; - const unsigned int uv_blk_col_step = 8, blk_col_step = 8 << ss_x; - const unsigned int uv_mid_width = uv_width >> 1, - uv_last_width = uv_width - uv_blk_col_step; - int top_weight = blk_fw[0], - bottom_weight = use_whole_blk ? blk_fw[0] : blk_fw[2]; - const uint32_t *const *neighbors_fst; - const uint32_t *const *neighbors_snd; - - if (uv_width == 8) { - // Special Case: We are subsampling in x direction on a 16x16 block. Since - // we are operating on a row of 8 chroma pixels, we can't use the usual - // left-middle-right pattern. - assert(ss_x); - - if (ss_y) { - neighbors_fst = HIGHBD_CHROMA_DOUBLE_SS_LEFT_COLUMN_NEIGHBORS; - neighbors_snd = HIGHBD_CHROMA_DOUBLE_SS_RIGHT_COLUMN_NEIGHBORS; - } else { - neighbors_fst = HIGHBD_CHROMA_SINGLE_SS_LEFT_COLUMN_NEIGHBORS; - neighbors_snd = HIGHBD_CHROMA_SINGLE_SS_RIGHT_COLUMN_NEIGHBORS; - } - - if (use_whole_blk) { - vp9_highbd_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_width, - uv_height, ss_x, ss_y, strength, u_accum + uv_blk_col, - u_count + uv_blk_col, v_accum + uv_blk_col, v_count + uv_blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, - neighbors_fst, neighbors_snd, top_weight, bottom_weight, NULL); - } else { - vp9_highbd_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_width, - uv_height, ss_x, ss_y, strength, u_accum + uv_blk_col, - u_count + uv_blk_col, v_accum + uv_blk_col, v_count + uv_blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, - neighbors_fst, neighbors_snd, 0, 0, blk_fw); - } - - return; - } - - // Left - if (ss_x && ss_y) { - neighbors_fst = HIGHBD_CHROMA_DOUBLE_SS_LEFT_COLUMN_NEIGHBORS; - neighbors_snd = HIGHBD_CHROMA_DOUBLE_SS_MIDDLE_COLUMN_NEIGHBORS; - } else if (ss_x || ss_y) { - neighbors_fst = HIGHBD_CHROMA_SINGLE_SS_LEFT_COLUMN_NEIGHBORS; - neighbors_snd = HIGHBD_CHROMA_SINGLE_SS_MIDDLE_COLUMN_NEIGHBORS; - } else { - neighbors_fst = HIGHBD_CHROMA_NO_SS_LEFT_COLUMN_NEIGHBORS; - neighbors_snd = HIGHBD_CHROMA_NO_SS_MIDDLE_COLUMN_NEIGHBORS; - } - - vp9_highbd_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_width, - uv_height, ss_x, ss_y, strength, u_accum + uv_blk_col, - u_count + uv_blk_col, v_accum + uv_blk_col, v_count + uv_blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors_fst, - neighbors_snd, top_weight, bottom_weight, NULL); - - blk_col += blk_col_step; - uv_blk_col += uv_blk_col_step; - - // Middle First - if (ss_x && ss_y) { - neighbors_fst = HIGHBD_CHROMA_DOUBLE_SS_MIDDLE_COLUMN_NEIGHBORS; - } else if (ss_x || ss_y) { - neighbors_fst = HIGHBD_CHROMA_SINGLE_SS_MIDDLE_COLUMN_NEIGHBORS; - } else { - neighbors_fst = HIGHBD_CHROMA_NO_SS_MIDDLE_COLUMN_NEIGHBORS; - } - - for (; uv_blk_col < uv_mid_width; - blk_col += blk_col_step, uv_blk_col += uv_blk_col_step) { - vp9_highbd_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_width, - uv_height, ss_x, ss_y, strength, u_accum + uv_blk_col, - u_count + uv_blk_col, v_accum + uv_blk_col, v_count + uv_blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, - neighbors_fst, neighbors_snd, top_weight, bottom_weight, NULL); - } - - if (!use_whole_blk) { - top_weight = blk_fw[1]; - bottom_weight = blk_fw[3]; - } - - // Middle Second - for (; uv_blk_col < uv_last_width; - blk_col += blk_col_step, uv_blk_col += uv_blk_col_step) { - vp9_highbd_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_width, - uv_height, ss_x, ss_y, strength, u_accum + uv_blk_col, - u_count + uv_blk_col, v_accum + uv_blk_col, v_count + uv_blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, - neighbors_fst, neighbors_snd, top_weight, bottom_weight, NULL); - } - - // Right - if (ss_x && ss_y) { - neighbors_snd = HIGHBD_CHROMA_DOUBLE_SS_RIGHT_COLUMN_NEIGHBORS; - } else if (ss_x || ss_y) { - neighbors_snd = HIGHBD_CHROMA_SINGLE_SS_RIGHT_COLUMN_NEIGHBORS; - } else { - neighbors_snd = HIGHBD_CHROMA_NO_SS_RIGHT_COLUMN_NEIGHBORS; - } - - vp9_highbd_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_width, - uv_height, ss_x, ss_y, strength, u_accum + uv_blk_col, - u_count + uv_blk_col, v_accum + uv_blk_col, v_count + uv_blk_col, - y_dist + blk_col, u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors_fst, - neighbors_snd, top_weight, bottom_weight, NULL); -} - -void vp9_highbd_apply_temporal_filter_sse4_1( - const uint16_t *y_src, int y_src_stride, const uint16_t *y_pre, - int y_pre_stride, const uint16_t *u_src, const uint16_t *v_src, - int uv_src_stride, const uint16_t *u_pre, const uint16_t *v_pre, - int uv_pre_stride, unsigned int block_width, unsigned int block_height, - int ss_x, int ss_y, int strength, const int *const blk_fw, - int use_whole_blk, uint32_t *y_accum, uint16_t *y_count, uint32_t *u_accum, - uint16_t *u_count, uint32_t *v_accum, uint16_t *v_count) { - const unsigned int chroma_height = block_height >> ss_y, - chroma_width = block_width >> ss_x; - - DECLARE_ALIGNED(16, uint32_t, y_dist[BH * DIST_STRIDE]) = { 0 }; - DECLARE_ALIGNED(16, uint32_t, u_dist[BH * DIST_STRIDE]) = { 0 }; - DECLARE_ALIGNED(16, uint32_t, v_dist[BH * DIST_STRIDE]) = { 0 }; - - uint32_t *y_dist_ptr = y_dist + 1, *u_dist_ptr = u_dist + 1, - *v_dist_ptr = v_dist + 1; - const uint16_t *y_src_ptr = y_src, *u_src_ptr = u_src, *v_src_ptr = v_src; - const uint16_t *y_pre_ptr = y_pre, *u_pre_ptr = u_pre, *v_pre_ptr = v_pre; - - // Loop variables - unsigned int row, blk_col; - - assert(block_width <= BW && "block width too large"); - assert(block_height <= BH && "block height too large"); - assert(block_width % 16 == 0 && "block width must be multiple of 16"); - assert(block_height % 2 == 0 && "block height must be even"); - assert((ss_x == 0 || ss_x == 1) && (ss_y == 0 || ss_y == 1) && - "invalid chroma subsampling"); - assert(strength >= 4 && strength <= 14 && - "invalid adjusted temporal filter strength"); - assert(blk_fw[0] >= 0 && "filter weight must be positive"); - assert( - (use_whole_blk || (blk_fw[1] >= 0 && blk_fw[2] >= 0 && blk_fw[3] >= 0)) && - "subblock filter weight must be positive"); - assert(blk_fw[0] <= 2 && "sublock filter weight must be less than 2"); - assert( - (use_whole_blk || (blk_fw[1] <= 2 && blk_fw[2] <= 2 && blk_fw[3] <= 2)) && - "subblock filter weight must be less than 2"); - - // Precompute the difference squared - for (row = 0; row < block_height; row++) { - for (blk_col = 0; blk_col < block_width; blk_col += 8) { - highbd_store_dist_8(y_src_ptr + blk_col, y_pre_ptr + blk_col, - y_dist_ptr + blk_col); - } - y_src_ptr += y_src_stride; - y_pre_ptr += y_pre_stride; - y_dist_ptr += DIST_STRIDE; - } - - for (row = 0; row < chroma_height; row++) { - for (blk_col = 0; blk_col < chroma_width; blk_col += 8) { - highbd_store_dist_8(u_src_ptr + blk_col, u_pre_ptr + blk_col, - u_dist_ptr + blk_col); - highbd_store_dist_8(v_src_ptr + blk_col, v_pre_ptr + blk_col, - v_dist_ptr + blk_col); - } - - u_src_ptr += uv_src_stride; - u_pre_ptr += uv_pre_stride; - u_dist_ptr += DIST_STRIDE; - v_src_ptr += uv_src_stride; - v_pre_ptr += uv_pre_stride; - v_dist_ptr += DIST_STRIDE; - } - - y_dist_ptr = y_dist + 1; - u_dist_ptr = u_dist + 1; - v_dist_ptr = v_dist + 1; - - vp9_highbd_apply_temporal_filter_luma(y_pre, y_pre_stride, block_width, - block_height, ss_x, ss_y, strength, - blk_fw, use_whole_blk, y_accum, y_count, - y_dist_ptr, u_dist_ptr, v_dist_ptr); - - vp9_highbd_apply_temporal_filter_chroma( - u_pre, v_pre, uv_pre_stride, block_width, block_height, ss_x, ss_y, - strength, blk_fw, use_whole_blk, u_accum, u_count, v_accum, v_count, - y_dist_ptr, u_dist_ptr, v_dist_ptr); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/temporal_filter_sse4.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/temporal_filter_sse4.c deleted file mode 100644 index 7571bfcc..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/temporal_filter_sse4.c +++ /dev/null @@ -1,875 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vp9_rtcd.h" -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_temporal_filter.h" -#include "vp9/encoder/vp9_temporal_filter_constants.h" - -// Read in 8 pixels from a and b as 8-bit unsigned integers, compute the -// difference squared, and store as unsigned 16-bit integer to dst. -static INLINE void store_dist_8(const uint8_t *a, const uint8_t *b, - uint16_t *dst) { - const __m128i a_reg = _mm_loadl_epi64((const __m128i *)a); - const __m128i b_reg = _mm_loadl_epi64((const __m128i *)b); - - const __m128i a_first = _mm_cvtepu8_epi16(a_reg); - const __m128i b_first = _mm_cvtepu8_epi16(b_reg); - - __m128i dist_first; - - dist_first = _mm_sub_epi16(a_first, b_first); - dist_first = _mm_mullo_epi16(dist_first, dist_first); - - _mm_storeu_si128((__m128i *)dst, dist_first); -} - -static INLINE void store_dist_16(const uint8_t *a, const uint8_t *b, - uint16_t *dst) { - const __m128i zero = _mm_setzero_si128(); - const __m128i a_reg = _mm_loadu_si128((const __m128i *)a); - const __m128i b_reg = _mm_loadu_si128((const __m128i *)b); - - const __m128i a_first = _mm_cvtepu8_epi16(a_reg); - const __m128i a_second = _mm_unpackhi_epi8(a_reg, zero); - const __m128i b_first = _mm_cvtepu8_epi16(b_reg); - const __m128i b_second = _mm_unpackhi_epi8(b_reg, zero); - - __m128i dist_first, dist_second; - - dist_first = _mm_sub_epi16(a_first, b_first); - dist_second = _mm_sub_epi16(a_second, b_second); - dist_first = _mm_mullo_epi16(dist_first, dist_first); - dist_second = _mm_mullo_epi16(dist_second, dist_second); - - _mm_storeu_si128((__m128i *)dst, dist_first); - _mm_storeu_si128((__m128i *)(dst + 8), dist_second); -} - -static INLINE void read_dist_8(const uint16_t *dist, __m128i *dist_reg) { - *dist_reg = _mm_loadu_si128((const __m128i *)dist); -} - -static INLINE void read_dist_16(const uint16_t *dist, __m128i *reg_first, - __m128i *reg_second) { - read_dist_8(dist, reg_first); - read_dist_8(dist + 8, reg_second); -} - -// Average the value based on the number of values summed (9 for pixels away -// from the border, 4 for pixels in corners, and 6 for other edge values). -// -// Add in the rounding factor and shift, clamp to 16, invert and shift. Multiply -// by weight. -static INLINE __m128i average_8(__m128i sum, const __m128i *mul_constants, - const int strength, const int rounding, - const __m128i *weight) { - // _mm_srl_epi16 uses the lower 64 bit value for the shift. - const __m128i strength_u128 = _mm_set_epi32(0, 0, 0, strength); - const __m128i rounding_u16 = _mm_set1_epi16(rounding); - const __m128i weight_u16 = *weight; - const __m128i sixteen = _mm_set1_epi16(16); - - // modifier * 3 / index; - sum = _mm_mulhi_epu16(sum, *mul_constants); - - sum = _mm_adds_epu16(sum, rounding_u16); - sum = _mm_srl_epi16(sum, strength_u128); - - // The maximum input to this comparison is UINT16_MAX * NEIGHBOR_CONSTANT_4 - // >> 16 (also NEIGHBOR_CONSTANT_4 -1) which is 49151 / 0xbfff / -16385 - // So this needs to use the epu16 version which did not come until SSE4. - sum = _mm_min_epu16(sum, sixteen); - - sum = _mm_sub_epi16(sixteen, sum); - - return _mm_mullo_epi16(sum, weight_u16); -} - -// Add 'sum_u16' to 'count'. Multiply by 'pred' and add to 'accumulator.' -static void accumulate_and_store_8(const __m128i sum_u16, const uint8_t *pred, - uint16_t *count, uint32_t *accumulator) { - const __m128i pred_u8 = _mm_loadl_epi64((const __m128i *)pred); - const __m128i zero = _mm_setzero_si128(); - __m128i count_u16 = _mm_loadu_si128((const __m128i *)count); - __m128i pred_u16 = _mm_cvtepu8_epi16(pred_u8); - __m128i pred_0_u32, pred_1_u32; - __m128i accum_0_u32, accum_1_u32; - - count_u16 = _mm_adds_epu16(count_u16, sum_u16); - _mm_storeu_si128((__m128i *)count, count_u16); - - pred_u16 = _mm_mullo_epi16(sum_u16, pred_u16); - - pred_0_u32 = _mm_cvtepu16_epi32(pred_u16); - pred_1_u32 = _mm_unpackhi_epi16(pred_u16, zero); - - accum_0_u32 = _mm_loadu_si128((const __m128i *)accumulator); - accum_1_u32 = _mm_loadu_si128((const __m128i *)(accumulator + 4)); - - accum_0_u32 = _mm_add_epi32(pred_0_u32, accum_0_u32); - accum_1_u32 = _mm_add_epi32(pred_1_u32, accum_1_u32); - - _mm_storeu_si128((__m128i *)accumulator, accum_0_u32); - _mm_storeu_si128((__m128i *)(accumulator + 4), accum_1_u32); -} - -static INLINE void accumulate_and_store_16(const __m128i sum_0_u16, - const __m128i sum_1_u16, - const uint8_t *pred, uint16_t *count, - uint32_t *accumulator) { - const __m128i pred_u8 = _mm_loadu_si128((const __m128i *)pred); - const __m128i zero = _mm_setzero_si128(); - __m128i count_0_u16 = _mm_loadu_si128((const __m128i *)count), - count_1_u16 = _mm_loadu_si128((const __m128i *)(count + 8)); - __m128i pred_0_u16 = _mm_cvtepu8_epi16(pred_u8), - pred_1_u16 = _mm_unpackhi_epi8(pred_u8, zero); - __m128i pred_0_u32, pred_1_u32, pred_2_u32, pred_3_u32; - __m128i accum_0_u32, accum_1_u32, accum_2_u32, accum_3_u32; - - count_0_u16 = _mm_adds_epu16(count_0_u16, sum_0_u16); - _mm_storeu_si128((__m128i *)count, count_0_u16); - - count_1_u16 = _mm_adds_epu16(count_1_u16, sum_1_u16); - _mm_storeu_si128((__m128i *)(count + 8), count_1_u16); - - pred_0_u16 = _mm_mullo_epi16(sum_0_u16, pred_0_u16); - pred_1_u16 = _mm_mullo_epi16(sum_1_u16, pred_1_u16); - - pred_0_u32 = _mm_cvtepu16_epi32(pred_0_u16); - pred_1_u32 = _mm_unpackhi_epi16(pred_0_u16, zero); - pred_2_u32 = _mm_cvtepu16_epi32(pred_1_u16); - pred_3_u32 = _mm_unpackhi_epi16(pred_1_u16, zero); - - accum_0_u32 = _mm_loadu_si128((const __m128i *)accumulator); - accum_1_u32 = _mm_loadu_si128((const __m128i *)(accumulator + 4)); - accum_2_u32 = _mm_loadu_si128((const __m128i *)(accumulator + 8)); - accum_3_u32 = _mm_loadu_si128((const __m128i *)(accumulator + 12)); - - accum_0_u32 = _mm_add_epi32(pred_0_u32, accum_0_u32); - accum_1_u32 = _mm_add_epi32(pred_1_u32, accum_1_u32); - accum_2_u32 = _mm_add_epi32(pred_2_u32, accum_2_u32); - accum_3_u32 = _mm_add_epi32(pred_3_u32, accum_3_u32); - - _mm_storeu_si128((__m128i *)accumulator, accum_0_u32); - _mm_storeu_si128((__m128i *)(accumulator + 4), accum_1_u32); - _mm_storeu_si128((__m128i *)(accumulator + 8), accum_2_u32); - _mm_storeu_si128((__m128i *)(accumulator + 12), accum_3_u32); -} - -// Read in 8 pixels from y_dist. For each index i, compute y_dist[i-1] + -// y_dist[i] + y_dist[i+1] and store in sum as 16-bit unsigned int. -static INLINE void get_sum_8(const uint16_t *y_dist, __m128i *sum) { - __m128i dist_reg, dist_left, dist_right; - - dist_reg = _mm_loadu_si128((const __m128i *)y_dist); - dist_left = _mm_loadu_si128((const __m128i *)(y_dist - 1)); - dist_right = _mm_loadu_si128((const __m128i *)(y_dist + 1)); - - *sum = _mm_adds_epu16(dist_reg, dist_left); - *sum = _mm_adds_epu16(*sum, dist_right); -} - -// Read in 16 pixels from y_dist. For each index i, compute y_dist[i-1] + -// y_dist[i] + y_dist[i+1]. Store the result for first 8 pixels in sum_first and -// the rest in sum_second. -static INLINE void get_sum_16(const uint16_t *y_dist, __m128i *sum_first, - __m128i *sum_second) { - get_sum_8(y_dist, sum_first); - get_sum_8(y_dist + 8, sum_second); -} - -// Read in a row of chroma values corresponds to a row of 16 luma values. -static INLINE void read_chroma_dist_row_16(int ss_x, const uint16_t *u_dist, - const uint16_t *v_dist, - __m128i *u_first, __m128i *u_second, - __m128i *v_first, - __m128i *v_second) { - if (!ss_x) { - // If there is no chroma subsampling in the horizontal direction, then we - // need to load 16 entries from chroma. - read_dist_16(u_dist, u_first, u_second); - read_dist_16(v_dist, v_first, v_second); - } else { // ss_x == 1 - // Otherwise, we only need to load 8 entries - __m128i u_reg, v_reg; - - read_dist_8(u_dist, &u_reg); - - *u_first = _mm_unpacklo_epi16(u_reg, u_reg); - *u_second = _mm_unpackhi_epi16(u_reg, u_reg); - - read_dist_8(v_dist, &v_reg); - - *v_first = _mm_unpacklo_epi16(v_reg, v_reg); - *v_second = _mm_unpackhi_epi16(v_reg, v_reg); - } -} - -// Horizontal add unsigned 16-bit ints in src and store them as signed 32-bit -// int in dst. -static INLINE void hadd_epu16(__m128i *src, __m128i *dst) { - const __m128i zero = _mm_setzero_si128(); - const __m128i shift_right = _mm_srli_si128(*src, 2); - - const __m128i odd = _mm_blend_epi16(shift_right, zero, 170); - const __m128i even = _mm_blend_epi16(*src, zero, 170); - - *dst = _mm_add_epi32(even, odd); -} - -// Add a row of luma distortion to 8 corresponding chroma mods. -static INLINE void add_luma_dist_to_8_chroma_mod(const uint16_t *y_dist, - int ss_x, int ss_y, - __m128i *u_mod, - __m128i *v_mod) { - __m128i y_reg; - if (!ss_x) { - read_dist_8(y_dist, &y_reg); - if (ss_y == 1) { - __m128i y_tmp; - read_dist_8(y_dist + DIST_STRIDE, &y_tmp); - - y_reg = _mm_adds_epu16(y_reg, y_tmp); - } - } else { - __m128i y_first, y_second; - read_dist_16(y_dist, &y_first, &y_second); - if (ss_y == 1) { - __m128i y_tmp_0, y_tmp_1; - read_dist_16(y_dist + DIST_STRIDE, &y_tmp_0, &y_tmp_1); - - y_first = _mm_adds_epu16(y_first, y_tmp_0); - y_second = _mm_adds_epu16(y_second, y_tmp_1); - } - - hadd_epu16(&y_first, &y_first); - hadd_epu16(&y_second, &y_second); - - y_reg = _mm_packus_epi32(y_first, y_second); - } - - *u_mod = _mm_adds_epu16(*u_mod, y_reg); - *v_mod = _mm_adds_epu16(*v_mod, y_reg); -} - -// Apply temporal filter to the luma components. This performs temporal -// filtering on a luma block of 16 X block_height. Use blk_fw as an array of -// size 4 for the weights for each of the 4 subblocks if blk_fw is not NULL, -// else use top_weight for top half, and bottom weight for bottom half. -static void vp9_apply_temporal_filter_luma_16( - const uint8_t *y_pre, int y_pre_stride, unsigned int block_width, - unsigned int block_height, int ss_x, int ss_y, int strength, - int use_whole_blk, uint32_t *y_accum, uint16_t *y_count, - const uint16_t *y_dist, const uint16_t *u_dist, const uint16_t *v_dist, - const int16_t *const *neighbors_first, - const int16_t *const *neighbors_second, int top_weight, int bottom_weight, - const int *blk_fw) { - const int rounding = (1 << strength) >> 1; - __m128i weight_first, weight_second; - - __m128i mul_first, mul_second; - - __m128i sum_row_1_first, sum_row_1_second; - __m128i sum_row_2_first, sum_row_2_second; - __m128i sum_row_3_first, sum_row_3_second; - - __m128i u_first, u_second; - __m128i v_first, v_second; - - __m128i sum_row_first; - __m128i sum_row_second; - - // Loop variables - unsigned int h; - - assert(strength >= 0); - assert(strength <= 6); - - assert(block_width == 16); - (void)block_width; - - // Initialize the weights - if (blk_fw) { - weight_first = _mm_set1_epi16(blk_fw[0]); - weight_second = _mm_set1_epi16(blk_fw[1]); - } else { - weight_first = _mm_set1_epi16(top_weight); - weight_second = weight_first; - } - - // First row - mul_first = _mm_load_si128((const __m128i *)neighbors_first[0]); - mul_second = _mm_load_si128((const __m128i *)neighbors_second[0]); - - // Add luma values - get_sum_16(y_dist, &sum_row_2_first, &sum_row_2_second); - get_sum_16(y_dist + DIST_STRIDE, &sum_row_3_first, &sum_row_3_second); - - sum_row_first = _mm_adds_epu16(sum_row_2_first, sum_row_3_first); - sum_row_second = _mm_adds_epu16(sum_row_2_second, sum_row_3_second); - - // Add chroma values - read_chroma_dist_row_16(ss_x, u_dist, v_dist, &u_first, &u_second, &v_first, - &v_second); - - sum_row_first = _mm_adds_epu16(sum_row_first, u_first); - sum_row_second = _mm_adds_epu16(sum_row_second, u_second); - - sum_row_first = _mm_adds_epu16(sum_row_first, v_first); - sum_row_second = _mm_adds_epu16(sum_row_second, v_second); - - // Get modifier and store result - sum_row_first = - average_8(sum_row_first, &mul_first, strength, rounding, &weight_first); - sum_row_second = average_8(sum_row_second, &mul_second, strength, rounding, - &weight_second); - accumulate_and_store_16(sum_row_first, sum_row_second, y_pre, y_count, - y_accum); - - y_pre += y_pre_stride; - y_count += y_pre_stride; - y_accum += y_pre_stride; - y_dist += DIST_STRIDE; - - u_dist += DIST_STRIDE; - v_dist += DIST_STRIDE; - - // Then all the rows except the last one - mul_first = _mm_load_si128((const __m128i *)neighbors_first[1]); - mul_second = _mm_load_si128((const __m128i *)neighbors_second[1]); - - for (h = 1; h < block_height - 1; ++h) { - // Move the weight to bottom half - if (!use_whole_blk && h == block_height / 2) { - if (blk_fw) { - weight_first = _mm_set1_epi16(blk_fw[2]); - weight_second = _mm_set1_epi16(blk_fw[3]); - } else { - weight_first = _mm_set1_epi16(bottom_weight); - weight_second = weight_first; - } - } - // Shift the rows up - sum_row_1_first = sum_row_2_first; - sum_row_1_second = sum_row_2_second; - sum_row_2_first = sum_row_3_first; - sum_row_2_second = sum_row_3_second; - - // Add luma values to the modifier - sum_row_first = _mm_adds_epu16(sum_row_1_first, sum_row_2_first); - sum_row_second = _mm_adds_epu16(sum_row_1_second, sum_row_2_second); - - get_sum_16(y_dist + DIST_STRIDE, &sum_row_3_first, &sum_row_3_second); - - sum_row_first = _mm_adds_epu16(sum_row_first, sum_row_3_first); - sum_row_second = _mm_adds_epu16(sum_row_second, sum_row_3_second); - - // Add chroma values to the modifier - if (ss_y == 0 || h % 2 == 0) { - // Only calculate the new chroma distortion if we are at a pixel that - // corresponds to a new chroma row - read_chroma_dist_row_16(ss_x, u_dist, v_dist, &u_first, &u_second, - &v_first, &v_second); - - u_dist += DIST_STRIDE; - v_dist += DIST_STRIDE; - } - - sum_row_first = _mm_adds_epu16(sum_row_first, u_first); - sum_row_second = _mm_adds_epu16(sum_row_second, u_second); - sum_row_first = _mm_adds_epu16(sum_row_first, v_first); - sum_row_second = _mm_adds_epu16(sum_row_second, v_second); - - // Get modifier and store result - sum_row_first = - average_8(sum_row_first, &mul_first, strength, rounding, &weight_first); - sum_row_second = average_8(sum_row_second, &mul_second, strength, rounding, - &weight_second); - accumulate_and_store_16(sum_row_first, sum_row_second, y_pre, y_count, - y_accum); - - y_pre += y_pre_stride; - y_count += y_pre_stride; - y_accum += y_pre_stride; - y_dist += DIST_STRIDE; - } - - // The last row - mul_first = _mm_load_si128((const __m128i *)neighbors_first[0]); - mul_second = _mm_load_si128((const __m128i *)neighbors_second[0]); - - // Shift the rows up - sum_row_1_first = sum_row_2_first; - sum_row_1_second = sum_row_2_second; - sum_row_2_first = sum_row_3_first; - sum_row_2_second = sum_row_3_second; - - // Add luma values to the modifier - sum_row_first = _mm_adds_epu16(sum_row_1_first, sum_row_2_first); - sum_row_second = _mm_adds_epu16(sum_row_1_second, sum_row_2_second); - - // Add chroma values to the modifier - if (ss_y == 0) { - // Only calculate the new chroma distortion if we are at a pixel that - // corresponds to a new chroma row - read_chroma_dist_row_16(ss_x, u_dist, v_dist, &u_first, &u_second, &v_first, - &v_second); - } - - sum_row_first = _mm_adds_epu16(sum_row_first, u_first); - sum_row_second = _mm_adds_epu16(sum_row_second, u_second); - sum_row_first = _mm_adds_epu16(sum_row_first, v_first); - sum_row_second = _mm_adds_epu16(sum_row_second, v_second); - - // Get modifier and store result - sum_row_first = - average_8(sum_row_first, &mul_first, strength, rounding, &weight_first); - sum_row_second = average_8(sum_row_second, &mul_second, strength, rounding, - &weight_second); - accumulate_and_store_16(sum_row_first, sum_row_second, y_pre, y_count, - y_accum); -} - -// Perform temporal filter for the luma component. -static void vp9_apply_temporal_filter_luma( - const uint8_t *y_pre, int y_pre_stride, unsigned int block_width, - unsigned int block_height, int ss_x, int ss_y, int strength, - const int *blk_fw, int use_whole_blk, uint32_t *y_accum, uint16_t *y_count, - const uint16_t *y_dist, const uint16_t *u_dist, const uint16_t *v_dist) { - unsigned int blk_col = 0, uv_blk_col = 0; - const unsigned int blk_col_step = 16, uv_blk_col_step = 16 >> ss_x; - const unsigned int mid_width = block_width >> 1, - last_width = block_width - blk_col_step; - int top_weight = blk_fw[0], - bottom_weight = use_whole_blk ? blk_fw[0] : blk_fw[2]; - const int16_t *const *neighbors_first; - const int16_t *const *neighbors_second; - - if (block_width == 16) { - // Special Case: The blockwidth is 16 and we are operating on a row of 16 - // chroma pixels. In this case, we can't use the usual left-middle-right - // pattern. We also don't support splitting now. - neighbors_first = LUMA_LEFT_COLUMN_NEIGHBORS; - neighbors_second = LUMA_RIGHT_COLUMN_NEIGHBORS; - if (use_whole_blk) { - vp9_apply_temporal_filter_luma_16( - y_pre + blk_col, y_pre_stride, 16, block_height, ss_x, ss_y, strength, - use_whole_blk, y_accum + blk_col, y_count + blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors_first, - neighbors_second, top_weight, bottom_weight, NULL); - } else { - vp9_apply_temporal_filter_luma_16( - y_pre + blk_col, y_pre_stride, 16, block_height, ss_x, ss_y, strength, - use_whole_blk, y_accum + blk_col, y_count + blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors_first, - neighbors_second, 0, 0, blk_fw); - } - - return; - } - - // Left - neighbors_first = LUMA_LEFT_COLUMN_NEIGHBORS; - neighbors_second = LUMA_MIDDLE_COLUMN_NEIGHBORS; - vp9_apply_temporal_filter_luma_16( - y_pre + blk_col, y_pre_stride, 16, block_height, ss_x, ss_y, strength, - use_whole_blk, y_accum + blk_col, y_count + blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors_first, - neighbors_second, top_weight, bottom_weight, NULL); - - blk_col += blk_col_step; - uv_blk_col += uv_blk_col_step; - - // Middle First - neighbors_first = LUMA_MIDDLE_COLUMN_NEIGHBORS; - for (; blk_col < mid_width; - blk_col += blk_col_step, uv_blk_col += uv_blk_col_step) { - vp9_apply_temporal_filter_luma_16( - y_pre + blk_col, y_pre_stride, 16, block_height, ss_x, ss_y, strength, - use_whole_blk, y_accum + blk_col, y_count + blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors_first, - neighbors_second, top_weight, bottom_weight, NULL); - } - - if (!use_whole_blk) { - top_weight = blk_fw[1]; - bottom_weight = blk_fw[3]; - } - - // Middle Second - for (; blk_col < last_width; - blk_col += blk_col_step, uv_blk_col += uv_blk_col_step) { - vp9_apply_temporal_filter_luma_16( - y_pre + blk_col, y_pre_stride, 16, block_height, ss_x, ss_y, strength, - use_whole_blk, y_accum + blk_col, y_count + blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors_first, - neighbors_second, top_weight, bottom_weight, NULL); - } - - // Right - neighbors_second = LUMA_RIGHT_COLUMN_NEIGHBORS; - vp9_apply_temporal_filter_luma_16( - y_pre + blk_col, y_pre_stride, 16, block_height, ss_x, ss_y, strength, - use_whole_blk, y_accum + blk_col, y_count + blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors_first, - neighbors_second, top_weight, bottom_weight, NULL); -} - -// Apply temporal filter to the chroma components. This performs temporal -// filtering on a chroma block of 8 X uv_height. If blk_fw is not NULL, use -// blk_fw as an array of size 4 for the weights for each of the 4 subblocks, -// else use top_weight for top half, and bottom weight for bottom half. -static void vp9_apply_temporal_filter_chroma_8( - const uint8_t *u_pre, const uint8_t *v_pre, int uv_pre_stride, - unsigned int uv_block_height, int ss_x, int ss_y, int strength, - uint32_t *u_accum, uint16_t *u_count, uint32_t *v_accum, uint16_t *v_count, - const uint16_t *y_dist, const uint16_t *u_dist, const uint16_t *v_dist, - const int16_t *const *neighbors, int top_weight, int bottom_weight, - const int *blk_fw) { - const int rounding = (1 << strength) >> 1; - - __m128i weight; - - __m128i mul; - - __m128i u_sum_row_1, u_sum_row_2, u_sum_row_3; - __m128i v_sum_row_1, v_sum_row_2, v_sum_row_3; - - __m128i u_sum_row, v_sum_row; - - // Loop variable - unsigned int h; - - // Initialize weight - if (blk_fw) { - weight = _mm_setr_epi16(blk_fw[0], blk_fw[0], blk_fw[0], blk_fw[0], - blk_fw[1], blk_fw[1], blk_fw[1], blk_fw[1]); - } else { - weight = _mm_set1_epi16(top_weight); - } - - // First row - mul = _mm_load_si128((const __m128i *)neighbors[0]); - - // Add chroma values - get_sum_8(u_dist, &u_sum_row_2); - get_sum_8(u_dist + DIST_STRIDE, &u_sum_row_3); - - u_sum_row = _mm_adds_epu16(u_sum_row_2, u_sum_row_3); - - get_sum_8(v_dist, &v_sum_row_2); - get_sum_8(v_dist + DIST_STRIDE, &v_sum_row_3); - - v_sum_row = _mm_adds_epu16(v_sum_row_2, v_sum_row_3); - - // Add luma values - add_luma_dist_to_8_chroma_mod(y_dist, ss_x, ss_y, &u_sum_row, &v_sum_row); - - // Get modifier and store result - u_sum_row = average_8(u_sum_row, &mul, strength, rounding, &weight); - v_sum_row = average_8(v_sum_row, &mul, strength, rounding, &weight); - - accumulate_and_store_8(u_sum_row, u_pre, u_count, u_accum); - accumulate_and_store_8(v_sum_row, v_pre, v_count, v_accum); - - u_pre += uv_pre_stride; - u_dist += DIST_STRIDE; - v_pre += uv_pre_stride; - v_dist += DIST_STRIDE; - u_count += uv_pre_stride; - u_accum += uv_pre_stride; - v_count += uv_pre_stride; - v_accum += uv_pre_stride; - - y_dist += DIST_STRIDE * (1 + ss_y); - - // Then all the rows except the last one - mul = _mm_load_si128((const __m128i *)neighbors[1]); - - for (h = 1; h < uv_block_height - 1; ++h) { - // Move the weight pointer to the bottom half of the blocks - if (h == uv_block_height / 2) { - if (blk_fw) { - weight = _mm_setr_epi16(blk_fw[2], blk_fw[2], blk_fw[2], blk_fw[2], - blk_fw[3], blk_fw[3], blk_fw[3], blk_fw[3]); - } else { - weight = _mm_set1_epi16(bottom_weight); - } - } - - // Shift the rows up - u_sum_row_1 = u_sum_row_2; - u_sum_row_2 = u_sum_row_3; - - v_sum_row_1 = v_sum_row_2; - v_sum_row_2 = v_sum_row_3; - - // Add chroma values - u_sum_row = _mm_adds_epu16(u_sum_row_1, u_sum_row_2); - get_sum_8(u_dist + DIST_STRIDE, &u_sum_row_3); - u_sum_row = _mm_adds_epu16(u_sum_row, u_sum_row_3); - - v_sum_row = _mm_adds_epu16(v_sum_row_1, v_sum_row_2); - get_sum_8(v_dist + DIST_STRIDE, &v_sum_row_3); - v_sum_row = _mm_adds_epu16(v_sum_row, v_sum_row_3); - - // Add luma values - add_luma_dist_to_8_chroma_mod(y_dist, ss_x, ss_y, &u_sum_row, &v_sum_row); - - // Get modifier and store result - u_sum_row = average_8(u_sum_row, &mul, strength, rounding, &weight); - v_sum_row = average_8(v_sum_row, &mul, strength, rounding, &weight); - - accumulate_and_store_8(u_sum_row, u_pre, u_count, u_accum); - accumulate_and_store_8(v_sum_row, v_pre, v_count, v_accum); - - u_pre += uv_pre_stride; - u_dist += DIST_STRIDE; - v_pre += uv_pre_stride; - v_dist += DIST_STRIDE; - u_count += uv_pre_stride; - u_accum += uv_pre_stride; - v_count += uv_pre_stride; - v_accum += uv_pre_stride; - - y_dist += DIST_STRIDE * (1 + ss_y); - } - - // The last row - mul = _mm_load_si128((const __m128i *)neighbors[0]); - - // Shift the rows up - u_sum_row_1 = u_sum_row_2; - u_sum_row_2 = u_sum_row_3; - - v_sum_row_1 = v_sum_row_2; - v_sum_row_2 = v_sum_row_3; - - // Add chroma values - u_sum_row = _mm_adds_epu16(u_sum_row_1, u_sum_row_2); - v_sum_row = _mm_adds_epu16(v_sum_row_1, v_sum_row_2); - - // Add luma values - add_luma_dist_to_8_chroma_mod(y_dist, ss_x, ss_y, &u_sum_row, &v_sum_row); - - // Get modifier and store result - u_sum_row = average_8(u_sum_row, &mul, strength, rounding, &weight); - v_sum_row = average_8(v_sum_row, &mul, strength, rounding, &weight); - - accumulate_and_store_8(u_sum_row, u_pre, u_count, u_accum); - accumulate_and_store_8(v_sum_row, v_pre, v_count, v_accum); -} - -// Perform temporal filter for the chroma components. -static void vp9_apply_temporal_filter_chroma( - const uint8_t *u_pre, const uint8_t *v_pre, int uv_pre_stride, - unsigned int block_width, unsigned int block_height, int ss_x, int ss_y, - int strength, const int *blk_fw, int use_whole_blk, uint32_t *u_accum, - uint16_t *u_count, uint32_t *v_accum, uint16_t *v_count, - const uint16_t *y_dist, const uint16_t *u_dist, const uint16_t *v_dist) { - const unsigned int uv_width = block_width >> ss_x, - uv_height = block_height >> ss_y; - - unsigned int blk_col = 0, uv_blk_col = 0; - const unsigned int uv_blk_col_step = 8, blk_col_step = 8 << ss_x; - const unsigned int uv_mid_width = uv_width >> 1, - uv_last_width = uv_width - uv_blk_col_step; - int top_weight = blk_fw[0], - bottom_weight = use_whole_blk ? blk_fw[0] : blk_fw[2]; - const int16_t *const *neighbors; - - if (uv_width == 8) { - // Special Case: We are subsampling in x direction on a 16x16 block. Since - // we are operating on a row of 8 chroma pixels, we can't use the usual - // left-middle-right pattern. - assert(ss_x); - - if (ss_y) { - neighbors = CHROMA_DOUBLE_SS_SINGLE_COLUMN_NEIGHBORS; - } else { - neighbors = CHROMA_SINGLE_SS_SINGLE_COLUMN_NEIGHBORS; - } - - if (use_whole_blk) { - vp9_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_height, - ss_x, ss_y, strength, u_accum + uv_blk_col, u_count + uv_blk_col, - v_accum + uv_blk_col, v_count + uv_blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors, top_weight, - bottom_weight, NULL); - } else { - vp9_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_height, - ss_x, ss_y, strength, u_accum + uv_blk_col, u_count + uv_blk_col, - v_accum + uv_blk_col, v_count + uv_blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors, 0, 0, blk_fw); - } - - return; - } - - // Left - if (ss_x && ss_y) { - neighbors = CHROMA_DOUBLE_SS_LEFT_COLUMN_NEIGHBORS; - } else if (ss_x || ss_y) { - neighbors = CHROMA_SINGLE_SS_LEFT_COLUMN_NEIGHBORS; - } else { - neighbors = CHROMA_NO_SS_LEFT_COLUMN_NEIGHBORS; - } - - vp9_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_height, ss_x, - ss_y, strength, u_accum + uv_blk_col, u_count + uv_blk_col, - v_accum + uv_blk_col, v_count + uv_blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors, top_weight, - bottom_weight, NULL); - - blk_col += blk_col_step; - uv_blk_col += uv_blk_col_step; - - // Middle First - if (ss_x && ss_y) { - neighbors = CHROMA_DOUBLE_SS_MIDDLE_COLUMN_NEIGHBORS; - } else if (ss_x || ss_y) { - neighbors = CHROMA_SINGLE_SS_MIDDLE_COLUMN_NEIGHBORS; - } else { - neighbors = CHROMA_NO_SS_MIDDLE_COLUMN_NEIGHBORS; - } - - for (; uv_blk_col < uv_mid_width; - blk_col += blk_col_step, uv_blk_col += uv_blk_col_step) { - vp9_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_height, ss_x, - ss_y, strength, u_accum + uv_blk_col, u_count + uv_blk_col, - v_accum + uv_blk_col, v_count + uv_blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors, top_weight, - bottom_weight, NULL); - } - - if (!use_whole_blk) { - top_weight = blk_fw[1]; - bottom_weight = blk_fw[3]; - } - - // Middle Second - for (; uv_blk_col < uv_last_width; - blk_col += blk_col_step, uv_blk_col += uv_blk_col_step) { - vp9_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_height, ss_x, - ss_y, strength, u_accum + uv_blk_col, u_count + uv_blk_col, - v_accum + uv_blk_col, v_count + uv_blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors, top_weight, - bottom_weight, NULL); - } - - // Right - if (ss_x && ss_y) { - neighbors = CHROMA_DOUBLE_SS_RIGHT_COLUMN_NEIGHBORS; - } else if (ss_x || ss_y) { - neighbors = CHROMA_SINGLE_SS_RIGHT_COLUMN_NEIGHBORS; - } else { - neighbors = CHROMA_NO_SS_RIGHT_COLUMN_NEIGHBORS; - } - - vp9_apply_temporal_filter_chroma_8( - u_pre + uv_blk_col, v_pre + uv_blk_col, uv_pre_stride, uv_height, ss_x, - ss_y, strength, u_accum + uv_blk_col, u_count + uv_blk_col, - v_accum + uv_blk_col, v_count + uv_blk_col, y_dist + blk_col, - u_dist + uv_blk_col, v_dist + uv_blk_col, neighbors, top_weight, - bottom_weight, NULL); -} - -void vp9_apply_temporal_filter_sse4_1( - const uint8_t *y_src, int y_src_stride, const uint8_t *y_pre, - int y_pre_stride, const uint8_t *u_src, const uint8_t *v_src, - int uv_src_stride, const uint8_t *u_pre, const uint8_t *v_pre, - int uv_pre_stride, unsigned int block_width, unsigned int block_height, - int ss_x, int ss_y, int strength, const int *const blk_fw, - int use_whole_blk, uint32_t *y_accum, uint16_t *y_count, uint32_t *u_accum, - uint16_t *u_count, uint32_t *v_accum, uint16_t *v_count) { - const unsigned int chroma_height = block_height >> ss_y, - chroma_width = block_width >> ss_x; - - DECLARE_ALIGNED(16, uint16_t, y_dist[BH * DIST_STRIDE]) = { 0 }; - DECLARE_ALIGNED(16, uint16_t, u_dist[BH * DIST_STRIDE]) = { 0 }; - DECLARE_ALIGNED(16, uint16_t, v_dist[BH * DIST_STRIDE]) = { 0 }; - const int *blk_fw_ptr = blk_fw; - - uint16_t *y_dist_ptr = y_dist + 1, *u_dist_ptr = u_dist + 1, - *v_dist_ptr = v_dist + 1; - const uint8_t *y_src_ptr = y_src, *u_src_ptr = u_src, *v_src_ptr = v_src; - const uint8_t *y_pre_ptr = y_pre, *u_pre_ptr = u_pre, *v_pre_ptr = v_pre; - - // Loop variables - unsigned int row, blk_col; - - assert(block_width <= BW && "block width too large"); - assert(block_height <= BH && "block height too large"); - assert(block_width % 16 == 0 && "block width must be multiple of 16"); - assert(block_height % 2 == 0 && "block height must be even"); - assert((ss_x == 0 || ss_x == 1) && (ss_y == 0 || ss_y == 1) && - "invalid chroma subsampling"); - assert(strength >= 0 && strength <= 6 && "invalid temporal filter strength"); - assert(blk_fw[0] >= 0 && "filter weight must be positive"); - assert( - (use_whole_blk || (blk_fw[1] >= 0 && blk_fw[2] >= 0 && blk_fw[3] >= 0)) && - "subblock filter weight must be positive"); - assert(blk_fw[0] <= 2 && "subblock filter weight must be less than 2"); - assert( - (use_whole_blk || (blk_fw[1] <= 2 && blk_fw[2] <= 2 && blk_fw[3] <= 2)) && - "subblock filter weight must be less than 2"); - - // Precompute the difference squared - for (row = 0; row < block_height; row++) { - for (blk_col = 0; blk_col < block_width; blk_col += 16) { - store_dist_16(y_src_ptr + blk_col, y_pre_ptr + blk_col, - y_dist_ptr + blk_col); - } - y_src_ptr += y_src_stride; - y_pre_ptr += y_pre_stride; - y_dist_ptr += DIST_STRIDE; - } - - for (row = 0; row < chroma_height; row++) { - for (blk_col = 0; blk_col < chroma_width; blk_col += 8) { - store_dist_8(u_src_ptr + blk_col, u_pre_ptr + blk_col, - u_dist_ptr + blk_col); - store_dist_8(v_src_ptr + blk_col, v_pre_ptr + blk_col, - v_dist_ptr + blk_col); - } - - u_src_ptr += uv_src_stride; - u_pre_ptr += uv_pre_stride; - u_dist_ptr += DIST_STRIDE; - v_src_ptr += uv_src_stride; - v_pre_ptr += uv_pre_stride; - v_dist_ptr += DIST_STRIDE; - } - - y_dist_ptr = y_dist + 1; - u_dist_ptr = u_dist + 1; - v_dist_ptr = v_dist + 1; - - vp9_apply_temporal_filter_luma(y_pre, y_pre_stride, block_width, block_height, - ss_x, ss_y, strength, blk_fw_ptr, - use_whole_blk, y_accum, y_count, y_dist_ptr, - u_dist_ptr, v_dist_ptr); - - vp9_apply_temporal_filter_chroma( - u_pre, v_pre, uv_pre_stride, block_width, block_height, ss_x, ss_y, - strength, blk_fw_ptr, use_whole_blk, u_accum, u_count, v_accum, v_count, - y_dist_ptr, u_dist_ptr, v_dist_ptr); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_dct_intrin_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_dct_intrin_sse2.c deleted file mode 100644 index e9943447..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_dct_intrin_sse2.c +++ /dev/null @@ -1,1537 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include // SSE2 - -#include "./vp9_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/txfm_common.h" -#include "vpx_dsp/x86/bitdepth_conversion_sse2.h" -#include "vpx_dsp/x86/fwd_txfm_sse2.h" -#include "vpx_dsp/x86/transpose_sse2.h" -#include "vpx_dsp/x86/txfm_common_sse2.h" -#include "vpx_ports/mem.h" - -static INLINE void load_buffer_4x4(const int16_t *input, __m128i *in, - int stride) { - const __m128i k__nonzero_bias_a = _mm_setr_epi16(0, 1, 1, 1, 1, 1, 1, 1); - const __m128i k__nonzero_bias_b = _mm_setr_epi16(1, 0, 0, 0, 0, 0, 0, 0); - __m128i mask; - - in[0] = _mm_loadl_epi64((const __m128i *)(input + 0 * stride)); - in[1] = _mm_loadl_epi64((const __m128i *)(input + 1 * stride)); - in[2] = _mm_loadl_epi64((const __m128i *)(input + 2 * stride)); - in[3] = _mm_loadl_epi64((const __m128i *)(input + 3 * stride)); - - in[0] = _mm_slli_epi16(in[0], 4); - in[1] = _mm_slli_epi16(in[1], 4); - in[2] = _mm_slli_epi16(in[2], 4); - in[3] = _mm_slli_epi16(in[3], 4); - - mask = _mm_cmpeq_epi16(in[0], k__nonzero_bias_a); - in[0] = _mm_add_epi16(in[0], mask); - in[0] = _mm_add_epi16(in[0], k__nonzero_bias_b); -} - -static INLINE void write_buffer_4x4(tran_low_t *output, __m128i *res) { - const __m128i kOne = _mm_set1_epi16(1); - __m128i in01 = _mm_unpacklo_epi64(res[0], res[1]); - __m128i in23 = _mm_unpacklo_epi64(res[2], res[3]); - __m128i out01 = _mm_add_epi16(in01, kOne); - __m128i out23 = _mm_add_epi16(in23, kOne); - out01 = _mm_srai_epi16(out01, 2); - out23 = _mm_srai_epi16(out23, 2); - store_output(&out01, (output + 0 * 8)); - store_output(&out23, (output + 1 * 8)); -} - -static INLINE void transpose_4x4(__m128i *res) { - // Combine and transpose - // 00 01 02 03 20 21 22 23 - // 10 11 12 13 30 31 32 33 - const __m128i tr0_0 = _mm_unpacklo_epi16(res[0], res[1]); - const __m128i tr0_1 = _mm_unpackhi_epi16(res[0], res[1]); - - // 00 10 01 11 02 12 03 13 - // 20 30 21 31 22 32 23 33 - res[0] = _mm_unpacklo_epi32(tr0_0, tr0_1); - res[2] = _mm_unpackhi_epi32(tr0_0, tr0_1); - - // 00 10 20 30 01 11 21 31 - // 02 12 22 32 03 13 23 33 - // only use the first 4 16-bit integers - res[1] = _mm_unpackhi_epi64(res[0], res[0]); - res[3] = _mm_unpackhi_epi64(res[2], res[2]); -} - -static void fdct4_sse2(__m128i *in) { - const __m128i k__cospi_p16_p16 = _mm_set1_epi16(cospi_16_64); - const __m128i k__cospi_p16_m16 = pair_set_epi16(cospi_16_64, -cospi_16_64); - const __m128i k__cospi_p08_p24 = pair_set_epi16(cospi_8_64, cospi_24_64); - const __m128i k__cospi_p24_m08 = pair_set_epi16(cospi_24_64, -cospi_8_64); - const __m128i k__DCT_CONST_ROUNDING = _mm_set1_epi32(DCT_CONST_ROUNDING); - - __m128i u[4], v[4]; - u[0] = _mm_unpacklo_epi16(in[0], in[1]); - u[1] = _mm_unpacklo_epi16(in[3], in[2]); - - v[0] = _mm_add_epi16(u[0], u[1]); - v[1] = _mm_sub_epi16(u[0], u[1]); - - u[0] = _mm_madd_epi16(v[0], k__cospi_p16_p16); // 0 - u[1] = _mm_madd_epi16(v[0], k__cospi_p16_m16); // 2 - u[2] = _mm_madd_epi16(v[1], k__cospi_p08_p24); // 1 - u[3] = _mm_madd_epi16(v[1], k__cospi_p24_m08); // 3 - - v[0] = _mm_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm_add_epi32(u[3], k__DCT_CONST_ROUNDING); - u[0] = _mm_srai_epi32(v[0], DCT_CONST_BITS); - u[1] = _mm_srai_epi32(v[1], DCT_CONST_BITS); - u[2] = _mm_srai_epi32(v[2], DCT_CONST_BITS); - u[3] = _mm_srai_epi32(v[3], DCT_CONST_BITS); - - in[0] = _mm_packs_epi32(u[0], u[1]); - in[1] = _mm_packs_epi32(u[2], u[3]); - transpose_4x4(in); -} - -static void fadst4_sse2(__m128i *in) { - const __m128i k__sinpi_p01_p02 = pair_set_epi16(sinpi_1_9, sinpi_2_9); - const __m128i k__sinpi_p04_m01 = pair_set_epi16(sinpi_4_9, -sinpi_1_9); - const __m128i k__sinpi_p03_p04 = pair_set_epi16(sinpi_3_9, sinpi_4_9); - const __m128i k__sinpi_m03_p02 = pair_set_epi16(-sinpi_3_9, sinpi_2_9); - const __m128i k__sinpi_p03_p03 = _mm_set1_epi16((int16_t)sinpi_3_9); - const __m128i kZero = _mm_setzero_si128(); - const __m128i k__DCT_CONST_ROUNDING = _mm_set1_epi32(DCT_CONST_ROUNDING); - __m128i u[8], v[8]; - __m128i in7 = _mm_add_epi16(in[0], in[1]); - - u[0] = _mm_unpacklo_epi16(in[0], in[1]); - u[1] = _mm_unpacklo_epi16(in[2], in[3]); - u[2] = _mm_unpacklo_epi16(in7, kZero); - u[3] = _mm_unpacklo_epi16(in[2], kZero); - u[4] = _mm_unpacklo_epi16(in[3], kZero); - - v[0] = _mm_madd_epi16(u[0], k__sinpi_p01_p02); // s0 + s2 - v[1] = _mm_madd_epi16(u[1], k__sinpi_p03_p04); // s4 + s5 - v[2] = _mm_madd_epi16(u[2], k__sinpi_p03_p03); // x1 - v[3] = _mm_madd_epi16(u[0], k__sinpi_p04_m01); // s1 - s3 - v[4] = _mm_madd_epi16(u[1], k__sinpi_m03_p02); // -s4 + s6 - v[5] = _mm_madd_epi16(u[3], k__sinpi_p03_p03); // s4 - v[6] = _mm_madd_epi16(u[4], k__sinpi_p03_p03); - - u[0] = _mm_add_epi32(v[0], v[1]); - u[1] = _mm_sub_epi32(v[2], v[6]); - u[2] = _mm_add_epi32(v[3], v[4]); - u[3] = _mm_sub_epi32(u[2], u[0]); - u[4] = _mm_slli_epi32(v[5], 2); - u[5] = _mm_sub_epi32(u[4], v[5]); - u[6] = _mm_add_epi32(u[3], u[5]); - - v[0] = _mm_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm_add_epi32(u[6], k__DCT_CONST_ROUNDING); - - u[0] = _mm_srai_epi32(v[0], DCT_CONST_BITS); - u[1] = _mm_srai_epi32(v[1], DCT_CONST_BITS); - u[2] = _mm_srai_epi32(v[2], DCT_CONST_BITS); - u[3] = _mm_srai_epi32(v[3], DCT_CONST_BITS); - - in[0] = _mm_packs_epi32(u[0], u[2]); - in[1] = _mm_packs_epi32(u[1], u[3]); - transpose_4x4(in); -} - -void vp9_fht4x4_sse2(const int16_t *input, tran_low_t *output, int stride, - int tx_type) { - __m128i in[4]; - - switch (tx_type) { - case DCT_DCT: vpx_fdct4x4_sse2(input, output, stride); break; - case ADST_DCT: - load_buffer_4x4(input, in, stride); - fadst4_sse2(in); - fdct4_sse2(in); - write_buffer_4x4(output, in); - break; - case DCT_ADST: - load_buffer_4x4(input, in, stride); - fdct4_sse2(in); - fadst4_sse2(in); - write_buffer_4x4(output, in); - break; - default: - assert(tx_type == ADST_ADST); - load_buffer_4x4(input, in, stride); - fadst4_sse2(in); - fadst4_sse2(in); - write_buffer_4x4(output, in); - break; - } -} - -// load 8x8 array -static INLINE void load_buffer_8x8(const int16_t *input, __m128i *in, - int stride) { - in[0] = _mm_load_si128((const __m128i *)(input + 0 * stride)); - in[1] = _mm_load_si128((const __m128i *)(input + 1 * stride)); - in[2] = _mm_load_si128((const __m128i *)(input + 2 * stride)); - in[3] = _mm_load_si128((const __m128i *)(input + 3 * stride)); - in[4] = _mm_load_si128((const __m128i *)(input + 4 * stride)); - in[5] = _mm_load_si128((const __m128i *)(input + 5 * stride)); - in[6] = _mm_load_si128((const __m128i *)(input + 6 * stride)); - in[7] = _mm_load_si128((const __m128i *)(input + 7 * stride)); - - in[0] = _mm_slli_epi16(in[0], 2); - in[1] = _mm_slli_epi16(in[1], 2); - in[2] = _mm_slli_epi16(in[2], 2); - in[3] = _mm_slli_epi16(in[3], 2); - in[4] = _mm_slli_epi16(in[4], 2); - in[5] = _mm_slli_epi16(in[5], 2); - in[6] = _mm_slli_epi16(in[6], 2); - in[7] = _mm_slli_epi16(in[7], 2); -} - -// right shift and rounding -static INLINE void right_shift_8x8(__m128i *res, const int bit) { - __m128i sign0 = _mm_srai_epi16(res[0], 15); - __m128i sign1 = _mm_srai_epi16(res[1], 15); - __m128i sign2 = _mm_srai_epi16(res[2], 15); - __m128i sign3 = _mm_srai_epi16(res[3], 15); - __m128i sign4 = _mm_srai_epi16(res[4], 15); - __m128i sign5 = _mm_srai_epi16(res[5], 15); - __m128i sign6 = _mm_srai_epi16(res[6], 15); - __m128i sign7 = _mm_srai_epi16(res[7], 15); - - if (bit == 2) { - const __m128i const_rounding = _mm_set1_epi16(1); - res[0] = _mm_add_epi16(res[0], const_rounding); - res[1] = _mm_add_epi16(res[1], const_rounding); - res[2] = _mm_add_epi16(res[2], const_rounding); - res[3] = _mm_add_epi16(res[3], const_rounding); - res[4] = _mm_add_epi16(res[4], const_rounding); - res[5] = _mm_add_epi16(res[5], const_rounding); - res[6] = _mm_add_epi16(res[6], const_rounding); - res[7] = _mm_add_epi16(res[7], const_rounding); - } - - res[0] = _mm_sub_epi16(res[0], sign0); - res[1] = _mm_sub_epi16(res[1], sign1); - res[2] = _mm_sub_epi16(res[2], sign2); - res[3] = _mm_sub_epi16(res[3], sign3); - res[4] = _mm_sub_epi16(res[4], sign4); - res[5] = _mm_sub_epi16(res[5], sign5); - res[6] = _mm_sub_epi16(res[6], sign6); - res[7] = _mm_sub_epi16(res[7], sign7); - - if (bit == 1) { - res[0] = _mm_srai_epi16(res[0], 1); - res[1] = _mm_srai_epi16(res[1], 1); - res[2] = _mm_srai_epi16(res[2], 1); - res[3] = _mm_srai_epi16(res[3], 1); - res[4] = _mm_srai_epi16(res[4], 1); - res[5] = _mm_srai_epi16(res[5], 1); - res[6] = _mm_srai_epi16(res[6], 1); - res[7] = _mm_srai_epi16(res[7], 1); - } else { - res[0] = _mm_srai_epi16(res[0], 2); - res[1] = _mm_srai_epi16(res[1], 2); - res[2] = _mm_srai_epi16(res[2], 2); - res[3] = _mm_srai_epi16(res[3], 2); - res[4] = _mm_srai_epi16(res[4], 2); - res[5] = _mm_srai_epi16(res[5], 2); - res[6] = _mm_srai_epi16(res[6], 2); - res[7] = _mm_srai_epi16(res[7], 2); - } -} - -// write 8x8 array -static INLINE void write_buffer_8x8(tran_low_t *output, __m128i *res, - int stride) { - store_output(&res[0], (output + 0 * stride)); - store_output(&res[1], (output + 1 * stride)); - store_output(&res[2], (output + 2 * stride)); - store_output(&res[3], (output + 3 * stride)); - store_output(&res[4], (output + 4 * stride)); - store_output(&res[5], (output + 5 * stride)); - store_output(&res[6], (output + 6 * stride)); - store_output(&res[7], (output + 7 * stride)); -} - -static void fdct8_sse2(__m128i *in) { - // constants - const __m128i k__cospi_p16_p16 = _mm_set1_epi16(cospi_16_64); - const __m128i k__cospi_p16_m16 = pair_set_epi16(cospi_16_64, -cospi_16_64); - const __m128i k__cospi_p24_p08 = pair_set_epi16(cospi_24_64, cospi_8_64); - const __m128i k__cospi_m08_p24 = pair_set_epi16(-cospi_8_64, cospi_24_64); - const __m128i k__cospi_p28_p04 = pair_set_epi16(cospi_28_64, cospi_4_64); - const __m128i k__cospi_m04_p28 = pair_set_epi16(-cospi_4_64, cospi_28_64); - const __m128i k__cospi_p12_p20 = pair_set_epi16(cospi_12_64, cospi_20_64); - const __m128i k__cospi_m20_p12 = pair_set_epi16(-cospi_20_64, cospi_12_64); - const __m128i k__DCT_CONST_ROUNDING = _mm_set1_epi32(DCT_CONST_ROUNDING); - __m128i u0, u1, u2, u3, u4, u5, u6, u7; - __m128i v0, v1, v2, v3, v4, v5, v6, v7; - __m128i s0, s1, s2, s3, s4, s5, s6, s7; - - // stage 1 - s0 = _mm_add_epi16(in[0], in[7]); - s1 = _mm_add_epi16(in[1], in[6]); - s2 = _mm_add_epi16(in[2], in[5]); - s3 = _mm_add_epi16(in[3], in[4]); - s4 = _mm_sub_epi16(in[3], in[4]); - s5 = _mm_sub_epi16(in[2], in[5]); - s6 = _mm_sub_epi16(in[1], in[6]); - s7 = _mm_sub_epi16(in[0], in[7]); - - u0 = _mm_add_epi16(s0, s3); - u1 = _mm_add_epi16(s1, s2); - u2 = _mm_sub_epi16(s1, s2); - u3 = _mm_sub_epi16(s0, s3); - // interleave and perform butterfly multiplication/addition - v0 = _mm_unpacklo_epi16(u0, u1); - v1 = _mm_unpackhi_epi16(u0, u1); - v2 = _mm_unpacklo_epi16(u2, u3); - v3 = _mm_unpackhi_epi16(u2, u3); - - u0 = _mm_madd_epi16(v0, k__cospi_p16_p16); - u1 = _mm_madd_epi16(v1, k__cospi_p16_p16); - u2 = _mm_madd_epi16(v0, k__cospi_p16_m16); - u3 = _mm_madd_epi16(v1, k__cospi_p16_m16); - u4 = _mm_madd_epi16(v2, k__cospi_p24_p08); - u5 = _mm_madd_epi16(v3, k__cospi_p24_p08); - u6 = _mm_madd_epi16(v2, k__cospi_m08_p24); - u7 = _mm_madd_epi16(v3, k__cospi_m08_p24); - - // shift and rounding - v0 = _mm_add_epi32(u0, k__DCT_CONST_ROUNDING); - v1 = _mm_add_epi32(u1, k__DCT_CONST_ROUNDING); - v2 = _mm_add_epi32(u2, k__DCT_CONST_ROUNDING); - v3 = _mm_add_epi32(u3, k__DCT_CONST_ROUNDING); - v4 = _mm_add_epi32(u4, k__DCT_CONST_ROUNDING); - v5 = _mm_add_epi32(u5, k__DCT_CONST_ROUNDING); - v6 = _mm_add_epi32(u6, k__DCT_CONST_ROUNDING); - v7 = _mm_add_epi32(u7, k__DCT_CONST_ROUNDING); - - u0 = _mm_srai_epi32(v0, DCT_CONST_BITS); - u1 = _mm_srai_epi32(v1, DCT_CONST_BITS); - u2 = _mm_srai_epi32(v2, DCT_CONST_BITS); - u3 = _mm_srai_epi32(v3, DCT_CONST_BITS); - u4 = _mm_srai_epi32(v4, DCT_CONST_BITS); - u5 = _mm_srai_epi32(v5, DCT_CONST_BITS); - u6 = _mm_srai_epi32(v6, DCT_CONST_BITS); - u7 = _mm_srai_epi32(v7, DCT_CONST_BITS); - - in[0] = _mm_packs_epi32(u0, u1); - in[2] = _mm_packs_epi32(u4, u5); - in[4] = _mm_packs_epi32(u2, u3); - in[6] = _mm_packs_epi32(u6, u7); - - // stage 2 - // interleave and perform butterfly multiplication/addition - u0 = _mm_unpacklo_epi16(s6, s5); - u1 = _mm_unpackhi_epi16(s6, s5); - v0 = _mm_madd_epi16(u0, k__cospi_p16_m16); - v1 = _mm_madd_epi16(u1, k__cospi_p16_m16); - v2 = _mm_madd_epi16(u0, k__cospi_p16_p16); - v3 = _mm_madd_epi16(u1, k__cospi_p16_p16); - - // shift and rounding - u0 = _mm_add_epi32(v0, k__DCT_CONST_ROUNDING); - u1 = _mm_add_epi32(v1, k__DCT_CONST_ROUNDING); - u2 = _mm_add_epi32(v2, k__DCT_CONST_ROUNDING); - u3 = _mm_add_epi32(v3, k__DCT_CONST_ROUNDING); - - v0 = _mm_srai_epi32(u0, DCT_CONST_BITS); - v1 = _mm_srai_epi32(u1, DCT_CONST_BITS); - v2 = _mm_srai_epi32(u2, DCT_CONST_BITS); - v3 = _mm_srai_epi32(u3, DCT_CONST_BITS); - - u0 = _mm_packs_epi32(v0, v1); - u1 = _mm_packs_epi32(v2, v3); - - // stage 3 - s0 = _mm_add_epi16(s4, u0); - s1 = _mm_sub_epi16(s4, u0); - s2 = _mm_sub_epi16(s7, u1); - s3 = _mm_add_epi16(s7, u1); - - // stage 4 - u0 = _mm_unpacklo_epi16(s0, s3); - u1 = _mm_unpackhi_epi16(s0, s3); - u2 = _mm_unpacklo_epi16(s1, s2); - u3 = _mm_unpackhi_epi16(s1, s2); - - v0 = _mm_madd_epi16(u0, k__cospi_p28_p04); - v1 = _mm_madd_epi16(u1, k__cospi_p28_p04); - v2 = _mm_madd_epi16(u2, k__cospi_p12_p20); - v3 = _mm_madd_epi16(u3, k__cospi_p12_p20); - v4 = _mm_madd_epi16(u2, k__cospi_m20_p12); - v5 = _mm_madd_epi16(u3, k__cospi_m20_p12); - v6 = _mm_madd_epi16(u0, k__cospi_m04_p28); - v7 = _mm_madd_epi16(u1, k__cospi_m04_p28); - - // shift and rounding - u0 = _mm_add_epi32(v0, k__DCT_CONST_ROUNDING); - u1 = _mm_add_epi32(v1, k__DCT_CONST_ROUNDING); - u2 = _mm_add_epi32(v2, k__DCT_CONST_ROUNDING); - u3 = _mm_add_epi32(v3, k__DCT_CONST_ROUNDING); - u4 = _mm_add_epi32(v4, k__DCT_CONST_ROUNDING); - u5 = _mm_add_epi32(v5, k__DCT_CONST_ROUNDING); - u6 = _mm_add_epi32(v6, k__DCT_CONST_ROUNDING); - u7 = _mm_add_epi32(v7, k__DCT_CONST_ROUNDING); - - v0 = _mm_srai_epi32(u0, DCT_CONST_BITS); - v1 = _mm_srai_epi32(u1, DCT_CONST_BITS); - v2 = _mm_srai_epi32(u2, DCT_CONST_BITS); - v3 = _mm_srai_epi32(u3, DCT_CONST_BITS); - v4 = _mm_srai_epi32(u4, DCT_CONST_BITS); - v5 = _mm_srai_epi32(u5, DCT_CONST_BITS); - v6 = _mm_srai_epi32(u6, DCT_CONST_BITS); - v7 = _mm_srai_epi32(u7, DCT_CONST_BITS); - - in[1] = _mm_packs_epi32(v0, v1); - in[3] = _mm_packs_epi32(v4, v5); - in[5] = _mm_packs_epi32(v2, v3); - in[7] = _mm_packs_epi32(v6, v7); - - // transpose - transpose_16bit_8x8(in, in); -} - -static void fadst8_sse2(__m128i *in) { - // Constants - const __m128i k__cospi_p02_p30 = pair_set_epi16(cospi_2_64, cospi_30_64); - const __m128i k__cospi_p30_m02 = pair_set_epi16(cospi_30_64, -cospi_2_64); - const __m128i k__cospi_p10_p22 = pair_set_epi16(cospi_10_64, cospi_22_64); - const __m128i k__cospi_p22_m10 = pair_set_epi16(cospi_22_64, -cospi_10_64); - const __m128i k__cospi_p18_p14 = pair_set_epi16(cospi_18_64, cospi_14_64); - const __m128i k__cospi_p14_m18 = pair_set_epi16(cospi_14_64, -cospi_18_64); - const __m128i k__cospi_p26_p06 = pair_set_epi16(cospi_26_64, cospi_6_64); - const __m128i k__cospi_p06_m26 = pair_set_epi16(cospi_6_64, -cospi_26_64); - const __m128i k__cospi_p08_p24 = pair_set_epi16(cospi_8_64, cospi_24_64); - const __m128i k__cospi_p24_m08 = pair_set_epi16(cospi_24_64, -cospi_8_64); - const __m128i k__cospi_m24_p08 = pair_set_epi16(-cospi_24_64, cospi_8_64); - const __m128i k__cospi_p16_m16 = pair_set_epi16(cospi_16_64, -cospi_16_64); - const __m128i k__cospi_p16_p16 = _mm_set1_epi16(cospi_16_64); - const __m128i k__const_0 = _mm_setzero_si128(); - const __m128i k__DCT_CONST_ROUNDING = _mm_set1_epi32(DCT_CONST_ROUNDING); - - __m128i u0, u1, u2, u3, u4, u5, u6, u7, u8, u9, u10, u11, u12, u13, u14, u15; - __m128i v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15; - __m128i w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; - __m128i s0, s1, s2, s3, s4, s5, s6, s7; - __m128i in0, in1, in2, in3, in4, in5, in6, in7; - - // properly aligned for butterfly input - in0 = in[7]; - in1 = in[0]; - in2 = in[5]; - in3 = in[2]; - in4 = in[3]; - in5 = in[4]; - in6 = in[1]; - in7 = in[6]; - - // column transformation - // stage 1 - // interleave and multiply/add into 32-bit integer - s0 = _mm_unpacklo_epi16(in0, in1); - s1 = _mm_unpackhi_epi16(in0, in1); - s2 = _mm_unpacklo_epi16(in2, in3); - s3 = _mm_unpackhi_epi16(in2, in3); - s4 = _mm_unpacklo_epi16(in4, in5); - s5 = _mm_unpackhi_epi16(in4, in5); - s6 = _mm_unpacklo_epi16(in6, in7); - s7 = _mm_unpackhi_epi16(in6, in7); - - u0 = _mm_madd_epi16(s0, k__cospi_p02_p30); - u1 = _mm_madd_epi16(s1, k__cospi_p02_p30); - u2 = _mm_madd_epi16(s0, k__cospi_p30_m02); - u3 = _mm_madd_epi16(s1, k__cospi_p30_m02); - u4 = _mm_madd_epi16(s2, k__cospi_p10_p22); - u5 = _mm_madd_epi16(s3, k__cospi_p10_p22); - u6 = _mm_madd_epi16(s2, k__cospi_p22_m10); - u7 = _mm_madd_epi16(s3, k__cospi_p22_m10); - u8 = _mm_madd_epi16(s4, k__cospi_p18_p14); - u9 = _mm_madd_epi16(s5, k__cospi_p18_p14); - u10 = _mm_madd_epi16(s4, k__cospi_p14_m18); - u11 = _mm_madd_epi16(s5, k__cospi_p14_m18); - u12 = _mm_madd_epi16(s6, k__cospi_p26_p06); - u13 = _mm_madd_epi16(s7, k__cospi_p26_p06); - u14 = _mm_madd_epi16(s6, k__cospi_p06_m26); - u15 = _mm_madd_epi16(s7, k__cospi_p06_m26); - - // addition - w0 = _mm_add_epi32(u0, u8); - w1 = _mm_add_epi32(u1, u9); - w2 = _mm_add_epi32(u2, u10); - w3 = _mm_add_epi32(u3, u11); - w4 = _mm_add_epi32(u4, u12); - w5 = _mm_add_epi32(u5, u13); - w6 = _mm_add_epi32(u6, u14); - w7 = _mm_add_epi32(u7, u15); - w8 = _mm_sub_epi32(u0, u8); - w9 = _mm_sub_epi32(u1, u9); - w10 = _mm_sub_epi32(u2, u10); - w11 = _mm_sub_epi32(u3, u11); - w12 = _mm_sub_epi32(u4, u12); - w13 = _mm_sub_epi32(u5, u13); - w14 = _mm_sub_epi32(u6, u14); - w15 = _mm_sub_epi32(u7, u15); - - // shift and rounding - v0 = _mm_add_epi32(w0, k__DCT_CONST_ROUNDING); - v1 = _mm_add_epi32(w1, k__DCT_CONST_ROUNDING); - v2 = _mm_add_epi32(w2, k__DCT_CONST_ROUNDING); - v3 = _mm_add_epi32(w3, k__DCT_CONST_ROUNDING); - v4 = _mm_add_epi32(w4, k__DCT_CONST_ROUNDING); - v5 = _mm_add_epi32(w5, k__DCT_CONST_ROUNDING); - v6 = _mm_add_epi32(w6, k__DCT_CONST_ROUNDING); - v7 = _mm_add_epi32(w7, k__DCT_CONST_ROUNDING); - v8 = _mm_add_epi32(w8, k__DCT_CONST_ROUNDING); - v9 = _mm_add_epi32(w9, k__DCT_CONST_ROUNDING); - v10 = _mm_add_epi32(w10, k__DCT_CONST_ROUNDING); - v11 = _mm_add_epi32(w11, k__DCT_CONST_ROUNDING); - v12 = _mm_add_epi32(w12, k__DCT_CONST_ROUNDING); - v13 = _mm_add_epi32(w13, k__DCT_CONST_ROUNDING); - v14 = _mm_add_epi32(w14, k__DCT_CONST_ROUNDING); - v15 = _mm_add_epi32(w15, k__DCT_CONST_ROUNDING); - - u0 = _mm_srai_epi32(v0, DCT_CONST_BITS); - u1 = _mm_srai_epi32(v1, DCT_CONST_BITS); - u2 = _mm_srai_epi32(v2, DCT_CONST_BITS); - u3 = _mm_srai_epi32(v3, DCT_CONST_BITS); - u4 = _mm_srai_epi32(v4, DCT_CONST_BITS); - u5 = _mm_srai_epi32(v5, DCT_CONST_BITS); - u6 = _mm_srai_epi32(v6, DCT_CONST_BITS); - u7 = _mm_srai_epi32(v7, DCT_CONST_BITS); - u8 = _mm_srai_epi32(v8, DCT_CONST_BITS); - u9 = _mm_srai_epi32(v9, DCT_CONST_BITS); - u10 = _mm_srai_epi32(v10, DCT_CONST_BITS); - u11 = _mm_srai_epi32(v11, DCT_CONST_BITS); - u12 = _mm_srai_epi32(v12, DCT_CONST_BITS); - u13 = _mm_srai_epi32(v13, DCT_CONST_BITS); - u14 = _mm_srai_epi32(v14, DCT_CONST_BITS); - u15 = _mm_srai_epi32(v15, DCT_CONST_BITS); - - // back to 16-bit and pack 8 integers into __m128i - in[0] = _mm_packs_epi32(u0, u1); - in[1] = _mm_packs_epi32(u2, u3); - in[2] = _mm_packs_epi32(u4, u5); - in[3] = _mm_packs_epi32(u6, u7); - in[4] = _mm_packs_epi32(u8, u9); - in[5] = _mm_packs_epi32(u10, u11); - in[6] = _mm_packs_epi32(u12, u13); - in[7] = _mm_packs_epi32(u14, u15); - - // stage 2 - s0 = _mm_add_epi16(in[0], in[2]); - s1 = _mm_add_epi16(in[1], in[3]); - s2 = _mm_sub_epi16(in[0], in[2]); - s3 = _mm_sub_epi16(in[1], in[3]); - u0 = _mm_unpacklo_epi16(in[4], in[5]); - u1 = _mm_unpackhi_epi16(in[4], in[5]); - u2 = _mm_unpacklo_epi16(in[6], in[7]); - u3 = _mm_unpackhi_epi16(in[6], in[7]); - - v0 = _mm_madd_epi16(u0, k__cospi_p08_p24); - v1 = _mm_madd_epi16(u1, k__cospi_p08_p24); - v2 = _mm_madd_epi16(u0, k__cospi_p24_m08); - v3 = _mm_madd_epi16(u1, k__cospi_p24_m08); - v4 = _mm_madd_epi16(u2, k__cospi_m24_p08); - v5 = _mm_madd_epi16(u3, k__cospi_m24_p08); - v6 = _mm_madd_epi16(u2, k__cospi_p08_p24); - v7 = _mm_madd_epi16(u3, k__cospi_p08_p24); - - w0 = _mm_add_epi32(v0, v4); - w1 = _mm_add_epi32(v1, v5); - w2 = _mm_add_epi32(v2, v6); - w3 = _mm_add_epi32(v3, v7); - w4 = _mm_sub_epi32(v0, v4); - w5 = _mm_sub_epi32(v1, v5); - w6 = _mm_sub_epi32(v2, v6); - w7 = _mm_sub_epi32(v3, v7); - - v0 = _mm_add_epi32(w0, k__DCT_CONST_ROUNDING); - v1 = _mm_add_epi32(w1, k__DCT_CONST_ROUNDING); - v2 = _mm_add_epi32(w2, k__DCT_CONST_ROUNDING); - v3 = _mm_add_epi32(w3, k__DCT_CONST_ROUNDING); - v4 = _mm_add_epi32(w4, k__DCT_CONST_ROUNDING); - v5 = _mm_add_epi32(w5, k__DCT_CONST_ROUNDING); - v6 = _mm_add_epi32(w6, k__DCT_CONST_ROUNDING); - v7 = _mm_add_epi32(w7, k__DCT_CONST_ROUNDING); - - u0 = _mm_srai_epi32(v0, DCT_CONST_BITS); - u1 = _mm_srai_epi32(v1, DCT_CONST_BITS); - u2 = _mm_srai_epi32(v2, DCT_CONST_BITS); - u3 = _mm_srai_epi32(v3, DCT_CONST_BITS); - u4 = _mm_srai_epi32(v4, DCT_CONST_BITS); - u5 = _mm_srai_epi32(v5, DCT_CONST_BITS); - u6 = _mm_srai_epi32(v6, DCT_CONST_BITS); - u7 = _mm_srai_epi32(v7, DCT_CONST_BITS); - - // back to 16-bit intergers - s4 = _mm_packs_epi32(u0, u1); - s5 = _mm_packs_epi32(u2, u3); - s6 = _mm_packs_epi32(u4, u5); - s7 = _mm_packs_epi32(u6, u7); - - // stage 3 - u0 = _mm_unpacklo_epi16(s2, s3); - u1 = _mm_unpackhi_epi16(s2, s3); - u2 = _mm_unpacklo_epi16(s6, s7); - u3 = _mm_unpackhi_epi16(s6, s7); - - v0 = _mm_madd_epi16(u0, k__cospi_p16_p16); - v1 = _mm_madd_epi16(u1, k__cospi_p16_p16); - v2 = _mm_madd_epi16(u0, k__cospi_p16_m16); - v3 = _mm_madd_epi16(u1, k__cospi_p16_m16); - v4 = _mm_madd_epi16(u2, k__cospi_p16_p16); - v5 = _mm_madd_epi16(u3, k__cospi_p16_p16); - v6 = _mm_madd_epi16(u2, k__cospi_p16_m16); - v7 = _mm_madd_epi16(u3, k__cospi_p16_m16); - - u0 = _mm_add_epi32(v0, k__DCT_CONST_ROUNDING); - u1 = _mm_add_epi32(v1, k__DCT_CONST_ROUNDING); - u2 = _mm_add_epi32(v2, k__DCT_CONST_ROUNDING); - u3 = _mm_add_epi32(v3, k__DCT_CONST_ROUNDING); - u4 = _mm_add_epi32(v4, k__DCT_CONST_ROUNDING); - u5 = _mm_add_epi32(v5, k__DCT_CONST_ROUNDING); - u6 = _mm_add_epi32(v6, k__DCT_CONST_ROUNDING); - u7 = _mm_add_epi32(v7, k__DCT_CONST_ROUNDING); - - v0 = _mm_srai_epi32(u0, DCT_CONST_BITS); - v1 = _mm_srai_epi32(u1, DCT_CONST_BITS); - v2 = _mm_srai_epi32(u2, DCT_CONST_BITS); - v3 = _mm_srai_epi32(u3, DCT_CONST_BITS); - v4 = _mm_srai_epi32(u4, DCT_CONST_BITS); - v5 = _mm_srai_epi32(u5, DCT_CONST_BITS); - v6 = _mm_srai_epi32(u6, DCT_CONST_BITS); - v7 = _mm_srai_epi32(u7, DCT_CONST_BITS); - - s2 = _mm_packs_epi32(v0, v1); - s3 = _mm_packs_epi32(v2, v3); - s6 = _mm_packs_epi32(v4, v5); - s7 = _mm_packs_epi32(v6, v7); - - // FIXME(jingning): do subtract using bit inversion? - in[0] = s0; - in[1] = _mm_sub_epi16(k__const_0, s4); - in[2] = s6; - in[3] = _mm_sub_epi16(k__const_0, s2); - in[4] = s3; - in[5] = _mm_sub_epi16(k__const_0, s7); - in[6] = s5; - in[7] = _mm_sub_epi16(k__const_0, s1); - - // transpose - transpose_16bit_8x8(in, in); -} - -void vp9_fht8x8_sse2(const int16_t *input, tran_low_t *output, int stride, - int tx_type) { - __m128i in[8]; - - switch (tx_type) { - case DCT_DCT: vpx_fdct8x8_sse2(input, output, stride); break; - case ADST_DCT: - load_buffer_8x8(input, in, stride); - fadst8_sse2(in); - fdct8_sse2(in); - right_shift_8x8(in, 1); - write_buffer_8x8(output, in, 8); - break; - case DCT_ADST: - load_buffer_8x8(input, in, stride); - fdct8_sse2(in); - fadst8_sse2(in); - right_shift_8x8(in, 1); - write_buffer_8x8(output, in, 8); - break; - default: - assert(tx_type == ADST_ADST); - load_buffer_8x8(input, in, stride); - fadst8_sse2(in); - fadst8_sse2(in); - right_shift_8x8(in, 1); - write_buffer_8x8(output, in, 8); - break; - } -} - -static INLINE void load_buffer_16x16(const int16_t *input, __m128i *in0, - __m128i *in1, int stride) { - // load first 8 columns - load_buffer_8x8(input, in0, stride); - load_buffer_8x8(input + 8 * stride, in0 + 8, stride); - - input += 8; - // load second 8 columns - load_buffer_8x8(input, in1, stride); - load_buffer_8x8(input + 8 * stride, in1 + 8, stride); -} - -static INLINE void write_buffer_16x16(tran_low_t *output, __m128i *in0, - __m128i *in1, int stride) { - // write first 8 columns - write_buffer_8x8(output, in0, stride); - write_buffer_8x8(output + 8 * stride, in0 + 8, stride); - // write second 8 columns - output += 8; - write_buffer_8x8(output, in1, stride); - write_buffer_8x8(output + 8 * stride, in1 + 8, stride); -} - -static INLINE void right_shift_16x16(__m128i *res0, __m128i *res1) { - // perform rounding operations - right_shift_8x8(res0, 2); - right_shift_8x8(res0 + 8, 2); - right_shift_8x8(res1, 2); - right_shift_8x8(res1 + 8, 2); -} - -static void fdct16_8col(__m128i *in) { - // perform 16x16 1-D DCT for 8 columns - __m128i i[8], s[8], p[8], t[8], u[16], v[16]; - const __m128i k__cospi_p16_p16 = _mm_set1_epi16(cospi_16_64); - const __m128i k__cospi_p16_m16 = pair_set_epi16(cospi_16_64, -cospi_16_64); - const __m128i k__cospi_m16_p16 = pair_set_epi16(-cospi_16_64, cospi_16_64); - const __m128i k__cospi_p24_p08 = pair_set_epi16(cospi_24_64, cospi_8_64); - const __m128i k__cospi_p08_m24 = pair_set_epi16(cospi_8_64, -cospi_24_64); - const __m128i k__cospi_m08_p24 = pair_set_epi16(-cospi_8_64, cospi_24_64); - const __m128i k__cospi_p28_p04 = pair_set_epi16(cospi_28_64, cospi_4_64); - const __m128i k__cospi_m04_p28 = pair_set_epi16(-cospi_4_64, cospi_28_64); - const __m128i k__cospi_p12_p20 = pair_set_epi16(cospi_12_64, cospi_20_64); - const __m128i k__cospi_m20_p12 = pair_set_epi16(-cospi_20_64, cospi_12_64); - const __m128i k__cospi_p30_p02 = pair_set_epi16(cospi_30_64, cospi_2_64); - const __m128i k__cospi_p14_p18 = pair_set_epi16(cospi_14_64, cospi_18_64); - const __m128i k__cospi_m02_p30 = pair_set_epi16(-cospi_2_64, cospi_30_64); - const __m128i k__cospi_m18_p14 = pair_set_epi16(-cospi_18_64, cospi_14_64); - const __m128i k__cospi_p22_p10 = pair_set_epi16(cospi_22_64, cospi_10_64); - const __m128i k__cospi_p06_p26 = pair_set_epi16(cospi_6_64, cospi_26_64); - const __m128i k__cospi_m10_p22 = pair_set_epi16(-cospi_10_64, cospi_22_64); - const __m128i k__cospi_m26_p06 = pair_set_epi16(-cospi_26_64, cospi_6_64); - const __m128i k__DCT_CONST_ROUNDING = _mm_set1_epi32(DCT_CONST_ROUNDING); - - // stage 1 - i[0] = _mm_add_epi16(in[0], in[15]); - i[1] = _mm_add_epi16(in[1], in[14]); - i[2] = _mm_add_epi16(in[2], in[13]); - i[3] = _mm_add_epi16(in[3], in[12]); - i[4] = _mm_add_epi16(in[4], in[11]); - i[5] = _mm_add_epi16(in[5], in[10]); - i[6] = _mm_add_epi16(in[6], in[9]); - i[7] = _mm_add_epi16(in[7], in[8]); - - s[0] = _mm_sub_epi16(in[7], in[8]); - s[1] = _mm_sub_epi16(in[6], in[9]); - s[2] = _mm_sub_epi16(in[5], in[10]); - s[3] = _mm_sub_epi16(in[4], in[11]); - s[4] = _mm_sub_epi16(in[3], in[12]); - s[5] = _mm_sub_epi16(in[2], in[13]); - s[6] = _mm_sub_epi16(in[1], in[14]); - s[7] = _mm_sub_epi16(in[0], in[15]); - - p[0] = _mm_add_epi16(i[0], i[7]); - p[1] = _mm_add_epi16(i[1], i[6]); - p[2] = _mm_add_epi16(i[2], i[5]); - p[3] = _mm_add_epi16(i[3], i[4]); - p[4] = _mm_sub_epi16(i[3], i[4]); - p[5] = _mm_sub_epi16(i[2], i[5]); - p[6] = _mm_sub_epi16(i[1], i[6]); - p[7] = _mm_sub_epi16(i[0], i[7]); - - u[0] = _mm_add_epi16(p[0], p[3]); - u[1] = _mm_add_epi16(p[1], p[2]); - u[2] = _mm_sub_epi16(p[1], p[2]); - u[3] = _mm_sub_epi16(p[0], p[3]); - - v[0] = _mm_unpacklo_epi16(u[0], u[1]); - v[1] = _mm_unpackhi_epi16(u[0], u[1]); - v[2] = _mm_unpacklo_epi16(u[2], u[3]); - v[3] = _mm_unpackhi_epi16(u[2], u[3]); - - u[0] = _mm_madd_epi16(v[0], k__cospi_p16_p16); - u[1] = _mm_madd_epi16(v[1], k__cospi_p16_p16); - u[2] = _mm_madd_epi16(v[0], k__cospi_p16_m16); - u[3] = _mm_madd_epi16(v[1], k__cospi_p16_m16); - u[4] = _mm_madd_epi16(v[2], k__cospi_p24_p08); - u[5] = _mm_madd_epi16(v[3], k__cospi_p24_p08); - u[6] = _mm_madd_epi16(v[2], k__cospi_m08_p24); - u[7] = _mm_madd_epi16(v[3], k__cospi_m08_p24); - - v[0] = _mm_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm_add_epi32(u[3], k__DCT_CONST_ROUNDING); - v[4] = _mm_add_epi32(u[4], k__DCT_CONST_ROUNDING); - v[5] = _mm_add_epi32(u[5], k__DCT_CONST_ROUNDING); - v[6] = _mm_add_epi32(u[6], k__DCT_CONST_ROUNDING); - v[7] = _mm_add_epi32(u[7], k__DCT_CONST_ROUNDING); - - u[0] = _mm_srai_epi32(v[0], DCT_CONST_BITS); - u[1] = _mm_srai_epi32(v[1], DCT_CONST_BITS); - u[2] = _mm_srai_epi32(v[2], DCT_CONST_BITS); - u[3] = _mm_srai_epi32(v[3], DCT_CONST_BITS); - u[4] = _mm_srai_epi32(v[4], DCT_CONST_BITS); - u[5] = _mm_srai_epi32(v[5], DCT_CONST_BITS); - u[6] = _mm_srai_epi32(v[6], DCT_CONST_BITS); - u[7] = _mm_srai_epi32(v[7], DCT_CONST_BITS); - - in[0] = _mm_packs_epi32(u[0], u[1]); - in[4] = _mm_packs_epi32(u[4], u[5]); - in[8] = _mm_packs_epi32(u[2], u[3]); - in[12] = _mm_packs_epi32(u[6], u[7]); - - u[0] = _mm_unpacklo_epi16(p[5], p[6]); - u[1] = _mm_unpackhi_epi16(p[5], p[6]); - v[0] = _mm_madd_epi16(u[0], k__cospi_m16_p16); - v[1] = _mm_madd_epi16(u[1], k__cospi_m16_p16); - v[2] = _mm_madd_epi16(u[0], k__cospi_p16_p16); - v[3] = _mm_madd_epi16(u[1], k__cospi_p16_p16); - - u[0] = _mm_add_epi32(v[0], k__DCT_CONST_ROUNDING); - u[1] = _mm_add_epi32(v[1], k__DCT_CONST_ROUNDING); - u[2] = _mm_add_epi32(v[2], k__DCT_CONST_ROUNDING); - u[3] = _mm_add_epi32(v[3], k__DCT_CONST_ROUNDING); - - v[0] = _mm_srai_epi32(u[0], DCT_CONST_BITS); - v[1] = _mm_srai_epi32(u[1], DCT_CONST_BITS); - v[2] = _mm_srai_epi32(u[2], DCT_CONST_BITS); - v[3] = _mm_srai_epi32(u[3], DCT_CONST_BITS); - - u[0] = _mm_packs_epi32(v[0], v[1]); - u[1] = _mm_packs_epi32(v[2], v[3]); - - t[0] = _mm_add_epi16(p[4], u[0]); - t[1] = _mm_sub_epi16(p[4], u[0]); - t[2] = _mm_sub_epi16(p[7], u[1]); - t[3] = _mm_add_epi16(p[7], u[1]); - - u[0] = _mm_unpacklo_epi16(t[0], t[3]); - u[1] = _mm_unpackhi_epi16(t[0], t[3]); - u[2] = _mm_unpacklo_epi16(t[1], t[2]); - u[3] = _mm_unpackhi_epi16(t[1], t[2]); - - v[0] = _mm_madd_epi16(u[0], k__cospi_p28_p04); - v[1] = _mm_madd_epi16(u[1], k__cospi_p28_p04); - v[2] = _mm_madd_epi16(u[2], k__cospi_p12_p20); - v[3] = _mm_madd_epi16(u[3], k__cospi_p12_p20); - v[4] = _mm_madd_epi16(u[2], k__cospi_m20_p12); - v[5] = _mm_madd_epi16(u[3], k__cospi_m20_p12); - v[6] = _mm_madd_epi16(u[0], k__cospi_m04_p28); - v[7] = _mm_madd_epi16(u[1], k__cospi_m04_p28); - - u[0] = _mm_add_epi32(v[0], k__DCT_CONST_ROUNDING); - u[1] = _mm_add_epi32(v[1], k__DCT_CONST_ROUNDING); - u[2] = _mm_add_epi32(v[2], k__DCT_CONST_ROUNDING); - u[3] = _mm_add_epi32(v[3], k__DCT_CONST_ROUNDING); - u[4] = _mm_add_epi32(v[4], k__DCT_CONST_ROUNDING); - u[5] = _mm_add_epi32(v[5], k__DCT_CONST_ROUNDING); - u[6] = _mm_add_epi32(v[6], k__DCT_CONST_ROUNDING); - u[7] = _mm_add_epi32(v[7], k__DCT_CONST_ROUNDING); - - v[0] = _mm_srai_epi32(u[0], DCT_CONST_BITS); - v[1] = _mm_srai_epi32(u[1], DCT_CONST_BITS); - v[2] = _mm_srai_epi32(u[2], DCT_CONST_BITS); - v[3] = _mm_srai_epi32(u[3], DCT_CONST_BITS); - v[4] = _mm_srai_epi32(u[4], DCT_CONST_BITS); - v[5] = _mm_srai_epi32(u[5], DCT_CONST_BITS); - v[6] = _mm_srai_epi32(u[6], DCT_CONST_BITS); - v[7] = _mm_srai_epi32(u[7], DCT_CONST_BITS); - - in[2] = _mm_packs_epi32(v[0], v[1]); - in[6] = _mm_packs_epi32(v[4], v[5]); - in[10] = _mm_packs_epi32(v[2], v[3]); - in[14] = _mm_packs_epi32(v[6], v[7]); - - // stage 2 - u[0] = _mm_unpacklo_epi16(s[2], s[5]); - u[1] = _mm_unpackhi_epi16(s[2], s[5]); - u[2] = _mm_unpacklo_epi16(s[3], s[4]); - u[3] = _mm_unpackhi_epi16(s[3], s[4]); - - v[0] = _mm_madd_epi16(u[0], k__cospi_m16_p16); - v[1] = _mm_madd_epi16(u[1], k__cospi_m16_p16); - v[2] = _mm_madd_epi16(u[2], k__cospi_m16_p16); - v[3] = _mm_madd_epi16(u[3], k__cospi_m16_p16); - v[4] = _mm_madd_epi16(u[2], k__cospi_p16_p16); - v[5] = _mm_madd_epi16(u[3], k__cospi_p16_p16); - v[6] = _mm_madd_epi16(u[0], k__cospi_p16_p16); - v[7] = _mm_madd_epi16(u[1], k__cospi_p16_p16); - - u[0] = _mm_add_epi32(v[0], k__DCT_CONST_ROUNDING); - u[1] = _mm_add_epi32(v[1], k__DCT_CONST_ROUNDING); - u[2] = _mm_add_epi32(v[2], k__DCT_CONST_ROUNDING); - u[3] = _mm_add_epi32(v[3], k__DCT_CONST_ROUNDING); - u[4] = _mm_add_epi32(v[4], k__DCT_CONST_ROUNDING); - u[5] = _mm_add_epi32(v[5], k__DCT_CONST_ROUNDING); - u[6] = _mm_add_epi32(v[6], k__DCT_CONST_ROUNDING); - u[7] = _mm_add_epi32(v[7], k__DCT_CONST_ROUNDING); - - v[0] = _mm_srai_epi32(u[0], DCT_CONST_BITS); - v[1] = _mm_srai_epi32(u[1], DCT_CONST_BITS); - v[2] = _mm_srai_epi32(u[2], DCT_CONST_BITS); - v[3] = _mm_srai_epi32(u[3], DCT_CONST_BITS); - v[4] = _mm_srai_epi32(u[4], DCT_CONST_BITS); - v[5] = _mm_srai_epi32(u[5], DCT_CONST_BITS); - v[6] = _mm_srai_epi32(u[6], DCT_CONST_BITS); - v[7] = _mm_srai_epi32(u[7], DCT_CONST_BITS); - - t[2] = _mm_packs_epi32(v[0], v[1]); - t[3] = _mm_packs_epi32(v[2], v[3]); - t[4] = _mm_packs_epi32(v[4], v[5]); - t[5] = _mm_packs_epi32(v[6], v[7]); - - // stage 3 - p[0] = _mm_add_epi16(s[0], t[3]); - p[1] = _mm_add_epi16(s[1], t[2]); - p[2] = _mm_sub_epi16(s[1], t[2]); - p[3] = _mm_sub_epi16(s[0], t[3]); - p[4] = _mm_sub_epi16(s[7], t[4]); - p[5] = _mm_sub_epi16(s[6], t[5]); - p[6] = _mm_add_epi16(s[6], t[5]); - p[7] = _mm_add_epi16(s[7], t[4]); - - // stage 4 - u[0] = _mm_unpacklo_epi16(p[1], p[6]); - u[1] = _mm_unpackhi_epi16(p[1], p[6]); - u[2] = _mm_unpacklo_epi16(p[2], p[5]); - u[3] = _mm_unpackhi_epi16(p[2], p[5]); - - v[0] = _mm_madd_epi16(u[0], k__cospi_m08_p24); - v[1] = _mm_madd_epi16(u[1], k__cospi_m08_p24); - v[2] = _mm_madd_epi16(u[2], k__cospi_p24_p08); - v[3] = _mm_madd_epi16(u[3], k__cospi_p24_p08); - v[4] = _mm_madd_epi16(u[2], k__cospi_p08_m24); - v[5] = _mm_madd_epi16(u[3], k__cospi_p08_m24); - v[6] = _mm_madd_epi16(u[0], k__cospi_p24_p08); - v[7] = _mm_madd_epi16(u[1], k__cospi_p24_p08); - - u[0] = _mm_add_epi32(v[0], k__DCT_CONST_ROUNDING); - u[1] = _mm_add_epi32(v[1], k__DCT_CONST_ROUNDING); - u[2] = _mm_add_epi32(v[2], k__DCT_CONST_ROUNDING); - u[3] = _mm_add_epi32(v[3], k__DCT_CONST_ROUNDING); - u[4] = _mm_add_epi32(v[4], k__DCT_CONST_ROUNDING); - u[5] = _mm_add_epi32(v[5], k__DCT_CONST_ROUNDING); - u[6] = _mm_add_epi32(v[6], k__DCT_CONST_ROUNDING); - u[7] = _mm_add_epi32(v[7], k__DCT_CONST_ROUNDING); - - v[0] = _mm_srai_epi32(u[0], DCT_CONST_BITS); - v[1] = _mm_srai_epi32(u[1], DCT_CONST_BITS); - v[2] = _mm_srai_epi32(u[2], DCT_CONST_BITS); - v[3] = _mm_srai_epi32(u[3], DCT_CONST_BITS); - v[4] = _mm_srai_epi32(u[4], DCT_CONST_BITS); - v[5] = _mm_srai_epi32(u[5], DCT_CONST_BITS); - v[6] = _mm_srai_epi32(u[6], DCT_CONST_BITS); - v[7] = _mm_srai_epi32(u[7], DCT_CONST_BITS); - - t[1] = _mm_packs_epi32(v[0], v[1]); - t[2] = _mm_packs_epi32(v[2], v[3]); - t[5] = _mm_packs_epi32(v[4], v[5]); - t[6] = _mm_packs_epi32(v[6], v[7]); - - // stage 5 - s[0] = _mm_add_epi16(p[0], t[1]); - s[1] = _mm_sub_epi16(p[0], t[1]); - s[2] = _mm_add_epi16(p[3], t[2]); - s[3] = _mm_sub_epi16(p[3], t[2]); - s[4] = _mm_sub_epi16(p[4], t[5]); - s[5] = _mm_add_epi16(p[4], t[5]); - s[6] = _mm_sub_epi16(p[7], t[6]); - s[7] = _mm_add_epi16(p[7], t[6]); - - // stage 6 - u[0] = _mm_unpacklo_epi16(s[0], s[7]); - u[1] = _mm_unpackhi_epi16(s[0], s[7]); - u[2] = _mm_unpacklo_epi16(s[1], s[6]); - u[3] = _mm_unpackhi_epi16(s[1], s[6]); - u[4] = _mm_unpacklo_epi16(s[2], s[5]); - u[5] = _mm_unpackhi_epi16(s[2], s[5]); - u[6] = _mm_unpacklo_epi16(s[3], s[4]); - u[7] = _mm_unpackhi_epi16(s[3], s[4]); - - v[0] = _mm_madd_epi16(u[0], k__cospi_p30_p02); - v[1] = _mm_madd_epi16(u[1], k__cospi_p30_p02); - v[2] = _mm_madd_epi16(u[2], k__cospi_p14_p18); - v[3] = _mm_madd_epi16(u[3], k__cospi_p14_p18); - v[4] = _mm_madd_epi16(u[4], k__cospi_p22_p10); - v[5] = _mm_madd_epi16(u[5], k__cospi_p22_p10); - v[6] = _mm_madd_epi16(u[6], k__cospi_p06_p26); - v[7] = _mm_madd_epi16(u[7], k__cospi_p06_p26); - v[8] = _mm_madd_epi16(u[6], k__cospi_m26_p06); - v[9] = _mm_madd_epi16(u[7], k__cospi_m26_p06); - v[10] = _mm_madd_epi16(u[4], k__cospi_m10_p22); - v[11] = _mm_madd_epi16(u[5], k__cospi_m10_p22); - v[12] = _mm_madd_epi16(u[2], k__cospi_m18_p14); - v[13] = _mm_madd_epi16(u[3], k__cospi_m18_p14); - v[14] = _mm_madd_epi16(u[0], k__cospi_m02_p30); - v[15] = _mm_madd_epi16(u[1], k__cospi_m02_p30); - - u[0] = _mm_add_epi32(v[0], k__DCT_CONST_ROUNDING); - u[1] = _mm_add_epi32(v[1], k__DCT_CONST_ROUNDING); - u[2] = _mm_add_epi32(v[2], k__DCT_CONST_ROUNDING); - u[3] = _mm_add_epi32(v[3], k__DCT_CONST_ROUNDING); - u[4] = _mm_add_epi32(v[4], k__DCT_CONST_ROUNDING); - u[5] = _mm_add_epi32(v[5], k__DCT_CONST_ROUNDING); - u[6] = _mm_add_epi32(v[6], k__DCT_CONST_ROUNDING); - u[7] = _mm_add_epi32(v[7], k__DCT_CONST_ROUNDING); - u[8] = _mm_add_epi32(v[8], k__DCT_CONST_ROUNDING); - u[9] = _mm_add_epi32(v[9], k__DCT_CONST_ROUNDING); - u[10] = _mm_add_epi32(v[10], k__DCT_CONST_ROUNDING); - u[11] = _mm_add_epi32(v[11], k__DCT_CONST_ROUNDING); - u[12] = _mm_add_epi32(v[12], k__DCT_CONST_ROUNDING); - u[13] = _mm_add_epi32(v[13], k__DCT_CONST_ROUNDING); - u[14] = _mm_add_epi32(v[14], k__DCT_CONST_ROUNDING); - u[15] = _mm_add_epi32(v[15], k__DCT_CONST_ROUNDING); - - v[0] = _mm_srai_epi32(u[0], DCT_CONST_BITS); - v[1] = _mm_srai_epi32(u[1], DCT_CONST_BITS); - v[2] = _mm_srai_epi32(u[2], DCT_CONST_BITS); - v[3] = _mm_srai_epi32(u[3], DCT_CONST_BITS); - v[4] = _mm_srai_epi32(u[4], DCT_CONST_BITS); - v[5] = _mm_srai_epi32(u[5], DCT_CONST_BITS); - v[6] = _mm_srai_epi32(u[6], DCT_CONST_BITS); - v[7] = _mm_srai_epi32(u[7], DCT_CONST_BITS); - v[8] = _mm_srai_epi32(u[8], DCT_CONST_BITS); - v[9] = _mm_srai_epi32(u[9], DCT_CONST_BITS); - v[10] = _mm_srai_epi32(u[10], DCT_CONST_BITS); - v[11] = _mm_srai_epi32(u[11], DCT_CONST_BITS); - v[12] = _mm_srai_epi32(u[12], DCT_CONST_BITS); - v[13] = _mm_srai_epi32(u[13], DCT_CONST_BITS); - v[14] = _mm_srai_epi32(u[14], DCT_CONST_BITS); - v[15] = _mm_srai_epi32(u[15], DCT_CONST_BITS); - - in[1] = _mm_packs_epi32(v[0], v[1]); - in[9] = _mm_packs_epi32(v[2], v[3]); - in[5] = _mm_packs_epi32(v[4], v[5]); - in[13] = _mm_packs_epi32(v[6], v[7]); - in[3] = _mm_packs_epi32(v[8], v[9]); - in[11] = _mm_packs_epi32(v[10], v[11]); - in[7] = _mm_packs_epi32(v[12], v[13]); - in[15] = _mm_packs_epi32(v[14], v[15]); -} - -static void fadst16_8col(__m128i *in) { - // perform 16x16 1-D ADST for 8 columns - __m128i s[16], x[16], u[32], v[32]; - const __m128i k__cospi_p01_p31 = pair_set_epi16(cospi_1_64, cospi_31_64); - const __m128i k__cospi_p31_m01 = pair_set_epi16(cospi_31_64, -cospi_1_64); - const __m128i k__cospi_p05_p27 = pair_set_epi16(cospi_5_64, cospi_27_64); - const __m128i k__cospi_p27_m05 = pair_set_epi16(cospi_27_64, -cospi_5_64); - const __m128i k__cospi_p09_p23 = pair_set_epi16(cospi_9_64, cospi_23_64); - const __m128i k__cospi_p23_m09 = pair_set_epi16(cospi_23_64, -cospi_9_64); - const __m128i k__cospi_p13_p19 = pair_set_epi16(cospi_13_64, cospi_19_64); - const __m128i k__cospi_p19_m13 = pair_set_epi16(cospi_19_64, -cospi_13_64); - const __m128i k__cospi_p17_p15 = pair_set_epi16(cospi_17_64, cospi_15_64); - const __m128i k__cospi_p15_m17 = pair_set_epi16(cospi_15_64, -cospi_17_64); - const __m128i k__cospi_p21_p11 = pair_set_epi16(cospi_21_64, cospi_11_64); - const __m128i k__cospi_p11_m21 = pair_set_epi16(cospi_11_64, -cospi_21_64); - const __m128i k__cospi_p25_p07 = pair_set_epi16(cospi_25_64, cospi_7_64); - const __m128i k__cospi_p07_m25 = pair_set_epi16(cospi_7_64, -cospi_25_64); - const __m128i k__cospi_p29_p03 = pair_set_epi16(cospi_29_64, cospi_3_64); - const __m128i k__cospi_p03_m29 = pair_set_epi16(cospi_3_64, -cospi_29_64); - const __m128i k__cospi_p04_p28 = pair_set_epi16(cospi_4_64, cospi_28_64); - const __m128i k__cospi_p28_m04 = pair_set_epi16(cospi_28_64, -cospi_4_64); - const __m128i k__cospi_p20_p12 = pair_set_epi16(cospi_20_64, cospi_12_64); - const __m128i k__cospi_p12_m20 = pair_set_epi16(cospi_12_64, -cospi_20_64); - const __m128i k__cospi_m28_p04 = pair_set_epi16(-cospi_28_64, cospi_4_64); - const __m128i k__cospi_m12_p20 = pair_set_epi16(-cospi_12_64, cospi_20_64); - const __m128i k__cospi_p08_p24 = pair_set_epi16(cospi_8_64, cospi_24_64); - const __m128i k__cospi_p24_m08 = pair_set_epi16(cospi_24_64, -cospi_8_64); - const __m128i k__cospi_m24_p08 = pair_set_epi16(-cospi_24_64, cospi_8_64); - const __m128i k__cospi_m16_m16 = _mm_set1_epi16(-cospi_16_64); - const __m128i k__cospi_p16_p16 = _mm_set1_epi16(cospi_16_64); - const __m128i k__cospi_p16_m16 = pair_set_epi16(cospi_16_64, -cospi_16_64); - const __m128i k__cospi_m16_p16 = pair_set_epi16(-cospi_16_64, cospi_16_64); - const __m128i k__DCT_CONST_ROUNDING = _mm_set1_epi32(DCT_CONST_ROUNDING); - const __m128i kZero = _mm_setzero_si128(); - - u[0] = _mm_unpacklo_epi16(in[15], in[0]); - u[1] = _mm_unpackhi_epi16(in[15], in[0]); - u[2] = _mm_unpacklo_epi16(in[13], in[2]); - u[3] = _mm_unpackhi_epi16(in[13], in[2]); - u[4] = _mm_unpacklo_epi16(in[11], in[4]); - u[5] = _mm_unpackhi_epi16(in[11], in[4]); - u[6] = _mm_unpacklo_epi16(in[9], in[6]); - u[7] = _mm_unpackhi_epi16(in[9], in[6]); - u[8] = _mm_unpacklo_epi16(in[7], in[8]); - u[9] = _mm_unpackhi_epi16(in[7], in[8]); - u[10] = _mm_unpacklo_epi16(in[5], in[10]); - u[11] = _mm_unpackhi_epi16(in[5], in[10]); - u[12] = _mm_unpacklo_epi16(in[3], in[12]); - u[13] = _mm_unpackhi_epi16(in[3], in[12]); - u[14] = _mm_unpacklo_epi16(in[1], in[14]); - u[15] = _mm_unpackhi_epi16(in[1], in[14]); - - v[0] = _mm_madd_epi16(u[0], k__cospi_p01_p31); - v[1] = _mm_madd_epi16(u[1], k__cospi_p01_p31); - v[2] = _mm_madd_epi16(u[0], k__cospi_p31_m01); - v[3] = _mm_madd_epi16(u[1], k__cospi_p31_m01); - v[4] = _mm_madd_epi16(u[2], k__cospi_p05_p27); - v[5] = _mm_madd_epi16(u[3], k__cospi_p05_p27); - v[6] = _mm_madd_epi16(u[2], k__cospi_p27_m05); - v[7] = _mm_madd_epi16(u[3], k__cospi_p27_m05); - v[8] = _mm_madd_epi16(u[4], k__cospi_p09_p23); - v[9] = _mm_madd_epi16(u[5], k__cospi_p09_p23); - v[10] = _mm_madd_epi16(u[4], k__cospi_p23_m09); - v[11] = _mm_madd_epi16(u[5], k__cospi_p23_m09); - v[12] = _mm_madd_epi16(u[6], k__cospi_p13_p19); - v[13] = _mm_madd_epi16(u[7], k__cospi_p13_p19); - v[14] = _mm_madd_epi16(u[6], k__cospi_p19_m13); - v[15] = _mm_madd_epi16(u[7], k__cospi_p19_m13); - v[16] = _mm_madd_epi16(u[8], k__cospi_p17_p15); - v[17] = _mm_madd_epi16(u[9], k__cospi_p17_p15); - v[18] = _mm_madd_epi16(u[8], k__cospi_p15_m17); - v[19] = _mm_madd_epi16(u[9], k__cospi_p15_m17); - v[20] = _mm_madd_epi16(u[10], k__cospi_p21_p11); - v[21] = _mm_madd_epi16(u[11], k__cospi_p21_p11); - v[22] = _mm_madd_epi16(u[10], k__cospi_p11_m21); - v[23] = _mm_madd_epi16(u[11], k__cospi_p11_m21); - v[24] = _mm_madd_epi16(u[12], k__cospi_p25_p07); - v[25] = _mm_madd_epi16(u[13], k__cospi_p25_p07); - v[26] = _mm_madd_epi16(u[12], k__cospi_p07_m25); - v[27] = _mm_madd_epi16(u[13], k__cospi_p07_m25); - v[28] = _mm_madd_epi16(u[14], k__cospi_p29_p03); - v[29] = _mm_madd_epi16(u[15], k__cospi_p29_p03); - v[30] = _mm_madd_epi16(u[14], k__cospi_p03_m29); - v[31] = _mm_madd_epi16(u[15], k__cospi_p03_m29); - - u[0] = _mm_add_epi32(v[0], v[16]); - u[1] = _mm_add_epi32(v[1], v[17]); - u[2] = _mm_add_epi32(v[2], v[18]); - u[3] = _mm_add_epi32(v[3], v[19]); - u[4] = _mm_add_epi32(v[4], v[20]); - u[5] = _mm_add_epi32(v[5], v[21]); - u[6] = _mm_add_epi32(v[6], v[22]); - u[7] = _mm_add_epi32(v[7], v[23]); - u[8] = _mm_add_epi32(v[8], v[24]); - u[9] = _mm_add_epi32(v[9], v[25]); - u[10] = _mm_add_epi32(v[10], v[26]); - u[11] = _mm_add_epi32(v[11], v[27]); - u[12] = _mm_add_epi32(v[12], v[28]); - u[13] = _mm_add_epi32(v[13], v[29]); - u[14] = _mm_add_epi32(v[14], v[30]); - u[15] = _mm_add_epi32(v[15], v[31]); - u[16] = _mm_sub_epi32(v[0], v[16]); - u[17] = _mm_sub_epi32(v[1], v[17]); - u[18] = _mm_sub_epi32(v[2], v[18]); - u[19] = _mm_sub_epi32(v[3], v[19]); - u[20] = _mm_sub_epi32(v[4], v[20]); - u[21] = _mm_sub_epi32(v[5], v[21]); - u[22] = _mm_sub_epi32(v[6], v[22]); - u[23] = _mm_sub_epi32(v[7], v[23]); - u[24] = _mm_sub_epi32(v[8], v[24]); - u[25] = _mm_sub_epi32(v[9], v[25]); - u[26] = _mm_sub_epi32(v[10], v[26]); - u[27] = _mm_sub_epi32(v[11], v[27]); - u[28] = _mm_sub_epi32(v[12], v[28]); - u[29] = _mm_sub_epi32(v[13], v[29]); - u[30] = _mm_sub_epi32(v[14], v[30]); - u[31] = _mm_sub_epi32(v[15], v[31]); - - v[0] = _mm_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm_add_epi32(u[3], k__DCT_CONST_ROUNDING); - v[4] = _mm_add_epi32(u[4], k__DCT_CONST_ROUNDING); - v[5] = _mm_add_epi32(u[5], k__DCT_CONST_ROUNDING); - v[6] = _mm_add_epi32(u[6], k__DCT_CONST_ROUNDING); - v[7] = _mm_add_epi32(u[7], k__DCT_CONST_ROUNDING); - v[8] = _mm_add_epi32(u[8], k__DCT_CONST_ROUNDING); - v[9] = _mm_add_epi32(u[9], k__DCT_CONST_ROUNDING); - v[10] = _mm_add_epi32(u[10], k__DCT_CONST_ROUNDING); - v[11] = _mm_add_epi32(u[11], k__DCT_CONST_ROUNDING); - v[12] = _mm_add_epi32(u[12], k__DCT_CONST_ROUNDING); - v[13] = _mm_add_epi32(u[13], k__DCT_CONST_ROUNDING); - v[14] = _mm_add_epi32(u[14], k__DCT_CONST_ROUNDING); - v[15] = _mm_add_epi32(u[15], k__DCT_CONST_ROUNDING); - v[16] = _mm_add_epi32(u[16], k__DCT_CONST_ROUNDING); - v[17] = _mm_add_epi32(u[17], k__DCT_CONST_ROUNDING); - v[18] = _mm_add_epi32(u[18], k__DCT_CONST_ROUNDING); - v[19] = _mm_add_epi32(u[19], k__DCT_CONST_ROUNDING); - v[20] = _mm_add_epi32(u[20], k__DCT_CONST_ROUNDING); - v[21] = _mm_add_epi32(u[21], k__DCT_CONST_ROUNDING); - v[22] = _mm_add_epi32(u[22], k__DCT_CONST_ROUNDING); - v[23] = _mm_add_epi32(u[23], k__DCT_CONST_ROUNDING); - v[24] = _mm_add_epi32(u[24], k__DCT_CONST_ROUNDING); - v[25] = _mm_add_epi32(u[25], k__DCT_CONST_ROUNDING); - v[26] = _mm_add_epi32(u[26], k__DCT_CONST_ROUNDING); - v[27] = _mm_add_epi32(u[27], k__DCT_CONST_ROUNDING); - v[28] = _mm_add_epi32(u[28], k__DCT_CONST_ROUNDING); - v[29] = _mm_add_epi32(u[29], k__DCT_CONST_ROUNDING); - v[30] = _mm_add_epi32(u[30], k__DCT_CONST_ROUNDING); - v[31] = _mm_add_epi32(u[31], k__DCT_CONST_ROUNDING); - - u[0] = _mm_srai_epi32(v[0], DCT_CONST_BITS); - u[1] = _mm_srai_epi32(v[1], DCT_CONST_BITS); - u[2] = _mm_srai_epi32(v[2], DCT_CONST_BITS); - u[3] = _mm_srai_epi32(v[3], DCT_CONST_BITS); - u[4] = _mm_srai_epi32(v[4], DCT_CONST_BITS); - u[5] = _mm_srai_epi32(v[5], DCT_CONST_BITS); - u[6] = _mm_srai_epi32(v[6], DCT_CONST_BITS); - u[7] = _mm_srai_epi32(v[7], DCT_CONST_BITS); - u[8] = _mm_srai_epi32(v[8], DCT_CONST_BITS); - u[9] = _mm_srai_epi32(v[9], DCT_CONST_BITS); - u[10] = _mm_srai_epi32(v[10], DCT_CONST_BITS); - u[11] = _mm_srai_epi32(v[11], DCT_CONST_BITS); - u[12] = _mm_srai_epi32(v[12], DCT_CONST_BITS); - u[13] = _mm_srai_epi32(v[13], DCT_CONST_BITS); - u[14] = _mm_srai_epi32(v[14], DCT_CONST_BITS); - u[15] = _mm_srai_epi32(v[15], DCT_CONST_BITS); - u[16] = _mm_srai_epi32(v[16], DCT_CONST_BITS); - u[17] = _mm_srai_epi32(v[17], DCT_CONST_BITS); - u[18] = _mm_srai_epi32(v[18], DCT_CONST_BITS); - u[19] = _mm_srai_epi32(v[19], DCT_CONST_BITS); - u[20] = _mm_srai_epi32(v[20], DCT_CONST_BITS); - u[21] = _mm_srai_epi32(v[21], DCT_CONST_BITS); - u[22] = _mm_srai_epi32(v[22], DCT_CONST_BITS); - u[23] = _mm_srai_epi32(v[23], DCT_CONST_BITS); - u[24] = _mm_srai_epi32(v[24], DCT_CONST_BITS); - u[25] = _mm_srai_epi32(v[25], DCT_CONST_BITS); - u[26] = _mm_srai_epi32(v[26], DCT_CONST_BITS); - u[27] = _mm_srai_epi32(v[27], DCT_CONST_BITS); - u[28] = _mm_srai_epi32(v[28], DCT_CONST_BITS); - u[29] = _mm_srai_epi32(v[29], DCT_CONST_BITS); - u[30] = _mm_srai_epi32(v[30], DCT_CONST_BITS); - u[31] = _mm_srai_epi32(v[31], DCT_CONST_BITS); - - s[0] = _mm_packs_epi32(u[0], u[1]); - s[1] = _mm_packs_epi32(u[2], u[3]); - s[2] = _mm_packs_epi32(u[4], u[5]); - s[3] = _mm_packs_epi32(u[6], u[7]); - s[4] = _mm_packs_epi32(u[8], u[9]); - s[5] = _mm_packs_epi32(u[10], u[11]); - s[6] = _mm_packs_epi32(u[12], u[13]); - s[7] = _mm_packs_epi32(u[14], u[15]); - s[8] = _mm_packs_epi32(u[16], u[17]); - s[9] = _mm_packs_epi32(u[18], u[19]); - s[10] = _mm_packs_epi32(u[20], u[21]); - s[11] = _mm_packs_epi32(u[22], u[23]); - s[12] = _mm_packs_epi32(u[24], u[25]); - s[13] = _mm_packs_epi32(u[26], u[27]); - s[14] = _mm_packs_epi32(u[28], u[29]); - s[15] = _mm_packs_epi32(u[30], u[31]); - - // stage 2 - u[0] = _mm_unpacklo_epi16(s[8], s[9]); - u[1] = _mm_unpackhi_epi16(s[8], s[9]); - u[2] = _mm_unpacklo_epi16(s[10], s[11]); - u[3] = _mm_unpackhi_epi16(s[10], s[11]); - u[4] = _mm_unpacklo_epi16(s[12], s[13]); - u[5] = _mm_unpackhi_epi16(s[12], s[13]); - u[6] = _mm_unpacklo_epi16(s[14], s[15]); - u[7] = _mm_unpackhi_epi16(s[14], s[15]); - - v[0] = _mm_madd_epi16(u[0], k__cospi_p04_p28); - v[1] = _mm_madd_epi16(u[1], k__cospi_p04_p28); - v[2] = _mm_madd_epi16(u[0], k__cospi_p28_m04); - v[3] = _mm_madd_epi16(u[1], k__cospi_p28_m04); - v[4] = _mm_madd_epi16(u[2], k__cospi_p20_p12); - v[5] = _mm_madd_epi16(u[3], k__cospi_p20_p12); - v[6] = _mm_madd_epi16(u[2], k__cospi_p12_m20); - v[7] = _mm_madd_epi16(u[3], k__cospi_p12_m20); - v[8] = _mm_madd_epi16(u[4], k__cospi_m28_p04); - v[9] = _mm_madd_epi16(u[5], k__cospi_m28_p04); - v[10] = _mm_madd_epi16(u[4], k__cospi_p04_p28); - v[11] = _mm_madd_epi16(u[5], k__cospi_p04_p28); - v[12] = _mm_madd_epi16(u[6], k__cospi_m12_p20); - v[13] = _mm_madd_epi16(u[7], k__cospi_m12_p20); - v[14] = _mm_madd_epi16(u[6], k__cospi_p20_p12); - v[15] = _mm_madd_epi16(u[7], k__cospi_p20_p12); - - u[0] = _mm_add_epi32(v[0], v[8]); - u[1] = _mm_add_epi32(v[1], v[9]); - u[2] = _mm_add_epi32(v[2], v[10]); - u[3] = _mm_add_epi32(v[3], v[11]); - u[4] = _mm_add_epi32(v[4], v[12]); - u[5] = _mm_add_epi32(v[5], v[13]); - u[6] = _mm_add_epi32(v[6], v[14]); - u[7] = _mm_add_epi32(v[7], v[15]); - u[8] = _mm_sub_epi32(v[0], v[8]); - u[9] = _mm_sub_epi32(v[1], v[9]); - u[10] = _mm_sub_epi32(v[2], v[10]); - u[11] = _mm_sub_epi32(v[3], v[11]); - u[12] = _mm_sub_epi32(v[4], v[12]); - u[13] = _mm_sub_epi32(v[5], v[13]); - u[14] = _mm_sub_epi32(v[6], v[14]); - u[15] = _mm_sub_epi32(v[7], v[15]); - - v[0] = _mm_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm_add_epi32(u[3], k__DCT_CONST_ROUNDING); - v[4] = _mm_add_epi32(u[4], k__DCT_CONST_ROUNDING); - v[5] = _mm_add_epi32(u[5], k__DCT_CONST_ROUNDING); - v[6] = _mm_add_epi32(u[6], k__DCT_CONST_ROUNDING); - v[7] = _mm_add_epi32(u[7], k__DCT_CONST_ROUNDING); - v[8] = _mm_add_epi32(u[8], k__DCT_CONST_ROUNDING); - v[9] = _mm_add_epi32(u[9], k__DCT_CONST_ROUNDING); - v[10] = _mm_add_epi32(u[10], k__DCT_CONST_ROUNDING); - v[11] = _mm_add_epi32(u[11], k__DCT_CONST_ROUNDING); - v[12] = _mm_add_epi32(u[12], k__DCT_CONST_ROUNDING); - v[13] = _mm_add_epi32(u[13], k__DCT_CONST_ROUNDING); - v[14] = _mm_add_epi32(u[14], k__DCT_CONST_ROUNDING); - v[15] = _mm_add_epi32(u[15], k__DCT_CONST_ROUNDING); - - u[0] = _mm_srai_epi32(v[0], DCT_CONST_BITS); - u[1] = _mm_srai_epi32(v[1], DCT_CONST_BITS); - u[2] = _mm_srai_epi32(v[2], DCT_CONST_BITS); - u[3] = _mm_srai_epi32(v[3], DCT_CONST_BITS); - u[4] = _mm_srai_epi32(v[4], DCT_CONST_BITS); - u[5] = _mm_srai_epi32(v[5], DCT_CONST_BITS); - u[6] = _mm_srai_epi32(v[6], DCT_CONST_BITS); - u[7] = _mm_srai_epi32(v[7], DCT_CONST_BITS); - u[8] = _mm_srai_epi32(v[8], DCT_CONST_BITS); - u[9] = _mm_srai_epi32(v[9], DCT_CONST_BITS); - u[10] = _mm_srai_epi32(v[10], DCT_CONST_BITS); - u[11] = _mm_srai_epi32(v[11], DCT_CONST_BITS); - u[12] = _mm_srai_epi32(v[12], DCT_CONST_BITS); - u[13] = _mm_srai_epi32(v[13], DCT_CONST_BITS); - u[14] = _mm_srai_epi32(v[14], DCT_CONST_BITS); - u[15] = _mm_srai_epi32(v[15], DCT_CONST_BITS); - - x[0] = _mm_add_epi16(s[0], s[4]); - x[1] = _mm_add_epi16(s[1], s[5]); - x[2] = _mm_add_epi16(s[2], s[6]); - x[3] = _mm_add_epi16(s[3], s[7]); - x[4] = _mm_sub_epi16(s[0], s[4]); - x[5] = _mm_sub_epi16(s[1], s[5]); - x[6] = _mm_sub_epi16(s[2], s[6]); - x[7] = _mm_sub_epi16(s[3], s[7]); - x[8] = _mm_packs_epi32(u[0], u[1]); - x[9] = _mm_packs_epi32(u[2], u[3]); - x[10] = _mm_packs_epi32(u[4], u[5]); - x[11] = _mm_packs_epi32(u[6], u[7]); - x[12] = _mm_packs_epi32(u[8], u[9]); - x[13] = _mm_packs_epi32(u[10], u[11]); - x[14] = _mm_packs_epi32(u[12], u[13]); - x[15] = _mm_packs_epi32(u[14], u[15]); - - // stage 3 - u[0] = _mm_unpacklo_epi16(x[4], x[5]); - u[1] = _mm_unpackhi_epi16(x[4], x[5]); - u[2] = _mm_unpacklo_epi16(x[6], x[7]); - u[3] = _mm_unpackhi_epi16(x[6], x[7]); - u[4] = _mm_unpacklo_epi16(x[12], x[13]); - u[5] = _mm_unpackhi_epi16(x[12], x[13]); - u[6] = _mm_unpacklo_epi16(x[14], x[15]); - u[7] = _mm_unpackhi_epi16(x[14], x[15]); - - v[0] = _mm_madd_epi16(u[0], k__cospi_p08_p24); - v[1] = _mm_madd_epi16(u[1], k__cospi_p08_p24); - v[2] = _mm_madd_epi16(u[0], k__cospi_p24_m08); - v[3] = _mm_madd_epi16(u[1], k__cospi_p24_m08); - v[4] = _mm_madd_epi16(u[2], k__cospi_m24_p08); - v[5] = _mm_madd_epi16(u[3], k__cospi_m24_p08); - v[6] = _mm_madd_epi16(u[2], k__cospi_p08_p24); - v[7] = _mm_madd_epi16(u[3], k__cospi_p08_p24); - v[8] = _mm_madd_epi16(u[4], k__cospi_p08_p24); - v[9] = _mm_madd_epi16(u[5], k__cospi_p08_p24); - v[10] = _mm_madd_epi16(u[4], k__cospi_p24_m08); - v[11] = _mm_madd_epi16(u[5], k__cospi_p24_m08); - v[12] = _mm_madd_epi16(u[6], k__cospi_m24_p08); - v[13] = _mm_madd_epi16(u[7], k__cospi_m24_p08); - v[14] = _mm_madd_epi16(u[6], k__cospi_p08_p24); - v[15] = _mm_madd_epi16(u[7], k__cospi_p08_p24); - - u[0] = _mm_add_epi32(v[0], v[4]); - u[1] = _mm_add_epi32(v[1], v[5]); - u[2] = _mm_add_epi32(v[2], v[6]); - u[3] = _mm_add_epi32(v[3], v[7]); - u[4] = _mm_sub_epi32(v[0], v[4]); - u[5] = _mm_sub_epi32(v[1], v[5]); - u[6] = _mm_sub_epi32(v[2], v[6]); - u[7] = _mm_sub_epi32(v[3], v[7]); - u[8] = _mm_add_epi32(v[8], v[12]); - u[9] = _mm_add_epi32(v[9], v[13]); - u[10] = _mm_add_epi32(v[10], v[14]); - u[11] = _mm_add_epi32(v[11], v[15]); - u[12] = _mm_sub_epi32(v[8], v[12]); - u[13] = _mm_sub_epi32(v[9], v[13]); - u[14] = _mm_sub_epi32(v[10], v[14]); - u[15] = _mm_sub_epi32(v[11], v[15]); - - u[0] = _mm_add_epi32(u[0], k__DCT_CONST_ROUNDING); - u[1] = _mm_add_epi32(u[1], k__DCT_CONST_ROUNDING); - u[2] = _mm_add_epi32(u[2], k__DCT_CONST_ROUNDING); - u[3] = _mm_add_epi32(u[3], k__DCT_CONST_ROUNDING); - u[4] = _mm_add_epi32(u[4], k__DCT_CONST_ROUNDING); - u[5] = _mm_add_epi32(u[5], k__DCT_CONST_ROUNDING); - u[6] = _mm_add_epi32(u[6], k__DCT_CONST_ROUNDING); - u[7] = _mm_add_epi32(u[7], k__DCT_CONST_ROUNDING); - u[8] = _mm_add_epi32(u[8], k__DCT_CONST_ROUNDING); - u[9] = _mm_add_epi32(u[9], k__DCT_CONST_ROUNDING); - u[10] = _mm_add_epi32(u[10], k__DCT_CONST_ROUNDING); - u[11] = _mm_add_epi32(u[11], k__DCT_CONST_ROUNDING); - u[12] = _mm_add_epi32(u[12], k__DCT_CONST_ROUNDING); - u[13] = _mm_add_epi32(u[13], k__DCT_CONST_ROUNDING); - u[14] = _mm_add_epi32(u[14], k__DCT_CONST_ROUNDING); - u[15] = _mm_add_epi32(u[15], k__DCT_CONST_ROUNDING); - - v[0] = _mm_srai_epi32(u[0], DCT_CONST_BITS); - v[1] = _mm_srai_epi32(u[1], DCT_CONST_BITS); - v[2] = _mm_srai_epi32(u[2], DCT_CONST_BITS); - v[3] = _mm_srai_epi32(u[3], DCT_CONST_BITS); - v[4] = _mm_srai_epi32(u[4], DCT_CONST_BITS); - v[5] = _mm_srai_epi32(u[5], DCT_CONST_BITS); - v[6] = _mm_srai_epi32(u[6], DCT_CONST_BITS); - v[7] = _mm_srai_epi32(u[7], DCT_CONST_BITS); - v[8] = _mm_srai_epi32(u[8], DCT_CONST_BITS); - v[9] = _mm_srai_epi32(u[9], DCT_CONST_BITS); - v[10] = _mm_srai_epi32(u[10], DCT_CONST_BITS); - v[11] = _mm_srai_epi32(u[11], DCT_CONST_BITS); - v[12] = _mm_srai_epi32(u[12], DCT_CONST_BITS); - v[13] = _mm_srai_epi32(u[13], DCT_CONST_BITS); - v[14] = _mm_srai_epi32(u[14], DCT_CONST_BITS); - v[15] = _mm_srai_epi32(u[15], DCT_CONST_BITS); - - s[0] = _mm_add_epi16(x[0], x[2]); - s[1] = _mm_add_epi16(x[1], x[3]); - s[2] = _mm_sub_epi16(x[0], x[2]); - s[3] = _mm_sub_epi16(x[1], x[3]); - s[4] = _mm_packs_epi32(v[0], v[1]); - s[5] = _mm_packs_epi32(v[2], v[3]); - s[6] = _mm_packs_epi32(v[4], v[5]); - s[7] = _mm_packs_epi32(v[6], v[7]); - s[8] = _mm_add_epi16(x[8], x[10]); - s[9] = _mm_add_epi16(x[9], x[11]); - s[10] = _mm_sub_epi16(x[8], x[10]); - s[11] = _mm_sub_epi16(x[9], x[11]); - s[12] = _mm_packs_epi32(v[8], v[9]); - s[13] = _mm_packs_epi32(v[10], v[11]); - s[14] = _mm_packs_epi32(v[12], v[13]); - s[15] = _mm_packs_epi32(v[14], v[15]); - - // stage 4 - u[0] = _mm_unpacklo_epi16(s[2], s[3]); - u[1] = _mm_unpackhi_epi16(s[2], s[3]); - u[2] = _mm_unpacklo_epi16(s[6], s[7]); - u[3] = _mm_unpackhi_epi16(s[6], s[7]); - u[4] = _mm_unpacklo_epi16(s[10], s[11]); - u[5] = _mm_unpackhi_epi16(s[10], s[11]); - u[6] = _mm_unpacklo_epi16(s[14], s[15]); - u[7] = _mm_unpackhi_epi16(s[14], s[15]); - - v[0] = _mm_madd_epi16(u[0], k__cospi_m16_m16); - v[1] = _mm_madd_epi16(u[1], k__cospi_m16_m16); - v[2] = _mm_madd_epi16(u[0], k__cospi_p16_m16); - v[3] = _mm_madd_epi16(u[1], k__cospi_p16_m16); - v[4] = _mm_madd_epi16(u[2], k__cospi_p16_p16); - v[5] = _mm_madd_epi16(u[3], k__cospi_p16_p16); - v[6] = _mm_madd_epi16(u[2], k__cospi_m16_p16); - v[7] = _mm_madd_epi16(u[3], k__cospi_m16_p16); - v[8] = _mm_madd_epi16(u[4], k__cospi_p16_p16); - v[9] = _mm_madd_epi16(u[5], k__cospi_p16_p16); - v[10] = _mm_madd_epi16(u[4], k__cospi_m16_p16); - v[11] = _mm_madd_epi16(u[5], k__cospi_m16_p16); - v[12] = _mm_madd_epi16(u[6], k__cospi_m16_m16); - v[13] = _mm_madd_epi16(u[7], k__cospi_m16_m16); - v[14] = _mm_madd_epi16(u[6], k__cospi_p16_m16); - v[15] = _mm_madd_epi16(u[7], k__cospi_p16_m16); - - u[0] = _mm_add_epi32(v[0], k__DCT_CONST_ROUNDING); - u[1] = _mm_add_epi32(v[1], k__DCT_CONST_ROUNDING); - u[2] = _mm_add_epi32(v[2], k__DCT_CONST_ROUNDING); - u[3] = _mm_add_epi32(v[3], k__DCT_CONST_ROUNDING); - u[4] = _mm_add_epi32(v[4], k__DCT_CONST_ROUNDING); - u[5] = _mm_add_epi32(v[5], k__DCT_CONST_ROUNDING); - u[6] = _mm_add_epi32(v[6], k__DCT_CONST_ROUNDING); - u[7] = _mm_add_epi32(v[7], k__DCT_CONST_ROUNDING); - u[8] = _mm_add_epi32(v[8], k__DCT_CONST_ROUNDING); - u[9] = _mm_add_epi32(v[9], k__DCT_CONST_ROUNDING); - u[10] = _mm_add_epi32(v[10], k__DCT_CONST_ROUNDING); - u[11] = _mm_add_epi32(v[11], k__DCT_CONST_ROUNDING); - u[12] = _mm_add_epi32(v[12], k__DCT_CONST_ROUNDING); - u[13] = _mm_add_epi32(v[13], k__DCT_CONST_ROUNDING); - u[14] = _mm_add_epi32(v[14], k__DCT_CONST_ROUNDING); - u[15] = _mm_add_epi32(v[15], k__DCT_CONST_ROUNDING); - - v[0] = _mm_srai_epi32(u[0], DCT_CONST_BITS); - v[1] = _mm_srai_epi32(u[1], DCT_CONST_BITS); - v[2] = _mm_srai_epi32(u[2], DCT_CONST_BITS); - v[3] = _mm_srai_epi32(u[3], DCT_CONST_BITS); - v[4] = _mm_srai_epi32(u[4], DCT_CONST_BITS); - v[5] = _mm_srai_epi32(u[5], DCT_CONST_BITS); - v[6] = _mm_srai_epi32(u[6], DCT_CONST_BITS); - v[7] = _mm_srai_epi32(u[7], DCT_CONST_BITS); - v[8] = _mm_srai_epi32(u[8], DCT_CONST_BITS); - v[9] = _mm_srai_epi32(u[9], DCT_CONST_BITS); - v[10] = _mm_srai_epi32(u[10], DCT_CONST_BITS); - v[11] = _mm_srai_epi32(u[11], DCT_CONST_BITS); - v[12] = _mm_srai_epi32(u[12], DCT_CONST_BITS); - v[13] = _mm_srai_epi32(u[13], DCT_CONST_BITS); - v[14] = _mm_srai_epi32(u[14], DCT_CONST_BITS); - v[15] = _mm_srai_epi32(u[15], DCT_CONST_BITS); - - in[0] = s[0]; - in[1] = _mm_sub_epi16(kZero, s[8]); - in[2] = s[12]; - in[3] = _mm_sub_epi16(kZero, s[4]); - in[4] = _mm_packs_epi32(v[4], v[5]); - in[5] = _mm_packs_epi32(v[12], v[13]); - in[6] = _mm_packs_epi32(v[8], v[9]); - in[7] = _mm_packs_epi32(v[0], v[1]); - in[8] = _mm_packs_epi32(v[2], v[3]); - in[9] = _mm_packs_epi32(v[10], v[11]); - in[10] = _mm_packs_epi32(v[14], v[15]); - in[11] = _mm_packs_epi32(v[6], v[7]); - in[12] = s[5]; - in[13] = _mm_sub_epi16(kZero, s[13]); - in[14] = s[9]; - in[15] = _mm_sub_epi16(kZero, s[1]); -} - -static void fdct16_sse2(__m128i *in0, __m128i *in1) { - fdct16_8col(in0); - fdct16_8col(in1); - transpose_16bit_16x16(in0, in1); -} - -static void fadst16_sse2(__m128i *in0, __m128i *in1) { - fadst16_8col(in0); - fadst16_8col(in1); - transpose_16bit_16x16(in0, in1); -} - -void vp9_fht16x16_sse2(const int16_t *input, tran_low_t *output, int stride, - int tx_type) { - __m128i in0[16], in1[16]; - - switch (tx_type) { - case DCT_DCT: vpx_fdct16x16_sse2(input, output, stride); break; - case ADST_DCT: - load_buffer_16x16(input, in0, in1, stride); - fadst16_sse2(in0, in1); - right_shift_16x16(in0, in1); - fdct16_sse2(in0, in1); - write_buffer_16x16(output, in0, in1, 16); - break; - case DCT_ADST: - load_buffer_16x16(input, in0, in1, stride); - fdct16_sse2(in0, in1); - right_shift_16x16(in0, in1); - fadst16_sse2(in0, in1); - write_buffer_16x16(output, in0, in1, 16); - break; - default: - assert(tx_type == ADST_ADST); - load_buffer_16x16(input, in0, in1, stride); - fadst16_sse2(in0, in1); - right_shift_16x16(in0, in1); - fadst16_sse2(in0, in1); - write_buffer_16x16(output, in0, in1, 16); - break; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_dct_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_dct_sse2.asm deleted file mode 100644 index 8152dce8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_dct_sse2.asm +++ /dev/null @@ -1,69 +0,0 @@ -; -; Copyright (c) 2016 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%define private_prefix vp9 - -%include "third_party/x86inc/x86inc.asm" -%include "vpx_dsp/x86/bitdepth_conversion_sse2.asm" - -SECTION .text - -%macro TRANSFORM_COLS 0 - paddw m0, m1 - movq m4, m0 - psubw m3, m2 - psubw m4, m3 - psraw m4, 1 - movq m5, m4 - psubw m5, m1 ;b1 - psubw m4, m2 ;c1 - psubw m0, m4 - paddw m3, m5 - ; m0 a0 - SWAP 1, 4 ; m1 c1 - SWAP 2, 3 ; m2 d1 - SWAP 3, 5 ; m3 b1 -%endmacro - -%macro TRANSPOSE_4X4 0 - ; 00 01 02 03 - ; 10 11 12 13 - ; 20 21 22 23 - ; 30 31 32 33 - punpcklwd m0, m1 ; 00 10 01 11 02 12 03 13 - punpcklwd m2, m3 ; 20 30 21 31 22 32 23 33 - mova m1, m0 - punpckldq m0, m2 ; 00 10 20 30 01 11 21 31 - punpckhdq m1, m2 ; 02 12 22 32 03 13 23 33 -%endmacro - -INIT_XMM sse2 -cglobal fwht4x4, 3, 4, 8, input, output, stride - lea r3q, [inputq + strideq*4] - movq m0, [inputq] ;a1 - movq m1, [inputq + strideq*2] ;b1 - movq m2, [r3q] ;c1 - movq m3, [r3q + strideq*2] ;d1 - - TRANSFORM_COLS - TRANSPOSE_4X4 - SWAP 1, 2 - psrldq m1, m0, 8 - psrldq m3, m2, 8 - TRANSFORM_COLS - TRANSPOSE_4X4 - - psllw m0, 2 - psllw m1, 2 - - STORE_TRAN_LOW 0, outputq, 0, 2, 3 - STORE_TRAN_LOW 1, outputq, 8, 2, 3 - - RET diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_denoiser_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_denoiser_sse2.c deleted file mode 100644 index 5930bf49..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_denoiser_sse2.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vp9_rtcd.h" - -#include "vpx/vpx_integer.h" -#include "vp9/common/vp9_reconinter.h" -#include "vp9/encoder/vp9_context_tree.h" -#include "vp9/encoder/vp9_denoiser.h" -#include "vpx_mem/vpx_mem.h" - -// Compute the sum of all pixel differences of this MB. -static INLINE int sum_diff_16x1(__m128i acc_diff) { - const __m128i k_1 = _mm_set1_epi16(1); - const __m128i acc_diff_lo = - _mm_srai_epi16(_mm_unpacklo_epi8(acc_diff, acc_diff), 8); - const __m128i acc_diff_hi = - _mm_srai_epi16(_mm_unpackhi_epi8(acc_diff, acc_diff), 8); - const __m128i acc_diff_16 = _mm_add_epi16(acc_diff_lo, acc_diff_hi); - const __m128i hg_fe_dc_ba = _mm_madd_epi16(acc_diff_16, k_1); - const __m128i hgfe_dcba = - _mm_add_epi32(hg_fe_dc_ba, _mm_srli_si128(hg_fe_dc_ba, 8)); - const __m128i hgfedcba = - _mm_add_epi32(hgfe_dcba, _mm_srli_si128(hgfe_dcba, 4)); - return _mm_cvtsi128_si32(hgfedcba); -} - -// Denoise a 16x1 vector. -static INLINE __m128i vp9_denoiser_16x1_sse2( - const uint8_t *sig, const uint8_t *mc_running_avg_y, uint8_t *running_avg_y, - const __m128i *k_0, const __m128i *k_4, const __m128i *k_8, - const __m128i *k_16, const __m128i *l3, const __m128i *l32, - const __m128i *l21, __m128i acc_diff) { - // Calculate differences - const __m128i v_sig = _mm_loadu_si128((const __m128i *)(&sig[0])); - const __m128i v_mc_running_avg_y = - _mm_loadu_si128((const __m128i *)(&mc_running_avg_y[0])); - __m128i v_running_avg_y; - const __m128i pdiff = _mm_subs_epu8(v_mc_running_avg_y, v_sig); - const __m128i ndiff = _mm_subs_epu8(v_sig, v_mc_running_avg_y); - // Obtain the sign. FF if diff is negative. - const __m128i diff_sign = _mm_cmpeq_epi8(pdiff, *k_0); - // Clamp absolute difference to 16 to be used to get mask. Doing this - // allows us to use _mm_cmpgt_epi8, which operates on signed byte. - const __m128i clamped_absdiff = - _mm_min_epu8(_mm_or_si128(pdiff, ndiff), *k_16); - // Get masks for l2 l1 and l0 adjustments. - const __m128i mask2 = _mm_cmpgt_epi8(*k_16, clamped_absdiff); - const __m128i mask1 = _mm_cmpgt_epi8(*k_8, clamped_absdiff); - const __m128i mask0 = _mm_cmpgt_epi8(*k_4, clamped_absdiff); - // Get adjustments for l2, l1, and l0. - __m128i adj2 = _mm_and_si128(mask2, *l32); - const __m128i adj1 = _mm_and_si128(mask1, *l21); - const __m128i adj0 = _mm_and_si128(mask0, clamped_absdiff); - __m128i adj, padj, nadj; - - // Combine the adjustments and get absolute adjustments. - adj2 = _mm_add_epi8(adj2, adj1); - adj = _mm_sub_epi8(*l3, adj2); - adj = _mm_andnot_si128(mask0, adj); - adj = _mm_or_si128(adj, adj0); - - // Restore the sign and get positive and negative adjustments. - padj = _mm_andnot_si128(diff_sign, adj); - nadj = _mm_and_si128(diff_sign, adj); - - // Calculate filtered value. - v_running_avg_y = _mm_adds_epu8(v_sig, padj); - v_running_avg_y = _mm_subs_epu8(v_running_avg_y, nadj); - _mm_storeu_si128((__m128i *)running_avg_y, v_running_avg_y); - - // Adjustments <=7, and each element in acc_diff can fit in signed - // char. - acc_diff = _mm_adds_epi8(acc_diff, padj); - acc_diff = _mm_subs_epi8(acc_diff, nadj); - return acc_diff; -} - -// Denoise a 16x1 vector with a weaker filter. -static INLINE __m128i vp9_denoiser_adj_16x1_sse2( - const uint8_t *sig, const uint8_t *mc_running_avg_y, uint8_t *running_avg_y, - const __m128i k_0, const __m128i k_delta, __m128i acc_diff) { - __m128i v_running_avg_y = _mm_loadu_si128((__m128i *)(&running_avg_y[0])); - // Calculate differences. - const __m128i v_sig = _mm_loadu_si128((const __m128i *)(&sig[0])); - const __m128i v_mc_running_avg_y = - _mm_loadu_si128((const __m128i *)(&mc_running_avg_y[0])); - const __m128i pdiff = _mm_subs_epu8(v_mc_running_avg_y, v_sig); - const __m128i ndiff = _mm_subs_epu8(v_sig, v_mc_running_avg_y); - // Obtain the sign. FF if diff is negative. - const __m128i diff_sign = _mm_cmpeq_epi8(pdiff, k_0); - // Clamp absolute difference to delta to get the adjustment. - const __m128i adj = _mm_min_epu8(_mm_or_si128(pdiff, ndiff), k_delta); - // Restore the sign and get positive and negative adjustments. - __m128i padj, nadj; - padj = _mm_andnot_si128(diff_sign, adj); - nadj = _mm_and_si128(diff_sign, adj); - // Calculate filtered value. - v_running_avg_y = _mm_subs_epu8(v_running_avg_y, padj); - v_running_avg_y = _mm_adds_epu8(v_running_avg_y, nadj); - _mm_storeu_si128((__m128i *)running_avg_y, v_running_avg_y); - - // Accumulate the adjustments. - acc_diff = _mm_subs_epi8(acc_diff, padj); - acc_diff = _mm_adds_epi8(acc_diff, nadj); - return acc_diff; -} - -// Denoise 8x8 and 8x16 blocks. -static int vp9_denoiser_NxM_sse2_small(const uint8_t *sig, int sig_stride, - const uint8_t *mc_running_avg_y, - int mc_avg_y_stride, - uint8_t *running_avg_y, int avg_y_stride, - int increase_denoising, BLOCK_SIZE bs, - int motion_magnitude, int width) { - int sum_diff_thresh, r, sum_diff = 0; - const int shift_inc = - (increase_denoising && motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) - ? 1 - : 0; - uint8_t sig_buffer[8][16], mc_running_buffer[8][16], running_buffer[8][16]; - __m128i acc_diff = _mm_setzero_si128(); - const __m128i k_0 = _mm_setzero_si128(); - const __m128i k_4 = _mm_set1_epi8(4 + shift_inc); - const __m128i k_8 = _mm_set1_epi8(8); - const __m128i k_16 = _mm_set1_epi8(16); - // Modify each level's adjustment according to motion_magnitude. - const __m128i l3 = _mm_set1_epi8( - (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) ? 7 + shift_inc : 6); - // Difference between level 3 and level 2 is 2. - const __m128i l32 = _mm_set1_epi8(2); - // Difference between level 2 and level 1 is 1. - const __m128i l21 = _mm_set1_epi8(1); - const int b_height = (4 << b_height_log2_lookup[bs]) >> 1; - - for (r = 0; r < b_height; ++r) { - memcpy(sig_buffer[r], sig, width); - memcpy(sig_buffer[r] + width, sig + sig_stride, width); - memcpy(mc_running_buffer[r], mc_running_avg_y, width); - memcpy(mc_running_buffer[r] + width, mc_running_avg_y + mc_avg_y_stride, - width); - memcpy(running_buffer[r], running_avg_y, width); - memcpy(running_buffer[r] + width, running_avg_y + avg_y_stride, width); - acc_diff = vp9_denoiser_16x1_sse2(sig_buffer[r], mc_running_buffer[r], - running_buffer[r], &k_0, &k_4, &k_8, - &k_16, &l3, &l32, &l21, acc_diff); - memcpy(running_avg_y, running_buffer[r], width); - memcpy(running_avg_y + avg_y_stride, running_buffer[r] + width, width); - // Update pointers for next iteration. - sig += (sig_stride << 1); - mc_running_avg_y += (mc_avg_y_stride << 1); - running_avg_y += (avg_y_stride << 1); - } - - { - sum_diff = sum_diff_16x1(acc_diff); - sum_diff_thresh = total_adj_strong_thresh(bs, increase_denoising); - if (abs(sum_diff) > sum_diff_thresh) { - // Before returning to copy the block (i.e., apply no denoising), - // check if we can still apply some (weaker) temporal filtering to - // this block, that would otherwise not be denoised at all. Simplest - // is to apply an additional adjustment to running_avg_y to bring it - // closer to sig. The adjustment is capped by a maximum delta, and - // chosen such that in most cases the resulting sum_diff will be - // within the acceptable range given by sum_diff_thresh. - - // The delta is set by the excess of absolute pixel diff over the - // threshold. - const int delta = - ((abs(sum_diff) - sum_diff_thresh) >> num_pels_log2_lookup[bs]) + 1; - // Only apply the adjustment for max delta up to 3. - if (delta < 4) { - const __m128i k_delta = _mm_set1_epi8(delta); - running_avg_y -= avg_y_stride * (b_height << 1); - for (r = 0; r < b_height; ++r) { - acc_diff = vp9_denoiser_adj_16x1_sse2( - sig_buffer[r], mc_running_buffer[r], running_buffer[r], k_0, - k_delta, acc_diff); - memcpy(running_avg_y, running_buffer[r], width); - memcpy(running_avg_y + avg_y_stride, running_buffer[r] + width, - width); - // Update pointers for next iteration. - running_avg_y += (avg_y_stride << 1); - } - sum_diff = sum_diff_16x1(acc_diff); - if (abs(sum_diff) > sum_diff_thresh) { - return COPY_BLOCK; - } - } else { - return COPY_BLOCK; - } - } - } - return FILTER_BLOCK; -} - -// Denoise 16x16, 16x32, 32x16, 32x32, 32x64, 64x32 and 64x64 blocks. -static int vp9_denoiser_NxM_sse2_big(const uint8_t *sig, int sig_stride, - const uint8_t *mc_running_avg_y, - int mc_avg_y_stride, - uint8_t *running_avg_y, int avg_y_stride, - int increase_denoising, BLOCK_SIZE bs, - int motion_magnitude) { - int sum_diff_thresh, r, c, sum_diff = 0; - const int shift_inc = - (increase_denoising && motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) - ? 1 - : 0; - __m128i acc_diff[4][4]; - const __m128i k_0 = _mm_setzero_si128(); - const __m128i k_4 = _mm_set1_epi8(4 + shift_inc); - const __m128i k_8 = _mm_set1_epi8(8); - const __m128i k_16 = _mm_set1_epi8(16); - // Modify each level's adjustment according to motion_magnitude. - const __m128i l3 = _mm_set1_epi8( - (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) ? 7 + shift_inc : 6); - // Difference between level 3 and level 2 is 2. - const __m128i l32 = _mm_set1_epi8(2); - // Difference between level 2 and level 1 is 1. - const __m128i l21 = _mm_set1_epi8(1); - const int b_width = (4 << b_width_log2_lookup[bs]); - const int b_height = (4 << b_height_log2_lookup[bs]); - const int b_width_shift4 = b_width >> 4; - - for (r = 0; r < 4; ++r) { - for (c = 0; c < b_width_shift4; ++c) { - acc_diff[c][r] = _mm_setzero_si128(); - } - } - - for (r = 0; r < b_height; ++r) { - for (c = 0; c < b_width_shift4; ++c) { - acc_diff[c][r >> 4] = vp9_denoiser_16x1_sse2( - sig, mc_running_avg_y, running_avg_y, &k_0, &k_4, &k_8, &k_16, &l3, - &l32, &l21, acc_diff[c][r >> 4]); - // Update pointers for next iteration. - sig += 16; - mc_running_avg_y += 16; - running_avg_y += 16; - } - - if ((r & 0xf) == 0xf || (bs == BLOCK_16X8 && r == 7)) { - for (c = 0; c < b_width_shift4; ++c) { - sum_diff += sum_diff_16x1(acc_diff[c][r >> 4]); - } - } - - // Update pointers for next iteration. - sig = sig - b_width + sig_stride; - mc_running_avg_y = mc_running_avg_y - b_width + mc_avg_y_stride; - running_avg_y = running_avg_y - b_width + avg_y_stride; - } - - { - sum_diff_thresh = total_adj_strong_thresh(bs, increase_denoising); - if (abs(sum_diff) > sum_diff_thresh) { - const int delta = - ((abs(sum_diff) - sum_diff_thresh) >> num_pels_log2_lookup[bs]) + 1; - - // Only apply the adjustment for max delta up to 3. - if (delta < 4) { - const __m128i k_delta = _mm_set1_epi8(delta); - sig -= sig_stride * b_height; - mc_running_avg_y -= mc_avg_y_stride * b_height; - running_avg_y -= avg_y_stride * b_height; - sum_diff = 0; - for (r = 0; r < b_height; ++r) { - for (c = 0; c < b_width_shift4; ++c) { - acc_diff[c][r >> 4] = - vp9_denoiser_adj_16x1_sse2(sig, mc_running_avg_y, running_avg_y, - k_0, k_delta, acc_diff[c][r >> 4]); - // Update pointers for next iteration. - sig += 16; - mc_running_avg_y += 16; - running_avg_y += 16; - } - - if ((r & 0xf) == 0xf || (bs == BLOCK_16X8 && r == 7)) { - for (c = 0; c < b_width_shift4; ++c) { - sum_diff += sum_diff_16x1(acc_diff[c][r >> 4]); - } - } - sig = sig - b_width + sig_stride; - mc_running_avg_y = mc_running_avg_y - b_width + mc_avg_y_stride; - running_avg_y = running_avg_y - b_width + avg_y_stride; - } - if (abs(sum_diff) > sum_diff_thresh) { - return COPY_BLOCK; - } - } else { - return COPY_BLOCK; - } - } - } - return FILTER_BLOCK; -} - -int vp9_denoiser_filter_sse2(const uint8_t *sig, int sig_stride, - const uint8_t *mc_avg, int mc_avg_stride, - uint8_t *avg, int avg_stride, - int increase_denoising, BLOCK_SIZE bs, - int motion_magnitude) { - // Rank by frequency of the block type to have an early termination. - if (bs == BLOCK_16X16 || bs == BLOCK_32X32 || bs == BLOCK_64X64 || - bs == BLOCK_16X32 || bs == BLOCK_16X8 || bs == BLOCK_32X16 || - bs == BLOCK_32X64 || bs == BLOCK_64X32) { - return vp9_denoiser_NxM_sse2_big(sig, sig_stride, mc_avg, mc_avg_stride, - avg, avg_stride, increase_denoising, bs, - motion_magnitude); - } else if (bs == BLOCK_8X8 || bs == BLOCK_8X16) { - return vp9_denoiser_NxM_sse2_small(sig, sig_stride, mc_avg, mc_avg_stride, - avg, avg_stride, increase_denoising, bs, - motion_magnitude, 8); - } else { - return COPY_BLOCK; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_error_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_error_avx2.c deleted file mode 100644 index 99fef31d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_error_avx2.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vp9_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/x86/bitdepth_conversion_avx2.h" - -int64_t vp9_block_error_avx2(const tran_low_t *coeff, const tran_low_t *dqcoeff, - intptr_t block_size, int64_t *ssz) { - __m256i sse_256, ssz_256; - __m256i exp_dqcoeff_lo, exp_dqcoeff_hi, exp_coeff_lo, exp_coeff_hi; - __m256i sse_hi, ssz_hi; - __m128i sse_128, ssz_128; - int64_t sse; - const __m256i zero = _mm256_setzero_si256(); - - // If the block size is 16 then the results will fit in 32 bits. - if (block_size == 16) { - __m256i coeff_256, dqcoeff_256, coeff_hi, dqcoeff_hi; - // Load 16 elements for coeff and dqcoeff. - coeff_256 = load_tran_low(coeff); - dqcoeff_256 = load_tran_low(dqcoeff); - // dqcoeff - coeff - dqcoeff_256 = _mm256_sub_epi16(dqcoeff_256, coeff_256); - // madd (dqcoeff - coeff) - dqcoeff_256 = _mm256_madd_epi16(dqcoeff_256, dqcoeff_256); - // madd coeff - coeff_256 = _mm256_madd_epi16(coeff_256, coeff_256); - // Save the higher 64 bit of each 128 bit lane. - dqcoeff_hi = _mm256_srli_si256(dqcoeff_256, 8); - coeff_hi = _mm256_srli_si256(coeff_256, 8); - // Add the higher 64 bit to the low 64 bit. - dqcoeff_256 = _mm256_add_epi32(dqcoeff_256, dqcoeff_hi); - coeff_256 = _mm256_add_epi32(coeff_256, coeff_hi); - // Expand each double word in the lower 64 bits to quad word. - sse_256 = _mm256_unpacklo_epi32(dqcoeff_256, zero); - ssz_256 = _mm256_unpacklo_epi32(coeff_256, zero); - } else { - int i; - assert(block_size % 32 == 0); - sse_256 = zero; - ssz_256 = zero; - - for (i = 0; i < block_size; i += 32) { - __m256i coeff_0, coeff_1, dqcoeff_0, dqcoeff_1; - // Load 32 elements for coeff and dqcoeff. - coeff_0 = load_tran_low(coeff + i); - dqcoeff_0 = load_tran_low(dqcoeff + i); - coeff_1 = load_tran_low(coeff + i + 16); - dqcoeff_1 = load_tran_low(dqcoeff + i + 16); - // dqcoeff - coeff - dqcoeff_0 = _mm256_sub_epi16(dqcoeff_0, coeff_0); - dqcoeff_1 = _mm256_sub_epi16(dqcoeff_1, coeff_1); - // madd (dqcoeff - coeff) - dqcoeff_0 = _mm256_madd_epi16(dqcoeff_0, dqcoeff_0); - dqcoeff_1 = _mm256_madd_epi16(dqcoeff_1, dqcoeff_1); - // madd coeff - coeff_0 = _mm256_madd_epi16(coeff_0, coeff_0); - coeff_1 = _mm256_madd_epi16(coeff_1, coeff_1); - // Add the first madd (dqcoeff - coeff) with the second. - dqcoeff_0 = _mm256_add_epi32(dqcoeff_0, dqcoeff_1); - // Add the first madd (coeff) with the second. - coeff_0 = _mm256_add_epi32(coeff_0, coeff_1); - // Expand each double word of madd (dqcoeff - coeff) to quad word. - exp_dqcoeff_lo = _mm256_unpacklo_epi32(dqcoeff_0, zero); - exp_dqcoeff_hi = _mm256_unpackhi_epi32(dqcoeff_0, zero); - // expand each double word of madd (coeff) to quad word - exp_coeff_lo = _mm256_unpacklo_epi32(coeff_0, zero); - exp_coeff_hi = _mm256_unpackhi_epi32(coeff_0, zero); - // Add each quad word of madd (dqcoeff - coeff) and madd (coeff). - sse_256 = _mm256_add_epi64(sse_256, exp_dqcoeff_lo); - ssz_256 = _mm256_add_epi64(ssz_256, exp_coeff_lo); - sse_256 = _mm256_add_epi64(sse_256, exp_dqcoeff_hi); - ssz_256 = _mm256_add_epi64(ssz_256, exp_coeff_hi); - } - } - // Save the higher 64 bit of each 128 bit lane. - sse_hi = _mm256_srli_si256(sse_256, 8); - ssz_hi = _mm256_srli_si256(ssz_256, 8); - // Add the higher 64 bit to the low 64 bit. - sse_256 = _mm256_add_epi64(sse_256, sse_hi); - ssz_256 = _mm256_add_epi64(ssz_256, ssz_hi); - - // Add each 64 bit from each of the 128 bit lane of the 256 bit. - sse_128 = _mm_add_epi64(_mm256_castsi256_si128(sse_256), - _mm256_extractf128_si256(sse_256, 1)); - - ssz_128 = _mm_add_epi64(_mm256_castsi256_si128(ssz_256), - _mm256_extractf128_si256(ssz_256, 1)); - - // Store the results. - _mm_storel_epi64((__m128i *)(&sse), sse_128); - - _mm_storel_epi64((__m128i *)(ssz), ssz_128); - return sse; -} - -int64_t vp9_block_error_fp_avx2(const tran_low_t *coeff, - const tran_low_t *dqcoeff, int block_size) { - int i; - const __m256i zero = _mm256_setzero_si256(); - __m256i sse_256 = zero; - __m256i sse_hi; - __m128i sse_128; - int64_t sse; - - if (block_size == 16) { - // Load 16 elements for coeff and dqcoeff. - const __m256i _coeff = load_tran_low(coeff); - const __m256i _dqcoeff = load_tran_low(dqcoeff); - // dqcoeff - coeff - const __m256i diff = _mm256_sub_epi16(_dqcoeff, _coeff); - // madd (dqcoeff - coeff) - const __m256i error_lo = _mm256_madd_epi16(diff, diff); - // Save the higher 64 bit of each 128 bit lane. - const __m256i error_hi = _mm256_srli_si256(error_lo, 8); - // Add the higher 64 bit to the low 64 bit. - const __m256i error = _mm256_add_epi32(error_lo, error_hi); - // Expand each double word in the lower 64 bits to quad word. - sse_256 = _mm256_unpacklo_epi32(error, zero); - } else { - for (i = 0; i < block_size; i += 16) { - // Load 16 elements for coeff and dqcoeff. - const __m256i _coeff = load_tran_low(coeff); - const __m256i _dqcoeff = load_tran_low(dqcoeff); - const __m256i diff = _mm256_sub_epi16(_dqcoeff, _coeff); - const __m256i error = _mm256_madd_epi16(diff, diff); - // Expand each double word of madd (dqcoeff - coeff) to quad word. - const __m256i exp_error_lo = _mm256_unpacklo_epi32(error, zero); - const __m256i exp_error_hi = _mm256_unpackhi_epi32(error, zero); - // Add each quad word of madd (dqcoeff - coeff). - sse_256 = _mm256_add_epi64(sse_256, exp_error_lo); - sse_256 = _mm256_add_epi64(sse_256, exp_error_hi); - coeff += 16; - dqcoeff += 16; - } - } - // Save the higher 64 bit of each 128 bit lane. - sse_hi = _mm256_srli_si256(sse_256, 8); - // Add the higher 64 bit to the low 64 bit. - sse_256 = _mm256_add_epi64(sse_256, sse_hi); - - // Add each 64 bit from each of the 128 bit lane of the 256 bit. - sse_128 = _mm_add_epi64(_mm256_castsi256_si128(sse_256), - _mm256_extractf128_si256(sse_256, 1)); - - // Store the results. - _mm_storel_epi64((__m128i *)&sse, sse_128); - return sse; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_error_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_error_sse2.asm deleted file mode 100644 index 7beec130..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_error_sse2.asm +++ /dev/null @@ -1,115 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%define private_prefix vp9 - -%include "third_party/x86inc/x86inc.asm" -%include "vpx_dsp/x86/bitdepth_conversion_sse2.asm" - -SECTION .text - -; int64_t vp9_block_error(int16_t *coeff, int16_t *dqcoeff, intptr_t block_size, -; int64_t *ssz) - -INIT_XMM sse2 -cglobal block_error, 3, 3, 8, uqc, dqc, size, ssz - pxor m4, m4 ; sse accumulator - pxor m6, m6 ; ssz accumulator - pxor m5, m5 ; dedicated zero register -.loop: - LOAD_TRAN_LOW 2, uqcq, 0 - LOAD_TRAN_LOW 0, dqcq, 0 - LOAD_TRAN_LOW 3, uqcq, 8 - LOAD_TRAN_LOW 1, dqcq, 8 - INCREMENT_ELEMENTS_TRAN_LOW uqcq, 16 - INCREMENT_ELEMENTS_TRAN_LOW dqcq, 16 - sub sizeq, 16 - psubw m0, m2 - psubw m1, m3 - ; individual errors are max. 15bit+sign, so squares are 30bit, and - ; thus the sum of 2 should fit in a 31bit integer (+ unused sign bit) - pmaddwd m0, m0 - pmaddwd m1, m1 - pmaddwd m2, m2 - pmaddwd m3, m3 - ; the sum of 2 31bit integers will fit in a 32bit unsigned integer - paddd m0, m1 - paddd m2, m3 - ; accumulate in 64bit - punpckldq m7, m0, m5 - punpckhdq m0, m5 - paddq m4, m7 - punpckldq m7, m2, m5 - paddq m4, m0 - punpckhdq m2, m5 - paddq m6, m7 - paddq m6, m2 - jg .loop - - ; accumulate horizontally and store in return value - movhlps m5, m4 - movhlps m7, m6 - paddq m4, m5 - paddq m6, m7 -%if VPX_ARCH_X86_64 - movq rax, m4 - movq [sszq], m6 -%else - mov eax, sszm - pshufd m5, m4, 0x1 - movq [eax], m6 - movd eax, m4 - movd edx, m5 -%endif - RET - -; Compute the sum of squared difference between two tran_low_t vectors. -; Vectors are converted (if necessary) to int16_t for calculations. -; int64_t vp9_block_error_fp(tran_low_t *coeff, tran_low_t *dqcoeff, -; intptr_t block_size) - -INIT_XMM sse2 -cglobal block_error_fp, 3, 3, 6, uqc, dqc, size - pxor m4, m4 ; sse accumulator - pxor m5, m5 ; dedicated zero register -.loop: - LOAD_TRAN_LOW 2, uqcq, 0 - LOAD_TRAN_LOW 0, dqcq, 0 - LOAD_TRAN_LOW 3, uqcq, 8 - LOAD_TRAN_LOW 1, dqcq, 8 - INCREMENT_ELEMENTS_TRAN_LOW uqcq, 16 - INCREMENT_ELEMENTS_TRAN_LOW dqcq, 16 - sub sizeq, 16 - psubw m0, m2 - psubw m1, m3 - ; individual errors are max. 15bit+sign, so squares are 30bit, and - ; thus the sum of 2 should fit in a 31bit integer (+ unused sign bit) - pmaddwd m0, m0 - pmaddwd m1, m1 - ; the sum of 2 31bit integers will fit in a 32bit unsigned integer - paddd m0, m1 - ; accumulate in 64bit - punpckldq m3, m0, m5 - punpckhdq m0, m5 - paddq m4, m3 - paddq m4, m0 - jnz .loop - - ; accumulate horizontally and store in return value - movhlps m5, m4 - paddq m4, m5 -%if VPX_ARCH_X86_64 - movq rax, m4 -%else - pshufd m5, m4, 0x1 - movd eax, m4 - movd edx, m5 -%endif - RET diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_frame_scale_ssse3.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_frame_scale_ssse3.c deleted file mode 100644 index 628dc4fe..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_frame_scale_ssse3.c +++ /dev/null @@ -1,907 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // SSSE3 - -#include "./vp9_rtcd.h" -#include "./vpx_dsp_rtcd.h" -#include "./vpx_scale_rtcd.h" -#include "vpx_dsp/x86/convolve_ssse3.h" -#include "vpx_dsp/x86/mem_sse2.h" -#include "vpx_dsp/x86/transpose_sse2.h" -#include "vpx_scale/yv12config.h" - -static INLINE __m128i scale_plane_2_to_1_phase_0_kernel( - const uint8_t *const src, const __m128i *const mask) { - const __m128i a = _mm_loadu_si128((const __m128i *)(&src[0])); - const __m128i b = _mm_loadu_si128((const __m128i *)(&src[16])); - const __m128i a_and = _mm_and_si128(a, *mask); - const __m128i b_and = _mm_and_si128(b, *mask); - return _mm_packus_epi16(a_and, b_and); -} - -static void scale_plane_2_to_1_phase_0(const uint8_t *src, - const ptrdiff_t src_stride, uint8_t *dst, - const ptrdiff_t dst_stride, - const int dst_w, const int dst_h) { - const int max_width = (dst_w + 15) & ~15; - const __m128i mask = _mm_set1_epi16(0x00FF); - int y = dst_h; - - do { - int x = max_width; - do { - const __m128i d = scale_plane_2_to_1_phase_0_kernel(src, &mask); - _mm_storeu_si128((__m128i *)dst, d); - src += 32; - dst += 16; - x -= 16; - } while (x); - src += 2 * (src_stride - max_width); - dst += dst_stride - max_width; - } while (--y); -} - -static void scale_plane_4_to_1_phase_0(const uint8_t *src, - const ptrdiff_t src_stride, uint8_t *dst, - const ptrdiff_t dst_stride, - const int dst_w, const int dst_h) { - const int max_width = (dst_w + 15) & ~15; - const __m128i mask = _mm_set1_epi32(0x000000FF); - int y = dst_h; - - do { - int x = max_width; - do { - const __m128i d0 = scale_plane_2_to_1_phase_0_kernel(&src[0], &mask); - const __m128i d1 = scale_plane_2_to_1_phase_0_kernel(&src[32], &mask); - const __m128i d2 = _mm_packus_epi16(d0, d1); - _mm_storeu_si128((__m128i *)dst, d2); - src += 64; - dst += 16; - x -= 16; - } while (x); - src += 4 * (src_stride - max_width); - dst += dst_stride - max_width; - } while (--y); -} - -static INLINE __m128i scale_plane_bilinear_kernel(const __m128i *const s, - const __m128i c0c1) { - const __m128i k_64 = _mm_set1_epi16(1 << 6); - const __m128i t0 = _mm_maddubs_epi16(s[0], c0c1); - const __m128i t1 = _mm_maddubs_epi16(s[1], c0c1); - // round and shift by 7 bit each 16 bit - const __m128i t2 = _mm_adds_epi16(t0, k_64); - const __m128i t3 = _mm_adds_epi16(t1, k_64); - const __m128i t4 = _mm_srai_epi16(t2, 7); - const __m128i t5 = _mm_srai_epi16(t3, 7); - return _mm_packus_epi16(t4, t5); -} - -static void scale_plane_2_to_1_bilinear(const uint8_t *src, - const ptrdiff_t src_stride, - uint8_t *dst, - const ptrdiff_t dst_stride, - const int dst_w, const int dst_h, - const __m128i c0c1) { - const int max_width = (dst_w + 15) & ~15; - int y = dst_h; - - do { - int x = max_width; - do { - __m128i s[2], d[2]; - - // Horizontal - // Even rows - s[0] = _mm_loadu_si128((const __m128i *)(src + 0)); - s[1] = _mm_loadu_si128((const __m128i *)(src + 16)); - d[0] = scale_plane_bilinear_kernel(s, c0c1); - - // odd rows - s[0] = _mm_loadu_si128((const __m128i *)(src + src_stride + 0)); - s[1] = _mm_loadu_si128((const __m128i *)(src + src_stride + 16)); - d[1] = scale_plane_bilinear_kernel(s, c0c1); - - // Vertical - s[0] = _mm_unpacklo_epi8(d[0], d[1]); - s[1] = _mm_unpackhi_epi8(d[0], d[1]); - d[0] = scale_plane_bilinear_kernel(s, c0c1); - - _mm_storeu_si128((__m128i *)dst, d[0]); - src += 32; - dst += 16; - x -= 16; - } while (x); - src += 2 * (src_stride - max_width); - dst += dst_stride - max_width; - } while (--y); -} - -static void scale_plane_4_to_1_bilinear(const uint8_t *src, - const ptrdiff_t src_stride, - uint8_t *dst, - const ptrdiff_t dst_stride, - const int dst_w, const int dst_h, - const __m128i c0c1) { - const int max_width = (dst_w + 15) & ~15; - int y = dst_h; - - do { - int x = max_width; - do { - __m128i s[8], d[8]; - - // Note: Using _mm_packus_epi32() in SSE4.1 could be faster. - // Here we tried to not use shuffle instructions which would be slow - // on some x86 CPUs. - - // Horizontal - // 000 001 xx xx 004 005 xx xx 008 009 xx xx 00C 00D xx xx - // 010 011 xx xx 014 015 xx xx 018 019 xx xx 01C 01D xx xx - // 020 021 xx xx 024 025 xx xx 028 029 xx xx 02C 02D xx xx - // 030 031 xx xx 034 035 xx xx 038 039 xx xx 03C 03D xx xx - // 100 101 xx xx 104 105 xx xx 108 109 xx xx 10C 10D xx xx - // 110 111 xx xx 114 115 xx xx 118 119 xx xx 11C 11D xx xx - // 120 121 xx xx 124 125 xx xx 128 129 xx xx 12C 12D xx xx - // 130 131 xx xx 134 135 xx xx 138 139 xx xx 13C 13D xx xx - s[0] = _mm_loadu_si128((const __m128i *)(&src[0])); - s[1] = _mm_loadu_si128((const __m128i *)(&src[16])); - s[2] = _mm_loadu_si128((const __m128i *)(&src[32])); - s[3] = _mm_loadu_si128((const __m128i *)(&src[48])); - s[4] = _mm_loadu_si128((const __m128i *)(src + src_stride + 0)); - s[5] = _mm_loadu_si128((const __m128i *)(src + src_stride + 16)); - s[6] = _mm_loadu_si128((const __m128i *)(src + src_stride + 32)); - s[7] = _mm_loadu_si128((const __m128i *)(src + src_stride + 48)); - - // 000 001 100 101 xx xx xx xx 004 005 104 105 xx xx xx xx - // 008 009 108 109 xx xx xx xx 00C 00D 10C 10D xx xx xx xx - // 010 011 110 111 xx xx xx xx 014 015 114 115 xx xx xx xx - // 018 019 118 119 xx xx xx xx 01C 01D 11C 11D xx xx xx xx - // 020 021 120 121 xx xx xx xx 024 025 124 125 xx xx xx xx - // 028 029 128 129 xx xx xx xx 02C 02D 12C 12D xx xx xx xx - // 030 031 130 131 xx xx xx xx 034 035 134 135 xx xx xx xx - // 038 039 138 139 xx xx xx xx 03C 03D 13C 13D xx xx xx xx - d[0] = _mm_unpacklo_epi16(s[0], s[4]); - d[1] = _mm_unpackhi_epi16(s[0], s[4]); - d[2] = _mm_unpacklo_epi16(s[1], s[5]); - d[3] = _mm_unpackhi_epi16(s[1], s[5]); - d[4] = _mm_unpacklo_epi16(s[2], s[6]); - d[5] = _mm_unpackhi_epi16(s[2], s[6]); - d[6] = _mm_unpacklo_epi16(s[3], s[7]); - d[7] = _mm_unpackhi_epi16(s[3], s[7]); - - // 000 001 100 101 008 009 108 109 xx xx xx xx xx xx xx xx - // 004 005 104 105 00C 00D 10C 10D xx xx xx xx xx xx xx xx - // 010 011 110 111 018 019 118 119 xx xx xx xx xx xx xx xx - // 014 015 114 115 01C 01D 11C 11D xx xx xx xx xx xx xx xx - // 020 021 120 121 028 029 128 129 xx xx xx xx xx xx xx xx - // 024 025 124 125 02C 02D 12C 12D xx xx xx xx xx xx xx xx - // 030 031 130 131 038 039 138 139 xx xx xx xx xx xx xx xx - // 034 035 134 135 03C 03D 13C 13D xx xx xx xx xx xx xx xx - s[0] = _mm_unpacklo_epi32(d[0], d[1]); - s[1] = _mm_unpackhi_epi32(d[0], d[1]); - s[2] = _mm_unpacklo_epi32(d[2], d[3]); - s[3] = _mm_unpackhi_epi32(d[2], d[3]); - s[4] = _mm_unpacklo_epi32(d[4], d[5]); - s[5] = _mm_unpackhi_epi32(d[4], d[5]); - s[6] = _mm_unpacklo_epi32(d[6], d[7]); - s[7] = _mm_unpackhi_epi32(d[6], d[7]); - - // 000 001 100 101 004 005 104 105 008 009 108 109 00C 00D 10C 10D - // 010 011 110 111 014 015 114 115 018 019 118 119 01C 01D 11C 11D - // 020 021 120 121 024 025 124 125 028 029 128 129 02C 02D 12C 12D - // 030 031 130 131 034 035 134 135 038 039 138 139 03C 03D 13C 13D - d[0] = _mm_unpacklo_epi32(s[0], s[1]); - d[1] = _mm_unpacklo_epi32(s[2], s[3]); - d[2] = _mm_unpacklo_epi32(s[4], s[5]); - d[3] = _mm_unpacklo_epi32(s[6], s[7]); - - d[0] = scale_plane_bilinear_kernel(&d[0], c0c1); - d[1] = scale_plane_bilinear_kernel(&d[2], c0c1); - - // Vertical - d[0] = scale_plane_bilinear_kernel(d, c0c1); - - _mm_storeu_si128((__m128i *)dst, d[0]); - src += 64; - dst += 16; - x -= 16; - } while (x); - src += 4 * (src_stride - max_width); - dst += dst_stride - max_width; - } while (--y); -} - -static void scale_plane_2_to_1_general(const uint8_t *src, const int src_stride, - uint8_t *dst, const int dst_stride, - const int w, const int h, - const int16_t *const coef, - uint8_t *const temp_buffer) { - const int width_hor = (w + 3) & ~3; - const int width_ver = (w + 7) & ~7; - const int height_hor = (2 * h + SUBPEL_TAPS - 2 + 7) & ~7; - const int height_ver = (h + 3) & ~3; - int x, y = height_hor; - uint8_t *t = temp_buffer; - __m128i s[11], d[4]; - __m128i f[4]; - - assert(w && h); - - shuffle_filter_ssse3(coef, f); - src -= (SUBPEL_TAPS / 2 - 1) * src_stride + SUBPEL_TAPS / 2 + 1; - - // horizontal 4x8 - do { - load_8bit_8x8(src + 2, src_stride, s); - // 00 01 10 11 20 21 30 31 40 41 50 51 60 61 70 71 - // 02 03 12 13 22 23 32 33 42 43 52 53 62 63 72 73 - // 04 05 14 15 24 25 34 35 44 45 54 55 64 65 74 75 - // 06 07 16 17 26 27 36 37 46 47 56 57 66 67 76 77 (overlapped) - transpose_16bit_4x8(s, s); - x = width_hor; - - do { - src += 8; - load_8bit_8x8(src, src_stride, &s[3]); - // 06 07 16 17 26 27 36 37 46 47 56 57 66 67 76 77 - // 08 09 18 19 28 29 38 39 48 49 58 59 68 69 78 79 - // 0A 0B 1A 1B 2A 2B 3A 3B 4A 4B 5A 5B 6A 6B 7A 7B - // 0C 0D 1C 1D 2C 2D 3C 3D 4C 4D 5C 5D 6C 6D 7C 7D - transpose_16bit_4x8(&s[3], &s[3]); - - d[0] = convolve8_8_ssse3(&s[0], f); // 00 10 20 30 40 50 60 70 - d[1] = convolve8_8_ssse3(&s[1], f); // 01 11 21 31 41 51 61 71 - d[2] = convolve8_8_ssse3(&s[2], f); // 02 12 22 32 42 52 62 72 - d[3] = convolve8_8_ssse3(&s[3], f); // 03 13 23 33 43 53 63 73 - - // 00 10 20 30 40 50 60 70 02 12 22 32 42 52 62 72 - // 01 11 21 31 41 51 61 71 03 13 23 33 43 53 63 73 - d[0] = _mm_packus_epi16(d[0], d[2]); - d[1] = _mm_packus_epi16(d[1], d[3]); - // 00 10 01 11 20 30 21 31 40 50 41 51 60 70 61 71 - // 02 12 03 13 22 32 23 33 42 52 43 53 62 72 63 73 - d[2] = _mm_unpacklo_epi16(d[0], d[1]); - d[3] = _mm_unpackhi_epi16(d[0], d[1]); - // 00 10 01 11 02 12 03 13 20 30 21 31 22 32 23 33 - // 40 50 41 51 42 52 43 53 60 70 61 71 62 72 63 73 - d[0] = _mm_unpacklo_epi32(d[2], d[3]); - d[1] = _mm_unpackhi_epi32(d[2], d[3]); - store_8bit_8x4_from_16x2(d, t, 2 * width_hor); - - s[0] = s[4]; - s[1] = s[5]; - s[2] = s[6]; - - t += 8; - x -= 4; - } while (x); - src += 8 * src_stride - 2 * width_hor; - t += 6 * width_hor; - y -= 8; - } while (y); - - // vertical 8x4 - x = width_ver; - t = temp_buffer; - do { - // 00 10 01 11 02 12 03 13 04 14 05 15 06 16 07 17 - // 20 30 21 31 22 32 23 33 24 34 25 35 26 36 27 37 - // 40 50 41 51 42 52 43 53 44 54 45 55 46 56 47 57 - s[0] = _mm_loadu_si128((const __m128i *)(t + 0 * width_hor)); - s[1] = _mm_loadu_si128((const __m128i *)(t + 2 * width_hor)); - s[2] = _mm_loadu_si128((const __m128i *)(t + 4 * width_hor)); - t += 6 * width_hor; - y = height_ver; - - do { - // 60 70 61 71 62 72 63 73 64 74 65 75 66 76 67 77 - // 80 90 81 91 82 92 83 93 84 94 85 95 86 96 87 77 - // A0 B0 A1 B1 A2 B2 A3 B3 A4 B4 A5 B5 A6 B6 A7 77 - // C0 D0 C1 D1 C2 D2 C3 D3 C4 D4 C5 D5 C6 D6 C7 77 - loadu_8bit_16x4(t, 2 * width_hor, &s[3]); - t += 8 * width_hor; - - d[0] = convolve8_8_ssse3(&s[0], f); // 00 01 02 03 04 05 06 07 - d[1] = convolve8_8_ssse3(&s[1], f); // 10 11 12 13 14 15 16 17 - d[2] = convolve8_8_ssse3(&s[2], f); // 20 21 22 23 24 25 26 27 - d[3] = convolve8_8_ssse3(&s[3], f); // 30 31 32 33 34 35 36 37 - - // 00 01 02 03 04 05 06 07 10 11 12 13 14 15 16 17 - // 20 21 22 23 24 25 26 27 30 31 32 33 34 35 36 37 - d[0] = _mm_packus_epi16(d[0], d[1]); - d[1] = _mm_packus_epi16(d[2], d[3]); - store_8bit_8x4_from_16x2(d, dst, dst_stride); - - s[0] = s[4]; - s[1] = s[5]; - s[2] = s[6]; - - dst += 4 * dst_stride; - y -= 4; - } while (y); - t -= width_hor * (2 * height_ver + 6); - t += 16; - dst -= height_ver * dst_stride; - dst += 8; - x -= 8; - } while (x); -} - -static void scale_plane_4_to_1_general(const uint8_t *src, const int src_stride, - uint8_t *dst, const int dst_stride, - const int w, const int h, - const int16_t *const coef, - uint8_t *const temp_buffer) { - const int width_hor = (w + 1) & ~1; - const int width_ver = (w + 7) & ~7; - const int height_hor = (4 * h + SUBPEL_TAPS - 2 + 7) & ~7; - const int height_ver = (h + 1) & ~1; - int x, y = height_hor; - uint8_t *t = temp_buffer; - __m128i s[11], d[4]; - __m128i f[4]; - - assert(w && h); - - shuffle_filter_ssse3(coef, f); - src -= (SUBPEL_TAPS / 2 - 1) * src_stride + SUBPEL_TAPS / 2 + 3; - - // horizontal 2x8 - do { - load_8bit_8x8(src + 4, src_stride, s); - // 00 01 10 11 20 21 30 31 40 41 50 51 60 61 70 71 - // 02 03 12 13 22 23 32 33 42 43 52 53 62 63 72 73 - // 04 05 14 15 24 25 34 35 44 45 54 55 64 65 74 75 (overlapped) - // 06 07 16 17 26 27 36 37 46 47 56 57 66 67 76 77 (overlapped) - transpose_16bit_4x8(s, s); - x = width_hor; - - do { - src += 8; - load_8bit_8x8(src, src_stride, &s[2]); - // 04 05 14 15 24 25 34 35 44 45 54 55 64 65 74 75 - // 06 07 16 17 26 27 36 37 46 47 56 57 66 67 76 77 - // 08 09 18 19 28 29 38 39 48 49 58 59 68 69 78 79 - // 0A 0B 1A 1B 2A 2B 3A 3B 4A 4B 5A 5B 6A 6B 7A 7B - transpose_16bit_4x8(&s[2], &s[2]); - - d[0] = convolve8_8_ssse3(&s[0], f); // 00 10 20 30 40 50 60 70 - d[1] = convolve8_8_ssse3(&s[2], f); // 01 11 21 31 41 51 61 71 - - // 00 10 20 30 40 50 60 70 xx xx xx xx xx xx xx xx - // 01 11 21 31 41 51 61 71 xx xx xx xx xx xx xx xx - d[0] = _mm_packus_epi16(d[0], d[0]); - d[1] = _mm_packus_epi16(d[1], d[1]); - // 00 10 01 11 20 30 21 31 40 50 41 51 60 70 61 71 - d[0] = _mm_unpacklo_epi16(d[0], d[1]); - store_8bit_4x4_sse2(d[0], t, 2 * width_hor); - - s[0] = s[4]; - s[1] = s[5]; - - t += 4; - x -= 2; - } while (x); - src += 8 * src_stride - 4 * width_hor; - t += 6 * width_hor; - y -= 8; - } while (y); - - // vertical 8x2 - x = width_ver; - t = temp_buffer; - do { - // 00 10 01 11 02 12 03 13 04 14 05 15 06 16 07 17 - // 20 30 21 31 22 32 23 33 24 34 25 35 26 36 27 37 - s[0] = _mm_loadu_si128((const __m128i *)(t + 0 * width_hor)); - s[1] = _mm_loadu_si128((const __m128i *)(t + 2 * width_hor)); - t += 4 * width_hor; - y = height_ver; - - do { - // 40 50 41 51 42 52 43 53 44 54 45 55 46 56 47 57 - // 60 70 61 71 62 72 63 73 64 74 65 75 66 76 67 77 - // 80 90 81 91 82 92 83 93 84 94 85 95 86 96 87 77 - // A0 B0 A1 B1 A2 B2 A3 B3 A4 B4 A5 B5 A6 B6 A7 77 - loadu_8bit_16x4(t, 2 * width_hor, &s[2]); - t += 8 * width_hor; - - d[0] = convolve8_8_ssse3(&s[0], f); // 00 01 02 03 04 05 06 07 - d[1] = convolve8_8_ssse3(&s[2], f); // 10 11 12 13 14 15 16 17 - - // 00 01 02 03 04 05 06 07 10 11 12 13 14 15 16 17 - d[0] = _mm_packus_epi16(d[0], d[1]); - _mm_storel_epi64((__m128i *)(dst + 0 * dst_stride), d[0]); - _mm_storeh_epi64((__m128i *)(dst + 1 * dst_stride), d[0]); - - s[0] = s[4]; - s[1] = s[5]; - - dst += 2 * dst_stride; - y -= 2; - } while (y); - t -= width_hor * (4 * height_ver + 4); - t += 16; - dst -= height_ver * dst_stride; - dst += 8; - x -= 8; - } while (x); -} - -typedef void (*shuffle_filter_funcs)(const int16_t *const filter, - __m128i *const f); - -typedef __m128i (*convolve8_funcs)(const __m128i *const s, - const __m128i *const f); - -static void scale_plane_4_to_3_general(const uint8_t *src, const int src_stride, - uint8_t *dst, const int dst_stride, - const int w, const int h, - const InterpKernel *const coef, - const int phase_scaler, - uint8_t *const temp_buffer) { - static const int step_q4 = 16 * 4 / 3; - const int width_hor = (w + 5) - ((w + 5) % 6); - const int stride_hor = 2 * width_hor + 4; // store 4 extra pixels - const int width_ver = (w + 7) & ~7; - // We need (SUBPEL_TAPS - 1) extra rows: (SUBPEL_TAPS / 2 - 1) extra rows - // above and (SUBPEL_TAPS / 2) extra rows below. - const int height_hor = (4 * h / 3 + SUBPEL_TAPS - 1 + 7) & ~7; - const int height_ver = (h + 5) - ((h + 5) % 6); - int x, y = height_hor; - uint8_t *t = temp_buffer; - __m128i s[12], d[6], dd[4]; - __m128i f0[4], f1[5], f2[5]; - // The offset of the first row is always less than 1 pixel. - const int offset1_q4 = phase_scaler + 1 * step_q4; - const int offset2_q4 = phase_scaler + 2 * step_q4; - // offset_idxx indicates the pixel offset is even (0) or odd (1). - // It's used to choose the src offset and filter coefficient offset. - const int offset_idx1 = (offset1_q4 >> 4) & 1; - const int offset_idx2 = (offset2_q4 >> 4) & 1; - static const shuffle_filter_funcs kShuffleFilterFuncs[2] = { - shuffle_filter_ssse3, shuffle_filter_odd_ssse3 - }; - static const convolve8_funcs kConvolve8Funcs[2] = { - convolve8_8_even_offset_ssse3, convolve8_8_odd_offset_ssse3 - }; - - assert(w && h); - - shuffle_filter_ssse3(coef[(phase_scaler + 0 * step_q4) & SUBPEL_MASK], f0); - kShuffleFilterFuncs[offset_idx1](coef[offset1_q4 & SUBPEL_MASK], f1); - kShuffleFilterFuncs[offset_idx2](coef[offset2_q4 & SUBPEL_MASK], f2); - - // Sub 64 to avoid overflow. - // Coef 128 would be treated as -128 in PMADDUBSW. Sub 64 here. - // Coef 128 is in either fx[1] or fx[2] depending on the phase idx. - // When filter phase idx is 1, the two biggest coefficients are shuffled - // together, and the sum of them are always no less than 128. Sub 64 here. - // After the subtraction, when the sum of all positive coefficients are no - // larger than 128, and the sum of all negative coefficients are no - // less than -128, there will be no overflow in the convolve8 functions. - f0[1] = _mm_sub_epi8(f0[1], _mm_set1_epi8(64)); - f1[1 + offset_idx1] = _mm_sub_epi8(f1[1 + offset_idx1], _mm_set1_epi8(64)); - f2[1 + offset_idx2] = _mm_sub_epi8(f2[1 + offset_idx2], _mm_set1_epi8(64)); - - src -= (SUBPEL_TAPS / 2 - 1) * src_stride + SUBPEL_TAPS / 2 - 1; - - // horizontal 6x8 - do { - load_8bit_8x8(src, src_stride, s); - // 00 01 10 11 20 21 30 31 40 41 50 51 60 61 70 71 - // 02 03 12 13 22 23 32 33 42 43 52 53 62 63 72 73 - // 04 05 14 15 24 25 34 35 44 45 54 55 64 65 74 75 - // 06 07 16 17 26 27 36 37 46 47 56 57 66 67 76 77 - transpose_16bit_4x8(s, s); - x = width_hor; - - do { - src += 8; - load_8bit_8x8(src, src_stride, &s[4]); - // 08 09 18 19 28 29 38 39 48 49 58 59 68 69 78 79 - // 0A 0B 1A 1B 2A 2B 3A 3B 4A 4B 5A 5B 6A 6B 7A 7B - // OC 0D 1C 1D 2C 2D 3C 3D 4C 4D 5C 5D 6C 6D 7C 7D - // 0E 0F 1E 1F 2E 2F 3E 3F 4E 4F 5E 5F 6E 6F 7E 7F - transpose_16bit_4x8(&s[4], &s[4]); - - // 00 10 20 30 40 50 60 70 - // 01 11 21 31 41 51 61 71 - // 02 12 22 32 42 52 62 72 - // 03 13 23 33 43 53 63 73 - // 04 14 24 34 44 54 64 74 - // 05 15 25 35 45 55 65 75 - d[0] = convolve8_8_even_offset_ssse3(&s[0], f0); - d[1] = kConvolve8Funcs[offset_idx1](&s[offset1_q4 >> 5], f1); - d[2] = kConvolve8Funcs[offset_idx2](&s[offset2_q4 >> 5], f2); - d[3] = convolve8_8_even_offset_ssse3(&s[2], f0); - d[4] = kConvolve8Funcs[offset_idx1](&s[2 + (offset1_q4 >> 5)], f1); - d[5] = kConvolve8Funcs[offset_idx2](&s[2 + (offset2_q4 >> 5)], f2); - - // 00 10 20 30 40 50 60 70 02 12 22 32 42 52 62 72 - // 01 11 21 31 41 51 61 71 03 13 23 33 43 53 63 73 - // 04 14 24 34 44 54 64 74 xx xx xx xx xx xx xx xx - // 05 15 25 35 45 55 65 75 xx xx xx xx xx xx xx xx - dd[0] = _mm_packus_epi16(d[0], d[2]); - dd[1] = _mm_packus_epi16(d[1], d[3]); - dd[2] = _mm_packus_epi16(d[4], d[4]); - dd[3] = _mm_packus_epi16(d[5], d[5]); - - // 00 10 01 11 20 30 21 31 40 50 41 51 60 70 61 71 - // 02 12 03 13 22 32 23 33 42 52 43 53 62 72 63 73 - // 04 14 05 15 24 34 25 35 44 54 45 55 64 74 65 75 - d[0] = _mm_unpacklo_epi16(dd[0], dd[1]); - d[1] = _mm_unpackhi_epi16(dd[0], dd[1]); - d[2] = _mm_unpacklo_epi16(dd[2], dd[3]); - - // 00 10 01 11 02 12 03 13 20 30 21 31 22 32 23 33 - // 40 50 41 51 42 52 43 53 60 70 61 71 62 72 63 73 - // 04 14 05 15 xx xx xx xx 24 34 25 35 xx xx xx xx - // 44 54 45 55 xx xx xx xx 64 74 65 75 xx xx xx xx - dd[0] = _mm_unpacklo_epi32(d[0], d[1]); - dd[1] = _mm_unpackhi_epi32(d[0], d[1]); - dd[2] = _mm_unpacklo_epi32(d[2], d[2]); - dd[3] = _mm_unpackhi_epi32(d[2], d[2]); - - // 00 10 01 11 02 12 03 13 04 14 05 15 xx xx xx xx - // 20 30 21 31 22 32 23 33 24 34 25 35 xx xx xx xx - // 40 50 41 51 42 52 43 53 44 54 45 55 xx xx xx xx - // 60 70 61 71 62 72 63 73 64 74 65 75 xx xx xx xx - d[0] = _mm_unpacklo_epi64(dd[0], dd[2]); - d[1] = _mm_unpackhi_epi64(dd[0], dd[2]); - d[2] = _mm_unpacklo_epi64(dd[1], dd[3]); - d[3] = _mm_unpackhi_epi64(dd[1], dd[3]); - - // store 4 extra pixels - storeu_8bit_16x4(d, t, stride_hor); - - s[0] = s[4]; - s[1] = s[5]; - s[2] = s[6]; - s[3] = s[7]; - - t += 12; - x -= 6; - } while (x); - src += 8 * src_stride - 4 * width_hor / 3; - t += 3 * stride_hor + 4; - y -= 8; - } while (y); - - // vertical 8x6 - x = width_ver; - t = temp_buffer; - do { - // 00 10 01 11 02 12 03 13 04 14 05 15 06 16 07 17 - // 20 30 21 31 22 32 23 33 24 34 25 35 26 36 27 37 - // 40 50 41 51 42 52 43 53 44 54 45 55 46 56 47 57 - // 60 70 61 71 62 72 63 73 64 74 65 75 66 76 67 77 - loadu_8bit_16x4(t, stride_hor, s); - y = height_ver; - - do { - // 80 90 81 91 82 92 83 93 84 94 85 95 86 96 87 97 - // A0 B0 A1 B1 A2 B2 A3 B3 A4 B4 A5 B5 A6 B6 A7 B7 - // C0 D0 C1 D1 C2 D2 C3 D3 C4 D4 C5 D5 C6 D6 C7 D7 - // E0 F0 E1 F1 E2 F2 E3 F3 E4 F4 E5 F5 E6 F6 E7 F7 - t += 4 * stride_hor; - loadu_8bit_16x4(t, stride_hor, &s[4]); - - d[0] = convolve8_8_even_offset_ssse3(&s[0], f0); - d[1] = kConvolve8Funcs[offset_idx1](&s[offset1_q4 >> 5], f1); - d[2] = kConvolve8Funcs[offset_idx2](&s[offset2_q4 >> 5], f2); - d[3] = convolve8_8_even_offset_ssse3(&s[2], f0); - d[4] = kConvolve8Funcs[offset_idx1](&s[2 + (offset1_q4 >> 5)], f1); - d[5] = kConvolve8Funcs[offset_idx2](&s[2 + (offset2_q4 >> 5)], f2); - - // 00 01 02 03 04 05 06 07 10 11 12 13 14 15 16 17 - // 20 21 22 23 24 25 26 27 30 31 32 33 34 35 36 37 - // 40 41 42 43 44 45 46 47 50 51 52 53 54 55 56 57 - d[0] = _mm_packus_epi16(d[0], d[1]); - d[2] = _mm_packus_epi16(d[2], d[3]); - d[4] = _mm_packus_epi16(d[4], d[5]); - - _mm_storel_epi64((__m128i *)(dst + 0 * dst_stride), d[0]); - _mm_storeh_epi64((__m128i *)(dst + 1 * dst_stride), d[0]); - _mm_storel_epi64((__m128i *)(dst + 2 * dst_stride), d[2]); - _mm_storeh_epi64((__m128i *)(dst + 3 * dst_stride), d[2]); - _mm_storel_epi64((__m128i *)(dst + 4 * dst_stride), d[4]); - _mm_storeh_epi64((__m128i *)(dst + 5 * dst_stride), d[4]); - - s[0] = s[4]; - s[1] = s[5]; - s[2] = s[6]; - s[3] = s[7]; - - dst += 6 * dst_stride; - y -= 6; - } while (y); - t -= stride_hor * 2 * height_ver / 3; - t += 16; - dst -= height_ver * dst_stride; - dst += 8; - x -= 8; - } while (x); -} - -static INLINE __m128i scale_1_to_2_phase_0_kernel(const __m128i *const s, - const __m128i *const f) { - __m128i ss[4], temp; - - ss[0] = _mm_unpacklo_epi8(s[0], s[1]); - ss[1] = _mm_unpacklo_epi8(s[2], s[3]); - ss[2] = _mm_unpacklo_epi8(s[4], s[5]); - ss[3] = _mm_unpacklo_epi8(s[6], s[7]); - temp = convolve8_8_ssse3(ss, f); - return _mm_packus_epi16(temp, temp); -} - -// Only calculate odd columns since even columns are just src pixels' copies. -static void scale_1_to_2_phase_0_row(const uint8_t *src, uint8_t *dst, - const int w, const __m128i *const f) { - int x = w; - - do { - __m128i s[8], temp; - s[0] = _mm_loadl_epi64((const __m128i *)(src + 0)); - s[1] = _mm_loadl_epi64((const __m128i *)(src + 1)); - s[2] = _mm_loadl_epi64((const __m128i *)(src + 2)); - s[3] = _mm_loadl_epi64((const __m128i *)(src + 3)); - s[4] = _mm_loadl_epi64((const __m128i *)(src + 4)); - s[5] = _mm_loadl_epi64((const __m128i *)(src + 5)); - s[6] = _mm_loadl_epi64((const __m128i *)(src + 6)); - s[7] = _mm_loadl_epi64((const __m128i *)(src + 7)); - temp = scale_1_to_2_phase_0_kernel(s, f); - _mm_storel_epi64((__m128i *)dst, temp); - src += 8; - dst += 8; - x -= 8; - } while (x); -} - -static void scale_plane_1_to_2_phase_0(const uint8_t *src, - const ptrdiff_t src_stride, uint8_t *dst, - const ptrdiff_t dst_stride, - const int src_w, const int src_h, - const int16_t *const coef, - uint8_t *const temp_buffer) { - int max_width; - int y; - uint8_t *tmp[9]; - __m128i f[4]; - - max_width = (src_w + 7) & ~7; - tmp[0] = temp_buffer + 0 * max_width; - tmp[1] = temp_buffer + 1 * max_width; - tmp[2] = temp_buffer + 2 * max_width; - tmp[3] = temp_buffer + 3 * max_width; - tmp[4] = temp_buffer + 4 * max_width; - tmp[5] = temp_buffer + 5 * max_width; - tmp[6] = temp_buffer + 6 * max_width; - tmp[7] = temp_buffer + 7 * max_width; - - shuffle_filter_ssse3(coef, f); - - scale_1_to_2_phase_0_row(src - 3 * src_stride - 3, tmp[0], max_width, f); - scale_1_to_2_phase_0_row(src - 2 * src_stride - 3, tmp[1], max_width, f); - scale_1_to_2_phase_0_row(src - 1 * src_stride - 3, tmp[2], max_width, f); - scale_1_to_2_phase_0_row(src + 0 * src_stride - 3, tmp[3], max_width, f); - scale_1_to_2_phase_0_row(src + 1 * src_stride - 3, tmp[4], max_width, f); - scale_1_to_2_phase_0_row(src + 2 * src_stride - 3, tmp[5], max_width, f); - scale_1_to_2_phase_0_row(src + 3 * src_stride - 3, tmp[6], max_width, f); - - y = src_h; - do { - int x; - scale_1_to_2_phase_0_row(src + 4 * src_stride - 3, tmp[7], max_width, f); - for (x = 0; x < max_width; x += 8) { - __m128i s[8], C, D, CD; - - // Even rows - const __m128i a = _mm_loadl_epi64((const __m128i *)(src + x)); - const __m128i b = _mm_loadl_epi64((const __m128i *)(tmp[3] + x)); - const __m128i ab = _mm_unpacklo_epi8(a, b); - _mm_storeu_si128((__m128i *)(dst + 2 * x), ab); - - // Odd rows - // Even columns - load_8bit_8x8(src + x - 3 * src_stride, src_stride, s); - C = scale_1_to_2_phase_0_kernel(s, f); - - // Odd columns - s[0] = _mm_loadl_epi64((const __m128i *)(tmp[0] + x)); - s[1] = _mm_loadl_epi64((const __m128i *)(tmp[1] + x)); - s[2] = _mm_loadl_epi64((const __m128i *)(tmp[2] + x)); - s[3] = _mm_loadl_epi64((const __m128i *)(tmp[3] + x)); - s[4] = _mm_loadl_epi64((const __m128i *)(tmp[4] + x)); - s[5] = _mm_loadl_epi64((const __m128i *)(tmp[5] + x)); - s[6] = _mm_loadl_epi64((const __m128i *)(tmp[6] + x)); - s[7] = _mm_loadl_epi64((const __m128i *)(tmp[7] + x)); - D = scale_1_to_2_phase_0_kernel(s, f); - - CD = _mm_unpacklo_epi8(C, D); - _mm_storeu_si128((__m128i *)(dst + dst_stride + 2 * x), CD); - } - - src += src_stride; - dst += 2 * dst_stride; - tmp[8] = tmp[0]; - tmp[0] = tmp[1]; - tmp[1] = tmp[2]; - tmp[2] = tmp[3]; - tmp[3] = tmp[4]; - tmp[4] = tmp[5]; - tmp[5] = tmp[6]; - tmp[6] = tmp[7]; - tmp[7] = tmp[8]; - } while (--y); -} - -void vp9_scale_and_extend_frame_ssse3(const YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst, - uint8_t filter_type, int phase_scaler) { - const int src_w = src->y_crop_width; - const int src_h = src->y_crop_height; - const int dst_w = dst->y_crop_width; - const int dst_h = dst->y_crop_height; - const int dst_uv_w = dst->uv_crop_width; - const int dst_uv_h = dst->uv_crop_height; - int scaled = 0; - - // phase_scaler is usually 0 or 8. - assert(phase_scaler >= 0 && phase_scaler < 16); - - if (dst_w * 2 == src_w && dst_h * 2 == src_h) { - // 2 to 1 - scaled = 1; - - if (phase_scaler == 0) { - scale_plane_2_to_1_phase_0(src->y_buffer, src->y_stride, dst->y_buffer, - dst->y_stride, dst_w, dst_h); - scale_plane_2_to_1_phase_0(src->u_buffer, src->uv_stride, dst->u_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h); - scale_plane_2_to_1_phase_0(src->v_buffer, src->uv_stride, dst->v_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h); - } else if (filter_type == BILINEAR) { - const int16_t c0 = vp9_filter_kernels[BILINEAR][phase_scaler][3]; - const int16_t c1 = vp9_filter_kernels[BILINEAR][phase_scaler][4]; - const __m128i c0c1 = _mm_set1_epi16(c0 | (c1 << 8)); // c0 and c1 >= 0 - scale_plane_2_to_1_bilinear(src->y_buffer, src->y_stride, dst->y_buffer, - dst->y_stride, dst_w, dst_h, c0c1); - scale_plane_2_to_1_bilinear(src->u_buffer, src->uv_stride, dst->u_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h, c0c1); - scale_plane_2_to_1_bilinear(src->v_buffer, src->uv_stride, dst->v_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h, c0c1); - } else { - const int buffer_stride = (dst_w + 3) & ~3; - const int buffer_height = (2 * dst_h + SUBPEL_TAPS - 2 + 7) & ~7; - uint8_t *const temp_buffer = - (uint8_t *)malloc(buffer_stride * buffer_height); - if (temp_buffer) { - scale_plane_2_to_1_general( - src->y_buffer, src->y_stride, dst->y_buffer, dst->y_stride, dst_w, - dst_h, vp9_filter_kernels[filter_type][phase_scaler], temp_buffer); - scale_plane_2_to_1_general( - src->u_buffer, src->uv_stride, dst->u_buffer, dst->uv_stride, - dst_uv_w, dst_uv_h, vp9_filter_kernels[filter_type][phase_scaler], - temp_buffer); - scale_plane_2_to_1_general( - src->v_buffer, src->uv_stride, dst->v_buffer, dst->uv_stride, - dst_uv_w, dst_uv_h, vp9_filter_kernels[filter_type][phase_scaler], - temp_buffer); - free(temp_buffer); - } else { - scaled = 0; - } - } - } else if (4 * dst_w == src_w && 4 * dst_h == src_h) { - // 4 to 1 - scaled = 1; - if (phase_scaler == 0) { - scale_plane_4_to_1_phase_0(src->y_buffer, src->y_stride, dst->y_buffer, - dst->y_stride, dst_w, dst_h); - scale_plane_4_to_1_phase_0(src->u_buffer, src->uv_stride, dst->u_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h); - scale_plane_4_to_1_phase_0(src->v_buffer, src->uv_stride, dst->v_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h); - } else if (filter_type == BILINEAR) { - const int16_t c0 = vp9_filter_kernels[BILINEAR][phase_scaler][3]; - const int16_t c1 = vp9_filter_kernels[BILINEAR][phase_scaler][4]; - const __m128i c0c1 = _mm_set1_epi16(c0 | (c1 << 8)); // c0 and c1 >= 0 - scale_plane_4_to_1_bilinear(src->y_buffer, src->y_stride, dst->y_buffer, - dst->y_stride, dst_w, dst_h, c0c1); - scale_plane_4_to_1_bilinear(src->u_buffer, src->uv_stride, dst->u_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h, c0c1); - scale_plane_4_to_1_bilinear(src->v_buffer, src->uv_stride, dst->v_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h, c0c1); - } else { - const int buffer_stride = (dst_w + 1) & ~1; - const int buffer_height = (4 * dst_h + SUBPEL_TAPS - 2 + 7) & ~7; - // When dst_w is 1 or 2, we need extra padding to avoid heap read overflow - const int extra_padding = 16; - uint8_t *const temp_buffer = - (uint8_t *)malloc(buffer_stride * buffer_height + extra_padding); - if (temp_buffer) { - scale_plane_4_to_1_general( - src->y_buffer, src->y_stride, dst->y_buffer, dst->y_stride, dst_w, - dst_h, vp9_filter_kernels[filter_type][phase_scaler], temp_buffer); - scale_plane_4_to_1_general( - src->u_buffer, src->uv_stride, dst->u_buffer, dst->uv_stride, - dst_uv_w, dst_uv_h, vp9_filter_kernels[filter_type][phase_scaler], - temp_buffer); - scale_plane_4_to_1_general( - src->v_buffer, src->uv_stride, dst->v_buffer, dst->uv_stride, - dst_uv_w, dst_uv_h, vp9_filter_kernels[filter_type][phase_scaler], - temp_buffer); - free(temp_buffer); - } else { - scaled = 0; - } - } - } else if (4 * dst_w == 3 * src_w && 4 * dst_h == 3 * src_h) { - // 4 to 3 - const int buffer_stride_hor = (dst_w + 5) - ((dst_w + 5) % 6) + 2; - const int buffer_stride_ver = (dst_w + 7) & ~7; - const int buffer_height = (4 * dst_h / 3 + SUBPEL_TAPS - 1 + 7) & ~7; - // When the vertical filter reads more pixels than the horizontal filter - // generated in each row, we need extra padding to avoid heap read overflow. - // For example, the horizontal filter generates 18 pixels but the vertical - // filter reads 24 pixels in a row. The difference is multiplied by 2 since - // two rows are interlaced together in the optimization. - const int extra_padding = (buffer_stride_ver > buffer_stride_hor) - ? 2 * (buffer_stride_ver - buffer_stride_hor) - : 0; - const int buffer_size = buffer_stride_hor * buffer_height + extra_padding; - uint8_t *const temp_buffer = (uint8_t *)malloc(buffer_size); - if (temp_buffer) { - scaled = 1; - scale_plane_4_to_3_general( - src->y_buffer, src->y_stride, dst->y_buffer, dst->y_stride, dst_w, - dst_h, vp9_filter_kernels[filter_type], phase_scaler, temp_buffer); - scale_plane_4_to_3_general(src->u_buffer, src->uv_stride, dst->u_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h, - vp9_filter_kernels[filter_type], phase_scaler, - temp_buffer); - scale_plane_4_to_3_general(src->v_buffer, src->uv_stride, dst->v_buffer, - dst->uv_stride, dst_uv_w, dst_uv_h, - vp9_filter_kernels[filter_type], phase_scaler, - temp_buffer); - free(temp_buffer); - } - } else if (dst_w == src_w * 2 && dst_h == src_h * 2 && phase_scaler == 0) { - // 1 to 2 - uint8_t *const temp_buffer = (uint8_t *)malloc(8 * ((src_w + 7) & ~7)); - if (temp_buffer) { - scaled = 1; - scale_plane_1_to_2_phase_0( - src->y_buffer, src->y_stride, dst->y_buffer, dst->y_stride, src_w, - src_h, vp9_filter_kernels[filter_type][8], temp_buffer); - const int src_uv_w = src->uv_crop_width; - const int src_uv_h = src->uv_crop_height; - scale_plane_1_to_2_phase_0( - src->u_buffer, src->uv_stride, dst->u_buffer, dst->uv_stride, - src_uv_w, src_uv_h, vp9_filter_kernels[filter_type][8], temp_buffer); - scale_plane_1_to_2_phase_0( - src->v_buffer, src->uv_stride, dst->v_buffer, dst->uv_stride, - src_uv_w, src_uv_h, vp9_filter_kernels[filter_type][8], temp_buffer); - free(temp_buffer); - } - } - - if (scaled) { - vpx_extend_frame_borders(dst); - } else { - // Call c version for all other scaling ratios. - vp9_scale_and_extend_frame_c(src, dst, filter_type, phase_scaler); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_highbd_block_error_intrin_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_highbd_block_error_intrin_sse2.c deleted file mode 100644 index d7aafe7b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_highbd_block_error_intrin_sse2.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vp9_rtcd.h" -#include "vp9/common/vp9_common.h" - -int64_t vp9_highbd_block_error_sse2(const tran_low_t *coeff, - const tran_low_t *dqcoeff, - intptr_t block_size, int64_t *ssz, int bd) { - int i, j, test; - uint32_t temp[4]; - __m128i max, min, cmp0, cmp1, cmp2, cmp3; - int64_t error = 0, sqcoeff = 0; - const int shift = 2 * (bd - 8); - const int rounding = shift > 0 ? 1 << (shift - 1) : 0; - - for (i = 0; i < block_size; i += 8) { - // Load the data into xmm registers - __m128i mm_coeff = _mm_load_si128((const __m128i *)(coeff + i)); - __m128i mm_coeff2 = _mm_load_si128((const __m128i *)(coeff + i + 4)); - __m128i mm_dqcoeff = _mm_load_si128((const __m128i *)(dqcoeff + i)); - __m128i mm_dqcoeff2 = _mm_load_si128((const __m128i *)(dqcoeff + i + 4)); - // Check if any values require more than 15 bit - max = _mm_set1_epi32(0x3fff); - min = _mm_set1_epi32((int32_t)0xffffc000); - cmp0 = _mm_xor_si128(_mm_cmpgt_epi32(mm_coeff, max), - _mm_cmplt_epi32(mm_coeff, min)); - cmp1 = _mm_xor_si128(_mm_cmpgt_epi32(mm_coeff2, max), - _mm_cmplt_epi32(mm_coeff2, min)); - cmp2 = _mm_xor_si128(_mm_cmpgt_epi32(mm_dqcoeff, max), - _mm_cmplt_epi32(mm_dqcoeff, min)); - cmp3 = _mm_xor_si128(_mm_cmpgt_epi32(mm_dqcoeff2, max), - _mm_cmplt_epi32(mm_dqcoeff2, min)); - test = _mm_movemask_epi8( - _mm_or_si128(_mm_or_si128(cmp0, cmp1), _mm_or_si128(cmp2, cmp3))); - - if (!test) { - __m128i mm_diff, error_sse2, sqcoeff_sse2; - mm_coeff = _mm_packs_epi32(mm_coeff, mm_coeff2); - mm_dqcoeff = _mm_packs_epi32(mm_dqcoeff, mm_dqcoeff2); - mm_diff = _mm_sub_epi16(mm_coeff, mm_dqcoeff); - error_sse2 = _mm_madd_epi16(mm_diff, mm_diff); - sqcoeff_sse2 = _mm_madd_epi16(mm_coeff, mm_coeff); - _mm_storeu_si128((__m128i *)temp, error_sse2); - error = error + temp[0] + temp[1] + temp[2] + temp[3]; - _mm_storeu_si128((__m128i *)temp, sqcoeff_sse2); - sqcoeff += temp[0] + temp[1] + temp[2] + temp[3]; - } else { - for (j = 0; j < 8; j++) { - const int64_t diff = coeff[i + j] - dqcoeff[i + j]; - error += diff * diff; - sqcoeff += (int64_t)coeff[i + j] * (int64_t)coeff[i + j]; - } - } - } - assert(error >= 0 && sqcoeff >= 0); - error = (error + rounding) >> shift; - sqcoeff = (sqcoeff + rounding) >> shift; - - *ssz = sqcoeff; - return error; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_quantize_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_quantize_avx2.c deleted file mode 100644 index bf44b086..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_quantize_avx2.c +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include // AVX2 - -#include "./vp9_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/x86/bitdepth_conversion_avx2.h" -#include "vpx_dsp/x86/quantize_sse2.h" -#include "vp9/common/vp9_scan.h" -#include "vp9/encoder/vp9_block.h" - -// Zero fill 8 positions in the output buffer. -static VPX_FORCE_INLINE void store_zero_tran_low(tran_low_t *a) { - const __m256i zero = _mm256_setzero_si256(); -#if CONFIG_VP9_HIGHBITDEPTH - _mm256_storeu_si256((__m256i *)(a), zero); - _mm256_storeu_si256((__m256i *)(a + 8), zero); -#else - _mm256_storeu_si256((__m256i *)(a), zero); -#endif -} - -static VPX_FORCE_INLINE void load_fp_values_avx2( - const struct macroblock_plane *mb_plane, __m256i *round, __m256i *quant, - const int16_t *dequant_ptr, __m256i *dequant) { - *round = _mm256_castsi128_si256( - _mm_load_si128((const __m128i *)mb_plane->round_fp)); - *round = _mm256_permute4x64_epi64(*round, 0x54); - *quant = _mm256_castsi128_si256( - _mm_load_si128((const __m128i *)mb_plane->quant_fp)); - *quant = _mm256_permute4x64_epi64(*quant, 0x54); - *dequant = - _mm256_castsi128_si256(_mm_load_si128((const __m128i *)dequant_ptr)); - *dequant = _mm256_permute4x64_epi64(*dequant, 0x54); -} - -static VPX_FORCE_INLINE __m256i get_max_lane_eob(const int16_t *iscan, - __m256i v_eobmax, - __m256i v_mask) { -#if CONFIG_VP9_HIGHBITDEPTH - const __m256i v_iscan = _mm256_permute4x64_epi64( - _mm256_loadu_si256((const __m256i *)iscan), 0xD8); -#else - const __m256i v_iscan = _mm256_loadu_si256((const __m256i *)iscan); -#endif - const __m256i v_nz_iscan = _mm256_and_si256(v_iscan, v_mask); - return _mm256_max_epi16(v_eobmax, v_nz_iscan); -} - -static VPX_FORCE_INLINE uint16_t get_max_eob(__m256i eob256) { - const __m256i eob_lo = eob256; - // Copy upper 128 to lower 128 - const __m256i eob_hi = _mm256_permute2x128_si256(eob256, eob256, 0X81); - __m256i eob = _mm256_max_epi16(eob_lo, eob_hi); - __m256i eob_s = _mm256_shuffle_epi32(eob, 0xe); - eob = _mm256_max_epi16(eob, eob_s); - eob_s = _mm256_shufflelo_epi16(eob, 0xe); - eob = _mm256_max_epi16(eob, eob_s); - eob_s = _mm256_shufflelo_epi16(eob, 1); - eob = _mm256_max_epi16(eob, eob_s); -#if defined(_MSC_VER) && (_MSC_VER < 1910) - return _mm_cvtsi128_si32(_mm256_extracti128_si256(eob, 0)) & 0xffff; -#else - return (uint16_t)_mm256_extract_epi16(eob, 0); -#endif -} - -static VPX_FORCE_INLINE void quantize_fp_16( - const __m256i *round, const __m256i *quant, const __m256i *dequant, - const __m256i *thr, const tran_low_t *coeff_ptr, const int16_t *iscan_ptr, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, __m256i *eob_max) { - const __m256i coeff = load_tran_low(coeff_ptr); - const __m256i abs_coeff = _mm256_abs_epi16(coeff); - const int32_t nzflag = - _mm256_movemask_epi8(_mm256_cmpgt_epi16(abs_coeff, *thr)); - - if (nzflag) { - const __m256i tmp_rnd = _mm256_adds_epi16(abs_coeff, *round); - const __m256i abs_qcoeff = _mm256_mulhi_epi16(tmp_rnd, *quant); - const __m256i qcoeff = _mm256_sign_epi16(abs_qcoeff, coeff); - const __m256i dqcoeff = _mm256_mullo_epi16(qcoeff, *dequant); - const __m256i nz_mask = - _mm256_cmpgt_epi16(abs_qcoeff, _mm256_setzero_si256()); - store_tran_low(qcoeff, qcoeff_ptr); - store_tran_low(dqcoeff, dqcoeff_ptr); - - *eob_max = get_max_lane_eob(iscan_ptr, *eob_max, nz_mask); - } else { - store_zero_tran_low(qcoeff_ptr); - store_zero_tran_low(dqcoeff_ptr); - } -} - -void vp9_quantize_fp_avx2(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - __m256i round, quant, dequant, thr; - __m256i eob_max = _mm256_setzero_si256(); - const int16_t *iscan = scan_order->iscan; - - coeff_ptr += n_coeffs; - iscan += n_coeffs; - qcoeff_ptr += n_coeffs; - dqcoeff_ptr += n_coeffs; - n_coeffs = -n_coeffs; - - // Setup global values - load_fp_values_avx2(mb_plane, &round, &quant, dequant_ptr, &dequant); - thr = _mm256_setzero_si256(); - - quantize_fp_16(&round, &quant, &dequant, &thr, coeff_ptr + n_coeffs, - iscan + n_coeffs, qcoeff_ptr + n_coeffs, - dqcoeff_ptr + n_coeffs, &eob_max); - - n_coeffs += 8 * 2; - - // remove dc constants - dequant = _mm256_permute2x128_si256(dequant, dequant, 0x31); - quant = _mm256_permute2x128_si256(quant, quant, 0x31); - round = _mm256_permute2x128_si256(round, round, 0x31); - thr = _mm256_srai_epi16(dequant, 1); - - // AC only loop - while (n_coeffs < 0) { - quantize_fp_16(&round, &quant, &dequant, &thr, coeff_ptr + n_coeffs, - iscan + n_coeffs, qcoeff_ptr + n_coeffs, - dqcoeff_ptr + n_coeffs, &eob_max); - n_coeffs += 8 * 2; - } - - *eob_ptr = get_max_eob(eob_max); -} - -// Enable this flag when matching the optimized code to -// vp9_quantize_fp_32x32_c(). Disabled, the optimized code will match the -// existing ssse3 code and quantize_fp_32x32_nz_c(). -// -// #define MATCH_VP9_QUANTIZE_FP_32X32_C - -#ifndef MATCH_VP9_QUANTIZE_FP_32X32_C -static VPX_FORCE_INLINE void quantize_fp_32x32_16_no_nzflag( - const __m256i *round, const __m256i *quant, const __m256i *dequant, - const __m256i *thr, const tran_low_t *coeff_ptr, const int16_t *iscan_ptr, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, __m256i *eob_max) { - const __m256i coeff = load_tran_low(coeff_ptr); - const __m256i abs_coeff = _mm256_abs_epi16(coeff); - const __m256i tmp_rnd = _mm256_adds_epi16(abs_coeff, *round); - const __m256i abs_qcoeff = _mm256_mulhi_epi16(tmp_rnd, *quant); - const __m256i qcoeff = _mm256_sign_epi16(abs_qcoeff, coeff); - const __m256i abs_dqcoeff = - _mm256_srli_epi16(_mm256_mullo_epi16(abs_qcoeff, *dequant), 1); - const __m256i dqcoeff = _mm256_sign_epi16(abs_dqcoeff, coeff); - const __m256i nz_mask = - _mm256_cmpgt_epi16(abs_qcoeff, _mm256_setzero_si256()); - store_tran_low(qcoeff, qcoeff_ptr); - store_tran_low(dqcoeff, dqcoeff_ptr); - - *eob_max = get_max_lane_eob(iscan_ptr, *eob_max, nz_mask); - (void)thr; -} -#endif - -static VPX_FORCE_INLINE void quantize_fp_32x32_16( - const __m256i *round, const __m256i *quant, const __m256i *dequant, - const __m256i *thr, const tran_low_t *coeff_ptr, const int16_t *iscan_ptr, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, __m256i *eob_max) { - const __m256i coeff = load_tran_low(coeff_ptr); - const __m256i abs_coeff = _mm256_abs_epi16(coeff); - const __m256i thr_mask = _mm256_cmpgt_epi16(abs_coeff, *thr); - const int32_t nzflag = _mm256_movemask_epi8(thr_mask); - - if (nzflag) { -#ifdef MATCH_VP9_QUANTIZE_FP_32X32_C - const __m256i tmp_rnd = - _mm256_and_si256(_mm256_adds_epi16(abs_coeff, *round), thr_mask); -#else - const __m256i tmp_rnd = _mm256_adds_epi16(abs_coeff, *round); -#endif - const __m256i abs_qcoeff = _mm256_mulhi_epi16(tmp_rnd, *quant); - const __m256i qcoeff = _mm256_sign_epi16(abs_qcoeff, coeff); - const __m256i abs_dqcoeff = - _mm256_srli_epi16(_mm256_mullo_epi16(abs_qcoeff, *dequant), 1); - const __m256i dqcoeff = _mm256_sign_epi16(abs_dqcoeff, coeff); - const __m256i nz_mask = - _mm256_cmpgt_epi16(abs_qcoeff, _mm256_setzero_si256()); - store_tran_low(qcoeff, qcoeff_ptr); - store_tran_low(dqcoeff, dqcoeff_ptr); - - *eob_max = get_max_lane_eob(iscan_ptr, *eob_max, nz_mask); - } else { - store_zero_tran_low(qcoeff_ptr); - store_zero_tran_low(dqcoeff_ptr); - } -} - -void vp9_quantize_fp_32x32_avx2(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - __m256i round, quant, dequant, thr; - __m256i eob_max = _mm256_setzero_si256(); - const int16_t *iscan = scan_order->iscan; - - coeff_ptr += n_coeffs; - iscan += n_coeffs; - qcoeff_ptr += n_coeffs; - dqcoeff_ptr += n_coeffs; - n_coeffs = -n_coeffs; - - // Setup global values - load_fp_values_avx2(mb_plane, &round, &quant, dequant_ptr, &dequant); - thr = _mm256_srli_epi16(dequant, 2); - quant = _mm256_slli_epi16(quant, 1); - { - const __m256i rnd = _mm256_set1_epi16((int16_t)1); - round = _mm256_add_epi16(round, rnd); - round = _mm256_srai_epi16(round, 1); - } - -#ifdef MATCH_VP9_QUANTIZE_FP_32X32_C - // Subtracting 1 here eliminates a _mm256_cmpeq_epi16() instruction when - // calculating the zbin mask. - thr = _mm256_sub_epi16(thr, _mm256_set1_epi16(1)); - quantize_fp_32x32_16(&round, &quant, &dequant, &thr, coeff_ptr + n_coeffs, - iscan + n_coeffs, qcoeff_ptr + n_coeffs, - dqcoeff_ptr + n_coeffs, &eob_max); -#else - quantize_fp_32x32_16_no_nzflag( - &round, &quant, &dequant, &thr, coeff_ptr + n_coeffs, iscan + n_coeffs, - qcoeff_ptr + n_coeffs, dqcoeff_ptr + n_coeffs, &eob_max); -#endif - - n_coeffs += 8 * 2; - - // remove dc constants - dequant = _mm256_permute2x128_si256(dequant, dequant, 0x31); - quant = _mm256_permute2x128_si256(quant, quant, 0x31); - round = _mm256_permute2x128_si256(round, round, 0x31); - thr = _mm256_permute2x128_si256(thr, thr, 0x31); - - // AC only loop - while (n_coeffs < 0) { - quantize_fp_32x32_16(&round, &quant, &dequant, &thr, coeff_ptr + n_coeffs, - iscan + n_coeffs, qcoeff_ptr + n_coeffs, - dqcoeff_ptr + n_coeffs, &eob_max); - n_coeffs += 8 * 2; - } - - *eob_ptr = get_max_eob(eob_max); -} - -#if CONFIG_VP9_HIGHBITDEPTH -static VPX_FORCE_INLINE __m256i mm256_mul_shift_epi32_logscale(const __m256i *x, - const __m256i *y, - int log_scale) { - __m256i prod_lo = _mm256_mul_epi32(*x, *y); - __m256i prod_hi = _mm256_srli_epi64(*x, 32); - const __m256i mult_hi = _mm256_srli_epi64(*y, 32); - const __m256i mask = _mm256_set_epi32(0, -1, 0, -1, 0, -1, 0, -1); - prod_hi = _mm256_mul_epi32(prod_hi, mult_hi); - prod_lo = _mm256_srli_epi64(prod_lo, 16 - log_scale); - prod_lo = _mm256_and_si256(prod_lo, mask); - prod_hi = _mm256_srli_epi64(prod_hi, 16 - log_scale); - prod_hi = _mm256_slli_epi64(prod_hi, 32); - return _mm256_or_si256(prod_lo, prod_hi); -} - -static VPX_FORCE_INLINE __m256i highbd_init_256(const int16_t *val_ptr) { - const __m128i v = _mm_load_si128((const __m128i *)val_ptr); - const __m128i zero = _mm_setzero_si128(); - const __m128i dc = _mm_unpacklo_epi16(v, zero); - const __m128i ac = _mm_unpackhi_epi16(v, zero); - return _mm256_insertf128_si256(_mm256_castsi128_si256(dc), ac, 1); -} - -static VPX_FORCE_INLINE void highbd_load_fp_values( - const struct macroblock_plane *mb_plane, __m256i *round, __m256i *quant, - const int16_t *dequant_ptr, __m256i *dequant) { - *round = highbd_init_256(mb_plane->round_fp); - *quant = highbd_init_256(mb_plane->quant_fp); - *dequant = highbd_init_256(dequant_ptr); -} - -static VPX_FORCE_INLINE __m256i highbd_get_max_lane_eob( - const int16_t *iscan_ptr, __m256i eobmax, __m256i nz_mask) { - const __m256i packed_nz_mask = - _mm256_packs_epi32(nz_mask, _mm256_setzero_si256()); - const __m256i packed_nz_mask_perm = - _mm256_permute4x64_epi64(packed_nz_mask, 0xD8); - const __m256i iscan = - _mm256_castsi128_si256(_mm_loadu_si128((const __m128i *)iscan_ptr)); - const __m256i nz_iscan = _mm256_and_si256(iscan, packed_nz_mask_perm); - return _mm256_max_epi16(eobmax, nz_iscan); -} - -static VPX_FORCE_INLINE void highbd_quantize_fp( - const __m256i *round, const __m256i *quant, const __m256i *dequant, - const tran_low_t *coeff_ptr, const int16_t *iscan_ptr, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, __m256i *eob) { - const __m256i coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr); - const __m256i abs_coeff = _mm256_abs_epi32(coeff); - const __m256i tmp_rnd = _mm256_add_epi32(abs_coeff, *round); - const __m256i abs_q = mm256_mul_shift_epi32_logscale(&tmp_rnd, quant, 0); - const __m256i abs_dq = _mm256_mullo_epi32(abs_q, *dequant); - const __m256i q = _mm256_sign_epi32(abs_q, coeff); - const __m256i dq = _mm256_sign_epi32(abs_dq, coeff); - const __m256i nz_mask = _mm256_cmpgt_epi32(abs_q, _mm256_setzero_si256()); - - _mm256_storeu_si256((__m256i *)qcoeff_ptr, q); - _mm256_storeu_si256((__m256i *)dqcoeff_ptr, dq); - - *eob = highbd_get_max_lane_eob(iscan_ptr, *eob, nz_mask); -} - -void vp9_highbd_quantize_fp_avx2(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - const int step = 8; - __m256i round, quant, dequant; - __m256i eob_max = _mm256_setzero_si256(); - const int16_t *iscan = scan_order->iscan; - - coeff_ptr += n_coeffs; - iscan += n_coeffs; - qcoeff_ptr += n_coeffs; - dqcoeff_ptr += n_coeffs; - n_coeffs = -n_coeffs; - - // Setup global values - highbd_load_fp_values(mb_plane, &round, &quant, dequant_ptr, &dequant); - - highbd_quantize_fp(&round, &quant, &dequant, coeff_ptr + n_coeffs, - iscan + n_coeffs, qcoeff_ptr + n_coeffs, - dqcoeff_ptr + n_coeffs, &eob_max); - - n_coeffs += step; - - // remove dc constants - dequant = _mm256_permute2x128_si256(dequant, dequant, 0x31); - quant = _mm256_permute2x128_si256(quant, quant, 0x31); - round = _mm256_permute2x128_si256(round, round, 0x31); - - // AC only loop - while (n_coeffs < 0) { - highbd_quantize_fp(&round, &quant, &dequant, coeff_ptr + n_coeffs, - iscan + n_coeffs, qcoeff_ptr + n_coeffs, - dqcoeff_ptr + n_coeffs, &eob_max); - n_coeffs += step; - } - - *eob_ptr = get_max_eob(eob_max); -} - -static VPX_FORCE_INLINE void highbd_quantize_fp_32x32( - const __m256i *round, const __m256i *quant, const __m256i *dequant, - const __m256i *thr, const tran_low_t *coeff_ptr, const int16_t *iscan_ptr, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, __m256i *eob) { - const __m256i coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr); - const __m256i abs_coeff = _mm256_abs_epi32(coeff); - const __m256i thr_mask = _mm256_cmpgt_epi32(abs_coeff, *thr); - const __m256i tmp_rnd = - _mm256_and_si256(_mm256_add_epi32(abs_coeff, *round), thr_mask); - const __m256i abs_q = mm256_mul_shift_epi32_logscale(&tmp_rnd, quant, 0); - const __m256i abs_dq = - _mm256_srli_epi32(_mm256_mullo_epi32(abs_q, *dequant), 1); - const __m256i q = _mm256_sign_epi32(abs_q, coeff); - const __m256i dq = _mm256_sign_epi32(abs_dq, coeff); - const __m256i nz_mask = _mm256_cmpgt_epi32(abs_q, _mm256_setzero_si256()); - - _mm256_storeu_si256((__m256i *)qcoeff_ptr, q); - _mm256_storeu_si256((__m256i *)dqcoeff_ptr, dq); - - *eob = highbd_get_max_lane_eob(iscan_ptr, *eob, nz_mask); -} - -void vp9_highbd_quantize_fp_32x32_avx2( - const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - const int step = 8; - __m256i round, quant, dequant, thr; - __m256i eob_max = _mm256_setzero_si256(); - const int16_t *iscan = scan_order->iscan; - - coeff_ptr += n_coeffs; - iscan += n_coeffs; - qcoeff_ptr += n_coeffs; - dqcoeff_ptr += n_coeffs; - n_coeffs = -n_coeffs; - - // Setup global values - highbd_load_fp_values(mb_plane, &round, &quant, dequant_ptr, &dequant); - thr = _mm256_srli_epi32(dequant, 2); - // Subtracting 1 here eliminates a _mm256_cmpeq_epi32() instruction when - // calculating the zbin mask. - thr = _mm256_sub_epi32(thr, _mm256_set1_epi32(1)); - quant = _mm256_slli_epi32(quant, 1); - round = _mm256_srai_epi32(_mm256_add_epi32(round, _mm256_set1_epi32(1)), 1); - - highbd_quantize_fp_32x32(&round, &quant, &dequant, &thr, coeff_ptr + n_coeffs, - iscan + n_coeffs, qcoeff_ptr + n_coeffs, - dqcoeff_ptr + n_coeffs, &eob_max); - - n_coeffs += step; - - // remove dc constants - dequant = _mm256_permute2x128_si256(dequant, dequant, 0x31); - quant = _mm256_permute2x128_si256(quant, quant, 0x31); - round = _mm256_permute2x128_si256(round, round, 0x31); - thr = _mm256_permute2x128_si256(thr, thr, 0x31); - - // AC only loop - while (n_coeffs < 0) { - highbd_quantize_fp_32x32( - &round, &quant, &dequant, &thr, coeff_ptr + n_coeffs, iscan + n_coeffs, - qcoeff_ptr + n_coeffs, dqcoeff_ptr + n_coeffs, &eob_max); - n_coeffs += step; - } - - *eob_ptr = get_max_eob(eob_max); -} -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_quantize_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_quantize_sse2.c deleted file mode 100644 index 2481eb36..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_quantize_sse2.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "./vp9_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/x86/bitdepth_conversion_sse2.h" -#include "vpx_dsp/x86/quantize_sse2.h" -#include "vp9/common/vp9_scan.h" -#include "vp9/encoder/vp9_block.h" - -void vp9_quantize_fp_sse2(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - const __m128i zero = _mm_setzero_si128(); - __m128i thr; - int nzflag; - int index = 16; - __m128i round, quant, dequant; - __m128i coeff0, coeff1, coeff0_sign, coeff1_sign; - __m128i qcoeff0, qcoeff1; - __m128i eob; - const int16_t *iscan = scan_order->iscan; - - // Setup global values. - load_fp_values(mb_plane, &round, &quant, dequant_ptr, &dequant); - - // Do DC and first 15 AC. - coeff0 = load_tran_low(coeff_ptr); - coeff1 = load_tran_low(coeff_ptr + 8); - - // Poor man's abs(). - coeff0_sign = _mm_srai_epi16(coeff0, 15); - coeff1_sign = _mm_srai_epi16(coeff1, 15); - qcoeff0 = invert_sign_sse2(coeff0, coeff0_sign); - qcoeff1 = invert_sign_sse2(coeff1, coeff1_sign); - - qcoeff0 = _mm_adds_epi16(qcoeff0, round); - qcoeff0 = _mm_mulhi_epi16(qcoeff0, quant); - - round = _mm_unpackhi_epi64(round, round); - quant = _mm_unpackhi_epi64(quant, quant); - - qcoeff1 = _mm_adds_epi16(qcoeff1, round); - qcoeff1 = _mm_mulhi_epi16(qcoeff1, quant); - - // Reinsert signs. - qcoeff0 = invert_sign_sse2(qcoeff0, coeff0_sign); - qcoeff1 = invert_sign_sse2(qcoeff1, coeff1_sign); - - store_tran_low(qcoeff0, qcoeff_ptr); - store_tran_low(qcoeff1, qcoeff_ptr + 8); - - qcoeff0 = _mm_mullo_epi16(qcoeff0, dequant); - dequant = _mm_unpackhi_epi64(dequant, dequant); - qcoeff1 = _mm_mullo_epi16(qcoeff1, dequant); - - store_tran_low(qcoeff0, dqcoeff_ptr); - store_tran_low(qcoeff1, dqcoeff_ptr + 8); - - eob = scan_for_eob(&qcoeff0, &qcoeff1, iscan, 0, zero); - - thr = _mm_srai_epi16(dequant, 1); - - // AC only loop. - while (index < n_coeffs) { - coeff0 = load_tran_low(coeff_ptr + index); - coeff1 = load_tran_low(coeff_ptr + index + 8); - - // Poor man's abs(). - coeff0_sign = _mm_srai_epi16(coeff0, 15); - coeff1_sign = _mm_srai_epi16(coeff1, 15); - qcoeff0 = invert_sign_sse2(coeff0, coeff0_sign); - qcoeff1 = invert_sign_sse2(coeff1, coeff1_sign); - - nzflag = _mm_movemask_epi8(_mm_cmpgt_epi16(qcoeff0, thr)) | - _mm_movemask_epi8(_mm_cmpgt_epi16(qcoeff1, thr)); - - if (nzflag) { - __m128i eob0; - qcoeff0 = _mm_adds_epi16(qcoeff0, round); - qcoeff1 = _mm_adds_epi16(qcoeff1, round); - qcoeff0 = _mm_mulhi_epi16(qcoeff0, quant); - qcoeff1 = _mm_mulhi_epi16(qcoeff1, quant); - - // Reinsert signs. - qcoeff0 = invert_sign_sse2(qcoeff0, coeff0_sign); - qcoeff1 = invert_sign_sse2(qcoeff1, coeff1_sign); - - store_tran_low(qcoeff0, qcoeff_ptr + index); - store_tran_low(qcoeff1, qcoeff_ptr + index + 8); - - qcoeff0 = _mm_mullo_epi16(qcoeff0, dequant); - qcoeff1 = _mm_mullo_epi16(qcoeff1, dequant); - - store_tran_low(qcoeff0, dqcoeff_ptr + index); - store_tran_low(qcoeff1, dqcoeff_ptr + index + 8); - - eob0 = scan_for_eob(&qcoeff0, &qcoeff1, iscan, index, zero); - eob = _mm_max_epi16(eob, eob0); - } else { - store_zero_tran_low(qcoeff_ptr + index); - store_zero_tran_low(qcoeff_ptr + index + 8); - - store_zero_tran_low(dqcoeff_ptr + index); - store_zero_tran_low(dqcoeff_ptr + index + 8); - } - - index += 16; - } - - *eob_ptr = accumulate_eob(eob); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_quantize_ssse3.c b/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_quantize_ssse3.c deleted file mode 100644 index 98decae7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/encoder/x86/vp9_quantize_ssse3.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vp9_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/x86/bitdepth_conversion_sse2.h" -#include "vpx_dsp/x86/quantize_sse2.h" -#include "vpx_dsp/x86/quantize_ssse3.h" -#include "vp9/common/vp9_scan.h" -#include "vp9/encoder/vp9_block.h" - -void vp9_quantize_fp_ssse3(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - const __m128i zero = _mm_setzero_si128(); - __m128i thr; - int nzflag; - int index = 16; - __m128i round, quant, dequant; - __m128i coeff0, coeff1; - __m128i qcoeff0, qcoeff1; - __m128i eob; - const int16_t *iscan = scan_order->iscan; - - // Setup global values. - load_fp_values(mb_plane, &round, &quant, dequant_ptr, &dequant); - - // Do DC and first 15 AC. - coeff0 = load_tran_low(coeff_ptr); - coeff1 = load_tran_low(coeff_ptr + 8); - - qcoeff0 = _mm_abs_epi16(coeff0); - qcoeff1 = _mm_abs_epi16(coeff1); - - qcoeff0 = _mm_adds_epi16(qcoeff0, round); - qcoeff0 = _mm_mulhi_epi16(qcoeff0, quant); - - round = _mm_unpackhi_epi64(round, round); - quant = _mm_unpackhi_epi64(quant, quant); - - qcoeff1 = _mm_adds_epi16(qcoeff1, round); - qcoeff1 = _mm_mulhi_epi16(qcoeff1, quant); - - // Reinsert signs. - qcoeff0 = _mm_sign_epi16(qcoeff0, coeff0); - qcoeff1 = _mm_sign_epi16(qcoeff1, coeff1); - - store_tran_low(qcoeff0, qcoeff_ptr); - store_tran_low(qcoeff1, qcoeff_ptr + 8); - - qcoeff0 = _mm_mullo_epi16(qcoeff0, dequant); - dequant = _mm_unpackhi_epi64(dequant, dequant); - qcoeff1 = _mm_mullo_epi16(qcoeff1, dequant); - - store_tran_low(qcoeff0, dqcoeff_ptr); - store_tran_low(qcoeff1, dqcoeff_ptr + 8); - - eob = scan_for_eob(&qcoeff0, &qcoeff1, iscan, 0, zero); - - thr = _mm_srai_epi16(dequant, 1); - - // AC only loop. - while (index < n_coeffs) { - coeff0 = load_tran_low(coeff_ptr + index); - coeff1 = load_tran_low(coeff_ptr + index + 8); - - qcoeff0 = _mm_abs_epi16(coeff0); - qcoeff1 = _mm_abs_epi16(coeff1); - - nzflag = _mm_movemask_epi8(_mm_cmpgt_epi16(qcoeff0, thr)) | - _mm_movemask_epi8(_mm_cmpgt_epi16(qcoeff1, thr)); - - if (nzflag) { - __m128i eob0; - qcoeff0 = _mm_adds_epi16(qcoeff0, round); - qcoeff1 = _mm_adds_epi16(qcoeff1, round); - qcoeff0 = _mm_mulhi_epi16(qcoeff0, quant); - qcoeff1 = _mm_mulhi_epi16(qcoeff1, quant); - - // Reinsert signs. - qcoeff0 = _mm_sign_epi16(qcoeff0, coeff0); - qcoeff1 = _mm_sign_epi16(qcoeff1, coeff1); - - store_tran_low(qcoeff0, qcoeff_ptr + index); - store_tran_low(qcoeff1, qcoeff_ptr + index + 8); - - qcoeff0 = _mm_mullo_epi16(qcoeff0, dequant); - qcoeff1 = _mm_mullo_epi16(qcoeff1, dequant); - - store_tran_low(qcoeff0, dqcoeff_ptr + index); - store_tran_low(qcoeff1, dqcoeff_ptr + index + 8); - - eob0 = scan_for_eob(&qcoeff0, &qcoeff1, iscan, index, zero); - eob = _mm_max_epi16(eob, eob0); - } else { - store_zero_tran_low(qcoeff_ptr + index); - store_zero_tran_low(qcoeff_ptr + index + 8); - - store_zero_tran_low(dqcoeff_ptr + index); - store_zero_tran_low(dqcoeff_ptr + index + 8); - } - - index += 16; - } - - *eob_ptr = accumulate_eob(eob); -} - -void vp9_quantize_fp_32x32_ssse3(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - const __m128i zero = _mm_setzero_si128(); - const __m128i one_s16 = _mm_set1_epi16(1); - __m128i thr; - int nzflag; - int index = 16; - __m128i round, quant, dequant; - __m128i coeff0, coeff1; - __m128i qcoeff0, qcoeff1; - __m128i eob; - const int16_t *iscan = scan_order->iscan; - - // Setup global values. - load_fp_values(mb_plane, &round, &quant, dequant_ptr, &dequant); - // The 32x32 halves round. - round = _mm_add_epi16(round, one_s16); - round = _mm_srli_epi16(round, 1); - - // The 16x16 shifts by 16, the 32x32 shifts by 15. We want to use pmulhw so - // upshift quant to account for this. - quant = _mm_slli_epi16(quant, 1); - - // Do DC and first 15 AC. - coeff0 = load_tran_low(coeff_ptr); - coeff1 = load_tran_low(coeff_ptr + 8); - - qcoeff0 = _mm_abs_epi16(coeff0); - qcoeff1 = _mm_abs_epi16(coeff1); - - qcoeff0 = _mm_adds_epi16(qcoeff0, round); - qcoeff0 = _mm_mulhi_epi16(qcoeff0, quant); - - round = _mm_unpackhi_epi64(round, round); - quant = _mm_unpackhi_epi64(quant, quant); - - qcoeff1 = _mm_adds_epi16(qcoeff1, round); - qcoeff1 = _mm_mulhi_epi16(qcoeff1, quant); - - // Reinsert signs. - qcoeff0 = _mm_sign_epi16(qcoeff0, coeff0); - qcoeff1 = _mm_sign_epi16(qcoeff1, coeff1); - - store_tran_low(qcoeff0, qcoeff_ptr); - store_tran_low(qcoeff1, qcoeff_ptr + 8); - - // Get the abs value of qcoeff again so we can use shifts for division. - qcoeff0 = _mm_abs_epi16(qcoeff0); - qcoeff1 = _mm_abs_epi16(qcoeff1); - - qcoeff0 = _mm_mullo_epi16(qcoeff0, dequant); - dequant = _mm_unpackhi_epi64(dequant, dequant); - qcoeff1 = _mm_mullo_epi16(qcoeff1, dequant); - - // Divide by 2. - qcoeff0 = _mm_srli_epi16(qcoeff0, 1); - qcoeff1 = _mm_srli_epi16(qcoeff1, 1); - - // Reinsert signs. - qcoeff0 = _mm_sign_epi16(qcoeff0, coeff0); - qcoeff1 = _mm_sign_epi16(qcoeff1, coeff1); - - store_tran_low(qcoeff0, dqcoeff_ptr); - store_tran_low(qcoeff1, dqcoeff_ptr + 8); - - eob = scan_for_eob(&qcoeff0, &qcoeff1, iscan, 0, zero); - - thr = _mm_srai_epi16(dequant, 2); - - // AC only loop. - while (index < n_coeffs) { - coeff0 = load_tran_low(coeff_ptr + index); - coeff1 = load_tran_low(coeff_ptr + index + 8); - - qcoeff0 = _mm_abs_epi16(coeff0); - qcoeff1 = _mm_abs_epi16(coeff1); - - nzflag = _mm_movemask_epi8(_mm_cmpgt_epi16(qcoeff0, thr)) | - _mm_movemask_epi8(_mm_cmpgt_epi16(qcoeff1, thr)); - - if (nzflag) { - qcoeff0 = _mm_adds_epi16(qcoeff0, round); - qcoeff1 = _mm_adds_epi16(qcoeff1, round); - qcoeff0 = _mm_mulhi_epi16(qcoeff0, quant); - qcoeff1 = _mm_mulhi_epi16(qcoeff1, quant); - - // Reinsert signs. - qcoeff0 = _mm_sign_epi16(qcoeff0, coeff0); - qcoeff1 = _mm_sign_epi16(qcoeff1, coeff1); - - store_tran_low(qcoeff0, qcoeff_ptr + index); - store_tran_low(qcoeff1, qcoeff_ptr + index + 8); - - // Get the abs value of qcoeff again so we can use shifts for division. - qcoeff0 = _mm_abs_epi16(qcoeff0); - qcoeff1 = _mm_abs_epi16(qcoeff1); - - qcoeff0 = _mm_mullo_epi16(qcoeff0, dequant); - qcoeff1 = _mm_mullo_epi16(qcoeff1, dequant); - - // Divide by 2. - qcoeff0 = _mm_srli_epi16(qcoeff0, 1); - qcoeff1 = _mm_srli_epi16(qcoeff1, 1); - - // Reinsert signs. - qcoeff0 = _mm_sign_epi16(qcoeff0, coeff0); - qcoeff1 = _mm_sign_epi16(qcoeff1, coeff1); - - store_tran_low(qcoeff0, dqcoeff_ptr + index); - store_tran_low(qcoeff1, dqcoeff_ptr + index + 8); - } else { - store_zero_tran_low(qcoeff_ptr + index); - store_zero_tran_low(qcoeff_ptr + index + 8); - - store_zero_tran_low(dqcoeff_ptr + index); - store_zero_tran_low(dqcoeff_ptr + index + 8); - } - - if (nzflag) { - const __m128i eob0 = scan_for_eob(&qcoeff0, &qcoeff1, iscan, index, zero); - eob = _mm_max_epi16(eob, eob0); - } - index += 16; - } - - *eob_ptr = accumulate_eob(eob); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/exports_dec b/presentation/src/main/cpp/third_party/libvpx/vp9/exports_dec deleted file mode 100644 index 0a61fde3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/exports_dec +++ /dev/null @@ -1,2 +0,0 @@ -data vpx_codec_vp9_dx_algo -text vpx_codec_vp9_dx diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/exports_enc b/presentation/src/main/cpp/third_party/libvpx/vp9/exports_enc deleted file mode 100644 index 2a0fef3e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/exports_enc +++ /dev/null @@ -1,2 +0,0 @@ -data vpx_codec_vp9_cx_algo -text vpx_codec_vp9_cx diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/ratectrl_rtc.cc b/presentation/src/main/cpp/third_party/libvpx/vp9/ratectrl_rtc.cc deleted file mode 100644 index b29e1ec2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/ratectrl_rtc.cc +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Copyright (c) 2020 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "vp9/ratectrl_rtc.h" - -#include - -#include "vp9/common/vp9_common.h" -#include "vp9/encoder/vp9_aq_cyclicrefresh.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_picklpf.h" -#include "vpx/vp8cx.h" -#include "vpx/vpx_codec.h" -#include "vpx_mem/vpx_mem.h" - -namespace libvpx { - -std::unique_ptr VP9RateControlRTC::Create( - const VP9RateControlRtcConfig &cfg) { - std::unique_ptr rc_api(new (std::nothrow) - VP9RateControlRTC()); - if (!rc_api) return nullptr; - rc_api->cpi_ = static_cast(vpx_memalign(32, sizeof(*cpi_))); - if (!rc_api->cpi_) return nullptr; - vp9_zero(*rc_api->cpi_); - - if (!rc_api->InitRateControl(cfg)) return nullptr; - if (cfg.aq_mode) { - VP9_COMP *const cpi = rc_api->cpi_; - cpi->segmentation_map = static_cast( - vpx_calloc(cpi->common.mi_rows * cpi->common.mi_cols, - sizeof(*cpi->segmentation_map))); - if (!cpi->segmentation_map) return nullptr; - cpi->cyclic_refresh = - vp9_cyclic_refresh_alloc(cpi->common.mi_rows, cpi->common.mi_cols); - cpi->cyclic_refresh->content_mode = 0; - } - return rc_api; -} - -VP9RateControlRTC::~VP9RateControlRTC() { - if (cpi_) { - if (cpi_->svc.number_spatial_layers > 1 || - cpi_->svc.number_temporal_layers > 1) { - for (int sl = 0; sl < cpi_->svc.number_spatial_layers; sl++) { - for (int tl = 0; tl < cpi_->svc.number_temporal_layers; tl++) { - int layer = LAYER_IDS_TO_IDX(sl, tl, cpi_->oxcf.ts_number_layers); - LAYER_CONTEXT *const lc = &cpi_->svc.layer_context[layer]; - vpx_free(lc->map); - vpx_free(lc->last_coded_q_map); - vpx_free(lc->consec_zero_mv); - } - } - } - if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ) { - vpx_free(cpi_->segmentation_map); - cpi_->segmentation_map = NULL; - vp9_cyclic_refresh_free(cpi_->cyclic_refresh); - } - vpx_free(cpi_); - } -} - -bool VP9RateControlRTC::InitRateControl(const VP9RateControlRtcConfig &rc_cfg) { - VP9_COMMON *cm = &cpi_->common; - VP9EncoderConfig *oxcf = &cpi_->oxcf; - RATE_CONTROL *const rc = &cpi_->rc; - cm->profile = PROFILE_0; - cm->bit_depth = VPX_BITS_8; - cm->show_frame = 1; - oxcf->profile = cm->profile; - oxcf->bit_depth = cm->bit_depth; - oxcf->rc_mode = rc_cfg.rc_mode; - oxcf->pass = 0; - oxcf->aq_mode = rc_cfg.aq_mode ? CYCLIC_REFRESH_AQ : NO_AQ; - oxcf->content = VP9E_CONTENT_DEFAULT; - oxcf->drop_frames_water_mark = 0; - cm->current_video_frame = 0; - rc->kf_boost = DEFAULT_KF_BOOST; - - if (!UpdateRateControl(rc_cfg)) return false; - vp9_set_mb_mi(cm, cm->width, cm->height); - - cpi_->use_svc = (cpi_->svc.number_spatial_layers > 1 || - cpi_->svc.number_temporal_layers > 1) - ? 1 - : 0; - - rc->rc_1_frame = 0; - rc->rc_2_frame = 0; - vp9_rc_init_minq_luts(); - vp9_rc_init(oxcf, 0, rc); - rc->constrain_gf_key_freq_onepass_vbr = 0; - cpi_->sf.use_nonrd_pick_mode = 1; - return true; -} - -bool VP9RateControlRTC::UpdateRateControl( - const VP9RateControlRtcConfig &rc_cfg) { - // Since VPX_MAX_LAYERS (12) is less than the product of VPX_SS_MAX_LAYERS (5) - // and VPX_TS_MAX_LAYERS (5), check all three. - if (rc_cfg.ss_number_layers < 1 || - rc_cfg.ss_number_layers > VPX_SS_MAX_LAYERS || - rc_cfg.ts_number_layers < 1 || - rc_cfg.ts_number_layers > VPX_TS_MAX_LAYERS || - rc_cfg.ss_number_layers * rc_cfg.ts_number_layers > VPX_MAX_LAYERS) { - return false; - } - - VP9_COMMON *cm = &cpi_->common; - VP9EncoderConfig *oxcf = &cpi_->oxcf; - RATE_CONTROL *const rc = &cpi_->rc; - - cm->width = rc_cfg.width; - cm->height = rc_cfg.height; - oxcf->width = rc_cfg.width; - oxcf->height = rc_cfg.height; - oxcf->worst_allowed_q = vp9_quantizer_to_qindex(rc_cfg.max_quantizer); - oxcf->best_allowed_q = vp9_quantizer_to_qindex(rc_cfg.min_quantizer); - rc->worst_quality = oxcf->worst_allowed_q; - rc->best_quality = oxcf->best_allowed_q; - oxcf->init_framerate = rc_cfg.framerate; - oxcf->target_bandwidth = 1000 * rc_cfg.target_bandwidth; - oxcf->starting_buffer_level_ms = rc_cfg.buf_initial_sz; - oxcf->optimal_buffer_level_ms = rc_cfg.buf_optimal_sz; - oxcf->maximum_buffer_size_ms = rc_cfg.buf_sz; - oxcf->under_shoot_pct = rc_cfg.undershoot_pct; - oxcf->over_shoot_pct = rc_cfg.overshoot_pct; - oxcf->drop_frames_water_mark = rc_cfg.frame_drop_thresh; - oxcf->content = rc_cfg.is_screen ? VP9E_CONTENT_SCREEN : VP9E_CONTENT_DEFAULT; - oxcf->ss_number_layers = rc_cfg.ss_number_layers; - oxcf->ts_number_layers = rc_cfg.ts_number_layers; - oxcf->temporal_layering_mode = - (VP9E_TEMPORAL_LAYERING_MODE)((rc_cfg.ts_number_layers > 1) - ? rc_cfg.ts_number_layers - : 0); - - cpi_->oxcf.rc_max_intra_bitrate_pct = rc_cfg.max_intra_bitrate_pct; - cpi_->oxcf.rc_max_inter_bitrate_pct = rc_cfg.max_inter_bitrate_pct; - cpi_->framerate = rc_cfg.framerate; - cpi_->svc.number_spatial_layers = rc_cfg.ss_number_layers; - cpi_->svc.number_temporal_layers = rc_cfg.ts_number_layers; - - vp9_set_mb_mi(cm, cm->width, cm->height); - - if (setjmp(cpi_->common.error.jmp)) { - cpi_->common.error.setjmp = 0; - vpx_clear_system_state(); - return false; - } - cpi_->common.error.setjmp = 1; - - for (int tl = 0; tl < cpi_->svc.number_temporal_layers; ++tl) { - oxcf->ts_rate_decimator[tl] = rc_cfg.ts_rate_decimator[tl]; - } - for (int sl = 0; sl < cpi_->svc.number_spatial_layers; ++sl) { - for (int tl = 0; tl < cpi_->svc.number_temporal_layers; ++tl) { - const int layer = - LAYER_IDS_TO_IDX(sl, tl, cpi_->svc.number_temporal_layers); - LAYER_CONTEXT *lc = &cpi_->svc.layer_context[layer]; - RATE_CONTROL *const lrc = &lc->rc; - oxcf->layer_target_bitrate[layer] = - 1000 * rc_cfg.layer_target_bitrate[layer]; - lrc->worst_quality = - vp9_quantizer_to_qindex(rc_cfg.max_quantizers[layer]); - lrc->best_quality = vp9_quantizer_to_qindex(rc_cfg.min_quantizers[layer]); - lc->scaling_factor_num = rc_cfg.scaling_factor_num[sl]; - lc->scaling_factor_den = rc_cfg.scaling_factor_den[sl]; - } - } - vp9_set_rc_buffer_sizes(cpi_); - vp9_new_framerate(cpi_, cpi_->framerate); - if (cpi_->svc.number_temporal_layers > 1 || - cpi_->svc.number_spatial_layers > 1) { - if (cm->current_video_frame == 0) { - vp9_init_layer_context(cpi_); - // svc->framedrop_mode is not currently exposed, so only allow for - // full superframe drop for now. - cpi_->svc.framedrop_mode = FULL_SUPERFRAME_DROP; - } - vp9_update_layer_context_change_config(cpi_, - (int)cpi_->oxcf.target_bandwidth); - cpi_->svc.max_consec_drop = rc_cfg.max_consec_drop; - } - vp9_check_reset_rc_flag(cpi_); - - cpi_->common.error.setjmp = 0; - return true; -} - -// Compute the QP for the frame. If the frame is dropped this function -// returns kDrop, and no QP is computed. If the frame is encoded (not dropped) -// the QP is computed and kOk is returned. -FrameDropDecision VP9RateControlRTC::ComputeQP( - const VP9FrameParamsQpRTC &frame_params) { - VP9_COMMON *const cm = &cpi_->common; - int width, height; - cpi_->svc.spatial_layer_id = frame_params.spatial_layer_id; - cpi_->svc.temporal_layer_id = frame_params.temporal_layer_id; - if (cpi_->svc.number_spatial_layers > 1) { - const int layer = LAYER_IDS_TO_IDX(cpi_->svc.spatial_layer_id, - cpi_->svc.temporal_layer_id, - cpi_->svc.number_temporal_layers); - LAYER_CONTEXT *lc = &cpi_->svc.layer_context[layer]; - get_layer_resolution(cpi_->oxcf.width, cpi_->oxcf.height, - lc->scaling_factor_num, lc->scaling_factor_den, &width, - &height); - cm->width = width; - cm->height = height; - } - vp9_set_mb_mi(cm, cm->width, cm->height); - cm->frame_type = static_cast(frame_params.frame_type); - // This is needed to ensure key frame does not get unset in rc_get_svc_params. - cpi_->frame_flags = (cm->frame_type == KEY_FRAME) ? FRAMEFLAGS_KEY : 0; - cpi_->refresh_golden_frame = (cm->frame_type == KEY_FRAME) ? 1 : 0; - cpi_->sf.use_nonrd_pick_mode = 1; - if (cpi_->svc.number_spatial_layers == 1 && - cpi_->svc.number_temporal_layers == 1) { - int target = 0; - if (cpi_->oxcf.rc_mode == VPX_CBR) { - if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ) - vp9_cyclic_refresh_update_parameters(cpi_); - if (frame_is_intra_only(cm)) - target = vp9_calc_iframe_target_size_one_pass_cbr(cpi_); - else - target = vp9_calc_pframe_target_size_one_pass_cbr(cpi_); - } else if (cpi_->oxcf.rc_mode == VPX_VBR) { - if (cm->frame_type == KEY_FRAME) { - cpi_->rc.this_key_frame_forced = cm->current_video_frame != 0; - cpi_->rc.frames_to_key = cpi_->oxcf.key_freq; - } - vp9_set_gf_update_one_pass_vbr(cpi_); - if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ) - vp9_cyclic_refresh_update_parameters(cpi_); - if (frame_is_intra_only(cm)) - target = vp9_calc_iframe_target_size_one_pass_vbr(cpi_); - else - target = vp9_calc_pframe_target_size_one_pass_vbr(cpi_); - } - vp9_rc_set_frame_target(cpi_, target); - vp9_update_buffer_level_preencode(cpi_); - } else { - vp9_update_temporal_layer_framerate(cpi_); - vp9_restore_layer_context(cpi_); - vp9_rc_get_svc_params(cpi_); - } - if (cpi_->svc.spatial_layer_id == 0) vp9_zero(cpi_->svc.drop_spatial_layer); - // SVC: check for skip encoding of enhancement layer if the - // layer target bandwidth = 0. - if (vp9_svc_check_skip_enhancement_layer(cpi_)) - return FrameDropDecision::kDrop; - // Check for dropping this frame based on buffer level. - // Never drop on key frame, or if base layer is key for svc, - if (!frame_is_intra_only(cm) && - (!cpi_->use_svc || - !cpi_->svc.layer_context[cpi_->svc.temporal_layer_id].is_key_frame)) { - if (vp9_rc_drop_frame(cpi_)) { - // For FULL_SUPERFRAME_DROP mode (the only mode considered here): - // if the superframe drop is decided we need to save the layer context for - // all spatial layers, and call update_buffer_level and postencode_drop - // for all spatial layers. - if (cpi_->svc.number_spatial_layers > 1 || - cpi_->svc.number_temporal_layers > 1) { - vp9_save_layer_context(cpi_); - for (int sl = 1; sl < cpi_->svc.number_spatial_layers; sl++) { - cpi_->svc.spatial_layer_id = sl; - vp9_restore_layer_context(cpi_); - vp9_update_buffer_level_svc_preencode(cpi_); - vp9_rc_postencode_update_drop_frame(cpi_); - vp9_save_layer_context(cpi_); - } - } - return FrameDropDecision::kDrop; - } - } - // Compute the QP for the frame. - int bottom_index, top_index; - cpi_->common.base_qindex = - vp9_rc_pick_q_and_bounds(cpi_, &bottom_index, &top_index); - - if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ) vp9_cyclic_refresh_setup(cpi_); - if (cpi_->svc.number_spatial_layers > 1 || - cpi_->svc.number_temporal_layers > 1) - vp9_save_layer_context(cpi_); - - cpi_->last_frame_dropped = 0; - cpi_->svc.last_layer_dropped[cpi_->svc.spatial_layer_id] = 0; - if (cpi_->svc.spatial_layer_id == cpi_->svc.number_spatial_layers - 1) - cpi_->svc.num_encoded_top_layer++; - - return FrameDropDecision::kOk; -} - -int VP9RateControlRTC::GetQP() const { return cpi_->common.base_qindex; } - -int VP9RateControlRTC::GetLoopfilterLevel() const { - struct loopfilter *const lf = &cpi_->common.lf; - vp9_pick_filter_level(nullptr, cpi_, LPF_PICK_FROM_Q); - return lf->filter_level; -} - -bool VP9RateControlRTC::GetSegmentationData( - VP9SegmentationData *segmentation_data) const { - if (!cpi_->cyclic_refresh || !cpi_->cyclic_refresh->apply_cyclic_refresh) { - return false; - } - - segmentation_data->segmentation_map = cpi_->segmentation_map; - segmentation_data->segmentation_map_size = - cpi_->common.mi_cols * cpi_->common.mi_rows; - segmentation_data->delta_q = cpi_->cyclic_refresh->qindex_delta; - segmentation_data->delta_q_size = 3u; - return true; -} - -void VP9RateControlRTC::PostEncodeUpdate( - uint64_t encoded_frame_size, const VP9FrameParamsQpRTC &frame_params) { - cpi_->common.frame_type = static_cast(frame_params.frame_type); - cpi_->svc.spatial_layer_id = frame_params.spatial_layer_id; - cpi_->svc.temporal_layer_id = frame_params.temporal_layer_id; - if (cpi_->svc.number_spatial_layers > 1 || - cpi_->svc.number_temporal_layers > 1) { - vp9_restore_layer_context(cpi_); - const int layer = LAYER_IDS_TO_IDX(cpi_->svc.spatial_layer_id, - cpi_->svc.temporal_layer_id, - cpi_->svc.number_temporal_layers); - LAYER_CONTEXT *lc = &cpi_->svc.layer_context[layer]; - cpi_->common.base_qindex = lc->frame_qp; - cpi_->common.MBs = lc->MBs; - // For spatial-svc, allow cyclic-refresh to be applied on the spatial - // layers, for the base temporal layer. - if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ && - cpi_->svc.number_spatial_layers > 1 && - cpi_->svc.temporal_layer_id == 0) { - CYCLIC_REFRESH *const cr = cpi_->cyclic_refresh; - cr->qindex_delta[0] = lc->qindex_delta[0]; - cr->qindex_delta[1] = lc->qindex_delta[1]; - cr->qindex_delta[2] = lc->qindex_delta[2]; - } - } - vp9_rc_postencode_update(cpi_, encoded_frame_size); - if (cpi_->svc.number_spatial_layers > 1 || - cpi_->svc.number_temporal_layers > 1) - vp9_save_layer_context(cpi_); - cpi_->common.current_video_frame++; -} - -} // namespace libvpx diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/ratectrl_rtc.h b/presentation/src/main/cpp/third_party/libvpx/vp9/ratectrl_rtc.h deleted file mode 100644 index 4c392558..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/ratectrl_rtc.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2020 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_RATECTRL_RTC_H_ -#define VPX_VP9_RATECTRL_RTC_H_ - -#include -#include -#include -#include - -#include "vpx/vpx_encoder.h" -#include "vpx/internal/vpx_ratectrl_rtc.h" - -struct VP9_COMP; - -namespace libvpx { -struct VP9RateControlRtcConfig : public VpxRateControlRtcConfig { - VP9RateControlRtcConfig() { - memset(layer_target_bitrate, 0, sizeof(layer_target_bitrate)); - memset(ts_rate_decimator, 0, sizeof(ts_rate_decimator)); - scaling_factor_num[0] = 1; - scaling_factor_den[0] = 1; - max_quantizers[0] = max_quantizer; - min_quantizers[0] = min_quantizer; - } - - // Number of spatial layers - int ss_number_layers = 1; - int max_quantizers[VPX_MAX_LAYERS] = {}; - int min_quantizers[VPX_MAX_LAYERS] = {}; - int scaling_factor_num[VPX_SS_MAX_LAYERS] = {}; - int scaling_factor_den[VPX_SS_MAX_LAYERS] = {}; - // This is only for SVC for now. - int max_consec_drop = std::numeric_limits::max(); -}; - -struct VP9FrameParamsQpRTC { - RcFrameType frame_type; - int spatial_layer_id; - int temporal_layer_id; -}; - -struct VP9SegmentationData { - const uint8_t *segmentation_map; - size_t segmentation_map_size; - const int *delta_q; - size_t delta_q_size; -}; - -// This interface allows using VP9 real-time rate control without initializing -// the encoder. To use this interface, you need to link with libvpxrc.a. -// -// #include "vp9/ratectrl_rtc.h" -// VP9RateControlRtcConfig cfg; -// VP9FrameParamsQpRTC frame_params; -// -// YourFunctionToInitializeConfig(cfg); -// std::unique_ptr rc_api = VP9RateControlRTC::Create(cfg); -// // start encoding -// while (frame_to_encode) { -// if (config_changed) -// rc_api->UpdateRateControl(cfg); -// YourFunctionToFillFrameParams(frame_params); -// rc_api->ComputeQP(frame_params); -// YourFunctionToUseQP(rc_api->GetQP()); -// YourFunctionToUseLoopfilter(rc_api->GetLoopfilterLevel()); -// // After encoding -// rc_api->PostEncode(encoded_frame_size, frame_params); -// } -class VP9RateControlRTC { - public: - static std::unique_ptr Create( - const VP9RateControlRtcConfig &cfg); - ~VP9RateControlRTC(); - - bool UpdateRateControl(const VP9RateControlRtcConfig &rc_cfg); - // GetQP() needs to be called after ComputeQP() to get the latest QP - int GetQP() const; - int GetLoopfilterLevel() const; - bool GetSegmentationData(VP9SegmentationData *segmentation_data) const; - // ComputeQP computes the QP if the frame is not dropped (kOk return), - // otherwise it returns kDrop and subsequent GetQP and PostEncodeUpdate - // are not to be called (vp9_rc_postencode_update_drop_frame is already - // called via ComputeQP if drop is decided). - FrameDropDecision ComputeQP(const VP9FrameParamsQpRTC &frame_params); - // Feedback to rate control with the size of current encoded frame - void PostEncodeUpdate(uint64_t encoded_frame_size, - const VP9FrameParamsQpRTC &frame_params); - - private: - VP9RateControlRTC() = default; - bool InitRateControl(const VP9RateControlRtcConfig &cfg); - struct VP9_COMP *cpi_ = nullptr; -}; - -} // namespace libvpx - -#endif // VPX_VP9_RATECTRL_RTC_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/simple_encode.cc b/presentation/src/main/cpp/third_party/libvpx/vp9/simple_encode.cc deleted file mode 100644 index 54b4f385..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/simple_encode.cc +++ /dev/null @@ -1,1345 +0,0 @@ -/* - * Copyright (c) 2019 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include -#include - -#include "./ivfenc.h" -#include "vp9/common/vp9_entropymode.h" -#include "vp9/common/vp9_enums.h" -#include "vp9/common/vp9_onyxc_int.h" -#include "vp9/vp9_iface_common.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_firstpass.h" -#include "vp9/simple_encode.h" -#include "vp9/vp9_cx_iface.h" - -namespace vp9 { - -static int get_plane_height(vpx_img_fmt_t img_fmt, int frame_height, - int plane) { - assert(plane < 3); - if (plane == 0) { - return frame_height; - } - switch (img_fmt) { - case VPX_IMG_FMT_I420: - case VPX_IMG_FMT_I440: - case VPX_IMG_FMT_YV12: - case VPX_IMG_FMT_I42016: - case VPX_IMG_FMT_I44016: return (frame_height + 1) >> 1; - default: return frame_height; - } -} - -static int get_plane_width(vpx_img_fmt_t img_fmt, int frame_width, int plane) { - assert(plane < 3); - if (plane == 0) { - return frame_width; - } - switch (img_fmt) { - case VPX_IMG_FMT_I420: - case VPX_IMG_FMT_YV12: - case VPX_IMG_FMT_I422: - case VPX_IMG_FMT_I42016: - case VPX_IMG_FMT_I42216: return (frame_width + 1) >> 1; - default: return frame_width; - } -} - -// TODO(angiebird): Merge this function with vpx_img_plane_width() -static int img_plane_width(const vpx_image_t *img, int plane) { - if (plane > 0 && img->x_chroma_shift > 0) - return (img->d_w + 1) >> img->x_chroma_shift; - else - return img->d_w; -} - -// TODO(angiebird): Merge this function with vpx_img_plane_height() -static int img_plane_height(const vpx_image_t *img, int plane) { - if (plane > 0 && img->y_chroma_shift > 0) - return (img->d_h + 1) >> img->y_chroma_shift; - else - return img->d_h; -} - -// TODO(angiebird): Merge this function with vpx_img_read() -static int img_read(vpx_image_t *img, FILE *file) { - int plane; - - for (plane = 0; plane < 3; ++plane) { - unsigned char *buf = img->planes[plane]; - const int stride = img->stride[plane]; - const int w = img_plane_width(img, plane) * - ((img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1); - const int h = img_plane_height(img, plane); - int y; - - for (y = 0; y < h; ++y) { - if (fread(buf, 1, w, file) != (size_t)w) return 0; - buf += stride; - } - } - - return 1; -} - -// Assume every config in VP9EncoderConfig is less than 100 characters. -#define ENCODE_CONFIG_BUF_SIZE 100 -struct EncodeConfig { - char name[ENCODE_CONFIG_BUF_SIZE]; - char value[ENCODE_CONFIG_BUF_SIZE]; -}; - -class SimpleEncode::EncodeImpl { - public: - VP9_COMP *cpi; - vpx_img_fmt_t img_fmt; - vpx_image_t tmp_img; - std::vector first_pass_stats; - std::vector encode_config_list; -}; - -static VP9_COMP *init_encoder(const VP9EncoderConfig *oxcf, - vpx_img_fmt_t img_fmt) { - VP9_COMP *cpi; - BufferPool *buffer_pool = (BufferPool *)vpx_calloc(1, sizeof(*buffer_pool)); - if (!buffer_pool) return NULL; - vp9_initialize_enc(); - cpi = vp9_create_compressor(oxcf, buffer_pool); - vp9_update_compressor_with_img_fmt(cpi, img_fmt); - return cpi; -} - -static void free_encoder(VP9_COMP *cpi) { - BufferPool *buffer_pool = cpi->common.buffer_pool; - vp9_remove_compressor(cpi); - // buffer_pool needs to be free after cpi because buffer_pool contains - // allocated buffers that will be free in vp9_remove_compressor() - vpx_free(buffer_pool); -} - -static INLINE vpx_rational_t make_vpx_rational(int num, int den) { - vpx_rational_t v; - v.num = num; - v.den = den; - return v; -} - -static INLINE FrameType -get_frame_type_from_update_type(FRAME_UPDATE_TYPE update_type) { - switch (update_type) { - case KF_UPDATE: return kFrameTypeKey; - case ARF_UPDATE: return kFrameTypeAltRef; - case GF_UPDATE: return kFrameTypeGolden; - case OVERLAY_UPDATE: return kFrameTypeOverlay; - case LF_UPDATE: return kFrameTypeInter; - default: - fprintf(stderr, "Unsupported update_type %d\n", update_type); - abort(); - } -} - -static void update_partition_info(const PARTITION_INFO *input_partition_info, - const int num_rows_4x4, - const int num_cols_4x4, - PartitionInfo *output_partition_info) { - const int num_units_4x4 = num_rows_4x4 * num_cols_4x4; - for (int i = 0; i < num_units_4x4; ++i) { - output_partition_info[i].row = input_partition_info[i].row; - output_partition_info[i].column = input_partition_info[i].column; - output_partition_info[i].row_start = input_partition_info[i].row_start; - output_partition_info[i].column_start = - input_partition_info[i].column_start; - output_partition_info[i].width = input_partition_info[i].width; - output_partition_info[i].height = input_partition_info[i].height; - } -} - -// translate MV_REFERENCE_FRAME to RefFrameType -static RefFrameType mv_ref_frame_to_ref_frame_type( - MV_REFERENCE_FRAME mv_ref_frame) { - switch (mv_ref_frame) { - case LAST_FRAME: return kRefFrameTypeLast; - case GOLDEN_FRAME: return kRefFrameTypePast; - case ALTREF_FRAME: return kRefFrameTypeFuture; - default: return kRefFrameTypeNone; - } -} - -static void update_motion_vector_info( - const MOTION_VECTOR_INFO *input_motion_vector_info, const int num_rows_4x4, - const int num_cols_4x4, MotionVectorInfo *output_motion_vector_info, - int motion_vector_scale) { - const int num_units_4x4 = num_rows_4x4 * num_cols_4x4; - for (int i = 0; i < num_units_4x4; ++i) { - const MV_REFERENCE_FRAME *in_ref_frame = - input_motion_vector_info[i].ref_frame; - output_motion_vector_info[i].mv_count = - (in_ref_frame[0] == INTRA_FRAME) - ? 0 - : ((in_ref_frame[1] == NO_REF_FRAME) ? 1 : 2); - if (in_ref_frame[0] == NO_REF_FRAME) { - fprintf(stderr, "in_ref_frame[0] shouldn't be NO_REF_FRAME\n"); - abort(); - } - output_motion_vector_info[i].ref_frame[0] = - mv_ref_frame_to_ref_frame_type(in_ref_frame[0]); - output_motion_vector_info[i].ref_frame[1] = - mv_ref_frame_to_ref_frame_type(in_ref_frame[1]); - output_motion_vector_info[i].mv_row[0] = - (double)input_motion_vector_info[i].mv[0].as_mv.row / - motion_vector_scale; - output_motion_vector_info[i].mv_column[0] = - (double)input_motion_vector_info[i].mv[0].as_mv.col / - motion_vector_scale; - output_motion_vector_info[i].mv_row[1] = - (double)input_motion_vector_info[i].mv[1].as_mv.row / - motion_vector_scale; - output_motion_vector_info[i].mv_column[1] = - (double)input_motion_vector_info[i].mv[1].as_mv.col / - motion_vector_scale; - } -} - -static void update_tpl_stats_info(const TplDepStats *input_tpl_stats_info, - const int show_frame_count, - TplStatsInfo *output_tpl_stats_info) { - int frame_idx; - for (frame_idx = 0; frame_idx < show_frame_count; ++frame_idx) { - output_tpl_stats_info[frame_idx].intra_cost = - input_tpl_stats_info[frame_idx].intra_cost; - output_tpl_stats_info[frame_idx].inter_cost = - input_tpl_stats_info[frame_idx].inter_cost; - output_tpl_stats_info[frame_idx].mc_flow = - input_tpl_stats_info[frame_idx].mc_flow; - output_tpl_stats_info[frame_idx].mc_dep_cost = - input_tpl_stats_info[frame_idx].mc_dep_cost; - output_tpl_stats_info[frame_idx].mc_ref_cost = - input_tpl_stats_info[frame_idx].mc_ref_cost; - } -} - -static void update_frame_counts(const FRAME_COUNTS *input_counts, - FrameCounts *output_counts) { - // Init array sizes. - output_counts->y_mode.resize(BLOCK_SIZE_GROUPS); - for (int i = 0; i < BLOCK_SIZE_GROUPS; ++i) { - output_counts->y_mode[i].resize(INTRA_MODES); - } - - output_counts->uv_mode.resize(INTRA_MODES); - for (int i = 0; i < INTRA_MODES; ++i) { - output_counts->uv_mode[i].resize(INTRA_MODES); - } - - output_counts->partition.resize(PARTITION_CONTEXTS); - for (int i = 0; i < PARTITION_CONTEXTS; ++i) { - output_counts->partition[i].resize(PARTITION_TYPES); - } - - output_counts->coef.resize(TX_SIZES); - output_counts->eob_branch.resize(TX_SIZES); - for (int i = 0; i < TX_SIZES; ++i) { - output_counts->coef[i].resize(PLANE_TYPES); - output_counts->eob_branch[i].resize(PLANE_TYPES); - for (int j = 0; j < PLANE_TYPES; ++j) { - output_counts->coef[i][j].resize(REF_TYPES); - output_counts->eob_branch[i][j].resize(REF_TYPES); - for (int k = 0; k < REF_TYPES; ++k) { - output_counts->coef[i][j][k].resize(COEF_BANDS); - output_counts->eob_branch[i][j][k].resize(COEF_BANDS); - for (int l = 0; l < COEF_BANDS; ++l) { - output_counts->coef[i][j][k][l].resize(COEFF_CONTEXTS); - output_counts->eob_branch[i][j][k][l].resize(COEFF_CONTEXTS); - for (int m = 0; m < COEFF_CONTEXTS; ++m) { - output_counts->coef[i][j][k][l][m].resize(UNCONSTRAINED_NODES + 1); - } - } - } - } - } - - output_counts->switchable_interp.resize(SWITCHABLE_FILTER_CONTEXTS); - for (int i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) { - output_counts->switchable_interp[i].resize(SWITCHABLE_FILTERS); - } - - output_counts->inter_mode.resize(INTER_MODE_CONTEXTS); - for (int i = 0; i < INTER_MODE_CONTEXTS; ++i) { - output_counts->inter_mode[i].resize(INTER_MODES); - } - - output_counts->intra_inter.resize(INTRA_INTER_CONTEXTS); - for (int i = 0; i < INTRA_INTER_CONTEXTS; ++i) { - output_counts->intra_inter[i].resize(2); - } - - output_counts->comp_inter.resize(COMP_INTER_CONTEXTS); - for (int i = 0; i < COMP_INTER_CONTEXTS; ++i) { - output_counts->comp_inter[i].resize(2); - } - - output_counts->single_ref.resize(REF_CONTEXTS); - for (int i = 0; i < REF_CONTEXTS; ++i) { - output_counts->single_ref[i].resize(2); - for (int j = 0; j < 2; ++j) { - output_counts->single_ref[i][j].resize(2); - } - } - - output_counts->comp_ref.resize(REF_CONTEXTS); - for (int i = 0; i < REF_CONTEXTS; ++i) { - output_counts->comp_ref[i].resize(2); - } - - output_counts->skip.resize(SKIP_CONTEXTS); - for (int i = 0; i < SKIP_CONTEXTS; ++i) { - output_counts->skip[i].resize(2); - } - - output_counts->tx.p32x32.resize(TX_SIZE_CONTEXTS); - output_counts->tx.p16x16.resize(TX_SIZE_CONTEXTS); - output_counts->tx.p8x8.resize(TX_SIZE_CONTEXTS); - for (int i = 0; i < TX_SIZE_CONTEXTS; i++) { - output_counts->tx.p32x32[i].resize(TX_SIZES); - output_counts->tx.p16x16[i].resize(TX_SIZES - 1); - output_counts->tx.p8x8[i].resize(TX_SIZES - 2); - } - output_counts->tx.tx_totals.resize(TX_SIZES); - - output_counts->mv.joints.resize(MV_JOINTS); - output_counts->mv.comps.resize(2); - for (int i = 0; i < 2; ++i) { - output_counts->mv.comps[i].sign.resize(2); - output_counts->mv.comps[i].classes.resize(MV_CLASSES); - output_counts->mv.comps[i].class0.resize(CLASS0_SIZE); - output_counts->mv.comps[i].bits.resize(MV_OFFSET_BITS); - for (int j = 0; j < MV_OFFSET_BITS; ++j) { - output_counts->mv.comps[i].bits[j].resize(2); - } - output_counts->mv.comps[i].class0_fp.resize(CLASS0_SIZE); - for (int j = 0; j < CLASS0_SIZE; ++j) { - output_counts->mv.comps[i].class0_fp[j].resize(MV_FP_SIZE); - } - output_counts->mv.comps[i].fp.resize(MV_FP_SIZE); - output_counts->mv.comps[i].class0_hp.resize(2); - output_counts->mv.comps[i].hp.resize(2); - } - - // Populate counts. - for (int i = 0; i < BLOCK_SIZE_GROUPS; ++i) { - for (int j = 0; j < INTRA_MODES; ++j) { - output_counts->y_mode[i][j] = input_counts->y_mode[i][j]; - } - } - for (int i = 0; i < INTRA_MODES; ++i) { - for (int j = 0; j < INTRA_MODES; ++j) { - output_counts->uv_mode[i][j] = input_counts->uv_mode[i][j]; - } - } - for (int i = 0; i < PARTITION_CONTEXTS; ++i) { - for (int j = 0; j < PARTITION_TYPES; ++j) { - output_counts->partition[i][j] = input_counts->partition[i][j]; - } - } - for (int i = 0; i < TX_SIZES; ++i) { - for (int j = 0; j < PLANE_TYPES; ++j) { - for (int k = 0; k < REF_TYPES; ++k) { - for (int l = 0; l < COEF_BANDS; ++l) { - for (int m = 0; m < COEFF_CONTEXTS; ++m) { - output_counts->eob_branch[i][j][k][l][m] = - input_counts->eob_branch[i][j][k][l][m]; - for (int n = 0; n < UNCONSTRAINED_NODES + 1; n++) { - output_counts->coef[i][j][k][l][m][n] = - input_counts->coef[i][j][k][l][m][n]; - } - } - } - } - } - } - for (int i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) { - for (int j = 0; j < SWITCHABLE_FILTERS; ++j) { - output_counts->switchable_interp[i][j] = - input_counts->switchable_interp[i][j]; - } - } - for (int i = 0; i < INTER_MODE_CONTEXTS; ++i) { - for (int j = 0; j < INTER_MODES; ++j) { - output_counts->inter_mode[i][j] = input_counts->inter_mode[i][j]; - } - } - for (int i = 0; i < INTRA_INTER_CONTEXTS; ++i) { - for (int j = 0; j < 2; ++j) { - output_counts->intra_inter[i][j] = input_counts->intra_inter[i][j]; - } - } - for (int i = 0; i < COMP_INTER_CONTEXTS; ++i) { - for (int j = 0; j < 2; ++j) { - output_counts->comp_inter[i][j] = input_counts->comp_inter[i][j]; - } - } - for (int i = 0; i < REF_CONTEXTS; ++i) { - for (int j = 0; j < 2; ++j) { - for (int k = 0; k < 2; ++k) { - output_counts->single_ref[i][j][k] = input_counts->single_ref[i][j][k]; - } - } - } - for (int i = 0; i < REF_CONTEXTS; ++i) { - for (int j = 0; j < 2; ++j) { - output_counts->comp_ref[i][j] = input_counts->comp_ref[i][j]; - } - } - for (int i = 0; i < SKIP_CONTEXTS; ++i) { - for (int j = 0; j < 2; ++j) { - output_counts->skip[i][j] = input_counts->skip[i][j]; - } - } - for (int i = 0; i < TX_SIZE_CONTEXTS; i++) { - for (int j = 0; j < TX_SIZES; j++) { - output_counts->tx.p32x32[i][j] = input_counts->tx.p32x32[i][j]; - } - for (int j = 0; j < TX_SIZES - 1; j++) { - output_counts->tx.p16x16[i][j] = input_counts->tx.p16x16[i][j]; - } - for (int j = 0; j < TX_SIZES - 2; j++) { - output_counts->tx.p8x8[i][j] = input_counts->tx.p8x8[i][j]; - } - } - for (int i = 0; i < TX_SIZES; i++) { - output_counts->tx.tx_totals[i] = input_counts->tx.tx_totals[i]; - } - for (int i = 0; i < MV_JOINTS; i++) { - output_counts->mv.joints[i] = input_counts->mv.joints[i]; - } - for (int k = 0; k < 2; k++) { - const nmv_component_counts *const comps_t = &input_counts->mv.comps[k]; - for (int i = 0; i < 2; i++) { - output_counts->mv.comps[k].sign[i] = comps_t->sign[i]; - output_counts->mv.comps[k].class0_hp[i] = comps_t->class0_hp[i]; - output_counts->mv.comps[k].hp[i] = comps_t->hp[i]; - } - for (int i = 0; i < MV_CLASSES; i++) { - output_counts->mv.comps[k].classes[i] = comps_t->classes[i]; - } - for (int i = 0; i < CLASS0_SIZE; i++) { - output_counts->mv.comps[k].class0[i] = comps_t->class0[i]; - for (int j = 0; j < MV_FP_SIZE; j++) { - output_counts->mv.comps[k].class0_fp[i][j] = comps_t->class0_fp[i][j]; - } - } - for (int i = 0; i < MV_OFFSET_BITS; i++) { - for (int j = 0; j < 2; j++) { - output_counts->mv.comps[k].bits[i][j] = comps_t->bits[i][j]; - } - } - for (int i = 0; i < MV_FP_SIZE; i++) { - output_counts->mv.comps[k].fp[i] = comps_t->fp[i]; - } - } -} - -void output_image_buffer(const ImageBuffer &image_buffer, std::FILE *out_file) { - for (int plane = 0; plane < 3; ++plane) { - const int w = image_buffer.plane_width[plane]; - const int h = image_buffer.plane_height[plane]; - const uint8_t *buf = image_buffer.plane_buffer[plane].get(); - fprintf(out_file, "%d %d\n", h, w); - for (int i = 0; i < w * h; ++i) { - fprintf(out_file, "%d ", (int)buf[i]); - } - fprintf(out_file, "\n"); - } -} - -static bool init_image_buffer(ImageBuffer *image_buffer, int frame_width, - int frame_height, vpx_img_fmt_t img_fmt) { - for (int plane = 0; plane < 3; ++plane) { - const int w = get_plane_width(img_fmt, frame_width, plane); - const int h = get_plane_height(img_fmt, frame_height, plane); - image_buffer->plane_width[plane] = w; - image_buffer->plane_height[plane] = h; - image_buffer->plane_buffer[plane].reset(new (std::nothrow) uint8_t[w * h]); - if (image_buffer->plane_buffer[plane].get() == nullptr) { - return false; - } - } - return true; -} - -static void ImageBuffer_to_IMAGE_BUFFER(const ImageBuffer &image_buffer, - IMAGE_BUFFER *image_buffer_c) { - image_buffer_c->allocated = 1; - for (int plane = 0; plane < 3; ++plane) { - image_buffer_c->plane_width[plane] = image_buffer.plane_width[plane]; - image_buffer_c->plane_height[plane] = image_buffer.plane_height[plane]; - image_buffer_c->plane_buffer[plane] = - image_buffer.plane_buffer[plane].get(); - } -} - -static size_t get_max_coding_data_byte_size(int frame_width, int frame_height) { - return frame_width * frame_height * 3; -} - -static bool init_encode_frame_result(EncodeFrameResult *encode_frame_result, - int frame_width, int frame_height, - vpx_img_fmt_t img_fmt) { - const size_t max_coding_data_byte_size = - get_max_coding_data_byte_size(frame_width, frame_height); - - encode_frame_result->coding_data.reset( - new (std::nothrow) uint8_t[max_coding_data_byte_size]); - encode_frame_result->max_coding_data_byte_size = max_coding_data_byte_size; - - encode_frame_result->num_rows_4x4 = get_num_unit_4x4(frame_height); - encode_frame_result->num_cols_4x4 = get_num_unit_4x4(frame_width); - encode_frame_result->partition_info.resize(encode_frame_result->num_rows_4x4 * - encode_frame_result->num_cols_4x4); - encode_frame_result->motion_vector_info.resize( - encode_frame_result->num_rows_4x4 * encode_frame_result->num_cols_4x4); - encode_frame_result->tpl_stats_info.resize(MAX_LAG_BUFFERS); - - if (encode_frame_result->coding_data.get() == nullptr) { - encode_frame_result->max_coding_data_byte_size = 0; - return false; - } - return init_image_buffer(&encode_frame_result->coded_frame, frame_width, - frame_height, img_fmt); -} - -static void encode_frame_result_update_rq_history( - const RATE_QINDEX_HISTORY *rq_history, - EncodeFrameResult *encode_frame_result) { - encode_frame_result->recode_count = rq_history->recode_count; - for (int i = 0; i < encode_frame_result->recode_count; ++i) { - const int q_index = rq_history->q_index_history[i]; - const int rate = rq_history->rate_history[i]; - encode_frame_result->q_index_history.push_back(q_index); - encode_frame_result->rate_history.push_back(rate); - } -} - -static void update_encode_frame_result( - EncodeFrameResult *encode_frame_result, const int show_frame_count, - const ENCODE_FRAME_RESULT *encode_frame_info) { - encode_frame_result->coding_data_bit_size = - encode_frame_result->coding_data_byte_size * 8; - encode_frame_result->show_idx = encode_frame_info->show_idx; - encode_frame_result->coding_idx = encode_frame_info->frame_coding_index; - assert(kRefFrameTypeMax == MAX_INTER_REF_FRAMES); - for (int i = 0; i < kRefFrameTypeMax; ++i) { - encode_frame_result->ref_frame_info.coding_indexes[i] = - encode_frame_info->ref_frame_coding_indexes[i]; - encode_frame_result->ref_frame_info.valid_list[i] = - encode_frame_info->ref_frame_valid_list[i]; - } - encode_frame_result->frame_type = - get_frame_type_from_update_type(encode_frame_info->update_type); - encode_frame_result->psnr = encode_frame_info->psnr; - encode_frame_result->sse = encode_frame_info->sse; - encode_frame_result->quantize_index = encode_frame_info->quantize_index; - update_partition_info(encode_frame_info->partition_info, - encode_frame_result->num_rows_4x4, - encode_frame_result->num_cols_4x4, - &encode_frame_result->partition_info[0]); - update_motion_vector_info(encode_frame_info->motion_vector_info, - encode_frame_result->num_rows_4x4, - encode_frame_result->num_cols_4x4, - &encode_frame_result->motion_vector_info[0], - kMotionVectorSubPixelPrecision); - update_frame_counts(&encode_frame_info->frame_counts, - &encode_frame_result->frame_counts); - if (encode_frame_result->frame_type == kFrameTypeAltRef) { - update_tpl_stats_info(encode_frame_info->tpl_stats_info, show_frame_count, - &encode_frame_result->tpl_stats_info[0]); - } - encode_frame_result_update_rq_history(&encode_frame_info->rq_history, - encode_frame_result); -} - -static void IncreaseGroupOfPictureIndex(GroupOfPicture *group_of_picture) { - ++group_of_picture->next_encode_frame_index; -} - -static int IsGroupOfPictureFinished(const GroupOfPicture &group_of_picture) { - return static_cast(group_of_picture.next_encode_frame_index) == - group_of_picture.encode_frame_list.size(); -} - -bool operator==(const RefFrameInfo &a, const RefFrameInfo &b) { - bool match = true; - for (int i = 0; i < kRefFrameTypeMax; ++i) { - match &= a.coding_indexes[i] == b.coding_indexes[i]; - match &= a.valid_list[i] == b.valid_list[i]; - } - return match; -} - -static void InitRefFrameInfo(RefFrameInfo *ref_frame_info) { - for (int i = 0; i < kRefFrameTypeMax; ++i) { - ref_frame_info->coding_indexes[i] = -1; - ref_frame_info->valid_list[i] = 0; - } -} - -// After finishing coding a frame, this function will update the coded frame -// into the ref_frame_info based on the frame_type and the coding_index. -static void PostUpdateRefFrameInfo(FrameType frame_type, int frame_coding_index, - RefFrameInfo *ref_frame_info) { - // This part is written based on the logics in vp9_configure_buffer_updates() - // and update_ref_frames() - int *ref_frame_coding_indexes = ref_frame_info->coding_indexes; - switch (frame_type) { - case kFrameTypeKey: - ref_frame_coding_indexes[kRefFrameTypeLast] = frame_coding_index; - ref_frame_coding_indexes[kRefFrameTypePast] = frame_coding_index; - ref_frame_coding_indexes[kRefFrameTypeFuture] = frame_coding_index; - break; - case kFrameTypeInter: - ref_frame_coding_indexes[kRefFrameTypeLast] = frame_coding_index; - break; - case kFrameTypeAltRef: - ref_frame_coding_indexes[kRefFrameTypeFuture] = frame_coding_index; - break; - case kFrameTypeOverlay: - // Reserve the past coding_index in the future slot. This logic is from - // update_ref_frames() with condition vp9_preserve_existing_gf() == 1 - // TODO(angiebird): Invetegate why we need this. - ref_frame_coding_indexes[kRefFrameTypeFuture] = - ref_frame_coding_indexes[kRefFrameTypePast]; - ref_frame_coding_indexes[kRefFrameTypePast] = frame_coding_index; - break; - case kFrameTypeGolden: - ref_frame_coding_indexes[kRefFrameTypePast] = frame_coding_index; - ref_frame_coding_indexes[kRefFrameTypeLast] = frame_coding_index; - break; - } - - // This part is written based on the logics in get_ref_frame_flags() but we - // rename the flags alt, golden to future, past respectively. Mark - // non-duplicated reference frames as valid. The priorities are - // kRefFrameTypeLast > kRefFrameTypePast > kRefFrameTypeFuture. - const int last_index = ref_frame_coding_indexes[kRefFrameTypeLast]; - const int past_index = ref_frame_coding_indexes[kRefFrameTypePast]; - const int future_index = ref_frame_coding_indexes[kRefFrameTypeFuture]; - - int *ref_frame_valid_list = ref_frame_info->valid_list; - for (int ref_frame_idx = 0; ref_frame_idx < kRefFrameTypeMax; - ++ref_frame_idx) { - ref_frame_valid_list[ref_frame_idx] = 1; - } - - if (past_index == last_index) { - ref_frame_valid_list[kRefFrameTypePast] = 0; - } - - if (future_index == last_index) { - ref_frame_valid_list[kRefFrameTypeFuture] = 0; - } - - if (future_index == past_index) { - ref_frame_valid_list[kRefFrameTypeFuture] = 0; - } -} - -static void SetGroupOfPicture(int first_is_key_frame, int use_alt_ref, - int coding_frame_count, int first_show_idx, - int last_gop_use_alt_ref, int start_coding_index, - const RefFrameInfo &start_ref_frame_info, - GroupOfPicture *group_of_picture) { - // Clean up the state of previous group of picture. - group_of_picture->encode_frame_list.clear(); - group_of_picture->next_encode_frame_index = 0; - group_of_picture->show_frame_count = coding_frame_count - use_alt_ref; - group_of_picture->start_show_index = first_show_idx; - group_of_picture->start_coding_index = start_coding_index; - group_of_picture->first_is_key_frame = first_is_key_frame; - group_of_picture->use_alt_ref = use_alt_ref; - group_of_picture->last_gop_use_alt_ref = last_gop_use_alt_ref; - - // We need to make a copy of start reference frame info because we - // use it to simulate the ref frame update. - RefFrameInfo ref_frame_info = start_ref_frame_info; - - { - // First frame in the group of pictures. It's either key frame or show inter - // frame. - EncodeFrameInfo encode_frame_info; - // Set frame_type - if (first_is_key_frame) { - encode_frame_info.frame_type = kFrameTypeKey; - } else { - if (last_gop_use_alt_ref) { - encode_frame_info.frame_type = kFrameTypeOverlay; - } else { - encode_frame_info.frame_type = kFrameTypeGolden; - } - } - - encode_frame_info.show_idx = first_show_idx; - encode_frame_info.coding_index = start_coding_index; - - encode_frame_info.ref_frame_info = ref_frame_info; - PostUpdateRefFrameInfo(encode_frame_info.frame_type, - encode_frame_info.coding_index, &ref_frame_info); - - group_of_picture->encode_frame_list.push_back(encode_frame_info); - } - - const int show_frame_count = coding_frame_count - use_alt_ref; - if (use_alt_ref) { - // If there is alternate reference, it is always coded at the second place. - // Its show index (or timestamp) is at the last of this group - EncodeFrameInfo encode_frame_info; - encode_frame_info.frame_type = kFrameTypeAltRef; - encode_frame_info.show_idx = first_show_idx + show_frame_count; - encode_frame_info.coding_index = start_coding_index + 1; - - encode_frame_info.ref_frame_info = ref_frame_info; - PostUpdateRefFrameInfo(encode_frame_info.frame_type, - encode_frame_info.coding_index, &ref_frame_info); - - group_of_picture->encode_frame_list.push_back(encode_frame_info); - } - - // Encode the rest show inter frames. - for (int i = 1; i < show_frame_count; ++i) { - EncodeFrameInfo encode_frame_info; - encode_frame_info.frame_type = kFrameTypeInter; - encode_frame_info.show_idx = first_show_idx + i; - encode_frame_info.coding_index = start_coding_index + use_alt_ref + i; - - encode_frame_info.ref_frame_info = ref_frame_info; - PostUpdateRefFrameInfo(encode_frame_info.frame_type, - encode_frame_info.coding_index, &ref_frame_info); - - group_of_picture->encode_frame_list.push_back(encode_frame_info); - } -} - -// Gets group of picture information from VP9's decision, and update -// |group_of_picture| accordingly. -// This is called at the starting of encoding of each group of picture. -static void UpdateGroupOfPicture(const VP9_COMP *cpi, int start_coding_index, - const RefFrameInfo &start_ref_frame_info, - GroupOfPicture *group_of_picture) { - int first_is_key_frame; - int use_alt_ref; - int coding_frame_count; - int first_show_idx; - int last_gop_use_alt_ref; - vp9_get_next_group_of_picture(cpi, &first_is_key_frame, &use_alt_ref, - &coding_frame_count, &first_show_idx, - &last_gop_use_alt_ref); - SetGroupOfPicture(first_is_key_frame, use_alt_ref, coding_frame_count, - first_show_idx, last_gop_use_alt_ref, start_coding_index, - start_ref_frame_info, group_of_picture); -} - -#define SET_STRUCT_VALUE(config, structure, ret, field) \ - do { \ - if (strcmp(config.name, #field) == 0) { \ - structure->field = atoi(config.value); \ - ret = 1; \ - } \ - } while (false) - -static void UpdateEncodeConfig(const EncodeConfig &config, - VP9EncoderConfig *oxcf) { - int ret = 0; - SET_STRUCT_VALUE(config, oxcf, ret, key_freq); - SET_STRUCT_VALUE(config, oxcf, ret, two_pass_vbrmin_section); - SET_STRUCT_VALUE(config, oxcf, ret, two_pass_vbrmax_section); - SET_STRUCT_VALUE(config, oxcf, ret, under_shoot_pct); - SET_STRUCT_VALUE(config, oxcf, ret, over_shoot_pct); - SET_STRUCT_VALUE(config, oxcf, ret, max_threads); - SET_STRUCT_VALUE(config, oxcf, ret, frame_parallel_decoding_mode); - SET_STRUCT_VALUE(config, oxcf, ret, tile_columns); - SET_STRUCT_VALUE(config, oxcf, ret, arnr_max_frames); - SET_STRUCT_VALUE(config, oxcf, ret, arnr_strength); - SET_STRUCT_VALUE(config, oxcf, ret, lag_in_frames); - SET_STRUCT_VALUE(config, oxcf, ret, encode_breakout); - SET_STRUCT_VALUE(config, oxcf, ret, enable_tpl_model); - SET_STRUCT_VALUE(config, oxcf, ret, enable_auto_arf); - if (strcmp(config.name, "rc_mode") == 0) { - int rc_mode = atoi(config.value); - if (rc_mode >= VPX_VBR && rc_mode <= VPX_Q) { - oxcf->rc_mode = (enum vpx_rc_mode)rc_mode; - ret = 1; - } else { - fprintf(stderr, "Invalid rc_mode value: %d\n", rc_mode); - } - } - SET_STRUCT_VALUE(config, oxcf, ret, cq_level); - if (ret == 0) { - fprintf(stderr, "Ignored unsupported encode_config %s\n", config.name); - } -} - -static VP9EncoderConfig GetEncodeConfig( - int frame_width, int frame_height, vpx_rational_t frame_rate, - int target_bitrate, int encode_speed, int target_level, - vpx_enc_pass enc_pass, - const std::vector &encode_config_list) { - VP9EncoderConfig oxcf = vp9_get_encoder_config( - frame_width, frame_height, frame_rate, target_bitrate, encode_speed, - target_level, enc_pass); - for (const auto &config : encode_config_list) { - UpdateEncodeConfig(config, &oxcf); - } - if (enc_pass == VPX_RC_FIRST_PASS) { - oxcf.lag_in_frames = 0; - } - oxcf.use_simple_encode_api = 1; - return oxcf; -} - -SimpleEncode::SimpleEncode(int frame_width, int frame_height, - int frame_rate_num, int frame_rate_den, - int target_bitrate, int num_frames, int target_level, - const char *infile_path, const char *outfile_path) { - impl_ptr_ = std::unique_ptr(new EncodeImpl()); - frame_width_ = frame_width; - frame_height_ = frame_height; - frame_rate_num_ = frame_rate_num; - frame_rate_den_ = frame_rate_den; - target_bitrate_ = target_bitrate; - num_frames_ = num_frames; - encode_speed_ = 0; - target_level_ = target_level; - - frame_coding_index_ = 0; - show_frame_count_ = 0; - - key_frame_group_index_ = 0; - key_frame_group_size_ = 0; - - // TODO(angirbid): Should we keep a file pointer here or keep the file_path? - assert(infile_path != nullptr); - in_file_ = fopen(infile_path, "r"); - if (outfile_path != nullptr) { - out_file_ = fopen(outfile_path, "w"); - } else { - out_file_ = nullptr; - } - impl_ptr_->cpi = nullptr; - impl_ptr_->img_fmt = VPX_IMG_FMT_I420; - - InitRefFrameInfo(&ref_frame_info_); -} - -void SimpleEncode::SetEncodeSpeed(int encode_speed) { - encode_speed_ = encode_speed; -} - -StatusCode SimpleEncode::SetEncodeConfig(const char *name, const char *value) { - if (name == nullptr || value == nullptr) { - fprintf(stderr, "SetEncodeConfig: null pointer, name %p value %p\n", name, - value); - return StatusError; - } - EncodeConfig config; - snprintf(config.name, ENCODE_CONFIG_BUF_SIZE, "%s", name); - snprintf(config.value, ENCODE_CONFIG_BUF_SIZE, "%s", value); - impl_ptr_->encode_config_list.push_back(config); - return StatusOk; -} - -StatusCode SimpleEncode::DumpEncodeConfigs(int pass, FILE *fp) { - if (fp == nullptr) { - fprintf(stderr, "DumpEncodeConfigs: null pointer, fp %p\n", fp); - return StatusError; - } - vpx_enc_pass enc_pass; - if (pass == 1) { - enc_pass = VPX_RC_FIRST_PASS; - } else { - enc_pass = VPX_RC_LAST_PASS; - } - const vpx_rational_t frame_rate = - make_vpx_rational(frame_rate_num_, frame_rate_den_); - const VP9EncoderConfig oxcf = GetEncodeConfig( - frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_, - target_level_, enc_pass, impl_ptr_->encode_config_list); - vp9_dump_encoder_config(&oxcf, fp); - return StatusOk; -} - -void SimpleEncode::ComputeFirstPassStats() { - vpx_rational_t frame_rate = - make_vpx_rational(frame_rate_num_, frame_rate_den_); - const VP9EncoderConfig oxcf = GetEncodeConfig( - frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_, - target_level_, VPX_RC_FIRST_PASS, impl_ptr_->encode_config_list); - impl_ptr_->cpi = init_encoder(&oxcf, impl_ptr_->img_fmt); - struct lookahead_ctx *lookahead = impl_ptr_->cpi->lookahead; - int i; - int use_highbitdepth = 0; - const int num_rows_16x16 = get_num_unit_16x16(frame_height_); - const int num_cols_16x16 = get_num_unit_16x16(frame_width_); -#if CONFIG_VP9_HIGHBITDEPTH - use_highbitdepth = impl_ptr_->cpi->common.use_highbitdepth; -#endif - vpx_image_t img; - if (impl_ptr_->img_fmt == VPX_IMG_FMT_NV12) { - fprintf(stderr, "VPX_IMG_FMT_NV12 is not supported\n"); - abort(); - } - vpx_img_alloc(&img, impl_ptr_->img_fmt, frame_width_, frame_height_, 1); - rewind(in_file_); - impl_ptr_->first_pass_stats.clear(); - for (i = 0; i < num_frames_; ++i) { - assert(!vp9_lookahead_full(lookahead)); - if (img_read(&img, in_file_)) { - int next_show_idx = vp9_lookahead_next_show_idx(lookahead); - int64_t ts_start = - timebase_units_to_ticks(&oxcf.g_timebase_in_ts, next_show_idx); - int64_t ts_end = - timebase_units_to_ticks(&oxcf.g_timebase_in_ts, next_show_idx + 1); - YV12_BUFFER_CONFIG sd; - image2yuvconfig(&img, &sd); - vp9_lookahead_push(lookahead, &sd, ts_start, ts_end, use_highbitdepth, 0); - { - int64_t time_stamp; - int64_t time_end; - int flush = 1; // Makes vp9_get_compressed_data process a frame - size_t size; - unsigned int frame_flags = 0; - ENCODE_FRAME_RESULT encode_frame_info; - vp9_init_encode_frame_result(&encode_frame_info); - // TODO(angiebird): Call vp9_first_pass directly - vp9_get_compressed_data(impl_ptr_->cpi, &frame_flags, &size, nullptr, 0, - &time_stamp, &time_end, flush, - &encode_frame_info); - // vp9_get_compressed_data only generates first pass stats not - // compresses data - assert(size == 0); - // Get vp9 first pass motion vector info. - std::vector mv_info(num_rows_16x16 * num_cols_16x16); - update_motion_vector_info( - impl_ptr_->cpi->fp_motion_vector_info, num_rows_16x16, - num_cols_16x16, mv_info.data(), kMotionVectorFullPixelPrecision); - fp_motion_vector_info_.push_back(mv_info); - } - impl_ptr_->first_pass_stats.push_back( - vp9_get_frame_stats(&impl_ptr_->cpi->twopass)); - } - } - // TODO(angiebird): Store the total_stats apart form first_pass_stats - impl_ptr_->first_pass_stats.push_back( - vp9_get_total_stats(&impl_ptr_->cpi->twopass)); - vp9_end_first_pass(impl_ptr_->cpi); - - // Generate key_frame_map based on impl_ptr_->first_pass_stats. - key_frame_map_ = ComputeKeyFrameMap(); - - free_encoder(impl_ptr_->cpi); - impl_ptr_->cpi = nullptr; - rewind(in_file_); - vpx_img_free(&img); -} - -std::vector> SimpleEncode::ObserveFirstPassStats() { - std::vector> output_stats; - // TODO(angiebird): This function make several assumptions of - // FIRSTPASS_STATS. 1) All elements in FIRSTPASS_STATS are double except the - // last one. 2) The last entry of first_pass_stats is the total_stats. - // Change the code structure, so that we don't have to make these assumptions - - // Note the last entry of first_pass_stats is the total_stats, we don't need - // it. - for (size_t i = 0; i < impl_ptr_->first_pass_stats.size() - 1; ++i) { - double *buf_start = - reinterpret_cast(&impl_ptr_->first_pass_stats[i]); - // We use - 1 here because the last member in FIRSTPASS_STATS is not double - double *buf_end = - buf_start + sizeof(impl_ptr_->first_pass_stats[i]) / sizeof(*buf_end) - - 1; - std::vector this_stats(buf_start, buf_end); - output_stats.push_back(this_stats); - } - return output_stats; -} - -std::vector> -SimpleEncode::ObserveFirstPassMotionVectors() { - return fp_motion_vector_info_; -} - -void SimpleEncode::SetExternalGroupOfPicturesMap(int *gop_map, - int gop_map_size) { - for (int i = 0; i < gop_map_size; ++i) { - gop_map_.push_back(gop_map[i]); - } - // The following will check and modify gop_map_ to make sure the - // gop_map_ satisfies the constraints. - // 1) Each key frame position should be at the start of a gop. - // 2) The last gop should not use an alt ref. - assert(gop_map_.size() == key_frame_map_.size()); - int last_gop_start = 0; - for (int i = 0; static_cast(i) < gop_map_.size(); ++i) { - if (key_frame_map_[i] == 1 && gop_map_[i] == 0) { - fprintf(stderr, "Add an extra gop start at show_idx %d\n", i); - // Insert a gop start at key frame location. - gop_map_[i] |= kGopMapFlagStart; - gop_map_[i] |= kGopMapFlagUseAltRef; - } - if (gop_map_[i] & kGopMapFlagStart) { - last_gop_start = i; - } - } - if (gop_map_[last_gop_start] & kGopMapFlagUseAltRef) { - fprintf(stderr, - "Last group of pictures starting at show_idx %d shouldn't use alt " - "ref\n", - last_gop_start); - gop_map_[last_gop_start] &= ~kGopMapFlagUseAltRef; - } -} - -std::vector SimpleEncode::ObserveExternalGroupOfPicturesMap() { - return gop_map_; -} - -template -T *GetVectorData(const std::vector &v) { - if (v.empty()) { - return nullptr; - } - return const_cast(v.data()); -} - -static GOP_COMMAND GetGopCommand(const std::vector &gop_map, - int start_show_index) { - GOP_COMMAND gop_command; - if (static_cast(start_show_index) < gop_map.size()) { - assert((gop_map[start_show_index] & kGopMapFlagStart) != 0); - int end_show_index = start_show_index + 1; - // gop_map[end_show_index] & kGopMapFlagStart == 0 means this is - // the start of a gop. - while (static_cast(end_show_index) < gop_map.size() && - (gop_map[end_show_index] & kGopMapFlagStart) == 0) { - ++end_show_index; - } - const int show_frame_count = end_show_index - start_show_index; - int use_alt_ref = (gop_map[start_show_index] & kGopMapFlagUseAltRef) != 0; - if (static_cast(end_show_index) == gop_map.size()) { - // This is the last gop group, there must be no altref. - use_alt_ref = 0; - } - gop_command_on(&gop_command, show_frame_count, use_alt_ref); - } else { - gop_command_off(&gop_command); - } - return gop_command; -} - -void SimpleEncode::StartEncode() { - assert(impl_ptr_->first_pass_stats.size() > 0); - vpx_rational_t frame_rate = - make_vpx_rational(frame_rate_num_, frame_rate_den_); - VP9EncoderConfig oxcf = GetEncodeConfig( - frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_, - target_level_, VPX_RC_LAST_PASS, impl_ptr_->encode_config_list); - - vpx_fixed_buf_t stats; - stats.buf = GetVectorData(impl_ptr_->first_pass_stats); - stats.sz = sizeof(impl_ptr_->first_pass_stats[0]) * - impl_ptr_->first_pass_stats.size(); - - vp9_set_first_pass_stats(&oxcf, &stats); - assert(impl_ptr_->cpi == nullptr); - impl_ptr_->cpi = init_encoder(&oxcf, impl_ptr_->img_fmt); - if (impl_ptr_->img_fmt == VPX_IMG_FMT_NV12) { - fprintf(stderr, "VPX_IMG_FMT_NV12 is not supported\n"); - abort(); - } - vpx_img_alloc(&impl_ptr_->tmp_img, impl_ptr_->img_fmt, frame_width_, - frame_height_, 1); - - frame_coding_index_ = 0; - show_frame_count_ = 0; - - assert(impl_ptr_->cpi != nullptr); - FRAME_INFO frame_info = vp9_get_frame_info(&oxcf); - unsigned int screen_area = frame_info.frame_width * frame_info.frame_height; - vp9_init_vizier_params(&impl_ptr_->cpi->twopass, screen_area); - - UpdateKeyFrameGroup(show_frame_count_); - - const GOP_COMMAND gop_command = GetGopCommand(gop_map_, show_frame_count_); - encode_command_set_gop_command(&impl_ptr_->cpi->encode_command, gop_command); - UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_, ref_frame_info_, - &group_of_picture_); - rewind(in_file_); - - if (out_file_ != nullptr) { - const char *fourcc = "VP90"; - // In SimpleEncode, we use time_base = 1 / TICKS_PER_SEC. - // Based on that, the ivf_timestamp for each image is set to - // show_idx * TICKS_PER_SEC / frame_rate - // such that each image's actual timestamp in seconds can be computed as - // ivf_timestamp * time_base == show_idx / frame_rate - // TODO(angiebird): 1) Add unit test for ivf timestamp. - // 2) Simplify the frame_rate setting process. - vpx_rational_t time_base = make_vpx_rational(1, TICKS_PER_SEC); - ivf_write_file_header_with_video_info(out_file_, *(const uint32_t *)fourcc, - num_frames_, frame_width_, - frame_height_, time_base); - } -} - -void SimpleEncode::EndEncode() { - free_encoder(impl_ptr_->cpi); - impl_ptr_->cpi = nullptr; - vpx_img_free(&impl_ptr_->tmp_img); - rewind(in_file_); -} - -void SimpleEncode::UpdateKeyFrameGroup(int key_frame_show_index) { - const VP9_COMP *cpi = impl_ptr_->cpi; - key_frame_group_index_ = 0; - key_frame_group_size_ = vp9_get_frames_to_next_key( - &cpi->oxcf, &cpi->twopass, key_frame_show_index, cpi->rc.min_gf_interval); - assert(key_frame_group_size_ > 0); - // Init the reference frame info when a new key frame group appears. - InitRefFrameInfo(&ref_frame_info_); -} - -void SimpleEncode::PostUpdateKeyFrameGroupIndex(FrameType frame_type) { - if (frame_type != kFrameTypeAltRef) { - // key_frame_group_index_ only counts show frames - ++key_frame_group_index_; - } -} - -int SimpleEncode::GetKeyFrameGroupSize() const { return key_frame_group_size_; } - -GroupOfPicture SimpleEncode::ObserveGroupOfPicture() const { - return group_of_picture_; -} - -EncodeFrameInfo SimpleEncode::GetNextEncodeFrameInfo() const { - return group_of_picture_ - .encode_frame_list[group_of_picture_.next_encode_frame_index]; -} - -void SimpleEncode::PostUpdateState( - const EncodeFrameResult &encode_frame_result) { - // This function needs to be called before the increament of - // frame_coding_index_ - PostUpdateRefFrameInfo(encode_frame_result.frame_type, frame_coding_index_, - &ref_frame_info_); - ++frame_coding_index_; - if (encode_frame_result.frame_type != kFrameTypeAltRef) { - // Only kFrameTypeAltRef is not a show frame - ++show_frame_count_; - } - - PostUpdateKeyFrameGroupIndex(encode_frame_result.frame_type); - if (key_frame_group_index_ == key_frame_group_size_) { - UpdateKeyFrameGroup(show_frame_count_); - } - - IncreaseGroupOfPictureIndex(&group_of_picture_); - if (IsGroupOfPictureFinished(group_of_picture_)) { - const GOP_COMMAND gop_command = GetGopCommand(gop_map_, show_frame_count_); - encode_command_set_gop_command(&impl_ptr_->cpi->encode_command, - gop_command); - // This function needs to be called after ref_frame_info_ is updated - // properly in PostUpdateRefFrameInfo() and UpdateKeyFrameGroup(). - UpdateGroupOfPicture(impl_ptr_->cpi, frame_coding_index_, ref_frame_info_, - &group_of_picture_); - } -} - -void SimpleEncode::EncodeFrame(EncodeFrameResult *encode_frame_result) { - VP9_COMP *cpi = impl_ptr_->cpi; - struct lookahead_ctx *lookahead = cpi->lookahead; - int use_highbitdepth = 0; -#if CONFIG_VP9_HIGHBITDEPTH - use_highbitdepth = cpi->common.use_highbitdepth; -#endif - // The lookahead's size is set to oxcf->lag_in_frames. - // We want to fill lookahead to it's max capacity if possible so that the - // encoder can construct alt ref frame in time. - // In the other words, we hope vp9_get_compressed_data to encode a frame - // every time in the function - while (!vp9_lookahead_full(lookahead)) { - // TODO(angiebird): Check whether we can move this file read logics to - // lookahead - if (img_read(&impl_ptr_->tmp_img, in_file_)) { - int next_show_idx = vp9_lookahead_next_show_idx(lookahead); - int64_t ts_start = - timebase_units_to_ticks(&cpi->oxcf.g_timebase_in_ts, next_show_idx); - int64_t ts_end = timebase_units_to_ticks(&cpi->oxcf.g_timebase_in_ts, - next_show_idx + 1); - YV12_BUFFER_CONFIG sd; - image2yuvconfig(&impl_ptr_->tmp_img, &sd); - vp9_lookahead_push(lookahead, &sd, ts_start, ts_end, use_highbitdepth, 0); - } else { - break; - } - } - - if (init_encode_frame_result(encode_frame_result, frame_width_, frame_height_, - impl_ptr_->img_fmt)) { - int64_t time_stamp; - int64_t time_end; - int flush = 1; // Make vp9_get_compressed_data encode a frame - unsigned int frame_flags = 0; - ENCODE_FRAME_RESULT encode_frame_info; - vp9_init_encode_frame_result(&encode_frame_info); - ImageBuffer_to_IMAGE_BUFFER(encode_frame_result->coded_frame, - &encode_frame_info.coded_frame); - vp9_get_compressed_data(cpi, &frame_flags, - &encode_frame_result->coding_data_byte_size, - encode_frame_result->coding_data.get(), - encode_frame_result->max_coding_data_byte_size, - &time_stamp, &time_end, flush, &encode_frame_info); - if (out_file_ != nullptr) { - ivf_write_frame_header(out_file_, time_stamp, - encode_frame_result->coding_data_byte_size); - fwrite(encode_frame_result->coding_data.get(), 1, - encode_frame_result->coding_data_byte_size, out_file_); - } - - // vp9_get_compressed_data is expected to encode a frame every time, so the - // data size should be greater than zero. - if (encode_frame_result->coding_data_byte_size <= 0) { - fprintf(stderr, "Coding data size <= 0\n"); - abort(); - } - if (encode_frame_result->coding_data_byte_size > - encode_frame_result->max_coding_data_byte_size) { - fprintf(stderr, "Coding data size exceeds the maximum.\n"); - abort(); - } - - const GroupOfPicture group_of_picture = this->ObserveGroupOfPicture(); - const int show_frame_count = group_of_picture.show_frame_count; - update_encode_frame_result(encode_frame_result, show_frame_count, - &encode_frame_info); - PostUpdateState(*encode_frame_result); - } else { - // TODO(angiebird): Clean up encode_frame_result. - fprintf(stderr, "init_encode_frame_result() failed.\n"); - this->EndEncode(); - } -} - -void SimpleEncode::EncodeFrameWithQuantizeIndex( - EncodeFrameResult *encode_frame_result, int quantize_index) { - encode_command_set_external_quantize_index(&impl_ptr_->cpi->encode_command, - quantize_index); - EncodeFrame(encode_frame_result); - encode_command_reset_external_quantize_index(&impl_ptr_->cpi->encode_command); -} - -void SimpleEncode::EncodeFrameWithTargetFrameBits( - EncodeFrameResult *encode_frame_result, int target_frame_bits, - double percent_diff) { - encode_command_set_target_frame_bits(&impl_ptr_->cpi->encode_command, - target_frame_bits, percent_diff); - EncodeFrame(encode_frame_result); - encode_command_reset_target_frame_bits(&impl_ptr_->cpi->encode_command); -} - -static int GetCodingFrameNumFromGopMap(const std::vector &gop_map) { - int start_show_index = 0; - int coding_frame_count = 0; - while (static_cast(start_show_index) < gop_map.size()) { - const GOP_COMMAND gop_command = GetGopCommand(gop_map, start_show_index); - start_show_index += gop_command.show_frame_count; - coding_frame_count += gop_command_coding_frame_count(&gop_command); - } - assert(static_cast(start_show_index) == gop_map.size()); - return coding_frame_count; -} - -int SimpleEncode::GetCodingFrameNum() const { - assert(impl_ptr_->first_pass_stats.size() > 0); - if (gop_map_.size() > 0) { - return GetCodingFrameNumFromGopMap(gop_map_); - } - - // These are the default settings for now. - TWO_PASS twopass; - const int multi_layer_arf = 0; - const int allow_alt_ref = 1; - vpx_rational_t frame_rate = - make_vpx_rational(frame_rate_num_, frame_rate_den_); - const VP9EncoderConfig oxcf = GetEncodeConfig( - frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_, - target_level_, VPX_RC_LAST_PASS, impl_ptr_->encode_config_list); - FRAME_INFO frame_info = vp9_get_frame_info(&oxcf); - fps_init_first_pass_info(&twopass.first_pass_info, - GetVectorData(impl_ptr_->first_pass_stats), - num_frames_); - unsigned int screen_area = frame_info.frame_width * frame_info.frame_height; - vp9_init_vizier_params(&twopass, screen_area); - return vp9_get_coding_frame_num(&oxcf, &twopass, &frame_info, multi_layer_arf, - allow_alt_ref); -} - -std::vector SimpleEncode::ComputeKeyFrameMap() const { - // The last entry of first_pass_stats is the overall stats. - assert(impl_ptr_->first_pass_stats.size() == - static_cast(num_frames_) + 1); - vpx_rational_t frame_rate = - make_vpx_rational(frame_rate_num_, frame_rate_den_); - const VP9EncoderConfig oxcf = GetEncodeConfig( - frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_, - target_level_, VPX_RC_LAST_PASS, impl_ptr_->encode_config_list); - TWO_PASS twopass; - fps_init_first_pass_info(&twopass.first_pass_info, - GetVectorData(impl_ptr_->first_pass_stats), - num_frames_); - std::vector key_frame_map(num_frames_, 0); - vp9_get_key_frame_map(&oxcf, &twopass, GetVectorData(key_frame_map)); - return key_frame_map; -} - -std::vector SimpleEncode::ObserveKeyFrameMap() const { - return key_frame_map_; -} - -uint64_t SimpleEncode::GetFramePixelCount() const { - assert(frame_width_ % 2 == 0); - assert(frame_height_ % 2 == 0); - switch (impl_ptr_->img_fmt) { - case VPX_IMG_FMT_I420: return frame_width_ * frame_height_ * 3 / 2; - case VPX_IMG_FMT_I422: return frame_width_ * frame_height_ * 2; - case VPX_IMG_FMT_I444: return frame_width_ * frame_height_ * 3; - case VPX_IMG_FMT_I440: return frame_width_ * frame_height_ * 2; - case VPX_IMG_FMT_I42016: return frame_width_ * frame_height_ * 3 / 2; - case VPX_IMG_FMT_I42216: return frame_width_ * frame_height_ * 2; - case VPX_IMG_FMT_I44416: return frame_width_ * frame_height_ * 3; - case VPX_IMG_FMT_I44016: return frame_width_ * frame_height_ * 2; - default: return 0; - } -} - -SimpleEncode::~SimpleEncode() { - if (in_file_ != nullptr) { - fclose(in_file_); - } - if (out_file_ != nullptr) { - fclose(out_file_); - } -} - -} // namespace vp9 diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/simple_encode.h b/presentation/src/main/cpp/third_party/libvpx/vp9/simple_encode.h deleted file mode 100644 index 94ecbf28..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/simple_encode.h +++ /dev/null @@ -1,584 +0,0 @@ -/* - * Copyright (c) 2019 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_SIMPLE_ENCODE_H_ -#define VPX_VP9_SIMPLE_ENCODE_H_ - -#include -#include -#include -#include -#include - -namespace vp9 { - -enum StatusCode { - StatusOk = 0, - StatusError, -}; - -// TODO(angiebird): Add description for each frame type. -enum FrameType { - kFrameTypeKey = 0, - kFrameTypeInter = 1, - kFrameTypeAltRef = 2, - kFrameTypeOverlay = 3, - kFrameTypeGolden = 4, -}; - -// TODO(angiebird): Add description for each reference frame type. -// This enum numbers have to be contiguous and start from zero except -// kNoneRefFrame. -enum RefFrameType { - kRefFrameTypeLast = 0, - kRefFrameTypePast = 1, - kRefFrameTypeFuture = 2, - kRefFrameTypeMax = 3, - kRefFrameTypeNone = -1, -}; - -enum VP9_LEVEL { - LEVEL_UNKNOWN = 0, - LEVEL_AUTO = 1, - LEVEL_1 = 10, - LEVEL_1_1 = 11, - LEVEL_2 = 20, - LEVEL_2_1 = 21, - LEVEL_3 = 30, - LEVEL_3_1 = 31, - LEVEL_4 = 40, - LEVEL_4_1 = 41, - LEVEL_5 = 50, - LEVEL_5_1 = 51, - LEVEL_5_2 = 52, - LEVEL_6 = 60, - LEVEL_6_1 = 61, - LEVEL_6_2 = 62, - LEVEL_MAX = 255 -}; - -enum GopMapFlag { - kGopMapFlagStart = - 1 << 0, // Indicate this location is the start of a group of pictures. - kGopMapFlagUseAltRef = - 1 << 1, // Indicate this group of pictures will use an alt ref. Only set - // this flag when kGopMapFlagStart is set. -}; - -// The frame is split to 4x4 blocks. -// This structure contains the information of each 4x4 block. -struct PartitionInfo { - int row; // row pixel offset of current 4x4 block - int column; // column pixel offset of current 4x4 block - int row_start; // row pixel offset of the start of the prediction block - int column_start; // column pixel offset of the start of the prediction block - int width; // prediction block width - int height; // prediction block height -}; - -constexpr int kMotionVectorSubPixelPrecision = 8; -constexpr int kMotionVectorFullPixelPrecision = 1; - -// In the first pass. The frame is split to 16x16 blocks. -// This structure contains the information of each 16x16 block. -// In the second pass. The frame is split to 4x4 blocks. -// This structure contains the information of each 4x4 block. -struct MotionVectorInfo { - // Number of valid motion vectors, always 0 if this block is in the key frame. - // For inter frames, it could be 1 or 2. - int mv_count; - // The reference frame for motion vectors. If the second motion vector does - // not exist (mv_count = 1), the reference frame is kNoneRefFrame. - // Otherwise, the reference frame is either kRefFrameTypeLast, or - // kRefFrameTypePast, or kRefFrameTypeFuture. - RefFrameType ref_frame[2]; - // The row offset of motion vectors in the unit of pixel. - // If the second motion vector does not exist, the value is 0. - double mv_row[2]; - // The column offset of motion vectors in the unit of pixel. - // If the second motion vector does not exist, the value is 0. - double mv_column[2]; -}; - -// Accumulated tpl stats of all blocks in one frame. -// For each frame, the tpl stats are computed per 32x32 block. -struct TplStatsInfo { - // Intra complexity: the sum of absolute transform difference (SATD) of - // intra predicted residuals. - int64_t intra_cost; - // Inter complexity: the SATD of inter predicted residuals. - int64_t inter_cost; - // Motion compensated information flow. It measures how much information - // is propagated from the current frame to other frames. - int64_t mc_flow; - // Motion compensated dependency cost. It equals to its own intra_cost - // plus the mc_flow. - int64_t mc_dep_cost; - // Motion compensated reference cost. - int64_t mc_ref_cost; -}; - -struct RefFrameInfo { - int coding_indexes[kRefFrameTypeMax]; - - // Indicate whether the reference frames are available or not. - // When the reference frame type is not valid, it means either the to-be-coded - // frame is a key frame or the reference frame already appears in other - // reference frame type. vp9 always keeps three types of reference frame - // available. However, the duplicated reference frames will not be - // chosen by the encoder. The priorities of choosing reference frames are - // kRefFrameTypeLast > kRefFrameTypePast > kRefFrameTypeFuture. - // For example, if kRefFrameTypeLast and kRefFrameTypePast both point to the - // same frame, kRefFrameTypePast will be set to invalid. - // 1: the ref frame type is available 0: the ref frame type is not available - int valid_list[kRefFrameTypeMax]; -}; - -bool operator==(const RefFrameInfo &a, const RefFrameInfo &b); - -struct EncodeFrameInfo { - int show_idx; - - // Each show or no show frame is assigned with a coding index based on its - // coding order (starting from zero) in the coding process of the entire - // video. The coding index for each frame is unique. - int coding_index; - RefFrameInfo ref_frame_info; - FrameType frame_type; -}; - -// This structure is a copy of vp9 |nmv_component_counts|. -struct NewMotionvectorComponentCounts { - std::vector sign; - std::vector classes; - std::vector class0; - std::vector> bits; - std::vector> class0_fp; - std::vector fp; - std::vector class0_hp; - std::vector hp; -}; - -// This structure is a copy of vp9 |nmv_context_counts|. -struct NewMotionVectorContextCounts { - std::vector joints; - std::vector comps; -}; - -using UintArray2D = std::vector>; -using UintArray3D = std::vector>>; -using UintArray5D = std::vector< - std::vector>>>>; -using UintArray6D = std::vector>>>>>; - -// This structure is a copy of vp9 |tx_counts|. -struct TransformSizeCounts { - // Transform size found in blocks of partition size 32x32. - // First dimension: transform size contexts (2). - // Second dimension: transform size type (3: 32x32, 16x16, 8x8) - UintArray2D p32x32; - // Transform size found in blocks of partition size 16x16. - // First dimension: transform size contexts (2). - // Second dimension: transform size type (2: 16x16, 8x8) - UintArray2D p16x16; - // Transform size found in blocks of partition size 8x8. - // First dimension: transform size contexts (2). - // Second dimension: transform size type (1: 8x8) - UintArray2D p8x8; - // Overall transform size count. - std::vector tx_totals; -}; - -// This structure is a copy of vp9 |FRAME_COUNTS|. -struct FrameCounts { - // Intra prediction mode for luma plane. First dimension: block size (4). - // Second dimension: intra prediction mode (10). - UintArray2D y_mode; - // Intra prediction mode for chroma plane. First and second dimension: - // intra prediction mode (10). - UintArray2D uv_mode; - // Partition type. First dimension: partition contexts (16). - // Second dimension: partition type (4). - UintArray2D partition; - // Transform coefficient. - UintArray6D coef; - // End of block (the position of the last non-zero transform coefficient) - UintArray5D eob_branch; - // Interpolation filter type. First dimension: switchable filter contexts (4). - // Second dimension: filter types (3). - UintArray2D switchable_interp; - // Inter prediction mode (the motion vector type). - // First dimension: inter mode contexts (7). - // Second dimension: mode type (4). - UintArray2D inter_mode; - // Block is intra or inter predicted. First dimension: contexts (4). - // Second dimension: type (0 for intra, 1 for inter). - UintArray2D intra_inter; - // Block is compound predicted (predicted from average of two blocks). - // First dimension: contexts (5). - // Second dimension: type (0 for single, 1 for compound prediction). - UintArray2D comp_inter; - // Type of the reference frame. Only one reference frame. - // First dimension: context (5). Second dimension: context (2). - // Third dimension: count (2). - UintArray3D single_ref; - // Type of the two reference frames. - // First dimension: context (5). Second dimension: count (2). - UintArray2D comp_ref; - // Block skips transform and quantization, uses prediction as reconstruction. - // First dimension: contexts (3). Second dimension: type (0 not skip, 1 skip). - UintArray2D skip; - // Transform size. - TransformSizeCounts tx; - // New motion vector. - NewMotionVectorContextCounts mv; -}; - -struct ImageBuffer { - // The image data is stored in raster order, - // i.e. image[plane][r][c] = - // plane_buffer[plane][r * plane_width[plane] + plane_height[plane]]. - std::unique_ptr plane_buffer[3]; - int plane_width[3]; - int plane_height[3]; -}; - -void output_image_buffer(const ImageBuffer &image_buffer, std::FILE *out_file); - -struct EncodeFrameResult { - int show_idx; - FrameType frame_type; - int coding_idx; - RefFrameInfo ref_frame_info; - size_t coding_data_bit_size; - size_t coding_data_byte_size; - // The EncodeFrame will allocate a buffer, write the coding data into the - // buffer and give the ownership of the buffer to coding_data. - std::unique_ptr coding_data; - size_t max_coding_data_byte_size; - double psnr; - uint64_t sse; - int quantize_index; - FrameCounts frame_counts; - int num_rows_4x4; // number of row units, in size of 4. - int num_cols_4x4; // number of column units, in size of 4. - // A vector of the partition information of the frame. - // The number of elements is |num_rows_4x4| * |num_cols_4x4|. - // The frame is divided 4x4 blocks of |num_rows_4x4| rows and - // |num_cols_4x4| columns. - // Each 4x4 block contains the current pixel position (|row|, |column|), - // the start pixel position of the partition (|row_start|, |column_start|), - // and the |width|, |height| of the partition. - // The current pixel position can be the same as the start pixel position - // if the 4x4 block is the top-left block in the partition. Otherwise, they - // are different. - // Within the same partition, all 4x4 blocks have the same |row_start|, - // |column_start|, |width| and |height|. - // For example, if the frame is partitioned to a 32x32 block, - // starting at (0, 0). Then, there're 64 4x4 blocks within this partition. - // They all have the same |row_start|, |column_start|, |width|, |height|, - // which can be used to figure out the start of the current partition and - // the start of the next partition block. - // Horizontal next: |column_start| + |width|, - // Vertical next: |row_start| + |height|. - std::vector partition_info; - // A vector of the motion vector information of the frame. - // The number of elements is |num_rows_4x4| * |num_cols_4x4|. - // The frame is divided into 4x4 blocks of |num_rows_4x4| rows and - // |num_cols_4x4| columns. - // Each 4x4 block contains 0 motion vector if this is an intra predicted - // frame (for example, the key frame). If the frame is inter predicted, - // each 4x4 block contains either 1 or 2 motion vectors. - // Similar to partition info, all 4x4 blocks inside the same partition block - // share the same motion vector information. - std::vector motion_vector_info; - // A vector of the tpl stats information. - // The tpl stats measure the complexity of a frame, as well as the - // information propagated along the motion trajectory between frames, in - // the reference frame structure. - // The tpl stats could be used as a more accurate spatial and temporal - // complexity measure in addition to the first pass stats. - // The vector contains tpl stats for all show frames in a GOP. - // The tpl stats stored in the vector is according to the encoding order. - // For example, suppose there are N show frames for the current GOP. - // Then tpl_stats_info[0] stores the information of the first frame to be - // encoded for this GOP, i.e., the AltRef frame. - std::vector tpl_stats_info; - ImageBuffer coded_frame; - - // recode_count, q_index_history and rate_history are only available when - // EncodeFrameWithTargetFrameBits() is used. - int recode_count; - std::vector q_index_history; - std::vector rate_history; -}; - -struct GroupOfPicture { - // This list will be updated internally in StartEncode() and - // EncodeFrame()/EncodeFrameWithQuantizeIndex(). - // In EncodeFrame()/EncodeFrameWithQuantizeIndex(), the update will only be - // triggered when the coded frame is the last one in the previous group of - // pictures. - std::vector encode_frame_list; - - // Indicates the index of the next coding frame in encode_frame_list. - // In other words, EncodeFrameInfo of the next coding frame can be - // obtained with encode_frame_list[next_encode_frame_index]. - // Internally, next_encode_frame_index will be set to zero after the last - // frame of the group of pictures is coded. Otherwise, next_encode_frame_index - // will be increased after each EncodeFrame()/EncodeFrameWithQuantizeIndex() - // call. - int next_encode_frame_index; - - // Number of show frames in this group of pictures. - int show_frame_count; - - // The show index/timestamp of the earliest show frame in the group of - // pictures. - int start_show_index; - - // The coding index of the first coding frame in the group of pictures. - int start_coding_index; - - // Indicates whether this group of pictures starts with a key frame. - int first_is_key_frame; - - // Indicates whether this group of pictures uses an alt ref. - int use_alt_ref; - - // Indicates whether previous group of pictures used an alt ref. - int last_gop_use_alt_ref; -}; - -class SimpleEncode { - public: - // When outfile_path is set, the encoder will output the bitstream in ivf - // format. - SimpleEncode(int frame_width, int frame_height, int frame_rate_num, - int frame_rate_den, int target_bitrate, int num_frames, - int target_level, const char *infile_path, - const char *outfile_path = nullptr); - ~SimpleEncode(); - SimpleEncode(SimpleEncode &) = delete; - SimpleEncode &operator=(const SimpleEncode &) = delete; - - // Adjusts the encoder's coding speed. - // If this function is not called, the encoder will use default encode_speed - // 0. Call this function before ComputeFirstPassStats() if needed. - // The encode_speed is equivalent to --cpu-used of the vpxenc command. - // The encode_speed's range should be [0, 9]. - // Setting the encode_speed to a higher level will yield faster coding - // at the cost of lower compression efficiency. - void SetEncodeSpeed(int encode_speed); - - // Set encoder config - // The following configs in VP9EncoderConfig are allowed to change in this - // function. See https://ffmpeg.org/ffmpeg-codecs.html#libvpx for each - // config's meaning. - // Configs in VP9EncoderConfig: Equivalent configs in ffmpeg: - // 1 key_freq -g - // 2 two_pass_vbrmin_section -minrate * 100LL / bit_rate - // 3 two_pass_vbrmax_section -maxrate * 100LL / bit_rate - // 4 under_shoot_pct -undershoot-pct - // 5 over_shoot_pct -overshoot-pct - // 6 max_threads -threads - // 7 frame_parallel_decoding_mode -frame-parallel - // 8 tile_column -tile-columns - // 9 arnr_max_frames -arnr-maxframes - // 10 arnr_strength -arnr-strength - // 11 lag_in_frames -rc_lookahead - // 12 encode_breakout -static-thresh - // 13 enable_tpl_model -enable-tpl - // 14 enable_auto_arf -auto-alt-ref - // 15 rc_mode - // Possible Settings: - // 0 - Variable Bit Rate (VPX_VBR) -b:v - // 1 - Constant Bit Rate (VPX_CBR) -b:v -minrate - // -maxrate - // two_pass_vbrmin_section == 100 i.e. bit_rate == minrate == maxrate - // two_pass_vbrmax_section == 100 - // 2 - Constrained Quality (VPX_CQ) -crf -b:v bit_rate - // 3 - Constant Quality (VPX_Q) -crf -b:v 0 - // See https://trac.ffmpeg.org/wiki/Encode/VP9 for more details. - // 16 cq_level see rc_mode for details. - StatusCode SetEncodeConfig(const char *name, const char *value); - - // A debug function that dumps configs from VP9EncoderConfig - // pass = 1: first pass, pass = 2: second pass - // fp: file pointer for dumping config - StatusCode DumpEncodeConfigs(int pass, FILE *fp); - - // Makes encoder compute the first pass stats and store it at - // impl_ptr_->first_pass_stats. key_frame_map_ is also computed based on the - // first pass stats. - void ComputeFirstPassStats(); - - // Outputs the first pass stats represented by a 2-D vector. - // One can use the frame index at first dimension to retrieve the stats for - // each video frame. The stats of each video frame is a vector of 25 double - // values. For details, please check FIRSTPASS_STATS in vp9_firstpass.h - std::vector> ObserveFirstPassStats(); - - // Outputs the first pass motion vectors represented by a 2-D vector. - // One can use the frame index at first dimension to retrieve the mvs for - // each video frame. The frame is divided into 16x16 blocks. The number of - // elements is round_up(|num_rows_4x4| / 4) * round_up(|num_cols_4x4| / 4). - std::vector> ObserveFirstPassMotionVectors(); - - // Ouputs a copy of key_frame_map_, a binary vector with size equal to the - // number of show frames in the video. For each entry in the vector, 1 - // indicates the position is a key frame and 0 indicates it's not a key frame. - // This function should be called after ComputeFirstPassStats() - std::vector ObserveKeyFrameMap() const; - - // Sets group of pictures map for coding the entire video. - // Each entry in the gop_map corresponds to a show frame in the video. - // Therefore, the size of gop_map should equal to the number of show frames in - // the entire video. - // If a given entry's kGopMapFlagStart is set, it means this is the start of a - // gop. Once kGopMapFlagStart is set, one can set kGopMapFlagUseAltRef to - // indicate whether this gop use altref. - // If a given entry is zero, it means it's in the middle of a gop. - // This function should be called only once after ComputeFirstPassStats(), - // before StartEncode(). - // This API will check and modify the gop_map to satisfy the following - // constraints. - // 1) Each key frame position should be at the start of a gop. - // 2) The last gop should not use an alt ref. - void SetExternalGroupOfPicturesMap(int *gop_map, int gop_map_size); - - // Observe the group of pictures map set through - // SetExternalGroupOfPicturesMap(). This function should be called after - // SetExternalGroupOfPicturesMap(). - std::vector ObserveExternalGroupOfPicturesMap(); - - // Initializes the encoder for actual encoding. - // This function should be called after ComputeFirstPassStats(). - void StartEncode(); - - // Frees the encoder. - // This function should be called after StartEncode() or EncodeFrame(). - void EndEncode(); - - // The key frame group size includes one key frame plus the number of - // following inter frames. Note that the key frame group size only counts the - // show frames. The number of no show frames like alternate refereces are not - // counted. - int GetKeyFrameGroupSize() const; - - // Provides the group of pictures that the next coding frame is in. - // Only call this function between StartEncode() and EndEncode() - GroupOfPicture ObserveGroupOfPicture() const; - - // Gets encode_frame_info for the next coding frame. - // Only call this function between StartEncode() and EndEncode() - EncodeFrameInfo GetNextEncodeFrameInfo() const; - - // Encodes a frame - // This function should be called after StartEncode() and before EndEncode(). - void EncodeFrame(EncodeFrameResult *encode_frame_result); - - // Encodes a frame with a specific quantize index. - // This function should be called after StartEncode() and before EndEncode(). - void EncodeFrameWithQuantizeIndex(EncodeFrameResult *encode_frame_result, - int quantize_index); - - // Encode a frame with target frame bits usage. - // The encoder will find a quantize index to make the actual frame bits usage - // match the target. EncodeFrameWithTargetFrameBits() will recode the frame - // up to 7 times to find a q_index to make the actual_frame_bits satisfy the - // following inequality. |actual_frame_bits - target_frame_bits| * 100 / - // target_frame_bits - // <= percent_diff. - void EncodeFrameWithTargetFrameBits(EncodeFrameResult *encode_frame_result, - int target_frame_bits, - double percent_diff); - - // Gets the number of coding frames for the video. The coding frames include - // show frame and no show frame. - // This function should be called after ComputeFirstPassStats(). - int GetCodingFrameNum() const; - - // Gets the total number of pixels of YUV planes per frame. - uint64_t GetFramePixelCount() const; - - private: - // Compute the key frame locations of the video based on first pass stats. - // The results are returned as a binary vector with 1s indicating keyframes - // and 0s indicating non keyframes. - // It has to be called after impl_ptr_->first_pass_stats is computed. - std::vector ComputeKeyFrameMap() const; - - // Updates key_frame_group_size_, reset key_frame_group_index_ and init - // ref_frame_info_. - void UpdateKeyFrameGroup(int key_frame_show_index); - - // Update key_frame_group_index_. - void PostUpdateKeyFrameGroupIndex(FrameType frame_type); - - void PostUpdateState(const EncodeFrameResult &encode_frame_result); - - class EncodeImpl; - - int frame_width_; // frame width in pixels. - int frame_height_; // frame height in pixels. - int frame_rate_num_; - int frame_rate_den_; - int target_bitrate_; - int num_frames_; - int encode_speed_; - int target_level_; - - std::FILE *in_file_; - std::FILE *out_file_; - std::unique_ptr impl_ptr_; - - std::vector key_frame_map_; - std::vector gop_map_; - GroupOfPicture group_of_picture_; - - // The key frame group size includes one key frame plus the number of - // following inter frames. Note that the key frame group size only counts the - // show frames. The number of no show frames like alternate references are not - // counted. - int key_frame_group_size_; - - // The index for the to-be-coded show frame in the key frame group. - int key_frame_group_index_; - - // Each show or no show frame is assigned with a coding index based on its - // coding order (starting from zero) in the coding process of the entire - // video. The coding index of the to-be-coded frame. - int frame_coding_index_; - - // Number of show frames we have coded so far. - int show_frame_count_; - - // TODO(angiebird): Do we need to reset ref_frames_info_ when the next key - // frame appears? - // Reference frames info of the to-be-coded frame. - RefFrameInfo ref_frame_info_; - - // A 2-D vector of motion vector information of the frame collected - // from the first pass. The first dimension is the frame index. - // Each frame is divided into 16x16 blocks. The number of elements is - // round_up(|num_rows_4x4| / 4) * round_up(|num_cols_4x4| / 4). - // Each 16x16 block contains 0 motion vector if this is an intra predicted - // frame (for example, the key frame). If the frame is inter predicted, - // each 16x16 block contains either 1 or 2 motion vectors. - // The first motion vector is always from the LAST_FRAME. - // The second motion vector is always from the GOLDEN_FRAME. - std::vector> fp_motion_vector_info_; -}; - -} // namespace vp9 - -#endif // VPX_VP9_SIMPLE_ENCODE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_common.mk b/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_common.mk deleted file mode 100644 index 5ef2f891..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_common.mk +++ /dev/null @@ -1,99 +0,0 @@ -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -VP9_COMMON_SRCS-yes += vp9_common.mk -VP9_COMMON_SRCS-yes += vp9_iface_common.h -VP9_COMMON_SRCS-yes += vp9_iface_common.c -VP9_COMMON_SRCS-yes += common/vp9_ppflags.h -VP9_COMMON_SRCS-yes += common/vp9_alloccommon.c -VP9_COMMON_SRCS-yes += common/vp9_blockd.c -# VP9_COMMON_SRCS-yes += common/vp9_debugmodes.c -VP9_COMMON_SRCS-yes += common/vp9_entropy.c -VP9_COMMON_SRCS-yes += common/vp9_entropymode.c -VP9_COMMON_SRCS-yes += common/vp9_entropymv.c -VP9_COMMON_SRCS-yes += common/vp9_frame_buffers.c -VP9_COMMON_SRCS-yes += common/vp9_frame_buffers.h -VP9_COMMON_SRCS-yes += common/vp9_idct.c -VP9_COMMON_SRCS-yes += common/vp9_alloccommon.h -VP9_COMMON_SRCS-yes += common/vp9_blockd.h -VP9_COMMON_SRCS-yes += common/vp9_common.h -VP9_COMMON_SRCS-yes += common/vp9_entropy.h -VP9_COMMON_SRCS-yes += common/vp9_entropymode.h -VP9_COMMON_SRCS-yes += common/vp9_entropymv.h -VP9_COMMON_SRCS-yes += common/vp9_enums.h -VP9_COMMON_SRCS-yes += common/vp9_filter.h -VP9_COMMON_SRCS-yes += common/vp9_filter.c -VP9_COMMON_SRCS-yes += common/vp9_idct.h -VP9_COMMON_SRCS-yes += common/vp9_loopfilter.h -VP9_COMMON_SRCS-yes += common/vp9_thread_common.h -VP9_COMMON_SRCS-yes += common/vp9_mv.h -VP9_COMMON_SRCS-yes += common/vp9_onyxc_int.h -VP9_COMMON_SRCS-yes += common/vp9_pred_common.h -VP9_COMMON_SRCS-yes += common/vp9_pred_common.c -VP9_COMMON_SRCS-yes += common/vp9_quant_common.h -VP9_COMMON_SRCS-yes += common/vp9_reconinter.h -VP9_COMMON_SRCS-yes += common/vp9_reconintra.h -VP9_COMMON_SRCS-yes += common/vp9_rtcd.c -VP9_COMMON_SRCS-yes += common/vp9_rtcd_defs.pl -VP9_COMMON_SRCS-yes += common/vp9_scale.h -VP9_COMMON_SRCS-yes += common/vp9_scale.c -VP9_COMMON_SRCS-yes += common/vp9_seg_common.h -VP9_COMMON_SRCS-yes += common/vp9_seg_common.c -VP9_COMMON_SRCS-yes += common/vp9_tile_common.h -VP9_COMMON_SRCS-yes += common/vp9_tile_common.c -VP9_COMMON_SRCS-yes += common/vp9_loopfilter.c -VP9_COMMON_SRCS-yes += common/vp9_thread_common.c -VP9_COMMON_SRCS-yes += common/vp9_mvref_common.c -VP9_COMMON_SRCS-yes += common/vp9_mvref_common.h -VP9_COMMON_SRCS-yes += common/vp9_quant_common.c -VP9_COMMON_SRCS-yes += common/vp9_reconinter.c -VP9_COMMON_SRCS-yes += common/vp9_reconintra.c -VP9_COMMON_SRCS-yes += common/vp9_common_data.c -VP9_COMMON_SRCS-yes += common/vp9_common_data.h -VP9_COMMON_SRCS-yes += common/vp9_scan.c -VP9_COMMON_SRCS-yes += common/vp9_scan.h - -VP9_COMMON_SRCS-$(CONFIG_VP9_POSTPROC) += common/vp9_postproc.h -VP9_COMMON_SRCS-$(CONFIG_VP9_POSTPROC) += common/vp9_postproc.c -VP9_COMMON_SRCS-$(CONFIG_VP9_POSTPROC) += common/vp9_mfqe.h -VP9_COMMON_SRCS-$(CONFIG_VP9_POSTPROC) += common/vp9_mfqe.c - -ifneq ($(CONFIG_VP9_HIGHBITDEPTH),yes) -VP9_COMMON_SRCS-$(HAVE_MSA) += common/mips/msa/vp9_idct4x4_msa.c -VP9_COMMON_SRCS-$(HAVE_MSA) += common/mips/msa/vp9_idct8x8_msa.c -VP9_COMMON_SRCS-$(HAVE_MSA) += common/mips/msa/vp9_idct16x16_msa.c -endif # !CONFIG_VP9_HIGHBITDEPTH - -VP9_COMMON_SRCS-$(HAVE_SSE2) += common/x86/vp9_idct_intrin_sse2.c -VP9_COMMON_SRCS-$(HAVE_VSX) += common/ppc/vp9_idct_vsx.c -VP9_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp9_iht4x4_add_neon.c -VP9_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp9_iht8x8_add_neon.c -VP9_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp9_iht16x16_add_neon.c -VP9_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp9_iht_neon.h - -ifeq ($(CONFIG_VP9_POSTPROC),yes) -VP9_COMMON_SRCS-$(HAVE_MSA) += common/mips/msa/vp9_mfqe_msa.c -VP9_COMMON_SRCS-$(HAVE_SSE2) += common/x86/vp9_mfqe_sse2.asm -endif - -ifneq ($(CONFIG_VP9_HIGHBITDEPTH),yes) -VP9_COMMON_SRCS-$(HAVE_DSPR2) += common/mips/dspr2/vp9_itrans4_dspr2.c -VP9_COMMON_SRCS-$(HAVE_DSPR2) += common/mips/dspr2/vp9_itrans8_dspr2.c -VP9_COMMON_SRCS-$(HAVE_DSPR2) += common/mips/dspr2/vp9_itrans16_dspr2.c -else -VP9_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp9_highbd_iht4x4_add_neon.c -VP9_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp9_highbd_iht8x8_add_neon.c -VP9_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp9_highbd_iht16x16_add_neon.c -VP9_COMMON_SRCS-$(HAVE_SSE4_1) += common/x86/vp9_highbd_iht4x4_add_sse4.c -VP9_COMMON_SRCS-$(HAVE_SSE4_1) += common/x86/vp9_highbd_iht8x8_add_sse4.c -VP9_COMMON_SRCS-$(HAVE_SSE4_1) += common/x86/vp9_highbd_iht16x16_add_sse4.c -endif - -$(eval $(call rtcd_h_template,vp9_rtcd,vp9/common/vp9_rtcd_defs.pl)) diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_cx_iface.c b/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_cx_iface.c deleted file mode 100644 index 55a2d0b7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_cx_iface.c +++ /dev/null @@ -1,2515 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "./vpx_config.h" -#include "vpx/vpx_encoder.h" -#include "vpx/vpx_ext_ratectrl.h" -#include "vpx_dsp/psnr.h" -#include "vpx_ports/static_assert.h" -#include "vpx_ports/system_state.h" -#include "vpx_util/vpx_timestamp.h" -#include "vpx/internal/vpx_codec_internal.h" -#include "./vpx_version.h" -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/encoder/vp9_ethread.h" -#include "vpx/vp8cx.h" -#include "vp9/common/vp9_alloccommon.h" -#include "vp9/common/vp9_scale.h" -#include "vp9/vp9_cx_iface.h" -#include "vp9/encoder/vp9_firstpass.h" -#include "vp9/encoder/vp9_lookahead.h" -#include "vp9/vp9_cx_iface.h" -#include "vp9/vp9_iface_common.h" - -#include "vpx/vpx_tpl.h" - -typedef struct vp9_extracfg { - int cpu_used; // available cpu percentage in 1/16 - unsigned int enable_auto_alt_ref; - unsigned int noise_sensitivity; - unsigned int sharpness; - unsigned int static_thresh; - unsigned int tile_columns; - unsigned int tile_rows; - unsigned int enable_tpl_model; - unsigned int enable_keyframe_filtering; - unsigned int arnr_max_frames; - unsigned int arnr_strength; - unsigned int min_gf_interval; - unsigned int max_gf_interval; - vp8e_tuning tuning; - unsigned int cq_level; // constrained quality level - unsigned int rc_max_intra_bitrate_pct; - unsigned int rc_max_inter_bitrate_pct; - unsigned int gf_cbr_boost_pct; - unsigned int lossless; - unsigned int target_level; - unsigned int frame_parallel_decoding_mode; - AQ_MODE aq_mode; - int alt_ref_aq; - unsigned int frame_periodic_boost; - vpx_bit_depth_t bit_depth; - vp9e_tune_content content; - vpx_color_space_t color_space; - vpx_color_range_t color_range; - int render_width; - int render_height; - unsigned int row_mt; - unsigned int motion_vector_unit_test; - int delta_q_uv; -} vp9_extracfg; - -static struct vp9_extracfg default_extra_cfg = { -#if CONFIG_REALTIME_ONLY - 5, // cpu_used -#else - 0, // cpu_used -#endif - 1, // enable_auto_alt_ref - 0, // noise_sensitivity - 0, // sharpness - 0, // static_thresh - 6, // tile_columns - 0, // tile_rows - 1, // enable_tpl_model - 0, // enable_keyframe_filtering - 7, // arnr_max_frames - 5, // arnr_strength - 0, // min_gf_interval; 0 -> default decision - 0, // max_gf_interval; 0 -> default decision - VP8_TUNE_PSNR, // tuning - 10, // cq_level - 0, // rc_max_intra_bitrate_pct - 0, // rc_max_inter_bitrate_pct - 0, // gf_cbr_boost_pct - 0, // lossless - 255, // target_level - 1, // frame_parallel_decoding_mode - NO_AQ, // aq_mode - 0, // alt_ref_aq - 0, // frame_periodic_delta_q - VPX_BITS_8, // Bit depth - VP9E_CONTENT_DEFAULT, // content - VPX_CS_UNKNOWN, // color space - 0, // color range - 0, // render width - 0, // render height - 0, // row_mt - 0, // motion_vector_unit_test - 0, // delta_q_uv -}; - -struct vpx_codec_alg_priv { - vpx_codec_priv_t base; - vpx_codec_enc_cfg_t cfg; - struct vp9_extracfg extra_cfg; - vpx_codec_pts_t pts_offset; - unsigned char pts_offset_initialized; - VP9EncoderConfig oxcf; - VP9_COMP *cpi; - unsigned char *cx_data; - size_t cx_data_sz; - unsigned char *pending_cx_data; - size_t pending_cx_data_sz; - int pending_frame_count; - size_t pending_frame_sizes[8]; - size_t pending_frame_magnitude; - vpx_image_t preview_img; - vpx_enc_frame_flags_t next_frame_flags; - vp8_postproc_cfg_t preview_ppcfg; - vpx_codec_pkt_list_decl(256) pkt_list; - unsigned int fixed_kf_cntr; - vpx_codec_priv_output_cx_pkt_cb_pair_t output_cx_pkt_cb; - // BufferPool that holds all reference frames. - BufferPool *buffer_pool; - vpx_fixed_buf_t global_headers; - int global_header_subsampling; -}; - -// Called by encoder_set_config() and encoder_encode() only. Must not be called -// by encoder_init() because the `error` paramerer (cpi->common.error) will be -// destroyed by vpx_codec_enc_init_ver() after encoder_init() returns an error. -// See the "IMPORTANT" comment in vpx_codec_enc_init_ver(). -static vpx_codec_err_t update_error_state( - vpx_codec_alg_priv_t *ctx, const struct vpx_internal_error_info *error) { - const vpx_codec_err_t res = error->error_code; - - if (res != VPX_CODEC_OK) - ctx->base.err_detail = error->has_detail ? error->detail : NULL; - - return res; -} - -#undef ERROR -#define ERROR(str) \ - do { \ - ctx->base.err_detail = str; \ - return VPX_CODEC_INVALID_PARAM; \ - } while (0) - -#define RANGE_CHECK(p, memb, lo, hi) \ - do { \ - if (!(((p)->memb == (lo) || (p)->memb > (lo)) && (p)->memb <= (hi))) \ - ERROR(#memb " out of range [" #lo ".." #hi "]"); \ - } while (0) - -#define RANGE_CHECK_HI(p, memb, hi) \ - do { \ - if (!((p)->memb <= (hi))) ERROR(#memb " out of range [.." #hi "]"); \ - } while (0) - -#define RANGE_CHECK_LO(p, memb, lo) \ - do { \ - if (!((p)->memb >= (lo))) ERROR(#memb " out of range [" #lo "..]"); \ - } while (0) - -#define RANGE_CHECK_BOOL(p, memb) \ - do { \ - if (!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean"); \ - } while (0) - -static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, - const vpx_codec_enc_cfg_t *cfg, - const struct vp9_extracfg *extra_cfg) { - RANGE_CHECK(cfg, g_w, 1, 65536); // 16 bits available - RANGE_CHECK(cfg, g_h, 1, 65536); // 16 bits available - RANGE_CHECK(cfg, g_timebase.den, 1, 1000000000); - RANGE_CHECK(cfg, g_timebase.num, 1, 1000000000); - RANGE_CHECK_HI(cfg, g_profile, 3); - - RANGE_CHECK_HI(cfg, rc_max_quantizer, 63); - RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer); - RANGE_CHECK_BOOL(extra_cfg, lossless); - RANGE_CHECK_BOOL(extra_cfg, frame_parallel_decoding_mode); - RANGE_CHECK(extra_cfg, aq_mode, 0, AQ_MODE_COUNT - 2); - RANGE_CHECK(extra_cfg, alt_ref_aq, 0, 1); - RANGE_CHECK(extra_cfg, frame_periodic_boost, 0, 1); - RANGE_CHECK_HI(cfg, g_threads, MAX_NUM_THREADS); - RANGE_CHECK_HI(cfg, g_lag_in_frames, MAX_LAG_BUFFERS); - RANGE_CHECK(cfg, rc_end_usage, VPX_VBR, VPX_Q); - RANGE_CHECK_HI(cfg, rc_undershoot_pct, 100); - RANGE_CHECK_HI(cfg, rc_overshoot_pct, 100); - RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100); - RANGE_CHECK(cfg, rc_2pass_vbr_corpus_complexity, 0, 10000); - RANGE_CHECK(cfg, kf_mode, VPX_KF_DISABLED, VPX_KF_AUTO); - RANGE_CHECK_BOOL(cfg, rc_resize_allowed); - RANGE_CHECK_HI(cfg, rc_dropframe_thresh, 100); - RANGE_CHECK_HI(cfg, rc_resize_up_thresh, 100); - RANGE_CHECK_HI(cfg, rc_resize_down_thresh, 100); -#if CONFIG_REALTIME_ONLY - RANGE_CHECK(cfg, g_pass, VPX_RC_ONE_PASS, VPX_RC_ONE_PASS); -#else - RANGE_CHECK(cfg, g_pass, VPX_RC_ONE_PASS, VPX_RC_LAST_PASS); -#endif - RANGE_CHECK(extra_cfg, min_gf_interval, 0, (MAX_LAG_BUFFERS - 1)); - RANGE_CHECK(extra_cfg, max_gf_interval, 0, (MAX_LAG_BUFFERS - 1)); - if (extra_cfg->max_gf_interval > 0) { - RANGE_CHECK(extra_cfg, max_gf_interval, 2, (MAX_LAG_BUFFERS - 1)); - } - if (extra_cfg->min_gf_interval > 0 && extra_cfg->max_gf_interval > 0) { - RANGE_CHECK(extra_cfg, max_gf_interval, extra_cfg->min_gf_interval, - (MAX_LAG_BUFFERS - 1)); - } - - // For formation of valid ARF groups lag_in _frames should be 0 or greater - // than the max_gf_interval + 2 - if (cfg->g_lag_in_frames > 0 && extra_cfg->max_gf_interval > 0 && - cfg->g_lag_in_frames < extra_cfg->max_gf_interval + 2) { - ERROR("Set lag in frames to 0 (low delay) or >= (max-gf-interval + 2)"); - } - - if (cfg->rc_resize_allowed == 1) { - RANGE_CHECK(cfg, rc_scaled_width, 0, cfg->g_w); - RANGE_CHECK(cfg, rc_scaled_height, 0, cfg->g_h); - } - - RANGE_CHECK(cfg, ss_number_layers, 1, VPX_SS_MAX_LAYERS); - RANGE_CHECK(cfg, ts_number_layers, 1, VPX_TS_MAX_LAYERS); - - { - unsigned int level = extra_cfg->target_level; - if (level != LEVEL_1 && level != LEVEL_1_1 && level != LEVEL_2 && - level != LEVEL_2_1 && level != LEVEL_3 && level != LEVEL_3_1 && - level != LEVEL_4 && level != LEVEL_4_1 && level != LEVEL_5 && - level != LEVEL_5_1 && level != LEVEL_5_2 && level != LEVEL_6 && - level != LEVEL_6_1 && level != LEVEL_6_2 && level != LEVEL_UNKNOWN && - level != LEVEL_AUTO && level != LEVEL_MAX) - ERROR("target_level is invalid"); - } - - if (cfg->ss_number_layers * cfg->ts_number_layers > VPX_MAX_LAYERS) - ERROR("ss_number_layers * ts_number_layers is out of range"); - if (cfg->ts_number_layers > 1) { - unsigned int sl, tl; - for (sl = 1; sl < cfg->ss_number_layers; ++sl) { - for (tl = 1; tl < cfg->ts_number_layers; ++tl) { - const int layer = LAYER_IDS_TO_IDX(sl, tl, cfg->ts_number_layers); - if (cfg->layer_target_bitrate[layer] < - cfg->layer_target_bitrate[layer - 1]) - ERROR("ts_target_bitrate entries are not increasing"); - } - } - - RANGE_CHECK(cfg, ts_rate_decimator[cfg->ts_number_layers - 1], 1, 1); - for (tl = cfg->ts_number_layers - 2; tl > 0; --tl) - if (cfg->ts_rate_decimator[tl - 1] != 2 * cfg->ts_rate_decimator[tl]) - ERROR("ts_rate_decimator factors are not powers of 2"); - } - - // VP9 does not support a lower bound on the keyframe interval in - // automatic keyframe placement mode. - if (cfg->kf_mode != VPX_KF_DISABLED && cfg->kf_min_dist != cfg->kf_max_dist && - cfg->kf_min_dist > 0) - ERROR( - "kf_min_dist not supported in auto mode, use 0 " - "or kf_max_dist instead."); - - RANGE_CHECK(extra_cfg, row_mt, 0, 1); - RANGE_CHECK(extra_cfg, motion_vector_unit_test, 0, 2); - RANGE_CHECK(extra_cfg, enable_auto_alt_ref, 0, MAX_ARF_LAYERS); - RANGE_CHECK(extra_cfg, cpu_used, -9, 9); - RANGE_CHECK_HI(extra_cfg, noise_sensitivity, 6); - RANGE_CHECK(extra_cfg, tile_columns, 0, 6); - RANGE_CHECK(extra_cfg, tile_rows, 0, 2); - RANGE_CHECK_HI(extra_cfg, sharpness, 7); - RANGE_CHECK(extra_cfg, arnr_max_frames, 0, 15); - RANGE_CHECK_HI(extra_cfg, arnr_strength, 6); - RANGE_CHECK(extra_cfg, cq_level, 0, 63); - RANGE_CHECK(cfg, g_bit_depth, VPX_BITS_8, VPX_BITS_12); - RANGE_CHECK(cfg, g_input_bit_depth, 8, 12); - RANGE_CHECK(extra_cfg, content, VP9E_CONTENT_DEFAULT, - VP9E_CONTENT_INVALID - 1); - -#if !CONFIG_REALTIME_ONLY - if (cfg->g_pass == VPX_RC_LAST_PASS) { - const size_t packet_sz = sizeof(FIRSTPASS_STATS); - const int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz); - const FIRSTPASS_STATS *stats; - - if (cfg->rc_twopass_stats_in.buf == NULL) - ERROR("rc_twopass_stats_in.buf not set."); - - if (cfg->rc_twopass_stats_in.sz % packet_sz) - ERROR("rc_twopass_stats_in.sz indicates truncated packet."); - - if (cfg->ss_number_layers > 1 || cfg->ts_number_layers > 1) { - int i; - unsigned int n_packets_per_layer[VPX_SS_MAX_LAYERS] = { 0 }; - - stats = cfg->rc_twopass_stats_in.buf; - for (i = 0; i < n_packets; ++i) { - const int layer_id = (int)stats[i].spatial_layer_id; - if (layer_id >= 0 && layer_id < (int)cfg->ss_number_layers) { - ++n_packets_per_layer[layer_id]; - } - } - - for (i = 0; i < (int)cfg->ss_number_layers; ++i) { - unsigned int layer_id; - if (n_packets_per_layer[i] < 2) { - ERROR( - "rc_twopass_stats_in requires at least two packets for each " - "layer."); - } - - stats = (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + - n_packets - cfg->ss_number_layers + i; - layer_id = (int)stats->spatial_layer_id; - - if (layer_id >= cfg->ss_number_layers || - (unsigned int)(stats->count + 0.5) != - n_packets_per_layer[layer_id] - 1) - ERROR("rc_twopass_stats_in missing EOS stats packet"); - } - } else { - if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz) - ERROR("rc_twopass_stats_in requires at least two packets."); - - stats = - (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + n_packets - 1; - - if ((int)(stats->count + 0.5) != n_packets - 1) - ERROR("rc_twopass_stats_in missing EOS stats packet"); - } - } -#endif // !CONFIG_REALTIME_ONLY - -#if !CONFIG_VP9_HIGHBITDEPTH - if (cfg->g_profile > (unsigned int)PROFILE_1) { - ERROR("Profile > 1 not supported in this build configuration"); - } -#endif - if (cfg->g_profile <= (unsigned int)PROFILE_1 && - cfg->g_bit_depth > VPX_BITS_8) { - ERROR("Codec high bit-depth not supported in profile < 2"); - } - if (cfg->g_profile <= (unsigned int)PROFILE_1 && cfg->g_input_bit_depth > 8) { - ERROR("Source high bit-depth not supported in profile < 2"); - } - if (cfg->g_profile > (unsigned int)PROFILE_1 && - cfg->g_bit_depth == VPX_BITS_8) { - ERROR("Codec bit-depth 8 not supported in profile > 1"); - } - RANGE_CHECK(extra_cfg, color_space, VPX_CS_UNKNOWN, VPX_CS_SRGB); - RANGE_CHECK(extra_cfg, color_range, VPX_CR_STUDIO_RANGE, VPX_CR_FULL_RANGE); - - // The range below shall be further tuned. - RANGE_CHECK(cfg, use_vizier_rc_params, 0, 1); - RANGE_CHECK(cfg, active_wq_factor.den, 1, 1000); - RANGE_CHECK(cfg, err_per_mb_factor.den, 1, 1000); - RANGE_CHECK(cfg, sr_default_decay_limit.den, 1, 1000); - RANGE_CHECK(cfg, sr_diff_factor.den, 1, 1000); - RANGE_CHECK(cfg, kf_err_per_mb_factor.den, 1, 1000); - RANGE_CHECK(cfg, kf_frame_min_boost_factor.den, 1, 1000); - RANGE_CHECK(cfg, kf_frame_max_boost_subs_factor.den, 1, 1000); - RANGE_CHECK(cfg, kf_max_total_boost_factor.den, 1, 1000); - RANGE_CHECK(cfg, gf_max_total_boost_factor.den, 1, 1000); - RANGE_CHECK(cfg, gf_frame_max_boost_factor.den, 1, 1000); - RANGE_CHECK(cfg, zm_factor.den, 1, 1000); - RANGE_CHECK(cfg, rd_mult_inter_qp_fac.den, 1, 1000); - RANGE_CHECK(cfg, rd_mult_arf_qp_fac.den, 1, 1000); - RANGE_CHECK(cfg, rd_mult_key_qp_fac.den, 1, 1000); - - return VPX_CODEC_OK; -} - -static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx, - const vpx_image_t *img) { - switch (img->fmt) { - case VPX_IMG_FMT_YV12: - case VPX_IMG_FMT_I420: - case VPX_IMG_FMT_I42016: - case VPX_IMG_FMT_NV12: break; - case VPX_IMG_FMT_I422: - case VPX_IMG_FMT_I444: - case VPX_IMG_FMT_I440: - if (ctx->cfg.g_profile != (unsigned int)PROFILE_1) { - ERROR( - "Invalid image format. I422, I444, I440 images are not supported " - "in profile."); - } - break; - case VPX_IMG_FMT_I42216: - case VPX_IMG_FMT_I44416: - case VPX_IMG_FMT_I44016: - if (ctx->cfg.g_profile != (unsigned int)PROFILE_1 && - ctx->cfg.g_profile != (unsigned int)PROFILE_3) { - ERROR( - "Invalid image format. 16-bit I422, I444, I440 images are " - "not supported in profile."); - } - break; - default: - ERROR( - "Invalid image format. Only YV12, I420, I422, I444, I440, NV12 " - "images are supported."); - break; - } - - if (img->d_w != ctx->cfg.g_w || img->d_h != ctx->cfg.g_h) - ERROR("Image size must match encoder init configuration size"); - - return VPX_CODEC_OK; -} - -static int get_image_bps(const vpx_image_t *img) { - switch (img->fmt) { - case VPX_IMG_FMT_YV12: - case VPX_IMG_FMT_NV12: - case VPX_IMG_FMT_I420: return 12; - case VPX_IMG_FMT_I422: return 16; - case VPX_IMG_FMT_I444: return 24; - case VPX_IMG_FMT_I440: return 16; - case VPX_IMG_FMT_I42016: return 24; - case VPX_IMG_FMT_I42216: return 32; - case VPX_IMG_FMT_I44416: return 48; - case VPX_IMG_FMT_I44016: return 32; - default: assert(0 && "Invalid image format"); break; - } - return 0; -} - -// Modify the encoder config for the target level. -static void config_target_level(VP9EncoderConfig *oxcf) { - double max_average_bitrate; // in bits per second - int max_over_shoot_pct; - const int target_level_index = get_level_index(oxcf->target_level); - - vpx_clear_system_state(); - assert(target_level_index >= 0); - assert(target_level_index < VP9_LEVELS); - - // Maximum target bit-rate is level_limit * 80%. - max_average_bitrate = - vp9_level_defs[target_level_index].average_bitrate * 800.0; - if ((double)oxcf->target_bandwidth > max_average_bitrate) - oxcf->target_bandwidth = (int64_t)(max_average_bitrate); - if (oxcf->ss_number_layers == 1 && oxcf->pass != 0) - oxcf->ss_target_bitrate[0] = (int)oxcf->target_bandwidth; - - // Adjust max over-shoot percentage. - max_over_shoot_pct = - (int)((max_average_bitrate * 1.10 - (double)oxcf->target_bandwidth) * - 100 / (double)(oxcf->target_bandwidth)); - if (oxcf->over_shoot_pct > max_over_shoot_pct) - oxcf->over_shoot_pct = max_over_shoot_pct; - - // Adjust worst allowed quantizer. - oxcf->worst_allowed_q = vp9_quantizer_to_qindex(63); - - // Adjust minimum art-ref distance. - // min_gf_interval should be no less than min_altref_distance + 1, - // as the encoder may produce bitstream with alt-ref distance being - // min_gf_interval - 1. - if (oxcf->min_gf_interval <= - (int)vp9_level_defs[target_level_index].min_altref_distance) { - oxcf->min_gf_interval = - (int)vp9_level_defs[target_level_index].min_altref_distance + 1; - // If oxcf->max_gf_interval == 0, it will be assigned with a default value - // in vp9_rc_set_gf_interval_range(). - if (oxcf->max_gf_interval != 0) { - oxcf->max_gf_interval = - VPXMAX(oxcf->max_gf_interval, oxcf->min_gf_interval); - } - } - - // Adjust maximum column tiles. - if (vp9_level_defs[target_level_index].max_col_tiles < - (1 << oxcf->tile_columns)) { - while (oxcf->tile_columns > 0 && - vp9_level_defs[target_level_index].max_col_tiles < - (1 << oxcf->tile_columns)) - --oxcf->tile_columns; - } -} - -static vpx_rational64_t get_g_timebase_in_ts(vpx_rational_t g_timebase) { - vpx_rational64_t g_timebase_in_ts; - g_timebase_in_ts.den = g_timebase.den; - g_timebase_in_ts.num = g_timebase.num; - g_timebase_in_ts.num *= TICKS_PER_SEC; - reduce_ratio(&g_timebase_in_ts); - return g_timebase_in_ts; -} - -static vpx_codec_err_t set_encoder_config( - VP9EncoderConfig *oxcf, vpx_codec_enc_cfg_t *cfg, - const struct vp9_extracfg *extra_cfg) { - const int is_vbr = cfg->rc_end_usage == VPX_VBR; - int sl, tl; - unsigned int raw_target_rate; - oxcf->profile = cfg->g_profile; - oxcf->max_threads = (int)cfg->g_threads; - oxcf->width = cfg->g_w; - oxcf->height = cfg->g_h; - oxcf->bit_depth = cfg->g_bit_depth; - oxcf->input_bit_depth = cfg->g_input_bit_depth; - // TODO(angiebird): Figure out if we can just use g_timebase to indicate the - // inverse of framerate - // guess a frame rate if out of whack, use 30 - oxcf->init_framerate = (double)cfg->g_timebase.den / cfg->g_timebase.num; - if (oxcf->init_framerate > 180) oxcf->init_framerate = 30; - oxcf->g_timebase = cfg->g_timebase; - oxcf->g_timebase_in_ts = get_g_timebase_in_ts(oxcf->g_timebase); - - oxcf->mode = GOOD; - - switch (cfg->g_pass) { - case VPX_RC_ONE_PASS: oxcf->pass = 0; break; - case VPX_RC_FIRST_PASS: oxcf->pass = 1; break; - case VPX_RC_LAST_PASS: oxcf->pass = 2; break; - } - - oxcf->lag_in_frames = - cfg->g_pass == VPX_RC_FIRST_PASS ? 0 : cfg->g_lag_in_frames; - oxcf->rc_mode = cfg->rc_end_usage; - - raw_target_rate = - (unsigned int)((int64_t)oxcf->width * oxcf->height * oxcf->bit_depth * 3 * - oxcf->init_framerate / 1000); - // Cap target bitrate to raw rate or 1000Mbps, whichever is less - cfg->rc_target_bitrate = - VPXMIN(VPXMIN(raw_target_rate, cfg->rc_target_bitrate), 1000000); - - // Convert target bandwidth from Kbit/s to Bit/s - oxcf->target_bandwidth = 1000 * (int64_t)cfg->rc_target_bitrate; - oxcf->rc_max_intra_bitrate_pct = extra_cfg->rc_max_intra_bitrate_pct; - oxcf->rc_max_inter_bitrate_pct = extra_cfg->rc_max_inter_bitrate_pct; - oxcf->gf_cbr_boost_pct = extra_cfg->gf_cbr_boost_pct; - - oxcf->best_allowed_q = - extra_cfg->lossless ? 0 : vp9_quantizer_to_qindex(cfg->rc_min_quantizer); - oxcf->worst_allowed_q = - extra_cfg->lossless ? 0 : vp9_quantizer_to_qindex(cfg->rc_max_quantizer); - oxcf->cq_level = vp9_quantizer_to_qindex(extra_cfg->cq_level); - oxcf->fixed_q = -1; - - oxcf->under_shoot_pct = cfg->rc_undershoot_pct; - oxcf->over_shoot_pct = cfg->rc_overshoot_pct; - - oxcf->scaled_frame_width = cfg->rc_scaled_width; - oxcf->scaled_frame_height = cfg->rc_scaled_height; - if (cfg->rc_resize_allowed == 1) { - oxcf->resize_mode = - (oxcf->scaled_frame_width == 0 || oxcf->scaled_frame_height == 0) - ? RESIZE_DYNAMIC - : RESIZE_FIXED; - } else { - oxcf->resize_mode = RESIZE_NONE; - } - - oxcf->maximum_buffer_size_ms = is_vbr ? 240000 : cfg->rc_buf_sz; - oxcf->starting_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_initial_sz; - oxcf->optimal_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_optimal_sz; - - oxcf->drop_frames_water_mark = cfg->rc_dropframe_thresh; - - oxcf->two_pass_vbrbias = cfg->rc_2pass_vbr_bias_pct; - oxcf->two_pass_vbrmin_section = cfg->rc_2pass_vbr_minsection_pct; - oxcf->two_pass_vbrmax_section = cfg->rc_2pass_vbr_maxsection_pct; - oxcf->vbr_corpus_complexity = cfg->rc_2pass_vbr_corpus_complexity; - - oxcf->auto_key = - cfg->kf_mode == VPX_KF_AUTO && cfg->kf_min_dist != cfg->kf_max_dist; - - oxcf->key_freq = cfg->kf_max_dist; - - oxcf->speed = abs(extra_cfg->cpu_used); - oxcf->encode_breakout = extra_cfg->static_thresh; - oxcf->enable_auto_arf = extra_cfg->enable_auto_alt_ref; - if (oxcf->bit_depth == VPX_BITS_8) { - oxcf->noise_sensitivity = extra_cfg->noise_sensitivity; - } else { - // Disable denoiser for high bitdepth since vp9_denoiser_filter only works - // for 8 bits. - oxcf->noise_sensitivity = 0; - } - oxcf->sharpness = extra_cfg->sharpness; - - vp9_set_first_pass_stats(oxcf, &cfg->rc_twopass_stats_in); - - oxcf->color_space = extra_cfg->color_space; - oxcf->color_range = extra_cfg->color_range; - oxcf->render_width = extra_cfg->render_width; - oxcf->render_height = extra_cfg->render_height; - oxcf->arnr_max_frames = extra_cfg->arnr_max_frames; - oxcf->arnr_strength = extra_cfg->arnr_strength; - oxcf->min_gf_interval = extra_cfg->min_gf_interval; - oxcf->max_gf_interval = extra_cfg->max_gf_interval; - - oxcf->tuning = extra_cfg->tuning; - oxcf->content = extra_cfg->content; - - oxcf->tile_columns = extra_cfg->tile_columns; - - oxcf->enable_tpl_model = extra_cfg->enable_tpl_model; - - oxcf->enable_keyframe_filtering = extra_cfg->enable_keyframe_filtering; - - // TODO(yunqing): The dependencies between row tiles cause error in multi- - // threaded encoding. For now, tile_rows is forced to be 0 in this case. - // The further fix can be done by adding synchronizations after a tile row - // is encoded. But this will hurt multi-threaded encoder performance. So, - // it is recommended to use tile-rows=0 while encoding with threads > 1. - if (oxcf->max_threads > 1 && oxcf->tile_columns > 0) - oxcf->tile_rows = 0; - else - oxcf->tile_rows = extra_cfg->tile_rows; - - oxcf->error_resilient_mode = cfg->g_error_resilient; - oxcf->frame_parallel_decoding_mode = extra_cfg->frame_parallel_decoding_mode; - - oxcf->aq_mode = extra_cfg->aq_mode; - oxcf->alt_ref_aq = extra_cfg->alt_ref_aq; - - oxcf->frame_periodic_boost = extra_cfg->frame_periodic_boost; - - oxcf->ss_number_layers = cfg->ss_number_layers; - oxcf->ts_number_layers = cfg->ts_number_layers; - oxcf->temporal_layering_mode = - (enum vp9e_temporal_layering_mode)cfg->temporal_layering_mode; - - oxcf->target_level = extra_cfg->target_level; - - oxcf->row_mt = extra_cfg->row_mt; - oxcf->motion_vector_unit_test = extra_cfg->motion_vector_unit_test; - - oxcf->delta_q_uv = extra_cfg->delta_q_uv; - - for (sl = 0; sl < oxcf->ss_number_layers; ++sl) { - for (tl = 0; tl < oxcf->ts_number_layers; ++tl) { - const int layer = sl * oxcf->ts_number_layers + tl; - if (cfg->layer_target_bitrate[layer] > INT_MAX / 1000) - oxcf->layer_target_bitrate[layer] = INT_MAX; - else - oxcf->layer_target_bitrate[layer] = - 1000 * cfg->layer_target_bitrate[layer]; - } - } - if (oxcf->ss_number_layers == 1 && oxcf->pass != 0) { - oxcf->ss_target_bitrate[0] = (int)oxcf->target_bandwidth; - } - if (oxcf->ts_number_layers > 1) { - for (tl = 0; tl < VPX_TS_MAX_LAYERS; ++tl) { - oxcf->ts_rate_decimator[tl] = - cfg->ts_rate_decimator[tl] ? cfg->ts_rate_decimator[tl] : 1; - } - } else if (oxcf->ts_number_layers == 1) { - oxcf->ts_rate_decimator[0] = 1; - } - - if (get_level_index(oxcf->target_level) >= 0) config_target_level(oxcf); - oxcf->use_simple_encode_api = 0; - // vp9_dump_encoder_config(oxcf, stderr); - return VPX_CODEC_OK; -} - -static vpx_codec_err_t set_twopass_params_from_config( - const vpx_codec_enc_cfg_t *const cfg, struct VP9_COMP *cpi) { - if (!cfg->use_vizier_rc_params) return VPX_CODEC_OK; - if (cpi == NULL) return VPX_CODEC_ERROR; - - cpi->twopass.use_vizier_rc_params = cfg->use_vizier_rc_params; - - // The values set here are factors that will be applied to default values - // to get the final value used in the two pass code. Hence 1.0 will - // match the default behaviour when not using passed in values. - // We also apply limits here to prevent the user from applying settings - // that make no sense. - cpi->twopass.active_wq_factor = - (double)cfg->active_wq_factor.num / (double)cfg->active_wq_factor.den; - if (cpi->twopass.active_wq_factor < 0.25) - cpi->twopass.active_wq_factor = 0.25; - else if (cpi->twopass.active_wq_factor > 16.0) - cpi->twopass.active_wq_factor = 16.0; - - cpi->twopass.err_per_mb = - (double)cfg->err_per_mb_factor.num / (double)cfg->err_per_mb_factor.den; - if (cpi->twopass.err_per_mb < 0.25) - cpi->twopass.err_per_mb = 0.25; - else if (cpi->twopass.err_per_mb > 4.0) - cpi->twopass.err_per_mb = 4.0; - - cpi->twopass.sr_default_decay_limit = - (double)cfg->sr_default_decay_limit.num / - (double)cfg->sr_default_decay_limit.den; - if (cpi->twopass.sr_default_decay_limit < 0.25) - cpi->twopass.sr_default_decay_limit = 0.25; - // If the default changes this will need to change. - else if (cpi->twopass.sr_default_decay_limit > 1.33) - cpi->twopass.sr_default_decay_limit = 1.33; - - cpi->twopass.sr_diff_factor = - (double)cfg->sr_diff_factor.num / (double)cfg->sr_diff_factor.den; - if (cpi->twopass.sr_diff_factor < 0.25) - cpi->twopass.sr_diff_factor = 0.25; - else if (cpi->twopass.sr_diff_factor > 4.0) - cpi->twopass.sr_diff_factor = 4.0; - - cpi->twopass.kf_err_per_mb = (double)cfg->kf_err_per_mb_factor.num / - (double)cfg->kf_err_per_mb_factor.den; - if (cpi->twopass.kf_err_per_mb < 0.25) - cpi->twopass.kf_err_per_mb = 0.25; - else if (cpi->twopass.kf_err_per_mb > 4.0) - cpi->twopass.kf_err_per_mb = 4.0; - - cpi->twopass.kf_frame_min_boost = (double)cfg->kf_frame_min_boost_factor.num / - (double)cfg->kf_frame_min_boost_factor.den; - if (cpi->twopass.kf_frame_min_boost < 0.25) - cpi->twopass.kf_frame_min_boost = 0.25; - else if (cpi->twopass.kf_frame_min_boost > 4.0) - cpi->twopass.kf_frame_min_boost = 4.0; - - cpi->twopass.kf_frame_max_boost_first = - (double)cfg->kf_frame_max_boost_first_factor.num / - (double)cfg->kf_frame_max_boost_first_factor.den; - if (cpi->twopass.kf_frame_max_boost_first < 0.25) - cpi->twopass.kf_frame_max_boost_first = 0.25; - else if (cpi->twopass.kf_frame_max_boost_first > 4.0) - cpi->twopass.kf_frame_max_boost_first = 4.0; - - cpi->twopass.kf_frame_max_boost_subs = - (double)cfg->kf_frame_max_boost_subs_factor.num / - (double)cfg->kf_frame_max_boost_subs_factor.den; - if (cpi->twopass.kf_frame_max_boost_subs < 0.25) - cpi->twopass.kf_frame_max_boost_subs = 0.25; - else if (cpi->twopass.kf_frame_max_boost_subs > 4.0) - cpi->twopass.kf_frame_max_boost_subs = 4.0; - - cpi->twopass.kf_max_total_boost = (double)cfg->kf_max_total_boost_factor.num / - (double)cfg->kf_max_total_boost_factor.den; - if (cpi->twopass.kf_max_total_boost < 0.25) - cpi->twopass.kf_max_total_boost = 0.25; - else if (cpi->twopass.kf_max_total_boost > 4.0) - cpi->twopass.kf_max_total_boost = 4.0; - - cpi->twopass.gf_max_total_boost = (double)cfg->gf_max_total_boost_factor.num / - (double)cfg->gf_max_total_boost_factor.den; - if (cpi->twopass.gf_max_total_boost < 0.25) - cpi->twopass.gf_max_total_boost = 0.25; - else if (cpi->twopass.gf_max_total_boost > 4.0) - cpi->twopass.gf_max_total_boost = 4.0; - - cpi->twopass.gf_frame_max_boost = (double)cfg->gf_frame_max_boost_factor.num / - (double)cfg->gf_frame_max_boost_factor.den; - if (cpi->twopass.gf_frame_max_boost < 0.25) - cpi->twopass.gf_frame_max_boost = 0.25; - else if (cpi->twopass.gf_frame_max_boost > 4.0) - cpi->twopass.gf_frame_max_boost = 4.0; - - cpi->twopass.zm_factor = - (double)cfg->zm_factor.num / (double)cfg->zm_factor.den; - if (cpi->twopass.zm_factor < 0.25) - cpi->twopass.zm_factor = 0.25; - else if (cpi->twopass.zm_factor > 2.0) - cpi->twopass.zm_factor = 2.0; - - cpi->rd_ctrl.rd_mult_inter_qp_fac = (double)cfg->rd_mult_inter_qp_fac.num / - (double)cfg->rd_mult_inter_qp_fac.den; - if (cpi->rd_ctrl.rd_mult_inter_qp_fac < 0.25) - cpi->rd_ctrl.rd_mult_inter_qp_fac = 0.25; - else if (cpi->rd_ctrl.rd_mult_inter_qp_fac > 4.0) - cpi->rd_ctrl.rd_mult_inter_qp_fac = 4.0; - - cpi->rd_ctrl.rd_mult_arf_qp_fac = - (double)cfg->rd_mult_arf_qp_fac.num / (double)cfg->rd_mult_arf_qp_fac.den; - if (cpi->rd_ctrl.rd_mult_arf_qp_fac < 0.25) - cpi->rd_ctrl.rd_mult_arf_qp_fac = 0.25; - else if (cpi->rd_ctrl.rd_mult_arf_qp_fac > 4.0) - cpi->rd_ctrl.rd_mult_arf_qp_fac = 4.0; - - cpi->rd_ctrl.rd_mult_key_qp_fac = - (double)cfg->rd_mult_key_qp_fac.num / (double)cfg->rd_mult_key_qp_fac.den; - if (cpi->rd_ctrl.rd_mult_key_qp_fac < 0.25) - cpi->rd_ctrl.rd_mult_key_qp_fac = 0.25; - else if (cpi->rd_ctrl.rd_mult_key_qp_fac > 4.0) - cpi->rd_ctrl.rd_mult_key_qp_fac = 4.0; - - return VPX_CODEC_OK; -} - -static vpx_codec_err_t encoder_set_config(vpx_codec_alg_priv_t *ctx, - const vpx_codec_enc_cfg_t *cfg) { - vpx_codec_err_t res; - volatile int force_key = 0; - - if (cfg->g_w != ctx->cfg.g_w || cfg->g_h != ctx->cfg.g_h) { - if (cfg->g_lag_in_frames > 1 || cfg->g_pass != VPX_RC_ONE_PASS) - ERROR("Cannot change width or height after initialization"); - // Note: function encoder_set_config() is allowed to be called multiple - // times. However, when the original frame width or height is less than two - // times of the new frame width or height, a forced key frame should be - // used. To make sure the correct detection of a forced key frame, we need - // to update the frame width and height only when the actual encoding is - // performed. cpi->last_coded_width and cpi->last_coded_height are used to - // track the actual coded frame size. - if ((ctx->cpi->last_coded_width && ctx->cpi->last_coded_height && - !valid_ref_frame_size(ctx->cpi->last_coded_width, - ctx->cpi->last_coded_height, cfg->g_w, - cfg->g_h)) || - (ctx->cpi->initial_width && (int)cfg->g_w > ctx->cpi->initial_width) || - (ctx->cpi->initial_height && - (int)cfg->g_h > ctx->cpi->initial_height)) { - force_key = 1; - } - } - - // Prevent increasing lag_in_frames. This check is stricter than it needs - // to be -- the limit is not increasing past the first lag_in_frames - // value, but we don't track the initial config, only the last successful - // config. - if (cfg->g_lag_in_frames > ctx->cfg.g_lag_in_frames) - ERROR("Cannot increase lag_in_frames"); - - res = validate_config(ctx, cfg, &ctx->extra_cfg); - if (res != VPX_CODEC_OK) return res; - - if (setjmp(ctx->cpi->common.error.jmp)) { - const vpx_codec_err_t codec_err = - update_error_state(ctx, &ctx->cpi->common.error); - ctx->cpi->common.error.setjmp = 0; - vpx_clear_system_state(); - assert(codec_err != VPX_CODEC_OK); - return codec_err; - } - ctx->cpi->common.error.setjmp = 1; - - ctx->cfg = *cfg; - set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg); - set_twopass_params_from_config(&ctx->cfg, ctx->cpi); - // On profile change, request a key frame - force_key |= ctx->cpi->common.profile != ctx->oxcf.profile; - vp9_change_config(ctx->cpi, &ctx->oxcf); - - if (force_key) ctx->next_frame_flags |= VPX_EFLAG_FORCE_KF; - - ctx->cpi->common.error.setjmp = 0; - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_get_quantizer(vpx_codec_alg_priv_t *ctx, - va_list args) { - int *const arg = va_arg(args, int *); - if (arg == NULL) return VPX_CODEC_INVALID_PARAM; - *arg = vp9_get_quantizer(ctx->cpi); - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_get_quantizer64(vpx_codec_alg_priv_t *ctx, - va_list args) { - int *const arg = va_arg(args, int *); - if (arg == NULL) return VPX_CODEC_INVALID_PARAM; - *arg = vp9_qindex_to_quantizer(vp9_get_quantizer(ctx->cpi)); - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_get_quantizer_svc_layers(vpx_codec_alg_priv_t *ctx, - va_list args) { - int *const arg = va_arg(args, int *); - int i; - if (arg == NULL) return VPX_CODEC_INVALID_PARAM; - for (i = 0; i < VPX_SS_MAX_LAYERS; i++) { - arg[i] = ctx->cpi->svc.base_qindex[i]; - } - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_get_loopfilter_level(vpx_codec_alg_priv_t *ctx, - va_list args) { - int *const arg = va_arg(args, int *); - if (arg == NULL) return VPX_CODEC_INVALID_PARAM; - *arg = ctx->cpi->common.lf.filter_level; - return VPX_CODEC_OK; -} - -static vpx_codec_err_t update_extra_cfg(vpx_codec_alg_priv_t *ctx, - const struct vp9_extracfg *extra_cfg) { - const vpx_codec_err_t res = validate_config(ctx, &ctx->cfg, extra_cfg); - if (res == VPX_CODEC_OK) { - ctx->extra_cfg = *extra_cfg; - set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg); - set_twopass_params_from_config(&ctx->cfg, ctx->cpi); - vp9_change_config(ctx->cpi, &ctx->oxcf); - } - return res; -} - -static vpx_codec_err_t ctrl_set_cpuused(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - // Use fastest speed setting (speed 9 or -9) if it's set beyond the range. - extra_cfg.cpu_used = CAST(VP8E_SET_CPUUSED, args); - extra_cfg.cpu_used = VPXMIN(9, extra_cfg.cpu_used); - extra_cfg.cpu_used = VPXMAX(-9, extra_cfg.cpu_used); -#if CONFIG_REALTIME_ONLY - if (extra_cfg.cpu_used > -5 && extra_cfg.cpu_used < 5) - extra_cfg.cpu_used = (extra_cfg.cpu_used > 0) ? 5 : -5; -#endif - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_enable_auto_alt_ref(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.enable_auto_alt_ref = CAST(VP8E_SET_ENABLEAUTOALTREF, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_noise_sensitivity(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.noise_sensitivity = CAST(VP9E_SET_NOISE_SENSITIVITY, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_sharpness(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.sharpness = CAST(VP8E_SET_SHARPNESS, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_static_thresh(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.static_thresh = CAST(VP8E_SET_STATIC_THRESHOLD, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_tile_columns(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.tile_columns = CAST(VP9E_SET_TILE_COLUMNS, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_tile_rows(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.tile_rows = CAST(VP9E_SET_TILE_ROWS, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_tpl_model(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.enable_tpl_model = CAST(VP9E_SET_TPL, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_keyframe_filtering(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.enable_keyframe_filtering = - CAST(VP9E_SET_KEY_FRAME_FILTERING, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_arnr_max_frames(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.arnr_max_frames = CAST(VP8E_SET_ARNR_MAXFRAMES, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_arnr_strength(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.arnr_strength = CAST(VP8E_SET_ARNR_STRENGTH, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_arnr_type(vpx_codec_alg_priv_t *ctx, - va_list args) { - (void)ctx; - (void)args; - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_tuning(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.tuning = CAST(VP8E_SET_TUNING, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_cq_level(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.cq_level = CAST(VP8E_SET_CQ_LEVEL, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_rc_max_intra_bitrate_pct( - vpx_codec_alg_priv_t *ctx, va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.rc_max_intra_bitrate_pct = - CAST(VP8E_SET_MAX_INTRA_BITRATE_PCT, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_rc_max_inter_bitrate_pct( - vpx_codec_alg_priv_t *ctx, va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.rc_max_inter_bitrate_pct = - CAST(VP9E_SET_MAX_INTER_BITRATE_PCT, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_rc_gf_cbr_boost_pct(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.gf_cbr_boost_pct = CAST(VP9E_SET_GF_CBR_BOOST_PCT, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_lossless(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.lossless = CAST(VP9E_SET_LOSSLESS, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_frame_parallel_decoding_mode( - vpx_codec_alg_priv_t *ctx, va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.frame_parallel_decoding_mode = - CAST(VP9E_SET_FRAME_PARALLEL_DECODING, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_aq_mode(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.aq_mode = CAST(VP9E_SET_AQ_MODE, args); - if (ctx->cpi->fixed_qp_onepass) extra_cfg.aq_mode = 0; - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_alt_ref_aq(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.alt_ref_aq = CAST(VP9E_SET_ALT_REF_AQ, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_min_gf_interval(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.min_gf_interval = CAST(VP9E_SET_MIN_GF_INTERVAL, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_max_gf_interval(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.max_gf_interval = CAST(VP9E_SET_MAX_GF_INTERVAL, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_frame_periodic_boost(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.frame_periodic_boost = CAST(VP9E_SET_FRAME_PERIODIC_BOOST, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_target_level(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.target_level = CAST(VP9E_SET_TARGET_LEVEL, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_row_mt(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.row_mt = CAST(VP9E_SET_ROW_MT, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_rtc_external_ratectrl(vpx_codec_alg_priv_t *ctx, - va_list args) { - VP9_COMP *const cpi = ctx->cpi; - const unsigned int data = va_arg(args, unsigned int); - if (data) { - cpi->compute_frame_low_motion_onepass = 0; - cpi->rc.constrain_gf_key_freq_onepass_vbr = 0; - cpi->cyclic_refresh->content_mode = 0; - cpi->disable_scene_detection_rtc_ratectrl = 1; - } - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_enable_motion_vector_unit_test( - vpx_codec_alg_priv_t *ctx, va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.motion_vector_unit_test = - CAST(VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_get_level(vpx_codec_alg_priv_t *ctx, va_list args) { - int *const arg = va_arg(args, int *); - if (arg == NULL) return VPX_CODEC_INVALID_PARAM; - *arg = (int)vp9_get_level(&ctx->cpi->level_info.level_spec); - return VPX_CODEC_OK; -} - -static vpx_codec_err_t encoder_init(vpx_codec_ctx_t *ctx, - vpx_codec_priv_enc_mr_cfg_t *data) { - vpx_codec_err_t res = VPX_CODEC_OK; - (void)data; - - if (ctx->priv == NULL) { - vpx_codec_alg_priv_t *const priv = vpx_calloc(1, sizeof(*priv)); - if (priv == NULL) return VPX_CODEC_MEM_ERROR; - - ctx->priv = (vpx_codec_priv_t *)priv; - ctx->priv->init_flags = ctx->init_flags; - ctx->priv->enc.total_encoders = 1; - priv->buffer_pool = (BufferPool *)vpx_calloc(1, sizeof(BufferPool)); - if (priv->buffer_pool == NULL) return VPX_CODEC_MEM_ERROR; - - if (ctx->config.enc) { - // Update the reference to the config structure to an internal copy. - priv->cfg = *ctx->config.enc; - ctx->config.enc = &priv->cfg; - } - - priv->extra_cfg = default_extra_cfg; - vp9_initialize_enc(); - - res = validate_config(priv, &priv->cfg, &priv->extra_cfg); - - if (res == VPX_CODEC_OK) { - priv->pts_offset_initialized = 0; - priv->global_header_subsampling = -1; - set_encoder_config(&priv->oxcf, &priv->cfg, &priv->extra_cfg); -#if CONFIG_VP9_HIGHBITDEPTH - priv->oxcf.use_highbitdepth = - (ctx->init_flags & VPX_CODEC_USE_HIGHBITDEPTH) ? 1 : 0; -#endif - priv->cpi = vp9_create_compressor(&priv->oxcf, priv->buffer_pool); - if (priv->cpi == NULL) res = VPX_CODEC_MEM_ERROR; - set_twopass_params_from_config(&priv->cfg, priv->cpi); - } - } - - return res; -} - -static vpx_codec_err_t encoder_destroy(vpx_codec_alg_priv_t *ctx) { - free(ctx->cx_data); - free(ctx->global_headers.buf); - vp9_remove_compressor(ctx->cpi); - vpx_free(ctx->buffer_pool); - vpx_free(ctx); - return VPX_CODEC_OK; -} - -static vpx_codec_err_t pick_quickcompress_mode(vpx_codec_alg_priv_t *ctx, - unsigned long duration, - vpx_enc_deadline_t deadline) { - MODE new_mode = BEST; - -#if CONFIG_REALTIME_ONLY - (void)duration; - deadline = VPX_DL_REALTIME; -#else - switch (ctx->cfg.g_pass) { - case VPX_RC_ONE_PASS: - if (deadline > 0) { - // Convert duration parameter from stream timebase to microseconds. - VPX_STATIC_ASSERT(TICKS_PER_SEC > 1000000 && - (TICKS_PER_SEC % 1000000) == 0); - - if (duration > UINT64_MAX / (uint64_t)ctx->oxcf.g_timebase_in_ts.num) { - ERROR("duration is too big"); - } - uint64_t duration_us = duration * - (uint64_t)ctx->oxcf.g_timebase_in_ts.num / - ((uint64_t)ctx->oxcf.g_timebase_in_ts.den * - (TICKS_PER_SEC / 1000000)); - - // If the deadline is more that the duration this frame is to be shown, - // use good quality mode. Otherwise use realtime mode. - new_mode = (deadline > duration_us) ? GOOD : REALTIME; - } else { - new_mode = BEST; - } - break; - case VPX_RC_FIRST_PASS: break; - case VPX_RC_LAST_PASS: new_mode = deadline > 0 ? GOOD : BEST; break; - } -#endif // CONFIG_REALTIME_ONLY - - if (deadline == VPX_DL_REALTIME) { - ctx->oxcf.pass = 0; - new_mode = REALTIME; - } - - if (ctx->oxcf.mode != new_mode) { - ctx->oxcf.mode = new_mode; - vp9_change_config(ctx->cpi, &ctx->oxcf); - } - return VPX_CODEC_OK; -} - -// Turn on to test if supplemental superframe data breaks decoding -// #define TEST_SUPPLEMENTAL_SUPERFRAME_DATA -static int write_superframe_index(vpx_codec_alg_priv_t *ctx) { - uint8_t marker = 0xc0; - unsigned int mask; - int mag, index_sz; - - assert(ctx->pending_frame_count); - assert(ctx->pending_frame_count <= 8); - - // Add the number of frames to the marker byte - marker |= ctx->pending_frame_count - 1; - - // Choose the magnitude - for (mag = 0, mask = 0xff; mag < 4; mag++) { - if (ctx->pending_frame_magnitude < mask) break; - mask <<= 8; - mask |= 0xff; - } - marker |= mag << 3; - - // Write the index - index_sz = 2 + (mag + 1) * ctx->pending_frame_count; - if (ctx->pending_cx_data_sz + index_sz < ctx->cx_data_sz) { - uint8_t *x = ctx->pending_cx_data + ctx->pending_cx_data_sz; - int i, j; -#ifdef TEST_SUPPLEMENTAL_SUPERFRAME_DATA - uint8_t marker_test = 0xc0; - int mag_test = 2; // 1 - 4 - int frames_test = 4; // 1 - 8 - int index_sz_test = 2 + mag_test * frames_test; - marker_test |= frames_test - 1; - marker_test |= (mag_test - 1) << 3; - *x++ = marker_test; - for (i = 0; i < mag_test * frames_test; ++i) - *x++ = 0; // fill up with arbitrary data - *x++ = marker_test; - ctx->pending_cx_data_sz += index_sz_test; - printf("Added supplemental superframe data\n"); -#endif - - *x++ = marker; - for (i = 0; i < ctx->pending_frame_count; i++) { - unsigned int this_sz = (unsigned int)ctx->pending_frame_sizes[i]; - - for (j = 0; j <= mag; j++) { - *x++ = this_sz & 0xff; - this_sz >>= 8; - } - } - *x++ = marker; - ctx->pending_cx_data_sz += index_sz; -#ifdef TEST_SUPPLEMENTAL_SUPERFRAME_DATA - index_sz += index_sz_test; -#endif - } - return index_sz; -} - -static vpx_codec_frame_flags_t get_frame_pkt_flags(const VP9_COMP *cpi, - unsigned int lib_flags) { - vpx_codec_frame_flags_t flags = lib_flags << 16; - - if (lib_flags & FRAMEFLAGS_KEY || - (cpi->use_svc && cpi->svc - .layer_context[cpi->svc.spatial_layer_id * - cpi->svc.number_temporal_layers + - cpi->svc.temporal_layer_id] - .is_key_frame)) - flags |= VPX_FRAME_IS_KEY; - - if (!cpi->common.show_frame) { - flags |= VPX_FRAME_IS_INVISIBLE; - } - - if (cpi->droppable) flags |= VPX_FRAME_IS_DROPPABLE; - - return flags; -} - -static INLINE vpx_codec_cx_pkt_t get_psnr_pkt(const PSNR_STATS *psnr) { - vpx_codec_cx_pkt_t pkt; - pkt.kind = VPX_CODEC_PSNR_PKT; - pkt.data.psnr = *psnr; - return pkt; -} - -#if !CONFIG_REALTIME_ONLY -static INLINE vpx_codec_cx_pkt_t -get_first_pass_stats_pkt(FIRSTPASS_STATS *stats) { - // WARNNING: This function assumes that stats will - // exist and not be changed until the packet is processed - // TODO(angiebird): Refactor the code to avoid using the assumption. - vpx_codec_cx_pkt_t pkt; - pkt.kind = VPX_CODEC_STATS_PKT; - pkt.data.twopass_stats.buf = stats; - pkt.data.twopass_stats.sz = sizeof(*stats); - return pkt; -} -#endif - -const size_t kMinCompressedSize = 8192; -static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, - const vpx_image_t *img, - vpx_codec_pts_t pts_val, - unsigned long duration, - vpx_enc_frame_flags_t enc_flags, - vpx_enc_deadline_t deadline) { - volatile vpx_codec_err_t res = VPX_CODEC_OK; - volatile vpx_enc_frame_flags_t flags = enc_flags; - volatile vpx_codec_pts_t pts = pts_val; - VP9_COMP *const cpi = ctx->cpi; - const vpx_rational64_t *const timebase_in_ts = &ctx->oxcf.g_timebase_in_ts; - size_t data_sz; - vpx_codec_cx_pkt_t pkt; - memset(&pkt, 0, sizeof(pkt)); - - if (cpi == NULL) return VPX_CODEC_INVALID_PARAM; - - cpi->last_coded_width = ctx->oxcf.width; - cpi->last_coded_height = ctx->oxcf.height; - - if (img != NULL) { - res = validate_img(ctx, img); - if (res == VPX_CODEC_OK) { - // There's no codec control for multiple alt-refs so check the encoder - // instance for its status to determine the compressed data size. - data_sz = ctx->cfg.g_w * ctx->cfg.g_h * get_image_bps(img) / 8 * - (cpi->multi_layer_arf ? 8 : 2); - if (data_sz < kMinCompressedSize) data_sz = kMinCompressedSize; - if (ctx->cx_data == NULL || ctx->cx_data_sz < data_sz) { - ctx->cx_data_sz = data_sz; - free(ctx->cx_data); - ctx->cx_data = (unsigned char *)malloc(ctx->cx_data_sz); - if (ctx->cx_data == NULL) { - return VPX_CODEC_MEM_ERROR; - } - } - - int chroma_subsampling = -1; - if ((img->fmt & VPX_IMG_FMT_I420) == VPX_IMG_FMT_I420 || - (img->fmt & VPX_IMG_FMT_NV12) == VPX_IMG_FMT_NV12 || - (img->fmt & VPX_IMG_FMT_YV12) == VPX_IMG_FMT_YV12) { - chroma_subsampling = 1; // matches default for Codec Parameter String - } else if ((img->fmt & VPX_IMG_FMT_I422) == VPX_IMG_FMT_I422) { - chroma_subsampling = 2; - } else if ((img->fmt & VPX_IMG_FMT_I444) == VPX_IMG_FMT_I444) { - chroma_subsampling = 3; - } - if (chroma_subsampling > ctx->global_header_subsampling) { - ctx->global_header_subsampling = chroma_subsampling; - } - } - } - - res = pick_quickcompress_mode(ctx, duration, deadline); - if (res != VPX_CODEC_OK) { - return res; - } - vpx_codec_pkt_list_init(&ctx->pkt_list); - - // Handle Flags - if (((flags & VP8_EFLAG_NO_UPD_GF) && (flags & VP8_EFLAG_FORCE_GF)) || - ((flags & VP8_EFLAG_NO_UPD_ARF) && (flags & VP8_EFLAG_FORCE_ARF))) { - ctx->base.err_detail = "Conflicting flags."; - return VPX_CODEC_INVALID_PARAM; - } - - if (setjmp(cpi->common.error.jmp)) { - cpi->common.error.setjmp = 0; - res = update_error_state(ctx, &cpi->common.error); - vpx_clear_system_state(); - return res; - } - cpi->common.error.setjmp = 1; - - if (res == VPX_CODEC_OK) vp9_apply_encoding_flags(cpi, flags); - - // Handle fixed keyframe intervals - if (ctx->cfg.kf_mode == VPX_KF_AUTO && - ctx->cfg.kf_min_dist == ctx->cfg.kf_max_dist) { - if (++ctx->fixed_kf_cntr > ctx->cfg.kf_min_dist) { - flags |= VPX_EFLAG_FORCE_KF; - ctx->fixed_kf_cntr = 1; - } - } - - if (res == VPX_CODEC_OK) { - unsigned int lib_flags = 0; - size_t size, cx_data_sz; - unsigned char *cx_data; - - // Set up internal flags - if (ctx->base.init_flags & VPX_CODEC_USE_PSNR) cpi->b_calculate_psnr = 1; - - if (img != NULL) { - YV12_BUFFER_CONFIG sd; - - if (!ctx->pts_offset_initialized) { - ctx->pts_offset = pts; - ctx->pts_offset_initialized = 1; - } - if (pts < ctx->pts_offset) { - vpx_internal_error(&cpi->common.error, VPX_CODEC_INVALID_PARAM, - "pts is smaller than initial pts"); - } - pts -= ctx->pts_offset; - if (pts > INT64_MAX / timebase_in_ts->num) { - vpx_internal_error( - &cpi->common.error, VPX_CODEC_INVALID_PARAM, - "conversion of relative pts to ticks would overflow"); - } - const int64_t dst_time_stamp = - timebase_units_to_ticks(timebase_in_ts, pts); - - cpi->svc.timebase_fac = timebase_units_to_ticks(timebase_in_ts, 1); - cpi->svc.time_stamp_superframe = dst_time_stamp; - -#if ULONG_MAX > INT64_MAX - if (duration > INT64_MAX) { - vpx_internal_error(&cpi->common.error, VPX_CODEC_INVALID_PARAM, - "duration is too big"); - } -#endif - if (pts > INT64_MAX - (int64_t)duration) { - vpx_internal_error(&cpi->common.error, VPX_CODEC_INVALID_PARAM, - "relative pts + duration is too big"); - } - vpx_codec_pts_t pts_end = pts + (int64_t)duration; - if (pts_end > INT64_MAX / timebase_in_ts->num) { - vpx_internal_error( - &cpi->common.error, VPX_CODEC_INVALID_PARAM, - "conversion of relative pts + duration to ticks would overflow"); - } - const int64_t dst_end_time_stamp = - timebase_units_to_ticks(timebase_in_ts, pts_end); - res = image2yuvconfig(img, &sd); - - // Store the original flags in to the frame buffer. Will extract the - // key frame flag when we actually encode this frame. - if (vp9_receive_raw_frame(cpi, flags | ctx->next_frame_flags, &sd, - dst_time_stamp, dst_end_time_stamp)) { - res = update_error_state(ctx, &cpi->common.error); - } - ctx->next_frame_flags = 0; - } - - cx_data = ctx->cx_data; - cx_data_sz = ctx->cx_data_sz; - - /* Any pending invisible frames? */ - if (ctx->pending_cx_data) { - assert(cx_data_sz >= ctx->pending_cx_data_sz); - memmove(cx_data, ctx->pending_cx_data, ctx->pending_cx_data_sz); - ctx->pending_cx_data = cx_data; - cx_data += ctx->pending_cx_data_sz; - cx_data_sz -= ctx->pending_cx_data_sz; - - /* TODO(webm:1844): this is a minimal check, the underlying codec doesn't - * respect the buffer size anyway. - */ - if (cx_data_sz < ctx->cx_data_sz / 2) { - vpx_internal_error(&cpi->common.error, VPX_CODEC_ERROR, - "Compressed data buffer too small"); - } - } - - if (cpi->oxcf.pass == 1 && !cpi->use_svc) { -#if !CONFIG_REALTIME_ONLY - // compute first pass stats - if (img) { - int ret; - int64_t dst_time_stamp; - int64_t dst_end_time_stamp; - vpx_codec_cx_pkt_t fps_pkt; - ENCODE_FRAME_RESULT encode_frame_result; - vp9_init_encode_frame_result(&encode_frame_result); - // TODO(angiebird): Call vp9_first_pass directly - ret = vp9_get_compressed_data( - cpi, &lib_flags, &size, cx_data, cx_data_sz, &dst_time_stamp, - &dst_end_time_stamp, !img, &encode_frame_result); - assert(size == 0); // There is no compressed data in the first pass - (void)ret; - assert(ret == 0); - fps_pkt = get_first_pass_stats_pkt(&cpi->twopass.this_frame_stats); - vpx_codec_pkt_list_add(&ctx->pkt_list.head, &fps_pkt); - } else { - if (!cpi->twopass.first_pass_done) { - vpx_codec_cx_pkt_t fps_pkt; - vp9_end_first_pass(cpi); - fps_pkt = get_first_pass_stats_pkt(&cpi->twopass.total_stats); - vpx_codec_pkt_list_add(&ctx->pkt_list.head, &fps_pkt); - } - } -#else // !CONFIG_REALTIME_ONLY - assert(0); -#endif // !CONFIG_REALTIME_ONLY - } else { - ENCODE_FRAME_RESULT encode_frame_result; - int64_t dst_time_stamp; - int64_t dst_end_time_stamp; - vp9_init_encode_frame_result(&encode_frame_result); - while (cx_data_sz >= ctx->cx_data_sz / 2 && - -1 != vp9_get_compressed_data(cpi, &lib_flags, &size, cx_data, - cx_data_sz, &dst_time_stamp, - &dst_end_time_stamp, !img, - &encode_frame_result)) { - // Pack psnr pkt - if (size > 0 && !cpi->use_svc) { - // TODO(angiebird): Figure out while we don't need psnr pkt when - // use_svc is on - PSNR_STATS psnr; - if (vp9_get_psnr(cpi, &psnr)) { - vpx_codec_cx_pkt_t psnr_pkt = get_psnr_pkt(&psnr); - vpx_codec_pkt_list_add(&ctx->pkt_list.head, &psnr_pkt); - } - } - - if (size || (cpi->use_svc && cpi->svc.skip_enhancement_layer)) { - // Pack invisible frames with the next visible frame - if (!cpi->common.show_frame || - (cpi->use_svc && cpi->svc.spatial_layer_id < - cpi->svc.number_spatial_layers - 1)) { - if (ctx->pending_cx_data == NULL) ctx->pending_cx_data = cx_data; - ctx->pending_cx_data_sz += size; - if (size) - ctx->pending_frame_sizes[ctx->pending_frame_count++] = size; - ctx->pending_frame_magnitude |= size; - cx_data += size; - cx_data_sz -= size; - pkt.data.frame.width[cpi->svc.spatial_layer_id] = cpi->common.width; - pkt.data.frame.height[cpi->svc.spatial_layer_id] = - cpi->common.height; - pkt.data.frame.spatial_layer_encoded[cpi->svc.spatial_layer_id] = - 1 - cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id]; - - if (ctx->output_cx_pkt_cb.output_cx_pkt) { - pkt.kind = VPX_CODEC_CX_FRAME_PKT; - pkt.data.frame.pts = - ticks_to_timebase_units(timebase_in_ts, dst_time_stamp) + - ctx->pts_offset; - pkt.data.frame.duration = (unsigned long)ticks_to_timebase_units( - timebase_in_ts, dst_end_time_stamp - dst_time_stamp); - pkt.data.frame.flags = get_frame_pkt_flags(cpi, lib_flags); - pkt.data.frame.buf = ctx->pending_cx_data; - pkt.data.frame.sz = size; - ctx->pending_cx_data = NULL; - ctx->pending_cx_data_sz = 0; - ctx->pending_frame_count = 0; - ctx->pending_frame_magnitude = 0; - ctx->output_cx_pkt_cb.output_cx_pkt( - &pkt, ctx->output_cx_pkt_cb.user_priv); - } - continue; - } - - // Add the frame packet to the list of returned packets. - pkt.kind = VPX_CODEC_CX_FRAME_PKT; - pkt.data.frame.pts = - ticks_to_timebase_units(timebase_in_ts, dst_time_stamp) + - ctx->pts_offset; - pkt.data.frame.duration = (unsigned long)ticks_to_timebase_units( - timebase_in_ts, dst_end_time_stamp - dst_time_stamp); - pkt.data.frame.flags = get_frame_pkt_flags(cpi, lib_flags); - pkt.data.frame.width[cpi->svc.spatial_layer_id] = cpi->common.width; - pkt.data.frame.height[cpi->svc.spatial_layer_id] = cpi->common.height; - pkt.data.frame.spatial_layer_encoded[cpi->svc.spatial_layer_id] = - 1 - cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id]; - - if (ctx->pending_cx_data) { - if (size) - ctx->pending_frame_sizes[ctx->pending_frame_count++] = size; - ctx->pending_frame_magnitude |= size; - ctx->pending_cx_data_sz += size; - // write the superframe only for the case when - if (!ctx->output_cx_pkt_cb.output_cx_pkt) - size += write_superframe_index(ctx); - pkt.data.frame.buf = ctx->pending_cx_data; - pkt.data.frame.sz = ctx->pending_cx_data_sz; - ctx->pending_cx_data = NULL; - ctx->pending_cx_data_sz = 0; - ctx->pending_frame_count = 0; - ctx->pending_frame_magnitude = 0; - } else { - pkt.data.frame.buf = cx_data; - pkt.data.frame.sz = size; - } - pkt.data.frame.partition_id = -1; - - if (ctx->output_cx_pkt_cb.output_cx_pkt) - ctx->output_cx_pkt_cb.output_cx_pkt( - &pkt, ctx->output_cx_pkt_cb.user_priv); - else - vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt); - - cx_data += size; - cx_data_sz -= size; - if (is_one_pass_svc(cpi) && (cpi->svc.spatial_layer_id == - cpi->svc.number_spatial_layers - 1)) { - // Encoded all spatial layers; exit loop. - break; - } - } - } - } - } - - cpi->common.error.setjmp = 0; - return res; -} - -static const vpx_codec_cx_pkt_t *encoder_get_cxdata(vpx_codec_alg_priv_t *ctx, - vpx_codec_iter_t *iter) { - return vpx_codec_pkt_list_get(&ctx->pkt_list.head, iter); -} - -static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_ref_frame_t *const frame = va_arg(args, vpx_ref_frame_t *); - - if (frame != NULL) { - YV12_BUFFER_CONFIG sd; - - image2yuvconfig(&frame->img, &sd); - vp9_set_reference_enc(ctx->cpi, ref_frame_to_vp9_reframe(frame->frame_type), - &sd); - return VPX_CODEC_OK; - } - return VPX_CODEC_INVALID_PARAM; -} - -static vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_ref_frame_t *const frame = va_arg(args, vpx_ref_frame_t *); - - if (frame != NULL) { - YV12_BUFFER_CONFIG sd; - - image2yuvconfig(&frame->img, &sd); - vp9_copy_reference_enc(ctx->cpi, - ref_frame_to_vp9_reframe(frame->frame_type), &sd); - return VPX_CODEC_OK; - } - return VPX_CODEC_INVALID_PARAM; -} - -static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx, - va_list args) { - vp9_ref_frame_t *const frame = va_arg(args, vp9_ref_frame_t *); - - if (frame != NULL) { - const int fb_idx = ctx->cpi->common.cur_show_frame_fb_idx; - YV12_BUFFER_CONFIG *fb = get_buf_frame(&ctx->cpi->common, fb_idx); - if (fb == NULL) return VPX_CODEC_ERROR; - yuvconfig2image(&frame->img, fb, NULL); - return VPX_CODEC_OK; - } - return VPX_CODEC_INVALID_PARAM; -} - -static vpx_codec_err_t ctrl_set_previewpp(vpx_codec_alg_priv_t *ctx, - va_list args) { -#if CONFIG_VP9_POSTPROC - vp8_postproc_cfg_t *config = va_arg(args, vp8_postproc_cfg_t *); - if (config != NULL) { - ctx->preview_ppcfg = *config; - return VPX_CODEC_OK; - } - return VPX_CODEC_INVALID_PARAM; -#else - (void)ctx; - (void)args; - return VPX_CODEC_INCAPABLE; -#endif -} - -// Returns the contents of CodecPrivate described in: -// https://www.webmproject.org/docs/container/#vp9-codec-feature-metadata-codecprivate -// This includes Profile, Level, Bit depth and Chroma subsampling. Each entry -// is 3 bytes. 1 byte ID, 1 byte length (= 1) and 1 byte value. -static vpx_fixed_buf_t *encoder_get_global_headers(vpx_codec_alg_priv_t *ctx) { - if (!ctx->cpi) return NULL; - - const unsigned int profile = ctx->cfg.g_profile; - const VP9_LEVEL level = vp9_get_level(&ctx->cpi->level_info.level_spec); - const vpx_bit_depth_t bit_depth = ctx->cfg.g_bit_depth; - const int subsampling = ctx->global_header_subsampling; - const uint8_t buf[12] = { - 1, 1, (uint8_t)profile, 2, 1, (uint8_t)level, - 3, 1, (uint8_t)bit_depth, 4, 1, (uint8_t)subsampling - }; - - if (ctx->global_headers.buf) free(ctx->global_headers.buf); - ctx->global_headers.buf = malloc(sizeof(buf)); - if (!ctx->global_headers.buf) return NULL; - - ctx->global_headers.sz = sizeof(buf); - // No data or I440, which isn't mapped. - if (ctx->global_header_subsampling == -1) ctx->global_headers.sz -= 3; - memcpy(ctx->global_headers.buf, buf, ctx->global_headers.sz); - - return &ctx->global_headers; -} - -static vpx_image_t *encoder_get_preview(vpx_codec_alg_priv_t *ctx) { - YV12_BUFFER_CONFIG sd; - vp9_ppflags_t flags; - vp9_zero(flags); - - if (ctx->preview_ppcfg.post_proc_flag) { - flags.post_proc_flag = ctx->preview_ppcfg.post_proc_flag; - flags.deblocking_level = ctx->preview_ppcfg.deblocking_level; - flags.noise_level = ctx->preview_ppcfg.noise_level; - } - - if (vp9_get_preview_raw_frame(ctx->cpi, &sd, &flags) == 0) { - yuvconfig2image(&ctx->preview_img, &sd, NULL); - return &ctx->preview_img; - } - return NULL; -} - -static vpx_codec_err_t ctrl_set_roi_map(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_roi_map_t *data = va_arg(args, vpx_roi_map_t *); - - if (data) { - vpx_roi_map_t *roi = (vpx_roi_map_t *)data; - return vp9_set_roi_map(ctx->cpi, roi->roi_map, roi->rows, roi->cols, - roi->delta_q, roi->delta_lf, roi->skip, - roi->ref_frame); - } - return VPX_CODEC_INVALID_PARAM; -} - -static vpx_codec_err_t ctrl_set_active_map(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_active_map_t *const map = va_arg(args, vpx_active_map_t *); - - if (map) { - if (!vp9_set_active_map(ctx->cpi, map->active_map, (int)map->rows, - (int)map->cols)) - return VPX_CODEC_OK; - - return VPX_CODEC_INVALID_PARAM; - } - return VPX_CODEC_INVALID_PARAM; -} - -static vpx_codec_err_t ctrl_get_active_map(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_active_map_t *const map = va_arg(args, vpx_active_map_t *); - - if (map) { - if (!vp9_get_active_map(ctx->cpi, map->active_map, (int)map->rows, - (int)map->cols)) - return VPX_CODEC_OK; - - return VPX_CODEC_INVALID_PARAM; - } - return VPX_CODEC_INVALID_PARAM; -} - -static vpx_codec_err_t ctrl_set_scale_mode(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_scaling_mode_t *const mode = va_arg(args, vpx_scaling_mode_t *); - - if (mode) { - const int res = vp9_set_internal_size(ctx->cpi, mode->h_scaling_mode, - mode->v_scaling_mode); - return (res == 0) ? VPX_CODEC_OK : VPX_CODEC_INVALID_PARAM; - } - return VPX_CODEC_INVALID_PARAM; -} - -static vpx_codec_err_t ctrl_set_svc(vpx_codec_alg_priv_t *ctx, va_list args) { - int data = va_arg(args, int); - const vpx_codec_enc_cfg_t *cfg = &ctx->cfg; - // Both one-pass and two-pass RC are supported now. - // User setting this has to make sure of the following. - // In two-pass setting: either (but not both) - // cfg->ss_number_layers > 1, or cfg->ts_number_layers > 1 - // In one-pass setting: - // either or both cfg->ss_number_layers > 1, or cfg->ts_number_layers > 1 - - vp9_set_svc(ctx->cpi, data); - - if (data == 1 && - (cfg->g_pass == VPX_RC_FIRST_PASS || cfg->g_pass == VPX_RC_LAST_PASS) && - cfg->ss_number_layers > 1 && cfg->ts_number_layers > 1) { - return VPX_CODEC_INVALID_PARAM; - } - - vp9_set_row_mt(ctx->cpi); - - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_svc_layer_id(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_svc_layer_id_t *const data = va_arg(args, vpx_svc_layer_id_t *); - VP9_COMP *const cpi = (VP9_COMP *)ctx->cpi; - SVC *const svc = &cpi->svc; - int sl; - - svc->spatial_layer_to_encode = data->spatial_layer_id; - svc->first_spatial_layer_to_encode = data->spatial_layer_id; - // TODO(jianj): Deprecated to be removed. - svc->temporal_layer_id = data->temporal_layer_id; - // Allow for setting temporal layer per spatial layer for superframe. - for (sl = 0; sl < cpi->svc.number_spatial_layers; ++sl) { - svc->temporal_layer_id_per_spatial[sl] = - data->temporal_layer_id_per_spatial[sl]; - } - // Checks on valid layer_id input. - if (svc->temporal_layer_id < 0 || - svc->temporal_layer_id >= (int)ctx->cfg.ts_number_layers) { - return VPX_CODEC_INVALID_PARAM; - } - - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_get_svc_layer_id(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_svc_layer_id_t *data = va_arg(args, vpx_svc_layer_id_t *); - VP9_COMP *const cpi = (VP9_COMP *)ctx->cpi; - SVC *const svc = &cpi->svc; - - data->spatial_layer_id = svc->spatial_layer_id; - data->temporal_layer_id = svc->temporal_layer_id; - - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_svc_parameters(vpx_codec_alg_priv_t *ctx, - va_list args) { - VP9_COMP *const cpi = ctx->cpi; - vpx_svc_extra_cfg_t *const params = va_arg(args, vpx_svc_extra_cfg_t *); - int sl, tl; - - // Number of temporal layers and number of spatial layers have to be set - // properly before calling this control function. - for (sl = 0; sl < cpi->svc.number_spatial_layers; ++sl) { - for (tl = 0; tl < cpi->svc.number_temporal_layers; ++tl) { - const int layer = - LAYER_IDS_TO_IDX(sl, tl, cpi->svc.number_temporal_layers); - LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer]; - lc->max_q = params->max_quantizers[layer]; - lc->min_q = params->min_quantizers[layer]; - lc->scaling_factor_num = params->scaling_factor_num[sl]; - lc->scaling_factor_den = params->scaling_factor_den[sl]; - lc->speed = params->speed_per_layer[sl]; - lc->loopfilter_ctrl = params->loopfilter_ctrl[sl]; - } - } - - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_get_svc_ref_frame_config(vpx_codec_alg_priv_t *ctx, - va_list args) { - VP9_COMP *const cpi = ctx->cpi; - vpx_svc_ref_frame_config_t *data = va_arg(args, vpx_svc_ref_frame_config_t *); - int sl; - for (sl = 0; sl <= cpi->svc.spatial_layer_id; sl++) { - data->update_buffer_slot[sl] = cpi->svc.update_buffer_slot[sl]; - data->reference_last[sl] = cpi->svc.reference_last[sl]; - data->reference_golden[sl] = cpi->svc.reference_golden[sl]; - data->reference_alt_ref[sl] = cpi->svc.reference_altref[sl]; - data->lst_fb_idx[sl] = cpi->svc.lst_fb_idx[sl]; - data->gld_fb_idx[sl] = cpi->svc.gld_fb_idx[sl]; - data->alt_fb_idx[sl] = cpi->svc.alt_fb_idx[sl]; - // TODO(jianj): Remove these 3, deprecated. - data->update_last[sl] = cpi->svc.update_last[sl]; - data->update_golden[sl] = cpi->svc.update_golden[sl]; - data->update_alt_ref[sl] = cpi->svc.update_altref[sl]; - } - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_svc_ref_frame_config(vpx_codec_alg_priv_t *ctx, - va_list args) { - VP9_COMP *const cpi = ctx->cpi; - vpx_svc_ref_frame_config_t *data = va_arg(args, vpx_svc_ref_frame_config_t *); - int sl; - cpi->svc.use_set_ref_frame_config = 1; - for (sl = 0; sl < cpi->svc.number_spatial_layers; ++sl) { - cpi->svc.update_buffer_slot[sl] = data->update_buffer_slot[sl]; - cpi->svc.reference_last[sl] = data->reference_last[sl]; - cpi->svc.reference_golden[sl] = data->reference_golden[sl]; - cpi->svc.reference_altref[sl] = data->reference_alt_ref[sl]; - cpi->svc.lst_fb_idx[sl] = data->lst_fb_idx[sl]; - cpi->svc.gld_fb_idx[sl] = data->gld_fb_idx[sl]; - cpi->svc.alt_fb_idx[sl] = data->alt_fb_idx[sl]; - cpi->svc.duration[sl] = data->duration[sl]; - } - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_svc_inter_layer_pred(vpx_codec_alg_priv_t *ctx, - va_list args) { - const int data = va_arg(args, int); - VP9_COMP *const cpi = ctx->cpi; - cpi->svc.disable_inter_layer_pred = data; - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_svc_frame_drop_layer(vpx_codec_alg_priv_t *ctx, - va_list args) { - VP9_COMP *const cpi = ctx->cpi; - vpx_svc_frame_drop_t *data = va_arg(args, vpx_svc_frame_drop_t *); - int sl; - cpi->svc.framedrop_mode = data->framedrop_mode; - for (sl = 0; sl < cpi->svc.number_spatial_layers; ++sl) - cpi->svc.framedrop_thresh[sl] = data->framedrop_thresh[sl]; - // Don't allow max_consec_drop values below 1. - cpi->svc.max_consec_drop = VPXMAX(1, data->max_consec_drop); - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_svc_gf_temporal_ref(vpx_codec_alg_priv_t *ctx, - va_list args) { - VP9_COMP *const cpi = ctx->cpi; - const unsigned int data = va_arg(args, unsigned int); - cpi->svc.use_gf_temporal_ref = data; - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_svc_spatial_layer_sync( - vpx_codec_alg_priv_t *ctx, va_list args) { - VP9_COMP *const cpi = ctx->cpi; - vpx_svc_spatial_layer_sync_t *data = - va_arg(args, vpx_svc_spatial_layer_sync_t *); - int sl; - for (sl = 0; sl < cpi->svc.number_spatial_layers; ++sl) - cpi->svc.spatial_layer_sync[sl] = data->spatial_layer_sync[sl]; - cpi->svc.set_intra_only_frame = data->base_layer_intra_only; - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_delta_q_uv(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - int data = va_arg(args, int); - data = VPXMIN(VPXMAX(data, -15), 15); - extra_cfg.delta_q_uv = data; - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_register_cx_callback(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_codec_priv_output_cx_pkt_cb_pair_t *cbp = - (vpx_codec_priv_output_cx_pkt_cb_pair_t *)va_arg(args, void *); - ctx->output_cx_pkt_cb.output_cx_pkt = cbp->output_cx_pkt; - ctx->output_cx_pkt_cb.user_priv = cbp->user_priv; - - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_tune_content(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.content = CAST(VP9E_SET_TUNE_CONTENT, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_color_space(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.color_space = CAST(VP9E_SET_COLOR_SPACE, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_color_range(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - extra_cfg.color_range = CAST(VP9E_SET_COLOR_RANGE, args); - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_render_size(vpx_codec_alg_priv_t *ctx, - va_list args) { - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - int *const render_size = va_arg(args, int *); - extra_cfg.render_width = render_size[0]; - extra_cfg.render_height = render_size[1]; - return update_extra_cfg(ctx, &extra_cfg); -} - -static vpx_codec_err_t ctrl_set_postencode_drop(vpx_codec_alg_priv_t *ctx, - va_list args) { - VP9_COMP *const cpi = ctx->cpi; - const unsigned int data = va_arg(args, unsigned int); - cpi->rc.ext_use_post_encode_drop = data; - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_disable_overshoot_maxq_cbr( - vpx_codec_alg_priv_t *ctx, va_list args) { - VP9_COMP *const cpi = ctx->cpi; - const unsigned int data = va_arg(args, unsigned int); - cpi->rc.disable_overshoot_maxq_cbr = data; - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_disable_loopfilter(vpx_codec_alg_priv_t *ctx, - va_list args) { - VP9_COMP *const cpi = ctx->cpi; - const unsigned int data = va_arg(args, unsigned int); - cpi->loopfilter_ctrl = data; - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_external_rate_control(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_rc_funcs_t funcs = *CAST(VP9E_SET_EXTERNAL_RATE_CONTROL, args); - VP9_COMP *cpi = ctx->cpi; - EXT_RATECTRL *ext_ratectrl = &cpi->ext_ratectrl; - const VP9EncoderConfig *oxcf = &cpi->oxcf; - if (oxcf->pass == 2) { - const FRAME_INFO *frame_info = &cpi->frame_info; - vpx_rc_config_t ratectrl_config; - vpx_codec_err_t codec_status; - memset(&ratectrl_config, 0, sizeof(ratectrl_config)); - - ratectrl_config.frame_width = frame_info->frame_width; - ratectrl_config.frame_height = frame_info->frame_height; - ratectrl_config.show_frame_count = cpi->twopass.first_pass_info.num_frames; - ratectrl_config.max_gf_interval = oxcf->max_gf_interval; - ratectrl_config.min_gf_interval = oxcf->min_gf_interval; - // TODO(angiebird): Double check whether this is the proper way to set up - // target_bitrate and frame_rate. - ratectrl_config.target_bitrate_kbps = (int)(oxcf->target_bandwidth / 1000); - ratectrl_config.frame_rate_num = oxcf->g_timebase.den; - ratectrl_config.frame_rate_den = oxcf->g_timebase.num; - ratectrl_config.overshoot_percent = oxcf->over_shoot_pct; - ratectrl_config.undershoot_percent = oxcf->under_shoot_pct; - ratectrl_config.min_base_q_index = oxcf->best_allowed_q; - ratectrl_config.max_base_q_index = oxcf->worst_allowed_q; - ratectrl_config.base_qp = oxcf->cq_level; - - if (oxcf->rc_mode == VPX_VBR) { - ratectrl_config.rc_mode = VPX_RC_VBR; - } else if (oxcf->rc_mode == VPX_Q) { - ratectrl_config.rc_mode = VPX_RC_QMODE; - } else if (oxcf->rc_mode == VPX_CQ) { - ratectrl_config.rc_mode = VPX_RC_CQ; - } - - codec_status = vp9_extrc_create(funcs, ratectrl_config, ext_ratectrl); - if (codec_status != VPX_CODEC_OK) { - return codec_status; - } - } - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_quantizer_one_pass(vpx_codec_alg_priv_t *ctx, - va_list args) { - VP9_COMP *const cpi = ctx->cpi; - const int qp = va_arg(args, int); - vpx_codec_enc_cfg_t *cfg = &ctx->cfg; - struct vp9_extracfg extra_cfg = ctx->extra_cfg; - vpx_codec_err_t res; - - if (qp < 0 || qp > 63) return VPX_CODEC_INVALID_PARAM; - - cfg->rc_min_quantizer = cfg->rc_max_quantizer = qp; - extra_cfg.aq_mode = 0; - cpi->fixed_qp_onepass = 1; - - res = update_extra_cfg(ctx, &extra_cfg); - return res; -} - -static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = { - { VP8_COPY_REFERENCE, ctrl_copy_reference }, - - // Setters - { VP8_SET_REFERENCE, ctrl_set_reference }, - { VP8_SET_POSTPROC, ctrl_set_previewpp }, - { VP9E_SET_ROI_MAP, ctrl_set_roi_map }, - { VP8E_SET_ACTIVEMAP, ctrl_set_active_map }, - { VP8E_SET_SCALEMODE, ctrl_set_scale_mode }, - { VP8E_SET_CPUUSED, ctrl_set_cpuused }, - { VP8E_SET_ENABLEAUTOALTREF, ctrl_set_enable_auto_alt_ref }, - { VP8E_SET_SHARPNESS, ctrl_set_sharpness }, - { VP8E_SET_STATIC_THRESHOLD, ctrl_set_static_thresh }, - { VP9E_SET_TILE_COLUMNS, ctrl_set_tile_columns }, - { VP9E_SET_TILE_ROWS, ctrl_set_tile_rows }, - { VP9E_SET_TPL, ctrl_set_tpl_model }, - { VP9E_SET_KEY_FRAME_FILTERING, ctrl_set_keyframe_filtering }, - { VP8E_SET_ARNR_MAXFRAMES, ctrl_set_arnr_max_frames }, - { VP8E_SET_ARNR_STRENGTH, ctrl_set_arnr_strength }, - { VP8E_SET_ARNR_TYPE, ctrl_set_arnr_type }, - { VP8E_SET_TUNING, ctrl_set_tuning }, - { VP8E_SET_CQ_LEVEL, ctrl_set_cq_level }, - { VP8E_SET_MAX_INTRA_BITRATE_PCT, ctrl_set_rc_max_intra_bitrate_pct }, - { VP9E_SET_MAX_INTER_BITRATE_PCT, ctrl_set_rc_max_inter_bitrate_pct }, - { VP9E_SET_GF_CBR_BOOST_PCT, ctrl_set_rc_gf_cbr_boost_pct }, - { VP9E_SET_LOSSLESS, ctrl_set_lossless }, - { VP9E_SET_FRAME_PARALLEL_DECODING, ctrl_set_frame_parallel_decoding_mode }, - { VP9E_SET_AQ_MODE, ctrl_set_aq_mode }, - { VP9E_SET_ALT_REF_AQ, ctrl_set_alt_ref_aq }, - { VP9E_SET_FRAME_PERIODIC_BOOST, ctrl_set_frame_periodic_boost }, - { VP9E_SET_SVC, ctrl_set_svc }, - { VP9E_SET_SVC_PARAMETERS, ctrl_set_svc_parameters }, - { VP9E_REGISTER_CX_CALLBACK, ctrl_register_cx_callback }, - { VP9E_SET_SVC_LAYER_ID, ctrl_set_svc_layer_id }, - { VP9E_SET_TUNE_CONTENT, ctrl_set_tune_content }, - { VP9E_SET_COLOR_SPACE, ctrl_set_color_space }, - { VP9E_SET_COLOR_RANGE, ctrl_set_color_range }, - { VP9E_SET_NOISE_SENSITIVITY, ctrl_set_noise_sensitivity }, - { VP9E_SET_MIN_GF_INTERVAL, ctrl_set_min_gf_interval }, - { VP9E_SET_MAX_GF_INTERVAL, ctrl_set_max_gf_interval }, - { VP9E_SET_SVC_REF_FRAME_CONFIG, ctrl_set_svc_ref_frame_config }, - { VP9E_SET_RENDER_SIZE, ctrl_set_render_size }, - { VP9E_SET_TARGET_LEVEL, ctrl_set_target_level }, - { VP9E_SET_ROW_MT, ctrl_set_row_mt }, - { VP9E_SET_POSTENCODE_DROP, ctrl_set_postencode_drop }, - { VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, ctrl_set_disable_overshoot_maxq_cbr }, - { VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, ctrl_enable_motion_vector_unit_test }, - { VP9E_SET_SVC_INTER_LAYER_PRED, ctrl_set_svc_inter_layer_pred }, - { VP9E_SET_SVC_FRAME_DROP_LAYER, ctrl_set_svc_frame_drop_layer }, - { VP9E_SET_SVC_GF_TEMPORAL_REF, ctrl_set_svc_gf_temporal_ref }, - { VP9E_SET_SVC_SPATIAL_LAYER_SYNC, ctrl_set_svc_spatial_layer_sync }, - { VP9E_SET_DELTA_Q_UV, ctrl_set_delta_q_uv }, - { VP9E_SET_DISABLE_LOOPFILTER, ctrl_set_disable_loopfilter }, - { VP9E_SET_RTC_EXTERNAL_RATECTRL, ctrl_set_rtc_external_ratectrl }, - { VP9E_SET_EXTERNAL_RATE_CONTROL, ctrl_set_external_rate_control }, - { VP9E_SET_QUANTIZER_ONE_PASS, ctrl_set_quantizer_one_pass }, - - // Getters - { VP8E_GET_LAST_QUANTIZER, ctrl_get_quantizer }, - { VP8E_GET_LAST_QUANTIZER_64, ctrl_get_quantizer64 }, - { VP9E_GET_LAST_QUANTIZER_SVC_LAYERS, ctrl_get_quantizer_svc_layers }, - { VP9E_GET_LOOPFILTER_LEVEL, ctrl_get_loopfilter_level }, - { VP9_GET_REFERENCE, ctrl_get_reference }, - { VP9E_GET_SVC_LAYER_ID, ctrl_get_svc_layer_id }, - { VP9E_GET_ACTIVEMAP, ctrl_get_active_map }, - { VP9E_GET_LEVEL, ctrl_get_level }, - { VP9E_GET_SVC_REF_FRAME_CONFIG, ctrl_get_svc_ref_frame_config }, - - { -1, NULL }, -}; - -static vpx_codec_enc_cfg_map_t encoder_usage_cfg_map[] = { - { 0, - { - // NOLINT - 0, // g_usage (unused) - 8, // g_threads - 0, // g_profile - - 320, // g_width - 240, // g_height - VPX_BITS_8, // g_bit_depth - 8, // g_input_bit_depth - - { 1, 30 }, // g_timebase - - 0, // g_error_resilient - - VPX_RC_ONE_PASS, // g_pass - - 25, // g_lag_in_frames - - 0, // rc_dropframe_thresh - 0, // rc_resize_allowed - 0, // rc_scaled_width - 0, // rc_scaled_height - 60, // rc_resize_down_thresh - 30, // rc_resize_up_thresh - - VPX_VBR, // rc_end_usage - { NULL, 0 }, // rc_twopass_stats_in - { NULL, 0 }, // rc_firstpass_mb_stats_in - 256, // rc_target_bitrate - 0, // rc_min_quantizer - 63, // rc_max_quantizer - 25, // rc_undershoot_pct - 25, // rc_overshoot_pct - - 6000, // rc_max_buffer_size - 4000, // rc_buffer_initial_size - 5000, // rc_buffer_optimal_size - - 50, // rc_two_pass_vbrbias - 0, // rc_two_pass_vbrmin_section - 2000, // rc_two_pass_vbrmax_section - 0, // rc_2pass_vbr_corpus_complexity (non 0 for corpus vbr) - - // keyframing settings (kf) - VPX_KF_AUTO, // g_kfmode - 0, // kf_min_dist - 128, // kf_max_dist - - VPX_SS_DEFAULT_LAYERS, // ss_number_layers - { 0 }, - { 0 }, // ss_target_bitrate - 1, // ts_number_layers - { 0 }, // ts_target_bitrate - { 0 }, // ts_rate_decimator - 0, // ts_periodicity - { 0 }, // ts_layer_id - { 0 }, // layer_target_bitrate - 0, // temporal_layering_mode - 0, // use_vizier_rc_params - { 1, 1 }, // active_wq_factor - { 1, 1 }, // err_per_mb_factor - { 1, 1 }, // sr_default_decay_limit - { 1, 1 }, // sr_diff_factor - { 1, 1 }, // kf_err_per_mb_factor - { 1, 1 }, // kf_frame_min_boost_factor - { 1, 1 }, // kf_frame_max_boost_first_factor - { 1, 1 }, // kf_frame_max_boost_subs_factor - { 1, 1 }, // kf_max_total_boost_factor - { 1, 1 }, // gf_max_total_boost_factor - { 1, 1 }, // gf_frame_max_boost_factor - { 1, 1 }, // zm_factor - { 1, 1 }, // rd_mult_inter_qp_fac - { 1, 1 }, // rd_mult_arf_qp_fac - { 1, 1 }, // rd_mult_key_qp_fac - } }, -}; - -#ifndef VERSION_STRING -#define VERSION_STRING -#endif -CODEC_INTERFACE(vpx_codec_vp9_cx) = { - "WebM Project VP9 Encoder" VERSION_STRING, - VPX_CODEC_INTERNAL_ABI_VERSION, -#if CONFIG_VP9_HIGHBITDEPTH - VPX_CODEC_CAP_HIGHBITDEPTH | -#endif - VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR, // vpx_codec_caps_t - encoder_init, // vpx_codec_init_fn_t - encoder_destroy, // vpx_codec_destroy_fn_t - encoder_ctrl_maps, // vpx_codec_ctrl_fn_map_t - { - // NOLINT - NULL, // vpx_codec_peek_si_fn_t - NULL, // vpx_codec_get_si_fn_t - NULL, // vpx_codec_decode_fn_t - NULL, // vpx_codec_frame_get_fn_t - NULL // vpx_codec_set_fb_fn_t - }, - { - // NOLINT - 1, // 1 cfg map - encoder_usage_cfg_map, // vpx_codec_enc_cfg_map_t - encoder_encode, // vpx_codec_encode_fn_t - encoder_get_cxdata, // vpx_codec_get_cx_data_fn_t - encoder_set_config, // vpx_codec_enc_config_set_fn_t - encoder_get_global_headers, // vpx_codec_get_global_headers_fn_t - encoder_get_preview, // vpx_codec_get_preview_frame_fn_t - NULL // vpx_codec_enc_mr_get_mem_loc_fn_t - } -}; - -static vpx_codec_enc_cfg_t get_enc_cfg(int frame_width, int frame_height, - vpx_rational_t frame_rate, - int target_bitrate, - vpx_enc_pass enc_pass) { - vpx_codec_enc_cfg_t enc_cfg = encoder_usage_cfg_map[0].cfg; - enc_cfg.g_w = frame_width; - enc_cfg.g_h = frame_height; - enc_cfg.rc_target_bitrate = target_bitrate; - enc_cfg.g_pass = enc_pass; - // g_timebase is the inverse of frame_rate - enc_cfg.g_timebase.num = frame_rate.den; - enc_cfg.g_timebase.den = frame_rate.num; - return enc_cfg; -} - -static vp9_extracfg get_extra_cfg(void) { - vp9_extracfg extra_cfg = default_extra_cfg; - return extra_cfg; -} - -VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height, - vpx_rational_t frame_rate, - int target_bitrate, int encode_speed, - int target_level, - vpx_enc_pass enc_pass) { - /* This function will generate the same VP9EncoderConfig used by the - * vpxenc command given below. - * The configs in the vpxenc command corresponds to parameters of - * vp9_get_encoder_config() as follows. - * - * WIDTH: frame_width - * HEIGHT: frame_height - * FPS: frame_rate - * BITRATE: target_bitrate - * CPU_USED:encode_speed - * TARGET_LEVEL: target_level - * - * INPUT, OUTPUT, LIMIT will not affect VP9EncoderConfig - * - * vpxenc command: - * INPUT=bus_cif.y4m - * OUTPUT=output.webm - * WIDTH=352 - * HEIGHT=288 - * BITRATE=600 - * FPS=30/1 - * LIMIT=150 - * CPU_USED=0 - * TARGET_LEVEL=0 - * ./vpxenc --limit=$LIMIT --width=$WIDTH --height=$HEIGHT --fps=$FPS - * --lag-in-frames=25 \ - * --codec=vp9 --good --cpu-used=CPU_USED --threads=0 --profile=0 \ - * --min-q=0 --max-q=63 --auto-alt-ref=1 --passes=2 --kf-max-dist=150 \ - * --kf-min-dist=0 --drop-frame=0 --static-thresh=0 --bias-pct=50 \ - * --minsection-pct=0 --maxsection-pct=150 --arnr-maxframes=7 --psnr \ - * --arnr-strength=5 --sharpness=0 --undershoot-pct=100 --overshoot-pct=100 \ - * --frame-parallel=0 --tile-columns=0 --cpu-used=0 --end-usage=vbr \ - * --target-bitrate=$BITRATE --target-level=0 -o $OUTPUT $INPUT - */ - - VP9EncoderConfig oxcf; - vp9_extracfg extra_cfg = get_extra_cfg(); - vpx_codec_enc_cfg_t enc_cfg = get_enc_cfg( - frame_width, frame_height, frame_rate, target_bitrate, enc_pass); - set_encoder_config(&oxcf, &enc_cfg, &extra_cfg); - - // These settings are made to match the settings of the vpxenc command. - oxcf.key_freq = 150; - oxcf.under_shoot_pct = 100; - oxcf.over_shoot_pct = 100; - oxcf.max_threads = 0; - oxcf.tile_columns = 0; - oxcf.frame_parallel_decoding_mode = 0; - oxcf.two_pass_vbrmax_section = 150; - oxcf.speed = abs(encode_speed); - oxcf.target_level = target_level; - return oxcf; -} - -#define DUMP_STRUCT_VALUE(fp, structure, value) \ - fprintf(fp, #value " %" PRId64 "\n", (int64_t)(structure)->value) - -void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf, FILE *fp) { - DUMP_STRUCT_VALUE(fp, oxcf, profile); - DUMP_STRUCT_VALUE(fp, oxcf, bit_depth); - DUMP_STRUCT_VALUE(fp, oxcf, width); - DUMP_STRUCT_VALUE(fp, oxcf, height); - DUMP_STRUCT_VALUE(fp, oxcf, input_bit_depth); - DUMP_STRUCT_VALUE(fp, oxcf, init_framerate); - // TODO(angiebird): dump g_timebase - // TODO(angiebird): dump g_timebase_in_ts - - DUMP_STRUCT_VALUE(fp, oxcf, target_bandwidth); - - DUMP_STRUCT_VALUE(fp, oxcf, noise_sensitivity); - DUMP_STRUCT_VALUE(fp, oxcf, sharpness); - DUMP_STRUCT_VALUE(fp, oxcf, speed); - DUMP_STRUCT_VALUE(fp, oxcf, rc_max_intra_bitrate_pct); - DUMP_STRUCT_VALUE(fp, oxcf, rc_max_inter_bitrate_pct); - DUMP_STRUCT_VALUE(fp, oxcf, gf_cbr_boost_pct); - - DUMP_STRUCT_VALUE(fp, oxcf, mode); - DUMP_STRUCT_VALUE(fp, oxcf, pass); - - // Key Framing Operations - DUMP_STRUCT_VALUE(fp, oxcf, auto_key); - DUMP_STRUCT_VALUE(fp, oxcf, key_freq); - - DUMP_STRUCT_VALUE(fp, oxcf, lag_in_frames); - - // ---------------------------------------------------------------- - // DATARATE CONTROL OPTIONS - - // vbr, cbr, constrained quality or constant quality - DUMP_STRUCT_VALUE(fp, oxcf, rc_mode); - - // buffer targeting aggressiveness - DUMP_STRUCT_VALUE(fp, oxcf, under_shoot_pct); - DUMP_STRUCT_VALUE(fp, oxcf, over_shoot_pct); - - // buffering parameters - // TODO(angiebird): dump tarting_buffer_level_ms - // TODO(angiebird): dump ptimal_buffer_level_ms - // TODO(angiebird): dump maximum_buffer_size_ms - - // Frame drop threshold. - DUMP_STRUCT_VALUE(fp, oxcf, drop_frames_water_mark); - - // controlling quality - DUMP_STRUCT_VALUE(fp, oxcf, fixed_q); - DUMP_STRUCT_VALUE(fp, oxcf, worst_allowed_q); - DUMP_STRUCT_VALUE(fp, oxcf, best_allowed_q); - DUMP_STRUCT_VALUE(fp, oxcf, cq_level); - DUMP_STRUCT_VALUE(fp, oxcf, aq_mode); - - // Special handling of Adaptive Quantization for AltRef frames - DUMP_STRUCT_VALUE(fp, oxcf, alt_ref_aq); - - // Internal frame size scaling. - DUMP_STRUCT_VALUE(fp, oxcf, resize_mode); - DUMP_STRUCT_VALUE(fp, oxcf, scaled_frame_width); - DUMP_STRUCT_VALUE(fp, oxcf, scaled_frame_height); - - // Enable feature to reduce the frame quantization every x frames. - DUMP_STRUCT_VALUE(fp, oxcf, frame_periodic_boost); - - // two pass datarate control - DUMP_STRUCT_VALUE(fp, oxcf, two_pass_vbrbias); - DUMP_STRUCT_VALUE(fp, oxcf, two_pass_vbrmin_section); - DUMP_STRUCT_VALUE(fp, oxcf, two_pass_vbrmax_section); - DUMP_STRUCT_VALUE(fp, oxcf, vbr_corpus_complexity); - // END DATARATE CONTROL OPTIONS - // ---------------------------------------------------------------- - - // Spatial and temporal scalability. - DUMP_STRUCT_VALUE(fp, oxcf, ss_number_layers); - DUMP_STRUCT_VALUE(fp, oxcf, ts_number_layers); - - // Bitrate allocation for spatial layers. - // TODO(angiebird): dump layer_target_bitrate[VPX_MAX_LAYERS] - // TODO(angiebird): dump ss_target_bitrate[VPX_SS_MAX_LAYERS] - // TODO(angiebird): dump ss_enable_auto_arf[VPX_SS_MAX_LAYERS] - // TODO(angiebird): dump ts_rate_decimator[VPX_TS_MAX_LAYERS] - - DUMP_STRUCT_VALUE(fp, oxcf, enable_auto_arf); - DUMP_STRUCT_VALUE(fp, oxcf, encode_breakout); - DUMP_STRUCT_VALUE(fp, oxcf, error_resilient_mode); - DUMP_STRUCT_VALUE(fp, oxcf, frame_parallel_decoding_mode); - - DUMP_STRUCT_VALUE(fp, oxcf, arnr_max_frames); - DUMP_STRUCT_VALUE(fp, oxcf, arnr_strength); - - DUMP_STRUCT_VALUE(fp, oxcf, min_gf_interval); - DUMP_STRUCT_VALUE(fp, oxcf, max_gf_interval); - - DUMP_STRUCT_VALUE(fp, oxcf, tile_columns); - DUMP_STRUCT_VALUE(fp, oxcf, tile_rows); - - DUMP_STRUCT_VALUE(fp, oxcf, enable_tpl_model); - - DUMP_STRUCT_VALUE(fp, oxcf, enable_keyframe_filtering); - - DUMP_STRUCT_VALUE(fp, oxcf, max_threads); - - DUMP_STRUCT_VALUE(fp, oxcf, target_level); - - // TODO(angiebird): dump two_pass_stats_in - DUMP_STRUCT_VALUE(fp, oxcf, tuning); - DUMP_STRUCT_VALUE(fp, oxcf, content); -#if CONFIG_VP9_HIGHBITDEPTH - DUMP_STRUCT_VALUE(fp, oxcf, use_highbitdepth); -#endif - DUMP_STRUCT_VALUE(fp, oxcf, color_space); - DUMP_STRUCT_VALUE(fp, oxcf, color_range); - DUMP_STRUCT_VALUE(fp, oxcf, render_width); - DUMP_STRUCT_VALUE(fp, oxcf, render_height); - DUMP_STRUCT_VALUE(fp, oxcf, temporal_layering_mode); - - DUMP_STRUCT_VALUE(fp, oxcf, row_mt); - DUMP_STRUCT_VALUE(fp, oxcf, motion_vector_unit_test); - DUMP_STRUCT_VALUE(fp, oxcf, delta_q_uv); - DUMP_STRUCT_VALUE(fp, oxcf, use_simple_encode_api); -} - -FRAME_INFO vp9_get_frame_info(const VP9EncoderConfig *oxcf) { - FRAME_INFO frame_info; - int dummy; - frame_info.frame_width = oxcf->width; - frame_info.frame_height = oxcf->height; - frame_info.render_frame_width = oxcf->width; - frame_info.render_frame_height = oxcf->height; - frame_info.bit_depth = oxcf->bit_depth; - vp9_set_mi_size(&frame_info.mi_rows, &frame_info.mi_cols, &dummy, - frame_info.frame_width, frame_info.frame_height); - vp9_set_mb_size(&frame_info.mb_rows, &frame_info.mb_cols, &frame_info.num_mbs, - frame_info.mi_rows, frame_info.mi_cols); - // TODO(angiebird): Figure out how to get subsampling_x/y here - return frame_info; -} - -void vp9_set_first_pass_stats(VP9EncoderConfig *oxcf, - const vpx_fixed_buf_t *stats) { - oxcf->two_pass_stats_in = *stats; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_cx_iface.h b/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_cx_iface.h deleted file mode 100644 index f2de8507..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_cx_iface.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2019 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_VP9_CX_IFACE_H_ -#define VPX_VP9_VP9_CX_IFACE_H_ -#include "vp9/encoder/vp9_encoder.h" -#include "vp9/common/vp9_onyxc_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height, - vpx_rational_t frame_rate, - int target_bitrate, int encode_speed, - int target_level, - vpx_enc_pass enc_pass); - -void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf, FILE *fp); - -FRAME_INFO vp9_get_frame_info(const VP9EncoderConfig *oxcf); - -static INLINE int64_t -timebase_units_to_ticks(const vpx_rational64_t *timestamp_ratio, int64_t n) { - return n * timestamp_ratio->num / timestamp_ratio->den; -} - -static INLINE int64_t -ticks_to_timebase_units(const vpx_rational64_t *timestamp_ratio, int64_t n) { - int64_t round = timestamp_ratio->num / 2; - if (round > 0) --round; - return (n * timestamp_ratio->den + round) / timestamp_ratio->num; -} - -void vp9_set_first_pass_stats(VP9EncoderConfig *oxcf, - const vpx_fixed_buf_t *stats); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_VP9_CX_IFACE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_dx_iface.c b/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_dx_iface.c deleted file mode 100644 index 7567910b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_dx_iface.c +++ /dev/null @@ -1,742 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vpx_version.h" - -#include "vpx/internal/vpx_codec_internal.h" -#include "vpx/vp8dx.h" -#include "vpx/vpx_decoder.h" -#include "vpx_dsp/bitreader_buffer.h" -#include "vpx_dsp/vpx_dsp_common.h" - -#include "vp9/common/vp9_alloccommon.h" -#include "vp9/common/vp9_frame_buffers.h" - -#include "vp9/decoder/vp9_decodeframe.h" - -#include "vp9/vp9_dx_iface.h" -#include "vp9/vp9_iface_common.h" - -#define VP9_CAP_POSTPROC (CONFIG_VP9_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0) - -static vpx_codec_err_t decoder_init(vpx_codec_ctx_t *ctx, - vpx_codec_priv_enc_mr_cfg_t *data) { - // This function only allocates space for the vpx_codec_alg_priv_t - // structure. More memory may be required at the time the stream - // information becomes known. - (void)data; - - if (!ctx->priv) { - vpx_codec_alg_priv_t *const priv = - (vpx_codec_alg_priv_t *)vpx_calloc(1, sizeof(*priv)); - if (priv == NULL) return VPX_CODEC_MEM_ERROR; - - ctx->priv = (vpx_codec_priv_t *)priv; - ctx->priv->init_flags = ctx->init_flags; - priv->si.sz = sizeof(priv->si); - priv->flushed = 0; - if (ctx->config.dec) { - priv->cfg = *ctx->config.dec; - ctx->config.dec = &priv->cfg; - } - } - - return VPX_CODEC_OK; -} - -static vpx_codec_err_t decoder_destroy(vpx_codec_alg_priv_t *ctx) { - if (ctx->pbi != NULL) { - vp9_decoder_remove(ctx->pbi); - } - - if (ctx->buffer_pool) { - vp9_free_ref_frame_buffers(ctx->buffer_pool); - vp9_free_internal_frame_buffers(&ctx->buffer_pool->int_frame_buffers); - } - - vpx_free(ctx->buffer_pool); - vpx_free(ctx); - return VPX_CODEC_OK; -} - -static int parse_bitdepth_colorspace_sampling(BITSTREAM_PROFILE profile, - struct vpx_read_bit_buffer *rb) { - vpx_color_space_t color_space; - if (profile >= PROFILE_2) rb->bit_offset += 1; // Bit-depth 10 or 12. - color_space = (vpx_color_space_t)vpx_rb_read_literal(rb, 3); - if (color_space != VPX_CS_SRGB) { - rb->bit_offset += 1; // [16,235] (including xvycc) vs [0,255] range. - if (profile == PROFILE_1 || profile == PROFILE_3) { - rb->bit_offset += 2; // subsampling x/y. - rb->bit_offset += 1; // unused. - } - } else { - if (profile == PROFILE_1 || profile == PROFILE_3) { - rb->bit_offset += 1; // unused - } else { - // RGB is only available in version 1. - return 0; - } - } - return 1; -} - -static vpx_codec_err_t decoder_peek_si_internal( - const uint8_t *data, unsigned int data_sz, vpx_codec_stream_info_t *si, - int *is_intra_only, vpx_decrypt_cb decrypt_cb, void *decrypt_state) { - int intra_only_flag = 0; - uint8_t clear_buffer[11]; - - if (data + data_sz <= data) return VPX_CODEC_INVALID_PARAM; - - si->is_kf = 0; - si->w = si->h = 0; - - if (decrypt_cb) { - data_sz = VPXMIN(sizeof(clear_buffer), data_sz); - decrypt_cb(decrypt_state, data, clear_buffer, data_sz); - data = clear_buffer; - } - - // A maximum of 6 bits are needed to read the frame marker, profile and - // show_existing_frame. - if (data_sz < 1) return VPX_CODEC_UNSUP_BITSTREAM; - - { - int show_frame; - int error_resilient; - struct vpx_read_bit_buffer rb = { data, data + data_sz, 0, NULL, NULL }; - const int frame_marker = vpx_rb_read_literal(&rb, 2); - const BITSTREAM_PROFILE profile = vp9_read_profile(&rb); - - if (frame_marker != VP9_FRAME_MARKER) return VPX_CODEC_UNSUP_BITSTREAM; - - if (profile >= MAX_PROFILES) return VPX_CODEC_UNSUP_BITSTREAM; - - if (vpx_rb_read_bit(&rb)) { // show an existing frame - // If profile is > 2 and show_existing_frame is true, then at least 1 more - // byte (6+3=9 bits) is needed. - if (profile > 2 && data_sz < 2) return VPX_CODEC_UNSUP_BITSTREAM; - vpx_rb_read_literal(&rb, 3); // Frame buffer to show. - return VPX_CODEC_OK; - } - - // For the rest of the function, a maximum of 9 more bytes are needed - // (computed by taking the maximum possible bits needed in each case). Note - // that this has to be updated if we read any more bits in this function. - if (data_sz < 10) return VPX_CODEC_UNSUP_BITSTREAM; - - si->is_kf = !vpx_rb_read_bit(&rb); - show_frame = vpx_rb_read_bit(&rb); - error_resilient = vpx_rb_read_bit(&rb); - - if (si->is_kf) { - if (!vp9_read_sync_code(&rb)) return VPX_CODEC_UNSUP_BITSTREAM; - - if (!parse_bitdepth_colorspace_sampling(profile, &rb)) - return VPX_CODEC_UNSUP_BITSTREAM; - vp9_read_frame_size(&rb, (int *)&si->w, (int *)&si->h); - } else { - intra_only_flag = show_frame ? 0 : vpx_rb_read_bit(&rb); - - rb.bit_offset += error_resilient ? 0 : 2; // reset_frame_context - - if (intra_only_flag) { - if (!vp9_read_sync_code(&rb)) return VPX_CODEC_UNSUP_BITSTREAM; - if (profile > PROFILE_0) { - if (!parse_bitdepth_colorspace_sampling(profile, &rb)) - return VPX_CODEC_UNSUP_BITSTREAM; - // The colorspace info may cause vp9_read_frame_size() to need 11 - // bytes. - if (data_sz < 11) return VPX_CODEC_UNSUP_BITSTREAM; - } - rb.bit_offset += REF_FRAMES; // refresh_frame_flags - vp9_read_frame_size(&rb, (int *)&si->w, (int *)&si->h); - } - } - } - if (is_intra_only != NULL) *is_intra_only = intra_only_flag; - return VPX_CODEC_OK; -} - -static vpx_codec_err_t decoder_peek_si(const uint8_t *data, - unsigned int data_sz, - vpx_codec_stream_info_t *si) { - return decoder_peek_si_internal(data, data_sz, si, NULL, NULL, NULL); -} - -static vpx_codec_err_t decoder_get_si(vpx_codec_alg_priv_t *ctx, - vpx_codec_stream_info_t *si) { - const size_t sz = (si->sz >= sizeof(vp9_stream_info_t)) - ? sizeof(vp9_stream_info_t) - : sizeof(vpx_codec_stream_info_t); - memcpy(si, &ctx->si, sz); - si->sz = (unsigned int)sz; - - return VPX_CODEC_OK; -} - -static void set_error_detail(vpx_codec_alg_priv_t *ctx, - const char *const error) { - ctx->base.err_detail = error; -} - -static vpx_codec_err_t update_error_state( - vpx_codec_alg_priv_t *ctx, const struct vpx_internal_error_info *error) { - if (error->error_code) - set_error_detail(ctx, error->has_detail ? error->detail : NULL); - - return error->error_code; -} - -static vpx_codec_err_t init_buffer_callbacks(vpx_codec_alg_priv_t *ctx) { - VP9_COMMON *const cm = &ctx->pbi->common; - BufferPool *const pool = cm->buffer_pool; - - cm->new_fb_idx = INVALID_IDX; - cm->byte_alignment = ctx->byte_alignment; - cm->skip_loop_filter = ctx->skip_loop_filter; - - if (ctx->get_ext_fb_cb != NULL && ctx->release_ext_fb_cb != NULL) { - pool->get_fb_cb = ctx->get_ext_fb_cb; - pool->release_fb_cb = ctx->release_ext_fb_cb; - pool->cb_priv = ctx->ext_priv; - } else { - pool->get_fb_cb = vp9_get_frame_buffer; - pool->release_fb_cb = vp9_release_frame_buffer; - - if (vp9_alloc_internal_frame_buffers(&pool->int_frame_buffers)) { - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to initialize internal frame buffers"); - return VPX_CODEC_MEM_ERROR; - } - - pool->cb_priv = &pool->int_frame_buffers; - } - - return VPX_CODEC_OK; -} - -static void set_default_ppflags(vp8_postproc_cfg_t *cfg) { - cfg->post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK; - cfg->deblocking_level = 4; - cfg->noise_level = 0; -} - -static void set_ppflags(const vpx_codec_alg_priv_t *ctx, vp9_ppflags_t *flags) { - flags->post_proc_flag = ctx->postproc_cfg.post_proc_flag; - - flags->deblocking_level = ctx->postproc_cfg.deblocking_level; - flags->noise_level = ctx->postproc_cfg.noise_level; -} - -#undef ERROR -#define ERROR(str) \ - do { \ - ctx->base.err_detail = str; \ - return VPX_CODEC_INVALID_PARAM; \ - } while (0) - -#define RANGE_CHECK(p, memb, lo, hi) \ - do { \ - if (!(((p)->memb == (lo) || (p)->memb > (lo)) && (p)->memb <= (hi))) \ - ERROR(#memb " out of range [" #lo ".." #hi "]"); \ - } while (0) - -static vpx_codec_err_t init_decoder(vpx_codec_alg_priv_t *ctx) { - vpx_codec_err_t res; - ctx->last_show_frame = -1; - ctx->need_resync = 1; - ctx->flushed = 0; - - ctx->buffer_pool = (BufferPool *)vpx_calloc(1, sizeof(BufferPool)); - if (ctx->buffer_pool == NULL) return VPX_CODEC_MEM_ERROR; - - ctx->pbi = vp9_decoder_create(ctx->buffer_pool); - if (ctx->pbi == NULL) { - vpx_free(ctx->buffer_pool); - ctx->buffer_pool = NULL; - set_error_detail(ctx, "Failed to allocate decoder"); - return VPX_CODEC_MEM_ERROR; - } - ctx->pbi->max_threads = ctx->cfg.threads; - ctx->pbi->inv_tile_order = ctx->invert_tile_order; - - RANGE_CHECK(ctx, row_mt, 0, 1); - ctx->pbi->row_mt = ctx->row_mt; - - RANGE_CHECK(ctx, lpf_opt, 0, 1); - ctx->pbi->lpf_mt_opt = ctx->lpf_opt; - - // If postprocessing was enabled by the application and a - // configuration has not been provided, default it. - if (!ctx->postproc_cfg_set && (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) - set_default_ppflags(&ctx->postproc_cfg); - - res = init_buffer_callbacks(ctx); - if (res != VPX_CODEC_OK) { - vpx_free(ctx->buffer_pool); - ctx->buffer_pool = NULL; - vp9_decoder_remove(ctx->pbi); - ctx->pbi = NULL; - } - return res; -} - -static INLINE void check_resync(vpx_codec_alg_priv_t *const ctx, - const VP9Decoder *const pbi) { - // Clear resync flag if the decoder got a key frame or intra only frame. - if (ctx->need_resync == 1 && pbi->need_resync == 0 && - (pbi->common.intra_only || pbi->common.frame_type == KEY_FRAME)) - ctx->need_resync = 0; -} - -static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx, - const uint8_t **data, unsigned int data_sz, - void *user_priv) { - // Determine the stream parameters. Note that we rely on peek_si to - // validate that we have a buffer that does not wrap around the top - // of the heap. - if (!ctx->si.h) { - int is_intra_only = 0; - const vpx_codec_err_t res = - decoder_peek_si_internal(*data, data_sz, &ctx->si, &is_intra_only, - ctx->decrypt_cb, ctx->decrypt_state); - if (res != VPX_CODEC_OK) return res; - - if (!ctx->si.is_kf && !is_intra_only) return VPX_CODEC_ERROR; - } - - ctx->user_priv = user_priv; - - // Set these even if already initialized. The caller may have changed the - // decrypt config between frames. - ctx->pbi->decrypt_cb = ctx->decrypt_cb; - ctx->pbi->decrypt_state = ctx->decrypt_state; - - if (vp9_receive_compressed_data(ctx->pbi, data_sz, data)) { - ctx->pbi->cur_buf->buf.corrupted = 1; - ctx->pbi->need_resync = 1; - ctx->need_resync = 1; - return update_error_state(ctx, &ctx->pbi->common.error); - } - - check_resync(ctx, ctx->pbi); - - return VPX_CODEC_OK; -} - -static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx, - const uint8_t *data, unsigned int data_sz, - void *user_priv) { - const uint8_t *data_start = data; - vpx_codec_err_t res; - uint32_t frame_sizes[8]; - int frame_count; - - if (data == NULL && data_sz == 0) { - ctx->flushed = 1; - return VPX_CODEC_OK; - } - - // Reset flushed when receiving a valid frame. - ctx->flushed = 0; - - // Initialize the decoder on the first frame. - if (ctx->pbi == NULL) { - res = init_decoder(ctx); - if (res != VPX_CODEC_OK) return res; - } - - res = vp9_parse_superframe_index(data, data_sz, frame_sizes, &frame_count, - ctx->decrypt_cb, ctx->decrypt_state); - if (res != VPX_CODEC_OK) return res; - - if (ctx->svc_decoding && ctx->svc_spatial_layer < frame_count - 1) - frame_count = ctx->svc_spatial_layer + 1; - - // Decode in serial mode. - if (frame_count > 0) { - const uint8_t *const data_end = data + data_sz; - int i; - - for (i = 0; i < frame_count; ++i) { - const uint8_t *data_start_copy = data_start; - const uint32_t frame_size = frame_sizes[i]; - if (data_start < data || frame_size > (uint32_t)(data_end - data_start)) { - set_error_detail(ctx, "Invalid frame size in index"); - return VPX_CODEC_CORRUPT_FRAME; - } - - res = decode_one(ctx, &data_start_copy, frame_size, user_priv); - if (res != VPX_CODEC_OK) return res; - - data_start += frame_size; - } - } else { - const uint8_t *const data_end = data + data_sz; - while (data_start < data_end) { - const uint32_t frame_size = (uint32_t)(data_end - data_start); - res = decode_one(ctx, &data_start, frame_size, user_priv); - if (res != VPX_CODEC_OK) return res; - - // Account for suboptimal termination by the encoder. - while (data_start < data_end) { - const uint8_t marker = - read_marker(ctx->decrypt_cb, ctx->decrypt_state, data_start); - if (marker) break; - ++data_start; - } - } - } - - return res; -} - -static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx, - vpx_codec_iter_t *iter) { - vpx_image_t *img = NULL; - - // Legacy parameter carried over from VP8. Has no effect for VP9 since we - // always return only 1 frame per decode call. - (void)iter; - - if (ctx->pbi != NULL) { - YV12_BUFFER_CONFIG sd; - vp9_ppflags_t flags = { 0, 0, 0 }; - if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) set_ppflags(ctx, &flags); - if (vp9_get_raw_frame(ctx->pbi, &sd, &flags) == 0) { - VP9_COMMON *const cm = &ctx->pbi->common; - RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs; - ctx->last_show_frame = ctx->pbi->common.new_fb_idx; - if (ctx->need_resync) return NULL; - yuvconfig2image(&ctx->img, &sd, ctx->user_priv); - ctx->img.fb_priv = frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv; - img = &ctx->img; - return img; - } - } - return NULL; -} - -static vpx_codec_err_t decoder_set_fb_fn( - vpx_codec_alg_priv_t *ctx, vpx_get_frame_buffer_cb_fn_t cb_get, - vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) { - if (cb_get == NULL || cb_release == NULL) { - return VPX_CODEC_INVALID_PARAM; - } else if (ctx->pbi == NULL) { - // If the decoder has already been initialized, do not accept changes to - // the frame buffer functions. - ctx->get_ext_fb_cb = cb_get; - ctx->release_ext_fb_cb = cb_release; - ctx->ext_priv = cb_priv; - return VPX_CODEC_OK; - } - - return VPX_CODEC_ERROR; -} - -static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_ref_frame_t *const data = va_arg(args, vpx_ref_frame_t *); - - if (data) { - vpx_ref_frame_t *const frame = (vpx_ref_frame_t *)data; - YV12_BUFFER_CONFIG sd; - image2yuvconfig(&frame->img, &sd); - return vp9_set_reference_dec( - &ctx->pbi->common, ref_frame_to_vp9_reframe(frame->frame_type), &sd); - } else { - return VPX_CODEC_INVALID_PARAM; - } -} - -static vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *); - - if (data) { - vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data; - YV12_BUFFER_CONFIG sd; - image2yuvconfig(&frame->img, &sd); - return vp9_copy_reference_dec(ctx->pbi, (VP9_REFFRAME)frame->frame_type, - &sd); - } else { - return VPX_CODEC_INVALID_PARAM; - } -} - -static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx, - va_list args) { - vp9_ref_frame_t *data = va_arg(args, vp9_ref_frame_t *); - - if (data) { - if (ctx->pbi) { - const int fb_idx = ctx->pbi->common.cur_show_frame_fb_idx; - YV12_BUFFER_CONFIG *fb = get_buf_frame(&ctx->pbi->common, fb_idx); - if (fb == NULL) return VPX_CODEC_ERROR; - yuvconfig2image(&data->img, fb, NULL); - return VPX_CODEC_OK; - } else { - return VPX_CODEC_ERROR; - } - } else { - return VPX_CODEC_INVALID_PARAM; - } -} - -static vpx_codec_err_t ctrl_set_postproc(vpx_codec_alg_priv_t *ctx, - va_list args) { -#if CONFIG_VP9_POSTPROC - vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *); - - if (data) { - ctx->postproc_cfg_set = 1; - ctx->postproc_cfg = *((vp8_postproc_cfg_t *)data); - return VPX_CODEC_OK; - } else { - return VPX_CODEC_INVALID_PARAM; - } -#else - (void)ctx; - (void)args; - return VPX_CODEC_INCAPABLE; -#endif -} - -static vpx_codec_err_t ctrl_get_quantizer(vpx_codec_alg_priv_t *ctx, - va_list args) { - int *const arg = va_arg(args, int *); - if (arg == NULL || ctx->pbi == NULL) return VPX_CODEC_INVALID_PARAM; - *arg = ctx->pbi->common.base_qindex; - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_get_last_ref_updates(vpx_codec_alg_priv_t *ctx, - va_list args) { - int *const update_info = va_arg(args, int *); - - if (update_info) { - if (ctx->pbi != NULL) { - *update_info = ctx->pbi->refresh_frame_flags; - return VPX_CODEC_OK; - } else { - return VPX_CODEC_ERROR; - } - } - - return VPX_CODEC_INVALID_PARAM; -} - -static vpx_codec_err_t ctrl_get_frame_corrupted(vpx_codec_alg_priv_t *ctx, - va_list args) { - int *corrupted = va_arg(args, int *); - - if (corrupted) { - if (ctx->pbi != NULL) { - RefCntBuffer *const frame_bufs = ctx->pbi->common.buffer_pool->frame_bufs; - if (ctx->pbi->common.frame_to_show == NULL) return VPX_CODEC_ERROR; - if (ctx->last_show_frame >= 0) - *corrupted = frame_bufs[ctx->last_show_frame].buf.corrupted; - return VPX_CODEC_OK; - } else { - return VPX_CODEC_ERROR; - } - } - - return VPX_CODEC_INVALID_PARAM; -} - -static vpx_codec_err_t ctrl_get_frame_size(vpx_codec_alg_priv_t *ctx, - va_list args) { - int *const frame_size = va_arg(args, int *); - - if (frame_size) { - if (ctx->pbi != NULL) { - const VP9_COMMON *const cm = &ctx->pbi->common; - frame_size[0] = cm->width; - frame_size[1] = cm->height; - return VPX_CODEC_OK; - } else { - return VPX_CODEC_ERROR; - } - } - - return VPX_CODEC_INVALID_PARAM; -} - -static vpx_codec_err_t ctrl_get_render_size(vpx_codec_alg_priv_t *ctx, - va_list args) { - int *const render_size = va_arg(args, int *); - - if (render_size) { - if (ctx->pbi != NULL) { - const VP9_COMMON *const cm = &ctx->pbi->common; - render_size[0] = cm->render_width; - render_size[1] = cm->render_height; - return VPX_CODEC_OK; - } else { - return VPX_CODEC_ERROR; - } - } - - return VPX_CODEC_INVALID_PARAM; -} - -static vpx_codec_err_t ctrl_get_bit_depth(vpx_codec_alg_priv_t *ctx, - va_list args) { - unsigned int *const bit_depth = va_arg(args, unsigned int *); - - if (bit_depth) { - if (ctx->pbi != NULL) { - const VP9_COMMON *const cm = &ctx->pbi->common; - *bit_depth = cm->bit_depth; - return VPX_CODEC_OK; - } else { - return VPX_CODEC_ERROR; - } - } - - return VPX_CODEC_INVALID_PARAM; -} - -static vpx_codec_err_t ctrl_set_invert_tile_order(vpx_codec_alg_priv_t *ctx, - va_list args) { - ctx->invert_tile_order = va_arg(args, int); - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_decryptor(vpx_codec_alg_priv_t *ctx, - va_list args) { - vpx_decrypt_init *init = va_arg(args, vpx_decrypt_init *); - ctx->decrypt_cb = init ? init->decrypt_cb : NULL; - ctx->decrypt_state = init ? init->decrypt_state : NULL; - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_byte_alignment(vpx_codec_alg_priv_t *ctx, - va_list args) { - const int legacy_byte_alignment = 0; - const int min_byte_alignment = 32; - const int max_byte_alignment = 1024; - const int byte_alignment = va_arg(args, int); - - if (byte_alignment != legacy_byte_alignment && - (byte_alignment < min_byte_alignment || - byte_alignment > max_byte_alignment || - (byte_alignment & (byte_alignment - 1)) != 0)) - return VPX_CODEC_INVALID_PARAM; - - ctx->byte_alignment = byte_alignment; - if (ctx->pbi != NULL) { - ctx->pbi->common.byte_alignment = byte_alignment; - } - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_skip_loop_filter(vpx_codec_alg_priv_t *ctx, - va_list args) { - ctx->skip_loop_filter = va_arg(args, int); - - if (ctx->pbi != NULL) { - ctx->pbi->common.skip_loop_filter = ctx->skip_loop_filter; - } - - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_spatial_layer_svc(vpx_codec_alg_priv_t *ctx, - va_list args) { - ctx->svc_decoding = 1; - ctx->svc_spatial_layer = va_arg(args, int); - if (ctx->svc_spatial_layer < 0) - return VPX_CODEC_INVALID_PARAM; - else - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_set_row_mt(vpx_codec_alg_priv_t *ctx, - va_list args) { - ctx->row_mt = va_arg(args, int); - - return VPX_CODEC_OK; -} - -static vpx_codec_err_t ctrl_enable_lpf_opt(vpx_codec_alg_priv_t *ctx, - va_list args) { - ctx->lpf_opt = va_arg(args, int); - - return VPX_CODEC_OK; -} - -static vpx_codec_ctrl_fn_map_t decoder_ctrl_maps[] = { - { VP8_COPY_REFERENCE, ctrl_copy_reference }, - - // Setters - { VP8_SET_REFERENCE, ctrl_set_reference }, - { VP8_SET_POSTPROC, ctrl_set_postproc }, - { VP9_INVERT_TILE_DECODE_ORDER, ctrl_set_invert_tile_order }, - { VPXD_SET_DECRYPTOR, ctrl_set_decryptor }, - { VP9_SET_BYTE_ALIGNMENT, ctrl_set_byte_alignment }, - { VP9_SET_SKIP_LOOP_FILTER, ctrl_set_skip_loop_filter }, - { VP9_DECODE_SVC_SPATIAL_LAYER, ctrl_set_spatial_layer_svc }, - { VP9D_SET_ROW_MT, ctrl_set_row_mt }, - { VP9D_SET_LOOP_FILTER_OPT, ctrl_enable_lpf_opt }, - - // Getters - { VPXD_GET_LAST_QUANTIZER, ctrl_get_quantizer }, - { VP8D_GET_LAST_REF_UPDATES, ctrl_get_last_ref_updates }, - { VP8D_GET_FRAME_CORRUPTED, ctrl_get_frame_corrupted }, - { VP9_GET_REFERENCE, ctrl_get_reference }, - { VP9D_GET_DISPLAY_SIZE, ctrl_get_render_size }, - { VP9D_GET_BIT_DEPTH, ctrl_get_bit_depth }, - { VP9D_GET_FRAME_SIZE, ctrl_get_frame_size }, - - { -1, NULL }, -}; - -#ifndef VERSION_STRING -#define VERSION_STRING -#endif -CODEC_INTERFACE(vpx_codec_vp9_dx) = { - "WebM Project VP9 Decoder" VERSION_STRING, - VPX_CODEC_INTERNAL_ABI_VERSION, -#if CONFIG_VP9_HIGHBITDEPTH - VPX_CODEC_CAP_HIGHBITDEPTH | -#endif - VPX_CODEC_CAP_DECODER | VP9_CAP_POSTPROC | - VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER, // vpx_codec_caps_t - decoder_init, // vpx_codec_init_fn_t - decoder_destroy, // vpx_codec_destroy_fn_t - decoder_ctrl_maps, // vpx_codec_ctrl_fn_map_t - { - // NOLINT - decoder_peek_si, // vpx_codec_peek_si_fn_t - decoder_get_si, // vpx_codec_get_si_fn_t - decoder_decode, // vpx_codec_decode_fn_t - decoder_get_frame, // vpx_codec_frame_get_fn_t - decoder_set_fb_fn, // vpx_codec_set_fb_fn_t - }, - { - // NOLINT - 0, - NULL, // vpx_codec_enc_cfg_map_t - NULL, // vpx_codec_encode_fn_t - NULL, // vpx_codec_get_cx_data_fn_t - NULL, // vpx_codec_enc_config_set_fn_t - NULL, // vpx_codec_get_global_headers_fn_t - NULL, // vpx_codec_get_preview_frame_fn_t - NULL // vpx_codec_enc_mr_get_mem_loc_fn_t - } -}; diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_dx_iface.h b/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_dx_iface.h deleted file mode 100644 index f60688c4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_dx_iface.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VP9_VP9_DX_IFACE_H_ -#define VPX_VP9_VP9_DX_IFACE_H_ - -#include "vp9/decoder/vp9_decoder.h" - -typedef vpx_codec_stream_info_t vp9_stream_info_t; - -struct vpx_codec_alg_priv { - vpx_codec_priv_t base; - vpx_codec_dec_cfg_t cfg; - vp9_stream_info_t si; - VP9Decoder *pbi; - void *user_priv; - int postproc_cfg_set; - vp8_postproc_cfg_t postproc_cfg; - vpx_decrypt_cb decrypt_cb; - void *decrypt_state; - vpx_image_t img; - int img_avail; - int flushed; - int invert_tile_order; - int last_show_frame; // Index of last output frame. - int byte_alignment; - int skip_loop_filter; - - int need_resync; // wait for key/intra-only frame - // BufferPool that holds all reference frames. - BufferPool *buffer_pool; - - // External frame buffer info to save for VP9 common. - void *ext_priv; // Private data associated with the external frame buffers. - vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb; - vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb; - - // Allow for decoding up to a given spatial layer for SVC stream. - int svc_decoding; - int svc_spatial_layer; - int row_mt; - int lpf_opt; -}; - -#endif // VPX_VP9_VP9_DX_IFACE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_iface_common.c b/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_iface_common.c deleted file mode 100644 index 8d031694..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_iface_common.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2019 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file in the root of the source tree. An additional - * intellectual property rights grant can be found in the file PATENTS. - * All contributing project authors may be found in the AUTHORS file in - * the root of the source tree. - */ - -#include "vp9/vp9_iface_common.h" -void yuvconfig2image(vpx_image_t *img, const YV12_BUFFER_CONFIG *yv12, - void *user_priv) { - /** vpx_img_wrap() doesn't allow specifying independent strides for - * the Y, U, and V planes, nor other alignment adjustments that - * might be representable by a YV12_BUFFER_CONFIG, so we just - * initialize all the fields.*/ - int bps; - if (!yv12->subsampling_y) { - if (!yv12->subsampling_x) { - img->fmt = VPX_IMG_FMT_I444; - bps = 24; - } else { - img->fmt = VPX_IMG_FMT_I422; - bps = 16; - } - } else { - if (!yv12->subsampling_x) { - img->fmt = VPX_IMG_FMT_I440; - bps = 16; - } else { - img->fmt = VPX_IMG_FMT_I420; - bps = 12; - } - } - img->cs = yv12->color_space; - img->range = yv12->color_range; - img->bit_depth = 8; - img->w = yv12->y_stride; - img->h = ALIGN_POWER_OF_TWO(yv12->y_height + 2 * VP9_ENC_BORDER_IN_PIXELS, 3); - img->d_w = yv12->y_crop_width; - img->d_h = yv12->y_crop_height; - img->r_w = yv12->render_width; - img->r_h = yv12->render_height; - img->x_chroma_shift = yv12->subsampling_x; - img->y_chroma_shift = yv12->subsampling_y; - img->planes[VPX_PLANE_Y] = yv12->y_buffer; - img->planes[VPX_PLANE_U] = yv12->u_buffer; - img->planes[VPX_PLANE_V] = yv12->v_buffer; - img->planes[VPX_PLANE_ALPHA] = NULL; - img->stride[VPX_PLANE_Y] = yv12->y_stride; - img->stride[VPX_PLANE_U] = yv12->uv_stride; - img->stride[VPX_PLANE_V] = yv12->uv_stride; - img->stride[VPX_PLANE_ALPHA] = yv12->y_stride; -#if CONFIG_VP9_HIGHBITDEPTH - if (yv12->flags & YV12_FLAG_HIGHBITDEPTH) { - // vpx_image_t uses byte strides and a pointer to the first byte - // of the image. - img->fmt = (vpx_img_fmt_t)(img->fmt | VPX_IMG_FMT_HIGHBITDEPTH); - img->bit_depth = yv12->bit_depth; - img->planes[VPX_PLANE_Y] = (uint8_t *)CONVERT_TO_SHORTPTR(yv12->y_buffer); - img->planes[VPX_PLANE_U] = (uint8_t *)CONVERT_TO_SHORTPTR(yv12->u_buffer); - img->planes[VPX_PLANE_V] = (uint8_t *)CONVERT_TO_SHORTPTR(yv12->v_buffer); - img->planes[VPX_PLANE_ALPHA] = NULL; - img->stride[VPX_PLANE_Y] = 2 * yv12->y_stride; - img->stride[VPX_PLANE_U] = 2 * yv12->uv_stride; - img->stride[VPX_PLANE_V] = 2 * yv12->uv_stride; - img->stride[VPX_PLANE_ALPHA] = 2 * yv12->y_stride; - } -#endif // CONFIG_VP9_HIGHBITDEPTH - img->bps = bps; - img->user_priv = user_priv; - img->img_data = yv12->buffer_alloc; - img->img_data_owner = 0; - img->self_allocd = 0; -} - -vpx_codec_err_t image2yuvconfig(const vpx_image_t *img, - YV12_BUFFER_CONFIG *yv12) { - yv12->y_buffer = img->planes[VPX_PLANE_Y]; - yv12->u_buffer = img->planes[VPX_PLANE_U]; - yv12->v_buffer = img->planes[VPX_PLANE_V]; - - yv12->y_crop_width = img->d_w; - yv12->y_crop_height = img->d_h; - yv12->render_width = img->r_w; - yv12->render_height = img->r_h; - yv12->y_width = img->d_w; - yv12->y_height = img->d_h; - - yv12->uv_width = img->x_chroma_shift == 1 || img->fmt == VPX_IMG_FMT_NV12 - ? (1 + yv12->y_width) / 2 - : yv12->y_width; - yv12->uv_height = - img->y_chroma_shift == 1 ? (1 + yv12->y_height) / 2 : yv12->y_height; - yv12->uv_crop_width = yv12->uv_width; - yv12->uv_crop_height = yv12->uv_height; - - yv12->y_stride = img->stride[VPX_PLANE_Y]; - yv12->uv_stride = img->stride[VPX_PLANE_U]; - yv12->color_space = img->cs; - yv12->color_range = img->range; - -#if CONFIG_VP9_HIGHBITDEPTH - if (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) { - // In vpx_image_t - // planes point to uint8 address of start of data - // stride counts uint8s to reach next row - // In YV12_BUFFER_CONFIG - // y_buffer, u_buffer, v_buffer point to uint16 address of data - // stride and border counts in uint16s - // This means that all the address calculations in the main body of code - // should work correctly. - // However, before we do any pixel operations we need to cast the address - // to a uint16 ponter and double its value. - yv12->y_buffer = CONVERT_TO_BYTEPTR(yv12->y_buffer); - yv12->u_buffer = CONVERT_TO_BYTEPTR(yv12->u_buffer); - yv12->v_buffer = CONVERT_TO_BYTEPTR(yv12->v_buffer); - yv12->y_stride >>= 1; - yv12->uv_stride >>= 1; - yv12->flags = YV12_FLAG_HIGHBITDEPTH; - } else { - yv12->flags = 0; - } - yv12->border = (yv12->y_stride - img->w) / 2; -#else - yv12->border = (img->stride[VPX_PLANE_Y] - img->w) / 2; -#endif // CONFIG_VP9_HIGHBITDEPTH - yv12->subsampling_x = img->x_chroma_shift; - yv12->subsampling_y = img->y_chroma_shift; - // When reading the data, UV are in one plane for NV12 format, thus - // x_chroma_shift is 0. After converting, UV are in separate planes, and - // subsampling_x should be set to 1. - if (img->fmt == VPX_IMG_FMT_NV12) yv12->subsampling_x = 1; - return VPX_CODEC_OK; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_iface_common.h b/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_iface_common.h deleted file mode 100644 index e646917c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9_iface_common.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_VP9_VP9_IFACE_COMMON_H_ -#define VPX_VP9_VP9_IFACE_COMMON_H_ - -#include -#include "vpx_ports/mem.h" -#include "vpx/vp8.h" -#include "vpx_scale/yv12config.h" -#include "common/vp9_enums.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void yuvconfig2image(vpx_image_t *img, const YV12_BUFFER_CONFIG *yv12, - void *user_priv); - -vpx_codec_err_t image2yuvconfig(const vpx_image_t *img, - YV12_BUFFER_CONFIG *yv12); - -static INLINE VP9_REFFRAME -ref_frame_to_vp9_reframe(vpx_ref_frame_type_t frame) { - switch (frame) { - case VP8_LAST_FRAME: return VP9_LAST_FLAG; - case VP8_GOLD_FRAME: return VP9_GOLD_FLAG; - case VP8_ALTR_FRAME: return VP9_ALT_FLAG; - } - assert(0 && "Invalid Reference Frame"); - return VP9_LAST_FLAG; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VP9_VP9_IFACE_COMMON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9cx.mk b/presentation/src/main/cpp/third_party/libvpx/vp9/vp9cx.mk deleted file mode 100644 index 7a0e2d8d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9cx.mk +++ /dev/null @@ -1,179 +0,0 @@ -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -VP9_CX_EXPORTS += exports_enc - -VP9_CX_SRCS-yes += $(VP9_COMMON_SRCS-yes) -VP9_CX_SRCS-no += $(VP9_COMMON_SRCS-no) -VP9_CX_SRCS_REMOVE-yes += $(VP9_COMMON_SRCS_REMOVE-yes) -VP9_CX_SRCS_REMOVE-no += $(VP9_COMMON_SRCS_REMOVE-no) - -VP9_CX_SRCS-yes += vp9_cx_iface.c -VP9_CX_SRCS-yes += vp9_cx_iface.h - -VP9_CX_SRCS-yes += encoder/vp9_bitstream.c -VP9_CX_SRCS-yes += encoder/vp9_context_tree.c -VP9_CX_SRCS-yes += encoder/vp9_context_tree.h -VP9_CX_SRCS-yes += encoder/vp9_cost.h -VP9_CX_SRCS-yes += encoder/vp9_cost.c -VP9_CX_SRCS-yes += encoder/vp9_dct.c -VP9_CX_SRCS-$(CONFIG_VP9_TEMPORAL_DENOISING) += encoder/vp9_denoiser.c -VP9_CX_SRCS-$(CONFIG_VP9_TEMPORAL_DENOISING) += encoder/vp9_denoiser.h -VP9_CX_SRCS-yes += encoder/vp9_encodeframe.c -VP9_CX_SRCS-yes += encoder/vp9_encodeframe.h -VP9_CX_SRCS-yes += encoder/vp9_encodemb.c -VP9_CX_SRCS-yes += encoder/vp9_encodemv.c -VP9_CX_SRCS-yes += encoder/vp9_ethread.h -VP9_CX_SRCS-yes += encoder/vp9_ethread.c -VP9_CX_SRCS-yes += encoder/vp9_extend.c -VP9_CX_SRCS-yes += encoder/vp9_firstpass.c -VP9_CX_SRCS-yes += encoder/vp9_block.h -VP9_CX_SRCS-yes += encoder/vp9_bitstream.h -VP9_CX_SRCS-yes += encoder/vp9_encodemb.h -VP9_CX_SRCS-yes += encoder/vp9_encodemv.h -VP9_CX_SRCS-yes += encoder/vp9_extend.h -VP9_CX_SRCS-yes += encoder/vp9_firstpass.h -VP9_CX_SRCS-yes += encoder/vp9_firstpass_stats.h -VP9_CX_SRCS-yes += encoder/vp9_frame_scale.c -VP9_CX_SRCS-yes += encoder/vp9_job_queue.h -VP9_CX_SRCS-yes += encoder/vp9_lookahead.c -VP9_CX_SRCS-yes += encoder/vp9_lookahead.h -VP9_CX_SRCS-yes += encoder/vp9_mcomp.h -VP9_CX_SRCS-yes += encoder/vp9_multi_thread.c -VP9_CX_SRCS-yes += encoder/vp9_multi_thread.h -VP9_CX_SRCS-yes += encoder/vp9_encoder.h -VP9_CX_SRCS-yes += encoder/vp9_quantize.h -VP9_CX_SRCS-yes += encoder/vp9_ratectrl.h -VP9_CX_SRCS-yes += encoder/vp9_rd.h -VP9_CX_SRCS-yes += encoder/vp9_rdopt.h -VP9_CX_SRCS-yes += encoder/vp9_pickmode.h -VP9_CX_SRCS-yes += encoder/vp9_svc_layercontext.h -VP9_CX_SRCS-yes += encoder/vp9_tokenize.h -VP9_CX_SRCS-yes += encoder/vp9_treewriter.h -VP9_CX_SRCS-yes += encoder/vp9_mcomp.c -VP9_CX_SRCS-yes += encoder/vp9_encoder.c -VP9_CX_SRCS-yes += encoder/vp9_picklpf.c -VP9_CX_SRCS-yes += encoder/vp9_picklpf.h -VP9_CX_SRCS-yes += encoder/vp9_quantize.c -VP9_CX_SRCS-yes += encoder/vp9_ratectrl.c -VP9_CX_SRCS-yes += encoder/vp9_rd.c -VP9_CX_SRCS-yes += encoder/vp9_rdopt.c -VP9_CX_SRCS-yes += encoder/vp9_pickmode.c -VP9_CX_SRCS-yes += encoder/vp9_partition_models.h -VP9_CX_SRCS-yes += encoder/vp9_segmentation.c -VP9_CX_SRCS-yes += encoder/vp9_segmentation.h -VP9_CX_SRCS-yes += encoder/vp9_speed_features.c -VP9_CX_SRCS-yes += encoder/vp9_speed_features.h -VP9_CX_SRCS-yes += encoder/vp9_subexp.c -VP9_CX_SRCS-yes += encoder/vp9_subexp.h -VP9_CX_SRCS-yes += encoder/vp9_svc_layercontext.c -VP9_CX_SRCS-yes += encoder/vp9_resize.c -VP9_CX_SRCS-yes += encoder/vp9_resize.h -VP9_CX_SRCS-$(CONFIG_INTERNAL_STATS) += encoder/vp9_blockiness.c -VP9_CX_SRCS-$(CONFIG_INTERNAL_STATS) += encoder/vp9_blockiness.h -VP9_CX_SRCS-$(CONFIG_NON_GREEDY_MV) += encoder/vp9_non_greedy_mv.c -VP9_CX_SRCS-$(CONFIG_NON_GREEDY_MV) += encoder/vp9_non_greedy_mv.h - -VP9_CX_SRCS-yes += encoder/vp9_tokenize.c -VP9_CX_SRCS-yes += encoder/vp9_treewriter.c -VP9_CX_SRCS-yes += encoder/vp9_aq_variance.c -VP9_CX_SRCS-yes += encoder/vp9_aq_variance.h -VP9_CX_SRCS-yes += encoder/vp9_aq_360.c -VP9_CX_SRCS-yes += encoder/vp9_aq_360.h -VP9_CX_SRCS-yes += encoder/vp9_aq_cyclicrefresh.c -VP9_CX_SRCS-yes += encoder/vp9_aq_cyclicrefresh.h -VP9_CX_SRCS-yes += encoder/vp9_aq_complexity.c -VP9_CX_SRCS-yes += encoder/vp9_aq_complexity.h -VP9_CX_SRCS-yes += encoder/vp9_alt_ref_aq.h -VP9_CX_SRCS-yes += encoder/vp9_alt_ref_aq.c -VP9_CX_SRCS-yes += encoder/vp9_skin_detection.c -VP9_CX_SRCS-yes += encoder/vp9_skin_detection.h -VP9_CX_SRCS-yes += encoder/vp9_noise_estimate.c -VP9_CX_SRCS-yes += encoder/vp9_noise_estimate.h -VP9_CX_SRCS-yes += encoder/vp9_ext_ratectrl.c -VP9_CX_SRCS-yes += encoder/vp9_ext_ratectrl.h -ifeq ($(CONFIG_VP9_POSTPROC),yes) -VP9_CX_SRCS-$(CONFIG_INTERNAL_STATS) += common/vp9_postproc.h -VP9_CX_SRCS-$(CONFIG_INTERNAL_STATS) += common/vp9_postproc.c -endif -VP9_CX_SRCS-yes += encoder/vp9_temporal_filter.c -VP9_CX_SRCS-yes += encoder/vp9_temporal_filter.h -VP9_CX_SRCS-yes += encoder/vp9_tpl_model.c -VP9_CX_SRCS-yes += encoder/vp9_tpl_model.h -VP9_CX_SRCS-yes += encoder/vp9_mbgraph.c -VP9_CX_SRCS-yes += encoder/vp9_mbgraph.h - -VP9_CX_SRCS-$(HAVE_SSE4_1) += encoder/x86/temporal_filter_sse4.c -VP9_CX_SRCS-$(HAVE_SSE4_1) += encoder/vp9_temporal_filter_constants.h -VP9_CX_SRCS-$(HAVE_NEON) += encoder/arm/neon/vp9_temporal_filter_neon.c -VP9_CX_SRCS-$(HAVE_NEON) += encoder/vp9_temporal_filter_constants.h - -VP9_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp9_quantize_sse2.c -VP9_CX_SRCS-$(HAVE_SSSE3) += encoder/x86/vp9_quantize_ssse3.c -VP9_CX_SRCS-$(HAVE_AVX2) += encoder/x86/vp9_quantize_avx2.c -VP9_CX_SRCS-$(HAVE_NEON) += encoder/arm/neon/vp9_diamond_search_sad_neon.c -ifeq ($(CONFIG_VP9_HIGHBITDEPTH),yes) -VP9_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp9_highbd_block_error_intrin_sse2.c -VP9_CX_SRCS-$(HAVE_SSE4_1) += encoder/x86/highbd_temporal_filter_sse4.c -VP9_CX_SRCS-$(HAVE_NEON) += encoder/arm/neon/vp9_highbd_temporal_filter_neon.c -endif - -VP9_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp9_dct_sse2.asm -VP9_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp9_error_sse2.asm - -VP9_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp9_dct_intrin_sse2.c -VP9_CX_SRCS-$(HAVE_SSSE3) += encoder/x86/vp9_frame_scale_ssse3.c -VP9_CX_SRCS-$(HAVE_NEON) += encoder/arm/neon/vp9_dct_neon.c - -ifeq ($(CONFIG_VP9_TEMPORAL_DENOISING),yes) -VP9_CX_SRCS-$(HAVE_SSE2) += encoder/x86/vp9_denoiser_sse2.c -VP9_CX_SRCS-$(HAVE_NEON) += encoder/arm/neon/vp9_denoiser_neon.c -endif - -VP9_CX_SRCS-$(HAVE_AVX2) += encoder/x86/vp9_error_avx2.c - -VP9_CX_SRCS-$(HAVE_NEON) += encoder/arm/neon/vp9_error_neon.c -VP9_CX_SRCS-$(HAVE_SVE) += encoder/arm/neon/vp9_error_sve.c -VP9_CX_SRCS-$(HAVE_NEON) += encoder/arm/neon/vp9_frame_scale_neon.c -VP9_CX_SRCS-$(HAVE_NEON) += encoder/arm/neon/vp9_quantize_neon.c -ifeq ($(CONFIG_VP9_HIGHBITDEPTH),yes) -VP9_CX_SRCS-$(HAVE_NEON) += encoder/arm/neon/vp9_highbd_error_neon.c -endif - -VP9_CX_SRCS-$(HAVE_MSA) += encoder/mips/msa/vp9_error_msa.c - -ifneq ($(CONFIG_VP9_HIGHBITDEPTH),yes) -VP9_CX_SRCS-$(HAVE_MSA) += encoder/mips/msa/vp9_fdct4x4_msa.c -VP9_CX_SRCS-$(HAVE_MSA) += encoder/mips/msa/vp9_fdct8x8_msa.c -VP9_CX_SRCS-$(HAVE_MSA) += encoder/mips/msa/vp9_fdct16x16_msa.c -VP9_CX_SRCS-$(HAVE_MSA) += encoder/mips/msa/vp9_fdct_msa.h -endif # !CONFIG_VP9_HIGHBITDEPTH - -VP9_CX_SRCS-$(HAVE_VSX) += encoder/ppc/vp9_quantize_vsx.c - -# Strip unnecessary files with CONFIG_REALTIME_ONLY -VP9_CX_SRCS_REMOVE-$(CONFIG_REALTIME_ONLY) += encoder/vp9_firstpass.c -VP9_CX_SRCS_REMOVE-$(CONFIG_REALTIME_ONLY) += encoder/vp9_mbgraph.c -VP9_CX_SRCS_REMOVE-$(CONFIG_REALTIME_ONLY) += encoder/vp9_temporal_filter.c -VP9_CX_SRCS_REMOVE-$(CONFIG_REALTIME_ONLY) += encoder/x86/temporal_filter_sse4.c -VP9_CX_SRCS_REMOVE-$(CONFIG_REALTIME_ONLY) += encoder/vp9_temporal_filter_constants.h -VP9_CX_SRCS_REMOVE-$(CONFIG_REALTIME_ONLY) += encoder/x86/highbd_temporal_filter_sse4.c -VP9_CX_SRCS_REMOVE-$(CONFIG_REALTIME_ONLY) += encoder/arm/neon/vp9_temporal_filter_neon.c -VP9_CX_SRCS_REMOVE-$(CONFIG_REALTIME_ONLY) += encoder/arm/neon/vp9_highbd_temporal_filter_neon.c -VP9_CX_SRCS_REMOVE-$(CONFIG_REALTIME_ONLY) += encoder/vp9_alt_ref_aq.h -VP9_CX_SRCS_REMOVE-$(CONFIG_REALTIME_ONLY) += encoder/vp9_alt_ref_aq.c -VP9_CX_SRCS_REMOVE-$(CONFIG_REALTIME_ONLY) += encoder/vp9_aq_variance.c -VP9_CX_SRCS_REMOVE-$(CONFIG_REALTIME_ONLY) += encoder/vp9_aq_variance.h -VP9_CX_SRCS_REMOVE-$(CONFIG_REALTIME_ONLY) += encoder/vp9_aq_360.c -VP9_CX_SRCS_REMOVE-$(CONFIG_REALTIME_ONLY) += encoder/vp9_aq_360.h -VP9_CX_SRCS_REMOVE-$(CONFIG_REALTIME_ONLY) += encoder/vp9_aq_complexity.c -VP9_CX_SRCS_REMOVE-$(CONFIG_REALTIME_ONLY) += encoder/vp9_aq_complexity.h - -VP9_CX_SRCS-yes := $(filter-out $(VP9_CX_SRCS_REMOVE-yes),$(VP9_CX_SRCS-yes)) diff --git a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9dx.mk b/presentation/src/main/cpp/third_party/libvpx/vp9/vp9dx.mk deleted file mode 100644 index 93a5f368..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vp9/vp9dx.mk +++ /dev/null @@ -1,34 +0,0 @@ -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -VP9_DX_EXPORTS += exports_dec - -VP9_DX_SRCS-yes += $(VP9_COMMON_SRCS-yes) -VP9_DX_SRCS-no += $(VP9_COMMON_SRCS-no) -VP9_DX_SRCS_REMOVE-yes += $(VP9_COMMON_SRCS_REMOVE-yes) -VP9_DX_SRCS_REMOVE-no += $(VP9_COMMON_SRCS_REMOVE-no) - -VP9_DX_SRCS-yes += vp9_dx_iface.c -VP9_DX_SRCS-yes += vp9_dx_iface.h - -VP9_DX_SRCS-yes += decoder/vp9_decodemv.c -VP9_DX_SRCS-yes += decoder/vp9_decodeframe.c -VP9_DX_SRCS-yes += decoder/vp9_decodeframe.h -VP9_DX_SRCS-yes += decoder/vp9_detokenize.c -VP9_DX_SRCS-yes += decoder/vp9_decodemv.h -VP9_DX_SRCS-yes += decoder/vp9_detokenize.h -VP9_DX_SRCS-yes += decoder/vp9_decoder.c -VP9_DX_SRCS-yes += decoder/vp9_decoder.h -VP9_DX_SRCS-yes += decoder/vp9_dsubexp.c -VP9_DX_SRCS-yes += decoder/vp9_dsubexp.h -VP9_DX_SRCS-yes += decoder/vp9_job_queue.c -VP9_DX_SRCS-yes += decoder/vp9_job_queue.h - -VP9_DX_SRCS-yes := $(filter-out $(VP9_DX_SRCS_REMOVE-yes),$(VP9_DX_SRCS-yes)) diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/exports_com b/presentation/src/main/cpp/third_party/libvpx/vpx/exports_com deleted file mode 100644 index 2ab05099..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/exports_com +++ /dev/null @@ -1,16 +0,0 @@ -text vpx_codec_build_config -text vpx_codec_control_ -text vpx_codec_destroy -text vpx_codec_err_to_string -text vpx_codec_error -text vpx_codec_error_detail -text vpx_codec_get_caps -text vpx_codec_iface_name -text vpx_codec_version -text vpx_codec_version_extra_str -text vpx_codec_version_str -text vpx_img_alloc -text vpx_img_flip -text vpx_img_free -text vpx_img_set_rect -text vpx_img_wrap diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/exports_dec b/presentation/src/main/cpp/third_party/libvpx/vpx/exports_dec deleted file mode 100644 index c694ebae..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/exports_dec +++ /dev/null @@ -1,8 +0,0 @@ -text vpx_codec_dec_init_ver -text vpx_codec_decode -text vpx_codec_get_frame -text vpx_codec_get_stream_info -text vpx_codec_peek_stream_info -text vpx_codec_register_put_frame_cb -text vpx_codec_register_put_slice_cb -text vpx_codec_set_frame_buffer_functions diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/exports_enc b/presentation/src/main/cpp/third_party/libvpx/vpx/exports_enc deleted file mode 100644 index 914e36cd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/exports_enc +++ /dev/null @@ -1,9 +0,0 @@ -text vpx_codec_enc_config_default -text vpx_codec_enc_config_set -text vpx_codec_enc_init_multi_ver -text vpx_codec_enc_init_ver -text vpx_codec_encode -text vpx_codec_get_cx_data -text vpx_codec_get_global_headers -text vpx_codec_get_preview_frame -text vpx_codec_set_cx_data_buf diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/internal/vpx_codec_internal.h b/presentation/src/main/cpp/third_party/libvpx/vpx/internal/vpx_codec_internal.h deleted file mode 100644 index 275b6a43..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/internal/vpx_codec_internal.h +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/*!\file - * \brief Describes the decoder algorithm interface for algorithm - * implementations. - * - * This file defines the private structures and data types that are only - * relevant to implementing an algorithm, as opposed to using it. - * - * To create a decoder algorithm class, an interface structure is put - * into the global namespace: - *

- *     my_codec.c:
- *       vpx_codec_iface_t my_codec = {
- *           "My Codec v1.0",
- *           VPX_CODEC_ALG_ABI_VERSION,
- *           ...
- *       };
- *     
- * - * An application instantiates a specific decoder instance by using - * vpx_codec_dec_init() and a pointer to the algorithm's interface structure: - *
- *     my_app.c:
- *       extern vpx_codec_iface_t my_codec;
- *       {
- *           vpx_codec_ctx_t algo;
- *           int threads = 4;
- *           vpx_codec_dec_cfg_t cfg = { threads, 0, 0 };
- *           res = vpx_codec_dec_init(&algo, &my_codec, &cfg, 0);
- *       }
- *     
- * - * Once initialized, the instance is manged using other functions from - * the vpx_codec_* family. - */ -#ifndef VPX_VPX_INTERNAL_VPX_CODEC_INTERNAL_H_ -#define VPX_VPX_INTERNAL_VPX_CODEC_INTERNAL_H_ -#include "../vpx_decoder.h" -#include "../vpx_encoder.h" -#include - -#include "vpx_config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*!\brief Current ABI version number - * - * \internal - * If this file is altered in any way that changes the ABI, this value - * must be bumped. Examples include, but are not limited to, changing - * types, removing or reassigning enums, adding/removing/rearranging - * fields to structures - */ -#define VPX_CODEC_INTERNAL_ABI_VERSION (5) /**<\hideinitializer*/ - -typedef struct vpx_codec_alg_priv vpx_codec_alg_priv_t; -typedef struct vpx_codec_priv_enc_mr_cfg vpx_codec_priv_enc_mr_cfg_t; - -/*!\brief init function pointer prototype - * - * Performs algorithm-specific initialization of the decoder context. This - * function is called by vpx_codec_dec_init() and vpx_codec_enc_init(), so - * plugins implementing this interface may trust the input parameters to be - * properly initialized. - * - * \param[in] ctx Pointer to this instance's context - * \retval #VPX_CODEC_OK - * The input stream was recognized and decoder initialized. - * \retval #VPX_CODEC_MEM_ERROR - * Memory operation failed. - */ -typedef vpx_codec_err_t (*vpx_codec_init_fn_t)( - vpx_codec_ctx_t *ctx, vpx_codec_priv_enc_mr_cfg_t *data); - -/*!\brief destroy function pointer prototype - * - * Performs algorithm-specific destruction of the decoder context. This - * function is called by the generic vpx_codec_destroy() wrapper function, - * so plugins implementing this interface may trust the input parameters - * to be properly initialized. - * - * \param[in] ctx Pointer to this instance's context - * \retval #VPX_CODEC_OK - * The input stream was recognized and decoder initialized. - * \retval #VPX_CODEC_MEM_ERROR - * Memory operation failed. - */ -typedef vpx_codec_err_t (*vpx_codec_destroy_fn_t)(vpx_codec_alg_priv_t *ctx); - -/*!\brief parse stream info function pointer prototype - * - * Performs high level parsing of the bitstream. This function is called by the - * generic vpx_codec_peek_stream_info() wrapper function, so plugins - * implementing this interface may trust the input parameters to be properly - * initialized. - * - * \param[in] data Pointer to a block of data to parse - * \param[in] data_sz Size of the data buffer - * \param[in,out] si Pointer to stream info to update. The size member - * \ref MUST be properly initialized, but \ref MAY be - * clobbered by the algorithm. This parameter \ref MAY - * be NULL. - * - * \retval #VPX_CODEC_OK - * Bitstream is parsable and stream information updated - */ -typedef vpx_codec_err_t (*vpx_codec_peek_si_fn_t)(const uint8_t *data, - unsigned int data_sz, - vpx_codec_stream_info_t *si); - -/*!\brief Return information about the current stream. - * - * Returns information about the stream that has been parsed during decoding. - * - * \param[in] ctx Pointer to this instance's context - * \param[in,out] si Pointer to stream info to update. The size member - * \ref MUST be properly initialized, but \ref MAY be - * clobbered by the algorithm. This parameter \ref MAY - * be NULL. - * - * \retval #VPX_CODEC_OK - * Bitstream is parsable and stream information updated - */ -typedef vpx_codec_err_t (*vpx_codec_get_si_fn_t)(vpx_codec_alg_priv_t *ctx, - vpx_codec_stream_info_t *si); - -/*!\brief control function pointer prototype - * - * This function is used to exchange algorithm specific data with the decoder - * instance. This can be used to implement features specific to a particular - * algorithm. - * - * This function is called by the generic vpx_codec_control() wrapper - * function, so plugins implementing this interface may trust the input - * parameters to be properly initialized. However, this interface does not - * provide type safety for the exchanged data or assign meanings to the - * control codes. Those details should be specified in the algorithm's - * header file. In particular, the ctrl_id parameter is guaranteed to exist - * in the algorithm's control mapping table, and the data parameter may be NULL. - * - * - * \param[in] ctx Pointer to this instance's context - * \param[in] ctrl_id Algorithm specific control identifier - * \param[in,out] data Data to exchange with algorithm instance. - * - * \retval #VPX_CODEC_OK - * The internal state data was deserialized. - */ -typedef vpx_codec_err_t (*vpx_codec_control_fn_t)(vpx_codec_alg_priv_t *ctx, - va_list ap); - -/*!\brief control function pointer mapping - * - * This structure stores the mapping between control identifiers and - * implementing functions. Each algorithm provides a list of these - * mappings. This list is searched by the vpx_codec_control() wrapper - * function to determine which function to invoke. The special - * value {0, NULL} is used to indicate end-of-list, and must be - * present. The special value {0, } can be used as a catch-all - * mapping. This implies that ctrl_id values chosen by the algorithm - * \ref MUST be non-zero. - */ -typedef const struct vpx_codec_ctrl_fn_map { - int ctrl_id; - vpx_codec_control_fn_t fn; -} vpx_codec_ctrl_fn_map_t; - -/*!\brief decode data function pointer prototype - * - * Processes a buffer of coded data. If the processing results in a new - * decoded frame becoming available, put_slice and put_frame callbacks - * are invoked as appropriate. This function is called by the generic - * vpx_codec_decode() wrapper function, so plugins implementing this - * interface may trust the input parameters to be properly initialized. - * - * \param[in] ctx Pointer to this instance's context - * \param[in] data Pointer to this block of new coded data. If - * NULL, the put_frame callback is invoked for - * the previously decoded frame. - * \param[in] data_sz Size of the coded data, in bytes. - * - * \return Returns #VPX_CODEC_OK if the coded data was processed completely - * and future pictures can be decoded without error. Otherwise, - * see the descriptions of the other error codes in ::vpx_codec_err_t - * for recoverability capabilities. - */ -typedef vpx_codec_err_t (*vpx_codec_decode_fn_t)(vpx_codec_alg_priv_t *ctx, - const uint8_t *data, - unsigned int data_sz, - void *user_priv); - -/*!\brief Decoded frames iterator - * - * Iterates over a list of the frames available for display. The iterator - * storage should be initialized to NULL to start the iteration. Iteration is - * complete when this function returns NULL. - * - * The list of available frames becomes valid upon completion of the - * vpx_codec_decode call, and remains valid until the next call to - * vpx_codec_decode. - * - * \param[in] ctx Pointer to this instance's context - * \param[in out] iter Iterator storage, initialized to NULL - * - * \return Returns a pointer to an image, if one is ready for display. Frames - * produced will always be in PTS (presentation time stamp) order. - */ -typedef vpx_image_t *(*vpx_codec_get_frame_fn_t)(vpx_codec_alg_priv_t *ctx, - vpx_codec_iter_t *iter); - -/*!\brief Pass in external frame buffers for the decoder to use. - * - * Registers functions to be called when libvpx needs a frame buffer - * to decode the current frame and a function to be called when libvpx does - * not internally reference the frame buffer. This set function must - * be called before the first call to decode or libvpx will assume the - * default behavior of allocating frame buffers internally. - * - * \param[in] ctx Pointer to this instance's context - * \param[in] cb_get Pointer to the get callback function - * \param[in] cb_release Pointer to the release callback function - * \param[in] cb_priv Callback's private data - * - * \retval #VPX_CODEC_OK - * External frame buffers will be used by libvpx. - * \retval #VPX_CODEC_INVALID_PARAM - * One or more of the callbacks were NULL. - * \retval #VPX_CODEC_ERROR - * Decoder context not initialized, or algorithm not capable of - * using external frame buffers. - * - * \note - * When decoding VP9, the application may be required to pass in at least - * #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS external frame - * buffers. - */ -typedef vpx_codec_err_t (*vpx_codec_set_fb_fn_t)( - vpx_codec_alg_priv_t *ctx, vpx_get_frame_buffer_cb_fn_t cb_get, - vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv); - -typedef vpx_codec_err_t (*vpx_codec_encode_fn_t)(vpx_codec_alg_priv_t *ctx, - const vpx_image_t *img, - vpx_codec_pts_t pts, - unsigned long duration, - vpx_enc_frame_flags_t flags, - vpx_enc_deadline_t deadline); -typedef const vpx_codec_cx_pkt_t *(*vpx_codec_get_cx_data_fn_t)( - vpx_codec_alg_priv_t *ctx, vpx_codec_iter_t *iter); - -typedef vpx_codec_err_t (*vpx_codec_enc_config_set_fn_t)( - vpx_codec_alg_priv_t *ctx, const vpx_codec_enc_cfg_t *cfg); -typedef vpx_fixed_buf_t *(*vpx_codec_get_global_headers_fn_t)( - vpx_codec_alg_priv_t *ctx); - -typedef vpx_image_t *(*vpx_codec_get_preview_frame_fn_t)( - vpx_codec_alg_priv_t *ctx); - -typedef vpx_codec_err_t (*vpx_codec_enc_mr_get_mem_loc_fn_t)( - const vpx_codec_enc_cfg_t *cfg, void **mem_loc); - -/*!\brief usage configuration mapping - * - * This structure stores the mapping between usage identifiers and - * configuration structures. Each algorithm provides a list of these - * mappings. This list is searched by the vpx_codec_enc_config_default() - * wrapper function to determine which config to return. The special value - * {-1, {0}} is used to indicate end-of-list, and must be present. At least - * one mapping must be present, in addition to the end-of-list. - * - */ -typedef const struct vpx_codec_enc_cfg_map { - int usage; - vpx_codec_enc_cfg_t cfg; -} vpx_codec_enc_cfg_map_t; - -/*!\brief Decoder algorithm interface - * - * All decoders \ref MUST expose a variable of this type. - */ -struct vpx_codec_iface { - const char *name; /**< Identification String */ - int abi_version; /**< Implemented ABI version */ - vpx_codec_caps_t caps; /**< Decoder capabilities */ - vpx_codec_init_fn_t init; /**< \copydoc ::vpx_codec_init_fn_t */ - vpx_codec_destroy_fn_t destroy; /**< \copydoc ::vpx_codec_destroy_fn_t */ - vpx_codec_ctrl_fn_map_t *ctrl_maps; /**< \copydoc ::vpx_codec_ctrl_fn_map_t */ - struct vpx_codec_dec_iface { - vpx_codec_peek_si_fn_t peek_si; /**< \copydoc ::vpx_codec_peek_si_fn_t */ - vpx_codec_get_si_fn_t get_si; /**< \copydoc ::vpx_codec_get_si_fn_t */ - vpx_codec_decode_fn_t decode; /**< \copydoc ::vpx_codec_decode_fn_t */ - vpx_codec_get_frame_fn_t - get_frame; /**< \copydoc ::vpx_codec_get_frame_fn_t */ - vpx_codec_set_fb_fn_t set_fb_fn; /**< \copydoc ::vpx_codec_set_fb_fn_t */ - } dec; - struct vpx_codec_enc_iface { - int cfg_map_count; - vpx_codec_enc_cfg_map_t - *cfg_maps; /**< \copydoc ::vpx_codec_enc_cfg_map_t */ - vpx_codec_encode_fn_t encode; /**< \copydoc ::vpx_codec_encode_fn_t */ - vpx_codec_get_cx_data_fn_t - get_cx_data; /**< \copydoc ::vpx_codec_get_cx_data_fn_t */ - vpx_codec_enc_config_set_fn_t - cfg_set; /**< \copydoc ::vpx_codec_enc_config_set_fn_t */ - vpx_codec_get_global_headers_fn_t - get_glob_hdrs; /**< \copydoc ::vpx_codec_get_global_headers_fn_t */ - vpx_codec_get_preview_frame_fn_t - get_preview; /**< \copydoc ::vpx_codec_get_preview_frame_fn_t */ - vpx_codec_enc_mr_get_mem_loc_fn_t - mr_get_mem_loc; /**< \copydoc ::vpx_codec_enc_mr_get_mem_loc_fn_t */ - } enc; -}; - -/*!\brief Callback function pointer / user data pair storage */ -typedef struct vpx_codec_priv_cb_pair { - union { - vpx_codec_put_frame_cb_fn_t put_frame; - vpx_codec_put_slice_cb_fn_t put_slice; - } u; - void *user_priv; -} vpx_codec_priv_cb_pair_t; - -/*!\brief Instance private storage - * - * This structure is allocated by the algorithm's init function. It can be - * extended in one of two ways. First, a second, algorithm specific structure - * can be allocated and the priv member pointed to it. Alternatively, this - * structure can be made the first member of the algorithm specific structure, - * and the pointer cast to the proper type. - */ -struct vpx_codec_priv { - const char *err_detail; - vpx_codec_flags_t init_flags; - struct { - vpx_codec_priv_cb_pair_t put_frame_cb; - vpx_codec_priv_cb_pair_t put_slice_cb; - } dec; - struct { - vpx_fixed_buf_t cx_data_dst_buf; - unsigned int cx_data_pad_before; - unsigned int cx_data_pad_after; - vpx_codec_cx_pkt_t cx_data_pkt; - unsigned int total_encoders; - } enc; -}; - -/* - * Multi-resolution encoding internal configuration - */ -struct vpx_codec_priv_enc_mr_cfg { - unsigned int mr_total_resolutions; - unsigned int mr_encoder_id; - struct vpx_rational mr_down_sampling_factor; - void *mr_low_res_mode_info; -}; - -#undef VPX_CTRL_USE_TYPE -#define VPX_CTRL_USE_TYPE(id, typ) \ - static VPX_INLINE typ id##__value(va_list args) { return va_arg(args, typ); } - -#undef VPX_CTRL_USE_TYPE_DEPRECATED -#define VPX_CTRL_USE_TYPE_DEPRECATED(id, typ) \ - static VPX_INLINE typ id##__value(va_list args) { return va_arg(args, typ); } - -#define CAST(id, arg) id##__value(arg) - -/* CODEC_INTERFACE convenience macro - * - * By convention, each codec interface is a struct with extern linkage, where - * the symbol is suffixed with _algo. A getter function is also defined to - * return a pointer to the struct, since in some cases it's easier to work - * with text symbols than data symbols (see issue #169). This function has - * the same name as the struct, less the _algo suffix. The CODEC_INTERFACE - * macro is provided to define this getter function automatically. - */ -#define CODEC_INTERFACE(id) \ - vpx_codec_iface_t *id(void) { return &id##_algo; } \ - vpx_codec_iface_t id##_algo - -/* Internal Utility Functions - * - * The following functions are intended to be used inside algorithms as - * utilities for manipulating vpx_codec_* data structures. - */ -struct vpx_codec_pkt_list { - unsigned int cnt; - unsigned int max; - struct vpx_codec_cx_pkt pkts[1]; -}; - -#define vpx_codec_pkt_list_decl(n) \ - union { \ - struct vpx_codec_pkt_list head; \ - struct { \ - struct vpx_codec_pkt_list head; \ - struct vpx_codec_cx_pkt pkts[n]; \ - } alloc; \ - } - -#define vpx_codec_pkt_list_init(m) \ - (m)->alloc.head.cnt = 0, \ - (m)->alloc.head.max = sizeof((m)->alloc.pkts) / sizeof((m)->alloc.pkts[0]) - -int vpx_codec_pkt_list_add(struct vpx_codec_pkt_list *, - const struct vpx_codec_cx_pkt *); - -const vpx_codec_cx_pkt_t *vpx_codec_pkt_list_get( - struct vpx_codec_pkt_list *list, vpx_codec_iter_t *iter); - -#include -#include - -struct vpx_internal_error_info { - vpx_codec_err_t error_code; - int has_detail; - char detail[80]; - int setjmp; - jmp_buf jmp; -}; - -#if CONFIG_DEBUG -#define CHECK_MEM_ERROR(error, lval, expr) \ - do { \ - assert((error)->setjmp); \ - (lval) = (expr); \ - if (!(lval)) \ - vpx_internal_error(error, VPX_CODEC_MEM_ERROR, \ - "Failed to allocate " #lval " at %s:%d", __FILE__, \ - __LINE__); \ - } while (0) -#else -#define CHECK_MEM_ERROR(error, lval, expr) \ - do { \ - assert((error)->setjmp); \ - (lval) = (expr); \ - if (!(lval)) \ - vpx_internal_error(error, VPX_CODEC_MEM_ERROR, \ - "Failed to allocate " #lval); \ - } while (0) -#endif - -#define CLANG_ANALYZER_NORETURN -#if defined(__has_feature) -#if __has_feature(attribute_analyzer_noreturn) -#undef CLANG_ANALYZER_NORETURN -#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn)) -#endif -#endif - -// Tells the compiler to perform `printf` format string checking if the -// compiler supports it; see the 'format' attribute in -// . -#define LIBVPX_FORMAT_PRINTF(string_index, first_to_check) -#if defined(__has_attribute) -#if __has_attribute(format) -#undef LIBVPX_FORMAT_PRINTF -#define LIBVPX_FORMAT_PRINTF(string_index, first_to_check) \ - __attribute__((__format__(__printf__, string_index, first_to_check))) -#endif -#endif - -void vpx_internal_error(struct vpx_internal_error_info *info, - vpx_codec_err_t error, const char *fmt, ...) - LIBVPX_FORMAT_PRINTF(3, 4) CLANG_ANALYZER_NORETURN; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_INTERNAL_VPX_CODEC_INTERNAL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/internal/vpx_ratectrl_rtc.h b/presentation/src/main/cpp/third_party/libvpx/vpx/internal/vpx_ratectrl_rtc.h deleted file mode 100644 index 2643b557..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/internal/vpx_ratectrl_rtc.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2021 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_INTERNAL_VPX_RATECTRL_RTC_H_ -#define VPX_VPX_INTERNAL_VPX_RATECTRL_RTC_H_ - -#include "vpx/vpx_encoder.h" - -namespace libvpx { - -enum class RcFrameType { kKeyFrame = 0, kInterFrame = 1 }; - -enum class FrameDropDecision { - kOk, // Frame is encoded. - kDrop, // Frame is dropped. -}; - -struct UVDeltaQP { - // For the UV channel: the QP for the dc/ac value is given as - // GetQP() + uvdc/ac_delta_q, where the uvdc/ac_delta_q are negative numbers. - int uvdc_delta_q; - int uvac_delta_q; -}; - -struct VpxRateControlRtcConfig { - VpxRateControlRtcConfig() { - width = 1280; - height = 720; - max_quantizer = 63; - min_quantizer = 2; - target_bandwidth = 1000; - buf_initial_sz = 600; - buf_optimal_sz = 600; - buf_sz = 1000; - undershoot_pct = overshoot_pct = 50; - max_intra_bitrate_pct = 50; - max_inter_bitrate_pct = 0; - framerate = 30.0; - ts_number_layers = 1; - rc_mode = VPX_CBR; - aq_mode = 0; - layer_target_bitrate[0] = static_cast(target_bandwidth); - ts_rate_decimator[0] = 1; - frame_drop_thresh = 0; - is_screen = false; - } - - int width; - int height; - // 0-63 - int max_quantizer; - int min_quantizer; - int64_t target_bandwidth; - int64_t buf_initial_sz; - int64_t buf_optimal_sz; - int64_t buf_sz; - int undershoot_pct; - int overshoot_pct; - int max_intra_bitrate_pct; - int max_inter_bitrate_pct; - double framerate; - // Number of temporal layers - int ts_number_layers; - int layer_target_bitrate[VPX_MAX_LAYERS]; - int ts_rate_decimator[VPX_TS_MAX_LAYERS]; - // vbr, cbr - enum vpx_rc_mode rc_mode; - int aq_mode; - int frame_drop_thresh; - bool is_screen; -}; -} // namespace libvpx -#endif // VPX_VPX_INTERNAL_VPX_RATECTRL_RTC_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/src/vpx_codec.c b/presentation/src/main/cpp/third_party/libvpx/vpx/src/vpx_codec.c deleted file mode 100644 index c54a18ec..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/src/vpx_codec.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/*!\file - * \brief Provides the high level interface to wrap decoder algorithms. - * - */ -#include -#include -#include -#include "vpx/vpx_integer.h" -#include "vpx/internal/vpx_codec_internal.h" -#include "vpx_version.h" - -#define SAVE_STATUS(ctx, var) (ctx ? (ctx->err = var) : var) - -int vpx_codec_version(void) { return VERSION_PACKED; } - -const char *vpx_codec_version_str(void) { return VERSION_STRING_NOSP; } - -const char *vpx_codec_version_extra_str(void) { return VERSION_EXTRA; } - -const char *vpx_codec_iface_name(vpx_codec_iface_t *iface) { - return iface ? iface->name : ""; -} - -const char *vpx_codec_err_to_string(vpx_codec_err_t err) { - switch (err) { - case VPX_CODEC_OK: return "Success"; - case VPX_CODEC_ERROR: return "Unspecified internal error"; - case VPX_CODEC_MEM_ERROR: return "Memory allocation error"; - case VPX_CODEC_ABI_MISMATCH: return "ABI version mismatch"; - case VPX_CODEC_INCAPABLE: - return "Codec does not implement requested capability"; - case VPX_CODEC_UNSUP_BITSTREAM: - return "Bitstream not supported by this decoder"; - case VPX_CODEC_UNSUP_FEATURE: - return "Bitstream required feature not supported by this decoder"; - case VPX_CODEC_CORRUPT_FRAME: return "Corrupt frame detected"; - case VPX_CODEC_INVALID_PARAM: return "Invalid parameter"; - case VPX_CODEC_LIST_END: return "End of iterated list"; - } - - return "Unrecognized error code"; -} - -const char *vpx_codec_error(const vpx_codec_ctx_t *ctx) { - return (ctx) ? vpx_codec_err_to_string(ctx->err) - : vpx_codec_err_to_string(VPX_CODEC_INVALID_PARAM); -} - -const char *vpx_codec_error_detail(const vpx_codec_ctx_t *ctx) { - if (ctx && ctx->err) - return ctx->priv ? ctx->priv->err_detail : ctx->err_detail; - - return NULL; -} - -vpx_codec_err_t vpx_codec_destroy(vpx_codec_ctx_t *ctx) { - vpx_codec_err_t res; - - if (!ctx) - res = VPX_CODEC_INVALID_PARAM; - else if (!ctx->iface || !ctx->priv) - res = VPX_CODEC_ERROR; - else { - ctx->iface->destroy((vpx_codec_alg_priv_t *)ctx->priv); - - ctx->iface = NULL; - ctx->name = NULL; - ctx->priv = NULL; - res = VPX_CODEC_OK; - } - - return SAVE_STATUS(ctx, res); -} - -vpx_codec_caps_t vpx_codec_get_caps(vpx_codec_iface_t *iface) { - return iface ? iface->caps : 0; -} - -vpx_codec_err_t vpx_codec_control_(vpx_codec_ctx_t *ctx, int ctrl_id, ...) { - vpx_codec_err_t res; - - if (!ctx || !ctrl_id) - res = VPX_CODEC_INVALID_PARAM; - else if (!ctx->iface || !ctx->priv || !ctx->iface->ctrl_maps) - res = VPX_CODEC_ERROR; - else { - vpx_codec_ctrl_fn_map_t *entry; - - res = VPX_CODEC_INCAPABLE; - - for (entry = ctx->iface->ctrl_maps; entry->fn; entry++) { - if (!entry->ctrl_id || entry->ctrl_id == ctrl_id) { - va_list ap; - - va_start(ap, ctrl_id); - res = entry->fn((vpx_codec_alg_priv_t *)ctx->priv, ap); - va_end(ap); - break; - } - } - } - - return SAVE_STATUS(ctx, res); -} - -void vpx_internal_error(struct vpx_internal_error_info *info, - vpx_codec_err_t error, const char *fmt, ...) { - va_list ap; - - info->error_code = error; - info->has_detail = 0; - - if (fmt) { - size_t sz = sizeof(info->detail); - - info->has_detail = 1; - va_start(ap, fmt); - vsnprintf(info->detail, sz - 1, fmt, ap); - va_end(ap); - info->detail[sz - 1] = '\0'; - } - - if (info->setjmp) longjmp(info->jmp, info->error_code); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/src/vpx_decoder.c b/presentation/src/main/cpp/third_party/libvpx/vpx/src/vpx_decoder.c deleted file mode 100644 index c79cc708..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/src/vpx_decoder.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/*!\file - * \brief Provides the high level interface to wrap decoder algorithms. - * - */ -#include -#include "vpx/internal/vpx_codec_internal.h" - -#define SAVE_STATUS(ctx, var) (ctx ? (ctx->err = var) : var) - -static vpx_codec_alg_priv_t *get_alg_priv(vpx_codec_ctx_t *ctx) { - return (vpx_codec_alg_priv_t *)ctx->priv; -} - -vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t *ctx, - vpx_codec_iface_t *iface, - const vpx_codec_dec_cfg_t *cfg, - vpx_codec_flags_t flags, int ver) { - vpx_codec_err_t res; - - if (ver != VPX_DECODER_ABI_VERSION) - res = VPX_CODEC_ABI_MISMATCH; - else if (!ctx || !iface) - res = VPX_CODEC_INVALID_PARAM; - else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION) - res = VPX_CODEC_ABI_MISMATCH; - else if ((flags & VPX_CODEC_USE_POSTPROC) && - !(iface->caps & VPX_CODEC_CAP_POSTPROC)) - res = VPX_CODEC_INCAPABLE; - else if ((flags & VPX_CODEC_USE_ERROR_CONCEALMENT) && - !(iface->caps & VPX_CODEC_CAP_ERROR_CONCEALMENT)) - res = VPX_CODEC_INCAPABLE; - else if ((flags & VPX_CODEC_USE_INPUT_FRAGMENTS) && - !(iface->caps & VPX_CODEC_CAP_INPUT_FRAGMENTS)) - res = VPX_CODEC_INCAPABLE; - else if (!(iface->caps & VPX_CODEC_CAP_DECODER)) - res = VPX_CODEC_INCAPABLE; - else { - memset(ctx, 0, sizeof(*ctx)); - ctx->iface = iface; - ctx->name = iface->name; - ctx->priv = NULL; - ctx->init_flags = flags; - ctx->config.dec = cfg; - - res = ctx->iface->init(ctx, NULL); - if (res) { - ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL; - vpx_codec_destroy(ctx); - } - } - - return SAVE_STATUS(ctx, res); -} - -vpx_codec_err_t vpx_codec_peek_stream_info(vpx_codec_iface_t *iface, - const uint8_t *data, - unsigned int data_sz, - vpx_codec_stream_info_t *si) { - vpx_codec_err_t res; - - if (!iface || !data || !data_sz || !si || - si->sz < sizeof(vpx_codec_stream_info_t)) - res = VPX_CODEC_INVALID_PARAM; - else { - /* Set default/unknown values */ - si->w = 0; - si->h = 0; - - res = iface->dec.peek_si(data, data_sz, si); - } - - return res; -} - -vpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t *ctx, - vpx_codec_stream_info_t *si) { - vpx_codec_err_t res; - - if (!ctx || !si || si->sz < sizeof(vpx_codec_stream_info_t)) - res = VPX_CODEC_INVALID_PARAM; - else if (!ctx->iface || !ctx->priv) - res = VPX_CODEC_ERROR; - else { - /* Set default/unknown values */ - si->w = 0; - si->h = 0; - - res = ctx->iface->dec.get_si(get_alg_priv(ctx), si); - } - - return SAVE_STATUS(ctx, res); -} - -vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t *ctx, const uint8_t *data, - unsigned int data_sz, void *user_priv, - long deadline) { - vpx_codec_err_t res; - (void)deadline; - - /* Sanity checks */ - /* NULL data ptr allowed if data_sz is 0 too */ - if (!ctx || (!data && data_sz) || (data && !data_sz)) - res = VPX_CODEC_INVALID_PARAM; - else if (!ctx->iface || !ctx->priv) - res = VPX_CODEC_ERROR; - else - res = ctx->iface->dec.decode(get_alg_priv(ctx), data, data_sz, user_priv); - - return SAVE_STATUS(ctx, res); -} - -vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t *ctx, vpx_codec_iter_t *iter) { - vpx_image_t *img; - - if (!ctx || !iter || !ctx->iface || !ctx->priv) - img = NULL; - else - img = ctx->iface->dec.get_frame(get_alg_priv(ctx), iter); - - return img; -} - -vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t *ctx, - vpx_codec_put_frame_cb_fn_t cb, - void *user_priv) { - vpx_codec_err_t res; - - if (!ctx || !cb) - res = VPX_CODEC_INVALID_PARAM; - else if (!ctx->iface || !ctx->priv) - res = VPX_CODEC_ERROR; - else if (!(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME)) - res = VPX_CODEC_INCAPABLE; - else { - ctx->priv->dec.put_frame_cb.u.put_frame = cb; - ctx->priv->dec.put_frame_cb.user_priv = user_priv; - res = VPX_CODEC_OK; - } - - return SAVE_STATUS(ctx, res); -} - -vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t *ctx, - vpx_codec_put_slice_cb_fn_t cb, - void *user_priv) { - vpx_codec_err_t res; - - if (!ctx || !cb) - res = VPX_CODEC_INVALID_PARAM; - else if (!ctx->iface || !ctx->priv) - res = VPX_CODEC_ERROR; - else if (!(ctx->iface->caps & VPX_CODEC_CAP_PUT_SLICE)) - res = VPX_CODEC_INCAPABLE; - else { - ctx->priv->dec.put_slice_cb.u.put_slice = cb; - ctx->priv->dec.put_slice_cb.user_priv = user_priv; - res = VPX_CODEC_OK; - } - - return SAVE_STATUS(ctx, res); -} - -vpx_codec_err_t vpx_codec_set_frame_buffer_functions( - vpx_codec_ctx_t *ctx, vpx_get_frame_buffer_cb_fn_t cb_get, - vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) { - vpx_codec_err_t res; - - if (!ctx || !cb_get || !cb_release) { - res = VPX_CODEC_INVALID_PARAM; - } else if (!ctx->iface || !ctx->priv) { - res = VPX_CODEC_ERROR; - } else if (!(ctx->iface->caps & VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER)) { - res = VPX_CODEC_INCAPABLE; - } else { - res = ctx->iface->dec.set_fb_fn(get_alg_priv(ctx), cb_get, cb_release, - cb_priv); - } - - return SAVE_STATUS(ctx, res); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/src/vpx_encoder.c b/presentation/src/main/cpp/third_party/libvpx/vpx/src/vpx_encoder.c deleted file mode 100644 index 3af4cea3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/src/vpx_encoder.c +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/*!\file - * \brief Provides the high level interface to wrap encoder algorithms. - * - */ -#include -#include -#include -#include -#include -#include "vp8/common/blockd.h" -#include "vpx_config.h" -#include "vpx/internal/vpx_codec_internal.h" - -#define SAVE_STATUS(ctx, var) ((ctx) ? ((ctx)->err = (var)) : (var)) - -static vpx_codec_alg_priv_t *get_alg_priv(vpx_codec_ctx_t *ctx) { - return (vpx_codec_alg_priv_t *)ctx->priv; -} - -vpx_codec_err_t vpx_codec_enc_init_ver(vpx_codec_ctx_t *ctx, - vpx_codec_iface_t *iface, - const vpx_codec_enc_cfg_t *cfg, - vpx_codec_flags_t flags, int ver) { - vpx_codec_err_t res; - - if (ver != VPX_ENCODER_ABI_VERSION) - res = VPX_CODEC_ABI_MISMATCH; - else if (!ctx || !iface || !cfg) - res = VPX_CODEC_INVALID_PARAM; - else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION) - res = VPX_CODEC_ABI_MISMATCH; - else if (!(iface->caps & VPX_CODEC_CAP_ENCODER)) - res = VPX_CODEC_INCAPABLE; - else if ((flags & VPX_CODEC_USE_PSNR) && !(iface->caps & VPX_CODEC_CAP_PSNR)) - res = VPX_CODEC_INCAPABLE; - else if ((flags & VPX_CODEC_USE_OUTPUT_PARTITION) && - !(iface->caps & VPX_CODEC_CAP_OUTPUT_PARTITION)) - res = VPX_CODEC_INCAPABLE; - else { - ctx->iface = iface; - ctx->name = iface->name; - ctx->priv = NULL; - ctx->init_flags = flags; - ctx->config.enc = cfg; - res = ctx->iface->init(ctx, NULL); - - if (res) { - // IMPORTANT: ctx->priv->err_detail must be null or point to a string - // that remains valid after ctx->priv is destroyed, such as a C string - // literal. This makes it safe to call vpx_codec_error_detail() after - // vpx_codec_enc_init_ver() failed. - ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL; - vpx_codec_destroy(ctx); - } - } - - return SAVE_STATUS(ctx, res); -} - -vpx_codec_err_t vpx_codec_enc_init_multi_ver( - vpx_codec_ctx_t *ctx, vpx_codec_iface_t *iface, vpx_codec_enc_cfg_t *cfg, - int num_enc, vpx_codec_flags_t flags, vpx_rational_t *dsf, int ver) { - vpx_codec_err_t res = VPX_CODEC_OK; - - if (ver != VPX_ENCODER_ABI_VERSION) - res = VPX_CODEC_ABI_MISMATCH; - else if (!ctx || !iface || !cfg || (num_enc > 16 || num_enc < 1)) - res = VPX_CODEC_INVALID_PARAM; - else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION) - res = VPX_CODEC_ABI_MISMATCH; - else if (!(iface->caps & VPX_CODEC_CAP_ENCODER)) - res = VPX_CODEC_INCAPABLE; - else if ((flags & VPX_CODEC_USE_PSNR) && !(iface->caps & VPX_CODEC_CAP_PSNR)) - res = VPX_CODEC_INCAPABLE; - else if ((flags & VPX_CODEC_USE_OUTPUT_PARTITION) && - !(iface->caps & VPX_CODEC_CAP_OUTPUT_PARTITION)) - res = VPX_CODEC_INCAPABLE; - else { - int i; -#if CONFIG_MULTI_RES_ENCODING - int mem_loc_owned = 0; -#endif - void *mem_loc = NULL; - - if (iface->enc.mr_get_mem_loc == NULL) return VPX_CODEC_INCAPABLE; - - if (!(res = iface->enc.mr_get_mem_loc(cfg, &mem_loc))) { - for (i = 0; i < num_enc; i++) { - vpx_codec_priv_enc_mr_cfg_t mr_cfg; - - /* Validate down-sampling factor. */ - if (dsf->num < 1 || dsf->num > 4096 || dsf->den < 1 || - dsf->den > dsf->num) { - res = VPX_CODEC_INVALID_PARAM; - } else { - mr_cfg.mr_low_res_mode_info = mem_loc; - mr_cfg.mr_total_resolutions = num_enc; - mr_cfg.mr_encoder_id = num_enc - 1 - i; - mr_cfg.mr_down_sampling_factor.num = dsf->num; - mr_cfg.mr_down_sampling_factor.den = dsf->den; - - ctx->iface = iface; - ctx->name = iface->name; - ctx->priv = NULL; - ctx->init_flags = flags; - ctx->config.enc = cfg; - // ctx takes ownership of mr_cfg.mr_low_res_mode_info if and only if - // this call succeeds. The first ctx entry in the array is - // responsible for freeing the memory. - res = ctx->iface->init(ctx, &mr_cfg); - } - - if (res) { - const char *error_detail = ctx->priv ? ctx->priv->err_detail : NULL; - /* Destroy current ctx */ - ctx->err_detail = error_detail; - vpx_codec_destroy(ctx); - - /* Destroy already allocated high-level ctx */ - while (i) { - ctx--; - ctx->err_detail = error_detail; - vpx_codec_destroy(ctx); - i--; - } -#if CONFIG_MULTI_RES_ENCODING - if (!mem_loc_owned) { - assert(mem_loc); - free(((LOWER_RES_FRAME_INFO *)mem_loc)->mb_info); - free(mem_loc); - } -#endif - return SAVE_STATUS(ctx, res); - } -#if CONFIG_MULTI_RES_ENCODING - mem_loc_owned = 1; -#endif - ctx++; - cfg++; - dsf++; - } - ctx--; - } - } - - return SAVE_STATUS(ctx, res); -} - -vpx_codec_err_t vpx_codec_enc_config_default(vpx_codec_iface_t *iface, - vpx_codec_enc_cfg_t *cfg, - unsigned int usage) { - vpx_codec_err_t res; - - if (!iface || !cfg || usage != 0) - res = VPX_CODEC_INVALID_PARAM; - else if (!(iface->caps & VPX_CODEC_CAP_ENCODER)) - res = VPX_CODEC_INCAPABLE; - else { - assert(iface->enc.cfg_map_count == 1); - *cfg = iface->enc.cfg_maps->cfg; - res = VPX_CODEC_OK; - } - - return res; -} - -#if VPX_ARCH_X86 || VPX_ARCH_X86_64 -/* On X86, disable the x87 unit's internal 80 bit precision for better - * consistency with the SSE unit's 64 bit precision. - */ -#include "vpx_ports/x86.h" -#define FLOATING_POINT_INIT() \ - do { \ - unsigned short x87_orig_mode = x87_set_double_precision() -#define FLOATING_POINT_RESTORE() \ - x87_set_control_word(x87_orig_mode); \ - } \ - while (0) - -#else -static void FLOATING_POINT_INIT(void) {} -static void FLOATING_POINT_RESTORE(void) {} -#endif - -vpx_codec_err_t vpx_codec_encode(vpx_codec_ctx_t *ctx, const vpx_image_t *img, - vpx_codec_pts_t pts, unsigned long duration, - vpx_enc_frame_flags_t flags, - vpx_enc_deadline_t deadline) { - vpx_codec_err_t res = VPX_CODEC_OK; - - if (!ctx || (img && !duration)) - res = VPX_CODEC_INVALID_PARAM; - else if (!ctx->iface || !ctx->priv) - res = VPX_CODEC_ERROR; - else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER)) - res = VPX_CODEC_INCAPABLE; -#if ULONG_MAX > UINT32_MAX - else if (duration > UINT32_MAX || deadline > UINT32_MAX) - res = VPX_CODEC_INVALID_PARAM; -#endif - else { - unsigned int num_enc = ctx->priv->enc.total_encoders; - - /* Execute in a normalized floating point environment, if the platform - * requires it. - */ - FLOATING_POINT_INIT(); - - if (num_enc == 1) - res = ctx->iface->enc.encode(get_alg_priv(ctx), img, pts, duration, flags, - deadline); - else { - /* Multi-resolution encoding: - * Encode multi-levels in reverse order. For example, - * if mr_total_resolutions = 3, first encode level 2, - * then encode level 1, and finally encode level 0. - */ - int i; - - ctx += num_enc - 1; - if (img) img += num_enc - 1; - - for (i = num_enc - 1; i >= 0; i--) { - if ((res = ctx->iface->enc.encode(get_alg_priv(ctx), img, pts, duration, - flags, deadline))) - break; - - ctx--; - if (img) img--; - } - ctx++; - } - - FLOATING_POINT_RESTORE(); - } - - return SAVE_STATUS(ctx, res); -} - -const vpx_codec_cx_pkt_t *vpx_codec_get_cx_data(vpx_codec_ctx_t *ctx, - vpx_codec_iter_t *iter) { - const vpx_codec_cx_pkt_t *pkt = NULL; - - if (ctx) { - if (!iter) - ctx->err = VPX_CODEC_INVALID_PARAM; - else if (!ctx->iface || !ctx->priv) - ctx->err = VPX_CODEC_ERROR; - else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER)) - ctx->err = VPX_CODEC_INCAPABLE; - else - pkt = ctx->iface->enc.get_cx_data(get_alg_priv(ctx), iter); - } - - if (pkt && pkt->kind == VPX_CODEC_CX_FRAME_PKT) { - // If the application has specified a destination area for the - // compressed data, and the codec has not placed the data there, - // and it fits, copy it. - vpx_codec_priv_t *const priv = ctx->priv; - char *const dst_buf = (char *)priv->enc.cx_data_dst_buf.buf; - - if (dst_buf && pkt->data.raw.buf != dst_buf && - pkt->data.raw.sz + priv->enc.cx_data_pad_before + - priv->enc.cx_data_pad_after <= - priv->enc.cx_data_dst_buf.sz) { - vpx_codec_cx_pkt_t *modified_pkt = &priv->enc.cx_data_pkt; - - memcpy(dst_buf + priv->enc.cx_data_pad_before, pkt->data.raw.buf, - pkt->data.raw.sz); - *modified_pkt = *pkt; - modified_pkt->data.raw.buf = dst_buf; - modified_pkt->data.raw.sz += - priv->enc.cx_data_pad_before + priv->enc.cx_data_pad_after; - pkt = modified_pkt; - } - - if (dst_buf == pkt->data.raw.buf) { - priv->enc.cx_data_dst_buf.buf = dst_buf + pkt->data.raw.sz; - priv->enc.cx_data_dst_buf.sz -= pkt->data.raw.sz; - } - } - - return pkt; -} - -vpx_codec_err_t vpx_codec_set_cx_data_buf(vpx_codec_ctx_t *ctx, - const vpx_fixed_buf_t *buf, - unsigned int pad_before, - unsigned int pad_after) { - if (!ctx || !ctx->priv) return VPX_CODEC_INVALID_PARAM; - - if (buf) { - ctx->priv->enc.cx_data_dst_buf = *buf; - ctx->priv->enc.cx_data_pad_before = pad_before; - ctx->priv->enc.cx_data_pad_after = pad_after; - } else { - ctx->priv->enc.cx_data_dst_buf.buf = NULL; - ctx->priv->enc.cx_data_dst_buf.sz = 0; - ctx->priv->enc.cx_data_pad_before = 0; - ctx->priv->enc.cx_data_pad_after = 0; - } - - return VPX_CODEC_OK; -} - -const vpx_image_t *vpx_codec_get_preview_frame(vpx_codec_ctx_t *ctx) { - vpx_image_t *img = NULL; - - if (ctx) { - if (!ctx->iface || !ctx->priv) - ctx->err = VPX_CODEC_ERROR; - else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER)) - ctx->err = VPX_CODEC_INCAPABLE; - else if (!ctx->iface->enc.get_preview) - ctx->err = VPX_CODEC_INCAPABLE; - else - img = ctx->iface->enc.get_preview(get_alg_priv(ctx)); - } - - return img; -} - -vpx_fixed_buf_t *vpx_codec_get_global_headers(vpx_codec_ctx_t *ctx) { - vpx_fixed_buf_t *buf = NULL; - - if (ctx) { - if (!ctx->iface || !ctx->priv) - ctx->err = VPX_CODEC_ERROR; - else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER)) - ctx->err = VPX_CODEC_INCAPABLE; - else if (!ctx->iface->enc.get_glob_hdrs) - ctx->err = VPX_CODEC_INCAPABLE; - else - buf = ctx->iface->enc.get_glob_hdrs(get_alg_priv(ctx)); - } - - return buf; -} - -vpx_codec_err_t vpx_codec_enc_config_set(vpx_codec_ctx_t *ctx, - const vpx_codec_enc_cfg_t *cfg) { - vpx_codec_err_t res; - - if (!ctx || !ctx->iface || !ctx->priv || !cfg) - res = VPX_CODEC_INVALID_PARAM; - else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER)) - res = VPX_CODEC_INCAPABLE; - else - res = ctx->iface->enc.cfg_set(get_alg_priv(ctx), cfg); - - return SAVE_STATUS(ctx, res); -} - -int vpx_codec_pkt_list_add(struct vpx_codec_pkt_list *list, - const struct vpx_codec_cx_pkt *pkt) { - if (list->cnt < list->max) { - list->pkts[list->cnt++] = *pkt; - return 0; - } - - return 1; -} - -const vpx_codec_cx_pkt_t *vpx_codec_pkt_list_get( - struct vpx_codec_pkt_list *list, vpx_codec_iter_t *iter) { - const vpx_codec_cx_pkt_t *pkt; - - if (!(*iter)) { - *iter = list->pkts; - } - - pkt = (const vpx_codec_cx_pkt_t *)*iter; - - if ((size_t)(pkt - list->pkts) < list->cnt) - *iter = pkt + 1; - else - pkt = NULL; - - return pkt; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/src/vpx_image.c b/presentation/src/main/cpp/third_party/libvpx/vpx/src/vpx_image.c deleted file mode 100644 index 7f9f6cd4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/src/vpx_image.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include - -#include "vpx/vpx_image.h" -#include "vpx/vpx_integer.h" -#include "vpx_mem/vpx_mem.h" - -static vpx_image_t *img_alloc_helper(vpx_image_t *img, vpx_img_fmt_t fmt, - unsigned int d_w, unsigned int d_h, - unsigned int buf_align, - unsigned int stride_align, - unsigned char *img_data) { - unsigned int h, w, xcs, ycs, bps; - uint64_t s; - int stride_in_bytes; - unsigned int align; - - if (img != NULL) memset(img, 0, sizeof(vpx_image_t)); - - if (fmt == VPX_IMG_FMT_NONE) goto fail; - - /* Impose maximum values on input parameters so that this function can - * perform arithmetic operations without worrying about overflows. - */ - if (d_w > 0x08000000 || d_h > 0x08000000 || buf_align > 65536 || - stride_align > 65536) { - goto fail; - } - - /* Treat align==0 like align==1 */ - if (!buf_align) buf_align = 1; - - /* Validate alignment (must be power of 2) */ - if (buf_align & (buf_align - 1)) goto fail; - - /* Treat align==0 like align==1 */ - if (!stride_align) stride_align = 1; - - /* Validate alignment (must be power of 2) */ - if (stride_align & (stride_align - 1)) goto fail; - - /* Get sample size for this format */ - switch (fmt) { - case VPX_IMG_FMT_I420: - case VPX_IMG_FMT_YV12: - case VPX_IMG_FMT_NV12: bps = 12; break; - case VPX_IMG_FMT_I422: - case VPX_IMG_FMT_I440: bps = 16; break; - case VPX_IMG_FMT_I444: bps = 24; break; - case VPX_IMG_FMT_I42016: bps = 24; break; - case VPX_IMG_FMT_I42216: - case VPX_IMG_FMT_I44016: bps = 32; break; - case VPX_IMG_FMT_I44416: bps = 48; break; - default: bps = 16; break; - } - - /* Get chroma shift values for this format */ - // For VPX_IMG_FMT_NV12, xcs needs to be 0 such that UV data is all read at - // once. - switch (fmt) { - case VPX_IMG_FMT_I420: - case VPX_IMG_FMT_YV12: - case VPX_IMG_FMT_I422: - case VPX_IMG_FMT_I42016: - case VPX_IMG_FMT_I42216: xcs = 1; break; - default: xcs = 0; break; - } - - switch (fmt) { - case VPX_IMG_FMT_I420: - case VPX_IMG_FMT_NV12: - case VPX_IMG_FMT_I440: - case VPX_IMG_FMT_YV12: - case VPX_IMG_FMT_I42016: - case VPX_IMG_FMT_I44016: ycs = 1; break; - default: ycs = 0; break; - } - - /* Calculate storage sizes. */ - if (img_data) { - /* If the buffer was allocated externally, the width and height shouldn't - * be adjusted. */ - w = d_w; - h = d_h; - } else { - /* Calculate storage sizes given the chroma subsampling */ - align = (1 << xcs) - 1; - w = (d_w + align) & ~align; - assert(d_w <= w); - align = (1 << ycs) - 1; - h = (d_h + align) & ~align; - assert(d_h <= h); - } - - s = (fmt & VPX_IMG_FMT_PLANAR) ? w : (uint64_t)bps * w / 8; - s = (fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? s * 2 : s; - s = (s + stride_align - 1) & ~((uint64_t)stride_align - 1); - if (s > INT_MAX) goto fail; - stride_in_bytes = (int)s; - s = (fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? s / 2 : s; - - /* Allocate the new image */ - if (!img) { - img = (vpx_image_t *)calloc(1, sizeof(vpx_image_t)); - - if (!img) goto fail; - - img->self_allocd = 1; - } - - img->img_data = img_data; - - if (!img_data) { - uint64_t alloc_size; - alloc_size = (fmt & VPX_IMG_FMT_PLANAR) ? (uint64_t)h * s * bps / 8 - : (uint64_t)h * s; - - if (alloc_size != (size_t)alloc_size) goto fail; - - img->img_data = (uint8_t *)vpx_memalign(buf_align, (size_t)alloc_size); - img->img_data_owner = 1; - } - - if (!img->img_data) goto fail; - - img->fmt = fmt; - img->bit_depth = (fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 16 : 8; - img->w = w; - img->h = h; - img->x_chroma_shift = xcs; - img->y_chroma_shift = ycs; - img->bps = bps; - - /* Calculate strides */ - img->stride[VPX_PLANE_Y] = img->stride[VPX_PLANE_ALPHA] = stride_in_bytes; - img->stride[VPX_PLANE_U] = img->stride[VPX_PLANE_V] = stride_in_bytes >> xcs; - - /* Default viewport to entire image. (This vpx_img_set_rect call always - * succeeds.) */ - int ret = vpx_img_set_rect(img, 0, 0, d_w, d_h); - assert(ret == 0); - (void)ret; - return img; - -fail: - vpx_img_free(img); - return NULL; -} - -vpx_image_t *vpx_img_alloc(vpx_image_t *img, vpx_img_fmt_t fmt, - unsigned int d_w, unsigned int d_h, - unsigned int align) { - return img_alloc_helper(img, fmt, d_w, d_h, align, align, NULL); -} - -vpx_image_t *vpx_img_wrap(vpx_image_t *img, vpx_img_fmt_t fmt, unsigned int d_w, - unsigned int d_h, unsigned int stride_align, - unsigned char *img_data) { - /* Set buf_align = 1. It is ignored by img_alloc_helper because img_data is - * not NULL. */ - return img_alloc_helper(img, fmt, d_w, d_h, 1, stride_align, img_data); -} - -int vpx_img_set_rect(vpx_image_t *img, unsigned int x, unsigned int y, - unsigned int w, unsigned int h) { - if (x <= UINT_MAX - w && x + w <= img->w && y <= UINT_MAX - h && - y + h <= img->h) { - img->d_w = w; - img->d_h = h; - - /* Calculate plane pointers */ - if (!(img->fmt & VPX_IMG_FMT_PLANAR)) { - img->planes[VPX_PLANE_PACKED] = - img->img_data + x * img->bps / 8 + y * img->stride[VPX_PLANE_PACKED]; - } else { - const int bytes_per_sample = - (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1; - unsigned char *data = img->img_data; - - if (img->fmt & VPX_IMG_FMT_HAS_ALPHA) { - img->planes[VPX_PLANE_ALPHA] = - data + x * bytes_per_sample + y * img->stride[VPX_PLANE_ALPHA]; - data += (size_t)img->h * img->stride[VPX_PLANE_ALPHA]; - } - - img->planes[VPX_PLANE_Y] = - data + x * bytes_per_sample + y * img->stride[VPX_PLANE_Y]; - data += (size_t)img->h * img->stride[VPX_PLANE_Y]; - - unsigned int uv_x = x >> img->x_chroma_shift; - unsigned int uv_y = y >> img->y_chroma_shift; - if (img->fmt == VPX_IMG_FMT_NV12) { - img->planes[VPX_PLANE_U] = - data + uv_x + uv_y * img->stride[VPX_PLANE_U]; - img->planes[VPX_PLANE_V] = img->planes[VPX_PLANE_U] + 1; - } else if (!(img->fmt & VPX_IMG_FMT_UV_FLIP)) { - img->planes[VPX_PLANE_U] = - data + uv_x * bytes_per_sample + uv_y * img->stride[VPX_PLANE_U]; - data += - (size_t)(img->h >> img->y_chroma_shift) * img->stride[VPX_PLANE_U]; - img->planes[VPX_PLANE_V] = - data + uv_x * bytes_per_sample + uv_y * img->stride[VPX_PLANE_V]; - } else { - img->planes[VPX_PLANE_V] = - data + uv_x * bytes_per_sample + uv_y * img->stride[VPX_PLANE_V]; - data += - (size_t)(img->h >> img->y_chroma_shift) * img->stride[VPX_PLANE_V]; - img->planes[VPX_PLANE_U] = - data + uv_x * bytes_per_sample + uv_y * img->stride[VPX_PLANE_U]; - } - } - return 0; - } - return -1; -} - -void vpx_img_flip(vpx_image_t *img) { - /* Note: In the calculation pointer adjustment calculation, we want the - * rhs to be promoted to a signed type. Section 6.3.1.8 of the ISO C99 - * standard indicates that if the adjustment parameter is unsigned, the - * stride parameter will be promoted to unsigned, causing errors when - * the lhs is a larger type than the rhs. - */ - img->planes[VPX_PLANE_Y] += (signed)(img->d_h - 1) * img->stride[VPX_PLANE_Y]; - img->stride[VPX_PLANE_Y] = -img->stride[VPX_PLANE_Y]; - - img->planes[VPX_PLANE_U] += (signed)((img->d_h >> img->y_chroma_shift) - 1) * - img->stride[VPX_PLANE_U]; - img->stride[VPX_PLANE_U] = -img->stride[VPX_PLANE_U]; - - img->planes[VPX_PLANE_V] += (signed)((img->d_h >> img->y_chroma_shift) - 1) * - img->stride[VPX_PLANE_V]; - img->stride[VPX_PLANE_V] = -img->stride[VPX_PLANE_V]; - - img->planes[VPX_PLANE_ALPHA] += - (signed)(img->d_h - 1) * img->stride[VPX_PLANE_ALPHA]; - img->stride[VPX_PLANE_ALPHA] = -img->stride[VPX_PLANE_ALPHA]; -} - -void vpx_img_free(vpx_image_t *img) { - if (img) { - if (img->img_data && img->img_data_owner) vpx_free(img->img_data); - - if (img->self_allocd) free(img); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/vp8.h b/presentation/src/main/cpp/third_party/libvpx/vpx/vp8.h deleted file mode 100644 index f30dafed..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/vp8.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/*!\defgroup vp8 VP8 - * \ingroup codecs - * VP8 is a video compression algorithm that uses motion - * compensated prediction, Discrete Cosine Transform (DCT) coding of the - * prediction error signal and context dependent entropy coding techniques - * based on arithmetic principles. It features: - * - YUV 4:2:0 image format - * - Macro-block based coding (16x16 luma plus two 8x8 chroma) - * - 1/4 (1/8) pixel accuracy motion compensated prediction - * - 4x4 DCT transform - * - 128 level linear quantizer - * - In loop deblocking filter - * - Context-based entropy coding - * - * @{ - */ -/*!\file - * \brief Provides controls common to both the VP8 encoder and decoder. - */ -#ifndef VPX_VPX_VP8_H_ -#define VPX_VPX_VP8_H_ - -#include "./vpx_codec.h" -#include "./vpx_image.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*!\brief Control functions - * - * The set of macros define the control functions of VP8 interface - */ -enum vp8_com_control_id { - /*!\brief pass in an external frame into decoder to be used as reference frame - */ - VP8_SET_REFERENCE = 1, - VP8_COPY_REFERENCE = 2, /**< get a copy of reference frame from the decoder */ - VP8_SET_POSTPROC = 3, /**< set the decoder's post processing settings */ - - /* TODO(jkoleszar): The encoder incorrectly reuses some of these values (5+) - * for its control ids. These should be migrated to something like the - * VP8_DECODER_CTRL_ID_START range next time we're ready to break the ABI. - */ - VP9_GET_REFERENCE = 128, /**< get a pointer to a reference frame */ - VP8_COMMON_CTRL_ID_MAX, - VP8_DECODER_CTRL_ID_START = 256 -}; - -/*!\brief post process flags - * - * The set of macros define VP8 decoder post processing flags - */ -enum vp8_postproc_level { - VP8_NOFILTERING = 0, - VP8_DEBLOCK = 1 << 0, - VP8_DEMACROBLOCK = 1 << 1, - VP8_ADDNOISE = 1 << 2, - VP8_MFQE = 1 << 3 -}; - -/*!\brief post process flags - * - * This define a structure that describe the post processing settings. For - * the best objective measure (using the PSNR metric) set post_proc_flag - * to VP8_DEBLOCK and deblocking_level to 1. - */ - -typedef struct vp8_postproc_cfg { - /*!\brief the types of post processing to be done, should be combination of - * "vp8_postproc_level" */ - int post_proc_flag; - int deblocking_level; /**< the strength of deblocking, valid range [0, 16] */ - int noise_level; /**< the strength of additive noise, valid range [0, 16] */ -} vp8_postproc_cfg_t; - -/*!\brief reference frame type - * - * The set of macros define the type of VP8 reference frames - */ -typedef enum vpx_ref_frame_type { - VP8_LAST_FRAME = 1, - VP8_GOLD_FRAME = 2, - VP8_ALTR_FRAME = 4 -} vpx_ref_frame_type_t; - -/*!\brief reference frame data struct - * - * Define the data struct to access vp8 reference frames. - */ -typedef struct vpx_ref_frame { - vpx_ref_frame_type_t frame_type; /**< which reference frame */ - vpx_image_t img; /**< reference frame data in image format */ -} vpx_ref_frame_t; - -/*!\brief VP9 specific reference frame data struct - * - * Define the data struct to access vp9 reference frames. - */ -typedef struct vp9_ref_frame { - int idx; /**< frame index to get (input) */ - vpx_image_t img; /**< img structure to populate (output) */ -} vp9_ref_frame_t; - -/*!\cond */ -/*!\brief vp8 decoder control function parameter type - * - * defines the data type for each of VP8 decoder control function requires - */ -VPX_CTRL_USE_TYPE(VP8_SET_REFERENCE, vpx_ref_frame_t *) -#define VPX_CTRL_VP8_SET_REFERENCE -VPX_CTRL_USE_TYPE(VP8_COPY_REFERENCE, vpx_ref_frame_t *) -#define VPX_CTRL_VP8_COPY_REFERENCE -VPX_CTRL_USE_TYPE(VP8_SET_POSTPROC, vp8_postproc_cfg_t *) -#define VPX_CTRL_VP8_SET_POSTPROC -VPX_CTRL_USE_TYPE(VP9_GET_REFERENCE, vp9_ref_frame_t *) -#define VPX_CTRL_VP9_GET_REFERENCE - -/*!\endcond */ -/*! @} - end defgroup vp8 */ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_VP8_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/vp8cx.h b/presentation/src/main/cpp/third_party/libvpx/vpx/vp8cx.h deleted file mode 100644 index 4e29725c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/vp8cx.h +++ /dev/null @@ -1,1118 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_VPX_VP8CX_H_ -#define VPX_VPX_VP8CX_H_ - -/*!\defgroup vp8_encoder WebM VP8/VP9 Encoder - * \ingroup vp8 - * - * @{ - */ -#include "./vp8.h" -#include "./vpx_encoder.h" -#include "./vpx_ext_ratectrl.h" - -/*!\file - * \brief Provides definitions for using VP8 or VP9 encoder algorithm within the - * vpx Codec Interface. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/*!\name Algorithm interface for VP8 - * - * This interface provides the capability to encode raw VP8 streams. - * @{ - */ - -/*!\brief A single instance of the VP8 encoder. - *\deprecated This access mechanism is provided for backwards compatibility; - * prefer vpx_codec_vp8_cx(). - */ -extern vpx_codec_iface_t vpx_codec_vp8_cx_algo; - -/*!\brief The interface to the VP8 encoder. - */ -extern vpx_codec_iface_t *vpx_codec_vp8_cx(void); -/*!@} - end algorithm interface member group*/ - -/*!\name Algorithm interface for VP9 - * - * This interface provides the capability to encode raw VP9 streams. - * @{ - */ - -/*!\brief A single instance of the VP9 encoder. - *\deprecated This access mechanism is provided for backwards compatibility; - * prefer vpx_codec_vp9_cx(). - */ -extern vpx_codec_iface_t vpx_codec_vp9_cx_algo; - -/*!\brief The interface to the VP9 encoder. - */ -extern vpx_codec_iface_t *vpx_codec_vp9_cx(void); -/*!@} - end algorithm interface member group*/ - -/* - * Algorithm Flags - */ - -/*!\brief Don't reference the last frame - * - * When this flag is set, the encoder will not use the last frame as a - * predictor. When not set, the encoder will choose whether to use the - * last frame or not automatically. - */ -#define VP8_EFLAG_NO_REF_LAST (1 << 16) - -/*!\brief Don't reference the golden frame - * - * When this flag is set, the encoder will not use the golden frame as a - * predictor. When not set, the encoder will choose whether to use the - * golden frame or not automatically. - */ -#define VP8_EFLAG_NO_REF_GF (1 << 17) - -/*!\brief Don't reference the alternate reference frame - * - * When this flag is set, the encoder will not use the alt ref frame as a - * predictor. When not set, the encoder will choose whether to use the - * alt ref frame or not automatically. - */ -#define VP8_EFLAG_NO_REF_ARF (1 << 21) - -/*!\brief Don't update the last frame - * - * When this flag is set, the encoder will not update the last frame with - * the contents of the current frame. - */ -#define VP8_EFLAG_NO_UPD_LAST (1 << 18) - -/*!\brief Don't update the golden frame - * - * When this flag is set, the encoder will not update the golden frame with - * the contents of the current frame. - */ -#define VP8_EFLAG_NO_UPD_GF (1 << 22) - -/*!\brief Don't update the alternate reference frame - * - * When this flag is set, the encoder will not update the alt ref frame with - * the contents of the current frame. - */ -#define VP8_EFLAG_NO_UPD_ARF (1 << 23) - -/*!\brief Force golden frame update - * - * When this flag is set, the encoder copy the contents of the current frame - * to the golden frame buffer. - */ -#define VP8_EFLAG_FORCE_GF (1 << 19) - -/*!\brief Force alternate reference frame update - * - * When this flag is set, the encoder copy the contents of the current frame - * to the alternate reference frame buffer. - */ -#define VP8_EFLAG_FORCE_ARF (1 << 24) - -/*!\brief Disable entropy update - * - * When this flag is set, the encoder will not update its internal entropy - * model based on the entropy of this frame. - */ -#define VP8_EFLAG_NO_UPD_ENTROPY (1 << 20) - -/*!\brief VPx encoder control functions - * - * This set of macros define the control functions available for VPx - * encoder interface. - * - * \sa #vpx_codec_control - */ -enum vp8e_enc_control_id { - /*!\brief Codec control function to pass an ROI map to encoder. - * - * Supported in codecs: VP8 - */ - VP8E_SET_ROI_MAP = 8, - - /*!\brief Codec control function to pass an Active map to encoder. - * - * Supported in codecs: VP8, VP9 - */ - VP8E_SET_ACTIVEMAP, - - /*!\brief Codec control function to set encoder scaling mode. - * - * Supported in codecs: VP8, VP9 - */ - VP8E_SET_SCALEMODE = 11, - - /*!\brief Codec control function to set encoder internal speed settings. - * - * Changes in this value influences, among others, the encoder's selection - * of motion estimation methods. Values greater than 0 will increase encoder - * speed at the expense of quality. - * - * \note Valid range for VP8: -16..16 - * \note Valid range for VP9: -9..9 - * \note A negative value (-n) is treated as its absolute value (n) in VP9. - * - * Supported in codecs: VP8, VP9 - */ - VP8E_SET_CPUUSED = 13, - - /*!\brief Codec control function to enable automatic use of arf frames. - * - * \note Valid range for VP8: 0..1 - * \note Valid range for VP9: 0..6 - * - * Supported in codecs: VP8, VP9 - */ - VP8E_SET_ENABLEAUTOALTREF, - - /*!\brief control function to set noise sensitivity - * - * 0: off, 1: OnYOnly, 2: OnYUV, - * 3: OnYUVAggressive, 4: Adaptive - * - * Supported in codecs: VP8 - */ - VP8E_SET_NOISE_SENSITIVITY, - - /*!\brief Codec control function to set higher sharpness at the expense - * of a lower PSNR. - * - * \note Valid range: 0..7 - * - * Supported in codecs: VP8, VP9 - */ - VP8E_SET_SHARPNESS, - - /*!\brief Codec control function to set the threshold for MBs treated static. - * - * Supported in codecs: VP8, VP9 - */ - VP8E_SET_STATIC_THRESHOLD, - - /*!\brief Codec control function to set the number of token partitions. - * - * Supported in codecs: VP8 - */ - VP8E_SET_TOKEN_PARTITIONS, - - /*!\brief Codec control function to get last quantizer chosen by the encoder. - * - * Return value uses internal quantizer scale defined by the codec. - * - * Supported in codecs: VP8, VP9 - */ - VP8E_GET_LAST_QUANTIZER, - - /*!\brief Codec control function to get last quantizer chosen by the encoder. - * - * Return value uses the 0..63 scale as used by the rc_*_quantizer config - * parameters. - * - * Supported in codecs: VP8, VP9 - */ - VP8E_GET_LAST_QUANTIZER_64, - - /*!\brief Codec control function to set the max no of frames to create arf. - * - * Supported in codecs: VP8, VP9 - */ - VP8E_SET_ARNR_MAXFRAMES, - - /*!\brief Codec control function to set the filter strength for the arf. - * - * Supported in codecs: VP8, VP9 - */ - VP8E_SET_ARNR_STRENGTH, - - /*!\deprecated control function to set the filter type to use for the arf. */ - VP8E_SET_ARNR_TYPE, - - /*!\brief Codec control function to set visual tuning. - * - * Supported in codecs: VP8, VP9 - */ - VP8E_SET_TUNING, - - /*!\brief Codec control function to set constrained / constant quality level. - * - * \attention For this value to be used vpx_codec_enc_cfg_t::rc_end_usage must - * be set to #VPX_CQ or #VPX_Q - * \note Valid range: 0..63 - * - * Supported in codecs: VP8, VP9 - */ - VP8E_SET_CQ_LEVEL, - - /*!\brief Codec control function to set Max data rate for Intra frames. - * - * This value controls additional clamping on the maximum size of a - * keyframe. It is expressed as a percentage of the average - * per-frame bitrate, with the special (and default) value 0 meaning - * unlimited, or no additional clamping beyond the codec's built-in - * algorithm. - * - * For example, to allocate no more than 4.5 frames worth of bitrate - * to a keyframe, set this to 450. - * - * Supported in codecs: VP8, VP9 - */ - VP8E_SET_MAX_INTRA_BITRATE_PCT, - - /*!\brief Codec control function to set reference and update frame flags. - * - * Supported in codecs: VP8 - */ - VP8E_SET_FRAME_FLAGS, - - /*!\brief Codec control function to set max data rate for Inter frames. - * - * This value controls additional clamping on the maximum size of an - * inter frame. It is expressed as a percentage of the average - * per-frame bitrate, with the special (and default) value 0 meaning - * unlimited, or no additional clamping beyond the codec's built-in - * algorithm. - * - * For example, to allow no more than 4.5 frames worth of bitrate - * to an inter frame, set this to 450. - * - * Supported in codecs: VP9 - */ - VP9E_SET_MAX_INTER_BITRATE_PCT, - - /*!\brief Boost percentage for Golden Frame in CBR mode. - * - * This value controls the amount of boost given to Golden Frame in - * CBR mode. It is expressed as a percentage of the average - * per-frame bitrate, with the special (and default) value 0 meaning - * the feature is off, i.e., no golden frame boost in CBR mode and - * average bitrate target is used. - * - * For example, to allow 100% more bits, i.e., 2X, in a golden frame - * than average frame, set this to 100. - * - * Supported in codecs: VP9 - */ - VP9E_SET_GF_CBR_BOOST_PCT, - - /*!\brief Codec control function to set the temporal layer id. - * - * For temporal scalability: this control allows the application to set the - * layer id for each frame to be encoded. Note that this control must be set - * for every frame prior to encoding. The usage of this control function - * supersedes the internal temporal pattern counter, which is now deprecated. - * - * Supported in codecs: VP8 - */ - VP8E_SET_TEMPORAL_LAYER_ID, - - /*!\brief Codec control function to set encoder screen content mode. - * - * 0: off, 1: On, 2: On with more aggressive rate control. - * - * Supported in codecs: VP8 - */ - VP8E_SET_SCREEN_CONTENT_MODE, - - /*!\brief Codec control function to set lossless encoding mode. - * - * VP9 can operate in lossless encoding mode, in which the bitstream - * produced will be able to decode and reconstruct a perfect copy of - * input source. This control function provides a mean to switch encoder - * into lossless coding mode(1) or normal coding mode(0) that may be lossy. - * 0 = lossy coding mode - * 1 = lossless coding mode - * - * By default, encoder operates in normal coding mode (maybe lossy). - * - * Supported in codecs: VP9 - */ - VP9E_SET_LOSSLESS, - - /*!\brief Codec control function to set number of tile columns. - * - * In encoding and decoding, VP9 allows an input image frame be partitioned - * into separated vertical tile columns, which can be encoded or decoded - * independently. This enables easy implementation of parallel encoding and - * decoding. This control requests the encoder to use column tiles in - * encoding an input frame, with number of tile columns (in Log2 unit) as - * the parameter: - * 0 = 1 tile column - * 1 = 2 tile columns - * 2 = 4 tile columns - * ..... - * n = 2**n tile columns - * The requested tile columns will be capped by the encoder based on image - * size limitations (The minimum width of a tile column is 256 pixels, the - * maximum is 4096). - * - * By default, the value is 6, i.e., the maximum number of tiles supported by - * the resolution. - * - * Supported in codecs: VP9 - */ - VP9E_SET_TILE_COLUMNS, - - /*!\brief Codec control function to set number of tile rows. - * - * In encoding and decoding, VP9 allows an input image frame be partitioned - * into separated horizontal tile rows. Tile rows are encoded or decoded - * sequentially. Even though encoding/decoding of later tile rows depends on - * earlier ones, this allows the encoder to output data packets for tile rows - * prior to completely processing all tile rows in a frame, thereby reducing - * the latency in processing between input and output. The parameter - * for this control describes the number of tile rows, which has a valid - * range [0, 2]: - * 0 = 1 tile row - * 1 = 2 tile rows - * 2 = 4 tile rows - * - * By default, the value is 0, i.e. one single row tile for entire image. - * - * Supported in codecs: VP9 - */ - VP9E_SET_TILE_ROWS, - - /*!\brief Codec control function to enable frame parallel decoding feature. - * - * VP9 has a bitstream feature to reduce decoding dependency between frames - * by turning off backward update of probability context used in encoding - * and decoding. This allows staged parallel processing of more than one - * video frame in the decoder. This control function provides a means to - * turn this feature on or off for bitstreams produced by encoder. - * - * By default, this feature is on. - * - * Supported in codecs: VP9 - */ - VP9E_SET_FRAME_PARALLEL_DECODING, - - /*!\brief Codec control function to set adaptive quantization mode. - * - * VP9 has a segment based feature that allows encoder to adaptively change - * quantization parameter for each segment within a frame to improve the - * subjective quality. This control makes encoder operate in one of the - * several AQ_modes supported. - * - * By default, encoder operates with AQ_Mode 0(adaptive quantization off). - * - * Supported in codecs: VP9 - */ - VP9E_SET_AQ_MODE, - - /*!\brief Codec control function to enable/disable periodic Q boost. - * - * One VP9 encoder speed feature is to enable quality boost by lowering - * frame level Q periodically. This control function provides a mean to - * turn on/off this feature. - * 0 = off - * 1 = on - * - * By default, the encoder is allowed to use this feature for appropriate - * encoding modes. - * - * Supported in codecs: VP9 - */ - VP9E_SET_FRAME_PERIODIC_BOOST, - - /*!\brief Codec control function to set noise sensitivity. - * - * 0: off, 1: On(YOnly), 2: For SVC only, on top two spatial layers(YOnly) - * - * Supported in codecs: VP9 - */ - VP9E_SET_NOISE_SENSITIVITY, - - /*!\brief Codec control function to turn on/off SVC in encoder. - * \note Return value is VPX_CODEC_INVALID_PARAM if the encoder does not - * support SVC in its current encoding mode - * 0: off, 1: on - * - * Supported in codecs: VP9 - */ - VP9E_SET_SVC, - - /*!\brief Codec control function to pass an ROI map to encoder. - * - * Supported in codecs: VP9 - */ - VP9E_SET_ROI_MAP, - - /*!\brief Codec control function to set parameters for SVC. - * \note Parameters contain min_q, max_q, scaling factor for each of the - * SVC layers. - * - * Supported in codecs: VP9 - */ - VP9E_SET_SVC_PARAMETERS, - - /*!\brief Codec control function to set svc layer for spatial and temporal. - * \note Valid ranges: 0..#vpx_codec_enc_cfg::ss_number_layers for spatial - * layer and 0..#vpx_codec_enc_cfg::ts_number_layers for - * temporal layer. - * - * Supported in codecs: VP9 - */ - VP9E_SET_SVC_LAYER_ID, - - /*!\brief Codec control function to set content type. - * \note Valid parameter range: - * VP9E_CONTENT_DEFAULT = Regular video content (Default) - * VP9E_CONTENT_SCREEN = Screen capture content - * VP9E_CONTENT_FILM = Film content: improves grain retention - * - * Supported in codecs: VP9 - */ - VP9E_SET_TUNE_CONTENT, - - /*!\brief Codec control function to get svc layer ID. - * \note The layer ID returned is for the data packet from the registered - * callback function. - * - * Supported in codecs: VP9 - */ - VP9E_GET_SVC_LAYER_ID, - - /*!\brief Codec control function to register callback to get per layer packet. - * \note Parameter for this control function is a structure with a callback - * function and a pointer to private data used by the callback. - * - * Supported in codecs: VP9 - */ - VP9E_REGISTER_CX_CALLBACK, - - /*!\brief Codec control function to set color space info. - * \note Valid ranges: 0..7, default is "UNKNOWN". - * 0 = UNKNOWN, - * 1 = BT_601 - * 2 = BT_709 - * 3 = SMPTE_170 - * 4 = SMPTE_240 - * 5 = BT_2020 - * 6 = RESERVED - * 7 = SRGB - * - * Supported in codecs: VP9 - */ - VP9E_SET_COLOR_SPACE, - - /*!\brief Codec control function to set minimum interval between GF/ARF frames - * - * By default the value is set as 4. - * - * Supported in codecs: VP9 - */ - VP9E_SET_MIN_GF_INTERVAL = 48, - - /*!\brief Codec control function to set minimum interval between GF/ARF frames - * - * By default the value is set as 16. - * - * Supported in codecs: VP9 - */ - VP9E_SET_MAX_GF_INTERVAL, - - /*!\brief Codec control function to get an Active map back from the encoder. - * - * Supported in codecs: VP9 - */ - VP9E_GET_ACTIVEMAP, - - /*!\brief Codec control function to set color range bit. - * \note Valid ranges: 0..1, default is 0 - * 0 = Limited range (16..235 or HBD equivalent) - * 1 = Full range (0..255 or HBD equivalent) - * - * Supported in codecs: VP9 - */ - VP9E_SET_COLOR_RANGE, - - /*!\brief Codec control function to set the frame flags and buffer indices - * for spatial layers. The frame flags and buffer indices are set using the - * struct #vpx_svc_ref_frame_config defined below. - * - * Supported in codecs: VP9 - */ - VP9E_SET_SVC_REF_FRAME_CONFIG, - - /*!\brief Codec control function to set intended rendering image size. - * - * By default, this is identical to the image size in pixels. - * - * Supported in codecs: VP9 - */ - VP9E_SET_RENDER_SIZE, - - /*!\brief Codec control function to set target level. - * - * 255: off (default); 0: only keep level stats; 10: target for level 1.0; - * 11: target for level 1.1; ... 62: target for level 6.2 - * - * Supported in codecs: VP9 - */ - VP9E_SET_TARGET_LEVEL, - - /*!\brief Codec control function to set row level multi-threading. - * - * 0 : off, 1 : on - * - * Supported in codecs: VP9 - */ - VP9E_SET_ROW_MT, - - /*!\brief Codec control function to get bitstream level. - * - * Supported in codecs: VP9 - */ - VP9E_GET_LEVEL, - - /*!\brief Codec control function to enable/disable special mode for altref - * adaptive quantization. You can use it with --aq-mode concurrently. - * - * Enable special adaptive quantization for altref frames based on their - * expected prediction quality for the future frames. - * - * Supported in codecs: VP9 - */ - VP9E_SET_ALT_REF_AQ, - - /*!\brief Boost percentage for Golden Frame in CBR mode. - * - * This value controls the amount of boost given to Golden Frame in - * CBR mode. It is expressed as a percentage of the average - * per-frame bitrate, with the special (and default) value 0 meaning - * the feature is off, i.e., no golden frame boost in CBR mode and - * average bitrate target is used. - * - * For example, to allow 100% more bits, i.e., 2X, in a golden frame - * than average frame, set this to 100. - * - * Supported in codecs: VP8 - */ - VP8E_SET_GF_CBR_BOOST_PCT, - - /*!\brief Codec control function to enable the extreme motion vector unit test - * in VP9. Please note that this is only used in motion vector unit test. - * - * 0 : off, 1 : MAX_EXTREME_MV, 2 : MIN_EXTREME_MV - * - * Supported in codecs: VP9 - */ - VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, - - /*!\brief Codec control function to constrain the inter-layer prediction - * (prediction of lower spatial resolution) in VP9 SVC. - * - * 0 : inter-layer prediction on, 1 : off, 2 : off only on non-key frames - * - * Supported in codecs: VP9 - */ - VP9E_SET_SVC_INTER_LAYER_PRED, - - /*!\brief Codec control function to set mode and thresholds for frame - * dropping in SVC. Drop frame thresholds are set per-layer. Mode is set as: - * 0 : layer-dependent dropping, 1 : constrained dropping, current layer drop - * forces drop on all upper layers. Default mode is 0. - * - * Supported in codecs: VP9 - */ - VP9E_SET_SVC_FRAME_DROP_LAYER, - - /*!\brief Codec control function to get the refresh and reference flags and - * the buffer indices, up to the last encoded spatial layer. - * - * Supported in codecs: VP9 - */ - VP9E_GET_SVC_REF_FRAME_CONFIG, - - /*!\brief Codec control function to enable/disable use of golden reference as - * a second temporal reference for SVC. Only used when inter-layer prediction - * is disabled on INTER frames. - * - * 0: Off, 1: Enabled (default) - * - * Supported in codecs: VP9 - */ - VP9E_SET_SVC_GF_TEMPORAL_REF, - - /*!\brief Codec control function to enable spatial layer sync frame, for any - * spatial layer. Enabling it for layer k means spatial layer k will disable - * all temporal prediction, but keep the inter-layer prediction. It will - * refresh any temporal reference buffer for that layer, and reset the - * temporal layer for the superframe to 0. Setting the layer sync for base - * spatial layer forces a key frame. Default is off (0) for all spatial - * layers. Spatial layer sync flag is reset to 0 after each encoded layer, - * so when control is invoked it is only used for the current superframe. - * - * 0: Off (default), 1: Enabled - * - * Supported in codecs: VP9 - */ - VP9E_SET_SVC_SPATIAL_LAYER_SYNC, - - /*!\brief Codec control function to enable temporal dependency model. - * - * Vp9 allows the encoder to run temporal dependency model and use it to - * improve the compression performance. To enable, set this parameter to be - * 1. The default value is set to be 1. - */ - VP9E_SET_TPL, - - /*!\brief Codec control function to enable postencode frame drop. - * - * This will allow encoder to drop frame after it's encoded. - * - * 0: Off (default), 1: Enabled - * - * Supported in codecs: VP9 - */ - VP9E_SET_POSTENCODE_DROP, - - /*!\brief Codec control function to set delta q for uv. - * - * Cap it at +/-15. - * - * Supported in codecs: VP9 - */ - VP9E_SET_DELTA_Q_UV, - - /*!\brief Codec control function to disable increase Q on overshoot in CBR. - * - * 0: On (default), 1: Disable. - * - * Supported in codecs: VP9 - */ - VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, - - /*!\brief Codec control function to disable loopfilter. - * - * 0: Loopfilter on all frames, 1: Disable on non reference frames. - * 2: Disable on all frames. - * - * Supported in codecs: VP9 - */ - VP9E_SET_DISABLE_LOOPFILTER, - - /*!\brief Codec control function to enable external rate control library. - * - * args[0]: path of the rate control library - * - * args[1]: private config of the rate control library - * - * Supported in codecs: VP9 - */ - VP9E_SET_EXTERNAL_RATE_CONTROL, - - /*!\brief Codec control to disable internal features in rate control. - * - * This will do 3 things, only for 1 pass: - * - Turn off low motion computation - * - Turn off gf update constraint on key frame frequency - * - Turn off content mode for cyclic refresh - * - * With those, the rate control is expected to work exactly the same as the - * interface provided in ratectrl_rtc.cc/h - * - * Supported in codecs: VP9 - */ - VP9E_SET_RTC_EXTERNAL_RATECTRL, - - /*!\brief Codec control function to get loopfilter level in the encoder. - * - * Supported in codecs: VP9 - */ - VP9E_GET_LOOPFILTER_LEVEL, - - /*!\brief Codec control to get last quantizers for all spatial layers. - * - * Return value uses an array of internal quantizers scale defined by the - * codec, for all spatial layers. - * The size of the array passed in should be #VPX_SS_MAX_LAYERS. - * - * Supported in codecs: VP9 - */ - VP9E_GET_LAST_QUANTIZER_SVC_LAYERS, - - /*!\brief Codec control to disable internal features in rate control. - * - * This will turn off cyclic refresh for vp8. - * - * With this, the rate control is expected to work exactly the same as the - * interface provided in vp8_ratectrl_rtc.cc/h - * - * Supported in codecs: VP8 - */ - VP8E_SET_RTC_EXTERNAL_RATECTRL, - - /*!\brief Codec control to set quantizer for the next frame. - * - * This will turn off cyclic refresh. Only applicable to 1-pass without - * spatial layers. - * - * Supported in codecs: VP9 - * - */ - VP9E_SET_QUANTIZER_ONE_PASS, - - /*!\brief Codec control function to enable key frame temporal filtering. - * - * Vp9 allows the encoder to run key frame temporal filtering and use it to - * improve the compression performance. To enable, set this parameter to be - * 1. The default value is set to be 0. - */ - VP9E_SET_KEY_FRAME_FILTERING, -}; - -/*!\brief vpx 1-D scaling mode - * - * This set of constants define 1-D vpx scaling modes - */ -typedef enum vpx_scaling_mode_1d { - VP8E_NORMAL = 0, - VP8E_FOURFIVE = 1, - VP8E_THREEFIVE = 2, - VP8E_ONETWO = 3 -} VPX_SCALING_MODE; - -/*!\brief Temporal layering mode enum for VP9 SVC. - * - * This set of macros define the different temporal layering modes. - * Supported codecs: VP9 (in SVC mode) - * - */ -typedef enum vp9e_temporal_layering_mode { - /*!\brief No temporal layering. - * Used when only spatial layering is used. - */ - VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING = 0, - - /*!\brief Bypass mode. - * Used when application needs to control temporal layering. - * This will only work when the number of spatial layers equals 1. - */ - VP9E_TEMPORAL_LAYERING_MODE_BYPASS = 1, - - /*!\brief 0-1-0-1... temporal layering scheme with two temporal layers. - */ - VP9E_TEMPORAL_LAYERING_MODE_0101 = 2, - - /*!\brief 0-2-1-2... temporal layering scheme with three temporal layers. - */ - VP9E_TEMPORAL_LAYERING_MODE_0212 = 3 -} VP9E_TEMPORAL_LAYERING_MODE; - -/*!\brief vpx region of interest map - * - * These defines the data structures for the region of interest map - * - */ - -typedef struct vpx_roi_map { - /*! If ROI is enabled. */ - uint8_t enabled; - /*! An id between 0-3 (0-7 for vp9) for each 16x16 (8x8 for VP9) - * region within a frame. */ - unsigned char *roi_map; - unsigned int rows; /**< Number of rows. */ - unsigned int cols; /**< Number of columns. */ - /*! VP8 only uses the first 4 segments. VP9 uses 8 segments. */ - int delta_q[8]; /**< Quantizer deltas. Valid range: [-63, 63].*/ - int delta_lf[8]; /**< Loop filter deltas. Valid range: [-63, 63].*/ - /*! skip and ref frame segment is only used in VP9. */ - int skip[8]; /**< Skip this block. */ - int ref_frame[8]; /**< Reference frame for this block. */ - /*! Static breakout threshold for each segment. Only used in VP8. */ - unsigned int static_threshold[4]; -} vpx_roi_map_t; - -/*!\brief vpx active region map - * - * These defines the data structures for active region map - * - */ - -typedef struct vpx_active_map { - /*!\brief specify an on (1) or off (0) each 16x16 region within a frame */ - unsigned char *active_map; - unsigned int rows; /**< number of rows */ - unsigned int cols; /**< number of cols */ -} vpx_active_map_t; - -/*!\brief vpx image scaling mode - * - * This defines the data structure for image scaling mode - * - */ -typedef struct vpx_scaling_mode { - VPX_SCALING_MODE h_scaling_mode; /**< horizontal scaling mode */ - VPX_SCALING_MODE v_scaling_mode; /**< vertical scaling mode */ -} vpx_scaling_mode_t; - -/*!\brief VP8 token partition mode - * - * This defines VP8 partitioning mode for compressed data, i.e., the number of - * sub-streams in the bitstream. Used for parallelized decoding. - * - */ - -typedef enum { - VP8_ONE_TOKENPARTITION = 0, - VP8_TWO_TOKENPARTITION = 1, - VP8_FOUR_TOKENPARTITION = 2, - VP8_EIGHT_TOKENPARTITION = 3 -} vp8e_token_partitions; - -/*!brief VP9 encoder content type */ -typedef enum { - VP9E_CONTENT_DEFAULT, - VP9E_CONTENT_SCREEN, - VP9E_CONTENT_FILM, - VP9E_CONTENT_INVALID -} vp9e_tune_content; - -/*!\brief VP8 model tuning parameters - * - * Changes the encoder to tune for certain types of input material. - * - */ -typedef enum { VP8_TUNE_PSNR, VP8_TUNE_SSIM } vp8e_tuning; - -/*!\brief vp9 svc layer parameters - * - * This defines the spatial and temporal layer id numbers for svc encoding. - * This is used with the #VP9E_SET_SVC_LAYER_ID control to set the spatial and - * temporal layer id for the current frame. - * - */ -typedef struct vpx_svc_layer_id { - int spatial_layer_id; /**< First spatial layer to start encoding. */ - // TODO(jianj): Deprecated, to be removed. - int temporal_layer_id; /**< Temporal layer id number. */ - int temporal_layer_id_per_spatial[VPX_SS_MAX_LAYERS]; /**< Temp layer id. */ -} vpx_svc_layer_id_t; - -/*!\brief vp9 svc frame flag parameters. - * - * This defines the frame flags and buffer indices for each spatial layer for - * svc encoding. - * This is used with the #VP9E_SET_SVC_REF_FRAME_CONFIG control to set frame - * flags and buffer indices for each spatial layer for the current (super)frame. - * - */ -typedef struct vpx_svc_ref_frame_config { - int lst_fb_idx[VPX_SS_MAX_LAYERS]; /**< Last buffer index. */ - int gld_fb_idx[VPX_SS_MAX_LAYERS]; /**< Golden buffer index. */ - int alt_fb_idx[VPX_SS_MAX_LAYERS]; /**< Altref buffer index. */ - int update_buffer_slot[VPX_SS_MAX_LAYERS]; /**< Update reference frames. */ - // TODO(jianj): Remove update_last/golden/alt_ref, these are deprecated. - int update_last[VPX_SS_MAX_LAYERS]; /**< Update last. */ - int update_golden[VPX_SS_MAX_LAYERS]; /**< Update golden. */ - int update_alt_ref[VPX_SS_MAX_LAYERS]; /**< Update altref. */ - int reference_last[VPX_SS_MAX_LAYERS]; /**< Last as reference. */ - int reference_golden[VPX_SS_MAX_LAYERS]; /**< Golden as reference. */ - int reference_alt_ref[VPX_SS_MAX_LAYERS]; /**< Altref as reference. */ - int64_t duration[VPX_SS_MAX_LAYERS]; /**< Duration per spatial layer. */ -} vpx_svc_ref_frame_config_t; - -/*!\brief VP9 svc frame dropping mode. - * - * This defines the frame drop mode for SVC. - * - */ -typedef enum { - CONSTRAINED_LAYER_DROP, - /**< Upper layers are constrained to drop if current layer drops. */ - LAYER_DROP, /**< Any spatial layer can drop. */ - FULL_SUPERFRAME_DROP, /**< Only full superframe can drop. */ - CONSTRAINED_FROM_ABOVE_DROP, - /**< Lower layers are constrained to drop if current layer drops. */ -} SVC_LAYER_DROP_MODE; - -/*!\brief vp9 svc frame dropping parameters. - * - * This defines the frame drop thresholds for each spatial layer, and - * the frame dropping mode: 0 = layer based frame dropping (default), - * 1 = constrained dropping where current layer drop forces all upper - * spatial layers to drop. - */ -typedef struct vpx_svc_frame_drop { - int framedrop_thresh[VPX_SS_MAX_LAYERS]; /**< Frame drop thresholds */ - SVC_LAYER_DROP_MODE - framedrop_mode; /**< Layer-based or constrained dropping. */ - int max_consec_drop; /**< Maximum consecutive drops, for any layer. */ -} vpx_svc_frame_drop_t; - -/*!\brief vp9 svc spatial layer sync parameters. - * - * This defines the spatial layer sync flag, defined per spatial layer. - * - */ -typedef struct vpx_svc_spatial_layer_sync { - int spatial_layer_sync[VPX_SS_MAX_LAYERS]; /**< Sync layer flags */ - int base_layer_intra_only; /**< Flag for setting Intra-only frame on base */ -} vpx_svc_spatial_layer_sync_t; - -/*!\cond */ -/*!\brief VP8 encoder control function parameter type - * - * Defines the data types that VP8E control functions take. Note that - * additional common controls are defined in vp8.h - * - */ - -VPX_CTRL_USE_TYPE(VP8E_SET_ROI_MAP, vpx_roi_map_t *) -#define VPX_CTRL_VP8E_SET_ROI_MAP -VPX_CTRL_USE_TYPE(VP8E_SET_ACTIVEMAP, vpx_active_map_t *) -#define VPX_CTRL_VP8E_SET_ACTIVEMAP -VPX_CTRL_USE_TYPE(VP8E_SET_SCALEMODE, vpx_scaling_mode_t *) -#define VPX_CTRL_VP8E_SET_SCALEMODE -VPX_CTRL_USE_TYPE(VP8E_SET_CPUUSED, int) -#define VPX_CTRL_VP8E_SET_CPUUSED -VPX_CTRL_USE_TYPE(VP8E_SET_ENABLEAUTOALTREF, unsigned int) -#define VPX_CTRL_VP8E_SET_ENABLEAUTOALTREF -VPX_CTRL_USE_TYPE(VP8E_SET_NOISE_SENSITIVITY, unsigned int) -#define VPX_CTRL_VP8E_SET_NOISE_SENSITIVITY -VPX_CTRL_USE_TYPE(VP8E_SET_SHARPNESS, unsigned int) -#define VPX_CTRL_VP8E_SET_SHARPNESS -VPX_CTRL_USE_TYPE(VP8E_SET_STATIC_THRESHOLD, unsigned int) -#define VPX_CTRL_VP8E_SET_STATIC_THRESHOLD -VPX_CTRL_USE_TYPE(VP8E_SET_TOKEN_PARTITIONS, int) /* vp8e_token_partitions */ -#define VPX_CTRL_VP8E_SET_TOKEN_PARTITIONS -VPX_CTRL_USE_TYPE(VP8E_GET_LAST_QUANTIZER, int *) -#define VPX_CTRL_VP8E_GET_LAST_QUANTIZER -VPX_CTRL_USE_TYPE(VP8E_GET_LAST_QUANTIZER_64, int *) -#define VPX_CTRL_VP8E_GET_LAST_QUANTIZER_64 -VPX_CTRL_USE_TYPE(VP8E_SET_ARNR_MAXFRAMES, unsigned int) -#define VPX_CTRL_VP8E_SET_ARNR_MAXFRAMES -VPX_CTRL_USE_TYPE(VP8E_SET_ARNR_STRENGTH, unsigned int) -#define VPX_CTRL_VP8E_SET_ARNR_STRENGTH -VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_SET_ARNR_TYPE, unsigned int) -#define VPX_CTRL_VP8E_SET_ARNR_TYPE -VPX_CTRL_USE_TYPE(VP8E_SET_TUNING, int) /* vp8e_tuning */ -#define VPX_CTRL_VP8E_SET_TUNING -VPX_CTRL_USE_TYPE(VP8E_SET_CQ_LEVEL, unsigned int) -#define VPX_CTRL_VP8E_SET_CQ_LEVEL -VPX_CTRL_USE_TYPE(VP8E_SET_MAX_INTRA_BITRATE_PCT, unsigned int) -#define VPX_CTRL_VP8E_SET_MAX_INTRA_BITRATE_PCT -VPX_CTRL_USE_TYPE(VP8E_SET_FRAME_FLAGS, int) -#define VPX_CTRL_VP8E_SET_FRAME_FLAGS -VPX_CTRL_USE_TYPE(VP9E_SET_MAX_INTER_BITRATE_PCT, unsigned int) -#define VPX_CTRL_VP9E_SET_MAX_INTER_BITRATE_PCT -VPX_CTRL_USE_TYPE(VP9E_SET_GF_CBR_BOOST_PCT, unsigned int) -#define VPX_CTRL_VP9E_SET_GF_CBR_BOOST_PCT -VPX_CTRL_USE_TYPE(VP8E_SET_TEMPORAL_LAYER_ID, int) -#define VPX_CTRL_VP8E_SET_TEMPORAL_LAYER_ID -VPX_CTRL_USE_TYPE(VP8E_SET_SCREEN_CONTENT_MODE, unsigned int) -#define VPX_CTRL_VP8E_SET_SCREEN_CONTENT_MODE -VPX_CTRL_USE_TYPE(VP9E_SET_LOSSLESS, unsigned int) -#define VPX_CTRL_VP9E_SET_LOSSLESS -VPX_CTRL_USE_TYPE(VP9E_SET_TILE_COLUMNS, int) -#define VPX_CTRL_VP9E_SET_TILE_COLUMNS -VPX_CTRL_USE_TYPE(VP9E_SET_TILE_ROWS, int) -#define VPX_CTRL_VP9E_SET_TILE_ROWS -VPX_CTRL_USE_TYPE(VP9E_SET_FRAME_PARALLEL_DECODING, unsigned int) -#define VPX_CTRL_VP9E_SET_FRAME_PARALLEL_DECODING -VPX_CTRL_USE_TYPE(VP9E_SET_AQ_MODE, unsigned int) -#define VPX_CTRL_VP9E_SET_AQ_MODE -VPX_CTRL_USE_TYPE(VP9E_SET_FRAME_PERIODIC_BOOST, unsigned int) -#define VPX_CTRL_VP9E_SET_FRAME_PERIODIC_BOOST -VPX_CTRL_USE_TYPE(VP9E_SET_NOISE_SENSITIVITY, unsigned int) -#define VPX_CTRL_VP9E_SET_NOISE_SENSITIVITY -VPX_CTRL_USE_TYPE(VP9E_SET_SVC, int) -#define VPX_CTRL_VP9E_SET_SVC -VPX_CTRL_USE_TYPE(VP9E_SET_ROI_MAP, vpx_roi_map_t *) -#define VPX_CTRL_VP9E_SET_ROI_MAP -VPX_CTRL_USE_TYPE(VP9E_SET_SVC_PARAMETERS, void *) -#define VPX_CTRL_VP9E_SET_SVC_PARAMETERS -VPX_CTRL_USE_TYPE(VP9E_SET_SVC_LAYER_ID, vpx_svc_layer_id_t *) -#define VPX_CTRL_VP9E_SET_SVC_LAYER_ID -VPX_CTRL_USE_TYPE(VP9E_SET_TUNE_CONTENT, int) /* vp9e_tune_content */ -#define VPX_CTRL_VP9E_SET_TUNE_CONTENT -VPX_CTRL_USE_TYPE(VP9E_GET_SVC_LAYER_ID, vpx_svc_layer_id_t *) -#define VPX_CTRL_VP9E_GET_SVC_LAYER_ID -VPX_CTRL_USE_TYPE(VP9E_REGISTER_CX_CALLBACK, void *) -#define VPX_CTRL_VP9E_REGISTER_CX_CALLBACK -VPX_CTRL_USE_TYPE(VP9E_SET_COLOR_SPACE, int) -#define VPX_CTRL_VP9E_SET_COLOR_SPACE -VPX_CTRL_USE_TYPE(VP9E_SET_MIN_GF_INTERVAL, unsigned int) -#define VPX_CTRL_VP9E_SET_MIN_GF_INTERVAL -VPX_CTRL_USE_TYPE(VP9E_SET_MAX_GF_INTERVAL, unsigned int) -#define VPX_CTRL_VP9E_SET_MAX_GF_INTERVAL -VPX_CTRL_USE_TYPE(VP9E_GET_ACTIVEMAP, vpx_active_map_t *) -#define VPX_CTRL_VP9E_GET_ACTIVEMAP -VPX_CTRL_USE_TYPE(VP9E_SET_COLOR_RANGE, int) -#define VPX_CTRL_VP9E_SET_COLOR_RANGE -VPX_CTRL_USE_TYPE(VP9E_SET_SVC_REF_FRAME_CONFIG, vpx_svc_ref_frame_config_t *) -#define VPX_CTRL_VP9E_SET_SVC_REF_FRAME_CONFIG -VPX_CTRL_USE_TYPE(VP9E_SET_RENDER_SIZE, int *) -#define VPX_CTRL_VP9E_SET_RENDER_SIZE -VPX_CTRL_USE_TYPE(VP9E_SET_TARGET_LEVEL, unsigned int) -#define VPX_CTRL_VP9E_SET_TARGET_LEVEL -VPX_CTRL_USE_TYPE(VP9E_SET_ROW_MT, unsigned int) -#define VPX_CTRL_VP9E_SET_ROW_MT -VPX_CTRL_USE_TYPE(VP9E_GET_LEVEL, int *) -#define VPX_CTRL_VP9E_GET_LEVEL -VPX_CTRL_USE_TYPE(VP9E_SET_ALT_REF_AQ, int) -#define VPX_CTRL_VP9E_SET_ALT_REF_AQ -VPX_CTRL_USE_TYPE(VP8E_SET_GF_CBR_BOOST_PCT, unsigned int) -#define VPX_CTRL_VP8E_SET_GF_CBR_BOOST_PCT -VPX_CTRL_USE_TYPE(VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, unsigned int) -#define VPX_CTRL_VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST -VPX_CTRL_USE_TYPE(VP9E_SET_SVC_INTER_LAYER_PRED, unsigned int) -#define VPX_CTRL_VP9E_SET_SVC_INTER_LAYER_PRED -VPX_CTRL_USE_TYPE(VP9E_SET_SVC_FRAME_DROP_LAYER, vpx_svc_frame_drop_t *) -#define VPX_CTRL_VP9E_SET_SVC_FRAME_DROP_LAYER -VPX_CTRL_USE_TYPE(VP9E_GET_SVC_REF_FRAME_CONFIG, vpx_svc_ref_frame_config_t *) -#define VPX_CTRL_VP9E_GET_SVC_REF_FRAME_CONFIG -VPX_CTRL_USE_TYPE(VP9E_SET_SVC_GF_TEMPORAL_REF, unsigned int) -#define VPX_CTRL_VP9E_SET_SVC_GF_TEMPORAL_REF -VPX_CTRL_USE_TYPE(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, - vpx_svc_spatial_layer_sync_t *) -#define VPX_CTRL_VP9E_SET_SVC_SPATIAL_LAYER_SYNC -VPX_CTRL_USE_TYPE(VP9E_SET_TPL, int) -#define VPX_CTRL_VP9E_SET_TPL -VPX_CTRL_USE_TYPE(VP9E_SET_POSTENCODE_DROP, unsigned int) -#define VPX_CTRL_VP9E_SET_POSTENCODE_DROP -VPX_CTRL_USE_TYPE(VP9E_SET_DELTA_Q_UV, int) -#define VPX_CTRL_VP9E_SET_DELTA_Q_UV -VPX_CTRL_USE_TYPE(VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, int) -#define VPX_CTRL_VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR -VPX_CTRL_USE_TYPE(VP9E_SET_DISABLE_LOOPFILTER, int) -#define VPX_CTRL_VP9E_SET_DISABLE_LOOPFILTER -VPX_CTRL_USE_TYPE(VP9E_SET_EXTERNAL_RATE_CONTROL, vpx_rc_funcs_t *) -#define VPX_CTRL_VP9E_SET_EXTERNAL_RATE_CONTROL -VPX_CTRL_USE_TYPE(VP9E_SET_RTC_EXTERNAL_RATECTRL, int) -#define VPX_CTRL_VP9E_SET_RTC_EXTERNAL_RATECTRL -VPX_CTRL_USE_TYPE(VP9E_GET_LOOPFILTER_LEVEL, int *) -#define VPX_CTRL_VP9E_GET_LOOPFILTER_LEVEL -VPX_CTRL_USE_TYPE(VP9E_GET_LAST_QUANTIZER_SVC_LAYERS, int *) -#define VPX_CTRL_VP9E_GET_LAST_QUANTIZER_SVC_LAYERS -VPX_CTRL_USE_TYPE(VP8E_SET_RTC_EXTERNAL_RATECTRL, int) -#define VPX_CTRL_VP8E_SET_RTC_EXTERNAL_RATECTRL -VPX_CTRL_USE_TYPE(VP9E_SET_QUANTIZER_ONE_PASS, int) -#define VPX_CTRL_VP9E_SET_QUANTIZER_ONE_PASS -VPX_CTRL_USE_TYPE(VP9E_SET_KEY_FRAME_FILTERING, int) -#define VPX_CTRL_VP9E_SET_KEY_FRAME_FILTERING - -/*!\endcond */ -/*! @} - end defgroup vp8_encoder */ -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_VP8CX_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/vp8dx.h b/presentation/src/main/cpp/third_party/libvpx/vpx/vp8dx.h deleted file mode 100644 index 8c13649f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/vp8dx.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/*!\defgroup vp8_decoder WebM VP8/VP9 Decoder - * \ingroup vp8 - * - * @{ - */ -/*!\file - * \brief Provides definitions for using VP8 or VP9 within the vpx Decoder - * interface. - */ -#ifndef VPX_VPX_VP8DX_H_ -#define VPX_VPX_VP8DX_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Include controls common to both the encoder and decoder */ -#include "./vp8.h" - -/*!\name Algorithm interface for VP8 - * - * This interface provides the capability to decode VP8 streams. - * @{ - */ - -/*!\brief A single instance of the VP8 decoder. - *\deprecated This access mechanism is provided for backwards compatibility; - * prefer vpx_codec_vp8_dx(). - */ -extern vpx_codec_iface_t vpx_codec_vp8_dx_algo; - -/*!\brief The interface to the VP8 decoder. - */ -extern vpx_codec_iface_t *vpx_codec_vp8_dx(void); -/*!@} - end algorithm interface member group*/ - -/*!\name Algorithm interface for VP9 - * - * This interface provides the capability to decode VP9 streams. - * @{ - */ - -/*!\brief A single instance of the VP9 decoder. - *\deprecated This access mechanism is provided for backwards compatibility; - * prefer vpx_codec_vp9_dx(). - */ -extern vpx_codec_iface_t vpx_codec_vp9_dx_algo; - -/*!\brief The interface to the VP9 decoder. - */ -extern vpx_codec_iface_t *vpx_codec_vp9_dx(void); -/*!@} - end algorithm interface member group*/ - -/*!\enum vp8_dec_control_id - * \brief VP8 decoder control functions - * - * This set of macros define the control functions available for the VP8 - * decoder interface. - * - * \sa #vpx_codec_control - */ -enum vp8_dec_control_id { - /** control function to get info on which reference frames were updated - * by the last decode - */ - VP8D_GET_LAST_REF_UPDATES = VP8_DECODER_CTRL_ID_START, - - /** check if the indicated frame is corrupted */ - VP8D_GET_FRAME_CORRUPTED, - - /** control function to get info on which reference frames were used - * by the last decode - */ - VP8D_GET_LAST_REF_USED, - - /** decryption function to decrypt encoded buffer data immediately - * before decoding. Takes a vpx_decrypt_init, which contains - * a callback function and opaque context pointer. - */ - VPXD_SET_DECRYPTOR, - VP8D_SET_DECRYPTOR = VPXD_SET_DECRYPTOR, - - /** control function to get the dimensions that the current frame is decoded - * at. This may be different to the intended display size for the frame as - * specified in the wrapper or frame header (see VP9D_GET_DISPLAY_SIZE). */ - VP9D_GET_FRAME_SIZE, - - /** control function to get the current frame's intended display dimensions - * (as specified in the wrapper or frame header). This may be different to - * the decoded dimensions of this frame (see VP9D_GET_FRAME_SIZE). */ - VP9D_GET_DISPLAY_SIZE, - - /** control function to get the bit depth of the stream. */ - VP9D_GET_BIT_DEPTH, - - /** control function to set the byte alignment of the planes in the reference - * buffers. Valid values are power of 2, from 32 to 1024. A value of 0 sets - * legacy alignment. I.e. Y plane is aligned to 32 bytes, U plane directly - * follows Y plane, and V plane directly follows U plane. Default value is 0. - */ - VP9_SET_BYTE_ALIGNMENT, - - /** control function to invert the decoding order to from right to left. The - * function is used in a test to confirm the decoding independence of tile - * columns. The function may be used in application where this order - * of decoding is desired. - * - * TODO(yaowu): Rework the unit test that uses this control, and in a future - * release, this test-only control shall be removed. - */ - VP9_INVERT_TILE_DECODE_ORDER, - - /** control function to set the skip loop filter flag. Valid values are - * integers. The decoder will skip the loop filter when its value is set to - * nonzero. If the loop filter is skipped the decoder may accumulate decode - * artifacts. The default value is 0. - */ - VP9_SET_SKIP_LOOP_FILTER, - - /** control function to decode SVC stream up to the x spatial layers, - * where x is passed in through the control, and is 0 for base layer. - */ - VP9_DECODE_SVC_SPATIAL_LAYER, - - /*!\brief Codec control function to get last decoded frame quantizer. - * - * Return value uses internal quantizer scale defined by the codec. - * - * Supported in codecs: VP8, VP9 - */ - VPXD_GET_LAST_QUANTIZER, - - /*!\brief Codec control function to set row level multi-threading. - * - * 0 : off, 1 : on - * - * Supported in codecs: VP9 - */ - VP9D_SET_ROW_MT, - - /*!\brief Codec control function to set loopfilter optimization. - * - * 0 : off, Loop filter is done after all tiles have been decoded - * 1 : on, Loop filter is done immediately after decode without - * waiting for all threads to sync. - * - * Supported in codecs: VP9 - */ - VP9D_SET_LOOP_FILTER_OPT, - - VP8_DECODER_CTRL_ID_MAX -}; - -/** Decrypt n bytes of data from input -> output, using the decrypt_state - * passed in VPXD_SET_DECRYPTOR. - */ -typedef void (*vpx_decrypt_cb)(void *decrypt_state, const unsigned char *input, - unsigned char *output, int count); - -/*!\brief Structure to hold decryption state - * - * Defines a structure to hold the decryption state and access function. - */ -typedef struct vpx_decrypt_init { - /*! Decrypt callback. */ - vpx_decrypt_cb decrypt_cb; - - /*! Decryption state. */ - void *decrypt_state; -} vpx_decrypt_init; - -/*!\cond */ -/*!\brief VP8 decoder control function parameter type - * - * Defines the data types that VP8D control functions take. Note that - * additional common controls are defined in vp8.h - * - */ - -VPX_CTRL_USE_TYPE(VP8D_GET_LAST_REF_UPDATES, int *) -#define VPX_CTRL_VP8D_GET_LAST_REF_UPDATES -VPX_CTRL_USE_TYPE(VP8D_GET_FRAME_CORRUPTED, int *) -#define VPX_CTRL_VP8D_GET_FRAME_CORRUPTED -VPX_CTRL_USE_TYPE(VP8D_GET_LAST_REF_USED, int *) -#define VPX_CTRL_VP8D_GET_LAST_REF_USED -VPX_CTRL_USE_TYPE(VPXD_SET_DECRYPTOR, vpx_decrypt_init *) -#define VPX_CTRL_VPXD_SET_DECRYPTOR -VPX_CTRL_USE_TYPE(VP8D_SET_DECRYPTOR, vpx_decrypt_init *) -#define VPX_CTRL_VP8D_SET_DECRYPTOR -VPX_CTRL_USE_TYPE(VP9D_GET_FRAME_SIZE, int *) -#define VPX_CTRL_VP9D_GET_FRAME_SIZE -VPX_CTRL_USE_TYPE(VP9D_GET_DISPLAY_SIZE, int *) -#define VPX_CTRL_VP9D_GET_DISPLAY_SIZE -VPX_CTRL_USE_TYPE(VP9D_GET_BIT_DEPTH, unsigned int *) -#define VPX_CTRL_VP9D_GET_BIT_DEPTH -VPX_CTRL_USE_TYPE(VP9_SET_BYTE_ALIGNMENT, int) -#define VPX_CTRL_VP9_SET_BYTE_ALIGNMENT -VPX_CTRL_USE_TYPE(VP9_INVERT_TILE_DECODE_ORDER, int) -#define VPX_CTRL_VP9_INVERT_TILE_DECODE_ORDER -VPX_CTRL_USE_TYPE(VP9_SET_SKIP_LOOP_FILTER, int) -#define VPX_CTRL_VP9_SET_SKIP_LOOP_FILTER -VPX_CTRL_USE_TYPE(VP9_DECODE_SVC_SPATIAL_LAYER, int) -#define VPX_CTRL_VP9_DECODE_SVC_SPATIAL_LAYER -VPX_CTRL_USE_TYPE(VPXD_GET_LAST_QUANTIZER, int *) -#define VPX_CTRL_VPXD_GET_LAST_QUANTIZER -VPX_CTRL_USE_TYPE(VP9D_SET_ROW_MT, int) -#define VPX_CTRL_VP9_DECODE_SET_ROW_MT -VPX_CTRL_USE_TYPE(VP9D_SET_LOOP_FILTER_OPT, int) -#define VPX_CTRL_VP9_SET_LOOP_FILTER_OPT - -/*!\endcond */ -/*! @} - end defgroup vp8_decoder */ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_VP8DX_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_codec.h b/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_codec.h deleted file mode 100644 index 60288977..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_codec.h +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/*!\defgroup codec Common Algorithm Interface - * This abstraction allows applications to easily support multiple video - * formats with minimal code duplication. This section describes the interface - * common to all codecs (both encoders and decoders). - * @{ - */ - -/*!\file - * \brief Describes the codec algorithm interface to applications. - * - * This file describes the interface between an application and a - * video codec algorithm. - * - * An application instantiates a specific codec instance by using - * vpx_codec_dec_init() or vpx_codec_enc_init() and a pointer to the - * algorithm's interface structure: - *
- *     my_app.c:
- *       extern vpx_codec_iface_t my_codec;
- *       {
- *           vpx_codec_ctx_t algo;
- *           int threads = 4;
- *           vpx_codec_dec_cfg_t cfg = { threads, 0, 0 };
- *           res = vpx_codec_dec_init(&algo, &my_codec, &cfg, 0);
- *       }
- *     
- * - * Once initialized, the instance is manged using other functions from - * the vpx_codec_* family. - */ -#ifndef VPX_VPX_VPX_CODEC_H_ -#define VPX_VPX_VPX_CODEC_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "./vpx_image.h" -#include "./vpx_integer.h" - -/*!\brief Decorator indicating a function is deprecated */ -#ifndef VPX_DEPRECATED -#if defined(__GNUC__) -#define VPX_DEPRECATED __attribute__((deprecated)) -#elif defined(_MSC_VER) -#define VPX_DEPRECATED -#else -#define VPX_DEPRECATED -#endif -#endif /* VPX_DEPRECATED */ - -#ifndef VPX_DECLSPEC_DEPRECATED -#if defined(__GNUC__) -#define VPX_DECLSPEC_DEPRECATED /**< \copydoc #VPX_DEPRECATED */ -#elif defined(_MSC_VER) -/*!\brief \copydoc #VPX_DEPRECATED */ -#define VPX_DECLSPEC_DEPRECATED __declspec(deprecated) -#else -#define VPX_DECLSPEC_DEPRECATED /**< \copydoc #VPX_DEPRECATED */ -#endif -#endif /* VPX_DECLSPEC_DEPRECATED */ - -/*!\brief Decorator indicating a function is potentially unused */ -#ifndef VPX_UNUSED -#if defined(__GNUC__) || defined(__clang__) -#define VPX_UNUSED __attribute__((unused)) -#else -#define VPX_UNUSED -#endif -#endif /* VPX_UNUSED */ - -/*!\brief Current ABI version number - * - * \internal - * If this file is altered in any way that changes the ABI, this value - * must be bumped. Examples include, but are not limited to, changing - * types, removing or reassigning enums, adding/removing/rearranging - * fields to structures - */ -#define VPX_CODEC_ABI_VERSION (4 + VPX_IMAGE_ABI_VERSION) /**<\hideinitializer*/ - -/*!\brief Algorithm return codes */ -typedef enum { - /*!\brief Operation completed without error */ - VPX_CODEC_OK, - - /*!\brief Unspecified error */ - VPX_CODEC_ERROR, - - /*!\brief Memory operation failed */ - VPX_CODEC_MEM_ERROR, - - /*!\brief ABI version mismatch */ - VPX_CODEC_ABI_MISMATCH, - - /*!\brief Algorithm does not have required capability */ - VPX_CODEC_INCAPABLE, - - /*!\brief The given bitstream is not supported. - * - * The bitstream was unable to be parsed at the highest level. The decoder - * is unable to proceed. This error \ref SHOULD be treated as fatal to the - * stream. */ - VPX_CODEC_UNSUP_BITSTREAM, - - /*!\brief Encoded bitstream uses an unsupported feature - * - * The decoder does not implement a feature required by the encoder. This - * return code should only be used for features that prevent future - * pictures from being properly decoded. This error \ref MAY be treated as - * fatal to the stream or \ref MAY be treated as fatal to the current GOP. - */ - VPX_CODEC_UNSUP_FEATURE, - - /*!\brief The coded data for this stream is corrupt or incomplete - * - * There was a problem decoding the current frame. This return code - * should only be used for failures that prevent future pictures from - * being properly decoded. This error \ref MAY be treated as fatal to the - * stream or \ref MAY be treated as fatal to the current GOP. If decoding - * is continued for the current GOP, artifacts may be present. - */ - VPX_CODEC_CORRUPT_FRAME, - - /*!\brief An application-supplied parameter is not valid. - * - */ - VPX_CODEC_INVALID_PARAM, - - /*!\brief An iterator reached the end of list. - * - */ - VPX_CODEC_LIST_END - -} vpx_codec_err_t; - -/*! \brief Codec capabilities bitfield - * - * Each codec advertises the capabilities it supports as part of its - * ::vpx_codec_iface_t interface structure. Capabilities are extra interfaces - * or functionality, and are not required to be supported. - * - * The available flags are specified by VPX_CODEC_CAP_* defines. - */ -typedef long vpx_codec_caps_t; -#define VPX_CODEC_CAP_DECODER 0x1 /**< Is a decoder */ -#define VPX_CODEC_CAP_ENCODER 0x2 /**< Is an encoder */ - -/*! Can support images at greater than 8 bitdepth. - */ -#define VPX_CODEC_CAP_HIGHBITDEPTH 0x4 - -/*! \brief Initialization-time Feature Enabling - * - * Certain codec features must be known at initialization time, to allow for - * proper memory allocation. - * - * The available flags are specified by VPX_CODEC_USE_* defines. - */ -typedef long vpx_codec_flags_t; - -/*!\brief Codec interface structure. - * - * Contains function pointers and other data private to the codec - * implementation. This structure is opaque to the application. - */ -typedef const struct vpx_codec_iface vpx_codec_iface_t; - -/*!\brief Codec private data structure. - * - * Contains data private to the codec implementation. This structure is opaque - * to the application. - */ -typedef struct vpx_codec_priv vpx_codec_priv_t; - -/*!\brief Iterator - * - * Opaque storage used for iterating over lists. - */ -typedef const void *vpx_codec_iter_t; - -/*!\brief Codec context structure - * - * All codecs \ref MUST support this context structure fully. In general, - * this data should be considered private to the codec algorithm, and - * not be manipulated or examined by the calling application. Applications - * may reference the 'name' member to get a printable description of the - * algorithm. - */ -typedef struct vpx_codec_ctx { - const char *name; /**< Printable interface name */ - vpx_codec_iface_t *iface; /**< Interface pointers */ - vpx_codec_err_t err; /**< Last returned error */ - const char *err_detail; /**< Detailed info, if available */ - vpx_codec_flags_t init_flags; /**< Flags passed at init time */ - union { - /**< Decoder Configuration Pointer */ - const struct vpx_codec_dec_cfg *dec; - /**< Encoder Configuration Pointer */ - const struct vpx_codec_enc_cfg *enc; - const void *raw; - } config; /**< Configuration pointer aliasing union */ - vpx_codec_priv_t *priv; /**< Algorithm private storage */ -} vpx_codec_ctx_t; - -/*!\brief Bit depth for codec - * * - * This enumeration determines the bit depth of the codec. - */ -typedef enum vpx_bit_depth { - VPX_BITS_8 = 8, /**< 8 bits */ - VPX_BITS_10 = 10, /**< 10 bits */ - VPX_BITS_12 = 12, /**< 12 bits */ -} vpx_bit_depth_t; - -/* - * Library Version Number Interface - * - * For example, see the following sample return values: - * vpx_codec_version() (1<<16 | 2<<8 | 3) - * vpx_codec_version_str() "v1.2.3-rc1-16-gec6a1ba" - * vpx_codec_version_extra_str() "rc1-16-gec6a1ba" - */ - -/*!\brief Return the version information (as an integer) - * - * Returns a packed encoding of the library version number. This will only - * include - * the major.minor.patch component of the version number. Note that this encoded - * value should be accessed through the macros provided, as the encoding may - * change - * in the future. - * - */ -int vpx_codec_version(void); -#define VPX_VERSION_MAJOR(v) \ - (((v) >> 16) & 0xff) /**< extract major from packed version */ -#define VPX_VERSION_MINOR(v) \ - (((v) >> 8) & 0xff) /**< extract minor from packed version */ -#define VPX_VERSION_PATCH(v) \ - (((v) >> 0) & 0xff) /**< extract patch from packed version */ - -/*!\brief Return the version major number */ -#define vpx_codec_version_major() ((vpx_codec_version() >> 16) & 0xff) - -/*!\brief Return the version minor number */ -#define vpx_codec_version_minor() ((vpx_codec_version() >> 8) & 0xff) - -/*!\brief Return the version patch number */ -#define vpx_codec_version_patch() ((vpx_codec_version() >> 0) & 0xff) - -/*!\brief Return the version information (as a string) - * - * Returns a printable string containing the full library version number. This - * may - * contain additional text following the three digit version number, as to - * indicate - * release candidates, prerelease versions, etc. - * - */ -const char *vpx_codec_version_str(void); - -/*!\brief Return the version information (as a string) - * - * Returns a printable "extra string". This is the component of the string - * returned - * by vpx_codec_version_str() following the three digit version number. - * - */ -const char *vpx_codec_version_extra_str(void); - -/*!\brief Return the build configuration - * - * Returns a printable string containing an encoded version of the build - * configuration. This may be useful to vpx support. - * - */ -const char *vpx_codec_build_config(void); - -/*!\brief Return the name for a given interface - * - * Returns a human readable string for name of the given codec interface. - * - * \param[in] iface Interface pointer - * - */ -const char *vpx_codec_iface_name(vpx_codec_iface_t *iface); - -/*!\brief Convert error number to printable string - * - * Returns a human readable string for the last error returned by the - * algorithm. The returned error will be one line and will not contain - * any newline characters. - * - * - * \param[in] err Error number. - * - */ -const char *vpx_codec_err_to_string(vpx_codec_err_t err); - -/*!\brief Retrieve error synopsis for codec context - * - * Returns a human readable string for the last error returned by the - * algorithm. The returned error will be one line and will not contain - * any newline characters. - * - * - * \param[in] ctx Pointer to this instance's context. - * - */ -const char *vpx_codec_error(const vpx_codec_ctx_t *ctx); - -/*!\brief Retrieve detailed error information for codec context - * - * Returns a human readable string providing detailed information about - * the last error. The returned string is only valid until the next - * vpx_codec_* function call (except vpx_codec_error and - * vpx_codec_error_detail) on the codec context. - * - * \param[in] ctx Pointer to this instance's context. - * - * \retval NULL - * No detailed information is available. - */ -const char *vpx_codec_error_detail(const vpx_codec_ctx_t *ctx); - -/* REQUIRED FUNCTIONS - * - * The following functions are required to be implemented for all codecs. - * They represent the base case functionality expected of all codecs. - */ - -/*!\brief Destroy a codec instance - * - * Destroys a codec context, freeing any associated memory buffers. - * - * \param[in] ctx Pointer to this instance's context - * - * \retval #VPX_CODEC_OK - * The codec instance has been destroyed. - * \retval #VPX_CODEC_INVALID_PARAM - * ctx is a null pointer. - * \retval #VPX_CODEC_ERROR - * Codec context not initialized. - */ -vpx_codec_err_t vpx_codec_destroy(vpx_codec_ctx_t *ctx); - -/*!\brief Get the capabilities of an algorithm. - * - * Retrieves the capabilities bitfield from the algorithm's interface. - * - * \param[in] iface Pointer to the algorithm interface - * - */ -vpx_codec_caps_t vpx_codec_get_caps(vpx_codec_iface_t *iface); - -/*!\brief Control algorithm - * - * This function is used to exchange algorithm specific data with the codec - * instance. This can be used to implement features specific to a particular - * algorithm. - * - * This wrapper function dispatches the request to the helper function - * associated with the given ctrl_id. It tries to call this function - * transparently, but will return #VPX_CODEC_ERROR if the request could not - * be dispatched. - * - * Note that this function should not be used directly. Call the - * #vpx_codec_control wrapper macro instead. - * - * \param[in] ctx Pointer to this instance's context - * \param[in] ctrl_id Algorithm specific control identifier - * - * \retval #VPX_CODEC_OK - * The control request was processed. - * \retval #VPX_CODEC_ERROR - * The control request was not processed. - * \retval #VPX_CODEC_INVALID_PARAM - * The data was not valid. - */ -vpx_codec_err_t vpx_codec_control_(vpx_codec_ctx_t *ctx, int ctrl_id, ...); -#if defined(VPX_DISABLE_CTRL_TYPECHECKS) && VPX_DISABLE_CTRL_TYPECHECKS -#define vpx_codec_control(ctx, id, data) vpx_codec_control_(ctx, id, data) -#define VPX_CTRL_USE_TYPE(id, typ) -#define VPX_CTRL_USE_TYPE_DEPRECATED(id, typ) -#define VPX_CTRL_VOID(id, typ) - -#else -/*!\brief vpx_codec_control wrapper macro - * - * This macro allows for type safe conversions across the variadic parameter - * to vpx_codec_control_(). - * - * \internal - * It works by dispatching the call to the control function through a wrapper - * function named with the id parameter. - */ -#define vpx_codec_control(ctx, id, data) \ - vpx_codec_control_##id(ctx, id, data) /**<\hideinitializer*/ - -/*!\brief vpx_codec_control type definition macro - * - * This macro allows for type safe conversions across the variadic parameter - * to vpx_codec_control_(). It defines the type of the argument for a given - * control identifier. - * - * \internal - * It defines a static function with - * the correctly typed arguments as a wrapper to the type-unsafe internal - * function. - */ -#define VPX_CTRL_USE_TYPE(id, typ) \ - static vpx_codec_err_t vpx_codec_control_##id(vpx_codec_ctx_t *, int, typ) \ - VPX_UNUSED; \ - \ - static vpx_codec_err_t vpx_codec_control_##id(vpx_codec_ctx_t *ctx, \ - int ctrl_id, typ data) { \ - return vpx_codec_control_(ctx, ctrl_id, data); \ - } /**<\hideinitializer*/ - -/*!\brief vpx_codec_control deprecated type definition macro - * - * Like #VPX_CTRL_USE_TYPE, but indicates that the specified control is - * deprecated and should not be used. Consult the documentation for your - * codec for more information. - * - * \internal - * It defines a static function with the correctly typed arguments as a - * wrapper to the type-unsafe internal function. - */ -#define VPX_CTRL_USE_TYPE_DEPRECATED(id, typ) \ - VPX_DECLSPEC_DEPRECATED static vpx_codec_err_t vpx_codec_control_##id( \ - vpx_codec_ctx_t *, int, typ) VPX_DEPRECATED VPX_UNUSED; \ - \ - VPX_DECLSPEC_DEPRECATED static vpx_codec_err_t vpx_codec_control_##id( \ - vpx_codec_ctx_t *ctx, int ctrl_id, typ data) { \ - return vpx_codec_control_(ctx, ctrl_id, data); \ - } /**<\hideinitializer*/ - -/*!\brief vpx_codec_control void type definition macro - * - * This macro allows for type safe conversions across the variadic parameter - * to vpx_codec_control_(). It indicates that a given control identifier takes - * no argument. - * - * \internal - * It defines a static function without a data argument as a wrapper to the - * type-unsafe internal function. - */ -#define VPX_CTRL_VOID(id) \ - static vpx_codec_err_t vpx_codec_control_##id(vpx_codec_ctx_t *, int) \ - VPX_UNUSED; \ - \ - static vpx_codec_err_t vpx_codec_control_##id(vpx_codec_ctx_t *ctx, \ - int ctrl_id) { \ - return vpx_codec_control_(ctx, ctrl_id); \ - } /**<\hideinitializer*/ - -#endif - -/*!@} - end defgroup codec*/ -#ifdef __cplusplus -} -#endif -#endif // VPX_VPX_VPX_CODEC_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_codec.mk b/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_codec.mk deleted file mode 100644 index 778f1a61..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_codec.mk +++ /dev/null @@ -1,46 +0,0 @@ -## -## Copyright (c) 2010 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - - -API_EXPORTS += exports - -API_SRCS-$(CONFIG_VP8_ENCODER) += vp8.h -API_SRCS-$(CONFIG_VP8_ENCODER) += vp8cx.h -API_DOC_SRCS-$(CONFIG_VP8_ENCODER) += vp8.h -API_DOC_SRCS-$(CONFIG_VP8_ENCODER) += vp8cx.h - -API_SRCS-$(CONFIG_VP8_DECODER) += vp8.h -API_SRCS-$(CONFIG_VP8_DECODER) += vp8dx.h -API_DOC_SRCS-$(CONFIG_VP8_DECODER) += vp8.h -API_DOC_SRCS-$(CONFIG_VP8_DECODER) += vp8dx.h - -API_DOC_SRCS-yes += vpx_codec.h -API_DOC_SRCS-yes += vpx_decoder.h -API_DOC_SRCS-yes += vpx_encoder.h -API_DOC_SRCS-$(CONFIG_ENCODERS) += vpx_ext_ratectrl.h -API_DOC_SRCS-yes += vpx_frame_buffer.h -API_DOC_SRCS-yes += vpx_image.h -API_DOC_SRCS-$(CONFIG_ENCODERS) += vpx_tpl.h - -API_SRCS-yes += src/vpx_decoder.c -API_SRCS-yes += vpx_decoder.h -API_SRCS-yes += src/vpx_encoder.c -API_SRCS-yes += vpx_encoder.h -API_SRCS-yes += internal/vpx_codec_internal.h -API_SRCS-yes += internal/vpx_ratectrl_rtc.h -API_SRCS-yes += src/vpx_codec.c -API_SRCS-yes += src/vpx_image.c -API_SRCS-yes += vpx_codec.h -API_SRCS-yes += vpx_codec.mk -API_SRCS-yes += vpx_frame_buffer.h -API_SRCS-yes += vpx_image.h -API_SRCS-yes += vpx_integer.h -API_SRCS-yes += vpx_ext_ratectrl.h -API_SRCS-yes += vpx_tpl.h diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_decoder.h b/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_decoder.h deleted file mode 100644 index e2c31ea7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_decoder.h +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_VPX_VPX_DECODER_H_ -#define VPX_VPX_VPX_DECODER_H_ - -/*!\defgroup decoder Decoder Algorithm Interface - * \ingroup codec - * This abstraction allows applications using this decoder to easily support - * multiple video formats with minimal code duplication. This section describes - * the interface common to all decoders. - * @{ - */ - -/*!\file - * \brief Describes the decoder algorithm interface to applications. - * - * This file describes the interface between an application and a - * video decoder algorithm. - * - */ -#ifdef __cplusplus -extern "C" { -#endif - -#include "./vpx_codec.h" // IWYU pragma: export -#include "./vpx_frame_buffer.h" - -/*!\brief Current ABI version number - * - * \internal - * If this file is altered in any way that changes the ABI, this value - * must be bumped. Examples include, but are not limited to, changing - * types, removing or reassigning enums, adding/removing/rearranging - * fields to structures - */ -#define VPX_DECODER_ABI_VERSION \ - (3 + VPX_CODEC_ABI_VERSION) /**<\hideinitializer*/ - -/*! \brief Decoder capabilities bitfield - * - * Each decoder advertises the capabilities it supports as part of its - * ::vpx_codec_iface_t interface structure. Capabilities are extra interfaces - * or functionality, and are not required to be supported by a decoder. - * - * The available flags are specified by VPX_CODEC_CAP_* defines. - */ -#define VPX_CODEC_CAP_PUT_SLICE 0x10000 /**< Will issue put_slice callbacks */ -#define VPX_CODEC_CAP_PUT_FRAME 0x20000 /**< Will issue put_frame callbacks */ -#define VPX_CODEC_CAP_POSTPROC 0x40000 /**< Can postprocess decoded frame */ -/*!\brief Can conceal errors due to packet loss */ -#define VPX_CODEC_CAP_ERROR_CONCEALMENT 0x80000 -/*!\brief Can receive encoded frames one fragment at a time */ -#define VPX_CODEC_CAP_INPUT_FRAGMENTS 0x100000 -/*!\brief Can support frame-based multi-threading */ -#define VPX_CODEC_CAP_FRAME_THREADING 0x200000 -/*!brief Can support external frame buffers */ -#define VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER 0x400000 - -/*! \brief Initialization-time Feature Enabling - * - * Certain codec features must be known at initialization time, to allow for - * proper memory allocation. - * - * The available flags are specified by VPX_CODEC_USE_* defines. - */ -#define VPX_CODEC_USE_POSTPROC 0x10000 /**< Postprocess decoded frame */ -/*!\brief Conceal errors in decoded frames */ -#define VPX_CODEC_USE_ERROR_CONCEALMENT 0x20000 -/*!\brief The input frame should be passed to the decoder one fragment at a - * time */ -#define VPX_CODEC_USE_INPUT_FRAGMENTS 0x40000 -/*!\brief Enable frame-based multi-threading */ -#define VPX_CODEC_USE_FRAME_THREADING 0x80000 - -/*!\brief Stream properties - * - * This structure is used to query or set properties of the decoded - * stream. Algorithms may extend this structure with data specific - * to their bitstream by setting the sz member appropriately. - */ -typedef struct vpx_codec_stream_info { - unsigned int sz; /**< Size of this structure */ - unsigned int w; /**< Width (or 0 for unknown/default) */ - unsigned int h; /**< Height (or 0 for unknown/default) */ - unsigned int is_kf; /**< Current frame is a keyframe */ -} vpx_codec_stream_info_t; - -/* REQUIRED FUNCTIONS - * - * The following functions are required to be implemented for all decoders. - * They represent the base case functionality expected of all decoders. - */ - -/*!\brief Initialization Configurations - * - * This structure is used to pass init time configuration options to the - * decoder. - */ -typedef struct vpx_codec_dec_cfg { - unsigned int threads; /**< Maximum number of threads to use, default 1 */ - unsigned int w; /**< Width */ - unsigned int h; /**< Height */ -} vpx_codec_dec_cfg_t; /**< alias for struct vpx_codec_dec_cfg */ - -/*!\brief Initialize a decoder instance - * - * Initializes a decoder context using the given interface. Applications - * should call the vpx_codec_dec_init convenience macro instead of this - * function directly, to ensure that the ABI version number parameter - * is properly initialized. - * - * If the library was configured with --disable-multithread, this call - * is not thread safe and should be guarded with a lock if being used - * in a multithreaded context. - * - * \param[in] ctx Pointer to this instance's context. - * \param[in] iface Pointer to the algorithm interface to use. - * \param[in] cfg Configuration to use, if known. May be NULL. - * \param[in] flags Bitfield of VPX_CODEC_USE_* flags - * \param[in] ver ABI version number. Must be set to - * VPX_DECODER_ABI_VERSION - * \retval #VPX_CODEC_OK - * The decoder algorithm has been initialized. - * \retval #VPX_CODEC_MEM_ERROR - * Memory allocation failed. - */ -vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t *ctx, - vpx_codec_iface_t *iface, - const vpx_codec_dec_cfg_t *cfg, - vpx_codec_flags_t flags, int ver); - -/*!\brief Convenience macro for vpx_codec_dec_init_ver() - * - * Ensures the ABI version parameter is properly set. - */ -#define vpx_codec_dec_init(ctx, iface, cfg, flags) \ - vpx_codec_dec_init_ver(ctx, iface, cfg, flags, VPX_DECODER_ABI_VERSION) - -/*!\brief Parse stream info from a buffer - * - * Performs high level parsing of the bitstream. Construction of a decoder - * context is not necessary. Can be used to determine if the bitstream is - * of the proper format, and to extract information from the stream. - * - * \param[in] iface Pointer to the algorithm interface - * \param[in] data Pointer to a block of data to parse - * \param[in] data_sz Size of the data buffer - * \param[in,out] si Pointer to stream info to update. The sz member - * \ref MUST be properly initialized, but \ref MAY be - * clobbered by the algorithm. This parameter \ref MAY - * be NULL. - * - * \retval #VPX_CODEC_OK - * Bitstream is parsable and stream information updated - */ -vpx_codec_err_t vpx_codec_peek_stream_info(vpx_codec_iface_t *iface, - const uint8_t *data, - unsigned int data_sz, - vpx_codec_stream_info_t *si); - -/*!\brief Return information about the current stream. - * - * Returns information about the stream that has been parsed during decoding. - * - * \param[in] ctx Pointer to this instance's context - * \param[in,out] si Pointer to stream info to update. The sz member - * \ref MUST be properly initialized, but \ref MAY be - * clobbered by the algorithm. This parameter \ref MAY - * be NULL. - * - * \retval #VPX_CODEC_OK - * Bitstream is parsable and stream information updated - */ -vpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t *ctx, - vpx_codec_stream_info_t *si); - -/*!\brief Decode data - * - * Processes a buffer of coded data. If the processing results in a new - * decoded frame becoming available, put_slice and put_frame callbacks may be - * invoked, as appropriate. Encoded data \ref MUST be passed in DTS (decode - * time stamp) order. Frames produced will always be in PTS (presentation - * time stamp) order. - * If the decoder is configured with VPX_CODEC_USE_INPUT_FRAGMENTS enabled, - * data and data_sz can contain a fragment of the encoded frame. Fragment - * \#n must contain at least partition \#n, but can also contain subsequent - * partitions (\#n+1 - \#n+i), and if so, fragments \#n+1, .., \#n+i must - * be empty. When no more data is available, this function should be called - * with NULL as data and 0 as data_sz. The memory passed to this function - * must be available until the frame has been decoded. - * - * \param[in] ctx Pointer to this instance's context - * \param[in] data Pointer to this block of new coded data. If - * NULL, the put_frame callback is invoked for - * the previously decoded frame. - * \param[in] data_sz Size of the coded data, in bytes. - * \param[in] user_priv Application specific data to associate with - * this frame. - * \param[in] deadline Soft deadline the decoder should attempt to meet, - * in us. Set to zero for unlimited. - * NOTE: The deadline parameter is ignored. Always - * pass 0. - * - * \return Returns #VPX_CODEC_OK if the coded data was processed completely - * and future pictures can be decoded without error. Otherwise, - * see the descriptions of the other error codes in ::vpx_codec_err_t - * for recoverability capabilities. - */ -vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t *ctx, const uint8_t *data, - unsigned int data_sz, void *user_priv, - long deadline); - -/*!\brief Decoded frames iterator - * - * Iterates over a list of the frames available for display. The iterator - * storage should be initialized to NULL to start the iteration. Iteration is - * complete when this function returns NULL. - * - * The list of available frames becomes valid upon completion of the - * vpx_codec_decode call, and remains valid until the next call to - * vpx_codec_decode. - * - * \param[in] ctx Pointer to this instance's context - * \param[in,out] iter Iterator storage, initialized to NULL - * - * \return Returns a pointer to an image, if one is ready for display. Frames - * produced will always be in PTS (presentation time stamp) order. - */ -vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t *ctx, vpx_codec_iter_t *iter); - -/*!\defgroup cap_put_frame Frame-Based Decoding Functions - * - * The following function is required to be implemented for all decoders - * that advertise the VPX_CODEC_CAP_PUT_FRAME capability. Calling this - * function for codecs that don't advertise this capability will result in - * an error code being returned, usually VPX_CODEC_INCAPABLE. - * @{ - */ - -/*!\brief put frame callback prototype - * - * This callback is invoked by the decoder to notify the application of - * the availability of decoded image data. - */ -typedef void (*vpx_codec_put_frame_cb_fn_t)(void *user_priv, - const vpx_image_t *img); - -/*!\brief Register for notification of frame completion. - * - * Registers a given function to be called when a decoded frame is - * available. - * - * \param[in] ctx Pointer to this instance's context - * \param[in] cb Pointer to the callback function - * \param[in] user_priv User's private data - * - * \retval #VPX_CODEC_OK - * Callback successfully registered. - * \retval #VPX_CODEC_ERROR - * Decoder context not initialized. - * \retval #VPX_CODEC_INCAPABLE - * Algorithm not capable of posting frame completion. - */ -vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t *ctx, - vpx_codec_put_frame_cb_fn_t cb, - void *user_priv); - -/*!@} - end defgroup cap_put_frame */ - -/*!\defgroup cap_put_slice Slice-Based Decoding Functions - * - * The following function is required to be implemented for all decoders - * that advertise the VPX_CODEC_CAP_PUT_SLICE capability. Calling this - * function for codecs that don't advertise this capability will result in - * an error code being returned, usually VPX_CODEC_INCAPABLE. - * @{ - */ - -/*!\brief put slice callback prototype - * - * This callback is invoked by the decoder to notify the application of - * the availability of partially decoded image data. - */ -typedef void (*vpx_codec_put_slice_cb_fn_t)(void *user_priv, - const vpx_image_t *img, - const vpx_image_rect_t *valid, - const vpx_image_rect_t *update); - -/*!\brief Register for notification of slice completion. - * - * Registers a given function to be called when a decoded slice is - * available. - * - * \param[in] ctx Pointer to this instance's context - * \param[in] cb Pointer to the callback function - * \param[in] user_priv User's private data - * - * \retval #VPX_CODEC_OK - * Callback successfully registered. - * \retval #VPX_CODEC_ERROR - * Decoder context not initialized. - * \retval #VPX_CODEC_INCAPABLE - * Algorithm not capable of posting slice completion. - */ -vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t *ctx, - vpx_codec_put_slice_cb_fn_t cb, - void *user_priv); - -/*!@} - end defgroup cap_put_slice*/ - -/*!\defgroup cap_external_frame_buffer External Frame Buffer Functions - * - * The following function is required to be implemented for all decoders - * that advertise the VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER capability. - * Calling this function for codecs that don't advertise this capability - * will result in an error code being returned, usually VPX_CODEC_INCAPABLE. - * - * \note - * Currently this only works with VP9. - * @{ - */ - -/*!\brief Pass in external frame buffers for the decoder to use. - * - * Registers functions to be called when libvpx needs a frame buffer - * to decode the current frame and a function to be called when libvpx does - * not internally reference the frame buffer. This set function must - * be called before the first call to decode or libvpx will assume the - * default behavior of allocating frame buffers internally. - * - * \param[in] ctx Pointer to this instance's context - * \param[in] cb_get Pointer to the get callback function - * \param[in] cb_release Pointer to the release callback function - * \param[in] cb_priv Callback's private data - * - * \retval #VPX_CODEC_OK - * External frame buffers will be used by libvpx. - * \retval #VPX_CODEC_INVALID_PARAM - * One or more of the callbacks were NULL. - * \retval #VPX_CODEC_ERROR - * Decoder context not initialized. - * \retval #VPX_CODEC_INCAPABLE - * Algorithm not capable of using external frame buffers. - * - * \note - * When decoding VP9, the application may be required to pass in at least - * #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS external frame - * buffers. - */ -vpx_codec_err_t vpx_codec_set_frame_buffer_functions( - vpx_codec_ctx_t *ctx, vpx_get_frame_buffer_cb_fn_t cb_get, - vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv); - -/*!@} - end defgroup cap_external_frame_buffer */ - -/*!@} - end defgroup decoder*/ -#ifdef __cplusplus -} -#endif -#endif // VPX_VPX_VPX_DECODER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_encoder.h b/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_encoder.h deleted file mode 100644 index 501723b4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_encoder.h +++ /dev/null @@ -1,1150 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_VPX_VPX_ENCODER_H_ -#define VPX_VPX_VPX_ENCODER_H_ - -/*!\defgroup encoder Encoder Algorithm Interface - * \ingroup codec - * This abstraction allows applications using this encoder to easily support - * multiple video formats with minimal code duplication. This section describes - * the interface common to all encoders. - * @{ - */ - -/*!\file - * \brief Describes the encoder algorithm interface to applications. - * - * This file describes the interface between an application and a - * video encoder algorithm. - * - */ -#ifdef __cplusplus -extern "C" { -#endif - -#include "./vpx_codec.h" // IWYU pragma: export -#include "./vpx_ext_ratectrl.h" - -/*! Temporal Scalability: Maximum length of the sequence defining frame - * layer membership - */ -#define VPX_TS_MAX_PERIODICITY 16 - -/*! Temporal Scalability: Maximum number of coding layers */ -#define VPX_TS_MAX_LAYERS 5 - -/*! Temporal+Spatial Scalability: Maximum number of coding layers */ -#define VPX_MAX_LAYERS 12 // 3 temporal + 4 spatial layers are allowed. - -/*! Spatial Scalability: Maximum number of coding layers */ -#define VPX_SS_MAX_LAYERS 5 - -/*! Spatial Scalability: Default number of coding layers */ -#define VPX_SS_DEFAULT_LAYERS 1 - -/*!\brief Current ABI version number - * - * \internal - * If this file is altered in any way that changes the ABI, this value - * must be bumped. Examples include, but are not limited to, changing - * types, removing or reassigning enums, adding/removing/rearranging - * fields to structures - * - * \note - * VPX_ENCODER_ABI_VERSION has a VPX_EXT_RATECTRL_ABI_VERSION component - * because the VP9E_SET_EXTERNAL_RATE_CONTROL codec control uses - * vpx_rc_funcs_t. - */ -#define VPX_ENCODER_ABI_VERSION \ - (18 + VPX_CODEC_ABI_VERSION + \ - VPX_EXT_RATECTRL_ABI_VERSION) /**<\hideinitializer*/ - -/*! \brief Encoder capabilities bitfield - * - * Each encoder advertises the capabilities it supports as part of its - * ::vpx_codec_iface_t interface structure. Capabilities are extra - * interfaces or functionality, and are not required to be supported - * by an encoder. - * - * The available flags are specified by VPX_CODEC_CAP_* defines. - */ -#define VPX_CODEC_CAP_PSNR 0x10000 /**< Can issue PSNR packets */ - -/*! Can output one partition at a time. Each partition is returned in its - * own VPX_CODEC_CX_FRAME_PKT, with the FRAME_IS_FRAGMENT flag set for - * every partition but the last. In this mode all frames are always - * returned partition by partition. - */ -#define VPX_CODEC_CAP_OUTPUT_PARTITION 0x20000 - -/*! \brief Initialization-time Feature Enabling - * - * Certain codec features must be known at initialization time, to allow - * for proper memory allocation. - * - * The available flags are specified by VPX_CODEC_USE_* defines. - */ -#define VPX_CODEC_USE_PSNR 0x10000 /**< Calculate PSNR on each frame */ -/*!\brief Make the encoder output one partition at a time. */ -#define VPX_CODEC_USE_OUTPUT_PARTITION 0x20000 -#define VPX_CODEC_USE_HIGHBITDEPTH 0x40000 /**< Use high bitdepth */ - -/*!\brief Generic fixed size buffer structure - * - * This structure is able to hold a reference to any fixed size buffer. - */ -typedef struct vpx_fixed_buf { - void *buf; /**< Pointer to the data */ - size_t sz; /**< Length of the buffer, in chars */ -} vpx_fixed_buf_t; /**< alias for struct vpx_fixed_buf */ - -/*!\brief Time Stamp Type - * - * An integer, which when multiplied by the stream's time base, provides - * the absolute time of a sample. - */ -typedef int64_t vpx_codec_pts_t; - -/*!\brief Compressed Frame Flags - * - * This type represents a bitfield containing information about a compressed - * frame that may be useful to an application. The most significant 16 bits - * can be used by an algorithm to provide additional detail, for example to - * support frame types that are codec specific (MPEG-1 D-frames for example) - */ -typedef uint32_t vpx_codec_frame_flags_t; -#define VPX_FRAME_IS_KEY 0x1u /**< frame is the start of a GOP */ -/*!\brief frame can be dropped without affecting the stream (no future frame - * depends on this one) */ -#define VPX_FRAME_IS_DROPPABLE 0x2u -/*!\brief frame should be decoded but will not be shown */ -#define VPX_FRAME_IS_INVISIBLE 0x4u -/*!\brief this is a fragment of the encoded frame */ -#define VPX_FRAME_IS_FRAGMENT 0x8u - -/*!\brief Error Resilient flags - * - * These flags define which error resilient features to enable in the - * encoder. The flags are specified through the - * vpx_codec_enc_cfg::g_error_resilient variable. - */ -typedef uint32_t vpx_codec_er_flags_t; -/*!\brief Improve resiliency against losses of whole frames */ -#define VPX_ERROR_RESILIENT_DEFAULT 0x1u -/*!\brief The frame partitions are independently decodable by the bool decoder, - * meaning that partitions can be decoded even though earlier partitions have - * been lost. Note that intra prediction is still done over the partition - * boundary. - * \note This is only supported by VP8.*/ -#define VPX_ERROR_RESILIENT_PARTITIONS 0x2u - -/*!\brief Encoder output packet variants - * - * This enumeration lists the different kinds of data packets that can be - * returned by calls to vpx_codec_get_cx_data(). Algorithms \ref MAY - * extend this list to provide additional functionality. - */ -enum vpx_codec_cx_pkt_kind { - VPX_CODEC_CX_FRAME_PKT, /**< Compressed video frame */ - VPX_CODEC_STATS_PKT, /**< Two-pass statistics for this frame */ - VPX_CODEC_FPMB_STATS_PKT, /**< first pass mb statistics for this frame */ - VPX_CODEC_PSNR_PKT, /**< PSNR statistics for this frame */ - VPX_CODEC_CUSTOM_PKT = 256 /**< Algorithm extensions */ -}; - -/*!\brief Encoder output packet - * - * This structure contains the different kinds of output data the encoder - * may produce while compressing a frame. - */ -typedef struct vpx_codec_cx_pkt { - enum vpx_codec_cx_pkt_kind kind; /**< packet variant */ - union { - struct { - void *buf; /**< compressed data buffer */ - size_t sz; /**< length of compressed data */ - /*!\brief time stamp to show frame (in timebase units) */ - vpx_codec_pts_t pts; - /*!\brief duration to show frame (in timebase units) */ - unsigned long duration; - vpx_codec_frame_flags_t flags; /**< flags for this frame */ - /*!\brief the partition id defines the decoding order of the partitions. - * Only applicable when "output partition" mode is enabled. First - * partition has id 0.*/ - int partition_id; - /*!\brief Width and height of frames in this packet. VP8 will only use the - * first one.*/ - unsigned int width[VPX_SS_MAX_LAYERS]; /**< frame width */ - unsigned int height[VPX_SS_MAX_LAYERS]; /**< frame height */ - /*!\brief Flag to indicate if spatial layer frame in this packet is - * encoded or dropped. VP8 will always be set to 1.*/ - uint8_t spatial_layer_encoded[VPX_SS_MAX_LAYERS]; - } frame; /**< data for compressed frame packet */ - vpx_fixed_buf_t twopass_stats; /**< data for two-pass packet */ - vpx_fixed_buf_t firstpass_mb_stats; /**< first pass mb packet */ - struct vpx_psnr_pkt { - unsigned int samples[4]; /**< Number of samples, total/y/u/v */ - uint64_t sse[4]; /**< sum squared error, total/y/u/v */ - double psnr[4]; /**< PSNR, total/y/u/v */ - } psnr; /**< data for PSNR packet */ - vpx_fixed_buf_t raw; /**< data for arbitrary packets */ - - /* This packet size is fixed to allow codecs to extend this - * interface without having to manage storage for raw packets, - * i.e., if it's smaller than 128 bytes, you can store in the - * packet list directly. - */ - char pad[128 - sizeof(enum vpx_codec_cx_pkt_kind)]; /**< fixed sz */ - } data; /**< packet data */ -} vpx_codec_cx_pkt_t; /**< alias for struct vpx_codec_cx_pkt */ - -/*!\brief Encoder return output buffer callback - * - * This callback function, when registered, returns with packets when each - * spatial layer is encoded. - */ -typedef void (*vpx_codec_enc_output_cx_pkt_cb_fn_t)(vpx_codec_cx_pkt_t *pkt, - void *user_data); - -/*!\brief Callback function pointer / user data pair storage */ -typedef struct vpx_codec_enc_output_cx_cb_pair { - vpx_codec_enc_output_cx_pkt_cb_fn_t output_cx_pkt; /**< Callback function */ - void *user_priv; /**< Pointer to private data */ -} vpx_codec_priv_output_cx_pkt_cb_pair_t; - -/*!\brief Rational Number - * - * This structure holds a fractional value. - */ -typedef struct vpx_rational { - int num; /**< fraction numerator */ - int den; /**< fraction denominator */ -} vpx_rational_t; /**< alias for struct vpx_rational */ - -/*!\brief Multi-pass Encoding Pass */ -typedef enum vpx_enc_pass { - VPX_RC_ONE_PASS, /**< Single pass mode */ - VPX_RC_FIRST_PASS, /**< First pass of multi-pass mode */ - VPX_RC_LAST_PASS /**< Final pass of multi-pass mode */ -} vpx_enc_pass; - -/*!\brief Rate control mode */ -enum vpx_rc_mode { - VPX_VBR, /**< Variable Bit Rate (VBR) mode */ - VPX_CBR, /**< Constant Bit Rate (CBR) mode */ - VPX_CQ, /**< Constrained Quality (CQ) mode */ - VPX_Q, /**< Constant Quality (Q) mode */ -}; - -/*!\brief Keyframe placement mode. - * - * This enumeration determines whether keyframes are placed automatically by - * the encoder or whether this behavior is disabled. Older releases of this - * SDK were implemented such that VPX_KF_FIXED meant keyframes were disabled. - * This name is confusing for this behavior, so the new symbols to be used - * are VPX_KF_AUTO and VPX_KF_DISABLED. - */ -enum vpx_kf_mode { - VPX_KF_FIXED, /**< deprecated, implies VPX_KF_DISABLED */ - VPX_KF_AUTO, /**< Encoder determines optimal placement automatically */ - VPX_KF_DISABLED = 0 /**< Encoder does not place keyframes. */ -}; - -/*!\brief Encoded Frame Flags - * - * This type indicates a bitfield to be passed to vpx_codec_encode(), defining - * per-frame boolean values. By convention, bits common to all codecs will be - * named VPX_EFLAG_*, and bits specific to an algorithm will be named - * /algo/_eflag_*. The lower order 16 bits are reserved for common use. - */ -typedef long vpx_enc_frame_flags_t; -#define VPX_EFLAG_FORCE_KF (1 << 0) /**< Force this frame to be a keyframe */ - -/*!\brief Encoder configuration structure - * - * This structure contains the encoder settings that have common representations - * across all codecs. This doesn't imply that all codecs support all features, - * however. - */ -typedef struct vpx_codec_enc_cfg { - /* - * generic settings (g) - */ - - /*!\brief Deprecated: Algorithm specific "usage" value - * - * This value must be zero. - */ - unsigned int g_usage; - - /*!\brief Maximum number of threads to use - * - * For multi-threaded implementations, use no more than this number of - * threads. The codec may use fewer threads than allowed. The value - * 0 is equivalent to the value 1. - */ - unsigned int g_threads; - - /*!\brief Bitstream profile to use - * - * Some codecs support a notion of multiple bitstream profiles. Typically - * this maps to a set of features that are turned on or off. Often the - * profile to use is determined by the features of the intended decoder. - * Consult the documentation for the codec to determine the valid values - * for this parameter, or set to zero for a sane default. - */ - unsigned int g_profile; /**< profile of bitstream to use */ - - /*!\brief Width of the frame - * - * This value identifies the presentation resolution of the frame, - * in pixels. Note that the frames passed as input to the encoder must - * have this resolution. Frames will be presented by the decoder in this - * resolution, independent of any spatial resampling the encoder may do. - */ - unsigned int g_w; - - /*!\brief Height of the frame - * - * This value identifies the presentation resolution of the frame, - * in pixels. Note that the frames passed as input to the encoder must - * have this resolution. Frames will be presented by the decoder in this - * resolution, independent of any spatial resampling the encoder may do. - */ - unsigned int g_h; - - /*!\brief Bit-depth of the codec - * - * This value identifies the bit_depth of the codec, - * Only certain bit-depths are supported as identified in the - * vpx_bit_depth_t enum. - */ - vpx_bit_depth_t g_bit_depth; - - /*!\brief Bit-depth of the input frames - * - * This value identifies the bit_depth of the input frames in bits. - * Note that the frames passed as input to the encoder must have - * this bit-depth. - */ - unsigned int g_input_bit_depth; - - /*!\brief Stream timebase units - * - * Indicates the smallest interval of time, in seconds, used by the stream. - * For fixed frame rate material, or variable frame rate material where - * frames are timed at a multiple of a given clock (ex: video capture), - * the \ref RECOMMENDED method is to set the timebase to the reciprocal - * of the frame rate (ex: 1001/30000 for 29.970 Hz NTSC). This allows the - * pts to correspond to the frame number, which can be handy. For - * re-encoding video from containers with absolute time timestamps, the - * \ref RECOMMENDED method is to set the timebase to that of the parent - * container or multimedia framework (ex: 1/1000 for ms, as in FLV). - */ - struct vpx_rational g_timebase; - - /*!\brief Enable error resilient modes. - * - * The error resilient bitfield indicates to the encoder which features - * it should enable to take measures for streaming over lossy or noisy - * links. - */ - vpx_codec_er_flags_t g_error_resilient; - - /*!\brief Multi-pass Encoding Mode - * - * This value should be set to the current phase for multi-pass encoding. - * For single pass, set to #VPX_RC_ONE_PASS. - */ - enum vpx_enc_pass g_pass; - - /*!\brief Allow lagged encoding - * - * If set, this value allows the encoder to consume a number of input - * frames before producing output frames. This allows the encoder to - * base decisions for the current frame on future frames. This does - * increase the latency of the encoding pipeline, so it is not appropriate - * in all situations (ex: realtime encoding). - * - * Note that this is a maximum value -- the encoder may produce frames - * sooner than the given limit. Set this value to 0 to disable this - * feature. - */ - unsigned int g_lag_in_frames; - - /* - * rate control settings (rc) - */ - - /*!\brief Temporal resampling configuration, if supported by the codec. - * - * Temporal resampling allows the codec to "drop" frames as a strategy to - * meet its target data rate. This can cause temporal discontinuities in - * the encoded video, which may appear as stuttering during playback. This - * trade-off is often acceptable, but for many applications is not. It can - * be disabled in these cases. - * - * This threshold is described as a percentage of the target data buffer. - * When the data buffer falls below this percentage of fullness, a - * dropped frame is indicated. Set the threshold to zero (0) to disable - * this feature. - */ - unsigned int rc_dropframe_thresh; - - /*!\brief Enable/disable spatial resampling, if supported by the codec. - * - * Spatial resampling allows the codec to compress a lower resolution - * version of the frame, which is then upscaled by the encoder to the - * correct presentation resolution. This increases visual quality at - * low data rates, at the expense of CPU time on the encoder/decoder. - */ - unsigned int rc_resize_allowed; - - /*!\brief Internal coded frame width. - * - * If spatial resampling is enabled this specifies the width of the - * encoded frame. - */ - unsigned int rc_scaled_width; - - /*!\brief Internal coded frame height. - * - * If spatial resampling is enabled this specifies the height of the - * encoded frame. - */ - unsigned int rc_scaled_height; - - /*!\brief Spatial resampling up watermark. - * - * This threshold is described as a percentage of the target data buffer. - * When the data buffer rises above this percentage of fullness, the - * encoder will step up to a higher resolution version of the frame. - */ - unsigned int rc_resize_up_thresh; - - /*!\brief Spatial resampling down watermark. - * - * This threshold is described as a percentage of the target data buffer. - * When the data buffer falls below this percentage of fullness, the - * encoder will step down to a lower resolution version of the frame. - */ - unsigned int rc_resize_down_thresh; - - /*!\brief Rate control algorithm to use. - * - * Indicates whether the end usage of this stream is to be streamed over - * a bandwidth constrained link, indicating that Constant Bit Rate (CBR) - * mode should be used, or whether it will be played back on a high - * bandwidth link, as from a local disk, where higher variations in - * bitrate are acceptable. - */ - enum vpx_rc_mode rc_end_usage; - - /*!\brief Two-pass stats buffer. - * - * A buffer containing all of the stats packets produced in the first - * pass, concatenated. - */ - vpx_fixed_buf_t rc_twopass_stats_in; - - /*!\brief first pass mb stats buffer. - * - * A buffer containing all of the first pass mb stats packets produced - * in the first pass, concatenated. - */ - vpx_fixed_buf_t rc_firstpass_mb_stats_in; - - /*!\brief Target data rate - * - * Target bitrate to use for this stream, in kilobits per second. - * Internally capped to the smaller of the uncompressed bitrate and - * 1000000 kilobits per second. - */ - unsigned int rc_target_bitrate; - - /* - * quantizer settings - */ - - /*!\brief Minimum (Best Quality) Quantizer - * - * The quantizer is the most direct control over the quality of the - * encoded image. The range of valid values for the quantizer is codec - * specific. Consult the documentation for the codec to determine the - * values to use. - */ - unsigned int rc_min_quantizer; - - /*!\brief Maximum (Worst Quality) Quantizer - * - * The quantizer is the most direct control over the quality of the - * encoded image. The range of valid values for the quantizer is codec - * specific. Consult the documentation for the codec to determine the - * values to use. - */ - unsigned int rc_max_quantizer; - - /* - * bitrate tolerance - */ - - /*!\brief Rate control adaptation undershoot control - * - * VP8: Expressed as a percentage of the target bitrate, - * controls the maximum allowed adaptation speed of the codec. - * This factor controls the maximum amount of bits that can - * be subtracted from the target bitrate in order to compensate - * for prior overshoot. - * VP9: Expressed as a percentage of the target bitrate, a threshold - * undershoot level (current rate vs target) beyond which more aggressive - * corrective measures are taken. - * * - * Valid values in the range VP8:0-100 VP9: 0-100. - */ - unsigned int rc_undershoot_pct; - - /*!\brief Rate control adaptation overshoot control - * - * VP8: Expressed as a percentage of the target bitrate, - * controls the maximum allowed adaptation speed of the codec. - * This factor controls the maximum amount of bits that can - * be added to the target bitrate in order to compensate for - * prior undershoot. - * VP9: Expressed as a percentage of the target bitrate, a threshold - * overshoot level (current rate vs target) beyond which more aggressive - * corrective measures are taken. - * - * Valid values in the range VP8:0-100 VP9: 0-100. - */ - unsigned int rc_overshoot_pct; - - /* - * decoder buffer model parameters - */ - - /*!\brief Decoder Buffer Size - * - * This value indicates the amount of data that may be buffered by the - * decoding application. Note that this value is expressed in units of - * time (milliseconds). For example, a value of 5000 indicates that the - * client will buffer (at least) 5000ms worth of encoded data. Use the - * target bitrate (#rc_target_bitrate) to convert to bits/bytes, if - * necessary. - */ - unsigned int rc_buf_sz; - - /*!\brief Decoder Buffer Initial Size - * - * This value indicates the amount of data that will be buffered by the - * decoding application prior to beginning playback. This value is - * expressed in units of time (milliseconds). Use the target bitrate - * (#rc_target_bitrate) to convert to bits/bytes, if necessary. - */ - unsigned int rc_buf_initial_sz; - - /*!\brief Decoder Buffer Optimal Size - * - * This value indicates the amount of data that the encoder should try - * to maintain in the decoder's buffer. This value is expressed in units - * of time (milliseconds). Use the target bitrate (#rc_target_bitrate) - * to convert to bits/bytes, if necessary. - */ - unsigned int rc_buf_optimal_sz; - - /* - * 2 pass rate control parameters - */ - - /*!\brief Two-pass mode CBR/VBR bias - * - * Bias, expressed on a scale of 0 to 100, for determining target size - * for the current frame. The value 0 indicates the optimal CBR mode - * value should be used. The value 100 indicates the optimal VBR mode - * value should be used. Values in between indicate which way the - * encoder should "lean." - */ - unsigned int rc_2pass_vbr_bias_pct; - - /*!\brief Two-pass mode per-GOP minimum bitrate - * - * This value, expressed as a percentage of the target bitrate, indicates - * the minimum bitrate to be used for a single GOP (aka "section") - */ - unsigned int rc_2pass_vbr_minsection_pct; - - /*!\brief Two-pass mode per-GOP maximum bitrate - * - * This value, expressed as a percentage of the target bitrate, indicates - * the maximum bitrate to be used for a single GOP (aka "section") - */ - unsigned int rc_2pass_vbr_maxsection_pct; - - /*!\brief Two-pass corpus vbr mode complexity control - * Used only in VP9: A value representing the corpus midpoint complexity - * for corpus vbr mode. This value defaults to 0 which disables corpus vbr - * mode in favour of normal vbr mode. - */ - unsigned int rc_2pass_vbr_corpus_complexity; - - /* - * keyframing settings (kf) - */ - - /*!\brief Keyframe placement mode - * - * This value indicates whether the encoder should place keyframes at a - * fixed interval, or determine the optimal placement automatically - * (as governed by the #kf_min_dist and #kf_max_dist parameters) - */ - enum vpx_kf_mode kf_mode; - - /*!\brief Keyframe minimum interval - * - * This value, expressed as a number of frames, prevents the encoder from - * placing a keyframe nearer than kf_min_dist to the previous keyframe. At - * least kf_min_dist frames non-keyframes will be coded before the next - * keyframe. Set kf_min_dist equal to kf_max_dist for a fixed interval. - */ - unsigned int kf_min_dist; - - /*!\brief Keyframe maximum interval - * - * This value, expressed as a number of frames, forces the encoder to code - * a keyframe if one has not been coded in the last kf_max_dist frames. - * A value of 0 implies all frames will be keyframes. Set kf_min_dist - * equal to kf_max_dist for a fixed interval. - */ - unsigned int kf_max_dist; - - /* - * Spatial scalability settings (ss) - */ - - /*!\brief Number of spatial coding layers. - * - * This value specifies the number of spatial coding layers to be used. - */ - unsigned int ss_number_layers; - - /*!\brief Enable auto alt reference flags for each spatial layer. - * - * These values specify if auto alt reference frame is enabled for each - * spatial layer. - */ - int ss_enable_auto_alt_ref[VPX_SS_MAX_LAYERS]; - - /*!\brief Target bitrate for each spatial layer. - * - * These values specify the target coding bitrate to be used for each - * spatial layer. (in kbps) - */ - unsigned int ss_target_bitrate[VPX_SS_MAX_LAYERS]; - - /*!\brief Number of temporal coding layers. - * - * This value specifies the number of temporal layers to be used. - */ - unsigned int ts_number_layers; - - /*!\brief Target bitrate for each temporal layer. - * - * These values specify the target coding bitrate to be used for each - * temporal layer. (in kbps) - */ - unsigned int ts_target_bitrate[VPX_TS_MAX_LAYERS]; - - /*!\brief Frame rate decimation factor for each temporal layer. - * - * These values specify the frame rate decimation factors to apply - * to each temporal layer. - */ - unsigned int ts_rate_decimator[VPX_TS_MAX_LAYERS]; - - /*!\brief Length of the sequence defining frame temporal layer membership. - * - * This value specifies the length of the sequence that defines the - * membership of frames to temporal layers. For example, if the - * ts_periodicity = 8, then the frames are assigned to coding layers with a - * repeated sequence of length 8. - */ - unsigned int ts_periodicity; - - /*!\brief Template defining the membership of frames to temporal layers. - * - * This array defines the membership of frames to temporal coding layers. - * For a 2-layer encoding that assigns even numbered frames to one temporal - * layer (0) and odd numbered frames to a second temporal layer (1) with - * ts_periodicity=8, then ts_layer_id = (0,1,0,1,0,1,0,1). - */ - unsigned int ts_layer_id[VPX_TS_MAX_PERIODICITY]; - - /*!\brief Target bitrate for each spatial/temporal layer. - * - * These values specify the target coding bitrate to be used for each - * spatial/temporal layer. (in kbps) - * - */ - unsigned int layer_target_bitrate[VPX_MAX_LAYERS]; - - /*!\brief Temporal layering mode indicating which temporal layering scheme to - * use. - * - * The value (refer to VP9E_TEMPORAL_LAYERING_MODE) specifies the - * temporal layering mode to use. - * - */ - int temporal_layering_mode; - - /*!\brief A flag indicating whether to use external rate control parameters. - * By default is 0. If set to 1, the following parameters will be used in the - * rate control system. - */ - int use_vizier_rc_params; - - /*!\brief Active worst quality factor. - * - * Rate control parameters, set from external experiment results. - * Only when |use_vizier_rc_params| is set to 1, the pass in value will be - * used. Otherwise, the default value is used. - * - */ - vpx_rational_t active_wq_factor; - - /*!\brief Error per macroblock adjustment factor. - * - * Rate control parameters, set from external experiment results. - * Only when |use_vizier_rc_params| is set to 1, the pass in value will be - * used. Otherwise, the default value is used. - * - */ - vpx_rational_t err_per_mb_factor; - - /*!\brief Second reference default decay limit. - * - * Rate control parameters, set from external experiment results. - * Only when |use_vizier_rc_params| is set to 1, the pass in value will be - * used. Otherwise, the default value is used. - * - */ - vpx_rational_t sr_default_decay_limit; - - /*!\brief Second reference difference factor. - * - * Rate control parameters, set from external experiment results. - * Only when |use_vizier_rc_params| is set to 1, the pass in value will be - * used. Otherwise, the default value is used. - * - */ - vpx_rational_t sr_diff_factor; - - /*!\brief Keyframe error per macroblock adjustment factor. - * - * Rate control parameters, set from external experiment results. - * Only when |use_vizier_rc_params| is set to 1, the pass in value will be - * used. Otherwise, the default value is used. - * - */ - vpx_rational_t kf_err_per_mb_factor; - - /*!\brief Keyframe minimum boost adjustment factor. - * - * Rate control parameters, set from external experiment results. - * Only when |use_vizier_rc_params| is set to 1, the pass in value will be - * used. Otherwise, the default value is used. - * - */ - vpx_rational_t kf_frame_min_boost_factor; - - /*!\brief Keyframe maximum boost adjustment factor, for the first keyframe - * in a chunk. - * - * Rate control parameters, set from external experiment results. - * Only when |use_vizier_rc_params| is set to 1, the pass in value will be - * used. Otherwise, the default value is used. - * - */ - vpx_rational_t kf_frame_max_boost_first_factor; - - /*!\brief Keyframe maximum boost adjustment factor, for subsequent keyframes. - * - * Rate control parameters, set from external experiment results. - * Only when |use_vizier_rc_params| is set to 1, the pass in value will be - * used. Otherwise, the default value is used. - * - */ - vpx_rational_t kf_frame_max_boost_subs_factor; - - /*!\brief Keyframe maximum total boost adjustment factor. - * - * Rate control parameters, set from external experiment results. - * Only when |use_vizier_rc_params| is set to 1, the pass in value will be - * used. Otherwise, the default value is used. - * - */ - vpx_rational_t kf_max_total_boost_factor; - - /*!\brief Golden frame maximum total boost adjustment factor. - * - * Rate control parameters, set from external experiment results. - * Only when |use_vizier_rc_params| is set to 1, the pass in value will be - * used. Otherwise, the default value is used. - * - */ - vpx_rational_t gf_max_total_boost_factor; - - /*!\brief Golden frame maximum boost adjustment factor. - * - * Rate control parameters, set from external experiment results. - * Only when |use_vizier_rc_params| is set to 1, the pass in value will be - * used. Otherwise, the default value is used. - * - */ - vpx_rational_t gf_frame_max_boost_factor; - - /*!\brief Zero motion power factor. - * - * Rate control parameters, set from external experiment results. - * Only when |use_vizier_rc_params| is set to 1, the pass in value will be - * used. Otherwise, the default value is used. - * - */ - vpx_rational_t zm_factor; - - /*!\brief Rate-distortion multiplier for inter frames. - * The multiplier is a crucial parameter in the calculation of rate distortion - * cost. It is often related to the qp (qindex) value. - * Rate control parameters, could be set from external experiment results. - * Only when |use_vizier_rc_params| is set to 1, the pass in value will be - * used. Otherwise, the default value is used. - * - */ - vpx_rational_t rd_mult_inter_qp_fac; - - /*!\brief Rate-distortion multiplier for alt-ref frames. - * The multiplier is a crucial parameter in the calculation of rate distortion - * cost. It is often related to the qp (qindex) value. - * Rate control parameters, could be set from external experiment results. - * Only when |use_vizier_rc_params| is set to 1, the pass in value will be - * used. Otherwise, the default value is used. - * - */ - vpx_rational_t rd_mult_arf_qp_fac; - - /*!\brief Rate-distortion multiplier for key frames. - * The multiplier is a crucial parameter in the calculation of rate distortion - * cost. It is often related to the qp (qindex) value. - * Rate control parameters, could be set from external experiment results. - * Only when |use_vizier_rc_params| is set to 1, the pass in value will be - * used. Otherwise, the default value is used. - * - */ - vpx_rational_t rd_mult_key_qp_fac; -} vpx_codec_enc_cfg_t; /**< alias for struct vpx_codec_enc_cfg */ - -/*!\brief vp9 svc extra configure parameters - * - * This defines max/min quantizers and scale factors for each layer - * - */ -typedef struct vpx_svc_parameters { - int max_quantizers[VPX_MAX_LAYERS]; /**< Max Q for each layer */ - int min_quantizers[VPX_MAX_LAYERS]; /**< Min Q for each layer */ - int scaling_factor_num[VPX_MAX_LAYERS]; /**< Scaling factor-numerator */ - int scaling_factor_den[VPX_MAX_LAYERS]; /**< Scaling factor-denominator */ - int speed_per_layer[VPX_MAX_LAYERS]; /**< Speed setting for each sl */ - int temporal_layering_mode; /**< Temporal layering mode */ - int loopfilter_ctrl[VPX_MAX_LAYERS]; /**< Loopfilter ctrl for each sl */ -} vpx_svc_extra_cfg_t; - -/*!\brief Initialize an encoder instance - * - * Initializes an encoder context using the given interface. Applications - * should call the vpx_codec_enc_init convenience macro instead of this - * function directly, to ensure that the ABI version number parameter - * is properly initialized. - * - * If the library was configured with --disable-multithread, this call - * is not thread safe and should be guarded with a lock if being used - * in a multithreaded context. - * - * If vpx_codec_enc_init_ver() fails, it is not necessary to call - * vpx_codec_destroy() on the encoder context. - * - * \param[in] ctx Pointer to this instance's context. - * \param[in] iface Pointer to the algorithm interface to use. - * \param[in] cfg Configuration to use, if known. May be NULL. - * \param[in] flags Bitfield of VPX_CODEC_USE_* flags - * \param[in] ver ABI version number. Must be set to - * VPX_ENCODER_ABI_VERSION - * \retval #VPX_CODEC_OK - * The decoder algorithm initialized. - * \retval #VPX_CODEC_MEM_ERROR - * Memory allocation failed. - */ -vpx_codec_err_t vpx_codec_enc_init_ver(vpx_codec_ctx_t *ctx, - vpx_codec_iface_t *iface, - const vpx_codec_enc_cfg_t *cfg, - vpx_codec_flags_t flags, int ver); - -/*!\brief Convenience macro for vpx_codec_enc_init_ver() - * - * Ensures the ABI version parameter is properly set. - */ -#define vpx_codec_enc_init(ctx, iface, cfg, flags) \ - vpx_codec_enc_init_ver(ctx, iface, cfg, flags, VPX_ENCODER_ABI_VERSION) - -/*!\brief Initialize multi-encoder instance - * - * Initializes multi-encoder context using the given interface. - * Applications should call the vpx_codec_enc_init_multi convenience macro - * instead of this function directly, to ensure that the ABI version number - * parameter is properly initialized. - * - * \param[in] ctx Pointer to this instance's context. - * \param[in] iface Pointer to the algorithm interface to use. - * \param[in] cfg Configuration to use, if known. May be NULL. - * \param[in] num_enc Total number of encoders. - * \param[in] flags Bitfield of VPX_CODEC_USE_* flags - * \param[in] dsf Pointer to down-sampling factors. - * \param[in] ver ABI version number. Must be set to - * VPX_ENCODER_ABI_VERSION - * \retval #VPX_CODEC_OK - * The encoder algorithm has been initialized. - * \retval #VPX_CODEC_MEM_ERROR - * Memory allocation failed. - */ -vpx_codec_err_t vpx_codec_enc_init_multi_ver( - vpx_codec_ctx_t *ctx, vpx_codec_iface_t *iface, vpx_codec_enc_cfg_t *cfg, - int num_enc, vpx_codec_flags_t flags, vpx_rational_t *dsf, int ver); - -/*!\brief Convenience macro for vpx_codec_enc_init_multi_ver() - * - * Ensures the ABI version parameter is properly set. - */ -#define vpx_codec_enc_init_multi(ctx, iface, cfg, num_enc, flags, dsf) \ - vpx_codec_enc_init_multi_ver(ctx, iface, cfg, num_enc, flags, dsf, \ - VPX_ENCODER_ABI_VERSION) - -/*!\brief Get a default configuration - * - * Initializes a encoder configuration structure with default values. Supports - * the notion of "usages" so that an algorithm may offer different default - * settings depending on the user's intended goal. This function \ref SHOULD - * be called by all applications to initialize the configuration structure - * before specializing the configuration with application specific values. - * - * \param[in] iface Pointer to the algorithm interface to use. - * \param[out] cfg Configuration buffer to populate. - * \param[in] usage Must be set to 0. - * - * \retval #VPX_CODEC_OK - * The configuration was populated. - * \retval #VPX_CODEC_INCAPABLE - * Interface is not an encoder interface. - * \retval #VPX_CODEC_INVALID_PARAM - * A parameter was NULL, or the usage value was not recognized. - */ -vpx_codec_err_t vpx_codec_enc_config_default(vpx_codec_iface_t *iface, - vpx_codec_enc_cfg_t *cfg, - unsigned int usage); - -/*!\brief Set or change configuration - * - * Reconfigures an encoder instance according to the given configuration. - * - * \param[in] ctx Pointer to this instance's context - * \param[in] cfg Configuration buffer to use - * - * \retval #VPX_CODEC_OK - * The configuration was populated. - * \retval #VPX_CODEC_INCAPABLE - * Interface is not an encoder interface. - * \retval #VPX_CODEC_INVALID_PARAM - * A parameter was NULL, or the usage value was not recognized. - */ -vpx_codec_err_t vpx_codec_enc_config_set(vpx_codec_ctx_t *ctx, - const vpx_codec_enc_cfg_t *cfg); - -/*!\brief Get global stream headers - * - * Retrieves a stream level global header packet, if supported by the codec. - * - * \li VP8: Unsupported - * \li VP9: Returns a buffer of ID (1 byte)|Length (1 byte)|Length - * bytes values. The function should be called after encoding to retrieve - * the most accurate information. - * - * \param[in] ctx Pointer to this instance's context - * - * \retval NULL - * Encoder does not support global header - * \retval Non-NULL - * Pointer to buffer containing global header packet. The buffer pointer - * and its contents are only valid for the lifetime of \a ctx. The contents - * may change in subsequent calls to the function. - * \sa - * https://www.webmproject.org/docs/container/#vp9-codec-feature-metadata-codecprivate - */ -vpx_fixed_buf_t *vpx_codec_get_global_headers(vpx_codec_ctx_t *ctx); - -/*!\brief Encode Deadline - * - * This type indicates a deadline, in microseconds, to be passed to - * vpx_codec_encode(). - */ -typedef unsigned long vpx_enc_deadline_t; -/*!\brief deadline parameter analogous to VPx REALTIME mode. */ -#define VPX_DL_REALTIME 1ul -/*!\brief deadline parameter analogous to VPx GOOD QUALITY mode. */ -#define VPX_DL_GOOD_QUALITY 1000000ul -/*!\brief deadline parameter analogous to VPx BEST QUALITY mode. */ -#define VPX_DL_BEST_QUALITY 0ul -/*!\brief Encode a frame - * - * Encodes a video frame at the given "presentation time." The presentation - * time stamp (PTS) \ref MUST be strictly increasing. - * - * The encoder supports the notion of a soft real-time deadline. Given a - * non-zero value to the deadline parameter, the encoder will make a "best - * effort" guarantee to return before the given time slice expires. It is - * implicit that limiting the available time to encode will degrade the - * output quality. The encoder can be given an unlimited time to produce the - * best possible frame by specifying a deadline of '0'. This deadline - * supersedes the VPx notion of "best quality, good quality, realtime". - * Applications that wish to map these former settings to the new deadline - * based system can use the symbols #VPX_DL_REALTIME, #VPX_DL_GOOD_QUALITY, - * and #VPX_DL_BEST_QUALITY. - * - * When the last frame has been passed to the encoder, this function should - * continue to be called, with the img parameter set to NULL. This will - * signal the end-of-stream condition to the encoder and allow it to encode - * any held buffers. Encoding is complete when vpx_codec_encode() is called - * and vpx_codec_get_cx_data() returns no data. - * - * \param[in] ctx Pointer to this instance's context - * \param[in] img Image data to encode, NULL to flush. - * Encoding sample values outside the range - * [0..(1<bit_depth)-1] is undefined behavior. - * \param[in] pts Presentation time stamp, in timebase units. - * \param[in] duration Duration to show frame, in timebase units. - * \param[in] flags Flags to use for encoding this frame. - * \param[in] deadline Time to spend encoding, in microseconds. (0=infinite) - * - * \retval #VPX_CODEC_OK - * The configuration was populated. - * \retval #VPX_CODEC_INCAPABLE - * Interface is not an encoder interface. - * \retval #VPX_CODEC_INVALID_PARAM - * A parameter was NULL, the image format is unsupported, etc. - */ -vpx_codec_err_t vpx_codec_encode(vpx_codec_ctx_t *ctx, const vpx_image_t *img, - vpx_codec_pts_t pts, unsigned long duration, - vpx_enc_frame_flags_t flags, - vpx_enc_deadline_t deadline); - -/*!\brief Set compressed data output buffer - * - * Sets the buffer that the codec should output the compressed data - * into. This call effectively sets the buffer pointer returned in the - * next VPX_CODEC_CX_FRAME_PKT packet. Subsequent packets will be - * appended into this buffer. The buffer is preserved across frames, - * so applications must periodically call this function after flushing - * the accumulated compressed data to disk or to the network to reset - * the pointer to the buffer's head. - * - * `pad_before` bytes will be skipped before writing the compressed - * data, and `pad_after` bytes will be appended to the packet. The size - * of the packet will be the sum of the size of the actual compressed - * data, pad_before, and pad_after. The padding bytes will be preserved - * (not overwritten). - * - * Note that calling this function does not guarantee that the returned - * compressed data will be placed into the specified buffer. In the - * event that the encoded data will not fit into the buffer provided, - * the returned packet \ref MAY point to an internal buffer, as it would - * if this call were never used. In this event, the output packet will - * NOT have any padding, and the application must free space and copy it - * to the proper place. This is of particular note in configurations - * that may output multiple packets for a single encoded frame (e.g., lagged - * encoding) or if the application does not reset the buffer periodically. - * - * Applications may restore the default behavior of the codec providing - * the compressed data buffer by calling this function with a NULL - * buffer. - * - * Applications \ref MUSTNOT call this function during iteration of - * vpx_codec_get_cx_data(). - * - * \param[in] ctx Pointer to this instance's context - * \param[in] buf Buffer to store compressed data into - * \param[in] pad_before Bytes to skip before writing compressed data - * \param[in] pad_after Bytes to skip after writing compressed data - * - * \retval #VPX_CODEC_OK - * The buffer was set successfully. - * \retval #VPX_CODEC_INVALID_PARAM - * A parameter was NULL, the image format is unsupported, etc. - * - * \note - * `duration` and `deadline` are of the unsigned long type, which can be 32 - * or 64 bits. `duration` and `deadline` must be less than or equal to - * UINT32_MAX so that their ranges are independent of the size of unsigned - * long. - */ -vpx_codec_err_t vpx_codec_set_cx_data_buf(vpx_codec_ctx_t *ctx, - const vpx_fixed_buf_t *buf, - unsigned int pad_before, - unsigned int pad_after); - -/*!\brief Encoded data iterator - * - * Iterates over a list of data packets to be passed from the encoder to the - * application. The different kinds of packets available are enumerated in - * #vpx_codec_cx_pkt_kind. - * - * #VPX_CODEC_CX_FRAME_PKT packets should be passed to the application's - * muxer. Multiple compressed frames may be in the list. - * #VPX_CODEC_STATS_PKT packets should be appended to a global buffer. - * - * The application \ref MUST silently ignore any packet kinds that it does - * not recognize or support. - * - * The data buffers returned from this function are only guaranteed to be - * valid until the application makes another call to any vpx_codec_* function. - * - * \param[in] ctx Pointer to this instance's context - * \param[in,out] iter Iterator storage, initialized to NULL - * - * \return Returns a pointer to an output data packet (compressed frame data, - * two-pass statistics, etc.) or NULL to signal end-of-list. - * - */ -const vpx_codec_cx_pkt_t *vpx_codec_get_cx_data(vpx_codec_ctx_t *ctx, - vpx_codec_iter_t *iter); - -/*!\brief Get Preview Frame - * - * Returns an image that can be used as a preview. Shows the image as it would - * exist at the decompressor. The application \ref MUST NOT write into this - * image buffer. - * - * \param[in] ctx Pointer to this instance's context - * - * \return Returns a pointer to a preview image, or NULL if no image is - * available. - * - */ -const vpx_image_t *vpx_codec_get_preview_frame(vpx_codec_ctx_t *ctx); - -/*!@} - end defgroup encoder*/ -#ifdef __cplusplus -} -#endif -#endif // VPX_VPX_VPX_ENCODER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_ext_ratectrl.h b/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_ext_ratectrl.h deleted file mode 100644 index 4820d367..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_ext_ratectrl.h +++ /dev/null @@ -1,590 +0,0 @@ -/* - * Copyright (c) 2020 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/*!\file - * \brief Defines structs and callbacks needed for external rate control. - * - */ -#ifndef VPX_VPX_VPX_EXT_RATECTRL_H_ -#define VPX_VPX_VPX_EXT_RATECTRL_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "./vpx_integer.h" -#include "./vpx_tpl.h" - -/*!\brief Current ABI version number - * - * \internal - * If this file is altered in any way that changes the ABI, this value - * must be bumped. Examples include, but are not limited to, changing - * types, removing or reassigning enums, adding/removing/rearranging - * fields to structures. - */ -#define VPX_EXT_RATECTRL_ABI_VERSION (6 + VPX_TPL_ABI_VERSION) - -/*!\brief Corresponds to MAX_STATIC_GF_GROUP_LENGTH defined in vp9_ratectrl.h - */ -#define VPX_RC_MAX_STATIC_GF_GROUP_LENGTH 250 - -/*!\brief Max number of ref frames returned by the external RC. - * - * Corresponds to MAX_REF_FRAMES defined in vp9_blockd.h. - */ -#define VPX_RC_MAX_REF_FRAMES 4 - -/*!\brief The type of the external rate control. - * - * This controls what encoder parameters are determined by the external rate - * control. - */ -typedef enum vpx_rc_type { - /*! - * The external rate control doesn't determine anything. - * This mode is used as baseline. - */ - VPX_RC_NONE = 0, - /*! - * The external rate control model determines the quantization parameter (QP) - * for each frame. - */ - VPX_RC_QP = 1 << 0, - /*! - * The external rate control model determines the group of picture (GOP) of - * the video sequence. - */ - VPX_RC_GOP = 1 << 1, - /*! - * The external rate control model determines the rate-distortion multiplier - * (rdmult) for the current frame. - */ - VPX_RC_RDMULT = 1 << 2, - /*! - * The external rate control model determines both QP and GOP. - */ - VPX_RC_GOP_QP = VPX_RC_QP | VPX_RC_GOP, - /*! - * The external rate control model determines the QP, GOP and the rdmult. - */ - VPX_RC_GOP_QP_RDMULT = VPX_RC_QP | VPX_RC_GOP | VPX_RC_RDMULT -} vpx_rc_type_t; - -/*!\brief The rate control mode for the external rate control model. - */ -typedef enum vpx_ext_rc_mode { - VPX_RC_QMODE = 0, - VPX_RC_VBR = 1, - VPX_RC_CQ = 2, -} vpx_ext_rc_mode_t; - -/*!\brief Corresponds to FRAME_UPDATE_TYPE defined in vp9_firstpass.h. - */ -typedef enum vpx_rc_frame_update_type { - VPX_RC_INVALID_UPDATE_TYPE = -1, - VPX_RC_KF_UPDATE = 0, - VPX_RC_LF_UPDATE = 1, - VPX_RC_GF_UPDATE = 2, - VPX_RC_ARF_UPDATE = 3, - VPX_RC_OVERLAY_UPDATE = 4, - VPX_RC_MID_OVERLAY_UPDATE = 5, - VPX_RC_USE_BUF_FRAME = 6, -} vpx_rc_frame_update_type_t; - -/*!\brief Name for the ref frames returned by the external RC. - * - * Corresponds to the ref frames defined in vp9_blockd.h. - */ -typedef enum vpx_rc_ref_name { - VPX_RC_INVALID_REF_FRAME = -1, - VPX_RC_INTRA_FRAME = 0, - VPX_RC_LAST_FRAME = 1, - VPX_RC_GOLDEN_FRAME = 2, - VPX_RC_ALTREF_FRAME = 3, -} vpx_rc_ref_name_t; - -/*!\brief Abstract rate control model handler - * - * The encoder will receive the model handler from - * vpx_rc_funcs_t::create_model(). - */ -typedef void *vpx_rc_model_t; - -/*!\brief A reserved value for the q index. - * If the external rate control model returns this value, - * the encoder will use the default q selected by libvpx's rate control - * system. - */ -#define VPX_DEFAULT_Q -1 - -/*!\brief A reserved value for the rdmult. - * If the external rate control model returns this value, - * the encoder will use the default rdmult selected by libvpx's rate control - * system. - */ -#define VPX_DEFAULT_RDMULT -1 - -/*!\brief Encode frame decision made by the external rate control model - * - * The encoder will receive the decision from the external rate control model - * through vpx_rc_funcs_t::get_encodeframe_decision(). - */ -typedef struct vpx_rc_encodeframe_decision { - int q_index; /**< Quantizer step index [0..255]*/ - int rdmult; /**< Frame level Lagrangian multiplier*/ -} vpx_rc_encodeframe_decision_t; - -/*!\brief Information for the frame to be encoded. - * - * The encoder will send the information to external rate control model through - * vpx_rc_funcs_t::get_encodeframe_decision(). - * - */ -typedef struct vpx_rc_encodeframe_info { - /*! - * 0: Key frame - * 1: Inter frame - * 2: Alternate reference frame - * 3: Overlay frame - * 4: Golden frame - */ - int frame_type; - int show_index; /**< display index, starts from zero*/ - int coding_index; /**< coding index, starts from zero*/ - /*! - * index of the current frame in this group of picture, starts from zero. - */ - int gop_index; - int ref_frame_coding_indexes[3]; /**< three reference frames' coding indices*/ - /*! - * The validity of the three reference frames. - * 0: Invalid - * 1: Valid - */ - int ref_frame_valid_list[3]; - /*! - * The length of the current GOP. - */ - int gop_size; - /*! - * Whether the current GOP uses an alt ref. - */ - int use_alt_ref; -} vpx_rc_encodeframe_info_t; - -/*!\brief Frame coding result - * - * The encoder will send the result to the external rate control model through - * vpx_rc_funcs_t::update_encodeframe_result(). - */ -typedef struct vpx_rc_encodeframe_result { - int64_t bit_count; /**< number of bits spent on coding the frame*/ - int actual_encoding_qindex; /**< the actual qindex used to encode the frame*/ -} vpx_rc_encodeframe_result_t; - -/*!\brief Status returned by rate control callback functions. - */ -typedef enum vpx_rc_status { - VPX_RC_OK = 0, - VPX_RC_ERROR = 1, -} vpx_rc_status_t; - -/*!\brief First pass frame stats - * This is a mirror of vp9's FIRSTPASS_STATS except that spatial_layer_id is - * omitted - */ -typedef struct vpx_rc_frame_stats { - /*! - * Frame number in display order, if stats are for a single frame. - * No real meaning for a collection of frames. - */ - double frame; - /*! - * Weight assigned to this frame (or total weight for the collection of - * frames) currently based on intra factor and brightness factor. This is used - * to distribute bits between easier and harder frames. - */ - double weight; - /*! - * Intra prediction error. - */ - double intra_error; - /*! - * Best of intra pred error and inter pred error using last frame as ref. - */ - double coded_error; - /*! - * Best of intra pred error and inter pred error using golden frame as ref. - */ - double sr_coded_error; - /*! - * Estimate the noise energy of the current frame. - */ - double frame_noise_energy; - /*! - * Percentage of blocks with inter pred error < intra pred error. - */ - double pcnt_inter; - /*! - * Percentage of blocks using (inter prediction and) non-zero motion vectors. - */ - double pcnt_motion; - /*! - * Percentage of blocks where golden frame was better than last or intra: - * inter pred error using golden frame < inter pred error using last frame and - * inter pred error using golden frame < intra pred error - */ - double pcnt_second_ref; - /*! - * Percentage of blocks where intra and inter prediction errors were very - * close. - */ - double pcnt_neutral; - /*! - * Percentage of blocks that have intra error < inter error and inter error < - * LOW_I_THRESH - * - bit_depth 8: LOW_I_THRESH = 24000 - * - bit_depth 10: LOW_I_THRESH = 24000 << 4 - * - bit_depth 12: LOW_I_THRESH = 24000 << 8 - */ - double pcnt_intra_low; - /*! - * Percentage of blocks that have intra error < inter error and intra error < - * LOW_I_THRESH but inter error >= LOW_I_THRESH LOW_I_THRESH - * - bit_depth 8: LOW_I_THRESH = 24000 - * - bit_depth 10: LOW_I_THRESH = 24000 << 4 - * - bit_depth 12: LOW_I_THRESH = 24000 << 8 - */ - double pcnt_intra_high; - /*! - * Percentage of blocks that have almost no intra error residual - * (i.e. are in effect completely flat and untextured in the intra - * domain). In natural videos this is uncommon, but it is much more - * common in animations, graphics and screen content, so may be used - * as a signal to detect these types of content. - */ - double intra_skip_pct; - /*! - * Percentage of blocks that have intra error < SMOOTH_INTRA_THRESH - * - bit_depth 8: SMOOTH_INTRA_THRESH = 4000 - * - bit_depth 10: SMOOTH_INTRA_THRESH = 4000 << 4 - * - bit_depth 12: SMOOTH_INTRA_THRESH = 4000 << 8 - */ - double intra_smooth_pct; - /*! - * Image mask rows top and bottom. - */ - double inactive_zone_rows; - /*! - * Image mask columns at left and right edges. - */ - double inactive_zone_cols; - /*! - * Mean of row motion vectors. - */ - double MVr; - /*! - * Mean of absolute value of row motion vectors. - */ - double mvr_abs; - /*! - * Mean of column motion vectors. - */ - double MVc; - /*! - * Mean of absolute value of column motion vectors. - */ - double mvc_abs; - /*! - * Variance of row motion vectors. - */ - double MVrv; - /*! - * Variance of column motion vectors. - */ - double MVcv; - /*! - * Value in range [-1,1] indicating fraction of row and column motion vectors - * that point inwards (negative MV value) or outwards (positive MV value). - * For example, value of 1 indicates, all row/column MVs are inwards. - */ - double mv_in_out_count; - /*! - * Duration of the frame / collection of frames. - */ - double duration; - /*! - * 1.0 if stats are for a single frame, or - * number of frames whose stats are accumulated. - */ - double count; - /*! - * Number of new mv in a frame. - */ - double new_mv_count; -} vpx_rc_frame_stats_t; - -/*!\brief Collection of first pass frame stats - */ -typedef struct vpx_rc_firstpass_stats { - /*! - * Pointer to first pass frame stats. - * The pointed array of vpx_rc_frame_stats_t should have length equal to - * number of show frames in the video. - */ - vpx_rc_frame_stats_t *frame_stats; - /*! - * Number of show frames in the video. - */ - int num_frames; -} vpx_rc_firstpass_stats_t; - -/*!\brief Encode config sent to external rate control model - */ -typedef struct vpx_rc_config { - int frame_width; /**< frame width */ - int frame_height; /**< frame height */ - int show_frame_count; /**< number of visible frames in the video */ - int max_gf_interval; /**< max GOP size in number of show frames */ - int min_gf_interval; /**< min GOP size in number of show frames */ - /*! - * Target bitrate in kilobytes per second - */ - int target_bitrate_kbps; - int frame_rate_num; /**< numerator of frame rate */ - int frame_rate_den; /**< denominator of frame rate */ - /*! - * The following fields are only for external rate control models that support - * different rate control modes. - */ - vpx_ext_rc_mode_t rc_mode; /**< Q mode or VBR mode */ - int overshoot_percent; /**< for VBR mode only */ - int undershoot_percent; /**< for VBR mode only */ - int min_base_q_index; /**< for VBR mode only */ - int max_base_q_index; /**< for VBR mode only */ - int base_qp; /**< base QP for leaf frames, 0-255 */ -} vpx_rc_config_t; - -/*!\brief Control what ref frame to use and its index. - */ -typedef struct vpx_rc_ref_frame { - /*! - * Ref frame index. Corresponding to |lst_fb_idx|, |gld_fb_idx| or - * |alt_fb_idx| in VP9_COMP depending on the ref frame #name. - */ - int index[VPX_RC_MAX_REF_FRAMES]; - /*! - * Ref frame name. This decides whether the #index is used as - * |lst_fb_idx|, |gld_fb_idx| or |alt_fb_idx| in VP9_COMP. - * - */ - vpx_rc_ref_name_t name[VPX_RC_MAX_REF_FRAMES]; -} vpx_rc_ref_frame_t; - -/*!\brief The decision made by the external rate control model to set the - * group of picture. - */ -typedef struct vpx_rc_gop_decision { - int gop_coding_frames; /**< The number of frames of this GOP */ - int use_alt_ref; /**< Whether to use alt ref for this GOP */ - int use_key_frame; /**< Whether to set key frame for this GOP */ - /*! - * Frame type for each frame in this GOP. - * This will be populated to |update_type| in GF_GROUP defined in - * vp9_firstpass.h - */ - vpx_rc_frame_update_type_t update_type[VPX_RC_MAX_STATIC_GF_GROUP_LENGTH + 2]; - /*! Ref frame buffer index to be updated for each frame in this GOP. */ - int update_ref_index[VPX_RC_MAX_STATIC_GF_GROUP_LENGTH + 2]; - /*! Ref frame list to be used for each frame in this GOP. */ - vpx_rc_ref_frame_t ref_frame_list[VPX_RC_MAX_STATIC_GF_GROUP_LENGTH + 2]; -} vpx_rc_gop_decision_t; - -/*!\brief The decision made by the external rate control model to set the - * key frame location and the show frame count in the key frame group - */ -typedef struct vpx_rc_key_frame_decision { - int key_frame_show_index; /**< This key frame's show index in the video */ - int key_frame_group_size; /**< Show frame count of this key frame group */ -} vpx_rc_key_frame_decision_t; - -/*!\brief Create an external rate control model callback prototype - * - * This callback is invoked by the encoder to create an external rate control - * model. - * - * \param[in] priv Callback's private data - * \param[in] ratectrl_config Pointer to vpx_rc_config_t - * \param[out] rate_ctrl_model_ptr Pointer to vpx_rc_model_t - */ -typedef vpx_rc_status_t (*vpx_rc_create_model_cb_fn_t)( - void *priv, const vpx_rc_config_t *ratectrl_config, - vpx_rc_model_t *rate_ctrl_model_ptr); - -/*!\brief Send first pass stats to the external rate control model callback - * prototype - * - * This callback is invoked by the encoder to send first pass stats to the - * external rate control model. - * - * \param[in] rate_ctrl_model rate control model - * \param[in] first_pass_stats first pass stats - */ -typedef vpx_rc_status_t (*vpx_rc_send_firstpass_stats_cb_fn_t)( - vpx_rc_model_t rate_ctrl_model, - const vpx_rc_firstpass_stats_t *first_pass_stats); - -/*!\brief Send TPL stats for the current GOP to the external rate control model - * callback prototype - * - * This callback is invoked by the encoder to send TPL stats for the GOP to the - * external rate control model. - * - * \param[in] rate_ctrl_model rate control model - * \param[in] tpl_gop_stats TPL stats for current GOP - */ -typedef vpx_rc_status_t (*vpx_rc_send_tpl_gop_stats_cb_fn_t)( - vpx_rc_model_t rate_ctrl_model, const VpxTplGopStats *tpl_gop_stats); - -/*!\brief Receive encode frame decision callback prototype - * - * This callback is invoked by the encoder to receive encode frame decision from - * the external rate control model. - * - * \param[in] rate_ctrl_model rate control model - * \param[in] frame_gop_index index of the frame in current gop - * \param[out] frame_decision encode decision of the coding frame - */ -typedef vpx_rc_status_t (*vpx_rc_get_encodeframe_decision_cb_fn_t)( - vpx_rc_model_t rate_ctrl_model, const int frame_gop_index, - vpx_rc_encodeframe_decision_t *frame_decision); - -/*!\brief Update encode frame result callback prototype - * - * This callback is invoked by the encoder to update encode frame result to the - * external rate control model. - * - * \param[in] rate_ctrl_model rate control model - * \param[out] encode_frame_result encode result of the coding frame - */ -typedef vpx_rc_status_t (*vpx_rc_update_encodeframe_result_cb_fn_t)( - vpx_rc_model_t rate_ctrl_model, - const vpx_rc_encodeframe_result_t *encode_frame_result); - -/*!\brief Get the key frame decision from the external rate control model. - * - * This callback is invoked by the encoder to get key frame decision from - * the external rate control model. - * - * \param[in] rate_ctrl_model rate control model - * \param[out] key_frame_decision key frame decision from the model - */ -typedef vpx_rc_status_t (*vpx_rc_get_key_frame_decision_cb_fn_t)( - vpx_rc_model_t rate_ctrl_model, - vpx_rc_key_frame_decision_t *key_frame_decision); - -/*!\brief Get the GOP structure from the external rate control model. - * - * This callback is invoked by the encoder to get GOP decisions from - * the external rate control model. - * - * \param[in] rate_ctrl_model rate control model - * \param[out] gop_decision GOP decision from the model - */ -typedef vpx_rc_status_t (*vpx_rc_get_gop_decision_cb_fn_t)( - vpx_rc_model_t rate_ctrl_model, vpx_rc_gop_decision_t *gop_decision); - -/*!\brief Get the frame rdmult from the external rate control model. - * - * This callback is invoked by the encoder to get rdmult from - * the external rate control model. - * - * \param[in] rate_ctrl_model rate control model - * \param[in] frame_info information collected from the encoder - * \param[out] rdmult frame rate-distortion multiplier from the model - */ -typedef vpx_rc_status_t (*vpx_rc_get_frame_rdmult_cb_fn_t)( - vpx_rc_model_t rate_ctrl_model, const vpx_rc_encodeframe_info_t *frame_info, - int *rdmult); - -/*!\brief Delete the external rate control model callback prototype - * - * This callback is invoked by the encoder to delete the external rate control - * model. - * - * \param[in] rate_ctrl_model rate control model - */ -typedef vpx_rc_status_t (*vpx_rc_delete_model_cb_fn_t)( - vpx_rc_model_t rate_ctrl_model); - -/*!\brief Callback function set for external rate control. - * - * The user can enable external rate control by registering - * a set of callback functions with the codec control flag - * #VP9E_SET_EXTERNAL_RATE_CONTROL. - */ -typedef struct vpx_rc_funcs { - /*! - * The rate control type of this API. - */ - vpx_rc_type_t rc_type; - /*! - * Create an external rate control model. - */ - vpx_rc_create_model_cb_fn_t create_model; - /*! - * Send first pass stats to the external rate control model. - */ - vpx_rc_send_firstpass_stats_cb_fn_t send_firstpass_stats; - /*! - * Send TPL stats for current GOP to the external rate control model. - */ - vpx_rc_send_tpl_gop_stats_cb_fn_t send_tpl_gop_stats; - /*! - * Get encodeframe decision from the external rate control model. - */ - vpx_rc_get_encodeframe_decision_cb_fn_t get_encodeframe_decision; - /*! - * Update encodeframe result to the external rate control model. - */ - vpx_rc_update_encodeframe_result_cb_fn_t update_encodeframe_result; - /*! - * Get key frame decision from the external rate control model. - */ - vpx_rc_get_key_frame_decision_cb_fn_t get_key_frame_decision; - /*! - * Get GOP decisions from the external rate control model. - */ - vpx_rc_get_gop_decision_cb_fn_t get_gop_decision; - /*! - * Get rdmult for the frame from the external rate control model. - */ - vpx_rc_get_frame_rdmult_cb_fn_t get_frame_rdmult; - /*! - * Delete the external rate control model. - */ - vpx_rc_delete_model_cb_fn_t delete_model; - - /*! - * Rate control log path. - */ - const char *rate_ctrl_log_path; - /*! - * Private data for the external rate control model. - */ - void *priv; -} vpx_rc_funcs_t; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_VPX_EXT_RATECTRL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_frame_buffer.h b/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_frame_buffer.h deleted file mode 100644 index fc832001..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_frame_buffer.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_VPX_FRAME_BUFFER_H_ -#define VPX_VPX_VPX_FRAME_BUFFER_H_ - -/*!\file - * \brief Describes the decoder external frame buffer interface. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "./vpx_integer.h" - -/*!\brief The maximum number of work buffers used by libvpx. - * Support maximum 4 threads to decode video in parallel. - * Each thread will use one work buffer. - * TODO(hkuang): Add support to set number of worker threads dynamically. - */ -#define VPX_MAXIMUM_WORK_BUFFERS 8 - -/*!\brief The maximum number of reference buffers that a VP9 encoder may use. - */ -#define VP9_MAXIMUM_REF_BUFFERS 8 - -/*!\brief External frame buffer - * - * This structure holds allocated frame buffers used by the decoder. - */ -typedef struct vpx_codec_frame_buffer { - uint8_t *data; /**< Pointer to the data buffer */ - size_t size; /**< Size of data in bytes */ - void *priv; /**< Frame's private data */ -} vpx_codec_frame_buffer_t; - -/*!\brief get frame buffer callback prototype - * - * This callback is invoked by the decoder to retrieve data for the frame - * buffer in order for the decode call to complete. The callback must - * allocate at least min_size in bytes and assign it to fb->data. The callback - * must zero out all the data allocated. Then the callback must set fb->size - * to the allocated size. The application does not need to align the allocated - * data. The callback is triggered when the decoder needs a frame buffer to - * decode a compressed image into. This function may be called more than once - * for every call to vpx_codec_decode. The application may set fb->priv to - * some data which will be passed back in the vpx_image_t and the release - * function call. |fb| is guaranteed to not be NULL. On success the callback - * must return 0. Any failure the callback must return a value less than 0. - * - * \param[in] priv Callback's private data - * \param[in] min_size Size in bytes needed by the buffer - * \param[in,out] fb Pointer to vpx_codec_frame_buffer_t - */ -typedef int (*vpx_get_frame_buffer_cb_fn_t)(void *priv, size_t min_size, - vpx_codec_frame_buffer_t *fb); - -/*!\brief release frame buffer callback prototype - * - * This callback is invoked by the decoder when the frame buffer is not - * referenced by any other buffers. |fb| is guaranteed to not be NULL. On - * success the callback must return 0. Any failure the callback must return - * a value less than 0. - * - * \param[in] priv Callback's private data - * \param[in] fb Pointer to vpx_codec_frame_buffer_t - */ -typedef int (*vpx_release_frame_buffer_cb_fn_t)(void *priv, - vpx_codec_frame_buffer_t *fb); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_VPX_FRAME_BUFFER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_image.h b/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_image.h deleted file mode 100644 index 314f6447..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_image.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/*!\file - * \brief Describes the vpx image descriptor and associated operations - * - */ -#ifndef VPX_VPX_VPX_IMAGE_H_ -#define VPX_VPX_VPX_IMAGE_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/*!\brief Current ABI version number - * - * \internal - * If this file is altered in any way that changes the ABI, this value - * must be bumped. Examples include, but are not limited to, changing - * types, removing or reassigning enums, adding/removing/rearranging - * fields to structures - */ -#define VPX_IMAGE_ABI_VERSION (5) /**<\hideinitializer*/ - -#define VPX_IMG_FMT_PLANAR 0x100 /**< Image is a planar format. */ -#define VPX_IMG_FMT_UV_FLIP 0x200 /**< V plane precedes U in memory. */ -#define VPX_IMG_FMT_HAS_ALPHA 0x400 /**< Image has an alpha channel. */ -#define VPX_IMG_FMT_HIGHBITDEPTH 0x800 /**< Image uses 16bit framebuffer. */ - -/*!\brief List of supported image formats */ -typedef enum vpx_img_fmt { - VPX_IMG_FMT_NONE, - VPX_IMG_FMT_YV12 = - VPX_IMG_FMT_PLANAR | VPX_IMG_FMT_UV_FLIP | 1, /**< planar YVU */ - VPX_IMG_FMT_I420 = VPX_IMG_FMT_PLANAR | 2, - VPX_IMG_FMT_I422 = VPX_IMG_FMT_PLANAR | 5, - VPX_IMG_FMT_I444 = VPX_IMG_FMT_PLANAR | 6, - VPX_IMG_FMT_I440 = VPX_IMG_FMT_PLANAR | 7, - VPX_IMG_FMT_NV12 = VPX_IMG_FMT_PLANAR | 9, - VPX_IMG_FMT_I42016 = VPX_IMG_FMT_I420 | VPX_IMG_FMT_HIGHBITDEPTH, - VPX_IMG_FMT_I42216 = VPX_IMG_FMT_I422 | VPX_IMG_FMT_HIGHBITDEPTH, - VPX_IMG_FMT_I44416 = VPX_IMG_FMT_I444 | VPX_IMG_FMT_HIGHBITDEPTH, - VPX_IMG_FMT_I44016 = VPX_IMG_FMT_I440 | VPX_IMG_FMT_HIGHBITDEPTH -} vpx_img_fmt_t; /**< alias for enum vpx_img_fmt */ - -/*!\brief List of supported color spaces */ -typedef enum vpx_color_space { - VPX_CS_UNKNOWN = 0, /**< Unknown */ - VPX_CS_BT_601 = 1, /**< BT.601 */ - VPX_CS_BT_709 = 2, /**< BT.709 */ - VPX_CS_SMPTE_170 = 3, /**< SMPTE.170 */ - VPX_CS_SMPTE_240 = 4, /**< SMPTE.240 */ - VPX_CS_BT_2020 = 5, /**< BT.2020 */ - VPX_CS_RESERVED = 6, /**< Reserved */ - VPX_CS_SRGB = 7 /**< sRGB */ -} vpx_color_space_t; /**< alias for enum vpx_color_space */ - -/*!\brief List of supported color range */ -typedef enum vpx_color_range { - VPX_CR_STUDIO_RANGE = 0, /**<- Y [16..235], UV [16..240] (bit depth 8) */ - /**<- Y [64..940], UV [64..960] (bit depth 10) */ - /**<- Y [256..3760], UV [256..3840] (bit depth 12) */ - VPX_CR_FULL_RANGE = 1 /**<- YUV/RGB [0..255] (bit depth 8) */ - /**<- YUV/RGB [0..1023] (bit depth 10) */ - /**<- YUV/RGB [0..4095] (bit depth 12) */ -} vpx_color_range_t; /**< alias for enum vpx_color_range */ - -/**\brief Image Descriptor */ -typedef struct vpx_image { - vpx_img_fmt_t fmt; /**< Image Format */ - vpx_color_space_t cs; /**< Color Space */ - vpx_color_range_t range; /**< Color Range */ - - /* Image storage dimensions */ - unsigned int w; /**< Stored image width */ - unsigned int h; /**< Stored image height */ - unsigned int bit_depth; /**< Stored image bit-depth */ - - /* Image display dimensions */ - unsigned int d_w; /**< Displayed image width */ - unsigned int d_h; /**< Displayed image height */ - - /* Image intended rendering dimensions */ - unsigned int r_w; /**< Intended rendering image width */ - unsigned int r_h; /**< Intended rendering image height */ - - /* Chroma subsampling info */ - unsigned int x_chroma_shift; /**< subsampling order, X */ - unsigned int y_chroma_shift; /**< subsampling order, Y */ - -/* Image data pointers. */ -#define VPX_PLANE_PACKED 0 /**< To be used for all packed formats */ -#define VPX_PLANE_Y 0 /**< Y (Luminance) plane */ -#define VPX_PLANE_U 1 /**< U (Chroma) plane */ -#define VPX_PLANE_V 2 /**< V (Chroma) plane */ -#define VPX_PLANE_ALPHA 3 /**< A (Transparency) plane */ - unsigned char *planes[4]; /**< pointer to the top left pixel for each plane */ - int stride[4]; /**< stride between rows for each plane */ - - int bps; /**< bits per sample (for packed formats) */ - - /*!\brief The following member may be set by the application to associate - * data with this image. - */ - void *user_priv; - - /* The following members should be treated as private. */ - unsigned char *img_data; /**< private */ - int img_data_owner; /**< private */ - int self_allocd; /**< private */ - - void *fb_priv; /**< Frame buffer data associated with the image. */ -} vpx_image_t; /**< alias for struct vpx_image */ - -/**\brief Representation of a rectangle on a surface */ -typedef struct vpx_image_rect { - unsigned int x; /**< leftmost column */ - unsigned int y; /**< topmost row */ - unsigned int w; /**< width */ - unsigned int h; /**< height */ -} vpx_image_rect_t; /**< alias for struct vpx_image_rect */ - -/*!\brief Open a descriptor, allocating storage for the underlying image - * - * Returns a descriptor for storing an image of the given format. The - * storage for the descriptor is allocated on the heap. - * - * \param[in] img Pointer to storage for descriptor. If this parameter - * is NULL, the storage for the descriptor will be - * allocated on the heap. - * \param[in] fmt Format for the image - * \param[in] d_w Width of the image. Must not exceed 0x08000000 - * (2^27). - * \param[in] d_h Height of the image. Must not exceed 0x08000000 - * (2^27). - * \param[in] align Alignment, in bytes, of the image buffer and - * each row in the image (stride). Must not exceed - * 65536. - * - * \return Returns a pointer to the initialized image descriptor. If the img - * parameter is non-null, the value of the img parameter will be - * returned. - */ -vpx_image_t *vpx_img_alloc(vpx_image_t *img, vpx_img_fmt_t fmt, - unsigned int d_w, unsigned int d_h, - unsigned int align); - -/*!\brief Open a descriptor, using existing storage for the underlying image - * - * Returns a descriptor for storing an image of the given format. The - * storage for descriptor has been allocated elsewhere, and a descriptor is - * desired to "wrap" that storage. - * - * \param[in] img Pointer to storage for descriptor. If this - * parameter is NULL, the storage for the descriptor - * will be allocated on the heap. - * \param[in] fmt Format for the image - * \param[in] d_w Width of the image. Must not exceed 0x08000000 - * (2^27). - * \param[in] d_h Height of the image. Must not exceed 0x08000000 - * (2^27). - * \param[in] stride_align Alignment, in bytes, of each row in the image - * (stride). Must not exceed 65536. - * \param[in] img_data Storage to use for the image. The storage must - * outlive the returned image descriptor; it can be - * disposed of after calling vpx_img_free(). - * - * \return Returns a pointer to the initialized image descriptor. If the img - * parameter is non-null, the value of the img parameter will be - * returned. - */ -vpx_image_t *vpx_img_wrap(vpx_image_t *img, vpx_img_fmt_t fmt, unsigned int d_w, - unsigned int d_h, unsigned int stride_align, - unsigned char *img_data); - -/*!\brief Set the rectangle identifying the displayed portion of the image - * - * Updates the displayed rectangle (aka viewport) on the image surface to - * match the specified coordinates and size. Specifically, sets img->d_w, - * img->d_h, and elements of the img->planes[] array. - * - * \param[in] img Image descriptor - * \param[in] x leftmost column - * \param[in] y topmost row - * \param[in] w width - * \param[in] h height - * - * \return 0 if the requested rectangle is valid, nonzero (-1) otherwise. - */ -int vpx_img_set_rect(vpx_image_t *img, unsigned int x, unsigned int y, - unsigned int w, unsigned int h); - -/*!\brief Flip the image vertically (top for bottom) - * - * Adjusts the image descriptor's pointers and strides to make the image - * be referenced upside-down. - * - * \param[in] img Image descriptor - */ -void vpx_img_flip(vpx_image_t *img); - -/*!\brief Close an image descriptor - * - * Frees all allocated storage associated with an image descriptor. - * - * \param[in] img Image descriptor - */ -void vpx_img_free(vpx_image_t *img); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_VPX_IMAGE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_integer.h b/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_integer.h deleted file mode 100644 index 34e37964..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_integer.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_VPX_INTEGER_H_ -#define VPX_VPX_VPX_INTEGER_H_ - -/* get ptrdiff_t, size_t, wchar_t, NULL */ -#include // IWYU pragma: export - -#if defined(_MSC_VER) -#define VPX_FORCE_INLINE __forceinline -#define VPX_INLINE __inline -#else -#define VPX_FORCE_INLINE __inline__ __attribute__((always_inline)) -// TODO(jbb): Allow a way to force inline off for older compilers. -#define VPX_INLINE inline -#endif - -/* Assume platforms have the C99 standard integer types. */ - -#if defined(__cplusplus) -#if !defined(__STDC_FORMAT_MACROS) -#define __STDC_FORMAT_MACROS -#endif -#if !defined(__STDC_LIMIT_MACROS) -#define __STDC_LIMIT_MACROS -#endif -#endif // __cplusplus - -#include // IWYU pragma: export -#include // IWYU pragma: export - -#endif // VPX_VPX_VPX_INTEGER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_tpl.h b/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_tpl.h deleted file mode 100644 index e14eefcd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx/vpx_tpl.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/*!\file - * \brief Describes the TPL stats descriptor and associated operations - * - */ -#ifndef VPX_VPX_VPX_TPL_H_ -#define VPX_VPX_VPX_TPL_H_ - -#include "./vpx_integer.h" -#include "./vpx_codec.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*!\brief Current ABI version number - * - * \internal - * If this file is altered in any way that changes the ABI, this value - * must be bumped. Examples include, but are not limited to, changing - * types, removing or reassigning enums, adding/removing/rearranging - * fields to structures - */ -#define VPX_TPL_ABI_VERSION 4 /**<\hideinitializer*/ - -/*!\brief Temporal dependency model stats for each block before propagation */ -typedef struct VpxTplBlockStats { - int16_t row; /**< Pixel row of the top left corner */ - int16_t col; /**< Pixel col of the top left corner */ - int64_t intra_cost; /**< Intra cost */ - int64_t inter_cost; /**< Inter cost */ - int16_t mv_r; /**< Motion vector row */ - int16_t mv_c; /**< Motion vector col */ - int64_t srcrf_rate; /**< Rate from source ref frame */ - int64_t srcrf_dist; /**< Distortion from source ref frame */ - int64_t inter_pred_err; /**< Inter prediction error */ - int64_t intra_pred_err; /**< Intra prediction error */ - int ref_frame_index; /**< Ref frame index in the ref frame buffer */ -} VpxTplBlockStats; - -/*!\brief Temporal dependency model stats for each frame before propagation */ -typedef struct VpxTplFrameStats { - int frame_width; /**< Frame width */ - int frame_height; /**< Frame height */ - int num_blocks; /**< Number of blocks. Size of block_stats_list */ - VpxTplBlockStats *block_stats_list; /**< List of tpl stats for each block */ -} VpxTplFrameStats; - -/*!\brief Temporal dependency model stats for each GOP before propagation */ -typedef struct VpxTplGopStats { - int size; /**< GOP size, also the size of frame_stats_list. */ - VpxTplFrameStats *frame_stats_list; /**< List of tpl stats for each frame */ -} VpxTplGopStats; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_VPX_TPL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/add_noise.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/add_noise.c deleted file mode 100644 index 6839e979..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/add_noise.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx/vpx_integer.h" -#include "vpx_dsp/postproc.h" -#include "vpx_ports/mem.h" - -void vpx_plane_add_noise_c(uint8_t *start, const int8_t *noise, int blackclamp, - int whiteclamp, int width, int height, int pitch) { - int i, j; - int bothclamp = blackclamp + whiteclamp; - for (i = 0; i < height; ++i) { - uint8_t *pos = start + i * pitch; - const int8_t *ref = (const int8_t *)(noise + (rand() & 0xff)); // NOLINT - - for (j = 0; j < width; ++j) { - int v = pos[j]; - - v = clamp(v - blackclamp, 0, 255); - v = clamp(v + bothclamp, 0, 255); - v = clamp(v - whiteclamp, 0, 255); - - pos[j] = v + ref[j]; - } - } -} - -static double gaussian(double sigma, double mu, double x) { - return 1 / (sigma * sqrt(2.0 * 3.14159265)) * - (exp(-(x - mu) * (x - mu) / (2 * sigma * sigma))); -} - -int vpx_setup_noise(double sigma, int8_t *noise, int size) { - int8_t char_dist[256]; - int next = 0, i, j; - - // set up a 256 entry lookup that matches gaussian distribution - for (i = -32; i < 32; ++i) { - const int a_i = (int)(0.5 + 256 * gaussian(sigma, 0, i)); - if (a_i) { - for (j = 0; j < a_i; ++j) { - if (next + j >= 256) goto set_noise; - char_dist[next + j] = (int8_t)i; - } - next = next + j; - } - } - - // Rounding error - might mean we have less than 256. - for (; next < 256; ++next) { - char_dist[next] = 0; - } - -set_noise: - for (i = 0; i < size; ++i) { - noise[i] = char_dist[rand() & 0xff]; // NOLINT - } - - // Returns the highest non 0 value used in distribution. - return -char_dist[0]; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/avg_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/avg_neon.c deleted file mode 100644 index 1b17a326..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/avg_neon.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "./vpx_config.h" - -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" - -uint32_t vpx_avg_4x4_neon(const uint8_t *a, int a_stride) { - const uint8x16_t b = load_unaligned_u8q(a, a_stride); - const uint16x8_t c = vaddl_u8(vget_low_u8(b), vget_high_u8(b)); - return (horizontal_add_uint16x8(c) + (1 << 3)) >> 4; -} - -uint32_t vpx_avg_8x8_neon(const uint8_t *a, int a_stride) { - int i; - uint8x8_t b, c; - uint16x8_t sum; - b = vld1_u8(a); - a += a_stride; - c = vld1_u8(a); - a += a_stride; - sum = vaddl_u8(b, c); - - for (i = 0; i < 6; ++i) { - const uint8x8_t d = vld1_u8(a); - a += a_stride; - sum = vaddw_u8(sum, d); - } - - return (horizontal_add_uint16x8(sum) + (1 << 5)) >> 6; -} - -// coeff: 16 bits, dynamic range [-32640, 32640]. -// length: value range {16, 64, 256, 1024}. -// satd: 26 bits, dynamic range [-32640 * 1024, 32640 * 1024] -int vpx_satd_neon(const tran_low_t *coeff, int length) { - int32x4_t sum_s32[2] = { vdupq_n_s32(0), vdupq_n_s32(0) }; - - do { - int16x8_t abs0, abs1; - const int16x8_t s0 = load_tran_low_to_s16q(coeff); - const int16x8_t s1 = load_tran_low_to_s16q(coeff + 8); - - abs0 = vabsq_s16(s0); - sum_s32[0] = vpadalq_s16(sum_s32[0], abs0); - abs1 = vabsq_s16(s1); - sum_s32[1] = vpadalq_s16(sum_s32[1], abs1); - - length -= 16; - coeff += 16; - } while (length != 0); - - return horizontal_add_int32x4(vaddq_s32(sum_s32[0], sum_s32[1])); -} - -void vpx_int_pro_row_neon(int16_t hbuf[16], uint8_t const *ref, - const int ref_stride, const int height) { - int i; - uint8x16_t r0, r1, r2, r3; - uint16x8_t sum_lo[2], sum_hi[2]; - uint16x8_t tmp_lo[2], tmp_hi[2]; - int16x8_t avg_lo, avg_hi; - - const int norm_factor = (height >> 5) + 3; - const int16x8_t neg_norm_factor = vdupq_n_s16(-norm_factor); - - assert(height >= 4 && height % 4 == 0); - - r0 = vld1q_u8(ref + 0 * ref_stride); - r1 = vld1q_u8(ref + 1 * ref_stride); - r2 = vld1q_u8(ref + 2 * ref_stride); - r3 = vld1q_u8(ref + 3 * ref_stride); - - sum_lo[0] = vaddl_u8(vget_low_u8(r0), vget_low_u8(r1)); - sum_hi[0] = vaddl_u8(vget_high_u8(r0), vget_high_u8(r1)); - sum_lo[1] = vaddl_u8(vget_low_u8(r2), vget_low_u8(r3)); - sum_hi[1] = vaddl_u8(vget_high_u8(r2), vget_high_u8(r3)); - - ref += 4 * ref_stride; - - for (i = 4; i < height; i += 4) { - r0 = vld1q_u8(ref + 0 * ref_stride); - r1 = vld1q_u8(ref + 1 * ref_stride); - r2 = vld1q_u8(ref + 2 * ref_stride); - r3 = vld1q_u8(ref + 3 * ref_stride); - - tmp_lo[0] = vaddl_u8(vget_low_u8(r0), vget_low_u8(r1)); - tmp_hi[0] = vaddl_u8(vget_high_u8(r0), vget_high_u8(r1)); - tmp_lo[1] = vaddl_u8(vget_low_u8(r2), vget_low_u8(r3)); - tmp_hi[1] = vaddl_u8(vget_high_u8(r2), vget_high_u8(r3)); - - sum_lo[0] = vaddq_u16(sum_lo[0], tmp_lo[0]); - sum_hi[0] = vaddq_u16(sum_hi[0], tmp_hi[0]); - sum_lo[1] = vaddq_u16(sum_lo[1], tmp_lo[1]); - sum_hi[1] = vaddq_u16(sum_hi[1], tmp_hi[1]); - - ref += 4 * ref_stride; - } - - sum_lo[0] = vaddq_u16(sum_lo[0], sum_lo[1]); - sum_hi[0] = vaddq_u16(sum_hi[0], sum_hi[1]); - - avg_lo = vshlq_s16(vreinterpretq_s16_u16(sum_lo[0]), neg_norm_factor); - avg_hi = vshlq_s16(vreinterpretq_s16_u16(sum_hi[0]), neg_norm_factor); - - vst1q_s16(hbuf, avg_lo); - vst1q_s16(hbuf + 8, avg_hi); -} - -int16_t vpx_int_pro_col_neon(uint8_t const *ref, const int width) { - uint16x8_t sum; - int i; - - assert(width >= 16 && width % 16 == 0); - - sum = vpaddlq_u8(vld1q_u8(ref)); - for (i = 16; i < width; i += 16) { - sum = vpadalq_u8(sum, vld1q_u8(ref + i)); - } - - return (int16_t)horizontal_add_uint16x8(sum); -} - -// ref, src = [0, 510] - max diff = 16-bits -// bwl = {2, 3, 4}, width = {16, 32, 64} -int vpx_vector_var_neon(int16_t const *ref, int16_t const *src, const int bwl) { - int width = 4 << bwl; - int32x4_t sse = vdupq_n_s32(0); - int16x8_t total = vdupq_n_s16(0); - - assert(width >= 8); - assert((width % 8) == 0); - - do { - const int16x8_t r = vld1q_s16(ref); - const int16x8_t s = vld1q_s16(src); - const int16x8_t diff = vsubq_s16(r, s); // [-510, 510], 10 bits. - const int16x4_t diff_lo = vget_low_s16(diff); - const int16x4_t diff_hi = vget_high_s16(diff); - sse = vmlal_s16(sse, diff_lo, diff_lo); // dynamic range 26 bits. - sse = vmlal_s16(sse, diff_hi, diff_hi); - total = vaddq_s16(total, diff); // dynamic range 16 bits. - - ref += 8; - src += 8; - width -= 8; - } while (width != 0); - - { - // Note: 'total''s pairwise addition could be implemented similarly to - // horizontal_add_uint16x8(), but one less vpaddl with 'total' when paired - // with the summation of 'sse' performed better on a Cortex-A15. - const int32x4_t t0 = vpaddlq_s16(total); // cascading summation of 'total' - const int32x2_t t1 = vadd_s32(vget_low_s32(t0), vget_high_s32(t0)); - const int32x2_t t2 = vpadd_s32(t1, t1); - const int t = vget_lane_s32(t2, 0); - const int64x2_t s0 = vpaddlq_s32(sse); // cascading summation of 'sse'. - const int32x2_t s1 = vadd_s32(vreinterpret_s32_s64(vget_low_s64(s0)), - vreinterpret_s32_s64(vget_high_s64(s0))); - const int s = vget_lane_s32(s1, 0); - const int shift_factor = bwl + 2; - return s - ((t * t) >> shift_factor); - } -} - -void vpx_minmax_8x8_neon(const uint8_t *a, int a_stride, const uint8_t *b, - int b_stride, int *min, int *max) { - // Load and concatenate. - const uint8x16_t a01 = vcombine_u8(vld1_u8(a), vld1_u8(a + a_stride)); - const uint8x16_t a23 = - vcombine_u8(vld1_u8(a + 2 * a_stride), vld1_u8(a + 3 * a_stride)); - const uint8x16_t a45 = - vcombine_u8(vld1_u8(a + 4 * a_stride), vld1_u8(a + 5 * a_stride)); - const uint8x16_t a67 = - vcombine_u8(vld1_u8(a + 6 * a_stride), vld1_u8(a + 7 * a_stride)); - - const uint8x16_t b01 = vcombine_u8(vld1_u8(b), vld1_u8(b + b_stride)); - const uint8x16_t b23 = - vcombine_u8(vld1_u8(b + 2 * b_stride), vld1_u8(b + 3 * b_stride)); - const uint8x16_t b45 = - vcombine_u8(vld1_u8(b + 4 * b_stride), vld1_u8(b + 5 * b_stride)); - const uint8x16_t b67 = - vcombine_u8(vld1_u8(b + 6 * b_stride), vld1_u8(b + 7 * b_stride)); - - // Absolute difference. - const uint8x16_t ab01_diff = vabdq_u8(a01, b01); - const uint8x16_t ab23_diff = vabdq_u8(a23, b23); - const uint8x16_t ab45_diff = vabdq_u8(a45, b45); - const uint8x16_t ab67_diff = vabdq_u8(a67, b67); - - // Max values between the Q vectors. - const uint8x16_t ab0123_max = vmaxq_u8(ab01_diff, ab23_diff); - const uint8x16_t ab4567_max = vmaxq_u8(ab45_diff, ab67_diff); - const uint8x16_t ab0123_min = vminq_u8(ab01_diff, ab23_diff); - const uint8x16_t ab4567_min = vminq_u8(ab45_diff, ab67_diff); - - const uint8x16_t ab07_max = vmaxq_u8(ab0123_max, ab4567_max); - const uint8x16_t ab07_min = vminq_u8(ab0123_min, ab4567_min); - -#if VPX_ARCH_AARCH64 - *min = *max = 0; // Clear high bits - *((uint8_t *)max) = vmaxvq_u8(ab07_max); - *((uint8_t *)min) = vminvq_u8(ab07_min); -#else - // Split into 64-bit vectors and execute pairwise min/max. - uint8x8_t ab_max = vmax_u8(vget_high_u8(ab07_max), vget_low_u8(ab07_max)); - uint8x8_t ab_min = vmin_u8(vget_high_u8(ab07_min), vget_low_u8(ab07_min)); - - // Enough runs of vpmax/min propagate the max/min values to every position. - ab_max = vpmax_u8(ab_max, ab_max); - ab_min = vpmin_u8(ab_min, ab_min); - - ab_max = vpmax_u8(ab_max, ab_max); - ab_min = vpmin_u8(ab_min, ab_min); - - ab_max = vpmax_u8(ab_max, ab_max); - ab_min = vpmin_u8(ab_min, ab_min); - - *min = *max = 0; // Clear high bits - // Store directly to avoid costly neon->gpr transfer. - vst1_lane_u8((uint8_t *)max, ab_max, 0); - vst1_lane_u8((uint8_t *)min, ab_min, 0); -#endif -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/avg_pred_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/avg_pred_neon.c deleted file mode 100644 index 5afdece0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/avg_pred_neon.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/mem_neon.h" - -void vpx_comp_avg_pred_neon(uint8_t *comp, const uint8_t *pred, int width, - int height, const uint8_t *ref, int ref_stride) { - if (width > 8) { - int x, y = height; - do { - for (x = 0; x < width; x += 16) { - const uint8x16_t p = vld1q_u8(pred + x); - const uint8x16_t r = vld1q_u8(ref + x); - const uint8x16_t avg = vrhaddq_u8(p, r); - vst1q_u8(comp + x, avg); - } - comp += width; - pred += width; - ref += ref_stride; - } while (--y); - } else if (width == 8) { - int i = width * height; - do { - const uint8x16_t p = vld1q_u8(pred); - uint8x16_t r; - const uint8x8_t r_0 = vld1_u8(ref); - const uint8x8_t r_1 = vld1_u8(ref + ref_stride); - r = vcombine_u8(r_0, r_1); - ref += 2 * ref_stride; - r = vrhaddq_u8(r, p); - vst1q_u8(comp, r); - - pred += 16; - comp += 16; - i -= 16; - } while (i); - } else { - int i = width * height; - assert(width == 4); - do { - const uint8x16_t p = vld1q_u8(pred); - uint8x16_t r; - - r = load_unaligned_u8q(ref, ref_stride); - ref += 4 * ref_stride; - r = vrhaddq_u8(r, p); - vst1q_u8(comp, r); - - pred += 16; - comp += 16; - i -= 16; - } while (i); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/deblock_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/deblock_neon.c deleted file mode 100644 index 7efce327..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/deblock_neon.c +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/transpose_neon.h" - -extern const int16_t vpx_rv[]; - -static uint8x8_t average_k_out(const uint8x8_t a2, const uint8x8_t a1, - const uint8x8_t v0, const uint8x8_t b1, - const uint8x8_t b2) { - const uint8x8_t k1 = vrhadd_u8(a2, a1); - const uint8x8_t k2 = vrhadd_u8(b2, b1); - const uint8x8_t k3 = vrhadd_u8(k1, k2); - return vrhadd_u8(k3, v0); -} - -static uint8x8_t generate_mask(const uint8x8_t a2, const uint8x8_t a1, - const uint8x8_t v0, const uint8x8_t b1, - const uint8x8_t b2, const uint8x8_t filter) { - const uint8x8_t a2_v0 = vabd_u8(a2, v0); - const uint8x8_t a1_v0 = vabd_u8(a1, v0); - const uint8x8_t b1_v0 = vabd_u8(b1, v0); - const uint8x8_t b2_v0 = vabd_u8(b2, v0); - - uint8x8_t max = vmax_u8(a2_v0, a1_v0); - max = vmax_u8(b1_v0, max); - max = vmax_u8(b2_v0, max); - return vclt_u8(max, filter); -} - -static uint8x8_t generate_output(const uint8x8_t a2, const uint8x8_t a1, - const uint8x8_t v0, const uint8x8_t b1, - const uint8x8_t b2, const uint8x8_t filter) { - const uint8x8_t k_out = average_k_out(a2, a1, v0, b1, b2); - const uint8x8_t mask = generate_mask(a2, a1, v0, b1, b2, filter); - - return vbsl_u8(mask, k_out, v0); -} - -// Same functions but for uint8x16_t. -static uint8x16_t average_k_outq(const uint8x16_t a2, const uint8x16_t a1, - const uint8x16_t v0, const uint8x16_t b1, - const uint8x16_t b2) { - const uint8x16_t k1 = vrhaddq_u8(a2, a1); - const uint8x16_t k2 = vrhaddq_u8(b2, b1); - const uint8x16_t k3 = vrhaddq_u8(k1, k2); - return vrhaddq_u8(k3, v0); -} - -static uint8x16_t generate_maskq(const uint8x16_t a2, const uint8x16_t a1, - const uint8x16_t v0, const uint8x16_t b1, - const uint8x16_t b2, const uint8x16_t filter) { - const uint8x16_t a2_v0 = vabdq_u8(a2, v0); - const uint8x16_t a1_v0 = vabdq_u8(a1, v0); - const uint8x16_t b1_v0 = vabdq_u8(b1, v0); - const uint8x16_t b2_v0 = vabdq_u8(b2, v0); - - uint8x16_t max = vmaxq_u8(a2_v0, a1_v0); - max = vmaxq_u8(b1_v0, max); - max = vmaxq_u8(b2_v0, max); - return vcltq_u8(max, filter); -} - -static uint8x16_t generate_outputq(const uint8x16_t a2, const uint8x16_t a1, - const uint8x16_t v0, const uint8x16_t b1, - const uint8x16_t b2, - const uint8x16_t filter) { - const uint8x16_t k_out = average_k_outq(a2, a1, v0, b1, b2); - const uint8x16_t mask = generate_maskq(a2, a1, v0, b1, b2, filter); - - return vbslq_u8(mask, k_out, v0); -} - -void vpx_post_proc_down_and_across_mb_row_neon(uint8_t *src_ptr, - uint8_t *dst_ptr, int src_stride, - int dst_stride, int cols, - uint8_t *f, int size) { - uint8_t *src, *dst; - int row; - int col; - - // While columns of length 16 can be processed, load them. - for (col = 0; col < cols - 8; col += 16) { - uint8x16_t a0, a1, a2, a3, a4, a5, a6, a7; - src = src_ptr - 2 * src_stride; - dst = dst_ptr; - - a0 = vld1q_u8(src); - src += src_stride; - a1 = vld1q_u8(src); - src += src_stride; - a2 = vld1q_u8(src); - src += src_stride; - a3 = vld1q_u8(src); - src += src_stride; - - for (row = 0; row < size; row += 4) { - uint8x16_t v_out_0, v_out_1, v_out_2, v_out_3; - const uint8x16_t filterq = vld1q_u8(f + col); - - a4 = vld1q_u8(src); - src += src_stride; - a5 = vld1q_u8(src); - src += src_stride; - a6 = vld1q_u8(src); - src += src_stride; - a7 = vld1q_u8(src); - src += src_stride; - - v_out_0 = generate_outputq(a0, a1, a2, a3, a4, filterq); - v_out_1 = generate_outputq(a1, a2, a3, a4, a5, filterq); - v_out_2 = generate_outputq(a2, a3, a4, a5, a6, filterq); - v_out_3 = generate_outputq(a3, a4, a5, a6, a7, filterq); - - vst1q_u8(dst, v_out_0); - dst += dst_stride; - vst1q_u8(dst, v_out_1); - dst += dst_stride; - vst1q_u8(dst, v_out_2); - dst += dst_stride; - vst1q_u8(dst, v_out_3); - dst += dst_stride; - - // Rotate over to the next slot. - a0 = a4; - a1 = a5; - a2 = a6; - a3 = a7; - } - - src_ptr += 16; - dst_ptr += 16; - } - - // Clean up any left over column of length 8. - if (col != cols) { - uint8x8_t a0, a1, a2, a3, a4, a5, a6, a7; - src = src_ptr - 2 * src_stride; - dst = dst_ptr; - - a0 = vld1_u8(src); - src += src_stride; - a1 = vld1_u8(src); - src += src_stride; - a2 = vld1_u8(src); - src += src_stride; - a3 = vld1_u8(src); - src += src_stride; - - for (row = 0; row < size; row += 4) { - uint8x8_t v_out_0, v_out_1, v_out_2, v_out_3; - const uint8x8_t filter = vld1_u8(f + col); - - a4 = vld1_u8(src); - src += src_stride; - a5 = vld1_u8(src); - src += src_stride; - a6 = vld1_u8(src); - src += src_stride; - a7 = vld1_u8(src); - src += src_stride; - - v_out_0 = generate_output(a0, a1, a2, a3, a4, filter); - v_out_1 = generate_output(a1, a2, a3, a4, a5, filter); - v_out_2 = generate_output(a2, a3, a4, a5, a6, filter); - v_out_3 = generate_output(a3, a4, a5, a6, a7, filter); - - vst1_u8(dst, v_out_0); - dst += dst_stride; - vst1_u8(dst, v_out_1); - dst += dst_stride; - vst1_u8(dst, v_out_2); - dst += dst_stride; - vst1_u8(dst, v_out_3); - dst += dst_stride; - - // Rotate over to the next slot. - a0 = a4; - a1 = a5; - a2 = a6; - a3 = a7; - } - - // Not strictly necessary but makes resetting dst_ptr easier. - dst_ptr += 8; - } - - dst_ptr -= cols; - - for (row = 0; row < size; row += 8) { - uint8x8_t a0, a1, a2, a3; - uint8x8_t b0, b1, b2, b3, b4, b5, b6, b7; - - src = dst_ptr; - dst = dst_ptr; - - // Load 8 values, transpose 4 of them, and discard 2 because they will be - // reloaded later. - load_and_transpose_u8_4x8(src, dst_stride, &a0, &a1, &a2, &a3); - a3 = a1; - a2 = a1 = a0; // Extend left border. - - src += 2; - - for (col = 0; col < cols; col += 8) { - uint8x8_t v_out_0, v_out_1, v_out_2, v_out_3, v_out_4, v_out_5, v_out_6, - v_out_7; - // Although the filter is meant to be applied vertically and is instead - // being applied horizontally here it's OK because it's set in blocks of 8 - // (or 16). - const uint8x8_t filter = vld1_u8(f + col); - - load_and_transpose_u8_8x8(src, dst_stride, &b0, &b1, &b2, &b3, &b4, &b5, - &b6, &b7); - - if (col + 8 == cols) { - // Last row. Extend border (b5). - b6 = b7 = b5; - } - - v_out_0 = generate_output(a0, a1, a2, a3, b0, filter); - v_out_1 = generate_output(a1, a2, a3, b0, b1, filter); - v_out_2 = generate_output(a2, a3, b0, b1, b2, filter); - v_out_3 = generate_output(a3, b0, b1, b2, b3, filter); - v_out_4 = generate_output(b0, b1, b2, b3, b4, filter); - v_out_5 = generate_output(b1, b2, b3, b4, b5, filter); - v_out_6 = generate_output(b2, b3, b4, b5, b6, filter); - v_out_7 = generate_output(b3, b4, b5, b6, b7, filter); - - transpose_and_store_u8_8x8(dst, dst_stride, v_out_0, v_out_1, v_out_2, - v_out_3, v_out_4, v_out_5, v_out_6, v_out_7); - - a0 = b4; - a1 = b5; - a2 = b6; - a3 = b7; - - src += 8; - dst += 8; - } - - dst_ptr += 8 * dst_stride; - } -} - -// sum += x; -// sumsq += x * y; -static void accumulate_sum_sumsq(const int16x4_t x, const int32x4_t xy, - int16x4_t *const sum, int32x4_t *const sumsq) { - const int16x4_t zero = vdup_n_s16(0); - const int32x4_t zeroq = vdupq_n_s32(0); - - // Add in the first set because vext doesn't work with '0'. - *sum = vadd_s16(*sum, x); - *sumsq = vaddq_s32(*sumsq, xy); - - // Shift x and xy to the right and sum. vext requires an immediate. - *sum = vadd_s16(*sum, vext_s16(zero, x, 1)); - *sumsq = vaddq_s32(*sumsq, vextq_s32(zeroq, xy, 1)); - - *sum = vadd_s16(*sum, vext_s16(zero, x, 2)); - *sumsq = vaddq_s32(*sumsq, vextq_s32(zeroq, xy, 2)); - - *sum = vadd_s16(*sum, vext_s16(zero, x, 3)); - *sumsq = vaddq_s32(*sumsq, vextq_s32(zeroq, xy, 3)); -} - -// Generate mask based on (sumsq * 15 - sum * sum < flimit) -static uint16x4_t calculate_mask(const int16x4_t sum, const int32x4_t sumsq, - const int32x4_t f, const int32x4_t fifteen) { - const int32x4_t a = vmulq_s32(sumsq, fifteen); - const int32x4_t b = vmlsl_s16(a, sum, sum); - const uint32x4_t mask32 = vcltq_s32(b, f); - return vmovn_u32(mask32); -} - -static uint8x8_t combine_mask(const int16x4_t sum_low, const int16x4_t sum_high, - const int32x4_t sumsq_low, - const int32x4_t sumsq_high, const int32x4_t f) { - const int32x4_t fifteen = vdupq_n_s32(15); - const uint16x4_t mask16_low = calculate_mask(sum_low, sumsq_low, f, fifteen); - const uint16x4_t mask16_high = - calculate_mask(sum_high, sumsq_high, f, fifteen); - return vmovn_u16(vcombine_u16(mask16_low, mask16_high)); -} - -// Apply filter of (8 + sum + s[c]) >> 4. -static uint8x8_t filter_pixels(const int16x8_t sum, const uint8x8_t s) { - const int16x8_t s16 = vreinterpretq_s16_u16(vmovl_u8(s)); - const int16x8_t sum_s = vaddq_s16(sum, s16); - - return vqrshrun_n_s16(sum_s, 4); -} - -void vpx_mbpost_proc_across_ip_neon(uint8_t *src, int pitch, int rows, int cols, - int flimit) { - int row, col; - const int32x4_t f = vdupq_n_s32(flimit); - - assert(cols % 8 == 0); - - for (row = 0; row < rows; ++row) { - // Sum the first 8 elements, which are extended from s[0]. - // sumsq gets primed with +16. - int sumsq = src[0] * src[0] * 9 + 16; - int sum = src[0] * 9; - - uint8x8_t left_context, s, right_context; - int16x4_t sum_low, sum_high; - int32x4_t sumsq_low, sumsq_high; - - // Sum (+square) the next 6 elements. - // Skip [0] because it's included above. - for (col = 1; col <= 6; ++col) { - sumsq += src[col] * src[col]; - sum += src[col]; - } - - // Prime the sums. Later the loop uses the _high values to prime the new - // vectors. - sumsq_high = vdupq_n_s32(sumsq); - sum_high = vdup_n_s16(sum); - - // Manually extend the left border. - left_context = vdup_n_u8(src[0]); - - for (col = 0; col < cols; col += 8) { - uint8x8_t mask, output; - int16x8_t x, y; - int32x4_t xy_low, xy_high; - - s = vld1_u8(src + col); - - if (col + 8 == cols) { - // Last row. Extend border. - right_context = vdup_n_u8(src[col + 7]); - } else { - right_context = vld1_u8(src + col + 7); - } - - x = vreinterpretq_s16_u16(vsubl_u8(right_context, left_context)); - y = vreinterpretq_s16_u16(vaddl_u8(right_context, left_context)); - xy_low = vmull_s16(vget_low_s16(x), vget_low_s16(y)); - xy_high = vmull_s16(vget_high_s16(x), vget_high_s16(y)); - - // Catch up to the last sum'd value. - sum_low = vdup_lane_s16(sum_high, 3); - sumsq_low = vdupq_lane_s32(vget_high_s32(sumsq_high), 1); - - accumulate_sum_sumsq(vget_low_s16(x), xy_low, &sum_low, &sumsq_low); - - // Need to do this sequentially because we need the max value from - // sum_low. - sum_high = vdup_lane_s16(sum_low, 3); - sumsq_high = vdupq_lane_s32(vget_high_s32(sumsq_low), 1); - - accumulate_sum_sumsq(vget_high_s16(x), xy_high, &sum_high, &sumsq_high); - - mask = combine_mask(sum_low, sum_high, sumsq_low, sumsq_high, f); - - output = filter_pixels(vcombine_s16(sum_low, sum_high), s); - output = vbsl_u8(mask, output, s); - - vst1_u8(src + col, output); - - left_context = s; - } - - src += pitch; - } -} - -// Apply filter of (vpx_rv + sum + s[c]) >> 4. -static uint8x8_t filter_pixels_rv(const int16x8_t sum, const uint8x8_t s, - const int16x8_t rv) { - const int16x8_t s16 = vreinterpretq_s16_u16(vmovl_u8(s)); - const int16x8_t sum_s = vaddq_s16(sum, s16); - const int16x8_t rounded = vaddq_s16(sum_s, rv); - - return vqshrun_n_s16(rounded, 4); -} - -void vpx_mbpost_proc_down_neon(uint8_t *dst, int pitch, int rows, int cols, - int flimit) { - int row, col, i; - const int32x4_t f = vdupq_n_s32(flimit); - uint8x8_t below_context = vdup_n_u8(0); - - // 8 columns are processed at a time. - // If rows is less than 8 the bottom border extension fails. - assert(cols % 8 == 0); - assert(rows >= 8); - - // Load and keep the first 8 values in memory. Process a vertical stripe that - // is 8 wide. - for (col = 0; col < cols; col += 8) { - uint8x8_t s, above_context[8]; - int16x8_t sum, sum_tmp; - int32x4_t sumsq_low, sumsq_high; - - // Load and extend the top border. - s = vld1_u8(dst); - for (i = 0; i < 8; i++) { - above_context[i] = s; - } - - sum_tmp = vreinterpretq_s16_u16(vmovl_u8(s)); - - // sum * 9 - sum = vmulq_n_s16(sum_tmp, 9); - - // (sum * 9) * sum == sum * sum * 9 - sumsq_low = vmull_s16(vget_low_s16(sum), vget_low_s16(sum_tmp)); - sumsq_high = vmull_s16(vget_high_s16(sum), vget_high_s16(sum_tmp)); - - // Load and discard the next 6 values to prime sum and sumsq. - for (i = 1; i <= 6; ++i) { - const uint8x8_t a = vld1_u8(dst + i * pitch); - const int16x8_t b = vreinterpretq_s16_u16(vmovl_u8(a)); - sum = vaddq_s16(sum, b); - - sumsq_low = vmlal_s16(sumsq_low, vget_low_s16(b), vget_low_s16(b)); - sumsq_high = vmlal_s16(sumsq_high, vget_high_s16(b), vget_high_s16(b)); - } - - for (row = 0; row < rows; ++row) { - uint8x8_t mask, output; - int16x8_t x, y; - int32x4_t xy_low, xy_high; - - s = vld1_u8(dst + row * pitch); - - // Extend the bottom border. - if (row + 7 < rows) { - below_context = vld1_u8(dst + (row + 7) * pitch); - } - - x = vreinterpretq_s16_u16(vsubl_u8(below_context, above_context[0])); - y = vreinterpretq_s16_u16(vaddl_u8(below_context, above_context[0])); - xy_low = vmull_s16(vget_low_s16(x), vget_low_s16(y)); - xy_high = vmull_s16(vget_high_s16(x), vget_high_s16(y)); - - sum = vaddq_s16(sum, x); - - sumsq_low = vaddq_s32(sumsq_low, xy_low); - sumsq_high = vaddq_s32(sumsq_high, xy_high); - - mask = combine_mask(vget_low_s16(sum), vget_high_s16(sum), sumsq_low, - sumsq_high, f); - - output = filter_pixels_rv(sum, s, vld1q_s16(vpx_rv + (row & 127))); - output = vbsl_u8(mask, output, s); - - vst1_u8(dst + row * pitch, output); - - above_context[0] = above_context[1]; - above_context[1] = above_context[2]; - above_context[2] = above_context[3]; - above_context[3] = above_context[4]; - above_context[4] = above_context[5]; - above_context[5] = above_context[6]; - above_context[6] = above_context[7]; - above_context[7] = s; - } - - dst += 8; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct16x16_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct16x16_neon.c deleted file mode 100644 index fde71ff3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct16x16_neon.c +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/txfm_common.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/arm/fdct16x16_neon.h" - -// Some builds of gcc 4.9.2 and .3 have trouble with some of the inline -// functions. -#if !defined(__clang__) && !defined(__ANDROID__) && defined(__GNUC__) && \ - __GNUC__ == 4 && __GNUC_MINOR__ == 9 && __GNUC_PATCHLEVEL__ < 4 - -void vpx_fdct16x16_neon(const int16_t *input, tran_low_t *output, int stride) { - vpx_fdct16x16_c(input, output, stride); -} - -#else - -// Main body of fdct16x16. -static void vpx_fdct8x16_body(const int16x8_t *in /*[16]*/, - int16x8_t *out /*[16]*/) { - int16x8_t s[8]; - int16x8_t x[4]; - int16x8_t step[8]; - - // stage 1 - // From fwd_txfm.c: Work on the first eight values; fdct8(input, - // even_results);" - s[0] = vaddq_s16(in[0], in[7]); - s[1] = vaddq_s16(in[1], in[6]); - s[2] = vaddq_s16(in[2], in[5]); - s[3] = vaddq_s16(in[3], in[4]); - s[4] = vsubq_s16(in[3], in[4]); - s[5] = vsubq_s16(in[2], in[5]); - s[6] = vsubq_s16(in[1], in[6]); - s[7] = vsubq_s16(in[0], in[7]); - - // fdct4(step, step); - x[0] = vaddq_s16(s[0], s[3]); - x[1] = vaddq_s16(s[1], s[2]); - x[2] = vsubq_s16(s[1], s[2]); - x[3] = vsubq_s16(s[0], s[3]); - - // out[0] = fdct_round_shift((x0 + x1) * cospi_16_64) - // out[8] = fdct_round_shift((x0 - x1) * cospi_16_64) - butterfly_one_coeff_s16_s32_fast_narrow(x[0], x[1], cospi_16_64, &out[0], - &out[8]); - // out[4] = fdct_round_shift(x3 * cospi_8_64 + x2 * cospi_24_64); - // out[12] = fdct_round_shift(x3 * cospi_24_64 - x2 * cospi_8_64); - butterfly_two_coeff(x[3], x[2], cospi_8_64, cospi_24_64, &out[4], &out[12]); - - // Stage 2 - // Re-using source s5/s6 - // s5 = fdct_round_shift((s6 - s5) * cospi_16_64) - // s6 = fdct_round_shift((s6 + s5) * cospi_16_64) - butterfly_one_coeff_s16_fast(s[6], s[5], cospi_16_64, &s[6], &s[5]); - - // Stage 3 - x[0] = vaddq_s16(s[4], s[5]); - x[1] = vsubq_s16(s[4], s[5]); - x[2] = vsubq_s16(s[7], s[6]); - x[3] = vaddq_s16(s[7], s[6]); - - // Stage 4 - // out[2] = fdct_round_shift(x3 * cospi_4_64 + x0 * cospi_28_64) - // out[14] = fdct_round_shift(x3 * cospi_28_64 - x0 * cospi_4_64) - butterfly_two_coeff(x[3], x[0], cospi_4_64, cospi_28_64, &out[2], &out[14]); - // out[6] = fdct_round_shift(x2 * cospi_20_64 + x1 * cospi_12_64) - // out[10] = fdct_round_shift(x2 * cospi_12_64 - x1 * cospi_20_64) - butterfly_two_coeff(x[2], x[1], cospi_20_64, cospi_12_64, &out[10], &out[6]); - - // step 2 - // From fwd_txfm.c: Work on the next eight values; step1 -> odd_results" - // That file distinguished between "in_high" and "step1" but the only - // difference is that "in_high" is the first 8 values and "step 1" is the - // second. Here, since they are all in one array, "step1" values are += 8. - - // step2[2] = fdct_round_shift((step1[5] - step1[2]) * cospi_16_64) - // step2[3] = fdct_round_shift((step1[4] - step1[3]) * cospi_16_64) - // step2[4] = fdct_round_shift((step1[4] + step1[3]) * cospi_16_64) - // step2[5] = fdct_round_shift((step1[5] + step1[2]) * cospi_16_64) - butterfly_one_coeff_s16_fast(in[13], in[10], cospi_16_64, &s[5], &s[2]); - butterfly_one_coeff_s16_fast(in[12], in[11], cospi_16_64, &s[4], &s[3]); - - // step 3 - s[0] = vaddq_s16(in[8], s[3]); - s[1] = vaddq_s16(in[9], s[2]); - x[0] = vsubq_s16(in[9], s[2]); - x[1] = vsubq_s16(in[8], s[3]); - x[2] = vsubq_s16(in[15], s[4]); - x[3] = vsubq_s16(in[14], s[5]); - s[6] = vaddq_s16(in[14], s[5]); - s[7] = vaddq_s16(in[15], s[4]); - - // step 4 - // step2[6] = fdct_round_shift(step3[6] * cospi_8_64 + step3[1] * - // cospi_24_64) step2[1] = fdct_round_shift(step3[6] * cospi_24_64 - step3[1] - // * cospi_8_64) - butterfly_two_coeff(s[6], s[1], cospi_8_64, cospi_24_64, &s[6], &s[1]); - - // step2[2] = fdct_round_shift(step3[2] * cospi_24_64 + step3[5] * cospi_8_64) - // step2[5] = fdct_round_shift(step3[2] * cospi_8_64 - step3[5] * - // cospi_24_64) - butterfly_two_coeff(x[0], x[3], cospi_24_64, cospi_8_64, &s[2], &s[5]); - - // step 5 - step[0] = vaddq_s16(s[0], s[1]); - step[1] = vsubq_s16(s[0], s[1]); - step[2] = vaddq_s16(x[1], s[2]); - step[3] = vsubq_s16(x[1], s[2]); - step[4] = vsubq_s16(x[2], s[5]); - step[5] = vaddq_s16(x[2], s[5]); - step[6] = vsubq_s16(s[7], s[6]); - step[7] = vaddq_s16(s[7], s[6]); - - // step 6 - // out[9] = fdct_round_shift(step1[6] * cospi_18_64 + step1[1] * cospi_14_64) - // out[7] = fdct_round_shift(step1[6] * cospi_14_64 - step1[1] * cospi_18_64) - butterfly_two_coeff(step[6], step[1], cospi_18_64, cospi_14_64, &out[9], - &out[7]); - // out[1] = fdct_round_shift(step1[7] * cospi_2_64 + step1[0] * cospi_30_64) - // out[15] = fdct_round_shift(step1[7] * cospi_30_64 - step1[0] * cospi_2_64) - butterfly_two_coeff(step[7], step[0], cospi_2_64, cospi_30_64, &out[1], - &out[15]); - - // out[13] = fdct_round_shift(step1[4] * cospi_26_64 + step1[3] * cospi_6_64) - // out[3] = fdct_round_shift(step1[4] * cospi_6_64 - step1[3] * cospi_26_64) - butterfly_two_coeff(step[4], step[3], cospi_26_64, cospi_6_64, &out[13], - &out[3]); - - // out[5] = fdct_round_shift(step1[5] * cospi_10_64 + step1[2] * cospi_22_64) - // out[11] = fdct_round_shift(step1[5] * cospi_22_64 - step1[2] * cospi_10_64) - butterfly_two_coeff(step[5], step[2], cospi_10_64, cospi_22_64, &out[5], - &out[11]); -} - -void vpx_fdct16x16_neon(const int16_t *input, tran_low_t *output, int stride) { - int16x8_t temp0[16]; - int16x8_t temp1[16]; - int16x8_t temp2[16]; - int16x8_t temp3[16]; - - // Left half. - load_cross(input, stride, temp0); - scale_input(temp0, temp1); - vpx_fdct8x16_body(temp1, temp0); - - // Right half. - load_cross(input + 8, stride, temp1); - scale_input(temp1, temp2); - vpx_fdct8x16_body(temp2, temp1); - - // Transpose top left and top right quarters into one contiguous location to - // process to the top half. - - transpose_s16_8x8q(&temp0[0], &temp2[0]); - transpose_s16_8x8q(&temp1[0], &temp2[8]); - partial_round_shift(temp2); - cross_input(temp2, temp3); - vpx_fdct8x16_body(temp3, temp2); - transpose_s16_8x8(&temp2[0], &temp2[1], &temp2[2], &temp2[3], &temp2[4], - &temp2[5], &temp2[6], &temp2[7]); - transpose_s16_8x8(&temp2[8], &temp2[9], &temp2[10], &temp2[11], &temp2[12], - &temp2[13], &temp2[14], &temp2[15]); - store(output, temp2); - store(output + 8, temp2 + 8); - output += 8 * 16; - - // Transpose bottom left and bottom right quarters into one contiguous - // location to process to the bottom half. - transpose_s16_8x8q(&temp0[8], &temp1[0]); - - transpose_s16_8x8(&temp1[8], &temp1[9], &temp1[10], &temp1[11], &temp1[12], - &temp1[13], &temp1[14], &temp1[15]); - partial_round_shift(temp1); - cross_input(temp1, temp0); - vpx_fdct8x16_body(temp0, temp1); - transpose_s16_8x8(&temp1[0], &temp1[1], &temp1[2], &temp1[3], &temp1[4], - &temp1[5], &temp1[6], &temp1[7]); - transpose_s16_8x8(&temp1[8], &temp1[9], &temp1[10], &temp1[11], &temp1[12], - &temp1[13], &temp1[14], &temp1[15]); - store(output, temp1); - store(output + 8, temp1 + 8); -} - -#if CONFIG_VP9_HIGHBITDEPTH - -// Main body of fdct8x16 column -static void vpx_highbd_fdct8x16_body(int32x4_t *left /*[16]*/, - int32x4_t *right /* [16] */) { - int32x4_t sl[8]; - int32x4_t sr[8]; - int32x4_t xl[4]; - int32x4_t xr[4]; - int32x4_t inl[8]; - int32x4_t inr[8]; - int32x4_t stepl[8]; - int32x4_t stepr[8]; - - // stage 1 - // From fwd_txfm.c: Work on the first eight values; fdct8(input, - // even_results);" - sl[0] = vaddq_s32(left[0], left[7]); - sr[0] = vaddq_s32(right[0], right[7]); - sl[1] = vaddq_s32(left[1], left[6]); - sr[1] = vaddq_s32(right[1], right[6]); - sl[2] = vaddq_s32(left[2], left[5]); - sr[2] = vaddq_s32(right[2], right[5]); - sl[3] = vaddq_s32(left[3], left[4]); - sr[3] = vaddq_s32(right[3], right[4]); - sl[4] = vsubq_s32(left[3], left[4]); - sr[4] = vsubq_s32(right[3], right[4]); - sl[5] = vsubq_s32(left[2], left[5]); - sr[5] = vsubq_s32(right[2], right[5]); - sl[6] = vsubq_s32(left[1], left[6]); - sr[6] = vsubq_s32(right[1], right[6]); - sl[7] = vsubq_s32(left[0], left[7]); - sr[7] = vsubq_s32(right[0], right[7]); - - // Copy values 8-15 as we're storing in-place - inl[0] = left[8]; - inr[0] = right[8]; - inl[1] = left[9]; - inr[1] = right[9]; - inl[2] = left[10]; - inr[2] = right[10]; - inl[3] = left[11]; - inr[3] = right[11]; - inl[4] = left[12]; - inr[4] = right[12]; - inl[5] = left[13]; - inr[5] = right[13]; - inl[6] = left[14]; - inr[6] = right[14]; - inl[7] = left[15]; - inr[7] = right[15]; - - // fdct4(step, step); - xl[0] = vaddq_s32(sl[0], sl[3]); - xr[0] = vaddq_s32(sr[0], sr[3]); - xl[1] = vaddq_s32(sl[1], sl[2]); - xr[1] = vaddq_s32(sr[1], sr[2]); - xl[2] = vsubq_s32(sl[1], sl[2]); - xr[2] = vsubq_s32(sr[1], sr[2]); - xl[3] = vsubq_s32(sl[0], sl[3]); - xr[3] = vsubq_s32(sr[0], sr[3]); - - // out[0] = fdct_round_shift((x0 + x1) * cospi_16_64) - // out[8] = fdct_round_shift((x0 - x1) * cospi_16_64) - butterfly_one_coeff_s32_fast(xl[0], xr[0], xl[1], xr[1], cospi_16_64, - &left[0], &right[0], &left[8], &right[8]); - - // out[4] = fdct_round_shift(x3 * cospi_8_64 + x2 * cospi_24_64); - // out[12] = fdct_round_shift(x3 * cospi_24_64 - x2 * cospi_8_64); - butterfly_two_coeff_s32_s64_narrow(xl[3], xr[3], xl[2], xr[2], cospi_8_64, - cospi_24_64, &left[4], &right[4], - &left[12], &right[12]); - - // Stage 2 - // Re-using source s5/s6 - // s5 = fdct_round_shift((s6 - s5) * cospi_16_64) - // s6 = fdct_round_shift((s6 + s5) * cospi_16_64) - butterfly_one_coeff_s32_fast(sl[6], sr[6], sl[5], sr[5], cospi_16_64, &sl[6], - &sr[6], &sl[5], &sr[5]); - - // Stage 3 - xl[0] = vaddq_s32(sl[4], sl[5]); - xr[0] = vaddq_s32(sr[4], sr[5]); - xl[1] = vsubq_s32(sl[4], sl[5]); - xr[1] = vsubq_s32(sr[4], sr[5]); - xl[2] = vsubq_s32(sl[7], sl[6]); - xr[2] = vsubq_s32(sr[7], sr[6]); - xl[3] = vaddq_s32(sl[7], sl[6]); - xr[3] = vaddq_s32(sr[7], sr[6]); - - // Stage 4 - // out[2] = fdct_round_shift(x3 * cospi_4_64 + x0 * cospi_28_64) - // out[14] = fdct_round_shift(x3 * cospi_28_64 - x0 * cospi_4_64) - butterfly_two_coeff_s32_s64_narrow(xl[3], xr[3], xl[0], xr[0], cospi_4_64, - cospi_28_64, &left[2], &right[2], - &left[14], &right[14]); - // out[6] = fdct_round_shift(x2 * cospi_20_64 + x1 * cospi_12_64) - // out[10] = fdct_round_shift(x2 * cospi_12_64 - x1 * cospi_20_64) - butterfly_two_coeff_s32_s64_narrow(xl[2], xr[2], xl[1], xr[1], cospi_20_64, - cospi_12_64, &left[10], &right[10], - &left[6], &right[6]); - - // step 2 - // From fwd_txfm.c: Work on the next eight values; step1 -> odd_results" - // That file distinguished between "in_high" and "step1" but the only - // difference is that "in_high" is the first 8 values and "step 1" is the - // second. Here, since they are all in one array, "step1" values are += 8. - - // step2[2] = fdct_round_shift((step1[5] - step1[2]) * cospi_16_64) - // step2[3] = fdct_round_shift((step1[4] - step1[3]) * cospi_16_64) - // step2[4] = fdct_round_shift((step1[4] + step1[3]) * cospi_16_64) - // step2[5] = fdct_round_shift((step1[5] + step1[2]) * cospi_16_64) - butterfly_one_coeff_s32_fast(inl[5], inr[5], inl[2], inr[2], cospi_16_64, - &sl[5], &sr[5], &sl[2], &sr[2]); - butterfly_one_coeff_s32_fast(inl[4], inr[4], inl[3], inr[3], cospi_16_64, - &sl[4], &sr[4], &sl[3], &sr[3]); - - // step 3 - sl[0] = vaddq_s32(inl[0], sl[3]); - sr[0] = vaddq_s32(inr[0], sr[3]); - sl[1] = vaddq_s32(inl[1], sl[2]); - sr[1] = vaddq_s32(inr[1], sr[2]); - xl[0] = vsubq_s32(inl[1], sl[2]); - xr[0] = vsubq_s32(inr[1], sr[2]); - xl[1] = vsubq_s32(inl[0], sl[3]); - xr[1] = vsubq_s32(inr[0], sr[3]); - xl[2] = vsubq_s32(inl[7], sl[4]); - xr[2] = vsubq_s32(inr[7], sr[4]); - xl[3] = vsubq_s32(inl[6], sl[5]); - xr[3] = vsubq_s32(inr[6], sr[5]); - sl[6] = vaddq_s32(inl[6], sl[5]); - sr[6] = vaddq_s32(inr[6], sr[5]); - sl[7] = vaddq_s32(inl[7], sl[4]); - sr[7] = vaddq_s32(inr[7], sr[4]); - - // step 4 - // step2[6] = fdct_round_shift(step3[6] * cospi_8_64 + step3[1] * - // cospi_24_64) step2[1] = fdct_round_shift(step3[6] * cospi_24_64 - step3[1] - // * cospi_8_64) - butterfly_two_coeff_s32_s64_narrow(sl[6], sr[6], sl[1], sr[1], cospi_8_64, - cospi_24_64, &sl[6], &sr[6], &sl[1], - &sr[1]); - // step2[2] = fdct_round_shift(step3[2] * cospi_24_64 + step3[5] * cospi_8_64) - // step2[5] = fdct_round_shift(step3[2] * cospi_8_64 - step3[5] * - // cospi_24_64) - butterfly_two_coeff_s32_s64_narrow(xl[0], xr[0], xl[3], xr[3], cospi_24_64, - cospi_8_64, &sl[2], &sr[2], &sl[5], - &sr[5]); - - // step 5 - stepl[0] = vaddq_s32(sl[0], sl[1]); - stepr[0] = vaddq_s32(sr[0], sr[1]); - stepl[1] = vsubq_s32(sl[0], sl[1]); - stepr[1] = vsubq_s32(sr[0], sr[1]); - stepl[2] = vaddq_s32(xl[1], sl[2]); - stepr[2] = vaddq_s32(xr[1], sr[2]); - stepl[3] = vsubq_s32(xl[1], sl[2]); - stepr[3] = vsubq_s32(xr[1], sr[2]); - stepl[4] = vsubq_s32(xl[2], sl[5]); - stepr[4] = vsubq_s32(xr[2], sr[5]); - stepl[5] = vaddq_s32(xl[2], sl[5]); - stepr[5] = vaddq_s32(xr[2], sr[5]); - stepl[6] = vsubq_s32(sl[7], sl[6]); - stepr[6] = vsubq_s32(sr[7], sr[6]); - stepl[7] = vaddq_s32(sl[7], sl[6]); - stepr[7] = vaddq_s32(sr[7], sr[6]); - - // step 6 - // out[9] = fdct_round_shift(step1[6] * cospi_18_64 + step1[1] * cospi_14_64) - // out[7] = fdct_round_shift(step1[6] * cospi_14_64 - step1[1] * cospi_18_64) - butterfly_two_coeff_s32_s64_narrow(stepl[6], stepr[6], stepl[1], stepr[1], - cospi_18_64, cospi_14_64, &left[9], - &right[9], &left[7], &right[7]); - // out[1] = fdct_round_shift(step1[7] * cospi_2_64 + step1[0] * cospi_30_64) - // out[15] = fdct_round_shift(step1[7] * cospi_30_64 - step1[0] * cospi_2_64) - butterfly_two_coeff_s32_s64_narrow(stepl[7], stepr[7], stepl[0], stepr[0], - cospi_2_64, cospi_30_64, &left[1], - &right[1], &left[15], &right[15]); - // out[13] = fdct_round_shift(step1[4] * cospi_26_64 + step1[3] * cospi_6_64) - // out[3] = fdct_round_shift(step1[4] * cospi_6_64 - step1[3] * cospi_26_64) - butterfly_two_coeff_s32_s64_narrow(stepl[4], stepr[4], stepl[3], stepr[3], - cospi_26_64, cospi_6_64, &left[13], - &right[13], &left[3], &right[3]); - // out[5] = fdct_round_shift(step1[5] * cospi_10_64 + step1[2] * cospi_22_64) - // out[11] = fdct_round_shift(step1[5] * cospi_22_64 - step1[2] * cospi_10_64) - butterfly_two_coeff_s32_s64_narrow(stepl[5], stepr[5], stepl[2], stepr[2], - cospi_10_64, cospi_22_64, &left[5], - &right[5], &left[11], &right[11]); -} - -void vpx_highbd_fdct16x16_neon(const int16_t *input, tran_low_t *output, - int stride) { - int16x8_t temp0[16]; - int32x4_t left1[16], left2[16], left3[16], left4[16], right1[16], right2[16], - right3[16], right4[16]; - - // Left half. - load_cross(input, stride, temp0); - highbd_scale_input(temp0, left1, right1); - vpx_highbd_fdct8x16_body(left1, right1); - - // right half. - load_cross(input + 8, stride, temp0); - highbd_scale_input(temp0, left2, right2); - vpx_highbd_fdct8x16_body(left2, right2); - - // Transpose top left and top right quarters into one contiguous location to - // process to the top half. - - transpose_s32_8x8_2(left1, right1, left3, right3); - transpose_s32_8x8_2(left2, right2, left3 + 8, right3 + 8); - transpose_s32_8x8_2(left1 + 8, right1 + 8, left4, right4); - transpose_s32_8x8_2(left2 + 8, right2 + 8, left4 + 8, right4 + 8); - - highbd_partial_round_shift(left3, right3); - highbd_cross_input(left3, right3, left1, right1); - vpx_highbd_fdct8x16_body(left1, right1); - - // Transpose bottom left and bottom right quarters into one contiguous - // location to process to the bottom half. - - highbd_partial_round_shift(left4, right4); - highbd_cross_input(left4, right4, left2, right2); - vpx_highbd_fdct8x16_body(left2, right2); - - transpose_s32_8x8_2(left1, right1, left3, right3); - transpose_s32_8x8_2(left2, right2, left3 + 8, right3 + 8); - transpose_s32_8x8_2(left1 + 8, right1 + 8, left4, right4); - transpose_s32_8x8_2(left2 + 8, right2 + 8, left4 + 8, right4 + 8); - store16_s32(output, left3); - output += 4; - store16_s32(output, right3); - output += 4; - - store16_s32(output, left4); - output += 4; - store16_s32(output, right4); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -#endif // !defined(__clang__) && !defined(__ANDROID__) && defined(__GNUC__) && - // __GNUC__ == 4 && __GNUC_MINOR__ == 9 && __GNUC_PATCHLEVEL__ < 4 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct16x16_neon.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct16x16_neon.h deleted file mode 100644 index cd58675c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct16x16_neon.h +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_ARM_FDCT16X16_NEON_H_ -#define VPX_VPX_DSP_ARM_FDCT16X16_NEON_H_ - -#include - -#include "fdct_neon.h" - -static INLINE void load(const int16_t *a, int stride, int16x8_t *b /*[16]*/) { - b[0] = vld1q_s16(a); - a += stride; - b[1] = vld1q_s16(a); - a += stride; - b[2] = vld1q_s16(a); - a += stride; - b[3] = vld1q_s16(a); - a += stride; - b[4] = vld1q_s16(a); - a += stride; - b[5] = vld1q_s16(a); - a += stride; - b[6] = vld1q_s16(a); - a += stride; - b[7] = vld1q_s16(a); - a += stride; - b[8] = vld1q_s16(a); - a += stride; - b[9] = vld1q_s16(a); - a += stride; - b[10] = vld1q_s16(a); - a += stride; - b[11] = vld1q_s16(a); - a += stride; - b[12] = vld1q_s16(a); - a += stride; - b[13] = vld1q_s16(a); - a += stride; - b[14] = vld1q_s16(a); - a += stride; - b[15] = vld1q_s16(a); -} - -// Store 8 16x8 values, assuming stride == 16. -static INLINE void store(tran_low_t *a, const int16x8_t *b /*[8]*/) { - store_s16q_to_tran_low(a, b[0]); - a += 16; - store_s16q_to_tran_low(a, b[1]); - a += 16; - store_s16q_to_tran_low(a, b[2]); - a += 16; - store_s16q_to_tran_low(a, b[3]); - a += 16; - store_s16q_to_tran_low(a, b[4]); - a += 16; - store_s16q_to_tran_low(a, b[5]); - a += 16; - store_s16q_to_tran_low(a, b[6]); - a += 16; - store_s16q_to_tran_low(a, b[7]); -} - -// Load step of each pass. Add and subtract clear across the input, requiring -// all 16 values to be loaded. For the first pass it also multiplies by 4. - -// To maybe reduce register usage this could be combined with the load() step to -// get the first 4 and last 4 values, cross those, then load the middle 8 values -// and cross them. -static INLINE void scale_input(const int16x8_t *a /*[16]*/, - int16x8_t *b /*[16]*/) { - b[0] = vshlq_n_s16(a[0], 2); - b[1] = vshlq_n_s16(a[1], 2); - b[2] = vshlq_n_s16(a[2], 2); - b[3] = vshlq_n_s16(a[3], 2); - b[4] = vshlq_n_s16(a[4], 2); - b[5] = vshlq_n_s16(a[5], 2); - b[6] = vshlq_n_s16(a[6], 2); - b[7] = vshlq_n_s16(a[7], 2); - - b[8] = vshlq_n_s16(a[8], 2); - b[9] = vshlq_n_s16(a[9], 2); - b[10] = vshlq_n_s16(a[10], 2); - b[11] = vshlq_n_s16(a[11], 2); - b[12] = vshlq_n_s16(a[12], 2); - b[13] = vshlq_n_s16(a[13], 2); - b[14] = vshlq_n_s16(a[14], 2); - b[15] = vshlq_n_s16(a[15], 2); -} - -static INLINE void cross_input(const int16x8_t *a /*[16]*/, - int16x8_t *b /*[16]*/) { - b[0] = vaddq_s16(a[0], a[15]); - b[1] = vaddq_s16(a[1], a[14]); - b[2] = vaddq_s16(a[2], a[13]); - b[3] = vaddq_s16(a[3], a[12]); - b[4] = vaddq_s16(a[4], a[11]); - b[5] = vaddq_s16(a[5], a[10]); - b[6] = vaddq_s16(a[6], a[9]); - b[7] = vaddq_s16(a[7], a[8]); - - b[8] = vsubq_s16(a[7], a[8]); - b[9] = vsubq_s16(a[6], a[9]); - b[10] = vsubq_s16(a[5], a[10]); - b[11] = vsubq_s16(a[4], a[11]); - b[12] = vsubq_s16(a[3], a[12]); - b[13] = vsubq_s16(a[2], a[13]); - b[14] = vsubq_s16(a[1], a[14]); - b[15] = vsubq_s16(a[0], a[15]); -} - -static INLINE void load_cross(const int16_t *a, int stride, - int16x8_t *b /*[16]*/) { - b[0] = vaddq_s16(vld1q_s16(a + 0 * stride), vld1q_s16(a + 15 * stride)); - b[1] = vaddq_s16(vld1q_s16(a + 1 * stride), vld1q_s16(a + 14 * stride)); - b[2] = vaddq_s16(vld1q_s16(a + 2 * stride), vld1q_s16(a + 13 * stride)); - b[3] = vaddq_s16(vld1q_s16(a + 3 * stride), vld1q_s16(a + 12 * stride)); - b[4] = vaddq_s16(vld1q_s16(a + 4 * stride), vld1q_s16(a + 11 * stride)); - b[5] = vaddq_s16(vld1q_s16(a + 5 * stride), vld1q_s16(a + 10 * stride)); - b[6] = vaddq_s16(vld1q_s16(a + 6 * stride), vld1q_s16(a + 9 * stride)); - b[7] = vaddq_s16(vld1q_s16(a + 7 * stride), vld1q_s16(a + 8 * stride)); - - b[8] = vsubq_s16(vld1q_s16(a + 7 * stride), vld1q_s16(a + 8 * stride)); - b[9] = vsubq_s16(vld1q_s16(a + 6 * stride), vld1q_s16(a + 9 * stride)); - b[10] = vsubq_s16(vld1q_s16(a + 5 * stride), vld1q_s16(a + 10 * stride)); - b[11] = vsubq_s16(vld1q_s16(a + 4 * stride), vld1q_s16(a + 11 * stride)); - b[12] = vsubq_s16(vld1q_s16(a + 3 * stride), vld1q_s16(a + 12 * stride)); - b[13] = vsubq_s16(vld1q_s16(a + 2 * stride), vld1q_s16(a + 13 * stride)); - b[14] = vsubq_s16(vld1q_s16(a + 1 * stride), vld1q_s16(a + 14 * stride)); - b[15] = vsubq_s16(vld1q_s16(a + 0 * stride), vld1q_s16(a + 15 * stride)); -} - -// Quarter round at the beginning of the second pass. Can't use vrshr (rounding) -// because this only adds 1, not 1 << 2. -static INLINE void partial_round_shift(int16x8_t *a /*[16]*/) { - const int16x8_t one = vdupq_n_s16(1); - a[0] = vshrq_n_s16(vaddq_s16(a[0], one), 2); - a[1] = vshrq_n_s16(vaddq_s16(a[1], one), 2); - a[2] = vshrq_n_s16(vaddq_s16(a[2], one), 2); - a[3] = vshrq_n_s16(vaddq_s16(a[3], one), 2); - a[4] = vshrq_n_s16(vaddq_s16(a[4], one), 2); - a[5] = vshrq_n_s16(vaddq_s16(a[5], one), 2); - a[6] = vshrq_n_s16(vaddq_s16(a[6], one), 2); - a[7] = vshrq_n_s16(vaddq_s16(a[7], one), 2); - a[8] = vshrq_n_s16(vaddq_s16(a[8], one), 2); - a[9] = vshrq_n_s16(vaddq_s16(a[9], one), 2); - a[10] = vshrq_n_s16(vaddq_s16(a[10], one), 2); - a[11] = vshrq_n_s16(vaddq_s16(a[11], one), 2); - a[12] = vshrq_n_s16(vaddq_s16(a[12], one), 2); - a[13] = vshrq_n_s16(vaddq_s16(a[13], one), 2); - a[14] = vshrq_n_s16(vaddq_s16(a[14], one), 2); - a[15] = vshrq_n_s16(vaddq_s16(a[15], one), 2); -} - -#if CONFIG_VP9_HIGHBITDEPTH - -static INLINE void highbd_scale_input(const int16x8_t *a /*[16]*/, - int32x4_t *left /*[16]*/, - int32x4_t *right /* [16] */) { - left[0] = vshll_n_s16(vget_low_s16(a[0]), 2); - left[1] = vshll_n_s16(vget_low_s16(a[1]), 2); - left[2] = vshll_n_s16(vget_low_s16(a[2]), 2); - left[3] = vshll_n_s16(vget_low_s16(a[3]), 2); - left[4] = vshll_n_s16(vget_low_s16(a[4]), 2); - left[5] = vshll_n_s16(vget_low_s16(a[5]), 2); - left[6] = vshll_n_s16(vget_low_s16(a[6]), 2); - left[7] = vshll_n_s16(vget_low_s16(a[7]), 2); - left[8] = vshll_n_s16(vget_low_s16(a[8]), 2); - left[9] = vshll_n_s16(vget_low_s16(a[9]), 2); - left[10] = vshll_n_s16(vget_low_s16(a[10]), 2); - left[11] = vshll_n_s16(vget_low_s16(a[11]), 2); - left[12] = vshll_n_s16(vget_low_s16(a[12]), 2); - left[13] = vshll_n_s16(vget_low_s16(a[13]), 2); - left[14] = vshll_n_s16(vget_low_s16(a[14]), 2); - left[15] = vshll_n_s16(vget_low_s16(a[15]), 2); - - right[0] = vshll_n_s16(vget_high_s16(a[0]), 2); - right[1] = vshll_n_s16(vget_high_s16(a[1]), 2); - right[2] = vshll_n_s16(vget_high_s16(a[2]), 2); - right[3] = vshll_n_s16(vget_high_s16(a[3]), 2); - right[4] = vshll_n_s16(vget_high_s16(a[4]), 2); - right[5] = vshll_n_s16(vget_high_s16(a[5]), 2); - right[6] = vshll_n_s16(vget_high_s16(a[6]), 2); - right[7] = vshll_n_s16(vget_high_s16(a[7]), 2); - right[8] = vshll_n_s16(vget_high_s16(a[8]), 2); - right[9] = vshll_n_s16(vget_high_s16(a[9]), 2); - right[10] = vshll_n_s16(vget_high_s16(a[10]), 2); - right[11] = vshll_n_s16(vget_high_s16(a[11]), 2); - right[12] = vshll_n_s16(vget_high_s16(a[12]), 2); - right[13] = vshll_n_s16(vget_high_s16(a[13]), 2); - right[14] = vshll_n_s16(vget_high_s16(a[14]), 2); - right[15] = vshll_n_s16(vget_high_s16(a[15]), 2); -} - -static INLINE void highbd_cross_input(const int32x4_t *a_left /*[16]*/, - int32x4_t *a_right /*[16]*/, - int32x4_t *b_left /*[16]*/, - int32x4_t *b_right /*[16]*/) { - b_left[0] = vaddq_s32(a_left[0], a_left[15]); - b_left[1] = vaddq_s32(a_left[1], a_left[14]); - b_left[2] = vaddq_s32(a_left[2], a_left[13]); - b_left[3] = vaddq_s32(a_left[3], a_left[12]); - b_left[4] = vaddq_s32(a_left[4], a_left[11]); - b_left[5] = vaddq_s32(a_left[5], a_left[10]); - b_left[6] = vaddq_s32(a_left[6], a_left[9]); - b_left[7] = vaddq_s32(a_left[7], a_left[8]); - - b_right[0] = vaddq_s32(a_right[0], a_right[15]); - b_right[1] = vaddq_s32(a_right[1], a_right[14]); - b_right[2] = vaddq_s32(a_right[2], a_right[13]); - b_right[3] = vaddq_s32(a_right[3], a_right[12]); - b_right[4] = vaddq_s32(a_right[4], a_right[11]); - b_right[5] = vaddq_s32(a_right[5], a_right[10]); - b_right[6] = vaddq_s32(a_right[6], a_right[9]); - b_right[7] = vaddq_s32(a_right[7], a_right[8]); - - b_left[8] = vsubq_s32(a_left[7], a_left[8]); - b_left[9] = vsubq_s32(a_left[6], a_left[9]); - b_left[10] = vsubq_s32(a_left[5], a_left[10]); - b_left[11] = vsubq_s32(a_left[4], a_left[11]); - b_left[12] = vsubq_s32(a_left[3], a_left[12]); - b_left[13] = vsubq_s32(a_left[2], a_left[13]); - b_left[14] = vsubq_s32(a_left[1], a_left[14]); - b_left[15] = vsubq_s32(a_left[0], a_left[15]); - - b_right[8] = vsubq_s32(a_right[7], a_right[8]); - b_right[9] = vsubq_s32(a_right[6], a_right[9]); - b_right[10] = vsubq_s32(a_right[5], a_right[10]); - b_right[11] = vsubq_s32(a_right[4], a_right[11]); - b_right[12] = vsubq_s32(a_right[3], a_right[12]); - b_right[13] = vsubq_s32(a_right[2], a_right[13]); - b_right[14] = vsubq_s32(a_right[1], a_right[14]); - b_right[15] = vsubq_s32(a_right[0], a_right[15]); -} - -static INLINE void highbd_partial_round_shift(int32x4_t *left /*[16]*/, - int32x4_t *right /* [16] */) { - const int32x4_t one = vdupq_n_s32(1); - left[0] = vshrq_n_s32(vaddq_s32(left[0], one), 2); - left[1] = vshrq_n_s32(vaddq_s32(left[1], one), 2); - left[2] = vshrq_n_s32(vaddq_s32(left[2], one), 2); - left[3] = vshrq_n_s32(vaddq_s32(left[3], one), 2); - left[4] = vshrq_n_s32(vaddq_s32(left[4], one), 2); - left[5] = vshrq_n_s32(vaddq_s32(left[5], one), 2); - left[6] = vshrq_n_s32(vaddq_s32(left[6], one), 2); - left[7] = vshrq_n_s32(vaddq_s32(left[7], one), 2); - left[8] = vshrq_n_s32(vaddq_s32(left[8], one), 2); - left[9] = vshrq_n_s32(vaddq_s32(left[9], one), 2); - left[10] = vshrq_n_s32(vaddq_s32(left[10], one), 2); - left[11] = vshrq_n_s32(vaddq_s32(left[11], one), 2); - left[12] = vshrq_n_s32(vaddq_s32(left[12], one), 2); - left[13] = vshrq_n_s32(vaddq_s32(left[13], one), 2); - left[14] = vshrq_n_s32(vaddq_s32(left[14], one), 2); - left[15] = vshrq_n_s32(vaddq_s32(left[15], one), 2); - - right[0] = vshrq_n_s32(vaddq_s32(right[0], one), 2); - right[1] = vshrq_n_s32(vaddq_s32(right[1], one), 2); - right[2] = vshrq_n_s32(vaddq_s32(right[2], one), 2); - right[3] = vshrq_n_s32(vaddq_s32(right[3], one), 2); - right[4] = vshrq_n_s32(vaddq_s32(right[4], one), 2); - right[5] = vshrq_n_s32(vaddq_s32(right[5], one), 2); - right[6] = vshrq_n_s32(vaddq_s32(right[6], one), 2); - right[7] = vshrq_n_s32(vaddq_s32(right[7], one), 2); - right[8] = vshrq_n_s32(vaddq_s32(right[8], one), 2); - right[9] = vshrq_n_s32(vaddq_s32(right[9], one), 2); - right[10] = vshrq_n_s32(vaddq_s32(right[10], one), 2); - right[11] = vshrq_n_s32(vaddq_s32(right[11], one), 2); - right[12] = vshrq_n_s32(vaddq_s32(right[12], one), 2); - right[13] = vshrq_n_s32(vaddq_s32(right[13], one), 2); - right[14] = vshrq_n_s32(vaddq_s32(right[14], one), 2); - right[15] = vshrq_n_s32(vaddq_s32(right[15], one), 2); -} - -// Store 16 32x4 vectors, assuming stride == 16. -static INLINE void store16_s32(tran_low_t *a, const int32x4_t *b /*[32]*/) { - vst1q_s32(a, b[0]); - a += 16; - vst1q_s32(a, b[1]); - a += 16; - vst1q_s32(a, b[2]); - a += 16; - vst1q_s32(a, b[3]); - a += 16; - vst1q_s32(a, b[4]); - a += 16; - vst1q_s32(a, b[5]); - a += 16; - vst1q_s32(a, b[6]); - a += 16; - vst1q_s32(a, b[7]); - a += 16; - vst1q_s32(a, b[8]); - a += 16; - vst1q_s32(a, b[9]); - a += 16; - vst1q_s32(a, b[10]); - a += 16; - vst1q_s32(a, b[11]); - a += 16; - vst1q_s32(a, b[12]); - a += 16; - vst1q_s32(a, b[13]); - a += 16; - vst1q_s32(a, b[14]); - a += 16; - vst1q_s32(a, b[15]); -} - -#endif // CONFIG_VP9_HIGHBITDEPTH - -#endif // VPX_VPX_DSP_ARM_FDCT16X16_NEON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct32x32_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct32x32_neon.c deleted file mode 100644 index a91730ce..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct32x32_neon.c +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/txfm_common.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/arm/fdct_neon.h" -#include "vpx_dsp/arm/fdct32x32_neon.h" - -// Most gcc 4.9 distributions outside of Android do not generate correct code -// for this function. -#if !defined(__clang__) && !defined(__ANDROID__) && defined(__GNUC__) && \ - __GNUC__ == 4 && __GNUC_MINOR__ <= 9 - -void vpx_fdct32x32_neon(const int16_t *input, tran_low_t *output, int stride) { - vpx_fdct32x32_c(input, output, stride); -} - -void vpx_fdct32x32_rd_neon(const int16_t *input, tran_low_t *output, - int stride) { - vpx_fdct32x32_rd_c(input, output, stride); -} - -#else - -void vpx_fdct32x32_neon(const int16_t *input, tran_low_t *output, int stride) { - int16x8_t temp0[32]; - int16x8_t temp1[32]; - int16x8_t temp2[32]; - int16x8_t temp3[32]; - int16x8_t temp4[32]; - int16x8_t temp5[32]; - - // Process in 8x32 columns. - load_cross(input, stride, temp0); - scale_input(temp0, temp5); - dct_body_first_pass(temp5, temp1); - - load_cross(input + 8, stride, temp0); - scale_input(temp0, temp5); - dct_body_first_pass(temp5, temp2); - - load_cross(input + 16, stride, temp0); - scale_input(temp0, temp5); - dct_body_first_pass(temp5, temp3); - - load_cross(input + 24, stride, temp0); - scale_input(temp0, temp5); - dct_body_first_pass(temp5, temp4); - - // Generate the top row by munging the first set of 8 from each one together. - transpose_s16_8x8q(&temp1[0], &temp0[0]); - transpose_s16_8x8q(&temp2[0], &temp0[8]); - transpose_s16_8x8q(&temp3[0], &temp0[16]); - transpose_s16_8x8q(&temp4[0], &temp0[24]); - - dct_body_second_pass(temp0, temp5); - - transpose_s16_8x8(&temp5[0], &temp5[1], &temp5[2], &temp5[3], &temp5[4], - &temp5[5], &temp5[6], &temp5[7]); - transpose_s16_8x8(&temp5[8], &temp5[9], &temp5[10], &temp5[11], &temp5[12], - &temp5[13], &temp5[14], &temp5[15]); - transpose_s16_8x8(&temp5[16], &temp5[17], &temp5[18], &temp5[19], &temp5[20], - &temp5[21], &temp5[22], &temp5[23]); - transpose_s16_8x8(&temp5[24], &temp5[25], &temp5[26], &temp5[27], &temp5[28], - &temp5[29], &temp5[30], &temp5[31]); - store(output, temp5); - - // Second row of 8x32. - transpose_s16_8x8q(&temp1[8], &temp0[0]); - transpose_s16_8x8q(&temp2[8], &temp0[8]); - transpose_s16_8x8q(&temp3[8], &temp0[16]); - transpose_s16_8x8q(&temp4[8], &temp0[24]); - - dct_body_second_pass(temp0, temp5); - - transpose_s16_8x8(&temp5[0], &temp5[1], &temp5[2], &temp5[3], &temp5[4], - &temp5[5], &temp5[6], &temp5[7]); - transpose_s16_8x8(&temp5[8], &temp5[9], &temp5[10], &temp5[11], &temp5[12], - &temp5[13], &temp5[14], &temp5[15]); - transpose_s16_8x8(&temp5[16], &temp5[17], &temp5[18], &temp5[19], &temp5[20], - &temp5[21], &temp5[22], &temp5[23]); - transpose_s16_8x8(&temp5[24], &temp5[25], &temp5[26], &temp5[27], &temp5[28], - &temp5[29], &temp5[30], &temp5[31]); - store(output + 8 * 32, temp5); - - // Third row of 8x32 - transpose_s16_8x8q(&temp1[16], &temp0[0]); - transpose_s16_8x8q(&temp2[16], &temp0[8]); - transpose_s16_8x8q(&temp3[16], &temp0[16]); - transpose_s16_8x8q(&temp4[16], &temp0[24]); - - dct_body_second_pass(temp0, temp5); - - transpose_s16_8x8(&temp5[0], &temp5[1], &temp5[2], &temp5[3], &temp5[4], - &temp5[5], &temp5[6], &temp5[7]); - transpose_s16_8x8(&temp5[8], &temp5[9], &temp5[10], &temp5[11], &temp5[12], - &temp5[13], &temp5[14], &temp5[15]); - transpose_s16_8x8(&temp5[16], &temp5[17], &temp5[18], &temp5[19], &temp5[20], - &temp5[21], &temp5[22], &temp5[23]); - transpose_s16_8x8(&temp5[24], &temp5[25], &temp5[26], &temp5[27], &temp5[28], - &temp5[29], &temp5[30], &temp5[31]); - store(output + 16 * 32, temp5); - - // Final row of 8x32. - transpose_s16_8x8q(&temp1[24], &temp0[0]); - transpose_s16_8x8q(&temp2[24], &temp0[8]); - transpose_s16_8x8q(&temp3[24], &temp0[16]); - transpose_s16_8x8q(&temp4[24], &temp0[24]); - - dct_body_second_pass(temp0, temp5); - - transpose_s16_8x8(&temp5[0], &temp5[1], &temp5[2], &temp5[3], &temp5[4], - &temp5[5], &temp5[6], &temp5[7]); - transpose_s16_8x8(&temp5[8], &temp5[9], &temp5[10], &temp5[11], &temp5[12], - &temp5[13], &temp5[14], &temp5[15]); - transpose_s16_8x8(&temp5[16], &temp5[17], &temp5[18], &temp5[19], &temp5[20], - &temp5[21], &temp5[22], &temp5[23]); - transpose_s16_8x8(&temp5[24], &temp5[25], &temp5[26], &temp5[27], &temp5[28], - &temp5[29], &temp5[30], &temp5[31]); - store(output + 24 * 32, temp5); -} - -void vpx_fdct32x32_rd_neon(const int16_t *input, tran_low_t *output, - int stride) { - int16x8_t temp0[32]; - int16x8_t temp1[32]; - int16x8_t temp2[32]; - int16x8_t temp3[32]; - int16x8_t temp4[32]; - int16x8_t temp5[32]; - - // Process in 8x32 columns. - load_cross(input, stride, temp0); - scale_input(temp0, temp5); - dct_body_first_pass(temp5, temp1); - - load_cross(input + 8, stride, temp0); - scale_input(temp0, temp5); - dct_body_first_pass(temp5, temp2); - - load_cross(input + 16, stride, temp0); - scale_input(temp0, temp5); - dct_body_first_pass(temp5, temp3); - - load_cross(input + 24, stride, temp0); - scale_input(temp0, temp5); - dct_body_first_pass(temp5, temp4); - - // Generate the top row by munging the first set of 8 from each one together. - transpose_s16_8x8q(&temp1[0], &temp0[0]); - transpose_s16_8x8q(&temp2[0], &temp0[8]); - transpose_s16_8x8q(&temp3[0], &temp0[16]); - transpose_s16_8x8q(&temp4[0], &temp0[24]); - - dct_body_second_pass_rd(temp0, temp5); - - transpose_s16_8x8(&temp5[0], &temp5[1], &temp5[2], &temp5[3], &temp5[4], - &temp5[5], &temp5[6], &temp5[7]); - transpose_s16_8x8(&temp5[8], &temp5[9], &temp5[10], &temp5[11], &temp5[12], - &temp5[13], &temp5[14], &temp5[15]); - transpose_s16_8x8(&temp5[16], &temp5[17], &temp5[18], &temp5[19], &temp5[20], - &temp5[21], &temp5[22], &temp5[23]); - transpose_s16_8x8(&temp5[24], &temp5[25], &temp5[26], &temp5[27], &temp5[28], - &temp5[29], &temp5[30], &temp5[31]); - store(output, temp5); - - // Second row of 8x32. - transpose_s16_8x8q(&temp1[8], &temp0[0]); - transpose_s16_8x8q(&temp2[8], &temp0[8]); - transpose_s16_8x8q(&temp3[8], &temp0[16]); - transpose_s16_8x8q(&temp4[8], &temp0[24]); - - dct_body_second_pass_rd(temp0, temp5); - - transpose_s16_8x8(&temp5[0], &temp5[1], &temp5[2], &temp5[3], &temp5[4], - &temp5[5], &temp5[6], &temp5[7]); - transpose_s16_8x8(&temp5[8], &temp5[9], &temp5[10], &temp5[11], &temp5[12], - &temp5[13], &temp5[14], &temp5[15]); - transpose_s16_8x8(&temp5[16], &temp5[17], &temp5[18], &temp5[19], &temp5[20], - &temp5[21], &temp5[22], &temp5[23]); - transpose_s16_8x8(&temp5[24], &temp5[25], &temp5[26], &temp5[27], &temp5[28], - &temp5[29], &temp5[30], &temp5[31]); - store(output + 8 * 32, temp5); - - // Third row of 8x32 - transpose_s16_8x8q(&temp1[16], &temp0[0]); - transpose_s16_8x8q(&temp2[16], &temp0[8]); - transpose_s16_8x8q(&temp3[16], &temp0[16]); - transpose_s16_8x8q(&temp4[16], &temp0[24]); - - dct_body_second_pass_rd(temp0, temp5); - - transpose_s16_8x8(&temp5[0], &temp5[1], &temp5[2], &temp5[3], &temp5[4], - &temp5[5], &temp5[6], &temp5[7]); - transpose_s16_8x8(&temp5[8], &temp5[9], &temp5[10], &temp5[11], &temp5[12], - &temp5[13], &temp5[14], &temp5[15]); - transpose_s16_8x8(&temp5[16], &temp5[17], &temp5[18], &temp5[19], &temp5[20], - &temp5[21], &temp5[22], &temp5[23]); - transpose_s16_8x8(&temp5[24], &temp5[25], &temp5[26], &temp5[27], &temp5[28], - &temp5[29], &temp5[30], &temp5[31]); - store(output + 16 * 32, temp5); - - // Final row of 8x32. - transpose_s16_8x8q(&temp1[24], &temp0[0]); - transpose_s16_8x8q(&temp2[24], &temp0[8]); - transpose_s16_8x8q(&temp3[24], &temp0[16]); - transpose_s16_8x8q(&temp4[24], &temp0[24]); - - dct_body_second_pass_rd(temp0, temp5); - - transpose_s16_8x8(&temp5[0], &temp5[1], &temp5[2], &temp5[3], &temp5[4], - &temp5[5], &temp5[6], &temp5[7]); - transpose_s16_8x8(&temp5[8], &temp5[9], &temp5[10], &temp5[11], &temp5[12], - &temp5[13], &temp5[14], &temp5[15]); - transpose_s16_8x8(&temp5[16], &temp5[17], &temp5[18], &temp5[19], &temp5[20], - &temp5[21], &temp5[22], &temp5[23]); - transpose_s16_8x8(&temp5[24], &temp5[25], &temp5[26], &temp5[27], &temp5[28], - &temp5[29], &temp5[30], &temp5[31]); - store(output + 24 * 32, temp5); -} - -#if CONFIG_VP9_HIGHBITDEPTH - -void vpx_highbd_fdct32x32_neon(const int16_t *input, tran_low_t *output, - int stride) { - int16x8_t temp0[32]; - int32x4_t left1[32], left2[32], left3[32], left4[32], right1[32], right2[32], - right3[32], right4[32]; - int32x4_t left5[32], right5[32], left6[32], right6[32], left7[32], right7[32], - left8[32], right8[32]; - int32x4_t temp1[32], temp2[32]; - - // Process in 8x32 columns. - load_cross(input, stride, temp0); - highbd_scale_input(temp0, left1, right1); - highbd_dct8x32_body_first_pass(left1, right1); - highbd_partial_sub_round_shift(left1, right1); - - load_cross(input + 8, stride, temp0); - highbd_scale_input(temp0, left2, right2); - highbd_dct8x32_body_first_pass(left2, right2); - highbd_partial_sub_round_shift(left2, right2); - - load_cross(input + 16, stride, temp0); - highbd_scale_input(temp0, left3, right3); - highbd_dct8x32_body_first_pass(left3, right3); - highbd_partial_sub_round_shift(left3, right3); - - load_cross(input + 24, stride, temp0); - highbd_scale_input(temp0, left4, right4); - highbd_dct8x32_body_first_pass(left4, right4); - highbd_partial_sub_round_shift(left4, right4); - - // Generate the top row by munging the first set of 8 from each one together. - transpose_s32_8x8_2(left1, right1, temp1, temp2); - transpose_s32_8x8_2(left2, right2, temp1 + 8, temp2 + 8); - transpose_s32_8x8_2(left3, right3, temp1 + 16, temp2 + 16); - transpose_s32_8x8_2(left4, right4, temp1 + 24, temp2 + 24); - - highbd_cross_input(temp1, temp2, left5, right5); - highbd_dct8x32_body_second_pass(left5, right5); - highbd_partial_add_round_shift(left5, right5); - - // Second row of 8x32. - transpose_s32_8x8_2(left1 + 8, right1 + 8, temp1, temp2); - transpose_s32_8x8_2(left2 + 8, right2 + 8, temp1 + 8, temp2 + 8); - transpose_s32_8x8_2(left3 + 8, right3 + 8, temp1 + 16, temp2 + 16); - transpose_s32_8x8_2(left4 + 8, right4 + 8, temp1 + 24, temp2 + 24); - - highbd_cross_input(temp1, temp2, left6, right6); - highbd_dct8x32_body_second_pass(left6, right6); - highbd_partial_add_round_shift(left6, right6); - - // Third row of 8x32 - transpose_s32_8x8_2(left1 + 16, right1 + 16, temp1, temp2); - transpose_s32_8x8_2(left2 + 16, right2 + 16, temp1 + 8, temp2 + 8); - transpose_s32_8x8_2(left3 + 16, right3 + 16, temp1 + 16, temp2 + 16); - transpose_s32_8x8_2(left4 + 16, right4 + 16, temp1 + 24, temp2 + 24); - - highbd_cross_input(temp1, temp2, left7, right7); - highbd_dct8x32_body_second_pass(left7, right7); - highbd_partial_add_round_shift(left7, right7); - - // Final row of 8x32. - transpose_s32_8x8_2(left1 + 24, right1 + 24, temp1, temp2); - transpose_s32_8x8_2(left2 + 24, right2 + 24, temp1 + 8, temp2 + 8); - transpose_s32_8x8_2(left3 + 24, right3 + 24, temp1 + 16, temp2 + 16); - transpose_s32_8x8_2(left4 + 24, right4 + 24, temp1 + 24, temp2 + 24); - - highbd_cross_input(temp1, temp2, left8, right8); - highbd_dct8x32_body_second_pass(left8, right8); - highbd_partial_add_round_shift(left8, right8); - - // Final transpose - transpose_s32_8x8_2(left5, right5, left1, right1); - transpose_s32_8x8_2(left5 + 8, right5 + 8, left2, right2); - transpose_s32_8x8_2(left5 + 16, right5 + 16, left3, right3); - transpose_s32_8x8_2(left5 + 24, right5 + 24, left4, right4); - transpose_s32_8x8_2(left6, right6, left1 + 8, right1 + 8); - transpose_s32_8x8_2(left6 + 8, right6 + 8, left2 + 8, right2 + 8); - transpose_s32_8x8_2(left6 + 16, right6 + 16, left3 + 8, right3 + 8); - transpose_s32_8x8_2(left6 + 24, right6 + 24, left4 + 8, right4 + 8); - transpose_s32_8x8_2(left7, right7, left1 + 16, right1 + 16); - transpose_s32_8x8_2(left7 + 8, right7 + 8, left2 + 16, right2 + 16); - transpose_s32_8x8_2(left7 + 16, right7 + 16, left3 + 16, right3 + 16); - transpose_s32_8x8_2(left7 + 24, right7 + 24, left4 + 16, right4 + 16); - transpose_s32_8x8_2(left8, right8, left1 + 24, right1 + 24); - transpose_s32_8x8_2(left8 + 8, right8 + 8, left2 + 24, right2 + 24); - transpose_s32_8x8_2(left8 + 16, right8 + 16, left3 + 24, right3 + 24); - transpose_s32_8x8_2(left8 + 24, right8 + 24, left4 + 24, right4 + 24); - - store32x32_s32(output, left1, right1, left2, right2, left3, right3, left4, - right4); -} - -void vpx_highbd_fdct32x32_rd_neon(const int16_t *input, tran_low_t *output, - int stride) { - int16x8_t temp0[32]; - int32x4_t left1[32], left2[32], left3[32], left4[32], right1[32], right2[32], - right3[32], right4[32]; - int32x4_t left5[32], right5[32], left6[32], right6[32], left7[32], right7[32], - left8[32], right8[32]; - int32x4_t temp1[32], temp2[32]; - - // Process in 8x32 columns. - load_cross(input, stride, temp0); - highbd_scale_input(temp0, left1, right1); - highbd_dct8x32_body_first_pass(left1, right1); - highbd_partial_sub_round_shift(left1, right1); - - load_cross(input + 8, stride, temp0); - highbd_scale_input(temp0, left2, right2); - highbd_dct8x32_body_first_pass(left2, right2); - highbd_partial_sub_round_shift(left2, right2); - - load_cross(input + 16, stride, temp0); - highbd_scale_input(temp0, left3, right3); - highbd_dct8x32_body_first_pass(left3, right3); - highbd_partial_sub_round_shift(left3, right3); - - load_cross(input + 24, stride, temp0); - highbd_scale_input(temp0, left4, right4); - highbd_dct8x32_body_first_pass(left4, right4); - highbd_partial_sub_round_shift(left4, right4); - - // Generate the top row by munging the first set of 8 from each one together. - transpose_s32_8x8_2(left1, right1, temp1, temp2); - transpose_s32_8x8_2(left2, right2, temp1 + 8, temp2 + 8); - transpose_s32_8x8_2(left3, right3, temp1 + 16, temp2 + 16); - transpose_s32_8x8_2(left4, right4, temp1 + 24, temp2 + 24); - - highbd_cross_input(temp1, temp2, left5, right5); - highbd_dct8x32_body_second_pass_rd(left5, right5); - - // Second row of 8x32. - transpose_s32_8x8_2(left1 + 8, right1 + 8, temp1, temp2); - transpose_s32_8x8_2(left2 + 8, right2 + 8, temp1 + 8, temp2 + 8); - transpose_s32_8x8_2(left3 + 8, right3 + 8, temp1 + 16, temp2 + 16); - transpose_s32_8x8_2(left4 + 8, right4 + 8, temp1 + 24, temp2 + 24); - - highbd_cross_input(temp1, temp2, left6, right6); - highbd_dct8x32_body_second_pass_rd(left6, right6); - - // Third row of 8x32 - transpose_s32_8x8_2(left1 + 16, right1 + 16, temp1, temp2); - transpose_s32_8x8_2(left2 + 16, right2 + 16, temp1 + 8, temp2 + 8); - transpose_s32_8x8_2(left3 + 16, right3 + 16, temp1 + 16, temp2 + 16); - transpose_s32_8x8_2(left4 + 16, right4 + 16, temp1 + 24, temp2 + 24); - - highbd_cross_input(temp1, temp2, left7, right7); - highbd_dct8x32_body_second_pass_rd(left7, right7); - - // Final row of 8x32. - transpose_s32_8x8_2(left1 + 24, right1 + 24, temp1, temp2); - transpose_s32_8x8_2(left2 + 24, right2 + 24, temp1 + 8, temp2 + 8); - transpose_s32_8x8_2(left3 + 24, right3 + 24, temp1 + 16, temp2 + 16); - transpose_s32_8x8_2(left4 + 24, right4 + 24, temp1 + 24, temp2 + 24); - - highbd_cross_input(temp1, temp2, left8, right8); - highbd_dct8x32_body_second_pass_rd(left8, right8); - - // Final transpose - transpose_s32_8x8_2(left5, right5, left1, right1); - transpose_s32_8x8_2(left5 + 8, right5 + 8, left2, right2); - transpose_s32_8x8_2(left5 + 16, right5 + 16, left3, right3); - transpose_s32_8x8_2(left5 + 24, right5 + 24, left4, right4); - transpose_s32_8x8_2(left6, right6, left1 + 8, right1 + 8); - transpose_s32_8x8_2(left6 + 8, right6 + 8, left2 + 8, right2 + 8); - transpose_s32_8x8_2(left6 + 16, right6 + 16, left3 + 8, right3 + 8); - transpose_s32_8x8_2(left6 + 24, right6 + 24, left4 + 8, right4 + 8); - transpose_s32_8x8_2(left7, right7, left1 + 16, right1 + 16); - transpose_s32_8x8_2(left7 + 8, right7 + 8, left2 + 16, right2 + 16); - transpose_s32_8x8_2(left7 + 16, right7 + 16, left3 + 16, right3 + 16); - transpose_s32_8x8_2(left7 + 24, right7 + 24, left4 + 16, right4 + 16); - transpose_s32_8x8_2(left8, right8, left1 + 24, right1 + 24); - transpose_s32_8x8_2(left8 + 8, right8 + 8, left2 + 24, right2 + 24); - transpose_s32_8x8_2(left8 + 16, right8 + 16, left3 + 24, right3 + 24); - transpose_s32_8x8_2(left8 + 24, right8 + 24, left4 + 24, right4 + 24); - - store32x32_s32(output, left1, right1, left2, right2, left3, right3, left4, - right4); -} - -#endif // CONFIG_VP9_HIGHBITDEPTH - -#endif // !defined(__clang__) && !defined(__ANDROID__) && defined(__GNUC__) && - // __GNUC__ == 4 && __GNUC_MINOR__ <= 9 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct32x32_neon.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct32x32_neon.h deleted file mode 100644 index 3b9e64c6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct32x32_neon.h +++ /dev/null @@ -1,2919 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_ARM_FDCT32X32_NEON_H_ -#define VPX_VPX_DSP_ARM_FDCT32X32_NEON_H_ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/txfm_common.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/arm/fdct_neon.h" - -// Load & cross the first 8 and last 8, then the middle -static INLINE void load_cross(const int16_t *a, int stride, int16x8_t *b) { - b[0] = vaddq_s16(vld1q_s16(a + 0 * stride), vld1q_s16(a + 31 * stride)); - b[1] = vaddq_s16(vld1q_s16(a + 1 * stride), vld1q_s16(a + 30 * stride)); - b[2] = vaddq_s16(vld1q_s16(a + 2 * stride), vld1q_s16(a + 29 * stride)); - b[3] = vaddq_s16(vld1q_s16(a + 3 * stride), vld1q_s16(a + 28 * stride)); - b[4] = vaddq_s16(vld1q_s16(a + 4 * stride), vld1q_s16(a + 27 * stride)); - b[5] = vaddq_s16(vld1q_s16(a + 5 * stride), vld1q_s16(a + 26 * stride)); - b[6] = vaddq_s16(vld1q_s16(a + 6 * stride), vld1q_s16(a + 25 * stride)); - b[7] = vaddq_s16(vld1q_s16(a + 7 * stride), vld1q_s16(a + 24 * stride)); - - b[24] = vsubq_s16(vld1q_s16(a + 7 * stride), vld1q_s16(a + 24 * stride)); - b[25] = vsubq_s16(vld1q_s16(a + 6 * stride), vld1q_s16(a + 25 * stride)); - b[26] = vsubq_s16(vld1q_s16(a + 5 * stride), vld1q_s16(a + 26 * stride)); - b[27] = vsubq_s16(vld1q_s16(a + 4 * stride), vld1q_s16(a + 27 * stride)); - b[28] = vsubq_s16(vld1q_s16(a + 3 * stride), vld1q_s16(a + 28 * stride)); - b[29] = vsubq_s16(vld1q_s16(a + 2 * stride), vld1q_s16(a + 29 * stride)); - b[30] = vsubq_s16(vld1q_s16(a + 1 * stride), vld1q_s16(a + 30 * stride)); - b[31] = vsubq_s16(vld1q_s16(a + 0 * stride), vld1q_s16(a + 31 * stride)); - - b[8] = vaddq_s16(vld1q_s16(a + 8 * stride), vld1q_s16(a + 23 * stride)); - b[9] = vaddq_s16(vld1q_s16(a + 9 * stride), vld1q_s16(a + 22 * stride)); - b[10] = vaddq_s16(vld1q_s16(a + 10 * stride), vld1q_s16(a + 21 * stride)); - b[11] = vaddq_s16(vld1q_s16(a + 11 * stride), vld1q_s16(a + 20 * stride)); - b[12] = vaddq_s16(vld1q_s16(a + 12 * stride), vld1q_s16(a + 19 * stride)); - b[13] = vaddq_s16(vld1q_s16(a + 13 * stride), vld1q_s16(a + 18 * stride)); - b[14] = vaddq_s16(vld1q_s16(a + 14 * stride), vld1q_s16(a + 17 * stride)); - b[15] = vaddq_s16(vld1q_s16(a + 15 * stride), vld1q_s16(a + 16 * stride)); - - b[16] = vsubq_s16(vld1q_s16(a + 15 * stride), vld1q_s16(a + 16 * stride)); - b[17] = vsubq_s16(vld1q_s16(a + 14 * stride), vld1q_s16(a + 17 * stride)); - b[18] = vsubq_s16(vld1q_s16(a + 13 * stride), vld1q_s16(a + 18 * stride)); - b[19] = vsubq_s16(vld1q_s16(a + 12 * stride), vld1q_s16(a + 19 * stride)); - b[20] = vsubq_s16(vld1q_s16(a + 11 * stride), vld1q_s16(a + 20 * stride)); - b[21] = vsubq_s16(vld1q_s16(a + 10 * stride), vld1q_s16(a + 21 * stride)); - b[22] = vsubq_s16(vld1q_s16(a + 9 * stride), vld1q_s16(a + 22 * stride)); - b[23] = vsubq_s16(vld1q_s16(a + 8 * stride), vld1q_s16(a + 23 * stride)); -} - -#define STORE_S16(src, index, dest) \ - do { \ - store_s16q_to_tran_low(dest, src[index]); \ - dest += 8; \ - } while (0) - -// Store 32 16x8 values, assuming stride == 32. -// Slight twist: store horizontally in blocks of 8. -static INLINE void store(tran_low_t *a, const int16x8_t *b) { - STORE_S16(b, 0, a); - STORE_S16(b, 8, a); - STORE_S16(b, 16, a); - STORE_S16(b, 24, a); - STORE_S16(b, 1, a); - STORE_S16(b, 9, a); - STORE_S16(b, 17, a); - STORE_S16(b, 25, a); - STORE_S16(b, 2, a); - STORE_S16(b, 10, a); - STORE_S16(b, 18, a); - STORE_S16(b, 26, a); - STORE_S16(b, 3, a); - STORE_S16(b, 11, a); - STORE_S16(b, 19, a); - STORE_S16(b, 27, a); - STORE_S16(b, 4, a); - STORE_S16(b, 12, a); - STORE_S16(b, 20, a); - STORE_S16(b, 28, a); - STORE_S16(b, 5, a); - STORE_S16(b, 13, a); - STORE_S16(b, 21, a); - STORE_S16(b, 29, a); - STORE_S16(b, 6, a); - STORE_S16(b, 14, a); - STORE_S16(b, 22, a); - STORE_S16(b, 30, a); - STORE_S16(b, 7, a); - STORE_S16(b, 15, a); - STORE_S16(b, 23, a); - STORE_S16(b, 31, a); -} - -#undef STORE_S16 - -static INLINE void scale_input(const int16x8_t *in /*32*/, - int16x8_t *out /*32*/) { - out[0] = vshlq_n_s16(in[0], 2); - out[1] = vshlq_n_s16(in[1], 2); - out[2] = vshlq_n_s16(in[2], 2); - out[3] = vshlq_n_s16(in[3], 2); - out[4] = vshlq_n_s16(in[4], 2); - out[5] = vshlq_n_s16(in[5], 2); - out[6] = vshlq_n_s16(in[6], 2); - out[7] = vshlq_n_s16(in[7], 2); - - out[8] = vshlq_n_s16(in[8], 2); - out[9] = vshlq_n_s16(in[9], 2); - out[10] = vshlq_n_s16(in[10], 2); - out[11] = vshlq_n_s16(in[11], 2); - out[12] = vshlq_n_s16(in[12], 2); - out[13] = vshlq_n_s16(in[13], 2); - out[14] = vshlq_n_s16(in[14], 2); - out[15] = vshlq_n_s16(in[15], 2); - - out[16] = vshlq_n_s16(in[16], 2); - out[17] = vshlq_n_s16(in[17], 2); - out[18] = vshlq_n_s16(in[18], 2); - out[19] = vshlq_n_s16(in[19], 2); - out[20] = vshlq_n_s16(in[20], 2); - out[21] = vshlq_n_s16(in[21], 2); - out[22] = vshlq_n_s16(in[22], 2); - out[23] = vshlq_n_s16(in[23], 2); - - out[24] = vshlq_n_s16(in[24], 2); - out[25] = vshlq_n_s16(in[25], 2); - out[26] = vshlq_n_s16(in[26], 2); - out[27] = vshlq_n_s16(in[27], 2); - out[28] = vshlq_n_s16(in[28], 2); - out[29] = vshlq_n_s16(in[29], 2); - out[30] = vshlq_n_s16(in[30], 2); - out[31] = vshlq_n_s16(in[31], 2); -} - -static INLINE void dct_body_first_pass(const int16x8_t *in, int16x8_t *out) { - int16x8_t a[32]; - int16x8_t b[32]; - - // Stage 1: Done as part of the load. - - // Stage 2. - // Mini cross. X the first 16 values and the middle 8 of the second half. - a[0] = vaddq_s16(in[0], in[15]); - a[1] = vaddq_s16(in[1], in[14]); - a[2] = vaddq_s16(in[2], in[13]); - a[3] = vaddq_s16(in[3], in[12]); - a[4] = vaddq_s16(in[4], in[11]); - a[5] = vaddq_s16(in[5], in[10]); - a[6] = vaddq_s16(in[6], in[9]); - a[7] = vaddq_s16(in[7], in[8]); - - a[8] = vsubq_s16(in[7], in[8]); - a[9] = vsubq_s16(in[6], in[9]); - a[10] = vsubq_s16(in[5], in[10]); - a[11] = vsubq_s16(in[4], in[11]); - a[12] = vsubq_s16(in[3], in[12]); - a[13] = vsubq_s16(in[2], in[13]); - a[14] = vsubq_s16(in[1], in[14]); - a[15] = vsubq_s16(in[0], in[15]); - - a[16] = in[16]; - a[17] = in[17]; - a[18] = in[18]; - a[19] = in[19]; - - butterfly_one_coeff_s16_s32_narrow(in[27], in[20], cospi_16_64, &a[27], - &a[20]); - butterfly_one_coeff_s16_s32_narrow(in[26], in[21], cospi_16_64, &a[26], - &a[21]); - butterfly_one_coeff_s16_s32_narrow(in[25], in[22], cospi_16_64, &a[25], - &a[22]); - butterfly_one_coeff_s16_s32_narrow(in[24], in[23], cospi_16_64, &a[24], - &a[23]); - - a[28] = in[28]; - a[29] = in[29]; - a[30] = in[30]; - a[31] = in[31]; - - // Stage 3. - b[0] = vaddq_s16(a[0], a[7]); - b[1] = vaddq_s16(a[1], a[6]); - b[2] = vaddq_s16(a[2], a[5]); - b[3] = vaddq_s16(a[3], a[4]); - - b[4] = vsubq_s16(a[3], a[4]); - b[5] = vsubq_s16(a[2], a[5]); - b[6] = vsubq_s16(a[1], a[6]); - b[7] = vsubq_s16(a[0], a[7]); - - b[8] = a[8]; - b[9] = a[9]; - - butterfly_one_coeff_s16_s32_narrow(a[13], a[10], cospi_16_64, &b[13], &b[10]); - butterfly_one_coeff_s16_s32_narrow(a[12], a[11], cospi_16_64, &b[12], &b[11]); - - b[14] = a[14]; - b[15] = a[15]; - - b[16] = vaddq_s16(in[16], a[23]); - b[17] = vaddq_s16(in[17], a[22]); - b[18] = vaddq_s16(in[18], a[21]); - b[19] = vaddq_s16(in[19], a[20]); - - b[20] = vsubq_s16(in[19], a[20]); - b[21] = vsubq_s16(in[18], a[21]); - b[22] = vsubq_s16(in[17], a[22]); - b[23] = vsubq_s16(in[16], a[23]); - - b[24] = vsubq_s16(in[31], a[24]); - b[25] = vsubq_s16(in[30], a[25]); - b[26] = vsubq_s16(in[29], a[26]); - b[27] = vsubq_s16(in[28], a[27]); - - b[28] = vaddq_s16(in[28], a[27]); - b[29] = vaddq_s16(in[29], a[26]); - b[30] = vaddq_s16(in[30], a[25]); - b[31] = vaddq_s16(in[31], a[24]); - - // Stage 4. - a[0] = vaddq_s16(b[0], b[3]); - a[1] = vaddq_s16(b[1], b[2]); - a[2] = vsubq_s16(b[1], b[2]); - a[3] = vsubq_s16(b[0], b[3]); - - a[4] = b[4]; - - butterfly_one_coeff_s16_s32_narrow(b[6], b[5], cospi_16_64, &a[6], &a[5]); - - a[7] = b[7]; - - a[8] = vaddq_s16(b[8], b[11]); - a[9] = vaddq_s16(b[9], b[10]); - a[10] = vsubq_s16(b[9], b[10]); - a[11] = vsubq_s16(b[8], b[11]); - a[12] = vsubq_s16(b[15], b[12]); - a[13] = vsubq_s16(b[14], b[13]); - a[14] = vaddq_s16(b[14], b[13]); - a[15] = vaddq_s16(b[15], b[12]); - - a[16] = b[16]; - a[17] = b[17]; - - butterfly_two_coeff(b[29], b[18], cospi_8_64, cospi_24_64, &a[29], &a[18]); - butterfly_two_coeff(b[28], b[19], cospi_8_64, cospi_24_64, &a[28], &a[19]); - butterfly_two_coeff(b[27], b[20], cospi_24_64, -cospi_8_64, &a[27], &a[20]); - butterfly_two_coeff(b[26], b[21], cospi_24_64, -cospi_8_64, &a[26], &a[21]); - - a[22] = b[22]; - a[23] = b[23]; - a[24] = b[24]; - a[25] = b[25]; - - a[30] = b[30]; - a[31] = b[31]; - - // Stage 5. - butterfly_one_coeff_s16_fast(a[0], a[1], cospi_16_64, &b[0], &b[1]); - butterfly_two_coeff(a[3], a[2], cospi_8_64, cospi_24_64, &b[2], &b[3]); - - b[4] = vaddq_s16(a[4], a[5]); - b[5] = vsubq_s16(a[4], a[5]); - b[6] = vsubq_s16(a[7], a[6]); - b[7] = vaddq_s16(a[7], a[6]); - - b[8] = a[8]; - - butterfly_two_coeff(a[14], a[9], cospi_8_64, cospi_24_64, &b[14], &b[9]); - butterfly_two_coeff(a[13], a[10], cospi_24_64, -cospi_8_64, &b[13], &b[10]); - - b[11] = a[11]; - b[12] = a[12]; - - b[15] = a[15]; - - b[16] = vaddq_s16(a[19], a[16]); - b[17] = vaddq_s16(a[18], a[17]); - b[18] = vsubq_s16(a[17], a[18]); - b[19] = vsubq_s16(a[16], a[19]); - b[20] = vsubq_s16(a[23], a[20]); - b[21] = vsubq_s16(a[22], a[21]); - b[22] = vaddq_s16(a[21], a[22]); - b[23] = vaddq_s16(a[20], a[23]); - b[24] = vaddq_s16(a[27], a[24]); - b[25] = vaddq_s16(a[26], a[25]); - b[26] = vsubq_s16(a[25], a[26]); - b[27] = vsubq_s16(a[24], a[27]); - b[28] = vsubq_s16(a[31], a[28]); - b[29] = vsubq_s16(a[30], a[29]); - b[30] = vaddq_s16(a[29], a[30]); - b[31] = vaddq_s16(a[28], a[31]); - - // Stage 6. - a[0] = b[0]; - a[1] = b[1]; - a[2] = b[2]; - a[3] = b[3]; - - butterfly_two_coeff(b[7], b[4], cospi_4_64, cospi_28_64, &a[4], &a[7]); - butterfly_two_coeff(b[6], b[5], cospi_20_64, cospi_12_64, &a[5], &a[6]); - - a[8] = vaddq_s16(b[8], b[9]); - a[9] = vsubq_s16(b[8], b[9]); - a[10] = vsubq_s16(b[11], b[10]); - a[11] = vaddq_s16(b[11], b[10]); - a[12] = vaddq_s16(b[12], b[13]); - a[13] = vsubq_s16(b[12], b[13]); - a[14] = vsubq_s16(b[15], b[14]); - a[15] = vaddq_s16(b[15], b[14]); - - a[16] = b[16]; - a[19] = b[19]; - a[20] = b[20]; - a[23] = b[23]; - a[24] = b[24]; - a[27] = b[27]; - a[28] = b[28]; - a[31] = b[31]; - - butterfly_two_coeff(b[30], b[17], cospi_4_64, cospi_28_64, &a[30], &a[17]); - butterfly_two_coeff(b[29], b[18], cospi_28_64, -cospi_4_64, &a[29], &a[18]); - - butterfly_two_coeff(b[26], b[21], cospi_20_64, cospi_12_64, &a[26], &a[21]); - butterfly_two_coeff(b[25], b[22], cospi_12_64, -cospi_20_64, &a[25], &a[22]); - - // Stage 7. - b[0] = a[0]; - b[1] = a[1]; - b[2] = a[2]; - b[3] = a[3]; - b[4] = a[4]; - b[5] = a[5]; - b[6] = a[6]; - b[7] = a[7]; - - butterfly_two_coeff(a[15], a[8], cospi_2_64, cospi_30_64, &b[8], &b[15]); - butterfly_two_coeff(a[14], a[9], cospi_18_64, cospi_14_64, &b[9], &b[14]); - butterfly_two_coeff(a[13], a[10], cospi_10_64, cospi_22_64, &b[10], &b[13]); - butterfly_two_coeff(a[12], a[11], cospi_26_64, cospi_6_64, &b[11], &b[12]); - - b[16] = vaddq_s16(a[16], a[17]); - b[17] = vsubq_s16(a[16], a[17]); - b[18] = vsubq_s16(a[19], a[18]); - b[19] = vaddq_s16(a[19], a[18]); - b[20] = vaddq_s16(a[20], a[21]); - b[21] = vsubq_s16(a[20], a[21]); - b[22] = vsubq_s16(a[23], a[22]); - b[23] = vaddq_s16(a[23], a[22]); - b[24] = vaddq_s16(a[24], a[25]); - b[25] = vsubq_s16(a[24], a[25]); - b[26] = vsubq_s16(a[27], a[26]); - b[27] = vaddq_s16(a[27], a[26]); - b[28] = vaddq_s16(a[28], a[29]); - b[29] = vsubq_s16(a[28], a[29]); - b[30] = vsubq_s16(a[31], a[30]); - b[31] = vaddq_s16(a[31], a[30]); - - // Final stage. - // Also compute partial rounding shift: - // output[j * 32 + i] = (temp_out[j] + 1 + (temp_out[j] > 0)) >> 2; - out[0] = sub_round_shift_s16(b[0]); - out[16] = sub_round_shift_s16(b[1]); - out[8] = sub_round_shift_s16(b[2]); - out[24] = sub_round_shift_s16(b[3]); - out[4] = sub_round_shift_s16(b[4]); - out[20] = sub_round_shift_s16(b[5]); - out[12] = sub_round_shift_s16(b[6]); - out[28] = sub_round_shift_s16(b[7]); - out[2] = sub_round_shift_s16(b[8]); - out[18] = sub_round_shift_s16(b[9]); - out[10] = sub_round_shift_s16(b[10]); - out[26] = sub_round_shift_s16(b[11]); - out[6] = sub_round_shift_s16(b[12]); - out[22] = sub_round_shift_s16(b[13]); - out[14] = sub_round_shift_s16(b[14]); - out[30] = sub_round_shift_s16(b[15]); - - butterfly_two_coeff(b[31], b[16], cospi_1_64, cospi_31_64, &a[1], &a[31]); - out[1] = sub_round_shift_s16(a[1]); - out[31] = sub_round_shift_s16(a[31]); - - butterfly_two_coeff(b[30], b[17], cospi_17_64, cospi_15_64, &a[17], &a[15]); - out[17] = sub_round_shift_s16(a[17]); - out[15] = sub_round_shift_s16(a[15]); - - butterfly_two_coeff(b[29], b[18], cospi_9_64, cospi_23_64, &a[9], &a[23]); - out[9] = sub_round_shift_s16(a[9]); - out[23] = sub_round_shift_s16(a[23]); - - butterfly_two_coeff(b[28], b[19], cospi_25_64, cospi_7_64, &a[25], &a[7]); - out[25] = sub_round_shift_s16(a[25]); - out[7] = sub_round_shift_s16(a[7]); - - butterfly_two_coeff(b[27], b[20], cospi_5_64, cospi_27_64, &a[5], &a[27]); - out[5] = sub_round_shift_s16(a[5]); - out[27] = sub_round_shift_s16(a[27]); - - butterfly_two_coeff(b[26], b[21], cospi_21_64, cospi_11_64, &a[21], &a[11]); - out[21] = sub_round_shift_s16(a[21]); - out[11] = sub_round_shift_s16(a[11]); - - butterfly_two_coeff(b[25], b[22], cospi_13_64, cospi_19_64, &a[13], &a[19]); - out[13] = sub_round_shift_s16(a[13]); - out[19] = sub_round_shift_s16(a[19]); - - butterfly_two_coeff(b[24], b[23], cospi_29_64, cospi_3_64, &a[29], &a[3]); - out[29] = sub_round_shift_s16(a[29]); - out[3] = sub_round_shift_s16(a[3]); -} - -#define PASS_THROUGH(src, dst, element) \ - do { \ - dst##_lo[element] = src##_lo[element]; \ - dst##_hi[element] = src##_hi[element]; \ - } while (0) - -#define ADD_S16_S32(a, left_index, right_index, b, b_index) \ - do { \ - b##_lo[b_index] = \ - vaddl_s16(vget_low_s16(a[left_index]), vget_low_s16(a[right_index])); \ - b##_hi[b_index] = vaddl_s16(vget_high_s16(a[left_index]), \ - vget_high_s16(a[right_index])); \ - } while (0) - -#define SUB_S16_S32(a, left_index, right_index, b, b_index) \ - do { \ - b##_lo[b_index] = \ - vsubl_s16(vget_low_s16(a[left_index]), vget_low_s16(a[right_index])); \ - b##_hi[b_index] = vsubl_s16(vget_high_s16(a[left_index]), \ - vget_high_s16(a[right_index])); \ - } while (0) - -#define ADDW_S16_S32(a, a_index, b, b_index, c, c_index) \ - do { \ - c##_lo[c_index] = vaddw_s16(a##_lo[a_index], vget_low_s16(b[b_index])); \ - c##_hi[c_index] = vaddw_s16(a##_hi[a_index], vget_high_s16(b[b_index])); \ - } while (0) - -#define SUBW_S16_S32(a, a_index, b, b_index, temp, temp_index, c, c_index) \ - do { \ - temp##_lo[temp_index] = vmovl_s16(vget_low_s16(a[a_index])); \ - temp##_hi[temp_index] = vmovl_s16(vget_high_s16(a[a_index])); \ - c##_lo[c_index] = vsubq_s32(temp##_lo[temp_index], b##_lo[b_index]); \ - c##_hi[c_index] = vsubq_s32(temp##_hi[temp_index], b##_hi[b_index]); \ - } while (0) - -#define ADD_S32(a, left_index, right_index, b, b_index) \ - do { \ - b##_lo[b_index] = vaddq_s32(a##_lo[left_index], a##_lo[right_index]); \ - b##_hi[b_index] = vaddq_s32(a##_hi[left_index], a##_hi[right_index]); \ - } while (0) - -#define SUB_S32(a, left_index, right_index, b, b_index) \ - do { \ - b##_lo[b_index] = vsubq_s32(a##_lo[left_index], a##_lo[right_index]); \ - b##_hi[b_index] = vsubq_s32(a##_hi[left_index], a##_hi[right_index]); \ - } while (0) - -#define BUTTERFLY_ONE_S16_S32(a, left_index, right_index, constant, b, \ - add_index, sub_index) \ - do { \ - butterfly_one_coeff_s16_s32(a[left_index], a[right_index], constant, \ - &b##_lo[add_index], &b##_hi[add_index], \ - &b##_lo[sub_index], &b##_hi[sub_index]); \ - } while (0) - -#define BUTTERFLY_ONE_S32(a, left_index, right_index, constant, b, add_index, \ - sub_index) \ - do { \ - butterfly_one_coeff_s32_fast( \ - a##_lo[left_index], a##_hi[left_index], a##_lo[right_index], \ - a##_hi[right_index], constant, &b##_lo[add_index], &b##_hi[add_index], \ - &b##_lo[sub_index], &b##_hi[sub_index]); \ - } while (0) - -#define BUTTERFLY_TWO_S32(a, left_index, right_index, left_constant, \ - right_constant, b, add_index, sub_index) \ - do { \ - butterfly_two_coeff_s32(a##_lo[left_index], a##_hi[left_index], \ - a##_lo[right_index], a##_hi[right_index], \ - left_constant, right_constant, &b##_lo[add_index], \ - &b##_hi[add_index], &b##_lo[sub_index], \ - &b##_hi[sub_index]); \ - } while (0) - -static INLINE void dct_body_second_pass(const int16x8_t *in, int16x8_t *out) { - int16x8_t a[32]; - int16x8_t b[32]; - int32x4_t c_lo[32]; - int32x4_t c_hi[32]; - int32x4_t d_lo[32]; - int32x4_t d_hi[32]; - - // Stage 1. Done as part of the load for the first pass. - a[0] = vaddq_s16(in[0], in[31]); - a[1] = vaddq_s16(in[1], in[30]); - a[2] = vaddq_s16(in[2], in[29]); - a[3] = vaddq_s16(in[3], in[28]); - a[4] = vaddq_s16(in[4], in[27]); - a[5] = vaddq_s16(in[5], in[26]); - a[6] = vaddq_s16(in[6], in[25]); - a[7] = vaddq_s16(in[7], in[24]); - a[8] = vaddq_s16(in[8], in[23]); - a[9] = vaddq_s16(in[9], in[22]); - a[10] = vaddq_s16(in[10], in[21]); - a[11] = vaddq_s16(in[11], in[20]); - a[12] = vaddq_s16(in[12], in[19]); - a[13] = vaddq_s16(in[13], in[18]); - a[14] = vaddq_s16(in[14], in[17]); - a[15] = vaddq_s16(in[15], in[16]); - a[16] = vsubq_s16(in[15], in[16]); - a[17] = vsubq_s16(in[14], in[17]); - a[18] = vsubq_s16(in[13], in[18]); - a[19] = vsubq_s16(in[12], in[19]); - a[20] = vsubq_s16(in[11], in[20]); - a[21] = vsubq_s16(in[10], in[21]); - a[22] = vsubq_s16(in[9], in[22]); - a[23] = vsubq_s16(in[8], in[23]); - a[24] = vsubq_s16(in[7], in[24]); - a[25] = vsubq_s16(in[6], in[25]); - a[26] = vsubq_s16(in[5], in[26]); - a[27] = vsubq_s16(in[4], in[27]); - a[28] = vsubq_s16(in[3], in[28]); - a[29] = vsubq_s16(in[2], in[29]); - a[30] = vsubq_s16(in[1], in[30]); - a[31] = vsubq_s16(in[0], in[31]); - - // Stage 2. - b[0] = vaddq_s16(a[0], a[15]); - b[1] = vaddq_s16(a[1], a[14]); - b[2] = vaddq_s16(a[2], a[13]); - b[3] = vaddq_s16(a[3], a[12]); - b[4] = vaddq_s16(a[4], a[11]); - b[5] = vaddq_s16(a[5], a[10]); - b[6] = vaddq_s16(a[6], a[9]); - b[7] = vaddq_s16(a[7], a[8]); - - b[8] = vsubq_s16(a[7], a[8]); - b[9] = vsubq_s16(a[6], a[9]); - b[10] = vsubq_s16(a[5], a[10]); - b[11] = vsubq_s16(a[4], a[11]); - b[12] = vsubq_s16(a[3], a[12]); - b[13] = vsubq_s16(a[2], a[13]); - b[14] = vsubq_s16(a[1], a[14]); - b[15] = vsubq_s16(a[0], a[15]); - - b[16] = a[16]; - b[17] = a[17]; - b[18] = a[18]; - b[19] = a[19]; - - butterfly_one_coeff_s16_s32_narrow(a[27], a[20], cospi_16_64, &b[27], &b[20]); - butterfly_one_coeff_s16_s32_narrow(a[26], a[21], cospi_16_64, &b[26], &b[21]); - butterfly_one_coeff_s16_s32_narrow(a[25], a[22], cospi_16_64, &b[25], &b[22]); - butterfly_one_coeff_s16_s32_narrow(a[24], a[23], cospi_16_64, &b[24], &b[23]); - - b[28] = a[28]; - b[29] = a[29]; - b[30] = a[30]; - b[31] = a[31]; - - // Stage 3. With extreme values for input this calculation rolls over int16_t. - // The sources for b[0] get added multiple times and, through testing, have - // been shown to overflow starting here. - ADD_S16_S32(b, 0, 7, c, 0); - ADD_S16_S32(b, 1, 6, c, 1); - ADD_S16_S32(b, 2, 5, c, 2); - ADD_S16_S32(b, 3, 4, c, 3); - SUB_S16_S32(b, 3, 4, c, 4); - SUB_S16_S32(b, 2, 5, c, 5); - SUB_S16_S32(b, 1, 6, c, 6); - SUB_S16_S32(b, 0, 7, c, 7); - - a[8] = b[8]; - a[9] = b[9]; - - BUTTERFLY_ONE_S16_S32(b, 13, 10, cospi_16_64, c, 13, 10); - BUTTERFLY_ONE_S16_S32(b, 12, 11, cospi_16_64, c, 12, 11); - - a[14] = b[14]; - a[15] = b[15]; - - ADD_S16_S32(b, 16, 23, c, 16); - ADD_S16_S32(b, 17, 22, c, 17); - ADD_S16_S32(b, 18, 21, c, 18); - ADD_S16_S32(b, 19, 20, c, 19); - SUB_S16_S32(b, 19, 20, c, 20); - SUB_S16_S32(b, 18, 21, c, 21); - SUB_S16_S32(b, 17, 22, c, 22); - SUB_S16_S32(b, 16, 23, c, 23); - SUB_S16_S32(b, 31, 24, c, 24); - SUB_S16_S32(b, 30, 25, c, 25); - SUB_S16_S32(b, 29, 26, c, 26); - SUB_S16_S32(b, 28, 27, c, 27); - ADD_S16_S32(b, 28, 27, c, 28); - ADD_S16_S32(b, 29, 26, c, 29); - ADD_S16_S32(b, 30, 25, c, 30); - ADD_S16_S32(b, 31, 24, c, 31); - - // Stage 4. - ADD_S32(c, 0, 3, d, 0); - ADD_S32(c, 1, 2, d, 1); - SUB_S32(c, 1, 2, d, 2); - SUB_S32(c, 0, 3, d, 3); - - PASS_THROUGH(c, d, 4); - - BUTTERFLY_ONE_S32(c, 6, 5, cospi_16_64, d, 6, 5); - - PASS_THROUGH(c, d, 7); - - ADDW_S16_S32(c, 11, a, 8, d, 8); - ADDW_S16_S32(c, 10, a, 9, d, 9); - SUBW_S16_S32(a, 9, c, 10, c, 9, d, 10); - SUBW_S16_S32(a, 8, c, 11, c, 8, d, 11); - SUBW_S16_S32(a, 15, c, 12, c, 15, d, 12); - SUBW_S16_S32(a, 14, c, 13, c, 14, d, 13); - ADDW_S16_S32(c, 13, b, 14, d, 14); - ADDW_S16_S32(c, 12, b, 15, d, 15); - - PASS_THROUGH(c, d, 16); - PASS_THROUGH(c, d, 17); - - BUTTERFLY_TWO_S32(c, 29, 18, cospi_8_64, cospi_24_64, d, 29, 18); - BUTTERFLY_TWO_S32(c, 28, 19, cospi_8_64, cospi_24_64, d, 28, 19); - BUTTERFLY_TWO_S32(c, 27, 20, cospi_24_64, -cospi_8_64, d, 27, 20); - BUTTERFLY_TWO_S32(c, 26, 21, cospi_24_64, -cospi_8_64, d, 26, 21); - - PASS_THROUGH(c, d, 22); - PASS_THROUGH(c, d, 23); - PASS_THROUGH(c, d, 24); - PASS_THROUGH(c, d, 25); - - PASS_THROUGH(c, d, 30); - PASS_THROUGH(c, d, 31); - - // Stage 5. - BUTTERFLY_ONE_S32(d, 0, 1, cospi_16_64, c, 0, 1); - BUTTERFLY_TWO_S32(d, 3, 2, cospi_8_64, cospi_24_64, c, 2, 3); - - ADD_S32(d, 4, 5, c, 4); - SUB_S32(d, 4, 5, c, 5); - SUB_S32(d, 7, 6, c, 6); - ADD_S32(d, 7, 6, c, 7); - - PASS_THROUGH(d, c, 8); - - BUTTERFLY_TWO_S32(d, 14, 9, cospi_8_64, cospi_24_64, c, 14, 9); - BUTTERFLY_TWO_S32(d, 13, 10, cospi_24_64, -cospi_8_64, c, 13, 10); - - PASS_THROUGH(d, c, 11); - PASS_THROUGH(d, c, 12); - PASS_THROUGH(d, c, 15); - - ADD_S32(d, 16, 19, c, 16); - ADD_S32(d, 17, 18, c, 17); - SUB_S32(d, 17, 18, c, 18); - SUB_S32(d, 16, 19, c, 19); - SUB_S32(d, 23, 20, c, 20); - SUB_S32(d, 22, 21, c, 21); - ADD_S32(d, 22, 21, c, 22); - ADD_S32(d, 23, 20, c, 23); - ADD_S32(d, 24, 27, c, 24); - ADD_S32(d, 25, 26, c, 25); - SUB_S32(d, 25, 26, c, 26); - SUB_S32(d, 24, 27, c, 27); - SUB_S32(d, 31, 28, c, 28); - SUB_S32(d, 30, 29, c, 29); - ADD_S32(d, 30, 29, c, 30); - ADD_S32(d, 31, 28, c, 31); - - // Stage 6. - PASS_THROUGH(c, d, 0); - PASS_THROUGH(c, d, 1); - PASS_THROUGH(c, d, 2); - PASS_THROUGH(c, d, 3); - - BUTTERFLY_TWO_S32(c, 7, 4, cospi_4_64, cospi_28_64, d, 4, 7); - BUTTERFLY_TWO_S32(c, 6, 5, cospi_20_64, cospi_12_64, d, 5, 6); - - ADD_S32(c, 8, 9, d, 8); - SUB_S32(c, 8, 9, d, 9); - SUB_S32(c, 11, 10, d, 10); - ADD_S32(c, 11, 10, d, 11); - ADD_S32(c, 12, 13, d, 12); - SUB_S32(c, 12, 13, d, 13); - SUB_S32(c, 15, 14, d, 14); - ADD_S32(c, 15, 14, d, 15); - - PASS_THROUGH(c, d, 16); - PASS_THROUGH(c, d, 19); - PASS_THROUGH(c, d, 20); - PASS_THROUGH(c, d, 23); - PASS_THROUGH(c, d, 24); - PASS_THROUGH(c, d, 27); - PASS_THROUGH(c, d, 28); - PASS_THROUGH(c, d, 31); - - BUTTERFLY_TWO_S32(c, 30, 17, cospi_4_64, cospi_28_64, d, 30, 17); - BUTTERFLY_TWO_S32(c, 29, 18, cospi_28_64, -cospi_4_64, d, 29, 18); - BUTTERFLY_TWO_S32(c, 26, 21, cospi_20_64, cospi_12_64, d, 26, 21); - BUTTERFLY_TWO_S32(c, 25, 22, cospi_12_64, -cospi_20_64, d, 25, 22); - - // Stage 7. - PASS_THROUGH(d, c, 0); - PASS_THROUGH(d, c, 1); - PASS_THROUGH(d, c, 2); - PASS_THROUGH(d, c, 3); - PASS_THROUGH(d, c, 4); - PASS_THROUGH(d, c, 5); - PASS_THROUGH(d, c, 6); - PASS_THROUGH(d, c, 7); - - BUTTERFLY_TWO_S32(d, 15, 8, cospi_2_64, cospi_30_64, c, 8, 15); - BUTTERFLY_TWO_S32(d, 14, 9, cospi_18_64, cospi_14_64, c, 9, 14); - BUTTERFLY_TWO_S32(d, 13, 10, cospi_10_64, cospi_22_64, c, 10, 13); - BUTTERFLY_TWO_S32(d, 12, 11, cospi_26_64, cospi_6_64, c, 11, 12); - - ADD_S32(d, 16, 17, c, 16); - SUB_S32(d, 16, 17, c, 17); - SUB_S32(d, 19, 18, c, 18); - ADD_S32(d, 19, 18, c, 19); - ADD_S32(d, 20, 21, c, 20); - SUB_S32(d, 20, 21, c, 21); - SUB_S32(d, 23, 22, c, 22); - ADD_S32(d, 23, 22, c, 23); - ADD_S32(d, 24, 25, c, 24); - SUB_S32(d, 24, 25, c, 25); - SUB_S32(d, 27, 26, c, 26); - ADD_S32(d, 27, 26, c, 27); - ADD_S32(d, 28, 29, c, 28); - SUB_S32(d, 28, 29, c, 29); - SUB_S32(d, 31, 30, c, 30); - ADD_S32(d, 31, 30, c, 31); - - // Final stage. - // Roll rounding into this function so we can pass back int16x8. - - out[0] = add_round_shift_s32_narrow(c_lo[0], c_hi[0]); - out[16] = add_round_shift_s32_narrow(c_lo[1], c_hi[1]); - - out[8] = add_round_shift_s32_narrow(c_lo[2], c_hi[2]); - out[24] = add_round_shift_s32_narrow(c_lo[3], c_hi[3]); - out[4] = add_round_shift_s32_narrow(c_lo[4], c_hi[4]); - out[20] = add_round_shift_s32_narrow(c_lo[5], c_hi[5]); - out[12] = add_round_shift_s32_narrow(c_lo[6], c_hi[6]); - - out[28] = add_round_shift_s32_narrow(c_lo[7], c_hi[7]); - out[2] = add_round_shift_s32_narrow(c_lo[8], c_hi[8]); - out[18] = add_round_shift_s32_narrow(c_lo[9], c_hi[9]); - out[10] = add_round_shift_s32_narrow(c_lo[10], c_hi[10]); - - out[26] = add_round_shift_s32_narrow(c_lo[11], c_hi[11]); - out[6] = add_round_shift_s32_narrow(c_lo[12], c_hi[12]); - out[22] = add_round_shift_s32_narrow(c_lo[13], c_hi[13]); - out[14] = add_round_shift_s32_narrow(c_lo[14], c_hi[14]); - out[30] = add_round_shift_s32_narrow(c_lo[15], c_hi[15]); - - BUTTERFLY_TWO_S32(c, 31, 16, cospi_1_64, cospi_31_64, d, 1, 31); - out[1] = add_round_shift_s32_narrow(d_lo[1], d_hi[1]); - out[31] = add_round_shift_s32_narrow(d_lo[31], d_hi[31]); - - BUTTERFLY_TWO_S32(c, 30, 17, cospi_17_64, cospi_15_64, d, 17, 15); - out[17] = add_round_shift_s32_narrow(d_lo[17], d_hi[17]); - out[15] = add_round_shift_s32_narrow(d_lo[15], d_hi[15]); - - BUTTERFLY_TWO_S32(c, 29, 18, cospi_9_64, cospi_23_64, d, 9, 23); - out[9] = add_round_shift_s32_narrow(d_lo[9], d_hi[9]); - out[23] = add_round_shift_s32_narrow(d_lo[23], d_hi[23]); - - BUTTERFLY_TWO_S32(c, 28, 19, cospi_25_64, cospi_7_64, d, 25, 7); - out[25] = add_round_shift_s32_narrow(d_lo[25], d_hi[25]); - out[7] = add_round_shift_s32_narrow(d_lo[7], d_hi[7]); - - BUTTERFLY_TWO_S32(c, 27, 20, cospi_5_64, cospi_27_64, d, 5, 27); - out[5] = add_round_shift_s32_narrow(d_lo[5], d_hi[5]); - out[27] = add_round_shift_s32_narrow(d_lo[27], d_hi[27]); - - BUTTERFLY_TWO_S32(c, 26, 21, cospi_21_64, cospi_11_64, d, 21, 11); - out[21] = add_round_shift_s32_narrow(d_lo[21], d_hi[21]); - out[11] = add_round_shift_s32_narrow(d_lo[11], d_hi[11]); - - BUTTERFLY_TWO_S32(c, 25, 22, cospi_13_64, cospi_19_64, d, 13, 19); - out[13] = add_round_shift_s32_narrow(d_lo[13], d_hi[13]); - out[19] = add_round_shift_s32_narrow(d_lo[19], d_hi[19]); - - BUTTERFLY_TWO_S32(c, 24, 23, cospi_29_64, cospi_3_64, d, 29, 3); - out[29] = add_round_shift_s32_narrow(d_lo[29], d_hi[29]); - out[3] = add_round_shift_s32_narrow(d_lo[3], d_hi[3]); -} - -static INLINE void dct_body_second_pass_rd(const int16x8_t *in, - int16x8_t *out) { - int16x8_t a[32]; - int16x8_t b[32]; - - // Stage 1. Done as part of the load for the first pass. - a[0] = vaddq_s16(in[0], in[31]); - a[1] = vaddq_s16(in[1], in[30]); - a[2] = vaddq_s16(in[2], in[29]); - a[3] = vaddq_s16(in[3], in[28]); - a[4] = vaddq_s16(in[4], in[27]); - a[5] = vaddq_s16(in[5], in[26]); - a[6] = vaddq_s16(in[6], in[25]); - a[7] = vaddq_s16(in[7], in[24]); - a[8] = vaddq_s16(in[8], in[23]); - a[9] = vaddq_s16(in[9], in[22]); - a[10] = vaddq_s16(in[10], in[21]); - a[11] = vaddq_s16(in[11], in[20]); - a[12] = vaddq_s16(in[12], in[19]); - a[13] = vaddq_s16(in[13], in[18]); - a[14] = vaddq_s16(in[14], in[17]); - a[15] = vaddq_s16(in[15], in[16]); - a[16] = vsubq_s16(in[15], in[16]); - a[17] = vsubq_s16(in[14], in[17]); - a[18] = vsubq_s16(in[13], in[18]); - a[19] = vsubq_s16(in[12], in[19]); - a[20] = vsubq_s16(in[11], in[20]); - a[21] = vsubq_s16(in[10], in[21]); - a[22] = vsubq_s16(in[9], in[22]); - a[23] = vsubq_s16(in[8], in[23]); - a[24] = vsubq_s16(in[7], in[24]); - a[25] = vsubq_s16(in[6], in[25]); - a[26] = vsubq_s16(in[5], in[26]); - a[27] = vsubq_s16(in[4], in[27]); - a[28] = vsubq_s16(in[3], in[28]); - a[29] = vsubq_s16(in[2], in[29]); - a[30] = vsubq_s16(in[1], in[30]); - a[31] = vsubq_s16(in[0], in[31]); - - // Stage 2. - // For the "rd" version, all the values are rounded down after stage 2 to keep - // the values in 16 bits. - b[0] = add_round_shift_s16(vaddq_s16(a[0], a[15])); - b[1] = add_round_shift_s16(vaddq_s16(a[1], a[14])); - b[2] = add_round_shift_s16(vaddq_s16(a[2], a[13])); - b[3] = add_round_shift_s16(vaddq_s16(a[3], a[12])); - b[4] = add_round_shift_s16(vaddq_s16(a[4], a[11])); - b[5] = add_round_shift_s16(vaddq_s16(a[5], a[10])); - b[6] = add_round_shift_s16(vaddq_s16(a[6], a[9])); - b[7] = add_round_shift_s16(vaddq_s16(a[7], a[8])); - - b[8] = add_round_shift_s16(vsubq_s16(a[7], a[8])); - b[9] = add_round_shift_s16(vsubq_s16(a[6], a[9])); - b[10] = add_round_shift_s16(vsubq_s16(a[5], a[10])); - b[11] = add_round_shift_s16(vsubq_s16(a[4], a[11])); - b[12] = add_round_shift_s16(vsubq_s16(a[3], a[12])); - b[13] = add_round_shift_s16(vsubq_s16(a[2], a[13])); - b[14] = add_round_shift_s16(vsubq_s16(a[1], a[14])); - b[15] = add_round_shift_s16(vsubq_s16(a[0], a[15])); - - b[16] = add_round_shift_s16(a[16]); - b[17] = add_round_shift_s16(a[17]); - b[18] = add_round_shift_s16(a[18]); - b[19] = add_round_shift_s16(a[19]); - - butterfly_one_coeff_s16_s32_narrow(a[27], a[20], cospi_16_64, &b[27], &b[20]); - butterfly_one_coeff_s16_s32_narrow(a[26], a[21], cospi_16_64, &b[26], &b[21]); - butterfly_one_coeff_s16_s32_narrow(a[25], a[22], cospi_16_64, &b[25], &b[22]); - butterfly_one_coeff_s16_s32_narrow(a[24], a[23], cospi_16_64, &b[24], &b[23]); - b[20] = add_round_shift_s16(b[20]); - b[21] = add_round_shift_s16(b[21]); - b[22] = add_round_shift_s16(b[22]); - b[23] = add_round_shift_s16(b[23]); - b[24] = add_round_shift_s16(b[24]); - b[25] = add_round_shift_s16(b[25]); - b[26] = add_round_shift_s16(b[26]); - b[27] = add_round_shift_s16(b[27]); - - b[28] = add_round_shift_s16(a[28]); - b[29] = add_round_shift_s16(a[29]); - b[30] = add_round_shift_s16(a[30]); - b[31] = add_round_shift_s16(a[31]); - - // Stage 3. - a[0] = vaddq_s16(b[0], b[7]); - a[1] = vaddq_s16(b[1], b[6]); - a[2] = vaddq_s16(b[2], b[5]); - a[3] = vaddq_s16(b[3], b[4]); - - a[4] = vsubq_s16(b[3], b[4]); - a[5] = vsubq_s16(b[2], b[5]); - a[6] = vsubq_s16(b[1], b[6]); - a[7] = vsubq_s16(b[0], b[7]); - - a[8] = b[8]; - a[9] = b[9]; - - butterfly_one_coeff_s16_s32_narrow(b[13], b[10], cospi_16_64, &a[13], &a[10]); - butterfly_one_coeff_s16_s32_narrow(b[12], b[11], cospi_16_64, &a[12], &a[11]); - - a[14] = b[14]; - a[15] = b[15]; - - a[16] = vaddq_s16(b[16], b[23]); - a[17] = vaddq_s16(b[17], b[22]); - a[18] = vaddq_s16(b[18], b[21]); - a[19] = vaddq_s16(b[19], b[20]); - - a[20] = vsubq_s16(b[19], b[20]); - a[21] = vsubq_s16(b[18], b[21]); - a[22] = vsubq_s16(b[17], b[22]); - a[23] = vsubq_s16(b[16], b[23]); - - a[24] = vsubq_s16(b[31], b[24]); - a[25] = vsubq_s16(b[30], b[25]); - a[26] = vsubq_s16(b[29], b[26]); - a[27] = vsubq_s16(b[28], b[27]); - - a[28] = vaddq_s16(b[28], b[27]); - a[29] = vaddq_s16(b[29], b[26]); - a[30] = vaddq_s16(b[30], b[25]); - a[31] = vaddq_s16(b[31], b[24]); - - // Stage 4. - b[0] = vaddq_s16(a[0], a[3]); - b[1] = vaddq_s16(a[1], a[2]); - b[2] = vsubq_s16(a[1], a[2]); - b[3] = vsubq_s16(a[0], a[3]); - - b[4] = a[4]; - - butterfly_one_coeff_s16_s32_narrow(a[6], a[5], cospi_16_64, &b[6], &b[5]); - - b[7] = a[7]; - - b[8] = vaddq_s16(a[8], a[11]); - b[9] = vaddq_s16(a[9], a[10]); - b[10] = vsubq_s16(a[9], a[10]); - b[11] = vsubq_s16(a[8], a[11]); - b[12] = vsubq_s16(a[15], a[12]); - b[13] = vsubq_s16(a[14], a[13]); - b[14] = vaddq_s16(a[14], a[13]); - b[15] = vaddq_s16(a[15], a[12]); - - b[16] = a[16]; - b[17] = a[17]; - - butterfly_two_coeff(a[29], a[18], cospi_8_64, cospi_24_64, &b[29], &b[18]); - butterfly_two_coeff(a[28], a[19], cospi_8_64, cospi_24_64, &b[28], &b[19]); - butterfly_two_coeff(a[27], a[20], cospi_24_64, -cospi_8_64, &b[27], &b[20]); - butterfly_two_coeff(a[26], a[21], cospi_24_64, -cospi_8_64, &b[26], &b[21]); - - b[22] = a[22]; - b[23] = a[23]; - b[24] = a[24]; - b[25] = a[25]; - - b[30] = a[30]; - b[31] = a[31]; - - // Stage 5. - butterfly_one_coeff_s16_s32_narrow(b[0], b[1], cospi_16_64, &a[0], &a[1]); - butterfly_two_coeff(b[3], b[2], cospi_8_64, cospi_24_64, &a[2], &a[3]); - - a[4] = vaddq_s16(b[4], b[5]); - a[5] = vsubq_s16(b[4], b[5]); - a[6] = vsubq_s16(b[7], b[6]); - a[7] = vaddq_s16(b[7], b[6]); - - a[8] = b[8]; - - butterfly_two_coeff(b[14], b[9], cospi_8_64, cospi_24_64, &a[14], &a[9]); - butterfly_two_coeff(b[13], b[10], cospi_24_64, -cospi_8_64, &a[13], &a[10]); - - a[11] = b[11]; - a[12] = b[12]; - - a[15] = b[15]; - - a[16] = vaddq_s16(b[19], b[16]); - a[17] = vaddq_s16(b[18], b[17]); - a[18] = vsubq_s16(b[17], b[18]); - a[19] = vsubq_s16(b[16], b[19]); - a[20] = vsubq_s16(b[23], b[20]); - a[21] = vsubq_s16(b[22], b[21]); - a[22] = vaddq_s16(b[21], b[22]); - a[23] = vaddq_s16(b[20], b[23]); - a[24] = vaddq_s16(b[27], b[24]); - a[25] = vaddq_s16(b[26], b[25]); - a[26] = vsubq_s16(b[25], b[26]); - a[27] = vsubq_s16(b[24], b[27]); - a[28] = vsubq_s16(b[31], b[28]); - a[29] = vsubq_s16(b[30], b[29]); - a[30] = vaddq_s16(b[29], b[30]); - a[31] = vaddq_s16(b[28], b[31]); - - // Stage 6. - b[0] = a[0]; - b[1] = a[1]; - b[2] = a[2]; - b[3] = a[3]; - - butterfly_two_coeff(a[7], a[4], cospi_4_64, cospi_28_64, &b[4], &b[7]); - butterfly_two_coeff(a[6], a[5], cospi_20_64, cospi_12_64, &b[5], &b[6]); - - b[8] = vaddq_s16(a[8], a[9]); - b[9] = vsubq_s16(a[8], a[9]); - b[10] = vsubq_s16(a[11], a[10]); - b[11] = vaddq_s16(a[11], a[10]); - b[12] = vaddq_s16(a[12], a[13]); - b[13] = vsubq_s16(a[12], a[13]); - b[14] = vsubq_s16(a[15], a[14]); - b[15] = vaddq_s16(a[15], a[14]); - - b[16] = a[16]; - b[19] = a[19]; - b[20] = a[20]; - b[23] = a[23]; - b[24] = a[24]; - b[27] = a[27]; - b[28] = a[28]; - b[31] = a[31]; - - butterfly_two_coeff(a[30], a[17], cospi_4_64, cospi_28_64, &b[30], &b[17]); - butterfly_two_coeff(a[29], a[18], cospi_28_64, -cospi_4_64, &b[29], &b[18]); - - butterfly_two_coeff(a[26], a[21], cospi_20_64, cospi_12_64, &b[26], &b[21]); - butterfly_two_coeff(a[25], a[22], cospi_12_64, -cospi_20_64, &b[25], &b[22]); - - // Stage 7. - a[0] = b[0]; - a[1] = b[1]; - a[2] = b[2]; - a[3] = b[3]; - a[4] = b[4]; - a[5] = b[5]; - a[6] = b[6]; - a[7] = b[7]; - - butterfly_two_coeff(b[15], b[8], cospi_2_64, cospi_30_64, &a[8], &a[15]); - butterfly_two_coeff(b[14], b[9], cospi_18_64, cospi_14_64, &a[9], &a[14]); - butterfly_two_coeff(b[13], b[10], cospi_10_64, cospi_22_64, &a[10], &a[13]); - butterfly_two_coeff(b[12], b[11], cospi_26_64, cospi_6_64, &a[11], &a[12]); - - a[16] = vaddq_s16(b[16], b[17]); - a[17] = vsubq_s16(b[16], b[17]); - a[18] = vsubq_s16(b[19], b[18]); - a[19] = vaddq_s16(b[19], b[18]); - a[20] = vaddq_s16(b[20], b[21]); - a[21] = vsubq_s16(b[20], b[21]); - a[22] = vsubq_s16(b[23], b[22]); - a[23] = vaddq_s16(b[23], b[22]); - a[24] = vaddq_s16(b[24], b[25]); - a[25] = vsubq_s16(b[24], b[25]); - a[26] = vsubq_s16(b[27], b[26]); - a[27] = vaddq_s16(b[27], b[26]); - a[28] = vaddq_s16(b[28], b[29]); - a[29] = vsubq_s16(b[28], b[29]); - a[30] = vsubq_s16(b[31], b[30]); - a[31] = vaddq_s16(b[31], b[30]); - - // Final stage. - out[0] = a[0]; - out[16] = a[1]; - out[8] = a[2]; - out[24] = a[3]; - out[4] = a[4]; - out[20] = a[5]; - out[12] = a[6]; - out[28] = a[7]; - out[2] = a[8]; - out[18] = a[9]; - out[10] = a[10]; - out[26] = a[11]; - out[6] = a[12]; - out[22] = a[13]; - out[14] = a[14]; - out[30] = a[15]; - - butterfly_two_coeff(a[31], a[16], cospi_1_64, cospi_31_64, &out[1], &out[31]); - butterfly_two_coeff(a[30], a[17], cospi_17_64, cospi_15_64, &out[17], - &out[15]); - butterfly_two_coeff(a[29], a[18], cospi_9_64, cospi_23_64, &out[9], &out[23]); - butterfly_two_coeff(a[28], a[19], cospi_25_64, cospi_7_64, &out[25], &out[7]); - butterfly_two_coeff(a[27], a[20], cospi_5_64, cospi_27_64, &out[5], &out[27]); - butterfly_two_coeff(a[26], a[21], cospi_21_64, cospi_11_64, &out[21], - &out[11]); - butterfly_two_coeff(a[25], a[22], cospi_13_64, cospi_19_64, &out[13], - &out[19]); - butterfly_two_coeff(a[24], a[23], cospi_29_64, cospi_3_64, &out[29], &out[3]); -} - -#undef PASS_THROUGH -#undef ADD_S16_S32 -#undef SUB_S16_S32 -#undef ADDW_S16_S32 -#undef SUBW_S16_S32 -#undef ADD_S32 -#undef SUB_S32 -#undef BUTTERFLY_ONE_S16_S32 -#undef BUTTERFLY_ONE_S32 -#undef BUTTERFLY_TWO_S32 - -#if CONFIG_VP9_HIGHBITDEPTH - -// Store 32 32x4 vectors, assuming stride == 32. -static INLINE void store32x32_s32( - tran_low_t *a, const int32x4_t *l1 /*[16]*/, const int32x4_t *r1 /*[16]*/, - const int32x4_t *l2 /*[16]*/, const int32x4_t *r2 /*[16]*/, - const int32x4_t *l3 /*[16]*/, const int32x4_t *r3 /*[16]*/, - const int32x4_t *l4 /*[16]*/, const int32x4_t *r4 /*[16]*/) { - int i; - for (i = 0; i < 32; i++) { - vst1q_s32(a, l1[i]); - vst1q_s32(a + 4, r1[i]); - vst1q_s32(a + 8, l2[i]); - vst1q_s32(a + 12, r2[i]); - vst1q_s32(a + 16, l3[i]); - vst1q_s32(a + 20, r3[i]); - vst1q_s32(a + 24, l4[i]); - vst1q_s32(a + 28, r4[i]); - a += 32; - } -} - -static INLINE void highbd_scale_input(const int16x8_t *a /*[32]*/, - int32x4_t *left /*[32]*/, - int32x4_t *right /* [32] */) { - left[0] = vshll_n_s16(vget_low_s16(a[0]), 2); - left[1] = vshll_n_s16(vget_low_s16(a[1]), 2); - left[2] = vshll_n_s16(vget_low_s16(a[2]), 2); - left[3] = vshll_n_s16(vget_low_s16(a[3]), 2); - left[4] = vshll_n_s16(vget_low_s16(a[4]), 2); - left[5] = vshll_n_s16(vget_low_s16(a[5]), 2); - left[6] = vshll_n_s16(vget_low_s16(a[6]), 2); - left[7] = vshll_n_s16(vget_low_s16(a[7]), 2); - left[8] = vshll_n_s16(vget_low_s16(a[8]), 2); - left[9] = vshll_n_s16(vget_low_s16(a[9]), 2); - left[10] = vshll_n_s16(vget_low_s16(a[10]), 2); - left[11] = vshll_n_s16(vget_low_s16(a[11]), 2); - left[12] = vshll_n_s16(vget_low_s16(a[12]), 2); - left[13] = vshll_n_s16(vget_low_s16(a[13]), 2); - left[14] = vshll_n_s16(vget_low_s16(a[14]), 2); - left[15] = vshll_n_s16(vget_low_s16(a[15]), 2); - left[16] = vshll_n_s16(vget_low_s16(a[16]), 2); - left[17] = vshll_n_s16(vget_low_s16(a[17]), 2); - left[18] = vshll_n_s16(vget_low_s16(a[18]), 2); - left[19] = vshll_n_s16(vget_low_s16(a[19]), 2); - left[20] = vshll_n_s16(vget_low_s16(a[20]), 2); - left[21] = vshll_n_s16(vget_low_s16(a[21]), 2); - left[22] = vshll_n_s16(vget_low_s16(a[22]), 2); - left[23] = vshll_n_s16(vget_low_s16(a[23]), 2); - left[24] = vshll_n_s16(vget_low_s16(a[24]), 2); - left[25] = vshll_n_s16(vget_low_s16(a[25]), 2); - left[26] = vshll_n_s16(vget_low_s16(a[26]), 2); - left[27] = vshll_n_s16(vget_low_s16(a[27]), 2); - left[28] = vshll_n_s16(vget_low_s16(a[28]), 2); - left[29] = vshll_n_s16(vget_low_s16(a[29]), 2); - left[30] = vshll_n_s16(vget_low_s16(a[30]), 2); - left[31] = vshll_n_s16(vget_low_s16(a[31]), 2); - - right[0] = vshll_n_s16(vget_high_s16(a[0]), 2); - right[1] = vshll_n_s16(vget_high_s16(a[1]), 2); - right[2] = vshll_n_s16(vget_high_s16(a[2]), 2); - right[3] = vshll_n_s16(vget_high_s16(a[3]), 2); - right[4] = vshll_n_s16(vget_high_s16(a[4]), 2); - right[5] = vshll_n_s16(vget_high_s16(a[5]), 2); - right[6] = vshll_n_s16(vget_high_s16(a[6]), 2); - right[7] = vshll_n_s16(vget_high_s16(a[7]), 2); - right[8] = vshll_n_s16(vget_high_s16(a[8]), 2); - right[9] = vshll_n_s16(vget_high_s16(a[9]), 2); - right[10] = vshll_n_s16(vget_high_s16(a[10]), 2); - right[11] = vshll_n_s16(vget_high_s16(a[11]), 2); - right[12] = vshll_n_s16(vget_high_s16(a[12]), 2); - right[13] = vshll_n_s16(vget_high_s16(a[13]), 2); - right[14] = vshll_n_s16(vget_high_s16(a[14]), 2); - right[15] = vshll_n_s16(vget_high_s16(a[15]), 2); - right[16] = vshll_n_s16(vget_high_s16(a[16]), 2); - right[17] = vshll_n_s16(vget_high_s16(a[17]), 2); - right[18] = vshll_n_s16(vget_high_s16(a[18]), 2); - right[19] = vshll_n_s16(vget_high_s16(a[19]), 2); - right[20] = vshll_n_s16(vget_high_s16(a[20]), 2); - right[21] = vshll_n_s16(vget_high_s16(a[21]), 2); - right[22] = vshll_n_s16(vget_high_s16(a[22]), 2); - right[23] = vshll_n_s16(vget_high_s16(a[23]), 2); - right[24] = vshll_n_s16(vget_high_s16(a[24]), 2); - right[25] = vshll_n_s16(vget_high_s16(a[25]), 2); - right[26] = vshll_n_s16(vget_high_s16(a[26]), 2); - right[27] = vshll_n_s16(vget_high_s16(a[27]), 2); - right[28] = vshll_n_s16(vget_high_s16(a[28]), 2); - right[29] = vshll_n_s16(vget_high_s16(a[29]), 2); - right[30] = vshll_n_s16(vget_high_s16(a[30]), 2); - right[31] = vshll_n_s16(vget_high_s16(a[31]), 2); -} - -static INLINE void highbd_cross_input(const int32x4_t *a_left /*[32]*/, - int32x4_t *a_right /*[32]*/, - int32x4_t *b_left /*[32]*/, - int32x4_t *b_right /*[32]*/) { - // Stage 1. Done as part of the load for the first pass. - b_left[0] = vaddq_s32(a_left[0], a_left[31]); - b_left[1] = vaddq_s32(a_left[1], a_left[30]); - b_left[2] = vaddq_s32(a_left[2], a_left[29]); - b_left[3] = vaddq_s32(a_left[3], a_left[28]); - b_left[4] = vaddq_s32(a_left[4], a_left[27]); - b_left[5] = vaddq_s32(a_left[5], a_left[26]); - b_left[6] = vaddq_s32(a_left[6], a_left[25]); - b_left[7] = vaddq_s32(a_left[7], a_left[24]); - b_left[8] = vaddq_s32(a_left[8], a_left[23]); - b_left[9] = vaddq_s32(a_left[9], a_left[22]); - b_left[10] = vaddq_s32(a_left[10], a_left[21]); - b_left[11] = vaddq_s32(a_left[11], a_left[20]); - b_left[12] = vaddq_s32(a_left[12], a_left[19]); - b_left[13] = vaddq_s32(a_left[13], a_left[18]); - b_left[14] = vaddq_s32(a_left[14], a_left[17]); - b_left[15] = vaddq_s32(a_left[15], a_left[16]); - - b_right[0] = vaddq_s32(a_right[0], a_right[31]); - b_right[1] = vaddq_s32(a_right[1], a_right[30]); - b_right[2] = vaddq_s32(a_right[2], a_right[29]); - b_right[3] = vaddq_s32(a_right[3], a_right[28]); - b_right[4] = vaddq_s32(a_right[4], a_right[27]); - b_right[5] = vaddq_s32(a_right[5], a_right[26]); - b_right[6] = vaddq_s32(a_right[6], a_right[25]); - b_right[7] = vaddq_s32(a_right[7], a_right[24]); - b_right[8] = vaddq_s32(a_right[8], a_right[23]); - b_right[9] = vaddq_s32(a_right[9], a_right[22]); - b_right[10] = vaddq_s32(a_right[10], a_right[21]); - b_right[11] = vaddq_s32(a_right[11], a_right[20]); - b_right[12] = vaddq_s32(a_right[12], a_right[19]); - b_right[13] = vaddq_s32(a_right[13], a_right[18]); - b_right[14] = vaddq_s32(a_right[14], a_right[17]); - b_right[15] = vaddq_s32(a_right[15], a_right[16]); - - b_left[16] = vsubq_s32(a_left[15], a_left[16]); - b_left[17] = vsubq_s32(a_left[14], a_left[17]); - b_left[18] = vsubq_s32(a_left[13], a_left[18]); - b_left[19] = vsubq_s32(a_left[12], a_left[19]); - b_left[20] = vsubq_s32(a_left[11], a_left[20]); - b_left[21] = vsubq_s32(a_left[10], a_left[21]); - b_left[22] = vsubq_s32(a_left[9], a_left[22]); - b_left[23] = vsubq_s32(a_left[8], a_left[23]); - b_left[24] = vsubq_s32(a_left[7], a_left[24]); - b_left[25] = vsubq_s32(a_left[6], a_left[25]); - b_left[26] = vsubq_s32(a_left[5], a_left[26]); - b_left[27] = vsubq_s32(a_left[4], a_left[27]); - b_left[28] = vsubq_s32(a_left[3], a_left[28]); - b_left[29] = vsubq_s32(a_left[2], a_left[29]); - b_left[30] = vsubq_s32(a_left[1], a_left[30]); - b_left[31] = vsubq_s32(a_left[0], a_left[31]); - - b_right[16] = vsubq_s32(a_right[15], a_right[16]); - b_right[17] = vsubq_s32(a_right[14], a_right[17]); - b_right[18] = vsubq_s32(a_right[13], a_right[18]); - b_right[19] = vsubq_s32(a_right[12], a_right[19]); - b_right[20] = vsubq_s32(a_right[11], a_right[20]); - b_right[21] = vsubq_s32(a_right[10], a_right[21]); - b_right[22] = vsubq_s32(a_right[9], a_right[22]); - b_right[23] = vsubq_s32(a_right[8], a_right[23]); - b_right[24] = vsubq_s32(a_right[7], a_right[24]); - b_right[25] = vsubq_s32(a_right[6], a_right[25]); - b_right[26] = vsubq_s32(a_right[5], a_right[26]); - b_right[27] = vsubq_s32(a_right[4], a_right[27]); - b_right[28] = vsubq_s32(a_right[3], a_right[28]); - b_right[29] = vsubq_s32(a_right[2], a_right[29]); - b_right[30] = vsubq_s32(a_right[1], a_right[30]); - b_right[31] = vsubq_s32(a_right[0], a_right[31]); -} - -static INLINE void highbd_partial_add_round_shift(int32x4_t *left /*[32]*/, - int32x4_t *right /* [32] */) { - // Also compute partial rounding shift: - // output[j * 32 + i] = (temp_out[j] + 1 + (temp_out[j] > 0)) >> 2; - - left[0] = add_round_shift_s32(left[0]); - left[1] = add_round_shift_s32(left[1]); - left[2] = add_round_shift_s32(left[2]); - left[3] = add_round_shift_s32(left[3]); - left[4] = add_round_shift_s32(left[4]); - left[5] = add_round_shift_s32(left[5]); - left[6] = add_round_shift_s32(left[6]); - left[7] = add_round_shift_s32(left[7]); - left[8] = add_round_shift_s32(left[8]); - left[9] = add_round_shift_s32(left[9]); - left[10] = add_round_shift_s32(left[10]); - left[11] = add_round_shift_s32(left[11]); - left[12] = add_round_shift_s32(left[12]); - left[13] = add_round_shift_s32(left[13]); - left[14] = add_round_shift_s32(left[14]); - left[15] = add_round_shift_s32(left[15]); - left[16] = add_round_shift_s32(left[16]); - left[17] = add_round_shift_s32(left[17]); - left[18] = add_round_shift_s32(left[18]); - left[19] = add_round_shift_s32(left[19]); - left[20] = add_round_shift_s32(left[20]); - left[21] = add_round_shift_s32(left[21]); - left[22] = add_round_shift_s32(left[22]); - left[23] = add_round_shift_s32(left[23]); - left[24] = add_round_shift_s32(left[24]); - left[25] = add_round_shift_s32(left[25]); - left[26] = add_round_shift_s32(left[26]); - left[27] = add_round_shift_s32(left[27]); - left[28] = add_round_shift_s32(left[28]); - left[29] = add_round_shift_s32(left[29]); - left[30] = add_round_shift_s32(left[30]); - left[31] = add_round_shift_s32(left[31]); - - right[0] = add_round_shift_s32(right[0]); - right[1] = add_round_shift_s32(right[1]); - right[2] = add_round_shift_s32(right[2]); - right[3] = add_round_shift_s32(right[3]); - right[4] = add_round_shift_s32(right[4]); - right[5] = add_round_shift_s32(right[5]); - right[6] = add_round_shift_s32(right[6]); - right[7] = add_round_shift_s32(right[7]); - right[8] = add_round_shift_s32(right[8]); - right[9] = add_round_shift_s32(right[9]); - right[10] = add_round_shift_s32(right[10]); - right[11] = add_round_shift_s32(right[11]); - right[12] = add_round_shift_s32(right[12]); - right[13] = add_round_shift_s32(right[13]); - right[14] = add_round_shift_s32(right[14]); - right[15] = add_round_shift_s32(right[15]); - right[16] = add_round_shift_s32(right[16]); - right[17] = add_round_shift_s32(right[17]); - right[18] = add_round_shift_s32(right[18]); - right[19] = add_round_shift_s32(right[19]); - right[20] = add_round_shift_s32(right[20]); - right[21] = add_round_shift_s32(right[21]); - right[22] = add_round_shift_s32(right[22]); - right[23] = add_round_shift_s32(right[23]); - right[24] = add_round_shift_s32(right[24]); - right[25] = add_round_shift_s32(right[25]); - right[26] = add_round_shift_s32(right[26]); - right[27] = add_round_shift_s32(right[27]); - right[28] = add_round_shift_s32(right[28]); - right[29] = add_round_shift_s32(right[29]); - right[30] = add_round_shift_s32(right[30]); - right[31] = add_round_shift_s32(right[31]); -} - -static INLINE void highbd_partial_sub_round_shift(int32x4_t *left /*[32]*/, - int32x4_t *right /* [32] */) { - // Also compute partial rounding shift: - // output[j * 32 + i] = (temp_out[j] + 1 + (temp_out[j] > 0)) >> 2; - - left[0] = sub_round_shift_s32(left[0]); - left[1] = sub_round_shift_s32(left[1]); - left[2] = sub_round_shift_s32(left[2]); - left[3] = sub_round_shift_s32(left[3]); - left[4] = sub_round_shift_s32(left[4]); - left[5] = sub_round_shift_s32(left[5]); - left[6] = sub_round_shift_s32(left[6]); - left[7] = sub_round_shift_s32(left[7]); - left[8] = sub_round_shift_s32(left[8]); - left[9] = sub_round_shift_s32(left[9]); - left[10] = sub_round_shift_s32(left[10]); - left[11] = sub_round_shift_s32(left[11]); - left[12] = sub_round_shift_s32(left[12]); - left[13] = sub_round_shift_s32(left[13]); - left[14] = sub_round_shift_s32(left[14]); - left[15] = sub_round_shift_s32(left[15]); - left[16] = sub_round_shift_s32(left[16]); - left[17] = sub_round_shift_s32(left[17]); - left[18] = sub_round_shift_s32(left[18]); - left[19] = sub_round_shift_s32(left[19]); - left[20] = sub_round_shift_s32(left[20]); - left[21] = sub_round_shift_s32(left[21]); - left[22] = sub_round_shift_s32(left[22]); - left[23] = sub_round_shift_s32(left[23]); - left[24] = sub_round_shift_s32(left[24]); - left[25] = sub_round_shift_s32(left[25]); - left[26] = sub_round_shift_s32(left[26]); - left[27] = sub_round_shift_s32(left[27]); - left[28] = sub_round_shift_s32(left[28]); - left[29] = sub_round_shift_s32(left[29]); - left[30] = sub_round_shift_s32(left[30]); - left[31] = sub_round_shift_s32(left[31]); - - right[0] = sub_round_shift_s32(right[0]); - right[1] = sub_round_shift_s32(right[1]); - right[2] = sub_round_shift_s32(right[2]); - right[3] = sub_round_shift_s32(right[3]); - right[4] = sub_round_shift_s32(right[4]); - right[5] = sub_round_shift_s32(right[5]); - right[6] = sub_round_shift_s32(right[6]); - right[7] = sub_round_shift_s32(right[7]); - right[8] = sub_round_shift_s32(right[8]); - right[9] = sub_round_shift_s32(right[9]); - right[10] = sub_round_shift_s32(right[10]); - right[11] = sub_round_shift_s32(right[11]); - right[12] = sub_round_shift_s32(right[12]); - right[13] = sub_round_shift_s32(right[13]); - right[14] = sub_round_shift_s32(right[14]); - right[15] = sub_round_shift_s32(right[15]); - right[16] = sub_round_shift_s32(right[16]); - right[17] = sub_round_shift_s32(right[17]); - right[18] = sub_round_shift_s32(right[18]); - right[19] = sub_round_shift_s32(right[19]); - right[20] = sub_round_shift_s32(right[20]); - right[21] = sub_round_shift_s32(right[21]); - right[22] = sub_round_shift_s32(right[22]); - right[23] = sub_round_shift_s32(right[23]); - right[24] = sub_round_shift_s32(right[24]); - right[25] = sub_round_shift_s32(right[25]); - right[26] = sub_round_shift_s32(right[26]); - right[27] = sub_round_shift_s32(right[27]); - right[28] = sub_round_shift_s32(right[28]); - right[29] = sub_round_shift_s32(right[29]); - right[30] = sub_round_shift_s32(right[30]); - right[31] = sub_round_shift_s32(right[31]); -} - -static INLINE void highbd_dct8x32_body_first_pass(int32x4_t *left /*32*/, - int32x4_t *right /*32*/) { - int32x4_t al[32], ar[32]; - int32x4_t bl[32], br[32]; - - // Stage 1: Done as part of the load. - - // Stage 2. - // Mini cross. X the first 16 values and the middle 8 of the second half. - al[0] = vaddq_s32(left[0], left[15]); - ar[0] = vaddq_s32(right[0], right[15]); - al[1] = vaddq_s32(left[1], left[14]); - ar[1] = vaddq_s32(right[1], right[14]); - al[2] = vaddq_s32(left[2], left[13]); - ar[2] = vaddq_s32(right[2], right[13]); - al[3] = vaddq_s32(left[3], left[12]); - ar[3] = vaddq_s32(right[3], right[12]); - al[4] = vaddq_s32(left[4], left[11]); - ar[4] = vaddq_s32(right[4], right[11]); - al[5] = vaddq_s32(left[5], left[10]); - ar[5] = vaddq_s32(right[5], right[10]); - al[6] = vaddq_s32(left[6], left[9]); - ar[6] = vaddq_s32(right[6], right[9]); - al[7] = vaddq_s32(left[7], left[8]); - ar[7] = vaddq_s32(right[7], right[8]); - - al[8] = vsubq_s32(left[7], left[8]); - ar[8] = vsubq_s32(right[7], right[8]); - al[9] = vsubq_s32(left[6], left[9]); - ar[9] = vsubq_s32(right[6], right[9]); - al[10] = vsubq_s32(left[5], left[10]); - ar[10] = vsubq_s32(right[5], right[10]); - al[11] = vsubq_s32(left[4], left[11]); - ar[11] = vsubq_s32(right[4], right[11]); - al[12] = vsubq_s32(left[3], left[12]); - ar[12] = vsubq_s32(right[3], right[12]); - al[13] = vsubq_s32(left[2], left[13]); - ar[13] = vsubq_s32(right[2], right[13]); - al[14] = vsubq_s32(left[1], left[14]); - ar[14] = vsubq_s32(right[1], right[14]); - al[15] = vsubq_s32(left[0], left[15]); - ar[15] = vsubq_s32(right[0], right[15]); - - al[16] = left[16]; - ar[16] = right[16]; - al[17] = left[17]; - ar[17] = right[17]; - al[18] = left[18]; - ar[18] = right[18]; - al[19] = left[19]; - ar[19] = right[19]; - - butterfly_one_coeff_s32_fast(left[27], right[27], left[20], right[20], - cospi_16_64, &al[27], &ar[27], &al[20], &ar[20]); - butterfly_one_coeff_s32_fast(left[26], right[26], left[21], right[21], - cospi_16_64, &al[26], &ar[26], &al[21], &ar[21]); - butterfly_one_coeff_s32_fast(left[25], right[25], left[22], right[22], - cospi_16_64, &al[25], &ar[25], &al[22], &ar[22]); - butterfly_one_coeff_s32_fast(left[24], right[24], left[23], right[23], - cospi_16_64, &al[24], &ar[24], &al[23], &ar[23]); - - al[28] = left[28]; - ar[28] = right[28]; - al[29] = left[29]; - ar[29] = right[29]; - al[30] = left[30]; - ar[30] = right[30]; - al[31] = left[31]; - ar[31] = right[31]; - - // Stage 3. - bl[0] = vaddq_s32(al[0], al[7]); - br[0] = vaddq_s32(ar[0], ar[7]); - bl[1] = vaddq_s32(al[1], al[6]); - br[1] = vaddq_s32(ar[1], ar[6]); - bl[2] = vaddq_s32(al[2], al[5]); - br[2] = vaddq_s32(ar[2], ar[5]); - bl[3] = vaddq_s32(al[3], al[4]); - br[3] = vaddq_s32(ar[3], ar[4]); - - bl[4] = vsubq_s32(al[3], al[4]); - br[4] = vsubq_s32(ar[3], ar[4]); - bl[5] = vsubq_s32(al[2], al[5]); - br[5] = vsubq_s32(ar[2], ar[5]); - bl[6] = vsubq_s32(al[1], al[6]); - br[6] = vsubq_s32(ar[1], ar[6]); - bl[7] = vsubq_s32(al[0], al[7]); - br[7] = vsubq_s32(ar[0], ar[7]); - - bl[8] = al[8]; - br[8] = ar[8]; - bl[9] = al[9]; - br[9] = ar[9]; - - butterfly_one_coeff_s32_fast(al[13], ar[13], al[10], ar[10], cospi_16_64, - &bl[13], &br[13], &bl[10], &br[10]); - butterfly_one_coeff_s32_fast(al[12], ar[12], al[11], ar[11], cospi_16_64, - &bl[12], &br[12], &bl[11], &br[11]); - - bl[14] = al[14]; - br[14] = ar[14]; - bl[15] = al[15]; - br[15] = ar[15]; - - bl[16] = vaddq_s32(left[16], al[23]); - br[16] = vaddq_s32(right[16], ar[23]); - bl[17] = vaddq_s32(left[17], al[22]); - br[17] = vaddq_s32(right[17], ar[22]); - bl[18] = vaddq_s32(left[18], al[21]); - br[18] = vaddq_s32(right[18], ar[21]); - bl[19] = vaddq_s32(left[19], al[20]); - br[19] = vaddq_s32(right[19], ar[20]); - - bl[20] = vsubq_s32(left[19], al[20]); - br[20] = vsubq_s32(right[19], ar[20]); - bl[21] = vsubq_s32(left[18], al[21]); - br[21] = vsubq_s32(right[18], ar[21]); - bl[22] = vsubq_s32(left[17], al[22]); - br[22] = vsubq_s32(right[17], ar[22]); - bl[23] = vsubq_s32(left[16], al[23]); - br[23] = vsubq_s32(right[16], ar[23]); - - bl[24] = vsubq_s32(left[31], al[24]); - br[24] = vsubq_s32(right[31], ar[24]); - bl[25] = vsubq_s32(left[30], al[25]); - br[25] = vsubq_s32(right[30], ar[25]); - bl[26] = vsubq_s32(left[29], al[26]); - br[26] = vsubq_s32(right[29], ar[26]); - bl[27] = vsubq_s32(left[28], al[27]); - br[27] = vsubq_s32(right[28], ar[27]); - - bl[28] = vaddq_s32(left[28], al[27]); - br[28] = vaddq_s32(right[28], ar[27]); - bl[29] = vaddq_s32(left[29], al[26]); - br[29] = vaddq_s32(right[29], ar[26]); - bl[30] = vaddq_s32(left[30], al[25]); - br[30] = vaddq_s32(right[30], ar[25]); - bl[31] = vaddq_s32(left[31], al[24]); - br[31] = vaddq_s32(right[31], ar[24]); - - // Stage 4. - al[0] = vaddq_s32(bl[0], bl[3]); - ar[0] = vaddq_s32(br[0], br[3]); - al[1] = vaddq_s32(bl[1], bl[2]); - ar[1] = vaddq_s32(br[1], br[2]); - al[2] = vsubq_s32(bl[1], bl[2]); - ar[2] = vsubq_s32(br[1], br[2]); - al[3] = vsubq_s32(bl[0], bl[3]); - ar[3] = vsubq_s32(br[0], br[3]); - - al[4] = bl[4]; - ar[4] = br[4]; - - butterfly_one_coeff_s32_fast(bl[6], br[6], bl[5], br[5], cospi_16_64, &al[6], - &ar[6], &al[5], &ar[5]); - - al[7] = bl[7]; - ar[7] = br[7]; - - al[8] = vaddq_s32(bl[8], bl[11]); - ar[8] = vaddq_s32(br[8], br[11]); - al[9] = vaddq_s32(bl[9], bl[10]); - ar[9] = vaddq_s32(br[9], br[10]); - al[10] = vsubq_s32(bl[9], bl[10]); - ar[10] = vsubq_s32(br[9], br[10]); - al[11] = vsubq_s32(bl[8], bl[11]); - ar[11] = vsubq_s32(br[8], br[11]); - al[12] = vsubq_s32(bl[15], bl[12]); - ar[12] = vsubq_s32(br[15], br[12]); - al[13] = vsubq_s32(bl[14], bl[13]); - ar[13] = vsubq_s32(br[14], br[13]); - al[14] = vaddq_s32(bl[14], bl[13]); - ar[14] = vaddq_s32(br[14], br[13]); - al[15] = vaddq_s32(bl[15], bl[12]); - ar[15] = vaddq_s32(br[15], br[12]); - - al[16] = bl[16]; - ar[16] = br[16]; - al[17] = bl[17]; - ar[17] = br[17]; - - butterfly_two_coeff_s32_s64_narrow(bl[29], br[29], bl[18], br[18], cospi_8_64, - cospi_24_64, &al[29], &ar[29], &al[18], - &ar[18]); - butterfly_two_coeff_s32_s64_narrow(bl[28], br[28], bl[19], br[19], cospi_8_64, - cospi_24_64, &al[28], &ar[28], &al[19], - &ar[19]); - butterfly_two_coeff_s32_s64_narrow(bl[27], br[27], bl[20], br[20], - cospi_24_64, -cospi_8_64, &al[27], &ar[27], - &al[20], &ar[20]); - butterfly_two_coeff_s32_s64_narrow(bl[26], br[26], bl[21], br[21], - cospi_24_64, -cospi_8_64, &al[26], &ar[26], - &al[21], &ar[21]); - - al[22] = bl[22]; - ar[22] = br[22]; - al[23] = bl[23]; - ar[23] = br[23]; - al[24] = bl[24]; - ar[24] = br[24]; - al[25] = bl[25]; - ar[25] = br[25]; - - al[30] = bl[30]; - ar[30] = br[30]; - al[31] = bl[31]; - ar[31] = br[31]; - - // Stage 5. - butterfly_one_coeff_s32_fast(al[0], ar[0], al[1], ar[1], cospi_16_64, &bl[0], - &br[0], &bl[1], &br[1]); - butterfly_two_coeff_s32_s64_narrow(al[3], ar[3], al[2], ar[2], cospi_8_64, - cospi_24_64, &bl[2], &br[2], &bl[3], - &br[3]); - - bl[4] = vaddq_s32(al[4], al[5]); - br[4] = vaddq_s32(ar[4], ar[5]); - bl[5] = vsubq_s32(al[4], al[5]); - br[5] = vsubq_s32(ar[4], ar[5]); - bl[6] = vsubq_s32(al[7], al[6]); - br[6] = vsubq_s32(ar[7], ar[6]); - bl[7] = vaddq_s32(al[7], al[6]); - br[7] = vaddq_s32(ar[7], ar[6]); - - bl[8] = al[8]; - br[8] = ar[8]; - - butterfly_two_coeff_s32_s64_narrow(al[14], ar[14], al[9], ar[9], cospi_8_64, - cospi_24_64, &bl[14], &br[14], &bl[9], - &br[9]); - butterfly_two_coeff_s32_s64_narrow(al[13], ar[13], al[10], ar[10], - cospi_24_64, -cospi_8_64, &bl[13], &br[13], - &bl[10], &br[10]); - - bl[11] = al[11]; - br[11] = ar[11]; - bl[12] = al[12]; - br[12] = ar[12]; - - bl[15] = al[15]; - br[15] = ar[15]; - - bl[16] = vaddq_s32(al[19], al[16]); - br[16] = vaddq_s32(ar[19], ar[16]); - bl[17] = vaddq_s32(al[18], al[17]); - br[17] = vaddq_s32(ar[18], ar[17]); - bl[18] = vsubq_s32(al[17], al[18]); - br[18] = vsubq_s32(ar[17], ar[18]); - bl[19] = vsubq_s32(al[16], al[19]); - br[19] = vsubq_s32(ar[16], ar[19]); - bl[20] = vsubq_s32(al[23], al[20]); - br[20] = vsubq_s32(ar[23], ar[20]); - bl[21] = vsubq_s32(al[22], al[21]); - br[21] = vsubq_s32(ar[22], ar[21]); - bl[22] = vaddq_s32(al[21], al[22]); - br[22] = vaddq_s32(ar[21], ar[22]); - bl[23] = vaddq_s32(al[20], al[23]); - br[23] = vaddq_s32(ar[20], ar[23]); - bl[24] = vaddq_s32(al[27], al[24]); - br[24] = vaddq_s32(ar[27], ar[24]); - bl[25] = vaddq_s32(al[26], al[25]); - br[25] = vaddq_s32(ar[26], ar[25]); - bl[26] = vsubq_s32(al[25], al[26]); - br[26] = vsubq_s32(ar[25], ar[26]); - bl[27] = vsubq_s32(al[24], al[27]); - br[27] = vsubq_s32(ar[24], ar[27]); - bl[28] = vsubq_s32(al[31], al[28]); - br[28] = vsubq_s32(ar[31], ar[28]); - bl[29] = vsubq_s32(al[30], al[29]); - br[29] = vsubq_s32(ar[30], ar[29]); - bl[30] = vaddq_s32(al[29], al[30]); - br[30] = vaddq_s32(ar[29], ar[30]); - bl[31] = vaddq_s32(al[28], al[31]); - br[31] = vaddq_s32(ar[28], ar[31]); - - // Stage 6. - al[0] = bl[0]; - ar[0] = br[0]; - al[1] = bl[1]; - ar[1] = br[1]; - al[2] = bl[2]; - ar[2] = br[2]; - al[3] = bl[3]; - ar[3] = br[3]; - - butterfly_two_coeff_s32_s64_narrow(bl[7], br[7], bl[4], br[4], cospi_4_64, - cospi_28_64, &al[4], &ar[4], &al[7], - &ar[7]); - butterfly_two_coeff_s32_s64_narrow(bl[6], br[6], bl[5], br[5], cospi_20_64, - cospi_12_64, &al[5], &ar[5], &al[6], - &ar[6]); - - al[8] = vaddq_s32(bl[8], bl[9]); - ar[8] = vaddq_s32(br[8], br[9]); - al[9] = vsubq_s32(bl[8], bl[9]); - ar[9] = vsubq_s32(br[8], br[9]); - al[10] = vsubq_s32(bl[11], bl[10]); - ar[10] = vsubq_s32(br[11], br[10]); - al[11] = vaddq_s32(bl[11], bl[10]); - ar[11] = vaddq_s32(br[11], br[10]); - al[12] = vaddq_s32(bl[12], bl[13]); - ar[12] = vaddq_s32(br[12], br[13]); - al[13] = vsubq_s32(bl[12], bl[13]); - ar[13] = vsubq_s32(br[12], br[13]); - al[14] = vsubq_s32(bl[15], bl[14]); - ar[14] = vsubq_s32(br[15], br[14]); - al[15] = vaddq_s32(bl[15], bl[14]); - ar[15] = vaddq_s32(br[15], br[14]); - - al[16] = bl[16]; - ar[16] = br[16]; - al[19] = bl[19]; - ar[19] = br[19]; - al[20] = bl[20]; - ar[20] = br[20]; - al[23] = bl[23]; - ar[23] = br[23]; - al[24] = bl[24]; - ar[24] = br[24]; - al[27] = bl[27]; - ar[27] = br[27]; - al[28] = bl[28]; - ar[28] = br[28]; - al[31] = bl[31]; - ar[31] = br[31]; - - butterfly_two_coeff_s32_s64_narrow(bl[30], br[30], bl[17], br[17], cospi_4_64, - cospi_28_64, &al[30], &ar[30], &al[17], - &ar[17]); - butterfly_two_coeff_s32_s64_narrow(bl[29], br[29], bl[18], br[18], - cospi_28_64, -cospi_4_64, &al[29], &ar[29], - &al[18], &ar[18]); - butterfly_two_coeff_s32_s64_narrow(bl[26], br[26], bl[21], br[21], - cospi_20_64, cospi_12_64, &al[26], &ar[26], - &al[21], &ar[21]); - butterfly_two_coeff_s32_s64_narrow(bl[25], br[25], bl[22], br[22], - cospi_12_64, -cospi_20_64, &al[25], - &ar[25], &al[22], &ar[22]); - - // Stage 7. - bl[0] = al[0]; - br[0] = ar[0]; - bl[1] = al[1]; - br[1] = ar[1]; - bl[2] = al[2]; - br[2] = ar[2]; - bl[3] = al[3]; - br[3] = ar[3]; - bl[4] = al[4]; - br[4] = ar[4]; - bl[5] = al[5]; - br[5] = ar[5]; - bl[6] = al[6]; - br[6] = ar[6]; - bl[7] = al[7]; - br[7] = ar[7]; - - butterfly_two_coeff_s32_s64_narrow(al[15], ar[15], al[8], ar[8], cospi_2_64, - cospi_30_64, &bl[8], &br[8], &bl[15], - &br[15]); - butterfly_two_coeff_s32_s64_narrow(al[14], ar[14], al[9], ar[9], cospi_18_64, - cospi_14_64, &bl[9], &br[9], &bl[14], - &br[14]); - butterfly_two_coeff_s32_s64_narrow(al[13], ar[13], al[10], ar[10], - cospi_10_64, cospi_22_64, &bl[10], &br[10], - &bl[13], &br[13]); - butterfly_two_coeff_s32_s64_narrow(al[12], ar[12], al[11], ar[11], - cospi_26_64, cospi_6_64, &bl[11], &br[11], - &bl[12], &br[12]); - - bl[16] = vaddq_s32(al[16], al[17]); - br[16] = vaddq_s32(ar[16], ar[17]); - bl[17] = vsubq_s32(al[16], al[17]); - br[17] = vsubq_s32(ar[16], ar[17]); - bl[18] = vsubq_s32(al[19], al[18]); - br[18] = vsubq_s32(ar[19], ar[18]); - bl[19] = vaddq_s32(al[19], al[18]); - br[19] = vaddq_s32(ar[19], ar[18]); - bl[20] = vaddq_s32(al[20], al[21]); - br[20] = vaddq_s32(ar[20], ar[21]); - bl[21] = vsubq_s32(al[20], al[21]); - br[21] = vsubq_s32(ar[20], ar[21]); - bl[22] = vsubq_s32(al[23], al[22]); - br[22] = vsubq_s32(ar[23], ar[22]); - bl[23] = vaddq_s32(al[23], al[22]); - br[23] = vaddq_s32(ar[23], ar[22]); - bl[24] = vaddq_s32(al[24], al[25]); - br[24] = vaddq_s32(ar[24], ar[25]); - bl[25] = vsubq_s32(al[24], al[25]); - br[25] = vsubq_s32(ar[24], ar[25]); - bl[26] = vsubq_s32(al[27], al[26]); - br[26] = vsubq_s32(ar[27], ar[26]); - bl[27] = vaddq_s32(al[27], al[26]); - br[27] = vaddq_s32(ar[27], ar[26]); - bl[28] = vaddq_s32(al[28], al[29]); - br[28] = vaddq_s32(ar[28], ar[29]); - bl[29] = vsubq_s32(al[28], al[29]); - br[29] = vsubq_s32(ar[28], ar[29]); - bl[30] = vsubq_s32(al[31], al[30]); - br[30] = vsubq_s32(ar[31], ar[30]); - bl[31] = vaddq_s32(al[31], al[30]); - br[31] = vaddq_s32(ar[31], ar[30]); - - // Final stage. - - left[0] = bl[0]; - right[0] = br[0]; - left[16] = bl[1]; - right[16] = br[1]; - left[8] = bl[2]; - right[8] = br[2]; - left[24] = bl[3]; - right[24] = br[3]; - left[4] = bl[4]; - right[4] = br[4]; - left[20] = bl[5]; - right[20] = br[5]; - left[12] = bl[6]; - right[12] = br[6]; - left[28] = bl[7]; - right[28] = br[7]; - left[2] = bl[8]; - right[2] = br[8]; - left[18] = bl[9]; - right[18] = br[9]; - left[10] = bl[10]; - right[10] = br[10]; - left[26] = bl[11]; - right[26] = br[11]; - left[6] = bl[12]; - right[6] = br[12]; - left[22] = bl[13]; - right[22] = br[13]; - left[14] = bl[14]; - right[14] = br[14]; - left[30] = bl[15]; - right[30] = br[15]; - - butterfly_two_coeff_s32_s64_narrow(bl[31], br[31], bl[16], br[16], cospi_1_64, - cospi_31_64, &al[1], &ar[1], &al[31], - &ar[31]); - left[1] = al[1]; - right[1] = ar[1]; - left[31] = al[31]; - right[31] = ar[31]; - - butterfly_two_coeff_s32_s64_narrow(bl[30], br[30], bl[17], br[17], - cospi_17_64, cospi_15_64, &al[17], &ar[17], - &al[15], &ar[15]); - left[17] = al[17]; - right[17] = ar[17]; - left[15] = al[15]; - right[15] = ar[15]; - - butterfly_two_coeff_s32_s64_narrow(bl[29], br[29], bl[18], br[18], cospi_9_64, - cospi_23_64, &al[9], &ar[9], &al[23], - &ar[23]); - left[9] = al[9]; - right[9] = ar[9]; - left[23] = al[23]; - right[23] = ar[23]; - - butterfly_two_coeff_s32_s64_narrow(bl[28], br[28], bl[19], br[19], - cospi_25_64, cospi_7_64, &al[25], &ar[25], - &al[7], &ar[7]); - left[25] = al[25]; - right[25] = ar[25]; - left[7] = al[7]; - right[7] = ar[7]; - - butterfly_two_coeff_s32_s64_narrow(bl[27], br[27], bl[20], br[20], cospi_5_64, - cospi_27_64, &al[5], &ar[5], &al[27], - &ar[27]); - left[5] = al[5]; - right[5] = ar[5]; - left[27] = al[27]; - right[27] = ar[27]; - - butterfly_two_coeff_s32_s64_narrow(bl[26], br[26], bl[21], br[21], - cospi_21_64, cospi_11_64, &al[21], &ar[21], - &al[11], &ar[11]); - left[21] = al[21]; - right[21] = ar[21]; - left[11] = al[11]; - right[11] = ar[11]; - - butterfly_two_coeff_s32_s64_narrow(bl[25], br[25], bl[22], br[22], - cospi_13_64, cospi_19_64, &al[13], &ar[13], - &al[19], &ar[19]); - left[13] = al[13]; - right[13] = ar[13]; - left[19] = al[19]; - right[19] = ar[19]; - - butterfly_two_coeff_s32_s64_narrow(bl[24], br[24], bl[23], br[23], - cospi_29_64, cospi_3_64, &al[29], &ar[29], - &al[3], &ar[3]); - left[29] = al[29]; - right[29] = ar[29]; - left[3] = al[3]; - right[3] = ar[3]; -} - -static INLINE void highbd_dct8x32_body_second_pass(int32x4_t *left /*32*/, - int32x4_t *right /*32*/) { - int32x4_t al[32], ar[32]; - int32x4_t bl[32], br[32]; - - // Stage 1: Done as part of the load. - - // Stage 2. - // Mini cross. X the first 16 values and the middle 8 of the second half. - al[0] = vaddq_s32(left[0], left[15]); - ar[0] = vaddq_s32(right[0], right[15]); - al[1] = vaddq_s32(left[1], left[14]); - ar[1] = vaddq_s32(right[1], right[14]); - al[2] = vaddq_s32(left[2], left[13]); - ar[2] = vaddq_s32(right[2], right[13]); - al[3] = vaddq_s32(left[3], left[12]); - ar[3] = vaddq_s32(right[3], right[12]); - al[4] = vaddq_s32(left[4], left[11]); - ar[4] = vaddq_s32(right[4], right[11]); - al[5] = vaddq_s32(left[5], left[10]); - ar[5] = vaddq_s32(right[5], right[10]); - al[6] = vaddq_s32(left[6], left[9]); - ar[6] = vaddq_s32(right[6], right[9]); - al[7] = vaddq_s32(left[7], left[8]); - ar[7] = vaddq_s32(right[7], right[8]); - - al[8] = vsubq_s32(left[7], left[8]); - ar[8] = vsubq_s32(right[7], right[8]); - al[9] = vsubq_s32(left[6], left[9]); - ar[9] = vsubq_s32(right[6], right[9]); - al[10] = vsubq_s32(left[5], left[10]); - ar[10] = vsubq_s32(right[5], right[10]); - al[11] = vsubq_s32(left[4], left[11]); - ar[11] = vsubq_s32(right[4], right[11]); - al[12] = vsubq_s32(left[3], left[12]); - ar[12] = vsubq_s32(right[3], right[12]); - al[13] = vsubq_s32(left[2], left[13]); - ar[13] = vsubq_s32(right[2], right[13]); - al[14] = vsubq_s32(left[1], left[14]); - ar[14] = vsubq_s32(right[1], right[14]); - al[15] = vsubq_s32(left[0], left[15]); - ar[15] = vsubq_s32(right[0], right[15]); - - al[16] = left[16]; - ar[16] = right[16]; - al[17] = left[17]; - ar[17] = right[17]; - al[18] = left[18]; - ar[18] = right[18]; - al[19] = left[19]; - ar[19] = right[19]; - - butterfly_one_coeff_s32_fast(left[27], right[27], left[20], right[20], - cospi_16_64, &al[27], &ar[27], &al[20], &ar[20]); - butterfly_one_coeff_s32_fast(left[26], right[26], left[21], right[21], - cospi_16_64, &al[26], &ar[26], &al[21], &ar[21]); - butterfly_one_coeff_s32_fast(left[25], right[25], left[22], right[22], - cospi_16_64, &al[25], &ar[25], &al[22], &ar[22]); - butterfly_one_coeff_s32_fast(left[24], right[24], left[23], right[23], - cospi_16_64, &al[24], &ar[24], &al[23], &ar[23]); - - al[28] = left[28]; - ar[28] = right[28]; - al[29] = left[29]; - ar[29] = right[29]; - al[30] = left[30]; - ar[30] = right[30]; - al[31] = left[31]; - ar[31] = right[31]; - - // Stage 3. - bl[0] = vaddq_s32(al[0], al[7]); - br[0] = vaddq_s32(ar[0], ar[7]); - bl[1] = vaddq_s32(al[1], al[6]); - br[1] = vaddq_s32(ar[1], ar[6]); - bl[2] = vaddq_s32(al[2], al[5]); - br[2] = vaddq_s32(ar[2], ar[5]); - bl[3] = vaddq_s32(al[3], al[4]); - br[3] = vaddq_s32(ar[3], ar[4]); - - bl[4] = vsubq_s32(al[3], al[4]); - br[4] = vsubq_s32(ar[3], ar[4]); - bl[5] = vsubq_s32(al[2], al[5]); - br[5] = vsubq_s32(ar[2], ar[5]); - bl[6] = vsubq_s32(al[1], al[6]); - br[6] = vsubq_s32(ar[1], ar[6]); - bl[7] = vsubq_s32(al[0], al[7]); - br[7] = vsubq_s32(ar[0], ar[7]); - - bl[8] = al[8]; - br[8] = ar[8]; - bl[9] = al[9]; - br[9] = ar[9]; - - butterfly_one_coeff_s32_fast(al[13], ar[13], al[10], ar[10], cospi_16_64, - &bl[13], &br[13], &bl[10], &br[10]); - butterfly_one_coeff_s32_fast(al[12], ar[12], al[11], ar[11], cospi_16_64, - &bl[12], &br[12], &bl[11], &br[11]); - - bl[14] = al[14]; - br[14] = ar[14]; - bl[15] = al[15]; - br[15] = ar[15]; - - bl[16] = vaddq_s32(left[16], al[23]); - br[16] = vaddq_s32(right[16], ar[23]); - bl[17] = vaddq_s32(left[17], al[22]); - br[17] = vaddq_s32(right[17], ar[22]); - bl[18] = vaddq_s32(left[18], al[21]); - br[18] = vaddq_s32(right[18], ar[21]); - bl[19] = vaddq_s32(left[19], al[20]); - br[19] = vaddq_s32(right[19], ar[20]); - - bl[20] = vsubq_s32(left[19], al[20]); - br[20] = vsubq_s32(right[19], ar[20]); - bl[21] = vsubq_s32(left[18], al[21]); - br[21] = vsubq_s32(right[18], ar[21]); - bl[22] = vsubq_s32(left[17], al[22]); - br[22] = vsubq_s32(right[17], ar[22]); - bl[23] = vsubq_s32(left[16], al[23]); - br[23] = vsubq_s32(right[16], ar[23]); - - bl[24] = vsubq_s32(left[31], al[24]); - br[24] = vsubq_s32(right[31], ar[24]); - bl[25] = vsubq_s32(left[30], al[25]); - br[25] = vsubq_s32(right[30], ar[25]); - bl[26] = vsubq_s32(left[29], al[26]); - br[26] = vsubq_s32(right[29], ar[26]); - bl[27] = vsubq_s32(left[28], al[27]); - br[27] = vsubq_s32(right[28], ar[27]); - - bl[28] = vaddq_s32(left[28], al[27]); - br[28] = vaddq_s32(right[28], ar[27]); - bl[29] = vaddq_s32(left[29], al[26]); - br[29] = vaddq_s32(right[29], ar[26]); - bl[30] = vaddq_s32(left[30], al[25]); - br[30] = vaddq_s32(right[30], ar[25]); - bl[31] = vaddq_s32(left[31], al[24]); - br[31] = vaddq_s32(right[31], ar[24]); - - // Stage 4. - al[0] = vaddq_s32(bl[0], bl[3]); - ar[0] = vaddq_s32(br[0], br[3]); - al[1] = vaddq_s32(bl[1], bl[2]); - ar[1] = vaddq_s32(br[1], br[2]); - al[2] = vsubq_s32(bl[1], bl[2]); - ar[2] = vsubq_s32(br[1], br[2]); - al[3] = vsubq_s32(bl[0], bl[3]); - ar[3] = vsubq_s32(br[0], br[3]); - - al[4] = bl[4]; - ar[4] = br[4]; - - butterfly_one_coeff_s32_fast(bl[6], br[6], bl[5], br[5], cospi_16_64, &al[6], - &ar[6], &al[5], &ar[5]); - - al[7] = bl[7]; - ar[7] = br[7]; - - al[8] = vaddq_s32(bl[8], bl[11]); - ar[8] = vaddq_s32(br[8], br[11]); - al[9] = vaddq_s32(bl[9], bl[10]); - ar[9] = vaddq_s32(br[9], br[10]); - al[10] = vsubq_s32(bl[9], bl[10]); - ar[10] = vsubq_s32(br[9], br[10]); - al[11] = vsubq_s32(bl[8], bl[11]); - ar[11] = vsubq_s32(br[8], br[11]); - al[12] = vsubq_s32(bl[15], bl[12]); - ar[12] = vsubq_s32(br[15], br[12]); - al[13] = vsubq_s32(bl[14], bl[13]); - ar[13] = vsubq_s32(br[14], br[13]); - al[14] = vaddq_s32(bl[14], bl[13]); - ar[14] = vaddq_s32(br[14], br[13]); - al[15] = vaddq_s32(bl[15], bl[12]); - ar[15] = vaddq_s32(br[15], br[12]); - - al[16] = bl[16]; - ar[16] = br[16]; - al[17] = bl[17]; - ar[17] = br[17]; - - butterfly_two_coeff_s32_s64_narrow(bl[29], br[29], bl[18], br[18], cospi_8_64, - cospi_24_64, &al[29], &ar[29], &al[18], - &ar[18]); - butterfly_two_coeff_s32_s64_narrow(bl[28], br[28], bl[19], br[19], cospi_8_64, - cospi_24_64, &al[28], &ar[28], &al[19], - &ar[19]); - butterfly_two_coeff_s32_s64_narrow(bl[27], br[27], bl[20], br[20], - cospi_24_64, -cospi_8_64, &al[27], &ar[27], - &al[20], &ar[20]); - butterfly_two_coeff_s32_s64_narrow(bl[26], br[26], bl[21], br[21], - cospi_24_64, -cospi_8_64, &al[26], &ar[26], - &al[21], &ar[21]); - - al[22] = bl[22]; - ar[22] = br[22]; - al[23] = bl[23]; - ar[23] = br[23]; - al[24] = bl[24]; - ar[24] = br[24]; - al[25] = bl[25]; - ar[25] = br[25]; - - al[30] = bl[30]; - ar[30] = br[30]; - al[31] = bl[31]; - ar[31] = br[31]; - - // Stage 5. - butterfly_one_coeff_s32_fast(al[0], ar[0], al[1], ar[1], cospi_16_64, &bl[0], - &br[0], &bl[1], &br[1]); - butterfly_two_coeff_s32_s64_narrow(al[3], ar[3], al[2], ar[2], cospi_8_64, - cospi_24_64, &bl[2], &br[2], &bl[3], - &br[3]); - - bl[4] = vaddq_s32(al[4], al[5]); - br[4] = vaddq_s32(ar[4], ar[5]); - bl[5] = vsubq_s32(al[4], al[5]); - br[5] = vsubq_s32(ar[4], ar[5]); - bl[6] = vsubq_s32(al[7], al[6]); - br[6] = vsubq_s32(ar[7], ar[6]); - bl[7] = vaddq_s32(al[7], al[6]); - br[7] = vaddq_s32(ar[7], ar[6]); - - bl[8] = al[8]; - br[8] = ar[8]; - - butterfly_two_coeff_s32_s64_narrow(al[14], ar[14], al[9], ar[9], cospi_8_64, - cospi_24_64, &bl[14], &br[14], &bl[9], - &br[9]); - butterfly_two_coeff_s32_s64_narrow(al[13], ar[13], al[10], ar[10], - cospi_24_64, -cospi_8_64, &bl[13], &br[13], - &bl[10], &br[10]); - - bl[11] = al[11]; - br[11] = ar[11]; - bl[12] = al[12]; - br[12] = ar[12]; - - bl[15] = al[15]; - br[15] = ar[15]; - - bl[16] = vaddq_s32(al[19], al[16]); - br[16] = vaddq_s32(ar[19], ar[16]); - bl[17] = vaddq_s32(al[18], al[17]); - br[17] = vaddq_s32(ar[18], ar[17]); - bl[18] = vsubq_s32(al[17], al[18]); - br[18] = vsubq_s32(ar[17], ar[18]); - bl[19] = vsubq_s32(al[16], al[19]); - br[19] = vsubq_s32(ar[16], ar[19]); - bl[20] = vsubq_s32(al[23], al[20]); - br[20] = vsubq_s32(ar[23], ar[20]); - bl[21] = vsubq_s32(al[22], al[21]); - br[21] = vsubq_s32(ar[22], ar[21]); - bl[22] = vaddq_s32(al[21], al[22]); - br[22] = vaddq_s32(ar[21], ar[22]); - bl[23] = vaddq_s32(al[20], al[23]); - br[23] = vaddq_s32(ar[20], ar[23]); - bl[24] = vaddq_s32(al[27], al[24]); - br[24] = vaddq_s32(ar[27], ar[24]); - bl[25] = vaddq_s32(al[26], al[25]); - br[25] = vaddq_s32(ar[26], ar[25]); - bl[26] = vsubq_s32(al[25], al[26]); - br[26] = vsubq_s32(ar[25], ar[26]); - bl[27] = vsubq_s32(al[24], al[27]); - br[27] = vsubq_s32(ar[24], ar[27]); - bl[28] = vsubq_s32(al[31], al[28]); - br[28] = vsubq_s32(ar[31], ar[28]); - bl[29] = vsubq_s32(al[30], al[29]); - br[29] = vsubq_s32(ar[30], ar[29]); - bl[30] = vaddq_s32(al[29], al[30]); - br[30] = vaddq_s32(ar[29], ar[30]); - bl[31] = vaddq_s32(al[28], al[31]); - br[31] = vaddq_s32(ar[28], ar[31]); - - // Stage 6. - al[0] = bl[0]; - ar[0] = br[0]; - al[1] = bl[1]; - ar[1] = br[1]; - al[2] = bl[2]; - ar[2] = br[2]; - al[3] = bl[3]; - ar[3] = br[3]; - - butterfly_two_coeff_s32_s64_narrow(bl[7], br[7], bl[4], br[4], cospi_4_64, - cospi_28_64, &al[4], &ar[4], &al[7], - &ar[7]); - butterfly_two_coeff_s32_s64_narrow(bl[6], br[6], bl[5], br[5], cospi_20_64, - cospi_12_64, &al[5], &ar[5], &al[6], - &ar[6]); - - al[8] = vaddq_s32(bl[8], bl[9]); - ar[8] = vaddq_s32(br[8], br[9]); - al[9] = vsubq_s32(bl[8], bl[9]); - ar[9] = vsubq_s32(br[8], br[9]); - al[10] = vsubq_s32(bl[11], bl[10]); - ar[10] = vsubq_s32(br[11], br[10]); - al[11] = vaddq_s32(bl[11], bl[10]); - ar[11] = vaddq_s32(br[11], br[10]); - al[12] = vaddq_s32(bl[12], bl[13]); - ar[12] = vaddq_s32(br[12], br[13]); - al[13] = vsubq_s32(bl[12], bl[13]); - ar[13] = vsubq_s32(br[12], br[13]); - al[14] = vsubq_s32(bl[15], bl[14]); - ar[14] = vsubq_s32(br[15], br[14]); - al[15] = vaddq_s32(bl[15], bl[14]); - ar[15] = vaddq_s32(br[15], br[14]); - - al[16] = bl[16]; - ar[16] = br[16]; - al[19] = bl[19]; - ar[19] = br[19]; - al[20] = bl[20]; - ar[20] = br[20]; - al[23] = bl[23]; - ar[23] = br[23]; - al[24] = bl[24]; - ar[24] = br[24]; - al[27] = bl[27]; - ar[27] = br[27]; - al[28] = bl[28]; - ar[28] = br[28]; - al[31] = bl[31]; - ar[31] = br[31]; - - butterfly_two_coeff_s32_s64_narrow(bl[30], br[30], bl[17], br[17], cospi_4_64, - cospi_28_64, &al[30], &ar[30], &al[17], - &ar[17]); - butterfly_two_coeff_s32_s64_narrow(bl[29], br[29], bl[18], br[18], - cospi_28_64, -cospi_4_64, &al[29], &ar[29], - &al[18], &ar[18]); - butterfly_two_coeff_s32_s64_narrow(bl[26], br[26], bl[21], br[21], - cospi_20_64, cospi_12_64, &al[26], &ar[26], - &al[21], &ar[21]); - butterfly_two_coeff_s32_s64_narrow(bl[25], br[25], bl[22], br[22], - cospi_12_64, -cospi_20_64, &al[25], - &ar[25], &al[22], &ar[22]); - - // Stage 7. - bl[0] = al[0]; - br[0] = ar[0]; - bl[1] = al[1]; - br[1] = ar[1]; - bl[2] = al[2]; - br[2] = ar[2]; - bl[3] = al[3]; - br[3] = ar[3]; - bl[4] = al[4]; - br[4] = ar[4]; - bl[5] = al[5]; - br[5] = ar[5]; - bl[6] = al[6]; - br[6] = ar[6]; - bl[7] = al[7]; - br[7] = ar[7]; - - butterfly_two_coeff_s32_s64_narrow(al[15], ar[15], al[8], ar[8], cospi_2_64, - cospi_30_64, &bl[8], &br[8], &bl[15], - &br[15]); - butterfly_two_coeff_s32_s64_narrow(al[14], ar[14], al[9], ar[9], cospi_18_64, - cospi_14_64, &bl[9], &br[9], &bl[14], - &br[14]); - butterfly_two_coeff_s32_s64_narrow(al[13], ar[13], al[10], ar[10], - cospi_10_64, cospi_22_64, &bl[10], &br[10], - &bl[13], &br[13]); - butterfly_two_coeff_s32_s64_narrow(al[12], ar[12], al[11], ar[11], - cospi_26_64, cospi_6_64, &bl[11], &br[11], - &bl[12], &br[12]); - - bl[16] = vaddq_s32(al[16], al[17]); - br[16] = vaddq_s32(ar[16], ar[17]); - bl[17] = vsubq_s32(al[16], al[17]); - br[17] = vsubq_s32(ar[16], ar[17]); - bl[18] = vsubq_s32(al[19], al[18]); - br[18] = vsubq_s32(ar[19], ar[18]); - bl[19] = vaddq_s32(al[19], al[18]); - br[19] = vaddq_s32(ar[19], ar[18]); - bl[20] = vaddq_s32(al[20], al[21]); - br[20] = vaddq_s32(ar[20], ar[21]); - bl[21] = vsubq_s32(al[20], al[21]); - br[21] = vsubq_s32(ar[20], ar[21]); - bl[22] = vsubq_s32(al[23], al[22]); - br[22] = vsubq_s32(ar[23], ar[22]); - bl[23] = vaddq_s32(al[23], al[22]); - br[23] = vaddq_s32(ar[23], ar[22]); - bl[24] = vaddq_s32(al[24], al[25]); - br[24] = vaddq_s32(ar[24], ar[25]); - bl[25] = vsubq_s32(al[24], al[25]); - br[25] = vsubq_s32(ar[24], ar[25]); - bl[26] = vsubq_s32(al[27], al[26]); - br[26] = vsubq_s32(ar[27], ar[26]); - bl[27] = vaddq_s32(al[27], al[26]); - br[27] = vaddq_s32(ar[27], ar[26]); - bl[28] = vaddq_s32(al[28], al[29]); - br[28] = vaddq_s32(ar[28], ar[29]); - bl[29] = vsubq_s32(al[28], al[29]); - br[29] = vsubq_s32(ar[28], ar[29]); - bl[30] = vsubq_s32(al[31], al[30]); - br[30] = vsubq_s32(ar[31], ar[30]); - bl[31] = vaddq_s32(al[31], al[30]); - br[31] = vaddq_s32(ar[31], ar[30]); - - // Final stage. - - left[0] = bl[0]; - right[0] = br[0]; - left[16] = bl[1]; - right[16] = br[1]; - left[8] = bl[2]; - right[8] = br[2]; - left[24] = bl[3]; - right[24] = br[3]; - left[4] = bl[4]; - right[4] = br[4]; - left[20] = bl[5]; - right[20] = br[5]; - left[12] = bl[6]; - right[12] = br[6]; - left[28] = bl[7]; - right[28] = br[7]; - left[2] = bl[8]; - right[2] = br[8]; - left[18] = bl[9]; - right[18] = br[9]; - left[10] = bl[10]; - right[10] = br[10]; - left[26] = bl[11]; - right[26] = br[11]; - left[6] = bl[12]; - right[6] = br[12]; - left[22] = bl[13]; - right[22] = br[13]; - left[14] = bl[14]; - right[14] = br[14]; - left[30] = bl[15]; - right[30] = br[15]; - - butterfly_two_coeff_s32_s64_narrow(bl[31], br[31], bl[16], br[16], cospi_1_64, - cospi_31_64, &al[1], &ar[1], &al[31], - &ar[31]); - left[1] = al[1]; - right[1] = ar[1]; - left[31] = al[31]; - right[31] = ar[31]; - - butterfly_two_coeff_s32_s64_narrow(bl[30], br[30], bl[17], br[17], - cospi_17_64, cospi_15_64, &al[17], &ar[17], - &al[15], &ar[15]); - left[17] = al[17]; - right[17] = ar[17]; - left[15] = al[15]; - right[15] = ar[15]; - - butterfly_two_coeff_s32_s64_narrow(bl[29], br[29], bl[18], br[18], cospi_9_64, - cospi_23_64, &al[9], &ar[9], &al[23], - &ar[23]); - left[9] = al[9]; - right[9] = ar[9]; - left[23] = al[23]; - right[23] = ar[23]; - - butterfly_two_coeff_s32_s64_narrow(bl[28], br[28], bl[19], br[19], - cospi_25_64, cospi_7_64, &al[25], &ar[25], - &al[7], &ar[7]); - left[25] = al[25]; - right[25] = ar[25]; - left[7] = al[7]; - right[7] = ar[7]; - - butterfly_two_coeff_s32_s64_narrow(bl[27], br[27], bl[20], br[20], cospi_5_64, - cospi_27_64, &al[5], &ar[5], &al[27], - &ar[27]); - left[5] = al[5]; - right[5] = ar[5]; - left[27] = al[27]; - right[27] = ar[27]; - - butterfly_two_coeff_s32_s64_narrow(bl[26], br[26], bl[21], br[21], - cospi_21_64, cospi_11_64, &al[21], &ar[21], - &al[11], &ar[11]); - left[21] = al[21]; - right[21] = ar[21]; - left[11] = al[11]; - right[11] = ar[11]; - - butterfly_two_coeff_s32_s64_narrow(bl[25], br[25], bl[22], br[22], - cospi_13_64, cospi_19_64, &al[13], &ar[13], - &al[19], &ar[19]); - left[13] = al[13]; - right[13] = ar[13]; - left[19] = al[19]; - right[19] = ar[19]; - - butterfly_two_coeff_s32_s64_narrow(bl[24], br[24], bl[23], br[23], - cospi_29_64, cospi_3_64, &al[29], &ar[29], - &al[3], &ar[3]); - left[29] = al[29]; - right[29] = ar[29]; - left[3] = al[3]; - right[3] = ar[3]; -} - -static INLINE void highbd_dct8x32_body_second_pass_rd(int32x4_t *left /*32*/, - int32x4_t *right /*32*/) { - int32x4_t al[32], ar[32]; - int32x4_t bl[32], br[32]; - - // Stage 1: Done as part of the load. - - // Stage 2. - // For the "rd" version, all the values are rounded down after stage 2 to keep - // the values in 16 bits. - al[0] = add_round_shift_s32(vaddq_s32(left[0], left[15])); - ar[0] = add_round_shift_s32(vaddq_s32(right[0], right[15])); - al[1] = add_round_shift_s32(vaddq_s32(left[1], left[14])); - ar[1] = add_round_shift_s32(vaddq_s32(right[1], right[14])); - al[2] = add_round_shift_s32(vaddq_s32(left[2], left[13])); - ar[2] = add_round_shift_s32(vaddq_s32(right[2], right[13])); - al[3] = add_round_shift_s32(vaddq_s32(left[3], left[12])); - ar[3] = add_round_shift_s32(vaddq_s32(right[3], right[12])); - al[4] = add_round_shift_s32(vaddq_s32(left[4], left[11])); - ar[4] = add_round_shift_s32(vaddq_s32(right[4], right[11])); - al[5] = add_round_shift_s32(vaddq_s32(left[5], left[10])); - ar[5] = add_round_shift_s32(vaddq_s32(right[5], right[10])); - al[6] = add_round_shift_s32(vaddq_s32(left[6], left[9])); - ar[6] = add_round_shift_s32(vaddq_s32(right[6], right[9])); - al[7] = add_round_shift_s32(vaddq_s32(left[7], left[8])); - ar[7] = add_round_shift_s32(vaddq_s32(right[7], right[8])); - - al[8] = add_round_shift_s32(vsubq_s32(left[7], left[8])); - ar[8] = add_round_shift_s32(vsubq_s32(right[7], right[8])); - al[9] = add_round_shift_s32(vsubq_s32(left[6], left[9])); - ar[9] = add_round_shift_s32(vsubq_s32(right[6], right[9])); - al[10] = add_round_shift_s32(vsubq_s32(left[5], left[10])); - ar[10] = add_round_shift_s32(vsubq_s32(right[5], right[10])); - al[11] = add_round_shift_s32(vsubq_s32(left[4], left[11])); - ar[11] = add_round_shift_s32(vsubq_s32(right[4], right[11])); - al[12] = add_round_shift_s32(vsubq_s32(left[3], left[12])); - ar[12] = add_round_shift_s32(vsubq_s32(right[3], right[12])); - al[13] = add_round_shift_s32(vsubq_s32(left[2], left[13])); - ar[13] = add_round_shift_s32(vsubq_s32(right[2], right[13])); - al[14] = add_round_shift_s32(vsubq_s32(left[1], left[14])); - ar[14] = add_round_shift_s32(vsubq_s32(right[1], right[14])); - al[15] = add_round_shift_s32(vsubq_s32(left[0], left[15])); - ar[15] = add_round_shift_s32(vsubq_s32(right[0], right[15])); - - al[16] = add_round_shift_s32(left[16]); - ar[16] = add_round_shift_s32(right[16]); - al[17] = add_round_shift_s32(left[17]); - ar[17] = add_round_shift_s32(right[17]); - al[18] = add_round_shift_s32(left[18]); - ar[18] = add_round_shift_s32(right[18]); - al[19] = add_round_shift_s32(left[19]); - ar[19] = add_round_shift_s32(right[19]); - - butterfly_one_coeff_s32_fast(left[27], right[27], left[20], right[20], - cospi_16_64, &al[27], &ar[27], &al[20], &ar[20]); - butterfly_one_coeff_s32_fast(left[26], right[26], left[21], right[21], - cospi_16_64, &al[26], &ar[26], &al[21], &ar[21]); - butterfly_one_coeff_s32_fast(left[25], right[25], left[22], right[22], - cospi_16_64, &al[25], &ar[25], &al[22], &ar[22]); - butterfly_one_coeff_s32_fast(left[24], right[24], left[23], right[23], - cospi_16_64, &al[24], &ar[24], &al[23], &ar[23]); - - al[20] = add_round_shift_s32(al[20]); - ar[20] = add_round_shift_s32(ar[20]); - al[21] = add_round_shift_s32(al[21]); - ar[21] = add_round_shift_s32(ar[21]); - al[22] = add_round_shift_s32(al[22]); - ar[22] = add_round_shift_s32(ar[22]); - al[23] = add_round_shift_s32(al[23]); - ar[23] = add_round_shift_s32(ar[23]); - al[24] = add_round_shift_s32(al[24]); - ar[24] = add_round_shift_s32(ar[24]); - al[25] = add_round_shift_s32(al[25]); - ar[25] = add_round_shift_s32(ar[25]); - al[26] = add_round_shift_s32(al[26]); - ar[26] = add_round_shift_s32(ar[26]); - al[27] = add_round_shift_s32(al[27]); - ar[27] = add_round_shift_s32(ar[27]); - - al[28] = add_round_shift_s32(left[28]); - ar[28] = add_round_shift_s32(right[28]); - al[29] = add_round_shift_s32(left[29]); - ar[29] = add_round_shift_s32(right[29]); - al[30] = add_round_shift_s32(left[30]); - ar[30] = add_round_shift_s32(right[30]); - al[31] = add_round_shift_s32(left[31]); - ar[31] = add_round_shift_s32(right[31]); - - // Stage 3. - bl[0] = vaddq_s32(al[0], al[7]); - br[0] = vaddq_s32(ar[0], ar[7]); - bl[1] = vaddq_s32(al[1], al[6]); - br[1] = vaddq_s32(ar[1], ar[6]); - bl[2] = vaddq_s32(al[2], al[5]); - br[2] = vaddq_s32(ar[2], ar[5]); - bl[3] = vaddq_s32(al[3], al[4]); - br[3] = vaddq_s32(ar[3], ar[4]); - - bl[4] = vsubq_s32(al[3], al[4]); - br[4] = vsubq_s32(ar[3], ar[4]); - bl[5] = vsubq_s32(al[2], al[5]); - br[5] = vsubq_s32(ar[2], ar[5]); - bl[6] = vsubq_s32(al[1], al[6]); - br[6] = vsubq_s32(ar[1], ar[6]); - bl[7] = vsubq_s32(al[0], al[7]); - br[7] = vsubq_s32(ar[0], ar[7]); - - bl[8] = al[8]; - br[8] = ar[8]; - bl[9] = al[9]; - br[9] = ar[9]; - - butterfly_one_coeff_s32_fast(al[13], ar[13], al[10], ar[10], cospi_16_64, - &bl[13], &br[13], &bl[10], &br[10]); - butterfly_one_coeff_s32_fast(al[12], ar[12], al[11], ar[11], cospi_16_64, - &bl[12], &br[12], &bl[11], &br[11]); - - bl[14] = al[14]; - br[14] = ar[14]; - bl[15] = al[15]; - br[15] = ar[15]; - - bl[16] = vaddq_s32(al[16], al[23]); - br[16] = vaddq_s32(ar[16], ar[23]); - bl[17] = vaddq_s32(al[17], al[22]); - br[17] = vaddq_s32(ar[17], ar[22]); - bl[18] = vaddq_s32(al[18], al[21]); - br[18] = vaddq_s32(ar[18], ar[21]); - bl[19] = vaddq_s32(al[19], al[20]); - br[19] = vaddq_s32(ar[19], ar[20]); - - bl[20] = vsubq_s32(al[19], al[20]); - br[20] = vsubq_s32(ar[19], ar[20]); - bl[21] = vsubq_s32(al[18], al[21]); - br[21] = vsubq_s32(ar[18], ar[21]); - bl[22] = vsubq_s32(al[17], al[22]); - br[22] = vsubq_s32(ar[17], ar[22]); - bl[23] = vsubq_s32(al[16], al[23]); - br[23] = vsubq_s32(ar[16], ar[23]); - - bl[24] = vsubq_s32(al[31], al[24]); - br[24] = vsubq_s32(ar[31], ar[24]); - bl[25] = vsubq_s32(al[30], al[25]); - br[25] = vsubq_s32(ar[30], ar[25]); - bl[26] = vsubq_s32(al[29], al[26]); - br[26] = vsubq_s32(ar[29], ar[26]); - bl[27] = vsubq_s32(al[28], al[27]); - br[27] = vsubq_s32(ar[28], ar[27]); - - bl[28] = vaddq_s32(al[28], al[27]); - br[28] = vaddq_s32(ar[28], ar[27]); - bl[29] = vaddq_s32(al[29], al[26]); - br[29] = vaddq_s32(ar[29], ar[26]); - bl[30] = vaddq_s32(al[30], al[25]); - br[30] = vaddq_s32(ar[30], ar[25]); - bl[31] = vaddq_s32(al[31], al[24]); - br[31] = vaddq_s32(ar[31], ar[24]); - - // Stage 4. - al[0] = vaddq_s32(bl[0], bl[3]); - ar[0] = vaddq_s32(br[0], br[3]); - al[1] = vaddq_s32(bl[1], bl[2]); - ar[1] = vaddq_s32(br[1], br[2]); - al[2] = vsubq_s32(bl[1], bl[2]); - ar[2] = vsubq_s32(br[1], br[2]); - al[3] = vsubq_s32(bl[0], bl[3]); - ar[3] = vsubq_s32(br[0], br[3]); - - al[4] = bl[4]; - ar[4] = br[4]; - - butterfly_one_coeff_s32_fast(bl[6], br[6], bl[5], br[5], cospi_16_64, &al[6], - &ar[6], &al[5], &ar[5]); - - al[7] = bl[7]; - ar[7] = br[7]; - - al[8] = vaddq_s32(bl[8], bl[11]); - ar[8] = vaddq_s32(br[8], br[11]); - al[9] = vaddq_s32(bl[9], bl[10]); - ar[9] = vaddq_s32(br[9], br[10]); - al[10] = vsubq_s32(bl[9], bl[10]); - ar[10] = vsubq_s32(br[9], br[10]); - al[11] = vsubq_s32(bl[8], bl[11]); - ar[11] = vsubq_s32(br[8], br[11]); - al[12] = vsubq_s32(bl[15], bl[12]); - ar[12] = vsubq_s32(br[15], br[12]); - al[13] = vsubq_s32(bl[14], bl[13]); - ar[13] = vsubq_s32(br[14], br[13]); - al[14] = vaddq_s32(bl[14], bl[13]); - ar[14] = vaddq_s32(br[14], br[13]); - al[15] = vaddq_s32(bl[15], bl[12]); - ar[15] = vaddq_s32(br[15], br[12]); - - al[16] = bl[16]; - ar[16] = br[16]; - al[17] = bl[17]; - ar[17] = br[17]; - - butterfly_two_coeff_s32(bl[29], br[29], bl[18], br[18], cospi_8_64, - cospi_24_64, &al[29], &ar[29], &al[18], &ar[18]); - butterfly_two_coeff_s32(bl[28], br[28], bl[19], br[19], cospi_8_64, - cospi_24_64, &al[28], &ar[28], &al[19], &ar[19]); - butterfly_two_coeff_s32(bl[27], br[27], bl[20], br[20], cospi_24_64, - -cospi_8_64, &al[27], &ar[27], &al[20], &ar[20]); - butterfly_two_coeff_s32(bl[26], br[26], bl[21], br[21], cospi_24_64, - -cospi_8_64, &al[26], &ar[26], &al[21], &ar[21]); - - al[22] = bl[22]; - ar[22] = br[22]; - al[23] = bl[23]; - ar[23] = br[23]; - al[24] = bl[24]; - ar[24] = br[24]; - al[25] = bl[25]; - ar[25] = br[25]; - - al[30] = bl[30]; - ar[30] = br[30]; - al[31] = bl[31]; - ar[31] = br[31]; - - // Stage 5. - butterfly_one_coeff_s32_fast(al[0], ar[0], al[1], ar[1], cospi_16_64, &bl[0], - &br[0], &bl[1], &br[1]); - butterfly_two_coeff_s32(al[3], ar[3], al[2], ar[2], cospi_8_64, cospi_24_64, - &bl[2], &br[2], &bl[3], &br[3]); - - bl[4] = vaddq_s32(al[4], al[5]); - br[4] = vaddq_s32(ar[4], ar[5]); - bl[5] = vsubq_s32(al[4], al[5]); - br[5] = vsubq_s32(ar[4], ar[5]); - bl[6] = vsubq_s32(al[7], al[6]); - br[6] = vsubq_s32(ar[7], ar[6]); - bl[7] = vaddq_s32(al[7], al[6]); - br[7] = vaddq_s32(ar[7], ar[6]); - - bl[8] = al[8]; - br[8] = ar[8]; - - butterfly_two_coeff_s32(al[14], ar[14], al[9], ar[9], cospi_8_64, cospi_24_64, - &bl[14], &br[14], &bl[9], &br[9]); - butterfly_two_coeff_s32(al[13], ar[13], al[10], ar[10], cospi_24_64, - -cospi_8_64, &bl[13], &br[13], &bl[10], &br[10]); - - bl[11] = al[11]; - br[11] = ar[11]; - bl[12] = al[12]; - br[12] = ar[12]; - - bl[15] = al[15]; - br[15] = ar[15]; - - bl[16] = vaddq_s32(al[19], al[16]); - br[16] = vaddq_s32(ar[19], ar[16]); - bl[17] = vaddq_s32(al[18], al[17]); - br[17] = vaddq_s32(ar[18], ar[17]); - bl[18] = vsubq_s32(al[17], al[18]); - br[18] = vsubq_s32(ar[17], ar[18]); - bl[19] = vsubq_s32(al[16], al[19]); - br[19] = vsubq_s32(ar[16], ar[19]); - bl[20] = vsubq_s32(al[23], al[20]); - br[20] = vsubq_s32(ar[23], ar[20]); - bl[21] = vsubq_s32(al[22], al[21]); - br[21] = vsubq_s32(ar[22], ar[21]); - bl[22] = vaddq_s32(al[21], al[22]); - br[22] = vaddq_s32(ar[21], ar[22]); - bl[23] = vaddq_s32(al[20], al[23]); - br[23] = vaddq_s32(ar[20], ar[23]); - bl[24] = vaddq_s32(al[27], al[24]); - br[24] = vaddq_s32(ar[27], ar[24]); - bl[25] = vaddq_s32(al[26], al[25]); - br[25] = vaddq_s32(ar[26], ar[25]); - bl[26] = vsubq_s32(al[25], al[26]); - br[26] = vsubq_s32(ar[25], ar[26]); - bl[27] = vsubq_s32(al[24], al[27]); - br[27] = vsubq_s32(ar[24], ar[27]); - bl[28] = vsubq_s32(al[31], al[28]); - br[28] = vsubq_s32(ar[31], ar[28]); - bl[29] = vsubq_s32(al[30], al[29]); - br[29] = vsubq_s32(ar[30], ar[29]); - bl[30] = vaddq_s32(al[29], al[30]); - br[30] = vaddq_s32(ar[29], ar[30]); - bl[31] = vaddq_s32(al[28], al[31]); - br[31] = vaddq_s32(ar[28], ar[31]); - - // Stage 6. - al[0] = bl[0]; - ar[0] = br[0]; - al[1] = bl[1]; - ar[1] = br[1]; - al[2] = bl[2]; - ar[2] = br[2]; - al[3] = bl[3]; - ar[3] = br[3]; - - butterfly_two_coeff_s32(bl[7], br[7], bl[4], br[4], cospi_4_64, cospi_28_64, - &al[4], &ar[4], &al[7], &ar[7]); - butterfly_two_coeff_s32(bl[6], br[6], bl[5], br[5], cospi_20_64, cospi_12_64, - &al[5], &ar[5], &al[6], &ar[6]); - - al[8] = vaddq_s32(bl[8], bl[9]); - ar[8] = vaddq_s32(br[8], br[9]); - al[9] = vsubq_s32(bl[8], bl[9]); - ar[9] = vsubq_s32(br[8], br[9]); - al[10] = vsubq_s32(bl[11], bl[10]); - ar[10] = vsubq_s32(br[11], br[10]); - al[11] = vaddq_s32(bl[11], bl[10]); - ar[11] = vaddq_s32(br[11], br[10]); - al[12] = vaddq_s32(bl[12], bl[13]); - ar[12] = vaddq_s32(br[12], br[13]); - al[13] = vsubq_s32(bl[12], bl[13]); - ar[13] = vsubq_s32(br[12], br[13]); - al[14] = vsubq_s32(bl[15], bl[14]); - ar[14] = vsubq_s32(br[15], br[14]); - al[15] = vaddq_s32(bl[15], bl[14]); - ar[15] = vaddq_s32(br[15], br[14]); - - al[16] = bl[16]; - ar[16] = br[16]; - al[19] = bl[19]; - ar[19] = br[19]; - al[20] = bl[20]; - ar[20] = br[20]; - al[23] = bl[23]; - ar[23] = br[23]; - al[24] = bl[24]; - ar[24] = br[24]; - al[27] = bl[27]; - ar[27] = br[27]; - al[28] = bl[28]; - ar[28] = br[28]; - al[31] = bl[31]; - ar[31] = br[31]; - - butterfly_two_coeff_s32(bl[30], br[30], bl[17], br[17], cospi_4_64, - cospi_28_64, &al[30], &ar[30], &al[17], &ar[17]); - butterfly_two_coeff_s32(bl[29], br[29], bl[18], br[18], cospi_28_64, - -cospi_4_64, &al[29], &ar[29], &al[18], &ar[18]); - butterfly_two_coeff_s32(bl[26], br[26], bl[21], br[21], cospi_20_64, - cospi_12_64, &al[26], &ar[26], &al[21], &ar[21]); - butterfly_two_coeff_s32(bl[25], br[25], bl[22], br[22], cospi_12_64, - -cospi_20_64, &al[25], &ar[25], &al[22], &ar[22]); - - // Stage 7. - bl[0] = al[0]; - br[0] = ar[0]; - bl[1] = al[1]; - br[1] = ar[1]; - bl[2] = al[2]; - br[2] = ar[2]; - bl[3] = al[3]; - br[3] = ar[3]; - bl[4] = al[4]; - br[4] = ar[4]; - bl[5] = al[5]; - br[5] = ar[5]; - bl[6] = al[6]; - br[6] = ar[6]; - bl[7] = al[7]; - br[7] = ar[7]; - - butterfly_two_coeff_s32(al[15], ar[15], al[8], ar[8], cospi_2_64, cospi_30_64, - &bl[8], &br[8], &bl[15], &br[15]); - butterfly_two_coeff_s32(al[14], ar[14], al[9], ar[9], cospi_18_64, - cospi_14_64, &bl[9], &br[9], &bl[14], &br[14]); - butterfly_two_coeff_s32(al[13], ar[13], al[10], ar[10], cospi_10_64, - cospi_22_64, &bl[10], &br[10], &bl[13], &br[13]); - butterfly_two_coeff_s32(al[12], ar[12], al[11], ar[11], cospi_26_64, - cospi_6_64, &bl[11], &br[11], &bl[12], &br[12]); - - bl[16] = vaddq_s32(al[16], al[17]); - br[16] = vaddq_s32(ar[16], ar[17]); - bl[17] = vsubq_s32(al[16], al[17]); - br[17] = vsubq_s32(ar[16], ar[17]); - bl[18] = vsubq_s32(al[19], al[18]); - br[18] = vsubq_s32(ar[19], ar[18]); - bl[19] = vaddq_s32(al[19], al[18]); - br[19] = vaddq_s32(ar[19], ar[18]); - bl[20] = vaddq_s32(al[20], al[21]); - br[20] = vaddq_s32(ar[20], ar[21]); - bl[21] = vsubq_s32(al[20], al[21]); - br[21] = vsubq_s32(ar[20], ar[21]); - bl[22] = vsubq_s32(al[23], al[22]); - br[22] = vsubq_s32(ar[23], ar[22]); - bl[23] = vaddq_s32(al[23], al[22]); - br[23] = vaddq_s32(ar[23], ar[22]); - bl[24] = vaddq_s32(al[24], al[25]); - br[24] = vaddq_s32(ar[24], ar[25]); - bl[25] = vsubq_s32(al[24], al[25]); - br[25] = vsubq_s32(ar[24], ar[25]); - bl[26] = vsubq_s32(al[27], al[26]); - br[26] = vsubq_s32(ar[27], ar[26]); - bl[27] = vaddq_s32(al[27], al[26]); - br[27] = vaddq_s32(ar[27], ar[26]); - bl[28] = vaddq_s32(al[28], al[29]); - br[28] = vaddq_s32(ar[28], ar[29]); - bl[29] = vsubq_s32(al[28], al[29]); - br[29] = vsubq_s32(ar[28], ar[29]); - bl[30] = vsubq_s32(al[31], al[30]); - br[30] = vsubq_s32(ar[31], ar[30]); - bl[31] = vaddq_s32(al[31], al[30]); - br[31] = vaddq_s32(ar[31], ar[30]); - - // Final stage. - left[0] = bl[0]; - right[0] = br[0]; - left[16] = bl[1]; - right[16] = br[1]; - left[8] = bl[2]; - right[8] = br[2]; - left[24] = bl[3]; - right[24] = br[3]; - left[4] = bl[4]; - right[4] = br[4]; - left[20] = bl[5]; - right[20] = br[5]; - left[12] = bl[6]; - right[12] = br[6]; - left[28] = bl[7]; - right[28] = br[7]; - left[2] = bl[8]; - right[2] = br[8]; - left[18] = bl[9]; - right[18] = br[9]; - left[10] = bl[10]; - right[10] = br[10]; - left[26] = bl[11]; - right[26] = br[11]; - left[6] = bl[12]; - right[6] = br[12]; - left[22] = bl[13]; - right[22] = br[13]; - left[14] = bl[14]; - right[14] = br[14]; - left[30] = bl[15]; - right[30] = br[15]; - - butterfly_two_coeff_s32(bl[31], br[31], bl[16], br[16], cospi_1_64, - cospi_31_64, &al[1], &ar[1], &al[31], &ar[31]); - left[1] = al[1]; - right[1] = ar[1]; - left[31] = al[31]; - right[31] = ar[31]; - - butterfly_two_coeff_s32(bl[30], br[30], bl[17], br[17], cospi_17_64, - cospi_15_64, &al[17], &ar[17], &al[15], &ar[15]); - left[17] = al[17]; - right[17] = ar[17]; - left[15] = al[15]; - right[15] = ar[15]; - - butterfly_two_coeff_s32(bl[29], br[29], bl[18], br[18], cospi_9_64, - cospi_23_64, &al[9], &ar[9], &al[23], &ar[23]); - left[9] = al[9]; - right[9] = ar[9]; - left[23] = al[23]; - right[23] = ar[23]; - - butterfly_two_coeff_s32(bl[28], br[28], bl[19], br[19], cospi_25_64, - cospi_7_64, &al[25], &ar[25], &al[7], &ar[7]); - left[25] = al[25]; - right[25] = ar[25]; - left[7] = al[7]; - right[7] = ar[7]; - - butterfly_two_coeff_s32(bl[27], br[27], bl[20], br[20], cospi_5_64, - cospi_27_64, &al[5], &ar[5], &al[27], &ar[27]); - left[5] = al[5]; - right[5] = ar[5]; - left[27] = al[27]; - right[27] = ar[27]; - - butterfly_two_coeff_s32(bl[26], br[26], bl[21], br[21], cospi_21_64, - cospi_11_64, &al[21], &ar[21], &al[11], &ar[11]); - left[21] = al[21]; - right[21] = ar[21]; - left[11] = al[11]; - right[11] = ar[11]; - - butterfly_two_coeff_s32(bl[25], br[25], bl[22], br[22], cospi_13_64, - cospi_19_64, &al[13], &ar[13], &al[19], &ar[19]); - left[13] = al[13]; - right[13] = ar[13]; - left[19] = al[19]; - right[19] = ar[19]; - - butterfly_two_coeff_s32(bl[24], br[24], bl[23], br[23], cospi_29_64, - cospi_3_64, &al[29], &ar[29], &al[3], &ar[3]); - left[29] = al[29]; - right[29] = ar[29]; - left[3] = al[3]; - right[3] = ar[3]; -} - -#endif // CONFIG_VP9_HIGHBITDEPTH - -#endif // VPX_VPX_DSP_ARM_FDCT32X32_NEON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct4x4_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct4x4_neon.c deleted file mode 100644 index 4bc968ec..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct4x4_neon.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/txfm_common.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/fdct_neon.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/arm/fdct4x4_neon.h" - -void vpx_fdct4x4_neon(const int16_t *input, tran_low_t *final_output, - int stride) { - // input[M * stride] * 16 - int16x4_t in[4]; - in[0] = vshl_n_s16(vld1_s16(input + 0 * stride), 4); - in[1] = vshl_n_s16(vld1_s16(input + 1 * stride), 4); - in[2] = vshl_n_s16(vld1_s16(input + 2 * stride), 4); - in[3] = vshl_n_s16(vld1_s16(input + 3 * stride), 4); - - // If the very first value != 0, then add 1. - if (input[0] != 0) { - const int16x4_t one = vreinterpret_s16_s64(vdup_n_s64(1)); - in[0] = vadd_s16(in[0], one); - } - vpx_fdct4x4_pass1_neon(in); - vpx_fdct4x4_pass2_neon(in); - { - // Not quite a rounding shift. Only add 1 despite shifting by 2. - const int16x8_t one = vdupq_n_s16(1); - int16x8_t out_01 = vcombine_s16(in[0], in[1]); - int16x8_t out_23 = vcombine_s16(in[2], in[3]); - out_01 = vshrq_n_s16(vaddq_s16(out_01, one), 2); - out_23 = vshrq_n_s16(vaddq_s16(out_23, one), 2); - store_s16q_to_tran_low(final_output + 0 * 8, out_01); - store_s16q_to_tran_low(final_output + 1 * 8, out_23); - } -} - -#if CONFIG_VP9_HIGHBITDEPTH - -void vpx_highbd_fdct4x4_neon(const int16_t *input, tran_low_t *final_output, - int stride) { - const int32x4_t const_one = vdupq_n_s32(1); - - // input[M * stride] * 16 - int32x4_t in[4]; - in[0] = vshll_n_s16(vld1_s16(input + 0 * stride), 4); - in[1] = vshll_n_s16(vld1_s16(input + 1 * stride), 4); - in[2] = vshll_n_s16(vld1_s16(input + 2 * stride), 4); - in[3] = vshll_n_s16(vld1_s16(input + 3 * stride), 4); - - // If the very first value != 0, then add 1. - if (input[0] != 0) { - static const int32_t k1000[4] = { 1, 0, 0, 0 }; - in[0] = vaddq_s32(in[0], vld1q_s32(k1000)); - } - - vpx_highbd_fdct4x4_pass1_neon(in); - vpx_highbd_fdct4x4_pass1_neon(in); - { - // Not quite a rounding shift. Only add 1 despite shifting by 2. - in[0] = vshrq_n_s32(vaddq_s32(in[0], const_one), 2); - in[1] = vshrq_n_s32(vaddq_s32(in[1], const_one), 2); - in[2] = vshrq_n_s32(vaddq_s32(in[2], const_one), 2); - in[3] = vshrq_n_s32(vaddq_s32(in[3], const_one), 2); - - vst1q_s32(final_output, in[0]); - vst1q_s32(final_output + 4, in[1]); - vst1q_s32(final_output + 8, in[2]); - vst1q_s32(final_output + 12, in[3]); - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct4x4_neon.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct4x4_neon.h deleted file mode 100644 index de3db977..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct4x4_neon.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_ARM_FDCT4X4_NEON_H_ -#define VPX_VPX_DSP_ARM_FDCT4X4_NEON_H_ - -#include - -static INLINE void vpx_fdct4x4_pass1_neon(int16x4_t *in) { - int16x4_t out[4]; - - const int16x8_t input_01 = vcombine_s16(in[0], in[1]); - const int16x8_t input_32 = vcombine_s16(in[3], in[2]); - - // in_0 +/- in_3, in_1 +/- in_2 - const int16x8_t s_01 = vaddq_s16(input_01, input_32); - const int16x8_t s_32 = vsubq_s16(input_01, input_32); - - // step_0 +/- step_1, step_2 +/- step_3 - const int16x4_t s_0 = vget_low_s16(s_01); - const int16x4_t s_1 = vget_high_s16(s_01); - const int16x4_t s_2 = vget_high_s16(s_32); - const int16x4_t s_3 = vget_low_s16(s_32); - - // fdct_round_shift(s_0 +/- s_1) * cospi_16_64 - butterfly_one_coeff_s16_fast_half(s_0, s_1, cospi_16_64, &out[0], &out[2]); - - // s_3 * cospi_8_64 + s_2 * cospi_24_64 - // s_3 * cospi_24_64 - s_2 * cospi_8_64 - butterfly_two_coeff_half(s_3, s_2, cospi_8_64, cospi_24_64, &out[1], &out[3]); - - transpose_s16_4x4d(&out[0], &out[1], &out[2], &out[3]); - - in[0] = out[0]; - in[1] = out[1]; - in[2] = out[2]; - in[3] = out[3]; -} - -static INLINE void vpx_fdct4x4_pass2_neon(int16x4_t *in) { - int16x4_t out[4]; - - const int16x8_t input_01 = vcombine_s16(in[0], in[1]); - const int16x8_t input_32 = vcombine_s16(in[3], in[2]); - - // in_0 +/- in_3, in_1 +/- in_2 - const int16x8_t s_01 = vaddq_s16(input_01, input_32); - const int16x8_t s_32 = vsubq_s16(input_01, input_32); - - // step_0 +/- step_1, step_2 +/- step_3 - const int16x4_t s_0 = vget_low_s16(s_01); - const int16x4_t s_1 = vget_high_s16(s_01); - const int16x4_t s_2 = vget_high_s16(s_32); - const int16x4_t s_3 = vget_low_s16(s_32); - - // fdct_round_shift(s_0 +/- s_1) * cospi_16_64 - butterfly_one_coeff_s16_s32_fast_narrow_half(s_0, s_1, cospi_16_64, &out[0], - &out[2]); - - // s_3 * cospi_8_64 + s_2 * cospi_24_64 - // s_3 * cospi_24_64 - s_2 * cospi_8_64 - butterfly_two_coeff_half(s_3, s_2, cospi_8_64, cospi_24_64, &out[1], &out[3]); - - transpose_s16_4x4d(&out[0], &out[1], &out[2], &out[3]); - - in[0] = out[0]; - in[1] = out[1]; - in[2] = out[2]; - in[3] = out[3]; -} - -#if CONFIG_VP9_HIGHBITDEPTH - -static INLINE void vpx_highbd_fdct4x4_pass1_neon(int32x4_t *in) { - int32x4_t out[4]; - // in_0 +/- in_3, in_1 +/- in_2 - const int32x4_t s_0 = vaddq_s32(in[0], in[3]); - const int32x4_t s_1 = vaddq_s32(in[1], in[2]); - const int32x4_t s_2 = vsubq_s32(in[1], in[2]); - const int32x4_t s_3 = vsubq_s32(in[0], in[3]); - - butterfly_one_coeff_s32_fast_half(s_0, s_1, cospi_16_64, &out[0], &out[2]); - - // out[1] = s_3 * cospi_8_64 + s_2 * cospi_24_64 - // out[3] = s_3 * cospi_24_64 - s_2 * cospi_8_64 - butterfly_two_coeff_s32_s64_narrow_half(s_3, s_2, cospi_8_64, cospi_24_64, - &out[1], &out[3]); - - transpose_s32_4x4(&out[0], &out[1], &out[2], &out[3]); - - in[0] = out[0]; - in[1] = out[1]; - in[2] = out[2]; - in[3] = out[3]; -} - -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif // VPX_VPX_DSP_ARM_FDCT4X4_NEON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct8x8_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct8x8_neon.c deleted file mode 100644 index 75ee6f22..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct8x8_neon.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/txfm_common.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/fdct_neon.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/fdct8x8_neon.h" - -void vpx_fdct8x8_neon(const int16_t *input, tran_low_t *final_output, - int stride) { - // stage 1 - int16x8_t in[8]; - in[0] = vshlq_n_s16(vld1q_s16(&input[0 * stride]), 2); - in[1] = vshlq_n_s16(vld1q_s16(&input[1 * stride]), 2); - in[2] = vshlq_n_s16(vld1q_s16(&input[2 * stride]), 2); - in[3] = vshlq_n_s16(vld1q_s16(&input[3 * stride]), 2); - in[4] = vshlq_n_s16(vld1q_s16(&input[4 * stride]), 2); - in[5] = vshlq_n_s16(vld1q_s16(&input[5 * stride]), 2); - in[6] = vshlq_n_s16(vld1q_s16(&input[6 * stride]), 2); - in[7] = vshlq_n_s16(vld1q_s16(&input[7 * stride]), 2); - - vpx_fdct8x8_pass1_neon(in); - vpx_fdct8x8_pass2_neon(in); - { - // from vpx_dct_sse2.c - // Post-condition (division by two) - // division of two 16 bits signed numbers using shifts - // n / 2 = (n - (n >> 15)) >> 1 - const int16x8_t sign_in0 = vshrq_n_s16(in[0], 15); - const int16x8_t sign_in1 = vshrq_n_s16(in[1], 15); - const int16x8_t sign_in2 = vshrq_n_s16(in[2], 15); - const int16x8_t sign_in3 = vshrq_n_s16(in[3], 15); - const int16x8_t sign_in4 = vshrq_n_s16(in[4], 15); - const int16x8_t sign_in5 = vshrq_n_s16(in[5], 15); - const int16x8_t sign_in6 = vshrq_n_s16(in[6], 15); - const int16x8_t sign_in7 = vshrq_n_s16(in[7], 15); - in[0] = vhsubq_s16(in[0], sign_in0); - in[1] = vhsubq_s16(in[1], sign_in1); - in[2] = vhsubq_s16(in[2], sign_in2); - in[3] = vhsubq_s16(in[3], sign_in3); - in[4] = vhsubq_s16(in[4], sign_in4); - in[5] = vhsubq_s16(in[5], sign_in5); - in[6] = vhsubq_s16(in[6], sign_in6); - in[7] = vhsubq_s16(in[7], sign_in7); - // store results - store_s16q_to_tran_low(final_output + 0 * 8, in[0]); - store_s16q_to_tran_low(final_output + 1 * 8, in[1]); - store_s16q_to_tran_low(final_output + 2 * 8, in[2]); - store_s16q_to_tran_low(final_output + 3 * 8, in[3]); - store_s16q_to_tran_low(final_output + 4 * 8, in[4]); - store_s16q_to_tran_low(final_output + 5 * 8, in[5]); - store_s16q_to_tran_low(final_output + 6 * 8, in[6]); - store_s16q_to_tran_low(final_output + 7 * 8, in[7]); - } -} - -#if CONFIG_VP9_HIGHBITDEPTH - -void vpx_highbd_fdct8x8_neon(const int16_t *input, tran_low_t *final_output, - int stride) { - // input[M * stride] * 16 - int32x4_t left[8], right[8]; - int16x8_t in[8]; - in[0] = vld1q_s16(input + 0 * stride); - in[1] = vld1q_s16(input + 1 * stride); - in[2] = vld1q_s16(input + 2 * stride); - in[3] = vld1q_s16(input + 3 * stride); - in[4] = vld1q_s16(input + 4 * stride); - in[5] = vld1q_s16(input + 5 * stride); - in[6] = vld1q_s16(input + 6 * stride); - in[7] = vld1q_s16(input + 7 * stride); - - left[0] = vshll_n_s16(vget_low_s16(in[0]), 2); - left[1] = vshll_n_s16(vget_low_s16(in[1]), 2); - left[2] = vshll_n_s16(vget_low_s16(in[2]), 2); - left[3] = vshll_n_s16(vget_low_s16(in[3]), 2); - left[4] = vshll_n_s16(vget_low_s16(in[4]), 2); - left[5] = vshll_n_s16(vget_low_s16(in[5]), 2); - left[6] = vshll_n_s16(vget_low_s16(in[6]), 2); - left[7] = vshll_n_s16(vget_low_s16(in[7]), 2); - right[0] = vshll_n_s16(vget_high_s16(in[0]), 2); - right[1] = vshll_n_s16(vget_high_s16(in[1]), 2); - right[2] = vshll_n_s16(vget_high_s16(in[2]), 2); - right[3] = vshll_n_s16(vget_high_s16(in[3]), 2); - right[4] = vshll_n_s16(vget_high_s16(in[4]), 2); - right[5] = vshll_n_s16(vget_high_s16(in[5]), 2); - right[6] = vshll_n_s16(vget_high_s16(in[6]), 2); - right[7] = vshll_n_s16(vget_high_s16(in[7]), 2); - - vpx_highbd_fdct8x8_pass1_neon(left, right); - vpx_highbd_fdct8x8_pass2_neon(left, right); - { - left[0] = add_round_shift_half_s32(left[0]); - left[1] = add_round_shift_half_s32(left[1]); - left[2] = add_round_shift_half_s32(left[2]); - left[3] = add_round_shift_half_s32(left[3]); - left[4] = add_round_shift_half_s32(left[4]); - left[5] = add_round_shift_half_s32(left[5]); - left[6] = add_round_shift_half_s32(left[6]); - left[7] = add_round_shift_half_s32(left[7]); - right[0] = add_round_shift_half_s32(right[0]); - right[1] = add_round_shift_half_s32(right[1]); - right[2] = add_round_shift_half_s32(right[2]); - right[3] = add_round_shift_half_s32(right[3]); - right[4] = add_round_shift_half_s32(right[4]); - right[5] = add_round_shift_half_s32(right[5]); - right[6] = add_round_shift_half_s32(right[6]); - right[7] = add_round_shift_half_s32(right[7]); - - // store results - vst1q_s32(final_output, left[0]); - vst1q_s32(final_output + 4, right[0]); - vst1q_s32(final_output + 8, left[1]); - vst1q_s32(final_output + 12, right[1]); - vst1q_s32(final_output + 16, left[2]); - vst1q_s32(final_output + 20, right[2]); - vst1q_s32(final_output + 24, left[3]); - vst1q_s32(final_output + 28, right[3]); - vst1q_s32(final_output + 32, left[4]); - vst1q_s32(final_output + 36, right[4]); - vst1q_s32(final_output + 40, left[5]); - vst1q_s32(final_output + 44, right[5]); - vst1q_s32(final_output + 48, left[6]); - vst1q_s32(final_output + 52, right[6]); - vst1q_s32(final_output + 56, left[7]); - vst1q_s32(final_output + 60, right[7]); - } -} - -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct8x8_neon.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct8x8_neon.h deleted file mode 100644 index cc651574..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct8x8_neon.h +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_ARM_FDCT8X8_NEON_H_ -#define VPX_VPX_DSP_ARM_FDCT8X8_NEON_H_ - -#include - -static INLINE void vpx_fdct8x8_pass1_notranspose_neon(int16x8_t *in, - int16x8_t *out) { - int16x8_t s[8], x[4], t[2]; - - s[0] = vaddq_s16(in[0], in[7]); - s[1] = vaddq_s16(in[1], in[6]); - s[2] = vaddq_s16(in[2], in[5]); - s[3] = vaddq_s16(in[3], in[4]); - s[4] = vsubq_s16(in[3], in[4]); - s[5] = vsubq_s16(in[2], in[5]); - s[6] = vsubq_s16(in[1], in[6]); - s[7] = vsubq_s16(in[0], in[7]); - // fdct4(step, step); - x[0] = vaddq_s16(s[0], s[3]); - x[1] = vaddq_s16(s[1], s[2]); - x[2] = vsubq_s16(s[1], s[2]); - x[3] = vsubq_s16(s[0], s[3]); - - // fdct4(step, step); - // out[0] = (tran_low_t)fdct_round_shift((x0 + x1) * cospi_16_64) - // out[4] = (tran_low_t)fdct_round_shift((x0 - x1) * cospi_16_64) - butterfly_one_coeff_s16_fast(x[0], x[1], cospi_16_64, &out[0], &out[4]); - // out[2] = (tran_low_t)fdct_round_shift(x2 * cospi_24_64 + x3 * cospi_8_64) - // out[6] = (tran_low_t)fdct_round_shift(-x2 * cospi_8_64 + x3 * cospi_24_64) - butterfly_two_coeff(x[3], x[2], cospi_8_64, cospi_24_64, &out[2], &out[6]); - - // Stage 2 - // t0 = (s6 - s5) * cospi_16_64; - // t1 = (s6 + s5) * cospi_16_64; - butterfly_one_coeff_s16_fast(s[6], s[5], cospi_16_64, &t[1], &t[0]); - - // Stage 3 - x[0] = vaddq_s16(s[4], t[0]); - x[1] = vsubq_s16(s[4], t[0]); - x[2] = vsubq_s16(s[7], t[1]); - x[3] = vaddq_s16(s[7], t[1]); - - // Stage 4 - // out[1] = (tran_low_t)fdct_round_shift(x0 * cospi_28_64 + x3 * cospi_4_64) - // out[7] = (tran_low_t)fdct_round_shift(x3 * cospi_28_64 + x0 * -cospi_4_64) - butterfly_two_coeff(x[3], x[0], cospi_4_64, cospi_28_64, &out[1], &out[7]); - - // out[5] = (tran_low_t)fdct_round_shift(x1 * cospi_12_64 + x2 * cospi_20_64) - // out[3] = (tran_low_t)fdct_round_shift(x2 * cospi_12_64 + x1 * -cospi_20_64) - butterfly_two_coeff(x[2], x[1], cospi_20_64, cospi_12_64, &out[5], &out[3]); -} - -static INLINE void vpx_fdct8x8_pass2_notranspose_neon(int16x8_t *in, - int16x8_t *out) { - int16x8_t s[8], x[4], t[2]; - - s[0] = vaddq_s16(in[0], in[7]); - s[1] = vaddq_s16(in[1], in[6]); - s[2] = vaddq_s16(in[2], in[5]); - s[3] = vaddq_s16(in[3], in[4]); - s[4] = vsubq_s16(in[3], in[4]); - s[5] = vsubq_s16(in[2], in[5]); - s[6] = vsubq_s16(in[1], in[6]); - s[7] = vsubq_s16(in[0], in[7]); - // fdct4(step, step); - x[0] = vaddq_s16(s[0], s[3]); - x[1] = vaddq_s16(s[1], s[2]); - x[2] = vsubq_s16(s[1], s[2]); - x[3] = vsubq_s16(s[0], s[3]); - - // fdct4(step, step); - // out[0] = (tran_low_t)fdct_round_shift((x0 + x1) * cospi_16_64) - // out[4] = (tran_low_t)fdct_round_shift((x0 - x1) * cospi_16_64) - butterfly_one_coeff_s16_s32_fast_narrow(x[0], x[1], cospi_16_64, &out[0], - &out[4]); - // out[2] = (tran_low_t)fdct_round_shift(x2 * cospi_24_64 + x3 * cospi_8_64) - // out[6] = (tran_low_t)fdct_round_shift(-x2 * cospi_8_64 + x3 * cospi_24_64) - butterfly_two_coeff(x[3], x[2], cospi_8_64, cospi_24_64, &out[2], &out[6]); - - // Stage 2 - // t0 = (s6 - s5) * cospi_16_64; - // t1 = (s6 + s5) * cospi_16_64; - butterfly_one_coeff_s16_s32_fast_narrow(s[6], s[5], cospi_16_64, &t[1], - &t[0]); - - // Stage 3 - x[0] = vaddq_s16(s[4], t[0]); - x[1] = vsubq_s16(s[4], t[0]); - x[2] = vsubq_s16(s[7], t[1]); - x[3] = vaddq_s16(s[7], t[1]); - - // Stage 4 - // out[1] = (tran_low_t)fdct_round_shift(x0 * cospi_28_64 + x3 * cospi_4_64) - // out[7] = (tran_low_t)fdct_round_shift(x3 * cospi_28_64 + x0 * -cospi_4_64) - butterfly_two_coeff(x[3], x[0], cospi_4_64, cospi_28_64, &out[1], &out[7]); - - // out[5] = (tran_low_t)fdct_round_shift(x1 * cospi_12_64 + x2 * cospi_20_64) - // out[3] = (tran_low_t)fdct_round_shift(x2 * cospi_12_64 + x1 * -cospi_20_64) - butterfly_two_coeff(x[2], x[1], cospi_20_64, cospi_12_64, &out[5], &out[3]); -} - -static INLINE void vpx_fdct8x8_pass1_neon(int16x8_t *in) { - int16x8_t out[8]; - vpx_fdct8x8_pass1_notranspose_neon(in, out); - // transpose 8x8 - transpose_s16_8x8(&out[0], &out[1], &out[2], &out[3], &out[4], &out[5], - &out[6], &out[7]); - in[0] = out[0]; - in[1] = out[1]; - in[2] = out[2]; - in[3] = out[3]; - in[4] = out[4]; - in[5] = out[5]; - in[6] = out[6]; - in[7] = out[7]; -} - -static INLINE void vpx_fdct8x8_pass2_neon(int16x8_t *in) { - int16x8_t out[8]; - vpx_fdct8x8_pass2_notranspose_neon(in, out); - // transpose 8x8 - transpose_s16_8x8(&out[0], &out[1], &out[2], &out[3], &out[4], &out[5], - &out[6], &out[7]); - in[0] = out[0]; - in[1] = out[1]; - in[2] = out[2]; - in[3] = out[3]; - in[4] = out[4]; - in[5] = out[5]; - in[6] = out[6]; - in[7] = out[7]; -} - -#if CONFIG_VP9_HIGHBITDEPTH -static INLINE void vpx_highbd_fdct8x8_pass1_notranspose_neon(int32x4_t *left, - int32x4_t *right) { - int32x4_t sl[8], sr[8], xl[4], xr[4], tl[4], tr[4]; - - sl[0] = vaddq_s32(left[0], left[7]); - sl[1] = vaddq_s32(left[1], left[6]); - sl[2] = vaddq_s32(left[2], left[5]); - sl[3] = vaddq_s32(left[3], left[4]); - sl[4] = vsubq_s32(left[3], left[4]); - sl[5] = vsubq_s32(left[2], left[5]); - sl[6] = vsubq_s32(left[1], left[6]); - sl[7] = vsubq_s32(left[0], left[7]); - sr[0] = vaddq_s32(right[0], right[7]); - sr[1] = vaddq_s32(right[1], right[6]); - sr[2] = vaddq_s32(right[2], right[5]); - sr[3] = vaddq_s32(right[3], right[4]); - sr[4] = vsubq_s32(right[3], right[4]); - sr[5] = vsubq_s32(right[2], right[5]); - sr[6] = vsubq_s32(right[1], right[6]); - sr[7] = vsubq_s32(right[0], right[7]); - - // fdct4(step, step); - // x0 = s0 + s3; - xl[0] = vaddq_s32(sl[0], sl[3]); - xr[0] = vaddq_s32(sr[0], sr[3]); - // x1 = s1 + s2; - xl[1] = vaddq_s32(sl[1], sl[2]); - xr[1] = vaddq_s32(sr[1], sr[2]); - // x2 = s1 - s2; - xl[2] = vsubq_s32(sl[1], sl[2]); - xr[2] = vsubq_s32(sr[1], sr[2]); - // x3 = s0 - s3; - xl[3] = vsubq_s32(sl[0], sl[3]); - xr[3] = vsubq_s32(sr[0], sr[3]); - - // fdct4(step, step); - // out[0] = (tran_low_t)fdct_round_shift((x0 + x1) * cospi_16_64) - // out[4] = (tran_low_t)fdct_round_shift((x0 - x1) * cospi_16_64) - butterfly_one_coeff_s32_fast(xl[0], xr[0], xl[1], xr[1], cospi_16_64, - &left[0], &right[0], &left[4], &right[4]); - // out[2] = (tran_low_t)fdct_round_shift(x2 * cospi_24_64 + x3 * cospi_8_64) - // out[6] = (tran_low_t)fdct_round_shift(-x2 * cospi_8_64 + x3 * cospi_24_64) - butterfly_two_coeff_s32(xl[3], xr[3], xl[2], xr[2], cospi_8_64, cospi_24_64, - &left[2], &right[2], &left[6], &right[6]); - - // Stage 2 - // t0 = (s6 - s5) * cospi_16_64; - // t1 = (s6 + s5) * cospi_16_64; - butterfly_one_coeff_s32_fast(sl[6], sr[6], sl[5], sr[5], cospi_16_64, &tl[1], - &tr[1], &tl[0], &tr[0]); - - // Stage 3 - xl[0] = vaddq_s32(sl[4], tl[0]); - xr[0] = vaddq_s32(sr[4], tr[0]); - xl[1] = vsubq_s32(sl[4], tl[0]); - xr[1] = vsubq_s32(sr[4], tr[0]); - xl[2] = vsubq_s32(sl[7], tl[1]); - xr[2] = vsubq_s32(sr[7], tr[1]); - xl[3] = vaddq_s32(sl[7], tl[1]); - xr[3] = vaddq_s32(sr[7], tr[1]); - - // Stage 4 - // out[1] = (tran_low_t)fdct_round_shift(x0 * cospi_28_64 + x3 * cospi_4_64) - // out[7] = (tran_low_t)fdct_round_shift(x3 * cospi_28_64 + x0 * -cospi_4_64) - butterfly_two_coeff_s32(xl[3], xr[3], xl[0], xr[0], cospi_4_64, cospi_28_64, - &left[1], &right[1], &left[7], &right[7]); - - // out[5] = (tran_low_t)fdct_round_shift(x1 * cospi_12_64 + x2 * cospi_20_64) - // out[3] = (tran_low_t)fdct_round_shift(x2 * cospi_12_64 + x1 * -cospi_20_64) - butterfly_two_coeff_s32(xl[2], xr[2], xl[1], xr[1], cospi_20_64, cospi_12_64, - &left[5], &right[5], &left[3], &right[3]); -} - -static INLINE void vpx_highbd_fdct8x8_pass2_notranspose_neon(int32x4_t *left, - int32x4_t *right) { - int32x4_t sl[8], sr[8], xl[4], xr[4], tl[4], tr[4]; - - sl[0] = vaddq_s32(left[0], left[7]); - sl[1] = vaddq_s32(left[1], left[6]); - sl[2] = vaddq_s32(left[2], left[5]); - sl[3] = vaddq_s32(left[3], left[4]); - sl[4] = vsubq_s32(left[3], left[4]); - sl[5] = vsubq_s32(left[2], left[5]); - sl[6] = vsubq_s32(left[1], left[6]); - sl[7] = vsubq_s32(left[0], left[7]); - sr[0] = vaddq_s32(right[0], right[7]); - sr[1] = vaddq_s32(right[1], right[6]); - sr[2] = vaddq_s32(right[2], right[5]); - sr[3] = vaddq_s32(right[3], right[4]); - sr[4] = vsubq_s32(right[3], right[4]); - sr[5] = vsubq_s32(right[2], right[5]); - sr[6] = vsubq_s32(right[1], right[6]); - sr[7] = vsubq_s32(right[0], right[7]); - - // fdct4(step, step); - // x0 = s0 + s3; - xl[0] = vaddq_s32(sl[0], sl[3]); - xr[0] = vaddq_s32(sr[0], sr[3]); - // x1 = s1 + s2; - xl[1] = vaddq_s32(sl[1], sl[2]); - xr[1] = vaddq_s32(sr[1], sr[2]); - // x2 = s1 - s2; - xl[2] = vsubq_s32(sl[1], sl[2]); - xr[2] = vsubq_s32(sr[1], sr[2]); - // x3 = s0 - s3; - xl[3] = vsubq_s32(sl[0], sl[3]); - xr[3] = vsubq_s32(sr[0], sr[3]); - - // fdct4(step, step); - // out[0] = (tran_low_t)fdct_round_shift((x0 + x1) * cospi_16_64) - // out[4] = (tran_low_t)fdct_round_shift((x0 - x1) * cospi_16_64) - butterfly_one_coeff_s32_fast(xl[0], xr[0], xl[1], xr[1], cospi_16_64, - &left[0], &right[0], &left[4], &right[4]); - // out[2] = (tran_low_t)fdct_round_shift(x2 * cospi_24_64 + x3 * cospi_8_64) - // out[6] = (tran_low_t)fdct_round_shift(-x2 * cospi_8_64 + x3 * cospi_24_64) - butterfly_two_coeff_s32_s64_narrow(xl[3], xr[3], xl[2], xr[2], cospi_8_64, - cospi_24_64, &left[2], &right[2], &left[6], - &right[6]); - - // Stage 2 - // t0 = (s6 - s5) * cospi_16_64; - // t1 = (s6 + s5) * cospi_16_64; - butterfly_one_coeff_s32_fast(sl[6], sr[6], sl[5], sr[5], cospi_16_64, &tl[1], - &tr[1], &tl[0], &tr[0]); - - // Stage 3 - xl[0] = vaddq_s32(sl[4], tl[0]); - xr[0] = vaddq_s32(sr[4], tr[0]); - xl[1] = vsubq_s32(sl[4], tl[0]); - xr[1] = vsubq_s32(sr[4], tr[0]); - xl[2] = vsubq_s32(sl[7], tl[1]); - xr[2] = vsubq_s32(sr[7], tr[1]); - xl[3] = vaddq_s32(sl[7], tl[1]); - xr[3] = vaddq_s32(sr[7], tr[1]); - - // Stage 4 - // out[1] = (tran_low_t)fdct_round_shift(x0 * cospi_28_64 + x3 * cospi_4_64) - // out[7] = (tran_low_t)fdct_round_shift(x3 * cospi_28_64 + x0 * -cospi_4_64) - butterfly_two_coeff_s32_s64_narrow(xl[3], xr[3], xl[0], xr[0], cospi_4_64, - cospi_28_64, &left[1], &right[1], &left[7], - &right[7]); - - // out[5] = (tran_low_t)fdct_round_shift(x1 * cospi_12_64 + x2 * cospi_20_64) - // out[3] = (tran_low_t)fdct_round_shift(x2 * cospi_12_64 + x1 * -cospi_20_64) - butterfly_two_coeff_s32_s64_narrow(xl[2], xr[2], xl[1], xr[1], cospi_20_64, - cospi_12_64, &left[5], &right[5], &left[3], - &right[3]); -} - -static INLINE void vpx_highbd_fdct8x8_pass1_neon(int32x4_t *left, - int32x4_t *right) { - vpx_highbd_fdct8x8_pass1_notranspose_neon(left, right); - transpose_s32_8x8_2(left, right, left, right); -} - -static INLINE void vpx_highbd_fdct8x8_pass2_neon(int32x4_t *left, - int32x4_t *right) { - vpx_highbd_fdct8x8_pass2_notranspose_neon(left, right); - transpose_s32_8x8_2(left, right, left, right); -} - -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif // VPX_VPX_DSP_ARM_FDCT8X8_NEON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct_neon.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct_neon.h deleted file mode 100644 index 16f5c5fc..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct_neon.h +++ /dev/null @@ -1,542 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_ARM_FDCT_NEON_H_ -#define VPX_VPX_DSP_ARM_FDCT_NEON_H_ - -#include - -// fdct_round_shift((a +/- b) * c) -// Variant that performs fast vqrdmulh_s16 operation on half vector -// can be slightly less accurate, adequate for pass1 -static INLINE void butterfly_one_coeff_s16_fast_half(const int16x4_t a, - const int16x4_t b, - const tran_coef_t constant, - int16x4_t *add, - int16x4_t *sub) { - int16x4_t c = vdup_n_s16(2 * constant); - *add = vqrdmulh_s16(vadd_s16(a, b), c); - *sub = vqrdmulh_s16(vsub_s16(a, b), c); -} - -// fdct_round_shift((a +/- b) * c) -// Variant that performs fast vqrdmulh_s16 operation on full vector -// can be slightly less accurate, adequate for pass1 -static INLINE void butterfly_one_coeff_s16_fast(const int16x8_t a, - const int16x8_t b, - const tran_coef_t constant, - int16x8_t *add, - int16x8_t *sub) { - int16x8_t c = vdupq_n_s16(2 * constant); - *add = vqrdmulhq_s16(vaddq_s16(a, b), c); - *sub = vqrdmulhq_s16(vsubq_s16(a, b), c); -} - -// fdct_round_shift((a +/- b) * c) -// Variant that performs fast vqrdmulhq_s32 operation on full vector -// more accurate does 32-bit processing, takes 16-bit input values, -// returns full 32-bit values, high/low -static INLINE void butterfly_one_coeff_s16_s32_fast( - const int16x8_t a, const int16x8_t b, const tran_coef_t constant, - int32x4_t *add_lo, int32x4_t *add_hi, int32x4_t *sub_lo, - int32x4_t *sub_hi) { - int32x4_t c = vdupq_n_s32(constant << 17); - const int16x4_t a_lo = vget_low_s16(a); - const int16x4_t a_hi = vget_high_s16(a); - const int16x4_t b_lo = vget_low_s16(b); - const int16x4_t b_hi = vget_high_s16(b); - *add_lo = vqrdmulhq_s32(vaddl_s16(a_lo, b_lo), c); - *add_hi = vqrdmulhq_s32(vaddl_s16(a_hi, b_hi), c); - *sub_lo = vqrdmulhq_s32(vsubl_s16(a_lo, b_lo), c); - *sub_hi = vqrdmulhq_s32(vsubl_s16(a_hi, b_hi), c); -} - -// fdct_round_shift((a +/- b) * c) -// Variant that performs fast vqrdmulhq_s32 operation on full vector -// more accurate does 32-bit processing, takes 16-bit input values, -// returns full 32-bit values, high/low -static INLINE void butterfly_one_coeff_s16_s32_fast_narrow( - const int16x8_t a, const int16x8_t b, const tran_coef_t constant, - int16x8_t *add, int16x8_t *sub) { - int32x4_t add_lo, add_hi, sub_lo, sub_hi; - butterfly_one_coeff_s16_s32_fast(a, b, constant, &add_lo, &add_hi, &sub_lo, - &sub_hi); - *add = vcombine_s16(vmovn_s32(add_lo), vmovn_s32(add_hi)); - *sub = vcombine_s16(vmovn_s32(sub_lo), vmovn_s32(sub_hi)); -} - -// fdct_round_shift((a +/- b) * c) -// Variant that performs fast vqrdmulhq_s32 operation on full vector -// more accurate does 32-bit processing, takes 16-bit input values, -// returns full 32-bit values, high/low -static INLINE void butterfly_one_coeff_s16_s32_fast_half( - const int16x4_t a, const int16x4_t b, const tran_coef_t constant, - int32x4_t *add, int32x4_t *sub) { - int32x4_t c = vdupq_n_s32(constant << 17); - *add = vqrdmulhq_s32(vaddl_s16(a, b), c); - *sub = vqrdmulhq_s32(vsubl_s16(a, b), c); -} - -// fdct_round_shift((a +/- b) * c) -// Variant that performs fast vqrdmulhq_s32 operation on half vector -// more accurate does 32-bit processing, takes 16-bit input values, -// returns narrowed down 16-bit values -static INLINE void butterfly_one_coeff_s16_s32_fast_narrow_half( - const int16x4_t a, const int16x4_t b, const tran_coef_t constant, - int16x4_t *add, int16x4_t *sub) { - int32x4_t add32, sub32; - butterfly_one_coeff_s16_s32_fast_half(a, b, constant, &add32, &sub32); - *add = vmovn_s32(add32); - *sub = vmovn_s32(sub32); -} - -// fdct_round_shift((a +/- b) * c) -// Original Variant that performs normal implementation on full vector -// fully accurate does 32-bit processing, takes 16-bit values -static INLINE void butterfly_one_coeff_s16_s32( - const int16x8_t a, const int16x8_t b, const tran_coef_t constant, - int32x4_t *add_lo, int32x4_t *add_hi, int32x4_t *sub_lo, - int32x4_t *sub_hi) { - const int32x4_t a0 = vmull_n_s16(vget_low_s16(a), constant); - const int32x4_t a1 = vmull_n_s16(vget_high_s16(a), constant); - const int32x4_t sum0 = vmlal_n_s16(a0, vget_low_s16(b), constant); - const int32x4_t sum1 = vmlal_n_s16(a1, vget_high_s16(b), constant); - const int32x4_t diff0 = vmlsl_n_s16(a0, vget_low_s16(b), constant); - const int32x4_t diff1 = vmlsl_n_s16(a1, vget_high_s16(b), constant); - *add_lo = vrshrq_n_s32(sum0, DCT_CONST_BITS); - *add_hi = vrshrq_n_s32(sum1, DCT_CONST_BITS); - *sub_lo = vrshrq_n_s32(diff0, DCT_CONST_BITS); - *sub_hi = vrshrq_n_s32(diff1, DCT_CONST_BITS); -} - -// fdct_round_shift((a +/- b) * c) -// Original Variant that performs normal implementation on full vector -// fully accurate does 32-bit processing, takes 16-bit values -// returns narrowed down 16-bit values -static INLINE void butterfly_one_coeff_s16_s32_narrow( - const int16x8_t a, const int16x8_t b, const tran_coef_t constant, - int16x8_t *add, int16x8_t *sub) { - int32x4_t add32_lo, add32_hi, sub32_lo, sub32_hi; - butterfly_one_coeff_s16_s32(a, b, constant, &add32_lo, &add32_hi, &sub32_lo, - &sub32_hi); - *add = vcombine_s16(vmovn_s32(add32_lo), vmovn_s32(add32_hi)); - *sub = vcombine_s16(vmovn_s32(sub32_lo), vmovn_s32(sub32_hi)); -} - -// fdct_round_shift((a +/- b) * c) -// Variant that performs fast vqrdmulhq_s32 operation on full vector -// more accurate does 32-bit processing, takes and returns 32-bit values, -// high/low -static INLINE void butterfly_one_coeff_s32_noround( - const int32x4_t a_lo, const int32x4_t a_hi, const int32x4_t b_lo, - const int32x4_t b_hi, const tran_coef_t constant, int32x4_t *add_lo, - int32x4_t *add_hi, int32x4_t *sub_lo, int32x4_t *sub_hi) { - const int32x4_t a1 = vmulq_n_s32(a_lo, constant); - const int32x4_t a2 = vmulq_n_s32(a_hi, constant); - const int32x4_t a3 = vmulq_n_s32(a_lo, constant); - const int32x4_t a4 = vmulq_n_s32(a_hi, constant); - *add_lo = vmlaq_n_s32(a1, b_lo, constant); - *add_hi = vmlaq_n_s32(a2, b_hi, constant); - *sub_lo = vmlsq_n_s32(a3, b_lo, constant); - *sub_hi = vmlsq_n_s32(a4, b_hi, constant); -} - -// fdct_round_shift((a +/- b) * c) -// Variant that performs fast vqrdmulhq_s32 operation on full vector -// more accurate does 32-bit processing, takes and returns 32-bit values, -// high/low -static INLINE void butterfly_one_coeff_s32_fast_half(const int32x4_t a, - const int32x4_t b, - const tran_coef_t constant, - int32x4_t *add, - int32x4_t *sub) { - const int32x4_t c = vdupq_n_s32(constant << 17); - *add = vqrdmulhq_s32(vaddq_s32(a, b), c); - *sub = vqrdmulhq_s32(vsubq_s32(a, b), c); -} - -// fdct_round_shift((a +/- b) * c) -// Variant that performs fast vqrdmulhq_s32 operation on full vector -// more accurate does 32-bit processing, takes and returns 32-bit values, -// high/low -static INLINE void butterfly_one_coeff_s32_fast( - const int32x4_t a_lo, const int32x4_t a_hi, const int32x4_t b_lo, - const int32x4_t b_hi, const tran_coef_t constant, int32x4_t *add_lo, - int32x4_t *add_hi, int32x4_t *sub_lo, int32x4_t *sub_hi) { - const int32x4_t c = vdupq_n_s32(constant << 17); - *add_lo = vqrdmulhq_s32(vaddq_s32(a_lo, b_lo), c); - *add_hi = vqrdmulhq_s32(vaddq_s32(a_hi, b_hi), c); - *sub_lo = vqrdmulhq_s32(vsubq_s32(a_lo, b_lo), c); - *sub_hi = vqrdmulhq_s32(vsubq_s32(a_hi, b_hi), c); -} - -// fdct_round_shift((a +/- b) * c) -// Variant that performs normal implementation on full vector -// more accurate does 64-bit processing, takes and returns 32-bit values -// returns narrowed results -static INLINE void butterfly_one_coeff_s32_s64_narrow( - const int32x4_t a_lo, const int32x4_t a_hi, const int32x4_t b_lo, - const int32x4_t b_hi, const tran_coef_t constant, int32x4_t *add_lo, - int32x4_t *add_hi, int32x4_t *sub_lo, int32x4_t *sub_hi) { - // ac holds the following values: - // ac: vget_low_s32(a_lo) * c, vget_high_s32(a_lo) * c, - // vget_low_s32(a_hi) * c, vget_high_s32(a_hi) * c - int64x2_t ac[4]; - int64x2_t sum[4]; - int64x2_t diff[4]; - - ac[0] = vmull_n_s32(vget_low_s32(a_lo), constant); - ac[1] = vmull_n_s32(vget_high_s32(a_lo), constant); - ac[2] = vmull_n_s32(vget_low_s32(a_hi), constant); - ac[3] = vmull_n_s32(vget_high_s32(a_hi), constant); - - sum[0] = vmlal_n_s32(ac[0], vget_low_s32(b_lo), constant); - sum[1] = vmlal_n_s32(ac[1], vget_high_s32(b_lo), constant); - sum[2] = vmlal_n_s32(ac[2], vget_low_s32(b_hi), constant); - sum[3] = vmlal_n_s32(ac[3], vget_high_s32(b_hi), constant); - *add_lo = vcombine_s32(vrshrn_n_s64(sum[0], DCT_CONST_BITS), - vrshrn_n_s64(sum[1], DCT_CONST_BITS)); - *add_hi = vcombine_s32(vrshrn_n_s64(sum[2], DCT_CONST_BITS), - vrshrn_n_s64(sum[3], DCT_CONST_BITS)); - - diff[0] = vmlsl_n_s32(ac[0], vget_low_s32(b_lo), constant); - diff[1] = vmlsl_n_s32(ac[1], vget_high_s32(b_lo), constant); - diff[2] = vmlsl_n_s32(ac[2], vget_low_s32(b_hi), constant); - diff[3] = vmlsl_n_s32(ac[3], vget_high_s32(b_hi), constant); - *sub_lo = vcombine_s32(vrshrn_n_s64(diff[0], DCT_CONST_BITS), - vrshrn_n_s64(diff[1], DCT_CONST_BITS)); - *sub_hi = vcombine_s32(vrshrn_n_s64(diff[2], DCT_CONST_BITS), - vrshrn_n_s64(diff[3], DCT_CONST_BITS)); -} - -// fdct_round_shift(a * c1 +/- b * c2) -// Variant that performs normal implementation on half vector -// more accurate does 64-bit processing, takes and returns 32-bit values -// returns narrowed results -static INLINE void butterfly_two_coeff_s32_s64_narrow_half( - const int32x4_t a, const int32x4_t b, const tran_coef_t constant1, - const tran_coef_t constant2, int32x4_t *add, int32x4_t *sub) { - const int32x2_t a_lo = vget_low_s32(a); - const int32x2_t a_hi = vget_high_s32(a); - const int32x2_t b_lo = vget_low_s32(b); - const int32x2_t b_hi = vget_high_s32(b); - - const int64x2_t axc0_64_lo = vmull_n_s32(a_lo, constant1); - const int64x2_t axc0_64_hi = vmull_n_s32(a_hi, constant1); - const int64x2_t axc1_64_lo = vmull_n_s32(a_lo, constant2); - const int64x2_t axc1_64_hi = vmull_n_s32(a_hi, constant2); - - const int64x2_t sum_lo = vmlal_n_s32(axc0_64_lo, b_lo, constant2); - const int64x2_t sum_hi = vmlal_n_s32(axc0_64_hi, b_hi, constant2); - const int64x2_t diff_lo = vmlsl_n_s32(axc1_64_lo, b_lo, constant1); - const int64x2_t diff_hi = vmlsl_n_s32(axc1_64_hi, b_hi, constant1); - - *add = vcombine_s32(vrshrn_n_s64(sum_lo, DCT_CONST_BITS), - vrshrn_n_s64(sum_hi, DCT_CONST_BITS)); - *sub = vcombine_s32(vrshrn_n_s64(diff_lo, DCT_CONST_BITS), - vrshrn_n_s64(diff_hi, DCT_CONST_BITS)); -} - -// fdct_round_shift(a * c1 +/- b * c2) -// Variant that performs normal implementation on full vector -// more accurate does 64-bit processing, takes and returns 64-bit values -// returns results without rounding -static INLINE void butterfly_two_coeff_s32_s64_noround( - const int32x4_t a_lo, const int32x4_t a_hi, const int32x4_t b_lo, - const int32x4_t b_hi, const tran_coef_t constant1, - const tran_coef_t constant2, int64x2_t *add_lo /*[2]*/, - int64x2_t *add_hi /*[2]*/, int64x2_t *sub_lo /*[2]*/, - int64x2_t *sub_hi /*[2]*/) { - // ac1/ac2 hold the following values: - // ac1: vget_low_s32(a_lo) * c1, vget_high_s32(a_lo) * c1, - // vget_low_s32(a_hi) * c1, vget_high_s32(a_hi) * c1 - // ac2: vget_low_s32(a_lo) * c2, vget_high_s32(a_lo) * c2, - // vget_low_s32(a_hi) * c2, vget_high_s32(a_hi) * c2 - int64x2_t ac1[4]; - int64x2_t ac2[4]; - - ac1[0] = vmull_n_s32(vget_low_s32(a_lo), constant1); - ac1[1] = vmull_n_s32(vget_high_s32(a_lo), constant1); - ac1[2] = vmull_n_s32(vget_low_s32(a_hi), constant1); - ac1[3] = vmull_n_s32(vget_high_s32(a_hi), constant1); - ac2[0] = vmull_n_s32(vget_low_s32(a_lo), constant2); - ac2[1] = vmull_n_s32(vget_high_s32(a_lo), constant2); - ac2[2] = vmull_n_s32(vget_low_s32(a_hi), constant2); - ac2[3] = vmull_n_s32(vget_high_s32(a_hi), constant2); - - add_lo[0] = vmlal_n_s32(ac1[0], vget_low_s32(b_lo), constant2); - add_lo[1] = vmlal_n_s32(ac1[1], vget_high_s32(b_lo), constant2); - add_hi[0] = vmlal_n_s32(ac1[2], vget_low_s32(b_hi), constant2); - add_hi[1] = vmlal_n_s32(ac1[3], vget_high_s32(b_hi), constant2); - - sub_lo[0] = vmlsl_n_s32(ac2[0], vget_low_s32(b_lo), constant1); - sub_lo[1] = vmlsl_n_s32(ac2[1], vget_high_s32(b_lo), constant1); - sub_hi[0] = vmlsl_n_s32(ac2[2], vget_low_s32(b_hi), constant1); - sub_hi[1] = vmlsl_n_s32(ac2[3], vget_high_s32(b_hi), constant1); -} - -// fdct_round_shift(a * c1 +/- b * c2) -// Variant that performs normal implementation on full vector -// more accurate does 64-bit processing, takes and returns 32-bit values -// returns narrowed results -static INLINE void butterfly_two_coeff_s32_s64_narrow( - const int32x4_t a_lo, const int32x4_t a_hi, const int32x4_t b_lo, - const int32x4_t b_hi, const tran_coef_t constant1, - const tran_coef_t constant2, int32x4_t *add_lo, int32x4_t *add_hi, - int32x4_t *sub_lo, int32x4_t *sub_hi) { - // ac1/ac2 hold the following values: - // ac1: vget_low_s32(a_lo) * c1, vget_high_s32(a_lo) * c1, - // vget_low_s32(a_hi) * c1, vget_high_s32(a_hi) * c1 - // ac2: vget_low_s32(a_lo) * c2, vget_high_s32(a_lo) * c2, - // vget_low_s32(a_hi) * c2, vget_high_s32(a_hi) * c2 - int64x2_t ac1[4]; - int64x2_t ac2[4]; - int64x2_t sum[4]; - int64x2_t diff[4]; - - ac1[0] = vmull_n_s32(vget_low_s32(a_lo), constant1); - ac1[1] = vmull_n_s32(vget_high_s32(a_lo), constant1); - ac1[2] = vmull_n_s32(vget_low_s32(a_hi), constant1); - ac1[3] = vmull_n_s32(vget_high_s32(a_hi), constant1); - ac2[0] = vmull_n_s32(vget_low_s32(a_lo), constant2); - ac2[1] = vmull_n_s32(vget_high_s32(a_lo), constant2); - ac2[2] = vmull_n_s32(vget_low_s32(a_hi), constant2); - ac2[3] = vmull_n_s32(vget_high_s32(a_hi), constant2); - - sum[0] = vmlal_n_s32(ac1[0], vget_low_s32(b_lo), constant2); - sum[1] = vmlal_n_s32(ac1[1], vget_high_s32(b_lo), constant2); - sum[2] = vmlal_n_s32(ac1[2], vget_low_s32(b_hi), constant2); - sum[3] = vmlal_n_s32(ac1[3], vget_high_s32(b_hi), constant2); - *add_lo = vcombine_s32(vrshrn_n_s64(sum[0], DCT_CONST_BITS), - vrshrn_n_s64(sum[1], DCT_CONST_BITS)); - *add_hi = vcombine_s32(vrshrn_n_s64(sum[2], DCT_CONST_BITS), - vrshrn_n_s64(sum[3], DCT_CONST_BITS)); - - diff[0] = vmlsl_n_s32(ac2[0], vget_low_s32(b_lo), constant1); - diff[1] = vmlsl_n_s32(ac2[1], vget_high_s32(b_lo), constant1); - diff[2] = vmlsl_n_s32(ac2[2], vget_low_s32(b_hi), constant1); - diff[3] = vmlsl_n_s32(ac2[3], vget_high_s32(b_hi), constant1); - *sub_lo = vcombine_s32(vrshrn_n_s64(diff[0], DCT_CONST_BITS), - vrshrn_n_s64(diff[1], DCT_CONST_BITS)); - *sub_hi = vcombine_s32(vrshrn_n_s64(diff[2], DCT_CONST_BITS), - vrshrn_n_s64(diff[3], DCT_CONST_BITS)); -} - -// fdct_round_shift(a * c1 +/- b * c2) -// Original Variant that performs normal implementation on full vector -// more accurate does 32-bit processing, takes and returns 32-bit values -// returns narrowed results -static INLINE void butterfly_two_coeff_s16_s32_noround( - const int16x4_t a_lo, const int16x4_t a_hi, const int16x4_t b_lo, - const int16x4_t b_hi, const tran_coef_t constant1, - const tran_coef_t constant2, int32x4_t *add_lo, int32x4_t *add_hi, - int32x4_t *sub_lo, int32x4_t *sub_hi) { - const int32x4_t a1 = vmull_n_s16(a_lo, constant1); - const int32x4_t a2 = vmull_n_s16(a_hi, constant1); - const int32x4_t a3 = vmull_n_s16(a_lo, constant2); - const int32x4_t a4 = vmull_n_s16(a_hi, constant2); - *add_lo = vmlal_n_s16(a1, b_lo, constant2); - *add_hi = vmlal_n_s16(a2, b_hi, constant2); - *sub_lo = vmlsl_n_s16(a3, b_lo, constant1); - *sub_hi = vmlsl_n_s16(a4, b_hi, constant1); -} - -// fdct_round_shift(a * c1 +/- b * c2) -// Original Variant that performs normal implementation on full vector -// more accurate does 32-bit processing, takes and returns 32-bit values -// returns narrowed results -static INLINE void butterfly_two_coeff_s32_noround( - const int32x4_t a_lo, const int32x4_t a_hi, const int32x4_t b_lo, - const int32x4_t b_hi, const tran_coef_t constant1, - const tran_coef_t constant2, int32x4_t *add_lo, int32x4_t *add_hi, - int32x4_t *sub_lo, int32x4_t *sub_hi) { - const int32x4_t a1 = vmulq_n_s32(a_lo, constant1); - const int32x4_t a2 = vmulq_n_s32(a_hi, constant1); - const int32x4_t a3 = vmulq_n_s32(a_lo, constant2); - const int32x4_t a4 = vmulq_n_s32(a_hi, constant2); - *add_lo = vmlaq_n_s32(a1, b_lo, constant2); - *add_hi = vmlaq_n_s32(a2, b_hi, constant2); - *sub_lo = vmlsq_n_s32(a3, b_lo, constant1); - *sub_hi = vmlsq_n_s32(a4, b_hi, constant1); -} - -// fdct_round_shift(a * c1 +/- b * c2) -// Variant that performs normal implementation on half vector -// more accurate does 32-bit processing, takes and returns 16-bit values -// returns narrowed results -static INLINE void butterfly_two_coeff_half(const int16x4_t a, - const int16x4_t b, - const tran_coef_t constant1, - const tran_coef_t constant2, - int16x4_t *add, int16x4_t *sub) { - const int32x4_t a1 = vmull_n_s16(a, constant1); - const int32x4_t a2 = vmull_n_s16(a, constant2); - const int32x4_t sum = vmlal_n_s16(a1, b, constant2); - const int32x4_t diff = vmlsl_n_s16(a2, b, constant1); - *add = vqrshrn_n_s32(sum, DCT_CONST_BITS); - *sub = vqrshrn_n_s32(diff, DCT_CONST_BITS); -} - -// fdct_round_shift(a * c1 +/- b * c2) -// Original Variant that performs normal implementation on full vector -// more accurate does 32-bit processing, takes and returns 16-bit values -// returns narrowed results -static INLINE void butterfly_two_coeff(const int16x8_t a, const int16x8_t b, - const tran_coef_t constant1, - const tran_coef_t constant2, - int16x8_t *add, int16x8_t *sub) { - const int32x4_t a1 = vmull_n_s16(vget_low_s16(a), constant1); - const int32x4_t a2 = vmull_n_s16(vget_high_s16(a), constant1); - const int32x4_t a3 = vmull_n_s16(vget_low_s16(a), constant2); - const int32x4_t a4 = vmull_n_s16(vget_high_s16(a), constant2); - const int32x4_t sum0 = vmlal_n_s16(a1, vget_low_s16(b), constant2); - const int32x4_t sum1 = vmlal_n_s16(a2, vget_high_s16(b), constant2); - const int32x4_t diff0 = vmlsl_n_s16(a3, vget_low_s16(b), constant1); - const int32x4_t diff1 = vmlsl_n_s16(a4, vget_high_s16(b), constant1); - const int16x4_t rounded0 = vqrshrn_n_s32(sum0, DCT_CONST_BITS); - const int16x4_t rounded1 = vqrshrn_n_s32(sum1, DCT_CONST_BITS); - const int16x4_t rounded2 = vqrshrn_n_s32(diff0, DCT_CONST_BITS); - const int16x4_t rounded3 = vqrshrn_n_s32(diff1, DCT_CONST_BITS); - *add = vcombine_s16(rounded0, rounded1); - *sub = vcombine_s16(rounded2, rounded3); -} - -// fdct_round_shift(a * c1 +/- b * c2) -// Original Variant that performs normal implementation on full vector -// more accurate does 32-bit processing, takes and returns 32-bit values -// returns narrowed results -static INLINE void butterfly_two_coeff_s32( - const int32x4_t a_lo, const int32x4_t a_hi, const int32x4_t b_lo, - const int32x4_t b_hi, const tran_coef_t constant1, - const tran_coef_t constant2, int32x4_t *add_lo, int32x4_t *add_hi, - int32x4_t *sub_lo, int32x4_t *sub_hi) { - const int32x4_t a1 = vmulq_n_s32(a_lo, constant1); - const int32x4_t a2 = vmulq_n_s32(a_hi, constant1); - const int32x4_t a3 = vmulq_n_s32(a_lo, constant2); - const int32x4_t a4 = vmulq_n_s32(a_hi, constant2); - const int32x4_t sum0 = vmlaq_n_s32(a1, b_lo, constant2); - const int32x4_t sum1 = vmlaq_n_s32(a2, b_hi, constant2); - const int32x4_t diff0 = vmlsq_n_s32(a3, b_lo, constant1); - const int32x4_t diff1 = vmlsq_n_s32(a4, b_hi, constant1); - *add_lo = vrshrq_n_s32(sum0, DCT_CONST_BITS); - *add_hi = vrshrq_n_s32(sum1, DCT_CONST_BITS); - *sub_lo = vrshrq_n_s32(diff0, DCT_CONST_BITS); - *sub_hi = vrshrq_n_s32(diff1, DCT_CONST_BITS); -} - -// Add 1 if positive, 2 if negative, and shift by 2. -// In practice, add 1, then add the sign bit, then shift without rounding. -static INLINE int16x8_t add_round_shift_s16(const int16x8_t a) { - const int16x8_t one = vdupq_n_s16(1); - const uint16x8_t a_u16 = vreinterpretq_u16_s16(a); - const uint16x8_t a_sign_u16 = vshrq_n_u16(a_u16, 15); - const int16x8_t a_sign_s16 = vreinterpretq_s16_u16(a_sign_u16); - return vshrq_n_s16(vaddq_s16(vaddq_s16(a, a_sign_s16), one), 2); -} - -// Add 1 if positive, 2 if negative, and shift by 2. -// In practice, add 1, then add the sign bit, then shift and round, -// return narrowed results -static INLINE int16x8_t add_round_shift_s32_narrow(const int32x4_t a_lo, - const int32x4_t a_hi) { - const int32x4_t one = vdupq_n_s32(1); - const uint32x4_t a_lo_u32 = vreinterpretq_u32_s32(a_lo); - const uint32x4_t a_lo_sign_u32 = vshrq_n_u32(a_lo_u32, 31); - const int32x4_t a_lo_sign_s32 = vreinterpretq_s32_u32(a_lo_sign_u32); - const int16x4_t b_lo = - vshrn_n_s32(vqaddq_s32(vqaddq_s32(a_lo, a_lo_sign_s32), one), 2); - const uint32x4_t a_hi_u32 = vreinterpretq_u32_s32(a_hi); - const uint32x4_t a_hi_sign_u32 = vshrq_n_u32(a_hi_u32, 31); - const int32x4_t a_hi_sign_s32 = vreinterpretq_s32_u32(a_hi_sign_u32); - const int16x4_t b_hi = - vshrn_n_s32(vqaddq_s32(vqaddq_s32(a_hi, a_hi_sign_s32), one), 2); - return vcombine_s16(b_lo, b_hi); -} - -// Add 1 if negative, and shift by 1. -// In practice, add the sign bit, then shift and round -static INLINE int32x4_t add_round_shift_half_s32(const int32x4_t a) { - const uint32x4_t a_u32 = vreinterpretq_u32_s32(a); - const uint32x4_t a_sign_u32 = vshrq_n_u32(a_u32, 31); - const int32x4_t a_sign_s32 = vreinterpretq_s32_u32(a_sign_u32); - return vshrq_n_s32(vaddq_s32(a, a_sign_s32), 1); -} - -// Add 1 if positive, 2 if negative, and shift by 2. -// In practice, add 1, then add the sign bit, then shift without rounding. -static INLINE int32x4_t add_round_shift_s32(const int32x4_t a) { - const int32x4_t one = vdupq_n_s32(1); - const uint32x4_t a_u32 = vreinterpretq_u32_s32(a); - const uint32x4_t a_sign_u32 = vshrq_n_u32(a_u32, 31); - const int32x4_t a_sign_s32 = vreinterpretq_s32_u32(a_sign_u32); - return vshrq_n_s32(vaddq_s32(vaddq_s32(a, a_sign_s32), one), 2); -} - -// Add 2 if positive, 1 if negative, and shift by 2. -// In practice, subtract the sign bit, then shift with rounding. -static INLINE int16x8_t sub_round_shift_s16(const int16x8_t a) { - const uint16x8_t a_u16 = vreinterpretq_u16_s16(a); - const uint16x8_t a_sign_u16 = vshrq_n_u16(a_u16, 15); - const int16x8_t a_sign_s16 = vreinterpretq_s16_u16(a_sign_u16); - return vrshrq_n_s16(vsubq_s16(a, a_sign_s16), 2); -} - -// Add 2 if positive, 1 if negative, and shift by 2. -// In practice, subtract the sign bit, then shift with rounding. -static INLINE int32x4_t sub_round_shift_s32(const int32x4_t a) { - const uint32x4_t a_u32 = vreinterpretq_u32_s32(a); - const uint32x4_t a_sign_u32 = vshrq_n_u32(a_u32, 31); - const int32x4_t a_sign_s32 = vreinterpretq_s32_u32(a_sign_u32); - return vrshrq_n_s32(vsubq_s32(a, a_sign_s32), 2); -} - -static INLINE int32x4_t add_s64_round_narrow(const int64x2_t *a /*[2]*/, - const int64x2_t *b /*[2]*/) { - int64x2_t result[2]; - result[0] = vaddq_s64(a[0], b[0]); - result[1] = vaddq_s64(a[1], b[1]); - return vcombine_s32(vrshrn_n_s64(result[0], DCT_CONST_BITS), - vrshrn_n_s64(result[1], DCT_CONST_BITS)); -} - -static INLINE int32x4_t sub_s64_round_narrow(const int64x2_t *a /*[2]*/, - const int64x2_t *b /*[2]*/) { - int64x2_t result[2]; - result[0] = vsubq_s64(a[0], b[0]); - result[1] = vsubq_s64(a[1], b[1]); - return vcombine_s32(vrshrn_n_s64(result[0], DCT_CONST_BITS), - vrshrn_n_s64(result[1], DCT_CONST_BITS)); -} - -static INLINE int32x4_t add_s32_s64_narrow(const int32x4_t a, - const int32x4_t b) { - int64x2_t a64[2], b64[2], result[2]; - a64[0] = vmovl_s32(vget_low_s32(a)); - a64[1] = vmovl_s32(vget_high_s32(a)); - b64[0] = vmovl_s32(vget_low_s32(b)); - b64[1] = vmovl_s32(vget_high_s32(b)); - result[0] = vaddq_s64(a64[0], b64[0]); - result[1] = vaddq_s64(a64[1], b64[1]); - return vcombine_s32(vmovn_s64(result[0]), vmovn_s64(result[1])); -} - -static INLINE int32x4_t sub_s32_s64_narrow(const int32x4_t a, - const int32x4_t b) { - int64x2_t a64[2], b64[2], result[2]; - a64[0] = vmovl_s32(vget_low_s32(a)); - a64[1] = vmovl_s32(vget_high_s32(a)); - b64[0] = vmovl_s32(vget_low_s32(b)); - b64[1] = vmovl_s32(vget_high_s32(b)); - result[0] = vsubq_s64(a64[0], b64[0]); - result[1] = vsubq_s64(a64[1], b64[1]); - return vcombine_s32(vmovn_s64(result[0]), vmovn_s64(result[1])); -} - -#endif // VPX_VPX_DSP_ARM_FDCT_NEON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct_partial_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct_partial_neon.c deleted file mode 100644 index df0da543..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/fdct_partial_neon.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "./vpx_config.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" - -void vpx_fdct4x4_1_neon(const int16_t *input, tran_low_t *output, int stride) { - int16x4_t a0, a1, a2, a3; - int16x8_t b0, b1; - int16x8_t c; - - a0 = vld1_s16(input); - input += stride; - a1 = vld1_s16(input); - input += stride; - a2 = vld1_s16(input); - input += stride; - a3 = vld1_s16(input); - - b0 = vcombine_s16(a0, a1); - b1 = vcombine_s16(a2, a3); - - c = vaddq_s16(b0, b1); - - output[0] = (tran_low_t)(horizontal_add_int16x8(c) << 1); - output[1] = 0; -} - -// Visual Studio 2022 (cl.exe) targeting AArch64 with optimizations enabled -// will fail with an internal compiler error. -// See: -// https://developercommunity.visualstudio.com/t/Compiler-crash-C1001-when-building-a-for/10346110 -// TODO(jzern): check the compiler version after a fix for the issue is -// released. -#if defined(_MSC_VER) && defined(_M_ARM64) && !defined(__clang__) -#pragma optimize("", off) -#endif -void vpx_fdct8x8_1_neon(const int16_t *input, tran_low_t *output, int stride) { - int r; - int16x8_t sum = vld1q_s16(&input[0]); - - for (r = 1; r < 8; ++r) { - const int16x8_t input_00 = vld1q_s16(&input[r * stride]); - sum = vaddq_s16(sum, input_00); - } - - output[0] = (tran_low_t)horizontal_add_int16x8(sum); - output[1] = 0; -} -#if defined(_MSC_VER) && defined(_M_ARM64) && !defined(__clang__) -#pragma optimize("", on) -#endif - -void vpx_fdct16x16_1_neon(const int16_t *input, tran_low_t *output, - int stride) { - int r; - int16x8_t left = vld1q_s16(input); - int16x8_t right = vld1q_s16(input + 8); - int32_t sum; - input += stride; - - for (r = 1; r < 16; ++r) { - const int16x8_t a = vld1q_s16(input); - const int16x8_t b = vld1q_s16(input + 8); - input += stride; - left = vaddq_s16(left, a); - right = vaddq_s16(right, b); - } - - sum = horizontal_add_int16x8(left) + horizontal_add_int16x8(right); - - output[0] = (tran_low_t)(sum >> 1); - output[1] = 0; -} - -void vpx_fdct32x32_1_neon(const int16_t *input, tran_low_t *output, - int stride) { - int r; - int16x8_t a0 = vld1q_s16(input); - int16x8_t a1 = vld1q_s16(input + 8); - int16x8_t a2 = vld1q_s16(input + 16); - int16x8_t a3 = vld1q_s16(input + 24); - int32_t sum; - input += stride; - - for (r = 1; r < 32; ++r) { - const int16x8_t b0 = vld1q_s16(input); - const int16x8_t b1 = vld1q_s16(input + 8); - const int16x8_t b2 = vld1q_s16(input + 16); - const int16x8_t b3 = vld1q_s16(input + 24); - input += stride; - a0 = vaddq_s16(a0, b0); - a1 = vaddq_s16(a1, b1); - a2 = vaddq_s16(a2, b2); - a3 = vaddq_s16(a3, b3); - } - - sum = horizontal_add_int16x8(a0); - sum += horizontal_add_int16x8(a1); - sum += horizontal_add_int16x8(a2); - sum += horizontal_add_int16x8(a3); - output[0] = (tran_low_t)(sum >> 3); - output[1] = 0; -} - -#if CONFIG_VP9_HIGHBITDEPTH - -void vpx_highbd_fdct16x16_1_neon(const int16_t *input, tran_low_t *output, - int stride) { - int32x4_t partial_sum[4] = { vdupq_n_s32(0), vdupq_n_s32(0), vdupq_n_s32(0), - vdupq_n_s32(0) }; - int32_t sum; - - int r = 0; - do { - const int16x8_t a = vld1q_s16(input); - const int16x8_t b = vld1q_s16(input + 8); - input += stride; - partial_sum[0] = vaddw_s16(partial_sum[0], vget_low_s16(a)); - partial_sum[1] = vaddw_s16(partial_sum[1], vget_high_s16(a)); - partial_sum[2] = vaddw_s16(partial_sum[2], vget_low_s16(b)); - partial_sum[3] = vaddw_s16(partial_sum[3], vget_high_s16(b)); - r++; - } while (r < 16); - - partial_sum[0] = vaddq_s32(partial_sum[0], partial_sum[1]); - partial_sum[2] = vaddq_s32(partial_sum[2], partial_sum[3]); - partial_sum[0] = vaddq_s32(partial_sum[0], partial_sum[2]); - sum = horizontal_add_int32x4(partial_sum[0]); - - output[0] = (tran_low_t)(sum >> 1); - output[1] = 0; -} - -void vpx_highbd_fdct32x32_1_neon(const int16_t *input, tran_low_t *output, - int stride) { - int32x4_t partial_sum[4] = { vdupq_n_s32(0), vdupq_n_s32(0), vdupq_n_s32(0), - vdupq_n_s32(0) }; - - int32_t sum; - - int r = 0; - do { - const int16x8_t a0 = vld1q_s16(input); - const int16x8_t a1 = vld1q_s16(input + 8); - const int16x8_t a2 = vld1q_s16(input + 16); - const int16x8_t a3 = vld1q_s16(input + 24); - input += stride; - partial_sum[0] = vaddw_s16(partial_sum[0], vget_low_s16(a0)); - partial_sum[0] = vaddw_s16(partial_sum[0], vget_high_s16(a0)); - partial_sum[1] = vaddw_s16(partial_sum[1], vget_low_s16(a1)); - partial_sum[1] = vaddw_s16(partial_sum[1], vget_high_s16(a1)); - partial_sum[2] = vaddw_s16(partial_sum[2], vget_low_s16(a2)); - partial_sum[2] = vaddw_s16(partial_sum[2], vget_high_s16(a2)); - partial_sum[3] = vaddw_s16(partial_sum[3], vget_low_s16(a3)); - partial_sum[3] = vaddw_s16(partial_sum[3], vget_high_s16(a3)); - r++; - } while (r < 32); - - partial_sum[0] = vaddq_s32(partial_sum[0], partial_sum[1]); - partial_sum[2] = vaddq_s32(partial_sum[2], partial_sum[3]); - partial_sum[0] = vaddq_s32(partial_sum[0], partial_sum[2]); - sum = horizontal_add_int32x4(partial_sum[0]); - - output[0] = (tran_low_t)(sum >> 3); - output[1] = 0; -} - -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/hadamard_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/hadamard_neon.c deleted file mode 100644 index f5a044be..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/hadamard_neon.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" - -static void hadamard8x8_one_pass(int16x8_t *a0, int16x8_t *a1, int16x8_t *a2, - int16x8_t *a3, int16x8_t *a4, int16x8_t *a5, - int16x8_t *a6, int16x8_t *a7) { - const int16x8_t b0 = vaddq_s16(*a0, *a1); - const int16x8_t b1 = vsubq_s16(*a0, *a1); - const int16x8_t b2 = vaddq_s16(*a2, *a3); - const int16x8_t b3 = vsubq_s16(*a2, *a3); - const int16x8_t b4 = vaddq_s16(*a4, *a5); - const int16x8_t b5 = vsubq_s16(*a4, *a5); - const int16x8_t b6 = vaddq_s16(*a6, *a7); - const int16x8_t b7 = vsubq_s16(*a6, *a7); - - const int16x8_t c0 = vaddq_s16(b0, b2); - const int16x8_t c1 = vaddq_s16(b1, b3); - const int16x8_t c2 = vsubq_s16(b0, b2); - const int16x8_t c3 = vsubq_s16(b1, b3); - const int16x8_t c4 = vaddq_s16(b4, b6); - const int16x8_t c5 = vaddq_s16(b5, b7); - const int16x8_t c6 = vsubq_s16(b4, b6); - const int16x8_t c7 = vsubq_s16(b5, b7); - - *a0 = vaddq_s16(c0, c4); - *a1 = vsubq_s16(c2, c6); - *a2 = vsubq_s16(c0, c4); - *a3 = vaddq_s16(c2, c6); - *a4 = vaddq_s16(c3, c7); - *a5 = vsubq_s16(c3, c7); - *a6 = vsubq_s16(c1, c5); - *a7 = vaddq_s16(c1, c5); -} - -void vpx_hadamard_8x8_neon(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { - int16x8_t a0 = vld1q_s16(src_diff); - int16x8_t a1 = vld1q_s16(src_diff + src_stride); - int16x8_t a2 = vld1q_s16(src_diff + 2 * src_stride); - int16x8_t a3 = vld1q_s16(src_diff + 3 * src_stride); - int16x8_t a4 = vld1q_s16(src_diff + 4 * src_stride); - int16x8_t a5 = vld1q_s16(src_diff + 5 * src_stride); - int16x8_t a6 = vld1q_s16(src_diff + 6 * src_stride); - int16x8_t a7 = vld1q_s16(src_diff + 7 * src_stride); - - hadamard8x8_one_pass(&a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7); - - transpose_s16_8x8(&a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7); - - hadamard8x8_one_pass(&a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7); - - // Skip the second transpose because it is not required. - - store_s16q_to_tran_low(coeff + 0, a0); - store_s16q_to_tran_low(coeff + 8, a1); - store_s16q_to_tran_low(coeff + 16, a2); - store_s16q_to_tran_low(coeff + 24, a3); - store_s16q_to_tran_low(coeff + 32, a4); - store_s16q_to_tran_low(coeff + 40, a5); - store_s16q_to_tran_low(coeff + 48, a6); - store_s16q_to_tran_low(coeff + 56, a7); -} - -void vpx_hadamard_16x16_neon(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { - int i; - - /* Rearrange 16x16 to 8x32 and remove stride. - * Top left first. */ - vpx_hadamard_8x8_neon(src_diff + 0 + 0 * src_stride, src_stride, coeff + 0); - /* Top right. */ - vpx_hadamard_8x8_neon(src_diff + 8 + 0 * src_stride, src_stride, coeff + 64); - /* Bottom left. */ - vpx_hadamard_8x8_neon(src_diff + 0 + 8 * src_stride, src_stride, coeff + 128); - /* Bottom right. */ - vpx_hadamard_8x8_neon(src_diff + 8 + 8 * src_stride, src_stride, coeff + 192); - - for (i = 0; i < 64; i += 8) { - const int16x8_t a0 = load_tran_low_to_s16q(coeff + 0); - const int16x8_t a1 = load_tran_low_to_s16q(coeff + 64); - const int16x8_t a2 = load_tran_low_to_s16q(coeff + 128); - const int16x8_t a3 = load_tran_low_to_s16q(coeff + 192); - - const int16x8_t b0 = vhaddq_s16(a0, a1); - const int16x8_t b1 = vhsubq_s16(a0, a1); - const int16x8_t b2 = vhaddq_s16(a2, a3); - const int16x8_t b3 = vhsubq_s16(a2, a3); - - const int16x8_t c0 = vaddq_s16(b0, b2); - const int16x8_t c1 = vaddq_s16(b1, b3); - const int16x8_t c2 = vsubq_s16(b0, b2); - const int16x8_t c3 = vsubq_s16(b1, b3); - - store_s16q_to_tran_low(coeff + 0, c0); - store_s16q_to_tran_low(coeff + 64, c1); - store_s16q_to_tran_low(coeff + 128, c2); - store_s16q_to_tran_low(coeff + 192, c3); - - coeff += 8; - } -} - -void vpx_hadamard_32x32_neon(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { - int i; - - /* Rearrange 32x32 to 16x64 and remove stride. - * Top left first. */ - vpx_hadamard_16x16_neon(src_diff + 0 + 0 * src_stride, src_stride, coeff + 0); - /* Top right. */ - vpx_hadamard_16x16_neon(src_diff + 16 + 0 * src_stride, src_stride, - coeff + 256); - /* Bottom left. */ - vpx_hadamard_16x16_neon(src_diff + 0 + 16 * src_stride, src_stride, - coeff + 512); - /* Bottom right. */ - vpx_hadamard_16x16_neon(src_diff + 16 + 16 * src_stride, src_stride, - coeff + 768); - - for (i = 0; i < 256; i += 8) { - const int16x8_t a0 = load_tran_low_to_s16q(coeff + 0); - const int16x8_t a1 = load_tran_low_to_s16q(coeff + 256); - const int16x8_t a2 = load_tran_low_to_s16q(coeff + 512); - const int16x8_t a3 = load_tran_low_to_s16q(coeff + 768); - - const int16x8_t b0 = vshrq_n_s16(vhaddq_s16(a0, a1), 1); - const int16x8_t b1 = vshrq_n_s16(vhsubq_s16(a0, a1), 1); - const int16x8_t b2 = vshrq_n_s16(vhaddq_s16(a2, a3), 1); - const int16x8_t b3 = vshrq_n_s16(vhsubq_s16(a2, a3), 1); - - const int16x8_t c0 = vaddq_s16(b0, b2); - const int16x8_t c1 = vaddq_s16(b1, b3); - const int16x8_t c2 = vsubq_s16(b0, b2); - const int16x8_t c3 = vsubq_s16(b1, b3); - - store_s16q_to_tran_low(coeff + 0, c0); - store_s16q_to_tran_low(coeff + 256, c1); - store_s16q_to_tran_low(coeff + 512, c2); - store_s16q_to_tran_low(coeff + 768, c3); - - coeff += 8; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_avg_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_avg_neon.c deleted file mode 100644 index 4265596c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_avg_neon.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "./vpx_config.h" - -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" - -uint32_t vpx_highbd_avg_4x4_neon(const uint8_t *s8, int p) { - const uint16_t *a_ptr = CONVERT_TO_SHORTPTR(s8); - const uint16x8_t a0 = load_unaligned_u16q(a_ptr + 0 * p, p); - const uint16x8_t a1 = load_unaligned_u16q(a_ptr + 2 * p, p); - return (horizontal_add_uint16x8(vaddq_u16(a0, a1)) + (1 << 3)) >> 4; -} - -uint32_t vpx_highbd_avg_8x8_neon(const uint8_t *s8, int p) { - const uint16_t *a_ptr = CONVERT_TO_SHORTPTR(s8); - uint16x8_t sum, a0, a1, a2, a3, a4, a5, a6, a7; - - load_u16_8x8(a_ptr, p, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7); - - sum = vaddq_u16(a0, a1); - sum = vaddq_u16(sum, a2); - sum = vaddq_u16(sum, a3); - sum = vaddq_u16(sum, a4); - sum = vaddq_u16(sum, a5); - sum = vaddq_u16(sum, a6); - sum = vaddq_u16(sum, a7); - - return (horizontal_add_uint16x8(sum) + (1 << 5)) >> 6; -} - -// coeff: 32 bits, dynamic range [-2147483648, 2147483647]. -// length: value range {16, 64, 256, 1024}. -// satd: 42 bits, dynamic range [-2147483648 * 1024, 2147483647 * 1024] -int vpx_highbd_satd_neon(const tran_low_t *coeff, int length) { - int64x2_t sum_s64[2] = { vdupq_n_s64(0), vdupq_n_s64(0) }; - - do { - int32x4_t abs0, abs1; - const int32x4_t s0 = load_tran_low_to_s32q(coeff); - const int32x4_t s1 = load_tran_low_to_s32q(coeff + 4); - - abs0 = vabsq_s32(s0); - sum_s64[0] = vpadalq_s32(sum_s64[0], abs0); - abs1 = vabsq_s32(s1); - sum_s64[1] = vpadalq_s32(sum_s64[1], abs1); - - length -= 8; - coeff += 8; - } while (length != 0); - - return (int)horizontal_add_int64x2(vaddq_s64(sum_s64[0], sum_s64[1])); -} - -void vpx_highbd_minmax_8x8_neon(const uint8_t *s8, int p, const uint8_t *d8, - int dp, int *min, int *max) { - const uint16_t *a_ptr = CONVERT_TO_SHORTPTR(s8); - const uint16_t *b_ptr = CONVERT_TO_SHORTPTR(d8); - - const uint16x8_t a0 = vld1q_u16(a_ptr + 0 * p); - const uint16x8_t a1 = vld1q_u16(a_ptr + 1 * p); - const uint16x8_t a2 = vld1q_u16(a_ptr + 2 * p); - const uint16x8_t a3 = vld1q_u16(a_ptr + 3 * p); - const uint16x8_t a4 = vld1q_u16(a_ptr + 4 * p); - const uint16x8_t a5 = vld1q_u16(a_ptr + 5 * p); - const uint16x8_t a6 = vld1q_u16(a_ptr + 6 * p); - const uint16x8_t a7 = vld1q_u16(a_ptr + 7 * p); - - const uint16x8_t b0 = vld1q_u16(b_ptr + 0 * dp); - const uint16x8_t b1 = vld1q_u16(b_ptr + 1 * dp); - const uint16x8_t b2 = vld1q_u16(b_ptr + 2 * dp); - const uint16x8_t b3 = vld1q_u16(b_ptr + 3 * dp); - const uint16x8_t b4 = vld1q_u16(b_ptr + 4 * dp); - const uint16x8_t b5 = vld1q_u16(b_ptr + 5 * dp); - const uint16x8_t b6 = vld1q_u16(b_ptr + 6 * dp); - const uint16x8_t b7 = vld1q_u16(b_ptr + 7 * dp); - - const uint16x8_t abs_diff0 = vabdq_u16(a0, b0); - const uint16x8_t abs_diff1 = vabdq_u16(a1, b1); - const uint16x8_t abs_diff2 = vabdq_u16(a2, b2); - const uint16x8_t abs_diff3 = vabdq_u16(a3, b3); - const uint16x8_t abs_diff4 = vabdq_u16(a4, b4); - const uint16x8_t abs_diff5 = vabdq_u16(a5, b5); - const uint16x8_t abs_diff6 = vabdq_u16(a6, b6); - const uint16x8_t abs_diff7 = vabdq_u16(a7, b7); - - const uint16x8_t max01 = vmaxq_u16(abs_diff0, abs_diff1); - const uint16x8_t max23 = vmaxq_u16(abs_diff2, abs_diff3); - const uint16x8_t max45 = vmaxq_u16(abs_diff4, abs_diff5); - const uint16x8_t max67 = vmaxq_u16(abs_diff6, abs_diff7); - - const uint16x8_t max0123 = vmaxq_u16(max01, max23); - const uint16x8_t max4567 = vmaxq_u16(max45, max67); - const uint16x8_t max07 = vmaxq_u16(max0123, max4567); - - const uint16x8_t min01 = vminq_u16(abs_diff0, abs_diff1); - const uint16x8_t min23 = vminq_u16(abs_diff2, abs_diff3); - const uint16x8_t min45 = vminq_u16(abs_diff4, abs_diff5); - const uint16x8_t min67 = vminq_u16(abs_diff6, abs_diff7); - - const uint16x8_t min0123 = vminq_u16(min01, min23); - const uint16x8_t min4567 = vminq_u16(min45, min67); - const uint16x8_t min07 = vminq_u16(min0123, min4567); - -#if VPX_ARCH_AARCH64 - *min = *max = 0; // Clear high bits - *((uint16_t *)max) = vmaxvq_u16(max07); - *((uint16_t *)min) = vminvq_u16(min07); -#else - // Split into 64-bit vectors and execute pairwise min/max. - uint16x4_t ab_max = vmax_u16(vget_high_u16(max07), vget_low_u16(max07)); - uint16x4_t ab_min = vmin_u16(vget_high_u16(min07), vget_low_u16(min07)); - - // Enough runs of vpmax/min propagate the max/min values to every position. - ab_max = vpmax_u16(ab_max, ab_max); - ab_min = vpmin_u16(ab_min, ab_min); - - ab_max = vpmax_u16(ab_max, ab_max); - ab_min = vpmin_u16(ab_min, ab_min); - - ab_max = vpmax_u16(ab_max, ab_max); - ab_min = vpmin_u16(ab_min, ab_min); - - *min = *max = 0; // Clear high bits - // Store directly to avoid costly neon->gpr transfer. - vst1_lane_u16((uint16_t *)max, ab_max, 0); - vst1_lane_u16((uint16_t *)min, ab_min, 0); -#endif -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_avg_pred_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_avg_pred_neon.c deleted file mode 100644 index 3063acbb..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_avg_pred_neon.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "./vpx_config.h" - -void vpx_highbd_comp_avg_pred_neon(uint16_t *comp_pred, const uint16_t *pred, - int width, int height, const uint16_t *ref, - int ref_stride) { - int i = height; - if (width > 8) { - do { - int j = 0; - do { - const uint16x8_t p = vld1q_u16(pred + j); - const uint16x8_t r = vld1q_u16(ref + j); - - uint16x8_t avg = vrhaddq_u16(p, r); - vst1q_u16(comp_pred + j, avg); - - j += 8; - } while (j < width); - - comp_pred += width; - pred += width; - ref += ref_stride; - } while (--i != 0); - } else if (width == 8) { - do { - const uint16x8_t p = vld1q_u16(pred); - const uint16x8_t r = vld1q_u16(ref); - - uint16x8_t avg = vrhaddq_u16(p, r); - vst1q_u16(comp_pred, avg); - - comp_pred += width; - pred += width; - ref += ref_stride; - } while (--i != 0); - } else { - assert(width == 4); - do { - const uint16x4_t p = vld1_u16(pred); - const uint16x4_t r = vld1_u16(ref); - - uint16x4_t avg = vrhadd_u16(p, r); - vst1_u16(comp_pred, avg); - - comp_pred += width; - pred += width; - ref += ref_stride; - } while (--i != 0); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_convolve8_neon.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_convolve8_neon.h deleted file mode 100644 index ccc4a797..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_convolve8_neon.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2024 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_ARM_HIGHBD_CONVOLVE8_NEON_H_ -#define VPX_VPX_DSP_ARM_HIGHBD_CONVOLVE8_NEON_H_ - -#include - -static INLINE uint16x4_t highbd_convolve4_4_neon( - const int16x4_t s0, const int16x4_t s1, const int16x4_t s2, - const int16x4_t s3, const int16x4_t filters, const uint16x4_t max) { - int32x4_t sum = vmull_lane_s16(s0, filters, 0); - sum = vmlal_lane_s16(sum, s1, filters, 1); - sum = vmlal_lane_s16(sum, s2, filters, 2); - sum = vmlal_lane_s16(sum, s3, filters, 3); - - uint16x4_t res = vqrshrun_n_s32(sum, FILTER_BITS); - return vmin_u16(res, max); -} - -static INLINE uint16x8_t highbd_convolve4_8_neon( - const int16x8_t s0, const int16x8_t s1, const int16x8_t s2, - const int16x8_t s3, const int16x4_t filters, const uint16x8_t max) { - int32x4_t sum0 = vmull_lane_s16(vget_low_s16(s0), filters, 0); - sum0 = vmlal_lane_s16(sum0, vget_low_s16(s1), filters, 1); - sum0 = vmlal_lane_s16(sum0, vget_low_s16(s2), filters, 2); - sum0 = vmlal_lane_s16(sum0, vget_low_s16(s3), filters, 3); - - int32x4_t sum1 = vmull_lane_s16(vget_high_s16(s0), filters, 0); - sum1 = vmlal_lane_s16(sum1, vget_high_s16(s1), filters, 1); - sum1 = vmlal_lane_s16(sum1, vget_high_s16(s2), filters, 2); - sum1 = vmlal_lane_s16(sum1, vget_high_s16(s3), filters, 3); - - uint16x8_t res = vcombine_u16(vqrshrun_n_s32(sum0, FILTER_BITS), - vqrshrun_n_s32(sum1, FILTER_BITS)); - return vminq_u16(res, max); -} - -#endif // VPX_VPX_DSP_ARM_HIGHBD_CONVOLVE8_NEON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_convolve8_sve.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_convolve8_sve.h deleted file mode 100644 index bc90d9b4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_convolve8_sve.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2024 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_ARM_HIGHBD_CONVOLVE8_SVE_H_ -#define VPX_VPX_DSP_ARM_HIGHBD_CONVOLVE8_SVE_H_ - -#include - -#include "vpx_dsp/arm/vpx_neon_sve_bridge.h" - -static INLINE uint16x4_t highbd_convolve4_4_sve(const int16x4_t s[4], - const int16x8_t filter, - const uint16x4_t max) { - int16x8_t s01 = vcombine_s16(s[0], s[1]); - int16x8_t s23 = vcombine_s16(s[2], s[3]); - - int64x2_t sum01 = vpx_dotq_lane_s16(vdupq_n_s64(0), s01, filter, 0); - int64x2_t sum23 = vpx_dotq_lane_s16(vdupq_n_s64(0), s23, filter, 0); - - int32x4_t res_s32 = vcombine_s32(vmovn_s64(sum01), vmovn_s64(sum23)); - - uint16x4_t res_u16 = vqrshrun_n_s32(res_s32, FILTER_BITS); - return vmin_u16(res_u16, max); -} - -static INLINE uint16x8_t highbd_convolve4_8_sve(const int16x8_t s[4], - const int16x8_t filter, - const uint16x8_t max, - uint16x8_t idx) { - int64x2_t sum04 = vpx_dotq_lane_s16(vdupq_n_s64(0), s[0], filter, 0); - int64x2_t sum15 = vpx_dotq_lane_s16(vdupq_n_s64(0), s[1], filter, 0); - int64x2_t sum26 = vpx_dotq_lane_s16(vdupq_n_s64(0), s[2], filter, 0); - int64x2_t sum37 = vpx_dotq_lane_s16(vdupq_n_s64(0), s[3], filter, 0); - - int32x4_t res0 = vcombine_s32(vmovn_s64(sum04), vmovn_s64(sum15)); - int32x4_t res1 = vcombine_s32(vmovn_s64(sum26), vmovn_s64(sum37)); - - uint16x8_t res = vcombine_u16(vqrshrun_n_s32(res0, FILTER_BITS), - vqrshrun_n_s32(res1, FILTER_BITS)); - - res = vpx_tbl_u16(res, idx); - - return vminq_u16(res, max); -} - -static INLINE uint16x4_t highbd_convolve8_4(const int16x8_t s[4], - const int16x8_t filter, - const uint16x4_t max) { - int64x2_t sum[4]; - - sum[0] = vpx_dotq_s16(vdupq_n_s64(0), s[0], filter); - sum[1] = vpx_dotq_s16(vdupq_n_s64(0), s[1], filter); - sum[2] = vpx_dotq_s16(vdupq_n_s64(0), s[2], filter); - sum[3] = vpx_dotq_s16(vdupq_n_s64(0), s[3], filter); - - sum[0] = vpaddq_s64(sum[0], sum[1]); - sum[2] = vpaddq_s64(sum[2], sum[3]); - - int32x4_t res_s32 = vcombine_s32(vmovn_s64(sum[0]), vmovn_s64(sum[2])); - - uint16x4_t res_u16 = vqrshrun_n_s32(res_s32, FILTER_BITS); - return vmin_u16(res_u16, max); -} - -static INLINE uint16x8_t highbd_convolve8_8(const int16x8_t s[8], - const int16x8_t filter, - const uint16x8_t max) { - int64x2_t sum[8]; - - sum[0] = vpx_dotq_s16(vdupq_n_s64(0), s[0], filter); - sum[1] = vpx_dotq_s16(vdupq_n_s64(0), s[1], filter); - sum[2] = vpx_dotq_s16(vdupq_n_s64(0), s[2], filter); - sum[3] = vpx_dotq_s16(vdupq_n_s64(0), s[3], filter); - sum[4] = vpx_dotq_s16(vdupq_n_s64(0), s[4], filter); - sum[5] = vpx_dotq_s16(vdupq_n_s64(0), s[5], filter); - sum[6] = vpx_dotq_s16(vdupq_n_s64(0), s[6], filter); - sum[7] = vpx_dotq_s16(vdupq_n_s64(0), s[7], filter); - - int64x2_t sum01 = vpaddq_s64(sum[0], sum[1]); - int64x2_t sum23 = vpaddq_s64(sum[2], sum[3]); - int64x2_t sum45 = vpaddq_s64(sum[4], sum[5]); - int64x2_t sum67 = vpaddq_s64(sum[6], sum[7]); - - int32x4_t res0 = vcombine_s32(vmovn_s64(sum01), vmovn_s64(sum23)); - int32x4_t res1 = vcombine_s32(vmovn_s64(sum45), vmovn_s64(sum67)); - - uint16x8_t res = vcombine_u16(vqrshrun_n_s32(res0, FILTER_BITS), - vqrshrun_n_s32(res1, FILTER_BITS)); - return vminq_u16(res, max); -} - -#endif // VPX_VPX_DSP_ARM_HIGHBD_CONVOLVE8_SVE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_hadamard_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_hadamard_neon.c deleted file mode 100644 index 7be88f6b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_hadamard_neon.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "./vpx_config.h" - -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" - -static INLINE void hadamard_highbd_col8_first_pass(int16x8_t *a0, int16x8_t *a1, - int16x8_t *a2, int16x8_t *a3, - int16x8_t *a4, int16x8_t *a5, - int16x8_t *a6, - int16x8_t *a7) { - int16x8_t b0 = vaddq_s16(*a0, *a1); - int16x8_t b1 = vsubq_s16(*a0, *a1); - int16x8_t b2 = vaddq_s16(*a2, *a3); - int16x8_t b3 = vsubq_s16(*a2, *a3); - int16x8_t b4 = vaddq_s16(*a4, *a5); - int16x8_t b5 = vsubq_s16(*a4, *a5); - int16x8_t b6 = vaddq_s16(*a6, *a7); - int16x8_t b7 = vsubq_s16(*a6, *a7); - - int16x8_t c0 = vaddq_s16(b0, b2); - int16x8_t c2 = vsubq_s16(b0, b2); - int16x8_t c1 = vaddq_s16(b1, b3); - int16x8_t c3 = vsubq_s16(b1, b3); - int16x8_t c4 = vaddq_s16(b4, b6); - int16x8_t c6 = vsubq_s16(b4, b6); - int16x8_t c5 = vaddq_s16(b5, b7); - int16x8_t c7 = vsubq_s16(b5, b7); - - *a0 = vaddq_s16(c0, c4); - *a2 = vsubq_s16(c0, c4); - *a7 = vaddq_s16(c1, c5); - *a6 = vsubq_s16(c1, c5); - *a3 = vaddq_s16(c2, c6); - *a1 = vsubq_s16(c2, c6); - *a4 = vaddq_s16(c3, c7); - *a5 = vsubq_s16(c3, c7); -} - -static INLINE void hadamard_highbd_col4_second_pass(int16x4_t a0, int16x4_t a1, - int16x4_t a2, int16x4_t a3, - int16x4_t a4, int16x4_t a5, - int16x4_t a6, int16x4_t a7, - tran_low_t *coeff) { - int32x4_t b0 = vaddl_s16(a0, a1); - int32x4_t b1 = vsubl_s16(a0, a1); - int32x4_t b2 = vaddl_s16(a2, a3); - int32x4_t b3 = vsubl_s16(a2, a3); - int32x4_t b4 = vaddl_s16(a4, a5); - int32x4_t b5 = vsubl_s16(a4, a5); - int32x4_t b6 = vaddl_s16(a6, a7); - int32x4_t b7 = vsubl_s16(a6, a7); - - int32x4_t c0 = vaddq_s32(b0, b2); - int32x4_t c2 = vsubq_s32(b0, b2); - int32x4_t c1 = vaddq_s32(b1, b3); - int32x4_t c3 = vsubq_s32(b1, b3); - int32x4_t c4 = vaddq_s32(b4, b6); - int32x4_t c6 = vsubq_s32(b4, b6); - int32x4_t c5 = vaddq_s32(b5, b7); - int32x4_t c7 = vsubq_s32(b5, b7); - - int32x4_t d0 = vaddq_s32(c0, c4); - int32x4_t d2 = vsubq_s32(c0, c4); - int32x4_t d7 = vaddq_s32(c1, c5); - int32x4_t d6 = vsubq_s32(c1, c5); - int32x4_t d3 = vaddq_s32(c2, c6); - int32x4_t d1 = vsubq_s32(c2, c6); - int32x4_t d4 = vaddq_s32(c3, c7); - int32x4_t d5 = vsubq_s32(c3, c7); - - store_s32q_to_tran_low(coeff + 0, d0); - store_s32q_to_tran_low(coeff + 4, d1); - store_s32q_to_tran_low(coeff + 8, d2); - store_s32q_to_tran_low(coeff + 12, d3); - store_s32q_to_tran_low(coeff + 16, d4); - store_s32q_to_tran_low(coeff + 20, d5); - store_s32q_to_tran_low(coeff + 24, d6); - store_s32q_to_tran_low(coeff + 28, d7); -} - -void vpx_highbd_hadamard_8x8_neon(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { - int16x4_t b0, b1, b2, b3, b4, b5, b6, b7; - - int16x8_t s0 = vld1q_s16(src_diff + 0 * src_stride); - int16x8_t s1 = vld1q_s16(src_diff + 1 * src_stride); - int16x8_t s2 = vld1q_s16(src_diff + 2 * src_stride); - int16x8_t s3 = vld1q_s16(src_diff + 3 * src_stride); - int16x8_t s4 = vld1q_s16(src_diff + 4 * src_stride); - int16x8_t s5 = vld1q_s16(src_diff + 5 * src_stride); - int16x8_t s6 = vld1q_s16(src_diff + 6 * src_stride); - int16x8_t s7 = vld1q_s16(src_diff + 7 * src_stride); - - // For the first pass we can stay in 16-bit elements (4095*8 = 32760). - hadamard_highbd_col8_first_pass(&s0, &s1, &s2, &s3, &s4, &s5, &s6, &s7); - - transpose_s16_8x8(&s0, &s1, &s2, &s3, &s4, &s5, &s6, &s7); - - // For the second pass we need to widen to 32-bit elements, so we're - // processing 4 columns at a time. - // Skip the second transpose because it is not required. - - b0 = vget_low_s16(s0); - b1 = vget_low_s16(s1); - b2 = vget_low_s16(s2); - b3 = vget_low_s16(s3); - b4 = vget_low_s16(s4); - b5 = vget_low_s16(s5); - b6 = vget_low_s16(s6); - b7 = vget_low_s16(s7); - - hadamard_highbd_col4_second_pass(b0, b1, b2, b3, b4, b5, b6, b7, coeff); - - b0 = vget_high_s16(s0); - b1 = vget_high_s16(s1); - b2 = vget_high_s16(s2); - b3 = vget_high_s16(s3); - b4 = vget_high_s16(s4); - b5 = vget_high_s16(s5); - b6 = vget_high_s16(s6); - b7 = vget_high_s16(s7); - - hadamard_highbd_col4_second_pass(b0, b1, b2, b3, b4, b5, b6, b7, coeff + 32); -} - -void vpx_highbd_hadamard_16x16_neon(const int16_t *src_diff, - ptrdiff_t src_stride, tran_low_t *coeff) { - int i = 0; - - // Rearrange 16x16 to 8x32 and remove stride. - // Top left first. - vpx_highbd_hadamard_8x8_neon(src_diff, src_stride, coeff); - // Top right. - vpx_highbd_hadamard_8x8_neon(src_diff + 8, src_stride, coeff + 64); - // Bottom left. - vpx_highbd_hadamard_8x8_neon(src_diff + 8 * src_stride, src_stride, - coeff + 128); - // Bottom right. - vpx_highbd_hadamard_8x8_neon(src_diff + 8 * src_stride + 8, src_stride, - coeff + 192); - - do { - int32x4_t a0 = load_tran_low_to_s32q(coeff + 4 * i); - int32x4_t a1 = load_tran_low_to_s32q(coeff + 4 * i + 64); - int32x4_t a2 = load_tran_low_to_s32q(coeff + 4 * i + 128); - int32x4_t a3 = load_tran_low_to_s32q(coeff + 4 * i + 192); - - int32x4_t b0 = vhaddq_s32(a0, a1); - int32x4_t b1 = vhsubq_s32(a0, a1); - int32x4_t b2 = vhaddq_s32(a2, a3); - int32x4_t b3 = vhsubq_s32(a2, a3); - - int32x4_t c0 = vaddq_s32(b0, b2); - int32x4_t c1 = vaddq_s32(b1, b3); - int32x4_t c2 = vsubq_s32(b0, b2); - int32x4_t c3 = vsubq_s32(b1, b3); - - store_s32q_to_tran_low(coeff + 4 * i, c0); - store_s32q_to_tran_low(coeff + 4 * i + 64, c1); - store_s32q_to_tran_low(coeff + 4 * i + 128, c2); - store_s32q_to_tran_low(coeff + 4 * i + 192, c3); - } while (++i < 16); -} - -void vpx_highbd_hadamard_32x32_neon(const int16_t *src_diff, - ptrdiff_t src_stride, tran_low_t *coeff) { - int i = 0; - - // Rearrange 32x32 to 16x64 and remove stride. - // Top left first. - vpx_highbd_hadamard_16x16_neon(src_diff, src_stride, coeff); - // Top right. - vpx_highbd_hadamard_16x16_neon(src_diff + 16, src_stride, coeff + 256); - // Bottom left. - vpx_highbd_hadamard_16x16_neon(src_diff + 16 * src_stride, src_stride, - coeff + 512); - // Bottom right. - vpx_highbd_hadamard_16x16_neon(src_diff + 16 * src_stride + 16, src_stride, - coeff + 768); - - do { - int32x4_t a0 = load_tran_low_to_s32q(coeff + 4 * i); - int32x4_t a1 = load_tran_low_to_s32q(coeff + 4 * i + 256); - int32x4_t a2 = load_tran_low_to_s32q(coeff + 4 * i + 512); - int32x4_t a3 = load_tran_low_to_s32q(coeff + 4 * i + 768); - - int32x4_t b0 = vshrq_n_s32(vaddq_s32(a0, a1), 2); - int32x4_t b1 = vshrq_n_s32(vsubq_s32(a0, a1), 2); - int32x4_t b2 = vshrq_n_s32(vaddq_s32(a2, a3), 2); - int32x4_t b3 = vshrq_n_s32(vsubq_s32(a2, a3), 2); - - int32x4_t c0 = vaddq_s32(b0, b2); - int32x4_t c1 = vaddq_s32(b1, b3); - int32x4_t c2 = vsubq_s32(b0, b2); - int32x4_t c3 = vsubq_s32(b1, b3); - - store_s32q_to_tran_low(coeff + 4 * i, c0); - store_s32q_to_tran_low(coeff + 4 * i + 256, c1); - store_s32q_to_tran_low(coeff + 4 * i + 512, c2); - store_s32q_to_tran_low(coeff + 4 * i + 768, c3); - } while (++i < 64); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct16x16_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct16x16_add_neon.c deleted file mode 100644 index 654ab42c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct16x16_add_neon.c +++ /dev/null @@ -1,1361 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/highbd_idct_neon.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/inv_txfm.h" - -static INLINE int32x4_t dct_const_round_shift_high_4(const int64x2x2_t in) { - int32x2x2_t t32; - - t32.val[0] = vrshrn_n_s64(in.val[0], DCT_CONST_BITS); - t32.val[1] = vrshrn_n_s64(in.val[1], DCT_CONST_BITS); - return vcombine_s32(t32.val[0], t32.val[1]); -} - -static INLINE void dct_const_round_shift_high_4_dual( - const int64x2x2_t *const in, int32x4_t *const d0, int32x4_t *const d1) { - *d0 = dct_const_round_shift_high_4(in[0]); - *d1 = dct_const_round_shift_high_4(in[1]); -} - -static INLINE int32x4x2_t -dct_const_round_shift_high_4x2_int64x2x2(const int64x2x2_t *const in) { - int32x4x2_t out; - out.val[0] = dct_const_round_shift_high_4(in[0]); - out.val[1] = dct_const_round_shift_high_4(in[1]); - return out; -} - -static INLINE void dct_const_round_shift_high_4x2x2(const int64x2x2_t *const in, - int32x4x2_t *const d0, - int32x4x2_t *const d1) { - *d0 = dct_const_round_shift_high_4x2_int64x2x2(in + 0); - *d1 = dct_const_round_shift_high_4x2_int64x2x2(in + 2); -} - -static INLINE void highbd_idct_cospi_2_30(const int32x4x2_t s0, - const int32x4x2_t s1, - const int32x4_t cospi_2_30_10_22, - int32x4x2_t *const d0, - int32x4x2_t *const d1) { - int64x2x2_t t[4]; - - t[0].val[0] = vmull_lane_s32(vget_low_s32(s0.val[0]), - vget_low_s32(cospi_2_30_10_22), 1); - t[0].val[1] = vmull_lane_s32(vget_high_s32(s0.val[0]), - vget_low_s32(cospi_2_30_10_22), 1); - t[1].val[0] = vmull_lane_s32(vget_low_s32(s0.val[1]), - vget_low_s32(cospi_2_30_10_22), 1); - t[1].val[1] = vmull_lane_s32(vget_high_s32(s0.val[1]), - vget_low_s32(cospi_2_30_10_22), 1); - t[2].val[0] = vmull_lane_s32(vget_low_s32(s1.val[0]), - vget_low_s32(cospi_2_30_10_22), 1); - t[2].val[1] = vmull_lane_s32(vget_high_s32(s1.val[0]), - vget_low_s32(cospi_2_30_10_22), 1); - t[3].val[0] = vmull_lane_s32(vget_low_s32(s1.val[1]), - vget_low_s32(cospi_2_30_10_22), 1); - t[3].val[1] = vmull_lane_s32(vget_high_s32(s1.val[1]), - vget_low_s32(cospi_2_30_10_22), 1); - t[0].val[0] = vmlsl_lane_s32(t[0].val[0], vget_low_s32(s1.val[0]), - vget_low_s32(cospi_2_30_10_22), 0); - t[0].val[1] = vmlsl_lane_s32(t[0].val[1], vget_high_s32(s1.val[0]), - vget_low_s32(cospi_2_30_10_22), 0); - t[1].val[0] = vmlsl_lane_s32(t[1].val[0], vget_low_s32(s1.val[1]), - vget_low_s32(cospi_2_30_10_22), 0); - t[1].val[1] = vmlsl_lane_s32(t[1].val[1], vget_high_s32(s1.val[1]), - vget_low_s32(cospi_2_30_10_22), 0); - t[2].val[0] = vmlal_lane_s32(t[2].val[0], vget_low_s32(s0.val[0]), - vget_low_s32(cospi_2_30_10_22), 0); - t[2].val[1] = vmlal_lane_s32(t[2].val[1], vget_high_s32(s0.val[0]), - vget_low_s32(cospi_2_30_10_22), 0); - t[3].val[0] = vmlal_lane_s32(t[3].val[0], vget_low_s32(s0.val[1]), - vget_low_s32(cospi_2_30_10_22), 0); - t[3].val[1] = vmlal_lane_s32(t[3].val[1], vget_high_s32(s0.val[1]), - vget_low_s32(cospi_2_30_10_22), 0); - dct_const_round_shift_high_4x2x2(t, d0, d1); -} - -static INLINE void highbd_idct_cospi_4_28(const int32x4x2_t s0, - const int32x4x2_t s1, - const int32x4_t cospi_4_12_20N_28, - int32x4x2_t *const d0, - int32x4x2_t *const d1) { - int64x2x2_t t[4]; - - t[0].val[0] = vmull_lane_s32(vget_low_s32(s0.val[0]), - vget_high_s32(cospi_4_12_20N_28), 1); - t[0].val[1] = vmull_lane_s32(vget_high_s32(s0.val[0]), - vget_high_s32(cospi_4_12_20N_28), 1); - t[1].val[0] = vmull_lane_s32(vget_low_s32(s0.val[1]), - vget_high_s32(cospi_4_12_20N_28), 1); - t[1].val[1] = vmull_lane_s32(vget_high_s32(s0.val[1]), - vget_high_s32(cospi_4_12_20N_28), 1); - t[2].val[0] = vmull_lane_s32(vget_low_s32(s1.val[0]), - vget_high_s32(cospi_4_12_20N_28), 1); - t[2].val[1] = vmull_lane_s32(vget_high_s32(s1.val[0]), - vget_high_s32(cospi_4_12_20N_28), 1); - t[3].val[0] = vmull_lane_s32(vget_low_s32(s1.val[1]), - vget_high_s32(cospi_4_12_20N_28), 1); - t[3].val[1] = vmull_lane_s32(vget_high_s32(s1.val[1]), - vget_high_s32(cospi_4_12_20N_28), 1); - t[0].val[0] = vmlsl_lane_s32(t[0].val[0], vget_low_s32(s1.val[0]), - vget_low_s32(cospi_4_12_20N_28), 0); - t[0].val[1] = vmlsl_lane_s32(t[0].val[1], vget_high_s32(s1.val[0]), - vget_low_s32(cospi_4_12_20N_28), 0); - t[1].val[0] = vmlsl_lane_s32(t[1].val[0], vget_low_s32(s1.val[1]), - vget_low_s32(cospi_4_12_20N_28), 0); - t[1].val[1] = vmlsl_lane_s32(t[1].val[1], vget_high_s32(s1.val[1]), - vget_low_s32(cospi_4_12_20N_28), 0); - t[2].val[0] = vmlal_lane_s32(t[2].val[0], vget_low_s32(s0.val[0]), - vget_low_s32(cospi_4_12_20N_28), 0); - t[2].val[1] = vmlal_lane_s32(t[2].val[1], vget_high_s32(s0.val[0]), - vget_low_s32(cospi_4_12_20N_28), 0); - t[3].val[0] = vmlal_lane_s32(t[3].val[0], vget_low_s32(s0.val[1]), - vget_low_s32(cospi_4_12_20N_28), 0); - t[3].val[1] = vmlal_lane_s32(t[3].val[1], vget_high_s32(s0.val[1]), - vget_low_s32(cospi_4_12_20N_28), 0); - dct_const_round_shift_high_4x2x2(t, d0, d1); -} - -static INLINE void highbd_idct_cospi_6_26(const int32x4x2_t s0, - const int32x4x2_t s1, - const int32x4_t cospi_6_26N_14_18N, - int32x4x2_t *const d0, - int32x4x2_t *const d1) { - int64x2x2_t t[4]; - - t[0].val[0] = vmull_lane_s32(vget_low_s32(s0.val[0]), - vget_low_s32(cospi_6_26N_14_18N), 0); - t[0].val[1] = vmull_lane_s32(vget_high_s32(s0.val[0]), - vget_low_s32(cospi_6_26N_14_18N), 0); - t[1].val[0] = vmull_lane_s32(vget_low_s32(s0.val[1]), - vget_low_s32(cospi_6_26N_14_18N), 0); - t[1].val[1] = vmull_lane_s32(vget_high_s32(s0.val[1]), - vget_low_s32(cospi_6_26N_14_18N), 0); - t[2].val[0] = vmull_lane_s32(vget_low_s32(s1.val[0]), - vget_low_s32(cospi_6_26N_14_18N), 0); - t[2].val[1] = vmull_lane_s32(vget_high_s32(s1.val[0]), - vget_low_s32(cospi_6_26N_14_18N), 0); - t[3].val[0] = vmull_lane_s32(vget_low_s32(s1.val[1]), - vget_low_s32(cospi_6_26N_14_18N), 0); - t[3].val[1] = vmull_lane_s32(vget_high_s32(s1.val[1]), - vget_low_s32(cospi_6_26N_14_18N), 0); - t[0].val[0] = vmlal_lane_s32(t[0].val[0], vget_low_s32(s1.val[0]), - vget_low_s32(cospi_6_26N_14_18N), 1); - t[0].val[1] = vmlal_lane_s32(t[0].val[1], vget_high_s32(s1.val[0]), - vget_low_s32(cospi_6_26N_14_18N), 1); - t[1].val[0] = vmlal_lane_s32(t[1].val[0], vget_low_s32(s1.val[1]), - vget_low_s32(cospi_6_26N_14_18N), 1); - t[1].val[1] = vmlal_lane_s32(t[1].val[1], vget_high_s32(s1.val[1]), - vget_low_s32(cospi_6_26N_14_18N), 1); - t[2].val[0] = vmlsl_lane_s32(t[2].val[0], vget_low_s32(s0.val[0]), - vget_low_s32(cospi_6_26N_14_18N), 1); - t[2].val[1] = vmlsl_lane_s32(t[2].val[1], vget_high_s32(s0.val[0]), - vget_low_s32(cospi_6_26N_14_18N), 1); - t[3].val[0] = vmlsl_lane_s32(t[3].val[0], vget_low_s32(s0.val[1]), - vget_low_s32(cospi_6_26N_14_18N), 1); - t[3].val[1] = vmlsl_lane_s32(t[3].val[1], vget_high_s32(s0.val[1]), - vget_low_s32(cospi_6_26N_14_18N), 1); - dct_const_round_shift_high_4x2x2(t, d0, d1); -} - -static INLINE void highbd_idct_cospi_10_22(const int32x4x2_t s0, - const int32x4x2_t s1, - const int32x4_t cospi_2_30_10_22, - int32x4x2_t *const d0, - int32x4x2_t *const d1) { - int64x2x2_t t[4]; - - t[0].val[0] = vmull_lane_s32(vget_low_s32(s0.val[0]), - vget_high_s32(cospi_2_30_10_22), 1); - t[0].val[1] = vmull_lane_s32(vget_high_s32(s0.val[0]), - vget_high_s32(cospi_2_30_10_22), 1); - t[1].val[0] = vmull_lane_s32(vget_low_s32(s0.val[1]), - vget_high_s32(cospi_2_30_10_22), 1); - t[1].val[1] = vmull_lane_s32(vget_high_s32(s0.val[1]), - vget_high_s32(cospi_2_30_10_22), 1); - t[2].val[0] = vmull_lane_s32(vget_low_s32(s1.val[0]), - vget_high_s32(cospi_2_30_10_22), 1); - t[2].val[1] = vmull_lane_s32(vget_high_s32(s1.val[0]), - vget_high_s32(cospi_2_30_10_22), 1); - t[3].val[0] = vmull_lane_s32(vget_low_s32(s1.val[1]), - vget_high_s32(cospi_2_30_10_22), 1); - t[3].val[1] = vmull_lane_s32(vget_high_s32(s1.val[1]), - vget_high_s32(cospi_2_30_10_22), 1); - t[0].val[0] = vmlsl_lane_s32(t[0].val[0], vget_low_s32(s1.val[0]), - vget_high_s32(cospi_2_30_10_22), 0); - t[0].val[1] = vmlsl_lane_s32(t[0].val[1], vget_high_s32(s1.val[0]), - vget_high_s32(cospi_2_30_10_22), 0); - t[1].val[0] = vmlsl_lane_s32(t[1].val[0], vget_low_s32(s1.val[1]), - vget_high_s32(cospi_2_30_10_22), 0); - t[1].val[1] = vmlsl_lane_s32(t[1].val[1], vget_high_s32(s1.val[1]), - vget_high_s32(cospi_2_30_10_22), 0); - t[2].val[0] = vmlal_lane_s32(t[2].val[0], vget_low_s32(s0.val[0]), - vget_high_s32(cospi_2_30_10_22), 0); - t[2].val[1] = vmlal_lane_s32(t[2].val[1], vget_high_s32(s0.val[0]), - vget_high_s32(cospi_2_30_10_22), 0); - t[3].val[0] = vmlal_lane_s32(t[3].val[0], vget_low_s32(s0.val[1]), - vget_high_s32(cospi_2_30_10_22), 0); - t[3].val[1] = vmlal_lane_s32(t[3].val[1], vget_high_s32(s0.val[1]), - vget_high_s32(cospi_2_30_10_22), 0); - dct_const_round_shift_high_4x2x2(t, d0, d1); -} - -static INLINE void highbd_idct_cospi_12_20(const int32x4x2_t s0, - const int32x4x2_t s1, - const int32x4_t cospi_4_12_20N_28, - int32x4x2_t *const d0, - int32x4x2_t *const d1) { - int64x2x2_t t[4]; - - t[0].val[0] = vmull_lane_s32(vget_low_s32(s0.val[0]), - vget_low_s32(cospi_4_12_20N_28), 1); - t[0].val[1] = vmull_lane_s32(vget_high_s32(s0.val[0]), - vget_low_s32(cospi_4_12_20N_28), 1); - t[1].val[0] = vmull_lane_s32(vget_low_s32(s0.val[1]), - vget_low_s32(cospi_4_12_20N_28), 1); - t[1].val[1] = vmull_lane_s32(vget_high_s32(s0.val[1]), - vget_low_s32(cospi_4_12_20N_28), 1); - t[2].val[0] = vmull_lane_s32(vget_low_s32(s1.val[0]), - vget_low_s32(cospi_4_12_20N_28), 1); - t[2].val[1] = vmull_lane_s32(vget_high_s32(s1.val[0]), - vget_low_s32(cospi_4_12_20N_28), 1); - t[3].val[0] = vmull_lane_s32(vget_low_s32(s1.val[1]), - vget_low_s32(cospi_4_12_20N_28), 1); - t[3].val[1] = vmull_lane_s32(vget_high_s32(s1.val[1]), - vget_low_s32(cospi_4_12_20N_28), 1); - t[0].val[0] = vmlal_lane_s32(t[0].val[0], vget_low_s32(s1.val[0]), - vget_high_s32(cospi_4_12_20N_28), 0); - t[0].val[1] = vmlal_lane_s32(t[0].val[1], vget_high_s32(s1.val[0]), - vget_high_s32(cospi_4_12_20N_28), 0); - t[1].val[0] = vmlal_lane_s32(t[1].val[0], vget_low_s32(s1.val[1]), - vget_high_s32(cospi_4_12_20N_28), 0); - t[1].val[1] = vmlal_lane_s32(t[1].val[1], vget_high_s32(s1.val[1]), - vget_high_s32(cospi_4_12_20N_28), 0); - t[2].val[0] = vmlsl_lane_s32(t[2].val[0], vget_low_s32(s0.val[0]), - vget_high_s32(cospi_4_12_20N_28), 0); - t[2].val[1] = vmlsl_lane_s32(t[2].val[1], vget_high_s32(s0.val[0]), - vget_high_s32(cospi_4_12_20N_28), 0); - t[3].val[0] = vmlsl_lane_s32(t[3].val[0], vget_low_s32(s0.val[1]), - vget_high_s32(cospi_4_12_20N_28), 0); - t[3].val[1] = vmlsl_lane_s32(t[3].val[1], vget_high_s32(s0.val[1]), - vget_high_s32(cospi_4_12_20N_28), 0); - dct_const_round_shift_high_4x2x2(t, d0, d1); -} - -static INLINE void highbd_idct_cospi_14_18(const int32x4x2_t s0, - const int32x4x2_t s1, - const int32x4_t cospi_6_26N_14_18N, - int32x4x2_t *const d0, - int32x4x2_t *const d1) { - int64x2x2_t t[4]; - - t[0].val[0] = vmull_lane_s32(vget_low_s32(s0.val[0]), - vget_high_s32(cospi_6_26N_14_18N), 0); - t[0].val[1] = vmull_lane_s32(vget_high_s32(s0.val[0]), - vget_high_s32(cospi_6_26N_14_18N), 0); - t[1].val[0] = vmull_lane_s32(vget_low_s32(s0.val[1]), - vget_high_s32(cospi_6_26N_14_18N), 0); - t[1].val[1] = vmull_lane_s32(vget_high_s32(s0.val[1]), - vget_high_s32(cospi_6_26N_14_18N), 0); - t[2].val[0] = vmull_lane_s32(vget_low_s32(s1.val[0]), - vget_high_s32(cospi_6_26N_14_18N), 0); - t[2].val[1] = vmull_lane_s32(vget_high_s32(s1.val[0]), - vget_high_s32(cospi_6_26N_14_18N), 0); - t[3].val[0] = vmull_lane_s32(vget_low_s32(s1.val[1]), - vget_high_s32(cospi_6_26N_14_18N), 0); - t[3].val[1] = vmull_lane_s32(vget_high_s32(s1.val[1]), - vget_high_s32(cospi_6_26N_14_18N), 0); - t[0].val[0] = vmlal_lane_s32(t[0].val[0], vget_low_s32(s1.val[0]), - vget_high_s32(cospi_6_26N_14_18N), 1); - t[0].val[1] = vmlal_lane_s32(t[0].val[1], vget_high_s32(s1.val[0]), - vget_high_s32(cospi_6_26N_14_18N), 1); - t[1].val[0] = vmlal_lane_s32(t[1].val[0], vget_low_s32(s1.val[1]), - vget_high_s32(cospi_6_26N_14_18N), 1); - t[1].val[1] = vmlal_lane_s32(t[1].val[1], vget_high_s32(s1.val[1]), - vget_high_s32(cospi_6_26N_14_18N), 1); - t[2].val[0] = vmlsl_lane_s32(t[2].val[0], vget_low_s32(s0.val[0]), - vget_high_s32(cospi_6_26N_14_18N), 1); - t[2].val[1] = vmlsl_lane_s32(t[2].val[1], vget_high_s32(s0.val[0]), - vget_high_s32(cospi_6_26N_14_18N), 1); - t[3].val[0] = vmlsl_lane_s32(t[3].val[0], vget_low_s32(s0.val[1]), - vget_high_s32(cospi_6_26N_14_18N), 1); - t[3].val[1] = vmlsl_lane_s32(t[3].val[1], vget_high_s32(s0.val[1]), - vget_high_s32(cospi_6_26N_14_18N), 1); - dct_const_round_shift_high_4x2x2(t, d0, d1); -} - -static INLINE void highbd_idct_cospi_8_24_q_kernel( - const int32x4x2_t s0, const int32x4x2_t s1, const int32x4_t cospi_0_8_16_24, - int64x2x2_t *const t) { - t[0].val[0] = vmull_lane_s32(vget_low_s32(s0.val[0]), - vget_high_s32(cospi_0_8_16_24), 1); - t[0].val[1] = vmull_lane_s32(vget_high_s32(s0.val[0]), - vget_high_s32(cospi_0_8_16_24), 1); - t[1].val[0] = vmull_lane_s32(vget_low_s32(s0.val[1]), - vget_high_s32(cospi_0_8_16_24), 1); - t[1].val[1] = vmull_lane_s32(vget_high_s32(s0.val[1]), - vget_high_s32(cospi_0_8_16_24), 1); - t[2].val[0] = vmull_lane_s32(vget_low_s32(s1.val[0]), - vget_high_s32(cospi_0_8_16_24), 1); - t[2].val[1] = vmull_lane_s32(vget_high_s32(s1.val[0]), - vget_high_s32(cospi_0_8_16_24), 1); - t[3].val[0] = vmull_lane_s32(vget_low_s32(s1.val[1]), - vget_high_s32(cospi_0_8_16_24), 1); - t[3].val[1] = vmull_lane_s32(vget_high_s32(s1.val[1]), - vget_high_s32(cospi_0_8_16_24), 1); - t[0].val[0] = vmlsl_lane_s32(t[0].val[0], vget_low_s32(s1.val[0]), - vget_low_s32(cospi_0_8_16_24), 1); - t[0].val[1] = vmlsl_lane_s32(t[0].val[1], vget_high_s32(s1.val[0]), - vget_low_s32(cospi_0_8_16_24), 1); - t[1].val[0] = vmlsl_lane_s32(t[1].val[0], vget_low_s32(s1.val[1]), - vget_low_s32(cospi_0_8_16_24), 1); - t[1].val[1] = vmlsl_lane_s32(t[1].val[1], vget_high_s32(s1.val[1]), - vget_low_s32(cospi_0_8_16_24), 1); - t[2].val[0] = vmlal_lane_s32(t[2].val[0], vget_low_s32(s0.val[0]), - vget_low_s32(cospi_0_8_16_24), 1); - t[2].val[1] = vmlal_lane_s32(t[2].val[1], vget_high_s32(s0.val[0]), - vget_low_s32(cospi_0_8_16_24), 1); - t[3].val[0] = vmlal_lane_s32(t[3].val[0], vget_low_s32(s0.val[1]), - vget_low_s32(cospi_0_8_16_24), 1); - t[3].val[1] = vmlal_lane_s32(t[3].val[1], vget_high_s32(s0.val[1]), - vget_low_s32(cospi_0_8_16_24), 1); -} - -static INLINE void highbd_idct_cospi_8_24_d_kernel( - const int32x4_t s0, const int32x4_t s1, const int32x4_t cospi_0_8_16_24, - int64x2x2_t *const t) { - t[0].val[0] = - vmull_lane_s32(vget_low_s32(s0), vget_high_s32(cospi_0_8_16_24), 1); - t[0].val[1] = - vmull_lane_s32(vget_high_s32(s0), vget_high_s32(cospi_0_8_16_24), 1); - t[1].val[0] = - vmull_lane_s32(vget_low_s32(s1), vget_high_s32(cospi_0_8_16_24), 1); - t[1].val[1] = - vmull_lane_s32(vget_high_s32(s1), vget_high_s32(cospi_0_8_16_24), 1); - t[0].val[0] = vmlsl_lane_s32(t[0].val[0], vget_low_s32(s1), - vget_low_s32(cospi_0_8_16_24), 1); - t[0].val[1] = vmlsl_lane_s32(t[0].val[1], vget_high_s32(s1), - vget_low_s32(cospi_0_8_16_24), 1); - t[1].val[0] = vmlal_lane_s32(t[1].val[0], vget_low_s32(s0), - vget_low_s32(cospi_0_8_16_24), 1); - t[1].val[1] = vmlal_lane_s32(t[1].val[1], vget_high_s32(s0), - vget_low_s32(cospi_0_8_16_24), 1); -} - -static INLINE void highbd_idct_cospi_8_24_q(const int32x4x2_t s0, - const int32x4x2_t s1, - const int32x4_t cospi_0_8_16_24, - int32x4x2_t *const d0, - int32x4x2_t *const d1) { - int64x2x2_t t[4]; - - highbd_idct_cospi_8_24_q_kernel(s0, s1, cospi_0_8_16_24, t); - dct_const_round_shift_high_4x2x2(t, d0, d1); -} - -static INLINE void highbd_idct_cospi_8_24_d(const int32x4_t s0, - const int32x4_t s1, - const int32x4_t cospi_0_8_16_24, - int32x4_t *const d0, - int32x4_t *const d1) { - int64x2x2_t t[2]; - - highbd_idct_cospi_8_24_d_kernel(s0, s1, cospi_0_8_16_24, t); - dct_const_round_shift_high_4_dual(t, d0, d1); -} - -static INLINE void highbd_idct_cospi_8_24_neg_q(const int32x4x2_t s0, - const int32x4x2_t s1, - const int32x4_t cospi_0_8_16_24, - int32x4x2_t *const d0, - int32x4x2_t *const d1) { - int64x2x2_t t[4]; - - highbd_idct_cospi_8_24_q_kernel(s0, s1, cospi_0_8_16_24, t); - t[2].val[0] = vsubq_s64(vdupq_n_s64(0), t[2].val[0]); - t[2].val[1] = vsubq_s64(vdupq_n_s64(0), t[2].val[1]); - t[3].val[0] = vsubq_s64(vdupq_n_s64(0), t[3].val[0]); - t[3].val[1] = vsubq_s64(vdupq_n_s64(0), t[3].val[1]); - dct_const_round_shift_high_4x2x2(t, d0, d1); -} - -static INLINE void highbd_idct_cospi_8_24_neg_d(const int32x4_t s0, - const int32x4_t s1, - const int32x4_t cospi_0_8_16_24, - int32x4_t *const d0, - int32x4_t *const d1) { - int64x2x2_t t[2]; - - highbd_idct_cospi_8_24_d_kernel(s0, s1, cospi_0_8_16_24, t); - t[1].val[0] = vsubq_s64(vdupq_n_s64(0), t[1].val[0]); - t[1].val[1] = vsubq_s64(vdupq_n_s64(0), t[1].val[1]); - dct_const_round_shift_high_4_dual(t, d0, d1); -} - -static INLINE void highbd_idct_cospi_16_16_q(const int32x4x2_t s0, - const int32x4x2_t s1, - const int32x4_t cospi_0_8_16_24, - int32x4x2_t *const d0, - int32x4x2_t *const d1) { - int64x2x2_t t[6]; - - t[4].val[0] = vmull_lane_s32(vget_low_s32(s1.val[0]), - vget_high_s32(cospi_0_8_16_24), 0); - t[4].val[1] = vmull_lane_s32(vget_high_s32(s1.val[0]), - vget_high_s32(cospi_0_8_16_24), 0); - t[5].val[0] = vmull_lane_s32(vget_low_s32(s1.val[1]), - vget_high_s32(cospi_0_8_16_24), 0); - t[5].val[1] = vmull_lane_s32(vget_high_s32(s1.val[1]), - vget_high_s32(cospi_0_8_16_24), 0); - t[0].val[0] = vmlsl_lane_s32(t[4].val[0], vget_low_s32(s0.val[0]), - vget_high_s32(cospi_0_8_16_24), 0); - t[0].val[1] = vmlsl_lane_s32(t[4].val[1], vget_high_s32(s0.val[0]), - vget_high_s32(cospi_0_8_16_24), 0); - t[1].val[0] = vmlsl_lane_s32(t[5].val[0], vget_low_s32(s0.val[1]), - vget_high_s32(cospi_0_8_16_24), 0); - t[1].val[1] = vmlsl_lane_s32(t[5].val[1], vget_high_s32(s0.val[1]), - vget_high_s32(cospi_0_8_16_24), 0); - t[2].val[0] = vmlal_lane_s32(t[4].val[0], vget_low_s32(s0.val[0]), - vget_high_s32(cospi_0_8_16_24), 0); - t[2].val[1] = vmlal_lane_s32(t[4].val[1], vget_high_s32(s0.val[0]), - vget_high_s32(cospi_0_8_16_24), 0); - t[3].val[0] = vmlal_lane_s32(t[5].val[0], vget_low_s32(s0.val[1]), - vget_high_s32(cospi_0_8_16_24), 0); - t[3].val[1] = vmlal_lane_s32(t[5].val[1], vget_high_s32(s0.val[1]), - vget_high_s32(cospi_0_8_16_24), 0); - dct_const_round_shift_high_4x2x2(t, d0, d1); -} - -static INLINE void highbd_idct_cospi_16_16_d(const int32x4_t s0, - const int32x4_t s1, - const int32x4_t cospi_0_8_16_24, - int32x4_t *const d0, - int32x4_t *const d1) { - int64x2x2_t t[3]; - - t[2].val[0] = - vmull_lane_s32(vget_low_s32(s1), vget_high_s32(cospi_0_8_16_24), 0); - t[2].val[1] = - vmull_lane_s32(vget_high_s32(s1), vget_high_s32(cospi_0_8_16_24), 0); - t[0].val[0] = vmlsl_lane_s32(t[2].val[0], vget_low_s32(s0), - vget_high_s32(cospi_0_8_16_24), 0); - t[0].val[1] = vmlsl_lane_s32(t[2].val[1], vget_high_s32(s0), - vget_high_s32(cospi_0_8_16_24), 0); - t[1].val[0] = vmlal_lane_s32(t[2].val[0], vget_low_s32(s0), - vget_high_s32(cospi_0_8_16_24), 0); - t[1].val[1] = vmlal_lane_s32(t[2].val[1], vget_high_s32(s0), - vget_high_s32(cospi_0_8_16_24), 0); - dct_const_round_shift_high_4_dual(t, d0, d1); -} - -static INLINE void highbd_idct16x16_add_stage7_dual( - const int32x4x2_t *const step2, int32x4x2_t *const out) { - out[0].val[0] = vaddq_s32(step2[0].val[0], step2[15].val[0]); - out[0].val[1] = vaddq_s32(step2[0].val[1], step2[15].val[1]); - out[1].val[0] = vaddq_s32(step2[1].val[0], step2[14].val[0]); - out[1].val[1] = vaddq_s32(step2[1].val[1], step2[14].val[1]); - out[2].val[0] = vaddq_s32(step2[2].val[0], step2[13].val[0]); - out[2].val[1] = vaddq_s32(step2[2].val[1], step2[13].val[1]); - out[3].val[0] = vaddq_s32(step2[3].val[0], step2[12].val[0]); - out[3].val[1] = vaddq_s32(step2[3].val[1], step2[12].val[1]); - out[4].val[0] = vaddq_s32(step2[4].val[0], step2[11].val[0]); - out[4].val[1] = vaddq_s32(step2[4].val[1], step2[11].val[1]); - out[5].val[0] = vaddq_s32(step2[5].val[0], step2[10].val[0]); - out[5].val[1] = vaddq_s32(step2[5].val[1], step2[10].val[1]); - out[6].val[0] = vaddq_s32(step2[6].val[0], step2[9].val[0]); - out[6].val[1] = vaddq_s32(step2[6].val[1], step2[9].val[1]); - out[7].val[0] = vaddq_s32(step2[7].val[0], step2[8].val[0]); - out[7].val[1] = vaddq_s32(step2[7].val[1], step2[8].val[1]); - out[8].val[0] = vsubq_s32(step2[7].val[0], step2[8].val[0]); - out[8].val[1] = vsubq_s32(step2[7].val[1], step2[8].val[1]); - out[9].val[0] = vsubq_s32(step2[6].val[0], step2[9].val[0]); - out[9].val[1] = vsubq_s32(step2[6].val[1], step2[9].val[1]); - out[10].val[0] = vsubq_s32(step2[5].val[0], step2[10].val[0]); - out[10].val[1] = vsubq_s32(step2[5].val[1], step2[10].val[1]); - out[11].val[0] = vsubq_s32(step2[4].val[0], step2[11].val[0]); - out[11].val[1] = vsubq_s32(step2[4].val[1], step2[11].val[1]); - out[12].val[0] = vsubq_s32(step2[3].val[0], step2[12].val[0]); - out[12].val[1] = vsubq_s32(step2[3].val[1], step2[12].val[1]); - out[13].val[0] = vsubq_s32(step2[2].val[0], step2[13].val[0]); - out[13].val[1] = vsubq_s32(step2[2].val[1], step2[13].val[1]); - out[14].val[0] = vsubq_s32(step2[1].val[0], step2[14].val[0]); - out[14].val[1] = vsubq_s32(step2[1].val[1], step2[14].val[1]); - out[15].val[0] = vsubq_s32(step2[0].val[0], step2[15].val[0]); - out[15].val[1] = vsubq_s32(step2[0].val[1], step2[15].val[1]); -} - -static INLINE void highbd_idct16x16_add_stage7(const int32x4_t *const step2, - int32x4_t *const out) { - out[0] = vaddq_s32(step2[0], step2[15]); - out[1] = vaddq_s32(step2[1], step2[14]); - out[2] = vaddq_s32(step2[2], step2[13]); - out[3] = vaddq_s32(step2[3], step2[12]); - out[4] = vaddq_s32(step2[4], step2[11]); - out[5] = vaddq_s32(step2[5], step2[10]); - out[6] = vaddq_s32(step2[6], step2[9]); - out[7] = vaddq_s32(step2[7], step2[8]); - out[8] = vsubq_s32(step2[7], step2[8]); - out[9] = vsubq_s32(step2[6], step2[9]); - out[10] = vsubq_s32(step2[5], step2[10]); - out[11] = vsubq_s32(step2[4], step2[11]); - out[12] = vsubq_s32(step2[3], step2[12]); - out[13] = vsubq_s32(step2[2], step2[13]); - out[14] = vsubq_s32(step2[1], step2[14]); - out[15] = vsubq_s32(step2[0], step2[15]); -} - -void vpx_highbd_idct16x16_256_add_half1d(const int32_t *input, int32_t *output, - uint16_t *dest, const int stride, - const int bd) { - const int32x4_t cospi_0_8_16_24 = vld1q_s32(kCospi32 + 0); - const int32x4_t cospi_4_12_20N_28 = vld1q_s32(kCospi32 + 4); - const int32x4_t cospi_2_30_10_22 = vld1q_s32(kCospi32 + 8); - const int32x4_t cospi_6_26N_14_18N = vld1q_s32(kCospi32 + 12); - int32x4x2_t in[16], step1[16], step2[16], out[16]; - - // Load input (16x8) - in[0].val[0] = vld1q_s32(input); - in[0].val[1] = vld1q_s32(input + 4); - input += 8; - in[8].val[0] = vld1q_s32(input); - in[8].val[1] = vld1q_s32(input + 4); - input += 8; - in[1].val[0] = vld1q_s32(input); - in[1].val[1] = vld1q_s32(input + 4); - input += 8; - in[9].val[0] = vld1q_s32(input); - in[9].val[1] = vld1q_s32(input + 4); - input += 8; - in[2].val[0] = vld1q_s32(input); - in[2].val[1] = vld1q_s32(input + 4); - input += 8; - in[10].val[0] = vld1q_s32(input); - in[10].val[1] = vld1q_s32(input + 4); - input += 8; - in[3].val[0] = vld1q_s32(input); - in[3].val[1] = vld1q_s32(input + 4); - input += 8; - in[11].val[0] = vld1q_s32(input); - in[11].val[1] = vld1q_s32(input + 4); - input += 8; - in[4].val[0] = vld1q_s32(input); - in[4].val[1] = vld1q_s32(input + 4); - input += 8; - in[12].val[0] = vld1q_s32(input); - in[12].val[1] = vld1q_s32(input + 4); - input += 8; - in[5].val[0] = vld1q_s32(input); - in[5].val[1] = vld1q_s32(input + 4); - input += 8; - in[13].val[0] = vld1q_s32(input); - in[13].val[1] = vld1q_s32(input + 4); - input += 8; - in[6].val[0] = vld1q_s32(input); - in[6].val[1] = vld1q_s32(input + 4); - input += 8; - in[14].val[0] = vld1q_s32(input); - in[14].val[1] = vld1q_s32(input + 4); - input += 8; - in[7].val[0] = vld1q_s32(input); - in[7].val[1] = vld1q_s32(input + 4); - input += 8; - in[15].val[0] = vld1q_s32(input); - in[15].val[1] = vld1q_s32(input + 4); - - // Transpose - transpose_s32_8x8(&in[0], &in[1], &in[2], &in[3], &in[4], &in[5], &in[6], - &in[7]); - transpose_s32_8x8(&in[8], &in[9], &in[10], &in[11], &in[12], &in[13], &in[14], - &in[15]); - - // stage 1 - step1[0] = in[0 / 2]; - step1[1] = in[16 / 2]; - step1[2] = in[8 / 2]; - step1[3] = in[24 / 2]; - step1[4] = in[4 / 2]; - step1[5] = in[20 / 2]; - step1[6] = in[12 / 2]; - step1[7] = in[28 / 2]; - step1[8] = in[2 / 2]; - step1[9] = in[18 / 2]; - step1[10] = in[10 / 2]; - step1[11] = in[26 / 2]; - step1[12] = in[6 / 2]; - step1[13] = in[22 / 2]; - step1[14] = in[14 / 2]; - step1[15] = in[30 / 2]; - - // stage 2 - step2[0] = step1[0]; - step2[1] = step1[1]; - step2[2] = step1[2]; - step2[3] = step1[3]; - step2[4] = step1[4]; - step2[5] = step1[5]; - step2[6] = step1[6]; - step2[7] = step1[7]; - highbd_idct_cospi_2_30(step1[8], step1[15], cospi_2_30_10_22, &step2[8], - &step2[15]); - highbd_idct_cospi_14_18(step1[9], step1[14], cospi_6_26N_14_18N, &step2[9], - &step2[14]); - highbd_idct_cospi_10_22(step1[10], step1[13], cospi_2_30_10_22, &step2[10], - &step2[13]); - highbd_idct_cospi_6_26(step1[11], step1[12], cospi_6_26N_14_18N, &step2[11], - &step2[12]); - - // stage 3 - step1[0] = step2[0]; - step1[1] = step2[1]; - step1[2] = step2[2]; - step1[3] = step2[3]; - highbd_idct_cospi_4_28(step2[4], step2[7], cospi_4_12_20N_28, &step1[4], - &step1[7]); - highbd_idct_cospi_12_20(step2[5], step2[6], cospi_4_12_20N_28, &step1[5], - &step1[6]); - step1[8].val[0] = vaddq_s32(step2[8].val[0], step2[9].val[0]); - step1[8].val[1] = vaddq_s32(step2[8].val[1], step2[9].val[1]); - step1[9].val[0] = vsubq_s32(step2[8].val[0], step2[9].val[0]); - step1[9].val[1] = vsubq_s32(step2[8].val[1], step2[9].val[1]); - step1[10].val[0] = vsubq_s32(step2[11].val[0], step2[10].val[0]); - step1[10].val[1] = vsubq_s32(step2[11].val[1], step2[10].val[1]); - step1[11].val[0] = vaddq_s32(step2[11].val[0], step2[10].val[0]); - step1[11].val[1] = vaddq_s32(step2[11].val[1], step2[10].val[1]); - step1[12].val[0] = vaddq_s32(step2[12].val[0], step2[13].val[0]); - step1[12].val[1] = vaddq_s32(step2[12].val[1], step2[13].val[1]); - step1[13].val[0] = vsubq_s32(step2[12].val[0], step2[13].val[0]); - step1[13].val[1] = vsubq_s32(step2[12].val[1], step2[13].val[1]); - step1[14].val[0] = vsubq_s32(step2[15].val[0], step2[14].val[0]); - step1[14].val[1] = vsubq_s32(step2[15].val[1], step2[14].val[1]); - step1[15].val[0] = vaddq_s32(step2[15].val[0], step2[14].val[0]); - step1[15].val[1] = vaddq_s32(step2[15].val[1], step2[14].val[1]); - - // stage 4 - highbd_idct_cospi_16_16_q(step1[1], step1[0], cospi_0_8_16_24, &step2[1], - &step2[0]); - highbd_idct_cospi_8_24_q(step1[2], step1[3], cospi_0_8_16_24, &step2[2], - &step2[3]); - step2[4].val[0] = vaddq_s32(step1[4].val[0], step1[5].val[0]); - step2[4].val[1] = vaddq_s32(step1[4].val[1], step1[5].val[1]); - step2[5].val[0] = vsubq_s32(step1[4].val[0], step1[5].val[0]); - step2[5].val[1] = vsubq_s32(step1[4].val[1], step1[5].val[1]); - step2[6].val[0] = vsubq_s32(step1[7].val[0], step1[6].val[0]); - step2[6].val[1] = vsubq_s32(step1[7].val[1], step1[6].val[1]); - step2[7].val[0] = vaddq_s32(step1[7].val[0], step1[6].val[0]); - step2[7].val[1] = vaddq_s32(step1[7].val[1], step1[6].val[1]); - step2[8] = step1[8]; - highbd_idct_cospi_8_24_q(step1[14], step1[9], cospi_0_8_16_24, &step2[9], - &step2[14]); - highbd_idct_cospi_8_24_neg_q(step1[13], step1[10], cospi_0_8_16_24, - &step2[13], &step2[10]); - step2[11] = step1[11]; - step2[12] = step1[12]; - step2[15] = step1[15]; - - // stage 5 - step1[0].val[0] = vaddq_s32(step2[0].val[0], step2[3].val[0]); - step1[0].val[1] = vaddq_s32(step2[0].val[1], step2[3].val[1]); - step1[1].val[0] = vaddq_s32(step2[1].val[0], step2[2].val[0]); - step1[1].val[1] = vaddq_s32(step2[1].val[1], step2[2].val[1]); - step1[2].val[0] = vsubq_s32(step2[1].val[0], step2[2].val[0]); - step1[2].val[1] = vsubq_s32(step2[1].val[1], step2[2].val[1]); - step1[3].val[0] = vsubq_s32(step2[0].val[0], step2[3].val[0]); - step1[3].val[1] = vsubq_s32(step2[0].val[1], step2[3].val[1]); - step1[4] = step2[4]; - highbd_idct_cospi_16_16_q(step2[5], step2[6], cospi_0_8_16_24, &step1[5], - &step1[6]); - step1[7] = step2[7]; - step1[8].val[0] = vaddq_s32(step2[8].val[0], step2[11].val[0]); - step1[8].val[1] = vaddq_s32(step2[8].val[1], step2[11].val[1]); - step1[9].val[0] = vaddq_s32(step2[9].val[0], step2[10].val[0]); - step1[9].val[1] = vaddq_s32(step2[9].val[1], step2[10].val[1]); - step1[10].val[0] = vsubq_s32(step2[9].val[0], step2[10].val[0]); - step1[10].val[1] = vsubq_s32(step2[9].val[1], step2[10].val[1]); - step1[11].val[0] = vsubq_s32(step2[8].val[0], step2[11].val[0]); - step1[11].val[1] = vsubq_s32(step2[8].val[1], step2[11].val[1]); - step1[12].val[0] = vsubq_s32(step2[15].val[0], step2[12].val[0]); - step1[12].val[1] = vsubq_s32(step2[15].val[1], step2[12].val[1]); - step1[13].val[0] = vsubq_s32(step2[14].val[0], step2[13].val[0]); - step1[13].val[1] = vsubq_s32(step2[14].val[1], step2[13].val[1]); - step1[14].val[0] = vaddq_s32(step2[14].val[0], step2[13].val[0]); - step1[14].val[1] = vaddq_s32(step2[14].val[1], step2[13].val[1]); - step1[15].val[0] = vaddq_s32(step2[15].val[0], step2[12].val[0]); - step1[15].val[1] = vaddq_s32(step2[15].val[1], step2[12].val[1]); - - // stage 6 - step2[0].val[0] = vaddq_s32(step1[0].val[0], step1[7].val[0]); - step2[0].val[1] = vaddq_s32(step1[0].val[1], step1[7].val[1]); - step2[1].val[0] = vaddq_s32(step1[1].val[0], step1[6].val[0]); - step2[1].val[1] = vaddq_s32(step1[1].val[1], step1[6].val[1]); - step2[2].val[0] = vaddq_s32(step1[2].val[0], step1[5].val[0]); - step2[2].val[1] = vaddq_s32(step1[2].val[1], step1[5].val[1]); - step2[3].val[0] = vaddq_s32(step1[3].val[0], step1[4].val[0]); - step2[3].val[1] = vaddq_s32(step1[3].val[1], step1[4].val[1]); - step2[4].val[0] = vsubq_s32(step1[3].val[0], step1[4].val[0]); - step2[4].val[1] = vsubq_s32(step1[3].val[1], step1[4].val[1]); - step2[5].val[0] = vsubq_s32(step1[2].val[0], step1[5].val[0]); - step2[5].val[1] = vsubq_s32(step1[2].val[1], step1[5].val[1]); - step2[6].val[0] = vsubq_s32(step1[1].val[0], step1[6].val[0]); - step2[6].val[1] = vsubq_s32(step1[1].val[1], step1[6].val[1]); - step2[7].val[0] = vsubq_s32(step1[0].val[0], step1[7].val[0]); - step2[7].val[1] = vsubq_s32(step1[0].val[1], step1[7].val[1]); - highbd_idct_cospi_16_16_q(step1[10], step1[13], cospi_0_8_16_24, &step2[10], - &step2[13]); - highbd_idct_cospi_16_16_q(step1[11], step1[12], cospi_0_8_16_24, &step2[11], - &step2[12]); - step2[8] = step1[8]; - step2[9] = step1[9]; - step2[14] = step1[14]; - step2[15] = step1[15]; - - // stage 7 - highbd_idct16x16_add_stage7_dual(step2, out); - - if (output) { - highbd_idct16x16_store_pass1(out, output); - } else { - highbd_idct16x16_add_store(out, dest, stride, bd); - } -} - -static INLINE int32x4x2_t highbd_idct_cospi_lane0_dual(const int32x4x2_t s, - const int32x2_t coef) { - int64x2x2_t t[2]; - - t[0].val[0] = vmull_lane_s32(vget_low_s32(s.val[0]), coef, 0); - t[0].val[1] = vmull_lane_s32(vget_high_s32(s.val[0]), coef, 0); - t[1].val[0] = vmull_lane_s32(vget_low_s32(s.val[1]), coef, 0); - t[1].val[1] = vmull_lane_s32(vget_high_s32(s.val[1]), coef, 0); - return dct_const_round_shift_high_4x2_int64x2x2(t); -} - -static INLINE int32x4_t highbd_idct_cospi_lane0(const int32x4_t s, - const int32x2_t coef) { - int64x2x2_t t; - - t.val[0] = vmull_lane_s32(vget_low_s32(s), coef, 0); - t.val[1] = vmull_lane_s32(vget_high_s32(s), coef, 0); - return dct_const_round_shift_high_4(t); -} - -static INLINE int32x4x2_t highbd_idct_cospi_lane1_dual(const int32x4x2_t s, - const int32x2_t coef) { - int64x2x2_t t[2]; - - t[0].val[0] = vmull_lane_s32(vget_low_s32(s.val[0]), coef, 1); - t[0].val[1] = vmull_lane_s32(vget_high_s32(s.val[0]), coef, 1); - t[1].val[0] = vmull_lane_s32(vget_low_s32(s.val[1]), coef, 1); - t[1].val[1] = vmull_lane_s32(vget_high_s32(s.val[1]), coef, 1); - return dct_const_round_shift_high_4x2_int64x2x2(t); -} - -static INLINE int32x4_t highbd_idct_cospi_lane1(const int32x4_t s, - const int32x2_t coef) { - int64x2x2_t t; - - t.val[0] = vmull_lane_s32(vget_low_s32(s), coef, 1); - t.val[1] = vmull_lane_s32(vget_high_s32(s), coef, 1); - return dct_const_round_shift_high_4(t); -} - -static void vpx_highbd_idct16x16_38_add_half1d(const int32_t *input, - int32_t *output, uint16_t *dest, - const int stride, const int bd) { - const int32x4_t cospi_0_8_16_24 = vld1q_s32(kCospi32 + 0); - const int32x4_t cospi_4_12_20N_28 = vld1q_s32(kCospi32 + 4); - const int32x4_t cospi_2_30_10_22 = vld1q_s32(kCospi32 + 8); - const int32x4_t cospi_6_26N_14_18N = vld1q_s32(kCospi32 + 12); - int32x4x2_t in[8], step1[16], step2[16], out[16]; - - // Load input (8x8) - in[0].val[0] = vld1q_s32(input); - in[0].val[1] = vld1q_s32(input + 4); - input += 16; - in[1].val[0] = vld1q_s32(input); - in[1].val[1] = vld1q_s32(input + 4); - input += 16; - in[2].val[0] = vld1q_s32(input); - in[2].val[1] = vld1q_s32(input + 4); - input += 16; - in[3].val[0] = vld1q_s32(input); - in[3].val[1] = vld1q_s32(input + 4); - input += 16; - in[4].val[0] = vld1q_s32(input); - in[4].val[1] = vld1q_s32(input + 4); - input += 16; - in[5].val[0] = vld1q_s32(input); - in[5].val[1] = vld1q_s32(input + 4); - input += 16; - in[6].val[0] = vld1q_s32(input); - in[6].val[1] = vld1q_s32(input + 4); - input += 16; - in[7].val[0] = vld1q_s32(input); - in[7].val[1] = vld1q_s32(input + 4); - - // Transpose - transpose_s32_8x8(&in[0], &in[1], &in[2], &in[3], &in[4], &in[5], &in[6], - &in[7]); - - // stage 1 - step1[0] = in[0 / 2]; - step1[2] = in[8 / 2]; - step1[4] = in[4 / 2]; - step1[6] = in[12 / 2]; - step1[8] = in[2 / 2]; - step1[10] = in[10 / 2]; - step1[12] = in[6 / 2]; - step1[14] = in[14 / 2]; // 0 in pass 1 - - // stage 2 - step2[0] = step1[0]; - step2[2] = step1[2]; - step2[4] = step1[4]; - step2[6] = step1[6]; - step2[8] = - highbd_idct_cospi_lane1_dual(step1[8], vget_low_s32(cospi_2_30_10_22)); - step2[9] = highbd_idct_cospi_lane1_dual(step1[14], - vget_high_s32(cospi_6_26N_14_18N)); - step2[10] = - highbd_idct_cospi_lane1_dual(step1[10], vget_high_s32(cospi_2_30_10_22)); - step2[11] = - highbd_idct_cospi_lane1_dual(step1[12], vget_low_s32(cospi_6_26N_14_18N)); - step2[12] = - highbd_idct_cospi_lane0_dual(step1[12], vget_low_s32(cospi_6_26N_14_18N)); - step2[13] = - highbd_idct_cospi_lane0_dual(step1[10], vget_high_s32(cospi_2_30_10_22)); - step2[14] = highbd_idct_cospi_lane0_dual(step1[14], - vget_high_s32(cospi_6_26N_14_18N)); - step2[15] = - highbd_idct_cospi_lane0_dual(step1[8], vget_low_s32(cospi_2_30_10_22)); - - // stage 3 - step1[0] = step2[0]; - step1[2] = step2[2]; - step1[4] = - highbd_idct_cospi_lane1_dual(step2[4], vget_high_s32(cospi_4_12_20N_28)); - step1[5] = - highbd_idct_cospi_lane0_dual(step2[6], vget_high_s32(cospi_4_12_20N_28)); - step1[6] = - highbd_idct_cospi_lane1_dual(step2[6], vget_low_s32(cospi_4_12_20N_28)); - step1[7] = - highbd_idct_cospi_lane0_dual(step2[4], vget_low_s32(cospi_4_12_20N_28)); - step1[8] = highbd_idct_add_dual(step2[8], step2[9]); - step1[9] = highbd_idct_sub_dual(step2[8], step2[9]); - step1[10] = highbd_idct_sub_dual(step2[11], step2[10]); - step1[11] = highbd_idct_add_dual(step2[11], step2[10]); - step1[12] = highbd_idct_add_dual(step2[12], step2[13]); - step1[13] = highbd_idct_sub_dual(step2[12], step2[13]); - step1[14] = highbd_idct_sub_dual(step2[15], step2[14]); - step1[15] = highbd_idct_add_dual(step2[15], step2[14]); - - // stage 4 - step2[0] = step2[1] = - highbd_idct_cospi_lane0_dual(step1[0], vget_high_s32(cospi_0_8_16_24)); - step2[2] = - highbd_idct_cospi_lane1_dual(step1[2], vget_high_s32(cospi_0_8_16_24)); - step2[3] = - highbd_idct_cospi_lane1_dual(step1[2], vget_low_s32(cospi_0_8_16_24)); - step2[4] = highbd_idct_add_dual(step1[4], step1[5]); - step2[5] = highbd_idct_sub_dual(step1[4], step1[5]); - step2[6] = highbd_idct_sub_dual(step1[7], step1[6]); - step2[7] = highbd_idct_add_dual(step1[7], step1[6]); - step2[8] = step1[8]; - highbd_idct_cospi_8_24_q(step1[14], step1[9], cospi_0_8_16_24, &step2[9], - &step2[14]); - highbd_idct_cospi_8_24_neg_q(step1[13], step1[10], cospi_0_8_16_24, - &step2[13], &step2[10]); - step2[11] = step1[11]; - step2[12] = step1[12]; - step2[15] = step1[15]; - - // stage 5 - step1[0] = highbd_idct_add_dual(step2[0], step2[3]); - step1[1] = highbd_idct_add_dual(step2[1], step2[2]); - step1[2] = highbd_idct_sub_dual(step2[1], step2[2]); - step1[3] = highbd_idct_sub_dual(step2[0], step2[3]); - step1[4] = step2[4]; - highbd_idct_cospi_16_16_q(step2[5], step2[6], cospi_0_8_16_24, &step1[5], - &step1[6]); - step1[7] = step2[7]; - step1[8] = highbd_idct_add_dual(step2[8], step2[11]); - step1[9] = highbd_idct_add_dual(step2[9], step2[10]); - step1[10] = highbd_idct_sub_dual(step2[9], step2[10]); - step1[11] = highbd_idct_sub_dual(step2[8], step2[11]); - step1[12] = highbd_idct_sub_dual(step2[15], step2[12]); - step1[13] = highbd_idct_sub_dual(step2[14], step2[13]); - step1[14] = highbd_idct_add_dual(step2[14], step2[13]); - step1[15] = highbd_idct_add_dual(step2[15], step2[12]); - - // stage 6 - step2[0] = highbd_idct_add_dual(step1[0], step1[7]); - step2[1] = highbd_idct_add_dual(step1[1], step1[6]); - step2[2] = highbd_idct_add_dual(step1[2], step1[5]); - step2[3] = highbd_idct_add_dual(step1[3], step1[4]); - step2[4] = highbd_idct_sub_dual(step1[3], step1[4]); - step2[5] = highbd_idct_sub_dual(step1[2], step1[5]); - step2[6] = highbd_idct_sub_dual(step1[1], step1[6]); - step2[7] = highbd_idct_sub_dual(step1[0], step1[7]); - highbd_idct_cospi_16_16_q(step1[10], step1[13], cospi_0_8_16_24, &step2[10], - &step2[13]); - highbd_idct_cospi_16_16_q(step1[11], step1[12], cospi_0_8_16_24, &step2[11], - &step2[12]); - step2[8] = step1[8]; - step2[9] = step1[9]; - step2[14] = step1[14]; - step2[15] = step1[15]; - - // stage 7 - highbd_idct16x16_add_stage7_dual(step2, out); - - if (output) { - highbd_idct16x16_store_pass1(out, output); - } else { - highbd_idct16x16_add_store(out, dest, stride, bd); - } -} - -static void highbd_idct16x16_10_add_half1d_pass1(const tran_low_t *input, - int32_t *output) { - const int32x4_t cospi_0_8_16_24 = vld1q_s32(kCospi32 + 0); - const int32x4_t cospi_4_12_20N_28 = vld1q_s32(kCospi32 + 4); - const int32x4_t cospi_2_30_10_22 = vld1q_s32(kCospi32 + 8); - const int32x4_t cospi_6_26N_14_18N = vld1q_s32(kCospi32 + 12); - int32x4_t in[4], step1[16], step2[16], out[16]; - - // Load input (4x4) - in[0] = vld1q_s32(input); - input += 16; - in[1] = vld1q_s32(input); - input += 16; - in[2] = vld1q_s32(input); - input += 16; - in[3] = vld1q_s32(input); - - // Transpose - transpose_s32_4x4(&in[0], &in[1], &in[2], &in[3]); - - // stage 1 - step1[0] = in[0 / 2]; - step1[4] = in[4 / 2]; - step1[8] = in[2 / 2]; - step1[12] = in[6 / 2]; - - // stage 2 - step2[0] = step1[0]; - step2[4] = step1[4]; - step2[8] = highbd_idct_cospi_lane1(step1[8], vget_low_s32(cospi_2_30_10_22)); - step2[11] = - highbd_idct_cospi_lane1(step1[12], vget_low_s32(cospi_6_26N_14_18N)); - step2[12] = - highbd_idct_cospi_lane0(step1[12], vget_low_s32(cospi_6_26N_14_18N)); - step2[15] = highbd_idct_cospi_lane0(step1[8], vget_low_s32(cospi_2_30_10_22)); - - // stage 3 - step1[0] = step2[0]; - step1[4] = - highbd_idct_cospi_lane1(step2[4], vget_high_s32(cospi_4_12_20N_28)); - step1[7] = highbd_idct_cospi_lane0(step2[4], vget_low_s32(cospi_4_12_20N_28)); - step1[8] = step2[8]; - step1[9] = step2[8]; - step1[10] = step2[11]; - step1[11] = step2[11]; - step1[12] = step2[12]; - step1[13] = step2[12]; - step1[14] = step2[15]; - step1[15] = step2[15]; - - // stage 4 - step2[0] = step2[1] = - highbd_idct_cospi_lane0(step1[0], vget_high_s32(cospi_0_8_16_24)); - step2[4] = step1[4]; - step2[5] = step1[4]; - step2[6] = step1[7]; - step2[7] = step1[7]; - step2[8] = step1[8]; - highbd_idct_cospi_8_24_d(step1[14], step1[9], cospi_0_8_16_24, &step2[9], - &step2[14]); - highbd_idct_cospi_8_24_neg_d(step1[13], step1[10], cospi_0_8_16_24, - &step2[13], &step2[10]); - step2[11] = step1[11]; - step2[12] = step1[12]; - step2[15] = step1[15]; - - // stage 5 - step1[0] = step2[0]; - step1[1] = step2[1]; - step1[2] = step2[1]; - step1[3] = step2[0]; - step1[4] = step2[4]; - highbd_idct_cospi_16_16_d(step2[5], step2[6], cospi_0_8_16_24, &step1[5], - &step1[6]); - step1[7] = step2[7]; - step1[8] = vaddq_s32(step2[8], step2[11]); - step1[9] = vaddq_s32(step2[9], step2[10]); - step1[10] = vsubq_s32(step2[9], step2[10]); - step1[11] = vsubq_s32(step2[8], step2[11]); - step1[12] = vsubq_s32(step2[15], step2[12]); - step1[13] = vsubq_s32(step2[14], step2[13]); - step1[14] = vaddq_s32(step2[14], step2[13]); - step1[15] = vaddq_s32(step2[15], step2[12]); - - // stage 6 - step2[0] = vaddq_s32(step1[0], step1[7]); - step2[1] = vaddq_s32(step1[1], step1[6]); - step2[2] = vaddq_s32(step1[2], step1[5]); - step2[3] = vaddq_s32(step1[3], step1[4]); - step2[4] = vsubq_s32(step1[3], step1[4]); - step2[5] = vsubq_s32(step1[2], step1[5]); - step2[6] = vsubq_s32(step1[1], step1[6]); - step2[7] = vsubq_s32(step1[0], step1[7]); - highbd_idct_cospi_16_16_d(step1[10], step1[13], cospi_0_8_16_24, &step2[10], - &step2[13]); - highbd_idct_cospi_16_16_d(step1[11], step1[12], cospi_0_8_16_24, &step2[11], - &step2[12]); - step2[8] = step1[8]; - step2[9] = step1[9]; - step2[14] = step1[14]; - step2[15] = step1[15]; - - // stage 7 - highbd_idct16x16_add_stage7(step2, out); - - // pass 1: save the result into output - vst1q_s32(output, out[0]); - output += 4; - vst1q_s32(output, out[1]); - output += 4; - vst1q_s32(output, out[2]); - output += 4; - vst1q_s32(output, out[3]); - output += 4; - vst1q_s32(output, out[4]); - output += 4; - vst1q_s32(output, out[5]); - output += 4; - vst1q_s32(output, out[6]); - output += 4; - vst1q_s32(output, out[7]); - output += 4; - vst1q_s32(output, out[8]); - output += 4; - vst1q_s32(output, out[9]); - output += 4; - vst1q_s32(output, out[10]); - output += 4; - vst1q_s32(output, out[11]); - output += 4; - vst1q_s32(output, out[12]); - output += 4; - vst1q_s32(output, out[13]); - output += 4; - vst1q_s32(output, out[14]); - output += 4; - vst1q_s32(output, out[15]); -} - -static void highbd_idct16x16_10_add_half1d_pass2(const int32_t *input, - int32_t *const output, - uint16_t *const dest, - const int stride, - const int bd) { - const int32x4_t cospi_0_8_16_24 = vld1q_s32(kCospi32 + 0); - const int32x4_t cospi_4_12_20N_28 = vld1q_s32(kCospi32 + 4); - const int32x4_t cospi_2_30_10_22 = vld1q_s32(kCospi32 + 8); - const int32x4_t cospi_6_26N_14_18N = vld1q_s32(kCospi32 + 12); - int32x4x2_t in[4], step1[16], step2[16], out[16]; - - // Load input (4x8) - in[0].val[0] = vld1q_s32(input); - input += 4; - in[0].val[1] = vld1q_s32(input); - input += 4; - in[1].val[0] = vld1q_s32(input); - input += 4; - in[1].val[1] = vld1q_s32(input); - input += 4; - in[2].val[0] = vld1q_s32(input); - input += 4; - in[2].val[1] = vld1q_s32(input); - input += 4; - in[3].val[0] = vld1q_s32(input); - input += 4; - in[3].val[1] = vld1q_s32(input); - - // Transpose - transpose_s32_4x8(&in[0].val[0], &in[0].val[1], &in[1].val[0], &in[1].val[1], - &in[2].val[0], &in[2].val[1], &in[3].val[0], &in[3].val[1]); - - // stage 1 - step1[0] = in[0 / 2]; - step1[4] = in[4 / 2]; - step1[8] = in[2 / 2]; - step1[12] = in[6 / 2]; - - // stage 2 - step2[0] = step1[0]; - step2[4] = step1[4]; - step2[8] = - highbd_idct_cospi_lane1_dual(step1[8], vget_low_s32(cospi_2_30_10_22)); - step2[11] = - highbd_idct_cospi_lane1_dual(step1[12], vget_low_s32(cospi_6_26N_14_18N)); - step2[12] = - highbd_idct_cospi_lane0_dual(step1[12], vget_low_s32(cospi_6_26N_14_18N)); - step2[15] = - highbd_idct_cospi_lane0_dual(step1[8], vget_low_s32(cospi_2_30_10_22)); - - // stage 3 - step1[0] = step2[0]; - step1[4] = - highbd_idct_cospi_lane1_dual(step2[4], vget_high_s32(cospi_4_12_20N_28)); - step1[7] = - highbd_idct_cospi_lane0_dual(step2[4], vget_low_s32(cospi_4_12_20N_28)); - step1[8] = step2[8]; - step1[9] = step2[8]; - step1[10] = step2[11]; - step1[11] = step2[11]; - step1[12] = step2[12]; - step1[13] = step2[12]; - step1[14] = step2[15]; - step1[15] = step2[15]; - - // stage 4 - step2[0] = step2[1] = - highbd_idct_cospi_lane0_dual(step1[0], vget_high_s32(cospi_0_8_16_24)); - step2[4] = step1[4]; - step2[5] = step1[4]; - step2[6] = step1[7]; - step2[7] = step1[7]; - step2[8] = step1[8]; - highbd_idct_cospi_8_24_q(step1[14], step1[9], cospi_0_8_16_24, &step2[9], - &step2[14]); - highbd_idct_cospi_8_24_neg_q(step1[13], step1[10], cospi_0_8_16_24, - &step2[13], &step2[10]); - step2[11] = step1[11]; - step2[12] = step1[12]; - step2[15] = step1[15]; - - // stage 5 - step1[0] = step2[0]; - step1[1] = step2[1]; - step1[2] = step2[1]; - step1[3] = step2[0]; - step1[4] = step2[4]; - highbd_idct_cospi_16_16_q(step2[5], step2[6], cospi_0_8_16_24, &step1[5], - &step1[6]); - step1[7] = step2[7]; - step1[8] = highbd_idct_add_dual(step2[8], step2[11]); - step1[9] = highbd_idct_add_dual(step2[9], step2[10]); - step1[10] = highbd_idct_sub_dual(step2[9], step2[10]); - step1[11] = highbd_idct_sub_dual(step2[8], step2[11]); - step1[12] = highbd_idct_sub_dual(step2[15], step2[12]); - step1[13] = highbd_idct_sub_dual(step2[14], step2[13]); - step1[14] = highbd_idct_add_dual(step2[14], step2[13]); - step1[15] = highbd_idct_add_dual(step2[15], step2[12]); - - // stage 6 - step2[0] = highbd_idct_add_dual(step1[0], step1[7]); - step2[1] = highbd_idct_add_dual(step1[1], step1[6]); - step2[2] = highbd_idct_add_dual(step1[2], step1[5]); - step2[3] = highbd_idct_add_dual(step1[3], step1[4]); - step2[4] = highbd_idct_sub_dual(step1[3], step1[4]); - step2[5] = highbd_idct_sub_dual(step1[2], step1[5]); - step2[6] = highbd_idct_sub_dual(step1[1], step1[6]); - step2[7] = highbd_idct_sub_dual(step1[0], step1[7]); - highbd_idct_cospi_16_16_q(step1[10], step1[13], cospi_0_8_16_24, &step2[10], - &step2[13]); - highbd_idct_cospi_16_16_q(step1[11], step1[12], cospi_0_8_16_24, &step2[11], - &step2[12]); - step2[8] = step1[8]; - step2[9] = step1[9]; - step2[14] = step1[14]; - step2[15] = step1[15]; - - // stage 7 - highbd_idct16x16_add_stage7_dual(step2, out); - - if (output) { - highbd_idct16x16_store_pass1(out, output); - } else { - highbd_idct16x16_add_store(out, dest, stride, bd); - } -} - -void vpx_highbd_idct16x16_256_add_neon(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - if (bd == 8) { - int16_t row_idct_output[16 * 16]; - - // pass 1 - // Parallel idct on the upper 8 rows - vpx_idct16x16_256_add_half1d(input, row_idct_output, dest, stride, 1); - - // Parallel idct on the lower 8 rows - vpx_idct16x16_256_add_half1d(input + 8 * 16, row_idct_output + 8, dest, - stride, 1); - - // pass 2 - // Parallel idct to get the left 8 columns - vpx_idct16x16_256_add_half1d(row_idct_output, NULL, dest, stride, 1); - - // Parallel idct to get the right 8 columns - vpx_idct16x16_256_add_half1d(row_idct_output + 8 * 16, NULL, dest + 8, - stride, 1); - } else { - int32_t row_idct_output[16 * 16]; - - // pass 1 - // Parallel idct on the upper 8 rows - vpx_highbd_idct16x16_256_add_half1d(input, row_idct_output, dest, stride, - bd); - - // Parallel idct on the lower 8 rows - vpx_highbd_idct16x16_256_add_half1d(input + 8 * 16, row_idct_output + 8, - dest, stride, bd); - - // pass 2 - // Parallel idct to get the left 8 columns - vpx_highbd_idct16x16_256_add_half1d(row_idct_output, NULL, dest, stride, - bd); - - // Parallel idct to get the right 8 columns - vpx_highbd_idct16x16_256_add_half1d(row_idct_output + 8 * 16, NULL, - dest + 8, stride, bd); - } -} - -void vpx_highbd_idct16x16_38_add_neon(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - if (bd == 8) { - int16_t row_idct_output[16 * 16]; - - // pass 1 - // Parallel idct on the upper 8 rows - vpx_idct16x16_38_add_half1d(input, row_idct_output, dest, stride, 1); - - // pass 2 - // Parallel idct to get the left 8 columns - vpx_idct16x16_38_add_half1d(row_idct_output, NULL, dest, stride, 1); - - // Parallel idct to get the right 8 columns - vpx_idct16x16_38_add_half1d(row_idct_output + 16 * 8, NULL, dest + 8, - stride, 1); - } else { - int32_t row_idct_output[16 * 16]; - - // pass 1 - // Parallel idct on the upper 8 rows - vpx_highbd_idct16x16_38_add_half1d(input, row_idct_output, dest, stride, - bd); - - // pass 2 - // Parallel idct to get the left 8 columns - vpx_highbd_idct16x16_38_add_half1d(row_idct_output, NULL, dest, stride, bd); - - // Parallel idct to get the right 8 columns - vpx_highbd_idct16x16_38_add_half1d(row_idct_output + 16 * 8, NULL, dest + 8, - stride, bd); - } -} - -void vpx_highbd_idct16x16_10_add_neon(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - if (bd == 8) { - int16_t row_idct_output[4 * 16]; - - // pass 1 - // Parallel idct on the upper 8 rows - vpx_idct16x16_10_add_half1d_pass1(input, row_idct_output); - - // pass 2 - // Parallel idct to get the left 8 columns - vpx_idct16x16_10_add_half1d_pass2(row_idct_output, NULL, dest, stride, 1); - - // Parallel idct to get the right 8 columns - vpx_idct16x16_10_add_half1d_pass2(row_idct_output + 4 * 8, NULL, dest + 8, - stride, 1); - } else { - int32_t row_idct_output[4 * 16]; - - // pass 1 - // Parallel idct on the upper 8 rows - highbd_idct16x16_10_add_half1d_pass1(input, row_idct_output); - - // pass 2 - // Parallel idct to get the left 8 columns - highbd_idct16x16_10_add_half1d_pass2(row_idct_output, NULL, dest, stride, - bd); - - // Parallel idct to get the right 8 columns - highbd_idct16x16_10_add_half1d_pass2(row_idct_output + 4 * 8, NULL, - dest + 8, stride, bd); - } -} - -static INLINE void highbd_idct16x16_1_add_pos_kernel(uint16_t **dest, - const int stride, - const int16x8_t res, - const int16x8_t max) { - const uint16x8_t a0 = vld1q_u16(*dest + 0); - const uint16x8_t a1 = vld1q_u16(*dest + 8); - const int16x8_t b0 = vaddq_s16(res, vreinterpretq_s16_u16(a0)); - const int16x8_t b1 = vaddq_s16(res, vreinterpretq_s16_u16(a1)); - const int16x8_t c0 = vminq_s16(b0, max); - const int16x8_t c1 = vminq_s16(b1, max); - vst1q_u16(*dest + 0, vreinterpretq_u16_s16(c0)); - vst1q_u16(*dest + 8, vreinterpretq_u16_s16(c1)); - *dest += stride; -} - -static INLINE void highbd_idct16x16_1_add_neg_kernel(uint16_t **dest, - const int stride, - const int16x8_t res) { - const uint16x8_t a0 = vld1q_u16(*dest + 0); - const uint16x8_t a1 = vld1q_u16(*dest + 8); - const int16x8_t b0 = vaddq_s16(res, vreinterpretq_s16_u16(a0)); - const int16x8_t b1 = vaddq_s16(res, vreinterpretq_s16_u16(a1)); - const uint16x8_t c0 = vqshluq_n_s16(b0, 0); - const uint16x8_t c1 = vqshluq_n_s16(b1, 0); - vst1q_u16(*dest + 0, c0); - vst1q_u16(*dest + 8, c1); - *dest += stride; -} - -void vpx_highbd_idct16x16_1_add_neon(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - const tran_low_t out0 = HIGHBD_WRAPLOW( - dct_const_round_shift(input[0] * (tran_high_t)cospi_16_64), bd); - const tran_low_t out1 = HIGHBD_WRAPLOW( - dct_const_round_shift(out0 * (tran_high_t)cospi_16_64), bd); - const int16_t a1 = ROUND_POWER_OF_TWO(out1, 6); - const int16x8_t dc = vdupq_n_s16(a1); - int i; - - if (a1 >= 0) { - const int16x8_t max = vdupq_n_s16((1 << bd) - 1); - for (i = 0; i < 4; ++i) { - highbd_idct16x16_1_add_pos_kernel(&dest, stride, dc, max); - highbd_idct16x16_1_add_pos_kernel(&dest, stride, dc, max); - highbd_idct16x16_1_add_pos_kernel(&dest, stride, dc, max); - highbd_idct16x16_1_add_pos_kernel(&dest, stride, dc, max); - } - } else { - for (i = 0; i < 4; ++i) { - highbd_idct16x16_1_add_neg_kernel(&dest, stride, dc); - highbd_idct16x16_1_add_neg_kernel(&dest, stride, dc); - highbd_idct16x16_1_add_neg_kernel(&dest, stride, dc); - highbd_idct16x16_1_add_neg_kernel(&dest, stride, dc); - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct32x32_1024_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct32x32_1024_add_neon.c deleted file mode 100644 index 5b36f733..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct32x32_1024_add_neon.c +++ /dev/null @@ -1,640 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/txfm_common.h" - -static INLINE void load_from_transformed(const int32_t *const trans_buf, - const int first, const int second, - int32x4x2_t *const q0, - int32x4x2_t *const q1) { - q0->val[0] = vld1q_s32(trans_buf + first * 8); - q0->val[1] = vld1q_s32(trans_buf + first * 8 + 4); - q1->val[0] = vld1q_s32(trans_buf + second * 8); - q1->val[1] = vld1q_s32(trans_buf + second * 8 + 4); -} - -static INLINE void load_from_output(const int32_t *const out, const int first, - const int second, int32x4x2_t *const q0, - int32x4x2_t *const q1) { - q0->val[0] = vld1q_s32(out + first * 32); - q0->val[1] = vld1q_s32(out + first * 32 + 4); - q1->val[0] = vld1q_s32(out + second * 32); - q1->val[1] = vld1q_s32(out + second * 32 + 4); -} - -static INLINE void store_in_output(int32_t *const out, const int first, - const int second, const int32x4x2_t q0, - const int32x4x2_t q1) { - vst1q_s32(out + first * 32, q0.val[0]); - vst1q_s32(out + first * 32 + 4, q0.val[1]); - vst1q_s32(out + second * 32, q1.val[0]); - vst1q_s32(out + second * 32 + 4, q1.val[1]); -} - -static INLINE void highbd_store_combine_results( - uint16_t *p1, uint16_t *p2, const int stride, const int32x4x2_t q0, - const int32x4x2_t q1, const int32x4x2_t q2, const int32x4x2_t q3, - const int16x8_t max) { - int16x8_t o[4]; - uint16x8_t d[4]; - - d[0] = vld1q_u16(p1); - p1 += stride; - d[1] = vld1q_u16(p1); - d[3] = vld1q_u16(p2); - p2 -= stride; - d[2] = vld1q_u16(p2); - - o[0] = vcombine_s16(vrshrn_n_s32(q0.val[0], 6), vrshrn_n_s32(q0.val[1], 6)); - o[1] = vcombine_s16(vrshrn_n_s32(q1.val[0], 6), vrshrn_n_s32(q1.val[1], 6)); - o[2] = vcombine_s16(vrshrn_n_s32(q2.val[0], 6), vrshrn_n_s32(q2.val[1], 6)); - o[3] = vcombine_s16(vrshrn_n_s32(q3.val[0], 6), vrshrn_n_s32(q3.val[1], 6)); - - o[0] = vqaddq_s16(o[0], vreinterpretq_s16_u16(d[0])); - o[1] = vqaddq_s16(o[1], vreinterpretq_s16_u16(d[1])); - o[2] = vqaddq_s16(o[2], vreinterpretq_s16_u16(d[2])); - o[3] = vqaddq_s16(o[3], vreinterpretq_s16_u16(d[3])); - o[0] = vminq_s16(o[0], max); - o[1] = vminq_s16(o[1], max); - o[2] = vminq_s16(o[2], max); - o[3] = vminq_s16(o[3], max); - d[0] = vqshluq_n_s16(o[0], 0); - d[1] = vqshluq_n_s16(o[1], 0); - d[2] = vqshluq_n_s16(o[2], 0); - d[3] = vqshluq_n_s16(o[3], 0); - - vst1q_u16(p1, d[1]); - p1 -= stride; - vst1q_u16(p1, d[0]); - vst1q_u16(p2, d[2]); - p2 += stride; - vst1q_u16(p2, d[3]); -} - -static INLINE void do_butterfly(const int32x4x2_t qIn0, const int32x4x2_t qIn1, - const int32_t first_const, - const int32_t second_const, - int32x4x2_t *const qOut0, - int32x4x2_t *const qOut1) { - int64x2x2_t q[4]; - int32x2_t d[6]; - - // Note: using v{mul, mla, mls}l_n_s32 here slows down 35% with gcc 4.9. - d[4] = vdup_n_s32(first_const); - d[5] = vdup_n_s32(second_const); - - q[0].val[0] = vmull_s32(vget_low_s32(qIn0.val[0]), d[4]); - q[0].val[1] = vmull_s32(vget_high_s32(qIn0.val[0]), d[4]); - q[1].val[0] = vmull_s32(vget_low_s32(qIn0.val[1]), d[4]); - q[1].val[1] = vmull_s32(vget_high_s32(qIn0.val[1]), d[4]); - q[0].val[0] = vmlsl_s32(q[0].val[0], vget_low_s32(qIn1.val[0]), d[5]); - q[0].val[1] = vmlsl_s32(q[0].val[1], vget_high_s32(qIn1.val[0]), d[5]); - q[1].val[0] = vmlsl_s32(q[1].val[0], vget_low_s32(qIn1.val[1]), d[5]); - q[1].val[1] = vmlsl_s32(q[1].val[1], vget_high_s32(qIn1.val[1]), d[5]); - - q[2].val[0] = vmull_s32(vget_low_s32(qIn0.val[0]), d[5]); - q[2].val[1] = vmull_s32(vget_high_s32(qIn0.val[0]), d[5]); - q[3].val[0] = vmull_s32(vget_low_s32(qIn0.val[1]), d[5]); - q[3].val[1] = vmull_s32(vget_high_s32(qIn0.val[1]), d[5]); - q[2].val[0] = vmlal_s32(q[2].val[0], vget_low_s32(qIn1.val[0]), d[4]); - q[2].val[1] = vmlal_s32(q[2].val[1], vget_high_s32(qIn1.val[0]), d[4]); - q[3].val[0] = vmlal_s32(q[3].val[0], vget_low_s32(qIn1.val[1]), d[4]); - q[3].val[1] = vmlal_s32(q[3].val[1], vget_high_s32(qIn1.val[1]), d[4]); - - qOut0->val[0] = vcombine_s32(vrshrn_n_s64(q[0].val[0], DCT_CONST_BITS), - vrshrn_n_s64(q[0].val[1], DCT_CONST_BITS)); - qOut0->val[1] = vcombine_s32(vrshrn_n_s64(q[1].val[0], DCT_CONST_BITS), - vrshrn_n_s64(q[1].val[1], DCT_CONST_BITS)); - qOut1->val[0] = vcombine_s32(vrshrn_n_s64(q[2].val[0], DCT_CONST_BITS), - vrshrn_n_s64(q[2].val[1], DCT_CONST_BITS)); - qOut1->val[1] = vcombine_s32(vrshrn_n_s64(q[3].val[0], DCT_CONST_BITS), - vrshrn_n_s64(q[3].val[1], DCT_CONST_BITS)); -} - -static INLINE void load_s32x4q_dual(const int32_t *in, int32x4x2_t *const s) { - s[0].val[0] = vld1q_s32(in); - s[0].val[1] = vld1q_s32(in + 4); - in += 32; - s[1].val[0] = vld1q_s32(in); - s[1].val[1] = vld1q_s32(in + 4); - in += 32; - s[2].val[0] = vld1q_s32(in); - s[2].val[1] = vld1q_s32(in + 4); - in += 32; - s[3].val[0] = vld1q_s32(in); - s[3].val[1] = vld1q_s32(in + 4); - in += 32; - s[4].val[0] = vld1q_s32(in); - s[4].val[1] = vld1q_s32(in + 4); - in += 32; - s[5].val[0] = vld1q_s32(in); - s[5].val[1] = vld1q_s32(in + 4); - in += 32; - s[6].val[0] = vld1q_s32(in); - s[6].val[1] = vld1q_s32(in + 4); - in += 32; - s[7].val[0] = vld1q_s32(in); - s[7].val[1] = vld1q_s32(in + 4); -} - -static INLINE void transpose_and_store_s32_8x8(int32x4x2_t *const a, - int32_t **out) { - transpose_s32_8x8(&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7]); - - vst1q_s32(*out, a[0].val[0]); - *out += 4; - vst1q_s32(*out, a[0].val[1]); - *out += 4; - vst1q_s32(*out, a[1].val[0]); - *out += 4; - vst1q_s32(*out, a[1].val[1]); - *out += 4; - vst1q_s32(*out, a[2].val[0]); - *out += 4; - vst1q_s32(*out, a[2].val[1]); - *out += 4; - vst1q_s32(*out, a[3].val[0]); - *out += 4; - vst1q_s32(*out, a[3].val[1]); - *out += 4; - vst1q_s32(*out, a[4].val[0]); - *out += 4; - vst1q_s32(*out, a[4].val[1]); - *out += 4; - vst1q_s32(*out, a[5].val[0]); - *out += 4; - vst1q_s32(*out, a[5].val[1]); - *out += 4; - vst1q_s32(*out, a[6].val[0]); - *out += 4; - vst1q_s32(*out, a[6].val[1]); - *out += 4; - vst1q_s32(*out, a[7].val[0]); - *out += 4; - vst1q_s32(*out, a[7].val[1]); - *out += 4; -} - -static INLINE void idct32_transpose_pair(const int32_t *input, int32_t *t_buf) { - int i; - int32x4x2_t s[8]; - - for (i = 0; i < 4; i++, input += 8) { - load_s32x4q_dual(input, s); - transpose_and_store_s32_8x8(s, &t_buf); - } -} - -static INLINE void idct32_bands_end_1st_pass(int32_t *const out, - int32x4x2_t *const q) { - store_in_output(out, 16, 17, q[6], q[7]); - store_in_output(out, 14, 15, q[8], q[9]); - - load_from_output(out, 30, 31, &q[0], &q[1]); - q[4] = highbd_idct_add_dual(q[2], q[1]); - q[5] = highbd_idct_add_dual(q[3], q[0]); - q[6] = highbd_idct_sub_dual(q[3], q[0]); - q[7] = highbd_idct_sub_dual(q[2], q[1]); - store_in_output(out, 30, 31, q[6], q[7]); - store_in_output(out, 0, 1, q[4], q[5]); - - load_from_output(out, 12, 13, &q[0], &q[1]); - q[2] = highbd_idct_add_dual(q[10], q[1]); - q[3] = highbd_idct_add_dual(q[11], q[0]); - q[4] = highbd_idct_sub_dual(q[11], q[0]); - q[5] = highbd_idct_sub_dual(q[10], q[1]); - - load_from_output(out, 18, 19, &q[0], &q[1]); - q[8] = highbd_idct_add_dual(q[4], q[1]); - q[9] = highbd_idct_add_dual(q[5], q[0]); - q[6] = highbd_idct_sub_dual(q[5], q[0]); - q[7] = highbd_idct_sub_dual(q[4], q[1]); - store_in_output(out, 18, 19, q[6], q[7]); - store_in_output(out, 12, 13, q[8], q[9]); - - load_from_output(out, 28, 29, &q[0], &q[1]); - q[4] = highbd_idct_add_dual(q[2], q[1]); - q[5] = highbd_idct_add_dual(q[3], q[0]); - q[6] = highbd_idct_sub_dual(q[3], q[0]); - q[7] = highbd_idct_sub_dual(q[2], q[1]); - store_in_output(out, 28, 29, q[6], q[7]); - store_in_output(out, 2, 3, q[4], q[5]); - - load_from_output(out, 10, 11, &q[0], &q[1]); - q[2] = highbd_idct_add_dual(q[12], q[1]); - q[3] = highbd_idct_add_dual(q[13], q[0]); - q[4] = highbd_idct_sub_dual(q[13], q[0]); - q[5] = highbd_idct_sub_dual(q[12], q[1]); - - load_from_output(out, 20, 21, &q[0], &q[1]); - q[8] = highbd_idct_add_dual(q[4], q[1]); - q[9] = highbd_idct_add_dual(q[5], q[0]); - q[6] = highbd_idct_sub_dual(q[5], q[0]); - q[7] = highbd_idct_sub_dual(q[4], q[1]); - store_in_output(out, 20, 21, q[6], q[7]); - store_in_output(out, 10, 11, q[8], q[9]); - - load_from_output(out, 26, 27, &q[0], &q[1]); - q[4] = highbd_idct_add_dual(q[2], q[1]); - q[5] = highbd_idct_add_dual(q[3], q[0]); - q[6] = highbd_idct_sub_dual(q[3], q[0]); - q[7] = highbd_idct_sub_dual(q[2], q[1]); - store_in_output(out, 26, 27, q[6], q[7]); - store_in_output(out, 4, 5, q[4], q[5]); - - load_from_output(out, 8, 9, &q[0], &q[1]); - q[2] = highbd_idct_add_dual(q[14], q[1]); - q[3] = highbd_idct_add_dual(q[15], q[0]); - q[4] = highbd_idct_sub_dual(q[15], q[0]); - q[5] = highbd_idct_sub_dual(q[14], q[1]); - - load_from_output(out, 22, 23, &q[0], &q[1]); - q[8] = highbd_idct_add_dual(q[4], q[1]); - q[9] = highbd_idct_add_dual(q[5], q[0]); - q[6] = highbd_idct_sub_dual(q[5], q[0]); - q[7] = highbd_idct_sub_dual(q[4], q[1]); - store_in_output(out, 22, 23, q[6], q[7]); - store_in_output(out, 8, 9, q[8], q[9]); - - load_from_output(out, 24, 25, &q[0], &q[1]); - q[4] = highbd_idct_add_dual(q[2], q[1]); - q[5] = highbd_idct_add_dual(q[3], q[0]); - q[6] = highbd_idct_sub_dual(q[3], q[0]); - q[7] = highbd_idct_sub_dual(q[2], q[1]); - store_in_output(out, 24, 25, q[6], q[7]); - store_in_output(out, 6, 7, q[4], q[5]); -} - -static INLINE void idct32_bands_end_2nd_pass(const int32_t *const out, - uint16_t *const dest, - const int stride, - const int16x8_t max, - int32x4x2_t *const q) { - uint16_t *dest0 = dest + 0 * stride; - uint16_t *dest1 = dest + 31 * stride; - uint16_t *dest2 = dest + 16 * stride; - uint16_t *dest3 = dest + 15 * stride; - const int str2 = stride << 1; - - highbd_store_combine_results(dest2, dest3, stride, q[6], q[7], q[8], q[9], - max); - dest2 += str2; - dest3 -= str2; - - load_from_output(out, 30, 31, &q[0], &q[1]); - q[4] = highbd_idct_add_dual(q[2], q[1]); - q[5] = highbd_idct_add_dual(q[3], q[0]); - q[6] = highbd_idct_sub_dual(q[3], q[0]); - q[7] = highbd_idct_sub_dual(q[2], q[1]); - highbd_store_combine_results(dest0, dest1, stride, q[4], q[5], q[6], q[7], - max); - dest0 += str2; - dest1 -= str2; - - load_from_output(out, 12, 13, &q[0], &q[1]); - q[2] = highbd_idct_add_dual(q[10], q[1]); - q[3] = highbd_idct_add_dual(q[11], q[0]); - q[4] = highbd_idct_sub_dual(q[11], q[0]); - q[5] = highbd_idct_sub_dual(q[10], q[1]); - - load_from_output(out, 18, 19, &q[0], &q[1]); - q[8] = highbd_idct_add_dual(q[4], q[1]); - q[9] = highbd_idct_add_dual(q[5], q[0]); - q[6] = highbd_idct_sub_dual(q[5], q[0]); - q[7] = highbd_idct_sub_dual(q[4], q[1]); - highbd_store_combine_results(dest2, dest3, stride, q[6], q[7], q[8], q[9], - max); - dest2 += str2; - dest3 -= str2; - - load_from_output(out, 28, 29, &q[0], &q[1]); - q[4] = highbd_idct_add_dual(q[2], q[1]); - q[5] = highbd_idct_add_dual(q[3], q[0]); - q[6] = highbd_idct_sub_dual(q[3], q[0]); - q[7] = highbd_idct_sub_dual(q[2], q[1]); - highbd_store_combine_results(dest0, dest1, stride, q[4], q[5], q[6], q[7], - max); - dest0 += str2; - dest1 -= str2; - - load_from_output(out, 10, 11, &q[0], &q[1]); - q[2] = highbd_idct_add_dual(q[12], q[1]); - q[3] = highbd_idct_add_dual(q[13], q[0]); - q[4] = highbd_idct_sub_dual(q[13], q[0]); - q[5] = highbd_idct_sub_dual(q[12], q[1]); - - load_from_output(out, 20, 21, &q[0], &q[1]); - q[8] = highbd_idct_add_dual(q[4], q[1]); - q[9] = highbd_idct_add_dual(q[5], q[0]); - q[6] = highbd_idct_sub_dual(q[5], q[0]); - q[7] = highbd_idct_sub_dual(q[4], q[1]); - highbd_store_combine_results(dest2, dest3, stride, q[6], q[7], q[8], q[9], - max); - dest2 += str2; - dest3 -= str2; - - load_from_output(out, 26, 27, &q[0], &q[1]); - q[4] = highbd_idct_add_dual(q[2], q[1]); - q[5] = highbd_idct_add_dual(q[3], q[0]); - q[6] = highbd_idct_sub_dual(q[3], q[0]); - q[7] = highbd_idct_sub_dual(q[2], q[1]); - highbd_store_combine_results(dest0, dest1, stride, q[4], q[5], q[6], q[7], - max); - dest0 += str2; - dest1 -= str2; - - load_from_output(out, 8, 9, &q[0], &q[1]); - q[2] = highbd_idct_add_dual(q[14], q[1]); - q[3] = highbd_idct_add_dual(q[15], q[0]); - q[4] = highbd_idct_sub_dual(q[15], q[0]); - q[5] = highbd_idct_sub_dual(q[14], q[1]); - - load_from_output(out, 22, 23, &q[0], &q[1]); - q[8] = highbd_idct_add_dual(q[4], q[1]); - q[9] = highbd_idct_add_dual(q[5], q[0]); - q[6] = highbd_idct_sub_dual(q[5], q[0]); - q[7] = highbd_idct_sub_dual(q[4], q[1]); - highbd_store_combine_results(dest2, dest3, stride, q[6], q[7], q[8], q[9], - max); - - load_from_output(out, 24, 25, &q[0], &q[1]); - q[4] = highbd_idct_add_dual(q[2], q[1]); - q[5] = highbd_idct_add_dual(q[3], q[0]); - q[6] = highbd_idct_sub_dual(q[3], q[0]); - q[7] = highbd_idct_sub_dual(q[2], q[1]); - highbd_store_combine_results(dest0, dest1, stride, q[4], q[5], q[6], q[7], - max); -} - -static INLINE void vpx_highbd_idct32_32_neon(const tran_low_t *input, - uint16_t *dst, const int stride, - const int bd) { - int i, idct32_pass_loop; - int32_t trans_buf[32 * 8]; - int32_t pass1[32 * 32]; - int32_t pass2[32 * 32]; - int32_t *out; - int32x4x2_t q[16]; - - for (idct32_pass_loop = 0, out = pass1; idct32_pass_loop < 2; - idct32_pass_loop++, input = pass1, out = pass2) { - for (i = 0; i < 4; i++, out += 8) { // idct32_bands_loop - idct32_transpose_pair(input, trans_buf); - input += 32 * 8; - - // ----------------------------------------- - // BLOCK A: 16-19,28-31 - // ----------------------------------------- - // generate 16,17,30,31 - // part of stage 1 - load_from_transformed(trans_buf, 1, 31, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_31_64, cospi_1_64, &q[0], &q[2]); - load_from_transformed(trans_buf, 17, 15, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_15_64, cospi_17_64, &q[1], &q[3]); - // part of stage 2 - q[4] = highbd_idct_add_dual(q[0], q[1]); - q[13] = highbd_idct_sub_dual(q[0], q[1]); - q[6] = highbd_idct_add_dual(q[2], q[3]); - q[14] = highbd_idct_sub_dual(q[2], q[3]); - // part of stage 3 - do_butterfly(q[14], q[13], cospi_28_64, cospi_4_64, &q[5], &q[7]); - - // generate 18,19,28,29 - // part of stage 1 - load_from_transformed(trans_buf, 9, 23, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_23_64, cospi_9_64, &q[0], &q[2]); - load_from_transformed(trans_buf, 25, 7, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_7_64, cospi_25_64, &q[1], &q[3]); - // part of stage 2 - q[13] = highbd_idct_sub_dual(q[3], q[2]); - q[3] = highbd_idct_add_dual(q[3], q[2]); - q[14] = highbd_idct_sub_dual(q[1], q[0]); - q[2] = highbd_idct_add_dual(q[1], q[0]); - // part of stage 3 - do_butterfly(q[14], q[13], -cospi_4_64, -cospi_28_64, &q[1], &q[0]); - // part of stage 4 - q[8] = highbd_idct_add_dual(q[4], q[2]); - q[9] = highbd_idct_add_dual(q[5], q[0]); - q[10] = highbd_idct_add_dual(q[7], q[1]); - q[15] = highbd_idct_add_dual(q[6], q[3]); - q[13] = highbd_idct_sub_dual(q[5], q[0]); - q[14] = highbd_idct_sub_dual(q[7], q[1]); - store_in_output(out, 16, 31, q[8], q[15]); - store_in_output(out, 17, 30, q[9], q[10]); - // part of stage 5 - do_butterfly(q[14], q[13], cospi_24_64, cospi_8_64, &q[0], &q[1]); - store_in_output(out, 29, 18, q[1], q[0]); - // part of stage 4 - q[13] = highbd_idct_sub_dual(q[4], q[2]); - q[14] = highbd_idct_sub_dual(q[6], q[3]); - // part of stage 5 - do_butterfly(q[14], q[13], cospi_24_64, cospi_8_64, &q[4], &q[6]); - store_in_output(out, 19, 28, q[4], q[6]); - - // ----------------------------------------- - // BLOCK B: 20-23,24-27 - // ----------------------------------------- - // generate 20,21,26,27 - // part of stage 1 - load_from_transformed(trans_buf, 5, 27, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_27_64, cospi_5_64, &q[0], &q[2]); - load_from_transformed(trans_buf, 21, 11, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_11_64, cospi_21_64, &q[1], &q[3]); - // part of stage 2 - q[13] = highbd_idct_sub_dual(q[0], q[1]); - q[0] = highbd_idct_add_dual(q[0], q[1]); - q[14] = highbd_idct_sub_dual(q[2], q[3]); - q[2] = highbd_idct_add_dual(q[2], q[3]); - // part of stage 3 - do_butterfly(q[14], q[13], cospi_12_64, cospi_20_64, &q[1], &q[3]); - - // generate 22,23,24,25 - // part of stage 1 - load_from_transformed(trans_buf, 13, 19, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_19_64, cospi_13_64, &q[5], &q[7]); - load_from_transformed(trans_buf, 29, 3, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_3_64, cospi_29_64, &q[4], &q[6]); - // part of stage 2 - q[14] = highbd_idct_sub_dual(q[4], q[5]); - q[5] = highbd_idct_add_dual(q[4], q[5]); - q[13] = highbd_idct_sub_dual(q[6], q[7]); - q[6] = highbd_idct_add_dual(q[6], q[7]); - // part of stage 3 - do_butterfly(q[14], q[13], -cospi_20_64, -cospi_12_64, &q[4], &q[7]); - // part of stage 4 - q[10] = highbd_idct_add_dual(q[7], q[1]); - q[11] = highbd_idct_add_dual(q[5], q[0]); - q[12] = highbd_idct_add_dual(q[6], q[2]); - q[15] = highbd_idct_add_dual(q[4], q[3]); - // part of stage 6 - load_from_output(out, 16, 17, &q[14], &q[13]); - q[8] = highbd_idct_add_dual(q[14], q[11]); - q[9] = highbd_idct_add_dual(q[13], q[10]); - q[13] = highbd_idct_sub_dual(q[13], q[10]); - q[11] = highbd_idct_sub_dual(q[14], q[11]); - store_in_output(out, 17, 16, q[9], q[8]); - load_from_output(out, 30, 31, &q[14], &q[9]); - q[8] = highbd_idct_sub_dual(q[9], q[12]); - q[10] = highbd_idct_add_dual(q[14], q[15]); - q[14] = highbd_idct_sub_dual(q[14], q[15]); - q[12] = highbd_idct_add_dual(q[9], q[12]); - store_in_output(out, 30, 31, q[10], q[12]); - // part of stage 7 - do_butterfly(q[14], q[13], cospi_16_64, cospi_16_64, &q[13], &q[14]); - store_in_output(out, 25, 22, q[14], q[13]); - do_butterfly(q[8], q[11], cospi_16_64, cospi_16_64, &q[13], &q[14]); - store_in_output(out, 24, 23, q[14], q[13]); - // part of stage 4 - q[14] = highbd_idct_sub_dual(q[5], q[0]); - q[13] = highbd_idct_sub_dual(q[6], q[2]); - do_butterfly(q[14], q[13], -cospi_8_64, -cospi_24_64, &q[5], &q[6]); - q[14] = highbd_idct_sub_dual(q[7], q[1]); - q[13] = highbd_idct_sub_dual(q[4], q[3]); - do_butterfly(q[14], q[13], -cospi_8_64, -cospi_24_64, &q[0], &q[1]); - // part of stage 6 - load_from_output(out, 18, 19, &q[14], &q[13]); - q[8] = highbd_idct_add_dual(q[14], q[1]); - q[9] = highbd_idct_add_dual(q[13], q[6]); - q[13] = highbd_idct_sub_dual(q[13], q[6]); - q[1] = highbd_idct_sub_dual(q[14], q[1]); - store_in_output(out, 18, 19, q[8], q[9]); - load_from_output(out, 28, 29, &q[8], &q[9]); - q[14] = highbd_idct_sub_dual(q[8], q[5]); - q[10] = highbd_idct_add_dual(q[8], q[5]); - q[11] = highbd_idct_add_dual(q[9], q[0]); - q[0] = highbd_idct_sub_dual(q[9], q[0]); - store_in_output(out, 28, 29, q[10], q[11]); - // part of stage 7 - do_butterfly(q[14], q[13], cospi_16_64, cospi_16_64, &q[13], &q[14]); - store_in_output(out, 20, 27, q[13], q[14]); - do_butterfly(q[0], q[1], cospi_16_64, cospi_16_64, &q[1], &q[0]); - store_in_output(out, 21, 26, q[1], q[0]); - - // ----------------------------------------- - // BLOCK C: 8-10,11-15 - // ----------------------------------------- - // generate 8,9,14,15 - // part of stage 2 - load_from_transformed(trans_buf, 2, 30, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_30_64, cospi_2_64, &q[0], &q[2]); - load_from_transformed(trans_buf, 18, 14, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_14_64, cospi_18_64, &q[1], &q[3]); - // part of stage 3 - q[13] = highbd_idct_sub_dual(q[0], q[1]); - q[0] = highbd_idct_add_dual(q[0], q[1]); - q[14] = highbd_idct_sub_dual(q[2], q[3]); - q[2] = highbd_idct_add_dual(q[2], q[3]); - // part of stage 4 - do_butterfly(q[14], q[13], cospi_24_64, cospi_8_64, &q[1], &q[3]); - - // generate 10,11,12,13 - // part of stage 2 - load_from_transformed(trans_buf, 10, 22, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_22_64, cospi_10_64, &q[5], &q[7]); - load_from_transformed(trans_buf, 26, 6, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_6_64, cospi_26_64, &q[4], &q[6]); - // part of stage 3 - q[14] = highbd_idct_sub_dual(q[4], q[5]); - q[5] = highbd_idct_add_dual(q[4], q[5]); - q[13] = highbd_idct_sub_dual(q[6], q[7]); - q[6] = highbd_idct_add_dual(q[6], q[7]); - // part of stage 4 - do_butterfly(q[14], q[13], -cospi_8_64, -cospi_24_64, &q[4], &q[7]); - // part of stage 5 - q[8] = highbd_idct_add_dual(q[0], q[5]); - q[9] = highbd_idct_add_dual(q[1], q[7]); - q[13] = highbd_idct_sub_dual(q[1], q[7]); - q[14] = highbd_idct_sub_dual(q[3], q[4]); - q[10] = highbd_idct_add_dual(q[3], q[4]); - q[15] = highbd_idct_add_dual(q[2], q[6]); - store_in_output(out, 8, 15, q[8], q[15]); - store_in_output(out, 9, 14, q[9], q[10]); - // part of stage 6 - do_butterfly(q[14], q[13], cospi_16_64, cospi_16_64, &q[1], &q[3]); - store_in_output(out, 13, 10, q[3], q[1]); - q[13] = highbd_idct_sub_dual(q[0], q[5]); - q[14] = highbd_idct_sub_dual(q[2], q[6]); - do_butterfly(q[14], q[13], cospi_16_64, cospi_16_64, &q[1], &q[3]); - store_in_output(out, 11, 12, q[1], q[3]); - - // ----------------------------------------- - // BLOCK D: 0-3,4-7 - // ----------------------------------------- - // generate 4,5,6,7 - // part of stage 3 - load_from_transformed(trans_buf, 4, 28, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_28_64, cospi_4_64, &q[0], &q[2]); - load_from_transformed(trans_buf, 20, 12, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_12_64, cospi_20_64, &q[1], &q[3]); - // part of stage 4 - q[13] = highbd_idct_sub_dual(q[0], q[1]); - q[0] = highbd_idct_add_dual(q[0], q[1]); - q[14] = highbd_idct_sub_dual(q[2], q[3]); - q[2] = highbd_idct_add_dual(q[2], q[3]); - // part of stage 5 - do_butterfly(q[14], q[13], cospi_16_64, cospi_16_64, &q[1], &q[3]); - - // generate 0,1,2,3 - // part of stage 4 - load_from_transformed(trans_buf, 0, 16, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_16_64, cospi_16_64, &q[5], &q[7]); - load_from_transformed(trans_buf, 8, 24, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_24_64, cospi_8_64, &q[14], &q[6]); - // part of stage 5 - q[4] = highbd_idct_add_dual(q[7], q[6]); - q[7] = highbd_idct_sub_dual(q[7], q[6]); - q[6] = highbd_idct_sub_dual(q[5], q[14]); - q[5] = highbd_idct_add_dual(q[5], q[14]); - // part of stage 6 - q[8] = highbd_idct_add_dual(q[4], q[2]); - q[9] = highbd_idct_add_dual(q[5], q[3]); - q[10] = highbd_idct_add_dual(q[6], q[1]); - q[11] = highbd_idct_add_dual(q[7], q[0]); - q[12] = highbd_idct_sub_dual(q[7], q[0]); - q[13] = highbd_idct_sub_dual(q[6], q[1]); - q[14] = highbd_idct_sub_dual(q[5], q[3]); - q[15] = highbd_idct_sub_dual(q[4], q[2]); - // part of stage 7 - load_from_output(out, 14, 15, &q[0], &q[1]); - q[2] = highbd_idct_add_dual(q[8], q[1]); - q[3] = highbd_idct_add_dual(q[9], q[0]); - q[4] = highbd_idct_sub_dual(q[9], q[0]); - q[5] = highbd_idct_sub_dual(q[8], q[1]); - load_from_output(out, 16, 17, &q[0], &q[1]); - q[8] = highbd_idct_add_dual(q[4], q[1]); - q[9] = highbd_idct_add_dual(q[5], q[0]); - q[6] = highbd_idct_sub_dual(q[5], q[0]); - q[7] = highbd_idct_sub_dual(q[4], q[1]); - - if (idct32_pass_loop == 0) { - idct32_bands_end_1st_pass(out, q); - } else { - const int16x8_t max = vdupq_n_s16((1 << bd) - 1); - idct32_bands_end_2nd_pass(out, dst, stride, max, q); - dst += 8; - } - } - } -} - -void vpx_highbd_idct32x32_1024_add_neon(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - if (bd == 8) { - vpx_idct32_32_neon(input, CAST_TO_BYTEPTR(dest), stride, 1); - } else { - vpx_highbd_idct32_32_neon(input, dest, stride, bd); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct32x32_135_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct32x32_135_add_neon.c deleted file mode 100644 index 6750c1a4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct32x32_135_add_neon.c +++ /dev/null @@ -1,757 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/highbd_idct_neon.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/txfm_common.h" - -static INLINE void load_8x8_s32_dual( - const tran_low_t *input, int32x4x2_t *const in0, int32x4x2_t *const in1, - int32x4x2_t *const in2, int32x4x2_t *const in3, int32x4x2_t *const in4, - int32x4x2_t *const in5, int32x4x2_t *const in6, int32x4x2_t *const in7) { - in0->val[0] = vld1q_s32(input); - in0->val[1] = vld1q_s32(input + 4); - input += 32; - in1->val[0] = vld1q_s32(input); - in1->val[1] = vld1q_s32(input + 4); - input += 32; - in2->val[0] = vld1q_s32(input); - in2->val[1] = vld1q_s32(input + 4); - input += 32; - in3->val[0] = vld1q_s32(input); - in3->val[1] = vld1q_s32(input + 4); - input += 32; - in4->val[0] = vld1q_s32(input); - in4->val[1] = vld1q_s32(input + 4); - input += 32; - in5->val[0] = vld1q_s32(input); - in5->val[1] = vld1q_s32(input + 4); - input += 32; - in6->val[0] = vld1q_s32(input); - in6->val[1] = vld1q_s32(input + 4); - input += 32; - in7->val[0] = vld1q_s32(input); - in7->val[1] = vld1q_s32(input + 4); -} - -static INLINE void load_4x8_s32_dual(const tran_low_t *input, - int32x4_t *const in0, int32x4_t *const in1, - int32x4_t *const in2, int32x4_t *const in3, - int32x4_t *const in4, int32x4_t *const in5, - int32x4_t *const in6, - int32x4_t *const in7) { - *in0 = vld1q_s32(input); - input += 32; - *in1 = vld1q_s32(input); - input += 32; - *in2 = vld1q_s32(input); - input += 32; - *in3 = vld1q_s32(input); - input += 32; - *in4 = vld1q_s32(input); - input += 32; - *in5 = vld1q_s32(input); - input += 32; - *in6 = vld1q_s32(input); - input += 32; - *in7 = vld1q_s32(input); -} - -// Only for the first pass of the _135_ variant. Since it only uses values from -// the top left 16x16 it can safely assume all the remaining values are 0 and -// skip an awful lot of calculations. In fact, only the first 12 columns make -// the cut. None of the elements in the 13th, 14th, 15th or 16th columns are -// used so it skips any calls to input[12|13|14|15] too. -// In C this does a single row of 32 for each call. Here it transposes the top -// left 12x8 to allow using SIMD. - -// vp9/common/vp9_scan.c:vp9_default_iscan_32x32 arranges the first 135 non-zero -// coefficients as follows: -// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 -// 0 0 2 5 10 17 25 38 47 62 83 101 121 -// 1 1 4 8 15 22 30 45 58 74 92 112 133 -// 2 3 7 12 18 28 36 52 64 82 102 118 -// 3 6 11 16 23 31 43 60 73 90 109 126 -// 4 9 14 19 29 37 50 65 78 98 116 134 -// 5 13 20 26 35 44 54 72 85 105 123 -// 6 21 27 33 42 53 63 80 94 113 132 -// 7 24 32 39 48 57 71 88 104 120 -// 8 34 40 46 56 68 81 96 111 130 -// 9 41 49 55 67 77 91 107 124 -// 10 51 59 66 76 89 99 119 131 -// 11 61 69 75 87 100 114 129 -// 12 70 79 86 97 108 122 -// 13 84 93 103 110 125 -// 14 98 106 115 127 -// 15 117 128 -static void vpx_highbd_idct32_12_neon(const tran_low_t *const input, - int32_t *output) { - int32x4x2_t in[12], s1[32], s2[32], s3[32], s4[32], s5[32], s6[32], s7[32], - s8[32]; - - load_8x8_s32_dual(input, &in[0], &in[1], &in[2], &in[3], &in[4], &in[5], - &in[6], &in[7]); - transpose_s32_8x8(&in[0], &in[1], &in[2], &in[3], &in[4], &in[5], &in[6], - &in[7]); - - load_4x8_s32_dual(input + 8, &in[8].val[0], &in[8].val[1], &in[9].val[0], - &in[9].val[1], &in[10].val[0], &in[10].val[1], - &in[11].val[0], &in[11].val[1]); - transpose_s32_4x8(&in[8].val[0], &in[8].val[1], &in[9].val[0], &in[9].val[1], - &in[10].val[0], &in[10].val[1], &in[11].val[0], - &in[11].val[1]); - - // stage 1 - s1[16] = multiply_shift_and_narrow_s32_dual(in[1], cospi_31_64); - s1[31] = multiply_shift_and_narrow_s32_dual(in[1], cospi_1_64); - - s1[18] = multiply_shift_and_narrow_s32_dual(in[9], cospi_23_64); - s1[29] = multiply_shift_and_narrow_s32_dual(in[9], cospi_9_64); - - s1[19] = multiply_shift_and_narrow_s32_dual(in[7], -cospi_25_64); - s1[28] = multiply_shift_and_narrow_s32_dual(in[7], cospi_7_64); - - s1[20] = multiply_shift_and_narrow_s32_dual(in[5], cospi_27_64); - s1[27] = multiply_shift_and_narrow_s32_dual(in[5], cospi_5_64); - - s1[21] = multiply_shift_and_narrow_s32_dual(in[11], -cospi_21_64); - s1[26] = multiply_shift_and_narrow_s32_dual(in[11], cospi_11_64); - - s1[23] = multiply_shift_and_narrow_s32_dual(in[3], -cospi_29_64); - s1[24] = multiply_shift_and_narrow_s32_dual(in[3], cospi_3_64); - - // stage 2 - s2[8] = multiply_shift_and_narrow_s32_dual(in[2], cospi_30_64); - s2[15] = multiply_shift_and_narrow_s32_dual(in[2], cospi_2_64); - - s2[10] = multiply_shift_and_narrow_s32_dual(in[10], cospi_22_64); - s2[13] = multiply_shift_and_narrow_s32_dual(in[10], cospi_10_64); - - s2[11] = multiply_shift_and_narrow_s32_dual(in[6], -cospi_26_64); - s2[12] = multiply_shift_and_narrow_s32_dual(in[6], cospi_6_64); - - s2[18] = highbd_idct_sub_dual(s1[19], s1[18]); - s2[19] = highbd_idct_add_dual(s1[18], s1[19]); - s2[20] = highbd_idct_add_dual(s1[20], s1[21]); - s2[21] = highbd_idct_sub_dual(s1[20], s1[21]); - s2[26] = highbd_idct_sub_dual(s1[27], s1[26]); - s2[27] = highbd_idct_add_dual(s1[26], s1[27]); - s2[28] = highbd_idct_add_dual(s1[28], s1[29]); - s2[29] = highbd_idct_sub_dual(s1[28], s1[29]); - - // stage 3 - s3[4] = multiply_shift_and_narrow_s32_dual(in[4], cospi_28_64); - s3[7] = multiply_shift_and_narrow_s32_dual(in[4], cospi_4_64); - - s3[10] = highbd_idct_sub_dual(s2[11], s2[10]); - s3[11] = highbd_idct_add_dual(s2[10], s2[11]); - s3[12] = highbd_idct_add_dual(s2[12], s2[13]); - s3[13] = highbd_idct_sub_dual(s2[12], s2[13]); - - s3[17] = multiply_accumulate_shift_and_narrow_s32_dual(s1[16], -cospi_4_64, - s1[31], cospi_28_64); - s3[30] = multiply_accumulate_shift_and_narrow_s32_dual(s1[16], cospi_28_64, - s1[31], cospi_4_64); - - s3[18] = multiply_accumulate_shift_and_narrow_s32_dual(s2[18], -cospi_28_64, - s2[29], -cospi_4_64); - s3[29] = multiply_accumulate_shift_and_narrow_s32_dual(s2[18], -cospi_4_64, - s2[29], cospi_28_64); - - s3[21] = multiply_accumulate_shift_and_narrow_s32_dual(s2[21], -cospi_20_64, - s2[26], cospi_12_64); - s3[26] = multiply_accumulate_shift_and_narrow_s32_dual(s2[21], cospi_12_64, - s2[26], cospi_20_64); - - s3[22] = multiply_accumulate_shift_and_narrow_s32_dual(s1[23], -cospi_12_64, - s1[24], -cospi_20_64); - s3[25] = multiply_accumulate_shift_and_narrow_s32_dual(s1[23], -cospi_20_64, - s1[24], cospi_12_64); - - // stage 4 - s4[0] = multiply_shift_and_narrow_s32_dual(in[0], cospi_16_64); - s4[2] = multiply_shift_and_narrow_s32_dual(in[8], cospi_24_64); - s4[3] = multiply_shift_and_narrow_s32_dual(in[8], cospi_8_64); - - s4[9] = multiply_accumulate_shift_and_narrow_s32_dual(s2[8], -cospi_8_64, - s2[15], cospi_24_64); - s4[14] = multiply_accumulate_shift_and_narrow_s32_dual(s2[8], cospi_24_64, - s2[15], cospi_8_64); - - s4[10] = multiply_accumulate_shift_and_narrow_s32_dual(s3[10], -cospi_24_64, - s3[13], -cospi_8_64); - s4[13] = multiply_accumulate_shift_and_narrow_s32_dual(s3[10], -cospi_8_64, - s3[13], cospi_24_64); - - s4[16] = highbd_idct_add_dual(s1[16], s2[19]); - s4[17] = highbd_idct_add_dual(s3[17], s3[18]); - s4[18] = highbd_idct_sub_dual(s3[17], s3[18]); - s4[19] = highbd_idct_sub_dual(s1[16], s2[19]); - s4[20] = highbd_idct_sub_dual(s1[23], s2[20]); - s4[21] = highbd_idct_sub_dual(s3[22], s3[21]); - s4[22] = highbd_idct_add_dual(s3[21], s3[22]); - s4[23] = highbd_idct_add_dual(s2[20], s1[23]); - s4[24] = highbd_idct_add_dual(s1[24], s2[27]); - s4[25] = highbd_idct_add_dual(s3[25], s3[26]); - s4[26] = highbd_idct_sub_dual(s3[25], s3[26]); - s4[27] = highbd_idct_sub_dual(s1[24], s2[27]); - s4[28] = highbd_idct_sub_dual(s1[31], s2[28]); - s4[29] = highbd_idct_sub_dual(s3[30], s3[29]); - s4[30] = highbd_idct_add_dual(s3[29], s3[30]); - s4[31] = highbd_idct_add_dual(s2[28], s1[31]); - - // stage 5 - s5[0] = highbd_idct_add_dual(s4[0], s4[3]); - s5[1] = highbd_idct_add_dual(s4[0], s4[2]); - s5[2] = highbd_idct_sub_dual(s4[0], s4[2]); - s5[3] = highbd_idct_sub_dual(s4[0], s4[3]); - - s5[5] = sub_multiply_shift_and_narrow_s32_dual(s3[7], s3[4], cospi_16_64); - s5[6] = add_multiply_shift_and_narrow_s32_dual(s3[4], s3[7], cospi_16_64); - - s5[8] = highbd_idct_add_dual(s2[8], s3[11]); - s5[9] = highbd_idct_add_dual(s4[9], s4[10]); - s5[10] = highbd_idct_sub_dual(s4[9], s4[10]); - s5[11] = highbd_idct_sub_dual(s2[8], s3[11]); - s5[12] = highbd_idct_sub_dual(s2[15], s3[12]); - s5[13] = highbd_idct_sub_dual(s4[14], s4[13]); - s5[14] = highbd_idct_add_dual(s4[13], s4[14]); - s5[15] = highbd_idct_add_dual(s2[15], s3[12]); - - s5[18] = multiply_accumulate_shift_and_narrow_s32_dual(s4[18], -cospi_8_64, - s4[29], cospi_24_64); - s5[29] = multiply_accumulate_shift_and_narrow_s32_dual(s4[18], cospi_24_64, - s4[29], cospi_8_64); - - s5[19] = multiply_accumulate_shift_and_narrow_s32_dual(s4[19], -cospi_8_64, - s4[28], cospi_24_64); - s5[28] = multiply_accumulate_shift_and_narrow_s32_dual(s4[19], cospi_24_64, - s4[28], cospi_8_64); - - s5[20] = multiply_accumulate_shift_and_narrow_s32_dual(s4[20], -cospi_24_64, - s4[27], -cospi_8_64); - s5[27] = multiply_accumulate_shift_and_narrow_s32_dual(s4[20], -cospi_8_64, - s4[27], cospi_24_64); - - s5[21] = multiply_accumulate_shift_and_narrow_s32_dual(s4[21], -cospi_24_64, - s4[26], -cospi_8_64); - s5[26] = multiply_accumulate_shift_and_narrow_s32_dual(s4[21], -cospi_8_64, - s4[26], cospi_24_64); - - // stage 6 - s6[0] = highbd_idct_add_dual(s5[0], s3[7]); - s6[1] = highbd_idct_add_dual(s5[1], s5[6]); - s6[2] = highbd_idct_add_dual(s5[2], s5[5]); - s6[3] = highbd_idct_add_dual(s5[3], s3[4]); - s6[4] = highbd_idct_sub_dual(s5[3], s3[4]); - s6[5] = highbd_idct_sub_dual(s5[2], s5[5]); - s6[6] = highbd_idct_sub_dual(s5[1], s5[6]); - s6[7] = highbd_idct_sub_dual(s5[0], s3[7]); - - s6[10] = sub_multiply_shift_and_narrow_s32_dual(s5[13], s5[10], cospi_16_64); - s6[13] = add_multiply_shift_and_narrow_s32_dual(s5[10], s5[13], cospi_16_64); - - s6[11] = sub_multiply_shift_and_narrow_s32_dual(s5[12], s5[11], cospi_16_64); - s6[12] = add_multiply_shift_and_narrow_s32_dual(s5[11], s5[12], cospi_16_64); - - s6[16] = highbd_idct_add_dual(s4[16], s4[23]); - s6[17] = highbd_idct_add_dual(s4[17], s4[22]); - s6[18] = highbd_idct_add_dual(s5[18], s5[21]); - s6[19] = highbd_idct_add_dual(s5[19], s5[20]); - s6[20] = highbd_idct_sub_dual(s5[19], s5[20]); - s6[21] = highbd_idct_sub_dual(s5[18], s5[21]); - s6[22] = highbd_idct_sub_dual(s4[17], s4[22]); - s6[23] = highbd_idct_sub_dual(s4[16], s4[23]); - - s6[24] = highbd_idct_sub_dual(s4[31], s4[24]); - s6[25] = highbd_idct_sub_dual(s4[30], s4[25]); - s6[26] = highbd_idct_sub_dual(s5[29], s5[26]); - s6[27] = highbd_idct_sub_dual(s5[28], s5[27]); - s6[28] = highbd_idct_add_dual(s5[27], s5[28]); - s6[29] = highbd_idct_add_dual(s5[26], s5[29]); - s6[30] = highbd_idct_add_dual(s4[25], s4[30]); - s6[31] = highbd_idct_add_dual(s4[24], s4[31]); - - // stage 7 - s7[0] = highbd_idct_add_dual(s6[0], s5[15]); - s7[1] = highbd_idct_add_dual(s6[1], s5[14]); - s7[2] = highbd_idct_add_dual(s6[2], s6[13]); - s7[3] = highbd_idct_add_dual(s6[3], s6[12]); - s7[4] = highbd_idct_add_dual(s6[4], s6[11]); - s7[5] = highbd_idct_add_dual(s6[5], s6[10]); - s7[6] = highbd_idct_add_dual(s6[6], s5[9]); - s7[7] = highbd_idct_add_dual(s6[7], s5[8]); - s7[8] = highbd_idct_sub_dual(s6[7], s5[8]); - s7[9] = highbd_idct_sub_dual(s6[6], s5[9]); - s7[10] = highbd_idct_sub_dual(s6[5], s6[10]); - s7[11] = highbd_idct_sub_dual(s6[4], s6[11]); - s7[12] = highbd_idct_sub_dual(s6[3], s6[12]); - s7[13] = highbd_idct_sub_dual(s6[2], s6[13]); - s7[14] = highbd_idct_sub_dual(s6[1], s5[14]); - s7[15] = highbd_idct_sub_dual(s6[0], s5[15]); - - s7[20] = sub_multiply_shift_and_narrow_s32_dual(s6[27], s6[20], cospi_16_64); - s7[27] = add_multiply_shift_and_narrow_s32_dual(s6[20], s6[27], cospi_16_64); - - s7[21] = sub_multiply_shift_and_narrow_s32_dual(s6[26], s6[21], cospi_16_64); - s7[26] = add_multiply_shift_and_narrow_s32_dual(s6[21], s6[26], cospi_16_64); - - s7[22] = sub_multiply_shift_and_narrow_s32_dual(s6[25], s6[22], cospi_16_64); - s7[25] = add_multiply_shift_and_narrow_s32_dual(s6[22], s6[25], cospi_16_64); - - s7[23] = sub_multiply_shift_and_narrow_s32_dual(s6[24], s6[23], cospi_16_64); - s7[24] = add_multiply_shift_and_narrow_s32_dual(s6[23], s6[24], cospi_16_64); - - // final stage - s8[0] = highbd_idct_add_dual(s7[0], s6[31]); - s8[1] = highbd_idct_add_dual(s7[1], s6[30]); - s8[2] = highbd_idct_add_dual(s7[2], s6[29]); - s8[3] = highbd_idct_add_dual(s7[3], s6[28]); - s8[4] = highbd_idct_add_dual(s7[4], s7[27]); - s8[5] = highbd_idct_add_dual(s7[5], s7[26]); - s8[6] = highbd_idct_add_dual(s7[6], s7[25]); - s8[7] = highbd_idct_add_dual(s7[7], s7[24]); - s8[8] = highbd_idct_add_dual(s7[8], s7[23]); - s8[9] = highbd_idct_add_dual(s7[9], s7[22]); - s8[10] = highbd_idct_add_dual(s7[10], s7[21]); - s8[11] = highbd_idct_add_dual(s7[11], s7[20]); - s8[12] = highbd_idct_add_dual(s7[12], s6[19]); - s8[13] = highbd_idct_add_dual(s7[13], s6[18]); - s8[14] = highbd_idct_add_dual(s7[14], s6[17]); - s8[15] = highbd_idct_add_dual(s7[15], s6[16]); - s8[16] = highbd_idct_sub_dual(s7[15], s6[16]); - s8[17] = highbd_idct_sub_dual(s7[14], s6[17]); - s8[18] = highbd_idct_sub_dual(s7[13], s6[18]); - s8[19] = highbd_idct_sub_dual(s7[12], s6[19]); - s8[20] = highbd_idct_sub_dual(s7[11], s7[20]); - s8[21] = highbd_idct_sub_dual(s7[10], s7[21]); - s8[22] = highbd_idct_sub_dual(s7[9], s7[22]); - s8[23] = highbd_idct_sub_dual(s7[8], s7[23]); - s8[24] = highbd_idct_sub_dual(s7[7], s7[24]); - s8[25] = highbd_idct_sub_dual(s7[6], s7[25]); - s8[26] = highbd_idct_sub_dual(s7[5], s7[26]); - s8[27] = highbd_idct_sub_dual(s7[4], s7[27]); - s8[28] = highbd_idct_sub_dual(s7[3], s6[28]); - s8[29] = highbd_idct_sub_dual(s7[2], s6[29]); - s8[30] = highbd_idct_sub_dual(s7[1], s6[30]); - s8[31] = highbd_idct_sub_dual(s7[0], s6[31]); - - vst1q_s32(output + 0, s8[0].val[0]); - vst1q_s32(output + 4, s8[0].val[1]); - output += 16; - vst1q_s32(output + 0, s8[1].val[0]); - vst1q_s32(output + 4, s8[1].val[1]); - output += 16; - vst1q_s32(output + 0, s8[2].val[0]); - vst1q_s32(output + 4, s8[2].val[1]); - output += 16; - vst1q_s32(output + 0, s8[3].val[0]); - vst1q_s32(output + 4, s8[3].val[1]); - output += 16; - vst1q_s32(output + 0, s8[4].val[0]); - vst1q_s32(output + 4, s8[4].val[1]); - output += 16; - vst1q_s32(output + 0, s8[5].val[0]); - vst1q_s32(output + 4, s8[5].val[1]); - output += 16; - vst1q_s32(output + 0, s8[6].val[0]); - vst1q_s32(output + 4, s8[6].val[1]); - output += 16; - vst1q_s32(output + 0, s8[7].val[0]); - vst1q_s32(output + 4, s8[7].val[1]); - output += 16; - - vst1q_s32(output + 0, s8[8].val[0]); - vst1q_s32(output + 4, s8[8].val[1]); - output += 16; - vst1q_s32(output + 0, s8[9].val[0]); - vst1q_s32(output + 4, s8[9].val[1]); - output += 16; - vst1q_s32(output + 0, s8[10].val[0]); - vst1q_s32(output + 4, s8[10].val[1]); - output += 16; - vst1q_s32(output + 0, s8[11].val[0]); - vst1q_s32(output + 4, s8[11].val[1]); - output += 16; - vst1q_s32(output + 0, s8[12].val[0]); - vst1q_s32(output + 4, s8[12].val[1]); - output += 16; - vst1q_s32(output + 0, s8[13].val[0]); - vst1q_s32(output + 4, s8[13].val[1]); - output += 16; - vst1q_s32(output + 0, s8[14].val[0]); - vst1q_s32(output + 4, s8[14].val[1]); - output += 16; - vst1q_s32(output + 0, s8[15].val[0]); - vst1q_s32(output + 4, s8[15].val[1]); - output += 16; - - vst1q_s32(output + 0, s8[16].val[0]); - vst1q_s32(output + 4, s8[16].val[1]); - output += 16; - vst1q_s32(output + 0, s8[17].val[0]); - vst1q_s32(output + 4, s8[17].val[1]); - output += 16; - vst1q_s32(output + 0, s8[18].val[0]); - vst1q_s32(output + 4, s8[18].val[1]); - output += 16; - vst1q_s32(output + 0, s8[19].val[0]); - vst1q_s32(output + 4, s8[19].val[1]); - output += 16; - vst1q_s32(output + 0, s8[20].val[0]); - vst1q_s32(output + 4, s8[20].val[1]); - output += 16; - vst1q_s32(output + 0, s8[21].val[0]); - vst1q_s32(output + 4, s8[21].val[1]); - output += 16; - vst1q_s32(output + 0, s8[22].val[0]); - vst1q_s32(output + 4, s8[22].val[1]); - output += 16; - vst1q_s32(output + 0, s8[23].val[0]); - vst1q_s32(output + 4, s8[23].val[1]); - output += 16; - - vst1q_s32(output + 0, s8[24].val[0]); - vst1q_s32(output + 4, s8[24].val[1]); - output += 16; - vst1q_s32(output + 0, s8[25].val[0]); - vst1q_s32(output + 4, s8[25].val[1]); - output += 16; - vst1q_s32(output + 0, s8[26].val[0]); - vst1q_s32(output + 4, s8[26].val[1]); - output += 16; - vst1q_s32(output + 0, s8[27].val[0]); - vst1q_s32(output + 4, s8[27].val[1]); - output += 16; - vst1q_s32(output + 0, s8[28].val[0]); - vst1q_s32(output + 4, s8[28].val[1]); - output += 16; - vst1q_s32(output + 0, s8[29].val[0]); - vst1q_s32(output + 4, s8[29].val[1]); - output += 16; - vst1q_s32(output + 0, s8[30].val[0]); - vst1q_s32(output + 4, s8[30].val[1]); - output += 16; - vst1q_s32(output + 0, s8[31].val[0]); - vst1q_s32(output + 4, s8[31].val[1]); -} - -static void vpx_highbd_idct32_16_neon(const int32_t *const input, - uint16_t *const output, const int stride, - const int bd) { - int32x4x2_t in[16], s1[32], s2[32], s3[32], s4[32], s5[32], s6[32], s7[32], - out[32]; - - load_and_transpose_s32_8x8(input, 16, &in[0], &in[1], &in[2], &in[3], &in[4], - &in[5], &in[6], &in[7]); - - load_and_transpose_s32_8x8(input + 8, 16, &in[8], &in[9], &in[10], &in[11], - &in[12], &in[13], &in[14], &in[15]); - - // stage 1 - s1[16] = multiply_shift_and_narrow_s32_dual(in[1], cospi_31_64); - s1[31] = multiply_shift_and_narrow_s32_dual(in[1], cospi_1_64); - - s1[17] = multiply_shift_and_narrow_s32_dual(in[15], -cospi_17_64); - s1[30] = multiply_shift_and_narrow_s32_dual(in[15], cospi_15_64); - - s1[18] = multiply_shift_and_narrow_s32_dual(in[9], cospi_23_64); - s1[29] = multiply_shift_and_narrow_s32_dual(in[9], cospi_9_64); - - s1[19] = multiply_shift_and_narrow_s32_dual(in[7], -cospi_25_64); - s1[28] = multiply_shift_and_narrow_s32_dual(in[7], cospi_7_64); - - s1[20] = multiply_shift_and_narrow_s32_dual(in[5], cospi_27_64); - s1[27] = multiply_shift_and_narrow_s32_dual(in[5], cospi_5_64); - - s1[21] = multiply_shift_and_narrow_s32_dual(in[11], -cospi_21_64); - s1[26] = multiply_shift_and_narrow_s32_dual(in[11], cospi_11_64); - - s1[22] = multiply_shift_and_narrow_s32_dual(in[13], cospi_19_64); - s1[25] = multiply_shift_and_narrow_s32_dual(in[13], cospi_13_64); - - s1[23] = multiply_shift_and_narrow_s32_dual(in[3], -cospi_29_64); - s1[24] = multiply_shift_and_narrow_s32_dual(in[3], cospi_3_64); - - // stage 2 - s2[8] = multiply_shift_and_narrow_s32_dual(in[2], cospi_30_64); - s2[15] = multiply_shift_and_narrow_s32_dual(in[2], cospi_2_64); - - s2[9] = multiply_shift_and_narrow_s32_dual(in[14], -cospi_18_64); - s2[14] = multiply_shift_and_narrow_s32_dual(in[14], cospi_14_64); - - s2[10] = multiply_shift_and_narrow_s32_dual(in[10], cospi_22_64); - s2[13] = multiply_shift_and_narrow_s32_dual(in[10], cospi_10_64); - - s2[11] = multiply_shift_and_narrow_s32_dual(in[6], -cospi_26_64); - s2[12] = multiply_shift_and_narrow_s32_dual(in[6], cospi_6_64); - - s2[16] = highbd_idct_add_dual(s1[16], s1[17]); - s2[17] = highbd_idct_sub_dual(s1[16], s1[17]); - s2[18] = highbd_idct_sub_dual(s1[19], s1[18]); - s2[19] = highbd_idct_add_dual(s1[18], s1[19]); - s2[20] = highbd_idct_add_dual(s1[20], s1[21]); - s2[21] = highbd_idct_sub_dual(s1[20], s1[21]); - s2[22] = highbd_idct_sub_dual(s1[23], s1[22]); - s2[23] = highbd_idct_add_dual(s1[22], s1[23]); - s2[24] = highbd_idct_add_dual(s1[24], s1[25]); - s2[25] = highbd_idct_sub_dual(s1[24], s1[25]); - s2[26] = highbd_idct_sub_dual(s1[27], s1[26]); - s2[27] = highbd_idct_add_dual(s1[26], s1[27]); - s2[28] = highbd_idct_add_dual(s1[28], s1[29]); - s2[29] = highbd_idct_sub_dual(s1[28], s1[29]); - s2[30] = highbd_idct_sub_dual(s1[31], s1[30]); - s2[31] = highbd_idct_add_dual(s1[30], s1[31]); - - // stage 3 - s3[4] = multiply_shift_and_narrow_s32_dual(in[4], cospi_28_64); - s3[7] = multiply_shift_and_narrow_s32_dual(in[4], cospi_4_64); - - s3[5] = multiply_shift_and_narrow_s32_dual(in[12], -cospi_20_64); - s3[6] = multiply_shift_and_narrow_s32_dual(in[12], cospi_12_64); - - s3[8] = highbd_idct_add_dual(s2[8], s2[9]); - s3[9] = highbd_idct_sub_dual(s2[8], s2[9]); - s3[10] = highbd_idct_sub_dual(s2[11], s2[10]); - s3[11] = highbd_idct_add_dual(s2[10], s2[11]); - s3[12] = highbd_idct_add_dual(s2[12], s2[13]); - s3[13] = highbd_idct_sub_dual(s2[12], s2[13]); - s3[14] = highbd_idct_sub_dual(s2[15], s2[14]); - s3[15] = highbd_idct_add_dual(s2[14], s2[15]); - - s3[17] = multiply_accumulate_shift_and_narrow_s32_dual(s2[17], -cospi_4_64, - s2[30], cospi_28_64); - s3[30] = multiply_accumulate_shift_and_narrow_s32_dual(s2[17], cospi_28_64, - s2[30], cospi_4_64); - - s3[18] = multiply_accumulate_shift_and_narrow_s32_dual(s2[18], -cospi_28_64, - s2[29], -cospi_4_64); - s3[29] = multiply_accumulate_shift_and_narrow_s32_dual(s2[18], -cospi_4_64, - s2[29], cospi_28_64); - - s3[21] = multiply_accumulate_shift_and_narrow_s32_dual(s2[21], -cospi_20_64, - s2[26], cospi_12_64); - s3[26] = multiply_accumulate_shift_and_narrow_s32_dual(s2[21], cospi_12_64, - s2[26], cospi_20_64); - - s3[22] = multiply_accumulate_shift_and_narrow_s32_dual(s2[22], -cospi_12_64, - s2[25], -cospi_20_64); - s3[25] = multiply_accumulate_shift_and_narrow_s32_dual(s2[22], -cospi_20_64, - s2[25], cospi_12_64); - - // stage 4 - s4[0] = multiply_shift_and_narrow_s32_dual(in[0], cospi_16_64); - s4[2] = multiply_shift_and_narrow_s32_dual(in[8], cospi_24_64); - s4[3] = multiply_shift_and_narrow_s32_dual(in[8], cospi_8_64); - - s4[4] = highbd_idct_add_dual(s3[4], s3[5]); - s4[5] = highbd_idct_sub_dual(s3[4], s3[5]); - s4[6] = highbd_idct_sub_dual(s3[7], s3[6]); - s4[7] = highbd_idct_add_dual(s3[6], s3[7]); - - s4[9] = multiply_accumulate_shift_and_narrow_s32_dual(s3[9], -cospi_8_64, - s3[14], cospi_24_64); - s4[14] = multiply_accumulate_shift_and_narrow_s32_dual(s3[9], cospi_24_64, - s3[14], cospi_8_64); - - s4[10] = multiply_accumulate_shift_and_narrow_s32_dual(s3[10], -cospi_24_64, - s3[13], -cospi_8_64); - s4[13] = multiply_accumulate_shift_and_narrow_s32_dual(s3[10], -cospi_8_64, - s3[13], cospi_24_64); - - s4[16] = highbd_idct_add_dual(s2[16], s2[19]); - s4[17] = highbd_idct_add_dual(s3[17], s3[18]); - s4[18] = highbd_idct_sub_dual(s3[17], s3[18]); - s4[19] = highbd_idct_sub_dual(s2[16], s2[19]); - s4[20] = highbd_idct_sub_dual(s2[23], s2[20]); - s4[21] = highbd_idct_sub_dual(s3[22], s3[21]); - s4[22] = highbd_idct_add_dual(s3[21], s3[22]); - s4[23] = highbd_idct_add_dual(s2[20], s2[23]); - s4[24] = highbd_idct_add_dual(s2[24], s2[27]); - s4[25] = highbd_idct_add_dual(s3[25], s3[26]); - s4[26] = highbd_idct_sub_dual(s3[25], s3[26]); - s4[27] = highbd_idct_sub_dual(s2[24], s2[27]); - s4[28] = highbd_idct_sub_dual(s2[31], s2[28]); - s4[29] = highbd_idct_sub_dual(s3[30], s3[29]); - s4[30] = highbd_idct_add_dual(s3[29], s3[30]); - s4[31] = highbd_idct_add_dual(s2[28], s2[31]); - - // stage 5 - s5[0] = highbd_idct_add_dual(s4[0], s4[3]); - s5[1] = highbd_idct_add_dual(s4[0], s4[2]); - s5[2] = highbd_idct_sub_dual(s4[0], s4[2]); - s5[3] = highbd_idct_sub_dual(s4[0], s4[3]); - - s5[5] = sub_multiply_shift_and_narrow_s32_dual(s4[6], s4[5], cospi_16_64); - s5[6] = add_multiply_shift_and_narrow_s32_dual(s4[5], s4[6], cospi_16_64); - - s5[8] = highbd_idct_add_dual(s3[8], s3[11]); - s5[9] = highbd_idct_add_dual(s4[9], s4[10]); - s5[10] = highbd_idct_sub_dual(s4[9], s4[10]); - s5[11] = highbd_idct_sub_dual(s3[8], s3[11]); - s5[12] = highbd_idct_sub_dual(s3[15], s3[12]); - s5[13] = highbd_idct_sub_dual(s4[14], s4[13]); - s5[14] = highbd_idct_add_dual(s4[13], s4[14]); - s5[15] = highbd_idct_add_dual(s3[15], s3[12]); - - s5[18] = multiply_accumulate_shift_and_narrow_s32_dual(s4[18], -cospi_8_64, - s4[29], cospi_24_64); - s5[29] = multiply_accumulate_shift_and_narrow_s32_dual(s4[18], cospi_24_64, - s4[29], cospi_8_64); - - s5[19] = multiply_accumulate_shift_and_narrow_s32_dual(s4[19], -cospi_8_64, - s4[28], cospi_24_64); - s5[28] = multiply_accumulate_shift_and_narrow_s32_dual(s4[19], cospi_24_64, - s4[28], cospi_8_64); - - s5[20] = multiply_accumulate_shift_and_narrow_s32_dual(s4[20], -cospi_24_64, - s4[27], -cospi_8_64); - s5[27] = multiply_accumulate_shift_and_narrow_s32_dual(s4[20], -cospi_8_64, - s4[27], cospi_24_64); - - s5[21] = multiply_accumulate_shift_and_narrow_s32_dual(s4[21], -cospi_24_64, - s4[26], -cospi_8_64); - s5[26] = multiply_accumulate_shift_and_narrow_s32_dual(s4[21], -cospi_8_64, - s4[26], cospi_24_64); - - // stage 6 - s6[0] = highbd_idct_add_dual(s5[0], s4[7]); - s6[1] = highbd_idct_add_dual(s5[1], s5[6]); - s6[2] = highbd_idct_add_dual(s5[2], s5[5]); - s6[3] = highbd_idct_add_dual(s5[3], s4[4]); - s6[4] = highbd_idct_sub_dual(s5[3], s4[4]); - s6[5] = highbd_idct_sub_dual(s5[2], s5[5]); - s6[6] = highbd_idct_sub_dual(s5[1], s5[6]); - s6[7] = highbd_idct_sub_dual(s5[0], s4[7]); - - s6[10] = sub_multiply_shift_and_narrow_s32_dual(s5[13], s5[10], cospi_16_64); - s6[13] = add_multiply_shift_and_narrow_s32_dual(s5[10], s5[13], cospi_16_64); - - s6[11] = sub_multiply_shift_and_narrow_s32_dual(s5[12], s5[11], cospi_16_64); - s6[12] = add_multiply_shift_and_narrow_s32_dual(s5[11], s5[12], cospi_16_64); - - s6[16] = highbd_idct_add_dual(s4[16], s4[23]); - s6[17] = highbd_idct_add_dual(s4[17], s4[22]); - s6[18] = highbd_idct_add_dual(s5[18], s5[21]); - s6[19] = highbd_idct_add_dual(s5[19], s5[20]); - s6[20] = highbd_idct_sub_dual(s5[19], s5[20]); - s6[21] = highbd_idct_sub_dual(s5[18], s5[21]); - s6[22] = highbd_idct_sub_dual(s4[17], s4[22]); - s6[23] = highbd_idct_sub_dual(s4[16], s4[23]); - s6[24] = highbd_idct_sub_dual(s4[31], s4[24]); - s6[25] = highbd_idct_sub_dual(s4[30], s4[25]); - s6[26] = highbd_idct_sub_dual(s5[29], s5[26]); - s6[27] = highbd_idct_sub_dual(s5[28], s5[27]); - s6[28] = highbd_idct_add_dual(s5[27], s5[28]); - s6[29] = highbd_idct_add_dual(s5[26], s5[29]); - s6[30] = highbd_idct_add_dual(s4[25], s4[30]); - s6[31] = highbd_idct_add_dual(s4[24], s4[31]); - - // stage 7 - s7[0] = highbd_idct_add_dual(s6[0], s5[15]); - s7[1] = highbd_idct_add_dual(s6[1], s5[14]); - s7[2] = highbd_idct_add_dual(s6[2], s6[13]); - s7[3] = highbd_idct_add_dual(s6[3], s6[12]); - s7[4] = highbd_idct_add_dual(s6[4], s6[11]); - s7[5] = highbd_idct_add_dual(s6[5], s6[10]); - s7[6] = highbd_idct_add_dual(s6[6], s5[9]); - s7[7] = highbd_idct_add_dual(s6[7], s5[8]); - s7[8] = highbd_idct_sub_dual(s6[7], s5[8]); - s7[9] = highbd_idct_sub_dual(s6[6], s5[9]); - s7[10] = highbd_idct_sub_dual(s6[5], s6[10]); - s7[11] = highbd_idct_sub_dual(s6[4], s6[11]); - s7[12] = highbd_idct_sub_dual(s6[3], s6[12]); - s7[13] = highbd_idct_sub_dual(s6[2], s6[13]); - s7[14] = highbd_idct_sub_dual(s6[1], s5[14]); - s7[15] = highbd_idct_sub_dual(s6[0], s5[15]); - - s7[20] = sub_multiply_shift_and_narrow_s32_dual(s6[27], s6[20], cospi_16_64); - s7[27] = add_multiply_shift_and_narrow_s32_dual(s6[20], s6[27], cospi_16_64); - - s7[21] = sub_multiply_shift_and_narrow_s32_dual(s6[26], s6[21], cospi_16_64); - s7[26] = add_multiply_shift_and_narrow_s32_dual(s6[21], s6[26], cospi_16_64); - - s7[22] = sub_multiply_shift_and_narrow_s32_dual(s6[25], s6[22], cospi_16_64); - s7[25] = add_multiply_shift_and_narrow_s32_dual(s6[22], s6[25], cospi_16_64); - - s7[23] = sub_multiply_shift_and_narrow_s32_dual(s6[24], s6[23], cospi_16_64); - s7[24] = add_multiply_shift_and_narrow_s32_dual(s6[23], s6[24], cospi_16_64); - - // final stage - out[0] = highbd_idct_add_dual(s7[0], s6[31]); - out[1] = highbd_idct_add_dual(s7[1], s6[30]); - out[2] = highbd_idct_add_dual(s7[2], s6[29]); - out[3] = highbd_idct_add_dual(s7[3], s6[28]); - out[4] = highbd_idct_add_dual(s7[4], s7[27]); - out[5] = highbd_idct_add_dual(s7[5], s7[26]); - out[6] = highbd_idct_add_dual(s7[6], s7[25]); - out[7] = highbd_idct_add_dual(s7[7], s7[24]); - out[8] = highbd_idct_add_dual(s7[8], s7[23]); - out[9] = highbd_idct_add_dual(s7[9], s7[22]); - out[10] = highbd_idct_add_dual(s7[10], s7[21]); - out[11] = highbd_idct_add_dual(s7[11], s7[20]); - out[12] = highbd_idct_add_dual(s7[12], s6[19]); - out[13] = highbd_idct_add_dual(s7[13], s6[18]); - out[14] = highbd_idct_add_dual(s7[14], s6[17]); - out[15] = highbd_idct_add_dual(s7[15], s6[16]); - out[16] = highbd_idct_sub_dual(s7[15], s6[16]); - out[17] = highbd_idct_sub_dual(s7[14], s6[17]); - out[18] = highbd_idct_sub_dual(s7[13], s6[18]); - out[19] = highbd_idct_sub_dual(s7[12], s6[19]); - out[20] = highbd_idct_sub_dual(s7[11], s7[20]); - out[21] = highbd_idct_sub_dual(s7[10], s7[21]); - out[22] = highbd_idct_sub_dual(s7[9], s7[22]); - out[23] = highbd_idct_sub_dual(s7[8], s7[23]); - out[24] = highbd_idct_sub_dual(s7[7], s7[24]); - out[25] = highbd_idct_sub_dual(s7[6], s7[25]); - out[26] = highbd_idct_sub_dual(s7[5], s7[26]); - out[27] = highbd_idct_sub_dual(s7[4], s7[27]); - out[28] = highbd_idct_sub_dual(s7[3], s6[28]); - out[29] = highbd_idct_sub_dual(s7[2], s6[29]); - out[30] = highbd_idct_sub_dual(s7[1], s6[30]); - out[31] = highbd_idct_sub_dual(s7[0], s6[31]); - - highbd_idct16x16_add_store(out, output, stride, bd); - highbd_idct16x16_add_store(out + 16, output + 16 * stride, stride, bd); -} - -void vpx_highbd_idct32x32_135_add_neon(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i; - - if (bd == 8) { - int16_t temp[32 * 16]; - int16_t *t = temp; - vpx_idct32_12_neon(input, temp); - vpx_idct32_12_neon(input + 32 * 8, temp + 8); - - for (i = 0; i < 32; i += 8) { - vpx_idct32_16_neon(t, dest, stride, 1); - t += (16 * 8); - dest += 8; - } - } else { - int32_t temp[32 * 16]; - int32_t *t = temp; - vpx_highbd_idct32_12_neon(input, temp); - vpx_highbd_idct32_12_neon(input + 32 * 8, temp + 8); - - for (i = 0; i < 32; i += 8) { - vpx_highbd_idct32_16_neon(t, dest, stride, bd); - t += (16 * 8); - dest += 8; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct32x32_34_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct32x32_34_add_neon.c deleted file mode 100644 index f05932ce..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct32x32_34_add_neon.c +++ /dev/null @@ -1,625 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/highbd_idct_neon.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/txfm_common.h" - -// Only for the first pass of the _34_ variant. Since it only uses values from -// the top left 8x8 it can safely assume all the remaining values are 0 and skip -// an awful lot of calculations. In fact, only the first 6 columns make the cut. -// None of the elements in the 7th or 8th column are used so it skips any calls -// to input[67] too. -// In C this does a single row of 32 for each call. Here it transposes the top -// left 8x8 to allow using SIMD. - -// vp9/common/vp9_scan.c:vp9_default_iscan_32x32 arranges the first 34 non-zero -// coefficients as follows: -// 0 1 2 3 4 5 6 7 -// 0 0 2 5 10 17 25 -// 1 1 4 8 15 22 30 -// 2 3 7 12 18 28 -// 3 6 11 16 23 31 -// 4 9 14 19 29 -// 5 13 20 26 -// 6 21 27 33 -// 7 24 32 -static void vpx_highbd_idct32_6_neon(const tran_low_t *input, int32_t *output) { - int32x4x2_t in[8], s1[32], s2[32], s3[32]; - - in[0].val[0] = vld1q_s32(input); - in[0].val[1] = vld1q_s32(input + 4); - input += 32; - in[1].val[0] = vld1q_s32(input); - in[1].val[1] = vld1q_s32(input + 4); - input += 32; - in[2].val[0] = vld1q_s32(input); - in[2].val[1] = vld1q_s32(input + 4); - input += 32; - in[3].val[0] = vld1q_s32(input); - in[3].val[1] = vld1q_s32(input + 4); - input += 32; - in[4].val[0] = vld1q_s32(input); - in[4].val[1] = vld1q_s32(input + 4); - input += 32; - in[5].val[0] = vld1q_s32(input); - in[5].val[1] = vld1q_s32(input + 4); - input += 32; - in[6].val[0] = vld1q_s32(input); - in[6].val[1] = vld1q_s32(input + 4); - input += 32; - in[7].val[0] = vld1q_s32(input); - in[7].val[1] = vld1q_s32(input + 4); - transpose_s32_8x8(&in[0], &in[1], &in[2], &in[3], &in[4], &in[5], &in[6], - &in[7]); - - // stage 1 - // input[1] * cospi_31_64 - input[31] * cospi_1_64 (but input[31] == 0) - s1[16] = multiply_shift_and_narrow_s32_dual(in[1], cospi_31_64); - // input[1] * cospi_1_64 + input[31] * cospi_31_64 (but input[31] == 0) - s1[31] = multiply_shift_and_narrow_s32_dual(in[1], cospi_1_64); - - s1[20] = multiply_shift_and_narrow_s32_dual(in[5], cospi_27_64); - s1[27] = multiply_shift_and_narrow_s32_dual(in[5], cospi_5_64); - - s1[23] = multiply_shift_and_narrow_s32_dual(in[3], -cospi_29_64); - s1[24] = multiply_shift_and_narrow_s32_dual(in[3], cospi_3_64); - - // stage 2 - s2[8] = multiply_shift_and_narrow_s32_dual(in[2], cospi_30_64); - s2[15] = multiply_shift_and_narrow_s32_dual(in[2], cospi_2_64); - - // stage 3 - s1[4] = multiply_shift_and_narrow_s32_dual(in[4], cospi_28_64); - s1[7] = multiply_shift_and_narrow_s32_dual(in[4], cospi_4_64); - - s1[17] = multiply_accumulate_shift_and_narrow_s32_dual(s1[16], -cospi_4_64, - s1[31], cospi_28_64); - s1[30] = multiply_accumulate_shift_and_narrow_s32_dual(s1[16], cospi_28_64, - s1[31], cospi_4_64); - - s1[21] = multiply_accumulate_shift_and_narrow_s32_dual(s1[20], -cospi_20_64, - s1[27], cospi_12_64); - s1[26] = multiply_accumulate_shift_and_narrow_s32_dual(s1[20], cospi_12_64, - s1[27], cospi_20_64); - - s1[22] = multiply_accumulate_shift_and_narrow_s32_dual(s1[23], -cospi_12_64, - s1[24], -cospi_20_64); - s1[25] = multiply_accumulate_shift_and_narrow_s32_dual(s1[23], -cospi_20_64, - s1[24], cospi_12_64); - - // stage 4 - s1[0] = multiply_shift_and_narrow_s32_dual(in[0], cospi_16_64); - - s2[9] = multiply_accumulate_shift_and_narrow_s32_dual(s2[8], -cospi_8_64, - s2[15], cospi_24_64); - s2[14] = multiply_accumulate_shift_and_narrow_s32_dual(s2[8], cospi_24_64, - s2[15], cospi_8_64); - - s2[20] = highbd_idct_sub_dual(s1[23], s1[20]); - s2[21] = highbd_idct_sub_dual(s1[22], s1[21]); - s2[22] = highbd_idct_add_dual(s1[21], s1[22]); - s2[23] = highbd_idct_add_dual(s1[20], s1[23]); - s2[24] = highbd_idct_add_dual(s1[24], s1[27]); - s2[25] = highbd_idct_add_dual(s1[25], s1[26]); - s2[26] = highbd_idct_sub_dual(s1[25], s1[26]); - s2[27] = highbd_idct_sub_dual(s1[24], s1[27]); - - // stage 5 - s1[5] = sub_multiply_shift_and_narrow_s32_dual(s1[7], s1[4], cospi_16_64); - s1[6] = add_multiply_shift_and_narrow_s32_dual(s1[4], s1[7], cospi_16_64); - - s1[18] = multiply_accumulate_shift_and_narrow_s32_dual(s1[17], -cospi_8_64, - s1[30], cospi_24_64); - s1[29] = multiply_accumulate_shift_and_narrow_s32_dual(s1[17], cospi_24_64, - s1[30], cospi_8_64); - - s1[19] = multiply_accumulate_shift_and_narrow_s32_dual(s1[16], -cospi_8_64, - s1[31], cospi_24_64); - s1[28] = multiply_accumulate_shift_and_narrow_s32_dual(s1[16], cospi_24_64, - s1[31], cospi_8_64); - - s1[20] = multiply_accumulate_shift_and_narrow_s32_dual(s2[20], -cospi_24_64, - s2[27], -cospi_8_64); - s1[27] = multiply_accumulate_shift_and_narrow_s32_dual(s2[20], -cospi_8_64, - s2[27], cospi_24_64); - - s1[21] = multiply_accumulate_shift_and_narrow_s32_dual(s2[21], -cospi_24_64, - s2[26], -cospi_8_64); - s1[26] = multiply_accumulate_shift_and_narrow_s32_dual(s2[21], -cospi_8_64, - s2[26], cospi_24_64); - - // stage 6 - s2[0] = highbd_idct_add_dual(s1[0], s1[7]); - s2[1] = highbd_idct_add_dual(s1[0], s1[6]); - s2[2] = highbd_idct_add_dual(s1[0], s1[5]); - s2[3] = highbd_idct_add_dual(s1[0], s1[4]); - s2[4] = highbd_idct_sub_dual(s1[0], s1[4]); - s2[5] = highbd_idct_sub_dual(s1[0], s1[5]); - s2[6] = highbd_idct_sub_dual(s1[0], s1[6]); - s2[7] = highbd_idct_sub_dual(s1[0], s1[7]); - - s2[10] = sub_multiply_shift_and_narrow_s32_dual(s2[14], s2[9], cospi_16_64); - s2[13] = add_multiply_shift_and_narrow_s32_dual(s2[9], s2[14], cospi_16_64); - - s2[11] = sub_multiply_shift_and_narrow_s32_dual(s2[15], s2[8], cospi_16_64); - s2[12] = add_multiply_shift_and_narrow_s32_dual(s2[8], s2[15], cospi_16_64); - - s2[16] = highbd_idct_add_dual(s1[16], s2[23]); - s2[17] = highbd_idct_add_dual(s1[17], s2[22]); - s2[18] = highbd_idct_add_dual(s1[18], s1[21]); - s2[19] = highbd_idct_add_dual(s1[19], s1[20]); - s2[20] = highbd_idct_sub_dual(s1[19], s1[20]); - s2[21] = highbd_idct_sub_dual(s1[18], s1[21]); - s2[22] = highbd_idct_sub_dual(s1[17], s2[22]); - s2[23] = highbd_idct_sub_dual(s1[16], s2[23]); - - s3[24] = highbd_idct_sub_dual(s1[31], s2[24]); - s3[25] = highbd_idct_sub_dual(s1[30], s2[25]); - s3[26] = highbd_idct_sub_dual(s1[29], s1[26]); - s3[27] = highbd_idct_sub_dual(s1[28], s1[27]); - s2[28] = highbd_idct_add_dual(s1[27], s1[28]); - s2[29] = highbd_idct_add_dual(s1[26], s1[29]); - s2[30] = highbd_idct_add_dual(s2[25], s1[30]); - s2[31] = highbd_idct_add_dual(s2[24], s1[31]); - - // stage 7 - s1[0] = highbd_idct_add_dual(s2[0], s2[15]); - s1[1] = highbd_idct_add_dual(s2[1], s2[14]); - s1[2] = highbd_idct_add_dual(s2[2], s2[13]); - s1[3] = highbd_idct_add_dual(s2[3], s2[12]); - s1[4] = highbd_idct_add_dual(s2[4], s2[11]); - s1[5] = highbd_idct_add_dual(s2[5], s2[10]); - s1[6] = highbd_idct_add_dual(s2[6], s2[9]); - s1[7] = highbd_idct_add_dual(s2[7], s2[8]); - s1[8] = highbd_idct_sub_dual(s2[7], s2[8]); - s1[9] = highbd_idct_sub_dual(s2[6], s2[9]); - s1[10] = highbd_idct_sub_dual(s2[5], s2[10]); - s1[11] = highbd_idct_sub_dual(s2[4], s2[11]); - s1[12] = highbd_idct_sub_dual(s2[3], s2[12]); - s1[13] = highbd_idct_sub_dual(s2[2], s2[13]); - s1[14] = highbd_idct_sub_dual(s2[1], s2[14]); - s1[15] = highbd_idct_sub_dual(s2[0], s2[15]); - - s1[20] = sub_multiply_shift_and_narrow_s32_dual(s3[27], s2[20], cospi_16_64); - s1[27] = add_multiply_shift_and_narrow_s32_dual(s2[20], s3[27], cospi_16_64); - - s1[21] = sub_multiply_shift_and_narrow_s32_dual(s3[26], s2[21], cospi_16_64); - s1[26] = add_multiply_shift_and_narrow_s32_dual(s2[21], s3[26], cospi_16_64); - - s1[22] = sub_multiply_shift_and_narrow_s32_dual(s3[25], s2[22], cospi_16_64); - s1[25] = add_multiply_shift_and_narrow_s32_dual(s2[22], s3[25], cospi_16_64); - - s1[23] = sub_multiply_shift_and_narrow_s32_dual(s3[24], s2[23], cospi_16_64); - s1[24] = add_multiply_shift_and_narrow_s32_dual(s2[23], s3[24], cospi_16_64); - - // final stage - s3[0] = highbd_idct_add_dual(s1[0], s2[31]); - s3[1] = highbd_idct_add_dual(s1[1], s2[30]); - s3[2] = highbd_idct_add_dual(s1[2], s2[29]); - s3[3] = highbd_idct_add_dual(s1[3], s2[28]); - s3[4] = highbd_idct_add_dual(s1[4], s1[27]); - s3[5] = highbd_idct_add_dual(s1[5], s1[26]); - s3[6] = highbd_idct_add_dual(s1[6], s1[25]); - s3[7] = highbd_idct_add_dual(s1[7], s1[24]); - s3[8] = highbd_idct_add_dual(s1[8], s1[23]); - s3[9] = highbd_idct_add_dual(s1[9], s1[22]); - s3[10] = highbd_idct_add_dual(s1[10], s1[21]); - s3[11] = highbd_idct_add_dual(s1[11], s1[20]); - s3[12] = highbd_idct_add_dual(s1[12], s2[19]); - s3[13] = highbd_idct_add_dual(s1[13], s2[18]); - s3[14] = highbd_idct_add_dual(s1[14], s2[17]); - s3[15] = highbd_idct_add_dual(s1[15], s2[16]); - s3[16] = highbd_idct_sub_dual(s1[15], s2[16]); - s3[17] = highbd_idct_sub_dual(s1[14], s2[17]); - s3[18] = highbd_idct_sub_dual(s1[13], s2[18]); - s3[19] = highbd_idct_sub_dual(s1[12], s2[19]); - s3[20] = highbd_idct_sub_dual(s1[11], s1[20]); - s3[21] = highbd_idct_sub_dual(s1[10], s1[21]); - s3[22] = highbd_idct_sub_dual(s1[9], s1[22]); - s3[23] = highbd_idct_sub_dual(s1[8], s1[23]); - s3[24] = highbd_idct_sub_dual(s1[7], s1[24]); - s3[25] = highbd_idct_sub_dual(s1[6], s1[25]); - s3[26] = highbd_idct_sub_dual(s1[5], s1[26]); - s3[27] = highbd_idct_sub_dual(s1[4], s1[27]); - s3[28] = highbd_idct_sub_dual(s1[3], s2[28]); - s3[29] = highbd_idct_sub_dual(s1[2], s2[29]); - s3[30] = highbd_idct_sub_dual(s1[1], s2[30]); - s3[31] = highbd_idct_sub_dual(s1[0], s2[31]); - - vst1q_s32(output, s3[0].val[0]); - output += 4; - vst1q_s32(output, s3[0].val[1]); - output += 4; - vst1q_s32(output, s3[1].val[0]); - output += 4; - vst1q_s32(output, s3[1].val[1]); - output += 4; - vst1q_s32(output, s3[2].val[0]); - output += 4; - vst1q_s32(output, s3[2].val[1]); - output += 4; - vst1q_s32(output, s3[3].val[0]); - output += 4; - vst1q_s32(output, s3[3].val[1]); - output += 4; - vst1q_s32(output, s3[4].val[0]); - output += 4; - vst1q_s32(output, s3[4].val[1]); - output += 4; - vst1q_s32(output, s3[5].val[0]); - output += 4; - vst1q_s32(output, s3[5].val[1]); - output += 4; - vst1q_s32(output, s3[6].val[0]); - output += 4; - vst1q_s32(output, s3[6].val[1]); - output += 4; - vst1q_s32(output, s3[7].val[0]); - output += 4; - vst1q_s32(output, s3[7].val[1]); - output += 4; - - vst1q_s32(output, s3[8].val[0]); - output += 4; - vst1q_s32(output, s3[8].val[1]); - output += 4; - vst1q_s32(output, s3[9].val[0]); - output += 4; - vst1q_s32(output, s3[9].val[1]); - output += 4; - vst1q_s32(output, s3[10].val[0]); - output += 4; - vst1q_s32(output, s3[10].val[1]); - output += 4; - vst1q_s32(output, s3[11].val[0]); - output += 4; - vst1q_s32(output, s3[11].val[1]); - output += 4; - vst1q_s32(output, s3[12].val[0]); - output += 4; - vst1q_s32(output, s3[12].val[1]); - output += 4; - vst1q_s32(output, s3[13].val[0]); - output += 4; - vst1q_s32(output, s3[13].val[1]); - output += 4; - vst1q_s32(output, s3[14].val[0]); - output += 4; - vst1q_s32(output, s3[14].val[1]); - output += 4; - vst1q_s32(output, s3[15].val[0]); - output += 4; - vst1q_s32(output, s3[15].val[1]); - output += 4; - - vst1q_s32(output, s3[16].val[0]); - output += 4; - vst1q_s32(output, s3[16].val[1]); - output += 4; - vst1q_s32(output, s3[17].val[0]); - output += 4; - vst1q_s32(output, s3[17].val[1]); - output += 4; - vst1q_s32(output, s3[18].val[0]); - output += 4; - vst1q_s32(output, s3[18].val[1]); - output += 4; - vst1q_s32(output, s3[19].val[0]); - output += 4; - vst1q_s32(output, s3[19].val[1]); - output += 4; - vst1q_s32(output, s3[20].val[0]); - output += 4; - vst1q_s32(output, s3[20].val[1]); - output += 4; - vst1q_s32(output, s3[21].val[0]); - output += 4; - vst1q_s32(output, s3[21].val[1]); - output += 4; - vst1q_s32(output, s3[22].val[0]); - output += 4; - vst1q_s32(output, s3[22].val[1]); - output += 4; - vst1q_s32(output, s3[23].val[0]); - output += 4; - vst1q_s32(output, s3[23].val[1]); - output += 4; - - vst1q_s32(output, s3[24].val[0]); - output += 4; - vst1q_s32(output, s3[24].val[1]); - output += 4; - vst1q_s32(output, s3[25].val[0]); - output += 4; - vst1q_s32(output, s3[25].val[1]); - output += 4; - vst1q_s32(output, s3[26].val[0]); - output += 4; - vst1q_s32(output, s3[26].val[1]); - output += 4; - vst1q_s32(output, s3[27].val[0]); - output += 4; - vst1q_s32(output, s3[27].val[1]); - output += 4; - vst1q_s32(output, s3[28].val[0]); - output += 4; - vst1q_s32(output, s3[28].val[1]); - output += 4; - vst1q_s32(output, s3[29].val[0]); - output += 4; - vst1q_s32(output, s3[29].val[1]); - output += 4; - vst1q_s32(output, s3[30].val[0]); - output += 4; - vst1q_s32(output, s3[30].val[1]); - output += 4; - vst1q_s32(output, s3[31].val[0]); - output += 4; - vst1q_s32(output, s3[31].val[1]); -} - -static void vpx_highbd_idct32_8_neon(const int32_t *input, uint16_t *output, - int stride, const int bd) { - int32x4x2_t in[8], s1[32], s2[32], s3[32], out[32]; - - load_and_transpose_s32_8x8(input, 8, &in[0], &in[1], &in[2], &in[3], &in[4], - &in[5], &in[6], &in[7]); - - // stage 1 - s1[16] = multiply_shift_and_narrow_s32_dual(in[1], cospi_31_64); - s1[31] = multiply_shift_and_narrow_s32_dual(in[1], cospi_1_64); - - // Different for _8_ - s1[19] = multiply_shift_and_narrow_s32_dual(in[7], -cospi_25_64); - s1[28] = multiply_shift_and_narrow_s32_dual(in[7], cospi_7_64); - - s1[20] = multiply_shift_and_narrow_s32_dual(in[5], cospi_27_64); - s1[27] = multiply_shift_and_narrow_s32_dual(in[5], cospi_5_64); - - s1[23] = multiply_shift_and_narrow_s32_dual(in[3], -cospi_29_64); - s1[24] = multiply_shift_and_narrow_s32_dual(in[3], cospi_3_64); - - // stage 2 - s2[8] = multiply_shift_and_narrow_s32_dual(in[2], cospi_30_64); - s2[15] = multiply_shift_and_narrow_s32_dual(in[2], cospi_2_64); - - s2[11] = multiply_shift_and_narrow_s32_dual(in[6], -cospi_26_64); - s2[12] = multiply_shift_and_narrow_s32_dual(in[6], cospi_6_64); - - // stage 3 - s1[4] = multiply_shift_and_narrow_s32_dual(in[4], cospi_28_64); - s1[7] = multiply_shift_and_narrow_s32_dual(in[4], cospi_4_64); - - s1[17] = multiply_accumulate_shift_and_narrow_s32_dual(s1[16], -cospi_4_64, - s1[31], cospi_28_64); - s1[30] = multiply_accumulate_shift_and_narrow_s32_dual(s1[16], cospi_28_64, - s1[31], cospi_4_64); - - // Different for _8_ - s1[18] = multiply_accumulate_shift_and_narrow_s32_dual(s1[19], -cospi_28_64, - s1[28], -cospi_4_64); - s1[29] = multiply_accumulate_shift_and_narrow_s32_dual(s1[19], -cospi_4_64, - s1[28], cospi_28_64); - - s1[21] = multiply_accumulate_shift_and_narrow_s32_dual(s1[20], -cospi_20_64, - s1[27], cospi_12_64); - s1[26] = multiply_accumulate_shift_and_narrow_s32_dual(s1[20], cospi_12_64, - s1[27], cospi_20_64); - - s1[22] = multiply_accumulate_shift_and_narrow_s32_dual(s1[23], -cospi_12_64, - s1[24], -cospi_20_64); - s1[25] = multiply_accumulate_shift_and_narrow_s32_dual(s1[23], -cospi_20_64, - s1[24], cospi_12_64); - - // stage 4 - s1[0] = multiply_shift_and_narrow_s32_dual(in[0], cospi_16_64); - - s2[9] = multiply_accumulate_shift_and_narrow_s32_dual(s2[8], -cospi_8_64, - s2[15], cospi_24_64); - s2[14] = multiply_accumulate_shift_and_narrow_s32_dual(s2[8], cospi_24_64, - s2[15], cospi_8_64); - - s2[10] = multiply_accumulate_shift_and_narrow_s32_dual(s2[11], -cospi_24_64, - s2[12], -cospi_8_64); - s2[13] = multiply_accumulate_shift_and_narrow_s32_dual(s2[11], -cospi_8_64, - s2[12], cospi_24_64); - - s2[16] = highbd_idct_add_dual(s1[16], s1[19]); - - s2[17] = highbd_idct_add_dual(s1[17], s1[18]); - s2[18] = highbd_idct_sub_dual(s1[17], s1[18]); - - s2[19] = highbd_idct_sub_dual(s1[16], s1[19]); - - s2[20] = highbd_idct_sub_dual(s1[23], s1[20]); - s2[21] = highbd_idct_sub_dual(s1[22], s1[21]); - - s2[22] = highbd_idct_add_dual(s1[21], s1[22]); - s2[23] = highbd_idct_add_dual(s1[20], s1[23]); - - s2[24] = highbd_idct_add_dual(s1[24], s1[27]); - s2[25] = highbd_idct_add_dual(s1[25], s1[26]); - s2[26] = highbd_idct_sub_dual(s1[25], s1[26]); - s2[27] = highbd_idct_sub_dual(s1[24], s1[27]); - - s2[28] = highbd_idct_sub_dual(s1[31], s1[28]); - s2[29] = highbd_idct_sub_dual(s1[30], s1[29]); - s2[30] = highbd_idct_add_dual(s1[29], s1[30]); - s2[31] = highbd_idct_add_dual(s1[28], s1[31]); - - // stage 5 - s1[5] = sub_multiply_shift_and_narrow_s32_dual(s1[7], s1[4], cospi_16_64); - s1[6] = add_multiply_shift_and_narrow_s32_dual(s1[4], s1[7], cospi_16_64); - - s1[8] = highbd_idct_add_dual(s2[8], s2[11]); - s1[9] = highbd_idct_add_dual(s2[9], s2[10]); - s1[10] = highbd_idct_sub_dual(s2[9], s2[10]); - s1[11] = highbd_idct_sub_dual(s2[8], s2[11]); - s1[12] = highbd_idct_sub_dual(s2[15], s2[12]); - s1[13] = highbd_idct_sub_dual(s2[14], s2[13]); - s1[14] = highbd_idct_add_dual(s2[13], s2[14]); - s1[15] = highbd_idct_add_dual(s2[12], s2[15]); - - s1[18] = multiply_accumulate_shift_and_narrow_s32_dual(s2[18], -cospi_8_64, - s2[29], cospi_24_64); - s1[29] = multiply_accumulate_shift_and_narrow_s32_dual(s2[18], cospi_24_64, - s2[29], cospi_8_64); - - s1[19] = multiply_accumulate_shift_and_narrow_s32_dual(s2[19], -cospi_8_64, - s2[28], cospi_24_64); - s1[28] = multiply_accumulate_shift_and_narrow_s32_dual(s2[19], cospi_24_64, - s2[28], cospi_8_64); - - s1[20] = multiply_accumulate_shift_and_narrow_s32_dual(s2[20], -cospi_24_64, - s2[27], -cospi_8_64); - s1[27] = multiply_accumulate_shift_and_narrow_s32_dual(s2[20], -cospi_8_64, - s2[27], cospi_24_64); - - s1[21] = multiply_accumulate_shift_and_narrow_s32_dual(s2[21], -cospi_24_64, - s2[26], -cospi_8_64); - s1[26] = multiply_accumulate_shift_and_narrow_s32_dual(s2[21], -cospi_8_64, - s2[26], cospi_24_64); - - // stage 6 - s2[0] = highbd_idct_add_dual(s1[0], s1[7]); - s2[1] = highbd_idct_add_dual(s1[0], s1[6]); - s2[2] = highbd_idct_add_dual(s1[0], s1[5]); - s2[3] = highbd_idct_add_dual(s1[0], s1[4]); - s2[4] = highbd_idct_sub_dual(s1[0], s1[4]); - s2[5] = highbd_idct_sub_dual(s1[0], s1[5]); - s2[6] = highbd_idct_sub_dual(s1[0], s1[6]); - s2[7] = highbd_idct_sub_dual(s1[0], s1[7]); - - s2[10] = sub_multiply_shift_and_narrow_s32_dual(s1[13], s1[10], cospi_16_64); - s2[13] = add_multiply_shift_and_narrow_s32_dual(s1[10], s1[13], cospi_16_64); - - s2[11] = sub_multiply_shift_and_narrow_s32_dual(s1[12], s1[11], cospi_16_64); - s2[12] = add_multiply_shift_and_narrow_s32_dual(s1[11], s1[12], cospi_16_64); - - s1[16] = highbd_idct_add_dual(s2[16], s2[23]); - s1[17] = highbd_idct_add_dual(s2[17], s2[22]); - s2[18] = highbd_idct_add_dual(s1[18], s1[21]); - s2[19] = highbd_idct_add_dual(s1[19], s1[20]); - s2[20] = highbd_idct_sub_dual(s1[19], s1[20]); - s2[21] = highbd_idct_sub_dual(s1[18], s1[21]); - s1[22] = highbd_idct_sub_dual(s2[17], s2[22]); - s1[23] = highbd_idct_sub_dual(s2[16], s2[23]); - - s3[24] = highbd_idct_sub_dual(s2[31], s2[24]); - s3[25] = highbd_idct_sub_dual(s2[30], s2[25]); - s3[26] = highbd_idct_sub_dual(s1[29], s1[26]); - s3[27] = highbd_idct_sub_dual(s1[28], s1[27]); - s2[28] = highbd_idct_add_dual(s1[27], s1[28]); - s2[29] = highbd_idct_add_dual(s1[26], s1[29]); - s2[30] = highbd_idct_add_dual(s2[25], s2[30]); - s2[31] = highbd_idct_add_dual(s2[24], s2[31]); - - // stage 7 - s1[0] = highbd_idct_add_dual(s2[0], s1[15]); - s1[1] = highbd_idct_add_dual(s2[1], s1[14]); - s1[2] = highbd_idct_add_dual(s2[2], s2[13]); - s1[3] = highbd_idct_add_dual(s2[3], s2[12]); - s1[4] = highbd_idct_add_dual(s2[4], s2[11]); - s1[5] = highbd_idct_add_dual(s2[5], s2[10]); - s1[6] = highbd_idct_add_dual(s2[6], s1[9]); - s1[7] = highbd_idct_add_dual(s2[7], s1[8]); - s1[8] = highbd_idct_sub_dual(s2[7], s1[8]); - s1[9] = highbd_idct_sub_dual(s2[6], s1[9]); - s1[10] = highbd_idct_sub_dual(s2[5], s2[10]); - s1[11] = highbd_idct_sub_dual(s2[4], s2[11]); - s1[12] = highbd_idct_sub_dual(s2[3], s2[12]); - s1[13] = highbd_idct_sub_dual(s2[2], s2[13]); - s1[14] = highbd_idct_sub_dual(s2[1], s1[14]); - s1[15] = highbd_idct_sub_dual(s2[0], s1[15]); - - s1[20] = sub_multiply_shift_and_narrow_s32_dual(s3[27], s2[20], cospi_16_64); - s1[27] = add_multiply_shift_and_narrow_s32_dual(s2[20], s3[27], cospi_16_64); - - s1[21] = sub_multiply_shift_and_narrow_s32_dual(s3[26], s2[21], cospi_16_64); - s1[26] = add_multiply_shift_and_narrow_s32_dual(s2[21], s3[26], cospi_16_64); - - s2[22] = sub_multiply_shift_and_narrow_s32_dual(s3[25], s1[22], cospi_16_64); - s1[25] = add_multiply_shift_and_narrow_s32_dual(s1[22], s3[25], cospi_16_64); - - s2[23] = sub_multiply_shift_and_narrow_s32_dual(s3[24], s1[23], cospi_16_64); - s1[24] = add_multiply_shift_and_narrow_s32_dual(s1[23], s3[24], cospi_16_64); - - // final stage - out[0] = highbd_idct_add_dual(s1[0], s2[31]); - out[1] = highbd_idct_add_dual(s1[1], s2[30]); - out[2] = highbd_idct_add_dual(s1[2], s2[29]); - out[3] = highbd_idct_add_dual(s1[3], s2[28]); - out[4] = highbd_idct_add_dual(s1[4], s1[27]); - out[5] = highbd_idct_add_dual(s1[5], s1[26]); - out[6] = highbd_idct_add_dual(s1[6], s1[25]); - out[7] = highbd_idct_add_dual(s1[7], s1[24]); - out[8] = highbd_idct_add_dual(s1[8], s2[23]); - out[9] = highbd_idct_add_dual(s1[9], s2[22]); - out[10] = highbd_idct_add_dual(s1[10], s1[21]); - out[11] = highbd_idct_add_dual(s1[11], s1[20]); - out[12] = highbd_idct_add_dual(s1[12], s2[19]); - out[13] = highbd_idct_add_dual(s1[13], s2[18]); - out[14] = highbd_idct_add_dual(s1[14], s1[17]); - out[15] = highbd_idct_add_dual(s1[15], s1[16]); - out[16] = highbd_idct_sub_dual(s1[15], s1[16]); - out[17] = highbd_idct_sub_dual(s1[14], s1[17]); - out[18] = highbd_idct_sub_dual(s1[13], s2[18]); - out[19] = highbd_idct_sub_dual(s1[12], s2[19]); - out[20] = highbd_idct_sub_dual(s1[11], s1[20]); - out[21] = highbd_idct_sub_dual(s1[10], s1[21]); - out[22] = highbd_idct_sub_dual(s1[9], s2[22]); - out[23] = highbd_idct_sub_dual(s1[8], s2[23]); - out[24] = highbd_idct_sub_dual(s1[7], s1[24]); - out[25] = highbd_idct_sub_dual(s1[6], s1[25]); - out[26] = highbd_idct_sub_dual(s1[5], s1[26]); - out[27] = highbd_idct_sub_dual(s1[4], s1[27]); - out[28] = highbd_idct_sub_dual(s1[3], s2[28]); - out[29] = highbd_idct_sub_dual(s1[2], s2[29]); - out[30] = highbd_idct_sub_dual(s1[1], s2[30]); - out[31] = highbd_idct_sub_dual(s1[0], s2[31]); - - highbd_idct16x16_add_store(out, output, stride, bd); - highbd_idct16x16_add_store(out + 16, output + 16 * stride, stride, bd); -} - -void vpx_highbd_idct32x32_34_add_neon(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i; - - if (bd == 8) { - int16_t temp[32 * 8]; - int16_t *t = temp; - - vpx_idct32_6_neon(input, t); - - for (i = 0; i < 32; i += 8) { - vpx_idct32_8_neon(t, dest, stride, 1); - t += (8 * 8); - dest += 8; - } - } else { - int32_t temp[32 * 8]; - int32_t *t = temp; - - vpx_highbd_idct32_6_neon(input, t); - - for (i = 0; i < 32; i += 8) { - vpx_highbd_idct32_8_neon(t, dest, stride, bd); - t += (8 * 8); - dest += 8; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct32x32_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct32x32_add_neon.c deleted file mode 100644 index c1354c0c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct32x32_add_neon.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/inv_txfm.h" - -static INLINE void highbd_idct32x32_1_add_pos_kernel(uint16_t **dest, - const int stride, - const int16x8_t res, - const int16x8_t max) { - const uint16x8_t a0 = vld1q_u16(*dest); - const uint16x8_t a1 = vld1q_u16(*dest + 8); - const uint16x8_t a2 = vld1q_u16(*dest + 16); - const uint16x8_t a3 = vld1q_u16(*dest + 24); - const int16x8_t b0 = vaddq_s16(res, vreinterpretq_s16_u16(a0)); - const int16x8_t b1 = vaddq_s16(res, vreinterpretq_s16_u16(a1)); - const int16x8_t b2 = vaddq_s16(res, vreinterpretq_s16_u16(a2)); - const int16x8_t b3 = vaddq_s16(res, vreinterpretq_s16_u16(a3)); - const int16x8_t c0 = vminq_s16(b0, max); - const int16x8_t c1 = vminq_s16(b1, max); - const int16x8_t c2 = vminq_s16(b2, max); - const int16x8_t c3 = vminq_s16(b3, max); - vst1q_u16(*dest, vreinterpretq_u16_s16(c0)); - vst1q_u16(*dest + 8, vreinterpretq_u16_s16(c1)); - vst1q_u16(*dest + 16, vreinterpretq_u16_s16(c2)); - vst1q_u16(*dest + 24, vreinterpretq_u16_s16(c3)); - *dest += stride; -} - -static INLINE void highbd_idct32x32_1_add_neg_kernel(uint16_t **dest, - const int stride, - const int16x8_t res) { - const uint16x8_t a0 = vld1q_u16(*dest); - const uint16x8_t a1 = vld1q_u16(*dest + 8); - const uint16x8_t a2 = vld1q_u16(*dest + 16); - const uint16x8_t a3 = vld1q_u16(*dest + 24); - const int16x8_t b0 = vaddq_s16(res, vreinterpretq_s16_u16(a0)); - const int16x8_t b1 = vaddq_s16(res, vreinterpretq_s16_u16(a1)); - const int16x8_t b2 = vaddq_s16(res, vreinterpretq_s16_u16(a2)); - const int16x8_t b3 = vaddq_s16(res, vreinterpretq_s16_u16(a3)); - const uint16x8_t c0 = vqshluq_n_s16(b0, 0); - const uint16x8_t c1 = vqshluq_n_s16(b1, 0); - const uint16x8_t c2 = vqshluq_n_s16(b2, 0); - const uint16x8_t c3 = vqshluq_n_s16(b3, 0); - vst1q_u16(*dest, c0); - vst1q_u16(*dest + 8, c1); - vst1q_u16(*dest + 16, c2); - vst1q_u16(*dest + 24, c3); - *dest += stride; -} - -void vpx_highbd_idct32x32_1_add_neon(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - const tran_low_t out0 = HIGHBD_WRAPLOW( - dct_const_round_shift(input[0] * (tran_high_t)cospi_16_64), bd); - const tran_low_t out1 = HIGHBD_WRAPLOW( - dct_const_round_shift(out0 * (tran_high_t)cospi_16_64), bd); - const int16_t a1 = ROUND_POWER_OF_TWO(out1, 6); - const int16x8_t dc = vdupq_n_s16(a1); - int i; - - if (a1 >= 0) { - const int16x8_t max = vdupq_n_s16((1 << bd) - 1); - for (i = 0; i < 8; ++i) { - highbd_idct32x32_1_add_pos_kernel(&dest, stride, dc, max); - highbd_idct32x32_1_add_pos_kernel(&dest, stride, dc, max); - highbd_idct32x32_1_add_pos_kernel(&dest, stride, dc, max); - highbd_idct32x32_1_add_pos_kernel(&dest, stride, dc, max); - } - } else { - for (i = 0; i < 8; ++i) { - highbd_idct32x32_1_add_neg_kernel(&dest, stride, dc); - highbd_idct32x32_1_add_neg_kernel(&dest, stride, dc); - highbd_idct32x32_1_add_neg_kernel(&dest, stride, dc); - highbd_idct32x32_1_add_neg_kernel(&dest, stride, dc); - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct4x4_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct4x4_add_neon.c deleted file mode 100644 index 7be1dad1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct4x4_add_neon.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/highbd_idct_neon.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/inv_txfm.h" - -// res is in reverse row order -static INLINE void highbd_idct4x4_1_add_kernel2(uint16_t **dest, - const int stride, - const int16x8_t res, - const int16x8_t max) { - const uint16x4_t a0 = vld1_u16(*dest); - const uint16x4_t a1 = vld1_u16(*dest + stride); - const int16x8_t a = vreinterpretq_s16_u16(vcombine_u16(a1, a0)); - // Note: In some profile tests, res is quite close to +/-32767. - // We use saturating addition. - const int16x8_t b = vqaddq_s16(res, a); - const int16x8_t c = vminq_s16(b, max); - const uint16x8_t d = vqshluq_n_s16(c, 0); - vst1_u16(*dest, vget_high_u16(d)); - *dest += stride; - vst1_u16(*dest, vget_low_u16(d)); - *dest += stride; -} - -void vpx_highbd_idct4x4_1_add_neon(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - const int16x8_t max = vdupq_n_s16((1 << bd) - 1); - const tran_low_t out0 = HIGHBD_WRAPLOW( - dct_const_round_shift(input[0] * (tran_high_t)cospi_16_64), bd); - const tran_low_t out1 = HIGHBD_WRAPLOW( - dct_const_round_shift(out0 * (tran_high_t)cospi_16_64), bd); - const int16_t a1 = ROUND_POWER_OF_TWO(out1, 4); - const int16x8_t dc = vdupq_n_s16(a1); - - highbd_idct4x4_1_add_kernel1(&dest, stride, dc, max); - highbd_idct4x4_1_add_kernel1(&dest, stride, dc, max); -} - -void vpx_highbd_idct4x4_16_add_neon(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - const int16x8_t max = vdupq_n_s16((1 << bd) - 1); - int16x8_t a[2]; - int32x4_t c[4]; - - c[0] = vld1q_s32(input); - c[1] = vld1q_s32(input + 4); - c[2] = vld1q_s32(input + 8); - c[3] = vld1q_s32(input + 12); - - if (bd == 8) { - // Rows - a[0] = vcombine_s16(vmovn_s32(c[0]), vmovn_s32(c[1])); - a[1] = vcombine_s16(vmovn_s32(c[2]), vmovn_s32(c[3])); - transpose_idct4x4_16_bd8(a); - - // Columns - a[1] = vcombine_s16(vget_high_s16(a[1]), vget_low_s16(a[1])); - transpose_idct4x4_16_bd8(a); - a[0] = vrshrq_n_s16(a[0], 4); - a[1] = vrshrq_n_s16(a[1], 4); - } else { - const int32x4_t cospis = vld1q_s32(kCospi32); - - if (bd == 10) { - idct4x4_16_kernel_bd10(cospis, c); - idct4x4_16_kernel_bd10(cospis, c); - } else { - idct4x4_16_kernel_bd12(cospis, c); - idct4x4_16_kernel_bd12(cospis, c); - } - a[0] = vcombine_s16(vqrshrn_n_s32(c[0], 4), vqrshrn_n_s32(c[1], 4)); - a[1] = vcombine_s16(vqrshrn_n_s32(c[3], 4), vqrshrn_n_s32(c[2], 4)); - } - - highbd_idct4x4_1_add_kernel1(&dest, stride, a[0], max); - highbd_idct4x4_1_add_kernel2(&dest, stride, a[1], max); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct8x8_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct8x8_add_neon.c deleted file mode 100644 index bed3227c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct8x8_add_neon.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/highbd_idct_neon.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/inv_txfm.h" - -static INLINE void highbd_idct8x8_1_add_pos_kernel(uint16_t **dest, - const int stride, - const int16x8_t res, - const int16x8_t max) { - const uint16x8_t a = vld1q_u16(*dest); - const int16x8_t b = vaddq_s16(res, vreinterpretq_s16_u16(a)); - const int16x8_t c = vminq_s16(b, max); - vst1q_u16(*dest, vreinterpretq_u16_s16(c)); - *dest += stride; -} - -static INLINE void highbd_idct8x8_1_add_neg_kernel(uint16_t **dest, - const int stride, - const int16x8_t res) { - const uint16x8_t a = vld1q_u16(*dest); - const int16x8_t b = vaddq_s16(res, vreinterpretq_s16_u16(a)); - const uint16x8_t c = vqshluq_n_s16(b, 0); - vst1q_u16(*dest, c); - *dest += stride; -} - -void vpx_highbd_idct8x8_1_add_neon(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - const tran_low_t out0 = HIGHBD_WRAPLOW( - dct_const_round_shift(input[0] * (tran_high_t)cospi_16_64), bd); - const tran_low_t out1 = HIGHBD_WRAPLOW( - dct_const_round_shift(out0 * (tran_high_t)cospi_16_64), bd); - const int16_t a1 = ROUND_POWER_OF_TWO(out1, 5); - const int16x8_t dc = vdupq_n_s16(a1); - - if (a1 >= 0) { - const int16x8_t max = vdupq_n_s16((1 << bd) - 1); - highbd_idct8x8_1_add_pos_kernel(&dest, stride, dc, max); - highbd_idct8x8_1_add_pos_kernel(&dest, stride, dc, max); - highbd_idct8x8_1_add_pos_kernel(&dest, stride, dc, max); - highbd_idct8x8_1_add_pos_kernel(&dest, stride, dc, max); - highbd_idct8x8_1_add_pos_kernel(&dest, stride, dc, max); - highbd_idct8x8_1_add_pos_kernel(&dest, stride, dc, max); - highbd_idct8x8_1_add_pos_kernel(&dest, stride, dc, max); - highbd_idct8x8_1_add_pos_kernel(&dest, stride, dc, max); - } else { - highbd_idct8x8_1_add_neg_kernel(&dest, stride, dc); - highbd_idct8x8_1_add_neg_kernel(&dest, stride, dc); - highbd_idct8x8_1_add_neg_kernel(&dest, stride, dc); - highbd_idct8x8_1_add_neg_kernel(&dest, stride, dc); - highbd_idct8x8_1_add_neg_kernel(&dest, stride, dc); - highbd_idct8x8_1_add_neg_kernel(&dest, stride, dc); - highbd_idct8x8_1_add_neg_kernel(&dest, stride, dc); - highbd_idct8x8_1_add_neg_kernel(&dest, stride, dc); - } -} - -static INLINE void idct8x8_12_half1d_bd10( - const int32x4_t cospis0, const int32x4_t cospis1, int32x4_t *const io0, - int32x4_t *const io1, int32x4_t *const io2, int32x4_t *const io3, - int32x4_t *const io4, int32x4_t *const io5, int32x4_t *const io6, - int32x4_t *const io7) { - int32x4_t step1[8], step2[8]; - - transpose_s32_4x4(io0, io1, io2, io3); - - // stage 1 - step1[4] = vmulq_lane_s32(*io1, vget_high_s32(cospis1), 1); - step1[5] = vmulq_lane_s32(*io3, vget_high_s32(cospis1), 0); - step1[6] = vmulq_lane_s32(*io3, vget_low_s32(cospis1), 1); - step1[7] = vmulq_lane_s32(*io1, vget_low_s32(cospis1), 0); - step1[4] = vrshrq_n_s32(step1[4], DCT_CONST_BITS); - step1[5] = vrshrq_n_s32(step1[5], DCT_CONST_BITS); - step1[6] = vrshrq_n_s32(step1[6], DCT_CONST_BITS); - step1[7] = vrshrq_n_s32(step1[7], DCT_CONST_BITS); - - // stage 2 - step2[1] = vmulq_lane_s32(*io0, vget_high_s32(cospis0), 0); - step2[2] = vmulq_lane_s32(*io2, vget_high_s32(cospis0), 1); - step2[3] = vmulq_lane_s32(*io2, vget_low_s32(cospis0), 1); - step2[1] = vrshrq_n_s32(step2[1], DCT_CONST_BITS); - step2[2] = vrshrq_n_s32(step2[2], DCT_CONST_BITS); - step2[3] = vrshrq_n_s32(step2[3], DCT_CONST_BITS); - - step2[4] = vaddq_s32(step1[4], step1[5]); - step2[5] = vsubq_s32(step1[4], step1[5]); - step2[6] = vsubq_s32(step1[7], step1[6]); - step2[7] = vaddq_s32(step1[7], step1[6]); - - // stage 3 - step1[0] = vaddq_s32(step2[1], step2[3]); - step1[1] = vaddq_s32(step2[1], step2[2]); - step1[2] = vsubq_s32(step2[1], step2[2]); - step1[3] = vsubq_s32(step2[1], step2[3]); - - step1[6] = vmulq_lane_s32(step2[6], vget_high_s32(cospis0), 0); - step1[5] = vmlsq_lane_s32(step1[6], step2[5], vget_high_s32(cospis0), 0); - step1[6] = vmlaq_lane_s32(step1[6], step2[5], vget_high_s32(cospis0), 0); - step1[5] = vrshrq_n_s32(step1[5], DCT_CONST_BITS); - step1[6] = vrshrq_n_s32(step1[6], DCT_CONST_BITS); - - // stage 4 - *io0 = vaddq_s32(step1[0], step2[7]); - *io1 = vaddq_s32(step1[1], step1[6]); - *io2 = vaddq_s32(step1[2], step1[5]); - *io3 = vaddq_s32(step1[3], step2[4]); - *io4 = vsubq_s32(step1[3], step2[4]); - *io5 = vsubq_s32(step1[2], step1[5]); - *io6 = vsubq_s32(step1[1], step1[6]); - *io7 = vsubq_s32(step1[0], step2[7]); -} - -static INLINE void idct8x8_12_half1d_bd12( - const int32x4_t cospis0, const int32x4_t cospis1, int32x4_t *const io0, - int32x4_t *const io1, int32x4_t *const io2, int32x4_t *const io3, - int32x4_t *const io4, int32x4_t *const io5, int32x4_t *const io6, - int32x4_t *const io7) { - int32x2_t input1l, input1h, input3l, input3h; - int32x2_t step1l[2], step1h[2]; - int32x4_t step1[8], step2[8]; - int64x2_t t64[8]; - int32x2_t t32[8]; - - transpose_s32_4x4(io0, io1, io2, io3); - - // stage 1 - input1l = vget_low_s32(*io1); - input1h = vget_high_s32(*io1); - input3l = vget_low_s32(*io3); - input3h = vget_high_s32(*io3); - step1l[0] = vget_low_s32(*io0); - step1h[0] = vget_high_s32(*io0); - step1l[1] = vget_low_s32(*io2); - step1h[1] = vget_high_s32(*io2); - - t64[0] = vmull_lane_s32(input1l, vget_high_s32(cospis1), 1); - t64[1] = vmull_lane_s32(input1h, vget_high_s32(cospis1), 1); - t64[2] = vmull_lane_s32(input3l, vget_high_s32(cospis1), 0); - t64[3] = vmull_lane_s32(input3h, vget_high_s32(cospis1), 0); - t64[4] = vmull_lane_s32(input3l, vget_low_s32(cospis1), 1); - t64[5] = vmull_lane_s32(input3h, vget_low_s32(cospis1), 1); - t64[6] = vmull_lane_s32(input1l, vget_low_s32(cospis1), 0); - t64[7] = vmull_lane_s32(input1h, vget_low_s32(cospis1), 0); - t32[0] = vrshrn_n_s64(t64[0], DCT_CONST_BITS); - t32[1] = vrshrn_n_s64(t64[1], DCT_CONST_BITS); - t32[2] = vrshrn_n_s64(t64[2], DCT_CONST_BITS); - t32[3] = vrshrn_n_s64(t64[3], DCT_CONST_BITS); - t32[4] = vrshrn_n_s64(t64[4], DCT_CONST_BITS); - t32[5] = vrshrn_n_s64(t64[5], DCT_CONST_BITS); - t32[6] = vrshrn_n_s64(t64[6], DCT_CONST_BITS); - t32[7] = vrshrn_n_s64(t64[7], DCT_CONST_BITS); - step1[4] = vcombine_s32(t32[0], t32[1]); - step1[5] = vcombine_s32(t32[2], t32[3]); - step1[6] = vcombine_s32(t32[4], t32[5]); - step1[7] = vcombine_s32(t32[6], t32[7]); - - // stage 2 - t64[2] = vmull_lane_s32(step1l[0], vget_high_s32(cospis0), 0); - t64[3] = vmull_lane_s32(step1h[0], vget_high_s32(cospis0), 0); - t64[4] = vmull_lane_s32(step1l[1], vget_high_s32(cospis0), 1); - t64[5] = vmull_lane_s32(step1h[1], vget_high_s32(cospis0), 1); - t64[6] = vmull_lane_s32(step1l[1], vget_low_s32(cospis0), 1); - t64[7] = vmull_lane_s32(step1h[1], vget_low_s32(cospis0), 1); - t32[2] = vrshrn_n_s64(t64[2], DCT_CONST_BITS); - t32[3] = vrshrn_n_s64(t64[3], DCT_CONST_BITS); - t32[4] = vrshrn_n_s64(t64[4], DCT_CONST_BITS); - t32[5] = vrshrn_n_s64(t64[5], DCT_CONST_BITS); - t32[6] = vrshrn_n_s64(t64[6], DCT_CONST_BITS); - t32[7] = vrshrn_n_s64(t64[7], DCT_CONST_BITS); - step2[1] = vcombine_s32(t32[2], t32[3]); - step2[2] = vcombine_s32(t32[4], t32[5]); - step2[3] = vcombine_s32(t32[6], t32[7]); - - step2[4] = vaddq_s32(step1[4], step1[5]); - step2[5] = vsubq_s32(step1[4], step1[5]); - step2[6] = vsubq_s32(step1[7], step1[6]); - step2[7] = vaddq_s32(step1[7], step1[6]); - - // stage 3 - step1[0] = vaddq_s32(step2[1], step2[3]); - step1[1] = vaddq_s32(step2[1], step2[2]); - step1[2] = vsubq_s32(step2[1], step2[2]); - step1[3] = vsubq_s32(step2[1], step2[3]); - - t64[2] = vmull_lane_s32(vget_low_s32(step2[6]), vget_high_s32(cospis0), 0); - t64[3] = vmull_lane_s32(vget_high_s32(step2[6]), vget_high_s32(cospis0), 0); - t64[0] = - vmlsl_lane_s32(t64[2], vget_low_s32(step2[5]), vget_high_s32(cospis0), 0); - t64[1] = vmlsl_lane_s32(t64[3], vget_high_s32(step2[5]), - vget_high_s32(cospis0), 0); - t64[2] = - vmlal_lane_s32(t64[2], vget_low_s32(step2[5]), vget_high_s32(cospis0), 0); - t64[3] = vmlal_lane_s32(t64[3], vget_high_s32(step2[5]), - vget_high_s32(cospis0), 0); - t32[0] = vrshrn_n_s64(t64[0], DCT_CONST_BITS); - t32[1] = vrshrn_n_s64(t64[1], DCT_CONST_BITS); - t32[2] = vrshrn_n_s64(t64[2], DCT_CONST_BITS); - t32[3] = vrshrn_n_s64(t64[3], DCT_CONST_BITS); - step1[5] = vcombine_s32(t32[0], t32[1]); - step1[6] = vcombine_s32(t32[2], t32[3]); - - // stage 4 - *io0 = vaddq_s32(step1[0], step2[7]); - *io1 = vaddq_s32(step1[1], step1[6]); - *io2 = vaddq_s32(step1[2], step1[5]); - *io3 = vaddq_s32(step1[3], step2[4]); - *io4 = vsubq_s32(step1[3], step2[4]); - *io5 = vsubq_s32(step1[2], step1[5]); - *io6 = vsubq_s32(step1[1], step1[6]); - *io7 = vsubq_s32(step1[0], step2[7]); -} - -void vpx_highbd_idct8x8_12_add_neon(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int32x4_t a[16]; - int16x8_t c[8]; - - a[0] = vld1q_s32(input); - a[1] = vld1q_s32(input + 8); - a[2] = vld1q_s32(input + 16); - a[3] = vld1q_s32(input + 24); - - if (bd == 8) { - const int16x8_t cospis = vld1q_s16(kCospi); - const int16x8_t cospisd = vaddq_s16(cospis, cospis); - const int16x4_t cospis0 = vget_low_s16(cospis); // cospi 0, 8, 16, 24 - const int16x4_t cospisd0 = vget_low_s16(cospisd); // doubled 0, 8, 16, 24 - const int16x4_t cospisd1 = vget_high_s16(cospisd); // doubled 4, 12, 20, 28 - int16x4_t b[8]; - - b[0] = vmovn_s32(a[0]); - b[1] = vmovn_s32(a[1]); - b[2] = vmovn_s32(a[2]); - b[3] = vmovn_s32(a[3]); - - idct8x8_12_pass1_bd8(cospis0, cospisd0, cospisd1, b); - idct8x8_12_pass2_bd8(cospis0, cospisd0, cospisd1, b, c); - c[0] = vrshrq_n_s16(c[0], 5); - c[1] = vrshrq_n_s16(c[1], 5); - c[2] = vrshrq_n_s16(c[2], 5); - c[3] = vrshrq_n_s16(c[3], 5); - c[4] = vrshrq_n_s16(c[4], 5); - c[5] = vrshrq_n_s16(c[5], 5); - c[6] = vrshrq_n_s16(c[6], 5); - c[7] = vrshrq_n_s16(c[7], 5); - } else { - const int32x4_t cospis0 = vld1q_s32(kCospi32); // cospi 0, 8, 16, 24 - const int32x4_t cospis1 = vld1q_s32(kCospi32 + 4); // cospi 4, 12, 20, 28 - - if (bd == 10) { - idct8x8_12_half1d_bd10(cospis0, cospis1, &a[0], &a[1], &a[2], &a[3], - &a[4], &a[5], &a[6], &a[7]); - idct8x8_12_half1d_bd10(cospis0, cospis1, &a[0], &a[1], &a[2], &a[3], - &a[8], &a[9], &a[10], &a[11]); - idct8x8_12_half1d_bd10(cospis0, cospis1, &a[4], &a[5], &a[6], &a[7], - &a[12], &a[13], &a[14], &a[15]); - } else { - idct8x8_12_half1d_bd12(cospis0, cospis1, &a[0], &a[1], &a[2], &a[3], - &a[4], &a[5], &a[6], &a[7]); - idct8x8_12_half1d_bd12(cospis0, cospis1, &a[0], &a[1], &a[2], &a[3], - &a[8], &a[9], &a[10], &a[11]); - idct8x8_12_half1d_bd12(cospis0, cospis1, &a[4], &a[5], &a[6], &a[7], - &a[12], &a[13], &a[14], &a[15]); - } - c[0] = vcombine_s16(vrshrn_n_s32(a[0], 5), vrshrn_n_s32(a[4], 5)); - c[1] = vcombine_s16(vrshrn_n_s32(a[1], 5), vrshrn_n_s32(a[5], 5)); - c[2] = vcombine_s16(vrshrn_n_s32(a[2], 5), vrshrn_n_s32(a[6], 5)); - c[3] = vcombine_s16(vrshrn_n_s32(a[3], 5), vrshrn_n_s32(a[7], 5)); - c[4] = vcombine_s16(vrshrn_n_s32(a[8], 5), vrshrn_n_s32(a[12], 5)); - c[5] = vcombine_s16(vrshrn_n_s32(a[9], 5), vrshrn_n_s32(a[13], 5)); - c[6] = vcombine_s16(vrshrn_n_s32(a[10], 5), vrshrn_n_s32(a[14], 5)); - c[7] = vcombine_s16(vrshrn_n_s32(a[11], 5), vrshrn_n_s32(a[15], 5)); - } - highbd_add8x8(c, dest, stride, bd); -} - -void vpx_highbd_idct8x8_64_add_neon(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int32x4_t a[16]; - int16x8_t c[8]; - - a[0] = vld1q_s32(input); - a[1] = vld1q_s32(input + 4); - a[2] = vld1q_s32(input + 8); - a[3] = vld1q_s32(input + 12); - a[4] = vld1q_s32(input + 16); - a[5] = vld1q_s32(input + 20); - a[6] = vld1q_s32(input + 24); - a[7] = vld1q_s32(input + 28); - a[8] = vld1q_s32(input + 32); - a[9] = vld1q_s32(input + 36); - a[10] = vld1q_s32(input + 40); - a[11] = vld1q_s32(input + 44); - a[12] = vld1q_s32(input + 48); - a[13] = vld1q_s32(input + 52); - a[14] = vld1q_s32(input + 56); - a[15] = vld1q_s32(input + 60); - - if (bd == 8) { - const int16x8_t cospis = vld1q_s16(kCospi); - const int16x4_t cospis0 = vget_low_s16(cospis); // cospi 0, 8, 16, 24 - const int16x4_t cospis1 = vget_high_s16(cospis); // cospi 4, 12, 20, 28 - int16x8_t b[8]; - - b[0] = vcombine_s16(vmovn_s32(a[0]), vmovn_s32(a[1])); - b[1] = vcombine_s16(vmovn_s32(a[2]), vmovn_s32(a[3])); - b[2] = vcombine_s16(vmovn_s32(a[4]), vmovn_s32(a[5])); - b[3] = vcombine_s16(vmovn_s32(a[6]), vmovn_s32(a[7])); - b[4] = vcombine_s16(vmovn_s32(a[8]), vmovn_s32(a[9])); - b[5] = vcombine_s16(vmovn_s32(a[10]), vmovn_s32(a[11])); - b[6] = vcombine_s16(vmovn_s32(a[12]), vmovn_s32(a[13])); - b[7] = vcombine_s16(vmovn_s32(a[14]), vmovn_s32(a[15])); - - idct8x8_64_1d_bd8(cospis0, cospis1, b); - idct8x8_64_1d_bd8(cospis0, cospis1, b); - - c[0] = vrshrq_n_s16(b[0], 5); - c[1] = vrshrq_n_s16(b[1], 5); - c[2] = vrshrq_n_s16(b[2], 5); - c[3] = vrshrq_n_s16(b[3], 5); - c[4] = vrshrq_n_s16(b[4], 5); - c[5] = vrshrq_n_s16(b[5], 5); - c[6] = vrshrq_n_s16(b[6], 5); - c[7] = vrshrq_n_s16(b[7], 5); - } else { - const int32x4_t cospis0 = vld1q_s32(kCospi32); // cospi 0, 8, 16, 24 - const int32x4_t cospis1 = vld1q_s32(kCospi32 + 4); // cospi 4, 12, 20, 28 - - if (bd == 10) { - idct8x8_64_half1d_bd10(cospis0, cospis1, &a[0], &a[1], &a[2], &a[3], - &a[4], &a[5], &a[6], &a[7]); - idct8x8_64_half1d_bd10(cospis0, cospis1, &a[8], &a[9], &a[10], &a[11], - &a[12], &a[13], &a[14], &a[15]); - idct8x8_64_half1d_bd10(cospis0, cospis1, &a[0], &a[8], &a[1], &a[9], - &a[2], &a[10], &a[3], &a[11]); - idct8x8_64_half1d_bd10(cospis0, cospis1, &a[4], &a[12], &a[5], &a[13], - &a[6], &a[14], &a[7], &a[15]); - } else { - idct8x8_64_half1d_bd12(cospis0, cospis1, &a[0], &a[1], &a[2], &a[3], - &a[4], &a[5], &a[6], &a[7]); - idct8x8_64_half1d_bd12(cospis0, cospis1, &a[8], &a[9], &a[10], &a[11], - &a[12], &a[13], &a[14], &a[15]); - idct8x8_64_half1d_bd12(cospis0, cospis1, &a[0], &a[8], &a[1], &a[9], - &a[2], &a[10], &a[3], &a[11]); - idct8x8_64_half1d_bd12(cospis0, cospis1, &a[4], &a[12], &a[5], &a[13], - &a[6], &a[14], &a[7], &a[15]); - } - c[0] = vcombine_s16(vrshrn_n_s32(a[0], 5), vrshrn_n_s32(a[4], 5)); - c[1] = vcombine_s16(vrshrn_n_s32(a[8], 5), vrshrn_n_s32(a[12], 5)); - c[2] = vcombine_s16(vrshrn_n_s32(a[1], 5), vrshrn_n_s32(a[5], 5)); - c[3] = vcombine_s16(vrshrn_n_s32(a[9], 5), vrshrn_n_s32(a[13], 5)); - c[4] = vcombine_s16(vrshrn_n_s32(a[2], 5), vrshrn_n_s32(a[6], 5)); - c[5] = vcombine_s16(vrshrn_n_s32(a[10], 5), vrshrn_n_s32(a[14], 5)); - c[6] = vcombine_s16(vrshrn_n_s32(a[3], 5), vrshrn_n_s32(a[7], 5)); - c[7] = vcombine_s16(vrshrn_n_s32(a[11], 5), vrshrn_n_s32(a[15], 5)); - } - highbd_add8x8(c, dest, stride, bd); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct_neon.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct_neon.h deleted file mode 100644 index 518ef433..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_idct_neon.h +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_ARM_HIGHBD_IDCT_NEON_H_ -#define VPX_VPX_DSP_ARM_HIGHBD_IDCT_NEON_H_ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/inv_txfm.h" - -static INLINE void highbd_idct4x4_1_add_kernel1(uint16_t **dest, - const int stride, - const int16x8_t res, - const int16x8_t max) { - const uint16x4_t a0 = vld1_u16(*dest); - const uint16x4_t a1 = vld1_u16(*dest + stride); - const int16x8_t a = vreinterpretq_s16_u16(vcombine_u16(a0, a1)); - // Note: In some profile tests, res is quite close to +/-32767. - // We use saturating addition. - const int16x8_t b = vqaddq_s16(res, a); - const int16x8_t c = vminq_s16(b, max); - const uint16x8_t d = vqshluq_n_s16(c, 0); - vst1_u16(*dest, vget_low_u16(d)); - *dest += stride; - vst1_u16(*dest, vget_high_u16(d)); - *dest += stride; -} - -static INLINE void idct4x4_16_kernel_bd10(const int32x4_t cospis, - int32x4_t *const a) { - int32x4_t b0, b1, b2, b3; - - transpose_s32_4x4(&a[0], &a[1], &a[2], &a[3]); - b0 = vaddq_s32(a[0], a[2]); - b1 = vsubq_s32(a[0], a[2]); - b0 = vmulq_lane_s32(b0, vget_high_s32(cospis), 0); - b1 = vmulq_lane_s32(b1, vget_high_s32(cospis), 0); - b2 = vmulq_lane_s32(a[1], vget_high_s32(cospis), 1); - b3 = vmulq_lane_s32(a[1], vget_low_s32(cospis), 1); - b2 = vmlsq_lane_s32(b2, a[3], vget_low_s32(cospis), 1); - b3 = vmlaq_lane_s32(b3, a[3], vget_high_s32(cospis), 1); - b0 = vrshrq_n_s32(b0, DCT_CONST_BITS); - b1 = vrshrq_n_s32(b1, DCT_CONST_BITS); - b2 = vrshrq_n_s32(b2, DCT_CONST_BITS); - b3 = vrshrq_n_s32(b3, DCT_CONST_BITS); - a[0] = vaddq_s32(b0, b3); - a[1] = vaddq_s32(b1, b2); - a[2] = vsubq_s32(b1, b2); - a[3] = vsubq_s32(b0, b3); -} - -static INLINE void idct4x4_16_kernel_bd12(const int32x4_t cospis, - int32x4_t *const a) { - int32x4_t b0, b1, b2, b3; - int64x2_t c[12]; - - transpose_s32_4x4(&a[0], &a[1], &a[2], &a[3]); - b0 = vaddq_s32(a[0], a[2]); - b1 = vsubq_s32(a[0], a[2]); - c[0] = vmull_lane_s32(vget_low_s32(b0), vget_high_s32(cospis), 0); - c[1] = vmull_lane_s32(vget_high_s32(b0), vget_high_s32(cospis), 0); - c[2] = vmull_lane_s32(vget_low_s32(b1), vget_high_s32(cospis), 0); - c[3] = vmull_lane_s32(vget_high_s32(b1), vget_high_s32(cospis), 0); - c[4] = vmull_lane_s32(vget_low_s32(a[1]), vget_high_s32(cospis), 1); - c[5] = vmull_lane_s32(vget_high_s32(a[1]), vget_high_s32(cospis), 1); - c[6] = vmull_lane_s32(vget_low_s32(a[1]), vget_low_s32(cospis), 1); - c[7] = vmull_lane_s32(vget_high_s32(a[1]), vget_low_s32(cospis), 1); - c[8] = vmull_lane_s32(vget_low_s32(a[3]), vget_low_s32(cospis), 1); - c[9] = vmull_lane_s32(vget_high_s32(a[3]), vget_low_s32(cospis), 1); - c[10] = vmull_lane_s32(vget_low_s32(a[3]), vget_high_s32(cospis), 1); - c[11] = vmull_lane_s32(vget_high_s32(a[3]), vget_high_s32(cospis), 1); - c[4] = vsubq_s64(c[4], c[8]); - c[5] = vsubq_s64(c[5], c[9]); - c[6] = vaddq_s64(c[6], c[10]); - c[7] = vaddq_s64(c[7], c[11]); - b0 = vcombine_s32(vrshrn_n_s64(c[0], DCT_CONST_BITS), - vrshrn_n_s64(c[1], DCT_CONST_BITS)); - b1 = vcombine_s32(vrshrn_n_s64(c[2], DCT_CONST_BITS), - vrshrn_n_s64(c[3], DCT_CONST_BITS)); - b2 = vcombine_s32(vrshrn_n_s64(c[4], DCT_CONST_BITS), - vrshrn_n_s64(c[5], DCT_CONST_BITS)); - b3 = vcombine_s32(vrshrn_n_s64(c[6], DCT_CONST_BITS), - vrshrn_n_s64(c[7], DCT_CONST_BITS)); - a[0] = vaddq_s32(b0, b3); - a[1] = vaddq_s32(b1, b2); - a[2] = vsubq_s32(b1, b2); - a[3] = vsubq_s32(b0, b3); -} - -static INLINE void highbd_add8x8(int16x8_t *const a, uint16_t *dest, - const int stride, const int bd) { - const int16x8_t max = vdupq_n_s16((1 << bd) - 1); - const uint16_t *dst = dest; - uint16x8_t d0, d1, d2, d3, d4, d5, d6, d7; - uint16x8_t d0_u16, d1_u16, d2_u16, d3_u16, d4_u16, d5_u16, d6_u16, d7_u16; - int16x8_t d0_s16, d1_s16, d2_s16, d3_s16, d4_s16, d5_s16, d6_s16, d7_s16; - - d0 = vld1q_u16(dst); - dst += stride; - d1 = vld1q_u16(dst); - dst += stride; - d2 = vld1q_u16(dst); - dst += stride; - d3 = vld1q_u16(dst); - dst += stride; - d4 = vld1q_u16(dst); - dst += stride; - d5 = vld1q_u16(dst); - dst += stride; - d6 = vld1q_u16(dst); - dst += stride; - d7 = vld1q_u16(dst); - - d0_s16 = vqaddq_s16(a[0], vreinterpretq_s16_u16(d0)); - d1_s16 = vqaddq_s16(a[1], vreinterpretq_s16_u16(d1)); - d2_s16 = vqaddq_s16(a[2], vreinterpretq_s16_u16(d2)); - d3_s16 = vqaddq_s16(a[3], vreinterpretq_s16_u16(d3)); - d4_s16 = vqaddq_s16(a[4], vreinterpretq_s16_u16(d4)); - d5_s16 = vqaddq_s16(a[5], vreinterpretq_s16_u16(d5)); - d6_s16 = vqaddq_s16(a[6], vreinterpretq_s16_u16(d6)); - d7_s16 = vqaddq_s16(a[7], vreinterpretq_s16_u16(d7)); - - d0_s16 = vminq_s16(d0_s16, max); - d1_s16 = vminq_s16(d1_s16, max); - d2_s16 = vminq_s16(d2_s16, max); - d3_s16 = vminq_s16(d3_s16, max); - d4_s16 = vminq_s16(d4_s16, max); - d5_s16 = vminq_s16(d5_s16, max); - d6_s16 = vminq_s16(d6_s16, max); - d7_s16 = vminq_s16(d7_s16, max); - d0_u16 = vqshluq_n_s16(d0_s16, 0); - d1_u16 = vqshluq_n_s16(d1_s16, 0); - d2_u16 = vqshluq_n_s16(d2_s16, 0); - d3_u16 = vqshluq_n_s16(d3_s16, 0); - d4_u16 = vqshluq_n_s16(d4_s16, 0); - d5_u16 = vqshluq_n_s16(d5_s16, 0); - d6_u16 = vqshluq_n_s16(d6_s16, 0); - d7_u16 = vqshluq_n_s16(d7_s16, 0); - - vst1q_u16(dest, d0_u16); - dest += stride; - vst1q_u16(dest, d1_u16); - dest += stride; - vst1q_u16(dest, d2_u16); - dest += stride; - vst1q_u16(dest, d3_u16); - dest += stride; - vst1q_u16(dest, d4_u16); - dest += stride; - vst1q_u16(dest, d5_u16); - dest += stride; - vst1q_u16(dest, d6_u16); - dest += stride; - vst1q_u16(dest, d7_u16); -} - -static INLINE void idct8x8_64_half1d_bd10( - const int32x4_t cospis0, const int32x4_t cospis1, int32x4_t *const io0, - int32x4_t *const io1, int32x4_t *const io2, int32x4_t *const io3, - int32x4_t *const io4, int32x4_t *const io5, int32x4_t *const io6, - int32x4_t *const io7) { - int32x4_t step1[8], step2[8]; - - transpose_s32_8x4(io0, io1, io2, io3, io4, io5, io6, io7); - - // stage 1 - step1[4] = vmulq_lane_s32(*io1, vget_high_s32(cospis1), 1); - step1[5] = vmulq_lane_s32(*io3, vget_high_s32(cospis1), 0); - step1[6] = vmulq_lane_s32(*io3, vget_low_s32(cospis1), 1); - step1[7] = vmulq_lane_s32(*io1, vget_low_s32(cospis1), 0); - - step1[4] = vmlsq_lane_s32(step1[4], *io7, vget_low_s32(cospis1), 0); - step1[5] = vmlaq_lane_s32(step1[5], *io5, vget_low_s32(cospis1), 1); - step1[6] = vmlsq_lane_s32(step1[6], *io5, vget_high_s32(cospis1), 0); - step1[7] = vmlaq_lane_s32(step1[7], *io7, vget_high_s32(cospis1), 1); - - step1[4] = vrshrq_n_s32(step1[4], DCT_CONST_BITS); - step1[5] = vrshrq_n_s32(step1[5], DCT_CONST_BITS); - step1[6] = vrshrq_n_s32(step1[6], DCT_CONST_BITS); - step1[7] = vrshrq_n_s32(step1[7], DCT_CONST_BITS); - - // stage 2 - step2[1] = vmulq_lane_s32(*io0, vget_high_s32(cospis0), 0); - step2[2] = vmulq_lane_s32(*io2, vget_high_s32(cospis0), 1); - step2[3] = vmulq_lane_s32(*io2, vget_low_s32(cospis0), 1); - - step2[0] = vmlaq_lane_s32(step2[1], *io4, vget_high_s32(cospis0), 0); - step2[1] = vmlsq_lane_s32(step2[1], *io4, vget_high_s32(cospis0), 0); - step2[2] = vmlsq_lane_s32(step2[2], *io6, vget_low_s32(cospis0), 1); - step2[3] = vmlaq_lane_s32(step2[3], *io6, vget_high_s32(cospis0), 1); - - step2[0] = vrshrq_n_s32(step2[0], DCT_CONST_BITS); - step2[1] = vrshrq_n_s32(step2[1], DCT_CONST_BITS); - step2[2] = vrshrq_n_s32(step2[2], DCT_CONST_BITS); - step2[3] = vrshrq_n_s32(step2[3], DCT_CONST_BITS); - - step2[4] = vaddq_s32(step1[4], step1[5]); - step2[5] = vsubq_s32(step1[4], step1[5]); - step2[6] = vsubq_s32(step1[7], step1[6]); - step2[7] = vaddq_s32(step1[7], step1[6]); - - // stage 3 - step1[0] = vaddq_s32(step2[0], step2[3]); - step1[1] = vaddq_s32(step2[1], step2[2]); - step1[2] = vsubq_s32(step2[1], step2[2]); - step1[3] = vsubq_s32(step2[0], step2[3]); - - step1[6] = vmulq_lane_s32(step2[6], vget_high_s32(cospis0), 0); - step1[5] = vmlsq_lane_s32(step1[6], step2[5], vget_high_s32(cospis0), 0); - step1[6] = vmlaq_lane_s32(step1[6], step2[5], vget_high_s32(cospis0), 0); - step1[5] = vrshrq_n_s32(step1[5], DCT_CONST_BITS); - step1[6] = vrshrq_n_s32(step1[6], DCT_CONST_BITS); - - // stage 4 - *io0 = vaddq_s32(step1[0], step2[7]); - *io1 = vaddq_s32(step1[1], step1[6]); - *io2 = vaddq_s32(step1[2], step1[5]); - *io3 = vaddq_s32(step1[3], step2[4]); - *io4 = vsubq_s32(step1[3], step2[4]); - *io5 = vsubq_s32(step1[2], step1[5]); - *io6 = vsubq_s32(step1[1], step1[6]); - *io7 = vsubq_s32(step1[0], step2[7]); -} - -static INLINE void idct8x8_64_half1d_bd12( - const int32x4_t cospis0, const int32x4_t cospis1, int32x4_t *const io0, - int32x4_t *const io1, int32x4_t *const io2, int32x4_t *const io3, - int32x4_t *const io4, int32x4_t *const io5, int32x4_t *const io6, - int32x4_t *const io7) { - int32x2_t input1l, input1h, input3l, input3h, input5l, input5h, input7l, - input7h; - int32x2_t step1l[4], step1h[4]; - int32x4_t step1[8], step2[8]; - int64x2_t t64[8]; - int32x2_t t32[8]; - - transpose_s32_8x4(io0, io1, io2, io3, io4, io5, io6, io7); - - // stage 1 - input1l = vget_low_s32(*io1); - input1h = vget_high_s32(*io1); - input3l = vget_low_s32(*io3); - input3h = vget_high_s32(*io3); - input5l = vget_low_s32(*io5); - input5h = vget_high_s32(*io5); - input7l = vget_low_s32(*io7); - input7h = vget_high_s32(*io7); - step1l[0] = vget_low_s32(*io0); - step1h[0] = vget_high_s32(*io0); - step1l[1] = vget_low_s32(*io2); - step1h[1] = vget_high_s32(*io2); - step1l[2] = vget_low_s32(*io4); - step1h[2] = vget_high_s32(*io4); - step1l[3] = vget_low_s32(*io6); - step1h[3] = vget_high_s32(*io6); - - t64[0] = vmull_lane_s32(input1l, vget_high_s32(cospis1), 1); - t64[1] = vmull_lane_s32(input1h, vget_high_s32(cospis1), 1); - t64[2] = vmull_lane_s32(input3l, vget_high_s32(cospis1), 0); - t64[3] = vmull_lane_s32(input3h, vget_high_s32(cospis1), 0); - t64[4] = vmull_lane_s32(input3l, vget_low_s32(cospis1), 1); - t64[5] = vmull_lane_s32(input3h, vget_low_s32(cospis1), 1); - t64[6] = vmull_lane_s32(input1l, vget_low_s32(cospis1), 0); - t64[7] = vmull_lane_s32(input1h, vget_low_s32(cospis1), 0); - t64[0] = vmlsl_lane_s32(t64[0], input7l, vget_low_s32(cospis1), 0); - t64[1] = vmlsl_lane_s32(t64[1], input7h, vget_low_s32(cospis1), 0); - t64[2] = vmlal_lane_s32(t64[2], input5l, vget_low_s32(cospis1), 1); - t64[3] = vmlal_lane_s32(t64[3], input5h, vget_low_s32(cospis1), 1); - t64[4] = vmlsl_lane_s32(t64[4], input5l, vget_high_s32(cospis1), 0); - t64[5] = vmlsl_lane_s32(t64[5], input5h, vget_high_s32(cospis1), 0); - t64[6] = vmlal_lane_s32(t64[6], input7l, vget_high_s32(cospis1), 1); - t64[7] = vmlal_lane_s32(t64[7], input7h, vget_high_s32(cospis1), 1); - t32[0] = vrshrn_n_s64(t64[0], DCT_CONST_BITS); - t32[1] = vrshrn_n_s64(t64[1], DCT_CONST_BITS); - t32[2] = vrshrn_n_s64(t64[2], DCT_CONST_BITS); - t32[3] = vrshrn_n_s64(t64[3], DCT_CONST_BITS); - t32[4] = vrshrn_n_s64(t64[4], DCT_CONST_BITS); - t32[5] = vrshrn_n_s64(t64[5], DCT_CONST_BITS); - t32[6] = vrshrn_n_s64(t64[6], DCT_CONST_BITS); - t32[7] = vrshrn_n_s64(t64[7], DCT_CONST_BITS); - step1[4] = vcombine_s32(t32[0], t32[1]); - step1[5] = vcombine_s32(t32[2], t32[3]); - step1[6] = vcombine_s32(t32[4], t32[5]); - step1[7] = vcombine_s32(t32[6], t32[7]); - - // stage 2 - t64[2] = vmull_lane_s32(step1l[0], vget_high_s32(cospis0), 0); - t64[3] = vmull_lane_s32(step1h[0], vget_high_s32(cospis0), 0); - t64[4] = vmull_lane_s32(step1l[1], vget_high_s32(cospis0), 1); - t64[5] = vmull_lane_s32(step1h[1], vget_high_s32(cospis0), 1); - t64[6] = vmull_lane_s32(step1l[1], vget_low_s32(cospis0), 1); - t64[7] = vmull_lane_s32(step1h[1], vget_low_s32(cospis0), 1); - t64[0] = vmlal_lane_s32(t64[2], step1l[2], vget_high_s32(cospis0), 0); - t64[1] = vmlal_lane_s32(t64[3], step1h[2], vget_high_s32(cospis0), 0); - t64[2] = vmlsl_lane_s32(t64[2], step1l[2], vget_high_s32(cospis0), 0); - t64[3] = vmlsl_lane_s32(t64[3], step1h[2], vget_high_s32(cospis0), 0); - t64[4] = vmlsl_lane_s32(t64[4], step1l[3], vget_low_s32(cospis0), 1); - t64[5] = vmlsl_lane_s32(t64[5], step1h[3], vget_low_s32(cospis0), 1); - t64[6] = vmlal_lane_s32(t64[6], step1l[3], vget_high_s32(cospis0), 1); - t64[7] = vmlal_lane_s32(t64[7], step1h[3], vget_high_s32(cospis0), 1); - t32[0] = vrshrn_n_s64(t64[0], DCT_CONST_BITS); - t32[1] = vrshrn_n_s64(t64[1], DCT_CONST_BITS); - t32[2] = vrshrn_n_s64(t64[2], DCT_CONST_BITS); - t32[3] = vrshrn_n_s64(t64[3], DCT_CONST_BITS); - t32[4] = vrshrn_n_s64(t64[4], DCT_CONST_BITS); - t32[5] = vrshrn_n_s64(t64[5], DCT_CONST_BITS); - t32[6] = vrshrn_n_s64(t64[6], DCT_CONST_BITS); - t32[7] = vrshrn_n_s64(t64[7], DCT_CONST_BITS); - step2[0] = vcombine_s32(t32[0], t32[1]); - step2[1] = vcombine_s32(t32[2], t32[3]); - step2[2] = vcombine_s32(t32[4], t32[5]); - step2[3] = vcombine_s32(t32[6], t32[7]); - - step2[4] = vaddq_s32(step1[4], step1[5]); - step2[5] = vsubq_s32(step1[4], step1[5]); - step2[6] = vsubq_s32(step1[7], step1[6]); - step2[7] = vaddq_s32(step1[7], step1[6]); - - // stage 3 - step1[0] = vaddq_s32(step2[0], step2[3]); - step1[1] = vaddq_s32(step2[1], step2[2]); - step1[2] = vsubq_s32(step2[1], step2[2]); - step1[3] = vsubq_s32(step2[0], step2[3]); - - t64[2] = vmull_lane_s32(vget_low_s32(step2[6]), vget_high_s32(cospis0), 0); - t64[3] = vmull_lane_s32(vget_high_s32(step2[6]), vget_high_s32(cospis0), 0); - t64[0] = - vmlsl_lane_s32(t64[2], vget_low_s32(step2[5]), vget_high_s32(cospis0), 0); - t64[1] = vmlsl_lane_s32(t64[3], vget_high_s32(step2[5]), - vget_high_s32(cospis0), 0); - t64[2] = - vmlal_lane_s32(t64[2], vget_low_s32(step2[5]), vget_high_s32(cospis0), 0); - t64[3] = vmlal_lane_s32(t64[3], vget_high_s32(step2[5]), - vget_high_s32(cospis0), 0); - t32[0] = vrshrn_n_s64(t64[0], DCT_CONST_BITS); - t32[1] = vrshrn_n_s64(t64[1], DCT_CONST_BITS); - t32[2] = vrshrn_n_s64(t64[2], DCT_CONST_BITS); - t32[3] = vrshrn_n_s64(t64[3], DCT_CONST_BITS); - step1[5] = vcombine_s32(t32[0], t32[1]); - step1[6] = vcombine_s32(t32[2], t32[3]); - - // stage 4 - *io0 = vaddq_s32(step1[0], step2[7]); - *io1 = vaddq_s32(step1[1], step1[6]); - *io2 = vaddq_s32(step1[2], step1[5]); - *io3 = vaddq_s32(step1[3], step2[4]); - *io4 = vsubq_s32(step1[3], step2[4]); - *io5 = vsubq_s32(step1[2], step1[5]); - *io6 = vsubq_s32(step1[1], step1[6]); - *io7 = vsubq_s32(step1[0], step2[7]); -} - -static INLINE void highbd_idct16x16_store_pass1(const int32x4x2_t *const out, - int32_t *output) { - // Save the result into output - vst1q_s32(output + 0, out[0].val[0]); - vst1q_s32(output + 4, out[0].val[1]); - output += 16; - vst1q_s32(output + 0, out[1].val[0]); - vst1q_s32(output + 4, out[1].val[1]); - output += 16; - vst1q_s32(output + 0, out[2].val[0]); - vst1q_s32(output + 4, out[2].val[1]); - output += 16; - vst1q_s32(output + 0, out[3].val[0]); - vst1q_s32(output + 4, out[3].val[1]); - output += 16; - vst1q_s32(output + 0, out[4].val[0]); - vst1q_s32(output + 4, out[4].val[1]); - output += 16; - vst1q_s32(output + 0, out[5].val[0]); - vst1q_s32(output + 4, out[5].val[1]); - output += 16; - vst1q_s32(output + 0, out[6].val[0]); - vst1q_s32(output + 4, out[6].val[1]); - output += 16; - vst1q_s32(output + 0, out[7].val[0]); - vst1q_s32(output + 4, out[7].val[1]); - output += 16; - vst1q_s32(output + 0, out[8].val[0]); - vst1q_s32(output + 4, out[8].val[1]); - output += 16; - vst1q_s32(output + 0, out[9].val[0]); - vst1q_s32(output + 4, out[9].val[1]); - output += 16; - vst1q_s32(output + 0, out[10].val[0]); - vst1q_s32(output + 4, out[10].val[1]); - output += 16; - vst1q_s32(output + 0, out[11].val[0]); - vst1q_s32(output + 4, out[11].val[1]); - output += 16; - vst1q_s32(output + 0, out[12].val[0]); - vst1q_s32(output + 4, out[12].val[1]); - output += 16; - vst1q_s32(output + 0, out[13].val[0]); - vst1q_s32(output + 4, out[13].val[1]); - output += 16; - vst1q_s32(output + 0, out[14].val[0]); - vst1q_s32(output + 4, out[14].val[1]); - output += 16; - vst1q_s32(output + 0, out[15].val[0]); - vst1q_s32(output + 4, out[15].val[1]); -} - -static INLINE void highbd_idct16x16_add_store(const int32x4x2_t *const out, - uint16_t *dest, const int stride, - const int bd) { - // Add the result to dest - const int16x8_t max = vdupq_n_s16((1 << bd) - 1); - int16x8_t o[16]; - o[0] = vcombine_s16(vrshrn_n_s32(out[0].val[0], 6), - vrshrn_n_s32(out[0].val[1], 6)); - o[1] = vcombine_s16(vrshrn_n_s32(out[1].val[0], 6), - vrshrn_n_s32(out[1].val[1], 6)); - o[2] = vcombine_s16(vrshrn_n_s32(out[2].val[0], 6), - vrshrn_n_s32(out[2].val[1], 6)); - o[3] = vcombine_s16(vrshrn_n_s32(out[3].val[0], 6), - vrshrn_n_s32(out[3].val[1], 6)); - o[4] = vcombine_s16(vrshrn_n_s32(out[4].val[0], 6), - vrshrn_n_s32(out[4].val[1], 6)); - o[5] = vcombine_s16(vrshrn_n_s32(out[5].val[0], 6), - vrshrn_n_s32(out[5].val[1], 6)); - o[6] = vcombine_s16(vrshrn_n_s32(out[6].val[0], 6), - vrshrn_n_s32(out[6].val[1], 6)); - o[7] = vcombine_s16(vrshrn_n_s32(out[7].val[0], 6), - vrshrn_n_s32(out[7].val[1], 6)); - o[8] = vcombine_s16(vrshrn_n_s32(out[8].val[0], 6), - vrshrn_n_s32(out[8].val[1], 6)); - o[9] = vcombine_s16(vrshrn_n_s32(out[9].val[0], 6), - vrshrn_n_s32(out[9].val[1], 6)); - o[10] = vcombine_s16(vrshrn_n_s32(out[10].val[0], 6), - vrshrn_n_s32(out[10].val[1], 6)); - o[11] = vcombine_s16(vrshrn_n_s32(out[11].val[0], 6), - vrshrn_n_s32(out[11].val[1], 6)); - o[12] = vcombine_s16(vrshrn_n_s32(out[12].val[0], 6), - vrshrn_n_s32(out[12].val[1], 6)); - o[13] = vcombine_s16(vrshrn_n_s32(out[13].val[0], 6), - vrshrn_n_s32(out[13].val[1], 6)); - o[14] = vcombine_s16(vrshrn_n_s32(out[14].val[0], 6), - vrshrn_n_s32(out[14].val[1], 6)); - o[15] = vcombine_s16(vrshrn_n_s32(out[15].val[0], 6), - vrshrn_n_s32(out[15].val[1], 6)); - highbd_idct16x16_add8x1(o[0], max, &dest, stride); - highbd_idct16x16_add8x1(o[1], max, &dest, stride); - highbd_idct16x16_add8x1(o[2], max, &dest, stride); - highbd_idct16x16_add8x1(o[3], max, &dest, stride); - highbd_idct16x16_add8x1(o[4], max, &dest, stride); - highbd_idct16x16_add8x1(o[5], max, &dest, stride); - highbd_idct16x16_add8x1(o[6], max, &dest, stride); - highbd_idct16x16_add8x1(o[7], max, &dest, stride); - highbd_idct16x16_add8x1(o[8], max, &dest, stride); - highbd_idct16x16_add8x1(o[9], max, &dest, stride); - highbd_idct16x16_add8x1(o[10], max, &dest, stride); - highbd_idct16x16_add8x1(o[11], max, &dest, stride); - highbd_idct16x16_add8x1(o[12], max, &dest, stride); - highbd_idct16x16_add8x1(o[13], max, &dest, stride); - highbd_idct16x16_add8x1(o[14], max, &dest, stride); - highbd_idct16x16_add8x1(o[15], max, &dest, stride); -} - -void vpx_highbd_idct16x16_256_add_half1d(const int32_t *input, int32_t *output, - uint16_t *dest, const int stride, - const int bd); - -#endif // VPX_VPX_DSP_ARM_HIGHBD_IDCT_NEON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_intrapred_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_intrapred_neon.c deleted file mode 100644 index 235cb5b9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_intrapred_neon.c +++ /dev/null @@ -1,2514 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "sum_neon.h" -#include "vpx/vpx_integer.h" - -//------------------------------------------------------------------------------ -// DC 4x4 - -static INLINE uint16_t dc_sum_4(const uint16_t *ref) { - const uint16x4_t ref_u16 = vld1_u16(ref); - return horizontal_add_uint16x4(ref_u16); -} - -static INLINE void dc_store_4x4(uint16_t *dst, ptrdiff_t stride, - const uint16x4_t dc) { - int i; - for (i = 0; i < 4; ++i, dst += stride) { - vst1_u16(dst, dc); - } -} - -void vpx_highbd_dc_predictor_4x4_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x4_t a = vld1_u16(above); - const uint16x4_t l = vld1_u16(left); - const uint16_t sum = horizontal_add_uint16x4(vadd_u16(a, l)); - const uint16x4_t dc = vrshr_n_u16(vdup_n_u16(sum), 3); - (void)bd; - dc_store_4x4(dst, stride, dc); -} - -void vpx_highbd_dc_left_predictor_4x4_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16_t sum = dc_sum_4(left); - const uint16x4_t dc = vrshr_n_u16(vdup_n_u16(sum), 2); - (void)above; - (void)bd; - dc_store_4x4(dst, stride, dc); -} - -void vpx_highbd_dc_top_predictor_4x4_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16_t sum = dc_sum_4(above); - const uint16x4_t dc = vrshr_n_u16(vdup_n_u16(sum), 2); - (void)left; - (void)bd; - dc_store_4x4(dst, stride, dc); -} - -void vpx_highbd_dc_128_predictor_4x4_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x4_t dc = vdup_n_u16(1 << (bd - 1)); - (void)above; - (void)left; - dc_store_4x4(dst, stride, dc); -} - -//------------------------------------------------------------------------------ -// DC 8x8 - -static INLINE uint16_t dc_sum_8(const uint16_t *ref) { - const uint16x8_t ref_u16 = vld1q_u16(ref); - return horizontal_add_uint16x8(ref_u16); -} - -static INLINE void dc_store_8x8(uint16_t *dst, ptrdiff_t stride, - const uint16x8_t dc) { - int i; - for (i = 0; i < 8; ++i, dst += stride) { - vst1q_u16(dst, dc); - } -} - -void vpx_highbd_dc_predictor_8x8_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x8_t above_u16 = vld1q_u16(above); - const uint16x8_t left_u16 = vld1q_u16(left); - const uint16x8_t p0 = vaddq_u16(above_u16, left_u16); - const uint16_t sum = horizontal_add_uint16x8(p0); - const uint16x8_t dc = vrshrq_n_u16(vdupq_n_u16(sum), 4); - (void)bd; - dc_store_8x8(dst, stride, dc); -} - -void vpx_highbd_dc_left_predictor_8x8_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16_t sum = dc_sum_8(left); - const uint16x8_t dc = vrshrq_n_u16(vdupq_n_u16(sum), 3); - (void)above; - (void)bd; - dc_store_8x8(dst, stride, dc); -} - -void vpx_highbd_dc_top_predictor_8x8_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16_t sum = dc_sum_8(above); - const uint16x8_t dc = vrshrq_n_u16(vdupq_n_u16(sum), 3); - (void)left; - (void)bd; - dc_store_8x8(dst, stride, dc); -} - -void vpx_highbd_dc_128_predictor_8x8_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x8_t dc = vdupq_n_u16(1 << (bd - 1)); - (void)above; - (void)left; - dc_store_8x8(dst, stride, dc); -} - -//------------------------------------------------------------------------------ -// DC 16x16 - -static INLINE uint16_t dc_sum_16(const uint16_t *ref) { - const uint16x8_t ref_u16_0 = vld1q_u16(ref + 0); - const uint16x8_t ref_u16_1 = vld1q_u16(ref + 8); - const uint16x8_t p0 = vaddq_u16(ref_u16_0, ref_u16_1); - return horizontal_add_uint16x8(p0); -} - -static INLINE void dc_store_16x16(uint16_t *dst, ptrdiff_t stride, - const uint16x8_t dc) { - int i; - for (i = 0; i < 16; ++i, dst += stride) { - vst1q_u16(dst + 0, dc); - vst1q_u16(dst + 8, dc); - } -} - -void vpx_highbd_dc_predictor_16x16_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x8_t a0 = vld1q_u16(above + 0); - const uint16x8_t a1 = vld1q_u16(above + 8); - const uint16x8_t l0 = vld1q_u16(left + 0); - const uint16x8_t l1 = vld1q_u16(left + 8); - const uint16x8_t pa = vaddq_u16(a0, a1); - const uint16x8_t pl = vaddq_u16(l0, l1); - const uint16x8_t pal0 = vaddq_u16(pa, pl); - const uint32_t sum = horizontal_add_uint16x8(pal0); - const uint16x8_t dc = vdupq_lane_u16(vrshrn_n_u32(vdupq_n_u32(sum), 5), 0); - (void)bd; - dc_store_16x16(dst, stride, dc); -} - -void vpx_highbd_dc_left_predictor_16x16_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16_t sum = dc_sum_16(left); - const uint16x8_t dc = vrshrq_n_u16(vdupq_n_u16(sum), 4); - (void)above; - (void)bd; - dc_store_16x16(dst, stride, dc); -} - -void vpx_highbd_dc_top_predictor_16x16_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16_t sum = dc_sum_16(above); - const uint16x8_t dc = vrshrq_n_u16(vdupq_n_u16(sum), 4); - (void)left; - (void)bd; - dc_store_16x16(dst, stride, dc); -} - -void vpx_highbd_dc_128_predictor_16x16_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x8_t dc = vdupq_n_u16(1 << (bd - 1)); - (void)above; - (void)left; - dc_store_16x16(dst, stride, dc); -} - -//------------------------------------------------------------------------------ -// DC 32x32 - -static INLINE uint32_t dc_sum_32(const uint16_t *ref) { - const uint16x8_t r0 = vld1q_u16(ref + 0); - const uint16x8_t r1 = vld1q_u16(ref + 8); - const uint16x8_t r2 = vld1q_u16(ref + 16); - const uint16x8_t r3 = vld1q_u16(ref + 24); - const uint16x8_t p0 = vaddq_u16(r0, r1); - const uint16x8_t p1 = vaddq_u16(r2, r3); - const uint16x8_t p2 = vaddq_u16(p0, p1); - return horizontal_add_uint16x8(p2); -} - -static INLINE void dc_store_32x32(uint16_t *dst, ptrdiff_t stride, - const uint16x8_t dc) { - int i; - for (i = 0; i < 32; ++i) { - vst1q_u16(dst + 0, dc); - vst1q_u16(dst + 8, dc); - vst1q_u16(dst + 16, dc); - vst1q_u16(dst + 24, dc); - dst += stride; - } -} - -void vpx_highbd_dc_predictor_32x32_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x8_t a0 = vld1q_u16(above + 0); - const uint16x8_t a1 = vld1q_u16(above + 8); - const uint16x8_t a2 = vld1q_u16(above + 16); - const uint16x8_t a3 = vld1q_u16(above + 24); - const uint16x8_t l0 = vld1q_u16(left + 0); - const uint16x8_t l1 = vld1q_u16(left + 8); - const uint16x8_t l2 = vld1q_u16(left + 16); - const uint16x8_t l3 = vld1q_u16(left + 24); - const uint16x8_t pa0 = vaddq_u16(a0, a1); - const uint16x8_t pa1 = vaddq_u16(a2, a3); - const uint16x8_t pl0 = vaddq_u16(l0, l1); - const uint16x8_t pl1 = vaddq_u16(l2, l3); - const uint16x8_t pa = vaddq_u16(pa0, pa1); - const uint16x8_t pl = vaddq_u16(pl0, pl1); - const uint16x8_t pal0 = vaddq_u16(pa, pl); - const uint32_t sum = horizontal_add_uint16x8(pal0); - const uint16x8_t dc = vdupq_lane_u16(vrshrn_n_u32(vdupq_n_u32(sum), 6), 0); - (void)bd; - dc_store_32x32(dst, stride, dc); -} - -void vpx_highbd_dc_left_predictor_32x32_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint32_t sum = dc_sum_32(left); - const uint16x8_t dc = vdupq_lane_u16(vrshrn_n_u32(vdupq_n_u32(sum), 5), 0); - (void)above; - (void)bd; - dc_store_32x32(dst, stride, dc); -} - -void vpx_highbd_dc_top_predictor_32x32_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint32_t sum = dc_sum_32(above); - const uint16x8_t dc = vdupq_lane_u16(vrshrn_n_u32(vdupq_n_u32(sum), 5), 0); - (void)left; - (void)bd; - dc_store_32x32(dst, stride, dc); -} - -void vpx_highbd_dc_128_predictor_32x32_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x8_t dc = vdupq_n_u16(1 << (bd - 1)); - (void)above; - (void)left; - dc_store_32x32(dst, stride, dc); -} - -// ----------------------------------------------------------------------------- - -void vpx_highbd_d45_predictor_4x4_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - uint16x8_t a0, a1, a2, d0; - uint16_t a7; - (void)left; - (void)bd; - - a0 = vld1q_u16(above); - a7 = above[7]; - - // [ above[1], ..., above[6], x, x ] - a1 = vextq_u16(a0, a0, 1); - // [ above[2], ..., above[7], x, x ] - a2 = vextq_u16(a0, a0, 2); - - // d0[0] = AVG3(above[0], above[1], above[2]); - // ... - // d0[5] = AVG3(above[5], above[6], above[7]); - // d0[6] = x (don't care) - // d0[7] = x (don't care) - d0 = vrhaddq_u16(vhaddq_u16(a0, a2), a1); - - // We want: - // stride=0 [ d0[0], d0[1], d0[2], d0[3] ] - // stride=1 [ d0[1], d0[2], d0[3], d0[4] ] - // stride=2 [ d0[2], d0[3], d0[4], d0[5] ] - // stride=2 [ d0[3], d0[4], d0[5], above[7] ] - vst1_u16(dst + 0 * stride, vget_low_u16(d0)); - vst1_u16(dst + 1 * stride, vget_low_u16(vextq_u16(d0, d0, 1))); - vst1_u16(dst + 2 * stride, vget_low_u16(vextq_u16(d0, d0, 2))); - vst1_u16(dst + 3 * stride, vget_low_u16(vextq_u16(d0, d0, 3))); - - // We stored d0[6] above, so fixup into above[7]. - dst[3 * stride + 3] = a7; -} - -void vpx_highbd_d45_predictor_8x8_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - uint16x8_t ax0, a0, a1, a7, d0; - (void)left; - (void)bd; - - a0 = vld1q_u16(above + 0); - a1 = vld1q_u16(above + 1); - a7 = vld1q_dup_u16(above + 7); - - // We want to calculate the AVG3 result in lanes 1-7 inclusive so we can - // shift in above[7] later, so shift a0 across by one to get the right - // inputs: - // [ x, above[0], ... , above[6] ] - ax0 = vextq_u16(a0, a0, 7); - - // d0[0] = x (don't care) - // d0[1] = AVG3(above[0], above[1], above[2]); - // ... - // d0[7] = AVG3(above[6], above[7], above[8]); - d0 = vrhaddq_u16(vhaddq_u16(ax0, a1), a0); - - // Undo the earlier ext, incrementally shift in duplicates of above[7]. - vst1q_u16(dst + 0 * stride, vextq_u16(d0, a7, 1)); - vst1q_u16(dst + 1 * stride, vextq_u16(d0, a7, 2)); - vst1q_u16(dst + 2 * stride, vextq_u16(d0, a7, 3)); - vst1q_u16(dst + 3 * stride, vextq_u16(d0, a7, 4)); - vst1q_u16(dst + 4 * stride, vextq_u16(d0, a7, 5)); - vst1q_u16(dst + 5 * stride, vextq_u16(d0, a7, 6)); - vst1q_u16(dst + 6 * stride, vextq_u16(d0, a7, 7)); - vst1q_u16(dst + 7 * stride, a7); -} - -void vpx_highbd_d45_predictor_16x16_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - uint16x8_t ax0, a0, a1, a7, a8, a9, a15, d0[2]; - (void)left; - (void)bd; - - a0 = vld1q_u16(above + 0); - a1 = vld1q_u16(above + 1); - a7 = vld1q_u16(above + 7); - a8 = vld1q_u16(above + 8); - a9 = vld1q_u16(above + 9); - a15 = vld1q_dup_u16(above + 15); - - // [ x, above[0], ... , above[6] ] - ax0 = vextq_u16(a0, a0, 7); - - // We have one unused lane here to leave room to shift in above[15] in the - // last lane: - // d0[0][1] = x (don't care) - // d0[0][1] = AVG3(above[0], above[1], above[2]); - // ... - // d0[0][7] = AVG3(above[6], above[7], above[8]); - // d0[1][0] = AVG3(above[7], above[8], above[9]); - // ... - // d0[1][7] = AVG3(above[14], above[15], above[16]); - d0[0] = vrhaddq_u16(vhaddq_u16(ax0, a1), a0); - d0[1] = vrhaddq_u16(vhaddq_u16(a7, a9), a8); - - // Incrementally shift in duplicates of above[15]. - vst1q_u16(dst + 0 * stride + 0, vextq_u16(d0[0], d0[1], 1)); - vst1q_u16(dst + 0 * stride + 8, vextq_u16(d0[1], a15, 1)); - vst1q_u16(dst + 1 * stride + 0, vextq_u16(d0[0], d0[1], 2)); - vst1q_u16(dst + 1 * stride + 8, vextq_u16(d0[1], a15, 2)); - vst1q_u16(dst + 2 * stride + 0, vextq_u16(d0[0], d0[1], 3)); - vst1q_u16(dst + 2 * stride + 8, vextq_u16(d0[1], a15, 3)); - vst1q_u16(dst + 3 * stride + 0, vextq_u16(d0[0], d0[1], 4)); - vst1q_u16(dst + 3 * stride + 8, vextq_u16(d0[1], a15, 4)); - vst1q_u16(dst + 4 * stride + 0, vextq_u16(d0[0], d0[1], 5)); - vst1q_u16(dst + 4 * stride + 8, vextq_u16(d0[1], a15, 5)); - vst1q_u16(dst + 5 * stride + 0, vextq_u16(d0[0], d0[1], 6)); - vst1q_u16(dst + 5 * stride + 8, vextq_u16(d0[1], a15, 6)); - vst1q_u16(dst + 6 * stride + 0, vextq_u16(d0[0], d0[1], 7)); - vst1q_u16(dst + 6 * stride + 8, vextq_u16(d0[1], a15, 7)); - vst1q_u16(dst + 7 * stride + 0, d0[1]); - vst1q_u16(dst + 7 * stride + 8, a15); - - vst1q_u16(dst + 8 * stride + 0, vextq_u16(d0[1], a15, 1)); - vst1q_u16(dst + 8 * stride + 8, a15); - vst1q_u16(dst + 9 * stride + 0, vextq_u16(d0[1], a15, 2)); - vst1q_u16(dst + 9 * stride + 8, a15); - vst1q_u16(dst + 10 * stride + 0, vextq_u16(d0[1], a15, 3)); - vst1q_u16(dst + 10 * stride + 8, a15); - vst1q_u16(dst + 11 * stride + 0, vextq_u16(d0[1], a15, 4)); - vst1q_u16(dst + 11 * stride + 8, a15); - vst1q_u16(dst + 12 * stride + 0, vextq_u16(d0[1], a15, 5)); - vst1q_u16(dst + 12 * stride + 8, a15); - vst1q_u16(dst + 13 * stride + 0, vextq_u16(d0[1], a15, 6)); - vst1q_u16(dst + 13 * stride + 8, a15); - vst1q_u16(dst + 14 * stride + 0, vextq_u16(d0[1], a15, 7)); - vst1q_u16(dst + 14 * stride + 8, a15); - vst1q_u16(dst + 15 * stride + 0, a15); - vst1q_u16(dst + 15 * stride + 8, a15); -} - -void vpx_highbd_d45_predictor_32x32_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - uint16x8_t ax0, a0, a1, a7, a8, a9, a15, a16, a17, a23, a24, a25, a31, d0[4]; - int i; - (void)left; - (void)bd; - - a0 = vld1q_u16(above + 0); - a1 = vld1q_u16(above + 1); - a7 = vld1q_u16(above + 7); - a8 = vld1q_u16(above + 8); - a9 = vld1q_u16(above + 9); - a15 = vld1q_u16(above + 15); - a16 = vld1q_u16(above + 16); - a17 = vld1q_u16(above + 17); - a23 = vld1q_u16(above + 23); - a24 = vld1q_u16(above + 24); - a25 = vld1q_u16(above + 25); - a31 = vld1q_dup_u16(above + 31); - - // [ x, above[0], ... , above[6] ] - ax0 = vextq_u16(a0, a0, 7); - - d0[0] = vrhaddq_u16(vhaddq_u16(ax0, a1), a0); - d0[1] = vrhaddq_u16(vhaddq_u16(a7, a9), a8); - d0[2] = vrhaddq_u16(vhaddq_u16(a15, a17), a16); - d0[3] = vrhaddq_u16(vhaddq_u16(a23, a25), a24); - - for (i = 0; i < 32; ++i) { - d0[0] = vextq_u16(d0[0], d0[1], 1); - d0[1] = vextq_u16(d0[1], d0[2], 1); - d0[2] = vextq_u16(d0[2], d0[3], 1); - d0[3] = vextq_u16(d0[3], a31, 1); - vst1q_u16(dst + 0, d0[0]); - vst1q_u16(dst + 8, d0[1]); - vst1q_u16(dst + 16, d0[2]); - vst1q_u16(dst + 24, d0[3]); - dst += stride; - } -} - -// ----------------------------------------------------------------------------- - -void vpx_highbd_d63_predictor_4x4_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - uint16x4_t a0, a1, a2, a3, d0, d1, d2, d3; - (void)left; - (void)bd; - - a0 = vld1_u16(above + 0); - a1 = vld1_u16(above + 1); - a2 = vld1_u16(above + 2); - a3 = vld1_u16(above + 3); - - d0 = vrhadd_u16(a0, a1); - d1 = vrhadd_u16(vhadd_u16(a0, a2), a1); - d2 = vrhadd_u16(a1, a2); - d3 = vrhadd_u16(vhadd_u16(a1, a3), a2); - - // Note that here we are performing a full avg calculation for the final - // elements rather than storing a duplicate of above[3], which differs - // (correctly) from the general scheme employed by the bs={8,16,32} - // implementations in order to match the original C implementation. - vst1_u16(dst + 0 * stride, d0); - vst1_u16(dst + 1 * stride, d1); - vst1_u16(dst + 2 * stride, d2); - vst1_u16(dst + 3 * stride, d3); -} - -void vpx_highbd_d63_predictor_8x8_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - uint16x8_t a0, a1, a2, a7, d0, d1, d0_ext, d1_ext; - (void)left; - (void)bd; - - a0 = vld1q_u16(above + 0); - a1 = vld1q_u16(above + 1); - a2 = vld1q_u16(above + 2); - a7 = vld1q_dup_u16(above + 7); - - d0 = vrhaddq_u16(a0, a1); - d1 = vrhaddq_u16(vhaddq_u16(a0, a2), a1); - - // We want to store: - // stride=0 [ d0[0], d0[1], d0[2], d0[3], d0[4], d0[5], d0[6], d0[7] ] - // stride=1 [ d1[0], d1[1], d1[2], d1[3], d1[4], d1[5], d1[6], d1[7] ] - // stride=2 [ d0[1], d0[2], d0[3], d0[4], d0[5], d0[6], a[7], a[7] ] - // stride=3 [ d1[1], d1[2], d1[3], d1[4], d1[5], d1[6], a[7], a[7] ] - // stride=4 [ d0[2], d0[3], d0[4], d0[5], d0[6], a[7], a[7], a[7] ] - // stride=5 [ d1[2], d1[3], d1[4], d1[5], d1[6], a[7], a[7], a[7] ] - // stride=6 [ d0[3], d0[4], d0[5], d0[6], a[7], a[7], a[7], a[7] ] - // stride=7 [ d1[3], d1[4], d1[5], d1[6], a[7], a[7], a[7], a[7] ] - // Note in particular that d0[7] and d1[7] are only ever referenced in the - // stride=0 and stride=1 cases respectively, and in later strides are - // replaced by a copy of above[7]. These are equivalent if for i>7, - // above[i]==above[7], however that is not always the case. - - // Strip out d0[7] and d1[7] so that we can replace it with an additional - // copy of above[7], the first vector here doesn't matter so just reuse - // d0/d1. - d0_ext = vextq_u16(d0, d0, 7); - d1_ext = vextq_u16(d1, d1, 7); - - // Shuffle in duplicates of above[7] and store. - vst1q_u16(dst + 0 * stride, d0); - vst1q_u16(dst + 1 * stride, d1); - vst1q_u16(dst + 2 * stride, vextq_u16(d0_ext, a7, 2)); - vst1q_u16(dst + 3 * stride, vextq_u16(d1_ext, a7, 2)); - vst1q_u16(dst + 4 * stride, vextq_u16(d0_ext, a7, 3)); - vst1q_u16(dst + 5 * stride, vextq_u16(d1_ext, a7, 3)); - vst1q_u16(dst + 6 * stride, vextq_u16(d0_ext, a7, 4)); - vst1q_u16(dst + 7 * stride, vextq_u16(d1_ext, a7, 4)); -} - -void vpx_highbd_d63_predictor_16x16_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - // See vpx_highbd_d63_predictor_8x8_neon for details on the implementation. - uint16x8_t a0, a1, a2, a8, a9, a10, a15, d0[2], d1[2], d0_ext, d1_ext; - (void)left; - (void)bd; - - a0 = vld1q_u16(above + 0); - a1 = vld1q_u16(above + 1); - a2 = vld1q_u16(above + 2); - a8 = vld1q_u16(above + 8); - a9 = vld1q_u16(above + 9); - a10 = vld1q_u16(above + 10); - a15 = vld1q_dup_u16(above + 15); - - d0[0] = vrhaddq_u16(a0, a1); - d0[1] = vrhaddq_u16(a8, a9); - d1[0] = vrhaddq_u16(vhaddq_u16(a0, a2), a1); - d1[1] = vrhaddq_u16(vhaddq_u16(a8, a10), a9); - - // Strip out the final element of d0/d1 so that we can replace it with an - // additional copy of above[7], the first vector here doesn't matter so just - // reuse the same vector. - d0_ext = vextq_u16(d0[1], d0[1], 7); - d1_ext = vextq_u16(d1[1], d1[1], 7); - - // Shuffle in duplicates of above[7] and store. Note that cases involving - // {d0,d1}_ext require an extra shift to undo the shifting out of the final - // element from above. - vst1q_u16(dst + 0 * stride + 0, d0[0]); - vst1q_u16(dst + 0 * stride + 8, d0[1]); - vst1q_u16(dst + 1 * stride + 0, d1[0]); - vst1q_u16(dst + 1 * stride + 8, d1[1]); - vst1q_u16(dst + 2 * stride + 0, vextq_u16(d0[0], d0[1], 1)); - vst1q_u16(dst + 2 * stride + 8, vextq_u16(d0_ext, a15, 2)); - vst1q_u16(dst + 3 * stride + 0, vextq_u16(d1[0], d1[1], 1)); - vst1q_u16(dst + 3 * stride + 8, vextq_u16(d1_ext, a15, 2)); - vst1q_u16(dst + 4 * stride + 0, vextq_u16(d0[0], d0[1], 2)); - vst1q_u16(dst + 4 * stride + 8, vextq_u16(d0_ext, a15, 3)); - vst1q_u16(dst + 5 * stride + 0, vextq_u16(d1[0], d1[1], 2)); - vst1q_u16(dst + 5 * stride + 8, vextq_u16(d1_ext, a15, 3)); - vst1q_u16(dst + 6 * stride + 0, vextq_u16(d0[0], d0[1], 3)); - vst1q_u16(dst + 6 * stride + 8, vextq_u16(d0_ext, a15, 4)); - vst1q_u16(dst + 7 * stride + 0, vextq_u16(d1[0], d1[1], 3)); - vst1q_u16(dst + 7 * stride + 8, vextq_u16(d1_ext, a15, 4)); - vst1q_u16(dst + 8 * stride + 0, vextq_u16(d0[0], d0[1], 4)); - vst1q_u16(dst + 8 * stride + 8, vextq_u16(d0_ext, a15, 5)); - vst1q_u16(dst + 9 * stride + 0, vextq_u16(d1[0], d1[1], 4)); - vst1q_u16(dst + 9 * stride + 8, vextq_u16(d1_ext, a15, 5)); - vst1q_u16(dst + 10 * stride + 0, vextq_u16(d0[0], d0[1], 5)); - vst1q_u16(dst + 10 * stride + 8, vextq_u16(d0_ext, a15, 6)); - vst1q_u16(dst + 11 * stride + 0, vextq_u16(d1[0], d1[1], 5)); - vst1q_u16(dst + 11 * stride + 8, vextq_u16(d1_ext, a15, 6)); - vst1q_u16(dst + 12 * stride + 0, vextq_u16(d0[0], d0[1], 6)); - vst1q_u16(dst + 12 * stride + 8, vextq_u16(d0_ext, a15, 7)); - vst1q_u16(dst + 13 * stride + 0, vextq_u16(d1[0], d1[1], 6)); - vst1q_u16(dst + 13 * stride + 8, vextq_u16(d1_ext, a15, 7)); - vst1q_u16(dst + 14 * stride + 0, vextq_u16(d0[0], d0[1], 7)); - vst1q_u16(dst + 14 * stride + 8, a15); - vst1q_u16(dst + 15 * stride + 0, vextq_u16(d1[0], d1[1], 7)); - vst1q_u16(dst + 15 * stride + 8, a15); -} - -void vpx_highbd_d63_predictor_32x32_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - // See vpx_highbd_d63_predictor_8x8_neon for details on the implementation. - uint16x8_t a0, a1, a2, a8, a9, a10, a16, a17, a18, a24, a25, a26, a31, d0[4], - d1[4], d0_ext, d1_ext; - (void)left; - (void)bd; - - a0 = vld1q_u16(above + 0); - a1 = vld1q_u16(above + 1); - a2 = vld1q_u16(above + 2); - a8 = vld1q_u16(above + 8); - a9 = vld1q_u16(above + 9); - a10 = vld1q_u16(above + 10); - a16 = vld1q_u16(above + 16); - a17 = vld1q_u16(above + 17); - a18 = vld1q_u16(above + 18); - a24 = vld1q_u16(above + 24); - a25 = vld1q_u16(above + 25); - a26 = vld1q_u16(above + 26); - a31 = vld1q_dup_u16(above + 31); - - d0[0] = vrhaddq_u16(a0, a1); - d0[1] = vrhaddq_u16(a8, a9); - d0[2] = vrhaddq_u16(a16, a17); - d0[3] = vrhaddq_u16(a24, a25); - d1[0] = vrhaddq_u16(vhaddq_u16(a0, a2), a1); - d1[1] = vrhaddq_u16(vhaddq_u16(a8, a10), a9); - d1[2] = vrhaddq_u16(vhaddq_u16(a16, a18), a17); - d1[3] = vrhaddq_u16(vhaddq_u16(a24, a26), a25); - - // Strip out the final element of d0/d1 so that we can replace it with an - // additional copy of above[7], the first vector here doesn't matter so just - // reuse the same vector. - d0_ext = vextq_u16(d0[3], d0[3], 7); - d1_ext = vextq_u16(d1[3], d1[3], 7); - - // Shuffle in duplicates of above[7] and store. Note that cases involving - // {d0,d1}_ext require an extra shift to undo the shifting out of the final - // element from above. - - vst1q_u16(dst + 0 * stride + 0, d0[0]); - vst1q_u16(dst + 0 * stride + 8, d0[1]); - vst1q_u16(dst + 0 * stride + 16, d0[2]); - vst1q_u16(dst + 0 * stride + 24, d0[3]); - vst1q_u16(dst + 1 * stride + 0, d1[0]); - vst1q_u16(dst + 1 * stride + 8, d1[1]); - vst1q_u16(dst + 1 * stride + 16, d1[2]); - vst1q_u16(dst + 1 * stride + 24, d1[3]); - - vst1q_u16(dst + 2 * stride + 0, vextq_u16(d0[0], d0[1], 1)); - vst1q_u16(dst + 2 * stride + 8, vextq_u16(d0[1], d0[2], 1)); - vst1q_u16(dst + 2 * stride + 16, vextq_u16(d0[2], d0[3], 1)); - vst1q_u16(dst + 2 * stride + 24, vextq_u16(d0_ext, a31, 2)); - vst1q_u16(dst + 3 * stride + 0, vextq_u16(d1[0], d1[1], 1)); - vst1q_u16(dst + 3 * stride + 8, vextq_u16(d1[1], d1[2], 1)); - vst1q_u16(dst + 3 * stride + 16, vextq_u16(d1[2], d1[3], 1)); - vst1q_u16(dst + 3 * stride + 24, vextq_u16(d1_ext, a31, 2)); - - vst1q_u16(dst + 4 * stride + 0, vextq_u16(d0[0], d0[1], 2)); - vst1q_u16(dst + 4 * stride + 8, vextq_u16(d0[1], d0[2], 2)); - vst1q_u16(dst + 4 * stride + 16, vextq_u16(d0[2], d0[3], 2)); - vst1q_u16(dst + 4 * stride + 24, vextq_u16(d0_ext, a31, 3)); - vst1q_u16(dst + 5 * stride + 0, vextq_u16(d1[0], d1[1], 2)); - vst1q_u16(dst + 5 * stride + 8, vextq_u16(d1[1], d1[2], 2)); - vst1q_u16(dst + 5 * stride + 16, vextq_u16(d1[2], d1[3], 2)); - vst1q_u16(dst + 5 * stride + 24, vextq_u16(d1_ext, a31, 3)); - - vst1q_u16(dst + 6 * stride + 0, vextq_u16(d0[0], d0[1], 3)); - vst1q_u16(dst + 6 * stride + 8, vextq_u16(d0[1], d0[2], 3)); - vst1q_u16(dst + 6 * stride + 16, vextq_u16(d0[2], d0[3], 3)); - vst1q_u16(dst + 6 * stride + 24, vextq_u16(d0_ext, a31, 4)); - vst1q_u16(dst + 7 * stride + 0, vextq_u16(d1[0], d1[1], 3)); - vst1q_u16(dst + 7 * stride + 8, vextq_u16(d1[1], d1[2], 3)); - vst1q_u16(dst + 7 * stride + 16, vextq_u16(d1[2], d1[3], 3)); - vst1q_u16(dst + 7 * stride + 24, vextq_u16(d1_ext, a31, 4)); - - vst1q_u16(dst + 8 * stride + 0, vextq_u16(d0[0], d0[1], 4)); - vst1q_u16(dst + 8 * stride + 8, vextq_u16(d0[1], d0[2], 4)); - vst1q_u16(dst + 8 * stride + 16, vextq_u16(d0[2], d0[3], 4)); - vst1q_u16(dst + 8 * stride + 24, vextq_u16(d0_ext, a31, 5)); - vst1q_u16(dst + 9 * stride + 0, vextq_u16(d1[0], d1[1], 4)); - vst1q_u16(dst + 9 * stride + 8, vextq_u16(d1[1], d1[2], 4)); - vst1q_u16(dst + 9 * stride + 16, vextq_u16(d1[2], d1[3], 4)); - vst1q_u16(dst + 9 * stride + 24, vextq_u16(d1_ext, a31, 5)); - - vst1q_u16(dst + 10 * stride + 0, vextq_u16(d0[0], d0[1], 5)); - vst1q_u16(dst + 10 * stride + 8, vextq_u16(d0[1], d0[2], 5)); - vst1q_u16(dst + 10 * stride + 16, vextq_u16(d0[2], d0[3], 5)); - vst1q_u16(dst + 10 * stride + 24, vextq_u16(d0_ext, a31, 6)); - vst1q_u16(dst + 11 * stride + 0, vextq_u16(d1[0], d1[1], 5)); - vst1q_u16(dst + 11 * stride + 8, vextq_u16(d1[1], d1[2], 5)); - vst1q_u16(dst + 11 * stride + 16, vextq_u16(d1[2], d1[3], 5)); - vst1q_u16(dst + 11 * stride + 24, vextq_u16(d1_ext, a31, 6)); - - vst1q_u16(dst + 12 * stride + 0, vextq_u16(d0[0], d0[1], 6)); - vst1q_u16(dst + 12 * stride + 8, vextq_u16(d0[1], d0[2], 6)); - vst1q_u16(dst + 12 * stride + 16, vextq_u16(d0[2], d0[3], 6)); - vst1q_u16(dst + 12 * stride + 24, vextq_u16(d0_ext, a31, 7)); - vst1q_u16(dst + 13 * stride + 0, vextq_u16(d1[0], d1[1], 6)); - vst1q_u16(dst + 13 * stride + 8, vextq_u16(d1[1], d1[2], 6)); - vst1q_u16(dst + 13 * stride + 16, vextq_u16(d1[2], d1[3], 6)); - vst1q_u16(dst + 13 * stride + 24, vextq_u16(d1_ext, a31, 7)); - - vst1q_u16(dst + 14 * stride + 0, vextq_u16(d0[0], d0[1], 7)); - vst1q_u16(dst + 14 * stride + 8, vextq_u16(d0[1], d0[2], 7)); - vst1q_u16(dst + 14 * stride + 16, vextq_u16(d0[2], d0[3], 7)); - vst1q_u16(dst + 14 * stride + 24, a31); - vst1q_u16(dst + 15 * stride + 0, vextq_u16(d1[0], d1[1], 7)); - vst1q_u16(dst + 15 * stride + 8, vextq_u16(d1[1], d1[2], 7)); - vst1q_u16(dst + 15 * stride + 16, vextq_u16(d1[2], d1[3], 7)); - vst1q_u16(dst + 15 * stride + 24, a31); - - vst1q_u16(dst + 16 * stride + 0, d0[1]); - vst1q_u16(dst + 16 * stride + 8, d0[2]); - vst1q_u16(dst + 16 * stride + 16, vextq_u16(d0_ext, a31, 1)); - vst1q_u16(dst + 16 * stride + 24, a31); - vst1q_u16(dst + 17 * stride + 0, d1[1]); - vst1q_u16(dst + 17 * stride + 8, d1[2]); - vst1q_u16(dst + 17 * stride + 16, vextq_u16(d1_ext, a31, 1)); - vst1q_u16(dst + 17 * stride + 24, a31); - - vst1q_u16(dst + 18 * stride + 0, vextq_u16(d0[1], d0[2], 1)); - vst1q_u16(dst + 18 * stride + 8, vextq_u16(d0[2], d0[3], 1)); - vst1q_u16(dst + 18 * stride + 16, vextq_u16(d0_ext, a31, 2)); - vst1q_u16(dst + 18 * stride + 24, a31); - vst1q_u16(dst + 19 * stride + 0, vextq_u16(d1[1], d1[2], 1)); - vst1q_u16(dst + 19 * stride + 8, vextq_u16(d1[2], d1[3], 1)); - vst1q_u16(dst + 19 * stride + 16, vextq_u16(d1_ext, a31, 2)); - vst1q_u16(dst + 19 * stride + 24, a31); - - vst1q_u16(dst + 20 * stride + 0, vextq_u16(d0[1], d0[2], 2)); - vst1q_u16(dst + 20 * stride + 8, vextq_u16(d0[2], d0[3], 2)); - vst1q_u16(dst + 20 * stride + 16, vextq_u16(d0_ext, a31, 3)); - vst1q_u16(dst + 20 * stride + 24, a31); - vst1q_u16(dst + 21 * stride + 0, vextq_u16(d1[1], d1[2], 2)); - vst1q_u16(dst + 21 * stride + 8, vextq_u16(d1[2], d1[3], 2)); - vst1q_u16(dst + 21 * stride + 16, vextq_u16(d1_ext, a31, 3)); - vst1q_u16(dst + 21 * stride + 24, a31); - - vst1q_u16(dst + 22 * stride + 0, vextq_u16(d0[1], d0[2], 3)); - vst1q_u16(dst + 22 * stride + 8, vextq_u16(d0[2], d0[3], 3)); - vst1q_u16(dst + 22 * stride + 16, vextq_u16(d0_ext, a31, 4)); - vst1q_u16(dst + 22 * stride + 24, a31); - vst1q_u16(dst + 23 * stride + 0, vextq_u16(d1[1], d1[2], 3)); - vst1q_u16(dst + 23 * stride + 8, vextq_u16(d1[2], d1[3], 3)); - vst1q_u16(dst + 23 * stride + 16, vextq_u16(d1_ext, a31, 4)); - vst1q_u16(dst + 23 * stride + 24, a31); - - vst1q_u16(dst + 24 * stride + 0, vextq_u16(d0[1], d0[2], 4)); - vst1q_u16(dst + 24 * stride + 8, vextq_u16(d0[2], d0[3], 4)); - vst1q_u16(dst + 24 * stride + 16, vextq_u16(d0_ext, a31, 5)); - vst1q_u16(dst + 24 * stride + 24, a31); - vst1q_u16(dst + 25 * stride + 0, vextq_u16(d1[1], d1[2], 4)); - vst1q_u16(dst + 25 * stride + 8, vextq_u16(d1[2], d1[3], 4)); - vst1q_u16(dst + 25 * stride + 16, vextq_u16(d1_ext, a31, 5)); - vst1q_u16(dst + 25 * stride + 24, a31); - - vst1q_u16(dst + 26 * stride + 0, vextq_u16(d0[1], d0[2], 5)); - vst1q_u16(dst + 26 * stride + 8, vextq_u16(d0[2], d0[3], 5)); - vst1q_u16(dst + 26 * stride + 16, vextq_u16(d0_ext, a31, 6)); - vst1q_u16(dst + 26 * stride + 24, a31); - vst1q_u16(dst + 27 * stride + 0, vextq_u16(d1[1], d1[2], 5)); - vst1q_u16(dst + 27 * stride + 8, vextq_u16(d1[2], d1[3], 5)); - vst1q_u16(dst + 27 * stride + 16, vextq_u16(d1_ext, a31, 6)); - vst1q_u16(dst + 27 * stride + 24, a31); - - vst1q_u16(dst + 28 * stride + 0, vextq_u16(d0[1], d0[2], 6)); - vst1q_u16(dst + 28 * stride + 8, vextq_u16(d0[2], d0[3], 6)); - vst1q_u16(dst + 28 * stride + 16, vextq_u16(d0_ext, a31, 7)); - vst1q_u16(dst + 28 * stride + 24, a31); - vst1q_u16(dst + 29 * stride + 0, vextq_u16(d1[1], d1[2], 6)); - vst1q_u16(dst + 29 * stride + 8, vextq_u16(d1[2], d1[3], 6)); - vst1q_u16(dst + 29 * stride + 16, vextq_u16(d1_ext, a31, 7)); - vst1q_u16(dst + 29 * stride + 24, a31); - - vst1q_u16(dst + 30 * stride + 0, vextq_u16(d0[1], d0[2], 7)); - vst1q_u16(dst + 30 * stride + 8, vextq_u16(d0[2], d0[3], 7)); - vst1q_u16(dst + 30 * stride + 16, a31); - vst1q_u16(dst + 30 * stride + 24, a31); - vst1q_u16(dst + 31 * stride + 0, vextq_u16(d1[1], d1[2], 7)); - vst1q_u16(dst + 31 * stride + 8, vextq_u16(d1[2], d1[3], 7)); - vst1q_u16(dst + 31 * stride + 16, a31); - vst1q_u16(dst + 31 * stride + 24, a31); -} - -// ----------------------------------------------------------------------------- - -void vpx_highbd_d117_predictor_4x4_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - uint16x4_t az, a0, l0az, l0, l1, azl0, col0, col0_even, col0_odd, d0, d1; - (void)bd; - - az = vld1_u16(above - 1); - a0 = vld1_u16(above + 0); - // [ left[0], above[-1], above[0], above[1] ] - l0az = vext_u16(vld1_dup_u16(left), az, 3); - - l0 = vld1_u16(left + 0); - // The last lane here is unused, reading left[4] could cause a buffer - // over-read, so just fill with a duplicate of left[0] to avoid needing to - // materialize a zero: - // [ left[1], left[2], left[3], x ] - l1 = vext_u16(l0, l0, 1); - // [ above[-1], left[0], left[1], left[2] ] - azl0 = vext_u16(vld1_dup_u16(above - 1), l0, 3); - - d0 = vrhadd_u16(az, a0); - d1 = vrhadd_u16(vhadd_u16(l0az, a0), az); - - col0 = vrhadd_u16(vhadd_u16(azl0, l1), l0); - col0_even = vdup_lane_u16(col0, 0); - col0_odd = vdup_lane_u16(col0, 1); - - vst1_u16(dst + 0 * stride, d0); - vst1_u16(dst + 1 * stride, d1); - vst1_u16(dst + 2 * stride, vext_u16(col0_even, d0, 3)); - vst1_u16(dst + 3 * stride, vext_u16(col0_odd, d1, 3)); -} - -void vpx_highbd_d117_predictor_8x8_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - uint16x8_t az, a0, l0az, l0, l1, azl0, col0, col0_even, col0_odd, d0, d1; - (void)bd; - - az = vld1q_u16(above - 1); - a0 = vld1q_u16(above + 0); - // [ left[0], above[-1], ..., left[5] ] - l0az = vextq_u16(vld1q_dup_u16(left), az, 7); - - l0 = vld1q_u16(left + 0); - // The last lane here is unused, reading left[8] could cause a buffer - // over-read, so just fill with a duplicate of left[0] to avoid needing to - // materialize a zero: - // [ left[1], ... , left[7], x ] - l1 = vextq_u16(l0, l0, 1); - // [ above[-1], left[0], ..., left[6] ] - azl0 = vextq_u16(vld1q_dup_u16(above - 1), l0, 7); - - // d0[0] = AVG2(above[-1], above[0]) - // ... - // d0[7] = AVG2(above[6], above[7]) - d0 = vrhaddq_u16(az, a0); - - // d1[0] = AVG3(left[0], above[-1], above[0]) - // d1[1] = AVG3(above[-1], above[0], above[1]) - // ... - // d1[7] = AVG3(above[5], above[6], above[7]) - d1 = vrhaddq_u16(vhaddq_u16(l0az, a0), az); - - // The ext instruction shifts elements in from the end of the vector rather - // than the start, so reverse the vector to put the elements to be shifted in - // at the end: - // col0[7] = AVG3(above[-1], left[0], left[1]) - // col0[6] = AVG3(left[0], left[1], left[2]) - // ... - // col0[0] = AVG3(left[6], left[7], left[8]) - col0 = vrhaddq_u16(vhaddq_u16(azl0, l1), l0); - col0 = vrev64q_u16(vextq_u16(col0, col0, 4)); - - // We don't care about the first parameter to this uzp since we only ever use - // the high three elements, we just use col0 again since it is already - // available: - // col0_even = [ x, x, x, x, x, col0[3], col0[5], col0[7] ] - // col0_odd = [ x, x, x, x, x, col0[2], col0[4], col0[6] ] - col0_even = vuzpq_u16(col0, col0).val[1]; - col0_odd = vuzpq_u16(col0, col0).val[0]; - - // Incrementally shift more elements from col0 into d0/1: - // stride=0 [ d0[0], d0[1], d0[2], d0[3], d0[4], d0[5], d0[6], d0[7] ] - // stride=1 [ d1[0], d1[1], d1[2], d1[3], d1[4], d1[5], d1[6], d1[7] ] - // stride=2 [ col0[7], d0[0], d0[1], d0[2], d0[3], d0[4], d0[5], d0[6] ] - // stride=3 [ col0[6], d1[0], d1[1], d1[2], d1[3], d1[4], d1[5], d1[6] ] - // stride=4 [ col0[5], col0[7], d0[0], d0[1], d0[2], d0[3], d0[4], d0[5] ] - // stride=5 [ col0[4], col0[6], d1[0], d1[1], d1[2], d1[3], d1[4], d1[5] ] - // stride=6 [ col0[3], col0[5], col0[7], d0[0], d0[1], d0[2], d0[3], d0[4] ] - // stride=7 [ col0[2], col0[4], col0[6], d1[0], d1[1], d1[2], d1[3], d1[4] ] - vst1q_u16(dst + 0 * stride, d0); - vst1q_u16(dst + 1 * stride, d1); - vst1q_u16(dst + 2 * stride, vextq_u16(col0_even, d0, 7)); - vst1q_u16(dst + 3 * stride, vextq_u16(col0_odd, d1, 7)); - vst1q_u16(dst + 4 * stride, vextq_u16(col0_even, d0, 6)); - vst1q_u16(dst + 5 * stride, vextq_u16(col0_odd, d1, 6)); - vst1q_u16(dst + 6 * stride, vextq_u16(col0_even, d0, 5)); - vst1q_u16(dst + 7 * stride, vextq_u16(col0_odd, d1, 5)); -} - -void vpx_highbd_d117_predictor_16x16_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - uint16x8_t az, a0, a6, a7, a8, l0az, l0, l1, l7, l8, l9, azl0, col0_lo, - col0_hi, col0_even, col0_odd, d0_lo, d0_hi, d1_lo, d1_hi; - (void)bd; - - az = vld1q_u16(above - 1); - a0 = vld1q_u16(above + 0); - a6 = vld1q_u16(above + 6); - a7 = vld1q_u16(above + 7); - a8 = vld1q_u16(above + 8); - // [ left[0], above[-1], ..., left[5] ] - l0az = vextq_u16(vld1q_dup_u16(left), az, 7); - - l0 = vld1q_u16(left + 0); - l1 = vld1q_u16(left + 1); - l7 = vld1q_u16(left + 7); - l8 = vld1q_u16(left + 8); - // The last lane here is unused, reading left[16] could cause a buffer - // over-read, so just fill with a duplicate of left[8] to avoid needing to - // materialize a zero: - // [ left[9], ... , left[15], x ] - l9 = vextq_u16(l8, l8, 1); - // [ above[-1], left[0], ..., left[6] ] - azl0 = vextq_u16(vld1q_dup_u16(above - 1), l0, 7); - - d0_lo = vrhaddq_u16(az, a0); - d0_hi = vrhaddq_u16(a7, a8); - d1_lo = vrhaddq_u16(vhaddq_u16(l0az, a0), az); - d1_hi = vrhaddq_u16(vhaddq_u16(a6, a8), a7); - - col0_lo = vrhaddq_u16(vhaddq_u16(azl0, l1), l0); - col0_hi = vrhaddq_u16(vhaddq_u16(l7, l9), l8); - - // Reverse within each vector, then swap the array indices in the uzp to - // complete the reversal across all 16 elements. - col0_lo = vrev64q_u16(vextq_u16(col0_lo, col0_lo, 4)); - col0_hi = vrev64q_u16(vextq_u16(col0_hi, col0_hi, 4)); - col0_even = vuzpq_u16(col0_hi, col0_lo).val[1]; - col0_odd = vuzpq_u16(col0_hi, col0_lo).val[0]; - - vst1q_u16(dst + 0 * stride + 0, d0_lo); - vst1q_u16(dst + 0 * stride + 8, d0_hi); - vst1q_u16(dst + 1 * stride + 0, d1_lo); - vst1q_u16(dst + 1 * stride + 8, d1_hi); - - vst1q_u16(dst + 2 * stride + 0, vextq_u16(col0_even, d0_lo, 7)); - vst1q_u16(dst + 2 * stride + 8, vextq_u16(d0_lo, d0_hi, 7)); - vst1q_u16(dst + 3 * stride + 0, vextq_u16(col0_odd, d1_lo, 7)); - vst1q_u16(dst + 3 * stride + 8, vextq_u16(d1_lo, d1_hi, 7)); - - vst1q_u16(dst + 4 * stride + 0, vextq_u16(col0_even, d0_lo, 6)); - vst1q_u16(dst + 4 * stride + 8, vextq_u16(d0_lo, d0_hi, 6)); - vst1q_u16(dst + 5 * stride + 0, vextq_u16(col0_odd, d1_lo, 6)); - vst1q_u16(dst + 5 * stride + 8, vextq_u16(d1_lo, d1_hi, 6)); - - vst1q_u16(dst + 6 * stride + 0, vextq_u16(col0_even, d0_lo, 5)); - vst1q_u16(dst + 6 * stride + 8, vextq_u16(d0_lo, d0_hi, 5)); - vst1q_u16(dst + 7 * stride + 0, vextq_u16(col0_odd, d1_lo, 5)); - vst1q_u16(dst + 7 * stride + 8, vextq_u16(d1_lo, d1_hi, 5)); - - vst1q_u16(dst + 8 * stride + 0, vextq_u16(col0_even, d0_lo, 4)); - vst1q_u16(dst + 8 * stride + 8, vextq_u16(d0_lo, d0_hi, 4)); - vst1q_u16(dst + 9 * stride + 0, vextq_u16(col0_odd, d1_lo, 4)); - vst1q_u16(dst + 9 * stride + 8, vextq_u16(d1_lo, d1_hi, 4)); - - vst1q_u16(dst + 10 * stride + 0, vextq_u16(col0_even, d0_lo, 3)); - vst1q_u16(dst + 10 * stride + 8, vextq_u16(d0_lo, d0_hi, 3)); - vst1q_u16(dst + 11 * stride + 0, vextq_u16(col0_odd, d1_lo, 3)); - vst1q_u16(dst + 11 * stride + 8, vextq_u16(d1_lo, d1_hi, 3)); - - vst1q_u16(dst + 12 * stride + 0, vextq_u16(col0_even, d0_lo, 2)); - vst1q_u16(dst + 12 * stride + 8, vextq_u16(d0_lo, d0_hi, 2)); - vst1q_u16(dst + 13 * stride + 0, vextq_u16(col0_odd, d1_lo, 2)); - vst1q_u16(dst + 13 * stride + 8, vextq_u16(d1_lo, d1_hi, 2)); - - vst1q_u16(dst + 14 * stride + 0, vextq_u16(col0_even, d0_lo, 1)); - vst1q_u16(dst + 14 * stride + 8, vextq_u16(d0_lo, d0_hi, 1)); - vst1q_u16(dst + 15 * stride + 0, vextq_u16(col0_odd, d1_lo, 1)); - vst1q_u16(dst + 15 * stride + 8, vextq_u16(d1_lo, d1_hi, 1)); -} - -void vpx_highbd_d117_predictor_32x32_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - uint16x8_t az, a0, a6, a7, a8, a14, a15, a16, a22, a23, a24, l0az, l0, l1, l7, - l8, l9, l15, l16, l17, l23, l24, l25, azl0, d0[4], d1[4], col0[4], - col0_even[2], col0_odd[2]; - (void)bd; - - az = vld1q_u16(above - 1); - a0 = vld1q_u16(above + 0); - a6 = vld1q_u16(above + 6); - a7 = vld1q_u16(above + 7); - a8 = vld1q_u16(above + 8); - a14 = vld1q_u16(above + 14); - a15 = vld1q_u16(above + 15); - a16 = vld1q_u16(above + 16); - a22 = vld1q_u16(above + 22); - a23 = vld1q_u16(above + 23); - a24 = vld1q_u16(above + 24); - // [ left[0], above[-1], ..., left[5] ] - l0az = vextq_u16(vld1q_dup_u16(left), az, 7); - - l0 = vld1q_u16(left + 0); - l1 = vld1q_u16(left + 1); - l7 = vld1q_u16(left + 7); - l8 = vld1q_u16(left + 8); - l9 = vld1q_u16(left + 9); - l15 = vld1q_u16(left + 15); - l16 = vld1q_u16(left + 16); - l17 = vld1q_u16(left + 17); - l23 = vld1q_u16(left + 23); - l24 = vld1q_u16(left + 24); - l25 = vld1q_u16(left + 25); - // The last lane here is unused, reading left[32] could cause a buffer - // over-read, so just fill with a duplicate of left[24] to avoid needing to - // materialize a zero: - // [ left[25], ... , left[31], x ] - l25 = vextq_u16(l24, l24, 1); - // [ above[-1], left[0], ..., left[6] ] - azl0 = vextq_u16(vld1q_dup_u16(above - 1), l0, 7); - - d0[0] = vrhaddq_u16(az, a0); - d0[1] = vrhaddq_u16(a7, a8); - d0[2] = vrhaddq_u16(a15, a16); - d0[3] = vrhaddq_u16(a23, a24); - d1[0] = vrhaddq_u16(vhaddq_u16(l0az, a0), az); - d1[1] = vrhaddq_u16(vhaddq_u16(a6, a8), a7); - d1[2] = vrhaddq_u16(vhaddq_u16(a14, a16), a15); - d1[3] = vrhaddq_u16(vhaddq_u16(a22, a24), a23); - - col0[0] = vrhaddq_u16(vhaddq_u16(azl0, l1), l0); - col0[1] = vrhaddq_u16(vhaddq_u16(l7, l9), l8); - col0[2] = vrhaddq_u16(vhaddq_u16(l15, l17), l16); - col0[3] = vrhaddq_u16(vhaddq_u16(l23, l25), l24); - - // Reverse within each vector, then swap the array indices in both the uzp - // and the col0_{even,odd} assignment to complete the reversal across all - // 32-elements. - col0[0] = vrev64q_u16(vextq_u16(col0[0], col0[0], 4)); - col0[1] = vrev64q_u16(vextq_u16(col0[1], col0[1], 4)); - col0[2] = vrev64q_u16(vextq_u16(col0[2], col0[2], 4)); - col0[3] = vrev64q_u16(vextq_u16(col0[3], col0[3], 4)); - - col0_even[1] = vuzpq_u16(col0[1], col0[0]).val[1]; - col0_even[0] = vuzpq_u16(col0[3], col0[2]).val[1]; - col0_odd[1] = vuzpq_u16(col0[1], col0[0]).val[0]; - col0_odd[0] = vuzpq_u16(col0[3], col0[2]).val[0]; - - vst1q_u16(dst + 0 * stride + 0, d0[0]); - vst1q_u16(dst + 0 * stride + 8, d0[1]); - vst1q_u16(dst + 0 * stride + 16, d0[2]); - vst1q_u16(dst + 0 * stride + 24, d0[3]); - vst1q_u16(dst + 1 * stride + 0, d1[0]); - vst1q_u16(dst + 1 * stride + 8, d1[1]); - vst1q_u16(dst + 1 * stride + 16, d1[2]); - vst1q_u16(dst + 1 * stride + 24, d1[3]); - - vst1q_u16(dst + 2 * stride + 0, vextq_u16(col0_even[1], d0[0], 7)); - vst1q_u16(dst + 2 * stride + 8, vextq_u16(d0[0], d0[1], 7)); - vst1q_u16(dst + 2 * stride + 16, vextq_u16(d0[1], d0[2], 7)); - vst1q_u16(dst + 2 * stride + 24, vextq_u16(d0[2], d0[3], 7)); - vst1q_u16(dst + 3 * stride + 0, vextq_u16(col0_odd[1], d1[0], 7)); - vst1q_u16(dst + 3 * stride + 8, vextq_u16(d1[0], d1[1], 7)); - vst1q_u16(dst + 3 * stride + 16, vextq_u16(d1[1], d1[2], 7)); - vst1q_u16(dst + 3 * stride + 24, vextq_u16(d1[2], d1[3], 7)); - - vst1q_u16(dst + 4 * stride + 0, vextq_u16(col0_even[1], d0[0], 6)); - vst1q_u16(dst + 4 * stride + 8, vextq_u16(d0[0], d0[1], 6)); - vst1q_u16(dst + 4 * stride + 16, vextq_u16(d0[1], d0[2], 6)); - vst1q_u16(dst + 4 * stride + 24, vextq_u16(d0[2], d0[3], 6)); - vst1q_u16(dst + 5 * stride + 0, vextq_u16(col0_odd[1], d1[0], 6)); - vst1q_u16(dst + 5 * stride + 8, vextq_u16(d1[0], d1[1], 6)); - vst1q_u16(dst + 5 * stride + 16, vextq_u16(d1[1], d1[2], 6)); - vst1q_u16(dst + 5 * stride + 24, vextq_u16(d1[2], d1[3], 6)); - - vst1q_u16(dst + 6 * stride + 0, vextq_u16(col0_even[1], d0[0], 5)); - vst1q_u16(dst + 6 * stride + 8, vextq_u16(d0[0], d0[1], 5)); - vst1q_u16(dst + 6 * stride + 16, vextq_u16(d0[1], d0[2], 5)); - vst1q_u16(dst + 6 * stride + 24, vextq_u16(d0[2], d0[3], 5)); - vst1q_u16(dst + 7 * stride + 0, vextq_u16(col0_odd[1], d1[0], 5)); - vst1q_u16(dst + 7 * stride + 8, vextq_u16(d1[0], d1[1], 5)); - vst1q_u16(dst + 7 * stride + 16, vextq_u16(d1[1], d1[2], 5)); - vst1q_u16(dst + 7 * stride + 24, vextq_u16(d1[2], d1[3], 5)); - - vst1q_u16(dst + 8 * stride + 0, vextq_u16(col0_even[1], d0[0], 4)); - vst1q_u16(dst + 8 * stride + 8, vextq_u16(d0[0], d0[1], 4)); - vst1q_u16(dst + 8 * stride + 16, vextq_u16(d0[1], d0[2], 4)); - vst1q_u16(dst + 8 * stride + 24, vextq_u16(d0[2], d0[3], 4)); - vst1q_u16(dst + 9 * stride + 0, vextq_u16(col0_odd[1], d1[0], 4)); - vst1q_u16(dst + 9 * stride + 8, vextq_u16(d1[0], d1[1], 4)); - vst1q_u16(dst + 9 * stride + 16, vextq_u16(d1[1], d1[2], 4)); - vst1q_u16(dst + 9 * stride + 24, vextq_u16(d1[2], d1[3], 4)); - - vst1q_u16(dst + 10 * stride + 0, vextq_u16(col0_even[1], d0[0], 3)); - vst1q_u16(dst + 10 * stride + 8, vextq_u16(d0[0], d0[1], 3)); - vst1q_u16(dst + 10 * stride + 16, vextq_u16(d0[1], d0[2], 3)); - vst1q_u16(dst + 10 * stride + 24, vextq_u16(d0[2], d0[3], 3)); - vst1q_u16(dst + 11 * stride + 0, vextq_u16(col0_odd[1], d1[0], 3)); - vst1q_u16(dst + 11 * stride + 8, vextq_u16(d1[0], d1[1], 3)); - vst1q_u16(dst + 11 * stride + 16, vextq_u16(d1[1], d1[2], 3)); - vst1q_u16(dst + 11 * stride + 24, vextq_u16(d1[2], d1[3], 3)); - - vst1q_u16(dst + 12 * stride + 0, vextq_u16(col0_even[1], d0[0], 2)); - vst1q_u16(dst + 12 * stride + 8, vextq_u16(d0[0], d0[1], 2)); - vst1q_u16(dst + 12 * stride + 16, vextq_u16(d0[1], d0[2], 2)); - vst1q_u16(dst + 12 * stride + 24, vextq_u16(d0[2], d0[3], 2)); - vst1q_u16(dst + 13 * stride + 0, vextq_u16(col0_odd[1], d1[0], 2)); - vst1q_u16(dst + 13 * stride + 8, vextq_u16(d1[0], d1[1], 2)); - vst1q_u16(dst + 13 * stride + 16, vextq_u16(d1[1], d1[2], 2)); - vst1q_u16(dst + 13 * stride + 24, vextq_u16(d1[2], d1[3], 2)); - - vst1q_u16(dst + 14 * stride + 0, vextq_u16(col0_even[1], d0[0], 1)); - vst1q_u16(dst + 14 * stride + 8, vextq_u16(d0[0], d0[1], 1)); - vst1q_u16(dst + 14 * stride + 16, vextq_u16(d0[1], d0[2], 1)); - vst1q_u16(dst + 14 * stride + 24, vextq_u16(d0[2], d0[3], 1)); - vst1q_u16(dst + 15 * stride + 0, vextq_u16(col0_odd[1], d1[0], 1)); - vst1q_u16(dst + 15 * stride + 8, vextq_u16(d1[0], d1[1], 1)); - vst1q_u16(dst + 15 * stride + 16, vextq_u16(d1[1], d1[2], 1)); - vst1q_u16(dst + 15 * stride + 24, vextq_u16(d1[2], d1[3], 1)); - - vst1q_u16(dst + 16 * stride + 0, col0_even[1]); - vst1q_u16(dst + 16 * stride + 8, d0[0]); - vst1q_u16(dst + 16 * stride + 16, d0[1]); - vst1q_u16(dst + 16 * stride + 24, d0[2]); - vst1q_u16(dst + 17 * stride + 0, col0_odd[1]); - vst1q_u16(dst + 17 * stride + 8, d1[0]); - vst1q_u16(dst + 17 * stride + 16, d1[1]); - vst1q_u16(dst + 17 * stride + 24, d1[2]); - - vst1q_u16(dst + 18 * stride + 0, vextq_u16(col0_even[0], col0_even[1], 7)); - vst1q_u16(dst + 18 * stride + 8, vextq_u16(col0_even[1], d0[0], 7)); - vst1q_u16(dst + 18 * stride + 16, vextq_u16(d0[0], d0[1], 7)); - vst1q_u16(dst + 18 * stride + 24, vextq_u16(d0[1], d0[2], 7)); - vst1q_u16(dst + 19 * stride + 0, vextq_u16(col0_odd[0], col0_odd[1], 7)); - vst1q_u16(dst + 19 * stride + 8, vextq_u16(col0_odd[1], d1[0], 7)); - vst1q_u16(dst + 19 * stride + 16, vextq_u16(d1[0], d1[1], 7)); - vst1q_u16(dst + 19 * stride + 24, vextq_u16(d1[1], d1[2], 7)); - - vst1q_u16(dst + 20 * stride + 0, vextq_u16(col0_even[0], col0_even[1], 6)); - vst1q_u16(dst + 20 * stride + 8, vextq_u16(col0_even[1], d0[0], 6)); - vst1q_u16(dst + 20 * stride + 16, vextq_u16(d0[0], d0[1], 6)); - vst1q_u16(dst + 20 * stride + 24, vextq_u16(d0[1], d0[2], 6)); - vst1q_u16(dst + 21 * stride + 0, vextq_u16(col0_odd[0], col0_odd[1], 6)); - vst1q_u16(dst + 21 * stride + 8, vextq_u16(col0_odd[1], d1[0], 6)); - vst1q_u16(dst + 21 * stride + 16, vextq_u16(d1[0], d1[1], 6)); - vst1q_u16(dst + 21 * stride + 24, vextq_u16(d1[1], d1[2], 6)); - - vst1q_u16(dst + 22 * stride + 0, vextq_u16(col0_even[0], col0_even[1], 5)); - vst1q_u16(dst + 22 * stride + 8, vextq_u16(col0_even[1], d0[0], 5)); - vst1q_u16(dst + 22 * stride + 16, vextq_u16(d0[0], d0[1], 5)); - vst1q_u16(dst + 22 * stride + 24, vextq_u16(d0[1], d0[2], 5)); - vst1q_u16(dst + 23 * stride + 0, vextq_u16(col0_odd[0], col0_odd[1], 5)); - vst1q_u16(dst + 23 * stride + 8, vextq_u16(col0_odd[1], d1[0], 5)); - vst1q_u16(dst + 23 * stride + 16, vextq_u16(d1[0], d1[1], 5)); - vst1q_u16(dst + 23 * stride + 24, vextq_u16(d1[1], d1[2], 5)); - - vst1q_u16(dst + 24 * stride + 0, vextq_u16(col0_even[0], col0_even[1], 4)); - vst1q_u16(dst + 24 * stride + 8, vextq_u16(col0_even[1], d0[0], 4)); - vst1q_u16(dst + 24 * stride + 16, vextq_u16(d0[0], d0[1], 4)); - vst1q_u16(dst + 24 * stride + 24, vextq_u16(d0[1], d0[2], 4)); - vst1q_u16(dst + 25 * stride + 0, vextq_u16(col0_odd[0], col0_odd[1], 4)); - vst1q_u16(dst + 25 * stride + 8, vextq_u16(col0_odd[1], d1[0], 4)); - vst1q_u16(dst + 25 * stride + 16, vextq_u16(d1[0], d1[1], 4)); - vst1q_u16(dst + 25 * stride + 24, vextq_u16(d1[1], d1[2], 4)); - - vst1q_u16(dst + 26 * stride + 0, vextq_u16(col0_even[0], col0_even[1], 3)); - vst1q_u16(dst + 26 * stride + 8, vextq_u16(col0_even[1], d0[0], 3)); - vst1q_u16(dst + 26 * stride + 16, vextq_u16(d0[0], d0[1], 3)); - vst1q_u16(dst + 26 * stride + 24, vextq_u16(d0[1], d0[2], 3)); - vst1q_u16(dst + 27 * stride + 0, vextq_u16(col0_odd[0], col0_odd[1], 3)); - vst1q_u16(dst + 27 * stride + 8, vextq_u16(col0_odd[1], d1[0], 3)); - vst1q_u16(dst + 27 * stride + 16, vextq_u16(d1[0], d1[1], 3)); - vst1q_u16(dst + 27 * stride + 24, vextq_u16(d1[1], d1[2], 3)); - - vst1q_u16(dst + 28 * stride + 0, vextq_u16(col0_even[0], col0_even[1], 2)); - vst1q_u16(dst + 28 * stride + 8, vextq_u16(col0_even[1], d0[0], 2)); - vst1q_u16(dst + 28 * stride + 16, vextq_u16(d0[0], d0[1], 2)); - vst1q_u16(dst + 28 * stride + 24, vextq_u16(d0[1], d0[2], 2)); - vst1q_u16(dst + 29 * stride + 0, vextq_u16(col0_odd[0], col0_odd[1], 2)); - vst1q_u16(dst + 29 * stride + 8, vextq_u16(col0_odd[1], d1[0], 2)); - vst1q_u16(dst + 29 * stride + 16, vextq_u16(d1[0], d1[1], 2)); - vst1q_u16(dst + 29 * stride + 24, vextq_u16(d1[1], d1[2], 2)); - - vst1q_u16(dst + 30 * stride + 0, vextq_u16(col0_even[0], col0_even[1], 1)); - vst1q_u16(dst + 30 * stride + 8, vextq_u16(col0_even[1], d0[0], 1)); - vst1q_u16(dst + 30 * stride + 16, vextq_u16(d0[0], d0[1], 1)); - vst1q_u16(dst + 30 * stride + 24, vextq_u16(d0[1], d0[2], 1)); - vst1q_u16(dst + 31 * stride + 0, vextq_u16(col0_odd[0], col0_odd[1], 1)); - vst1q_u16(dst + 31 * stride + 8, vextq_u16(col0_odd[1], d1[0], 1)); - vst1q_u16(dst + 31 * stride + 16, vextq_u16(d1[0], d1[1], 1)); - vst1q_u16(dst + 31 * stride + 24, vextq_u16(d1[1], d1[2], 1)); -} - -// ----------------------------------------------------------------------------- - -void vpx_highbd_d153_predictor_4x4_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - // See vpx_highbd_d153_predictor_8x8_neon for details on the implementation. - uint16x4_t az, a0, l0az, l0, l1, azl0, d0, d1, d2, d20_lo, d20_hi; - (void)bd; - - az = vld1_u16(above - 1); - a0 = vld1_u16(above + 0); - // [ left[0], above[-1], above[0], above[1] ] - l0az = vext_u16(vld1_dup_u16(left), az, 3); - - l0 = vld1_u16(left); - // The last lane here is unused, reading left[4] could cause a buffer - // over-read, so just fill with a duplicate of left[0] to avoid needing to - // materialize a zero: - // [ left[1], left[2], left[3], x ] - l1 = vext_u16(l0, l0, 1); - // [ above[-1], left[0], left[1], left[2] ] - azl0 = vext_u16(vld1_dup_u16(above - 1), l0, 3); - - d0 = vrhadd_u16(azl0, l0); - d1 = vrhadd_u16(vhadd_u16(l0az, a0), az); - d2 = vrhadd_u16(vhadd_u16(azl0, l1), l0); - - d20_lo = vzip_u16(vrev64_u16(d2), vrev64_u16(d0)).val[0]; - d20_hi = vzip_u16(vrev64_u16(d2), vrev64_u16(d0)).val[1]; - - // Incrementally shift more elements from d0/d2 reversed into d1: - // stride=0 [ d0[0], d1[0], d1[1], d1[2] ] - // stride=1 [ d0[1], d2[0], d0[0], d1[0] ] - // stride=2 [ d0[2], d2[1], d0[1], d2[0] ] - // stride=3 [ d0[3], d2[2], d0[2], d2[1] ] - vst1_u16(dst + 0 * stride, vext_u16(d20_hi, d1, 3)); - vst1_u16(dst + 1 * stride, vext_u16(d20_hi, d1, 1)); - vst1_u16(dst + 2 * stride, vext_u16(d20_lo, d20_hi, 3)); - vst1_u16(dst + 3 * stride, vext_u16(d20_lo, d20_hi, 1)); -} - -void vpx_highbd_d153_predictor_8x8_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - uint16x8_t az, a0, l0az, l0, l1, azl0, d0, d1, d2, d0_rev, d2_rev, d20_lo, - d20_hi; - (void)bd; - - az = vld1q_u16(above - 1); - a0 = vld1q_u16(above + 0); - // [ left[0], above[-1], ... , above[5] ] - l0az = vextq_u16(vld1q_dup_u16(left), az, 7); - - l0 = vld1q_u16(left); - // The last lane here is unused, reading left[8] could cause a buffer - // over-read, so just fill with a duplicate of left[0] to avoid needing to - // materialize a zero: - // [ left[1], ... , left[7], x ] - l1 = vextq_u16(l0, l0, 1); - // [ above[-1], left[0], ... , left[6] ] - azl0 = vextq_u16(vld1q_dup_u16(above - 1), l0, 7); - - // d0[0] = AVG2(above[-1], left[0]) - // d0[1] = AVG2(left[0], left[1]) - // ... - // d0[7] = AVG2(left[6], left[7]) - d0 = vrhaddq_u16(azl0, l0); - - // d1[0] = AVG3(left[0], above[-1], above[0]) - // d1[1] = AVG3(above[-1], above[0], above[1]) - // ... - // d1[7] = AVG3(above[5], above[6], above[7]) - d1 = vrhaddq_u16(vhaddq_u16(l0az, a0), az); - - // d2[0] = AVG3(above[-1], left[0], left[1]) - // d2[1] = AVG3(left[0], left[1], left[2]) - // ... - // d2[7] = AVG3(left[6], left[7], left[8]) - d2 = vrhaddq_u16(vhaddq_u16(azl0, l1), l0); - - // The ext instruction shifts elements in from the end of the vector rather - // than the start, so reverse the vectors to put the elements to be shifted - // in at the end: - d0_rev = vrev64q_u16(vextq_u16(d0, d0, 4)); - d2_rev = vrev64q_u16(vextq_u16(d2, d2, 4)); - - d20_lo = vzipq_u16(d2_rev, d0_rev).val[0]; - d20_hi = vzipq_u16(d2_rev, d0_rev).val[1]; - - // Incrementally shift more elements from d0/d2 reversed into d1: - // stride=0 [ d0[0], d1[0], d1[1], d1[2], d1[3], d1[4], d1[5], d1[6] ] - // stride=1 [ d0[1], d2[0], d0[0], d1[0], d1[1], d1[2], d1[3], d1[4] ] - // stride=2 [ d0[2], d2[1], d0[1], d2[0], d0[0], d1[0], d1[1], d1[2] ] - // stride=3 [ d0[3], d2[2], d0[2], d2[1], d0[1], d2[0], d0[0], d1[0] ] - // stride=4 [ d0[4], d2[3], d0[3], d2[2], d0[2], d2[1], d0[1], d2[0] ] - // stride=5 [ d0[5], d2[4], d0[4], d2[3], d0[3], d2[2], d0[2], d2[1] ] - // stride=6 [ d0[6], d2[5], d0[5], d2[4], d0[4], d2[3], d0[3], d2[2] ] - // stride=7 [ d0[7], d2[6], d0[6], d2[5], d0[5], d2[4], d0[4], d2[3] ] - vst1q_u16(dst + 0 * stride, vextq_u16(d20_hi, d1, 7)); - vst1q_u16(dst + 1 * stride, vextq_u16(d20_hi, d1, 5)); - vst1q_u16(dst + 2 * stride, vextq_u16(d20_hi, d1, 3)); - vst1q_u16(dst + 3 * stride, vextq_u16(d20_hi, d1, 1)); - vst1q_u16(dst + 4 * stride, vextq_u16(d20_lo, d20_hi, 7)); - vst1q_u16(dst + 5 * stride, vextq_u16(d20_lo, d20_hi, 5)); - vst1q_u16(dst + 6 * stride, vextq_u16(d20_lo, d20_hi, 3)); - vst1q_u16(dst + 7 * stride, vextq_u16(d20_lo, d20_hi, 1)); -} - -void vpx_highbd_d153_predictor_16x16_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - // See vpx_highbd_d153_predictor_8x8_neon for details on the implementation. - uint16x8_t az, a0, a6, a7, a8, l0az, l0, l1, l7, l8, l9, azl0, d0[2], d1[2], - d2[2], d20[4]; - (void)bd; - - az = vld1q_u16(above - 1); - a0 = vld1q_u16(above + 0); - a6 = vld1q_u16(above + 6); - a7 = vld1q_u16(above + 7); - a8 = vld1q_u16(above + 8); - // [ left[0], above[-1], ... , above[13] ] - l0az = vextq_u16(vld1q_dup_u16(left), az, 7); - - l0 = vld1q_u16(left + 0); - l1 = vld1q_u16(left + 1); - l7 = vld1q_u16(left + 7); - l8 = vld1q_u16(left + 8); - // The last lane here is unused, reading left[16] could cause a buffer - // over-read, so just fill with a duplicate of left[8] to avoid needing to - // materialize a zero: - // [ left[9], ... , left[15], x ] - l9 = vextq_u16(l8, l8, 1); - // [ above[-1], left[0], ... , left[14] ] - azl0 = vextq_u16(vld1q_dup_u16(above - 1), l0, 7); - - d0[0] = vrhaddq_u16(azl0, l0); - d0[1] = vrhaddq_u16(l7, l8); - d1[0] = vrhaddq_u16(vhaddq_u16(l0az, a0), az); - d1[1] = vrhaddq_u16(vhaddq_u16(a6, a8), a7); - d2[0] = vrhaddq_u16(vhaddq_u16(azl0, l1), l0); - d2[1] = vrhaddq_u16(vhaddq_u16(l7, l9), l8); - - d0[0] = vrev64q_u16(vextq_u16(d0[0], d0[0], 4)); - d0[1] = vrev64q_u16(vextq_u16(d0[1], d0[1], 4)); - d2[0] = vrev64q_u16(vextq_u16(d2[0], d2[0], 4)); - d2[1] = vrev64q_u16(vextq_u16(d2[1], d2[1], 4)); - - d20[0] = vzipq_u16(d2[1], d0[1]).val[0]; - d20[1] = vzipq_u16(d2[1], d0[1]).val[1]; - d20[2] = vzipq_u16(d2[0], d0[0]).val[0]; - d20[3] = vzipq_u16(d2[0], d0[0]).val[1]; - - vst1q_u16(dst + 0 * stride + 0, vextq_u16(d20[3], d1[0], 7)); - vst1q_u16(dst + 0 * stride + 8, vextq_u16(d1[0], d1[1], 7)); - vst1q_u16(dst + 1 * stride + 0, vextq_u16(d20[3], d1[0], 5)); - vst1q_u16(dst + 1 * stride + 8, vextq_u16(d1[0], d1[1], 5)); - vst1q_u16(dst + 2 * stride + 0, vextq_u16(d20[3], d1[0], 3)); - vst1q_u16(dst + 2 * stride + 8, vextq_u16(d1[0], d1[1], 3)); - vst1q_u16(dst + 3 * stride + 0, vextq_u16(d20[3], d1[0], 1)); - vst1q_u16(dst + 3 * stride + 8, vextq_u16(d1[0], d1[1], 1)); - - vst1q_u16(dst + 4 * stride + 0, vextq_u16(d20[2], d20[3], 7)); - vst1q_u16(dst + 4 * stride + 8, vextq_u16(d20[3], d1[0], 7)); - vst1q_u16(dst + 5 * stride + 0, vextq_u16(d20[2], d20[3], 5)); - vst1q_u16(dst + 5 * stride + 8, vextq_u16(d20[3], d1[0], 5)); - vst1q_u16(dst + 6 * stride + 0, vextq_u16(d20[2], d20[3], 3)); - vst1q_u16(dst + 6 * stride + 8, vextq_u16(d20[3], d1[0], 3)); - vst1q_u16(dst + 7 * stride + 0, vextq_u16(d20[2], d20[3], 1)); - vst1q_u16(dst + 7 * stride + 8, vextq_u16(d20[3], d1[0], 1)); - - vst1q_u16(dst + 8 * stride + 0, vextq_u16(d20[1], d20[2], 7)); - vst1q_u16(dst + 8 * stride + 8, vextq_u16(d20[2], d20[3], 7)); - vst1q_u16(dst + 9 * stride + 0, vextq_u16(d20[1], d20[2], 5)); - vst1q_u16(dst + 9 * stride + 8, vextq_u16(d20[2], d20[3], 5)); - vst1q_u16(dst + 10 * stride + 0, vextq_u16(d20[1], d20[2], 3)); - vst1q_u16(dst + 10 * stride + 8, vextq_u16(d20[2], d20[3], 3)); - vst1q_u16(dst + 11 * stride + 0, vextq_u16(d20[1], d20[2], 1)); - vst1q_u16(dst + 11 * stride + 8, vextq_u16(d20[2], d20[3], 1)); - - vst1q_u16(dst + 12 * stride + 0, vextq_u16(d20[0], d20[1], 7)); - vst1q_u16(dst + 12 * stride + 8, vextq_u16(d20[1], d20[2], 7)); - vst1q_u16(dst + 13 * stride + 0, vextq_u16(d20[0], d20[1], 5)); - vst1q_u16(dst + 13 * stride + 8, vextq_u16(d20[1], d20[2], 5)); - vst1q_u16(dst + 14 * stride + 0, vextq_u16(d20[0], d20[1], 3)); - vst1q_u16(dst + 14 * stride + 8, vextq_u16(d20[1], d20[2], 3)); - vst1q_u16(dst + 15 * stride + 0, vextq_u16(d20[0], d20[1], 1)); - vst1q_u16(dst + 15 * stride + 8, vextq_u16(d20[1], d20[2], 1)); -} - -void vpx_highbd_d153_predictor_32x32_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - // See vpx_highbd_d153_predictor_8x8_neon for details on the implementation. - uint16x8_t az, a0, a6, a7, a8, a14, a15, a16, a22, a23, a24, l0az, l0, l1, l7, - l8, l9, l15, l16, l17, l23, l24, l25, azl0, d0[4], d1[4], d2[4], d20[8]; - (void)bd; - - az = vld1q_u16(above - 1); - a0 = vld1q_u16(above + 0); - a6 = vld1q_u16(above + 6); - a7 = vld1q_u16(above + 7); - a8 = vld1q_u16(above + 8); - a14 = vld1q_u16(above + 14); - a15 = vld1q_u16(above + 15); - a16 = vld1q_u16(above + 16); - a22 = vld1q_u16(above + 22); - a23 = vld1q_u16(above + 23); - a24 = vld1q_u16(above + 24); - // [ left[0], above[-1], ... , above[13] ] - l0az = vextq_u16(vld1q_dup_u16(left), az, 7); - - l0 = vld1q_u16(left + 0); - l1 = vld1q_u16(left + 1); - l7 = vld1q_u16(left + 7); - l8 = vld1q_u16(left + 8); - l9 = vld1q_u16(left + 9); - l15 = vld1q_u16(left + 15); - l16 = vld1q_u16(left + 16); - l17 = vld1q_u16(left + 17); - l23 = vld1q_u16(left + 23); - l24 = vld1q_u16(left + 24); - // The last lane here is unused, reading left[32] could cause a buffer - // over-read, so just fill with a duplicate of left[24] to avoid needing to - // materialize a zero: - // [ left[25], ... , left[31], x ] - l25 = vextq_u16(l24, l24, 1); - // [ above[-1], left[0], ... , left[14] ] - azl0 = vextq_u16(vld1q_dup_u16(above - 1), l0, 7); - - d0[0] = vrhaddq_u16(azl0, l0); - d0[1] = vrhaddq_u16(l7, l8); - d0[2] = vrhaddq_u16(l15, l16); - d0[3] = vrhaddq_u16(l23, l24); - - d1[0] = vrhaddq_u16(vhaddq_u16(l0az, a0), az); - d1[1] = vrhaddq_u16(vhaddq_u16(a6, a8), a7); - d1[2] = vrhaddq_u16(vhaddq_u16(a14, a16), a15); - d1[3] = vrhaddq_u16(vhaddq_u16(a22, a24), a23); - - d2[0] = vrhaddq_u16(vhaddq_u16(azl0, l1), l0); - d2[1] = vrhaddq_u16(vhaddq_u16(l7, l9), l8); - d2[2] = vrhaddq_u16(vhaddq_u16(l15, l17), l16); - d2[3] = vrhaddq_u16(vhaddq_u16(l23, l25), l24); - - d0[0] = vrev64q_u16(vextq_u16(d0[0], d0[0], 4)); - d0[1] = vrev64q_u16(vextq_u16(d0[1], d0[1], 4)); - d0[2] = vrev64q_u16(vextq_u16(d0[2], d0[2], 4)); - d0[3] = vrev64q_u16(vextq_u16(d0[3], d0[3], 4)); - d2[0] = vrev64q_u16(vextq_u16(d2[0], d2[0], 4)); - d2[1] = vrev64q_u16(vextq_u16(d2[1], d2[1], 4)); - d2[2] = vrev64q_u16(vextq_u16(d2[2], d2[2], 4)); - d2[3] = vrev64q_u16(vextq_u16(d2[3], d2[3], 4)); - - d20[0] = vzipq_u16(d2[3], d0[3]).val[0]; - d20[1] = vzipq_u16(d2[3], d0[3]).val[1]; - d20[2] = vzipq_u16(d2[2], d0[2]).val[0]; - d20[3] = vzipq_u16(d2[2], d0[2]).val[1]; - d20[4] = vzipq_u16(d2[1], d0[1]).val[0]; - d20[5] = vzipq_u16(d2[1], d0[1]).val[1]; - d20[6] = vzipq_u16(d2[0], d0[0]).val[0]; - d20[7] = vzipq_u16(d2[0], d0[0]).val[1]; - - vst1q_u16(dst + 0 * stride + 0, vextq_u16(d20[7], d1[0], 7)); - vst1q_u16(dst + 0 * stride + 8, vextq_u16(d1[0], d1[1], 7)); - vst1q_u16(dst + 0 * stride + 16, vextq_u16(d1[1], d1[2], 7)); - vst1q_u16(dst + 0 * stride + 24, vextq_u16(d1[2], d1[3], 7)); - vst1q_u16(dst + 1 * stride + 0, vextq_u16(d20[7], d1[0], 5)); - vst1q_u16(dst + 1 * stride + 8, vextq_u16(d1[0], d1[1], 5)); - vst1q_u16(dst + 1 * stride + 16, vextq_u16(d1[1], d1[2], 5)); - vst1q_u16(dst + 1 * stride + 24, vextq_u16(d1[2], d1[3], 5)); - vst1q_u16(dst + 2 * stride + 0, vextq_u16(d20[7], d1[0], 3)); - vst1q_u16(dst + 2 * stride + 8, vextq_u16(d1[0], d1[1], 3)); - vst1q_u16(dst + 2 * stride + 16, vextq_u16(d1[1], d1[2], 3)); - vst1q_u16(dst + 2 * stride + 24, vextq_u16(d1[2], d1[3], 3)); - vst1q_u16(dst + 3 * stride + 0, vextq_u16(d20[7], d1[0], 1)); - vst1q_u16(dst + 3 * stride + 8, vextq_u16(d1[0], d1[1], 1)); - vst1q_u16(dst + 3 * stride + 16, vextq_u16(d1[1], d1[2], 1)); - vst1q_u16(dst + 3 * stride + 24, vextq_u16(d1[2], d1[3], 1)); - - vst1q_u16(dst + 4 * stride + 0, vextq_u16(d20[6], d20[7], 7)); - vst1q_u16(dst + 4 * stride + 8, vextq_u16(d20[7], d1[0], 7)); - vst1q_u16(dst + 4 * stride + 16, vextq_u16(d1[0], d1[1], 7)); - vst1q_u16(dst + 4 * stride + 24, vextq_u16(d1[1], d1[2], 7)); - vst1q_u16(dst + 5 * stride + 0, vextq_u16(d20[6], d20[7], 5)); - vst1q_u16(dst + 5 * stride + 8, vextq_u16(d20[7], d1[0], 5)); - vst1q_u16(dst + 5 * stride + 16, vextq_u16(d1[0], d1[1], 5)); - vst1q_u16(dst + 5 * stride + 24, vextq_u16(d1[1], d1[2], 5)); - vst1q_u16(dst + 6 * stride + 0, vextq_u16(d20[6], d20[7], 3)); - vst1q_u16(dst + 6 * stride + 8, vextq_u16(d20[7], d1[0], 3)); - vst1q_u16(dst + 6 * stride + 16, vextq_u16(d1[0], d1[1], 3)); - vst1q_u16(dst + 6 * stride + 24, vextq_u16(d1[1], d1[2], 3)); - vst1q_u16(dst + 7 * stride + 0, vextq_u16(d20[6], d20[7], 1)); - vst1q_u16(dst + 7 * stride + 8, vextq_u16(d20[7], d1[0], 1)); - vst1q_u16(dst + 7 * stride + 16, vextq_u16(d1[0], d1[1], 1)); - vst1q_u16(dst + 7 * stride + 24, vextq_u16(d1[1], d1[2], 1)); - - vst1q_u16(dst + 8 * stride + 0, vextq_u16(d20[5], d20[6], 7)); - vst1q_u16(dst + 8 * stride + 8, vextq_u16(d20[6], d20[7], 7)); - vst1q_u16(dst + 8 * stride + 16, vextq_u16(d20[7], d1[0], 7)); - vst1q_u16(dst + 8 * stride + 24, vextq_u16(d1[0], d1[1], 7)); - vst1q_u16(dst + 9 * stride + 0, vextq_u16(d20[5], d20[6], 5)); - vst1q_u16(dst + 9 * stride + 8, vextq_u16(d20[6], d20[7], 5)); - vst1q_u16(dst + 9 * stride + 16, vextq_u16(d20[7], d1[0], 5)); - vst1q_u16(dst + 9 * stride + 24, vextq_u16(d1[0], d1[1], 5)); - vst1q_u16(dst + 10 * stride + 0, vextq_u16(d20[5], d20[6], 3)); - vst1q_u16(dst + 10 * stride + 8, vextq_u16(d20[6], d20[7], 3)); - vst1q_u16(dst + 10 * stride + 16, vextq_u16(d20[7], d1[0], 3)); - vst1q_u16(dst + 10 * stride + 24, vextq_u16(d1[0], d1[1], 3)); - vst1q_u16(dst + 11 * stride + 0, vextq_u16(d20[5], d20[6], 1)); - vst1q_u16(dst + 11 * stride + 8, vextq_u16(d20[6], d20[7], 1)); - vst1q_u16(dst + 11 * stride + 16, vextq_u16(d20[7], d1[0], 1)); - vst1q_u16(dst + 11 * stride + 24, vextq_u16(d1[0], d1[1], 1)); - - vst1q_u16(dst + 12 * stride + 0, vextq_u16(d20[4], d20[5], 7)); - vst1q_u16(dst + 12 * stride + 8, vextq_u16(d20[5], d20[6], 7)); - vst1q_u16(dst + 12 * stride + 16, vextq_u16(d20[6], d20[7], 7)); - vst1q_u16(dst + 12 * stride + 24, vextq_u16(d20[7], d1[0], 7)); - vst1q_u16(dst + 13 * stride + 0, vextq_u16(d20[4], d20[5], 5)); - vst1q_u16(dst + 13 * stride + 8, vextq_u16(d20[5], d20[6], 5)); - vst1q_u16(dst + 13 * stride + 16, vextq_u16(d20[6], d20[7], 5)); - vst1q_u16(dst + 13 * stride + 24, vextq_u16(d20[7], d1[0], 5)); - vst1q_u16(dst + 14 * stride + 0, vextq_u16(d20[4], d20[5], 3)); - vst1q_u16(dst + 14 * stride + 8, vextq_u16(d20[5], d20[6], 3)); - vst1q_u16(dst + 14 * stride + 16, vextq_u16(d20[6], d20[7], 3)); - vst1q_u16(dst + 14 * stride + 24, vextq_u16(d20[7], d1[0], 3)); - vst1q_u16(dst + 15 * stride + 0, vextq_u16(d20[4], d20[5], 1)); - vst1q_u16(dst + 15 * stride + 8, vextq_u16(d20[5], d20[6], 1)); - vst1q_u16(dst + 15 * stride + 16, vextq_u16(d20[6], d20[7], 1)); - vst1q_u16(dst + 15 * stride + 24, vextq_u16(d20[7], d1[0], 1)); - - vst1q_u16(dst + 16 * stride + 0, vextq_u16(d20[3], d20[4], 7)); - vst1q_u16(dst + 16 * stride + 8, vextq_u16(d20[4], d20[5], 7)); - vst1q_u16(dst + 16 * stride + 16, vextq_u16(d20[5], d20[6], 7)); - vst1q_u16(dst + 16 * stride + 24, vextq_u16(d20[6], d20[7], 7)); - vst1q_u16(dst + 17 * stride + 0, vextq_u16(d20[3], d20[4], 5)); - vst1q_u16(dst + 17 * stride + 8, vextq_u16(d20[4], d20[5], 5)); - vst1q_u16(dst + 17 * stride + 16, vextq_u16(d20[5], d20[6], 5)); - vst1q_u16(dst + 17 * stride + 24, vextq_u16(d20[6], d20[7], 5)); - vst1q_u16(dst + 18 * stride + 0, vextq_u16(d20[3], d20[4], 3)); - vst1q_u16(dst + 18 * stride + 8, vextq_u16(d20[4], d20[5], 3)); - vst1q_u16(dst + 18 * stride + 16, vextq_u16(d20[5], d20[6], 3)); - vst1q_u16(dst + 18 * stride + 24, vextq_u16(d20[6], d20[7], 3)); - vst1q_u16(dst + 19 * stride + 0, vextq_u16(d20[3], d20[4], 1)); - vst1q_u16(dst + 19 * stride + 8, vextq_u16(d20[4], d20[5], 1)); - vst1q_u16(dst + 19 * stride + 16, vextq_u16(d20[5], d20[6], 1)); - vst1q_u16(dst + 19 * stride + 24, vextq_u16(d20[6], d20[7], 1)); - - vst1q_u16(dst + 20 * stride + 0, vextq_u16(d20[2], d20[3], 7)); - vst1q_u16(dst + 20 * stride + 8, vextq_u16(d20[3], d20[4], 7)); - vst1q_u16(dst + 20 * stride + 16, vextq_u16(d20[4], d20[5], 7)); - vst1q_u16(dst + 20 * stride + 24, vextq_u16(d20[5], d20[6], 7)); - vst1q_u16(dst + 21 * stride + 0, vextq_u16(d20[2], d20[3], 5)); - vst1q_u16(dst + 21 * stride + 8, vextq_u16(d20[3], d20[4], 5)); - vst1q_u16(dst + 21 * stride + 16, vextq_u16(d20[4], d20[5], 5)); - vst1q_u16(dst + 21 * stride + 24, vextq_u16(d20[5], d20[6], 5)); - vst1q_u16(dst + 22 * stride + 0, vextq_u16(d20[2], d20[3], 3)); - vst1q_u16(dst + 22 * stride + 8, vextq_u16(d20[3], d20[4], 3)); - vst1q_u16(dst + 22 * stride + 16, vextq_u16(d20[4], d20[5], 3)); - vst1q_u16(dst + 22 * stride + 24, vextq_u16(d20[5], d20[6], 3)); - vst1q_u16(dst + 23 * stride + 0, vextq_u16(d20[2], d20[3], 1)); - vst1q_u16(dst + 23 * stride + 8, vextq_u16(d20[3], d20[4], 1)); - vst1q_u16(dst + 23 * stride + 16, vextq_u16(d20[4], d20[5], 1)); - vst1q_u16(dst + 23 * stride + 24, vextq_u16(d20[5], d20[6], 1)); - - vst1q_u16(dst + 24 * stride + 0, vextq_u16(d20[1], d20[2], 7)); - vst1q_u16(dst + 24 * stride + 8, vextq_u16(d20[2], d20[3], 7)); - vst1q_u16(dst + 24 * stride + 16, vextq_u16(d20[3], d20[4], 7)); - vst1q_u16(dst + 24 * stride + 24, vextq_u16(d20[4], d20[5], 7)); - vst1q_u16(dst + 25 * stride + 0, vextq_u16(d20[1], d20[2], 5)); - vst1q_u16(dst + 25 * stride + 8, vextq_u16(d20[2], d20[3], 5)); - vst1q_u16(dst + 25 * stride + 16, vextq_u16(d20[3], d20[4], 5)); - vst1q_u16(dst + 25 * stride + 24, vextq_u16(d20[4], d20[5], 5)); - vst1q_u16(dst + 26 * stride + 0, vextq_u16(d20[1], d20[2], 3)); - vst1q_u16(dst + 26 * stride + 8, vextq_u16(d20[2], d20[3], 3)); - vst1q_u16(dst + 26 * stride + 16, vextq_u16(d20[3], d20[4], 3)); - vst1q_u16(dst + 26 * stride + 24, vextq_u16(d20[4], d20[5], 3)); - vst1q_u16(dst + 27 * stride + 0, vextq_u16(d20[1], d20[2], 1)); - vst1q_u16(dst + 27 * stride + 8, vextq_u16(d20[2], d20[3], 1)); - vst1q_u16(dst + 27 * stride + 16, vextq_u16(d20[3], d20[4], 1)); - vst1q_u16(dst + 27 * stride + 24, vextq_u16(d20[4], d20[5], 1)); - - vst1q_u16(dst + 28 * stride + 0, vextq_u16(d20[0], d20[1], 7)); - vst1q_u16(dst + 28 * stride + 8, vextq_u16(d20[1], d20[2], 7)); - vst1q_u16(dst + 28 * stride + 16, vextq_u16(d20[2], d20[3], 7)); - vst1q_u16(dst + 28 * stride + 24, vextq_u16(d20[3], d20[4], 7)); - vst1q_u16(dst + 29 * stride + 0, vextq_u16(d20[0], d20[1], 5)); - vst1q_u16(dst + 29 * stride + 8, vextq_u16(d20[1], d20[2], 5)); - vst1q_u16(dst + 29 * stride + 16, vextq_u16(d20[2], d20[3], 5)); - vst1q_u16(dst + 29 * stride + 24, vextq_u16(d20[3], d20[4], 5)); - vst1q_u16(dst + 30 * stride + 0, vextq_u16(d20[0], d20[1], 3)); - vst1q_u16(dst + 30 * stride + 8, vextq_u16(d20[1], d20[2], 3)); - vst1q_u16(dst + 30 * stride + 16, vextq_u16(d20[2], d20[3], 3)); - vst1q_u16(dst + 30 * stride + 24, vextq_u16(d20[3], d20[4], 3)); - vst1q_u16(dst + 31 * stride + 0, vextq_u16(d20[0], d20[1], 1)); - vst1q_u16(dst + 31 * stride + 8, vextq_u16(d20[1], d20[2], 1)); - vst1q_u16(dst + 31 * stride + 16, vextq_u16(d20[2], d20[3], 1)); - vst1q_u16(dst + 31 * stride + 24, vextq_u16(d20[3], d20[4], 1)); -} - -// ----------------------------------------------------------------------------- - -void vpx_highbd_d135_predictor_4x4_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x8_t XA0123___ = vld1q_u16(above - 1); - const uint16x4_t L0123 = vld1_u16(left); - const uint16x4_t L3210 = vrev64_u16(L0123); - const uint16x8_t L____3210 = vcombine_u16(L0123, L3210); - const uint16x8_t L3210XA012 = vcombine_u16(L3210, vget_low_u16(XA0123___)); - const uint16x8_t L210XA0123 = vextq_u16(L____3210, XA0123___, 5); - const uint16x8_t L10XA0123_ = vextq_u16(L____3210, XA0123___, 6); - const uint16x8_t avg1 = vhaddq_u16(L3210XA012, L10XA0123_); - const uint16x8_t avg2 = vrhaddq_u16(avg1, L210XA0123); - const uint16x4_t row_0 = vget_low_u16(avg2); - const uint16x4_t row_1 = vget_high_u16(avg2); - const uint16x4_t r0 = vext_u16(row_0, row_1, 3); - const uint16x4_t r1 = vext_u16(row_0, row_1, 2); - const uint16x4_t r2 = vext_u16(row_0, row_1, 1); - (void)bd; - vst1_u16(dst, r0); - dst += stride; - vst1_u16(dst, r1); - dst += stride; - vst1_u16(dst, r2); - dst += stride; - vst1_u16(dst, row_0); -} - -void vpx_highbd_d135_predictor_8x8_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x8_t XA0123456 = vld1q_u16(above - 1); - const uint16x8_t A01234567 = vld1q_u16(above); - const uint16x8_t A1234567_ = vld1q_u16(above + 1); - const uint16x8_t L01234567 = vld1q_u16(left); - const uint16x4_t L3210 = vrev64_u16(vget_low_u16(L01234567)); - const uint16x4_t L7654 = vrev64_u16(vget_high_u16(L01234567)); - const uint16x8_t L76543210 = vcombine_u16(L7654, L3210); - const uint16x8_t L6543210X = vextq_u16(L76543210, XA0123456, 1); - const uint16x8_t L543210XA0 = vextq_u16(L76543210, XA0123456, 2); - const uint16x8_t avg_0 = vhaddq_u16(L76543210, L543210XA0); - const uint16x8_t avg_1 = vhaddq_u16(XA0123456, A1234567_); - const uint16x8_t row_0 = vrhaddq_u16(avg_0, L6543210X); - const uint16x8_t row_1 = vrhaddq_u16(avg_1, A01234567); - const uint16x8_t r0 = vextq_u16(row_0, row_1, 7); - const uint16x8_t r1 = vextq_u16(row_0, row_1, 6); - const uint16x8_t r2 = vextq_u16(row_0, row_1, 5); - const uint16x8_t r3 = vextq_u16(row_0, row_1, 4); - const uint16x8_t r4 = vextq_u16(row_0, row_1, 3); - const uint16x8_t r5 = vextq_u16(row_0, row_1, 2); - const uint16x8_t r6 = vextq_u16(row_0, row_1, 1); - (void)bd; - vst1q_u16(dst, r0); - dst += stride; - vst1q_u16(dst, r1); - dst += stride; - vst1q_u16(dst, r2); - dst += stride; - vst1q_u16(dst, r3); - dst += stride; - vst1q_u16(dst, r4); - dst += stride; - vst1q_u16(dst, r5); - dst += stride; - vst1q_u16(dst, r6); - dst += stride; - vst1q_u16(dst, row_0); -} - -static INLINE void d135_store_16(uint16_t **dst, const ptrdiff_t stride, - const uint16x8_t row_0, - const uint16x8_t row_1) { - vst1q_u16(*dst, row_0); - *dst += 8; - vst1q_u16(*dst, row_1); - *dst += stride - 8; -} - -void vpx_highbd_d135_predictor_16x16_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x8_t L01234567 = vld1q_u16(left); - const uint16x8_t L89abcdef = vld1q_u16(left + 8); - const uint16x4_t L3210 = vrev64_u16(vget_low_u16(L01234567)); - const uint16x4_t L7654 = vrev64_u16(vget_high_u16(L01234567)); - const uint16x4_t Lba98 = vrev64_u16(vget_low_u16(L89abcdef)); - const uint16x4_t Lfedc = vrev64_u16(vget_high_u16(L89abcdef)); - const uint16x8_t L76543210 = vcombine_u16(L7654, L3210); - const uint16x8_t Lfedcba98 = vcombine_u16(Lfedc, Lba98); - const uint16x8_t Ledcba987 = vextq_u16(Lfedcba98, L76543210, 1); - const uint16x8_t Ldcba9876 = vextq_u16(Lfedcba98, L76543210, 2); - const uint16x8_t avg_0 = vhaddq_u16(Lfedcba98, Ldcba9876); - const uint16x8_t row_0 = vrhaddq_u16(avg_0, Ledcba987); - - const uint16x8_t XA0123456 = vld1q_u16(above - 1); - const uint16x8_t L6543210X = vextq_u16(L76543210, XA0123456, 1); - const uint16x8_t L543210XA0 = vextq_u16(L76543210, XA0123456, 2); - const uint16x8_t avg_1 = vhaddq_u16(L76543210, L543210XA0); - const uint16x8_t row_1 = vrhaddq_u16(avg_1, L6543210X); - - const uint16x8_t A01234567 = vld1q_u16(above); - const uint16x8_t A12345678 = vld1q_u16(above + 1); - const uint16x8_t avg_2 = vhaddq_u16(XA0123456, A12345678); - const uint16x8_t row_2 = vrhaddq_u16(avg_2, A01234567); - - const uint16x8_t A789abcde = vld1q_u16(above + 7); - const uint16x8_t A89abcdef = vld1q_u16(above + 8); - const uint16x8_t A9abcdef_ = vld1q_u16(above + 9); - const uint16x8_t avg_3 = vhaddq_u16(A789abcde, A9abcdef_); - const uint16x8_t row_3 = vrhaddq_u16(avg_3, A89abcdef); - - const uint16x8_t r0_0 = vextq_u16(row_1, row_2, 7); - const uint16x8_t r0_1 = vextq_u16(row_2, row_3, 7); - const uint16x8_t r1_0 = vextq_u16(row_1, row_2, 6); - const uint16x8_t r1_1 = vextq_u16(row_2, row_3, 6); - const uint16x8_t r2_0 = vextq_u16(row_1, row_2, 5); - const uint16x8_t r2_1 = vextq_u16(row_2, row_3, 5); - const uint16x8_t r3_0 = vextq_u16(row_1, row_2, 4); - const uint16x8_t r3_1 = vextq_u16(row_2, row_3, 4); - const uint16x8_t r4_0 = vextq_u16(row_1, row_2, 3); - const uint16x8_t r4_1 = vextq_u16(row_2, row_3, 3); - const uint16x8_t r5_0 = vextq_u16(row_1, row_2, 2); - const uint16x8_t r5_1 = vextq_u16(row_2, row_3, 2); - const uint16x8_t r6_0 = vextq_u16(row_1, row_2, 1); - const uint16x8_t r6_1 = vextq_u16(row_2, row_3, 1); - const uint16x8_t r8_0 = vextq_u16(row_0, row_1, 7); - const uint16x8_t r9_0 = vextq_u16(row_0, row_1, 6); - const uint16x8_t ra_0 = vextq_u16(row_0, row_1, 5); - const uint16x8_t rb_0 = vextq_u16(row_0, row_1, 4); - const uint16x8_t rc_0 = vextq_u16(row_0, row_1, 3); - const uint16x8_t rd_0 = vextq_u16(row_0, row_1, 2); - const uint16x8_t re_0 = vextq_u16(row_0, row_1, 1); - (void)bd; - - d135_store_16(&dst, stride, r0_0, r0_1); - d135_store_16(&dst, stride, r1_0, r1_1); - d135_store_16(&dst, stride, r2_0, r2_1); - d135_store_16(&dst, stride, r3_0, r3_1); - d135_store_16(&dst, stride, r4_0, r4_1); - d135_store_16(&dst, stride, r5_0, r5_1); - d135_store_16(&dst, stride, r6_0, r6_1); - d135_store_16(&dst, stride, row_1, row_2); - d135_store_16(&dst, stride, r8_0, r0_0); - d135_store_16(&dst, stride, r9_0, r1_0); - d135_store_16(&dst, stride, ra_0, r2_0); - d135_store_16(&dst, stride, rb_0, r3_0); - d135_store_16(&dst, stride, rc_0, r4_0); - d135_store_16(&dst, stride, rd_0, r5_0); - d135_store_16(&dst, stride, re_0, r6_0); - vst1q_u16(dst, row_0); - dst += 8; - vst1q_u16(dst, row_1); -} - -void vpx_highbd_d135_predictor_32x32_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x8_t LL01234567 = vld1q_u16(left + 16); - const uint16x8_t LL89abcdef = vld1q_u16(left + 24); - const uint16x4_t LL3210 = vrev64_u16(vget_low_u16(LL01234567)); - const uint16x4_t LL7654 = vrev64_u16(vget_high_u16(LL01234567)); - const uint16x4_t LLba98 = vrev64_u16(vget_low_u16(LL89abcdef)); - const uint16x4_t LLfedc = vrev64_u16(vget_high_u16(LL89abcdef)); - const uint16x8_t LL76543210 = vcombine_u16(LL7654, LL3210); - const uint16x8_t LLfedcba98 = vcombine_u16(LLfedc, LLba98); - const uint16x8_t LLedcba987 = vextq_u16(LLfedcba98, LL76543210, 1); - const uint16x8_t LLdcba9876 = vextq_u16(LLfedcba98, LL76543210, 2); - const uint16x8_t avg_0 = vhaddq_u16(LLfedcba98, LLdcba9876); - uint16x8_t row_0 = vrhaddq_u16(avg_0, LLedcba987); - - const uint16x8_t LU01234567 = vld1q_u16(left); - const uint16x8_t LU89abcdef = vld1q_u16(left + 8); - const uint16x4_t LU3210 = vrev64_u16(vget_low_u16(LU01234567)); - const uint16x4_t LU7654 = vrev64_u16(vget_high_u16(LU01234567)); - const uint16x4_t LUba98 = vrev64_u16(vget_low_u16(LU89abcdef)); - const uint16x4_t LUfedc = vrev64_u16(vget_high_u16(LU89abcdef)); - const uint16x8_t LU76543210 = vcombine_u16(LU7654, LU3210); - const uint16x8_t LUfedcba98 = vcombine_u16(LUfedc, LUba98); - const uint16x8_t LL6543210Uf = vextq_u16(LL76543210, LUfedcba98, 1); - const uint16x8_t LL543210Ufe = vextq_u16(LL76543210, LUfedcba98, 2); - const uint16x8_t avg_1 = vhaddq_u16(LL76543210, LL543210Ufe); - uint16x8_t row_1 = vrhaddq_u16(avg_1, LL6543210Uf); - - const uint16x8_t LUedcba987 = vextq_u16(LUfedcba98, LU76543210, 1); - const uint16x8_t LUdcba9876 = vextq_u16(LUfedcba98, LU76543210, 2); - const uint16x8_t avg_2 = vhaddq_u16(LUfedcba98, LUdcba9876); - uint16x8_t row_2 = vrhaddq_u16(avg_2, LUedcba987); - - const uint16x8_t XAL0123456 = vld1q_u16(above - 1); - const uint16x8_t LU6543210X = vextq_u16(LU76543210, XAL0123456, 1); - const uint16x8_t LU543210XA0 = vextq_u16(LU76543210, XAL0123456, 2); - const uint16x8_t avg_3 = vhaddq_u16(LU76543210, LU543210XA0); - uint16x8_t row_3 = vrhaddq_u16(avg_3, LU6543210X); - - const uint16x8_t AL01234567 = vld1q_u16(above); - const uint16x8_t AL12345678 = vld1q_u16(above + 1); - const uint16x8_t avg_4 = vhaddq_u16(XAL0123456, AL12345678); - uint16x8_t row_4 = vrhaddq_u16(avg_4, AL01234567); - - const uint16x8_t AL789abcde = vld1q_u16(above + 7); - const uint16x8_t AL89abcdef = vld1q_u16(above + 8); - const uint16x8_t AL9abcdefg = vld1q_u16(above + 9); - const uint16x8_t avg_5 = vhaddq_u16(AL789abcde, AL9abcdefg); - uint16x8_t row_5 = vrhaddq_u16(avg_5, AL89abcdef); - - const uint16x8_t ALfR0123456 = vld1q_u16(above + 15); - const uint16x8_t AR01234567 = vld1q_u16(above + 16); - const uint16x8_t AR12345678 = vld1q_u16(above + 17); - const uint16x8_t avg_6 = vhaddq_u16(ALfR0123456, AR12345678); - uint16x8_t row_6 = vrhaddq_u16(avg_6, AR01234567); - - const uint16x8_t AR789abcde = vld1q_u16(above + 23); - const uint16x8_t AR89abcdef = vld1q_u16(above + 24); - const uint16x8_t AR9abcdef_ = vld1q_u16(above + 25); - const uint16x8_t avg_7 = vhaddq_u16(AR789abcde, AR9abcdef_); - uint16x8_t row_7 = vrhaddq_u16(avg_7, AR89abcdef); - int i, j; - (void)bd; - - dst += 31 * stride; - for (i = 0; i < 4; ++i) { - for (j = 0; j < 8; ++j) { - vst1q_u16(dst, row_0); - dst += 8; - vst1q_u16(dst, row_1); - dst += 8; - vst1q_u16(dst, row_2); - dst += 8; - vst1q_u16(dst, row_3); - dst -= stride + 24; - row_0 = vextq_u16(row_0, row_1, 1); - row_1 = vextq_u16(row_1, row_2, 1); - row_2 = vextq_u16(row_2, row_3, 1); - row_3 = vextq_u16(row_3, row_4, 1); - row_4 = vextq_u16(row_4, row_4, 1); - } - row_4 = row_5; - row_5 = row_6; - row_6 = row_7; - } -} - -//------------------------------------------------------------------------------ - -void vpx_highbd_d207_predictor_4x4_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - uint16x4_t l0, l1, l2, l3, c0, c1, c01_lo, c01_hi; - (void)above; - (void)bd; - - l0 = vld1_u16(left + 0); - l3 = vld1_dup_u16(left + 3); - - // [ left[1], left[2], left[3], left[3] ] - l1 = vext_u16(l0, l3, 1); - // [ left[2], left[3], left[3], left[3] ] - l2 = vext_u16(l0, l3, 2); - - c0 = vrhadd_u16(l0, l1); - c1 = vrhadd_u16(vhadd_u16(l0, l2), l1); - - c01_lo = vzip_u16(c0, c1).val[0]; - c01_hi = vzip_u16(c0, c1).val[1]; - - // stride=0 [ c0[0], c1[0], c0[1], c1[1] ] - // stride=1 [ c0[1], c1[1], c0[2], c1[2] ] - // stride=2 [ c0[2], c1[2], c0[3], c1[3] ] - // stride=3 [ c0[3], c1[3], left[3], left[3] ] - vst1_u16(dst + 0 * stride, c01_lo); - vst1_u16(dst + 1 * stride, vext_u16(c01_lo, c01_hi, 2)); - vst1_u16(dst + 2 * stride, c01_hi); - vst1_u16(dst + 3 * stride, vext_u16(c01_hi, l3, 2)); -} - -void vpx_highbd_d207_predictor_8x8_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - uint16x8_t l0, l1, l2, l7, c0, c1, c01_lo, c01_hi; - (void)above; - (void)bd; - - l0 = vld1q_u16(left + 0); - l7 = vld1q_dup_u16(left + 7); - - // [ left[1], left[2], left[3], left[4], left[5], left[6], left[7], left[7] ] - l1 = vextq_u16(l0, l7, 1); - // [ left[2], left[3], left[4], left[5], left[6], left[7], left[7], left[7] ] - l2 = vextq_u16(l0, l7, 2); - - c0 = vrhaddq_u16(l0, l1); - c1 = vrhaddq_u16(vhaddq_u16(l0, l2), l1); - - c01_lo = vzipq_u16(c0, c1).val[0]; - c01_hi = vzipq_u16(c0, c1).val[1]; - - vst1q_u16(dst + 0 * stride, c01_lo); - vst1q_u16(dst + 1 * stride, vextq_u16(c01_lo, c01_hi, 2)); - vst1q_u16(dst + 2 * stride, vextq_u16(c01_lo, c01_hi, 4)); - vst1q_u16(dst + 3 * stride, vextq_u16(c01_lo, c01_hi, 6)); - vst1q_u16(dst + 4 * stride, c01_hi); - vst1q_u16(dst + 5 * stride, vextq_u16(c01_hi, l7, 2)); - vst1q_u16(dst + 6 * stride, vextq_u16(c01_hi, l7, 4)); - vst1q_u16(dst + 7 * stride, vextq_u16(c01_hi, l7, 6)); -} - -void vpx_highbd_d207_predictor_16x16_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - uint16x8_t l0, l1, l2, l8, l9, l10, l15, c0[2], c1[2], c01[4]; - (void)above; - (void)bd; - - l0 = vld1q_u16(left + 0); - l1 = vld1q_u16(left + 1); - l2 = vld1q_u16(left + 2); - l8 = vld1q_u16(left + 8); - l15 = vld1q_dup_u16(left + 15); - - l9 = vextq_u16(l8, l15, 1); - l10 = vextq_u16(l8, l15, 2); - - c0[0] = vrhaddq_u16(l0, l1); - c0[1] = vrhaddq_u16(l8, l9); - c1[0] = vrhaddq_u16(vhaddq_u16(l0, l2), l1); - c1[1] = vrhaddq_u16(vhaddq_u16(l8, l10), l9); - - c01[0] = vzipq_u16(c0[0], c1[0]).val[0]; - c01[1] = vzipq_u16(c0[0], c1[0]).val[1]; - c01[2] = vzipq_u16(c0[1], c1[1]).val[0]; - c01[3] = vzipq_u16(c0[1], c1[1]).val[1]; - - vst1q_u16(dst + 0 * stride + 0, c01[0]); - vst1q_u16(dst + 0 * stride + 8, c01[1]); - vst1q_u16(dst + 1 * stride + 0, vextq_u16(c01[0], c01[1], 2)); - vst1q_u16(dst + 1 * stride + 8, vextq_u16(c01[1], c01[2], 2)); - vst1q_u16(dst + 2 * stride + 0, vextq_u16(c01[0], c01[1], 4)); - vst1q_u16(dst + 2 * stride + 8, vextq_u16(c01[1], c01[2], 4)); - vst1q_u16(dst + 3 * stride + 0, vextq_u16(c01[0], c01[1], 6)); - vst1q_u16(dst + 3 * stride + 8, vextq_u16(c01[1], c01[2], 6)); - - vst1q_u16(dst + 4 * stride + 0, c01[1]); - vst1q_u16(dst + 4 * stride + 8, c01[2]); - vst1q_u16(dst + 5 * stride + 0, vextq_u16(c01[1], c01[2], 2)); - vst1q_u16(dst + 5 * stride + 8, vextq_u16(c01[2], c01[3], 2)); - vst1q_u16(dst + 6 * stride + 0, vextq_u16(c01[1], c01[2], 4)); - vst1q_u16(dst + 6 * stride + 8, vextq_u16(c01[2], c01[3], 4)); - vst1q_u16(dst + 7 * stride + 0, vextq_u16(c01[1], c01[2], 6)); - vst1q_u16(dst + 7 * stride + 8, vextq_u16(c01[2], c01[3], 6)); - - vst1q_u16(dst + 8 * stride + 0, c01[2]); - vst1q_u16(dst + 8 * stride + 8, c01[3]); - vst1q_u16(dst + 9 * stride + 0, vextq_u16(c01[2], c01[3], 2)); - vst1q_u16(dst + 9 * stride + 8, vextq_u16(c01[3], l15, 2)); - vst1q_u16(dst + 10 * stride + 0, vextq_u16(c01[2], c01[3], 4)); - vst1q_u16(dst + 10 * stride + 8, vextq_u16(c01[3], l15, 4)); - vst1q_u16(dst + 11 * stride + 0, vextq_u16(c01[2], c01[3], 6)); - vst1q_u16(dst + 11 * stride + 8, vextq_u16(c01[3], l15, 6)); - - vst1q_u16(dst + 12 * stride + 0, c01[3]); - vst1q_u16(dst + 12 * stride + 8, l15); - vst1q_u16(dst + 13 * stride + 0, vextq_u16(c01[3], l15, 2)); - vst1q_u16(dst + 13 * stride + 8, l15); - vst1q_u16(dst + 14 * stride + 0, vextq_u16(c01[3], l15, 4)); - vst1q_u16(dst + 14 * stride + 8, l15); - vst1q_u16(dst + 15 * stride + 0, vextq_u16(c01[3], l15, 6)); - vst1q_u16(dst + 15 * stride + 8, l15); -} - -void vpx_highbd_d207_predictor_32x32_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - uint16x8_t l0, l1, l2, l8, l9, l10, l16, l17, l18, l24, l25, l26, l31, c0[4], - c1[4], c01[8]; - (void)above; - (void)bd; - - l0 = vld1q_u16(left + 0); - l1 = vld1q_u16(left + 1); - l2 = vld1q_u16(left + 2); - l8 = vld1q_u16(left + 8); - l9 = vld1q_u16(left + 9); - l10 = vld1q_u16(left + 10); - l16 = vld1q_u16(left + 16); - l17 = vld1q_u16(left + 17); - l18 = vld1q_u16(left + 18); - l24 = vld1q_u16(left + 24); - l31 = vld1q_dup_u16(left + 31); - - l25 = vextq_u16(l24, l31, 1); - l26 = vextq_u16(l24, l31, 2); - - c0[0] = vrhaddq_u16(l0, l1); - c0[1] = vrhaddq_u16(l8, l9); - c0[2] = vrhaddq_u16(l16, l17); - c0[3] = vrhaddq_u16(l24, l25); - c1[0] = vrhaddq_u16(vhaddq_u16(l0, l2), l1); - c1[1] = vrhaddq_u16(vhaddq_u16(l8, l10), l9); - c1[2] = vrhaddq_u16(vhaddq_u16(l16, l18), l17); - c1[3] = vrhaddq_u16(vhaddq_u16(l24, l26), l25); - - c01[0] = vzipq_u16(c0[0], c1[0]).val[0]; - c01[1] = vzipq_u16(c0[0], c1[0]).val[1]; - c01[2] = vzipq_u16(c0[1], c1[1]).val[0]; - c01[3] = vzipq_u16(c0[1], c1[1]).val[1]; - c01[4] = vzipq_u16(c0[2], c1[2]).val[0]; - c01[5] = vzipq_u16(c0[2], c1[2]).val[1]; - c01[6] = vzipq_u16(c0[3], c1[3]).val[0]; - c01[7] = vzipq_u16(c0[3], c1[3]).val[1]; - - vst1q_u16(dst + 0 * stride + 0, c01[0]); - vst1q_u16(dst + 0 * stride + 8, c01[1]); - vst1q_u16(dst + 0 * stride + 16, c01[2]); - vst1q_u16(dst + 0 * stride + 24, c01[3]); - vst1q_u16(dst + 1 * stride + 0, vextq_u16(c01[0], c01[1], 2)); - vst1q_u16(dst + 1 * stride + 8, vextq_u16(c01[1], c01[2], 2)); - vst1q_u16(dst + 1 * stride + 16, vextq_u16(c01[2], c01[3], 2)); - vst1q_u16(dst + 1 * stride + 24, vextq_u16(c01[3], c01[4], 2)); - vst1q_u16(dst + 2 * stride + 0, vextq_u16(c01[0], c01[1], 4)); - vst1q_u16(dst + 2 * stride + 8, vextq_u16(c01[1], c01[2], 4)); - vst1q_u16(dst + 2 * stride + 16, vextq_u16(c01[2], c01[3], 4)); - vst1q_u16(dst + 2 * stride + 24, vextq_u16(c01[3], c01[4], 4)); - vst1q_u16(dst + 3 * stride + 0, vextq_u16(c01[0], c01[1], 6)); - vst1q_u16(dst + 3 * stride + 8, vextq_u16(c01[1], c01[2], 6)); - vst1q_u16(dst + 3 * stride + 16, vextq_u16(c01[2], c01[3], 6)); - vst1q_u16(dst + 3 * stride + 24, vextq_u16(c01[3], c01[4], 6)); - - vst1q_u16(dst + 4 * stride + 0, c01[1]); - vst1q_u16(dst + 4 * stride + 8, c01[2]); - vst1q_u16(dst + 4 * stride + 16, c01[3]); - vst1q_u16(dst + 4 * stride + 24, c01[4]); - vst1q_u16(dst + 5 * stride + 0, vextq_u16(c01[1], c01[2], 2)); - vst1q_u16(dst + 5 * stride + 8, vextq_u16(c01[2], c01[3], 2)); - vst1q_u16(dst + 5 * stride + 16, vextq_u16(c01[3], c01[4], 2)); - vst1q_u16(dst + 5 * stride + 24, vextq_u16(c01[4], c01[5], 2)); - vst1q_u16(dst + 6 * stride + 0, vextq_u16(c01[1], c01[2], 4)); - vst1q_u16(dst + 6 * stride + 8, vextq_u16(c01[2], c01[3], 4)); - vst1q_u16(dst + 6 * stride + 16, vextq_u16(c01[3], c01[4], 4)); - vst1q_u16(dst + 6 * stride + 24, vextq_u16(c01[4], c01[5], 4)); - vst1q_u16(dst + 7 * stride + 0, vextq_u16(c01[1], c01[2], 6)); - vst1q_u16(dst + 7 * stride + 8, vextq_u16(c01[2], c01[3], 6)); - vst1q_u16(dst + 7 * stride + 16, vextq_u16(c01[3], c01[4], 6)); - vst1q_u16(dst + 7 * stride + 24, vextq_u16(c01[4], c01[5], 6)); - - vst1q_u16(dst + 8 * stride + 0, c01[2]); - vst1q_u16(dst + 8 * stride + 8, c01[3]); - vst1q_u16(dst + 8 * stride + 16, c01[4]); - vst1q_u16(dst + 8 * stride + 24, c01[5]); - vst1q_u16(dst + 9 * stride + 0, vextq_u16(c01[2], c01[3], 2)); - vst1q_u16(dst + 9 * stride + 8, vextq_u16(c01[3], c01[4], 2)); - vst1q_u16(dst + 9 * stride + 16, vextq_u16(c01[4], c01[5], 2)); - vst1q_u16(dst + 9 * stride + 24, vextq_u16(c01[5], c01[6], 2)); - vst1q_u16(dst + 10 * stride + 0, vextq_u16(c01[2], c01[3], 4)); - vst1q_u16(dst + 10 * stride + 8, vextq_u16(c01[3], c01[4], 4)); - vst1q_u16(dst + 10 * stride + 16, vextq_u16(c01[4], c01[5], 4)); - vst1q_u16(dst + 10 * stride + 24, vextq_u16(c01[5], c01[6], 4)); - vst1q_u16(dst + 11 * stride + 0, vextq_u16(c01[2], c01[3], 6)); - vst1q_u16(dst + 11 * stride + 8, vextq_u16(c01[3], c01[4], 6)); - vst1q_u16(dst + 11 * stride + 16, vextq_u16(c01[4], c01[5], 6)); - vst1q_u16(dst + 11 * stride + 24, vextq_u16(c01[5], c01[6], 6)); - - vst1q_u16(dst + 12 * stride + 0, c01[3]); - vst1q_u16(dst + 12 * stride + 8, c01[4]); - vst1q_u16(dst + 12 * stride + 16, c01[5]); - vst1q_u16(dst + 12 * stride + 24, c01[6]); - vst1q_u16(dst + 13 * stride + 0, vextq_u16(c01[3], c01[4], 2)); - vst1q_u16(dst + 13 * stride + 8, vextq_u16(c01[4], c01[5], 2)); - vst1q_u16(dst + 13 * stride + 16, vextq_u16(c01[5], c01[6], 2)); - vst1q_u16(dst + 13 * stride + 24, vextq_u16(c01[6], c01[7], 2)); - vst1q_u16(dst + 14 * stride + 0, vextq_u16(c01[3], c01[4], 4)); - vst1q_u16(dst + 14 * stride + 8, vextq_u16(c01[4], c01[5], 4)); - vst1q_u16(dst + 14 * stride + 16, vextq_u16(c01[5], c01[6], 4)); - vst1q_u16(dst + 14 * stride + 24, vextq_u16(c01[6], c01[7], 4)); - vst1q_u16(dst + 15 * stride + 0, vextq_u16(c01[3], c01[4], 6)); - vst1q_u16(dst + 15 * stride + 8, vextq_u16(c01[4], c01[5], 6)); - vst1q_u16(dst + 15 * stride + 16, vextq_u16(c01[5], c01[6], 6)); - vst1q_u16(dst + 15 * stride + 24, vextq_u16(c01[6], c01[7], 6)); - - vst1q_u16(dst + 16 * stride + 0, c01[4]); - vst1q_u16(dst + 16 * stride + 8, c01[5]); - vst1q_u16(dst + 16 * stride + 16, c01[6]); - vst1q_u16(dst + 16 * stride + 24, c01[7]); - vst1q_u16(dst + 17 * stride + 0, vextq_u16(c01[4], c01[5], 2)); - vst1q_u16(dst + 17 * stride + 8, vextq_u16(c01[5], c01[6], 2)); - vst1q_u16(dst + 17 * stride + 16, vextq_u16(c01[6], c01[7], 2)); - vst1q_u16(dst + 17 * stride + 24, vextq_u16(c01[7], l31, 2)); - vst1q_u16(dst + 18 * stride + 0, vextq_u16(c01[4], c01[5], 4)); - vst1q_u16(dst + 18 * stride + 8, vextq_u16(c01[5], c01[6], 4)); - vst1q_u16(dst + 18 * stride + 16, vextq_u16(c01[6], c01[7], 4)); - vst1q_u16(dst + 18 * stride + 24, vextq_u16(c01[7], l31, 4)); - vst1q_u16(dst + 19 * stride + 0, vextq_u16(c01[4], c01[5], 6)); - vst1q_u16(dst + 19 * stride + 8, vextq_u16(c01[5], c01[6], 6)); - vst1q_u16(dst + 19 * stride + 16, vextq_u16(c01[6], c01[7], 6)); - vst1q_u16(dst + 19 * stride + 24, vextq_u16(c01[7], l31, 6)); - - vst1q_u16(dst + 20 * stride + 0, c01[5]); - vst1q_u16(dst + 20 * stride + 8, c01[6]); - vst1q_u16(dst + 20 * stride + 16, c01[7]); - vst1q_u16(dst + 20 * stride + 24, l31); - vst1q_u16(dst + 21 * stride + 0, vextq_u16(c01[5], c01[6], 2)); - vst1q_u16(dst + 21 * stride + 8, vextq_u16(c01[6], c01[7], 2)); - vst1q_u16(dst + 21 * stride + 16, vextq_u16(c01[7], l31, 2)); - vst1q_u16(dst + 21 * stride + 24, vextq_u16(l31, l31, 2)); - vst1q_u16(dst + 22 * stride + 0, vextq_u16(c01[5], c01[6], 4)); - vst1q_u16(dst + 22 * stride + 8, vextq_u16(c01[6], c01[7], 4)); - vst1q_u16(dst + 22 * stride + 16, vextq_u16(c01[7], l31, 4)); - vst1q_u16(dst + 22 * stride + 24, vextq_u16(l31, l31, 4)); - vst1q_u16(dst + 23 * stride + 0, vextq_u16(c01[5], c01[6], 6)); - vst1q_u16(dst + 23 * stride + 8, vextq_u16(c01[6], c01[7], 6)); - vst1q_u16(dst + 23 * stride + 16, vextq_u16(c01[7], l31, 6)); - vst1q_u16(dst + 23 * stride + 24, vextq_u16(l31, l31, 6)); - - vst1q_u16(dst + 24 * stride + 0, c01[6]); - vst1q_u16(dst + 24 * stride + 8, c01[7]); - vst1q_u16(dst + 24 * stride + 16, l31); - vst1q_u16(dst + 24 * stride + 24, l31); - vst1q_u16(dst + 25 * stride + 0, vextq_u16(c01[6], c01[7], 2)); - vst1q_u16(dst + 25 * stride + 8, vextq_u16(c01[7], l31, 2)); - vst1q_u16(dst + 25 * stride + 16, vextq_u16(l31, l31, 2)); - vst1q_u16(dst + 25 * stride + 24, vextq_u16(l31, l31, 2)); - vst1q_u16(dst + 26 * stride + 0, vextq_u16(c01[6], c01[7], 4)); - vst1q_u16(dst + 26 * stride + 8, vextq_u16(c01[7], l31, 4)); - vst1q_u16(dst + 26 * stride + 16, vextq_u16(l31, l31, 4)); - vst1q_u16(dst + 26 * stride + 24, vextq_u16(l31, l31, 4)); - vst1q_u16(dst + 27 * stride + 0, vextq_u16(c01[6], c01[7], 6)); - vst1q_u16(dst + 27 * stride + 8, vextq_u16(c01[7], l31, 6)); - vst1q_u16(dst + 27 * stride + 16, vextq_u16(l31, l31, 6)); - vst1q_u16(dst + 27 * stride + 24, vextq_u16(l31, l31, 6)); - - vst1q_u16(dst + 28 * stride + 0, c01[7]); - vst1q_u16(dst + 28 * stride + 8, l31); - vst1q_u16(dst + 28 * stride + 16, l31); - vst1q_u16(dst + 28 * stride + 24, l31); - vst1q_u16(dst + 29 * stride + 0, vextq_u16(c01[7], l31, 2)); - vst1q_u16(dst + 29 * stride + 8, vextq_u16(l31, l31, 2)); - vst1q_u16(dst + 29 * stride + 16, vextq_u16(l31, l31, 2)); - vst1q_u16(dst + 29 * stride + 24, vextq_u16(l31, l31, 2)); - vst1q_u16(dst + 30 * stride + 0, vextq_u16(c01[7], l31, 4)); - vst1q_u16(dst + 30 * stride + 8, vextq_u16(l31, l31, 4)); - vst1q_u16(dst + 30 * stride + 16, vextq_u16(l31, l31, 4)); - vst1q_u16(dst + 30 * stride + 24, vextq_u16(l31, l31, 4)); - vst1q_u16(dst + 31 * stride + 0, vextq_u16(c01[7], l31, 6)); - vst1q_u16(dst + 31 * stride + 8, vextq_u16(l31, l31, 6)); - vst1q_u16(dst + 31 * stride + 16, vextq_u16(l31, l31, 6)); - vst1q_u16(dst + 31 * stride + 24, vextq_u16(l31, l31, 6)); -} - -//------------------------------------------------------------------------------ - -void vpx_highbd_v_predictor_4x4_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x4_t row = vld1_u16(above); - int i; - (void)left; - (void)bd; - - for (i = 0; i < 4; i++, dst += stride) { - vst1_u16(dst, row); - } -} - -void vpx_highbd_v_predictor_8x8_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x8_t row = vld1q_u16(above); - int i; - (void)left; - (void)bd; - - for (i = 0; i < 8; i++, dst += stride) { - vst1q_u16(dst, row); - } -} - -void vpx_highbd_v_predictor_16x16_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x8_t row0 = vld1q_u16(above + 0); - const uint16x8_t row1 = vld1q_u16(above + 8); - int i; - (void)left; - (void)bd; - - for (i = 0; i < 16; i++) { - vst1q_u16(dst + 0, row0); - vst1q_u16(dst + 8, row1); - dst += stride; - } -} - -void vpx_highbd_v_predictor_32x32_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x8_t row0 = vld1q_u16(above + 0); - const uint16x8_t row1 = vld1q_u16(above + 8); - const uint16x8_t row2 = vld1q_u16(above + 16); - const uint16x8_t row3 = vld1q_u16(above + 24); - int i; - (void)left; - (void)bd; - - for (i = 0; i < 32; i++) { - vst1q_u16(dst + 0, row0); - vst1q_u16(dst + 8, row1); - vst1q_u16(dst + 16, row2); - vst1q_u16(dst + 24, row3); - dst += stride; - } -} - -// ----------------------------------------------------------------------------- - -void vpx_highbd_h_predictor_4x4_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x4_t left_u16 = vld1_u16(left); - uint16x4_t row; - (void)above; - (void)bd; - - row = vdup_lane_u16(left_u16, 0); - vst1_u16(dst, row); - dst += stride; - row = vdup_lane_u16(left_u16, 1); - vst1_u16(dst, row); - dst += stride; - row = vdup_lane_u16(left_u16, 2); - vst1_u16(dst, row); - dst += stride; - row = vdup_lane_u16(left_u16, 3); - vst1_u16(dst, row); -} - -void vpx_highbd_h_predictor_8x8_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16x8_t left_u16 = vld1q_u16(left); - const uint16x4_t left_low = vget_low_u16(left_u16); - const uint16x4_t left_high = vget_high_u16(left_u16); - uint16x8_t row; - (void)above; - (void)bd; - - row = vdupq_lane_u16(left_low, 0); - vst1q_u16(dst, row); - dst += stride; - row = vdupq_lane_u16(left_low, 1); - vst1q_u16(dst, row); - dst += stride; - row = vdupq_lane_u16(left_low, 2); - vst1q_u16(dst, row); - dst += stride; - row = vdupq_lane_u16(left_low, 3); - vst1q_u16(dst, row); - dst += stride; - row = vdupq_lane_u16(left_high, 0); - vst1q_u16(dst, row); - dst += stride; - row = vdupq_lane_u16(left_high, 1); - vst1q_u16(dst, row); - dst += stride; - row = vdupq_lane_u16(left_high, 2); - vst1q_u16(dst, row); - dst += stride; - row = vdupq_lane_u16(left_high, 3); - vst1q_u16(dst, row); -} - -static INLINE void h_store_16(uint16_t **dst, const ptrdiff_t stride, - const uint16x8_t row) { - // Note: vst1q is faster than vst2q - vst1q_u16(*dst, row); - *dst += 8; - vst1q_u16(*dst, row); - *dst += stride - 8; -} - -void vpx_highbd_h_predictor_16x16_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - int i; - (void)above; - (void)bd; - - for (i = 0; i < 2; i++, left += 8) { - const uint16x8_t left_u16q = vld1q_u16(left); - const uint16x4_t left_low = vget_low_u16(left_u16q); - const uint16x4_t left_high = vget_high_u16(left_u16q); - uint16x8_t row; - - row = vdupq_lane_u16(left_low, 0); - h_store_16(&dst, stride, row); - row = vdupq_lane_u16(left_low, 1); - h_store_16(&dst, stride, row); - row = vdupq_lane_u16(left_low, 2); - h_store_16(&dst, stride, row); - row = vdupq_lane_u16(left_low, 3); - h_store_16(&dst, stride, row); - row = vdupq_lane_u16(left_high, 0); - h_store_16(&dst, stride, row); - row = vdupq_lane_u16(left_high, 1); - h_store_16(&dst, stride, row); - row = vdupq_lane_u16(left_high, 2); - h_store_16(&dst, stride, row); - row = vdupq_lane_u16(left_high, 3); - h_store_16(&dst, stride, row); - } -} - -static INLINE void h_store_32(uint16_t **dst, const ptrdiff_t stride, - const uint16x8_t row) { - // Note: vst1q is faster than vst2q - vst1q_u16(*dst, row); - *dst += 8; - vst1q_u16(*dst, row); - *dst += 8; - vst1q_u16(*dst, row); - *dst += 8; - vst1q_u16(*dst, row); - *dst += stride - 24; -} - -void vpx_highbd_h_predictor_32x32_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - int i; - (void)above; - (void)bd; - - for (i = 0; i < 4; i++, left += 8) { - const uint16x8_t left_u16q = vld1q_u16(left); - const uint16x4_t left_low = vget_low_u16(left_u16q); - const uint16x4_t left_high = vget_high_u16(left_u16q); - uint16x8_t row; - - row = vdupq_lane_u16(left_low, 0); - h_store_32(&dst, stride, row); - row = vdupq_lane_u16(left_low, 1); - h_store_32(&dst, stride, row); - row = vdupq_lane_u16(left_low, 2); - h_store_32(&dst, stride, row); - row = vdupq_lane_u16(left_low, 3); - h_store_32(&dst, stride, row); - row = vdupq_lane_u16(left_high, 0); - h_store_32(&dst, stride, row); - row = vdupq_lane_u16(left_high, 1); - h_store_32(&dst, stride, row); - row = vdupq_lane_u16(left_high, 2); - h_store_32(&dst, stride, row); - row = vdupq_lane_u16(left_high, 3); - h_store_32(&dst, stride, row); - } -} - -// ----------------------------------------------------------------------------- - -void vpx_highbd_tm_predictor_4x4_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const int16x8_t max = vmovq_n_s16((1 << bd) - 1); - const int16x8_t top_left = vld1q_dup_s16((const int16_t *)(above - 1)); - const int16x4_t above_s16d = vld1_s16((const int16_t *)above); - const int16x8_t above_s16 = vcombine_s16(above_s16d, above_s16d); - const int16x4_t left_s16 = vld1_s16((const int16_t *)left); - const int16x8_t sub = vsubq_s16(above_s16, top_left); - int16x8_t sum; - uint16x8_t row; - - sum = vcombine_s16(vdup_lane_s16(left_s16, 0), vdup_lane_s16(left_s16, 1)); - sum = vaddq_s16(sum, sub); - sum = vminq_s16(sum, max); - row = vqshluq_n_s16(sum, 0); - vst1_u16(dst, vget_low_u16(row)); - dst += stride; - vst1_u16(dst, vget_high_u16(row)); - dst += stride; - - sum = vcombine_s16(vdup_lane_s16(left_s16, 2), vdup_lane_s16(left_s16, 3)); - sum = vaddq_s16(sum, sub); - sum = vminq_s16(sum, max); - row = vqshluq_n_s16(sum, 0); - vst1_u16(dst, vget_low_u16(row)); - dst += stride; - vst1_u16(dst, vget_high_u16(row)); -} - -static INLINE void tm_8_kernel(uint16_t **dst, const ptrdiff_t stride, - const int16x8_t left_dup, const int16x8_t sub, - const int16x8_t max) { - uint16x8_t row; - int16x8_t sum = vaddq_s16(left_dup, sub); - sum = vminq_s16(sum, max); - row = vqshluq_n_s16(sum, 0); - vst1q_u16(*dst, row); - *dst += stride; -} - -void vpx_highbd_tm_predictor_8x8_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const int16x8_t max = vmovq_n_s16((1 << bd) - 1); - const int16x8_t top_left = vld1q_dup_s16((const int16_t *)(above - 1)); - const int16x8_t above_s16 = vld1q_s16((const int16_t *)above); - const int16x8_t left_s16 = vld1q_s16((const int16_t *)left); - const int16x8_t sub = vsubq_s16(above_s16, top_left); - int16x4_t left_s16d; - int16x8_t left_dup; - int i; - - left_s16d = vget_low_s16(left_s16); - - for (i = 0; i < 2; i++, left_s16d = vget_high_s16(left_s16)) { - left_dup = vdupq_lane_s16(left_s16d, 0); - tm_8_kernel(&dst, stride, left_dup, sub, max); - - left_dup = vdupq_lane_s16(left_s16d, 1); - tm_8_kernel(&dst, stride, left_dup, sub, max); - - left_dup = vdupq_lane_s16(left_s16d, 2); - tm_8_kernel(&dst, stride, left_dup, sub, max); - - left_dup = vdupq_lane_s16(left_s16d, 3); - tm_8_kernel(&dst, stride, left_dup, sub, max); - } -} - -static INLINE void tm_16_kernel(uint16_t **dst, const ptrdiff_t stride, - const int16x8_t left_dup, const int16x8_t sub0, - const int16x8_t sub1, const int16x8_t max) { - uint16x8_t row0, row1; - int16x8_t sum0 = vaddq_s16(left_dup, sub0); - int16x8_t sum1 = vaddq_s16(left_dup, sub1); - sum0 = vminq_s16(sum0, max); - sum1 = vminq_s16(sum1, max); - row0 = vqshluq_n_s16(sum0, 0); - row1 = vqshluq_n_s16(sum1, 0); - vst1q_u16(*dst, row0); - *dst += 8; - vst1q_u16(*dst, row1); - *dst += stride - 8; -} - -void vpx_highbd_tm_predictor_16x16_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const int16x8_t max = vmovq_n_s16((1 << bd) - 1); - const int16x8_t top_left = vld1q_dup_s16((const int16_t *)(above - 1)); - const int16x8_t above0 = vld1q_s16((const int16_t *)above); - const int16x8_t above1 = vld1q_s16((const int16_t *)(above + 8)); - const int16x8_t sub0 = vsubq_s16(above0, top_left); - const int16x8_t sub1 = vsubq_s16(above1, top_left); - int16x8_t left_dup; - int i, j; - - for (j = 0; j < 2; j++, left += 8) { - const int16x8_t left_s16q = vld1q_s16((const int16_t *)left); - int16x4_t left_s16d = vget_low_s16(left_s16q); - for (i = 0; i < 2; i++, left_s16d = vget_high_s16(left_s16q)) { - left_dup = vdupq_lane_s16(left_s16d, 0); - tm_16_kernel(&dst, stride, left_dup, sub0, sub1, max); - - left_dup = vdupq_lane_s16(left_s16d, 1); - tm_16_kernel(&dst, stride, left_dup, sub0, sub1, max); - - left_dup = vdupq_lane_s16(left_s16d, 2); - tm_16_kernel(&dst, stride, left_dup, sub0, sub1, max); - - left_dup = vdupq_lane_s16(left_s16d, 3); - tm_16_kernel(&dst, stride, left_dup, sub0, sub1, max); - } - } -} - -static INLINE void tm_32_kernel(uint16_t **dst, const ptrdiff_t stride, - const int16x8_t left_dup, const int16x8_t sub0, - const int16x8_t sub1, const int16x8_t sub2, - const int16x8_t sub3, const int16x8_t max) { - uint16x8_t row0, row1, row2, row3; - int16x8_t sum0 = vaddq_s16(left_dup, sub0); - int16x8_t sum1 = vaddq_s16(left_dup, sub1); - int16x8_t sum2 = vaddq_s16(left_dup, sub2); - int16x8_t sum3 = vaddq_s16(left_dup, sub3); - sum0 = vminq_s16(sum0, max); - sum1 = vminq_s16(sum1, max); - sum2 = vminq_s16(sum2, max); - sum3 = vminq_s16(sum3, max); - row0 = vqshluq_n_s16(sum0, 0); - row1 = vqshluq_n_s16(sum1, 0); - row2 = vqshluq_n_s16(sum2, 0); - row3 = vqshluq_n_s16(sum3, 0); - vst1q_u16(*dst, row0); - *dst += 8; - vst1q_u16(*dst, row1); - *dst += 8; - vst1q_u16(*dst, row2); - *dst += 8; - vst1q_u16(*dst, row3); - *dst += stride - 24; -} - -void vpx_highbd_tm_predictor_32x32_neon(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const int16x8_t max = vmovq_n_s16((1 << bd) - 1); - const int16x8_t top_left = vld1q_dup_s16((const int16_t *)(above - 1)); - const int16x8_t above0 = vld1q_s16((const int16_t *)above); - const int16x8_t above1 = vld1q_s16((const int16_t *)(above + 8)); - const int16x8_t above2 = vld1q_s16((const int16_t *)(above + 16)); - const int16x8_t above3 = vld1q_s16((const int16_t *)(above + 24)); - const int16x8_t sub0 = vsubq_s16(above0, top_left); - const int16x8_t sub1 = vsubq_s16(above1, top_left); - const int16x8_t sub2 = vsubq_s16(above2, top_left); - const int16x8_t sub3 = vsubq_s16(above3, top_left); - int16x8_t left_dup; - int i, j; - - for (i = 0; i < 4; i++, left += 8) { - const int16x8_t left_s16q = vld1q_s16((const int16_t *)left); - int16x4_t left_s16d = vget_low_s16(left_s16q); - for (j = 0; j < 2; j++, left_s16d = vget_high_s16(left_s16q)) { - left_dup = vdupq_lane_s16(left_s16d, 0); - tm_32_kernel(&dst, stride, left_dup, sub0, sub1, sub2, sub3, max); - - left_dup = vdupq_lane_s16(left_s16d, 1); - tm_32_kernel(&dst, stride, left_dup, sub0, sub1, sub2, sub3, max); - - left_dup = vdupq_lane_s16(left_s16d, 2); - tm_32_kernel(&dst, stride, left_dup, sub0, sub1, sub2, sub3, max); - - left_dup = vdupq_lane_s16(left_s16d, 3); - tm_32_kernel(&dst, stride, left_dup, sub0, sub1, sub2, sub3, max); - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_loopfilter_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_loopfilter_neon.c deleted file mode 100644 index 8d6e8acc..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_loopfilter_neon.c +++ /dev/null @@ -1,776 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/transpose_neon.h" - -static INLINE void load_thresh(const uint8_t *blimit, const uint8_t *limit, - const uint8_t *thresh, uint16x8_t *blimit_vec, - uint16x8_t *limit_vec, uint16x8_t *thresh_vec, - const int bd) { - const int16x8_t shift = vdupq_n_s16(bd - 8); - *blimit_vec = vmovl_u8(vld1_dup_u8(blimit)); - *limit_vec = vmovl_u8(vld1_dup_u8(limit)); - *thresh_vec = vmovl_u8(vld1_dup_u8(thresh)); - *blimit_vec = vshlq_u16(*blimit_vec, shift); - *limit_vec = vshlq_u16(*limit_vec, shift); - *thresh_vec = vshlq_u16(*thresh_vec, shift); -} - -// Here flat is 128-bit long, with each 16-bit chunk being a mask of -// a pixel. When used to control filter branches, we only detect whether it is -// all 0s or all 1s. We pairwise add flat to a 32-bit long number flat_status. -// flat equals 0 if and only if flat_status equals 0. -// flat equals -1 (all 1s) if and only if flat_status equals -4. (This is true -// because each mask occupies more than 1 bit.) -static INLINE uint32_t calc_flat_status(const uint16x8_t flat) { - const uint64x1_t t0 = vadd_u64(vreinterpret_u64_u16(vget_low_u16(flat)), - vreinterpret_u64_u16(vget_high_u16(flat))); - const uint64x1_t t1 = vpaddl_u32(vreinterpret_u32_u64(t0)); - return vget_lane_u32(vreinterpret_u32_u64(t1), 0); -} - -static INLINE uint16x8_t -filter_hev_mask4(const uint16x8_t limit, const uint16x8_t blimit, - const uint16x8_t thresh, const uint16x8_t p3, - const uint16x8_t p2, const uint16x8_t p1, const uint16x8_t p0, - const uint16x8_t q0, const uint16x8_t q1, const uint16x8_t q2, - const uint16x8_t q3, uint16x8_t *hev, uint16x8_t *mask) { - uint16x8_t max, t0, t1; - - max = vabdq_u16(p1, p0); - max = vmaxq_u16(max, vabdq_u16(q1, q0)); - *hev = vcgtq_u16(max, thresh); - *mask = vmaxq_u16(max, vabdq_u16(p3, p2)); - *mask = vmaxq_u16(*mask, vabdq_u16(p2, p1)); - *mask = vmaxq_u16(*mask, vabdq_u16(q2, q1)); - *mask = vmaxq_u16(*mask, vabdq_u16(q3, q2)); - t0 = vabdq_u16(p0, q0); - t1 = vabdq_u16(p1, q1); - t0 = vaddq_u16(t0, t0); - t1 = vshrq_n_u16(t1, 1); - t0 = vaddq_u16(t0, t1); - *mask = vcleq_u16(*mask, limit); - t0 = vcleq_u16(t0, blimit); - *mask = vandq_u16(*mask, t0); - - return max; -} - -static INLINE uint16x8_t filter_flat_hev_mask( - const uint16x8_t limit, const uint16x8_t blimit, const uint16x8_t thresh, - const uint16x8_t p3, const uint16x8_t p2, const uint16x8_t p1, - const uint16x8_t p0, const uint16x8_t q0, const uint16x8_t q1, - const uint16x8_t q2, const uint16x8_t q3, uint16x8_t *flat, - uint32_t *flat_status, uint16x8_t *hev, const int bd) { - uint16x8_t mask; - const uint16x8_t max = filter_hev_mask4(limit, blimit, thresh, p3, p2, p1, p0, - q0, q1, q2, q3, hev, &mask); - *flat = vmaxq_u16(max, vabdq_u16(p2, p0)); - *flat = vmaxq_u16(*flat, vabdq_u16(q2, q0)); - *flat = vmaxq_u16(*flat, vabdq_u16(p3, p0)); - *flat = vmaxq_u16(*flat, vabdq_u16(q3, q0)); - *flat = vcleq_u16(*flat, vdupq_n_u16(1 << (bd - 8))); /* flat_mask4() */ - *flat = vandq_u16(*flat, mask); - *flat_status = calc_flat_status(*flat); - - return mask; -} - -static INLINE uint16x8_t flat_mask5(const uint16x8_t p4, const uint16x8_t p3, - const uint16x8_t p2, const uint16x8_t p1, - const uint16x8_t p0, const uint16x8_t q0, - const uint16x8_t q1, const uint16x8_t q2, - const uint16x8_t q3, const uint16x8_t q4, - const uint16x8_t flat, - uint32_t *flat2_status, const int bd) { - uint16x8_t flat2 = vabdq_u16(p4, p0); - flat2 = vmaxq_u16(flat2, vabdq_u16(p3, p0)); - flat2 = vmaxq_u16(flat2, vabdq_u16(p2, p0)); - flat2 = vmaxq_u16(flat2, vabdq_u16(p1, p0)); - flat2 = vmaxq_u16(flat2, vabdq_u16(q1, q0)); - flat2 = vmaxq_u16(flat2, vabdq_u16(q2, q0)); - flat2 = vmaxq_u16(flat2, vabdq_u16(q3, q0)); - flat2 = vmaxq_u16(flat2, vabdq_u16(q4, q0)); - flat2 = vcleq_u16(flat2, vdupq_n_u16(1 << (bd - 8))); - flat2 = vandq_u16(flat2, flat); - *flat2_status = calc_flat_status(flat2); - - return flat2; -} - -static INLINE int16x8_t flip_sign(const uint16x8_t v, const int bd) { - const uint16x8_t offset = vdupq_n_u16(0x80 << (bd - 8)); - return vreinterpretq_s16_u16(vsubq_u16(v, offset)); -} - -static INLINE uint16x8_t flip_sign_back(const int16x8_t v, const int bd) { - const int16x8_t offset = vdupq_n_s16(0x80 << (bd - 8)); - return vreinterpretq_u16_s16(vaddq_s16(v, offset)); -} - -static INLINE void filter_update(const uint16x8_t sub0, const uint16x8_t sub1, - const uint16x8_t add0, const uint16x8_t add1, - uint16x8_t *sum) { - *sum = vsubq_u16(*sum, sub0); - *sum = vsubq_u16(*sum, sub1); - *sum = vaddq_u16(*sum, add0); - *sum = vaddq_u16(*sum, add1); -} - -static INLINE uint16x8_t calc_7_tap_filter_kernel(const uint16x8_t sub0, - const uint16x8_t sub1, - const uint16x8_t add0, - const uint16x8_t add1, - uint16x8_t *sum) { - filter_update(sub0, sub1, add0, add1, sum); - return vrshrq_n_u16(*sum, 3); -} - -static INLINE uint16x8_t apply_15_tap_filter_kernel( - const uint16x8_t flat, const uint16x8_t sub0, const uint16x8_t sub1, - const uint16x8_t add0, const uint16x8_t add1, const uint16x8_t in, - uint16x8_t *sum) { - filter_update(sub0, sub1, add0, add1, sum); - return vbslq_u16(flat, vrshrq_n_u16(*sum, 4), in); -} - -// 7-tap filter [1, 1, 1, 2, 1, 1, 1] -static INLINE void calc_7_tap_filter(const uint16x8_t p3, const uint16x8_t p2, - const uint16x8_t p1, const uint16x8_t p0, - const uint16x8_t q0, const uint16x8_t q1, - const uint16x8_t q2, const uint16x8_t q3, - uint16x8_t *op2, uint16x8_t *op1, - uint16x8_t *op0, uint16x8_t *oq0, - uint16x8_t *oq1, uint16x8_t *oq2) { - uint16x8_t sum; - sum = vaddq_u16(p3, p3); // 2*p3 - sum = vaddq_u16(sum, p3); // 3*p3 - sum = vaddq_u16(sum, p2); // 3*p3+p2 - sum = vaddq_u16(sum, p2); // 3*p3+2*p2 - sum = vaddq_u16(sum, p1); // 3*p3+2*p2+p1 - sum = vaddq_u16(sum, p0); // 3*p3+2*p2+p1+p0 - sum = vaddq_u16(sum, q0); // 3*p3+2*p2+p1+p0+q0 - *op2 = vrshrq_n_u16(sum, 3); - *op1 = calc_7_tap_filter_kernel(p3, p2, p1, q1, &sum); - *op0 = calc_7_tap_filter_kernel(p3, p1, p0, q2, &sum); - *oq0 = calc_7_tap_filter_kernel(p3, p0, q0, q3, &sum); - *oq1 = calc_7_tap_filter_kernel(p2, q0, q1, q3, &sum); - *oq2 = calc_7_tap_filter_kernel(p1, q1, q2, q3, &sum); -} - -static INLINE void apply_7_tap_filter(const uint16x8_t flat, - const uint16x8_t p3, const uint16x8_t p2, - const uint16x8_t p1, const uint16x8_t p0, - const uint16x8_t q0, const uint16x8_t q1, - const uint16x8_t q2, const uint16x8_t q3, - uint16x8_t *op2, uint16x8_t *op1, - uint16x8_t *op0, uint16x8_t *oq0, - uint16x8_t *oq1, uint16x8_t *oq2) { - uint16x8_t tp1, tp0, tq0, tq1; - calc_7_tap_filter(p3, p2, p1, p0, q0, q1, q2, q3, op2, &tp1, &tp0, &tq0, &tq1, - oq2); - *op2 = vbslq_u16(flat, *op2, p2); - *op1 = vbslq_u16(flat, tp1, *op1); - *op0 = vbslq_u16(flat, tp0, *op0); - *oq0 = vbslq_u16(flat, tq0, *oq0); - *oq1 = vbslq_u16(flat, tq1, *oq1); - *oq2 = vbslq_u16(flat, *oq2, q2); -} - -// 15-tap filter [1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1] -static INLINE void apply_15_tap_filter( - const uint16x8_t flat2, const uint16x8_t p7, const uint16x8_t p6, - const uint16x8_t p5, const uint16x8_t p4, const uint16x8_t p3, - const uint16x8_t p2, const uint16x8_t p1, const uint16x8_t p0, - const uint16x8_t q0, const uint16x8_t q1, const uint16x8_t q2, - const uint16x8_t q3, const uint16x8_t q4, const uint16x8_t q5, - const uint16x8_t q6, const uint16x8_t q7, uint16x8_t *op6, uint16x8_t *op5, - uint16x8_t *op4, uint16x8_t *op3, uint16x8_t *op2, uint16x8_t *op1, - uint16x8_t *op0, uint16x8_t *oq0, uint16x8_t *oq1, uint16x8_t *oq2, - uint16x8_t *oq3, uint16x8_t *oq4, uint16x8_t *oq5, uint16x8_t *oq6) { - uint16x8_t sum; - sum = vshlq_n_u16(p7, 3); // 8*p7 - sum = vsubq_u16(sum, p7); // 7*p7 - sum = vaddq_u16(sum, p6); // 7*p7+p6 - sum = vaddq_u16(sum, p6); // 7*p7+2*p6 - sum = vaddq_u16(sum, p5); // 7*p7+2*p6+p5 - sum = vaddq_u16(sum, p4); // 7*p7+2*p6+p5+p4 - sum = vaddq_u16(sum, p3); // 7*p7+2*p6+p5+p4+p3 - sum = vaddq_u16(sum, p2); // 7*p7+2*p6+p5+p4+p3+p2 - sum = vaddq_u16(sum, p1); // 7*p7+2*p6+p5+p4+p3+p2+p1 - sum = vaddq_u16(sum, p0); // 7*p7+2*p6+p5+p4+p3+p2+p1+p0 - sum = vaddq_u16(sum, q0); // 7*p7+2*p6+p5+p4+p3+p2+p1+p0+q0 - *op6 = vbslq_u16(flat2, vrshrq_n_u16(sum, 4), p6); - *op5 = apply_15_tap_filter_kernel(flat2, p7, p6, p5, q1, p5, &sum); - *op4 = apply_15_tap_filter_kernel(flat2, p7, p5, p4, q2, p4, &sum); - *op3 = apply_15_tap_filter_kernel(flat2, p7, p4, p3, q3, p3, &sum); - *op2 = apply_15_tap_filter_kernel(flat2, p7, p3, p2, q4, *op2, &sum); - *op1 = apply_15_tap_filter_kernel(flat2, p7, p2, p1, q5, *op1, &sum); - *op0 = apply_15_tap_filter_kernel(flat2, p7, p1, p0, q6, *op0, &sum); - *oq0 = apply_15_tap_filter_kernel(flat2, p7, p0, q0, q7, *oq0, &sum); - *oq1 = apply_15_tap_filter_kernel(flat2, p6, q0, q1, q7, *oq1, &sum); - *oq2 = apply_15_tap_filter_kernel(flat2, p5, q1, q2, q7, *oq2, &sum); - *oq3 = apply_15_tap_filter_kernel(flat2, p4, q2, q3, q7, q3, &sum); - *oq4 = apply_15_tap_filter_kernel(flat2, p3, q3, q4, q7, q4, &sum); - *oq5 = apply_15_tap_filter_kernel(flat2, p2, q4, q5, q7, q5, &sum); - *oq6 = apply_15_tap_filter_kernel(flat2, p1, q5, q6, q7, q6, &sum); -} - -static INLINE void filter4(const uint16x8_t mask, const uint16x8_t hev, - const uint16x8_t p1, const uint16x8_t p0, - const uint16x8_t q0, const uint16x8_t q1, - uint16x8_t *op1, uint16x8_t *op0, uint16x8_t *oq0, - uint16x8_t *oq1, const int bd) { - const int16x8_t max = vdupq_n_s16((1 << (bd - 1)) - 1); - const int16x8_t min = vdupq_n_s16((int16_t)(((uint32_t)-1) << (bd - 1))); - int16x8_t filter, filter1, filter2, t; - int16x8_t ps1 = flip_sign(p1, bd); - int16x8_t ps0 = flip_sign(p0, bd); - int16x8_t qs0 = flip_sign(q0, bd); - int16x8_t qs1 = flip_sign(q1, bd); - - /* add outer taps if we have high edge variance */ - filter = vsubq_s16(ps1, qs1); - filter = vmaxq_s16(filter, min); - filter = vminq_s16(filter, max); - filter = vandq_s16(filter, vreinterpretq_s16_u16(hev)); - t = vsubq_s16(qs0, ps0); - - /* inner taps */ - filter = vaddq_s16(filter, t); - filter = vaddq_s16(filter, t); - filter = vaddq_s16(filter, t); - filter = vmaxq_s16(filter, min); - filter = vminq_s16(filter, max); - filter = vandq_s16(filter, vreinterpretq_s16_u16(mask)); - - /* save bottom 3 bits so that we round one side +4 and the other +3 */ - /* if it equals 4 we'll set it to adjust by -1 to account for the fact */ - /* we'd round it by 3 the other way */ - t = vaddq_s16(filter, vdupq_n_s16(4)); - t = vminq_s16(t, max); - filter1 = vshrq_n_s16(t, 3); - t = vaddq_s16(filter, vdupq_n_s16(3)); - t = vminq_s16(t, max); - filter2 = vshrq_n_s16(t, 3); - - qs0 = vsubq_s16(qs0, filter1); - qs0 = vmaxq_s16(qs0, min); - qs0 = vminq_s16(qs0, max); - ps0 = vaddq_s16(ps0, filter2); - ps0 = vmaxq_s16(ps0, min); - ps0 = vminq_s16(ps0, max); - *oq0 = flip_sign_back(qs0, bd); - *op0 = flip_sign_back(ps0, bd); - - /* outer tap adjustments */ - filter = vrshrq_n_s16(filter1, 1); - filter = vbicq_s16(filter, vreinterpretq_s16_u16(hev)); - - qs1 = vsubq_s16(qs1, filter); - qs1 = vmaxq_s16(qs1, min); - qs1 = vminq_s16(qs1, max); - ps1 = vaddq_s16(ps1, filter); - ps1 = vmaxq_s16(ps1, min); - ps1 = vminq_s16(ps1, max); - *oq1 = flip_sign_back(qs1, bd); - *op1 = flip_sign_back(ps1, bd); -} - -static INLINE void filter8(const uint16x8_t mask, const uint16x8_t flat, - const uint32_t flat_status, const uint16x8_t hev, - const uint16x8_t p3, const uint16x8_t p2, - const uint16x8_t p1, const uint16x8_t p0, - const uint16x8_t q0, const uint16x8_t q1, - const uint16x8_t q2, const uint16x8_t q3, - uint16x8_t *op2, uint16x8_t *op1, uint16x8_t *op0, - uint16x8_t *oq0, uint16x8_t *oq1, uint16x8_t *oq2, - const int bd) { - if (flat_status != (uint32_t)-4) { - filter4(mask, hev, p1, p0, q0, q1, op1, op0, oq0, oq1, bd); - *op2 = p2; - *oq2 = q2; - if (flat_status) { - apply_7_tap_filter(flat, p3, p2, p1, p0, q0, q1, q2, q3, op2, op1, op0, - oq0, oq1, oq2); - } - } else { - calc_7_tap_filter(p3, p2, p1, p0, q0, q1, q2, q3, op2, op1, op0, oq0, oq1, - oq2); - } -} - -static INLINE void filter16( - const uint16x8_t mask, const uint16x8_t flat, const uint32_t flat_status, - const uint16x8_t flat2, const uint32_t flat2_status, const uint16x8_t hev, - const uint16x8_t p7, const uint16x8_t p6, const uint16x8_t p5, - const uint16x8_t p4, const uint16x8_t p3, const uint16x8_t p2, - const uint16x8_t p1, const uint16x8_t p0, const uint16x8_t q0, - const uint16x8_t q1, const uint16x8_t q2, const uint16x8_t q3, - const uint16x8_t q4, const uint16x8_t q5, const uint16x8_t q6, - const uint16x8_t q7, uint16x8_t *op6, uint16x8_t *op5, uint16x8_t *op4, - uint16x8_t *op3, uint16x8_t *op2, uint16x8_t *op1, uint16x8_t *op0, - uint16x8_t *oq0, uint16x8_t *oq1, uint16x8_t *oq2, uint16x8_t *oq3, - uint16x8_t *oq4, uint16x8_t *oq5, uint16x8_t *oq6, const int bd) { - if (flat_status != (uint32_t)-4) { - filter4(mask, hev, p1, p0, q0, q1, op1, op0, oq0, oq1, bd); - } - - if (flat_status) { - *op2 = p2; - *oq2 = q2; - if (flat2_status != (uint32_t)-4) { - apply_7_tap_filter(flat, p3, p2, p1, p0, q0, q1, q2, q3, op2, op1, op0, - oq0, oq1, oq2); - } - if (flat2_status) { - apply_15_tap_filter(flat2, p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, - q4, q5, q6, q7, op6, op5, op4, op3, op2, op1, op0, - oq0, oq1, oq2, oq3, oq4, oq5, oq6); - } - } -} - -static INLINE void load_8x8(const uint16_t *s, const int p, uint16x8_t *p3, - uint16x8_t *p2, uint16x8_t *p1, uint16x8_t *p0, - uint16x8_t *q0, uint16x8_t *q1, uint16x8_t *q2, - uint16x8_t *q3) { - *p3 = vld1q_u16(s); - s += p; - *p2 = vld1q_u16(s); - s += p; - *p1 = vld1q_u16(s); - s += p; - *p0 = vld1q_u16(s); - s += p; - *q0 = vld1q_u16(s); - s += p; - *q1 = vld1q_u16(s); - s += p; - *q2 = vld1q_u16(s); - s += p; - *q3 = vld1q_u16(s); -} - -static INLINE void load_8x16(const uint16_t *s, const int p, uint16x8_t *s0, - uint16x8_t *s1, uint16x8_t *s2, uint16x8_t *s3, - uint16x8_t *s4, uint16x8_t *s5, uint16x8_t *s6, - uint16x8_t *s7, uint16x8_t *s8, uint16x8_t *s9, - uint16x8_t *s10, uint16x8_t *s11, uint16x8_t *s12, - uint16x8_t *s13, uint16x8_t *s14, - uint16x8_t *s15) { - *s0 = vld1q_u16(s); - s += p; - *s1 = vld1q_u16(s); - s += p; - *s2 = vld1q_u16(s); - s += p; - *s3 = vld1q_u16(s); - s += p; - *s4 = vld1q_u16(s); - s += p; - *s5 = vld1q_u16(s); - s += p; - *s6 = vld1q_u16(s); - s += p; - *s7 = vld1q_u16(s); - s += p; - *s8 = vld1q_u16(s); - s += p; - *s9 = vld1q_u16(s); - s += p; - *s10 = vld1q_u16(s); - s += p; - *s11 = vld1q_u16(s); - s += p; - *s12 = vld1q_u16(s); - s += p; - *s13 = vld1q_u16(s); - s += p; - *s14 = vld1q_u16(s); - s += p; - *s15 = vld1q_u16(s); -} - -static INLINE void store_8x4(uint16_t *s, const int p, const uint16x8_t s0, - const uint16x8_t s1, const uint16x8_t s2, - const uint16x8_t s3) { - vst1q_u16(s, s0); - s += p; - vst1q_u16(s, s1); - s += p; - vst1q_u16(s, s2); - s += p; - vst1q_u16(s, s3); -} - -static INLINE void store_8x6(uint16_t *s, const int p, const uint16x8_t s0, - const uint16x8_t s1, const uint16x8_t s2, - const uint16x8_t s3, const uint16x8_t s4, - const uint16x8_t s5) { - vst1q_u16(s, s0); - s += p; - vst1q_u16(s, s1); - s += p; - vst1q_u16(s, s2); - s += p; - vst1q_u16(s, s3); - s += p; - vst1q_u16(s, s4); - s += p; - vst1q_u16(s, s5); -} - -static INLINE void store_4x8(uint16_t *s, const int p, const uint16x8_t p1, - const uint16x8_t p0, const uint16x8_t q0, - const uint16x8_t q1) { - uint16x8x4_t o; - - o.val[0] = p1; - o.val[1] = p0; - o.val[2] = q0; - o.val[3] = q1; - vst4q_lane_u16(s, o, 0); - s += p; - vst4q_lane_u16(s, o, 1); - s += p; - vst4q_lane_u16(s, o, 2); - s += p; - vst4q_lane_u16(s, o, 3); - s += p; - vst4q_lane_u16(s, o, 4); - s += p; - vst4q_lane_u16(s, o, 5); - s += p; - vst4q_lane_u16(s, o, 6); - s += p; - vst4q_lane_u16(s, o, 7); -} - -static INLINE void store_6x8(uint16_t *s, const int p, const uint16x8_t s0, - const uint16x8_t s1, const uint16x8_t s2, - const uint16x8_t s3, const uint16x8_t s4, - const uint16x8_t s5) { - uint16x8x3_t o0, o1; - - o0.val[0] = s0; - o0.val[1] = s1; - o0.val[2] = s2; - o1.val[0] = s3; - o1.val[1] = s4; - o1.val[2] = s5; - vst3q_lane_u16(s - 3, o0, 0); - vst3q_lane_u16(s + 0, o1, 0); - s += p; - vst3q_lane_u16(s - 3, o0, 1); - vst3q_lane_u16(s + 0, o1, 1); - s += p; - vst3q_lane_u16(s - 3, o0, 2); - vst3q_lane_u16(s + 0, o1, 2); - s += p; - vst3q_lane_u16(s - 3, o0, 3); - vst3q_lane_u16(s + 0, o1, 3); - s += p; - vst3q_lane_u16(s - 3, o0, 4); - vst3q_lane_u16(s + 0, o1, 4); - s += p; - vst3q_lane_u16(s - 3, o0, 5); - vst3q_lane_u16(s + 0, o1, 5); - s += p; - vst3q_lane_u16(s - 3, o0, 6); - vst3q_lane_u16(s + 0, o1, 6); - s += p; - vst3q_lane_u16(s - 3, o0, 7); - vst3q_lane_u16(s + 0, o1, 7); -} - -static INLINE void store_7x8(uint16_t *s, const int p, const uint16x8_t s0, - const uint16x8_t s1, const uint16x8_t s2, - const uint16x8_t s3, const uint16x8_t s4, - const uint16x8_t s5, const uint16x8_t s6) { - uint16x8x4_t o0; - uint16x8x3_t o1; - - o0.val[0] = s0; - o0.val[1] = s1; - o0.val[2] = s2; - o0.val[3] = s3; - o1.val[0] = s4; - o1.val[1] = s5; - o1.val[2] = s6; - vst4q_lane_u16(s - 4, o0, 0); - vst3q_lane_u16(s + 0, o1, 0); - s += p; - vst4q_lane_u16(s - 4, o0, 1); - vst3q_lane_u16(s + 0, o1, 1); - s += p; - vst4q_lane_u16(s - 4, o0, 2); - vst3q_lane_u16(s + 0, o1, 2); - s += p; - vst4q_lane_u16(s - 4, o0, 3); - vst3q_lane_u16(s + 0, o1, 3); - s += p; - vst4q_lane_u16(s - 4, o0, 4); - vst3q_lane_u16(s + 0, o1, 4); - s += p; - vst4q_lane_u16(s - 4, o0, 5); - vst3q_lane_u16(s + 0, o1, 5); - s += p; - vst4q_lane_u16(s - 4, o0, 6); - vst3q_lane_u16(s + 0, o1, 6); - s += p; - vst4q_lane_u16(s - 4, o0, 7); - vst3q_lane_u16(s + 0, o1, 7); -} - -static INLINE void store_8x14(uint16_t *s, const int p, const uint16x8_t p6, - const uint16x8_t p5, const uint16x8_t p4, - const uint16x8_t p3, const uint16x8_t p2, - const uint16x8_t p1, const uint16x8_t p0, - const uint16x8_t q0, const uint16x8_t q1, - const uint16x8_t q2, const uint16x8_t q3, - const uint16x8_t q4, const uint16x8_t q5, - const uint16x8_t q6, const uint32_t flat_status, - const uint32_t flat2_status) { - if (flat_status) { - if (flat2_status) { - vst1q_u16(s - 7 * p, p6); - vst1q_u16(s - 6 * p, p5); - vst1q_u16(s - 5 * p, p4); - vst1q_u16(s - 4 * p, p3); - vst1q_u16(s + 3 * p, q3); - vst1q_u16(s + 4 * p, q4); - vst1q_u16(s + 5 * p, q5); - vst1q_u16(s + 6 * p, q6); - } - vst1q_u16(s - 3 * p, p2); - vst1q_u16(s + 2 * p, q2); - } - vst1q_u16(s - 2 * p, p1); - vst1q_u16(s - 1 * p, p0); - vst1q_u16(s + 0 * p, q0); - vst1q_u16(s + 1 * p, q1); -} - -void vpx_highbd_lpf_horizontal_4_neon(uint16_t *s, int p, const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh, int bd) { - uint16x8_t blimit_vec, limit_vec, thresh_vec, p3, p2, p1, p0, q0, q1, q2, q3, - mask, hev; - - load_thresh(blimit, limit, thresh, &blimit_vec, &limit_vec, &thresh_vec, bd); - load_8x8(s - 4 * p, p, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3); - filter_hev_mask4(limit_vec, blimit_vec, thresh_vec, p3, p2, p1, p0, q0, q1, - q2, q3, &hev, &mask); - filter4(mask, hev, p1, p0, q0, q1, &p1, &p0, &q0, &q1, bd); - store_8x4(s - 2 * p, p, p1, p0, q0, q1); -} - -void vpx_highbd_lpf_horizontal_4_dual_neon( - uint16_t *s, int p, const uint8_t *blimit0, const uint8_t *limit0, - const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1, int bd) { - vpx_highbd_lpf_horizontal_4_neon(s, p, blimit0, limit0, thresh0, bd); - vpx_highbd_lpf_horizontal_4_neon(s + 8, p, blimit1, limit1, thresh1, bd); -} - -void vpx_highbd_lpf_vertical_4_neon(uint16_t *s, int p, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh, - int bd) { - uint16x8_t blimit_vec, limit_vec, thresh_vec, p3, p2, p1, p0, q0, q1, q2, q3, - mask, hev; - - load_8x8(s - 4, p, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3); - transpose_s16_8x8((int16x8_t *)&p3, (int16x8_t *)&p2, (int16x8_t *)&p1, - (int16x8_t *)&p0, (int16x8_t *)&q0, (int16x8_t *)&q1, - (int16x8_t *)&q2, (int16x8_t *)&q3); - load_thresh(blimit, limit, thresh, &blimit_vec, &limit_vec, &thresh_vec, bd); - filter_hev_mask4(limit_vec, blimit_vec, thresh_vec, p3, p2, p1, p0, q0, q1, - q2, q3, &hev, &mask); - filter4(mask, hev, p1, p0, q0, q1, &p1, &p0, &q0, &q1, bd); - store_4x8(s - 2, p, p1, p0, q0, q1); -} - -void vpx_highbd_lpf_vertical_4_dual_neon( - uint16_t *s, int p, const uint8_t *blimit0, const uint8_t *limit0, - const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1, int bd) { - vpx_highbd_lpf_vertical_4_neon(s, p, blimit0, limit0, thresh0, bd); - vpx_highbd_lpf_vertical_4_neon(s + 8 * p, p, blimit1, limit1, thresh1, bd); -} - -void vpx_highbd_lpf_horizontal_8_neon(uint16_t *s, int p, const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh, int bd) { - uint16x8_t blimit_vec, limit_vec, thresh_vec, p3, p2, p1, p0, q0, q1, q2, q3, - op2, op1, op0, oq0, oq1, oq2, mask, flat, hev; - uint32_t flat_status; - - load_thresh(blimit, limit, thresh, &blimit_vec, &limit_vec, &thresh_vec, bd); - load_8x8(s - 4 * p, p, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3); - mask = filter_flat_hev_mask(limit_vec, blimit_vec, thresh_vec, p3, p2, p1, p0, - q0, q1, q2, q3, &flat, &flat_status, &hev, bd); - filter8(mask, flat, flat_status, hev, p3, p2, p1, p0, q0, q1, q2, q3, &op2, - &op1, &op0, &oq0, &oq1, &oq2, bd); - store_8x6(s - 3 * p, p, op2, op1, op0, oq0, oq1, oq2); -} - -void vpx_highbd_lpf_horizontal_8_dual_neon( - uint16_t *s, int p, const uint8_t *blimit0, const uint8_t *limit0, - const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1, int bd) { - vpx_highbd_lpf_horizontal_8_neon(s, p, blimit0, limit0, thresh0, bd); - vpx_highbd_lpf_horizontal_8_neon(s + 8, p, blimit1, limit1, thresh1, bd); -} - -void vpx_highbd_lpf_vertical_8_neon(uint16_t *s, int p, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh, - int bd) { - uint16x8_t blimit_vec, limit_vec, thresh_vec, p3, p2, p1, p0, q0, q1, q2, q3, - op2, op1, op0, oq0, oq1, oq2, mask, flat, hev; - uint32_t flat_status; - - load_8x8(s - 4, p, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3); - transpose_s16_8x8((int16x8_t *)&p3, (int16x8_t *)&p2, (int16x8_t *)&p1, - (int16x8_t *)&p0, (int16x8_t *)&q0, (int16x8_t *)&q1, - (int16x8_t *)&q2, (int16x8_t *)&q3); - load_thresh(blimit, limit, thresh, &blimit_vec, &limit_vec, &thresh_vec, bd); - mask = filter_flat_hev_mask(limit_vec, blimit_vec, thresh_vec, p3, p2, p1, p0, - q0, q1, q2, q3, &flat, &flat_status, &hev, bd); - filter8(mask, flat, flat_status, hev, p3, p2, p1, p0, q0, q1, q2, q3, &op2, - &op1, &op0, &oq0, &oq1, &oq2, bd); - // Note: store_6x8() is faster than transpose + store_8x8(). - store_6x8(s, p, op2, op1, op0, oq0, oq1, oq2); -} - -void vpx_highbd_lpf_vertical_8_dual_neon( - uint16_t *s, int p, const uint8_t *blimit0, const uint8_t *limit0, - const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1, int bd) { - vpx_highbd_lpf_vertical_8_neon(s, p, blimit0, limit0, thresh0, bd); - vpx_highbd_lpf_vertical_8_neon(s + 8 * p, p, blimit1, limit1, thresh1, bd); -} - -// Quiet warnings of the form: 'vpx_dsp/arm/highbd_loopfilter_neon.c|675 col 67| -// warning: 'oq1' may be used uninitialized in this function -// [-Wmaybe-uninitialized]', for oq1-op1. Without reworking the code or adding -// an additional branch this warning cannot be silenced otherwise. The -// loopfilter is only called when needed for a block so these output pixels -// will be set. -#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - -static void lpf_horizontal_16_kernel(uint16_t *s, int p, - const uint16x8_t blimit_vec, - const uint16x8_t limit_vec, - const uint16x8_t thresh_vec, - const int bd) { - uint16x8_t mask, flat, flat2, hev, p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, - q3, q4, q5, q6, q7, op6, op5, op4, op3, op2, op1, op0, oq0, oq1, oq2, oq3, - oq4, oq5, oq6; - uint32_t flat_status, flat2_status; - - load_8x16(s - 8 * p, p, &p7, &p6, &p5, &p4, &p3, &p2, &p1, &p0, &q0, &q1, &q2, - &q3, &q4, &q5, &q6, &q7); - mask = filter_flat_hev_mask(limit_vec, blimit_vec, thresh_vec, p3, p2, p1, p0, - q0, q1, q2, q3, &flat, &flat_status, &hev, bd); - flat2 = flat_mask5(p7, p6, p5, p4, p0, q0, q4, q5, q6, q7, flat, - &flat2_status, bd); - filter16(mask, flat, flat_status, flat2, flat2_status, hev, p7, p6, p5, p4, - p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7, &op6, &op5, &op4, - &op3, &op2, &op1, &op0, &oq0, &oq1, &oq2, &oq3, &oq4, &oq5, &oq6, - bd); - store_8x14(s, p, op6, op5, op4, op3, op2, op1, op0, oq0, oq1, oq2, oq3, oq4, - oq5, oq6, flat_status, flat2_status); -} - -static void lpf_vertical_16_kernel(uint16_t *s, int p, - const uint16x8_t blimit_vec, - const uint16x8_t limit_vec, - const uint16x8_t thresh_vec, const int bd) { - uint16x8_t mask, flat, flat2, hev, p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, - q3, q4, q5, q6, q7, op6, op5, op4, op3, op2, op1, op0, oq0, oq1, oq2, oq3, - oq4, oq5, oq6; - uint32_t flat_status, flat2_status; - - load_8x8(s - 8, p, &p7, &p6, &p5, &p4, &p3, &p2, &p1, &p0); - transpose_s16_8x8((int16x8_t *)&p7, (int16x8_t *)&p6, (int16x8_t *)&p5, - (int16x8_t *)&p4, (int16x8_t *)&p3, (int16x8_t *)&p2, - (int16x8_t *)&p1, (int16x8_t *)&p0); - load_8x8(s, p, &q0, &q1, &q2, &q3, &q4, &q5, &q6, &q7); - transpose_s16_8x8((int16x8_t *)&q0, (int16x8_t *)&q1, (int16x8_t *)&q2, - (int16x8_t *)&q3, (int16x8_t *)&q4, (int16x8_t *)&q5, - (int16x8_t *)&q6, (int16x8_t *)&q7); - mask = filter_flat_hev_mask(limit_vec, blimit_vec, thresh_vec, p3, p2, p1, p0, - q0, q1, q2, q3, &flat, &flat_status, &hev, bd); - flat2 = flat_mask5(p7, p6, p5, p4, p0, q0, q4, q5, q6, q7, flat, - &flat2_status, bd); - filter16(mask, flat, flat_status, flat2, flat2_status, hev, p7, p6, p5, p4, - p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7, &op6, &op5, &op4, - &op3, &op2, &op1, &op0, &oq0, &oq1, &oq2, &oq3, &oq4, &oq5, &oq6, - bd); - if (flat_status) { - if (flat2_status) { - store_7x8(s - 3, p, op6, op5, op4, op3, op2, op1, op0); - store_7x8(s + 4, p, oq0, oq1, oq2, oq3, oq4, oq5, oq6); - } else { - // Note: store_6x8() is faster than transpose + store_8x8(). - store_6x8(s, p, op2, op1, op0, oq0, oq1, oq2); - } - } else { - store_4x8(s - 2, p, op1, op0, oq0, oq1); - } -} - -#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__clang__) -#pragma GCC diagnostic pop -#endif - -void vpx_highbd_lpf_horizontal_16_neon(uint16_t *s, int p, - const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh, int bd) { - uint16x8_t blimit_vec, limit_vec, thresh_vec; - load_thresh(blimit, limit, thresh, &blimit_vec, &limit_vec, &thresh_vec, bd); - lpf_horizontal_16_kernel(s, p, blimit_vec, limit_vec, thresh_vec, bd); -} - -void vpx_highbd_lpf_horizontal_16_dual_neon(uint16_t *s, int p, - const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh, int bd) { - uint16x8_t blimit_vec, limit_vec, thresh_vec; - load_thresh(blimit, limit, thresh, &blimit_vec, &limit_vec, &thresh_vec, bd); - lpf_horizontal_16_kernel(s, p, blimit_vec, limit_vec, thresh_vec, bd); - lpf_horizontal_16_kernel(s + 8, p, blimit_vec, limit_vec, thresh_vec, bd); -} - -void vpx_highbd_lpf_vertical_16_neon(uint16_t *s, int p, const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh, int bd) { - uint16x8_t blimit_vec, limit_vec, thresh_vec; - load_thresh(blimit, limit, thresh, &blimit_vec, &limit_vec, &thresh_vec, bd); - lpf_vertical_16_kernel(s, p, blimit_vec, limit_vec, thresh_vec, bd); -} - -void vpx_highbd_lpf_vertical_16_dual_neon(uint16_t *s, int p, - const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh, int bd) { - uint16x8_t blimit_vec, limit_vec, thresh_vec; - load_thresh(blimit, limit, thresh, &blimit_vec, &limit_vec, &thresh_vec, bd); - lpf_vertical_16_kernel(s, p, blimit_vec, limit_vec, thresh_vec, bd); - lpf_vertical_16_kernel(s + 8 * p, p, blimit_vec, limit_vec, thresh_vec, bd); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_quantize_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_quantize_neon.c deleted file mode 100644 index c2ad34a6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_quantize_neon.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vp9/common/vp9_scan.h" -#include "vp9/encoder/vp9_block.h" - -static VPX_FORCE_INLINE void highbd_calculate_dqcoeff_and_store( - const int32x4_t dqcoeff_0, const int32x4_t dqcoeff_1, - tran_low_t *dqcoeff_ptr) { - vst1q_s32(dqcoeff_ptr, dqcoeff_0); - vst1q_s32(dqcoeff_ptr + 4, dqcoeff_1); -} - -static VPX_FORCE_INLINE void highbd_quantize_8_neon( - const int32x4_t coeff_0, const int32x4_t coeff_1, const int32x4_t zbin, - const int32x4_t round, const int32x4_t quant, const int32x4_t quant_shift, - int32x4_t *qcoeff_0, int32x4_t *qcoeff_1) { - // Load coeffs as 2 vectors of 4 x 32-bit ints each, take sign and abs values - const int32x4_t coeff_0_sign = vshrq_n_s32(coeff_0, 31); - const int32x4_t coeff_1_sign = vshrq_n_s32(coeff_1, 31); - const int32x4_t coeff_0_abs = vabsq_s32(coeff_0); - const int32x4_t coeff_1_abs = vabsq_s32(coeff_1); - - // Calculate 2 masks of elements outside the bin - const int32x4_t zbin_mask_0 = - vreinterpretq_s32_u32(vcgeq_s32(coeff_0_abs, zbin)); - const int32x4_t zbin_mask_1 = vreinterpretq_s32_u32( - vcgeq_s32(coeff_1_abs, vdupq_lane_s32(vget_low_s32(zbin), 1))); - - // Get the rounded values - const int32x4_t rounded_0 = vaddq_s32(coeff_0_abs, round); - const int32x4_t rounded_1 = - vaddq_s32(coeff_1_abs, vdupq_lane_s32(vget_low_s32(round), 1)); - - // (round * (quant << 15) * 2) >> 16 == (round * quant) - int32x4_t qcoeff_tmp_0 = vqdmulhq_s32(rounded_0, quant); - int32x4_t qcoeff_tmp_1 = - vqdmulhq_s32(rounded_1, vdupq_lane_s32(vget_low_s32(quant), 1)); - - // Add rounded values - qcoeff_tmp_0 = vaddq_s32(qcoeff_tmp_0, rounded_0); - qcoeff_tmp_1 = vaddq_s32(qcoeff_tmp_1, rounded_1); - - // (round * (quant_shift << 15) * 2) >> 16 == (round * quant_shift) - qcoeff_tmp_0 = vqdmulhq_s32(qcoeff_tmp_0, quant_shift); - qcoeff_tmp_1 = - vqdmulhq_s32(qcoeff_tmp_1, vdupq_lane_s32(vget_low_s32(quant_shift), 1)); - - // Restore the sign bit. - qcoeff_tmp_0 = veorq_s32(qcoeff_tmp_0, coeff_0_sign); - qcoeff_tmp_1 = veorq_s32(qcoeff_tmp_1, coeff_1_sign); - qcoeff_tmp_0 = vsubq_s32(qcoeff_tmp_0, coeff_0_sign); - qcoeff_tmp_1 = vsubq_s32(qcoeff_tmp_1, coeff_1_sign); - - // Only keep the relevant coeffs - *qcoeff_0 = vandq_s32(qcoeff_tmp_0, zbin_mask_0); - *qcoeff_1 = vandq_s32(qcoeff_tmp_1, zbin_mask_1); -} - -static VPX_FORCE_INLINE int16x8_t -highbd_quantize_b_neon(const tran_low_t *coeff_ptr, tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, const int32x4_t zbin, - const int32x4_t round, const int32x4_t quant, - const int32x4_t quant_shift, const int32x4_t dequant) { - int32x4_t qcoeff_0, qcoeff_1, dqcoeff_0, dqcoeff_1; - - // Load coeffs as 2 vectors of 4 x 32-bit ints each, take sign and abs values - const int32x4_t coeff_0 = vld1q_s32(coeff_ptr); - const int32x4_t coeff_1 = vld1q_s32(coeff_ptr + 4); - highbd_quantize_8_neon(coeff_0, coeff_1, zbin, round, quant, quant_shift, - &qcoeff_0, &qcoeff_1); - - // Store the 32-bit qcoeffs - vst1q_s32(qcoeff_ptr, qcoeff_0); - vst1q_s32(qcoeff_ptr + 4, qcoeff_1); - - // Calculate and store the dqcoeffs - dqcoeff_0 = vmulq_s32(qcoeff_0, dequant); - dqcoeff_1 = vmulq_s32(qcoeff_1, vdupq_lane_s32(vget_low_s32(dequant), 1)); - - highbd_calculate_dqcoeff_and_store(dqcoeff_0, dqcoeff_1, dqcoeff_ptr); - - return vcombine_s16(vmovn_s32(qcoeff_0), vmovn_s32(qcoeff_1)); -} - -void vpx_highbd_quantize_b_neon(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - const int16x8_t neg_one = vdupq_n_s16(-1); - uint16x8_t eob_max; - const int16_t *iscan = scan_order->iscan; - - // Only the first element of each vector is DC. - // High half has identical elements, but we can reconstruct it from the low - // half by duplicating the 2nd element. So we only need to pass a 4x32-bit - // vector - int32x4_t zbin = vmovl_s16(vld1_s16(mb_plane->zbin)); - int32x4_t round = vmovl_s16(vld1_s16(mb_plane->round)); - // Extend the quant, quant_shift vectors to ones of 32-bit elements - // scale to high-half, so we can use vqdmulhq_s32 - int32x4_t quant = vshlq_n_s32(vmovl_s16(vld1_s16(mb_plane->quant)), 15); - int32x4_t quant_shift = - vshlq_n_s32(vmovl_s16(vld1_s16(mb_plane->quant_shift)), 15); - int32x4_t dequant = vmovl_s16(vld1_s16(dequant_ptr)); - - // Process first 8 values which include a dc component. - { - const uint16x8_t v_iscan = vreinterpretq_u16_s16(vld1q_s16(iscan)); - - const int16x8_t qcoeff = - highbd_quantize_b_neon(coeff_ptr, qcoeff_ptr, dqcoeff_ptr, zbin, round, - quant, quant_shift, dequant); - - // Set non-zero elements to -1 and use that to extract values for eob. - eob_max = vandq_u16(vtstq_s16(qcoeff, neg_one), v_iscan); - - __builtin_prefetch(coeff_ptr + 64); - - coeff_ptr += 8; - iscan += 8; - qcoeff_ptr += 8; - dqcoeff_ptr += 8; - } - - n_coeffs -= 8; - - { - zbin = vdupq_lane_s32(vget_low_s32(zbin), 1); - round = vdupq_lane_s32(vget_low_s32(round), 1); - quant = vdupq_lane_s32(vget_low_s32(quant), 1); - quant_shift = vdupq_lane_s32(vget_low_s32(quant_shift), 1); - dequant = vdupq_lane_s32(vget_low_s32(dequant), 1); - - do { - const uint16x8_t v_iscan = vreinterpretq_u16_s16(vld1q_s16(iscan)); - - const int16x8_t qcoeff = - highbd_quantize_b_neon(coeff_ptr, qcoeff_ptr, dqcoeff_ptr, zbin, - round, quant, quant_shift, dequant); - - // Set non-zero elements to -1 and use that to extract values for eob. - eob_max = - vmaxq_u16(eob_max, vandq_u16(vtstq_s16(qcoeff, neg_one), v_iscan)); - - __builtin_prefetch(coeff_ptr + 64); - coeff_ptr += 8; - iscan += 8; - qcoeff_ptr += 8; - dqcoeff_ptr += 8; - n_coeffs -= 8; - } while (n_coeffs > 0); - } - -#if VPX_ARCH_AARCH64 - *eob_ptr = vmaxvq_u16(eob_max); -#else - { - const uint16x4_t eob_max_0 = - vmax_u16(vget_low_u16(eob_max), vget_high_u16(eob_max)); - const uint16x4_t eob_max_1 = vpmax_u16(eob_max_0, eob_max_0); - const uint16x4_t eob_max_2 = vpmax_u16(eob_max_1, eob_max_1); - vst1_lane_u16(eob_ptr, eob_max_2, 0); - } -#endif // VPX_ARCH_AARCH64 -} - -static VPX_FORCE_INLINE int32x4_t extract_sign_bit(int32x4_t a) { - return vreinterpretq_s32_u32(vshrq_n_u32(vreinterpretq_u32_s32(a), 31)); -} - -static VPX_FORCE_INLINE void highbd_calculate_dqcoeff_and_store_32x32( - int32x4_t dqcoeff_0, int32x4_t dqcoeff_1, tran_low_t *dqcoeff_ptr) { - // Add 1 if negative to round towards zero because the C uses division. - dqcoeff_0 = vaddq_s32(dqcoeff_0, extract_sign_bit(dqcoeff_0)); - dqcoeff_1 = vaddq_s32(dqcoeff_1, extract_sign_bit(dqcoeff_1)); - - dqcoeff_0 = vshrq_n_s32(dqcoeff_0, 1); - dqcoeff_1 = vshrq_n_s32(dqcoeff_1, 1); - vst1q_s32(dqcoeff_ptr, dqcoeff_0); - vst1q_s32(dqcoeff_ptr + 4, dqcoeff_1); -} - -static VPX_FORCE_INLINE int16x8_t highbd_quantize_b_32x32_neon( - const tran_low_t *coeff_ptr, tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, const int32x4_t zbin, const int32x4_t round, - const int32x4_t quant, const int32x4_t quant_shift, - const int32x4_t dequant) { - int32x4_t qcoeff_0, qcoeff_1, dqcoeff_0, dqcoeff_1; - - // Load coeffs as 2 vectors of 4 x 32-bit ints each, take sign and abs values - const int32x4_t coeff_0 = vld1q_s32(coeff_ptr); - const int32x4_t coeff_1 = vld1q_s32(coeff_ptr + 4); - highbd_quantize_8_neon(coeff_0, coeff_1, zbin, round, quant, quant_shift, - &qcoeff_0, &qcoeff_1); - - // Store the 32-bit qcoeffs - vst1q_s32(qcoeff_ptr, qcoeff_0); - vst1q_s32(qcoeff_ptr + 4, qcoeff_1); - - // Calculate and store the dqcoeffs - dqcoeff_0 = vmulq_s32(qcoeff_0, dequant); - dqcoeff_1 = vmulq_s32(qcoeff_1, vdupq_lane_s32(vget_low_s32(dequant), 1)); - - highbd_calculate_dqcoeff_and_store_32x32(dqcoeff_0, dqcoeff_1, dqcoeff_ptr); - - return vcombine_s16(vmovn_s32(qcoeff_0), vmovn_s32(qcoeff_1)); -} - -void vpx_highbd_quantize_b_32x32_neon( - const tran_low_t *coeff_ptr, const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, - uint16_t *eob_ptr, const struct ScanOrder *const scan_order) { - const int16x8_t neg_one = vdupq_n_s16(-1); - uint16x8_t eob_max; - int i; - const int16_t *iscan = scan_order->iscan; - - // Only the first element of each vector is DC. - // High half has identical elements, but we can reconstruct it from the low - // half by duplicating the 2nd element. So we only need to pass a 4x32-bit - // vector - int32x4_t zbin = vrshrq_n_s32(vmovl_s16(vld1_s16(mb_plane->zbin)), 1); - int32x4_t round = vrshrq_n_s32(vmovl_s16(vld1_s16(mb_plane->round)), 1); - // Extend the quant, quant_shift vectors to ones of 32-bit elements - // scale to high-half, so we can use vqdmulhq_s32 - int32x4_t quant = vshlq_n_s32(vmovl_s16(vld1_s16(mb_plane->quant)), 15); - int32x4_t quant_shift = - vshlq_n_s32(vmovl_s16(vld1_s16(mb_plane->quant_shift)), 16); - int32x4_t dequant = vmovl_s16(vld1_s16(dequant_ptr)); - - // Process first 8 values which include a dc component. - { - const uint16x8_t v_iscan = vreinterpretq_u16_s16(vld1q_s16(iscan)); - - const int16x8_t qcoeff = - highbd_quantize_b_32x32_neon(coeff_ptr, qcoeff_ptr, dqcoeff_ptr, zbin, - round, quant, quant_shift, dequant); - - // Set non-zero elements to -1 and use that to extract values for eob. - eob_max = vandq_u16(vtstq_s16(qcoeff, neg_one), v_iscan); - - __builtin_prefetch(coeff_ptr + 64); - coeff_ptr += 8; - iscan += 8; - qcoeff_ptr += 8; - dqcoeff_ptr += 8; - } - - { - zbin = vdupq_lane_s32(vget_low_s32(zbin), 1); - round = vdupq_lane_s32(vget_low_s32(round), 1); - quant = vdupq_lane_s32(vget_low_s32(quant), 1); - quant_shift = vdupq_lane_s32(vget_low_s32(quant_shift), 1); - dequant = vdupq_lane_s32(vget_low_s32(dequant), 1); - - for (i = 1; i < 32 * 32 / 8; ++i) { - const uint16x8_t v_iscan = vreinterpretq_u16_s16(vld1q_s16(iscan)); - - const int16x8_t qcoeff = - highbd_quantize_b_32x32_neon(coeff_ptr, qcoeff_ptr, dqcoeff_ptr, zbin, - round, quant, quant_shift, dequant); - - // Set non-zero elements to -1 and use that to extract values for eob. - eob_max = - vmaxq_u16(eob_max, vandq_u16(vtstq_s16(qcoeff, neg_one), v_iscan)); - - __builtin_prefetch(coeff_ptr + 64); - coeff_ptr += 8; - iscan += 8; - qcoeff_ptr += 8; - dqcoeff_ptr += 8; - } - } - -#if VPX_ARCH_AARCH64 - *eob_ptr = vmaxvq_u16(eob_max); -#else - { - const uint16x4_t eob_max_0 = - vmax_u16(vget_low_u16(eob_max), vget_high_u16(eob_max)); - const uint16x4_t eob_max_1 = vpmax_u16(eob_max_0, eob_max_0); - const uint16x4_t eob_max_2 = vpmax_u16(eob_max_1, eob_max_1); - vst1_lane_u16(eob_ptr, eob_max_2, 0); - } -#endif // VPX_ARCH_AARCH64 -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_sad4d_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_sad4d_neon.c deleted file mode 100644 index a6684b05..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_sad4d_neon.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" - -static INLINE void highbd_sad4xhx4d_neon(const uint8_t *src_ptr, int src_stride, - const uint8_t *const ref_ptr[4], - int ref_stride, uint32_t res[4], - int h) { - const uint16_t *src16_ptr = CONVERT_TO_SHORTPTR(src_ptr); - const uint16_t *ref16_ptr0 = CONVERT_TO_SHORTPTR(ref_ptr[0]); - const uint16_t *ref16_ptr1 = CONVERT_TO_SHORTPTR(ref_ptr[1]); - const uint16_t *ref16_ptr2 = CONVERT_TO_SHORTPTR(ref_ptr[2]); - const uint16_t *ref16_ptr3 = CONVERT_TO_SHORTPTR(ref_ptr[3]); - - uint32x4_t sum[4] = { vdupq_n_u32(0), vdupq_n_u32(0), vdupq_n_u32(0), - vdupq_n_u32(0) }; - - int i = 0; - do { - uint16x4_t s = vld1_u16(src16_ptr + i * src_stride); - uint16x4_t r0 = vld1_u16(ref16_ptr0 + i * ref_stride); - uint16x4_t r1 = vld1_u16(ref16_ptr1 + i * ref_stride); - uint16x4_t r2 = vld1_u16(ref16_ptr2 + i * ref_stride); - uint16x4_t r3 = vld1_u16(ref16_ptr3 + i * ref_stride); - - sum[0] = vabal_u16(sum[0], s, r0); - sum[1] = vabal_u16(sum[1], s, r1); - sum[2] = vabal_u16(sum[2], s, r2); - sum[3] = vabal_u16(sum[3], s, r3); - - } while (++i < h); - - vst1q_u32(res, horizontal_add_4d_uint32x4(sum)); -} - -static INLINE void highbd_sad8xhx4d_neon(const uint8_t *src_ptr, int src_stride, - const uint8_t *const ref_ptr[4], - int ref_stride, uint32_t res[4], - int h) { - const uint16_t *src16_ptr = CONVERT_TO_SHORTPTR(src_ptr); - const uint16_t *ref16_ptr0 = CONVERT_TO_SHORTPTR(ref_ptr[0]); - const uint16_t *ref16_ptr1 = CONVERT_TO_SHORTPTR(ref_ptr[1]); - const uint16_t *ref16_ptr2 = CONVERT_TO_SHORTPTR(ref_ptr[2]); - const uint16_t *ref16_ptr3 = CONVERT_TO_SHORTPTR(ref_ptr[3]); - - uint16x8_t sum[4] = { vdupq_n_u16(0), vdupq_n_u16(0), vdupq_n_u16(0), - vdupq_n_u16(0) }; - uint32x4_t sum_u32[4]; - - int i = 0; - do { - uint16x8_t s = vld1q_u16(src16_ptr + i * src_stride); - - sum[0] = vabaq_u16(sum[0], s, vld1q_u16(ref16_ptr0 + i * ref_stride)); - sum[1] = vabaq_u16(sum[1], s, vld1q_u16(ref16_ptr1 + i * ref_stride)); - sum[2] = vabaq_u16(sum[2], s, vld1q_u16(ref16_ptr2 + i * ref_stride)); - sum[3] = vabaq_u16(sum[3], s, vld1q_u16(ref16_ptr3 + i * ref_stride)); - - } while (++i < h); - - sum_u32[0] = vpaddlq_u16(sum[0]); - sum_u32[1] = vpaddlq_u16(sum[1]); - sum_u32[2] = vpaddlq_u16(sum[2]); - sum_u32[3] = vpaddlq_u16(sum[3]); - vst1q_u32(res, horizontal_add_4d_uint32x4(sum_u32)); -} - -static INLINE void sad8_neon(uint16x8_t src, uint16x8_t ref, - uint32x4_t *const sad_sum) { - uint16x8_t abs_diff = vabdq_u16(src, ref); - *sad_sum = vpadalq_u16(*sad_sum, abs_diff); -} - -static INLINE void highbd_sad16xhx4d_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *const ref_ptr[4], - int ref_stride, uint32_t res[4], - int h) { - const uint16_t *src16_ptr = CONVERT_TO_SHORTPTR(src_ptr); - const uint16_t *ref16_ptr0 = CONVERT_TO_SHORTPTR(ref_ptr[0]); - const uint16_t *ref16_ptr1 = CONVERT_TO_SHORTPTR(ref_ptr[1]); - const uint16_t *ref16_ptr2 = CONVERT_TO_SHORTPTR(ref_ptr[2]); - const uint16_t *ref16_ptr3 = CONVERT_TO_SHORTPTR(ref_ptr[3]); - - uint32x4_t sum_lo[4] = { vdupq_n_u32(0), vdupq_n_u32(0), vdupq_n_u32(0), - vdupq_n_u32(0) }; - uint32x4_t sum_hi[4] = { vdupq_n_u32(0), vdupq_n_u32(0), vdupq_n_u32(0), - vdupq_n_u32(0) }; - uint32x4_t sum[4]; - - int i = 0; - do { - uint16x8_t s0, s1; - - s0 = vld1q_u16(src16_ptr + i * src_stride); - sad8_neon(s0, vld1q_u16(ref16_ptr0 + i * ref_stride), &sum_lo[0]); - sad8_neon(s0, vld1q_u16(ref16_ptr1 + i * ref_stride), &sum_lo[1]); - sad8_neon(s0, vld1q_u16(ref16_ptr2 + i * ref_stride), &sum_lo[2]); - sad8_neon(s0, vld1q_u16(ref16_ptr3 + i * ref_stride), &sum_lo[3]); - - s1 = vld1q_u16(src16_ptr + i * src_stride + 8); - sad8_neon(s1, vld1q_u16(ref16_ptr0 + i * ref_stride + 8), &sum_hi[0]); - sad8_neon(s1, vld1q_u16(ref16_ptr1 + i * ref_stride + 8), &sum_hi[1]); - sad8_neon(s1, vld1q_u16(ref16_ptr2 + i * ref_stride + 8), &sum_hi[2]); - sad8_neon(s1, vld1q_u16(ref16_ptr3 + i * ref_stride + 8), &sum_hi[3]); - - } while (++i < h); - - sum[0] = vaddq_u32(sum_lo[0], sum_hi[0]); - sum[1] = vaddq_u32(sum_lo[1], sum_hi[1]); - sum[2] = vaddq_u32(sum_lo[2], sum_hi[2]); - sum[3] = vaddq_u32(sum_lo[3], sum_hi[3]); - - vst1q_u32(res, horizontal_add_4d_uint32x4(sum)); -} - -static INLINE void highbd_sadwxhx4d_neon(const uint8_t *src_ptr, int src_stride, - const uint8_t *const ref_ptr[4], - int ref_stride, uint32_t res[4], int w, - int h) { - const uint16_t *src16_ptr = CONVERT_TO_SHORTPTR(src_ptr); - const uint16_t *ref16_ptr0 = CONVERT_TO_SHORTPTR(ref_ptr[0]); - const uint16_t *ref16_ptr1 = CONVERT_TO_SHORTPTR(ref_ptr[1]); - const uint16_t *ref16_ptr2 = CONVERT_TO_SHORTPTR(ref_ptr[2]); - const uint16_t *ref16_ptr3 = CONVERT_TO_SHORTPTR(ref_ptr[3]); - - uint32x4_t sum_lo[4] = { vdupq_n_u32(0), vdupq_n_u32(0), vdupq_n_u32(0), - vdupq_n_u32(0) }; - uint32x4_t sum_hi[4] = { vdupq_n_u32(0), vdupq_n_u32(0), vdupq_n_u32(0), - vdupq_n_u32(0) }; - uint32x4_t sum[4]; - - int i = 0; - do { - int j = 0; - do { - uint16x8_t s0, s1, s2, s3; - - s0 = vld1q_u16(src16_ptr + i * src_stride + j); - sad8_neon(s0, vld1q_u16(ref16_ptr0 + i * ref_stride + j), &sum_lo[0]); - sad8_neon(s0, vld1q_u16(ref16_ptr1 + i * ref_stride + j), &sum_lo[1]); - sad8_neon(s0, vld1q_u16(ref16_ptr2 + i * ref_stride + j), &sum_lo[2]); - sad8_neon(s0, vld1q_u16(ref16_ptr3 + i * ref_stride + j), &sum_lo[3]); - - s1 = vld1q_u16(src16_ptr + i * src_stride + j + 8); - sad8_neon(s1, vld1q_u16(ref16_ptr0 + i * ref_stride + j + 8), &sum_hi[0]); - sad8_neon(s1, vld1q_u16(ref16_ptr1 + i * ref_stride + j + 8), &sum_hi[1]); - sad8_neon(s1, vld1q_u16(ref16_ptr2 + i * ref_stride + j + 8), &sum_hi[2]); - sad8_neon(s1, vld1q_u16(ref16_ptr3 + i * ref_stride + j + 8), &sum_hi[3]); - - s2 = vld1q_u16(src16_ptr + i * src_stride + j + 16); - sad8_neon(s2, vld1q_u16(ref16_ptr0 + i * ref_stride + j + 16), - &sum_lo[0]); - sad8_neon(s2, vld1q_u16(ref16_ptr1 + i * ref_stride + j + 16), - &sum_lo[1]); - sad8_neon(s2, vld1q_u16(ref16_ptr2 + i * ref_stride + j + 16), - &sum_lo[2]); - sad8_neon(s2, vld1q_u16(ref16_ptr3 + i * ref_stride + j + 16), - &sum_lo[3]); - - s3 = vld1q_u16(src16_ptr + i * src_stride + j + 24); - sad8_neon(s3, vld1q_u16(ref16_ptr0 + i * ref_stride + j + 24), - &sum_hi[0]); - sad8_neon(s3, vld1q_u16(ref16_ptr1 + i * ref_stride + j + 24), - &sum_hi[1]); - sad8_neon(s3, vld1q_u16(ref16_ptr2 + i * ref_stride + j + 24), - &sum_hi[2]); - sad8_neon(s3, vld1q_u16(ref16_ptr3 + i * ref_stride + j + 24), - &sum_hi[3]); - - j += 32; - } while (j < w); - - } while (++i < h); - - sum[0] = vaddq_u32(sum_lo[0], sum_hi[0]); - sum[1] = vaddq_u32(sum_lo[1], sum_hi[1]); - sum[2] = vaddq_u32(sum_lo[2], sum_hi[2]); - sum[3] = vaddq_u32(sum_lo[3], sum_hi[3]); - - vst1q_u32(res, horizontal_add_4d_uint32x4(sum)); -} - -static INLINE void highbd_sad64xhx4d_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *const ref_ptr[4], - int ref_stride, uint32_t res[4], - int h) { - highbd_sadwxhx4d_neon(src_ptr, src_stride, ref_ptr, ref_stride, res, 64, h); -} - -static INLINE void highbd_sad32xhx4d_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *const ref_ptr[4], - int ref_stride, uint32_t res[4], - int h) { - highbd_sadwxhx4d_neon(src_ptr, src_stride, ref_ptr, ref_stride, res, 32, h); -} - -#define HBD_SAD_WXH_4D_NEON(w, h) \ - void vpx_highbd_sad##w##x##h##x4d_neon( \ - const uint8_t *src, int src_stride, const uint8_t *const ref_array[4], \ - int ref_stride, uint32_t sad_array[4]) { \ - highbd_sad##w##xhx4d_neon(src, src_stride, ref_array, ref_stride, \ - sad_array, (h)); \ - } - -HBD_SAD_WXH_4D_NEON(4, 4) -HBD_SAD_WXH_4D_NEON(4, 8) - -HBD_SAD_WXH_4D_NEON(8, 4) -HBD_SAD_WXH_4D_NEON(8, 8) -HBD_SAD_WXH_4D_NEON(8, 16) - -HBD_SAD_WXH_4D_NEON(16, 8) -HBD_SAD_WXH_4D_NEON(16, 16) -HBD_SAD_WXH_4D_NEON(16, 32) - -HBD_SAD_WXH_4D_NEON(32, 16) -HBD_SAD_WXH_4D_NEON(32, 32) -HBD_SAD_WXH_4D_NEON(32, 64) - -HBD_SAD_WXH_4D_NEON(64, 32) -HBD_SAD_WXH_4D_NEON(64, 64) - -#undef HBD_SAD_WXH_4D_NEON - -#define HBD_SAD_SKIP_WXH_4D_NEON(w, h) \ - void vpx_highbd_sad_skip_##w##x##h##x4d_neon( \ - const uint8_t *src, int src_stride, const uint8_t *const ref_array[4], \ - int ref_stride, uint32_t sad_array[4]) { \ - highbd_sad##w##xhx4d_neon(src, 2 * src_stride, ref_array, 2 * ref_stride, \ - sad_array, ((h) >> 1)); \ - sad_array[0] <<= 1; \ - sad_array[1] <<= 1; \ - sad_array[2] <<= 1; \ - sad_array[3] <<= 1; \ - } - -HBD_SAD_SKIP_WXH_4D_NEON(4, 4) -HBD_SAD_SKIP_WXH_4D_NEON(4, 8) - -HBD_SAD_SKIP_WXH_4D_NEON(8, 4) -HBD_SAD_SKIP_WXH_4D_NEON(8, 8) -HBD_SAD_SKIP_WXH_4D_NEON(8, 16) - -HBD_SAD_SKIP_WXH_4D_NEON(16, 8) -HBD_SAD_SKIP_WXH_4D_NEON(16, 16) -HBD_SAD_SKIP_WXH_4D_NEON(16, 32) - -HBD_SAD_SKIP_WXH_4D_NEON(32, 16) -HBD_SAD_SKIP_WXH_4D_NEON(32, 32) -HBD_SAD_SKIP_WXH_4D_NEON(32, 64) - -HBD_SAD_SKIP_WXH_4D_NEON(64, 32) -HBD_SAD_SKIP_WXH_4D_NEON(64, 64) - -#undef HBD_SAD_SKIP_WXH_4D_NEON diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_sad_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_sad_neon.c deleted file mode 100644 index b99bac66..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_sad_neon.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" - -static INLINE uint32_t highbd_sad4xh_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h) { - const uint16_t *src16_ptr = CONVERT_TO_SHORTPTR(src_ptr); - const uint16_t *ref16_ptr = CONVERT_TO_SHORTPTR(ref_ptr); - uint32x4_t sum = vdupq_n_u32(0); - - int i = h; - do { - uint16x4_t s = vld1_u16(src16_ptr); - uint16x4_t r = vld1_u16(ref16_ptr); - sum = vabal_u16(sum, s, r); - - src16_ptr += src_stride; - ref16_ptr += ref_stride; - } while (--i != 0); - - return horizontal_add_uint32x4(sum); -} - -static INLINE uint32_t highbd_sad8xh_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h) { - const uint16_t *src16_ptr = CONVERT_TO_SHORTPTR(src_ptr); - const uint16_t *ref16_ptr = CONVERT_TO_SHORTPTR(ref_ptr); - uint16x8_t sum = vdupq_n_u16(0); - - int i = h; - do { - uint16x8_t s = vld1q_u16(src16_ptr); - uint16x8_t r = vld1q_u16(ref16_ptr); - sum = vabaq_u16(sum, s, r); - - src16_ptr += src_stride; - ref16_ptr += ref_stride; - } while (--i != 0); - - return horizontal_add_uint16x8(sum); -} - -static INLINE uint32_t highbd_sad16xh_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h) { - const uint16_t *src16_ptr = CONVERT_TO_SHORTPTR(src_ptr); - const uint16_t *ref16_ptr = CONVERT_TO_SHORTPTR(ref_ptr); - uint32x4_t sum[2] = { vdupq_n_u32(0), vdupq_n_u32(0) }; - - int i = h; - do { - uint16x8_t s0, s1, r0, r1; - uint16x8_t diff0, diff1; - - s0 = vld1q_u16(src16_ptr); - r0 = vld1q_u16(ref16_ptr); - diff0 = vabdq_u16(s0, r0); - sum[0] = vpadalq_u16(sum[0], diff0); - - s1 = vld1q_u16(src16_ptr + 8); - r1 = vld1q_u16(ref16_ptr + 8); - diff1 = vabdq_u16(s1, r1); - sum[1] = vpadalq_u16(sum[1], diff1); - - src16_ptr += src_stride; - ref16_ptr += ref_stride; - } while (--i != 0); - - sum[0] = vaddq_u32(sum[0], sum[1]); - return horizontal_add_uint32x4(sum[0]); -} - -static INLINE uint32_t highbd_sadwxh_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int w, int h) { - const uint16_t *src16_ptr = CONVERT_TO_SHORTPTR(src_ptr); - const uint16_t *ref16_ptr = CONVERT_TO_SHORTPTR(ref_ptr); - uint32x4_t sum[4] = { vdupq_n_u32(0), vdupq_n_u32(0), vdupq_n_u32(0), - vdupq_n_u32(0) }; - - int i = h; - do { - int j = 0; - do { - uint16x8_t s0, s1, s2, s3, r0, r1, r2, r3; - uint16x8_t diff0, diff1, diff2, diff3; - - s0 = vld1q_u16(src16_ptr + j); - r0 = vld1q_u16(ref16_ptr + j); - diff0 = vabdq_u16(s0, r0); - sum[0] = vpadalq_u16(sum[0], diff0); - - s1 = vld1q_u16(src16_ptr + j + 8); - r1 = vld1q_u16(ref16_ptr + j + 8); - diff1 = vabdq_u16(s1, r1); - sum[1] = vpadalq_u16(sum[1], diff1); - - s2 = vld1q_u16(src16_ptr + j + 16); - r2 = vld1q_u16(ref16_ptr + j + 16); - diff2 = vabdq_u16(s2, r2); - sum[2] = vpadalq_u16(sum[2], diff2); - - s3 = vld1q_u16(src16_ptr + j + 24); - r3 = vld1q_u16(ref16_ptr + j + 24); - diff3 = vabdq_u16(s3, r3); - sum[3] = vpadalq_u16(sum[3], diff3); - - j += 32; - } while (j < w); - - src16_ptr += src_stride; - ref16_ptr += ref_stride; - } while (--i != 0); - - sum[0] = vaddq_u32(sum[0], sum[1]); - sum[2] = vaddq_u32(sum[2], sum[3]); - sum[0] = vaddq_u32(sum[0], sum[2]); - - return horizontal_add_uint32x4(sum[0]); -} - -static INLINE unsigned int highbd_sad64xh_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h) { - return highbd_sadwxh_neon(src_ptr, src_stride, ref_ptr, ref_stride, 64, h); -} - -static INLINE unsigned int highbd_sad32xh_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h) { - return highbd_sadwxh_neon(src_ptr, src_stride, ref_ptr, ref_stride, 32, h); -} - -#define HBD_SAD_WXH_NEON(w, h) \ - unsigned int vpx_highbd_sad##w##x##h##_neon( \ - const uint8_t *src, int src_stride, const uint8_t *ref, \ - int ref_stride) { \ - return highbd_sad##w##xh_neon(src, src_stride, ref, ref_stride, (h)); \ - } - -HBD_SAD_WXH_NEON(4, 4) -HBD_SAD_WXH_NEON(4, 8) - -HBD_SAD_WXH_NEON(8, 4) -HBD_SAD_WXH_NEON(8, 8) -HBD_SAD_WXH_NEON(8, 16) - -HBD_SAD_WXH_NEON(16, 8) -HBD_SAD_WXH_NEON(16, 16) -HBD_SAD_WXH_NEON(16, 32) - -HBD_SAD_WXH_NEON(32, 16) -HBD_SAD_WXH_NEON(32, 32) -HBD_SAD_WXH_NEON(32, 64) - -HBD_SAD_WXH_NEON(64, 32) -HBD_SAD_WXH_NEON(64, 64) - -#undef HBD_SAD_WXH_NEON - -#define HBD_SAD_SKIP_WXH_NEON(w, h) \ - unsigned int vpx_highbd_sad_skip_##w##x##h##_neon( \ - const uint8_t *src, int src_stride, const uint8_t *ref, \ - int ref_stride) { \ - return 2 * highbd_sad##w##xh_neon(src, 2 * src_stride, ref, \ - 2 * ref_stride, (h) / 2); \ - } - -HBD_SAD_SKIP_WXH_NEON(4, 4) -HBD_SAD_SKIP_WXH_NEON(4, 8) - -HBD_SAD_SKIP_WXH_NEON(8, 4) -HBD_SAD_SKIP_WXH_NEON(8, 8) -HBD_SAD_SKIP_WXH_NEON(8, 16) - -HBD_SAD_SKIP_WXH_NEON(16, 8) -HBD_SAD_SKIP_WXH_NEON(16, 16) -HBD_SAD_SKIP_WXH_NEON(16, 32) - -HBD_SAD_SKIP_WXH_NEON(32, 16) -HBD_SAD_SKIP_WXH_NEON(32, 32) -HBD_SAD_SKIP_WXH_NEON(32, 64) - -HBD_SAD_SKIP_WXH_NEON(64, 32) -HBD_SAD_SKIP_WXH_NEON(64, 64) - -#undef HBD_SAD_SKIP_WXH_NEON - -static INLINE uint32_t highbd_sad4xh_avg_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h, - const uint8_t *second_pred) { - const uint16_t *src16_ptr = CONVERT_TO_SHORTPTR(src_ptr); - const uint16_t *ref16_ptr = CONVERT_TO_SHORTPTR(ref_ptr); - const uint16_t *pred16_ptr = CONVERT_TO_SHORTPTR(second_pred); - uint32x4_t sum = vdupq_n_u32(0); - - int i = h; - do { - uint16x4_t s = vld1_u16(src16_ptr); - uint16x4_t r = vld1_u16(ref16_ptr); - uint16x4_t p = vld1_u16(pred16_ptr); - - uint16x4_t avg = vrhadd_u16(r, p); - sum = vabal_u16(sum, s, avg); - - src16_ptr += src_stride; - ref16_ptr += ref_stride; - pred16_ptr += 4; - } while (--i != 0); - - return horizontal_add_uint32x4(sum); -} - -static INLINE uint32_t highbd_sad8xh_avg_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h, - const uint8_t *second_pred) { - const uint16_t *src16_ptr = CONVERT_TO_SHORTPTR(src_ptr); - const uint16_t *ref16_ptr = CONVERT_TO_SHORTPTR(ref_ptr); - const uint16_t *pred16_ptr = CONVERT_TO_SHORTPTR(second_pred); - uint32x4_t sum = vdupq_n_u32(0); - - int i = h; - do { - uint16x8_t s = vld1q_u16(src16_ptr); - uint16x8_t r = vld1q_u16(ref16_ptr); - uint16x8_t p = vld1q_u16(pred16_ptr); - - uint16x8_t avg = vrhaddq_u16(r, p); - uint16x8_t diff = vabdq_u16(s, avg); - sum = vpadalq_u16(sum, diff); - - src16_ptr += src_stride; - ref16_ptr += ref_stride; - pred16_ptr += 8; - } while (--i != 0); - - return horizontal_add_uint32x4(sum); -} - -static INLINE uint32_t highbd_sad16xh_avg_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h, - const uint8_t *second_pred) { - const uint16_t *src16_ptr = CONVERT_TO_SHORTPTR(src_ptr); - const uint16_t *ref16_ptr = CONVERT_TO_SHORTPTR(ref_ptr); - const uint16_t *pred16_ptr = CONVERT_TO_SHORTPTR(second_pred); - uint32x4_t sum[2] = { vdupq_n_u32(0), vdupq_n_u32(0) }; - - int i = h; - do { - uint16x8_t s0, s1, r0, r1, p0, p1; - uint16x8_t avg0, avg1, diff0, diff1; - - s0 = vld1q_u16(src16_ptr); - r0 = vld1q_u16(ref16_ptr); - p0 = vld1q_u16(pred16_ptr); - avg0 = vrhaddq_u16(r0, p0); - diff0 = vabdq_u16(s0, avg0); - sum[0] = vpadalq_u16(sum[0], diff0); - - s1 = vld1q_u16(src16_ptr + 8); - r1 = vld1q_u16(ref16_ptr + 8); - p1 = vld1q_u16(pred16_ptr + 8); - avg1 = vrhaddq_u16(r1, p1); - diff1 = vabdq_u16(s1, avg1); - sum[1] = vpadalq_u16(sum[1], diff1); - - src16_ptr += src_stride; - ref16_ptr += ref_stride; - pred16_ptr += 16; - } while (--i != 0); - - sum[0] = vaddq_u32(sum[0], sum[1]); - return horizontal_add_uint32x4(sum[0]); -} - -static INLINE uint32_t highbd_sadwxh_avg_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int w, int h, - const uint8_t *second_pred) { - const uint16_t *src16_ptr = CONVERT_TO_SHORTPTR(src_ptr); - const uint16_t *ref16_ptr = CONVERT_TO_SHORTPTR(ref_ptr); - const uint16_t *pred16_ptr = CONVERT_TO_SHORTPTR(second_pred); - uint32x4_t sum[4] = { vdupq_n_u32(0), vdupq_n_u32(0), vdupq_n_u32(0), - vdupq_n_u32(0) }; - - int i = h; - do { - int j = 0; - do { - uint16x8_t s0, s1, s2, s3, r0, r1, r2, r3, p0, p1, p2, p3; - uint16x8_t avg0, avg1, avg2, avg3, diff0, diff1, diff2, diff3; - - s0 = vld1q_u16(src16_ptr + j); - r0 = vld1q_u16(ref16_ptr + j); - p0 = vld1q_u16(pred16_ptr + j); - avg0 = vrhaddq_u16(r0, p0); - diff0 = vabdq_u16(s0, avg0); - sum[0] = vpadalq_u16(sum[0], diff0); - - s1 = vld1q_u16(src16_ptr + j + 8); - r1 = vld1q_u16(ref16_ptr + j + 8); - p1 = vld1q_u16(pred16_ptr + j + 8); - avg1 = vrhaddq_u16(r1, p1); - diff1 = vabdq_u16(s1, avg1); - sum[1] = vpadalq_u16(sum[1], diff1); - - s2 = vld1q_u16(src16_ptr + j + 16); - r2 = vld1q_u16(ref16_ptr + j + 16); - p2 = vld1q_u16(pred16_ptr + j + 16); - avg2 = vrhaddq_u16(r2, p2); - diff2 = vabdq_u16(s2, avg2); - sum[2] = vpadalq_u16(sum[2], diff2); - - s3 = vld1q_u16(src16_ptr + j + 24); - r3 = vld1q_u16(ref16_ptr + j + 24); - p3 = vld1q_u16(pred16_ptr + j + 24); - avg3 = vrhaddq_u16(r3, p3); - diff3 = vabdq_u16(s3, avg3); - sum[3] = vpadalq_u16(sum[3], diff3); - - j += 32; - } while (j < w); - - src16_ptr += src_stride; - ref16_ptr += ref_stride; - pred16_ptr += w; - } while (--i != 0); - - sum[0] = vaddq_u32(sum[0], sum[1]); - sum[2] = vaddq_u32(sum[2], sum[3]); - sum[0] = vaddq_u32(sum[0], sum[2]); - - return horizontal_add_uint32x4(sum[0]); -} - -static INLINE unsigned int highbd_sad64xh_avg_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h, - const uint8_t *second_pred) { - return highbd_sadwxh_avg_neon(src_ptr, src_stride, ref_ptr, ref_stride, 64, h, - second_pred); -} - -static INLINE unsigned int highbd_sad32xh_avg_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h, - const uint8_t *second_pred) { - return highbd_sadwxh_avg_neon(src_ptr, src_stride, ref_ptr, ref_stride, 32, h, - second_pred); -} - -#define HBD_SAD_WXH_AVG_NEON(w, h) \ - uint32_t vpx_highbd_sad##w##x##h##_avg_neon( \ - const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride, \ - const uint8_t *second_pred) { \ - return highbd_sad##w##xh_avg_neon(src, src_stride, ref, ref_stride, (h), \ - second_pred); \ - } - -HBD_SAD_WXH_AVG_NEON(4, 4) -HBD_SAD_WXH_AVG_NEON(4, 8) - -HBD_SAD_WXH_AVG_NEON(8, 4) -HBD_SAD_WXH_AVG_NEON(8, 8) -HBD_SAD_WXH_AVG_NEON(8, 16) - -HBD_SAD_WXH_AVG_NEON(16, 8) -HBD_SAD_WXH_AVG_NEON(16, 16) -HBD_SAD_WXH_AVG_NEON(16, 32) - -HBD_SAD_WXH_AVG_NEON(32, 16) -HBD_SAD_WXH_AVG_NEON(32, 32) -HBD_SAD_WXH_AVG_NEON(32, 64) - -HBD_SAD_WXH_AVG_NEON(64, 32) -HBD_SAD_WXH_AVG_NEON(64, 64) diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_sse_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_sse_neon.c deleted file mode 100644 index 91dfebf9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_sse_neon.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/sum_neon.h" - -static INLINE void highbd_sse_8x1_init_neon(const uint16_t *src, - const uint16_t *ref, - uint32x4_t *sse_acc0, - uint32x4_t *sse_acc1) { - uint16x8_t s = vld1q_u16(src); - uint16x8_t r = vld1q_u16(ref); - - uint16x8_t abs_diff = vabdq_u16(s, r); - uint16x4_t abs_diff_lo = vget_low_u16(abs_diff); - uint16x4_t abs_diff_hi = vget_high_u16(abs_diff); - - *sse_acc0 = vmull_u16(abs_diff_lo, abs_diff_lo); - *sse_acc1 = vmull_u16(abs_diff_hi, abs_diff_hi); -} - -static INLINE void highbd_sse_8x1_neon(const uint16_t *src, const uint16_t *ref, - uint32x4_t *sse_acc0, - uint32x4_t *sse_acc1) { - uint16x8_t s = vld1q_u16(src); - uint16x8_t r = vld1q_u16(ref); - - uint16x8_t abs_diff = vabdq_u16(s, r); - uint16x4_t abs_diff_lo = vget_low_u16(abs_diff); - uint16x4_t abs_diff_hi = vget_high_u16(abs_diff); - - *sse_acc0 = vmlal_u16(*sse_acc0, abs_diff_lo, abs_diff_lo); - *sse_acc1 = vmlal_u16(*sse_acc1, abs_diff_hi, abs_diff_hi); -} - -static INLINE int64_t highbd_sse_64xh_neon(const uint16_t *src, int src_stride, - const uint16_t *ref, int ref_stride, - int height) { - uint32x4_t sse[8]; - highbd_sse_8x1_init_neon(src + 0 * 8, ref + 0 * 8, &sse[0], &sse[1]); - highbd_sse_8x1_init_neon(src + 1 * 8, ref + 1 * 8, &sse[2], &sse[3]); - highbd_sse_8x1_init_neon(src + 2 * 8, ref + 2 * 8, &sse[4], &sse[5]); - highbd_sse_8x1_init_neon(src + 3 * 8, ref + 3 * 8, &sse[6], &sse[7]); - highbd_sse_8x1_neon(src + 4 * 8, ref + 4 * 8, &sse[0], &sse[1]); - highbd_sse_8x1_neon(src + 5 * 8, ref + 5 * 8, &sse[2], &sse[3]); - highbd_sse_8x1_neon(src + 6 * 8, ref + 6 * 8, &sse[4], &sse[5]); - highbd_sse_8x1_neon(src + 7 * 8, ref + 7 * 8, &sse[6], &sse[7]); - - src += src_stride; - ref += ref_stride; - - while (--height != 0) { - highbd_sse_8x1_neon(src + 0 * 8, ref + 0 * 8, &sse[0], &sse[1]); - highbd_sse_8x1_neon(src + 1 * 8, ref + 1 * 8, &sse[2], &sse[3]); - highbd_sse_8x1_neon(src + 2 * 8, ref + 2 * 8, &sse[4], &sse[5]); - highbd_sse_8x1_neon(src + 3 * 8, ref + 3 * 8, &sse[6], &sse[7]); - highbd_sse_8x1_neon(src + 4 * 8, ref + 4 * 8, &sse[0], &sse[1]); - highbd_sse_8x1_neon(src + 5 * 8, ref + 5 * 8, &sse[2], &sse[3]); - highbd_sse_8x1_neon(src + 6 * 8, ref + 6 * 8, &sse[4], &sse[5]); - highbd_sse_8x1_neon(src + 7 * 8, ref + 7 * 8, &sse[6], &sse[7]); - - src += src_stride; - ref += ref_stride; - } - - return horizontal_long_add_uint32x4_x8(sse); -} - -static INLINE int64_t highbd_sse_32xh_neon(const uint16_t *src, int src_stride, - const uint16_t *ref, int ref_stride, - int height) { - uint32x4_t sse[8]; - highbd_sse_8x1_init_neon(src + 0 * 8, ref + 0 * 8, &sse[0], &sse[1]); - highbd_sse_8x1_init_neon(src + 1 * 8, ref + 1 * 8, &sse[2], &sse[3]); - highbd_sse_8x1_init_neon(src + 2 * 8, ref + 2 * 8, &sse[4], &sse[5]); - highbd_sse_8x1_init_neon(src + 3 * 8, ref + 3 * 8, &sse[6], &sse[7]); - - src += src_stride; - ref += ref_stride; - - while (--height != 0) { - highbd_sse_8x1_neon(src + 0 * 8, ref + 0 * 8, &sse[0], &sse[1]); - highbd_sse_8x1_neon(src + 1 * 8, ref + 1 * 8, &sse[2], &sse[3]); - highbd_sse_8x1_neon(src + 2 * 8, ref + 2 * 8, &sse[4], &sse[5]); - highbd_sse_8x1_neon(src + 3 * 8, ref + 3 * 8, &sse[6], &sse[7]); - - src += src_stride; - ref += ref_stride; - } - - return horizontal_long_add_uint32x4_x8(sse); -} - -static INLINE int64_t highbd_sse_16xh_neon(const uint16_t *src, int src_stride, - const uint16_t *ref, int ref_stride, - int height) { - uint32x4_t sse[4]; - highbd_sse_8x1_init_neon(src + 0 * 8, ref + 0 * 8, &sse[0], &sse[1]); - highbd_sse_8x1_init_neon(src + 1 * 8, ref + 1 * 8, &sse[2], &sse[3]); - - src += src_stride; - ref += ref_stride; - - while (--height != 0) { - highbd_sse_8x1_neon(src + 0 * 8, ref + 0 * 8, &sse[0], &sse[1]); - highbd_sse_8x1_neon(src + 1 * 8, ref + 1 * 8, &sse[2], &sse[3]); - - src += src_stride; - ref += ref_stride; - } - - return horizontal_long_add_uint32x4_x4(sse); -} - -static INLINE int64_t highbd_sse_8xh_neon(const uint16_t *src, int src_stride, - const uint16_t *ref, int ref_stride, - int height) { - uint32x4_t sse[2]; - highbd_sse_8x1_init_neon(src, ref, &sse[0], &sse[1]); - - src += src_stride; - ref += ref_stride; - - while (--height != 0) { - highbd_sse_8x1_neon(src, ref, &sse[0], &sse[1]); - - src += src_stride; - ref += ref_stride; - } - - return horizontal_long_add_uint32x4_x2(sse); -} - -static INLINE int64_t highbd_sse_4xh_neon(const uint16_t *src, int src_stride, - const uint16_t *ref, int ref_stride, - int height) { - // Peel the first loop iteration. - uint16x4_t s = vld1_u16(src); - uint16x4_t r = vld1_u16(ref); - - uint16x4_t abs_diff = vabd_u16(s, r); - uint32x4_t sse = vmull_u16(abs_diff, abs_diff); - - src += src_stride; - ref += ref_stride; - - while (--height != 0) { - s = vld1_u16(src); - r = vld1_u16(ref); - - abs_diff = vabd_u16(s, r); - sse = vmlal_u16(sse, abs_diff, abs_diff); - - src += src_stride; - ref += ref_stride; - } - - return horizontal_long_add_uint32x4(sse); -} - -static INLINE int64_t highbd_sse_wxh_neon(const uint16_t *src, int src_stride, - const uint16_t *ref, int ref_stride, - int width, int height) { - // { 0, 1, 2, 3, 4, 5, 6, 7 } - uint16x8_t k01234567 = vmovl_u8(vcreate_u8(0x0706050403020100)); - uint16x8_t remainder_mask = vcltq_u16(k01234567, vdupq_n_u16(width & 7)); - uint64_t sse = 0; - - do { - int w = width; - int offset = 0; - - do { - uint16x8_t s = vld1q_u16(src + offset); - uint16x8_t r = vld1q_u16(ref + offset); - uint16x8_t abs_diff; - uint16x4_t abs_diff_lo; - uint16x4_t abs_diff_hi; - uint32x4_t sse_u32; - - if (w < 8) { - // Mask out-of-range elements. - s = vandq_u16(s, remainder_mask); - r = vandq_u16(r, remainder_mask); - } - - abs_diff = vabdq_u16(s, r); - abs_diff_lo = vget_low_u16(abs_diff); - abs_diff_hi = vget_high_u16(abs_diff); - - sse_u32 = vmull_u16(abs_diff_lo, abs_diff_lo); - sse_u32 = vmlal_u16(sse_u32, abs_diff_hi, abs_diff_hi); - - sse += horizontal_long_add_uint32x4(sse_u32); - - offset += 8; - w -= 8; - } while (w > 0); - - src += src_stride; - ref += ref_stride; - } while (--height != 0); - - return sse; -} - -int64_t vpx_highbd_sse_neon(const uint8_t *src8, int src_stride, - const uint8_t *ref8, int ref_stride, int width, - int height) { - uint16_t *src = CONVERT_TO_SHORTPTR(src8); - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); - - switch (width) { - case 4: - return highbd_sse_4xh_neon(src, src_stride, ref, ref_stride, height); - case 8: - return highbd_sse_8xh_neon(src, src_stride, ref, ref_stride, height); - case 16: - return highbd_sse_16xh_neon(src, src_stride, ref, ref_stride, height); - case 32: - return highbd_sse_32xh_neon(src, src_stride, ref, ref_stride, height); - case 64: - return highbd_sse_64xh_neon(src, src_stride, ref, ref_stride, height); - default: - return highbd_sse_wxh_neon(src, src_stride, ref, ref_stride, width, - height); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_subpel_variance_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_subpel_variance_neon.c deleted file mode 100644 index f8b94620..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_subpel_variance_neon.c +++ /dev/null @@ -1,586 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "./vpx_config.h" - -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/mem_neon.h" - -// The bilinear filters look like this: -// -// {{ 128, 0 }, { 112, 16 }, { 96, 32 }, { 80, 48 }, -// { 64, 64 }, { 48, 80 }, { 32, 96 }, { 16, 112 }} -// -// We can factor out the highest common multiple, such that the sum of both -// weights will be 8 instead of 128. The benefits of this are two-fold: -// -// 1) We can infer the filter values from the filter_offset parameter in the -// bilinear filter functions below - we don't have to actually load the values -// from memory: -// f0 = 8 - filter_offset -// f1 = filter_offset -// -// 2) Scaling the pixel values by 8, instead of 128 enables us to operate on -// 16-bit data types at all times, rather than widening out to 32-bit and -// requiring double the number of data processing instructions. (12-bit * 8 = -// 15-bit.) - -// Process a block exactly 4 wide and any height. -static void highbd_var_filter_block2d_bil_w4(const uint16_t *src_ptr, - uint16_t *dst_ptr, int src_stride, - int pixel_step, int dst_height, - int filter_offset) { - const uint16x4_t f0 = vdup_n_u16(8 - filter_offset); - const uint16x4_t f1 = vdup_n_u16(filter_offset); - - int i = dst_height; - do { - uint16x4_t s0 = load_unaligned_u16(src_ptr); - uint16x4_t s1 = load_unaligned_u16(src_ptr + pixel_step); - - uint16x4_t blend = vmul_u16(s0, f0); - blend = vmla_u16(blend, s1, f1); - blend = vrshr_n_u16(blend, 3); - - vst1_u16(dst_ptr, blend); - - src_ptr += src_stride; - dst_ptr += 4; - } while (--i != 0); -} - -// Process a block which is a multiple of 8 and any height. -static void highbd_var_filter_block2d_bil_large(const uint16_t *src_ptr, - uint16_t *dst_ptr, - int src_stride, int pixel_step, - int dst_width, int dst_height, - int filter_offset) { - const uint16x8_t f0 = vdupq_n_u16(8 - filter_offset); - const uint16x8_t f1 = vdupq_n_u16(filter_offset); - - int i = dst_height; - do { - int j = 0; - do { - uint16x8_t s0 = vld1q_u16(src_ptr + j); - uint16x8_t s1 = vld1q_u16(src_ptr + j + pixel_step); - - uint16x8_t blend = vmulq_u16(s0, f0); - blend = vmlaq_u16(blend, s1, f1); - blend = vrshrq_n_u16(blend, 3); - - vst1q_u16(dst_ptr + j, blend); - - j += 8; - } while (j < dst_width); - - src_ptr += src_stride; - dst_ptr += dst_width; - } while (--i != 0); -} - -static void highbd_var_filter_block2d_bil_w8(const uint16_t *src_ptr, - uint16_t *dst_ptr, int src_stride, - int pixel_step, int dst_height, - int filter_offset) { - highbd_var_filter_block2d_bil_large(src_ptr, dst_ptr, src_stride, pixel_step, - 8, dst_height, filter_offset); -} -static void highbd_var_filter_block2d_bil_w16(const uint16_t *src_ptr, - uint16_t *dst_ptr, int src_stride, - int pixel_step, int dst_height, - int filter_offset) { - highbd_var_filter_block2d_bil_large(src_ptr, dst_ptr, src_stride, pixel_step, - 16, dst_height, filter_offset); -} -static void highbd_var_filter_block2d_bil_w32(const uint16_t *src_ptr, - uint16_t *dst_ptr, int src_stride, - int pixel_step, int dst_height, - int filter_offset) { - highbd_var_filter_block2d_bil_large(src_ptr, dst_ptr, src_stride, pixel_step, - 32, dst_height, filter_offset); -} -static void highbd_var_filter_block2d_bil_w64(const uint16_t *src_ptr, - uint16_t *dst_ptr, int src_stride, - int pixel_step, int dst_height, - int filter_offset) { - highbd_var_filter_block2d_bil_large(src_ptr, dst_ptr, src_stride, pixel_step, - 64, dst_height, filter_offset); -} - -static void highbd_var_filter_block2d_avg(const uint16_t *src_ptr, - uint16_t *dst_ptr, int src_stride, - int pixel_step, int dst_width, - int dst_height) { - int i = dst_height; - - // We only specialize on the filter values for large block sizes (>= 16x16.) - assert(dst_width >= 16 && dst_width % 16 == 0); - - do { - int j = 0; - do { - uint16x8_t s0 = vld1q_u16(src_ptr + j); - uint16x8_t s1 = vld1q_u16(src_ptr + j + pixel_step); - uint16x8_t avg = vrhaddq_u16(s0, s1); - vst1q_u16(dst_ptr + j, avg); - - j += 8; - } while (j < dst_width); - - src_ptr += src_stride; - dst_ptr += dst_width; - } while (--i != 0); -} - -#define HBD_SUBPEL_VARIANCE_WXH_NEON(bitdepth, w, h) \ - unsigned int vpx_highbd_##bitdepth##_sub_pixel_variance##w##x##h##_neon( \ - const uint8_t *src, int src_stride, int xoffset, int yoffset, \ - const uint8_t *ref, int ref_stride, uint32_t *sse) { \ - uint16_t tmp0[w * (h + 1)]; \ - uint16_t tmp1[w * h]; \ - uint16_t *src_ptr = CONVERT_TO_SHORTPTR(src); \ - \ - highbd_var_filter_block2d_bil_w##w(src_ptr, tmp0, src_stride, 1, (h + 1), \ - xoffset); \ - highbd_var_filter_block2d_bil_w##w(tmp0, tmp1, w, w, h, yoffset); \ - \ - return vpx_highbd_##bitdepth##_variance##w##x##h(CONVERT_TO_BYTEPTR(tmp1), \ - w, ref, ref_stride, sse); \ - } - -#define HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(bitdepth, w, h) \ - unsigned int vpx_highbd_##bitdepth##_sub_pixel_variance##w##x##h##_neon( \ - const uint8_t *src, int src_stride, int xoffset, int yoffset, \ - const uint8_t *ref, int ref_stride, unsigned int *sse) { \ - uint16_t *src_ptr = CONVERT_TO_SHORTPTR(src); \ - \ - if (xoffset == 0) { \ - if (yoffset == 0) { \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(src_ptr), src_stride, ref, ref_stride, sse); \ - } else if (yoffset == 4) { \ - uint16_t tmp[w * h]; \ - highbd_var_filter_block2d_avg(src_ptr, tmp, src_stride, src_stride, w, \ - h); \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(tmp), w, ref, ref_stride, sse); \ - } else { \ - uint16_t tmp[w * h]; \ - highbd_var_filter_block2d_bil_w##w(src_ptr, tmp, src_stride, \ - src_stride, h, yoffset); \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(tmp), w, ref, ref_stride, sse); \ - } \ - } else if (xoffset == 4) { \ - uint16_t tmp0[w * (h + 1)]; \ - if (yoffset == 0) { \ - highbd_var_filter_block2d_avg(src_ptr, tmp0, src_stride, 1, w, h); \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(tmp0), w, ref, ref_stride, sse); \ - } else if (yoffset == 4) { \ - uint16_t tmp1[w * (h + 1)]; \ - highbd_var_filter_block2d_avg(src_ptr, tmp0, src_stride, 1, w, \ - (h + 1)); \ - highbd_var_filter_block2d_avg(tmp0, tmp1, w, w, w, h); \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(tmp1), w, ref, ref_stride, sse); \ - } else { \ - uint16_t tmp1[w * (h + 1)]; \ - highbd_var_filter_block2d_avg(src_ptr, tmp0, src_stride, 1, w, \ - (h + 1)); \ - highbd_var_filter_block2d_bil_w##w(tmp0, tmp1, w, w, h, yoffset); \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(tmp1), w, ref, ref_stride, sse); \ - } \ - } else { \ - uint16_t tmp0[w * (h + 1)]; \ - if (yoffset == 0) { \ - highbd_var_filter_block2d_bil_w##w(src_ptr, tmp0, src_stride, 1, h, \ - xoffset); \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(tmp0), w, ref, ref_stride, sse); \ - } else if (yoffset == 4) { \ - uint16_t tmp1[w * h]; \ - highbd_var_filter_block2d_bil_w##w(src_ptr, tmp0, src_stride, 1, \ - (h + 1), xoffset); \ - highbd_var_filter_block2d_avg(tmp0, tmp1, w, w, w, h); \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(tmp1), w, ref, ref_stride, sse); \ - } else { \ - uint16_t tmp1[w * h]; \ - highbd_var_filter_block2d_bil_w##w(src_ptr, tmp0, src_stride, 1, \ - (h + 1), xoffset); \ - highbd_var_filter_block2d_bil_w##w(tmp0, tmp1, w, w, h, yoffset); \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(tmp1), w, ref, ref_stride, sse); \ - } \ - } \ - } - -// 8-bit -HBD_SUBPEL_VARIANCE_WXH_NEON(8, 4, 4) -HBD_SUBPEL_VARIANCE_WXH_NEON(8, 4, 8) - -HBD_SUBPEL_VARIANCE_WXH_NEON(8, 8, 4) -HBD_SUBPEL_VARIANCE_WXH_NEON(8, 8, 8) -HBD_SUBPEL_VARIANCE_WXH_NEON(8, 8, 16) - -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(8, 16, 8) -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(8, 16, 16) -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(8, 16, 32) - -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(8, 32, 16) -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(8, 32, 32) -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(8, 32, 64) - -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(8, 64, 32) -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(8, 64, 64) - -// 10-bit -HBD_SUBPEL_VARIANCE_WXH_NEON(10, 4, 4) -HBD_SUBPEL_VARIANCE_WXH_NEON(10, 4, 8) - -HBD_SUBPEL_VARIANCE_WXH_NEON(10, 8, 4) -HBD_SUBPEL_VARIANCE_WXH_NEON(10, 8, 8) -HBD_SUBPEL_VARIANCE_WXH_NEON(10, 8, 16) - -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(10, 16, 8) -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(10, 16, 16) -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(10, 16, 32) - -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(10, 32, 16) -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(10, 32, 32) -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(10, 32, 64) - -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(10, 64, 32) -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(10, 64, 64) - -// 12-bit -HBD_SUBPEL_VARIANCE_WXH_NEON(12, 4, 4) -HBD_SUBPEL_VARIANCE_WXH_NEON(12, 4, 8) - -HBD_SUBPEL_VARIANCE_WXH_NEON(12, 8, 4) -HBD_SUBPEL_VARIANCE_WXH_NEON(12, 8, 8) -HBD_SUBPEL_VARIANCE_WXH_NEON(12, 8, 16) - -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(12, 16, 8) -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(12, 16, 16) -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(12, 16, 32) - -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(12, 32, 16) -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(12, 32, 32) -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(12, 32, 64) - -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(12, 64, 32) -HBD_SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(12, 64, 64) - -// Combine bilinear filter with vpx_highbd_comp_avg_pred for blocks having -// width 4. -static void highbd_avg_pred_var_filter_block2d_bil_w4( - const uint16_t *src_ptr, uint16_t *dst_ptr, int src_stride, int pixel_step, - int dst_height, int filter_offset, const uint16_t *second_pred) { - const uint16x4_t f0 = vdup_n_u16(8 - filter_offset); - const uint16x4_t f1 = vdup_n_u16(filter_offset); - - int i = dst_height; - do { - uint16x4_t s0 = load_unaligned_u16(src_ptr); - uint16x4_t s1 = load_unaligned_u16(src_ptr + pixel_step); - uint16x4_t p = vld1_u16(second_pred); - - uint16x4_t blend = vmul_u16(s0, f0); - blend = vmla_u16(blend, s1, f1); - blend = vrshr_n_u16(blend, 3); - - vst1_u16(dst_ptr, vrhadd_u16(blend, p)); - - src_ptr += src_stride; - dst_ptr += 4; - second_pred += 4; - } while (--i != 0); -} - -// Combine bilinear filter with vpx_highbd_comp_avg_pred for large blocks. -static void highbd_avg_pred_var_filter_block2d_bil_large( - const uint16_t *src_ptr, uint16_t *dst_ptr, int src_stride, int pixel_step, - int dst_width, int dst_height, int filter_offset, - const uint16_t *second_pred) { - const uint16x8_t f0 = vdupq_n_u16(8 - filter_offset); - const uint16x8_t f1 = vdupq_n_u16(filter_offset); - - int i = dst_height; - do { - int j = 0; - do { - uint16x8_t s0 = vld1q_u16(src_ptr + j); - uint16x8_t s1 = vld1q_u16(src_ptr + j + pixel_step); - uint16x8_t p = vld1q_u16(second_pred); - - uint16x8_t blend = vmulq_u16(s0, f0); - blend = vmlaq_u16(blend, s1, f1); - blend = vrshrq_n_u16(blend, 3); - - vst1q_u16(dst_ptr + j, vrhaddq_u16(blend, p)); - - j += 8; - second_pred += 8; - } while (j < dst_width); - - src_ptr += src_stride; - dst_ptr += dst_width; - } while (--i != 0); -} - -static void highbd_avg_pred_var_filter_block2d_bil_w8( - const uint16_t *src_ptr, uint16_t *dst_ptr, int src_stride, int pixel_step, - int dst_height, int filter_offset, const uint16_t *second_pred) { - highbd_avg_pred_var_filter_block2d_bil_large(src_ptr, dst_ptr, src_stride, - pixel_step, 8, dst_height, - filter_offset, second_pred); -} -static void highbd_avg_pred_var_filter_block2d_bil_w16( - const uint16_t *src_ptr, uint16_t *dst_ptr, int src_stride, int pixel_step, - int dst_height, int filter_offset, const uint16_t *second_pred) { - highbd_avg_pred_var_filter_block2d_bil_large(src_ptr, dst_ptr, src_stride, - pixel_step, 16, dst_height, - filter_offset, second_pred); -} -static void highbd_avg_pred_var_filter_block2d_bil_w32( - const uint16_t *src_ptr, uint16_t *dst_ptr, int src_stride, int pixel_step, - int dst_height, int filter_offset, const uint16_t *second_pred) { - highbd_avg_pred_var_filter_block2d_bil_large(src_ptr, dst_ptr, src_stride, - pixel_step, 32, dst_height, - filter_offset, second_pred); -} -static void highbd_avg_pred_var_filter_block2d_bil_w64( - const uint16_t *src_ptr, uint16_t *dst_ptr, int src_stride, int pixel_step, - int dst_height, int filter_offset, const uint16_t *second_pred) { - highbd_avg_pred_var_filter_block2d_bil_large(src_ptr, dst_ptr, src_stride, - pixel_step, 64, dst_height, - filter_offset, second_pred); -} - -// Combine averaging subpel filter with vpx_highbd_comp_avg_pred. -static void highbd_avg_pred_var_filter_block2d_avg( - const uint16_t *src_ptr, uint16_t *dst_ptr, int src_stride, int pixel_step, - int dst_width, int dst_height, const uint16_t *second_pred) { - int i = dst_height; - - // We only specialize on the filter values for large block sizes (>= 16x16.) - assert(dst_width >= 16 && dst_width % 16 == 0); - - do { - int j = 0; - do { - uint16x8_t s0 = vld1q_u16(src_ptr + j); - uint16x8_t s1 = vld1q_u16(src_ptr + j + pixel_step); - uint16x8_t avg = vrhaddq_u16(s0, s1); - - uint16x8_t p = vld1q_u16(second_pred); - avg = vrhaddq_u16(avg, p); - - vst1q_u16(dst_ptr + j, avg); - - j += 8; - second_pred += 8; - } while (j < dst_width); - - src_ptr += src_stride; - dst_ptr += dst_width; - } while (--i != 0); -} - -// Implementation of vpx_highbd_comp_avg_pred for blocks having width >= 16. -static void highbd_avg_pred(const uint16_t *src_ptr, uint16_t *dst_ptr, - int src_stride, int dst_width, int dst_height, - const uint16_t *second_pred) { - int i = dst_height; - - // We only specialize on the filter values for large block sizes (>= 16x16.) - assert(dst_width >= 16 && dst_width % 16 == 0); - - do { - int j = 0; - do { - uint16x8_t s = vld1q_u16(src_ptr + j); - uint16x8_t p = vld1q_u16(second_pred); - - uint16x8_t avg = vrhaddq_u16(s, p); - - vst1q_u16(dst_ptr + j, avg); - - j += 8; - second_pred += 8; - } while (j < dst_width); - - src_ptr += src_stride; - dst_ptr += dst_width; - } while (--i != 0); -} - -#define HBD_SUBPEL_AVG_VARIANCE_WXH_NEON(bitdepth, w, h) \ - uint32_t vpx_highbd_##bitdepth##_sub_pixel_avg_variance##w##x##h##_neon( \ - const uint8_t *src, int src_stride, int xoffset, int yoffset, \ - const uint8_t *ref, int ref_stride, uint32_t *sse, \ - const uint8_t *second_pred) { \ - uint16_t tmp0[w * (h + 1)]; \ - uint16_t tmp1[w * h]; \ - uint16_t *src_ptr = CONVERT_TO_SHORTPTR(src); \ - \ - highbd_var_filter_block2d_bil_w##w(src_ptr, tmp0, src_stride, 1, (h + 1), \ - xoffset); \ - highbd_avg_pred_var_filter_block2d_bil_w##w( \ - tmp0, tmp1, w, w, h, yoffset, CONVERT_TO_SHORTPTR(second_pred)); \ - \ - return vpx_highbd_##bitdepth##_variance##w##x##h(CONVERT_TO_BYTEPTR(tmp1), \ - w, ref, ref_stride, sse); \ - } - -#define HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(bitdepth, w, h) \ - unsigned int vpx_highbd_##bitdepth##_sub_pixel_avg_variance##w##x##h##_neon( \ - const uint8_t *src, int source_stride, int xoffset, int yoffset, \ - const uint8_t *ref, int ref_stride, unsigned int *sse, \ - const uint8_t *second_pred) { \ - uint16_t *src_ptr = CONVERT_TO_SHORTPTR(src); \ - \ - if (xoffset == 0) { \ - uint16_t tmp[w * h]; \ - if (yoffset == 0) { \ - highbd_avg_pred(src_ptr, tmp, source_stride, w, h, \ - CONVERT_TO_SHORTPTR(second_pred)); \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(tmp), w, ref, ref_stride, sse); \ - } else if (yoffset == 4) { \ - highbd_avg_pred_var_filter_block2d_avg( \ - src_ptr, tmp, source_stride, source_stride, w, h, \ - CONVERT_TO_SHORTPTR(second_pred)); \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(tmp), w, ref, ref_stride, sse); \ - } else { \ - highbd_avg_pred_var_filter_block2d_bil_w##w( \ - src_ptr, tmp, source_stride, source_stride, h, yoffset, \ - CONVERT_TO_SHORTPTR(second_pred)); \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(tmp), w, ref, ref_stride, sse); \ - } \ - } else if (xoffset == 4) { \ - uint16_t tmp0[w * (h + 1)]; \ - if (yoffset == 0) { \ - highbd_avg_pred_var_filter_block2d_avg( \ - src_ptr, tmp0, source_stride, 1, w, h, \ - CONVERT_TO_SHORTPTR(second_pred)); \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(tmp0), w, ref, ref_stride, sse); \ - } else if (yoffset == 4) { \ - uint16_t tmp1[w * (h + 1)]; \ - highbd_var_filter_block2d_avg(src_ptr, tmp0, source_stride, 1, w, \ - (h + 1)); \ - highbd_avg_pred_var_filter_block2d_avg( \ - tmp0, tmp1, w, w, w, h, CONVERT_TO_SHORTPTR(second_pred)); \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(tmp1), w, ref, ref_stride, sse); \ - } else { \ - uint16_t tmp1[w * (h + 1)]; \ - highbd_var_filter_block2d_avg(src_ptr, tmp0, source_stride, 1, w, \ - (h + 1)); \ - highbd_avg_pred_var_filter_block2d_bil_w##w( \ - tmp0, tmp1, w, w, h, yoffset, CONVERT_TO_SHORTPTR(second_pred)); \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(tmp1), w, ref, ref_stride, sse); \ - } \ - } else { \ - uint16_t tmp0[w * (h + 1)]; \ - if (yoffset == 0) { \ - highbd_avg_pred_var_filter_block2d_bil_w##w( \ - src_ptr, tmp0, source_stride, 1, h, xoffset, \ - CONVERT_TO_SHORTPTR(second_pred)); \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(tmp0), w, ref, ref_stride, sse); \ - } else if (yoffset == 4) { \ - uint16_t tmp1[w * h]; \ - highbd_var_filter_block2d_bil_w##w(src_ptr, tmp0, source_stride, 1, \ - (h + 1), xoffset); \ - highbd_avg_pred_var_filter_block2d_avg( \ - tmp0, tmp1, w, w, w, h, CONVERT_TO_SHORTPTR(second_pred)); \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(tmp1), w, ref, ref_stride, sse); \ - } else { \ - uint16_t tmp1[w * h]; \ - highbd_var_filter_block2d_bil_w##w(src_ptr, tmp0, source_stride, 1, \ - (h + 1), xoffset); \ - highbd_avg_pred_var_filter_block2d_bil_w##w( \ - tmp0, tmp1, w, w, h, yoffset, CONVERT_TO_SHORTPTR(second_pred)); \ - return vpx_highbd_##bitdepth##_variance##w##x##h( \ - CONVERT_TO_BYTEPTR(tmp1), w, ref, ref_stride, sse); \ - } \ - } \ - } - -// 8-bit -HBD_SUBPEL_AVG_VARIANCE_WXH_NEON(8, 4, 4) -HBD_SUBPEL_AVG_VARIANCE_WXH_NEON(8, 4, 8) - -HBD_SUBPEL_AVG_VARIANCE_WXH_NEON(8, 8, 4) -HBD_SUBPEL_AVG_VARIANCE_WXH_NEON(8, 8, 8) -HBD_SUBPEL_AVG_VARIANCE_WXH_NEON(8, 8, 16) - -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(8, 16, 8) -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(8, 16, 16) -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(8, 16, 32) - -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(8, 32, 16) -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(8, 32, 32) -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(8, 32, 64) - -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(8, 64, 32) -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(8, 64, 64) - -// 10-bit -HBD_SUBPEL_AVG_VARIANCE_WXH_NEON(10, 4, 4) -HBD_SUBPEL_AVG_VARIANCE_WXH_NEON(10, 4, 8) - -HBD_SUBPEL_AVG_VARIANCE_WXH_NEON(10, 8, 4) -HBD_SUBPEL_AVG_VARIANCE_WXH_NEON(10, 8, 8) -HBD_SUBPEL_AVG_VARIANCE_WXH_NEON(10, 8, 16) - -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(10, 16, 8) -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(10, 16, 16) -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(10, 16, 32) - -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(10, 32, 16) -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(10, 32, 32) -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(10, 32, 64) - -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(10, 64, 32) -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(10, 64, 64) - -// 12-bit -HBD_SUBPEL_AVG_VARIANCE_WXH_NEON(12, 4, 4) -HBD_SUBPEL_AVG_VARIANCE_WXH_NEON(12, 4, 8) - -HBD_SUBPEL_AVG_VARIANCE_WXH_NEON(12, 8, 4) -HBD_SUBPEL_AVG_VARIANCE_WXH_NEON(12, 8, 8) -HBD_SUBPEL_AVG_VARIANCE_WXH_NEON(12, 8, 16) - -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(12, 16, 8) -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(12, 16, 16) -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(12, 16, 32) - -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(12, 32, 16) -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(12, 32, 32) -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(12, 32, 64) - -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(12, 64, 32) -HBD_SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(12, 64, 64) diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_variance_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_variance_neon.c deleted file mode 100644 index 309ae7fd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_variance_neon.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "./vpx_config.h" - -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" -#include "vpx_ports/mem.h" - -// Process a block of width 4 two rows at a time. -static INLINE void highbd_variance_4xh_neon(const uint16_t *src_ptr, - int src_stride, - const uint16_t *ref_ptr, - int ref_stride, int h, - uint64_t *sse, int64_t *sum) { - int16x8_t sum_s16 = vdupq_n_s16(0); - int32x4_t sse_s32 = vdupq_n_s32(0); - - int i = h; - do { - const uint16x8_t s = load_unaligned_u16q(src_ptr, src_stride); - const uint16x8_t r = load_unaligned_u16q(ref_ptr, ref_stride); - - int16x8_t diff = vreinterpretq_s16_u16(vsubq_u16(s, r)); - sum_s16 = vaddq_s16(sum_s16, diff); - - sse_s32 = vmlal_s16(sse_s32, vget_low_s16(diff), vget_low_s16(diff)); - sse_s32 = vmlal_s16(sse_s32, vget_high_s16(diff), vget_high_s16(diff)); - - src_ptr += 2 * src_stride; - ref_ptr += 2 * ref_stride; - i -= 2; - } while (i != 0); - - *sum = horizontal_add_int16x8(sum_s16); - *sse = horizontal_add_int32x4(sse_s32); -} - -// For 8-bit and 10-bit data, since we're using two int32x4 accumulators, all -// block sizes can be processed in 32-bit elements (1023*1023*64*16 = 1071645696 -// for a 64x64 block). -static INLINE void highbd_variance_large_neon(const uint16_t *src_ptr, - int src_stride, - const uint16_t *ref_ptr, - int ref_stride, int w, int h, - uint64_t *sse, int64_t *sum) { - int32x4_t sum_s32 = vdupq_n_s32(0); - int32x4_t sse_s32[2] = { vdupq_n_s32(0), vdupq_n_s32(0) }; - - int i = h; - do { - int j = 0; - do { - const uint16x8_t s = vld1q_u16(src_ptr + j); - const uint16x8_t r = vld1q_u16(ref_ptr + j); - - const int16x8_t diff = vreinterpretq_s16_u16(vsubq_u16(s, r)); - sum_s32 = vpadalq_s16(sum_s32, diff); - - sse_s32[0] = - vmlal_s16(sse_s32[0], vget_low_s16(diff), vget_low_s16(diff)); - sse_s32[1] = - vmlal_s16(sse_s32[1], vget_high_s16(diff), vget_high_s16(diff)); - - j += 8; - } while (j < w); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--i != 0); - - *sum = horizontal_add_int32x4(sum_s32); - *sse = horizontal_long_add_uint32x4(vaddq_u32( - vreinterpretq_u32_s32(sse_s32[0]), vreinterpretq_u32_s32(sse_s32[1]))); -} - -static INLINE void highbd_variance_8xh_neon(const uint16_t *src, int src_stride, - const uint16_t *ref, int ref_stride, - int h, uint64_t *sse, - int64_t *sum) { - highbd_variance_large_neon(src, src_stride, ref, ref_stride, 8, h, sse, sum); -} - -static INLINE void highbd_variance_16xh_neon(const uint16_t *src, - int src_stride, - const uint16_t *ref, - int ref_stride, int h, - uint64_t *sse, int64_t *sum) { - highbd_variance_large_neon(src, src_stride, ref, ref_stride, 16, h, sse, sum); -} - -static INLINE void highbd_variance_32xh_neon(const uint16_t *src, - int src_stride, - const uint16_t *ref, - int ref_stride, int h, - uint64_t *sse, int64_t *sum) { - highbd_variance_large_neon(src, src_stride, ref, ref_stride, 32, h, sse, sum); -} - -static INLINE void highbd_variance_64xh_neon(const uint16_t *src, - int src_stride, - const uint16_t *ref, - int ref_stride, int h, - uint64_t *sse, int64_t *sum) { - highbd_variance_large_neon(src, src_stride, ref, ref_stride, 64, h, sse, sum); -} - -// For 12-bit data, we can only accumulate up to 128 elements in the sum of -// squares (4095*4095*128 = 2146435200), and because we're using two int32x4 -// accumulators, we can only process up to 32 32-element rows (32*32/8 = 128) -// or 16 64-element rows before we have to accumulate into 64-bit elements. -// Therefore blocks of size 32x64, 64x32 and 64x64 are processed in a different -// helper function. - -// Process a block of any size where the width is divisible by 8, with -// accumulation into 64-bit elements. -static INLINE void highbd_variance_xlarge_neon( - const uint16_t *src_ptr, int src_stride, const uint16_t *ref_ptr, - int ref_stride, int w, int h, int h_limit, uint64_t *sse, int64_t *sum) { - int32x4_t sum_s32 = vdupq_n_s32(0); - int64x2_t sse_s64 = vdupq_n_s64(0); - - // 'h_limit' is the number of 'w'-width rows we can process before our 32-bit - // accumulator overflows. After hitting this limit we accumulate into 64-bit - // elements. - int h_tmp = h > h_limit ? h_limit : h; - - int i = 0; - do { - int32x4_t sse_s32[2] = { vdupq_n_s32(0), vdupq_n_s32(0) }; - do { - int j = 0; - do { - const uint16x8_t s0 = vld1q_u16(src_ptr + j); - const uint16x8_t r0 = vld1q_u16(ref_ptr + j); - - const int16x8_t diff = vreinterpretq_s16_u16(vsubq_u16(s0, r0)); - sum_s32 = vpadalq_s16(sum_s32, diff); - - sse_s32[0] = - vmlal_s16(sse_s32[0], vget_low_s16(diff), vget_low_s16(diff)); - sse_s32[1] = - vmlal_s16(sse_s32[1], vget_high_s16(diff), vget_high_s16(diff)); - - j += 8; - } while (j < w); - - src_ptr += src_stride; - ref_ptr += ref_stride; - i++; - } while (i < h_tmp); - - sse_s64 = vpadalq_s32(sse_s64, sse_s32[0]); - sse_s64 = vpadalq_s32(sse_s64, sse_s32[1]); - h_tmp += h_limit; - } while (i < h); - - *sum = horizontal_add_int32x4(sum_s32); - *sse = (uint64_t)horizontal_add_int64x2(sse_s64); -} - -static INLINE void highbd_variance_32xh_xlarge_neon( - const uint16_t *src, int src_stride, const uint16_t *ref, int ref_stride, - int h, uint64_t *sse, int64_t *sum) { - highbd_variance_xlarge_neon(src, src_stride, ref, ref_stride, 32, h, 32, sse, - sum); -} - -static INLINE void highbd_variance_64xh_xlarge_neon( - const uint16_t *src, int src_stride, const uint16_t *ref, int ref_stride, - int h, uint64_t *sse, int64_t *sum) { - highbd_variance_xlarge_neon(src, src_stride, ref, ref_stride, 64, h, 16, sse, - sum); -} - -#define HBD_VARIANCE_WXH_8_NEON(w, h) \ - uint32_t vpx_highbd_8_variance##w##x##h##_neon( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - int sum; \ - uint64_t sse_long = 0; \ - int64_t sum_long = 0; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - highbd_variance_##w##xh_neon(src, src_stride, ref, ref_stride, h, \ - &sse_long, &sum_long); \ - *sse = (uint32_t)sse_long; \ - sum = (int)sum_long; \ - return *sse - (uint32_t)(((int64_t)sum * sum) / (w * h)); \ - } - -#define HBD_VARIANCE_WXH_10_NEON(w, h) \ - uint32_t vpx_highbd_10_variance##w##x##h##_neon( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - int sum; \ - int64_t var; \ - uint64_t sse_long = 0; \ - int64_t sum_long = 0; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - highbd_variance_##w##xh_neon(src, src_stride, ref, ref_stride, h, \ - &sse_long, &sum_long); \ - *sse = (uint32_t)ROUND_POWER_OF_TWO(sse_long, 4); \ - sum = (int)ROUND_POWER_OF_TWO(sum_long, 2); \ - var = (int64_t)(*sse) - (((int64_t)sum * sum) / (w * h)); \ - return (var >= 0) ? (uint32_t)var : 0; \ - } - -#define HBD_VARIANCE_WXH_12_NEON(w, h) \ - uint32_t vpx_highbd_12_variance##w##x##h##_neon( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - int sum; \ - int64_t var; \ - uint64_t sse_long = 0; \ - int64_t sum_long = 0; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - highbd_variance_##w##xh_neon(src, src_stride, ref, ref_stride, h, \ - &sse_long, &sum_long); \ - *sse = (uint32_t)ROUND_POWER_OF_TWO(sse_long, 8); \ - sum = (int)ROUND_POWER_OF_TWO(sum_long, 4); \ - var = (int64_t)(*sse) - (((int64_t)sum * sum) / (w * h)); \ - return (var >= 0) ? (uint32_t)var : 0; \ - } - -#define HBD_VARIANCE_WXH_12_XLARGE_NEON(w, h) \ - uint32_t vpx_highbd_12_variance##w##x##h##_neon( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - int sum; \ - int64_t var; \ - uint64_t sse_long = 0; \ - int64_t sum_long = 0; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - highbd_variance_##w##xh_xlarge_neon(src, src_stride, ref, ref_stride, h, \ - &sse_long, &sum_long); \ - *sse = (uint32_t)ROUND_POWER_OF_TWO(sse_long, 8); \ - sum = (int)ROUND_POWER_OF_TWO(sum_long, 4); \ - var = (int64_t)(*sse) - (((int64_t)sum * sum) / (w * h)); \ - return (var >= 0) ? (uint32_t)var : 0; \ - } - -// 8-bit -HBD_VARIANCE_WXH_8_NEON(4, 4) -HBD_VARIANCE_WXH_8_NEON(4, 8) - -HBD_VARIANCE_WXH_8_NEON(8, 4) -HBD_VARIANCE_WXH_8_NEON(8, 8) -HBD_VARIANCE_WXH_8_NEON(8, 16) - -HBD_VARIANCE_WXH_8_NEON(16, 8) -HBD_VARIANCE_WXH_8_NEON(16, 16) -HBD_VARIANCE_WXH_8_NEON(16, 32) - -HBD_VARIANCE_WXH_8_NEON(32, 16) -HBD_VARIANCE_WXH_8_NEON(32, 32) -HBD_VARIANCE_WXH_8_NEON(32, 64) - -HBD_VARIANCE_WXH_8_NEON(64, 32) -HBD_VARIANCE_WXH_8_NEON(64, 64) - -// 10-bit -HBD_VARIANCE_WXH_10_NEON(4, 4) -HBD_VARIANCE_WXH_10_NEON(4, 8) - -HBD_VARIANCE_WXH_10_NEON(8, 4) -HBD_VARIANCE_WXH_10_NEON(8, 8) -HBD_VARIANCE_WXH_10_NEON(8, 16) - -HBD_VARIANCE_WXH_10_NEON(16, 8) -HBD_VARIANCE_WXH_10_NEON(16, 16) -HBD_VARIANCE_WXH_10_NEON(16, 32) - -HBD_VARIANCE_WXH_10_NEON(32, 16) -HBD_VARIANCE_WXH_10_NEON(32, 32) -HBD_VARIANCE_WXH_10_NEON(32, 64) - -HBD_VARIANCE_WXH_10_NEON(64, 32) -HBD_VARIANCE_WXH_10_NEON(64, 64) - -// 12-bit -HBD_VARIANCE_WXH_12_NEON(4, 4) -HBD_VARIANCE_WXH_12_NEON(4, 8) - -HBD_VARIANCE_WXH_12_NEON(8, 4) -HBD_VARIANCE_WXH_12_NEON(8, 8) -HBD_VARIANCE_WXH_12_NEON(8, 16) - -HBD_VARIANCE_WXH_12_NEON(16, 8) -HBD_VARIANCE_WXH_12_NEON(16, 16) -HBD_VARIANCE_WXH_12_NEON(16, 32) - -HBD_VARIANCE_WXH_12_NEON(32, 16) -HBD_VARIANCE_WXH_12_NEON(32, 32) -HBD_VARIANCE_WXH_12_XLARGE_NEON(32, 64) - -HBD_VARIANCE_WXH_12_XLARGE_NEON(64, 32) -HBD_VARIANCE_WXH_12_XLARGE_NEON(64, 64) - -#define HIGHBD_GET_VAR(S) \ - void vpx_highbd_8_get##S##x##S##var_neon( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse, int *sum) { \ - uint64_t sse_long = 0; \ - int64_t sum_long = 0; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - highbd_variance_##S##xh_neon(src, src_stride, ref, ref_stride, S, \ - &sse_long, &sum_long); \ - *sse = (uint32_t)sse_long; \ - *sum = (int)sum_long; \ - } \ - \ - void vpx_highbd_10_get##S##x##S##var_neon( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse, int *sum) { \ - uint64_t sse_long = 0; \ - int64_t sum_long = 0; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - highbd_variance_##S##xh_neon(src, src_stride, ref, ref_stride, S, \ - &sse_long, &sum_long); \ - *sse = (uint32_t)ROUND_POWER_OF_TWO(sse_long, 4); \ - *sum = (int)ROUND_POWER_OF_TWO(sum_long, 2); \ - } \ - \ - void vpx_highbd_12_get##S##x##S##var_neon( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse, int *sum) { \ - uint64_t sse_long = 0; \ - int64_t sum_long = 0; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - highbd_variance_##S##xh_neon(src, src_stride, ref, ref_stride, S, \ - &sse_long, &sum_long); \ - *sse = (uint32_t)ROUND_POWER_OF_TWO(sse_long, 8); \ - *sum = (int)ROUND_POWER_OF_TWO(sum_long, 4); \ - } - -HIGHBD_GET_VAR(8) -HIGHBD_GET_VAR(16) - -static INLINE uint32_t highbd_mse_wxh_neon(const uint16_t *src_ptr, - int src_stride, - const uint16_t *ref_ptr, - int ref_stride, int w, int h) { - uint32x4_t sse_u32[2] = { vdupq_n_u32(0), vdupq_n_u32(0) }; - - int i = h; - do { - int j = 0; - do { - uint16x8_t s = vld1q_u16(src_ptr + j); - uint16x8_t r = vld1q_u16(ref_ptr + j); - - uint16x8_t diff = vabdq_u16(s, r); - - sse_u32[0] = - vmlal_u16(sse_u32[0], vget_low_u16(diff), vget_low_u16(diff)); - sse_u32[1] = - vmlal_u16(sse_u32[1], vget_high_u16(diff), vget_high_u16(diff)); - - j += 8; - } while (j < w); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--i != 0); - - return horizontal_add_uint32x4(vaddq_u32(sse_u32[0], sse_u32[1])); -} - -static INLINE uint32_t highbd_mse8_8xh_neon(const uint16_t *src_ptr, - int src_stride, - const uint16_t *ref_ptr, - int ref_stride, int h) { - return highbd_mse_wxh_neon(src_ptr, src_stride, ref_ptr, ref_stride, 8, h); -} - -static INLINE uint32_t highbd_mse8_16xh_neon(const uint16_t *src_ptr, - int src_stride, - const uint16_t *ref_ptr, - int ref_stride, int h) { - return highbd_mse_wxh_neon(src_ptr, src_stride, ref_ptr, ref_stride, 16, h); -} - -#define HIGHBD_MSE_WXH_NEON(w, h) \ - uint32_t vpx_highbd_8_mse##w##x##h##_neon( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - *sse = highbd_mse8_##w##xh_neon(src, src_stride, ref, ref_stride, h); \ - return *sse; \ - } \ - \ - uint32_t vpx_highbd_10_mse##w##x##h##_neon( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - *sse = highbd_mse_wxh_neon(src, src_stride, ref, ref_stride, w, h); \ - *sse = ROUND_POWER_OF_TWO(*sse, 4); \ - return *sse; \ - } \ - \ - uint32_t vpx_highbd_12_mse##w##x##h##_neon( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - *sse = highbd_mse_wxh_neon(src, src_stride, ref, ref_stride, w, h); \ - *sse = ROUND_POWER_OF_TWO(*sse, 8); \ - return *sse; \ - } - -HIGHBD_MSE_WXH_NEON(16, 16) -HIGHBD_MSE_WXH_NEON(16, 8) -HIGHBD_MSE_WXH_NEON(8, 16) -HIGHBD_MSE_WXH_NEON(8, 8) - -#undef HIGHBD_MSE_WXH_NEON diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_variance_neon_dotprod.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_variance_neon_dotprod.c deleted file mode 100644 index 1a887201..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_variance_neon_dotprod.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "./vpx_config.h" - -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" -#include "vpx_ports/mem.h" - -static INLINE uint32_t highbd_mse8_8xh_neon_dotprod(const uint16_t *src_ptr, - int src_stride, - const uint16_t *ref_ptr, - int ref_stride, int h) { - uint32x4_t sse_u32 = vdupq_n_u32(0); - - int i = h / 2; - do { - uint16x8_t s0, s1, r0, r1; - uint8x16_t s, r, diff; - - s0 = vld1q_u16(src_ptr); - src_ptr += src_stride; - s1 = vld1q_u16(src_ptr); - src_ptr += src_stride; - r0 = vld1q_u16(ref_ptr); - ref_ptr += ref_stride; - r1 = vld1q_u16(ref_ptr); - ref_ptr += ref_stride; - - s = vcombine_u8(vmovn_u16(s0), vmovn_u16(s1)); - r = vcombine_u8(vmovn_u16(r0), vmovn_u16(r1)); - - diff = vabdq_u8(s, r); - sse_u32 = vdotq_u32(sse_u32, diff, diff); - } while (--i != 0); - - return horizontal_add_uint32x4(sse_u32); -} - -static INLINE uint32_t highbd_mse8_16xh_neon_dotprod(const uint16_t *src_ptr, - int src_stride, - const uint16_t *ref_ptr, - int ref_stride, int h) { - uint32x4_t sse_u32 = vdupq_n_u32(0); - - int i = h; - do { - uint16x8_t s0, s1, r0, r1; - uint8x16_t s, r, diff; - - s0 = vld1q_u16(src_ptr); - s1 = vld1q_u16(src_ptr + 8); - r0 = vld1q_u16(ref_ptr); - r1 = vld1q_u16(ref_ptr + 8); - - s = vcombine_u8(vmovn_u16(s0), vmovn_u16(s1)); - r = vcombine_u8(vmovn_u16(r0), vmovn_u16(r1)); - - diff = vabdq_u8(s, r); - sse_u32 = vdotq_u32(sse_u32, diff, diff); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--i != 0); - - return horizontal_add_uint32x4(sse_u32); -} - -#define HIGHBD_MSE_WXH_NEON_DOTPROD(w, h) \ - uint32_t vpx_highbd_8_mse##w##x##h##_neon_dotprod( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - *sse = \ - highbd_mse8_##w##xh_neon_dotprod(src, src_stride, ref, ref_stride, h); \ - return *sse; \ - } - -HIGHBD_MSE_WXH_NEON_DOTPROD(16, 16) -HIGHBD_MSE_WXH_NEON_DOTPROD(16, 8) -HIGHBD_MSE_WXH_NEON_DOTPROD(8, 16) -HIGHBD_MSE_WXH_NEON_DOTPROD(8, 8) - -#undef HIGHBD_MSE_WXH_NEON_DOTPROD diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_variance_sve.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_variance_sve.c deleted file mode 100644 index cebe06b0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_variance_sve.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (c) 2024 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "./vpx_config.h" - -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" -#include "vpx_dsp/arm/vpx_neon_sve_bridge.h" -#include "vpx_ports/mem.h" - -static INLINE uint32_t highbd_mse_wxh_sve(const uint16_t *src_ptr, - int src_stride, - const uint16_t *ref_ptr, - int ref_stride, int w, int h) { - uint64x2_t sse = vdupq_n_u64(0); - - do { - int j = 0; - do { - uint16x8_t s = vld1q_u16(src_ptr + j); - uint16x8_t r = vld1q_u16(ref_ptr + j); - - uint16x8_t diff = vabdq_u16(s, r); - - sse = vpx_dotq_u16(sse, diff, diff); - - j += 8; - } while (j < w); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--h != 0); - - return (uint32_t)horizontal_add_uint64x2(sse); -} - -#define HIGHBD_MSE_WXH_SVE(w, h) \ - uint32_t vpx_highbd_10_mse##w##x##h##_sve( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - uint32_t sse_tmp = \ - highbd_mse_wxh_sve(src, src_stride, ref, ref_stride, w, h); \ - sse_tmp = ROUND_POWER_OF_TWO(sse_tmp, 4); \ - *sse = sse_tmp; \ - return sse_tmp; \ - } \ - \ - uint32_t vpx_highbd_12_mse##w##x##h##_sve( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - uint32_t sse_tmp = \ - highbd_mse_wxh_sve(src, src_stride, ref, ref_stride, w, h); \ - sse_tmp = ROUND_POWER_OF_TWO(sse_tmp, 8); \ - *sse = sse_tmp; \ - return sse_tmp; \ - } - -HIGHBD_MSE_WXH_SVE(16, 16) -HIGHBD_MSE_WXH_SVE(16, 8) -HIGHBD_MSE_WXH_SVE(8, 16) -HIGHBD_MSE_WXH_SVE(8, 8) - -#undef HIGHBD_MSE_WXH_SVE - -// Process a block of width 4 two rows at a time. -static INLINE void highbd_variance_4xh_sve(const uint16_t *src_ptr, - int src_stride, - const uint16_t *ref_ptr, - int ref_stride, int h, uint64_t *sse, - int64_t *sum) { - int16x8_t sum_s16 = vdupq_n_s16(0); - int64x2_t sse_s64 = vdupq_n_s64(0); - - do { - const uint16x8_t s = load_unaligned_u16q(src_ptr, src_stride); - const uint16x8_t r = load_unaligned_u16q(ref_ptr, ref_stride); - - int16x8_t diff = vreinterpretq_s16_u16(vsubq_u16(s, r)); - sum_s16 = vaddq_s16(sum_s16, diff); - sse_s64 = vpx_dotq_s16(sse_s64, diff, diff); - - src_ptr += 2 * src_stride; - ref_ptr += 2 * ref_stride; - h -= 2; - } while (h != 0); - - *sum = horizontal_add_int16x8(sum_s16); - *sse = horizontal_add_int64x2(sse_s64); -} - -static INLINE void highbd_variance_8xh_sve(const uint16_t *src_ptr, - int src_stride, - const uint16_t *ref_ptr, - int ref_stride, int h, uint64_t *sse, - int64_t *sum) { - int32x4_t sum_s32 = vdupq_n_s32(0); - int64x2_t sse_s64 = vdupq_n_s64(0); - - do { - const uint16x8_t s = vld1q_u16(src_ptr); - const uint16x8_t r = vld1q_u16(ref_ptr); - - const int16x8_t diff = vreinterpretq_s16_u16(vsubq_u16(s, r)); - sum_s32 = vpadalq_s16(sum_s32, diff); - sse_s64 = vpx_dotq_s16(sse_s64, diff, diff); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--h != 0); - - *sum = horizontal_add_int32x4(sum_s32); - *sse = horizontal_add_int64x2(sse_s64); -} - -static INLINE void highbd_variance_16xh_sve(const uint16_t *src_ptr, - int src_stride, - const uint16_t *ref_ptr, - int ref_stride, int h, - uint64_t *sse, int64_t *sum) { - int32x4_t sum_s32[2] = { vdupq_n_s32(0), vdupq_n_s32(0) }; - int64x2_t sse_s64[2] = { vdupq_n_s64(0), vdupq_n_s64(0) }; - - do { - const uint16x8_t s0 = vld1q_u16(src_ptr); - const uint16x8_t s1 = vld1q_u16(src_ptr + 8); - - const uint16x8_t r0 = vld1q_u16(ref_ptr); - const uint16x8_t r1 = vld1q_u16(ref_ptr + 8); - - const int16x8_t diff0 = vreinterpretq_s16_u16(vsubq_u16(s0, r0)); - const int16x8_t diff1 = vreinterpretq_s16_u16(vsubq_u16(s1, r1)); - - sum_s32[0] = vpadalq_s16(sum_s32[0], diff0); - sum_s32[1] = vpadalq_s16(sum_s32[1], diff1); - - sse_s64[0] = vpx_dotq_s16(sse_s64[0], diff0, diff0); - sse_s64[1] = vpx_dotq_s16(sse_s64[1], diff1, diff1); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--h != 0); - - sum_s32[0] = vaddq_s32(sum_s32[0], sum_s32[1]); - sse_s64[0] = vaddq_s64(sse_s64[0], sse_s64[1]); - - *sum = horizontal_add_int32x4(sum_s32[0]); - *sse = horizontal_add_int64x2(sse_s64[0]); -} - -static INLINE void highbd_variance_wxh_sve(const uint16_t *src_ptr, - int src_stride, - const uint16_t *ref_ptr, - int ref_stride, int w, int h, - uint64_t *sse, int64_t *sum) { - int32x4_t sum_s32[4] = { vdupq_n_s32(0), vdupq_n_s32(0), vdupq_n_s32(0), - vdupq_n_s32(0) }; - int64x2_t sse_s64[4] = { vdupq_n_s64(0), vdupq_n_s64(0), vdupq_n_s64(0), - vdupq_n_s64(0) }; - - do { - int i = 0; - do { - const uint16x8_t s0 = vld1q_u16(src_ptr + i); - const uint16x8_t s1 = vld1q_u16(src_ptr + i + 8); - const uint16x8_t s2 = vld1q_u16(src_ptr + i + 16); - const uint16x8_t s3 = vld1q_u16(src_ptr + i + 24); - - const uint16x8_t r0 = vld1q_u16(ref_ptr + i); - const uint16x8_t r1 = vld1q_u16(ref_ptr + i + 8); - const uint16x8_t r2 = vld1q_u16(ref_ptr + i + 16); - const uint16x8_t r3 = vld1q_u16(ref_ptr + i + 24); - - const int16x8_t diff0 = vreinterpretq_s16_u16(vsubq_u16(s0, r0)); - const int16x8_t diff1 = vreinterpretq_s16_u16(vsubq_u16(s1, r1)); - const int16x8_t diff2 = vreinterpretq_s16_u16(vsubq_u16(s2, r2)); - const int16x8_t diff3 = vreinterpretq_s16_u16(vsubq_u16(s3, r3)); - - sum_s32[0] = vpadalq_s16(sum_s32[0], diff0); - sum_s32[1] = vpadalq_s16(sum_s32[1], diff1); - sum_s32[2] = vpadalq_s16(sum_s32[2], diff2); - sum_s32[3] = vpadalq_s16(sum_s32[3], diff3); - - sse_s64[0] = vpx_dotq_s16(sse_s64[0], diff0, diff0); - sse_s64[1] = vpx_dotq_s16(sse_s64[1], diff1, diff1); - sse_s64[2] = vpx_dotq_s16(sse_s64[2], diff2, diff2); - sse_s64[3] = vpx_dotq_s16(sse_s64[3], diff3, diff3); - - i += 32; - } while (i < w); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--h != 0); - - sum_s32[0] = vaddq_s32(sum_s32[0], sum_s32[1]); - sum_s32[2] = vaddq_s32(sum_s32[2], sum_s32[3]); - sum_s32[0] = vaddq_s32(sum_s32[0], sum_s32[2]); - - sse_s64[0] = vaddq_s64(sse_s64[0], sse_s64[1]); - sse_s64[2] = vaddq_s64(sse_s64[2], sse_s64[3]); - sse_s64[0] = vaddq_s64(sse_s64[0], sse_s64[2]); - - *sum = horizontal_add_int32x4(sum_s32[0]); - *sse = horizontal_add_int64x2(sse_s64[0]); -} - -static INLINE void highbd_variance_32xh_sve(const uint16_t *src, int src_stride, - const uint16_t *ref, int ref_stride, - int h, uint64_t *sse, - int64_t *sum) { - highbd_variance_wxh_sve(src, src_stride, ref, ref_stride, 32, h, sse, sum); -} - -static INLINE void highbd_variance_64xh_sve(const uint16_t *src, int src_stride, - const uint16_t *ref, int ref_stride, - int h, uint64_t *sse, - int64_t *sum) { - highbd_variance_wxh_sve(src, src_stride, ref, ref_stride, 64, h, sse, sum); -} - -#define HBD_VARIANCE_WXH_SVE(w, h) \ - uint32_t vpx_highbd_8_variance##w##x##h##_sve( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - int sum; \ - uint64_t sse_long = 0; \ - int64_t sum_long = 0; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - highbd_variance_##w##xh_sve(src, src_stride, ref, ref_stride, h, \ - &sse_long, &sum_long); \ - *sse = (uint32_t)sse_long; \ - sum = (int)sum_long; \ - return *sse - (uint32_t)(((int64_t)sum * sum) / (w * h)); \ - } \ - \ - uint32_t vpx_highbd_10_variance##w##x##h##_sve( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - int sum; \ - int64_t var; \ - uint64_t sse_long = 0; \ - int64_t sum_long = 0; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - highbd_variance_##w##xh_sve(src, src_stride, ref, ref_stride, h, \ - &sse_long, &sum_long); \ - *sse = (uint32_t)ROUND_POWER_OF_TWO(sse_long, 4); \ - sum = (int)ROUND_POWER_OF_TWO(sum_long, 2); \ - var = (int64_t)(*sse) - (((int64_t)sum * sum) / (w * h)); \ - return (var >= 0) ? (uint32_t)var : 0; \ - } \ - \ - uint32_t vpx_highbd_12_variance##w##x##h##_sve( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - int sum; \ - int64_t var; \ - uint64_t sse_long = 0; \ - int64_t sum_long = 0; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - highbd_variance_##w##xh_sve(src, src_stride, ref, ref_stride, h, \ - &sse_long, &sum_long); \ - *sse = (uint32_t)ROUND_POWER_OF_TWO(sse_long, 8); \ - sum = (int)ROUND_POWER_OF_TWO(sum_long, 4); \ - var = (int64_t)(*sse) - (((int64_t)sum * sum) / (w * h)); \ - return (var >= 0) ? (uint32_t)var : 0; \ - } - -HBD_VARIANCE_WXH_SVE(4, 4) -HBD_VARIANCE_WXH_SVE(4, 8) - -HBD_VARIANCE_WXH_SVE(8, 4) -HBD_VARIANCE_WXH_SVE(8, 8) -HBD_VARIANCE_WXH_SVE(8, 16) - -HBD_VARIANCE_WXH_SVE(16, 8) -HBD_VARIANCE_WXH_SVE(16, 16) -HBD_VARIANCE_WXH_SVE(16, 32) - -HBD_VARIANCE_WXH_SVE(32, 16) -HBD_VARIANCE_WXH_SVE(32, 32) -HBD_VARIANCE_WXH_SVE(32, 64) - -HBD_VARIANCE_WXH_SVE(64, 32) -HBD_VARIANCE_WXH_SVE(64, 64) - -#define HIGHBD_GET_VAR_SVE(s) \ - void vpx_highbd_8_get##s##x##s##var_sve( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse, int *sum) { \ - uint64_t sse_long = 0; \ - int64_t sum_long = 0; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - highbd_variance_##s##xh_sve(src, src_stride, ref, ref_stride, s, \ - &sse_long, &sum_long); \ - *sse = (uint32_t)sse_long; \ - *sum = (int)sum_long; \ - } \ - \ - void vpx_highbd_10_get##s##x##s##var_sve( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse, int *sum) { \ - uint64_t sse_long = 0; \ - int64_t sum_long = 0; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - highbd_variance_##s##xh_sve(src, src_stride, ref, ref_stride, s, \ - &sse_long, &sum_long); \ - *sse = (uint32_t)ROUND_POWER_OF_TWO(sse_long, 4); \ - *sum = (int)ROUND_POWER_OF_TWO(sum_long, 2); \ - } \ - \ - void vpx_highbd_12_get##s##x##s##var_sve( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse, int *sum) { \ - uint64_t sse_long = 0; \ - int64_t sum_long = 0; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - highbd_variance_##s##xh_sve(src, src_stride, ref, ref_stride, s, \ - &sse_long, &sum_long); \ - *sse = (uint32_t)ROUND_POWER_OF_TWO(sse_long, 8); \ - *sum = (int)ROUND_POWER_OF_TWO(sum_long, 4); \ - } - -HIGHBD_GET_VAR_SVE(8) -HIGHBD_GET_VAR_SVE(16) diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_vpx_convolve8_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_vpx_convolve8_neon.c deleted file mode 100644 index cc6307f9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_vpx_convolve8_neon.c +++ /dev/null @@ -1,1231 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/highbd_convolve8_neon.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_ports/mem.h" - -static INLINE uint16x4_t -highbd_convolve8_4(const int16x4_t s0, const int16x4_t s1, const int16x4_t s2, - const int16x4_t s3, const int16x4_t s4, const int16x4_t s5, - const int16x4_t s6, const int16x4_t s7, - const int16x8_t filters, const uint16x4_t max) { - const int16x4_t filters_lo = vget_low_s16(filters); - const int16x4_t filters_hi = vget_high_s16(filters); - - int32x4_t sum = vmull_lane_s16(s0, filters_lo, 0); - sum = vmlal_lane_s16(sum, s1, filters_lo, 1); - sum = vmlal_lane_s16(sum, s2, filters_lo, 2); - sum = vmlal_lane_s16(sum, s3, filters_lo, 3); - sum = vmlal_lane_s16(sum, s4, filters_hi, 0); - sum = vmlal_lane_s16(sum, s5, filters_hi, 1); - sum = vmlal_lane_s16(sum, s6, filters_hi, 2); - sum = vmlal_lane_s16(sum, s7, filters_hi, 3); - - uint16x4_t res = vqrshrun_n_s32(sum, FILTER_BITS); - return vmin_u16(res, max); -} - -static INLINE uint16x8_t -highbd_convolve8_8(const int16x8_t s0, const int16x8_t s1, const int16x8_t s2, - const int16x8_t s3, const int16x8_t s4, const int16x8_t s5, - const int16x8_t s6, const int16x8_t s7, - const int16x8_t filters, const uint16x8_t max) { - const int16x4_t filters_lo = vget_low_s16(filters); - const int16x4_t filters_hi = vget_high_s16(filters); - - int32x4_t sum0 = vmull_lane_s16(vget_low_s16(s0), filters_lo, 0); - sum0 = vmlal_lane_s16(sum0, vget_low_s16(s1), filters_lo, 1); - sum0 = vmlal_lane_s16(sum0, vget_low_s16(s2), filters_lo, 2); - sum0 = vmlal_lane_s16(sum0, vget_low_s16(s3), filters_lo, 3); - sum0 = vmlal_lane_s16(sum0, vget_low_s16(s4), filters_hi, 0); - sum0 = vmlal_lane_s16(sum0, vget_low_s16(s5), filters_hi, 1); - sum0 = vmlal_lane_s16(sum0, vget_low_s16(s6), filters_hi, 2); - sum0 = vmlal_lane_s16(sum0, vget_low_s16(s7), filters_hi, 3); - - int32x4_t sum1 = vmull_lane_s16(vget_high_s16(s0), filters_lo, 0); - sum1 = vmlal_lane_s16(sum1, vget_high_s16(s1), filters_lo, 1); - sum1 = vmlal_lane_s16(sum1, vget_high_s16(s2), filters_lo, 2); - sum1 = vmlal_lane_s16(sum1, vget_high_s16(s3), filters_lo, 3); - sum1 = vmlal_lane_s16(sum1, vget_high_s16(s4), filters_hi, 0); - sum1 = vmlal_lane_s16(sum1, vget_high_s16(s5), filters_hi, 1); - sum1 = vmlal_lane_s16(sum1, vget_high_s16(s6), filters_hi, 2); - sum1 = vmlal_lane_s16(sum1, vget_high_s16(s7), filters_hi, 3); - - uint16x8_t res = vcombine_u16(vqrshrun_n_s32(sum0, FILTER_BITS), - vqrshrun_n_s32(sum1, FILTER_BITS)); - return vminq_u16(res, max); -} - -static INLINE void highbd_convolve_4tap_horiz_neon( - const uint16_t *src, ptrdiff_t src_stride, uint16_t *dst, - ptrdiff_t dst_stride, int w, int h, const int16x4_t filter, int bd) { - if (w == 4) { - const uint16x4_t max = vdup_n_u16((1 << bd) - 1); - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - - do { - int16x4_t s0[4], s1[4], s2[4], s3[4]; - load_s16_4x4(s + 0 * src_stride, 1, &s0[0], &s0[1], &s0[2], &s0[3]); - load_s16_4x4(s + 1 * src_stride, 1, &s1[0], &s1[1], &s1[2], &s1[3]); - load_s16_4x4(s + 2 * src_stride, 1, &s2[0], &s2[1], &s2[2], &s2[3]); - load_s16_4x4(s + 3 * src_stride, 1, &s3[0], &s3[1], &s3[2], &s3[3]); - - uint16x4_t d0 = - highbd_convolve4_4_neon(s0[0], s0[1], s0[2], s0[3], filter, max); - uint16x4_t d1 = - highbd_convolve4_4_neon(s1[0], s1[1], s1[2], s1[3], filter, max); - uint16x4_t d2 = - highbd_convolve4_4_neon(s2[0], s2[1], s2[2], s2[3], filter, max); - uint16x4_t d3 = - highbd_convolve4_4_neon(s3[0], s3[1], s3[2], s3[3], filter, max); - - store_u16_4x4(d, dst_stride, d0, d1, d2, d3); - - s += 4 * src_stride; - d += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint16x8_t max = vdupq_n_u16((1 << bd) - 1); - - do { - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - int width = w; - - do { - int16x8_t s0[4], s1[4], s2[4], s3[4]; - load_s16_8x4(s + 0 * src_stride, 1, &s0[0], &s0[1], &s0[2], &s0[3]); - load_s16_8x4(s + 1 * src_stride, 1, &s1[0], &s1[1], &s1[2], &s1[3]); - load_s16_8x4(s + 2 * src_stride, 1, &s2[0], &s2[1], &s2[2], &s2[3]); - load_s16_8x4(s + 3 * src_stride, 1, &s3[0], &s3[1], &s3[2], &s3[3]); - - uint16x8_t d0 = - highbd_convolve4_8_neon(s0[0], s0[1], s0[2], s0[3], filter, max); - uint16x8_t d1 = - highbd_convolve4_8_neon(s1[0], s1[1], s1[2], s1[3], filter, max); - uint16x8_t d2 = - highbd_convolve4_8_neon(s2[0], s2[1], s2[2], s2[3], filter, max); - uint16x8_t d3 = - highbd_convolve4_8_neon(s3[0], s3[1], s3[2], s3[3], filter, max); - - store_u16_8x4(d, dst_stride, d0, d1, d2, d3); - - s += 8; - d += 8; - width -= 8; - } while (width != 0); - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } -} - -static INLINE void highbd_convolve_8tap_horiz_neon( - const uint16_t *src, ptrdiff_t src_stride, uint16_t *dst, - ptrdiff_t dst_stride, int w, int h, const int16x8_t filter, int bd) { - if (w == 4) { - const uint16x4_t max = vdup_n_u16((1 << bd) - 1); - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - - do { - int16x4_t s0[8], s1[8], s2[8], s3[8]; - load_s16_4x8(s + 0 * src_stride, 1, &s0[0], &s0[1], &s0[2], &s0[3], - &s0[4], &s0[5], &s0[6], &s0[7]); - load_s16_4x8(s + 1 * src_stride, 1, &s1[0], &s1[1], &s1[2], &s1[3], - &s1[4], &s1[5], &s1[6], &s1[7]); - load_s16_4x8(s + 2 * src_stride, 1, &s2[0], &s2[1], &s2[2], &s2[3], - &s2[4], &s2[5], &s2[6], &s2[7]); - load_s16_4x8(s + 3 * src_stride, 1, &s3[0], &s3[1], &s3[2], &s3[3], - &s3[4], &s3[5], &s3[6], &s3[7]); - - uint16x4_t d0 = highbd_convolve8_4(s0[0], s0[1], s0[2], s0[3], s0[4], - s0[5], s0[6], s0[7], filter, max); - uint16x4_t d1 = highbd_convolve8_4(s1[0], s1[1], s1[2], s1[3], s1[4], - s1[5], s1[6], s1[7], filter, max); - uint16x4_t d2 = highbd_convolve8_4(s2[0], s2[1], s2[2], s2[3], s2[4], - s2[5], s2[6], s2[7], filter, max); - uint16x4_t d3 = highbd_convolve8_4(s3[0], s3[1], s3[2], s3[3], s3[4], - s3[5], s3[6], s3[7], filter, max); - - store_u16_4x4(d, dst_stride, d0, d1, d2, d3); - - s += 4 * src_stride; - d += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint16x8_t max = vdupq_n_u16((1 << bd) - 1); - - do { - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - int width = w; - - do { - int16x8_t s0[8], s1[8], s2[8], s3[8]; - load_s16_8x8(s + 0 * src_stride, 1, &s0[0], &s0[1], &s0[2], &s0[3], - &s0[4], &s0[5], &s0[6], &s0[7]); - load_s16_8x8(s + 1 * src_stride, 1, &s1[0], &s1[1], &s1[2], &s1[3], - &s1[4], &s1[5], &s1[6], &s1[7]); - load_s16_8x8(s + 2 * src_stride, 1, &s2[0], &s2[1], &s2[2], &s2[3], - &s2[4], &s2[5], &s2[6], &s2[7]); - load_s16_8x8(s + 3 * src_stride, 1, &s3[0], &s3[1], &s3[2], &s3[3], - &s3[4], &s3[5], &s3[6], &s3[7]); - - uint16x8_t d0 = highbd_convolve8_8(s0[0], s0[1], s0[2], s0[3], s0[4], - s0[5], s0[6], s0[7], filter, max); - uint16x8_t d1 = highbd_convolve8_8(s1[0], s1[1], s1[2], s1[3], s1[4], - s1[5], s1[6], s1[7], filter, max); - uint16x8_t d2 = highbd_convolve8_8(s2[0], s2[1], s2[2], s2[3], s2[4], - s2[5], s2[6], s2[7], filter, max); - uint16x8_t d3 = highbd_convolve8_8(s3[0], s3[1], s3[2], s3[3], s3[4], - s3[5], s3[6], s3[7], filter, max); - - store_u16_8x4(d, dst_stride, d0, d1, d2, d3); - - s += 8; - d += 8; - width -= 8; - } while (width != 0); - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } -} - -void vpx_highbd_convolve8_horiz_neon(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd) { - if (x_step_q4 != 16) { - vpx_highbd_convolve8_horiz_c(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h, bd); - return; - } - - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - assert(x_step_q4 == 16); - - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - if (vpx_get_filter_taps(filter[x0_q4]) <= 4) { - const int16x4_t x_filter_4tap = vld1_s16(filter[x0_q4] + 2); - highbd_convolve_4tap_horiz_neon(src - 1, src_stride, dst, dst_stride, w, h, - x_filter_4tap, bd); - } else { - const int16x8_t x_filter_8tap = vld1q_s16(filter[x0_q4]); - highbd_convolve_8tap_horiz_neon(src - 3, src_stride, dst, dst_stride, w, h, - x_filter_8tap, bd); - } -} - -void vpx_highbd_convolve8_avg_horiz_neon(const uint16_t *src, - ptrdiff_t src_stride, uint16_t *dst, - ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, - int y_step_q4, int w, int h, int bd) { - if (x_step_q4 != 16) { - vpx_highbd_convolve8_avg_horiz_c(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h, - bd); - return; - } - - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - - const int16x8_t filters = vld1q_s16(filter[x0_q4]); - - src -= 3; - - if (w == 4) { - const uint16x4_t max = vdup_n_u16((1 << bd) - 1); - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - - do { - int16x4_t s0[8], s1[8], s2[8], s3[8]; - load_s16_4x8(s + 0 * src_stride, 1, &s0[0], &s0[1], &s0[2], &s0[3], - &s0[4], &s0[5], &s0[6], &s0[7]); - load_s16_4x8(s + 1 * src_stride, 1, &s1[0], &s1[1], &s1[2], &s1[3], - &s1[4], &s1[5], &s1[6], &s1[7]); - load_s16_4x8(s + 2 * src_stride, 1, &s2[0], &s2[1], &s2[2], &s2[3], - &s2[4], &s2[5], &s2[6], &s2[7]); - load_s16_4x8(s + 3 * src_stride, 1, &s3[0], &s3[1], &s3[2], &s3[3], - &s3[4], &s3[5], &s3[6], &s3[7]); - - uint16x4_t d0 = highbd_convolve8_4(s0[0], s0[1], s0[2], s0[3], s0[4], - s0[5], s0[6], s0[7], filters, max); - uint16x4_t d1 = highbd_convolve8_4(s1[0], s1[1], s1[2], s1[3], s1[4], - s1[5], s1[6], s1[7], filters, max); - uint16x4_t d2 = highbd_convolve8_4(s2[0], s2[1], s2[2], s2[3], s2[4], - s2[5], s2[6], s2[7], filters, max); - uint16x4_t d3 = highbd_convolve8_4(s3[0], s3[1], s3[2], s3[3], s3[4], - s3[5], s3[6], s3[7], filters, max); - - d0 = vrhadd_u16(d0, vld1_u16(d + 0 * dst_stride)); - d1 = vrhadd_u16(d1, vld1_u16(d + 1 * dst_stride)); - d2 = vrhadd_u16(d2, vld1_u16(d + 2 * dst_stride)); - d3 = vrhadd_u16(d3, vld1_u16(d + 3 * dst_stride)); - - store_u16_4x4(d, dst_stride, d0, d1, d2, d3); - - s += 4 * src_stride; - d += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint16x8_t max = vdupq_n_u16((1 << bd) - 1); - - do { - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - int width = w; - - do { - int16x8_t s0[8], s1[8], s2[8], s3[8]; - load_s16_8x8(s + 0 * src_stride, 1, &s0[0], &s0[1], &s0[2], &s0[3], - &s0[4], &s0[5], &s0[6], &s0[7]); - load_s16_8x8(s + 1 * src_stride, 1, &s1[0], &s1[1], &s1[2], &s1[3], - &s1[4], &s1[5], &s1[6], &s1[7]); - load_s16_8x8(s + 2 * src_stride, 1, &s2[0], &s2[1], &s2[2], &s2[3], - &s2[4], &s2[5], &s2[6], &s2[7]); - load_s16_8x8(s + 3 * src_stride, 1, &s3[0], &s3[1], &s3[2], &s3[3], - &s3[4], &s3[5], &s3[6], &s3[7]); - - uint16x8_t d0 = highbd_convolve8_8(s0[0], s0[1], s0[2], s0[3], s0[4], - s0[5], s0[6], s0[7], filters, max); - uint16x8_t d1 = highbd_convolve8_8(s1[0], s1[1], s1[2], s1[3], s1[4], - s1[5], s1[6], s1[7], filters, max); - uint16x8_t d2 = highbd_convolve8_8(s2[0], s2[1], s2[2], s2[3], s2[4], - s2[5], s2[6], s2[7], filters, max); - uint16x8_t d3 = highbd_convolve8_8(s3[0], s3[1], s3[2], s3[3], s3[4], - s3[5], s3[6], s3[7], filters, max); - - d0 = vrhaddq_u16(d0, vld1q_u16(d + 0 * dst_stride)); - d1 = vrhaddq_u16(d1, vld1q_u16(d + 1 * dst_stride)); - d2 = vrhaddq_u16(d2, vld1q_u16(d + 2 * dst_stride)); - d3 = vrhaddq_u16(d3, vld1q_u16(d + 3 * dst_stride)); - - store_u16_8x4(d, dst_stride, d0, d1, d2, d3); - - s += 8; - d += 8; - width -= 8; - } while (width != 0); - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } -} - -static INLINE void highbd_convolve_4tap_vert_neon( - const uint16_t *src, ptrdiff_t src_stride, uint16_t *dst, - ptrdiff_t dst_stride, int w, int h, const int16x4_t filter, int bd) { - if (w == 4) { - const uint16x4_t max = vdup_n_u16((1 << bd) - 1); - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - - int16x4_t s0, s1, s2; - load_s16_4x3(s, src_stride, &s0, &s1, &s2); - - s += 3 * src_stride; - - do { - int16x4_t s3, s4, s5, s6; - load_s16_4x4(s, src_stride, &s3, &s4, &s5, &s6); - - uint16x4_t d0 = highbd_convolve4_4_neon(s0, s1, s2, s3, filter, max); - uint16x4_t d1 = highbd_convolve4_4_neon(s1, s2, s3, s4, filter, max); - uint16x4_t d2 = highbd_convolve4_4_neon(s2, s3, s4, s5, filter, max); - uint16x4_t d3 = highbd_convolve4_4_neon(s3, s4, s5, s6, filter, max); - - store_u16_4x4(d, dst_stride, d0, d1, d2, d3); - - s0 = s4; - s1 = s5; - s2 = s6; - s += 4 * src_stride; - d += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint16x8_t max = vdupq_n_u16((1 << bd) - 1); - - do { - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - int height = h; - - int16x8_t s0, s1, s2; - load_s16_8x3(s, src_stride, &s0, &s1, &s2); - - s += 3 * src_stride; - - do { - int16x8_t s3, s4, s5, s6; - load_s16_8x4(s, src_stride, &s3, &s4, &s5, &s6); - - uint16x8_t d0 = highbd_convolve4_8_neon(s0, s1, s2, s3, filter, max); - uint16x8_t d1 = highbd_convolve4_8_neon(s1, s2, s3, s4, filter, max); - uint16x8_t d2 = highbd_convolve4_8_neon(s2, s3, s4, s5, filter, max); - uint16x8_t d3 = highbd_convolve4_8_neon(s3, s4, s5, s6, filter, max); - - store_u16_8x4(d, dst_stride, d0, d1, d2, d3); - - s0 = s4; - s1 = s5; - s2 = s6; - s += 4 * src_stride; - d += 4 * dst_stride; - height -= 4; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); - } -} - -static INLINE void highbd_convolve_8tap_vert_neon( - const uint16_t *src, ptrdiff_t src_stride, uint16_t *dst, - ptrdiff_t dst_stride, int w, int h, const int16x8_t filter, int bd) { - if (w == 4) { - const uint16x4_t max = vdup_n_u16((1 << bd) - 1); - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - - int16x4_t s0, s1, s2, s3, s4, s5, s6; - load_s16_4x7(s, src_stride, &s0, &s1, &s2, &s3, &s4, &s5, &s6); - - s += 7 * src_stride; - - do { - int16x4_t s7, s8, s9, s10; - load_s16_4x4(s, src_stride, &s7, &s8, &s9, &s10); - - uint16x4_t d0 = - highbd_convolve8_4(s0, s1, s2, s3, s4, s5, s6, s7, filter, max); - uint16x4_t d1 = - highbd_convolve8_4(s1, s2, s3, s4, s5, s6, s7, s8, filter, max); - uint16x4_t d2 = - highbd_convolve8_4(s2, s3, s4, s5, s6, s7, s8, s9, filter, max); - uint16x4_t d3 = - highbd_convolve8_4(s3, s4, s5, s6, s7, s8, s9, s10, filter, max); - - store_u16_4x4(d, dst_stride, d0, d1, d2, d3); - - s0 = s4; - s1 = s5; - s2 = s6; - s3 = s7; - s4 = s8; - s5 = s9; - s6 = s10; - s += 4 * src_stride; - d += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint16x8_t max = vdupq_n_u16((1 << bd) - 1); - - do { - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - int height = h; - - int16x8_t s0, s1, s2, s3, s4, s5, s6; - load_s16_8x7(s, src_stride, &s0, &s1, &s2, &s3, &s4, &s5, &s6); - - s += 7 * src_stride; - - do { - int16x8_t s7, s8, s9, s10; - load_s16_8x4(s, src_stride, &s7, &s8, &s9, &s10); - - uint16x8_t d0 = - highbd_convolve8_8(s0, s1, s2, s3, s4, s5, s6, s7, filter, max); - uint16x8_t d1 = - highbd_convolve8_8(s1, s2, s3, s4, s5, s6, s7, s8, filter, max); - uint16x8_t d2 = - highbd_convolve8_8(s2, s3, s4, s5, s6, s7, s8, s9, filter, max); - uint16x8_t d3 = - highbd_convolve8_8(s3, s4, s5, s6, s7, s8, s9, s10, filter, max); - - store_u16_8x4(d, dst_stride, d0, d1, d2, d3); - - s0 = s4; - s1 = s5; - s2 = s6; - s3 = s7; - s4 = s8; - s5 = s9; - s6 = s10; - s += 4 * src_stride; - d += 4 * dst_stride; - height -= 4; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); - } -} - -void vpx_highbd_convolve8_vert_neon(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd) { - if (y_step_q4 != 16) { - vpx_highbd_convolve8_vert_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h, bd); - return; - } - - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - assert(y_step_q4 == 16); - - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - if (vpx_get_filter_taps(filter[y0_q4]) <= 4) { - const int16x4_t y_filter_4tap = vld1_s16(filter[y0_q4] + 2); - highbd_convolve_4tap_vert_neon(src - src_stride, src_stride, dst, - dst_stride, w, h, y_filter_4tap, bd); - } else { - const int16x8_t y_filter_8tap = vld1q_s16(filter[y0_q4]); - highbd_convolve_8tap_vert_neon(src - 3 * src_stride, src_stride, dst, - dst_stride, w, h, y_filter_8tap, bd); - } -} - -void vpx_highbd_convolve8_avg_vert_neon(const uint16_t *src, - ptrdiff_t src_stride, uint16_t *dst, - ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd) { - if (y_step_q4 != 16) { - vpx_highbd_convolve8_avg_vert_c(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h, - bd); - return; - } - - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - - const int16x8_t filters = vld1q_s16(filter[y0_q4]); - - src -= 3 * src_stride; - - if (w == 4) { - const uint16x4_t max = vdup_n_u16((1 << bd) - 1); - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - - int16x4_t s0, s1, s2, s3, s4, s5, s6; - load_s16_4x7(s, src_stride, &s0, &s1, &s2, &s3, &s4, &s5, &s6); - - s += 7 * src_stride; - - do { - int16x4_t s7, s8, s9, s10; - load_s16_4x4(s, src_stride, &s7, &s8, &s9, &s10); - - uint16x4_t d0 = - highbd_convolve8_4(s0, s1, s2, s3, s4, s5, s6, s7, filters, max); - uint16x4_t d1 = - highbd_convolve8_4(s1, s2, s3, s4, s5, s6, s7, s8, filters, max); - uint16x4_t d2 = - highbd_convolve8_4(s2, s3, s4, s5, s6, s7, s8, s9, filters, max); - uint16x4_t d3 = - highbd_convolve8_4(s3, s4, s5, s6, s7, s8, s9, s10, filters, max); - - d0 = vrhadd_u16(d0, vld1_u16(d + 0 * dst_stride)); - d1 = vrhadd_u16(d1, vld1_u16(d + 1 * dst_stride)); - d2 = vrhadd_u16(d2, vld1_u16(d + 2 * dst_stride)); - d3 = vrhadd_u16(d3, vld1_u16(d + 3 * dst_stride)); - - store_u16_4x4(d, dst_stride, d0, d1, d2, d3); - - s0 = s4; - s1 = s5; - s2 = s6; - s3 = s7; - s4 = s8; - s5 = s9; - s6 = s10; - s += 4 * src_stride; - d += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint16x8_t max = vdupq_n_u16((1 << bd) - 1); - - do { - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - int height = h; - - int16x8_t s0, s1, s2, s3, s4, s5, s6; - load_s16_8x7(s, src_stride, &s0, &s1, &s2, &s3, &s4, &s5, &s6); - - s += 7 * src_stride; - - do { - int16x8_t s7, s8, s9, s10; - load_s16_8x4(s, src_stride, &s7, &s8, &s9, &s10); - - uint16x8_t d0 = - highbd_convolve8_8(s0, s1, s2, s3, s4, s5, s6, s7, filters, max); - uint16x8_t d1 = - highbd_convolve8_8(s1, s2, s3, s4, s5, s6, s7, s8, filters, max); - uint16x8_t d2 = - highbd_convolve8_8(s2, s3, s4, s5, s6, s7, s8, s9, filters, max); - uint16x8_t d3 = - highbd_convolve8_8(s3, s4, s5, s6, s7, s8, s9, s10, filters, max); - - d0 = vrhaddq_u16(d0, vld1q_u16(d + 0 * dst_stride)); - d1 = vrhaddq_u16(d1, vld1q_u16(d + 1 * dst_stride)); - d2 = vrhaddq_u16(d2, vld1q_u16(d + 2 * dst_stride)); - d3 = vrhaddq_u16(d3, vld1q_u16(d + 3 * dst_stride)); - - store_u16_8x4(d, dst_stride, d0, d1, d2, d3); - - s0 = s4; - s1 = s5; - s2 = s6; - s3 = s7; - s4 = s8; - s5 = s9; - s6 = s10; - s += 4 * src_stride; - d += 4 * dst_stride; - height -= 4; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); - } -} - -static INLINE void highbd_convolve_2d_4tap_neon( - const uint16_t *src, ptrdiff_t src_stride, uint16_t *dst, - ptrdiff_t dst_stride, int w, int h, const int16x4_t x_filter, - const int16x4_t y_filter, int bd) { - if (w == 4) { - const uint16x4_t max = vdup_n_u16((1 << bd) - 1); - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - - int16x4_t h_s0[4], h_s1[4], h_s2[4]; - load_s16_4x4(s + 0 * src_stride, 1, &h_s0[0], &h_s0[1], &h_s0[2], &h_s0[3]); - load_s16_4x4(s + 1 * src_stride, 1, &h_s1[0], &h_s1[1], &h_s1[2], &h_s1[3]); - load_s16_4x4(s + 2 * src_stride, 1, &h_s2[0], &h_s2[1], &h_s2[2], &h_s2[3]); - - int16x4_t v_s0 = vreinterpret_s16_u16(highbd_convolve4_4_neon( - h_s0[0], h_s0[1], h_s0[2], h_s0[3], x_filter, max)); - int16x4_t v_s1 = vreinterpret_s16_u16(highbd_convolve4_4_neon( - h_s1[0], h_s1[1], h_s1[2], h_s1[3], x_filter, max)); - int16x4_t v_s2 = vreinterpret_s16_u16(highbd_convolve4_4_neon( - h_s2[0], h_s2[1], h_s2[2], h_s2[3], x_filter, max)); - - s += 3 * src_stride; - - do { - int16x4_t h_s3[4], h_s4[4], h_s5[4], h_s6[4]; - load_s16_4x4(s + 0 * src_stride, 1, &h_s3[0], &h_s3[1], &h_s3[2], - &h_s3[3]); - load_s16_4x4(s + 1 * src_stride, 1, &h_s4[0], &h_s4[1], &h_s4[2], - &h_s4[3]); - load_s16_4x4(s + 2 * src_stride, 1, &h_s5[0], &h_s5[1], &h_s5[2], - &h_s5[3]); - load_s16_4x4(s + 3 * src_stride, 1, &h_s6[0], &h_s6[1], &h_s6[2], - &h_s6[3]); - - int16x4_t v_s3 = vreinterpret_s16_u16(highbd_convolve4_4_neon( - h_s3[0], h_s3[1], h_s3[2], h_s3[3], x_filter, max)); - int16x4_t v_s4 = vreinterpret_s16_u16(highbd_convolve4_4_neon( - h_s4[0], h_s4[1], h_s4[2], h_s4[3], x_filter, max)); - int16x4_t v_s5 = vreinterpret_s16_u16(highbd_convolve4_4_neon( - h_s5[0], h_s5[1], h_s5[2], h_s5[3], x_filter, max)); - int16x4_t v_s6 = vreinterpret_s16_u16(highbd_convolve4_4_neon( - h_s6[0], h_s6[1], h_s6[2], h_s6[3], x_filter, max)); - - uint16x4_t d0 = - highbd_convolve4_4_neon(v_s0, v_s1, v_s2, v_s3, y_filter, max); - uint16x4_t d1 = - highbd_convolve4_4_neon(v_s1, v_s2, v_s3, v_s4, y_filter, max); - uint16x4_t d2 = - highbd_convolve4_4_neon(v_s2, v_s3, v_s4, v_s5, y_filter, max); - uint16x4_t d3 = - highbd_convolve4_4_neon(v_s3, v_s4, v_s5, v_s6, y_filter, max); - - store_u16_4x4(d, dst_stride, d0, d1, d2, d3); - - v_s0 = v_s4; - v_s1 = v_s5; - v_s2 = v_s6; - s += 4 * src_stride; - d += 4 * dst_stride; - h -= 4; - } while (h != 0); - - return; - } - - const uint16x8_t max = vdupq_n_u16((1 << bd) - 1); - - do { - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - int height = h; - - int16x8_t h_s0[4], h_s1[4], h_s2[4]; - load_s16_8x4(s + 0 * src_stride, 1, &h_s0[0], &h_s0[1], &h_s0[2], &h_s0[3]); - load_s16_8x4(s + 1 * src_stride, 1, &h_s1[0], &h_s1[1], &h_s1[2], &h_s1[3]); - load_s16_8x4(s + 2 * src_stride, 1, &h_s2[0], &h_s2[1], &h_s2[2], &h_s2[3]); - - int16x8_t v_s0 = vreinterpretq_s16_u16(highbd_convolve4_8_neon( - h_s0[0], h_s0[1], h_s0[2], h_s0[3], x_filter, max)); - int16x8_t v_s1 = vreinterpretq_s16_u16(highbd_convolve4_8_neon( - h_s1[0], h_s1[1], h_s1[2], h_s1[3], x_filter, max)); - int16x8_t v_s2 = vreinterpretq_s16_u16(highbd_convolve4_8_neon( - h_s2[0], h_s2[1], h_s2[2], h_s2[3], x_filter, max)); - - s += 3 * src_stride; - - do { - int16x8_t h_s3[4], h_s4[4], h_s5[4], h_s6[4]; - load_s16_8x4(s + 0 * src_stride, 1, &h_s3[0], &h_s3[1], &h_s3[2], - &h_s3[3]); - load_s16_8x4(s + 1 * src_stride, 1, &h_s4[0], &h_s4[1], &h_s4[2], - &h_s4[3]); - load_s16_8x4(s + 2 * src_stride, 1, &h_s5[0], &h_s5[1], &h_s5[2], - &h_s5[3]); - load_s16_8x4(s + 3 * src_stride, 1, &h_s6[0], &h_s6[1], &h_s6[2], - &h_s6[3]); - - int16x8_t v_s3 = vreinterpretq_s16_u16(highbd_convolve4_8_neon( - h_s3[0], h_s3[1], h_s3[2], h_s3[3], x_filter, max)); - int16x8_t v_s4 = vreinterpretq_s16_u16(highbd_convolve4_8_neon( - h_s4[0], h_s4[1], h_s4[2], h_s4[3], x_filter, max)); - int16x8_t v_s5 = vreinterpretq_s16_u16(highbd_convolve4_8_neon( - h_s5[0], h_s5[1], h_s5[2], h_s5[3], x_filter, max)); - int16x8_t v_s6 = vreinterpretq_s16_u16(highbd_convolve4_8_neon( - h_s6[0], h_s6[1], h_s6[2], h_s6[3], x_filter, max)); - - uint16x8_t d0 = - highbd_convolve4_8_neon(v_s0, v_s1, v_s2, v_s3, y_filter, max); - uint16x8_t d1 = - highbd_convolve4_8_neon(v_s1, v_s2, v_s3, v_s4, y_filter, max); - uint16x8_t d2 = - highbd_convolve4_8_neon(v_s2, v_s3, v_s4, v_s5, y_filter, max); - uint16x8_t d3 = - highbd_convolve4_8_neon(v_s3, v_s4, v_s5, v_s6, y_filter, max); - - store_u16_8x4(d, dst_stride, d0, d1, d2, d3); - - v_s0 = v_s4; - v_s1 = v_s5; - v_s2 = v_s6; - s += 4 * src_stride; - d += 4 * dst_stride; - height -= 4; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); -} - -static INLINE void highbd_convolve_2d_8tap_neon( - const uint16_t *src, ptrdiff_t src_stride, uint16_t *dst, - ptrdiff_t dst_stride, int w, int h, const int16x8_t x_filter, - const int16x8_t y_filter, int bd) { - if (w == 4) { - const uint16x4_t max = vdup_n_u16((1 << bd) - 1); - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - - int16x4_t h_s0[8], h_s1[8], h_s2[8], h_s3[8], h_s4[8], h_s5[8], h_s6[8]; - load_s16_4x8(s + 0 * src_stride, 1, &h_s0[0], &h_s0[1], &h_s0[2], &h_s0[3], - &h_s0[4], &h_s0[5], &h_s0[6], &h_s0[7]); - load_s16_4x8(s + 1 * src_stride, 1, &h_s1[0], &h_s1[1], &h_s1[2], &h_s1[3], - &h_s1[4], &h_s1[5], &h_s1[6], &h_s1[7]); - load_s16_4x8(s + 2 * src_stride, 1, &h_s2[0], &h_s2[1], &h_s2[2], &h_s2[3], - &h_s2[4], &h_s2[5], &h_s2[6], &h_s2[7]); - load_s16_4x8(s + 3 * src_stride, 1, &h_s3[0], &h_s3[1], &h_s3[2], &h_s3[3], - &h_s3[4], &h_s3[5], &h_s3[6], &h_s3[7]); - load_s16_4x8(s + 4 * src_stride, 1, &h_s4[0], &h_s4[1], &h_s4[2], &h_s4[3], - &h_s4[4], &h_s4[5], &h_s4[6], &h_s4[7]); - load_s16_4x8(s + 5 * src_stride, 1, &h_s5[0], &h_s5[1], &h_s5[2], &h_s5[3], - &h_s5[4], &h_s5[5], &h_s5[6], &h_s5[7]); - load_s16_4x8(s + 6 * src_stride, 1, &h_s6[0], &h_s6[1], &h_s6[2], &h_s6[3], - &h_s6[4], &h_s6[5], &h_s6[6], &h_s6[7]); - - int16x4_t v_s0 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s0[0], h_s0[1], h_s0[2], h_s0[3], h_s0[4], h_s0[5], - h_s0[6], h_s0[7], x_filter, max)); - int16x4_t v_s1 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s1[0], h_s1[1], h_s1[2], h_s1[3], h_s1[4], h_s1[5], - h_s1[6], h_s1[7], x_filter, max)); - int16x4_t v_s2 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s2[0], h_s2[1], h_s2[2], h_s2[3], h_s2[4], h_s2[5], - h_s2[6], h_s2[7], x_filter, max)); - int16x4_t v_s3 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s3[0], h_s3[1], h_s3[2], h_s3[3], h_s3[4], h_s3[5], - h_s3[6], h_s3[7], x_filter, max)); - int16x4_t v_s4 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s4[0], h_s4[1], h_s4[2], h_s4[3], h_s4[4], h_s4[5], - h_s4[6], h_s4[7], x_filter, max)); - int16x4_t v_s5 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s5[0], h_s5[1], h_s5[2], h_s5[3], h_s5[4], h_s5[5], - h_s5[6], h_s5[7], x_filter, max)); - int16x4_t v_s6 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s6[0], h_s6[1], h_s6[2], h_s6[3], h_s6[4], h_s6[5], - h_s6[6], h_s6[7], x_filter, max)); - - s += 7 * src_stride; - - do { - int16x4_t h_s7[8], h_s8[8], h_s9[8], h_s10[8]; - load_s16_4x8(s + 0 * src_stride, 1, &h_s7[0], &h_s7[1], &h_s7[2], - &h_s7[3], &h_s7[4], &h_s7[5], &h_s7[6], &h_s7[7]); - load_s16_4x8(s + 1 * src_stride, 1, &h_s8[0], &h_s8[1], &h_s8[2], - &h_s8[3], &h_s8[4], &h_s8[5], &h_s8[6], &h_s8[7]); - load_s16_4x8(s + 2 * src_stride, 1, &h_s9[0], &h_s9[1], &h_s9[2], - &h_s9[3], &h_s9[4], &h_s9[5], &h_s9[6], &h_s9[7]); - load_s16_4x8(s + 3 * src_stride, 1, &h_s10[0], &h_s10[1], &h_s10[2], - &h_s10[3], &h_s10[4], &h_s10[5], &h_s10[6], &h_s10[7]); - - int16x4_t v_s7 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s7[0], h_s7[1], h_s7[2], h_s7[3], h_s7[4], - h_s7[5], h_s7[6], h_s7[7], x_filter, max)); - int16x4_t v_s8 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s8[0], h_s8[1], h_s8[2], h_s8[3], h_s8[4], - h_s8[5], h_s8[6], h_s8[7], x_filter, max)); - int16x4_t v_s9 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s9[0], h_s9[1], h_s9[2], h_s9[3], h_s9[4], - h_s9[5], h_s9[6], h_s9[7], x_filter, max)); - int16x4_t v_s10 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s10[0], h_s10[1], h_s10[2], h_s10[3], h_s10[4], - h_s10[5], h_s10[6], h_s10[7], x_filter, max)); - - uint16x4_t d0 = highbd_convolve8_4(v_s0, v_s1, v_s2, v_s3, v_s4, v_s5, - v_s6, v_s7, y_filter, max); - uint16x4_t d1 = highbd_convolve8_4(v_s1, v_s2, v_s3, v_s4, v_s5, v_s6, - v_s7, v_s8, y_filter, max); - uint16x4_t d2 = highbd_convolve8_4(v_s2, v_s3, v_s4, v_s5, v_s6, v_s7, - v_s8, v_s9, y_filter, max); - uint16x4_t d3 = highbd_convolve8_4(v_s3, v_s4, v_s5, v_s6, v_s7, v_s8, - v_s9, v_s10, y_filter, max); - - store_u16_4x4(d, dst_stride, d0, d1, d2, d3); - - v_s0 = v_s4; - v_s1 = v_s5; - v_s2 = v_s6; - v_s3 = v_s7; - v_s4 = v_s8; - v_s5 = v_s9; - v_s6 = v_s10; - s += 4 * src_stride; - d += 4 * dst_stride; - h -= 4; - } while (h != 0); - - return; - } - - const uint16x8_t max = vdupq_n_u16((1 << bd) - 1); - - do { - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - int height = h; - - int16x8_t h_s0[8], h_s1[8], h_s2[8], h_s3[8], h_s4[8], h_s5[8], h_s6[8]; - load_s16_8x8(s + 0 * src_stride, 1, &h_s0[0], &h_s0[1], &h_s0[2], &h_s0[3], - &h_s0[4], &h_s0[5], &h_s0[6], &h_s0[7]); - load_s16_8x8(s + 1 * src_stride, 1, &h_s1[0], &h_s1[1], &h_s1[2], &h_s1[3], - &h_s1[4], &h_s1[5], &h_s1[6], &h_s1[7]); - load_s16_8x8(s + 2 * src_stride, 1, &h_s2[0], &h_s2[1], &h_s2[2], &h_s2[3], - &h_s2[4], &h_s2[5], &h_s2[6], &h_s2[7]); - load_s16_8x8(s + 3 * src_stride, 1, &h_s3[0], &h_s3[1], &h_s3[2], &h_s3[3], - &h_s3[4], &h_s3[5], &h_s3[6], &h_s3[7]); - load_s16_8x8(s + 4 * src_stride, 1, &h_s4[0], &h_s4[1], &h_s4[2], &h_s4[3], - &h_s4[4], &h_s4[5], &h_s4[6], &h_s4[7]); - load_s16_8x8(s + 5 * src_stride, 1, &h_s5[0], &h_s5[1], &h_s5[2], &h_s5[3], - &h_s5[4], &h_s5[5], &h_s5[6], &h_s5[7]); - load_s16_8x8(s + 6 * src_stride, 1, &h_s6[0], &h_s6[1], &h_s6[2], &h_s6[3], - &h_s6[4], &h_s6[5], &h_s6[6], &h_s6[7]); - - int16x8_t v_s0 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s0[0], h_s0[1], h_s0[2], h_s0[3], h_s0[4], h_s0[5], - h_s0[6], h_s0[7], x_filter, max)); - int16x8_t v_s1 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s1[0], h_s1[1], h_s1[2], h_s1[3], h_s1[4], h_s1[5], - h_s1[6], h_s1[7], x_filter, max)); - int16x8_t v_s2 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s2[0], h_s2[1], h_s2[2], h_s2[3], h_s2[4], h_s2[5], - h_s2[6], h_s2[7], x_filter, max)); - int16x8_t v_s3 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s3[0], h_s3[1], h_s3[2], h_s3[3], h_s3[4], h_s3[5], - h_s3[6], h_s3[7], x_filter, max)); - int16x8_t v_s4 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s4[0], h_s4[1], h_s4[2], h_s4[3], h_s4[4], h_s4[5], - h_s4[6], h_s4[7], x_filter, max)); - int16x8_t v_s5 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s5[0], h_s5[1], h_s5[2], h_s5[3], h_s5[4], h_s5[5], - h_s5[6], h_s5[7], x_filter, max)); - int16x8_t v_s6 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s6[0], h_s6[1], h_s6[2], h_s6[3], h_s6[4], h_s6[5], - h_s6[6], h_s6[7], x_filter, max)); - - s += 7 * src_stride; - - do { - int16x8_t h_s7[8], h_s8[8], h_s9[8], h_s10[8]; - load_s16_8x8(s + 0 * src_stride, 1, &h_s7[0], &h_s7[1], &h_s7[2], - &h_s7[3], &h_s7[4], &h_s7[5], &h_s7[6], &h_s7[7]); - load_s16_8x8(s + 1 * src_stride, 1, &h_s8[0], &h_s8[1], &h_s8[2], - &h_s8[3], &h_s8[4], &h_s8[5], &h_s8[6], &h_s8[7]); - load_s16_8x8(s + 2 * src_stride, 1, &h_s9[0], &h_s9[1], &h_s9[2], - &h_s9[3], &h_s9[4], &h_s9[5], &h_s9[6], &h_s9[7]); - load_s16_8x8(s + 3 * src_stride, 1, &h_s10[0], &h_s10[1], &h_s10[2], - &h_s10[3], &h_s10[4], &h_s10[5], &h_s10[6], &h_s10[7]); - - int16x8_t v_s7 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s7[0], h_s7[1], h_s7[2], h_s7[3], h_s7[4], - h_s7[5], h_s7[6], h_s7[7], x_filter, max)); - int16x8_t v_s8 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s8[0], h_s8[1], h_s8[2], h_s8[3], h_s8[4], - h_s8[5], h_s8[6], h_s8[7], x_filter, max)); - int16x8_t v_s9 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s9[0], h_s9[1], h_s9[2], h_s9[3], h_s9[4], - h_s9[5], h_s9[6], h_s9[7], x_filter, max)); - int16x8_t v_s10 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s10[0], h_s10[1], h_s10[2], h_s10[3], h_s10[4], - h_s10[5], h_s10[6], h_s10[7], x_filter, max)); - - uint16x8_t d0 = highbd_convolve8_8(v_s0, v_s1, v_s2, v_s3, v_s4, v_s5, - v_s6, v_s7, y_filter, max); - uint16x8_t d1 = highbd_convolve8_8(v_s1, v_s2, v_s3, v_s4, v_s5, v_s6, - v_s7, v_s8, y_filter, max); - uint16x8_t d2 = highbd_convolve8_8(v_s2, v_s3, v_s4, v_s5, v_s6, v_s7, - v_s8, v_s9, y_filter, max); - uint16x8_t d3 = highbd_convolve8_8(v_s3, v_s4, v_s5, v_s6, v_s7, v_s8, - v_s9, v_s10, y_filter, max); - - store_u16_8x4(d, dst_stride, d0, d1, d2, d3); - - v_s0 = v_s4; - v_s1 = v_s5; - v_s2 = v_s6; - v_s3 = v_s7; - v_s4 = v_s8; - v_s5 = v_s9; - v_s6 = v_s10; - s += 4 * src_stride; - d += 4 * dst_stride; - height -= 4; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); -} - -void vpx_highbd_convolve8_neon(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h, int bd) { - if (x_step_q4 != 16 || y_step_q4 != 16) { - vpx_highbd_convolve8_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h, bd); - return; - } - - const int x_filter_taps = vpx_get_filter_taps(filter[x0_q4]) <= 4 ? 4 : 8; - const int y_filter_taps = vpx_get_filter_taps(filter[y0_q4]) <= 4 ? 4 : 8; - // Account for needing filter_taps / 2 - 1 lines prior and filter_taps / 2 - // lines post both horizontally and vertically. - const ptrdiff_t horiz_offset = x_filter_taps / 2 - 1; - const ptrdiff_t vert_offset = (y_filter_taps / 2 - 1) * src_stride; - - if (x_filter_taps == 4 && y_filter_taps == 4) { - const int16x4_t x_filter = vld1_s16(filter[x0_q4] + 2); - const int16x4_t y_filter = vld1_s16(filter[y0_q4] + 2); - - highbd_convolve_2d_4tap_neon(src - horiz_offset - vert_offset, src_stride, - dst, dst_stride, w, h, x_filter, y_filter, bd); - return; - } - - const int16x8_t x_filter = vld1q_s16(filter[x0_q4]); - const int16x8_t y_filter = vld1q_s16(filter[y0_q4]); - - highbd_convolve_2d_8tap_neon(src - horiz_offset - vert_offset, src_stride, - dst, dst_stride, w, h, x_filter, y_filter, bd); -} - -void vpx_highbd_convolve8_avg_neon(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd) { - if (x_step_q4 != 16 || y_step_q4 != 16) { - vpx_highbd_convolve8_avg_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h, bd); - return; - } - - // Averaging convolution always uses an 8-tap filter. - const ptrdiff_t horiz_offset = SUBPEL_TAPS / 2 - 1; - const ptrdiff_t vert_offset = (SUBPEL_TAPS / 2 - 1) * src_stride; - // Account for needing SUBPEL_TAPS / 2 - 1 lines prior and SUBPEL_TAPS / 2 - // lines post both horizontally and vertically. - src = src - horiz_offset - vert_offset; - - const int16x8_t x_filter = vld1q_s16(filter[x0_q4]); - const int16x8_t y_filter = vld1q_s16(filter[y0_q4]); - - if (w == 4) { - const uint16x4_t max = vdup_n_u16((1 << bd) - 1); - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - - int16x4_t h_s0[8], h_s1[8], h_s2[8], h_s3[8], h_s4[8], h_s5[8], h_s6[8]; - load_s16_4x8(s + 0 * src_stride, 1, &h_s0[0], &h_s0[1], &h_s0[2], &h_s0[3], - &h_s0[4], &h_s0[5], &h_s0[6], &h_s0[7]); - load_s16_4x8(s + 1 * src_stride, 1, &h_s1[0], &h_s1[1], &h_s1[2], &h_s1[3], - &h_s1[4], &h_s1[5], &h_s1[6], &h_s1[7]); - load_s16_4x8(s + 2 * src_stride, 1, &h_s2[0], &h_s2[1], &h_s2[2], &h_s2[3], - &h_s2[4], &h_s2[5], &h_s2[6], &h_s2[7]); - load_s16_4x8(s + 3 * src_stride, 1, &h_s3[0], &h_s3[1], &h_s3[2], &h_s3[3], - &h_s3[4], &h_s3[5], &h_s3[6], &h_s3[7]); - load_s16_4x8(s + 4 * src_stride, 1, &h_s4[0], &h_s4[1], &h_s4[2], &h_s4[3], - &h_s4[4], &h_s4[5], &h_s4[6], &h_s4[7]); - load_s16_4x8(s + 5 * src_stride, 1, &h_s5[0], &h_s5[1], &h_s5[2], &h_s5[3], - &h_s5[4], &h_s5[5], &h_s5[6], &h_s5[7]); - load_s16_4x8(s + 6 * src_stride, 1, &h_s6[0], &h_s6[1], &h_s6[2], &h_s6[3], - &h_s6[4], &h_s6[5], &h_s6[6], &h_s6[7]); - - int16x4_t v_s0 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s0[0], h_s0[1], h_s0[2], h_s0[3], h_s0[4], h_s0[5], - h_s0[6], h_s0[7], x_filter, max)); - int16x4_t v_s1 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s1[0], h_s1[1], h_s1[2], h_s1[3], h_s1[4], h_s1[5], - h_s1[6], h_s1[7], x_filter, max)); - int16x4_t v_s2 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s2[0], h_s2[1], h_s2[2], h_s2[3], h_s2[4], h_s2[5], - h_s2[6], h_s2[7], x_filter, max)); - int16x4_t v_s3 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s3[0], h_s3[1], h_s3[2], h_s3[3], h_s3[4], h_s3[5], - h_s3[6], h_s3[7], x_filter, max)); - int16x4_t v_s4 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s4[0], h_s4[1], h_s4[2], h_s4[3], h_s4[4], h_s4[5], - h_s4[6], h_s4[7], x_filter, max)); - int16x4_t v_s5 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s5[0], h_s5[1], h_s5[2], h_s5[3], h_s5[4], h_s5[5], - h_s5[6], h_s5[7], x_filter, max)); - int16x4_t v_s6 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s6[0], h_s6[1], h_s6[2], h_s6[3], h_s6[4], h_s6[5], - h_s6[6], h_s6[7], x_filter, max)); - - s += 7 * src_stride; - - do { - int16x4_t h_s7[8], h_s8[8], h_s9[8], h_s10[8]; - load_s16_4x8(s + 0 * src_stride, 1, &h_s7[0], &h_s7[1], &h_s7[2], - &h_s7[3], &h_s7[4], &h_s7[5], &h_s7[6], &h_s7[7]); - load_s16_4x8(s + 1 * src_stride, 1, &h_s8[0], &h_s8[1], &h_s8[2], - &h_s8[3], &h_s8[4], &h_s8[5], &h_s8[6], &h_s8[7]); - load_s16_4x8(s + 2 * src_stride, 1, &h_s9[0], &h_s9[1], &h_s9[2], - &h_s9[3], &h_s9[4], &h_s9[5], &h_s9[6], &h_s9[7]); - load_s16_4x8(s + 3 * src_stride, 1, &h_s10[0], &h_s10[1], &h_s10[2], - &h_s10[3], &h_s10[4], &h_s10[5], &h_s10[6], &h_s10[7]); - - int16x4_t v_s7 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s7[0], h_s7[1], h_s7[2], h_s7[3], h_s7[4], - h_s7[5], h_s7[6], h_s7[7], x_filter, max)); - int16x4_t v_s8 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s8[0], h_s8[1], h_s8[2], h_s8[3], h_s8[4], - h_s8[5], h_s8[6], h_s8[7], x_filter, max)); - int16x4_t v_s9 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s9[0], h_s9[1], h_s9[2], h_s9[3], h_s9[4], - h_s9[5], h_s9[6], h_s9[7], x_filter, max)); - int16x4_t v_s10 = vreinterpret_s16_u16( - highbd_convolve8_4(h_s10[0], h_s10[1], h_s10[2], h_s10[3], h_s10[4], - h_s10[5], h_s10[6], h_s10[7], x_filter, max)); - - uint16x4_t d0 = highbd_convolve8_4(v_s0, v_s1, v_s2, v_s3, v_s4, v_s5, - v_s6, v_s7, y_filter, max); - uint16x4_t d1 = highbd_convolve8_4(v_s1, v_s2, v_s3, v_s4, v_s5, v_s6, - v_s7, v_s8, y_filter, max); - uint16x4_t d2 = highbd_convolve8_4(v_s2, v_s3, v_s4, v_s5, v_s6, v_s7, - v_s8, v_s9, y_filter, max); - uint16x4_t d3 = highbd_convolve8_4(v_s3, v_s4, v_s5, v_s6, v_s7, v_s8, - v_s9, v_s10, y_filter, max); - - d0 = vrhadd_u16(d0, vld1_u16(d + 0 * dst_stride)); - d1 = vrhadd_u16(d1, vld1_u16(d + 1 * dst_stride)); - d2 = vrhadd_u16(d2, vld1_u16(d + 2 * dst_stride)); - d3 = vrhadd_u16(d3, vld1_u16(d + 3 * dst_stride)); - - store_u16_4x4(d, dst_stride, d0, d1, d2, d3); - - v_s0 = v_s4; - v_s1 = v_s5; - v_s2 = v_s6; - v_s3 = v_s7; - v_s4 = v_s8; - v_s5 = v_s9; - v_s6 = v_s10; - s += 4 * src_stride; - d += 4 * dst_stride; - h -= 4; - } while (h != 0); - - return; - } - - const uint16x8_t max = vdupq_n_u16((1 << bd) - 1); - - do { - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - int height = h; - - int16x8_t h_s0[8], h_s1[8], h_s2[8], h_s3[8], h_s4[8], h_s5[8], h_s6[8]; - load_s16_8x8(s + 0 * src_stride, 1, &h_s0[0], &h_s0[1], &h_s0[2], &h_s0[3], - &h_s0[4], &h_s0[5], &h_s0[6], &h_s0[7]); - load_s16_8x8(s + 1 * src_stride, 1, &h_s1[0], &h_s1[1], &h_s1[2], &h_s1[3], - &h_s1[4], &h_s1[5], &h_s1[6], &h_s1[7]); - load_s16_8x8(s + 2 * src_stride, 1, &h_s2[0], &h_s2[1], &h_s2[2], &h_s2[3], - &h_s2[4], &h_s2[5], &h_s2[6], &h_s2[7]); - load_s16_8x8(s + 3 * src_stride, 1, &h_s3[0], &h_s3[1], &h_s3[2], &h_s3[3], - &h_s3[4], &h_s3[5], &h_s3[6], &h_s3[7]); - load_s16_8x8(s + 4 * src_stride, 1, &h_s4[0], &h_s4[1], &h_s4[2], &h_s4[3], - &h_s4[4], &h_s4[5], &h_s4[6], &h_s4[7]); - load_s16_8x8(s + 5 * src_stride, 1, &h_s5[0], &h_s5[1], &h_s5[2], &h_s5[3], - &h_s5[4], &h_s5[5], &h_s5[6], &h_s5[7]); - load_s16_8x8(s + 6 * src_stride, 1, &h_s6[0], &h_s6[1], &h_s6[2], &h_s6[3], - &h_s6[4], &h_s6[5], &h_s6[6], &h_s6[7]); - - int16x8_t v_s0 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s0[0], h_s0[1], h_s0[2], h_s0[3], h_s0[4], h_s0[5], - h_s0[6], h_s0[7], x_filter, max)); - int16x8_t v_s1 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s1[0], h_s1[1], h_s1[2], h_s1[3], h_s1[4], h_s1[5], - h_s1[6], h_s1[7], x_filter, max)); - int16x8_t v_s2 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s2[0], h_s2[1], h_s2[2], h_s2[3], h_s2[4], h_s2[5], - h_s2[6], h_s2[7], x_filter, max)); - int16x8_t v_s3 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s3[0], h_s3[1], h_s3[2], h_s3[3], h_s3[4], h_s3[5], - h_s3[6], h_s3[7], x_filter, max)); - int16x8_t v_s4 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s4[0], h_s4[1], h_s4[2], h_s4[3], h_s4[4], h_s4[5], - h_s4[6], h_s4[7], x_filter, max)); - int16x8_t v_s5 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s5[0], h_s5[1], h_s5[2], h_s5[3], h_s5[4], h_s5[5], - h_s5[6], h_s5[7], x_filter, max)); - int16x8_t v_s6 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s6[0], h_s6[1], h_s6[2], h_s6[3], h_s6[4], h_s6[5], - h_s6[6], h_s6[7], x_filter, max)); - - s += 7 * src_stride; - - do { - int16x8_t h_s7[8], h_s8[8], h_s9[8], h_s10[8]; - load_s16_8x8(s + 0 * src_stride, 1, &h_s7[0], &h_s7[1], &h_s7[2], - &h_s7[3], &h_s7[4], &h_s7[5], &h_s7[6], &h_s7[7]); - load_s16_8x8(s + 1 * src_stride, 1, &h_s8[0], &h_s8[1], &h_s8[2], - &h_s8[3], &h_s8[4], &h_s8[5], &h_s8[6], &h_s8[7]); - load_s16_8x8(s + 2 * src_stride, 1, &h_s9[0], &h_s9[1], &h_s9[2], - &h_s9[3], &h_s9[4], &h_s9[5], &h_s9[6], &h_s9[7]); - load_s16_8x8(s + 3 * src_stride, 1, &h_s10[0], &h_s10[1], &h_s10[2], - &h_s10[3], &h_s10[4], &h_s10[5], &h_s10[6], &h_s10[7]); - - int16x8_t v_s7 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s7[0], h_s7[1], h_s7[2], h_s7[3], h_s7[4], - h_s7[5], h_s7[6], h_s7[7], x_filter, max)); - int16x8_t v_s8 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s8[0], h_s8[1], h_s8[2], h_s8[3], h_s8[4], - h_s8[5], h_s8[6], h_s8[7], x_filter, max)); - int16x8_t v_s9 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s9[0], h_s9[1], h_s9[2], h_s9[3], h_s9[4], - h_s9[5], h_s9[6], h_s9[7], x_filter, max)); - int16x8_t v_s10 = vreinterpretq_s16_u16( - highbd_convolve8_8(h_s10[0], h_s10[1], h_s10[2], h_s10[3], h_s10[4], - h_s10[5], h_s10[6], h_s10[7], x_filter, max)); - - uint16x8_t d0 = highbd_convolve8_8(v_s0, v_s1, v_s2, v_s3, v_s4, v_s5, - v_s6, v_s7, y_filter, max); - uint16x8_t d1 = highbd_convolve8_8(v_s1, v_s2, v_s3, v_s4, v_s5, v_s6, - v_s7, v_s8, y_filter, max); - uint16x8_t d2 = highbd_convolve8_8(v_s2, v_s3, v_s4, v_s5, v_s6, v_s7, - v_s8, v_s9, y_filter, max); - uint16x8_t d3 = highbd_convolve8_8(v_s3, v_s4, v_s5, v_s6, v_s7, v_s8, - v_s9, v_s10, y_filter, max); - - d0 = vrhaddq_u16(d0, vld1q_u16(d + 0 * dst_stride)); - d1 = vrhaddq_u16(d1, vld1q_u16(d + 1 * dst_stride)); - d2 = vrhaddq_u16(d2, vld1q_u16(d + 2 * dst_stride)); - d3 = vrhaddq_u16(d3, vld1q_u16(d + 3 * dst_stride)); - - store_u16_8x4(d, dst_stride, d0, d1, d2, d3); - - v_s0 = v_s4; - v_s1 = v_s5; - v_s2 = v_s6; - v_s3 = v_s7; - v_s4 = v_s8; - v_s5 = v_s9; - v_s6 = v_s10; - s += 4 * src_stride; - d += 4 * dst_stride; - height -= 4; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_vpx_convolve8_sve.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_vpx_convolve8_sve.c deleted file mode 100644 index f909e06a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_vpx_convolve8_sve.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2024 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/highbd_convolve8_sve.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/arm/vpx_neon_sve_bridge.h" - -DECLARE_ALIGNED(16, static const uint16_t, kTblConv4_8[8]) = { 0, 2, 4, 6, - 1, 3, 5, 7 }; - -static INLINE void highbd_convolve_4tap_horiz_sve( - const uint16_t *src, ptrdiff_t src_stride, uint16_t *dst, - ptrdiff_t dst_stride, int w, int h, const int16x4_t filters, int bd) { - const int16x8_t filter = vcombine_s16(filters, vdup_n_s16(0)); - - if (w == 4) { - const uint16x4_t max = vdup_n_u16((1 << bd) - 1); - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - - do { - int16x4_t s0[4], s1[4], s2[4], s3[4]; - load_s16_4x4(s + 0 * src_stride, 1, &s0[0], &s0[1], &s0[2], &s0[3]); - load_s16_4x4(s + 1 * src_stride, 1, &s1[0], &s1[1], &s1[2], &s1[3]); - load_s16_4x4(s + 2 * src_stride, 1, &s2[0], &s2[1], &s2[2], &s2[3]); - load_s16_4x4(s + 3 * src_stride, 1, &s3[0], &s3[1], &s3[2], &s3[3]); - - uint16x4_t d0 = highbd_convolve4_4_sve(s0, filter, max); - uint16x4_t d1 = highbd_convolve4_4_sve(s1, filter, max); - uint16x4_t d2 = highbd_convolve4_4_sve(s2, filter, max); - uint16x4_t d3 = highbd_convolve4_4_sve(s3, filter, max); - - store_u16_4x4(d, dst_stride, d0, d1, d2, d3); - - s += 4 * src_stride; - d += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint16x8_t max = vdupq_n_u16((1 << bd) - 1); - const uint16x8_t idx = vld1q_u16(kTblConv4_8); - - do { - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - int width = w; - - do { - int16x8_t s0[4], s1[4], s2[4], s3[4]; - load_s16_8x4(s + 0 * src_stride, 1, &s0[0], &s0[1], &s0[2], &s0[3]); - load_s16_8x4(s + 1 * src_stride, 1, &s1[0], &s1[1], &s1[2], &s1[3]); - load_s16_8x4(s + 2 * src_stride, 1, &s2[0], &s2[1], &s2[2], &s2[3]); - load_s16_8x4(s + 3 * src_stride, 1, &s3[0], &s3[1], &s3[2], &s3[3]); - - uint16x8_t d0 = highbd_convolve4_8_sve(s0, filter, max, idx); - uint16x8_t d1 = highbd_convolve4_8_sve(s1, filter, max, idx); - uint16x8_t d2 = highbd_convolve4_8_sve(s2, filter, max, idx); - uint16x8_t d3 = highbd_convolve4_8_sve(s3, filter, max, idx); - - store_u16_8x4(d, dst_stride, d0, d1, d2, d3); - - s += 8; - d += 8; - width -= 8; - } while (width != 0); - - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } -} - -static INLINE void highbd_convolve_8tap_horiz_sve( - const uint16_t *src, ptrdiff_t src_stride, uint16_t *dst, - ptrdiff_t dst_stride, int w, int h, const int16x8_t filters, int bd) { - if (w == 4) { - const uint16x4_t max = vdup_n_u16((1 << bd) - 1); - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - - do { - int16x8_t s0[4], s1[4], s2[4], s3[4]; - load_s16_8x4(s + 0 * src_stride, 1, &s0[0], &s0[1], &s0[2], &s0[3]); - load_s16_8x4(s + 1 * src_stride, 1, &s1[0], &s1[1], &s1[2], &s1[3]); - load_s16_8x4(s + 2 * src_stride, 1, &s2[0], &s2[1], &s2[2], &s2[3]); - load_s16_8x4(s + 3 * src_stride, 1, &s3[0], &s3[1], &s3[2], &s3[3]); - - uint16x4_t d0 = highbd_convolve8_4(s0, filters, max); - uint16x4_t d1 = highbd_convolve8_4(s1, filters, max); - uint16x4_t d2 = highbd_convolve8_4(s2, filters, max); - uint16x4_t d3 = highbd_convolve8_4(s3, filters, max); - - store_u16_4x4(d, dst_stride, d0, d1, d2, d3); - - s += 4 * src_stride; - d += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint16x8_t max = vdupq_n_u16((1 << bd) - 1); - - do { - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - int width = w; - - do { - int16x8_t s0[8], s1[8], s2[8], s3[8]; - load_s16_8x8(s + 0 * src_stride, 1, &s0[0], &s0[1], &s0[2], &s0[3], - &s0[4], &s0[5], &s0[6], &s0[7]); - load_s16_8x8(s + 1 * src_stride, 1, &s1[0], &s1[1], &s1[2], &s1[3], - &s1[4], &s1[5], &s1[6], &s1[7]); - load_s16_8x8(s + 2 * src_stride, 1, &s2[0], &s2[1], &s2[2], &s2[3], - &s2[4], &s2[5], &s2[6], &s2[7]); - load_s16_8x8(s + 3 * src_stride, 1, &s3[0], &s3[1], &s3[2], &s3[3], - &s3[4], &s3[5], &s3[6], &s3[7]); - - uint16x8_t d0 = highbd_convolve8_8(s0, filters, max); - uint16x8_t d1 = highbd_convolve8_8(s1, filters, max); - uint16x8_t d2 = highbd_convolve8_8(s2, filters, max); - uint16x8_t d3 = highbd_convolve8_8(s3, filters, max); - - store_u16_8x4(d, dst_stride, d0, d1, d2, d3); - - s += 8; - d += 8; - width -= 8; - } while (width != 0); - - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } -} - -void vpx_highbd_convolve8_horiz_sve(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd) { - if (x_step_q4 != 16) { - vpx_highbd_convolve8_horiz_c(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h, bd); - return; - } - - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - assert(x_step_q4 == 16); - - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - if (vpx_get_filter_taps(filter[x0_q4]) <= 4) { - const int16x4_t x_filter_4tap = vld1_s16(filter[x0_q4] + 2); - highbd_convolve_4tap_horiz_sve(src - 1, src_stride, dst, dst_stride, w, h, - x_filter_4tap, bd); - } else { - const int16x8_t x_filter_8tap = vld1q_s16(filter[x0_q4]); - highbd_convolve_8tap_horiz_sve(src - 3, src_stride, dst, dst_stride, w, h, - x_filter_8tap, bd); - } -} - -void vpx_highbd_convolve8_avg_horiz_sve(const uint16_t *src, - ptrdiff_t src_stride, uint16_t *dst, - ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd) { - if (x_step_q4 != 16) { - vpx_highbd_convolve8_avg_horiz_c(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h, - bd); - return; - } - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - - const int16x8_t filters = vld1q_s16(filter[x0_q4]); - - src -= 3; - - if (w == 4) { - const uint16x4_t max = vdup_n_u16((1 << bd) - 1); - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - - do { - int16x8_t s0[4], s1[4], s2[4], s3[4]; - load_s16_8x4(s + 0 * src_stride, 1, &s0[0], &s0[1], &s0[2], &s0[3]); - load_s16_8x4(s + 1 * src_stride, 1, &s1[0], &s1[1], &s1[2], &s1[3]); - load_s16_8x4(s + 2 * src_stride, 1, &s2[0], &s2[1], &s2[2], &s2[3]); - load_s16_8x4(s + 3 * src_stride, 1, &s3[0], &s3[1], &s3[2], &s3[3]); - - uint16x4_t d0 = highbd_convolve8_4(s0, filters, max); - uint16x4_t d1 = highbd_convolve8_4(s1, filters, max); - uint16x4_t d2 = highbd_convolve8_4(s2, filters, max); - uint16x4_t d3 = highbd_convolve8_4(s3, filters, max); - - d0 = vrhadd_u16(d0, vld1_u16(d + 0 * dst_stride)); - d1 = vrhadd_u16(d1, vld1_u16(d + 1 * dst_stride)); - d2 = vrhadd_u16(d2, vld1_u16(d + 2 * dst_stride)); - d3 = vrhadd_u16(d3, vld1_u16(d + 3 * dst_stride)); - - store_u16_4x4(d, dst_stride, d0, d1, d2, d3); - - s += 4 * src_stride; - d += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint16x8_t max = vdupq_n_u16((1 << bd) - 1); - - do { - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - int width = w; - - do { - int16x8_t s0[8], s1[8], s2[8], s3[8]; - load_s16_8x8(s + 0 * src_stride, 1, &s0[0], &s0[1], &s0[2], &s0[3], - &s0[4], &s0[5], &s0[6], &s0[7]); - load_s16_8x8(s + 1 * src_stride, 1, &s1[0], &s1[1], &s1[2], &s1[3], - &s1[4], &s1[5], &s1[6], &s1[7]); - load_s16_8x8(s + 2 * src_stride, 1, &s2[0], &s2[1], &s2[2], &s2[3], - &s2[4], &s2[5], &s2[6], &s2[7]); - load_s16_8x8(s + 3 * src_stride, 1, &s3[0], &s3[1], &s3[2], &s3[3], - &s3[4], &s3[5], &s3[6], &s3[7]); - - uint16x8_t d0 = highbd_convolve8_8(s0, filters, max); - uint16x8_t d1 = highbd_convolve8_8(s1, filters, max); - uint16x8_t d2 = highbd_convolve8_8(s2, filters, max); - uint16x8_t d3 = highbd_convolve8_8(s3, filters, max); - - d0 = vrhaddq_u16(d0, vld1q_u16(d + 0 * dst_stride)); - d1 = vrhaddq_u16(d1, vld1q_u16(d + 1 * dst_stride)); - d2 = vrhaddq_u16(d2, vld1q_u16(d + 2 * dst_stride)); - d3 = vrhaddq_u16(d3, vld1q_u16(d + 3 * dst_stride)); - - store_u16_8x4(d, dst_stride, d0, d1, d2, d3); - - s += 8; - d += 8; - width -= 8; - } while (width != 0); - - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_vpx_convolve8_sve2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_vpx_convolve8_sve2.c deleted file mode 100644 index bf0ee960..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_vpx_convolve8_sve2.c +++ /dev/null @@ -1,788 +0,0 @@ -/* - * Copyright (c) 2024 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/highbd_convolve8_neon.h" -#include "vpx_dsp/arm/highbd_convolve8_sve.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/arm/vpx_neon_sve_bridge.h" -#include "vpx_dsp/arm/vpx_neon_sve2_bridge.h" - -// clang-format off -DECLARE_ALIGNED(16, static const uint16_t, kDotProdMergeBlockTbl[24]) = { - // Shift left and insert new last column in transposed 4x4 block. - 1, 2, 3, 0, 5, 6, 7, 4, - // Shift left and insert two new columns in transposed 4x4 block. - 2, 3, 0, 1, 6, 7, 4, 5, - // Shift left and insert three new columns in transposed 4x4 block. - 3, 0, 1, 2, 7, 4, 5, 6, -}; -// clang-format on - -DECLARE_ALIGNED(16, static const uint16_t, kTblConv4_8[8]) = { 0, 2, 4, 6, - 1, 3, 5, 7 }; - -static INLINE void transpose_concat_4x4(const int16x4_t s0, const int16x4_t s1, - const int16x4_t s2, const int16x4_t s3, - int16x8_t res[2]) { - // Transpose 16-bit elements: - // s0: 00, 01, 02, 03 - // s1: 10, 11, 12, 13 - // s2: 20, 21, 22, 23 - // s3: 30, 31, 32, 33 - // - // res[0]: 00 10 20 30 01 11 21 31 - // res[1]: 02 12 22 32 03 13 23 33 - - int16x8_t s0q = vcombine_s16(s0, vdup_n_s16(0)); - int16x8_t s1q = vcombine_s16(s1, vdup_n_s16(0)); - int16x8_t s2q = vcombine_s16(s2, vdup_n_s16(0)); - int16x8_t s3q = vcombine_s16(s3, vdup_n_s16(0)); - - int32x4_t s01 = vreinterpretq_s32_s16(vzip1q_s16(s0q, s1q)); - int32x4_t s23 = vreinterpretq_s32_s16(vzip1q_s16(s2q, s3q)); - - int32x4x2_t t0123 = vzipq_s32(s01, s23); - - res[0] = vreinterpretq_s16_s32(t0123.val[0]); - res[1] = vreinterpretq_s16_s32(t0123.val[1]); -} - -static INLINE void transpose_concat_8x4(const int16x8_t s0, const int16x8_t s1, - const int16x8_t s2, const int16x8_t s3, - int16x8_t res[4]) { - // Transpose 16-bit elements: - // s0: 00, 01, 02, 03, 04, 05, 06, 07 - // s1: 10, 11, 12, 13, 14, 15, 16, 17 - // s2: 20, 21, 22, 23, 24, 25, 26, 27 - // s3: 30, 31, 32, 33, 34, 35, 36, 37 - // - // res[0]: 00 10 20 30 01 11 21 31 - // res[1]: 02 12 22 32 03 13 23 33 - // res[2]: 04 14 24 34 05 15 25 35 - // res[3]: 06 16 26 36 07 17 27 37 - - int16x8x2_t s01 = vzipq_s16(s0, s1); - int16x8x2_t s23 = vzipq_s16(s2, s3); - - int32x4x2_t t0123_lo = vzipq_s32(vreinterpretq_s32_s16(s01.val[0]), - vreinterpretq_s32_s16(s23.val[0])); - int32x4x2_t t0123_hi = vzipq_s32(vreinterpretq_s32_s16(s01.val[1]), - vreinterpretq_s32_s16(s23.val[1])); - - res[0] = vreinterpretq_s16_s32(t0123_lo.val[0]); - res[1] = vreinterpretq_s16_s32(t0123_lo.val[1]); - res[2] = vreinterpretq_s16_s32(t0123_hi.val[0]); - res[3] = vreinterpretq_s16_s32(t0123_hi.val[1]); -} - -static INLINE void vpx_tbl2x4_s16(int16x8_t s0[4], int16x8_t s1[4], - int16x8_t res[4], uint16x8_t idx) { - res[0] = vpx_tbl2_s16(s0[0], s1[0], idx); - res[1] = vpx_tbl2_s16(s0[1], s1[1], idx); - res[2] = vpx_tbl2_s16(s0[2], s1[2], idx); - res[3] = vpx_tbl2_s16(s0[3], s1[3], idx); -} - -static INLINE void vpx_tbl2x2_s16(int16x8_t s0[2], int16x8_t s1[2], - int16x8_t res[2], uint16x8_t idx) { - res[0] = vpx_tbl2_s16(s0[0], s1[0], idx); - res[1] = vpx_tbl2_s16(s0[1], s1[1], idx); -} - -static INLINE uint16x4_t highbd_convolve8_4_v(int16x8_t s_lo[2], - int16x8_t s_hi[2], - int16x8_t filter, - uint16x4_t max) { - int64x2_t sum01 = vpx_dotq_lane_s16(vdupq_n_s64(0), s_lo[0], filter, 0); - sum01 = vpx_dotq_lane_s16(sum01, s_hi[0], filter, 1); - - int64x2_t sum23 = vpx_dotq_lane_s16(vdupq_n_s64(0), s_lo[1], filter, 0); - sum23 = vpx_dotq_lane_s16(sum23, s_hi[1], filter, 1); - - int32x4_t sum0123 = vcombine_s32(vmovn_s64(sum01), vmovn_s64(sum23)); - - uint16x4_t res = vqrshrun_n_s32(sum0123, FILTER_BITS); - return vmin_u16(res, max); -} - -static INLINE uint16x8_t highbd_convolve8_8_v(const int16x8_t s_lo[4], - const int16x8_t s_hi[4], - const int16x8_t filter, - const uint16x8_t max) { - int64x2_t sum01 = vpx_dotq_lane_s16(vdupq_n_s64(0), s_lo[0], filter, 0); - sum01 = vpx_dotq_lane_s16(sum01, s_hi[0], filter, 1); - - int64x2_t sum23 = vpx_dotq_lane_s16(vdupq_n_s64(0), s_lo[1], filter, 0); - sum23 = vpx_dotq_lane_s16(sum23, s_hi[1], filter, 1); - - int64x2_t sum45 = vpx_dotq_lane_s16(vdupq_n_s64(0), s_lo[2], filter, 0); - sum45 = vpx_dotq_lane_s16(sum45, s_hi[2], filter, 1); - - int64x2_t sum67 = vpx_dotq_lane_s16(vdupq_n_s64(0), s_lo[3], filter, 0); - sum67 = vpx_dotq_lane_s16(sum67, s_hi[3], filter, 1); - - int32x4_t sum0123 = vcombine_s32(vmovn_s64(sum01), vmovn_s64(sum23)); - int32x4_t sum4567 = vcombine_s32(vmovn_s64(sum45), vmovn_s64(sum67)); - - uint16x8_t res = vcombine_u16(vqrshrun_n_s32(sum0123, FILTER_BITS), - vqrshrun_n_s32(sum4567, FILTER_BITS)); - return vminq_u16(res, max); -} - -static INLINE void highbd_convolve8_8tap_vert_sve2( - const uint16_t *src, ptrdiff_t src_stride, uint16_t *dst, - ptrdiff_t dst_stride, int w, int h, const int16x8_t filter, int bd) { - assert(w >= 4 && h >= 4); - uint16x8x3_t merge_tbl_idx = vld1q_u16_x3(kDotProdMergeBlockTbl); - - // Correct indices by the size of vector length. - merge_tbl_idx.val[0] = vaddq_u16( - merge_tbl_idx.val[0], - vreinterpretq_u16_u64(vdupq_n_u64(svcnth() * 0x0001000000000000ULL))); - merge_tbl_idx.val[1] = vaddq_u16( - merge_tbl_idx.val[1], - vreinterpretq_u16_u64(vdupq_n_u64(svcnth() * 0x0001000100000000ULL))); - merge_tbl_idx.val[2] = vaddq_u16( - merge_tbl_idx.val[2], - vreinterpretq_u16_u64(vdupq_n_u64(svcnth() * 0x0001000100010000ULL))); - - if (w == 4) { - const uint16x4_t max = vdup_n_u16((1 << bd) - 1); - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - - int16x4_t s0, s1, s2, s3, s4, s5, s6; - load_s16_4x7(s, src_stride, &s0, &s1, &s2, &s3, &s4, &s5, &s6); - s += 7 * src_stride; - - int16x8_t s0123[2], s1234[2], s2345[2], s3456[2]; - transpose_concat_4x4(s0, s1, s2, s3, s0123); - transpose_concat_4x4(s1, s2, s3, s4, s1234); - transpose_concat_4x4(s2, s3, s4, s5, s2345); - transpose_concat_4x4(s3, s4, s5, s6, s3456); - - do { - int16x4_t s7, s8, s9, sA; - - load_s16_4x4(s, src_stride, &s7, &s8, &s9, &sA); - - int16x8_t s4567[2], s5678[2], s6789[2], s789A[2]; - transpose_concat_4x4(s7, s8, s9, sA, s789A); - - vpx_tbl2x2_s16(s3456, s789A, s4567, merge_tbl_idx.val[0]); - vpx_tbl2x2_s16(s3456, s789A, s5678, merge_tbl_idx.val[1]); - vpx_tbl2x2_s16(s3456, s789A, s6789, merge_tbl_idx.val[2]); - - uint16x4_t d0 = highbd_convolve8_4_v(s0123, s4567, filter, max); - uint16x4_t d1 = highbd_convolve8_4_v(s1234, s5678, filter, max); - uint16x4_t d2 = highbd_convolve8_4_v(s2345, s6789, filter, max); - uint16x4_t d3 = highbd_convolve8_4_v(s3456, s789A, filter, max); - - store_u16_4x4(d, dst_stride, d0, d1, d2, d3); - - s0123[0] = s4567[0]; - s0123[1] = s4567[1]; - s1234[0] = s5678[0]; - s1234[1] = s5678[1]; - s2345[0] = s6789[0]; - s2345[1] = s6789[1]; - s3456[0] = s789A[0]; - s3456[1] = s789A[1]; - - s += 4 * src_stride; - d += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint16x8_t max = vdupq_n_u16((1 << bd) - 1); - - do { - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - int height = h; - - int16x8_t s0, s1, s2, s3, s4, s5, s6; - load_s16_8x7(s, src_stride, &s0, &s1, &s2, &s3, &s4, &s5, &s6); - s += 7 * src_stride; - - int16x8_t s0123[4], s1234[4], s2345[4], s3456[4]; - transpose_concat_8x4(s0, s1, s2, s3, s0123); - transpose_concat_8x4(s1, s2, s3, s4, s1234); - transpose_concat_8x4(s2, s3, s4, s5, s2345); - transpose_concat_8x4(s3, s4, s5, s6, s3456); - - do { - int16x8_t s7, s8, s9, sA; - load_s16_8x4(s, src_stride, &s7, &s8, &s9, &sA); - - int16x8_t s4567[4], s5678[5], s6789[4], s789A[4]; - transpose_concat_8x4(s7, s8, s9, sA, s789A); - - vpx_tbl2x4_s16(s3456, s789A, s4567, merge_tbl_idx.val[0]); - vpx_tbl2x4_s16(s3456, s789A, s5678, merge_tbl_idx.val[1]); - vpx_tbl2x4_s16(s3456, s789A, s6789, merge_tbl_idx.val[2]); - - uint16x8_t d0 = highbd_convolve8_8_v(s0123, s4567, filter, max); - uint16x8_t d1 = highbd_convolve8_8_v(s1234, s5678, filter, max); - uint16x8_t d2 = highbd_convolve8_8_v(s2345, s6789, filter, max); - uint16x8_t d3 = highbd_convolve8_8_v(s3456, s789A, filter, max); - - store_u16_8x4(d, dst_stride, d0, d1, d2, d3); - - s0123[0] = s4567[0]; - s0123[1] = s4567[1]; - s0123[2] = s4567[2]; - s0123[3] = s4567[3]; - s1234[0] = s5678[0]; - s1234[1] = s5678[1]; - s1234[2] = s5678[2]; - s1234[3] = s5678[3]; - s2345[0] = s6789[0]; - s2345[1] = s6789[1]; - s2345[2] = s6789[2]; - s2345[3] = s6789[3]; - s3456[0] = s789A[0]; - s3456[1] = s789A[1]; - s3456[2] = s789A[2]; - s3456[3] = s789A[3]; - - s += 4 * src_stride; - d += 4 * dst_stride; - height -= 4; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); - } -} - -void vpx_highbd_convolve8_vert_sve2(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd) { - if (y_step_q4 != 16) { - vpx_highbd_convolve8_vert_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h, bd); - return; - } - - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - assert(y_step_q4 == 16); - - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - if (vpx_get_filter_taps(filter[y0_q4]) <= 4) { - vpx_highbd_convolve8_vert_neon(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h, - bd); - } else { - const int16x8_t y_filter_8tap = vld1q_s16(filter[y0_q4]); - highbd_convolve8_8tap_vert_sve2(src - 3 * src_stride, src_stride, dst, - dst_stride, w, h, y_filter_8tap, bd); - } -} - -void vpx_highbd_convolve8_avg_vert_sve2(const uint16_t *src, - ptrdiff_t src_stride, uint16_t *dst, - ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd) { - if (y_step_q4 != 16) { - vpx_highbd_convolve8_avg_vert_c(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h, - bd); - return; - } - - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - - const int16x8_t filters = vld1q_s16(filter[y0_q4]); - - src -= 3 * src_stride; - - uint16x8x3_t merge_tbl_idx = vld1q_u16_x3(kDotProdMergeBlockTbl); - - // Correct indices by the size of vector length. - merge_tbl_idx.val[0] = vaddq_u16( - merge_tbl_idx.val[0], - vreinterpretq_u16_u64(vdupq_n_u64(svcnth() * 0x0001000000000000ULL))); - merge_tbl_idx.val[1] = vaddq_u16( - merge_tbl_idx.val[1], - vreinterpretq_u16_u64(vdupq_n_u64(svcnth() * 0x0001000100000000ULL))); - merge_tbl_idx.val[2] = vaddq_u16( - merge_tbl_idx.val[2], - vreinterpretq_u16_u64(vdupq_n_u64(svcnth() * 0x0001000100010000ULL))); - - if (w == 4) { - const uint16x4_t max = vdup_n_u16((1 << bd) - 1); - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - - int16x4_t s0, s1, s2, s3, s4, s5, s6; - load_s16_4x7(s, src_stride, &s0, &s1, &s2, &s3, &s4, &s5, &s6); - s += 7 * src_stride; - - int16x8_t s0123[2], s1234[2], s2345[2], s3456[2]; - transpose_concat_4x4(s0, s1, s2, s3, s0123); - transpose_concat_4x4(s1, s2, s3, s4, s1234); - transpose_concat_4x4(s2, s3, s4, s5, s2345); - transpose_concat_4x4(s3, s4, s5, s6, s3456); - - do { - int16x4_t s7, s8, s9, sA; - - load_s16_4x4(s, src_stride, &s7, &s8, &s9, &sA); - - int16x8_t s4567[2], s5678[2], s6789[2], s789A[2]; - transpose_concat_4x4(s7, s8, s9, sA, s789A); - - vpx_tbl2x2_s16(s3456, s789A, s4567, merge_tbl_idx.val[0]); - vpx_tbl2x2_s16(s3456, s789A, s5678, merge_tbl_idx.val[1]); - vpx_tbl2x2_s16(s3456, s789A, s6789, merge_tbl_idx.val[2]); - - uint16x4_t d0 = highbd_convolve8_4_v(s0123, s4567, filters, max); - uint16x4_t d1 = highbd_convolve8_4_v(s1234, s5678, filters, max); - uint16x4_t d2 = highbd_convolve8_4_v(s2345, s6789, filters, max); - uint16x4_t d3 = highbd_convolve8_4_v(s3456, s789A, filters, max); - - d0 = vrhadd_u16(d0, vld1_u16(d + 0 * dst_stride)); - d1 = vrhadd_u16(d1, vld1_u16(d + 1 * dst_stride)); - d2 = vrhadd_u16(d2, vld1_u16(d + 2 * dst_stride)); - d3 = vrhadd_u16(d3, vld1_u16(d + 3 * dst_stride)); - - store_u16_4x4(d, dst_stride, d0, d1, d2, d3); - - s0123[0] = s4567[0]; - s0123[1] = s4567[1]; - s1234[0] = s5678[0]; - s1234[1] = s5678[1]; - s2345[0] = s6789[0]; - s2345[1] = s6789[1]; - s3456[0] = s789A[0]; - s3456[1] = s789A[1]; - - s += 4 * src_stride; - d += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint16x8_t max = vdupq_n_u16((1 << bd) - 1); - - do { - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - int height = h; - - int16x8_t s0, s1, s2, s3, s4, s5, s6; - load_s16_8x7(s, src_stride, &s0, &s1, &s2, &s3, &s4, &s5, &s6); - s += 7 * src_stride; - - int16x8_t s0123[4], s1234[4], s2345[4], s3456[4]; - transpose_concat_8x4(s0, s1, s2, s3, s0123); - transpose_concat_8x4(s1, s2, s3, s4, s1234); - transpose_concat_8x4(s2, s3, s4, s5, s2345); - transpose_concat_8x4(s3, s4, s5, s6, s3456); - - do { - int16x8_t s7, s8, s9, sA; - load_s16_8x4(s, src_stride, &s7, &s8, &s9, &sA); - - int16x8_t s4567[4], s5678[5], s6789[4], s789A[4]; - transpose_concat_8x4(s7, s8, s9, sA, s789A); - - vpx_tbl2x4_s16(s3456, s789A, s4567, merge_tbl_idx.val[0]); - vpx_tbl2x4_s16(s3456, s789A, s5678, merge_tbl_idx.val[1]); - vpx_tbl2x4_s16(s3456, s789A, s6789, merge_tbl_idx.val[2]); - - uint16x8_t d0 = highbd_convolve8_8_v(s0123, s4567, filters, max); - uint16x8_t d1 = highbd_convolve8_8_v(s1234, s5678, filters, max); - uint16x8_t d2 = highbd_convolve8_8_v(s2345, s6789, filters, max); - uint16x8_t d3 = highbd_convolve8_8_v(s3456, s789A, filters, max); - - d0 = vrhaddq_u16(d0, vld1q_u16(d + 0 * dst_stride)); - d1 = vrhaddq_u16(d1, vld1q_u16(d + 1 * dst_stride)); - d2 = vrhaddq_u16(d2, vld1q_u16(d + 2 * dst_stride)); - d3 = vrhaddq_u16(d3, vld1q_u16(d + 3 * dst_stride)); - - store_u16_8x4(d, dst_stride, d0, d1, d2, d3); - - s0123[0] = s4567[0]; - s0123[1] = s4567[1]; - s0123[2] = s4567[2]; - s0123[3] = s4567[3]; - s1234[0] = s5678[0]; - s1234[1] = s5678[1]; - s1234[2] = s5678[2]; - s1234[3] = s5678[3]; - s2345[0] = s6789[0]; - s2345[1] = s6789[1]; - s2345[2] = s6789[2]; - s2345[3] = s6789[3]; - s3456[0] = s789A[0]; - s3456[1] = s789A[1]; - s3456[2] = s789A[2]; - s3456[3] = s789A[3]; - - s += 4 * src_stride; - d += 4 * dst_stride; - height -= 4; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); - } -} - -static INLINE void highbd_convolve_2d_4tap_sve2( - const uint16_t *src, ptrdiff_t src_stride, uint16_t *dst, - ptrdiff_t dst_stride, int w, int h, const int16x4_t x_filters, - const int16x4_t y_filters, int bd) { - const int16x8_t x_filter = vcombine_s16(x_filters, vdup_n_s16(0)); - - if (w == 4) { - const uint16x4_t max = vdup_n_u16((1 << bd) - 1); - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - - int16x4_t h_s0[4], h_s1[4], h_s2[4]; - load_s16_4x4(s + 0 * src_stride, 1, &h_s0[0], &h_s0[1], &h_s0[2], &h_s0[3]); - load_s16_4x4(s + 1 * src_stride, 1, &h_s1[0], &h_s1[1], &h_s1[2], &h_s1[3]); - load_s16_4x4(s + 2 * src_stride, 1, &h_s2[0], &h_s2[1], &h_s2[2], &h_s2[3]); - - int16x4_t v_s0 = - vreinterpret_s16_u16(highbd_convolve4_4_sve(h_s0, x_filter, max)); - int16x4_t v_s1 = - vreinterpret_s16_u16(highbd_convolve4_4_sve(h_s1, x_filter, max)); - int16x4_t v_s2 = - vreinterpret_s16_u16(highbd_convolve4_4_sve(h_s2, x_filter, max)); - - s += 3 * src_stride; - - do { - int16x4_t h_s3[4], h_s4[4], h_s5[4], h_s6[4]; - load_s16_4x4(s + 0 * src_stride, 1, &h_s3[0], &h_s3[1], &h_s3[2], - &h_s3[3]); - load_s16_4x4(s + 1 * src_stride, 1, &h_s4[0], &h_s4[1], &h_s4[2], - &h_s4[3]); - load_s16_4x4(s + 2 * src_stride, 1, &h_s5[0], &h_s5[1], &h_s5[2], - &h_s5[3]); - load_s16_4x4(s + 3 * src_stride, 1, &h_s6[0], &h_s6[1], &h_s6[2], - &h_s6[3]); - - int16x4_t v_s3 = - vreinterpret_s16_u16(highbd_convolve4_4_sve(h_s3, x_filter, max)); - int16x4_t v_s4 = - vreinterpret_s16_u16(highbd_convolve4_4_sve(h_s4, x_filter, max)); - int16x4_t v_s5 = - vreinterpret_s16_u16(highbd_convolve4_4_sve(h_s5, x_filter, max)); - int16x4_t v_s6 = - vreinterpret_s16_u16(highbd_convolve4_4_sve(h_s6, x_filter, max)); - - uint16x4_t d0 = - highbd_convolve4_4_neon(v_s0, v_s1, v_s2, v_s3, y_filters, max); - uint16x4_t d1 = - highbd_convolve4_4_neon(v_s1, v_s2, v_s3, v_s4, y_filters, max); - uint16x4_t d2 = - highbd_convolve4_4_neon(v_s2, v_s3, v_s4, v_s5, y_filters, max); - uint16x4_t d3 = - highbd_convolve4_4_neon(v_s3, v_s4, v_s5, v_s6, y_filters, max); - - store_u16_4x4(d, dst_stride, d0, d1, d2, d3); - - v_s0 = v_s4; - v_s1 = v_s5; - v_s2 = v_s6; - s += 4 * src_stride; - d += 4 * dst_stride; - h -= 4; - } while (h != 0); - - } else { - const uint16x8_t max = vdupq_n_u16((1 << bd) - 1); - const uint16x8_t idx = vld1q_u16(kTblConv4_8); - - do { - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - int height = h; - - int16x8_t h_s0[4], h_s1[4], h_s2[4]; - load_s16_8x4(s + 0 * src_stride, 1, &h_s0[0], &h_s0[1], &h_s0[2], - &h_s0[3]); - load_s16_8x4(s + 1 * src_stride, 1, &h_s1[0], &h_s1[1], &h_s1[2], - &h_s1[3]); - load_s16_8x4(s + 2 * src_stride, 1, &h_s2[0], &h_s2[1], &h_s2[2], - &h_s2[3]); - - int16x8_t v_s0 = vreinterpretq_s16_u16( - highbd_convolve4_8_sve(h_s0, x_filter, max, idx)); - int16x8_t v_s1 = vreinterpretq_s16_u16( - highbd_convolve4_8_sve(h_s1, x_filter, max, idx)); - int16x8_t v_s2 = vreinterpretq_s16_u16( - highbd_convolve4_8_sve(h_s2, x_filter, max, idx)); - - s += 3 * src_stride; - - do { - int16x8_t h_s3[4], h_s4[4], h_s5[4], h_s6[4]; - load_s16_8x4(s + 0 * src_stride, 1, &h_s3[0], &h_s3[1], &h_s3[2], - &h_s3[3]); - load_s16_8x4(s + 1 * src_stride, 1, &h_s4[0], &h_s4[1], &h_s4[2], - &h_s4[3]); - load_s16_8x4(s + 2 * src_stride, 1, &h_s5[0], &h_s5[1], &h_s5[2], - &h_s5[3]); - load_s16_8x4(s + 3 * src_stride, 1, &h_s6[0], &h_s6[1], &h_s6[2], - &h_s6[3]); - - int16x8_t v_s3 = vreinterpretq_s16_u16( - highbd_convolve4_8_sve(h_s3, x_filter, max, idx)); - int16x8_t v_s4 = vreinterpretq_s16_u16( - highbd_convolve4_8_sve(h_s4, x_filter, max, idx)); - int16x8_t v_s5 = vreinterpretq_s16_u16( - highbd_convolve4_8_sve(h_s5, x_filter, max, idx)); - int16x8_t v_s6 = vreinterpretq_s16_u16( - highbd_convolve4_8_sve(h_s6, x_filter, max, idx)); - - uint16x8_t d0 = - highbd_convolve4_8_neon(v_s0, v_s1, v_s2, v_s3, y_filters, max); - uint16x8_t d1 = - highbd_convolve4_8_neon(v_s1, v_s2, v_s3, v_s4, y_filters, max); - uint16x8_t d2 = - highbd_convolve4_8_neon(v_s2, v_s3, v_s4, v_s5, y_filters, max); - uint16x8_t d3 = - highbd_convolve4_8_neon(v_s3, v_s4, v_s5, v_s6, y_filters, max); - - store_u16_8x4(d, dst_stride, d0, d1, d2, d3); - - v_s0 = v_s4; - v_s1 = v_s5; - v_s2 = v_s6; - s += 4 * src_stride; - d += 4 * dst_stride; - height -= 4; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); - } -} - -static INLINE void highbd_convolve8_2d_horiz_sve2( - const uint16_t *src, ptrdiff_t src_stride, uint16_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, - int y0_q4, int y_step_q4, int w, int h, int bd) { - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - assert(x_step_q4 == 16); - assert(h % 4 == 3 && h >= 7); - - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - const int16x8_t filters = vld1q_s16(filter[x0_q4]); - - src -= 3; - - if (w == 4) { - const uint16x4_t max = vdup_n_u16((1 << bd) - 1); - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - - do { - int16x8_t s0[4], s1[4], s2[4], s3[4]; - load_s16_8x4(s + 0 * src_stride, 1, &s0[0], &s0[1], &s0[2], &s0[3]); - load_s16_8x4(s + 1 * src_stride, 1, &s1[0], &s1[1], &s1[2], &s1[3]); - load_s16_8x4(s + 2 * src_stride, 1, &s2[0], &s2[1], &s2[2], &s2[3]); - load_s16_8x4(s + 3 * src_stride, 1, &s3[0], &s3[1], &s3[2], &s3[3]); - - uint16x4_t d0 = highbd_convolve8_4(s0, filters, max); - uint16x4_t d1 = highbd_convolve8_4(s1, filters, max); - uint16x4_t d2 = highbd_convolve8_4(s2, filters, max); - uint16x4_t d3 = highbd_convolve8_4(s3, filters, max); - - store_u16_4x4(d, dst_stride, d0, d1, d2, d3); - - s += 4 * src_stride; - d += 4 * dst_stride; - h -= 4; - } while (h != 3); - - // Process final three rows (h % 4 == 3). - int16x8_t s0[4], s1[4], s2[4]; - load_s16_8x4(s + 0 * src_stride, 1, &s0[0], &s0[1], &s0[2], &s0[3]); - load_s16_8x4(s + 1 * src_stride, 1, &s1[0], &s1[1], &s1[2], &s1[3]); - load_s16_8x4(s + 2 * src_stride, 1, &s2[0], &s2[1], &s2[2], &s2[3]); - - uint16x4_t d0 = highbd_convolve8_4(s0, filters, max); - uint16x4_t d1 = highbd_convolve8_4(s1, filters, max); - uint16x4_t d2 = highbd_convolve8_4(s2, filters, max); - - store_u16_4x3(d, dst_stride, d0, d1, d2); - } else { - const uint16x8_t max = vdupq_n_u16((1 << bd) - 1); - - do { - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - int width = w; - - do { - int16x8_t s0[8], s1[8], s2[8], s3[8]; - load_s16_8x8(s + 0 * src_stride, 1, &s0[0], &s0[1], &s0[2], &s0[3], - &s0[4], &s0[5], &s0[6], &s0[7]); - load_s16_8x8(s + 1 * src_stride, 1, &s1[0], &s1[1], &s1[2], &s1[3], - &s1[4], &s1[5], &s1[6], &s1[7]); - load_s16_8x8(s + 2 * src_stride, 1, &s2[0], &s2[1], &s2[2], &s2[3], - &s2[4], &s2[5], &s2[6], &s2[7]); - load_s16_8x8(s + 3 * src_stride, 1, &s3[0], &s3[1], &s3[2], &s3[3], - &s3[4], &s3[5], &s3[6], &s3[7]); - - uint16x8_t d0 = highbd_convolve8_8(s0, filters, max); - uint16x8_t d1 = highbd_convolve8_8(s1, filters, max); - uint16x8_t d2 = highbd_convolve8_8(s2, filters, max); - uint16x8_t d3 = highbd_convolve8_8(s3, filters, max); - - store_u16_8x4(d, dst_stride, d0, d1, d2, d3); - - s += 8; - d += 8; - width -= 8; - } while (width != 0); - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 3); - - // Process final three rows (h % 4 == 3). - const int16_t *s = (const int16_t *)src; - uint16_t *d = dst; - int width = w; - - do { - int16x8_t s0[8], s1[8], s2[8]; - load_s16_8x8(s + 0 * src_stride, 1, &s0[0], &s0[1], &s0[2], &s0[3], - &s0[4], &s0[5], &s0[6], &s0[7]); - load_s16_8x8(s + 1 * src_stride, 1, &s1[0], &s1[1], &s1[2], &s1[3], - &s1[4], &s1[5], &s1[6], &s1[7]); - load_s16_8x8(s + 2 * src_stride, 1, &s2[0], &s2[1], &s2[2], &s2[3], - &s2[4], &s2[5], &s2[6], &s2[7]); - - uint16x8_t d0 = highbd_convolve8_8(s0, filters, max); - uint16x8_t d1 = highbd_convolve8_8(s1, filters, max); - uint16x8_t d2 = highbd_convolve8_8(s2, filters, max); - - store_u16_8x3(d, dst_stride, d0, d1, d2); - - s += 8; - d += 8; - width -= 8; - } while (width != 0); - } -} - -void vpx_highbd_convolve8_sve2(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h, int bd) { - if (x_step_q4 != 16 || y_step_q4 != 16) { - vpx_highbd_convolve8_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h, bd); - return; - } - - assert(y_step_q4 == 16); - assert(x_step_q4 == 16); - - const int horiz_filter_taps = vpx_get_filter_taps(filter[x0_q4]) <= 4 ? 4 : 8; - const int vert_filter_taps = vpx_get_filter_taps(filter[y0_q4]) <= 4 ? 4 : 8; - - if (horiz_filter_taps == 4 || vert_filter_taps == 4) { - const ptrdiff_t horiz_offset = horiz_filter_taps / 2 - 1; - const ptrdiff_t vert_offset = (vert_filter_taps / 2 - 1) * src_stride; - const int16x4_t x_filter = vld1_s16(filter[x0_q4] + 2); - const int16x4_t y_filter = vld1_s16(filter[y0_q4] + 2); - - highbd_convolve_2d_4tap_sve2(src - horiz_offset - vert_offset, src_stride, - dst, dst_stride, w, h, x_filter, y_filter, bd); - return; - } - - // Given our constraints: w <= 64, h <= 64, taps <= 8 we can reduce the - // maximum buffer size to 64 * (64 + 7). - DECLARE_ALIGNED(32, uint16_t, im_block[64 * 71]); - const int im_stride = 64; - - // Account for the vertical phase needing SUBPEL_TAPS / 2 - 1 lines prior - // and SUBPEL_TAPS / 2 lines post. - const int im_height = h + SUBPEL_TAPS - 1; - const ptrdiff_t border_offset = SUBPEL_TAPS / 2 - 1; - - highbd_convolve8_2d_horiz_sve2(src - src_stride * border_offset, src_stride, - im_block, im_stride, filter, x0_q4, x_step_q4, - y0_q4, y_step_q4, w, im_height, bd); - - // Step into the temporary buffer border_offset rows to get actual frame data. - vpx_highbd_convolve8_vert_sve2(im_block + im_stride * border_offset, - im_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h, bd); -} - -void vpx_highbd_convolve8_avg_sve2(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd) { - if (x_step_q4 != 16 || y_step_q4 != 16) { - vpx_highbd_convolve8_avg_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h, bd); - return; - } - - assert(y_step_q4 == 16); - assert(x_step_q4 == 16); - - // Given our constraints: w <= 64, h <= 64, taps <= 8 we can reduce the - // maximum buffer size to 64 * (64 + 7). - DECLARE_ALIGNED(32, uint16_t, im_block[64 * 71]); - const int im_stride = 64; - - // Account for the vertical phase needing SUBPEL_TAPS / 2 - 1 lines prior - // and SUBPEL_TAPS / 2 lines post. - const int im_height = h + SUBPEL_TAPS - 1; - const ptrdiff_t border_offset = SUBPEL_TAPS / 2 - 1; - - highbd_convolve8_2d_horiz_sve2(src - src_stride * border_offset, src_stride, - im_block, im_stride, filter, x0_q4, x_step_q4, - y0_q4, y_step_q4, w, im_height, bd); - - // Step into the temporary buffer border_offset rows to get actual frame data. - vpx_highbd_convolve8_avg_vert_sve2(im_block + im_stride * border_offset, - im_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h, bd); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_vpx_convolve_avg_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_vpx_convolve_avg_neon.c deleted file mode 100644 index 765a054f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_vpx_convolve_avg_neon.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" - -void vpx_highbd_convolve_avg_neon(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd) { - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - (void)bd; - - if (w < 8) { // avg4 - uint16x4_t s0, s1, d0, d1; - uint16x8_t s01, d01; - do { - s0 = vld1_u16(src); - d0 = vld1_u16(dst); - src += src_stride; - s1 = vld1_u16(src); - d1 = vld1_u16(dst + dst_stride); - src += src_stride; - s01 = vcombine_u16(s0, s1); - d01 = vcombine_u16(d0, d1); - d01 = vrhaddq_u16(s01, d01); - vst1_u16(dst, vget_low_u16(d01)); - dst += dst_stride; - vst1_u16(dst, vget_high_u16(d01)); - dst += dst_stride; - h -= 2; - } while (h > 0); - } else if (w == 8) { // avg8 - uint16x8_t s0, s1, d0, d1; - do { - s0 = vld1q_u16(src); - d0 = vld1q_u16(dst); - src += src_stride; - s1 = vld1q_u16(src); - d1 = vld1q_u16(dst + dst_stride); - src += src_stride; - - d0 = vrhaddq_u16(s0, d0); - d1 = vrhaddq_u16(s1, d1); - - vst1q_u16(dst, d0); - dst += dst_stride; - vst1q_u16(dst, d1); - dst += dst_stride; - h -= 2; - } while (h > 0); - } else if (w < 32) { // avg16 - uint16x8_t s0l, s0h, s1l, s1h, d0l, d0h, d1l, d1h; - do { - s0l = vld1q_u16(src); - s0h = vld1q_u16(src + 8); - d0l = vld1q_u16(dst); - d0h = vld1q_u16(dst + 8); - src += src_stride; - s1l = vld1q_u16(src); - s1h = vld1q_u16(src + 8); - d1l = vld1q_u16(dst + dst_stride); - d1h = vld1q_u16(dst + dst_stride + 8); - src += src_stride; - - d0l = vrhaddq_u16(s0l, d0l); - d0h = vrhaddq_u16(s0h, d0h); - d1l = vrhaddq_u16(s1l, d1l); - d1h = vrhaddq_u16(s1h, d1h); - - vst1q_u16(dst, d0l); - vst1q_u16(dst + 8, d0h); - dst += dst_stride; - vst1q_u16(dst, d1l); - vst1q_u16(dst + 8, d1h); - dst += dst_stride; - h -= 2; - } while (h > 0); - } else if (w == 32) { // avg32 - uint16x8_t s0, s1, s2, s3, d0, d1, d2, d3; - do { - s0 = vld1q_u16(src); - s1 = vld1q_u16(src + 8); - s2 = vld1q_u16(src + 16); - s3 = vld1q_u16(src + 24); - d0 = vld1q_u16(dst); - d1 = vld1q_u16(dst + 8); - d2 = vld1q_u16(dst + 16); - d3 = vld1q_u16(dst + 24); - src += src_stride; - - d0 = vrhaddq_u16(s0, d0); - d1 = vrhaddq_u16(s1, d1); - d2 = vrhaddq_u16(s2, d2); - d3 = vrhaddq_u16(s3, d3); - - vst1q_u16(dst, d0); - vst1q_u16(dst + 8, d1); - vst1q_u16(dst + 16, d2); - vst1q_u16(dst + 24, d3); - dst += dst_stride; - - s0 = vld1q_u16(src); - s1 = vld1q_u16(src + 8); - s2 = vld1q_u16(src + 16); - s3 = vld1q_u16(src + 24); - d0 = vld1q_u16(dst); - d1 = vld1q_u16(dst + 8); - d2 = vld1q_u16(dst + 16); - d3 = vld1q_u16(dst + 24); - src += src_stride; - - d0 = vrhaddq_u16(s0, d0); - d1 = vrhaddq_u16(s1, d1); - d2 = vrhaddq_u16(s2, d2); - d3 = vrhaddq_u16(s3, d3); - - vst1q_u16(dst, d0); - vst1q_u16(dst + 8, d1); - vst1q_u16(dst + 16, d2); - vst1q_u16(dst + 24, d3); - dst += dst_stride; - h -= 2; - } while (h > 0); - } else { // avg64 - uint16x8_t s0, s1, s2, s3, d0, d1, d2, d3; - do { - s0 = vld1q_u16(src); - s1 = vld1q_u16(src + 8); - s2 = vld1q_u16(src + 16); - s3 = vld1q_u16(src + 24); - d0 = vld1q_u16(dst); - d1 = vld1q_u16(dst + 8); - d2 = vld1q_u16(dst + 16); - d3 = vld1q_u16(dst + 24); - - d0 = vrhaddq_u16(s0, d0); - d1 = vrhaddq_u16(s1, d1); - d2 = vrhaddq_u16(s2, d2); - d3 = vrhaddq_u16(s3, d3); - - vst1q_u16(dst, d0); - vst1q_u16(dst + 8, d1); - vst1q_u16(dst + 16, d2); - vst1q_u16(dst + 24, d3); - - s0 = vld1q_u16(src + 32); - s1 = vld1q_u16(src + 40); - s2 = vld1q_u16(src + 48); - s3 = vld1q_u16(src + 56); - d0 = vld1q_u16(dst + 32); - d1 = vld1q_u16(dst + 40); - d2 = vld1q_u16(dst + 48); - d3 = vld1q_u16(dst + 56); - - d0 = vrhaddq_u16(s0, d0); - d1 = vrhaddq_u16(s1, d1); - d2 = vrhaddq_u16(s2, d2); - d3 = vrhaddq_u16(s3, d3); - - vst1q_u16(dst + 32, d0); - vst1q_u16(dst + 40, d1); - vst1q_u16(dst + 48, d2); - vst1q_u16(dst + 56, d3); - src += src_stride; - dst += dst_stride; - } while (--h); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_vpx_convolve_copy_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_vpx_convolve_copy_neon.c deleted file mode 100644 index 77510820..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/highbd_vpx_convolve_copy_neon.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" - -void vpx_highbd_convolve_copy_neon(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd) { - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - (void)bd; - - if (w < 8) { // copy4 - uint16x4_t s0, s1; - do { - s0 = vld1_u16(src); - src += src_stride; - s1 = vld1_u16(src); - src += src_stride; - - vst1_u16(dst, s0); - dst += dst_stride; - vst1_u16(dst, s1); - dst += dst_stride; - h -= 2; - } while (h != 0); - } else if (w == 8) { // copy8 - uint16x8_t s0, s1; - do { - s0 = vld1q_u16(src); - src += src_stride; - s1 = vld1q_u16(src); - src += src_stride; - - vst1q_u16(dst, s0); - dst += dst_stride; - vst1q_u16(dst, s1); - dst += dst_stride; - h -= 2; - } while (h != 0); - } else if (w < 32) { // copy16 - uint16x8_t s0, s1, s2, s3; - do { - s0 = vld1q_u16(src); - s1 = vld1q_u16(src + 8); - src += src_stride; - s2 = vld1q_u16(src); - s3 = vld1q_u16(src + 8); - src += src_stride; - - vst1q_u16(dst, s0); - vst1q_u16(dst + 8, s1); - dst += dst_stride; - vst1q_u16(dst, s2); - vst1q_u16(dst + 8, s3); - dst += dst_stride; - h -= 2; - } while (h != 0); - } else if (w == 32) { // copy32 - uint16x8_t s0, s1, s2, s3; - do { - s0 = vld1q_u16(src); - s1 = vld1q_u16(src + 8); - s2 = vld1q_u16(src + 16); - s3 = vld1q_u16(src + 24); - src += src_stride; - - vst1q_u16(dst, s0); - vst1q_u16(dst + 8, s1); - vst1q_u16(dst + 16, s2); - vst1q_u16(dst + 24, s3); - dst += dst_stride; - } while (--h != 0); - } else { // copy64 - uint16x8_t s0, s1, s2, s3, s4, s5, s6, s7; - do { - s0 = vld1q_u16(src); - s1 = vld1q_u16(src + 8); - s2 = vld1q_u16(src + 16); - s3 = vld1q_u16(src + 24); - s4 = vld1q_u16(src + 32); - s5 = vld1q_u16(src + 40); - s6 = vld1q_u16(src + 48); - s7 = vld1q_u16(src + 56); - src += src_stride; - - vst1q_u16(dst, s0); - vst1q_u16(dst + 8, s1); - vst1q_u16(dst + 16, s2); - vst1q_u16(dst + 24, s3); - vst1q_u16(dst + 32, s4); - vst1q_u16(dst + 40, s5); - vst1q_u16(dst + 48, s6); - vst1q_u16(dst + 56, s7); - dst += dst_stride; - } while (--h != 0); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct16x16_1_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct16x16_1_add_neon.c deleted file mode 100644 index bf5192a6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct16x16_1_add_neon.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/inv_txfm.h" - -static INLINE void idct16x16_1_add_pos_kernel(uint8_t **dest, const int stride, - const uint8x16_t res) { - const uint8x16_t a = vld1q_u8(*dest); - const uint8x16_t b = vqaddq_u8(a, res); - vst1q_u8(*dest, b); - *dest += stride; -} - -static INLINE void idct16x16_1_add_neg_kernel(uint8_t **dest, const int stride, - const uint8x16_t res) { - const uint8x16_t a = vld1q_u8(*dest); - const uint8x16_t b = vqsubq_u8(a, res); - vst1q_u8(*dest, b); - *dest += stride; -} - -void vpx_idct16x16_1_add_neon(const tran_low_t *input, uint8_t *dest, - int stride) { - const int16_t out0 = - WRAPLOW(dct_const_round_shift((int16_t)input[0] * cospi_16_64)); - const int16_t out1 = WRAPLOW(dct_const_round_shift(out0 * cospi_16_64)); - const int16_t a1 = ROUND_POWER_OF_TWO(out1, 6); - - if (a1 >= 0) { - const uint8x16_t dc = create_dcq(a1); - idct16x16_1_add_pos_kernel(&dest, stride, dc); - idct16x16_1_add_pos_kernel(&dest, stride, dc); - idct16x16_1_add_pos_kernel(&dest, stride, dc); - idct16x16_1_add_pos_kernel(&dest, stride, dc); - idct16x16_1_add_pos_kernel(&dest, stride, dc); - idct16x16_1_add_pos_kernel(&dest, stride, dc); - idct16x16_1_add_pos_kernel(&dest, stride, dc); - idct16x16_1_add_pos_kernel(&dest, stride, dc); - idct16x16_1_add_pos_kernel(&dest, stride, dc); - idct16x16_1_add_pos_kernel(&dest, stride, dc); - idct16x16_1_add_pos_kernel(&dest, stride, dc); - idct16x16_1_add_pos_kernel(&dest, stride, dc); - idct16x16_1_add_pos_kernel(&dest, stride, dc); - idct16x16_1_add_pos_kernel(&dest, stride, dc); - idct16x16_1_add_pos_kernel(&dest, stride, dc); - idct16x16_1_add_pos_kernel(&dest, stride, dc); - } else { - const uint8x16_t dc = create_dcq(-a1); - idct16x16_1_add_neg_kernel(&dest, stride, dc); - idct16x16_1_add_neg_kernel(&dest, stride, dc); - idct16x16_1_add_neg_kernel(&dest, stride, dc); - idct16x16_1_add_neg_kernel(&dest, stride, dc); - idct16x16_1_add_neg_kernel(&dest, stride, dc); - idct16x16_1_add_neg_kernel(&dest, stride, dc); - idct16x16_1_add_neg_kernel(&dest, stride, dc); - idct16x16_1_add_neg_kernel(&dest, stride, dc); - idct16x16_1_add_neg_kernel(&dest, stride, dc); - idct16x16_1_add_neg_kernel(&dest, stride, dc); - idct16x16_1_add_neg_kernel(&dest, stride, dc); - idct16x16_1_add_neg_kernel(&dest, stride, dc); - idct16x16_1_add_neg_kernel(&dest, stride, dc); - idct16x16_1_add_neg_kernel(&dest, stride, dc); - idct16x16_1_add_neg_kernel(&dest, stride, dc); - idct16x16_1_add_neg_kernel(&dest, stride, dc); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct16x16_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct16x16_add_neon.c deleted file mode 100644 index fc7f4a77..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct16x16_add_neon.c +++ /dev/null @@ -1,764 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/txfm_common.h" - -static INLINE void wrap_low_4x2(const int32x4_t *const t32, int16x4_t *const d0, - int16x4_t *const d1) { - *d0 = vrshrn_n_s32(t32[0], DCT_CONST_BITS); - *d1 = vrshrn_n_s32(t32[1], DCT_CONST_BITS); -} - -static INLINE void idct_cospi_8_24_d_kernel(const int16x4_t s0, - const int16x4_t s1, - const int16x4_t cospi_0_8_16_24, - int32x4_t *const t32) { - t32[0] = vmull_lane_s16(s0, cospi_0_8_16_24, 3); - t32[1] = vmull_lane_s16(s1, cospi_0_8_16_24, 3); - t32[0] = vmlsl_lane_s16(t32[0], s1, cospi_0_8_16_24, 1); - t32[1] = vmlal_lane_s16(t32[1], s0, cospi_0_8_16_24, 1); -} - -static INLINE void idct_cospi_8_24_d(const int16x4_t s0, const int16x4_t s1, - const int16x4_t cospi_0_8_16_24, - int16x4_t *const d0, int16x4_t *const d1) { - int32x4_t t32[2]; - - idct_cospi_8_24_d_kernel(s0, s1, cospi_0_8_16_24, t32); - wrap_low_4x2(t32, d0, d1); -} - -static INLINE void idct_cospi_8_24_neg_d(const int16x4_t s0, const int16x4_t s1, - const int16x4_t cospi_0_8_16_24, - int16x4_t *const d0, - int16x4_t *const d1) { - int32x4_t t32[2]; - - idct_cospi_8_24_d_kernel(s0, s1, cospi_0_8_16_24, t32); - t32[1] = vnegq_s32(t32[1]); - wrap_low_4x2(t32, d0, d1); -} - -static INLINE void idct_cospi_16_16_d(const int16x4_t s0, const int16x4_t s1, - const int16x4_t cospi_0_8_16_24, - int16x4_t *const d0, - int16x4_t *const d1) { - int32x4_t t32[3]; - - t32[2] = vmull_lane_s16(s1, cospi_0_8_16_24, 2); - t32[0] = vmlsl_lane_s16(t32[2], s0, cospi_0_8_16_24, 2); - t32[1] = vmlal_lane_s16(t32[2], s0, cospi_0_8_16_24, 2); - wrap_low_4x2(t32, d0, d1); -} - -void vpx_idct16x16_256_add_half1d(const void *const input, int16_t *output, - void *const dest, const int stride, - const int highbd_flag) { - const int16x8_t cospis0 = vld1q_s16(kCospi); - const int16x8_t cospis1 = vld1q_s16(kCospi + 8); - const int16x4_t cospi_0_8_16_24 = vget_low_s16(cospis0); - const int16x4_t cospi_4_12_20N_28 = vget_high_s16(cospis0); - const int16x4_t cospi_2_30_10_22 = vget_low_s16(cospis1); - const int16x4_t cospi_6_26N_14_18N = vget_high_s16(cospis1); - int16x8_t in[16], step1[16], step2[16], out[16]; - - // Load input (16x8) - if (output) { - const tran_low_t *inputT = (const tran_low_t *)input; - in[0] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[8] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[1] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[9] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[2] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[10] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[3] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[11] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[4] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[12] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[5] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[13] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[6] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[14] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[7] = load_tran_low_to_s16q(inputT); - inputT += 8; - in[15] = load_tran_low_to_s16q(inputT); - } else { - const int16_t *inputT = (const int16_t *)input; - in[0] = vld1q_s16(inputT); - inputT += 8; - in[8] = vld1q_s16(inputT); - inputT += 8; - in[1] = vld1q_s16(inputT); - inputT += 8; - in[9] = vld1q_s16(inputT); - inputT += 8; - in[2] = vld1q_s16(inputT); - inputT += 8; - in[10] = vld1q_s16(inputT); - inputT += 8; - in[3] = vld1q_s16(inputT); - inputT += 8; - in[11] = vld1q_s16(inputT); - inputT += 8; - in[4] = vld1q_s16(inputT); - inputT += 8; - in[12] = vld1q_s16(inputT); - inputT += 8; - in[5] = vld1q_s16(inputT); - inputT += 8; - in[13] = vld1q_s16(inputT); - inputT += 8; - in[6] = vld1q_s16(inputT); - inputT += 8; - in[14] = vld1q_s16(inputT); - inputT += 8; - in[7] = vld1q_s16(inputT); - inputT += 8; - in[15] = vld1q_s16(inputT); - } - - // Transpose - transpose_s16_8x8(&in[0], &in[1], &in[2], &in[3], &in[4], &in[5], &in[6], - &in[7]); - transpose_s16_8x8(&in[8], &in[9], &in[10], &in[11], &in[12], &in[13], &in[14], - &in[15]); - - // stage 1 - step1[0] = in[0 / 2]; - step1[1] = in[16 / 2]; - step1[2] = in[8 / 2]; - step1[3] = in[24 / 2]; - step1[4] = in[4 / 2]; - step1[5] = in[20 / 2]; - step1[6] = in[12 / 2]; - step1[7] = in[28 / 2]; - step1[8] = in[2 / 2]; - step1[9] = in[18 / 2]; - step1[10] = in[10 / 2]; - step1[11] = in[26 / 2]; - step1[12] = in[6 / 2]; - step1[13] = in[22 / 2]; - step1[14] = in[14 / 2]; - step1[15] = in[30 / 2]; - - // stage 2 - step2[0] = step1[0]; - step2[1] = step1[1]; - step2[2] = step1[2]; - step2[3] = step1[3]; - step2[4] = step1[4]; - step2[5] = step1[5]; - step2[6] = step1[6]; - step2[7] = step1[7]; - idct_cospi_2_30(step1[8], step1[15], cospi_2_30_10_22, &step2[8], &step2[15]); - idct_cospi_14_18(step1[9], step1[14], cospi_6_26N_14_18N, &step2[9], - &step2[14]); - idct_cospi_10_22(step1[10], step1[13], cospi_2_30_10_22, &step2[10], - &step2[13]); - idct_cospi_6_26(step1[11], step1[12], cospi_6_26N_14_18N, &step2[11], - &step2[12]); - - // stage 3 - step1[0] = step2[0]; - step1[1] = step2[1]; - step1[2] = step2[2]; - step1[3] = step2[3]; - idct_cospi_4_28(step2[4], step2[7], cospi_4_12_20N_28, &step1[4], &step1[7]); - idct_cospi_12_20(step2[5], step2[6], cospi_4_12_20N_28, &step1[5], &step1[6]); - step1[8] = vaddq_s16(step2[8], step2[9]); - step1[9] = vsubq_s16(step2[8], step2[9]); - step1[10] = vsubq_s16(step2[11], step2[10]); - step1[11] = vaddq_s16(step2[11], step2[10]); - step1[12] = vaddq_s16(step2[12], step2[13]); - step1[13] = vsubq_s16(step2[12], step2[13]); - step1[14] = vsubq_s16(step2[15], step2[14]); - step1[15] = vaddq_s16(step2[15], step2[14]); - - // stage 4 - idct_cospi_16_16_q(step1[1], step1[0], cospi_0_8_16_24, &step2[1], &step2[0]); - idct_cospi_8_24_q(step1[2], step1[3], cospi_0_8_16_24, &step2[2], &step2[3]); - step2[4] = vaddq_s16(step1[4], step1[5]); - step2[5] = vsubq_s16(step1[4], step1[5]); - step2[6] = vsubq_s16(step1[7], step1[6]); - step2[7] = vaddq_s16(step1[7], step1[6]); - step2[8] = step1[8]; - idct_cospi_8_24_q(step1[14], step1[9], cospi_0_8_16_24, &step2[9], - &step2[14]); - idct_cospi_8_24_neg_q(step1[13], step1[10], cospi_0_8_16_24, &step2[13], - &step2[10]); - step2[11] = step1[11]; - step2[12] = step1[12]; - step2[15] = step1[15]; - - // stage 5 - step1[0] = vaddq_s16(step2[0], step2[3]); - step1[1] = vaddq_s16(step2[1], step2[2]); - step1[2] = vsubq_s16(step2[1], step2[2]); - step1[3] = vsubq_s16(step2[0], step2[3]); - step1[4] = step2[4]; - idct_cospi_16_16_q(step2[5], step2[6], cospi_0_8_16_24, &step1[5], &step1[6]); - step1[7] = step2[7]; - step1[8] = vaddq_s16(step2[8], step2[11]); - step1[9] = vaddq_s16(step2[9], step2[10]); - step1[10] = vsubq_s16(step2[9], step2[10]); - step1[11] = vsubq_s16(step2[8], step2[11]); - step1[12] = vsubq_s16(step2[15], step2[12]); - step1[13] = vsubq_s16(step2[14], step2[13]); - step1[14] = vaddq_s16(step2[14], step2[13]); - step1[15] = vaddq_s16(step2[15], step2[12]); - - // stage 6 - step2[0] = vaddq_s16(step1[0], step1[7]); - step2[1] = vaddq_s16(step1[1], step1[6]); - step2[2] = vaddq_s16(step1[2], step1[5]); - step2[3] = vaddq_s16(step1[3], step1[4]); - step2[4] = vsubq_s16(step1[3], step1[4]); - step2[5] = vsubq_s16(step1[2], step1[5]); - step2[6] = vsubq_s16(step1[1], step1[6]); - step2[7] = vsubq_s16(step1[0], step1[7]); - idct_cospi_16_16_q(step1[10], step1[13], cospi_0_8_16_24, &step2[10], - &step2[13]); - idct_cospi_16_16_q(step1[11], step1[12], cospi_0_8_16_24, &step2[11], - &step2[12]); - step2[8] = step1[8]; - step2[9] = step1[9]; - step2[14] = step1[14]; - step2[15] = step1[15]; - - // stage 7 - idct16x16_add_stage7(step2, out); - - if (output) { - idct16x16_store_pass1(out, output); - } else { - if (highbd_flag) { - idct16x16_add_store_bd8(out, dest, stride); - } else { - idct16x16_add_store(out, dest, stride); - } - } -} - -void vpx_idct16x16_38_add_half1d(const void *const input, int16_t *const output, - void *const dest, const int stride, - const int highbd_flag) { - const int16x8_t cospis0 = vld1q_s16(kCospi); - const int16x8_t cospis1 = vld1q_s16(kCospi + 8); - const int16x8_t cospisd0 = vaddq_s16(cospis0, cospis0); - const int16x8_t cospisd1 = vaddq_s16(cospis1, cospis1); - const int16x4_t cospi_0_8_16_24 = vget_low_s16(cospis0); - const int16x4_t cospid_0_8_16_24 = vget_low_s16(cospisd0); - const int16x4_t cospid_4_12_20N_28 = vget_high_s16(cospisd0); - const int16x4_t cospid_2_30_10_22 = vget_low_s16(cospisd1); - const int16x4_t cospid_6_26_14_18N = vget_high_s16(cospisd1); - int16x8_t in[8], step1[16], step2[16], out[16]; - - // Load input (8x8) - if (output) { - const tran_low_t *inputT = (const tran_low_t *)input; - in[0] = load_tran_low_to_s16q(inputT); - inputT += 16; - in[1] = load_tran_low_to_s16q(inputT); - inputT += 16; - in[2] = load_tran_low_to_s16q(inputT); - inputT += 16; - in[3] = load_tran_low_to_s16q(inputT); - inputT += 16; - in[4] = load_tran_low_to_s16q(inputT); - inputT += 16; - in[5] = load_tran_low_to_s16q(inputT); - inputT += 16; - in[6] = load_tran_low_to_s16q(inputT); - inputT += 16; - in[7] = load_tran_low_to_s16q(inputT); - } else { - const int16_t *inputT = (const int16_t *)input; - in[0] = vld1q_s16(inputT); - inputT += 16; - in[1] = vld1q_s16(inputT); - inputT += 16; - in[2] = vld1q_s16(inputT); - inputT += 16; - in[3] = vld1q_s16(inputT); - inputT += 16; - in[4] = vld1q_s16(inputT); - inputT += 16; - in[5] = vld1q_s16(inputT); - inputT += 16; - in[6] = vld1q_s16(inputT); - inputT += 16; - in[7] = vld1q_s16(inputT); - } - - // Transpose - transpose_s16_8x8(&in[0], &in[1], &in[2], &in[3], &in[4], &in[5], &in[6], - &in[7]); - - // stage 1 - step1[0] = in[0 / 2]; - step1[2] = in[8 / 2]; - step1[4] = in[4 / 2]; - step1[6] = in[12 / 2]; - step1[8] = in[2 / 2]; - step1[10] = in[10 / 2]; - step1[12] = in[6 / 2]; - step1[14] = in[14 / 2]; // 0 in pass 1 - - // stage 2 - step2[0] = step1[0]; - step2[2] = step1[2]; - step2[4] = step1[4]; - step2[6] = step1[6]; - step2[8] = vqrdmulhq_lane_s16(step1[8], cospid_2_30_10_22, 1); - step2[9] = vqrdmulhq_lane_s16(step1[14], cospid_6_26_14_18N, 3); - step2[10] = vqrdmulhq_lane_s16(step1[10], cospid_2_30_10_22, 3); - step2[11] = vqrdmulhq_lane_s16(step1[12], cospid_6_26_14_18N, 1); - step2[12] = vqrdmulhq_lane_s16(step1[12], cospid_6_26_14_18N, 0); - step2[13] = vqrdmulhq_lane_s16(step1[10], cospid_2_30_10_22, 2); - step2[14] = vqrdmulhq_lane_s16(step1[14], cospid_6_26_14_18N, 2); - step2[15] = vqrdmulhq_lane_s16(step1[8], cospid_2_30_10_22, 0); - - // stage 3 - step1[0] = step2[0]; - step1[2] = step2[2]; - step1[4] = vqrdmulhq_lane_s16(step2[4], cospid_4_12_20N_28, 3); - step1[5] = vqrdmulhq_lane_s16(step2[6], cospid_4_12_20N_28, 2); - step1[6] = vqrdmulhq_lane_s16(step2[6], cospid_4_12_20N_28, 1); - step1[7] = vqrdmulhq_lane_s16(step2[4], cospid_4_12_20N_28, 0); - step1[8] = vaddq_s16(step2[8], step2[9]); - step1[9] = vsubq_s16(step2[8], step2[9]); - step1[10] = vsubq_s16(step2[11], step2[10]); - step1[11] = vaddq_s16(step2[11], step2[10]); - step1[12] = vaddq_s16(step2[12], step2[13]); - step1[13] = vsubq_s16(step2[12], step2[13]); - step1[14] = vsubq_s16(step2[15], step2[14]); - step1[15] = vaddq_s16(step2[15], step2[14]); - - // stage 4 - step2[0] = step2[1] = vqrdmulhq_lane_s16(step1[0], cospid_0_8_16_24, 2); - step2[2] = vqrdmulhq_lane_s16(step1[2], cospid_0_8_16_24, 3); - step2[3] = vqrdmulhq_lane_s16(step1[2], cospid_0_8_16_24, 1); - step2[4] = vaddq_s16(step1[4], step1[5]); - step2[5] = vsubq_s16(step1[4], step1[5]); - step2[6] = vsubq_s16(step1[7], step1[6]); - step2[7] = vaddq_s16(step1[7], step1[6]); - step2[8] = step1[8]; - idct_cospi_8_24_q(step1[14], step1[9], cospi_0_8_16_24, &step2[9], - &step2[14]); - idct_cospi_8_24_neg_q(step1[13], step1[10], cospi_0_8_16_24, &step2[13], - &step2[10]); - step2[11] = step1[11]; - step2[12] = step1[12]; - step2[15] = step1[15]; - - // stage 5 - step1[0] = vaddq_s16(step2[0], step2[3]); - step1[1] = vaddq_s16(step2[1], step2[2]); - step1[2] = vsubq_s16(step2[1], step2[2]); - step1[3] = vsubq_s16(step2[0], step2[3]); - step1[4] = step2[4]; - idct_cospi_16_16_q(step2[5], step2[6], cospi_0_8_16_24, &step1[5], &step1[6]); - step1[7] = step2[7]; - step1[8] = vaddq_s16(step2[8], step2[11]); - step1[9] = vaddq_s16(step2[9], step2[10]); - step1[10] = vsubq_s16(step2[9], step2[10]); - step1[11] = vsubq_s16(step2[8], step2[11]); - step1[12] = vsubq_s16(step2[15], step2[12]); - step1[13] = vsubq_s16(step2[14], step2[13]); - step1[14] = vaddq_s16(step2[14], step2[13]); - step1[15] = vaddq_s16(step2[15], step2[12]); - - // stage 6 - step2[0] = vaddq_s16(step1[0], step1[7]); - step2[1] = vaddq_s16(step1[1], step1[6]); - step2[2] = vaddq_s16(step1[2], step1[5]); - step2[3] = vaddq_s16(step1[3], step1[4]); - step2[4] = vsubq_s16(step1[3], step1[4]); - step2[5] = vsubq_s16(step1[2], step1[5]); - step2[6] = vsubq_s16(step1[1], step1[6]); - step2[7] = vsubq_s16(step1[0], step1[7]); - idct_cospi_16_16_q(step1[10], step1[13], cospi_0_8_16_24, &step2[10], - &step2[13]); - idct_cospi_16_16_q(step1[11], step1[12], cospi_0_8_16_24, &step2[11], - &step2[12]); - step2[8] = step1[8]; - step2[9] = step1[9]; - step2[14] = step1[14]; - step2[15] = step1[15]; - - // stage 7 - idct16x16_add_stage7(step2, out); - - if (output) { - idct16x16_store_pass1(out, output); - } else { - if (highbd_flag) { - idct16x16_add_store_bd8(out, dest, stride); - } else { - idct16x16_add_store(out, dest, stride); - } - } -} - -void vpx_idct16x16_10_add_half1d_pass1(const tran_low_t *input, - int16_t *output) { - const int16x8_t cospis0 = vld1q_s16(kCospi); - const int16x8_t cospis1 = vld1q_s16(kCospi + 8); - const int16x8_t cospisd0 = vaddq_s16(cospis0, cospis0); - const int16x8_t cospisd1 = vaddq_s16(cospis1, cospis1); - const int16x4_t cospi_0_8_16_24 = vget_low_s16(cospis0); - const int16x4_t cospid_0_8_16_24 = vget_low_s16(cospisd0); - const int16x4_t cospid_4_12_20N_28 = vget_high_s16(cospisd0); - const int16x4_t cospid_2_30_10_22 = vget_low_s16(cospisd1); - const int16x4_t cospid_6_26_14_18N = vget_high_s16(cospisd1); - int16x4_t in[4], step1[16], step2[16], out[16]; - - // Load input (4x4) - in[0] = load_tran_low_to_s16d(input); - input += 16; - in[1] = load_tran_low_to_s16d(input); - input += 16; - in[2] = load_tran_low_to_s16d(input); - input += 16; - in[3] = load_tran_low_to_s16d(input); - - // Transpose - transpose_s16_4x4d(&in[0], &in[1], &in[2], &in[3]); - - // stage 1 - step1[0] = in[0 / 2]; - step1[4] = in[4 / 2]; - step1[8] = in[2 / 2]; - step1[12] = in[6 / 2]; - - // stage 2 - step2[0] = step1[0]; - step2[4] = step1[4]; - step2[8] = vqrdmulh_lane_s16(step1[8], cospid_2_30_10_22, 1); - step2[11] = vqrdmulh_lane_s16(step1[12], cospid_6_26_14_18N, 1); - step2[12] = vqrdmulh_lane_s16(step1[12], cospid_6_26_14_18N, 0); - step2[15] = vqrdmulh_lane_s16(step1[8], cospid_2_30_10_22, 0); - - // stage 3 - step1[0] = step2[0]; - step1[4] = vqrdmulh_lane_s16(step2[4], cospid_4_12_20N_28, 3); - step1[7] = vqrdmulh_lane_s16(step2[4], cospid_4_12_20N_28, 0); - step1[8] = step2[8]; - step1[9] = step2[8]; - step1[10] = step2[11]; - step1[11] = step2[11]; - step1[12] = step2[12]; - step1[13] = step2[12]; - step1[14] = step2[15]; - step1[15] = step2[15]; - - // stage 4 - step2[0] = step2[1] = vqrdmulh_lane_s16(step1[0], cospid_0_8_16_24, 2); - step2[4] = step1[4]; - step2[5] = step1[4]; - step2[6] = step1[7]; - step2[7] = step1[7]; - step2[8] = step1[8]; - idct_cospi_8_24_d(step1[14], step1[9], cospi_0_8_16_24, &step2[9], - &step2[14]); - idct_cospi_8_24_neg_d(step1[13], step1[10], cospi_0_8_16_24, &step2[13], - &step2[10]); - step2[11] = step1[11]; - step2[12] = step1[12]; - step2[15] = step1[15]; - - // stage 5 - step1[0] = step2[0]; - step1[1] = step2[1]; - step1[2] = step2[1]; - step1[3] = step2[0]; - step1[4] = step2[4]; - idct_cospi_16_16_d(step2[5], step2[6], cospi_0_8_16_24, &step1[5], &step1[6]); - step1[7] = step2[7]; - step1[8] = vadd_s16(step2[8], step2[11]); - step1[9] = vadd_s16(step2[9], step2[10]); - step1[10] = vsub_s16(step2[9], step2[10]); - step1[11] = vsub_s16(step2[8], step2[11]); - step1[12] = vsub_s16(step2[15], step2[12]); - step1[13] = vsub_s16(step2[14], step2[13]); - step1[14] = vadd_s16(step2[14], step2[13]); - step1[15] = vadd_s16(step2[15], step2[12]); - - // stage 6 - step2[0] = vadd_s16(step1[0], step1[7]); - step2[1] = vadd_s16(step1[1], step1[6]); - step2[2] = vadd_s16(step1[2], step1[5]); - step2[3] = vadd_s16(step1[3], step1[4]); - step2[4] = vsub_s16(step1[3], step1[4]); - step2[5] = vsub_s16(step1[2], step1[5]); - step2[6] = vsub_s16(step1[1], step1[6]); - step2[7] = vsub_s16(step1[0], step1[7]); - idct_cospi_16_16_d(step1[10], step1[13], cospi_0_8_16_24, &step2[10], - &step2[13]); - idct_cospi_16_16_d(step1[11], step1[12], cospi_0_8_16_24, &step2[11], - &step2[12]); - step2[8] = step1[8]; - step2[9] = step1[9]; - step2[14] = step1[14]; - step2[15] = step1[15]; - - // stage 7 - out[0] = vadd_s16(step2[0], step2[15]); - out[1] = vadd_s16(step2[1], step2[14]); - out[2] = vadd_s16(step2[2], step2[13]); - out[3] = vadd_s16(step2[3], step2[12]); - out[4] = vadd_s16(step2[4], step2[11]); - out[5] = vadd_s16(step2[5], step2[10]); - out[6] = vadd_s16(step2[6], step2[9]); - out[7] = vadd_s16(step2[7], step2[8]); - out[8] = vsub_s16(step2[7], step2[8]); - out[9] = vsub_s16(step2[6], step2[9]); - out[10] = vsub_s16(step2[5], step2[10]); - out[11] = vsub_s16(step2[4], step2[11]); - out[12] = vsub_s16(step2[3], step2[12]); - out[13] = vsub_s16(step2[2], step2[13]); - out[14] = vsub_s16(step2[1], step2[14]); - out[15] = vsub_s16(step2[0], step2[15]); - - // pass 1: save the result into output - vst1_s16(output, out[0]); - output += 4; - vst1_s16(output, out[1]); - output += 4; - vst1_s16(output, out[2]); - output += 4; - vst1_s16(output, out[3]); - output += 4; - vst1_s16(output, out[4]); - output += 4; - vst1_s16(output, out[5]); - output += 4; - vst1_s16(output, out[6]); - output += 4; - vst1_s16(output, out[7]); - output += 4; - vst1_s16(output, out[8]); - output += 4; - vst1_s16(output, out[9]); - output += 4; - vst1_s16(output, out[10]); - output += 4; - vst1_s16(output, out[11]); - output += 4; - vst1_s16(output, out[12]); - output += 4; - vst1_s16(output, out[13]); - output += 4; - vst1_s16(output, out[14]); - output += 4; - vst1_s16(output, out[15]); -} - -void vpx_idct16x16_10_add_half1d_pass2(const int16_t *input, - int16_t *const output, void *const dest, - const int stride, - const int highbd_flag) { - const int16x8_t cospis0 = vld1q_s16(kCospi); - const int16x8_t cospis1 = vld1q_s16(kCospi + 8); - const int16x8_t cospisd0 = vaddq_s16(cospis0, cospis0); - const int16x8_t cospisd1 = vaddq_s16(cospis1, cospis1); - const int16x4_t cospi_0_8_16_24 = vget_low_s16(cospis0); - const int16x4_t cospid_0_8_16_24 = vget_low_s16(cospisd0); - const int16x4_t cospid_4_12_20N_28 = vget_high_s16(cospisd0); - const int16x4_t cospid_2_30_10_22 = vget_low_s16(cospisd1); - const int16x4_t cospid_6_26_14_18N = vget_high_s16(cospisd1); - int16x4_t ind[8]; - int16x8_t in[4], step1[16], step2[16], out[16]; - - // Load input (4x8) - ind[0] = vld1_s16(input); - input += 4; - ind[1] = vld1_s16(input); - input += 4; - ind[2] = vld1_s16(input); - input += 4; - ind[3] = vld1_s16(input); - input += 4; - ind[4] = vld1_s16(input); - input += 4; - ind[5] = vld1_s16(input); - input += 4; - ind[6] = vld1_s16(input); - input += 4; - ind[7] = vld1_s16(input); - - // Transpose - transpose_s16_4x8(ind[0], ind[1], ind[2], ind[3], ind[4], ind[5], ind[6], - ind[7], &in[0], &in[1], &in[2], &in[3]); - - // stage 1 - step1[0] = in[0 / 2]; - step1[4] = in[4 / 2]; - step1[8] = in[2 / 2]; - step1[12] = in[6 / 2]; - - // stage 2 - step2[0] = step1[0]; - step2[4] = step1[4]; - step2[8] = vqrdmulhq_lane_s16(step1[8], cospid_2_30_10_22, 1); - step2[11] = vqrdmulhq_lane_s16(step1[12], cospid_6_26_14_18N, 1); - step2[12] = vqrdmulhq_lane_s16(step1[12], cospid_6_26_14_18N, 0); - step2[15] = vqrdmulhq_lane_s16(step1[8], cospid_2_30_10_22, 0); - - // stage 3 - step1[0] = step2[0]; - step1[4] = vqrdmulhq_lane_s16(step2[4], cospid_4_12_20N_28, 3); - step1[7] = vqrdmulhq_lane_s16(step2[4], cospid_4_12_20N_28, 0); - step1[8] = step2[8]; - step1[9] = step2[8]; - step1[10] = step2[11]; - step1[11] = step2[11]; - step1[12] = step2[12]; - step1[13] = step2[12]; - step1[14] = step2[15]; - step1[15] = step2[15]; - - // stage 4 - step2[0] = step2[1] = vqrdmulhq_lane_s16(step1[0], cospid_0_8_16_24, 2); - step2[4] = step1[4]; - step2[5] = step1[4]; - step2[6] = step1[7]; - step2[7] = step1[7]; - step2[8] = step1[8]; - idct_cospi_8_24_q(step1[14], step1[9], cospi_0_8_16_24, &step2[9], - &step2[14]); - idct_cospi_8_24_neg_q(step1[13], step1[10], cospi_0_8_16_24, &step2[13], - &step2[10]); - step2[11] = step1[11]; - step2[12] = step1[12]; - step2[15] = step1[15]; - - // stage 5 - step1[0] = step2[0]; - step1[1] = step2[1]; - step1[2] = step2[1]; - step1[3] = step2[0]; - step1[4] = step2[4]; - idct_cospi_16_16_q(step2[5], step2[6], cospi_0_8_16_24, &step1[5], &step1[6]); - step1[7] = step2[7]; - step1[8] = vaddq_s16(step2[8], step2[11]); - step1[9] = vaddq_s16(step2[9], step2[10]); - step1[10] = vsubq_s16(step2[9], step2[10]); - step1[11] = vsubq_s16(step2[8], step2[11]); - step1[12] = vsubq_s16(step2[15], step2[12]); - step1[13] = vsubq_s16(step2[14], step2[13]); - step1[14] = vaddq_s16(step2[14], step2[13]); - step1[15] = vaddq_s16(step2[15], step2[12]); - - // stage 6 - step2[0] = vaddq_s16(step1[0], step1[7]); - step2[1] = vaddq_s16(step1[1], step1[6]); - step2[2] = vaddq_s16(step1[2], step1[5]); - step2[3] = vaddq_s16(step1[3], step1[4]); - step2[4] = vsubq_s16(step1[3], step1[4]); - step2[5] = vsubq_s16(step1[2], step1[5]); - step2[6] = vsubq_s16(step1[1], step1[6]); - step2[7] = vsubq_s16(step1[0], step1[7]); - idct_cospi_16_16_q(step1[10], step1[13], cospi_0_8_16_24, &step2[10], - &step2[13]); - idct_cospi_16_16_q(step1[11], step1[12], cospi_0_8_16_24, &step2[11], - &step2[12]); - step2[8] = step1[8]; - step2[9] = step1[9]; - step2[14] = step1[14]; - step2[15] = step1[15]; - - // stage 7 - idct16x16_add_stage7(step2, out); - - if (output) { - idct16x16_store_pass1(out, output); - } else { - if (highbd_flag) { - idct16x16_add_store_bd8(out, dest, stride); - } else { - idct16x16_add_store(out, dest, stride); - } - } -} - -void vpx_idct16x16_256_add_neon(const tran_low_t *input, uint8_t *dest, - int stride) { - int16_t row_idct_output[16 * 16]; - - // pass 1 - // Parallel idct on the upper 8 rows - vpx_idct16x16_256_add_half1d(input, row_idct_output, dest, stride, 0); - - // Parallel idct on the lower 8 rows - vpx_idct16x16_256_add_half1d(input + 8 * 16, row_idct_output + 8, dest, - stride, 0); - - // pass 2 - // Parallel idct to get the left 8 columns - vpx_idct16x16_256_add_half1d(row_idct_output, NULL, dest, stride, 0); - - // Parallel idct to get the right 8 columns - vpx_idct16x16_256_add_half1d(row_idct_output + 16 * 8, NULL, dest + 8, stride, - 0); -} - -void vpx_idct16x16_38_add_neon(const tran_low_t *input, uint8_t *dest, - int stride) { - int16_t row_idct_output[16 * 16]; - - // pass 1 - // Parallel idct on the upper 8 rows - vpx_idct16x16_38_add_half1d(input, row_idct_output, dest, stride, 0); - - // pass 2 - // Parallel idct to get the left 8 columns - vpx_idct16x16_38_add_half1d(row_idct_output, NULL, dest, stride, 0); - - // Parallel idct to get the right 8 columns - vpx_idct16x16_38_add_half1d(row_idct_output + 16 * 8, NULL, dest + 8, stride, - 0); -} - -void vpx_idct16x16_10_add_neon(const tran_low_t *input, uint8_t *dest, - int stride) { - int16_t row_idct_output[4 * 16]; - - // pass 1 - // Parallel idct on the upper 8 rows - vpx_idct16x16_10_add_half1d_pass1(input, row_idct_output); - - // pass 2 - // Parallel idct to get the left 8 columns - vpx_idct16x16_10_add_half1d_pass2(row_idct_output, NULL, dest, stride, 0); - - // Parallel idct to get the right 8 columns - vpx_idct16x16_10_add_half1d_pass2(row_idct_output + 4 * 8, NULL, dest + 8, - stride, 0); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct32x32_135_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct32x32_135_add_neon.c deleted file mode 100644 index 057731ad..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct32x32_135_add_neon.c +++ /dev/null @@ -1,674 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/txfm_common.h" - -static INLINE void load_8x8_s16(const tran_low_t *input, int16x8_t *const in0, - int16x8_t *const in1, int16x8_t *const in2, - int16x8_t *const in3, int16x8_t *const in4, - int16x8_t *const in5, int16x8_t *const in6, - int16x8_t *const in7) { - *in0 = load_tran_low_to_s16q(input); - input += 32; - *in1 = load_tran_low_to_s16q(input); - input += 32; - *in2 = load_tran_low_to_s16q(input); - input += 32; - *in3 = load_tran_low_to_s16q(input); - input += 32; - *in4 = load_tran_low_to_s16q(input); - input += 32; - *in5 = load_tran_low_to_s16q(input); - input += 32; - *in6 = load_tran_low_to_s16q(input); - input += 32; - *in7 = load_tran_low_to_s16q(input); -} - -static INLINE void load_4x8_s16(const tran_low_t *input, int16x4_t *const in0, - int16x4_t *const in1, int16x4_t *const in2, - int16x4_t *const in3, int16x4_t *const in4, - int16x4_t *const in5, int16x4_t *const in6, - int16x4_t *const in7) { - *in0 = load_tran_low_to_s16d(input); - input += 32; - *in1 = load_tran_low_to_s16d(input); - input += 32; - *in2 = load_tran_low_to_s16d(input); - input += 32; - *in3 = load_tran_low_to_s16d(input); - input += 32; - *in4 = load_tran_low_to_s16d(input); - input += 32; - *in5 = load_tran_low_to_s16d(input); - input += 32; - *in6 = load_tran_low_to_s16d(input); - input += 32; - *in7 = load_tran_low_to_s16d(input); -} - -// Only for the first pass of the _135_ variant. Since it only uses values from -// the top left 16x16 it can safely assume all the remaining values are 0 and -// skip an awful lot of calculations. In fact, only the first 12 columns make -// the cut. None of the elements in the 13th, 14th, 15th or 16th columns are -// used so it skips any calls to input[12|13|14|15] too. -// In C this does a single row of 32 for each call. Here it transposes the top -// left 12x8 to allow using SIMD. - -// vp9/common/vp9_scan.c:vp9_default_iscan_32x32 arranges the first 135 non-zero -// coefficients as follows: -// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 -// 0 0 2 5 10 17 25 38 47 62 83 101 121 -// 1 1 4 8 15 22 30 45 58 74 92 112 133 -// 2 3 7 12 18 28 36 52 64 82 102 118 -// 3 6 11 16 23 31 43 60 73 90 109 126 -// 4 9 14 19 29 37 50 65 78 98 116 134 -// 5 13 20 26 35 44 54 72 85 105 123 -// 6 21 27 33 42 53 63 80 94 113 132 -// 7 24 32 39 48 57 71 88 104 120 -// 8 34 40 46 56 68 81 96 111 130 -// 9 41 49 55 67 77 91 107 124 -// 10 51 59 66 76 89 99 119 131 -// 11 61 69 75 87 100 114 129 -// 12 70 79 86 97 108 122 -// 13 84 93 103 110 125 -// 14 98 106 115 127 -// 15 117 128 -void vpx_idct32_12_neon(const tran_low_t *const input, int16_t *output) { - int16x4_t tmp[8]; - int16x8_t in[12], s1[32], s2[32], s3[32], s4[32], s5[32], s6[32], s7[32]; - - load_8x8_s16(input, &in[0], &in[1], &in[2], &in[3], &in[4], &in[5], &in[6], - &in[7]); - transpose_s16_8x8(&in[0], &in[1], &in[2], &in[3], &in[4], &in[5], &in[6], - &in[7]); - - load_4x8_s16(input + 8, &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5], - &tmp[6], &tmp[7]); - transpose_s16_4x8(tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], - tmp[7], &in[8], &in[9], &in[10], &in[11]); - - // stage 1 - s1[16] = multiply_shift_and_narrow_s16(in[1], cospi_31_64); - s1[31] = multiply_shift_and_narrow_s16(in[1], cospi_1_64); - - s1[18] = multiply_shift_and_narrow_s16(in[9], cospi_23_64); - s1[29] = multiply_shift_and_narrow_s16(in[9], cospi_9_64); - - s1[19] = multiply_shift_and_narrow_s16(in[7], -cospi_25_64); - s1[28] = multiply_shift_and_narrow_s16(in[7], cospi_7_64); - - s1[20] = multiply_shift_and_narrow_s16(in[5], cospi_27_64); - s1[27] = multiply_shift_and_narrow_s16(in[5], cospi_5_64); - - s1[21] = multiply_shift_and_narrow_s16(in[11], -cospi_21_64); - s1[26] = multiply_shift_and_narrow_s16(in[11], cospi_11_64); - - s1[23] = multiply_shift_and_narrow_s16(in[3], -cospi_29_64); - s1[24] = multiply_shift_and_narrow_s16(in[3], cospi_3_64); - - // stage 2 - s2[8] = multiply_shift_and_narrow_s16(in[2], cospi_30_64); - s2[15] = multiply_shift_and_narrow_s16(in[2], cospi_2_64); - - s2[10] = multiply_shift_and_narrow_s16(in[10], cospi_22_64); - s2[13] = multiply_shift_and_narrow_s16(in[10], cospi_10_64); - - s2[11] = multiply_shift_and_narrow_s16(in[6], -cospi_26_64); - s2[12] = multiply_shift_and_narrow_s16(in[6], cospi_6_64); - - s2[18] = vsubq_s16(s1[19], s1[18]); - s2[19] = vaddq_s16(s1[18], s1[19]); - s2[20] = vaddq_s16(s1[20], s1[21]); - s2[21] = vsubq_s16(s1[20], s1[21]); - s2[26] = vsubq_s16(s1[27], s1[26]); - s2[27] = vaddq_s16(s1[26], s1[27]); - s2[28] = vaddq_s16(s1[28], s1[29]); - s2[29] = vsubq_s16(s1[28], s1[29]); - - // stage 3 - s3[4] = multiply_shift_and_narrow_s16(in[4], cospi_28_64); - s3[7] = multiply_shift_and_narrow_s16(in[4], cospi_4_64); - - s3[10] = vsubq_s16(s2[11], s2[10]); - s3[11] = vaddq_s16(s2[10], s2[11]); - s3[12] = vaddq_s16(s2[12], s2[13]); - s3[13] = vsubq_s16(s2[12], s2[13]); - - s3[17] = multiply_accumulate_shift_and_narrow_s16(s1[16], -cospi_4_64, s1[31], - cospi_28_64); - s3[30] = multiply_accumulate_shift_and_narrow_s16(s1[16], cospi_28_64, s1[31], - cospi_4_64); - - s3[18] = multiply_accumulate_shift_and_narrow_s16(s2[18], -cospi_28_64, - s2[29], -cospi_4_64); - s3[29] = multiply_accumulate_shift_and_narrow_s16(s2[18], -cospi_4_64, s2[29], - cospi_28_64); - - s3[21] = multiply_accumulate_shift_and_narrow_s16(s2[21], -cospi_20_64, - s2[26], cospi_12_64); - s3[26] = multiply_accumulate_shift_and_narrow_s16(s2[21], cospi_12_64, s2[26], - cospi_20_64); - - s3[22] = multiply_accumulate_shift_and_narrow_s16(s1[23], -cospi_12_64, - s1[24], -cospi_20_64); - s3[25] = multiply_accumulate_shift_and_narrow_s16(s1[23], -cospi_20_64, - s1[24], cospi_12_64); - - // stage 4 - s4[0] = multiply_shift_and_narrow_s16(in[0], cospi_16_64); - s4[2] = multiply_shift_and_narrow_s16(in[8], cospi_24_64); - s4[3] = multiply_shift_and_narrow_s16(in[8], cospi_8_64); - - s4[9] = multiply_accumulate_shift_and_narrow_s16(s2[8], -cospi_8_64, s2[15], - cospi_24_64); - s4[14] = multiply_accumulate_shift_and_narrow_s16(s2[8], cospi_24_64, s2[15], - cospi_8_64); - - s4[10] = multiply_accumulate_shift_and_narrow_s16(s3[10], -cospi_24_64, - s3[13], -cospi_8_64); - s4[13] = multiply_accumulate_shift_and_narrow_s16(s3[10], -cospi_8_64, s3[13], - cospi_24_64); - - s4[16] = vaddq_s16(s1[16], s2[19]); - s4[17] = vaddq_s16(s3[17], s3[18]); - s4[18] = vsubq_s16(s3[17], s3[18]); - s4[19] = vsubq_s16(s1[16], s2[19]); - s4[20] = vsubq_s16(s1[23], s2[20]); - s4[21] = vsubq_s16(s3[22], s3[21]); - s4[22] = vaddq_s16(s3[21], s3[22]); - s4[23] = vaddq_s16(s2[20], s1[23]); - s4[24] = vaddq_s16(s1[24], s2[27]); - s4[25] = vaddq_s16(s3[25], s3[26]); - s4[26] = vsubq_s16(s3[25], s3[26]); - s4[27] = vsubq_s16(s1[24], s2[27]); - s4[28] = vsubq_s16(s1[31], s2[28]); - s4[29] = vsubq_s16(s3[30], s3[29]); - s4[30] = vaddq_s16(s3[29], s3[30]); - s4[31] = vaddq_s16(s2[28], s1[31]); - - // stage 5 - s5[0] = vaddq_s16(s4[0], s4[3]); - s5[1] = vaddq_s16(s4[0], s4[2]); - s5[2] = vsubq_s16(s4[0], s4[2]); - s5[3] = vsubq_s16(s4[0], s4[3]); - - s5[5] = sub_multiply_shift_and_narrow_s16(s3[7], s3[4], cospi_16_64); - s5[6] = add_multiply_shift_and_narrow_s16(s3[4], s3[7], cospi_16_64); - - s5[8] = vaddq_s16(s2[8], s3[11]); - s5[9] = vaddq_s16(s4[9], s4[10]); - s5[10] = vsubq_s16(s4[9], s4[10]); - s5[11] = vsubq_s16(s2[8], s3[11]); - s5[12] = vsubq_s16(s2[15], s3[12]); - s5[13] = vsubq_s16(s4[14], s4[13]); - s5[14] = vaddq_s16(s4[13], s4[14]); - s5[15] = vaddq_s16(s2[15], s3[12]); - - s5[18] = multiply_accumulate_shift_and_narrow_s16(s4[18], -cospi_8_64, s4[29], - cospi_24_64); - s5[29] = multiply_accumulate_shift_and_narrow_s16(s4[18], cospi_24_64, s4[29], - cospi_8_64); - - s5[19] = multiply_accumulate_shift_and_narrow_s16(s4[19], -cospi_8_64, s4[28], - cospi_24_64); - s5[28] = multiply_accumulate_shift_and_narrow_s16(s4[19], cospi_24_64, s4[28], - cospi_8_64); - - s5[20] = multiply_accumulate_shift_and_narrow_s16(s4[20], -cospi_24_64, - s4[27], -cospi_8_64); - s5[27] = multiply_accumulate_shift_and_narrow_s16(s4[20], -cospi_8_64, s4[27], - cospi_24_64); - - s5[21] = multiply_accumulate_shift_and_narrow_s16(s4[21], -cospi_24_64, - s4[26], -cospi_8_64); - s5[26] = multiply_accumulate_shift_and_narrow_s16(s4[21], -cospi_8_64, s4[26], - cospi_24_64); - - // stage 6 - s6[0] = vaddq_s16(s5[0], s3[7]); - s6[1] = vaddq_s16(s5[1], s5[6]); - s6[2] = vaddq_s16(s5[2], s5[5]); - s6[3] = vaddq_s16(s5[3], s3[4]); - s6[4] = vsubq_s16(s5[3], s3[4]); - s6[5] = vsubq_s16(s5[2], s5[5]); - s6[6] = vsubq_s16(s5[1], s5[6]); - s6[7] = vsubq_s16(s5[0], s3[7]); - - s6[10] = sub_multiply_shift_and_narrow_s16(s5[13], s5[10], cospi_16_64); - s6[13] = add_multiply_shift_and_narrow_s16(s5[10], s5[13], cospi_16_64); - - s6[11] = sub_multiply_shift_and_narrow_s16(s5[12], s5[11], cospi_16_64); - s6[12] = add_multiply_shift_and_narrow_s16(s5[11], s5[12], cospi_16_64); - - s6[16] = vaddq_s16(s4[16], s4[23]); - s6[17] = vaddq_s16(s4[17], s4[22]); - s6[18] = vaddq_s16(s5[18], s5[21]); - s6[19] = vaddq_s16(s5[19], s5[20]); - s6[20] = vsubq_s16(s5[19], s5[20]); - s6[21] = vsubq_s16(s5[18], s5[21]); - s6[22] = vsubq_s16(s4[17], s4[22]); - s6[23] = vsubq_s16(s4[16], s4[23]); - - s6[24] = vsubq_s16(s4[31], s4[24]); - s6[25] = vsubq_s16(s4[30], s4[25]); - s6[26] = vsubq_s16(s5[29], s5[26]); - s6[27] = vsubq_s16(s5[28], s5[27]); - s6[28] = vaddq_s16(s5[27], s5[28]); - s6[29] = vaddq_s16(s5[26], s5[29]); - s6[30] = vaddq_s16(s4[25], s4[30]); - s6[31] = vaddq_s16(s4[24], s4[31]); - - // stage 7 - s7[0] = vaddq_s16(s6[0], s5[15]); - s7[1] = vaddq_s16(s6[1], s5[14]); - s7[2] = vaddq_s16(s6[2], s6[13]); - s7[3] = vaddq_s16(s6[3], s6[12]); - s7[4] = vaddq_s16(s6[4], s6[11]); - s7[5] = vaddq_s16(s6[5], s6[10]); - s7[6] = vaddq_s16(s6[6], s5[9]); - s7[7] = vaddq_s16(s6[7], s5[8]); - s7[8] = vsubq_s16(s6[7], s5[8]); - s7[9] = vsubq_s16(s6[6], s5[9]); - s7[10] = vsubq_s16(s6[5], s6[10]); - s7[11] = vsubq_s16(s6[4], s6[11]); - s7[12] = vsubq_s16(s6[3], s6[12]); - s7[13] = vsubq_s16(s6[2], s6[13]); - s7[14] = vsubq_s16(s6[1], s5[14]); - s7[15] = vsubq_s16(s6[0], s5[15]); - - s7[20] = sub_multiply_shift_and_narrow_s16(s6[27], s6[20], cospi_16_64); - s7[27] = add_multiply_shift_and_narrow_s16(s6[20], s6[27], cospi_16_64); - - s7[21] = sub_multiply_shift_and_narrow_s16(s6[26], s6[21], cospi_16_64); - s7[26] = add_multiply_shift_and_narrow_s16(s6[21], s6[26], cospi_16_64); - - s7[22] = sub_multiply_shift_and_narrow_s16(s6[25], s6[22], cospi_16_64); - s7[25] = add_multiply_shift_and_narrow_s16(s6[22], s6[25], cospi_16_64); - - s7[23] = sub_multiply_shift_and_narrow_s16(s6[24], s6[23], cospi_16_64); - s7[24] = add_multiply_shift_and_narrow_s16(s6[23], s6[24], cospi_16_64); - - // final stage - vst1q_s16(output, vaddq_s16(s7[0], s6[31])); - output += 16; - vst1q_s16(output, vaddq_s16(s7[1], s6[30])); - output += 16; - vst1q_s16(output, vaddq_s16(s7[2], s6[29])); - output += 16; - vst1q_s16(output, vaddq_s16(s7[3], s6[28])); - output += 16; - vst1q_s16(output, vaddq_s16(s7[4], s7[27])); - output += 16; - vst1q_s16(output, vaddq_s16(s7[5], s7[26])); - output += 16; - vst1q_s16(output, vaddq_s16(s7[6], s7[25])); - output += 16; - vst1q_s16(output, vaddq_s16(s7[7], s7[24])); - output += 16; - - vst1q_s16(output, vaddq_s16(s7[8], s7[23])); - output += 16; - vst1q_s16(output, vaddq_s16(s7[9], s7[22])); - output += 16; - vst1q_s16(output, vaddq_s16(s7[10], s7[21])); - output += 16; - vst1q_s16(output, vaddq_s16(s7[11], s7[20])); - output += 16; - vst1q_s16(output, vaddq_s16(s7[12], s6[19])); - output += 16; - vst1q_s16(output, vaddq_s16(s7[13], s6[18])); - output += 16; - vst1q_s16(output, vaddq_s16(s7[14], s6[17])); - output += 16; - vst1q_s16(output, vaddq_s16(s7[15], s6[16])); - output += 16; - - vst1q_s16(output, vsubq_s16(s7[15], s6[16])); - output += 16; - vst1q_s16(output, vsubq_s16(s7[14], s6[17])); - output += 16; - vst1q_s16(output, vsubq_s16(s7[13], s6[18])); - output += 16; - vst1q_s16(output, vsubq_s16(s7[12], s6[19])); - output += 16; - vst1q_s16(output, vsubq_s16(s7[11], s7[20])); - output += 16; - vst1q_s16(output, vsubq_s16(s7[10], s7[21])); - output += 16; - vst1q_s16(output, vsubq_s16(s7[9], s7[22])); - output += 16; - vst1q_s16(output, vsubq_s16(s7[8], s7[23])); - output += 16; - - vst1q_s16(output, vsubq_s16(s7[7], s7[24])); - output += 16; - vst1q_s16(output, vsubq_s16(s7[6], s7[25])); - output += 16; - vst1q_s16(output, vsubq_s16(s7[5], s7[26])); - output += 16; - vst1q_s16(output, vsubq_s16(s7[4], s7[27])); - output += 16; - vst1q_s16(output, vsubq_s16(s7[3], s6[28])); - output += 16; - vst1q_s16(output, vsubq_s16(s7[2], s6[29])); - output += 16; - vst1q_s16(output, vsubq_s16(s7[1], s6[30])); - output += 16; - vst1q_s16(output, vsubq_s16(s7[0], s6[31])); -} - -void vpx_idct32_16_neon(const int16_t *const input, void *const output, - const int stride, const int highbd_flag) { - int16x8_t in[16], s1[32], s2[32], s3[32], s4[32], s5[32], s6[32], s7[32], - out[32]; - - load_and_transpose_s16_8x8(input, 16, &in[0], &in[1], &in[2], &in[3], &in[4], - &in[5], &in[6], &in[7]); - - load_and_transpose_s16_8x8(input + 8, 16, &in[8], &in[9], &in[10], &in[11], - &in[12], &in[13], &in[14], &in[15]); - - // stage 1 - s1[16] = multiply_shift_and_narrow_s16(in[1], cospi_31_64); - s1[31] = multiply_shift_and_narrow_s16(in[1], cospi_1_64); - - s1[17] = multiply_shift_and_narrow_s16(in[15], -cospi_17_64); - s1[30] = multiply_shift_and_narrow_s16(in[15], cospi_15_64); - - s1[18] = multiply_shift_and_narrow_s16(in[9], cospi_23_64); - s1[29] = multiply_shift_and_narrow_s16(in[9], cospi_9_64); - - s1[19] = multiply_shift_and_narrow_s16(in[7], -cospi_25_64); - s1[28] = multiply_shift_and_narrow_s16(in[7], cospi_7_64); - - s1[20] = multiply_shift_and_narrow_s16(in[5], cospi_27_64); - s1[27] = multiply_shift_and_narrow_s16(in[5], cospi_5_64); - - s1[21] = multiply_shift_and_narrow_s16(in[11], -cospi_21_64); - s1[26] = multiply_shift_and_narrow_s16(in[11], cospi_11_64); - - s1[22] = multiply_shift_and_narrow_s16(in[13], cospi_19_64); - s1[25] = multiply_shift_and_narrow_s16(in[13], cospi_13_64); - - s1[23] = multiply_shift_and_narrow_s16(in[3], -cospi_29_64); - s1[24] = multiply_shift_and_narrow_s16(in[3], cospi_3_64); - - // stage 2 - s2[8] = multiply_shift_and_narrow_s16(in[2], cospi_30_64); - s2[15] = multiply_shift_and_narrow_s16(in[2], cospi_2_64); - - s2[9] = multiply_shift_and_narrow_s16(in[14], -cospi_18_64); - s2[14] = multiply_shift_and_narrow_s16(in[14], cospi_14_64); - - s2[10] = multiply_shift_and_narrow_s16(in[10], cospi_22_64); - s2[13] = multiply_shift_and_narrow_s16(in[10], cospi_10_64); - - s2[11] = multiply_shift_and_narrow_s16(in[6], -cospi_26_64); - s2[12] = multiply_shift_and_narrow_s16(in[6], cospi_6_64); - - s2[16] = vaddq_s16(s1[16], s1[17]); - s2[17] = vsubq_s16(s1[16], s1[17]); - s2[18] = vsubq_s16(s1[19], s1[18]); - s2[19] = vaddq_s16(s1[18], s1[19]); - s2[20] = vaddq_s16(s1[20], s1[21]); - s2[21] = vsubq_s16(s1[20], s1[21]); - s2[22] = vsubq_s16(s1[23], s1[22]); - s2[23] = vaddq_s16(s1[22], s1[23]); - s2[24] = vaddq_s16(s1[24], s1[25]); - s2[25] = vsubq_s16(s1[24], s1[25]); - s2[26] = vsubq_s16(s1[27], s1[26]); - s2[27] = vaddq_s16(s1[26], s1[27]); - s2[28] = vaddq_s16(s1[28], s1[29]); - s2[29] = vsubq_s16(s1[28], s1[29]); - s2[30] = vsubq_s16(s1[31], s1[30]); - s2[31] = vaddq_s16(s1[30], s1[31]); - - // stage 3 - s3[4] = multiply_shift_and_narrow_s16(in[4], cospi_28_64); - s3[7] = multiply_shift_and_narrow_s16(in[4], cospi_4_64); - - s3[5] = multiply_shift_and_narrow_s16(in[12], -cospi_20_64); - s3[6] = multiply_shift_and_narrow_s16(in[12], cospi_12_64); - - s3[8] = vaddq_s16(s2[8], s2[9]); - s3[9] = vsubq_s16(s2[8], s2[9]); - s3[10] = vsubq_s16(s2[11], s2[10]); - s3[11] = vaddq_s16(s2[10], s2[11]); - s3[12] = vaddq_s16(s2[12], s2[13]); - s3[13] = vsubq_s16(s2[12], s2[13]); - s3[14] = vsubq_s16(s2[15], s2[14]); - s3[15] = vaddq_s16(s2[14], s2[15]); - - s3[17] = multiply_accumulate_shift_and_narrow_s16(s2[17], -cospi_4_64, s2[30], - cospi_28_64); - s3[30] = multiply_accumulate_shift_and_narrow_s16(s2[17], cospi_28_64, s2[30], - cospi_4_64); - - s3[18] = multiply_accumulate_shift_and_narrow_s16(s2[18], -cospi_28_64, - s2[29], -cospi_4_64); - s3[29] = multiply_accumulate_shift_and_narrow_s16(s2[18], -cospi_4_64, s2[29], - cospi_28_64); - - s3[21] = multiply_accumulate_shift_and_narrow_s16(s2[21], -cospi_20_64, - s2[26], cospi_12_64); - s3[26] = multiply_accumulate_shift_and_narrow_s16(s2[21], cospi_12_64, s2[26], - cospi_20_64); - - s3[22] = multiply_accumulate_shift_and_narrow_s16(s2[22], -cospi_12_64, - s2[25], -cospi_20_64); - s3[25] = multiply_accumulate_shift_and_narrow_s16(s2[22], -cospi_20_64, - s2[25], cospi_12_64); - - // stage 4 - s4[0] = multiply_shift_and_narrow_s16(in[0], cospi_16_64); - s4[2] = multiply_shift_and_narrow_s16(in[8], cospi_24_64); - s4[3] = multiply_shift_and_narrow_s16(in[8], cospi_8_64); - - s4[4] = vaddq_s16(s3[4], s3[5]); - s4[5] = vsubq_s16(s3[4], s3[5]); - s4[6] = vsubq_s16(s3[7], s3[6]); - s4[7] = vaddq_s16(s3[6], s3[7]); - - s4[9] = multiply_accumulate_shift_and_narrow_s16(s3[9], -cospi_8_64, s3[14], - cospi_24_64); - s4[14] = multiply_accumulate_shift_and_narrow_s16(s3[9], cospi_24_64, s3[14], - cospi_8_64); - - s4[10] = multiply_accumulate_shift_and_narrow_s16(s3[10], -cospi_24_64, - s3[13], -cospi_8_64); - s4[13] = multiply_accumulate_shift_and_narrow_s16(s3[10], -cospi_8_64, s3[13], - cospi_24_64); - - s4[16] = vaddq_s16(s2[16], s2[19]); - s4[17] = vaddq_s16(s3[17], s3[18]); - s4[18] = vsubq_s16(s3[17], s3[18]); - s4[19] = vsubq_s16(s2[16], s2[19]); - s4[20] = vsubq_s16(s2[23], s2[20]); - s4[21] = vsubq_s16(s3[22], s3[21]); - s4[22] = vaddq_s16(s3[21], s3[22]); - s4[23] = vaddq_s16(s2[20], s2[23]); - s4[24] = vaddq_s16(s2[24], s2[27]); - s4[25] = vaddq_s16(s3[25], s3[26]); - s4[26] = vsubq_s16(s3[25], s3[26]); - s4[27] = vsubq_s16(s2[24], s2[27]); - s4[28] = vsubq_s16(s2[31], s2[28]); - s4[29] = vsubq_s16(s3[30], s3[29]); - s4[30] = vaddq_s16(s3[29], s3[30]); - s4[31] = vaddq_s16(s2[28], s2[31]); - - // stage 5 - s5[0] = vaddq_s16(s4[0], s4[3]); - s5[1] = vaddq_s16(s4[0], s4[2]); - s5[2] = vsubq_s16(s4[0], s4[2]); - s5[3] = vsubq_s16(s4[0], s4[3]); - - s5[5] = sub_multiply_shift_and_narrow_s16(s4[6], s4[5], cospi_16_64); - s5[6] = add_multiply_shift_and_narrow_s16(s4[5], s4[6], cospi_16_64); - - s5[8] = vaddq_s16(s3[8], s3[11]); - s5[9] = vaddq_s16(s4[9], s4[10]); - s5[10] = vsubq_s16(s4[9], s4[10]); - s5[11] = vsubq_s16(s3[8], s3[11]); - s5[12] = vsubq_s16(s3[15], s3[12]); - s5[13] = vsubq_s16(s4[14], s4[13]); - s5[14] = vaddq_s16(s4[13], s4[14]); - s5[15] = vaddq_s16(s3[15], s3[12]); - - s5[18] = multiply_accumulate_shift_and_narrow_s16(s4[18], -cospi_8_64, s4[29], - cospi_24_64); - s5[29] = multiply_accumulate_shift_and_narrow_s16(s4[18], cospi_24_64, s4[29], - cospi_8_64); - - s5[19] = multiply_accumulate_shift_and_narrow_s16(s4[19], -cospi_8_64, s4[28], - cospi_24_64); - s5[28] = multiply_accumulate_shift_and_narrow_s16(s4[19], cospi_24_64, s4[28], - cospi_8_64); - - s5[20] = multiply_accumulate_shift_and_narrow_s16(s4[20], -cospi_24_64, - s4[27], -cospi_8_64); - s5[27] = multiply_accumulate_shift_and_narrow_s16(s4[20], -cospi_8_64, s4[27], - cospi_24_64); - - s5[21] = multiply_accumulate_shift_and_narrow_s16(s4[21], -cospi_24_64, - s4[26], -cospi_8_64); - s5[26] = multiply_accumulate_shift_and_narrow_s16(s4[21], -cospi_8_64, s4[26], - cospi_24_64); - - // stage 6 - s6[0] = vaddq_s16(s5[0], s4[7]); - s6[1] = vaddq_s16(s5[1], s5[6]); - s6[2] = vaddq_s16(s5[2], s5[5]); - s6[3] = vaddq_s16(s5[3], s4[4]); - s6[4] = vsubq_s16(s5[3], s4[4]); - s6[5] = vsubq_s16(s5[2], s5[5]); - s6[6] = vsubq_s16(s5[1], s5[6]); - s6[7] = vsubq_s16(s5[0], s4[7]); - - s6[10] = sub_multiply_shift_and_narrow_s16(s5[13], s5[10], cospi_16_64); - s6[13] = add_multiply_shift_and_narrow_s16(s5[10], s5[13], cospi_16_64); - - s6[11] = sub_multiply_shift_and_narrow_s16(s5[12], s5[11], cospi_16_64); - s6[12] = add_multiply_shift_and_narrow_s16(s5[11], s5[12], cospi_16_64); - - s6[16] = vaddq_s16(s4[16], s4[23]); - s6[17] = vaddq_s16(s4[17], s4[22]); - s6[18] = vaddq_s16(s5[18], s5[21]); - s6[19] = vaddq_s16(s5[19], s5[20]); - s6[20] = vsubq_s16(s5[19], s5[20]); - s6[21] = vsubq_s16(s5[18], s5[21]); - s6[22] = vsubq_s16(s4[17], s4[22]); - s6[23] = vsubq_s16(s4[16], s4[23]); - s6[24] = vsubq_s16(s4[31], s4[24]); - s6[25] = vsubq_s16(s4[30], s4[25]); - s6[26] = vsubq_s16(s5[29], s5[26]); - s6[27] = vsubq_s16(s5[28], s5[27]); - s6[28] = vaddq_s16(s5[27], s5[28]); - s6[29] = vaddq_s16(s5[26], s5[29]); - s6[30] = vaddq_s16(s4[25], s4[30]); - s6[31] = vaddq_s16(s4[24], s4[31]); - - // stage 7 - s7[0] = vaddq_s16(s6[0], s5[15]); - s7[1] = vaddq_s16(s6[1], s5[14]); - s7[2] = vaddq_s16(s6[2], s6[13]); - s7[3] = vaddq_s16(s6[3], s6[12]); - s7[4] = vaddq_s16(s6[4], s6[11]); - s7[5] = vaddq_s16(s6[5], s6[10]); - s7[6] = vaddq_s16(s6[6], s5[9]); - s7[7] = vaddq_s16(s6[7], s5[8]); - s7[8] = vsubq_s16(s6[7], s5[8]); - s7[9] = vsubq_s16(s6[6], s5[9]); - s7[10] = vsubq_s16(s6[5], s6[10]); - s7[11] = vsubq_s16(s6[4], s6[11]); - s7[12] = vsubq_s16(s6[3], s6[12]); - s7[13] = vsubq_s16(s6[2], s6[13]); - s7[14] = vsubq_s16(s6[1], s5[14]); - s7[15] = vsubq_s16(s6[0], s5[15]); - - s7[20] = sub_multiply_shift_and_narrow_s16(s6[27], s6[20], cospi_16_64); - s7[27] = add_multiply_shift_and_narrow_s16(s6[20], s6[27], cospi_16_64); - - s7[21] = sub_multiply_shift_and_narrow_s16(s6[26], s6[21], cospi_16_64); - s7[26] = add_multiply_shift_and_narrow_s16(s6[21], s6[26], cospi_16_64); - - s7[22] = sub_multiply_shift_and_narrow_s16(s6[25], s6[22], cospi_16_64); - s7[25] = add_multiply_shift_and_narrow_s16(s6[22], s6[25], cospi_16_64); - - s7[23] = sub_multiply_shift_and_narrow_s16(s6[24], s6[23], cospi_16_64); - s7[24] = add_multiply_shift_and_narrow_s16(s6[23], s6[24], cospi_16_64); - - // final stage - out[0] = final_add(s7[0], s6[31]); - out[1] = final_add(s7[1], s6[30]); - out[2] = final_add(s7[2], s6[29]); - out[3] = final_add(s7[3], s6[28]); - out[4] = final_add(s7[4], s7[27]); - out[5] = final_add(s7[5], s7[26]); - out[6] = final_add(s7[6], s7[25]); - out[7] = final_add(s7[7], s7[24]); - out[8] = final_add(s7[8], s7[23]); - out[9] = final_add(s7[9], s7[22]); - out[10] = final_add(s7[10], s7[21]); - out[11] = final_add(s7[11], s7[20]); - out[12] = final_add(s7[12], s6[19]); - out[13] = final_add(s7[13], s6[18]); - out[14] = final_add(s7[14], s6[17]); - out[15] = final_add(s7[15], s6[16]); - out[16] = final_sub(s7[15], s6[16]); - out[17] = final_sub(s7[14], s6[17]); - out[18] = final_sub(s7[13], s6[18]); - out[19] = final_sub(s7[12], s6[19]); - out[20] = final_sub(s7[11], s7[20]); - out[21] = final_sub(s7[10], s7[21]); - out[22] = final_sub(s7[9], s7[22]); - out[23] = final_sub(s7[8], s7[23]); - out[24] = final_sub(s7[7], s7[24]); - out[25] = final_sub(s7[6], s7[25]); - out[26] = final_sub(s7[5], s7[26]); - out[27] = final_sub(s7[4], s7[27]); - out[28] = final_sub(s7[3], s6[28]); - out[29] = final_sub(s7[2], s6[29]); - out[30] = final_sub(s7[1], s6[30]); - out[31] = final_sub(s7[0], s6[31]); - - if (highbd_flag) { - highbd_add_and_store_bd8(out, output, stride); - } else { - uint8_t *const outputT = (uint8_t *)output; - add_and_store_u8_s16(out + 0, outputT, stride); - add_and_store_u8_s16(out + 8, outputT + (8 * stride), stride); - add_and_store_u8_s16(out + 16, outputT + (16 * stride), stride); - add_and_store_u8_s16(out + 24, outputT + (24 * stride), stride); - } -} - -void vpx_idct32x32_135_add_neon(const tran_low_t *input, uint8_t *dest, - int stride) { - int i; - int16_t temp[32 * 16]; - int16_t *t = temp; - - vpx_idct32_12_neon(input, temp); - vpx_idct32_12_neon(input + 32 * 8, temp + 8); - - for (i = 0; i < 32; i += 8) { - vpx_idct32_16_neon(t, dest, stride, 0); - t += (16 * 8); - dest += 8; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct32x32_1_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct32x32_1_add_neon.c deleted file mode 100644 index 8920b933..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct32x32_1_add_neon.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/inv_txfm.h" - -static INLINE void idct32x32_1_add_pos_kernel(uint8_t **dest, const int stride, - const uint8x16_t res) { - const uint8x16_t a0 = vld1q_u8(*dest); - const uint8x16_t a1 = vld1q_u8(*dest + 16); - const uint8x16_t b0 = vqaddq_u8(a0, res); - const uint8x16_t b1 = vqaddq_u8(a1, res); - vst1q_u8(*dest, b0); - vst1q_u8(*dest + 16, b1); - *dest += stride; -} - -static INLINE void idct32x32_1_add_neg_kernel(uint8_t **dest, const int stride, - const uint8x16_t res) { - const uint8x16_t a0 = vld1q_u8(*dest); - const uint8x16_t a1 = vld1q_u8(*dest + 16); - const uint8x16_t b0 = vqsubq_u8(a0, res); - const uint8x16_t b1 = vqsubq_u8(a1, res); - vst1q_u8(*dest, b0); - vst1q_u8(*dest + 16, b1); - *dest += stride; -} - -void vpx_idct32x32_1_add_neon(const tran_low_t *input, uint8_t *dest, - int stride) { - int i; - const int16_t out0 = - WRAPLOW(dct_const_round_shift((int16_t)input[0] * cospi_16_64)); - const int16_t out1 = WRAPLOW(dct_const_round_shift(out0 * cospi_16_64)); - const int16_t a1 = ROUND_POWER_OF_TWO(out1, 6); - - if (a1 >= 0) { - const uint8x16_t dc = create_dcq(a1); - for (i = 0; i < 32; i++) { - idct32x32_1_add_pos_kernel(&dest, stride, dc); - } - } else { - const uint8x16_t dc = create_dcq(-a1); - for (i = 0; i < 32; i++) { - idct32x32_1_add_neg_kernel(&dest, stride, dc); - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct32x32_34_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct32x32_34_add_neon.c deleted file mode 100644 index f570547e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct32x32_34_add_neon.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/txfm_common.h" - -// Only for the first pass of the _34_ variant. Since it only uses values from -// the top left 8x8 it can safely assume all the remaining values are 0 and skip -// an awful lot of calculations. In fact, only the first 6 columns make the cut. -// None of the elements in the 7th or 8th column are used so it skips any calls -// to input[67] too. -// In C this does a single row of 32 for each call. Here it transposes the top -// left 8x8 to allow using SIMD. - -// vp9/common/vp9_scan.c:vp9_default_iscan_32x32 arranges the first 34 non-zero -// coefficients as follows: -// 0 1 2 3 4 5 6 7 -// 0 0 2 5 10 17 25 -// 1 1 4 8 15 22 30 -// 2 3 7 12 18 28 -// 3 6 11 16 23 31 -// 4 9 14 19 29 -// 5 13 20 26 -// 6 21 27 33 -// 7 24 32 -void vpx_idct32_6_neon(const tran_low_t *input, int16_t *output) { - int16x8_t in[8], s1[32], s2[32], s3[32]; - - in[0] = load_tran_low_to_s16q(input); - input += 32; - in[1] = load_tran_low_to_s16q(input); - input += 32; - in[2] = load_tran_low_to_s16q(input); - input += 32; - in[3] = load_tran_low_to_s16q(input); - input += 32; - in[4] = load_tran_low_to_s16q(input); - input += 32; - in[5] = load_tran_low_to_s16q(input); - input += 32; - in[6] = load_tran_low_to_s16q(input); - input += 32; - in[7] = load_tran_low_to_s16q(input); - transpose_s16_8x8(&in[0], &in[1], &in[2], &in[3], &in[4], &in[5], &in[6], - &in[7]); - - // stage 1 - // input[1] * cospi_31_64 - input[31] * cospi_1_64 (but input[31] == 0) - s1[16] = multiply_shift_and_narrow_s16(in[1], cospi_31_64); - // input[1] * cospi_1_64 + input[31] * cospi_31_64 (but input[31] == 0) - s1[31] = multiply_shift_and_narrow_s16(in[1], cospi_1_64); - - s1[20] = multiply_shift_and_narrow_s16(in[5], cospi_27_64); - s1[27] = multiply_shift_and_narrow_s16(in[5], cospi_5_64); - - s1[23] = multiply_shift_and_narrow_s16(in[3], -cospi_29_64); - s1[24] = multiply_shift_and_narrow_s16(in[3], cospi_3_64); - - // stage 2 - s2[8] = multiply_shift_and_narrow_s16(in[2], cospi_30_64); - s2[15] = multiply_shift_and_narrow_s16(in[2], cospi_2_64); - - // stage 3 - s1[4] = multiply_shift_and_narrow_s16(in[4], cospi_28_64); - s1[7] = multiply_shift_and_narrow_s16(in[4], cospi_4_64); - - s1[17] = multiply_accumulate_shift_and_narrow_s16(s1[16], -cospi_4_64, s1[31], - cospi_28_64); - s1[30] = multiply_accumulate_shift_and_narrow_s16(s1[16], cospi_28_64, s1[31], - cospi_4_64); - - s1[21] = multiply_accumulate_shift_and_narrow_s16(s1[20], -cospi_20_64, - s1[27], cospi_12_64); - s1[26] = multiply_accumulate_shift_and_narrow_s16(s1[20], cospi_12_64, s1[27], - cospi_20_64); - - s1[22] = multiply_accumulate_shift_and_narrow_s16(s1[23], -cospi_12_64, - s1[24], -cospi_20_64); - s1[25] = multiply_accumulate_shift_and_narrow_s16(s1[23], -cospi_20_64, - s1[24], cospi_12_64); - - // stage 4 - s1[0] = multiply_shift_and_narrow_s16(in[0], cospi_16_64); - - s2[9] = multiply_accumulate_shift_and_narrow_s16(s2[8], -cospi_8_64, s2[15], - cospi_24_64); - s2[14] = multiply_accumulate_shift_and_narrow_s16(s2[8], cospi_24_64, s2[15], - cospi_8_64); - - s2[20] = vsubq_s16(s1[23], s1[20]); - s2[21] = vsubq_s16(s1[22], s1[21]); - s2[22] = vaddq_s16(s1[21], s1[22]); - s2[23] = vaddq_s16(s1[20], s1[23]); - s2[24] = vaddq_s16(s1[24], s1[27]); - s2[25] = vaddq_s16(s1[25], s1[26]); - s2[26] = vsubq_s16(s1[25], s1[26]); - s2[27] = vsubq_s16(s1[24], s1[27]); - - // stage 5 - s1[5] = sub_multiply_shift_and_narrow_s16(s1[7], s1[4], cospi_16_64); - s1[6] = add_multiply_shift_and_narrow_s16(s1[4], s1[7], cospi_16_64); - - s1[18] = multiply_accumulate_shift_and_narrow_s16(s1[17], -cospi_8_64, s1[30], - cospi_24_64); - s1[29] = multiply_accumulate_shift_and_narrow_s16(s1[17], cospi_24_64, s1[30], - cospi_8_64); - - s1[19] = multiply_accumulate_shift_and_narrow_s16(s1[16], -cospi_8_64, s1[31], - cospi_24_64); - s1[28] = multiply_accumulate_shift_and_narrow_s16(s1[16], cospi_24_64, s1[31], - cospi_8_64); - - s1[20] = multiply_accumulate_shift_and_narrow_s16(s2[20], -cospi_24_64, - s2[27], -cospi_8_64); - s1[27] = multiply_accumulate_shift_and_narrow_s16(s2[20], -cospi_8_64, s2[27], - cospi_24_64); - - s1[21] = multiply_accumulate_shift_and_narrow_s16(s2[21], -cospi_24_64, - s2[26], -cospi_8_64); - s1[26] = multiply_accumulate_shift_and_narrow_s16(s2[21], -cospi_8_64, s2[26], - cospi_24_64); - - // stage 6 - s2[0] = vaddq_s16(s1[0], s1[7]); - s2[1] = vaddq_s16(s1[0], s1[6]); - s2[2] = vaddq_s16(s1[0], s1[5]); - s2[3] = vaddq_s16(s1[0], s1[4]); - s2[4] = vsubq_s16(s1[0], s1[4]); - s2[5] = vsubq_s16(s1[0], s1[5]); - s2[6] = vsubq_s16(s1[0], s1[6]); - s2[7] = vsubq_s16(s1[0], s1[7]); - - s2[10] = sub_multiply_shift_and_narrow_s16(s2[14], s2[9], cospi_16_64); - s2[13] = add_multiply_shift_and_narrow_s16(s2[9], s2[14], cospi_16_64); - - s2[11] = sub_multiply_shift_and_narrow_s16(s2[15], s2[8], cospi_16_64); - s2[12] = add_multiply_shift_and_narrow_s16(s2[8], s2[15], cospi_16_64); - - s2[16] = vaddq_s16(s1[16], s2[23]); - s2[17] = vaddq_s16(s1[17], s2[22]); - s2[18] = vaddq_s16(s1[18], s1[21]); - s2[19] = vaddq_s16(s1[19], s1[20]); - s2[20] = vsubq_s16(s1[19], s1[20]); - s2[21] = vsubq_s16(s1[18], s1[21]); - s2[22] = vsubq_s16(s1[17], s2[22]); - s2[23] = vsubq_s16(s1[16], s2[23]); - - s3[24] = vsubq_s16(s1[31], s2[24]); - s3[25] = vsubq_s16(s1[30], s2[25]); - s3[26] = vsubq_s16(s1[29], s1[26]); - s3[27] = vsubq_s16(s1[28], s1[27]); - s2[28] = vaddq_s16(s1[27], s1[28]); - s2[29] = vaddq_s16(s1[26], s1[29]); - s2[30] = vaddq_s16(s2[25], s1[30]); - s2[31] = vaddq_s16(s2[24], s1[31]); - - // stage 7 - s1[0] = vaddq_s16(s2[0], s2[15]); - s1[1] = vaddq_s16(s2[1], s2[14]); - s1[2] = vaddq_s16(s2[2], s2[13]); - s1[3] = vaddq_s16(s2[3], s2[12]); - s1[4] = vaddq_s16(s2[4], s2[11]); - s1[5] = vaddq_s16(s2[5], s2[10]); - s1[6] = vaddq_s16(s2[6], s2[9]); - s1[7] = vaddq_s16(s2[7], s2[8]); - s1[8] = vsubq_s16(s2[7], s2[8]); - s1[9] = vsubq_s16(s2[6], s2[9]); - s1[10] = vsubq_s16(s2[5], s2[10]); - s1[11] = vsubq_s16(s2[4], s2[11]); - s1[12] = vsubq_s16(s2[3], s2[12]); - s1[13] = vsubq_s16(s2[2], s2[13]); - s1[14] = vsubq_s16(s2[1], s2[14]); - s1[15] = vsubq_s16(s2[0], s2[15]); - - s1[20] = sub_multiply_shift_and_narrow_s16(s3[27], s2[20], cospi_16_64); - s1[27] = add_multiply_shift_and_narrow_s16(s2[20], s3[27], cospi_16_64); - - s1[21] = sub_multiply_shift_and_narrow_s16(s3[26], s2[21], cospi_16_64); - s1[26] = add_multiply_shift_and_narrow_s16(s2[21], s3[26], cospi_16_64); - - s1[22] = sub_multiply_shift_and_narrow_s16(s3[25], s2[22], cospi_16_64); - s1[25] = add_multiply_shift_and_narrow_s16(s2[22], s3[25], cospi_16_64); - - s1[23] = sub_multiply_shift_and_narrow_s16(s3[24], s2[23], cospi_16_64); - s1[24] = add_multiply_shift_and_narrow_s16(s2[23], s3[24], cospi_16_64); - - // final stage - vst1q_s16(output, vaddq_s16(s1[0], s2[31])); - output += 8; - vst1q_s16(output, vaddq_s16(s1[1], s2[30])); - output += 8; - vst1q_s16(output, vaddq_s16(s1[2], s2[29])); - output += 8; - vst1q_s16(output, vaddq_s16(s1[3], s2[28])); - output += 8; - vst1q_s16(output, vaddq_s16(s1[4], s1[27])); - output += 8; - vst1q_s16(output, vaddq_s16(s1[5], s1[26])); - output += 8; - vst1q_s16(output, vaddq_s16(s1[6], s1[25])); - output += 8; - vst1q_s16(output, vaddq_s16(s1[7], s1[24])); - output += 8; - - vst1q_s16(output, vaddq_s16(s1[8], s1[23])); - output += 8; - vst1q_s16(output, vaddq_s16(s1[9], s1[22])); - output += 8; - vst1q_s16(output, vaddq_s16(s1[10], s1[21])); - output += 8; - vst1q_s16(output, vaddq_s16(s1[11], s1[20])); - output += 8; - vst1q_s16(output, vaddq_s16(s1[12], s2[19])); - output += 8; - vst1q_s16(output, vaddq_s16(s1[13], s2[18])); - output += 8; - vst1q_s16(output, vaddq_s16(s1[14], s2[17])); - output += 8; - vst1q_s16(output, vaddq_s16(s1[15], s2[16])); - output += 8; - - vst1q_s16(output, vsubq_s16(s1[15], s2[16])); - output += 8; - vst1q_s16(output, vsubq_s16(s1[14], s2[17])); - output += 8; - vst1q_s16(output, vsubq_s16(s1[13], s2[18])); - output += 8; - vst1q_s16(output, vsubq_s16(s1[12], s2[19])); - output += 8; - vst1q_s16(output, vsubq_s16(s1[11], s1[20])); - output += 8; - vst1q_s16(output, vsubq_s16(s1[10], s1[21])); - output += 8; - vst1q_s16(output, vsubq_s16(s1[9], s1[22])); - output += 8; - vst1q_s16(output, vsubq_s16(s1[8], s1[23])); - output += 8; - - vst1q_s16(output, vsubq_s16(s1[7], s1[24])); - output += 8; - vst1q_s16(output, vsubq_s16(s1[6], s1[25])); - output += 8; - vst1q_s16(output, vsubq_s16(s1[5], s1[26])); - output += 8; - vst1q_s16(output, vsubq_s16(s1[4], s1[27])); - output += 8; - vst1q_s16(output, vsubq_s16(s1[3], s2[28])); - output += 8; - vst1q_s16(output, vsubq_s16(s1[2], s2[29])); - output += 8; - vst1q_s16(output, vsubq_s16(s1[1], s2[30])); - output += 8; - vst1q_s16(output, vsubq_s16(s1[0], s2[31])); -} - -void vpx_idct32_8_neon(const int16_t *input, void *const output, int stride, - const int highbd_flag) { - int16x8_t in[8], s1[32], s2[32], s3[32], out[32]; - - load_and_transpose_s16_8x8(input, 8, &in[0], &in[1], &in[2], &in[3], &in[4], - &in[5], &in[6], &in[7]); - - // stage 1 - s1[16] = multiply_shift_and_narrow_s16(in[1], cospi_31_64); - s1[31] = multiply_shift_and_narrow_s16(in[1], cospi_1_64); - - // Different for _8_ - s1[19] = multiply_shift_and_narrow_s16(in[7], -cospi_25_64); - s1[28] = multiply_shift_and_narrow_s16(in[7], cospi_7_64); - - s1[20] = multiply_shift_and_narrow_s16(in[5], cospi_27_64); - s1[27] = multiply_shift_and_narrow_s16(in[5], cospi_5_64); - - s1[23] = multiply_shift_and_narrow_s16(in[3], -cospi_29_64); - s1[24] = multiply_shift_and_narrow_s16(in[3], cospi_3_64); - - // stage 2 - s2[8] = multiply_shift_and_narrow_s16(in[2], cospi_30_64); - s2[15] = multiply_shift_and_narrow_s16(in[2], cospi_2_64); - - s2[11] = multiply_shift_and_narrow_s16(in[6], -cospi_26_64); - s2[12] = multiply_shift_and_narrow_s16(in[6], cospi_6_64); - - // stage 3 - s1[4] = multiply_shift_and_narrow_s16(in[4], cospi_28_64); - s1[7] = multiply_shift_and_narrow_s16(in[4], cospi_4_64); - - s1[17] = multiply_accumulate_shift_and_narrow_s16(s1[16], -cospi_4_64, s1[31], - cospi_28_64); - s1[30] = multiply_accumulate_shift_and_narrow_s16(s1[16], cospi_28_64, s1[31], - cospi_4_64); - - // Different for _8_ - s1[18] = multiply_accumulate_shift_and_narrow_s16(s1[19], -cospi_28_64, - s1[28], -cospi_4_64); - s1[29] = multiply_accumulate_shift_and_narrow_s16(s1[19], -cospi_4_64, s1[28], - cospi_28_64); - - s1[21] = multiply_accumulate_shift_and_narrow_s16(s1[20], -cospi_20_64, - s1[27], cospi_12_64); - s1[26] = multiply_accumulate_shift_and_narrow_s16(s1[20], cospi_12_64, s1[27], - cospi_20_64); - - s1[22] = multiply_accumulate_shift_and_narrow_s16(s1[23], -cospi_12_64, - s1[24], -cospi_20_64); - s1[25] = multiply_accumulate_shift_and_narrow_s16(s1[23], -cospi_20_64, - s1[24], cospi_12_64); - - // stage 4 - s1[0] = multiply_shift_and_narrow_s16(in[0], cospi_16_64); - - s2[9] = multiply_accumulate_shift_and_narrow_s16(s2[8], -cospi_8_64, s2[15], - cospi_24_64); - s2[14] = multiply_accumulate_shift_and_narrow_s16(s2[8], cospi_24_64, s2[15], - cospi_8_64); - - s2[10] = multiply_accumulate_shift_and_narrow_s16(s2[11], -cospi_24_64, - s2[12], -cospi_8_64); - s2[13] = multiply_accumulate_shift_and_narrow_s16(s2[11], -cospi_8_64, s2[12], - cospi_24_64); - - s2[16] = vaddq_s16(s1[16], s1[19]); - - s2[17] = vaddq_s16(s1[17], s1[18]); - s2[18] = vsubq_s16(s1[17], s1[18]); - - s2[19] = vsubq_s16(s1[16], s1[19]); - - s2[20] = vsubq_s16(s1[23], s1[20]); - s2[21] = vsubq_s16(s1[22], s1[21]); - - s2[22] = vaddq_s16(s1[21], s1[22]); - s2[23] = vaddq_s16(s1[20], s1[23]); - - s2[24] = vaddq_s16(s1[24], s1[27]); - s2[25] = vaddq_s16(s1[25], s1[26]); - s2[26] = vsubq_s16(s1[25], s1[26]); - s2[27] = vsubq_s16(s1[24], s1[27]); - - s2[28] = vsubq_s16(s1[31], s1[28]); - s2[29] = vsubq_s16(s1[30], s1[29]); - s2[30] = vaddq_s16(s1[29], s1[30]); - s2[31] = vaddq_s16(s1[28], s1[31]); - - // stage 5 - s1[5] = sub_multiply_shift_and_narrow_s16(s1[7], s1[4], cospi_16_64); - s1[6] = add_multiply_shift_and_narrow_s16(s1[4], s1[7], cospi_16_64); - - s1[8] = vaddq_s16(s2[8], s2[11]); - s1[9] = vaddq_s16(s2[9], s2[10]); - s1[10] = vsubq_s16(s2[9], s2[10]); - s1[11] = vsubq_s16(s2[8], s2[11]); - s1[12] = vsubq_s16(s2[15], s2[12]); - s1[13] = vsubq_s16(s2[14], s2[13]); - s1[14] = vaddq_s16(s2[13], s2[14]); - s1[15] = vaddq_s16(s2[12], s2[15]); - - s1[18] = multiply_accumulate_shift_and_narrow_s16(s2[18], -cospi_8_64, s2[29], - cospi_24_64); - s1[29] = multiply_accumulate_shift_and_narrow_s16(s2[18], cospi_24_64, s2[29], - cospi_8_64); - - s1[19] = multiply_accumulate_shift_and_narrow_s16(s2[19], -cospi_8_64, s2[28], - cospi_24_64); - s1[28] = multiply_accumulate_shift_and_narrow_s16(s2[19], cospi_24_64, s2[28], - cospi_8_64); - - s1[20] = multiply_accumulate_shift_and_narrow_s16(s2[20], -cospi_24_64, - s2[27], -cospi_8_64); - s1[27] = multiply_accumulate_shift_and_narrow_s16(s2[20], -cospi_8_64, s2[27], - cospi_24_64); - - s1[21] = multiply_accumulate_shift_and_narrow_s16(s2[21], -cospi_24_64, - s2[26], -cospi_8_64); - s1[26] = multiply_accumulate_shift_and_narrow_s16(s2[21], -cospi_8_64, s2[26], - cospi_24_64); - - // stage 6 - s2[0] = vaddq_s16(s1[0], s1[7]); - s2[1] = vaddq_s16(s1[0], s1[6]); - s2[2] = vaddq_s16(s1[0], s1[5]); - s2[3] = vaddq_s16(s1[0], s1[4]); - s2[4] = vsubq_s16(s1[0], s1[4]); - s2[5] = vsubq_s16(s1[0], s1[5]); - s2[6] = vsubq_s16(s1[0], s1[6]); - s2[7] = vsubq_s16(s1[0], s1[7]); - - s2[10] = sub_multiply_shift_and_narrow_s16(s1[13], s1[10], cospi_16_64); - s2[13] = add_multiply_shift_and_narrow_s16(s1[10], s1[13], cospi_16_64); - - s2[11] = sub_multiply_shift_and_narrow_s16(s1[12], s1[11], cospi_16_64); - s2[12] = add_multiply_shift_and_narrow_s16(s1[11], s1[12], cospi_16_64); - - s1[16] = vaddq_s16(s2[16], s2[23]); - s1[17] = vaddq_s16(s2[17], s2[22]); - s2[18] = vaddq_s16(s1[18], s1[21]); - s2[19] = vaddq_s16(s1[19], s1[20]); - s2[20] = vsubq_s16(s1[19], s1[20]); - s2[21] = vsubq_s16(s1[18], s1[21]); - s1[22] = vsubq_s16(s2[17], s2[22]); - s1[23] = vsubq_s16(s2[16], s2[23]); - - s3[24] = vsubq_s16(s2[31], s2[24]); - s3[25] = vsubq_s16(s2[30], s2[25]); - s3[26] = vsubq_s16(s1[29], s1[26]); - s3[27] = vsubq_s16(s1[28], s1[27]); - s2[28] = vaddq_s16(s1[27], s1[28]); - s2[29] = vaddq_s16(s1[26], s1[29]); - s2[30] = vaddq_s16(s2[25], s2[30]); - s2[31] = vaddq_s16(s2[24], s2[31]); - - // stage 7 - s1[0] = vaddq_s16(s2[0], s1[15]); - s1[1] = vaddq_s16(s2[1], s1[14]); - s1[2] = vaddq_s16(s2[2], s2[13]); - s1[3] = vaddq_s16(s2[3], s2[12]); - s1[4] = vaddq_s16(s2[4], s2[11]); - s1[5] = vaddq_s16(s2[5], s2[10]); - s1[6] = vaddq_s16(s2[6], s1[9]); - s1[7] = vaddq_s16(s2[7], s1[8]); - s1[8] = vsubq_s16(s2[7], s1[8]); - s1[9] = vsubq_s16(s2[6], s1[9]); - s1[10] = vsubq_s16(s2[5], s2[10]); - s1[11] = vsubq_s16(s2[4], s2[11]); - s1[12] = vsubq_s16(s2[3], s2[12]); - s1[13] = vsubq_s16(s2[2], s2[13]); - s1[14] = vsubq_s16(s2[1], s1[14]); - s1[15] = vsubq_s16(s2[0], s1[15]); - - s1[20] = sub_multiply_shift_and_narrow_s16(s3[27], s2[20], cospi_16_64); - s1[27] = add_multiply_shift_and_narrow_s16(s2[20], s3[27], cospi_16_64); - - s1[21] = sub_multiply_shift_and_narrow_s16(s3[26], s2[21], cospi_16_64); - s1[26] = add_multiply_shift_and_narrow_s16(s2[21], s3[26], cospi_16_64); - - s2[22] = sub_multiply_shift_and_narrow_s16(s3[25], s1[22], cospi_16_64); - s1[25] = add_multiply_shift_and_narrow_s16(s1[22], s3[25], cospi_16_64); - - s2[23] = sub_multiply_shift_and_narrow_s16(s3[24], s1[23], cospi_16_64); - s1[24] = add_multiply_shift_and_narrow_s16(s1[23], s3[24], cospi_16_64); - - // final stage - out[0] = final_add(s1[0], s2[31]); - out[1] = final_add(s1[1], s2[30]); - out[2] = final_add(s1[2], s2[29]); - out[3] = final_add(s1[3], s2[28]); - out[4] = final_add(s1[4], s1[27]); - out[5] = final_add(s1[5], s1[26]); - out[6] = final_add(s1[6], s1[25]); - out[7] = final_add(s1[7], s1[24]); - out[8] = final_add(s1[8], s2[23]); - out[9] = final_add(s1[9], s2[22]); - out[10] = final_add(s1[10], s1[21]); - out[11] = final_add(s1[11], s1[20]); - out[12] = final_add(s1[12], s2[19]); - out[13] = final_add(s1[13], s2[18]); - out[14] = final_add(s1[14], s1[17]); - out[15] = final_add(s1[15], s1[16]); - out[16] = final_sub(s1[15], s1[16]); - out[17] = final_sub(s1[14], s1[17]); - out[18] = final_sub(s1[13], s2[18]); - out[19] = final_sub(s1[12], s2[19]); - out[20] = final_sub(s1[11], s1[20]); - out[21] = final_sub(s1[10], s1[21]); - out[22] = final_sub(s1[9], s2[22]); - out[23] = final_sub(s1[8], s2[23]); - out[24] = final_sub(s1[7], s1[24]); - out[25] = final_sub(s1[6], s1[25]); - out[26] = final_sub(s1[5], s1[26]); - out[27] = final_sub(s1[4], s1[27]); - out[28] = final_sub(s1[3], s2[28]); - out[29] = final_sub(s1[2], s2[29]); - out[30] = final_sub(s1[1], s2[30]); - out[31] = final_sub(s1[0], s2[31]); - - if (highbd_flag) { - highbd_add_and_store_bd8(out, output, stride); - } else { - uint8_t *const outputT = (uint8_t *)output; - add_and_store_u8_s16(out + 0, outputT, stride); - add_and_store_u8_s16(out + 8, outputT + (8 * stride), stride); - add_and_store_u8_s16(out + 16, outputT + (16 * stride), stride); - add_and_store_u8_s16(out + 24, outputT + (24 * stride), stride); - } -} - -void vpx_idct32x32_34_add_neon(const tran_low_t *input, uint8_t *dest, - int stride) { - int i; - int16_t temp[32 * 8]; - int16_t *t = temp; - - vpx_idct32_6_neon(input, t); - - for (i = 0; i < 32; i += 8) { - vpx_idct32_8_neon(t, dest, stride, 0); - t += (8 * 8); - dest += 8; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct32x32_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct32x32_add_neon.c deleted file mode 100644 index 9f4589ea..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct32x32_add_neon.c +++ /dev/null @@ -1,776 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/txfm_common.h" - -static INLINE void load_from_transformed(const int16_t *const trans_buf, - const int first, const int second, - int16x8_t *const q0, - int16x8_t *const q1) { - *q0 = vld1q_s16(trans_buf + first * 8); - *q1 = vld1q_s16(trans_buf + second * 8); -} - -static INLINE void load_from_output(const int16_t *const out, const int first, - const int second, int16x8_t *const q0, - int16x8_t *const q1) { - *q0 = vld1q_s16(out + first * 32); - *q1 = vld1q_s16(out + second * 32); -} - -static INLINE void store_in_output(int16_t *const out, const int first, - const int second, const int16x8_t q0, - const int16x8_t q1) { - vst1q_s16(out + first * 32, q0); - vst1q_s16(out + second * 32, q1); -} - -static INLINE void store_combine_results(uint8_t *p1, uint8_t *p2, - const int stride, int16x8_t q0, - int16x8_t q1, int16x8_t q2, - int16x8_t q3) { - uint8x8_t d[4]; - - d[0] = vld1_u8(p1); - p1 += stride; - d[1] = vld1_u8(p1); - d[3] = vld1_u8(p2); - p2 -= stride; - d[2] = vld1_u8(p2); - - q0 = vrshrq_n_s16(q0, 6); - q1 = vrshrq_n_s16(q1, 6); - q2 = vrshrq_n_s16(q2, 6); - q3 = vrshrq_n_s16(q3, 6); - - q0 = vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(q0), d[0])); - q1 = vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(q1), d[1])); - q2 = vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(q2), d[2])); - q3 = vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(q3), d[3])); - - d[0] = vqmovun_s16(q0); - d[1] = vqmovun_s16(q1); - d[2] = vqmovun_s16(q2); - d[3] = vqmovun_s16(q3); - - vst1_u8(p1, d[1]); - p1 -= stride; - vst1_u8(p1, d[0]); - vst1_u8(p2, d[2]); - p2 += stride; - vst1_u8(p2, d[3]); -} - -static INLINE void highbd_store_combine_results_bd8(uint16_t *p1, uint16_t *p2, - const int stride, - int16x8_t q0, int16x8_t q1, - int16x8_t q2, - int16x8_t q3) { - uint16x8_t d[4]; - - d[0] = vld1q_u16(p1); - p1 += stride; - d[1] = vld1q_u16(p1); - d[3] = vld1q_u16(p2); - p2 -= stride; - d[2] = vld1q_u16(p2); - - q0 = vrshrq_n_s16(q0, 6); - q1 = vrshrq_n_s16(q1, 6); - q2 = vrshrq_n_s16(q2, 6); - q3 = vrshrq_n_s16(q3, 6); - - q0 = vaddq_s16(q0, vreinterpretq_s16_u16(d[0])); - q1 = vaddq_s16(q1, vreinterpretq_s16_u16(d[1])); - q2 = vaddq_s16(q2, vreinterpretq_s16_u16(d[2])); - q3 = vaddq_s16(q3, vreinterpretq_s16_u16(d[3])); - - d[0] = vmovl_u8(vqmovun_s16(q0)); - d[1] = vmovl_u8(vqmovun_s16(q1)); - d[2] = vmovl_u8(vqmovun_s16(q2)); - d[3] = vmovl_u8(vqmovun_s16(q3)); - - vst1q_u16(p1, d[1]); - p1 -= stride; - vst1q_u16(p1, d[0]); - vst1q_u16(p2, d[2]); - p2 += stride; - vst1q_u16(p2, d[3]); -} - -static INLINE void do_butterfly(const int16x8_t qIn0, const int16x8_t qIn1, - const int16_t first_const, - const int16_t second_const, - int16x8_t *const qOut0, - int16x8_t *const qOut1) { - int32x4_t q[4]; - int16x4_t d[6]; - - d[0] = vget_low_s16(qIn0); - d[1] = vget_high_s16(qIn0); - d[2] = vget_low_s16(qIn1); - d[3] = vget_high_s16(qIn1); - - // Note: using v{mul, mla, mls}l_n_s16 here slows down 35% with gcc 4.9. - d[4] = vdup_n_s16(first_const); - d[5] = vdup_n_s16(second_const); - - q[0] = vmull_s16(d[0], d[4]); - q[1] = vmull_s16(d[1], d[4]); - q[0] = vmlsl_s16(q[0], d[2], d[5]); - q[1] = vmlsl_s16(q[1], d[3], d[5]); - - q[2] = vmull_s16(d[0], d[5]); - q[3] = vmull_s16(d[1], d[5]); - q[2] = vmlal_s16(q[2], d[2], d[4]); - q[3] = vmlal_s16(q[3], d[3], d[4]); - - *qOut0 = vcombine_s16(vrshrn_n_s32(q[0], DCT_CONST_BITS), - vrshrn_n_s32(q[1], DCT_CONST_BITS)); - *qOut1 = vcombine_s16(vrshrn_n_s32(q[2], DCT_CONST_BITS), - vrshrn_n_s32(q[3], DCT_CONST_BITS)); -} - -static INLINE void load_s16x8q(const int16_t *in, int16x8_t *const s0, - int16x8_t *const s1, int16x8_t *const s2, - int16x8_t *const s3, int16x8_t *const s4, - int16x8_t *const s5, int16x8_t *const s6, - int16x8_t *const s7) { - *s0 = vld1q_s16(in); - in += 32; - *s1 = vld1q_s16(in); - in += 32; - *s2 = vld1q_s16(in); - in += 32; - *s3 = vld1q_s16(in); - in += 32; - *s4 = vld1q_s16(in); - in += 32; - *s5 = vld1q_s16(in); - in += 32; - *s6 = vld1q_s16(in); - in += 32; - *s7 = vld1q_s16(in); -} - -static INLINE void transpose_and_store_s16_8x8(int16x8_t a0, int16x8_t a1, - int16x8_t a2, int16x8_t a3, - int16x8_t a4, int16x8_t a5, - int16x8_t a6, int16x8_t a7, - int16_t **out) { - transpose_s16_8x8(&a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7); - - vst1q_s16(*out, a0); - *out += 8; - vst1q_s16(*out, a1); - *out += 8; - vst1q_s16(*out, a2); - *out += 8; - vst1q_s16(*out, a3); - *out += 8; - vst1q_s16(*out, a4); - *out += 8; - vst1q_s16(*out, a5); - *out += 8; - vst1q_s16(*out, a6); - *out += 8; - vst1q_s16(*out, a7); - *out += 8; -} - -static INLINE void idct32_transpose_pair(const int16_t *input, int16_t *t_buf) { - int i; - int16x8_t s0, s1, s2, s3, s4, s5, s6, s7; - - for (i = 0; i < 4; i++, input += 8) { - load_s16x8q(input, &s0, &s1, &s2, &s3, &s4, &s5, &s6, &s7); - transpose_and_store_s16_8x8(s0, s1, s2, s3, s4, s5, s6, s7, &t_buf); - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -static INLINE void load_s16x8q_tran_low( - const tran_low_t *in, int16x8_t *const s0, int16x8_t *const s1, - int16x8_t *const s2, int16x8_t *const s3, int16x8_t *const s4, - int16x8_t *const s5, int16x8_t *const s6, int16x8_t *const s7) { - *s0 = load_tran_low_to_s16q(in); - in += 32; - *s1 = load_tran_low_to_s16q(in); - in += 32; - *s2 = load_tran_low_to_s16q(in); - in += 32; - *s3 = load_tran_low_to_s16q(in); - in += 32; - *s4 = load_tran_low_to_s16q(in); - in += 32; - *s5 = load_tran_low_to_s16q(in); - in += 32; - *s6 = load_tran_low_to_s16q(in); - in += 32; - *s7 = load_tran_low_to_s16q(in); -} - -static INLINE void idct32_transpose_pair_tran_low(const tran_low_t *input, - int16_t *t_buf) { - int i; - int16x8_t s0, s1, s2, s3, s4, s5, s6, s7; - - for (i = 0; i < 4; i++, input += 8) { - load_s16x8q_tran_low(input, &s0, &s1, &s2, &s3, &s4, &s5, &s6, &s7); - transpose_and_store_s16_8x8(s0, s1, s2, s3, s4, s5, s6, s7, &t_buf); - } -} -#else // !CONFIG_VP9_HIGHBITDEPTH -#define idct32_transpose_pair_tran_low idct32_transpose_pair -#endif // CONFIG_VP9_HIGHBITDEPTH - -static INLINE void idct32_bands_end_1st_pass(int16_t *const out, - int16x8_t *const q) { - store_in_output(out, 16, 17, q[6], q[7]); - store_in_output(out, 14, 15, q[8], q[9]); - - load_from_output(out, 30, 31, &q[0], &q[1]); - q[4] = vaddq_s16(q[2], q[1]); - q[5] = vaddq_s16(q[3], q[0]); - q[6] = vsubq_s16(q[3], q[0]); - q[7] = vsubq_s16(q[2], q[1]); - store_in_output(out, 30, 31, q[6], q[7]); - store_in_output(out, 0, 1, q[4], q[5]); - - load_from_output(out, 12, 13, &q[0], &q[1]); - q[2] = vaddq_s16(q[10], q[1]); - q[3] = vaddq_s16(q[11], q[0]); - q[4] = vsubq_s16(q[11], q[0]); - q[5] = vsubq_s16(q[10], q[1]); - - load_from_output(out, 18, 19, &q[0], &q[1]); - q[8] = vaddq_s16(q[4], q[1]); - q[9] = vaddq_s16(q[5], q[0]); - q[6] = vsubq_s16(q[5], q[0]); - q[7] = vsubq_s16(q[4], q[1]); - store_in_output(out, 18, 19, q[6], q[7]); - store_in_output(out, 12, 13, q[8], q[9]); - - load_from_output(out, 28, 29, &q[0], &q[1]); - q[4] = vaddq_s16(q[2], q[1]); - q[5] = vaddq_s16(q[3], q[0]); - q[6] = vsubq_s16(q[3], q[0]); - q[7] = vsubq_s16(q[2], q[1]); - store_in_output(out, 28, 29, q[6], q[7]); - store_in_output(out, 2, 3, q[4], q[5]); - - load_from_output(out, 10, 11, &q[0], &q[1]); - q[2] = vaddq_s16(q[12], q[1]); - q[3] = vaddq_s16(q[13], q[0]); - q[4] = vsubq_s16(q[13], q[0]); - q[5] = vsubq_s16(q[12], q[1]); - - load_from_output(out, 20, 21, &q[0], &q[1]); - q[8] = vaddq_s16(q[4], q[1]); - q[9] = vaddq_s16(q[5], q[0]); - q[6] = vsubq_s16(q[5], q[0]); - q[7] = vsubq_s16(q[4], q[1]); - store_in_output(out, 20, 21, q[6], q[7]); - store_in_output(out, 10, 11, q[8], q[9]); - - load_from_output(out, 26, 27, &q[0], &q[1]); - q[4] = vaddq_s16(q[2], q[1]); - q[5] = vaddq_s16(q[3], q[0]); - q[6] = vsubq_s16(q[3], q[0]); - q[7] = vsubq_s16(q[2], q[1]); - store_in_output(out, 26, 27, q[6], q[7]); - store_in_output(out, 4, 5, q[4], q[5]); - - load_from_output(out, 8, 9, &q[0], &q[1]); - q[2] = vaddq_s16(q[14], q[1]); - q[3] = vaddq_s16(q[15], q[0]); - q[4] = vsubq_s16(q[15], q[0]); - q[5] = vsubq_s16(q[14], q[1]); - - load_from_output(out, 22, 23, &q[0], &q[1]); - q[8] = vaddq_s16(q[4], q[1]); - q[9] = vaddq_s16(q[5], q[0]); - q[6] = vsubq_s16(q[5], q[0]); - q[7] = vsubq_s16(q[4], q[1]); - store_in_output(out, 22, 23, q[6], q[7]); - store_in_output(out, 8, 9, q[8], q[9]); - - load_from_output(out, 24, 25, &q[0], &q[1]); - q[4] = vaddq_s16(q[2], q[1]); - q[5] = vaddq_s16(q[3], q[0]); - q[6] = vsubq_s16(q[3], q[0]); - q[7] = vsubq_s16(q[2], q[1]); - store_in_output(out, 24, 25, q[6], q[7]); - store_in_output(out, 6, 7, q[4], q[5]); -} - -static INLINE void idct32_bands_end_2nd_pass(const int16_t *const out, - uint8_t *const dest, - const int stride, - int16x8_t *const q) { - uint8_t *dest0 = dest + 0 * stride; - uint8_t *dest1 = dest + 31 * stride; - uint8_t *dest2 = dest + 16 * stride; - uint8_t *dest3 = dest + 15 * stride; - const int str2 = stride << 1; - - store_combine_results(dest2, dest3, stride, q[6], q[7], q[8], q[9]); - dest2 += str2; - dest3 -= str2; - - load_from_output(out, 30, 31, &q[0], &q[1]); - q[4] = final_add(q[2], q[1]); - q[5] = final_add(q[3], q[0]); - q[6] = final_sub(q[3], q[0]); - q[7] = final_sub(q[2], q[1]); - store_combine_results(dest0, dest1, stride, q[4], q[5], q[6], q[7]); - dest0 += str2; - dest1 -= str2; - - load_from_output(out, 12, 13, &q[0], &q[1]); - q[2] = vaddq_s16(q[10], q[1]); - q[3] = vaddq_s16(q[11], q[0]); - q[4] = vsubq_s16(q[11], q[0]); - q[5] = vsubq_s16(q[10], q[1]); - - load_from_output(out, 18, 19, &q[0], &q[1]); - q[8] = final_add(q[4], q[1]); - q[9] = final_add(q[5], q[0]); - q[6] = final_sub(q[5], q[0]); - q[7] = final_sub(q[4], q[1]); - store_combine_results(dest2, dest3, stride, q[6], q[7], q[8], q[9]); - dest2 += str2; - dest3 -= str2; - - load_from_output(out, 28, 29, &q[0], &q[1]); - q[4] = final_add(q[2], q[1]); - q[5] = final_add(q[3], q[0]); - q[6] = final_sub(q[3], q[0]); - q[7] = final_sub(q[2], q[1]); - store_combine_results(dest0, dest1, stride, q[4], q[5], q[6], q[7]); - dest0 += str2; - dest1 -= str2; - - load_from_output(out, 10, 11, &q[0], &q[1]); - q[2] = vaddq_s16(q[12], q[1]); - q[3] = vaddq_s16(q[13], q[0]); - q[4] = vsubq_s16(q[13], q[0]); - q[5] = vsubq_s16(q[12], q[1]); - - load_from_output(out, 20, 21, &q[0], &q[1]); - q[8] = final_add(q[4], q[1]); - q[9] = final_add(q[5], q[0]); - q[6] = final_sub(q[5], q[0]); - q[7] = final_sub(q[4], q[1]); - store_combine_results(dest2, dest3, stride, q[6], q[7], q[8], q[9]); - dest2 += str2; - dest3 -= str2; - - load_from_output(out, 26, 27, &q[0], &q[1]); - q[4] = final_add(q[2], q[1]); - q[5] = final_add(q[3], q[0]); - q[6] = final_sub(q[3], q[0]); - q[7] = final_sub(q[2], q[1]); - store_combine_results(dest0, dest1, stride, q[4], q[5], q[6], q[7]); - dest0 += str2; - dest1 -= str2; - - load_from_output(out, 8, 9, &q[0], &q[1]); - q[2] = vaddq_s16(q[14], q[1]); - q[3] = vaddq_s16(q[15], q[0]); - q[4] = vsubq_s16(q[15], q[0]); - q[5] = vsubq_s16(q[14], q[1]); - - load_from_output(out, 22, 23, &q[0], &q[1]); - q[8] = final_add(q[4], q[1]); - q[9] = final_add(q[5], q[0]); - q[6] = final_sub(q[5], q[0]); - q[7] = final_sub(q[4], q[1]); - store_combine_results(dest2, dest3, stride, q[6], q[7], q[8], q[9]); - - load_from_output(out, 24, 25, &q[0], &q[1]); - q[4] = final_add(q[2], q[1]); - q[5] = final_add(q[3], q[0]); - q[6] = final_sub(q[3], q[0]); - q[7] = final_sub(q[2], q[1]); - store_combine_results(dest0, dest1, stride, q[4], q[5], q[6], q[7]); -} - -static INLINE void highbd_idct32_bands_end_2nd_pass_bd8( - const int16_t *const out, uint16_t *const dest, const int stride, - int16x8_t *const q) { - uint16_t *dest0 = dest + 0 * stride; - uint16_t *dest1 = dest + 31 * stride; - uint16_t *dest2 = dest + 16 * stride; - uint16_t *dest3 = dest + 15 * stride; - const int str2 = stride << 1; - - highbd_store_combine_results_bd8(dest2, dest3, stride, q[6], q[7], q[8], - q[9]); - dest2 += str2; - dest3 -= str2; - - load_from_output(out, 30, 31, &q[0], &q[1]); - q[4] = final_add(q[2], q[1]); - q[5] = final_add(q[3], q[0]); - q[6] = final_sub(q[3], q[0]); - q[7] = final_sub(q[2], q[1]); - highbd_store_combine_results_bd8(dest0, dest1, stride, q[4], q[5], q[6], - q[7]); - dest0 += str2; - dest1 -= str2; - - load_from_output(out, 12, 13, &q[0], &q[1]); - q[2] = vaddq_s16(q[10], q[1]); - q[3] = vaddq_s16(q[11], q[0]); - q[4] = vsubq_s16(q[11], q[0]); - q[5] = vsubq_s16(q[10], q[1]); - - load_from_output(out, 18, 19, &q[0], &q[1]); - q[8] = final_add(q[4], q[1]); - q[9] = final_add(q[5], q[0]); - q[6] = final_sub(q[5], q[0]); - q[7] = final_sub(q[4], q[1]); - highbd_store_combine_results_bd8(dest2, dest3, stride, q[6], q[7], q[8], - q[9]); - dest2 += str2; - dest3 -= str2; - - load_from_output(out, 28, 29, &q[0], &q[1]); - q[4] = final_add(q[2], q[1]); - q[5] = final_add(q[3], q[0]); - q[6] = final_sub(q[3], q[0]); - q[7] = final_sub(q[2], q[1]); - highbd_store_combine_results_bd8(dest0, dest1, stride, q[4], q[5], q[6], - q[7]); - dest0 += str2; - dest1 -= str2; - - load_from_output(out, 10, 11, &q[0], &q[1]); - q[2] = vaddq_s16(q[12], q[1]); - q[3] = vaddq_s16(q[13], q[0]); - q[4] = vsubq_s16(q[13], q[0]); - q[5] = vsubq_s16(q[12], q[1]); - - load_from_output(out, 20, 21, &q[0], &q[1]); - q[8] = final_add(q[4], q[1]); - q[9] = final_add(q[5], q[0]); - q[6] = final_sub(q[5], q[0]); - q[7] = final_sub(q[4], q[1]); - highbd_store_combine_results_bd8(dest2, dest3, stride, q[6], q[7], q[8], - q[9]); - dest2 += str2; - dest3 -= str2; - - load_from_output(out, 26, 27, &q[0], &q[1]); - q[4] = final_add(q[2], q[1]); - q[5] = final_add(q[3], q[0]); - q[6] = final_sub(q[3], q[0]); - q[7] = final_sub(q[2], q[1]); - highbd_store_combine_results_bd8(dest0, dest1, stride, q[4], q[5], q[6], - q[7]); - dest0 += str2; - dest1 -= str2; - - load_from_output(out, 8, 9, &q[0], &q[1]); - q[2] = vaddq_s16(q[14], q[1]); - q[3] = vaddq_s16(q[15], q[0]); - q[4] = vsubq_s16(q[15], q[0]); - q[5] = vsubq_s16(q[14], q[1]); - - load_from_output(out, 22, 23, &q[0], &q[1]); - q[8] = final_add(q[4], q[1]); - q[9] = final_add(q[5], q[0]); - q[6] = final_sub(q[5], q[0]); - q[7] = final_sub(q[4], q[1]); - highbd_store_combine_results_bd8(dest2, dest3, stride, q[6], q[7], q[8], - q[9]); - - load_from_output(out, 24, 25, &q[0], &q[1]); - q[4] = final_add(q[2], q[1]); - q[5] = final_add(q[3], q[0]); - q[6] = final_sub(q[3], q[0]); - q[7] = final_sub(q[2], q[1]); - highbd_store_combine_results_bd8(dest0, dest1, stride, q[4], q[5], q[6], - q[7]); -} - -void vpx_idct32_32_neon(const tran_low_t *input, uint8_t *dest, - const int stride, const int highbd_flag) { - int i, idct32_pass_loop; - int16_t trans_buf[32 * 8]; - int16_t pass1[32 * 32]; - int16_t pass2[32 * 32]; - const int16_t *input_pass2 = pass1; // input of pass2 is the result of pass1 - int16_t *out; - int16x8_t q[16]; - uint16_t *dst = CAST_TO_SHORTPTR(dest); - - for (idct32_pass_loop = 0, out = pass1; idct32_pass_loop < 2; - idct32_pass_loop++, out = pass2) { - for (i = 0; i < 4; i++, out += 8) { // idct32_bands_loop - if (idct32_pass_loop == 0) { - idct32_transpose_pair_tran_low(input, trans_buf); - input += 32 * 8; - } else { - idct32_transpose_pair(input_pass2, trans_buf); - input_pass2 += 32 * 8; - } - - // ----------------------------------------- - // BLOCK A: 16-19,28-31 - // ----------------------------------------- - // generate 16,17,30,31 - // part of stage 1 - load_from_transformed(trans_buf, 1, 31, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_31_64, cospi_1_64, &q[0], &q[2]); - load_from_transformed(trans_buf, 17, 15, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_15_64, cospi_17_64, &q[1], &q[3]); - // part of stage 2 - q[4] = vaddq_s16(q[0], q[1]); - q[13] = vsubq_s16(q[0], q[1]); - q[6] = vaddq_s16(q[2], q[3]); - q[14] = vsubq_s16(q[2], q[3]); - // part of stage 3 - do_butterfly(q[14], q[13], cospi_28_64, cospi_4_64, &q[5], &q[7]); - - // generate 18,19,28,29 - // part of stage 1 - load_from_transformed(trans_buf, 9, 23, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_23_64, cospi_9_64, &q[0], &q[2]); - load_from_transformed(trans_buf, 25, 7, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_7_64, cospi_25_64, &q[1], &q[3]); - // part of stage 2 - q[13] = vsubq_s16(q[3], q[2]); - q[3] = vaddq_s16(q[3], q[2]); - q[14] = vsubq_s16(q[1], q[0]); - q[2] = vaddq_s16(q[1], q[0]); - // part of stage 3 - do_butterfly(q[14], q[13], -cospi_4_64, -cospi_28_64, &q[1], &q[0]); - // part of stage 4 - q[8] = vaddq_s16(q[4], q[2]); - q[9] = vaddq_s16(q[5], q[0]); - q[10] = vaddq_s16(q[7], q[1]); - q[15] = vaddq_s16(q[6], q[3]); - q[13] = vsubq_s16(q[5], q[0]); - q[14] = vsubq_s16(q[7], q[1]); - store_in_output(out, 16, 31, q[8], q[15]); - store_in_output(out, 17, 30, q[9], q[10]); - // part of stage 5 - do_butterfly(q[14], q[13], cospi_24_64, cospi_8_64, &q[0], &q[1]); - store_in_output(out, 29, 18, q[1], q[0]); - // part of stage 4 - q[13] = vsubq_s16(q[4], q[2]); - q[14] = vsubq_s16(q[6], q[3]); - // part of stage 5 - do_butterfly(q[14], q[13], cospi_24_64, cospi_8_64, &q[4], &q[6]); - store_in_output(out, 19, 28, q[4], q[6]); - - // ----------------------------------------- - // BLOCK B: 20-23,24-27 - // ----------------------------------------- - // generate 20,21,26,27 - // part of stage 1 - load_from_transformed(trans_buf, 5, 27, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_27_64, cospi_5_64, &q[0], &q[2]); - load_from_transformed(trans_buf, 21, 11, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_11_64, cospi_21_64, &q[1], &q[3]); - // part of stage 2 - q[13] = vsubq_s16(q[0], q[1]); - q[0] = vaddq_s16(q[0], q[1]); - q[14] = vsubq_s16(q[2], q[3]); - q[2] = vaddq_s16(q[2], q[3]); - // part of stage 3 - do_butterfly(q[14], q[13], cospi_12_64, cospi_20_64, &q[1], &q[3]); - - // generate 22,23,24,25 - // part of stage 1 - load_from_transformed(trans_buf, 13, 19, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_19_64, cospi_13_64, &q[5], &q[7]); - load_from_transformed(trans_buf, 29, 3, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_3_64, cospi_29_64, &q[4], &q[6]); - // part of stage 2 - q[14] = vsubq_s16(q[4], q[5]); - q[5] = vaddq_s16(q[4], q[5]); - q[13] = vsubq_s16(q[6], q[7]); - q[6] = vaddq_s16(q[6], q[7]); - // part of stage 3 - do_butterfly(q[14], q[13], -cospi_20_64, -cospi_12_64, &q[4], &q[7]); - // part of stage 4 - q[10] = vaddq_s16(q[7], q[1]); - q[11] = vaddq_s16(q[5], q[0]); - q[12] = vaddq_s16(q[6], q[2]); - q[15] = vaddq_s16(q[4], q[3]); - // part of stage 6 - load_from_output(out, 16, 17, &q[14], &q[13]); - q[8] = vaddq_s16(q[14], q[11]); - q[9] = vaddq_s16(q[13], q[10]); - q[13] = vsubq_s16(q[13], q[10]); - q[11] = vsubq_s16(q[14], q[11]); - store_in_output(out, 17, 16, q[9], q[8]); - load_from_output(out, 30, 31, &q[14], &q[9]); - q[8] = vsubq_s16(q[9], q[12]); - q[10] = vaddq_s16(q[14], q[15]); - q[14] = vsubq_s16(q[14], q[15]); - q[12] = vaddq_s16(q[9], q[12]); - store_in_output(out, 30, 31, q[10], q[12]); - // part of stage 7 - do_butterfly(q[14], q[13], cospi_16_64, cospi_16_64, &q[13], &q[14]); - store_in_output(out, 25, 22, q[14], q[13]); - do_butterfly(q[8], q[11], cospi_16_64, cospi_16_64, &q[13], &q[14]); - store_in_output(out, 24, 23, q[14], q[13]); - // part of stage 4 - q[14] = vsubq_s16(q[5], q[0]); - q[13] = vsubq_s16(q[6], q[2]); - do_butterfly(q[14], q[13], -cospi_8_64, -cospi_24_64, &q[5], &q[6]); - q[14] = vsubq_s16(q[7], q[1]); - q[13] = vsubq_s16(q[4], q[3]); - do_butterfly(q[14], q[13], -cospi_8_64, -cospi_24_64, &q[0], &q[1]); - // part of stage 6 - load_from_output(out, 18, 19, &q[14], &q[13]); - q[8] = vaddq_s16(q[14], q[1]); - q[9] = vaddq_s16(q[13], q[6]); - q[13] = vsubq_s16(q[13], q[6]); - q[1] = vsubq_s16(q[14], q[1]); - store_in_output(out, 18, 19, q[8], q[9]); - load_from_output(out, 28, 29, &q[8], &q[9]); - q[14] = vsubq_s16(q[8], q[5]); - q[10] = vaddq_s16(q[8], q[5]); - q[11] = vaddq_s16(q[9], q[0]); - q[0] = vsubq_s16(q[9], q[0]); - store_in_output(out, 28, 29, q[10], q[11]); - // part of stage 7 - do_butterfly(q[14], q[13], cospi_16_64, cospi_16_64, &q[13], &q[14]); - store_in_output(out, 20, 27, q[13], q[14]); - do_butterfly(q[0], q[1], cospi_16_64, cospi_16_64, &q[1], &q[0]); - store_in_output(out, 21, 26, q[1], q[0]); - - // ----------------------------------------- - // BLOCK C: 8-10,11-15 - // ----------------------------------------- - // generate 8,9,14,15 - // part of stage 2 - load_from_transformed(trans_buf, 2, 30, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_30_64, cospi_2_64, &q[0], &q[2]); - load_from_transformed(trans_buf, 18, 14, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_14_64, cospi_18_64, &q[1], &q[3]); - // part of stage 3 - q[13] = vsubq_s16(q[0], q[1]); - q[0] = vaddq_s16(q[0], q[1]); - q[14] = vsubq_s16(q[2], q[3]); - q[2] = vaddq_s16(q[2], q[3]); - // part of stage 4 - do_butterfly(q[14], q[13], cospi_24_64, cospi_8_64, &q[1], &q[3]); - - // generate 10,11,12,13 - // part of stage 2 - load_from_transformed(trans_buf, 10, 22, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_22_64, cospi_10_64, &q[5], &q[7]); - load_from_transformed(trans_buf, 26, 6, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_6_64, cospi_26_64, &q[4], &q[6]); - // part of stage 3 - q[14] = vsubq_s16(q[4], q[5]); - q[5] = vaddq_s16(q[4], q[5]); - q[13] = vsubq_s16(q[6], q[7]); - q[6] = vaddq_s16(q[6], q[7]); - // part of stage 4 - do_butterfly(q[14], q[13], -cospi_8_64, -cospi_24_64, &q[4], &q[7]); - // part of stage 5 - q[8] = vaddq_s16(q[0], q[5]); - q[9] = vaddq_s16(q[1], q[7]); - q[13] = vsubq_s16(q[1], q[7]); - q[14] = vsubq_s16(q[3], q[4]); - q[10] = vaddq_s16(q[3], q[4]); - q[15] = vaddq_s16(q[2], q[6]); - store_in_output(out, 8, 15, q[8], q[15]); - store_in_output(out, 9, 14, q[9], q[10]); - // part of stage 6 - do_butterfly(q[14], q[13], cospi_16_64, cospi_16_64, &q[1], &q[3]); - store_in_output(out, 13, 10, q[3], q[1]); - q[13] = vsubq_s16(q[0], q[5]); - q[14] = vsubq_s16(q[2], q[6]); - do_butterfly(q[14], q[13], cospi_16_64, cospi_16_64, &q[1], &q[3]); - store_in_output(out, 11, 12, q[1], q[3]); - - // ----------------------------------------- - // BLOCK D: 0-3,4-7 - // ----------------------------------------- - // generate 4,5,6,7 - // part of stage 3 - load_from_transformed(trans_buf, 4, 28, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_28_64, cospi_4_64, &q[0], &q[2]); - load_from_transformed(trans_buf, 20, 12, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_12_64, cospi_20_64, &q[1], &q[3]); - // part of stage 4 - q[13] = vsubq_s16(q[0], q[1]); - q[0] = vaddq_s16(q[0], q[1]); - q[14] = vsubq_s16(q[2], q[3]); - q[2] = vaddq_s16(q[2], q[3]); - // part of stage 5 - do_butterfly(q[14], q[13], cospi_16_64, cospi_16_64, &q[1], &q[3]); - - // generate 0,1,2,3 - // part of stage 4 - load_from_transformed(trans_buf, 0, 16, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_16_64, cospi_16_64, &q[5], &q[7]); - load_from_transformed(trans_buf, 8, 24, &q[14], &q[13]); - do_butterfly(q[14], q[13], cospi_24_64, cospi_8_64, &q[14], &q[6]); - // part of stage 5 - q[4] = vaddq_s16(q[7], q[6]); - q[7] = vsubq_s16(q[7], q[6]); - q[6] = vsubq_s16(q[5], q[14]); - q[5] = vaddq_s16(q[5], q[14]); - // part of stage 6 - q[8] = vaddq_s16(q[4], q[2]); - q[9] = vaddq_s16(q[5], q[3]); - q[10] = vaddq_s16(q[6], q[1]); - q[11] = vaddq_s16(q[7], q[0]); - q[12] = vsubq_s16(q[7], q[0]); - q[13] = vsubq_s16(q[6], q[1]); - q[14] = vsubq_s16(q[5], q[3]); - q[15] = vsubq_s16(q[4], q[2]); - // part of stage 7 - load_from_output(out, 14, 15, &q[0], &q[1]); - q[2] = vaddq_s16(q[8], q[1]); - q[3] = vaddq_s16(q[9], q[0]); - q[4] = vsubq_s16(q[9], q[0]); - q[5] = vsubq_s16(q[8], q[1]); - load_from_output(out, 16, 17, &q[0], &q[1]); - q[8] = final_add(q[4], q[1]); - q[9] = final_add(q[5], q[0]); - q[6] = final_sub(q[5], q[0]); - q[7] = final_sub(q[4], q[1]); - - if (idct32_pass_loop == 0) { - idct32_bands_end_1st_pass(out, q); - } else { - if (highbd_flag) { - highbd_idct32_bands_end_2nd_pass_bd8(out, dst, stride, q); - dst += 8; - } else { - idct32_bands_end_2nd_pass(out, dest, stride, q); - dest += 8; - } - } - } - } -} - -void vpx_idct32x32_1024_add_neon(const tran_low_t *input, uint8_t *dest, - int stride) { - vpx_idct32_32_neon(input, dest, stride, 0); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct4x4_1_add_neon.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct4x4_1_add_neon.asm deleted file mode 100644 index d83421e9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct4x4_1_add_neon.asm +++ /dev/null @@ -1,66 +0,0 @@ -; -; Copyright (c) 2013 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license and patent -; grant that can be found in the LICENSE file in the root of the source -; tree. All contributing project authors may be found in the AUTHORS -; file in the root of the source tree. -; - - - EXPORT |vpx_idct4x4_1_add_neon| - ARM - REQUIRE8 - PRESERVE8 - - AREA ||.text||, CODE, READONLY, ALIGN=2 - -;void vpx_idct4x4_1_add_neon(int16_t *input, uint8_t *dest, int stride) -; -; r0 int16_t input -; r1 uint8_t *dest -; r2 int stride) - -|vpx_idct4x4_1_add_neon| PROC - ldrsh r0, [r0] - - ; cospi_16_64 = 11585 - movw r12, #0x2d41 - - ; out = dct_const_round_shift(input[0] * cospi_16_64) - mul r0, r0, r12 ; input[0] * cospi_16_64 - add r0, r0, #0x2000 ; +(1 << ((DCT_CONST_BITS) - 1)) - asr r0, r0, #14 ; >> DCT_CONST_BITS - - ; out = dct_const_round_shift(out * cospi_16_64) - mul r0, r0, r12 ; out * cospi_16_64 - mov r12, r1 ; save dest - add r0, r0, #0x2000 ; +(1 << ((DCT_CONST_BITS) - 1)) - asr r0, r0, #14 ; >> DCT_CONST_BITS - - ; a1 = ROUND_POWER_OF_TWO(out, 4) - add r0, r0, #8 ; + (1 <<((4) - 1)) - asr r0, r0, #4 ; >> 4 - - vdup.s16 q0, r0 ; duplicate a1 - - vld1.32 {d2[0]}, [r1], r2 - vld1.32 {d2[1]}, [r1], r2 - vld1.32 {d4[0]}, [r1], r2 - vld1.32 {d4[1]}, [r1] - - vaddw.u8 q8, q0, d2 ; dest[x] + a1 - vaddw.u8 q9, q0, d4 - - vqmovun.s16 d6, q8 ; clip_pixel - vqmovun.s16 d7, q9 - - vst1.32 {d6[0]}, [r12], r2 - vst1.32 {d6[1]}, [r12], r2 - vst1.32 {d7[0]}, [r12], r2 - vst1.32 {d7[1]}, [r12] - - bx lr - ENDP ; |vpx_idct4x4_1_add_neon| - - END diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct4x4_1_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct4x4_1_add_neon.c deleted file mode 100644 index a14b8954..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct4x4_1_add_neon.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/inv_txfm.h" - -static INLINE void idct4x4_1_add_kernel(uint8_t **dest, const int stride, - const int16x8_t res, - uint32x2_t *const d) { - uint16x8_t a; - uint8x8_t b; - *d = vld1_lane_u32((const uint32_t *)*dest, *d, 0); - *d = vld1_lane_u32((const uint32_t *)(*dest + stride), *d, 1); - a = vaddw_u8(vreinterpretq_u16_s16(res), vreinterpret_u8_u32(*d)); - b = vqmovun_s16(vreinterpretq_s16_u16(a)); - vst1_lane_u32((uint32_t *)*dest, vreinterpret_u32_u8(b), 0); - *dest += stride; - vst1_lane_u32((uint32_t *)*dest, vreinterpret_u32_u8(b), 1); - *dest += stride; -} - -void vpx_idct4x4_1_add_neon(const tran_low_t *input, uint8_t *dest, - int stride) { - const int16_t out0 = - WRAPLOW(dct_const_round_shift((int16_t)input[0] * cospi_16_64)); - const int16_t out1 = WRAPLOW(dct_const_round_shift(out0 * cospi_16_64)); - const int16_t a1 = ROUND_POWER_OF_TWO(out1, 4); - const int16x8_t dc = vdupq_n_s16(a1); - uint32x2_t d = vdup_n_u32(0); - - assert(!((intptr_t)dest % sizeof(uint32_t))); - assert(!(stride % sizeof(uint32_t))); - - idct4x4_1_add_kernel(&dest, stride, dc, &d); - idct4x4_1_add_kernel(&dest, stride, dc, &d); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct4x4_add_neon.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct4x4_add_neon.asm deleted file mode 100644 index 175ba7fb..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct4x4_add_neon.asm +++ /dev/null @@ -1,188 +0,0 @@ -; -; Copyright (c) 2013 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - EXPORT |vpx_idct4x4_16_add_neon| - ARM - REQUIRE8 - PRESERVE8 - - AREA ||.text||, CODE, READONLY, ALIGN=2 - - INCLUDE vpx_dsp/arm/idct_neon.asm.S - - AREA Block, CODE, READONLY -;void vpx_idct4x4_16_add_neon(int16_t *input, uint8_t *dest, int stride) -; -; r0 int16_t input -; r1 uint8_t *dest -; r2 int stride) - -|vpx_idct4x4_16_add_neon| PROC - - ; The 2D transform is done with two passes which are actually pretty - ; similar. We first transform the rows. This is done by transposing - ; the inputs, doing an SIMD column transform (the columns are the - ; transposed rows) and then transpose the results (so that it goes back - ; in normal/row positions). Then, we transform the columns by doing - ; another SIMD column transform. - ; So, two passes of a transpose followed by a column transform. - - ; load the inputs into q8-q9, d16-d19 - LOAD_TRAN_LOW_TO_S16 d16, d17, d18, d19, r0 - - ; generate scalar constants - ; cospi_8_64 = 15137 - movw r0, #0x3b21 - ; cospi_16_64 = 11585 - movw r3, #0x2d41 - ; cospi_24_64 = 6270 - movw r12, #0x187e - - ; transpose the input data - ; 00 01 02 03 d16 - ; 10 11 12 13 d17 - ; 20 21 22 23 d18 - ; 30 31 32 33 d19 - vtrn.16 d16, d17 - vtrn.16 d18, d19 - - ; generate constant vectors - vdup.16 d20, r0 ; replicate cospi_8_64 - vdup.16 d21, r3 ; replicate cospi_16_64 - - ; 00 10 02 12 d16 - ; 01 11 03 13 d17 - ; 20 30 22 32 d18 - ; 21 31 23 33 d19 - vtrn.32 q8, q9 - ; 00 10 20 30 d16 - ; 01 11 21 31 d17 - ; 02 12 22 32 d18 - ; 03 13 23 33 d19 - - vdup.16 d22, r12 ; replicate cospi_24_64 - - ; do the transform on transposed rows - - ; stage 1 - vmull.s16 q15, d17, d22 ; input[1] * cospi_24_64 - vmull.s16 q1, d17, d20 ; input[1] * cospi_8_64 - - ; (input[0] + input[2]) * cospi_16_64; - ; (input[0] - input[2]) * cospi_16_64; - vmull.s16 q8, d16, d21 - vmull.s16 q14, d18, d21 - vadd.s32 q13, q8, q14 - vsub.s32 q14, q8, q14 - - ; input[1] * cospi_24_64 - input[3] * cospi_8_64; - ; input[1] * cospi_8_64 + input[3] * cospi_24_64; - vmlsl.s16 q15, d19, d20 - vmlal.s16 q1, d19, d22 - - ; dct_const_round_shift - vrshrn.s32 d26, q13, #14 - vrshrn.s32 d27, q14, #14 - vrshrn.s32 d29, q15, #14 - vrshrn.s32 d28, q1, #14 - - ; stage 2 - ; output[0] = step[0] + step[3]; - ; output[1] = step[1] + step[2]; - ; output[3] = step[0] - step[3]; - ; output[2] = step[1] - step[2]; - vadd.s16 q8, q13, q14 - vsub.s16 q9, q13, q14 - vswp d18, d19 - - ; transpose the results - ; 00 01 02 03 d16 - ; 10 11 12 13 d17 - ; 20 21 22 23 d18 - ; 30 31 32 33 d19 - vtrn.16 d16, d17 - vtrn.16 d18, d19 - ; 00 10 02 12 d16 - ; 01 11 03 13 d17 - ; 20 30 22 32 d18 - ; 21 31 23 33 d19 - vtrn.32 q8, q9 - ; 00 10 20 30 d16 - ; 01 11 21 31 d17 - ; 02 12 22 32 d18 - ; 03 13 23 33 d19 - - ; do the transform on columns - - ; stage 1 - vadd.s16 d23, d16, d18 ; (input[0] + input[2]) - vsub.s16 d24, d16, d18 ; (input[0] - input[2]) - - vmull.s16 q15, d17, d22 ; input[1] * cospi_24_64 - vmull.s16 q1, d17, d20 ; input[1] * cospi_8_64 - - ; (input[0] + input[2]) * cospi_16_64; - ; (input[0] - input[2]) * cospi_16_64; - vmull.s16 q13, d23, d21 - vmull.s16 q14, d24, d21 - - ; input[1] * cospi_24_64 - input[3] * cospi_8_64; - ; input[1] * cospi_8_64 + input[3] * cospi_24_64; - vmlsl.s16 q15, d19, d20 - vmlal.s16 q1, d19, d22 - - ; dct_const_round_shift - vrshrn.s32 d26, q13, #14 - vrshrn.s32 d27, q14, #14 - vrshrn.s32 d29, q15, #14 - vrshrn.s32 d28, q1, #14 - - ; stage 2 - ; output[0] = step[0] + step[3]; - ; output[1] = step[1] + step[2]; - ; output[3] = step[0] - step[3]; - ; output[2] = step[1] - step[2]; - vadd.s16 q8, q13, q14 - vsub.s16 q9, q13, q14 - - ; The results are in two registers, one of them being swapped. This will - ; be taken care of by loading the 'dest' value in a swapped fashion and - ; also storing them in the same swapped fashion. - ; temp_out[0, 1] = d16, d17 = q8 - ; temp_out[2, 3] = d19, d18 = q9 swapped - - ; ROUND_POWER_OF_TWO(temp_out[j], 4) - vrshr.s16 q8, q8, #4 - vrshr.s16 q9, q9, #4 - - vld1.32 {d26[0]}, [r1], r2 - vld1.32 {d26[1]}, [r1], r2 - vld1.32 {d27[1]}, [r1], r2 - vld1.32 {d27[0]}, [r1] ; no post-increment - - ; ROUND_POWER_OF_TWO(temp_out[j], 4) + dest[j * stride + i] - vaddw.u8 q8, q8, d26 - vaddw.u8 q9, q9, d27 - - ; clip_pixel - vqmovun.s16 d26, q8 - vqmovun.s16 d27, q9 - - ; do the stores in reverse order with negative post-increment, by changing - ; the sign of the stride - rsb r2, r2, #0 - vst1.32 {d27[0]}, [r1], r2 - vst1.32 {d27[1]}, [r1], r2 - vst1.32 {d26[1]}, [r1], r2 - vst1.32 {d26[0]}, [r1] ; no post-increment - bx lr - ENDP ; |vpx_idct4x4_16_add_neon| - - END diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct4x4_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct4x4_add_neon.c deleted file mode 100644 index 8192ee4c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct4x4_add_neon.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/txfm_common.h" - -void vpx_idct4x4_16_add_neon(const tran_low_t *input, uint8_t *dest, - int stride) { - const uint8_t *dst = dest; - uint32x2_t s32 = vdup_n_u32(0); - int16x8_t a[2]; - uint8x8_t s, d[2]; - uint16x8_t sum[2]; - - assert(!((intptr_t)dest % sizeof(uint32_t))); - assert(!(stride % sizeof(uint32_t))); - - // Rows - a[0] = load_tran_low_to_s16q(input); - a[1] = load_tran_low_to_s16q(input + 8); - transpose_idct4x4_16_bd8(a); - - // Columns - a[1] = vcombine_s16(vget_high_s16(a[1]), vget_low_s16(a[1])); - transpose_idct4x4_16_bd8(a); - a[0] = vrshrq_n_s16(a[0], 4); - a[1] = vrshrq_n_s16(a[1], 4); - - s = load_u8(dst, stride); - dst += 2 * stride; - // The elements are loaded in reverse order. - s32 = vld1_lane_u32((const uint32_t *)dst, s32, 1); - dst += stride; - s32 = vld1_lane_u32((const uint32_t *)dst, s32, 0); - - sum[0] = vaddw_u8(vreinterpretq_u16_s16(a[0]), s); - sum[1] = vaddw_u8(vreinterpretq_u16_s16(a[1]), vreinterpret_u8_u32(s32)); - d[0] = vqmovun_s16(vreinterpretq_s16_u16(sum[0])); - d[1] = vqmovun_s16(vreinterpretq_s16_u16(sum[1])); - - store_u8(dest, stride, d[0]); - dest += 2 * stride; - // The elements are stored in reverse order. - vst1_lane_u32((uint32_t *)dest, vreinterpret_u32_u8(d[1]), 1); - dest += stride; - vst1_lane_u32((uint32_t *)dest, vreinterpret_u32_u8(d[1]), 0); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct8x8_1_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct8x8_1_add_neon.c deleted file mode 100644 index ce9b4595..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct8x8_1_add_neon.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/inv_txfm.h" - -static INLINE uint8x8_t create_dcd(const int16_t dc) { - int16x8_t t = vdupq_n_s16(dc); - return vqmovun_s16(t); -} - -static INLINE void idct8x8_1_add_pos_kernel(uint8_t **dest, const int stride, - const uint8x8_t res) { - const uint8x8_t a = vld1_u8(*dest); - const uint8x8_t b = vqadd_u8(a, res); - vst1_u8(*dest, b); - *dest += stride; -} - -static INLINE void idct8x8_1_add_neg_kernel(uint8_t **dest, const int stride, - const uint8x8_t res) { - const uint8x8_t a = vld1_u8(*dest); - const uint8x8_t b = vqsub_u8(a, res); - vst1_u8(*dest, b); - *dest += stride; -} - -void vpx_idct8x8_1_add_neon(const tran_low_t *input, uint8_t *dest, - int stride) { - const int16_t out0 = - WRAPLOW(dct_const_round_shift((int16_t)input[0] * cospi_16_64)); - const int16_t out1 = WRAPLOW(dct_const_round_shift(out0 * cospi_16_64)); - const int16_t a1 = ROUND_POWER_OF_TWO(out1, 5); - - if (a1 >= 0) { - const uint8x8_t dc = create_dcd(a1); - idct8x8_1_add_pos_kernel(&dest, stride, dc); - idct8x8_1_add_pos_kernel(&dest, stride, dc); - idct8x8_1_add_pos_kernel(&dest, stride, dc); - idct8x8_1_add_pos_kernel(&dest, stride, dc); - idct8x8_1_add_pos_kernel(&dest, stride, dc); - idct8x8_1_add_pos_kernel(&dest, stride, dc); - idct8x8_1_add_pos_kernel(&dest, stride, dc); - idct8x8_1_add_pos_kernel(&dest, stride, dc); - } else { - const uint8x8_t dc = create_dcd(-a1); - idct8x8_1_add_neg_kernel(&dest, stride, dc); - idct8x8_1_add_neg_kernel(&dest, stride, dc); - idct8x8_1_add_neg_kernel(&dest, stride, dc); - idct8x8_1_add_neg_kernel(&dest, stride, dc); - idct8x8_1_add_neg_kernel(&dest, stride, dc); - idct8x8_1_add_neg_kernel(&dest, stride, dc); - idct8x8_1_add_neg_kernel(&dest, stride, dc); - idct8x8_1_add_neg_kernel(&dest, stride, dc); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct8x8_add_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct8x8_add_neon.c deleted file mode 100644 index 7471387e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct8x8_add_neon.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/idct_neon.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/txfm_common.h" - -void vpx_idct8x8_64_add_neon(const tran_low_t *input, uint8_t *dest, - int stride) { - const int16x8_t cospis = vld1q_s16(kCospi); - const int16x4_t cospis0 = vget_low_s16(cospis); // cospi 0, 8, 16, 24 - const int16x4_t cospis1 = vget_high_s16(cospis); // cospi 4, 12, 20, 28 - int16x8_t a[8]; - - a[0] = load_tran_low_to_s16q(input); - a[1] = load_tran_low_to_s16q(input + 8); - a[2] = load_tran_low_to_s16q(input + 16); - a[3] = load_tran_low_to_s16q(input + 24); - a[4] = load_tran_low_to_s16q(input + 32); - a[5] = load_tran_low_to_s16q(input + 40); - a[6] = load_tran_low_to_s16q(input + 48); - a[7] = load_tran_low_to_s16q(input + 56); - - idct8x8_64_1d_bd8(cospis0, cospis1, a); - idct8x8_64_1d_bd8(cospis0, cospis1, a); - idct8x8_add8x8_neon(a, dest, stride); -} - -void vpx_idct8x8_12_add_neon(const tran_low_t *input, uint8_t *dest, - int stride) { - const int16x8_t cospis = vld1q_s16(kCospi); - const int16x8_t cospisd = vaddq_s16(cospis, cospis); - const int16x4_t cospis0 = vget_low_s16(cospis); // cospi 0, 8, 16, 24 - const int16x4_t cospisd0 = vget_low_s16(cospisd); // doubled 0, 8, 16, 24 - const int16x4_t cospisd1 = vget_high_s16(cospisd); // doubled 4, 12, 20, 28 - int16x4_t a[8]; - int16x8_t b[8]; - - a[0] = load_tran_low_to_s16d(input); - a[1] = load_tran_low_to_s16d(input + 8); - a[2] = load_tran_low_to_s16d(input + 16); - a[3] = load_tran_low_to_s16d(input + 24); - - idct8x8_12_pass1_bd8(cospis0, cospisd0, cospisd1, a); - idct8x8_12_pass2_bd8(cospis0, cospisd0, cospisd1, a, b); - idct8x8_add8x8_neon(b, dest, stride); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct_neon.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct_neon.asm deleted file mode 100644 index 5dd9bdc7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct_neon.asm +++ /dev/null @@ -1,46 +0,0 @@ -; -; Copyright (c) 2016 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - INCLUDE ./vpx_config.asm - - ; Helper functions used to load tran_low_t into int16, narrowing if - ; necessary. - - ; $dst0..3 are d registers with the pairs assumed to be contiguous in - ; non-high-bitdepth builds. q0-q3 are used as temporaries in high-bitdepth. - MACRO - LOAD_TRAN_LOW_TO_S16 $dst0, $dst1, $dst2, $dst3, $src - IF CONFIG_VP9_HIGHBITDEPTH - vld1.s32 {q0,q1}, [$src]! - vld1.s32 {q2,q3}, [$src]! - vmovn.i32 $dst0, q0 - vmovn.i32 $dst1, q1 - vmovn.i32 $dst2, q2 - vmovn.i32 $dst3, q3 - ELSE - vld1.s16 {$dst0-$dst1,$dst2-$dst3}, [$src]! - ENDIF - MEND - - ; $dst0..3 are d registers. q0-q3 are used as temporaries in high-bitdepth. - MACRO - LOAD_TRAN_LOW_TO_S16X2 $dst0, $dst1, $dst2, $dst3, $src - IF CONFIG_VP9_HIGHBITDEPTH - vld2.s32 {q0,q1}, [$src]! - vld2.s32 {q2,q3}, [$src]! - vmovn.i32 $dst0, q0 - vmovn.i32 $dst1, q2 - vmovn.i32 $dst2, q1 - vmovn.i32 $dst3, q3 - ELSE - vld2.s16 {$dst0,$dst1,$dst2,$dst3}, [$src]! - ENDIF - MEND - END diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct_neon.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct_neon.h deleted file mode 100644 index c0231132..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/idct_neon.h +++ /dev/null @@ -1,919 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_ARM_IDCT_NEON_H_ -#define VPX_VPX_DSP_ARM_IDCT_NEON_H_ - -#include - -#include "./vpx_config.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/txfm_common.h" -#include "vpx_dsp/vpx_dsp_common.h" - -static const int16_t kCospi[16] = { - 16384 /* cospi_0_64 */, 15137 /* cospi_8_64 */, - 11585 /* cospi_16_64 */, 6270 /* cospi_24_64 */, - 16069 /* cospi_4_64 */, 13623 /* cospi_12_64 */, - -9102 /* -cospi_20_64 */, 3196 /* cospi_28_64 */, - 16305 /* cospi_2_64 */, 1606 /* cospi_30_64 */, - 14449 /* cospi_10_64 */, 7723 /* cospi_22_64 */, - 15679 /* cospi_6_64 */, -4756 /* -cospi_26_64 */, - 12665 /* cospi_14_64 */, -10394 /* -cospi_18_64 */ -}; - -static const int32_t kCospi32[16] = { - 16384 /* cospi_0_64 */, 15137 /* cospi_8_64 */, - 11585 /* cospi_16_64 */, 6270 /* cospi_24_64 */, - 16069 /* cospi_4_64 */, 13623 /* cospi_12_64 */, - -9102 /* -cospi_20_64 */, 3196 /* cospi_28_64 */, - 16305 /* cospi_2_64 */, 1606 /* cospi_30_64 */, - 14449 /* cospi_10_64 */, 7723 /* cospi_22_64 */, - 15679 /* cospi_6_64 */, -4756 /* -cospi_26_64 */, - 12665 /* cospi_14_64 */, -10394 /* -cospi_18_64 */ -}; - -//------------------------------------------------------------------------------ -// Use saturating add/sub to avoid overflow in 2nd pass in high bit-depth -static INLINE int16x8_t final_add(const int16x8_t a, const int16x8_t b) { -#if CONFIG_VP9_HIGHBITDEPTH - return vqaddq_s16(a, b); -#else - return vaddq_s16(a, b); -#endif -} - -static INLINE int16x8_t final_sub(const int16x8_t a, const int16x8_t b) { -#if CONFIG_VP9_HIGHBITDEPTH - return vqsubq_s16(a, b); -#else - return vsubq_s16(a, b); -#endif -} - -//------------------------------------------------------------------------------ - -static INLINE int32x4x2_t highbd_idct_add_dual(const int32x4x2_t s0, - const int32x4x2_t s1) { - int32x4x2_t t; - t.val[0] = vaddq_s32(s0.val[0], s1.val[0]); - t.val[1] = vaddq_s32(s0.val[1], s1.val[1]); - return t; -} - -static INLINE int32x4x2_t highbd_idct_sub_dual(const int32x4x2_t s0, - const int32x4x2_t s1) { - int32x4x2_t t; - t.val[0] = vsubq_s32(s0.val[0], s1.val[0]); - t.val[1] = vsubq_s32(s0.val[1], s1.val[1]); - return t; -} - -//------------------------------------------------------------------------------ - -static INLINE int16x8_t dct_const_round_shift_low_8(const int32x4_t *const in) { - return vcombine_s16(vrshrn_n_s32(in[0], DCT_CONST_BITS), - vrshrn_n_s32(in[1], DCT_CONST_BITS)); -} - -static INLINE void dct_const_round_shift_low_8_dual(const int32x4_t *const t32, - int16x8_t *const d0, - int16x8_t *const d1) { - *d0 = dct_const_round_shift_low_8(t32 + 0); - *d1 = dct_const_round_shift_low_8(t32 + 2); -} - -static INLINE int32x4x2_t -dct_const_round_shift_high_4x2(const int64x2_t *const in) { - int32x4x2_t out; - out.val[0] = vcombine_s32(vrshrn_n_s64(in[0], DCT_CONST_BITS), - vrshrn_n_s64(in[1], DCT_CONST_BITS)); - out.val[1] = vcombine_s32(vrshrn_n_s64(in[2], DCT_CONST_BITS), - vrshrn_n_s64(in[3], DCT_CONST_BITS)); - return out; -} - -// Multiply a by a_const. Saturate, shift and narrow by DCT_CONST_BITS. -static INLINE int16x8_t multiply_shift_and_narrow_s16(const int16x8_t a, - const int16_t a_const) { - // Shift by DCT_CONST_BITS + rounding will be within 16 bits for well formed - // streams. See WRAPLOW and dct_const_round_shift for details. - // This instruction doubles the result and returns the high half, essentially - // resulting in a right shift by 15. By multiplying the constant first that - // becomes a right shift by DCT_CONST_BITS. - // The largest possible value used here is - // vpx_dsp/txfm_common.h:cospi_1_64 = 16364 (* 2 = 32728) a which falls *just* - // within the range of int16_t (+32767 / -32768) even when negated. - return vqrdmulhq_n_s16(a, a_const * 2); -} - -// Add a and b, then multiply by ab_const. Shift and narrow by DCT_CONST_BITS. -static INLINE int16x8_t add_multiply_shift_and_narrow_s16( - const int16x8_t a, const int16x8_t b, const int16_t ab_const) { - // In both add_ and it's pair, sub_, the input for well-formed streams will be - // well within 16 bits (input to the idct is the difference between two frames - // and will be within -255 to 255, or 9 bits) - // However, for inputs over about 25,000 (valid for int16_t, but not for idct - // input) this function can not use vaddq_s16. - // In order to match existing behavior and intentionally out of range tests, - // expand the addition up to 32 bits to prevent truncation. - int32x4_t t[2]; - t[0] = vaddl_s16(vget_low_s16(a), vget_low_s16(b)); - t[1] = vaddl_s16(vget_high_s16(a), vget_high_s16(b)); - t[0] = vmulq_n_s32(t[0], ab_const); - t[1] = vmulq_n_s32(t[1], ab_const); - return dct_const_round_shift_low_8(t); -} - -// Subtract b from a, then multiply by ab_const. Shift and narrow by -// DCT_CONST_BITS. -static INLINE int16x8_t sub_multiply_shift_and_narrow_s16( - const int16x8_t a, const int16x8_t b, const int16_t ab_const) { - int32x4_t t[2]; - t[0] = vsubl_s16(vget_low_s16(a), vget_low_s16(b)); - t[1] = vsubl_s16(vget_high_s16(a), vget_high_s16(b)); - t[0] = vmulq_n_s32(t[0], ab_const); - t[1] = vmulq_n_s32(t[1], ab_const); - return dct_const_round_shift_low_8(t); -} - -// Multiply a by a_const and b by b_const, then accumulate. Shift and narrow by -// DCT_CONST_BITS. -static INLINE int16x8_t multiply_accumulate_shift_and_narrow_s16( - const int16x8_t a, const int16_t a_const, const int16x8_t b, - const int16_t b_const) { - int32x4_t t[2]; - t[0] = vmull_n_s16(vget_low_s16(a), a_const); - t[1] = vmull_n_s16(vget_high_s16(a), a_const); - t[0] = vmlal_n_s16(t[0], vget_low_s16(b), b_const); - t[1] = vmlal_n_s16(t[1], vget_high_s16(b), b_const); - return dct_const_round_shift_low_8(t); -} - -//------------------------------------------------------------------------------ - -// Note: The following 4 functions could use 32-bit operations for bit-depth 10. -// However, although it's 20% faster with gcc, it's 20% slower with clang. -// Use 64-bit operations for now. - -// Multiply a by a_const. Saturate, shift and narrow by DCT_CONST_BITS. -static INLINE int32x4x2_t -multiply_shift_and_narrow_s32_dual(const int32x4x2_t a, const int32_t a_const) { - int64x2_t b[4]; - - b[0] = vmull_n_s32(vget_low_s32(a.val[0]), a_const); - b[1] = vmull_n_s32(vget_high_s32(a.val[0]), a_const); - b[2] = vmull_n_s32(vget_low_s32(a.val[1]), a_const); - b[3] = vmull_n_s32(vget_high_s32(a.val[1]), a_const); - return dct_const_round_shift_high_4x2(b); -} - -// Add a and b, then multiply by ab_const. Shift and narrow by DCT_CONST_BITS. -static INLINE int32x4x2_t add_multiply_shift_and_narrow_s32_dual( - const int32x4x2_t a, const int32x4x2_t b, const int32_t ab_const) { - int32x4_t t[2]; - int64x2_t c[4]; - - t[0] = vaddq_s32(a.val[0], b.val[0]); - t[1] = vaddq_s32(a.val[1], b.val[1]); - c[0] = vmull_n_s32(vget_low_s32(t[0]), ab_const); - c[1] = vmull_n_s32(vget_high_s32(t[0]), ab_const); - c[2] = vmull_n_s32(vget_low_s32(t[1]), ab_const); - c[3] = vmull_n_s32(vget_high_s32(t[1]), ab_const); - return dct_const_round_shift_high_4x2(c); -} - -// Subtract b from a, then multiply by ab_const. Shift and narrow by -// DCT_CONST_BITS. -static INLINE int32x4x2_t sub_multiply_shift_and_narrow_s32_dual( - const int32x4x2_t a, const int32x4x2_t b, const int32_t ab_const) { - int32x4_t t[2]; - int64x2_t c[4]; - - t[0] = vsubq_s32(a.val[0], b.val[0]); - t[1] = vsubq_s32(a.val[1], b.val[1]); - c[0] = vmull_n_s32(vget_low_s32(t[0]), ab_const); - c[1] = vmull_n_s32(vget_high_s32(t[0]), ab_const); - c[2] = vmull_n_s32(vget_low_s32(t[1]), ab_const); - c[3] = vmull_n_s32(vget_high_s32(t[1]), ab_const); - return dct_const_round_shift_high_4x2(c); -} - -// Multiply a by a_const and b by b_const, then accumulate. Shift and narrow by -// DCT_CONST_BITS. -static INLINE int32x4x2_t multiply_accumulate_shift_and_narrow_s32_dual( - const int32x4x2_t a, const int32_t a_const, const int32x4x2_t b, - const int32_t b_const) { - int64x2_t c[4]; - c[0] = vmull_n_s32(vget_low_s32(a.val[0]), a_const); - c[1] = vmull_n_s32(vget_high_s32(a.val[0]), a_const); - c[2] = vmull_n_s32(vget_low_s32(a.val[1]), a_const); - c[3] = vmull_n_s32(vget_high_s32(a.val[1]), a_const); - c[0] = vmlal_n_s32(c[0], vget_low_s32(b.val[0]), b_const); - c[1] = vmlal_n_s32(c[1], vget_high_s32(b.val[0]), b_const); - c[2] = vmlal_n_s32(c[2], vget_low_s32(b.val[1]), b_const); - c[3] = vmlal_n_s32(c[3], vget_high_s32(b.val[1]), b_const); - return dct_const_round_shift_high_4x2(c); -} - -// Shift the output down by 6 and add it to the destination buffer. -static INLINE void add_and_store_u8_s16(const int16x8_t *const a, uint8_t *d, - const int stride) { - uint8x8_t b[8]; - int16x8_t c[8]; - - b[0] = vld1_u8(d); - d += stride; - b[1] = vld1_u8(d); - d += stride; - b[2] = vld1_u8(d); - d += stride; - b[3] = vld1_u8(d); - d += stride; - b[4] = vld1_u8(d); - d += stride; - b[5] = vld1_u8(d); - d += stride; - b[6] = vld1_u8(d); - d += stride; - b[7] = vld1_u8(d); - d -= (7 * stride); - - // c = b + (a >> 6) - c[0] = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b[0])), a[0], 6); - c[1] = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b[1])), a[1], 6); - c[2] = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b[2])), a[2], 6); - c[3] = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b[3])), a[3], 6); - c[4] = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b[4])), a[4], 6); - c[5] = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b[5])), a[5], 6); - c[6] = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b[6])), a[6], 6); - c[7] = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b[7])), a[7], 6); - - b[0] = vqmovun_s16(c[0]); - b[1] = vqmovun_s16(c[1]); - b[2] = vqmovun_s16(c[2]); - b[3] = vqmovun_s16(c[3]); - b[4] = vqmovun_s16(c[4]); - b[5] = vqmovun_s16(c[5]); - b[6] = vqmovun_s16(c[6]); - b[7] = vqmovun_s16(c[7]); - - vst1_u8(d, b[0]); - d += stride; - vst1_u8(d, b[1]); - d += stride; - vst1_u8(d, b[2]); - d += stride; - vst1_u8(d, b[3]); - d += stride; - vst1_u8(d, b[4]); - d += stride; - vst1_u8(d, b[5]); - d += stride; - vst1_u8(d, b[6]); - d += stride; - vst1_u8(d, b[7]); -} - -static INLINE uint8x16_t create_dcq(const int16_t dc) { - // Clip both sides and gcc may compile to assembly 'usat'. - const int16_t t = (dc < 0) ? 0 : ((dc > 255) ? 255 : dc); - return vdupq_n_u8((uint8_t)t); -} - -static INLINE void idct4x4_16_kernel_bd8(int16x8_t *const a) { - const int16x4_t cospis = vld1_s16(kCospi); - int16x4_t b[4]; - int32x4_t c[4]; - int16x8_t d[2]; - - b[0] = vget_low_s16(a[0]); - b[1] = vget_high_s16(a[0]); - b[2] = vget_low_s16(a[1]); - b[3] = vget_high_s16(a[1]); - c[0] = vmull_lane_s16(b[0], cospis, 2); - c[2] = vmull_lane_s16(b[1], cospis, 2); - c[1] = vsubq_s32(c[0], c[2]); - c[0] = vaddq_s32(c[0], c[2]); - c[3] = vmull_lane_s16(b[2], cospis, 3); - c[2] = vmull_lane_s16(b[2], cospis, 1); - c[3] = vmlsl_lane_s16(c[3], b[3], cospis, 1); - c[2] = vmlal_lane_s16(c[2], b[3], cospis, 3); - dct_const_round_shift_low_8_dual(c, &d[0], &d[1]); - a[0] = vaddq_s16(d[0], d[1]); - a[1] = vsubq_s16(d[0], d[1]); -} - -static INLINE void transpose_idct4x4_16_bd8(int16x8_t *const a) { - transpose_s16_4x4q(&a[0], &a[1]); - idct4x4_16_kernel_bd8(a); -} - -static INLINE void idct8x8_12_pass1_bd8(const int16x4_t cospis0, - const int16x4_t cospisd0, - const int16x4_t cospisd1, - int16x4_t *const io) { - int16x4_t step1[8], step2[8]; - int32x4_t t32[2]; - - transpose_s16_4x4d(&io[0], &io[1], &io[2], &io[3]); - - // stage 1 - step1[4] = vqrdmulh_lane_s16(io[1], cospisd1, 3); - step1[5] = vqrdmulh_lane_s16(io[3], cospisd1, 2); - step1[6] = vqrdmulh_lane_s16(io[3], cospisd1, 1); - step1[7] = vqrdmulh_lane_s16(io[1], cospisd1, 0); - - // stage 2 - step2[1] = vqrdmulh_lane_s16(io[0], cospisd0, 2); - step2[2] = vqrdmulh_lane_s16(io[2], cospisd0, 3); - step2[3] = vqrdmulh_lane_s16(io[2], cospisd0, 1); - - step2[4] = vadd_s16(step1[4], step1[5]); - step2[5] = vsub_s16(step1[4], step1[5]); - step2[6] = vsub_s16(step1[7], step1[6]); - step2[7] = vadd_s16(step1[7], step1[6]); - - // stage 3 - step1[0] = vadd_s16(step2[1], step2[3]); - step1[1] = vadd_s16(step2[1], step2[2]); - step1[2] = vsub_s16(step2[1], step2[2]); - step1[3] = vsub_s16(step2[1], step2[3]); - - t32[1] = vmull_lane_s16(step2[6], cospis0, 2); - t32[0] = vmlsl_lane_s16(t32[1], step2[5], cospis0, 2); - t32[1] = vmlal_lane_s16(t32[1], step2[5], cospis0, 2); - step1[5] = vrshrn_n_s32(t32[0], DCT_CONST_BITS); - step1[6] = vrshrn_n_s32(t32[1], DCT_CONST_BITS); - - // stage 4 - io[0] = vadd_s16(step1[0], step2[7]); - io[1] = vadd_s16(step1[1], step1[6]); - io[2] = vadd_s16(step1[2], step1[5]); - io[3] = vadd_s16(step1[3], step2[4]); - io[4] = vsub_s16(step1[3], step2[4]); - io[5] = vsub_s16(step1[2], step1[5]); - io[6] = vsub_s16(step1[1], step1[6]); - io[7] = vsub_s16(step1[0], step2[7]); -} - -static INLINE void idct8x8_12_pass2_bd8(const int16x4_t cospis0, - const int16x4_t cospisd0, - const int16x4_t cospisd1, - const int16x4_t *const input, - int16x8_t *const output) { - int16x8_t in[4]; - int16x8_t step1[8], step2[8]; - int32x4_t t32[8]; - - transpose_s16_4x8(input[0], input[1], input[2], input[3], input[4], input[5], - input[6], input[7], &in[0], &in[1], &in[2], &in[3]); - - // stage 1 - step1[4] = vqrdmulhq_lane_s16(in[1], cospisd1, 3); - step1[5] = vqrdmulhq_lane_s16(in[3], cospisd1, 2); - step1[6] = vqrdmulhq_lane_s16(in[3], cospisd1, 1); - step1[7] = vqrdmulhq_lane_s16(in[1], cospisd1, 0); - - // stage 2 - step2[1] = vqrdmulhq_lane_s16(in[0], cospisd0, 2); - step2[2] = vqrdmulhq_lane_s16(in[2], cospisd0, 3); - step2[3] = vqrdmulhq_lane_s16(in[2], cospisd0, 1); - - step2[4] = vaddq_s16(step1[4], step1[5]); - step2[5] = vsubq_s16(step1[4], step1[5]); - step2[6] = vsubq_s16(step1[7], step1[6]); - step2[7] = vaddq_s16(step1[7], step1[6]); - - // stage 3 - step1[0] = vaddq_s16(step2[1], step2[3]); - step1[1] = vaddq_s16(step2[1], step2[2]); - step1[2] = vsubq_s16(step2[1], step2[2]); - step1[3] = vsubq_s16(step2[1], step2[3]); - - t32[2] = vmull_lane_s16(vget_low_s16(step2[6]), cospis0, 2); - t32[3] = vmull_lane_s16(vget_high_s16(step2[6]), cospis0, 2); - t32[0] = vmlsl_lane_s16(t32[2], vget_low_s16(step2[5]), cospis0, 2); - t32[1] = vmlsl_lane_s16(t32[3], vget_high_s16(step2[5]), cospis0, 2); - t32[2] = vmlal_lane_s16(t32[2], vget_low_s16(step2[5]), cospis0, 2); - t32[3] = vmlal_lane_s16(t32[3], vget_high_s16(step2[5]), cospis0, 2); - dct_const_round_shift_low_8_dual(t32, &step1[5], &step1[6]); - - // stage 4 - output[0] = vaddq_s16(step1[0], step2[7]); - output[1] = vaddq_s16(step1[1], step1[6]); - output[2] = vaddq_s16(step1[2], step1[5]); - output[3] = vaddq_s16(step1[3], step2[4]); - output[4] = vsubq_s16(step1[3], step2[4]); - output[5] = vsubq_s16(step1[2], step1[5]); - output[6] = vsubq_s16(step1[1], step1[6]); - output[7] = vsubq_s16(step1[0], step2[7]); -} - -static INLINE void idct8x8_64_1d_bd8_kernel(const int16x4_t cospis0, - const int16x4_t cospis1, - int16x8_t *const io) { - int16x4_t input1l, input1h, input3l, input3h, input5l, input5h, input7l, - input7h; - int16x4_t step1l[4], step1h[4]; - int16x8_t step1[8], step2[8]; - int32x4_t t32[8]; - - // stage 1 - input1l = vget_low_s16(io[1]); - input1h = vget_high_s16(io[1]); - input3l = vget_low_s16(io[3]); - input3h = vget_high_s16(io[3]); - input5l = vget_low_s16(io[5]); - input5h = vget_high_s16(io[5]); - input7l = vget_low_s16(io[7]); - input7h = vget_high_s16(io[7]); - step1l[0] = vget_low_s16(io[0]); - step1h[0] = vget_high_s16(io[0]); - step1l[1] = vget_low_s16(io[2]); - step1h[1] = vget_high_s16(io[2]); - step1l[2] = vget_low_s16(io[4]); - step1h[2] = vget_high_s16(io[4]); - step1l[3] = vget_low_s16(io[6]); - step1h[3] = vget_high_s16(io[6]); - - t32[0] = vmull_lane_s16(input1l, cospis1, 3); - t32[1] = vmull_lane_s16(input1h, cospis1, 3); - t32[2] = vmull_lane_s16(input3l, cospis1, 2); - t32[3] = vmull_lane_s16(input3h, cospis1, 2); - t32[4] = vmull_lane_s16(input3l, cospis1, 1); - t32[5] = vmull_lane_s16(input3h, cospis1, 1); - t32[6] = vmull_lane_s16(input1l, cospis1, 0); - t32[7] = vmull_lane_s16(input1h, cospis1, 0); - t32[0] = vmlsl_lane_s16(t32[0], input7l, cospis1, 0); - t32[1] = vmlsl_lane_s16(t32[1], input7h, cospis1, 0); - t32[2] = vmlal_lane_s16(t32[2], input5l, cospis1, 1); - t32[3] = vmlal_lane_s16(t32[3], input5h, cospis1, 1); - t32[4] = vmlsl_lane_s16(t32[4], input5l, cospis1, 2); - t32[5] = vmlsl_lane_s16(t32[5], input5h, cospis1, 2); - t32[6] = vmlal_lane_s16(t32[6], input7l, cospis1, 3); - t32[7] = vmlal_lane_s16(t32[7], input7h, cospis1, 3); - dct_const_round_shift_low_8_dual(&t32[0], &step1[4], &step1[5]); - dct_const_round_shift_low_8_dual(&t32[4], &step1[6], &step1[7]); - - // stage 2 - t32[2] = vmull_lane_s16(step1l[0], cospis0, 2); - t32[3] = vmull_lane_s16(step1h[0], cospis0, 2); - t32[4] = vmull_lane_s16(step1l[1], cospis0, 3); - t32[5] = vmull_lane_s16(step1h[1], cospis0, 3); - t32[6] = vmull_lane_s16(step1l[1], cospis0, 1); - t32[7] = vmull_lane_s16(step1h[1], cospis0, 1); - t32[0] = vmlal_lane_s16(t32[2], step1l[2], cospis0, 2); - t32[1] = vmlal_lane_s16(t32[3], step1h[2], cospis0, 2); - t32[2] = vmlsl_lane_s16(t32[2], step1l[2], cospis0, 2); - t32[3] = vmlsl_lane_s16(t32[3], step1h[2], cospis0, 2); - t32[4] = vmlsl_lane_s16(t32[4], step1l[3], cospis0, 1); - t32[5] = vmlsl_lane_s16(t32[5], step1h[3], cospis0, 1); - t32[6] = vmlal_lane_s16(t32[6], step1l[3], cospis0, 3); - t32[7] = vmlal_lane_s16(t32[7], step1h[3], cospis0, 3); - dct_const_round_shift_low_8_dual(&t32[0], &step2[0], &step2[1]); - dct_const_round_shift_low_8_dual(&t32[4], &step2[2], &step2[3]); - - step2[4] = vaddq_s16(step1[4], step1[5]); - step2[5] = vsubq_s16(step1[4], step1[5]); - step2[6] = vsubq_s16(step1[7], step1[6]); - step2[7] = vaddq_s16(step1[7], step1[6]); - - // stage 3 - step1[0] = vaddq_s16(step2[0], step2[3]); - step1[1] = vaddq_s16(step2[1], step2[2]); - step1[2] = vsubq_s16(step2[1], step2[2]); - step1[3] = vsubq_s16(step2[0], step2[3]); - - t32[2] = vmull_lane_s16(vget_low_s16(step2[6]), cospis0, 2); - t32[3] = vmull_lane_s16(vget_high_s16(step2[6]), cospis0, 2); - t32[0] = vmlsl_lane_s16(t32[2], vget_low_s16(step2[5]), cospis0, 2); - t32[1] = vmlsl_lane_s16(t32[3], vget_high_s16(step2[5]), cospis0, 2); - t32[2] = vmlal_lane_s16(t32[2], vget_low_s16(step2[5]), cospis0, 2); - t32[3] = vmlal_lane_s16(t32[3], vget_high_s16(step2[5]), cospis0, 2); - dct_const_round_shift_low_8_dual(t32, &step1[5], &step1[6]); - - // stage 4 - io[0] = vaddq_s16(step1[0], step2[7]); - io[1] = vaddq_s16(step1[1], step1[6]); - io[2] = vaddq_s16(step1[2], step1[5]); - io[3] = vaddq_s16(step1[3], step2[4]); - io[4] = vsubq_s16(step1[3], step2[4]); - io[5] = vsubq_s16(step1[2], step1[5]); - io[6] = vsubq_s16(step1[1], step1[6]); - io[7] = vsubq_s16(step1[0], step2[7]); -} - -static INLINE void idct8x8_64_1d_bd8(const int16x4_t cospis0, - const int16x4_t cospis1, - int16x8_t *const io) { - transpose_s16_8x8(&io[0], &io[1], &io[2], &io[3], &io[4], &io[5], &io[6], - &io[7]); - idct8x8_64_1d_bd8_kernel(cospis0, cospis1, io); -} - -static INLINE void idct_cospi_8_24_q_kernel(const int16x8_t s0, - const int16x8_t s1, - const int16x4_t cospi_0_8_16_24, - int32x4_t *const t32) { - t32[0] = vmull_lane_s16(vget_low_s16(s0), cospi_0_8_16_24, 3); - t32[1] = vmull_lane_s16(vget_high_s16(s0), cospi_0_8_16_24, 3); - t32[2] = vmull_lane_s16(vget_low_s16(s1), cospi_0_8_16_24, 3); - t32[3] = vmull_lane_s16(vget_high_s16(s1), cospi_0_8_16_24, 3); - t32[0] = vmlsl_lane_s16(t32[0], vget_low_s16(s1), cospi_0_8_16_24, 1); - t32[1] = vmlsl_lane_s16(t32[1], vget_high_s16(s1), cospi_0_8_16_24, 1); - t32[2] = vmlal_lane_s16(t32[2], vget_low_s16(s0), cospi_0_8_16_24, 1); - t32[3] = vmlal_lane_s16(t32[3], vget_high_s16(s0), cospi_0_8_16_24, 1); -} - -static INLINE void idct_cospi_8_24_q(const int16x8_t s0, const int16x8_t s1, - const int16x4_t cospi_0_8_16_24, - int16x8_t *const d0, int16x8_t *const d1) { - int32x4_t t32[4]; - - idct_cospi_8_24_q_kernel(s0, s1, cospi_0_8_16_24, t32); - dct_const_round_shift_low_8_dual(t32, d0, d1); -} - -static INLINE void idct_cospi_8_24_neg_q(const int16x8_t s0, const int16x8_t s1, - const int16x4_t cospi_0_8_16_24, - int16x8_t *const d0, - int16x8_t *const d1) { - int32x4_t t32[4]; - - idct_cospi_8_24_q_kernel(s0, s1, cospi_0_8_16_24, t32); - t32[2] = vnegq_s32(t32[2]); - t32[3] = vnegq_s32(t32[3]); - dct_const_round_shift_low_8_dual(t32, d0, d1); -} - -static INLINE void idct_cospi_16_16_q(const int16x8_t s0, const int16x8_t s1, - const int16x4_t cospi_0_8_16_24, - int16x8_t *const d0, - int16x8_t *const d1) { - int32x4_t t32[6]; - - t32[4] = vmull_lane_s16(vget_low_s16(s1), cospi_0_8_16_24, 2); - t32[5] = vmull_lane_s16(vget_high_s16(s1), cospi_0_8_16_24, 2); - t32[0] = vmlsl_lane_s16(t32[4], vget_low_s16(s0), cospi_0_8_16_24, 2); - t32[1] = vmlsl_lane_s16(t32[5], vget_high_s16(s0), cospi_0_8_16_24, 2); - t32[2] = vmlal_lane_s16(t32[4], vget_low_s16(s0), cospi_0_8_16_24, 2); - t32[3] = vmlal_lane_s16(t32[5], vget_high_s16(s0), cospi_0_8_16_24, 2); - dct_const_round_shift_low_8_dual(t32, d0, d1); -} - -static INLINE void idct_cospi_2_30(const int16x8_t s0, const int16x8_t s1, - const int16x4_t cospi_2_30_10_22, - int16x8_t *const d0, int16x8_t *const d1) { - int32x4_t t32[4]; - - t32[0] = vmull_lane_s16(vget_low_s16(s0), cospi_2_30_10_22, 1); - t32[1] = vmull_lane_s16(vget_high_s16(s0), cospi_2_30_10_22, 1); - t32[2] = vmull_lane_s16(vget_low_s16(s1), cospi_2_30_10_22, 1); - t32[3] = vmull_lane_s16(vget_high_s16(s1), cospi_2_30_10_22, 1); - t32[0] = vmlsl_lane_s16(t32[0], vget_low_s16(s1), cospi_2_30_10_22, 0); - t32[1] = vmlsl_lane_s16(t32[1], vget_high_s16(s1), cospi_2_30_10_22, 0); - t32[2] = vmlal_lane_s16(t32[2], vget_low_s16(s0), cospi_2_30_10_22, 0); - t32[3] = vmlal_lane_s16(t32[3], vget_high_s16(s0), cospi_2_30_10_22, 0); - dct_const_round_shift_low_8_dual(t32, d0, d1); -} - -static INLINE void idct_cospi_4_28(const int16x8_t s0, const int16x8_t s1, - const int16x4_t cospi_4_12_20N_28, - int16x8_t *const d0, int16x8_t *const d1) { - int32x4_t t32[4]; - - t32[0] = vmull_lane_s16(vget_low_s16(s0), cospi_4_12_20N_28, 3); - t32[1] = vmull_lane_s16(vget_high_s16(s0), cospi_4_12_20N_28, 3); - t32[2] = vmull_lane_s16(vget_low_s16(s1), cospi_4_12_20N_28, 3); - t32[3] = vmull_lane_s16(vget_high_s16(s1), cospi_4_12_20N_28, 3); - t32[0] = vmlsl_lane_s16(t32[0], vget_low_s16(s1), cospi_4_12_20N_28, 0); - t32[1] = vmlsl_lane_s16(t32[1], vget_high_s16(s1), cospi_4_12_20N_28, 0); - t32[2] = vmlal_lane_s16(t32[2], vget_low_s16(s0), cospi_4_12_20N_28, 0); - t32[3] = vmlal_lane_s16(t32[3], vget_high_s16(s0), cospi_4_12_20N_28, 0); - dct_const_round_shift_low_8_dual(t32, d0, d1); -} - -static INLINE void idct_cospi_6_26(const int16x8_t s0, const int16x8_t s1, - const int16x4_t cospi_6_26N_14_18N, - int16x8_t *const d0, int16x8_t *const d1) { - int32x4_t t32[4]; - - t32[0] = vmull_lane_s16(vget_low_s16(s0), cospi_6_26N_14_18N, 0); - t32[1] = vmull_lane_s16(vget_high_s16(s0), cospi_6_26N_14_18N, 0); - t32[2] = vmull_lane_s16(vget_low_s16(s1), cospi_6_26N_14_18N, 0); - t32[3] = vmull_lane_s16(vget_high_s16(s1), cospi_6_26N_14_18N, 0); - t32[0] = vmlal_lane_s16(t32[0], vget_low_s16(s1), cospi_6_26N_14_18N, 1); - t32[1] = vmlal_lane_s16(t32[1], vget_high_s16(s1), cospi_6_26N_14_18N, 1); - t32[2] = vmlsl_lane_s16(t32[2], vget_low_s16(s0), cospi_6_26N_14_18N, 1); - t32[3] = vmlsl_lane_s16(t32[3], vget_high_s16(s0), cospi_6_26N_14_18N, 1); - dct_const_round_shift_low_8_dual(t32, d0, d1); -} - -static INLINE void idct_cospi_10_22(const int16x8_t s0, const int16x8_t s1, - const int16x4_t cospi_2_30_10_22, - int16x8_t *const d0, int16x8_t *const d1) { - int32x4_t t32[4]; - - t32[0] = vmull_lane_s16(vget_low_s16(s0), cospi_2_30_10_22, 3); - t32[1] = vmull_lane_s16(vget_high_s16(s0), cospi_2_30_10_22, 3); - t32[2] = vmull_lane_s16(vget_low_s16(s1), cospi_2_30_10_22, 3); - t32[3] = vmull_lane_s16(vget_high_s16(s1), cospi_2_30_10_22, 3); - t32[0] = vmlsl_lane_s16(t32[0], vget_low_s16(s1), cospi_2_30_10_22, 2); - t32[1] = vmlsl_lane_s16(t32[1], vget_high_s16(s1), cospi_2_30_10_22, 2); - t32[2] = vmlal_lane_s16(t32[2], vget_low_s16(s0), cospi_2_30_10_22, 2); - t32[3] = vmlal_lane_s16(t32[3], vget_high_s16(s0), cospi_2_30_10_22, 2); - dct_const_round_shift_low_8_dual(t32, d0, d1); -} - -static INLINE void idct_cospi_12_20(const int16x8_t s0, const int16x8_t s1, - const int16x4_t cospi_4_12_20N_28, - int16x8_t *const d0, int16x8_t *const d1) { - int32x4_t t32[4]; - - t32[0] = vmull_lane_s16(vget_low_s16(s0), cospi_4_12_20N_28, 1); - t32[1] = vmull_lane_s16(vget_high_s16(s0), cospi_4_12_20N_28, 1); - t32[2] = vmull_lane_s16(vget_low_s16(s1), cospi_4_12_20N_28, 1); - t32[3] = vmull_lane_s16(vget_high_s16(s1), cospi_4_12_20N_28, 1); - t32[0] = vmlal_lane_s16(t32[0], vget_low_s16(s1), cospi_4_12_20N_28, 2); - t32[1] = vmlal_lane_s16(t32[1], vget_high_s16(s1), cospi_4_12_20N_28, 2); - t32[2] = vmlsl_lane_s16(t32[2], vget_low_s16(s0), cospi_4_12_20N_28, 2); - t32[3] = vmlsl_lane_s16(t32[3], vget_high_s16(s0), cospi_4_12_20N_28, 2); - dct_const_round_shift_low_8_dual(t32, d0, d1); -} - -static INLINE void idct_cospi_14_18(const int16x8_t s0, const int16x8_t s1, - const int16x4_t cospi_6_26N_14_18N, - int16x8_t *const d0, int16x8_t *const d1) { - int32x4_t t32[4]; - - t32[0] = vmull_lane_s16(vget_low_s16(s0), cospi_6_26N_14_18N, 2); - t32[1] = vmull_lane_s16(vget_high_s16(s0), cospi_6_26N_14_18N, 2); - t32[2] = vmull_lane_s16(vget_low_s16(s1), cospi_6_26N_14_18N, 2); - t32[3] = vmull_lane_s16(vget_high_s16(s1), cospi_6_26N_14_18N, 2); - t32[0] = vmlal_lane_s16(t32[0], vget_low_s16(s1), cospi_6_26N_14_18N, 3); - t32[1] = vmlal_lane_s16(t32[1], vget_high_s16(s1), cospi_6_26N_14_18N, 3); - t32[2] = vmlsl_lane_s16(t32[2], vget_low_s16(s0), cospi_6_26N_14_18N, 3); - t32[3] = vmlsl_lane_s16(t32[3], vget_high_s16(s0), cospi_6_26N_14_18N, 3); - dct_const_round_shift_low_8_dual(t32, d0, d1); -} - -static INLINE void idct16x16_add_stage7(const int16x8_t *const step2, - int16x8_t *const out) { -#if CONFIG_VP9_HIGHBITDEPTH - // Use saturating add/sub to avoid overflow in 2nd pass - out[0] = vqaddq_s16(step2[0], step2[15]); - out[1] = vqaddq_s16(step2[1], step2[14]); - out[2] = vqaddq_s16(step2[2], step2[13]); - out[3] = vqaddq_s16(step2[3], step2[12]); - out[4] = vqaddq_s16(step2[4], step2[11]); - out[5] = vqaddq_s16(step2[5], step2[10]); - out[6] = vqaddq_s16(step2[6], step2[9]); - out[7] = vqaddq_s16(step2[7], step2[8]); - out[8] = vqsubq_s16(step2[7], step2[8]); - out[9] = vqsubq_s16(step2[6], step2[9]); - out[10] = vqsubq_s16(step2[5], step2[10]); - out[11] = vqsubq_s16(step2[4], step2[11]); - out[12] = vqsubq_s16(step2[3], step2[12]); - out[13] = vqsubq_s16(step2[2], step2[13]); - out[14] = vqsubq_s16(step2[1], step2[14]); - out[15] = vqsubq_s16(step2[0], step2[15]); -#else - out[0] = vaddq_s16(step2[0], step2[15]); - out[1] = vaddq_s16(step2[1], step2[14]); - out[2] = vaddq_s16(step2[2], step2[13]); - out[3] = vaddq_s16(step2[3], step2[12]); - out[4] = vaddq_s16(step2[4], step2[11]); - out[5] = vaddq_s16(step2[5], step2[10]); - out[6] = vaddq_s16(step2[6], step2[9]); - out[7] = vaddq_s16(step2[7], step2[8]); - out[8] = vsubq_s16(step2[7], step2[8]); - out[9] = vsubq_s16(step2[6], step2[9]); - out[10] = vsubq_s16(step2[5], step2[10]); - out[11] = vsubq_s16(step2[4], step2[11]); - out[12] = vsubq_s16(step2[3], step2[12]); - out[13] = vsubq_s16(step2[2], step2[13]); - out[14] = vsubq_s16(step2[1], step2[14]); - out[15] = vsubq_s16(step2[0], step2[15]); -#endif -} - -static INLINE void idct16x16_store_pass1(const int16x8_t *const out, - int16_t *output) { - // Save the result into output - vst1q_s16(output, out[0]); - output += 16; - vst1q_s16(output, out[1]); - output += 16; - vst1q_s16(output, out[2]); - output += 16; - vst1q_s16(output, out[3]); - output += 16; - vst1q_s16(output, out[4]); - output += 16; - vst1q_s16(output, out[5]); - output += 16; - vst1q_s16(output, out[6]); - output += 16; - vst1q_s16(output, out[7]); - output += 16; - vst1q_s16(output, out[8]); - output += 16; - vst1q_s16(output, out[9]); - output += 16; - vst1q_s16(output, out[10]); - output += 16; - vst1q_s16(output, out[11]); - output += 16; - vst1q_s16(output, out[12]); - output += 16; - vst1q_s16(output, out[13]); - output += 16; - vst1q_s16(output, out[14]); - output += 16; - vst1q_s16(output, out[15]); -} - -static INLINE void idct8x8_add8x1(const int16x8_t a, uint8_t **const dest, - const int stride) { - const uint8x8_t s = vld1_u8(*dest); - const int16x8_t res = vrshrq_n_s16(a, 5); - const uint16x8_t q = vaddw_u8(vreinterpretq_u16_s16(res), s); - const uint8x8_t d = vqmovun_s16(vreinterpretq_s16_u16(q)); - vst1_u8(*dest, d); - *dest += stride; -} - -static INLINE void idct8x8_add8x8_neon(int16x8_t *const out, uint8_t *dest, - const int stride) { - idct8x8_add8x1(out[0], &dest, stride); - idct8x8_add8x1(out[1], &dest, stride); - idct8x8_add8x1(out[2], &dest, stride); - idct8x8_add8x1(out[3], &dest, stride); - idct8x8_add8x1(out[4], &dest, stride); - idct8x8_add8x1(out[5], &dest, stride); - idct8x8_add8x1(out[6], &dest, stride); - idct8x8_add8x1(out[7], &dest, stride); -} - -static INLINE void idct16x16_add8x1(const int16x8_t a, uint8_t **const dest, - const int stride) { - const uint8x8_t s = vld1_u8(*dest); - const int16x8_t res = vrshrq_n_s16(a, 6); - const uint16x8_t q = vaddw_u8(vreinterpretq_u16_s16(res), s); - const uint8x8_t d = vqmovun_s16(vreinterpretq_s16_u16(q)); - vst1_u8(*dest, d); - *dest += stride; -} - -static INLINE void idct16x16_add_store(const int16x8_t *const out, - uint8_t *dest, const int stride) { - // Add the result to dest - idct16x16_add8x1(out[0], &dest, stride); - idct16x16_add8x1(out[1], &dest, stride); - idct16x16_add8x1(out[2], &dest, stride); - idct16x16_add8x1(out[3], &dest, stride); - idct16x16_add8x1(out[4], &dest, stride); - idct16x16_add8x1(out[5], &dest, stride); - idct16x16_add8x1(out[6], &dest, stride); - idct16x16_add8x1(out[7], &dest, stride); - idct16x16_add8x1(out[8], &dest, stride); - idct16x16_add8x1(out[9], &dest, stride); - idct16x16_add8x1(out[10], &dest, stride); - idct16x16_add8x1(out[11], &dest, stride); - idct16x16_add8x1(out[12], &dest, stride); - idct16x16_add8x1(out[13], &dest, stride); - idct16x16_add8x1(out[14], &dest, stride); - idct16x16_add8x1(out[15], &dest, stride); -} - -static INLINE void highbd_idct16x16_add8x1(const int16x8_t a, - const int16x8_t max, - uint16_t **const dest, - const int stride) { - const uint16x8_t s = vld1q_u16(*dest); - const int16x8_t res0 = vqaddq_s16(a, vreinterpretq_s16_u16(s)); - const int16x8_t res1 = vminq_s16(res0, max); - const uint16x8_t d = vqshluq_n_s16(res1, 0); - vst1q_u16(*dest, d); - *dest += stride; -} - -static INLINE void idct16x16_add_store_bd8(int16x8_t *const out, uint16_t *dest, - const int stride) { - // Add the result to dest - const int16x8_t max = vdupq_n_s16((1 << 8) - 1); - out[0] = vrshrq_n_s16(out[0], 6); - out[1] = vrshrq_n_s16(out[1], 6); - out[2] = vrshrq_n_s16(out[2], 6); - out[3] = vrshrq_n_s16(out[3], 6); - out[4] = vrshrq_n_s16(out[4], 6); - out[5] = vrshrq_n_s16(out[5], 6); - out[6] = vrshrq_n_s16(out[6], 6); - out[7] = vrshrq_n_s16(out[7], 6); - out[8] = vrshrq_n_s16(out[8], 6); - out[9] = vrshrq_n_s16(out[9], 6); - out[10] = vrshrq_n_s16(out[10], 6); - out[11] = vrshrq_n_s16(out[11], 6); - out[12] = vrshrq_n_s16(out[12], 6); - out[13] = vrshrq_n_s16(out[13], 6); - out[14] = vrshrq_n_s16(out[14], 6); - out[15] = vrshrq_n_s16(out[15], 6); - highbd_idct16x16_add8x1(out[0], max, &dest, stride); - highbd_idct16x16_add8x1(out[1], max, &dest, stride); - highbd_idct16x16_add8x1(out[2], max, &dest, stride); - highbd_idct16x16_add8x1(out[3], max, &dest, stride); - highbd_idct16x16_add8x1(out[4], max, &dest, stride); - highbd_idct16x16_add8x1(out[5], max, &dest, stride); - highbd_idct16x16_add8x1(out[6], max, &dest, stride); - highbd_idct16x16_add8x1(out[7], max, &dest, stride); - highbd_idct16x16_add8x1(out[8], max, &dest, stride); - highbd_idct16x16_add8x1(out[9], max, &dest, stride); - highbd_idct16x16_add8x1(out[10], max, &dest, stride); - highbd_idct16x16_add8x1(out[11], max, &dest, stride); - highbd_idct16x16_add8x1(out[12], max, &dest, stride); - highbd_idct16x16_add8x1(out[13], max, &dest, stride); - highbd_idct16x16_add8x1(out[14], max, &dest, stride); - highbd_idct16x16_add8x1(out[15], max, &dest, stride); -} - -static INLINE void highbd_idct16x16_add8x1_bd8(const int16x8_t a, - uint16_t **const dest, - const int stride) { - const uint16x8_t s = vld1q_u16(*dest); - const int16x8_t res = vrsraq_n_s16(vreinterpretq_s16_u16(s), a, 6); - const uint16x8_t d = vmovl_u8(vqmovun_s16(res)); - vst1q_u16(*dest, d); - *dest += stride; -} - -static INLINE void highbd_add_and_store_bd8(const int16x8_t *const a, - uint16_t *out, const int stride) { - highbd_idct16x16_add8x1_bd8(a[0], &out, stride); - highbd_idct16x16_add8x1_bd8(a[1], &out, stride); - highbd_idct16x16_add8x1_bd8(a[2], &out, stride); - highbd_idct16x16_add8x1_bd8(a[3], &out, stride); - highbd_idct16x16_add8x1_bd8(a[4], &out, stride); - highbd_idct16x16_add8x1_bd8(a[5], &out, stride); - highbd_idct16x16_add8x1_bd8(a[6], &out, stride); - highbd_idct16x16_add8x1_bd8(a[7], &out, stride); - highbd_idct16x16_add8x1_bd8(a[8], &out, stride); - highbd_idct16x16_add8x1_bd8(a[9], &out, stride); - highbd_idct16x16_add8x1_bd8(a[10], &out, stride); - highbd_idct16x16_add8x1_bd8(a[11], &out, stride); - highbd_idct16x16_add8x1_bd8(a[12], &out, stride); - highbd_idct16x16_add8x1_bd8(a[13], &out, stride); - highbd_idct16x16_add8x1_bd8(a[14], &out, stride); - highbd_idct16x16_add8x1_bd8(a[15], &out, stride); - highbd_idct16x16_add8x1_bd8(a[16], &out, stride); - highbd_idct16x16_add8x1_bd8(a[17], &out, stride); - highbd_idct16x16_add8x1_bd8(a[18], &out, stride); - highbd_idct16x16_add8x1_bd8(a[19], &out, stride); - highbd_idct16x16_add8x1_bd8(a[20], &out, stride); - highbd_idct16x16_add8x1_bd8(a[21], &out, stride); - highbd_idct16x16_add8x1_bd8(a[22], &out, stride); - highbd_idct16x16_add8x1_bd8(a[23], &out, stride); - highbd_idct16x16_add8x1_bd8(a[24], &out, stride); - highbd_idct16x16_add8x1_bd8(a[25], &out, stride); - highbd_idct16x16_add8x1_bd8(a[26], &out, stride); - highbd_idct16x16_add8x1_bd8(a[27], &out, stride); - highbd_idct16x16_add8x1_bd8(a[28], &out, stride); - highbd_idct16x16_add8x1_bd8(a[29], &out, stride); - highbd_idct16x16_add8x1_bd8(a[30], &out, stride); - highbd_idct16x16_add8x1_bd8(a[31], &out, stride); -} - -void vpx_idct16x16_256_add_half1d(const void *const input, int16_t *output, - void *const dest, const int stride, - const int highbd_flag); - -void vpx_idct16x16_38_add_half1d(const void *const input, int16_t *const output, - void *const dest, const int stride, - const int highbd_flag); - -void vpx_idct16x16_10_add_half1d_pass1(const tran_low_t *input, - int16_t *output); - -void vpx_idct16x16_10_add_half1d_pass2(const int16_t *input, - int16_t *const output, void *const dest, - const int stride, const int highbd_flag); - -void vpx_idct32_32_neon(const tran_low_t *input, uint8_t *dest, - const int stride, const int highbd_flag); - -void vpx_idct32_12_neon(const tran_low_t *const input, int16_t *output); -void vpx_idct32_16_neon(const int16_t *const input, void *const output, - const int stride, const int highbd_flag); - -void vpx_idct32_6_neon(const tran_low_t *input, int16_t *output); -void vpx_idct32_8_neon(const int16_t *input, void *const output, int stride, - const int highbd_flag); - -#endif // VPX_VPX_DSP_ARM_IDCT_NEON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/intrapred_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/intrapred_neon.c deleted file mode 100644 index 4f909e49..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/intrapred_neon.c +++ /dev/null @@ -1,1942 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "mem_neon.h" -#include "sum_neon.h" -#include "vpx/vpx_integer.h" - -//------------------------------------------------------------------------------ -// DC 4x4 - -static INLINE uint16_t dc_sum_4(const uint8_t *ref) { - return horizontal_add_uint8x4(load_unaligned_u8_4x1(ref)); -} - -static INLINE void dc_store_4x4(uint8_t *dst, ptrdiff_t stride, - const uint8x8_t dc) { - int i; - for (i = 0; i < 4; ++i, dst += stride) { - vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(dc), 0); - } -} - -void vpx_dc_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x8_t a = load_unaligned_u8_4x1(above); - const uint8x8_t l = load_unaligned_u8_4x1(left); - const uint16x4_t al = vget_low_u16(vaddl_u8(a, l)); - const uint16_t sum = horizontal_add_uint16x4(al); - const uint8x8_t dc = vrshrn_n_u16(vdupq_n_u16(sum), 3); - dc_store_4x4(dst, stride, dc); -} - -void vpx_dc_left_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint16_t sum = dc_sum_4(left); - const uint8x8_t dc = vrshrn_n_u16(vdupq_n_u16(sum), 2); - (void)above; - dc_store_4x4(dst, stride, dc); -} - -void vpx_dc_top_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint16_t sum = dc_sum_4(above); - const uint8x8_t dc = vrshrn_n_u16(vdupq_n_u16(sum), 2); - (void)left; - dc_store_4x4(dst, stride, dc); -} - -void vpx_dc_128_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x8_t dc = vdup_n_u8(0x80); - (void)above; - (void)left; - dc_store_4x4(dst, stride, dc); -} - -//------------------------------------------------------------------------------ -// DC 8x8 - -static INLINE uint16_t dc_sum_8(const uint8_t *ref) { - return horizontal_add_uint8x8(vld1_u8(ref)); -} - -static INLINE void dc_store_8x8(uint8_t *dst, ptrdiff_t stride, - const uint8x8_t dc) { - int i; - for (i = 0; i < 8; ++i, dst += stride) { - vst1_u8(dst, dc); - } -} - -void vpx_dc_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x8_t above_u8 = vld1_u8(above); - const uint8x8_t left_u8 = vld1_u8(left); - const uint16x8_t al = vaddl_u8(above_u8, left_u8); - const uint16_t sum = horizontal_add_uint16x8(al); - const uint8x8_t dc = vrshrn_n_u16(vdupq_n_u16(sum), 4); - dc_store_8x8(dst, stride, dc); -} - -void vpx_dc_left_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint16_t sum = dc_sum_8(left); - const uint8x8_t dc = vrshrn_n_u16(vdupq_n_u16(sum), 3); - (void)above; - dc_store_8x8(dst, stride, dc); -} - -void vpx_dc_top_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint16_t sum = dc_sum_8(above); - const uint8x8_t dc = vrshrn_n_u16(vdupq_n_u16(sum), 3); - (void)left; - dc_store_8x8(dst, stride, dc); -} - -void vpx_dc_128_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x8_t dc = vdup_n_u8(0x80); - (void)above; - (void)left; - dc_store_8x8(dst, stride, dc); -} - -//------------------------------------------------------------------------------ -// DC 16x16 - -static INLINE uint16_t dc_sum_16(const uint8_t *ref) { - return horizontal_add_uint8x16(vld1q_u8(ref)); -} - -static INLINE void dc_store_16x16(uint8_t *dst, ptrdiff_t stride, - const uint8x16_t dc) { - int i; - for (i = 0; i < 16; ++i, dst += stride) { - vst1q_u8(dst + 0, dc); - } -} - -void vpx_dc_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t ref0 = vld1q_u8(above); - const uint8x16_t ref1 = vld1q_u8(left); - const uint16x8_t a = vpaddlq_u8(ref0); - const uint16x8_t l = vpaddlq_u8(ref1); - const uint16x8_t al = vaddq_u16(a, l); - const uint16_t sum = horizontal_add_uint16x8(al); - const uint8x16_t dc = vdupq_lane_u8(vrshrn_n_u16(vdupq_n_u16(sum), 5), 0); - dc_store_16x16(dst, stride, dc); -} - -void vpx_dc_left_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, - const uint8_t *left) { - const uint16_t sum = dc_sum_16(left); - const uint8x16_t dc = vdupq_lane_u8(vrshrn_n_u16(vdupq_n_u16(sum), 4), 0); - (void)above; - dc_store_16x16(dst, stride, dc); -} - -void vpx_dc_top_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, - const uint8_t *left) { - const uint16_t sum = dc_sum_16(above); - const uint8x16_t dc = vdupq_lane_u8(vrshrn_n_u16(vdupq_n_u16(sum), 4), 0); - (void)left; - dc_store_16x16(dst, stride, dc); -} - -void vpx_dc_128_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, - const uint8_t *left) { - const uint8x16_t dc = vdupq_n_u8(0x80); - (void)above; - (void)left; - dc_store_16x16(dst, stride, dc); -} - -//------------------------------------------------------------------------------ -// DC 32x32 - -static INLINE uint16_t dc_sum_32(const uint8_t *ref) { - const uint8x16_t r0 = vld1q_u8(ref + 0); - const uint8x16_t r1 = vld1q_u8(ref + 16); - const uint16x8_t r01 = vaddq_u16(vpaddlq_u8(r0), vpaddlq_u8(r1)); - return horizontal_add_uint16x8(r01); -} - -static INLINE void dc_store_32x32(uint8_t *dst, ptrdiff_t stride, - const uint8x16_t dc) { - int i; - for (i = 0; i < 32; ++i, dst += stride) { - vst1q_u8(dst + 0, dc); - vst1q_u8(dst + 16, dc); - } -} - -void vpx_dc_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t a0 = vld1q_u8(above + 0); - const uint8x16_t a1 = vld1q_u8(above + 16); - const uint8x16_t l0 = vld1q_u8(left + 0); - const uint8x16_t l1 = vld1q_u8(left + 16); - const uint16x8_t a01 = vaddq_u16(vpaddlq_u8(a0), vpaddlq_u8(a1)); - const uint16x8_t l01 = vaddq_u16(vpaddlq_u8(l0), vpaddlq_u8(l1)); - const uint16x8_t al = vaddq_u16(a01, l01); - const uint16_t sum = horizontal_add_uint16x8(al); - const uint8x16_t dc = vdupq_lane_u8(vrshrn_n_u16(vdupq_n_u16(sum), 6), 0); - dc_store_32x32(dst, stride, dc); -} - -void vpx_dc_left_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, - const uint8_t *left) { - const uint16_t sum = dc_sum_32(left); - const uint8x16_t dc = vdupq_lane_u8(vrshrn_n_u16(vdupq_n_u16(sum), 5), 0); - (void)above; - dc_store_32x32(dst, stride, dc); -} - -void vpx_dc_top_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, - const uint8_t *left) { - const uint16_t sum = dc_sum_32(above); - const uint8x16_t dc = vdupq_lane_u8(vrshrn_n_u16(vdupq_n_u16(sum), 5), 0); - (void)left; - dc_store_32x32(dst, stride, dc); -} - -void vpx_dc_128_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, - const uint8_t *left) { - const uint8x16_t dc = vdupq_n_u8(0x80); - (void)above; - (void)left; - dc_store_32x32(dst, stride, dc); -} - -// ----------------------------------------------------------------------------- - -void vpx_d45_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - uint8x8_t a0, a1, a2, d0; - uint8_t a7; - (void)left; - - a0 = vld1_u8(above); - a7 = above[7]; - - // [ above[1], ..., above[6], x, x ] - a1 = vext_u8(a0, a0, 1); - // [ above[2], ..., above[7], x, x ] - a2 = vext_u8(a0, a0, 2); - - // d0[0] = AVG3(above[0], above[1], above[2]); - // ... - // d0[5] = AVG3(above[5], above[6], above[7]); - // d0[6] = x (don't care) - // d0[7] = x (don't care) - d0 = vrhadd_u8(vhadd_u8(a0, a2), a1); - - // We want: - // stride=0 [ d0[0], d0[1], d0[2], d0[3] ] - // stride=1 [ d0[1], d0[2], d0[3], d0[4] ] - // stride=2 [ d0[2], d0[3], d0[4], d0[5] ] - // stride=2 [ d0[3], d0[4], d0[5], above[7] ] - store_u8_4x1(dst + 0 * stride, d0); - store_u8_4x1(dst + 1 * stride, vext_u8(d0, d0, 1)); - store_u8_4x1(dst + 2 * stride, vext_u8(d0, d0, 2)); - store_u8_4x1(dst + 3 * stride, vext_u8(d0, d0, 3)); - - // We stored d0[6] above, so fixup into above[7]. - dst[3 * stride + 3] = a7; -} - -void vpx_d45_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - uint8x8_t ax0, a0, a1, a7, d0; - (void)left; - - a0 = vld1_u8(above + 0); - a1 = vld1_u8(above + 1); - a7 = vld1_dup_u8(above + 7); - - // We want to calculate the AVG3 result in lanes 1-7 inclusive so we can - // shift in above[7] later, so shift a0 across by one to get the right - // inputs: - // [ x, above[0], ... , above[6] ] - ax0 = vext_u8(a0, a0, 7); - - // d0[0] = x (don't care) - // d0[1] = AVG3(above[0], above[1], above[2]); - // ... - // d0[7] = AVG3(above[6], above[7], above[8]); - d0 = vrhadd_u8(vhadd_u8(ax0, a1), a0); - - // Undo the earlier ext, incrementally shift in duplicates of above[7]. - vst1_u8(dst + 0 * stride, vext_u8(d0, a7, 1)); - vst1_u8(dst + 1 * stride, vext_u8(d0, a7, 2)); - vst1_u8(dst + 2 * stride, vext_u8(d0, a7, 3)); - vst1_u8(dst + 3 * stride, vext_u8(d0, a7, 4)); - vst1_u8(dst + 4 * stride, vext_u8(d0, a7, 5)); - vst1_u8(dst + 5 * stride, vext_u8(d0, a7, 6)); - vst1_u8(dst + 6 * stride, vext_u8(d0, a7, 7)); - vst1_u8(dst + 7 * stride, a7); -} - -void vpx_d45_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - uint8x16_t ax0, a0, a1, a15, d0; - (void)left; - - a0 = vld1q_u8(above + 0); - a1 = vld1q_u8(above + 1); - a15 = vld1q_dup_u8(above + 15); - - // We want to calculate the AVG3 result in lanes 1-15 inclusive so we can - // shift in above[15] later, so shift a0 across by one to get the right - // inputs: - // [ x, above[0], ... , above[14] ] - ax0 = vextq_u8(a0, a0, 15); - - // d0[0] = x (don't care) - // d0[1] = AVG3(above[0], above[1], above[2]); - // ... - // d0[15] = AVG3(above[14], above[15], above[16]); - d0 = vrhaddq_u8(vhaddq_u8(ax0, a1), a0); - - // Undo the earlier ext, incrementally shift in duplicates of above[15]. - vst1q_u8(dst + 0 * stride, vextq_u8(d0, a15, 1)); - vst1q_u8(dst + 1 * stride, vextq_u8(d0, a15, 2)); - vst1q_u8(dst + 2 * stride, vextq_u8(d0, a15, 3)); - vst1q_u8(dst + 3 * stride, vextq_u8(d0, a15, 4)); - vst1q_u8(dst + 4 * stride, vextq_u8(d0, a15, 5)); - vst1q_u8(dst + 5 * stride, vextq_u8(d0, a15, 6)); - vst1q_u8(dst + 6 * stride, vextq_u8(d0, a15, 7)); - vst1q_u8(dst + 7 * stride, vextq_u8(d0, a15, 8)); - vst1q_u8(dst + 8 * stride, vextq_u8(d0, a15, 9)); - vst1q_u8(dst + 9 * stride, vextq_u8(d0, a15, 10)); - vst1q_u8(dst + 10 * stride, vextq_u8(d0, a15, 11)); - vst1q_u8(dst + 11 * stride, vextq_u8(d0, a15, 12)); - vst1q_u8(dst + 12 * stride, vextq_u8(d0, a15, 13)); - vst1q_u8(dst + 13 * stride, vextq_u8(d0, a15, 14)); - vst1q_u8(dst + 14 * stride, vextq_u8(d0, a15, 15)); - vst1q_u8(dst + 15 * stride, a15); -} - -void vpx_d45_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - uint8x16_t ax0, a0, a1, a15, a16, a17, a31, d0[2]; - (void)left; - - a0 = vld1q_u8(above + 0); - a1 = vld1q_u8(above + 1); - a15 = vld1q_u8(above + 15); - a16 = vld1q_u8(above + 16); - a17 = vld1q_u8(above + 17); - a31 = vld1q_dup_u8(above + 31); - - // We want to calculate the AVG3 result in lanes 1-15 inclusive so we can - // shift in above[15] later, so shift a0 across by one to get the right - // inputs: - // [ x, above[0], ... , above[14] ] - ax0 = vextq_u8(a0, a0, 15); - - // d0[0] = x (don't care) - // d0[1] = AVG3(above[0], above[1], above[2]); - // ... - // d0[15] = AVG3(above[14], above[15], above[16]); - d0[0] = vrhaddq_u8(vhaddq_u8(ax0, a1), a0); - d0[1] = vrhaddq_u8(vhaddq_u8(a15, a17), a16); - - // Undo the earlier ext, incrementally shift in duplicates of above[15]. - vst1q_u8(dst + 0 * stride + 0, vextq_u8(d0[0], d0[1], 1)); - vst1q_u8(dst + 0 * stride + 16, vextq_u8(d0[1], a31, 1)); - vst1q_u8(dst + 1 * stride + 0, vextq_u8(d0[0], d0[1], 2)); - vst1q_u8(dst + 1 * stride + 16, vextq_u8(d0[1], a31, 2)); - vst1q_u8(dst + 2 * stride + 0, vextq_u8(d0[0], d0[1], 3)); - vst1q_u8(dst + 2 * stride + 16, vextq_u8(d0[1], a31, 3)); - vst1q_u8(dst + 3 * stride + 0, vextq_u8(d0[0], d0[1], 4)); - vst1q_u8(dst + 3 * stride + 16, vextq_u8(d0[1], a31, 4)); - vst1q_u8(dst + 4 * stride + 0, vextq_u8(d0[0], d0[1], 5)); - vst1q_u8(dst + 4 * stride + 16, vextq_u8(d0[1], a31, 5)); - vst1q_u8(dst + 5 * stride + 0, vextq_u8(d0[0], d0[1], 6)); - vst1q_u8(dst + 5 * stride + 16, vextq_u8(d0[1], a31, 6)); - vst1q_u8(dst + 6 * stride + 0, vextq_u8(d0[0], d0[1], 7)); - vst1q_u8(dst + 6 * stride + 16, vextq_u8(d0[1], a31, 7)); - vst1q_u8(dst + 7 * stride + 0, vextq_u8(d0[0], d0[1], 8)); - vst1q_u8(dst + 7 * stride + 16, vextq_u8(d0[1], a31, 8)); - vst1q_u8(dst + 8 * stride + 0, vextq_u8(d0[0], d0[1], 9)); - vst1q_u8(dst + 8 * stride + 16, vextq_u8(d0[1], a31, 9)); - vst1q_u8(dst + 9 * stride + 0, vextq_u8(d0[0], d0[1], 10)); - vst1q_u8(dst + 9 * stride + 16, vextq_u8(d0[1], a31, 10)); - vst1q_u8(dst + 10 * stride + 0, vextq_u8(d0[0], d0[1], 11)); - vst1q_u8(dst + 10 * stride + 16, vextq_u8(d0[1], a31, 11)); - vst1q_u8(dst + 11 * stride + 0, vextq_u8(d0[0], d0[1], 12)); - vst1q_u8(dst + 11 * stride + 16, vextq_u8(d0[1], a31, 12)); - vst1q_u8(dst + 12 * stride + 0, vextq_u8(d0[0], d0[1], 13)); - vst1q_u8(dst + 12 * stride + 16, vextq_u8(d0[1], a31, 13)); - vst1q_u8(dst + 13 * stride + 0, vextq_u8(d0[0], d0[1], 14)); - vst1q_u8(dst + 13 * stride + 16, vextq_u8(d0[1], a31, 14)); - vst1q_u8(dst + 14 * stride + 0, vextq_u8(d0[0], d0[1], 15)); - vst1q_u8(dst + 14 * stride + 16, vextq_u8(d0[1], a31, 15)); - vst1q_u8(dst + 15 * stride + 0, d0[1]); - vst1q_u8(dst + 15 * stride + 16, a31); - - vst1q_u8(dst + 16 * stride + 0, vextq_u8(d0[1], a31, 1)); - vst1q_u8(dst + 16 * stride + 16, a31); - vst1q_u8(dst + 17 * stride + 0, vextq_u8(d0[1], a31, 2)); - vst1q_u8(dst + 17 * stride + 16, a31); - vst1q_u8(dst + 18 * stride + 0, vextq_u8(d0[1], a31, 3)); - vst1q_u8(dst + 18 * stride + 16, a31); - vst1q_u8(dst + 19 * stride + 0, vextq_u8(d0[1], a31, 4)); - vst1q_u8(dst + 19 * stride + 16, a31); - vst1q_u8(dst + 20 * stride + 0, vextq_u8(d0[1], a31, 5)); - vst1q_u8(dst + 20 * stride + 16, a31); - vst1q_u8(dst + 21 * stride + 0, vextq_u8(d0[1], a31, 6)); - vst1q_u8(dst + 21 * stride + 16, a31); - vst1q_u8(dst + 22 * stride + 0, vextq_u8(d0[1], a31, 7)); - vst1q_u8(dst + 22 * stride + 16, a31); - vst1q_u8(dst + 23 * stride + 0, vextq_u8(d0[1], a31, 8)); - vst1q_u8(dst + 23 * stride + 16, a31); - vst1q_u8(dst + 24 * stride + 0, vextq_u8(d0[1], a31, 9)); - vst1q_u8(dst + 24 * stride + 16, a31); - vst1q_u8(dst + 25 * stride + 0, vextq_u8(d0[1], a31, 10)); - vst1q_u8(dst + 25 * stride + 16, a31); - vst1q_u8(dst + 26 * stride + 0, vextq_u8(d0[1], a31, 11)); - vst1q_u8(dst + 26 * stride + 16, a31); - vst1q_u8(dst + 27 * stride + 0, vextq_u8(d0[1], a31, 12)); - vst1q_u8(dst + 27 * stride + 16, a31); - vst1q_u8(dst + 28 * stride + 0, vextq_u8(d0[1], a31, 13)); - vst1q_u8(dst + 28 * stride + 16, a31); - vst1q_u8(dst + 29 * stride + 0, vextq_u8(d0[1], a31, 14)); - vst1q_u8(dst + 29 * stride + 16, a31); - vst1q_u8(dst + 30 * stride + 0, vextq_u8(d0[1], a31, 15)); - vst1q_u8(dst + 30 * stride + 16, a31); - vst1q_u8(dst + 31 * stride + 0, a31); - vst1q_u8(dst + 31 * stride + 16, a31); -} - -// ----------------------------------------------------------------------------- - -void vpx_d63_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - uint8x8_t a0, a1, a2, a3, d0, d1, d2, d3; - (void)left; - - a0 = load_unaligned_u8_4x1(above + 0); - a1 = load_unaligned_u8_4x1(above + 1); - a2 = load_unaligned_u8_4x1(above + 2); - a3 = load_unaligned_u8_4x1(above + 3); - - d0 = vrhadd_u8(a0, a1); - d1 = vrhadd_u8(vhadd_u8(a0, a2), a1); - d2 = vrhadd_u8(a1, a2); - d3 = vrhadd_u8(vhadd_u8(a1, a3), a2); - - store_u8_4x1(dst + 0 * stride, d0); - store_u8_4x1(dst + 1 * stride, d1); - store_u8_4x1(dst + 2 * stride, d2); - store_u8_4x1(dst + 3 * stride, d3); -} - -void vpx_d63_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - uint8x8_t a0, a1, a2, a7, d0, d1; - (void)left; - - a0 = vld1_u8(above + 0); - a1 = vld1_u8(above + 1); - a2 = vld1_u8(above + 2); - a7 = vld1_dup_u8(above + 7); - - d0 = vrhadd_u8(a0, a1); - d1 = vrhadd_u8(vhadd_u8(a0, a2), a1); - - vst1_u8(dst + 0 * stride, d0); - vst1_u8(dst + 1 * stride, d1); - - d0 = vext_u8(d0, d0, 7); - d1 = vext_u8(d1, d1, 7); - - vst1_u8(dst + 2 * stride, vext_u8(d0, a7, 2)); - vst1_u8(dst + 3 * stride, vext_u8(d1, a7, 2)); - vst1_u8(dst + 4 * stride, vext_u8(d0, a7, 3)); - vst1_u8(dst + 5 * stride, vext_u8(d1, a7, 3)); - vst1_u8(dst + 6 * stride, vext_u8(d0, a7, 4)); - vst1_u8(dst + 7 * stride, vext_u8(d1, a7, 4)); -} - -void vpx_d63_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - uint8x16_t a0, a1, a2, a15, d0, d1; - (void)left; - - a0 = vld1q_u8(above + 0); - a1 = vld1q_u8(above + 1); - a2 = vld1q_u8(above + 2); - a15 = vld1q_dup_u8(above + 15); - - d0 = vrhaddq_u8(a0, a1); - d1 = vrhaddq_u8(vhaddq_u8(a0, a2), a1); - - vst1q_u8(dst + 0 * stride, d0); - vst1q_u8(dst + 1 * stride, d1); - - d0 = vextq_u8(d0, d0, 15); - d1 = vextq_u8(d1, d1, 15); - - vst1q_u8(dst + 2 * stride, vextq_u8(d0, a15, 2)); - vst1q_u8(dst + 3 * stride, vextq_u8(d1, a15, 2)); - vst1q_u8(dst + 4 * stride, vextq_u8(d0, a15, 3)); - vst1q_u8(dst + 5 * stride, vextq_u8(d1, a15, 3)); - vst1q_u8(dst + 6 * stride, vextq_u8(d0, a15, 4)); - vst1q_u8(dst + 7 * stride, vextq_u8(d1, a15, 4)); - vst1q_u8(dst + 8 * stride, vextq_u8(d0, a15, 5)); - vst1q_u8(dst + 9 * stride, vextq_u8(d1, a15, 5)); - vst1q_u8(dst + 10 * stride, vextq_u8(d0, a15, 6)); - vst1q_u8(dst + 11 * stride, vextq_u8(d1, a15, 6)); - vst1q_u8(dst + 12 * stride, vextq_u8(d0, a15, 7)); - vst1q_u8(dst + 13 * stride, vextq_u8(d1, a15, 7)); - vst1q_u8(dst + 14 * stride, vextq_u8(d0, a15, 8)); - vst1q_u8(dst + 15 * stride, vextq_u8(d1, a15, 8)); -} - -void vpx_d63_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - uint8x16_t a0, a1, a2, a16, a17, a18, a31, d0_lo, d0_hi, d1_lo, d1_hi; - (void)left; - - a0 = vld1q_u8(above + 0); - a1 = vld1q_u8(above + 1); - a2 = vld1q_u8(above + 2); - a16 = vld1q_u8(above + 16); - a17 = vld1q_u8(above + 17); - a18 = vld1q_u8(above + 18); - a31 = vld1q_dup_u8(above + 31); - - d0_lo = vrhaddq_u8(a0, a1); - d0_hi = vrhaddq_u8(a16, a17); - d1_lo = vrhaddq_u8(vhaddq_u8(a0, a2), a1); - d1_hi = vrhaddq_u8(vhaddq_u8(a16, a18), a17); - - vst1q_u8(dst + 0 * stride + 0, d0_lo); - vst1q_u8(dst + 0 * stride + 16, d0_hi); - vst1q_u8(dst + 1 * stride + 0, d1_lo); - vst1q_u8(dst + 1 * stride + 16, d1_hi); - - d0_hi = vextq_u8(d0_lo, d0_hi, 15); - d0_lo = vextq_u8(d0_lo, d0_lo, 15); - d1_hi = vextq_u8(d1_lo, d1_hi, 15); - d1_lo = vextq_u8(d1_lo, d1_lo, 15); - - vst1q_u8(dst + 2 * stride + 0, vextq_u8(d0_lo, d0_hi, 2)); - vst1q_u8(dst + 2 * stride + 16, vextq_u8(d0_hi, a31, 2)); - vst1q_u8(dst + 3 * stride + 0, vextq_u8(d1_lo, d1_hi, 2)); - vst1q_u8(dst + 3 * stride + 16, vextq_u8(d1_hi, a31, 2)); - vst1q_u8(dst + 4 * stride + 0, vextq_u8(d0_lo, d0_hi, 3)); - vst1q_u8(dst + 4 * stride + 16, vextq_u8(d0_hi, a31, 3)); - vst1q_u8(dst + 5 * stride + 0, vextq_u8(d1_lo, d1_hi, 3)); - vst1q_u8(dst + 5 * stride + 16, vextq_u8(d1_hi, a31, 3)); - vst1q_u8(dst + 6 * stride + 0, vextq_u8(d0_lo, d0_hi, 4)); - vst1q_u8(dst + 6 * stride + 16, vextq_u8(d0_hi, a31, 4)); - vst1q_u8(dst + 7 * stride + 0, vextq_u8(d1_lo, d1_hi, 4)); - vst1q_u8(dst + 7 * stride + 16, vextq_u8(d1_hi, a31, 4)); - vst1q_u8(dst + 8 * stride + 0, vextq_u8(d0_lo, d0_hi, 5)); - vst1q_u8(dst + 8 * stride + 16, vextq_u8(d0_hi, a31, 5)); - vst1q_u8(dst + 9 * stride + 0, vextq_u8(d1_lo, d1_hi, 5)); - vst1q_u8(dst + 9 * stride + 16, vextq_u8(d1_hi, a31, 5)); - vst1q_u8(dst + 10 * stride + 0, vextq_u8(d0_lo, d0_hi, 6)); - vst1q_u8(dst + 10 * stride + 16, vextq_u8(d0_hi, a31, 6)); - vst1q_u8(dst + 11 * stride + 0, vextq_u8(d1_lo, d1_hi, 6)); - vst1q_u8(dst + 11 * stride + 16, vextq_u8(d1_hi, a31, 6)); - vst1q_u8(dst + 12 * stride + 0, vextq_u8(d0_lo, d0_hi, 7)); - vst1q_u8(dst + 12 * stride + 16, vextq_u8(d0_hi, a31, 7)); - vst1q_u8(dst + 13 * stride + 0, vextq_u8(d1_lo, d1_hi, 7)); - vst1q_u8(dst + 13 * stride + 16, vextq_u8(d1_hi, a31, 7)); - vst1q_u8(dst + 14 * stride + 0, vextq_u8(d0_lo, d0_hi, 8)); - vst1q_u8(dst + 14 * stride + 16, vextq_u8(d0_hi, a31, 8)); - vst1q_u8(dst + 15 * stride + 0, vextq_u8(d1_lo, d1_hi, 8)); - vst1q_u8(dst + 15 * stride + 16, vextq_u8(d1_hi, a31, 8)); - vst1q_u8(dst + 16 * stride + 0, vextq_u8(d0_lo, d0_hi, 9)); - vst1q_u8(dst + 16 * stride + 16, vextq_u8(d0_hi, a31, 9)); - vst1q_u8(dst + 17 * stride + 0, vextq_u8(d1_lo, d1_hi, 9)); - vst1q_u8(dst + 17 * stride + 16, vextq_u8(d1_hi, a31, 9)); - vst1q_u8(dst + 18 * stride + 0, vextq_u8(d0_lo, d0_hi, 10)); - vst1q_u8(dst + 18 * stride + 16, vextq_u8(d0_hi, a31, 10)); - vst1q_u8(dst + 19 * stride + 0, vextq_u8(d1_lo, d1_hi, 10)); - vst1q_u8(dst + 19 * stride + 16, vextq_u8(d1_hi, a31, 10)); - vst1q_u8(dst + 20 * stride + 0, vextq_u8(d0_lo, d0_hi, 11)); - vst1q_u8(dst + 20 * stride + 16, vextq_u8(d0_hi, a31, 11)); - vst1q_u8(dst + 21 * stride + 0, vextq_u8(d1_lo, d1_hi, 11)); - vst1q_u8(dst + 21 * stride + 16, vextq_u8(d1_hi, a31, 11)); - vst1q_u8(dst + 22 * stride + 0, vextq_u8(d0_lo, d0_hi, 12)); - vst1q_u8(dst + 22 * stride + 16, vextq_u8(d0_hi, a31, 12)); - vst1q_u8(dst + 23 * stride + 0, vextq_u8(d1_lo, d1_hi, 12)); - vst1q_u8(dst + 23 * stride + 16, vextq_u8(d1_hi, a31, 12)); - vst1q_u8(dst + 24 * stride + 0, vextq_u8(d0_lo, d0_hi, 13)); - vst1q_u8(dst + 24 * stride + 16, vextq_u8(d0_hi, a31, 13)); - vst1q_u8(dst + 25 * stride + 0, vextq_u8(d1_lo, d1_hi, 13)); - vst1q_u8(dst + 25 * stride + 16, vextq_u8(d1_hi, a31, 13)); - vst1q_u8(dst + 26 * stride + 0, vextq_u8(d0_lo, d0_hi, 14)); - vst1q_u8(dst + 26 * stride + 16, vextq_u8(d0_hi, a31, 14)); - vst1q_u8(dst + 27 * stride + 0, vextq_u8(d1_lo, d1_hi, 14)); - vst1q_u8(dst + 27 * stride + 16, vextq_u8(d1_hi, a31, 14)); - vst1q_u8(dst + 28 * stride + 0, vextq_u8(d0_lo, d0_hi, 15)); - vst1q_u8(dst + 28 * stride + 16, vextq_u8(d0_hi, a31, 15)); - vst1q_u8(dst + 29 * stride + 0, vextq_u8(d1_lo, d1_hi, 15)); - vst1q_u8(dst + 29 * stride + 16, vextq_u8(d1_hi, a31, 15)); - vst1q_u8(dst + 30 * stride + 0, d0_hi); - vst1q_u8(dst + 30 * stride + 16, a31); - vst1q_u8(dst + 31 * stride + 0, d1_hi); - vst1q_u8(dst + 31 * stride + 16, a31); -} - -// ----------------------------------------------------------------------------- - -void vpx_d117_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - // See vpx_d117_predictor_8x8_neon for more details on the implementation. - uint8x8_t az, a0, l0az, d0, d1, d2, d3, col0, col1; - - az = load_unaligned_u8_4x1(above - 1); - a0 = load_unaligned_u8_4x1(above + 0); - // [ left[0], above[-1], above[0], above[1], x, x, x, x ] - l0az = vext_u8(vld1_dup_u8(left), az, 7); - - col0 = vdup_n_u8((above[-1] + 2 * left[0] + left[1] + 2) >> 2); - col1 = vdup_n_u8((left[0] + 2 * left[1] + left[2] + 2) >> 2); - - d0 = vrhadd_u8(az, a0); - d1 = vrhadd_u8(vhadd_u8(l0az, a0), az); - d2 = vext_u8(col0, d0, 7); - d3 = vext_u8(col1, d1, 7); - - store_u8_4x1(dst + 0 * stride, d0); - store_u8_4x1(dst + 1 * stride, d1); - store_u8_4x1(dst + 2 * stride, d2); - store_u8_4x1(dst + 3 * stride, d3); -} - -void vpx_d117_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - uint8x8_t az, a0, l0az, d0, d1, l0, l1, azl0, col0, col0_even, col0_odd; - - az = vld1_u8(above - 1); - a0 = vld1_u8(above + 0); - // [ left[0], above[-1], ... , above[5] ] - l0az = vext_u8(vld1_dup_u8(left), az, 7); - - l0 = vld1_u8(left + 0); - // The last lane here is unused, reading left[8] could cause a buffer - // over-read, so just fill with a duplicate of left[0] to avoid needing to - // materialize a zero: - // [ left[1], ... , left[7], x ] - l1 = vext_u8(l0, l0, 1); - // [ above[-1], left[0], ... , left[6] ] - azl0 = vext_u8(vld1_dup_u8(above - 1), l0, 7); - - // d0[0] = AVG2(above[-1], above[0]) - // d0[1] = AVG2(above[0], above[1]) - // ... - // d0[7] = AVG2(above[6], above[7]) - d0 = vrhadd_u8(az, a0); - - // d1[0] = AVG3(left[0], above[-1], above[0]) - // d1[1] = AVG3(above[-1], above[0], above[1]) - // ... - // d1[7] = AVG3(above[5], above[6], above[7]) - d1 = vrhadd_u8(vhadd_u8(l0az, a0), az); - - // The ext instruction shifts elements in from the end of the vector rather - // than the start, so reverse the vector to put the elements to be shifted in - // at the end. The lowest two lanes here are unused: - // col0[7] = AVG3(above[-1], left[0], left[1]) - // col0[6] = AVG3(left[0], left[1], left[2]) - // ... - // col0[2] = AVG3(left[4], left[5], left[6]) - // col0[1] = x (don't care) - // col0[0] = x (don't care) - col0 = vrev64_u8(vrhadd_u8(vhadd_u8(azl0, l1), l0)); - - // We don't care about the first parameter to this uzp since we only ever use - // the high three elements, we just use col0 again since it is already - // available: - // col0_even = [ x, x, x, x, x, col0[3], col0[5], col0[7] ] - // col0_odd = [ x, x, x, x, x, col0[2], col0[4], col0[6] ] - col0_even = vuzp_u8(col0, col0).val[1]; - col0_odd = vuzp_u8(col0, col0).val[0]; - - // Incrementally shift more elements from col0 into d0/1: - // stride=0 [ d0[0], d0[1], d0[2], d0[3], d0[4], d0[5], d0[6], d0[7] ] - // stride=1 [ d1[0], d1[1], d1[2], d1[3], d1[4], d1[5], d1[6], d1[7] ] - // stride=2 [ col0[7], d0[0], d0[1], d0[2], d0[3], d0[4], d0[5], d0[6] ] - // stride=3 [ col0[6], d1[0], d1[1], d1[2], d1[3], d1[4], d1[5], d1[6] ] - // stride=4 [ col0[5], col0[7], d0[0], d0[1], d0[2], d0[3], d0[4], d0[5] ] - // stride=5 [ col0[4], col0[6], d1[0], d1[1], d1[2], d1[3], d1[4], d1[5] ] - // stride=6 [ col0[3], col0[5], col0[7], d0[0], d0[1], d0[2], d0[3], d0[4] ] - // stride=7 [ col0[2], col0[4], col0[6], d1[0], d1[1], d1[2], d1[3], d1[4] ] - vst1_u8(dst + 0 * stride, d0); - vst1_u8(dst + 1 * stride, d1); - vst1_u8(dst + 2 * stride, vext_u8(col0_even, d0, 7)); - vst1_u8(dst + 3 * stride, vext_u8(col0_odd, d1, 7)); - vst1_u8(dst + 4 * stride, vext_u8(col0_even, d0, 6)); - vst1_u8(dst + 5 * stride, vext_u8(col0_odd, d1, 6)); - vst1_u8(dst + 6 * stride, vext_u8(col0_even, d0, 5)); - vst1_u8(dst + 7 * stride, vext_u8(col0_odd, d1, 5)); -} - -void vpx_d117_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - // See vpx_d117_predictor_8x8_neon for more details on the implementation. - uint8x16_t az, a0, l0az, d0, d1, l0, l1, azl0, col0, col0_even, col0_odd; - - az = vld1q_u8(above - 1); - a0 = vld1q_u8(above + 0); - // [ left[0], above[-1], ... , above[13] ] - l0az = vextq_u8(vld1q_dup_u8(left), az, 15); - - l0 = vld1q_u8(left + 0); - // The last lane here is unused, reading left[16] could cause a buffer - // over-read, so just fill with a duplicate of left[0] to avoid needing to - // materialize a zero: - // [ left[1], ... , left[15], x ] - l1 = vextq_u8(l0, l0, 1); - // [ above[-1], left[0], ... , left[14] ] - azl0 = vextq_u8(vld1q_dup_u8(above - 1), l0, 15); - - d0 = vrhaddq_u8(az, a0); - d1 = vrhaddq_u8(vhaddq_u8(l0az, a0), az); - - col0 = vrhaddq_u8(vhaddq_u8(azl0, l1), l0); - col0 = vrev64q_u8(vextq_u8(col0, col0, 8)); - - // The low nine lanes here are unused so the first input to the uzp is - // unused, so just use a duplicate of col0 since we have it already. This - // also means that the lowest lane of col0 here is unused. - col0_even = vuzpq_u8(col0, col0).val[1]; - col0_odd = vuzpq_u8(col0, col0).val[0]; - - vst1q_u8(dst + 0 * stride, d0); - vst1q_u8(dst + 1 * stride, d1); - vst1q_u8(dst + 2 * stride, vextq_u8(col0_even, d0, 15)); - vst1q_u8(dst + 3 * stride, vextq_u8(col0_odd, d1, 15)); - vst1q_u8(dst + 4 * stride, vextq_u8(col0_even, d0, 14)); - vst1q_u8(dst + 5 * stride, vextq_u8(col0_odd, d1, 14)); - vst1q_u8(dst + 6 * stride, vextq_u8(col0_even, d0, 13)); - vst1q_u8(dst + 7 * stride, vextq_u8(col0_odd, d1, 13)); - vst1q_u8(dst + 8 * stride, vextq_u8(col0_even, d0, 12)); - vst1q_u8(dst + 9 * stride, vextq_u8(col0_odd, d1, 12)); - vst1q_u8(dst + 10 * stride, vextq_u8(col0_even, d0, 11)); - vst1q_u8(dst + 11 * stride, vextq_u8(col0_odd, d1, 11)); - vst1q_u8(dst + 12 * stride, vextq_u8(col0_even, d0, 10)); - vst1q_u8(dst + 13 * stride, vextq_u8(col0_odd, d1, 10)); - vst1q_u8(dst + 14 * stride, vextq_u8(col0_even, d0, 9)); - vst1q_u8(dst + 15 * stride, vextq_u8(col0_odd, d1, 9)); -} - -void vpx_d117_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - // See vpx_d117_predictor_8x8_neon for more details on the implementation. - uint8x16_t az, a0, a14, a15, a16, l0az, d0_lo, d0_hi, d1_lo, d1_hi, l0, l1, - l15, l16, l17, azl0, col0_lo, col0_hi, col0_even, col0_odd; - - az = vld1q_u8(above - 1); - a0 = vld1q_u8(above + 0); - a14 = vld1q_u8(above + 14); - a15 = vld1q_u8(above + 15); - a16 = vld1q_u8(above + 16); - // [ left[0], above[-1], ... , above[13] ] - l0az = vextq_u8(vld1q_dup_u8(left), az, 15); - - l0 = vld1q_u8(left + 0); - l1 = vld1q_u8(left + 1); - l15 = vld1q_u8(left + 15); - l16 = vld1q_u8(left + 16); - // The last lane here is unused, reading left[32] would cause a buffer - // over-read (observed as an address-sanitizer failure), so just fill with a - // duplicate of left[16] to avoid needing to materialize a zero: - // [ left[17], ... , left[31], x ] - l17 = vextq_u8(l16, l16, 1); - // [ above[-1], left[0], ... , left[14] ] - azl0 = vextq_u8(vld1q_dup_u8(above - 1), l0, 15); - - d0_lo = vrhaddq_u8(az, a0); - d0_hi = vrhaddq_u8(a15, a16); - d1_lo = vrhaddq_u8(vhaddq_u8(l0az, a0), az); - d1_hi = vrhaddq_u8(vhaddq_u8(a14, a16), a15); - - // The last lane of col0_hi is unused here. - col0_lo = vrhaddq_u8(vhaddq_u8(azl0, l1), l0); - col0_hi = vrhaddq_u8(vhaddq_u8(l15, l17), l16); - - col0_lo = vrev64q_u8(vextq_u8(col0_lo, col0_lo, 8)); - col0_hi = vrev64q_u8(vextq_u8(col0_hi, col0_hi, 8)); - - // The first lane of these are unused since they are only ever called as - // ext(col0, _, i) where i >= 1. - col0_even = vuzpq_u8(col0_hi, col0_lo).val[1]; - col0_odd = vuzpq_u8(col0_hi, col0_lo).val[0]; - - vst1q_u8(dst + 0 * stride + 0, d0_lo); - vst1q_u8(dst + 0 * stride + 16, d0_hi); - vst1q_u8(dst + 1 * stride + 0, d1_lo); - vst1q_u8(dst + 1 * stride + 16, d1_hi); - vst1q_u8(dst + 2 * stride + 0, vextq_u8(col0_even, d0_lo, 15)); - vst1q_u8(dst + 2 * stride + 16, vextq_u8(d0_lo, d0_hi, 15)); - vst1q_u8(dst + 3 * stride + 0, vextq_u8(col0_odd, d1_lo, 15)); - vst1q_u8(dst + 3 * stride + 16, vextq_u8(d1_lo, d1_hi, 15)); - vst1q_u8(dst + 4 * stride + 0, vextq_u8(col0_even, d0_lo, 14)); - vst1q_u8(dst + 4 * stride + 16, vextq_u8(d0_lo, d0_hi, 14)); - vst1q_u8(dst + 5 * stride + 0, vextq_u8(col0_odd, d1_lo, 14)); - vst1q_u8(dst + 5 * stride + 16, vextq_u8(d1_lo, d1_hi, 14)); - vst1q_u8(dst + 6 * stride + 0, vextq_u8(col0_even, d0_lo, 13)); - vst1q_u8(dst + 6 * stride + 16, vextq_u8(d0_lo, d0_hi, 13)); - vst1q_u8(dst + 7 * stride + 0, vextq_u8(col0_odd, d1_lo, 13)); - vst1q_u8(dst + 7 * stride + 16, vextq_u8(d1_lo, d1_hi, 13)); - vst1q_u8(dst + 8 * stride + 0, vextq_u8(col0_even, d0_lo, 12)); - vst1q_u8(dst + 8 * stride + 16, vextq_u8(d0_lo, d0_hi, 12)); - vst1q_u8(dst + 9 * stride + 0, vextq_u8(col0_odd, d1_lo, 12)); - vst1q_u8(dst + 9 * stride + 16, vextq_u8(d1_lo, d1_hi, 12)); - vst1q_u8(dst + 10 * stride + 0, vextq_u8(col0_even, d0_lo, 11)); - vst1q_u8(dst + 10 * stride + 16, vextq_u8(d0_lo, d0_hi, 11)); - vst1q_u8(dst + 11 * stride + 0, vextq_u8(col0_odd, d1_lo, 11)); - vst1q_u8(dst + 11 * stride + 16, vextq_u8(d1_lo, d1_hi, 11)); - vst1q_u8(dst + 12 * stride + 0, vextq_u8(col0_even, d0_lo, 10)); - vst1q_u8(dst + 12 * stride + 16, vextq_u8(d0_lo, d0_hi, 10)); - vst1q_u8(dst + 13 * stride + 0, vextq_u8(col0_odd, d1_lo, 10)); - vst1q_u8(dst + 13 * stride + 16, vextq_u8(d1_lo, d1_hi, 10)); - vst1q_u8(dst + 14 * stride + 0, vextq_u8(col0_even, d0_lo, 9)); - vst1q_u8(dst + 14 * stride + 16, vextq_u8(d0_lo, d0_hi, 9)); - vst1q_u8(dst + 15 * stride + 0, vextq_u8(col0_odd, d1_lo, 9)); - vst1q_u8(dst + 15 * stride + 16, vextq_u8(d1_lo, d1_hi, 9)); - vst1q_u8(dst + 16 * stride + 0, vextq_u8(col0_even, d0_lo, 8)); - vst1q_u8(dst + 16 * stride + 16, vextq_u8(d0_lo, d0_hi, 8)); - vst1q_u8(dst + 17 * stride + 0, vextq_u8(col0_odd, d1_lo, 8)); - vst1q_u8(dst + 17 * stride + 16, vextq_u8(d1_lo, d1_hi, 8)); - vst1q_u8(dst + 18 * stride + 0, vextq_u8(col0_even, d0_lo, 7)); - vst1q_u8(dst + 18 * stride + 16, vextq_u8(d0_lo, d0_hi, 7)); - vst1q_u8(dst + 19 * stride + 0, vextq_u8(col0_odd, d1_lo, 7)); - vst1q_u8(dst + 19 * stride + 16, vextq_u8(d1_lo, d1_hi, 7)); - vst1q_u8(dst + 20 * stride + 0, vextq_u8(col0_even, d0_lo, 6)); - vst1q_u8(dst + 20 * stride + 16, vextq_u8(d0_lo, d0_hi, 6)); - vst1q_u8(dst + 21 * stride + 0, vextq_u8(col0_odd, d1_lo, 6)); - vst1q_u8(dst + 21 * stride + 16, vextq_u8(d1_lo, d1_hi, 6)); - vst1q_u8(dst + 22 * stride + 0, vextq_u8(col0_even, d0_lo, 5)); - vst1q_u8(dst + 22 * stride + 16, vextq_u8(d0_lo, d0_hi, 5)); - vst1q_u8(dst + 23 * stride + 0, vextq_u8(col0_odd, d1_lo, 5)); - vst1q_u8(dst + 23 * stride + 16, vextq_u8(d1_lo, d1_hi, 5)); - vst1q_u8(dst + 24 * stride + 0, vextq_u8(col0_even, d0_lo, 4)); - vst1q_u8(dst + 24 * stride + 16, vextq_u8(d0_lo, d0_hi, 4)); - vst1q_u8(dst + 25 * stride + 0, vextq_u8(col0_odd, d1_lo, 4)); - vst1q_u8(dst + 25 * stride + 16, vextq_u8(d1_lo, d1_hi, 4)); - vst1q_u8(dst + 26 * stride + 0, vextq_u8(col0_even, d0_lo, 3)); - vst1q_u8(dst + 26 * stride + 16, vextq_u8(d0_lo, d0_hi, 3)); - vst1q_u8(dst + 27 * stride + 0, vextq_u8(col0_odd, d1_lo, 3)); - vst1q_u8(dst + 27 * stride + 16, vextq_u8(d1_lo, d1_hi, 3)); - vst1q_u8(dst + 28 * stride + 0, vextq_u8(col0_even, d0_lo, 2)); - vst1q_u8(dst + 28 * stride + 16, vextq_u8(d0_lo, d0_hi, 2)); - vst1q_u8(dst + 29 * stride + 0, vextq_u8(col0_odd, d1_lo, 2)); - vst1q_u8(dst + 29 * stride + 16, vextq_u8(d1_lo, d1_hi, 2)); - vst1q_u8(dst + 30 * stride + 0, vextq_u8(col0_even, d0_lo, 1)); - vst1q_u8(dst + 30 * stride + 16, vextq_u8(d0_lo, d0_hi, 1)); - vst1q_u8(dst + 31 * stride + 0, vextq_u8(col0_odd, d1_lo, 1)); - vst1q_u8(dst + 31 * stride + 16, vextq_u8(d1_lo, d1_hi, 1)); -} - -// ----------------------------------------------------------------------------- - -void vpx_d135_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x8_t XA0123 = vld1_u8(above - 1); - const uint8x8_t L0123 = vld1_u8(left); - const uint8x8_t L3210 = vrev64_u8(L0123); - const uint8x8_t L3210XA012 = vext_u8(L3210, XA0123, 4); - const uint8x8_t L210XA0123 = vext_u8(L3210, XA0123, 5); - const uint8x8_t L10XA0123_ = vext_u8(L210XA0123, L210XA0123, 1); - const uint8x8_t avg1 = vhadd_u8(L10XA0123_, L3210XA012); - const uint8x8_t avg2 = vrhadd_u8(avg1, L210XA0123); - - store_u8_4x1(dst + 0 * stride, vext_u8(avg2, avg2, 3)); - store_u8_4x1(dst + 1 * stride, vext_u8(avg2, avg2, 2)); - store_u8_4x1(dst + 2 * stride, vext_u8(avg2, avg2, 1)); - store_u8_4x1(dst + 3 * stride, avg2); -} - -void vpx_d135_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x8_t XA0123456 = vld1_u8(above - 1); - const uint8x8_t A01234567 = vld1_u8(above); - const uint8x8_t A1234567_ = vld1_u8(above + 1); - const uint8x8_t L01234567 = vld1_u8(left); - const uint8x8_t L76543210 = vrev64_u8(L01234567); - const uint8x8_t L6543210X = vext_u8(L76543210, XA0123456, 1); - const uint8x8_t L543210XA0 = vext_u8(L76543210, XA0123456, 2); - const uint8x16_t L76543210XA0123456 = vcombine_u8(L76543210, XA0123456); - const uint8x16_t L6543210XA01234567 = vcombine_u8(L6543210X, A01234567); - const uint8x16_t L543210XA01234567_ = vcombine_u8(L543210XA0, A1234567_); - const uint8x16_t avg = vhaddq_u8(L76543210XA0123456, L543210XA01234567_); - const uint8x16_t row = vrhaddq_u8(avg, L6543210XA01234567); - - vst1_u8(dst + 0 * stride, vget_low_u8(vextq_u8(row, row, 7))); - vst1_u8(dst + 1 * stride, vget_low_u8(vextq_u8(row, row, 6))); - vst1_u8(dst + 2 * stride, vget_low_u8(vextq_u8(row, row, 5))); - vst1_u8(dst + 3 * stride, vget_low_u8(vextq_u8(row, row, 4))); - vst1_u8(dst + 4 * stride, vget_low_u8(vextq_u8(row, row, 3))); - vst1_u8(dst + 5 * stride, vget_low_u8(vextq_u8(row, row, 2))); - vst1_u8(dst + 6 * stride, vget_low_u8(vextq_u8(row, row, 1))); - vst1_u8(dst + 7 * stride, vget_low_u8(row)); -} - -static INLINE void d135_store_16x8( - uint8_t **dst, const ptrdiff_t stride, const uint8x16_t row_0, - const uint8x16_t row_1, const uint8x16_t row_2, const uint8x16_t row_3, - const uint8x16_t row_4, const uint8x16_t row_5, const uint8x16_t row_6, - const uint8x16_t row_7) { - vst1q_u8(*dst, row_0); - *dst += stride; - vst1q_u8(*dst, row_1); - *dst += stride; - vst1q_u8(*dst, row_2); - *dst += stride; - vst1q_u8(*dst, row_3); - *dst += stride; - vst1q_u8(*dst, row_4); - *dst += stride; - vst1q_u8(*dst, row_5); - *dst += stride; - vst1q_u8(*dst, row_6); - *dst += stride; - vst1q_u8(*dst, row_7); - *dst += stride; -} - -void vpx_d135_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t XA0123456789abcde = vld1q_u8(above - 1); - const uint8x16_t A0123456789abcdef = vld1q_u8(above); - const uint8x16_t A123456789abcdef_ = vld1q_u8(above + 1); - const uint8x16_t L0123456789abcdef = vld1q_u8(left); - const uint8x8_t L76543210 = vrev64_u8(vget_low_u8(L0123456789abcdef)); - const uint8x8_t Lfedcba98 = vrev64_u8(vget_high_u8(L0123456789abcdef)); - const uint8x16_t Lfedcba9876543210 = vcombine_u8(Lfedcba98, L76543210); - const uint8x16_t Ledcba9876543210X = - vextq_u8(Lfedcba9876543210, XA0123456789abcde, 1); - const uint8x16_t Ldcba9876543210XA0 = - vextq_u8(Lfedcba9876543210, XA0123456789abcde, 2); - const uint8x16_t avg_0 = vhaddq_u8(Lfedcba9876543210, Ldcba9876543210XA0); - const uint8x16_t avg_1 = vhaddq_u8(XA0123456789abcde, A123456789abcdef_); - const uint8x16_t row_0 = vrhaddq_u8(avg_0, Ledcba9876543210X); - const uint8x16_t row_1 = vrhaddq_u8(avg_1, A0123456789abcdef); - - const uint8x16_t r_0 = vextq_u8(row_0, row_1, 15); - const uint8x16_t r_1 = vextq_u8(row_0, row_1, 14); - const uint8x16_t r_2 = vextq_u8(row_0, row_1, 13); - const uint8x16_t r_3 = vextq_u8(row_0, row_1, 12); - const uint8x16_t r_4 = vextq_u8(row_0, row_1, 11); - const uint8x16_t r_5 = vextq_u8(row_0, row_1, 10); - const uint8x16_t r_6 = vextq_u8(row_0, row_1, 9); - const uint8x16_t r_7 = vextq_u8(row_0, row_1, 8); - const uint8x16_t r_8 = vextq_u8(row_0, row_1, 7); - const uint8x16_t r_9 = vextq_u8(row_0, row_1, 6); - const uint8x16_t r_a = vextq_u8(row_0, row_1, 5); - const uint8x16_t r_b = vextq_u8(row_0, row_1, 4); - const uint8x16_t r_c = vextq_u8(row_0, row_1, 3); - const uint8x16_t r_d = vextq_u8(row_0, row_1, 2); - const uint8x16_t r_e = vextq_u8(row_0, row_1, 1); - - d135_store_16x8(&dst, stride, r_0, r_1, r_2, r_3, r_4, r_5, r_6, r_7); - d135_store_16x8(&dst, stride, r_8, r_9, r_a, r_b, r_c, r_d, r_e, row_0); -} - -static INLINE void d135_store_32x2(uint8_t **dst, const ptrdiff_t stride, - const uint8x16_t row_0, - const uint8x16_t row_1, - const uint8x16_t row_2) { - uint8_t *dst2 = *dst; - vst1q_u8(dst2, row_1); - dst2 += 16; - vst1q_u8(dst2, row_2); - dst2 += 16 * stride - 16; - vst1q_u8(dst2, row_0); - dst2 += 16; - vst1q_u8(dst2, row_1); - *dst += stride; -} - -void vpx_d135_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t LL0123456789abcdef = vld1q_u8(left + 16); - const uint8x16_t LU0123456789abcdef = vld1q_u8(left); - const uint8x8_t LL76543210 = vrev64_u8(vget_low_u8(LL0123456789abcdef)); - const uint8x8_t LU76543210 = vrev64_u8(vget_low_u8(LU0123456789abcdef)); - const uint8x8_t LLfedcba98 = vrev64_u8(vget_high_u8(LL0123456789abcdef)); - const uint8x8_t LUfedcba98 = vrev64_u8(vget_high_u8(LU0123456789abcdef)); - const uint8x16_t LLfedcba9876543210 = vcombine_u8(LLfedcba98, LL76543210); - const uint8x16_t LUfedcba9876543210 = vcombine_u8(LUfedcba98, LU76543210); - const uint8x16_t LLedcba9876543210Uf = - vextq_u8(LLfedcba9876543210, LUfedcba9876543210, 1); - const uint8x16_t LLdcba9876543210Ufe = - vextq_u8(LLfedcba9876543210, LUfedcba9876543210, 2); - const uint8x16_t avg_0 = vhaddq_u8(LLfedcba9876543210, LLdcba9876543210Ufe); - const uint8x16_t row_0 = vrhaddq_u8(avg_0, LLedcba9876543210Uf); - - const uint8x16_t XAL0123456789abcde = vld1q_u8(above - 1); - const uint8x16_t LUedcba9876543210X = - vextq_u8(LUfedcba9876543210, XAL0123456789abcde, 1); - const uint8x16_t LUdcba9876543210XA0 = - vextq_u8(LUfedcba9876543210, XAL0123456789abcde, 2); - const uint8x16_t avg_1 = vhaddq_u8(LUfedcba9876543210, LUdcba9876543210XA0); - const uint8x16_t row_1 = vrhaddq_u8(avg_1, LUedcba9876543210X); - - const uint8x16_t AL0123456789abcdef = vld1q_u8(above); - const uint8x16_t AL123456789abcdefg = vld1q_u8(above + 1); - const uint8x16_t ALfR0123456789abcde = vld1q_u8(above + 15); - const uint8x16_t AR0123456789abcdef = vld1q_u8(above + 16); - const uint8x16_t AR123456789abcdef_ = vld1q_u8(above + 17); - const uint8x16_t avg_2 = vhaddq_u8(XAL0123456789abcde, AL123456789abcdefg); - const uint8x16_t row_2 = vrhaddq_u8(avg_2, AL0123456789abcdef); - const uint8x16_t avg_3 = vhaddq_u8(ALfR0123456789abcde, AR123456789abcdef_); - const uint8x16_t row_3 = vrhaddq_u8(avg_3, AR0123456789abcdef); - - { - const uint8x16_t r_0 = vextq_u8(row_0, row_1, 15); - const uint8x16_t r_1 = vextq_u8(row_1, row_2, 15); - const uint8x16_t r_2 = vextq_u8(row_2, row_3, 15); - d135_store_32x2(&dst, stride, r_0, r_1, r_2); - } - - { - const uint8x16_t r_0 = vextq_u8(row_0, row_1, 14); - const uint8x16_t r_1 = vextq_u8(row_1, row_2, 14); - const uint8x16_t r_2 = vextq_u8(row_2, row_3, 14); - d135_store_32x2(&dst, stride, r_0, r_1, r_2); - } - - { - const uint8x16_t r_0 = vextq_u8(row_0, row_1, 13); - const uint8x16_t r_1 = vextq_u8(row_1, row_2, 13); - const uint8x16_t r_2 = vextq_u8(row_2, row_3, 13); - d135_store_32x2(&dst, stride, r_0, r_1, r_2); - } - - { - const uint8x16_t r_0 = vextq_u8(row_0, row_1, 12); - const uint8x16_t r_1 = vextq_u8(row_1, row_2, 12); - const uint8x16_t r_2 = vextq_u8(row_2, row_3, 12); - d135_store_32x2(&dst, stride, r_0, r_1, r_2); - } - - { - const uint8x16_t r_0 = vextq_u8(row_0, row_1, 11); - const uint8x16_t r_1 = vextq_u8(row_1, row_2, 11); - const uint8x16_t r_2 = vextq_u8(row_2, row_3, 11); - d135_store_32x2(&dst, stride, r_0, r_1, r_2); - } - - { - const uint8x16_t r_0 = vextq_u8(row_0, row_1, 10); - const uint8x16_t r_1 = vextq_u8(row_1, row_2, 10); - const uint8x16_t r_2 = vextq_u8(row_2, row_3, 10); - d135_store_32x2(&dst, stride, r_0, r_1, r_2); - } - - { - const uint8x16_t r_0 = vextq_u8(row_0, row_1, 9); - const uint8x16_t r_1 = vextq_u8(row_1, row_2, 9); - const uint8x16_t r_2 = vextq_u8(row_2, row_3, 9); - d135_store_32x2(&dst, stride, r_0, r_1, r_2); - } - - { - const uint8x16_t r_0 = vextq_u8(row_0, row_1, 8); - const uint8x16_t r_1 = vextq_u8(row_1, row_2, 8); - const uint8x16_t r_2 = vextq_u8(row_2, row_3, 8); - d135_store_32x2(&dst, stride, r_0, r_1, r_2); - } - - { - const uint8x16_t r_0 = vextq_u8(row_0, row_1, 7); - const uint8x16_t r_1 = vextq_u8(row_1, row_2, 7); - const uint8x16_t r_2 = vextq_u8(row_2, row_3, 7); - d135_store_32x2(&dst, stride, r_0, r_1, r_2); - } - - { - const uint8x16_t r_0 = vextq_u8(row_0, row_1, 6); - const uint8x16_t r_1 = vextq_u8(row_1, row_2, 6); - const uint8x16_t r_2 = vextq_u8(row_2, row_3, 6); - d135_store_32x2(&dst, stride, r_0, r_1, r_2); - } - - { - const uint8x16_t r_0 = vextq_u8(row_0, row_1, 5); - const uint8x16_t r_1 = vextq_u8(row_1, row_2, 5); - const uint8x16_t r_2 = vextq_u8(row_2, row_3, 5); - d135_store_32x2(&dst, stride, r_0, r_1, r_2); - } - - { - const uint8x16_t r_0 = vextq_u8(row_0, row_1, 4); - const uint8x16_t r_1 = vextq_u8(row_1, row_2, 4); - const uint8x16_t r_2 = vextq_u8(row_2, row_3, 4); - d135_store_32x2(&dst, stride, r_0, r_1, r_2); - } - - { - const uint8x16_t r_0 = vextq_u8(row_0, row_1, 3); - const uint8x16_t r_1 = vextq_u8(row_1, row_2, 3); - const uint8x16_t r_2 = vextq_u8(row_2, row_3, 3); - d135_store_32x2(&dst, stride, r_0, r_1, r_2); - } - - { - const uint8x16_t r_0 = vextq_u8(row_0, row_1, 2); - const uint8x16_t r_1 = vextq_u8(row_1, row_2, 2); - const uint8x16_t r_2 = vextq_u8(row_2, row_3, 2); - d135_store_32x2(&dst, stride, r_0, r_1, r_2); - } - - { - const uint8x16_t r_0 = vextq_u8(row_0, row_1, 1); - const uint8x16_t r_1 = vextq_u8(row_1, row_2, 1); - const uint8x16_t r_2 = vextq_u8(row_2, row_3, 1); - d135_store_32x2(&dst, stride, r_0, r_1, r_2); - } - - d135_store_32x2(&dst, stride, row_0, row_1, row_2); -} - -// ----------------------------------------------------------------------------- - -void vpx_d153_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - // See vpx_d153_predictor_8x8_neon for more details on the implementation. - uint8x8_t az, a0, l0az, l0, l1, azl0, d0, d1, d2, d02; - - az = load_unaligned_u8_4x1(above - 1); - a0 = load_unaligned_u8_4x1(above + 0); - // [ left[0], above[-1], above[0], above[1], x, x, x, x ] - l0az = vext_u8(vld1_dup_u8(left), az, 7); - - l0 = load_unaligned_u8_4x1(left + 0); - l1 = load_unaligned_u8_4x1(left + 1); - // [ above[-1], left[0], left[1], left[2], x, x, x, x ] - azl0 = vext_u8(vld1_dup_u8(above - 1), l0, 7); - - d0 = vrhadd_u8(azl0, l0); - d1 = vrhadd_u8(vhadd_u8(l0az, a0), az); - d2 = vrhadd_u8(vhadd_u8(azl0, l1), l0); - - d02 = vrev64_u8(vzip_u8(d0, d2).val[0]); - - store_u8_4x1(dst + 0 * stride, vext_u8(d02, d1, 7)); - store_u8_4x1(dst + 1 * stride, vext_u8(d02, d1, 5)); - store_u8_4x1(dst + 2 * stride, vext_u8(d02, d1, 3)); - store_u8_4x1(dst + 3 * stride, vext_u8(d02, d1, 1)); -} - -void vpx_d153_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - uint8x8_t az, a0, l0az, l0, l1, azl0, d0, d1, d2, d02_lo, d02_hi; - - az = vld1_u8(above - 1); - a0 = vld1_u8(above + 0); - // [ left[0], above[-1], ... , above[5] ] - l0az = vext_u8(vld1_dup_u8(left), az, 7); - - l0 = vld1_u8(left); - // The last lane here is unused, reading left[8] could cause a buffer - // over-read, so just fill with a duplicate of left[0] to avoid needing to - // materialize a zero: - // [ left[1], ... , left[7], x ] - l1 = vext_u8(l0, l0, 1); - // [ above[-1], left[0], ... , left[6] ] - azl0 = vext_u8(vld1_dup_u8(above - 1), l0, 7); - - // d0[0] = AVG2(above[-1], left[0]) - // d0[1] = AVG2(left[0], left[1]) - // ... - // d0[7] = AVG2(left[6], left[7]) - d0 = vrhadd_u8(azl0, l0); - - // d1[0] = AVG3(left[0], above[-1], above[0]) - // d1[1] = AVG3(above[-1], above[0], above[1]) - // ... - // d1[7] = AVG3(above[5], above[6], above[7]) - d1 = vrhadd_u8(vhadd_u8(l0az, a0), az); - - // d2[0] = AVG3(above[-1], left[0], left[1]) - // d2[1] = AVG3(left[0], left[1], left[2]) - // ... - // d2[6] = AVG3(left[5], left[6], left[7]) - // d2[7] = x (don't care) - d2 = vrhadd_u8(vhadd_u8(azl0, l1), l0); - - // The ext instruction shifts elements in from the end of the vector rather - // than the start, so reverse the vectors to put the elements to be shifted - // in at the end. The lowest lane of d02_lo is unused. - d02_lo = vzip_u8(vrev64_u8(d2), vrev64_u8(d0)).val[0]; - d02_hi = vzip_u8(vrev64_u8(d2), vrev64_u8(d0)).val[1]; - - // Incrementally shift more elements from d0/d2 reversed into d1: - // stride=0 [ d0[0], d1[0], d1[1], d1[2], d1[3], d1[4], d1[5], d1[6] ] - // stride=1 [ d0[1], d2[0], d0[0], d1[0], d1[1], d1[2], d1[3], d1[4] ] - // stride=2 [ d0[2], d2[1], d0[1], d2[0], d0[0], d1[0], d1[1], d1[2] ] - // stride=3 [ d0[3], d2[2], d0[2], d2[1], d0[1], d2[0], d0[0], d1[0] ] - // stride=4 [ d0[4], d2[3], d0[3], d2[2], d0[2], d2[1], d0[1], d2[0] ] - // stride=5 [ d0[5], d2[4], d0[4], d2[3], d0[3], d2[2], d0[2], d2[1] ] - // stride=6 [ d0[6], d2[5], d0[5], d2[4], d0[4], d2[3], d0[3], d2[2] ] - // stride=7 [ d0[7], d2[6], d0[6], d2[5], d0[5], d2[4], d0[4], d2[3] ] - vst1_u8(dst + 0 * stride, vext_u8(d02_hi, d1, 7)); - vst1_u8(dst + 1 * stride, vext_u8(d02_hi, d1, 5)); - vst1_u8(dst + 2 * stride, vext_u8(d02_hi, d1, 3)); - vst1_u8(dst + 3 * stride, vext_u8(d02_hi, d1, 1)); - vst1_u8(dst + 4 * stride, vext_u8(d02_lo, d02_hi, 7)); - vst1_u8(dst + 5 * stride, vext_u8(d02_lo, d02_hi, 5)); - vst1_u8(dst + 6 * stride, vext_u8(d02_lo, d02_hi, 3)); - vst1_u8(dst + 7 * stride, vext_u8(d02_lo, d02_hi, 1)); -} - -void vpx_d153_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - // See vpx_d153_predictor_8x8_neon for more details on the implementation. - uint8x16_t az, a0, l0az, l0, l1, azl0, d0, d1, d2, d02_lo, d02_hi; - - az = vld1q_u8(above - 1); - a0 = vld1q_u8(above + 0); - // [ left[0], above[-1], ... , above[13] ] - l0az = vextq_u8(vld1q_dup_u8(left), az, 15); - - l0 = vld1q_u8(left + 0); - // The last lane here is unused, reading left[16] could cause a buffer - // over-read, so just fill with a duplicate of left[0] to avoid needing to - // materialize a zero: - // [ left[1], ... , left[15], x ] - l1 = vextq_u8(l0, l0, 1); - // [ above[-1], left[0], ... , left[14] ] - azl0 = vextq_u8(vld1q_dup_u8(above - 1), l0, 15); - - d0 = vrhaddq_u8(azl0, l0); - d1 = vrhaddq_u8(vhaddq_u8(l0az, a0), az); - d2 = vrhaddq_u8(vhaddq_u8(azl0, l1), l0); - - d0 = vrev64q_u8(vextq_u8(d0, d0, 8)); - d2 = vrev64q_u8(vextq_u8(d2, d2, 8)); - - // The lowest lane of d02_lo is unused. - d02_lo = vzipq_u8(d2, d0).val[0]; - d02_hi = vzipq_u8(d2, d0).val[1]; - - vst1q_u8(dst + 0 * stride, vextq_u8(d02_hi, d1, 15)); - vst1q_u8(dst + 1 * stride, vextq_u8(d02_hi, d1, 13)); - vst1q_u8(dst + 2 * stride, vextq_u8(d02_hi, d1, 11)); - vst1q_u8(dst + 3 * stride, vextq_u8(d02_hi, d1, 9)); - vst1q_u8(dst + 4 * stride, vextq_u8(d02_hi, d1, 7)); - vst1q_u8(dst + 5 * stride, vextq_u8(d02_hi, d1, 5)); - vst1q_u8(dst + 6 * stride, vextq_u8(d02_hi, d1, 3)); - vst1q_u8(dst + 7 * stride, vextq_u8(d02_hi, d1, 1)); - vst1q_u8(dst + 8 * stride, vextq_u8(d02_lo, d02_hi, 15)); - vst1q_u8(dst + 9 * stride, vextq_u8(d02_lo, d02_hi, 13)); - vst1q_u8(dst + 10 * stride, vextq_u8(d02_lo, d02_hi, 11)); - vst1q_u8(dst + 11 * stride, vextq_u8(d02_lo, d02_hi, 9)); - vst1q_u8(dst + 12 * stride, vextq_u8(d02_lo, d02_hi, 7)); - vst1q_u8(dst + 13 * stride, vextq_u8(d02_lo, d02_hi, 5)); - vst1q_u8(dst + 14 * stride, vextq_u8(d02_lo, d02_hi, 3)); - vst1q_u8(dst + 15 * stride, vextq_u8(d02_lo, d02_hi, 1)); -} - -void vpx_d153_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - // See vpx_d153_predictor_8x8_neon for more details on the implementation. - uint8x16_t az, a0, a14, a15, a16, l0az, l0, l1, l15, l16, l17, azl0, d0_lo, - d0_hi, d1_lo, d1_hi, d2_lo, d2_hi; - uint8x16x2_t d02_hi, d02_lo; - - az = vld1q_u8(above - 1); - a0 = vld1q_u8(above + 0); - a14 = vld1q_u8(above + 14); - a15 = vld1q_u8(above + 15); - a16 = vld1q_u8(above + 16); - // [ left[0], above[-1], ... , above[13] ] - l0az = vextq_u8(vld1q_dup_u8(left), az, 15); - - l0 = vld1q_u8(left); - l1 = vld1q_u8(left + 1); - l15 = vld1q_u8(left + 15); - l16 = vld1q_u8(left + 16); - // The last lane here is unused, reading left[32] would cause a buffer - // over-read (observed as an address-sanitizer failure), so just fill with a - // duplicate of left[16] to avoid needing to materialize a zero: - // [ left[17], ... , left[31], x ] - l17 = vextq_u8(l16, l16, 1); - // [ above[-1], left[0], ... , left[14] ] - azl0 = vextq_u8(vld1q_dup_u8(above - 1), l0, 15); - - d0_lo = vrhaddq_u8(azl0, l0); - d0_hi = vrhaddq_u8(l15, l16); - - d1_lo = vrhaddq_u8(vhaddq_u8(l0az, a0), az); - d1_hi = vrhaddq_u8(vhaddq_u8(a14, a16), a15); - - // The highest lane of d2_hi is unused. - d2_lo = vrhaddq_u8(vhaddq_u8(azl0, l1), l0); - d2_hi = vrhaddq_u8(vhaddq_u8(l15, l17), l16); - - d0_lo = vrev64q_u8(vextq_u8(d0_lo, d0_lo, 8)); - d0_hi = vrev64q_u8(vextq_u8(d0_hi, d0_hi, 8)); - - d2_lo = vrev64q_u8(vextq_u8(d2_lo, d2_lo, 8)); - d2_hi = vrev64q_u8(vextq_u8(d2_hi, d2_hi, 8)); - - // d02_hi.val[0][0] is unused here. - d02_hi = vzipq_u8(d2_hi, d0_hi); - d02_lo = vzipq_u8(d2_lo, d0_lo); - - vst1q_u8(dst + 0 * stride + 0, vextq_u8(d02_lo.val[1], d1_lo, 15)); - vst1q_u8(dst + 0 * stride + 16, vextq_u8(d1_lo, d1_hi, 15)); - vst1q_u8(dst + 1 * stride + 0, vextq_u8(d02_lo.val[1], d1_lo, 13)); - vst1q_u8(dst + 1 * stride + 16, vextq_u8(d1_lo, d1_hi, 13)); - vst1q_u8(dst + 2 * stride + 0, vextq_u8(d02_lo.val[1], d1_lo, 11)); - vst1q_u8(dst + 2 * stride + 16, vextq_u8(d1_lo, d1_hi, 11)); - vst1q_u8(dst + 3 * stride + 0, vextq_u8(d02_lo.val[1], d1_lo, 9)); - vst1q_u8(dst + 3 * stride + 16, vextq_u8(d1_lo, d1_hi, 9)); - vst1q_u8(dst + 4 * stride + 0, vextq_u8(d02_lo.val[1], d1_lo, 7)); - vst1q_u8(dst + 4 * stride + 16, vextq_u8(d1_lo, d1_hi, 7)); - vst1q_u8(dst + 5 * stride + 0, vextq_u8(d02_lo.val[1], d1_lo, 5)); - vst1q_u8(dst + 5 * stride + 16, vextq_u8(d1_lo, d1_hi, 5)); - vst1q_u8(dst + 6 * stride + 0, vextq_u8(d02_lo.val[1], d1_lo, 3)); - vst1q_u8(dst + 6 * stride + 16, vextq_u8(d1_lo, d1_hi, 3)); - vst1q_u8(dst + 7 * stride + 0, vextq_u8(d02_lo.val[1], d1_lo, 1)); - vst1q_u8(dst + 7 * stride + 16, vextq_u8(d1_lo, d1_hi, 1)); - vst1q_u8(dst + 8 * stride + 0, vextq_u8(d02_lo.val[0], d02_lo.val[1], 15)); - vst1q_u8(dst + 8 * stride + 16, vextq_u8(d02_lo.val[1], d1_lo, 15)); - vst1q_u8(dst + 9 * stride + 0, vextq_u8(d02_lo.val[0], d02_lo.val[1], 13)); - vst1q_u8(dst + 9 * stride + 16, vextq_u8(d02_lo.val[1], d1_lo, 13)); - vst1q_u8(dst + 10 * stride + 0, vextq_u8(d02_lo.val[0], d02_lo.val[1], 11)); - vst1q_u8(dst + 10 * stride + 16, vextq_u8(d02_lo.val[1], d1_lo, 11)); - vst1q_u8(dst + 11 * stride + 0, vextq_u8(d02_lo.val[0], d02_lo.val[1], 9)); - vst1q_u8(dst + 11 * stride + 16, vextq_u8(d02_lo.val[1], d1_lo, 9)); - vst1q_u8(dst + 12 * stride + 0, vextq_u8(d02_lo.val[0], d02_lo.val[1], 7)); - vst1q_u8(dst + 12 * stride + 16, vextq_u8(d02_lo.val[1], d1_lo, 7)); - vst1q_u8(dst + 13 * stride + 0, vextq_u8(d02_lo.val[0], d02_lo.val[1], 5)); - vst1q_u8(dst + 13 * stride + 16, vextq_u8(d02_lo.val[1], d1_lo, 5)); - vst1q_u8(dst + 14 * stride + 0, vextq_u8(d02_lo.val[0], d02_lo.val[1], 3)); - vst1q_u8(dst + 14 * stride + 16, vextq_u8(d02_lo.val[1], d1_lo, 3)); - vst1q_u8(dst + 15 * stride + 0, vextq_u8(d02_lo.val[0], d02_lo.val[1], 1)); - vst1q_u8(dst + 15 * stride + 16, vextq_u8(d02_lo.val[1], d1_lo, 1)); - vst1q_u8(dst + 16 * stride + 0, vextq_u8(d02_hi.val[1], d02_lo.val[0], 15)); - vst1q_u8(dst + 16 * stride + 16, vextq_u8(d02_lo.val[0], d02_lo.val[1], 15)); - vst1q_u8(dst + 17 * stride + 0, vextq_u8(d02_hi.val[1], d02_lo.val[0], 13)); - vst1q_u8(dst + 17 * stride + 16, vextq_u8(d02_lo.val[0], d02_lo.val[1], 13)); - vst1q_u8(dst + 18 * stride + 0, vextq_u8(d02_hi.val[1], d02_lo.val[0], 11)); - vst1q_u8(dst + 18 * stride + 16, vextq_u8(d02_lo.val[0], d02_lo.val[1], 11)); - vst1q_u8(dst + 19 * stride + 0, vextq_u8(d02_hi.val[1], d02_lo.val[0], 9)); - vst1q_u8(dst + 19 * stride + 16, vextq_u8(d02_lo.val[0], d02_lo.val[1], 9)); - vst1q_u8(dst + 20 * stride + 0, vextq_u8(d02_hi.val[1], d02_lo.val[0], 7)); - vst1q_u8(dst + 20 * stride + 16, vextq_u8(d02_lo.val[0], d02_lo.val[1], 7)); - vst1q_u8(dst + 21 * stride + 0, vextq_u8(d02_hi.val[1], d02_lo.val[0], 5)); - vst1q_u8(dst + 21 * stride + 16, vextq_u8(d02_lo.val[0], d02_lo.val[1], 5)); - vst1q_u8(dst + 22 * stride + 0, vextq_u8(d02_hi.val[1], d02_lo.val[0], 3)); - vst1q_u8(dst + 22 * stride + 16, vextq_u8(d02_lo.val[0], d02_lo.val[1], 3)); - vst1q_u8(dst + 23 * stride + 0, vextq_u8(d02_hi.val[1], d02_lo.val[0], 1)); - vst1q_u8(dst + 23 * stride + 16, vextq_u8(d02_lo.val[0], d02_lo.val[1], 1)); - vst1q_u8(dst + 24 * stride + 0, vextq_u8(d02_hi.val[0], d02_hi.val[1], 15)); - vst1q_u8(dst + 24 * stride + 16, vextq_u8(d02_hi.val[1], d02_lo.val[0], 15)); - vst1q_u8(dst + 25 * stride + 0, vextq_u8(d02_hi.val[0], d02_hi.val[1], 13)); - vst1q_u8(dst + 25 * stride + 16, vextq_u8(d02_hi.val[1], d02_lo.val[0], 13)); - vst1q_u8(dst + 26 * stride + 0, vextq_u8(d02_hi.val[0], d02_hi.val[1], 11)); - vst1q_u8(dst + 26 * stride + 16, vextq_u8(d02_hi.val[1], d02_lo.val[0], 11)); - vst1q_u8(dst + 27 * stride + 0, vextq_u8(d02_hi.val[0], d02_hi.val[1], 9)); - vst1q_u8(dst + 27 * stride + 16, vextq_u8(d02_hi.val[1], d02_lo.val[0], 9)); - vst1q_u8(dst + 28 * stride + 0, vextq_u8(d02_hi.val[0], d02_hi.val[1], 7)); - vst1q_u8(dst + 28 * stride + 16, vextq_u8(d02_hi.val[1], d02_lo.val[0], 7)); - vst1q_u8(dst + 29 * stride + 0, vextq_u8(d02_hi.val[0], d02_hi.val[1], 5)); - vst1q_u8(dst + 29 * stride + 16, vextq_u8(d02_hi.val[1], d02_lo.val[0], 5)); - vst1q_u8(dst + 30 * stride + 0, vextq_u8(d02_hi.val[0], d02_hi.val[1], 3)); - vst1q_u8(dst + 30 * stride + 16, vextq_u8(d02_hi.val[1], d02_lo.val[0], 3)); - vst1q_u8(dst + 31 * stride + 0, vextq_u8(d02_hi.val[0], d02_hi.val[1], 1)); - vst1q_u8(dst + 31 * stride + 16, vextq_u8(d02_hi.val[1], d02_lo.val[0], 1)); -} - -// ----------------------------------------------------------------------------- - -void vpx_d207_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - uint8x8_t l0, l3, l1, l2, c0, c1, c01, d0, d1; - (void)above; - - // We need the low half lanes here for the c0/c1 arithmetic but the high half - // lanes for the ext: - // [ left[0], left[1], left[2], left[3], left[0], left[1], left[2], left[3] ] - l0 = load_replicate_u8_4x1(left + 0); - l3 = vld1_dup_u8(left + 3); - - // [ left[1], left[2], left[3], left[3], x, x, x, x ] - l1 = vext_u8(l0, l3, 5); - // [ left[2], left[3], left[3], left[3], x, x, x, x ] - l2 = vext_u8(l0, l3, 6); - - c0 = vrhadd_u8(l0, l1); - c1 = vrhadd_u8(vhadd_u8(l0, l2), l1); - - // [ c0[0], c1[0], c0[1], c1[1], c0[2], c1[2], c0[3], c1[3] ] - c01 = vzip_u8(c0, c1).val[0]; - - d0 = c01; - d1 = vext_u8(c01, l3, 2); - - // Store the high half of the vector for stride={2,3} to avoid needing - // additional ext instructions: - // stride=0 [ c0[0], c1[0], c0[1], c1[1] ] - // stride=1 [ c0[1], c1[1], c0[2], c1[2] ] - // stride=2 [ c0[2], c1[2], c0[3], c1[3] ] - // stride=3 [ c0[3], c1[3], left[3], left[3] ] - store_u8_4x1(dst + 0 * stride, d0); - store_u8_4x1(dst + 1 * stride, d1); - store_u8_4x1_high(dst + 2 * stride, d0); - store_u8_4x1_high(dst + 3 * stride, d1); -} - -void vpx_d207_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - uint8x8_t l7, l0, l1, l2, c0, c1, c01_lo, c01_hi; - (void)above; - - l0 = vld1_u8(left + 0); - l7 = vld1_dup_u8(left + 7); - - // [ left[1], left[2], left[3], left[4], left[5], left[6], left[7], left[7] ] - l1 = vext_u8(l0, l7, 1); - // [ left[2], left[3], left[4], left[5], left[6], left[7], left[7], left[7] ] - l2 = vext_u8(l0, l7, 2); - - c0 = vrhadd_u8(l0, l1); - c1 = vrhadd_u8(vhadd_u8(l0, l2), l1); - - c01_lo = vzip_u8(c0, c1).val[0]; - c01_hi = vzip_u8(c0, c1).val[1]; - - vst1_u8(dst + 0 * stride, c01_lo); - vst1_u8(dst + 1 * stride, vext_u8(c01_lo, c01_hi, 2)); - vst1_u8(dst + 2 * stride, vext_u8(c01_lo, c01_hi, 4)); - vst1_u8(dst + 3 * stride, vext_u8(c01_lo, c01_hi, 6)); - vst1_u8(dst + 4 * stride, c01_hi); - vst1_u8(dst + 5 * stride, vext_u8(c01_hi, l7, 2)); - vst1_u8(dst + 6 * stride, vext_u8(c01_hi, l7, 4)); - vst1_u8(dst + 7 * stride, vext_u8(c01_hi, l7, 6)); -} - -void vpx_d207_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - uint8x16_t l15, l0, l1, l2, c0, c1, c01_lo, c01_hi; - (void)above; - - l0 = vld1q_u8(left + 0); - l15 = vld1q_dup_u8(left + 15); - - l1 = vextq_u8(l0, l15, 1); - l2 = vextq_u8(l0, l15, 2); - - c0 = vrhaddq_u8(l0, l1); - c1 = vrhaddq_u8(vhaddq_u8(l0, l2), l1); - - c01_lo = vzipq_u8(c0, c1).val[0]; - c01_hi = vzipq_u8(c0, c1).val[1]; - - vst1q_u8(dst + 0 * stride, c01_lo); - vst1q_u8(dst + 1 * stride, vextq_u8(c01_lo, c01_hi, 2)); - vst1q_u8(dst + 2 * stride, vextq_u8(c01_lo, c01_hi, 4)); - vst1q_u8(dst + 3 * stride, vextq_u8(c01_lo, c01_hi, 6)); - vst1q_u8(dst + 4 * stride, vextq_u8(c01_lo, c01_hi, 8)); - vst1q_u8(dst + 5 * stride, vextq_u8(c01_lo, c01_hi, 10)); - vst1q_u8(dst + 6 * stride, vextq_u8(c01_lo, c01_hi, 12)); - vst1q_u8(dst + 7 * stride, vextq_u8(c01_lo, c01_hi, 14)); - vst1q_u8(dst + 8 * stride, c01_hi); - vst1q_u8(dst + 9 * stride, vextq_u8(c01_hi, l15, 2)); - vst1q_u8(dst + 10 * stride, vextq_u8(c01_hi, l15, 4)); - vst1q_u8(dst + 11 * stride, vextq_u8(c01_hi, l15, 6)); - vst1q_u8(dst + 12 * stride, vextq_u8(c01_hi, l15, 8)); - vst1q_u8(dst + 13 * stride, vextq_u8(c01_hi, l15, 10)); - vst1q_u8(dst + 14 * stride, vextq_u8(c01_hi, l15, 12)); - vst1q_u8(dst + 15 * stride, vextq_u8(c01_hi, l15, 14)); -} - -void vpx_d207_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - uint8x16_t l0_lo, l0_hi, l1_lo, l1_hi, l2_lo, l2_hi, l31, c0_lo, c0_hi, c1_lo, - c1_hi, c01[4]; - (void)above; - - l0_lo = vld1q_u8(left + 0); - l0_hi = vld1q_u8(left + 16); - l31 = vld1q_dup_u8(left + 31); - - l1_lo = vextq_u8(l0_lo, l0_hi, 1); - l1_hi = vextq_u8(l0_hi, l31, 1); - l2_lo = vextq_u8(l0_lo, l0_hi, 2); - l2_hi = vextq_u8(l0_hi, l31, 2); - - c0_lo = vrhaddq_u8(l0_lo, l1_lo); - c0_hi = vrhaddq_u8(l0_hi, l1_hi); - c1_lo = vrhaddq_u8(vhaddq_u8(l0_lo, l2_lo), l1_lo); - c1_hi = vrhaddq_u8(vhaddq_u8(l0_hi, l2_hi), l1_hi); - - c01[0] = vzipq_u8(c0_lo, c1_lo).val[0]; - c01[1] = vzipq_u8(c0_lo, c1_lo).val[1]; - c01[2] = vzipq_u8(c0_hi, c1_hi).val[0]; - c01[3] = vzipq_u8(c0_hi, c1_hi).val[1]; - - vst1q_u8(dst + 0 * stride + 0, c01[0]); - vst1q_u8(dst + 0 * stride + 16, c01[1]); - vst1q_u8(dst + 1 * stride + 0, vextq_u8(c01[0], c01[1], 2)); - vst1q_u8(dst + 1 * stride + 16, vextq_u8(c01[1], c01[2], 2)); - vst1q_u8(dst + 2 * stride + 0, vextq_u8(c01[0], c01[1], 4)); - vst1q_u8(dst + 2 * stride + 16, vextq_u8(c01[1], c01[2], 4)); - vst1q_u8(dst + 3 * stride + 0, vextq_u8(c01[0], c01[1], 6)); - vst1q_u8(dst + 3 * stride + 16, vextq_u8(c01[1], c01[2], 6)); - vst1q_u8(dst + 4 * stride + 0, vextq_u8(c01[0], c01[1], 8)); - vst1q_u8(dst + 4 * stride + 16, vextq_u8(c01[1], c01[2], 8)); - vst1q_u8(dst + 5 * stride + 0, vextq_u8(c01[0], c01[1], 10)); - vst1q_u8(dst + 5 * stride + 16, vextq_u8(c01[1], c01[2], 10)); - vst1q_u8(dst + 6 * stride + 0, vextq_u8(c01[0], c01[1], 12)); - vst1q_u8(dst + 6 * stride + 16, vextq_u8(c01[1], c01[2], 12)); - vst1q_u8(dst + 7 * stride + 0, vextq_u8(c01[0], c01[1], 14)); - vst1q_u8(dst + 7 * stride + 16, vextq_u8(c01[1], c01[2], 14)); - vst1q_u8(dst + 8 * stride + 0, c01[1]); - vst1q_u8(dst + 8 * stride + 16, c01[2]); - vst1q_u8(dst + 9 * stride + 0, vextq_u8(c01[1], c01[2], 2)); - vst1q_u8(dst + 9 * stride + 16, vextq_u8(c01[2], c01[3], 2)); - vst1q_u8(dst + 10 * stride + 0, vextq_u8(c01[1], c01[2], 4)); - vst1q_u8(dst + 10 * stride + 16, vextq_u8(c01[2], c01[3], 4)); - vst1q_u8(dst + 11 * stride + 0, vextq_u8(c01[1], c01[2], 6)); - vst1q_u8(dst + 11 * stride + 16, vextq_u8(c01[2], c01[3], 6)); - vst1q_u8(dst + 12 * stride + 0, vextq_u8(c01[1], c01[2], 8)); - vst1q_u8(dst + 12 * stride + 16, vextq_u8(c01[2], c01[3], 8)); - vst1q_u8(dst + 13 * stride + 0, vextq_u8(c01[1], c01[2], 10)); - vst1q_u8(dst + 13 * stride + 16, vextq_u8(c01[2], c01[3], 10)); - vst1q_u8(dst + 14 * stride + 0, vextq_u8(c01[1], c01[2], 12)); - vst1q_u8(dst + 14 * stride + 16, vextq_u8(c01[2], c01[3], 12)); - vst1q_u8(dst + 15 * stride + 0, vextq_u8(c01[1], c01[2], 14)); - vst1q_u8(dst + 15 * stride + 16, vextq_u8(c01[2], c01[3], 14)); - vst1q_u8(dst + 16 * stride + 0, c01[2]); - vst1q_u8(dst + 16 * stride + 16, c01[3]); - vst1q_u8(dst + 17 * stride + 0, vextq_u8(c01[2], c01[3], 2)); - vst1q_u8(dst + 17 * stride + 16, vextq_u8(c01[3], l31, 2)); - vst1q_u8(dst + 18 * stride + 0, vextq_u8(c01[2], c01[3], 4)); - vst1q_u8(dst + 18 * stride + 16, vextq_u8(c01[3], l31, 4)); - vst1q_u8(dst + 19 * stride + 0, vextq_u8(c01[2], c01[3], 6)); - vst1q_u8(dst + 19 * stride + 16, vextq_u8(c01[3], l31, 6)); - vst1q_u8(dst + 20 * stride + 0, vextq_u8(c01[2], c01[3], 8)); - vst1q_u8(dst + 20 * stride + 16, vextq_u8(c01[3], l31, 8)); - vst1q_u8(dst + 21 * stride + 0, vextq_u8(c01[2], c01[3], 10)); - vst1q_u8(dst + 21 * stride + 16, vextq_u8(c01[3], l31, 10)); - vst1q_u8(dst + 22 * stride + 0, vextq_u8(c01[2], c01[3], 12)); - vst1q_u8(dst + 22 * stride + 16, vextq_u8(c01[3], l31, 12)); - vst1q_u8(dst + 23 * stride + 0, vextq_u8(c01[2], c01[3], 14)); - vst1q_u8(dst + 23 * stride + 16, vextq_u8(c01[3], l31, 14)); - vst1q_u8(dst + 24 * stride + 0, c01[3]); - vst1q_u8(dst + 24 * stride + 16, l31); - vst1q_u8(dst + 25 * stride + 0, vextq_u8(c01[3], l31, 2)); - vst1q_u8(dst + 25 * stride + 16, l31); - vst1q_u8(dst + 26 * stride + 0, vextq_u8(c01[3], l31, 4)); - vst1q_u8(dst + 26 * stride + 16, l31); - vst1q_u8(dst + 27 * stride + 0, vextq_u8(c01[3], l31, 6)); - vst1q_u8(dst + 27 * stride + 16, l31); - vst1q_u8(dst + 28 * stride + 0, vextq_u8(c01[3], l31, 8)); - vst1q_u8(dst + 28 * stride + 16, l31); - vst1q_u8(dst + 29 * stride + 0, vextq_u8(c01[3], l31, 10)); - vst1q_u8(dst + 29 * stride + 16, l31); - vst1q_u8(dst + 30 * stride + 0, vextq_u8(c01[3], l31, 12)); - vst1q_u8(dst + 30 * stride + 16, l31); - vst1q_u8(dst + 31 * stride + 0, vextq_u8(c01[3], l31, 14)); - vst1q_u8(dst + 31 * stride + 16, l31); -} - -// ----------------------------------------------------------------------------- - -#if !HAVE_NEON_ASM - -void vpx_v_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint32_t d = *(const uint32_t *)above; - int i; - (void)left; - - for (i = 0; i < 4; i++, dst += stride) { - *(uint32_t *)dst = d; - } -} - -void vpx_v_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x8_t d = vld1_u8(above); - int i; - (void)left; - - for (i = 0; i < 8; i++, dst += stride) { - vst1_u8(dst, d); - } -} - -void vpx_v_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t d = vld1q_u8(above); - int i; - (void)left; - - for (i = 0; i < 16; i++, dst += stride) { - vst1q_u8(dst, d); - } -} - -void vpx_v_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t d0 = vld1q_u8(above); - const uint8x16_t d1 = vld1q_u8(above + 16); - int i; - (void)left; - - for (i = 0; i < 32; i++) { - // Note: performance was worse using vst2q_u8 under gcc-4.9 & clang-3.8. - // clang-3.8 unrolled the loop fully with no filler so the cause is likely - // the latency of the instruction. - vst1q_u8(dst, d0); - dst += 16; - vst1q_u8(dst, d1); - dst += stride - 16; - } -} - -// ----------------------------------------------------------------------------- - -void vpx_h_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint32x2_t zero = vdup_n_u32(0); - const uint8x8_t left_u8 = - vreinterpret_u8_u32(vld1_lane_u32((const uint32_t *)left, zero, 0)); - uint8x8_t d; - (void)above; - - d = vdup_lane_u8(left_u8, 0); - vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d), 0); - dst += stride; - d = vdup_lane_u8(left_u8, 1); - vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d), 0); - dst += stride; - d = vdup_lane_u8(left_u8, 2); - vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d), 0); - dst += stride; - d = vdup_lane_u8(left_u8, 3); - vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d), 0); -} - -void vpx_h_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x8_t left_u8 = vld1_u8(left); - uint8x8_t d; - (void)above; - - d = vdup_lane_u8(left_u8, 0); - vst1_u8(dst, d); - dst += stride; - d = vdup_lane_u8(left_u8, 1); - vst1_u8(dst, d); - dst += stride; - d = vdup_lane_u8(left_u8, 2); - vst1_u8(dst, d); - dst += stride; - d = vdup_lane_u8(left_u8, 3); - vst1_u8(dst, d); - dst += stride; - d = vdup_lane_u8(left_u8, 4); - vst1_u8(dst, d); - dst += stride; - d = vdup_lane_u8(left_u8, 5); - vst1_u8(dst, d); - dst += stride; - d = vdup_lane_u8(left_u8, 6); - vst1_u8(dst, d); - dst += stride; - d = vdup_lane_u8(left_u8, 7); - vst1_u8(dst, d); -} - -static INLINE void h_store_16x8(uint8_t **dst, const ptrdiff_t stride, - const uint8x8_t left) { - const uint8x16_t row_0 = vdupq_lane_u8(left, 0); - const uint8x16_t row_1 = vdupq_lane_u8(left, 1); - const uint8x16_t row_2 = vdupq_lane_u8(left, 2); - const uint8x16_t row_3 = vdupq_lane_u8(left, 3); - const uint8x16_t row_4 = vdupq_lane_u8(left, 4); - const uint8x16_t row_5 = vdupq_lane_u8(left, 5); - const uint8x16_t row_6 = vdupq_lane_u8(left, 6); - const uint8x16_t row_7 = vdupq_lane_u8(left, 7); - - vst1q_u8(*dst, row_0); - *dst += stride; - vst1q_u8(*dst, row_1); - *dst += stride; - vst1q_u8(*dst, row_2); - *dst += stride; - vst1q_u8(*dst, row_3); - *dst += stride; - vst1q_u8(*dst, row_4); - *dst += stride; - vst1q_u8(*dst, row_5); - *dst += stride; - vst1q_u8(*dst, row_6); - *dst += stride; - vst1q_u8(*dst, row_7); - *dst += stride; -} - -void vpx_h_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t left_u8q = vld1q_u8(left); - (void)above; - - h_store_16x8(&dst, stride, vget_low_u8(left_u8q)); - h_store_16x8(&dst, stride, vget_high_u8(left_u8q)); -} - -static INLINE void h_store_32x8(uint8_t **dst, const ptrdiff_t stride, - const uint8x8_t left) { - const uint8x16_t row_0 = vdupq_lane_u8(left, 0); - const uint8x16_t row_1 = vdupq_lane_u8(left, 1); - const uint8x16_t row_2 = vdupq_lane_u8(left, 2); - const uint8x16_t row_3 = vdupq_lane_u8(left, 3); - const uint8x16_t row_4 = vdupq_lane_u8(left, 4); - const uint8x16_t row_5 = vdupq_lane_u8(left, 5); - const uint8x16_t row_6 = vdupq_lane_u8(left, 6); - const uint8x16_t row_7 = vdupq_lane_u8(left, 7); - - vst1q_u8(*dst, row_0); // Note clang-3.8 produced poor code w/vst2q_u8 - *dst += 16; - vst1q_u8(*dst, row_0); - *dst += stride - 16; - vst1q_u8(*dst, row_1); - *dst += 16; - vst1q_u8(*dst, row_1); - *dst += stride - 16; - vst1q_u8(*dst, row_2); - *dst += 16; - vst1q_u8(*dst, row_2); - *dst += stride - 16; - vst1q_u8(*dst, row_3); - *dst += 16; - vst1q_u8(*dst, row_3); - *dst += stride - 16; - vst1q_u8(*dst, row_4); - *dst += 16; - vst1q_u8(*dst, row_4); - *dst += stride - 16; - vst1q_u8(*dst, row_5); - *dst += 16; - vst1q_u8(*dst, row_5); - *dst += stride - 16; - vst1q_u8(*dst, row_6); - *dst += 16; - vst1q_u8(*dst, row_6); - *dst += stride - 16; - vst1q_u8(*dst, row_7); - *dst += 16; - vst1q_u8(*dst, row_7); - *dst += stride - 16; -} - -void vpx_h_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - int i; - (void)above; - - for (i = 0; i < 2; i++, left += 16) { - const uint8x16_t left_u8 = vld1q_u8(left); - h_store_32x8(&dst, stride, vget_low_u8(left_u8)); - h_store_32x8(&dst, stride, vget_high_u8(left_u8)); - } -} - -// ----------------------------------------------------------------------------- - -static INLINE int16x8_t convert_u8_to_s16(uint8x8_t v) { - return vreinterpretq_s16_u16(vmovl_u8(v)); -} - -void vpx_tm_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x8_t top_left = vld1_dup_u8(above - 1); - const uint8x8_t left_u8 = vld1_u8(left); - const uint8x8_t above_u8 = vld1_u8(above); - const int16x4_t left_s16 = vget_low_s16(convert_u8_to_s16(left_u8)); - int16x8_t sub, sum; - uint32x2_t d; - - sub = vreinterpretq_s16_u16(vsubl_u8(above_u8, top_left)); - // Avoid vcombine_s16() which generates lots of redundant code with clang-3.8. - sub = vreinterpretq_s16_s64( - vdupq_lane_s64(vreinterpret_s64_s16(vget_low_s16(sub)), 0)); - - sum = vcombine_s16(vdup_lane_s16(left_s16, 0), vdup_lane_s16(left_s16, 1)); - sum = vaddq_s16(sum, sub); - d = vreinterpret_u32_u8(vqmovun_s16(sum)); - vst1_lane_u32((uint32_t *)dst, d, 0); - dst += stride; - vst1_lane_u32((uint32_t *)dst, d, 1); - dst += stride; - - sum = vcombine_s16(vdup_lane_s16(left_s16, 2), vdup_lane_s16(left_s16, 3)); - sum = vaddq_s16(sum, sub); - d = vreinterpret_u32_u8(vqmovun_s16(sum)); - vst1_lane_u32((uint32_t *)dst, d, 0); - dst += stride; - vst1_lane_u32((uint32_t *)dst, d, 1); -} - -static INLINE void tm_8_kernel(uint8_t **dst, const ptrdiff_t stride, - const int16x8_t left_dup, const int16x8_t sub) { - const int16x8_t sum = vaddq_s16(left_dup, sub); - const uint8x8_t d = vqmovun_s16(sum); - vst1_u8(*dst, d); - *dst += stride; -} - -void vpx_tm_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x8_t top_left = vld1_dup_u8(above - 1); - const uint8x8_t above_u8 = vld1_u8(above); - const uint8x8_t left_u8 = vld1_u8(left); - const int16x8_t left_s16q = convert_u8_to_s16(left_u8); - const int16x8_t sub = vreinterpretq_s16_u16(vsubl_u8(above_u8, top_left)); - int16x4_t left_s16d = vget_low_s16(left_s16q); - int i; - - for (i = 0; i < 2; i++, left_s16d = vget_high_s16(left_s16q)) { - int16x8_t left_dup; - - left_dup = vdupq_lane_s16(left_s16d, 0); - tm_8_kernel(&dst, stride, left_dup, sub); - left_dup = vdupq_lane_s16(left_s16d, 1); - tm_8_kernel(&dst, stride, left_dup, sub); - left_dup = vdupq_lane_s16(left_s16d, 2); - tm_8_kernel(&dst, stride, left_dup, sub); - left_dup = vdupq_lane_s16(left_s16d, 3); - tm_8_kernel(&dst, stride, left_dup, sub); - } -} - -static INLINE void tm_16_kernel(uint8_t **dst, const ptrdiff_t stride, - const int16x8_t left_dup, const int16x8_t sub0, - const int16x8_t sub1) { - const int16x8_t sum0 = vaddq_s16(left_dup, sub0); - const int16x8_t sum1 = vaddq_s16(left_dup, sub1); - const uint8x8_t d0 = vqmovun_s16(sum0); - const uint8x8_t d1 = vqmovun_s16(sum1); - vst1_u8(*dst, d0); - *dst += 8; - vst1_u8(*dst, d1); - *dst += stride - 8; -} - -void vpx_tm_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t top_left = vld1q_dup_u8(above - 1); - const uint8x16_t above_u8 = vld1q_u8(above); - const int16x8_t sub0 = vreinterpretq_s16_u16( - vsubl_u8(vget_low_u8(above_u8), vget_low_u8(top_left))); - const int16x8_t sub1 = vreinterpretq_s16_u16( - vsubl_u8(vget_high_u8(above_u8), vget_high_u8(top_left))); - int16x8_t left_dup; - int i; - - for (i = 0; i < 2; i++, left += 8) { - const uint8x8_t left_u8 = vld1_u8(left); - const int16x8_t left_s16q = convert_u8_to_s16(left_u8); - const int16x4_t left_low = vget_low_s16(left_s16q); - const int16x4_t left_high = vget_high_s16(left_s16q); - - left_dup = vdupq_lane_s16(left_low, 0); - tm_16_kernel(&dst, stride, left_dup, sub0, sub1); - left_dup = vdupq_lane_s16(left_low, 1); - tm_16_kernel(&dst, stride, left_dup, sub0, sub1); - left_dup = vdupq_lane_s16(left_low, 2); - tm_16_kernel(&dst, stride, left_dup, sub0, sub1); - left_dup = vdupq_lane_s16(left_low, 3); - tm_16_kernel(&dst, stride, left_dup, sub0, sub1); - - left_dup = vdupq_lane_s16(left_high, 0); - tm_16_kernel(&dst, stride, left_dup, sub0, sub1); - left_dup = vdupq_lane_s16(left_high, 1); - tm_16_kernel(&dst, stride, left_dup, sub0, sub1); - left_dup = vdupq_lane_s16(left_high, 2); - tm_16_kernel(&dst, stride, left_dup, sub0, sub1); - left_dup = vdupq_lane_s16(left_high, 3); - tm_16_kernel(&dst, stride, left_dup, sub0, sub1); - } -} - -static INLINE void tm_32_kernel(uint8_t **dst, const ptrdiff_t stride, - const int16x8_t left_dup, const int16x8_t sub0, - const int16x8_t sub1, const int16x8_t sub2, - const int16x8_t sub3) { - const int16x8_t sum0 = vaddq_s16(left_dup, sub0); - const int16x8_t sum1 = vaddq_s16(left_dup, sub1); - const int16x8_t sum2 = vaddq_s16(left_dup, sub2); - const int16x8_t sum3 = vaddq_s16(left_dup, sub3); - const uint8x8_t d0 = vqmovun_s16(sum0); - const uint8x8_t d1 = vqmovun_s16(sum1); - const uint8x8_t d2 = vqmovun_s16(sum2); - const uint8x8_t d3 = vqmovun_s16(sum3); - - vst1q_u8(*dst, vcombine_u8(d0, d1)); - *dst += 16; - vst1q_u8(*dst, vcombine_u8(d2, d3)); - *dst += stride - 16; -} - -void vpx_tm_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t top_left = vld1q_dup_u8(above - 1); - const uint8x16_t above_low = vld1q_u8(above); - const uint8x16_t above_high = vld1q_u8(above + 16); - const int16x8_t sub0 = vreinterpretq_s16_u16( - vsubl_u8(vget_low_u8(above_low), vget_low_u8(top_left))); - const int16x8_t sub1 = vreinterpretq_s16_u16( - vsubl_u8(vget_high_u8(above_low), vget_high_u8(top_left))); - const int16x8_t sub2 = vreinterpretq_s16_u16( - vsubl_u8(vget_low_u8(above_high), vget_low_u8(top_left))); - const int16x8_t sub3 = vreinterpretq_s16_u16( - vsubl_u8(vget_high_u8(above_high), vget_high_u8(top_left))); - int16x8_t left_dup; - int i, j; - - for (j = 0; j < 4; j++, left += 8) { - const uint8x8_t left_u8 = vld1_u8(left); - const int16x8_t left_s16q = convert_u8_to_s16(left_u8); - int16x4_t left_s16d = vget_low_s16(left_s16q); - for (i = 0; i < 2; i++, left_s16d = vget_high_s16(left_s16q)) { - left_dup = vdupq_lane_s16(left_s16d, 0); - tm_32_kernel(&dst, stride, left_dup, sub0, sub1, sub2, sub3); - left_dup = vdupq_lane_s16(left_s16d, 1); - tm_32_kernel(&dst, stride, left_dup, sub0, sub1, sub2, sub3); - left_dup = vdupq_lane_s16(left_s16d, 2); - tm_32_kernel(&dst, stride, left_dup, sub0, sub1, sub2, sub3); - left_dup = vdupq_lane_s16(left_s16d, 3); - tm_32_kernel(&dst, stride, left_dup, sub0, sub1, sub2, sub3); - } - } -} -#endif // !HAVE_NEON_ASM diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/intrapred_neon_asm.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/intrapred_neon_asm.asm deleted file mode 100644 index 115790d4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/intrapred_neon_asm.asm +++ /dev/null @@ -1,630 +0,0 @@ -; -; Copyright (c) 2014 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - EXPORT |vpx_v_predictor_4x4_neon| - EXPORT |vpx_v_predictor_8x8_neon| - EXPORT |vpx_v_predictor_16x16_neon| - EXPORT |vpx_v_predictor_32x32_neon| - EXPORT |vpx_h_predictor_4x4_neon| - EXPORT |vpx_h_predictor_8x8_neon| - EXPORT |vpx_h_predictor_16x16_neon| - EXPORT |vpx_h_predictor_32x32_neon| - EXPORT |vpx_tm_predictor_4x4_neon| - EXPORT |vpx_tm_predictor_8x8_neon| - EXPORT |vpx_tm_predictor_16x16_neon| - EXPORT |vpx_tm_predictor_32x32_neon| - ARM - REQUIRE8 - PRESERVE8 - - AREA ||.text||, CODE, READONLY, ALIGN=2 - -;void vpx_v_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, -; const uint8_t *above, -; const uint8_t *left) -; r0 uint8_t *dst -; r1 ptrdiff_t y_stride -; r2 const uint8_t *above -; r3 const uint8_t *left - -|vpx_v_predictor_4x4_neon| PROC - vld1.32 {d0[0]}, [r2] - vst1.32 {d0[0]}, [r0], r1 - vst1.32 {d0[0]}, [r0], r1 - vst1.32 {d0[0]}, [r0], r1 - vst1.32 {d0[0]}, [r0], r1 - bx lr - ENDP ; |vpx_v_predictor_4x4_neon| - -;void vpx_v_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, -; const uint8_t *above, -; const uint8_t *left) -; r0 uint8_t *dst -; r1 ptrdiff_t y_stride -; r2 const uint8_t *above -; r3 const uint8_t *left - -|vpx_v_predictor_8x8_neon| PROC - vld1.8 {d0}, [r2] - vst1.8 {d0}, [r0], r1 - vst1.8 {d0}, [r0], r1 - vst1.8 {d0}, [r0], r1 - vst1.8 {d0}, [r0], r1 - vst1.8 {d0}, [r0], r1 - vst1.8 {d0}, [r0], r1 - vst1.8 {d0}, [r0], r1 - vst1.8 {d0}, [r0], r1 - bx lr - ENDP ; |vpx_v_predictor_8x8_neon| - -;void vpx_v_predictor_16x16_neon(uint8_t *dst, ptrdiff_t y_stride, -; const uint8_t *above, -; const uint8_t *left) -; r0 uint8_t *dst -; r1 ptrdiff_t y_stride -; r2 const uint8_t *above -; r3 const uint8_t *left - -|vpx_v_predictor_16x16_neon| PROC - vld1.8 {q0}, [r2] - vst1.8 {q0}, [r0], r1 - vst1.8 {q0}, [r0], r1 - vst1.8 {q0}, [r0], r1 - vst1.8 {q0}, [r0], r1 - vst1.8 {q0}, [r0], r1 - vst1.8 {q0}, [r0], r1 - vst1.8 {q0}, [r0], r1 - vst1.8 {q0}, [r0], r1 - vst1.8 {q0}, [r0], r1 - vst1.8 {q0}, [r0], r1 - vst1.8 {q0}, [r0], r1 - vst1.8 {q0}, [r0], r1 - vst1.8 {q0}, [r0], r1 - vst1.8 {q0}, [r0], r1 - vst1.8 {q0}, [r0], r1 - vst1.8 {q0}, [r0], r1 - bx lr - ENDP ; |vpx_v_predictor_16x16_neon| - -;void vpx_v_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, -; const uint8_t *above, -; const uint8_t *left) -; r0 uint8_t *dst -; r1 ptrdiff_t y_stride -; r2 const uint8_t *above -; r3 const uint8_t *left - -|vpx_v_predictor_32x32_neon| PROC - vld1.8 {q0, q1}, [r2] - mov r2, #2 -loop_v - vst1.8 {q0, q1}, [r0], r1 - vst1.8 {q0, q1}, [r0], r1 - vst1.8 {q0, q1}, [r0], r1 - vst1.8 {q0, q1}, [r0], r1 - vst1.8 {q0, q1}, [r0], r1 - vst1.8 {q0, q1}, [r0], r1 - vst1.8 {q0, q1}, [r0], r1 - vst1.8 {q0, q1}, [r0], r1 - vst1.8 {q0, q1}, [r0], r1 - vst1.8 {q0, q1}, [r0], r1 - vst1.8 {q0, q1}, [r0], r1 - vst1.8 {q0, q1}, [r0], r1 - vst1.8 {q0, q1}, [r0], r1 - vst1.8 {q0, q1}, [r0], r1 - vst1.8 {q0, q1}, [r0], r1 - vst1.8 {q0, q1}, [r0], r1 - subs r2, r2, #1 - bgt loop_v - bx lr - ENDP ; |vpx_v_predictor_32x32_neon| - -;void vpx_h_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, -; const uint8_t *above, -; const uint8_t *left) -; r0 uint8_t *dst -; r1 ptrdiff_t y_stride -; r2 const uint8_t *above -; r3 const uint8_t *left - -|vpx_h_predictor_4x4_neon| PROC - vld1.32 {d1[0]}, [r3] - vdup.8 d0, d1[0] - vst1.32 {d0[0]}, [r0], r1 - vdup.8 d0, d1[1] - vst1.32 {d0[0]}, [r0], r1 - vdup.8 d0, d1[2] - vst1.32 {d0[0]}, [r0], r1 - vdup.8 d0, d1[3] - vst1.32 {d0[0]}, [r0], r1 - bx lr - ENDP ; |vpx_h_predictor_4x4_neon| - -;void vpx_h_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, -; const uint8_t *above, -; const uint8_t *left) -; r0 uint8_t *dst -; r1 ptrdiff_t y_stride -; r2 const uint8_t *above -; r3 const uint8_t *left - -|vpx_h_predictor_8x8_neon| PROC - vld1.64 {d1}, [r3] - vdup.8 d0, d1[0] - vst1.64 {d0}, [r0], r1 - vdup.8 d0, d1[1] - vst1.64 {d0}, [r0], r1 - vdup.8 d0, d1[2] - vst1.64 {d0}, [r0], r1 - vdup.8 d0, d1[3] - vst1.64 {d0}, [r0], r1 - vdup.8 d0, d1[4] - vst1.64 {d0}, [r0], r1 - vdup.8 d0, d1[5] - vst1.64 {d0}, [r0], r1 - vdup.8 d0, d1[6] - vst1.64 {d0}, [r0], r1 - vdup.8 d0, d1[7] - vst1.64 {d0}, [r0], r1 - bx lr - ENDP ; |vpx_h_predictor_8x8_neon| - -;void vpx_h_predictor_16x16_neon(uint8_t *dst, ptrdiff_t y_stride, -; const uint8_t *above, -; const uint8_t *left) -; r0 uint8_t *dst -; r1 ptrdiff_t y_stride -; r2 const uint8_t *above -; r3 const uint8_t *left - -|vpx_h_predictor_16x16_neon| PROC - vld1.8 {q1}, [r3] - vdup.8 q0, d2[0] - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d2[1] - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d2[2] - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d2[3] - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d2[4] - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d2[5] - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d2[6] - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d2[7] - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d3[0] - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d3[1] - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d3[2] - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d3[3] - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d3[4] - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d3[5] - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d3[6] - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d3[7] - vst1.8 {q0}, [r0], r1 - bx lr - ENDP ; |vpx_h_predictor_16x16_neon| - -;void vpx_h_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, -; const uint8_t *above, -; const uint8_t *left) -; r0 uint8_t *dst -; r1 ptrdiff_t y_stride -; r2 const uint8_t *above -; r3 const uint8_t *left - -|vpx_h_predictor_32x32_neon| PROC - sub r1, r1, #16 - mov r2, #2 -loop_h - vld1.8 {q1}, [r3]! - vdup.8 q0, d2[0] - vst1.8 {q0}, [r0]! - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d2[1] - vst1.8 {q0}, [r0]! - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d2[2] - vst1.8 {q0}, [r0]! - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d2[3] - vst1.8 {q0}, [r0]! - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d2[4] - vst1.8 {q0}, [r0]! - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d2[5] - vst1.8 {q0}, [r0]! - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d2[6] - vst1.8 {q0}, [r0]! - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d2[7] - vst1.8 {q0}, [r0]! - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d3[0] - vst1.8 {q0}, [r0]! - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d3[1] - vst1.8 {q0}, [r0]! - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d3[2] - vst1.8 {q0}, [r0]! - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d3[3] - vst1.8 {q0}, [r0]! - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d3[4] - vst1.8 {q0}, [r0]! - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d3[5] - vst1.8 {q0}, [r0]! - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d3[6] - vst1.8 {q0}, [r0]! - vst1.8 {q0}, [r0], r1 - vdup.8 q0, d3[7] - vst1.8 {q0}, [r0]! - vst1.8 {q0}, [r0], r1 - subs r2, r2, #1 - bgt loop_h - bx lr - ENDP ; |vpx_h_predictor_32x32_neon| - -;void vpx_tm_predictor_4x4_neon (uint8_t *dst, ptrdiff_t y_stride, -; const uint8_t *above, -; const uint8_t *left) -; r0 uint8_t *dst -; r1 ptrdiff_t y_stride -; r2 const uint8_t *above -; r3 const uint8_t *left - -|vpx_tm_predictor_4x4_neon| PROC - ; Load ytop_left = above[-1]; - sub r12, r2, #1 - vld1.u8 {d0[]}, [r12] - - ; Load above 4 pixels - vld1.32 {d2[0]}, [r2] - - ; Compute above - ytop_left - vsubl.u8 q3, d2, d0 - - ; Load left row by row and compute left + (above - ytop_left) - ; 1st row and 2nd row - vld1.u8 {d2[]}, [r3]! - vld1.u8 {d4[]}, [r3]! - vmovl.u8 q1, d2 - vmovl.u8 q2, d4 - vadd.s16 q1, q1, q3 - vadd.s16 q2, q2, q3 - vqmovun.s16 d0, q1 - vqmovun.s16 d1, q2 - vst1.32 {d0[0]}, [r0], r1 - vst1.32 {d1[0]}, [r0], r1 - - ; 3rd row and 4th row - vld1.u8 {d2[]}, [r3]! - vld1.u8 {d4[]}, [r3] - vmovl.u8 q1, d2 - vmovl.u8 q2, d4 - vadd.s16 q1, q1, q3 - vadd.s16 q2, q2, q3 - vqmovun.s16 d0, q1 - vqmovun.s16 d1, q2 - vst1.32 {d0[0]}, [r0], r1 - vst1.32 {d1[0]}, [r0], r1 - bx lr - ENDP ; |vpx_tm_predictor_4x4_neon| - -;void vpx_tm_predictor_8x8_neon (uint8_t *dst, ptrdiff_t y_stride, -; const uint8_t *above, -; const uint8_t *left) -; r0 uint8_t *dst -; r1 ptrdiff_t y_stride -; r2 const uint8_t *above -; r3 const uint8_t *left - -|vpx_tm_predictor_8x8_neon| PROC - ; Load ytop_left = above[-1]; - sub r12, r2, #1 - vld1.8 {d0[]}, [r12] - - ; preload 8 left - vld1.8 {d30}, [r3] - - ; Load above 8 pixels - vld1.64 {d2}, [r2] - - vmovl.u8 q10, d30 - - ; Compute above - ytop_left - vsubl.u8 q3, d2, d0 - - ; Load left row by row and compute left + (above - ytop_left) - ; 1st row and 2nd row - vdup.16 q0, d20[0] - vdup.16 q1, d20[1] - vadd.s16 q0, q3, q0 - vadd.s16 q1, q3, q1 - - ; 3rd row and 4th row - vdup.16 q8, d20[2] - vdup.16 q9, d20[3] - vadd.s16 q8, q3, q8 - vadd.s16 q9, q3, q9 - - vqmovun.s16 d0, q0 - vqmovun.s16 d1, q1 - vqmovun.s16 d2, q8 - vqmovun.s16 d3, q9 - - vst1.64 {d0}, [r0], r1 - vst1.64 {d1}, [r0], r1 - vst1.64 {d2}, [r0], r1 - vst1.64 {d3}, [r0], r1 - - ; 5th row and 6th row - vdup.16 q0, d21[0] - vdup.16 q1, d21[1] - vadd.s16 q0, q3, q0 - vadd.s16 q1, q3, q1 - - ; 7th row and 8th row - vdup.16 q8, d21[2] - vdup.16 q9, d21[3] - vadd.s16 q8, q3, q8 - vadd.s16 q9, q3, q9 - - vqmovun.s16 d0, q0 - vqmovun.s16 d1, q1 - vqmovun.s16 d2, q8 - vqmovun.s16 d3, q9 - - vst1.64 {d0}, [r0], r1 - vst1.64 {d1}, [r0], r1 - vst1.64 {d2}, [r0], r1 - vst1.64 {d3}, [r0], r1 - - bx lr - ENDP ; |vpx_tm_predictor_8x8_neon| - -;void vpx_tm_predictor_16x16_neon (uint8_t *dst, ptrdiff_t y_stride, -; const uint8_t *above, -; const uint8_t *left) -; r0 uint8_t *dst -; r1 ptrdiff_t y_stride -; r2 const uint8_t *above -; r3 const uint8_t *left - -|vpx_tm_predictor_16x16_neon| PROC - ; Load ytop_left = above[-1]; - sub r12, r2, #1 - vld1.8 {d0[]}, [r12] - - ; Load above 8 pixels - vld1.8 {q1}, [r2] - - ; preload 8 left into r12 - vld1.8 {d18}, [r3]! - - ; Compute above - ytop_left - vsubl.u8 q2, d2, d0 - vsubl.u8 q3, d3, d0 - - vmovl.u8 q10, d18 - - ; Load left row by row and compute left + (above - ytop_left) - ; Process 8 rows in each single loop and loop 2 times to process 16 rows. - mov r2, #2 - -loop_16x16_neon - ; Process two rows. - vdup.16 q0, d20[0] - vdup.16 q8, d20[1] - vadd.s16 q1, q0, q2 - vadd.s16 q0, q0, q3 - vadd.s16 q11, q8, q2 - vadd.s16 q8, q8, q3 - vqmovun.s16 d2, q1 - vqmovun.s16 d3, q0 - vqmovun.s16 d22, q11 - vqmovun.s16 d23, q8 - vdup.16 q0, d20[2] ; proload next 2 rows data - vdup.16 q8, d20[3] - vst1.64 {d2,d3}, [r0], r1 - vst1.64 {d22,d23}, [r0], r1 - - ; Process two rows. - vadd.s16 q1, q0, q2 - vadd.s16 q0, q0, q3 - vadd.s16 q11, q8, q2 - vadd.s16 q8, q8, q3 - vqmovun.s16 d2, q1 - vqmovun.s16 d3, q0 - vqmovun.s16 d22, q11 - vqmovun.s16 d23, q8 - vdup.16 q0, d21[0] ; proload next 2 rows data - vdup.16 q8, d21[1] - vst1.64 {d2,d3}, [r0], r1 - vst1.64 {d22,d23}, [r0], r1 - - vadd.s16 q1, q0, q2 - vadd.s16 q0, q0, q3 - vadd.s16 q11, q8, q2 - vadd.s16 q8, q8, q3 - vqmovun.s16 d2, q1 - vqmovun.s16 d3, q0 - vqmovun.s16 d22, q11 - vqmovun.s16 d23, q8 - vdup.16 q0, d21[2] ; proload next 2 rows data - vdup.16 q8, d21[3] - vst1.64 {d2,d3}, [r0], r1 - vst1.64 {d22,d23}, [r0], r1 - - - vadd.s16 q1, q0, q2 - vadd.s16 q0, q0, q3 - vadd.s16 q11, q8, q2 - vadd.s16 q8, q8, q3 - vqmovun.s16 d2, q1 - vqmovun.s16 d3, q0 - vqmovun.s16 d22, q11 - vqmovun.s16 d23, q8 - vld1.8 {d18}, [r3]! ; preload 8 left into r12 - vmovl.u8 q10, d18 - vst1.64 {d2,d3}, [r0], r1 - vst1.64 {d22,d23}, [r0], r1 - - subs r2, r2, #1 - bgt loop_16x16_neon - - bx lr - ENDP ; |vpx_tm_predictor_16x16_neon| - -;void vpx_tm_predictor_32x32_neon (uint8_t *dst, ptrdiff_t y_stride, -; const uint8_t *above, -; const uint8_t *left) -; r0 uint8_t *dst -; r1 ptrdiff_t y_stride -; r2 const uint8_t *above -; r3 const uint8_t *left - -|vpx_tm_predictor_32x32_neon| PROC - ; Load ytop_left = above[-1]; - sub r12, r2, #1 - vld1.8 {d0[]}, [r12] - - ; Load above 32 pixels - vld1.8 {q1}, [r2]! - vld1.8 {q2}, [r2] - - ; preload 8 left pixels - vld1.8 {d26}, [r3]! - - ; Compute above - ytop_left - vsubl.u8 q8, d2, d0 - vsubl.u8 q9, d3, d0 - vsubl.u8 q10, d4, d0 - vsubl.u8 q11, d5, d0 - - vmovl.u8 q3, d26 - - ; Load left row by row and compute left + (above - ytop_left) - ; Process 8 rows in each single loop and loop 4 times to process 32 rows. - mov r2, #4 - -loop_32x32_neon - ; Process two rows. - vdup.16 q0, d6[0] - vdup.16 q2, d6[1] - vadd.s16 q12, q0, q8 - vadd.s16 q13, q0, q9 - vadd.s16 q14, q0, q10 - vadd.s16 q15, q0, q11 - vqmovun.s16 d0, q12 - vqmovun.s16 d1, q13 - vadd.s16 q12, q2, q8 - vadd.s16 q13, q2, q9 - vqmovun.s16 d2, q14 - vqmovun.s16 d3, q15 - vadd.s16 q14, q2, q10 - vadd.s16 q15, q2, q11 - vst1.64 {d0-d3}, [r0], r1 - vqmovun.s16 d24, q12 - vqmovun.s16 d25, q13 - vqmovun.s16 d26, q14 - vqmovun.s16 d27, q15 - vdup.16 q1, d6[2] - vdup.16 q2, d6[3] - vst1.64 {d24-d27}, [r0], r1 - - ; Process two rows. - vadd.s16 q12, q1, q8 - vadd.s16 q13, q1, q9 - vadd.s16 q14, q1, q10 - vadd.s16 q15, q1, q11 - vqmovun.s16 d0, q12 - vqmovun.s16 d1, q13 - vadd.s16 q12, q2, q8 - vadd.s16 q13, q2, q9 - vqmovun.s16 d2, q14 - vqmovun.s16 d3, q15 - vadd.s16 q14, q2, q10 - vadd.s16 q15, q2, q11 - vst1.64 {d0-d3}, [r0], r1 - vqmovun.s16 d24, q12 - vqmovun.s16 d25, q13 - vqmovun.s16 d26, q14 - vqmovun.s16 d27, q15 - vdup.16 q0, d7[0] - vdup.16 q2, d7[1] - vst1.64 {d24-d27}, [r0], r1 - - ; Process two rows. - vadd.s16 q12, q0, q8 - vadd.s16 q13, q0, q9 - vadd.s16 q14, q0, q10 - vadd.s16 q15, q0, q11 - vqmovun.s16 d0, q12 - vqmovun.s16 d1, q13 - vadd.s16 q12, q2, q8 - vadd.s16 q13, q2, q9 - vqmovun.s16 d2, q14 - vqmovun.s16 d3, q15 - vadd.s16 q14, q2, q10 - vadd.s16 q15, q2, q11 - vst1.64 {d0-d3}, [r0], r1 - vqmovun.s16 d24, q12 - vqmovun.s16 d25, q13 - vqmovun.s16 d26, q14 - vqmovun.s16 d27, q15 - vdup.16 q0, d7[2] - vdup.16 q2, d7[3] - vst1.64 {d24-d27}, [r0], r1 - - ; Process two rows. - vadd.s16 q12, q0, q8 - vadd.s16 q13, q0, q9 - vadd.s16 q14, q0, q10 - vadd.s16 q15, q0, q11 - vqmovun.s16 d0, q12 - vqmovun.s16 d1, q13 - vadd.s16 q12, q2, q8 - vadd.s16 q13, q2, q9 - vqmovun.s16 d2, q14 - vqmovun.s16 d3, q15 - vadd.s16 q14, q2, q10 - vadd.s16 q15, q2, q11 - vst1.64 {d0-d3}, [r0], r1 - vqmovun.s16 d24, q12 - vqmovun.s16 d25, q13 - vld1.8 {d0}, [r3]! ; preload 8 left pixels - vqmovun.s16 d26, q14 - vqmovun.s16 d27, q15 - vmovl.u8 q3, d0 - vst1.64 {d24-d27}, [r0], r1 - - subs r2, r2, #1 - bgt loop_32x32_neon - - bx lr - ENDP ; |vpx_tm_predictor_32x32_neon| - - END diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/loopfilter_16_neon.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/loopfilter_16_neon.asm deleted file mode 100644 index 730c40de..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/loopfilter_16_neon.asm +++ /dev/null @@ -1,666 +0,0 @@ -; -; Copyright (c) 2013 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - EXPORT |vpx_lpf_horizontal_16_neon| - EXPORT |vpx_lpf_horizontal_16_dual_neon| - EXPORT |vpx_lpf_vertical_16_neon| - EXPORT |vpx_lpf_vertical_16_dual_neon| - ARM - - AREA ||.text||, CODE, READONLY, ALIGN=2 - -; void mb_lpf_horizontal_edge(uint8_t *s, int p, -; const uint8_t *blimit, -; const uint8_t *limit, -; const uint8_t *thresh, -; int count) -; r0 uint8_t *s, -; r1 int p, /* pitch */ -; r2 const uint8_t *blimit, -; r3 const uint8_t *limit, -; sp const uint8_t *thresh, -; r12 int count -|mb_lpf_horizontal_edge| PROC - push {r4-r8, lr} - vpush {d8-d15} - ldr r4, [sp, #88] ; load thresh - -h_count - vld1.8 {d16[]}, [r2] ; load *blimit - vld1.8 {d17[]}, [r3] ; load *limit - vld1.8 {d18[]}, [r4] ; load *thresh - - sub r8, r0, r1, lsl #3 ; move src pointer down by 8 lines - - vld1.u8 {d0}, [r8@64], r1 ; p7 - vld1.u8 {d1}, [r8@64], r1 ; p6 - vld1.u8 {d2}, [r8@64], r1 ; p5 - vld1.u8 {d3}, [r8@64], r1 ; p4 - vld1.u8 {d4}, [r8@64], r1 ; p3 - vld1.u8 {d5}, [r8@64], r1 ; p2 - vld1.u8 {d6}, [r8@64], r1 ; p1 - vld1.u8 {d7}, [r8@64], r1 ; p0 - vld1.u8 {d8}, [r8@64], r1 ; q0 - vld1.u8 {d9}, [r8@64], r1 ; q1 - vld1.u8 {d10}, [r8@64], r1 ; q2 - vld1.u8 {d11}, [r8@64], r1 ; q3 - vld1.u8 {d12}, [r8@64], r1 ; q4 - vld1.u8 {d13}, [r8@64], r1 ; q5 - vld1.u8 {d14}, [r8@64], r1 ; q6 - vld1.u8 {d15}, [r8@64], r1 ; q7 - - bl vpx_wide_mbfilter_neon - - tst r7, #1 - beq h_mbfilter - - ; flat && mask were not set for any of the channels. Just store the values - ; from filter. - sub r8, r0, r1, lsl #1 - - vst1.u8 {d25}, [r8@64], r1 ; store op1 - vst1.u8 {d24}, [r8@64], r1 ; store op0 - vst1.u8 {d23}, [r8@64], r1 ; store oq0 - vst1.u8 {d26}, [r8@64], r1 ; store oq1 - - b h_next - -h_mbfilter - tst r7, #2 - beq h_wide_mbfilter - - ; flat2 was not set for any of the channels. Just store the values from - ; mbfilter. - sub r8, r0, r1, lsl #1 - sub r8, r8, r1 - - vst1.u8 {d18}, [r8@64], r1 ; store op2 - vst1.u8 {d19}, [r8@64], r1 ; store op1 - vst1.u8 {d20}, [r8@64], r1 ; store op0 - vst1.u8 {d21}, [r8@64], r1 ; store oq0 - vst1.u8 {d22}, [r8@64], r1 ; store oq1 - vst1.u8 {d23}, [r8@64], r1 ; store oq2 - - b h_next - -h_wide_mbfilter - sub r8, r0, r1, lsl #3 - add r8, r8, r1 - - vst1.u8 {d16}, [r8@64], r1 ; store op6 - vst1.u8 {d24}, [r8@64], r1 ; store op5 - vst1.u8 {d25}, [r8@64], r1 ; store op4 - vst1.u8 {d26}, [r8@64], r1 ; store op3 - vst1.u8 {d27}, [r8@64], r1 ; store op2 - vst1.u8 {d18}, [r8@64], r1 ; store op1 - vst1.u8 {d19}, [r8@64], r1 ; store op0 - vst1.u8 {d20}, [r8@64], r1 ; store oq0 - vst1.u8 {d21}, [r8@64], r1 ; store oq1 - vst1.u8 {d22}, [r8@64], r1 ; store oq2 - vst1.u8 {d23}, [r8@64], r1 ; store oq3 - vst1.u8 {d1}, [r8@64], r1 ; store oq4 - vst1.u8 {d2}, [r8@64], r1 ; store oq5 - vst1.u8 {d3}, [r8@64], r1 ; store oq6 - -h_next - add r0, r0, #8 - subs r12, r12, #1 - bne h_count - - vpop {d8-d15} - pop {r4-r8, pc} - - ENDP ; |mb_lpf_horizontal_edge| - -; void vpx_lpf_horizontal_16_neon(uint8_t *s, int pitch, -; const uint8_t *blimit, -; const uint8_t *limit, -; const uint8_t *thresh) -; r0 uint8_t *s, -; r1 int pitch, -; r2 const uint8_t *blimit, -; r3 const uint8_t *limit, -; sp const uint8_t *thresh -|vpx_lpf_horizontal_16_neon| PROC - mov r12, #1 - b mb_lpf_horizontal_edge - ENDP ; |vpx_lpf_horizontal_16_neon| - -; void vpx_lpf_horizontal_16_dual_neon(uint8_t *s, int pitch, -; const uint8_t *blimit, -; const uint8_t *limit, -; const uint8_t *thresh) -; r0 uint8_t *s, -; r1 int pitch, -; r2 const uint8_t *blimit, -; r3 const uint8_t *limit, -; sp const uint8_t *thresh -|vpx_lpf_horizontal_16_dual_neon| PROC - mov r12, #2 - b mb_lpf_horizontal_edge - ENDP ; |vpx_lpf_horizontal_16_dual_neon| - -; void mb_lpf_vertical_edge_w(uint8_t *s, int p, const uint8_t *blimit, -; const uint8_t *limit, const uint8_t *thresh, -; int count) { -; r0 uint8_t *s, -; r1 int p, /* pitch */ -; r2 const uint8_t *blimit, -; r3 const uint8_t *limit, -; sp const uint8_t *thresh, -; r12 int count -|mb_lpf_vertical_edge_w| PROC - push {r4-r8, lr} - vpush {d8-d15} - ldr r4, [sp, #88] ; load thresh - -v_count - vld1.8 {d16[]}, [r2] ; load *blimit - vld1.8 {d17[]}, [r3] ; load *limit - vld1.8 {d18[]}, [r4] ; load *thresh - - sub r8, r0, #8 - - vld1.8 {d0}, [r8@64], r1 - vld1.8 {d8}, [r0@64], r1 - vld1.8 {d1}, [r8@64], r1 - vld1.8 {d9}, [r0@64], r1 - vld1.8 {d2}, [r8@64], r1 - vld1.8 {d10}, [r0@64], r1 - vld1.8 {d3}, [r8@64], r1 - vld1.8 {d11}, [r0@64], r1 - vld1.8 {d4}, [r8@64], r1 - vld1.8 {d12}, [r0@64], r1 - vld1.8 {d5}, [r8@64], r1 - vld1.8 {d13}, [r0@64], r1 - vld1.8 {d6}, [r8@64], r1 - vld1.8 {d14}, [r0@64], r1 - vld1.8 {d7}, [r8@64], r1 - vld1.8 {d15}, [r0@64], r1 - - sub r0, r0, r1, lsl #3 - - vtrn.32 q0, q2 - vtrn.32 q1, q3 - vtrn.32 q4, q6 - vtrn.32 q5, q7 - - vtrn.16 q0, q1 - vtrn.16 q2, q3 - vtrn.16 q4, q5 - vtrn.16 q6, q7 - - vtrn.8 d0, d1 - vtrn.8 d2, d3 - vtrn.8 d4, d5 - vtrn.8 d6, d7 - - vtrn.8 d8, d9 - vtrn.8 d10, d11 - vtrn.8 d12, d13 - vtrn.8 d14, d15 - - bl vpx_wide_mbfilter_neon - - tst r7, #1 - beq v_mbfilter - - ; flat && mask were not set for any of the channels. Just store the values - ; from filter. - sub r0, #2 - - vswp d23, d25 - - vst4.8 {d23[0], d24[0], d25[0], d26[0]}, [r0], r1 - vst4.8 {d23[1], d24[1], d25[1], d26[1]}, [r0], r1 - vst4.8 {d23[2], d24[2], d25[2], d26[2]}, [r0], r1 - vst4.8 {d23[3], d24[3], d25[3], d26[3]}, [r0], r1 - vst4.8 {d23[4], d24[4], d25[4], d26[4]}, [r0], r1 - vst4.8 {d23[5], d24[5], d25[5], d26[5]}, [r0], r1 - vst4.8 {d23[6], d24[6], d25[6], d26[6]}, [r0], r1 - vst4.8 {d23[7], d24[7], d25[7], d26[7]}, [r0], r1 - add r0, #2 - - b v_next - -v_mbfilter - tst r7, #2 - beq v_wide_mbfilter - - ; flat2 was not set for any of the channels. Just store the values from - ; mbfilter. - sub r8, r0, #3 - - vst3.8 {d18[0], d19[0], d20[0]}, [r8], r1 - vst3.8 {d21[0], d22[0], d23[0]}, [r0], r1 - vst3.8 {d18[1], d19[1], d20[1]}, [r8], r1 - vst3.8 {d21[1], d22[1], d23[1]}, [r0], r1 - vst3.8 {d18[2], d19[2], d20[2]}, [r8], r1 - vst3.8 {d21[2], d22[2], d23[2]}, [r0], r1 - vst3.8 {d18[3], d19[3], d20[3]}, [r8], r1 - vst3.8 {d21[3], d22[3], d23[3]}, [r0], r1 - vst3.8 {d18[4], d19[4], d20[4]}, [r8], r1 - vst3.8 {d21[4], d22[4], d23[4]}, [r0], r1 - vst3.8 {d18[5], d19[5], d20[5]}, [r8], r1 - vst3.8 {d21[5], d22[5], d23[5]}, [r0], r1 - vst3.8 {d18[6], d19[6], d20[6]}, [r8], r1 - vst3.8 {d21[6], d22[6], d23[6]}, [r0], r1 - vst3.8 {d18[7], d19[7], d20[7]}, [r8], r1 - vst3.8 {d21[7], d22[7], d23[7]}, [r0], r1 - - b v_next - -v_wide_mbfilter - sub r8, r0, #8 - - vtrn.32 d0, d26 - vtrn.32 d16, d27 - vtrn.32 d24, d18 - vtrn.32 d25, d19 - - vtrn.16 d0, d24 - vtrn.16 d16, d25 - vtrn.16 d26, d18 - vtrn.16 d27, d19 - - vtrn.8 d0, d16 - vtrn.8 d24, d25 - vtrn.8 d26, d27 - vtrn.8 d18, d19 - - vtrn.32 d20, d1 - vtrn.32 d21, d2 - vtrn.32 d22, d3 - vtrn.32 d23, d15 - - vtrn.16 d20, d22 - vtrn.16 d21, d23 - vtrn.16 d1, d3 - vtrn.16 d2, d15 - - vtrn.8 d20, d21 - vtrn.8 d22, d23 - vtrn.8 d1, d2 - vtrn.8 d3, d15 - - vst1.8 {d0}, [r8@64], r1 - vst1.8 {d20}, [r0@64], r1 - vst1.8 {d16}, [r8@64], r1 - vst1.8 {d21}, [r0@64], r1 - vst1.8 {d24}, [r8@64], r1 - vst1.8 {d22}, [r0@64], r1 - vst1.8 {d25}, [r8@64], r1 - vst1.8 {d23}, [r0@64], r1 - vst1.8 {d26}, [r8@64], r1 - vst1.8 {d1}, [r0@64], r1 - vst1.8 {d27}, [r8@64], r1 - vst1.8 {d2}, [r0@64], r1 - vst1.8 {d18}, [r8@64], r1 - vst1.8 {d3}, [r0@64], r1 - vst1.8 {d19}, [r8@64], r1 - vst1.8 {d15}, [r0@64], r1 - -v_next - subs r12, #1 - bne v_count - - vpop {d8-d15} - pop {r4-r8, pc} - - ENDP ; |mb_lpf_vertical_edge_w| - -; void vpx_lpf_vertical_16_neon(uint8_t *s, int p, const uint8_t *blimit, -; const uint8_t *limit, const uint8_t *thresh) -; r0 uint8_t *s, -; r1 int p, /* pitch */ -; r2 const uint8_t *blimit, -; r3 const uint8_t *limit, -; sp const uint8_t *thresh -|vpx_lpf_vertical_16_neon| PROC - mov r12, #1 - b mb_lpf_vertical_edge_w - ENDP ; |vpx_lpf_vertical_16_neon| - -; void vpx_lpf_vertical_16_dual_neon(uint8_t *s, int p, const uint8_t *blimit, -; const uint8_t *limit, -; const uint8_t *thresh) -; r0 uint8_t *s, -; r1 int p, /* pitch */ -; r2 const uint8_t *blimit, -; r3 const uint8_t *limit, -; sp const uint8_t *thresh -|vpx_lpf_vertical_16_dual_neon| PROC - mov r12, #2 - b mb_lpf_vertical_edge_w - ENDP ; |vpx_lpf_vertical_16_dual_neon| - -; void vpx_wide_mbfilter_neon(); -; This is a helper function for the loopfilters. The invidual functions do the -; necessary load, transpose (if necessary) and store. -; -; r0-r3 PRESERVE -; d16 blimit -; d17 limit -; d18 thresh -; d0 p7 -; d1 p6 -; d2 p5 -; d3 p4 -; d4 p3 -; d5 p2 -; d6 p1 -; d7 p0 -; d8 q0 -; d9 q1 -; d10 q2 -; d11 q3 -; d12 q4 -; d13 q5 -; d14 q6 -; d15 q7 -|vpx_wide_mbfilter_neon| PROC - mov r7, #0 - - ; filter_mask - vabd.u8 d19, d4, d5 ; abs(p3 - p2) - vabd.u8 d20, d5, d6 ; abs(p2 - p1) - vabd.u8 d21, d6, d7 ; abs(p1 - p0) - vabd.u8 d22, d9, d8 ; abs(q1 - q0) - vabd.u8 d23, d10, d9 ; abs(q2 - q1) - vabd.u8 d24, d11, d10 ; abs(q3 - q2) - - ; only compare the largest value to limit - vmax.u8 d19, d19, d20 ; max(abs(p3 - p2), abs(p2 - p1)) - vmax.u8 d20, d21, d22 ; max(abs(p1 - p0), abs(q1 - q0)) - vmax.u8 d23, d23, d24 ; max(abs(q2 - q1), abs(q3 - q2)) - vmax.u8 d19, d19, d20 - - vabd.u8 d24, d7, d8 ; abs(p0 - q0) - - vmax.u8 d19, d19, d23 - - vabd.u8 d23, d6, d9 ; a = abs(p1 - q1) - vqadd.u8 d24, d24, d24 ; b = abs(p0 - q0) * 2 - - ; abs () > limit - vcge.u8 d19, d17, d19 - - ; flatmask4 - vabd.u8 d25, d7, d5 ; abs(p0 - p2) - vabd.u8 d26, d8, d10 ; abs(q0 - q2) - vabd.u8 d27, d4, d7 ; abs(p3 - p0) - vabd.u8 d28, d11, d8 ; abs(q3 - q0) - - ; only compare the largest value to thresh - vmax.u8 d25, d25, d26 ; max(abs(p0 - p2), abs(q0 - q2)) - vmax.u8 d26, d27, d28 ; max(abs(p3 - p0), abs(q3 - q0)) - vmax.u8 d25, d25, d26 - vmax.u8 d20, d20, d25 - - vshr.u8 d23, d23, #1 ; a = a / 2 - vqadd.u8 d24, d24, d23 ; a = b + a - - vmov.u8 d30, #1 - vcge.u8 d24, d16, d24 ; (a > blimit * 2 + limit) * -1 - - vcge.u8 d20, d30, d20 ; flat - - vand d19, d19, d24 ; mask - - ; hevmask - vcgt.u8 d21, d21, d18 ; (abs(p1 - p0) > thresh)*-1 - vcgt.u8 d22, d22, d18 ; (abs(q1 - q0) > thresh)*-1 - vorr d21, d21, d22 ; hev - - vand d16, d20, d19 ; flat && mask - vmov r5, r6, d16 - - ; flatmask5(1, p7, p6, p5, p4, p0, q0, q4, q5, q6, q7) - vabd.u8 d22, d3, d7 ; abs(p4 - p0) - vabd.u8 d23, d12, d8 ; abs(q4 - q0) - vabd.u8 d24, d7, d2 ; abs(p0 - p5) - vabd.u8 d25, d8, d13 ; abs(q0 - q5) - vabd.u8 d26, d1, d7 ; abs(p6 - p0) - vabd.u8 d27, d14, d8 ; abs(q6 - q0) - vabd.u8 d28, d0, d7 ; abs(p7 - p0) - vabd.u8 d29, d15, d8 ; abs(q7 - q0) - - ; only compare the largest value to thresh - vmax.u8 d22, d22, d23 ; max(abs(p4 - p0), abs(q4 - q0)) - vmax.u8 d23, d24, d25 ; max(abs(p0 - p5), abs(q0 - q5)) - vmax.u8 d24, d26, d27 ; max(abs(p6 - p0), abs(q6 - q0)) - vmax.u8 d25, d28, d29 ; max(abs(p7 - p0), abs(q7 - q0)) - - vmax.u8 d26, d22, d23 - vmax.u8 d27, d24, d25 - vmax.u8 d23, d26, d27 - - vcge.u8 d18, d30, d23 ; flat2 - - vmov.u8 d22, #0x80 - - orrs r5, r5, r6 ; Check for 0 - orreq r7, r7, #1 ; Only do filter branch - - vand d17, d18, d16 ; flat2 && flat && mask - vmov r5, r6, d17 - - ; mbfilter() function - - ; filter() function - ; convert to signed - veor d23, d8, d22 ; qs0 - veor d24, d7, d22 ; ps0 - veor d25, d6, d22 ; ps1 - veor d26, d9, d22 ; qs1 - - vmov.u8 d27, #3 - - vsub.s8 d28, d23, d24 ; ( qs0 - ps0) - vqsub.s8 d29, d25, d26 ; filter = clamp(ps1-qs1) - vmull.s8 q15, d28, d27 ; 3 * ( qs0 - ps0) - vand d29, d29, d21 ; filter &= hev - vaddw.s8 q15, q15, d29 ; filter + 3 * (qs0 - ps0) - vmov.u8 d29, #4 - - ; filter = clamp(filter + 3 * ( qs0 - ps0)) - vqmovn.s16 d28, q15 - - vand d28, d28, d19 ; filter &= mask - - vqadd.s8 d30, d28, d27 ; filter2 = clamp(filter+3) - vqadd.s8 d29, d28, d29 ; filter1 = clamp(filter+4) - vshr.s8 d30, d30, #3 ; filter2 >>= 3 - vshr.s8 d29, d29, #3 ; filter1 >>= 3 - - - vqadd.s8 d24, d24, d30 ; op0 = clamp(ps0 + filter2) - vqsub.s8 d23, d23, d29 ; oq0 = clamp(qs0 - filter1) - - ; outer tap adjustments: ++filter1 >> 1 - vrshr.s8 d29, d29, #1 - vbic d29, d29, d21 ; filter &= ~hev - - vqadd.s8 d25, d25, d29 ; op1 = clamp(ps1 + filter) - vqsub.s8 d26, d26, d29 ; oq1 = clamp(qs1 - filter) - - veor d24, d24, d22 ; *f_op0 = u^0x80 - veor d23, d23, d22 ; *f_oq0 = u^0x80 - veor d25, d25, d22 ; *f_op1 = u^0x80 - veor d26, d26, d22 ; *f_oq1 = u^0x80 - - tst r7, #1 - bxne lr - - orrs r5, r5, r6 ; Check for 0 - orreq r7, r7, #2 ; Only do mbfilter branch - - ; mbfilter flat && mask branch - ; TODO(fgalligan): Can I decrease the cycles shifting to consective d's - ; and using vibt on the q's? - vmov.u8 d29, #2 - vaddl.u8 q15, d7, d8 ; op2 = p0 + q0 - vmlal.u8 q15, d4, d27 ; op2 = p0 + q0 + p3 * 3 - vmlal.u8 q15, d5, d29 ; op2 = p0 + q0 + p3 * 3 + p2 * 2 - vaddl.u8 q10, d4, d5 - vaddw.u8 q15, d6 ; op2=p1 + p0 + q0 + p3 * 3 + p2 *2 - vaddl.u8 q14, d6, d9 - vqrshrn.u16 d18, q15, #3 ; r_op2 - - vsub.i16 q15, q10 - vaddl.u8 q10, d4, d6 - vadd.i16 q15, q14 - vaddl.u8 q14, d7, d10 - vqrshrn.u16 d19, q15, #3 ; r_op1 - - vsub.i16 q15, q10 - vadd.i16 q15, q14 - vaddl.u8 q14, d8, d11 - vqrshrn.u16 d20, q15, #3 ; r_op0 - - vsubw.u8 q15, d4 ; oq0 = op0 - p3 - vsubw.u8 q15, d7 ; oq0 -= p0 - vadd.i16 q15, q14 - vaddl.u8 q14, d9, d11 - vqrshrn.u16 d21, q15, #3 ; r_oq0 - - vsubw.u8 q15, d5 ; oq1 = oq0 - p2 - vsubw.u8 q15, d8 ; oq1 -= q0 - vadd.i16 q15, q14 - vaddl.u8 q14, d10, d11 - vqrshrn.u16 d22, q15, #3 ; r_oq1 - - vsubw.u8 q15, d6 ; oq2 = oq0 - p1 - vsubw.u8 q15, d9 ; oq2 -= q1 - vadd.i16 q15, q14 - vqrshrn.u16 d27, q15, #3 ; r_oq2 - - ; Filter does not set op2 or oq2, so use p2 and q2. - vbif d18, d5, d16 ; t_op2 |= p2 & ~(flat & mask) - vbif d19, d25, d16 ; t_op1 |= f_op1 & ~(flat & mask) - vbif d20, d24, d16 ; t_op0 |= f_op0 & ~(flat & mask) - vbif d21, d23, d16 ; t_oq0 |= f_oq0 & ~(flat & mask) - vbif d22, d26, d16 ; t_oq1 |= f_oq1 & ~(flat & mask) - - vbit d23, d27, d16 ; t_oq2 |= r_oq2 & (flat & mask) - vbif d23, d10, d16 ; t_oq2 |= q2 & ~(flat & mask) - - tst r7, #2 - bxne lr - - ; wide_mbfilter flat2 && flat && mask branch - vmov.u8 d16, #7 - vaddl.u8 q15, d7, d8 ; op6 = p0 + q0 - vaddl.u8 q12, d2, d3 - vaddl.u8 q13, d4, d5 - vaddl.u8 q14, d1, d6 - vmlal.u8 q15, d0, d16 ; op6 += p7 * 3 - vadd.i16 q12, q13 - vadd.i16 q15, q14 - vaddl.u8 q14, d2, d9 - vadd.i16 q15, q12 - vaddl.u8 q12, d0, d1 - vaddw.u8 q15, d1 - vaddl.u8 q13, d0, d2 - vadd.i16 q14, q15, q14 - vqrshrn.u16 d16, q15, #4 ; w_op6 - - vsub.i16 q15, q14, q12 - vaddl.u8 q14, d3, d10 - vqrshrn.u16 d24, q15, #4 ; w_op5 - - vsub.i16 q15, q13 - vaddl.u8 q13, d0, d3 - vadd.i16 q15, q14 - vaddl.u8 q14, d4, d11 - vqrshrn.u16 d25, q15, #4 ; w_op4 - - vadd.i16 q15, q14 - vaddl.u8 q14, d0, d4 - vsub.i16 q15, q13 - vsub.i16 q14, q15, q14 - vqrshrn.u16 d26, q15, #4 ; w_op3 - - vaddw.u8 q15, q14, d5 ; op2 += p2 - vaddl.u8 q14, d0, d5 - vaddw.u8 q15, d12 ; op2 += q4 - vbif d26, d4, d17 ; op3 |= p3 & ~(f2 & f & m) - vqrshrn.u16 d27, q15, #4 ; w_op2 - - vsub.i16 q15, q14 - vaddl.u8 q14, d0, d6 - vaddw.u8 q15, d6 ; op1 += p1 - vaddw.u8 q15, d13 ; op1 += q5 - vbif d27, d18, d17 ; op2 |= t_op2 & ~(f2 & f & m) - vqrshrn.u16 d18, q15, #4 ; w_op1 - - vsub.i16 q15, q14 - vaddl.u8 q14, d0, d7 - vaddw.u8 q15, d7 ; op0 += p0 - vaddw.u8 q15, d14 ; op0 += q6 - vbif d18, d19, d17 ; op1 |= t_op1 & ~(f2 & f & m) - vqrshrn.u16 d19, q15, #4 ; w_op0 - - vsub.i16 q15, q14 - vaddl.u8 q14, d1, d8 - vaddw.u8 q15, d8 ; oq0 += q0 - vaddw.u8 q15, d15 ; oq0 += q7 - vbif d19, d20, d17 ; op0 |= t_op0 & ~(f2 & f & m) - vqrshrn.u16 d20, q15, #4 ; w_oq0 - - vsub.i16 q15, q14 - vaddl.u8 q14, d2, d9 - vaddw.u8 q15, d9 ; oq1 += q1 - vaddl.u8 q4, d10, d15 - vaddw.u8 q15, d15 ; oq1 += q7 - vbif d20, d21, d17 ; oq0 |= t_oq0 & ~(f2 & f & m) - vqrshrn.u16 d21, q15, #4 ; w_oq1 - - vsub.i16 q15, q14 - vaddl.u8 q14, d3, d10 - vadd.i16 q15, q4 - vaddl.u8 q4, d11, d15 - vbif d21, d22, d17 ; oq1 |= t_oq1 & ~(f2 & f & m) - vqrshrn.u16 d22, q15, #4 ; w_oq2 - - vsub.i16 q15, q14 - vaddl.u8 q14, d4, d11 - vadd.i16 q15, q4 - vaddl.u8 q4, d12, d15 - vbif d22, d23, d17 ; oq2 |= t_oq2 & ~(f2 & f & m) - vqrshrn.u16 d23, q15, #4 ; w_oq3 - - vsub.i16 q15, q14 - vaddl.u8 q14, d5, d12 - vadd.i16 q15, q4 - vaddl.u8 q4, d13, d15 - vbif d16, d1, d17 ; op6 |= p6 & ~(f2 & f & m) - vqrshrn.u16 d1, q15, #4 ; w_oq4 - - vsub.i16 q15, q14 - vaddl.u8 q14, d6, d13 - vadd.i16 q15, q4 - vaddl.u8 q4, d14, d15 - vbif d24, d2, d17 ; op5 |= p5 & ~(f2 & f & m) - vqrshrn.u16 d2, q15, #4 ; w_oq5 - - vsub.i16 q15, q14 - vbif d25, d3, d17 ; op4 |= p4 & ~(f2 & f & m) - vadd.i16 q15, q4 - vbif d23, d11, d17 ; oq3 |= q3 & ~(f2 & f & m) - vqrshrn.u16 d3, q15, #4 ; w_oq6 - vbif d1, d12, d17 ; oq4 |= q4 & ~(f2 & f & m) - vbif d2, d13, d17 ; oq5 |= q5 & ~(f2 & f & m) - vbif d3, d14, d17 ; oq6 |= q6 & ~(f2 & f & m) - - bx lr - ENDP ; |vpx_wide_mbfilter_neon| - - END diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/loopfilter_4_neon.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/loopfilter_4_neon.asm deleted file mode 100644 index 907e9183..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/loopfilter_4_neon.asm +++ /dev/null @@ -1,549 +0,0 @@ -; -; Copyright (c) 2013 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - EXPORT |vpx_lpf_horizontal_4_neon| - EXPORT |vpx_lpf_vertical_4_neon| - EXPORT |vpx_lpf_horizontal_4_dual_neon| - EXPORT |vpx_lpf_vertical_4_dual_neon| - ARM - - AREA ||.text||, CODE, READONLY, ALIGN=2 - -; Currently vpx only works on iterations 8 at a time. The vp8 loop filter -; works on 16 iterations at a time. -; -; void vpx_lpf_horizontal_4_neon(uint8_t *s, -; int p /* pitch */, -; const uint8_t *blimit, -; const uint8_t *limit, -; const uint8_t *thresh) -; -; r0 uint8_t *s, -; r1 int p, /* pitch */ -; r2 const uint8_t *blimit, -; r3 const uint8_t *limit, -; sp const uint8_t *thresh, -|vpx_lpf_horizontal_4_neon| PROC - push {lr} - - vld1.8 {d0[]}, [r2] ; duplicate *blimit - ldr r2, [sp, #4] ; load thresh - add r1, r1, r1 ; double pitch - - vld1.8 {d1[]}, [r3] ; duplicate *limit - vld1.8 {d2[]}, [r2] ; duplicate *thresh - - sub r2, r0, r1, lsl #1 ; move src pointer down by 4 lines - add r3, r2, r1, lsr #1 ; set to 3 lines down - - vld1.u8 {d3}, [r2@64], r1 ; p3 - vld1.u8 {d4}, [r3@64], r1 ; p2 - vld1.u8 {d5}, [r2@64], r1 ; p1 - vld1.u8 {d6}, [r3@64], r1 ; p0 - vld1.u8 {d7}, [r2@64], r1 ; q0 - vld1.u8 {d16}, [r3@64], r1 ; q1 - vld1.u8 {d17}, [r2@64] ; q2 - vld1.u8 {d18}, [r3@64] ; q3 - - sub r2, r2, r1, lsl #1 - sub r3, r3, r1, lsl #1 - - bl filter4_8 - - vst1.u8 {d4}, [r2@64], r1 ; store op1 - vst1.u8 {d5}, [r3@64], r1 ; store op0 - vst1.u8 {d6}, [r2@64], r1 ; store oq0 - vst1.u8 {d7}, [r3@64], r1 ; store oq1 - - pop {pc} - ENDP ; |vpx_lpf_horizontal_4_neon| - -; Currently vpx only works on iterations 8 at a time. The vp8 loop filter -; works on 16 iterations at a time. -; -; void vpx_lpf_vertical_4_neon(uint8_t *s, -; int p /* pitch */, -; const uint8_t *blimit, -; const uint8_t *limit, -; const uint8_t *thresh) -; -; r0 uint8_t *s, -; r1 int p, /* pitch */ -; r2 const uint8_t *blimit, -; r3 const uint8_t *limit, -; sp const uint8_t *thresh, -|vpx_lpf_vertical_4_neon| PROC - push {lr} - - vld1.8 {d0[]}, [r2] ; duplicate *blimit - vld1.8 {d1[]}, [r3] ; duplicate *limit - - ldr r3, [sp, #4] ; load thresh - sub r2, r0, #4 ; move s pointer down by 4 columns - - vld1.8 {d2[]}, [r3] ; duplicate *thresh - - vld1.u8 {d3}, [r2], r1 ; load s data - vld1.u8 {d4}, [r2], r1 - vld1.u8 {d5}, [r2], r1 - vld1.u8 {d6}, [r2], r1 - vld1.u8 {d7}, [r2], r1 - vld1.u8 {d16}, [r2], r1 - vld1.u8 {d17}, [r2], r1 - vld1.u8 {d18}, [r2] - - ;transpose to 8x16 matrix - vtrn.32 d3, d7 - vtrn.32 d4, d16 - vtrn.32 d5, d17 - vtrn.32 d6, d18 - - vtrn.16 d3, d5 - vtrn.16 d4, d6 - vtrn.16 d7, d17 - vtrn.16 d16, d18 - - vtrn.8 d3, d4 - vtrn.8 d5, d6 - vtrn.8 d7, d16 - vtrn.8 d17, d18 - - bl filter4_8 - - sub r0, r0, #2 - - ;store op1, op0, oq0, oq1 - vst4.8 {d4[0], d5[0], d6[0], d7[0]}, [r0], r1 - vst4.8 {d4[1], d5[1], d6[1], d7[1]}, [r0], r1 - vst4.8 {d4[2], d5[2], d6[2], d7[2]}, [r0], r1 - vst4.8 {d4[3], d5[3], d6[3], d7[3]}, [r0], r1 - vst4.8 {d4[4], d5[4], d6[4], d7[4]}, [r0], r1 - vst4.8 {d4[5], d5[5], d6[5], d7[5]}, [r0], r1 - vst4.8 {d4[6], d5[6], d6[6], d7[6]}, [r0], r1 - vst4.8 {d4[7], d5[7], d6[7], d7[7]}, [r0] - - pop {pc} - ENDP ; |vpx_lpf_vertical_4_neon| - -; void filter4_8(); -; This is a helper function for the loopfilters. The invidual functions do the -; necessary load, transpose (if necessary) and store. The function does not use -; registers d8-d15. -; -; Inputs: -; r0-r3, r12 PRESERVE -; d0 blimit -; d1 limit -; d2 thresh -; d3 p3 -; d4 p2 -; d5 p1 -; d6 p0 -; d7 q0 -; d16 q1 -; d17 q2 -; d18 q3 -; -; Outputs: -; d4 op1 -; d5 op0 -; d6 oq0 -; d7 oq1 -|filter4_8| PROC - ; filter_mask - vabd.u8 d19, d3, d4 ; m1 = abs(p3 - p2) - vabd.u8 d20, d4, d5 ; m2 = abs(p2 - p1) - vabd.u8 d21, d5, d6 ; m3 = abs(p1 - p0) - vabd.u8 d22, d16, d7 ; m4 = abs(q1 - q0) - vabd.u8 d3, d17, d16 ; m5 = abs(q2 - q1) - vabd.u8 d4, d18, d17 ; m6 = abs(q3 - q2) - - ; only compare the largest value to limit - vmax.u8 d19, d19, d20 ; m1 = max(m1, m2) - vmax.u8 d20, d21, d22 ; m2 = max(m3, m4) - - vabd.u8 d17, d6, d7 ; abs(p0 - q0) - - vmax.u8 d3, d3, d4 ; m3 = max(m5, m6) - - vmov.u8 d18, #0x80 - - vmax.u8 d23, d19, d20 ; m1 = max(m1, m2) - - ; hevmask - vcgt.u8 d21, d21, d2 ; (abs(p1 - p0) > thresh)*-1 - vcgt.u8 d22, d22, d2 ; (abs(q1 - q0) > thresh)*-1 - vmax.u8 d23, d23, d3 ; m1 = max(m1, m3) - - vabd.u8 d28, d5, d16 ; a = abs(p1 - q1) - vqadd.u8 d17, d17, d17 ; b = abs(p0 - q0) * 2 - - veor d7, d7, d18 ; qs0 - - vcge.u8 d23, d1, d23 ; abs(m1) > limit - - ; filter() function - ; convert to signed - - vshr.u8 d28, d28, #1 ; a = a / 2 - veor d6, d6, d18 ; ps0 - - veor d5, d5, d18 ; ps1 - vqadd.u8 d17, d17, d28 ; a = b + a - - veor d16, d16, d18 ; qs1 - - vmov.u8 d19, #3 - - vsub.s8 d28, d7, d6 ; ( qs0 - ps0) - - vcge.u8 d17, d0, d17 ; a > blimit - - vqsub.s8 d27, d5, d16 ; filter = clamp(ps1-qs1) - vorr d22, d21, d22 ; hevmask - - vmull.s8 q12, d28, d19 ; 3 * ( qs0 - ps0) - - vand d27, d27, d22 ; filter &= hev - vand d23, d23, d17 ; filter_mask - - vaddw.s8 q12, q12, d27 ; filter + 3 * (qs0 - ps0) - - vmov.u8 d17, #4 - - ; filter = clamp(filter + 3 * ( qs0 - ps0)) - vqmovn.s16 d27, q12 - - vand d27, d27, d23 ; filter &= mask - - vqadd.s8 d28, d27, d19 ; filter2 = clamp(filter+3) - vqadd.s8 d27, d27, d17 ; filter1 = clamp(filter+4) - vshr.s8 d28, d28, #3 ; filter2 >>= 3 - vshr.s8 d27, d27, #3 ; filter1 >>= 3 - - vqadd.s8 d19, d6, d28 ; u = clamp(ps0 + filter2) - vqsub.s8 d26, d7, d27 ; u = clamp(qs0 - filter1) - - ; outer tap adjustments - vrshr.s8 d27, d27, #1 ; filter = ++filter1 >> 1 - - veor d6, d26, d18 ; *oq0 = u^0x80 - - vbic d27, d27, d22 ; filter &= ~hev - - vqadd.s8 d21, d5, d27 ; u = clamp(ps1 + filter) - vqsub.s8 d20, d16, d27 ; u = clamp(qs1 - filter) - - veor d5, d19, d18 ; *op0 = u^0x80 - veor d4, d21, d18 ; *op1 = u^0x80 - veor d7, d20, d18 ; *oq1 = u^0x80 - - bx lr - ENDP ; |filter4_8| - -;void vpx_lpf_horizontal_4_dual_neon(uint8_t *s, int p, -; const uint8_t *blimit0, -; const uint8_t *limit0, -; const uint8_t *thresh0, -; const uint8_t *blimit1, -; const uint8_t *limit1, -; const uint8_t *thresh1) -; r0 uint8_t *s, -; r1 int p, -; r2 const uint8_t *blimit0, -; r3 const uint8_t *limit0, -; sp const uint8_t *thresh0, -; sp+4 const uint8_t *blimit1, -; sp+8 const uint8_t *limit1, -; sp+12 const uint8_t *thresh1, - -|vpx_lpf_horizontal_4_dual_neon| PROC - push {lr} - - ldr r12, [sp, #4] ; load thresh0 - vld1.8 {d0}, [r2] ; load blimit0 to first half q - vld1.8 {d2}, [r3] ; load limit0 to first half q - - add r1, r1, r1 ; double pitch - ldr r2, [sp, #8] ; load blimit1 - - vld1.8 {d4}, [r12] ; load thresh0 to first half q - - ldr r3, [sp, #12] ; load limit1 - ldr r12, [sp, #16] ; load thresh1 - vld1.8 {d1}, [r2] ; load blimit1 to 2nd half q - - sub r2, r0, r1, lsl #1 ; s[-4 * p] - - vld1.8 {d3}, [r3] ; load limit1 to 2nd half q - vld1.8 {d5}, [r12] ; load thresh1 to 2nd half q - - vpush {d8-d15} ; save neon registers - - add r3, r2, r1, lsr #1 ; s[-3 * p] - - vld1.u8 {q3}, [r2@64], r1 ; p3 - vld1.u8 {q4}, [r3@64], r1 ; p2 - vld1.u8 {q5}, [r2@64], r1 ; p1 - vld1.u8 {q6}, [r3@64], r1 ; p0 - vld1.u8 {q7}, [r2@64], r1 ; q0 - vld1.u8 {q8}, [r3@64], r1 ; q1 - vld1.u8 {q9}, [r2@64] ; q2 - vld1.u8 {q10}, [r3@64] ; q3 - - sub r2, r2, r1, lsl #1 - sub r3, r3, r1, lsl #1 - - bl filter4_16 - - vst1.u8 {q5}, [r2@64], r1 ; store op1 - vst1.u8 {q6}, [r3@64], r1 ; store op0 - vst1.u8 {q7}, [r2@64], r1 ; store oq0 - vst1.u8 {q8}, [r3@64], r1 ; store oq1 - - vpop {d8-d15} ; restore neon registers - - pop {pc} - ENDP ; |vpx_lpf_horizontal_4_dual_neon| - -;void vpx_lpf_vertical_4_dual_neon(uint8_t *s, int p, -; const uint8_t *blimit0, -; const uint8_t *limit0, -; const uint8_t *thresh0, -; const uint8_t *blimit1, -; const uint8_t *limit1, -; const uint8_t *thresh1) -; r0 uint8_t *s, -; r1 int p, -; r2 const uint8_t *blimit0, -; r3 const uint8_t *limit0, -; sp const uint8_t *thresh0, -; sp+4 const uint8_t *blimit1, -; sp+8 const uint8_t *limit1, -; sp+12 const uint8_t *thresh1, - -|vpx_lpf_vertical_4_dual_neon| PROC - push {lr} - - ldr r12, [sp, #4] ; load thresh0 - vld1.8 {d0}, [r2] ; load blimit0 to first half q - vld1.8 {d2}, [r3] ; load limit0 to first half q - - ldr r2, [sp, #8] ; load blimit1 - - vld1.8 {d4}, [r12] ; load thresh0 to first half q - - ldr r3, [sp, #12] ; load limit1 - ldr r12, [sp, #16] ; load thresh1 - vld1.8 {d1}, [r2] ; load blimit1 to 2nd half q - - sub r2, r0, #4 ; s[-4] - - vld1.8 {d3}, [r3] ; load limit1 to 2nd half q - vld1.8 {d5}, [r12] ; load thresh1 to 2nd half q - - vpush {d8-d15} ; save neon registers - - vld1.u8 {d6}, [r2], r1 ; 00 01 02 03 04 05 06 07 - vld1.u8 {d8}, [r2], r1 ; 10 11 12 13 14 15 16 17 - vld1.u8 {d10}, [r2], r1 ; 20 21 22 23 24 25 26 27 - vld1.u8 {d12}, [r2], r1 ; 30 31 32 33 34 35 36 37 - vld1.u8 {d14}, [r2], r1 ; 40 41 42 43 44 45 46 47 - vld1.u8 {d16}, [r2], r1 ; 50 51 52 53 54 55 56 57 - vld1.u8 {d18}, [r2], r1 ; 60 61 62 63 64 65 66 67 - vld1.u8 {d20}, [r2], r1 ; 70 71 72 73 74 75 76 77 - vld1.u8 {d7}, [r2], r1 ; 80 81 82 83 84 85 86 87 - vld1.u8 {d9}, [r2], r1 ; 90 91 92 93 94 95 96 97 - vld1.u8 {d11}, [r2], r1 ; A0 A1 A2 A3 A4 A5 A6 A7 - vld1.u8 {d13}, [r2], r1 ; B0 B1 B2 B3 B4 B5 B6 B7 - vld1.u8 {d15}, [r2], r1 ; C0 C1 C2 C3 C4 C5 C6 C7 - vld1.u8 {d17}, [r2], r1 ; D0 D1 D2 D3 D4 D5 D6 D7 - vld1.u8 {d19}, [r2], r1 ; E0 E1 E2 E3 E4 E5 E6 E7 - vld1.u8 {d21}, [r2] ; F0 F1 F2 F3 F4 F5 F6 F7 - - vtrn.8 q3, q4 ; q3 : 00 10 02 12 04 14 06 16 80 90 82 92 84 94 86 96 - ; q4 : 01 11 03 13 05 15 07 17 81 91 83 93 85 95 87 97 - vtrn.8 q5, q6 ; q5 : 20 30 22 32 24 34 26 36 A0 B0 A2 B2 A4 B4 A6 B6 - ; q6 : 21 31 23 33 25 35 27 37 A1 B1 A3 B3 A5 B5 A7 B7 - vtrn.8 q7, q8 ; q7 : 40 50 42 52 44 54 46 56 C0 D0 C2 D2 C4 D4 C6 D6 - ; q8 : 41 51 43 53 45 55 47 57 C1 D1 C3 D3 C5 D5 C7 D7 - vtrn.8 q9, q10 ; q9 : 60 70 62 72 64 74 66 76 E0 F0 E2 F2 E4 F4 E6 F6 - ; q10: 61 71 63 73 65 75 67 77 E1 F1 E3 F3 E5 F5 E7 F7 - - vtrn.16 q3, q5 ; q3 : 00 10 20 30 04 14 24 34 80 90 A0 B0 84 94 A4 B4 - ; q5 : 02 12 22 32 06 16 26 36 82 92 A2 B2 86 96 A6 B6 - vtrn.16 q4, q6 ; q4 : 01 11 21 31 05 15 25 35 81 91 A1 B1 85 95 A5 B5 - ; q6 : 03 13 23 33 07 17 27 37 83 93 A3 B3 87 97 A7 B7 - vtrn.16 q7, q9 ; q7 : 40 50 60 70 44 54 64 74 C0 D0 E0 F0 C4 D4 E4 F4 - ; q9 : 42 52 62 72 46 56 66 76 C2 D2 E2 F2 C6 D6 E6 F6 - vtrn.16 q8, q10 ; q8 : 41 51 61 71 45 55 65 75 C1 D1 E1 F1 C5 D5 E5 F5 - ; q10: 43 53 63 73 47 57 67 77 C3 D3 E3 F3 C7 D7 E7 F7 - - vtrn.32 q3, q7 ; q3 : 00 10 20 30 40 50 60 70 80 90 A0 B0 C0 D0 E0 F0 - ; q7 : 04 14 24 34 44 54 64 74 84 94 A4 B4 C4 D4 E4 F4 - vtrn.32 q5, q9 ; q5 : 02 12 22 32 42 52 62 72 82 92 A2 B2 C2 D2 E2 F2 - ; q9 : 06 16 26 36 46 56 66 76 86 96 A6 B6 C6 D6 E6 F6 - vtrn.32 q4, q8 ; q4 : 01 11 21 31 41 51 61 71 81 91 A1 B1 C1 D1 E1 F1 - ; q8 : 05 15 25 35 45 55 65 75 85 95 A5 B5 C5 D5 E5 F5 - vtrn.32 q6, q10 ; q6 : 03 13 23 33 43 53 63 73 83 93 A3 B3 C3 D3 E3 F3 - ; q10: 07 17 27 37 47 57 67 77 87 97 A7 B7 C7 D7 E7 F7 - - bl filter4_16 - - sub r0, #2 - - vmov d0, d11 - vmov d1, d13 - vmov d2, d15 - vmov d3, d17 - vmov d11, d12 - vmov d12, d14 - vmov d13, d16 - vst4.8 {d10[0], d11[0], d12[0], d13[0]}, [r0], r1 - vst4.8 {d10[1], d11[1], d12[1], d13[1]}, [r0], r1 - vst4.8 {d10[2], d11[2], d12[2], d13[2]}, [r0], r1 - vst4.8 {d10[3], d11[3], d12[3], d13[3]}, [r0], r1 - vst4.8 {d10[4], d11[4], d12[4], d13[4]}, [r0], r1 - vst4.8 {d10[5], d11[5], d12[5], d13[5]}, [r0], r1 - vst4.8 {d10[6], d11[6], d12[6], d13[6]}, [r0], r1 - vst4.8 {d10[7], d11[7], d12[7], d13[7]}, [r0], r1 - vst4.8 {d0[0], d1[0], d2[0], d3[0]}, [r0], r1 - vst4.8 {d0[1], d1[1], d2[1], d3[1]}, [r0], r1 - vst4.8 {d0[2], d1[2], d2[2], d3[2]}, [r0], r1 - vst4.8 {d0[3], d1[3], d2[3], d3[3]}, [r0], r1 - vst4.8 {d0[4], d1[4], d2[4], d3[4]}, [r0], r1 - vst4.8 {d0[5], d1[5], d2[5], d3[5]}, [r0], r1 - vst4.8 {d0[6], d1[6], d2[6], d3[6]}, [r0], r1 - vst4.8 {d0[7], d1[7], d2[7], d3[7]}, [r0] - - vpop {d8-d15} ; restore neon registers - - pop {pc} - ENDP ; |vpx_lpf_vertical_4_dual_neon| - -; void filter4_16(); -; This is a helper function for the loopfilters. The invidual functions do the -; necessary load, transpose (if necessary) and store. This function uses -; registers d8-d15, so the calling function must save those registers. -; -; r0-r3, r12 PRESERVE -; q0 blimit -; q1 limit -; q2 thresh -; q3 p3 -; q4 p2 -; q5 p1 -; q6 p0 -; q7 q0 -; q8 q1 -; q9 q2 -; q10 q3 -; -; Outputs: -; q5 op1 -; q6 op0 -; q7 oq0 -; q8 oq1 -|filter4_16| PROC - - ; filter_mask - vabd.u8 q11, q3, q4 ; m1 = abs(p3 - p2) - vabd.u8 q12, q4, q5 ; m2 = abs(p2 - p1) - vabd.u8 q13, q5, q6 ; m3 = abs(p1 - p0) - vabd.u8 q14, q8, q7 ; m4 = abs(q1 - q0) - vabd.u8 q3, q9, q8 ; m5 = abs(q2 - q1) - vabd.u8 q4, q10, q9 ; m6 = abs(q3 - q2) - - ; only compare the largest value to limit - vmax.u8 q11, q11, q12 ; m7 = max(m1, m2) - vmax.u8 q12, q13, q14 ; m8 = max(m3, m4) - - vabd.u8 q9, q6, q7 ; abs(p0 - q0) - - vmax.u8 q3, q3, q4 ; m9 = max(m5, m6) - - vmov.u8 q10, #0x80 - - vmax.u8 q15, q11, q12 ; m10 = max(m7, m8) - - vcgt.u8 q13, q13, q2 ; (abs(p1 - p0) > thresh)*-1 - vcgt.u8 q14, q14, q2 ; (abs(q1 - q0) > thresh)*-1 - vmax.u8 q15, q15, q3 ; m11 = max(m10, m9) - - vabd.u8 q2, q5, q8 ; a = abs(p1 - q1) - vqadd.u8 q9, q9, q9 ; b = abs(p0 - q0) * 2 - - veor q7, q7, q10 ; qs0 - - vcge.u8 q15, q1, q15 ; abs(m11) > limit - - vshr.u8 q2, q2, #1 ; a = a / 2 - veor q6, q6, q10 ; ps0 - - veor q5, q5, q10 ; ps1 - vqadd.u8 q9, q9, q2 ; a = b + a - - veor q8, q8, q10 ; qs1 - - vmov.u16 q4, #3 - - vsubl.s8 q2, d14, d12 ; ( qs0 - ps0) - vsubl.s8 q11, d15, d13 - - vcge.u8 q9, q0, q9 ; a > blimit - - vqsub.s8 q1, q5, q8 ; filter = clamp(ps1-qs1) - vorr q14, q13, q14 ; hev - - vmul.i16 q2, q2, q4 ; 3 * ( qs0 - ps0) - vmul.i16 q11, q11, q4 - - vand q1, q1, q14 ; filter &= hev - vand q15, q15, q9 ; mask - - vmov.u8 q4, #3 - - vaddw.s8 q2, q2, d2 ; filter + 3 * (qs0 - ps0) - vaddw.s8 q11, q11, d3 - - vmov.u8 q9, #4 - - ; filter = clamp(filter + 3 * ( qs0 - ps0)) - vqmovn.s16 d2, q2 - vqmovn.s16 d3, q11 - vand q1, q1, q15 ; filter &= mask - - vqadd.s8 q2, q1, q4 ; filter2 = clamp(filter+3) - vqadd.s8 q1, q1, q9 ; filter1 = clamp(filter+4) - vshr.s8 q2, q2, #3 ; filter2 >>= 3 - vshr.s8 q1, q1, #3 ; filter1 >>= 3 - - - vqadd.s8 q11, q6, q2 ; u = clamp(ps0 + filter2) - vqsub.s8 q0, q7, q1 ; u = clamp(qs0 - filter1) - - ; outer tap adjustments - vrshr.s8 q1, q1, #1 ; filter = ++filter1 >> 1 - - veor q7, q0, q10 ; *oq0 = u^0x80 - - vbic q1, q1, q14 ; filter &= ~hev - - vqadd.s8 q13, q5, q1 ; u = clamp(ps1 + filter) - vqsub.s8 q12, q8, q1 ; u = clamp(qs1 - filter) - - veor q6, q11, q10 ; *op0 = u^0x80 - veor q5, q13, q10 ; *op1 = u^0x80 - veor q8, q12, q10 ; *oq1 = u^0x80 - - bx lr - ENDP ; |filter4_16| - - END diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/loopfilter_8_neon.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/loopfilter_8_neon.asm deleted file mode 100644 index a81a9d10..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/loopfilter_8_neon.asm +++ /dev/null @@ -1,491 +0,0 @@ -; -; Copyright (c) 2013 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - EXPORT |vpx_lpf_horizontal_8_neon| - EXPORT |vpx_lpf_horizontal_8_dual_neon| - EXPORT |vpx_lpf_vertical_8_neon| - EXPORT |vpx_lpf_vertical_8_dual_neon| - ARM - - AREA ||.text||, CODE, READONLY, ALIGN=2 - -; Currently vpx only works on iterations 8 at a time. The vp8 loop filter -; works on 16 iterations at a time. -; -; void vpx_lpf_horizontal_8_neon(uint8_t *s, int p, -; const uint8_t *blimit, -; const uint8_t *limit, -; const uint8_t *thresh) -; r0 uint8_t *s, -; r1 int p, /* pitch */ -; r2 const uint8_t *blimit, -; r3 const uint8_t *limit, -; sp const uint8_t *thresh, -|vpx_lpf_horizontal_8_neon| PROC - push {r4-r5, lr} - - vld1.8 {d0[]}, [r2] ; duplicate *blimit - ldr r2, [sp, #12] ; load thresh - add r1, r1, r1 ; double pitch - - vld1.8 {d1[]}, [r3] ; duplicate *limit - vld1.8 {d2[]}, [r2] ; duplicate *thresh - - sub r3, r0, r1, lsl #1 ; move src pointer down by 4 lines - add r2, r3, r1, lsr #1 ; set to 3 lines down - - vld1.u8 {d3}, [r3@64], r1 ; p3 - vld1.u8 {d4}, [r2@64], r1 ; p2 - vld1.u8 {d5}, [r3@64], r1 ; p1 - vld1.u8 {d6}, [r2@64], r1 ; p0 - vld1.u8 {d7}, [r3@64], r1 ; q0 - vld1.u8 {d16}, [r2@64], r1 ; q1 - vld1.u8 {d17}, [r3@64] ; q2 - vld1.u8 {d18}, [r2@64], r1 ; q3 - - sub r3, r3, r1, lsl #1 - sub r2, r2, r1, lsl #2 - - bl vpx_mbloop_filter_neon - - vst1.u8 {d0}, [r2@64], r1 ; store op2 - vst1.u8 {d1}, [r3@64], r1 ; store op1 - vst1.u8 {d2}, [r2@64], r1 ; store op0 - vst1.u8 {d3}, [r3@64], r1 ; store oq0 - vst1.u8 {d4}, [r2@64], r1 ; store oq1 - vst1.u8 {d5}, [r3@64], r1 ; store oq2 - - pop {r4-r5, pc} - - ENDP ; |vpx_lpf_horizontal_8_neon| - -;void vpx_lpf_horizontal_8_dual_neon(uint8_t *s, -; int p, -; const uint8_t *blimit0, -; const uint8_t *limit0, -; const uint8_t *thresh0, -; const uint8_t *blimit1, -; const uint8_t *limit1, -; const uint8_t *thresh1) -; r0 uint8_t *s, -; r1 int p, /* pitch */ -; r2 const uint8_t *blimit0, -; r3 const uint8_t *limit0, -; sp const uint8_t *thresh0, -; sp + 4 const uint8_t *blimit1, -; sp + 8 const uint8_t *limit1, -; sp + 12 const uint8_t *thresh1, -|vpx_lpf_horizontal_8_dual_neon| PROC - push {r0-r1, lr} - ldr lr, [sp, #12] - push {lr} ; thresh0 - bl vpx_lpf_horizontal_8_neon - - ldr r2, [sp, #20] ; blimit1 - ldr r3, [sp, #24] ; limit1 - ldr lr, [sp, #28] - str lr, [sp, #16] ; thresh1 - add sp, #4 - pop {r0-r1, lr} - add r0, #8 ; s + 8 - b vpx_lpf_horizontal_8_neon - ENDP ; |vpx_lpf_horizontal_8_dual_neon| - -; void vpx_lpf_vertical_8_neon(uint8_t *s, -; int pitch, -; const uint8_t *blimit, -; const uint8_t *limit, -; const uint8_t *thresh) -; -; r0 uint8_t *s, -; r1 int pitch, -; r2 const uint8_t *blimit, -; r3 const uint8_t *limit, -; sp const uint8_t *thresh, -|vpx_lpf_vertical_8_neon| PROC - push {r4-r5, lr} - - vld1.8 {d0[]}, [r2] ; duplicate *blimit - vld1.8 {d1[]}, [r3] ; duplicate *limit - - ldr r3, [sp, #12] ; load thresh - sub r2, r0, #4 ; move s pointer down by 4 columns - - vld1.8 {d2[]}, [r3] ; duplicate *thresh - - vld1.u8 {d3}, [r2], r1 ; load s data - vld1.u8 {d4}, [r2], r1 - vld1.u8 {d5}, [r2], r1 - vld1.u8 {d6}, [r2], r1 - vld1.u8 {d7}, [r2], r1 - vld1.u8 {d16}, [r2], r1 - vld1.u8 {d17}, [r2], r1 - vld1.u8 {d18}, [r2] - - ;transpose to 8x16 matrix - vtrn.32 d3, d7 - vtrn.32 d4, d16 - vtrn.32 d5, d17 - vtrn.32 d6, d18 - - vtrn.16 d3, d5 - vtrn.16 d4, d6 - vtrn.16 d7, d17 - vtrn.16 d16, d18 - - vtrn.8 d3, d4 - vtrn.8 d5, d6 - vtrn.8 d7, d16 - vtrn.8 d17, d18 - - sub r2, r0, #3 - add r3, r0, #1 - - bl vpx_mbloop_filter_neon - - ;store op2, op1, op0, oq0 - vst4.8 {d0[0], d1[0], d2[0], d3[0]}, [r2], r1 - vst4.8 {d0[1], d1[1], d2[1], d3[1]}, [r2], r1 - vst4.8 {d0[2], d1[2], d2[2], d3[2]}, [r2], r1 - vst4.8 {d0[3], d1[3], d2[3], d3[3]}, [r2], r1 - vst4.8 {d0[4], d1[4], d2[4], d3[4]}, [r2], r1 - vst4.8 {d0[5], d1[5], d2[5], d3[5]}, [r2], r1 - vst4.8 {d0[6], d1[6], d2[6], d3[6]}, [r2], r1 - vst4.8 {d0[7], d1[7], d2[7], d3[7]}, [r2] - - ;store oq1, oq2 - vst2.8 {d4[0], d5[0]}, [r3], r1 - vst2.8 {d4[1], d5[1]}, [r3], r1 - vst2.8 {d4[2], d5[2]}, [r3], r1 - vst2.8 {d4[3], d5[3]}, [r3], r1 - vst2.8 {d4[4], d5[4]}, [r3], r1 - vst2.8 {d4[5], d5[5]}, [r3], r1 - vst2.8 {d4[6], d5[6]}, [r3], r1 - vst2.8 {d4[7], d5[7]}, [r3] - - pop {r4-r5, pc} - ENDP ; |vpx_lpf_vertical_8_neon| - -;void vpx_lpf_vertical_8_dual_neon(uint8_t *s, -; int pitch, -; const uint8_t *blimit0, -; const uint8_t *limit0, -; const uint8_t *thresh0, -; const uint8_t *blimit1, -; const uint8_t *limit1, -; const uint8_t *thresh1) -; r0 uint8_t *s, -; r1 int pitch -; r2 const uint8_t *blimit0, -; r3 const uint8_t *limit0, -; sp const uint8_t *thresh0, -; sp + 4 const uint8_t *blimit1, -; sp + 8 const uint8_t *limit1, -; sp + 12 const uint8_t *thresh1, -|vpx_lpf_vertical_8_dual_neon| PROC - push {r0-r1, lr} - ldr lr, [sp, #12] - push {lr} ; thresh0 - bl vpx_lpf_vertical_8_neon - - ldr r2, [sp, #20] ; blimit1 - ldr r3, [sp, #24] ; limit1 - ldr lr, [sp, #28] - str lr, [sp, #16] ; thresh1 - add sp, #4 - pop {r0-r1, lr} - add r0, r0, r1, lsl #3 ; s + 8 * pitch - b vpx_lpf_vertical_8_neon - ENDP ; |vpx_lpf_vertical_8_dual_neon| - -; void vpx_mbloop_filter_neon(); -; This is a helper function for the loopfilters. The invidual functions do the -; necessary load, transpose (if necessary) and store. The function does not use -; registers d8-d15. -; -; Inputs: -; r0-r3, r12 PRESERVE -; d0 blimit -; d1 limit -; d2 thresh -; d3 p3 -; d4 p2 -; d5 p1 -; d6 p0 -; d7 q0 -; d16 q1 -; d17 q2 -; d18 q3 -; -; Outputs: -; d0 op2 -; d1 op1 -; d2 op0 -; d3 oq0 -; d4 oq1 -; d5 oq2 -|vpx_mbloop_filter_neon| PROC - ; filter_mask - vabd.u8 d19, d3, d4 ; m1 = abs(p3 - p2) - vabd.u8 d20, d4, d5 ; m2 = abs(p2 - p1) - vabd.u8 d21, d5, d6 ; m3 = abs(p1 - p0) - vabd.u8 d22, d16, d7 ; m4 = abs(q1 - q0) - vabd.u8 d23, d17, d16 ; m5 = abs(q2 - q1) - vabd.u8 d24, d18, d17 ; m6 = abs(q3 - q2) - - ; only compare the largest value to limit - vmax.u8 d19, d19, d20 ; m1 = max(m1, m2) - vmax.u8 d20, d21, d22 ; m2 = max(m3, m4) - - vabd.u8 d25, d6, d4 ; m7 = abs(p0 - p2) - - vmax.u8 d23, d23, d24 ; m3 = max(m5, m6) - - vabd.u8 d26, d7, d17 ; m8 = abs(q0 - q2) - - vmax.u8 d19, d19, d20 - - vabd.u8 d24, d6, d7 ; m9 = abs(p0 - q0) - vabd.u8 d27, d3, d6 ; m10 = abs(p3 - p0) - vabd.u8 d28, d18, d7 ; m11 = abs(q3 - q0) - - vmax.u8 d19, d19, d23 - - vabd.u8 d23, d5, d16 ; a = abs(p1 - q1) - vqadd.u8 d24, d24, d24 ; b = abs(p0 - q0) * 2 - - ; abs () > limit - vcge.u8 d19, d1, d19 - - ; only compare the largest value to thresh - vmax.u8 d25, d25, d26 ; m4 = max(m7, m8) - vmax.u8 d26, d27, d28 ; m5 = max(m10, m11) - - vshr.u8 d23, d23, #1 ; a = a / 2 - - vmax.u8 d25, d25, d26 ; m4 = max(m4, m5) - - vqadd.u8 d24, d24, d23 ; a = b + a - - vmax.u8 d20, d20, d25 ; m2 = max(m2, m4) - - vmov.u8 d23, #1 - vcge.u8 d24, d0, d24 ; a > blimit - - vcgt.u8 d21, d21, d2 ; (abs(p1 - p0) > thresh)*-1 - - vcge.u8 d20, d23, d20 ; flat - - vand d19, d19, d24 ; mask - - vcgt.u8 d23, d22, d2 ; (abs(q1 - q0) > thresh)*-1 - - vand d20, d20, d19 ; flat & mask - - vmov.u8 d22, #0x80 - - vorr d23, d21, d23 ; hev - - ; This instruction will truncate the "flat & mask" masks down to 4 bits - ; each to fit into one 32 bit arm register. The values are stored in - ; q10.64[0]. - vshrn.u16 d30, q10, #4 - vmov.u32 r4, d30[0] ; flat & mask 4bits - - adds r5, r4, #1 ; Check for all 1's - - ; If mask and flat are 1's for all vectors, then we only need to execute - ; the power branch for all vectors. - beq power_branch_only - - cmp r4, #0 ; Check for 0, set flag for later - - ; mbfilter() function - ; filter() function - ; convert to signed - veor d21, d7, d22 ; qs0 - veor d24, d6, d22 ; ps0 - veor d25, d5, d22 ; ps1 - veor d26, d16, d22 ; qs1 - - vmov.u8 d27, #3 - - vsub.s8 d28, d21, d24 ; ( qs0 - ps0) - - vqsub.s8 d29, d25, d26 ; filter = clamp(ps1-qs1) - - vmull.s8 q15, d28, d27 ; 3 * ( qs0 - ps0) - - vand d29, d29, d23 ; filter &= hev - - vaddw.s8 q15, q15, d29 ; filter + 3 * (qs0 - ps0) - - vmov.u8 d29, #4 - - ; filter = clamp(filter + 3 * ( qs0 - ps0)) - vqmovn.s16 d28, q15 - - vand d28, d28, d19 ; filter &= mask - - vqadd.s8 d30, d28, d27 ; filter2 = clamp(filter+3) - vqadd.s8 d29, d28, d29 ; filter1 = clamp(filter+4) - vshr.s8 d30, d30, #3 ; filter2 >>= 3 - vshr.s8 d29, d29, #3 ; filter1 >>= 3 - - vqadd.s8 d24, d24, d30 ; op0 = clamp(ps0 + filter2) - vqsub.s8 d21, d21, d29 ; oq0 = clamp(qs0 - filter1) - - ; outer tap adjustments: ++filter1 >> 1 - vrshr.s8 d29, d29, #1 - vbic d29, d29, d23 ; filter &= ~hev - - vqadd.s8 d25, d25, d29 ; op1 = clamp(ps1 + filter) - vqsub.s8 d26, d26, d29 ; oq1 = clamp(qs1 - filter) - - ; If mask and flat are 0's for all vectors, then we only need to execute - ; the filter branch for all vectors. - beq filter_branch_only - - ; If mask and flat are mixed then we must perform both branches and - ; combine the data. - veor d24, d24, d22 ; *f_op0 = u^0x80 - veor d21, d21, d22 ; *f_oq0 = u^0x80 - veor d25, d25, d22 ; *f_op1 = u^0x80 - veor d26, d26, d22 ; *f_oq1 = u^0x80 - - ; At this point we have already executed the filter branch. The filter - ; branch does not set op2 or oq2, so use p2 and q2. Execute the power - ; branch and combine the data. - vmov.u8 d23, #2 - vaddl.u8 q14, d6, d7 ; r_op2 = p0 + q0 - vmlal.u8 q14, d3, d27 ; r_op2 += p3 * 3 - vmlal.u8 q14, d4, d23 ; r_op2 += p2 * 2 - - vbif d0, d4, d20 ; op2 |= p2 & ~(flat & mask) - - vaddw.u8 q14, d5 ; r_op2 += p1 - - vbif d1, d25, d20 ; op1 |= f_op1 & ~(flat & mask) - - vqrshrn.u16 d30, q14, #3 ; r_op2 - - vsubw.u8 q14, d3 ; r_op1 = r_op2 - p3 - vsubw.u8 q14, d4 ; r_op1 -= p2 - vaddw.u8 q14, d5 ; r_op1 += p1 - vaddw.u8 q14, d16 ; r_op1 += q1 - - vbif d2, d24, d20 ; op0 |= f_op0 & ~(flat & mask) - - vqrshrn.u16 d31, q14, #3 ; r_op1 - - vsubw.u8 q14, d3 ; r_op0 = r_op1 - p3 - vsubw.u8 q14, d5 ; r_op0 -= p1 - vaddw.u8 q14, d6 ; r_op0 += p0 - vaddw.u8 q14, d17 ; r_op0 += q2 - - vbit d0, d30, d20 ; op2 |= r_op2 & (flat & mask) - - vqrshrn.u16 d23, q14, #3 ; r_op0 - - vsubw.u8 q14, d3 ; r_oq0 = r_op0 - p3 - vsubw.u8 q14, d6 ; r_oq0 -= p0 - vaddw.u8 q14, d7 ; r_oq0 += q0 - - vbit d1, d31, d20 ; op1 |= r_op1 & (flat & mask) - - vaddw.u8 q14, d18 ; oq0 += q3 - - vbit d2, d23, d20 ; op0 |= r_op0 & (flat & mask) - - vqrshrn.u16 d22, q14, #3 ; r_oq0 - - vsubw.u8 q14, d4 ; r_oq1 = r_oq0 - p2 - vsubw.u8 q14, d7 ; r_oq1 -= q0 - vaddw.u8 q14, d16 ; r_oq1 += q1 - - vbif d3, d21, d20 ; oq0 |= f_oq0 & ~(flat & mask) - - vaddw.u8 q14, d18 ; r_oq1 += q3 - - vbif d4, d26, d20 ; oq1 |= f_oq1 & ~(flat & mask) - - vqrshrn.u16 d6, q14, #3 ; r_oq1 - - vsubw.u8 q14, d5 ; r_oq2 = r_oq1 - p1 - vsubw.u8 q14, d16 ; r_oq2 -= q1 - vaddw.u8 q14, d17 ; r_oq2 += q2 - vaddw.u8 q14, d18 ; r_oq2 += q3 - - vbif d5, d17, d20 ; oq2 |= q2 & ~(flat & mask) - - vqrshrn.u16 d7, q14, #3 ; r_oq2 - - vbit d3, d22, d20 ; oq0 |= r_oq0 & (flat & mask) - vbit d4, d6, d20 ; oq1 |= r_oq1 & (flat & mask) - vbit d5, d7, d20 ; oq2 |= r_oq2 & (flat & mask) - - bx lr - -power_branch_only - vmov.u8 d27, #3 - vmov.u8 d21, #2 - vaddl.u8 q14, d6, d7 ; op2 = p0 + q0 - vmlal.u8 q14, d3, d27 ; op2 += p3 * 3 - vmlal.u8 q14, d4, d21 ; op2 += p2 * 2 - vaddw.u8 q14, d5 ; op2 += p1 - vqrshrn.u16 d0, q14, #3 ; op2 - - vsubw.u8 q14, d3 ; op1 = op2 - p3 - vsubw.u8 q14, d4 ; op1 -= p2 - vaddw.u8 q14, d5 ; op1 += p1 - vaddw.u8 q14, d16 ; op1 += q1 - vqrshrn.u16 d1, q14, #3 ; op1 - - vsubw.u8 q14, d3 ; op0 = op1 - p3 - vsubw.u8 q14, d5 ; op0 -= p1 - vaddw.u8 q14, d6 ; op0 += p0 - vaddw.u8 q14, d17 ; op0 += q2 - vqrshrn.u16 d2, q14, #3 ; op0 - - vsubw.u8 q14, d3 ; oq0 = op0 - p3 - vsubw.u8 q14, d6 ; oq0 -= p0 - vaddw.u8 q14, d7 ; oq0 += q0 - vaddw.u8 q14, d18 ; oq0 += q3 - vqrshrn.u16 d3, q14, #3 ; oq0 - - vsubw.u8 q14, d4 ; oq1 = oq0 - p2 - vsubw.u8 q14, d7 ; oq1 -= q0 - vaddw.u8 q14, d16 ; oq1 += q1 - vaddw.u8 q14, d18 ; oq1 += q3 - vqrshrn.u16 d4, q14, #3 ; oq1 - - vsubw.u8 q14, d5 ; oq2 = oq1 - p1 - vsubw.u8 q14, d16 ; oq2 -= q1 - vaddw.u8 q14, d17 ; oq2 += q2 - vaddw.u8 q14, d18 ; oq2 += q3 - vqrshrn.u16 d5, q14, #3 ; oq2 - - bx lr - -filter_branch_only - ; TODO(fgalligan): See if we can rearange registers so we do not need to - ; do the 2 vswp. - vswp d0, d4 ; op2 - vswp d5, d17 ; oq2 - veor d2, d24, d22 ; *op0 = u^0x80 - veor d3, d21, d22 ; *oq0 = u^0x80 - veor d1, d25, d22 ; *op1 = u^0x80 - veor d4, d26, d22 ; *oq1 = u^0x80 - - bx lr - - ENDP ; |vpx_mbloop_filter_neon| - - END diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/loopfilter_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/loopfilter_neon.c deleted file mode 100644 index 579096d7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/loopfilter_neon.c +++ /dev/null @@ -1,1107 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/transpose_neon.h" - -// For all the static inline functions, the functions ending with '_8' process -// 8 samples in a bunch, and the functions ending with '_16' process 16 samples -// in a bunch. - -#define FUN_LOAD_THRESH(w, r) \ - static INLINE void load_thresh_##w( \ - const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh, \ - uint8x##w##_t *blimit_vec, uint8x##w##_t *limit_vec, \ - uint8x##w##_t *thresh_vec) { \ - *blimit_vec = vld1##r##dup_u8(blimit); \ - *limit_vec = vld1##r##dup_u8(limit); \ - *thresh_vec = vld1##r##dup_u8(thresh); \ - } - -FUN_LOAD_THRESH(8, _) // load_thresh_8 -FUN_LOAD_THRESH(16, q_) // load_thresh_16 -#undef FUN_LOAD_THRESH - -static INLINE void load_thresh_8_dual( - const uint8_t *blimit0, const uint8_t *limit0, const uint8_t *thresh0, - const uint8_t *blimit1, const uint8_t *limit1, const uint8_t *thresh1, - uint8x16_t *blimit_vec, uint8x16_t *limit_vec, uint8x16_t *thresh_vec) { - *blimit_vec = vcombine_u8(vld1_dup_u8(blimit0), vld1_dup_u8(blimit1)); - *limit_vec = vcombine_u8(vld1_dup_u8(limit0), vld1_dup_u8(limit1)); - *thresh_vec = vcombine_u8(vld1_dup_u8(thresh0), vld1_dup_u8(thresh1)); -} - -// Here flat is 64-bit long, with each 8-bit (or 4-bit) chunk being a mask of a -// pixel. When used to control filter branches, we only detect whether it is all -// 0s or all 1s. We pairwise add flat to a 32-bit long number flat_status. -// flat equals 0 if and only if flat_status equals 0. -// flat equals -1 (all 1s) if and only if flat_status equals -2. (This is true -// because each mask occupies more than 1 bit.) -static INLINE uint32_t calc_flat_status_8(uint8x8_t flat) { - return vget_lane_u32( - vreinterpret_u32_u64(vpaddl_u32(vreinterpret_u32_u8(flat))), 0); -} - -// Here flat is 128-bit long, with each 8-bit chunk being a mask of a pixel. -// When used to control filter branches, we only detect whether it is all 0s or -// all 1s. We narrowing shift right each 16-bit chunk by 4 arithmetically, so -// we get a 64-bit long number, with each 4-bit chunk being a mask of a pixel. -// Then we pairwise add flat to a 32-bit long number flat_status. -// flat equals 0 if and only if flat_status equals 0. -// flat equals -1 (all 1s) if and only if flat_status equals -2. (This is true -// because each mask occupies more than 1 bit.) -static INLINE uint32_t calc_flat_status_16(uint8x16_t flat) { - const uint8x8_t flat_4bit = - vreinterpret_u8_s8(vshrn_n_s16(vreinterpretq_s16_u8(flat), 4)); - return calc_flat_status_8(flat_4bit); -} - -#define FUN_FILTER_HEV_MASK4(w, r) \ - static INLINE uint8x##w##_t filter_hev_mask4_##w( \ - const uint8x##w##_t limit, const uint8x##w##_t blimit, \ - const uint8x##w##_t thresh, const uint8x##w##_t p3, \ - const uint8x##w##_t p2, const uint8x##w##_t p1, const uint8x##w##_t p0, \ - const uint8x##w##_t q0, const uint8x##w##_t q1, const uint8x##w##_t q2, \ - const uint8x##w##_t q3, uint8x##w##_t *hev, uint8x##w##_t *mask) { \ - uint8x##w##_t max, t0, t1; \ - \ - max = vabd##r##u8(p1, p0); \ - max = vmax##r##u8(max, vabd##r##u8(q1, q0)); \ - *hev = vcgt##r##u8(max, thresh); \ - *mask = vmax##r##u8(max, vabd##r##u8(p3, p2)); \ - *mask = vmax##r##u8(*mask, vabd##r##u8(p2, p1)); \ - *mask = vmax##r##u8(*mask, vabd##r##u8(q2, q1)); \ - *mask = vmax##r##u8(*mask, vabd##r##u8(q3, q2)); \ - t0 = vabd##r##u8(p0, q0); \ - t1 = vabd##r##u8(p1, q1); \ - t0 = vqadd##r##u8(t0, t0); \ - t1 = vshr##r##n_u8(t1, 1); \ - t0 = vqadd##r##u8(t0, t1); \ - *mask = vcle##r##u8(*mask, limit); \ - t0 = vcle##r##u8(t0, blimit); \ - *mask = vand##r##u8(*mask, t0); \ - \ - return max; \ - } - -FUN_FILTER_HEV_MASK4(8, _) // filter_hev_mask4_8 -FUN_FILTER_HEV_MASK4(16, q_) // filter_hev_mask4_16 -#undef FUN_FILTER_HEV_MASK4 - -#define FUN_FILTER_FLAT_HEV_MASK(w, r) \ - static INLINE uint8x##w##_t filter_flat_hev_mask_##w( \ - const uint8x##w##_t limit, const uint8x##w##_t blimit, \ - const uint8x##w##_t thresh, const uint8x##w##_t p3, \ - const uint8x##w##_t p2, const uint8x##w##_t p1, const uint8x##w##_t p0, \ - const uint8x##w##_t q0, const uint8x##w##_t q1, const uint8x##w##_t q2, \ - const uint8x##w##_t q3, uint8x##w##_t *flat, uint32_t *flat_status, \ - uint8x##w##_t *hev) { \ - uint8x##w##_t max, mask; \ - \ - max = filter_hev_mask4_##w(limit, blimit, thresh, p3, p2, p1, p0, q0, q1, \ - q2, q3, hev, &mask); \ - *flat = vmax##r##u8(max, vabd##r##u8(p2, p0)); \ - *flat = vmax##r##u8(*flat, vabd##r##u8(q2, q0)); \ - *flat = vmax##r##u8(*flat, vabd##r##u8(p3, p0)); \ - *flat = vmax##r##u8(*flat, vabd##r##u8(q3, q0)); \ - *flat = vcle##r##u8(*flat, vdup##r##n_u8(1)); /* flat_mask4() */ \ - *flat = vand##r##u8(*flat, mask); \ - *flat_status = calc_flat_status_##w(*flat); \ - \ - return mask; \ - } - -FUN_FILTER_FLAT_HEV_MASK(8, _) // filter_flat_hev_mask_8 -FUN_FILTER_FLAT_HEV_MASK(16, q_) // filter_flat_hev_mask_16 -#undef FUN_FILTER_FLAT_HEV_MASK - -#define FUN_FLAT_MASK5(w, r) \ - static INLINE uint8x##w##_t flat_mask5_##w( \ - const uint8x##w##_t p4, const uint8x##w##_t p3, const uint8x##w##_t p2, \ - const uint8x##w##_t p1, const uint8x##w##_t p0, const uint8x##w##_t q0, \ - const uint8x##w##_t q1, const uint8x##w##_t q2, const uint8x##w##_t q3, \ - const uint8x##w##_t q4, const uint8x##w##_t flat, \ - uint32_t *flat2_status) { \ - uint8x##w##_t flat2 = vabd##r##u8(p4, p0); \ - flat2 = vmax##r##u8(flat2, vabd##r##u8(p3, p0)); \ - flat2 = vmax##r##u8(flat2, vabd##r##u8(p2, p0)); \ - flat2 = vmax##r##u8(flat2, vabd##r##u8(p1, p0)); \ - flat2 = vmax##r##u8(flat2, vabd##r##u8(q1, q0)); \ - flat2 = vmax##r##u8(flat2, vabd##r##u8(q2, q0)); \ - flat2 = vmax##r##u8(flat2, vabd##r##u8(q3, q0)); \ - flat2 = vmax##r##u8(flat2, vabd##r##u8(q4, q0)); \ - flat2 = vcle##r##u8(flat2, vdup##r##n_u8(1)); \ - flat2 = vand##r##u8(flat2, flat); \ - *flat2_status = calc_flat_status_##w(flat2); \ - \ - return flat2; \ - } - -FUN_FLAT_MASK5(8, _) // flat_mask5_8 -FUN_FLAT_MASK5(16, q_) // flat_mask5_16 -#undef FUN_FLAT_MASK5 - -#define FUN_FLIP_SIGN(w, r) \ - static INLINE int8x##w##_t flip_sign_##w(const uint8x##w##_t v) { \ - const uint8x##w##_t sign_bit = vdup##r##n_u8(0x80); \ - return vreinterpret##r##s8_u8(veor##r##u8(v, sign_bit)); \ - } - -FUN_FLIP_SIGN(8, _) // flip_sign_8 -FUN_FLIP_SIGN(16, q_) // flip_sign_16 -#undef FUN_FLIP_SIGN - -#define FUN_FLIP_SIGN_BACK(w, r) \ - static INLINE uint8x##w##_t flip_sign_back_##w(const int8x##w##_t v) { \ - const int8x##w##_t sign_bit = vdup##r##n_s8((int8_t)0x80); \ - return vreinterpret##r##u8_s8(veor##r##s8(v, sign_bit)); \ - } - -FUN_FLIP_SIGN_BACK(8, _) // flip_sign_back_8 -FUN_FLIP_SIGN_BACK(16, q_) // flip_sign_back_16 -#undef FUN_FLIP_SIGN_BACK - -static INLINE void filter_update_8(const uint8x8_t sub0, const uint8x8_t sub1, - const uint8x8_t add0, const uint8x8_t add1, - uint16x8_t *sum) { - *sum = vsubw_u8(*sum, sub0); - *sum = vsubw_u8(*sum, sub1); - *sum = vaddw_u8(*sum, add0); - *sum = vaddw_u8(*sum, add1); -} - -static INLINE void filter_update_16(const uint8x16_t sub0, - const uint8x16_t sub1, - const uint8x16_t add0, - const uint8x16_t add1, uint16x8_t *sum0, - uint16x8_t *sum1) { - *sum0 = vsubw_u8(*sum0, vget_low_u8(sub0)); - *sum1 = vsubw_u8(*sum1, vget_high_u8(sub0)); - *sum0 = vsubw_u8(*sum0, vget_low_u8(sub1)); - *sum1 = vsubw_u8(*sum1, vget_high_u8(sub1)); - *sum0 = vaddw_u8(*sum0, vget_low_u8(add0)); - *sum1 = vaddw_u8(*sum1, vget_high_u8(add0)); - *sum0 = vaddw_u8(*sum0, vget_low_u8(add1)); - *sum1 = vaddw_u8(*sum1, vget_high_u8(add1)); -} - -static INLINE uint8x8_t calc_7_tap_filter_8_kernel(const uint8x8_t sub0, - const uint8x8_t sub1, - const uint8x8_t add0, - const uint8x8_t add1, - uint16x8_t *sum) { - filter_update_8(sub0, sub1, add0, add1, sum); - return vrshrn_n_u16(*sum, 3); -} - -static INLINE uint8x16_t calc_7_tap_filter_16_kernel( - const uint8x16_t sub0, const uint8x16_t sub1, const uint8x16_t add0, - const uint8x16_t add1, uint16x8_t *sum0, uint16x8_t *sum1) { - filter_update_16(sub0, sub1, add0, add1, sum0, sum1); - return vcombine_u8(vrshrn_n_u16(*sum0, 3), vrshrn_n_u16(*sum1, 3)); -} - -static INLINE uint8x8_t apply_15_tap_filter_8_kernel( - const uint8x8_t flat, const uint8x8_t sub0, const uint8x8_t sub1, - const uint8x8_t add0, const uint8x8_t add1, const uint8x8_t in, - uint16x8_t *sum) { - filter_update_8(sub0, sub1, add0, add1, sum); - return vbsl_u8(flat, vrshrn_n_u16(*sum, 4), in); -} - -static INLINE uint8x16_t apply_15_tap_filter_16_kernel( - const uint8x16_t flat, const uint8x16_t sub0, const uint8x16_t sub1, - const uint8x16_t add0, const uint8x16_t add1, const uint8x16_t in, - uint16x8_t *sum0, uint16x8_t *sum1) { - uint8x16_t t; - filter_update_16(sub0, sub1, add0, add1, sum0, sum1); - t = vcombine_u8(vrshrn_n_u16(*sum0, 4), vrshrn_n_u16(*sum1, 4)); - return vbslq_u8(flat, t, in); -} - -// 7-tap filter [1, 1, 1, 2, 1, 1, 1] -static INLINE void calc_7_tap_filter_8(const uint8x8_t p3, const uint8x8_t p2, - const uint8x8_t p1, const uint8x8_t p0, - const uint8x8_t q0, const uint8x8_t q1, - const uint8x8_t q2, const uint8x8_t q3, - uint8x8_t *op2, uint8x8_t *op1, - uint8x8_t *op0, uint8x8_t *oq0, - uint8x8_t *oq1, uint8x8_t *oq2) { - uint16x8_t sum; - sum = vaddl_u8(p3, p3); // 2*p3 - sum = vaddw_u8(sum, p3); // 3*p3 - sum = vaddw_u8(sum, p2); // 3*p3+p2 - sum = vaddw_u8(sum, p2); // 3*p3+2*p2 - sum = vaddw_u8(sum, p1); // 3*p3+2*p2+p1 - sum = vaddw_u8(sum, p0); // 3*p3+2*p2+p1+p0 - sum = vaddw_u8(sum, q0); // 3*p3+2*p2+p1+p0+q0 - *op2 = vrshrn_n_u16(sum, 3); - *op1 = calc_7_tap_filter_8_kernel(p3, p2, p1, q1, &sum); - *op0 = calc_7_tap_filter_8_kernel(p3, p1, p0, q2, &sum); - *oq0 = calc_7_tap_filter_8_kernel(p3, p0, q0, q3, &sum); - *oq1 = calc_7_tap_filter_8_kernel(p2, q0, q1, q3, &sum); - *oq2 = calc_7_tap_filter_8_kernel(p1, q1, q2, q3, &sum); -} - -static INLINE void calc_7_tap_filter_16( - const uint8x16_t p3, const uint8x16_t p2, const uint8x16_t p1, - const uint8x16_t p0, const uint8x16_t q0, const uint8x16_t q1, - const uint8x16_t q2, const uint8x16_t q3, uint8x16_t *op2, uint8x16_t *op1, - uint8x16_t *op0, uint8x16_t *oq0, uint8x16_t *oq1, uint8x16_t *oq2) { - uint16x8_t sum0, sum1; - sum0 = vaddl_u8(vget_low_u8(p3), vget_low_u8(p3)); // 2*p3 - sum1 = vaddl_u8(vget_high_u8(p3), vget_high_u8(p3)); // 2*p3 - sum0 = vaddw_u8(sum0, vget_low_u8(p3)); // 3*p3 - sum1 = vaddw_u8(sum1, vget_high_u8(p3)); // 3*p3 - sum0 = vaddw_u8(sum0, vget_low_u8(p2)); // 3*p3+p2 - sum1 = vaddw_u8(sum1, vget_high_u8(p2)); // 3*p3+p2 - sum0 = vaddw_u8(sum0, vget_low_u8(p2)); // 3*p3+2*p2 - sum1 = vaddw_u8(sum1, vget_high_u8(p2)); // 3*p3+2*p2 - sum0 = vaddw_u8(sum0, vget_low_u8(p1)); // 3*p3+2*p2+p1 - sum1 = vaddw_u8(sum1, vget_high_u8(p1)); // 3*p3+2*p2+p1 - sum0 = vaddw_u8(sum0, vget_low_u8(p0)); // 3*p3+2*p2+p1+p0 - sum1 = vaddw_u8(sum1, vget_high_u8(p0)); // 3*p3+2*p2+p1+p0 - sum0 = vaddw_u8(sum0, vget_low_u8(q0)); // 3*p3+2*p2+p1+p0+q0 - sum1 = vaddw_u8(sum1, vget_high_u8(q0)); // 3*p3+2*p2+p1+p0+q0 - *op2 = vcombine_u8(vrshrn_n_u16(sum0, 3), vrshrn_n_u16(sum1, 3)); - *op1 = calc_7_tap_filter_16_kernel(p3, p2, p1, q1, &sum0, &sum1); - *op0 = calc_7_tap_filter_16_kernel(p3, p1, p0, q2, &sum0, &sum1); - *oq0 = calc_7_tap_filter_16_kernel(p3, p0, q0, q3, &sum0, &sum1); - *oq1 = calc_7_tap_filter_16_kernel(p2, q0, q1, q3, &sum0, &sum1); - *oq2 = calc_7_tap_filter_16_kernel(p1, q1, q2, q3, &sum0, &sum1); -} - -#define FUN_APPLY_7_TAP_FILTER(w, r) \ - static INLINE void apply_7_tap_filter_##w( \ - const uint8x##w##_t flat, const uint8x##w##_t p3, \ - const uint8x##w##_t p2, const uint8x##w##_t p1, const uint8x##w##_t p0, \ - const uint8x##w##_t q0, const uint8x##w##_t q1, const uint8x##w##_t q2, \ - const uint8x##w##_t q3, uint8x##w##_t *op2, uint8x##w##_t *op1, \ - uint8x##w##_t *op0, uint8x##w##_t *oq0, uint8x##w##_t *oq1, \ - uint8x##w##_t *oq2) { \ - uint8x##w##_t tp1, tp0, tq0, tq1; \ - calc_7_tap_filter_##w(p3, p2, p1, p0, q0, q1, q2, q3, op2, &tp1, &tp0, \ - &tq0, &tq1, oq2); \ - *op2 = vbsl##r##u8(flat, *op2, p2); \ - *op1 = vbsl##r##u8(flat, tp1, *op1); \ - *op0 = vbsl##r##u8(flat, tp0, *op0); \ - *oq0 = vbsl##r##u8(flat, tq0, *oq0); \ - *oq1 = vbsl##r##u8(flat, tq1, *oq1); \ - *oq2 = vbsl##r##u8(flat, *oq2, q2); \ - } - -FUN_APPLY_7_TAP_FILTER(8, _) // apply_7_tap_filter_8 -FUN_APPLY_7_TAP_FILTER(16, q_) // apply_7_tap_filter_16 -#undef FUN_APPLY_7_TAP_FILTER - -// 15-tap filter [1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1] -static INLINE void apply_15_tap_filter_8( - const uint8x8_t flat2, const uint8x8_t p7, const uint8x8_t p6, - const uint8x8_t p5, const uint8x8_t p4, const uint8x8_t p3, - const uint8x8_t p2, const uint8x8_t p1, const uint8x8_t p0, - const uint8x8_t q0, const uint8x8_t q1, const uint8x8_t q2, - const uint8x8_t q3, const uint8x8_t q4, const uint8x8_t q5, - const uint8x8_t q6, const uint8x8_t q7, uint8x8_t *op6, uint8x8_t *op5, - uint8x8_t *op4, uint8x8_t *op3, uint8x8_t *op2, uint8x8_t *op1, - uint8x8_t *op0, uint8x8_t *oq0, uint8x8_t *oq1, uint8x8_t *oq2, - uint8x8_t *oq3, uint8x8_t *oq4, uint8x8_t *oq5, uint8x8_t *oq6) { - uint16x8_t sum; - sum = vshll_n_u8(p7, 3); // 8*p7 - sum = vsubw_u8(sum, p7); // 7*p7 - sum = vaddw_u8(sum, p6); // 7*p7+p6 - sum = vaddw_u8(sum, p6); // 7*p7+2*p6 - sum = vaddw_u8(sum, p5); // 7*p7+2*p6+p5 - sum = vaddw_u8(sum, p4); // 7*p7+2*p6+p5+p4 - sum = vaddw_u8(sum, p3); // 7*p7+2*p6+p5+p4+p3 - sum = vaddw_u8(sum, p2); // 7*p7+2*p6+p5+p4+p3+p2 - sum = vaddw_u8(sum, p1); // 7*p7+2*p6+p5+p4+p3+p2+p1 - sum = vaddw_u8(sum, p0); // 7*p7+2*p6+p5+p4+p3+p2+p1+p0 - sum = vaddw_u8(sum, q0); // 7*p7+2*p6+p5+p4+p3+p2+p1+p0+q0 - *op6 = vbsl_u8(flat2, vrshrn_n_u16(sum, 4), p6); - *op5 = apply_15_tap_filter_8_kernel(flat2, p7, p6, p5, q1, p5, &sum); - *op4 = apply_15_tap_filter_8_kernel(flat2, p7, p5, p4, q2, p4, &sum); - *op3 = apply_15_tap_filter_8_kernel(flat2, p7, p4, p3, q3, p3, &sum); - *op2 = apply_15_tap_filter_8_kernel(flat2, p7, p3, p2, q4, *op2, &sum); - *op1 = apply_15_tap_filter_8_kernel(flat2, p7, p2, p1, q5, *op1, &sum); - *op0 = apply_15_tap_filter_8_kernel(flat2, p7, p1, p0, q6, *op0, &sum); - *oq0 = apply_15_tap_filter_8_kernel(flat2, p7, p0, q0, q7, *oq0, &sum); - *oq1 = apply_15_tap_filter_8_kernel(flat2, p6, q0, q1, q7, *oq1, &sum); - *oq2 = apply_15_tap_filter_8_kernel(flat2, p5, q1, q2, q7, *oq2, &sum); - *oq3 = apply_15_tap_filter_8_kernel(flat2, p4, q2, q3, q7, q3, &sum); - *oq4 = apply_15_tap_filter_8_kernel(flat2, p3, q3, q4, q7, q4, &sum); - *oq5 = apply_15_tap_filter_8_kernel(flat2, p2, q4, q5, q7, q5, &sum); - *oq6 = apply_15_tap_filter_8_kernel(flat2, p1, q5, q6, q7, q6, &sum); -} - -static INLINE void apply_15_tap_filter_16( - const uint8x16_t flat2, const uint8x16_t p7, const uint8x16_t p6, - const uint8x16_t p5, const uint8x16_t p4, const uint8x16_t p3, - const uint8x16_t p2, const uint8x16_t p1, const uint8x16_t p0, - const uint8x16_t q0, const uint8x16_t q1, const uint8x16_t q2, - const uint8x16_t q3, const uint8x16_t q4, const uint8x16_t q5, - const uint8x16_t q6, const uint8x16_t q7, uint8x16_t *op6, uint8x16_t *op5, - uint8x16_t *op4, uint8x16_t *op3, uint8x16_t *op2, uint8x16_t *op1, - uint8x16_t *op0, uint8x16_t *oq0, uint8x16_t *oq1, uint8x16_t *oq2, - uint8x16_t *oq3, uint8x16_t *oq4, uint8x16_t *oq5, uint8x16_t *oq6) { - uint16x8_t sum0, sum1; - uint8x16_t t; - sum0 = vshll_n_u8(vget_low_u8(p7), 3); // 8*p7 - sum1 = vshll_n_u8(vget_high_u8(p7), 3); // 8*p7 - sum0 = vsubw_u8(sum0, vget_low_u8(p7)); // 7*p7 - sum1 = vsubw_u8(sum1, vget_high_u8(p7)); // 7*p7 - sum0 = vaddw_u8(sum0, vget_low_u8(p6)); // 7*p7+p6 - sum1 = vaddw_u8(sum1, vget_high_u8(p6)); // 7*p7+p6 - sum0 = vaddw_u8(sum0, vget_low_u8(p6)); // 7*p7+2*p6 - sum1 = vaddw_u8(sum1, vget_high_u8(p6)); // 7*p7+2*p6 - sum0 = vaddw_u8(sum0, vget_low_u8(p5)); // 7*p7+2*p6+p5 - sum1 = vaddw_u8(sum1, vget_high_u8(p5)); // 7*p7+2*p6+p5 - sum0 = vaddw_u8(sum0, vget_low_u8(p4)); // 7*p7+2*p6+p5+p4 - sum1 = vaddw_u8(sum1, vget_high_u8(p4)); // 7*p7+2*p6+p5+p4 - sum0 = vaddw_u8(sum0, vget_low_u8(p3)); // 7*p7+2*p6+p5+p4+p3 - sum1 = vaddw_u8(sum1, vget_high_u8(p3)); // 7*p7+2*p6+p5+p4+p3 - sum0 = vaddw_u8(sum0, vget_low_u8(p2)); // 7*p7+2*p6+p5+p4+p3+p2 - sum1 = vaddw_u8(sum1, vget_high_u8(p2)); // 7*p7+2*p6+p5+p4+p3+p2 - sum0 = vaddw_u8(sum0, vget_low_u8(p1)); // 7*p7+2*p6+p5+p4+p3+p2+p1 - sum1 = vaddw_u8(sum1, vget_high_u8(p1)); // 7*p7+2*p6+p5+p4+p3+p2+p1 - sum0 = vaddw_u8(sum0, vget_low_u8(p0)); // 7*p7+2*p6+p5+p4+p3+p2+p1+p0 - sum1 = vaddw_u8(sum1, vget_high_u8(p0)); // 7*p7+2*p6+p5+p4+p3+p2+p1+p0 - sum0 = vaddw_u8(sum0, vget_low_u8(q0)); // 7*p7+2*p6+p5+p4+p3+p2+p1+p0+q0 - sum1 = vaddw_u8(sum1, vget_high_u8(q0)); // 7*p7+2*p6+p5+p4+p3+p2+p1+p0+q0 - t = vcombine_u8(vrshrn_n_u16(sum0, 4), vrshrn_n_u16(sum1, 4)); - *op6 = vbslq_u8(flat2, t, p6); - *op5 = apply_15_tap_filter_16_kernel(flat2, p7, p6, p5, q1, p5, &sum0, &sum1); - *op4 = apply_15_tap_filter_16_kernel(flat2, p7, p5, p4, q2, p4, &sum0, &sum1); - *op3 = apply_15_tap_filter_16_kernel(flat2, p7, p4, p3, q3, p3, &sum0, &sum1); - *op2 = - apply_15_tap_filter_16_kernel(flat2, p7, p3, p2, q4, *op2, &sum0, &sum1); - *op1 = - apply_15_tap_filter_16_kernel(flat2, p7, p2, p1, q5, *op1, &sum0, &sum1); - *op0 = - apply_15_tap_filter_16_kernel(flat2, p7, p1, p0, q6, *op0, &sum0, &sum1); - *oq0 = - apply_15_tap_filter_16_kernel(flat2, p7, p0, q0, q7, *oq0, &sum0, &sum1); - *oq1 = - apply_15_tap_filter_16_kernel(flat2, p6, q0, q1, q7, *oq1, &sum0, &sum1); - *oq2 = - apply_15_tap_filter_16_kernel(flat2, p5, q1, q2, q7, *oq2, &sum0, &sum1); - *oq3 = apply_15_tap_filter_16_kernel(flat2, p4, q2, q3, q7, q3, &sum0, &sum1); - *oq4 = apply_15_tap_filter_16_kernel(flat2, p3, q3, q4, q7, q4, &sum0, &sum1); - *oq5 = apply_15_tap_filter_16_kernel(flat2, p2, q4, q5, q7, q5, &sum0, &sum1); - *oq6 = apply_15_tap_filter_16_kernel(flat2, p1, q5, q6, q7, q6, &sum0, &sum1); -} - -#define FUN_FILTER4(w, r) \ - static INLINE void filter4_##w( \ - const uint8x##w##_t mask, const uint8x##w##_t hev, \ - const uint8x##w##_t p1, const uint8x##w##_t p0, const uint8x##w##_t q0, \ - const uint8x##w##_t q1, uint8x##w##_t *op1, uint8x##w##_t *op0, \ - uint8x##w##_t *oq0, uint8x##w##_t *oq1) { \ - int8x##w##_t filter, filter1, filter2, t; \ - int8x##w##_t ps1 = flip_sign_##w(p1); \ - int8x##w##_t ps0 = flip_sign_##w(p0); \ - int8x##w##_t qs0 = flip_sign_##w(q0); \ - int8x##w##_t qs1 = flip_sign_##w(q1); \ - \ - /* add outer taps if we have high edge variance */ \ - filter = vqsub##r##s8(ps1, qs1); \ - filter = vand##r##s8(filter, vreinterpret##r##s8_u8(hev)); \ - t = vqsub##r##s8(qs0, ps0); \ - \ - /* inner taps */ \ - filter = vqadd##r##s8(filter, t); \ - filter = vqadd##r##s8(filter, t); \ - filter = vqadd##r##s8(filter, t); \ - filter = vand##r##s8(filter, vreinterpret##r##s8_u8(mask)); \ - \ - /* save bottom 3 bits so that we round one side +4 and the other +3 */ \ - /* if it equals 4 we'll set it to adjust by -1 to account for the fact */ \ - /* we'd round it by 3 the other way */ \ - filter1 = vshr##r##n_s8(vqadd##r##s8(filter, vdup##r##n_s8(4)), 3); \ - filter2 = vshr##r##n_s8(vqadd##r##s8(filter, vdup##r##n_s8(3)), 3); \ - \ - qs0 = vqsub##r##s8(qs0, filter1); \ - ps0 = vqadd##r##s8(ps0, filter2); \ - *oq0 = flip_sign_back_##w(qs0); \ - *op0 = flip_sign_back_##w(ps0); \ - \ - /* outer tap adjustments */ \ - filter = vrshr##r##n_s8(filter1, 1); \ - filter = vbic##r##s8(filter, vreinterpret##r##s8_u8(hev)); \ - \ - qs1 = vqsub##r##s8(qs1, filter); \ - ps1 = vqadd##r##s8(ps1, filter); \ - *oq1 = flip_sign_back_##w(qs1); \ - *op1 = flip_sign_back_##w(ps1); \ - } - -FUN_FILTER4(8, _) // filter4_8 -FUN_FILTER4(16, q_) // filter4_16 -#undef FUN_FILTER4 - -#define FUN_FILTER8(w) \ - static INLINE void filter8_##w( \ - const uint8x##w##_t mask, const uint8x##w##_t flat, \ - const uint32_t flat_status, const uint8x##w##_t hev, \ - const uint8x##w##_t p3, const uint8x##w##_t p2, const uint8x##w##_t p1, \ - const uint8x##w##_t p0, const uint8x##w##_t q0, const uint8x##w##_t q1, \ - const uint8x##w##_t q2, const uint8x##w##_t q3, uint8x##w##_t *op2, \ - uint8x##w##_t *op1, uint8x##w##_t *op0, uint8x##w##_t *oq0, \ - uint8x##w##_t *oq1, uint8x##w##_t *oq2) { \ - if (flat_status != (uint32_t)-2) { \ - filter4_##w(mask, hev, p1, p0, q0, q1, op1, op0, oq0, oq1); \ - *op2 = p2; \ - *oq2 = q2; \ - if (flat_status) { \ - apply_7_tap_filter_##w(flat, p3, p2, p1, p0, q0, q1, q2, q3, op2, op1, \ - op0, oq0, oq1, oq2); \ - } \ - } else { \ - calc_7_tap_filter_##w(p3, p2, p1, p0, q0, q1, q2, q3, op2, op1, op0, \ - oq0, oq1, oq2); \ - } \ - } - -FUN_FILTER8(8) // filter8_8 -FUN_FILTER8(16) // filter8_16 -#undef FUN_FILTER8 - -#define FUN_FILTER16(w) \ - static INLINE void filter16_##w( \ - const uint8x##w##_t mask, const uint8x##w##_t flat, \ - const uint32_t flat_status, const uint8x##w##_t flat2, \ - const uint32_t flat2_status, const uint8x##w##_t hev, \ - const uint8x##w##_t p7, const uint8x##w##_t p6, const uint8x##w##_t p5, \ - const uint8x##w##_t p4, const uint8x##w##_t p3, const uint8x##w##_t p2, \ - const uint8x##w##_t p1, const uint8x##w##_t p0, const uint8x##w##_t q0, \ - const uint8x##w##_t q1, const uint8x##w##_t q2, const uint8x##w##_t q3, \ - const uint8x##w##_t q4, const uint8x##w##_t q5, const uint8x##w##_t q6, \ - const uint8x##w##_t q7, uint8x##w##_t *op6, uint8x##w##_t *op5, \ - uint8x##w##_t *op4, uint8x##w##_t *op3, uint8x##w##_t *op2, \ - uint8x##w##_t *op1, uint8x##w##_t *op0, uint8x##w##_t *oq0, \ - uint8x##w##_t *oq1, uint8x##w##_t *oq2, uint8x##w##_t *oq3, \ - uint8x##w##_t *oq4, uint8x##w##_t *oq5, uint8x##w##_t *oq6) { \ - if (flat_status != (uint32_t)-2) { \ - filter4_##w(mask, hev, p1, p0, q0, q1, op1, op0, oq0, oq1); \ - } \ - \ - if (flat_status) { \ - *op2 = p2; \ - *oq2 = q2; \ - if (flat2_status != (uint32_t)-2) { \ - apply_7_tap_filter_##w(flat, p3, p2, p1, p0, q0, q1, q2, q3, op2, op1, \ - op0, oq0, oq1, oq2); \ - } \ - if (flat2_status) { \ - apply_15_tap_filter_##w(flat2, p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, \ - q2, q3, q4, q5, q6, q7, op6, op5, op4, op3, \ - op2, op1, op0, oq0, oq1, oq2, oq3, oq4, oq5, \ - oq6); \ - } \ - } \ - } - -FUN_FILTER16(8) // filter16_8 -FUN_FILTER16(16) // filter16_16 -#undef FUN_FILTER16 - -#define FUN_LOAD8(w, r) \ - static INLINE void load_##w##x8( \ - const uint8_t *s, const int p, uint8x##w##_t *p3, uint8x##w##_t *p2, \ - uint8x##w##_t *p1, uint8x##w##_t *p0, uint8x##w##_t *q0, \ - uint8x##w##_t *q1, uint8x##w##_t *q2, uint8x##w##_t *q3) { \ - *p3 = vld1##r##u8(s); \ - s += p; \ - *p2 = vld1##r##u8(s); \ - s += p; \ - *p1 = vld1##r##u8(s); \ - s += p; \ - *p0 = vld1##r##u8(s); \ - s += p; \ - *q0 = vld1##r##u8(s); \ - s += p; \ - *q1 = vld1##r##u8(s); \ - s += p; \ - *q2 = vld1##r##u8(s); \ - s += p; \ - *q3 = vld1##r##u8(s); \ - } - -FUN_LOAD8(8, _) // load_8x8 -FUN_LOAD8(16, q_) // load_16x8 -#undef FUN_LOAD8 - -#define FUN_LOAD16(w, r) \ - static INLINE void load_##w##x16( \ - const uint8_t *s, const int p, uint8x##w##_t *s0, uint8x##w##_t *s1, \ - uint8x##w##_t *s2, uint8x##w##_t *s3, uint8x##w##_t *s4, \ - uint8x##w##_t *s5, uint8x##w##_t *s6, uint8x##w##_t *s7, \ - uint8x##w##_t *s8, uint8x##w##_t *s9, uint8x##w##_t *s10, \ - uint8x##w##_t *s11, uint8x##w##_t *s12, uint8x##w##_t *s13, \ - uint8x##w##_t *s14, uint8x##w##_t *s15) { \ - *s0 = vld1##r##u8(s); \ - s += p; \ - *s1 = vld1##r##u8(s); \ - s += p; \ - *s2 = vld1##r##u8(s); \ - s += p; \ - *s3 = vld1##r##u8(s); \ - s += p; \ - *s4 = vld1##r##u8(s); \ - s += p; \ - *s5 = vld1##r##u8(s); \ - s += p; \ - *s6 = vld1##r##u8(s); \ - s += p; \ - *s7 = vld1##r##u8(s); \ - s += p; \ - *s8 = vld1##r##u8(s); \ - s += p; \ - *s9 = vld1##r##u8(s); \ - s += p; \ - *s10 = vld1##r##u8(s); \ - s += p; \ - *s11 = vld1##r##u8(s); \ - s += p; \ - *s12 = vld1##r##u8(s); \ - s += p; \ - *s13 = vld1##r##u8(s); \ - s += p; \ - *s14 = vld1##r##u8(s); \ - s += p; \ - *s15 = vld1##r##u8(s); \ - } - -FUN_LOAD16(8, _) // load_8x16 -FUN_LOAD16(16, q_) // load_16x16 -#undef FUN_LOAD16 - -#define FUN_STORE4(w, r) \ - static INLINE void store_##w##x4( \ - uint8_t *s, const int p, const uint8x##w##_t s0, const uint8x##w##_t s1, \ - const uint8x##w##_t s2, const uint8x##w##_t s3) { \ - vst1##r##u8(s, s0); \ - s += p; \ - vst1##r##u8(s, s1); \ - s += p; \ - vst1##r##u8(s, s2); \ - s += p; \ - vst1##r##u8(s, s3); \ - } - -FUN_STORE4(8, _) // store_8x4 -FUN_STORE4(16, q_) // store_16x4 -#undef FUN_STORE4 - -#define FUN_STORE6(w, r) \ - static INLINE void store_##w##x6( \ - uint8_t *s, const int p, const uint8x##w##_t s0, const uint8x##w##_t s1, \ - const uint8x##w##_t s2, const uint8x##w##_t s3, const uint8x##w##_t s4, \ - const uint8x##w##_t s5) { \ - vst1##r##u8(s, s0); \ - s += p; \ - vst1##r##u8(s, s1); \ - s += p; \ - vst1##r##u8(s, s2); \ - s += p; \ - vst1##r##u8(s, s3); \ - s += p; \ - vst1##r##u8(s, s4); \ - s += p; \ - vst1##r##u8(s, s5); \ - } - -FUN_STORE6(8, _) // store_8x6 -FUN_STORE6(16, q_) // store_16x6 -#undef FUN_STORE6 - -static INLINE void store_4x8(uint8_t *s, const int p, const uint8x8_t p1, - const uint8x8_t p0, const uint8x8_t q0, - const uint8x8_t q1) { - uint8x8x4_t o; - - o.val[0] = p1; - o.val[1] = p0; - o.val[2] = q0; - o.val[3] = q1; - vst4_lane_u8(s, o, 0); - s += p; - vst4_lane_u8(s, o, 1); - s += p; - vst4_lane_u8(s, o, 2); - s += p; - vst4_lane_u8(s, o, 3); - s += p; - vst4_lane_u8(s, o, 4); - s += p; - vst4_lane_u8(s, o, 5); - s += p; - vst4_lane_u8(s, o, 6); - s += p; - vst4_lane_u8(s, o, 7); -} - -static INLINE void store_6x8(uint8_t *s, const int p, const uint8x8_t s0, - const uint8x8_t s1, const uint8x8_t s2, - const uint8x8_t s3, const uint8x8_t s4, - const uint8x8_t s5) { - uint8x8x3_t o0, o1; - - o0.val[0] = s0; - o0.val[1] = s1; - o0.val[2] = s2; - o1.val[0] = s3; - o1.val[1] = s4; - o1.val[2] = s5; - vst3_lane_u8(s - 3, o0, 0); - vst3_lane_u8(s + 0, o1, 0); - s += p; - vst3_lane_u8(s - 3, o0, 1); - vst3_lane_u8(s + 0, o1, 1); - s += p; - vst3_lane_u8(s - 3, o0, 2); - vst3_lane_u8(s + 0, o1, 2); - s += p; - vst3_lane_u8(s - 3, o0, 3); - vst3_lane_u8(s + 0, o1, 3); - s += p; - vst3_lane_u8(s - 3, o0, 4); - vst3_lane_u8(s + 0, o1, 4); - s += p; - vst3_lane_u8(s - 3, o0, 5); - vst3_lane_u8(s + 0, o1, 5); - s += p; - vst3_lane_u8(s - 3, o0, 6); - vst3_lane_u8(s + 0, o1, 6); - s += p; - vst3_lane_u8(s - 3, o0, 7); - vst3_lane_u8(s + 0, o1, 7); -} - -#define FUN_STORE8(w, r) \ - static INLINE void store_##w##x8( \ - uint8_t *s, const int p, const uint8x##w##_t s0, const uint8x##w##_t s1, \ - const uint8x##w##_t s2, const uint8x##w##_t s3, const uint8x##w##_t s4, \ - const uint8x##w##_t s5, const uint8x##w##_t s6, \ - const uint8x##w##_t s7) { \ - vst1##r##u8(s, s0); \ - s += p; \ - vst1##r##u8(s, s1); \ - s += p; \ - vst1##r##u8(s, s2); \ - s += p; \ - vst1##r##u8(s, s3); \ - s += p; \ - vst1##r##u8(s, s4); \ - s += p; \ - vst1##r##u8(s, s5); \ - s += p; \ - vst1##r##u8(s, s6); \ - s += p; \ - vst1##r##u8(s, s7); \ - } - -FUN_STORE8(8, _) // store_8x8 -FUN_STORE8(16, q_) // store_16x8 -#undef FUN_STORE8 - -#define FUN_STORE14(w, r) \ - static INLINE void store_##w##x14( \ - uint8_t *s, const int p, const uint8x##w##_t p6, const uint8x##w##_t p5, \ - const uint8x##w##_t p4, const uint8x##w##_t p3, const uint8x##w##_t p2, \ - const uint8x##w##_t p1, const uint8x##w##_t p0, const uint8x##w##_t q0, \ - const uint8x##w##_t q1, const uint8x##w##_t q2, const uint8x##w##_t q3, \ - const uint8x##w##_t q4, const uint8x##w##_t q5, const uint8x##w##_t q6, \ - const uint32_t flat_status, const uint32_t flat2_status) { \ - if (flat_status) { \ - if (flat2_status) { \ - vst1##r##u8(s - 7 * p, p6); \ - vst1##r##u8(s - 6 * p, p5); \ - vst1##r##u8(s - 5 * p, p4); \ - vst1##r##u8(s - 4 * p, p3); \ - vst1##r##u8(s + 3 * p, q3); \ - vst1##r##u8(s + 4 * p, q4); \ - vst1##r##u8(s + 5 * p, q5); \ - vst1##r##u8(s + 6 * p, q6); \ - } \ - vst1##r##u8(s - 3 * p, p2); \ - vst1##r##u8(s + 2 * p, q2); \ - } \ - vst1##r##u8(s - 2 * p, p1); \ - vst1##r##u8(s - 1 * p, p0); \ - vst1##r##u8(s + 0 * p, q0); \ - vst1##r##u8(s + 1 * p, q1); \ - } - -FUN_STORE14(8, _) // store_8x14 -FUN_STORE14(16, q_) // store_16x14 -#undef FUN_STORE14 - -static INLINE void store_16x16(uint8_t *s, const int p, const uint8x16_t s0, - const uint8x16_t s1, const uint8x16_t s2, - const uint8x16_t s3, const uint8x16_t s4, - const uint8x16_t s5, const uint8x16_t s6, - const uint8x16_t s7, const uint8x16_t s8, - const uint8x16_t s9, const uint8x16_t s10, - const uint8x16_t s11, const uint8x16_t s12, - const uint8x16_t s13, const uint8x16_t s14, - const uint8x16_t s15) { - vst1q_u8(s, s0); - s += p; - vst1q_u8(s, s1); - s += p; - vst1q_u8(s, s2); - s += p; - vst1q_u8(s, s3); - s += p; - vst1q_u8(s, s4); - s += p; - vst1q_u8(s, s5); - s += p; - vst1q_u8(s, s6); - s += p; - vst1q_u8(s, s7); - s += p; - vst1q_u8(s, s8); - s += p; - vst1q_u8(s, s9); - s += p; - vst1q_u8(s, s10); - s += p; - vst1q_u8(s, s11); - s += p; - vst1q_u8(s, s12); - s += p; - vst1q_u8(s, s13); - s += p; - vst1q_u8(s, s14); - s += p; - vst1q_u8(s, s15); -} - -#define FUN_HOR_4_KERNEL(name, w) \ - static INLINE void lpf_horizontal_4##name##kernel( \ - uint8_t *s, const int p, const uint8x##w##_t blimit, \ - const uint8x##w##_t limit, const uint8x##w##_t thresh) { \ - uint8x##w##_t p3, p2, p1, p0, q0, q1, q2, q3, mask, hev; \ - \ - load_##w##x8(s - 4 * p, p, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3); \ - filter_hev_mask4_##w(limit, blimit, thresh, p3, p2, p1, p0, q0, q1, q2, \ - q3, &hev, &mask); \ - filter4_##w(mask, hev, p1, p0, q0, q1, &p1, &p0, &q0, &q1); \ - store_##w##x4(s - 2 * p, p, p1, p0, q0, q1); \ - } - -FUN_HOR_4_KERNEL(_, 8) // lpf_horizontal_4_kernel -FUN_HOR_4_KERNEL(_dual_, 16) // lpf_horizontal_4_dual_kernel -#undef FUN_HOR_4_KERNEL - -void vpx_lpf_horizontal_4_neon(uint8_t *s, int p, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh) { - uint8x8_t blimit_vec, limit_vec, thresh_vec; - load_thresh_8(blimit, limit, thresh, &blimit_vec, &limit_vec, &thresh_vec); - lpf_horizontal_4_kernel(s, p, blimit_vec, limit_vec, thresh_vec); -} - -void vpx_lpf_horizontal_4_dual_neon(uint8_t *s, int p, const uint8_t *blimit0, - const uint8_t *limit0, - const uint8_t *thresh0, - const uint8_t *blimit1, - const uint8_t *limit1, - const uint8_t *thresh1) { - uint8x16_t blimit_vec, limit_vec, thresh_vec; - load_thresh_8_dual(blimit0, limit0, thresh0, blimit1, limit1, thresh1, - &blimit_vec, &limit_vec, &thresh_vec); - lpf_horizontal_4_dual_kernel(s, p, blimit_vec, limit_vec, thresh_vec); -} - -void vpx_lpf_vertical_4_neon(uint8_t *s, int p, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh) { - uint8x8_t blimit_vec, limit_vec, thresh_vec, p3, p2, p1, p0, q0, q1, q2, q3, - mask, hev; - load_thresh_8(blimit, limit, thresh, &blimit_vec, &limit_vec, &thresh_vec); - load_8x8(s - 4, p, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3); - transpose_u8_8x8(&p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3); - filter_hev_mask4_8(limit_vec, blimit_vec, thresh_vec, p3, p2, p1, p0, q0, q1, - q2, q3, &hev, &mask); - filter4_8(mask, hev, p1, p0, q0, q1, &p1, &p0, &q0, &q1); - store_4x8(s - 2, p, p1, p0, q0, q1); -} - -void vpx_lpf_vertical_4_dual_neon(uint8_t *s, int p, const uint8_t *blimit0, - const uint8_t *limit0, const uint8_t *thresh0, - const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1) { - uint8x16_t blimit_vec, limit_vec, thresh_vec, p3, p2, p1, p0, q0, q1, q2, q3, - mask, hev; - uint8x8_t s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, - s15; - - load_thresh_8_dual(blimit0, limit0, thresh0, blimit1, limit1, thresh1, - &blimit_vec, &limit_vec, &thresh_vec); - load_8x16(s - 4, p, &s0, &s1, &s2, &s3, &s4, &s5, &s6, &s7, &s8, &s9, &s10, - &s11, &s12, &s13, &s14, &s15); - transpose_u8_8x16(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, - s14, s15, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3); - filter_hev_mask4_16(limit_vec, blimit_vec, thresh_vec, p3, p2, p1, p0, q0, q1, - q2, q3, &hev, &mask); - filter4_16(mask, hev, p1, p0, q0, q1, &p1, &p0, &q0, &q1); - s -= 2; - store_4x8(s, p, vget_low_u8(p1), vget_low_u8(p0), vget_low_u8(q0), - vget_low_u8(q1)); - store_4x8(s + 8 * p, p, vget_high_u8(p1), vget_high_u8(p0), vget_high_u8(q0), - vget_high_u8(q1)); -} - -void vpx_lpf_horizontal_8_neon(uint8_t *s, int p, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh) { - uint8x8_t blimit_vec, limit_vec, thresh_vec, p3, p2, p1, p0, q0, q1, q2, q3, - op2, op1, op0, oq0, oq1, oq2, mask, flat, hev; - uint32_t flat_status; - - load_thresh_8(blimit, limit, thresh, &blimit_vec, &limit_vec, &thresh_vec); - load_8x8(s - 4 * p, p, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3); - mask = filter_flat_hev_mask_8(limit_vec, blimit_vec, thresh_vec, p3, p2, p1, - p0, q0, q1, q2, q3, &flat, &flat_status, &hev); - filter8_8(mask, flat, flat_status, hev, p3, p2, p1, p0, q0, q1, q2, q3, &op2, - &op1, &op0, &oq0, &oq1, &oq2); - store_8x6(s - 3 * p, p, op2, op1, op0, oq0, oq1, oq2); -} - -void vpx_lpf_horizontal_8_dual_neon(uint8_t *s, int p, const uint8_t *blimit0, - const uint8_t *limit0, - const uint8_t *thresh0, - const uint8_t *blimit1, - const uint8_t *limit1, - const uint8_t *thresh1) { - uint8x16_t blimit_vec, limit_vec, thresh_vec, p3, p2, p1, p0, q0, q1, q2, q3, - op2, op1, op0, oq0, oq1, oq2, mask, flat, hev; - uint32_t flat_status; - - load_thresh_8_dual(blimit0, limit0, thresh0, blimit1, limit1, thresh1, - &blimit_vec, &limit_vec, &thresh_vec); - load_16x8(s - 4 * p, p, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3); - mask = filter_flat_hev_mask_16(limit_vec, blimit_vec, thresh_vec, p3, p2, p1, - p0, q0, q1, q2, q3, &flat, &flat_status, &hev); - filter8_16(mask, flat, flat_status, hev, p3, p2, p1, p0, q0, q1, q2, q3, &op2, - &op1, &op0, &oq0, &oq1, &oq2); - store_16x6(s - 3 * p, p, op2, op1, op0, oq0, oq1, oq2); -} - -void vpx_lpf_vertical_8_neon(uint8_t *s, int p, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh) { - uint8x8_t blimit_vec, limit_vec, thresh_vec, p3, p2, p1, p0, q0, q1, q2, q3, - op2, op1, op0, oq0, oq1, oq2, mask, flat, hev; - uint32_t flat_status; - - load_thresh_8(blimit, limit, thresh, &blimit_vec, &limit_vec, &thresh_vec); - load_8x8(s - 4, p, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3); - transpose_u8_8x8(&p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3); - mask = filter_flat_hev_mask_8(limit_vec, blimit_vec, thresh_vec, p3, p2, p1, - p0, q0, q1, q2, q3, &flat, &flat_status, &hev); - filter8_8(mask, flat, flat_status, hev, p3, p2, p1, p0, q0, q1, q2, q3, &op2, - &op1, &op0, &oq0, &oq1, &oq2); - // Note: transpose + store_8x8() is faster than store_6x8(). - transpose_u8_8x8(&p3, &op2, &op1, &op0, &oq0, &oq1, &oq2, &q3); - store_8x8(s - 4, p, p3, op2, op1, op0, oq0, oq1, oq2, q3); -} - -void vpx_lpf_vertical_8_dual_neon(uint8_t *s, int p, const uint8_t *blimit0, - const uint8_t *limit0, const uint8_t *thresh0, - const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1) { - uint8x16_t blimit_vec, limit_vec, thresh_vec, p3, p2, p1, p0, q0, q1, q2, q3, - op2, op1, op0, oq0, oq1, oq2, mask, flat, hev; - uint8x8_t s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, - s15; - uint32_t flat_status; - - load_thresh_8_dual(blimit0, limit0, thresh0, blimit1, limit1, thresh1, - &blimit_vec, &limit_vec, &thresh_vec); - load_8x16(s - 4, p, &s0, &s1, &s2, &s3, &s4, &s5, &s6, &s7, &s8, &s9, &s10, - &s11, &s12, &s13, &s14, &s15); - transpose_u8_8x16(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, - s14, s15, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3); - mask = filter_flat_hev_mask_16(limit_vec, blimit_vec, thresh_vec, p3, p2, p1, - p0, q0, q1, q2, q3, &flat, &flat_status, &hev); - filter8_16(mask, flat, flat_status, hev, p3, p2, p1, p0, q0, q1, q2, q3, &op2, - &op1, &op0, &oq0, &oq1, &oq2); - // Note: store_6x8() twice is faster than transpose + store_8x16(). - store_6x8(s, p, vget_low_u8(op2), vget_low_u8(op1), vget_low_u8(op0), - vget_low_u8(oq0), vget_low_u8(oq1), vget_low_u8(oq2)); - store_6x8(s + 8 * p, p, vget_high_u8(op2), vget_high_u8(op1), - vget_high_u8(op0), vget_high_u8(oq0), vget_high_u8(oq1), - vget_high_u8(oq2)); -} - -#define FUN_LPF_16_KERNEL(name, w) \ - static INLINE void lpf_16##name##kernel( \ - const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh, \ - const uint8x##w##_t p7, const uint8x##w##_t p6, const uint8x##w##_t p5, \ - const uint8x##w##_t p4, const uint8x##w##_t p3, const uint8x##w##_t p2, \ - const uint8x##w##_t p1, const uint8x##w##_t p0, const uint8x##w##_t q0, \ - const uint8x##w##_t q1, const uint8x##w##_t q2, const uint8x##w##_t q3, \ - const uint8x##w##_t q4, const uint8x##w##_t q5, const uint8x##w##_t q6, \ - const uint8x##w##_t q7, uint8x##w##_t *op6, uint8x##w##_t *op5, \ - uint8x##w##_t *op4, uint8x##w##_t *op3, uint8x##w##_t *op2, \ - uint8x##w##_t *op1, uint8x##w##_t *op0, uint8x##w##_t *oq0, \ - uint8x##w##_t *oq1, uint8x##w##_t *oq2, uint8x##w##_t *oq3, \ - uint8x##w##_t *oq4, uint8x##w##_t *oq5, uint8x##w##_t *oq6, \ - uint32_t *flat_status, uint32_t *flat2_status) { \ - uint8x##w##_t blimit_vec, limit_vec, thresh_vec, mask, flat, flat2, hev; \ - \ - load_thresh_##w(blimit, limit, thresh, &blimit_vec, &limit_vec, \ - &thresh_vec); \ - mask = filter_flat_hev_mask_##w(limit_vec, blimit_vec, thresh_vec, p3, p2, \ - p1, p0, q0, q1, q2, q3, &flat, \ - flat_status, &hev); \ - flat2 = flat_mask5_##w(p7, p6, p5, p4, p0, q0, q4, q5, q6, q7, flat, \ - flat2_status); \ - filter16_##w(mask, flat, *flat_status, flat2, *flat2_status, hev, p7, p6, \ - p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7, op6, \ - op5, op4, op3, op2, op1, op0, oq0, oq1, oq2, oq3, oq4, oq5, \ - oq6); \ - } - -FUN_LPF_16_KERNEL(_, 8) // lpf_16_kernel -FUN_LPF_16_KERNEL(_dual_, 16) // lpf_16_dual_kernel -#undef FUN_LPF_16_KERNEL - -// Quiet warnings of the form: 'vpx_dsp/arm/loopfilter_neon.c|981 col 42| -// warning: 'oq1' may be used uninitialized in this function -// [-Wmaybe-uninitialized]', for oq1-op1. Without reworking the code or adding -// an additional branch this warning cannot be silenced otherwise. The -// loopfilter is only called when needed for a block so these output pixels -// will be set. -#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - -void vpx_lpf_horizontal_16_neon(uint8_t *s, int p, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh) { - uint8x8_t p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7, op6, - op5, op4, op3, op2, op1, op0, oq0, oq1, oq2, oq3, oq4, oq5, oq6; - uint32_t flat_status, flat2_status; - - load_8x16(s - 8 * p, p, &p7, &p6, &p5, &p4, &p3, &p2, &p1, &p0, &q0, &q1, &q2, - &q3, &q4, &q5, &q6, &q7); - lpf_16_kernel(blimit, limit, thresh, p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, - q2, q3, q4, q5, q6, q7, &op6, &op5, &op4, &op3, &op2, &op1, - &op0, &oq0, &oq1, &oq2, &oq3, &oq4, &oq5, &oq6, &flat_status, - &flat2_status); - store_8x14(s, p, op6, op5, op4, op3, op2, op1, op0, oq0, oq1, oq2, oq3, oq4, - oq5, oq6, flat_status, flat2_status); -} - -void vpx_lpf_horizontal_16_dual_neon(uint8_t *s, int p, const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh) { - uint8x16_t p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7, - op6, op5, op4, op3, op2, op1, op0, oq0, oq1, oq2, oq3, oq4, oq5, oq6; - uint32_t flat_status, flat2_status; - - load_16x8(s - 4 * p, p, &p3, &p2, &p1, &p0, &q0, &q1, &q2, &q3); - p7 = vld1q_u8(s - 8 * p); - p6 = vld1q_u8(s - 7 * p); - p5 = vld1q_u8(s - 6 * p); - p4 = vld1q_u8(s - 5 * p); - q4 = vld1q_u8(s + 4 * p); - q5 = vld1q_u8(s + 5 * p); - q6 = vld1q_u8(s + 6 * p); - q7 = vld1q_u8(s + 7 * p); - lpf_16_dual_kernel(blimit, limit, thresh, p7, p6, p5, p4, p3, p2, p1, p0, q0, - q1, q2, q3, q4, q5, q6, q7, &op6, &op5, &op4, &op3, &op2, - &op1, &op0, &oq0, &oq1, &oq2, &oq3, &oq4, &oq5, &oq6, - &flat_status, &flat2_status); - store_16x14(s, p, op6, op5, op4, op3, op2, op1, op0, oq0, oq1, oq2, oq3, oq4, - oq5, oq6, flat_status, flat2_status); -} - -void vpx_lpf_vertical_16_neon(uint8_t *s, int p, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh) { - uint8x8_t p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7, op6, - op5, op4, op3, op2, op1, op0, oq0, oq1, oq2, oq3, oq4, oq5, oq6; - uint8x16_t s0, s1, s2, s3, s4, s5, s6, s7; - uint32_t flat_status, flat2_status; - - s -= 8; - load_16x8(s, p, &s0, &s1, &s2, &s3, &s4, &s5, &s6, &s7); - transpose_u8_16x8(s0, s1, s2, s3, s4, s5, s6, s7, &p7, &p6, &p5, &p4, &p3, - &p2, &p1, &p0, &q0, &q1, &q2, &q3, &q4, &q5, &q6, &q7); - lpf_16_kernel(blimit, limit, thresh, p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, - q2, q3, q4, q5, q6, q7, &op6, &op5, &op4, &op3, &op2, &op1, - &op0, &oq0, &oq1, &oq2, &oq3, &oq4, &oq5, &oq6, &flat_status, - &flat2_status); - if (flat_status) { - if (flat2_status) { - transpose_u8_8x16(p7, op6, op5, op4, op3, op2, op1, op0, oq0, oq1, oq2, - oq3, oq4, oq5, oq6, q7, &s0, &s1, &s2, &s3, &s4, &s5, - &s6, &s7); - store_16x8(s, p, s0, s1, s2, s3, s4, s5, s6, s7); - } else { - // Note: transpose + store_8x8() is faster than store_6x8(). - transpose_u8_8x8(&p3, &op2, &op1, &op0, &oq0, &oq1, &oq2, &q3); - store_8x8(s + 4, p, p3, op2, op1, op0, oq0, oq1, oq2, q3); - } - } else { - store_4x8(s + 6, p, op1, op0, oq0, oq1); - } -} - -void vpx_lpf_vertical_16_dual_neon(uint8_t *s, int p, const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh) { - uint8x16_t p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7, - op6, op5, op4, op3, op2, op1, op0, oq0, oq1, oq2, oq3, oq4, oq5, oq6; - uint8x16_t s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, - s15; - uint32_t flat_status, flat2_status; - - s -= 8; - load_16x16(s, p, &s0, &s1, &s2, &s3, &s4, &s5, &s6, &s7, &s8, &s9, &s10, &s11, - &s12, &s13, &s14, &s15); - transpose_u8_16x16(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, - s14, s15, &p7, &p6, &p5, &p4, &p3, &p2, &p1, &p0, &q0, &q1, - &q2, &q3, &q4, &q5, &q6, &q7); - lpf_16_dual_kernel(blimit, limit, thresh, p7, p6, p5, p4, p3, p2, p1, p0, q0, - q1, q2, q3, q4, q5, q6, q7, &op6, &op5, &op4, &op3, &op2, - &op1, &op0, &oq0, &oq1, &oq2, &oq3, &oq4, &oq5, &oq6, - &flat_status, &flat2_status); - if (flat_status) { - if (flat2_status) { - transpose_u8_16x16(p7, op6, op5, op4, op3, op2, op1, op0, oq0, oq1, oq2, - oq3, oq4, oq5, oq6, q7, &s0, &s1, &s2, &s3, &s4, &s5, - &s6, &s7, &s8, &s9, &s10, &s11, &s12, &s13, &s14, - &s15); - store_16x16(s, p, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, - s13, s14, s15); - } else { - // Note: store_6x8() twice is faster than transpose + store_8x16(). - s += 8; - store_6x8(s, p, vget_low_u8(op2), vget_low_u8(op1), vget_low_u8(op0), - vget_low_u8(oq0), vget_low_u8(oq1), vget_low_u8(oq2)); - store_6x8(s + 8 * p, p, vget_high_u8(op2), vget_high_u8(op1), - vget_high_u8(op0), vget_high_u8(oq0), vget_high_u8(oq1), - vget_high_u8(oq2)); - } - } else { - s += 6; - store_4x8(s, p, vget_low_u8(op1), vget_low_u8(op0), vget_low_u8(oq0), - vget_low_u8(oq1)); - store_4x8(s + 8 * p, p, vget_high_u8(op1), vget_high_u8(op0), - vget_high_u8(oq0), vget_high_u8(oq1)); - } -} - -#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__clang__) -#pragma GCC diagnostic pop -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/mem_neon.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/mem_neon.h deleted file mode 100644 index 268c4bd9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/mem_neon.h +++ /dev/null @@ -1,640 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_ARM_MEM_NEON_H_ -#define VPX_VPX_DSP_ARM_MEM_NEON_H_ - -#include -#include -#include - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/vpx_dsp_common.h" - -// Support for these xN intrinsics is lacking in older versions of GCC. -#if defined(__GNUC__) && !defined(__clang__) -#if __GNUC__ < 8 || defined(__arm__) -static INLINE uint8x16x2_t vld1q_u8_x2(uint8_t const *ptr) { - uint8x16x2_t res = { { vld1q_u8(ptr + 0 * 16), vld1q_u8(ptr + 1 * 16) } }; - return res; -} -#endif - -#if __GNUC__ < 9 || defined(__arm__) -static INLINE uint8x16x3_t vld1q_u8_x3(uint8_t const *ptr) { - uint8x16x3_t res = { { vld1q_u8(ptr + 0 * 16), vld1q_u8(ptr + 1 * 16), - vld1q_u8(ptr + 2 * 16) } }; - return res; -} -#endif -#endif - -static INLINE int16x4_t create_s16x4_neon(const int16_t c0, const int16_t c1, - const int16_t c2, const int16_t c3) { - return vcreate_s16((uint16_t)c0 | ((uint32_t)c1 << 16) | - ((int64_t)(uint16_t)c2 << 32) | ((int64_t)c3 << 48)); -} - -static INLINE int32x2_t create_s32x2_neon(const int32_t c0, const int32_t c1) { - return vcreate_s32((uint32_t)c0 | ((int64_t)(uint32_t)c1 << 32)); -} - -static INLINE int32x4_t create_s32x4_neon(const int32_t c0, const int32_t c1, - const int32_t c2, const int32_t c3) { - return vcombine_s32(create_s32x2_neon(c0, c1), create_s32x2_neon(c2, c3)); -} - -// Helper functions used to load tran_low_t into int16, narrowing if necessary. -static INLINE int16x8x2_t load_tran_low_to_s16x2q(const tran_low_t *buf) { -#if CONFIG_VP9_HIGHBITDEPTH - const int32x4x2_t v0 = vld2q_s32(buf); - const int32x4x2_t v1 = vld2q_s32(buf + 8); - const int16x4_t s0 = vmovn_s32(v0.val[0]); - const int16x4_t s1 = vmovn_s32(v0.val[1]); - const int16x4_t s2 = vmovn_s32(v1.val[0]); - const int16x4_t s3 = vmovn_s32(v1.val[1]); - int16x8x2_t res; - res.val[0] = vcombine_s16(s0, s2); - res.val[1] = vcombine_s16(s1, s3); - return res; -#else - return vld2q_s16(buf); -#endif -} - -static INLINE int16x8_t load_tran_low_to_s16q(const tran_low_t *buf) { -#if CONFIG_VP9_HIGHBITDEPTH - const int32x4_t v0 = vld1q_s32(buf); - const int32x4_t v1 = vld1q_s32(buf + 4); - const int16x4_t s0 = vmovn_s32(v0); - const int16x4_t s1 = vmovn_s32(v1); - return vcombine_s16(s0, s1); -#else - return vld1q_s16(buf); -#endif -} - -static INLINE int16x4_t load_tran_low_to_s16d(const tran_low_t *buf) { -#if CONFIG_VP9_HIGHBITDEPTH - const int32x4_t v0 = vld1q_s32(buf); - return vmovn_s32(v0); -#else - return vld1_s16(buf); -#endif -} - -static INLINE void store_s16q_to_tran_low(tran_low_t *buf, const int16x8_t a) { -#if CONFIG_VP9_HIGHBITDEPTH - const int32x4_t v0 = vmovl_s16(vget_low_s16(a)); - const int32x4_t v1 = vmovl_s16(vget_high_s16(a)); - vst1q_s32(buf, v0); - vst1q_s32(buf + 4, v1); -#else - vst1q_s16(buf, a); -#endif -} - -#if CONFIG_VP9_HIGHBITDEPTH -static INLINE void store_s32q_to_tran_low(tran_low_t *buf, const int32x4_t a) { - vst1q_s32(buf, a); -} - -static INLINE int32x4_t load_tran_low_to_s32q(const tran_low_t *buf) { - return vld1q_s32(buf); -} -#endif - -// Propagate type information to the compiler. Without this the compiler may -// assume the required alignment of uint32_t (4 bytes) and add alignment hints -// to the memory access. -// -// This is used for functions operating on uint8_t which wish to load or store 4 -// values at a time but which may not be on 4 byte boundaries. -static INLINE void uint32_to_mem(uint8_t *buf, uint32_t a) { - memcpy(buf, &a, 4); -} - -// Load 4 contiguous bytes when alignment is not guaranteed. -static INLINE uint8x8_t load_unaligned_u8_4x1(const uint8_t *buf) { - uint32_t a; - uint32x2_t a_u32; - memcpy(&a, buf, 4); - a_u32 = vdup_n_u32(0); - a_u32 = vset_lane_u32(a, a_u32, 0); - return vreinterpret_u8_u32(a_u32); -} - -// Load 4 contiguous bytes and replicate across a vector when alignment is not -// guaranteed. -static INLINE uint8x8_t load_replicate_u8_4x1(const uint8_t *buf) { - uint32_t a; - memcpy(&a, buf, 4); - return vreinterpret_u8_u32(vdup_n_u32(a)); -} - -// Store 4 contiguous bytes from the low half of an 8x8 vector. -static INLINE void store_u8_4x1(uint8_t *buf, uint8x8_t a) { - vst1_lane_u32((uint32_t *)buf, vreinterpret_u32_u8(a), 0); -} - -// Store 4 contiguous bytes from the high half of an 8x8 vector. -static INLINE void store_u8_4x1_high(uint8_t *buf, uint8x8_t a) { - vst1_lane_u32((uint32_t *)buf, vreinterpret_u32_u8(a), 1); -} - -// Load 2 sets of 4 bytes when alignment is not guaranteed. -static INLINE uint8x8_t load_unaligned_u8(const uint8_t *buf, - ptrdiff_t stride) { - uint32_t a; - uint32x2_t a_u32 = vdup_n_u32(0); - memcpy(&a, buf, 4); - buf += stride; - a_u32 = vset_lane_u32(a, a_u32, 0); - memcpy(&a, buf, 4); - a_u32 = vset_lane_u32(a, a_u32, 1); - return vreinterpret_u8_u32(a_u32); -} - -// Load 8 bytes when alignment is not guaranteed. -static INLINE uint16x4_t load_unaligned_u16(const uint16_t *buf) { - uint64_t a; - uint64x1_t a_u64 = vdup_n_u64(0); - memcpy(&a, buf, 8); - a_u64 = vset_lane_u64(a, a_u64, 0); - return vreinterpret_u16_u64(a_u64); -} - -// Load 2 sets of 8 bytes when alignment is not guaranteed. -static INLINE uint16x8_t load_unaligned_u16q(const uint16_t *buf, - ptrdiff_t stride) { - uint64_t a; - uint64x2_t a_u64 = vdupq_n_u64(0); - memcpy(&a, buf, 8); - buf += stride; - a_u64 = vsetq_lane_u64(a, a_u64, 0); - memcpy(&a, buf, 8); - a_u64 = vsetq_lane_u64(a, a_u64, 1); - return vreinterpretq_u16_u64(a_u64); -} - -// Store 2 sets of 4 bytes when alignment is not guaranteed. -static INLINE void store_unaligned_u8(uint8_t *buf, ptrdiff_t stride, - const uint8x8_t a) { - const uint32x2_t a_u32 = vreinterpret_u32_u8(a); - uint32_to_mem(buf, vget_lane_u32(a_u32, 0)); - buf += stride; - uint32_to_mem(buf, vget_lane_u32(a_u32, 1)); -} - -// Load 4 sets of 4 bytes when alignment is not guaranteed. -static INLINE uint8x16_t load_unaligned_u8q(const uint8_t *buf, - ptrdiff_t stride) { - uint32_t a; - uint32x4_t a_u32 = vdupq_n_u32(0); - memcpy(&a, buf, 4); - buf += stride; - a_u32 = vsetq_lane_u32(a, a_u32, 0); - memcpy(&a, buf, 4); - buf += stride; - a_u32 = vsetq_lane_u32(a, a_u32, 1); - memcpy(&a, buf, 4); - buf += stride; - a_u32 = vsetq_lane_u32(a, a_u32, 2); - memcpy(&a, buf, 4); - buf += stride; - a_u32 = vsetq_lane_u32(a, a_u32, 3); - return vreinterpretq_u8_u32(a_u32); -} - -// Store 4 sets of 4 bytes when alignment is not guaranteed. -static INLINE void store_unaligned_u8q(uint8_t *buf, ptrdiff_t stride, - const uint8x16_t a) { - const uint32x4_t a_u32 = vreinterpretq_u32_u8(a); - uint32_to_mem(buf, vgetq_lane_u32(a_u32, 0)); - buf += stride; - uint32_to_mem(buf, vgetq_lane_u32(a_u32, 1)); - buf += stride; - uint32_to_mem(buf, vgetq_lane_u32(a_u32, 2)); - buf += stride; - uint32_to_mem(buf, vgetq_lane_u32(a_u32, 3)); -} - -// Load 2 sets of 4 bytes when alignment is guaranteed. -static INLINE uint8x8_t load_u8(const uint8_t *buf, ptrdiff_t stride) { - uint32x2_t a = vdup_n_u32(0); - - assert(!((intptr_t)buf % sizeof(uint32_t))); - assert(!(stride % sizeof(uint32_t))); - - a = vld1_lane_u32((const uint32_t *)buf, a, 0); - buf += stride; - a = vld1_lane_u32((const uint32_t *)buf, a, 1); - return vreinterpret_u8_u32(a); -} - -// Store 2 sets of 4 bytes when alignment is guaranteed. -static INLINE void store_u8(uint8_t *buf, ptrdiff_t stride, const uint8x8_t a) { - uint32x2_t a_u32 = vreinterpret_u32_u8(a); - - assert(!((intptr_t)buf % sizeof(uint32_t))); - assert(!(stride % sizeof(uint32_t))); - - vst1_lane_u32((uint32_t *)buf, a_u32, 0); - buf += stride; - vst1_lane_u32((uint32_t *)buf, a_u32, 1); -} - -static INLINE void store_u8_8x3(uint8_t *s, const ptrdiff_t p, - const uint8x8_t s0, const uint8x8_t s1, - const uint8x8_t s2) { - vst1_u8(s, s0); - s += p; - vst1_u8(s, s1); - s += p; - vst1_u8(s, s2); -} - -static INLINE void load_u8_8x3(const uint8_t *s, const ptrdiff_t p, - uint8x8_t *const s0, uint8x8_t *const s1, - uint8x8_t *const s2) { - *s0 = vld1_u8(s); - s += p; - *s1 = vld1_u8(s); - s += p; - *s2 = vld1_u8(s); -} - -static INLINE void load_u8_8x4(const uint8_t *s, const ptrdiff_t p, - uint8x8_t *const s0, uint8x8_t *const s1, - uint8x8_t *const s2, uint8x8_t *const s3) { - *s0 = vld1_u8(s); - s += p; - *s1 = vld1_u8(s); - s += p; - *s2 = vld1_u8(s); - s += p; - *s3 = vld1_u8(s); -} - -static INLINE void store_u8_8x4(uint8_t *s, const ptrdiff_t p, - const uint8x8_t s0, const uint8x8_t s1, - const uint8x8_t s2, const uint8x8_t s3) { - vst1_u8(s, s0); - s += p; - vst1_u8(s, s1); - s += p; - vst1_u8(s, s2); - s += p; - vst1_u8(s, s3); -} - -static INLINE void load_u8_16x3(const uint8_t *s, const ptrdiff_t p, - uint8x16_t *const s0, uint8x16_t *const s1, - uint8x16_t *const s2) { - *s0 = vld1q_u8(s); - s += p; - *s1 = vld1q_u8(s); - s += p; - *s2 = vld1q_u8(s); -} - -static INLINE void load_u8_16x4(const uint8_t *s, const ptrdiff_t p, - uint8x16_t *const s0, uint8x16_t *const s1, - uint8x16_t *const s2, uint8x16_t *const s3) { - *s0 = vld1q_u8(s); - s += p; - *s1 = vld1q_u8(s); - s += p; - *s2 = vld1q_u8(s); - s += p; - *s3 = vld1q_u8(s); -} - -static INLINE void store_u8_16x4(uint8_t *s, const ptrdiff_t p, - const uint8x16_t s0, const uint8x16_t s1, - const uint8x16_t s2, const uint8x16_t s3) { - vst1q_u8(s, s0); - s += p; - vst1q_u8(s, s1); - s += p; - vst1q_u8(s, s2); - s += p; - vst1q_u8(s, s3); -} - -static INLINE void load_u8_8x7(const uint8_t *s, const ptrdiff_t p, - uint8x8_t *const s0, uint8x8_t *const s1, - uint8x8_t *const s2, uint8x8_t *const s3, - uint8x8_t *const s4, uint8x8_t *const s5, - uint8x8_t *const s6) { - *s0 = vld1_u8(s); - s += p; - *s1 = vld1_u8(s); - s += p; - *s2 = vld1_u8(s); - s += p; - *s3 = vld1_u8(s); - s += p; - *s4 = vld1_u8(s); - s += p; - *s5 = vld1_u8(s); - s += p; - *s6 = vld1_u8(s); -} - -static INLINE void load_u8_8x8(const uint8_t *s, const ptrdiff_t p, - uint8x8_t *const s0, uint8x8_t *const s1, - uint8x8_t *const s2, uint8x8_t *const s3, - uint8x8_t *const s4, uint8x8_t *const s5, - uint8x8_t *const s6, uint8x8_t *const s7) { - *s0 = vld1_u8(s); - s += p; - *s1 = vld1_u8(s); - s += p; - *s2 = vld1_u8(s); - s += p; - *s3 = vld1_u8(s); - s += p; - *s4 = vld1_u8(s); - s += p; - *s5 = vld1_u8(s); - s += p; - *s6 = vld1_u8(s); - s += p; - *s7 = vld1_u8(s); -} - -static INLINE void store_u8_8x8(uint8_t *s, const ptrdiff_t p, - const uint8x8_t s0, const uint8x8_t s1, - const uint8x8_t s2, const uint8x8_t s3, - const uint8x8_t s4, const uint8x8_t s5, - const uint8x8_t s6, const uint8x8_t s7) { - vst1_u8(s, s0); - s += p; - vst1_u8(s, s1); - s += p; - vst1_u8(s, s2); - s += p; - vst1_u8(s, s3); - s += p; - vst1_u8(s, s4); - s += p; - vst1_u8(s, s5); - s += p; - vst1_u8(s, s6); - s += p; - vst1_u8(s, s7); -} - -static INLINE void load_u8_16x8(const uint8_t *s, const ptrdiff_t p, - uint8x16_t *const s0, uint8x16_t *const s1, - uint8x16_t *const s2, uint8x16_t *const s3, - uint8x16_t *const s4, uint8x16_t *const s5, - uint8x16_t *const s6, uint8x16_t *const s7) { - *s0 = vld1q_u8(s); - s += p; - *s1 = vld1q_u8(s); - s += p; - *s2 = vld1q_u8(s); - s += p; - *s3 = vld1q_u8(s); - s += p; - *s4 = vld1q_u8(s); - s += p; - *s5 = vld1q_u8(s); - s += p; - *s6 = vld1q_u8(s); - s += p; - *s7 = vld1q_u8(s); -} - -static INLINE void store_u8_16x8(uint8_t *s, const ptrdiff_t p, - const uint8x16_t s0, const uint8x16_t s1, - const uint8x16_t s2, const uint8x16_t s3, - const uint8x16_t s4, const uint8x16_t s5, - const uint8x16_t s6, const uint8x16_t s7) { - vst1q_u8(s, s0); - s += p; - vst1q_u8(s, s1); - s += p; - vst1q_u8(s, s2); - s += p; - vst1q_u8(s, s3); - s += p; - vst1q_u8(s, s4); - s += p; - vst1q_u8(s, s5); - s += p; - vst1q_u8(s, s6); - s += p; - vst1q_u8(s, s7); -} - -static INLINE void store_u16_4x3(uint16_t *s, const ptrdiff_t p, - const uint16x4_t s0, const uint16x4_t s1, - const uint16x4_t s2) { - vst1_u16(s, s0); - s += p; - vst1_u16(s, s1); - s += p; - vst1_u16(s, s2); -} - -static INLINE void load_s16_4x3(const int16_t *s, const ptrdiff_t p, - int16x4_t *s0, int16x4_t *s1, int16x4_t *s2) { - *s0 = vld1_s16(s); - s += p; - *s1 = vld1_s16(s); - s += p; - *s2 = vld1_s16(s); -} - -static INLINE void load_s16_4x4(const int16_t *s, const ptrdiff_t p, - int16x4_t *s0, int16x4_t *s1, int16x4_t *s2, - int16x4_t *s3) { - *s0 = vld1_s16(s); - s += p; - *s1 = vld1_s16(s); - s += p; - *s2 = vld1_s16(s); - s += p; - *s3 = vld1_s16(s); -} - -static INLINE void store_u16_4x4(uint16_t *s, const ptrdiff_t p, - const uint16x4_t s0, const uint16x4_t s1, - const uint16x4_t s2, const uint16x4_t s3) { - vst1_u16(s, s0); - s += p; - vst1_u16(s, s1); - s += p; - vst1_u16(s, s2); - s += p; - vst1_u16(s, s3); -} - -static INLINE void load_s16_4x7(const int16_t *s, const ptrdiff_t p, - int16x4_t *s0, int16x4_t *s1, int16x4_t *s2, - int16x4_t *s3, int16x4_t *s4, int16x4_t *s5, - int16x4_t *s6) { - *s0 = vld1_s16(s); - s += p; - *s1 = vld1_s16(s); - s += p; - *s2 = vld1_s16(s); - s += p; - *s3 = vld1_s16(s); - s += p; - *s4 = vld1_s16(s); - s += p; - *s5 = vld1_s16(s); - s += p; - *s6 = vld1_s16(s); -} - -static INLINE void load_s16_8x3(const int16_t *s, const ptrdiff_t p, - int16x8_t *s0, int16x8_t *s1, int16x8_t *s2) { - *s0 = vld1q_s16(s); - s += p; - *s1 = vld1q_s16(s); - s += p; - *s2 = vld1q_s16(s); -} - -static INLINE void load_s16_8x4(const int16_t *s, const ptrdiff_t p, - int16x8_t *s0, int16x8_t *s1, int16x8_t *s2, - int16x8_t *s3) { - *s0 = vld1q_s16(s); - s += p; - *s1 = vld1q_s16(s); - s += p; - *s2 = vld1q_s16(s); - s += p; - *s3 = vld1q_s16(s); -} - -static INLINE void load_u16_8x4(const uint16_t *s, const ptrdiff_t p, - uint16x8_t *s0, uint16x8_t *s1, uint16x8_t *s2, - uint16x8_t *s3) { - *s0 = vld1q_u16(s); - s += p; - *s1 = vld1q_u16(s); - s += p; - *s2 = vld1q_u16(s); - s += p; - *s3 = vld1q_u16(s); -} - -static INLINE void store_u16_8x4(uint16_t *s, const ptrdiff_t p, - const uint16x8_t s0, const uint16x8_t s1, - const uint16x8_t s2, const uint16x8_t s3) { - vst1q_u16(s, s0); - s += p; - vst1q_u16(s, s1); - s += p; - vst1q_u16(s, s2); - s += p; - vst1q_u16(s, s3); -} - -static INLINE void store_u16_8x3(uint16_t *s, const ptrdiff_t p, - const uint16x8_t s0, const uint16x8_t s1, - const uint16x8_t s2) { - vst1q_u16(s, s0); - s += p; - vst1q_u16(s, s1); - s += p; - vst1q_u16(s, s2); -} - -static INLINE void load_s16_8x7(const int16_t *s, const ptrdiff_t p, - int16x8_t *s0, int16x8_t *s1, int16x8_t *s2, - int16x8_t *s3, int16x8_t *s4, int16x8_t *s5, - int16x8_t *s6) { - *s0 = vld1q_s16(s); - s += p; - *s1 = vld1q_s16(s); - s += p; - *s2 = vld1q_s16(s); - s += p; - *s3 = vld1q_s16(s); - s += p; - *s4 = vld1q_s16(s); - s += p; - *s5 = vld1q_s16(s); - s += p; - *s6 = vld1q_s16(s); -} - -static INLINE void load_u16_8x8(const uint16_t *s, const ptrdiff_t p, - uint16x8_t *s0, uint16x8_t *s1, uint16x8_t *s2, - uint16x8_t *s3, uint16x8_t *s4, uint16x8_t *s5, - uint16x8_t *s6, uint16x8_t *s7) { - *s0 = vld1q_u16(s); - s += p; - *s1 = vld1q_u16(s); - s += p; - *s2 = vld1q_u16(s); - s += p; - *s3 = vld1q_u16(s); - s += p; - *s4 = vld1q_u16(s); - s += p; - *s5 = vld1q_u16(s); - s += p; - *s6 = vld1q_u16(s); - s += p; - *s7 = vld1q_u16(s); -} - -static INLINE void load_s16_4x8(const int16_t *s, const ptrdiff_t p, - int16x4_t *s0, int16x4_t *s1, int16x4_t *s2, - int16x4_t *s3, int16x4_t *s4, int16x4_t *s5, - int16x4_t *s6, int16x4_t *s7) { - *s0 = vld1_s16(s); - s += p; - *s1 = vld1_s16(s); - s += p; - *s2 = vld1_s16(s); - s += p; - *s3 = vld1_s16(s); - s += p; - *s4 = vld1_s16(s); - s += p; - *s5 = vld1_s16(s); - s += p; - *s6 = vld1_s16(s); - s += p; - *s7 = vld1_s16(s); -} - -static INLINE void load_s16_8x8(const int16_t *s, const ptrdiff_t p, - int16x8_t *s0, int16x8_t *s1, int16x8_t *s2, - int16x8_t *s3, int16x8_t *s4, int16x8_t *s5, - int16x8_t *s6, int16x8_t *s7) { - *s0 = vld1q_s16(s); - s += p; - *s1 = vld1q_s16(s); - s += p; - *s2 = vld1q_s16(s); - s += p; - *s3 = vld1q_s16(s); - s += p; - *s4 = vld1q_s16(s); - s += p; - *s5 = vld1q_s16(s); - s += p; - *s6 = vld1q_s16(s); - s += p; - *s7 = vld1q_s16(s); -} - -#endif // VPX_VPX_DSP_ARM_MEM_NEON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/quantize_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/quantize_neon.c deleted file mode 100644 index e2351fa2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/quantize_neon.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vp9/common/vp9_scan.h" -#include "vp9/encoder/vp9_block.h" - -static INLINE void calculate_dqcoeff_and_store(const int16x8_t qcoeff, - const int16x8_t dequant, - tran_low_t *dqcoeff_ptr) { -#if CONFIG_VP9_HIGHBITDEPTH - const int32x4_t dqcoeff_0 = - vmull_s16(vget_low_s16(qcoeff), vget_low_s16(dequant)); - const int32x4_t dqcoeff_1 = - vmull_s16(vget_high_s16(qcoeff), vget_high_s16(dequant)); - - vst1q_s32(dqcoeff_ptr, dqcoeff_0); - vst1q_s32(dqcoeff_ptr + 4, dqcoeff_1); -#else - vst1q_s16(dqcoeff_ptr, vmulq_s16(qcoeff, dequant)); -#endif // CONFIG_VP9_HIGHBITDEPTH -} - -static INLINE int16x8_t -quantize_b_neon(const tran_low_t *coeff_ptr, tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, const int16x8_t zbin, - const int16x8_t round, const int16x8_t quant, - const int16x8_t quant_shift, const int16x8_t dequant) { - // Load coeffs as 8 x 16-bit ints, take sign and abs values - const int16x8_t coeff = load_tran_low_to_s16q(coeff_ptr); - const int16x8_t coeff_sign = vshrq_n_s16(coeff, 15); - const int16x8_t coeff_abs = vabsq_s16(coeff); - - // Calculate mask of elements outside the bin - const int16x8_t zbin_mask = vreinterpretq_s16_u16(vcgeq_s16(coeff_abs, zbin)); - - // Get the rounded values - const int16x8_t rounded = vqaddq_s16(coeff_abs, round); - - // (round * quant * 2) >> 16 >> 1 == (round * quant) >> 16 - int16x8_t qcoeff = vshrq_n_s16(vqdmulhq_s16(rounded, quant), 1); - - qcoeff = vaddq_s16(qcoeff, rounded); - - // (qcoeff * quant_shift * 2) >> 16 >> 1 == (qcoeff * quant_shift) >> 16 - qcoeff = vshrq_n_s16(vqdmulhq_s16(qcoeff, quant_shift), 1); - - // Restore the sign bit. - qcoeff = veorq_s16(qcoeff, coeff_sign); - qcoeff = vsubq_s16(qcoeff, coeff_sign); - - // Only keep the relevant coeffs - qcoeff = vandq_s16(qcoeff, zbin_mask); - store_s16q_to_tran_low(qcoeff_ptr, qcoeff); - - calculate_dqcoeff_and_store(qcoeff, dequant, dqcoeff_ptr); - - return qcoeff; -} - -void vpx_quantize_b_neon(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - const int16x8_t neg_one = vdupq_n_s16(-1); - uint16x8_t eob_max; - int16_t const *iscan = scan_order->iscan; - - // Only the first element of each vector is DC. - int16x8_t zbin = vld1q_s16(mb_plane->zbin); - int16x8_t round = vld1q_s16(mb_plane->round); - int16x8_t quant = vld1q_s16(mb_plane->quant); - int16x8_t quant_shift = vld1q_s16(mb_plane->quant_shift); - int16x8_t dequant = vld1q_s16(dequant_ptr); - - // Process first 8 values which include a dc component. - { - const uint16x8_t v_iscan = vreinterpretq_u16_s16(vld1q_s16(iscan)); - - const int16x8_t qcoeff = - quantize_b_neon(coeff_ptr, qcoeff_ptr, dqcoeff_ptr, zbin, round, quant, - quant_shift, dequant); - - // Set non-zero elements to -1 and use that to extract values for eob. - eob_max = vandq_u16(vtstq_s16(qcoeff, neg_one), v_iscan); - - __builtin_prefetch(coeff_ptr + 64); - coeff_ptr += 8; - iscan += 8; - qcoeff_ptr += 8; - dqcoeff_ptr += 8; - } - - n_coeffs -= 8; - - { - zbin = vdupq_lane_s16(vget_low_s16(zbin), 1); - round = vdupq_lane_s16(vget_low_s16(round), 1); - quant = vdupq_lane_s16(vget_low_s16(quant), 1); - quant_shift = vdupq_lane_s16(vget_low_s16(quant_shift), 1); - dequant = vdupq_lane_s16(vget_low_s16(dequant), 1); - - do { - const uint16x8_t v_iscan = vreinterpretq_u16_s16(vld1q_s16(iscan)); - - const int16x8_t qcoeff = - quantize_b_neon(coeff_ptr, qcoeff_ptr, dqcoeff_ptr, zbin, round, - quant, quant_shift, dequant); - - // Set non-zero elements to -1 and use that to extract values for eob. - eob_max = - vmaxq_u16(eob_max, vandq_u16(vtstq_s16(qcoeff, neg_one), v_iscan)); - - __builtin_prefetch(coeff_ptr + 64); - coeff_ptr += 8; - iscan += 8; - qcoeff_ptr += 8; - dqcoeff_ptr += 8; - n_coeffs -= 8; - } while (n_coeffs > 0); - } - -#if VPX_ARCH_AARCH64 - *eob_ptr = vmaxvq_u16(eob_max); -#else - { - const uint16x4_t eob_max_0 = - vmax_u16(vget_low_u16(eob_max), vget_high_u16(eob_max)); - const uint16x4_t eob_max_1 = vpmax_u16(eob_max_0, eob_max_0); - const uint16x4_t eob_max_2 = vpmax_u16(eob_max_1, eob_max_1); - vst1_lane_u16(eob_ptr, eob_max_2, 0); - } -#endif // VPX_ARCH_AARCH64 -} - -static INLINE int32x4_t extract_sign_bit(int32x4_t a) { - return vreinterpretq_s32_u32(vshrq_n_u32(vreinterpretq_u32_s32(a), 31)); -} - -static INLINE void calculate_dqcoeff_and_store_32x32(const int16x8_t qcoeff, - const int16x8_t dequant, - tran_low_t *dqcoeff_ptr) { - int32x4_t dqcoeff_0 = vmull_s16(vget_low_s16(qcoeff), vget_low_s16(dequant)); - int32x4_t dqcoeff_1 = - vmull_s16(vget_high_s16(qcoeff), vget_high_s16(dequant)); - - // Add 1 if negative to round towards zero because the C uses division. - dqcoeff_0 = vaddq_s32(dqcoeff_0, extract_sign_bit(dqcoeff_0)); - dqcoeff_1 = vaddq_s32(dqcoeff_1, extract_sign_bit(dqcoeff_1)); - -#if CONFIG_VP9_HIGHBITDEPTH - dqcoeff_0 = vshrq_n_s32(dqcoeff_0, 1); - dqcoeff_1 = vshrq_n_s32(dqcoeff_1, 1); - vst1q_s32(dqcoeff_ptr, dqcoeff_0); - vst1q_s32(dqcoeff_ptr + 4, dqcoeff_1); -#else - vst1q_s16(dqcoeff_ptr, - vcombine_s16(vshrn_n_s32(dqcoeff_0, 1), vshrn_n_s32(dqcoeff_1, 1))); -#endif // CONFIG_VP9_HIGHBITDEPTH -} - -static INLINE int16x8_t -quantize_b_32x32_neon(const tran_low_t *coeff_ptr, tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, const int16x8_t zbin, - const int16x8_t round, const int16x8_t quant, - const int16x8_t quant_shift, const int16x8_t dequant) { - // Load coeffs as 8 x 16-bit ints, take sign and abs values - const int16x8_t coeff = load_tran_low_to_s16q(coeff_ptr); - const int16x8_t coeff_sign = vshrq_n_s16(coeff, 15); - const int16x8_t coeff_abs = vabsq_s16(coeff); - - // Calculate mask of elements outside the bin - const int16x8_t zbin_mask = vreinterpretq_s16_u16(vcgeq_s16(coeff_abs, zbin)); - - // Get the rounded values - const int16x8_t rounded = vqaddq_s16(coeff_abs, round); - - // (round * quant * 2) >> 16 >> 1 == (round * quant) >> 16 - int16x8_t qcoeff = vshrq_n_s16(vqdmulhq_s16(rounded, quant), 1); - - qcoeff = vaddq_s16(qcoeff, rounded); - - // (qcoeff * quant_shift * 2) >> 16 == (qcoeff * quant_shift) >> 15 - qcoeff = vqdmulhq_s16(qcoeff, quant_shift); - - // Restore the sign bit. - qcoeff = veorq_s16(qcoeff, coeff_sign); - qcoeff = vsubq_s16(qcoeff, coeff_sign); - - // Only keep the relevant coeffs - qcoeff = vandq_s16(qcoeff, zbin_mask); - store_s16q_to_tran_low(qcoeff_ptr, qcoeff); - - calculate_dqcoeff_and_store_32x32(qcoeff, dequant, dqcoeff_ptr); - - return qcoeff; -} - -// Main difference is that zbin values are halved before comparison and dqcoeff -// values are divided by 2. zbin is rounded but dqcoeff is not. -void vpx_quantize_b_32x32_neon(const tran_low_t *coeff_ptr, - const struct macroblock_plane *mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - const int16x8_t neg_one = vdupq_n_s16(-1); - uint16x8_t eob_max; - int i; - const int16_t *iscan = scan_order->iscan; - - // Only the first element of each vector is DC. - int16x8_t zbin = vrshrq_n_s16(vld1q_s16(mb_plane->zbin), 1); - int16x8_t round = vrshrq_n_s16(vld1q_s16(mb_plane->round), 1); - int16x8_t quant = vld1q_s16(mb_plane->quant); - int16x8_t quant_shift = vld1q_s16(mb_plane->quant_shift); - int16x8_t dequant = vld1q_s16(dequant_ptr); - - // Process first 8 values which include a dc component. - { - const uint16x8_t v_iscan = vreinterpretq_u16_s16(vld1q_s16(iscan)); - - const int16x8_t qcoeff = - quantize_b_32x32_neon(coeff_ptr, qcoeff_ptr, dqcoeff_ptr, zbin, round, - quant, quant_shift, dequant); - - // Set non-zero elements to -1 and use that to extract values for eob. - eob_max = vandq_u16(vtstq_s16(qcoeff, neg_one), v_iscan); - - __builtin_prefetch(coeff_ptr + 64); - coeff_ptr += 8; - iscan += 8; - qcoeff_ptr += 8; - dqcoeff_ptr += 8; - } - - { - zbin = vdupq_lane_s16(vget_low_s16(zbin), 1); - round = vdupq_lane_s16(vget_low_s16(round), 1); - quant = vdupq_lane_s16(vget_low_s16(quant), 1); - quant_shift = vdupq_lane_s16(vget_low_s16(quant_shift), 1); - dequant = vdupq_lane_s16(vget_low_s16(dequant), 1); - - for (i = 1; i < 32 * 32 / 8; ++i) { - const uint16x8_t v_iscan = vreinterpretq_u16_s16(vld1q_s16(iscan)); - - const int16x8_t qcoeff = - quantize_b_32x32_neon(coeff_ptr, qcoeff_ptr, dqcoeff_ptr, zbin, round, - quant, quant_shift, dequant); - - // Set non-zero elements to -1 and use that to extract values for eob. - eob_max = - vmaxq_u16(eob_max, vandq_u16(vtstq_s16(qcoeff, neg_one), v_iscan)); - - __builtin_prefetch(coeff_ptr + 64); - coeff_ptr += 8; - iscan += 8; - qcoeff_ptr += 8; - dqcoeff_ptr += 8; - } - } - -#if VPX_ARCH_AARCH64 - *eob_ptr = vmaxvq_u16(eob_max); -#else - { - const uint16x4_t eob_max_0 = - vmax_u16(vget_low_u16(eob_max), vget_high_u16(eob_max)); - const uint16x4_t eob_max_1 = vpmax_u16(eob_max_0, eob_max_0); - const uint16x4_t eob_max_2 = vpmax_u16(eob_max_1, eob_max_1); - vst1_lane_u16(eob_ptr, eob_max_2, 0); - } -#endif // VPX_ARCH_AARCH64 -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sad4d_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sad4d_neon.c deleted file mode 100644 index 713eec7a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sad4d_neon.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" - -static INLINE void sad16_neon(uint8x16_t src, uint8x16_t ref, - uint16x8_t *const sad_sum) { - uint8x16_t abs_diff = vabdq_u8(src, ref); - *sad_sum = vpadalq_u8(*sad_sum, abs_diff); -} - -static INLINE void sad64xhx4d_neon(const uint8_t *src, int src_stride, - const uint8_t *const ref[4], int ref_stride, - uint32_t res[4], int h) { - uint16x8_t sum_lo[4] = { vdupq_n_u16(0), vdupq_n_u16(0), vdupq_n_u16(0), - vdupq_n_u16(0) }; - uint16x8_t sum_hi[4] = { vdupq_n_u16(0), vdupq_n_u16(0), vdupq_n_u16(0), - vdupq_n_u16(0) }; - - int i = 0; - do { - uint8x16_t s0, s1, s2, s3; - - s0 = vld1q_u8(src + i * src_stride); - sad16_neon(s0, vld1q_u8(ref[0] + i * ref_stride), &sum_lo[0]); - sad16_neon(s0, vld1q_u8(ref[1] + i * ref_stride), &sum_lo[1]); - sad16_neon(s0, vld1q_u8(ref[2] + i * ref_stride), &sum_lo[2]); - sad16_neon(s0, vld1q_u8(ref[3] + i * ref_stride), &sum_lo[3]); - - s1 = vld1q_u8(src + i * src_stride + 16); - sad16_neon(s1, vld1q_u8(ref[0] + i * ref_stride + 16), &sum_hi[0]); - sad16_neon(s1, vld1q_u8(ref[1] + i * ref_stride + 16), &sum_hi[1]); - sad16_neon(s1, vld1q_u8(ref[2] + i * ref_stride + 16), &sum_hi[2]); - sad16_neon(s1, vld1q_u8(ref[3] + i * ref_stride + 16), &sum_hi[3]); - - s2 = vld1q_u8(src + i * src_stride + 32); - sad16_neon(s2, vld1q_u8(ref[0] + i * ref_stride + 32), &sum_lo[0]); - sad16_neon(s2, vld1q_u8(ref[1] + i * ref_stride + 32), &sum_lo[1]); - sad16_neon(s2, vld1q_u8(ref[2] + i * ref_stride + 32), &sum_lo[2]); - sad16_neon(s2, vld1q_u8(ref[3] + i * ref_stride + 32), &sum_lo[3]); - - s3 = vld1q_u8(src + i * src_stride + 48); - sad16_neon(s3, vld1q_u8(ref[0] + i * ref_stride + 48), &sum_hi[0]); - sad16_neon(s3, vld1q_u8(ref[1] + i * ref_stride + 48), &sum_hi[1]); - sad16_neon(s3, vld1q_u8(ref[2] + i * ref_stride + 48), &sum_hi[2]); - sad16_neon(s3, vld1q_u8(ref[3] + i * ref_stride + 48), &sum_hi[3]); - - i++; - } while (i < h); - - vst1q_u32(res, horizontal_long_add_4d_uint16x8(sum_lo, sum_hi)); -} - -static INLINE void sad32xhx4d_neon(const uint8_t *src, int src_stride, - const uint8_t *const ref[4], int ref_stride, - uint32_t res[4], int h) { - uint16x8_t sum_lo[4] = { vdupq_n_u16(0), vdupq_n_u16(0), vdupq_n_u16(0), - vdupq_n_u16(0) }; - uint16x8_t sum_hi[4] = { vdupq_n_u16(0), vdupq_n_u16(0), vdupq_n_u16(0), - vdupq_n_u16(0) }; - - int i = 0; - do { - uint8x16_t s0, s1; - - s0 = vld1q_u8(src + i * src_stride); - sad16_neon(s0, vld1q_u8(ref[0] + i * ref_stride), &sum_lo[0]); - sad16_neon(s0, vld1q_u8(ref[1] + i * ref_stride), &sum_lo[1]); - sad16_neon(s0, vld1q_u8(ref[2] + i * ref_stride), &sum_lo[2]); - sad16_neon(s0, vld1q_u8(ref[3] + i * ref_stride), &sum_lo[3]); - - s1 = vld1q_u8(src + i * src_stride + 16); - sad16_neon(s1, vld1q_u8(ref[0] + i * ref_stride + 16), &sum_hi[0]); - sad16_neon(s1, vld1q_u8(ref[1] + i * ref_stride + 16), &sum_hi[1]); - sad16_neon(s1, vld1q_u8(ref[2] + i * ref_stride + 16), &sum_hi[2]); - sad16_neon(s1, vld1q_u8(ref[3] + i * ref_stride + 16), &sum_hi[3]); - - i++; - } while (i < h); - - vst1q_u32(res, horizontal_long_add_4d_uint16x8(sum_lo, sum_hi)); -} - -static INLINE void sad16xhx4d_neon(const uint8_t *src, int src_stride, - const uint8_t *const ref[4], int ref_stride, - uint32_t res[4], int h) { - uint16x8_t sum[4] = { vdupq_n_u16(0), vdupq_n_u16(0), vdupq_n_u16(0), - vdupq_n_u16(0) }; - - int i = 0; - do { - const uint8x16_t s = vld1q_u8(src + i * src_stride); - sad16_neon(s, vld1q_u8(ref[0] + i * ref_stride), &sum[0]); - sad16_neon(s, vld1q_u8(ref[1] + i * ref_stride), &sum[1]); - sad16_neon(s, vld1q_u8(ref[2] + i * ref_stride), &sum[2]); - sad16_neon(s, vld1q_u8(ref[3] + i * ref_stride), &sum[3]); - - i++; - } while (i < h); - - vst1q_u32(res, horizontal_add_4d_uint16x8(sum)); -} - -static INLINE void sad8_neon(uint8x8_t src, uint8x8_t ref, - uint16x8_t *const sad_sum) { - uint8x8_t abs_diff = vabd_u8(src, ref); - *sad_sum = vaddw_u8(*sad_sum, abs_diff); -} - -static INLINE void sad8xhx4d_neon(const uint8_t *src, int src_stride, - const uint8_t *const ref[4], int ref_stride, - uint32_t res[4], int h) { - uint16x8_t sum[4] = { vdupq_n_u16(0), vdupq_n_u16(0), vdupq_n_u16(0), - vdupq_n_u16(0) }; - - int i = 0; - do { - const uint8x8_t s = vld1_u8(src + i * src_stride); - sad8_neon(s, vld1_u8(ref[0] + i * ref_stride), &sum[0]); - sad8_neon(s, vld1_u8(ref[1] + i * ref_stride), &sum[1]); - sad8_neon(s, vld1_u8(ref[2] + i * ref_stride), &sum[2]); - sad8_neon(s, vld1_u8(ref[3] + i * ref_stride), &sum[3]); - - i++; - } while (i < h); - - vst1q_u32(res, horizontal_add_4d_uint16x8(sum)); -} - -static INLINE void sad4xhx4d_neon(const uint8_t *src, int src_stride, - const uint8_t *const ref[4], int ref_stride, - uint32_t res[4], int h) { - uint16x8_t sum[4] = { vdupq_n_u16(0), vdupq_n_u16(0), vdupq_n_u16(0), - vdupq_n_u16(0) }; - - int i = 0; - do { - uint8x8_t s = load_unaligned_u8(src + i * src_stride, src_stride); - uint8x8_t r0 = load_unaligned_u8(ref[0] + i * ref_stride, ref_stride); - uint8x8_t r1 = load_unaligned_u8(ref[1] + i * ref_stride, ref_stride); - uint8x8_t r2 = load_unaligned_u8(ref[2] + i * ref_stride, ref_stride); - uint8x8_t r3 = load_unaligned_u8(ref[3] + i * ref_stride, ref_stride); - - sad8_neon(s, r0, &sum[0]); - sad8_neon(s, r1, &sum[1]); - sad8_neon(s, r2, &sum[2]); - sad8_neon(s, r3, &sum[3]); - - i += 2; - } while (i < h); - - vst1q_u32(res, horizontal_add_4d_uint16x8(sum)); -} - -#define SAD_WXH_4D_NEON(w, h) \ - void vpx_sad##w##x##h##x4d_neon(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *const ref_array[4], \ - int ref_stride, uint32_t sad_array[4]) { \ - sad##w##xhx4d_neon(src_ptr, src_stride, ref_array, ref_stride, sad_array, \ - (h)); \ - } - -SAD_WXH_4D_NEON(4, 4) -SAD_WXH_4D_NEON(4, 8) - -SAD_WXH_4D_NEON(8, 4) -SAD_WXH_4D_NEON(8, 8) -SAD_WXH_4D_NEON(8, 16) - -SAD_WXH_4D_NEON(16, 8) -SAD_WXH_4D_NEON(16, 16) -SAD_WXH_4D_NEON(16, 32) - -SAD_WXH_4D_NEON(32, 16) -SAD_WXH_4D_NEON(32, 32) -SAD_WXH_4D_NEON(32, 64) - -SAD_WXH_4D_NEON(64, 32) -SAD_WXH_4D_NEON(64, 64) - -#undef SAD_WXH_4D_NEON - -#define SAD_SKIP_WXH_4D_NEON(w, h) \ - void vpx_sad_skip_##w##x##h##x4d_neon( \ - const uint8_t *src_ptr, int src_stride, \ - const uint8_t *const ref_array[4], int ref_stride, \ - uint32_t sad_array[4]) { \ - sad##w##xhx4d_neon(src_ptr, 2 * src_stride, ref_array, 2 * ref_stride, \ - sad_array, ((h) >> 1)); \ - sad_array[0] <<= 1; \ - sad_array[1] <<= 1; \ - sad_array[2] <<= 1; \ - sad_array[3] <<= 1; \ - } - -SAD_SKIP_WXH_4D_NEON(4, 4) -SAD_SKIP_WXH_4D_NEON(4, 8) - -SAD_SKIP_WXH_4D_NEON(8, 4) -SAD_SKIP_WXH_4D_NEON(8, 8) -SAD_SKIP_WXH_4D_NEON(8, 16) - -SAD_SKIP_WXH_4D_NEON(16, 8) -SAD_SKIP_WXH_4D_NEON(16, 16) -SAD_SKIP_WXH_4D_NEON(16, 32) - -SAD_SKIP_WXH_4D_NEON(32, 16) -SAD_SKIP_WXH_4D_NEON(32, 32) -SAD_SKIP_WXH_4D_NEON(32, 64) - -SAD_SKIP_WXH_4D_NEON(64, 32) -SAD_SKIP_WXH_4D_NEON(64, 64) - -#undef SAD_SKIP_WXH_4D_NEON diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sad4d_neon_dotprod.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sad4d_neon_dotprod.c deleted file mode 100644 index 933fc48b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sad4d_neon_dotprod.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2021 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" - -static INLINE void sad16_neon(uint8x16_t src, uint8x16_t ref, - uint32x4_t *const sad_sum) { - uint8x16_t abs_diff = vabdq_u8(src, ref); - *sad_sum = vdotq_u32(*sad_sum, abs_diff, vdupq_n_u8(1)); -} - -static INLINE void sad64xhx4d_neon_dotprod(const uint8_t *src, int src_stride, - const uint8_t *const ref[4], - int ref_stride, uint32_t res[4], - int h) { - uint32x4_t sum_lo[4] = { vdupq_n_u32(0), vdupq_n_u32(0), vdupq_n_u32(0), - vdupq_n_u32(0) }; - uint32x4_t sum_hi[4] = { vdupq_n_u32(0), vdupq_n_u32(0), vdupq_n_u32(0), - vdupq_n_u32(0) }; - uint32x4_t sum[4]; - - int i = 0; - do { - uint8x16_t s0, s1, s2, s3; - - s0 = vld1q_u8(src + i * src_stride); - sad16_neon(s0, vld1q_u8(ref[0] + i * ref_stride), &sum_lo[0]); - sad16_neon(s0, vld1q_u8(ref[1] + i * ref_stride), &sum_lo[1]); - sad16_neon(s0, vld1q_u8(ref[2] + i * ref_stride), &sum_lo[2]); - sad16_neon(s0, vld1q_u8(ref[3] + i * ref_stride), &sum_lo[3]); - - s1 = vld1q_u8(src + i * src_stride + 16); - sad16_neon(s1, vld1q_u8(ref[0] + i * ref_stride + 16), &sum_hi[0]); - sad16_neon(s1, vld1q_u8(ref[1] + i * ref_stride + 16), &sum_hi[1]); - sad16_neon(s1, vld1q_u8(ref[2] + i * ref_stride + 16), &sum_hi[2]); - sad16_neon(s1, vld1q_u8(ref[3] + i * ref_stride + 16), &sum_hi[3]); - - s2 = vld1q_u8(src + i * src_stride + 32); - sad16_neon(s2, vld1q_u8(ref[0] + i * ref_stride + 32), &sum_lo[0]); - sad16_neon(s2, vld1q_u8(ref[1] + i * ref_stride + 32), &sum_lo[1]); - sad16_neon(s2, vld1q_u8(ref[2] + i * ref_stride + 32), &sum_lo[2]); - sad16_neon(s2, vld1q_u8(ref[3] + i * ref_stride + 32), &sum_lo[3]); - - s3 = vld1q_u8(src + i * src_stride + 48); - sad16_neon(s3, vld1q_u8(ref[0] + i * ref_stride + 48), &sum_hi[0]); - sad16_neon(s3, vld1q_u8(ref[1] + i * ref_stride + 48), &sum_hi[1]); - sad16_neon(s3, vld1q_u8(ref[2] + i * ref_stride + 48), &sum_hi[2]); - sad16_neon(s3, vld1q_u8(ref[3] + i * ref_stride + 48), &sum_hi[3]); - - } while (++i < h); - - sum[0] = vaddq_u32(sum_lo[0], sum_hi[0]); - sum[1] = vaddq_u32(sum_lo[1], sum_hi[1]); - sum[2] = vaddq_u32(sum_lo[2], sum_hi[2]); - sum[3] = vaddq_u32(sum_lo[3], sum_hi[3]); - - vst1q_u32(res, horizontal_add_4d_uint32x4(sum)); -} - -static INLINE void sad32xhx4d_neon_dotprod(const uint8_t *src, int src_stride, - const uint8_t *const ref[4], - int ref_stride, uint32_t res[4], - int h) { - uint32x4_t sum_lo[4] = { vdupq_n_u32(0), vdupq_n_u32(0), vdupq_n_u32(0), - vdupq_n_u32(0) }; - uint32x4_t sum_hi[4] = { vdupq_n_u32(0), vdupq_n_u32(0), vdupq_n_u32(0), - vdupq_n_u32(0) }; - uint32x4_t sum[4]; - - int i = 0; - do { - uint8x16_t s0, s1; - - s0 = vld1q_u8(src + i * src_stride); - sad16_neon(s0, vld1q_u8(ref[0] + i * ref_stride), &sum_lo[0]); - sad16_neon(s0, vld1q_u8(ref[1] + i * ref_stride), &sum_lo[1]); - sad16_neon(s0, vld1q_u8(ref[2] + i * ref_stride), &sum_lo[2]); - sad16_neon(s0, vld1q_u8(ref[3] + i * ref_stride), &sum_lo[3]); - - s1 = vld1q_u8(src + i * src_stride + 16); - sad16_neon(s1, vld1q_u8(ref[0] + i * ref_stride + 16), &sum_hi[0]); - sad16_neon(s1, vld1q_u8(ref[1] + i * ref_stride + 16), &sum_hi[1]); - sad16_neon(s1, vld1q_u8(ref[2] + i * ref_stride + 16), &sum_hi[2]); - sad16_neon(s1, vld1q_u8(ref[3] + i * ref_stride + 16), &sum_hi[3]); - - } while (++i < h); - - sum[0] = vaddq_u32(sum_lo[0], sum_hi[0]); - sum[1] = vaddq_u32(sum_lo[1], sum_hi[1]); - sum[2] = vaddq_u32(sum_lo[2], sum_hi[2]); - sum[3] = vaddq_u32(sum_lo[3], sum_hi[3]); - - vst1q_u32(res, horizontal_add_4d_uint32x4(sum)); -} - -static INLINE void sad16xhx4d_neon_dotprod(const uint8_t *src, int src_stride, - const uint8_t *const ref[4], - int ref_stride, uint32_t res[4], - int h) { - uint32x4_t sum[4] = { vdupq_n_u32(0), vdupq_n_u32(0), vdupq_n_u32(0), - vdupq_n_u32(0) }; - - int i = 0; - do { - const uint8x16_t s = vld1q_u8(src + i * src_stride); - sad16_neon(s, vld1q_u8(ref[0] + i * ref_stride), &sum[0]); - sad16_neon(s, vld1q_u8(ref[1] + i * ref_stride), &sum[1]); - sad16_neon(s, vld1q_u8(ref[2] + i * ref_stride), &sum[2]); - sad16_neon(s, vld1q_u8(ref[3] + i * ref_stride), &sum[3]); - - } while (++i < h); - - vst1q_u32(res, horizontal_add_4d_uint32x4(sum)); -} - -#define SAD_WXH_4D_NEON_DOTPROD(w, h) \ - void vpx_sad##w##x##h##x4d_neon_dotprod( \ - const uint8_t *src_ptr, int src_stride, \ - const uint8_t *const ref_array[4], int ref_stride, \ - uint32_t sad_array[4]) { \ - sad##w##xhx4d_neon_dotprod(src_ptr, src_stride, ref_array, ref_stride, \ - sad_array, (h)); \ - } - -SAD_WXH_4D_NEON_DOTPROD(16, 8) -SAD_WXH_4D_NEON_DOTPROD(16, 16) -SAD_WXH_4D_NEON_DOTPROD(16, 32) - -SAD_WXH_4D_NEON_DOTPROD(32, 16) -SAD_WXH_4D_NEON_DOTPROD(32, 32) -SAD_WXH_4D_NEON_DOTPROD(32, 64) - -SAD_WXH_4D_NEON_DOTPROD(64, 32) -SAD_WXH_4D_NEON_DOTPROD(64, 64) - -#undef SAD_WXH_4D_NEON_DOTPROD - -#define SAD_SKIP_WXH_4D_NEON_DOTPROD(w, h) \ - void vpx_sad_skip_##w##x##h##x4d_neon_dotprod( \ - const uint8_t *src_ptr, int src_stride, \ - const uint8_t *const ref_array[4], int ref_stride, \ - uint32_t sad_array[4]) { \ - sad##w##xhx4d_neon_dotprod(src_ptr, 2 * src_stride, ref_array, \ - 2 * ref_stride, sad_array, ((h) >> 1)); \ - sad_array[0] <<= 1; \ - sad_array[1] <<= 1; \ - sad_array[2] <<= 1; \ - sad_array[3] <<= 1; \ - } - -SAD_SKIP_WXH_4D_NEON_DOTPROD(16, 8) -SAD_SKIP_WXH_4D_NEON_DOTPROD(16, 16) -SAD_SKIP_WXH_4D_NEON_DOTPROD(16, 32) - -SAD_SKIP_WXH_4D_NEON_DOTPROD(32, 16) -SAD_SKIP_WXH_4D_NEON_DOTPROD(32, 32) -SAD_SKIP_WXH_4D_NEON_DOTPROD(32, 64) - -SAD_SKIP_WXH_4D_NEON_DOTPROD(64, 32) -SAD_SKIP_WXH_4D_NEON_DOTPROD(64, 64) - -#undef SAD_SKIP_WXH_4D_NEON_DOTPROD diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sad_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sad_neon.c deleted file mode 100644 index 4dd87ddc..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sad_neon.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" - -static INLINE unsigned int sad64xh_neon(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - int h) { - uint16x8_t sum[4] = { vdupq_n_u16(0), vdupq_n_u16(0), vdupq_n_u16(0), - vdupq_n_u16(0) }; - uint32x4_t sum_u32; - - int i = h; - do { - uint8x16_t s0, s1, s2, s3, r0, r1, r2, r3; - uint8x16_t diff0, diff1, diff2, diff3; - - s0 = vld1q_u8(src_ptr); - r0 = vld1q_u8(ref_ptr); - diff0 = vabdq_u8(s0, r0); - sum[0] = vpadalq_u8(sum[0], diff0); - - s1 = vld1q_u8(src_ptr + 16); - r1 = vld1q_u8(ref_ptr + 16); - diff1 = vabdq_u8(s1, r1); - sum[1] = vpadalq_u8(sum[1], diff1); - - s2 = vld1q_u8(src_ptr + 32); - r2 = vld1q_u8(ref_ptr + 32); - diff2 = vabdq_u8(s2, r2); - sum[2] = vpadalq_u8(sum[2], diff2); - - s3 = vld1q_u8(src_ptr + 48); - r3 = vld1q_u8(ref_ptr + 48); - diff3 = vabdq_u8(s3, r3); - sum[3] = vpadalq_u8(sum[3], diff3); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--i != 0); - - sum_u32 = vpaddlq_u16(sum[0]); - sum_u32 = vpadalq_u16(sum_u32, sum[1]); - sum_u32 = vpadalq_u16(sum_u32, sum[2]); - sum_u32 = vpadalq_u16(sum_u32, sum[3]); - - return horizontal_add_uint32x4(sum_u32); -} - -static INLINE unsigned int sad32xh_neon(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - int h) { - uint32x4_t sum = vdupq_n_u32(0); - - int i = h; - do { - uint8x16_t s0 = vld1q_u8(src_ptr); - uint8x16_t r0 = vld1q_u8(ref_ptr); - uint8x16_t diff0 = vabdq_u8(s0, r0); - uint16x8_t sum0 = vpaddlq_u8(diff0); - - uint8x16_t s1 = vld1q_u8(src_ptr + 16); - uint8x16_t r1 = vld1q_u8(ref_ptr + 16); - uint8x16_t diff1 = vabdq_u8(s1, r1); - uint16x8_t sum1 = vpaddlq_u8(diff1); - - sum = vpadalq_u16(sum, sum0); - sum = vpadalq_u16(sum, sum1); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--i != 0); - - return horizontal_add_uint32x4(sum); -} - -static INLINE unsigned int sad16xh_neon(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - int h) { - uint16x8_t sum = vdupq_n_u16(0); - - int i = h; - do { - uint8x16_t s = vld1q_u8(src_ptr); - uint8x16_t r = vld1q_u8(ref_ptr); - - uint8x16_t diff = vabdq_u8(s, r); - sum = vpadalq_u8(sum, diff); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--i != 0); - - return horizontal_add_uint16x8(sum); -} - -static INLINE unsigned int sad8xh_neon(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - int h) { - uint16x8_t sum = vdupq_n_u16(0); - - int i = h; - do { - uint8x8_t s = vld1_u8(src_ptr); - uint8x8_t r = vld1_u8(ref_ptr); - - sum = vabal_u8(sum, s, r); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--i != 0); - - return horizontal_add_uint16x8(sum); -} - -static INLINE unsigned int sad4xh_neon(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - int h) { - uint16x8_t sum = vdupq_n_u16(0); - - int i = h / 2; - do { - uint8x8_t s = load_unaligned_u8(src_ptr, src_stride); - uint8x8_t r = load_unaligned_u8(ref_ptr, ref_stride); - - sum = vabal_u8(sum, s, r); - - src_ptr += 2 * src_stride; - ref_ptr += 2 * ref_stride; - } while (--i != 0); - - return horizontal_add_uint16x8(sum); -} - -#define SAD_WXH_NEON(w, h) \ - unsigned int vpx_sad##w##x##h##_neon(const uint8_t *src, int src_stride, \ - const uint8_t *ref, int ref_stride) { \ - return sad##w##xh_neon(src, src_stride, ref, ref_stride, (h)); \ - } - -SAD_WXH_NEON(4, 4) -SAD_WXH_NEON(4, 8) - -SAD_WXH_NEON(8, 4) -SAD_WXH_NEON(8, 8) -SAD_WXH_NEON(8, 16) - -SAD_WXH_NEON(16, 8) -SAD_WXH_NEON(16, 16) -SAD_WXH_NEON(16, 32) - -SAD_WXH_NEON(32, 16) -SAD_WXH_NEON(32, 32) -SAD_WXH_NEON(32, 64) - -SAD_WXH_NEON(64, 32) -SAD_WXH_NEON(64, 64) - -#undef SAD_WXH_NEON - -#define SAD_SKIP_WXH_NEON(w, h) \ - unsigned int vpx_sad_skip_##w##x##h##_neon( \ - const uint8_t *src, int src_stride, const uint8_t *ref, \ - int ref_stride) { \ - return 2 * \ - sad##w##xh_neon(src, 2 * src_stride, ref, 2 * ref_stride, (h) / 2); \ - } - -SAD_SKIP_WXH_NEON(4, 4) -SAD_SKIP_WXH_NEON(4, 8) - -SAD_SKIP_WXH_NEON(8, 4) -SAD_SKIP_WXH_NEON(8, 8) -SAD_SKIP_WXH_NEON(8, 16) - -SAD_SKIP_WXH_NEON(16, 8) -SAD_SKIP_WXH_NEON(16, 16) -SAD_SKIP_WXH_NEON(16, 32) - -SAD_SKIP_WXH_NEON(32, 16) -SAD_SKIP_WXH_NEON(32, 32) -SAD_SKIP_WXH_NEON(32, 64) - -SAD_SKIP_WXH_NEON(64, 32) -SAD_SKIP_WXH_NEON(64, 64) - -#undef SAD_SKIP_WXH_NEON - -static INLINE unsigned int sad64xh_avg_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h, - const uint8_t *second_pred) { - uint16x8_t sum[4] = { vdupq_n_u16(0), vdupq_n_u16(0), vdupq_n_u16(0), - vdupq_n_u16(0) }; - uint32x4_t sum_u32; - - int i = h; - do { - uint8x16_t s0, s1, s2, s3, r0, r1, r2, r3, p0, p1, p2, p3; - uint8x16_t avg0, avg1, avg2, avg3, diff0, diff1, diff2, diff3; - - s0 = vld1q_u8(src_ptr); - r0 = vld1q_u8(ref_ptr); - p0 = vld1q_u8(second_pred); - avg0 = vrhaddq_u8(r0, p0); - diff0 = vabdq_u8(s0, avg0); - sum[0] = vpadalq_u8(sum[0], diff0); - - s1 = vld1q_u8(src_ptr + 16); - r1 = vld1q_u8(ref_ptr + 16); - p1 = vld1q_u8(second_pred + 16); - avg1 = vrhaddq_u8(r1, p1); - diff1 = vabdq_u8(s1, avg1); - sum[1] = vpadalq_u8(sum[1], diff1); - - s2 = vld1q_u8(src_ptr + 32); - r2 = vld1q_u8(ref_ptr + 32); - p2 = vld1q_u8(second_pred + 32); - avg2 = vrhaddq_u8(r2, p2); - diff2 = vabdq_u8(s2, avg2); - sum[2] = vpadalq_u8(sum[2], diff2); - - s3 = vld1q_u8(src_ptr + 48); - r3 = vld1q_u8(ref_ptr + 48); - p3 = vld1q_u8(second_pred + 48); - avg3 = vrhaddq_u8(r3, p3); - diff3 = vabdq_u8(s3, avg3); - sum[3] = vpadalq_u8(sum[3], diff3); - - src_ptr += src_stride; - ref_ptr += ref_stride; - second_pred += 64; - } while (--i != 0); - - sum_u32 = vpaddlq_u16(sum[0]); - sum_u32 = vpadalq_u16(sum_u32, sum[1]); - sum_u32 = vpadalq_u16(sum_u32, sum[2]); - sum_u32 = vpadalq_u16(sum_u32, sum[3]); - - return horizontal_add_uint32x4(sum_u32); -} - -static INLINE unsigned int sad32xh_avg_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h, - const uint8_t *second_pred) { - uint32x4_t sum = vdupq_n_u32(0); - - int i = h; - do { - uint8x16_t s0 = vld1q_u8(src_ptr); - uint8x16_t r0 = vld1q_u8(ref_ptr); - uint8x16_t p0 = vld1q_u8(second_pred); - uint8x16_t avg0 = vrhaddq_u8(r0, p0); - uint8x16_t diff0 = vabdq_u8(s0, avg0); - uint16x8_t sum0 = vpaddlq_u8(diff0); - - uint8x16_t s1 = vld1q_u8(src_ptr + 16); - uint8x16_t r1 = vld1q_u8(ref_ptr + 16); - uint8x16_t p1 = vld1q_u8(second_pred + 16); - uint8x16_t avg1 = vrhaddq_u8(r1, p1); - uint8x16_t diff1 = vabdq_u8(s1, avg1); - uint16x8_t sum1 = vpaddlq_u8(diff1); - - sum = vpadalq_u16(sum, sum0); - sum = vpadalq_u16(sum, sum1); - - src_ptr += src_stride; - ref_ptr += ref_stride; - second_pred += 32; - } while (--i != 0); - - return horizontal_add_uint32x4(sum); -} - -static INLINE unsigned int sad16xh_avg_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h, - const uint8_t *second_pred) { - uint16x8_t sum = vdupq_n_u16(0); - - int i = h; - do { - uint8x16_t s = vld1q_u8(src_ptr); - uint8x16_t r = vld1q_u8(ref_ptr); - uint8x16_t p = vld1q_u8(second_pred); - - uint8x16_t avg = vrhaddq_u8(r, p); - uint8x16_t diff = vabdq_u8(s, avg); - sum = vpadalq_u8(sum, diff); - - src_ptr += src_stride; - ref_ptr += ref_stride; - second_pred += 16; - } while (--i != 0); - - return horizontal_add_uint16x8(sum); -} - -static INLINE unsigned int sad8xh_avg_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h, - const uint8_t *second_pred) { - uint16x8_t sum = vdupq_n_u16(0); - - int i = h; - do { - uint8x8_t s = vld1_u8(src_ptr); - uint8x8_t r = vld1_u8(ref_ptr); - uint8x8_t p = vld1_u8(second_pred); - - uint8x8_t avg = vrhadd_u8(r, p); - sum = vabal_u8(sum, s, avg); - - src_ptr += src_stride; - ref_ptr += ref_stride; - second_pred += 8; - } while (--i != 0); - - return horizontal_add_uint16x8(sum); -} - -static INLINE unsigned int sad4xh_avg_neon(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h, - const uint8_t *second_pred) { - uint16x8_t sum = vdupq_n_u16(0); - - int i = h / 2; - do { - uint8x8_t s = load_unaligned_u8(src_ptr, src_stride); - uint8x8_t r = load_unaligned_u8(ref_ptr, ref_stride); - uint8x8_t p = vld1_u8(second_pred); - - uint8x8_t avg = vrhadd_u8(r, p); - sum = vabal_u8(sum, s, avg); - - src_ptr += 2 * src_stride; - ref_ptr += 2 * ref_stride; - second_pred += 8; - } while (--i != 0); - - return horizontal_add_uint16x8(sum); -} - -#define SAD_WXH_AVG_NEON(w, h) \ - uint32_t vpx_sad##w##x##h##_avg_neon(const uint8_t *src, int src_stride, \ - const uint8_t *ref, int ref_stride, \ - const uint8_t *second_pred) { \ - return sad##w##xh_avg_neon(src, src_stride, ref, ref_stride, (h), \ - second_pred); \ - } - -SAD_WXH_AVG_NEON(4, 4) -SAD_WXH_AVG_NEON(4, 8) - -SAD_WXH_AVG_NEON(8, 4) -SAD_WXH_AVG_NEON(8, 8) -SAD_WXH_AVG_NEON(8, 16) - -SAD_WXH_AVG_NEON(16, 8) -SAD_WXH_AVG_NEON(16, 16) -SAD_WXH_AVG_NEON(16, 32) - -SAD_WXH_AVG_NEON(32, 16) -SAD_WXH_AVG_NEON(32, 32) -SAD_WXH_AVG_NEON(32, 64) - -SAD_WXH_AVG_NEON(64, 32) -SAD_WXH_AVG_NEON(64, 64) - -#undef SAD_WXH_AVG_NEON diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sad_neon_dotprod.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sad_neon_dotprod.c deleted file mode 100644 index fbc0b8d7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sad_neon_dotprod.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2021 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" - -static INLINE unsigned int sadwxh_neon_dotprod(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int w, int h) { - // Only two accumulators are required for optimal instruction throughput of - // the ABD, UDOT sequence on CPUs with either 2 or 4 Neon pipes. - uint32x4_t sum[2] = { vdupq_n_u32(0), vdupq_n_u32(0) }; - - int i = h; - do { - int j = 0; - do { - uint8x16_t s0, s1, r0, r1, diff0, diff1; - - s0 = vld1q_u8(src_ptr + j); - r0 = vld1q_u8(ref_ptr + j); - diff0 = vabdq_u8(s0, r0); - sum[0] = vdotq_u32(sum[0], diff0, vdupq_n_u8(1)); - - s1 = vld1q_u8(src_ptr + j + 16); - r1 = vld1q_u8(ref_ptr + j + 16); - diff1 = vabdq_u8(s1, r1); - sum[1] = vdotq_u32(sum[1], diff1, vdupq_n_u8(1)); - - j += 32; - } while (j < w); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--i != 0); - - return horizontal_add_uint32x4(vaddq_u32(sum[0], sum[1])); -} - -static INLINE unsigned int sad64xh_neon_dotprod(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h) { - return sadwxh_neon_dotprod(src_ptr, src_stride, ref_ptr, ref_stride, 64, h); -} - -static INLINE unsigned int sad32xh_neon_dotprod(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h) { - return sadwxh_neon_dotprod(src_ptr, src_stride, ref_ptr, ref_stride, 32, h); -} - -static INLINE unsigned int sad16xh_neon_dotprod(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h) { - uint32x4_t sum[2] = { vdupq_n_u32(0), vdupq_n_u32(0) }; - - int i = h / 2; - do { - uint8x16_t s0, s1, r0, r1, diff0, diff1; - - s0 = vld1q_u8(src_ptr); - r0 = vld1q_u8(ref_ptr); - diff0 = vabdq_u8(s0, r0); - sum[0] = vdotq_u32(sum[0], diff0, vdupq_n_u8(1)); - - src_ptr += src_stride; - ref_ptr += ref_stride; - - s1 = vld1q_u8(src_ptr); - r1 = vld1q_u8(ref_ptr); - diff1 = vabdq_u8(s1, r1); - sum[1] = vdotq_u32(sum[1], diff1, vdupq_n_u8(1)); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--i != 0); - - return horizontal_add_uint32x4(vaddq_u32(sum[0], sum[1])); -} - -#define SAD_WXH_NEON_DOTPROD(w, h) \ - unsigned int vpx_sad##w##x##h##_neon_dotprod( \ - const uint8_t *src, int src_stride, const uint8_t *ref, \ - int ref_stride) { \ - return sad##w##xh_neon_dotprod(src, src_stride, ref, ref_stride, (h)); \ - } - -SAD_WXH_NEON_DOTPROD(16, 8) -SAD_WXH_NEON_DOTPROD(16, 16) -SAD_WXH_NEON_DOTPROD(16, 32) - -SAD_WXH_NEON_DOTPROD(32, 16) -SAD_WXH_NEON_DOTPROD(32, 32) -SAD_WXH_NEON_DOTPROD(32, 64) - -SAD_WXH_NEON_DOTPROD(64, 32) -SAD_WXH_NEON_DOTPROD(64, 64) - -#undef SAD_WXH_NEON_DOTPROD - -#define SAD_SKIP_WXH_NEON_DOTPROD(w, h) \ - unsigned int vpx_sad_skip_##w##x##h##_neon_dotprod( \ - const uint8_t *src, int src_stride, const uint8_t *ref, \ - int ref_stride) { \ - return 2 * sad##w##xh_neon_dotprod(src, 2 * src_stride, ref, \ - 2 * ref_stride, (h) / 2); \ - } - -SAD_SKIP_WXH_NEON_DOTPROD(16, 8) -SAD_SKIP_WXH_NEON_DOTPROD(16, 16) -SAD_SKIP_WXH_NEON_DOTPROD(16, 32) - -SAD_SKIP_WXH_NEON_DOTPROD(32, 16) -SAD_SKIP_WXH_NEON_DOTPROD(32, 32) -SAD_SKIP_WXH_NEON_DOTPROD(32, 64) - -SAD_SKIP_WXH_NEON_DOTPROD(64, 32) -SAD_SKIP_WXH_NEON_DOTPROD(64, 64) - -#undef SAD_SKIP_WXH_NEON_DOTPROD - -static INLINE unsigned int sadwxh_avg_neon_dotprod(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int w, int h, - const uint8_t *second_pred) { - // Only two accumulators are required for optimal instruction throughput of - // the ABD, UDOT sequence on CPUs with either 2 or 4 Neon pipes. - uint32x4_t sum[2] = { vdupq_n_u32(0), vdupq_n_u32(0) }; - - int i = h; - do { - int j = 0; - do { - uint8x16_t s0, s1, r0, r1, p0, p1, avg0, avg1, diff0, diff1; - - s0 = vld1q_u8(src_ptr + j); - r0 = vld1q_u8(ref_ptr + j); - p0 = vld1q_u8(second_pred); - avg0 = vrhaddq_u8(r0, p0); - diff0 = vabdq_u8(s0, avg0); - sum[0] = vdotq_u32(sum[0], diff0, vdupq_n_u8(1)); - - s1 = vld1q_u8(src_ptr + j + 16); - r1 = vld1q_u8(ref_ptr + j + 16); - p1 = vld1q_u8(second_pred + 16); - avg1 = vrhaddq_u8(r1, p1); - diff1 = vabdq_u8(s1, avg1); - sum[1] = vdotq_u32(sum[1], diff1, vdupq_n_u8(1)); - - j += 32; - second_pred += 32; - } while (j < w); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--i != 0); - - return horizontal_add_uint32x4(vaddq_u32(sum[0], sum[1])); -} - -static INLINE unsigned int sad64xh_avg_neon_dotprod( - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, - int ref_stride, int h, const uint8_t *second_pred) { - return sadwxh_avg_neon_dotprod(src_ptr, src_stride, ref_ptr, ref_stride, 64, - h, second_pred); -} - -static INLINE unsigned int sad32xh_avg_neon_dotprod( - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, - int ref_stride, int h, const uint8_t *second_pred) { - return sadwxh_avg_neon_dotprod(src_ptr, src_stride, ref_ptr, ref_stride, 32, - h, second_pred); -} - -static INLINE unsigned int sad16xh_avg_neon_dotprod( - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, - int ref_stride, int h, const uint8_t *second_pred) { - uint32x4_t sum[2] = { vdupq_n_u32(0), vdupq_n_u32(0) }; - - int i = h / 2; - do { - uint8x16_t s0, s1, r0, r1, p0, p1, avg0, avg1, diff0, diff1; - - s0 = vld1q_u8(src_ptr); - r0 = vld1q_u8(ref_ptr); - p0 = vld1q_u8(second_pred); - avg0 = vrhaddq_u8(r0, p0); - diff0 = vabdq_u8(s0, avg0); - sum[0] = vdotq_u32(sum[0], diff0, vdupq_n_u8(1)); - - src_ptr += src_stride; - ref_ptr += ref_stride; - second_pred += 16; - - s1 = vld1q_u8(src_ptr); - r1 = vld1q_u8(ref_ptr); - p1 = vld1q_u8(second_pred); - avg1 = vrhaddq_u8(r1, p1); - diff1 = vabdq_u8(s1, avg1); - sum[1] = vdotq_u32(sum[1], diff1, vdupq_n_u8(1)); - - src_ptr += src_stride; - ref_ptr += ref_stride; - second_pred += 16; - } while (--i != 0); - - return horizontal_add_uint32x4(vaddq_u32(sum[0], sum[1])); -} - -#define SAD_WXH_AVG_NEON_DOTPROD(w, h) \ - uint32_t vpx_sad##w##x##h##_avg_neon_dotprod( \ - const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride, \ - const uint8_t *second_pred) { \ - return sad##w##xh_avg_neon_dotprod(src, src_stride, ref, ref_stride, (h), \ - second_pred); \ - } - -SAD_WXH_AVG_NEON_DOTPROD(16, 8) -SAD_WXH_AVG_NEON_DOTPROD(16, 16) -SAD_WXH_AVG_NEON_DOTPROD(16, 32) - -SAD_WXH_AVG_NEON_DOTPROD(32, 16) -SAD_WXH_AVG_NEON_DOTPROD(32, 32) -SAD_WXH_AVG_NEON_DOTPROD(32, 64) - -SAD_WXH_AVG_NEON_DOTPROD(64, 32) -SAD_WXH_AVG_NEON_DOTPROD(64, 64) - -#undef SAD_WXH_AVG_NEON_DOTPROD diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/save_reg_neon.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/save_reg_neon.asm deleted file mode 100644 index 9811cd5a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/save_reg_neon.asm +++ /dev/null @@ -1,34 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - - EXPORT |vpx_push_neon| - EXPORT |vpx_pop_neon| - - ARM - REQUIRE8 - PRESERVE8 - - AREA ||.text||, CODE, READONLY, ALIGN=2 - -|vpx_push_neon| PROC - vstm r0!, {d8-d15} - bx lr - - ENDP - -|vpx_pop_neon| PROC - vldm r0!, {d8-d15} - bx lr - - ENDP - - END - diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sse_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sse_neon.c deleted file mode 100644 index 2dd57e59..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sse_neon.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" - -static INLINE void sse_16x1_neon(const uint8_t *src, const uint8_t *ref, - uint32x4_t *sse) { - uint8x16_t s = vld1q_u8(src); - uint8x16_t r = vld1q_u8(ref); - - uint8x16_t abs_diff = vabdq_u8(s, r); - uint8x8_t abs_diff_lo = vget_low_u8(abs_diff); - uint8x8_t abs_diff_hi = vget_high_u8(abs_diff); - - *sse = vpadalq_u16(*sse, vmull_u8(abs_diff_lo, abs_diff_lo)); - *sse = vpadalq_u16(*sse, vmull_u8(abs_diff_hi, abs_diff_hi)); -} - -static INLINE void sse_8x1_neon(const uint8_t *src, const uint8_t *ref, - uint32x4_t *sse) { - uint8x8_t s = vld1_u8(src); - uint8x8_t r = vld1_u8(ref); - - uint8x8_t abs_diff = vabd_u8(s, r); - - *sse = vpadalq_u16(*sse, vmull_u8(abs_diff, abs_diff)); -} - -static INLINE void sse_4x2_neon(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - uint32x4_t *sse) { - uint8x8_t s = load_unaligned_u8(src, src_stride); - uint8x8_t r = load_unaligned_u8(ref, ref_stride); - - uint8x8_t abs_diff = vabd_u8(s, r); - - *sse = vpadalq_u16(*sse, vmull_u8(abs_diff, abs_diff)); -} - -static INLINE uint32_t sse_wxh_neon(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - int width, int height) { - uint32x4_t sse = vdupq_n_u32(0); - - if ((width & 0x07) && ((width & 0x07) < 5)) { - int i = height; - do { - int j = 0; - do { - sse_8x1_neon(src + j, ref + j, &sse); - sse_8x1_neon(src + j + src_stride, ref + j + ref_stride, &sse); - j += 8; - } while (j + 4 < width); - - sse_4x2_neon(src + j, src_stride, ref + j, ref_stride, &sse); - src += 2 * src_stride; - ref += 2 * ref_stride; - i -= 2; - } while (i != 0); - } else { - int i = height; - do { - int j = 0; - do { - sse_8x1_neon(src + j, ref + j, &sse); - j += 8; - } while (j < width); - - src += src_stride; - ref += ref_stride; - } while (--i != 0); - } - return horizontal_add_uint32x4(sse); -} - -static INLINE uint32_t sse_64xh_neon(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - int height) { - uint32x4_t sse[2] = { vdupq_n_u32(0), vdupq_n_u32(0) }; - - int i = height; - do { - sse_16x1_neon(src, ref, &sse[0]); - sse_16x1_neon(src + 16, ref + 16, &sse[1]); - sse_16x1_neon(src + 32, ref + 32, &sse[0]); - sse_16x1_neon(src + 48, ref + 48, &sse[1]); - - src += src_stride; - ref += ref_stride; - } while (--i != 0); - - return horizontal_add_uint32x4(vaddq_u32(sse[0], sse[1])); -} - -static INLINE uint32_t sse_32xh_neon(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - int height) { - uint32x4_t sse[2] = { vdupq_n_u32(0), vdupq_n_u32(0) }; - - int i = height; - do { - sse_16x1_neon(src, ref, &sse[0]); - sse_16x1_neon(src + 16, ref + 16, &sse[1]); - - src += src_stride; - ref += ref_stride; - } while (--i != 0); - - return horizontal_add_uint32x4(vaddq_u32(sse[0], sse[1])); -} - -static INLINE uint32_t sse_16xh_neon(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - int height) { - uint32x4_t sse[2] = { vdupq_n_u32(0), vdupq_n_u32(0) }; - - int i = height; - do { - sse_16x1_neon(src, ref, &sse[0]); - src += src_stride; - ref += ref_stride; - sse_16x1_neon(src, ref, &sse[1]); - src += src_stride; - ref += ref_stride; - i -= 2; - } while (i != 0); - - return horizontal_add_uint32x4(vaddq_u32(sse[0], sse[1])); -} - -static INLINE uint32_t sse_8xh_neon(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - int height) { - uint32x4_t sse = vdupq_n_u32(0); - - int i = height; - do { - sse_8x1_neon(src, ref, &sse); - - src += src_stride; - ref += ref_stride; - } while (--i != 0); - - return horizontal_add_uint32x4(sse); -} - -static INLINE uint32_t sse_4xh_neon(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - int height) { - uint32x4_t sse = vdupq_n_u32(0); - - int i = height; - do { - sse_4x2_neon(src, src_stride, ref, ref_stride, &sse); - - src += 2 * src_stride; - ref += 2 * ref_stride; - i -= 2; - } while (i != 0); - - return horizontal_add_uint32x4(sse); -} - -int64_t vpx_sse_neon(const uint8_t *src, int src_stride, const uint8_t *ref, - int ref_stride, int width, int height) { - switch (width) { - case 4: return sse_4xh_neon(src, src_stride, ref, ref_stride, height); - case 8: return sse_8xh_neon(src, src_stride, ref, ref_stride, height); - case 16: return sse_16xh_neon(src, src_stride, ref, ref_stride, height); - case 32: return sse_32xh_neon(src, src_stride, ref, ref_stride, height); - case 64: return sse_64xh_neon(src, src_stride, ref, ref_stride, height); - default: - return sse_wxh_neon(src, src_stride, ref, ref_stride, width, height); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sse_neon_dotprod.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sse_neon_dotprod.c deleted file mode 100644 index 87777739..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sse_neon_dotprod.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" - -static INLINE void sse_16x1_neon_dotprod(const uint8_t *src, const uint8_t *ref, - uint32x4_t *sse) { - uint8x16_t s = vld1q_u8(src); - uint8x16_t r = vld1q_u8(ref); - - uint8x16_t abs_diff = vabdq_u8(s, r); - - *sse = vdotq_u32(*sse, abs_diff, abs_diff); -} - -static INLINE void sse_8x1_neon_dotprod(const uint8_t *src, const uint8_t *ref, - uint32x2_t *sse) { - uint8x8_t s = vld1_u8(src); - uint8x8_t r = vld1_u8(ref); - - uint8x8_t abs_diff = vabd_u8(s, r); - - *sse = vdot_u32(*sse, abs_diff, abs_diff); -} - -static INLINE void sse_4x2_neon_dotprod(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - uint32x2_t *sse) { - uint8x8_t s = load_unaligned_u8(src, src_stride); - uint8x8_t r = load_unaligned_u8(ref, ref_stride); - - uint8x8_t abs_diff = vabd_u8(s, r); - - *sse = vdot_u32(*sse, abs_diff, abs_diff); -} - -static INLINE uint32_t sse_wxh_neon_dotprod(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - int width, int height) { - uint32x2_t sse[2] = { vdup_n_u32(0), vdup_n_u32(0) }; - - if ((width & 0x07) && ((width & 0x07) < 5)) { - int i = height; - do { - int j = 0; - do { - sse_8x1_neon_dotprod(src + j, ref + j, &sse[0]); - sse_8x1_neon_dotprod(src + j + src_stride, ref + j + ref_stride, - &sse[1]); - j += 8; - } while (j + 4 < width); - - sse_4x2_neon_dotprod(src + j, src_stride, ref + j, ref_stride, &sse[0]); - src += 2 * src_stride; - ref += 2 * ref_stride; - i -= 2; - } while (i != 0); - } else { - int i = height; - do { - int j = 0; - do { - sse_8x1_neon_dotprod(src + j, ref + j, &sse[0]); - sse_8x1_neon_dotprod(src + j + src_stride, ref + j + ref_stride, - &sse[1]); - j += 8; - } while (j < width); - - src += 2 * src_stride; - ref += 2 * ref_stride; - i -= 2; - } while (i != 0); - } - return horizontal_add_uint32x4(vcombine_u32(sse[0], sse[1])); -} - -static INLINE uint32_t sse_64xh_neon_dotprod(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - int height) { - uint32x4_t sse[2] = { vdupq_n_u32(0), vdupq_n_u32(0) }; - - int i = height; - do { - sse_16x1_neon_dotprod(src, ref, &sse[0]); - sse_16x1_neon_dotprod(src + 16, ref + 16, &sse[1]); - sse_16x1_neon_dotprod(src + 32, ref + 32, &sse[0]); - sse_16x1_neon_dotprod(src + 48, ref + 48, &sse[1]); - - src += src_stride; - ref += ref_stride; - } while (--i != 0); - - return horizontal_add_uint32x4(vaddq_u32(sse[0], sse[1])); -} - -static INLINE uint32_t sse_32xh_neon_dotprod(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - int height) { - uint32x4_t sse[2] = { vdupq_n_u32(0), vdupq_n_u32(0) }; - - int i = height; - do { - sse_16x1_neon_dotprod(src, ref, &sse[0]); - sse_16x1_neon_dotprod(src + 16, ref + 16, &sse[1]); - - src += src_stride; - ref += ref_stride; - } while (--i != 0); - - return horizontal_add_uint32x4(vaddq_u32(sse[0], sse[1])); -} - -static INLINE uint32_t sse_16xh_neon_dotprod(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - int height) { - uint32x4_t sse[2] = { vdupq_n_u32(0), vdupq_n_u32(0) }; - - int i = height; - do { - sse_16x1_neon_dotprod(src, ref, &sse[0]); - src += src_stride; - ref += ref_stride; - sse_16x1_neon_dotprod(src, ref, &sse[1]); - src += src_stride; - ref += ref_stride; - i -= 2; - } while (i != 0); - - return horizontal_add_uint32x4(vaddq_u32(sse[0], sse[1])); -} - -static INLINE uint32_t sse_8xh_neon_dotprod(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - int height) { - uint32x2_t sse[2] = { vdup_n_u32(0), vdup_n_u32(0) }; - - int i = height; - do { - sse_8x1_neon_dotprod(src, ref, &sse[0]); - src += src_stride; - ref += ref_stride; - sse_8x1_neon_dotprod(src, ref, &sse[1]); - src += src_stride; - ref += ref_stride; - i -= 2; - } while (i != 0); - - return horizontal_add_uint32x4(vcombine_u32(sse[0], sse[1])); -} - -static INLINE uint32_t sse_4xh_neon_dotprod(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - int height) { - uint32x2_t sse = vdup_n_u32(0); - - int i = height; - do { - sse_4x2_neon_dotprod(src, src_stride, ref, ref_stride, &sse); - - src += 2 * src_stride; - ref += 2 * ref_stride; - i -= 2; - } while (i != 0); - - return horizontal_add_uint32x2(sse); -} - -int64_t vpx_sse_neon_dotprod(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, int width, - int height) { - switch (width) { - case 4: - return sse_4xh_neon_dotprod(src, src_stride, ref, ref_stride, height); - case 8: - return sse_8xh_neon_dotprod(src, src_stride, ref, ref_stride, height); - case 16: - return sse_16xh_neon_dotprod(src, src_stride, ref, ref_stride, height); - case 32: - return sse_32xh_neon_dotprod(src, src_stride, ref, ref_stride, height); - case 64: - return sse_64xh_neon_dotprod(src, src_stride, ref, ref_stride, height); - default: - return sse_wxh_neon_dotprod(src, src_stride, ref, ref_stride, width, - height); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/subpel_variance_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/subpel_variance_neon.c deleted file mode 100644 index d92f1615..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/subpel_variance_neon.c +++ /dev/null @@ -1,489 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "./vpx_config.h" - -#include "vpx/vpx_integer.h" - -#include "vpx_dsp/variance.h" -#include "vpx_dsp/arm/mem_neon.h" - -// Process a block exactly 4 wide and a multiple of 2 high. -static void var_filter_block2d_bil_w4(const uint8_t *src_ptr, uint8_t *dst_ptr, - int src_stride, int pixel_step, - int dst_height, int filter_offset) { - const uint8x8_t f0 = vdup_n_u8(8 - filter_offset); - const uint8x8_t f1 = vdup_n_u8(filter_offset); - - int i = dst_height; - do { - uint8x8_t s0 = load_unaligned_u8(src_ptr, src_stride); - uint8x8_t s1 = load_unaligned_u8(src_ptr + pixel_step, src_stride); - uint16x8_t blend = vmlal_u8(vmull_u8(s0, f0), s1, f1); - uint8x8_t blend_u8 = vrshrn_n_u16(blend, 3); - vst1_u8(dst_ptr, blend_u8); - - src_ptr += 2 * src_stride; - dst_ptr += 2 * 4; - i -= 2; - } while (i != 0); -} - -// Process a block exactly 8 wide and any height. -static void var_filter_block2d_bil_w8(const uint8_t *src_ptr, uint8_t *dst_ptr, - int src_stride, int pixel_step, - int dst_height, int filter_offset) { - const uint8x8_t f0 = vdup_n_u8(8 - filter_offset); - const uint8x8_t f1 = vdup_n_u8(filter_offset); - - int i = dst_height; - do { - uint8x8_t s0 = vld1_u8(src_ptr); - uint8x8_t s1 = vld1_u8(src_ptr + pixel_step); - uint16x8_t blend = vmlal_u8(vmull_u8(s0, f0), s1, f1); - uint8x8_t blend_u8 = vrshrn_n_u16(blend, 3); - vst1_u8(dst_ptr, blend_u8); - - src_ptr += src_stride; - dst_ptr += 8; - } while (--i != 0); -} - -// Process a block which is a mutiple of 16 wide and any height. -static void var_filter_block2d_bil_large(const uint8_t *src_ptr, - uint8_t *dst_ptr, int src_stride, - int pixel_step, int dst_width, - int dst_height, int filter_offset) { - const uint8x8_t f0 = vdup_n_u8(8 - filter_offset); - const uint8x8_t f1 = vdup_n_u8(filter_offset); - - int i = dst_height; - do { - int j = 0; - do { - uint8x16_t s0 = vld1q_u8(src_ptr + j); - uint8x16_t s1 = vld1q_u8(src_ptr + j + pixel_step); - uint16x8_t blend_l = - vmlal_u8(vmull_u8(vget_low_u8(s0), f0), vget_low_u8(s1), f1); - uint16x8_t blend_h = - vmlal_u8(vmull_u8(vget_high_u8(s0), f0), vget_high_u8(s1), f1); - uint8x8_t out_lo = vrshrn_n_u16(blend_l, 3); - uint8x8_t out_hi = vrshrn_n_u16(blend_h, 3); - vst1q_u8(dst_ptr + j, vcombine_u8(out_lo, out_hi)); - - j += 16; - } while (j < dst_width); - - src_ptr += src_stride; - dst_ptr += dst_width; - } while (--i != 0); -} - -static void var_filter_block2d_bil_w16(const uint8_t *src_ptr, uint8_t *dst_ptr, - int src_stride, int pixel_step, - int dst_height, int filter_offset) { - var_filter_block2d_bil_large(src_ptr, dst_ptr, src_stride, pixel_step, 16, - dst_height, filter_offset); -} -static void var_filter_block2d_bil_w32(const uint8_t *src_ptr, uint8_t *dst_ptr, - int src_stride, int pixel_step, - int dst_height, int filter_offset) { - var_filter_block2d_bil_large(src_ptr, dst_ptr, src_stride, pixel_step, 32, - dst_height, filter_offset); -} -static void var_filter_block2d_bil_w64(const uint8_t *src_ptr, uint8_t *dst_ptr, - int src_stride, int pixel_step, - int dst_height, int filter_offset) { - var_filter_block2d_bil_large(src_ptr, dst_ptr, src_stride, pixel_step, 64, - dst_height, filter_offset); -} - -static void var_filter_block2d_avg(const uint8_t *src_ptr, uint8_t *dst_ptr, - int src_stride, int pixel_step, - int dst_width, int dst_height) { - int i = dst_height; - - // We only specialize on the filter values for large block sizes (>= 16x16.) - assert(dst_width >= 16 && dst_width % 16 == 0); - - do { - int j = 0; - do { - uint8x16_t s0 = vld1q_u8(src_ptr + j); - uint8x16_t s1 = vld1q_u8(src_ptr + j + pixel_step); - uint8x16_t avg = vrhaddq_u8(s0, s1); - vst1q_u8(dst_ptr + j, avg); - - j += 16; - } while (j < dst_width); - - src_ptr += src_stride; - dst_ptr += dst_width; - } while (--i != 0); -} - -#define SUBPEL_VARIANCE_WXH_NEON(w, h, padding) \ - unsigned int vpx_sub_pixel_variance##w##x##h##_neon( \ - const uint8_t *src, int src_stride, int xoffset, int yoffset, \ - const uint8_t *ref, int ref_stride, uint32_t *sse) { \ - uint8_t tmp0[w * (h + padding)]; \ - uint8_t tmp1[w * h]; \ - var_filter_block2d_bil_w##w(src, tmp0, src_stride, 1, (h + padding), \ - xoffset); \ - var_filter_block2d_bil_w##w(tmp0, tmp1, w, w, h, yoffset); \ - return vpx_variance##w##x##h(tmp1, w, ref, ref_stride, sse); \ - } - -#define SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(w, h, padding) \ - unsigned int vpx_sub_pixel_variance##w##x##h##_neon( \ - const uint8_t *src, int src_stride, int xoffset, int yoffset, \ - const uint8_t *ref, int ref_stride, unsigned int *sse) { \ - if (xoffset == 0) { \ - if (yoffset == 0) { \ - return vpx_variance##w##x##h(src, src_stride, ref, ref_stride, sse); \ - } else if (yoffset == 4) { \ - uint8_t tmp[w * h]; \ - var_filter_block2d_avg(src, tmp, src_stride, src_stride, w, h); \ - return vpx_variance##w##x##h(tmp, w, ref, ref_stride, sse); \ - } else { \ - uint8_t tmp[w * h]; \ - var_filter_block2d_bil_w##w(src, tmp, src_stride, src_stride, h, \ - yoffset); \ - return vpx_variance##w##x##h(tmp, w, ref, ref_stride, sse); \ - } \ - } else if (xoffset == 4) { \ - uint8_t tmp0[w * (h + padding)]; \ - if (yoffset == 0) { \ - var_filter_block2d_avg(src, tmp0, src_stride, 1, w, h); \ - return vpx_variance##w##x##h(tmp0, w, ref, ref_stride, sse); \ - } else if (yoffset == 4) { \ - uint8_t tmp1[w * (h + padding)]; \ - var_filter_block2d_avg(src, tmp0, src_stride, 1, w, (h + padding)); \ - var_filter_block2d_avg(tmp0, tmp1, w, w, w, h); \ - return vpx_variance##w##x##h(tmp1, w, ref, ref_stride, sse); \ - } else { \ - uint8_t tmp1[w * (h + padding)]; \ - var_filter_block2d_avg(src, tmp0, src_stride, 1, w, (h + padding)); \ - var_filter_block2d_bil_w##w(tmp0, tmp1, w, w, h, yoffset); \ - return vpx_variance##w##x##h(tmp1, w, ref, ref_stride, sse); \ - } \ - } else { \ - uint8_t tmp0[w * (h + padding)]; \ - if (yoffset == 0) { \ - var_filter_block2d_bil_w##w(src, tmp0, src_stride, 1, h, xoffset); \ - return vpx_variance##w##x##h(tmp0, w, ref, ref_stride, sse); \ - } else if (yoffset == 4) { \ - uint8_t tmp1[w * h]; \ - var_filter_block2d_bil_w##w(src, tmp0, src_stride, 1, (h + padding), \ - xoffset); \ - var_filter_block2d_avg(tmp0, tmp1, w, w, w, h); \ - return vpx_variance##w##x##h(tmp1, w, ref, ref_stride, sse); \ - } else { \ - uint8_t tmp1[w * h]; \ - var_filter_block2d_bil_w##w(src, tmp0, src_stride, 1, (h + padding), \ - xoffset); \ - var_filter_block2d_bil_w##w(tmp0, tmp1, w, w, h, yoffset); \ - return vpx_variance##w##x##h(tmp1, w, ref, ref_stride, sse); \ - } \ - } \ - } - -// 4x blocks are processed two rows at a time, so require an extra row of -// padding. -SUBPEL_VARIANCE_WXH_NEON(4, 4, 2) -SUBPEL_VARIANCE_WXH_NEON(4, 8, 2) - -SUBPEL_VARIANCE_WXH_NEON(8, 4, 1) -SUBPEL_VARIANCE_WXH_NEON(8, 8, 1) -SUBPEL_VARIANCE_WXH_NEON(8, 16, 1) - -SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(16, 8, 1) -SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(16, 16, 1) -SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(16, 32, 1) - -SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(32, 16, 1) -SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(32, 32, 1) -SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(32, 64, 1) - -SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(64, 32, 1) -SPECIALIZED_SUBPEL_VARIANCE_WXH_NEON(64, 64, 1) - -// Combine bilinear filter with vpx_comp_avg_pred for blocks having width 4. -static void avg_pred_var_filter_block2d_bil_w4(const uint8_t *src_ptr, - uint8_t *dst_ptr, int src_stride, - int pixel_step, int dst_height, - int filter_offset, - const uint8_t *second_pred) { - const uint8x8_t f0 = vdup_n_u8(8 - filter_offset); - const uint8x8_t f1 = vdup_n_u8(filter_offset); - - int i = dst_height; - do { - uint8x8_t s0 = load_unaligned_u8(src_ptr, src_stride); - uint8x8_t s1 = load_unaligned_u8(src_ptr + pixel_step, src_stride); - uint16x8_t blend = vmlal_u8(vmull_u8(s0, f0), s1, f1); - uint8x8_t blend_u8 = vrshrn_n_u16(blend, 3); - - uint8x8_t p = vld1_u8(second_pred); - uint8x8_t avg = vrhadd_u8(blend_u8, p); - - vst1_u8(dst_ptr, avg); - - src_ptr += 2 * src_stride; - dst_ptr += 2 * 4; - second_pred += 2 * 4; - i -= 2; - } while (i != 0); -} - -// Combine bilinear filter with vpx_comp_avg_pred for blocks having width 8. -static void avg_pred_var_filter_block2d_bil_w8(const uint8_t *src_ptr, - uint8_t *dst_ptr, int src_stride, - int pixel_step, int dst_height, - int filter_offset, - const uint8_t *second_pred) { - const uint8x8_t f0 = vdup_n_u8(8 - filter_offset); - const uint8x8_t f1 = vdup_n_u8(filter_offset); - - int i = dst_height; - do { - uint8x8_t s0 = vld1_u8(src_ptr); - uint8x8_t s1 = vld1_u8(src_ptr + pixel_step); - uint16x8_t blend = vmlal_u8(vmull_u8(s0, f0), s1, f1); - uint8x8_t blend_u8 = vrshrn_n_u16(blend, 3); - - uint8x8_t p = vld1_u8(second_pred); - uint8x8_t avg = vrhadd_u8(blend_u8, p); - - vst1_u8(dst_ptr, avg); - - src_ptr += src_stride; - dst_ptr += 8; - second_pred += 8; - } while (--i > 0); -} - -// Combine bilinear filter with vpx_comp_avg_pred for large blocks. -static void avg_pred_var_filter_block2d_bil_large( - const uint8_t *src_ptr, uint8_t *dst_ptr, int src_stride, int pixel_step, - int dst_width, int dst_height, int filter_offset, - const uint8_t *second_pred) { - const uint8x8_t f0 = vdup_n_u8(8 - filter_offset); - const uint8x8_t f1 = vdup_n_u8(filter_offset); - - int i = dst_height; - do { - int j = 0; - do { - uint8x16_t s0 = vld1q_u8(src_ptr + j); - uint8x16_t s1 = vld1q_u8(src_ptr + j + pixel_step); - uint16x8_t blend_l = - vmlal_u8(vmull_u8(vget_low_u8(s0), f0), vget_low_u8(s1), f1); - uint16x8_t blend_h = - vmlal_u8(vmull_u8(vget_high_u8(s0), f0), vget_high_u8(s1), f1); - uint8x16_t blend_u8 = - vcombine_u8(vrshrn_n_u16(blend_l, 3), vrshrn_n_u16(blend_h, 3)); - - uint8x16_t p = vld1q_u8(second_pred); - uint8x16_t avg = vrhaddq_u8(blend_u8, p); - - vst1q_u8(dst_ptr + j, avg); - - j += 16; - second_pred += 16; - } while (j < dst_width); - - src_ptr += src_stride; - dst_ptr += dst_width; - } while (--i != 0); -} - -// Combine bilinear filter with vpx_comp_avg_pred for blocks having width 16. -static void avg_pred_var_filter_block2d_bil_w16( - const uint8_t *src_ptr, uint8_t *dst_ptr, int src_stride, int pixel_step, - int dst_height, int filter_offset, const uint8_t *second_pred) { - avg_pred_var_filter_block2d_bil_large(src_ptr, dst_ptr, src_stride, - pixel_step, 16, dst_height, - filter_offset, second_pred); -} - -// Combine bilinear filter with vpx_comp_avg_pred for blocks having width 32. -static void avg_pred_var_filter_block2d_bil_w32( - const uint8_t *src_ptr, uint8_t *dst_ptr, int src_stride, int pixel_step, - int dst_height, int filter_offset, const uint8_t *second_pred) { - avg_pred_var_filter_block2d_bil_large(src_ptr, dst_ptr, src_stride, - pixel_step, 32, dst_height, - filter_offset, second_pred); -} - -// Combine bilinear filter with vpx_comp_avg_pred for blocks having width 64. -static void avg_pred_var_filter_block2d_bil_w64( - const uint8_t *src_ptr, uint8_t *dst_ptr, int src_stride, int pixel_step, - int dst_height, int filter_offset, const uint8_t *second_pred) { - avg_pred_var_filter_block2d_bil_large(src_ptr, dst_ptr, src_stride, - pixel_step, 64, dst_height, - filter_offset, second_pred); -} - -// Combine averaging subpel filter with vpx_comp_avg_pred. -static void avg_pred_var_filter_block2d_avg(const uint8_t *src_ptr, - uint8_t *dst_ptr, int src_stride, - int pixel_step, int dst_width, - int dst_height, - const uint8_t *second_pred) { - int i = dst_height; - - // We only specialize on the filter values for large block sizes (>= 16x16.) - assert(dst_width >= 16 && dst_width % 16 == 0); - - do { - int j = 0; - do { - uint8x16_t s0 = vld1q_u8(src_ptr + j); - uint8x16_t s1 = vld1q_u8(src_ptr + j + pixel_step); - uint8x16_t avg = vrhaddq_u8(s0, s1); - - uint8x16_t p = vld1q_u8(second_pred); - avg = vrhaddq_u8(avg, p); - - vst1q_u8(dst_ptr + j, avg); - - j += 16; - second_pred += 16; - } while (j < dst_width); - - src_ptr += src_stride; - dst_ptr += dst_width; - } while (--i != 0); -} - -// Implementation of vpx_comp_avg_pred for blocks having width >= 16. -static void avg_pred(const uint8_t *src_ptr, uint8_t *dst_ptr, int src_stride, - int dst_width, int dst_height, - const uint8_t *second_pred) { - int i = dst_height; - - // We only specialize on the filter values for large block sizes (>= 16x16.) - assert(dst_width >= 16 && dst_width % 16 == 0); - - do { - int j = 0; - do { - uint8x16_t s = vld1q_u8(src_ptr + j); - uint8x16_t p = vld1q_u8(second_pred); - - uint8x16_t avg = vrhaddq_u8(s, p); - - vst1q_u8(dst_ptr + j, avg); - - j += 16; - second_pred += 16; - } while (j < dst_width); - - src_ptr += src_stride; - dst_ptr += dst_width; - } while (--i != 0); -} - -#define SUBPEL_AVG_VARIANCE_WXH_NEON(w, h, padding) \ - unsigned int vpx_sub_pixel_avg_variance##w##x##h##_neon( \ - const uint8_t *src, int source_stride, int xoffset, int yoffset, \ - const uint8_t *ref, int ref_stride, uint32_t *sse, \ - const uint8_t *second_pred) { \ - uint8_t tmp0[w * (h + padding)]; \ - uint8_t tmp1[w * h]; \ - var_filter_block2d_bil_w##w(src, tmp0, source_stride, 1, (h + padding), \ - xoffset); \ - avg_pred_var_filter_block2d_bil_w##w(tmp0, tmp1, w, w, h, yoffset, \ - second_pred); \ - return vpx_variance##w##x##h(tmp1, w, ref, ref_stride, sse); \ - } - -#define SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(w, h, padding) \ - unsigned int vpx_sub_pixel_avg_variance##w##x##h##_neon( \ - const uint8_t *src, int source_stride, int xoffset, int yoffset, \ - const uint8_t *ref, int ref_stride, unsigned int *sse, \ - const uint8_t *second_pred) { \ - if (xoffset == 0) { \ - uint8_t tmp[w * h]; \ - if (yoffset == 0) { \ - avg_pred(src, tmp, source_stride, w, h, second_pred); \ - return vpx_variance##w##x##h(tmp, w, ref, ref_stride, sse); \ - } else if (yoffset == 4) { \ - avg_pred_var_filter_block2d_avg(src, tmp, source_stride, \ - source_stride, w, h, second_pred); \ - return vpx_variance##w##x##h(tmp, w, ref, ref_stride, sse); \ - } else { \ - avg_pred_var_filter_block2d_bil_w##w( \ - src, tmp, source_stride, source_stride, h, yoffset, second_pred); \ - return vpx_variance##w##x##h(tmp, w, ref, ref_stride, sse); \ - } \ - } else if (xoffset == 4) { \ - uint8_t tmp0[w * (h + padding)]; \ - if (yoffset == 0) { \ - avg_pred_var_filter_block2d_avg(src, tmp0, source_stride, 1, w, h, \ - second_pred); \ - return vpx_variance##w##x##h(tmp0, w, ref, ref_stride, sse); \ - } else if (yoffset == 4) { \ - uint8_t tmp1[w * (h + padding)]; \ - var_filter_block2d_avg(src, tmp0, source_stride, 1, w, (h + padding)); \ - avg_pred_var_filter_block2d_avg(tmp0, tmp1, w, w, w, h, second_pred); \ - return vpx_variance##w##x##h(tmp1, w, ref, ref_stride, sse); \ - } else { \ - uint8_t tmp1[w * (h + padding)]; \ - var_filter_block2d_avg(src, tmp0, source_stride, 1, w, (h + padding)); \ - avg_pred_var_filter_block2d_bil_w##w(tmp0, tmp1, w, w, h, yoffset, \ - second_pred); \ - return vpx_variance##w##x##h(tmp1, w, ref, ref_stride, sse); \ - } \ - } else { \ - uint8_t tmp0[w * (h + padding)]; \ - if (yoffset == 0) { \ - avg_pred_var_filter_block2d_bil_w##w(src, tmp0, source_stride, 1, h, \ - xoffset, second_pred); \ - return vpx_variance##w##x##h(tmp0, w, ref, ref_stride, sse); \ - } else if (yoffset == 4) { \ - uint8_t tmp1[w * h]; \ - var_filter_block2d_bil_w##w(src, tmp0, source_stride, 1, \ - (h + padding), xoffset); \ - avg_pred_var_filter_block2d_avg(tmp0, tmp1, w, w, w, h, second_pred); \ - return vpx_variance##w##x##h(tmp1, w, ref, ref_stride, sse); \ - } else { \ - uint8_t tmp1[w * h]; \ - var_filter_block2d_bil_w##w(src, tmp0, source_stride, 1, \ - (h + padding), xoffset); \ - avg_pred_var_filter_block2d_bil_w##w(tmp0, tmp1, w, w, h, yoffset, \ - second_pred); \ - return vpx_variance##w##x##h(tmp1, w, ref, ref_stride, sse); \ - } \ - } \ - } - -// 4x blocks are processed two rows at a time, so require an extra row of -// padding. -SUBPEL_AVG_VARIANCE_WXH_NEON(4, 4, 2) -SUBPEL_AVG_VARIANCE_WXH_NEON(4, 8, 2) - -SUBPEL_AVG_VARIANCE_WXH_NEON(8, 4, 1) -SUBPEL_AVG_VARIANCE_WXH_NEON(8, 8, 1) -SUBPEL_AVG_VARIANCE_WXH_NEON(8, 16, 1) - -SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(16, 8, 1) -SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(16, 16, 1) -SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(16, 32, 1) - -SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(32, 16, 1) -SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(32, 32, 1) -SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(32, 64, 1) - -SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(64, 32, 1) -SPECIALIZED_SUBPEL_AVG_VARIANCE_WXH_NEON(64, 64, 1) diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/subtract_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/subtract_neon.c deleted file mode 100644 index 2c008e48..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/subtract_neon.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/mem_neon.h" - -void vpx_subtract_block_neon(int rows, int cols, int16_t *diff, - ptrdiff_t diff_stride, const uint8_t *src, - ptrdiff_t src_stride, const uint8_t *pred, - ptrdiff_t pred_stride) { - int r = rows, c; - - if (cols > 16) { - do { - for (c = 0; c < cols; c += 32) { - const uint8x16_t s0 = vld1q_u8(&src[c + 0]); - const uint8x16_t s1 = vld1q_u8(&src[c + 16]); - const uint8x16_t p0 = vld1q_u8(&pred[c + 0]); - const uint8x16_t p1 = vld1q_u8(&pred[c + 16]); - const uint16x8_t d0 = vsubl_u8(vget_low_u8(s0), vget_low_u8(p0)); - const uint16x8_t d1 = vsubl_u8(vget_high_u8(s0), vget_high_u8(p0)); - const uint16x8_t d2 = vsubl_u8(vget_low_u8(s1), vget_low_u8(p1)); - const uint16x8_t d3 = vsubl_u8(vget_high_u8(s1), vget_high_u8(p1)); - vst1q_s16(&diff[c + 0], vreinterpretq_s16_u16(d0)); - vst1q_s16(&diff[c + 8], vreinterpretq_s16_u16(d1)); - vst1q_s16(&diff[c + 16], vreinterpretq_s16_u16(d2)); - vst1q_s16(&diff[c + 24], vreinterpretq_s16_u16(d3)); - } - diff += diff_stride; - pred += pred_stride; - src += src_stride; - } while (--r); - } else if (cols > 8) { - do { - const uint8x16_t s = vld1q_u8(&src[0]); - const uint8x16_t p = vld1q_u8(&pred[0]); - const uint16x8_t d0 = vsubl_u8(vget_low_u8(s), vget_low_u8(p)); - const uint16x8_t d1 = vsubl_u8(vget_high_u8(s), vget_high_u8(p)); - vst1q_s16(&diff[0], vreinterpretq_s16_u16(d0)); - vst1q_s16(&diff[8], vreinterpretq_s16_u16(d1)); - diff += diff_stride; - pred += pred_stride; - src += src_stride; - } while (--r); - } else if (cols > 4) { - do { - const uint8x8_t s = vld1_u8(&src[0]); - const uint8x8_t p = vld1_u8(&pred[0]); - const uint16x8_t v_diff = vsubl_u8(s, p); - vst1q_s16(&diff[0], vreinterpretq_s16_u16(v_diff)); - diff += diff_stride; - pred += pred_stride; - src += src_stride; - } while (--r); - } else { - assert(cols == 4); - do { - const uint8x8_t s = load_unaligned_u8(src, (int)src_stride); - const uint8x8_t p = load_unaligned_u8(pred, (int)pred_stride); - const uint16x8_t d = vsubl_u8(s, p); - vst1_s16(diff + 0 * diff_stride, vreinterpret_s16_u16(vget_low_u16(d))); - vst1_s16(diff + 1 * diff_stride, vreinterpret_s16_u16(vget_high_u16(d))); - diff += 2 * diff_stride; - pred += 2 * pred_stride; - src += 2 * src_stride; - r -= 2; - } while (r); - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -void vpx_highbd_subtract_block_neon(int rows, int cols, int16_t *diff_ptr, - ptrdiff_t diff_stride, - const uint8_t *src8_ptr, - ptrdiff_t src_stride, - const uint8_t *pred8_ptr, - ptrdiff_t pred_stride, int bd) { - int r = rows, c; - uint16_t *src = CONVERT_TO_SHORTPTR(src8_ptr); - uint16_t *pred = CONVERT_TO_SHORTPTR(pred8_ptr); - (void)bd; - - if (cols >= 16) { - do { - for (c = 0; c < cols; c += 16) { - const uint16x8_t s0 = vld1q_u16(&src[c + 0]); - const uint16x8_t s1 = vld1q_u16(&src[c + 8]); - const uint16x8_t p0 = vld1q_u16(&pred[c + 0]); - const uint16x8_t p1 = vld1q_u16(&pred[c + 8]); - const uint16x8_t d0 = vsubq_u16(s0, p0); - const uint16x8_t d1 = vsubq_u16(s1, p1); - vst1q_s16(&diff_ptr[c + 0], vreinterpretq_s16_u16(d0)); - vst1q_s16(&diff_ptr[c + 8], vreinterpretq_s16_u16(d1)); - } - diff_ptr += diff_stride; - pred += pred_stride; - src += src_stride; - } while (--r); - } else if (cols >= 8) { - do { - for (c = 0; c < cols; c += 8) { - const uint16x8_t s = vld1q_u16(&src[c]); - const uint16x8_t p = vld1q_u16(&pred[c]); - const uint16x8_t d0 = vsubq_u16(s, p); - vst1q_s16(&diff_ptr[c], vreinterpretq_s16_u16(d0)); - } - diff_ptr += diff_stride; - pred += pred_stride; - src += src_stride; - } while (--r); - } else if (cols >= 4) { - do { - for (c = 0; c < cols; c += 4) { - const uint16x4_t s = vld1_u16(&src[c]); - const uint16x4_t p = vld1_u16(&pred[c]); - const uint16x4_t v_diff = vsub_u16(s, p); - vst1_s16(&diff_ptr[c], vreinterpret_s16_u16(v_diff)); - } - diff_ptr += diff_stride; - pred += pred_stride; - src += src_stride; - } while (--r); - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sum_neon.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sum_neon.h deleted file mode 100644 index 11821dc1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sum_neon.h +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_ARM_SUM_NEON_H_ -#define VPX_VPX_DSP_ARM_SUM_NEON_H_ - -#include - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" - -static INLINE uint16_t horizontal_add_uint8x4(const uint8x8_t a) { -#if VPX_ARCH_AARCH64 - return vaddlv_u8(a); -#else - const uint16x4_t b = vpaddl_u8(a); - const uint16x4_t c = vpadd_u16(b, b); - return vget_lane_u16(c, 0); -#endif -} - -static INLINE uint16_t horizontal_add_uint8x8(const uint8x8_t a) { -#if VPX_ARCH_AARCH64 - return vaddlv_u8(a); -#else - const uint16x4_t b = vpaddl_u8(a); - const uint16x4_t c = vpadd_u16(b, b); - const uint16x4_t d = vpadd_u16(c, c); - return vget_lane_u16(d, 0); -#endif -} - -static INLINE uint16_t horizontal_add_uint8x16(const uint8x16_t a) { -#if VPX_ARCH_AARCH64 - return vaddlvq_u8(a); -#else - const uint16x8_t b = vpaddlq_u8(a); - const uint16x4_t c = vadd_u16(vget_low_u16(b), vget_high_u16(b)); - const uint16x4_t d = vpadd_u16(c, c); - const uint16x4_t e = vpadd_u16(d, d); - return vget_lane_u16(e, 0); -#endif -} - -static INLINE uint16_t horizontal_add_uint16x4(const uint16x4_t a) { -#if VPX_ARCH_AARCH64 - return vaddv_u16(a); -#else - const uint16x4_t b = vpadd_u16(a, a); - const uint16x4_t c = vpadd_u16(b, b); - return vget_lane_u16(c, 0); -#endif -} - -static INLINE int32_t horizontal_add_int16x8(const int16x8_t a) { -#if VPX_ARCH_AARCH64 - return vaddlvq_s16(a); -#else - const int32x4_t b = vpaddlq_s16(a); - const int64x2_t c = vpaddlq_s32(b); - const int32x2_t d = vadd_s32(vreinterpret_s32_s64(vget_low_s64(c)), - vreinterpret_s32_s64(vget_high_s64(c))); - return vget_lane_s32(d, 0); -#endif -} - -static INLINE uint32_t horizontal_add_uint16x8(const uint16x8_t a) { -#if VPX_ARCH_AARCH64 - return vaddlvq_u16(a); -#else - const uint32x4_t b = vpaddlq_u16(a); - const uint64x2_t c = vpaddlq_u32(b); - const uint32x2_t d = vadd_u32(vreinterpret_u32_u64(vget_low_u64(c)), - vreinterpret_u32_u64(vget_high_u64(c))); - return vget_lane_u32(d, 0); -#endif -} - -static INLINE uint32x4_t horizontal_add_4d_uint16x8(const uint16x8_t sum[4]) { -#if VPX_ARCH_AARCH64 - const uint16x8_t a0 = vpaddq_u16(sum[0], sum[1]); - const uint16x8_t a1 = vpaddq_u16(sum[2], sum[3]); - const uint16x8_t b0 = vpaddq_u16(a0, a1); - return vpaddlq_u16(b0); -#else - const uint16x4_t a0 = vadd_u16(vget_low_u16(sum[0]), vget_high_u16(sum[0])); - const uint16x4_t a1 = vadd_u16(vget_low_u16(sum[1]), vget_high_u16(sum[1])); - const uint16x4_t a2 = vadd_u16(vget_low_u16(sum[2]), vget_high_u16(sum[2])); - const uint16x4_t a3 = vadd_u16(vget_low_u16(sum[3]), vget_high_u16(sum[3])); - const uint16x4_t b0 = vpadd_u16(a0, a1); - const uint16x4_t b1 = vpadd_u16(a2, a3); - return vpaddlq_u16(vcombine_u16(b0, b1)); -#endif -} - -static INLINE uint32_t horizontal_long_add_uint16x8(const uint16x8_t vec_lo, - const uint16x8_t vec_hi) { -#if VPX_ARCH_AARCH64 - return vaddlvq_u16(vec_lo) + vaddlvq_u16(vec_hi); -#else - const uint32x4_t vec_l_lo = - vaddl_u16(vget_low_u16(vec_lo), vget_high_u16(vec_lo)); - const uint32x4_t vec_l_hi = - vaddl_u16(vget_low_u16(vec_hi), vget_high_u16(vec_hi)); - const uint32x4_t a = vaddq_u32(vec_l_lo, vec_l_hi); - const uint64x2_t b = vpaddlq_u32(a); - const uint32x2_t c = vadd_u32(vreinterpret_u32_u64(vget_low_u64(b)), - vreinterpret_u32_u64(vget_high_u64(b))); - return vget_lane_u32(c, 0); -#endif -} - -static INLINE uint32x4_t horizontal_long_add_4d_uint16x8( - const uint16x8_t sum_lo[4], const uint16x8_t sum_hi[4]) { - const uint32x4_t a0 = vpaddlq_u16(sum_lo[0]); - const uint32x4_t a1 = vpaddlq_u16(sum_lo[1]); - const uint32x4_t a2 = vpaddlq_u16(sum_lo[2]); - const uint32x4_t a3 = vpaddlq_u16(sum_lo[3]); - const uint32x4_t b0 = vpadalq_u16(a0, sum_hi[0]); - const uint32x4_t b1 = vpadalq_u16(a1, sum_hi[1]); - const uint32x4_t b2 = vpadalq_u16(a2, sum_hi[2]); - const uint32x4_t b3 = vpadalq_u16(a3, sum_hi[3]); -#if VPX_ARCH_AARCH64 - const uint32x4_t c0 = vpaddq_u32(b0, b1); - const uint32x4_t c1 = vpaddq_u32(b2, b3); - return vpaddq_u32(c0, c1); -#else - const uint32x2_t c0 = vadd_u32(vget_low_u32(b0), vget_high_u32(b0)); - const uint32x2_t c1 = vadd_u32(vget_low_u32(b1), vget_high_u32(b1)); - const uint32x2_t c2 = vadd_u32(vget_low_u32(b2), vget_high_u32(b2)); - const uint32x2_t c3 = vadd_u32(vget_low_u32(b3), vget_high_u32(b3)); - const uint32x2_t d0 = vpadd_u32(c0, c1); - const uint32x2_t d1 = vpadd_u32(c2, c3); - return vcombine_u32(d0, d1); -#endif -} - -static INLINE int32_t horizontal_add_int32x2(const int32x2_t a) { -#if VPX_ARCH_AARCH64 - return vaddv_s32(a); -#else - return vget_lane_s32(a, 0) + vget_lane_s32(a, 1); -#endif -} - -static INLINE uint32_t horizontal_add_uint32x2(const uint32x2_t a) { -#if VPX_ARCH_AARCH64 - return vaddv_u32(a); -#else - const uint64x1_t b = vpaddl_u32(a); - return vget_lane_u32(vreinterpret_u32_u64(b), 0); -#endif -} - -static INLINE int32_t horizontal_add_int32x4(const int32x4_t a) { -#if VPX_ARCH_AARCH64 - return vaddvq_s32(a); -#else - const int64x2_t b = vpaddlq_s32(a); - const int32x2_t c = vadd_s32(vreinterpret_s32_s64(vget_low_s64(b)), - vreinterpret_s32_s64(vget_high_s64(b))); - return vget_lane_s32(c, 0); -#endif -} - -static INLINE uint32_t horizontal_add_uint32x4(const uint32x4_t a) { -#if VPX_ARCH_AARCH64 - return vaddvq_u32(a); -#else - const uint64x2_t b = vpaddlq_u32(a); - const uint32x2_t c = vadd_u32(vreinterpret_u32_u64(vget_low_u64(b)), - vreinterpret_u32_u64(vget_high_u64(b))); - return vget_lane_u32(c, 0); -#endif -} - -static INLINE uint32x4_t horizontal_add_4d_uint32x4(const uint32x4_t sum[4]) { -#if VPX_ARCH_AARCH64 - uint32x4_t res01 = vpaddq_u32(sum[0], sum[1]); - uint32x4_t res23 = vpaddq_u32(sum[2], sum[3]); - return vpaddq_u32(res01, res23); -#else - uint32x4_t res = vdupq_n_u32(0); - res = vsetq_lane_u32(horizontal_add_uint32x4(sum[0]), res, 0); - res = vsetq_lane_u32(horizontal_add_uint32x4(sum[1]), res, 1); - res = vsetq_lane_u32(horizontal_add_uint32x4(sum[2]), res, 2); - res = vsetq_lane_u32(horizontal_add_uint32x4(sum[3]), res, 3); - return res; -#endif -} - -static INLINE uint64_t horizontal_long_add_uint32x4(const uint32x4_t a) { -#if VPX_ARCH_AARCH64 - return vaddlvq_u32(a); -#else - const uint64x2_t b = vpaddlq_u32(a); - return vgetq_lane_u64(b, 0) + vgetq_lane_u64(b, 1); -#endif -} - -static INLINE int64_t horizontal_add_int64x2(const int64x2_t a) { -#if VPX_ARCH_AARCH64 - return vaddvq_s64(a); -#else - return vgetq_lane_s64(a, 0) + vgetq_lane_s64(a, 1); -#endif -} - -static INLINE uint64_t horizontal_add_uint64x2(const uint64x2_t a) { -#if VPX_ARCH_AARCH64 - return vaddvq_u64(a); -#else - return vgetq_lane_u64(a, 0) + vgetq_lane_u64(a, 1); -#endif -} - -static INLINE uint64_t horizontal_long_add_uint32x4_x2(const uint32x4_t a[2]) { - return horizontal_long_add_uint32x4(a[0]) + - horizontal_long_add_uint32x4(a[1]); -} - -static INLINE uint64_t horizontal_long_add_uint32x4_x4(const uint32x4_t a[4]) { - uint64x2_t sum = vpaddlq_u32(a[0]); - sum = vpadalq_u32(sum, a[1]); - sum = vpadalq_u32(sum, a[2]); - sum = vpadalq_u32(sum, a[3]); - - return horizontal_add_uint64x2(sum); -} - -static INLINE uint64_t horizontal_long_add_uint32x4_x8(const uint32x4_t a[8]) { - uint64x2_t sum[2]; - sum[0] = vpaddlq_u32(a[0]); - sum[1] = vpaddlq_u32(a[1]); - sum[0] = vpadalq_u32(sum[0], a[2]); - sum[1] = vpadalq_u32(sum[1], a[3]); - sum[0] = vpadalq_u32(sum[0], a[4]); - sum[1] = vpadalq_u32(sum[1], a[5]); - sum[0] = vpadalq_u32(sum[0], a[6]); - sum[1] = vpadalq_u32(sum[1], a[7]); - - return horizontal_add_uint64x2(vaddq_u64(sum[0], sum[1])); -} - -static INLINE uint64_t -horizontal_long_add_uint32x4_x16(const uint32x4_t a[16]) { - uint64x2_t sum[2]; - sum[0] = vpaddlq_u32(a[0]); - sum[1] = vpaddlq_u32(a[1]); - sum[0] = vpadalq_u32(sum[0], a[2]); - sum[1] = vpadalq_u32(sum[1], a[3]); - sum[0] = vpadalq_u32(sum[0], a[4]); - sum[1] = vpadalq_u32(sum[1], a[5]); - sum[0] = vpadalq_u32(sum[0], a[6]); - sum[1] = vpadalq_u32(sum[1], a[7]); - sum[0] = vpadalq_u32(sum[0], a[8]); - sum[1] = vpadalq_u32(sum[1], a[9]); - sum[0] = vpadalq_u32(sum[0], a[10]); - sum[1] = vpadalq_u32(sum[1], a[11]); - sum[0] = vpadalq_u32(sum[0], a[12]); - sum[1] = vpadalq_u32(sum[1], a[13]); - sum[0] = vpadalq_u32(sum[0], a[14]); - sum[1] = vpadalq_u32(sum[1], a[15]); - - return horizontal_add_uint64x2(vaddq_u64(sum[0], sum[1])); -} - -#endif // VPX_VPX_DSP_ARM_SUM_NEON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sum_squares_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sum_squares_neon.c deleted file mode 100644 index 074afe32..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sum_squares_neon.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/sum_neon.h" - -uint64_t vpx_sum_squares_2d_i16_neon(const int16_t *src, int stride, int size) { - if (size == 4) { - int16x4_t s[4]; - int32x4_t sum_s32; - - s[0] = vld1_s16(src + 0 * stride); - s[1] = vld1_s16(src + 1 * stride); - s[2] = vld1_s16(src + 2 * stride); - s[3] = vld1_s16(src + 3 * stride); - - sum_s32 = vmull_s16(s[0], s[0]); - sum_s32 = vmlal_s16(sum_s32, s[1], s[1]); - sum_s32 = vmlal_s16(sum_s32, s[2], s[2]); - sum_s32 = vmlal_s16(sum_s32, s[3], s[3]); - - return horizontal_long_add_uint32x4(vreinterpretq_u32_s32(sum_s32)); - } else { - uint64x2_t sum_u64 = vdupq_n_u64(0); - int rows = size; - - do { - const int16_t *src_ptr = src; - int32x4_t sum_s32[2] = { vdupq_n_s32(0), vdupq_n_s32(0) }; - int cols = size; - - do { - int16x8_t s[8]; - - s[0] = vld1q_s16(src_ptr + 0 * stride); - s[1] = vld1q_s16(src_ptr + 1 * stride); - s[2] = vld1q_s16(src_ptr + 2 * stride); - s[3] = vld1q_s16(src_ptr + 3 * stride); - s[4] = vld1q_s16(src_ptr + 4 * stride); - s[5] = vld1q_s16(src_ptr + 5 * stride); - s[6] = vld1q_s16(src_ptr + 6 * stride); - s[7] = vld1q_s16(src_ptr + 7 * stride); - - sum_s32[0] = - vmlal_s16(sum_s32[0], vget_low_s16(s[0]), vget_low_s16(s[0])); - sum_s32[0] = - vmlal_s16(sum_s32[0], vget_low_s16(s[1]), vget_low_s16(s[1])); - sum_s32[0] = - vmlal_s16(sum_s32[0], vget_low_s16(s[2]), vget_low_s16(s[2])); - sum_s32[0] = - vmlal_s16(sum_s32[0], vget_low_s16(s[3]), vget_low_s16(s[3])); - sum_s32[0] = - vmlal_s16(sum_s32[0], vget_low_s16(s[4]), vget_low_s16(s[4])); - sum_s32[0] = - vmlal_s16(sum_s32[0], vget_low_s16(s[5]), vget_low_s16(s[5])); - sum_s32[0] = - vmlal_s16(sum_s32[0], vget_low_s16(s[6]), vget_low_s16(s[6])); - sum_s32[0] = - vmlal_s16(sum_s32[0], vget_low_s16(s[7]), vget_low_s16(s[7])); - - sum_s32[1] = - vmlal_s16(sum_s32[1], vget_high_s16(s[0]), vget_high_s16(s[0])); - sum_s32[1] = - vmlal_s16(sum_s32[1], vget_high_s16(s[1]), vget_high_s16(s[1])); - sum_s32[1] = - vmlal_s16(sum_s32[1], vget_high_s16(s[2]), vget_high_s16(s[2])); - sum_s32[1] = - vmlal_s16(sum_s32[1], vget_high_s16(s[3]), vget_high_s16(s[3])); - sum_s32[1] = - vmlal_s16(sum_s32[1], vget_high_s16(s[4]), vget_high_s16(s[4])); - sum_s32[1] = - vmlal_s16(sum_s32[1], vget_high_s16(s[5]), vget_high_s16(s[5])); - sum_s32[1] = - vmlal_s16(sum_s32[1], vget_high_s16(s[6]), vget_high_s16(s[6])); - sum_s32[1] = - vmlal_s16(sum_s32[1], vget_high_s16(s[7]), vget_high_s16(s[7])); - - src_ptr += 8; - cols -= 8; - } while (cols); - - sum_u64 = vpadalq_u32(sum_u64, vreinterpretq_u32_s32(sum_s32[0])); - sum_u64 = vpadalq_u32(sum_u64, vreinterpretq_u32_s32(sum_s32[1])); - src += 8 * stride; - rows -= 8; - } while (rows); - - return horizontal_add_uint64x2(sum_u64); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sum_squares_sve.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sum_squares_sve.c deleted file mode 100644 index a18cbbd7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/sum_squares_sve.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2024 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" -#include "vpx_dsp/arm/vpx_neon_sve_bridge.h" - -uint64_t vpx_sum_squares_2d_i16_sve(const int16_t *src, int stride, int size) { - if (size == 4) { - int16x4_t s[4]; - int64x2_t sum = vdupq_n_s64(0); - - s[0] = vld1_s16(src + 0 * stride); - s[1] = vld1_s16(src + 1 * stride); - s[2] = vld1_s16(src + 2 * stride); - s[3] = vld1_s16(src + 3 * stride); - - int16x8_t s01 = vcombine_s16(s[0], s[1]); - int16x8_t s23 = vcombine_s16(s[2], s[3]); - - sum = vpx_dotq_s16(sum, s01, s01); - sum = vpx_dotq_s16(sum, s23, s23); - - return horizontal_add_uint64x2(vreinterpretq_u64_s64(sum)); - } else { - int rows = size; - int64x2_t sum[4] = { vdupq_n_s64(0), vdupq_n_s64(0), vdupq_n_s64(0), - vdupq_n_s64(0) }; - - do { - const int16_t *src_ptr = src; - int cols = size; - - do { - int16x8_t s[8]; - load_s16_8x8(src_ptr, stride, &s[0], &s[1], &s[2], &s[3], &s[4], &s[5], - &s[6], &s[7]); - - sum[0] = vpx_dotq_s16(sum[0], s[0], s[0]); - sum[1] = vpx_dotq_s16(sum[1], s[1], s[1]); - sum[2] = vpx_dotq_s16(sum[2], s[2], s[2]); - sum[3] = vpx_dotq_s16(sum[3], s[3], s[3]); - sum[0] = vpx_dotq_s16(sum[0], s[4], s[4]); - sum[1] = vpx_dotq_s16(sum[1], s[5], s[5]); - sum[2] = vpx_dotq_s16(sum[2], s[6], s[6]); - sum[3] = vpx_dotq_s16(sum[3], s[7], s[7]); - - src_ptr += 8; - cols -= 8; - } while (cols); - - src += 8 * stride; - rows -= 8; - } while (rows); - - sum[0] = vaddq_s64(sum[0], sum[1]); - sum[2] = vaddq_s64(sum[2], sum[3]); - sum[0] = vaddq_s64(sum[0], sum[2]); - - return horizontal_add_uint64x2(vreinterpretq_u64_s64(sum[0])); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/transpose_neon.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/transpose_neon.h deleted file mode 100644 index c989a672..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/transpose_neon.h +++ /dev/null @@ -1,1552 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_ARM_TRANSPOSE_NEON_H_ -#define VPX_VPX_DSP_ARM_TRANSPOSE_NEON_H_ - -#include - -#include "./vpx_config.h" - -// Transpose 64 bit elements as follows: -// a0: 00 01 02 03 04 05 06 07 -// a1: 16 17 18 19 20 21 22 23 -// -// b0.val[0]: 00 01 02 03 16 17 18 19 -// b0.val[1]: 04 05 06 07 20 21 22 23 -static INLINE int16x8x2_t vpx_vtrnq_s64_to_s16(int32x4_t a0, int32x4_t a1) { - int16x8x2_t b0; -#if VPX_ARCH_AARCH64 - b0.val[0] = vreinterpretq_s16_s64( - vtrn1q_s64(vreinterpretq_s64_s32(a0), vreinterpretq_s64_s32(a1))); - b0.val[1] = vreinterpretq_s16_s64( - vtrn2q_s64(vreinterpretq_s64_s32(a0), vreinterpretq_s64_s32(a1))); -#else - b0.val[0] = vcombine_s16(vreinterpret_s16_s32(vget_low_s32(a0)), - vreinterpret_s16_s32(vget_low_s32(a1))); - b0.val[1] = vcombine_s16(vreinterpret_s16_s32(vget_high_s32(a0)), - vreinterpret_s16_s32(vget_high_s32(a1))); -#endif - return b0; -} - -static INLINE int32x4x2_t vpx_vtrnq_s64_to_s32(int32x4_t a0, int32x4_t a1) { - int32x4x2_t b0; -#if VPX_ARCH_AARCH64 - b0.val[0] = vreinterpretq_s32_s64( - vtrn1q_s64(vreinterpretq_s64_s32(a0), vreinterpretq_s64_s32(a1))); - b0.val[1] = vreinterpretq_s32_s64( - vtrn2q_s64(vreinterpretq_s64_s32(a0), vreinterpretq_s64_s32(a1))); -#else - b0.val[0] = vcombine_s32(vget_low_s32(a0), vget_low_s32(a1)); - b0.val[1] = vcombine_s32(vget_high_s32(a0), vget_high_s32(a1)); -#endif - return b0; -} - -static INLINE int64x2x2_t vpx_vtrnq_s64(int32x4_t a0, int32x4_t a1) { - int64x2x2_t b0; -#if VPX_ARCH_AARCH64 - b0.val[0] = vtrn1q_s64(vreinterpretq_s64_s32(a0), vreinterpretq_s64_s32(a1)); - b0.val[1] = vtrn2q_s64(vreinterpretq_s64_s32(a0), vreinterpretq_s64_s32(a1)); -#else - b0.val[0] = vcombine_s64(vreinterpret_s64_s32(vget_low_s32(a0)), - vreinterpret_s64_s32(vget_low_s32(a1))); - b0.val[1] = vcombine_s64(vreinterpret_s64_s32(vget_high_s32(a0)), - vreinterpret_s64_s32(vget_high_s32(a1))); -#endif - return b0; -} - -static INLINE uint8x16x2_t vpx_vtrnq_u64_to_u8(uint32x4_t a0, uint32x4_t a1) { - uint8x16x2_t b0; -#if VPX_ARCH_AARCH64 - b0.val[0] = vreinterpretq_u8_u64( - vtrn1q_u64(vreinterpretq_u64_u32(a0), vreinterpretq_u64_u32(a1))); - b0.val[1] = vreinterpretq_u8_u64( - vtrn2q_u64(vreinterpretq_u64_u32(a0), vreinterpretq_u64_u32(a1))); -#else - b0.val[0] = vcombine_u8(vreinterpret_u8_u32(vget_low_u32(a0)), - vreinterpret_u8_u32(vget_low_u32(a1))); - b0.val[1] = vcombine_u8(vreinterpret_u8_u32(vget_high_u32(a0)), - vreinterpret_u8_u32(vget_high_u32(a1))); -#endif - return b0; -} - -static INLINE uint16x8x2_t vpx_vtrnq_u64_to_u16(uint32x4_t a0, uint32x4_t a1) { - uint16x8x2_t b0; -#if VPX_ARCH_AARCH64 - b0.val[0] = vreinterpretq_u16_u64( - vtrn1q_u64(vreinterpretq_u64_u32(a0), vreinterpretq_u64_u32(a1))); - b0.val[1] = vreinterpretq_u16_u64( - vtrn2q_u64(vreinterpretq_u64_u32(a0), vreinterpretq_u64_u32(a1))); -#else - b0.val[0] = vcombine_u16(vreinterpret_u16_u32(vget_low_u32(a0)), - vreinterpret_u16_u32(vget_low_u32(a1))); - b0.val[1] = vcombine_u16(vreinterpret_u16_u32(vget_high_u32(a0)), - vreinterpret_u16_u32(vget_high_u32(a1))); -#endif - return b0; -} - -static INLINE void transpose_u8_4x4(uint8x8_t *a0, uint8x8_t *a1) { - // Swap 16 bit elements. Goes from: - // a0: 00 01 02 03 10 11 12 13 - // a1: 20 21 22 23 30 31 32 33 - // to: - // b0.val[0]: 00 01 20 21 10 11 30 31 - // b0.val[1]: 02 03 22 23 12 13 32 33 - - const uint16x4x2_t b0 = - vtrn_u16(vreinterpret_u16_u8(*a0), vreinterpret_u16_u8(*a1)); - - // Swap 32 bit elements resulting in: - // c0.val[0]: 00 01 20 21 02 03 22 23 - // c0.val[1]: 10 11 30 31 12 13 32 33 - - const uint32x2x2_t c0 = vtrn_u32(vreinterpret_u32_u16(b0.val[0]), - vreinterpret_u32_u16(b0.val[1])); - - // Swap 8 bit elements resulting in: - // d0.val[0]: 00 10 20 30 02 12 22 32 - // d0.val[1]: 01 11 21 31 03 13 23 33 - - const uint8x8x2_t d0 = - vtrn_u8(vreinterpret_u8_u32(c0.val[0]), vreinterpret_u8_u32(c0.val[1])); - - *a0 = d0.val[0]; - *a1 = d0.val[1]; -} - -static INLINE void transpose_s16_4x4d(int16x4_t *a0, int16x4_t *a1, - int16x4_t *a2, int16x4_t *a3) { - // Swap 16 bit elements. Goes from: - // a0: 00 01 02 03 - // a1: 10 11 12 13 - // a2: 20 21 22 23 - // a3: 30 31 32 33 - // to: - // b0.val[0]: 00 10 02 12 - // b0.val[1]: 01 11 03 13 - // b1.val[0]: 20 30 22 32 - // b1.val[1]: 21 31 23 33 - - const int16x4x2_t b0 = vtrn_s16(*a0, *a1); - const int16x4x2_t b1 = vtrn_s16(*a2, *a3); - - // Swap 32 bit elements resulting in: - // c0.val[0]: 00 10 20 30 - // c0.val[1]: 02 12 22 32 - // c1.val[0]: 01 11 21 31 - // c1.val[1]: 03 13 23 33 - - const int32x2x2_t c0 = vtrn_s32(vreinterpret_s32_s16(b0.val[0]), - vreinterpret_s32_s16(b1.val[0])); - const int32x2x2_t c1 = vtrn_s32(vreinterpret_s32_s16(b0.val[1]), - vreinterpret_s32_s16(b1.val[1])); - - *a0 = vreinterpret_s16_s32(c0.val[0]); - *a1 = vreinterpret_s16_s32(c1.val[0]); - *a2 = vreinterpret_s16_s32(c0.val[1]); - *a3 = vreinterpret_s16_s32(c1.val[1]); -} - -static INLINE void transpose_s16_4x4q(int16x8_t *a0, int16x8_t *a1) { - // Swap 32 bit elements. Goes from: - // a0: 00 01 02 03 10 11 12 13 - // a1: 20 21 22 23 30 31 32 33 - // to: - // b0.val[0]: 00 01 20 21 10 11 30 31 - // b0.val[1]: 02 03 22 23 12 13 32 33 - - const int32x4x2_t b0 = - vtrnq_s32(vreinterpretq_s32_s16(*a0), vreinterpretq_s32_s16(*a1)); - - // Swap 64 bit elements resulting in: - // c0: 00 01 20 21 02 03 22 23 - // c1: 10 11 30 31 12 13 32 33 - - const int16x8x2_t c0 = vpx_vtrnq_s64_to_s16(b0.val[0], b0.val[1]); - - // Swap 16 bit elements resulting in: - // d0.val[0]: 00 10 20 30 02 12 22 32 - // d0.val[1]: 01 11 21 31 03 13 23 33 - - const int16x8x2_t d0 = vtrnq_s16(c0.val[0], c0.val[1]); - - *a0 = d0.val[0]; - *a1 = d0.val[1]; -} - -static INLINE void transpose_u16_4x4q(uint16x8_t *a0, uint16x8_t *a1) { - // Swap 32 bit elements. Goes from: - // a0: 00 01 02 03 10 11 12 13 - // a1: 20 21 22 23 30 31 32 33 - // to: - // b0.val[0]: 00 01 20 21 10 11 30 31 - // b0.val[1]: 02 03 22 23 12 13 32 33 - - const uint32x4x2_t b0 = - vtrnq_u32(vreinterpretq_u32_u16(*a0), vreinterpretq_u32_u16(*a1)); - - // Swap 64 bit elements resulting in: - // c0: 00 01 20 21 02 03 22 23 - // c1: 10 11 30 31 12 13 32 33 - - const uint16x8x2_t c0 = vpx_vtrnq_u64_to_u16(b0.val[0], b0.val[1]); - - // Swap 16 bit elements resulting in: - // d0.val[0]: 00 10 20 30 02 12 22 32 - // d0.val[1]: 01 11 21 31 03 13 23 33 - - const uint16x8x2_t d0 = vtrnq_u16(c0.val[0], c0.val[1]); - - *a0 = d0.val[0]; - *a1 = d0.val[1]; -} - -static INLINE void transpose_u8_4x8(uint8x8_t *a0, uint8x8_t *a1, uint8x8_t *a2, - uint8x8_t *a3, const uint8x8_t a4, - const uint8x8_t a5, const uint8x8_t a6, - const uint8x8_t a7) { - // Swap 32 bit elements. Goes from: - // a0: 00 01 02 03 XX XX XX XX - // a1: 10 11 12 13 XX XX XX XX - // a2: 20 21 22 23 XX XX XX XX - // a3; 30 31 32 33 XX XX XX XX - // a4: 40 41 42 43 XX XX XX XX - // a5: 50 51 52 53 XX XX XX XX - // a6: 60 61 62 63 XX XX XX XX - // a7: 70 71 72 73 XX XX XX XX - // to: - // b0.val[0]: 00 01 02 03 40 41 42 43 - // b1.val[0]: 10 11 12 13 50 51 52 53 - // b2.val[0]: 20 21 22 23 60 61 62 63 - // b3.val[0]: 30 31 32 33 70 71 72 73 - - const uint32x2x2_t b0 = - vtrn_u32(vreinterpret_u32_u8(*a0), vreinterpret_u32_u8(a4)); - const uint32x2x2_t b1 = - vtrn_u32(vreinterpret_u32_u8(*a1), vreinterpret_u32_u8(a5)); - const uint32x2x2_t b2 = - vtrn_u32(vreinterpret_u32_u8(*a2), vreinterpret_u32_u8(a6)); - const uint32x2x2_t b3 = - vtrn_u32(vreinterpret_u32_u8(*a3), vreinterpret_u32_u8(a7)); - - // Swap 16 bit elements resulting in: - // c0.val[0]: 00 01 20 21 40 41 60 61 - // c0.val[1]: 02 03 22 23 42 43 62 63 - // c1.val[0]: 10 11 30 31 50 51 70 71 - // c1.val[1]: 12 13 32 33 52 53 72 73 - - const uint16x4x2_t c0 = vtrn_u16(vreinterpret_u16_u32(b0.val[0]), - vreinterpret_u16_u32(b2.val[0])); - const uint16x4x2_t c1 = vtrn_u16(vreinterpret_u16_u32(b1.val[0]), - vreinterpret_u16_u32(b3.val[0])); - - // Swap 8 bit elements resulting in: - // d0.val[0]: 00 10 20 30 40 50 60 70 - // d0.val[1]: 01 11 21 31 41 51 61 71 - // d1.val[0]: 02 12 22 32 42 52 62 72 - // d1.val[1]: 03 13 23 33 43 53 63 73 - - const uint8x8x2_t d0 = - vtrn_u8(vreinterpret_u8_u16(c0.val[0]), vreinterpret_u8_u16(c1.val[0])); - const uint8x8x2_t d1 = - vtrn_u8(vreinterpret_u8_u16(c0.val[1]), vreinterpret_u8_u16(c1.val[1])); - - *a0 = d0.val[0]; - *a1 = d0.val[1]; - *a2 = d1.val[0]; - *a3 = d1.val[1]; -} - -static INLINE void transpose_s32_4x4(int32x4_t *a0, int32x4_t *a1, - int32x4_t *a2, int32x4_t *a3) { - // Swap 32 bit elements. Goes from: - // a0: 00 01 02 03 - // a1: 10 11 12 13 - // a2: 20 21 22 23 - // a3: 30 31 32 33 - // to: - // b0.val[0]: 00 10 02 12 - // b0.val[1]: 01 11 03 13 - // b1.val[0]: 20 30 22 32 - // b1.val[1]: 21 31 23 33 - - const int32x4x2_t b0 = vtrnq_s32(*a0, *a1); - const int32x4x2_t b1 = vtrnq_s32(*a2, *a3); - - // Swap 64 bit elements resulting in: - // c0.val[0]: 00 10 20 30 - // c0.val[1]: 02 12 22 32 - // c1.val[0]: 01 11 21 31 - // c1.val[1]: 03 13 23 33 - - const int32x4x2_t c0 = vpx_vtrnq_s64_to_s32(b0.val[0], b1.val[0]); - const int32x4x2_t c1 = vpx_vtrnq_s64_to_s32(b0.val[1], b1.val[1]); - - *a0 = c0.val[0]; - *a1 = c1.val[0]; - *a2 = c0.val[1]; - *a3 = c1.val[1]; -} - -static INLINE void transpose_s16_4x8(const int16x4_t a0, const int16x4_t a1, - const int16x4_t a2, const int16x4_t a3, - const int16x4_t a4, const int16x4_t a5, - const int16x4_t a6, const int16x4_t a7, - int16x8_t *const o0, int16x8_t *const o1, - int16x8_t *const o2, int16x8_t *const o3) { - // Combine rows. Goes from: - // a0: 00 01 02 03 - // a1: 10 11 12 13 - // a2: 20 21 22 23 - // a3: 30 31 32 33 - // a4: 40 41 42 43 - // a5: 50 51 52 53 - // a6: 60 61 62 63 - // a7: 70 71 72 73 - // to: - // b0: 00 01 02 03 40 41 42 43 - // b1: 10 11 12 13 50 51 52 53 - // b2: 20 21 22 23 60 61 62 63 - // b3: 30 31 32 33 70 71 72 73 - - const int16x8_t b0 = vcombine_s16(a0, a4); - const int16x8_t b1 = vcombine_s16(a1, a5); - const int16x8_t b2 = vcombine_s16(a2, a6); - const int16x8_t b3 = vcombine_s16(a3, a7); - - // Swap 16 bit elements resulting in: - // c0.val[0]: 00 10 02 12 40 50 42 52 - // c0.val[1]: 01 11 03 13 41 51 43 53 - // c1.val[0]: 20 30 22 32 60 70 62 72 - // c1.val[1]: 21 31 23 33 61 71 63 73 - - const int16x8x2_t c0 = vtrnq_s16(b0, b1); - const int16x8x2_t c1 = vtrnq_s16(b2, b3); - - // Swap 32 bit elements resulting in: - // d0.val[0]: 00 10 20 30 40 50 60 70 - // d0.val[1]: 02 12 22 32 42 52 62 72 - // d1.val[0]: 01 11 21 31 41 51 61 71 - // d1.val[1]: 03 13 23 33 43 53 63 73 - - const int32x4x2_t d0 = vtrnq_s32(vreinterpretq_s32_s16(c0.val[0]), - vreinterpretq_s32_s16(c1.val[0])); - const int32x4x2_t d1 = vtrnq_s32(vreinterpretq_s32_s16(c0.val[1]), - vreinterpretq_s32_s16(c1.val[1])); - - *o0 = vreinterpretq_s16_s32(d0.val[0]); - *o1 = vreinterpretq_s16_s32(d1.val[0]); - *o2 = vreinterpretq_s16_s32(d0.val[1]); - *o3 = vreinterpretq_s16_s32(d1.val[1]); -} - -static INLINE void transpose_s32_4x8(int32x4_t *const a0, int32x4_t *const a1, - int32x4_t *const a2, int32x4_t *const a3, - int32x4_t *const a4, int32x4_t *const a5, - int32x4_t *const a6, int32x4_t *const a7) { - // Swap 32 bit elements. Goes from: - // a0: 00 01 02 03 - // a1: 10 11 12 13 - // a2: 20 21 22 23 - // a3: 30 31 32 33 - // a4: 40 41 42 43 - // a5: 50 51 52 53 - // a6: 60 61 62 63 - // a7: 70 71 72 73 - // to: - // b0.val[0]: 00 10 02 12 - // b0.val[1]: 01 11 03 13 - // b1.val[0]: 20 30 22 32 - // b1.val[1]: 21 31 23 33 - // b2.val[0]: 40 50 42 52 - // b2.val[1]: 41 51 43 53 - // b3.val[0]: 60 70 62 72 - // b3.val[1]: 61 71 63 73 - - const int32x4x2_t b0 = vtrnq_s32(*a0, *a1); - const int32x4x2_t b1 = vtrnq_s32(*a2, *a3); - const int32x4x2_t b2 = vtrnq_s32(*a4, *a5); - const int32x4x2_t b3 = vtrnq_s32(*a6, *a7); - - // Swap 64 bit elements resulting in: - // c0.val[0]: 00 10 20 30 - // c0.val[1]: 02 12 22 32 - // c1.val[0]: 01 11 21 31 - // c1.val[1]: 03 13 23 33 - // c2.val[0]: 40 50 60 70 - // c2.val[1]: 42 52 62 72 - // c3.val[0]: 41 51 61 71 - // c3.val[1]: 43 53 63 73 - - const int64x2x2_t c0 = vpx_vtrnq_s64(b0.val[0], b1.val[0]); - const int64x2x2_t c1 = vpx_vtrnq_s64(b0.val[1], b1.val[1]); - const int64x2x2_t c2 = vpx_vtrnq_s64(b2.val[0], b3.val[0]); - const int64x2x2_t c3 = vpx_vtrnq_s64(b2.val[1], b3.val[1]); - - *a0 = vreinterpretq_s32_s64(c0.val[0]); - *a1 = vreinterpretq_s32_s64(c2.val[0]); - *a2 = vreinterpretq_s32_s64(c1.val[0]); - *a3 = vreinterpretq_s32_s64(c3.val[0]); - *a4 = vreinterpretq_s32_s64(c0.val[1]); - *a5 = vreinterpretq_s32_s64(c2.val[1]); - *a6 = vreinterpretq_s32_s64(c1.val[1]); - *a7 = vreinterpretq_s32_s64(c3.val[1]); -} - -static INLINE void transpose_u8_8x4(uint8x8_t *a0, uint8x8_t *a1, uint8x8_t *a2, - uint8x8_t *a3) { - // Swap 8 bit elements. Goes from: - // a0: 00 01 02 03 04 05 06 07 - // a1: 10 11 12 13 14 15 16 17 - // a2: 20 21 22 23 24 25 26 27 - // a3: 30 31 32 33 34 35 36 37 - // to: - // b0.val[0]: 00 10 02 12 04 14 06 16 - // b0.val[1]: 01 11 03 13 05 15 07 17 - // b1.val[0]: 20 30 22 32 24 34 26 36 - // b1.val[1]: 21 31 23 33 25 35 27 37 - - const uint8x8x2_t b0 = vtrn_u8(*a0, *a1); - const uint8x8x2_t b1 = vtrn_u8(*a2, *a3); - - // Swap 16 bit elements resulting in: - // c0.val[0]: 00 10 20 30 04 14 24 34 - // c0.val[1]: 02 12 22 32 06 16 26 36 - // c1.val[0]: 01 11 21 31 05 15 25 35 - // c1.val[1]: 03 13 23 33 07 17 27 37 - - const uint16x4x2_t c0 = - vtrn_u16(vreinterpret_u16_u8(b0.val[0]), vreinterpret_u16_u8(b1.val[0])); - const uint16x4x2_t c1 = - vtrn_u16(vreinterpret_u16_u8(b0.val[1]), vreinterpret_u16_u8(b1.val[1])); - - *a0 = vreinterpret_u8_u16(c0.val[0]); - *a1 = vreinterpret_u8_u16(c1.val[0]); - *a2 = vreinterpret_u8_u16(c0.val[1]); - *a3 = vreinterpret_u8_u16(c1.val[1]); -} - -static INLINE void transpose_u16_8x4(uint16x8_t *a0, uint16x8_t *a1, - uint16x8_t *a2, uint16x8_t *a3) { - // Swap 16 bit elements. Goes from: - // a0: 00 01 02 03 04 05 06 07 - // a1: 10 11 12 13 14 15 16 17 - // a2: 20 21 22 23 24 25 26 27 - // a3: 30 31 32 33 34 35 36 37 - // to: - // b0.val[0]: 00 10 02 12 04 14 06 16 - // b0.val[1]: 01 11 03 13 05 15 07 17 - // b1.val[0]: 20 30 22 32 24 34 26 36 - // b1.val[1]: 21 31 23 33 25 35 27 37 - - const uint16x8x2_t b0 = vtrnq_u16(*a0, *a1); - const uint16x8x2_t b1 = vtrnq_u16(*a2, *a3); - - // Swap 32 bit elements resulting in: - // c0.val[0]: 00 10 20 30 04 14 24 34 - // c0.val[1]: 02 12 22 32 06 16 26 36 - // c1.val[0]: 01 11 21 31 05 15 25 35 - // c1.val[1]: 03 13 23 33 07 17 27 37 - - const uint32x4x2_t c0 = vtrnq_u32(vreinterpretq_u32_u16(b0.val[0]), - vreinterpretq_u32_u16(b1.val[0])); - const uint32x4x2_t c1 = vtrnq_u32(vreinterpretq_u32_u16(b0.val[1]), - vreinterpretq_u32_u16(b1.val[1])); - - *a0 = vreinterpretq_u16_u32(c0.val[0]); - *a1 = vreinterpretq_u16_u32(c1.val[0]); - *a2 = vreinterpretq_u16_u32(c0.val[1]); - *a3 = vreinterpretq_u16_u32(c1.val[1]); -} - -static INLINE void transpose_s32_8x4(int32x4_t *const a0, int32x4_t *const a1, - int32x4_t *const a2, int32x4_t *const a3, - int32x4_t *const a4, int32x4_t *const a5, - int32x4_t *const a6, int32x4_t *const a7) { - // Swap 32 bit elements. Goes from: - // a0: 00 01 02 03 - // a1: 04 05 06 07 - // a2: 10 11 12 13 - // a3: 14 15 16 17 - // a4: 20 21 22 23 - // a5: 24 25 26 27 - // a6: 30 31 32 33 - // a7: 34 35 36 37 - // to: - // b0.val[0]: 00 10 02 12 - // b0.val[1]: 01 11 03 13 - // b1.val[0]: 04 14 06 16 - // b1.val[1]: 05 15 07 17 - // b2.val[0]: 20 30 22 32 - // b2.val[1]: 21 31 23 33 - // b3.val[0]: 24 34 26 36 - // b3.val[1]: 25 35 27 37 - - const int32x4x2_t b0 = vtrnq_s32(*a0, *a2); - const int32x4x2_t b1 = vtrnq_s32(*a1, *a3); - const int32x4x2_t b2 = vtrnq_s32(*a4, *a6); - const int32x4x2_t b3 = vtrnq_s32(*a5, *a7); - - // Swap 64 bit elements resulting in: - // c0.val[0]: 00 10 20 30 - // c0.val[1]: 02 12 22 32 - // c1.val[0]: 01 11 21 31 - // c1.val[1]: 03 13 23 33 - // c2.val[0]: 04 14 24 34 - // c2.val[1]: 06 16 26 36 - // c3.val[0]: 05 15 25 35 - // c3.val[1]: 07 17 27 37 - - const int64x2x2_t c0 = vpx_vtrnq_s64(b0.val[0], b2.val[0]); - const int64x2x2_t c1 = vpx_vtrnq_s64(b0.val[1], b2.val[1]); - const int64x2x2_t c2 = vpx_vtrnq_s64(b1.val[0], b3.val[0]); - const int64x2x2_t c3 = vpx_vtrnq_s64(b1.val[1], b3.val[1]); - - *a0 = vreinterpretq_s32_s64(c0.val[0]); - *a1 = vreinterpretq_s32_s64(c1.val[0]); - *a2 = vreinterpretq_s32_s64(c0.val[1]); - *a3 = vreinterpretq_s32_s64(c1.val[1]); - *a4 = vreinterpretq_s32_s64(c2.val[0]); - *a5 = vreinterpretq_s32_s64(c3.val[0]); - *a6 = vreinterpretq_s32_s64(c2.val[1]); - *a7 = vreinterpretq_s32_s64(c3.val[1]); -} - -static INLINE void transpose_u8_8x8(uint8x8_t *a0, uint8x8_t *a1, uint8x8_t *a2, - uint8x8_t *a3, uint8x8_t *a4, uint8x8_t *a5, - uint8x8_t *a6, uint8x8_t *a7) { - // Widen to 128-bit registers (usually a no-op once inlined.) - const uint8x16_t a0q = vcombine_u8(*a0, vdup_n_u8(0)); - const uint8x16_t a1q = vcombine_u8(*a1, vdup_n_u8(0)); - const uint8x16_t a2q = vcombine_u8(*a2, vdup_n_u8(0)); - const uint8x16_t a3q = vcombine_u8(*a3, vdup_n_u8(0)); - const uint8x16_t a4q = vcombine_u8(*a4, vdup_n_u8(0)); - const uint8x16_t a5q = vcombine_u8(*a5, vdup_n_u8(0)); - const uint8x16_t a6q = vcombine_u8(*a6, vdup_n_u8(0)); - const uint8x16_t a7q = vcombine_u8(*a7, vdup_n_u8(0)); - - // Zip 8 bit elements. Goes from: - // a0: 00 01 02 03 04 05 06 07 - // a1: 10 11 12 13 14 15 16 17 - // a2: 20 21 22 23 24 25 26 27 - // a3: 30 31 32 33 34 35 36 37 - // a4: 40 41 42 43 44 45 46 47 - // a5: 50 51 52 53 54 55 56 57 - // a6: 60 61 62 63 64 65 66 67 - // a7: 70 71 72 73 74 75 76 77 - // to: - // b0: 00 10 01 11 02 12 03 13 04 14 05 15 06 16 07 17 - // b1: 20 30 21 31 22 32 23 33 24 34 25 35 26 36 27 37 - // b2: 40 50 41 51 42 52 43 53 44 54 45 55 46 56 47 57 - // b3: 60 70 61 71 62 72 63 73 64 74 65 75 66 76 67 77 - const uint8x16_t b0 = vzipq_u8(a0q, a1q).val[0]; - const uint8x16_t b1 = vzipq_u8(a2q, a3q).val[0]; - const uint8x16_t b2 = vzipq_u8(a4q, a5q).val[0]; - const uint8x16_t b3 = vzipq_u8(a6q, a7q).val[0]; - - // Zip 16 bit elements resulting in: - // c0.val[0]: 00 10 20 30 01 11 21 31 02 12 22 32 03 13 23 33 - // c0.val[1]: 04 14 24 34 05 15 25 35 06 16 26 36 07 17 27 37 - // c1.val[0]: 40 50 60 70 41 51 61 71 42 52 62 72 43 53 63 73 - // c1.val[1]: 44 54 64 74 45 55 65 75 46 66 56 76 47 67 57 77 - const uint16x8x2_t c0 = - vzipq_u16(vreinterpretq_u16_u8(b0), vreinterpretq_u16_u8(b1)); - const uint16x8x2_t c1 = - vzipq_u16(vreinterpretq_u16_u8(b2), vreinterpretq_u16_u8(b3)); - - // Zip 32 bit elements resulting in: - // d0.val[0]: 00 10 20 30 40 50 60 70 01 11 21 31 41 51 61 71 - // d0.val[1]: 02 12 22 32 42 52 62 72 03 13 23 33 43 53 63 73 - // d1.val[0]: 04 14 24 34 44 54 64 74 05 15 25 35 45 55 65 75 - // d1.val[1]: 06 16 26 36 46 56 66 76 07 17 27 37 47 57 67 77 - const uint32x4x2_t d0 = vzipq_u32(vreinterpretq_u32_u16(c0.val[0]), - vreinterpretq_u32_u16(c1.val[0])); - const uint32x4x2_t d1 = vzipq_u32(vreinterpretq_u32_u16(c0.val[1]), - vreinterpretq_u32_u16(c1.val[1])); - - *a0 = vreinterpret_u8_u32(vget_low_u32(d0.val[0])); - *a1 = vreinterpret_u8_u32(vget_high_u32(d0.val[0])); - *a2 = vreinterpret_u8_u32(vget_low_u32(d0.val[1])); - *a3 = vreinterpret_u8_u32(vget_high_u32(d0.val[1])); - *a4 = vreinterpret_u8_u32(vget_low_u32(d1.val[0])); - *a5 = vreinterpret_u8_u32(vget_high_u32(d1.val[0])); - *a6 = vreinterpret_u8_u32(vget_low_u32(d1.val[1])); - *a7 = vreinterpret_u8_u32(vget_high_u32(d1.val[1])); -} - -// Transpose 8x8 to a new location. -static INLINE void transpose_s16_8x8q(int16x8_t *a, int16x8_t *out) { - // Swap 16 bit elements. Goes from: - // a0: 00 01 02 03 04 05 06 07 - // a1: 10 11 12 13 14 15 16 17 - // a2: 20 21 22 23 24 25 26 27 - // a3: 30 31 32 33 34 35 36 37 - // a4: 40 41 42 43 44 45 46 47 - // a5: 50 51 52 53 54 55 56 57 - // a6: 60 61 62 63 64 65 66 67 - // a7: 70 71 72 73 74 75 76 77 - // to: - // b0.val[0]: 00 10 02 12 04 14 06 16 - // b0.val[1]: 01 11 03 13 05 15 07 17 - // b1.val[0]: 20 30 22 32 24 34 26 36 - // b1.val[1]: 21 31 23 33 25 35 27 37 - // b2.val[0]: 40 50 42 52 44 54 46 56 - // b2.val[1]: 41 51 43 53 45 55 47 57 - // b3.val[0]: 60 70 62 72 64 74 66 76 - // b3.val[1]: 61 71 63 73 65 75 67 77 - - const int16x8x2_t b0 = vtrnq_s16(a[0], a[1]); - const int16x8x2_t b1 = vtrnq_s16(a[2], a[3]); - const int16x8x2_t b2 = vtrnq_s16(a[4], a[5]); - const int16x8x2_t b3 = vtrnq_s16(a[6], a[7]); - - // Swap 32 bit elements resulting in: - // c0.val[0]: 00 10 20 30 04 14 24 34 - // c0.val[1]: 02 12 22 32 06 16 26 36 - // c1.val[0]: 01 11 21 31 05 15 25 35 - // c1.val[1]: 03 13 23 33 07 17 27 37 - // c2.val[0]: 40 50 60 70 44 54 64 74 - // c2.val[1]: 42 52 62 72 46 56 66 76 - // c3.val[0]: 41 51 61 71 45 55 65 75 - // c3.val[1]: 43 53 63 73 47 57 67 77 - - const int32x4x2_t c0 = vtrnq_s32(vreinterpretq_s32_s16(b0.val[0]), - vreinterpretq_s32_s16(b1.val[0])); - const int32x4x2_t c1 = vtrnq_s32(vreinterpretq_s32_s16(b0.val[1]), - vreinterpretq_s32_s16(b1.val[1])); - const int32x4x2_t c2 = vtrnq_s32(vreinterpretq_s32_s16(b2.val[0]), - vreinterpretq_s32_s16(b3.val[0])); - const int32x4x2_t c3 = vtrnq_s32(vreinterpretq_s32_s16(b2.val[1]), - vreinterpretq_s32_s16(b3.val[1])); - - // Swap 64 bit elements resulting in: - // d0.val[0]: 00 10 20 30 40 50 60 70 - // d0.val[1]: 04 14 24 34 44 54 64 74 - // d1.val[0]: 01 11 21 31 41 51 61 71 - // d1.val[1]: 05 15 25 35 45 55 65 75 - // d2.val[0]: 02 12 22 32 42 52 62 72 - // d2.val[1]: 06 16 26 36 46 56 66 76 - // d3.val[0]: 03 13 23 33 43 53 63 73 - // d3.val[1]: 07 17 27 37 47 57 67 77 - - const int16x8x2_t d0 = vpx_vtrnq_s64_to_s16(c0.val[0], c2.val[0]); - const int16x8x2_t d1 = vpx_vtrnq_s64_to_s16(c1.val[0], c3.val[0]); - const int16x8x2_t d2 = vpx_vtrnq_s64_to_s16(c0.val[1], c2.val[1]); - const int16x8x2_t d3 = vpx_vtrnq_s64_to_s16(c1.val[1], c3.val[1]); - - out[0] = d0.val[0]; - out[1] = d1.val[0]; - out[2] = d2.val[0]; - out[3] = d3.val[0]; - out[4] = d0.val[1]; - out[5] = d1.val[1]; - out[6] = d2.val[1]; - out[7] = d3.val[1]; -} - -static INLINE void transpose_s16_8x8(int16x8_t *a0, int16x8_t *a1, - int16x8_t *a2, int16x8_t *a3, - int16x8_t *a4, int16x8_t *a5, - int16x8_t *a6, int16x8_t *a7) { - // Swap 16 bit elements. Goes from: - // a0: 00 01 02 03 04 05 06 07 - // a1: 10 11 12 13 14 15 16 17 - // a2: 20 21 22 23 24 25 26 27 - // a3: 30 31 32 33 34 35 36 37 - // a4: 40 41 42 43 44 45 46 47 - // a5: 50 51 52 53 54 55 56 57 - // a6: 60 61 62 63 64 65 66 67 - // a7: 70 71 72 73 74 75 76 77 - // to: - // b0.val[0]: 00 10 02 12 04 14 06 16 - // b0.val[1]: 01 11 03 13 05 15 07 17 - // b1.val[0]: 20 30 22 32 24 34 26 36 - // b1.val[1]: 21 31 23 33 25 35 27 37 - // b2.val[0]: 40 50 42 52 44 54 46 56 - // b2.val[1]: 41 51 43 53 45 55 47 57 - // b3.val[0]: 60 70 62 72 64 74 66 76 - // b3.val[1]: 61 71 63 73 65 75 67 77 - - const int16x8x2_t b0 = vtrnq_s16(*a0, *a1); - const int16x8x2_t b1 = vtrnq_s16(*a2, *a3); - const int16x8x2_t b2 = vtrnq_s16(*a4, *a5); - const int16x8x2_t b3 = vtrnq_s16(*a6, *a7); - - // Swap 32 bit elements resulting in: - // c0.val[0]: 00 10 20 30 04 14 24 34 - // c0.val[1]: 02 12 22 32 06 16 26 36 - // c1.val[0]: 01 11 21 31 05 15 25 35 - // c1.val[1]: 03 13 23 33 07 17 27 37 - // c2.val[0]: 40 50 60 70 44 54 64 74 - // c2.val[1]: 42 52 62 72 46 56 66 76 - // c3.val[0]: 41 51 61 71 45 55 65 75 - // c3.val[1]: 43 53 63 73 47 57 67 77 - - const int32x4x2_t c0 = vtrnq_s32(vreinterpretq_s32_s16(b0.val[0]), - vreinterpretq_s32_s16(b1.val[0])); - const int32x4x2_t c1 = vtrnq_s32(vreinterpretq_s32_s16(b0.val[1]), - vreinterpretq_s32_s16(b1.val[1])); - const int32x4x2_t c2 = vtrnq_s32(vreinterpretq_s32_s16(b2.val[0]), - vreinterpretq_s32_s16(b3.val[0])); - const int32x4x2_t c3 = vtrnq_s32(vreinterpretq_s32_s16(b2.val[1]), - vreinterpretq_s32_s16(b3.val[1])); - - // Swap 64 bit elements resulting in: - // d0.val[0]: 00 10 20 30 40 50 60 70 - // d0.val[1]: 04 14 24 34 44 54 64 74 - // d1.val[0]: 01 11 21 31 41 51 61 71 - // d1.val[1]: 05 15 25 35 45 55 65 75 - // d2.val[0]: 02 12 22 32 42 52 62 72 - // d2.val[1]: 06 16 26 36 46 56 66 76 - // d3.val[0]: 03 13 23 33 43 53 63 73 - // d3.val[1]: 07 17 27 37 47 57 67 77 - - const int16x8x2_t d0 = vpx_vtrnq_s64_to_s16(c0.val[0], c2.val[0]); - const int16x8x2_t d1 = vpx_vtrnq_s64_to_s16(c1.val[0], c3.val[0]); - const int16x8x2_t d2 = vpx_vtrnq_s64_to_s16(c0.val[1], c2.val[1]); - const int16x8x2_t d3 = vpx_vtrnq_s64_to_s16(c1.val[1], c3.val[1]); - - *a0 = d0.val[0]; - *a1 = d1.val[0]; - *a2 = d2.val[0]; - *a3 = d3.val[0]; - *a4 = d0.val[1]; - *a5 = d1.val[1]; - *a6 = d2.val[1]; - *a7 = d3.val[1]; -} - -static INLINE void transpose_u16_8x8(uint16x8_t *a0, uint16x8_t *a1, - uint16x8_t *a2, uint16x8_t *a3, - uint16x8_t *a4, uint16x8_t *a5, - uint16x8_t *a6, uint16x8_t *a7) { - // Swap 16 bit elements. Goes from: - // a0: 00 01 02 03 04 05 06 07 - // a1: 10 11 12 13 14 15 16 17 - // a2: 20 21 22 23 24 25 26 27 - // a3: 30 31 32 33 34 35 36 37 - // a4: 40 41 42 43 44 45 46 47 - // a5: 50 51 52 53 54 55 56 57 - // a6: 60 61 62 63 64 65 66 67 - // a7: 70 71 72 73 74 75 76 77 - // to: - // b0.val[0]: 00 10 02 12 04 14 06 16 - // b0.val[1]: 01 11 03 13 05 15 07 17 - // b1.val[0]: 20 30 22 32 24 34 26 36 - // b1.val[1]: 21 31 23 33 25 35 27 37 - // b2.val[0]: 40 50 42 52 44 54 46 56 - // b2.val[1]: 41 51 43 53 45 55 47 57 - // b3.val[0]: 60 70 62 72 64 74 66 76 - // b3.val[1]: 61 71 63 73 65 75 67 77 - - const uint16x8x2_t b0 = vtrnq_u16(*a0, *a1); - const uint16x8x2_t b1 = vtrnq_u16(*a2, *a3); - const uint16x8x2_t b2 = vtrnq_u16(*a4, *a5); - const uint16x8x2_t b3 = vtrnq_u16(*a6, *a7); - - // Swap 32 bit elements resulting in: - // c0.val[0]: 00 10 20 30 04 14 24 34 - // c0.val[1]: 02 12 22 32 06 16 26 36 - // c1.val[0]: 01 11 21 31 05 15 25 35 - // c1.val[1]: 03 13 23 33 07 17 27 37 - // c2.val[0]: 40 50 60 70 44 54 64 74 - // c2.val[1]: 42 52 62 72 46 56 66 76 - // c3.val[0]: 41 51 61 71 45 55 65 75 - // c3.val[1]: 43 53 63 73 47 57 67 77 - - const uint32x4x2_t c0 = vtrnq_u32(vreinterpretq_u32_u16(b0.val[0]), - vreinterpretq_u32_u16(b1.val[0])); - const uint32x4x2_t c1 = vtrnq_u32(vreinterpretq_u32_u16(b0.val[1]), - vreinterpretq_u32_u16(b1.val[1])); - const uint32x4x2_t c2 = vtrnq_u32(vreinterpretq_u32_u16(b2.val[0]), - vreinterpretq_u32_u16(b3.val[0])); - const uint32x4x2_t c3 = vtrnq_u32(vreinterpretq_u32_u16(b2.val[1]), - vreinterpretq_u32_u16(b3.val[1])); - - // Swap 64 bit elements resulting in: - // d0.val[0]: 00 10 20 30 40 50 60 70 - // d0.val[1]: 04 14 24 34 44 54 64 74 - // d1.val[0]: 01 11 21 31 41 51 61 71 - // d1.val[1]: 05 15 25 35 45 55 65 75 - // d2.val[0]: 02 12 22 32 42 52 62 72 - // d2.val[1]: 06 16 26 36 46 56 66 76 - // d3.val[0]: 03 13 23 33 43 53 63 73 - // d3.val[1]: 07 17 27 37 47 57 67 77 - - const uint16x8x2_t d0 = vpx_vtrnq_u64_to_u16(c0.val[0], c2.val[0]); - const uint16x8x2_t d1 = vpx_vtrnq_u64_to_u16(c1.val[0], c3.val[0]); - const uint16x8x2_t d2 = vpx_vtrnq_u64_to_u16(c0.val[1], c2.val[1]); - const uint16x8x2_t d3 = vpx_vtrnq_u64_to_u16(c1.val[1], c3.val[1]); - - *a0 = d0.val[0]; - *a1 = d1.val[0]; - *a2 = d2.val[0]; - *a3 = d3.val[0]; - *a4 = d0.val[1]; - *a5 = d1.val[1]; - *a6 = d2.val[1]; - *a7 = d3.val[1]; -} - -static INLINE void transpose_s32_8x8(int32x4x2_t *a0, int32x4x2_t *a1, - int32x4x2_t *a2, int32x4x2_t *a3, - int32x4x2_t *a4, int32x4x2_t *a5, - int32x4x2_t *a6, int32x4x2_t *a7) { - // Swap 32 bit elements. Goes from: - // a0: 00 01 02 03 04 05 06 07 - // a1: 10 11 12 13 14 15 16 17 - // a2: 20 21 22 23 24 25 26 27 - // a3: 30 31 32 33 34 35 36 37 - // a4: 40 41 42 43 44 45 46 47 - // a5: 50 51 52 53 54 55 56 57 - // a6: 60 61 62 63 64 65 66 67 - // a7: 70 71 72 73 74 75 76 77 - // to: - // b0: 00 10 02 12 01 11 03 13 - // b1: 20 30 22 32 21 31 23 33 - // b2: 40 50 42 52 41 51 43 53 - // b3: 60 70 62 72 61 71 63 73 - // b4: 04 14 06 16 05 15 07 17 - // b5: 24 34 26 36 25 35 27 37 - // b6: 44 54 46 56 45 55 47 57 - // b7: 64 74 66 76 65 75 67 77 - - const int32x4x2_t b0 = vtrnq_s32(a0->val[0], a1->val[0]); - const int32x4x2_t b1 = vtrnq_s32(a2->val[0], a3->val[0]); - const int32x4x2_t b2 = vtrnq_s32(a4->val[0], a5->val[0]); - const int32x4x2_t b3 = vtrnq_s32(a6->val[0], a7->val[0]); - const int32x4x2_t b4 = vtrnq_s32(a0->val[1], a1->val[1]); - const int32x4x2_t b5 = vtrnq_s32(a2->val[1], a3->val[1]); - const int32x4x2_t b6 = vtrnq_s32(a4->val[1], a5->val[1]); - const int32x4x2_t b7 = vtrnq_s32(a6->val[1], a7->val[1]); - - // Swap 64 bit elements resulting in: - // c0: 00 10 20 30 02 12 22 32 - // c1: 01 11 21 31 03 13 23 33 - // c2: 40 50 60 70 42 52 62 72 - // c3: 41 51 61 71 43 53 63 73 - // c4: 04 14 24 34 06 16 26 36 - // c5: 05 15 25 35 07 17 27 37 - // c6: 44 54 64 74 46 56 66 76 - // c7: 45 55 65 75 47 57 67 77 - const int32x4x2_t c0 = vpx_vtrnq_s64_to_s32(b0.val[0], b1.val[0]); - const int32x4x2_t c1 = vpx_vtrnq_s64_to_s32(b0.val[1], b1.val[1]); - const int32x4x2_t c2 = vpx_vtrnq_s64_to_s32(b2.val[0], b3.val[0]); - const int32x4x2_t c3 = vpx_vtrnq_s64_to_s32(b2.val[1], b3.val[1]); - const int32x4x2_t c4 = vpx_vtrnq_s64_to_s32(b4.val[0], b5.val[0]); - const int32x4x2_t c5 = vpx_vtrnq_s64_to_s32(b4.val[1], b5.val[1]); - const int32x4x2_t c6 = vpx_vtrnq_s64_to_s32(b6.val[0], b7.val[0]); - const int32x4x2_t c7 = vpx_vtrnq_s64_to_s32(b6.val[1], b7.val[1]); - - // Swap 128 bit elements resulting in: - // a0: 00 10 20 30 40 50 60 70 - // a1: 01 11 21 31 41 51 61 71 - // a2: 02 12 22 32 42 52 62 72 - // a3: 03 13 23 33 43 53 63 73 - // a4: 04 14 24 34 44 54 64 74 - // a5: 05 15 25 35 45 55 65 75 - // a6: 06 16 26 36 46 56 66 76 - // a7: 07 17 27 37 47 57 67 77 - a0->val[0] = c0.val[0]; - a0->val[1] = c2.val[0]; - a1->val[0] = c1.val[0]; - a1->val[1] = c3.val[0]; - a2->val[0] = c0.val[1]; - a2->val[1] = c2.val[1]; - a3->val[0] = c1.val[1]; - a3->val[1] = c3.val[1]; - a4->val[0] = c4.val[0]; - a4->val[1] = c6.val[0]; - a5->val[0] = c5.val[0]; - a5->val[1] = c7.val[0]; - a6->val[0] = c4.val[1]; - a6->val[1] = c6.val[1]; - a7->val[0] = c5.val[1]; - a7->val[1] = c7.val[1]; -} - -// Helper transpose function for highbd FDCT variants -static INLINE void transpose_s32_8x8_2(int32x4_t *left /*[8]*/, - int32x4_t *right /*[8]*/, - int32x4_t *out_left /*[8]*/, - int32x4_t *out_right /*[8]*/) { - int32x4x2_t out[8]; - - out[0].val[0] = left[0]; - out[0].val[1] = right[0]; - out[1].val[0] = left[1]; - out[1].val[1] = right[1]; - out[2].val[0] = left[2]; - out[2].val[1] = right[2]; - out[3].val[0] = left[3]; - out[3].val[1] = right[3]; - out[4].val[0] = left[4]; - out[4].val[1] = right[4]; - out[5].val[0] = left[5]; - out[5].val[1] = right[5]; - out[6].val[0] = left[6]; - out[6].val[1] = right[6]; - out[7].val[0] = left[7]; - out[7].val[1] = right[7]; - - transpose_s32_8x8(&out[0], &out[1], &out[2], &out[3], &out[4], &out[5], - &out[6], &out[7]); - - out_left[0] = out[0].val[0]; - out_left[1] = out[1].val[0]; - out_left[2] = out[2].val[0]; - out_left[3] = out[3].val[0]; - out_left[4] = out[4].val[0]; - out_left[5] = out[5].val[0]; - out_left[6] = out[6].val[0]; - out_left[7] = out[7].val[0]; - out_right[0] = out[0].val[1]; - out_right[1] = out[1].val[1]; - out_right[2] = out[2].val[1]; - out_right[3] = out[3].val[1]; - out_right[4] = out[4].val[1]; - out_right[5] = out[5].val[1]; - out_right[6] = out[6].val[1]; - out_right[7] = out[7].val[1]; -} - -static INLINE void transpose_s32_16x16(int32x4_t *left1, int32x4_t *right1, - int32x4_t *left2, int32x4_t *right2) { - int32x4_t tl[16], tr[16]; - - // transpose the 4 8x8 quadrants separately but first swap quadrants 2 and 3. - tl[0] = left1[8]; - tl[1] = left1[9]; - tl[2] = left1[10]; - tl[3] = left1[11]; - tl[4] = left1[12]; - tl[5] = left1[13]; - tl[6] = left1[14]; - tl[7] = left1[15]; - tr[0] = right1[8]; - tr[1] = right1[9]; - tr[2] = right1[10]; - tr[3] = right1[11]; - tr[4] = right1[12]; - tr[5] = right1[13]; - tr[6] = right1[14]; - tr[7] = right1[15]; - - left1[8] = left2[0]; - left1[9] = left2[1]; - left1[10] = left2[2]; - left1[11] = left2[3]; - left1[12] = left2[4]; - left1[13] = left2[5]; - left1[14] = left2[6]; - left1[15] = left2[7]; - right1[8] = right2[0]; - right1[9] = right2[1]; - right1[10] = right2[2]; - right1[11] = right2[3]; - right1[12] = right2[4]; - right1[13] = right2[5]; - right1[14] = right2[6]; - right1[15] = right2[7]; - - left2[0] = tl[0]; - left2[1] = tl[1]; - left2[2] = tl[2]; - left2[3] = tl[3]; - left2[4] = tl[4]; - left2[5] = tl[5]; - left2[6] = tl[6]; - left2[7] = tl[7]; - right2[0] = tr[0]; - right2[1] = tr[1]; - right2[2] = tr[2]; - right2[3] = tr[3]; - right2[4] = tr[4]; - right2[5] = tr[5]; - right2[6] = tr[6]; - right2[7] = tr[7]; - - transpose_s32_8x8_2(left1, right1, left1, right1); - transpose_s32_8x8_2(left2, right2, left2, right2); - transpose_s32_8x8_2(left1 + 8, right1 + 8, left1 + 8, right1 + 8); - transpose_s32_8x8_2(left2 + 8, right2 + 8, left2 + 8, right2 + 8); -} - -static INLINE void transpose_u8_16x8( - const uint8x16_t i0, const uint8x16_t i1, const uint8x16_t i2, - const uint8x16_t i3, const uint8x16_t i4, const uint8x16_t i5, - const uint8x16_t i6, const uint8x16_t i7, uint8x8_t *o0, uint8x8_t *o1, - uint8x8_t *o2, uint8x8_t *o3, uint8x8_t *o4, uint8x8_t *o5, uint8x8_t *o6, - uint8x8_t *o7, uint8x8_t *o8, uint8x8_t *o9, uint8x8_t *o10, uint8x8_t *o11, - uint8x8_t *o12, uint8x8_t *o13, uint8x8_t *o14, uint8x8_t *o15) { - // Swap 8 bit elements. Goes from: - // i0: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F - // i1: 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F - // i2: 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F - // i3: 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F - // i4: 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F - // i5: 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F - // i6: 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F - // i7: 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F - // to: - // b0.val[0]: 00 10 02 12 04 14 06 16 08 18 0A 1A 0C 1C 0E 1E - // b0.val[1]: 01 11 03 13 05 15 07 17 09 19 0B 1B 0D 1D 0F 1F - // b1.val[0]: 20 30 22 32 24 34 26 36 28 38 2A 3A 2C 3C 2E 3E - // b1.val[1]: 21 31 23 33 25 35 27 37 29 39 2B 3B 2D 3D 2F 3F - // b2.val[0]: 40 50 42 52 44 54 46 56 48 58 4A 5A 4C 5C 4E 5E - // b2.val[1]: 41 51 43 53 45 55 47 57 49 59 4B 5B 4D 5D 4F 5F - // b3.val[0]: 60 70 62 72 64 74 66 76 68 78 6A 7A 6C 7C 6E 7E - // b3.val[1]: 61 71 63 73 65 75 67 77 69 79 6B 7B 6D 7D 6F 7F - const uint8x16x2_t b0 = vtrnq_u8(i0, i1); - const uint8x16x2_t b1 = vtrnq_u8(i2, i3); - const uint8x16x2_t b2 = vtrnq_u8(i4, i5); - const uint8x16x2_t b3 = vtrnq_u8(i6, i7); - - // Swap 16 bit elements resulting in: - // c0.val[0]: 00 10 20 30 04 14 24 34 08 18 28 38 0C 1C 2C 3C - // c0.val[1]: 02 12 22 32 06 16 26 36 0A 1A 2A 3A 0E 1E 2E 3E - // c1.val[0]: 01 11 21 31 05 15 25 35 09 19 29 39 0D 1D 2D 3D - // c1.val[1]: 03 13 23 33 07 17 27 37 0B 1B 2B 3B 0F 1F 2F 3F - // c2.val[0]: 40 50 60 70 44 54 64 74 48 58 68 78 4C 5C 6C 7C - // c2.val[1]: 42 52 62 72 46 56 66 76 4A 5A 6A 7A 4E 5E 6E 7E - // c3.val[0]: 41 51 61 71 45 55 65 75 49 59 69 79 4D 5D 6D 7D - // c3.val[1]: 43 53 63 73 47 57 67 77 4B 5B 6B 7B 4F 5F 6F 7F - const uint16x8x2_t c0 = vtrnq_u16(vreinterpretq_u16_u8(b0.val[0]), - vreinterpretq_u16_u8(b1.val[0])); - const uint16x8x2_t c1 = vtrnq_u16(vreinterpretq_u16_u8(b0.val[1]), - vreinterpretq_u16_u8(b1.val[1])); - const uint16x8x2_t c2 = vtrnq_u16(vreinterpretq_u16_u8(b2.val[0]), - vreinterpretq_u16_u8(b3.val[0])); - const uint16x8x2_t c3 = vtrnq_u16(vreinterpretq_u16_u8(b2.val[1]), - vreinterpretq_u16_u8(b3.val[1])); - - // Swap 32 bit elements resulting in: - // d0.val[0]: 00 10 20 30 40 50 60 70 08 18 28 38 48 58 68 78 - // d0.val[1]: 04 14 24 34 44 54 64 74 0C 1C 2C 3C 4C 5C 6C 7C - // d1.val[0]: 02 12 22 32 42 52 62 72 0A 1A 2A 3A 4A 5A 6A 7A - // d1.val[1]: 06 16 26 36 46 56 66 76 0E 1E 2E 3E 4E 5E 6E 7E - // d2.val[0]: 01 11 21 31 41 51 61 71 09 19 29 39 49 59 69 79 - // d2.val[1]: 05 15 25 35 45 55 65 75 0D 1D 2D 3D 4D 5D 6D 7D - // d3.val[0]: 03 13 23 33 43 53 63 73 0B 1B 2B 3B 4B 5B 6B 7B - // d3.val[1]: 07 17 27 37 47 57 67 77 0F 1F 2F 3F 4F 5F 6F 7F - const uint32x4x2_t d0 = vtrnq_u32(vreinterpretq_u32_u16(c0.val[0]), - vreinterpretq_u32_u16(c2.val[0])); - const uint32x4x2_t d1 = vtrnq_u32(vreinterpretq_u32_u16(c0.val[1]), - vreinterpretq_u32_u16(c2.val[1])); - const uint32x4x2_t d2 = vtrnq_u32(vreinterpretq_u32_u16(c1.val[0]), - vreinterpretq_u32_u16(c3.val[0])); - const uint32x4x2_t d3 = vtrnq_u32(vreinterpretq_u32_u16(c1.val[1]), - vreinterpretq_u32_u16(c3.val[1])); - - // Output: - // o0 : 00 10 20 30 40 50 60 70 - // o1 : 01 11 21 31 41 51 61 71 - // o2 : 02 12 22 32 42 52 62 72 - // o3 : 03 13 23 33 43 53 63 73 - // o4 : 04 14 24 34 44 54 64 74 - // o5 : 05 15 25 35 45 55 65 75 - // o6 : 06 16 26 36 46 56 66 76 - // o7 : 07 17 27 37 47 57 67 77 - // o8 : 08 18 28 38 48 58 68 78 - // o9 : 09 19 29 39 49 59 69 79 - // o10: 0A 1A 2A 3A 4A 5A 6A 7A - // o11: 0B 1B 2B 3B 4B 5B 6B 7B - // o12: 0C 1C 2C 3C 4C 5C 6C 7C - // o13: 0D 1D 2D 3D 4D 5D 6D 7D - // o14: 0E 1E 2E 3E 4E 5E 6E 7E - // o15: 0F 1F 2F 3F 4F 5F 6F 7F - *o0 = vget_low_u8(vreinterpretq_u8_u32(d0.val[0])); - *o1 = vget_low_u8(vreinterpretq_u8_u32(d2.val[0])); - *o2 = vget_low_u8(vreinterpretq_u8_u32(d1.val[0])); - *o3 = vget_low_u8(vreinterpretq_u8_u32(d3.val[0])); - *o4 = vget_low_u8(vreinterpretq_u8_u32(d0.val[1])); - *o5 = vget_low_u8(vreinterpretq_u8_u32(d2.val[1])); - *o6 = vget_low_u8(vreinterpretq_u8_u32(d1.val[1])); - *o7 = vget_low_u8(vreinterpretq_u8_u32(d3.val[1])); - *o8 = vget_high_u8(vreinterpretq_u8_u32(d0.val[0])); - *o9 = vget_high_u8(vreinterpretq_u8_u32(d2.val[0])); - *o10 = vget_high_u8(vreinterpretq_u8_u32(d1.val[0])); - *o11 = vget_high_u8(vreinterpretq_u8_u32(d3.val[0])); - *o12 = vget_high_u8(vreinterpretq_u8_u32(d0.val[1])); - *o13 = vget_high_u8(vreinterpretq_u8_u32(d2.val[1])); - *o14 = vget_high_u8(vreinterpretq_u8_u32(d1.val[1])); - *o15 = vget_high_u8(vreinterpretq_u8_u32(d3.val[1])); -} - -static INLINE void transpose_u8_8x16( - const uint8x8_t i0, const uint8x8_t i1, const uint8x8_t i2, - const uint8x8_t i3, const uint8x8_t i4, const uint8x8_t i5, - const uint8x8_t i6, const uint8x8_t i7, const uint8x8_t i8, - const uint8x8_t i9, const uint8x8_t i10, const uint8x8_t i11, - const uint8x8_t i12, const uint8x8_t i13, const uint8x8_t i14, - const uint8x8_t i15, uint8x16_t *o0, uint8x16_t *o1, uint8x16_t *o2, - uint8x16_t *o3, uint8x16_t *o4, uint8x16_t *o5, uint8x16_t *o6, - uint8x16_t *o7) { - // Combine 8 bit elements. Goes from: - // i0 : 00 01 02 03 04 05 06 07 - // i1 : 10 11 12 13 14 15 16 17 - // i2 : 20 21 22 23 24 25 26 27 - // i3 : 30 31 32 33 34 35 36 37 - // i4 : 40 41 42 43 44 45 46 47 - // i5 : 50 51 52 53 54 55 56 57 - // i6 : 60 61 62 63 64 65 66 67 - // i7 : 70 71 72 73 74 75 76 77 - // i8 : 80 81 82 83 84 85 86 87 - // i9 : 90 91 92 93 94 95 96 97 - // i10: A0 A1 A2 A3 A4 A5 A6 A7 - // i11: B0 B1 B2 B3 B4 B5 B6 B7 - // i12: C0 C1 C2 C3 C4 C5 C6 C7 - // i13: D0 D1 D2 D3 D4 D5 D6 D7 - // i14: E0 E1 E2 E3 E4 E5 E6 E7 - // i15: F0 F1 F2 F3 F4 F5 F6 F7 - // to: - // a0: 00 01 02 03 04 05 06 07 80 81 82 83 84 85 86 87 - // a1: 10 11 12 13 14 15 16 17 90 91 92 93 94 95 96 97 - // a2: 20 21 22 23 24 25 26 27 A0 A1 A2 A3 A4 A5 A6 A7 - // a3: 30 31 32 33 34 35 36 37 B0 B1 B2 B3 B4 B5 B6 B7 - // a4: 40 41 42 43 44 45 46 47 C0 C1 C2 C3 C4 C5 C6 C7 - // a5: 50 51 52 53 54 55 56 57 D0 D1 D2 D3 D4 D5 D6 D7 - // a6: 60 61 62 63 64 65 66 67 E0 E1 E2 E3 E4 E5 E6 E7 - // a7: 70 71 72 73 74 75 76 77 F0 F1 F2 F3 F4 F5 F6 F7 - const uint8x16_t a0 = vcombine_u8(i0, i8); - const uint8x16_t a1 = vcombine_u8(i1, i9); - const uint8x16_t a2 = vcombine_u8(i2, i10); - const uint8x16_t a3 = vcombine_u8(i3, i11); - const uint8x16_t a4 = vcombine_u8(i4, i12); - const uint8x16_t a5 = vcombine_u8(i5, i13); - const uint8x16_t a6 = vcombine_u8(i6, i14); - const uint8x16_t a7 = vcombine_u8(i7, i15); - - // Swap 8 bit elements resulting in: - // b0.val[0]: 00 10 02 12 04 14 06 16 80 90 82 92 84 94 86 96 - // b0.val[1]: 01 11 03 13 05 15 07 17 81 91 83 93 85 95 87 97 - // b1.val[0]: 20 30 22 32 24 34 26 36 A0 B0 A2 B2 A4 B4 A6 B6 - // b1.val[1]: 21 31 23 33 25 35 27 37 A1 B1 A3 B3 A5 B5 A7 B7 - // b2.val[0]: 40 50 42 52 44 54 46 56 C0 D0 C2 D2 C4 D4 C6 D6 - // b2.val[1]: 41 51 43 53 45 55 47 57 C1 D1 C3 D3 C5 D5 C7 D7 - // b3.val[0]: 60 70 62 72 64 74 66 76 E0 F0 E2 F2 E4 F4 E6 F6 - // b3.val[1]: 61 71 63 73 65 75 67 77 E1 F1 E3 F3 E5 F5 E7 F7 - const uint8x16x2_t b0 = vtrnq_u8(a0, a1); - const uint8x16x2_t b1 = vtrnq_u8(a2, a3); - const uint8x16x2_t b2 = vtrnq_u8(a4, a5); - const uint8x16x2_t b3 = vtrnq_u8(a6, a7); - - // Swap 16 bit elements resulting in: - // c0.val[0]: 00 10 20 30 04 14 24 34 80 90 A0 B0 84 94 A4 B4 - // c0.val[1]: 02 12 22 32 06 16 26 36 82 92 A2 B2 86 96 A6 B6 - // c1.val[0]: 01 11 21 31 05 15 25 35 81 91 A1 B1 85 95 A5 B5 - // c1.val[1]: 03 13 23 33 07 17 27 37 83 93 A3 B3 87 97 A7 B7 - // c2.val[0]: 40 50 60 70 44 54 64 74 C0 D0 E0 F0 C4 D4 E4 F4 - // c2.val[1]: 42 52 62 72 46 56 66 76 C2 D2 E2 F2 C6 D6 E6 F6 - // c3.val[0]: 41 51 61 71 45 55 65 75 C1 D1 E1 F1 C5 D5 E5 F5 - // c3.val[1]: 43 53 63 73 47 57 67 77 C3 D3 E3 F3 C7 D7 E7 F7 - const uint16x8x2_t c0 = vtrnq_u16(vreinterpretq_u16_u8(b0.val[0]), - vreinterpretq_u16_u8(b1.val[0])); - const uint16x8x2_t c1 = vtrnq_u16(vreinterpretq_u16_u8(b0.val[1]), - vreinterpretq_u16_u8(b1.val[1])); - const uint16x8x2_t c2 = vtrnq_u16(vreinterpretq_u16_u8(b2.val[0]), - vreinterpretq_u16_u8(b3.val[0])); - const uint16x8x2_t c3 = vtrnq_u16(vreinterpretq_u16_u8(b2.val[1]), - vreinterpretq_u16_u8(b3.val[1])); - - // Swap 32 bit elements resulting in: - // d0.val[0]: 00 10 20 30 40 50 60 70 80 90 A0 B0 C0 D0 E0 F0 - // d0.val[1]: 04 14 24 34 44 54 64 74 84 94 A4 B4 C4 D4 E4 F4 - // d1.val[0]: 02 12 22 32 42 52 62 72 82 92 A2 B2 C2 D2 E2 F2 - // d1.val[1]: 06 16 26 36 46 56 66 76 86 96 A6 B6 C6 D6 E6 F6 - // d2.val[0]: 01 11 21 31 41 51 61 71 81 91 A1 B1 C1 D1 E1 F1 - // d2.val[1]: 05 15 25 35 45 55 65 75 85 95 A5 B5 C5 D5 E5 F5 - // d3.val[0]: 03 13 23 33 43 53 63 73 83 93 A3 B3 C3 D3 E3 F3 - // d3.val[1]: 07 17 27 37 47 57 67 77 87 97 A7 B7 C7 D7 E7 F7 - const uint32x4x2_t d0 = vtrnq_u32(vreinterpretq_u32_u16(c0.val[0]), - vreinterpretq_u32_u16(c2.val[0])); - const uint32x4x2_t d1 = vtrnq_u32(vreinterpretq_u32_u16(c0.val[1]), - vreinterpretq_u32_u16(c2.val[1])); - const uint32x4x2_t d2 = vtrnq_u32(vreinterpretq_u32_u16(c1.val[0]), - vreinterpretq_u32_u16(c3.val[0])); - const uint32x4x2_t d3 = vtrnq_u32(vreinterpretq_u32_u16(c1.val[1]), - vreinterpretq_u32_u16(c3.val[1])); - - // Output: - // o0: 00 10 20 30 40 50 60 70 80 90 A0 B0 C0 D0 E0 F0 - // o1: 01 11 21 31 41 51 61 71 81 91 A1 B1 C1 D1 E1 F1 - // o2: 02 12 22 32 42 52 62 72 82 92 A2 B2 C2 D2 E2 F2 - // o3: 03 13 23 33 43 53 63 73 83 93 A3 B3 C3 D3 E3 F3 - // o4: 04 14 24 34 44 54 64 74 84 94 A4 B4 C4 D4 E4 F4 - // o5: 05 15 25 35 45 55 65 75 85 95 A5 B5 C5 D5 E5 F5 - // o6: 06 16 26 36 46 56 66 76 86 96 A6 B6 C6 D6 E6 F6 - // o7: 07 17 27 37 47 57 67 77 87 97 A7 B7 C7 D7 E7 F7 - *o0 = vreinterpretq_u8_u32(d0.val[0]); - *o1 = vreinterpretq_u8_u32(d2.val[0]); - *o2 = vreinterpretq_u8_u32(d1.val[0]); - *o3 = vreinterpretq_u8_u32(d3.val[0]); - *o4 = vreinterpretq_u8_u32(d0.val[1]); - *o5 = vreinterpretq_u8_u32(d2.val[1]); - *o6 = vreinterpretq_u8_u32(d1.val[1]); - *o7 = vreinterpretq_u8_u32(d3.val[1]); -} - -static INLINE void transpose_u8_16x16( - const uint8x16_t i0, const uint8x16_t i1, const uint8x16_t i2, - const uint8x16_t i3, const uint8x16_t i4, const uint8x16_t i5, - const uint8x16_t i6, const uint8x16_t i7, const uint8x16_t i8, - const uint8x16_t i9, const uint8x16_t i10, const uint8x16_t i11, - const uint8x16_t i12, const uint8x16_t i13, const uint8x16_t i14, - const uint8x16_t i15, uint8x16_t *o0, uint8x16_t *o1, uint8x16_t *o2, - uint8x16_t *o3, uint8x16_t *o4, uint8x16_t *o5, uint8x16_t *o6, - uint8x16_t *o7, uint8x16_t *o8, uint8x16_t *o9, uint8x16_t *o10, - uint8x16_t *o11, uint8x16_t *o12, uint8x16_t *o13, uint8x16_t *o14, - uint8x16_t *o15) { - // Swap 8 bit elements. Goes from: - // i0: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F - // i1: 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F - // i2: 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F - // i3: 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F - // i4: 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F - // i5: 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F - // i6: 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F - // i7: 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F - // i8: 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F - // i9: 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F - // i10: A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF - // i11: B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF - // i12: C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF - // i13: D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF - // i14: E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF - // i15: F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF - // to: - // b0.val[0]: 00 10 02 12 04 14 06 16 08 18 0A 1A 0C 1C 0E 1E - // b0.val[1]: 01 11 03 13 05 15 07 17 09 19 0B 1B 0D 1D 0F 1F - // b1.val[0]: 20 30 22 32 24 34 26 36 28 38 2A 3A 2C 3C 2E 3E - // b1.val[1]: 21 31 23 33 25 35 27 37 29 39 2B 3B 2D 3D 2F 3F - // b2.val[0]: 40 50 42 52 44 54 46 56 48 58 4A 5A 4C 5C 4E 5E - // b2.val[1]: 41 51 43 53 45 55 47 57 49 59 4B 5B 4D 5D 4F 5F - // b3.val[0]: 60 70 62 72 64 74 66 76 68 78 6A 7A 6C 7C 6E 7E - // b3.val[1]: 61 71 63 73 65 75 67 77 69 79 6B 7B 6D 7D 6F 7F - // b4.val[0]: 80 90 82 92 84 94 86 96 88 98 8A 9A 8C 9C 8E 9E - // b4.val[1]: 81 91 83 93 85 95 87 97 89 99 8B 9B 8D 9D 8F 9F - // b5.val[0]: A0 B0 A2 B2 A4 B4 A6 B6 A8 B8 AA BA AC BC AE BE - // b5.val[1]: A1 B1 A3 B3 A5 B5 A7 B7 A9 B9 AB BB AD BD AF BF - // b6.val[0]: C0 D0 C2 D2 C4 D4 C6 D6 C8 D8 CA DA CC DC CE DE - // b6.val[1]: C1 D1 C3 D3 C5 D5 C7 D7 C9 D9 CB DB CD DD CF DF - // b7.val[0]: E0 F0 E2 F2 E4 F4 E6 F6 E8 F8 EA FA EC FC EE FE - // b7.val[1]: E1 F1 E3 F3 E5 F5 E7 F7 E9 F9 EB FB ED FD EF FF - const uint8x16x2_t b0 = vtrnq_u8(i0, i1); - const uint8x16x2_t b1 = vtrnq_u8(i2, i3); - const uint8x16x2_t b2 = vtrnq_u8(i4, i5); - const uint8x16x2_t b3 = vtrnq_u8(i6, i7); - const uint8x16x2_t b4 = vtrnq_u8(i8, i9); - const uint8x16x2_t b5 = vtrnq_u8(i10, i11); - const uint8x16x2_t b6 = vtrnq_u8(i12, i13); - const uint8x16x2_t b7 = vtrnq_u8(i14, i15); - - // Swap 16 bit elements resulting in: - // c0.val[0]: 00 10 20 30 04 14 24 34 08 18 28 38 0C 1C 2C 3C - // c0.val[1]: 02 12 22 32 06 16 26 36 0A 1A 2A 3A 0E 1E 2E 3E - // c1.val[0]: 01 11 21 31 05 15 25 35 09 19 29 39 0D 1D 2D 3D - // c1.val[1]: 03 13 23 33 07 17 27 37 0B 1B 2B 3B 0F 1F 2F 3F - // c2.val[0]: 40 50 60 70 44 54 64 74 48 58 68 78 4C 5C 6C 7C - // c2.val[1]: 42 52 62 72 46 56 66 76 4A 5A 6A 7A 4E 5E 6E 7E - // c3.val[0]: 41 51 61 71 45 55 65 75 49 59 69 79 4D 5D 6D 7D - // c3.val[1]: 43 53 63 73 47 57 67 77 4B 5B 6B 7B 4F 5F 6F 7F - // c4.val[0]: 80 90 A0 B0 84 94 A4 B4 88 98 A8 B8 8C 9C AC BC - // c4.val[1]: 82 92 A2 B2 86 96 A6 B6 8A 9A AA BA 8E 9E AE BE - // c5.val[0]: 81 91 A1 B1 85 95 A5 B5 89 99 A9 B9 8D 9D AD BD - // c5.val[1]: 83 93 A3 B3 87 97 A7 B7 8B 9B AB BB 8F 9F AF BF - // c6.val[0]: C0 D0 E0 F0 C4 D4 E4 F4 C8 D8 E8 F8 CC DC EC FC - // c6.val[1]: C2 D2 E2 F2 C6 D6 E6 F6 CA DA EA FA CE DE EE FE - // c7.val[0]: C1 D1 E1 F1 C5 D5 E5 F5 C9 D9 E9 F9 CD DD ED FD - // c7.val[1]: C3 D3 E3 F3 C7 D7 E7 F7 CB DB EB FB CF DF EF FF - const uint16x8x2_t c0 = vtrnq_u16(vreinterpretq_u16_u8(b0.val[0]), - vreinterpretq_u16_u8(b1.val[0])); - const uint16x8x2_t c1 = vtrnq_u16(vreinterpretq_u16_u8(b0.val[1]), - vreinterpretq_u16_u8(b1.val[1])); - const uint16x8x2_t c2 = vtrnq_u16(vreinterpretq_u16_u8(b2.val[0]), - vreinterpretq_u16_u8(b3.val[0])); - const uint16x8x2_t c3 = vtrnq_u16(vreinterpretq_u16_u8(b2.val[1]), - vreinterpretq_u16_u8(b3.val[1])); - const uint16x8x2_t c4 = vtrnq_u16(vreinterpretq_u16_u8(b4.val[0]), - vreinterpretq_u16_u8(b5.val[0])); - const uint16x8x2_t c5 = vtrnq_u16(vreinterpretq_u16_u8(b4.val[1]), - vreinterpretq_u16_u8(b5.val[1])); - const uint16x8x2_t c6 = vtrnq_u16(vreinterpretq_u16_u8(b6.val[0]), - vreinterpretq_u16_u8(b7.val[0])); - const uint16x8x2_t c7 = vtrnq_u16(vreinterpretq_u16_u8(b6.val[1]), - vreinterpretq_u16_u8(b7.val[1])); - - // Swap 32 bit elements resulting in: - // d0.val[0]: 00 10 20 30 40 50 60 70 08 18 28 38 48 58 68 78 - // d0.val[1]: 04 14 24 34 44 54 64 74 0C 1C 2C 3C 4C 5C 6C 7C - // d1.val[0]: 02 12 22 32 42 52 62 72 0A 1A 2A 3A 4A 5A 6A 7A - // d1.val[1]: 06 16 26 36 46 56 66 76 0E 1E 2E 3E 4E 5E 6E 7E - // d2.val[0]: 01 11 21 31 41 51 61 71 09 19 29 39 49 59 69 79 - // d2.val[1]: 05 15 25 35 45 55 65 75 0D 1D 2D 3D 4D 5D 6D 7D - // d3.val[0]: 03 13 23 33 43 53 63 73 0B 1B 2B 3B 4B 5B 6B 7B - // d3.val[1]: 07 17 27 37 47 57 67 77 0F 1F 2F 3F 4F 5F 6F 7F - // d4.val[0]: 80 90 A0 B0 C0 D0 E0 F0 88 98 A8 B8 C8 D8 E8 F8 - // d4.val[1]: 84 94 A4 B4 C4 D4 E4 F4 8C 9C AC BC CC DC EC FC - // d5.val[0]: 82 92 A2 B2 C2 D2 E2 F2 8A 9A AA BA CA DA EA FA - // d5.val[1]: 86 96 A6 B6 C6 D6 E6 F6 8E 9E AE BE CE DE EE FE - // d6.val[0]: 81 91 A1 B1 C1 D1 E1 F1 89 99 A9 B9 C9 D9 E9 F9 - // d6.val[1]: 85 95 A5 B5 C5 D5 E5 F5 8D 9D AD BD CD DD ED FD - // d7.val[0]: 83 93 A3 B3 C3 D3 E3 F3 8B 9B AB BB CB DB EB FB - // d7.val[1]: 87 97 A7 B7 C7 D7 E7 F7 8F 9F AF BF CF DF EF FF - const uint32x4x2_t d0 = vtrnq_u32(vreinterpretq_u32_u16(c0.val[0]), - vreinterpretq_u32_u16(c2.val[0])); - const uint32x4x2_t d1 = vtrnq_u32(vreinterpretq_u32_u16(c0.val[1]), - vreinterpretq_u32_u16(c2.val[1])); - const uint32x4x2_t d2 = vtrnq_u32(vreinterpretq_u32_u16(c1.val[0]), - vreinterpretq_u32_u16(c3.val[0])); - const uint32x4x2_t d3 = vtrnq_u32(vreinterpretq_u32_u16(c1.val[1]), - vreinterpretq_u32_u16(c3.val[1])); - const uint32x4x2_t d4 = vtrnq_u32(vreinterpretq_u32_u16(c4.val[0]), - vreinterpretq_u32_u16(c6.val[0])); - const uint32x4x2_t d5 = vtrnq_u32(vreinterpretq_u32_u16(c4.val[1]), - vreinterpretq_u32_u16(c6.val[1])); - const uint32x4x2_t d6 = vtrnq_u32(vreinterpretq_u32_u16(c5.val[0]), - vreinterpretq_u32_u16(c7.val[0])); - const uint32x4x2_t d7 = vtrnq_u32(vreinterpretq_u32_u16(c5.val[1]), - vreinterpretq_u32_u16(c7.val[1])); - - // Swap 64 bit elements resulting in: - // e0.val[0]: 00 10 20 30 40 50 60 70 80 90 A0 B0 C0 D0 E0 F0 - // e0.val[1]: 08 18 28 38 48 58 68 78 88 98 A8 B8 C8 D8 E8 F8 - // e1.val[0]: 01 11 21 31 41 51 61 71 84 94 A4 B4 C4 D4 E4 F4 - // e1.val[1]: 09 19 29 39 49 59 69 79 89 99 A9 B9 C9 D9 E9 F9 - // e2.val[0]: 02 12 22 32 42 52 62 72 82 92 A2 B2 C2 D2 E2 F2 - // e2.val[1]: 0A 1A 2A 3A 4A 5A 6A 7A 8A 9A AA BA CA DA EA FA - // e3.val[0]: 03 13 23 33 43 53 63 73 86 96 A6 B6 C6 D6 E6 F6 - // e3.val[1]: 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AB BB CB DB EB FB - // e4.val[0]: 04 14 24 34 44 54 64 74 81 91 A1 B1 C1 D1 E1 F1 - // e4.val[1]: 0C 1C 2C 3C 4C 5C 6C 7C 8C 9C AC BC CC DC EC FC - // e5.val[0]: 05 15 25 35 45 55 65 75 85 95 A5 B5 C5 D5 E5 F5 - // e5.val[1]: 0D 1D 2D 3D 4D 5D 6D 7D 8D 9D AD BD CD DD ED FD - // e6.val[0]: 06 16 26 36 46 56 66 76 83 93 A3 B3 C3 D3 E3 F3 - // e6.val[1]: 0E 1E 2E 3E 4E 5E 6E 7E 8E 9E AE BE CE DE EE FE - // e7.val[0]: 07 17 27 37 47 57 67 77 87 97 A7 B7 C7 D7 E7 F7 - // e7.val[1]: 0F 1F 2F 3F 4F 5F 6F 7F 8F 9F AF BF CF DF EF FF - const uint8x16x2_t e0 = vpx_vtrnq_u64_to_u8(d0.val[0], d4.val[0]); - const uint8x16x2_t e1 = vpx_vtrnq_u64_to_u8(d2.val[0], d6.val[0]); - const uint8x16x2_t e2 = vpx_vtrnq_u64_to_u8(d1.val[0], d5.val[0]); - const uint8x16x2_t e3 = vpx_vtrnq_u64_to_u8(d3.val[0], d7.val[0]); - const uint8x16x2_t e4 = vpx_vtrnq_u64_to_u8(d0.val[1], d4.val[1]); - const uint8x16x2_t e5 = vpx_vtrnq_u64_to_u8(d2.val[1], d6.val[1]); - const uint8x16x2_t e6 = vpx_vtrnq_u64_to_u8(d1.val[1], d5.val[1]); - const uint8x16x2_t e7 = vpx_vtrnq_u64_to_u8(d3.val[1], d7.val[1]); - - // Output: - // o0 : 00 10 20 30 40 50 60 70 80 90 A0 B0 C0 D0 E0 F0 - // o1 : 01 11 21 31 41 51 61 71 84 94 A4 B4 C4 D4 E4 F4 - // o2 : 02 12 22 32 42 52 62 72 82 92 A2 B2 C2 D2 E2 F2 - // o3 : 03 13 23 33 43 53 63 73 86 96 A6 B6 C6 D6 E6 F6 - // o4 : 04 14 24 34 44 54 64 74 81 91 A1 B1 C1 D1 E1 F1 - // o5 : 05 15 25 35 45 55 65 75 85 95 A5 B5 C5 D5 E5 F5 - // o6 : 06 16 26 36 46 56 66 76 83 93 A3 B3 C3 D3 E3 F3 - // o7 : 07 17 27 37 47 57 67 77 87 97 A7 B7 C7 D7 E7 F7 - // o8 : 08 18 28 38 48 58 68 78 88 98 A8 B8 C8 D8 E8 F8 - // o9 : 09 19 29 39 49 59 69 79 89 99 A9 B9 C9 D9 E9 F9 - // o10: 0A 1A 2A 3A 4A 5A 6A 7A 8A 9A AA BA CA DA EA FA - // o11: 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AB BB CB DB EB FB - // o12: 0C 1C 2C 3C 4C 5C 6C 7C 8C 9C AC BC CC DC EC FC - // o13: 0D 1D 2D 3D 4D 5D 6D 7D 8D 9D AD BD CD DD ED FD - // o14: 0E 1E 2E 3E 4E 5E 6E 7E 8E 9E AE BE CE DE EE FE - // o15: 0F 1F 2F 3F 4F 5F 6F 7F 8F 9F AF BF CF DF EF FF - *o0 = e0.val[0]; - *o1 = e1.val[0]; - *o2 = e2.val[0]; - *o3 = e3.val[0]; - *o4 = e4.val[0]; - *o5 = e5.val[0]; - *o6 = e6.val[0]; - *o7 = e7.val[0]; - *o8 = e0.val[1]; - *o9 = e1.val[1]; - *o10 = e2.val[1]; - *o11 = e3.val[1]; - *o12 = e4.val[1]; - *o13 = e5.val[1]; - *o14 = e6.val[1]; - *o15 = e7.val[1]; -} - -static INLINE void transpose_s16_16x16(int16x8_t *in0, int16x8_t *in1) { - int16x8_t t[8]; - - // transpose the 4 8x8 quadrants separately but first swap quadrants 2 and 3. - t[0] = in0[8]; - t[1] = in0[9]; - t[2] = in0[10]; - t[3] = in0[11]; - t[4] = in0[12]; - t[5] = in0[13]; - t[6] = in0[14]; - t[7] = in0[15]; - in0[8] = in1[0]; - in0[9] = in1[1]; - in0[10] = in1[2]; - in0[11] = in1[3]; - in0[12] = in1[4]; - in0[13] = in1[5]; - in0[14] = in1[6]; - in0[15] = in1[7]; - in1[0] = t[0]; - in1[1] = t[1]; - in1[2] = t[2]; - in1[3] = t[3]; - in1[4] = t[4]; - in1[5] = t[5]; - in1[6] = t[6]; - in1[7] = t[7]; - - transpose_s16_8x8(&in0[0], &in0[1], &in0[2], &in0[3], &in0[4], &in0[5], - &in0[6], &in0[7]); - transpose_s16_8x8(&in0[8], &in0[9], &in0[10], &in0[11], &in0[12], &in0[13], - &in0[14], &in0[15]); - transpose_s16_8x8(&in1[0], &in1[1], &in1[2], &in1[3], &in1[4], &in1[5], - &in1[6], &in1[7]); - transpose_s16_8x8(&in1[8], &in1[9], &in1[10], &in1[11], &in1[12], &in1[13], - &in1[14], &in1[15]); -} - -static INLINE void load_and_transpose_u8_4x8(const uint8_t *a, - const int a_stride, uint8x8_t *a0, - uint8x8_t *a1, uint8x8_t *a2, - uint8x8_t *a3) { - uint8x8_t a4, a5, a6, a7; - *a0 = vld1_u8(a); - a += a_stride; - *a1 = vld1_u8(a); - a += a_stride; - *a2 = vld1_u8(a); - a += a_stride; - *a3 = vld1_u8(a); - a += a_stride; - a4 = vld1_u8(a); - a += a_stride; - a5 = vld1_u8(a); - a += a_stride; - a6 = vld1_u8(a); - a += a_stride; - a7 = vld1_u8(a); - - transpose_u8_4x8(a0, a1, a2, a3, a4, a5, a6, a7); -} - -static INLINE void load_and_transpose_u8_8x8(const uint8_t *a, - const int a_stride, uint8x8_t *a0, - uint8x8_t *a1, uint8x8_t *a2, - uint8x8_t *a3, uint8x8_t *a4, - uint8x8_t *a5, uint8x8_t *a6, - uint8x8_t *a7) { - *a0 = vld1_u8(a); - a += a_stride; - *a1 = vld1_u8(a); - a += a_stride; - *a2 = vld1_u8(a); - a += a_stride; - *a3 = vld1_u8(a); - a += a_stride; - *a4 = vld1_u8(a); - a += a_stride; - *a5 = vld1_u8(a); - a += a_stride; - *a6 = vld1_u8(a); - a += a_stride; - *a7 = vld1_u8(a); - - transpose_u8_8x8(a0, a1, a2, a3, a4, a5, a6, a7); -} - -static INLINE void transpose_and_store_u8_8x8(uint8_t *a, const int a_stride, - uint8x8_t a0, uint8x8_t a1, - uint8x8_t a2, uint8x8_t a3, - uint8x8_t a4, uint8x8_t a5, - uint8x8_t a6, uint8x8_t a7) { - transpose_u8_8x8(&a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7); - - vst1_u8(a, a0); - a += a_stride; - vst1_u8(a, a1); - a += a_stride; - vst1_u8(a, a2); - a += a_stride; - vst1_u8(a, a3); - a += a_stride; - vst1_u8(a, a4); - a += a_stride; - vst1_u8(a, a5); - a += a_stride; - vst1_u8(a, a6); - a += a_stride; - vst1_u8(a, a7); -} - -static INLINE void load_and_transpose_s16_8x8(const int16_t *a, - const int a_stride, int16x8_t *a0, - int16x8_t *a1, int16x8_t *a2, - int16x8_t *a3, int16x8_t *a4, - int16x8_t *a5, int16x8_t *a6, - int16x8_t *a7) { - *a0 = vld1q_s16(a); - a += a_stride; - *a1 = vld1q_s16(a); - a += a_stride; - *a2 = vld1q_s16(a); - a += a_stride; - *a3 = vld1q_s16(a); - a += a_stride; - *a4 = vld1q_s16(a); - a += a_stride; - *a5 = vld1q_s16(a); - a += a_stride; - *a6 = vld1q_s16(a); - a += a_stride; - *a7 = vld1q_s16(a); - - transpose_s16_8x8(a0, a1, a2, a3, a4, a5, a6, a7); -} - -static INLINE void load_and_transpose_s32_8x8( - const int32_t *a, const int a_stride, int32x4x2_t *const a0, - int32x4x2_t *const a1, int32x4x2_t *const a2, int32x4x2_t *const a3, - int32x4x2_t *const a4, int32x4x2_t *const a5, int32x4x2_t *const a6, - int32x4x2_t *const a7) { - a0->val[0] = vld1q_s32(a); - a0->val[1] = vld1q_s32(a + 4); - a += a_stride; - a1->val[0] = vld1q_s32(a); - a1->val[1] = vld1q_s32(a + 4); - a += a_stride; - a2->val[0] = vld1q_s32(a); - a2->val[1] = vld1q_s32(a + 4); - a += a_stride; - a3->val[0] = vld1q_s32(a); - a3->val[1] = vld1q_s32(a + 4); - a += a_stride; - a4->val[0] = vld1q_s32(a); - a4->val[1] = vld1q_s32(a + 4); - a += a_stride; - a5->val[0] = vld1q_s32(a); - a5->val[1] = vld1q_s32(a + 4); - a += a_stride; - a6->val[0] = vld1q_s32(a); - a6->val[1] = vld1q_s32(a + 4); - a += a_stride; - a7->val[0] = vld1q_s32(a); - a7->val[1] = vld1q_s32(a + 4); - - transpose_s32_8x8(a0, a1, a2, a3, a4, a5, a6, a7); -} -#endif // VPX_VPX_DSP_ARM_TRANSPOSE_NEON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/variance_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/variance_neon.c deleted file mode 100644 index efb2c1d8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/variance_neon.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "./vpx_config.h" - -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" -#include "vpx_ports/mem.h" - -// Process a block of width 4 two rows at a time. -static INLINE void variance_4xh_neon(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - int h, uint32_t *sse, int *sum) { - int16x8_t sum_s16 = vdupq_n_s16(0); - int32x4_t sse_s32 = vdupq_n_s32(0); - int i = h; - - // Number of rows we can process before 'sum_s16' overflows: - // 32767 / 255 ~= 128, but we use an 8-wide accumulator; so 256 4-wide rows. - assert(h <= 256); - - do { - const uint8x8_t s = load_unaligned_u8(src_ptr, src_stride); - const uint8x8_t r = load_unaligned_u8(ref_ptr, ref_stride); - const int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(s, r)); - - sum_s16 = vaddq_s16(sum_s16, diff); - - sse_s32 = vmlal_s16(sse_s32, vget_low_s16(diff), vget_low_s16(diff)); - sse_s32 = vmlal_s16(sse_s32, vget_high_s16(diff), vget_high_s16(diff)); - - src_ptr += 2 * src_stride; - ref_ptr += 2 * ref_stride; - i -= 2; - } while (i != 0); - - *sum = horizontal_add_int16x8(sum_s16); - *sse = (uint32_t)horizontal_add_int32x4(sse_s32); -} - -// Process a block of width 8 one row at a time. -static INLINE void variance_8xh_neon(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - int h, uint32_t *sse, int *sum) { - int16x8_t sum_s16 = vdupq_n_s16(0); - int32x4_t sse_s32[2] = { vdupq_n_s32(0), vdupq_n_s32(0) }; - int i = h; - - // Number of rows we can process before 'sum_s16' overflows: - // 32767 / 255 ~= 128 - assert(h <= 128); - - do { - const uint8x8_t s = vld1_u8(src_ptr); - const uint8x8_t r = vld1_u8(ref_ptr); - const int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(s, r)); - - sum_s16 = vaddq_s16(sum_s16, diff); - - sse_s32[0] = vmlal_s16(sse_s32[0], vget_low_s16(diff), vget_low_s16(diff)); - sse_s32[1] = - vmlal_s16(sse_s32[1], vget_high_s16(diff), vget_high_s16(diff)); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--i != 0); - - *sum = horizontal_add_int16x8(sum_s16); - *sse = (uint32_t)horizontal_add_int32x4(vaddq_s32(sse_s32[0], sse_s32[1])); -} - -// Process a block of width 16 one row at a time. -static INLINE void variance_16xh_neon(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - int h, uint32_t *sse, int *sum) { - int16x8_t sum_s16[2] = { vdupq_n_s16(0), vdupq_n_s16(0) }; - int32x4_t sse_s32[2] = { vdupq_n_s32(0), vdupq_n_s32(0) }; - int i = h; - - // Number of rows we can process before 'sum_s16' accumulators overflow: - // 32767 / 255 ~= 128, so 128 16-wide rows. - assert(h <= 128); - - do { - const uint8x16_t s = vld1q_u8(src_ptr); - const uint8x16_t r = vld1q_u8(ref_ptr); - - const int16x8_t diff_l = - vreinterpretq_s16_u16(vsubl_u8(vget_low_u8(s), vget_low_u8(r))); - const int16x8_t diff_h = - vreinterpretq_s16_u16(vsubl_u8(vget_high_u8(s), vget_high_u8(r))); - - sum_s16[0] = vaddq_s16(sum_s16[0], diff_l); - sum_s16[1] = vaddq_s16(sum_s16[1], diff_h); - - sse_s32[0] = - vmlal_s16(sse_s32[0], vget_low_s16(diff_l), vget_low_s16(diff_l)); - sse_s32[1] = - vmlal_s16(sse_s32[1], vget_high_s16(diff_l), vget_high_s16(diff_l)); - sse_s32[0] = - vmlal_s16(sse_s32[0], vget_low_s16(diff_h), vget_low_s16(diff_h)); - sse_s32[1] = - vmlal_s16(sse_s32[1], vget_high_s16(diff_h), vget_high_s16(diff_h)); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--i != 0); - - *sum = horizontal_add_int16x8(vaddq_s16(sum_s16[0], sum_s16[1])); - *sse = (uint32_t)horizontal_add_int32x4(vaddq_s32(sse_s32[0], sse_s32[1])); -} - -// Process a block of any size where the width is divisible by 16. -static INLINE void variance_large_neon(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - int w, int h, int h_limit, - unsigned int *sse, int *sum) { - int32x4_t sum_s32 = vdupq_n_s32(0); - int32x4_t sse_s32[2] = { vdupq_n_s32(0), vdupq_n_s32(0) }; - - // 'h_limit' is the number of 'w'-width rows we can process before our 16-bit - // accumulator overflows. After hitting this limit we accumulate into 32-bit - // elements. - int h_tmp = h > h_limit ? h_limit : h; - - int i = 0; - do { - int16x8_t sum_s16[2] = { vdupq_n_s16(0), vdupq_n_s16(0) }; - do { - int j = 0; - do { - const uint8x16_t s = vld1q_u8(src_ptr + j); - const uint8x16_t r = vld1q_u8(ref_ptr + j); - - const int16x8_t diff_l = - vreinterpretq_s16_u16(vsubl_u8(vget_low_u8(s), vget_low_u8(r))); - const int16x8_t diff_h = - vreinterpretq_s16_u16(vsubl_u8(vget_high_u8(s), vget_high_u8(r))); - - sum_s16[0] = vaddq_s16(sum_s16[0], diff_l); - sum_s16[1] = vaddq_s16(sum_s16[1], diff_h); - - sse_s32[0] = - vmlal_s16(sse_s32[0], vget_low_s16(diff_l), vget_low_s16(diff_l)); - sse_s32[1] = - vmlal_s16(sse_s32[1], vget_high_s16(diff_l), vget_high_s16(diff_l)); - sse_s32[0] = - vmlal_s16(sse_s32[0], vget_low_s16(diff_h), vget_low_s16(diff_h)); - sse_s32[1] = - vmlal_s16(sse_s32[1], vget_high_s16(diff_h), vget_high_s16(diff_h)); - - j += 16; - } while (j < w); - - src_ptr += src_stride; - ref_ptr += ref_stride; - i++; - } while (i < h_tmp); - - sum_s32 = vpadalq_s16(sum_s32, sum_s16[0]); - sum_s32 = vpadalq_s16(sum_s32, sum_s16[1]); - - h_tmp += h_limit; - } while (i < h); - - *sum = horizontal_add_int32x4(sum_s32); - *sse = (uint32_t)horizontal_add_int32x4(vaddq_s32(sse_s32[0], sse_s32[1])); -} - -static INLINE void variance_32xh_neon(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, int h, - uint32_t *sse, int *sum) { - variance_large_neon(src, src_stride, ref, ref_stride, 32, h, 64, sse, sum); -} - -static INLINE void variance_64xh_neon(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, int h, - uint32_t *sse, int *sum) { - variance_large_neon(src, src_stride, ref, ref_stride, 64, h, 32, sse, sum); -} - -void vpx_get8x8var_neon(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse, int *sum) { - variance_8xh_neon(src_ptr, src_stride, ref_ptr, ref_stride, 8, sse, sum); -} - -void vpx_get16x16var_neon(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse, int *sum) { - variance_16xh_neon(src_ptr, src_stride, ref_ptr, ref_stride, 16, sse, sum); -} - -#define VARIANCE_WXH_NEON(w, h, shift) \ - unsigned int vpx_variance##w##x##h##_neon( \ - const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride, \ - unsigned int *sse) { \ - int sum; \ - variance_##w##xh_neon(src, src_stride, ref, ref_stride, h, sse, &sum); \ - return *sse - (uint32_t)(((int64_t)sum * sum) >> shift); \ - } - -VARIANCE_WXH_NEON(4, 4, 4) -VARIANCE_WXH_NEON(4, 8, 5) - -VARIANCE_WXH_NEON(8, 4, 5) -VARIANCE_WXH_NEON(8, 8, 6) -VARIANCE_WXH_NEON(8, 16, 7) - -VARIANCE_WXH_NEON(16, 8, 7) -VARIANCE_WXH_NEON(16, 16, 8) -VARIANCE_WXH_NEON(16, 32, 9) - -VARIANCE_WXH_NEON(32, 16, 9) -VARIANCE_WXH_NEON(32, 32, 10) -VARIANCE_WXH_NEON(32, 64, 11) - -VARIANCE_WXH_NEON(64, 32, 11) -VARIANCE_WXH_NEON(64, 64, 12) - -#undef VARIANCE_WXH_NEON - -static INLINE unsigned int vpx_mse8xh_neon(const unsigned char *src_ptr, - int src_stride, - const unsigned char *ref_ptr, - int ref_stride, int h) { - uint32x4_t sse_u32[2] = { vdupq_n_u32(0), vdupq_n_u32(0) }; - - int i = h / 2; - do { - uint8x8_t s0, s1, r0, r1, diff0, diff1; - uint16x8_t sse0, sse1; - - s0 = vld1_u8(src_ptr); - src_ptr += src_stride; - s1 = vld1_u8(src_ptr); - src_ptr += src_stride; - r0 = vld1_u8(ref_ptr); - ref_ptr += ref_stride; - r1 = vld1_u8(ref_ptr); - ref_ptr += ref_stride; - - diff0 = vabd_u8(s0, r0); - diff1 = vabd_u8(s1, r1); - - sse0 = vmull_u8(diff0, diff0); - sse_u32[0] = vpadalq_u16(sse_u32[0], sse0); - sse1 = vmull_u8(diff1, diff1); - sse_u32[1] = vpadalq_u16(sse_u32[1], sse1); - } while (--i != 0); - - return horizontal_add_uint32x4(vaddq_u32(sse_u32[0], sse_u32[1])); -} - -static INLINE unsigned int vpx_mse16xh_neon(const unsigned char *src_ptr, - int src_stride, - const unsigned char *ref_ptr, - int ref_stride, int h) { - uint32x4_t sse_u32[2] = { vdupq_n_u32(0), vdupq_n_u32(0) }; - - int i = h; - do { - uint8x16_t s, r, diff; - uint16x8_t sse0, sse1; - - s = vld1q_u8(src_ptr); - src_ptr += src_stride; - r = vld1q_u8(ref_ptr); - ref_ptr += ref_stride; - - diff = vabdq_u8(s, r); - - sse0 = vmull_u8(vget_low_u8(diff), vget_low_u8(diff)); - sse_u32[0] = vpadalq_u16(sse_u32[0], sse0); - sse1 = vmull_u8(vget_high_u8(diff), vget_high_u8(diff)); - sse_u32[1] = vpadalq_u16(sse_u32[1], sse1); - } while (--i != 0); - - return horizontal_add_uint32x4(vaddq_u32(sse_u32[0], sse_u32[1])); -} - -unsigned int vpx_get4x4sse_cs_neon(const unsigned char *src_ptr, int src_stride, - const unsigned char *ref_ptr, - int ref_stride) { - uint8x8_t s[2], r[2]; - uint16x8_t abs_diff[2]; - uint32x4_t sse; - - s[0] = load_u8(src_ptr, src_stride); - r[0] = load_u8(ref_ptr, ref_stride); - src_ptr += 2 * src_stride; - ref_ptr += 2 * ref_stride; - s[1] = load_u8(src_ptr, src_stride); - r[1] = load_u8(ref_ptr, ref_stride); - - abs_diff[0] = vabdl_u8(s[0], r[0]); - abs_diff[1] = vabdl_u8(s[1], r[1]); - - sse = vmull_u16(vget_low_u16(abs_diff[0]), vget_low_u16(abs_diff[0])); - sse = vmlal_u16(sse, vget_high_u16(abs_diff[0]), vget_high_u16(abs_diff[0])); - sse = vmlal_u16(sse, vget_low_u16(abs_diff[1]), vget_low_u16(abs_diff[1])); - sse = vmlal_u16(sse, vget_high_u16(abs_diff[1]), vget_high_u16(abs_diff[1])); - - return horizontal_add_uint32x4(sse); -} - -#define VPX_MSE_WXH_NEON(w, h) \ - unsigned int vpx_mse##w##x##h##_neon( \ - const unsigned char *src_ptr, int src_stride, \ - const unsigned char *ref_ptr, int ref_stride, unsigned int *sse) { \ - *sse = vpx_mse##w##xh_neon(src_ptr, src_stride, ref_ptr, ref_stride, h); \ - return *sse; \ - } - -VPX_MSE_WXH_NEON(8, 8) -VPX_MSE_WXH_NEON(8, 16) -VPX_MSE_WXH_NEON(16, 8) -VPX_MSE_WXH_NEON(16, 16) - -#undef VPX_MSE_WXH_NEON diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/variance_neon_dotprod.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/variance_neon_dotprod.c deleted file mode 100644 index ab843e9f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/variance_neon_dotprod.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (c) 2021 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "./vpx_config.h" - -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/sum_neon.h" -#include "vpx_ports/mem.h" - -// Process a block of width 4 four rows at a time. -static INLINE void variance_4xh_neon_dotprod(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h, - uint32_t *sse, int *sum) { - uint32x4_t src_sum = vdupq_n_u32(0); - uint32x4_t ref_sum = vdupq_n_u32(0); - uint32x4_t sse_u32 = vdupq_n_u32(0); - - int i = h; - do { - const uint8x16_t s = load_unaligned_u8q(src_ptr, src_stride); - const uint8x16_t r = load_unaligned_u8q(ref_ptr, ref_stride); - - const uint8x16_t abs_diff = vabdq_u8(s, r); - sse_u32 = vdotq_u32(sse_u32, abs_diff, abs_diff); - - src_sum = vdotq_u32(src_sum, s, vdupq_n_u8(1)); - ref_sum = vdotq_u32(ref_sum, r, vdupq_n_u8(1)); - - src_ptr += 4 * src_stride; - ref_ptr += 4 * ref_stride; - i -= 4; - } while (i != 0); - - *sum = horizontal_add_int32x4( - vreinterpretq_s32_u32(vsubq_u32(src_sum, ref_sum))); - *sse = horizontal_add_uint32x4(sse_u32); -} - -// Process a block of width 8 two rows at a time. -static INLINE void variance_8xh_neon_dotprod(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h, - uint32_t *sse, int *sum) { - uint32x4_t src_sum = vdupq_n_u32(0); - uint32x4_t ref_sum = vdupq_n_u32(0); - uint32x4_t sse_u32 = vdupq_n_u32(0); - - int i = h; - do { - const uint8x16_t s = - vcombine_u8(vld1_u8(src_ptr), vld1_u8(src_ptr + src_stride)); - const uint8x16_t r = - vcombine_u8(vld1_u8(ref_ptr), vld1_u8(ref_ptr + ref_stride)); - - const uint8x16_t abs_diff = vabdq_u8(s, r); - sse_u32 = vdotq_u32(sse_u32, abs_diff, abs_diff); - - src_sum = vdotq_u32(src_sum, s, vdupq_n_u8(1)); - ref_sum = vdotq_u32(ref_sum, r, vdupq_n_u8(1)); - - src_ptr += 2 * src_stride; - ref_ptr += 2 * ref_stride; - i -= 2; - } while (i != 0); - - *sum = horizontal_add_int32x4( - vreinterpretq_s32_u32(vsubq_u32(src_sum, ref_sum))); - *sse = horizontal_add_uint32x4(sse_u32); -} - -// Process a block of width 16 one row at a time. -static INLINE void variance_16xh_neon_dotprod(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int h, - uint32_t *sse, int *sum) { - uint32x4_t src_sum = vdupq_n_u32(0); - uint32x4_t ref_sum = vdupq_n_u32(0); - uint32x4_t sse_u32 = vdupq_n_u32(0); - - int i = h; - do { - const uint8x16_t s = vld1q_u8(src_ptr); - const uint8x16_t r = vld1q_u8(ref_ptr); - - const uint8x16_t abs_diff = vabdq_u8(s, r); - sse_u32 = vdotq_u32(sse_u32, abs_diff, abs_diff); - - src_sum = vdotq_u32(src_sum, s, vdupq_n_u8(1)); - ref_sum = vdotq_u32(ref_sum, r, vdupq_n_u8(1)); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--i != 0); - - *sum = horizontal_add_int32x4( - vreinterpretq_s32_u32(vsubq_u32(src_sum, ref_sum))); - *sse = horizontal_add_uint32x4(sse_u32); -} - -// Process a block of any size where the width is divisible by 16. -static INLINE void variance_large_neon_dotprod(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, int w, int h, - uint32_t *sse, int *sum) { - uint32x4_t src_sum = vdupq_n_u32(0); - uint32x4_t ref_sum = vdupq_n_u32(0); - uint32x4_t sse_u32 = vdupq_n_u32(0); - - int i = h; - do { - int j = 0; - do { - const uint8x16_t s = vld1q_u8(src_ptr + j); - const uint8x16_t r = vld1q_u8(ref_ptr + j); - - const uint8x16_t abs_diff = vabdq_u8(s, r); - sse_u32 = vdotq_u32(sse_u32, abs_diff, abs_diff); - - src_sum = vdotq_u32(src_sum, s, vdupq_n_u8(1)); - ref_sum = vdotq_u32(ref_sum, r, vdupq_n_u8(1)); - - j += 16; - } while (j < w); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } while (--i != 0); - - *sum = horizontal_add_int32x4( - vreinterpretq_s32_u32(vsubq_u32(src_sum, ref_sum))); - *sse = horizontal_add_uint32x4(sse_u32); -} - -static INLINE void variance_32xh_neon_dotprod(const uint8_t *src, - int src_stride, - const uint8_t *ref, - int ref_stride, int h, - uint32_t *sse, int *sum) { - variance_large_neon_dotprod(src, src_stride, ref, ref_stride, 32, h, sse, - sum); -} - -static INLINE void variance_64xh_neon_dotprod(const uint8_t *src, - int src_stride, - const uint8_t *ref, - int ref_stride, int h, - uint32_t *sse, int *sum) { - variance_large_neon_dotprod(src, src_stride, ref, ref_stride, 64, h, sse, - sum); -} - -void vpx_get8x8var_neon_dotprod(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse, int *sum) { - variance_8xh_neon_dotprod(src_ptr, src_stride, ref_ptr, ref_stride, 8, sse, - sum); -} - -void vpx_get16x16var_neon_dotprod(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse, int *sum) { - variance_16xh_neon_dotprod(src_ptr, src_stride, ref_ptr, ref_stride, 16, sse, - sum); -} - -#define VARIANCE_WXH_NEON_DOTPROD(w, h, shift) \ - unsigned int vpx_variance##w##x##h##_neon_dotprod( \ - const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride, \ - unsigned int *sse) { \ - int sum; \ - variance_##w##xh_neon_dotprod(src, src_stride, ref, ref_stride, h, sse, \ - &sum); \ - return *sse - (uint32_t)(((int64_t)sum * sum) >> shift); \ - } - -VARIANCE_WXH_NEON_DOTPROD(4, 4, 4) -VARIANCE_WXH_NEON_DOTPROD(4, 8, 5) - -VARIANCE_WXH_NEON_DOTPROD(8, 4, 5) -VARIANCE_WXH_NEON_DOTPROD(8, 8, 6) -VARIANCE_WXH_NEON_DOTPROD(8, 16, 7) - -VARIANCE_WXH_NEON_DOTPROD(16, 8, 7) -VARIANCE_WXH_NEON_DOTPROD(16, 16, 8) -VARIANCE_WXH_NEON_DOTPROD(16, 32, 9) - -VARIANCE_WXH_NEON_DOTPROD(32, 16, 9) -VARIANCE_WXH_NEON_DOTPROD(32, 32, 10) -VARIANCE_WXH_NEON_DOTPROD(32, 64, 11) - -VARIANCE_WXH_NEON_DOTPROD(64, 32, 11) -VARIANCE_WXH_NEON_DOTPROD(64, 64, 12) - -#undef VARIANCE_WXH_NEON_DOTPROD - -static INLINE unsigned int vpx_mse8xh_neon_dotprod(const unsigned char *src_ptr, - int src_stride, - const unsigned char *ref_ptr, - int ref_stride, int h) { - uint32x2_t sse_u32[2] = { vdup_n_u32(0), vdup_n_u32(0) }; - - int i = h / 2; - do { - uint8x8_t s0, s1, r0, r1, diff0, diff1; - - s0 = vld1_u8(src_ptr); - src_ptr += src_stride; - s1 = vld1_u8(src_ptr); - src_ptr += src_stride; - r0 = vld1_u8(ref_ptr); - ref_ptr += ref_stride; - r1 = vld1_u8(ref_ptr); - ref_ptr += ref_stride; - - diff0 = vabd_u8(s0, r0); - diff1 = vabd_u8(s1, r1); - - sse_u32[0] = vdot_u32(sse_u32[0], diff0, diff0); - sse_u32[1] = vdot_u32(sse_u32[1], diff1, diff1); - } while (--i != 0); - - return horizontal_add_uint32x2(vadd_u32(sse_u32[0], sse_u32[1])); -} - -static INLINE unsigned int vpx_mse16xh_neon_dotprod( - const unsigned char *src_ptr, int src_stride, const unsigned char *ref_ptr, - int ref_stride, int h) { - uint32x4_t sse_u32[2] = { vdupq_n_u32(0), vdupq_n_u32(0) }; - - int i = h / 2; - do { - uint8x16_t s0, s1, r0, r1, diff0, diff1; - - s0 = vld1q_u8(src_ptr); - src_ptr += src_stride; - s1 = vld1q_u8(src_ptr); - src_ptr += src_stride; - r0 = vld1q_u8(ref_ptr); - ref_ptr += ref_stride; - r1 = vld1q_u8(ref_ptr); - ref_ptr += ref_stride; - - diff0 = vabdq_u8(s0, r0); - diff1 = vabdq_u8(s1, r1); - - sse_u32[0] = vdotq_u32(sse_u32[0], diff0, diff0); - sse_u32[1] = vdotq_u32(sse_u32[1], diff1, diff1); - } while (--i != 0); - - return horizontal_add_uint32x4(vaddq_u32(sse_u32[0], sse_u32[1])); -} - -unsigned int vpx_get4x4sse_cs_neon_dotprod(const unsigned char *src_ptr, - int src_stride, - const unsigned char *ref_ptr, - int ref_stride) { - uint8x16_t s = load_unaligned_u8q(src_ptr, src_stride); - uint8x16_t r = load_unaligned_u8q(ref_ptr, ref_stride); - - uint8x16_t abs_diff = vabdq_u8(s, r); - - uint32x4_t sse = vdotq_u32(vdupq_n_u32(0), abs_diff, abs_diff); - - return horizontal_add_uint32x4(sse); -} - -#define VPX_MSE_WXH_NEON_DOTPROD(w, h) \ - unsigned int vpx_mse##w##x##h##_neon_dotprod( \ - const unsigned char *src_ptr, int src_stride, \ - const unsigned char *ref_ptr, int ref_stride, unsigned int *sse) { \ - *sse = vpx_mse##w##xh_neon_dotprod(src_ptr, src_stride, ref_ptr, \ - ref_stride, h); \ - return *sse; \ - } - -VPX_MSE_WXH_NEON_DOTPROD(8, 8) -VPX_MSE_WXH_NEON_DOTPROD(8, 16) -VPX_MSE_WXH_NEON_DOTPROD(16, 8) -VPX_MSE_WXH_NEON_DOTPROD(16, 16) - -#undef VPX_MSE_WXH_NEON_DOTPROD diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_avg_horiz_filter_type1_neon.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_avg_horiz_filter_type1_neon.asm deleted file mode 100644 index d8e4bcc3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_avg_horiz_filter_type1_neon.asm +++ /dev/null @@ -1,438 +0,0 @@ -; -; Copyright (c) 2018 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; -;**************Variables Vs Registers***************************************** -; r0 => src -; r1 => dst -; r2 => src_stride -; r3 => dst_stride -; r4 => filter_x0 -; r8 => ht -; r10 => wd - - EXPORT |vpx_convolve8_avg_horiz_filter_type1_neon| - ARM - REQUIRE8 - PRESERVE8 - - AREA ||.text||, CODE, READONLY, ALIGN=2 - -|vpx_convolve8_avg_horiz_filter_type1_neon| PROC - - stmfd sp!, {r4 - r12, r14} ;stack stores the values of - ; the arguments - vpush {d8 - d15} ; stack offset by 64 - mov r4, r1 - mov r1, r2 - mov r2, r4 - -start_loop_count - ldr r4, [sp, #104] ;loads pi1_coeff - ldr r8, [sp, #108] ;loads x0_q4 - add r4, r4, r8, lsl #4 ;r4 = filter[x0_q4] - ldr r8, [sp, #128] ;loads ht - ldr r10, [sp, #124] ;loads wd - vld2.8 {d0, d1}, [r4] ;coeff = vld1_s8(pi1_coeff) - mov r11, #1 - subs r14, r8, #0 ;checks for ht == 0 - vabs.s8 d2, d0 ;vabs_s8(coeff) - vdup.8 d24, d2[0] ;coeffabs_0 = vdup_lane_u8(coeffabs, - ; 0) - sub r12, r0, #3 ;pu1_src - 3 - vdup.8 d25, d2[1] ;coeffabs_1 = vdup_lane_u8(coeffabs, - ; 1) - add r4, r12, r2 ;pu1_src_tmp2_8 = pu1_src + src_strd - vdup.8 d26, d2[2] ;coeffabs_2 = vdup_lane_u8(coeffabs, - ; 2) - rsb r9, r10, r2, lsl #1 ;2*src_strd - wd - vdup.8 d27, d2[3] ;coeffabs_3 = vdup_lane_u8(coeffabs, - ; 3) - rsb r8, r10, r3, lsl #1 ;2*dst_strd - wd - vdup.8 d28, d2[4] ;coeffabs_4 = vdup_lane_u8(coeffabs, - ; 4) - vdup.8 d29, d2[5] ;coeffabs_5 = vdup_lane_u8(coeffabs, - ; 5) - vdup.8 d30, d2[6] ;coeffabs_6 = vdup_lane_u8(coeffabs, - ; 6) - vdup.8 d31, d2[7] ;coeffabs_7 = vdup_lane_u8(coeffabs, - ; 7) - mov r7, r1 - cmp r10, #4 - ble outer_loop_4 - - cmp r10, #24 - moveq r10, #16 - addeq r8, #8 - addeq r9, #8 - cmp r10, #16 - bge outer_loop_16 - - cmp r10, #12 - addeq r8, #4 - addeq r9, #4 - b outer_loop_8 - -outer_loop8_residual - sub r12, r0, #3 ;pu1_src - 3 - mov r1, r7 - mov r14, #32 - add r1, #16 - add r12, #16 - mov r10, #8 - add r8, #8 - add r9, #8 - -outer_loop_8 - add r6, r1, r3 ;pu1_dst + dst_strd - add r4, r12, r2 ;pu1_src + src_strd - subs r5, r10, #0 ;checks wd - ble end_inner_loop_8 - -inner_loop_8 - mov r7, #0xc000 - vld1.u32 {d0}, [r12], r11 ;vector load pu1_src - vdup.16 q4, r7 - vld1.u32 {d1}, [r12], r11 - vdup.16 q5, r7 - vld1.u32 {d2}, [r12], r11 - vld1.u32 {d3}, [r12], r11 - mov r7, #0x4000 - vld1.u32 {d4}, [r12], r11 - vmlsl.u8 q4, d1, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vld1.u32 {d5}, [r12], r11 - vmlal.u8 q4, d3, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - vld1.u32 {d6}, [r12], r11 - vmlsl.u8 q4, d0, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vld1.u32 {d7}, [r12], r11 - vmlal.u8 q4, d2, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vld1.u32 {d12}, [r4], r11 ;vector load pu1_src + src_strd - vmlal.u8 q4, d4, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vld1.u32 {d13}, [r4], r11 - vmlal.u8 q4, d5, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vld1.u32 {d14}, [r4], r11 - vmlsl.u8 q4, d6, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vld1.u32 {d15}, [r4], r11 - vmlsl.u8 q4, d7, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - vld1.u32 {d16}, [r4], r11 ;vector load pu1_src + src_strd - vdup.16 q11, r7 - vmlal.u8 q5, d15, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - vld1.u32 {d17}, [r4], r11 - vmlal.u8 q5, d14, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vhadd.s16 q4, q4, q11 - vld1.u32 {d18}, [r4], r11 - vmlal.u8 q5, d16, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vld1.u32 {d19}, [r4], r11 ;vector load pu1_src + src_strd - vmlal.u8 q5, d17, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vld1.u8 {d6}, [r1] - vqrshrun.s16 d20, q4, #6 ;right shift and saturating narrow - ; result 1 - vmlsl.u8 q5, d18, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vmlsl.u8 q5, d19, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - vld1.u8 {d7}, [r6] - vrhadd.u8 d20, d20, d6 - vmlsl.u8 q5, d12, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vmlsl.u8 q5, d13, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vst1.8 {d20}, [r1]! ;store the result pu1_dst - vhadd.s16 q5, q5, q11 - subs r5, r5, #8 ;decrement the wd loop - vqrshrun.s16 d8, q5, #6 ;right shift and saturating narrow - ; result 2 - vrhadd.u8 d8, d8, d7 - vst1.8 {d8}, [r6]! ;store the result pu1_dst - cmp r5, #4 - bgt inner_loop_8 - -end_inner_loop_8 - subs r14, r14, #2 ;decrement the ht loop - add r12, r12, r9 ;increment the src pointer by - ; 2*src_strd-wd - add r1, r1, r8 ;increment the dst pointer by - ; 2*dst_strd-wd - bgt outer_loop_8 - - ldr r10, [sp, #120] ;loads wd - cmp r10, #12 - beq outer_loop4_residual - -end_loops - b end_func - -outer_loop_16 - str r0, [sp, #-4]! - str r7, [sp, #-4]! - add r6, r1, r3 ;pu1_dst + dst_strd - add r4, r12, r2 ;pu1_src + src_strd - and r0, r12, #31 - mov r7, #0xc000 - sub r5, r10, #0 ;checks wd - pld [r4, r2, lsl #1] - pld [r12, r2, lsl #1] - vld1.u32 {q0}, [r12], r11 ;vector load pu1_src - vdup.16 q4, r7 - vld1.u32 {q1}, [r12], r11 - vld1.u32 {q2}, [r12], r11 - vld1.u32 {q3}, [r12], r11 - vmlsl.u8 q4, d0, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vld1.u32 {q6}, [r12], r11 - vmlsl.u8 q4, d2, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vld1.u32 {q7}, [r12], r11 - vmlal.u8 q4, d4, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vld1.u32 {q8}, [r12], r11 - vmlal.u8 q4, d6, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - vld1.u32 {q9}, [r12], r11 - vmlal.u8 q4, d12, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vmlal.u8 q4, d14, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vdup.16 q10, r7 - vmlsl.u8 q4, d16, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vmlsl.u8 q4, d18, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - -inner_loop_16 - vmlsl.u8 q10, d1, d24 - vdup.16 q5, r7 - vmlsl.u8 q10, d3, d25 - mov r7, #0x4000 - vdup.16 q11, r7 - vmlal.u8 q10, d5, d26 - vld1.u32 {q0}, [r4], r11 ;vector load pu1_src - vhadd.s16 q4, q4, q11 - vld1.u32 {q1}, [r4], r11 - vmlal.u8 q10, d7, d27 - add r12, #8 - subs r5, r5, #16 - vmlal.u8 q10, d13, d28 - vld1.u32 {q2}, [r4], r11 - vmlal.u8 q10, d15, d29 - vld1.u32 {q3}, [r4], r11 - vqrshrun.s16 d8, q4, #6 ;right shift and saturating narrow - ; result 1 - vmlsl.u8 q10, d17, d30 - vld1.u32 {q6}, [r4], r11 - vmlsl.u8 q10, d19, d31 - vld1.u32 {q7}, [r4], r11 - add r7, r1, #8 - vmlsl.u8 q5, d0, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vmlsl.u8 q5, d2, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vld1.u32 {q8}, [r4], r11 - vhadd.s16 q10, q10, q11 - vld1.u32 {q9}, [r4], r11 - vld1.u8 {d0}, [r1] - vmlal.u8 q5, d4, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vld1.u8 {d2}, [r7] - vmlal.u8 q5, d6, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - add r4, #8 - mov r7, #0xc000 - vmlal.u8 q5, d12, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vmlal.u8 q5, d14, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vqrshrun.s16 d9, q10, #6 - vdup.16 q11, r7 - vmlsl.u8 q5, d16, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vmlsl.u8 q5, d18, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - mov r7, #0x4000 - vrhadd.u8 d8, d8, d0 - vrhadd.u8 d9, d9, d2 - vmlsl.u8 q11, d1, d24 - vmlsl.u8 q11, d3, d25 - vdup.16 q10, r7 - vmlal.u8 q11, d5, d26 - pld [r12, r2, lsl #2] - pld [r4, r2, lsl #2] - addeq r12, r12, r9 ;increment the src pointer by - ; 2*src_strd-wd - addeq r4, r12, r2 ;pu1_src + src_strd - vmlal.u8 q11, d7, d27 - vmlal.u8 q11, d13, d28 - vst1.8 {q4}, [r1]! ;store the result pu1_dst - subeq r14, r14, #2 - vhadd.s16 q5, q5, q10 - vmlal.u8 q11, d15, d29 - addeq r1, r1, r8 - vmlsl.u8 q11, d17, d30 - cmp r14, #0 - vmlsl.u8 q11, d19, d31 - vqrshrun.s16 d10, q5, #6 ;right shift and saturating narrow - ; result 2 - beq epilog_16 - - vld1.u32 {q0}, [r12], r11 ;vector load pu1_src - mov r7, #0xc000 - cmp r5, #0 - vld1.u32 {q1}, [r12], r11 - vhadd.s16 q11, q11, q10 - vld1.u32 {q2}, [r12], r11 - vdup.16 q4, r7 - vmlsl.u8 q4, d0, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vdup.16 q10, r7 - vld1.u32 {q3}, [r12], r11 - add r7, r6, #8 - moveq r5, r10 - vld1.u8 {d0}, [r6] - vmlsl.u8 q4, d2, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vld1.u8 {d2}, [r7] - vqrshrun.s16 d11, q11, #6 - vmlal.u8 q4, d4, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vld1.u32 {q6}, [r12], r11 - vrhadd.u8 d10, d10, d0 - vld1.u32 {q7}, [r12], r11 - vrhadd.u8 d11, d11, d2 - vld1.u32 {q8}, [r12], r11 - vmlal.u8 q4, d6, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - vld1.u32 {q9}, [r12], r11 - vmlal.u8 q4, d12, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vmlal.u8 q4, d14, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - mov r7, #0xc000 - vmlsl.u8 q4, d16, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vst1.8 {q5}, [r6]! ;store the result pu1_dst - vmlsl.u8 q4, d18, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - addeq r6, r1, r3 ;pu1_dst + dst_strd - b inner_loop_16 - -epilog_16 - mov r7, #0x4000 - ldr r0, [sp], #4 - ldr r10, [sp, #120] - vdup.16 q10, r7 - vhadd.s16 q11, q11, q10 - vqrshrun.s16 d11, q11, #6 - add r7, r6, #8 - vld1.u8 {d20}, [r6] - vld1.u8 {d21}, [r7] - vrhadd.u8 d10, d10, d20 - vrhadd.u8 d11, d11, d21 - vst1.8 {q5}, [r6]! ;store the result pu1_dst - ldr r7, [sp], #4 - cmp r10, #24 - beq outer_loop8_residual - -end_loops1 - b end_func - -outer_loop4_residual - sub r12, r0, #3 ;pu1_src - 3 - mov r1, r7 - add r1, #8 - mov r10, #4 - add r12, #8 - mov r14, #16 - add r8, #4 - add r9, #4 - -outer_loop_4 - add r6, r1, r3 ;pu1_dst + dst_strd - add r4, r12, r2 ;pu1_src + src_strd - subs r5, r10, #0 ;checks wd - ble end_inner_loop_4 - -inner_loop_4 - vld1.u32 {d0}, [r12], r11 ;vector load pu1_src - vld1.u32 {d1}, [r12], r11 - vld1.u32 {d2}, [r12], r11 - vld1.u32 {d3}, [r12], r11 - vld1.u32 {d4}, [r12], r11 - vld1.u32 {d5}, [r12], r11 - vld1.u32 {d6}, [r12], r11 - vld1.u32 {d7}, [r12], r11 - sub r12, r12, #4 - vld1.u32 {d12}, [r4], r11 ;vector load pu1_src + src_strd - vld1.u32 {d13}, [r4], r11 - vzip.32 d0, d12 ;vector zip the i iteration and ii - ; interation in single register - vld1.u32 {d14}, [r4], r11 - vzip.32 d1, d13 - vld1.u32 {d15}, [r4], r11 - vzip.32 d2, d14 - vld1.u32 {d16}, [r4], r11 - vzip.32 d3, d15 - vld1.u32 {d17}, [r4], r11 - vzip.32 d4, d16 - vld1.u32 {d18}, [r4], r11 - vzip.32 d5, d17 - vld1.u32 {d19}, [r4], r11 - mov r7, #0xc000 - vdup.16 q4, r7 - sub r4, r4, #4 - vzip.32 d6, d18 - vzip.32 d7, d19 - vmlsl.u8 q4, d1, d25 ;arithmetic operations for ii - ; iteration in the same time - vmlsl.u8 q4, d0, d24 - vmlal.u8 q4, d2, d26 - vmlal.u8 q4, d3, d27 - vmlal.u8 q4, d4, d28 - vmlal.u8 q4, d5, d29 - vmlsl.u8 q4, d6, d30 - vmlsl.u8 q4, d7, d31 - mov r7, #0x4000 - vdup.16 q10, r7 - vhadd.s16 q4, q4, q10 - vqrshrun.s16 d8, q4, #6 - vld1.u32 {d10[0]}, [r1] - vld1.u32 {d10[1]}, [r6] - vrhadd.u8 d8, d8, d10 - vst1.32 {d8[0]},[r1]! ;store the i iteration result which - ; is in upper part of the register - vst1.32 {d8[1]},[r6]! ;store the ii iteration result which - ; is in lower part of the register - subs r5, r5, #4 ;decrement the wd by 4 - bgt inner_loop_4 - -end_inner_loop_4 - subs r14, r14, #2 ;decrement the ht by 4 - add r12, r12, r9 ;increment the input pointer - ; 2*src_strd-wd - add r1, r1, r8 ;increment the output pointer - ; 2*dst_strd-wd - bgt outer_loop_4 - -end_func - vpop {d8 - d15} - ldmfd sp!, {r4 - r12, r15} ;reload the registers from sp - - ENDP - - END diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_avg_horiz_filter_type2_neon.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_avg_horiz_filter_type2_neon.asm deleted file mode 100644 index 7a77747f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_avg_horiz_filter_type2_neon.asm +++ /dev/null @@ -1,439 +0,0 @@ -; -; Copyright (c) 2018 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; -;**************Variables Vs Registers*********************************** -; r0 => src -; r1 => dst -; r2 => src_stride -; r3 => dst_stride -; r4 => filter_x0 -; r8 => ht -; r10 => wd - - EXPORT |vpx_convolve8_avg_horiz_filter_type2_neon| - ARM - REQUIRE8 - PRESERVE8 - - AREA ||.text||, CODE, READONLY, ALIGN=2 - -|vpx_convolve8_avg_horiz_filter_type2_neon| PROC - - stmfd sp!, {r4 - r12, r14} ;stack stores the values of - ; the arguments - vpush {d8 - d15} ; stack offset by 64 - mov r4, r1 - mov r1, r2 - mov r2, r4 - -start_loop_count - ldr r4, [sp, #104] ;loads pi1_coeff - ldr r8, [sp, #108] ;loads x0_q4 - add r4, r4, r8, lsl #4 ;r4 = filter[x0_q4] - ldr r8, [sp, #128] ;loads ht - ldr r10, [sp, #124] ;loads wd - vld2.8 {d0, d1}, [r4] ;coeff = vld1_s8(pi1_coeff) - mov r11, #1 - subs r14, r8, #0 ;checks for ht == 0 - vabs.s8 d2, d0 ;vabs_s8(coeff) - vdup.8 d24, d2[0] ;coeffabs_0 = vdup_lane_u8(coeffabs, - ; 0) - sub r12, r0, #3 ;pu1_src - 3 - vdup.8 d25, d2[1] ;coeffabs_1 = vdup_lane_u8(coeffabs, - ; 1) - add r4, r12, r2 ;pu1_src_tmp2_8 = pu1_src + src_strd - vdup.8 d26, d2[2] ;coeffabs_2 = vdup_lane_u8(coeffabs, - ; 2) - rsb r9, r10, r2, lsl #1 ;2*src_strd - wd - vdup.8 d27, d2[3] ;coeffabs_3 = vdup_lane_u8(coeffabs, - ; 3) - rsb r8, r10, r3, lsl #1 ;2*dst_strd - wd - vdup.8 d28, d2[4] ;coeffabs_4 = vdup_lane_u8(coeffabs, - ; 4) - vdup.8 d29, d2[5] ;coeffabs_5 = vdup_lane_u8(coeffabs, - ; 5) - vdup.8 d30, d2[6] ;coeffabs_6 = vdup_lane_u8(coeffabs, - ; 6) - vdup.8 d31, d2[7] ;coeffabs_7 = vdup_lane_u8(coeffabs, - ; 7) - mov r7, r1 - cmp r10, #4 - ble outer_loop_4 - - cmp r10, #24 - moveq r10, #16 - addeq r8, #8 - addeq r9, #8 - cmp r10, #16 - bge outer_loop_16 - - cmp r10, #12 - addeq r8, #4 - addeq r9, #4 - b outer_loop_8 - -outer_loop8_residual - sub r12, r0, #3 ;pu1_src - 3 - mov r1, r7 - mov r14, #32 - add r1, #16 - add r12, #16 - mov r10, #8 - add r8, #8 - add r9, #8 - -outer_loop_8 - - add r6, r1, r3 ;pu1_dst + dst_strd - add r4, r12, r2 ;pu1_src + src_strd - subs r5, r10, #0 ;checks wd - ble end_inner_loop_8 - -inner_loop_8 - mov r7, #0xc000 - vld1.u32 {d0}, [r12], r11 ;vector load pu1_src - vdup.16 q4, r7 - vld1.u32 {d1}, [r12], r11 - vdup.16 q5, r7 - vld1.u32 {d2}, [r12], r11 - vld1.u32 {d3}, [r12], r11 - mov r7, #0x4000 - vld1.u32 {d4}, [r12], r11 - vmlal.u8 q4, d1, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vld1.u32 {d5}, [r12], r11 - vmlal.u8 q4, d3, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - vld1.u32 {d6}, [r12], r11 - vmlsl.u8 q4, d0, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vld1.u32 {d7}, [r12], r11 - vmlsl.u8 q4, d2, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vld1.u32 {d12}, [r4], r11 ;vector load pu1_src + src_strd - vmlal.u8 q4, d4, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vld1.u32 {d13}, [r4], r11 - vmlsl.u8 q4, d5, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vld1.u32 {d14}, [r4], r11 - vmlal.u8 q4, d6, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vld1.u32 {d15}, [r4], r11 - vmlsl.u8 q4, d7, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - vld1.u32 {d16}, [r4], r11 ;vector load pu1_src + src_strd - vdup.16 q11, r7 - vmlal.u8 q5, d15, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - vld1.u32 {d17}, [r4], r11 - vmlsl.u8 q5, d14, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vhadd.s16 q4, q4, q11 - vld1.u32 {d18}, [r4], r11 - vmlal.u8 q5, d16, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vld1.u32 {d19}, [r4], r11 ;vector load pu1_src + src_strd - vmlsl.u8 q5, d17, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vld1.u8 {d6}, [r1] - vqrshrun.s16 d20, q4, #6 ;right shift and saturating narrow - ; result 1 - vmlal.u8 q5, d18, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vmlsl.u8 q5, d19, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - vld1.u8 {d7}, [r6] - vrhadd.u8 d20, d20, d6 - vmlsl.u8 q5, d12, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vmlal.u8 q5, d13, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vst1.8 {d20}, [r1]! ;store the result pu1_dst - vhadd.s16 q5, q5, q11 - subs r5, r5, #8 ;decrement the wd loop - vqrshrun.s16 d8, q5, #6 ;right shift and saturating narrow - ; result 2 - vrhadd.u8 d8, d8, d7 - vst1.8 {d8}, [r6]! ;store the result pu1_dst - cmp r5, #4 - bgt inner_loop_8 - -end_inner_loop_8 - subs r14, r14, #2 ;decrement the ht loop - add r12, r12, r9 ;increment the src pointer by - ; 2*src_strd-wd - add r1, r1, r8 ;increment the dst pointer by - ; 2*dst_strd-wd - bgt outer_loop_8 - - ldr r10, [sp, #120] ;loads wd - cmp r10, #12 - beq outer_loop4_residual - -end_loops - b end_func - -outer_loop_16 - str r0, [sp, #-4]! - str r7, [sp, #-4]! - add r6, r1, r3 ;pu1_dst + dst_strd - add r4, r12, r2 ;pu1_src + src_strd - and r0, r12, #31 - mov r7, #0xc000 - sub r5, r10, #0 ;checks wd - pld [r4, r2, lsl #1] - pld [r12, r2, lsl #1] - vld1.u32 {q0}, [r12], r11 ;vector load pu1_src - vdup.16 q4, r7 - vld1.u32 {q1}, [r12], r11 - vld1.u32 {q2}, [r12], r11 - vld1.u32 {q3}, [r12], r11 - vmlsl.u8 q4, d0, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vld1.u32 {q6}, [r12], r11 - vmlal.u8 q4, d2, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vld1.u32 {q7}, [r12], r11 - vmlsl.u8 q4, d4, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vld1.u32 {q8}, [r12], r11 - vmlal.u8 q4, d6, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - vld1.u32 {q9}, [r12], r11 - vmlal.u8 q4, d12, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vmlsl.u8 q4, d14, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vdup.16 q10, r7 - vmlal.u8 q4, d16, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vmlsl.u8 q4, d18, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - -inner_loop_16 - vmlsl.u8 q10, d1, d24 - vdup.16 q5, r7 - vmlal.u8 q10, d3, d25 - mov r7, #0x4000 - vdup.16 q11, r7 - vmlsl.u8 q10, d5, d26 - vld1.u32 {q0}, [r4], r11 ;vector load pu1_src - vhadd.s16 q4, q4, q11 - vld1.u32 {q1}, [r4], r11 - vmlal.u8 q10, d7, d27 - add r12, #8 - subs r5, r5, #16 - vmlal.u8 q10, d13, d28 - vld1.u32 {q2}, [r4], r11 - vmlsl.u8 q10, d15, d29 - vld1.u32 {q3}, [r4], r11 - vqrshrun.s16 d8, q4, #6 ;right shift and saturating narrow - ; result 1 - vmlal.u8 q10, d17, d30 - vld1.u32 {q6}, [r4], r11 - vmlsl.u8 q10, d19, d31 - vld1.u32 {q7}, [r4], r11 - add r7, r1, #8 - vmlsl.u8 q5, d0, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vmlal.u8 q5, d2, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vld1.u32 {q8}, [r4], r11 - vhadd.s16 q10, q10, q11 - vld1.u32 {q9}, [r4], r11 - vld1.u8 {d0}, [r1] - vmlsl.u8 q5, d4, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vld1.u8 {d2}, [r7] - vmlal.u8 q5, d6, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - add r4, #8 - mov r7, #0xc000 - vmlal.u8 q5, d12, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vmlsl.u8 q5, d14, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vqrshrun.s16 d9, q10, #6 - vdup.16 q11, r7 - vmlal.u8 q5, d16, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vmlsl.u8 q5, d18, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - mov r7, #0x4000 - vrhadd.u8 d8, d8, d0 - vrhadd.u8 d9, d9, d2 - vmlsl.u8 q11, d1, d24 - vmlal.u8 q11, d3, d25 - vdup.16 q10, r7 - vmlsl.u8 q11, d5, d26 - pld [r12, r2, lsl #2] - pld [r4, r2, lsl #2] - addeq r12, r12, r9 ;increment the src pointer by - ; 2*src_strd-wd - addeq r4, r12, r2 ;pu1_src + src_strd - vmlal.u8 q11, d7, d27 - vmlal.u8 q11, d13, d28 - vst1.8 {q4}, [r1]! ;store the result pu1_dst - subeq r14, r14, #2 - vhadd.s16 q5, q5, q10 - vmlsl.u8 q11, d15, d29 - addeq r1, r1, r8 - vmlal.u8 q11, d17, d30 - cmp r14, #0 - vmlsl.u8 q11, d19, d31 - vqrshrun.s16 d10, q5, #6 ;right shift and saturating narrow - ; result 2 - beq epilog_16 - - vld1.u32 {q0}, [r12], r11 ;vector load pu1_src - mov r7, #0xc000 - cmp r5, #0 - vld1.u32 {q1}, [r12], r11 - vhadd.s16 q11, q11, q10 - vld1.u32 {q2}, [r12], r11 - vdup.16 q4, r7 - vmlsl.u8 q4, d0, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vdup.16 q10, r7 - vld1.u32 {q3}, [r12], r11 - add r7, r6, #8 - moveq r5, r10 - vld1.u8 {d0}, [r6] - vmlal.u8 q4, d2, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vld1.u8 {d2}, [r7] - vqrshrun.s16 d11, q11, #6 - vmlsl.u8 q4, d4, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vld1.u32 {q6}, [r12], r11 - vrhadd.u8 d10, d10, d0 - vld1.u32 {q7}, [r12], r11 - vrhadd.u8 d11, d11, d2 - vld1.u32 {q8}, [r12], r11 - vmlal.u8 q4, d6, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - vld1.u32 {q9}, [r12], r11 - vmlal.u8 q4, d12, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vmlsl.u8 q4, d14, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - mov r7, #0xc000 - vmlal.u8 q4, d16, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vst1.8 {q5}, [r6]! ;store the result pu1_dst - vmlsl.u8 q4, d18, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - addeq r6, r1, r3 ;pu1_dst + dst_strd - b inner_loop_16 - -epilog_16 - mov r7, #0x4000 - ldr r0, [sp], #4 - ldr r10, [sp, #120] - vdup.16 q10, r7 - vhadd.s16 q11, q11, q10 - vqrshrun.s16 d11, q11, #6 - add r7, r6, #8 - vld1.u8 {d20}, [r6] - vld1.u8 {d21}, [r7] - vrhadd.u8 d10, d10, d20 - vrhadd.u8 d11, d11, d21 - vst1.8 {q5}, [r6]! ;store the result pu1_dst - ldr r7, [sp], #4 - cmp r10, #24 - beq outer_loop8_residual - -end_loops1 - b end_func - -outer_loop4_residual - sub r12, r0, #3 ;pu1_src - 3 - mov r1, r7 - add r1, #8 - mov r10, #4 - add r12, #8 - mov r14, #16 - add r8, #4 - add r9, #4 - -outer_loop_4 - add r6, r1, r3 ;pu1_dst + dst_strd - add r4, r12, r2 ;pu1_src + src_strd - subs r5, r10, #0 ;checks wd - ble end_inner_loop_4 - -inner_loop_4 - vld1.u32 {d0}, [r12], r11 ;vector load pu1_src - vld1.u32 {d1}, [r12], r11 - vld1.u32 {d2}, [r12], r11 - vld1.u32 {d3}, [r12], r11 - vld1.u32 {d4}, [r12], r11 - vld1.u32 {d5}, [r12], r11 - vld1.u32 {d6}, [r12], r11 - vld1.u32 {d7}, [r12], r11 - sub r12, r12, #4 - vld1.u32 {d12}, [r4], r11 ;vector load pu1_src + src_strd - vld1.u32 {d13}, [r4], r11 - vzip.32 d0, d12 ;vector zip the i iteration and ii - ; interation in single register - vld1.u32 {d14}, [r4], r11 - vzip.32 d1, d13 - vld1.u32 {d15}, [r4], r11 - vzip.32 d2, d14 - vld1.u32 {d16}, [r4], r11 - vzip.32 d3, d15 - vld1.u32 {d17}, [r4], r11 - vzip.32 d4, d16 - vld1.u32 {d18}, [r4], r11 - vzip.32 d5, d17 - vld1.u32 {d19}, [r4], r11 - mov r7, #0xc000 - vdup.16 q4, r7 - sub r4, r4, #4 - vzip.32 d6, d18 - vzip.32 d7, d19 - vmlal.u8 q4, d1, d25 ;arithmetic operations for ii - ; iteration in the same time - vmlsl.u8 q4, d0, d24 - vmlsl.u8 q4, d2, d26 - vmlal.u8 q4, d3, d27 - vmlal.u8 q4, d4, d28 - vmlsl.u8 q4, d5, d29 - vmlal.u8 q4, d6, d30 - vmlsl.u8 q4, d7, d31 - mov r7, #0x4000 - vdup.16 q10, r7 - vhadd.s16 q4, q4, q10 - vqrshrun.s16 d8, q4, #6 - vld1.u32 {d10[0]}, [r1] - vld1.u32 {d10[1]}, [r6] - vrhadd.u8 d8, d8, d10 - vst1.32 {d8[0]},[r1]! ;store the i iteration result which - ; is in upper part of the register - vst1.32 {d8[1]},[r6]! ;store the ii iteration result which - ; is in lower part of the register - subs r5, r5, #4 ;decrement the wd by 4 - bgt inner_loop_4 - -end_inner_loop_4 - subs r14, r14, #2 ;decrement the ht by 4 - add r12, r12, r9 ;increment the input pointer - ; 2*src_strd-wd - add r1, r1, r8 ;increment the output pointer - ; 2*dst_strd-wd - bgt outer_loop_4 - -end_func - vpop {d8 - d15} - ldmfd sp!, {r4 - r12, r15} ;reload the registers from sp - - ENDP - - END diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_avg_vert_filter_type1_neon.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_avg_vert_filter_type1_neon.asm deleted file mode 100644 index d310a83d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_avg_vert_filter_type1_neon.asm +++ /dev/null @@ -1,486 +0,0 @@ -; -; Copyright (c) 2018 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; -;**************Variables Vs Registers*********************************** -; r0 => src -; r1 => dst -; r2 => src_stride -; r6 => dst_stride -; r12 => filter_y0 -; r5 => ht -; r3 => wd - - EXPORT |vpx_convolve8_avg_vert_filter_type1_neon| - ARM - REQUIRE8 - PRESERVE8 - - AREA ||.text||, CODE, READONLY, ALIGN=2 - -|vpx_convolve8_avg_vert_filter_type1_neon| PROC - - stmfd sp!, {r4 - r12, r14} ;stack stores the values of - ; the arguments - vpush {d8 - d15} ; stack offset by 64 - mov r4, r1 - mov r1, r2 - mov r2, r4 - vmov.i16 q15, #0x4000 - mov r11, #0xc000 - ldr r12, [sp, #104] ;load filter - ldr r6, [sp, #116] ;load y0_q4 - add r12, r12, r6, lsl #4 ;r12 = filter[y0_q4] - mov r6, r3 - ldr r5, [sp, #124] ;load wd - vld2.8 {d0, d1}, [r12] ;coeff = vld1_s8(pi1_coeff) - sub r12, r2, r2, lsl #2 ;src_ctrd & pi1_coeff - vabs.s8 d0, d0 ;vabs_s8(coeff) - add r0, r0, r12 ;r0->pu1_src r12->pi1_coeff - ldr r3, [sp, #128] ;load ht - subs r7, r3, #0 ;r3->ht - vdup.u8 d22, d0[0] ;coeffabs_0 = vdup_lane_u8(coeffabs, - ; 0); - cmp r5, #8 - vdup.u8 d23, d0[1] ;coeffabs_1 = vdup_lane_u8(coeffabs, - ; 1); - vdup.u8 d24, d0[2] ;coeffabs_2 = vdup_lane_u8(coeffabs, - ; 2); - vdup.u8 d25, d0[3] ;coeffabs_3 = vdup_lane_u8(coeffabs, - ; 3); - vdup.u8 d26, d0[4] ;coeffabs_4 = vdup_lane_u8(coeffabs, - ; 4); - vdup.u8 d27, d0[5] ;coeffabs_5 = vdup_lane_u8(coeffabs, - ; 5); - vdup.u8 d28, d0[6] ;coeffabs_6 = vdup_lane_u8(coeffabs, - ; 6); - vdup.u8 d29, d0[7] ;coeffabs_7 = vdup_lane_u8(coeffabs, - ; 7); - blt core_loop_wd_4 ;core loop wd 4 jump - str r0, [sp, #-4]! - str r1, [sp, #-4]! - bic r4, r5, #7 ;r5 ->wd - rsb r9, r4, r6, lsl #2 ;r6->dst_strd r5 ->wd - rsb r8, r4, r2, lsl #2 ;r2->src_strd - mov r3, r5, lsr #3 ;divide by 8 - mul r7, r3 ;multiply height by width - sub r7, #4 ;subtract by one for epilog - -prolog - and r10, r0, #31 - add r3, r0, r2 ;pu1_src_tmp += src_strd; - vdup.16 q4, r11 - vld1.u8 {d1}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vld1.u8 {d0}, [r0]! ;src_tmp1 = vld1_u8(pu1_src_tmp); - subs r4, r4, #8 - vld1.u8 {d2}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d1, d23 ;mul_res1 = vmull_u8(src_tmp2, - ; coeffabs_1); - vld1.u8 {d3}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d0, d22 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp1, coeffabs_0); - vld1.u8 {d4}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d2, d24 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp3, coeffabs_2); - vld1.u8 {d5}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d3, d25 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp4, coeffabs_3); - vld1.u8 {d6}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d4, d26 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp1, coeffabs_4); - vld1.u8 {d7}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d5, d27 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp2, coeffabs_5); - vld1.u8 {d16}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d6, d28 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp3, coeffabs_6); - vld1.u8 {d17}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d7, d29 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp4, coeffabs_7); - vdup.16 q5, r11 - vld1.u8 {d18}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q5, d2, d23 ;mul_res2 = vmull_u8(src_tmp3, - ; coeffabs_1); - addle r0, r0, r8 - vmlsl.u8 q5, d1, d22 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp2, coeffabs_0); - bicle r4, r5, #7 ;r5 ->wd - vmlal.u8 q5, d3, d24 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp4, coeffabs_2); - pld [r3] - vmlal.u8 q5, d4, d25 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp1, coeffabs_3); - vhadd.s16 q4, q4, q15 - vdup.16 q6, r11 - pld [r3, r2] - pld [r3, r2, lsl #1] - vmlal.u8 q5, d5, d26 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp2, coeffabs_4); - add r3, r3, r2 - vmlal.u8 q5, d6, d27 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp3, coeffabs_5); - pld [r3, r2, lsl #1] - vmlsl.u8 q5, d7, d28 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp4, coeffabs_6); - add r3, r0, r2 ;pu1_src_tmp += src_strd; - vmlsl.u8 q5, d16, d29 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp1, coeffabs_7); - vld1.u8 {d20}, [r1] - vqrshrun.s16 d8, q4, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vld1.u8 {d1}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q6, d3, d23 - vld1.u8 {d0}, [r0]! ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q6, d2, d22 - vrhadd.u8 d8, d8, d20 - vld1.u8 {d2}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q6, d4, d24 - vhadd.s16 q5, q5, q15 - vdup.16 q7, r11 - vmlal.u8 q6, d5, d25 - vmlal.u8 q6, d6, d26 - add r14, r1, r6 - vmlal.u8 q6, d7, d27 - vmlsl.u8 q6, d16, d28 - vst1.8 {d8}, [r1]! ;vst1_u8(pu1_dst,sto_res); - vmlsl.u8 q6, d17, d29 - vld1.u8 {d20}, [r14] - vqrshrun.s16 d10, q5, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - addle r1, r1, r9 - vmlsl.u8 q7, d4, d23 - subs r7, r7, #4 - vmlsl.u8 q7, d3, d22 - vmlal.u8 q7, d5, d24 - vld1.u8 {d3}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vmlal.u8 q7, d6, d25 - vrhadd.u8 d10, d10, d20 - vhadd.s16 q6, q6, q15 - vdup.16 q4, r11 - vmlal.u8 q7, d7, d26 - vld1.u8 {d4}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlal.u8 q7, d16, d27 - vld1.u8 {d5}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d17, d28 - vld1.u8 {d6}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d18, d29 - vld1.u8 {d7}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vst1.8 {d10}, [r14], r6 ;vst1_u8(pu1_dst_tmp,sto_res); - vqrshrun.s16 d12, q6, #6 - blt epilog_end ;jumps to epilog_end - - beq epilog ;jumps to epilog - -main_loop_8 - subs r4, r4, #8 - vmlsl.u8 q4, d1, d23 ;mul_res1 = vmull_u8(src_tmp2, - ; coeffabs_1); - vld1.u8 {d20}, [r14] - vmlsl.u8 q4, d0, d22 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp1, coeffabs_0); - addle r0, r0, r8 - bicle r4, r5, #7 ;r5 ->wd - vmlal.u8 q4, d2, d24 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp3, coeffabs_2); - vld1.u8 {d16}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d3, d25 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp4, coeffabs_3); - vrhadd.u8 d12, d12, d20 - vhadd.s16 q7, q7, q15 - vdup.16 q5, r11 - vld1.u8 {d17}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d4, d26 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp1, coeffabs_4); - vld1.u8 {d18}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d5, d27 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp2, coeffabs_5); - vmlsl.u8 q4, d6, d28 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp3, coeffabs_6); - vmlsl.u8 q4, d7, d29 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp4, coeffabs_7); - vst1.8 {d12}, [r14], r6 - vld1.u8 {d20}, [r14] - vqrshrun.s16 d14, q7, #6 - add r3, r0, r2 ;pu1_src_tmp += src_strd; - vmlsl.u8 q5, d2, d23 ;mul_res2 = vmull_u8(src_tmp3, - ; coeffabs_1); - vld1.u8 {d0}, [r0]! ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q5, d1, d22 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp2, coeffabs_0); - vrhadd.u8 d14, d14, d20 - vmlal.u8 q5, d3, d24 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp4, coeffabs_2); - vld1.u8 {d1}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q5, d4, d25 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp1, coeffabs_3); - vhadd.s16 q4, q4, q15 - vdup.16 q6, r11 - vst1.8 {d14}, [r14], r6 - vmlal.u8 q5, d5, d26 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp2, coeffabs_4); - add r14, r1, #0 - vmlal.u8 q5, d6, d27 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp3, coeffabs_5); - add r1, r1, #8 - vmlsl.u8 q5, d7, d28 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp4, coeffabs_6); - addle r1, r1, r9 - vmlsl.u8 q5, d16, d29 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp1, coeffabs_7); - vld1.u8 {d20}, [r14] - vqrshrun.s16 d8, q4, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vmlsl.u8 q6, d3, d23 - add r10, r3, r2, lsl #3 ; 10*strd - 8+2 - vmlsl.u8 q6, d2, d22 - vrhadd.u8 d8, d8, d20 - add r10, r10, r2 ; 11*strd - vmlal.u8 q6, d4, d24 - vld1.u8 {d2}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q6, d5, d25 - vhadd.s16 q5, q5, q15 - vdup.16 q7, r11 - vmlal.u8 q6, d6, d26 - vst1.8 {d8}, [r14], r6 ;vst1_u8(pu1_dst,sto_res); - pld [r10] ;11+ 0 - vmlal.u8 q6, d7, d27 - pld [r10, r2] ;11+ 1*strd - pld [r10, r2, lsl #1] ;11+ 2*strd - vmlsl.u8 q6, d16, d28 - add r10, r10, r2 ;12*strd - vmlsl.u8 q6, d17, d29 - vld1.u8 {d20}, [r14] - vqrshrun.s16 d10, q5, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - - pld [r10, r2, lsl #1] ;11+ 3*strd - vmlsl.u8 q7, d4, d23 - vmlsl.u8 q7, d3, d22 - vrhadd.u8 d10, d10, d20 - subs r7, r7, #4 - vmlal.u8 q7, d5, d24 - vmlal.u8 q7, d6, d25 - vld1.u8 {d3}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vhadd.s16 q6, q6, q15 - vdup.16 q4, r11 - vmlal.u8 q7, d7, d26 - vld1.u8 {d4}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlal.u8 q7, d16, d27 - vld1.u8 {d5}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d17, d28 - vld1.u8 {d6}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d18, d29 - vld1.u8 {d7}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vqrshrun.s16 d12, q6, #6 - vst1.8 {d10}, [r14], r6 ;vst1_u8(pu1_dst_tmp,sto_res); - bgt main_loop_8 ;jumps to main_loop_8 - -epilog - vld1.u8 {d20}, [r14] - vmlsl.u8 q4, d1, d23 ;mul_res1 = vmull_u8(src_tmp2, - ; coeffabs_1); - vmlsl.u8 q4, d0, d22 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp1, coeffabs_0); - vmlal.u8 q4, d2, d24 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp3, coeffabs_2); - vrhadd.u8 d12, d12, d20 - vmlal.u8 q4, d3, d25 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp4, coeffabs_3); - vhadd.s16 q7, q7, q15 - vdup.16 q5, r11 - vmlal.u8 q4, d4, d26 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp1, coeffabs_4); - vmlal.u8 q4, d5, d27 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp2, coeffabs_5); - vmlsl.u8 q4, d6, d28 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp3, coeffabs_6); - vst1.8 {d12}, [r14], r6 - vmlsl.u8 q4, d7, d29 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp4, coeffabs_7); - vld1.u8 {d20}, [r14] - vqrshrun.s16 d14, q7, #6 - vld1.u8 {d16}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q5, d2, d23 ;mul_res2 = vmull_u8(src_tmp3, - ; coeffabs_1); - vmlsl.u8 q5, d1, d22 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp2, coeffabs_0); - vrhadd.u8 d14, d14, d20 - vmlal.u8 q5, d3, d24 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp4, coeffabs_2); - vmlal.u8 q5, d4, d25 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp1, coeffabs_3); - vhadd.s16 q4, q4, q15 - vdup.16 q6, r11 - vmlal.u8 q5, d5, d26 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp2, coeffabs_4); - vmlal.u8 q5, d6, d27 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp3, coeffabs_5); - vmlsl.u8 q5, d7, d28 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp4, coeffabs_6); - vst1.8 {d14}, [r14], r6 - vmlsl.u8 q5, d16, d29 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp1, coeffabs_7); - vld1.u8 {d20}, [r1] - vqrshrun.s16 d8, q4, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vld1.u8 {d17}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q6, d3, d23 - vmlsl.u8 q6, d2, d22 - vrhadd.u8 d8, d8, d20 - vmlal.u8 q6, d4, d24 - vmlal.u8 q6, d5, d25 - vhadd.s16 q5, q5, q15 - vdup.16 q7, r11 - vmlal.u8 q6, d6, d26 - vmlal.u8 q6, d7, d27 - add r14, r1, r6 - vmlsl.u8 q6, d16, d28 - vst1.8 {d8}, [r1]! ;vst1_u8(pu1_dst,sto_res); - vmlsl.u8 q6, d17, d29 - vld1.u8 {d20}, [r14] - vqrshrun.s16 d10, q5, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vld1.u8 {d18}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d4, d23 - vmlsl.u8 q7, d3, d22 - vrhadd.u8 d10, d10, d20 - vmlal.u8 q7, d5, d24 - vmlal.u8 q7, d6, d25 - vhadd.s16 q6, q6, q15 - vmlal.u8 q7, d7, d26 - vmlal.u8 q7, d16, d27 - vmlsl.u8 q7, d17, d28 - vmlsl.u8 q7, d18, d29 - vst1.8 {d10}, [r14], r6 ;vst1_u8(pu1_dst_tmp,sto_res); - vqrshrun.s16 d12, q6, #6 - -epilog_end - vld1.u8 {d20}, [r14] - vrhadd.u8 d12, d12, d20 - vst1.8 {d12}, [r14], r6 - vhadd.s16 q7, q7, q15 - vqrshrun.s16 d14, q7, #6 - vld1.u8 {d20}, [r14] - vrhadd.u8 d14, d14, d20 - vst1.8 {d14}, [r14], r6 - -end_loops - tst r5, #7 - ldr r1, [sp], #4 - ldr r0, [sp], #4 - vpopeq {d8 - d15} - ldmfdeq sp!, {r4 - r12, r15} ;reload the registers from sp - mov r5, #4 - add r0, r0, #8 - add r1, r1, #8 - mov r7, #16 - -core_loop_wd_4 - rsb r9, r5, r6, lsl #2 ;r6->dst_strd r5 ->wd - rsb r8, r5, r2, lsl #2 ;r2->src_strd - vmov.i8 d4, #0 - -outer_loop_wd_4 - subs r12, r5, #0 - ble end_inner_loop_wd_4 ;outer loop jump - -inner_loop_wd_4 - add r3, r0, r2 - vld1.u32 {d4[1]},[r3], r2 ;src_tmp1 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp1, 1); - subs r12, r12, #4 - vdup.u32 d5, d4[1] ;src_tmp2 = vdup_lane_u32(src_tmp1, - ; 1); - vld1.u32 {d5[1]},[r3], r2 ;src_tmp2 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp2, 1); - vld1.u32 {d4[0]},[r0] ;src_tmp1 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp1, 0); - vdup.16 q0, r11 - vmlsl.u8 q0, d5, d23 ;mul_res1 = - ; vmull_u8(vreinterpret_u8_u32(src_tmp2), coeffabs_1); - vdup.u32 d6, d5[1] ;src_tmp3 = vdup_lane_u32(src_tmp2, - ; 1); - add r0, r0, #4 - vld1.u32 {d6[1]},[r3], r2 ;src_tmp3 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp3, 1); - vmlsl.u8 q0, d4, d22 ;mul_res1 = vmlsl_u8(mul_res1, - ; vreinterpret_u8_u32(src_tmp1), coeffabs_0); - vdup.u32 d7, d6[1] ;src_tmp4 = vdup_lane_u32(src_tmp3, - ; 1); - vld1.u32 {d7[1]},[r3], r2 ;src_tmp4 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp4, 1); - vmlal.u8 q0, d6, d24 ;mul_res1 = vmlsl_u8(mul_res1, - ; vreinterpret_u8_u32(src_tmp3), coeffabs_2); - vdup.16 q4, r11 - vmlsl.u8 q4, d7, d23 - vdup.u32 d4, d7[1] ;src_tmp1 = vdup_lane_u32(src_tmp4, - ; 1); - vmull.u8 q1, d7, d25 ;mul_res2 = - ; vmull_u8(vreinterpret_u8_u32(src_tmp4), coeffabs_3); - vld1.u32 {d4[1]},[r3], r2 ;src_tmp1 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp1, 1); - vmlsl.u8 q4, d6, d22 - vmlal.u8 q0, d4, d26 ;mul_res1 = vmlal_u8(mul_res1, - ; vreinterpret_u8_u32(src_tmp1), coeffabs_4); - vdup.u32 d5, d4[1] ;src_tmp2 = vdup_lane_u32(src_tmp1, - ; 1); - vmlal.u8 q4, d4, d24 - vld1.u32 {d5[1]},[r3], r2 ;src_tmp2 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp2, 1); - vmlal.u8 q1, d5, d27 ;mul_res2 = vmlsl_u8(mul_res2, - ; vreinterpret_u8_u32(src_tmp2), coeffabs_5); - vdup.u32 d6, d5[1] ;src_tmp3 = vdup_lane_u32(src_tmp2, - ; 1); - vmlal.u8 q4, d5, d25 - vld1.u32 {d6[1]},[r3], r2 ;src_tmp3 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp3, 1); - vmlsl.u8 q0, d6, d28 ;mul_res1 = vmlal_u8(mul_res1, - ; vreinterpret_u8_u32(src_tmp3), coeffabs_6); - vdup.u32 d7, d6[1] ;src_tmp4 = vdup_lane_u32(src_tmp3, - ; 1); - vmlal.u8 q4, d6, d26 - vld1.u32 {d7[1]},[r3], r2 ;src_tmp4 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp4, 1); - vmlsl.u8 q1, d7, d29 ;mul_res2 = vmlsl_u8(mul_res2, - ; vreinterpret_u8_u32(src_tmp4), coeffabs_7); - vdup.u32 d4, d7[1] - vadd.i16 q0, q0, q1 ;mul_res1 = vaddq_u16(mul_res1, - ; mul_res2); - vmlal.u8 q4, d7, d27 - vld1.u32 {d4[1]},[r3], r2 - vmlsl.u8 q4, d4, d28 - vdup.u32 d5, d4[1] - vhadd.s16 q0, q0, q15 - vqrshrun.s16 d0, q0, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vld1.u32 {d5[1]},[r3] - add r3, r1, r6 - vld1.u32 {d20[0]}, [r1] - vld1.u32 {d20[1]}, [r3] - vrhadd.u8 d0, d0, d20 - vst1.32 {d0[0]},[r1] ;vst1_lane_u32((uint32_t *)pu1_dst, - ; vreinterpret_u32_u8(sto_res), 0); - vmlsl.u8 q4, d5, d29 - vst1.32 {d0[1]},[r3], r6 ;vst1_lane_u32((uint32_t - ; *)pu1_dst_tmp, vreinterpret_u32_u8(sto_res), 1); - vhadd.s16 q4, q4, q15 - vqrshrun.s16 d8, q4, #6 - mov r4, r3 - vld1.u32 {d20[0]}, [r4], r6 - vld1.u32 {d20[1]}, [r4] - vrhadd.u8 d8, d8, d20 - vst1.32 {d8[0]},[r3], r6 - add r1, r1, #4 - vst1.32 {d8[1]},[r3] - bgt inner_loop_wd_4 - -end_inner_loop_wd_4 - subs r7, r7, #4 - add r1, r1, r9 - add r0, r0, r8 - bgt outer_loop_wd_4 - - vpop {d8 - d15} - ldmfd sp!, {r4 - r12, r15} ;reload the registers from sp - - ENDP - - END diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_avg_vert_filter_type2_neon.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_avg_vert_filter_type2_neon.asm deleted file mode 100644 index c5695fbd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_avg_vert_filter_type2_neon.asm +++ /dev/null @@ -1,487 +0,0 @@ -; -; Copyright (c) 2018 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; -;**************Variables Vs Registers*********************************** -; r0 => src -; r1 => dst -; r2 => src_stride -; r6 => dst_stride -; r12 => filter_y0 -; r5 => ht -; r3 => wd - - EXPORT |vpx_convolve8_avg_vert_filter_type2_neon| - ARM - REQUIRE8 - PRESERVE8 - - AREA ||.text||, CODE, READONLY, ALIGN=2 - -|vpx_convolve8_avg_vert_filter_type2_neon| PROC - - stmfd sp!, {r4 - r12, r14} ;stack stores the values of - ; the arguments - vpush {d8 - d15} ; stack offset by 64 - mov r4, r1 - mov r1, r2 - mov r2, r4 - vmov.i16 q15, #0x4000 - mov r11, #0xc000 - ldr r12, [sp, #104] ;load filter - ldr r6, [sp, #116] ;load y0_q4 - add r12, r12, r6, lsl #4 ;r12 = filter[y0_q4] - mov r6, r3 - ldr r5, [sp, #124] ;load wd - vld2.8 {d0, d1}, [r12] ;coeff = vld1_s8(pi1_coeff) - sub r12, r2, r2, lsl #2 ;src_ctrd & pi1_coeff - vabs.s8 d0, d0 ;vabs_s8(coeff) - add r0, r0, r12 ;r0->pu1_src r12->pi1_coeff - ldr r3, [sp, #128] ;load ht - subs r7, r3, #0 ;r3->ht - vdup.u8 d22, d0[0] ;coeffabs_0 = vdup_lane_u8(coeffabs, - ; 0); - cmp r5, #8 - vdup.u8 d23, d0[1] ;coeffabs_1 = vdup_lane_u8(coeffabs, - ; 1); - vdup.u8 d24, d0[2] ;coeffabs_2 = vdup_lane_u8(coeffabs, - ; 2); - vdup.u8 d25, d0[3] ;coeffabs_3 = vdup_lane_u8(coeffabs, - ; 3); - vdup.u8 d26, d0[4] ;coeffabs_4 = vdup_lane_u8(coeffabs, - ; 4); - vdup.u8 d27, d0[5] ;coeffabs_5 = vdup_lane_u8(coeffabs, - ; 5); - vdup.u8 d28, d0[6] ;coeffabs_6 = vdup_lane_u8(coeffabs, - ; 6); - vdup.u8 d29, d0[7] ;coeffabs_7 = vdup_lane_u8(coeffabs, - ; 7); - blt core_loop_wd_4 ;core loop wd 4 jump - - str r0, [sp, #-4]! - str r1, [sp, #-4]! - bic r4, r5, #7 ;r5 ->wd - rsb r9, r4, r6, lsl #2 ;r6->dst_strd r5 ->wd - rsb r8, r4, r2, lsl #2 ;r2->src_strd - mov r3, r5, lsr #3 ;divide by 8 - mul r7, r3 ;multiply height by width - sub r7, #4 ;subtract by one for epilog - -prolog - and r10, r0, #31 - add r3, r0, r2 ;pu1_src_tmp += src_strd; - vdup.16 q4, r11 - vld1.u8 {d1}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vld1.u8 {d0}, [r0]! ;src_tmp1 = vld1_u8(pu1_src_tmp); - subs r4, r4, #8 - vld1.u8 {d2}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d1, d23 ;mul_res1 = vmull_u8(src_tmp2, - ; coeffabs_1); - vld1.u8 {d3}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d0, d22 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp1, coeffabs_0); - vld1.u8 {d4}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d2, d24 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp3, coeffabs_2); - vld1.u8 {d5}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d3, d25 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp4, coeffabs_3); - vld1.u8 {d6}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d4, d26 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp1, coeffabs_4); - vld1.u8 {d7}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d5, d27 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp2, coeffabs_5); - vld1.u8 {d16}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d6, d28 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp3, coeffabs_6); - vld1.u8 {d17}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d7, d29 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp4, coeffabs_7); - vdup.16 q5, r11 - vld1.u8 {d18}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q5, d2, d23 ;mul_res2 = vmull_u8(src_tmp3, - ; coeffabs_1); - addle r0, r0, r8 - vmlsl.u8 q5, d1, d22 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp2, coeffabs_0); - bicle r4, r5, #7 ;r5 ->wd - vmlsl.u8 q5, d3, d24 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp4, coeffabs_2); - pld [r3] - vmlal.u8 q5, d4, d25 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp1, coeffabs_3); - vhadd.s16 q4, q4, q15 - vdup.16 q6, r11 - pld [r3, r2] - pld [r3, r2, lsl #1] - vmlal.u8 q5, d5, d26 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp2, coeffabs_4); - add r3, r3, r2 - vmlsl.u8 q5, d6, d27 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp3, coeffabs_5); - pld [r3, r2, lsl #1] - vmlal.u8 q5, d7, d28 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp4, coeffabs_6); - add r3, r0, r2 ;pu1_src_tmp += src_strd; - vmlsl.u8 q5, d16, d29 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp1, coeffabs_7); - vld1.u8 {d20}, [r1] - vqrshrun.s16 d8, q4, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vld1.u8 {d1}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q6, d3, d23 - vld1.u8 {d0}, [r0]! ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q6, d2, d22 - vrhadd.u8 d8, d8, d20 - vld1.u8 {d2}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q6, d4, d24 - vhadd.s16 q5, q5, q15 - vdup.16 q7, r11 - vmlal.u8 q6, d5, d25 - vmlal.u8 q6, d6, d26 - add r14, r1, r6 - vmlsl.u8 q6, d7, d27 - vmlal.u8 q6, d16, d28 - vst1.8 {d8}, [r1]! ;vst1_u8(pu1_dst,sto_res); - vmlsl.u8 q6, d17, d29 - vld1.u8 {d20}, [r14] - vqrshrun.s16 d10, q5, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - addle r1, r1, r9 - vmlal.u8 q7, d4, d23 - subs r7, r7, #4 - vmlsl.u8 q7, d3, d22 - vmlsl.u8 q7, d5, d24 - vld1.u8 {d3}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vmlal.u8 q7, d6, d25 - vrhadd.u8 d10, d10, d20 - vhadd.s16 q6, q6, q15 - vdup.16 q4, r11 - vmlal.u8 q7, d7, d26 - vld1.u8 {d4}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d16, d27 - vld1.u8 {d5}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q7, d17, d28 - vld1.u8 {d6}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d18, d29 - vld1.u8 {d7}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vst1.8 {d10}, [r14], r6 ;vst1_u8(pu1_dst_tmp,sto_res); - vqrshrun.s16 d12, q6, #6 - blt epilog_end ;jumps to epilog_end - - beq epilog ;jumps to epilog - -main_loop_8 - subs r4, r4, #8 - vmlal.u8 q4, d1, d23 ;mul_res1 = vmull_u8(src_tmp2, - ; coeffabs_1); - vld1.u8 {d20}, [r14] - vmlsl.u8 q4, d0, d22 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp1, coeffabs_0); - addle r0, r0, r8 - bicle r4, r5, #7 ;r5 ->wd - vmlsl.u8 q4, d2, d24 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp3, coeffabs_2); - vld1.u8 {d16}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d3, d25 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp4, coeffabs_3); - vrhadd.u8 d12, d12, d20 - vhadd.s16 q7, q7, q15 - vdup.16 q5, r11 - vld1.u8 {d17}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d4, d26 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp1, coeffabs_4); - vld1.u8 {d18}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d5, d27 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp2, coeffabs_5); - vmlal.u8 q4, d6, d28 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp3, coeffabs_6); - vmlsl.u8 q4, d7, d29 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp4, coeffabs_7); - vst1.8 {d12}, [r14], r6 - vld1.u8 {d20}, [r14] - vqrshrun.s16 d14, q7, #6 - add r3, r0, r2 ;pu1_src_tmp += src_strd; - vmlal.u8 q5, d2, d23 ;mul_res2 = vmull_u8(src_tmp3, - ; coeffabs_1); - vld1.u8 {d0}, [r0]! ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q5, d1, d22 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp2, coeffabs_0); - vrhadd.u8 d14, d14, d20 - vmlsl.u8 q5, d3, d24 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp4, coeffabs_2); - vld1.u8 {d1}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q5, d4, d25 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp1, coeffabs_3); - vhadd.s16 q4, q4, q15 - vdup.16 q6, r11 - vst1.8 {d14}, [r14], r6 - vmlal.u8 q5, d5, d26 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp2, coeffabs_4); - add r14, r1, #0 - vmlsl.u8 q5, d6, d27 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp3, coeffabs_5); - add r1, r1, #8 - vmlal.u8 q5, d7, d28 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp4, coeffabs_6); - addle r1, r1, r9 - vmlsl.u8 q5, d16, d29 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp1, coeffabs_7); - vld1.u8 {d20}, [r14] - vqrshrun.s16 d8, q4, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vmlal.u8 q6, d3, d23 - add r10, r3, r2, lsl #3 ; 10*strd - 8+2 - vmlsl.u8 q6, d2, d22 - vrhadd.u8 d8, d8, d20 - add r10, r10, r2 ; 11*strd - vmlsl.u8 q6, d4, d24 - vld1.u8 {d2}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q6, d5, d25 - vhadd.s16 q5, q5, q15 - vdup.16 q7, r11 - vmlal.u8 q6, d6, d26 - vst1.8 {d8}, [r14], r6 ;vst1_u8(pu1_dst,sto_res); - pld [r10] ;11+ 0 - vmlsl.u8 q6, d7, d27 - pld [r10, r2] ;11+ 1*strd - pld [r10, r2, lsl #1] ;11+ 2*strd - vmlal.u8 q6, d16, d28 - add r10, r10, r2 ;12*strd - vmlsl.u8 q6, d17, d29 - vld1.u8 {d20}, [r14] - vqrshrun.s16 d10, q5, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - pld [r10, r2, lsl #1] ;11+ 3*strd - vmlal.u8 q7, d4, d23 - vmlsl.u8 q7, d3, d22 - vrhadd.u8 d10, d10, d20 - subs r7, r7, #4 - vmlsl.u8 q7, d5, d24 - vmlal.u8 q7, d6, d25 - vld1.u8 {d3}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vhadd.s16 q6, q6, q15 - vdup.16 q4, r11 - vmlal.u8 q7, d7, d26 - vld1.u8 {d4}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d16, d27 - vld1.u8 {d5}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q7, d17, d28 - vld1.u8 {d6}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d18, d29 - vld1.u8 {d7}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vqrshrun.s16 d12, q6, #6 - vst1.8 {d10}, [r14], r6 ;vst1_u8(pu1_dst_tmp,sto_res); - bgt main_loop_8 ;jumps to main_loop_8 - -epilog - vld1.u8 {d20}, [r14] - vmlal.u8 q4, d1, d23 ;mul_res1 = vmull_u8(src_tmp2, - ; coeffabs_1); - vmlsl.u8 q4, d0, d22 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp1, coeffabs_0); - vmlsl.u8 q4, d2, d24 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp3, coeffabs_2); - vrhadd.u8 d12, d12, d20 - vmlal.u8 q4, d3, d25 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp4, coeffabs_3); - vhadd.s16 q7, q7, q15 - vdup.16 q5, r11 - vmlal.u8 q4, d4, d26 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp1, coeffabs_4); - vmlsl.u8 q4, d5, d27 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp2, coeffabs_5); - vmlal.u8 q4, d6, d28 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp3, coeffabs_6); - vst1.8 {d12}, [r14], r6 - vmlsl.u8 q4, d7, d29 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp4, coeffabs_7); - vld1.u8 {d20}, [r14] - vqrshrun.s16 d14, q7, #6 - vld1.u8 {d16}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlal.u8 q5, d2, d23 ;mul_res2 = vmull_u8(src_tmp3, - ; coeffabs_1); - vmlsl.u8 q5, d1, d22 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp2, coeffabs_0); - vrhadd.u8 d14, d14, d20 - vmlsl.u8 q5, d3, d24 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp4, coeffabs_2); - vmlal.u8 q5, d4, d25 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp1, coeffabs_3); - vhadd.s16 q4, q4, q15 - vdup.16 q6, r11 - vmlal.u8 q5, d5, d26 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp2, coeffabs_4); - vmlsl.u8 q5, d6, d27 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp3, coeffabs_5); - vmlal.u8 q5, d7, d28 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp4, coeffabs_6); - vst1.8 {d14}, [r14], r6 - vmlsl.u8 q5, d16, d29 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp1, coeffabs_7); - vld1.u8 {d20}, [r1] - vqrshrun.s16 d8, q4, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vld1.u8 {d17}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q6, d3, d23 - vmlsl.u8 q6, d2, d22 - vrhadd.u8 d8, d8, d20 - vmlsl.u8 q6, d4, d24 - vmlal.u8 q6, d5, d25 - vhadd.s16 q5, q5, q15 - vdup.16 q7, r11 - vmlal.u8 q6, d6, d26 - vmlsl.u8 q6, d7, d27 - add r14, r1, r6 - vmlal.u8 q6, d16, d28 - vst1.8 {d8}, [r1]! ;vst1_u8(pu1_dst,sto_res); - vmlsl.u8 q6, d17, d29 - vld1.u8 {d20}, [r14] - vqrshrun.s16 d10, q5, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vld1.u8 {d18}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q7, d4, d23 - vmlsl.u8 q7, d3, d22 - vrhadd.u8 d10, d10, d20 - vmlsl.u8 q7, d5, d24 - vmlal.u8 q7, d6, d25 - vhadd.s16 q6, q6, q15 - vmlal.u8 q7, d7, d26 - vmlsl.u8 q7, d16, d27 - vmlal.u8 q7, d17, d28 - vmlsl.u8 q7, d18, d29 - vst1.8 {d10}, [r14], r6 ;vst1_u8(pu1_dst_tmp,sto_res); - vqrshrun.s16 d12, q6, #6 - -epilog_end - vld1.u8 {d20}, [r14] - vrhadd.u8 d12, d12, d20 - vst1.8 {d12}, [r14], r6 - vhadd.s16 q7, q7, q15 - vqrshrun.s16 d14, q7, #6 - vld1.u8 {d20}, [r14] - vrhadd.u8 d14, d14, d20 - vst1.8 {d14}, [r14], r6 - -end_loops - tst r5, #7 - ldr r1, [sp], #4 - ldr r0, [sp], #4 - vpopeq {d8 - d15} - ldmfdeq sp!, {r4 - r12, r15} ;reload the registers from sp - - mov r5, #4 - add r0, r0, #8 - add r1, r1, #8 - mov r7, #16 - -core_loop_wd_4 - rsb r9, r5, r6, lsl #2 ;r6->dst_strd r5 ->wd - rsb r8, r5, r2, lsl #2 ;r2->src_strd - vmov.i8 d4, #0 - -outer_loop_wd_4 - subs r12, r5, #0 - ble end_inner_loop_wd_4 ;outer loop jump - -inner_loop_wd_4 - add r3, r0, r2 - vld1.u32 {d4[1]},[r3], r2 ;src_tmp1 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp1, 1); - subs r12, r12, #4 - vdup.u32 d5, d4[1] ;src_tmp2 = vdup_lane_u32(src_tmp1, - ; 1); - vld1.u32 {d5[1]},[r3], r2 ;src_tmp2 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp2, 1); - vld1.u32 {d4[0]},[r0] ;src_tmp1 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp1, 0); - vdup.16 q0, r11 - vmlal.u8 q0, d5, d23 ;mul_res1 = - ; vmull_u8(vreinterpret_u8_u32(src_tmp2), coeffabs_1); - vdup.u32 d6, d5[1] ;src_tmp3 = vdup_lane_u32(src_tmp2, - ; 1); - add r0, r0, #4 - vld1.u32 {d6[1]},[r3], r2 ;src_tmp3 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp3, 1); - vmlsl.u8 q0, d4, d22 ;mul_res1 = vmlsl_u8(mul_res1, - ; vreinterpret_u8_u32(src_tmp1), coeffabs_0); - vdup.u32 d7, d6[1] ;src_tmp4 = vdup_lane_u32(src_tmp3, - ; 1); - vld1.u32 {d7[1]},[r3], r2 ;src_tmp4 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp4, 1); - vmlsl.u8 q0, d6, d24 ;mul_res1 = vmlsl_u8(mul_res1, - ; vreinterpret_u8_u32(src_tmp3), coeffabs_2); - vdup.16 q4, r11 - vmlal.u8 q4, d7, d23 - vdup.u32 d4, d7[1] ;src_tmp1 = vdup_lane_u32(src_tmp4, - ; 1); - vmull.u8 q1, d7, d25 ;mul_res2 = - ; vmull_u8(vreinterpret_u8_u32(src_tmp4), coeffabs_3); - vld1.u32 {d4[1]},[r3], r2 ;src_tmp1 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp1, 1); - vmlsl.u8 q4, d6, d22 - vmlal.u8 q0, d4, d26 ;mul_res1 = vmlal_u8(mul_res1, - ; vreinterpret_u8_u32(src_tmp1), coeffabs_4); - vdup.u32 d5, d4[1] ;src_tmp2 = vdup_lane_u32(src_tmp1, - ; 1); - vmlsl.u8 q4, d4, d24 - vld1.u32 {d5[1]},[r3], r2 ;src_tmp2 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp2, 1); - vmlsl.u8 q1, d5, d27 ;mul_res2 = vmlsl_u8(mul_res2, - ; vreinterpret_u8_u32(src_tmp2), coeffabs_5); - vdup.u32 d6, d5[1] ;src_tmp3 = vdup_lane_u32(src_tmp2, - ; 1); - vmlal.u8 q4, d5, d25 - vld1.u32 {d6[1]},[r3], r2 ;src_tmp3 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp3, 1); - vmlal.u8 q0, d6, d28 ;mul_res1 = vmlal_u8(mul_res1, - ; vreinterpret_u8_u32(src_tmp3), coeffabs_6); - vdup.u32 d7, d6[1] ;src_tmp4 = vdup_lane_u32(src_tmp3, - ; 1); - vmlal.u8 q4, d6, d26 - vld1.u32 {d7[1]},[r3], r2 ;src_tmp4 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp4, 1); - vmlsl.u8 q1, d7, d29 ;mul_res2 = vmlsl_u8(mul_res2, - ; vreinterpret_u8_u32(src_tmp4), coeffabs_7); - vdup.u32 d4, d7[1] - vadd.i16 q0, q0, q1 ;mul_res1 = vaddq_u16(mul_res1, - ; mul_res2); - vmlsl.u8 q4, d7, d27 - vld1.u32 {d4[1]},[r3], r2 - vmlal.u8 q4, d4, d28 - vdup.u32 d5, d4[1] - vhadd.s16 q0, q0, q15 - vqrshrun.s16 d0, q0, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vld1.u32 {d5[1]},[r3] - add r3, r1, r6 - vld1.u32 {d20[0]}, [r1] - vld1.u32 {d20[1]}, [r3] - vrhadd.u8 d0, d0, d20 - vst1.32 {d0[0]},[r1] ;vst1_lane_u32((uint32_t *)pu1_dst, - ; vreinterpret_u32_u8(sto_res), 0); - vmlsl.u8 q4, d5, d29 - vst1.32 {d0[1]},[r3], r6 ;vst1_lane_u32((uint32_t - ; *)pu1_dst_tmp, vreinterpret_u32_u8(sto_res), 1); - vhadd.s16 q4, q4, q15 - vqrshrun.s16 d8, q4, #6 - mov r4, r3 - vld1.u32 {d20[0]}, [r4], r6 - vld1.u32 {d20[1]}, [r4] - vrhadd.u8 d8, d8, d20 - vst1.32 {d8[0]},[r3], r6 - add r1, r1, #4 - vst1.32 {d8[1]},[r3] - bgt inner_loop_wd_4 - -end_inner_loop_wd_4 - subs r7, r7, #4 - add r1, r1, r9 - add r0, r0, r8 - bgt outer_loop_wd_4 - - vpop {d8 - d15} - ldmfd sp!, {r4 - r12, r15} ;reload the registers from sp - - ENDP - - END diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_horiz_filter_type1_neon.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_horiz_filter_type1_neon.asm deleted file mode 100644 index fa1b7324..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_horiz_filter_type1_neon.asm +++ /dev/null @@ -1,415 +0,0 @@ -; -; Copyright (c) 2018 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; -;**************Variables Vs Registers*********************************** -; r0 => src -; r1 => dst -; r2 => src_stride -; r3 => dst_stride -; r4 => filter_x0 -; r8 => ht -; r10 => wd - - EXPORT |vpx_convolve8_horiz_filter_type1_neon| - ARM - REQUIRE8 - PRESERVE8 - - AREA ||.text||, CODE, READONLY, ALIGN=2 - -|vpx_convolve8_horiz_filter_type1_neon| PROC - - stmfd sp!, {r4 - r12, r14} ;stack stores the values of - ; the arguments - vpush {d8 - d15} ; stack offset by 64 - mov r4, r1 - mov r1, r2 - mov r2, r4 -start_loop_count - ldr r4, [sp, #104] ;loads pi1_coeff - ldr r8, [sp, #108] ;loads x0_q4 - add r4, r4, r8, lsl #4 ;r4 = filter[x0_q4] - ldr r8, [sp, #128] ;loads ht - ldr r10, [sp, #124] ;loads wd - vld2.8 {d0, d1}, [r4] ;coeff = vld1_s8(pi1_coeff) - mov r11, #1 - subs r14, r8, #0 ;checks for ht == 0 - vabs.s8 d2, d0 ;vabs_s8(coeff) - vdup.8 d24, d2[0] ;coeffabs_0 = vdup_lane_u8(coeffabs, - ; 0) - sub r12, r0, #3 ;pu1_src - 3 - vdup.8 d25, d2[1] ;coeffabs_1 = vdup_lane_u8(coeffabs, - ; 1) - add r4, r12, r2 ;pu1_src_tmp2_8 = pu1_src + src_strd - vdup.8 d26, d2[2] ;coeffabs_2 = vdup_lane_u8(coeffabs, - ; 2) - rsb r9, r10, r2, lsl #1 ;2*src_strd - wd - vdup.8 d27, d2[3] ;coeffabs_3 = vdup_lane_u8(coeffabs, - ; 3) - rsb r8, r10, r3, lsl #1 ;2*dst_strd - wd - vdup.8 d28, d2[4] ;coeffabs_4 = vdup_lane_u8(coeffabs, - ; 4) - vdup.8 d29, d2[5] ;coeffabs_5 = vdup_lane_u8(coeffabs, - ; 5) - vdup.8 d30, d2[6] ;coeffabs_6 = vdup_lane_u8(coeffabs, - ; 6) - vdup.8 d31, d2[7] ;coeffabs_7 = vdup_lane_u8(coeffabs, - ; 7) - mov r7, r1 - cmp r10, #4 - ble outer_loop_4 - - cmp r10, #24 - moveq r10, #16 - addeq r8, #8 - addeq r9, #8 - cmp r10, #16 - bge outer_loop_16 - - cmp r10, #12 - addeq r8, #4 - addeq r9, #4 - b outer_loop_8 - -outer_loop8_residual - sub r12, r0, #3 ;pu1_src - 3 - mov r1, r7 - mov r14, #32 - add r1, #16 - add r12, #16 - mov r10, #8 - add r8, #8 - add r9, #8 - -outer_loop_8 - - add r6, r1, r3 ;pu1_dst + dst_strd - add r4, r12, r2 ;pu1_src + src_strd - subs r5, r10, #0 ;checks wd - ble end_inner_loop_8 - -inner_loop_8 - mov r7, #0xc000 - vld1.u32 {d0}, [r12], r11 ;vector load pu1_src - vdup.16 q4, r7 - vld1.u32 {d1}, [r12], r11 - vdup.16 q5, r7 - vld1.u32 {d2}, [r12], r11 - vld1.u32 {d3}, [r12], r11 - mov r7, #0x4000 - vld1.u32 {d4}, [r12], r11 - vmlsl.u8 q4, d1, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vld1.u32 {d5}, [r12], r11 - vmlal.u8 q4, d3, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - vld1.u32 {d6}, [r12], r11 - vmlsl.u8 q4, d0, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vld1.u32 {d7}, [r12], r11 - vmlal.u8 q4, d2, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vld1.u32 {d12}, [r4], r11 ;vector load pu1_src + src_strd - vmlal.u8 q4, d4, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vld1.u32 {d13}, [r4], r11 - vmlal.u8 q4, d5, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vld1.u32 {d14}, [r4], r11 - vmlsl.u8 q4, d6, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vld1.u32 {d15}, [r4], r11 - vmlsl.u8 q4, d7, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - vld1.u32 {d16}, [r4], r11 ;vector load pu1_src + src_strd - vdup.16 q11, r7 - vmlal.u8 q5, d15, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - vld1.u32 {d17}, [r4], r11 - vmlal.u8 q5, d14, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vhadd.s16 q4, q4, q11 - vld1.u32 {d18}, [r4], r11 - vmlal.u8 q5, d16, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vld1.u32 {d19}, [r4], r11 ;vector load pu1_src + src_strd - vmlal.u8 q5, d17, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vmlsl.u8 q5, d18, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vmlsl.u8 q5, d19, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - vqrshrun.s16 d20, q4, #6 ;right shift and saturating narrow - ; result 1 - vmlsl.u8 q5, d12, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vmlsl.u8 q5, d13, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vst1.8 {d20}, [r1]! ;store the result pu1_dst - vhadd.s16 q5, q5, q11 - subs r5, r5, #8 ;decrement the wd loop - vqrshrun.s16 d8, q5, #6 ;right shift and saturating narrow - ; result 2 - vst1.8 {d8}, [r6]! ;store the result pu1_dst - cmp r5, #4 - bgt inner_loop_8 - -end_inner_loop_8 - subs r14, r14, #2 ;decrement the ht loop - add r12, r12, r9 ;increment the src pointer by - ; 2*src_strd-wd - add r1, r1, r8 ;increment the dst pointer by - ; 2*dst_strd-wd - bgt outer_loop_8 - - ldr r10, [sp, #120] ;loads wd - cmp r10, #12 - beq outer_loop4_residual - -end_loops - b end_func - -outer_loop_16 - str r0, [sp, #-4]! - str r7, [sp, #-4]! - add r6, r1, r3 ;pu1_dst + dst_strd - add r4, r12, r2 ;pu1_src + src_strd - and r0, r12, #31 - mov r7, #0xc000 - sub r5, r10, #0 ;checks wd - pld [r4, r2, lsl #1] - pld [r12, r2, lsl #1] - vld1.u32 {q0}, [r12], r11 ;vector load pu1_src - vdup.16 q4, r7 - vld1.u32 {q1}, [r12], r11 - vld1.u32 {q2}, [r12], r11 - vld1.u32 {q3}, [r12], r11 - vmlsl.u8 q4, d0, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vld1.u32 {q6}, [r12], r11 - vmlsl.u8 q4, d2, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vld1.u32 {q7}, [r12], r11 - vmlal.u8 q4, d4, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vld1.u32 {q8}, [r12], r11 - vmlal.u8 q4, d6, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - vld1.u32 {q9}, [r12], r11 - vmlal.u8 q4, d12, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vmlal.u8 q4, d14, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vdup.16 q10, r7 - vmlsl.u8 q4, d16, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vmlsl.u8 q4, d18, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - -inner_loop_16 - vmlsl.u8 q10, d1, d24 - vdup.16 q5, r7 - vmlsl.u8 q10, d3, d25 - mov r7, #0x4000 - vdup.16 q11, r7 - vmlal.u8 q10, d5, d26 - vld1.u32 {q0}, [r4], r11 ;vector load pu1_src - vhadd.s16 q4, q4, q11 - vld1.u32 {q1}, [r4], r11 - vmlal.u8 q10, d7, d27 - add r12, #8 - subs r5, r5, #16 - vmlal.u8 q10, d13, d28 - vld1.u32 {q2}, [r4], r11 - vmlal.u8 q10, d15, d29 - vld1.u32 {q3}, [r4], r11 - vqrshrun.s16 d8, q4, #6 ;right shift and saturating narrow - ; result 1 - vmlsl.u8 q10, d17, d30 - vld1.u32 {q6}, [r4], r11 - vmlsl.u8 q10, d19, d31 - vld1.u32 {q7}, [r4], r11 - vmlsl.u8 q5, d0, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vmlsl.u8 q5, d2, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vld1.u32 {q8}, [r4], r11 - vhadd.s16 q10, q10, q11 - vld1.u32 {q9}, [r4], r11 - vmlal.u8 q5, d4, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vmlal.u8 q5, d6, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - add r4, #8 - mov r7, #0xc000 - vmlal.u8 q5, d12, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vmlal.u8 q5, d14, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vqrshrun.s16 d9, q10, #6 - vdup.16 q11, r7 - vmlsl.u8 q5, d16, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vmlsl.u8 q5, d18, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - mov r7, #0x4000 - vmlsl.u8 q11, d1, d24 - vst1.8 {q4}, [r1]! ;store the result pu1_dst - vmlsl.u8 q11, d3, d25 - vdup.16 q10, r7 - vmlal.u8 q11, d5, d26 - pld [r12, r2, lsl #2] - pld [r4, r2, lsl #2] - addeq r12, r12, r9 ;increment the src pointer by - ; 2*src_strd-wd - addeq r4, r12, r2 ;pu1_src + src_strd - vmlal.u8 q11, d7, d27 - addeq r1, r1, r8 - subeq r14, r14, #2 - vmlal.u8 q11, d13, d28 - vhadd.s16 q5, q5, q10 - vmlal.u8 q11, d15, d29 - vmlsl.u8 q11, d17, d30 - cmp r14, #0 - vmlsl.u8 q11, d19, d31 - vqrshrun.s16 d10, q5, #6 ;right shift and saturating narrow - ; result 2 - beq epilog_16 - - vld1.u32 {q0}, [r12], r11 ;vector load pu1_src - mov r7, #0xc000 - cmp r5, #0 - vld1.u32 {q1}, [r12], r11 - vhadd.s16 q11, q11, q10 - vld1.u32 {q2}, [r12], r11 - vdup.16 q4, r7 - vld1.u32 {q3}, [r12], r11 - vmlsl.u8 q4, d0, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vld1.u32 {q6}, [r12], r11 - vld1.u32 {q7}, [r12], r11 - vmlsl.u8 q4, d2, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vld1.u32 {q8}, [r12], r11 - vmlal.u8 q4, d4, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vld1.u32 {q9}, [r12], r11 - vqrshrun.s16 d11, q11, #6 - vmlal.u8 q4, d6, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - moveq r5, r10 - vmlal.u8 q4, d12, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vdup.16 q10, r7 - vmlal.u8 q4, d14, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vst1.8 {q5}, [r6]! ;store the result pu1_dst - vmlsl.u8 q4, d16, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vmlsl.u8 q4, d18, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - addeq r6, r1, r3 ;pu1_dst + dst_strd - b inner_loop_16 - -epilog_16 - mov r7, #0x4000 - ldr r0, [sp], #4 - ldr r10, [sp, #120] - vdup.16 q10, r7 - vhadd.s16 q11, q11, q10 - vqrshrun.s16 d11, q11, #6 - vst1.8 {q5}, [r6]! ;store the result pu1_dst - ldr r7, [sp], #4 - cmp r10, #24 - beq outer_loop8_residual - -end_loops1 - b end_func - -outer_loop4_residual - sub r12, r0, #3 ;pu1_src - 3 - mov r1, r7 - add r1, #8 - mov r10, #4 - add r12, #8 - mov r14, #16 - add r8, #4 - add r9, #4 - -outer_loop_4 - add r6, r1, r3 ;pu1_dst + dst_strd - add r4, r12, r2 ;pu1_src + src_strd - subs r5, r10, #0 ;checks wd - ble end_inner_loop_4 - -inner_loop_4 - vld1.u32 {d0}, [r12], r11 ;vector load pu1_src - vld1.u32 {d1}, [r12], r11 - vld1.u32 {d2}, [r12], r11 - vld1.u32 {d3}, [r12], r11 - vld1.u32 {d4}, [r12], r11 - vld1.u32 {d5}, [r12], r11 - vld1.u32 {d6}, [r12], r11 - vld1.u32 {d7}, [r12], r11 - sub r12, r12, #4 - vld1.u32 {d12}, [r4], r11 ;vector load pu1_src + src_strd - vld1.u32 {d13}, [r4], r11 - vzip.32 d0, d12 ;vector zip the i iteration and ii - ; interation in single register - vld1.u32 {d14}, [r4], r11 - vzip.32 d1, d13 - vld1.u32 {d15}, [r4], r11 - vzip.32 d2, d14 - vld1.u32 {d16}, [r4], r11 - vzip.32 d3, d15 - vld1.u32 {d17}, [r4], r11 - vzip.32 d4, d16 - vld1.u32 {d18}, [r4], r11 - vzip.32 d5, d17 - vld1.u32 {d19}, [r4], r11 - mov r7, #0xc000 - vdup.16 q4, r7 - sub r4, r4, #4 - vzip.32 d6, d18 - vzip.32 d7, d19 - vmlsl.u8 q4, d1, d25 ;arithmetic operations for ii - ; iteration in the same time - vmlsl.u8 q4, d0, d24 - vmlal.u8 q4, d2, d26 - vmlal.u8 q4, d3, d27 - vmlal.u8 q4, d4, d28 - vmlal.u8 q4, d5, d29 - vmlsl.u8 q4, d6, d30 - vmlsl.u8 q4, d7, d31 - mov r7, #0x4000 - vdup.16 q10, r7 - vhadd.s16 q4, q4, q10 - vqrshrun.s16 d8, q4, #6 - vst1.32 {d8[0]},[r1]! ;store the i iteration result which - ; is in upper part of the register - vst1.32 {d8[1]},[r6]! ;store the ii iteration result which - ; is in lower part of the register - subs r5, r5, #4 ;decrement the wd by 4 - bgt inner_loop_4 - -end_inner_loop_4 - subs r14, r14, #2 ;decrement the ht by 4 - add r12, r12, r9 ;increment the input pointer - ; 2*src_strd-wd - add r1, r1, r8 ;increment the output pointer - ; 2*dst_strd-wd - bgt outer_loop_4 - -end_func - vpop {d8 - d15} - ldmfd sp!, {r4 - r12, r15} ;reload the registers from sp - - ENDP - - END diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_horiz_filter_type2_neon.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_horiz_filter_type2_neon.asm deleted file mode 100644 index 90b2c8fe..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_horiz_filter_type2_neon.asm +++ /dev/null @@ -1,415 +0,0 @@ -; -; Copyright (c) 2018 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; -;**************Variables Vs Registers*********************************** -; r0 => src -; r1 => dst -; r2 => src_stride -; r3 => dst_stride -; r4 => filter_x0 -; r8 => ht -; r10 => wd - - EXPORT |vpx_convolve8_horiz_filter_type2_neon| - ARM - REQUIRE8 - PRESERVE8 - - AREA ||.text||, CODE, READONLY, ALIGN=2 - -|vpx_convolve8_horiz_filter_type2_neon| PROC - - stmfd sp!, {r4 - r12, r14} ;stack stores the values of - ; the arguments - vpush {d8 - d15} ; stack offset by 64 - mov r4, r1 - mov r1, r2 - mov r2, r4 - -start_loop_count - ldr r4, [sp, #104] ;loads pi1_coeff - ldr r8, [sp, #108] ;loads x0_q4 - add r4, r4, r8, lsl #4 ;r4 = filter[x0_q4] - ldr r8, [sp, #128] ;loads ht - ldr r10, [sp, #124] ;loads wd - vld2.8 {d0, d1}, [r4] ;coeff = vld1_s8(pi1_coeff) - mov r11, #1 - subs r14, r8, #0 ;checks for ht == 0 - vabs.s8 d2, d0 ;vabs_s8(coeff) - vdup.8 d24, d2[0] ;coeffabs_0 = vdup_lane_u8(coeffabs, - ; 0) - sub r12, r0, #3 ;pu1_src - 3 - vdup.8 d25, d2[1] ;coeffabs_1 = vdup_lane_u8(coeffabs, - ; 1) - add r4, r12, r2 ;pu1_src_tmp2_8 = pu1_src + src_strd - vdup.8 d26, d2[2] ;coeffabs_2 = vdup_lane_u8(coeffabs, - ; 2) - rsb r9, r10, r2, lsl #1 ;2*src_strd - wd - vdup.8 d27, d2[3] ;coeffabs_3 = vdup_lane_u8(coeffabs, - ; 3) - rsb r8, r10, r3, lsl #1 ;2*dst_strd - wd - vdup.8 d28, d2[4] ;coeffabs_4 = vdup_lane_u8(coeffabs, - ; 4) - vdup.8 d29, d2[5] ;coeffabs_5 = vdup_lane_u8(coeffabs, - ; 5) - vdup.8 d30, d2[6] ;coeffabs_6 = vdup_lane_u8(coeffabs, - ; 6) - vdup.8 d31, d2[7] ;coeffabs_7 = vdup_lane_u8(coeffabs, - ; 7) - mov r7, r1 - cmp r10, #4 - ble outer_loop_4 - - cmp r10, #24 - moveq r10, #16 - addeq r8, #8 - addeq r9, #8 - cmp r10, #16 - bge outer_loop_16 - - cmp r10, #12 - addeq r8, #4 - addeq r9, #4 - b outer_loop_8 - -outer_loop8_residual - sub r12, r0, #3 ;pu1_src - 3 - mov r1, r7 - mov r14, #32 - add r1, #16 - add r12, #16 - mov r10, #8 - add r8, #8 - add r9, #8 - -outer_loop_8 - add r6, r1, r3 ;pu1_dst + dst_strd - add r4, r12, r2 ;pu1_src + src_strd - subs r5, r10, #0 ;checks wd - ble end_inner_loop_8 - -inner_loop_8 - mov r7, #0xc000 - vld1.u32 {d0}, [r12], r11 ;vector load pu1_src - vdup.16 q4, r7 - vld1.u32 {d1}, [r12], r11 - vdup.16 q5, r7 - vld1.u32 {d2}, [r12], r11 - vld1.u32 {d3}, [r12], r11 - mov r7, #0x4000 - vld1.u32 {d4}, [r12], r11 - vmlal.u8 q4, d1, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vld1.u32 {d5}, [r12], r11 - vmlal.u8 q4, d3, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - vld1.u32 {d6}, [r12], r11 - vmlsl.u8 q4, d0, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vld1.u32 {d7}, [r12], r11 - vmlsl.u8 q4, d2, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vld1.u32 {d12}, [r4], r11 ;vector load pu1_src + src_strd - vmlal.u8 q4, d4, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vld1.u32 {d13}, [r4], r11 - vmlsl.u8 q4, d5, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vld1.u32 {d14}, [r4], r11 - vmlal.u8 q4, d6, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vld1.u32 {d15}, [r4], r11 - vmlsl.u8 q4, d7, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - vld1.u32 {d16}, [r4], r11 ;vector load pu1_src + src_strd - vdup.16 q11, r7 - vmlal.u8 q5, d15, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - vld1.u32 {d17}, [r4], r11 - vmlsl.u8 q5, d14, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vhadd.s16 q4, q4, q11 - vld1.u32 {d18}, [r4], r11 - vmlal.u8 q5, d16, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vld1.u32 {d19}, [r4], r11 ;vector load pu1_src + src_strd - vmlsl.u8 q5, d17, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vmlal.u8 q5, d18, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vmlsl.u8 q5, d19, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - vqrshrun.s16 d20, q4, #6 ;right shift and saturating narrow - ; result 1 - vmlsl.u8 q5, d12, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vmlal.u8 q5, d13, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vst1.8 {d20}, [r1]! ;store the result pu1_dst - vhadd.s16 q5, q5, q11 - subs r5, r5, #8 ;decrement the wd loop - vqrshrun.s16 d8, q5, #6 ;right shift and saturating narrow - ; result 2 - vst1.8 {d8}, [r6]! ;store the result pu1_dst - cmp r5, #4 - bgt inner_loop_8 - -end_inner_loop_8 - subs r14, r14, #2 ;decrement the ht loop - add r12, r12, r9 ;increment the src pointer by - ; 2*src_strd-wd - add r1, r1, r8 ;increment the dst pointer by - ; 2*dst_strd-wd - bgt outer_loop_8 - - ldr r10, [sp, #120] ;loads wd - cmp r10, #12 - beq outer_loop4_residual - -end_loops - b end_func - -outer_loop_16 - str r0, [sp, #-4]! - str r7, [sp, #-4]! - add r6, r1, r3 ;pu1_dst + dst_strd - add r4, r12, r2 ;pu1_src + src_strd - and r0, r12, #31 - mov r7, #0xc000 - sub r5, r10, #0 ;checks wd - pld [r4, r2, lsl #1] - pld [r12, r2, lsl #1] - vld1.u32 {q0}, [r12], r11 ;vector load pu1_src - vdup.16 q4, r7 - vld1.u32 {q1}, [r12], r11 - vld1.u32 {q2}, [r12], r11 - vld1.u32 {q3}, [r12], r11 - vmlsl.u8 q4, d0, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vld1.u32 {q6}, [r12], r11 - vmlal.u8 q4, d2, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vld1.u32 {q7}, [r12], r11 - vmlsl.u8 q4, d4, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vld1.u32 {q8}, [r12], r11 - vmlal.u8 q4, d6, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - vld1.u32 {q9}, [r12], r11 - vmlal.u8 q4, d12, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vmlsl.u8 q4, d14, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vdup.16 q10, r7 - vmlal.u8 q4, d16, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vmlsl.u8 q4, d18, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - -inner_loop_16 - vmlsl.u8 q10, d1, d24 - vdup.16 q5, r7 - vmlal.u8 q10, d3, d25 - mov r7, #0x4000 - vdup.16 q11, r7 - vmlsl.u8 q10, d5, d26 - vld1.u32 {q0}, [r4], r11 ;vector load pu1_src - vhadd.s16 q4, q4, q11 - vld1.u32 {q1}, [r4], r11 - vmlal.u8 q10, d7, d27 - add r12, #8 - subs r5, r5, #16 - vmlal.u8 q10, d13, d28 - vld1.u32 {q2}, [r4], r11 - vmlsl.u8 q10, d15, d29 - vld1.u32 {q3}, [r4], r11 - vqrshrun.s16 d8, q4, #6 ;right shift and saturating narrow - ; result 1 - vmlal.u8 q10, d17, d30 - vld1.u32 {q6}, [r4], r11 - vmlsl.u8 q10, d19, d31 - vld1.u32 {q7}, [r4], r11 - vmlsl.u8 q5, d0, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vmlal.u8 q5, d2, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vld1.u32 {q8}, [r4], r11 - vhadd.s16 q10, q10, q11 - vld1.u32 {q9}, [r4], r11 - vmlsl.u8 q5, d4, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vmlal.u8 q5, d6, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - add r4, #8 - mov r7, #0xc000 - vmlal.u8 q5, d12, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vmlsl.u8 q5, d14, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vqrshrun.s16 d9, q10, #6 - vdup.16 q11, r7 - vmlal.u8 q5, d16, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vmlsl.u8 q5, d18, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - mov r7, #0x4000 - vmlsl.u8 q11, d1, d24 - vst1.8 {q4}, [r1]! ;store the result pu1_dst - vmlal.u8 q11, d3, d25 - vdup.16 q10, r7 - vmlsl.u8 q11, d5, d26 - pld [r12, r2, lsl #2] - pld [r4, r2, lsl #2] - addeq r12, r12, r9 ;increment the src pointer by - ; 2*src_strd-wd - addeq r4, r12, r2 ;pu1_src + src_strd - vmlal.u8 q11, d7, d27 - addeq r1, r1, r8 - subeq r14, r14, #2 - vmlal.u8 q11, d13, d28 - vhadd.s16 q5, q5, q10 - vmlsl.u8 q11, d15, d29 - vmlal.u8 q11, d17, d30 - cmp r14, #0 - vmlsl.u8 q11, d19, d31 - vqrshrun.s16 d10, q5, #6 ;right shift and saturating narrow - ; result 2 - beq epilog_16 - - vld1.u32 {q0}, [r12], r11 ;vector load pu1_src - mov r7, #0xc000 - cmp r5, #0 - vld1.u32 {q1}, [r12], r11 - vhadd.s16 q11, q11, q10 - vld1.u32 {q2}, [r12], r11 - vdup.16 q4, r7 - vld1.u32 {q3}, [r12], r11 - vmlsl.u8 q4, d0, d24 ;mul_res = vmlsl_u8(src[0_0], - ; coeffabs_0); - vld1.u32 {q6}, [r12], r11 - vld1.u32 {q7}, [r12], r11 - vmlal.u8 q4, d2, d25 ;mul_res = vmlal_u8(src[0_1], - ; coeffabs_1); - vld1.u32 {q8}, [r12], r11 - vmlsl.u8 q4, d4, d26 ;mul_res = vmlsl_u8(src[0_2], - ; coeffabs_2); - vld1.u32 {q9}, [r12], r11 - vqrshrun.s16 d11, q11, #6 - vmlal.u8 q4, d6, d27 ;mul_res = vmull_u8(src[0_3], - ; coeffabs_3); - moveq r5, r10 - vmlal.u8 q4, d12, d28 ;mul_res = vmlal_u8(src[0_4], - ; coeffabs_4); - vdup.16 q10, r7 - vmlsl.u8 q4, d14, d29 ;mul_res = vmlsl_u8(src[0_5], - ; coeffabs_5); - vst1.8 {q5}, [r6]! ;store the result pu1_dst - vmlal.u8 q4, d16, d30 ;mul_res = vmlal_u8(src[0_6], - ; coeffabs_6); - vmlsl.u8 q4, d18, d31 ;mul_res = vmlsl_u8(src[0_7], - ; coeffabs_7); - addeq r6, r1, r3 ;pu1_dst + dst_strd - b inner_loop_16 - -epilog_16 - mov r7, #0x4000 - ldr r0, [sp], #4 - ldr r10, [sp, #120] - vdup.16 q10, r7 - vhadd.s16 q11, q11, q10 - vqrshrun.s16 d11, q11, #6 - vst1.8 {q5}, [r6]! ;store the result pu1_dst - ldr r7, [sp], #4 - cmp r10, #24 - beq outer_loop8_residual - -end_loops1 - b end_func - -outer_loop4_residual - sub r12, r0, #3 ;pu1_src - 3 - mov r1, r7 - add r1, #8 - mov r10, #4 - add r12, #8 - mov r14, #16 - add r8, #4 - add r9, #4 - -outer_loop_4 - add r6, r1, r3 ;pu1_dst + dst_strd - add r4, r12, r2 ;pu1_src + src_strd - subs r5, r10, #0 ;checks wd - ble end_inner_loop_4 - -inner_loop_4 - vld1.u32 {d0}, [r12], r11 ;vector load pu1_src - vld1.u32 {d1}, [r12], r11 - vld1.u32 {d2}, [r12], r11 - vld1.u32 {d3}, [r12], r11 - vld1.u32 {d4}, [r12], r11 - vld1.u32 {d5}, [r12], r11 - vld1.u32 {d6}, [r12], r11 - vld1.u32 {d7}, [r12], r11 - sub r12, r12, #4 - vld1.u32 {d12}, [r4], r11 ;vector load pu1_src + src_strd - vld1.u32 {d13}, [r4], r11 - vzip.32 d0, d12 ;vector zip the i iteration and ii - ; interation in single register - vld1.u32 {d14}, [r4], r11 - vzip.32 d1, d13 - vld1.u32 {d15}, [r4], r11 - vzip.32 d2, d14 - vld1.u32 {d16}, [r4], r11 - vzip.32 d3, d15 - vld1.u32 {d17}, [r4], r11 - vzip.32 d4, d16 - vld1.u32 {d18}, [r4], r11 - vzip.32 d5, d17 - vld1.u32 {d19}, [r4], r11 - mov r7, #0xc000 - vdup.16 q4, r7 - sub r4, r4, #4 - vzip.32 d6, d18 - vzip.32 d7, d19 - vmlal.u8 q4, d1, d25 ;arithmetic operations for ii - ; iteration in the same time - vmlsl.u8 q4, d0, d24 - vmlsl.u8 q4, d2, d26 - vmlal.u8 q4, d3, d27 - vmlal.u8 q4, d4, d28 - vmlsl.u8 q4, d5, d29 - vmlal.u8 q4, d6, d30 - vmlsl.u8 q4, d7, d31 - mov r7, #0x4000 - vdup.16 q10, r7 - vhadd.s16 q4, q4, q10 - vqrshrun.s16 d8, q4, #6 - vst1.32 {d8[0]},[r1]! ;store the i iteration result which - ; is in upper part of the register - vst1.32 {d8[1]},[r6]! ;store the ii iteration result which - ; is in lower part of the register - subs r5, r5, #4 ;decrement the wd by 4 - bgt inner_loop_4 - -end_inner_loop_4 - subs r14, r14, #2 ;decrement the ht by 4 - add r12, r12, r9 ;increment the input pointer - ; 2*src_strd-wd - add r1, r1, r8 ;increment the output pointer - ; 2*dst_strd-wd - bgt outer_loop_4 - -end_func - vpop {d8 - d15} - ldmfd sp!, {r4 - r12, r15} ;reload the registers from sp - - ENDP - - END diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon.c deleted file mode 100644 index 037ea114..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon.c +++ /dev/null @@ -1,710 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/arm/vpx_convolve8_neon.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_ports/mem.h" - -static INLINE void convolve_4tap_horiz_neon(const uint8_t *src, - ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, int w, int h, - const int16x8_t filter) { - // 4-tap and bilinear filter values are even, so halve them to reduce - // intermediate precision requirements. - const uint8x8_t x_filter = - vshrn_n_u16(vreinterpretq_u16_s16(vabsq_s16(filter)), 1); - - // Neon does not have lane-referencing multiply or multiply-accumulate - // instructions that operate on vectors of 8-bit elements. This means we have - // to duplicate filter taps into a whole vector and use standard multiply / - // multiply-accumulate instructions. - const uint8x8_t filter_taps[4] = { vdup_lane_u8(x_filter, 2), - vdup_lane_u8(x_filter, 3), - vdup_lane_u8(x_filter, 4), - vdup_lane_u8(x_filter, 5) }; - - if (w == 4) { - do { - uint8x8_t s01[4]; - - s01[0] = load_unaligned_u8(src + 0, src_stride); - s01[1] = load_unaligned_u8(src + 1, src_stride); - s01[2] = load_unaligned_u8(src + 2, src_stride); - s01[3] = load_unaligned_u8(src + 3, src_stride); - - uint8x8_t d01 = convolve4_8(s01[0], s01[1], s01[2], s01[3], filter_taps); - - store_unaligned_u8(dst, dst_stride, d01); - - src += 2 * src_stride; - dst += 2 * dst_stride; - h -= 2; - } while (h > 0); - } else { - do { - const uint8_t *s = src; - uint8_t *d = dst; - int width = w; - - do { - uint8x8_t s0[4], s1[4]; - - s0[0] = vld1_u8(s + 0); - s0[1] = vld1_u8(s + 1); - s0[2] = vld1_u8(s + 2); - s0[3] = vld1_u8(s + 3); - - s1[0] = vld1_u8(s + src_stride + 0); - s1[1] = vld1_u8(s + src_stride + 1); - s1[2] = vld1_u8(s + src_stride + 2); - s1[3] = vld1_u8(s + src_stride + 3); - - uint8x8_t d0 = convolve4_8(s0[0], s0[1], s0[2], s0[3], filter_taps); - uint8x8_t d1 = convolve4_8(s1[0], s1[1], s1[2], s1[3], filter_taps); - - vst1_u8(d, d0); - vst1_u8(d + dst_stride, d1); - s += 8; - d += 8; - width -= 8; - } while (width != 0); - src += 2 * src_stride; - dst += 2 * dst_stride; - h -= 2; - } while (h > 0); - } -} - -static INLINE void convolve_8tap_horiz_neon(const uint8_t *src, - ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, int w, int h, - const int16x8_t filter) { - if (h == 4) { - uint8x8_t t0, t1, t2, t3; - load_u8_8x4(src, src_stride, &t0, &t1, &t2, &t3); - - transpose_u8_8x4(&t0, &t1, &t2, &t3); - int16x4_t s0 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t0))); - int16x4_t s1 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t1))); - int16x4_t s2 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t2))); - int16x4_t s3 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t3))); - int16x4_t s4 = vget_high_s16(vreinterpretq_s16_u16(vmovl_u8(t0))); - int16x4_t s5 = vget_high_s16(vreinterpretq_s16_u16(vmovl_u8(t1))); - int16x4_t s6 = vget_high_s16(vreinterpretq_s16_u16(vmovl_u8(t2))); - - src += 7; - - do { - uint8x8_t t7, t8, t9, t10; - load_u8_8x4(src, src_stride, &t7, &t8, &t9, &t10); - - transpose_u8_8x4(&t7, &t8, &t9, &t10); - int16x4_t s7 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t7))); - int16x4_t s8 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t8))); - int16x4_t s9 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t9))); - int16x4_t s10 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t10))); - - int16x4_t d0 = convolve8_4(s0, s1, s2, s3, s4, s5, s6, s7, filter); - int16x4_t d1 = convolve8_4(s1, s2, s3, s4, s5, s6, s7, s8, filter); - int16x4_t d2 = convolve8_4(s2, s3, s4, s5, s6, s7, s8, s9, filter); - int16x4_t d3 = convolve8_4(s3, s4, s5, s6, s7, s8, s9, s10, filter); - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(d0, d1), FILTER_BITS); - uint8x8_t d23 = vqrshrun_n_s16(vcombine_s16(d2, d3), FILTER_BITS); - - transpose_u8_4x4(&d01, &d23); - - store_u8(dst + 0 * dst_stride, 2 * dst_stride, d01); - store_u8(dst + 1 * dst_stride, 2 * dst_stride, d23); - - s0 = s4; - s1 = s5; - s2 = s6; - s3 = s7; - s4 = s8; - s5 = s9; - s6 = s10; - src += 4; - dst += 4; - w -= 4; - } while (w != 0); - } else { - if (w == 4) { - do { - uint8x8_t t0, t1, t2, t3, t4, t5, t6, t7; - load_u8_8x8(src, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7); - - transpose_u8_8x8(&t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7); - int16x8_t s0 = vreinterpretq_s16_u16(vmovl_u8(t0)); - int16x8_t s1 = vreinterpretq_s16_u16(vmovl_u8(t1)); - int16x8_t s2 = vreinterpretq_s16_u16(vmovl_u8(t2)); - int16x8_t s3 = vreinterpretq_s16_u16(vmovl_u8(t3)); - int16x8_t s4 = vreinterpretq_s16_u16(vmovl_u8(t4)); - int16x8_t s5 = vreinterpretq_s16_u16(vmovl_u8(t5)); - int16x8_t s6 = vreinterpretq_s16_u16(vmovl_u8(t6)); - - load_u8_8x8(src + 7, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6, - &t7); - - transpose_u8_4x8(&t0, &t1, &t2, &t3, t4, t5, t6, t7); - int16x8_t s7 = vreinterpretq_s16_u16(vmovl_u8(t0)); - int16x8_t s8 = vreinterpretq_s16_u16(vmovl_u8(t1)); - int16x8_t s9 = vreinterpretq_s16_u16(vmovl_u8(t2)); - int16x8_t s10 = vreinterpretq_s16_u16(vmovl_u8(t3)); - - uint8x8_t d04 = convolve8_8(s0, s1, s2, s3, s4, s5, s6, s7, filter); - uint8x8_t d15 = convolve8_8(s1, s2, s3, s4, s5, s6, s7, s8, filter); - uint8x8_t d26 = convolve8_8(s2, s3, s4, s5, s6, s7, s8, s9, filter); - uint8x8_t d37 = convolve8_8(s3, s4, s5, s6, s7, s8, s9, s10, filter); - - transpose_u8_8x4(&d04, &d15, &d26, &d37); - - store_u8(dst + 0 * dst_stride, 4 * dst_stride, d04); - store_u8(dst + 1 * dst_stride, 4 * dst_stride, d15); - store_u8(dst + 2 * dst_stride, 4 * dst_stride, d26); - store_u8(dst + 3 * dst_stride, 4 * dst_stride, d37); - - src += 8 * src_stride; - dst += 8 * dst_stride; - h -= 8; - } while (h > 0); - } else { - do { - uint8x8_t t0, t1, t2, t3, t4, t5, t6, t7; - load_u8_8x8(src, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7); - - transpose_u8_8x8(&t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7); - int16x8_t s0 = vreinterpretq_s16_u16(vmovl_u8(t0)); - int16x8_t s1 = vreinterpretq_s16_u16(vmovl_u8(t1)); - int16x8_t s2 = vreinterpretq_s16_u16(vmovl_u8(t2)); - int16x8_t s3 = vreinterpretq_s16_u16(vmovl_u8(t3)); - int16x8_t s4 = vreinterpretq_s16_u16(vmovl_u8(t4)); - int16x8_t s5 = vreinterpretq_s16_u16(vmovl_u8(t5)); - int16x8_t s6 = vreinterpretq_s16_u16(vmovl_u8(t6)); - - const uint8_t *s = src + 7; - uint8_t *d = dst; - int width = w; - - do { - uint8x8_t t8, t9, t10, t11, t12, t13, t14, t15; - load_u8_8x8(s, src_stride, &t8, &t9, &t10, &t11, &t12, &t13, &t14, - &t15); - - transpose_u8_8x8(&t8, &t9, &t10, &t11, &t12, &t13, &t14, &t15); - int16x8_t s7 = vreinterpretq_s16_u16(vmovl_u8(t8)); - int16x8_t s8 = vreinterpretq_s16_u16(vmovl_u8(t9)); - int16x8_t s9 = vreinterpretq_s16_u16(vmovl_u8(t10)); - int16x8_t s10 = vreinterpretq_s16_u16(vmovl_u8(t11)); - int16x8_t s11 = vreinterpretq_s16_u16(vmovl_u8(t12)); - int16x8_t s12 = vreinterpretq_s16_u16(vmovl_u8(t13)); - int16x8_t s13 = vreinterpretq_s16_u16(vmovl_u8(t14)); - int16x8_t s14 = vreinterpretq_s16_u16(vmovl_u8(t15)); - - uint8x8_t d0 = convolve8_8(s0, s1, s2, s3, s4, s5, s6, s7, filter); - uint8x8_t d1 = convolve8_8(s1, s2, s3, s4, s5, s6, s7, s8, filter); - uint8x8_t d2 = convolve8_8(s2, s3, s4, s5, s6, s7, s8, s9, filter); - uint8x8_t d3 = convolve8_8(s3, s4, s5, s6, s7, s8, s9, s10, filter); - uint8x8_t d4 = convolve8_8(s4, s5, s6, s7, s8, s9, s10, s11, filter); - uint8x8_t d5 = convolve8_8(s5, s6, s7, s8, s9, s10, s11, s12, filter); - uint8x8_t d6 = - convolve8_8(s6, s7, s8, s9, s10, s11, s12, s13, filter); - uint8x8_t d7 = - convolve8_8(s7, s8, s9, s10, s11, s12, s13, s14, filter); - - transpose_u8_8x8(&d0, &d1, &d2, &d3, &d4, &d5, &d6, &d7); - - store_u8_8x8(d, dst_stride, d0, d1, d2, d3, d4, d5, d6, d7); - - s0 = s8; - s1 = s9; - s2 = s10; - s3 = s11; - s4 = s12; - s5 = s13; - s6 = s14; - s += 8; - d += 8; - width -= 8; - } while (width != 0); - src += 8 * src_stride; - dst += 8 * dst_stride; - h -= 8; - } while (h > 0); - } - } -} - -void vpx_convolve8_horiz_neon(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - assert(x_step_q4 == 16); - - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - const int16x8_t x_filter = vld1q_s16(filter[x0_q4]); - - if (vpx_get_filter_taps(filter[x0_q4]) <= 4) { - convolve_4tap_horiz_neon(src - 1, src_stride, dst, dst_stride, w, h, - x_filter); - } else { - convolve_8tap_horiz_neon(src - 3, src_stride, dst, dst_stride, w, h, - x_filter); - } -} - -void vpx_convolve8_avg_horiz_neon(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - const int16x8_t filters = vld1q_s16(filter[x0_q4]); - - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - assert(x_step_q4 == 16); - - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - src -= 3; - - if (h == 4) { - uint8x8_t t0, t1, t2, t3; - load_u8_8x4(src, src_stride, &t0, &t1, &t2, &t3); - - transpose_u8_8x4(&t0, &t1, &t2, &t3); - int16x4_t s0 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t0))); - int16x4_t s1 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t1))); - int16x4_t s2 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t2))); - int16x4_t s3 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t3))); - int16x4_t s4 = vget_high_s16(vreinterpretq_s16_u16(vmovl_u8(t0))); - int16x4_t s5 = vget_high_s16(vreinterpretq_s16_u16(vmovl_u8(t1))); - int16x4_t s6 = vget_high_s16(vreinterpretq_s16_u16(vmovl_u8(t2))); - - src += 7; - - do { - uint8x8_t t7, t8, t9, t10; - load_u8_8x4(src, src_stride, &t7, &t8, &t9, &t10); - - transpose_u8_8x4(&t7, &t8, &t9, &t10); - int16x4_t s7 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t7))); - int16x4_t s8 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t8))); - int16x4_t s9 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t9))); - int16x4_t s10 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t10))); - - int16x4_t d0 = convolve8_4(s0, s1, s2, s3, s4, s5, s6, s7, filters); - int16x4_t d1 = convolve8_4(s1, s2, s3, s4, s5, s6, s7, s8, filters); - int16x4_t d2 = convolve8_4(s2, s3, s4, s5, s6, s7, s8, s9, filters); - int16x4_t d3 = convolve8_4(s3, s4, s5, s6, s7, s8, s9, s10, filters); - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(d0, d1), FILTER_BITS); - uint8x8_t d23 = vqrshrun_n_s16(vcombine_s16(d2, d3), FILTER_BITS); - - transpose_u8_4x4(&d01, &d23); - - uint8x8_t dd01 = load_u8(dst + 0 * dst_stride, 2 * dst_stride); - uint8x8_t dd23 = load_u8(dst + 1 * dst_stride, 2 * dst_stride); - - d01 = vrhadd_u8(d01, dd01); - d23 = vrhadd_u8(d23, dd23); - - store_u8(dst + 0 * dst_stride, 2 * dst_stride, d01); - store_u8(dst + 1 * dst_stride, 2 * dst_stride, d23); - - s0 = s4; - s1 = s5; - s2 = s6; - s3 = s7; - s4 = s8; - s5 = s9; - s6 = s10; - src += 4; - dst += 4; - w -= 4; - } while (w != 0); - } else { - if (w == 4) { - do { - uint8x8_t t0, t1, t2, t3, t4, t5, t6, t7; - load_u8_8x8(src, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7); - - transpose_u8_8x8(&t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7); - int16x8_t s0 = vreinterpretq_s16_u16(vmovl_u8(t0)); - int16x8_t s1 = vreinterpretq_s16_u16(vmovl_u8(t1)); - int16x8_t s2 = vreinterpretq_s16_u16(vmovl_u8(t2)); - int16x8_t s3 = vreinterpretq_s16_u16(vmovl_u8(t3)); - int16x8_t s4 = vreinterpretq_s16_u16(vmovl_u8(t4)); - int16x8_t s5 = vreinterpretq_s16_u16(vmovl_u8(t5)); - int16x8_t s6 = vreinterpretq_s16_u16(vmovl_u8(t6)); - - load_u8_8x8(src + 7, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6, - &t7); - - transpose_u8_4x8(&t0, &t1, &t2, &t3, t4, t5, t6, t7); - int16x8_t s7 = vreinterpretq_s16_u16(vmovl_u8(t0)); - int16x8_t s8 = vreinterpretq_s16_u16(vmovl_u8(t1)); - int16x8_t s9 = vreinterpretq_s16_u16(vmovl_u8(t2)); - int16x8_t s10 = vreinterpretq_s16_u16(vmovl_u8(t3)); - - uint8x8_t d04 = convolve8_8(s0, s1, s2, s3, s4, s5, s6, s7, filters); - uint8x8_t d15 = convolve8_8(s1, s2, s3, s4, s5, s6, s7, s8, filters); - uint8x8_t d26 = convolve8_8(s2, s3, s4, s5, s6, s7, s8, s9, filters); - uint8x8_t d37 = convolve8_8(s3, s4, s5, s6, s7, s8, s9, s10, filters); - - transpose_u8_8x4(&d04, &d15, &d26, &d37); - - uint8x8_t dd04 = load_u8(dst + 0 * dst_stride, 4 * dst_stride); - uint8x8_t dd15 = load_u8(dst + 1 * dst_stride, 4 * dst_stride); - uint8x8_t dd26 = load_u8(dst + 2 * dst_stride, 4 * dst_stride); - uint8x8_t dd37 = load_u8(dst + 3 * dst_stride, 4 * dst_stride); - - d04 = vrhadd_u8(d04, dd04); - d15 = vrhadd_u8(d15, dd15); - d26 = vrhadd_u8(d26, dd26); - d37 = vrhadd_u8(d37, dd37); - - store_u8(dst + 0 * dst_stride, 4 * dst_stride, d04); - store_u8(dst + 1 * dst_stride, 4 * dst_stride, d15); - store_u8(dst + 2 * dst_stride, 4 * dst_stride, d26); - store_u8(dst + 3 * dst_stride, 4 * dst_stride, d37); - - src += 8 * src_stride; - dst += 8 * dst_stride; - h -= 8; - } while (h != 0); - } else { - do { - uint8x8_t t0, t1, t2, t3, t4, t5, t6, t7; - load_u8_8x8(src, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7); - - transpose_u8_8x8(&t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7); - int16x8_t s0 = vreinterpretq_s16_u16(vmovl_u8(t0)); - int16x8_t s1 = vreinterpretq_s16_u16(vmovl_u8(t1)); - int16x8_t s2 = vreinterpretq_s16_u16(vmovl_u8(t2)); - int16x8_t s3 = vreinterpretq_s16_u16(vmovl_u8(t3)); - int16x8_t s4 = vreinterpretq_s16_u16(vmovl_u8(t4)); - int16x8_t s5 = vreinterpretq_s16_u16(vmovl_u8(t5)); - int16x8_t s6 = vreinterpretq_s16_u16(vmovl_u8(t6)); - - const uint8_t *s = src + 7; - uint8_t *d = dst; - int width = w; - - do { - uint8x8_t t8, t9, t10, t11, t12, t13, t14, t15; - load_u8_8x8(s, src_stride, &t8, &t9, &t10, &t11, &t12, &t13, &t14, - &t15); - - transpose_u8_8x8(&t8, &t9, &t10, &t11, &t12, &t13, &t14, &t15); - int16x8_t s7 = vreinterpretq_s16_u16(vmovl_u8(t8)); - int16x8_t s8 = vreinterpretq_s16_u16(vmovl_u8(t9)); - int16x8_t s9 = vreinterpretq_s16_u16(vmovl_u8(t10)); - int16x8_t s10 = vreinterpretq_s16_u16(vmovl_u8(t11)); - int16x8_t s11 = vreinterpretq_s16_u16(vmovl_u8(t12)); - int16x8_t s12 = vreinterpretq_s16_u16(vmovl_u8(t13)); - int16x8_t s13 = vreinterpretq_s16_u16(vmovl_u8(t14)); - int16x8_t s14 = vreinterpretq_s16_u16(vmovl_u8(t15)); - - uint8x8_t d0 = convolve8_8(s0, s1, s2, s3, s4, s5, s6, s7, filters); - uint8x8_t d1 = convolve8_8(s1, s2, s3, s4, s5, s6, s7, s8, filters); - uint8x8_t d2 = convolve8_8(s2, s3, s4, s5, s6, s7, s8, s9, filters); - uint8x8_t d3 = convolve8_8(s3, s4, s5, s6, s7, s8, s9, s10, filters); - uint8x8_t d4 = convolve8_8(s4, s5, s6, s7, s8, s9, s10, s11, filters); - uint8x8_t d5 = - convolve8_8(s5, s6, s7, s8, s9, s10, s11, s12, filters); - uint8x8_t d6 = - convolve8_8(s6, s7, s8, s9, s10, s11, s12, s13, filters); - uint8x8_t d7 = - convolve8_8(s7, s8, s9, s10, s11, s12, s13, s14, filters); - - transpose_u8_8x8(&d0, &d1, &d2, &d3, &d4, &d5, &d6, &d7); - - d0 = vrhadd_u8(d0, vld1_u8(d + 0 * dst_stride)); - d1 = vrhadd_u8(d1, vld1_u8(d + 1 * dst_stride)); - d2 = vrhadd_u8(d2, vld1_u8(d + 2 * dst_stride)); - d3 = vrhadd_u8(d3, vld1_u8(d + 3 * dst_stride)); - d4 = vrhadd_u8(d4, vld1_u8(d + 4 * dst_stride)); - d5 = vrhadd_u8(d5, vld1_u8(d + 5 * dst_stride)); - d6 = vrhadd_u8(d6, vld1_u8(d + 6 * dst_stride)); - d7 = vrhadd_u8(d7, vld1_u8(d + 7 * dst_stride)); - - store_u8_8x8(d, dst_stride, d0, d1, d2, d3, d4, d5, d6, d7); - - s0 = s8; - s1 = s9; - s2 = s10; - s3 = s11; - s4 = s12; - s5 = s13; - s6 = s14; - s += 8; - d += 8; - width -= 8; - } while (width != 0); - src += 8 * src_stride; - dst += 8 * dst_stride; - h -= 8; - } while (h != 0); - } - } -} - -static INLINE void convolve_8tap_vert_neon(const uint8_t *src, - ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, int w, int h, - const int16x8_t filter) { - if (w == 4) { - uint8x8_t t0, t1, t2, t3, t4, t5, t6; - load_u8_8x7(src, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6); - int16x4_t s0 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t0))); - int16x4_t s1 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t1))); - int16x4_t s2 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t2))); - int16x4_t s3 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t3))); - int16x4_t s4 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t4))); - int16x4_t s5 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t5))); - int16x4_t s6 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t6))); - - src += 7 * src_stride; - - do { - uint8x8_t t7, t8, t9, t10; - load_u8_8x4(src, src_stride, &t7, &t8, &t9, &t10); - int16x4_t s7 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t7))); - int16x4_t s8 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t8))); - int16x4_t s9 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t9))); - int16x4_t s10 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t10))); - - int16x4_t d0 = convolve8_4(s0, s1, s2, s3, s4, s5, s6, s7, filter); - int16x4_t d1 = convolve8_4(s1, s2, s3, s4, s5, s6, s7, s8, filter); - int16x4_t d2 = convolve8_4(s2, s3, s4, s5, s6, s7, s8, s9, filter); - int16x4_t d3 = convolve8_4(s3, s4, s5, s6, s7, s8, s9, s10, filter); - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(d0, d1), FILTER_BITS); - uint8x8_t d23 = vqrshrun_n_s16(vcombine_s16(d2, d3), FILTER_BITS); - - store_u8(dst + 0 * dst_stride, dst_stride, d01); - store_u8(dst + 2 * dst_stride, dst_stride, d23); - - s0 = s4; - s1 = s5; - s2 = s6; - s3 = s7; - s4 = s8; - s5 = s9; - s6 = s10; - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - do { - uint8x8_t t0, t1, t2, t3, t4, t5, t6; - load_u8_8x7(src, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6); - int16x8_t s0 = vreinterpretq_s16_u16(vmovl_u8(t0)); - int16x8_t s1 = vreinterpretq_s16_u16(vmovl_u8(t1)); - int16x8_t s2 = vreinterpretq_s16_u16(vmovl_u8(t2)); - int16x8_t s3 = vreinterpretq_s16_u16(vmovl_u8(t3)); - int16x8_t s4 = vreinterpretq_s16_u16(vmovl_u8(t4)); - int16x8_t s5 = vreinterpretq_s16_u16(vmovl_u8(t5)); - int16x8_t s6 = vreinterpretq_s16_u16(vmovl_u8(t6)); - - const uint8_t *s = src + 7 * src_stride; - uint8_t *d = dst; - int height = h; - - do { - uint8x8_t t7, t8, t9, t10; - load_u8_8x4(s, src_stride, &t7, &t8, &t9, &t10); - int16x8_t s7 = vreinterpretq_s16_u16(vmovl_u8(t7)); - int16x8_t s8 = vreinterpretq_s16_u16(vmovl_u8(t8)); - int16x8_t s9 = vreinterpretq_s16_u16(vmovl_u8(t9)); - int16x8_t s10 = vreinterpretq_s16_u16(vmovl_u8(t10)); - - uint8x8_t d0 = convolve8_8(s0, s1, s2, s3, s4, s5, s6, s7, filter); - uint8x8_t d1 = convolve8_8(s1, s2, s3, s4, s5, s6, s7, s8, filter); - uint8x8_t d2 = convolve8_8(s2, s3, s4, s5, s6, s7, s8, s9, filter); - uint8x8_t d3 = convolve8_8(s3, s4, s5, s6, s7, s8, s9, s10, filter); - - store_u8_8x4(d, dst_stride, d0, d1, d2, d3); - - s0 = s4; - s1 = s5; - s2 = s6; - s3 = s7; - s4 = s8; - s5 = s9; - s6 = s10; - s += 4 * src_stride; - d += 4 * dst_stride; - height -= 4; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); - } -} - -void vpx_convolve8_vert_neon(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - assert(y_step_q4 == 16); - - (void)x0_q4; - (void)x_step_q4; - (void)y_step_q4; - - const int16x8_t y_filter = vld1q_s16(filter[y0_q4]); - - if (vpx_get_filter_taps(filter[y0_q4]) <= 4) { - convolve_4tap_vert_neon(src - src_stride, src_stride, dst, dst_stride, w, h, - y_filter); - } else { - convolve_8tap_vert_neon(src - 3 * src_stride, src_stride, dst, dst_stride, - w, h, y_filter); - } -} - -void vpx_convolve8_avg_vert_neon(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - const int16x8_t filters = vld1q_s16(filter[y0_q4]); - - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - assert(y_step_q4 == 16); - - (void)x0_q4; - (void)x_step_q4; - (void)y_step_q4; - - src -= 3 * src_stride; - - if (w == 4) { - uint8x8_t t0, t1, t2, t3, t4, t5, t6; - load_u8_8x7(src, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6); - int16x4_t s0 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t0))); - int16x4_t s1 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t1))); - int16x4_t s2 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t2))); - int16x4_t s3 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t3))); - int16x4_t s4 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t4))); - int16x4_t s5 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t5))); - int16x4_t s6 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t6))); - - src += 7 * src_stride; - - do { - uint8x8_t t7, t8, t9, t10; - load_u8_8x4(src, src_stride, &t7, &t8, &t9, &t10); - int16x4_t s7 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t7))); - int16x4_t s8 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t8))); - int16x4_t s9 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t9))); - int16x4_t s10 = vreinterpret_s16_u16(vget_low_u16(vmovl_u8(t10))); - - int16x4_t d0 = convolve8_4(s0, s1, s2, s3, s4, s5, s6, s7, filters); - int16x4_t d1 = convolve8_4(s1, s2, s3, s4, s5, s6, s7, s8, filters); - int16x4_t d2 = convolve8_4(s2, s3, s4, s5, s6, s7, s8, s9, filters); - int16x4_t d3 = convolve8_4(s3, s4, s5, s6, s7, s8, s9, s10, filters); - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(d0, d1), FILTER_BITS); - uint8x8_t d23 = vqrshrun_n_s16(vcombine_s16(d2, d3), FILTER_BITS); - - uint8x8_t dd01 = load_u8(dst + 0 * dst_stride, dst_stride); - uint8x8_t dd23 = load_u8(dst + 2 * dst_stride, dst_stride); - - d01 = vrhadd_u8(d01, dd01); - d23 = vrhadd_u8(d23, dd23); - - store_u8(dst + 0 * dst_stride, dst_stride, d01); - store_u8(dst + 2 * dst_stride, dst_stride, d23); - - s0 = s4; - s1 = s5; - s2 = s6; - s3 = s7; - s4 = s8; - s5 = s9; - s6 = s10; - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - do { - uint8x8_t t0, t1, t2, t3, t4, t5, t6; - load_u8_8x7(src, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6); - int16x8_t s0 = vreinterpretq_s16_u16(vmovl_u8(t0)); - int16x8_t s1 = vreinterpretq_s16_u16(vmovl_u8(t1)); - int16x8_t s2 = vreinterpretq_s16_u16(vmovl_u8(t2)); - int16x8_t s3 = vreinterpretq_s16_u16(vmovl_u8(t3)); - int16x8_t s4 = vreinterpretq_s16_u16(vmovl_u8(t4)); - int16x8_t s5 = vreinterpretq_s16_u16(vmovl_u8(t5)); - int16x8_t s6 = vreinterpretq_s16_u16(vmovl_u8(t6)); - - const uint8_t *s = src + 7 * src_stride; - uint8_t *d = dst; - int height = h; - - do { - uint8x8_t t7, t8, t9, t10; - load_u8_8x4(s, src_stride, &t7, &t8, &t9, &t10); - int16x8_t s7 = vreinterpretq_s16_u16(vmovl_u8(t7)); - int16x8_t s8 = vreinterpretq_s16_u16(vmovl_u8(t8)); - int16x8_t s9 = vreinterpretq_s16_u16(vmovl_u8(t9)); - int16x8_t s10 = vreinterpretq_s16_u16(vmovl_u8(t10)); - - uint8x8_t d0 = convolve8_8(s0, s1, s2, s3, s4, s5, s6, s7, filters); - uint8x8_t d1 = convolve8_8(s1, s2, s3, s4, s5, s6, s7, s8, filters); - uint8x8_t d2 = convolve8_8(s2, s3, s4, s5, s6, s7, s8, s9, filters); - uint8x8_t d3 = convolve8_8(s3, s4, s5, s6, s7, s8, s9, s10, filters); - - d0 = vrhadd_u8(d0, vld1_u8(d + 0 * dst_stride)); - d1 = vrhadd_u8(d1, vld1_u8(d + 1 * dst_stride)); - d2 = vrhadd_u8(d2, vld1_u8(d + 2 * dst_stride)); - d3 = vrhadd_u8(d3, vld1_u8(d + 3 * dst_stride)); - - store_u8_8x4(d, dst_stride, d0, d1, d2, d3); - - s0 = s4; - s1 = s5; - s2 = s6; - s3 = s7; - s4 = s8; - s5 = s9; - s6 = s10; - height -= 4; - s += 4 * src_stride; - d += 4 * dst_stride; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon.h deleted file mode 100644 index 10cc761c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_ARM_VPX_CONVOLVE8_NEON_H_ -#define VPX_VPX_DSP_ARM_VPX_CONVOLVE8_NEON_H_ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/vpx_filter.h" - -static INLINE int16x4_t convolve8_4(const int16x4_t s0, const int16x4_t s1, - const int16x4_t s2, const int16x4_t s3, - const int16x4_t s4, const int16x4_t s5, - const int16x4_t s6, const int16x4_t s7, - const int16x8_t filters) { - const int16x4_t filters_lo = vget_low_s16(filters); - const int16x4_t filters_hi = vget_high_s16(filters); - int16x4_t sum; - - sum = vmul_lane_s16(s0, filters_lo, 0); - sum = vmla_lane_s16(sum, s1, filters_lo, 1); - sum = vmla_lane_s16(sum, s2, filters_lo, 2); - sum = vmla_lane_s16(sum, s5, filters_hi, 1); - sum = vmla_lane_s16(sum, s6, filters_hi, 2); - sum = vmla_lane_s16(sum, s7, filters_hi, 3); - sum = vqadd_s16(sum, vmul_lane_s16(s3, filters_lo, 3)); - sum = vqadd_s16(sum, vmul_lane_s16(s4, filters_hi, 0)); - return sum; -} - -static INLINE uint8x8_t convolve8_8(const int16x8_t s0, const int16x8_t s1, - const int16x8_t s2, const int16x8_t s3, - const int16x8_t s4, const int16x8_t s5, - const int16x8_t s6, const int16x8_t s7, - const int16x8_t filters) { - const int16x4_t filters_lo = vget_low_s16(filters); - const int16x4_t filters_hi = vget_high_s16(filters); - int16x8_t sum; - - sum = vmulq_lane_s16(s0, filters_lo, 0); - sum = vmlaq_lane_s16(sum, s1, filters_lo, 1); - sum = vmlaq_lane_s16(sum, s2, filters_lo, 2); - sum = vmlaq_lane_s16(sum, s5, filters_hi, 1); - sum = vmlaq_lane_s16(sum, s6, filters_hi, 2); - sum = vmlaq_lane_s16(sum, s7, filters_hi, 3); - sum = vqaddq_s16(sum, vmulq_lane_s16(s3, filters_lo, 3)); - sum = vqaddq_s16(sum, vmulq_lane_s16(s4, filters_hi, 0)); - return vqrshrun_n_s16(sum, FILTER_BITS); -} - -static INLINE uint8x8_t scale_filter_8(const uint8x8_t *const s, - const int16x8_t filters) { - int16x8_t ss[8]; - - ss[0] = vreinterpretq_s16_u16(vmovl_u8(s[0])); - ss[1] = vreinterpretq_s16_u16(vmovl_u8(s[1])); - ss[2] = vreinterpretq_s16_u16(vmovl_u8(s[2])); - ss[3] = vreinterpretq_s16_u16(vmovl_u8(s[3])); - ss[4] = vreinterpretq_s16_u16(vmovl_u8(s[4])); - ss[5] = vreinterpretq_s16_u16(vmovl_u8(s[5])); - ss[6] = vreinterpretq_s16_u16(vmovl_u8(s[6])); - ss[7] = vreinterpretq_s16_u16(vmovl_u8(s[7])); - - return convolve8_8(ss[0], ss[1], ss[2], ss[3], ss[4], ss[5], ss[6], ss[7], - filters); -} - -// 2-tap (bilinear) filter values are always positive, but 4-tap filter values -// are negative on the outer edges (taps 0 and 3), with taps 1 and 2 having much -// greater positive values to compensate. To use instructions that operate on -// 8-bit types we also need the types to be unsigned. Subtracting the products -// of taps 0 and 3 from the products of taps 1 and 2 always works given that -// 2-tap filters are 0-padded. -static INLINE uint8x8_t convolve4_8(const uint8x8_t s0, const uint8x8_t s1, - const uint8x8_t s2, const uint8x8_t s3, - const uint8x8_t filter_taps[4]) { - uint16x8_t sum = vmull_u8(s1, filter_taps[1]); - sum = vmlal_u8(sum, s2, filter_taps[2]); - sum = vmlsl_u8(sum, s0, filter_taps[0]); - sum = vmlsl_u8(sum, s3, filter_taps[3]); - // We halved the filter values so -1 from right shift. - return vqrshrun_n_s16(vreinterpretq_s16_u16(sum), FILTER_BITS - 1); -} - -static INLINE void convolve_4tap_vert_neon(const uint8_t *src, - ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, int w, int h, - const int16x8_t filter) { - // 4-tap and bilinear filter values are even, so halve them to reduce - // intermediate precision requirements. - const uint8x8_t y_filter = - vshrn_n_u16(vreinterpretq_u16_s16(vabsq_s16(filter)), 1); - - // Neon does not have lane-referencing multiply or multiply-accumulate - // instructions that operate on vectors of 8-bit elements. This means we have - // to duplicate filter taps into a whole vector and use standard multiply / - // multiply-accumulate instructions. - const uint8x8_t filter_taps[4] = { vdup_lane_u8(y_filter, 2), - vdup_lane_u8(y_filter, 3), - vdup_lane_u8(y_filter, 4), - vdup_lane_u8(y_filter, 5) }; - - if (w == 4) { - uint8x8_t s01 = load_unaligned_u8(src + 0 * src_stride, src_stride); - uint8x8_t s12 = load_unaligned_u8(src + 1 * src_stride, src_stride); - - src += 2 * src_stride; - - do { - uint8x8_t s23 = load_unaligned_u8(src + 0 * src_stride, src_stride); - uint8x8_t s34 = load_unaligned_u8(src + 1 * src_stride, src_stride); - uint8x8_t s45 = load_unaligned_u8(src + 2 * src_stride, src_stride); - uint8x8_t s56 = load_unaligned_u8(src + 3 * src_stride, src_stride); - - uint8x8_t d01 = convolve4_8(s01, s12, s23, s34, filter_taps); - uint8x8_t d23 = convolve4_8(s23, s34, s45, s56, filter_taps); - - store_unaligned_u8(dst + 0 * dst_stride, dst_stride, d01); - store_unaligned_u8(dst + 2 * dst_stride, dst_stride, d23); - - s01 = s45; - s12 = s56; - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - do { - const uint8_t *s = src; - uint8_t *d = dst; - int height = h; - - uint8x8_t s0, s1, s2; - load_u8_8x3(s, src_stride, &s0, &s1, &s2); - - s += 3 * src_stride; - - do { - uint8x8_t s3, s4, s5, s6; - load_u8_8x4(s, src_stride, &s3, &s4, &s5, &s6); - - uint8x8_t d0 = convolve4_8(s0, s1, s2, s3, filter_taps); - uint8x8_t d1 = convolve4_8(s1, s2, s3, s4, filter_taps); - uint8x8_t d2 = convolve4_8(s2, s3, s4, s5, filter_taps); - uint8x8_t d3 = convolve4_8(s3, s4, s5, s6, filter_taps); - - store_u8_8x4(d, dst_stride, d0, d1, d2, d3); - - s0 = s4; - s1 = s5; - s2 = s6; - s += 4 * src_stride; - d += 4 * dst_stride; - height -= 4; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); - } -} - -#endif // VPX_VPX_DSP_ARM_VPX_CONVOLVE8_NEON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon_asm.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon_asm.c deleted file mode 100644 index c4177c53..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon_asm.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vp9/common/vp9_filter.h" -#include "vpx_dsp/arm/vpx_convolve8_neon_asm.h" - -/* Type1 and Type2 functions are called depending on the position of the - * negative and positive coefficients in the filter. In type1, the filter kernel - * used is sub_pel_filters_8lp, in which only the first two and the last two - * coefficients are negative. In type2, the negative coefficients are 0, 2, 5 & - * 7. - */ - -#define DEFINE_FILTER(dir) \ - void vpx_convolve8_##dir##_neon( \ - const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, \ - ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, \ - int x_step_q4, int y0_q4, int y_step_q4, int w, int h) { \ - if (filter == vp9_filter_kernels[1]) { \ - vpx_convolve8_##dir##_filter_type1_neon( \ - src, src_stride, dst, dst_stride, filter, x0_q4, x_step_q4, y0_q4, \ - y_step_q4, w, h); \ - } else { \ - vpx_convolve8_##dir##_filter_type2_neon( \ - src, src_stride, dst, dst_stride, filter, x0_q4, x_step_q4, y0_q4, \ - y_step_q4, w, h); \ - } \ - } - -DEFINE_FILTER(horiz) -DEFINE_FILTER(avg_horiz) -DEFINE_FILTER(vert) -DEFINE_FILTER(avg_vert) diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon_asm.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon_asm.h deleted file mode 100644 index f1c7d62e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon_asm.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_ARM_VPX_CONVOLVE8_NEON_ASM_H_ -#define VPX_VPX_DSP_ARM_VPX_CONVOLVE8_NEON_ASM_H_ - -#define DECLARE_FILTER(dir, type) \ - void vpx_convolve8_##dir##_filter_##type##_neon( \ - const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, \ - ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, \ - int x_step_q4, int y0_q4, int y_step_q4, int w, int h); - -DECLARE_FILTER(horiz, type1) -DECLARE_FILTER(avg_horiz, type1) -DECLARE_FILTER(horiz, type2) -DECLARE_FILTER(avg_horiz, type2) -DECLARE_FILTER(vert, type1) -DECLARE_FILTER(avg_vert, type1) -DECLARE_FILTER(vert, type2) -DECLARE_FILTER(avg_vert, type2) - -#endif // VPX_VPX_DSP_ARM_VPX_CONVOLVE8_NEON_ASM_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon_dotprod.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon_dotprod.c deleted file mode 100644 index b05a49d3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon_dotprod.c +++ /dev/null @@ -1,1075 +0,0 @@ -/* - * Copyright (c) 2021 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/arm/vpx_convolve8_neon.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_ports/mem.h" - -// Filter values always sum to 128. -#define FILTER_SUM 128 - -DECLARE_ALIGNED(16, static const uint8_t, dot_prod_permute_tbl[48]) = { - 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6, - 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10, - 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14 -}; - -DECLARE_ALIGNED(16, static const uint8_t, dot_prod_merge_block_tbl[48]) = { - // Shift left and insert new last column in transposed 4x4 block. - 1, 2, 3, 16, 5, 6, 7, 20, 9, 10, 11, 24, 13, 14, 15, 28, - // Shift left and insert two new columns in transposed 4x4 block. - 2, 3, 16, 17, 6, 7, 20, 21, 10, 11, 24, 25, 14, 15, 28, 29, - // Shift left and insert three new columns in transposed 4x4 block. - 3, 16, 17, 18, 7, 20, 21, 22, 11, 24, 25, 26, 15, 28, 29, 30 -}; - -static INLINE int16x4_t convolve4_4_h(const uint8x16_t samples, - const int8x8_t filters, - const uint8x16_t permute_tbl) { - // Transform sample range to [-128, 127] for 8-bit signed dot product. - int8x16_t samples_128 = - vreinterpretq_s8_u8(vsubq_u8(samples, vdupq_n_u8(128))); - - // Permute samples ready for dot product. - // { 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 } - int8x16_t perm_samples = vqtbl1q_s8(samples_128, permute_tbl); - - // Accumulate into 128 * FILTER_SUM to account for range transform. (Divide - // by 2 since we halved the filter values.) - int32x4_t acc = vdupq_n_s32(128 * FILTER_SUM / 2); - int32x4_t sum = vdotq_lane_s32(acc, perm_samples, filters, 0); - - // Further narrowing and packing is performed by the caller. - return vmovn_s32(sum); -} - -static INLINE uint8x8_t convolve4_8_h(const uint8x16_t samples, - const int8x8_t filters, - const uint8x16x2_t permute_tbl) { - // Transform sample range to [-128, 127] for 8-bit signed dot product. - int8x16_t samples_128 = - vreinterpretq_s8_u8(vsubq_u8(samples, vdupq_n_u8(128))); - - // Permute samples ready for dot product. - // { 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 } - // { 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10 } - int8x16_t perm_samples[2] = { vqtbl1q_s8(samples_128, permute_tbl.val[0]), - vqtbl1q_s8(samples_128, permute_tbl.val[1]) }; - - // Accumulate into 128 * FILTER_SUM to account for range transform. (Divide - // by 2 since we halved the filter values.) - int32x4_t acc = vdupq_n_s32(128 * FILTER_SUM / 2); - // First 4 output values. - int32x4_t sum0 = vdotq_lane_s32(acc, perm_samples[0], filters, 0); - // Second 4 output values. - int32x4_t sum1 = vdotq_lane_s32(acc, perm_samples[1], filters, 0); - - // Narrow and re-pack. - int16x8_t sum = vcombine_s16(vmovn_s32(sum0), vmovn_s32(sum1)); - // We halved the filter values so -1 from right shift. - return vqrshrun_n_s16(sum, FILTER_BITS - 1); -} - -static INLINE int16x4_t convolve8_4_h(const uint8x16_t samples, - const int8x8_t filters, - const uint8x16x2_t permute_tbl) { - // Transform sample range to [-128, 127] for 8-bit signed dot product. - int8x16_t samples_128 = - vreinterpretq_s8_u8(vsubq_u8(samples, vdupq_n_u8(128))); - - // Permute samples ready for dot product. - // { 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 } - // { 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10 } - int8x16_t perm_samples[2] = { vqtbl1q_s8(samples_128, permute_tbl.val[0]), - vqtbl1q_s8(samples_128, permute_tbl.val[1]) }; - - // Accumulate into 128 * FILTER_SUM to account for range transform. - int32x4_t acc = vdupq_n_s32(128 * FILTER_SUM); - int32x4_t sum = vdotq_lane_s32(acc, perm_samples[0], filters, 0); - sum = vdotq_lane_s32(sum, perm_samples[1], filters, 1); - - // Further narrowing and packing is performed by the caller. - return vshrn_n_s32(sum, 1); -} - -static INLINE uint8x8_t convolve8_8_h(const uint8x16_t samples, - const int8x8_t filters, - const uint8x16x3_t permute_tbl) { - // Transform sample range to [-128, 127] for 8-bit signed dot product. - int8x16_t samples_128 = - vreinterpretq_s8_u8(vsubq_u8(samples, vdupq_n_u8(128))); - - // Permute samples ready for dot product. - // { 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 } - // { 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10 } - // { 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14 } - int8x16_t perm_samples[3] = { vqtbl1q_s8(samples_128, permute_tbl.val[0]), - vqtbl1q_s8(samples_128, permute_tbl.val[1]), - vqtbl1q_s8(samples_128, permute_tbl.val[2]) }; - - // Accumulate into 128 * FILTER_SUM to account for range transform. - int32x4_t acc = vdupq_n_s32(128 * FILTER_SUM); - // First 4 output values. - int32x4_t sum0 = vdotq_lane_s32(acc, perm_samples[0], filters, 0); - sum0 = vdotq_lane_s32(sum0, perm_samples[1], filters, 1); - // Second 4 output values. - int32x4_t sum1 = vdotq_lane_s32(acc, perm_samples[1], filters, 0); - sum1 = vdotq_lane_s32(sum1, perm_samples[2], filters, 1); - - // Narrow and re-pack. - int16x8_t sum = vcombine_s16(vshrn_n_s32(sum0, 1), vshrn_n_s32(sum1, 1)); - return vqrshrun_n_s16(sum, FILTER_BITS - 1); -} - -static INLINE void convolve_4tap_horiz_neon_dotprod( - const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, int w, int h, const int8x8_t filter) { - if (w == 4) { - const uint8x16_t permute_tbl = vld1q_u8(dot_prod_permute_tbl); - - do { - uint8x16_t s0, s1, s2, s3; - load_u8_16x4(src, src_stride, &s0, &s1, &s2, &s3); - - int16x4_t t0 = convolve4_4_h(s0, filter, permute_tbl); - int16x4_t t1 = convolve4_4_h(s1, filter, permute_tbl); - int16x4_t t2 = convolve4_4_h(s2, filter, permute_tbl); - int16x4_t t3 = convolve4_4_h(s3, filter, permute_tbl); - // We halved the filter values so -1 from right shift. - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(t0, t1), FILTER_BITS - 1); - uint8x8_t d23 = vqrshrun_n_s16(vcombine_s16(t2, t3), FILTER_BITS - 1); - - store_u8(dst + 0 * dst_stride, dst_stride, d01); - store_u8(dst + 2 * dst_stride, dst_stride, d23); - - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint8x16x2_t permute_tbl = vld1q_u8_x2(dot_prod_permute_tbl); - - do { - const uint8_t *s = src; - uint8_t *d = dst; - int width = w; - - do { - uint8x16_t s0, s1, s2, s3; - load_u8_16x4(s, src_stride, &s0, &s1, &s2, &s3); - - uint8x8_t d0 = convolve4_8_h(s0, filter, permute_tbl); - uint8x8_t d1 = convolve4_8_h(s1, filter, permute_tbl); - uint8x8_t d2 = convolve4_8_h(s2, filter, permute_tbl); - uint8x8_t d3 = convolve4_8_h(s3, filter, permute_tbl); - - store_u8_8x4(d, dst_stride, d0, d1, d2, d3); - - s += 8; - d += 8; - width -= 8; - } while (width != 0); - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } -} - -static INLINE void convolve_8tap_horiz_neon_dotprod( - const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, int w, int h, const int8x8_t filter) { - if (w == 4) { - const uint8x16x2_t permute_tbl = vld1q_u8_x2(dot_prod_permute_tbl); - - do { - uint8x16_t s0, s1, s2, s3; - load_u8_16x4(src, src_stride, &s0, &s1, &s2, &s3); - - int16x4_t t0 = convolve8_4_h(s0, filter, permute_tbl); - int16x4_t t1 = convolve8_4_h(s1, filter, permute_tbl); - int16x4_t t2 = convolve8_4_h(s2, filter, permute_tbl); - int16x4_t t3 = convolve8_4_h(s3, filter, permute_tbl); - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(t0, t1), FILTER_BITS - 1); - uint8x8_t d23 = vqrshrun_n_s16(vcombine_s16(t2, t3), FILTER_BITS - 1); - - store_u8(dst + 0 * dst_stride, dst_stride, d01); - store_u8(dst + 2 * dst_stride, dst_stride, d23); - - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint8x16x3_t permute_tbl = vld1q_u8_x3(dot_prod_permute_tbl); - - do { - const uint8_t *s = src; - uint8_t *d = dst; - int width = w; - - do { - uint8x16_t s0, s1, s2, s3; - load_u8_16x4(s, src_stride, &s0, &s1, &s2, &s3); - - uint8x8_t d0 = convolve8_8_h(s0, filter, permute_tbl); - uint8x8_t d1 = convolve8_8_h(s1, filter, permute_tbl); - uint8x8_t d2 = convolve8_8_h(s2, filter, permute_tbl); - uint8x8_t d3 = convolve8_8_h(s3, filter, permute_tbl); - - store_u8_8x4(d, dst_stride, d0, d1, d2, d3); - - s += 8; - d += 8; - width -= 8; - } while (width != 0); - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } -} - -void vpx_convolve8_horiz_neon_dotprod(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - assert(x_step_q4 == 16); - - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - if (vpx_get_filter_taps(filter[x0_q4]) <= 4) { - // Load 4-tap filter into first 4 elements of the vector. - // All 4-tap and bilinear filter values are even, so halve them to reduce - // intermediate precision requirements. - const int16x4_t x_filter = vld1_s16(filter[x0_q4] + 2); - const int8x8_t x_filter_4tap = - vshrn_n_s16(vcombine_s16(x_filter, vdup_n_s16(0)), 1); - - convolve_4tap_horiz_neon_dotprod(src - 1, src_stride, dst, dst_stride, w, h, - x_filter_4tap); - - } else { - const int8x8_t x_filter_8tap = vmovn_s16(vld1q_s16(filter[x0_q4])); - - convolve_8tap_horiz_neon_dotprod(src - 3, src_stride, dst, dst_stride, w, h, - x_filter_8tap); - } -} - -void vpx_convolve8_avg_horiz_neon_dotprod(const uint8_t *src, - ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, - int y_step_q4, int w, int h) { - const int8x8_t filters = vmovn_s16(vld1q_s16(filter[x0_q4])); - - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - assert(x_step_q4 == 16); - - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - src -= 3; - - if (w == 4) { - const uint8x16x2_t permute_tbl = vld1q_u8_x2(dot_prod_permute_tbl); - - do { - uint8x16_t s0, s1, s2, s3; - load_u8_16x4(src, src_stride, &s0, &s1, &s2, &s3); - - int16x4_t t0 = convolve8_4_h(s0, filters, permute_tbl); - int16x4_t t1 = convolve8_4_h(s1, filters, permute_tbl); - int16x4_t t2 = convolve8_4_h(s2, filters, permute_tbl); - int16x4_t t3 = convolve8_4_h(s3, filters, permute_tbl); - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(t0, t1), FILTER_BITS - 1); - uint8x8_t d23 = vqrshrun_n_s16(vcombine_s16(t2, t3), FILTER_BITS - 1); - - uint8x8_t dd01 = load_u8(dst + 0 * dst_stride, dst_stride); - uint8x8_t dd23 = load_u8(dst + 2 * dst_stride, dst_stride); - - d01 = vrhadd_u8(d01, dd01); - d23 = vrhadd_u8(d23, dd23); - - store_u8(dst + 0 * dst_stride, dst_stride, d01); - store_u8(dst + 2 * dst_stride, dst_stride, d23); - - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint8x16x3_t permute_tbl = vld1q_u8_x3(dot_prod_permute_tbl); - - do { - const uint8_t *s = src; - uint8_t *d = dst; - int width = w; - - do { - uint8x16_t s0, s1, s2, s3; - load_u8_16x4(s, src_stride, &s0, &s1, &s2, &s3); - - uint8x8_t d0 = convolve8_8_h(s0, filters, permute_tbl); - uint8x8_t d1 = convolve8_8_h(s1, filters, permute_tbl); - uint8x8_t d2 = convolve8_8_h(s2, filters, permute_tbl); - uint8x8_t d3 = convolve8_8_h(s3, filters, permute_tbl); - - uint8x8_t dd0, dd1, dd2, dd3; - load_u8_8x4(d, dst_stride, &dd0, &dd1, &dd2, &dd3); - - d0 = vrhadd_u8(d0, dd0); - d1 = vrhadd_u8(d1, dd1); - d2 = vrhadd_u8(d2, dd2); - d3 = vrhadd_u8(d3, dd3); - - store_u8_8x4(d, dst_stride, d0, d1, d2, d3); - - s += 8; - d += 8; - width -= 8; - } while (width != 0); - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } -} - -static INLINE void transpose_concat_4x4(int8x8_t a0, int8x8_t a1, int8x8_t a2, - int8x8_t a3, int8x16_t *b) { - // Transpose 8-bit elements and concatenate result rows as follows: - // a0: 00, 01, 02, 03, XX, XX, XX, XX - // a1: 10, 11, 12, 13, XX, XX, XX, XX - // a2: 20, 21, 22, 23, XX, XX, XX, XX - // a3: 30, 31, 32, 33, XX, XX, XX, XX - // - // b: 00, 10, 20, 30, 01, 11, 21, 31, 02, 12, 22, 32, 03, 13, 23, 33 - - int8x16_t a0q = vcombine_s8(a0, vdup_n_s8(0)); - int8x16_t a1q = vcombine_s8(a1, vdup_n_s8(0)); - int8x16_t a2q = vcombine_s8(a2, vdup_n_s8(0)); - int8x16_t a3q = vcombine_s8(a3, vdup_n_s8(0)); - - int8x16_t a01 = vzipq_s8(a0q, a1q).val[0]; - int8x16_t a23 = vzipq_s8(a2q, a3q).val[0]; - - int16x8_t a0123 = - vzipq_s16(vreinterpretq_s16_s8(a01), vreinterpretq_s16_s8(a23)).val[0]; - - *b = vreinterpretq_s8_s16(a0123); -} - -static INLINE void transpose_concat_8x4(int8x8_t a0, int8x8_t a1, int8x8_t a2, - int8x8_t a3, int8x16_t *b0, - int8x16_t *b1) { - // Transpose 8-bit elements and concatenate result rows as follows: - // a0: 00, 01, 02, 03, 04, 05, 06, 07 - // a1: 10, 11, 12, 13, 14, 15, 16, 17 - // a2: 20, 21, 22, 23, 24, 25, 26, 27 - // a3: 30, 31, 32, 33, 34, 35, 36, 37 - // - // b0: 00, 10, 20, 30, 01, 11, 21, 31, 02, 12, 22, 32, 03, 13, 23, 33 - // b1: 04, 14, 24, 34, 05, 15, 25, 35, 06, 16, 26, 36, 07, 17, 27, 37 - - int8x16_t a0q = vcombine_s8(a0, vdup_n_s8(0)); - int8x16_t a1q = vcombine_s8(a1, vdup_n_s8(0)); - int8x16_t a2q = vcombine_s8(a2, vdup_n_s8(0)); - int8x16_t a3q = vcombine_s8(a3, vdup_n_s8(0)); - - int8x16_t a01 = vzipq_s8(a0q, a1q).val[0]; - int8x16_t a23 = vzipq_s8(a2q, a3q).val[0]; - - int16x8x2_t a0123 = - vzipq_s16(vreinterpretq_s16_s8(a01), vreinterpretq_s16_s8(a23)); - - *b0 = vreinterpretq_s8_s16(a0123.val[0]); - *b1 = vreinterpretq_s8_s16(a0123.val[1]); -} - -static INLINE int16x4_t convolve8_4_v(const int8x16_t samples_lo, - const int8x16_t samples_hi, - const int8x8_t filters) { - // The sample range transform and permutation are performed by the caller. - - // Accumulate into 128 * FILTER_SUM to account for range transform. - int32x4_t acc = vdupq_n_s32(128 * FILTER_SUM); - int32x4_t sum = vdotq_lane_s32(acc, samples_lo, filters, 0); - sum = vdotq_lane_s32(sum, samples_hi, filters, 1); - - // Further narrowing and packing is performed by the caller. - return vshrn_n_s32(sum, 1); -} - -static INLINE uint8x8_t convolve8_8_v(const int8x16_t samples0_lo, - const int8x16_t samples0_hi, - const int8x16_t samples1_lo, - const int8x16_t samples1_hi, - const int8x8_t filters) { - // The sample range transform and permutation are performed by the caller. - - // Accumulate into 128 * FILTER_SUM to account for range transform. - int32x4_t acc = vdupq_n_s32(128 * FILTER_SUM); - // First 4 output values. - int32x4_t sum0 = vdotq_lane_s32(acc, samples0_lo, filters, 0); - sum0 = vdotq_lane_s32(sum0, samples0_hi, filters, 1); - // Second 4 output values. - int32x4_t sum1 = vdotq_lane_s32(acc, samples1_lo, filters, 0); - sum1 = vdotq_lane_s32(sum1, samples1_hi, filters, 1); - - // Narrow and re-pack. - int16x8_t sum = vcombine_s16(vshrn_n_s32(sum0, 1), vshrn_n_s32(sum1, 1)); - return vqrshrun_n_s16(sum, FILTER_BITS - 1); -} - -static INLINE void convolve_8tap_vert_neon_dotprod( - const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, int w, int h, const int8x8_t filter) { - const uint8x16x3_t merge_block_tbl = vld1q_u8_x3(dot_prod_merge_block_tbl); - - if (w == 4) { - uint8x8_t t0, t1, t2, t3, t4, t5, t6; - load_u8_8x7(src, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6); - src += 7 * src_stride; - - // Transform sample range to [-128, 127] for 8-bit signed dot product. - int8x8_t s0 = vreinterpret_s8_u8(vsub_u8(t0, vdup_n_u8(128))); - int8x8_t s1 = vreinterpret_s8_u8(vsub_u8(t1, vdup_n_u8(128))); - int8x8_t s2 = vreinterpret_s8_u8(vsub_u8(t2, vdup_n_u8(128))); - int8x8_t s3 = vreinterpret_s8_u8(vsub_u8(t3, vdup_n_u8(128))); - int8x8_t s4 = vreinterpret_s8_u8(vsub_u8(t4, vdup_n_u8(128))); - int8x8_t s5 = vreinterpret_s8_u8(vsub_u8(t5, vdup_n_u8(128))); - int8x8_t s6 = vreinterpret_s8_u8(vsub_u8(t6, vdup_n_u8(128))); - - // This operation combines a conventional transpose and the sample permute - // (see horizontal case) required before computing the dot product. - int8x16_t s0123, s1234, s2345, s3456; - transpose_concat_4x4(s0, s1, s2, s3, &s0123); - transpose_concat_4x4(s1, s2, s3, s4, &s1234); - transpose_concat_4x4(s2, s3, s4, s5, &s2345); - transpose_concat_4x4(s3, s4, s5, s6, &s3456); - - do { - uint8x8_t t7, t8, t9, t10; - load_u8_8x4(src, src_stride, &t7, &t8, &t9, &t10); - - int8x8_t s7 = vreinterpret_s8_u8(vsub_u8(t7, vdup_n_u8(128))); - int8x8_t s8 = vreinterpret_s8_u8(vsub_u8(t8, vdup_n_u8(128))); - int8x8_t s9 = vreinterpret_s8_u8(vsub_u8(t9, vdup_n_u8(128))); - int8x8_t s10 = vreinterpret_s8_u8(vsub_u8(t10, vdup_n_u8(128))); - - int8x16_t s78910; - transpose_concat_4x4(s7, s8, s9, s10, &s78910); - - // Merge new data into block from previous iteration. - int8x16x2_t samples_LUT = { { s3456, s78910 } }; - int8x16_t s4567 = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[0]); - int8x16_t s5678 = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[1]); - int8x16_t s6789 = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[2]); - - int16x4_t d0 = convolve8_4_v(s0123, s4567, filter); - int16x4_t d1 = convolve8_4_v(s1234, s5678, filter); - int16x4_t d2 = convolve8_4_v(s2345, s6789, filter); - int16x4_t d3 = convolve8_4_v(s3456, s78910, filter); - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(d0, d1), FILTER_BITS - 1); - uint8x8_t d23 = vqrshrun_n_s16(vcombine_s16(d2, d3), FILTER_BITS - 1); - - store_u8(dst + 0 * dst_stride, dst_stride, d01); - store_u8(dst + 2 * dst_stride, dst_stride, d23); - - /* Prepare block for next iteration - re-using as much as possible. */ - /* Shuffle everything up four rows. */ - s0123 = s4567; - s1234 = s5678; - s2345 = s6789; - s3456 = s78910; - - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - do { - const uint8_t *s = src; - uint8_t *d = dst; - int height = h; - - uint8x8_t t0, t1, t2, t3, t4, t5, t6; - load_u8_8x7(s, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6); - s += 7 * src_stride; - - // Transform sample range to [-128, 127] for 8-bit signed dot product. - int8x8_t s0 = vreinterpret_s8_u8(vsub_u8(t0, vdup_n_u8(128))); - int8x8_t s1 = vreinterpret_s8_u8(vsub_u8(t1, vdup_n_u8(128))); - int8x8_t s2 = vreinterpret_s8_u8(vsub_u8(t2, vdup_n_u8(128))); - int8x8_t s3 = vreinterpret_s8_u8(vsub_u8(t3, vdup_n_u8(128))); - int8x8_t s4 = vreinterpret_s8_u8(vsub_u8(t4, vdup_n_u8(128))); - int8x8_t s5 = vreinterpret_s8_u8(vsub_u8(t5, vdup_n_u8(128))); - int8x8_t s6 = vreinterpret_s8_u8(vsub_u8(t6, vdup_n_u8(128))); - - // This operation combines a conventional transpose and the sample permute - // (see horizontal case) required before computing the dot product. - int8x16_t s0123_lo, s0123_hi, s1234_lo, s1234_hi, s2345_lo, s2345_hi, - s3456_lo, s3456_hi; - transpose_concat_8x4(s0, s1, s2, s3, &s0123_lo, &s0123_hi); - transpose_concat_8x4(s1, s2, s3, s4, &s1234_lo, &s1234_hi); - transpose_concat_8x4(s2, s3, s4, s5, &s2345_lo, &s2345_hi); - transpose_concat_8x4(s3, s4, s5, s6, &s3456_lo, &s3456_hi); - - do { - uint8x8_t t7, t8, t9, t10; - load_u8_8x4(s, src_stride, &t7, &t8, &t9, &t10); - - int8x8_t s7 = vreinterpret_s8_u8(vsub_u8(t7, vdup_n_u8(128))); - int8x8_t s8 = vreinterpret_s8_u8(vsub_u8(t8, vdup_n_u8(128))); - int8x8_t s9 = vreinterpret_s8_u8(vsub_u8(t9, vdup_n_u8(128))); - int8x8_t s10 = vreinterpret_s8_u8(vsub_u8(t10, vdup_n_u8(128))); - - int8x16_t s78910_lo, s78910_hi; - transpose_concat_8x4(s7, s8, s9, s10, &s78910_lo, &s78910_hi); - - // Merge new data into block from previous iteration. - int8x16x2_t samples_LUT = { { s3456_lo, s78910_lo } }; - int8x16_t s4567_lo = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[0]); - int8x16_t s5678_lo = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[1]); - int8x16_t s6789_lo = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[2]); - - samples_LUT.val[0] = s3456_hi; - samples_LUT.val[1] = s78910_hi; - int8x16_t s4567_hi = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[0]); - int8x16_t s5678_hi = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[1]); - int8x16_t s6789_hi = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[2]); - - uint8x8_t d0 = - convolve8_8_v(s0123_lo, s4567_lo, s0123_hi, s4567_hi, filter); - uint8x8_t d1 = - convolve8_8_v(s1234_lo, s5678_lo, s1234_hi, s5678_hi, filter); - uint8x8_t d2 = - convolve8_8_v(s2345_lo, s6789_lo, s2345_hi, s6789_hi, filter); - uint8x8_t d3 = - convolve8_8_v(s3456_lo, s78910_lo, s3456_hi, s78910_hi, filter); - - store_u8_8x4(d, dst_stride, d0, d1, d2, d3); - - // Prepare block for next iteration - re-using as much as possible. - // Shuffle everything up four rows. - s0123_lo = s4567_lo; - s0123_hi = s4567_hi; - s1234_lo = s5678_lo; - s1234_hi = s5678_hi; - s2345_lo = s6789_lo; - s2345_hi = s6789_hi; - s3456_lo = s78910_lo; - s3456_hi = s78910_hi; - - s += 4 * src_stride; - d += 4 * dst_stride; - height -= 4; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); - } -} - -void vpx_convolve8_vert_neon_dotprod(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - assert(y_step_q4 == 16); - - (void)x0_q4; - (void)x_step_q4; - (void)y_step_q4; - - if (vpx_get_filter_taps(filter[y0_q4]) <= 4) { - const int16x8_t y_filter = vld1q_s16(filter[y0_q4]); - - convolve_4tap_vert_neon(src - src_stride, src_stride, dst, dst_stride, w, h, - y_filter); - } else { - const int8x8_t y_filter = vmovn_s16(vld1q_s16(filter[y0_q4])); - - convolve_8tap_vert_neon_dotprod(src - 3 * src_stride, src_stride, dst, - dst_stride, w, h, y_filter); - } -} - -void vpx_convolve8_avg_vert_neon_dotprod(const uint8_t *src, - ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, - int y_step_q4, int w, int h) { - const int8x8_t filters = vmovn_s16(vld1q_s16(filter[y0_q4])); - const uint8x16x3_t merge_block_tbl = vld1q_u8_x3(dot_prod_merge_block_tbl); - - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - assert(y_step_q4 == 16); - - (void)x0_q4; - (void)x_step_q4; - (void)y_step_q4; - - src -= 3 * src_stride; - - if (w == 4) { - uint8x8_t t0, t1, t2, t3, t4, t5, t6; - load_u8_8x7(src, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6); - src += 7 * src_stride; - - // Transform sample range to [-128, 127] for 8-bit signed dot product. - int8x8_t s0 = vreinterpret_s8_u8(vsub_u8(t0, vdup_n_u8(128))); - int8x8_t s1 = vreinterpret_s8_u8(vsub_u8(t1, vdup_n_u8(128))); - int8x8_t s2 = vreinterpret_s8_u8(vsub_u8(t2, vdup_n_u8(128))); - int8x8_t s3 = vreinterpret_s8_u8(vsub_u8(t3, vdup_n_u8(128))); - int8x8_t s4 = vreinterpret_s8_u8(vsub_u8(t4, vdup_n_u8(128))); - int8x8_t s5 = vreinterpret_s8_u8(vsub_u8(t5, vdup_n_u8(128))); - int8x8_t s6 = vreinterpret_s8_u8(vsub_u8(t6, vdup_n_u8(128))); - - // This operation combines a conventional transpose and the sample permute - // (see horizontal case) required before computing the dot product. - int8x16_t s0123, s1234, s2345, s3456; - transpose_concat_4x4(s0, s1, s2, s3, &s0123); - transpose_concat_4x4(s1, s2, s3, s4, &s1234); - transpose_concat_4x4(s2, s3, s4, s5, &s2345); - transpose_concat_4x4(s3, s4, s5, s6, &s3456); - - do { - uint8x8_t t7, t8, t9, t10; - load_u8_8x4(src, src_stride, &t7, &t8, &t9, &t10); - - int8x8_t s7 = vreinterpret_s8_u8(vsub_u8(t7, vdup_n_u8(128))); - int8x8_t s8 = vreinterpret_s8_u8(vsub_u8(t8, vdup_n_u8(128))); - int8x8_t s9 = vreinterpret_s8_u8(vsub_u8(t9, vdup_n_u8(128))); - int8x8_t s10 = vreinterpret_s8_u8(vsub_u8(t10, vdup_n_u8(128))); - - int8x16_t s78910; - transpose_concat_4x4(s7, s8, s9, s10, &s78910); - - // Merge new data into block from previous iteration. - int8x16x2_t samples_LUT = { { s3456, s78910 } }; - int8x16_t s4567 = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[0]); - int8x16_t s5678 = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[1]); - int8x16_t s6789 = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[2]); - - int16x4_t d0 = convolve8_4_v(s0123, s4567, filters); - int16x4_t d1 = convolve8_4_v(s1234, s5678, filters); - int16x4_t d2 = convolve8_4_v(s2345, s6789, filters); - int16x4_t d3 = convolve8_4_v(s3456, s78910, filters); - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(d0, d1), FILTER_BITS - 1); - uint8x8_t d23 = vqrshrun_n_s16(vcombine_s16(d2, d3), FILTER_BITS - 1); - - uint8x8_t dd01 = load_u8(dst + 0 * dst_stride, dst_stride); - uint8x8_t dd23 = load_u8(dst + 2 * dst_stride, dst_stride); - - d01 = vrhadd_u8(d01, dd01); - d23 = vrhadd_u8(d23, dd23); - - store_u8(dst + 0 * dst_stride, dst_stride, d01); - store_u8(dst + 2 * dst_stride, dst_stride, d23); - - // Prepare block for next iteration - re-using as much as possible. - // Shuffle everything up four rows. - s0123 = s4567; - s1234 = s5678; - s2345 = s6789; - s3456 = s78910; - - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - do { - const uint8_t *s = src; - uint8_t *d = dst; - int height = h; - - uint8x8_t t0, t1, t2, t3, t4, t5, t6; - load_u8_8x7(s, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6); - s += 7 * src_stride; - - // Transform sample range to [-128, 127] for 8-bit signed dot product. - int8x8_t s0 = vreinterpret_s8_u8(vsub_u8(t0, vdup_n_u8(128))); - int8x8_t s1 = vreinterpret_s8_u8(vsub_u8(t1, vdup_n_u8(128))); - int8x8_t s2 = vreinterpret_s8_u8(vsub_u8(t2, vdup_n_u8(128))); - int8x8_t s3 = vreinterpret_s8_u8(vsub_u8(t3, vdup_n_u8(128))); - int8x8_t s4 = vreinterpret_s8_u8(vsub_u8(t4, vdup_n_u8(128))); - int8x8_t s5 = vreinterpret_s8_u8(vsub_u8(t5, vdup_n_u8(128))); - int8x8_t s6 = vreinterpret_s8_u8(vsub_u8(t6, vdup_n_u8(128))); - - // This operation combines a conventional transpose and the sample permute - // (see horizontal case) required before computing the dot product. - int8x16_t s0123_lo, s0123_hi, s1234_lo, s1234_hi, s2345_lo, s2345_hi, - s3456_lo, s3456_hi; - transpose_concat_8x4(s0, s1, s2, s3, &s0123_lo, &s0123_hi); - transpose_concat_8x4(s1, s2, s3, s4, &s1234_lo, &s1234_hi); - transpose_concat_8x4(s2, s3, s4, s5, &s2345_lo, &s2345_hi); - transpose_concat_8x4(s3, s4, s5, s6, &s3456_lo, &s3456_hi); - - do { - uint8x8_t t7, t8, t9, t10; - load_u8_8x4(s, src_stride, &t7, &t8, &t9, &t10); - - int8x8_t s7 = vreinterpret_s8_u8(vsub_u8(t7, vdup_n_u8(128))); - int8x8_t s8 = vreinterpret_s8_u8(vsub_u8(t8, vdup_n_u8(128))); - int8x8_t s9 = vreinterpret_s8_u8(vsub_u8(t9, vdup_n_u8(128))); - int8x8_t s10 = vreinterpret_s8_u8(vsub_u8(t10, vdup_n_u8(128))); - - int8x16_t s78910_lo, s78910_hi; - transpose_concat_8x4(s7, s8, s9, s10, &s78910_lo, &s78910_hi); - - // Merge new data into block from previous iteration. - int8x16x2_t samples_LUT = { { s3456_lo, s78910_lo } }; - int8x16_t s4567_lo = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[0]); - int8x16_t s5678_lo = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[1]); - int8x16_t s6789_lo = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[2]); - - samples_LUT.val[0] = s3456_hi; - samples_LUT.val[1] = s78910_hi; - int8x16_t s4567_hi = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[0]); - int8x16_t s5678_hi = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[1]); - int8x16_t s6789_hi = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[2]); - - uint8x8_t d0 = - convolve8_8_v(s0123_lo, s4567_lo, s0123_hi, s4567_hi, filters); - uint8x8_t d1 = - convolve8_8_v(s1234_lo, s5678_lo, s1234_hi, s5678_hi, filters); - uint8x8_t d2 = - convolve8_8_v(s2345_lo, s6789_lo, s2345_hi, s6789_hi, filters); - uint8x8_t d3 = - convolve8_8_v(s3456_lo, s78910_lo, s3456_hi, s78910_hi, filters); - - uint8x8_t dd0, dd1, dd2, dd3; - load_u8_8x4(d, dst_stride, &dd0, &dd1, &dd2, &dd3); - - d0 = vrhadd_u8(d0, dd0); - d1 = vrhadd_u8(d1, dd1); - d2 = vrhadd_u8(d2, dd2); - d3 = vrhadd_u8(d3, dd3); - - store_u8_8x4(d, dst_stride, d0, d1, d2, d3); - - // Prepare block for next iteration - re-using as much as possible. - // Shuffle everything up four rows. - s0123_lo = s4567_lo; - s0123_hi = s4567_hi; - s1234_lo = s5678_lo; - s1234_hi = s5678_hi; - s2345_lo = s6789_lo; - s2345_hi = s6789_hi; - s3456_lo = s78910_lo; - s3456_hi = s78910_hi; - - s += 4 * src_stride; - d += 4 * dst_stride; - height -= 4; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); - } -} - -static INLINE void convolve_4tap_2d_neon_dotprod(const uint8_t *src, - ptrdiff_t src_stride, - uint8_t *dst, - ptrdiff_t dst_stride, int w, - int h, const int8x8_t x_filter, - const uint8x8_t y_filter) { - // Neon does not have lane-referencing multiply or multiply-accumulate - // instructions that operate on vectors of 8-bit elements. This means we have - // to duplicate filter taps into a whole vector and use standard multiply / - // multiply-accumulate instructions. - const uint8x8_t y_filter_taps[4] = { vdup_lane_u8(y_filter, 2), - vdup_lane_u8(y_filter, 3), - vdup_lane_u8(y_filter, 4), - vdup_lane_u8(y_filter, 5) }; - - if (w == 4) { - const uint8x16_t permute_tbl = vld1q_u8(dot_prod_permute_tbl); - - uint8x16_t h_s0, h_s1, h_s2; - load_u8_16x3(src, src_stride, &h_s0, &h_s1, &h_s2); - - int16x4_t t0 = convolve4_4_h(h_s0, x_filter, permute_tbl); - int16x4_t t1 = convolve4_4_h(h_s1, x_filter, permute_tbl); - int16x4_t t2 = convolve4_4_h(h_s2, x_filter, permute_tbl); - // We halved the filter values so -1 from right shift. - uint8x8_t v_s01 = vqrshrun_n_s16(vcombine_s16(t0, t1), FILTER_BITS - 1); - uint8x8_t v_s12 = vqrshrun_n_s16(vcombine_s16(t1, t2), FILTER_BITS - 1); - - src += 3 * src_stride; - - do { - uint8x16_t h_s3, h_s4, h_s5, h_s6; - load_u8_16x4(src, src_stride, &h_s3, &h_s4, &h_s5, &h_s6); - - int16x4_t t3 = convolve4_4_h(h_s3, x_filter, permute_tbl); - int16x4_t t4 = convolve4_4_h(h_s4, x_filter, permute_tbl); - int16x4_t t5 = convolve4_4_h(h_s5, x_filter, permute_tbl); - int16x4_t t6 = convolve4_4_h(h_s6, x_filter, permute_tbl); - // We halved the filter values so -1 from right shift. - uint8x8_t v_s34 = vqrshrun_n_s16(vcombine_s16(t3, t4), FILTER_BITS - 1); - uint8x8_t v_s56 = vqrshrun_n_s16(vcombine_s16(t5, t6), FILTER_BITS - 1); - uint8x8_t v_s23 = vext_u8(v_s12, v_s34, 4); - uint8x8_t v_s45 = vext_u8(v_s34, v_s56, 4); - - uint8x8_t d01 = convolve4_8(v_s01, v_s12, v_s23, v_s34, y_filter_taps); - uint8x8_t d23 = convolve4_8(v_s23, v_s34, v_s45, v_s56, y_filter_taps); - - store_unaligned_u8(dst + 0 * dst_stride, dst_stride, d01); - store_unaligned_u8(dst + 2 * dst_stride, dst_stride, d23); - - v_s01 = v_s45; - v_s12 = v_s56; - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint8x16x2_t permute_tbl = vld1q_u8_x2(dot_prod_permute_tbl); - - do { - const uint8_t *s = src; - uint8_t *d = dst; - int height = h; - - uint8x16_t h_s0, h_s1, h_s2; - load_u8_16x3(s, src_stride, &h_s0, &h_s1, &h_s2); - - uint8x8_t v_s0 = convolve4_8_h(h_s0, x_filter, permute_tbl); - uint8x8_t v_s1 = convolve4_8_h(h_s1, x_filter, permute_tbl); - uint8x8_t v_s2 = convolve4_8_h(h_s2, x_filter, permute_tbl); - - s += 3 * src_stride; - - do { - uint8x16_t h_s3, h_s4, h_s5, h_s6; - load_u8_16x4(s, src_stride, &h_s3, &h_s4, &h_s5, &h_s6); - - uint8x8_t v_s3 = convolve4_8_h(h_s3, x_filter, permute_tbl); - uint8x8_t v_s4 = convolve4_8_h(h_s4, x_filter, permute_tbl); - uint8x8_t v_s5 = convolve4_8_h(h_s5, x_filter, permute_tbl); - uint8x8_t v_s6 = convolve4_8_h(h_s6, x_filter, permute_tbl); - - uint8x8_t d0 = convolve4_8(v_s0, v_s1, v_s2, v_s3, y_filter_taps); - uint8x8_t d1 = convolve4_8(v_s1, v_s2, v_s3, v_s4, y_filter_taps); - uint8x8_t d2 = convolve4_8(v_s2, v_s3, v_s4, v_s5, y_filter_taps); - uint8x8_t d3 = convolve4_8(v_s3, v_s4, v_s5, v_s6, y_filter_taps); - - store_u8_8x4(d, dst_stride, d0, d1, d2, d3); - - v_s0 = v_s4; - v_s1 = v_s5; - v_s2 = v_s6; - s += 4 * src_stride; - d += 4 * dst_stride; - height -= 4; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); - } -} - -static INLINE void convolve_8tap_2d_horiz_neon_dotprod( - const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, int w, int h, const int8x8_t filter) { - if (w == 4) { - const uint8x16x2_t permute_tbl = vld1q_u8_x2(dot_prod_permute_tbl); - - do { - uint8x16_t s0, s1, s2, s3; - load_u8_16x4(src, src_stride, &s0, &s1, &s2, &s3); - - int16x4_t d0 = convolve8_4_h(s0, filter, permute_tbl); - int16x4_t d1 = convolve8_4_h(s1, filter, permute_tbl); - int16x4_t d2 = convolve8_4_h(s2, filter, permute_tbl); - int16x4_t d3 = convolve8_4_h(s3, filter, permute_tbl); - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(d0, d1), FILTER_BITS - 1); - uint8x8_t d23 = vqrshrun_n_s16(vcombine_s16(d2, d3), FILTER_BITS - 1); - - store_u8(dst + 0 * dst_stride, dst_stride, d01); - store_u8(dst + 2 * dst_stride, dst_stride, d23); - - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h > 3); - - // Process final three rows (h % 4 == 3). See vpx_convolve_neon_i8mm() - // below for further details on possible values of block height. - uint8x16_t s0, s1, s2; - load_u8_16x3(src, src_stride, &s0, &s1, &s2); - - int16x4_t d0 = convolve8_4_h(s0, filter, permute_tbl); - int16x4_t d1 = convolve8_4_h(s1, filter, permute_tbl); - int16x4_t d2 = convolve8_4_h(s2, filter, permute_tbl); - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(d0, d1), FILTER_BITS - 1); - uint8x8_t d23 = - vqrshrun_n_s16(vcombine_s16(d2, vdup_n_s16(0)), FILTER_BITS - 1); - - store_u8(dst + 0 * dst_stride, dst_stride, d01); - store_u8_4x1(dst + 2 * dst_stride, d23); - } else { - const uint8x16x3_t permute_tbl = vld1q_u8_x3(dot_prod_permute_tbl); - - do { - const uint8_t *s = src; - uint8_t *d = dst; - int width = w; - - do { - uint8x16_t s0, s1, s2, s3; - load_u8_16x4(s, src_stride, &s0, &s1, &s2, &s3); - - uint8x8_t d0 = convolve8_8_h(s0, filter, permute_tbl); - uint8x8_t d1 = convolve8_8_h(s1, filter, permute_tbl); - uint8x8_t d2 = convolve8_8_h(s2, filter, permute_tbl); - uint8x8_t d3 = convolve8_8_h(s3, filter, permute_tbl); - - store_u8_8x4(d, dst_stride, d0, d1, d2, d3); - - s += 8; - d += 8; - width -= 8; - } while (width > 0); - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h > 3); - - // Process final three rows (h % 4 == 3). See vpx_convolve_neon_i8mm() - // below for further details on possible values of block height. - const uint8_t *s = src; - uint8_t *d = dst; - int width = w; - - do { - uint8x16_t s0, s1, s2; - load_u8_16x3(s, src_stride, &s0, &s1, &s2); - - uint8x8_t d0 = convolve8_8_h(s0, filter, permute_tbl); - uint8x8_t d1 = convolve8_8_h(s1, filter, permute_tbl); - uint8x8_t d2 = convolve8_8_h(s2, filter, permute_tbl); - - store_u8_8x3(d, dst_stride, d0, d1, d2); - - s += 8; - d += 8; - width -= 8; - } while (width > 0); - } -} - -void vpx_convolve8_neon_dotprod(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - assert(x_step_q4 == 16); - assert(y_step_q4 == 16); - - (void)x_step_q4; - (void)y_step_q4; - - const int x_filter_taps = vpx_get_filter_taps(filter[x0_q4]) <= 4 ? 4 : 8; - const int y_filter_taps = vpx_get_filter_taps(filter[y0_q4]) <= 4 ? 4 : 8; - // Account for needing filter_taps / 2 - 1 lines prior and filter_taps / 2 - // lines post both horizontally and vertically. - const ptrdiff_t horiz_offset = x_filter_taps / 2 - 1; - const ptrdiff_t vert_offset = (y_filter_taps / 2 - 1) * src_stride; - - if (x_filter_taps == 4 && y_filter_taps == 4) { - const int16x4_t x_filter = vld1_s16(filter[x0_q4] + 2); - const int16x8_t y_filter = vld1q_s16(filter[y0_q4]); - - // 4-tap and bilinear filter values are even, so halve them to reduce - // intermediate precision requirements. - const int8x8_t x_filter_4tap = - vshrn_n_s16(vcombine_s16(x_filter, vdup_n_s16(0)), 1); - const uint8x8_t y_filter_4tap = - vshrn_n_u16(vreinterpretq_u16_s16(vabsq_s16(y_filter)), 1); - - convolve_4tap_2d_neon_dotprod(src - horiz_offset - vert_offset, src_stride, - dst, dst_stride, w, h, x_filter_4tap, - y_filter_4tap); - return; - } - - // Given our constraints: w <= 64, h <= 64, taps <= 8 we can reduce the - // maximum buffer size to 64 * (64 + 7). - DECLARE_ALIGNED(32, uint8_t, im_block[64 * 71]); - const int im_stride = 64; - const int im_height = h + SUBPEL_TAPS - 1; - - const int8x8_t x_filter_8tap = vmovn_s16(vld1q_s16(filter[x0_q4])); - const int8x8_t y_filter_8tap = vmovn_s16(vld1q_s16(filter[y0_q4])); - - convolve_8tap_2d_horiz_neon_dotprod(src - horiz_offset - vert_offset, - src_stride, im_block, im_stride, w, - im_height, x_filter_8tap); - - convolve_8tap_vert_neon_dotprod(im_block, im_stride, dst, dst_stride, w, h, - y_filter_8tap); -} - -void vpx_convolve8_avg_neon_dotprod(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - DECLARE_ALIGNED(32, uint8_t, im_block[64 * 71]); - const int im_stride = 64; - - // Averaging convolution always uses an 8-tap filter. - // Account for the vertical phase needing 3 lines prior and 4 lines post. - const int im_height = h + SUBPEL_TAPS - 1; - const ptrdiff_t offset = SUBPEL_TAPS / 2 - 1; - - assert(y_step_q4 == 16); - assert(x_step_q4 == 16); - - const int8x8_t x_filter_8tap = vmovn_s16(vld1q_s16(filter[x0_q4])); - - convolve_8tap_2d_horiz_neon_dotprod(src - offset - offset * src_stride, - src_stride, im_block, im_stride, w, - im_height, x_filter_8tap); - - vpx_convolve8_avg_vert_neon_dotprod(im_block + offset * im_stride, im_stride, - dst, dst_stride, filter, x0_q4, x_step_q4, - y0_q4, y_step_q4, w, h); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon_i8mm.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon_i8mm.c deleted file mode 100644 index e5820041..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_neon_i8mm.c +++ /dev/null @@ -1,995 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/arm/vpx_convolve8_neon.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_ports/mem.h" - -DECLARE_ALIGNED(16, static const uint8_t, dot_prod_permute_tbl[48]) = { - 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6, - 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10, - 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14 -}; - -DECLARE_ALIGNED(16, static const uint8_t, dot_prod_merge_block_tbl[48]) = { - // Shift left and insert new last column in transposed 4x4 block. - 1, 2, 3, 16, 5, 6, 7, 20, 9, 10, 11, 24, 13, 14, 15, 28, - // Shift left and insert two new columns in transposed 4x4 block. - 2, 3, 16, 17, 6, 7, 20, 21, 10, 11, 24, 25, 14, 15, 28, 29, - // Shift left and insert three new columns in transposed 4x4 block. - 3, 16, 17, 18, 7, 20, 21, 22, 11, 24, 25, 26, 15, 28, 29, 30 -}; - -static INLINE int16x4_t convolve4_4_h(const uint8x16_t samples, - const int8x8_t filters, - const uint8x16_t permute_tbl) { - // Permute samples ready for dot product. - // { 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 } - uint8x16_t permuted_samples = vqtbl1q_u8(samples, permute_tbl); - - int32x4_t sum = - vusdotq_lane_s32(vdupq_n_s32(0), permuted_samples, filters, 0); - - // Further narrowing and packing is performed by the caller. - return vmovn_s32(sum); -} - -static INLINE uint8x8_t convolve4_8_h(const uint8x16_t samples, - const int8x8_t filters, - const uint8x16x2_t permute_tbl) { - // Permute samples ready for dot product. - // { 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 } - // { 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10 } - uint8x16_t permuted_samples[2] = { vqtbl1q_u8(samples, permute_tbl.val[0]), - vqtbl1q_u8(samples, permute_tbl.val[1]) }; - - // First 4 output values. - int32x4_t sum0 = - vusdotq_lane_s32(vdupq_n_s32(0), permuted_samples[0], filters, 0); - // Second 4 output values. - int32x4_t sum1 = - vusdotq_lane_s32(vdupq_n_s32(0), permuted_samples[1], filters, 0); - - // Narrow and re-pack. - int16x8_t sum = vcombine_s16(vmovn_s32(sum0), vmovn_s32(sum1)); - // We halved the filter values so -1 from right shift. - return vqrshrun_n_s16(sum, FILTER_BITS - 1); -} - -static INLINE int16x4_t convolve8_4_h(const uint8x16_t samples, - const int8x8_t filters, - const uint8x16x2_t permute_tbl) { - // Permute samples ready for dot product. - // { 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 } - // { 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10 } - uint8x16_t permuted_samples[2] = { vqtbl1q_u8(samples, permute_tbl.val[0]), - vqtbl1q_u8(samples, permute_tbl.val[1]) }; - - int32x4_t sum = - vusdotq_lane_s32(vdupq_n_s32(0), permuted_samples[0], filters, 0); - sum = vusdotq_lane_s32(sum, permuted_samples[1], filters, 1); - - // Further narrowing and packing is performed by the caller. - return vshrn_n_s32(sum, 1); -} - -static INLINE uint8x8_t convolve8_8_h(const uint8x16_t samples, - const int8x8_t filters, - const uint8x16x3_t permute_tbl) { - // Permute samples ready for dot product. - // { 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 } - // { 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10 } - // { 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14 } - uint8x16_t permuted_samples[3] = { vqtbl1q_u8(samples, permute_tbl.val[0]), - vqtbl1q_u8(samples, permute_tbl.val[1]), - vqtbl1q_u8(samples, permute_tbl.val[2]) }; - - // First 4 output values. - int32x4_t sum0 = - vusdotq_lane_s32(vdupq_n_s32(0), permuted_samples[0], filters, 0); - sum0 = vusdotq_lane_s32(sum0, permuted_samples[1], filters, 1); - // Second 4 output values. - int32x4_t sum1 = - vusdotq_lane_s32(vdupq_n_s32(0), permuted_samples[1], filters, 0); - sum1 = vusdotq_lane_s32(sum1, permuted_samples[2], filters, 1); - - // Narrow and re-pack. - int16x8_t sum = vcombine_s16(vshrn_n_s32(sum0, 1), vshrn_n_s32(sum1, 1)); - return vqrshrun_n_s16(sum, FILTER_BITS - 1); -} - -static INLINE void convolve_4tap_horiz_neon_i8mm(const uint8_t *src, - ptrdiff_t src_stride, - uint8_t *dst, - ptrdiff_t dst_stride, int w, - int h, const int8x8_t filter) { - if (w == 4) { - const uint8x16_t permute_tbl = vld1q_u8(dot_prod_permute_tbl); - - do { - uint8x16_t s0, s1, s2, s3; - load_u8_16x4(src, src_stride, &s0, &s1, &s2, &s3); - - int16x4_t t0 = convolve4_4_h(s0, filter, permute_tbl); - int16x4_t t1 = convolve4_4_h(s1, filter, permute_tbl); - int16x4_t t2 = convolve4_4_h(s2, filter, permute_tbl); - int16x4_t t3 = convolve4_4_h(s3, filter, permute_tbl); - // We halved the filter values so -1 from right shift. - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(t0, t1), FILTER_BITS - 1); - uint8x8_t d23 = vqrshrun_n_s16(vcombine_s16(t2, t3), FILTER_BITS - 1); - - store_u8(dst + 0 * dst_stride, dst_stride, d01); - store_u8(dst + 2 * dst_stride, dst_stride, d23); - - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint8x16x2_t permute_tbl = vld1q_u8_x2(dot_prod_permute_tbl); - - do { - const uint8_t *s = src; - uint8_t *d = dst; - int width = w; - - do { - uint8x16_t s0, s1, s2, s3; - load_u8_16x4(s, src_stride, &s0, &s1, &s2, &s3); - - uint8x8_t d0 = convolve4_8_h(s0, filter, permute_tbl); - uint8x8_t d1 = convolve4_8_h(s1, filter, permute_tbl); - uint8x8_t d2 = convolve4_8_h(s2, filter, permute_tbl); - uint8x8_t d3 = convolve4_8_h(s3, filter, permute_tbl); - - store_u8_8x4(d, dst_stride, d0, d1, d2, d3); - - s += 8; - d += 8; - width -= 8; - } while (width != 0); - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } -} - -static INLINE void convolve_8tap_horiz_neon_i8mm(const uint8_t *src, - ptrdiff_t src_stride, - uint8_t *dst, - ptrdiff_t dst_stride, int w, - int h, const int8x8_t filter) { - if (w == 4) { - const uint8x16x2_t permute_tbl = vld1q_u8_x2(dot_prod_permute_tbl); - - do { - uint8x16_t s0, s1, s2, s3; - load_u8_16x4(src, src_stride, &s0, &s1, &s2, &s3); - - int16x4_t t0 = convolve8_4_h(s0, filter, permute_tbl); - int16x4_t t1 = convolve8_4_h(s1, filter, permute_tbl); - int16x4_t t2 = convolve8_4_h(s2, filter, permute_tbl); - int16x4_t t3 = convolve8_4_h(s3, filter, permute_tbl); - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(t0, t1), FILTER_BITS - 1); - uint8x8_t d23 = vqrshrun_n_s16(vcombine_s16(t2, t3), FILTER_BITS - 1); - - store_u8(dst + 0 * dst_stride, dst_stride, d01); - store_u8(dst + 2 * dst_stride, dst_stride, d23); - - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint8x16x3_t permute_tbl = vld1q_u8_x3(dot_prod_permute_tbl); - - do { - const uint8_t *s = src; - uint8_t *d = dst; - int width = w; - - do { - uint8x16_t s0, s1, s2, s3; - load_u8_16x4(s, src_stride, &s0, &s1, &s2, &s3); - - uint8x8_t d0 = convolve8_8_h(s0, filter, permute_tbl); - uint8x8_t d1 = convolve8_8_h(s1, filter, permute_tbl); - uint8x8_t d2 = convolve8_8_h(s2, filter, permute_tbl); - uint8x8_t d3 = convolve8_8_h(s3, filter, permute_tbl); - - store_u8_8x4(d, dst_stride, d0, d1, d2, d3); - - s += 8; - d += 8; - width -= 8; - } while (width != 0); - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } -} - -void vpx_convolve8_horiz_neon_i8mm(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - assert(x_step_q4 == 16); - - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - if (vpx_get_filter_taps(filter[x0_q4]) <= 4) { - // Load 4-tap filter into first 4 elements of the vector. - // All 4-tap and bilinear filter values are even, so halve them to reduce - // intermediate precision requirements. - const int16x4_t x_filter = vld1_s16(filter[x0_q4] + 2); - const int8x8_t x_filter_4tap = - vshrn_n_s16(vcombine_s16(x_filter, vdup_n_s16(0)), 1); - - convolve_4tap_horiz_neon_i8mm(src - 1, src_stride, dst, dst_stride, w, h, - x_filter_4tap); - - } else { - const int8x8_t x_filter_8tap = vmovn_s16(vld1q_s16(filter[x0_q4])); - - convolve_8tap_horiz_neon_i8mm(src - 3, src_stride, dst, dst_stride, w, h, - x_filter_8tap); - } -} - -void vpx_convolve8_avg_horiz_neon_i8mm(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - const int8x8_t filters = vmovn_s16(vld1q_s16(filter[x0_q4])); - - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - assert(x_step_q4 == 16); - - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - src -= 3; - - if (w == 4) { - const uint8x16x2_t permute_tbl = vld1q_u8_x2(dot_prod_permute_tbl); - - do { - uint8x16_t s0, s1, s2, s3; - load_u8_16x4(src, src_stride, &s0, &s1, &s2, &s3); - - int16x4_t t0 = convolve8_4_h(s0, filters, permute_tbl); - int16x4_t t1 = convolve8_4_h(s1, filters, permute_tbl); - int16x4_t t2 = convolve8_4_h(s2, filters, permute_tbl); - int16x4_t t3 = convolve8_4_h(s3, filters, permute_tbl); - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(t0, t1), FILTER_BITS - 1); - uint8x8_t d23 = vqrshrun_n_s16(vcombine_s16(t2, t3), FILTER_BITS - 1); - - uint8x8_t dd01 = load_u8(dst + 0 * dst_stride, dst_stride); - uint8x8_t dd23 = load_u8(dst + 2 * dst_stride, dst_stride); - - d01 = vrhadd_u8(d01, dd01); - d23 = vrhadd_u8(d23, dd23); - - store_u8(dst + 0 * dst_stride, dst_stride, d01); - store_u8(dst + 2 * dst_stride, dst_stride, d23); - - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint8x16x3_t permute_tbl = vld1q_u8_x3(dot_prod_permute_tbl); - - do { - const uint8_t *s = src; - uint8_t *d = dst; - int width = w; - - do { - uint8x16_t s0, s1, s2, s3; - load_u8_16x4(s, src_stride, &s0, &s1, &s2, &s3); - - uint8x8_t d0 = convolve8_8_h(s0, filters, permute_tbl); - uint8x8_t d1 = convolve8_8_h(s1, filters, permute_tbl); - uint8x8_t d2 = convolve8_8_h(s2, filters, permute_tbl); - uint8x8_t d3 = convolve8_8_h(s3, filters, permute_tbl); - - uint8x8_t dd0, dd1, dd2, dd3; - load_u8_8x4(d, dst_stride, &dd0, &dd1, &dd2, &dd3); - - d0 = vrhadd_u8(d0, dd0); - d1 = vrhadd_u8(d1, dd1); - d2 = vrhadd_u8(d2, dd2); - d3 = vrhadd_u8(d3, dd3); - - store_u8_8x4(d, dst_stride, d0, d1, d2, d3); - - s += 8; - d += 8; - width -= 8; - } while (width != 0); - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } -} - -static INLINE void transpose_concat_4x4(uint8x8_t a0, uint8x8_t a1, - uint8x8_t a2, uint8x8_t a3, - uint8x16_t *b) { - // Transpose 8-bit elements and concatenate result rows as follows: - // a0: 00, 01, 02, 03, XX, XX, XX, XX - // a1: 10, 11, 12, 13, XX, XX, XX, XX - // a2: 20, 21, 22, 23, XX, XX, XX, XX - // a3: 30, 31, 32, 33, XX, XX, XX, XX - // - // b: 00, 10, 20, 30, 01, 11, 21, 31, 02, 12, 22, 32, 03, 13, 23, 33 - - uint8x16_t a0q = vcombine_u8(a0, vdup_n_u8(0)); - uint8x16_t a1q = vcombine_u8(a1, vdup_n_u8(0)); - uint8x16_t a2q = vcombine_u8(a2, vdup_n_u8(0)); - uint8x16_t a3q = vcombine_u8(a3, vdup_n_u8(0)); - - uint8x16_t a01 = vzipq_u8(a0q, a1q).val[0]; - uint8x16_t a23 = vzipq_u8(a2q, a3q).val[0]; - - uint16x8_t a0123 = - vzipq_u16(vreinterpretq_u16_u8(a01), vreinterpretq_u16_u8(a23)).val[0]; - - *b = vreinterpretq_u8_u16(a0123); -} - -static INLINE void transpose_concat_8x4(uint8x8_t a0, uint8x8_t a1, - uint8x8_t a2, uint8x8_t a3, - uint8x16_t *b0, uint8x16_t *b1) { - // Transpose 8-bit elements and concatenate result rows as follows: - // a0: 00, 01, 02, 03, 04, 05, 06, 07 - // a1: 10, 11, 12, 13, 14, 15, 16, 17 - // a2: 20, 21, 22, 23, 24, 25, 26, 27 - // a3: 30, 31, 32, 33, 34, 35, 36, 37 - // - // b0: 00, 10, 20, 30, 01, 11, 21, 31, 02, 12, 22, 32, 03, 13, 23, 33 - // b1: 04, 14, 24, 34, 05, 15, 25, 35, 06, 16, 26, 36, 07, 17, 27, 37 - - uint8x16_t a0q = vcombine_u8(a0, vdup_n_u8(0)); - uint8x16_t a1q = vcombine_u8(a1, vdup_n_u8(0)); - uint8x16_t a2q = vcombine_u8(a2, vdup_n_u8(0)); - uint8x16_t a3q = vcombine_u8(a3, vdup_n_u8(0)); - - uint8x16_t a01 = vzipq_u8(a0q, a1q).val[0]; - uint8x16_t a23 = vzipq_u8(a2q, a3q).val[0]; - - uint16x8x2_t a0123 = - vzipq_u16(vreinterpretq_u16_u8(a01), vreinterpretq_u16_u8(a23)); - - *b0 = vreinterpretq_u8_u16(a0123.val[0]); - *b1 = vreinterpretq_u8_u16(a0123.val[1]); -} - -static INLINE int16x4_t convolve8_4_v(const uint8x16_t samples_lo, - const uint8x16_t samples_hi, - const int8x8_t filters) { - // Sample permutation is performed by the caller. - int32x4_t sum = vusdotq_lane_s32(vdupq_n_s32(0), samples_lo, filters, 0); - sum = vusdotq_lane_s32(sum, samples_hi, filters, 1); - - // Further narrowing and packing is performed by the caller. - return vshrn_n_s32(sum, 1); -} - -static INLINE uint8x8_t convolve8_8_v(const uint8x16_t samples0_lo, - const uint8x16_t samples0_hi, - const uint8x16_t samples1_lo, - const uint8x16_t samples1_hi, - const int8x8_t filters) { - // Sample permutation is performed by the caller. - - // First 4 output values. - int32x4_t sum0 = vusdotq_lane_s32(vdupq_n_s32(0), samples0_lo, filters, 0); - sum0 = vusdotq_lane_s32(sum0, samples0_hi, filters, 1); - // Second 4 output values. - int32x4_t sum1 = vusdotq_lane_s32(vdupq_n_s32(0), samples1_lo, filters, 0); - sum1 = vusdotq_lane_s32(sum1, samples1_hi, filters, 1); - - // Narrow and re-pack. - int16x8_t sum = vcombine_s16(vshrn_n_s32(sum0, 1), vshrn_n_s32(sum1, 1)); - return vqrshrun_n_s16(sum, FILTER_BITS - 1); -} - -static INLINE void convolve_8tap_vert_neon_i8mm(const uint8_t *src, - ptrdiff_t src_stride, - uint8_t *dst, - ptrdiff_t dst_stride, int w, - int h, const int8x8_t filter) { - const uint8x16x3_t merge_block_tbl = vld1q_u8_x3(dot_prod_merge_block_tbl); - if (w == 4) { - uint8x8_t s0, s1, s2, s3, s4, s5, s6; - load_u8_8x7(src, src_stride, &s0, &s1, &s2, &s3, &s4, &s5, &s6); - src += 7 * src_stride; - - // This operation combines a conventional transpose and the sample permute - // (see horizontal case) required before computing the dot product. - uint8x16_t s0123, s1234, s2345, s3456; - transpose_concat_4x4(s0, s1, s2, s3, &s0123); - transpose_concat_4x4(s1, s2, s3, s4, &s1234); - transpose_concat_4x4(s2, s3, s4, s5, &s2345); - transpose_concat_4x4(s3, s4, s5, s6, &s3456); - - do { - uint8x8_t s7, s8, s9, s10; - load_u8_8x4(src, src_stride, &s7, &s8, &s9, &s10); - - uint8x16_t s78910; - transpose_concat_4x4(s7, s8, s9, s10, &s78910); - - // Merge new data into block from previous iteration. - uint8x16x2_t samples_LUT = { { s3456, s78910 } }; - uint8x16_t s4567 = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[0]); - uint8x16_t s5678 = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[1]); - uint8x16_t s6789 = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[2]); - - int16x4_t d0 = convolve8_4_v(s0123, s4567, filter); - int16x4_t d1 = convolve8_4_v(s1234, s5678, filter); - int16x4_t d2 = convolve8_4_v(s2345, s6789, filter); - int16x4_t d3 = convolve8_4_v(s3456, s78910, filter); - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(d0, d1), FILTER_BITS - 1); - uint8x8_t d23 = vqrshrun_n_s16(vcombine_s16(d2, d3), FILTER_BITS - 1); - - store_u8(dst + 0 * dst_stride, dst_stride, d01); - store_u8(dst + 2 * dst_stride, dst_stride, d23); - - // Prepare block for next iteration - re-using as much as possible. - // Shuffle everything up four rows. - s0123 = s4567; - s1234 = s5678; - s2345 = s6789; - s3456 = s78910; - - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - do { - const uint8_t *s = src; - uint8_t *d = dst; - int height = h; - - uint8x8_t s0, s1, s2, s3, s4, s5, s6; - load_u8_8x7(s, src_stride, &s0, &s1, &s2, &s3, &s4, &s5, &s6); - s += 7 * src_stride; - - // This operation combines a conventional transpose and the sample permute - // (see horizontal case) required before computing the dot product. - uint8x16_t s0123_lo, s0123_hi, s1234_lo, s1234_hi, s2345_lo, s2345_hi, - s3456_lo, s3456_hi; - transpose_concat_8x4(s0, s1, s2, s3, &s0123_lo, &s0123_hi); - transpose_concat_8x4(s1, s2, s3, s4, &s1234_lo, &s1234_hi); - transpose_concat_8x4(s2, s3, s4, s5, &s2345_lo, &s2345_hi); - transpose_concat_8x4(s3, s4, s5, s6, &s3456_lo, &s3456_hi); - - do { - uint8x8_t s7, s8, s9, s10; - load_u8_8x4(s, src_stride, &s7, &s8, &s9, &s10); - - uint8x16_t s78910_lo, s78910_hi; - transpose_concat_8x4(s7, s8, s9, s10, &s78910_lo, &s78910_hi); - - // Merge new data into block from previous iteration. - uint8x16x2_t samples_LUT = { { s3456_lo, s78910_lo } }; - uint8x16_t s4567_lo = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[0]); - uint8x16_t s5678_lo = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[1]); - uint8x16_t s6789_lo = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[2]); - - samples_LUT.val[0] = s3456_hi; - samples_LUT.val[1] = s78910_hi; - uint8x16_t s4567_hi = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[0]); - uint8x16_t s5678_hi = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[1]); - uint8x16_t s6789_hi = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[2]); - - uint8x8_t d0 = - convolve8_8_v(s0123_lo, s4567_lo, s0123_hi, s4567_hi, filter); - uint8x8_t d1 = - convolve8_8_v(s1234_lo, s5678_lo, s1234_hi, s5678_hi, filter); - uint8x8_t d2 = - convolve8_8_v(s2345_lo, s6789_lo, s2345_hi, s6789_hi, filter); - uint8x8_t d3 = - convolve8_8_v(s3456_lo, s78910_lo, s3456_hi, s78910_hi, filter); - - store_u8_8x4(d, dst_stride, d0, d1, d2, d3); - - // Prepare block for next iteration - re-using as much as possible. - // Shuffle everything up four rows. - s0123_lo = s4567_lo; - s0123_hi = s4567_hi; - s1234_lo = s5678_lo; - s1234_hi = s5678_hi; - s2345_lo = s6789_lo; - s2345_hi = s6789_hi; - s3456_lo = s78910_lo; - s3456_hi = s78910_hi; - - s += 4 * src_stride; - d += 4 * dst_stride; - height -= 4; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); - } -} - -void vpx_convolve8_vert_neon_i8mm(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - assert(y_step_q4 == 16); - - (void)x0_q4; - (void)x_step_q4; - (void)y_step_q4; - - if (vpx_get_filter_taps(filter[y0_q4]) <= 4) { - const int16x8_t y_filter = vld1q_s16(filter[y0_q4]); - - convolve_4tap_vert_neon(src - src_stride, src_stride, dst, dst_stride, w, h, - y_filter); - } else { - const int8x8_t y_filter = vmovn_s16(vld1q_s16(filter[y0_q4])); - - convolve_8tap_vert_neon_i8mm(src - 3 * src_stride, src_stride, dst, - dst_stride, w, h, y_filter); - } -} - -void vpx_convolve8_avg_vert_neon_i8mm(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - const int8x8_t filters = vmovn_s16(vld1q_s16(filter[y0_q4])); - const uint8x16x3_t merge_block_tbl = vld1q_u8_x3(dot_prod_merge_block_tbl); - - assert((intptr_t)dst % 4 == 0); - assert(dst_stride % 4 == 0); - assert(y_step_q4 == 16); - - (void)x0_q4; - (void)x_step_q4; - (void)y_step_q4; - - src -= 3 * src_stride; - - if (w == 4) { - uint8x8_t s0, s1, s2, s3, s4, s5, s6; - load_u8_8x7(src, src_stride, &s0, &s1, &s2, &s3, &s4, &s5, &s6); - src += 7 * src_stride; - - // This operation combines a conventional transpose and the sample permute - // (see horizontal case) required before computing the dot product. - uint8x16_t s0123, s1234, s2345, s3456; - transpose_concat_4x4(s0, s1, s2, s3, &s0123); - transpose_concat_4x4(s1, s2, s3, s4, &s1234); - transpose_concat_4x4(s2, s3, s4, s5, &s2345); - transpose_concat_4x4(s3, s4, s5, s6, &s3456); - - do { - uint8x8_t s7, s8, s9, s10; - load_u8_8x4(src, src_stride, &s7, &s8, &s9, &s10); - - uint8x16_t s78910; - transpose_concat_4x4(s7, s8, s9, s10, &s78910); - - // Merge new data into block from previous iteration. - uint8x16x2_t samples_LUT = { { s3456, s78910 } }; - uint8x16_t s4567 = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[0]); - uint8x16_t s5678 = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[1]); - uint8x16_t s6789 = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[2]); - - int16x4_t d0 = convolve8_4_v(s0123, s4567, filters); - int16x4_t d1 = convolve8_4_v(s1234, s5678, filters); - int16x4_t d2 = convolve8_4_v(s2345, s6789, filters); - int16x4_t d3 = convolve8_4_v(s3456, s78910, filters); - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(d0, d1), FILTER_BITS - 1); - uint8x8_t d23 = vqrshrun_n_s16(vcombine_s16(d2, d3), FILTER_BITS - 1); - - uint8x8_t dd01 = load_u8(dst + 0 * dst_stride, dst_stride); - uint8x8_t dd23 = load_u8(dst + 2 * dst_stride, dst_stride); - - d01 = vrhadd_u8(d01, dd01); - d23 = vrhadd_u8(d23, dd23); - - store_u8(dst + 0 * dst_stride, dst_stride, d01); - store_u8(dst + 2 * dst_stride, dst_stride, d23); - - // Prepare block for next iteration - re-using as much as possible. - // Shuffle everything up four rows. - s0123 = s4567; - s1234 = s5678; - s2345 = s6789; - s3456 = s78910; - - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - do { - const uint8_t *s = src; - uint8_t *d = dst; - int height = h; - - uint8x8_t s0, s1, s2, s3, s4, s5, s6; - load_u8_8x7(s, src_stride, &s0, &s1, &s2, &s3, &s4, &s5, &s6); - s += 7 * src_stride; - - // This operation combines a conventional transpose and the sample permute - // (see horizontal case) required before computing the dot product. - uint8x16_t s0123_lo, s0123_hi, s1234_lo, s1234_hi, s2345_lo, s2345_hi, - s3456_lo, s3456_hi; - transpose_concat_8x4(s0, s1, s2, s3, &s0123_lo, &s0123_hi); - transpose_concat_8x4(s1, s2, s3, s4, &s1234_lo, &s1234_hi); - transpose_concat_8x4(s2, s3, s4, s5, &s2345_lo, &s2345_hi); - transpose_concat_8x4(s3, s4, s5, s6, &s3456_lo, &s3456_hi); - - do { - uint8x8_t s7, s8, s9, s10; - load_u8_8x4(s, src_stride, &s7, &s8, &s9, &s10); - - uint8x16_t s78910_lo, s78910_hi; - transpose_concat_8x4(s7, s8, s9, s10, &s78910_lo, &s78910_hi); - - // Merge new data into block from previous iteration. - uint8x16x2_t samples_LUT = { { s3456_lo, s78910_lo } }; - uint8x16_t s4567_lo = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[0]); - uint8x16_t s5678_lo = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[1]); - uint8x16_t s6789_lo = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[2]); - - samples_LUT.val[0] = s3456_hi; - samples_LUT.val[1] = s78910_hi; - uint8x16_t s4567_hi = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[0]); - uint8x16_t s5678_hi = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[1]); - uint8x16_t s6789_hi = vqtbl2q_u8(samples_LUT, merge_block_tbl.val[2]); - - uint8x8_t d0 = - convolve8_8_v(s0123_lo, s4567_lo, s0123_hi, s4567_hi, filters); - uint8x8_t d1 = - convolve8_8_v(s1234_lo, s5678_lo, s1234_hi, s5678_hi, filters); - uint8x8_t d2 = - convolve8_8_v(s2345_lo, s6789_lo, s2345_hi, s6789_hi, filters); - uint8x8_t d3 = - convolve8_8_v(s3456_lo, s78910_lo, s3456_hi, s78910_hi, filters); - - uint8x8_t dd0, dd1, dd2, dd3; - load_u8_8x4(d, dst_stride, &dd0, &dd1, &dd2, &dd3); - - d0 = vrhadd_u8(d0, dd0); - d1 = vrhadd_u8(d1, dd1); - d2 = vrhadd_u8(d2, dd2); - d3 = vrhadd_u8(d3, dd3); - - store_u8_8x4(d, dst_stride, d0, d1, d2, d3); - - /* Prepare block for next iteration - re-using as much as possible. */ - /* Shuffle everything up four rows. */ - s0123_lo = s4567_lo; - s0123_hi = s4567_hi; - s1234_lo = s5678_lo; - s1234_hi = s5678_hi; - s2345_lo = s6789_lo; - s2345_hi = s6789_hi; - s3456_lo = s78910_lo; - s3456_hi = s78910_hi; - - s += 4 * src_stride; - d += 4 * dst_stride; - height -= 4; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); - } -} - -static INLINE void convolve_4tap_2d_neon_i8mm(const uint8_t *src, - ptrdiff_t src_stride, - uint8_t *dst, - ptrdiff_t dst_stride, int w, - int h, const int8x8_t x_filter, - const uint8x8_t y_filter) { - // Neon does not have lane-referencing multiply or multiply-accumulate - // instructions that operate on vectors of 8-bit elements. This means we have - // to duplicate filter taps into a whole vector and use standard multiply / - // multiply-accumulate instructions. - const uint8x8_t y_filter_taps[4] = { vdup_lane_u8(y_filter, 2), - vdup_lane_u8(y_filter, 3), - vdup_lane_u8(y_filter, 4), - vdup_lane_u8(y_filter, 5) }; - - if (w == 4) { - const uint8x16_t permute_tbl = vld1q_u8(dot_prod_permute_tbl); - - uint8x16_t h_s0, h_s1, h_s2; - load_u8_16x3(src, src_stride, &h_s0, &h_s1, &h_s2); - - int16x4_t t0 = convolve4_4_h(h_s0, x_filter, permute_tbl); - int16x4_t t1 = convolve4_4_h(h_s1, x_filter, permute_tbl); - int16x4_t t2 = convolve4_4_h(h_s2, x_filter, permute_tbl); - // We halved the filter values so -1 from right shift. - uint8x8_t v_s01 = vqrshrun_n_s16(vcombine_s16(t0, t1), FILTER_BITS - 1); - uint8x8_t v_s12 = vqrshrun_n_s16(vcombine_s16(t1, t2), FILTER_BITS - 1); - - src += 3 * src_stride; - - do { - uint8x16_t h_s3, h_s4, h_s5, h_s6; - load_u8_16x4(src, src_stride, &h_s3, &h_s4, &h_s5, &h_s6); - - int16x4_t t3 = convolve4_4_h(h_s3, x_filter, permute_tbl); - int16x4_t t4 = convolve4_4_h(h_s4, x_filter, permute_tbl); - int16x4_t t5 = convolve4_4_h(h_s5, x_filter, permute_tbl); - int16x4_t t6 = convolve4_4_h(h_s6, x_filter, permute_tbl); - // We halved the filter values so -1 from right shift. - uint8x8_t v_s34 = vqrshrun_n_s16(vcombine_s16(t3, t4), FILTER_BITS - 1); - uint8x8_t v_s56 = vqrshrun_n_s16(vcombine_s16(t5, t6), FILTER_BITS - 1); - uint8x8_t v_s23 = vext_u8(v_s12, v_s34, 4); - uint8x8_t v_s45 = vext_u8(v_s34, v_s56, 4); - - uint8x8_t d01 = convolve4_8(v_s01, v_s12, v_s23, v_s34, y_filter_taps); - uint8x8_t d23 = convolve4_8(v_s23, v_s34, v_s45, v_s56, y_filter_taps); - - store_unaligned_u8(dst + 0 * dst_stride, dst_stride, d01); - store_unaligned_u8(dst + 2 * dst_stride, dst_stride, d23); - - v_s01 = v_s45; - v_s12 = v_s56; - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h != 0); - } else { - const uint8x16x2_t permute_tbl = vld1q_u8_x2(dot_prod_permute_tbl); - - do { - const uint8_t *s = src; - uint8_t *d = dst; - int height = h; - - uint8x16_t h_s0, h_s1, h_s2; - load_u8_16x3(s, src_stride, &h_s0, &h_s1, &h_s2); - - uint8x8_t v_s0 = convolve4_8_h(h_s0, x_filter, permute_tbl); - uint8x8_t v_s1 = convolve4_8_h(h_s1, x_filter, permute_tbl); - uint8x8_t v_s2 = convolve4_8_h(h_s2, x_filter, permute_tbl); - - s += 3 * src_stride; - - do { - uint8x16_t h_s3, h_s4, h_s5, h_s6; - load_u8_16x4(s, src_stride, &h_s3, &h_s4, &h_s5, &h_s6); - - uint8x8_t v_s3 = convolve4_8_h(h_s3, x_filter, permute_tbl); - uint8x8_t v_s4 = convolve4_8_h(h_s4, x_filter, permute_tbl); - uint8x8_t v_s5 = convolve4_8_h(h_s5, x_filter, permute_tbl); - uint8x8_t v_s6 = convolve4_8_h(h_s6, x_filter, permute_tbl); - - uint8x8_t d0 = convolve4_8(v_s0, v_s1, v_s2, v_s3, y_filter_taps); - uint8x8_t d1 = convolve4_8(v_s1, v_s2, v_s3, v_s4, y_filter_taps); - uint8x8_t d2 = convolve4_8(v_s2, v_s3, v_s4, v_s5, y_filter_taps); - uint8x8_t d3 = convolve4_8(v_s3, v_s4, v_s5, v_s6, y_filter_taps); - - store_u8_8x4(d, dst_stride, d0, d1, d2, d3); - - v_s0 = v_s4; - v_s1 = v_s5; - v_s2 = v_s6; - s += 4 * src_stride; - d += 4 * dst_stride; - height -= 4; - } while (height != 0); - src += 8; - dst += 8; - w -= 8; - } while (w != 0); - } -} - -static INLINE void convolve_8tap_2d_horiz_neon_i8mm( - const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, int w, int h, const int8x8_t filter) { - if (w == 4) { - const uint8x16x2_t permute_tbl = vld1q_u8_x2(dot_prod_permute_tbl); - - do { - uint8x16_t s0, s1, s2, s3; - load_u8_16x4(src, src_stride, &s0, &s1, &s2, &s3); - - int16x4_t d0 = convolve8_4_h(s0, filter, permute_tbl); - int16x4_t d1 = convolve8_4_h(s1, filter, permute_tbl); - int16x4_t d2 = convolve8_4_h(s2, filter, permute_tbl); - int16x4_t d3 = convolve8_4_h(s3, filter, permute_tbl); - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(d0, d1), FILTER_BITS - 1); - uint8x8_t d23 = vqrshrun_n_s16(vcombine_s16(d2, d3), FILTER_BITS - 1); - - store_u8(dst + 0 * dst_stride, dst_stride, d01); - store_u8(dst + 2 * dst_stride, dst_stride, d23); - - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h > 3); - - // Process final three rows (h % 4 == 3). See vpx_convolve_neon_i8mm() - // below for further details on possible values of block height. - uint8x16_t s0, s1, s2; - load_u8_16x3(src, src_stride, &s0, &s1, &s2); - - int16x4_t d0 = convolve8_4_h(s0, filter, permute_tbl); - int16x4_t d1 = convolve8_4_h(s1, filter, permute_tbl); - int16x4_t d2 = convolve8_4_h(s2, filter, permute_tbl); - uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(d0, d1), FILTER_BITS - 1); - uint8x8_t d23 = - vqrshrun_n_s16(vcombine_s16(d2, vdup_n_s16(0)), FILTER_BITS - 1); - - store_u8(dst + 0 * dst_stride, dst_stride, d01); - store_u8_4x1(dst + 2 * dst_stride, d23); - } else { - const uint8x16x3_t permute_tbl = vld1q_u8_x3(dot_prod_permute_tbl); - - do { - const uint8_t *s = src; - uint8_t *d = dst; - int width = w; - - do { - uint8x16_t s0, s1, s2, s3; - load_u8_16x4(s, src_stride, &s0, &s1, &s2, &s3); - - uint8x8_t d0 = convolve8_8_h(s0, filter, permute_tbl); - uint8x8_t d1 = convolve8_8_h(s1, filter, permute_tbl); - uint8x8_t d2 = convolve8_8_h(s2, filter, permute_tbl); - uint8x8_t d3 = convolve8_8_h(s3, filter, permute_tbl); - - store_u8_8x4(d, dst_stride, d0, d1, d2, d3); - - s += 8; - d += 8; - width -= 8; - } while (width > 0); - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h > 3); - - // Process final three rows (h % 4 == 3). See vpx_convolve_neon_i8mm() - // below for further details on possible values of block height. - const uint8_t *s = src; - uint8_t *d = dst; - int width = w; - - do { - uint8x16_t s0, s1, s2; - load_u8_16x3(s, src_stride, &s0, &s1, &s2); - - uint8x8_t d0 = convolve8_8_h(s0, filter, permute_tbl); - uint8x8_t d1 = convolve8_8_h(s1, filter, permute_tbl); - uint8x8_t d2 = convolve8_8_h(s2, filter, permute_tbl); - - store_u8_8x3(d, dst_stride, d0, d1, d2); - - s += 8; - d += 8; - width -= 8; - } while (width > 0); - } -} - -void vpx_convolve8_neon_i8mm(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - assert(x_step_q4 == 16); - assert(y_step_q4 == 16); - - (void)x_step_q4; - (void)y_step_q4; - - const int x_filter_taps = vpx_get_filter_taps(filter[x0_q4]) <= 4 ? 4 : 8; - const int y_filter_taps = vpx_get_filter_taps(filter[y0_q4]) <= 4 ? 4 : 8; - // Account for needing filter_taps / 2 - 1 lines prior and filter_taps / 2 - // lines post both horizontally and vertically. - const ptrdiff_t horiz_offset = x_filter_taps / 2 - 1; - const ptrdiff_t vert_offset = (y_filter_taps / 2 - 1) * src_stride; - - if (x_filter_taps == 4 && y_filter_taps == 4) { - const int16x4_t x_filter = vld1_s16(filter[x0_q4] + 2); - const int16x8_t y_filter = vld1q_s16(filter[y0_q4]); - - // 4-tap and bilinear filter values are even, so halve them to reduce - // intermediate precision requirements. - const int8x8_t x_filter_4tap = - vshrn_n_s16(vcombine_s16(x_filter, vdup_n_s16(0)), 1); - const uint8x8_t y_filter_4tap = - vshrn_n_u16(vreinterpretq_u16_s16(vabsq_s16(y_filter)), 1); - - convolve_4tap_2d_neon_i8mm(src - horiz_offset - vert_offset, src_stride, - dst, dst_stride, w, h, x_filter_4tap, - y_filter_4tap); - return; - } - - // Given our constraints: w <= 64, h <= 64, taps <= 8 we can reduce the - // maximum buffer size to 64 * (64 + 7). - DECLARE_ALIGNED(32, uint8_t, im_block[64 * 71]); - const int im_stride = 64; - const int im_height = h + SUBPEL_TAPS - 1; - - const int8x8_t x_filter_8tap = vmovn_s16(vld1q_s16(filter[x0_q4])); - const int8x8_t y_filter_8tap = vmovn_s16(vld1q_s16(filter[y0_q4])); - - convolve_8tap_2d_horiz_neon_i8mm(src - horiz_offset - vert_offset, src_stride, - im_block, im_stride, w, im_height, - x_filter_8tap); - - convolve_8tap_vert_neon_i8mm(im_block, im_stride, dst, dst_stride, w, h, - y_filter_8tap); -} - -void vpx_convolve8_avg_neon_i8mm(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - DECLARE_ALIGNED(32, uint8_t, im_block[64 * 71]); - const int im_stride = 64; - - // Averaging convolution always uses an 8-tap filter. - // Account for the vertical phase needing 3 lines prior and 4 lines post. - const int im_height = h + SUBPEL_TAPS - 1; - const ptrdiff_t offset = SUBPEL_TAPS / 2 - 1; - - assert(y_step_q4 == 16); - assert(x_step_q4 == 16); - - const int8x8_t x_filter_8tap = vmovn_s16(vld1q_s16(filter[x0_q4])); - - convolve_8tap_2d_horiz_neon_i8mm(src - offset - offset * src_stride, - src_stride, im_block, im_stride, w, - im_height, x_filter_8tap); - - vpx_convolve8_avg_vert_neon_i8mm(im_block + offset * im_stride, im_stride, - dst, dst_stride, filter, x0_q4, x_step_q4, - y0_q4, y_step_q4, w, h); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_vert_filter_type1_neon.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_vert_filter_type1_neon.asm deleted file mode 100644 index 2666d425..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_vert_filter_type1_neon.asm +++ /dev/null @@ -1,457 +0,0 @@ -; -; Copyright (c) 2018 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; -;**************Variables Vs Registers*********************************** -; r0 => src -; r1 => dst -; r2 => src_stride -; r6 => dst_stride -; r12 => filter_y0 -; r5 => ht -; r3 => wd - - EXPORT |vpx_convolve8_vert_filter_type1_neon| - ARM - REQUIRE8 - PRESERVE8 - - AREA ||.text||, CODE, READONLY, ALIGN=2 - -|vpx_convolve8_vert_filter_type1_neon| PROC - - stmfd sp!, {r4 - r12, r14} ;stack stores the values of - ; the arguments - vpush {d8 - d15} ; stack offset by 64 - mov r4, r1 - mov r1, r2 - mov r2, r4 - vmov.i16 q15, #0x4000 - mov r11, #0xc000 - ldr r12, [sp, #104] ;load filter - ldr r6, [sp, #116] ;load y0_q4 - add r12, r12, r6, lsl #4 ;r12 = filter[y0_q4] - mov r6, r3 - ldr r5, [sp, #124] ;load wd - vld2.8 {d0, d1}, [r12] ;coeff = vld1_s8(pi1_coeff) - sub r12, r2, r2, lsl #2 ;src_ctrd & pi1_coeff - vabs.s8 d0, d0 ;vabs_s8(coeff) - add r0, r0, r12 ;r0->pu1_src r12->pi1_coeff - ldr r3, [sp, #128] ;load ht - subs r7, r3, #0 ;r3->ht - vdup.u8 d22, d0[0] ;coeffabs_0 = vdup_lane_u8(coeffabs, - ; 0); - cmp r5, #8 - vdup.u8 d23, d0[1] ;coeffabs_1 = vdup_lane_u8(coeffabs, - ; 1); - vdup.u8 d24, d0[2] ;coeffabs_2 = vdup_lane_u8(coeffabs, - ; 2); - vdup.u8 d25, d0[3] ;coeffabs_3 = vdup_lane_u8(coeffabs, - ; 3); - vdup.u8 d26, d0[4] ;coeffabs_4 = vdup_lane_u8(coeffabs, - ; 4); - vdup.u8 d27, d0[5] ;coeffabs_5 = vdup_lane_u8(coeffabs, - ; 5); - vdup.u8 d28, d0[6] ;coeffabs_6 = vdup_lane_u8(coeffabs, - ; 6); - vdup.u8 d29, d0[7] ;coeffabs_7 = vdup_lane_u8(coeffabs, - ; 7); - blt core_loop_wd_4 ;core loop wd 4 jump - - str r0, [sp, #-4]! - str r1, [sp, #-4]! - bic r4, r5, #7 ;r5 ->wd - rsb r9, r4, r6, lsl #2 ;r6->dst_strd r5 ->wd - rsb r8, r4, r2, lsl #2 ;r2->src_strd - mov r3, r5, lsr #3 ;divide by 8 - mul r7, r3 ;multiply height by width - sub r7, #4 ;subtract by one for epilog - -prolog - and r10, r0, #31 - add r3, r0, r2 ;pu1_src_tmp += src_strd; - vdup.16 q4, r11 - vld1.u8 {d1}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vld1.u8 {d0}, [r0]! ;src_tmp1 = vld1_u8(pu1_src_tmp); - subs r4, r4, #8 - vld1.u8 {d2}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d1, d23 ;mul_res1 = vmull_u8(src_tmp2, - ; coeffabs_1); - vld1.u8 {d3}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d0, d22 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp1, coeffabs_0); - vld1.u8 {d4}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d2, d24 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp3, coeffabs_2); - vld1.u8 {d5}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d3, d25 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp4, coeffabs_3); - vld1.u8 {d6}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d4, d26 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp1, coeffabs_4); - vld1.u8 {d7}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d5, d27 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp2, coeffabs_5); - vld1.u8 {d16}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d6, d28 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp3, coeffabs_6); - vld1.u8 {d17}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d7, d29 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp4, coeffabs_7); - vdup.16 q5, r11 - vld1.u8 {d18}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q5, d2, d23 ;mul_res2 = vmull_u8(src_tmp3, - ; coeffabs_1); - addle r0, r0, r8 - vmlsl.u8 q5, d1, d22 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp2, coeffabs_0); - bicle r4, r5, #7 ;r5 ->wd - vmlal.u8 q5, d3, d24 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp4, coeffabs_2); - pld [r3] - vmlal.u8 q5, d4, d25 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp1, coeffabs_3); - vhadd.s16 q4, q4, q15 - vdup.16 q6, r11 - pld [r3, r2] - vmlal.u8 q5, d5, d26 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp2, coeffabs_4); - pld [r3, r2, lsl #1] - vmlal.u8 q5, d6, d27 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp3, coeffabs_5); - add r3, r3, r2 - vmlsl.u8 q5, d7, d28 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp4, coeffabs_6); - pld [r3, r2, lsl #1] - vmlsl.u8 q5, d16, d29 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp1, coeffabs_7); - add r3, r0, r2 ;pu1_src_tmp += src_strd; - vqrshrun.s16 d8, q4, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vld1.u8 {d1}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q6, d3, d23 - vld1.u8 {d0}, [r0]! ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q6, d2, d22 - vld1.u8 {d2}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q6, d4, d24 - vhadd.s16 q5, q5, q15 - vdup.16 q7, r11 - vmlal.u8 q6, d5, d25 - vmlal.u8 q6, d6, d26 - vmlal.u8 q6, d7, d27 - vmlsl.u8 q6, d16, d28 - vmlsl.u8 q6, d17, d29 - add r14, r1, r6 - vst1.8 {d8}, [r1]! ;vst1_u8(pu1_dst,sto_res); - vqrshrun.s16 d10, q5, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - addle r1, r1, r9 - vmlsl.u8 q7, d4, d23 - subs r7, r7, #4 - vmlsl.u8 q7, d3, d22 - vmlal.u8 q7, d5, d24 - vmlal.u8 q7, d6, d25 - vld1.u8 {d3}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vhadd.s16 q6, q6, q15 - vdup.16 q4, r11 - vmlal.u8 q7, d7, d26 - vld1.u8 {d4}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlal.u8 q7, d16, d27 - vld1.u8 {d5}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d17, d28 - vld1.u8 {d6}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d18, d29 - vld1.u8 {d7}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vst1.8 {d10}, [r14], r6 ;vst1_u8(pu1_dst_tmp,sto_res); - vqrshrun.s16 d12, q6, #6 - blt epilog_end ;jumps to epilog_end - - beq epilog ;jumps to epilog - -main_loop_8 - subs r4, r4, #8 - vmlsl.u8 q4, d1, d23 ;mul_res1 = vmull_u8(src_tmp2, - ; coeffabs_1); - addle r0, r0, r8 - vmlsl.u8 q4, d0, d22 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp1, coeffabs_0); - bicle r4, r5, #7 ;r5 ->wd - vmlal.u8 q4, d2, d24 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp3, coeffabs_2); - vld1.u8 {d16}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d3, d25 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp4, coeffabs_3); - vhadd.s16 q7, q7, q15 - vdup.16 q5, r11 - vld1.u8 {d17}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d4, d26 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp1, coeffabs_4); - vld1.u8 {d18}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d5, d27 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp2, coeffabs_5); - vmlsl.u8 q4, d6, d28 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp3, coeffabs_6); - vmlsl.u8 q4, d7, d29 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp4, coeffabs_7); - vst1.8 {d12}, [r14], r6 - vqrshrun.s16 d14, q7, #6 - add r3, r0, r2 ;pu1_src_tmp += src_strd; - vmlsl.u8 q5, d2, d23 ;mul_res2 = vmull_u8(src_tmp3, - ; coeffabs_1); - vld1.u8 {d0}, [r0]! ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q5, d1, d22 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp2, coeffabs_0); - vmlal.u8 q5, d3, d24 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp4, coeffabs_2); - vld1.u8 {d1}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q5, d4, d25 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp1, coeffabs_3); - vhadd.s16 q4, q4, q15 - vdup.16 q6, r11 - vst1.8 {d14}, [r14], r6 - vmlal.u8 q5, d5, d26 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp2, coeffabs_4); - add r14, r1, #0 - vmlal.u8 q5, d6, d27 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp3, coeffabs_5); - add r1, r1, #8 - vmlsl.u8 q5, d7, d28 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp4, coeffabs_6); - vmlsl.u8 q5, d16, d29 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp1, coeffabs_7); - addle r1, r1, r9 - vqrshrun.s16 d8, q4, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vmlsl.u8 q6, d3, d23 - add r10, r3, r2, lsl #3 ; 10*strd - 8+2 - vmlsl.u8 q6, d2, d22 - add r10, r10, r2 ; 11*strd - vmlal.u8 q6, d4, d24 - vld1.u8 {d2}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q6, d5, d25 - vhadd.s16 q5, q5, q15 - vdup.16 q7, r11 - vmlal.u8 q6, d6, d26 - vst1.8 {d8}, [r14], r6 ;vst1_u8(pu1_dst,sto_res); - pld [r10] ;11+ 0 - vmlal.u8 q6, d7, d27 - pld [r10, r2] ;11+ 1*strd - vmlsl.u8 q6, d16, d28 - pld [r10, r2, lsl #1] ;11+ 2*strd - vmlsl.u8 q6, d17, d29 - add r10, r10, r2 ;12*strd - vqrshrun.s16 d10, q5, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - pld [r10, r2, lsl #1] ;11+ 3*strd - vmlsl.u8 q7, d4, d23 - vmlsl.u8 q7, d3, d22 - subs r7, r7, #4 - vmlal.u8 q7, d5, d24 - vmlal.u8 q7, d6, d25 - vld1.u8 {d3}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vhadd.s16 q6, q6, q15 - vdup.16 q4, r11 - vmlal.u8 q7, d7, d26 - vld1.u8 {d4}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlal.u8 q7, d16, d27 - vld1.u8 {d5}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d17, d28 - vld1.u8 {d6}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d18, d29 - vld1.u8 {d7}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vqrshrun.s16 d12, q6, #6 - vst1.8 {d10}, [r14], r6 ;vst1_u8(pu1_dst_tmp,sto_res); - bgt main_loop_8 ;jumps to main_loop_8 - -epilog - vmlsl.u8 q4, d1, d23 ;mul_res1 = vmull_u8(src_tmp2, - ; coeffabs_1); - vmlsl.u8 q4, d0, d22 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp1, coeffabs_0); - vmlal.u8 q4, d2, d24 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp3, coeffabs_2); - vmlal.u8 q4, d3, d25 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp4, coeffabs_3); - vhadd.s16 q7, q7, q15 - vdup.16 q5, r11 - vmlal.u8 q4, d4, d26 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp1, coeffabs_4); - vmlal.u8 q4, d5, d27 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp2, coeffabs_5); - vmlsl.u8 q4, d6, d28 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp3, coeffabs_6); - vmlsl.u8 q4, d7, d29 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp4, coeffabs_7); - vst1.8 {d12}, [r14], r6 - vqrshrun.s16 d14, q7, #6 - vld1.u8 {d16}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q5, d2, d23 ;mul_res2 = vmull_u8(src_tmp3, - ; coeffabs_1); - vmlsl.u8 q5, d1, d22 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp2, coeffabs_0); - vmlal.u8 q5, d3, d24 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp4, coeffabs_2); - vmlal.u8 q5, d4, d25 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp1, coeffabs_3); - vhadd.s16 q4, q4, q15 - vdup.16 q6, r11 - vmlal.u8 q5, d5, d26 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp2, coeffabs_4); - vmlal.u8 q5, d6, d27 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp3, coeffabs_5); - vmlsl.u8 q5, d7, d28 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp4, coeffabs_6); - vmlsl.u8 q5, d16, d29 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp1, coeffabs_7); - vst1.8 {d14}, [r14], r6 - vqrshrun.s16 d8, q4, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vld1.u8 {d17}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q6, d3, d23 - vmlsl.u8 q6, d2, d22 - vmlal.u8 q6, d4, d24 - vmlal.u8 q6, d5, d25 - vhadd.s16 q5, q5, q15 - vdup.16 q7, r11 - vmlal.u8 q6, d6, d26 - vmlal.u8 q6, d7, d27 - vmlsl.u8 q6, d16, d28 - vmlsl.u8 q6, d17, d29 - add r14, r1, r6 - vst1.8 {d8}, [r1]! ;vst1_u8(pu1_dst,sto_res); - vqrshrun.s16 d10, q5, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vld1.u8 {d18}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d4, d23 - vmlsl.u8 q7, d3, d22 - vmlal.u8 q7, d5, d24 - vmlal.u8 q7, d6, d25 - vhadd.s16 q6, q6, q15 - vmlal.u8 q7, d7, d26 - vmlal.u8 q7, d16, d27 - vmlsl.u8 q7, d17, d28 - vmlsl.u8 q7, d18, d29 - vst1.8 {d10}, [r14], r6 ;vst1_u8(pu1_dst_tmp,sto_res); - vqrshrun.s16 d12, q6, #6 - -epilog_end - vst1.8 {d12}, [r14], r6 - vhadd.s16 q7, q7, q15 - vqrshrun.s16 d14, q7, #6 - vst1.8 {d14}, [r14], r6 - -end_loops - tst r5, #7 - ldr r1, [sp], #4 - ldr r0, [sp], #4 - vpopeq {d8 - d15} - ldmfdeq sp!, {r4 - r12, r15} ;reload the registers from - ; sp - mov r5, #4 - add r0, r0, #8 - add r1, r1, #8 - mov r7, #16 - -core_loop_wd_4 - rsb r9, r5, r6, lsl #2 ;r6->dst_strd r5 ->wd - rsb r8, r5, r2, lsl #2 ;r2->src_strd - vmov.i8 d4, #0 - -outer_loop_wd_4 - subs r12, r5, #0 - ble end_inner_loop_wd_4 ;outer loop jump - -inner_loop_wd_4 - add r3, r0, r2 - vld1.u32 {d4[1]},[r3], r2 ;src_tmp1 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp1, 1); - subs r12, r12, #4 - vdup.u32 d5, d4[1] ;src_tmp2 = vdup_lane_u32(src_tmp1, - ; 1); - vld1.u32 {d5[1]},[r3], r2 ;src_tmp2 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp2, 1); - vld1.u32 {d4[0]},[r0] ;src_tmp1 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp1, 0); - vdup.16 q0, r11 - vmlsl.u8 q0, d5, d23 ;mul_res1 = - ; vmull_u8(vreinterpret_u8_u32(src_tmp2), coeffabs_1); - - vdup.u32 d6, d5[1] ;src_tmp3 = vdup_lane_u32(src_tmp2, - ; 1); - add r0, r0, #4 - vld1.u32 {d6[1]},[r3], r2 ;src_tmp3 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp3, 1); - vmlsl.u8 q0, d4, d22 ;mul_res1 = vmlsl_u8(mul_res1, - ; vreinterpret_u8_u32(src_tmp1), coeffabs_0); - vdup.u32 d7, d6[1] ;src_tmp4 = vdup_lane_u32(src_tmp3, - ; 1); - vld1.u32 {d7[1]},[r3], r2 ;src_tmp4 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp4, 1); - vmlal.u8 q0, d6, d24 ;mul_res1 = vmlsl_u8(mul_res1, - ; vreinterpret_u8_u32(src_tmp3), coeffabs_2); - vdup.16 q4, r11 - vmlsl.u8 q4, d7, d23 - vdup.u32 d4, d7[1] ;src_tmp1 = vdup_lane_u32(src_tmp4, - ; 1); - vmull.u8 q1, d7, d25 ;mul_res2 = - ; vmull_u8(vreinterpret_u8_u32(src_tmp4), coeffabs_3); - vld1.u32 {d4[1]},[r3], r2 ;src_tmp1 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp1, 1); - vmlsl.u8 q4, d6, d22 - vmlal.u8 q0, d4, d26 ;mul_res1 = vmlal_u8(mul_res1, - ; vreinterpret_u8_u32(src_tmp1), coeffabs_4); - vdup.u32 d5, d4[1] ;src_tmp2 = vdup_lane_u32(src_tmp1, - ; 1); - vmlal.u8 q4, d4, d24 - vld1.u32 {d5[1]},[r3], r2 ;src_tmp2 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp2, 1); - vmlal.u8 q1, d5, d27 ;mul_res2 = vmlsl_u8(mul_res2, - ; vreinterpret_u8_u32(src_tmp2), coeffabs_5); - vdup.u32 d6, d5[1] ;src_tmp3 = vdup_lane_u32(src_tmp2, - ; 1); - vmlal.u8 q4, d5, d25 - vld1.u32 {d6[1]},[r3], r2 ;src_tmp3 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp3, 1); - vmlsl.u8 q0, d6, d28 ;mul_res1 = vmlal_u8(mul_res1, - ; vreinterpret_u8_u32(src_tmp3), coeffabs_6); - vdup.u32 d7, d6[1] ;src_tmp4 = vdup_lane_u32(src_tmp3, - ; 1); - vmlal.u8 q4, d6, d26 - vld1.u32 {d7[1]},[r3], r2 ;src_tmp4 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp4, 1); - vmlsl.u8 q1, d7, d29 ;mul_res2 = vmlsl_u8(mul_res2, - ; vreinterpret_u8_u32(src_tmp4), coeffabs_7); - vdup.u32 d4, d7[1] - vadd.i16 q0, q0, q1 ;mul_res1 = vaddq_u16(mul_res1, - ; mul_res2); - vmlal.u8 q4, d7, d27 - vld1.u32 {d4[1]},[r3], r2 - vmlsl.u8 q4, d4, d28 - vdup.u32 d5, d4[1] - vhadd.s16 q0, q0, q15 - vqrshrun.s16 d0, q0, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vld1.u32 {d5[1]},[r3] - add r3, r1, r6 - vst1.32 {d0[0]},[r1] ;vst1_lane_u32((uint32_t *)pu1_dst, - ; vreinterpret_u32_u8(sto_res), 0); - vmlsl.u8 q4, d5, d29 - vst1.32 {d0[1]},[r3], r6 ;vst1_lane_u32((uint32_t - ; *)pu1_dst_tmp, vreinterpret_u32_u8(sto_res), 1); - vhadd.s16 q4, q4, q15 - vqrshrun.s16 d8, q4, #6 - vst1.32 {d8[0]},[r3], r6 - add r1, r1, #4 - vst1.32 {d8[1]},[r3] - bgt inner_loop_wd_4 - -end_inner_loop_wd_4 - subs r7, r7, #4 - add r1, r1, r9 - add r0, r0, r8 - bgt outer_loop_wd_4 - - vpop {d8 - d15} - ldmfd sp!, {r4 - r12, r15} ;reload the registers from sp - - ENDP - - END diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_vert_filter_type2_neon.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_vert_filter_type2_neon.asm deleted file mode 100644 index cb5d6d3f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve8_vert_filter_type2_neon.asm +++ /dev/null @@ -1,455 +0,0 @@ -; -; Copyright (c) 2018 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; -;**************Variables Vs Registers*********************************** -; r0 => src -; r1 => dst -; r2 => src_stride -; r6 => dst_stride -; r12 => filter_y0 -; r5 => ht -; r3 => wd - - EXPORT |vpx_convolve8_vert_filter_type2_neon| - ARM - REQUIRE8 - PRESERVE8 - - AREA ||.text||, CODE, READONLY, ALIGN=2 - -|vpx_convolve8_vert_filter_type2_neon| PROC - - stmfd sp!, {r4 - r12, r14} ;stack stores the values of - ; the arguments - vpush {d8 - d15} ; stack offset by 64 - mov r4, r1 - mov r1, r2 - mov r2, r4 - vmov.i16 q15, #0x4000 - mov r11, #0xc000 - ldr r12, [sp, #104] ;load filter - ldr r6, [sp, #116] ;load y0_q4 - add r12, r12, r6, lsl #4 ;r12 = filter[y0_q4] - mov r6, r3 - ldr r5, [sp, #124] ;load wd - vld2.8 {d0, d1}, [r12] ;coeff = vld1_s8(pi1_coeff) - sub r12, r2, r2, lsl #2 ;src_ctrd & pi1_coeff - vabs.s8 d0, d0 ;vabs_s8(coeff) - add r0, r0, r12 ;r0->pu1_src r12->pi1_coeff - ldr r3, [sp, #128] ;load ht - subs r7, r3, #0 ;r3->ht - vdup.u8 d22, d0[0] ;coeffabs_0 = vdup_lane_u8(coeffabs, - ; 0); - cmp r5, #8 - vdup.u8 d23, d0[1] ;coeffabs_1 = vdup_lane_u8(coeffabs, - ; 1); - vdup.u8 d24, d0[2] ;coeffabs_2 = vdup_lane_u8(coeffabs, - ; 2); - vdup.u8 d25, d0[3] ;coeffabs_3 = vdup_lane_u8(coeffabs, - ; 3); - vdup.u8 d26, d0[4] ;coeffabs_4 = vdup_lane_u8(coeffabs, - ; 4); - vdup.u8 d27, d0[5] ;coeffabs_5 = vdup_lane_u8(coeffabs, - ; 5); - vdup.u8 d28, d0[6] ;coeffabs_6 = vdup_lane_u8(coeffabs, - ; 6); - vdup.u8 d29, d0[7] ;coeffabs_7 = vdup_lane_u8(coeffabs, - ; 7); - blt core_loop_wd_4 ;core loop wd 4 jump - - str r0, [sp, #-4]! - str r1, [sp, #-4]! - bic r4, r5, #7 ;r5 ->wd - rsb r9, r4, r6, lsl #2 ;r6->dst_strd r5 ->wd - rsb r8, r4, r2, lsl #2 ;r2->src_strd - mov r3, r5, lsr #3 ;divide by 8 - mul r7, r3 ;multiply height by width - sub r7, #4 ;subtract by one for epilog - -prolog - and r10, r0, #31 - add r3, r0, r2 ;pu1_src_tmp += src_strd; - vdup.16 q4, r11 - vld1.u8 {d1}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vld1.u8 {d0}, [r0]! ;src_tmp1 = vld1_u8(pu1_src_tmp); - subs r4, r4, #8 - vld1.u8 {d2}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d1, d23 ;mul_res1 = vmull_u8(src_tmp2, - ; coeffabs_1); - vld1.u8 {d3}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d0, d22 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp1, coeffabs_0); - vld1.u8 {d4}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d2, d24 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp3, coeffabs_2); - vld1.u8 {d5}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d3, d25 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp4, coeffabs_3); - vld1.u8 {d6}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d4, d26 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp1, coeffabs_4); - vld1.u8 {d7}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d5, d27 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp2, coeffabs_5); - vld1.u8 {d16}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d6, d28 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp3, coeffabs_6); - vld1.u8 {d17}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d7, d29 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp4, coeffabs_7); - vdup.16 q5, r11 - vld1.u8 {d18}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q5, d2, d23 ;mul_res2 = vmull_u8(src_tmp3, - ; coeffabs_1); - addle r0, r0, r8 - vmlsl.u8 q5, d1, d22 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp2, coeffabs_0); - bicle r4, r5, #7 ;r5 ->wd - vmlsl.u8 q5, d3, d24 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp4, coeffabs_2); - pld [r3] - vmlal.u8 q5, d4, d25 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp1, coeffabs_3); - vhadd.s16 q4, q4, q15 - vdup.16 q6, r11 - pld [r3, r2] - vmlal.u8 q5, d5, d26 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp2, coeffabs_4); - pld [r3, r2, lsl #1] - vmlsl.u8 q5, d6, d27 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp3, coeffabs_5); - add r3, r3, r2 - vmlal.u8 q5, d7, d28 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp4, coeffabs_6); - pld [r3, r2, lsl #1] - vmlsl.u8 q5, d16, d29 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp1, coeffabs_7); - add r3, r0, r2 ;pu1_src_tmp += src_strd; - vqrshrun.s16 d8, q4, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - - vld1.u8 {d1}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q6, d3, d23 - vld1.u8 {d0}, [r0]! ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q6, d2, d22 - vld1.u8 {d2}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q6, d4, d24 - vhadd.s16 q5, q5, q15 - vdup.16 q7, r11 - vmlal.u8 q6, d5, d25 - vmlal.u8 q6, d6, d26 - vmlsl.u8 q6, d7, d27 - vmlal.u8 q6, d16, d28 - vmlsl.u8 q6, d17, d29 - add r14, r1, r6 - vst1.8 {d8}, [r1]! ;vst1_u8(pu1_dst,sto_res); - vqrshrun.s16 d10, q5, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - addle r1, r1, r9 - vmlal.u8 q7, d4, d23 - subs r7, r7, #4 - vmlsl.u8 q7, d3, d22 - vmlsl.u8 q7, d5, d24 - vmlal.u8 q7, d6, d25 - vld1.u8 {d3}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vhadd.s16 q6, q6, q15 - vdup.16 q4, r11 - vmlal.u8 q7, d7, d26 - vld1.u8 {d4}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d16, d27 - vld1.u8 {d5}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q7, d17, d28 - vld1.u8 {d6}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d18, d29 - vld1.u8 {d7}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vst1.8 {d10}, [r14], r6 ;vst1_u8(pu1_dst_tmp,sto_res); - vqrshrun.s16 d12, q6, #6 - blt epilog_end ;jumps to epilog_end - - beq epilog ;jumps to epilog - -main_loop_8 - subs r4, r4, #8 - vmlal.u8 q4, d1, d23 ;mul_res1 = vmull_u8(src_tmp2, - ; coeffabs_1); - addle r0, r0, r8 - vmlsl.u8 q4, d0, d22 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp1, coeffabs_0); - bicle r4, r5, #7 ;r5 ->wd - vmlsl.u8 q4, d2, d24 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp3, coeffabs_2); - vld1.u8 {d16}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d3, d25 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp4, coeffabs_3); - vhadd.s16 q7, q7, q15 - vdup.16 q5, r11 - vld1.u8 {d17}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q4, d4, d26 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp1, coeffabs_4); - vld1.u8 {d18}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q4, d5, d27 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp2, coeffabs_5); - vmlal.u8 q4, d6, d28 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp3, coeffabs_6); - vmlsl.u8 q4, d7, d29 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp4, coeffabs_7); - vst1.8 {d12}, [r14], r6 - vqrshrun.s16 d14, q7, #6 - add r3, r0, r2 ;pu1_src_tmp += src_strd; - vmlal.u8 q5, d2, d23 ;mul_res2 = vmull_u8(src_tmp3, - ; coeffabs_1); - vld1.u8 {d0}, [r0]! ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q5, d1, d22 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp2, coeffabs_0); - vmlsl.u8 q5, d3, d24 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp4, coeffabs_2); - vld1.u8 {d1}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q5, d4, d25 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp1, coeffabs_3); - vhadd.s16 q4, q4, q15 - vdup.16 q6, r11 - vst1.8 {d14}, [r14], r6 - vmlal.u8 q5, d5, d26 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp2, coeffabs_4); - add r14, r1, #0 - vmlsl.u8 q5, d6, d27 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp3, coeffabs_5); - add r1, r1, #8 - vmlal.u8 q5, d7, d28 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp4, coeffabs_6); - vmlsl.u8 q5, d16, d29 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp1, coeffabs_7); - addle r1, r1, r9 - vqrshrun.s16 d8, q4, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vmlal.u8 q6, d3, d23 - add r10, r3, r2, lsl #3 ; 10*strd - 8+2 - vmlsl.u8 q6, d2, d22 - add r10, r10, r2 ; 11*strd - vmlsl.u8 q6, d4, d24 - vld1.u8 {d2}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q6, d5, d25 - vhadd.s16 q5, q5, q15 - vdup.16 q7, r11 - vmlal.u8 q6, d6, d26 - vst1.8 {d8}, [r14], r6 ;vst1_u8(pu1_dst,sto_res); - pld [r10] ;11+ 0 - vmlsl.u8 q6, d7, d27 - pld [r10, r2] ;11+ 1*strd - vmlal.u8 q6, d16, d28 - pld [r10, r2, lsl #1] ;11+ 2*strd - vmlsl.u8 q6, d17, d29 - add r10, r10, r2 ;12*strd - vqrshrun.s16 d10, q5, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - pld [r10, r2, lsl #1] ;11+ 3*strd - vmlal.u8 q7, d4, d23 - vmlsl.u8 q7, d3, d22 - subs r7, r7, #4 - vmlsl.u8 q7, d5, d24 - vmlal.u8 q7, d6, d25 - vld1.u8 {d3}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vhadd.s16 q6, q6, q15 - vdup.16 q4, r11 - vmlal.u8 q7, d7, d26 - vld1.u8 {d4}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d16, d27 - vld1.u8 {d5}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q7, d17, d28 - vld1.u8 {d6}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlsl.u8 q7, d18, d29 - vld1.u8 {d7}, [r3], r2 ;src_tmp4 = vld1_u8(pu1_src_tmp); - vqrshrun.s16 d12, q6, #6 - vst1.8 {d10}, [r14], r6 ;vst1_u8(pu1_dst_tmp,sto_res); - bgt main_loop_8 ;jumps to main_loop_8 - -epilog - vmlal.u8 q4, d1, d23 ;mul_res1 = vmull_u8(src_tmp2, - vmlsl.u8 q4, d0, d22 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp1, coeffabs_0); - vmlsl.u8 q4, d2, d24 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp3, coeffabs_2); - vmlal.u8 q4, d3, d25 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp4, coeffabs_3); - vhadd.s16 q7, q7, q15 - vdup.16 q5, r11 - vmlal.u8 q4, d4, d26 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp1, coeffabs_4); - vmlsl.u8 q4, d5, d27 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp2, coeffabs_5); - vmlal.u8 q4, d6, d28 ;mul_res1 = vmlal_u8(mul_res1, - ; src_tmp3, coeffabs_6); - vmlsl.u8 q4, d7, d29 ;mul_res1 = vmlsl_u8(mul_res1, - ; src_tmp4, coeffabs_7); - vst1.8 {d12}, [r14], r6 - vqrshrun.s16 d14, q7, #6 - vld1.u8 {d16}, [r3], r2 ;src_tmp1 = vld1_u8(pu1_src_tmp); - vmlal.u8 q5, d2, d23 ;mul_res2 = vmull_u8(src_tmp3, - ; coeffabs_1); - vmlsl.u8 q5, d1, d22 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp2, coeffabs_0); - vmlsl.u8 q5, d3, d24 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp4, coeffabs_2); - vmlal.u8 q5, d4, d25 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp1, coeffabs_3); - vhadd.s16 q4, q4, q15 - vdup.16 q6, r11 - vmlal.u8 q5, d5, d26 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp2, coeffabs_4); - vmlsl.u8 q5, d6, d27 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp3, coeffabs_5); - vmlal.u8 q5, d7, d28 ;mul_res2 = vmlal_u8(mul_res2, - ; src_tmp4, coeffabs_6); - vmlsl.u8 q5, d16, d29 ;mul_res2 = vmlsl_u8(mul_res2, - ; src_tmp1, coeffabs_7); - vst1.8 {d14}, [r14], r6 - vqrshrun.s16 d8, q4, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vld1.u8 {d17}, [r3], r2 ;src_tmp2 = vld1_u8(pu1_src_tmp); - vmlal.u8 q6, d3, d23 - vmlsl.u8 q6, d2, d22 - vmlsl.u8 q6, d4, d24 - vmlal.u8 q6, d5, d25 - vhadd.s16 q5, q5, q15 - vdup.16 q7, r11 - vmlal.u8 q6, d6, d26 - vmlsl.u8 q6, d7, d27 - vmlal.u8 q6, d16, d28 - vmlsl.u8 q6, d17, d29 - add r14, r1, r6 - vst1.8 {d8}, [r1]! ;vst1_u8(pu1_dst,sto_res); - vqrshrun.s16 d10, q5, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vld1.u8 {d18}, [r3], r2 ;src_tmp3 = vld1_u8(pu1_src_tmp); - vmlal.u8 q7, d4, d23 - vmlsl.u8 q7, d3, d22 - vmlsl.u8 q7, d5, d24 - vmlal.u8 q7, d6, d25 - vhadd.s16 q6, q6, q15 - vmlal.u8 q7, d7, d26 - vmlsl.u8 q7, d16, d27 - vmlal.u8 q7, d17, d28 - vmlsl.u8 q7, d18, d29 - vst1.8 {d10}, [r14], r6 ;vst1_u8(pu1_dst_tmp,sto_res); - vqrshrun.s16 d12, q6, #6 - -epilog_end - vst1.8 {d12}, [r14], r6 - vhadd.s16 q7, q7, q15 - vqrshrun.s16 d14, q7, #6 - vst1.8 {d14}, [r14], r6 - -end_loops - tst r5, #7 - ldr r1, [sp], #4 - ldr r0, [sp], #4 - vpopeq {d8 - d15} - ldmfdeq sp!, {r4 - r12, r15} ;reload the registers from sp - mov r5, #4 - add r0, r0, #8 - add r1, r1, #8 - mov r7, #16 - -core_loop_wd_4 - rsb r9, r5, r6, lsl #2 ;r6->dst_strd r5 ->wd - rsb r8, r5, r2, lsl #2 ;r2->src_strd - vmov.i8 d4, #0 - -outer_loop_wd_4 - subs r12, r5, #0 - ble end_inner_loop_wd_4 ;outer loop jump - -inner_loop_wd_4 - add r3, r0, r2 - vld1.u32 {d4[1]},[r3], r2 ;src_tmp1 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp1, 1); - subs r12, r12, #4 - vdup.u32 d5, d4[1] ;src_tmp2 = vdup_lane_u32(src_tmp1, - ; 1); - vld1.u32 {d5[1]},[r3], r2 ;src_tmp2 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp2, 1); - vld1.u32 {d4[0]},[r0] ;src_tmp1 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp1, 0); - vdup.16 q0, r11 - vmlal.u8 q0, d5, d23 ;mul_res1 = - ; vmull_u8(vreinterpret_u8_u32(src_tmp2), coeffabs_1); - vdup.u32 d6, d5[1] ;src_tmp3 = vdup_lane_u32(src_tmp2, - ; 1); - add r0, r0, #4 - vld1.u32 {d6[1]},[r3], r2 ;src_tmp3 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp3, 1); - vmlsl.u8 q0, d4, d22 ;mul_res1 = vmlsl_u8(mul_res1, - ; vreinterpret_u8_u32(src_tmp1), coeffabs_0); - vdup.u32 d7, d6[1] ;src_tmp4 = vdup_lane_u32(src_tmp3, - ; 1); - vld1.u32 {d7[1]},[r3], r2 ;src_tmp4 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp4, 1); - vmlsl.u8 q0, d6, d24 ;mul_res1 = vmlsl_u8(mul_res1, - ; vreinterpret_u8_u32(src_tmp3), coeffabs_2); - vdup.16 q4, r11 - vmlal.u8 q4, d7, d23 - vdup.u32 d4, d7[1] ;src_tmp1 = vdup_lane_u32(src_tmp4, - ; 1); - vmull.u8 q1, d7, d25 ;mul_res2 = - ; vmull_u8(vreinterpret_u8_u32(src_tmp4), coeffabs_3); - vld1.u32 {d4[1]},[r3], r2 ;src_tmp1 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp1, 1); - vmlsl.u8 q4, d6, d22 - vmlal.u8 q0, d4, d26 ;mul_res1 = vmlal_u8(mul_res1, - ; vreinterpret_u8_u32(src_tmp1), coeffabs_4); - vdup.u32 d5, d4[1] ;src_tmp2 = vdup_lane_u32(src_tmp1, - ; 1); - vmlsl.u8 q4, d4, d24 - vld1.u32 {d5[1]},[r3], r2 ;src_tmp2 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp2, 1); - vmlsl.u8 q1, d5, d27 ;mul_res2 = vmlsl_u8(mul_res2, - ; vreinterpret_u8_u32(src_tmp2), coeffabs_5); - vdup.u32 d6, d5[1] ;src_tmp3 = vdup_lane_u32(src_tmp2, - ; 1); - vmlal.u8 q4, d5, d25 - vld1.u32 {d6[1]},[r3], r2 ;src_tmp3 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp3, 1); - vmlal.u8 q0, d6, d28 ;mul_res1 = vmlal_u8(mul_res1, - ; vreinterpret_u8_u32(src_tmp3), coeffabs_6); - vdup.u32 d7, d6[1] ;src_tmp4 = vdup_lane_u32(src_tmp3, - ; 1); - vmlal.u8 q4, d6, d26 - vld1.u32 {d7[1]},[r3], r2 ;src_tmp4 = vld1_lane_u32((uint32_t - ; *)pu1_src_tmp, src_tmp4, 1); - vmlsl.u8 q1, d7, d29 ;mul_res2 = vmlsl_u8(mul_res2, - ; vreinterpret_u8_u32(src_tmp4), coeffabs_7); - vdup.u32 d4, d7[1] - vadd.i16 q0, q0, q1 ;mul_res1 = vaddq_u16(mul_res1, - ; mul_res2); - vmlsl.u8 q4, d7, d27 - vld1.u32 {d4[1]},[r3], r2 - vmlal.u8 q4, d4, d28 - vdup.u32 d5, d4[1] - vhadd.s16 q0, q0, q15 - vqrshrun.s16 d0, q0, #6 ;sto_res = vqmovun_s16(sto_res_tmp); - vld1.u32 {d5[1]},[r3] - add r3, r1, r6 - vst1.32 {d0[0]},[r1] ;vst1_lane_u32((uint32_t *)pu1_dst, - ; vreinterpret_u32_u8(sto_res), 0); - vmlsl.u8 q4, d5, d29 - vst1.32 {d0[1]},[r3], r6 ;vst1_lane_u32((uint32_t - ; *)pu1_dst_tmp, vreinterpret_u32_u8(sto_res), 1); - vhadd.s16 q4, q4, q15 - vqrshrun.s16 d8, q4, #6 - vst1.32 {d8[0]},[r3], r6 - add r1, r1, #4 - vst1.32 {d8[1]},[r3] - bgt inner_loop_wd_4 - -end_inner_loop_wd_4 - subs r7, r7, #4 - add r1, r1, r9 - add r0, r0, r8 - bgt outer_loop_wd_4 - - vpop {d8 - d15} - ldmfd sp!, {r4 - r12, r15} ;reload the registers from sp - - ENDP - - END diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve_avg_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve_avg_neon.c deleted file mode 100644 index 8e3ee599..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve_avg_neon.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" - -void vpx_convolve_avg_neon(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, int x_step_q4, - int y0_q4, int y_step_q4, int w, int h) { - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - if (w < 8) { // avg4 - uint8x8_t s0, s1; - uint8x8_t dd0 = vdup_n_u8(0); - uint32x2x2_t s01; - do { - s0 = vld1_u8(src); - src += src_stride; - s1 = vld1_u8(src); - src += src_stride; - s01 = vzip_u32(vreinterpret_u32_u8(s0), vreinterpret_u32_u8(s1)); - dd0 = vreinterpret_u8_u32( - vld1_lane_u32((const uint32_t *)dst, vreinterpret_u32_u8(dd0), 0)); - dd0 = vreinterpret_u8_u32(vld1_lane_u32( - (const uint32_t *)(dst + dst_stride), vreinterpret_u32_u8(dd0), 1)); - dd0 = vrhadd_u8(vreinterpret_u8_u32(s01.val[0]), dd0); - vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(dd0), 0); - dst += dst_stride; - vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(dd0), 1); - dst += dst_stride; - h -= 2; - } while (h != 0); - } else if (w == 8) { // avg8 - uint8x8_t s0, s1, d0, d1; - uint8x16_t s01, d01; - do { - s0 = vld1_u8(src); - src += src_stride; - s1 = vld1_u8(src); - src += src_stride; - d0 = vld1_u8(dst); - d1 = vld1_u8(dst + dst_stride); - - s01 = vcombine_u8(s0, s1); - d01 = vcombine_u8(d0, d1); - d01 = vrhaddq_u8(s01, d01); - - vst1_u8(dst, vget_low_u8(d01)); - dst += dst_stride; - vst1_u8(dst, vget_high_u8(d01)); - dst += dst_stride; - h -= 2; - } while (h != 0); - } else if (w < 32) { // avg16 - uint8x16_t s0, s1, d0, d1; - do { - s0 = vld1q_u8(src); - src += src_stride; - s1 = vld1q_u8(src); - src += src_stride; - d0 = vld1q_u8(dst); - d1 = vld1q_u8(dst + dst_stride); - - d0 = vrhaddq_u8(s0, d0); - d1 = vrhaddq_u8(s1, d1); - - vst1q_u8(dst, d0); - dst += dst_stride; - vst1q_u8(dst, d1); - dst += dst_stride; - h -= 2; - } while (h != 0); - } else if (w == 32) { // avg32 - uint8x16_t s0, s1, s2, s3, d0, d1, d2, d3; - do { - s0 = vld1q_u8(src); - s1 = vld1q_u8(src + 16); - src += src_stride; - s2 = vld1q_u8(src); - s3 = vld1q_u8(src + 16); - src += src_stride; - d0 = vld1q_u8(dst); - d1 = vld1q_u8(dst + 16); - d2 = vld1q_u8(dst + dst_stride); - d3 = vld1q_u8(dst + dst_stride + 16); - - d0 = vrhaddq_u8(s0, d0); - d1 = vrhaddq_u8(s1, d1); - d2 = vrhaddq_u8(s2, d2); - d3 = vrhaddq_u8(s3, d3); - - vst1q_u8(dst, d0); - vst1q_u8(dst + 16, d1); - dst += dst_stride; - vst1q_u8(dst, d2); - vst1q_u8(dst + 16, d3); - dst += dst_stride; - h -= 2; - } while (h != 0); - } else { // avg64 - uint8x16_t s0, s1, s2, s3, d0, d1, d2, d3; - do { - s0 = vld1q_u8(src); - s1 = vld1q_u8(src + 16); - s2 = vld1q_u8(src + 32); - s3 = vld1q_u8(src + 48); - src += src_stride; - d0 = vld1q_u8(dst); - d1 = vld1q_u8(dst + 16); - d2 = vld1q_u8(dst + 32); - d3 = vld1q_u8(dst + 48); - - d0 = vrhaddq_u8(s0, d0); - d1 = vrhaddq_u8(s1, d1); - d2 = vrhaddq_u8(s2, d2); - d3 = vrhaddq_u8(s3, d3); - - vst1q_u8(dst, d0); - vst1q_u8(dst + 16, d1); - vst1q_u8(dst + 32, d2); - vst1q_u8(dst + 48, d3); - dst += dst_stride; - } while (--h); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve_avg_neon_asm.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve_avg_neon_asm.asm deleted file mode 100644 index efd6574f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve_avg_neon_asm.asm +++ /dev/null @@ -1,116 +0,0 @@ -; -; Copyright (c) 2013 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - EXPORT |vpx_convolve_avg_neon| - ARM - REQUIRE8 - PRESERVE8 - - AREA ||.text||, CODE, READONLY, ALIGN=2 - -|vpx_convolve_avg_neon| PROC - push {r4-r6, lr} - ldrd r4, r5, [sp, #36] - mov r6, r2 - - cmp r4, #32 - bgt avg64 - beq avg32 - cmp r4, #8 - bgt avg16 - beq avg8 - b avg4 - -avg64 - sub lr, r1, #32 - sub r4, r3, #32 -avg64_h - pld [r0, r1, lsl #1] - vld1.8 {q0-q1}, [r0]! - vld1.8 {q2-q3}, [r0], lr - pld [r2, r3] - vld1.8 {q8-q9}, [r6@128]! - vld1.8 {q10-q11}, [r6@128], r4 - vrhadd.u8 q0, q0, q8 - vrhadd.u8 q1, q1, q9 - vrhadd.u8 q2, q2, q10 - vrhadd.u8 q3, q3, q11 - vst1.8 {q0-q1}, [r2@128]! - vst1.8 {q2-q3}, [r2@128], r4 - subs r5, r5, #1 - bgt avg64_h - pop {r4-r6, pc} - -avg32 - vld1.8 {q0-q1}, [r0], r1 - vld1.8 {q2-q3}, [r0], r1 - vld1.8 {q8-q9}, [r6@128], r3 - vld1.8 {q10-q11}, [r6@128], r3 - pld [r0] - vrhadd.u8 q0, q0, q8 - pld [r0, r1] - vrhadd.u8 q1, q1, q9 - pld [r6] - vrhadd.u8 q2, q2, q10 - pld [r6, r3] - vrhadd.u8 q3, q3, q11 - vst1.8 {q0-q1}, [r2@128], r3 - vst1.8 {q2-q3}, [r2@128], r3 - subs r5, r5, #2 - bgt avg32 - pop {r4-r6, pc} - -avg16 - vld1.8 {q0}, [r0], r1 - vld1.8 {q1}, [r0], r1 - vld1.8 {q2}, [r6@128], r3 - vld1.8 {q3}, [r6@128], r3 - pld [r0] - pld [r0, r1] - vrhadd.u8 q0, q0, q2 - pld [r6] - pld [r6, r3] - vrhadd.u8 q1, q1, q3 - vst1.8 {q0}, [r2@128], r3 - vst1.8 {q1}, [r2@128], r3 - subs r5, r5, #2 - bgt avg16 - pop {r4-r6, pc} - -avg8 - vld1.8 {d0}, [r0], r1 - vld1.8 {d1}, [r0], r1 - vld1.8 {d2}, [r6@64], r3 - vld1.8 {d3}, [r6@64], r3 - pld [r0] - pld [r0, r1] - vrhadd.u8 q0, q0, q1 - pld [r6] - pld [r6, r3] - vst1.8 {d0}, [r2@64], r3 - vst1.8 {d1}, [r2@64], r3 - subs r5, r5, #2 - bgt avg8 - pop {r4-r6, pc} - -avg4 - vld1.32 {d0[0]}, [r0], r1 - vld1.32 {d0[1]}, [r0], r1 - vld1.32 {d2[0]}, [r6@32], r3 - vld1.32 {d2[1]}, [r6@32], r3 - vrhadd.u8 d0, d0, d2 - vst1.32 {d0[0]}, [r2@32], r3 - vst1.32 {d0[1]}, [r2@32], r3 - subs r5, r5, #2 - bgt avg4 - pop {r4-r6, pc} - ENDP - - END diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve_copy_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve_copy_neon.c deleted file mode 100644 index bea7c984..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve_copy_neon.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" - -void vpx_convolve_copy_neon(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - if (w < 8) { // copy4 - do { - memcpy(dst, src, 4); - src += src_stride; - dst += dst_stride; - memcpy(dst, src, 4); - src += src_stride; - dst += dst_stride; - h -= 2; - } while (h != 0); - } else if (w == 8) { // copy8 - uint8x8_t s0, s1; - do { - s0 = vld1_u8(src); - src += src_stride; - s1 = vld1_u8(src); - src += src_stride; - - vst1_u8(dst, s0); - dst += dst_stride; - vst1_u8(dst, s1); - dst += dst_stride; - h -= 2; - } while (h != 0); - } else if (w < 32) { // copy16 - uint8x16_t s0, s1; - do { - s0 = vld1q_u8(src); - src += src_stride; - s1 = vld1q_u8(src); - src += src_stride; - - vst1q_u8(dst, s0); - dst += dst_stride; - vst1q_u8(dst, s1); - dst += dst_stride; - h -= 2; - } while (h != 0); - } else if (w == 32) { // copy32 - uint8x16_t s0, s1, s2, s3; - do { - s0 = vld1q_u8(src); - s1 = vld1q_u8(src + 16); - src += src_stride; - s2 = vld1q_u8(src); - s3 = vld1q_u8(src + 16); - src += src_stride; - - vst1q_u8(dst, s0); - vst1q_u8(dst + 16, s1); - dst += dst_stride; - vst1q_u8(dst, s2); - vst1q_u8(dst + 16, s3); - dst += dst_stride; - h -= 2; - } while (h != 0); - } else { // copy64 - uint8x16_t s0, s1, s2, s3; - do { - s0 = vld1q_u8(src); - s1 = vld1q_u8(src + 16); - s2 = vld1q_u8(src + 32); - s3 = vld1q_u8(src + 48); - src += src_stride; - - vst1q_u8(dst, s0); - vst1q_u8(dst + 16, s1); - vst1q_u8(dst + 32, s2); - vst1q_u8(dst + 48, s3); - dst += dst_stride; - } while (--h); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve_copy_neon_asm.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve_copy_neon_asm.asm deleted file mode 100644 index 7a66e3ce..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve_copy_neon_asm.asm +++ /dev/null @@ -1,84 +0,0 @@ -; -; Copyright (c) 2013 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - EXPORT |vpx_convolve_copy_neon| - ARM - REQUIRE8 - PRESERVE8 - - AREA ||.text||, CODE, READONLY, ALIGN=2 - -|vpx_convolve_copy_neon| PROC - push {r4-r5, lr} - ldrd r4, r5, [sp, #32] - - cmp r4, #32 - bgt copy64 - beq copy32 - cmp r4, #8 - bgt copy16 - beq copy8 - b copy4 - -copy64 - sub lr, r1, #32 - sub r3, r3, #32 -copy64_h - pld [r0, r1, lsl #1] - vld1.8 {q0-q1}, [r0]! - vld1.8 {q2-q3}, [r0], lr - vst1.8 {q0-q1}, [r2@128]! - vst1.8 {q2-q3}, [r2@128], r3 - subs r5, r5, #1 - bgt copy64_h - pop {r4-r5, pc} - -copy32 - pld [r0, r1, lsl #1] - vld1.8 {q0-q1}, [r0], r1 - pld [r0, r1, lsl #1] - vld1.8 {q2-q3}, [r0], r1 - vst1.8 {q0-q1}, [r2@128], r3 - vst1.8 {q2-q3}, [r2@128], r3 - subs r5, r5, #2 - bgt copy32 - pop {r4-r5, pc} - -copy16 - pld [r0, r1, lsl #1] - vld1.8 {q0}, [r0], r1 - pld [r0, r1, lsl #1] - vld1.8 {q1}, [r0], r1 - vst1.8 {q0}, [r2@128], r3 - vst1.8 {q1}, [r2@128], r3 - subs r5, r5, #2 - bgt copy16 - pop {r4-r5, pc} - -copy8 - pld [r0, r1, lsl #1] - vld1.8 {d0}, [r0], r1 - pld [r0, r1, lsl #1] - vld1.8 {d2}, [r0], r1 - vst1.8 {d0}, [r2@64], r3 - vst1.8 {d2}, [r2@64], r3 - subs r5, r5, #2 - bgt copy8 - pop {r4-r5, pc} - -copy4 - ldr r12, [r0], r1 - str r12, [r2], r3 - subs r5, r5, #1 - bgt copy4 - pop {r4-r5, pc} - ENDP - - END diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve_neon.c deleted file mode 100644 index de5fa294..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_convolve_neon.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_ports/mem.h" - -void vpx_convolve8_neon(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, - int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - // Given our constraints: w <= 64, h <= 64, taps <= 8 we can reduce the - // maximum buffer size to 64 * (64 + 7) (+1 row to make it divisible by 4). - DECLARE_ALIGNED(32, uint8_t, im_block[64 * 72]); - const int im_stride = 64; - - const int vert_filter_taps = vpx_get_filter_taps(filter[y0_q4]) <= 4 ? 4 : 8; - // Account for the vertical phase needing vert_filter_taps / 2 - 1 lines prior - // and vert_filter_taps / 2 lines post. (+1 to make total divisible by 4.) - const int im_height = h + vert_filter_taps; - const ptrdiff_t border_offset = vert_filter_taps / 2 - 1; - - assert(y_step_q4 == 16); - assert(x_step_q4 == 16); - - // Filter starting border_offset rows back. The Neon implementation will - // ignore the given height and filter a multiple of 4 lines. Since this goes - // into the temporary buffer which has lots of extra room and is subsequently - // discarded this is safe if somewhat less than ideal. - vpx_convolve8_horiz_neon(src - src_stride * border_offset, src_stride, - im_block, im_stride, filter, x0_q4, x_step_q4, y0_q4, - y_step_q4, w, im_height); - - // Step into the temporary buffer border_offset rows to get actual frame data. - vpx_convolve8_vert_neon(im_block + im_stride * border_offset, im_stride, dst, - dst_stride, filter, x0_q4, x_step_q4, y0_q4, - y_step_q4, w, h); -} - -void vpx_convolve8_avg_neon(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - DECLARE_ALIGNED(32, uint8_t, im_block[64 * 72]); - const int im_stride = 64; - const int im_height = h + SUBPEL_TAPS; - const ptrdiff_t border_offset = SUBPEL_TAPS / 2 - 1; - - assert(y_step_q4 == 16); - assert(x_step_q4 == 16); - - // This implementation has the same issues as above. In addition, we only want - // to average the values after both passes. - vpx_convolve8_horiz_neon(src - src_stride * border_offset, src_stride, - im_block, im_stride, filter, x0_q4, x_step_q4, y0_q4, - y_step_q4, w, im_height); - - vpx_convolve8_avg_vert_neon(im_block + im_stride * border_offset, im_stride, - dst, dst_stride, filter, x0_q4, x_step_q4, y0_q4, - y_step_q4, w, h); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_neon_sve2_bridge.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_neon_sve2_bridge.h deleted file mode 100644 index bf9f18c7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_neon_sve2_bridge.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2024 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_ARM_VPX_NEON_SVE2_BRIDGE_H_ -#define VPX_VPX_DSP_ARM_VPX_NEON_SVE2_BRIDGE_H_ - -#include -#include -#include - -// Some very useful instructions are exclusive to the SVE2 instruction set. -// However, we can access these instructions from a predominantly Neon context -// by making use of the Neon-SVE bridge intrinsics to reinterpret Neon vectors -// as SVE vectors - with the high part of the SVE vector (if it's longer than -// 128 bits) being "don't care". - -static INLINE int16x8_t vpx_tbl2_s16(int16x8_t s0, int16x8_t s1, - uint16x8_t tbl) { - svint16x2_t samples = svcreate2_s16(svset_neonq_s16(svundef_s16(), s0), - svset_neonq_s16(svundef_s16(), s1)); - return svget_neonq_s16( - svtbl2_s16(samples, svset_neonq_u16(svundef_u16(), tbl))); -} - -#endif // VPX_VPX_DSP_ARM_VPX_NEON_SVE2_BRIDGE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_neon_sve_bridge.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_neon_sve_bridge.h deleted file mode 100644 index 48534fb7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_neon_sve_bridge.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2024 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_ARM_VPX_NEON_SVE_BRIDGE_H_ -#define VPX_VPX_DSP_ARM_VPX_NEON_SVE_BRIDGE_H_ - -#include -#include -#include - -// Dot product instructions operating on 16-bit input elements are exclusive to -// the SVE instruction set. However, we can access these instructions from a -// predominantly Neon context by making use of the Neon-SVE bridge intrinsics -// to reinterpret Neon vectors as SVE vectors - with the high part of the SVE -// vector (if it's longer than 128 bits) being "don't care". - -// While sub-optimal on machines that have SVE vector length > 128-bit - as the -// remainder of the vector is unused - this approach is still beneficial when -// compared to a Neon-only solution. - -static INLINE uint64x2_t vpx_dotq_u16(uint64x2_t acc, uint16x8_t x, - uint16x8_t y) { - return svget_neonq_u64(svdot_u64(svset_neonq_u64(svundef_u64(), acc), - svset_neonq_u16(svundef_u16(), x), - svset_neonq_u16(svundef_u16(), y))); -} - -static INLINE int64x2_t vpx_dotq_s16(int64x2_t acc, int16x8_t x, int16x8_t y) { - return svget_neonq_s64(svdot_s64(svset_neonq_s64(svundef_s64(), acc), - svset_neonq_s16(svundef_s16(), x), - svset_neonq_s16(svundef_s16(), y))); -} - -#define vpx_dotq_lane_s16(acc, x, y, lane) \ - svget_neonq_s64(svdot_lane_s64(svset_neonq_s64(svundef_s64(), acc), \ - svset_neonq_s16(svundef_s16(), x), \ - svset_neonq_s16(svundef_s16(), y), lane)) - -static INLINE uint16x8_t vpx_tbl_u16(uint16x8_t data, uint16x8_t indices) { - return svget_neonq_u16(svtbl_u16(svset_neonq_u16(svundef_u16(), data), - svset_neonq_u16(svundef_u16(), indices))); -} - -#endif // VPX_VPX_DSP_ARM_VPX_NEON_SVE_BRIDGE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_scaled_convolve8_neon.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_scaled_convolve8_neon.c deleted file mode 100644 index f40b6a90..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/arm/vpx_scaled_convolve8_neon.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/arm/mem_neon.h" -#include "vpx_dsp/arm/transpose_neon.h" -#include "vpx_dsp/arm/vpx_convolve8_neon.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_ports/mem.h" - -static INLINE void scaledconvolve_horiz_neon( - const uint8_t *src, const ptrdiff_t src_stride, uint8_t *dst, - const ptrdiff_t dst_stride, const InterpKernel *const x_filter, - const int x0_q4, const int x_step_q4, int w, int h) { - DECLARE_ALIGNED(16, uint8_t, temp[8 * 8]); - - src -= SUBPEL_TAPS / 2 - 1; - - if (w == 4) { - do { - int x_q4 = x0_q4; - - // Process a 4x4 tile. - for (int r = 0; r < 4; ++r) { - const uint8_t *s = &src[x_q4 >> SUBPEL_BITS]; - - if (x_q4 & SUBPEL_MASK) { - const int16x8_t filter = vld1q_s16(x_filter[x_q4 & SUBPEL_MASK]); - - uint8x8_t t0, t1, t2, t3; - load_u8_8x4(s, src_stride, &t0, &t1, &t2, &t3); - transpose_u8_8x4(&t0, &t1, &t2, &t3); - - int16x4_t s0 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t0))); - int16x4_t s1 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t1))); - int16x4_t s2 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t2))); - int16x4_t s3 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t3))); - int16x4_t s4 = vget_high_s16(vreinterpretq_s16_u16(vmovl_u8(t0))); - int16x4_t s5 = vget_high_s16(vreinterpretq_s16_u16(vmovl_u8(t1))); - int16x4_t s6 = vget_high_s16(vreinterpretq_s16_u16(vmovl_u8(t2))); - int16x4_t s7 = vget_high_s16(vreinterpretq_s16_u16(vmovl_u8(t3))); - - int16x4_t dd0 = convolve8_4(s0, s1, s2, s3, s4, s5, s6, s7, filter); - uint8x8_t d0 = - vqrshrun_n_s16(vcombine_s16(dd0, vdup_n_s16(0)), FILTER_BITS); - - store_u8_4x1(&temp[4 * r], d0); - } else { - // Memcpy for non-subpel locations. - s += SUBPEL_TAPS / 2 - 1; - - for (int c = 0; c < 4; ++c) { - temp[r * 4 + c] = s[c * src_stride]; - } - } - x_q4 += x_step_q4; - } - - // Transpose the 4x4 result tile and store. - uint8x8_t d01 = vld1_u8(temp + 0); - uint8x8_t d23 = vld1_u8(temp + 8); - - transpose_u8_4x4(&d01, &d23); - - store_u8_4x1(dst + 0 * dst_stride, d01); - store_u8_4x1(dst + 1 * dst_stride, d23); - store_u8_4x1_high(dst + 2 * dst_stride, d01); - store_u8_4x1_high(dst + 3 * dst_stride, d23); - - src += 4 * src_stride; - dst += 4 * dst_stride; - h -= 4; - } while (h > 0); - return; - } - - do { - int x_q4 = x0_q4; - uint8_t *d = dst; - int width = w; - - do { - // Process an 8x8 tile. - for (int r = 0; r < 8; ++r) { - const uint8_t *s = &src[x_q4 >> SUBPEL_BITS]; - - if (x_q4 & SUBPEL_MASK) { - const int16x8_t filter = vld1q_s16(x_filter[x_q4 & SUBPEL_MASK]); - - uint8x8_t t0, t1, t2, t3, t4, t5, t6, t7; - load_u8_8x8(s, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7); - - transpose_u8_8x8(&t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7); - int16x8_t s0 = vreinterpretq_s16_u16(vmovl_u8(t0)); - int16x8_t s1 = vreinterpretq_s16_u16(vmovl_u8(t1)); - int16x8_t s2 = vreinterpretq_s16_u16(vmovl_u8(t2)); - int16x8_t s3 = vreinterpretq_s16_u16(vmovl_u8(t3)); - int16x8_t s4 = vreinterpretq_s16_u16(vmovl_u8(t4)); - int16x8_t s5 = vreinterpretq_s16_u16(vmovl_u8(t5)); - int16x8_t s6 = vreinterpretq_s16_u16(vmovl_u8(t6)); - int16x8_t s7 = vreinterpretq_s16_u16(vmovl_u8(t7)); - - uint8x8_t d0 = convolve8_8(s0, s1, s2, s3, s4, s5, s6, s7, filter); - - vst1_u8(&temp[r * 8], d0); - } else { - // Memcpy for non-subpel locations. - s += SUBPEL_TAPS / 2 - 1; - - for (int c = 0; c < 8; ++c) { - temp[r * 8 + c] = s[c * src_stride]; - } - } - x_q4 += x_step_q4; - } - - // Transpose the 8x8 result tile and store. - uint8x8_t d0, d1, d2, d3, d4, d5, d6, d7; - load_u8_8x8(temp, 8, &d0, &d1, &d2, &d3, &d4, &d5, &d6, &d7); - - transpose_u8_8x8(&d0, &d1, &d2, &d3, &d4, &d5, &d6, &d7); - - store_u8_8x8(d, dst_stride, d0, d1, d2, d3, d4, d5, d6, d7); - - d += 8; - width -= 8; - } while (width != 0); - - src += 8 * src_stride; - dst += 8 * dst_stride; - h -= 8; - } while (h > 0); -} - -static INLINE void scaledconvolve_vert_neon( - const uint8_t *src, const ptrdiff_t src_stride, uint8_t *dst, - const ptrdiff_t dst_stride, const InterpKernel *const y_filter, - const int y0_q4, const int y_step_q4, int w, int h) { - int y_q4 = y0_q4; - - if (w == 4) { - do { - const uint8_t *s = &src[(y_q4 >> SUBPEL_BITS) * src_stride]; - - if (y_q4 & SUBPEL_MASK) { - const int16x8_t filter = vld1q_s16(y_filter[y_q4 & SUBPEL_MASK]); - - uint8x8_t t0, t1, t2, t3, t4, t5, t6, t7; - load_u8_8x8(s, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7); - int16x4_t s0 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t0))); - int16x4_t s1 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t1))); - int16x4_t s2 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t2))); - int16x4_t s3 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t3))); - int16x4_t s4 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t4))); - int16x4_t s5 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t5))); - int16x4_t s6 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t6))); - int16x4_t s7 = vget_low_s16(vreinterpretq_s16_u16(vmovl_u8(t7))); - - int16x4_t dd0 = convolve8_4(s0, s1, s2, s3, s4, s5, s6, s7, filter); - uint8x8_t d0 = - vqrshrun_n_s16(vcombine_s16(dd0, vdup_n_s16(0)), FILTER_BITS); - - store_u8_4x1(dst, d0); - } else { - // Memcpy for non-subpel locations. - memcpy(dst, &s[(SUBPEL_TAPS / 2 - 1) * src_stride], 4); - } - - y_q4 += y_step_q4; - dst += dst_stride; - } while (--h != 0); - return; - } - - if (w == 8) { - do { - const uint8_t *s = &src[(y_q4 >> SUBPEL_BITS) * src_stride]; - - if (y_q4 & SUBPEL_MASK) { - const int16x8_t filter = vld1q_s16(y_filter[y_q4 & SUBPEL_MASK]); - - uint8x8_t t0, t1, t2, t3, t4, t5, t6, t7; - load_u8_8x8(s, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7); - int16x8_t s0 = vreinterpretq_s16_u16(vmovl_u8(t0)); - int16x8_t s1 = vreinterpretq_s16_u16(vmovl_u8(t1)); - int16x8_t s2 = vreinterpretq_s16_u16(vmovl_u8(t2)); - int16x8_t s3 = vreinterpretq_s16_u16(vmovl_u8(t3)); - int16x8_t s4 = vreinterpretq_s16_u16(vmovl_u8(t4)); - int16x8_t s5 = vreinterpretq_s16_u16(vmovl_u8(t5)); - int16x8_t s6 = vreinterpretq_s16_u16(vmovl_u8(t6)); - int16x8_t s7 = vreinterpretq_s16_u16(vmovl_u8(t7)); - - uint8x8_t d0 = convolve8_8(s0, s1, s2, s3, s4, s5, s6, s7, filter); - - vst1_u8(dst, d0); - } else { - // Memcpy for non-subpel locations. - memcpy(dst, &s[(SUBPEL_TAPS / 2 - 1) * src_stride], 8); - } - - y_q4 += y_step_q4; - dst += dst_stride; - } while (--h != 0); - return; - } - - do { - const uint8_t *s = &src[(y_q4 >> SUBPEL_BITS) * src_stride]; - uint8_t *d = dst; - int width = w; - - if (y_q4 & SUBPEL_MASK) { - do { - const int16x8_t filter = vld1q_s16(y_filter[y_q4 & SUBPEL_MASK]); - - uint8x16_t t0, t1, t2, t3, t4, t5, t6, t7; - load_u8_16x8(s, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7); - - int16x8_t s0[2], s1[2], s2[2], s3[2], s4[2], s5[2], s6[2], s7[2]; - s0[0] = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(t0))); - s1[0] = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(t1))); - s2[0] = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(t2))); - s3[0] = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(t3))); - s4[0] = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(t4))); - s5[0] = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(t5))); - s6[0] = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(t6))); - s7[0] = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(t7))); - - s0[1] = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(t0))); - s1[1] = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(t1))); - s2[1] = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(t2))); - s3[1] = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(t3))); - s4[1] = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(t4))); - s5[1] = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(t5))); - s6[1] = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(t6))); - s7[1] = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(t7))); - - uint8x8_t d0 = convolve8_8(s0[0], s1[0], s2[0], s3[0], s4[0], s5[0], - s6[0], s7[0], filter); - uint8x8_t d1 = convolve8_8(s0[1], s1[1], s2[1], s3[1], s4[1], s5[1], - s6[1], s7[1], filter); - - vst1q_u8(d, vcombine_u8(d0, d1)); - - s += 16; - d += 16; - width -= 16; - } while (width != 0); - } else { - // Memcpy for non-subpel locations. - s += (SUBPEL_TAPS / 2 - 1) * src_stride; - - do { - uint8x16_t s0 = vld1q_u8(s); - vst1q_u8(d, s0); - s += 16; - d += 16; - width -= 16; - } while (width != 0); - } - - y_q4 += y_step_q4; - dst += dst_stride; - } while (--h != 0); -} - -void vpx_scaled_2d_neon(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, - int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - // Fixed size intermediate buffer, im_block, places limits on parameters. - // 2d filtering proceeds in 2 steps: - // (1) Interpolate horizontally into an intermediate buffer, temp. - // (2) Interpolate temp vertically to derive the sub-pixel result. - // Deriving the maximum number of rows in the im_block buffer (135): - // --Smallest scaling factor is x1/2 ==> y_step_q4 = 32 (Normative). - // --Largest block size is 64x64 pixels. - // --64 rows in the downscaled frame span a distance of (64 - 1) * 32 in the - // original frame (in 1/16th pixel units). - // --Must round-up because block may be located at sub-pixel position. - // --Require an additional SUBPEL_TAPS rows for the 8-tap filter tails. - // --((64 - 1) * 32 + 15) >> 4 + 8 = 135. - // --Require an additional 8 rows for the horiz_w8 transpose tail. - // When calling in frame scaling function, the smallest scaling factor is x1/4 - // ==> y_step_q4 = 64. Since w and h are at most 16, the temp buffer is still - // big enough. - DECLARE_ALIGNED(16, uint8_t, im_block[(135 + 8) * 64]); - const int im_height = - (((h - 1) * y_step_q4 + y0_q4) >> SUBPEL_BITS) + SUBPEL_TAPS; - const ptrdiff_t im_stride = 64; - - assert(w <= 64); - assert(h <= 64); - assert(y_step_q4 <= 32 || (y_step_q4 <= 64 && h <= 32)); - assert(x_step_q4 <= 64); - - scaledconvolve_horiz_neon(src - src_stride * (SUBPEL_TAPS / 2 - 1), - src_stride, im_block, im_stride, filter, x0_q4, - x_step_q4, w, im_height); - - scaledconvolve_vert_neon(im_block, im_stride, dst, dst_stride, filter, y0_q4, - y_step_q4, w, h); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/avg.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/avg.c deleted file mode 100644 index a8dcab7d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/avg.c +++ /dev/null @@ -1,441 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_ports/mem.h" - -unsigned int vpx_avg_8x8_c(const uint8_t *s, int p) { - int i, j; - int sum = 0; - for (i = 0; i < 8; ++i, s += p) - for (j = 0; j < 8; sum += s[j], ++j) { - } - - return (sum + 32) >> 6; -} - -unsigned int vpx_avg_4x4_c(const uint8_t *s, int p) { - int i, j; - int sum = 0; - for (i = 0; i < 4; ++i, s += p) - for (j = 0; j < 4; sum += s[j], ++j) { - } - - return (sum + 8) >> 4; -} - -#if CONFIG_VP9_HIGHBITDEPTH -// src_diff: 13 bit, dynamic range [-4095, 4095] -// coeff: 16 bit -static void hadamard_highbd_col8_first_pass(const int16_t *src_diff, - ptrdiff_t src_stride, - int16_t *coeff) { - int16_t b0 = src_diff[0 * src_stride] + src_diff[1 * src_stride]; - int16_t b1 = src_diff[0 * src_stride] - src_diff[1 * src_stride]; - int16_t b2 = src_diff[2 * src_stride] + src_diff[3 * src_stride]; - int16_t b3 = src_diff[2 * src_stride] - src_diff[3 * src_stride]; - int16_t b4 = src_diff[4 * src_stride] + src_diff[5 * src_stride]; - int16_t b5 = src_diff[4 * src_stride] - src_diff[5 * src_stride]; - int16_t b6 = src_diff[6 * src_stride] + src_diff[7 * src_stride]; - int16_t b7 = src_diff[6 * src_stride] - src_diff[7 * src_stride]; - - int16_t c0 = b0 + b2; - int16_t c1 = b1 + b3; - int16_t c2 = b0 - b2; - int16_t c3 = b1 - b3; - int16_t c4 = b4 + b6; - int16_t c5 = b5 + b7; - int16_t c6 = b4 - b6; - int16_t c7 = b5 - b7; - - coeff[0] = c0 + c4; - coeff[7] = c1 + c5; - coeff[3] = c2 + c6; - coeff[4] = c3 + c7; - coeff[2] = c0 - c4; - coeff[6] = c1 - c5; - coeff[1] = c2 - c6; - coeff[5] = c3 - c7; -} - -// src_diff: 16 bit, dynamic range [-32760, 32760] -// coeff: 19 bit -static void hadamard_highbd_col8_second_pass(const int16_t *src_diff, - ptrdiff_t src_stride, - int32_t *coeff) { - int32_t b0 = src_diff[0 * src_stride] + src_diff[1 * src_stride]; - int32_t b1 = src_diff[0 * src_stride] - src_diff[1 * src_stride]; - int32_t b2 = src_diff[2 * src_stride] + src_diff[3 * src_stride]; - int32_t b3 = src_diff[2 * src_stride] - src_diff[3 * src_stride]; - int32_t b4 = src_diff[4 * src_stride] + src_diff[5 * src_stride]; - int32_t b5 = src_diff[4 * src_stride] - src_diff[5 * src_stride]; - int32_t b6 = src_diff[6 * src_stride] + src_diff[7 * src_stride]; - int32_t b7 = src_diff[6 * src_stride] - src_diff[7 * src_stride]; - - int32_t c0 = b0 + b2; - int32_t c1 = b1 + b3; - int32_t c2 = b0 - b2; - int32_t c3 = b1 - b3; - int32_t c4 = b4 + b6; - int32_t c5 = b5 + b7; - int32_t c6 = b4 - b6; - int32_t c7 = b5 - b7; - - coeff[0] = c0 + c4; - coeff[7] = c1 + c5; - coeff[3] = c2 + c6; - coeff[4] = c3 + c7; - coeff[2] = c0 - c4; - coeff[6] = c1 - c5; - coeff[1] = c2 - c6; - coeff[5] = c3 - c7; -} - -// The order of the output coeff of the hadamard is not important. For -// optimization purposes the final transpose may be skipped. -void vpx_highbd_hadamard_8x8_c(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { - int idx; - int16_t buffer[64]; - int32_t buffer2[64]; - int16_t *tmp_buf = &buffer[0]; - for (idx = 0; idx < 8; ++idx) { - // src_diff: 13 bit - // buffer: 16 bit, dynamic range [-32760, 32760] - hadamard_highbd_col8_first_pass(src_diff, src_stride, tmp_buf); - tmp_buf += 8; - ++src_diff; - } - - tmp_buf = &buffer[0]; - for (idx = 0; idx < 8; ++idx) { - // buffer: 16 bit - // buffer2: 19 bit, dynamic range [-262080, 262080] - hadamard_highbd_col8_second_pass(tmp_buf, 8, buffer2 + 8 * idx); - ++tmp_buf; - } - - for (idx = 0; idx < 64; ++idx) coeff[idx] = (tran_low_t)buffer2[idx]; -} - -// In place 16x16 2D Hadamard transform -void vpx_highbd_hadamard_16x16_c(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { - int idx; - for (idx = 0; idx < 4; ++idx) { - // src_diff: 13 bit, dynamic range [-4095, 4095] - const int16_t *src_ptr = - src_diff + (idx >> 1) * 8 * src_stride + (idx & 0x01) * 8; - vpx_highbd_hadamard_8x8_c(src_ptr, src_stride, coeff + idx * 64); - } - - // coeff: 19 bit, dynamic range [-262080, 262080] - for (idx = 0; idx < 64; ++idx) { - tran_low_t a0 = coeff[0]; - tran_low_t a1 = coeff[64]; - tran_low_t a2 = coeff[128]; - tran_low_t a3 = coeff[192]; - - tran_low_t b0 = (a0 + a1) >> 1; - tran_low_t b1 = (a0 - a1) >> 1; - tran_low_t b2 = (a2 + a3) >> 1; - tran_low_t b3 = (a2 - a3) >> 1; - - // new coeff dynamic range: 20 bit - coeff[0] = b0 + b2; - coeff[64] = b1 + b3; - coeff[128] = b0 - b2; - coeff[192] = b1 - b3; - - ++coeff; - } -} - -void vpx_highbd_hadamard_32x32_c(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { - int idx; - for (idx = 0; idx < 4; ++idx) { - // src_diff: 13 bit, dynamic range [-4095, 4095] - const int16_t *src_ptr = - src_diff + (idx >> 1) * 16 * src_stride + (idx & 0x01) * 16; - vpx_highbd_hadamard_16x16_c(src_ptr, src_stride, coeff + idx * 256); - } - - // coeff: 20 bit - for (idx = 0; idx < 256; ++idx) { - tran_low_t a0 = coeff[0]; - tran_low_t a1 = coeff[256]; - tran_low_t a2 = coeff[512]; - tran_low_t a3 = coeff[768]; - - tran_low_t b0 = (a0 + a1) >> 2; - tran_low_t b1 = (a0 - a1) >> 2; - tran_low_t b2 = (a2 + a3) >> 2; - tran_low_t b3 = (a2 - a3) >> 2; - - // new coeff dynamic range: 20 bit - coeff[0] = b0 + b2; - coeff[256] = b1 + b3; - coeff[512] = b0 - b2; - coeff[768] = b1 - b3; - - ++coeff; - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -// src_diff: first pass, 9 bit, dynamic range [-255, 255] -// second pass, 12 bit, dynamic range [-2040, 2040] -static void hadamard_col8(const int16_t *src_diff, ptrdiff_t src_stride, - int16_t *coeff) { - int16_t b0 = src_diff[0 * src_stride] + src_diff[1 * src_stride]; - int16_t b1 = src_diff[0 * src_stride] - src_diff[1 * src_stride]; - int16_t b2 = src_diff[2 * src_stride] + src_diff[3 * src_stride]; - int16_t b3 = src_diff[2 * src_stride] - src_diff[3 * src_stride]; - int16_t b4 = src_diff[4 * src_stride] + src_diff[5 * src_stride]; - int16_t b5 = src_diff[4 * src_stride] - src_diff[5 * src_stride]; - int16_t b6 = src_diff[6 * src_stride] + src_diff[7 * src_stride]; - int16_t b7 = src_diff[6 * src_stride] - src_diff[7 * src_stride]; - - int16_t c0 = b0 + b2; - int16_t c1 = b1 + b3; - int16_t c2 = b0 - b2; - int16_t c3 = b1 - b3; - int16_t c4 = b4 + b6; - int16_t c5 = b5 + b7; - int16_t c6 = b4 - b6; - int16_t c7 = b5 - b7; - - coeff[0] = c0 + c4; - coeff[7] = c1 + c5; - coeff[3] = c2 + c6; - coeff[4] = c3 + c7; - coeff[2] = c0 - c4; - coeff[6] = c1 - c5; - coeff[1] = c2 - c6; - coeff[5] = c3 - c7; -} - -// The order of the output coeff of the hadamard is not important. For -// optimization purposes the final transpose may be skipped. -void vpx_hadamard_8x8_c(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { - int idx; - int16_t buffer[64]; - int16_t buffer2[64]; - int16_t *tmp_buf = &buffer[0]; - for (idx = 0; idx < 8; ++idx) { - hadamard_col8(src_diff, src_stride, tmp_buf); // src_diff: 9 bit - // dynamic range [-255, 255] - tmp_buf += 8; - ++src_diff; - } - - tmp_buf = &buffer[0]; - for (idx = 0; idx < 8; ++idx) { - hadamard_col8(tmp_buf, 8, buffer2 + 8 * idx); // tmp_buf: 12 bit - // dynamic range [-2040, 2040] - // buffer2: 15 bit - // dynamic range [-16320, 16320] - ++tmp_buf; - } - - for (idx = 0; idx < 64; ++idx) coeff[idx] = (tran_low_t)buffer2[idx]; -} - -// In place 16x16 2D Hadamard transform -void vpx_hadamard_16x16_c(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { - int idx; - for (idx = 0; idx < 4; ++idx) { - // src_diff: 9 bit, dynamic range [-255, 255] - const int16_t *src_ptr = - src_diff + (idx >> 1) * 8 * src_stride + (idx & 0x01) * 8; - vpx_hadamard_8x8_c(src_ptr, src_stride, coeff + idx * 64); - } - - // coeff: 15 bit, dynamic range [-16320, 16320] - for (idx = 0; idx < 64; ++idx) { - tran_low_t a0 = coeff[0]; - tran_low_t a1 = coeff[64]; - tran_low_t a2 = coeff[128]; - tran_low_t a3 = coeff[192]; - - tran_low_t b0 = (a0 + a1) >> 1; // (a0 + a1): 16 bit, [-32640, 32640] - tran_low_t b1 = (a0 - a1) >> 1; // b0-b3: 15 bit, dynamic range - tran_low_t b2 = (a2 + a3) >> 1; // [-16320, 16320] - tran_low_t b3 = (a2 - a3) >> 1; - - coeff[0] = b0 + b2; // 16 bit, [-32640, 32640] - coeff[64] = b1 + b3; - coeff[128] = b0 - b2; - coeff[192] = b1 - b3; - - ++coeff; - } -} - -void vpx_hadamard_32x32_c(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { - int idx; - for (idx = 0; idx < 4; ++idx) { - // src_diff: 9 bit, dynamic range [-255, 255] - const int16_t *src_ptr = - src_diff + (idx >> 1) * 16 * src_stride + (idx & 0x01) * 16; - vpx_hadamard_16x16_c(src_ptr, src_stride, coeff + idx * 256); - } - - // coeff: 16 bit, dynamic range [-32768, 32767] - for (idx = 0; idx < 256; ++idx) { - tran_low_t a0 = coeff[0]; - tran_low_t a1 = coeff[256]; - tran_low_t a2 = coeff[512]; - tran_low_t a3 = coeff[768]; - - tran_low_t b0 = (a0 + a1) >> 2; // (a0 + a1): 17 bit, [-65536, 65535] - tran_low_t b1 = (a0 - a1) >> 2; // b0-b3: 15 bit, dynamic range - tran_low_t b2 = (a2 + a3) >> 2; // [-16384, 16383] - tran_low_t b3 = (a2 - a3) >> 2; - - coeff[0] = b0 + b2; // 16 bit, [-32768, 32767] - coeff[256] = b1 + b3; - coeff[512] = b0 - b2; - coeff[768] = b1 - b3; - - ++coeff; - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -// coeff: dynamic range 20 bit. -// length: value range {16, 64, 256, 1024}. -int vpx_highbd_satd_c(const tran_low_t *coeff, int length) { - int i; - int satd = 0; - for (i = 0; i < length; ++i) satd += abs(coeff[i]); - - // satd: 30 bits - return satd; -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -// coeff: 16 bits, dynamic range [-32640, 32640]. -// length: value range {16, 64, 256, 1024}. -int vpx_satd_c(const tran_low_t *coeff, int length) { - int i; - int satd = 0; - for (i = 0; i < length; ++i) satd += abs(coeff[i]); - - // satd: 26 bits, dynamic range [-32640 * 1024, 32640 * 1024] - return satd; -} - -// Integer projection onto row vectors. -// height: value range {16, 32, 64}. -void vpx_int_pro_row_c(int16_t hbuf[16], const uint8_t *ref, - const int ref_stride, const int height) { - int idx; - const int norm_factor = height >> 1; - assert(height >= 2); - for (idx = 0; idx < 16; ++idx) { - int i; - hbuf[idx] = 0; - // hbuf[idx]: 14 bit, dynamic range [0, 16320]. - for (i = 0; i < height; ++i) hbuf[idx] += ref[i * ref_stride]; - // hbuf[idx]: 9 bit, dynamic range [0, 510]. - hbuf[idx] /= norm_factor; - ++ref; - } -} - -// width: value range {16, 32, 64}. -int16_t vpx_int_pro_col_c(const uint8_t *ref, const int width) { - int idx; - int16_t sum = 0; - // sum: 14 bit, dynamic range [0, 16320] - for (idx = 0; idx < width; ++idx) sum += ref[idx]; - return sum; -} - -// ref: [0 - 510] -// src: [0 - 510] -// bwl: {2, 3, 4} -int vpx_vector_var_c(const int16_t *ref, const int16_t *src, const int bwl) { - int i; - int width = 4 << bwl; - int sse = 0, mean = 0, var; - - for (i = 0; i < width; ++i) { - int diff = ref[i] - src[i]; // diff: dynamic range [-510, 510], 10 bits. - mean += diff; // mean: dynamic range 16 bits. - sse += diff * diff; // sse: dynamic range 26 bits. - } - - // (mean * mean): dynamic range 31 bits. - var = sse - ((mean * mean) >> (bwl + 2)); - return var; -} - -void vpx_minmax_8x8_c(const uint8_t *s, int p, const uint8_t *d, int dp, - int *min, int *max) { - int i, j; - *min = 255; - *max = 0; - for (i = 0; i < 8; ++i, s += p, d += dp) { - for (j = 0; j < 8; ++j) { - int diff = abs(s[j] - d[j]); - *min = diff < *min ? diff : *min; - *max = diff > *max ? diff : *max; - } - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -unsigned int vpx_highbd_avg_8x8_c(const uint8_t *s8, int p) { - int i, j; - int sum = 0; - const uint16_t *s = CONVERT_TO_SHORTPTR(s8); - for (i = 0; i < 8; ++i, s += p) - for (j = 0; j < 8; sum += s[j], ++j) { - } - - return (sum + 32) >> 6; -} - -unsigned int vpx_highbd_avg_4x4_c(const uint8_t *s8, int p) { - int i, j; - int sum = 0; - const uint16_t *s = CONVERT_TO_SHORTPTR(s8); - for (i = 0; i < 4; ++i, s += p) - for (j = 0; j < 4; sum += s[j], ++j) { - } - - return (sum + 8) >> 4; -} - -void vpx_highbd_minmax_8x8_c(const uint8_t *s8, int p, const uint8_t *d8, - int dp, int *min, int *max) { - int i, j; - const uint16_t *s = CONVERT_TO_SHORTPTR(s8); - const uint16_t *d = CONVERT_TO_SHORTPTR(d8); - *min = 65535; - *max = 0; - for (i = 0; i < 8; ++i, s += p, d += dp) { - for (j = 0; j < 8; ++j) { - int diff = abs(s[j] - d[j]); - *min = diff < *min ? diff : *min; - *max = diff > *max ? diff : *max; - } - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitreader.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitreader.c deleted file mode 100644 index 90cbbba5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitreader.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include - -#include "./vpx_config.h" - -#include "vpx_dsp/bitreader.h" -#include "vpx_dsp/prob.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_ports/mem.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_util/endian_inl.h" - -int vpx_reader_init(vpx_reader *r, const uint8_t *buffer, size_t size, - vpx_decrypt_cb decrypt_cb, void *decrypt_state) { - if (size && !buffer) { - return 1; - } else { - r->buffer_end = buffer + size; - r->buffer = buffer; - r->value = 0; - r->count = -8; - r->range = 255; - r->decrypt_cb = decrypt_cb; - r->decrypt_state = decrypt_state; - vpx_reader_fill(r); - return vpx_read_bit(r) != 0; // marker bit - } -} - -void vpx_reader_fill(vpx_reader *r) { - const uint8_t *const buffer_end = r->buffer_end; - const uint8_t *buffer = r->buffer; - const uint8_t *buffer_start = buffer; - BD_VALUE value = r->value; - int count = r->count; - const size_t bytes_left = buffer_end - buffer; - const size_t bits_left = bytes_left * CHAR_BIT; - int shift = BD_VALUE_SIZE - CHAR_BIT - (count + CHAR_BIT); - - if (r->decrypt_cb) { - size_t n = VPXMIN(sizeof(r->clear_buffer), bytes_left); - r->decrypt_cb(r->decrypt_state, buffer, r->clear_buffer, (int)n); - buffer = r->clear_buffer; - buffer_start = r->clear_buffer; - } - if (bits_left > BD_VALUE_SIZE) { - const int bits = (shift & 0xfffffff8) + CHAR_BIT; - BD_VALUE nv; - BD_VALUE big_endian_values; - memcpy(&big_endian_values, buffer, sizeof(BD_VALUE)); -#if SIZE_MAX == 0xffffffffffffffffULL - big_endian_values = HToBE64(big_endian_values); -#else - big_endian_values = HToBE32(big_endian_values); -#endif - nv = big_endian_values >> (BD_VALUE_SIZE - bits); - count += bits; - buffer += (bits >> 3); - value = r->value | (nv << (shift & 0x7)); - } else { - const int bits_over = (int)(shift + CHAR_BIT - (int)bits_left); - int loop_end = 0; - if (bits_over >= 0) { - count += LOTS_OF_BITS; - loop_end = bits_over; - } - - if (bits_over < 0 || bits_left) { - while (shift >= loop_end) { - count += CHAR_BIT; - value |= (BD_VALUE)*buffer++ << shift; - shift -= CHAR_BIT; - } - } - } - - // NOTE: Variable 'buffer' may not relate to 'r->buffer' after decryption, - // so we increase 'r->buffer' by the amount that 'buffer' moved, rather than - // assign 'buffer' to 'r->buffer'. - r->buffer += buffer - buffer_start; - r->value = value; - r->count = count; -} - -const uint8_t *vpx_reader_find_end(vpx_reader *r) { - // Find the end of the coded buffer - while (r->count > CHAR_BIT && r->count < BD_VALUE_SIZE) { - r->count -= CHAR_BIT; - r->buffer--; - } - return r->buffer; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitreader.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitreader.h deleted file mode 100644 index a5927ea2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitreader.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_BITREADER_H_ -#define VPX_VPX_DSP_BITREADER_H_ - -#include -#include -#include - -#include "./vpx_config.h" -#include "vpx_ports/mem.h" -#include "vpx/vp8dx.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/prob.h" -#if CONFIG_BITSTREAM_DEBUG -#include "vpx_util/vpx_debug_util.h" -#endif // CONFIG_BITSTREAM_DEBUG - -#ifdef __cplusplus -extern "C" { -#endif - -typedef size_t BD_VALUE; - -#define BD_VALUE_SIZE ((int)sizeof(BD_VALUE) * CHAR_BIT) - -// This is meant to be a large, positive constant that can still be efficiently -// loaded as an immediate (on platforms like ARM, for example). -// Even relatively modest values like 100 would work fine. -#define LOTS_OF_BITS 0x40000000 - -typedef struct { - // Be careful when reordering this struct, it may impact the cache negatively. - BD_VALUE value; - unsigned int range; - int count; - const uint8_t *buffer_end; - const uint8_t *buffer; - vpx_decrypt_cb decrypt_cb; - void *decrypt_state; - uint8_t clear_buffer[sizeof(BD_VALUE) + 1]; -} vpx_reader; - -int vpx_reader_init(vpx_reader *r, const uint8_t *buffer, size_t size, - vpx_decrypt_cb decrypt_cb, void *decrypt_state); - -void vpx_reader_fill(vpx_reader *r); - -const uint8_t *vpx_reader_find_end(vpx_reader *r); - -static INLINE int vpx_reader_has_error(vpx_reader *r) { - // Check if we have reached the end of the buffer. - // - // Variable 'count' stores the number of bits in the 'value' buffer, minus - // 8. The top byte is part of the algorithm, and the remainder is buffered - // to be shifted into it. So if count == 8, the top 16 bits of 'value' are - // occupied, 8 for the algorithm and 8 in the buffer. - // - // When reading a byte from the user's buffer, count is filled with 8 and - // one byte is filled into the value buffer. When we reach the end of the - // data, count is additionally filled with LOTS_OF_BITS. So when - // count == LOTS_OF_BITS - 1, the user's data has been exhausted. - // - // 1 if we have tried to decode bits after the end of stream was encountered. - // 0 No error. - return r->count > BD_VALUE_SIZE && r->count < LOTS_OF_BITS; -} - -static INLINE int vpx_read(vpx_reader *r, int prob) { - unsigned int bit = 0; - BD_VALUE value; - BD_VALUE bigsplit; - int count; - unsigned int range; - unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT; - - if (r->count < 0) vpx_reader_fill(r); - - value = r->value; - count = r->count; - - bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT); - - range = split; - - if (value >= bigsplit) { - range = r->range - split; - value = value - bigsplit; - bit = 1; - } - - { - const unsigned char shift = vpx_norm[(unsigned char)range]; - range <<= shift; - value <<= shift; - count -= shift; - } - r->value = value; - r->count = count; - r->range = range; - -#if CONFIG_BITSTREAM_DEBUG - { - const int queue_r = bitstream_queue_get_read(); - const int frame_idx = bitstream_queue_get_frame_read(); - int ref_result, ref_prob; - bitstream_queue_pop(&ref_result, &ref_prob); - if ((int)bit != ref_result) { - fprintf(stderr, - "\n *** [bit] result error, frame_idx_r %d bit %d ref_result %d " - "queue_r %d\n", - frame_idx, bit, ref_result, queue_r); - - assert(0); - } - if (prob != ref_prob) { - fprintf(stderr, - "\n *** [bit] prob error, frame_idx_r %d prob %d ref_prob %d " - "queue_r %d\n", - frame_idx, prob, ref_prob, queue_r); - - assert(0); - } - } -#endif - - return bit; -} - -static INLINE int vpx_read_bit(vpx_reader *r) { - return vpx_read(r, 128); // vpx_prob_half -} - -static INLINE int vpx_read_literal(vpx_reader *r, int bits) { - int literal = 0, bit; - - for (bit = bits - 1; bit >= 0; bit--) literal |= vpx_read_bit(r) << bit; - - return literal; -} - -static INLINE int vpx_read_tree(vpx_reader *r, const vpx_tree_index *tree, - const vpx_prob *probs) { - vpx_tree_index i = 0; - - while ((i = tree[i + vpx_read(r, probs[i >> 1])]) > 0) continue; - - return -i; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_BITREADER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitreader_buffer.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitreader_buffer.c deleted file mode 100644 index f59f1f7c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitreader_buffer.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "./vpx_config.h" -#include "./bitreader_buffer.h" - -size_t vpx_rb_bytes_read(struct vpx_read_bit_buffer *rb) { - return (rb->bit_offset + 7) >> 3; -} - -int vpx_rb_read_bit(struct vpx_read_bit_buffer *rb) { - const size_t off = rb->bit_offset; - const size_t p = off >> 3; - const int q = 7 - (int)(off & 0x7); - if (rb->bit_buffer + p < rb->bit_buffer_end) { - const int bit = (rb->bit_buffer[p] >> q) & 1; - rb->bit_offset = off + 1; - return bit; - } else { - if (rb->error_handler != NULL) rb->error_handler(rb->error_handler_data); - return 0; - } -} - -int vpx_rb_read_literal(struct vpx_read_bit_buffer *rb, int bits) { - int value = 0, bit; - for (bit = bits - 1; bit >= 0; bit--) value |= vpx_rb_read_bit(rb) << bit; - return value; -} - -int vpx_rb_read_signed_literal(struct vpx_read_bit_buffer *rb, int bits) { - const int value = vpx_rb_read_literal(rb, bits); - return vpx_rb_read_bit(rb) ? -value : value; -} - -int vpx_rb_read_inv_signed_literal(struct vpx_read_bit_buffer *rb, int bits) { - return vpx_rb_read_signed_literal(rb, bits); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitreader_buffer.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitreader_buffer.h deleted file mode 100644 index b27703a4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitreader_buffer.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_BITREADER_BUFFER_H_ -#define VPX_VPX_DSP_BITREADER_BUFFER_H_ - -#include - -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*vpx_rb_error_handler)(void *data); - -struct vpx_read_bit_buffer { - const uint8_t *bit_buffer; - const uint8_t *bit_buffer_end; - size_t bit_offset; - - void *error_handler_data; - vpx_rb_error_handler error_handler; -}; - -size_t vpx_rb_bytes_read(struct vpx_read_bit_buffer *rb); - -int vpx_rb_read_bit(struct vpx_read_bit_buffer *rb); - -int vpx_rb_read_literal(struct vpx_read_bit_buffer *rb, int bits); - -int vpx_rb_read_signed_literal(struct vpx_read_bit_buffer *rb, int bits); - -int vpx_rb_read_inv_signed_literal(struct vpx_read_bit_buffer *rb, int bits); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_BITREADER_BUFFER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitwriter.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitwriter.c deleted file mode 100644 index d3ef9bd8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitwriter.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./bitwriter.h" - -#if CONFIG_BITSTREAM_DEBUG -#include "vpx_util/vpx_debug_util.h" -#endif - -void vpx_start_encode(vpx_writer *br, uint8_t *source, size_t size) { - br->lowvalue = 0; - br->range = 255; - br->count = -24; - br->error = 0; - br->pos = 0; - // Make sure it is safe to cast br->pos to int in vpx_write(). - if (size > INT_MAX) size = INT_MAX; - br->size = (unsigned int)size; - br->buffer = source; - vpx_write_bit(br, 0); -} - -int vpx_stop_encode(vpx_writer *br) { - int i; - -#if CONFIG_BITSTREAM_DEBUG - bitstream_queue_set_skip_write(1); -#endif - for (i = 0; i < 32; i++) vpx_write_bit(br, 0); - - // Ensure there's no ambigous collision with any index marker bytes - if (!br->error && (br->buffer[br->pos - 1] & 0xe0) == 0xc0) { - if (br->pos < br->size) { - br->buffer[br->pos++] = 0; - } else { - br->error = 1; - } - } - -#if CONFIG_BITSTREAM_DEBUG - bitstream_queue_set_skip_write(0); -#endif - - return br->error ? -1 : 0; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitwriter.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitwriter.h deleted file mode 100644 index daff331d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitwriter.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_BITWRITER_H_ -#define VPX_VPX_DSP_BITWRITER_H_ - -#include - -#include "vpx_ports/compiler_attributes.h" -#include "vpx_ports/mem.h" - -#include "vpx_dsp/prob.h" -#if CONFIG_BITSTREAM_DEBUG -#include "vpx_util/vpx_debug_util.h" -#endif // CONFIG_BITSTREAM_DEBUG - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct vpx_writer { - unsigned int lowvalue; - unsigned int range; - int count; - // Whether there has been an error. - int error; - // We maintain the invariant that pos <= size, i.e., we never write beyond - // the end of the buffer. If pos would be incremented to be greater than - // size, leave pos unchanged and set error to 1. - unsigned int pos; - unsigned int size; - uint8_t *buffer; -} vpx_writer; - -void vpx_start_encode(vpx_writer *br, uint8_t *source, size_t size); -// Returns 0 on success and returns -1 in case of error. -int vpx_stop_encode(vpx_writer *br); - -static INLINE VPX_NO_UNSIGNED_SHIFT_CHECK void vpx_write(vpx_writer *br, - int bit, - int probability) { - unsigned int split; - int count = br->count; - unsigned int range = br->range; - unsigned int lowvalue = br->lowvalue; - int shift; - -#if CONFIG_BITSTREAM_DEBUG - /* - int queue_r = 0; - int frame_idx_r = 0; - int queue_w = bitstream_queue_get_write(); - int frame_idx_w = bitstream_queue_get_frame_write(); - if (frame_idx_w == frame_idx_r && queue_w == queue_r) { - fprintf(stderr, "\n *** bitstream queue at frame_idx_w %d queue_w %d\n", - frame_idx_w, queue_w); - assert(0); - } - */ - bitstream_queue_push(bit, probability); -#endif - - split = 1 + (((range - 1) * probability) >> 8); - - range = split; - - if (bit) { - lowvalue += split; - range = br->range - split; - } - - shift = vpx_norm[range]; - - range <<= shift; - count += shift; - - if (count >= 0) { - int offset = shift - count; - - if (!br->error) { - if ((lowvalue << (offset - 1)) & 0x80000000) { - int x = (int)br->pos - 1; - - while (x >= 0 && br->buffer[x] == 0xff) { - br->buffer[x] = 0; - x--; - } - - // TODO(wtc): How to prove x >= 0? - br->buffer[x] += 1; - } - - if (br->pos < br->size) { - br->buffer[br->pos++] = (lowvalue >> (24 - offset)) & 0xff; - } else { - br->error = 1; - } - } - lowvalue <<= offset; - shift = count; - lowvalue &= 0xffffff; - count -= 8; - } - - lowvalue <<= shift; - br->count = count; - br->lowvalue = lowvalue; - br->range = range; -} - -static INLINE void vpx_write_bit(vpx_writer *w, int bit) { - vpx_write(w, bit, 128); // vpx_prob_half -} - -static INLINE void vpx_write_literal(vpx_writer *w, int data, int bits) { - int bit; - - for (bit = bits - 1; bit >= 0; bit--) vpx_write_bit(w, 1 & (data >> bit)); -} - -#define vpx_write_prob(w, v) vpx_write_literal((w), (v), 8) - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_BITWRITER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitwriter_buffer.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitwriter_buffer.c deleted file mode 100644 index b3a2490f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitwriter_buffer.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "./vpx_config.h" -#include "./bitwriter_buffer.h" - -void vpx_wb_init(struct vpx_write_bit_buffer *wb, uint8_t *bit_buffer, - size_t size) { - wb->error = 0; - wb->bit_offset = 0; - wb->size = size; - wb->bit_buffer = bit_buffer; -} - -int vpx_wb_has_error(const struct vpx_write_bit_buffer *wb) { - return wb->error; -} - -size_t vpx_wb_bytes_written(const struct vpx_write_bit_buffer *wb) { - assert(!wb->error); - return wb->bit_offset / CHAR_BIT + (wb->bit_offset % CHAR_BIT > 0); -} - -void vpx_wb_write_bit(struct vpx_write_bit_buffer *wb, int bit) { - if (wb->error) return; - const int off = (int)wb->bit_offset; - const int p = off / CHAR_BIT; - const int q = CHAR_BIT - 1 - off % CHAR_BIT; - if ((size_t)p >= wb->size) { - wb->error = 1; - return; - } - if (q == CHAR_BIT - 1) { - wb->bit_buffer[p] = bit << q; - } else { - assert((wb->bit_buffer[p] & (1 << q)) == 0); - wb->bit_buffer[p] |= bit << q; - } - wb->bit_offset = off + 1; -} - -void vpx_wb_write_literal(struct vpx_write_bit_buffer *wb, int data, int bits) { - int bit; - for (bit = bits - 1; bit >= 0; bit--) vpx_wb_write_bit(wb, (data >> bit) & 1); -} - -void vpx_wb_write_inv_signed_literal(struct vpx_write_bit_buffer *wb, int data, - int bits) { - vpx_wb_write_literal(wb, abs(data), bits); - vpx_wb_write_bit(wb, data < 0); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitwriter_buffer.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitwriter_buffer.h deleted file mode 100644 index 3ee0e965..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/bitwriter_buffer.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_BITWRITER_BUFFER_H_ -#define VPX_VPX_DSP_BITWRITER_BUFFER_H_ - -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct vpx_write_bit_buffer { - // Whether there has been an error. - int error; - // We maintain the invariant that bit_offset <= size * CHAR_BIT, i.e., we - // never write beyond the end of bit_buffer. If bit_offset would be - // incremented to be greater than size * CHAR_BIT, leave bit_offset unchanged - // and set error to 1. - size_t bit_offset; - // Size of bit_buffer in bytes. - size_t size; - uint8_t *bit_buffer; -}; - -void vpx_wb_init(struct vpx_write_bit_buffer *wb, uint8_t *bit_buffer, - size_t size); - -int vpx_wb_has_error(const struct vpx_write_bit_buffer *wb); - -// Must not be called if vpx_wb_has_error(wb) returns true. -size_t vpx_wb_bytes_written(const struct vpx_write_bit_buffer *wb); - -void vpx_wb_write_bit(struct vpx_write_bit_buffer *wb, int bit); - -void vpx_wb_write_literal(struct vpx_write_bit_buffer *wb, int data, int bits); - -void vpx_wb_write_inv_signed_literal(struct vpx_write_bit_buffer *wb, int data, - int bits); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_BITWRITER_BUFFER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/deblock.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/deblock.c deleted file mode 100644 index 455b73bb..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/deblock.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" - -const int16_t vpx_rv[] = { - 8, 5, 2, 2, 8, 12, 4, 9, 8, 3, 0, 3, 9, 0, 0, 0, 8, 3, 14, - 4, 10, 1, 11, 14, 1, 14, 9, 6, 12, 11, 8, 6, 10, 0, 0, 8, 9, 0, - 3, 14, 8, 11, 13, 4, 2, 9, 0, 3, 9, 6, 1, 2, 3, 14, 13, 1, 8, - 2, 9, 7, 3, 3, 1, 13, 13, 6, 6, 5, 2, 7, 11, 9, 11, 8, 7, 3, - 2, 0, 13, 13, 14, 4, 12, 5, 12, 10, 8, 10, 13, 10, 4, 14, 4, 10, 0, - 8, 11, 1, 13, 7, 7, 14, 6, 14, 13, 2, 13, 5, 4, 4, 0, 10, 0, 5, - 13, 2, 12, 7, 11, 13, 8, 0, 4, 10, 7, 2, 7, 2, 2, 5, 3, 4, 7, - 3, 3, 14, 14, 5, 9, 13, 3, 14, 3, 6, 3, 0, 11, 8, 13, 1, 13, 1, - 12, 0, 10, 9, 7, 6, 2, 8, 5, 2, 13, 7, 1, 13, 14, 7, 6, 7, 9, - 6, 10, 11, 7, 8, 7, 5, 14, 8, 4, 4, 0, 8, 7, 10, 0, 8, 14, 11, - 3, 12, 5, 7, 14, 3, 14, 5, 2, 6, 11, 12, 12, 8, 0, 11, 13, 1, 2, - 0, 5, 10, 14, 7, 8, 0, 4, 11, 0, 8, 0, 3, 10, 5, 8, 0, 11, 6, - 7, 8, 10, 7, 13, 9, 2, 5, 1, 5, 10, 2, 4, 3, 5, 6, 10, 8, 9, - 4, 11, 14, 0, 10, 0, 5, 13, 2, 12, 7, 11, 13, 8, 0, 4, 10, 7, 2, - 7, 2, 2, 5, 3, 4, 7, 3, 3, 14, 14, 5, 9, 13, 3, 14, 3, 6, 3, - 0, 11, 8, 13, 1, 13, 1, 12, 0, 10, 9, 7, 6, 2, 8, 5, 2, 13, 7, - 1, 13, 14, 7, 6, 7, 9, 6, 10, 11, 7, 8, 7, 5, 14, 8, 4, 4, 0, - 8, 7, 10, 0, 8, 14, 11, 3, 12, 5, 7, 14, 3, 14, 5, 2, 6, 11, 12, - 12, 8, 0, 11, 13, 1, 2, 0, 5, 10, 14, 7, 8, 0, 4, 11, 0, 8, 0, - 3, 10, 5, 8, 0, 11, 6, 7, 8, 10, 7, 13, 9, 2, 5, 1, 5, 10, 2, - 4, 3, 5, 6, 10, 8, 9, 4, 11, 14, 3, 8, 3, 7, 8, 5, 11, 4, 12, - 3, 11, 9, 14, 8, 14, 13, 4, 3, 1, 2, 14, 6, 5, 4, 4, 11, 4, 6, - 2, 1, 5, 8, 8, 12, 13, 5, 14, 10, 12, 13, 0, 9, 5, 5, 11, 10, 13, - 9, 10, 13, -}; - -void vpx_post_proc_down_and_across_mb_row_c(unsigned char *src, - unsigned char *dst, int src_pitch, - int dst_pitch, int cols, - unsigned char *flimits, int size) { - unsigned char *p_src, *p_dst; - int row; - int col; - unsigned char v; - unsigned char d[4]; - - assert(size >= 8); - assert(cols >= 8); - - for (row = 0; row < size; row++) { - /* post_proc_down for one row */ - p_src = src; - p_dst = dst; - - for (col = 0; col < cols; col++) { - unsigned char p_above2 = p_src[col - 2 * src_pitch]; - unsigned char p_above1 = p_src[col - src_pitch]; - unsigned char p_below1 = p_src[col + src_pitch]; - unsigned char p_below2 = p_src[col + 2 * src_pitch]; - - v = p_src[col]; - - if ((abs(v - p_above2) < flimits[col]) && - (abs(v - p_above1) < flimits[col]) && - (abs(v - p_below1) < flimits[col]) && - (abs(v - p_below2) < flimits[col])) { - unsigned char k1, k2, k3; - k1 = (p_above2 + p_above1 + 1) >> 1; - k2 = (p_below2 + p_below1 + 1) >> 1; - k3 = (k1 + k2 + 1) >> 1; - v = (k3 + v + 1) >> 1; - } - - p_dst[col] = v; - } - - /* now post_proc_across */ - p_src = dst; - p_dst = dst; - - p_src[-2] = p_src[-1] = p_src[0]; - p_src[cols] = p_src[cols + 1] = p_src[cols - 1]; - - for (col = 0; col < cols; col++) { - v = p_src[col]; - - if ((abs(v - p_src[col - 2]) < flimits[col]) && - (abs(v - p_src[col - 1]) < flimits[col]) && - (abs(v - p_src[col + 1]) < flimits[col]) && - (abs(v - p_src[col + 2]) < flimits[col])) { - unsigned char k1, k2, k3; - k1 = (p_src[col - 2] + p_src[col - 1] + 1) >> 1; - k2 = (p_src[col + 2] + p_src[col + 1] + 1) >> 1; - k3 = (k1 + k2 + 1) >> 1; - v = (k3 + v + 1) >> 1; - } - - d[col & 3] = v; - - if (col >= 2) p_dst[col - 2] = d[(col - 2) & 3]; - } - - /* handle the last two pixels */ - p_dst[col - 2] = d[(col - 2) & 3]; - p_dst[col - 1] = d[(col - 1) & 3]; - - /* next row */ - src += src_pitch; - dst += dst_pitch; - } -} - -void vpx_mbpost_proc_across_ip_c(unsigned char *src, int pitch, int rows, - int cols, int flimit) { - int r, c, i; - - unsigned char *s = src; - unsigned char d[16]; - - for (r = 0; r < rows; r++) { - int sumsq = 16; - int sum = 0; - - for (i = -8; i < 0; i++) s[i] = s[0]; - - /* 17 avoids valgrind warning - we buffer values in c in d - * and only write them when we've read 8 ahead... - */ - for (i = 0; i < 17; i++) s[i + cols] = s[cols - 1]; - - for (i = -8; i <= 6; i++) { - sumsq += s[i] * s[i]; - sum += s[i]; - d[i + 8] = 0; - } - - for (c = 0; c < cols + 8; c++) { - int x = s[c + 7] - s[c - 8]; - int y = s[c + 7] + s[c - 8]; - - sum += x; - sumsq += x * y; - - d[c & 15] = s[c]; - - if (sumsq * 15 - sum * sum < flimit) { - d[c & 15] = (8 + sum + s[c]) >> 4; - } - - s[c - 8] = d[(c - 8) & 15]; - } - - s += pitch; - } -} - -void vpx_mbpost_proc_down_c(unsigned char *dst, int pitch, int rows, int cols, - int flimit) { - int r, c, i; - - for (c = 0; c < cols; c++) { - unsigned char *s = &dst[c]; - int sumsq = 0; - int sum = 0; - unsigned char d[16]; - - for (i = -8; i < 0; i++) s[i * pitch] = s[0]; - - /* 17 avoids valgrind warning - we buffer values in c in d - * and only write them when we've read 8 ahead... - */ - for (i = 0; i < 17; i++) s[(i + rows) * pitch] = s[(rows - 1) * pitch]; - - for (i = -8; i <= 6; i++) { - sumsq += s[i * pitch] * s[i * pitch]; - sum += s[i * pitch]; - } - - for (r = 0; r < rows + 8; r++) { - sumsq += s[7 * pitch] * s[7 * pitch] - s[-8 * pitch] * s[-8 * pitch]; - sum += s[7 * pitch] - s[-8 * pitch]; - d[r & 15] = s[0]; - - if (sumsq * 15 - sum * sum < flimit) { - d[r & 15] = (vpx_rv[(r & 127) + (c & 7)] + sum + s[0]) >> 4; - } - if (r >= 8) s[-8 * pitch] = d[(r - 8) & 15]; - s += pitch; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/fastssim.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/fastssim.c deleted file mode 100644 index 4d32a02a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/fastssim.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - * - * This code was originally written by: Nathan E. Egge, at the Daala - * project. - */ -#include -#include -#include -#include -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/ssim.h" -#include "vpx_ports/system_state.h" - -typedef struct fs_level fs_level; -typedef struct fs_ctx fs_ctx; - -#define SSIM_C1 (255 * 255 * 0.01 * 0.01) -#define SSIM_C2 (255 * 255 * 0.03 * 0.03) -#if CONFIG_VP9_HIGHBITDEPTH -#define SSIM_C1_10 (1023 * 1023 * 0.01 * 0.01) -#define SSIM_C1_12 (4095 * 4095 * 0.01 * 0.01) -#define SSIM_C2_10 (1023 * 1023 * 0.03 * 0.03) -#define SSIM_C2_12 (4095 * 4095 * 0.03 * 0.03) -#endif -#define FS_MINI(_a, _b) ((_a) < (_b) ? (_a) : (_b)) -#define FS_MAXI(_a, _b) ((_a) > (_b) ? (_a) : (_b)) - -struct fs_level { - uint32_t *im1; - uint32_t *im2; - double *ssim; - int w; - int h; -}; - -struct fs_ctx { - fs_level *level; - int nlevels; - unsigned *col_buf; -}; - -static int fs_ctx_init(fs_ctx *_ctx, int _w, int _h, int _nlevels) { - unsigned char *data; - size_t data_size; - int lw; - int lh; - int l; - lw = (_w + 1) >> 1; - lh = (_h + 1) >> 1; - data_size = - _nlevels * sizeof(fs_level) + 2 * (lw + 8) * 8 * sizeof(*_ctx->col_buf); - for (l = 0; l < _nlevels; l++) { - size_t im_size; - size_t level_size; - im_size = lw * (size_t)lh; - level_size = 2 * im_size * sizeof(*_ctx->level[l].im1); - level_size += sizeof(*_ctx->level[l].ssim) - 1; - level_size /= sizeof(*_ctx->level[l].ssim); - level_size += im_size; - level_size *= sizeof(*_ctx->level[l].ssim); - data_size += level_size; - lw = (lw + 1) >> 1; - lh = (lh + 1) >> 1; - } - data = (unsigned char *)malloc(data_size); - if (!data) return -1; - _ctx->level = (fs_level *)data; - _ctx->nlevels = _nlevels; - data += _nlevels * sizeof(*_ctx->level); - lw = (_w + 1) >> 1; - lh = (_h + 1) >> 1; - for (l = 0; l < _nlevels; l++) { - size_t im_size; - size_t level_size; - _ctx->level[l].w = lw; - _ctx->level[l].h = lh; - im_size = lw * (size_t)lh; - level_size = 2 * im_size * sizeof(*_ctx->level[l].im1); - level_size += sizeof(*_ctx->level[l].ssim) - 1; - level_size /= sizeof(*_ctx->level[l].ssim); - level_size *= sizeof(*_ctx->level[l].ssim); - _ctx->level[l].im1 = (uint32_t *)data; - _ctx->level[l].im2 = _ctx->level[l].im1 + im_size; - data += level_size; - _ctx->level[l].ssim = (double *)data; - data += im_size * sizeof(*_ctx->level[l].ssim); - lw = (lw + 1) >> 1; - lh = (lh + 1) >> 1; - } - _ctx->col_buf = (unsigned *)data; - return 0; -} - -static void fs_ctx_clear(fs_ctx *_ctx) { free(_ctx->level); } - -static void fs_downsample_level(fs_ctx *_ctx, int _l) { - const uint32_t *src1; - const uint32_t *src2; - uint32_t *dst1; - uint32_t *dst2; - int w2; - int h2; - int w; - int h; - int i; - int j; - w = _ctx->level[_l].w; - h = _ctx->level[_l].h; - dst1 = _ctx->level[_l].im1; - dst2 = _ctx->level[_l].im2; - w2 = _ctx->level[_l - 1].w; - h2 = _ctx->level[_l - 1].h; - src1 = _ctx->level[_l - 1].im1; - src2 = _ctx->level[_l - 1].im2; - for (j = 0; j < h; j++) { - int j0offs; - int j1offs; - j0offs = 2 * j * w2; - j1offs = FS_MINI(2 * j + 1, h2) * w2; - for (i = 0; i < w; i++) { - int i0; - int i1; - i0 = 2 * i; - i1 = FS_MINI(i0 + 1, w2); - dst1[j * w + i] = - (uint32_t)((int64_t)src1[j0offs + i0] + src1[j0offs + i1] + - src1[j1offs + i0] + src1[j1offs + i1]); - dst2[j * w + i] = - (uint32_t)((int64_t)src2[j0offs + i0] + src2[j0offs + i1] + - src2[j1offs + i0] + src2[j1offs + i1]); - } - } -} - -static void fs_downsample_level0(fs_ctx *_ctx, const uint8_t *_src1, - int _s1ystride, const uint8_t *_src2, - int _s2ystride, int _w, int _h, uint32_t bd, - uint32_t shift) { - uint32_t *dst1; - uint32_t *dst2; - int w; - int h; - int i; - int j; - w = _ctx->level[0].w; - h = _ctx->level[0].h; - dst1 = _ctx->level[0].im1; - dst2 = _ctx->level[0].im2; - for (j = 0; j < h; j++) { - int j0; - int j1; - j0 = 2 * j; - j1 = FS_MINI(j0 + 1, _h); - for (i = 0; i < w; i++) { - int i0; - int i1; - i0 = 2 * i; - i1 = FS_MINI(i0 + 1, _w); - if (bd == 8 && shift == 0) { - dst1[j * w + i] = - _src1[j0 * _s1ystride + i0] + _src1[j0 * _s1ystride + i1] + - _src1[j1 * _s1ystride + i0] + _src1[j1 * _s1ystride + i1]; - dst2[j * w + i] = - _src2[j0 * _s2ystride + i0] + _src2[j0 * _s2ystride + i1] + - _src2[j1 * _s2ystride + i0] + _src2[j1 * _s2ystride + i1]; - } else { - uint16_t *src1s = CONVERT_TO_SHORTPTR(_src1); - uint16_t *src2s = CONVERT_TO_SHORTPTR(_src2); - dst1[j * w + i] = (src1s[j0 * _s1ystride + i0] >> shift) + - (src1s[j0 * _s1ystride + i1] >> shift) + - (src1s[j1 * _s1ystride + i0] >> shift) + - (src1s[j1 * _s1ystride + i1] >> shift); - dst2[j * w + i] = (src2s[j0 * _s2ystride + i0] >> shift) + - (src2s[j0 * _s2ystride + i1] >> shift) + - (src2s[j1 * _s2ystride + i0] >> shift) + - (src2s[j1 * _s2ystride + i1] >> shift); - } - } - } -} - -static void fs_apply_luminance(fs_ctx *_ctx, int _l, int bit_depth) { - unsigned *col_sums_x; - unsigned *col_sums_y; - uint32_t *im1; - uint32_t *im2; - double *ssim; - double c1; - int w; - int h; - int j0offs; - int j1offs; - int i; - int j; - double ssim_c1 = SSIM_C1; -#if CONFIG_VP9_HIGHBITDEPTH - if (bit_depth == 10) ssim_c1 = SSIM_C1_10; - if (bit_depth == 12) ssim_c1 = SSIM_C1_12; -#else - assert(bit_depth == 8); - (void)bit_depth; -#endif - w = _ctx->level[_l].w; - h = _ctx->level[_l].h; - col_sums_x = _ctx->col_buf; - col_sums_y = col_sums_x + w; - im1 = _ctx->level[_l].im1; - im2 = _ctx->level[_l].im2; - for (i = 0; i < w; i++) col_sums_x[i] = 5 * im1[i]; - for (i = 0; i < w; i++) col_sums_y[i] = 5 * im2[i]; - for (j = 1; j < 4; j++) { - j1offs = FS_MINI(j, h - 1) * w; - for (i = 0; i < w; i++) col_sums_x[i] += im1[j1offs + i]; - for (i = 0; i < w; i++) col_sums_y[i] += im2[j1offs + i]; - } - ssim = _ctx->level[_l].ssim; - c1 = (double)(ssim_c1 * 4096 * (1 << 4 * _l)); - for (j = 0; j < h; j++) { - int64_t mux; - int64_t muy; - int i0; - int i1; - mux = (int64_t)5 * col_sums_x[0]; - muy = (int64_t)5 * col_sums_y[0]; - for (i = 1; i < 4; i++) { - i1 = FS_MINI(i, w - 1); - mux += col_sums_x[i1]; - muy += col_sums_y[i1]; - } - for (i = 0; i < w; i++) { - ssim[j * w + i] *= (2 * mux * (double)muy + c1) / - (mux * (double)mux + muy * (double)muy + c1); - if (i + 1 < w) { - i0 = FS_MAXI(0, i - 4); - i1 = FS_MINI(i + 4, w - 1); - mux += (int)col_sums_x[i1] - (int)col_sums_x[i0]; - muy += (int)col_sums_x[i1] - (int)col_sums_x[i0]; - } - } - if (j + 1 < h) { - j0offs = FS_MAXI(0, j - 4) * w; - for (i = 0; i < w; i++) col_sums_x[i] -= im1[j0offs + i]; - for (i = 0; i < w; i++) col_sums_y[i] -= im2[j0offs + i]; - j1offs = FS_MINI(j + 4, h - 1) * w; - for (i = 0; i < w; i++) - col_sums_x[i] = (uint32_t)((int64_t)col_sums_x[i] + im1[j1offs + i]); - for (i = 0; i < w; i++) - col_sums_y[i] = (uint32_t)((int64_t)col_sums_y[i] + im2[j1offs + i]); - } - } -} - -#define FS_COL_SET(_col, _joffs, _ioffs) \ - do { \ - unsigned gx; \ - unsigned gy; \ - gx = gx_buf[((j + (_joffs)) & 7) * stride + i + (_ioffs)]; \ - gy = gy_buf[((j + (_joffs)) & 7) * stride + i + (_ioffs)]; \ - col_sums_gx2[(_col)] = gx * (double)gx; \ - col_sums_gy2[(_col)] = gy * (double)gy; \ - col_sums_gxgy[(_col)] = gx * (double)gy; \ - } while (0) - -#define FS_COL_ADD(_col, _joffs, _ioffs) \ - do { \ - unsigned gx; \ - unsigned gy; \ - gx = gx_buf[((j + (_joffs)) & 7) * stride + i + (_ioffs)]; \ - gy = gy_buf[((j + (_joffs)) & 7) * stride + i + (_ioffs)]; \ - col_sums_gx2[(_col)] += gx * (double)gx; \ - col_sums_gy2[(_col)] += gy * (double)gy; \ - col_sums_gxgy[(_col)] += gx * (double)gy; \ - } while (0) - -#define FS_COL_SUB(_col, _joffs, _ioffs) \ - do { \ - unsigned gx; \ - unsigned gy; \ - gx = gx_buf[((j + (_joffs)) & 7) * stride + i + (_ioffs)]; \ - gy = gy_buf[((j + (_joffs)) & 7) * stride + i + (_ioffs)]; \ - col_sums_gx2[(_col)] -= gx * (double)gx; \ - col_sums_gy2[(_col)] -= gy * (double)gy; \ - col_sums_gxgy[(_col)] -= gx * (double)gy; \ - } while (0) - -#define FS_COL_COPY(_col1, _col2) \ - do { \ - col_sums_gx2[(_col1)] = col_sums_gx2[(_col2)]; \ - col_sums_gy2[(_col1)] = col_sums_gy2[(_col2)]; \ - col_sums_gxgy[(_col1)] = col_sums_gxgy[(_col2)]; \ - } while (0) - -#define FS_COL_HALVE(_col1, _col2) \ - do { \ - col_sums_gx2[(_col1)] = col_sums_gx2[(_col2)] * 0.5; \ - col_sums_gy2[(_col1)] = col_sums_gy2[(_col2)] * 0.5; \ - col_sums_gxgy[(_col1)] = col_sums_gxgy[(_col2)] * 0.5; \ - } while (0) - -#define FS_COL_DOUBLE(_col1, _col2) \ - do { \ - col_sums_gx2[(_col1)] = col_sums_gx2[(_col2)] * 2; \ - col_sums_gy2[(_col1)] = col_sums_gy2[(_col2)] * 2; \ - col_sums_gxgy[(_col1)] = col_sums_gxgy[(_col2)] * 2; \ - } while (0) - -static void fs_calc_structure(fs_ctx *_ctx, int _l, int bit_depth) { - uint32_t *im1; - uint32_t *im2; - unsigned *gx_buf; - unsigned *gy_buf; - double *ssim; - double col_sums_gx2[8]; - double col_sums_gy2[8]; - double col_sums_gxgy[8]; - double c2; - int stride; - int w; - int h; - int i; - int j; - double ssim_c2 = SSIM_C2; -#if CONFIG_VP9_HIGHBITDEPTH - if (bit_depth == 10) ssim_c2 = SSIM_C2_10; - if (bit_depth == 12) ssim_c2 = SSIM_C2_12; -#else - assert(bit_depth == 8); - (void)bit_depth; -#endif - - w = _ctx->level[_l].w; - h = _ctx->level[_l].h; - im1 = _ctx->level[_l].im1; - im2 = _ctx->level[_l].im2; - ssim = _ctx->level[_l].ssim; - gx_buf = _ctx->col_buf; - stride = w + 8; - gy_buf = gx_buf + 8 * stride; - memset(gx_buf, 0, 2 * 8 * stride * sizeof(*gx_buf)); - c2 = ssim_c2 * (1 << 4 * _l) * 16 * 104; - for (j = 0; j < h + 4; j++) { - if (j < h - 1) { - for (i = 0; i < w - 1; i++) { - int64_t g1; - int64_t g2; - int64_t gx; - int64_t gy; - g1 = labs((int64_t)im1[(j + 1) * w + i + 1] - (int64_t)im1[j * w + i]); - g2 = labs((int64_t)im1[(j + 1) * w + i] - (int64_t)im1[j * w + i + 1]); - gx = 4 * FS_MAXI(g1, g2) + FS_MINI(g1, g2); - g1 = labs((int64_t)im2[(j + 1) * w + i + 1] - (int64_t)im2[j * w + i]); - g2 = labs((int64_t)im2[(j + 1) * w + i] - (int64_t)im2[j * w + i + 1]); - gy = ((int64_t)4 * FS_MAXI(g1, g2) + FS_MINI(g1, g2)); - gx_buf[(j & 7) * stride + i + 4] = (uint32_t)gx; - gy_buf[(j & 7) * stride + i + 4] = (uint32_t)gy; - } - } else { - memset(gx_buf + (j & 7) * stride, 0, stride * sizeof(*gx_buf)); - memset(gy_buf + (j & 7) * stride, 0, stride * sizeof(*gy_buf)); - } - if (j >= 4) { - int k; - col_sums_gx2[3] = col_sums_gx2[2] = col_sums_gx2[1] = col_sums_gx2[0] = 0; - col_sums_gy2[3] = col_sums_gy2[2] = col_sums_gy2[1] = col_sums_gy2[0] = 0; - col_sums_gxgy[3] = col_sums_gxgy[2] = col_sums_gxgy[1] = - col_sums_gxgy[0] = 0; - for (i = 4; i < 8; i++) { - FS_COL_SET(i, -1, 0); - FS_COL_ADD(i, 0, 0); - for (k = 1; k < 8 - i; k++) { - FS_COL_DOUBLE(i, i); - FS_COL_ADD(i, -k - 1, 0); - FS_COL_ADD(i, k, 0); - } - } - for (i = 0; i < w; i++) { - double mugx2; - double mugy2; - double mugxgy; - mugx2 = col_sums_gx2[0]; - for (k = 1; k < 8; k++) mugx2 += col_sums_gx2[k]; - mugy2 = col_sums_gy2[0]; - for (k = 1; k < 8; k++) mugy2 += col_sums_gy2[k]; - mugxgy = col_sums_gxgy[0]; - for (k = 1; k < 8; k++) mugxgy += col_sums_gxgy[k]; - ssim[(j - 4) * w + i] = (2 * mugxgy + c2) / (mugx2 + mugy2 + c2); - if (i + 1 < w) { - FS_COL_SET(0, -1, 1); - FS_COL_ADD(0, 0, 1); - FS_COL_SUB(2, -3, 2); - FS_COL_SUB(2, 2, 2); - FS_COL_HALVE(1, 2); - FS_COL_SUB(3, -4, 3); - FS_COL_SUB(3, 3, 3); - FS_COL_HALVE(2, 3); - FS_COL_COPY(3, 4); - FS_COL_DOUBLE(4, 5); - FS_COL_ADD(4, -4, 5); - FS_COL_ADD(4, 3, 5); - FS_COL_DOUBLE(5, 6); - FS_COL_ADD(5, -3, 6); - FS_COL_ADD(5, 2, 6); - FS_COL_DOUBLE(6, 7); - FS_COL_ADD(6, -2, 7); - FS_COL_ADD(6, 1, 7); - FS_COL_SET(7, -1, 8); - FS_COL_ADD(7, 0, 8); - } - } - } - } -} - -#define FS_NLEVELS (4) - -/*These weights were derived from the default weights found in Wang's original - Matlab implementation: {0.0448, 0.2856, 0.2363, 0.1333}. - We drop the finest scale and renormalize the rest to sum to 1.*/ - -static const double FS_WEIGHTS[FS_NLEVELS] = { - 0.2989654541015625, 0.3141326904296875, 0.2473602294921875, 0.1395416259765625 -}; - -static double fs_average(fs_ctx *_ctx, int _l) { - double *ssim; - double ret; - int w; - int h; - int i; - int j; - w = _ctx->level[_l].w; - h = _ctx->level[_l].h; - ssim = _ctx->level[_l].ssim; - ret = 0; - for (j = 0; j < h; j++) - for (i = 0; i < w; i++) ret += ssim[j * w + i]; - return pow(ret / (w * h), FS_WEIGHTS[_l]); -} - -static double convert_ssim_db(double _ssim, double _weight) { - assert(_weight >= _ssim); - if ((_weight - _ssim) < 1e-10) return MAX_SSIM_DB; - return 10 * (log10(_weight) - log10(_weight - _ssim)); -} - -static double calc_ssim(const uint8_t *_src, int _systride, const uint8_t *_dst, - int _dystride, int _w, int _h, uint32_t _bd, - uint32_t _shift) { - fs_ctx ctx; - double ret; - int l; - ret = 1; - if (fs_ctx_init(&ctx, _w, _h, FS_NLEVELS)) return 99.0; - fs_downsample_level0(&ctx, _src, _systride, _dst, _dystride, _w, _h, _bd, - _shift); - for (l = 0; l < FS_NLEVELS - 1; l++) { - fs_calc_structure(&ctx, l, _bd); - ret *= fs_average(&ctx, l); - fs_downsample_level(&ctx, l + 1); - } - fs_calc_structure(&ctx, l, _bd); - fs_apply_luminance(&ctx, l, _bd); - ret *= fs_average(&ctx, l); - fs_ctx_clear(&ctx); - return ret; -} - -double vpx_calc_fastssim(const YV12_BUFFER_CONFIG *source, - const YV12_BUFFER_CONFIG *dest, double *ssim_y, - double *ssim_u, double *ssim_v, uint32_t bd, - uint32_t in_bd) { - double ssimv; - uint32_t bd_shift = 0; - vpx_clear_system_state(); - assert(bd >= in_bd); - bd_shift = bd - in_bd; - - *ssim_y = calc_ssim(source->y_buffer, source->y_stride, dest->y_buffer, - dest->y_stride, source->y_crop_width, - source->y_crop_height, in_bd, bd_shift); - *ssim_u = calc_ssim(source->u_buffer, source->uv_stride, dest->u_buffer, - dest->uv_stride, source->uv_crop_width, - source->uv_crop_height, in_bd, bd_shift); - *ssim_v = calc_ssim(source->v_buffer, source->uv_stride, dest->v_buffer, - dest->uv_stride, source->uv_crop_width, - source->uv_crop_height, in_bd, bd_shift); - - ssimv = (*ssim_y) * .8 + .1 * ((*ssim_u) + (*ssim_v)); - return convert_ssim_db(ssimv, 1.0); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/fwd_txfm.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/fwd_txfm.c deleted file mode 100644 index ef66de02..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/fwd_txfm.c +++ /dev/null @@ -1,809 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/fwd_txfm.h" - -void vpx_fdct4x4_c(const int16_t *input, tran_low_t *output, int stride) { - // The 2D transform is done with two passes which are actually pretty - // similar. In the first one, we transform the columns and transpose - // the results. In the second one, we transform the rows. To achieve that, - // as the first pass results are transposed, we transpose the columns (that - // is the transposed rows) and transpose the results (so that it goes back - // in normal/row positions). - int pass; - // We need an intermediate buffer between passes. - tran_low_t intermediate[4 * 4]; - const tran_low_t *in_low = NULL; - tran_low_t *out = intermediate; - // Do the two transform/transpose passes - for (pass = 0; pass < 2; ++pass) { - tran_high_t in_high[4]; // canbe16 - tran_high_t step[4]; // canbe16 - tran_high_t temp1, temp2; // needs32 - int i; - for (i = 0; i < 4; ++i) { - // Load inputs. - if (pass == 0) { - in_high[0] = input[0 * stride] * 16; - in_high[1] = input[1 * stride] * 16; - in_high[2] = input[2 * stride] * 16; - in_high[3] = input[3 * stride] * 16; - if (i == 0 && in_high[0]) { - ++in_high[0]; - } - } else { - assert(in_low != NULL); - in_high[0] = in_low[0 * 4]; - in_high[1] = in_low[1 * 4]; - in_high[2] = in_low[2 * 4]; - in_high[3] = in_low[3 * 4]; - ++in_low; - } - // Transform. - step[0] = in_high[0] + in_high[3]; - step[1] = in_high[1] + in_high[2]; - step[2] = in_high[1] - in_high[2]; - step[3] = in_high[0] - in_high[3]; - temp1 = (step[0] + step[1]) * cospi_16_64; - temp2 = (step[0] - step[1]) * cospi_16_64; - out[0] = (tran_low_t)fdct_round_shift(temp1); - out[2] = (tran_low_t)fdct_round_shift(temp2); - temp1 = step[2] * cospi_24_64 + step[3] * cospi_8_64; - temp2 = -step[2] * cospi_8_64 + step[3] * cospi_24_64; - out[1] = (tran_low_t)fdct_round_shift(temp1); - out[3] = (tran_low_t)fdct_round_shift(temp2); - // Do next column (which is a transposed row in second/horizontal pass) - ++input; - out += 4; - } - // Setup in/out for next pass. - in_low = intermediate; - out = output; - } - - { - int i, j; - for (i = 0; i < 4; ++i) { - for (j = 0; j < 4; ++j) output[j + i * 4] = (output[j + i * 4] + 1) >> 2; - } - } -} - -void vpx_fdct4x4_1_c(const int16_t *input, tran_low_t *output, int stride) { - int r, c; - tran_low_t sum = 0; - for (r = 0; r < 4; ++r) - for (c = 0; c < 4; ++c) sum += input[r * stride + c]; - - output[0] = sum * 2; -} - -void vpx_fdct8x8_c(const int16_t *input, tran_low_t *output, int stride) { - int i, j; - tran_low_t intermediate[64]; - int pass; - tran_low_t *out = intermediate; - const tran_low_t *in = NULL; - - // Transform columns - for (pass = 0; pass < 2; ++pass) { - tran_high_t s0, s1, s2, s3, s4, s5, s6, s7; // canbe16 - tran_high_t t0, t1, t2, t3; // needs32 - tran_high_t x0, x1, x2, x3; // canbe16 - - for (i = 0; i < 8; i++) { - // stage 1 - if (pass == 0) { - s0 = (input[0 * stride] + input[7 * stride]) * 4; - s1 = (input[1 * stride] + input[6 * stride]) * 4; - s2 = (input[2 * stride] + input[5 * stride]) * 4; - s3 = (input[3 * stride] + input[4 * stride]) * 4; - s4 = (input[3 * stride] - input[4 * stride]) * 4; - s5 = (input[2 * stride] - input[5 * stride]) * 4; - s6 = (input[1 * stride] - input[6 * stride]) * 4; - s7 = (input[0 * stride] - input[7 * stride]) * 4; - ++input; - } else { - s0 = in[0 * 8] + in[7 * 8]; - s1 = in[1 * 8] + in[6 * 8]; - s2 = in[2 * 8] + in[5 * 8]; - s3 = in[3 * 8] + in[4 * 8]; - s4 = in[3 * 8] - in[4 * 8]; - s5 = in[2 * 8] - in[5 * 8]; - s6 = in[1 * 8] - in[6 * 8]; - s7 = in[0 * 8] - in[7 * 8]; - ++in; - } - - // fdct4(step, step); - x0 = s0 + s3; - x1 = s1 + s2; - x2 = s1 - s2; - x3 = s0 - s3; - t0 = (x0 + x1) * cospi_16_64; - t1 = (x0 - x1) * cospi_16_64; - t2 = x2 * cospi_24_64 + x3 * cospi_8_64; - t3 = -x2 * cospi_8_64 + x3 * cospi_24_64; - out[0] = (tran_low_t)fdct_round_shift(t0); - out[2] = (tran_low_t)fdct_round_shift(t2); - out[4] = (tran_low_t)fdct_round_shift(t1); - out[6] = (tran_low_t)fdct_round_shift(t3); - - // Stage 2 - t0 = (s6 - s5) * cospi_16_64; - t1 = (s6 + s5) * cospi_16_64; - t2 = fdct_round_shift(t0); - t3 = fdct_round_shift(t1); - - // Stage 3 - x0 = s4 + t2; - x1 = s4 - t2; - x2 = s7 - t3; - x3 = s7 + t3; - - // Stage 4 - t0 = x0 * cospi_28_64 + x3 * cospi_4_64; - t1 = x1 * cospi_12_64 + x2 * cospi_20_64; - t2 = x2 * cospi_12_64 + x1 * -cospi_20_64; - t3 = x3 * cospi_28_64 + x0 * -cospi_4_64; - out[1] = (tran_low_t)fdct_round_shift(t0); - out[3] = (tran_low_t)fdct_round_shift(t2); - out[5] = (tran_low_t)fdct_round_shift(t1); - out[7] = (tran_low_t)fdct_round_shift(t3); - out += 8; - } - in = intermediate; - out = output; - } - - // Rows - for (i = 0; i < 8; ++i) { - for (j = 0; j < 8; ++j) output[j + i * 8] /= 2; - } -} - -void vpx_fdct8x8_1_c(const int16_t *input, tran_low_t *output, int stride) { - int r, c; - tran_low_t sum = 0; - for (r = 0; r < 8; ++r) - for (c = 0; c < 8; ++c) sum += input[r * stride + c]; - - output[0] = sum; -} - -void vpx_fdct16x16_c(const int16_t *input, tran_low_t *output, int stride) { - // The 2D transform is done with two passes which are actually pretty - // similar. In the first one, we transform the columns and transpose - // the results. In the second one, we transform the rows. To achieve that, - // as the first pass results are transposed, we transpose the columns (that - // is the transposed rows) and transpose the results (so that it goes back - // in normal/row positions). - int pass; - // We need an intermediate buffer between passes. - tran_low_t intermediate[256]; - const tran_low_t *in_low = NULL; - tran_low_t *out = intermediate; - // Do the two transform/transpose passes - for (pass = 0; pass < 2; ++pass) { - tran_high_t step1[8]; // canbe16 - tran_high_t step2[8]; // canbe16 - tran_high_t step3[8]; // canbe16 - tran_high_t in_high[8]; // canbe16 - tran_high_t temp1, temp2; // needs32 - int i; - for (i = 0; i < 16; i++) { - if (0 == pass) { - // Calculate input for the first 8 results. - in_high[0] = (input[0 * stride] + input[15 * stride]) * 4; - in_high[1] = (input[1 * stride] + input[14 * stride]) * 4; - in_high[2] = (input[2 * stride] + input[13 * stride]) * 4; - in_high[3] = (input[3 * stride] + input[12 * stride]) * 4; - in_high[4] = (input[4 * stride] + input[11 * stride]) * 4; - in_high[5] = (input[5 * stride] + input[10 * stride]) * 4; - in_high[6] = (input[6 * stride] + input[9 * stride]) * 4; - in_high[7] = (input[7 * stride] + input[8 * stride]) * 4; - // Calculate input for the next 8 results. - step1[0] = (input[7 * stride] - input[8 * stride]) * 4; - step1[1] = (input[6 * stride] - input[9 * stride]) * 4; - step1[2] = (input[5 * stride] - input[10 * stride]) * 4; - step1[3] = (input[4 * stride] - input[11 * stride]) * 4; - step1[4] = (input[3 * stride] - input[12 * stride]) * 4; - step1[5] = (input[2 * stride] - input[13 * stride]) * 4; - step1[6] = (input[1 * stride] - input[14 * stride]) * 4; - step1[7] = (input[0 * stride] - input[15 * stride]) * 4; - } else { - // Calculate input for the first 8 results. - assert(in_low != NULL); - in_high[0] = ((in_low[0 * 16] + 1) >> 2) + ((in_low[15 * 16] + 1) >> 2); - in_high[1] = ((in_low[1 * 16] + 1) >> 2) + ((in_low[14 * 16] + 1) >> 2); - in_high[2] = ((in_low[2 * 16] + 1) >> 2) + ((in_low[13 * 16] + 1) >> 2); - in_high[3] = ((in_low[3 * 16] + 1) >> 2) + ((in_low[12 * 16] + 1) >> 2); - in_high[4] = ((in_low[4 * 16] + 1) >> 2) + ((in_low[11 * 16] + 1) >> 2); - in_high[5] = ((in_low[5 * 16] + 1) >> 2) + ((in_low[10 * 16] + 1) >> 2); - in_high[6] = ((in_low[6 * 16] + 1) >> 2) + ((in_low[9 * 16] + 1) >> 2); - in_high[7] = ((in_low[7 * 16] + 1) >> 2) + ((in_low[8 * 16] + 1) >> 2); - // Calculate input for the next 8 results. - step1[0] = ((in_low[7 * 16] + 1) >> 2) - ((in_low[8 * 16] + 1) >> 2); - step1[1] = ((in_low[6 * 16] + 1) >> 2) - ((in_low[9 * 16] + 1) >> 2); - step1[2] = ((in_low[5 * 16] + 1) >> 2) - ((in_low[10 * 16] + 1) >> 2); - step1[3] = ((in_low[4 * 16] + 1) >> 2) - ((in_low[11 * 16] + 1) >> 2); - step1[4] = ((in_low[3 * 16] + 1) >> 2) - ((in_low[12 * 16] + 1) >> 2); - step1[5] = ((in_low[2 * 16] + 1) >> 2) - ((in_low[13 * 16] + 1) >> 2); - step1[6] = ((in_low[1 * 16] + 1) >> 2) - ((in_low[14 * 16] + 1) >> 2); - step1[7] = ((in_low[0 * 16] + 1) >> 2) - ((in_low[15 * 16] + 1) >> 2); - in_low++; - } - // Work on the first eight values; fdct8(input, even_results); - { - tran_high_t s0, s1, s2, s3, s4, s5, s6, s7; // canbe16 - tran_high_t t0, t1, t2, t3; // needs32 - tran_high_t x0, x1, x2, x3; // canbe16 - - // stage 1 - s0 = in_high[0] + in_high[7]; - s1 = in_high[1] + in_high[6]; - s2 = in_high[2] + in_high[5]; - s3 = in_high[3] + in_high[4]; - s4 = in_high[3] - in_high[4]; - s5 = in_high[2] - in_high[5]; - s6 = in_high[1] - in_high[6]; - s7 = in_high[0] - in_high[7]; - - // fdct4(step, step); - x0 = s0 + s3; - x1 = s1 + s2; - x2 = s1 - s2; - x3 = s0 - s3; - t0 = (x0 + x1) * cospi_16_64; - t1 = (x0 - x1) * cospi_16_64; - t2 = x3 * cospi_8_64 + x2 * cospi_24_64; - t3 = x3 * cospi_24_64 - x2 * cospi_8_64; - out[0] = (tran_low_t)fdct_round_shift(t0); - out[4] = (tran_low_t)fdct_round_shift(t2); - out[8] = (tran_low_t)fdct_round_shift(t1); - out[12] = (tran_low_t)fdct_round_shift(t3); - - // Stage 2 - t0 = (s6 - s5) * cospi_16_64; - t1 = (s6 + s5) * cospi_16_64; - t2 = fdct_round_shift(t0); - t3 = fdct_round_shift(t1); - - // Stage 3 - x0 = s4 + t2; - x1 = s4 - t2; - x2 = s7 - t3; - x3 = s7 + t3; - - // Stage 4 - t0 = x0 * cospi_28_64 + x3 * cospi_4_64; - t1 = x1 * cospi_12_64 + x2 * cospi_20_64; - t2 = x2 * cospi_12_64 + x1 * -cospi_20_64; - t3 = x3 * cospi_28_64 + x0 * -cospi_4_64; - out[2] = (tran_low_t)fdct_round_shift(t0); - out[6] = (tran_low_t)fdct_round_shift(t2); - out[10] = (tran_low_t)fdct_round_shift(t1); - out[14] = (tran_low_t)fdct_round_shift(t3); - } - // Work on the next eight values; step1 -> odd_results - { - // step 2 - temp1 = (step1[5] - step1[2]) * cospi_16_64; - temp2 = (step1[4] - step1[3]) * cospi_16_64; - step2[2] = fdct_round_shift(temp1); - step2[3] = fdct_round_shift(temp2); - temp1 = (step1[4] + step1[3]) * cospi_16_64; - temp2 = (step1[5] + step1[2]) * cospi_16_64; - step2[4] = fdct_round_shift(temp1); - step2[5] = fdct_round_shift(temp2); - // step 3 - step3[0] = step1[0] + step2[3]; - step3[1] = step1[1] + step2[2]; - step3[2] = step1[1] - step2[2]; - step3[3] = step1[0] - step2[3]; - step3[4] = step1[7] - step2[4]; - step3[5] = step1[6] - step2[5]; - step3[6] = step1[6] + step2[5]; - step3[7] = step1[7] + step2[4]; - // step 4 - temp1 = step3[1] * -cospi_8_64 + step3[6] * cospi_24_64; - temp2 = step3[2] * cospi_24_64 + step3[5] * cospi_8_64; - step2[1] = fdct_round_shift(temp1); - step2[2] = fdct_round_shift(temp2); - temp1 = step3[2] * cospi_8_64 - step3[5] * cospi_24_64; - temp2 = step3[1] * cospi_24_64 + step3[6] * cospi_8_64; - step2[5] = fdct_round_shift(temp1); - step2[6] = fdct_round_shift(temp2); - // step 5 - step1[0] = step3[0] + step2[1]; - step1[1] = step3[0] - step2[1]; - step1[2] = step3[3] + step2[2]; - step1[3] = step3[3] - step2[2]; - step1[4] = step3[4] - step2[5]; - step1[5] = step3[4] + step2[5]; - step1[6] = step3[7] - step2[6]; - step1[7] = step3[7] + step2[6]; - // step 6 - temp1 = step1[0] * cospi_30_64 + step1[7] * cospi_2_64; - temp2 = step1[1] * cospi_14_64 + step1[6] * cospi_18_64; - out[1] = (tran_low_t)fdct_round_shift(temp1); - out[9] = (tran_low_t)fdct_round_shift(temp2); - temp1 = step1[2] * cospi_22_64 + step1[5] * cospi_10_64; - temp2 = step1[3] * cospi_6_64 + step1[4] * cospi_26_64; - out[5] = (tran_low_t)fdct_round_shift(temp1); - out[13] = (tran_low_t)fdct_round_shift(temp2); - temp1 = step1[3] * -cospi_26_64 + step1[4] * cospi_6_64; - temp2 = step1[2] * -cospi_10_64 + step1[5] * cospi_22_64; - out[3] = (tran_low_t)fdct_round_shift(temp1); - out[11] = (tran_low_t)fdct_round_shift(temp2); - temp1 = step1[1] * -cospi_18_64 + step1[6] * cospi_14_64; - temp2 = step1[0] * -cospi_2_64 + step1[7] * cospi_30_64; - out[7] = (tran_low_t)fdct_round_shift(temp1); - out[15] = (tran_low_t)fdct_round_shift(temp2); - } - // Do next column (which is a transposed row in second/horizontal pass) - input++; - out += 16; - } - // Setup in/out for next pass. - in_low = intermediate; - out = output; - } -} - -void vpx_fdct16x16_1_c(const int16_t *input, tran_low_t *output, int stride) { - int r, c; - int sum = 0; - for (r = 0; r < 16; ++r) - for (c = 0; c < 16; ++c) sum += input[r * stride + c]; - - output[0] = (tran_low_t)(sum >> 1); -} - -static INLINE tran_high_t dct_32_round(tran_high_t input) { - tran_high_t rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS); - // TODO(debargha, peter.derivaz): Find new bounds for this assert, - // and make the bounds consts. - // assert(-131072 <= rv && rv <= 131071); - return rv; -} - -static INLINE tran_high_t half_round_shift(tran_high_t input) { - tran_high_t rv = (input + 1 + (input < 0)) >> 2; - return rv; -} - -void vpx_fdct32(const tran_high_t *input, tran_high_t *output, int round) { - tran_high_t step[32]; - // Stage 1 - step[0] = input[0] + input[(32 - 1)]; - step[1] = input[1] + input[(32 - 2)]; - step[2] = input[2] + input[(32 - 3)]; - step[3] = input[3] + input[(32 - 4)]; - step[4] = input[4] + input[(32 - 5)]; - step[5] = input[5] + input[(32 - 6)]; - step[6] = input[6] + input[(32 - 7)]; - step[7] = input[7] + input[(32 - 8)]; - step[8] = input[8] + input[(32 - 9)]; - step[9] = input[9] + input[(32 - 10)]; - step[10] = input[10] + input[(32 - 11)]; - step[11] = input[11] + input[(32 - 12)]; - step[12] = input[12] + input[(32 - 13)]; - step[13] = input[13] + input[(32 - 14)]; - step[14] = input[14] + input[(32 - 15)]; - step[15] = input[15] + input[(32 - 16)]; - step[16] = -input[16] + input[(32 - 17)]; - step[17] = -input[17] + input[(32 - 18)]; - step[18] = -input[18] + input[(32 - 19)]; - step[19] = -input[19] + input[(32 - 20)]; - step[20] = -input[20] + input[(32 - 21)]; - step[21] = -input[21] + input[(32 - 22)]; - step[22] = -input[22] + input[(32 - 23)]; - step[23] = -input[23] + input[(32 - 24)]; - step[24] = -input[24] + input[(32 - 25)]; - step[25] = -input[25] + input[(32 - 26)]; - step[26] = -input[26] + input[(32 - 27)]; - step[27] = -input[27] + input[(32 - 28)]; - step[28] = -input[28] + input[(32 - 29)]; - step[29] = -input[29] + input[(32 - 30)]; - step[30] = -input[30] + input[(32 - 31)]; - step[31] = -input[31] + input[(32 - 32)]; - - // Stage 2 - output[0] = step[0] + step[16 - 1]; - output[1] = step[1] + step[16 - 2]; - output[2] = step[2] + step[16 - 3]; - output[3] = step[3] + step[16 - 4]; - output[4] = step[4] + step[16 - 5]; - output[5] = step[5] + step[16 - 6]; - output[6] = step[6] + step[16 - 7]; - output[7] = step[7] + step[16 - 8]; - output[8] = -step[8] + step[16 - 9]; - output[9] = -step[9] + step[16 - 10]; - output[10] = -step[10] + step[16 - 11]; - output[11] = -step[11] + step[16 - 12]; - output[12] = -step[12] + step[16 - 13]; - output[13] = -step[13] + step[16 - 14]; - output[14] = -step[14] + step[16 - 15]; - output[15] = -step[15] + step[16 - 16]; - - output[16] = step[16]; - output[17] = step[17]; - output[18] = step[18]; - output[19] = step[19]; - - output[20] = dct_32_round((-step[20] + step[27]) * cospi_16_64); - output[21] = dct_32_round((-step[21] + step[26]) * cospi_16_64); - output[22] = dct_32_round((-step[22] + step[25]) * cospi_16_64); - output[23] = dct_32_round((-step[23] + step[24]) * cospi_16_64); - - output[24] = dct_32_round((step[24] + step[23]) * cospi_16_64); - output[25] = dct_32_round((step[25] + step[22]) * cospi_16_64); - output[26] = dct_32_round((step[26] + step[21]) * cospi_16_64); - output[27] = dct_32_round((step[27] + step[20]) * cospi_16_64); - - output[28] = step[28]; - output[29] = step[29]; - output[30] = step[30]; - output[31] = step[31]; - - // dump the magnitude by 4, hence the intermediate values are within - // the range of 16 bits. - if (round) { - output[0] = half_round_shift(output[0]); - output[1] = half_round_shift(output[1]); - output[2] = half_round_shift(output[2]); - output[3] = half_round_shift(output[3]); - output[4] = half_round_shift(output[4]); - output[5] = half_round_shift(output[5]); - output[6] = half_round_shift(output[6]); - output[7] = half_round_shift(output[7]); - output[8] = half_round_shift(output[8]); - output[9] = half_round_shift(output[9]); - output[10] = half_round_shift(output[10]); - output[11] = half_round_shift(output[11]); - output[12] = half_round_shift(output[12]); - output[13] = half_round_shift(output[13]); - output[14] = half_round_shift(output[14]); - output[15] = half_round_shift(output[15]); - - output[16] = half_round_shift(output[16]); - output[17] = half_round_shift(output[17]); - output[18] = half_round_shift(output[18]); - output[19] = half_round_shift(output[19]); - output[20] = half_round_shift(output[20]); - output[21] = half_round_shift(output[21]); - output[22] = half_round_shift(output[22]); - output[23] = half_round_shift(output[23]); - output[24] = half_round_shift(output[24]); - output[25] = half_round_shift(output[25]); - output[26] = half_round_shift(output[26]); - output[27] = half_round_shift(output[27]); - output[28] = half_round_shift(output[28]); - output[29] = half_round_shift(output[29]); - output[30] = half_round_shift(output[30]); - output[31] = half_round_shift(output[31]); - } - - // Stage 3 - step[0] = output[0] + output[(8 - 1)]; - step[1] = output[1] + output[(8 - 2)]; - step[2] = output[2] + output[(8 - 3)]; - step[3] = output[3] + output[(8 - 4)]; - step[4] = -output[4] + output[(8 - 5)]; - step[5] = -output[5] + output[(8 - 6)]; - step[6] = -output[6] + output[(8 - 7)]; - step[7] = -output[7] + output[(8 - 8)]; - step[8] = output[8]; - step[9] = output[9]; - step[10] = dct_32_round((-output[10] + output[13]) * cospi_16_64); - step[11] = dct_32_round((-output[11] + output[12]) * cospi_16_64); - step[12] = dct_32_round((output[12] + output[11]) * cospi_16_64); - step[13] = dct_32_round((output[13] + output[10]) * cospi_16_64); - step[14] = output[14]; - step[15] = output[15]; - - step[16] = output[16] + output[23]; - step[17] = output[17] + output[22]; - step[18] = output[18] + output[21]; - step[19] = output[19] + output[20]; - step[20] = -output[20] + output[19]; - step[21] = -output[21] + output[18]; - step[22] = -output[22] + output[17]; - step[23] = -output[23] + output[16]; - step[24] = -output[24] + output[31]; - step[25] = -output[25] + output[30]; - step[26] = -output[26] + output[29]; - step[27] = -output[27] + output[28]; - step[28] = output[28] + output[27]; - step[29] = output[29] + output[26]; - step[30] = output[30] + output[25]; - step[31] = output[31] + output[24]; - - // Stage 4 - output[0] = step[0] + step[3]; - output[1] = step[1] + step[2]; - output[2] = -step[2] + step[1]; - output[3] = -step[3] + step[0]; - output[4] = step[4]; - output[5] = dct_32_round((-step[5] + step[6]) * cospi_16_64); - output[6] = dct_32_round((step[6] + step[5]) * cospi_16_64); - output[7] = step[7]; - output[8] = step[8] + step[11]; - output[9] = step[9] + step[10]; - output[10] = -step[10] + step[9]; - output[11] = -step[11] + step[8]; - output[12] = -step[12] + step[15]; - output[13] = -step[13] + step[14]; - output[14] = step[14] + step[13]; - output[15] = step[15] + step[12]; - - output[16] = step[16]; - output[17] = step[17]; - output[18] = dct_32_round(step[18] * -cospi_8_64 + step[29] * cospi_24_64); - output[19] = dct_32_round(step[19] * -cospi_8_64 + step[28] * cospi_24_64); - output[20] = dct_32_round(step[20] * -cospi_24_64 + step[27] * -cospi_8_64); - output[21] = dct_32_round(step[21] * -cospi_24_64 + step[26] * -cospi_8_64); - output[22] = step[22]; - output[23] = step[23]; - output[24] = step[24]; - output[25] = step[25]; - output[26] = dct_32_round(step[26] * cospi_24_64 + step[21] * -cospi_8_64); - output[27] = dct_32_round(step[27] * cospi_24_64 + step[20] * -cospi_8_64); - output[28] = dct_32_round(step[28] * cospi_8_64 + step[19] * cospi_24_64); - output[29] = dct_32_round(step[29] * cospi_8_64 + step[18] * cospi_24_64); - output[30] = step[30]; - output[31] = step[31]; - - // Stage 5 - step[0] = dct_32_round((output[0] + output[1]) * cospi_16_64); - step[1] = dct_32_round((-output[1] + output[0]) * cospi_16_64); - step[2] = dct_32_round(output[2] * cospi_24_64 + output[3] * cospi_8_64); - step[3] = dct_32_round(output[3] * cospi_24_64 - output[2] * cospi_8_64); - step[4] = output[4] + output[5]; - step[5] = -output[5] + output[4]; - step[6] = -output[6] + output[7]; - step[7] = output[7] + output[6]; - step[8] = output[8]; - step[9] = dct_32_round(output[9] * -cospi_8_64 + output[14] * cospi_24_64); - step[10] = dct_32_round(output[10] * -cospi_24_64 + output[13] * -cospi_8_64); - step[11] = output[11]; - step[12] = output[12]; - step[13] = dct_32_round(output[13] * cospi_24_64 + output[10] * -cospi_8_64); - step[14] = dct_32_round(output[14] * cospi_8_64 + output[9] * cospi_24_64); - step[15] = output[15]; - - step[16] = output[16] + output[19]; - step[17] = output[17] + output[18]; - step[18] = -output[18] + output[17]; - step[19] = -output[19] + output[16]; - step[20] = -output[20] + output[23]; - step[21] = -output[21] + output[22]; - step[22] = output[22] + output[21]; - step[23] = output[23] + output[20]; - step[24] = output[24] + output[27]; - step[25] = output[25] + output[26]; - step[26] = -output[26] + output[25]; - step[27] = -output[27] + output[24]; - step[28] = -output[28] + output[31]; - step[29] = -output[29] + output[30]; - step[30] = output[30] + output[29]; - step[31] = output[31] + output[28]; - - // Stage 6 - output[0] = step[0]; - output[1] = step[1]; - output[2] = step[2]; - output[3] = step[3]; - output[4] = dct_32_round(step[4] * cospi_28_64 + step[7] * cospi_4_64); - output[5] = dct_32_round(step[5] * cospi_12_64 + step[6] * cospi_20_64); - output[6] = dct_32_round(step[6] * cospi_12_64 + step[5] * -cospi_20_64); - output[7] = dct_32_round(step[7] * cospi_28_64 + step[4] * -cospi_4_64); - output[8] = step[8] + step[9]; - output[9] = -step[9] + step[8]; - output[10] = -step[10] + step[11]; - output[11] = step[11] + step[10]; - output[12] = step[12] + step[13]; - output[13] = -step[13] + step[12]; - output[14] = -step[14] + step[15]; - output[15] = step[15] + step[14]; - - output[16] = step[16]; - output[17] = dct_32_round(step[17] * -cospi_4_64 + step[30] * cospi_28_64); - output[18] = dct_32_round(step[18] * -cospi_28_64 + step[29] * -cospi_4_64); - output[19] = step[19]; - output[20] = step[20]; - output[21] = dct_32_round(step[21] * -cospi_20_64 + step[26] * cospi_12_64); - output[22] = dct_32_round(step[22] * -cospi_12_64 + step[25] * -cospi_20_64); - output[23] = step[23]; - output[24] = step[24]; - output[25] = dct_32_round(step[25] * cospi_12_64 + step[22] * -cospi_20_64); - output[26] = dct_32_round(step[26] * cospi_20_64 + step[21] * cospi_12_64); - output[27] = step[27]; - output[28] = step[28]; - output[29] = dct_32_round(step[29] * cospi_28_64 + step[18] * -cospi_4_64); - output[30] = dct_32_round(step[30] * cospi_4_64 + step[17] * cospi_28_64); - output[31] = step[31]; - - // Stage 7 - step[0] = output[0]; - step[1] = output[1]; - step[2] = output[2]; - step[3] = output[3]; - step[4] = output[4]; - step[5] = output[5]; - step[6] = output[6]; - step[7] = output[7]; - step[8] = dct_32_round(output[8] * cospi_30_64 + output[15] * cospi_2_64); - step[9] = dct_32_round(output[9] * cospi_14_64 + output[14] * cospi_18_64); - step[10] = dct_32_round(output[10] * cospi_22_64 + output[13] * cospi_10_64); - step[11] = dct_32_round(output[11] * cospi_6_64 + output[12] * cospi_26_64); - step[12] = dct_32_round(output[12] * cospi_6_64 + output[11] * -cospi_26_64); - step[13] = dct_32_round(output[13] * cospi_22_64 + output[10] * -cospi_10_64); - step[14] = dct_32_round(output[14] * cospi_14_64 + output[9] * -cospi_18_64); - step[15] = dct_32_round(output[15] * cospi_30_64 + output[8] * -cospi_2_64); - - step[16] = output[16] + output[17]; - step[17] = -output[17] + output[16]; - step[18] = -output[18] + output[19]; - step[19] = output[19] + output[18]; - step[20] = output[20] + output[21]; - step[21] = -output[21] + output[20]; - step[22] = -output[22] + output[23]; - step[23] = output[23] + output[22]; - step[24] = output[24] + output[25]; - step[25] = -output[25] + output[24]; - step[26] = -output[26] + output[27]; - step[27] = output[27] + output[26]; - step[28] = output[28] + output[29]; - step[29] = -output[29] + output[28]; - step[30] = -output[30] + output[31]; - step[31] = output[31] + output[30]; - - // Final stage --- outputs indices are bit-reversed. - output[0] = step[0]; - output[16] = step[1]; - output[8] = step[2]; - output[24] = step[3]; - output[4] = step[4]; - output[20] = step[5]; - output[12] = step[6]; - output[28] = step[7]; - output[2] = step[8]; - output[18] = step[9]; - output[10] = step[10]; - output[26] = step[11]; - output[6] = step[12]; - output[22] = step[13]; - output[14] = step[14]; - output[30] = step[15]; - - output[1] = dct_32_round(step[16] * cospi_31_64 + step[31] * cospi_1_64); - output[17] = dct_32_round(step[17] * cospi_15_64 + step[30] * cospi_17_64); - output[9] = dct_32_round(step[18] * cospi_23_64 + step[29] * cospi_9_64); - output[25] = dct_32_round(step[19] * cospi_7_64 + step[28] * cospi_25_64); - output[5] = dct_32_round(step[20] * cospi_27_64 + step[27] * cospi_5_64); - output[21] = dct_32_round(step[21] * cospi_11_64 + step[26] * cospi_21_64); - output[13] = dct_32_round(step[22] * cospi_19_64 + step[25] * cospi_13_64); - output[29] = dct_32_round(step[23] * cospi_3_64 + step[24] * cospi_29_64); - output[3] = dct_32_round(step[24] * cospi_3_64 + step[23] * -cospi_29_64); - output[19] = dct_32_round(step[25] * cospi_19_64 + step[22] * -cospi_13_64); - output[11] = dct_32_round(step[26] * cospi_11_64 + step[21] * -cospi_21_64); - output[27] = dct_32_round(step[27] * cospi_27_64 + step[20] * -cospi_5_64); - output[7] = dct_32_round(step[28] * cospi_7_64 + step[19] * -cospi_25_64); - output[23] = dct_32_round(step[29] * cospi_23_64 + step[18] * -cospi_9_64); - output[15] = dct_32_round(step[30] * cospi_15_64 + step[17] * -cospi_17_64); - output[31] = dct_32_round(step[31] * cospi_31_64 + step[16] * -cospi_1_64); -} - -void vpx_fdct32x32_c(const int16_t *input, tran_low_t *output, int stride) { - int i, j; - tran_high_t out[32 * 32]; - - // Columns - for (i = 0; i < 32; ++i) { - tran_high_t temp_in[32], temp_out[32]; - for (j = 0; j < 32; ++j) temp_in[j] = input[j * stride + i] * 4; - vpx_fdct32(temp_in, temp_out, 0); - for (j = 0; j < 32; ++j) - out[j * 32 + i] = (temp_out[j] + 1 + (temp_out[j] > 0)) >> 2; - } - - // Rows - for (i = 0; i < 32; ++i) { - tran_high_t temp_in[32], temp_out[32]; - for (j = 0; j < 32; ++j) temp_in[j] = out[j + i * 32]; - vpx_fdct32(temp_in, temp_out, 0); - for (j = 0; j < 32; ++j) - output[j + i * 32] = - (tran_low_t)((temp_out[j] + 1 + (temp_out[j] < 0)) >> 2); - } -} - -// Note that although we use dct_32_round in dct32 computation flow, -// this 2d fdct32x32 for rate-distortion optimization loop is operating -// within 16 bits precision. -void vpx_fdct32x32_rd_c(const int16_t *input, tran_low_t *output, int stride) { - int i, j; - tran_high_t out[32 * 32]; - - // Columns - for (i = 0; i < 32; ++i) { - tran_high_t temp_in[32], temp_out[32]; - for (j = 0; j < 32; ++j) temp_in[j] = input[j * stride + i] * 4; - vpx_fdct32(temp_in, temp_out, 0); - for (j = 0; j < 32; ++j) - // TODO(cd): see quality impact of only doing - // output[j * 32 + i] = (temp_out[j] + 1) >> 2; - // PS: also change code in vpx_dsp/x86/vpx_dct_sse2.c - out[j * 32 + i] = (temp_out[j] + 1 + (temp_out[j] > 0)) >> 2; - } - - // Rows - for (i = 0; i < 32; ++i) { - tran_high_t temp_in[32], temp_out[32]; - for (j = 0; j < 32; ++j) temp_in[j] = out[j + i * 32]; - vpx_fdct32(temp_in, temp_out, 1); - for (j = 0; j < 32; ++j) output[j + i * 32] = (tran_low_t)temp_out[j]; - } -} - -void vpx_fdct32x32_1_c(const int16_t *input, tran_low_t *output, int stride) { - int r, c; - int sum = 0; - for (r = 0; r < 32; ++r) - for (c = 0; c < 32; ++c) sum += input[r * stride + c]; - - output[0] = (tran_low_t)(sum >> 3); -} - -#if CONFIG_VP9_HIGHBITDEPTH -void vpx_highbd_fdct4x4_c(const int16_t *input, tran_low_t *output, - int stride) { - vpx_fdct4x4_c(input, output, stride); -} - -void vpx_highbd_fdct8x8_c(const int16_t *input, tran_low_t *output, - int stride) { - vpx_fdct8x8_c(input, output, stride); -} - -void vpx_highbd_fdct8x8_1_c(const int16_t *input, tran_low_t *output, - int stride) { - vpx_fdct8x8_1_c(input, output, stride); -} - -void vpx_highbd_fdct16x16_c(const int16_t *input, tran_low_t *output, - int stride) { - vpx_fdct16x16_c(input, output, stride); -} - -void vpx_highbd_fdct16x16_1_c(const int16_t *input, tran_low_t *output, - int stride) { - vpx_fdct16x16_1_c(input, output, stride); -} - -void vpx_highbd_fdct32x32_c(const int16_t *input, tran_low_t *output, - int stride) { - vpx_fdct32x32_c(input, output, stride); -} - -void vpx_highbd_fdct32x32_rd_c(const int16_t *input, tran_low_t *output, - int stride) { - vpx_fdct32x32_rd_c(input, output, stride); -} - -void vpx_highbd_fdct32x32_1_c(const int16_t *input, tran_low_t *output, - int stride) { - vpx_fdct32x32_1_c(input, output, stride); -} -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/fwd_txfm.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/fwd_txfm.h deleted file mode 100644 index a43c8ea7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/fwd_txfm.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_FWD_TXFM_H_ -#define VPX_VPX_DSP_FWD_TXFM_H_ - -#include "vpx_dsp/txfm_common.h" - -static INLINE tran_high_t fdct_round_shift(tran_high_t input) { - tran_high_t rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS); - // TODO(debargha, peter.derivaz): Find new bounds for this assert - // and make the bounds consts. - // assert(INT16_MIN <= rv && rv <= INT16_MAX); - return rv; -} - -void vpx_fdct32(const tran_high_t *input, tran_high_t *output, int round); -#endif // VPX_VPX_DSP_FWD_TXFM_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/intrapred.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/intrapred.c deleted file mode 100644 index 400e632e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/intrapred.c +++ /dev/null @@ -1,917 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" - -#define DST(x, y) dst[(x) + (y)*stride] -#define AVG3(a, b, c) (((a) + 2 * (b) + (c) + 2) >> 2) -#define AVG2(a, b) (((a) + (b) + 1) >> 1) - -static INLINE void d207_predictor(uint8_t *dst, ptrdiff_t stride, int bs, - const uint8_t *above, const uint8_t *left) { - int r, c; - (void)above; - // first column - for (r = 0; r < bs - 1; ++r) dst[r * stride] = AVG2(left[r], left[r + 1]); - dst[(bs - 1) * stride] = left[bs - 1]; - dst++; - - // second column - for (r = 0; r < bs - 2; ++r) - dst[r * stride] = AVG3(left[r], left[r + 1], left[r + 2]); - dst[(bs - 2) * stride] = AVG3(left[bs - 2], left[bs - 1], left[bs - 1]); - dst[(bs - 1) * stride] = left[bs - 1]; - dst++; - - // rest of last row - for (c = 0; c < bs - 2; ++c) dst[(bs - 1) * stride + c] = left[bs - 1]; - - for (r = bs - 2; r >= 0; --r) - for (c = 0; c < bs - 2; ++c) - dst[r * stride + c] = dst[(r + 1) * stride + c - 2]; -} - -static INLINE void d63_predictor(uint8_t *dst, ptrdiff_t stride, int bs, - const uint8_t *above, const uint8_t *left) { - int r, c; - int size; - (void)left; - for (c = 0; c < bs; ++c) { - dst[c] = AVG2(above[c], above[c + 1]); - dst[stride + c] = AVG3(above[c], above[c + 1], above[c + 2]); - } - for (r = 2, size = bs - 2; r < bs; r += 2, --size) { - memcpy(dst + (r + 0) * stride, dst + (r >> 1), size); - memset(dst + (r + 0) * stride + size, above[bs - 1], bs - size); - memcpy(dst + (r + 1) * stride, dst + stride + (r >> 1), size); - memset(dst + (r + 1) * stride + size, above[bs - 1], bs - size); - } -} - -static INLINE void d45_predictor(uint8_t *dst, ptrdiff_t stride, int bs, - const uint8_t *above, const uint8_t *left) { - const uint8_t above_right = above[bs - 1]; - const uint8_t *const dst_row0 = dst; - int x, size; - (void)left; - - for (x = 0; x < bs - 1; ++x) { - dst[x] = AVG3(above[x], above[x + 1], above[x + 2]); - } - dst[bs - 1] = above_right; - dst += stride; - for (x = 1, size = bs - 2; x < bs; ++x, --size) { - memcpy(dst, dst_row0 + x, size); - memset(dst + size, above_right, x + 1); - dst += stride; - } -} - -static INLINE void d117_predictor(uint8_t *dst, ptrdiff_t stride, int bs, - const uint8_t *above, const uint8_t *left) { - int r, c; - - // first row - for (c = 0; c < bs; c++) dst[c] = AVG2(above[c - 1], above[c]); - dst += stride; - - // second row - dst[0] = AVG3(left[0], above[-1], above[0]); - for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]); - dst += stride; - - // the rest of first col - dst[0] = AVG3(above[-1], left[0], left[1]); - for (r = 3; r < bs; ++r) - dst[(r - 2) * stride] = AVG3(left[r - 3], left[r - 2], left[r - 1]); - - // the rest of the block - for (r = 2; r < bs; ++r) { - for (c = 1; c < bs; c++) dst[c] = dst[-2 * stride + c - 1]; - dst += stride; - } -} - -static INLINE void d135_predictor(uint8_t *dst, ptrdiff_t stride, int bs, - const uint8_t *above, const uint8_t *left) { - int i; -#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 7 - // silence a spurious -Warray-bounds warning, possibly related to: - // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56273 - uint8_t border[69]; -#else - uint8_t border[32 + 32 - 1]; // outer border from bottom-left to top-right -#endif - - // dst(bs, bs - 2)[0], i.e., border starting at bottom-left - for (i = 0; i < bs - 2; ++i) { - border[i] = AVG3(left[bs - 3 - i], left[bs - 2 - i], left[bs - 1 - i]); - } - border[bs - 2] = AVG3(above[-1], left[0], left[1]); - border[bs - 1] = AVG3(left[0], above[-1], above[0]); - border[bs - 0] = AVG3(above[-1], above[0], above[1]); - // dst[0][2, size), i.e., remaining top border ascending - for (i = 0; i < bs - 2; ++i) { - border[bs + 1 + i] = AVG3(above[i], above[i + 1], above[i + 2]); - } - - for (i = 0; i < bs; ++i) { - memcpy(dst + i * stride, border + bs - 1 - i, bs); - } -} - -static INLINE void d153_predictor(uint8_t *dst, ptrdiff_t stride, int bs, - const uint8_t *above, const uint8_t *left) { - int r, c; - dst[0] = AVG2(above[-1], left[0]); - for (r = 1; r < bs; r++) dst[r * stride] = AVG2(left[r - 1], left[r]); - dst++; - - dst[0] = AVG3(left[0], above[-1], above[0]); - dst[stride] = AVG3(above[-1], left[0], left[1]); - for (r = 2; r < bs; r++) - dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]); - dst++; - - for (c = 0; c < bs - 2; c++) - dst[c] = AVG3(above[c - 1], above[c], above[c + 1]); - dst += stride; - - for (r = 1; r < bs; ++r) { - for (c = 0; c < bs - 2; c++) dst[c] = dst[-stride + c - 2]; - dst += stride; - } -} - -static INLINE void v_predictor(uint8_t *dst, ptrdiff_t stride, int bs, - const uint8_t *above, const uint8_t *left) { - int r; - (void)left; - - for (r = 0; r < bs; r++) { - memcpy(dst, above, bs); - dst += stride; - } -} - -static INLINE void h_predictor(uint8_t *dst, ptrdiff_t stride, int bs, - const uint8_t *above, const uint8_t *left) { - int r; - (void)above; - - for (r = 0; r < bs; r++) { - memset(dst, left[r], bs); - dst += stride; - } -} - -static INLINE void tm_predictor(uint8_t *dst, ptrdiff_t stride, int bs, - const uint8_t *above, const uint8_t *left) { - int r, c; - int ytop_left = above[-1]; - - for (r = 0; r < bs; r++) { - for (c = 0; c < bs; c++) - dst[c] = clip_pixel(left[r] + above[c] - ytop_left); - dst += stride; - } -} - -static INLINE void dc_128_predictor(uint8_t *dst, ptrdiff_t stride, int bs, - const uint8_t *above, const uint8_t *left) { - int r; - (void)above; - (void)left; - - for (r = 0; r < bs; r++) { - memset(dst, 128, bs); - dst += stride; - } -} - -static INLINE void dc_left_predictor(uint8_t *dst, ptrdiff_t stride, int bs, - const uint8_t *above, - const uint8_t *left) { - int i, r, expected_dc, sum = 0; - (void)above; - - for (i = 0; i < bs; i++) sum += left[i]; - expected_dc = (sum + (bs >> 1)) / bs; - - for (r = 0; r < bs; r++) { - memset(dst, expected_dc, bs); - dst += stride; - } -} - -static INLINE void dc_top_predictor(uint8_t *dst, ptrdiff_t stride, int bs, - const uint8_t *above, const uint8_t *left) { - int i, r, expected_dc, sum = 0; - (void)left; - - for (i = 0; i < bs; i++) sum += above[i]; - expected_dc = (sum + (bs >> 1)) / bs; - - for (r = 0; r < bs; r++) { - memset(dst, expected_dc, bs); - dst += stride; - } -} - -static INLINE void dc_predictor(uint8_t *dst, ptrdiff_t stride, int bs, - const uint8_t *above, const uint8_t *left) { - int i, r, expected_dc, sum = 0; - const int count = 2 * bs; - - for (i = 0; i < bs; i++) { - sum += above[i]; - sum += left[i]; - } - - expected_dc = (sum + (count >> 1)) / count; - - for (r = 0; r < bs; r++) { - memset(dst, expected_dc, bs); - dst += stride; - } -} - -void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const int H = above[-1]; - const int I = left[0]; - const int J = left[1]; - const int K = left[2]; - const int L = left[3]; - - memset(dst + stride * 0, AVG3(H, I, J), 4); - memset(dst + stride * 1, AVG3(I, J, K), 4); - memset(dst + stride * 2, AVG3(J, K, L), 4); - memset(dst + stride * 3, AVG3(K, L, L), 4); -} - -void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const int H = above[-1]; - const int I = above[0]; - const int J = above[1]; - const int K = above[2]; - const int L = above[3]; - const int M = above[4]; - (void)left; - - dst[0] = AVG3(H, I, J); - dst[1] = AVG3(I, J, K); - dst[2] = AVG3(J, K, L); - dst[3] = AVG3(K, L, M); - memcpy(dst + stride * 1, dst, 4); - memcpy(dst + stride * 2, dst, 4); - memcpy(dst + stride * 3, dst, 4); -} - -void vpx_d207_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const int I = left[0]; - const int J = left[1]; - const int K = left[2]; - const int L = left[3]; - (void)above; - DST(0, 0) = AVG2(I, J); - DST(2, 0) = DST(0, 1) = AVG2(J, K); - DST(2, 1) = DST(0, 2) = AVG2(K, L); - DST(1, 0) = AVG3(I, J, K); - DST(3, 0) = DST(1, 1) = AVG3(J, K, L); - DST(3, 1) = DST(1, 2) = AVG3(K, L, L); - DST(3, 2) = DST(2, 2) = DST(0, 3) = DST(1, 3) = DST(2, 3) = DST(3, 3) = L; -} - -void vpx_d63_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const int A = above[0]; - const int B = above[1]; - const int C = above[2]; - const int D = above[3]; - const int E = above[4]; - const int F = above[5]; - const int G = above[6]; - (void)left; - DST(0, 0) = AVG2(A, B); - DST(1, 0) = DST(0, 2) = AVG2(B, C); - DST(2, 0) = DST(1, 2) = AVG2(C, D); - DST(3, 0) = DST(2, 2) = AVG2(D, E); - DST(3, 2) = AVG2(E, F); // differs from vp8 - - DST(0, 1) = AVG3(A, B, C); - DST(1, 1) = DST(0, 3) = AVG3(B, C, D); - DST(2, 1) = DST(1, 3) = AVG3(C, D, E); - DST(3, 1) = DST(2, 3) = AVG3(D, E, F); - DST(3, 3) = AVG3(E, F, G); // differs from vp8 -} - -void vpx_d63e_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const int A = above[0]; - const int B = above[1]; - const int C = above[2]; - const int D = above[3]; - const int E = above[4]; - const int F = above[5]; - const int G = above[6]; - const int H = above[7]; - (void)left; - DST(0, 0) = AVG2(A, B); - DST(1, 0) = DST(0, 2) = AVG2(B, C); - DST(2, 0) = DST(1, 2) = AVG2(C, D); - DST(3, 0) = DST(2, 2) = AVG2(D, E); - DST(3, 2) = AVG3(E, F, G); - - DST(0, 1) = AVG3(A, B, C); - DST(1, 1) = DST(0, 3) = AVG3(B, C, D); - DST(2, 1) = DST(1, 3) = AVG3(C, D, E); - DST(3, 1) = DST(2, 3) = AVG3(D, E, F); - DST(3, 3) = AVG3(F, G, H); -} - -void vpx_d45_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const int A = above[0]; - const int B = above[1]; - const int C = above[2]; - const int D = above[3]; - const int E = above[4]; - const int F = above[5]; - const int G = above[6]; - const int H = above[7]; - (void)stride; - (void)left; - DST(0, 0) = AVG3(A, B, C); - DST(1, 0) = DST(0, 1) = AVG3(B, C, D); - DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E); - DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F); - DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G); - DST(3, 2) = DST(2, 3) = AVG3(F, G, H); - DST(3, 3) = H; // differs from vp8 -} - -void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const int A = above[0]; - const int B = above[1]; - const int C = above[2]; - const int D = above[3]; - const int E = above[4]; - const int F = above[5]; - const int G = above[6]; - const int H = above[7]; - (void)stride; - (void)left; - DST(0, 0) = AVG3(A, B, C); - DST(1, 0) = DST(0, 1) = AVG3(B, C, D); - DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E); - DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F); - DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G); - DST(3, 2) = DST(2, 3) = AVG3(F, G, H); - DST(3, 3) = AVG3(G, H, H); -} - -void vpx_d117_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const int I = left[0]; - const int J = left[1]; - const int K = left[2]; - const int X = above[-1]; - const int A = above[0]; - const int B = above[1]; - const int C = above[2]; - const int D = above[3]; - DST(0, 0) = DST(1, 2) = AVG2(X, A); - DST(1, 0) = DST(2, 2) = AVG2(A, B); - DST(2, 0) = DST(3, 2) = AVG2(B, C); - DST(3, 0) = AVG2(C, D); - - DST(0, 3) = AVG3(K, J, I); - DST(0, 2) = AVG3(J, I, X); - DST(0, 1) = DST(1, 3) = AVG3(I, X, A); - DST(1, 1) = DST(2, 3) = AVG3(X, A, B); - DST(2, 1) = DST(3, 3) = AVG3(A, B, C); - DST(3, 1) = AVG3(B, C, D); -} - -void vpx_d135_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const int I = left[0]; - const int J = left[1]; - const int K = left[2]; - const int L = left[3]; - const int X = above[-1]; - const int A = above[0]; - const int B = above[1]; - const int C = above[2]; - const int D = above[3]; - (void)stride; - DST(0, 3) = AVG3(J, K, L); - DST(1, 3) = DST(0, 2) = AVG3(I, J, K); - DST(2, 3) = DST(1, 2) = DST(0, 1) = AVG3(X, I, J); - DST(3, 3) = DST(2, 2) = DST(1, 1) = DST(0, 0) = AVG3(A, X, I); - DST(3, 2) = DST(2, 1) = DST(1, 0) = AVG3(B, A, X); - DST(3, 1) = DST(2, 0) = AVG3(C, B, A); - DST(3, 0) = AVG3(D, C, B); -} - -void vpx_d153_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const int I = left[0]; - const int J = left[1]; - const int K = left[2]; - const int L = left[3]; - const int X = above[-1]; - const int A = above[0]; - const int B = above[1]; - const int C = above[2]; - - DST(0, 0) = DST(2, 1) = AVG2(I, X); - DST(0, 1) = DST(2, 2) = AVG2(J, I); - DST(0, 2) = DST(2, 3) = AVG2(K, J); - DST(0, 3) = AVG2(L, K); - - DST(3, 0) = AVG3(A, B, C); - DST(2, 0) = AVG3(X, A, B); - DST(1, 0) = DST(3, 1) = AVG3(I, X, A); - DST(1, 1) = DST(3, 2) = AVG3(J, I, X); - DST(1, 2) = DST(3, 3) = AVG3(K, J, I); - DST(1, 3) = AVG3(L, K, J); -} - -#if CONFIG_VP9_HIGHBITDEPTH -static INLINE void highbd_d207_predictor(uint16_t *dst, ptrdiff_t stride, - int bs, const uint16_t *above, - const uint16_t *left, int bd) { - int r, c; - (void)above; - (void)bd; - - // First column. - for (r = 0; r < bs - 1; ++r) { - dst[r * stride] = AVG2(left[r], left[r + 1]); - } - dst[(bs - 1) * stride] = left[bs - 1]; - dst++; - - // Second column. - for (r = 0; r < bs - 2; ++r) { - dst[r * stride] = AVG3(left[r], left[r + 1], left[r + 2]); - } - dst[(bs - 2) * stride] = AVG3(left[bs - 2], left[bs - 1], left[bs - 1]); - dst[(bs - 1) * stride] = left[bs - 1]; - dst++; - - // Rest of last row. - for (c = 0; c < bs - 2; ++c) dst[(bs - 1) * stride + c] = left[bs - 1]; - - for (r = bs - 2; r >= 0; --r) { - for (c = 0; c < bs - 2; ++c) - dst[r * stride + c] = dst[(r + 1) * stride + c - 2]; - } -} - -static INLINE void highbd_d63_predictor(uint16_t *dst, ptrdiff_t stride, int bs, - const uint16_t *above, - const uint16_t *left, int bd) { - int r, c; - int size; - (void)left; - (void)bd; - for (c = 0; c < bs; ++c) { - dst[c] = AVG2(above[c], above[c + 1]); - dst[stride + c] = AVG3(above[c], above[c + 1], above[c + 2]); - } - for (r = 2, size = bs - 2; r < bs; r += 2, --size) { - memcpy(dst + (r + 0) * stride, dst + (r >> 1), size * sizeof(*dst)); - vpx_memset16(dst + (r + 0) * stride + size, above[bs - 1], bs - size); - memcpy(dst + (r + 1) * stride, dst + stride + (r >> 1), - size * sizeof(*dst)); - vpx_memset16(dst + (r + 1) * stride + size, above[bs - 1], bs - size); - } -} - -static INLINE void highbd_d45_predictor(uint16_t *dst, ptrdiff_t stride, int bs, - const uint16_t *above, - const uint16_t *left, int bd) { - const uint16_t above_right = above[bs - 1]; - const uint16_t *const dst_row0 = dst; - int x, size; - (void)left; - (void)bd; - - for (x = 0; x < bs - 1; ++x) { - dst[x] = AVG3(above[x], above[x + 1], above[x + 2]); - } - dst[bs - 1] = above_right; - dst += stride; - for (x = 1, size = bs - 2; x < bs; ++x, --size) { - memcpy(dst, dst_row0 + x, size * sizeof(*dst)); - vpx_memset16(dst + size, above_right, x + 1); - dst += stride; - } -} - -static INLINE void highbd_d117_predictor(uint16_t *dst, ptrdiff_t stride, - int bs, const uint16_t *above, - const uint16_t *left, int bd) { - int r, c; - (void)bd; - - // first row - for (c = 0; c < bs; c++) dst[c] = AVG2(above[c - 1], above[c]); - dst += stride; - - // second row - dst[0] = AVG3(left[0], above[-1], above[0]); - for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]); - dst += stride; - - // the rest of first col - dst[0] = AVG3(above[-1], left[0], left[1]); - for (r = 3; r < bs; ++r) - dst[(r - 2) * stride] = AVG3(left[r - 3], left[r - 2], left[r - 1]); - - // the rest of the block - for (r = 2; r < bs; ++r) { - for (c = 1; c < bs; c++) dst[c] = dst[-2 * stride + c - 1]; - dst += stride; - } -} - -static INLINE void highbd_d135_predictor(uint16_t *dst, ptrdiff_t stride, - int bs, const uint16_t *above, - const uint16_t *left, int bd) { - int i; -#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 7 - // silence a spurious -Warray-bounds warning, possibly related to: - // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56273 - uint16_t border[69]; -#else - uint16_t border[32 + 32 - 1]; // outer border from bottom-left to top-right -#endif - (void)bd; - - // dst(bs, bs - 2)[0], i.e., border starting at bottom-left - for (i = 0; i < bs - 2; ++i) { - border[i] = AVG3(left[bs - 3 - i], left[bs - 2 - i], left[bs - 1 - i]); - } - border[bs - 2] = AVG3(above[-1], left[0], left[1]); - border[bs - 1] = AVG3(left[0], above[-1], above[0]); - border[bs - 0] = AVG3(above[-1], above[0], above[1]); - // dst[0][2, size), i.e., remaining top border ascending - for (i = 0; i < bs - 2; ++i) { - border[bs + 1 + i] = AVG3(above[i], above[i + 1], above[i + 2]); - } - - for (i = 0; i < bs; ++i) { - memcpy(dst + i * stride, border + bs - 1 - i, bs * sizeof(dst[0])); - } -} - -static INLINE void highbd_d153_predictor(uint16_t *dst, ptrdiff_t stride, - int bs, const uint16_t *above, - const uint16_t *left, int bd) { - int r, c; - (void)bd; - dst[0] = AVG2(above[-1], left[0]); - for (r = 1; r < bs; r++) dst[r * stride] = AVG2(left[r - 1], left[r]); - dst++; - - dst[0] = AVG3(left[0], above[-1], above[0]); - dst[stride] = AVG3(above[-1], left[0], left[1]); - for (r = 2; r < bs; r++) - dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]); - dst++; - - for (c = 0; c < bs - 2; c++) - dst[c] = AVG3(above[c - 1], above[c], above[c + 1]); - dst += stride; - - for (r = 1; r < bs; ++r) { - for (c = 0; c < bs - 2; c++) dst[c] = dst[-stride + c - 2]; - dst += stride; - } -} - -static INLINE void highbd_v_predictor(uint16_t *dst, ptrdiff_t stride, int bs, - const uint16_t *above, - const uint16_t *left, int bd) { - int r; - (void)left; - (void)bd; - for (r = 0; r < bs; r++) { - memcpy(dst, above, bs * sizeof(uint16_t)); - dst += stride; - } -} - -static INLINE void highbd_h_predictor(uint16_t *dst, ptrdiff_t stride, int bs, - const uint16_t *above, - const uint16_t *left, int bd) { - int r; - (void)above; - (void)bd; - for (r = 0; r < bs; r++) { - vpx_memset16(dst, left[r], bs); - dst += stride; - } -} - -static INLINE void highbd_tm_predictor(uint16_t *dst, ptrdiff_t stride, int bs, - const uint16_t *above, - const uint16_t *left, int bd) { - int r, c; - int ytop_left = above[-1]; - (void)bd; - - for (r = 0; r < bs; r++) { - for (c = 0; c < bs; c++) - dst[c] = clip_pixel_highbd(left[r] + above[c] - ytop_left, bd); - dst += stride; - } -} - -static INLINE void highbd_dc_128_predictor(uint16_t *dst, ptrdiff_t stride, - int bs, const uint16_t *above, - const uint16_t *left, int bd) { - int r; - (void)above; - (void)left; - - for (r = 0; r < bs; r++) { - vpx_memset16(dst, 128 << (bd - 8), bs); - dst += stride; - } -} - -static INLINE void highbd_dc_left_predictor(uint16_t *dst, ptrdiff_t stride, - int bs, const uint16_t *above, - const uint16_t *left, int bd) { - int i, r, expected_dc, sum = 0; - (void)above; - (void)bd; - - for (i = 0; i < bs; i++) sum += left[i]; - expected_dc = (sum + (bs >> 1)) / bs; - - for (r = 0; r < bs; r++) { - vpx_memset16(dst, expected_dc, bs); - dst += stride; - } -} - -static INLINE void highbd_dc_top_predictor(uint16_t *dst, ptrdiff_t stride, - int bs, const uint16_t *above, - const uint16_t *left, int bd) { - int i, r, expected_dc, sum = 0; - (void)left; - (void)bd; - - for (i = 0; i < bs; i++) sum += above[i]; - expected_dc = (sum + (bs >> 1)) / bs; - - for (r = 0; r < bs; r++) { - vpx_memset16(dst, expected_dc, bs); - dst += stride; - } -} - -static INLINE void highbd_dc_predictor(uint16_t *dst, ptrdiff_t stride, int bs, - const uint16_t *above, - const uint16_t *left, int bd) { - int i, r, expected_dc, sum = 0; - const int count = 2 * bs; - (void)bd; - - for (i = 0; i < bs; i++) { - sum += above[i]; - sum += left[i]; - } - - expected_dc = (sum + (count >> 1)) / count; - - for (r = 0; r < bs; r++) { - vpx_memset16(dst, expected_dc, bs); - dst += stride; - } -} - -void vpx_highbd_d207_predictor_4x4_c(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const int I = left[0]; - const int J = left[1]; - const int K = left[2]; - const int L = left[3]; - (void)above; - (void)bd; - DST(0, 0) = AVG2(I, J); - DST(2, 0) = DST(0, 1) = AVG2(J, K); - DST(2, 1) = DST(0, 2) = AVG2(K, L); - DST(1, 0) = AVG3(I, J, K); - DST(3, 0) = DST(1, 1) = AVG3(J, K, L); - DST(3, 1) = DST(1, 2) = AVG3(K, L, L); - DST(3, 2) = DST(2, 2) = DST(0, 3) = DST(1, 3) = DST(2, 3) = DST(3, 3) = L; -} - -void vpx_highbd_d63_predictor_4x4_c(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, const uint16_t *left, - int bd) { - const int A = above[0]; - const int B = above[1]; - const int C = above[2]; - const int D = above[3]; - const int E = above[4]; - const int F = above[5]; - const int G = above[6]; - (void)left; - (void)bd; - DST(0, 0) = AVG2(A, B); - DST(1, 0) = DST(0, 2) = AVG2(B, C); - DST(2, 0) = DST(1, 2) = AVG2(C, D); - DST(3, 0) = DST(2, 2) = AVG2(D, E); - DST(3, 2) = AVG2(E, F); // differs from vp8 - - DST(0, 1) = AVG3(A, B, C); - DST(1, 1) = DST(0, 3) = AVG3(B, C, D); - DST(2, 1) = DST(1, 3) = AVG3(C, D, E); - DST(3, 1) = DST(2, 3) = AVG3(D, E, F); - DST(3, 3) = AVG3(E, F, G); // differs from vp8 -} - -void vpx_highbd_d45_predictor_4x4_c(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, const uint16_t *left, - int bd) { - const int A = above[0]; - const int B = above[1]; - const int C = above[2]; - const int D = above[3]; - const int E = above[4]; - const int F = above[5]; - const int G = above[6]; - const int H = above[7]; - (void)left; - (void)bd; - DST(0, 0) = AVG3(A, B, C); - DST(1, 0) = DST(0, 1) = AVG3(B, C, D); - DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E); - DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F); - DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G); - DST(3, 2) = DST(2, 3) = AVG3(F, G, H); - DST(3, 3) = H; // differs from vp8 -} - -void vpx_highbd_d117_predictor_4x4_c(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const int I = left[0]; - const int J = left[1]; - const int K = left[2]; - const int X = above[-1]; - const int A = above[0]; - const int B = above[1]; - const int C = above[2]; - const int D = above[3]; - (void)bd; - DST(0, 0) = DST(1, 2) = AVG2(X, A); - DST(1, 0) = DST(2, 2) = AVG2(A, B); - DST(2, 0) = DST(3, 2) = AVG2(B, C); - DST(3, 0) = AVG2(C, D); - - DST(0, 3) = AVG3(K, J, I); - DST(0, 2) = AVG3(J, I, X); - DST(0, 1) = DST(1, 3) = AVG3(I, X, A); - DST(1, 1) = DST(2, 3) = AVG3(X, A, B); - DST(2, 1) = DST(3, 3) = AVG3(A, B, C); - DST(3, 1) = AVG3(B, C, D); -} - -void vpx_highbd_d135_predictor_4x4_c(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const int I = left[0]; - const int J = left[1]; - const int K = left[2]; - const int L = left[3]; - const int X = above[-1]; - const int A = above[0]; - const int B = above[1]; - const int C = above[2]; - const int D = above[3]; - (void)bd; - DST(0, 3) = AVG3(J, K, L); - DST(1, 3) = DST(0, 2) = AVG3(I, J, K); - DST(2, 3) = DST(1, 2) = DST(0, 1) = AVG3(X, I, J); - DST(3, 3) = DST(2, 2) = DST(1, 1) = DST(0, 0) = AVG3(A, X, I); - DST(3, 2) = DST(2, 1) = DST(1, 0) = AVG3(B, A, X); - DST(3, 1) = DST(2, 0) = AVG3(C, B, A); - DST(3, 0) = AVG3(D, C, B); -} - -void vpx_highbd_d153_predictor_4x4_c(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const int I = left[0]; - const int J = left[1]; - const int K = left[2]; - const int L = left[3]; - const int X = above[-1]; - const int A = above[0]; - const int B = above[1]; - const int C = above[2]; - (void)bd; - - DST(0, 0) = DST(2, 1) = AVG2(I, X); - DST(0, 1) = DST(2, 2) = AVG2(J, I); - DST(0, 2) = DST(2, 3) = AVG2(K, J); - DST(0, 3) = AVG2(L, K); - - DST(3, 0) = AVG3(A, B, C); - DST(2, 0) = AVG3(X, A, B); - DST(1, 0) = DST(3, 1) = AVG3(I, X, A); - DST(1, 1) = DST(3, 2) = AVG3(J, I, X); - DST(1, 2) = DST(3, 3) = AVG3(K, J, I); - DST(1, 3) = AVG3(L, K, J); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -// This serves as a wrapper function, so that all the prediction functions -// can be unified and accessed as a pointer array. Note that the boundary -// above and left are not necessarily used all the time. -#define intra_pred_sized(type, size) \ - void vpx_##type##_predictor_##size##x##size##_c( \ - uint8_t *dst, ptrdiff_t stride, const uint8_t *above, \ - const uint8_t *left) { \ - type##_predictor(dst, stride, size, above, left); \ - } - -#if CONFIG_VP9_HIGHBITDEPTH -#define intra_pred_highbd_sized(type, size) \ - void vpx_highbd_##type##_predictor_##size##x##size##_c( \ - uint16_t *dst, ptrdiff_t stride, const uint16_t *above, \ - const uint16_t *left, int bd) { \ - highbd_##type##_predictor(dst, stride, size, above, left, bd); \ - } - -/* clang-format off */ -#define intra_pred_allsizes(type) \ - intra_pred_sized(type, 4) \ - intra_pred_sized(type, 8) \ - intra_pred_sized(type, 16) \ - intra_pred_sized(type, 32) \ - intra_pred_highbd_sized(type, 4) \ - intra_pred_highbd_sized(type, 8) \ - intra_pred_highbd_sized(type, 16) \ - intra_pred_highbd_sized(type, 32) - -#define intra_pred_no_4x4(type) \ - intra_pred_sized(type, 8) \ - intra_pred_sized(type, 16) \ - intra_pred_sized(type, 32) \ - intra_pred_highbd_sized(type, 8) \ - intra_pred_highbd_sized(type, 16) \ - intra_pred_highbd_sized(type, 32) - -#else -#define intra_pred_allsizes(type) \ - intra_pred_sized(type, 4) \ - intra_pred_sized(type, 8) \ - intra_pred_sized(type, 16) \ - intra_pred_sized(type, 32) - -#define intra_pred_no_4x4(type) \ - intra_pred_sized(type, 8) \ - intra_pred_sized(type, 16) \ - intra_pred_sized(type, 32) -#endif // CONFIG_VP9_HIGHBITDEPTH - -intra_pred_no_4x4(d207) -intra_pred_no_4x4(d63) -intra_pred_no_4x4(d45) -intra_pred_no_4x4(d117) -intra_pred_no_4x4(d135) -intra_pred_no_4x4(d153) -intra_pred_allsizes(v) -intra_pred_allsizes(h) -intra_pred_allsizes(tm) -intra_pred_allsizes(dc_128) -intra_pred_allsizes(dc_left) -intra_pred_allsizes(dc_top) -intra_pred_allsizes(dc) -/* clang-format on */ -#undef intra_pred_allsizes diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/inv_txfm.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/inv_txfm.c deleted file mode 100644 index 97655b3a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/inv_txfm.c +++ /dev/null @@ -1,2701 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/inv_txfm.h" - -void vpx_iwht4x4_16_add_c(const tran_low_t *input, uint8_t *dest, int stride) { - /* 4-point reversible, orthonormal inverse Walsh-Hadamard in 3.5 adds, - 0.5 shifts per pixel. */ - int i; - tran_low_t output[16]; - tran_high_t a1, b1, c1, d1, e1; - const tran_low_t *ip = input; - tran_low_t *op = output; - - for (i = 0; i < 4; i++) { - a1 = ip[0] >> UNIT_QUANT_SHIFT; - c1 = ip[1] >> UNIT_QUANT_SHIFT; - d1 = ip[2] >> UNIT_QUANT_SHIFT; - b1 = ip[3] >> UNIT_QUANT_SHIFT; - a1 += c1; - d1 -= b1; - e1 = (a1 - d1) >> 1; - b1 = e1 - b1; - c1 = e1 - c1; - a1 -= b1; - d1 += c1; - op[0] = WRAPLOW(a1); - op[1] = WRAPLOW(b1); - op[2] = WRAPLOW(c1); - op[3] = WRAPLOW(d1); - ip += 4; - op += 4; - } - - ip = output; - for (i = 0; i < 4; i++) { - a1 = ip[4 * 0]; - c1 = ip[4 * 1]; - d1 = ip[4 * 2]; - b1 = ip[4 * 3]; - a1 += c1; - d1 -= b1; - e1 = (a1 - d1) >> 1; - b1 = e1 - b1; - c1 = e1 - c1; - a1 -= b1; - d1 += c1; - dest[stride * 0] = clip_pixel_add(dest[stride * 0], WRAPLOW(a1)); - dest[stride * 1] = clip_pixel_add(dest[stride * 1], WRAPLOW(b1)); - dest[stride * 2] = clip_pixel_add(dest[stride * 2], WRAPLOW(c1)); - dest[stride * 3] = clip_pixel_add(dest[stride * 3], WRAPLOW(d1)); - - ip++; - dest++; - } -} - -void vpx_iwht4x4_1_add_c(const tran_low_t *input, uint8_t *dest, int stride) { - int i; - tran_high_t a1, e1; - tran_low_t tmp[4]; - const tran_low_t *ip = input; - tran_low_t *op = tmp; - - a1 = ip[0] >> UNIT_QUANT_SHIFT; - e1 = a1 >> 1; - a1 -= e1; - op[0] = WRAPLOW(a1); - op[1] = op[2] = op[3] = WRAPLOW(e1); - - ip = tmp; - for (i = 0; i < 4; i++) { - e1 = ip[0] >> 1; - a1 = ip[0] - e1; - dest[stride * 0] = clip_pixel_add(dest[stride * 0], a1); - dest[stride * 1] = clip_pixel_add(dest[stride * 1], e1); - dest[stride * 2] = clip_pixel_add(dest[stride * 2], e1); - dest[stride * 3] = clip_pixel_add(dest[stride * 3], e1); - ip++; - dest++; - } -} - -void iadst4_c(const tran_low_t *input, tran_low_t *output) { - tran_high_t s0, s1, s2, s3, s4, s5, s6, s7; - tran_low_t x0 = input[0]; - tran_low_t x1 = input[1]; - tran_low_t x2 = input[2]; - tran_low_t x3 = input[3]; - - if (!(x0 | x1 | x2 | x3)) { - memset(output, 0, 4 * sizeof(*output)); - return; - } - - // 32-bit result is enough for the following multiplications. - s0 = sinpi_1_9 * x0; - s1 = sinpi_2_9 * x0; - s2 = sinpi_3_9 * x1; - s3 = sinpi_4_9 * x2; - s4 = sinpi_1_9 * x2; - s5 = sinpi_2_9 * x3; - s6 = sinpi_4_9 * x3; - s7 = WRAPLOW(x0 - x2 + x3); - - s0 = s0 + s3 + s5; - s1 = s1 - s4 - s6; - s3 = s2; - s2 = sinpi_3_9 * s7; - - // 1-D transform scaling factor is sqrt(2). - // The overall dynamic range is 14b (input) + 14b (multiplication scaling) - // + 1b (addition) = 29b. - // Hence the output bit depth is 15b. - output[0] = WRAPLOW(dct_const_round_shift(s0 + s3)); - output[1] = WRAPLOW(dct_const_round_shift(s1 + s3)); - output[2] = WRAPLOW(dct_const_round_shift(s2)); - output[3] = WRAPLOW(dct_const_round_shift(s0 + s1 - s3)); -} - -void idct4_c(const tran_low_t *input, tran_low_t *output) { - int16_t step[4]; - tran_high_t temp1, temp2; - - // stage 1 - temp1 = ((int16_t)input[0] + (int16_t)input[2]) * cospi_16_64; - temp2 = ((int16_t)input[0] - (int16_t)input[2]) * cospi_16_64; - step[0] = WRAPLOW(dct_const_round_shift(temp1)); - step[1] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = (int16_t)input[1] * cospi_24_64 - (int16_t)input[3] * cospi_8_64; - temp2 = (int16_t)input[1] * cospi_8_64 + (int16_t)input[3] * cospi_24_64; - step[2] = WRAPLOW(dct_const_round_shift(temp1)); - step[3] = WRAPLOW(dct_const_round_shift(temp2)); - - // stage 2 - output[0] = WRAPLOW(step[0] + step[3]); - output[1] = WRAPLOW(step[1] + step[2]); - output[2] = WRAPLOW(step[1] - step[2]); - output[3] = WRAPLOW(step[0] - step[3]); -} - -void vpx_idct4x4_16_add_c(const tran_low_t *input, uint8_t *dest, int stride) { - int i, j; - tran_low_t out[4 * 4]; - tran_low_t *outptr = out; - tran_low_t temp_in[4], temp_out[4]; - - // Rows - for (i = 0; i < 4; ++i) { - idct4_c(input, outptr); - input += 4; - outptr += 4; - } - - // Columns - for (i = 0; i < 4; ++i) { - for (j = 0; j < 4; ++j) temp_in[j] = out[j * 4 + i]; - idct4_c(temp_in, temp_out); - for (j = 0; j < 4; ++j) { - dest[j * stride + i] = clip_pixel_add(dest[j * stride + i], - ROUND_POWER_OF_TWO(temp_out[j], 4)); - } - } -} - -void vpx_idct4x4_1_add_c(const tran_low_t *input, uint8_t *dest, int stride) { - int i; - tran_high_t a1; - tran_low_t out = - WRAPLOW(dct_const_round_shift((int16_t)input[0] * cospi_16_64)); - - out = WRAPLOW(dct_const_round_shift(out * cospi_16_64)); - a1 = ROUND_POWER_OF_TWO(out, 4); - - for (i = 0; i < 4; i++) { - dest[0] = clip_pixel_add(dest[0], a1); - dest[1] = clip_pixel_add(dest[1], a1); - dest[2] = clip_pixel_add(dest[2], a1); - dest[3] = clip_pixel_add(dest[3], a1); - dest += stride; - } -} - -void iadst8_c(const tran_low_t *input, tran_low_t *output) { - int s0, s1, s2, s3, s4, s5, s6, s7; - tran_high_t x0 = input[7]; - tran_high_t x1 = input[0]; - tran_high_t x2 = input[5]; - tran_high_t x3 = input[2]; - tran_high_t x4 = input[3]; - tran_high_t x5 = input[4]; - tran_high_t x6 = input[1]; - tran_high_t x7 = input[6]; - - if (!(x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7)) { - memset(output, 0, 8 * sizeof(*output)); - return; - } - - // stage 1 - s0 = (int)(cospi_2_64 * x0 + cospi_30_64 * x1); - s1 = (int)(cospi_30_64 * x0 - cospi_2_64 * x1); - s2 = (int)(cospi_10_64 * x2 + cospi_22_64 * x3); - s3 = (int)(cospi_22_64 * x2 - cospi_10_64 * x3); - s4 = (int)(cospi_18_64 * x4 + cospi_14_64 * x5); - s5 = (int)(cospi_14_64 * x4 - cospi_18_64 * x5); - s6 = (int)(cospi_26_64 * x6 + cospi_6_64 * x7); - s7 = (int)(cospi_6_64 * x6 - cospi_26_64 * x7); - - x0 = WRAPLOW(dct_const_round_shift(s0 + s4)); - x1 = WRAPLOW(dct_const_round_shift(s1 + s5)); - x2 = WRAPLOW(dct_const_round_shift(s2 + s6)); - x3 = WRAPLOW(dct_const_round_shift(s3 + s7)); - x4 = WRAPLOW(dct_const_round_shift(s0 - s4)); - x5 = WRAPLOW(dct_const_round_shift(s1 - s5)); - x6 = WRAPLOW(dct_const_round_shift(s2 - s6)); - x7 = WRAPLOW(dct_const_round_shift(s3 - s7)); - - // stage 2 - s0 = (int)x0; - s1 = (int)x1; - s2 = (int)x2; - s3 = (int)x3; - s4 = (int)(cospi_8_64 * x4 + cospi_24_64 * x5); - s5 = (int)(cospi_24_64 * x4 - cospi_8_64 * x5); - s6 = (int)(-cospi_24_64 * x6 + cospi_8_64 * x7); - s7 = (int)(cospi_8_64 * x6 + cospi_24_64 * x7); - - x0 = WRAPLOW(s0 + s2); - x1 = WRAPLOW(s1 + s3); - x2 = WRAPLOW(s0 - s2); - x3 = WRAPLOW(s1 - s3); - x4 = WRAPLOW(dct_const_round_shift(s4 + s6)); - x5 = WRAPLOW(dct_const_round_shift(s5 + s7)); - x6 = WRAPLOW(dct_const_round_shift(s4 - s6)); - x7 = WRAPLOW(dct_const_round_shift(s5 - s7)); - - // stage 3 - s2 = (int)(cospi_16_64 * (x2 + x3)); - s3 = (int)(cospi_16_64 * (x2 - x3)); - s6 = (int)(cospi_16_64 * (x6 + x7)); - s7 = (int)(cospi_16_64 * (x6 - x7)); - - x2 = WRAPLOW(dct_const_round_shift(s2)); - x3 = WRAPLOW(dct_const_round_shift(s3)); - x6 = WRAPLOW(dct_const_round_shift(s6)); - x7 = WRAPLOW(dct_const_round_shift(s7)); - - output[0] = WRAPLOW(x0); - output[1] = WRAPLOW(-x4); - output[2] = WRAPLOW(x6); - output[3] = WRAPLOW(-x2); - output[4] = WRAPLOW(x3); - output[5] = WRAPLOW(-x7); - output[6] = WRAPLOW(x5); - output[7] = WRAPLOW(-x1); -} - -void idct8_c(const tran_low_t *input, tran_low_t *output) { - int16_t step1[8], step2[8]; - tran_high_t temp1, temp2; - - // stage 1 - step1[0] = (int16_t)input[0]; - step1[2] = (int16_t)input[4]; - step1[1] = (int16_t)input[2]; - step1[3] = (int16_t)input[6]; - temp1 = (int16_t)input[1] * cospi_28_64 - (int16_t)input[7] * cospi_4_64; - temp2 = (int16_t)input[1] * cospi_4_64 + (int16_t)input[7] * cospi_28_64; - step1[4] = WRAPLOW(dct_const_round_shift(temp1)); - step1[7] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = (int16_t)input[5] * cospi_12_64 - (int16_t)input[3] * cospi_20_64; - temp2 = (int16_t)input[5] * cospi_20_64 + (int16_t)input[3] * cospi_12_64; - step1[5] = WRAPLOW(dct_const_round_shift(temp1)); - step1[6] = WRAPLOW(dct_const_round_shift(temp2)); - - // stage 2 - temp1 = (step1[0] + step1[2]) * cospi_16_64; - temp2 = (step1[0] - step1[2]) * cospi_16_64; - step2[0] = WRAPLOW(dct_const_round_shift(temp1)); - step2[1] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = step1[1] * cospi_24_64 - step1[3] * cospi_8_64; - temp2 = step1[1] * cospi_8_64 + step1[3] * cospi_24_64; - step2[2] = WRAPLOW(dct_const_round_shift(temp1)); - step2[3] = WRAPLOW(dct_const_round_shift(temp2)); - step2[4] = WRAPLOW(step1[4] + step1[5]); - step2[5] = WRAPLOW(step1[4] - step1[5]); - step2[6] = WRAPLOW(-step1[6] + step1[7]); - step2[7] = WRAPLOW(step1[6] + step1[7]); - - // stage 3 - step1[0] = WRAPLOW(step2[0] + step2[3]); - step1[1] = WRAPLOW(step2[1] + step2[2]); - step1[2] = WRAPLOW(step2[1] - step2[2]); - step1[3] = WRAPLOW(step2[0] - step2[3]); - step1[4] = step2[4]; - temp1 = (step2[6] - step2[5]) * cospi_16_64; - temp2 = (step2[5] + step2[6]) * cospi_16_64; - step1[5] = WRAPLOW(dct_const_round_shift(temp1)); - step1[6] = WRAPLOW(dct_const_round_shift(temp2)); - step1[7] = step2[7]; - - // stage 4 - output[0] = WRAPLOW(step1[0] + step1[7]); - output[1] = WRAPLOW(step1[1] + step1[6]); - output[2] = WRAPLOW(step1[2] + step1[5]); - output[3] = WRAPLOW(step1[3] + step1[4]); - output[4] = WRAPLOW(step1[3] - step1[4]); - output[5] = WRAPLOW(step1[2] - step1[5]); - output[6] = WRAPLOW(step1[1] - step1[6]); - output[7] = WRAPLOW(step1[0] - step1[7]); -} - -void vpx_idct8x8_64_add_c(const tran_low_t *input, uint8_t *dest, int stride) { - int i, j; - tran_low_t out[8 * 8]; - tran_low_t *outptr = out; - tran_low_t temp_in[8], temp_out[8]; - - // First transform rows - for (i = 0; i < 8; ++i) { - idct8_c(input, outptr); - input += 8; - outptr += 8; - } - - // Then transform columns - for (i = 0; i < 8; ++i) { - for (j = 0; j < 8; ++j) temp_in[j] = out[j * 8 + i]; - idct8_c(temp_in, temp_out); - for (j = 0; j < 8; ++j) { - dest[j * stride + i] = clip_pixel_add(dest[j * stride + i], - ROUND_POWER_OF_TWO(temp_out[j], 5)); - } - } -} - -void vpx_idct8x8_12_add_c(const tran_low_t *input, uint8_t *dest, int stride) { - int i, j; - tran_low_t out[8 * 8] = { 0 }; - tran_low_t *outptr = out; - tran_low_t temp_in[8], temp_out[8]; - - // First transform rows - // Only first 4 row has non-zero coefs - for (i = 0; i < 4; ++i) { - idct8_c(input, outptr); - input += 8; - outptr += 8; - } - - // Then transform columns - for (i = 0; i < 8; ++i) { - for (j = 0; j < 8; ++j) temp_in[j] = out[j * 8 + i]; - idct8_c(temp_in, temp_out); - for (j = 0; j < 8; ++j) { - dest[j * stride + i] = clip_pixel_add(dest[j * stride + i], - ROUND_POWER_OF_TWO(temp_out[j], 5)); - } - } -} - -void vpx_idct8x8_1_add_c(const tran_low_t *input, uint8_t *dest, int stride) { - int i, j; - tran_high_t a1; - tran_low_t out = - WRAPLOW(dct_const_round_shift((int16_t)input[0] * cospi_16_64)); - - out = WRAPLOW(dct_const_round_shift(out * cospi_16_64)); - a1 = ROUND_POWER_OF_TWO(out, 5); - for (j = 0; j < 8; ++j) { - for (i = 0; i < 8; ++i) dest[i] = clip_pixel_add(dest[i], a1); - dest += stride; - } -} - -void iadst16_c(const tran_low_t *input, tran_low_t *output) { - tran_high_t s0, s1, s2, s3, s4, s5, s6, s7, s8; - tran_high_t s9, s10, s11, s12, s13, s14, s15; - tran_high_t x0 = input[15]; - tran_high_t x1 = input[0]; - tran_high_t x2 = input[13]; - tran_high_t x3 = input[2]; - tran_high_t x4 = input[11]; - tran_high_t x5 = input[4]; - tran_high_t x6 = input[9]; - tran_high_t x7 = input[6]; - tran_high_t x8 = input[7]; - tran_high_t x9 = input[8]; - tran_high_t x10 = input[5]; - tran_high_t x11 = input[10]; - tran_high_t x12 = input[3]; - tran_high_t x13 = input[12]; - tran_high_t x14 = input[1]; - tran_high_t x15 = input[14]; - - if (!(x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | x11 | x12 | - x13 | x14 | x15)) { - memset(output, 0, 16 * sizeof(*output)); - return; - } - - // stage 1 - s0 = x0 * cospi_1_64 + x1 * cospi_31_64; - s1 = x0 * cospi_31_64 - x1 * cospi_1_64; - s2 = x2 * cospi_5_64 + x3 * cospi_27_64; - s3 = x2 * cospi_27_64 - x3 * cospi_5_64; - s4 = x4 * cospi_9_64 + x5 * cospi_23_64; - s5 = x4 * cospi_23_64 - x5 * cospi_9_64; - s6 = x6 * cospi_13_64 + x7 * cospi_19_64; - s7 = x6 * cospi_19_64 - x7 * cospi_13_64; - s8 = x8 * cospi_17_64 + x9 * cospi_15_64; - s9 = x8 * cospi_15_64 - x9 * cospi_17_64; - s10 = x10 * cospi_21_64 + x11 * cospi_11_64; - s11 = x10 * cospi_11_64 - x11 * cospi_21_64; - s12 = x12 * cospi_25_64 + x13 * cospi_7_64; - s13 = x12 * cospi_7_64 - x13 * cospi_25_64; - s14 = x14 * cospi_29_64 + x15 * cospi_3_64; - s15 = x14 * cospi_3_64 - x15 * cospi_29_64; - - x0 = WRAPLOW(dct_const_round_shift(s0 + s8)); - x1 = WRAPLOW(dct_const_round_shift(s1 + s9)); - x2 = WRAPLOW(dct_const_round_shift(s2 + s10)); - x3 = WRAPLOW(dct_const_round_shift(s3 + s11)); - x4 = WRAPLOW(dct_const_round_shift(s4 + s12)); - x5 = WRAPLOW(dct_const_round_shift(s5 + s13)); - x6 = WRAPLOW(dct_const_round_shift(s6 + s14)); - x7 = WRAPLOW(dct_const_round_shift(s7 + s15)); - x8 = WRAPLOW(dct_const_round_shift(s0 - s8)); - x9 = WRAPLOW(dct_const_round_shift(s1 - s9)); - x10 = WRAPLOW(dct_const_round_shift(s2 - s10)); - x11 = WRAPLOW(dct_const_round_shift(s3 - s11)); - x12 = WRAPLOW(dct_const_round_shift(s4 - s12)); - x13 = WRAPLOW(dct_const_round_shift(s5 - s13)); - x14 = WRAPLOW(dct_const_round_shift(s6 - s14)); - x15 = WRAPLOW(dct_const_round_shift(s7 - s15)); - - // stage 2 - s0 = x0; - s1 = x1; - s2 = x2; - s3 = x3; - s4 = x4; - s5 = x5; - s6 = x6; - s7 = x7; - s8 = x8 * cospi_4_64 + x9 * cospi_28_64; - s9 = x8 * cospi_28_64 - x9 * cospi_4_64; - s10 = x10 * cospi_20_64 + x11 * cospi_12_64; - s11 = x10 * cospi_12_64 - x11 * cospi_20_64; - s12 = -x12 * cospi_28_64 + x13 * cospi_4_64; - s13 = x12 * cospi_4_64 + x13 * cospi_28_64; - s14 = -x14 * cospi_12_64 + x15 * cospi_20_64; - s15 = x14 * cospi_20_64 + x15 * cospi_12_64; - - x0 = WRAPLOW(s0 + s4); - x1 = WRAPLOW(s1 + s5); - x2 = WRAPLOW(s2 + s6); - x3 = WRAPLOW(s3 + s7); - x4 = WRAPLOW(s0 - s4); - x5 = WRAPLOW(s1 - s5); - x6 = WRAPLOW(s2 - s6); - x7 = WRAPLOW(s3 - s7); - x8 = WRAPLOW(dct_const_round_shift(s8 + s12)); - x9 = WRAPLOW(dct_const_round_shift(s9 + s13)); - x10 = WRAPLOW(dct_const_round_shift(s10 + s14)); - x11 = WRAPLOW(dct_const_round_shift(s11 + s15)); - x12 = WRAPLOW(dct_const_round_shift(s8 - s12)); - x13 = WRAPLOW(dct_const_round_shift(s9 - s13)); - x14 = WRAPLOW(dct_const_round_shift(s10 - s14)); - x15 = WRAPLOW(dct_const_round_shift(s11 - s15)); - - // stage 3 - s0 = x0; - s1 = x1; - s2 = x2; - s3 = x3; - s4 = x4 * cospi_8_64 + x5 * cospi_24_64; - s5 = x4 * cospi_24_64 - x5 * cospi_8_64; - s6 = -x6 * cospi_24_64 + x7 * cospi_8_64; - s7 = x6 * cospi_8_64 + x7 * cospi_24_64; - s8 = x8; - s9 = x9; - s10 = x10; - s11 = x11; - s12 = x12 * cospi_8_64 + x13 * cospi_24_64; - s13 = x12 * cospi_24_64 - x13 * cospi_8_64; - s14 = -x14 * cospi_24_64 + x15 * cospi_8_64; - s15 = x14 * cospi_8_64 + x15 * cospi_24_64; - - x0 = WRAPLOW(s0 + s2); - x1 = WRAPLOW(s1 + s3); - x2 = WRAPLOW(s0 - s2); - x3 = WRAPLOW(s1 - s3); - x4 = WRAPLOW(dct_const_round_shift(s4 + s6)); - x5 = WRAPLOW(dct_const_round_shift(s5 + s7)); - x6 = WRAPLOW(dct_const_round_shift(s4 - s6)); - x7 = WRAPLOW(dct_const_round_shift(s5 - s7)); - x8 = WRAPLOW(s8 + s10); - x9 = WRAPLOW(s9 + s11); - x10 = WRAPLOW(s8 - s10); - x11 = WRAPLOW(s9 - s11); - x12 = WRAPLOW(dct_const_round_shift(s12 + s14)); - x13 = WRAPLOW(dct_const_round_shift(s13 + s15)); - x14 = WRAPLOW(dct_const_round_shift(s12 - s14)); - x15 = WRAPLOW(dct_const_round_shift(s13 - s15)); - - // stage 4 - s2 = (-cospi_16_64) * (x2 + x3); - s3 = cospi_16_64 * (x2 - x3); - s6 = cospi_16_64 * (x6 + x7); - s7 = cospi_16_64 * (-x6 + x7); - s10 = cospi_16_64 * (x10 + x11); - s11 = cospi_16_64 * (-x10 + x11); - s14 = (-cospi_16_64) * (x14 + x15); - s15 = cospi_16_64 * (x14 - x15); - - x2 = WRAPLOW(dct_const_round_shift(s2)); - x3 = WRAPLOW(dct_const_round_shift(s3)); - x6 = WRAPLOW(dct_const_round_shift(s6)); - x7 = WRAPLOW(dct_const_round_shift(s7)); - x10 = WRAPLOW(dct_const_round_shift(s10)); - x11 = WRAPLOW(dct_const_round_shift(s11)); - x14 = WRAPLOW(dct_const_round_shift(s14)); - x15 = WRAPLOW(dct_const_round_shift(s15)); - - output[0] = WRAPLOW(x0); - output[1] = WRAPLOW(-x8); - output[2] = WRAPLOW(x12); - output[3] = WRAPLOW(-x4); - output[4] = WRAPLOW(x6); - output[5] = WRAPLOW(x14); - output[6] = WRAPLOW(x10); - output[7] = WRAPLOW(x2); - output[8] = WRAPLOW(x3); - output[9] = WRAPLOW(x11); - output[10] = WRAPLOW(x15); - output[11] = WRAPLOW(x7); - output[12] = WRAPLOW(x5); - output[13] = WRAPLOW(-x13); - output[14] = WRAPLOW(x9); - output[15] = WRAPLOW(-x1); -} - -void idct16_c(const tran_low_t *input, tran_low_t *output) { - int16_t step1[16], step2[16]; - tran_high_t temp1, temp2; - - // stage 1 - step1[0] = (int16_t)input[0 / 2]; - step1[1] = (int16_t)input[16 / 2]; - step1[2] = (int16_t)input[8 / 2]; - step1[3] = (int16_t)input[24 / 2]; - step1[4] = (int16_t)input[4 / 2]; - step1[5] = (int16_t)input[20 / 2]; - step1[6] = (int16_t)input[12 / 2]; - step1[7] = (int16_t)input[28 / 2]; - step1[8] = (int16_t)input[2 / 2]; - step1[9] = (int16_t)input[18 / 2]; - step1[10] = (int16_t)input[10 / 2]; - step1[11] = (int16_t)input[26 / 2]; - step1[12] = (int16_t)input[6 / 2]; - step1[13] = (int16_t)input[22 / 2]; - step1[14] = (int16_t)input[14 / 2]; - step1[15] = (int16_t)input[30 / 2]; - - // stage 2 - step2[0] = step1[0]; - step2[1] = step1[1]; - step2[2] = step1[2]; - step2[3] = step1[3]; - step2[4] = step1[4]; - step2[5] = step1[5]; - step2[6] = step1[6]; - step2[7] = step1[7]; - - temp1 = step1[8] * cospi_30_64 - step1[15] * cospi_2_64; - temp2 = step1[8] * cospi_2_64 + step1[15] * cospi_30_64; - step2[8] = WRAPLOW(dct_const_round_shift(temp1)); - step2[15] = WRAPLOW(dct_const_round_shift(temp2)); - - temp1 = step1[9] * cospi_14_64 - step1[14] * cospi_18_64; - temp2 = step1[9] * cospi_18_64 + step1[14] * cospi_14_64; - step2[9] = WRAPLOW(dct_const_round_shift(temp1)); - step2[14] = WRAPLOW(dct_const_round_shift(temp2)); - - temp1 = step1[10] * cospi_22_64 - step1[13] * cospi_10_64; - temp2 = step1[10] * cospi_10_64 + step1[13] * cospi_22_64; - step2[10] = WRAPLOW(dct_const_round_shift(temp1)); - step2[13] = WRAPLOW(dct_const_round_shift(temp2)); - - temp1 = step1[11] * cospi_6_64 - step1[12] * cospi_26_64; - temp2 = step1[11] * cospi_26_64 + step1[12] * cospi_6_64; - step2[11] = WRAPLOW(dct_const_round_shift(temp1)); - step2[12] = WRAPLOW(dct_const_round_shift(temp2)); - - // stage 3 - step1[0] = step2[0]; - step1[1] = step2[1]; - step1[2] = step2[2]; - step1[3] = step2[3]; - - temp1 = step2[4] * cospi_28_64 - step2[7] * cospi_4_64; - temp2 = step2[4] * cospi_4_64 + step2[7] * cospi_28_64; - step1[4] = WRAPLOW(dct_const_round_shift(temp1)); - step1[7] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = step2[5] * cospi_12_64 - step2[6] * cospi_20_64; - temp2 = step2[5] * cospi_20_64 + step2[6] * cospi_12_64; - step1[5] = WRAPLOW(dct_const_round_shift(temp1)); - step1[6] = WRAPLOW(dct_const_round_shift(temp2)); - - step1[8] = WRAPLOW(step2[8] + step2[9]); - step1[9] = WRAPLOW(step2[8] - step2[9]); - step1[10] = WRAPLOW(-step2[10] + step2[11]); - step1[11] = WRAPLOW(step2[10] + step2[11]); - step1[12] = WRAPLOW(step2[12] + step2[13]); - step1[13] = WRAPLOW(step2[12] - step2[13]); - step1[14] = WRAPLOW(-step2[14] + step2[15]); - step1[15] = WRAPLOW(step2[14] + step2[15]); - - // stage 4 - temp1 = (step1[0] + step1[1]) * cospi_16_64; - temp2 = (step1[0] - step1[1]) * cospi_16_64; - step2[0] = WRAPLOW(dct_const_round_shift(temp1)); - step2[1] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = step1[2] * cospi_24_64 - step1[3] * cospi_8_64; - temp2 = step1[2] * cospi_8_64 + step1[3] * cospi_24_64; - step2[2] = WRAPLOW(dct_const_round_shift(temp1)); - step2[3] = WRAPLOW(dct_const_round_shift(temp2)); - step2[4] = WRAPLOW(step1[4] + step1[5]); - step2[5] = WRAPLOW(step1[4] - step1[5]); - step2[6] = WRAPLOW(-step1[6] + step1[7]); - step2[7] = WRAPLOW(step1[6] + step1[7]); - - step2[8] = step1[8]; - step2[15] = step1[15]; - temp1 = -step1[9] * cospi_8_64 + step1[14] * cospi_24_64; - temp2 = step1[9] * cospi_24_64 + step1[14] * cospi_8_64; - step2[9] = WRAPLOW(dct_const_round_shift(temp1)); - step2[14] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = -step1[10] * cospi_24_64 - step1[13] * cospi_8_64; - temp2 = -step1[10] * cospi_8_64 + step1[13] * cospi_24_64; - step2[10] = WRAPLOW(dct_const_round_shift(temp1)); - step2[13] = WRAPLOW(dct_const_round_shift(temp2)); - step2[11] = step1[11]; - step2[12] = step1[12]; - - // stage 5 - step1[0] = WRAPLOW(step2[0] + step2[3]); - step1[1] = WRAPLOW(step2[1] + step2[2]); - step1[2] = WRAPLOW(step2[1] - step2[2]); - step1[3] = WRAPLOW(step2[0] - step2[3]); - step1[4] = step2[4]; - temp1 = (step2[6] - step2[5]) * cospi_16_64; - temp2 = (step2[5] + step2[6]) * cospi_16_64; - step1[5] = WRAPLOW(dct_const_round_shift(temp1)); - step1[6] = WRAPLOW(dct_const_round_shift(temp2)); - step1[7] = step2[7]; - - step1[8] = WRAPLOW(step2[8] + step2[11]); - step1[9] = WRAPLOW(step2[9] + step2[10]); - step1[10] = WRAPLOW(step2[9] - step2[10]); - step1[11] = WRAPLOW(step2[8] - step2[11]); - step1[12] = WRAPLOW(-step2[12] + step2[15]); - step1[13] = WRAPLOW(-step2[13] + step2[14]); - step1[14] = WRAPLOW(step2[13] + step2[14]); - step1[15] = WRAPLOW(step2[12] + step2[15]); - - // stage 6 - step2[0] = WRAPLOW(step1[0] + step1[7]); - step2[1] = WRAPLOW(step1[1] + step1[6]); - step2[2] = WRAPLOW(step1[2] + step1[5]); - step2[3] = WRAPLOW(step1[3] + step1[4]); - step2[4] = WRAPLOW(step1[3] - step1[4]); - step2[5] = WRAPLOW(step1[2] - step1[5]); - step2[6] = WRAPLOW(step1[1] - step1[6]); - step2[7] = WRAPLOW(step1[0] - step1[7]); - step2[8] = step1[8]; - step2[9] = step1[9]; - temp1 = (-step1[10] + step1[13]) * cospi_16_64; - temp2 = (step1[10] + step1[13]) * cospi_16_64; - step2[10] = WRAPLOW(dct_const_round_shift(temp1)); - step2[13] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = (-step1[11] + step1[12]) * cospi_16_64; - temp2 = (step1[11] + step1[12]) * cospi_16_64; - step2[11] = WRAPLOW(dct_const_round_shift(temp1)); - step2[12] = WRAPLOW(dct_const_round_shift(temp2)); - step2[14] = step1[14]; - step2[15] = step1[15]; - - // stage 7 - output[0] = (tran_low_t)WRAPLOW(step2[0] + step2[15]); - output[1] = (tran_low_t)WRAPLOW(step2[1] + step2[14]); - output[2] = (tran_low_t)WRAPLOW(step2[2] + step2[13]); - output[3] = (tran_low_t)WRAPLOW(step2[3] + step2[12]); - output[4] = (tran_low_t)WRAPLOW(step2[4] + step2[11]); - output[5] = (tran_low_t)WRAPLOW(step2[5] + step2[10]); - output[6] = (tran_low_t)WRAPLOW(step2[6] + step2[9]); - output[7] = (tran_low_t)WRAPLOW(step2[7] + step2[8]); - output[8] = (tran_low_t)WRAPLOW(step2[7] - step2[8]); - output[9] = (tran_low_t)WRAPLOW(step2[6] - step2[9]); - output[10] = (tran_low_t)WRAPLOW(step2[5] - step2[10]); - output[11] = (tran_low_t)WRAPLOW(step2[4] - step2[11]); - output[12] = (tran_low_t)WRAPLOW(step2[3] - step2[12]); - output[13] = (tran_low_t)WRAPLOW(step2[2] - step2[13]); - output[14] = (tran_low_t)WRAPLOW(step2[1] - step2[14]); - output[15] = (tran_low_t)WRAPLOW(step2[0] - step2[15]); -} - -void vpx_idct16x16_256_add_c(const tran_low_t *input, uint8_t *dest, - int stride) { - int i, j; - tran_low_t out[16 * 16]; - tran_low_t *outptr = out; - tran_low_t temp_in[16], temp_out[16]; - - // First transform rows - for (i = 0; i < 16; ++i) { - idct16_c(input, outptr); - input += 16; - outptr += 16; - } - - // Then transform columns - for (i = 0; i < 16; ++i) { - for (j = 0; j < 16; ++j) temp_in[j] = out[j * 16 + i]; - idct16_c(temp_in, temp_out); - for (j = 0; j < 16; ++j) { - dest[j * stride + i] = clip_pixel_add(dest[j * stride + i], - ROUND_POWER_OF_TWO(temp_out[j], 6)); - } - } -} - -void vpx_idct16x16_38_add_c(const tran_low_t *input, uint8_t *dest, - int stride) { - int i, j; - tran_low_t out[16 * 16] = { 0 }; - tran_low_t *outptr = out; - tran_low_t temp_in[16], temp_out[16]; - - // First transform rows. Since all non-zero dct coefficients are in - // upper-left 8x8 area, we only need to calculate first 8 rows here. - for (i = 0; i < 8; ++i) { - idct16_c(input, outptr); - input += 16; - outptr += 16; - } - - // Then transform columns - for (i = 0; i < 16; ++i) { - for (j = 0; j < 16; ++j) temp_in[j] = out[j * 16 + i]; - idct16_c(temp_in, temp_out); - for (j = 0; j < 16; ++j) { - dest[j * stride + i] = clip_pixel_add(dest[j * stride + i], - ROUND_POWER_OF_TWO(temp_out[j], 6)); - } - } -} - -void vpx_idct16x16_10_add_c(const tran_low_t *input, uint8_t *dest, - int stride) { - int i, j; - tran_low_t out[16 * 16] = { 0 }; - tran_low_t *outptr = out; - tran_low_t temp_in[16], temp_out[16]; - - // First transform rows. Since all non-zero dct coefficients are in - // upper-left 4x4 area, we only need to calculate first 4 rows here. - for (i = 0; i < 4; ++i) { - idct16_c(input, outptr); - input += 16; - outptr += 16; - } - - // Then transform columns - for (i = 0; i < 16; ++i) { - for (j = 0; j < 16; ++j) temp_in[j] = out[j * 16 + i]; - idct16_c(temp_in, temp_out); - for (j = 0; j < 16; ++j) { - dest[j * stride + i] = clip_pixel_add(dest[j * stride + i], - ROUND_POWER_OF_TWO(temp_out[j], 6)); - } - } -} - -void vpx_idct16x16_1_add_c(const tran_low_t *input, uint8_t *dest, int stride) { - int i, j; - tran_high_t a1; - tran_low_t out = - WRAPLOW(dct_const_round_shift((int16_t)input[0] * cospi_16_64)); - - out = WRAPLOW(dct_const_round_shift(out * cospi_16_64)); - a1 = ROUND_POWER_OF_TWO(out, 6); - for (j = 0; j < 16; ++j) { - for (i = 0; i < 16; ++i) dest[i] = clip_pixel_add(dest[i], a1); - dest += stride; - } -} - -void idct32_c(const tran_low_t *input, tran_low_t *output) { - int16_t step1[32], step2[32]; - tran_high_t temp1, temp2; - - // stage 1 - step1[0] = (int16_t)input[0]; - step1[1] = (int16_t)input[16]; - step1[2] = (int16_t)input[8]; - step1[3] = (int16_t)input[24]; - step1[4] = (int16_t)input[4]; - step1[5] = (int16_t)input[20]; - step1[6] = (int16_t)input[12]; - step1[7] = (int16_t)input[28]; - step1[8] = (int16_t)input[2]; - step1[9] = (int16_t)input[18]; - step1[10] = (int16_t)input[10]; - step1[11] = (int16_t)input[26]; - step1[12] = (int16_t)input[6]; - step1[13] = (int16_t)input[22]; - step1[14] = (int16_t)input[14]; - step1[15] = (int16_t)input[30]; - - temp1 = (int16_t)input[1] * cospi_31_64 - (int16_t)input[31] * cospi_1_64; - temp2 = (int16_t)input[1] * cospi_1_64 + (int16_t)input[31] * cospi_31_64; - step1[16] = WRAPLOW(dct_const_round_shift(temp1)); - step1[31] = WRAPLOW(dct_const_round_shift(temp2)); - - temp1 = (int16_t)input[17] * cospi_15_64 - (int16_t)input[15] * cospi_17_64; - temp2 = (int16_t)input[17] * cospi_17_64 + (int16_t)input[15] * cospi_15_64; - step1[17] = WRAPLOW(dct_const_round_shift(temp1)); - step1[30] = WRAPLOW(dct_const_round_shift(temp2)); - - temp1 = (int16_t)input[9] * cospi_23_64 - (int16_t)input[23] * cospi_9_64; - temp2 = (int16_t)input[9] * cospi_9_64 + (int16_t)input[23] * cospi_23_64; - step1[18] = WRAPLOW(dct_const_round_shift(temp1)); - step1[29] = WRAPLOW(dct_const_round_shift(temp2)); - - temp1 = (int16_t)input[25] * cospi_7_64 - (int16_t)input[7] * cospi_25_64; - temp2 = (int16_t)input[25] * cospi_25_64 + (int16_t)input[7] * cospi_7_64; - step1[19] = WRAPLOW(dct_const_round_shift(temp1)); - step1[28] = WRAPLOW(dct_const_round_shift(temp2)); - - temp1 = (int16_t)input[5] * cospi_27_64 - (int16_t)input[27] * cospi_5_64; - temp2 = (int16_t)input[5] * cospi_5_64 + (int16_t)input[27] * cospi_27_64; - step1[20] = WRAPLOW(dct_const_round_shift(temp1)); - step1[27] = WRAPLOW(dct_const_round_shift(temp2)); - - temp1 = (int16_t)input[21] * cospi_11_64 - (int16_t)input[11] * cospi_21_64; - temp2 = (int16_t)input[21] * cospi_21_64 + (int16_t)input[11] * cospi_11_64; - step1[21] = WRAPLOW(dct_const_round_shift(temp1)); - step1[26] = WRAPLOW(dct_const_round_shift(temp2)); - - temp1 = (int16_t)input[13] * cospi_19_64 - (int16_t)input[19] * cospi_13_64; - temp2 = (int16_t)input[13] * cospi_13_64 + (int16_t)input[19] * cospi_19_64; - step1[22] = WRAPLOW(dct_const_round_shift(temp1)); - step1[25] = WRAPLOW(dct_const_round_shift(temp2)); - - temp1 = (int16_t)input[29] * cospi_3_64 - (int16_t)input[3] * cospi_29_64; - temp2 = (int16_t)input[29] * cospi_29_64 + (int16_t)input[3] * cospi_3_64; - step1[23] = WRAPLOW(dct_const_round_shift(temp1)); - step1[24] = WRAPLOW(dct_const_round_shift(temp2)); - - // stage 2 - step2[0] = step1[0]; - step2[1] = step1[1]; - step2[2] = step1[2]; - step2[3] = step1[3]; - step2[4] = step1[4]; - step2[5] = step1[5]; - step2[6] = step1[6]; - step2[7] = step1[7]; - - temp1 = step1[8] * cospi_30_64 - step1[15] * cospi_2_64; - temp2 = step1[8] * cospi_2_64 + step1[15] * cospi_30_64; - step2[8] = WRAPLOW(dct_const_round_shift(temp1)); - step2[15] = WRAPLOW(dct_const_round_shift(temp2)); - - temp1 = step1[9] * cospi_14_64 - step1[14] * cospi_18_64; - temp2 = step1[9] * cospi_18_64 + step1[14] * cospi_14_64; - step2[9] = WRAPLOW(dct_const_round_shift(temp1)); - step2[14] = WRAPLOW(dct_const_round_shift(temp2)); - - temp1 = step1[10] * cospi_22_64 - step1[13] * cospi_10_64; - temp2 = step1[10] * cospi_10_64 + step1[13] * cospi_22_64; - step2[10] = WRAPLOW(dct_const_round_shift(temp1)); - step2[13] = WRAPLOW(dct_const_round_shift(temp2)); - - temp1 = step1[11] * cospi_6_64 - step1[12] * cospi_26_64; - temp2 = step1[11] * cospi_26_64 + step1[12] * cospi_6_64; - step2[11] = WRAPLOW(dct_const_round_shift(temp1)); - step2[12] = WRAPLOW(dct_const_round_shift(temp2)); - - step2[16] = WRAPLOW(step1[16] + step1[17]); - step2[17] = WRAPLOW(step1[16] - step1[17]); - step2[18] = WRAPLOW(-step1[18] + step1[19]); - step2[19] = WRAPLOW(step1[18] + step1[19]); - step2[20] = WRAPLOW(step1[20] + step1[21]); - step2[21] = WRAPLOW(step1[20] - step1[21]); - step2[22] = WRAPLOW(-step1[22] + step1[23]); - step2[23] = WRAPLOW(step1[22] + step1[23]); - step2[24] = WRAPLOW(step1[24] + step1[25]); - step2[25] = WRAPLOW(step1[24] - step1[25]); - step2[26] = WRAPLOW(-step1[26] + step1[27]); - step2[27] = WRAPLOW(step1[26] + step1[27]); - step2[28] = WRAPLOW(step1[28] + step1[29]); - step2[29] = WRAPLOW(step1[28] - step1[29]); - step2[30] = WRAPLOW(-step1[30] + step1[31]); - step2[31] = WRAPLOW(step1[30] + step1[31]); - - // stage 3 - step1[0] = step2[0]; - step1[1] = step2[1]; - step1[2] = step2[2]; - step1[3] = step2[3]; - - temp1 = step2[4] * cospi_28_64 - step2[7] * cospi_4_64; - temp2 = step2[4] * cospi_4_64 + step2[7] * cospi_28_64; - step1[4] = WRAPLOW(dct_const_round_shift(temp1)); - step1[7] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = step2[5] * cospi_12_64 - step2[6] * cospi_20_64; - temp2 = step2[5] * cospi_20_64 + step2[6] * cospi_12_64; - step1[5] = WRAPLOW(dct_const_round_shift(temp1)); - step1[6] = WRAPLOW(dct_const_round_shift(temp2)); - - step1[8] = WRAPLOW(step2[8] + step2[9]); - step1[9] = WRAPLOW(step2[8] - step2[9]); - step1[10] = WRAPLOW(-step2[10] + step2[11]); - step1[11] = WRAPLOW(step2[10] + step2[11]); - step1[12] = WRAPLOW(step2[12] + step2[13]); - step1[13] = WRAPLOW(step2[12] - step2[13]); - step1[14] = WRAPLOW(-step2[14] + step2[15]); - step1[15] = WRAPLOW(step2[14] + step2[15]); - - step1[16] = step2[16]; - step1[31] = step2[31]; - temp1 = -step2[17] * cospi_4_64 + step2[30] * cospi_28_64; - temp2 = step2[17] * cospi_28_64 + step2[30] * cospi_4_64; - step1[17] = WRAPLOW(dct_const_round_shift(temp1)); - step1[30] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = -step2[18] * cospi_28_64 - step2[29] * cospi_4_64; - temp2 = -step2[18] * cospi_4_64 + step2[29] * cospi_28_64; - step1[18] = WRAPLOW(dct_const_round_shift(temp1)); - step1[29] = WRAPLOW(dct_const_round_shift(temp2)); - step1[19] = step2[19]; - step1[20] = step2[20]; - temp1 = -step2[21] * cospi_20_64 + step2[26] * cospi_12_64; - temp2 = step2[21] * cospi_12_64 + step2[26] * cospi_20_64; - step1[21] = WRAPLOW(dct_const_round_shift(temp1)); - step1[26] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = -step2[22] * cospi_12_64 - step2[25] * cospi_20_64; - temp2 = -step2[22] * cospi_20_64 + step2[25] * cospi_12_64; - step1[22] = WRAPLOW(dct_const_round_shift(temp1)); - step1[25] = WRAPLOW(dct_const_round_shift(temp2)); - step1[23] = step2[23]; - step1[24] = step2[24]; - step1[27] = step2[27]; - step1[28] = step2[28]; - - // stage 4 - temp1 = (step1[0] + step1[1]) * cospi_16_64; - temp2 = (step1[0] - step1[1]) * cospi_16_64; - step2[0] = WRAPLOW(dct_const_round_shift(temp1)); - step2[1] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = step1[2] * cospi_24_64 - step1[3] * cospi_8_64; - temp2 = step1[2] * cospi_8_64 + step1[3] * cospi_24_64; - step2[2] = WRAPLOW(dct_const_round_shift(temp1)); - step2[3] = WRAPLOW(dct_const_round_shift(temp2)); - step2[4] = WRAPLOW(step1[4] + step1[5]); - step2[5] = WRAPLOW(step1[4] - step1[5]); - step2[6] = WRAPLOW(-step1[6] + step1[7]); - step2[7] = WRAPLOW(step1[6] + step1[7]); - - step2[8] = step1[8]; - step2[15] = step1[15]; - temp1 = -step1[9] * cospi_8_64 + step1[14] * cospi_24_64; - temp2 = step1[9] * cospi_24_64 + step1[14] * cospi_8_64; - step2[9] = WRAPLOW(dct_const_round_shift(temp1)); - step2[14] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = -step1[10] * cospi_24_64 - step1[13] * cospi_8_64; - temp2 = -step1[10] * cospi_8_64 + step1[13] * cospi_24_64; - step2[10] = WRAPLOW(dct_const_round_shift(temp1)); - step2[13] = WRAPLOW(dct_const_round_shift(temp2)); - step2[11] = step1[11]; - step2[12] = step1[12]; - - step2[16] = WRAPLOW(step1[16] + step1[19]); - step2[17] = WRAPLOW(step1[17] + step1[18]); - step2[18] = WRAPLOW(step1[17] - step1[18]); - step2[19] = WRAPLOW(step1[16] - step1[19]); - step2[20] = WRAPLOW(-step1[20] + step1[23]); - step2[21] = WRAPLOW(-step1[21] + step1[22]); - step2[22] = WRAPLOW(step1[21] + step1[22]); - step2[23] = WRAPLOW(step1[20] + step1[23]); - - step2[24] = WRAPLOW(step1[24] + step1[27]); - step2[25] = WRAPLOW(step1[25] + step1[26]); - step2[26] = WRAPLOW(step1[25] - step1[26]); - step2[27] = WRAPLOW(step1[24] - step1[27]); - step2[28] = WRAPLOW(-step1[28] + step1[31]); - step2[29] = WRAPLOW(-step1[29] + step1[30]); - step2[30] = WRAPLOW(step1[29] + step1[30]); - step2[31] = WRAPLOW(step1[28] + step1[31]); - - // stage 5 - step1[0] = WRAPLOW(step2[0] + step2[3]); - step1[1] = WRAPLOW(step2[1] + step2[2]); - step1[2] = WRAPLOW(step2[1] - step2[2]); - step1[3] = WRAPLOW(step2[0] - step2[3]); - step1[4] = step2[4]; - temp1 = (step2[6] - step2[5]) * cospi_16_64; - temp2 = (step2[5] + step2[6]) * cospi_16_64; - step1[5] = WRAPLOW(dct_const_round_shift(temp1)); - step1[6] = WRAPLOW(dct_const_round_shift(temp2)); - step1[7] = step2[7]; - - step1[8] = WRAPLOW(step2[8] + step2[11]); - step1[9] = WRAPLOW(step2[9] + step2[10]); - step1[10] = WRAPLOW(step2[9] - step2[10]); - step1[11] = WRAPLOW(step2[8] - step2[11]); - step1[12] = WRAPLOW(-step2[12] + step2[15]); - step1[13] = WRAPLOW(-step2[13] + step2[14]); - step1[14] = WRAPLOW(step2[13] + step2[14]); - step1[15] = WRAPLOW(step2[12] + step2[15]); - - step1[16] = step2[16]; - step1[17] = step2[17]; - temp1 = -step2[18] * cospi_8_64 + step2[29] * cospi_24_64; - temp2 = step2[18] * cospi_24_64 + step2[29] * cospi_8_64; - step1[18] = WRAPLOW(dct_const_round_shift(temp1)); - step1[29] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = -step2[19] * cospi_8_64 + step2[28] * cospi_24_64; - temp2 = step2[19] * cospi_24_64 + step2[28] * cospi_8_64; - step1[19] = WRAPLOW(dct_const_round_shift(temp1)); - step1[28] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = -step2[20] * cospi_24_64 - step2[27] * cospi_8_64; - temp2 = -step2[20] * cospi_8_64 + step2[27] * cospi_24_64; - step1[20] = WRAPLOW(dct_const_round_shift(temp1)); - step1[27] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = -step2[21] * cospi_24_64 - step2[26] * cospi_8_64; - temp2 = -step2[21] * cospi_8_64 + step2[26] * cospi_24_64; - step1[21] = WRAPLOW(dct_const_round_shift(temp1)); - step1[26] = WRAPLOW(dct_const_round_shift(temp2)); - step1[22] = step2[22]; - step1[23] = step2[23]; - step1[24] = step2[24]; - step1[25] = step2[25]; - step1[30] = step2[30]; - step1[31] = step2[31]; - - // stage 6 - step2[0] = WRAPLOW(step1[0] + step1[7]); - step2[1] = WRAPLOW(step1[1] + step1[6]); - step2[2] = WRAPLOW(step1[2] + step1[5]); - step2[3] = WRAPLOW(step1[3] + step1[4]); - step2[4] = WRAPLOW(step1[3] - step1[4]); - step2[5] = WRAPLOW(step1[2] - step1[5]); - step2[6] = WRAPLOW(step1[1] - step1[6]); - step2[7] = WRAPLOW(step1[0] - step1[7]); - step2[8] = step1[8]; - step2[9] = step1[9]; - temp1 = (-step1[10] + step1[13]) * cospi_16_64; - temp2 = (step1[10] + step1[13]) * cospi_16_64; - step2[10] = WRAPLOW(dct_const_round_shift(temp1)); - step2[13] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = (-step1[11] + step1[12]) * cospi_16_64; - temp2 = (step1[11] + step1[12]) * cospi_16_64; - step2[11] = WRAPLOW(dct_const_round_shift(temp1)); - step2[12] = WRAPLOW(dct_const_round_shift(temp2)); - step2[14] = step1[14]; - step2[15] = step1[15]; - - step2[16] = WRAPLOW(step1[16] + step1[23]); - step2[17] = WRAPLOW(step1[17] + step1[22]); - step2[18] = WRAPLOW(step1[18] + step1[21]); - step2[19] = WRAPLOW(step1[19] + step1[20]); - step2[20] = WRAPLOW(step1[19] - step1[20]); - step2[21] = WRAPLOW(step1[18] - step1[21]); - step2[22] = WRAPLOW(step1[17] - step1[22]); - step2[23] = WRAPLOW(step1[16] - step1[23]); - - step2[24] = WRAPLOW(-step1[24] + step1[31]); - step2[25] = WRAPLOW(-step1[25] + step1[30]); - step2[26] = WRAPLOW(-step1[26] + step1[29]); - step2[27] = WRAPLOW(-step1[27] + step1[28]); - step2[28] = WRAPLOW(step1[27] + step1[28]); - step2[29] = WRAPLOW(step1[26] + step1[29]); - step2[30] = WRAPLOW(step1[25] + step1[30]); - step2[31] = WRAPLOW(step1[24] + step1[31]); - - // stage 7 - step1[0] = WRAPLOW(step2[0] + step2[15]); - step1[1] = WRAPLOW(step2[1] + step2[14]); - step1[2] = WRAPLOW(step2[2] + step2[13]); - step1[3] = WRAPLOW(step2[3] + step2[12]); - step1[4] = WRAPLOW(step2[4] + step2[11]); - step1[5] = WRAPLOW(step2[5] + step2[10]); - step1[6] = WRAPLOW(step2[6] + step2[9]); - step1[7] = WRAPLOW(step2[7] + step2[8]); - step1[8] = WRAPLOW(step2[7] - step2[8]); - step1[9] = WRAPLOW(step2[6] - step2[9]); - step1[10] = WRAPLOW(step2[5] - step2[10]); - step1[11] = WRAPLOW(step2[4] - step2[11]); - step1[12] = WRAPLOW(step2[3] - step2[12]); - step1[13] = WRAPLOW(step2[2] - step2[13]); - step1[14] = WRAPLOW(step2[1] - step2[14]); - step1[15] = WRAPLOW(step2[0] - step2[15]); - - step1[16] = step2[16]; - step1[17] = step2[17]; - step1[18] = step2[18]; - step1[19] = step2[19]; - temp1 = (-step2[20] + step2[27]) * cospi_16_64; - temp2 = (step2[20] + step2[27]) * cospi_16_64; - step1[20] = WRAPLOW(dct_const_round_shift(temp1)); - step1[27] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = (-step2[21] + step2[26]) * cospi_16_64; - temp2 = (step2[21] + step2[26]) * cospi_16_64; - step1[21] = WRAPLOW(dct_const_round_shift(temp1)); - step1[26] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = (-step2[22] + step2[25]) * cospi_16_64; - temp2 = (step2[22] + step2[25]) * cospi_16_64; - step1[22] = WRAPLOW(dct_const_round_shift(temp1)); - step1[25] = WRAPLOW(dct_const_round_shift(temp2)); - temp1 = (-step2[23] + step2[24]) * cospi_16_64; - temp2 = (step2[23] + step2[24]) * cospi_16_64; - step1[23] = WRAPLOW(dct_const_round_shift(temp1)); - step1[24] = WRAPLOW(dct_const_round_shift(temp2)); - step1[28] = step2[28]; - step1[29] = step2[29]; - step1[30] = step2[30]; - step1[31] = step2[31]; - - // final stage - output[0] = WRAPLOW(step1[0] + step1[31]); - output[1] = WRAPLOW(step1[1] + step1[30]); - output[2] = WRAPLOW(step1[2] + step1[29]); - output[3] = WRAPLOW(step1[3] + step1[28]); - output[4] = WRAPLOW(step1[4] + step1[27]); - output[5] = WRAPLOW(step1[5] + step1[26]); - output[6] = WRAPLOW(step1[6] + step1[25]); - output[7] = WRAPLOW(step1[7] + step1[24]); - output[8] = WRAPLOW(step1[8] + step1[23]); - output[9] = WRAPLOW(step1[9] + step1[22]); - output[10] = WRAPLOW(step1[10] + step1[21]); - output[11] = WRAPLOW(step1[11] + step1[20]); - output[12] = WRAPLOW(step1[12] + step1[19]); - output[13] = WRAPLOW(step1[13] + step1[18]); - output[14] = WRAPLOW(step1[14] + step1[17]); - output[15] = WRAPLOW(step1[15] + step1[16]); - output[16] = WRAPLOW(step1[15] - step1[16]); - output[17] = WRAPLOW(step1[14] - step1[17]); - output[18] = WRAPLOW(step1[13] - step1[18]); - output[19] = WRAPLOW(step1[12] - step1[19]); - output[20] = WRAPLOW(step1[11] - step1[20]); - output[21] = WRAPLOW(step1[10] - step1[21]); - output[22] = WRAPLOW(step1[9] - step1[22]); - output[23] = WRAPLOW(step1[8] - step1[23]); - output[24] = WRAPLOW(step1[7] - step1[24]); - output[25] = WRAPLOW(step1[6] - step1[25]); - output[26] = WRAPLOW(step1[5] - step1[26]); - output[27] = WRAPLOW(step1[4] - step1[27]); - output[28] = WRAPLOW(step1[3] - step1[28]); - output[29] = WRAPLOW(step1[2] - step1[29]); - output[30] = WRAPLOW(step1[1] - step1[30]); - output[31] = WRAPLOW(step1[0] - step1[31]); -} - -void vpx_idct32x32_1024_add_c(const tran_low_t *input, uint8_t *dest, - int stride) { - int i, j; - tran_low_t out[32 * 32]; - tran_low_t *outptr = out; - tran_low_t temp_in[32], temp_out[32]; - - // Rows - for (i = 0; i < 32; ++i) { - int16_t zero_coeff = 0; - for (j = 0; j < 32; ++j) zero_coeff |= input[j]; - - if (zero_coeff) - idct32_c(input, outptr); - else - memset(outptr, 0, sizeof(tran_low_t) * 32); - input += 32; - outptr += 32; - } - - // Columns - for (i = 0; i < 32; ++i) { - for (j = 0; j < 32; ++j) temp_in[j] = out[j * 32 + i]; - idct32_c(temp_in, temp_out); - for (j = 0; j < 32; ++j) { - dest[j * stride + i] = clip_pixel_add(dest[j * stride + i], - ROUND_POWER_OF_TWO(temp_out[j], 6)); - } - } -} - -void vpx_idct32x32_135_add_c(const tran_low_t *input, uint8_t *dest, - int stride) { - int i, j; - tran_low_t out[32 * 32] = { 0 }; - tran_low_t *outptr = out; - tran_low_t temp_in[32], temp_out[32]; - - // Rows - // Only upper-left 16x16 has non-zero coeff - for (i = 0; i < 16; ++i) { - idct32_c(input, outptr); - input += 32; - outptr += 32; - } - - // Columns - for (i = 0; i < 32; ++i) { - for (j = 0; j < 32; ++j) temp_in[j] = out[j * 32 + i]; - idct32_c(temp_in, temp_out); - for (j = 0; j < 32; ++j) { - dest[j * stride + i] = clip_pixel_add(dest[j * stride + i], - ROUND_POWER_OF_TWO(temp_out[j], 6)); - } - } -} - -void vpx_idct32x32_34_add_c(const tran_low_t *input, uint8_t *dest, - int stride) { - int i, j; - tran_low_t out[32 * 32] = { 0 }; - tran_low_t *outptr = out; - tran_low_t temp_in[32], temp_out[32]; - - // Rows - // Only upper-left 8x8 has non-zero coeff - for (i = 0; i < 8; ++i) { - idct32_c(input, outptr); - input += 32; - outptr += 32; - } - - // Columns - for (i = 0; i < 32; ++i) { - for (j = 0; j < 32; ++j) temp_in[j] = out[j * 32 + i]; - idct32_c(temp_in, temp_out); - for (j = 0; j < 32; ++j) { - dest[j * stride + i] = clip_pixel_add(dest[j * stride + i], - ROUND_POWER_OF_TWO(temp_out[j], 6)); - } - } -} - -void vpx_idct32x32_1_add_c(const tran_low_t *input, uint8_t *dest, int stride) { - int i, j; - tran_high_t a1; - tran_low_t out = - WRAPLOW(dct_const_round_shift((int16_t)input[0] * cospi_16_64)); - - out = WRAPLOW(dct_const_round_shift(out * cospi_16_64)); - a1 = ROUND_POWER_OF_TWO(out, 6); - - for (j = 0; j < 32; ++j) { - for (i = 0; i < 32; ++i) dest[i] = clip_pixel_add(dest[i], a1); - dest += stride; - } -} - -#if CONFIG_VP9_HIGHBITDEPTH - -// 12 signal input bits + 7 2D forward transform amplify bits + 5 1D inverse -// transform amplify bits + 1 bit for contingency in rounding and quantizing -#define HIGHBD_VALID_TXFM_MAGNITUDE_RANGE (1 << 25) - -static INLINE int detect_invalid_highbd_input(const tran_low_t *input, - int size) { - int i; - for (i = 0; i < size; ++i) - if (abs(input[i]) >= HIGHBD_VALID_TXFM_MAGNITUDE_RANGE) return 1; - return 0; -} - -void vpx_highbd_iwht4x4_16_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - /* 4-point reversible, orthonormal inverse Walsh-Hadamard in 3.5 adds, - 0.5 shifts per pixel. */ - int i; - tran_low_t output[16]; - tran_high_t a1, b1, c1, d1, e1; - const tran_low_t *ip = input; - tran_low_t *op = output; - - for (i = 0; i < 4; i++) { - a1 = ip[0] >> UNIT_QUANT_SHIFT; - c1 = ip[1] >> UNIT_QUANT_SHIFT; - d1 = ip[2] >> UNIT_QUANT_SHIFT; - b1 = ip[3] >> UNIT_QUANT_SHIFT; - a1 += c1; - d1 -= b1; - e1 = (a1 - d1) >> 1; - b1 = e1 - b1; - c1 = e1 - c1; - a1 -= b1; - d1 += c1; - op[0] = HIGHBD_WRAPLOW(a1, bd); - op[1] = HIGHBD_WRAPLOW(b1, bd); - op[2] = HIGHBD_WRAPLOW(c1, bd); - op[3] = HIGHBD_WRAPLOW(d1, bd); - ip += 4; - op += 4; - } - - ip = output; - for (i = 0; i < 4; i++) { - a1 = ip[4 * 0]; - c1 = ip[4 * 1]; - d1 = ip[4 * 2]; - b1 = ip[4 * 3]; - a1 += c1; - d1 -= b1; - e1 = (a1 - d1) >> 1; - b1 = e1 - b1; - c1 = e1 - c1; - a1 -= b1; - d1 += c1; - dest[stride * 0] = - highbd_clip_pixel_add(dest[stride * 0], HIGHBD_WRAPLOW(a1, bd), bd); - dest[stride * 1] = - highbd_clip_pixel_add(dest[stride * 1], HIGHBD_WRAPLOW(b1, bd), bd); - dest[stride * 2] = - highbd_clip_pixel_add(dest[stride * 2], HIGHBD_WRAPLOW(c1, bd), bd); - dest[stride * 3] = - highbd_clip_pixel_add(dest[stride * 3], HIGHBD_WRAPLOW(d1, bd), bd); - - ip++; - dest++; - } -} - -void vpx_highbd_iwht4x4_1_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i; - tran_high_t a1, e1; - tran_low_t tmp[4]; - const tran_low_t *ip = input; - tran_low_t *op = tmp; - (void)bd; - - a1 = ip[0] >> UNIT_QUANT_SHIFT; - e1 = a1 >> 1; - a1 -= e1; - op[0] = HIGHBD_WRAPLOW(a1, bd); - op[1] = op[2] = op[3] = HIGHBD_WRAPLOW(e1, bd); - - ip = tmp; - for (i = 0; i < 4; i++) { - e1 = ip[0] >> 1; - a1 = ip[0] - e1; - dest[stride * 0] = highbd_clip_pixel_add(dest[stride * 0], a1, bd); - dest[stride * 1] = highbd_clip_pixel_add(dest[stride * 1], e1, bd); - dest[stride * 2] = highbd_clip_pixel_add(dest[stride * 2], e1, bd); - dest[stride * 3] = highbd_clip_pixel_add(dest[stride * 3], e1, bd); - ip++; - dest++; - } -} - -void vpx_highbd_iadst4_c(const tran_low_t *input, tran_low_t *output, int bd) { - tran_high_t s0, s1, s2, s3, s4, s5, s6, s7; - tran_low_t x0 = input[0]; - tran_low_t x1 = input[1]; - tran_low_t x2 = input[2]; - tran_low_t x3 = input[3]; - (void)bd; - - if (detect_invalid_highbd_input(input, 4)) { -#if CONFIG_COEFFICIENT_RANGE_CHECKING - assert(0 && "invalid highbd txfm input"); -#endif // CONFIG_COEFFICIENT_RANGE_CHECKING - memset(output, 0, sizeof(*output) * 4); - return; - } - - if (!(x0 | x1 | x2 | x3)) { - memset(output, 0, 4 * sizeof(*output)); - return; - } - - s0 = (tran_high_t)sinpi_1_9 * x0; - s1 = (tran_high_t)sinpi_2_9 * x0; - s2 = (tran_high_t)sinpi_3_9 * x1; - s3 = (tran_high_t)sinpi_4_9 * x2; - s4 = (tran_high_t)sinpi_1_9 * x2; - s5 = (tran_high_t)sinpi_2_9 * x3; - s6 = (tran_high_t)sinpi_4_9 * x3; - s7 = (tran_high_t)HIGHBD_WRAPLOW(x0 - x2 + x3, bd); - - s0 = s0 + s3 + s5; - s1 = s1 - s4 - s6; - s3 = s2; - s2 = sinpi_3_9 * s7; - - // 1-D transform scaling factor is sqrt(2). - // The overall dynamic range is 14b (input) + 14b (multiplication scaling) - // + 1b (addition) = 29b. - // Hence the output bit depth is 15b. - output[0] = HIGHBD_WRAPLOW(dct_const_round_shift(s0 + s3), bd); - output[1] = HIGHBD_WRAPLOW(dct_const_round_shift(s1 + s3), bd); - output[2] = HIGHBD_WRAPLOW(dct_const_round_shift(s2), bd); - output[3] = HIGHBD_WRAPLOW(dct_const_round_shift(s0 + s1 - s3), bd); -} - -void vpx_highbd_idct4_c(const tran_low_t *input, tran_low_t *output, int bd) { - tran_low_t step[4]; - tran_high_t temp1, temp2; - (void)bd; - - if (detect_invalid_highbd_input(input, 4)) { -#if CONFIG_COEFFICIENT_RANGE_CHECKING - assert(0 && "invalid highbd txfm input"); -#endif // CONFIG_COEFFICIENT_RANGE_CHECKING - memset(output, 0, sizeof(*output) * 4); - return; - } - - // stage 1 - temp1 = (input[0] + input[2]) * (tran_high_t)cospi_16_64; - temp2 = (input[0] - input[2]) * (tran_high_t)cospi_16_64; - step[0] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step[1] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = - input[1] * (tran_high_t)cospi_24_64 - input[3] * (tran_high_t)cospi_8_64; - temp2 = - input[1] * (tran_high_t)cospi_8_64 + input[3] * (tran_high_t)cospi_24_64; - step[2] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step[3] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - // stage 2 - output[0] = HIGHBD_WRAPLOW(step[0] + step[3], bd); - output[1] = HIGHBD_WRAPLOW(step[1] + step[2], bd); - output[2] = HIGHBD_WRAPLOW(step[1] - step[2], bd); - output[3] = HIGHBD_WRAPLOW(step[0] - step[3], bd); -} - -void vpx_highbd_idct4x4_16_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i, j; - tran_low_t out[4 * 4]; - tran_low_t *outptr = out; - tran_low_t temp_in[4], temp_out[4]; - - // Rows - for (i = 0; i < 4; ++i) { - vpx_highbd_idct4_c(input, outptr, bd); - input += 4; - outptr += 4; - } - - // Columns - for (i = 0; i < 4; ++i) { - for (j = 0; j < 4; ++j) temp_in[j] = out[j * 4 + i]; - vpx_highbd_idct4_c(temp_in, temp_out, bd); - for (j = 0; j < 4; ++j) { - dest[j * stride + i] = highbd_clip_pixel_add( - dest[j * stride + i], ROUND_POWER_OF_TWO(temp_out[j], 4), bd); - } - } -} - -void vpx_highbd_idct4x4_1_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i; - tran_high_t a1; - tran_low_t out = HIGHBD_WRAPLOW( - dct_const_round_shift(input[0] * (tran_high_t)cospi_16_64), bd); - - out = - HIGHBD_WRAPLOW(dct_const_round_shift(out * (tran_high_t)cospi_16_64), bd); - a1 = ROUND_POWER_OF_TWO(out, 4); - - for (i = 0; i < 4; i++) { - dest[0] = highbd_clip_pixel_add(dest[0], a1, bd); - dest[1] = highbd_clip_pixel_add(dest[1], a1, bd); - dest[2] = highbd_clip_pixel_add(dest[2], a1, bd); - dest[3] = highbd_clip_pixel_add(dest[3], a1, bd); - dest += stride; - } -} - -void vpx_highbd_iadst8_c(const tran_low_t *input, tran_low_t *output, int bd) { - tran_high_t s0, s1, s2, s3, s4, s5, s6, s7; - tran_low_t x0 = input[7]; - tran_low_t x1 = input[0]; - tran_low_t x2 = input[5]; - tran_low_t x3 = input[2]; - tran_low_t x4 = input[3]; - tran_low_t x5 = input[4]; - tran_low_t x6 = input[1]; - tran_low_t x7 = input[6]; - (void)bd; - - if (detect_invalid_highbd_input(input, 8)) { -#if CONFIG_COEFFICIENT_RANGE_CHECKING - assert(0 && "invalid highbd txfm input"); -#endif // CONFIG_COEFFICIENT_RANGE_CHECKING - memset(output, 0, sizeof(*output) * 8); - return; - } - - if (!(x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7)) { - memset(output, 0, 8 * sizeof(*output)); - return; - } - - // stage 1 - s0 = (tran_high_t)cospi_2_64 * x0 + (tran_high_t)cospi_30_64 * x1; - s1 = (tran_high_t)cospi_30_64 * x0 - (tran_high_t)cospi_2_64 * x1; - s2 = (tran_high_t)cospi_10_64 * x2 + (tran_high_t)cospi_22_64 * x3; - s3 = (tran_high_t)cospi_22_64 * x2 - (tran_high_t)cospi_10_64 * x3; - s4 = (tran_high_t)cospi_18_64 * x4 + (tran_high_t)cospi_14_64 * x5; - s5 = (tran_high_t)cospi_14_64 * x4 - (tran_high_t)cospi_18_64 * x5; - s6 = (tran_high_t)cospi_26_64 * x6 + (tran_high_t)cospi_6_64 * x7; - s7 = (tran_high_t)cospi_6_64 * x6 - (tran_high_t)cospi_26_64 * x7; - - x0 = HIGHBD_WRAPLOW(dct_const_round_shift(s0 + s4), bd); - x1 = HIGHBD_WRAPLOW(dct_const_round_shift(s1 + s5), bd); - x2 = HIGHBD_WRAPLOW(dct_const_round_shift(s2 + s6), bd); - x3 = HIGHBD_WRAPLOW(dct_const_round_shift(s3 + s7), bd); - x4 = HIGHBD_WRAPLOW(dct_const_round_shift(s0 - s4), bd); - x5 = HIGHBD_WRAPLOW(dct_const_round_shift(s1 - s5), bd); - x6 = HIGHBD_WRAPLOW(dct_const_round_shift(s2 - s6), bd); - x7 = HIGHBD_WRAPLOW(dct_const_round_shift(s3 - s7), bd); - - // stage 2 - s0 = x0; - s1 = x1; - s2 = x2; - s3 = x3; - s4 = (tran_high_t)cospi_8_64 * x4 + (tran_high_t)cospi_24_64 * x5; - s5 = (tran_high_t)cospi_24_64 * x4 - (tran_high_t)cospi_8_64 * x5; - s6 = (tran_high_t)(-cospi_24_64) * x6 + (tran_high_t)cospi_8_64 * x7; - s7 = (tran_high_t)cospi_8_64 * x6 + (tran_high_t)cospi_24_64 * x7; - - x0 = HIGHBD_WRAPLOW(s0 + s2, bd); - x1 = HIGHBD_WRAPLOW(s1 + s3, bd); - x2 = HIGHBD_WRAPLOW(s0 - s2, bd); - x3 = HIGHBD_WRAPLOW(s1 - s3, bd); - x4 = HIGHBD_WRAPLOW(dct_const_round_shift(s4 + s6), bd); - x5 = HIGHBD_WRAPLOW(dct_const_round_shift(s5 + s7), bd); - x6 = HIGHBD_WRAPLOW(dct_const_round_shift(s4 - s6), bd); - x7 = HIGHBD_WRAPLOW(dct_const_round_shift(s5 - s7), bd); - - // stage 3 - s2 = (tran_high_t)cospi_16_64 * (x2 + x3); - s3 = (tran_high_t)cospi_16_64 * (x2 - x3); - s6 = (tran_high_t)cospi_16_64 * (x6 + x7); - s7 = (tran_high_t)cospi_16_64 * (x6 - x7); - - x2 = HIGHBD_WRAPLOW(dct_const_round_shift(s2), bd); - x3 = HIGHBD_WRAPLOW(dct_const_round_shift(s3), bd); - x6 = HIGHBD_WRAPLOW(dct_const_round_shift(s6), bd); - x7 = HIGHBD_WRAPLOW(dct_const_round_shift(s7), bd); - - output[0] = HIGHBD_WRAPLOW(x0, bd); - output[1] = HIGHBD_WRAPLOW(-x4, bd); - output[2] = HIGHBD_WRAPLOW(x6, bd); - output[3] = HIGHBD_WRAPLOW(-x2, bd); - output[4] = HIGHBD_WRAPLOW(x3, bd); - output[5] = HIGHBD_WRAPLOW(-x7, bd); - output[6] = HIGHBD_WRAPLOW(x5, bd); - output[7] = HIGHBD_WRAPLOW(-x1, bd); -} - -void vpx_highbd_idct8_c(const tran_low_t *input, tran_low_t *output, int bd) { - tran_low_t step1[8], step2[8]; - tran_high_t temp1, temp2; - - if (detect_invalid_highbd_input(input, 8)) { -#if CONFIG_COEFFICIENT_RANGE_CHECKING - assert(0 && "invalid highbd txfm input"); -#endif // CONFIG_COEFFICIENT_RANGE_CHECKING - memset(output, 0, sizeof(*output) * 8); - return; - } - - // stage 1 - step1[0] = input[0]; - step1[2] = input[4]; - step1[1] = input[2]; - step1[3] = input[6]; - temp1 = - input[1] * (tran_high_t)cospi_28_64 - input[7] * (tran_high_t)cospi_4_64; - temp2 = - input[1] * (tran_high_t)cospi_4_64 + input[7] * (tran_high_t)cospi_28_64; - step1[4] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[7] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = - input[5] * (tran_high_t)cospi_12_64 - input[3] * (tran_high_t)cospi_20_64; - temp2 = - input[5] * (tran_high_t)cospi_20_64 + input[3] * (tran_high_t)cospi_12_64; - step1[5] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[6] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - // stage 2 & stage 3 - even half - vpx_highbd_idct4_c(step1, step1, bd); - - // stage 2 - odd half - step2[4] = HIGHBD_WRAPLOW(step1[4] + step1[5], bd); - step2[5] = HIGHBD_WRAPLOW(step1[4] - step1[5], bd); - step2[6] = HIGHBD_WRAPLOW(-step1[6] + step1[7], bd); - step2[7] = HIGHBD_WRAPLOW(step1[6] + step1[7], bd); - - // stage 3 - odd half - step1[4] = step2[4]; - temp1 = (step2[6] - step2[5]) * (tran_high_t)cospi_16_64; - temp2 = (step2[5] + step2[6]) * (tran_high_t)cospi_16_64; - step1[5] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[6] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - step1[7] = step2[7]; - - // stage 4 - output[0] = HIGHBD_WRAPLOW(step1[0] + step1[7], bd); - output[1] = HIGHBD_WRAPLOW(step1[1] + step1[6], bd); - output[2] = HIGHBD_WRAPLOW(step1[2] + step1[5], bd); - output[3] = HIGHBD_WRAPLOW(step1[3] + step1[4], bd); - output[4] = HIGHBD_WRAPLOW(step1[3] - step1[4], bd); - output[5] = HIGHBD_WRAPLOW(step1[2] - step1[5], bd); - output[6] = HIGHBD_WRAPLOW(step1[1] - step1[6], bd); - output[7] = HIGHBD_WRAPLOW(step1[0] - step1[7], bd); -} - -void vpx_highbd_idct8x8_64_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i, j; - tran_low_t out[8 * 8]; - tran_low_t *outptr = out; - tran_low_t temp_in[8], temp_out[8]; - - // First transform rows - for (i = 0; i < 8; ++i) { - vpx_highbd_idct8_c(input, outptr, bd); - input += 8; - outptr += 8; - } - - // Then transform columns - for (i = 0; i < 8; ++i) { - for (j = 0; j < 8; ++j) temp_in[j] = out[j * 8 + i]; - vpx_highbd_idct8_c(temp_in, temp_out, bd); - for (j = 0; j < 8; ++j) { - dest[j * stride + i] = highbd_clip_pixel_add( - dest[j * stride + i], ROUND_POWER_OF_TWO(temp_out[j], 5), bd); - } - } -} - -void vpx_highbd_idct8x8_12_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i, j; - tran_low_t out[8 * 8] = { 0 }; - tran_low_t *outptr = out; - tran_low_t temp_in[8], temp_out[8]; - - // First transform rows - // Only first 4 row has non-zero coefs - for (i = 0; i < 4; ++i) { - vpx_highbd_idct8_c(input, outptr, bd); - input += 8; - outptr += 8; - } - - // Then transform columns - for (i = 0; i < 8; ++i) { - for (j = 0; j < 8; ++j) temp_in[j] = out[j * 8 + i]; - vpx_highbd_idct8_c(temp_in, temp_out, bd); - for (j = 0; j < 8; ++j) { - dest[j * stride + i] = highbd_clip_pixel_add( - dest[j * stride + i], ROUND_POWER_OF_TWO(temp_out[j], 5), bd); - } - } -} - -void vpx_highbd_idct8x8_1_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i, j; - tran_high_t a1; - tran_low_t out = HIGHBD_WRAPLOW( - dct_const_round_shift(input[0] * (tran_high_t)cospi_16_64), bd); - - out = - HIGHBD_WRAPLOW(dct_const_round_shift(out * (tran_high_t)cospi_16_64), bd); - a1 = ROUND_POWER_OF_TWO(out, 5); - for (j = 0; j < 8; ++j) { - for (i = 0; i < 8; ++i) dest[i] = highbd_clip_pixel_add(dest[i], a1, bd); - dest += stride; - } -} - -void vpx_highbd_iadst16_c(const tran_low_t *input, tran_low_t *output, int bd) { - tran_high_t s0, s1, s2, s3, s4, s5, s6, s7, s8; - tran_high_t s9, s10, s11, s12, s13, s14, s15; - tran_low_t x0 = input[15]; - tran_low_t x1 = input[0]; - tran_low_t x2 = input[13]; - tran_low_t x3 = input[2]; - tran_low_t x4 = input[11]; - tran_low_t x5 = input[4]; - tran_low_t x6 = input[9]; - tran_low_t x7 = input[6]; - tran_low_t x8 = input[7]; - tran_low_t x9 = input[8]; - tran_low_t x10 = input[5]; - tran_low_t x11 = input[10]; - tran_low_t x12 = input[3]; - tran_low_t x13 = input[12]; - tran_low_t x14 = input[1]; - tran_low_t x15 = input[14]; - (void)bd; - - if (detect_invalid_highbd_input(input, 16)) { -#if CONFIG_COEFFICIENT_RANGE_CHECKING - assert(0 && "invalid highbd txfm input"); -#endif // CONFIG_COEFFICIENT_RANGE_CHECKING - memset(output, 0, sizeof(*output) * 16); - return; - } - - if (!(x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | x11 | x12 | - x13 | x14 | x15)) { - memset(output, 0, 16 * sizeof(*output)); - return; - } - - // stage 1 - s0 = x0 * (tran_high_t)cospi_1_64 + x1 * (tran_high_t)cospi_31_64; - s1 = x0 * (tran_high_t)cospi_31_64 - x1 * (tran_high_t)cospi_1_64; - s2 = x2 * (tran_high_t)cospi_5_64 + x3 * (tran_high_t)cospi_27_64; - s3 = x2 * (tran_high_t)cospi_27_64 - x3 * (tran_high_t)cospi_5_64; - s4 = x4 * (tran_high_t)cospi_9_64 + x5 * (tran_high_t)cospi_23_64; - s5 = x4 * (tran_high_t)cospi_23_64 - x5 * (tran_high_t)cospi_9_64; - s6 = x6 * (tran_high_t)cospi_13_64 + x7 * (tran_high_t)cospi_19_64; - s7 = x6 * (tran_high_t)cospi_19_64 - x7 * (tran_high_t)cospi_13_64; - s8 = x8 * (tran_high_t)cospi_17_64 + x9 * (tran_high_t)cospi_15_64; - s9 = x8 * (tran_high_t)cospi_15_64 - x9 * (tran_high_t)cospi_17_64; - s10 = x10 * (tran_high_t)cospi_21_64 + x11 * (tran_high_t)cospi_11_64; - s11 = x10 * (tran_high_t)cospi_11_64 - x11 * (tran_high_t)cospi_21_64; - s12 = x12 * (tran_high_t)cospi_25_64 + x13 * (tran_high_t)cospi_7_64; - s13 = x12 * (tran_high_t)cospi_7_64 - x13 * (tran_high_t)cospi_25_64; - s14 = x14 * (tran_high_t)cospi_29_64 + x15 * (tran_high_t)cospi_3_64; - s15 = x14 * (tran_high_t)cospi_3_64 - x15 * (tran_high_t)cospi_29_64; - - x0 = HIGHBD_WRAPLOW(dct_const_round_shift(s0 + s8), bd); - x1 = HIGHBD_WRAPLOW(dct_const_round_shift(s1 + s9), bd); - x2 = HIGHBD_WRAPLOW(dct_const_round_shift(s2 + s10), bd); - x3 = HIGHBD_WRAPLOW(dct_const_round_shift(s3 + s11), bd); - x4 = HIGHBD_WRAPLOW(dct_const_round_shift(s4 + s12), bd); - x5 = HIGHBD_WRAPLOW(dct_const_round_shift(s5 + s13), bd); - x6 = HIGHBD_WRAPLOW(dct_const_round_shift(s6 + s14), bd); - x7 = HIGHBD_WRAPLOW(dct_const_round_shift(s7 + s15), bd); - x8 = HIGHBD_WRAPLOW(dct_const_round_shift(s0 - s8), bd); - x9 = HIGHBD_WRAPLOW(dct_const_round_shift(s1 - s9), bd); - x10 = HIGHBD_WRAPLOW(dct_const_round_shift(s2 - s10), bd); - x11 = HIGHBD_WRAPLOW(dct_const_round_shift(s3 - s11), bd); - x12 = HIGHBD_WRAPLOW(dct_const_round_shift(s4 - s12), bd); - x13 = HIGHBD_WRAPLOW(dct_const_round_shift(s5 - s13), bd); - x14 = HIGHBD_WRAPLOW(dct_const_round_shift(s6 - s14), bd); - x15 = HIGHBD_WRAPLOW(dct_const_round_shift(s7 - s15), bd); - - // stage 2 - s0 = x0; - s1 = x1; - s2 = x2; - s3 = x3; - s4 = x4; - s5 = x5; - s6 = x6; - s7 = x7; - s8 = x8 * (tran_high_t)cospi_4_64 + x9 * (tran_high_t)cospi_28_64; - s9 = x8 * (tran_high_t)cospi_28_64 - x9 * (tran_high_t)cospi_4_64; - s10 = x10 * (tran_high_t)cospi_20_64 + x11 * (tran_high_t)cospi_12_64; - s11 = x10 * (tran_high_t)cospi_12_64 - x11 * (tran_high_t)cospi_20_64; - s12 = -x12 * (tran_high_t)cospi_28_64 + x13 * (tran_high_t)cospi_4_64; - s13 = x12 * (tran_high_t)cospi_4_64 + x13 * (tran_high_t)cospi_28_64; - s14 = -x14 * (tran_high_t)cospi_12_64 + x15 * (tran_high_t)cospi_20_64; - s15 = x14 * (tran_high_t)cospi_20_64 + x15 * (tran_high_t)cospi_12_64; - - x0 = HIGHBD_WRAPLOW(s0 + s4, bd); - x1 = HIGHBD_WRAPLOW(s1 + s5, bd); - x2 = HIGHBD_WRAPLOW(s2 + s6, bd); - x3 = HIGHBD_WRAPLOW(s3 + s7, bd); - x4 = HIGHBD_WRAPLOW(s0 - s4, bd); - x5 = HIGHBD_WRAPLOW(s1 - s5, bd); - x6 = HIGHBD_WRAPLOW(s2 - s6, bd); - x7 = HIGHBD_WRAPLOW(s3 - s7, bd); - x8 = HIGHBD_WRAPLOW(dct_const_round_shift(s8 + s12), bd); - x9 = HIGHBD_WRAPLOW(dct_const_round_shift(s9 + s13), bd); - x10 = HIGHBD_WRAPLOW(dct_const_round_shift(s10 + s14), bd); - x11 = HIGHBD_WRAPLOW(dct_const_round_shift(s11 + s15), bd); - x12 = HIGHBD_WRAPLOW(dct_const_round_shift(s8 - s12), bd); - x13 = HIGHBD_WRAPLOW(dct_const_round_shift(s9 - s13), bd); - x14 = HIGHBD_WRAPLOW(dct_const_round_shift(s10 - s14), bd); - x15 = HIGHBD_WRAPLOW(dct_const_round_shift(s11 - s15), bd); - - // stage 3 - s0 = x0; - s1 = x1; - s2 = x2; - s3 = x3; - s4 = x4 * (tran_high_t)cospi_8_64 + x5 * (tran_high_t)cospi_24_64; - s5 = x4 * (tran_high_t)cospi_24_64 - x5 * (tran_high_t)cospi_8_64; - s6 = -x6 * (tran_high_t)cospi_24_64 + x7 * (tran_high_t)cospi_8_64; - s7 = x6 * (tran_high_t)cospi_8_64 + x7 * (tran_high_t)cospi_24_64; - s8 = x8; - s9 = x9; - s10 = x10; - s11 = x11; - s12 = x12 * (tran_high_t)cospi_8_64 + x13 * (tran_high_t)cospi_24_64; - s13 = x12 * (tran_high_t)cospi_24_64 - x13 * (tran_high_t)cospi_8_64; - s14 = -x14 * (tran_high_t)cospi_24_64 + x15 * (tran_high_t)cospi_8_64; - s15 = x14 * (tran_high_t)cospi_8_64 + x15 * (tran_high_t)cospi_24_64; - - x0 = HIGHBD_WRAPLOW(s0 + s2, bd); - x1 = HIGHBD_WRAPLOW(s1 + s3, bd); - x2 = HIGHBD_WRAPLOW(s0 - s2, bd); - x3 = HIGHBD_WRAPLOW(s1 - s3, bd); - x4 = HIGHBD_WRAPLOW(dct_const_round_shift(s4 + s6), bd); - x5 = HIGHBD_WRAPLOW(dct_const_round_shift(s5 + s7), bd); - x6 = HIGHBD_WRAPLOW(dct_const_round_shift(s4 - s6), bd); - x7 = HIGHBD_WRAPLOW(dct_const_round_shift(s5 - s7), bd); - x8 = HIGHBD_WRAPLOW(s8 + s10, bd); - x9 = HIGHBD_WRAPLOW(s9 + s11, bd); - x10 = HIGHBD_WRAPLOW(s8 - s10, bd); - x11 = HIGHBD_WRAPLOW(s9 - s11, bd); - x12 = HIGHBD_WRAPLOW(dct_const_round_shift(s12 + s14), bd); - x13 = HIGHBD_WRAPLOW(dct_const_round_shift(s13 + s15), bd); - x14 = HIGHBD_WRAPLOW(dct_const_round_shift(s12 - s14), bd); - x15 = HIGHBD_WRAPLOW(dct_const_round_shift(s13 - s15), bd); - - // stage 4 - s2 = (tran_high_t)(-cospi_16_64) * (x2 + x3); - s3 = (tran_high_t)cospi_16_64 * (x2 - x3); - s6 = (tran_high_t)cospi_16_64 * (x6 + x7); - s7 = (tran_high_t)cospi_16_64 * (-x6 + x7); - s10 = (tran_high_t)cospi_16_64 * (x10 + x11); - s11 = (tran_high_t)cospi_16_64 * (-x10 + x11); - s14 = (tran_high_t)(-cospi_16_64) * (x14 + x15); - s15 = (tran_high_t)cospi_16_64 * (x14 - x15); - - x2 = HIGHBD_WRAPLOW(dct_const_round_shift(s2), bd); - x3 = HIGHBD_WRAPLOW(dct_const_round_shift(s3), bd); - x6 = HIGHBD_WRAPLOW(dct_const_round_shift(s6), bd); - x7 = HIGHBD_WRAPLOW(dct_const_round_shift(s7), bd); - x10 = HIGHBD_WRAPLOW(dct_const_round_shift(s10), bd); - x11 = HIGHBD_WRAPLOW(dct_const_round_shift(s11), bd); - x14 = HIGHBD_WRAPLOW(dct_const_round_shift(s14), bd); - x15 = HIGHBD_WRAPLOW(dct_const_round_shift(s15), bd); - - output[0] = HIGHBD_WRAPLOW(x0, bd); - output[1] = HIGHBD_WRAPLOW(-x8, bd); - output[2] = HIGHBD_WRAPLOW(x12, bd); - output[3] = HIGHBD_WRAPLOW(-x4, bd); - output[4] = HIGHBD_WRAPLOW(x6, bd); - output[5] = HIGHBD_WRAPLOW(x14, bd); - output[6] = HIGHBD_WRAPLOW(x10, bd); - output[7] = HIGHBD_WRAPLOW(x2, bd); - output[8] = HIGHBD_WRAPLOW(x3, bd); - output[9] = HIGHBD_WRAPLOW(x11, bd); - output[10] = HIGHBD_WRAPLOW(x15, bd); - output[11] = HIGHBD_WRAPLOW(x7, bd); - output[12] = HIGHBD_WRAPLOW(x5, bd); - output[13] = HIGHBD_WRAPLOW(-x13, bd); - output[14] = HIGHBD_WRAPLOW(x9, bd); - output[15] = HIGHBD_WRAPLOW(-x1, bd); -} - -void vpx_highbd_idct16_c(const tran_low_t *input, tran_low_t *output, int bd) { - tran_low_t step1[16], step2[16]; - tran_high_t temp1, temp2; - (void)bd; - - if (detect_invalid_highbd_input(input, 16)) { -#if CONFIG_COEFFICIENT_RANGE_CHECKING - assert(0 && "invalid highbd txfm input"); -#endif // CONFIG_COEFFICIENT_RANGE_CHECKING - memset(output, 0, sizeof(*output) * 16); - return; - } - - // stage 1 - step1[0] = input[0 / 2]; - step1[1] = input[16 / 2]; - step1[2] = input[8 / 2]; - step1[3] = input[24 / 2]; - step1[4] = input[4 / 2]; - step1[5] = input[20 / 2]; - step1[6] = input[12 / 2]; - step1[7] = input[28 / 2]; - step1[8] = input[2 / 2]; - step1[9] = input[18 / 2]; - step1[10] = input[10 / 2]; - step1[11] = input[26 / 2]; - step1[12] = input[6 / 2]; - step1[13] = input[22 / 2]; - step1[14] = input[14 / 2]; - step1[15] = input[30 / 2]; - - // stage 2 - step2[0] = step1[0]; - step2[1] = step1[1]; - step2[2] = step1[2]; - step2[3] = step1[3]; - step2[4] = step1[4]; - step2[5] = step1[5]; - step2[6] = step1[6]; - step2[7] = step1[7]; - - temp1 = - step1[8] * (tran_high_t)cospi_30_64 - step1[15] * (tran_high_t)cospi_2_64; - temp2 = - step1[8] * (tran_high_t)cospi_2_64 + step1[15] * (tran_high_t)cospi_30_64; - step2[8] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[15] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - temp1 = step1[9] * (tran_high_t)cospi_14_64 - - step1[14] * (tran_high_t)cospi_18_64; - temp2 = step1[9] * (tran_high_t)cospi_18_64 + - step1[14] * (tran_high_t)cospi_14_64; - step2[9] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[14] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - temp1 = step1[10] * (tran_high_t)cospi_22_64 - - step1[13] * (tran_high_t)cospi_10_64; - temp2 = step1[10] * (tran_high_t)cospi_10_64 + - step1[13] * (tran_high_t)cospi_22_64; - step2[10] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[13] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - temp1 = step1[11] * (tran_high_t)cospi_6_64 - - step1[12] * (tran_high_t)cospi_26_64; - temp2 = step1[11] * (tran_high_t)cospi_26_64 + - step1[12] * (tran_high_t)cospi_6_64; - step2[11] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[12] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - // stage 3 - step1[0] = step2[0]; - step1[1] = step2[1]; - step1[2] = step2[2]; - step1[3] = step2[3]; - - temp1 = - step2[4] * (tran_high_t)cospi_28_64 - step2[7] * (tran_high_t)cospi_4_64; - temp2 = - step2[4] * (tran_high_t)cospi_4_64 + step2[7] * (tran_high_t)cospi_28_64; - step1[4] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[7] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = - step2[5] * (tran_high_t)cospi_12_64 - step2[6] * (tran_high_t)cospi_20_64; - temp2 = - step2[5] * (tran_high_t)cospi_20_64 + step2[6] * (tran_high_t)cospi_12_64; - step1[5] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[6] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - step1[8] = HIGHBD_WRAPLOW(step2[8] + step2[9], bd); - step1[9] = HIGHBD_WRAPLOW(step2[8] - step2[9], bd); - step1[10] = HIGHBD_WRAPLOW(-step2[10] + step2[11], bd); - step1[11] = HIGHBD_WRAPLOW(step2[10] + step2[11], bd); - step1[12] = HIGHBD_WRAPLOW(step2[12] + step2[13], bd); - step1[13] = HIGHBD_WRAPLOW(step2[12] - step2[13], bd); - step1[14] = HIGHBD_WRAPLOW(-step2[14] + step2[15], bd); - step1[15] = HIGHBD_WRAPLOW(step2[14] + step2[15], bd); - - // stage 4 - temp1 = (step1[0] + step1[1]) * (tran_high_t)cospi_16_64; - temp2 = (step1[0] - step1[1]) * (tran_high_t)cospi_16_64; - step2[0] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[1] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = - step1[2] * (tran_high_t)cospi_24_64 - step1[3] * (tran_high_t)cospi_8_64; - temp2 = - step1[2] * (tran_high_t)cospi_8_64 + step1[3] * (tran_high_t)cospi_24_64; - step2[2] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[3] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - step2[4] = HIGHBD_WRAPLOW(step1[4] + step1[5], bd); - step2[5] = HIGHBD_WRAPLOW(step1[4] - step1[5], bd); - step2[6] = HIGHBD_WRAPLOW(-step1[6] + step1[7], bd); - step2[7] = HIGHBD_WRAPLOW(step1[6] + step1[7], bd); - - step2[8] = step1[8]; - step2[15] = step1[15]; - temp1 = -step1[9] * (tran_high_t)cospi_8_64 + - step1[14] * (tran_high_t)cospi_24_64; - temp2 = - step1[9] * (tran_high_t)cospi_24_64 + step1[14] * (tran_high_t)cospi_8_64; - step2[9] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[14] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = -step1[10] * (tran_high_t)cospi_24_64 - - step1[13] * (tran_high_t)cospi_8_64; - temp2 = -step1[10] * (tran_high_t)cospi_8_64 + - step1[13] * (tran_high_t)cospi_24_64; - step2[10] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[13] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - step2[11] = step1[11]; - step2[12] = step1[12]; - - // stage 5 - step1[0] = HIGHBD_WRAPLOW(step2[0] + step2[3], bd); - step1[1] = HIGHBD_WRAPLOW(step2[1] + step2[2], bd); - step1[2] = HIGHBD_WRAPLOW(step2[1] - step2[2], bd); - step1[3] = HIGHBD_WRAPLOW(step2[0] - step2[3], bd); - step1[4] = step2[4]; - temp1 = (step2[6] - step2[5]) * (tran_high_t)cospi_16_64; - temp2 = (step2[5] + step2[6]) * (tran_high_t)cospi_16_64; - step1[5] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[6] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - step1[7] = step2[7]; - - step1[8] = HIGHBD_WRAPLOW(step2[8] + step2[11], bd); - step1[9] = HIGHBD_WRAPLOW(step2[9] + step2[10], bd); - step1[10] = HIGHBD_WRAPLOW(step2[9] - step2[10], bd); - step1[11] = HIGHBD_WRAPLOW(step2[8] - step2[11], bd); - step1[12] = HIGHBD_WRAPLOW(-step2[12] + step2[15], bd); - step1[13] = HIGHBD_WRAPLOW(-step2[13] + step2[14], bd); - step1[14] = HIGHBD_WRAPLOW(step2[13] + step2[14], bd); - step1[15] = HIGHBD_WRAPLOW(step2[12] + step2[15], bd); - - // stage 6 - step2[0] = HIGHBD_WRAPLOW(step1[0] + step1[7], bd); - step2[1] = HIGHBD_WRAPLOW(step1[1] + step1[6], bd); - step2[2] = HIGHBD_WRAPLOW(step1[2] + step1[5], bd); - step2[3] = HIGHBD_WRAPLOW(step1[3] + step1[4], bd); - step2[4] = HIGHBD_WRAPLOW(step1[3] - step1[4], bd); - step2[5] = HIGHBD_WRAPLOW(step1[2] - step1[5], bd); - step2[6] = HIGHBD_WRAPLOW(step1[1] - step1[6], bd); - step2[7] = HIGHBD_WRAPLOW(step1[0] - step1[7], bd); - step2[8] = step1[8]; - step2[9] = step1[9]; - temp1 = (-step1[10] + step1[13]) * (tran_high_t)cospi_16_64; - temp2 = (step1[10] + step1[13]) * (tran_high_t)cospi_16_64; - step2[10] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[13] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = (-step1[11] + step1[12]) * (tran_high_t)cospi_16_64; - temp2 = (step1[11] + step1[12]) * (tran_high_t)cospi_16_64; - step2[11] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[12] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - step2[14] = step1[14]; - step2[15] = step1[15]; - - // stage 7 - output[0] = HIGHBD_WRAPLOW(step2[0] + step2[15], bd); - output[1] = HIGHBD_WRAPLOW(step2[1] + step2[14], bd); - output[2] = HIGHBD_WRAPLOW(step2[2] + step2[13], bd); - output[3] = HIGHBD_WRAPLOW(step2[3] + step2[12], bd); - output[4] = HIGHBD_WRAPLOW(step2[4] + step2[11], bd); - output[5] = HIGHBD_WRAPLOW(step2[5] + step2[10], bd); - output[6] = HIGHBD_WRAPLOW(step2[6] + step2[9], bd); - output[7] = HIGHBD_WRAPLOW(step2[7] + step2[8], bd); - output[8] = HIGHBD_WRAPLOW(step2[7] - step2[8], bd); - output[9] = HIGHBD_WRAPLOW(step2[6] - step2[9], bd); - output[10] = HIGHBD_WRAPLOW(step2[5] - step2[10], bd); - output[11] = HIGHBD_WRAPLOW(step2[4] - step2[11], bd); - output[12] = HIGHBD_WRAPLOW(step2[3] - step2[12], bd); - output[13] = HIGHBD_WRAPLOW(step2[2] - step2[13], bd); - output[14] = HIGHBD_WRAPLOW(step2[1] - step2[14], bd); - output[15] = HIGHBD_WRAPLOW(step2[0] - step2[15], bd); -} - -void vpx_highbd_idct16x16_256_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i, j; - tran_low_t out[16 * 16]; - tran_low_t *outptr = out; - tran_low_t temp_in[16], temp_out[16]; - - // First transform rows - for (i = 0; i < 16; ++i) { - vpx_highbd_idct16_c(input, outptr, bd); - input += 16; - outptr += 16; - } - - // Then transform columns - for (i = 0; i < 16; ++i) { - for (j = 0; j < 16; ++j) temp_in[j] = out[j * 16 + i]; - vpx_highbd_idct16_c(temp_in, temp_out, bd); - for (j = 0; j < 16; ++j) { - dest[j * stride + i] = highbd_clip_pixel_add( - dest[j * stride + i], ROUND_POWER_OF_TWO(temp_out[j], 6), bd); - } - } -} - -void vpx_highbd_idct16x16_38_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i, j; - tran_low_t out[16 * 16] = { 0 }; - tran_low_t *outptr = out; - tran_low_t temp_in[16], temp_out[16]; - - // First transform rows. Since all non-zero dct coefficients are in - // upper-left 8x8 area, we only need to calculate first 8 rows here. - for (i = 0; i < 8; ++i) { - vpx_highbd_idct16_c(input, outptr, bd); - input += 16; - outptr += 16; - } - - // Then transform columns - for (i = 0; i < 16; ++i) { - uint16_t *destT = dest; - for (j = 0; j < 16; ++j) temp_in[j] = out[j * 16 + i]; - vpx_highbd_idct16_c(temp_in, temp_out, bd); - for (j = 0; j < 16; ++j) { - destT[i] = highbd_clip_pixel_add(destT[i], - ROUND_POWER_OF_TWO(temp_out[j], 6), bd); - destT += stride; - } - } -} - -void vpx_highbd_idct16x16_10_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i, j; - tran_low_t out[16 * 16] = { 0 }; - tran_low_t *outptr = out; - tran_low_t temp_in[16], temp_out[16]; - - // First transform rows. Since all non-zero dct coefficients are in - // upper-left 4x4 area, we only need to calculate first 4 rows here. - for (i = 0; i < 4; ++i) { - vpx_highbd_idct16_c(input, outptr, bd); - input += 16; - outptr += 16; - } - - // Then transform columns - for (i = 0; i < 16; ++i) { - for (j = 0; j < 16; ++j) temp_in[j] = out[j * 16 + i]; - vpx_highbd_idct16_c(temp_in, temp_out, bd); - for (j = 0; j < 16; ++j) { - dest[j * stride + i] = highbd_clip_pixel_add( - dest[j * stride + i], ROUND_POWER_OF_TWO(temp_out[j], 6), bd); - } - } -} - -void vpx_highbd_idct16x16_1_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i, j; - tran_high_t a1; - tran_low_t out = HIGHBD_WRAPLOW( - dct_const_round_shift(input[0] * (tran_high_t)cospi_16_64), bd); - - out = - HIGHBD_WRAPLOW(dct_const_round_shift(out * (tran_high_t)cospi_16_64), bd); - a1 = ROUND_POWER_OF_TWO(out, 6); - for (j = 0; j < 16; ++j) { - for (i = 0; i < 16; ++i) dest[i] = highbd_clip_pixel_add(dest[i], a1, bd); - dest += stride; - } -} - -static void highbd_idct32_c(const tran_low_t *input, tran_low_t *output, - int bd) { - tran_low_t step1[32], step2[32]; - tran_high_t temp1, temp2; - (void)bd; - - if (detect_invalid_highbd_input(input, 32)) { -#if CONFIG_COEFFICIENT_RANGE_CHECKING - assert(0 && "invalid highbd txfm input"); -#endif // CONFIG_COEFFICIENT_RANGE_CHECKING - memset(output, 0, sizeof(*output) * 32); - return; - } - - // stage 1 - step1[0] = input[0]; - step1[1] = input[16]; - step1[2] = input[8]; - step1[3] = input[24]; - step1[4] = input[4]; - step1[5] = input[20]; - step1[6] = input[12]; - step1[7] = input[28]; - step1[8] = input[2]; - step1[9] = input[18]; - step1[10] = input[10]; - step1[11] = input[26]; - step1[12] = input[6]; - step1[13] = input[22]; - step1[14] = input[14]; - step1[15] = input[30]; - - temp1 = - input[1] * (tran_high_t)cospi_31_64 - input[31] * (tran_high_t)cospi_1_64; - temp2 = - input[1] * (tran_high_t)cospi_1_64 + input[31] * (tran_high_t)cospi_31_64; - step1[16] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[31] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - temp1 = input[17] * (tran_high_t)cospi_15_64 - - input[15] * (tran_high_t)cospi_17_64; - temp2 = input[17] * (tran_high_t)cospi_17_64 + - input[15] * (tran_high_t)cospi_15_64; - step1[17] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[30] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - temp1 = - input[9] * (tran_high_t)cospi_23_64 - input[23] * (tran_high_t)cospi_9_64; - temp2 = - input[9] * (tran_high_t)cospi_9_64 + input[23] * (tran_high_t)cospi_23_64; - step1[18] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[29] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - temp1 = - input[25] * (tran_high_t)cospi_7_64 - input[7] * (tran_high_t)cospi_25_64; - temp2 = - input[25] * (tran_high_t)cospi_25_64 + input[7] * (tran_high_t)cospi_7_64; - step1[19] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[28] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - temp1 = - input[5] * (tran_high_t)cospi_27_64 - input[27] * (tran_high_t)cospi_5_64; - temp2 = - input[5] * (tran_high_t)cospi_5_64 + input[27] * (tran_high_t)cospi_27_64; - step1[20] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[27] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - temp1 = input[21] * (tran_high_t)cospi_11_64 - - input[11] * (tran_high_t)cospi_21_64; - temp2 = input[21] * (tran_high_t)cospi_21_64 + - input[11] * (tran_high_t)cospi_11_64; - step1[21] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[26] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - temp1 = input[13] * (tran_high_t)cospi_19_64 - - input[19] * (tran_high_t)cospi_13_64; - temp2 = input[13] * (tran_high_t)cospi_13_64 + - input[19] * (tran_high_t)cospi_19_64; - step1[22] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[25] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - temp1 = - input[29] * (tran_high_t)cospi_3_64 - input[3] * (tran_high_t)cospi_29_64; - temp2 = - input[29] * (tran_high_t)cospi_29_64 + input[3] * (tran_high_t)cospi_3_64; - step1[23] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[24] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - // stage 2 - step2[0] = step1[0]; - step2[1] = step1[1]; - step2[2] = step1[2]; - step2[3] = step1[3]; - step2[4] = step1[4]; - step2[5] = step1[5]; - step2[6] = step1[6]; - step2[7] = step1[7]; - - temp1 = - step1[8] * (tran_high_t)cospi_30_64 - step1[15] * (tran_high_t)cospi_2_64; - temp2 = - step1[8] * (tran_high_t)cospi_2_64 + step1[15] * (tran_high_t)cospi_30_64; - step2[8] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[15] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - temp1 = step1[9] * (tran_high_t)cospi_14_64 - - step1[14] * (tran_high_t)cospi_18_64; - temp2 = step1[9] * (tran_high_t)cospi_18_64 + - step1[14] * (tran_high_t)cospi_14_64; - step2[9] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[14] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - temp1 = step1[10] * (tran_high_t)cospi_22_64 - - step1[13] * (tran_high_t)cospi_10_64; - temp2 = step1[10] * (tran_high_t)cospi_10_64 + - step1[13] * (tran_high_t)cospi_22_64; - step2[10] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[13] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - temp1 = step1[11] * (tran_high_t)cospi_6_64 - - step1[12] * (tran_high_t)cospi_26_64; - temp2 = step1[11] * (tran_high_t)cospi_26_64 + - step1[12] * (tran_high_t)cospi_6_64; - step2[11] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[12] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - step2[16] = HIGHBD_WRAPLOW(step1[16] + step1[17], bd); - step2[17] = HIGHBD_WRAPLOW(step1[16] - step1[17], bd); - step2[18] = HIGHBD_WRAPLOW(-step1[18] + step1[19], bd); - step2[19] = HIGHBD_WRAPLOW(step1[18] + step1[19], bd); - step2[20] = HIGHBD_WRAPLOW(step1[20] + step1[21], bd); - step2[21] = HIGHBD_WRAPLOW(step1[20] - step1[21], bd); - step2[22] = HIGHBD_WRAPLOW(-step1[22] + step1[23], bd); - step2[23] = HIGHBD_WRAPLOW(step1[22] + step1[23], bd); - step2[24] = HIGHBD_WRAPLOW(step1[24] + step1[25], bd); - step2[25] = HIGHBD_WRAPLOW(step1[24] - step1[25], bd); - step2[26] = HIGHBD_WRAPLOW(-step1[26] + step1[27], bd); - step2[27] = HIGHBD_WRAPLOW(step1[26] + step1[27], bd); - step2[28] = HIGHBD_WRAPLOW(step1[28] + step1[29], bd); - step2[29] = HIGHBD_WRAPLOW(step1[28] - step1[29], bd); - step2[30] = HIGHBD_WRAPLOW(-step1[30] + step1[31], bd); - step2[31] = HIGHBD_WRAPLOW(step1[30] + step1[31], bd); - - // stage 3 - step1[0] = step2[0]; - step1[1] = step2[1]; - step1[2] = step2[2]; - step1[3] = step2[3]; - - temp1 = - step2[4] * (tran_high_t)cospi_28_64 - step2[7] * (tran_high_t)cospi_4_64; - temp2 = - step2[4] * (tran_high_t)cospi_4_64 + step2[7] * (tran_high_t)cospi_28_64; - step1[4] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[7] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = - step2[5] * (tran_high_t)cospi_12_64 - step2[6] * (tran_high_t)cospi_20_64; - temp2 = - step2[5] * (tran_high_t)cospi_20_64 + step2[6] * (tran_high_t)cospi_12_64; - step1[5] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[6] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - - step1[8] = HIGHBD_WRAPLOW(step2[8] + step2[9], bd); - step1[9] = HIGHBD_WRAPLOW(step2[8] - step2[9], bd); - step1[10] = HIGHBD_WRAPLOW(-step2[10] + step2[11], bd); - step1[11] = HIGHBD_WRAPLOW(step2[10] + step2[11], bd); - step1[12] = HIGHBD_WRAPLOW(step2[12] + step2[13], bd); - step1[13] = HIGHBD_WRAPLOW(step2[12] - step2[13], bd); - step1[14] = HIGHBD_WRAPLOW(-step2[14] + step2[15], bd); - step1[15] = HIGHBD_WRAPLOW(step2[14] + step2[15], bd); - - step1[16] = step2[16]; - step1[31] = step2[31]; - temp1 = -step2[17] * (tran_high_t)cospi_4_64 + - step2[30] * (tran_high_t)cospi_28_64; - temp2 = step2[17] * (tran_high_t)cospi_28_64 + - step2[30] * (tran_high_t)cospi_4_64; - step1[17] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[30] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = -step2[18] * (tran_high_t)cospi_28_64 - - step2[29] * (tran_high_t)cospi_4_64; - temp2 = -step2[18] * (tran_high_t)cospi_4_64 + - step2[29] * (tran_high_t)cospi_28_64; - step1[18] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[29] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - step1[19] = step2[19]; - step1[20] = step2[20]; - temp1 = -step2[21] * (tran_high_t)cospi_20_64 + - step2[26] * (tran_high_t)cospi_12_64; - temp2 = step2[21] * (tran_high_t)cospi_12_64 + - step2[26] * (tran_high_t)cospi_20_64; - step1[21] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[26] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = -step2[22] * (tran_high_t)cospi_12_64 - - step2[25] * (tran_high_t)cospi_20_64; - temp2 = -step2[22] * (tran_high_t)cospi_20_64 + - step2[25] * (tran_high_t)cospi_12_64; - step1[22] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[25] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - step1[23] = step2[23]; - step1[24] = step2[24]; - step1[27] = step2[27]; - step1[28] = step2[28]; - - // stage 4 - temp1 = (step1[0] + step1[1]) * (tran_high_t)cospi_16_64; - temp2 = (step1[0] - step1[1]) * (tran_high_t)cospi_16_64; - step2[0] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[1] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = - step1[2] * (tran_high_t)cospi_24_64 - step1[3] * (tran_high_t)cospi_8_64; - temp2 = - step1[2] * (tran_high_t)cospi_8_64 + step1[3] * (tran_high_t)cospi_24_64; - step2[2] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[3] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - step2[4] = HIGHBD_WRAPLOW(step1[4] + step1[5], bd); - step2[5] = HIGHBD_WRAPLOW(step1[4] - step1[5], bd); - step2[6] = HIGHBD_WRAPLOW(-step1[6] + step1[7], bd); - step2[7] = HIGHBD_WRAPLOW(step1[6] + step1[7], bd); - - step2[8] = step1[8]; - step2[15] = step1[15]; - temp1 = -step1[9] * (tran_high_t)cospi_8_64 + - step1[14] * (tran_high_t)cospi_24_64; - temp2 = - step1[9] * (tran_high_t)cospi_24_64 + step1[14] * (tran_high_t)cospi_8_64; - step2[9] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[14] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = -step1[10] * (tran_high_t)cospi_24_64 - - step1[13] * (tran_high_t)cospi_8_64; - temp2 = -step1[10] * (tran_high_t)cospi_8_64 + - step1[13] * (tran_high_t)cospi_24_64; - step2[10] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[13] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - step2[11] = step1[11]; - step2[12] = step1[12]; - - step2[16] = HIGHBD_WRAPLOW(step1[16] + step1[19], bd); - step2[17] = HIGHBD_WRAPLOW(step1[17] + step1[18], bd); - step2[18] = HIGHBD_WRAPLOW(step1[17] - step1[18], bd); - step2[19] = HIGHBD_WRAPLOW(step1[16] - step1[19], bd); - step2[20] = HIGHBD_WRAPLOW(-step1[20] + step1[23], bd); - step2[21] = HIGHBD_WRAPLOW(-step1[21] + step1[22], bd); - step2[22] = HIGHBD_WRAPLOW(step1[21] + step1[22], bd); - step2[23] = HIGHBD_WRAPLOW(step1[20] + step1[23], bd); - - step2[24] = HIGHBD_WRAPLOW(step1[24] + step1[27], bd); - step2[25] = HIGHBD_WRAPLOW(step1[25] + step1[26], bd); - step2[26] = HIGHBD_WRAPLOW(step1[25] - step1[26], bd); - step2[27] = HIGHBD_WRAPLOW(step1[24] - step1[27], bd); - step2[28] = HIGHBD_WRAPLOW(-step1[28] + step1[31], bd); - step2[29] = HIGHBD_WRAPLOW(-step1[29] + step1[30], bd); - step2[30] = HIGHBD_WRAPLOW(step1[29] + step1[30], bd); - step2[31] = HIGHBD_WRAPLOW(step1[28] + step1[31], bd); - - // stage 5 - step1[0] = HIGHBD_WRAPLOW(step2[0] + step2[3], bd); - step1[1] = HIGHBD_WRAPLOW(step2[1] + step2[2], bd); - step1[2] = HIGHBD_WRAPLOW(step2[1] - step2[2], bd); - step1[3] = HIGHBD_WRAPLOW(step2[0] - step2[3], bd); - step1[4] = step2[4]; - temp1 = (step2[6] - step2[5]) * (tran_high_t)cospi_16_64; - temp2 = (step2[5] + step2[6]) * (tran_high_t)cospi_16_64; - step1[5] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[6] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - step1[7] = step2[7]; - - step1[8] = HIGHBD_WRAPLOW(step2[8] + step2[11], bd); - step1[9] = HIGHBD_WRAPLOW(step2[9] + step2[10], bd); - step1[10] = HIGHBD_WRAPLOW(step2[9] - step2[10], bd); - step1[11] = HIGHBD_WRAPLOW(step2[8] - step2[11], bd); - step1[12] = HIGHBD_WRAPLOW(-step2[12] + step2[15], bd); - step1[13] = HIGHBD_WRAPLOW(-step2[13] + step2[14], bd); - step1[14] = HIGHBD_WRAPLOW(step2[13] + step2[14], bd); - step1[15] = HIGHBD_WRAPLOW(step2[12] + step2[15], bd); - - step1[16] = step2[16]; - step1[17] = step2[17]; - temp1 = -step2[18] * (tran_high_t)cospi_8_64 + - step2[29] * (tran_high_t)cospi_24_64; - temp2 = step2[18] * (tran_high_t)cospi_24_64 + - step2[29] * (tran_high_t)cospi_8_64; - step1[18] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[29] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = -step2[19] * (tran_high_t)cospi_8_64 + - step2[28] * (tran_high_t)cospi_24_64; - temp2 = step2[19] * (tran_high_t)cospi_24_64 + - step2[28] * (tran_high_t)cospi_8_64; - step1[19] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[28] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = -step2[20] * (tran_high_t)cospi_24_64 - - step2[27] * (tran_high_t)cospi_8_64; - temp2 = -step2[20] * (tran_high_t)cospi_8_64 + - step2[27] * (tran_high_t)cospi_24_64; - step1[20] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[27] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = -step2[21] * (tran_high_t)cospi_24_64 - - step2[26] * (tran_high_t)cospi_8_64; - temp2 = -step2[21] * (tran_high_t)cospi_8_64 + - step2[26] * (tran_high_t)cospi_24_64; - step1[21] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[26] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - step1[22] = step2[22]; - step1[23] = step2[23]; - step1[24] = step2[24]; - step1[25] = step2[25]; - step1[30] = step2[30]; - step1[31] = step2[31]; - - // stage 6 - step2[0] = HIGHBD_WRAPLOW(step1[0] + step1[7], bd); - step2[1] = HIGHBD_WRAPLOW(step1[1] + step1[6], bd); - step2[2] = HIGHBD_WRAPLOW(step1[2] + step1[5], bd); - step2[3] = HIGHBD_WRAPLOW(step1[3] + step1[4], bd); - step2[4] = HIGHBD_WRAPLOW(step1[3] - step1[4], bd); - step2[5] = HIGHBD_WRAPLOW(step1[2] - step1[5], bd); - step2[6] = HIGHBD_WRAPLOW(step1[1] - step1[6], bd); - step2[7] = HIGHBD_WRAPLOW(step1[0] - step1[7], bd); - step2[8] = step1[8]; - step2[9] = step1[9]; - temp1 = (-step1[10] + step1[13]) * (tran_high_t)cospi_16_64; - temp2 = (step1[10] + step1[13]) * (tran_high_t)cospi_16_64; - step2[10] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[13] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = (-step1[11] + step1[12]) * (tran_high_t)cospi_16_64; - temp2 = (step1[11] + step1[12]) * (tran_high_t)cospi_16_64; - step2[11] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step2[12] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - step2[14] = step1[14]; - step2[15] = step1[15]; - - step2[16] = HIGHBD_WRAPLOW(step1[16] + step1[23], bd); - step2[17] = HIGHBD_WRAPLOW(step1[17] + step1[22], bd); - step2[18] = HIGHBD_WRAPLOW(step1[18] + step1[21], bd); - step2[19] = HIGHBD_WRAPLOW(step1[19] + step1[20], bd); - step2[20] = HIGHBD_WRAPLOW(step1[19] - step1[20], bd); - step2[21] = HIGHBD_WRAPLOW(step1[18] - step1[21], bd); - step2[22] = HIGHBD_WRAPLOW(step1[17] - step1[22], bd); - step2[23] = HIGHBD_WRAPLOW(step1[16] - step1[23], bd); - - step2[24] = HIGHBD_WRAPLOW(-step1[24] + step1[31], bd); - step2[25] = HIGHBD_WRAPLOW(-step1[25] + step1[30], bd); - step2[26] = HIGHBD_WRAPLOW(-step1[26] + step1[29], bd); - step2[27] = HIGHBD_WRAPLOW(-step1[27] + step1[28], bd); - step2[28] = HIGHBD_WRAPLOW(step1[27] + step1[28], bd); - step2[29] = HIGHBD_WRAPLOW(step1[26] + step1[29], bd); - step2[30] = HIGHBD_WRAPLOW(step1[25] + step1[30], bd); - step2[31] = HIGHBD_WRAPLOW(step1[24] + step1[31], bd); - - // stage 7 - step1[0] = HIGHBD_WRAPLOW(step2[0] + step2[15], bd); - step1[1] = HIGHBD_WRAPLOW(step2[1] + step2[14], bd); - step1[2] = HIGHBD_WRAPLOW(step2[2] + step2[13], bd); - step1[3] = HIGHBD_WRAPLOW(step2[3] + step2[12], bd); - step1[4] = HIGHBD_WRAPLOW(step2[4] + step2[11], bd); - step1[5] = HIGHBD_WRAPLOW(step2[5] + step2[10], bd); - step1[6] = HIGHBD_WRAPLOW(step2[6] + step2[9], bd); - step1[7] = HIGHBD_WRAPLOW(step2[7] + step2[8], bd); - step1[8] = HIGHBD_WRAPLOW(step2[7] - step2[8], bd); - step1[9] = HIGHBD_WRAPLOW(step2[6] - step2[9], bd); - step1[10] = HIGHBD_WRAPLOW(step2[5] - step2[10], bd); - step1[11] = HIGHBD_WRAPLOW(step2[4] - step2[11], bd); - step1[12] = HIGHBD_WRAPLOW(step2[3] - step2[12], bd); - step1[13] = HIGHBD_WRAPLOW(step2[2] - step2[13], bd); - step1[14] = HIGHBD_WRAPLOW(step2[1] - step2[14], bd); - step1[15] = HIGHBD_WRAPLOW(step2[0] - step2[15], bd); - - step1[16] = step2[16]; - step1[17] = step2[17]; - step1[18] = step2[18]; - step1[19] = step2[19]; - temp1 = (-step2[20] + step2[27]) * (tran_high_t)cospi_16_64; - temp2 = (step2[20] + step2[27]) * (tran_high_t)cospi_16_64; - step1[20] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[27] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = (-step2[21] + step2[26]) * (tran_high_t)cospi_16_64; - temp2 = (step2[21] + step2[26]) * (tran_high_t)cospi_16_64; - step1[21] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[26] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = (-step2[22] + step2[25]) * (tran_high_t)cospi_16_64; - temp2 = (step2[22] + step2[25]) * (tran_high_t)cospi_16_64; - step1[22] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[25] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - temp1 = (-step2[23] + step2[24]) * (tran_high_t)cospi_16_64; - temp2 = (step2[23] + step2[24]) * (tran_high_t)cospi_16_64; - step1[23] = HIGHBD_WRAPLOW(dct_const_round_shift(temp1), bd); - step1[24] = HIGHBD_WRAPLOW(dct_const_round_shift(temp2), bd); - step1[28] = step2[28]; - step1[29] = step2[29]; - step1[30] = step2[30]; - step1[31] = step2[31]; - - // final stage - output[0] = HIGHBD_WRAPLOW(step1[0] + step1[31], bd); - output[1] = HIGHBD_WRAPLOW(step1[1] + step1[30], bd); - output[2] = HIGHBD_WRAPLOW(step1[2] + step1[29], bd); - output[3] = HIGHBD_WRAPLOW(step1[3] + step1[28], bd); - output[4] = HIGHBD_WRAPLOW(step1[4] + step1[27], bd); - output[5] = HIGHBD_WRAPLOW(step1[5] + step1[26], bd); - output[6] = HIGHBD_WRAPLOW(step1[6] + step1[25], bd); - output[7] = HIGHBD_WRAPLOW(step1[7] + step1[24], bd); - output[8] = HIGHBD_WRAPLOW(step1[8] + step1[23], bd); - output[9] = HIGHBD_WRAPLOW(step1[9] + step1[22], bd); - output[10] = HIGHBD_WRAPLOW(step1[10] + step1[21], bd); - output[11] = HIGHBD_WRAPLOW(step1[11] + step1[20], bd); - output[12] = HIGHBD_WRAPLOW(step1[12] + step1[19], bd); - output[13] = HIGHBD_WRAPLOW(step1[13] + step1[18], bd); - output[14] = HIGHBD_WRAPLOW(step1[14] + step1[17], bd); - output[15] = HIGHBD_WRAPLOW(step1[15] + step1[16], bd); - output[16] = HIGHBD_WRAPLOW(step1[15] - step1[16], bd); - output[17] = HIGHBD_WRAPLOW(step1[14] - step1[17], bd); - output[18] = HIGHBD_WRAPLOW(step1[13] - step1[18], bd); - output[19] = HIGHBD_WRAPLOW(step1[12] - step1[19], bd); - output[20] = HIGHBD_WRAPLOW(step1[11] - step1[20], bd); - output[21] = HIGHBD_WRAPLOW(step1[10] - step1[21], bd); - output[22] = HIGHBD_WRAPLOW(step1[9] - step1[22], bd); - output[23] = HIGHBD_WRAPLOW(step1[8] - step1[23], bd); - output[24] = HIGHBD_WRAPLOW(step1[7] - step1[24], bd); - output[25] = HIGHBD_WRAPLOW(step1[6] - step1[25], bd); - output[26] = HIGHBD_WRAPLOW(step1[5] - step1[26], bd); - output[27] = HIGHBD_WRAPLOW(step1[4] - step1[27], bd); - output[28] = HIGHBD_WRAPLOW(step1[3] - step1[28], bd); - output[29] = HIGHBD_WRAPLOW(step1[2] - step1[29], bd); - output[30] = HIGHBD_WRAPLOW(step1[1] - step1[30], bd); - output[31] = HIGHBD_WRAPLOW(step1[0] - step1[31], bd); -} - -void vpx_highbd_idct32x32_1024_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i, j; - tran_low_t out[32 * 32]; - tran_low_t *outptr = out; - tran_low_t temp_in[32], temp_out[32]; - - // Rows - for (i = 0; i < 32; ++i) { - tran_low_t zero_coeff = 0; - for (j = 0; j < 32; ++j) zero_coeff |= input[j]; - - if (zero_coeff) - highbd_idct32_c(input, outptr, bd); - else - memset(outptr, 0, sizeof(tran_low_t) * 32); - input += 32; - outptr += 32; - } - - // Columns - for (i = 0; i < 32; ++i) { - for (j = 0; j < 32; ++j) temp_in[j] = out[j * 32 + i]; - highbd_idct32_c(temp_in, temp_out, bd); - for (j = 0; j < 32; ++j) { - dest[j * stride + i] = highbd_clip_pixel_add( - dest[j * stride + i], ROUND_POWER_OF_TWO(temp_out[j], 6), bd); - } - } -} - -void vpx_highbd_idct32x32_135_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i, j; - tran_low_t out[32 * 32] = { 0 }; - tran_low_t *outptr = out; - tran_low_t temp_in[32], temp_out[32]; - - // Rows - // Only upper-left 16x16 has non-zero coeff - for (i = 0; i < 16; ++i) { - highbd_idct32_c(input, outptr, bd); - input += 32; - outptr += 32; - } - - // Columns - for (i = 0; i < 32; ++i) { - uint16_t *destT = dest; - for (j = 0; j < 32; ++j) temp_in[j] = out[j * 32 + i]; - highbd_idct32_c(temp_in, temp_out, bd); - for (j = 0; j < 32; ++j) { - destT[i] = highbd_clip_pixel_add(destT[i], - ROUND_POWER_OF_TWO(temp_out[j], 6), bd); - destT += stride; - } - } -} - -void vpx_highbd_idct32x32_34_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i, j; - tran_low_t out[32 * 32] = { 0 }; - tran_low_t *outptr = out; - tran_low_t temp_in[32], temp_out[32]; - - // Rows - // Only upper-left 8x8 has non-zero coeff - for (i = 0; i < 8; ++i) { - highbd_idct32_c(input, outptr, bd); - input += 32; - outptr += 32; - } - - // Columns - for (i = 0; i < 32; ++i) { - for (j = 0; j < 32; ++j) temp_in[j] = out[j * 32 + i]; - highbd_idct32_c(temp_in, temp_out, bd); - for (j = 0; j < 32; ++j) { - dest[j * stride + i] = highbd_clip_pixel_add( - dest[j * stride + i], ROUND_POWER_OF_TWO(temp_out[j], 6), bd); - } - } -} - -void vpx_highbd_idct32x32_1_add_c(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i, j; - int a1; - tran_low_t out = HIGHBD_WRAPLOW( - dct_const_round_shift(input[0] * (tran_high_t)cospi_16_64), bd); - - out = - HIGHBD_WRAPLOW(dct_const_round_shift(out * (tran_high_t)cospi_16_64), bd); - a1 = ROUND_POWER_OF_TWO(out, 6); - - for (j = 0; j < 32; ++j) { - for (i = 0; i < 32; ++i) dest[i] = highbd_clip_pixel_add(dest[i], a1, bd); - dest += stride; - } -} - -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/inv_txfm.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/inv_txfm.h deleted file mode 100644 index 6eedbeac..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/inv_txfm.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_INV_TXFM_H_ -#define VPX_VPX_DSP_INV_TXFM_H_ - -#include - -#include "./vpx_config.h" -#include "vpx_dsp/txfm_common.h" -#include "vpx_ports/mem.h" - -#ifdef __cplusplus -extern "C" { -#endif - -static INLINE tran_high_t check_range(tran_high_t input) { -#if CONFIG_COEFFICIENT_RANGE_CHECKING - // For valid VP9 input streams, intermediate stage coefficients should always - // stay within the range of a signed 16 bit integer. Coefficients can go out - // of this range for invalid/corrupt VP9 streams. However, strictly checking - // this range for every intermediate coefficient can burdensome for a decoder, - // therefore the following assertion is only enabled when configured with - // --enable-coefficient-range-checking. - assert(INT16_MIN <= input); - assert(input <= INT16_MAX); -#endif // CONFIG_COEFFICIENT_RANGE_CHECKING - return input; -} - -static INLINE tran_high_t dct_const_round_shift(tran_high_t input) { - tran_high_t rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS); - return (tran_high_t)rv; -} - -#if CONFIG_VP9_HIGHBITDEPTH -static INLINE tran_high_t highbd_check_range(tran_high_t input, int bd) { -#if CONFIG_COEFFICIENT_RANGE_CHECKING - // For valid highbitdepth VP9 streams, intermediate stage coefficients will - // stay within the ranges: - // - 8 bit: signed 16 bit integer - // - 10 bit: signed 18 bit integer - // - 12 bit: signed 20 bit integer - const int32_t int_max = (1 << (7 + bd)) - 1; - const int32_t int_min = -int_max - 1; - assert(int_min <= input); - assert(input <= int_max); - (void)int_min; -#endif // CONFIG_COEFFICIENT_RANGE_CHECKING - (void)bd; - return input; -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -#if CONFIG_EMULATE_HARDWARE -// When CONFIG_EMULATE_HARDWARE is 1 the transform performs a -// non-normative method to handle overflows. A stream that causes -// overflows in the inverse transform is considered invalid in VP9, -// and a hardware implementer is free to choose any reasonable -// method to handle overflows. However to aid in hardware -// verification they can use a specific implementation of the -// WRAPLOW() macro below that is identical to their intended -// hardware implementation (and also use configure options to trigger -// the C-implementation of the transform). -// -// The particular WRAPLOW implementation below performs strict -// overflow wrapping to match common hardware implementations. -// bd of 8 uses trans_low with 16bits, need to remove 16bits -// bd of 10 uses trans_low with 18bits, need to remove 14bits -// bd of 12 uses trans_low with 20bits, need to remove 12bits -// bd of x uses trans_low with 8+x bits, need to remove 24-x bits -#define WRAPLOW(x) ((((int32_t)check_range(x)) << 16) >> 16) -#if CONFIG_VP9_HIGHBITDEPTH -#define HIGHBD_WRAPLOW(x, bd) \ - ((((int32_t)highbd_check_range((x), bd)) << (24 - bd)) >> (24 - bd)) -#endif // CONFIG_VP9_HIGHBITDEPTH - -#else // CONFIG_EMULATE_HARDWARE - -#define WRAPLOW(x) ((int32_t)check_range(x)) -#if CONFIG_VP9_HIGHBITDEPTH -#define HIGHBD_WRAPLOW(x, bd) ((int32_t)highbd_check_range((x), bd)) -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif // CONFIG_EMULATE_HARDWARE - -void idct4_c(const tran_low_t *input, tran_low_t *output); -void idct8_c(const tran_low_t *input, tran_low_t *output); -void idct16_c(const tran_low_t *input, tran_low_t *output); -void idct32_c(const tran_low_t *input, tran_low_t *output); -void iadst4_c(const tran_low_t *input, tran_low_t *output); -void iadst8_c(const tran_low_t *input, tran_low_t *output); -void iadst16_c(const tran_low_t *input, tran_low_t *output); - -#if CONFIG_VP9_HIGHBITDEPTH -void vpx_highbd_idct4_c(const tran_low_t *input, tran_low_t *output, int bd); -void vpx_highbd_idct8_c(const tran_low_t *input, tran_low_t *output, int bd); -void vpx_highbd_idct16_c(const tran_low_t *input, tran_low_t *output, int bd); - -void vpx_highbd_iadst4_c(const tran_low_t *input, tran_low_t *output, int bd); -void vpx_highbd_iadst8_c(const tran_low_t *input, tran_low_t *output, int bd); -void vpx_highbd_iadst16_c(const tran_low_t *input, tran_low_t *output, int bd); - -static INLINE uint16_t highbd_clip_pixel_add(uint16_t dest, tran_high_t trans, - int bd) { - trans = HIGHBD_WRAPLOW(trans, bd); - return clip_pixel_highbd(dest + (int)trans, bd); -} -#endif - -static INLINE uint8_t clip_pixel_add(uint8_t dest, tran_high_t trans) { - trans = WRAPLOW(trans); - return clip_pixel(dest + (int)trans); -} -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_INV_TXFM_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/avg_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/avg_lsx.c deleted file mode 100644 index 750c9de2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/avg_lsx.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/loongarch/bitdepth_conversion_lsx.h" - -void vpx_hadamard_8x8_lsx(const int16_t *src, ptrdiff_t src_stride, - tran_low_t *dst) { - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - ptrdiff_t src_stride2 = src_stride << 1; - ptrdiff_t src_stride3 = src_stride2 + src_stride; - ptrdiff_t src_stride4 = src_stride2 << 1; - ptrdiff_t src_stride6 = src_stride3 << 1; - - int16_t *src_tmp = (int16_t *)src; - src0 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, src_stride2, src_tmp, src_stride4, src1, src2); - src3 = __lsx_vldx(src_tmp, src_stride6); - src_tmp += src_stride4; - src4 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, src_stride2, src_tmp, src_stride4, src5, src6); - src7 = __lsx_vldx(src_tmp, src_stride6); - - LSX_BUTTERFLY_8_H(src0, src2, src4, src6, src7, src5, src3, src1, tmp0, tmp2, - tmp4, tmp6, tmp7, tmp5, tmp3, tmp1); - LSX_BUTTERFLY_8_H(tmp0, tmp1, tmp4, tmp5, tmp7, tmp6, tmp3, tmp2, src0, src1, - src4, src5, src7, src6, src3, src2); - LSX_BUTTERFLY_8_H(src0, src1, src2, src3, src7, src6, src5, src4, tmp0, tmp7, - tmp3, tmp4, tmp5, tmp1, tmp6, tmp2); - LSX_TRANSPOSE8x8_H(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, src0, src1, - src2, src3, src4, src5, src6, src7); - LSX_BUTTERFLY_8_H(src0, src2, src4, src6, src7, src5, src3, src1, tmp0, tmp2, - tmp4, tmp6, tmp7, tmp5, tmp3, tmp1); - LSX_BUTTERFLY_8_H(tmp0, tmp1, tmp4, tmp5, tmp7, tmp6, tmp3, tmp2, src0, src1, - src4, src5, src7, src6, src3, src2); - LSX_BUTTERFLY_8_H(src0, src1, src2, src3, src7, src6, src5, src4, tmp0, tmp7, - tmp3, tmp4, tmp5, tmp1, tmp6, tmp2); - store_tran_low(tmp0, dst, 0); - store_tran_low(tmp1, dst, 8); - store_tran_low(tmp2, dst, 16); - store_tran_low(tmp3, dst, 24); - store_tran_low(tmp4, dst, 32); - store_tran_low(tmp5, dst, 40); - store_tran_low(tmp6, dst, 48); - store_tran_low(tmp7, dst, 56); -} - -void vpx_hadamard_16x16_lsx(const int16_t *src, ptrdiff_t src_stride, - tran_low_t *dst) { - int i; - __m128i a0, a1, a2, a3, b0, b1, b2, b3; - - /* Rearrange 16x16 to 8x32 and remove stride. - * Top left first. */ - vpx_hadamard_8x8_lsx(src + 0 + 0 * src_stride, src_stride, dst + 0); - /* Top right. */ - vpx_hadamard_8x8_lsx(src + 8 + 0 * src_stride, src_stride, dst + 64); - /* Bottom left. */ - vpx_hadamard_8x8_lsx(src + 0 + 8 * src_stride, src_stride, dst + 128); - /* Bottom right. */ - vpx_hadamard_8x8_lsx(src + 8 + 8 * src_stride, src_stride, dst + 192); - - for (i = 0; i < 64; i += 8) { - a0 = load_tran_low(dst); - a1 = load_tran_low(dst + 64); - a2 = load_tran_low(dst + 128); - a3 = load_tran_low(dst + 192); - - LSX_BUTTERFLY_4_H(a0, a2, a3, a1, b0, b2, b3, b1); - DUP4_ARG2(__lsx_vsrai_h, b0, 1, b1, 1, b2, 1, b3, 1, b0, b1, b2, b3); - LSX_BUTTERFLY_4_H(b0, b1, b3, b2, a0, a1, a3, a2); - - store_tran_low(a0, dst, 0); - store_tran_low(a1, dst, 64); - store_tran_low(a2, dst, 128); - store_tran_low(a3, dst, 192); - - dst += 8; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/avg_pred_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/avg_pred_lsx.c deleted file mode 100644 index 48262608..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/avg_pred_lsx.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_util/loongson_intrinsics.h" - -void vpx_comp_avg_pred_lsx(uint8_t *comp_pred, const uint8_t *pred, int width, - int height, const uint8_t *ref, int ref_stride) { - // width > 8 || width == 8 || width == 4 - if (width > 8) { - int i, j; - for (i = 0; i < height; ++i) { - for (j = 0; j < width; j += 16) { - __m128i p, r, avg; - - p = __lsx_vld(pred + j, 0); - r = __lsx_vld(ref + j, 0); - avg = __lsx_vavgr_bu(p, r); - __lsx_vst(avg, comp_pred + j, 0); - } - comp_pred += width; - pred += width; - ref += ref_stride; - } - } else if (width == 8) { - int i = height * width; - do { - __m128i p, r, r_0, r_1; - - p = __lsx_vld(pred, 0); - r_0 = __lsx_vld(ref, 0); - ref += ref_stride; - r_1 = __lsx_vld(ref, 0); - ref += ref_stride; - r = __lsx_vilvl_d(r_1, r_0); - r = __lsx_vavgr_bu(p, r); - - __lsx_vst(r, comp_pred, 0); - - pred += 16; - comp_pred += 16; - i -= 16; - } while (i); - } else { // width = 4 - int i = height * width; - assert(width == 4); - do { - __m128i p, r, r_0, r_1, r_2, r_3; - p = __lsx_vld(pred, 0); - - if (width == ref_stride) { - r = __lsx_vld(ref, 0); - ref += 16; - } else { - r_0 = __lsx_vld(ref, 0); - ref += ref_stride; - r_1 = __lsx_vld(ref, 0); - ref += ref_stride; - r_2 = __lsx_vld(ref, 0); - ref += ref_stride; - r_3 = __lsx_vld(ref, 0); - ref += ref_stride; - DUP2_ARG2(__lsx_vilvl_w, r_1, r_0, r_3, r_2, r_0, r_2); - r = __lsx_vilvl_d(r_2, r_0); - } - r = __lsx_vavgr_bu(p, r); - - __lsx_vst(r, comp_pred, 0); - comp_pred += 16; - pred += 16; - i -= 16; - } while (i); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/bitdepth_conversion_lsx.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/bitdepth_conversion_lsx.h deleted file mode 100644 index b0db1e99..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/bitdepth_conversion_lsx.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_LOONGARCH_BITDEPTH_CONVERSION_LSX_H_ -#define VPX_VPX_DSP_LOONGARCH_BITDEPTH_CONVERSION_LSX_H_ - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_util/loongson_intrinsics.h" - -static INLINE __m128i load_tran_low(const tran_low_t *s) { -#if CONFIG_VP9_HIGHBITDEPTH - __m128i v0_m = __lsx_vld(s, 0); - __m128i v1_m = __lsx_vld(s + 4, 0); - return __lsx_vsrlni_h_w(v0_m, v1_m, 0); -#else - return __lsx_vld(s, 0); -#endif -} - -static INLINE void store_tran_low(__m128i v, tran_low_t *s, int32_t c) { -#if CONFIG_VP9_HIGHBITDEPTH - __m128i v0_m, v1_m; - v1_m = __lsx_vexth_w_h(v); - v0_m = __lsx_vsllwil_w_h(v, 0); - __lsx_vst(v0_m, s + c, 0); - __lsx_vst(v1_m, s + c + 4, 0); -#else - __lsx_vst(v, s + c, 0); -#endif -} - -#endif // VPX_VPX_DSP_LOONGARCH_BITDEPTH_CONVERSION_LSX_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/fwd_dct32x32_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/fwd_dct32x32_lsx.c deleted file mode 100644 index 9bb38772..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/fwd_dct32x32_lsx.c +++ /dev/null @@ -1,1176 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/loongarch/fwd_txfm_lsx.h" -#include "vpx_dsp/fwd_txfm.h" - -#define UNPCK_SH_SW(in, out0, out1) \ - do { \ - out0 = __lsx_vsllwil_w_h(in, 0); \ - out1 = __lsx_vexth_w_h(in); \ - } while (0) - -static void fdct8x32_1d_column_load_butterfly(const int16_t *input, - int32_t src_stride, - int16_t *temp_buff) { - __m128i in0, in1, in2, in3, in4, in5, in6, in7; - __m128i step0, step1, step2, step3; - __m128i in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1; - __m128i step0_1, step1_1, step2_1, step3_1; - - int32_t stride = src_stride << 1; - int32_t stride2 = stride << 1; - int32_t stride3 = stride2 + stride; - const int16_t *input_tmp = (int16_t *)input; - - in0 = __lsx_vld(input_tmp, 0); - DUP2_ARG2(__lsx_vldx, input_tmp, stride, input_tmp, stride2, in1, in2); - in3 = __lsx_vldx(input_tmp, stride3); - - input_tmp += stride2; - in0_1 = __lsx_vld(input_tmp, 0); - DUP2_ARG2(__lsx_vldx, input_tmp, stride, input_tmp, stride2, in1_1, in2_1); - in3_1 = __lsx_vldx(input_tmp, stride3); - - input_tmp = input + (src_stride * 24); - in4_1 = __lsx_vld(input_tmp, 0); - DUP2_ARG2(__lsx_vldx, input_tmp, stride, input_tmp, stride2, in5_1, in6_1); - in7_1 = __lsx_vldx(input_tmp, stride3); - - input_tmp += stride2; - in4 = __lsx_vld(input_tmp, 0); - DUP2_ARG2(__lsx_vldx, input_tmp, stride, input_tmp, stride2, in5, in6); - in7 = __lsx_vldx(input_tmp, stride3); - - DUP4_ARG2(__lsx_vslli_h, in0, 2, in1, 2, in2, 2, in3, 2, in0, in1, in2, in3); - DUP4_ARG2(__lsx_vslli_h, in4, 2, in5, 2, in6, 2, in7, 2, in4, in5, in6, in7); - DUP4_ARG2(__lsx_vslli_h, in0_1, 2, in1_1, 2, in2_1, 2, in3_1, 2, in0_1, in1_1, - in2_1, in3_1); - DUP4_ARG2(__lsx_vslli_h, in4_1, 2, in5_1, 2, in6_1, 2, in7_1, 2, in4_1, in5_1, - in6_1, in7_1); - LSX_BUTTERFLY_8_H(in0, in1, in2, in3, in4, in5, in6, in7, step0, step1, step2, - step3, in4, in5, in6, in7); - LSX_BUTTERFLY_8_H(in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1, - step0_1, step1_1, step2_1, step3_1, in4_1, in5_1, in6_1, - in7_1); - - __lsx_vst(step0, temp_buff, 0); - __lsx_vst(step1, temp_buff, 16); - __lsx_vst(step2, temp_buff, 32); - __lsx_vst(step3, temp_buff, 48); - - __lsx_vst(in4, temp_buff, 448); - __lsx_vst(in5, temp_buff, 464); - __lsx_vst(in6, temp_buff, 480); - __lsx_vst(in7, temp_buff, 496); - - __lsx_vst(step0_1, temp_buff, 64); - __lsx_vst(step1_1, temp_buff, 80); - __lsx_vst(step2_1, temp_buff, 96); - __lsx_vst(step3_1, temp_buff, 112); - - __lsx_vst(in4_1, temp_buff, 384); - __lsx_vst(in5_1, temp_buff, 400); - __lsx_vst(in6_1, temp_buff, 416); - __lsx_vst(in7_1, temp_buff, 432); - - /* 3rd and 4th set */ - input_tmp = input + (src_stride * 8); - in0 = __lsx_vld(input_tmp, 0); - DUP2_ARG2(__lsx_vldx, input_tmp, stride, input_tmp, stride2, in1, in2); - in3 = __lsx_vldx(input_tmp, stride3); - - input_tmp += stride2; - in0_1 = __lsx_vld(input_tmp, 0); - DUP2_ARG2(__lsx_vldx, input_tmp, stride, input_tmp, stride2, in1_1, in2_1); - in3_1 = __lsx_vldx(input_tmp, stride3); - - input_tmp += stride2; - in4_1 = __lsx_vld(input_tmp, 0); - DUP2_ARG2(__lsx_vldx, input_tmp, stride, input_tmp, stride2, in5_1, in6_1); - in7_1 = __lsx_vldx(input_tmp, stride3); - - input_tmp += stride2; - in4 = __lsx_vld(input_tmp, 0); - DUP2_ARG2(__lsx_vldx, input_tmp, stride, input_tmp, stride2, in5, in6); - in7 = __lsx_vldx(input_tmp, stride3); - DUP4_ARG2(__lsx_vslli_h, in0, 2, in1, 2, in2, 2, in3, 2, in0, in1, in2, in3); - DUP4_ARG2(__lsx_vslli_h, in4, 2, in5, 2, in6, 2, in7, 2, in4, in5, in6, in7); - DUP4_ARG2(__lsx_vslli_h, in0_1, 2, in1_1, 2, in2_1, 2, in3_1, 2, in0_1, in1_1, - in2_1, in3_1); - DUP4_ARG2(__lsx_vslli_h, in4_1, 2, in5_1, 2, in6_1, 2, in7_1, 2, in4_1, in5_1, - in6_1, in7_1); - - LSX_BUTTERFLY_8_H(in0, in1, in2, in3, in4, in5, in6, in7, step0, step1, step2, - step3, in4, in5, in6, in7); - LSX_BUTTERFLY_8_H(in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1, - step0_1, step1_1, step2_1, step3_1, in4_1, in5_1, in6_1, - in7_1); - - __lsx_vst(step0, temp_buff, 128); - __lsx_vst(step1, temp_buff, 144); - __lsx_vst(step2, temp_buff, 160); - __lsx_vst(step3, temp_buff, 176); - - __lsx_vst(in4, temp_buff, 320); - __lsx_vst(in5, temp_buff, 336); - __lsx_vst(in6, temp_buff, 352); - __lsx_vst(in7, temp_buff, 368); - - __lsx_vst(step0_1, temp_buff, 192); - __lsx_vst(step1_1, temp_buff, 208); - __lsx_vst(step2_1, temp_buff, 224); - __lsx_vst(step3_1, temp_buff, 240); - - __lsx_vst(in4_1, temp_buff, 256); - __lsx_vst(in5_1, temp_buff, 272); - __lsx_vst(in6_1, temp_buff, 288); - __lsx_vst(in7_1, temp_buff, 304); -} - -static void fdct8x32_1d_column_even_store(int16_t *input, int16_t *temp) { - __m128i in0, in1, in2, in3, in4, in5, in6, in7; - __m128i in8, in9, in10, in11, in12, in13, in14, in15; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - __m128i temp0, temp1; - - /* fdct even */ - DUP4_ARG2(__lsx_vld, input, 0, input, 16, input, 32, input, 48, in0, in1, in2, - in3); - DUP4_ARG2(__lsx_vld, input, 192, input, 208, input, 224, input, 240, in12, - in13, in14, in15); - LSX_BUTTERFLY_8_H(in0, in1, in2, in3, in12, in13, in14, in15, vec0, vec1, - vec2, vec3, in12, in13, in14, in15); - DUP4_ARG2(__lsx_vld, input, 64, input, 80, input, 96, input, 112, in4, in5, - in6, in7); - DUP4_ARG2(__lsx_vld, input, 128, input, 144, input, 160, input, 176, in8, in9, - in10, in11); - LSX_BUTTERFLY_8_H(in4, in5, in6, in7, in8, in9, in10, in11, vec4, vec5, vec6, - vec7, in8, in9, in10, in11); - - /* Stage 3 */ - DUP4_ARG2(__lsx_vadd_h, vec0, vec7, vec1, vec6, vec2, vec5, vec3, vec4, in0, - in1, in2, in3); - LSX_BUTTERFLY_4_H(in0, in1, in2, in3, temp0, in4, in1, in0); - DOTP_CONST_PAIR(temp0, in4, cospi_16_64, cospi_16_64, temp1, temp0); - FDCT32_POSTPROC_2V_POS_H(temp0, temp1); - __lsx_vst(temp0, temp, 0); - __lsx_vst(temp1, temp, 1024); - - DOTP_CONST_PAIR(in0, in1, cospi_24_64, cospi_8_64, temp1, temp0); - FDCT32_POSTPROC_2V_POS_H(temp0, temp1); - __lsx_vst(temp0, temp, 512); - __lsx_vst(temp1, temp, 1536); - - DUP4_ARG2(__lsx_vsub_h, vec0, vec7, vec1, vec6, vec2, vec5, vec3, vec4, vec7, - vec6, vec5, vec4); - DOTP_CONST_PAIR(vec6, vec5, cospi_16_64, cospi_16_64, vec5, vec6); - DUP2_ARG2(__lsx_vadd_h, vec4, vec5, vec7, vec6, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_28_64, cospi_4_64, temp1, temp0); - FDCT32_POSTPROC_2V_POS_H(temp0, temp1); - __lsx_vst(temp0, temp, 256); - __lsx_vst(temp1, temp, 1792); - - DUP2_ARG2(__lsx_vsub_h, vec4, vec5, vec7, vec6, vec4, vec7); - DOTP_CONST_PAIR(vec7, vec4, cospi_12_64, cospi_20_64, temp1, temp0); - FDCT32_POSTPROC_2V_POS_H(temp0, temp1); - __lsx_vst(temp0, temp, 1280); - __lsx_vst(temp1, temp, 768); - - DOTP_CONST_PAIR(in13, in10, cospi_16_64, cospi_16_64, vec2, vec5); - DOTP_CONST_PAIR(in12, in11, cospi_16_64, cospi_16_64, vec3, vec4); - DUP4_ARG2(__lsx_vadd_h, in8, vec3, in9, vec2, in14, vec5, in15, vec4, in0, - vec1, vec6, in2); - DOTP_CONST_PAIR(vec6, vec1, cospi_24_64, cospi_8_64, in1, in3); - DUP2_ARG2(__lsx_vadd_h, in0, in1, in2, in3, vec0, vec7); - DOTP_CONST_PAIR(vec7, vec0, cospi_30_64, cospi_2_64, temp1, temp0); - FDCT32_POSTPROC_2V_POS_H(temp0, temp1); - __lsx_vst(temp0, temp, 128); - __lsx_vst(temp1, temp, 1920); - - DUP2_ARG2(__lsx_vsub_h, in0, in1, in2, in3, in0, in2); - DOTP_CONST_PAIR(in2, in0, cospi_14_64, cospi_18_64, temp1, temp0); - FDCT32_POSTPROC_2V_POS_H(temp0, temp1); - __lsx_vst(temp0, temp, 1152); - __lsx_vst(temp1, temp, 896); - - DUP2_ARG2(__lsx_vsub_h, in9, vec2, in14, vec5, vec2, vec5); - temp0 = __lsx_vneg_h(vec2); - DOTP_CONST_PAIR(temp0, vec5, cospi_24_64, cospi_8_64, in2, in1); - DUP4_ARG2(__lsx_vsub_h, in8, vec3, in15, vec4, in3, in2, in0, in1, in3, in0, - vec2, vec5); - DOTP_CONST_PAIR(vec5, vec2, cospi_22_64, cospi_10_64, temp1, temp0); - FDCT32_POSTPROC_2V_POS_H(temp0, temp1); - __lsx_vst(temp0, temp, 640); - __lsx_vst(temp1, temp, 1408); - - DUP2_ARG2(__lsx_vadd_h, in3, in2, in0, in1, vec3, vec4); - DOTP_CONST_PAIR(vec4, vec3, cospi_6_64, cospi_26_64, temp0, temp1); - FDCT32_POSTPROC_2V_POS_H(temp0, temp1); - __lsx_vst(temp0, temp, 384); - __lsx_vst(temp1, temp, 1664); -} - -static void fdct8x32_1d_column_odd_store(int16_t *input, int16_t *temp_ptr) { - __m128i in16, in17, in18, in19, in20, in21, in22, in23; - __m128i in24, in25, in26, in27, in28, in29, in30, in31, vec4, vec5; - __m128i tmp0, tmp1; - - DUP4_ARG2(__lsx_vld, input, 64, input, 80, input, 160, input, 176, in20, in21, - in26, in27); - - DOTP_CONST_PAIR(in27, in20, cospi_16_64, cospi_16_64, in20, in27); - DOTP_CONST_PAIR(in26, in21, cospi_16_64, cospi_16_64, in21, in26); - - DUP4_ARG2(__lsx_vld, input, 32, input, 48, input, 192, input, 208, in18, in19, - in28, in29); - - vec4 = __lsx_vsub_h(in19, in20); - __lsx_vst(vec4, input, 64); - vec4 = __lsx_vsub_h(in18, in21); - __lsx_vst(vec4, input, 80); - vec4 = __lsx_vsub_h(in29, in26); - __lsx_vst(vec4, input, 160); - vec4 = __lsx_vsub_h(in28, in27); - __lsx_vst(vec4, input, 176); - - in21 = __lsx_vadd_h(in18, in21); - in20 = __lsx_vadd_h(in19, in20); - in27 = __lsx_vadd_h(in28, in27); - in26 = __lsx_vadd_h(in29, in26); - - DUP4_ARG2(__lsx_vld, input, 96, input, 112, input, 128, input, 144, in22, - in23, in24, in25); - DOTP_CONST_PAIR(in25, in22, cospi_16_64, cospi_16_64, in22, in25); - DOTP_CONST_PAIR(in24, in23, cospi_16_64, cospi_16_64, in23, in24); - - DUP4_ARG2(__lsx_vld, input, 0, input, 16, input, 224, input, 240, in16, in17, - in30, in31); - - vec4 = __lsx_vsub_h(in17, in22); - __lsx_vst(vec4, input, 32); - vec4 = __lsx_vsub_h(in16, in23); - __lsx_vst(vec4, input, 48); - vec4 = __lsx_vsub_h(in31, in24); - __lsx_vst(vec4, input, 192); - vec4 = __lsx_vsub_h(in30, in25); - __lsx_vst(vec4, input, 208); - - DUP4_ARG2(__lsx_vadd_h, in16, in23, in17, in22, in30, in25, in31, in24, in16, - in17, in30, in31); - DOTP_CONST_PAIR(in26, in21, cospi_24_64, cospi_8_64, in18, in29); - DOTP_CONST_PAIR(in27, in20, cospi_24_64, cospi_8_64, in19, in28); - DUP4_ARG2(__lsx_vadd_h, in16, in19, in17, in18, in30, in29, in31, in28, in27, - in22, in21, in25); - DOTP_CONST_PAIR(in21, in22, cospi_28_64, cospi_4_64, in26, in24); - DUP2_ARG2(__lsx_vadd_h, in27, in26, in25, in24, in23, in20); - DOTP_CONST_PAIR(in20, in23, cospi_31_64, cospi_1_64, vec4, vec5); - FDCT32_POSTPROC_2V_POS_H(vec5, vec4); - __lsx_vst(vec5, temp_ptr, 0); - __lsx_vst(vec4, temp_ptr, 1920); - - DUP2_ARG2(__lsx_vsub_h, in27, in26, in25, in24, in22, in21); - DOTP_CONST_PAIR(in21, in22, cospi_15_64, cospi_17_64, vec5, vec4); - FDCT32_POSTPROC_2V_POS_H(vec5, vec4); - __lsx_vst(vec5, temp_ptr, 896); - __lsx_vst(vec4, temp_ptr, 1024); - - DUP4_ARG2(__lsx_vsub_h, in17, in18, in16, in19, in31, in28, in30, in29, in23, - in26, in24, in20); - tmp0 = __lsx_vneg_h(in23); - DOTP_CONST_PAIR(tmp0, in20, cospi_28_64, cospi_4_64, in27, in25); - DUP2_ARG2(__lsx_vsub_h, in26, in27, in24, in25, in23, in20); - DOTP_CONST_PAIR(in20, in23, cospi_23_64, cospi_9_64, vec4, vec5); - FDCT32_POSTPROC_2V_POS_H(vec5, vec4); - __lsx_vst(vec4, temp_ptr, 1408); - __lsx_vst(vec5, temp_ptr, 512); - - DUP2_ARG2(__lsx_vadd_h, in26, in27, in24, in25, in22, in21); - DOTP_CONST_PAIR(in21, in22, cospi_7_64, cospi_25_64, vec4, vec5); - FDCT32_POSTPROC_2V_POS_H(vec5, vec4); - __lsx_vst(vec4, temp_ptr, 384); - __lsx_vst(vec5, temp_ptr, 1536); - - DUP4_ARG2(__lsx_vld, input, 32, input, 48, input, 64, input, 80, in22, in23, - in20, in21); - DUP4_ARG2(__lsx_vld, input, 160, input, 176, input, 192, input, 208, in26, - in27, in24, in25); - in16 = in20; - in17 = in21; - DUP2_ARG1(__lsx_vneg_h, in16, in17, tmp0, tmp1); - DOTP_CONST_PAIR(tmp0, in27, cospi_24_64, cospi_8_64, in20, in27); - DOTP_CONST_PAIR(tmp1, in26, cospi_24_64, cospi_8_64, in21, in26); - DUP4_ARG2(__lsx_vsub_h, in23, in20, in22, in21, in25, in26, in24, in27, in28, - in17, in18, in31); - DOTP_CONST_PAIR(in18, in17, cospi_12_64, cospi_20_64, in29, in30); - DUP2_ARG2(__lsx_vadd_h, in28, in29, in31, in30, in16, in19); - DOTP_CONST_PAIR(in19, in16, cospi_27_64, cospi_5_64, vec5, vec4); - FDCT32_POSTPROC_2V_POS_H(vec5, vec4); - __lsx_vst(vec5, temp_ptr, 1664); - __lsx_vst(vec4, temp_ptr, 256); - - DUP2_ARG2(__lsx_vsub_h, in28, in29, in31, in30, in17, in18); - DOTP_CONST_PAIR(in18, in17, cospi_11_64, cospi_21_64, vec5, vec4); - FDCT32_POSTPROC_2V_POS_H(vec5, vec4); - __lsx_vst(vec5, temp_ptr, 640); - __lsx_vst(vec4, temp_ptr, 1280); - - DUP4_ARG2(__lsx_vadd_h, in22, in21, in23, in20, in24, in27, in25, in26, in16, - in29, in30, in19); - tmp0 = __lsx_vneg_h(in16); - DOTP_CONST_PAIR(tmp0, in19, cospi_12_64, cospi_20_64, in28, in31); - DUP2_ARG2(__lsx_vsub_h, in29, in28, in30, in31, in16, in19); - DOTP_CONST_PAIR(in19, in16, cospi_19_64, cospi_13_64, vec5, vec4); - FDCT32_POSTPROC_2V_POS_H(vec5, vec4); - __lsx_vst(vec5, temp_ptr, 1152); - __lsx_vst(vec4, temp_ptr, 768); - - DUP2_ARG2(__lsx_vadd_h, in29, in28, in30, in31, in17, in18); - DOTP_CONST_PAIR(in18, in17, cospi_3_64, cospi_29_64, vec5, vec4); - FDCT32_POSTPROC_2V_POS_H(vec5, vec4); - __lsx_vst(vec5, temp_ptr, 128); - __lsx_vst(vec4, temp_ptr, 1792); -} - -static void fdct8x32_1d_column(const int16_t *input, int32_t src_stride, - int16_t *tmp_buf, int16_t *tmp_buf_big) { - fdct8x32_1d_column_load_butterfly(input, src_stride, tmp_buf); - fdct8x32_1d_column_even_store(tmp_buf, tmp_buf_big); - fdct8x32_1d_column_odd_store(tmp_buf + 128, (tmp_buf_big + 32)); -} - -static void fdct8x32_1d_row_load_butterfly(int16_t *temp_buff, - int16_t *output) { - __m128i in0, in1, in2, in3, in4, in5, in6, in7; - __m128i in8, in9, in10, in11, in12, in13, in14, in15; - __m128i step0, step1, step2, step3, step4, step5, step6, step7; - - DUP4_ARG2(__lsx_vld, temp_buff, 0, temp_buff, 64, temp_buff, 128, temp_buff, - 192, in0, in1, in2, in3); - DUP4_ARG2(__lsx_vld, temp_buff, 256, temp_buff, 320, temp_buff, 384, - temp_buff, 448, in4, in5, in6, in7); - DUP4_ARG2(__lsx_vld, temp_buff, 48, temp_buff, 112, temp_buff, 176, temp_buff, - 240, in8, in9, in10, in11); - DUP4_ARG2(__lsx_vld, temp_buff, 304, temp_buff, 368, temp_buff, 432, - temp_buff, 496, in12, in13, in14, in15); - LSX_TRANSPOSE8x8_H(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - LSX_TRANSPOSE8x8_H(in8, in9, in10, in11, in12, in13, in14, in15, in8, in9, - in10, in11, in12, in13, in14, in15); - LSX_BUTTERFLY_16_H(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, - in11, in12, in13, in14, in15, step0, step1, step2, step3, - step4, step5, step6, step7, in8, in9, in10, in11, in12, - in13, in14, in15); - - __lsx_vst(step0, output, 0); - __lsx_vst(step1, output, 16); - __lsx_vst(step2, output, 32); - __lsx_vst(step3, output, 48); - __lsx_vst(step4, output, 64); - __lsx_vst(step5, output, 80); - __lsx_vst(step6, output, 96); - __lsx_vst(step7, output, 112); - - __lsx_vst(in8, output, 384); - __lsx_vst(in9, output, 400); - __lsx_vst(in10, output, 416); - __lsx_vst(in11, output, 432); - __lsx_vst(in12, output, 448); - __lsx_vst(in13, output, 464); - __lsx_vst(in14, output, 480); - __lsx_vst(in15, output, 496); - - /* 2nd set */ - DUP4_ARG2(__lsx_vld, temp_buff, 16, temp_buff, 80, temp_buff, 144, temp_buff, - 208, in0, in1, in2, in3); - DUP4_ARG2(__lsx_vld, temp_buff, 272, temp_buff, 336, temp_buff, 400, - temp_buff, 464, in4, in5, in6, in7); - DUP4_ARG2(__lsx_vld, temp_buff, 32, temp_buff, 96, temp_buff, 160, temp_buff, - 224, in8, in9, in10, in11); - DUP4_ARG2(__lsx_vld, temp_buff, 288, temp_buff, 352, temp_buff, 416, - temp_buff, 480, in12, in13, in14, in15); - LSX_TRANSPOSE8x8_H(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - LSX_TRANSPOSE8x8_H(in8, in9, in10, in11, in12, in13, in14, in15, in8, in9, - in10, in11, in12, in13, in14, in15); - LSX_BUTTERFLY_16_H(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, - in11, in12, in13, in14, in15, step0, step1, step2, step3, - step4, step5, step6, step7, in8, in9, in10, in11, in12, - in13, in14, in15); - - __lsx_vst(step0, output, 128); - __lsx_vst(step1, output, 144); - __lsx_vst(step2, output, 160); - __lsx_vst(step3, output, 176); - __lsx_vst(step4, output, 192); - __lsx_vst(step5, output, 208); - __lsx_vst(step6, output, 224); - __lsx_vst(step7, output, 240); - - __lsx_vst(in8, output, 256); - __lsx_vst(in9, output, 272); - __lsx_vst(in10, output, 288); - __lsx_vst(in11, output, 304); - __lsx_vst(in12, output, 320); - __lsx_vst(in13, output, 336); - __lsx_vst(in14, output, 352); - __lsx_vst(in15, output, 368); -} - -static void fdct8x32_1d_row_even_4x(int16_t *input, int16_t *interm_ptr, - int16_t *out) { - __m128i in0, in1, in2, in3, in4, in5, in6, in7; - __m128i in8, in9, in10, in11, in12, in13, in14, in15; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - __m128i vec0_l, vec1_l, vec2_l, vec3_l, vec4_l, vec5_l, vec6_l, vec7_l; - __m128i vec0_r, vec1_r, vec2_r, vec3_r, vec4_r, vec5_r, vec6_r, vec7_r; - __m128i tmp0_w, tmp1_w, tmp2_w, tmp3_w; - - /* fdct32 even */ - /* stage 2 */ - DUP4_ARG2(__lsx_vld, input, 0, input, 16, input, 32, input, 48, in0, in1, in2, - in3); - DUP4_ARG2(__lsx_vld, input, 64, input, 80, input, 96, input, 112, in4, in5, - in6, in7); - DUP4_ARG2(__lsx_vld, input, 128, input, 144, input, 160, input, 176, in8, in9, - in10, in11); - DUP4_ARG2(__lsx_vld, input, 192, input, 208, input, 224, input, 240, in12, - in13, in14, in15); - - LSX_BUTTERFLY_16_H(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, - in11, in12, in13, in14, in15, vec0, vec1, vec2, vec3, vec4, - vec5, vec6, vec7, in8, in9, in10, in11, in12, in13, in14, - in15); - - __lsx_vst(vec0, interm_ptr, 0); - __lsx_vst(vec1, interm_ptr, 16); - __lsx_vst(vec2, interm_ptr, 32); - __lsx_vst(vec3, interm_ptr, 48); - __lsx_vst(vec4, interm_ptr, 64); - __lsx_vst(vec5, interm_ptr, 80); - __lsx_vst(vec6, interm_ptr, 96); - __lsx_vst(vec7, interm_ptr, 112); - - __lsx_vst(in8, interm_ptr, 128); - __lsx_vst(in9, interm_ptr, 144); - __lsx_vst(in10, interm_ptr, 160); - __lsx_vst(in11, interm_ptr, 176); - __lsx_vst(in12, interm_ptr, 192); - __lsx_vst(in13, interm_ptr, 208); - __lsx_vst(in14, interm_ptr, 224); - __lsx_vst(in15, interm_ptr, 240); - - /* Stage 3 */ - UNPCK_SH_SW(vec0, vec0_l, vec0_r); - UNPCK_SH_SW(vec1, vec1_l, vec1_r); - UNPCK_SH_SW(vec2, vec2_l, vec2_r); - UNPCK_SH_SW(vec3, vec3_l, vec3_r); - UNPCK_SH_SW(vec4, vec4_l, vec4_r); - UNPCK_SH_SW(vec5, vec5_l, vec5_r); - UNPCK_SH_SW(vec6, vec6_l, vec6_r); - UNPCK_SH_SW(vec7, vec7_l, vec7_r); - DUP4_ARG2(__lsx_vadd_w, vec0_r, vec7_r, vec1_r, vec6_r, vec2_r, vec5_r, - vec3_r, vec4_r, tmp0_w, tmp1_w, tmp2_w, tmp3_w); - LSX_BUTTERFLY_4_W(tmp0_w, tmp1_w, tmp2_w, tmp3_w, vec4_r, vec6_r, vec7_r, - vec5_r); - DUP4_ARG2(__lsx_vadd_w, vec0_l, vec7_l, vec1_l, vec6_l, vec2_l, vec5_l, - vec3_l, vec4_l, vec0_r, vec1_r, vec2_r, vec3_r); - - tmp3_w = __lsx_vadd_w(vec0_r, vec3_r); - vec0_r = __lsx_vsub_w(vec0_r, vec3_r); - vec3_r = __lsx_vadd_w(vec1_r, vec2_r); - vec1_r = __lsx_vsub_w(vec1_r, vec2_r); - - DOTP_CONST_PAIR_W(vec4_r, vec6_r, tmp3_w, vec3_r, cospi_16_64, cospi_16_64, - vec4_r, tmp3_w, vec6_r, vec3_r); - FDCT32_POSTPROC_NEG_W(vec4_r); - FDCT32_POSTPROC_NEG_W(tmp3_w); - FDCT32_POSTPROC_NEG_W(vec6_r); - FDCT32_POSTPROC_NEG_W(vec3_r); - DUP2_ARG2(__lsx_vpickev_h, vec4_r, tmp3_w, vec6_r, vec3_r, vec4, vec5); - __lsx_vst(vec5, out, 0); - __lsx_vst(vec4, out, 16); - - DOTP_CONST_PAIR_W(vec5_r, vec7_r, vec0_r, vec1_r, cospi_24_64, cospi_8_64, - vec4_r, tmp3_w, vec6_r, vec3_r); - FDCT32_POSTPROC_NEG_W(vec4_r); - FDCT32_POSTPROC_NEG_W(tmp3_w); - FDCT32_POSTPROC_NEG_W(vec6_r); - FDCT32_POSTPROC_NEG_W(vec3_r); - DUP2_ARG2(__lsx_vpickev_h, vec4_r, tmp3_w, vec6_r, vec3_r, vec4, vec5); - __lsx_vst(vec5, out, 32); - __lsx_vst(vec4, out, 48); - - DUP4_ARG2(__lsx_vld, interm_ptr, 0, interm_ptr, 16, interm_ptr, 32, - interm_ptr, 48, vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vld, interm_ptr, 64, interm_ptr, 80, interm_ptr, 96, - interm_ptr, 112, vec4, vec5, vec6, vec7); - DUP4_ARG2(__lsx_vsub_h, vec3, vec4, vec2, vec5, vec1, vec6, vec0, vec7, vec4, - vec5, vec6, vec7); - DOTP_CONST_PAIR(vec6, vec5, cospi_16_64, cospi_16_64, vec5, vec6); - DUP2_ARG2(__lsx_vadd_h, vec4, vec5, vec7, vec6, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_28_64, cospi_4_64, in5, in4); - FDCT_POSTPROC_2V_NEG_H(in4, in5); - __lsx_vst(in4, out, 64); - __lsx_vst(in5, out, 112); - - DUP2_ARG2(__lsx_vsub_h, vec4, vec5, vec7, vec6, vec4, vec7); - DOTP_CONST_PAIR(vec7, vec4, cospi_12_64, cospi_20_64, in5, in4); - FDCT_POSTPROC_2V_NEG_H(in4, in5); - __lsx_vst(in4, out, 80); - __lsx_vst(in5, out, 96); - - DUP4_ARG2(__lsx_vld, interm_ptr, 128, interm_ptr, 144, interm_ptr, 160, - interm_ptr, 176, in8, in9, in10, in11); - DUP4_ARG2(__lsx_vld, interm_ptr, 192, interm_ptr, 208, interm_ptr, 224, - interm_ptr, 240, in12, in13, in14, in15); - DOTP_CONST_PAIR(in13, in10, cospi_16_64, cospi_16_64, vec2, vec5); - DOTP_CONST_PAIR(in12, in11, cospi_16_64, cospi_16_64, vec3, vec4); - DUP4_ARG2(__lsx_vadd_h, in8, vec3, in9, vec2, in14, vec5, in15, vec4, in0, - vec1, vec6, in2); - DOTP_CONST_PAIR(vec6, vec1, cospi_24_64, cospi_8_64, in1, in3); - DUP2_ARG2(__lsx_vadd_h, in0, in1, in2, in3, vec0, vec7); - DOTP_CONST_PAIR(vec7, vec0, cospi_30_64, cospi_2_64, in5, in4); - FDCT_POSTPROC_2V_NEG_H(in4, in5); - __lsx_vst(in4, out, 128); - __lsx_vst(in5, out, 240); - - DUP2_ARG2(__lsx_vsub_h, in0, in1, in2, in3, in0, in2); - DOTP_CONST_PAIR(in2, in0, cospi_14_64, cospi_18_64, in5, in4); - FDCT_POSTPROC_2V_NEG_H(in4, in5); - __lsx_vst(in4, out, 144); - __lsx_vst(in5, out, 224); - - DUP2_ARG2(__lsx_vsub_h, in9, vec2, in14, vec5, vec2, vec5); - tmp0_w = __lsx_vneg_h(vec2); - DOTP_CONST_PAIR(tmp0_w, vec5, cospi_24_64, cospi_8_64, in2, in1); - DUP4_ARG2(__lsx_vsub_h, in8, vec3, in15, vec4, in3, in2, in0, in1, in3, in0, - vec2, vec5); - DOTP_CONST_PAIR(vec5, vec2, cospi_22_64, cospi_10_64, in5, in4); - FDCT_POSTPROC_2V_NEG_H(in4, in5); - __lsx_vst(in4, out, 160); - __lsx_vst(in5, out, 208); - - DUP2_ARG2(__lsx_vadd_h, in3, in2, in0, in1, vec3, vec4); - DOTP_CONST_PAIR(vec4, vec3, cospi_6_64, cospi_26_64, in4, in5); - FDCT_POSTPROC_2V_NEG_H(in4, in5); - __lsx_vst(in4, out, 192); - __lsx_vst(in5, out, 176); -} - -static void fdct8x32_1d_row_even(int16_t *temp, int16_t *out) { - __m128i in0, in1, in2, in3, in4, in5, in6, in7; - __m128i in8, in9, in10, in11, in12, in13, in14, in15; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, temp0, temp1; - - /* fdct32 even */ - /* stage 2 */ - DUP4_ARG2(__lsx_vld, temp, 0, temp, 16, temp, 32, temp, 48, in0, in1, in2, - in3); - DUP4_ARG2(__lsx_vld, temp, 64, temp, 80, temp, 96, temp, 112, in4, in5, in6, - in7); - DUP4_ARG2(__lsx_vld, temp, 128, temp, 144, temp, 160, temp, 176, in8, in9, - in10, in11); - DUP4_ARG2(__lsx_vld, temp, 192, temp, 208, temp, 224, temp, 240, in12, in13, - in14, in15); - - LSX_BUTTERFLY_16_H(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, - in11, in12, in13, in14, in15, vec0, vec1, vec2, vec3, vec4, - vec5, vec6, vec7, in8, in9, in10, in11, in12, in13, in14, - in15); - /* Stage 3 */ - DUP4_ARG2(__lsx_vadd_h, vec0, vec7, vec1, vec6, vec2, vec5, vec3, vec4, in0, - in1, in2, in3); - LSX_BUTTERFLY_4_H(in0, in1, in2, in3, temp0, in4, in1, in0); - DOTP_CONST_PAIR(temp0, in4, cospi_16_64, cospi_16_64, temp1, temp0); - FDCT_POSTPROC_2V_NEG_H(temp0, temp1); - __lsx_vst(temp0, out, 0); - __lsx_vst(temp1, out, 16); - - DOTP_CONST_PAIR(in0, in1, cospi_24_64, cospi_8_64, temp1, temp0); - FDCT_POSTPROC_2V_NEG_H(temp0, temp1); - __lsx_vst(temp0, out, 32); - __lsx_vst(temp1, out, 48); - - DUP4_ARG2(__lsx_vsub_h, vec3, vec4, vec2, vec5, vec1, vec6, vec0, vec7, vec4, - vec5, vec6, vec7); - DOTP_CONST_PAIR(vec6, vec5, cospi_16_64, cospi_16_64, vec5, vec6); - DUP2_ARG2(__lsx_vadd_h, vec4, vec5, vec7, vec6, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_28_64, cospi_4_64, temp1, temp0); - FDCT_POSTPROC_2V_NEG_H(temp0, temp1); - __lsx_vst(temp0, out, 64); - __lsx_vst(temp1, out, 112); - - DUP2_ARG2(__lsx_vsub_h, vec4, vec5, vec7, vec6, vec4, vec7); - DOTP_CONST_PAIR(vec7, vec4, cospi_12_64, cospi_20_64, temp1, temp0); - FDCT_POSTPROC_2V_NEG_H(temp0, temp1); - __lsx_vst(temp0, out, 80); - __lsx_vst(temp1, out, 96); - - DOTP_CONST_PAIR(in13, in10, cospi_16_64, cospi_16_64, vec2, vec5); - DOTP_CONST_PAIR(in12, in11, cospi_16_64, cospi_16_64, vec3, vec4); - DUP4_ARG2(__lsx_vadd_h, in8, vec3, in9, vec2, in14, vec5, in15, vec4, in0, - vec1, vec6, in2); - DOTP_CONST_PAIR(vec6, vec1, cospi_24_64, cospi_8_64, in1, in3); - DUP2_ARG2(__lsx_vadd_h, in0, in1, in2, in3, vec0, vec7); - DOTP_CONST_PAIR(vec7, vec0, cospi_30_64, cospi_2_64, temp1, temp0); - FDCT_POSTPROC_2V_NEG_H(temp0, temp1); - __lsx_vst(temp0, out, 128); - __lsx_vst(temp1, out, 240); - - DUP2_ARG2(__lsx_vsub_h, in0, in1, in2, in3, in0, in2); - DOTP_CONST_PAIR(in2, in0, cospi_14_64, cospi_18_64, temp1, temp0); - FDCT_POSTPROC_2V_NEG_H(temp0, temp1); - __lsx_vst(temp0, out, 144); - __lsx_vst(temp1, out, 224); - - DUP2_ARG2(__lsx_vsub_h, in9, vec2, in14, vec5, vec2, vec5); - temp0 = __lsx_vneg_h(vec2); - DOTP_CONST_PAIR(temp0, vec5, cospi_24_64, cospi_8_64, in2, in1); - DUP4_ARG2(__lsx_vsub_h, in8, vec3, in15, vec4, in3, in2, in0, in1, in3, in0, - vec2, vec5) - DOTP_CONST_PAIR(vec5, vec2, cospi_22_64, cospi_10_64, temp1, temp0); - FDCT_POSTPROC_2V_NEG_H(temp0, temp1); - __lsx_vst(temp0, out, 160); - __lsx_vst(temp1, out, 208); - - DUP2_ARG2(__lsx_vadd_h, in3, in2, in0, in1, vec3, vec4); - DOTP_CONST_PAIR(vec4, vec3, cospi_6_64, cospi_26_64, temp0, temp1); - FDCT_POSTPROC_2V_NEG_H(temp0, temp1); - __lsx_vst(temp0, out, 192); - __lsx_vst(temp1, out, 176); -} - -static void fdct8x32_1d_row_odd(int16_t *temp, int16_t *interm_ptr, - int16_t *out) { - __m128i in16, in17, in18, in19, in20, in21, in22, in23; - __m128i in24, in25, in26, in27, in28, in29, in30, in31, vec4, vec5; - __m128i tmp0, tmp1; - - in20 = __lsx_vld(temp, 64); - in21 = __lsx_vld(temp, 80); - in26 = __lsx_vld(temp, 160); - in27 = __lsx_vld(temp, 176); - - DOTP_CONST_PAIR(in27, in20, cospi_16_64, cospi_16_64, in20, in27); - DOTP_CONST_PAIR(in26, in21, cospi_16_64, cospi_16_64, in21, in26); - - in18 = __lsx_vld(temp, 32); - in19 = __lsx_vld(temp, 48); - in28 = __lsx_vld(temp, 192); - in29 = __lsx_vld(temp, 208); - - vec4 = __lsx_vsub_h(in19, in20); - __lsx_vst(vec4, interm_ptr, 64); - vec4 = __lsx_vsub_h(in18, in21); - __lsx_vst(vec4, interm_ptr, 176); - vec4 = __lsx_vsub_h(in28, in27); - __lsx_vst(vec4, interm_ptr, 112); - vec4 = __lsx_vsub_h(in29, in26); - __lsx_vst(vec4, interm_ptr, 128); - - DUP4_ARG2(__lsx_vadd_h, in18, in21, in19, in20, in28, in27, in29, in26, in21, - in20, in27, in26); - - in22 = __lsx_vld(temp, 96); - in23 = __lsx_vld(temp, 112); - in24 = __lsx_vld(temp, 128); - in25 = __lsx_vld(temp, 144); - - DOTP_CONST_PAIR(in25, in22, cospi_16_64, cospi_16_64, in22, in25); - DOTP_CONST_PAIR(in24, in23, cospi_16_64, cospi_16_64, in23, in24); - - in16 = __lsx_vld(temp, 0); - in17 = __lsx_vld(temp, 16); - in30 = __lsx_vld(temp, 224); - in31 = __lsx_vld(temp, 240); - - vec4 = __lsx_vsub_h(in17, in22); - __lsx_vst(vec4, interm_ptr, 80); - vec4 = __lsx_vsub_h(in30, in25); - __lsx_vst(vec4, interm_ptr, 96); - vec4 = __lsx_vsub_h(in31, in24); - __lsx_vst(vec4, interm_ptr, 144); - vec4 = __lsx_vsub_h(in16, in23); - __lsx_vst(vec4, interm_ptr, 160); - - DUP4_ARG2(__lsx_vadd_h, in16, in23, in17, in22, in30, in25, in31, in24, in16, - in17, in30, in31); - DOTP_CONST_PAIR(in26, in21, cospi_24_64, cospi_8_64, in18, in29); - DOTP_CONST_PAIR(in27, in20, cospi_24_64, cospi_8_64, in19, in28); - - DUP4_ARG2(__lsx_vadd_h, in16, in19, in17, in18, in30, in29, in31, in28, in27, - in22, in21, in25); - DOTP_CONST_PAIR(in21, in22, cospi_28_64, cospi_4_64, in26, in24); - DUP2_ARG2(__lsx_vadd_h, in27, in26, in25, in24, in23, in20); - - DOTP_CONST_PAIR(in20, in23, cospi_31_64, cospi_1_64, vec4, vec5); - FDCT_POSTPROC_2V_NEG_H(vec5, vec4); - __lsx_vst(vec5, out, 0); - __lsx_vst(vec4, out, 240); - - DUP2_ARG2(__lsx_vsub_h, in27, in26, in25, in24, in22, in21); - - DOTP_CONST_PAIR(in21, in22, cospi_15_64, cospi_17_64, vec5, vec4); - FDCT_POSTPROC_2V_NEG_H(vec5, vec4); - __lsx_vst(vec5, out, 224); - __lsx_vst(vec4, out, 16); - - DUP4_ARG2(__lsx_vsub_h, in17, in18, in16, in19, in31, in28, in30, in29, in23, - in26, in24, in20); - tmp0 = __lsx_vneg_h(in23); - DOTP_CONST_PAIR(tmp0, in20, cospi_28_64, cospi_4_64, in27, in25); - DUP2_ARG2(__lsx_vsub_h, in26, in27, in24, in25, in23, in20); - - DOTP_CONST_PAIR(in20, in23, cospi_23_64, cospi_9_64, vec4, vec5); - FDCT_POSTPROC_2V_NEG_H(vec5, vec4); - __lsx_vst(vec4, out, 32); - __lsx_vst(vec5, out, 208); - - DUP2_ARG2(__lsx_vadd_h, in26, in27, in24, in25, in22, in21); - DOTP_CONST_PAIR(in21, in22, cospi_7_64, cospi_25_64, vec4, vec5); - FDCT_POSTPROC_2V_NEG_H(vec5, vec4); - __lsx_vst(vec4, out, 48); - __lsx_vst(vec5, out, 192); - - in20 = __lsx_vld(interm_ptr, 64); - in21 = __lsx_vld(interm_ptr, 176); - in27 = __lsx_vld(interm_ptr, 112); - in26 = __lsx_vld(interm_ptr, 128); - - in16 = in20; - in17 = in21; - DUP2_ARG1(__lsx_vneg_h, in16, in17, tmp0, tmp1); - DOTP_CONST_PAIR(tmp0, in27, cospi_24_64, cospi_8_64, in20, in27); - DOTP_CONST_PAIR(tmp1, in26, cospi_24_64, cospi_8_64, in21, in26); - - in22 = __lsx_vld(interm_ptr, 80); - in25 = __lsx_vld(interm_ptr, 96); - in24 = __lsx_vld(interm_ptr, 144); - in23 = __lsx_vld(interm_ptr, 160); - - DUP4_ARG2(__lsx_vsub_h, in23, in20, in22, in21, in25, in26, in24, in27, in28, - in17, in18, in31); - DOTP_CONST_PAIR(in18, in17, cospi_12_64, cospi_20_64, in29, in30); - DUP2_ARG2(__lsx_vadd_h, in28, in29, in31, in30, in16, in19); - DOTP_CONST_PAIR(in19, in16, cospi_27_64, cospi_5_64, vec5, vec4); - FDCT_POSTPROC_2V_NEG_H(vec5, vec4); - __lsx_vst(vec5, out, 64); - __lsx_vst(vec4, out, 176); - - DUP2_ARG2(__lsx_vsub_h, in28, in29, in31, in30, in17, in18); - DOTP_CONST_PAIR(in18, in17, cospi_11_64, cospi_21_64, vec5, vec4); - FDCT_POSTPROC_2V_NEG_H(vec5, vec4); - __lsx_vst(vec5, out, 80); - __lsx_vst(vec4, out, 160); - - DUP4_ARG2(__lsx_vadd_h, in22, in21, in23, in20, in24, in27, in25, in26, in16, - in29, in30, in19); - tmp0 = __lsx_vneg_h(in16); - DOTP_CONST_PAIR(tmp0, in19, cospi_12_64, cospi_20_64, in28, in31); - DUP2_ARG2(__lsx_vsub_h, in29, in28, in30, in31, in16, in19); - - DOTP_CONST_PAIR(in19, in16, cospi_19_64, cospi_13_64, vec5, vec4); - FDCT_POSTPROC_2V_NEG_H(vec5, vec4); - __lsx_vst(vec5, out, 144); - __lsx_vst(vec4, out, 96); - - DUP2_ARG2(__lsx_vadd_h, in29, in28, in30, in31, in17, in18); - - DOTP_CONST_PAIR(in18, in17, cospi_3_64, cospi_29_64, vec5, vec4); - FDCT_POSTPROC_2V_NEG_H(vec5, vec4); - __lsx_vst(vec4, out, 112); - __lsx_vst(vec5, out, 128); -} - -static void fdct8x32_1d_row_transpose_store(int16_t *temp, int16_t *output) { - __m128i in0, in1, in2, in3, in4, in5, in6, in7; - __m128i in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1; - - /* 1st set */ - in0 = __lsx_vld(temp, 0); - in4 = __lsx_vld(temp, 64); - in2 = __lsx_vld(temp, 128); - in6 = __lsx_vld(temp, 192); - in1 = __lsx_vld(temp, 256); - in7 = __lsx_vld(temp, 304); - in3 = __lsx_vld(temp, 384); - in5 = __lsx_vld(temp, 432); - - LSX_TRANSPOSE8x8_H(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - - /* 2nd set */ - in0_1 = __lsx_vld(temp, 32); - in1_1 = __lsx_vld(temp, 464); - in2_1 = __lsx_vld(temp, 160); - in3_1 = __lsx_vld(temp, 336); - in4_1 = __lsx_vld(temp, 96); - in5_1 = __lsx_vld(temp, 352); - in6_1 = __lsx_vld(temp, 224); - in7_1 = __lsx_vld(temp, 480); - - __lsx_vst(in0, output, 0); - __lsx_vst(in1, output, 64); - __lsx_vst(in2, output, 128); - __lsx_vst(in3, output, 192); - __lsx_vst(in4, output, 256); - __lsx_vst(in5, output, 320); - __lsx_vst(in6, output, 384); - __lsx_vst(in7, output, 448); - - LSX_TRANSPOSE8x8_H(in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1, - in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1); - - /* 3rd set */ - in0 = __lsx_vld(temp, 16); - in1 = __lsx_vld(temp, 272); - in2 = __lsx_vld(temp, 144); - in3 = __lsx_vld(temp, 400); - in4 = __lsx_vld(temp, 80); - in5 = __lsx_vld(temp, 416); - in6 = __lsx_vld(temp, 208); - in7 = __lsx_vld(temp, 288); - - __lsx_vst(in0_1, output, 16); - __lsx_vst(in1_1, output, 80); - __lsx_vst(in2_1, output, 144); - __lsx_vst(in3_1, output, 208); - __lsx_vst(in4_1, output, 272); - __lsx_vst(in5_1, output, 336); - __lsx_vst(in6_1, output, 400); - __lsx_vst(in7_1, output, 464); - - LSX_TRANSPOSE8x8_H(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - - __lsx_vst(in0, output, 32); - __lsx_vst(in1, output, 96); - __lsx_vst(in2, output, 160); - __lsx_vst(in3, output, 224); - __lsx_vst(in4, output, 288); - __lsx_vst(in5, output, 352); - __lsx_vst(in6, output, 416); - __lsx_vst(in7, output, 480); - - /* 4th set */ - in0_1 = __lsx_vld(temp, 48); - in1_1 = __lsx_vld(temp, 448); - in2_1 = __lsx_vld(temp, 176); - in3_1 = __lsx_vld(temp, 320); - in4_1 = __lsx_vld(temp, 112); - in5_1 = __lsx_vld(temp, 368); - in6_1 = __lsx_vld(temp, 240); - in7_1 = __lsx_vld(temp, 496); - - LSX_TRANSPOSE8x8_H(in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1, - in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1); - - __lsx_vst(in0_1, output, 48); - __lsx_vst(in1_1, output, 112); - __lsx_vst(in2_1, output, 176); - __lsx_vst(in3_1, output, 240); - __lsx_vst(in4_1, output, 304); - __lsx_vst(in5_1, output, 368); - __lsx_vst(in6_1, output, 432); - __lsx_vst(in7_1, output, 496); -} - -static void fdct32x8_1d_row(int16_t *temp, int16_t *temp_buf, int16_t *output) { - fdct8x32_1d_row_load_butterfly(temp, temp_buf); - fdct8x32_1d_row_even(temp_buf, temp_buf); - fdct8x32_1d_row_odd(temp_buf + 128, temp, temp_buf + 128); - fdct8x32_1d_row_transpose_store(temp_buf, output); -} - -static void fdct32x8_1d_row_4x(int16_t *tmp_buf_big, int16_t *tmp_buf, - int16_t *output) { - fdct8x32_1d_row_load_butterfly(tmp_buf_big, tmp_buf); - fdct8x32_1d_row_even_4x(tmp_buf, tmp_buf_big, tmp_buf); - fdct8x32_1d_row_odd(tmp_buf + 128, tmp_buf_big, tmp_buf + 128); - fdct8x32_1d_row_transpose_store(tmp_buf, output); -} - -void vpx_fdct32x32_lsx(const int16_t *input, int16_t *output, - int32_t src_stride) { - int i; - DECLARE_ALIGNED(32, int16_t, tmp_buf_big[1024]); - DECLARE_ALIGNED(32, int16_t, tmp_buf[256]); - - /* column transform */ - for (i = 0; i < 4; ++i) { - fdct8x32_1d_column(input + (8 * i), src_stride, tmp_buf, - tmp_buf_big + (8 * i)); - } - - /* row transform */ - fdct32x8_1d_row_4x(tmp_buf_big, tmp_buf, output); - - /* row transform */ - for (i = 1; i < 4; ++i) { - fdct32x8_1d_row(tmp_buf_big + (i * 256), tmp_buf, output + (i * 256)); - } -} - -static void fdct8x32_1d_row_even_rd(int16_t *temp, int16_t *out) { - __m128i in0, in1, in2, in3, in4, in5, in6, in7; - __m128i in8, in9, in10, in11, in12, in13, in14, in15; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, temp0, temp1; - - /* fdct32 even */ - /* stage 2 */ - DUP4_ARG2(__lsx_vld, temp, 0, temp, 16, temp, 32, temp, 48, in0, in1, in2, - in3); - DUP4_ARG2(__lsx_vld, temp, 64, temp, 80, temp, 96, temp, 112, in4, in5, in6, - in7); - DUP4_ARG2(__lsx_vld, temp, 128, temp, 144, temp, 160, temp, 176, in8, in9, - in10, in11); - DUP4_ARG2(__lsx_vld, temp, 192, temp, 208, temp, 224, temp, 240, in12, in13, - in14, in15); - LSX_BUTTERFLY_16_H(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, - in11, in12, in13, in14, in15, vec0, vec1, vec2, vec3, vec4, - vec5, vec6, vec7, in8, in9, in10, in11, in12, in13, in14, - in15); - - FDCT_POSTPROC_2V_NEG_H(vec0, vec1); - FDCT_POSTPROC_2V_NEG_H(vec2, vec3); - FDCT_POSTPROC_2V_NEG_H(vec4, vec5); - FDCT_POSTPROC_2V_NEG_H(vec6, vec7); - FDCT_POSTPROC_2V_NEG_H(in8, in9); - FDCT_POSTPROC_2V_NEG_H(in10, in11); - FDCT_POSTPROC_2V_NEG_H(in12, in13); - FDCT_POSTPROC_2V_NEG_H(in14, in15); - - /* Stage 3 */ - DUP4_ARG2(__lsx_vadd_h, vec0, vec7, vec1, vec6, vec2, vec5, vec3, vec4, in0, - in1, in2, in3); - - temp0 = __lsx_vadd_h(in0, in3); - in0 = __lsx_vsub_h(in0, in3); - in3 = __lsx_vadd_h(in1, in2); - in1 = __lsx_vsub_h(in1, in2); - - DOTP_CONST_PAIR(temp0, in3, cospi_16_64, cospi_16_64, temp1, temp0); - __lsx_vst(temp0, out, 0); - __lsx_vst(temp1, out, 16); - - DOTP_CONST_PAIR(in0, in1, cospi_24_64, cospi_8_64, temp1, temp0); - __lsx_vst(temp0, out, 32); - __lsx_vst(temp1, out, 48); - - DUP4_ARG2(__lsx_vsub_h, vec3, vec4, vec2, vec5, vec1, vec6, vec0, vec7, vec4, - vec5, vec6, vec7); - DOTP_CONST_PAIR(vec6, vec5, cospi_16_64, cospi_16_64, vec5, vec6); - DUP2_ARG2(__lsx_vadd_h, vec4, vec5, vec7, vec6, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_28_64, cospi_4_64, temp1, temp0); - __lsx_vst(temp0, out, 64); - __lsx_vst(temp1, out, 112); - - DUP2_ARG2(__lsx_vsub_h, vec4, vec5, vec7, vec6, vec4, vec7); - DOTP_CONST_PAIR(vec7, vec4, cospi_12_64, cospi_20_64, temp1, temp0); - __lsx_vst(temp0, out, 80); - __lsx_vst(temp1, out, 96); - - DOTP_CONST_PAIR(in13, in10, cospi_16_64, cospi_16_64, vec2, vec5); - DOTP_CONST_PAIR(in12, in11, cospi_16_64, cospi_16_64, vec3, vec4); - DUP4_ARG2(__lsx_vadd_h, in8, vec3, in9, vec2, in14, vec5, in15, vec4, in0, - vec1, vec6, in2); - DOTP_CONST_PAIR(vec6, vec1, cospi_24_64, cospi_8_64, in1, in3); - DUP2_ARG2(__lsx_vadd_h, in0, in1, in2, in3, vec0, vec7); - DOTP_CONST_PAIR(vec7, vec0, cospi_30_64, cospi_2_64, temp1, temp0); - __lsx_vst(temp0, out, 128); - __lsx_vst(temp1, out, 240); - - DUP2_ARG2(__lsx_vsub_h, in0, in1, in2, in3, in0, in2); - DOTP_CONST_PAIR(in2, in0, cospi_14_64, cospi_18_64, temp1, temp0); - __lsx_vst(temp0, out, 144); - __lsx_vst(temp1, out, 224); - - DUP2_ARG2(__lsx_vsub_h, in9, vec2, in14, vec5, vec2, vec5); - temp0 = __lsx_vneg_h(vec2); - DOTP_CONST_PAIR(temp0, vec5, cospi_24_64, cospi_8_64, in2, in1); - DUP4_ARG2(__lsx_vsub_h, in8, vec3, in15, vec4, in3, in2, in0, in1, in3, in0, - vec2, vec5); - DOTP_CONST_PAIR(vec5, vec2, cospi_22_64, cospi_10_64, temp1, temp0); - __lsx_vst(temp0, out, 160); - __lsx_vst(temp1, out, 208); - - DUP2_ARG2(__lsx_vadd_h, in3, in2, in0, in1, vec3, vec4); - DOTP_CONST_PAIR(vec4, vec3, cospi_6_64, cospi_26_64, temp0, temp1); - __lsx_vst(temp0, out, 192); - __lsx_vst(temp1, out, 176); -} - -static void fdct8x32_1d_row_odd_rd(int16_t *temp, int16_t *interm_ptr, - int16_t *out) { - __m128i in16, in17, in18, in19, in20, in21, in22, in23; - __m128i in24, in25, in26, in27, in28, in29, in30, in31; - __m128i vec4, vec5, tmp0, tmp1; - - in20 = __lsx_vld(temp, 64); - in21 = __lsx_vld(temp, 80); - in26 = __lsx_vld(temp, 160); - in27 = __lsx_vld(temp, 176); - - DOTP_CONST_PAIR(in27, in20, cospi_16_64, cospi_16_64, in20, in27); - DOTP_CONST_PAIR(in26, in21, cospi_16_64, cospi_16_64, in21, in26); - - FDCT_POSTPROC_2V_NEG_H(in20, in21); - FDCT_POSTPROC_2V_NEG_H(in26, in27); - - in18 = __lsx_vld(temp, 32); - in19 = __lsx_vld(temp, 48); - in28 = __lsx_vld(temp, 192); - in29 = __lsx_vld(temp, 208); - - FDCT_POSTPROC_2V_NEG_H(in18, in19); - FDCT_POSTPROC_2V_NEG_H(in28, in29); - - vec4 = __lsx_vsub_h(in19, in20); - __lsx_vst(vec4, interm_ptr, 64); - vec4 = __lsx_vsub_h(in18, in21); - __lsx_vst(vec4, interm_ptr, 176); - vec4 = __lsx_vsub_h(in29, in26); - __lsx_vst(vec4, interm_ptr, 128); - vec4 = __lsx_vsub_h(in28, in27); - __lsx_vst(vec4, interm_ptr, 112); - - DUP4_ARG2(__lsx_vadd_h, in18, in21, in19, in20, in28, in27, in29, in26, in21, - in20, in27, in26); - - in22 = __lsx_vld(temp, 96); - in23 = __lsx_vld(temp, 112); - in24 = __lsx_vld(temp, 128); - in25 = __lsx_vld(temp, 144); - - DOTP_CONST_PAIR(in25, in22, cospi_16_64, cospi_16_64, in22, in25); - DOTP_CONST_PAIR(in24, in23, cospi_16_64, cospi_16_64, in23, in24); - FDCT_POSTPROC_2V_NEG_H(in22, in23); - FDCT_POSTPROC_2V_NEG_H(in24, in25); - - in16 = __lsx_vld(temp, 0); - in17 = __lsx_vld(temp, 16); - in30 = __lsx_vld(temp, 224); - in31 = __lsx_vld(temp, 240); - - FDCT_POSTPROC_2V_NEG_H(in16, in17); - FDCT_POSTPROC_2V_NEG_H(in30, in31); - - vec4 = __lsx_vsub_h(in17, in22); - __lsx_vst(vec4, interm_ptr, 80); - vec4 = __lsx_vsub_h(in30, in25); - __lsx_vst(vec4, interm_ptr, 96); - vec4 = __lsx_vsub_h(in31, in24); - __lsx_vst(vec4, interm_ptr, 144); - vec4 = __lsx_vsub_h(in16, in23); - __lsx_vst(vec4, interm_ptr, 160); - - DUP4_ARG2(__lsx_vadd_h, in16, in23, in17, in22, in30, in25, in31, in24, in16, - in17, in30, in31); - DOTP_CONST_PAIR(in26, in21, cospi_24_64, cospi_8_64, in18, in29); - DOTP_CONST_PAIR(in27, in20, cospi_24_64, cospi_8_64, in19, in28); - DUP4_ARG2(__lsx_vadd_h, in16, in19, in17, in18, in30, in29, in31, in28, in27, - in22, in21, in25); - DOTP_CONST_PAIR(in21, in22, cospi_28_64, cospi_4_64, in26, in24); - DUP2_ARG2(__lsx_vadd_h, in27, in26, in25, in24, in23, in20); - DOTP_CONST_PAIR(in20, in23, cospi_31_64, cospi_1_64, vec4, vec5); - __lsx_vst(vec5, out, 0); - __lsx_vst(vec4, out, 240); - - DUP2_ARG2(__lsx_vsub_h, in27, in26, in25, in24, in22, in21); - DOTP_CONST_PAIR(in21, in22, cospi_15_64, cospi_17_64, vec5, vec4); - __lsx_vst(vec5, out, 224); - __lsx_vst(vec4, out, 16); - - DUP4_ARG2(__lsx_vsub_h, in17, in18, in16, in19, in31, in28, in30, in29, in23, - in26, in24, in20); - tmp0 = __lsx_vneg_h(in23); - DOTP_CONST_PAIR(tmp0, in20, cospi_28_64, cospi_4_64, in27, in25); - DUP2_ARG2(__lsx_vsub_h, in26, in27, in24, in25, in23, in20); - DOTP_CONST_PAIR(in20, in23, cospi_23_64, cospi_9_64, vec4, vec5); - __lsx_vst(vec4, out, 32); - __lsx_vst(vec5, out, 208); - - DUP2_ARG2(__lsx_vadd_h, in26, in27, in24, in25, in22, in21); - DOTP_CONST_PAIR(in21, in22, cospi_7_64, cospi_25_64, vec4, vec5); - __lsx_vst(vec4, out, 48); - __lsx_vst(vec5, out, 192); - - in20 = __lsx_vld(interm_ptr, 64); - in21 = __lsx_vld(interm_ptr, 176); - in27 = __lsx_vld(interm_ptr, 112); - in26 = __lsx_vld(interm_ptr, 128); - - in16 = in20; - in17 = in21; - DUP2_ARG1(__lsx_vneg_h, in16, in17, tmp0, tmp1); - DOTP_CONST_PAIR(tmp0, in27, cospi_24_64, cospi_8_64, in20, in27); - DOTP_CONST_PAIR(tmp1, in26, cospi_24_64, cospi_8_64, in21, in26); - - in22 = __lsx_vld(interm_ptr, 80); - in25 = __lsx_vld(interm_ptr, 96); - in24 = __lsx_vld(interm_ptr, 144); - in23 = __lsx_vld(interm_ptr, 160); - - DUP4_ARG2(__lsx_vsub_h, in23, in20, in22, in21, in25, in26, in24, in27, in28, - in17, in18, in31); - DOTP_CONST_PAIR(in18, in17, cospi_12_64, cospi_20_64, in29, in30); - in16 = __lsx_vadd_h(in28, in29); - in19 = __lsx_vadd_h(in31, in30); - DOTP_CONST_PAIR(in19, in16, cospi_27_64, cospi_5_64, vec5, vec4); - __lsx_vst(vec5, out, 64); - __lsx_vst(vec4, out, 176); - - DUP2_ARG2(__lsx_vsub_h, in28, in29, in31, in30, in17, in18); - DOTP_CONST_PAIR(in18, in17, cospi_11_64, cospi_21_64, vec5, vec4); - __lsx_vst(vec5, out, 80); - __lsx_vst(vec4, out, 160); - - DUP4_ARG2(__lsx_vadd_h, in22, in21, in23, in20, in24, in27, in25, in26, in16, - in29, in30, in19); - tmp0 = __lsx_vneg_h(in16); - DOTP_CONST_PAIR(tmp0, in19, cospi_12_64, cospi_20_64, in28, in31); - DUP2_ARG2(__lsx_vsub_h, in29, in28, in30, in31, in16, in19); - DOTP_CONST_PAIR(in19, in16, cospi_19_64, cospi_13_64, vec5, vec4); - __lsx_vst(vec5, out, 144); - __lsx_vst(vec4, out, 96); - - DUP2_ARG2(__lsx_vadd_h, in29, in28, in30, in31, in17, in18); - DOTP_CONST_PAIR(in18, in17, cospi_3_64, cospi_29_64, vec5, vec4); - __lsx_vst(vec4, out, 112); - __lsx_vst(vec5, out, 128); -} - -static void fdct32x8_1d_row_rd(int16_t *tmp_buf_big, int16_t *tmp_buf, - int16_t *output) { - fdct8x32_1d_row_load_butterfly(tmp_buf_big, tmp_buf); - fdct8x32_1d_row_even_rd(tmp_buf, tmp_buf); - fdct8x32_1d_row_odd_rd((tmp_buf + 128), tmp_buf_big, (tmp_buf + 128)); - fdct8x32_1d_row_transpose_store(tmp_buf, output); -} - -void vpx_fdct32x32_rd_lsx(const int16_t *input, int16_t *out, - int32_t src_stride) { - int32_t i; - DECLARE_ALIGNED(32, int16_t, tmp_buf_big[1024]); - DECLARE_ALIGNED(32, int16_t, tmp_buf[256]); - - /* column transform */ - for (i = 0; i < 4; ++i) { - fdct8x32_1d_column(input + (8 * i), src_stride, &tmp_buf[0], - &tmp_buf_big[0] + (8 * i)); - } - /* row transform */ - for (i = 0; i < 4; ++i) { - fdct32x8_1d_row_rd(&tmp_buf_big[0] + (8 * i * 32), &tmp_buf[0], - out + (8 * i * 32)); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/fwd_txfm_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/fwd_txfm_lsx.c deleted file mode 100644 index 508532b9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/fwd_txfm_lsx.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/loongarch/fwd_txfm_lsx.h" - -#define LSX_TRANSPOSE4x4_H(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ - do { \ - __m128i _s0, _s1, _s2, _s3, _t0, _t1, _t2, _t3; \ - \ - DUP2_ARG2(__lsx_vilvl_h, _in2, _in0, _in3, _in1, _s0, _s1); \ - DUP2_ARG2(__lsx_vilvh_h, _in2, _in0, _in3, _in1, _s2, _s3); \ - _t0 = __lsx_vilvl_h(_s1, _s0); \ - _t1 = __lsx_vilvh_h(_s1, _s0); \ - _t2 = __lsx_vilvl_h(_s3, _s2); \ - _t3 = __lsx_vilvh_h(_s3, _s2); \ - DUP2_ARG2(__lsx_vpickev_d, _t2, _t0, _t3, _t1, _out0, _out2); \ - DUP2_ARG2(__lsx_vpickod_d, _t2, _t0, _t3, _t1, _out1, _out3); \ - } while (0) - -#if !CONFIG_VP9_HIGHBITDEPTH -void fdct8x16_1d_column(const int16_t *input, int16_t *tmp_ptr, - int32_t src_stride) { - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - __m128i in0, in1, in2, in3, in4, in5, in6, in7; - __m128i in8, in9, in10, in11, in12, in13, in14, in15; - __m128i stp21, stp22, stp23, stp24, stp25, stp26, stp30; - __m128i stp31, stp32, stp33, stp34, stp35, stp36, stp37; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, cnst0, cnst1, cnst4, cnst5; - __m128i coeff = { 0x187e3b21d2bf2d41, 0x238e3537e782c4df }; - __m128i coeff1 = { 0x289a317906463fb1, 0x12943d3f1e2b3871 }; - __m128i coeff2 = { 0xed6cd766c78fc04f, 0x0 }; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride4 = src_stride2 << 1; - int32_t src_stride6 = src_stride4 + src_stride2; - int32_t src_stride8 = src_stride4 << 1; - int16_t *input_tmp = (int16_t *)input; - in0 = __lsx_vld(input_tmp, 0); - DUP4_ARG2(__lsx_vldx, input_tmp, src_stride2, input_tmp, src_stride4, - input_tmp, src_stride6, input_tmp, src_stride8, in1, in2, in3, in4); - input_tmp += src_stride4; - DUP4_ARG2(__lsx_vldx, input_tmp, src_stride2, input_tmp, src_stride4, - input_tmp, src_stride6, input_tmp, src_stride8, in5, in6, in7, in8); - input_tmp += src_stride4; - DUP4_ARG2(__lsx_vldx, input_tmp, src_stride2, input_tmp, src_stride4, - input_tmp, src_stride6, input_tmp, src_stride8, in9, in10, in11, - in12); - input_tmp += src_stride4; - DUP2_ARG2(__lsx_vldx, input_tmp, src_stride2, input_tmp, src_stride4, in13, - in14); - input_tmp += src_stride2; - in15 = __lsx_vldx(input_tmp, src_stride2); - - DUP4_ARG2(__lsx_vslli_h, in0, 2, in1, 2, in2, 2, in3, 2, in0, in1, in2, in3); - DUP4_ARG2(__lsx_vslli_h, in4, 2, in5, 2, in6, 2, in7, 2, in4, in5, in6, in7); - DUP4_ARG2(__lsx_vslli_h, in8, 2, in9, 2, in10, 2, in11, 2, in8, in9, in10, - in11); - DUP4_ARG2(__lsx_vslli_h, in12, 2, in13, 2, in14, 2, in15, 2, in12, in13, in14, - in15); - DUP4_ARG2(__lsx_vadd_h, in0, in15, in1, in14, in2, in13, in3, in12, tmp0, - tmp1, tmp2, tmp3); - DUP4_ARG2(__lsx_vadd_h, in4, in11, in5, in10, in6, in9, in7, in8, tmp4, tmp5, - tmp6, tmp7); - FDCT8x16_EVEN(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp0, tmp1, - tmp2, tmp3, tmp4, tmp5, tmp6, tmp7); - __lsx_vst(tmp0, tmp_ptr, 0); - __lsx_vst(tmp1, tmp_ptr, 64); - __lsx_vst(tmp2, tmp_ptr, 128); - __lsx_vst(tmp3, tmp_ptr, 192); - __lsx_vst(tmp4, tmp_ptr, 256); - __lsx_vst(tmp5, tmp_ptr, 320); - __lsx_vst(tmp6, tmp_ptr, 384); - __lsx_vst(tmp7, tmp_ptr, 448); - DUP4_ARG2(__lsx_vsub_h, in0, in15, in1, in14, in2, in13, in3, in12, in15, - in14, in13, in12); - DUP4_ARG2(__lsx_vsub_h, in4, in11, in5, in10, in6, in9, in7, in8, in11, in10, - in9, in8); - - tmp_ptr += 16; - - /* stp 1 */ - DUP2_ARG2(__lsx_vilvh_h, in10, in13, in11, in12, vec2, vec4); - DUP2_ARG2(__lsx_vilvl_h, in10, in13, in11, in12, vec3, vec5); - - cnst4 = __lsx_vreplvei_h(coeff, 0); - DOT_SHIFT_RIGHT_PCK_H(vec2, vec3, cnst4, stp25); - - cnst5 = __lsx_vreplvei_h(coeff, 1); - cnst5 = __lsx_vpackev_h(cnst5, cnst4); - DOT_SHIFT_RIGHT_PCK_H(vec2, vec3, cnst5, stp22); - DOT_SHIFT_RIGHT_PCK_H(vec4, vec5, cnst4, stp24); - DOT_SHIFT_RIGHT_PCK_H(vec4, vec5, cnst5, stp23); - - /* stp2 */ - LSX_BUTTERFLY_4_H(in8, in9, stp22, stp23, stp30, stp31, stp32, stp33); - LSX_BUTTERFLY_4_H(in15, in14, stp25, stp24, stp37, stp36, stp35, stp34); - DUP2_ARG2(__lsx_vilvh_h, stp36, stp31, stp35, stp32, vec2, vec4); - DUP2_ARG2(__lsx_vilvl_h, stp36, stp31, stp35, stp32, vec3, vec5); - DUP2_ARG2(__lsx_vreplvei_h, coeff, 2, coeff, 3, cnst0, cnst1); - cnst0 = __lsx_vpackev_h(cnst0, cnst1); - DOT_SHIFT_RIGHT_PCK_H(vec2, vec3, cnst0, stp26); - - cnst0 = __lsx_vreplvei_h(coeff, 4); - cnst1 = __lsx_vpackev_h(cnst1, cnst0); - DOT_SHIFT_RIGHT_PCK_H(vec2, vec3, cnst1, stp21); - - LSX_BUTTERFLY_4_H(stp30, stp37, stp26, stp21, in8, in15, in14, in9); - vec1 = __lsx_vilvl_h(in15, in8); - vec0 = __lsx_vilvh_h(in15, in8); - - DUP2_ARG2(__lsx_vreplvei_h, coeff1, 0, coeff1, 1, cnst0, cnst1); - cnst0 = __lsx_vpackev_h(cnst0, cnst1); - - DOT_SHIFT_RIGHT_PCK_H(vec0, vec1, cnst0, in8); - __lsx_vst(in8, tmp_ptr, 0); - - cnst0 = __lsx_vreplvei_h(coeff2, 0); - cnst0 = __lsx_vpackev_h(cnst1, cnst0); - DOT_SHIFT_RIGHT_PCK_H(vec0, vec1, cnst0, in8); - __lsx_vst(in8, tmp_ptr, 448); - - vec1 = __lsx_vilvl_h(in14, in9); - vec0 = __lsx_vilvh_h(in14, in9); - DUP2_ARG2(__lsx_vreplvei_h, coeff1, 2, coeff1, 3, cnst0, cnst1); - cnst1 = __lsx_vpackev_h(cnst1, cnst0); - - DOT_SHIFT_RIGHT_PCK_H(vec0, vec1, cnst1, in8); - __lsx_vst(in8, tmp_ptr, 256); - - cnst1 = __lsx_vreplvei_h(coeff2, 2); - cnst0 = __lsx_vpackev_h(cnst0, cnst1); - DOT_SHIFT_RIGHT_PCK_H(vec0, vec1, cnst0, in8); - __lsx_vst(in8, tmp_ptr, 192); - - DUP2_ARG2(__lsx_vreplvei_h, coeff, 2, coeff, 5, cnst0, cnst1); - cnst1 = __lsx_vpackev_h(cnst1, cnst0); - DOT_SHIFT_RIGHT_PCK_H(vec4, vec5, cnst1, stp25); - - cnst1 = __lsx_vreplvei_h(coeff, 3); - cnst1 = __lsx_vpackev_h(cnst0, cnst1); - DOT_SHIFT_RIGHT_PCK_H(vec4, vec5, cnst1, stp22); - - /* stp4 */ - DUP2_ARG2(__lsx_vadd_h, stp34, stp25, stp33, stp22, in13, in10); - - vec1 = __lsx_vilvl_h(in13, in10); - vec0 = __lsx_vilvh_h(in13, in10); - DUP2_ARG2(__lsx_vreplvei_h, coeff1, 4, coeff1, 5, cnst0, cnst1); - cnst0 = __lsx_vpackev_h(cnst0, cnst1); - DOT_SHIFT_RIGHT_PCK_H(vec0, vec1, cnst0, in8); - __lsx_vst(in8, tmp_ptr, 128); - - cnst0 = __lsx_vreplvei_h(coeff2, 1); - cnst0 = __lsx_vpackev_h(cnst1, cnst0); - DOT_SHIFT_RIGHT_PCK_H(vec0, vec1, cnst0, in8); - __lsx_vst(in8, tmp_ptr, 320); - - DUP2_ARG2(__lsx_vsub_h, stp34, stp25, stp33, stp22, in12, in11); - vec1 = __lsx_vilvl_h(in12, in11); - vec0 = __lsx_vilvh_h(in12, in11); - DUP2_ARG2(__lsx_vreplvei_h, coeff1, 6, coeff1, 7, cnst0, cnst1); - cnst1 = __lsx_vpackev_h(cnst1, cnst0); - - DOT_SHIFT_RIGHT_PCK_H(vec0, vec1, cnst1, in8); - __lsx_vst(in8, tmp_ptr, 384); - - cnst1 = __lsx_vreplvei_h(coeff2, 3); - cnst0 = __lsx_vpackev_h(cnst0, cnst1); - DOT_SHIFT_RIGHT_PCK_H(vec0, vec1, cnst0, in8); - __lsx_vst(in8, tmp_ptr, 64); -} - -void fdct16x8_1d_row(int16_t *input, int16_t *output) { - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - __m128i in0, in1, in2, in3, in4, in5, in6, in7; - __m128i in8, in9, in10, in11, in12, in13, in14, in15; - int16_t *input_tmp = input; - - DUP4_ARG2(__lsx_vld, input, 0, input, 32, input, 64, input, 96, in0, in1, in2, - in3); - DUP4_ARG2(__lsx_vld, input, 128, input, 160, input, 192, input, 224, in4, in5, - in6, in7); - DUP4_ARG2(__lsx_vld, input_tmp, 16, input_tmp, 48, input_tmp, 80, input_tmp, - 112, in8, in9, in10, in11); - DUP4_ARG2(__lsx_vld, input_tmp, 144, input_tmp, 176, input_tmp, 208, - input_tmp, 240, in12, in13, in14, in15); - - LSX_TRANSPOSE8x8_H(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - LSX_TRANSPOSE8x8_H(in8, in9, in10, in11, in12, in13, in14, in15, in8, in9, - in10, in11, in12, in13, in14, in15); - DUP4_ARG2(__lsx_vaddi_hu, in0, 1, in1, 1, in2, 1, in3, 1, in0, in1, in2, in3); - DUP4_ARG2(__lsx_vaddi_hu, in4, 1, in5, 1, in6, 1, in7, 1, in4, in5, in6, in7); - DUP4_ARG2(__lsx_vaddi_hu, in8, 1, in9, 1, in10, 1, in11, 1, in8, in9, in10, - in11); - DUP4_ARG2(__lsx_vaddi_hu, in12, 1, in13, 1, in14, 1, in15, 1, in12, in13, - in14, in15); - - DUP4_ARG2(__lsx_vsrai_h, in0, 2, in1, 2, in2, 2, in3, 2, in0, in1, in2, in3); - DUP4_ARG2(__lsx_vsrai_h, in4, 2, in5, 2, in6, 2, in7, 2, in4, in5, in6, in7); - DUP4_ARG2(__lsx_vsrai_h, in8, 2, in9, 2, in10, 2, in11, 2, in8, in9, in10, - in11); - DUP4_ARG2(__lsx_vsrai_h, in12, 2, in13, 2, in14, 2, in15, 2, in12, in13, in14, - in15); - LSX_BUTTERFLY_16_H(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, - in11, in12, in13, in14, in15, tmp0, tmp1, tmp2, tmp3, tmp4, - tmp5, tmp6, tmp7, in8, in9, in10, in11, in12, in13, in14, - in15); - __lsx_vst(in8, input, 0); - __lsx_vst(in9, input, 32); - __lsx_vst(in10, input, 64); - __lsx_vst(in11, input, 96); - __lsx_vst(in12, input, 128); - __lsx_vst(in13, input, 160); - __lsx_vst(in14, input, 192); - __lsx_vst(in15, input, 224); - - FDCT8x16_EVEN(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp0, tmp1, - tmp2, tmp3, tmp4, tmp5, tmp6, tmp7); - DUP4_ARG2(__lsx_vld, input, 0, input, 32, input, 64, input, 96, in8, in9, - in10, in11); - DUP4_ARG2(__lsx_vld, input, 128, input, 160, input, 192, input, 224, in12, - in13, in14, in15); - FDCT8x16_ODD(in8, in9, in10, in11, in12, in13, in14, in15, in0, in1, in2, in3, - in4, in5, in6, in7); - LSX_TRANSPOSE8x8_H(tmp0, in0, tmp1, in1, tmp2, in2, tmp3, in3, tmp0, in0, - tmp1, in1, tmp2, in2, tmp3, in3); - __lsx_vst(tmp0, output, 0); - __lsx_vst(in0, output, 32); - __lsx_vst(tmp1, output, 64); - __lsx_vst(in1, output, 96); - __lsx_vst(tmp2, output, 128); - __lsx_vst(in2, output, 160); - __lsx_vst(tmp3, output, 192); - __lsx_vst(in3, output, 224); - - LSX_TRANSPOSE8x8_H(tmp4, in4, tmp5, in5, tmp6, in6, tmp7, in7, tmp4, in4, - tmp5, in5, tmp6, in6, tmp7, in7); - __lsx_vst(tmp4, output, 16); - __lsx_vst(in4, output, 48); - __lsx_vst(tmp5, output, 80); - __lsx_vst(in5, output, 112); - __lsx_vst(tmp6, output, 144); - __lsx_vst(in6, output, 176); - __lsx_vst(tmp7, output, 208); - __lsx_vst(in7, output, 240); -} - -void vpx_fdct4x4_lsx(const int16_t *input, int16_t *output, - int32_t src_stride) { - __m128i in0, in1, in2, in3; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride4 = src_stride2 << 1; - int32_t src_stride6 = src_stride4 + src_stride2; - - in0 = __lsx_vld(input, 0); - DUP2_ARG2(__lsx_vldx, input, src_stride2, input, src_stride4, in1, in2); - in3 = __lsx_vldx(input, src_stride6); - - /* fdct4 pre-process */ - { - __m128i vec, mask; - __m128i zero = __lsx_vldi(0); - - mask = __lsx_vinsgr2vr_b(zero, 1, 0); - DUP4_ARG2(__lsx_vslli_h, in0, 4, in1, 4, in2, 4, in3, 4, in0, in1, in2, - in3); - vec = __lsx_vseqi_h(in0, 0); - vec = __lsx_vxori_b(vec, 255); - vec = __lsx_vand_v(mask, vec); - in0 = __lsx_vadd_h(in0, vec); - } - - VP9_FDCT4(in0, in1, in2, in3, in0, in1, in2, in3); - LSX_TRANSPOSE4x4_H(in0, in1, in2, in3, in0, in1, in2, in3); - VP9_FDCT4(in0, in1, in2, in3, in0, in1, in2, in3); - LSX_TRANSPOSE4x4_H(in0, in1, in2, in3, in0, in1, in2, in3); - DUP4_ARG2(__lsx_vaddi_hu, in0, 1, in1, 1, in2, 1, in3, 1, in0, in1, in2, in3); - DUP4_ARG2(__lsx_vsrai_h, in0, 2, in1, 2, in2, 2, in3, 2, in0, in1, in2, in3); - DUP2_ARG2(__lsx_vpickev_d, in1, in0, in3, in2, in0, in2); - __lsx_vst(in0, output, 0); - __lsx_vst(in2, output, 16); -} - -void vpx_fdct8x8_lsx(const int16_t *input, int16_t *output, - int32_t src_stride) { - __m128i in0, in1, in2, in3, in4, in5, in6, in7; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride4 = src_stride2 << 1; - int32_t src_stride6 = src_stride4 + src_stride2; - int16_t *input_tmp = (int16_t *)input; - - in0 = __lsx_vld(input_tmp, 0); - DUP2_ARG2(__lsx_vldx, input_tmp, src_stride2, input_tmp, src_stride4, in1, - in2); - in3 = __lsx_vldx(input_tmp, src_stride6); - input_tmp += src_stride4; - in4 = __lsx_vld(input_tmp, 0); - DUP2_ARG2(__lsx_vldx, input_tmp, src_stride2, input_tmp, src_stride4, in5, - in6); - in7 = __lsx_vldx(input_tmp, src_stride6); - - DUP4_ARG2(__lsx_vslli_h, in0, 2, in1, 2, in2, 2, in3, 2, in0, in1, in2, in3); - DUP4_ARG2(__lsx_vslli_h, in4, 2, in5, 2, in6, 2, in7, 2, in4, in5, in6, in7); - - VP9_FDCT8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, - in5, in6, in7); - LSX_TRANSPOSE8x8_H(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - VP9_FDCT8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, - in5, in6, in7); - LSX_TRANSPOSE8x8_H(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - SRLI_AVE_S_4V_H(in0, in1, in2, in3, in4, in5, in6, in7); - - __lsx_vst(in0, output, 0); - __lsx_vst(in1, output, 16); - __lsx_vst(in2, output, 32); - __lsx_vst(in3, output, 48); - __lsx_vst(in4, output, 64); - __lsx_vst(in5, output, 80); - __lsx_vst(in6, output, 96); - __lsx_vst(in7, output, 112); -} - -void vpx_fdct16x16_lsx(const int16_t *input, int16_t *output, - int32_t src_stride) { - int32_t i; - DECLARE_ALIGNED(32, int16_t, tmp_buf[16 * 16]); - - /* column transform */ - for (i = 0; i < 2; ++i) { - fdct8x16_1d_column((input + 8 * i), (&tmp_buf[0] + 8 * i), src_stride); - } - - /* row transform */ - for (i = 0; i < 2; ++i) { - fdct16x8_1d_row((&tmp_buf[0] + (128 * i)), (output + (128 * i))); - } -} -#endif // !CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/fwd_txfm_lsx.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/fwd_txfm_lsx.h deleted file mode 100644 index 4a9fce9a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/fwd_txfm_lsx.h +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_LOONGARCH_FWD_TXFM_LSX_H_ -#define VPX_VPX_DSP_LOONGARCH_FWD_TXFM_LSX_H_ - -#include "vpx_dsp/loongarch/txfm_macros_lsx.h" -#include "vpx_dsp/txfm_common.h" - -#define VP9_FDCT4(in0, in1, in2, in3, out0, out1, out2, out3) \ - do { \ - __m128i cnst0_m, cnst1_m, cnst2_m, cnst3_m; \ - __m128i vec0_m, vec1_m, vec2_m, vec3_m; \ - __m128i vec4_m, vec5_m, vec6_m, vec7_m; \ - __m128i coeff_m = { 0x187e3b21d2bf2d41, 0x000000000000c4df }; \ - \ - LSX_BUTTERFLY_4_H(in0, in1, in2, in3, vec0_m, vec1_m, vec2_m, vec3_m); \ - DUP2_ARG2(__lsx_vilvl_h, vec1_m, vec0_m, vec3_m, vec2_m, vec0_m, vec2_m); \ - DUP2_ARG2(__lsx_vreplvei_h, coeff_m, 0, coeff_m, 1, cnst0_m, cnst1_m); \ - cnst1_m = __lsx_vpackev_h(cnst1_m, cnst0_m); \ - vec5_m = __lsx_vdp2_w_h(vec0_m, cnst1_m); \ - DUP2_ARG2(__lsx_vreplvei_h, coeff_m, 4, coeff_m, 3, cnst2_m, cnst3_m); \ - cnst2_m = __lsx_vpackev_h(cnst3_m, cnst2_m); \ - vec7_m = __lsx_vdp2_w_h(vec2_m, cnst2_m); \ - \ - vec4_m = __lsx_vdp2_w_h(vec0_m, cnst0_m); \ - cnst2_m = __lsx_vreplvei_h(coeff_m, 2); \ - cnst2_m = __lsx_vpackev_h(cnst2_m, cnst3_m); \ - vec6_m = __lsx_vdp2_w_h(vec2_m, cnst2_m); \ - \ - DUP4_ARG3(__lsx_vssrarni_h_w, vec4_m, vec4_m, DCT_CONST_BITS, vec5_m, \ - vec5_m, DCT_CONST_BITS, vec6_m, vec6_m, DCT_CONST_BITS, vec7_m, \ - vec7_m, DCT_CONST_BITS, out0, out2, out1, out3); \ - } while (0) - -#define VP9_FDCT8(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, \ - out3, out4, out5, out6, out7) \ - do { \ - __m128i s0_m, s1_m, s2_m, s3_m, s4_m, s5_m, s6_m; \ - __m128i s7_m, x0_m, x1_m, x2_m, x3_m; \ - __m128i coeff_m = { 0x187e3b21d2bf2d41, 0x238e35370c7c3ec5 }; \ - \ - /* FDCT stage1 */ \ - LSX_BUTTERFLY_8_H(in0, in1, in2, in3, in4, in5, in6, in7, s0_m, s1_m, \ - s2_m, s3_m, s4_m, s5_m, s6_m, s7_m); \ - LSX_BUTTERFLY_4_H(s0_m, s1_m, s2_m, s3_m, x0_m, x1_m, x2_m, x3_m); \ - DUP2_ARG2(__lsx_vilvh_h, x1_m, x0_m, x3_m, x2_m, s0_m, s2_m); \ - DUP2_ARG2(__lsx_vilvl_h, x1_m, x0_m, x3_m, x2_m, s1_m, s3_m); \ - DUP2_ARG2(__lsx_vreplvei_h, coeff_m, 0, coeff_m, 1, x0_m, x1_m); \ - x1_m = __lsx_vpackev_h(x1_m, x0_m); \ - DOT_SHIFT_RIGHT_PCK_H(s0_m, s1_m, x1_m, out4); \ - \ - DUP2_ARG2(__lsx_vreplvei_h, coeff_m, 2, coeff_m, 3, x2_m, x3_m); \ - x2_m = __lsx_vneg_h(x2_m); \ - x2_m = __lsx_vpackev_h(x3_m, x2_m); \ - DOT_SHIFT_RIGHT_PCK_H(s2_m, s3_m, x2_m, out6); \ - \ - DOT_SHIFT_RIGHT_PCK_H(s0_m, s1_m, x0_m, out0); \ - x2_m = __lsx_vreplvei_h(coeff_m, 2); \ - x2_m = __lsx_vpackev_h(x2_m, x3_m); \ - DOT_SHIFT_RIGHT_PCK_H(s2_m, s3_m, x2_m, out2); \ - \ - /* stage2 */ \ - s1_m = __lsx_vilvl_h(s5_m, s6_m); \ - s0_m = __lsx_vilvh_h(s5_m, s6_m); \ - \ - DOT_SHIFT_RIGHT_PCK_H(s0_m, s1_m, x0_m, s6_m); \ - DOT_SHIFT_RIGHT_PCK_H(s0_m, s1_m, x1_m, s5_m); \ - \ - /* stage3 */ \ - LSX_BUTTERFLY_4_H(s4_m, s7_m, s6_m, s5_m, x0_m, x3_m, x2_m, x1_m); \ - \ - /* stage4 */ \ - DUP2_ARG2(__lsx_vilvh_h, x3_m, x0_m, x2_m, x1_m, s4_m, s6_m); \ - DUP2_ARG2(__lsx_vilvl_h, x3_m, x0_m, x2_m, x1_m, s5_m, s7_m); \ - \ - DUP2_ARG2(__lsx_vreplvei_h, coeff_m, 4, coeff_m, 5, x0_m, x1_m); \ - x1_m = __lsx_vpackev_h(x0_m, x1_m); \ - DOT_SHIFT_RIGHT_PCK_H(s4_m, s5_m, x1_m, out1); \ - \ - DUP2_ARG2(__lsx_vreplvei_h, coeff_m, 6, coeff_m, 7, x2_m, x3_m); \ - x2_m = __lsx_vpackev_h(x3_m, x2_m); \ - DOT_SHIFT_RIGHT_PCK_H(s6_m, s7_m, x2_m, out5); \ - \ - x1_m = __lsx_vreplvei_h(coeff_m, 5); \ - x0_m = __lsx_vneg_h(x0_m); \ - x0_m = __lsx_vpackev_h(x1_m, x0_m); \ - DOT_SHIFT_RIGHT_PCK_H(s4_m, s5_m, x0_m, out7); \ - x2_m = __lsx_vreplvei_h(coeff_m, 6); \ - x3_m = __lsx_vneg_h(x3_m); \ - x2_m = __lsx_vpackev_h(x2_m, x3_m); \ - DOT_SHIFT_RIGHT_PCK_H(s6_m, s7_m, x2_m, out3); \ - } while (0) - -#define SRLI_AVE_S_4V_H(in0, in1, in2, in3, in4, in5, in6, in7) \ - do { \ - __m128i vec0_m, vec1_m, vec2_m, vec3_m, vec4_m, vec5_m, vec6_m, vec7_m; \ - \ - DUP4_ARG2(__lsx_vsrli_h, in0, 15, in1, 15, in2, 15, in3, 15, vec0_m, \ - vec1_m, vec2_m, vec3_m); \ - DUP4_ARG2(__lsx_vsrli_h, in4, 15, in5, 15, in6, 15, in7, 15, vec4_m, \ - vec5_m, vec6_m, vec7_m); \ - DUP4_ARG2(__lsx_vavg_h, vec0_m, in0, vec1_m, in1, vec2_m, in2, vec3_m, \ - in3, in0, in1, in2, in3); \ - DUP4_ARG2(__lsx_vavg_h, vec4_m, in4, vec5_m, in5, vec6_m, in6, vec7_m, \ - in7, in4, in5, in6, in7); \ - } while (0) - -#define FDCT32_POSTPROC_2V_POS_H(vec0, vec1) \ - do { \ - __m128i tp0_m, tp1_m; \ - __m128i one = __lsx_vreplgr2vr_h(1); \ - \ - tp0_m = __lsx_vslei_h(vec0, 0); \ - tp1_m = __lsx_vslei_h(vec1, 0); \ - tp0_m = __lsx_vxori_b(tp0_m, 255); \ - tp1_m = __lsx_vxori_b(tp1_m, 255); \ - vec0 = __lsx_vadd_h(vec0, one); \ - vec1 = __lsx_vadd_h(vec1, one); \ - tp0_m = __lsx_vand_v(one, tp0_m); \ - tp1_m = __lsx_vand_v(one, tp1_m); \ - vec0 = __lsx_vadd_h(vec0, tp0_m); \ - vec1 = __lsx_vadd_h(vec1, tp1_m); \ - vec0 = __lsx_vsrai_h(vec0, 2); \ - vec1 = __lsx_vsrai_h(vec1, 2); \ - } while (0) - -#define FDCT_POSTPROC_2V_NEG_H(vec0, vec1) \ - do { \ - __m128i tp0_m, tp1_m; \ - __m128i one_m = __lsx_vldi(0x401); \ - \ - tp0_m = __lsx_vslti_h(vec0, 0); \ - tp1_m = __lsx_vslti_h(vec1, 0); \ - vec0 = __lsx_vadd_h(vec0, one_m); \ - vec1 = __lsx_vadd_h(vec1, one_m); \ - tp0_m = __lsx_vand_v(one_m, tp0_m); \ - tp1_m = __lsx_vand_v(one_m, tp1_m); \ - vec0 = __lsx_vadd_h(vec0, tp0_m); \ - vec1 = __lsx_vadd_h(vec1, tp1_m); \ - vec0 = __lsx_vsrai_h(vec0, 2); \ - vec1 = __lsx_vsrai_h(vec1, 2); \ - } while (0) - -#define FDCT32_POSTPROC_NEG_W(vec) \ - do { \ - __m128i temp_m; \ - __m128i one_m = __lsx_vreplgr2vr_w(1); \ - \ - temp_m = __lsx_vslti_w(vec, 0); \ - vec = __lsx_vadd_w(vec, one_m); \ - temp_m = __lsx_vand_v(one_m, temp_m); \ - vec = __lsx_vadd_w(vec, temp_m); \ - vec = __lsx_vsrai_w(vec, 2); \ - } while (0) - -#define DOTP_CONST_PAIR_W(reg0_left, reg1_left, reg0_right, reg1_right, \ - const0, const1, out0, out1, out2, out3) \ - do { \ - __m128i s0_m, s1_m, s2_m, s3_m, s4_m, s5_m, s6_m, s7_m; \ - __m128i tp0_m, tp1_m, tp2_m, tp3_m, _tmp0, _tmp1; \ - __m128i k0_m = __lsx_vreplgr2vr_w((int32_t)const0); \ - \ - s0_m = __lsx_vreplgr2vr_w((int32_t)const1); \ - k0_m = __lsx_vpackev_w(s0_m, k0_m); \ - \ - DUP2_ARG1(__lsx_vneg_w, reg1_left, reg1_right, _tmp0, _tmp1); \ - s1_m = __lsx_vilvl_w(_tmp0, reg0_left); \ - s0_m = __lsx_vilvh_w(_tmp0, reg0_left); \ - s3_m = __lsx_vilvl_w(reg0_left, reg1_left); \ - s2_m = __lsx_vilvh_w(reg0_left, reg1_left); \ - s5_m = __lsx_vilvl_w(_tmp1, reg0_right); \ - s4_m = __lsx_vilvh_w(_tmp1, reg0_right); \ - s7_m = __lsx_vilvl_w(reg0_right, reg1_right); \ - s6_m = __lsx_vilvh_w(reg0_right, reg1_right); \ - DUP2_ARG2(__lsx_vdp2_d_w, s0_m, k0_m, s1_m, k0_m, tp0_m, tp1_m); \ - DUP2_ARG2(__lsx_vdp2_d_w, s4_m, k0_m, s5_m, k0_m, tp2_m, tp3_m); \ - DUP2_ARG3(__lsx_vssrarni_w_d, tp0_m, tp1_m, DCT_CONST_BITS, tp2_m, tp3_m, \ - DCT_CONST_BITS, out0, out1); \ - DUP2_ARG2(__lsx_vdp2_d_w, s2_m, k0_m, s3_m, k0_m, tp0_m, tp1_m); \ - DUP2_ARG2(__lsx_vdp2_d_w, s6_m, k0_m, s7_m, k0_m, tp2_m, tp3_m); \ - DUP2_ARG3(__lsx_vssrarni_w_d, tp0_m, tp1_m, DCT_CONST_BITS, tp2_m, tp3_m, \ - DCT_CONST_BITS, out2, out3); \ - } while (0) - -#define VP9_ADDBLK_ST8x4_UB(dst, _stride, _stride2, _stride3, in0, in1, in2, \ - in3) \ - do { \ - __m128i dst0_m, dst1_m, dst2_m, dst3_m; \ - __m128i tmp0_m, tmp1_m; \ - __m128i res0_m, res1_m, res2_m, res3_m; \ - \ - dst0_m = __lsx_vld(dst, 0); \ - DUP2_ARG2(__lsx_vldx, dst, _stride, dst, _stride2, dst1_m, dst2_m); \ - dst3_m = __lsx_vldx(dst, _stride3); \ - DUP4_ARG2(__lsx_vsllwil_hu_bu, dst0_m, 0, dst1_m, 0, dst2_m, 0, dst3_m, 0, \ - res0_m, res1_m, res2_m, res3_m); \ - DUP4_ARG2(__lsx_vadd_h, res0_m, in0, res1_m, in1, res2_m, in2, res3_m, \ - in3, res0_m, res1_m, res2_m, res3_m); \ - DUP2_ARG3(__lsx_vssrarni_bu_h, res1_m, res0_m, 0, res3_m, res2_m, 0, \ - tmp0_m, tmp1_m); \ - __lsx_vstelm_d(tmp0_m, dst, 0, 0); \ - __lsx_vstelm_d(tmp0_m, dst + _stride, 0, 1); \ - __lsx_vstelm_d(tmp1_m, dst + _stride2, 0, 0); \ - __lsx_vstelm_d(tmp1_m, dst + _stride3, 0, 1); \ - } while (0) - -#define FDCT8x16_EVEN(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3, out4, out5, out6, out7) \ - do { \ - __m128i s0_m, s1_m, s2_m, s3_m, s4_m, s5_m, s6_m, s7_m; \ - __m128i x0_m, x1_m, x2_m, x3_m; \ - __m128i coeff_m = { 0x187e3b21d2bf2d41, 0x238e35370c7c3ec5 }; \ - \ - /* FDCT stage1 */ \ - LSX_BUTTERFLY_8_H(in0, in1, in2, in3, in4, in5, in6, in7, s0_m, s1_m, \ - s2_m, s3_m, s4_m, s5_m, s6_m, s7_m); \ - LSX_BUTTERFLY_4_H(s0_m, s1_m, s2_m, s3_m, x0_m, x1_m, x2_m, x3_m); \ - DUP2_ARG2(__lsx_vilvh_h, x1_m, x0_m, x3_m, x2_m, s0_m, s2_m); \ - DUP2_ARG2(__lsx_vilvl_h, x1_m, x0_m, x3_m, x2_m, s1_m, s3_m); \ - DUP2_ARG2(__lsx_vreplvei_h, coeff_m, 0, coeff_m, 1, x0_m, x1_m); \ - x1_m = __lsx_vpackev_h(x1_m, x0_m); \ - DOT_SHIFT_RIGHT_PCK_H(s0_m, s1_m, x1_m, out4); \ - \ - DUP2_ARG2(__lsx_vreplvei_h, coeff_m, 2, coeff_m, 3, x2_m, x3_m); \ - x2_m = __lsx_vneg_h(x2_m); \ - x2_m = __lsx_vpackev_h(x3_m, x2_m); \ - DOT_SHIFT_RIGHT_PCK_H(s2_m, s3_m, x2_m, out6); \ - \ - DOT_SHIFT_RIGHT_PCK_H(s0_m, s1_m, x0_m, out0); \ - x2_m = __lsx_vreplvei_h(coeff_m, 2); \ - x2_m = __lsx_vpackev_h(x2_m, x3_m); \ - DOT_SHIFT_RIGHT_PCK_H(s2_m, s3_m, x2_m, out2); \ - \ - /* stage2 */ \ - s1_m = __lsx_vilvl_h(s5_m, s6_m); \ - s0_m = __lsx_vilvh_h(s5_m, s6_m); \ - \ - DOT_SHIFT_RIGHT_PCK_H(s0_m, s1_m, x0_m, s6_m); \ - DOT_SHIFT_RIGHT_PCK_H(s0_m, s1_m, x1_m, s5_m); \ - \ - /* stage3 */ \ - LSX_BUTTERFLY_4_H(s4_m, s7_m, s6_m, s5_m, x0_m, x3_m, x2_m, x1_m); \ - \ - /* stage4 */ \ - DUP2_ARG2(__lsx_vilvh_h, x3_m, x0_m, x2_m, x1_m, s4_m, s6_m); \ - DUP2_ARG2(__lsx_vilvl_h, x3_m, x0_m, x2_m, x1_m, s5_m, s7_m); \ - \ - DUP2_ARG2(__lsx_vreplvei_h, coeff_m, 4, coeff_m, 5, x0_m, x1_m); \ - x1_m = __lsx_vpackev_h(x0_m, x1_m); \ - DOT_SHIFT_RIGHT_PCK_H(s4_m, s5_m, x1_m, out1); \ - \ - DUP2_ARG2(__lsx_vreplvei_h, coeff_m, 6, coeff_m, 7, x2_m, x3_m); \ - x2_m = __lsx_vpackev_h(x3_m, x2_m); \ - DOT_SHIFT_RIGHT_PCK_H(s6_m, s7_m, x2_m, out5); \ - \ - x1_m = __lsx_vreplvei_h(coeff_m, 5); \ - x0_m = __lsx_vneg_h(x0_m); \ - x0_m = __lsx_vpackev_h(x1_m, x0_m); \ - DOT_SHIFT_RIGHT_PCK_H(s4_m, s5_m, x0_m, out7); \ - \ - x2_m = __lsx_vreplvei_h(coeff_m, 6); \ - x3_m = __lsx_vneg_h(x3_m); \ - x2_m = __lsx_vpackev_h(x2_m, x3_m); \ - DOT_SHIFT_RIGHT_PCK_H(s6_m, s7_m, x2_m, out3); \ - } while (0) - -#define FDCT8x16_ODD(input0, input1, input2, input3, input4, input5, input6, \ - input7, out1, out3, out5, out7, out9, out11, out13, \ - out15) \ - do { \ - __m128i stp21_m, stp22_m, stp23_m, stp24_m, stp25_m, stp26_m; \ - __m128i stp30_m, stp31_m, stp32_m, stp33_m, stp34_m, stp35_m; \ - __m128i stp36_m, stp37_m, vec0_m, vec1_m; \ - __m128i vec2_m, vec3_m, vec4_m, vec5_m, vec6_m; \ - __m128i cnst0_m, cnst1_m, cnst4_m, cnst5_m; \ - __m128i coeff_m = { 0x187e3b21d2bf2d41, 0x238e3537e782c4df }; \ - __m128i coeff1_m = { 0x289a317906463fb1, 0x12943d3f1e2b3871 }; \ - __m128i coeff2_m = { 0xed6cd766c78fc04f, 0x0 }; \ - \ - /* stp 1 */ \ - DUP2_ARG2(__lsx_vilvh_h, input2, input5, input3, input4, vec2_m, vec4_m); \ - DUP2_ARG2(__lsx_vilvl_h, input2, input5, input3, input4, vec3_m, vec5_m); \ - \ - cnst4_m = __lsx_vreplvei_h(coeff_m, 0); \ - DOT_SHIFT_RIGHT_PCK_H(vec2_m, vec3_m, cnst4_m, stp25_m); \ - \ - cnst5_m = __lsx_vreplvei_h(coeff_m, 1); \ - cnst5_m = __lsx_vpackev_h(cnst5_m, cnst4_m); \ - DOT_SHIFT_RIGHT_PCK_H(vec2_m, vec3_m, cnst5_m, stp22_m); \ - DOT_SHIFT_RIGHT_PCK_H(vec4_m, vec5_m, cnst4_m, stp24_m); \ - DOT_SHIFT_RIGHT_PCK_H(vec4_m, vec5_m, cnst5_m, stp23_m); \ - \ - /* stp2 */ \ - LSX_BUTTERFLY_4_H(input0, input1, stp22_m, stp23_m, stp30_m, stp31_m, \ - stp32_m, stp33_m); \ - LSX_BUTTERFLY_4_H(input7, input6, stp25_m, stp24_m, stp37_m, stp36_m, \ - stp35_m, stp34_m); \ - \ - DUP2_ARG2(__lsx_vilvh_h, stp36_m, stp31_m, stp35_m, stp32_m, vec2_m, \ - vec4_m); \ - DUP2_ARG2(__lsx_vilvl_h, stp36_m, stp31_m, stp35_m, stp32_m, vec3_m, \ - vec5_m); \ - \ - DUP2_ARG2(__lsx_vreplvei_h, coeff_m, 2, coeff_m, 3, cnst0_m, cnst1_m); \ - cnst0_m = __lsx_vpackev_h(cnst0_m, cnst1_m); \ - DOT_SHIFT_RIGHT_PCK_H(vec2_m, vec3_m, cnst0_m, stp26_m); \ - \ - cnst0_m = __lsx_vreplvei_h(coeff_m, 4); \ - cnst1_m = __lsx_vpackev_h(cnst1_m, cnst0_m); \ - DOT_SHIFT_RIGHT_PCK_H(vec2_m, vec3_m, cnst1_m, stp21_m); \ - \ - DUP2_ARG2(__lsx_vreplvei_h, coeff_m, 5, coeff_m, 2, cnst0_m, cnst1_m); \ - cnst1_m = __lsx_vpackev_h(cnst0_m, cnst1_m); \ - DOT_SHIFT_RIGHT_PCK_H(vec4_m, vec5_m, cnst1_m, stp25_m); \ - \ - cnst0_m = __lsx_vreplvei_h(coeff_m, 3); \ - cnst1_m = __lsx_vpackev_h(cnst1_m, cnst0_m); \ - DOT_SHIFT_RIGHT_PCK_H(vec4_m, vec5_m, cnst1_m, stp22_m); \ - \ - /* stp4 */ \ - LSX_BUTTERFLY_4_H(stp30_m, stp37_m, stp26_m, stp21_m, vec6_m, vec2_m, \ - vec4_m, vec5_m); \ - LSX_BUTTERFLY_4_H(stp33_m, stp34_m, stp25_m, stp22_m, stp21_m, stp23_m, \ - stp24_m, stp31_m); \ - \ - vec1_m = __lsx_vilvl_h(vec2_m, vec6_m); \ - vec0_m = __lsx_vilvh_h(vec2_m, vec6_m); \ - DUP2_ARG2(__lsx_vreplvei_h, coeff1_m, 0, coeff1_m, 1, cnst0_m, cnst1_m); \ - cnst0_m = __lsx_vpackev_h(cnst0_m, cnst1_m); \ - \ - DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst0_m, out1); \ - \ - cnst0_m = __lsx_vreplvei_h(coeff2_m, 0); \ - cnst0_m = __lsx_vpackev_h(cnst1_m, cnst0_m); \ - DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst0_m, out15); \ - \ - vec1_m = __lsx_vilvl_h(vec4_m, vec5_m); \ - vec0_m = __lsx_vilvh_h(vec4_m, vec5_m); \ - DUP2_ARG2(__lsx_vreplvei_h, coeff1_m, 2, coeff1_m, 3, cnst0_m, cnst1_m); \ - cnst1_m = __lsx_vpackev_h(cnst1_m, cnst0_m); \ - \ - DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst1_m, out9); \ - \ - cnst1_m = __lsx_vreplvei_h(coeff2_m, 2); \ - cnst0_m = __lsx_vpackev_h(cnst0_m, cnst1_m); \ - DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst0_m, out7); \ - \ - vec1_m = __lsx_vilvl_h(stp23_m, stp21_m); \ - vec0_m = __lsx_vilvh_h(stp23_m, stp21_m); \ - DUP2_ARG2(__lsx_vreplvei_h, coeff1_m, 4, coeff1_m, 5, cnst0_m, cnst1_m); \ - cnst0_m = __lsx_vpackev_h(cnst0_m, cnst1_m); \ - DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst0_m, out5); \ - \ - cnst0_m = __lsx_vreplvei_h(coeff2_m, 1); \ - cnst0_m = __lsx_vpackev_h(cnst1_m, cnst0_m); \ - DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst0_m, out11); \ - \ - vec1_m = __lsx_vilvl_h(stp24_m, stp31_m); \ - vec0_m = __lsx_vilvh_h(stp24_m, stp31_m); \ - DUP2_ARG2(__lsx_vreplvei_h, coeff1_m, 6, coeff1_m, 7, cnst0_m, cnst1_m); \ - cnst1_m = __lsx_vpackev_h(cnst1_m, cnst0_m); \ - \ - DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst1_m, out13); \ - \ - cnst1_m = __lsx_vreplvei_h(coeff2_m, 3); \ - cnst0_m = __lsx_vpackev_h(cnst0_m, cnst1_m); \ - DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst0_m, out3); \ - } while (0) - -void fdct8x16_1d_column(const int16_t *input, int16_t *tmp_ptr, - int32_t src_stride); -void fdct16x8_1d_row(int16_t *input, int16_t *output); -#endif // VPX_VPX_DSP_LOONGARCH_FWD_TXFM_LSX_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/idct32x32_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/idct32x32_lsx.c deleted file mode 100644 index ec07f57d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/idct32x32_lsx.c +++ /dev/null @@ -1,834 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/loongarch/fwd_txfm_lsx.h" - -#define UNPCK_UB_SH(_in, _out0, _out1) \ - do { \ - _out0 = __lsx_vsllwil_hu_bu(_in, 0); \ - _out1 = __lsx_vexth_hu_bu(_in); \ - } while (0) - -static void idct32x8_row_transpose_store(const int16_t *input, - int16_t *tmp_buf) { - __m128i m0, m1, m2, m3, m4, m5, m6, m7; - __m128i n0, n1, n2, n3, n4, n5, n6, n7; - - /* 1st & 2nd 8x8 */ - DUP4_ARG2(__lsx_vld, input, 0, input, 64, input, 128, input, 192, m0, n0, m1, - n1); - DUP4_ARG2(__lsx_vld, input, 256, input, 320, input, 384, input, 448, m2, n2, - m3, n3); - DUP4_ARG2(__lsx_vld, input, 16, input, 80, input, 144, input, 208, m4, n4, m5, - n5); - DUP4_ARG2(__lsx_vld, input, 272, input, 336, input, 400, input, 464, m6, n6, - m7, n7); - - LSX_TRANSPOSE8x8_H(m0, n0, m1, n1, m2, n2, m3, n3, m0, n0, m1, n1, m2, n2, m3, - n3); - LSX_TRANSPOSE8x8_H(m4, n4, m5, n5, m6, n6, m7, n7, m4, n4, m5, n5, m6, n6, m7, - n7); - - __lsx_vst(m0, tmp_buf, 0); - __lsx_vst(n0, tmp_buf, 16); - __lsx_vst(m1, tmp_buf, 32); - __lsx_vst(n1, tmp_buf, 48); - __lsx_vst(m2, tmp_buf, 64); - __lsx_vst(n2, tmp_buf, 80); - __lsx_vst(m3, tmp_buf, 96); - __lsx_vst(n3, tmp_buf, 112); - __lsx_vst(m4, tmp_buf, 128); - __lsx_vst(n4, tmp_buf, 144); - __lsx_vst(m5, tmp_buf, 160); - __lsx_vst(n5, tmp_buf, 176); - __lsx_vst(m6, tmp_buf, 192); - __lsx_vst(n6, tmp_buf, 208); - __lsx_vst(m7, tmp_buf, 224); - __lsx_vst(n7, tmp_buf, 240); - - /* 3rd & 4th 8x8 */ - DUP4_ARG2(__lsx_vld, input, 32, input, 96, input, 160, input, 224, m0, n0, m1, - n1); - DUP4_ARG2(__lsx_vld, input, 288, input, 352, input, 416, input, 480, m2, n2, - m3, n3); - DUP4_ARG2(__lsx_vld, input, 48, input, 112, input, 176, input, 240, m4, n4, - m5, n5); - DUP4_ARG2(__lsx_vld, input, 304, input, 368, input, 432, input, 496, m6, n6, - m7, n7); - - LSX_TRANSPOSE8x8_H(m0, n0, m1, n1, m2, n2, m3, n3, m0, n0, m1, n1, m2, n2, m3, - n3); - LSX_TRANSPOSE8x8_H(m4, n4, m5, n5, m6, n6, m7, n7, m4, n4, m5, n5, m6, n6, m7, - n7); - - __lsx_vst(m0, tmp_buf, 256); - __lsx_vst(n0, tmp_buf, 272); - __lsx_vst(m1, tmp_buf, 288); - __lsx_vst(n1, tmp_buf, 304); - __lsx_vst(m2, tmp_buf, 320); - __lsx_vst(n2, tmp_buf, 336); - __lsx_vst(m3, tmp_buf, 352); - __lsx_vst(n3, tmp_buf, 368); - __lsx_vst(m4, tmp_buf, 384); - __lsx_vst(n4, tmp_buf, 400); - __lsx_vst(m5, tmp_buf, 416); - __lsx_vst(n5, tmp_buf, 432); - __lsx_vst(m6, tmp_buf, 448); - __lsx_vst(n6, tmp_buf, 464); - __lsx_vst(m7, tmp_buf, 480); - __lsx_vst(n7, tmp_buf, 496); -} - -static void idct32x8_row_even_process_store(int16_t *tmp_buf, - int16_t *tmp_eve_buf) { - __m128i vec0, vec1, vec2, vec3, loc0, loc1, loc2, loc3; - __m128i reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; - __m128i stp0, stp1, stp2, stp3, stp4, stp5, stp6, stp7; - __m128i tmp0; - - /* Even stage 1 */ - DUP4_ARG2(__lsx_vld, tmp_buf, 0, tmp_buf, 64, tmp_buf, 128, tmp_buf, 192, - reg0, reg1, reg2, reg3); - DUP4_ARG2(__lsx_vld, tmp_buf, 256, tmp_buf, 320, tmp_buf, 384, tmp_buf, 448, - reg4, reg5, reg6, reg7); - - DOTP_CONST_PAIR(reg1, reg7, cospi_28_64, cospi_4_64, reg1, reg7); - DOTP_CONST_PAIR(reg5, reg3, cospi_12_64, cospi_20_64, reg5, reg3); - LSX_BUTTERFLY_4_H(reg1, reg7, reg3, reg5, vec1, vec3, vec2, vec0); - DOTP_CONST_PAIR(vec2, vec0, cospi_16_64, cospi_16_64, loc2, loc3); - - loc1 = vec3; - loc0 = vec1; - - DOTP_CONST_PAIR(reg0, reg4, cospi_16_64, cospi_16_64, reg0, reg4); - DOTP_CONST_PAIR(reg2, reg6, cospi_24_64, cospi_8_64, reg2, reg6); - LSX_BUTTERFLY_4_H(reg4, reg0, reg2, reg6, vec1, vec3, vec2, vec0); - LSX_BUTTERFLY_4_H(vec0, vec1, loc1, loc0, stp3, stp0, stp7, stp4); - LSX_BUTTERFLY_4_H(vec2, vec3, loc3, loc2, stp2, stp1, stp6, stp5); - - /* Even stage 2 */ - DUP4_ARG2(__lsx_vld, tmp_buf, 32, tmp_buf, 96, tmp_buf, 160, tmp_buf, 224, - reg0, reg1, reg2, reg3); - DUP4_ARG2(__lsx_vld, tmp_buf, 288, tmp_buf, 352, tmp_buf, 416, tmp_buf, 480, - reg4, reg5, reg6, reg7); - DOTP_CONST_PAIR(reg0, reg7, cospi_30_64, cospi_2_64, reg0, reg7); - DOTP_CONST_PAIR(reg4, reg3, cospi_14_64, cospi_18_64, reg4, reg3); - DOTP_CONST_PAIR(reg2, reg5, cospi_22_64, cospi_10_64, reg2, reg5); - DOTP_CONST_PAIR(reg6, reg1, cospi_6_64, cospi_26_64, reg6, reg1); - - vec0 = __lsx_vadd_h(reg0, reg4); - reg0 = __lsx_vsub_h(reg0, reg4); - reg4 = __lsx_vadd_h(reg6, reg2); - reg6 = __lsx_vsub_h(reg6, reg2); - reg2 = __lsx_vadd_h(reg1, reg5); - reg1 = __lsx_vsub_h(reg1, reg5); - reg5 = __lsx_vadd_h(reg7, reg3); - reg7 = __lsx_vsub_h(reg7, reg3); - reg3 = vec0; - - vec1 = reg2; - reg2 = __lsx_vadd_h(reg3, reg4); - reg3 = __lsx_vsub_h(reg3, reg4); - reg4 = __lsx_vsub_h(reg5, vec1); - reg5 = __lsx_vadd_h(reg5, vec1); - - tmp0 = __lsx_vneg_h(reg6); - DOTP_CONST_PAIR(reg7, reg0, cospi_24_64, cospi_8_64, reg0, reg7); - DOTP_CONST_PAIR(tmp0, reg1, cospi_24_64, cospi_8_64, reg6, reg1); - - vec0 = __lsx_vsub_h(reg0, reg6); - reg0 = __lsx_vadd_h(reg0, reg6); - vec1 = __lsx_vsub_h(reg7, reg1); - reg7 = __lsx_vadd_h(reg7, reg1); - - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, reg6, reg1); - DOTP_CONST_PAIR(reg4, reg3, cospi_16_64, cospi_16_64, reg3, reg4); - - /* Even stage 3 : Dependency on Even stage 1 & Even stage 2 */ - LSX_BUTTERFLY_4_H(stp0, stp1, reg7, reg5, loc1, loc3, loc2, loc0); - __lsx_vst(loc0, tmp_eve_buf, 240); - __lsx_vst(loc1, tmp_eve_buf, 0); - __lsx_vst(loc2, tmp_eve_buf, 224); - __lsx_vst(loc3, tmp_eve_buf, 16); - - LSX_BUTTERFLY_4_H(stp2, stp3, reg4, reg1, loc1, loc3, loc2, loc0); - __lsx_vst(loc0, tmp_eve_buf, 208); - __lsx_vst(loc1, tmp_eve_buf, 32); - __lsx_vst(loc2, tmp_eve_buf, 192); - __lsx_vst(loc3, tmp_eve_buf, 48); - - /* Store 8 */ - LSX_BUTTERFLY_4_H(stp4, stp5, reg6, reg3, loc1, loc3, loc2, loc0); - __lsx_vst(loc0, tmp_eve_buf, 176); - __lsx_vst(loc1, tmp_eve_buf, 64); - __lsx_vst(loc2, tmp_eve_buf, 160); - __lsx_vst(loc3, tmp_eve_buf, 80); - - LSX_BUTTERFLY_4_H(stp6, stp7, reg2, reg0, loc1, loc3, loc2, loc0); - __lsx_vst(loc0, tmp_eve_buf, 144); - __lsx_vst(loc1, tmp_eve_buf, 96); - __lsx_vst(loc2, tmp_eve_buf, 128); - __lsx_vst(loc3, tmp_eve_buf, 112); -} - -static void idct32x8_row_odd_process_store(int16_t *tmp_buf, - int16_t *tmp_odd_buf) { - __m128i vec0, vec1, vec2, vec3, loc0, loc1, loc2, loc3; - __m128i reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; - - /* Odd stage 1 */ - DUP4_ARG2(__lsx_vld, tmp_buf, 16, tmp_buf, 112, tmp_buf, 144, tmp_buf, 240, - reg0, reg1, reg2, reg3); - DUP4_ARG2(__lsx_vld, tmp_buf, 272, tmp_buf, 368, tmp_buf, 400, tmp_buf, 496, - reg4, reg5, reg6, reg7); - - DOTP_CONST_PAIR(reg0, reg7, cospi_31_64, cospi_1_64, reg0, reg7); - DOTP_CONST_PAIR(reg4, reg3, cospi_15_64, cospi_17_64, reg3, reg4); - DOTP_CONST_PAIR(reg2, reg5, cospi_23_64, cospi_9_64, reg2, reg5); - DOTP_CONST_PAIR(reg6, reg1, cospi_7_64, cospi_25_64, reg1, reg6); - - vec0 = __lsx_vadd_h(reg0, reg3); - reg0 = __lsx_vsub_h(reg0, reg3); - reg3 = __lsx_vadd_h(reg7, reg4); - reg7 = __lsx_vsub_h(reg7, reg4); - reg4 = __lsx_vadd_h(reg1, reg2); - reg1 = __lsx_vsub_h(reg1, reg2); - reg2 = __lsx_vadd_h(reg6, reg5); - reg6 = __lsx_vsub_h(reg6, reg5); - reg5 = vec0; - - /* 4 Stores */ - DUP2_ARG2(__lsx_vadd_h, reg5, reg4, reg3, reg2, vec0, vec1); - __lsx_vst(vec0, tmp_odd_buf, 64); - __lsx_vst(vec1, tmp_odd_buf, 80); - - DUP2_ARG2(__lsx_vsub_h, reg5, reg4, reg3, reg2, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_24_64, cospi_8_64, vec0, vec1); - __lsx_vst(vec0, tmp_odd_buf, 0); - __lsx_vst(vec1, tmp_odd_buf, 16); - - /* 4 Stores */ - DOTP_CONST_PAIR(reg7, reg0, cospi_28_64, cospi_4_64, reg0, reg7); - DOTP_CONST_PAIR(reg6, reg1, -cospi_4_64, cospi_28_64, reg1, reg6); - LSX_BUTTERFLY_4_H(reg0, reg7, reg6, reg1, vec0, vec1, vec2, vec3); - __lsx_vst(vec0, tmp_odd_buf, 96); - __lsx_vst(vec1, tmp_odd_buf, 112); - - DOTP_CONST_PAIR(vec2, vec3, cospi_24_64, cospi_8_64, vec2, vec3); - __lsx_vst(vec2, tmp_odd_buf, 32); - __lsx_vst(vec3, tmp_odd_buf, 48); - - /* Odd stage 2 */ - /* 8 loads */ - DUP4_ARG2(__lsx_vld, tmp_buf, 48, tmp_buf, 80, tmp_buf, 176, tmp_buf, 208, - reg0, reg1, reg2, reg3); - DUP4_ARG2(__lsx_vld, tmp_buf, 304, tmp_buf, 336, tmp_buf, 432, tmp_buf, 464, - reg4, reg5, reg6, reg7); - - DOTP_CONST_PAIR(reg1, reg6, cospi_27_64, cospi_5_64, reg1, reg6); - DOTP_CONST_PAIR(reg5, reg2, cospi_11_64, cospi_21_64, reg2, reg5); - DOTP_CONST_PAIR(reg3, reg4, cospi_19_64, cospi_13_64, reg3, reg4); - DOTP_CONST_PAIR(reg7, reg0, cospi_3_64, cospi_29_64, reg0, reg7); - - /* 4 Stores */ - DUP4_ARG2(__lsx_vsub_h, reg1, reg2, reg6, reg5, reg0, reg3, reg7, reg4, vec0, - vec1, vec2, vec3); - DOTP_CONST_PAIR(vec1, vec0, cospi_12_64, cospi_20_64, loc0, loc1); - DOTP_CONST_PAIR(vec3, vec2, -cospi_20_64, cospi_12_64, loc2, loc3); - - LSX_BUTTERFLY_4_H(loc3, loc2, loc0, loc1, vec1, vec0, vec2, vec3); - __lsx_vst(vec0, tmp_odd_buf, 192); - __lsx_vst(vec1, tmp_odd_buf, 240); - - DOTP_CONST_PAIR(vec3, vec2, -cospi_8_64, cospi_24_64, vec0, vec1); - __lsx_vst(vec0, tmp_odd_buf, 160); - __lsx_vst(vec1, tmp_odd_buf, 176); - - /* 4 Stores */ - DUP4_ARG2(__lsx_vadd_h, reg1, reg2, reg6, reg5, reg0, reg3, reg7, reg4, vec1, - vec2, vec0, vec3); - LSX_BUTTERFLY_4_H(vec0, vec3, vec2, vec1, reg0, reg1, reg3, reg2); - __lsx_vst(reg0, tmp_odd_buf, 208); - __lsx_vst(reg1, tmp_odd_buf, 224); - - DOTP_CONST_PAIR(reg3, reg2, -cospi_8_64, cospi_24_64, reg0, reg1); - __lsx_vst(reg0, tmp_odd_buf, 128); - __lsx_vst(reg1, tmp_odd_buf, 144); - - /* Odd stage 3 : Dependency on Odd stage 1 & Odd stage 2 */ - - /* Load 8 & Store 8 */ - DUP4_ARG2(__lsx_vld, tmp_odd_buf, 0, tmp_odd_buf, 16, tmp_odd_buf, 32, - tmp_odd_buf, 48, reg0, reg1, reg2, reg3); - DUP4_ARG2(__lsx_vld, tmp_odd_buf, 128, tmp_odd_buf, 144, tmp_odd_buf, 160, - tmp_odd_buf, 176, reg4, reg5, reg6, reg7); - DUP4_ARG2(__lsx_vadd_h, reg0, reg4, reg1, reg5, reg2, reg6, reg3, reg7, loc0, - loc1, loc2, loc3); - __lsx_vst(loc0, tmp_odd_buf, 0); - __lsx_vst(loc1, tmp_odd_buf, 16); - __lsx_vst(loc2, tmp_odd_buf, 32); - __lsx_vst(loc3, tmp_odd_buf, 48); - - DUP2_ARG2(__lsx_vsub_h, reg0, reg4, reg1, reg5, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, loc0, loc1); - - DUP2_ARG2(__lsx_vsub_h, reg2, reg6, reg3, reg7, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, loc2, loc3); - __lsx_vst(loc0, tmp_odd_buf, 128); - __lsx_vst(loc1, tmp_odd_buf, 144); - __lsx_vst(loc2, tmp_odd_buf, 160); - __lsx_vst(loc3, tmp_odd_buf, 176); - - /* Load 8 & Store 8 */ - DUP4_ARG2(__lsx_vld, tmp_odd_buf, 64, tmp_odd_buf, 80, tmp_odd_buf, 96, - tmp_odd_buf, 112, reg1, reg2, reg0, reg3); - DUP4_ARG2(__lsx_vld, tmp_odd_buf, 192, tmp_odd_buf, 208, tmp_odd_buf, 224, - tmp_odd_buf, 240, reg4, reg5, reg6, reg7); - - DUP4_ARG2(__lsx_vadd_h, reg0, reg4, reg1, reg5, reg2, reg6, reg3, reg7, loc0, - loc1, loc2, loc3); - __lsx_vst(loc0, tmp_odd_buf, 64); - __lsx_vst(loc1, tmp_odd_buf, 80); - __lsx_vst(loc2, tmp_odd_buf, 96); - __lsx_vst(loc3, tmp_odd_buf, 112); - - DUP2_ARG2(__lsx_vsub_h, reg0, reg4, reg3, reg7, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, loc0, loc1); - DUP2_ARG2(__lsx_vsub_h, reg1, reg5, reg2, reg6, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, loc2, loc3); - __lsx_vst(loc0, tmp_odd_buf, 192); - __lsx_vst(loc1, tmp_odd_buf, 208); - __lsx_vst(loc2, tmp_odd_buf, 224); - __lsx_vst(loc3, tmp_odd_buf, 240); -} - -static void idct_butterfly_transpose_store(int16_t *tmp_buf, - int16_t *tmp_eve_buf, - int16_t *tmp_odd_buf, int16_t *dst) { - __m128i vec0, vec1, vec2, vec3, loc0, loc1, loc2, loc3; - __m128i m0, m1, m2, m3, m4, m5, m6, m7; - __m128i n0, n1, n2, n3, n4, n5, n6, n7; - __m128i reg0, reg1, reg2, reg3; - - /* FINAL BUTTERFLY : Dependency on Even & Odd */ - DUP4_ARG2(__lsx_vld, tmp_odd_buf, 0, tmp_odd_buf, 144, tmp_odd_buf, 224, - tmp_odd_buf, 96, vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vld, tmp_eve_buf, 0, tmp_eve_buf, 128, tmp_eve_buf, 64, - tmp_eve_buf, 192, loc0, loc1, loc2, loc3); - - DUP4_ARG2(__lsx_vadd_h, loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, m0, - m4, m2, m6); - DUP4_ARG2(__lsx_vsub_h, loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, reg0, - reg1, reg2, reg3); - __lsx_vst(reg0, tmp_buf, 496); - __lsx_vst(reg1, tmp_buf, 368); - __lsx_vst(reg2, tmp_buf, 432); - __lsx_vst(reg3, tmp_buf, 304); - - /* Load 8 & Store 8 */ - DUP4_ARG2(__lsx_vld, tmp_odd_buf, 64, tmp_odd_buf, 208, tmp_odd_buf, 160, - tmp_odd_buf, 48, vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vld, tmp_eve_buf, 32, tmp_eve_buf, 160, tmp_eve_buf, 96, - tmp_eve_buf, 224, loc0, loc1, loc2, loc3); - - DUP4_ARG2(__lsx_vadd_h, loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, m1, - m5, m3, m7); - DUP4_ARG2(__lsx_vsub_h, loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, reg0, - reg1, reg2, reg3); - __lsx_vst(reg0, tmp_buf, 464); - __lsx_vst(reg1, tmp_buf, 336); - __lsx_vst(reg2, tmp_buf, 400); - __lsx_vst(reg3, tmp_buf, 272); - - /* Load 8 & Store 8 */ - DUP4_ARG2(__lsx_vld, tmp_odd_buf, 32, tmp_odd_buf, 176, tmp_odd_buf, 192, - tmp_odd_buf, 112, vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vld, tmp_eve_buf, 16, tmp_eve_buf, 144, tmp_eve_buf, 80, - tmp_eve_buf, 208, loc0, loc1, loc2, loc3); - - DUP4_ARG2(__lsx_vadd_h, loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, n0, - n4, n2, n6); - DUP4_ARG2(__lsx_vsub_h, loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, reg0, - reg1, reg2, reg3); - __lsx_vst(reg0, tmp_buf, 480); - __lsx_vst(reg1, tmp_buf, 352); - __lsx_vst(reg2, tmp_buf, 416); - __lsx_vst(reg3, tmp_buf, 288); - - /* Load 8 & Store 8 */ - DUP4_ARG2(__lsx_vld, tmp_odd_buf, 80, tmp_odd_buf, 240, tmp_odd_buf, 128, - tmp_odd_buf, 16, vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vld, tmp_eve_buf, 48, tmp_eve_buf, 176, tmp_eve_buf, 112, - tmp_eve_buf, 240, loc0, loc1, loc2, loc3); - DUP4_ARG2(__lsx_vadd_h, loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, n1, - n5, n3, n7); - DUP4_ARG2(__lsx_vsub_h, loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, reg0, - reg1, reg2, reg3); - __lsx_vst(reg0, tmp_buf, 448); - __lsx_vst(reg1, tmp_buf, 320); - __lsx_vst(reg2, tmp_buf, 384); - __lsx_vst(reg3, tmp_buf, 256); - - /* Transpose : 16 vectors */ - /* 1st & 2nd 8x8 */ - LSX_TRANSPOSE8x8_H(m0, n0, m1, n1, m2, n2, m3, n3, m0, n0, m1, n1, m2, n2, m3, - n3); - __lsx_vst(m0, dst, 0); - __lsx_vst(n0, dst, 64); - __lsx_vst(m1, dst, 128); - __lsx_vst(n1, dst, 192); - __lsx_vst(m2, dst, 256); - __lsx_vst(n2, dst, 320); - __lsx_vst(m3, dst, 384); - __lsx_vst(n3, dst, 448); - - LSX_TRANSPOSE8x8_H(m4, n4, m5, n5, m6, n6, m7, n7, m4, n4, m5, n5, m6, n6, m7, - n7); - __lsx_vst(m4, dst, 16); - __lsx_vst(n4, dst, 80); - __lsx_vst(m5, dst, 144); - __lsx_vst(n5, dst, 208); - __lsx_vst(m6, dst, 272); - __lsx_vst(n6, dst, 336); - __lsx_vst(m7, dst, 400); - __lsx_vst(n7, dst, 464); - - /* 3rd & 4th 8x8 */ - DUP4_ARG2(__lsx_vld, tmp_buf, 256, tmp_buf, 272, tmp_buf, 288, tmp_buf, 304, - m0, n0, m1, n1); - DUP4_ARG2(__lsx_vld, tmp_buf, 320, tmp_buf, 336, tmp_buf, 352, tmp_buf, 368, - m2, n2, m3, n3); - DUP4_ARG2(__lsx_vld, tmp_buf, 384, tmp_buf, 400, tmp_buf, 416, tmp_buf, 432, - m4, n4, m5, n5); - DUP4_ARG2(__lsx_vld, tmp_buf, 448, tmp_buf, 464, tmp_buf, 480, tmp_buf, 496, - m6, n6, m7, n7); - LSX_TRANSPOSE8x8_H(m0, n0, m1, n1, m2, n2, m3, n3, m0, n0, m1, n1, m2, n2, m3, - n3); - LSX_TRANSPOSE8x8_H(m4, n4, m5, n5, m6, n6, m7, n7, m4, n4, m5, n5, m6, n6, m7, - n7); - __lsx_vst(m0, dst, 32); - __lsx_vst(n0, dst, 96); - __lsx_vst(m1, dst, 160); - __lsx_vst(n1, dst, 224); - __lsx_vst(m2, dst, 288); - __lsx_vst(n2, dst, 352); - __lsx_vst(m3, dst, 416); - __lsx_vst(n3, dst, 480); - __lsx_vst(m4, dst, 48); - __lsx_vst(n4, dst, 112); - __lsx_vst(m5, dst, 176); - __lsx_vst(n5, dst, 240); - __lsx_vst(m6, dst, 304); - __lsx_vst(n6, dst, 368); - __lsx_vst(m7, dst, 432); - __lsx_vst(n7, dst, 496); -} - -static void idct32x8_1d_rows_lsx(const int16_t *input, int16_t *output) { - DECLARE_ALIGNED(32, int16_t, tmp_buf[8 * 32]); - DECLARE_ALIGNED(32, int16_t, tmp_odd_buf[16 * 8]); - DECLARE_ALIGNED(32, int16_t, tmp_eve_buf[16 * 8]); - - idct32x8_row_transpose_store(input, &tmp_buf[0]); - idct32x8_row_even_process_store(&tmp_buf[0], &tmp_eve_buf[0]); - idct32x8_row_odd_process_store(&tmp_buf[0], &tmp_odd_buf[0]); - idct_butterfly_transpose_store(&tmp_buf[0], &tmp_eve_buf[0], &tmp_odd_buf[0], - output); -} - -static void idct8x32_column_even_process_store(int16_t *tmp_buf, - int16_t *tmp_eve_buf) { - __m128i vec0, vec1, vec2, vec3, loc0, loc1, loc2, loc3; - __m128i reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; - __m128i stp0, stp1, stp2, stp3, stp4, stp5, stp6, stp7; - __m128i tmp0; - - /* Even stage 1 */ - DUP4_ARG2(__lsx_vld, tmp_buf, 0, tmp_buf, 256, tmp_buf, 512, tmp_buf, 768, - reg0, reg1, reg2, reg3); - DUP4_ARG2(__lsx_vld, tmp_buf, 1024, tmp_buf, 1280, tmp_buf, 1536, tmp_buf, - 1792, reg4, reg5, reg6, reg7); - tmp_buf += 64; - - DOTP_CONST_PAIR(reg1, reg7, cospi_28_64, cospi_4_64, reg1, reg7); - DOTP_CONST_PAIR(reg5, reg3, cospi_12_64, cospi_20_64, reg5, reg3); - LSX_BUTTERFLY_4_H(reg1, reg7, reg3, reg5, vec1, vec3, vec2, vec0); - DOTP_CONST_PAIR(vec2, vec0, cospi_16_64, cospi_16_64, loc2, loc3); - - loc1 = vec3; - loc0 = vec1; - - DOTP_CONST_PAIR(reg0, reg4, cospi_16_64, cospi_16_64, reg0, reg4); - DOTP_CONST_PAIR(reg2, reg6, cospi_24_64, cospi_8_64, reg2, reg6); - LSX_BUTTERFLY_4_H(reg4, reg0, reg2, reg6, vec1, vec3, vec2, vec0); - LSX_BUTTERFLY_4_H(vec0, vec1, loc1, loc0, stp3, stp0, stp7, stp4); - LSX_BUTTERFLY_4_H(vec2, vec3, loc3, loc2, stp2, stp1, stp6, stp5); - - /* Even stage 2 */ - /* Load 8 */ - DUP4_ARG2(__lsx_vld, tmp_buf, 0, tmp_buf, 256, tmp_buf, 512, tmp_buf, 768, - reg0, reg1, reg2, reg3); - DUP4_ARG2(__lsx_vld, tmp_buf, 1024, tmp_buf, 1280, tmp_buf, 1536, tmp_buf, - 1792, reg4, reg5, reg6, reg7); - DOTP_CONST_PAIR(reg0, reg7, cospi_30_64, cospi_2_64, reg0, reg7); - DOTP_CONST_PAIR(reg4, reg3, cospi_14_64, cospi_18_64, reg4, reg3); - DOTP_CONST_PAIR(reg2, reg5, cospi_22_64, cospi_10_64, reg2, reg5); - DOTP_CONST_PAIR(reg6, reg1, cospi_6_64, cospi_26_64, reg6, reg1); - - vec0 = __lsx_vadd_h(reg0, reg4); - reg0 = __lsx_vsub_h(reg0, reg4); - reg4 = __lsx_vadd_h(reg6, reg2); - reg6 = __lsx_vsub_h(reg6, reg2); - reg2 = __lsx_vadd_h(reg1, reg5); - reg1 = __lsx_vsub_h(reg1, reg5); - reg5 = __lsx_vadd_h(reg7, reg3); - reg7 = __lsx_vsub_h(reg7, reg3); - reg3 = vec0; - - vec1 = reg2; - reg2 = __lsx_vadd_h(reg3, reg4); - reg3 = __lsx_vsub_h(reg3, reg4); - reg4 = __lsx_vsub_h(reg5, vec1); - reg5 = __lsx_vadd_h(reg5, vec1); - - tmp0 = __lsx_vneg_h(reg6); - DOTP_CONST_PAIR(reg7, reg0, cospi_24_64, cospi_8_64, reg0, reg7); - DOTP_CONST_PAIR(tmp0, reg1, cospi_24_64, cospi_8_64, reg6, reg1); - - vec0 = __lsx_vsub_h(reg0, reg6); - reg0 = __lsx_vadd_h(reg0, reg6); - vec1 = __lsx_vsub_h(reg7, reg1); - reg7 = __lsx_vadd_h(reg7, reg1); - - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, reg6, reg1); - DOTP_CONST_PAIR(reg4, reg3, cospi_16_64, cospi_16_64, reg3, reg4); - - /* Even stage 3 : Dependency on Even stage 1 & Even stage 2 */ - /* Store 8 */ - LSX_BUTTERFLY_4_H(stp0, stp1, reg7, reg5, loc1, loc3, loc2, loc0); - __lsx_vst(loc1, tmp_eve_buf, 0); - __lsx_vst(loc3, tmp_eve_buf, 16); - __lsx_vst(loc2, tmp_eve_buf, 224); - __lsx_vst(loc0, tmp_eve_buf, 240); - - LSX_BUTTERFLY_4_H(stp2, stp3, reg4, reg1, loc1, loc3, loc2, loc0); - __lsx_vst(loc1, tmp_eve_buf, 32); - __lsx_vst(loc3, tmp_eve_buf, 48); - __lsx_vst(loc2, tmp_eve_buf, 192); - __lsx_vst(loc0, tmp_eve_buf, 208); - - /* Store 8 */ - LSX_BUTTERFLY_4_H(stp4, stp5, reg6, reg3, loc1, loc3, loc2, loc0); - __lsx_vst(loc1, tmp_eve_buf, 64); - __lsx_vst(loc3, tmp_eve_buf, 80); - __lsx_vst(loc2, tmp_eve_buf, 160); - __lsx_vst(loc0, tmp_eve_buf, 176); - - LSX_BUTTERFLY_4_H(stp6, stp7, reg2, reg0, loc1, loc3, loc2, loc0); - __lsx_vst(loc1, tmp_eve_buf, 96); - __lsx_vst(loc3, tmp_eve_buf, 112); - __lsx_vst(loc2, tmp_eve_buf, 128); - __lsx_vst(loc0, tmp_eve_buf, 144); -} - -static void idct8x32_column_odd_process_store(int16_t *tmp_buf, - int16_t *tmp_odd_buf) { - __m128i vec0, vec1, vec2, vec3, loc0, loc1, loc2, loc3; - __m128i reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; - - /* Odd stage 1 */ - DUP4_ARG2(__lsx_vld, tmp_buf, 64, tmp_buf, 448, tmp_buf, 576, tmp_buf, 960, - reg0, reg1, reg2, reg3); - DUP4_ARG2(__lsx_vld, tmp_buf, 1088, tmp_buf, 1472, tmp_buf, 1600, tmp_buf, - 1984, reg4, reg5, reg6, reg7); - - DOTP_CONST_PAIR(reg0, reg7, cospi_31_64, cospi_1_64, reg0, reg7); - DOTP_CONST_PAIR(reg4, reg3, cospi_15_64, cospi_17_64, reg3, reg4); - DOTP_CONST_PAIR(reg2, reg5, cospi_23_64, cospi_9_64, reg2, reg5); - DOTP_CONST_PAIR(reg6, reg1, cospi_7_64, cospi_25_64, reg1, reg6); - - vec0 = __lsx_vadd_h(reg0, reg3); - reg0 = __lsx_vsub_h(reg0, reg3); - reg3 = __lsx_vadd_h(reg7, reg4); - reg7 = __lsx_vsub_h(reg7, reg4); - reg4 = __lsx_vadd_h(reg1, reg2); - reg1 = __lsx_vsub_h(reg1, reg2); - reg2 = __lsx_vadd_h(reg6, reg5); - reg6 = __lsx_vsub_h(reg6, reg5); - reg5 = vec0; - - /* 4 Stores */ - DUP2_ARG2(__lsx_vadd_h, reg5, reg4, reg3, reg2, vec0, vec1); - __lsx_vst(vec0, tmp_odd_buf, 64); - __lsx_vst(vec1, tmp_odd_buf, 80); - DUP2_ARG2(__lsx_vsub_h, reg5, reg4, reg3, reg2, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_24_64, cospi_8_64, vec0, vec1); - __lsx_vst(vec0, tmp_odd_buf, 0); - __lsx_vst(vec1, tmp_odd_buf, 16); - - /* 4 Stores */ - DOTP_CONST_PAIR(reg7, reg0, cospi_28_64, cospi_4_64, reg0, reg7); - DOTP_CONST_PAIR(reg6, reg1, -cospi_4_64, cospi_28_64, reg1, reg6); - LSX_BUTTERFLY_4_H(reg0, reg7, reg6, reg1, vec0, vec1, vec2, vec3); - DOTP_CONST_PAIR(vec2, vec3, cospi_24_64, cospi_8_64, vec2, vec3); - __lsx_vst(vec0, tmp_odd_buf, 96); - __lsx_vst(vec1, tmp_odd_buf, 112); - __lsx_vst(vec2, tmp_odd_buf, 32); - __lsx_vst(vec3, tmp_odd_buf, 48); - - /* Odd stage 2 */ - /* 8 loads */ - DUP4_ARG2(__lsx_vld, tmp_buf, 192, tmp_buf, 320, tmp_buf, 704, tmp_buf, 832, - reg0, reg1, reg2, reg3); - DUP4_ARG2(__lsx_vld, tmp_buf, 1216, tmp_buf, 1344, tmp_buf, 1728, tmp_buf, - 1856, reg4, reg5, reg6, reg7); - DOTP_CONST_PAIR(reg1, reg6, cospi_27_64, cospi_5_64, reg1, reg6); - DOTP_CONST_PAIR(reg5, reg2, cospi_11_64, cospi_21_64, reg2, reg5); - DOTP_CONST_PAIR(reg3, reg4, cospi_19_64, cospi_13_64, reg3, reg4); - DOTP_CONST_PAIR(reg7, reg0, cospi_3_64, cospi_29_64, reg0, reg7); - - /* 4 Stores */ - DUP4_ARG2(__lsx_vsub_h, reg1, reg2, reg6, reg5, reg0, reg3, reg7, reg4, vec0, - vec1, vec2, vec3); - DOTP_CONST_PAIR(vec1, vec0, cospi_12_64, cospi_20_64, loc0, loc1); - DOTP_CONST_PAIR(vec3, vec2, -cospi_20_64, cospi_12_64, loc2, loc3); - LSX_BUTTERFLY_4_H(loc2, loc3, loc1, loc0, vec0, vec1, vec3, vec2); - __lsx_vst(vec0, tmp_odd_buf, 192); - __lsx_vst(vec1, tmp_odd_buf, 240); - DOTP_CONST_PAIR(vec3, vec2, -cospi_8_64, cospi_24_64, vec0, vec1); - __lsx_vst(vec0, tmp_odd_buf, 160); - __lsx_vst(vec1, tmp_odd_buf, 176); - - /* 4 Stores */ - DUP4_ARG2(__lsx_vadd_h, reg0, reg3, reg1, reg2, reg5, reg6, reg4, reg7, vec0, - vec1, vec2, vec3); - LSX_BUTTERFLY_4_H(vec0, vec3, vec2, vec1, reg0, reg1, reg3, reg2); - __lsx_vst(reg0, tmp_odd_buf, 208); - __lsx_vst(reg1, tmp_odd_buf, 224); - DOTP_CONST_PAIR(reg3, reg2, -cospi_8_64, cospi_24_64, reg0, reg1); - __lsx_vst(reg0, tmp_odd_buf, 128); - __lsx_vst(reg1, tmp_odd_buf, 144); - - /* Odd stage 3 : Dependency on Odd stage 1 & Odd stage 2 */ - /* Load 8 & Store 8 */ - DUP4_ARG2(__lsx_vld, tmp_odd_buf, 0, tmp_odd_buf, 16, tmp_odd_buf, 32, - tmp_odd_buf, 48, reg0, reg1, reg2, reg3); - DUP4_ARG2(__lsx_vld, tmp_odd_buf, 128, tmp_odd_buf, 144, tmp_odd_buf, 160, - tmp_odd_buf, 176, reg4, reg5, reg6, reg7); - DUP4_ARG2(__lsx_vadd_h, reg0, reg4, reg1, reg5, reg2, reg6, reg3, reg7, loc0, - loc1, loc2, loc3); - __lsx_vst(loc0, tmp_odd_buf, 0); - __lsx_vst(loc1, tmp_odd_buf, 16); - __lsx_vst(loc2, tmp_odd_buf, 32); - __lsx_vst(loc3, tmp_odd_buf, 48); - - DUP2_ARG2(__lsx_vsub_h, reg0, reg4, reg1, reg5, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, loc0, loc1); - DUP2_ARG2(__lsx_vsub_h, reg2, reg6, reg3, reg7, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, loc2, loc3); - __lsx_vst(loc0, tmp_odd_buf, 128); - __lsx_vst(loc1, tmp_odd_buf, 144); - __lsx_vst(loc2, tmp_odd_buf, 160); - __lsx_vst(loc3, tmp_odd_buf, 176); - - /* Load 8 & Store 8 */ - DUP4_ARG2(__lsx_vld, tmp_odd_buf, 64, tmp_odd_buf, 80, tmp_odd_buf, 96, - tmp_odd_buf, 112, reg1, reg2, reg0, reg3); - DUP4_ARG2(__lsx_vld, tmp_odd_buf, 192, tmp_odd_buf, 208, tmp_odd_buf, 224, - tmp_odd_buf, 240, reg4, reg5, reg6, reg7); - DUP4_ARG2(__lsx_vadd_h, reg0, reg4, reg1, reg5, reg2, reg6, reg3, reg7, loc0, - loc1, loc2, loc3); - __lsx_vst(loc0, tmp_odd_buf, 64); - __lsx_vst(loc1, tmp_odd_buf, 80); - __lsx_vst(loc2, tmp_odd_buf, 96); - __lsx_vst(loc3, tmp_odd_buf, 112); - - DUP2_ARG2(__lsx_vsub_h, reg0, reg4, reg3, reg7, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, loc0, loc1); - DUP2_ARG2(__lsx_vsub_h, reg1, reg5, reg2, reg6, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, loc2, loc3); - __lsx_vst(loc0, tmp_odd_buf, 192); - __lsx_vst(loc1, tmp_odd_buf, 208); - __lsx_vst(loc2, tmp_odd_buf, 224); - __lsx_vst(loc3, tmp_odd_buf, 240); -} - -static void idct8x32_column_butterfly_addblk(int16_t *tmp_eve_buf, - int16_t *tmp_odd_buf, uint8_t *dst, - int32_t dst_stride) { - __m128i vec0, vec1, vec2, vec3, loc0, loc1, loc2, loc3; - __m128i m0, m1, m2, m3, m4, m5, m6, m7; - __m128i n0, n1, n2, n3, n4, n5, n6, n7; - int32_t stride = dst_stride << 2; - int32_t stride2 = stride << 1; - int32_t stride3 = stride + stride2; - - /* FINAL BUTTERFLY : Dependency on Even & Odd */ - DUP4_ARG2(__lsx_vld, tmp_odd_buf, 0, tmp_odd_buf, 144, tmp_odd_buf, 224, - tmp_odd_buf, 96, vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vld, tmp_eve_buf, 0, tmp_eve_buf, 128, tmp_eve_buf, 64, - tmp_eve_buf, 192, loc0, loc1, loc2, loc3); - - DUP4_ARG2(__lsx_vadd_h, loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, m0, - m4, m2, m6); - DUP4_ARG2(__lsx_vsrari_h, m0, 6, m2, 6, m4, 6, m6, 6, m0, m2, m4, m6); - VP9_ADDBLK_ST8x4_UB(dst, stride, stride2, stride3, m0, m2, m4, m6); - DUP4_ARG2(__lsx_vsub_h, loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, m6, - m2, m4, m0); - DUP4_ARG2(__lsx_vsrari_h, m0, 6, m2, 6, m4, 6, m6, 6, m0, m2, m4, m6); - VP9_ADDBLK_ST8x4_UB((dst + 19 * dst_stride), stride, stride2, stride3, m0, m2, - m4, m6); - - /* Load 8 & Store 8 */ - DUP4_ARG2(__lsx_vld, tmp_odd_buf, 64, tmp_odd_buf, 208, tmp_odd_buf, 160, - tmp_odd_buf, 48, vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vld, tmp_eve_buf, 32, tmp_eve_buf, 160, tmp_eve_buf, 96, - tmp_eve_buf, 224, loc0, loc1, loc2, loc3); - - DUP4_ARG2(__lsx_vadd_h, loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, m1, - m5, m3, m7); - DUP4_ARG2(__lsx_vsrari_h, m1, 6, m3, 6, m5, 6, m7, 6, m1, m3, m5, m7); - VP9_ADDBLK_ST8x4_UB((dst + 2 * dst_stride), stride, stride2, stride3, m1, m3, - m5, m7); - DUP4_ARG2(__lsx_vsub_h, loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, m7, - m3, m5, m1); - DUP4_ARG2(__lsx_vsrari_h, m1, 6, m3, 6, m5, 6, m7, 6, m1, m3, m5, m7); - VP9_ADDBLK_ST8x4_UB((dst + 17 * dst_stride), stride, stride2, stride3, m1, m3, - m5, m7); - - /* Load 8 & Store 8 */ - DUP4_ARG2(__lsx_vld, tmp_odd_buf, 32, tmp_odd_buf, 176, tmp_odd_buf, 192, - tmp_odd_buf, 112, vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vld, tmp_eve_buf, 16, tmp_eve_buf, 144, tmp_eve_buf, 80, - tmp_eve_buf, 208, loc0, loc1, loc2, loc3); - DUP4_ARG2(__lsx_vadd_h, loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, n0, - n4, n2, n6); - DUP4_ARG2(__lsx_vsrari_h, n0, 6, n2, 6, n4, 6, n6, 6, n0, n2, n4, n6); - VP9_ADDBLK_ST8x4_UB((dst + dst_stride), stride, stride2, stride3, n0, n2, n4, - n6); - DUP4_ARG2(__lsx_vsub_h, loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, n6, - n2, n4, n0); - DUP4_ARG2(__lsx_vsrari_h, n0, 6, n2, 6, n4, 6, n6, 6, n0, n2, n4, n6); - VP9_ADDBLK_ST8x4_UB((dst + 18 * dst_stride), stride, stride2, stride3, n0, n2, - n4, n6); - - /* Load 8 & Store 8 */ - DUP4_ARG2(__lsx_vld, tmp_odd_buf, 80, tmp_odd_buf, 240, tmp_odd_buf, 128, - tmp_odd_buf, 16, vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vld, tmp_eve_buf, 48, tmp_eve_buf, 176, tmp_eve_buf, 112, - tmp_eve_buf, 240, loc0, loc1, loc2, loc3); - DUP4_ARG2(__lsx_vadd_h, loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, n1, - n5, n3, n7); - DUP4_ARG2(__lsx_vsrari_h, n1, 6, n3, 6, n5, 6, n7, 6, n1, n3, n5, n7); - VP9_ADDBLK_ST8x4_UB((dst + 3 * dst_stride), stride, stride2, stride3, n1, n3, - n5, n7); - DUP4_ARG2(__lsx_vsub_h, loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, n7, - n3, n5, n1); - DUP4_ARG2(__lsx_vsrari_h, n1, 6, n3, 6, n5, 6, n7, 6, n1, n3, n5, n7); - VP9_ADDBLK_ST8x4_UB((dst + 16 * dst_stride), stride, stride2, stride3, n1, n3, - n5, n7); -} - -static void idct8x32_1d_columns_addblk_lsx(int16_t *input, uint8_t *dst, - int32_t dst_stride) { - DECLARE_ALIGNED(32, int16_t, tmp_odd_buf[16 * 8]); - DECLARE_ALIGNED(32, int16_t, tmp_eve_buf[16 * 8]); - - idct8x32_column_even_process_store(input, &tmp_eve_buf[0]); - idct8x32_column_odd_process_store(input, &tmp_odd_buf[0]); - idct8x32_column_butterfly_addblk(&tmp_eve_buf[0], &tmp_odd_buf[0], dst, - dst_stride); -} - -void vpx_idct32x32_1024_add_lsx(const int16_t *input, uint8_t *dst, - int32_t dst_stride) { - int32_t i; - DECLARE_ALIGNED(32, int16_t, out_arr[32 * 32]); - int16_t *out_ptr = out_arr; - - /* transform rows */ - for (i = 0; i < 4; ++i) { - /* process 32 * 8 block */ - idct32x8_1d_rows_lsx((input + (i << 8)), (out_ptr + (i << 8))); - } - - for (i = 0; i < 4; ++i) { - /* process 8 * 32 block */ - idct8x32_1d_columns_addblk_lsx((out_ptr + (i << 3)), (dst + (i << 3)), - dst_stride); - } -} - -void vpx_idct32x32_34_add_lsx(const int16_t *input, uint8_t *dst, - int32_t dst_stride) { - int32_t i; - DECLARE_ALIGNED(32, int16_t, out_arr[32 * 32]); - int16_t *out_ptr = out_arr; - __m128i zero = __lsx_vldi(0); - - for (i = 32; i--;) { - __lsx_vst(zero, out_ptr, 0); - __lsx_vst(zero, out_ptr, 16); - __lsx_vst(zero, out_ptr, 32); - __lsx_vst(zero, out_ptr, 48); - out_ptr += 32; - } - - out_ptr = out_arr; - - /* rows: only upper-left 8x8 has non-zero coeff */ - idct32x8_1d_rows_lsx(input, out_ptr); - - /* transform columns */ - for (i = 0; i < 4; ++i) { - /* process 8 * 32 block */ - idct8x32_1d_columns_addblk_lsx((out_ptr + (i << 3)), (dst + (i << 3)), - dst_stride); - } -} - -void vpx_idct32x32_1_add_lsx(const int16_t *input, uint8_t *dst, - int32_t dst_stride) { - int32_t i; - int16_t out; - __m128i dst0, dst1, dst2, dst3, tmp0, tmp1, tmp2, tmp3; - __m128i res0, res1, res2, res3, res4, res5, res6, res7, vec; - - out = ROUND_POWER_OF_TWO((input[0] * cospi_16_64), DCT_CONST_BITS); - out = ROUND_POWER_OF_TWO((out * cospi_16_64), DCT_CONST_BITS); - out = ROUND_POWER_OF_TWO(out, 6); - - vec = __lsx_vreplgr2vr_h(out); - - for (i = 16; i--;) { - DUP2_ARG2(__lsx_vld, dst, 0, dst, 16, dst0, dst1); - dst2 = __lsx_vldx(dst, dst_stride); - dst3 = __lsx_vldx(dst + 16, dst_stride); - - UNPCK_UB_SH(dst0, res0, res4); - UNPCK_UB_SH(dst1, res1, res5); - UNPCK_UB_SH(dst2, res2, res6); - UNPCK_UB_SH(dst3, res3, res7); - - DUP4_ARG2(__lsx_vadd_h, res0, vec, res1, vec, res2, vec, res3, vec, res0, - res1, res2, res3); - DUP4_ARG2(__lsx_vadd_h, res4, vec, res5, vec, res6, vec, res7, vec, res4, - res5, res6, res7); - DUP4_ARG3(__lsx_vssrarni_bu_h, res4, res0, 0, res5, res1, 0, res6, res2, 0, - res7, res3, 0, tmp0, tmp1, tmp2, tmp3); - __lsx_vst(tmp0, dst, 0); - __lsx_vst(tmp1, dst, 16); - dst += dst_stride; - __lsx_vst(tmp2, dst, 0); - __lsx_vst(tmp3, dst, 16); - dst += dst_stride; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/intrapred_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/intrapred_lsx.c deleted file mode 100644 index f9902117..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/intrapred_lsx.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2021 Loongson Technology Corporation Limited - * Contributed by Lu Wang - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_util/loongson_intrinsics.h" - -static inline void intra_predict_dc_8x8_lsx(const uint8_t *src_top, - const uint8_t *src_left, - uint8_t *dst, int32_t dst_stride) { - uint64_t val0, val1; - int32_t dst_stride_x2 = dst_stride << 1; - int32_t dst_stride_x3 = dst_stride_x2 + dst_stride; - int32_t dst_stride_x4 = dst_stride << 2; - __m128i store, sum_h, sum_w, sum_d; - __m128i src = { 0 }; - - val0 = *(const uint64_t *)src_top; - val1 = *(const uint64_t *)src_left; - DUP2_ARG3(__lsx_vinsgr2vr_d, src, val0, 0, src, val1, 1, src, src); - sum_h = __lsx_vhaddw_hu_bu(src, src); - sum_w = __lsx_vhaddw_wu_hu(sum_h, sum_h); - sum_d = __lsx_vhaddw_du_wu(sum_w, sum_w); - sum_w = __lsx_vpickev_w(sum_d, sum_d); - sum_d = __lsx_vhaddw_du_wu(sum_w, sum_w); - sum_w = __lsx_vsrari_w(sum_d, 4); - store = __lsx_vreplvei_b(sum_w, 0); - - __lsx_vstelm_d(store, dst, 0, 0); - __lsx_vstelm_d(store, dst + dst_stride, 0, 0); - __lsx_vstelm_d(store, dst + dst_stride_x2, 0, 0); - __lsx_vstelm_d(store, dst + dst_stride_x3, 0, 0); - dst += dst_stride_x4; - __lsx_vstelm_d(store, dst, 0, 0); - __lsx_vstelm_d(store, dst + dst_stride, 0, 0); - __lsx_vstelm_d(store, dst + dst_stride_x2, 0, 0); - __lsx_vstelm_d(store, dst + dst_stride_x3, 0, 0); -} - -static inline void intra_predict_dc_16x16_lsx(const uint8_t *src_top, - const uint8_t *src_left, - uint8_t *dst, - int32_t dst_stride) { - int32_t dst_stride_x2 = dst_stride << 1; - int32_t dst_stride_x3 = dst_stride_x2 + dst_stride; - int32_t dst_stride_x4 = dst_stride << 2; - __m128i top, left, out; - __m128i sum_h, sum_top, sum_left; - __m128i sum_w; - __m128i sum_d; - - DUP2_ARG2(__lsx_vld, src_top, 0, src_left, 0, top, left); - DUP2_ARG2(__lsx_vhaddw_hu_bu, top, top, left, left, sum_top, sum_left); - sum_h = __lsx_vadd_h(sum_top, sum_left); - sum_w = __lsx_vhaddw_wu_hu(sum_h, sum_h); - sum_d = __lsx_vhaddw_du_wu(sum_w, sum_w); - sum_w = __lsx_vpickev_w(sum_d, sum_d); - sum_d = __lsx_vhaddw_du_wu(sum_w, sum_w); - sum_w = __lsx_vsrari_w(sum_d, 5); - out = __lsx_vreplvei_b(sum_w, 0); - - __lsx_vstx(out, dst, 0); - __lsx_vstx(out, dst, dst_stride); - __lsx_vstx(out, dst, dst_stride_x2); - __lsx_vstx(out, dst, dst_stride_x3); - dst += dst_stride_x4; - __lsx_vstx(out, dst, 0); - __lsx_vstx(out, dst, dst_stride); - __lsx_vstx(out, dst, dst_stride_x2); - __lsx_vstx(out, dst, dst_stride_x3); - dst += dst_stride_x4; - __lsx_vstx(out, dst, 0); - __lsx_vstx(out, dst, dst_stride); - __lsx_vstx(out, dst, dst_stride_x2); - __lsx_vstx(out, dst, dst_stride_x3); - dst += dst_stride_x4; - __lsx_vstx(out, dst, 0); - __lsx_vstx(out, dst, dst_stride); - __lsx_vstx(out, dst, dst_stride_x2); - __lsx_vstx(out, dst, dst_stride_x3); -} - -void vpx_dc_predictor_8x8_lsx(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - intra_predict_dc_8x8_lsx(above, left, dst, y_stride); -} - -void vpx_dc_predictor_16x16_lsx(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - intra_predict_dc_16x16_lsx(above, left, dst, y_stride); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/loopfilter_16_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/loopfilter_16_lsx.c deleted file mode 100644 index 0503df99..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/loopfilter_16_lsx.c +++ /dev/null @@ -1,1320 +0,0 @@ -/* - * Copyright (c) 2022 Loongson Technology Corporation Limited - * Contributed by Hecai Yuan - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/loongarch/loopfilter_lsx.h" -#include "vpx_ports/mem.h" - -#define LSX_LD_8(_src, _stride, _stride2, _stride3, _stride4, _in0, _in1, \ - _in2, _in3, _in4, _in5, _in6, _in7) \ - do { \ - _in0 = __lsx_vld(_src, 0); \ - _in1 = __lsx_vldx(_src, _stride); \ - _in2 = __lsx_vldx(_src, _stride2); \ - _in3 = __lsx_vldx(_src, _stride3); \ - _src += _stride4; \ - _in4 = __lsx_vld(_src, 0); \ - _in5 = __lsx_vldx(_src, _stride); \ - _in6 = __lsx_vldx(_src, _stride2); \ - _in7 = __lsx_vldx(_src, _stride3); \ - } while (0) - -#define LSX_ST_8(_dst0, _dst1, _dst2, _dst3, _dst4, _dst5, _dst6, _dst7, _dst, \ - _stride, _stride2, _stride3, _stride4) \ - do { \ - __lsx_vst(_dst0, _dst, 0); \ - __lsx_vstx(_dst1, _dst, _stride); \ - __lsx_vstx(_dst2, _dst, _stride2); \ - __lsx_vstx(_dst3, _dst, _stride3); \ - _dst += _stride4; \ - __lsx_vst(_dst4, _dst, 0); \ - __lsx_vstx(_dst5, _dst, _stride); \ - __lsx_vstx(_dst6, _dst, _stride2); \ - __lsx_vstx(_dst7, _dst, _stride3); \ - } while (0) - -static int32_t hz_lpf_t4_and_t8_16w(uint8_t *dst, int32_t stride, - uint8_t *filter48, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - __m128i p3, p2, p1, p0, q3, q2, q1, q0; - __m128i p2_out, p1_out, p0_out, q0_out, q1_out, q2_out; - __m128i flat, mask, hev, thresh, b_limit, limit; - __m128i p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l; - __m128i p3_h, p2_h, p1_h, p0_h, q0_h, q1_h, q2_h, q3_h; - __m128i p2_filt8_l, p1_filt8_l, p0_filt8_l; - __m128i q0_filt8_l, q1_filt8_l, q2_filt8_l; - __m128i p2_filt8_h, p1_filt8_h, p0_filt8_h; - __m128i q0_filt8_h, q1_filt8_h, q2_filt8_h; - - int32_t stride2 = stride << 1; - int32_t stride3 = stride2 + stride; - int32_t stride4 = stride2 << 1; - - /* load vector elements */ - DUP4_ARG2(__lsx_vldx, dst, -stride4, dst, -stride3, dst, -stride2, dst, - -stride, p3, p2, p1, p0); - - q0 = __lsx_vld(dst, 0); - DUP2_ARG2(__lsx_vldx, dst, stride, dst, stride2, q1, q2); - q3 = __lsx_vldx(dst, stride3); - - thresh = __lsx_vldrepl_b(thresh_ptr, 0); - b_limit = __lsx_vldrepl_b(b_limit_ptr, 0); - limit = __lsx_vldrepl_b(limit_ptr, 0); - /* mask and hev */ - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); - - if (__lsx_bz_v(flat)) { - __lsx_vstx(p1_out, dst, -stride2); - __lsx_vstx(p0_out, dst, -stride); - __lsx_vst(q0_out, dst, 0); - __lsx_vstx(q1_out, dst, stride); - - return 1; - } - - DUP4_ARG2(__lsx_vsllwil_hu_bu, p3, 0, p2, 0, p1, 0, p0, 0, p3_l, p2_l, p1_l, - p0_l); - DUP4_ARG2(__lsx_vsllwil_hu_bu, q0, 0, q1, 0, q2, 0, q3, 0, q0_l, q1_l, q2_l, - q3_l); - - VP9_FILTER8(p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l, p2_filt8_l, - p1_filt8_l, p0_filt8_l, q0_filt8_l, q1_filt8_l, q2_filt8_l); - - DUP4_ARG1(__lsx_vexth_hu_bu, p3, p2, p1, p0, p3_h, p2_h, p1_h, p0_h); - DUP4_ARG1(__lsx_vexth_hu_bu, q0, q1, q2, q3, q0_h, q1_h, q2_h, q3_h); - VP9_FILTER8(p3_h, p2_h, p1_h, p0_h, q0_h, q1_h, q2_h, q3_h, p2_filt8_h, - p1_filt8_h, p0_filt8_h, q0_filt8_h, q1_filt8_h, q2_filt8_h); - - /* convert 16 bit output data into 8 bit */ - DUP4_ARG2(__lsx_vpickev_b, p2_filt8_h, p2_filt8_l, p1_filt8_h, p1_filt8_l, - p0_filt8_h, p0_filt8_l, q0_filt8_h, q0_filt8_l, p2_filt8_l, - p1_filt8_l, p0_filt8_l, q0_filt8_l); - DUP2_ARG2(__lsx_vpickev_b, q1_filt8_h, q1_filt8_l, q2_filt8_h, q2_filt8_l, - q1_filt8_l, q2_filt8_l); - - /* store pixel values */ - DUP4_ARG3(__lsx_vbitsel_v, p2, p2_filt8_l, flat, p1_out, p1_filt8_l, flat, - p0_out, p0_filt8_l, flat, q0_out, q0_filt8_l, flat, p2_out, p1_out, - p0_out, q0_out); - DUP2_ARG3(__lsx_vbitsel_v, q1_out, q1_filt8_l, flat, q2, q2_filt8_l, flat, - q1_out, q2_out); - - __lsx_vst(p2_out, filter48, 0); - __lsx_vst(p1_out, filter48, 16); - __lsx_vst(p0_out, filter48, 32); - __lsx_vst(q0_out, filter48, 48); - __lsx_vst(q1_out, filter48, 64); - __lsx_vst(q2_out, filter48, 80); - __lsx_vst(flat, filter48, 96); - - return 0; -} - -static void hz_lpf_t16_16w(uint8_t *dst, int32_t stride, uint8_t *filter48) { - int32_t stride2 = stride << 1; - int32_t stride3 = stride2 + stride; - int32_t stride4 = stride2 << 1; - uint8_t *dst_tmp0 = dst - stride4; - uint8_t *dst_tmp1 = dst + stride4; - - __m128i flat, flat2, filter8; - __m128i p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7; - __m128i out_h, out_l; - v8u16 p7_l_in, p6_l_in, p5_l_in, p4_l_in; - v8u16 p3_l_in, p2_l_in, p1_l_in, p0_l_in; - v8u16 q7_l_in, q6_l_in, q5_l_in, q4_l_in; - v8u16 q3_l_in, q2_l_in, q1_l_in, q0_l_in; - v8u16 p7_h_in, p6_h_in, p5_h_in, p4_h_in; - v8u16 p3_h_in, p2_h_in, p1_h_in, p0_h_in; - v8u16 q7_h_in, q6_h_in, q5_h_in, q4_h_in; - v8u16 q3_h_in, q2_h_in, q1_h_in, q0_h_in; - v8u16 tmp0_l, tmp1_l, tmp0_h, tmp1_h; - - flat = __lsx_vld(filter48, 96); - - DUP4_ARG2(__lsx_vldx, dst_tmp0, -stride4, dst_tmp0, -stride3, dst_tmp0, - -stride2, dst_tmp0, -stride, p7, p6, p5, p4); - - p3 = __lsx_vld(dst_tmp0, 0); - DUP2_ARG2(__lsx_vldx, dst_tmp0, stride, dst_tmp0, stride2, p2, p1); - p0 = __lsx_vldx(dst_tmp0, stride3); - - q0 = __lsx_vld(dst, 0); - DUP2_ARG2(__lsx_vldx, dst, stride, dst, stride2, q1, q2); - q3 = __lsx_vldx(dst, stride3); - - q4 = __lsx_vld(dst_tmp1, 0); - DUP2_ARG2(__lsx_vldx, dst_tmp1, stride, dst_tmp1, stride2, q5, q6); - q7 = __lsx_vldx(dst_tmp1, stride3); - - VP9_FLAT5(p7, p6, p5, p4, p0, q0, q4, q5, q6, q7, flat, flat2); - - if (__lsx_bz_v(flat2)) { - DUP4_ARG2(__lsx_vld, filter48, 0, filter48, 16, filter48, 32, filter48, 48, - p2, p1, p0, q0); - DUP2_ARG2(__lsx_vld, filter48, 64, filter48, 80, q1, q2); - __lsx_vstx(p2, dst, -stride3); - __lsx_vstx(p1, dst, -stride2); - __lsx_vstx(p0, dst, -stride); - __lsx_vst(q0, dst, 0); - __lsx_vstx(q1, dst, stride); - __lsx_vstx(q2, dst, stride2); - } else { - dst = dst_tmp0 - stride3; - - p7_l_in = (v8u16)__lsx_vsllwil_hu_bu(p7, 0); - p6_l_in = (v8u16)__lsx_vsllwil_hu_bu(p6, 0); - p5_l_in = (v8u16)__lsx_vsllwil_hu_bu(p5, 0); - p4_l_in = (v8u16)__lsx_vsllwil_hu_bu(p4, 0); - p3_l_in = (v8u16)__lsx_vsllwil_hu_bu(p3, 0); - p2_l_in = (v8u16)__lsx_vsllwil_hu_bu(p2, 0); - p1_l_in = (v8u16)__lsx_vsllwil_hu_bu(p1, 0); - p0_l_in = (v8u16)__lsx_vsllwil_hu_bu(p0, 0); - q0_l_in = (v8u16)__lsx_vsllwil_hu_bu(q0, 0); - - tmp0_l = p7_l_in << 3; - tmp0_l -= p7_l_in; - tmp0_l += p6_l_in; - tmp0_l += q0_l_in; - tmp1_l = p6_l_in + p5_l_in; - tmp1_l += p4_l_in; - tmp1_l += p3_l_in; - tmp1_l += p2_l_in; - tmp1_l += p1_l_in; - tmp1_l += p0_l_in; - tmp1_l += tmp0_l; - - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - - p7_h_in = (v8u16)__lsx_vexth_hu_bu(p7); - p6_h_in = (v8u16)__lsx_vexth_hu_bu(p6); - p5_h_in = (v8u16)__lsx_vexth_hu_bu(p5); - p4_h_in = (v8u16)__lsx_vexth_hu_bu(p4); - p3_h_in = (v8u16)__lsx_vexth_hu_bu(p3); - p2_h_in = (v8u16)__lsx_vexth_hu_bu(p2); - p1_h_in = (v8u16)__lsx_vexth_hu_bu(p1); - p0_h_in = (v8u16)__lsx_vexth_hu_bu(p0); - q0_h_in = (v8u16)__lsx_vexth_hu_bu(q0); - - tmp0_h = p7_h_in << 3; - tmp0_h -= p7_h_in; - tmp0_h += p6_h_in; - tmp0_h += q0_h_in; - tmp1_h = p6_h_in + p5_h_in; - tmp1_h += p4_h_in; - tmp1_h += p3_h_in; - tmp1_h += p2_h_in; - tmp1_h += p1_h_in; - tmp1_h += p0_h_in; - tmp1_h += tmp0_h; - - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - - out_l = __lsx_vpickev_b(out_h, out_l); - p6 = __lsx_vbitsel_v(p6, out_l, flat2); - __lsx_vst(p6, dst, 0); - dst += stride; - - /* p5 */ - q1_l_in = (v8u16)__lsx_vsllwil_hu_bu(q1, 0); - tmp0_l = p5_l_in - p6_l_in; - tmp0_l += q1_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - - q1_h_in = (v8u16)__lsx_vexth_hu_bu(q1); - tmp0_h = p5_h_in - p6_h_in; - tmp0_h += q1_h_in; - tmp0_h -= p7_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - - out_l = __lsx_vpickev_b(out_h, out_l); - p5 = __lsx_vbitsel_v(p5, out_l, flat2); - __lsx_vst(p5, dst, 0); - dst += stride; - - /* p4 */ - q2_l_in = (v8u16)__lsx_vsllwil_hu_bu(q2, 0); - tmp0_l = p4_l_in - p5_l_in; - tmp0_l += q2_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - - q2_h_in = (v8u16)__lsx_vexth_hu_bu(q2); - tmp0_h = p4_h_in - p5_h_in; - tmp0_h += q2_h_in; - tmp0_h -= p7_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - - out_l = __lsx_vpickev_b(out_h, out_l); - p4 = __lsx_vbitsel_v(p4, out_l, flat2); - __lsx_vst(p4, dst, 0); - dst += stride; - - /* p3 */ - q3_l_in = (v8u16)__lsx_vsllwil_hu_bu(q3, 0); - tmp0_l = p3_l_in - p4_l_in; - tmp0_l += q3_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - - q3_h_in = (v8u16)__lsx_vexth_hu_bu(q3); - tmp0_h = p3_h_in - p4_h_in; - tmp0_h += q3_h_in; - tmp0_h -= p7_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - - out_l = __lsx_vpickev_b(out_h, out_l); - p3 = __lsx_vbitsel_v(p3, out_l, flat2); - __lsx_vst(p3, dst, 0); - dst += stride; - - /* p2 */ - q4_l_in = (v8u16)__lsx_vsllwil_hu_bu(q4, 0); - filter8 = __lsx_vld(filter48, 0); - tmp0_l = p2_l_in - p3_l_in; - tmp0_l += q4_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - - q4_h_in = (v8u16)__lsx_vexth_hu_bu(q4); - tmp0_h = p2_h_in - p3_h_in; - tmp0_h += q4_h_in; - tmp0_h -= p7_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - - out_l = __lsx_vpickev_b(out_h, out_l); - filter8 = __lsx_vbitsel_v(filter8, out_l, flat2); - __lsx_vst(filter8, dst, 0); - dst += stride; - - /* p1 */ - q5_l_in = (v8u16)__lsx_vsllwil_hu_bu(q5, 0); - filter8 = __lsx_vld(filter48, 16); - tmp0_l = p1_l_in - p2_l_in; - tmp0_l += q5_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - - q5_h_in = (v8u16)__lsx_vexth_hu_bu(q5); - tmp0_h = p1_h_in - p2_h_in; - tmp0_h += q5_h_in; - tmp0_h -= p7_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - - out_l = __lsx_vpickev_b(out_h, out_l); - filter8 = __lsx_vbitsel_v(filter8, out_l, flat2); - __lsx_vst(filter8, dst, 0); - dst += stride; - - /* p0 */ - q6_l_in = (v8u16)__lsx_vsllwil_hu_bu(q6, 0); - filter8 = __lsx_vld(filter48, 32); - tmp0_l = p0_l_in - p1_l_in; - tmp0_l += q6_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - - q6_h_in = (v8u16)__lsx_vexth_hu_bu(q6); - tmp0_h = p0_h_in - p1_h_in; - tmp0_h += q6_h_in; - tmp0_h -= p7_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - - out_l = __lsx_vpickev_b(out_h, out_l); - filter8 = __lsx_vbitsel_v(filter8, out_l, flat2); - __lsx_vst(filter8, dst, 0); - dst += stride; - - /* q0 */ - q7_l_in = (v8u16)__lsx_vsllwil_hu_bu(q7, 0); - filter8 = __lsx_vld(filter48, 48); - tmp0_l = q7_l_in - p0_l_in; - tmp0_l += q0_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - - q7_h_in = (v8u16)__lsx_vexth_hu_bu(q7); - tmp0_h = q7_h_in - p0_h_in; - tmp0_h += q0_h_in; - tmp0_h -= p7_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - - out_l = __lsx_vpickev_b(out_h, out_l); - filter8 = __lsx_vbitsel_v(filter8, out_l, flat2); - __lsx_vst(filter8, dst, 0); - dst += stride; - - /* q1 */ - filter8 = __lsx_vld(filter48, 64); - tmp0_l = q7_l_in - q0_l_in; - tmp0_l += q1_l_in; - tmp0_l -= p6_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - - tmp0_h = q7_h_in - q0_h_in; - tmp0_h += q1_h_in; - tmp0_h -= p6_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - - out_l = __lsx_vpickev_b(out_h, out_l); - filter8 = __lsx_vbitsel_v(filter8, out_l, flat2); - __lsx_vst(filter8, dst, 0); - dst += stride; - - /* q2 */ - filter8 = __lsx_vld(filter48, 80); - tmp0_l = q7_l_in - q1_l_in; - tmp0_l += q2_l_in; - tmp0_l -= p5_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - - tmp0_h = q7_h_in - q1_h_in; - tmp0_h += q2_h_in; - tmp0_h -= p5_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - - out_l = __lsx_vpickev_b(out_h, out_l); - filter8 = __lsx_vbitsel_v(filter8, out_l, flat2); - __lsx_vst(filter8, dst, 0); - dst += stride; - - /* q3 */ - tmp0_l = q7_l_in - q2_l_in; - tmp0_l += q3_l_in; - tmp0_l -= p4_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - - tmp0_h = q7_h_in - q2_h_in; - tmp0_h += q3_h_in; - tmp0_h -= p4_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - - out_l = __lsx_vpickev_b(out_h, out_l); - q3 = __lsx_vbitsel_v(q3, out_l, flat2); - __lsx_vst(q3, dst, 0); - dst += stride; - - /* q4 */ - tmp0_l = q7_l_in - q3_l_in; - tmp0_l += q4_l_in; - tmp0_l -= p3_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - - tmp0_h = q7_h_in - q3_h_in; - tmp0_h += q4_h_in; - tmp0_h -= p3_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - - out_l = __lsx_vpickev_b(out_h, out_l); - q4 = __lsx_vbitsel_v(q4, out_l, flat2); - __lsx_vst(q4, dst, 0); - dst += stride; - - /* q5 */ - tmp0_l = q7_l_in - q4_l_in; - tmp0_l += q5_l_in; - tmp0_l -= p2_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - - tmp0_h = q7_h_in - q4_h_in; - tmp0_h += q5_h_in; - tmp0_h -= p2_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - - out_l = __lsx_vpickev_b(out_h, out_l); - q5 = __lsx_vbitsel_v(q5, out_l, flat2); - __lsx_vst(q5, dst, 0); - dst += stride; - - /* q6 */ - tmp0_l = q7_l_in - q5_l_in; - tmp0_l += q6_l_in; - tmp0_l -= p1_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - - tmp0_h = q7_h_in - q5_h_in; - tmp0_h += q6_h_in; - tmp0_h -= p1_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - - out_l = __lsx_vpickev_b(out_h, out_l); - q6 = __lsx_vbitsel_v(q6, out_l, flat2); - __lsx_vst(q6, dst, 0); - } -} - -static void mb_lpf_horizontal_edge_dual(uint8_t *dst, int32_t stride, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - DECLARE_ALIGNED(16, uint8_t, filter48[16 * 8]); - uint8_t early_exit = 0; - - early_exit = hz_lpf_t4_and_t8_16w(dst, stride, &filter48[0], b_limit_ptr, - limit_ptr, thresh_ptr); - - if (early_exit == 0) { - hz_lpf_t16_16w(dst, stride, filter48); - } -} - -static void mb_lpf_horizontal_edge(uint8_t *dst, int32_t stride, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr, int32_t count) { - if (count == 1) { - __m128i flat2, mask, hev, flat, thresh, b_limit, limit; - __m128i p3, p2, p1, p0, q3, q2, q1, q0, p7, p6, p5, p4, q4, q5, q6, q7; - __m128i p2_out, p1_out, p0_out, q0_out, q1_out, q2_out; - __m128i p0_filter16, p1_filter16; - __m128i p2_filter8, p1_filter8, p0_filter8; - __m128i q0_filter8, q1_filter8, q2_filter8; - __m128i p7_l, p6_l, p5_l, p4_l, q7_l, q6_l, q5_l, q4_l; - __m128i p3_l, p2_l, p1_l, p0_l, q3_l, q2_l, q1_l, q0_l; - __m128i zero = __lsx_vldi(0); - __m128i tmp0, tmp1, tmp2; - - int32_t stride2 = stride << 1; - int32_t stride3 = 2 + stride; - int32_t stride4 = stride << 2; - uint8_t *dst_tmp0 = dst - stride4; - uint8_t *dst_tmp1 = dst + stride4; - - /* load vector elements */ - DUP4_ARG2(__lsx_vldx, dst, -stride4, dst, -stride3, dst, -stride2, dst, - -stride, p3, p2, p1, p0); - q0 = __lsx_vld(dst, 0); - DUP2_ARG2(__lsx_vldx, dst, stride, dst, stride2, q1, q2); - q3 = __lsx_vldx(dst, stride3); - - thresh = __lsx_vldrepl_b(thresh_ptr, 0); - b_limit = __lsx_vldrepl_b(b_limit_ptr, 0); - limit = __lsx_vldrepl_b(limit_ptr, 0); - - /* filter_mask* */ - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, - q1_out); - flat = __lsx_vilvl_d(zero, flat); - if (__lsx_bz_v(flat)) { - __lsx_vstelm_d(p1_out, dst - stride2, 0, 0); - __lsx_vstelm_d(p0_out, dst - stride, 0, 0); - __lsx_vstelm_d(q0_out, dst, 0, 0); - __lsx_vstelm_d(q1_out, dst + stride, 0, 0); - } else { - /* convert 8 bit input data into 16 bit */ - DUP4_ARG2(__lsx_vilvl_b, zero, p3, zero, p2, zero, p1, zero, p0, p3_l, - p2_l, p1_l, p0_l); - DUP4_ARG2(__lsx_vilvl_b, zero, q0, zero, q1, zero, q2, zero, q3, q0_l, - q1_l, q2_l, q3_l); - VP9_FILTER8(p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l, p2_filter8, - p1_filter8, p0_filter8, q0_filter8, q1_filter8, q2_filter8); - - /* convert 16 bit output data into 8 bit */ - DUP4_ARG2(__lsx_vpickev_b, zero, p2_filter8, zero, p1_filter8, zero, - p0_filter8, zero, q0_filter8, p2_filter8, p1_filter8, - p0_filter8, q0_filter8); - DUP2_ARG2(__lsx_vpickev_b, zero, q1_filter8, zero, q2_filter8, q1_filter8, - q2_filter8); - - /* store pixel values */ - p2_out = __lsx_vbitsel_v(p2, p2_filter8, flat); - p1_out = __lsx_vbitsel_v(p1_out, p1_filter8, flat); - p0_out = __lsx_vbitsel_v(p0_out, p0_filter8, flat); - q0_out = __lsx_vbitsel_v(q0_out, q0_filter8, flat); - q1_out = __lsx_vbitsel_v(q1_out, q1_filter8, flat); - q2_out = __lsx_vbitsel_v(q2, q2_filter8, flat); - - /* load 16 vector elements */ - DUP4_ARG2(__lsx_vldx, dst_tmp0, -stride4, dst_tmp0, -stride3, dst_tmp0, - -stride2, dst_tmp0, -stride, p7, p6, p5, p4); - q4 = __lsx_vld(dst_tmp1, 0); - DUP2_ARG2(__lsx_vldx, dst_tmp1, stride, dst_tmp1, stride2, q5, q6); - q7 = __lsx_vldx(dst_tmp1, stride3); - - VP9_FLAT5(p7, p6, p5, p4, p0, q0, q4, q5, q6, q7, flat, flat2); - - if (__lsx_bz_v(flat2)) { - dst -= stride3; - __lsx_vstelm_d(p2_out, dst, 0, 0); - dst += stride; - __lsx_vstelm_d(p1_out, dst, 0, 0); - dst += stride; - __lsx_vstelm_d(p0_out, dst, 0, 0); - dst += stride; - __lsx_vstelm_d(q0_out, dst, 0, 0); - dst += stride; - __lsx_vstelm_d(q1_out, dst, 0, 0); - dst += stride; - __lsx_vstelm_d(q2_out, dst, 0, 0); - } else { - /* LSB(right) 8 pixel operation */ - DUP4_ARG2(__lsx_vilvl_b, zero, p7, zero, p6, zero, p5, zero, p4, p7_l, - p6_l, p5_l, p4_l); - DUP4_ARG2(__lsx_vilvl_b, zero, q4, zero, q5, zero, q6, zero, q7, q4_l, - q5_l, q6_l, q7_l); - - tmp0 = __lsx_vslli_h(p7_l, 3); - tmp0 = __lsx_vsub_h(tmp0, p7_l); - tmp0 = __lsx_vadd_h(tmp0, p6_l); - tmp0 = __lsx_vadd_h(tmp0, q0_l); - - dst = dst_tmp0 - stride3; - - /* calculation of p6 and p5 */ - tmp1 = __lsx_vadd_h(p6_l, p5_l); - tmp1 = __lsx_vadd_h(tmp1, p4_l); - tmp1 = __lsx_vadd_h(tmp1, p3_l); - tmp1 = __lsx_vadd_h(tmp1, p2_l); - tmp1 = __lsx_vadd_h(tmp1, p1_l); - tmp1 = __lsx_vadd_h(tmp1, p0_l); - tmp1 = __lsx_vadd_h(tmp1, tmp0); - p0_filter16 = __lsx_vsrari_h(tmp1, 4); - tmp0 = __lsx_vsub_h(p5_l, p6_l); - tmp0 = __lsx_vadd_h(tmp0, q1_l); - tmp0 = __lsx_vsub_h(tmp0, p7_l); - tmp1 = __lsx_vadd_h(tmp1, tmp0); - p1_filter16 = __lsx_vsrari_h(tmp1, 4); - DUP2_ARG2(__lsx_vpickev_b, zero, p0_filter16, zero, p1_filter16, - p0_filter16, p1_filter16); - DUP2_ARG3(__lsx_vbitsel_v, p6, p0_filter16, flat2, p5, p1_filter16, - flat2, p0_filter16, p1_filter16); - __lsx_vstelm_d(p0_filter16, dst, 0, 0); - dst += stride; - __lsx_vstelm_d(p1_filter16, dst, 0, 0); - dst += stride; - - /* calculation of p4 and p3 */ - tmp0 = __lsx_vsub_h(p4_l, p5_l); - tmp0 = __lsx_vadd_h(tmp0, q2_l); - tmp0 = __lsx_vsub_h(tmp0, p7_l); - tmp2 = __lsx_vsub_h(p3_l, p4_l); - tmp2 = __lsx_vadd_h(tmp2, q3_l); - tmp2 = __lsx_vsub_h(tmp2, p7_l); - tmp1 = __lsx_vadd_h(tmp1, tmp0); - p0_filter16 = __lsx_vsrari_h(tmp1, 4); - tmp1 = __lsx_vadd_h(tmp1, tmp2); - p1_filter16 = __lsx_vsrari_h(tmp1, 4); - DUP2_ARG2(__lsx_vpickev_b, zero, p0_filter16, zero, p1_filter16, - p0_filter16, p1_filter16); - DUP2_ARG3(__lsx_vbitsel_v, p4, p0_filter16, flat2, p3, p1_filter16, - flat2, p0_filter16, p1_filter16); - __lsx_vstelm_d(p0_filter16, dst, 0, 0); - dst += stride; - __lsx_vstelm_d(p1_filter16, dst, 0, 0); - dst += stride; - - /* calculation of p2 and p1 */ - tmp0 = __lsx_vsub_h(p2_l, p3_l); - tmp0 = __lsx_vadd_h(tmp0, q4_l); - tmp0 = __lsx_vsub_h(tmp0, p7_l); - tmp2 = __lsx_vsub_h(p1_l, p2_l); - tmp2 = __lsx_vadd_h(tmp2, q5_l); - tmp2 = __lsx_vsub_h(tmp2, p7_l); - tmp1 = __lsx_vadd_h(tmp1, tmp0); - p0_filter16 = __lsx_vsrari_h(tmp1, 4); - tmp1 = __lsx_vadd_h(tmp1, tmp2); - p1_filter16 = __lsx_vsrari_h(tmp1, 4); - DUP2_ARG2(__lsx_vpickev_b, zero, p0_filter16, zero, p1_filter16, - p0_filter16, p1_filter16); - DUP2_ARG3(__lsx_vbitsel_v, p2_out, p0_filter16, flat2, p1_out, - p1_filter16, flat2, p0_filter16, p1_filter16); - __lsx_vstelm_d(p0_filter16, dst, 0, 0); - dst += stride; - __lsx_vstelm_d(p1_filter16, dst, 0, 0); - dst += stride; - - /* calculation of p0 and q0 */ - tmp0 = __lsx_vsub_h(p0_l, p1_l); - tmp0 = __lsx_vadd_h(tmp0, q6_l); - tmp0 = __lsx_vsub_h(tmp0, p7_l); - tmp2 = __lsx_vsub_h(q7_l, p0_l); - tmp2 = __lsx_vadd_h(tmp2, q0_l); - tmp2 = __lsx_vsub_h(tmp2, p7_l); - tmp1 = __lsx_vadd_h(tmp1, tmp0); - p0_filter16 = __lsx_vsrari_h(tmp1, 4); - tmp1 = __lsx_vadd_h(tmp1, tmp2); - p1_filter16 = __lsx_vsrari_h(tmp1, 4); - DUP2_ARG2(__lsx_vpickev_b, zero, p0_filter16, zero, p1_filter16, - p0_filter16, p1_filter16); - DUP2_ARG3(__lsx_vbitsel_v, p0_out, p0_filter16, flat2, q0_out, - p1_filter16, flat2, p0_filter16, p1_filter16); - __lsx_vstelm_d(p0_filter16, dst, 0, 0); - dst += stride; - __lsx_vstelm_d(p1_filter16, dst, 0, 0); - dst += stride; - - /* calculation of q1 and q2 */ - tmp0 = __lsx_vsub_h(q7_l, q0_l); - tmp0 = __lsx_vadd_h(tmp0, q1_l); - tmp0 = __lsx_vsub_h(tmp0, p6_l); - tmp2 = __lsx_vsub_h(q7_l, q1_l); - tmp2 = __lsx_vadd_h(tmp2, q2_l); - tmp2 = __lsx_vsub_h(tmp2, p5_l); - tmp1 = __lsx_vadd_h(tmp1, tmp0); - p0_filter16 = __lsx_vsrari_h(tmp1, 4); - tmp1 = __lsx_vadd_h(tmp1, tmp2); - p1_filter16 = __lsx_vsrari_h(tmp1, 4); - DUP2_ARG2(__lsx_vpickev_b, zero, p0_filter16, zero, p1_filter16, - p0_filter16, p1_filter16); - DUP2_ARG3(__lsx_vbitsel_v, q1_out, p0_filter16, flat2, q2_out, - p1_filter16, flat2, p0_filter16, p1_filter16); - __lsx_vstelm_d(p0_filter16, dst, 0, 0); - dst += stride; - __lsx_vstelm_d(p1_filter16, dst, 0, 0); - dst += stride; - - /* calculation of q3 and q4 */ - tmp0 = __lsx_vsub_h(q7_l, q2_l); - tmp0 = __lsx_vadd_h(tmp0, q3_l); - tmp0 = __lsx_vsub_h(tmp0, p4_l); - tmp2 = __lsx_vsub_h(q7_l, q3_l); - tmp2 = __lsx_vadd_h(tmp2, q4_l); - tmp2 = __lsx_vsub_h(tmp2, p3_l); - tmp1 = __lsx_vadd_h(tmp1, tmp0); - p0_filter16 = __lsx_vsrari_h(tmp1, 4); - tmp1 = __lsx_vadd_h(tmp1, tmp2); - p1_filter16 = __lsx_vsrari_h(tmp1, 4); - DUP2_ARG2(__lsx_vpickev_b, zero, p0_filter16, zero, p1_filter16, - p0_filter16, p1_filter16); - DUP2_ARG3(__lsx_vbitsel_v, q3, p0_filter16, flat2, q4, p1_filter16, - flat2, p0_filter16, p1_filter16); - __lsx_vstelm_d(p0_filter16, dst, 0, 0); - dst += stride; - __lsx_vstelm_d(p1_filter16, dst, 0, 0); - dst += stride; - - /* calculation of q5 and q6 */ - tmp0 = __lsx_vsub_h(q7_l, q4_l); - tmp0 = __lsx_vadd_h(tmp0, q5_l); - tmp0 = __lsx_vsub_h(tmp0, p2_l); - tmp2 = __lsx_vsub_h(q7_l, q5_l); - tmp2 = __lsx_vadd_h(tmp2, q6_l); - tmp2 = __lsx_vsub_h(tmp2, p1_l); - tmp1 = __lsx_vadd_h(tmp1, tmp0); - p0_filter16 = __lsx_vsrari_h(tmp1, 4); - tmp1 = __lsx_vadd_h(tmp1, tmp2); - p1_filter16 = __lsx_vsrari_h(tmp1, 4); - DUP2_ARG2(__lsx_vpickev_b, zero, p0_filter16, zero, p1_filter16, - p0_filter16, p1_filter16); - DUP2_ARG3(__lsx_vbitsel_v, q5, p0_filter16, flat2, q6, p1_filter16, - flat2, p0_filter16, p1_filter16); - __lsx_vstelm_d(p0_filter16, dst, 0, 0); - dst += stride; - __lsx_vstelm_d(p1_filter16, dst, 0, 0); - } - } - } else { - mb_lpf_horizontal_edge_dual(dst, stride, b_limit_ptr, limit_ptr, - thresh_ptr); - } -} - -void vpx_lpf_horizontal_16_dual_lsx(uint8_t *dst, int32_t stride, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - mb_lpf_horizontal_edge(dst, stride, b_limit_ptr, limit_ptr, thresh_ptr, 2); -} - -static void transpose_16x16(uint8_t *input, int32_t in_stride, uint8_t *output, - int32_t out_stride) { - __m128i row0, row1, row2, row3, row4, row5, row6, row7; - __m128i row8, row9, row10, row11, row12, row13, row14, row15; - __m128i tmp0, tmp1, tmp4, tmp5, tmp6, tmp7; - __m128i tmp2, tmp3; - __m128i p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7; - int32_t in_stride2 = in_stride << 1; - int32_t in_stride3 = in_stride2 + in_stride; - int32_t in_stride4 = in_stride2 << 1; - int32_t out_stride2 = out_stride << 1; - int32_t out_stride3 = out_stride2 + out_stride; - int32_t out_stride4 = out_stride2 << 1; - - LSX_LD_8(input, in_stride, in_stride2, in_stride3, in_stride4, row0, row1, - row2, row3, row4, row5, row6, row7); - input += in_stride4; - LSX_LD_8(input, in_stride, in_stride2, in_stride3, in_stride4, row8, row9, - row10, row11, row12, row13, row14, row15); - - LSX_TRANSPOSE16x8_B(row0, row1, row2, row3, row4, row5, row6, row7, row8, - row9, row10, row11, row12, row13, row14, row15, p7, p6, - p5, p4, p3, p2, p1, p0); - - /* transpose 16x8 matrix into 8x16 */ - /* total 8 intermediate register and 32 instructions */ - q7 = __lsx_vpackod_d(row8, row0); - q6 = __lsx_vpackod_d(row9, row1); - q5 = __lsx_vpackod_d(row10, row2); - q4 = __lsx_vpackod_d(row11, row3); - q3 = __lsx_vpackod_d(row12, row4); - q2 = __lsx_vpackod_d(row13, row5); - q1 = __lsx_vpackod_d(row14, row6); - q0 = __lsx_vpackod_d(row15, row7); - - DUP2_ARG2(__lsx_vpackev_b, q6, q7, q4, q5, tmp0, tmp1); - DUP2_ARG2(__lsx_vpackod_b, q6, q7, q4, q5, tmp4, tmp5); - - DUP2_ARG2(__lsx_vpackev_b, q2, q3, q0, q1, q5, q7); - DUP2_ARG2(__lsx_vpackod_b, q2, q3, q0, q1, tmp6, tmp7); - - DUP2_ARG2(__lsx_vpackev_h, tmp1, tmp0, q7, q5, tmp2, tmp3); - q0 = __lsx_vpackev_w(tmp3, tmp2); - q4 = __lsx_vpackod_w(tmp3, tmp2); - - tmp2 = __lsx_vpackod_h(tmp1, tmp0); - tmp3 = __lsx_vpackod_h(q7, q5); - q2 = __lsx_vpackev_w(tmp3, tmp2); - q6 = __lsx_vpackod_w(tmp3, tmp2); - - DUP2_ARG2(__lsx_vpackev_h, tmp5, tmp4, tmp7, tmp6, tmp2, tmp3); - q1 = __lsx_vpackev_w(tmp3, tmp2); - q5 = __lsx_vpackod_w(tmp3, tmp2); - - tmp2 = __lsx_vpackod_h(tmp5, tmp4); - tmp3 = __lsx_vpackod_h(tmp7, tmp6); - q3 = __lsx_vpackev_w(tmp3, tmp2); - q7 = __lsx_vpackod_w(tmp3, tmp2); - - LSX_ST_8(p7, p6, p5, p4, p3, p2, p1, p0, output, out_stride, out_stride2, - out_stride3, out_stride4); - output += out_stride4; - LSX_ST_8(q0, q1, q2, q3, q4, q5, q6, q7, output, out_stride, out_stride2, - out_stride3, out_stride4); -} - -static int32_t vt_lpf_t4_and_t8_16w(uint8_t *dst, uint8_t *filter48, - uint8_t *dst_org, int32_t stride, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - int32_t stride2 = stride << 1; - int32_t stride3 = stride2 + stride; - int32_t stride4 = stride2 << 1; - __m128i p3, p2, p1, p0, q3, q2, q1, q0; - __m128i p2_out, p1_out, p0_out, q0_out, q1_out, q2_out; - __m128i flat, mask, hev, thresh, b_limit, limit; - __m128i p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l; - __m128i p3_h, p2_h, p1_h, p0_h, q0_h, q1_h, q2_h, q3_h; - __m128i p2_filt8_l, p1_filt8_l, p0_filt8_l; - __m128i q0_filt8_l, q1_filt8_l, q2_filt8_l; - __m128i p2_filt8_h, p1_filt8_h, p0_filt8_h; - __m128i q0_filt8_h, q1_filt8_h, q2_filt8_h; - __m128i vec0, vec1, vec2, vec3, vec4, vec5; - - /* load vector elements */ - DUP4_ARG2(__lsx_vld, dst, -64, dst, -48, dst, -32, dst, -16, p3, p2, p1, p0); - DUP4_ARG2(__lsx_vld, dst, 0, dst, 16, dst, 32, dst, 48, q0, q1, q2, q3); - - thresh = __lsx_vldrepl_b(thresh_ptr, 0); - b_limit = __lsx_vldrepl_b(b_limit_ptr, 0); - limit = __lsx_vldrepl_b(limit_ptr, 0); - - /* mask and hev */ - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - /* flat4 */ - VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); - /* filter4 */ - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); - - /* if flat is zero for all pixels, then no need to calculate other filter */ - if (__lsx_bz_v(flat)) { - DUP2_ARG2(__lsx_vilvl_b, p0_out, p1_out, q1_out, q0_out, vec0, vec1); - vec2 = __lsx_vilvl_h(vec1, vec0); - vec3 = __lsx_vilvh_h(vec1, vec0); - DUP2_ARG2(__lsx_vilvh_b, p0_out, p1_out, q1_out, q0_out, vec0, vec1); - vec4 = __lsx_vilvl_h(vec1, vec0); - vec5 = __lsx_vilvh_h(vec1, vec0); - - dst_org -= 2; - __lsx_vstelm_w(vec2, dst_org, 0, 0); - __lsx_vstelm_w(vec2, dst_org + stride, 0, 1); - __lsx_vstelm_w(vec2, dst_org + stride2, 0, 2); - __lsx_vstelm_w(vec2, dst_org + stride3, 0, 3); - dst_org += stride4; - __lsx_vstelm_w(vec3, dst_org, 0, 0); - __lsx_vstelm_w(vec3, dst_org + stride, 0, 1); - __lsx_vstelm_w(vec3, dst_org + stride2, 0, 2); - __lsx_vstelm_w(vec3, dst_org + stride3, 0, 3); - dst_org += stride4; - __lsx_vstelm_w(vec4, dst_org, 0, 0); - __lsx_vstelm_w(vec4, dst_org + stride, 0, 1); - __lsx_vstelm_w(vec4, dst_org + stride2, 0, 2); - __lsx_vstelm_w(vec4, dst_org + stride3, 0, 3); - dst_org += stride4; - __lsx_vstelm_w(vec5, dst_org, 0, 0); - __lsx_vstelm_w(vec5, dst_org + stride, 0, 1); - __lsx_vstelm_w(vec5, dst_org + stride2, 0, 2); - __lsx_vstelm_w(vec5, dst_org + stride3, 0, 3); - - return 1; - } - - DUP4_ARG2(__lsx_vsllwil_hu_bu, p3, 0, p2, 0, p1, 0, p0, 0, p3_l, p2_l, p1_l, - p0_l); - DUP4_ARG2(__lsx_vsllwil_hu_bu, q0, 0, q1, 0, q2, 0, q3, 0, q0_l, q1_l, q2_l, - q3_l); - VP9_FILTER8(p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l, p2_filt8_l, - p1_filt8_l, p0_filt8_l, q0_filt8_l, q1_filt8_l, q2_filt8_l); - DUP4_ARG1(__lsx_vexth_hu_bu, p3, p2, p1, p0, p3_h, p2_h, p1_h, p0_h); - DUP4_ARG1(__lsx_vexth_hu_bu, q0, q1, q2, q3, q0_h, q1_h, q2_h, q3_h); - VP9_FILTER8(p3_h, p2_h, p1_h, p0_h, q0_h, q1_h, q2_h, q3_h, p2_filt8_h, - p1_filt8_h, p0_filt8_h, q0_filt8_h, q1_filt8_h, q2_filt8_h); - - /* convert 16 bit output data into 8 bit */ - DUP4_ARG2(__lsx_vpickev_b, p2_filt8_h, p2_filt8_l, p1_filt8_h, p1_filt8_l, - p0_filt8_h, p0_filt8_l, q0_filt8_h, q0_filt8_l, p2_filt8_l, - p1_filt8_l, p0_filt8_l, q0_filt8_l); - DUP2_ARG2(__lsx_vpickev_b, q1_filt8_h, q1_filt8_l, q2_filt8_h, q2_filt8_l, - q1_filt8_l, q2_filt8_l); - - /* store pixel values */ - p2_out = __lsx_vbitsel_v(p2, p2_filt8_l, flat); - p1_out = __lsx_vbitsel_v(p1_out, p1_filt8_l, flat); - p0_out = __lsx_vbitsel_v(p0_out, p0_filt8_l, flat); - q0_out = __lsx_vbitsel_v(q0_out, q0_filt8_l, flat); - q1_out = __lsx_vbitsel_v(q1_out, q1_filt8_l, flat); - q2_out = __lsx_vbitsel_v(q2, q2_filt8_l, flat); - - __lsx_vst(p2_out, filter48, 0); - __lsx_vst(p1_out, filter48, 16); - __lsx_vst(p0_out, filter48, 32); - __lsx_vst(q0_out, filter48, 48); - __lsx_vst(q1_out, filter48, 64); - __lsx_vst(q2_out, filter48, 80); - __lsx_vst(flat, filter48, 96); - - return 0; -} - -static int32_t vt_lpf_t16_16w(uint8_t *dst, uint8_t *dst_org, int32_t stride, - uint8_t *filter48) { - __m128i flat, flat2, filter8; - __m128i p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7; - __m128i out_l, out_h; - v8u16 p7_l_in, p6_l_in, p5_l_in, p4_l_in; - v8u16 p3_l_in, p2_l_in, p1_l_in, p0_l_in; - v8u16 q7_l_in, q6_l_in, q5_l_in, q4_l_in; - v8u16 q3_l_in, q2_l_in, q1_l_in, q0_l_in; - v8u16 p7_h_in, p6_h_in, p5_h_in, p4_h_in; - v8u16 p3_h_in, p2_h_in, p1_h_in, p0_h_in; - v8u16 q7_h_in, q6_h_in, q5_h_in, q4_h_in; - v8u16 q3_h_in, q2_h_in, q1_h_in, q0_h_in; - v8u16 tmp0_l, tmp1_l, tmp0_h, tmp1_h; - uint8_t *dst_tmp = dst - 128; - - flat = __lsx_vld(filter48, 96); - - DUP4_ARG2(__lsx_vld, dst_tmp, 0, dst_tmp, 16, dst_tmp, 32, dst_tmp, 48, p7, - p6, p5, p4); - DUP4_ARG2(__lsx_vld, dst_tmp, 64, dst_tmp, 80, dst_tmp, 96, dst_tmp, 112, p3, - p2, p1, p0); - DUP4_ARG2(__lsx_vld, dst, 0, dst, 16, dst, 32, dst, 48, q0, q1, q2, q3); - DUP4_ARG2(__lsx_vld, dst, 64, dst, 80, dst, 96, dst, 112, q4, q5, q6, q7); - - VP9_FLAT5(p7, p6, p5, p4, p0, q0, q4, q5, q6, q7, flat, flat2); - /* if flat2 is zero for all pixels, then no need to calculate other filter */ - if (__lsx_bz_v(flat2)) { - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - - DUP4_ARG2(__lsx_vld, filter48, 0, filter48, 16, filter48, 32, filter48, 48, - p2, p1, p0, q0); - DUP2_ARG2(__lsx_vld, filter48, 64, filter48, 80, q1, q2); - - DUP2_ARG2(__lsx_vilvl_b, p1, p2, q0, p0, vec0, vec1); - vec3 = __lsx_vilvl_h(vec1, vec0); - vec4 = __lsx_vilvh_h(vec1, vec0); - DUP2_ARG2(__lsx_vilvh_b, p1, p2, q0, p0, vec0, vec1); - vec6 = __lsx_vilvl_h(vec1, vec0); - vec7 = __lsx_vilvh_h(vec1, vec0); - vec2 = __lsx_vilvl_b(q2, q1); - vec5 = __lsx_vilvh_b(q2, q1); - - dst_org -= 3; - __lsx_vstelm_w(vec3, dst_org, 0, 0); - __lsx_vstelm_h(vec2, dst_org, 4, 0); - dst_org += stride; - __lsx_vstelm_w(vec3, dst_org, 0, 1); - __lsx_vstelm_h(vec2, dst_org, 4, 1); - dst_org += stride; - __lsx_vstelm_w(vec3, dst_org, 0, 2); - __lsx_vstelm_h(vec2, dst_org, 4, 2); - dst_org += stride; - __lsx_vstelm_w(vec3, dst_org, 0, 3); - __lsx_vstelm_h(vec2, dst_org, 4, 3); - dst_org += stride; - __lsx_vstelm_w(vec4, dst_org, 0, 0); - __lsx_vstelm_h(vec2, dst_org, 4, 4); - dst_org += stride; - __lsx_vstelm_w(vec4, dst_org, 0, 1); - __lsx_vstelm_h(vec2, dst_org, 4, 5); - dst_org += stride; - __lsx_vstelm_w(vec4, dst_org, 0, 2); - __lsx_vstelm_h(vec2, dst_org, 4, 6); - dst_org += stride; - __lsx_vstelm_w(vec4, dst_org, 0, 3); - __lsx_vstelm_h(vec2, dst_org, 4, 7); - dst_org += stride; - __lsx_vstelm_w(vec6, dst_org, 0, 0); - __lsx_vstelm_h(vec5, dst_org, 4, 0); - dst_org += stride; - __lsx_vstelm_w(vec6, dst_org, 0, 1); - __lsx_vstelm_h(vec5, dst_org, 4, 1); - dst_org += stride; - __lsx_vstelm_w(vec6, dst_org, 0, 2); - __lsx_vstelm_h(vec5, dst_org, 4, 2); - dst_org += stride; - __lsx_vstelm_w(vec6, dst_org, 0, 3); - __lsx_vstelm_h(vec5, dst_org, 4, 3); - dst_org += stride; - __lsx_vstelm_w(vec7, dst_org, 0, 0); - __lsx_vstelm_h(vec5, dst_org, 4, 4); - dst_org += stride; - __lsx_vstelm_w(vec7, dst_org, 0, 1); - __lsx_vstelm_h(vec5, dst_org, 4, 5); - dst_org += stride; - __lsx_vstelm_w(vec7, dst_org, 0, 2); - __lsx_vstelm_h(vec5, dst_org, 4, 6); - dst_org += stride; - __lsx_vstelm_w(vec7, dst_org, 0, 3); - __lsx_vstelm_h(vec5, dst_org, 4, 7); - - return 1; - } - - dst -= 7 * 16; - - p7_l_in = (v8u16)__lsx_vsllwil_hu_bu(p7, 0); - p6_l_in = (v8u16)__lsx_vsllwil_hu_bu(p6, 0); - p5_l_in = (v8u16)__lsx_vsllwil_hu_bu(p5, 0); - p4_l_in = (v8u16)__lsx_vsllwil_hu_bu(p4, 0); - p3_l_in = (v8u16)__lsx_vsllwil_hu_bu(p3, 0); - p2_l_in = (v8u16)__lsx_vsllwil_hu_bu(p2, 0); - p1_l_in = (v8u16)__lsx_vsllwil_hu_bu(p1, 0); - p0_l_in = (v8u16)__lsx_vsllwil_hu_bu(p0, 0); - q0_l_in = (v8u16)__lsx_vsllwil_hu_bu(q0, 0); - - tmp0_l = p7_l_in << 3; - tmp0_l -= p7_l_in; - tmp0_l += p6_l_in; - tmp0_l += q0_l_in; - tmp1_l = p6_l_in + p5_l_in; - tmp1_l += p4_l_in; - tmp1_l += p3_l_in; - tmp1_l += p2_l_in; - tmp1_l += p1_l_in; - tmp1_l += p0_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - p7_h_in = (v8u16)__lsx_vexth_hu_bu(p7); - p6_h_in = (v8u16)__lsx_vexth_hu_bu(p6); - p5_h_in = (v8u16)__lsx_vexth_hu_bu(p5); - p4_h_in = (v8u16)__lsx_vexth_hu_bu(p4); - p3_h_in = (v8u16)__lsx_vexth_hu_bu(p3); - p2_h_in = (v8u16)__lsx_vexth_hu_bu(p2); - p1_h_in = (v8u16)__lsx_vexth_hu_bu(p1); - p0_h_in = (v8u16)__lsx_vexth_hu_bu(p0); - q0_h_in = (v8u16)__lsx_vexth_hu_bu(q0); - - tmp0_h = p7_h_in << 3; - tmp0_h -= p7_h_in; - tmp0_h += p6_h_in; - tmp0_h += q0_h_in; - tmp1_h = p6_h_in + p5_h_in; - tmp1_h += p4_h_in; - tmp1_h += p3_h_in; - tmp1_h += p2_h_in; - tmp1_h += p1_h_in; - tmp1_h += p0_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - - out_l = __lsx_vpickev_b(out_h, out_l); - p6 = __lsx_vbitsel_v(p6, out_l, flat2); - __lsx_vst(p6, dst, 0); - - /* p5 */ - q1_l_in = (v8u16)__lsx_vsllwil_hu_bu(q1, 0); - tmp0_l = p5_l_in - p6_l_in; - tmp0_l += q1_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - q1_h_in = (v8u16)__lsx_vexth_hu_bu(q1); - tmp0_h = p5_h_in - p6_h_in; - tmp0_h += q1_h_in; - tmp0_h -= p7_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - out_l = __lsx_vpickev_b(out_h, out_l); - p5 = __lsx_vbitsel_v(p5, out_l, flat2); - __lsx_vst(p5, dst, 16); - - /* p4 */ - q2_l_in = (v8u16)__lsx_vsllwil_hu_bu(q2, 0); - tmp0_l = p4_l_in - p5_l_in; - tmp0_l += q2_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - q2_h_in = (v8u16)__lsx_vexth_hu_bu(q2); - tmp0_h = p4_h_in - p5_h_in; - tmp0_h += q2_h_in; - tmp0_h -= p7_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - out_l = __lsx_vpickev_b(out_h, out_l); - p4 = __lsx_vbitsel_v(p4, out_l, flat2); - __lsx_vst(p4, dst, 16 * 2); - - /* p3 */ - q3_l_in = (v8u16)__lsx_vsllwil_hu_bu(q3, 0); - tmp0_l = p3_l_in - p4_l_in; - tmp0_l += q3_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - q3_h_in = (v8u16)__lsx_vexth_hu_bu(q3); - tmp0_h = p3_h_in - p4_h_in; - tmp0_h += q3_h_in; - tmp0_h -= p7_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - out_l = __lsx_vpickev_b(out_h, out_l); - p3 = __lsx_vbitsel_v(p3, out_l, flat2); - __lsx_vst(p3, dst, 16 * 3); - - /* p2 */ - q4_l_in = (v8u16)__lsx_vsllwil_hu_bu(q4, 0); - filter8 = __lsx_vld(filter48, 0); - tmp0_l = p2_l_in - p3_l_in; - tmp0_l += q4_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - q4_h_in = (v8u16)__lsx_vexth_hu_bu(q4); - tmp0_h = p2_h_in - p3_h_in; - tmp0_h += q4_h_in; - tmp0_h -= p7_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - out_l = __lsx_vpickev_b(out_h, out_l); - filter8 = __lsx_vbitsel_v(filter8, out_l, flat2); - __lsx_vst(filter8, dst, 16 * 4); - - /* p1 */ - q5_l_in = (v8u16)__lsx_vsllwil_hu_bu(q5, 0); - filter8 = __lsx_vld(filter48, 16); - tmp0_l = p1_l_in - p2_l_in; - tmp0_l += q5_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - q5_h_in = (v8u16)__lsx_vexth_hu_bu(q5); - tmp0_h = p1_h_in - p2_h_in; - tmp0_h += q5_h_in; - tmp0_h -= p7_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)(tmp1_h), 4); - out_l = __lsx_vpickev_b(out_h, out_l); - filter8 = __lsx_vbitsel_v(filter8, out_l, flat2); - __lsx_vst(filter8, dst, 16 * 5); - - /* p0 */ - q6_l_in = (v8u16)__lsx_vsllwil_hu_bu(q6, 0); - filter8 = __lsx_vld(filter48, 32); - tmp0_l = p0_l_in - p1_l_in; - tmp0_l += q6_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - q6_h_in = (v8u16)__lsx_vexth_hu_bu(q6); - tmp0_h = p0_h_in - p1_h_in; - tmp0_h += q6_h_in; - tmp0_h -= p7_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - out_l = __lsx_vpickev_b(out_h, out_l); - filter8 = __lsx_vbitsel_v(filter8, out_l, flat2); - __lsx_vst(filter8, dst, 16 * 6); - - /* q0 */ - q7_l_in = (v8u16)__lsx_vsllwil_hu_bu(q7, 0); - filter8 = __lsx_vld(filter48, 48); - tmp0_l = q7_l_in - p0_l_in; - tmp0_l += q0_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - q7_h_in = (v8u16)__lsx_vexth_hu_bu(q7); - tmp0_h = q7_h_in - p0_h_in; - tmp0_h += q0_h_in; - tmp0_h -= p7_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - out_l = __lsx_vpickev_b(out_h, out_l); - filter8 = __lsx_vbitsel_v(filter8, out_l, flat2); - __lsx_vst(filter8, dst, 16 * 7); - - /* q1 */ - filter8 = __lsx_vld(filter48, 64); - tmp0_l = q7_l_in - q0_l_in; - tmp0_l += q1_l_in; - tmp0_l -= p6_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - tmp0_h = q7_h_in - q0_h_in; - tmp0_h += q1_h_in; - tmp0_h -= p6_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - out_l = __lsx_vpickev_b(out_h, out_l); - filter8 = __lsx_vbitsel_v(filter8, out_l, flat2); - __lsx_vst(filter8, dst, 16 * 8); - - /* q2 */ - filter8 = __lsx_vld(filter48, 80); - tmp0_l = q7_l_in - q1_l_in; - tmp0_l += q2_l_in; - tmp0_l -= p5_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - tmp0_h = q7_h_in - q1_h_in; - tmp0_h += q2_h_in; - tmp0_h -= p5_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - out_l = __lsx_vpickev_b(out_h, out_l); - filter8 = __lsx_vbitsel_v(filter8, out_l, flat2); - __lsx_vst(filter8, dst, 16 * 9); - - /* q3 */ - tmp0_l = q7_l_in - q2_l_in; - tmp0_l += q3_l_in; - tmp0_l -= p4_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - tmp0_h = q7_h_in - q2_h_in; - tmp0_h += q3_h_in; - tmp0_h -= p4_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - out_l = __lsx_vpickev_b(out_h, out_l); - q3 = __lsx_vbitsel_v(q3, out_l, flat2); - __lsx_vst(q3, dst, 16 * 10); - - /* q4 */ - tmp0_l = q7_l_in - q3_l_in; - tmp0_l += q4_l_in; - tmp0_l -= p3_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - tmp0_h = q7_h_in - q3_h_in; - tmp0_h += q4_h_in; - tmp0_h -= p3_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - out_l = __lsx_vpickev_b(out_h, out_l); - q4 = __lsx_vbitsel_v(q4, out_l, flat2); - __lsx_vst(q4, dst, 16 * 11); - - /* q5 */ - tmp0_l = q7_l_in - q4_l_in; - tmp0_l += q5_l_in; - tmp0_l -= p2_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - tmp0_h = q7_h_in - q4_h_in; - tmp0_h += q5_h_in; - tmp0_h -= p2_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - out_l = __lsx_vpickev_b(out_h, out_l); - q5 = __lsx_vbitsel_v(q5, out_l, flat2); - __lsx_vst(q5, dst, 16 * 12); - - /* q6 */ - tmp0_l = q7_l_in - q5_l_in; - tmp0_l += q6_l_in; - tmp0_l -= p1_l_in; - tmp1_l += tmp0_l; - out_l = __lsx_vsrari_h((__m128i)tmp1_l, 4); - tmp0_h = q7_h_in - q5_h_in; - tmp0_h += q6_h_in; - tmp0_h -= p1_h_in; - tmp1_h += tmp0_h; - out_h = __lsx_vsrari_h((__m128i)tmp1_h, 4); - out_l = __lsx_vpickev_b(out_h, out_l); - q6 = __lsx_vbitsel_v(q6, out_l, flat2); - __lsx_vst(q6, dst, 16 * 13); - - return 0; -} - -void vpx_lpf_vertical_16_dual_lsx(uint8_t *src, int32_t pitch, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - uint8_t early_exit = 0; - DECLARE_ALIGNED(16, uint8_t, transposed_input[16 * 24]); - uint8_t *filter48 = &transposed_input[16 * 16]; - - transpose_16x16((src - 8), pitch, &transposed_input[0], 16); - - early_exit = - vt_lpf_t4_and_t8_16w((transposed_input + 16 * 8), &filter48[0], src, - pitch, b_limit_ptr, limit_ptr, thresh_ptr); - - if (early_exit == 0) { - early_exit = - vt_lpf_t16_16w((transposed_input + 16 * 8), src, pitch, &filter48[0]); - - if (early_exit == 0) { - transpose_16x16(transposed_input, 16, (src - 8), pitch); - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/loopfilter_4_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/loopfilter_4_lsx.c deleted file mode 100644 index 9300b5c5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/loopfilter_4_lsx.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/loongarch/loopfilter_lsx.h" - -void vpx_lpf_horizontal_4_lsx(uint8_t *src, int32_t pitch, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - __m128i mask, hev, flat, thresh, b_limit, limit; - __m128i p3, p2, p1, p0, q3, q2, q1, q0, p1_out, p0_out, q0_out, q1_out; - int32_t pitch2 = pitch << 1; - int32_t pitch3 = pitch2 + pitch; - int32_t pitch4 = pitch2 << 1; - - DUP4_ARG2(__lsx_vldx, src, -pitch4, src, -pitch3, src, -pitch2, src, -pitch, - p3, p2, p1, p0); - q0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, pitch, src, pitch2, q1, q2); - q3 = __lsx_vldx(src, pitch3); - - thresh = __lsx_vldrepl_b(thresh_ptr, 0); - b_limit = __lsx_vldrepl_b(b_limit_ptr, 0); - limit = __lsx_vldrepl_b(limit_ptr, 0); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); - - __lsx_vstelm_d(p1_out, src - pitch2, 0, 0); - __lsx_vstelm_d(p0_out, src - pitch, 0, 0); - __lsx_vstelm_d(q0_out, src, 0, 0); - __lsx_vstelm_d(q1_out, src + pitch, 0, 0); -} - -void vpx_lpf_horizontal_4_dual_lsx(uint8_t *src, int32_t pitch, - const uint8_t *b_limit0_ptr, - const uint8_t *limit0_ptr, - const uint8_t *thresh0_ptr, - const uint8_t *b_limit1_ptr, - const uint8_t *limit1_ptr, - const uint8_t *thresh1_ptr) { - __m128i mask, hev, flat, thresh0, b_limit0, limit0, thresh1, b_limit1, limit1; - __m128i p3, p2, p1, p0, q3, q2, q1, q0; - int32_t pitch2 = pitch << 1; - int32_t pitch3 = pitch2 + pitch; - int32_t pitch4 = pitch2 << 1; - - DUP4_ARG2(__lsx_vldx, src, -pitch4, src, -pitch3, src, -pitch2, src, -pitch, - p3, p2, p1, p0); - q0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, pitch, src, pitch2, q1, q2); - q3 = __lsx_vldx(src, pitch3); - - thresh0 = __lsx_vldrepl_b(thresh0_ptr, 0); - thresh1 = __lsx_vldrepl_b(thresh1_ptr, 0); - thresh0 = __lsx_vilvl_d(thresh1, thresh0); - - b_limit0 = __lsx_vldrepl_b(b_limit0_ptr, 0); - b_limit1 = __lsx_vldrepl_b(b_limit1_ptr, 0); - b_limit0 = __lsx_vilvl_d(b_limit1, b_limit0); - - limit0 = __lsx_vldrepl_b(limit0_ptr, 0); - limit1 = __lsx_vldrepl_b(limit1_ptr, 0); - limit0 = __lsx_vilvl_d(limit1, limit0); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit0, b_limit0, thresh0, hev, - mask, flat); - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1, p0, q0, q1); - - __lsx_vstx(p1, src, -pitch2); - __lsx_vstx(p0, src, -pitch); - __lsx_vst(q0, src, 0); - __lsx_vstx(q1, src, pitch); -} - -void vpx_lpf_vertical_4_lsx(uint8_t *src, int32_t pitch, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - __m128i mask, hev, flat, limit, thresh, b_limit; - __m128i p3, p2, p1, p0, q3, q2, q1, q0; - __m128i vec0, vec1, vec2, vec3; - int32_t pitch2 = pitch << 1; - int32_t pitch3 = pitch2 + pitch; - int32_t pitch4 = pitch2 << 1; - uint8_t *src_tmp = src - 4; - - p3 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, pitch, src_tmp, pitch2, p2, p1); - p0 = __lsx_vldx(src_tmp, pitch3); - src_tmp += pitch4; - q0 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, pitch, src_tmp, pitch2, q1, q2); - q3 = __lsx_vldx(src_tmp, pitch3); - - thresh = __lsx_vldrepl_b(thresh_ptr, 0); - b_limit = __lsx_vldrepl_b(b_limit_ptr, 0); - limit = __lsx_vldrepl_b(limit_ptr, 0); - - LSX_TRANSPOSE8x8_B(p3, p2, p1, p0, q0, q1, q2, q3, p3, p2, p1, p0, q0, q1, q2, - q3); - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1, p0, q0, q1); - DUP2_ARG2(__lsx_vilvl_b, p0, p1, q1, q0, vec0, vec1); - vec2 = __lsx_vilvl_h(vec1, vec0); - vec3 = __lsx_vilvh_h(vec1, vec0); - - src -= 2; - __lsx_vstelm_w(vec2, src, 0, 0); - src += pitch; - __lsx_vstelm_w(vec2, src, 0, 1); - src += pitch; - __lsx_vstelm_w(vec2, src, 0, 2); - src += pitch; - __lsx_vstelm_w(vec2, src, 0, 3); - src += pitch; - - __lsx_vstelm_w(vec3, src, 0, 0); - __lsx_vstelm_w(vec3, src + pitch, 0, 1); - __lsx_vstelm_w(vec3, src + pitch2, 0, 2); - __lsx_vstelm_w(vec3, src + pitch3, 0, 3); -} - -void vpx_lpf_vertical_4_dual_lsx(uint8_t *src, int32_t pitch, - const uint8_t *b_limit0_ptr, - const uint8_t *limit0_ptr, - const uint8_t *thresh0_ptr, - const uint8_t *b_limit1_ptr, - const uint8_t *limit1_ptr, - const uint8_t *thresh1_ptr) { - __m128i mask, hev, flat; - __m128i thresh0, b_limit0, limit0, thresh1, b_limit1, limit1; - __m128i p3, p2, p1, p0, q3, q2, q1, q0; - __m128i row0, row1, row2, row3, row4, row5, row6, row7; - __m128i row8, row9, row10, row11, row12, row13, row14, row15; - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; - int32_t pitch2 = pitch << 1; - int32_t pitch3 = pitch2 + pitch; - int32_t pitch4 = pitch2 << 1; - uint8_t *src_tmp = src - 4; - - row0 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, pitch, src_tmp, pitch2, row1, row2); - row3 = __lsx_vldx(src_tmp, pitch3); - src_tmp += pitch4; - row4 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, pitch, src_tmp, pitch2, row5, row6); - row7 = __lsx_vldx(src_tmp, pitch3); - src_tmp += pitch4; - row8 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, pitch, src_tmp, pitch2, row9, row10); - row11 = __lsx_vldx(src_tmp, pitch3); - src_tmp += pitch4; - row12 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, pitch, src_tmp, pitch2, row13, row14); - row15 = __lsx_vldx(src_tmp, pitch3); - - LSX_TRANSPOSE16x8_B(row0, row1, row2, row3, row4, row5, row6, row7, row8, - row9, row10, row11, row12, row13, row14, row15, p3, p2, - p1, p0, q0, q1, q2, q3); - - thresh0 = __lsx_vldrepl_b(thresh0_ptr, 0); - thresh1 = __lsx_vldrepl_b(thresh1_ptr, 0); - thresh0 = __lsx_vilvl_d(thresh1, thresh0); - - b_limit0 = __lsx_vldrepl_b(b_limit0_ptr, 0); - b_limit1 = __lsx_vldrepl_b(b_limit1_ptr, 0); - b_limit0 = __lsx_vilvl_d(b_limit1, b_limit0); - - limit0 = __lsx_vldrepl_b(limit0_ptr, 0); - limit1 = __lsx_vldrepl_b(limit1_ptr, 0); - limit0 = __lsx_vilvl_d(limit1, limit0); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit0, b_limit0, thresh0, hev, - mask, flat); - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1, p0, q0, q1); - DUP2_ARG2(__lsx_vilvl_b, p0, p1, q1, q0, tmp0, tmp1); - tmp2 = __lsx_vilvl_h(tmp1, tmp0); - tmp3 = __lsx_vilvh_h(tmp1, tmp0); - DUP2_ARG2(__lsx_vilvh_b, p0, p1, q1, q0, tmp0, tmp1); - tmp4 = __lsx_vilvl_h(tmp1, tmp0); - tmp5 = __lsx_vilvh_h(tmp1, tmp0); - - src -= 2; - __lsx_vstelm_w(tmp2, src, 0, 0); - __lsx_vstelm_w(tmp2, src + pitch, 0, 1); - __lsx_vstelm_w(tmp2, src + pitch2, 0, 2); - __lsx_vstelm_w(tmp2, src + pitch3, 0, 3); - src += pitch4; - __lsx_vstelm_w(tmp3, src, 0, 0); - __lsx_vstelm_w(tmp3, src + pitch, 0, 1); - __lsx_vstelm_w(tmp3, src + pitch2, 0, 2); - __lsx_vstelm_w(tmp3, src + pitch3, 0, 3); - src += pitch4; - __lsx_vstelm_w(tmp4, src, 0, 0); - __lsx_vstelm_w(tmp4, src + pitch, 0, 1); - __lsx_vstelm_w(tmp4, src + pitch2, 0, 2); - __lsx_vstelm_w(tmp4, src + pitch3, 0, 3); - src += pitch4; - __lsx_vstelm_w(tmp5, src, 0, 0); - __lsx_vstelm_w(tmp5, src + pitch, 0, 1); - __lsx_vstelm_w(tmp5, src + pitch2, 0, 2); - __lsx_vstelm_w(tmp5, src + pitch3, 0, 3); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/loopfilter_8_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/loopfilter_8_lsx.c deleted file mode 100644 index 00219ba7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/loopfilter_8_lsx.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/loongarch/loopfilter_lsx.h" - -void vpx_lpf_horizontal_8_lsx(uint8_t *dst, int32_t stride, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - __m128i mask, hev, flat, thresh, b_limit, limit; - __m128i p3, p2, p1, p0, q3, q2, q1, q0; - __m128i p2_out, p1_out, p0_out, q0_out, q1_out; - __m128i p2_filter8, p1_filter8, p0_filter8; - __m128i q0_filter8, q1_filter8, q2_filter8; - __m128i p3_l, p2_l, p1_l, p0_l, q3_l, q2_l, q1_l, q0_l; - - int32_t stride2 = stride << 1; - int32_t stride3 = stride2 + stride; - int32_t stride4 = stride2 << 1; - - /* load vector elements */ - DUP4_ARG2(__lsx_vldx, dst, -stride4, dst, -stride3, dst, -stride2, dst, - -stride, p3, p2, p1, p0); - q0 = __lsx_vld(dst, 0); - DUP2_ARG2(__lsx_vldx, dst, stride, dst, stride2, q1, q2); - q3 = __lsx_vldx(dst, stride3); - - thresh = __lsx_vldrepl_b(thresh_ptr, 0); - b_limit = __lsx_vldrepl_b(b_limit_ptr, 0); - limit = __lsx_vldrepl_b(limit_ptr, 0); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); - - flat = __lsx_vilvl_d(flat, flat); - - if (__lsx_bz_v(flat)) { - __lsx_vstelm_d(p1_out, dst - stride2, 0, 0); - __lsx_vstelm_d(p0_out, dst - stride, 0, 0); - __lsx_vstelm_d(q0_out, dst, 0, 0); - __lsx_vstelm_d(q1_out, dst + stride, 0, 0); - } else { - DUP4_ARG2(__lsx_vsllwil_hu_bu, p3, 0, p2, 0, p1, 0, p0, 0, p3_l, p2_l, p1_l, - p0_l); - DUP4_ARG2(__lsx_vsllwil_hu_bu, q0, 0, q1, 0, q2, 0, q3, 0, q0_l, q1_l, q2_l, - q3_l); - VP9_FILTER8(p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l, p2_filter8, - p1_filter8, p0_filter8, q0_filter8, q1_filter8, q2_filter8); - - DUP2_ARG2(__lsx_vpickev_b, p1_filter8, p2_filter8, q0_filter8, p0_filter8, - p1_filter8, q0_filter8); - q2_filter8 = __lsx_vpickev_b(q2_filter8, q1_filter8); - - p2 = __lsx_vilvl_d(p1_out, p2); - p0_out = __lsx_vilvl_d(q0_out, p0_out); - q1_out = __lsx_vilvl_d(q2, q1_out); - - DUP2_ARG3(__lsx_vbitsel_v, p2, p1_filter8, flat, p0_out, q0_filter8, flat, - p2_out, p1_out); - p0_out = __lsx_vbitsel_v(q1_out, q2_filter8, flat); - dst -= stride3; - - __lsx_vstelm_d(p2_out, dst, 0, 0); - __lsx_vstelm_d(p2_out, dst + stride, 0, 1); - __lsx_vstelm_d(p1_out, dst + stride2, 0, 0); - __lsx_vstelm_d(p1_out, dst + stride3, 0, 1); - - dst += stride4; - __lsx_vstelm_d(p0_out, dst, 0, 0); - dst += stride; - __lsx_vstelm_d(p0_out, dst, 0, 1); - } -} - -void vpx_lpf_horizontal_8_dual_lsx( - uint8_t *dst, int32_t stride, const uint8_t *b_limit0, - const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *b_limit1, - const uint8_t *limit1, const uint8_t *thresh1) { - __m128i p3, p2, p1, p0, q3, q2, q1, q0; - __m128i p2_out, p1_out, p0_out, q0_out, q1_out, q2_out; - __m128i flat, mask, hev, thresh, b_limit, limit; - __m128i p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l; - __m128i p3_h, p2_h, p1_h, p0_h, q0_h, q1_h, q2_h, q3_h; - __m128i p2_filt8_l, p1_filt8_l, p0_filt8_l; - __m128i q0_filt8_l, q1_filt8_l, q2_filt8_l; - __m128i p2_filt8_h, p1_filt8_h, p0_filt8_h; - __m128i q0_filt8_h, q1_filt8_h, q2_filt8_h; - - int32_t stride2 = stride << 1; - int32_t stride3 = stride2 + stride; - int32_t stride4 = stride2 << 1; - - DUP4_ARG2(__lsx_vldx, dst, -stride4, dst, -stride3, dst, -stride2, dst, - -stride, p3, p2, p1, p0); - q0 = __lsx_vld(dst, 0); - DUP2_ARG2(__lsx_vldx, dst, stride, dst, stride2, q1, q2); - q3 = __lsx_vldx(dst, stride3); - - thresh = __lsx_vldrepl_b(thresh0, 0); - p2_out = __lsx_vldrepl_b(thresh1, 0); - thresh = __lsx_vilvl_d(p2_out, thresh); - - b_limit = __lsx_vldrepl_b(b_limit0, 0); - p2_out = __lsx_vldrepl_b(b_limit1, 0); - b_limit = __lsx_vilvl_d(p2_out, b_limit); - - limit = __lsx_vldrepl_b(limit0, 0); - p2_out = __lsx_vldrepl_b(limit1, 0); - limit = __lsx_vilvl_d(p2_out, limit); - - /* mask and hev */ - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); - - if (__lsx_bz_v(flat)) { - __lsx_vst(p1_out, dst - stride2, 0); - __lsx_vst(p0_out, dst - stride, 0); - __lsx_vst(q0_out, dst, 0); - __lsx_vst(q1_out, dst + stride, 0); - } else { - DUP4_ARG2(__lsx_vsllwil_hu_bu, p3, 0, p2, 0, p1, 0, p0, 0, p3_l, p2_l, p1_l, - p0_l); - DUP4_ARG2(__lsx_vsllwil_hu_bu, q0, 0, q1, 0, q2, 0, q3, 0, q0_l, q1_l, q2_l, - q3_l); - VP9_FILTER8(p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l, p2_filt8_l, - p1_filt8_l, p0_filt8_l, q0_filt8_l, q1_filt8_l, q2_filt8_l); - - DUP4_ARG1(__lsx_vexth_hu_bu, p3, p2, p1, p0, p3_h, p2_h, p1_h, p0_h); - DUP4_ARG1(__lsx_vexth_hu_bu, q0, q1, q2, q3, q0_h, q1_h, q2_h, q3_h); - VP9_FILTER8(p3_h, p2_h, p1_h, p0_h, q0_h, q1_h, q2_h, q3_h, p2_filt8_h, - p1_filt8_h, p0_filt8_h, q0_filt8_h, q1_filt8_h, q2_filt8_h); - - /* convert 16 bit output data into 8 bit */ - DUP4_ARG2(__lsx_vpickev_b, p2_filt8_h, p2_filt8_l, p1_filt8_h, p1_filt8_l, - p0_filt8_h, p0_filt8_l, q0_filt8_h, q0_filt8_l, p2_filt8_l, - p1_filt8_l, p0_filt8_l, q0_filt8_l); - DUP2_ARG2(__lsx_vpickev_b, q1_filt8_h, q1_filt8_l, q2_filt8_h, q2_filt8_l, - q1_filt8_l, q2_filt8_l); - - /* store pixel values */ - p2_out = __lsx_vbitsel_v(p2, p2_filt8_l, flat); - p1_out = __lsx_vbitsel_v(p1_out, p1_filt8_l, flat); - p0_out = __lsx_vbitsel_v(p0_out, p0_filt8_l, flat); - q0_out = __lsx_vbitsel_v(q0_out, q0_filt8_l, flat); - q1_out = __lsx_vbitsel_v(q1_out, q1_filt8_l, flat); - q2_out = __lsx_vbitsel_v(q2, q2_filt8_l, flat); - - __lsx_vst(p2_out, dst - stride3, 0); - __lsx_vst(p1_out, dst - stride2, 0); - __lsx_vst(p0_out, dst - stride, 0); - __lsx_vst(q0_out, dst, 0); - __lsx_vst(q1_out, dst + stride, 0); - __lsx_vst(q2_out, dst + stride2, 0); - } -} - -void vpx_lpf_vertical_8_lsx(uint8_t *dst, int32_t stride, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - __m128i p3, p2, p1, p0, q3, q2, q1, q0; - __m128i p1_out, p0_out, q0_out, q1_out; - __m128i flat, mask, hev, thresh, b_limit, limit; - __m128i p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l; - __m128i p2_filt8_l, p1_filt8_l, p0_filt8_l; - __m128i q0_filt8_l, q1_filt8_l, q2_filt8_l; - __m128i zero = __lsx_vldi(0); - - int32_t stride2 = stride << 1; - int32_t stride3 = stride2 + stride; - int32_t stride4 = stride2 << 1; - uint8_t *dst_tmp = dst - 4; - - /* load vector elements */ - p3 = __lsx_vld(dst_tmp, 0); - DUP2_ARG2(__lsx_vldx, dst_tmp, stride, dst_tmp, stride2, p2, p1); - p0 = __lsx_vldx(dst_tmp, stride3); - dst_tmp += stride4; - q0 = __lsx_vld(dst_tmp, 0); - DUP2_ARG2(__lsx_vldx, dst_tmp, stride, dst_tmp, stride2, q1, q2); - q3 = __lsx_vldx(dst_tmp, stride3); - - LSX_TRANSPOSE8x8_B(p3, p2, p1, p0, q0, q1, q2, q3, p3, p2, p1, p0, q0, q1, q2, - q3); - - thresh = __lsx_vldrepl_b(thresh_ptr, 0); - b_limit = __lsx_vldrepl_b(b_limit_ptr, 0); - limit = __lsx_vldrepl_b(limit_ptr, 0); - - /* mask and hev */ - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - /* flat4 */ - VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); - /* filter4 */ - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); - - flat = __lsx_vilvl_d(zero, flat); - - /* if flat is zero for all pixels, then no need to calculate other filter */ - if (__lsx_bz_v(flat)) { - /* Store 4 pixels p1-_q1 */ - DUP2_ARG2(__lsx_vilvl_b, p0_out, p1_out, q1_out, q0_out, p0, p1); - p2 = __lsx_vilvl_h(p1, p0); - p3 = __lsx_vilvh_h(p1, p0); - - dst -= 2; - __lsx_vstelm_w(p2, dst, 0, 0); - __lsx_vstelm_w(p2, dst + stride, 0, 1); - __lsx_vstelm_w(p2, dst + stride2, 0, 2); - __lsx_vstelm_w(p2, dst + stride3, 0, 3); - dst += stride4; - __lsx_vstelm_w(p3, dst, 0, 0); - __lsx_vstelm_w(p3, dst + stride, 0, 1); - __lsx_vstelm_w(p3, dst + stride2, 0, 2); - __lsx_vstelm_w(p3, dst + stride3, 0, 3); - } else { - DUP4_ARG2(__lsx_vilvl_b, zero, p3, zero, p2, zero, p1, zero, p0, p3_l, p2_l, - p1_l, p0_l); - DUP4_ARG2(__lsx_vilvl_b, zero, q0, zero, q1, zero, q2, zero, q3, q0_l, q1_l, - q2_l, q3_l); - VP9_FILTER8(p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l, p2_filt8_l, - p1_filt8_l, p0_filt8_l, q0_filt8_l, q1_filt8_l, q2_filt8_l); - /* convert 16 bit output data into 8 bit */ - DUP4_ARG2(__lsx_vpickev_b, p2_filt8_l, p2_filt8_l, p1_filt8_l, p1_filt8_l, - p0_filt8_l, p0_filt8_l, q0_filt8_l, q0_filt8_l, p2_filt8_l, - p1_filt8_l, p0_filt8_l, q0_filt8_l); - DUP2_ARG2(__lsx_vpickev_b, q1_filt8_l, q1_filt8_l, q2_filt8_l, q2_filt8_l, - q1_filt8_l, q2_filt8_l); - /* store pixel values */ - p2 = __lsx_vbitsel_v(p2, p2_filt8_l, flat); - p1 = __lsx_vbitsel_v(p1_out, p1_filt8_l, flat); - p0 = __lsx_vbitsel_v(p0_out, p0_filt8_l, flat); - q0 = __lsx_vbitsel_v(q0_out, q0_filt8_l, flat); - q1 = __lsx_vbitsel_v(q1_out, q1_filt8_l, flat); - q2 = __lsx_vbitsel_v(q2, q2_filt8_l, flat); - - /* Store 6 pixels p2-_q2 */ - DUP2_ARG2(__lsx_vilvl_b, p1, p2, q0, p0, p3, q3); - p1 = __lsx_vilvl_h(q3, p3); - p2 = __lsx_vilvh_h(q3, p3); - p3 = __lsx_vilvl_b(q2, q1); - dst -= 3; - __lsx_vstelm_w(p1, dst, 0, 0); - __lsx_vstelm_h(p3, dst, 4, 0); - dst += stride; - __lsx_vstelm_w(p1, dst, 0, 1); - __lsx_vstelm_h(p3, dst, 4, 1); - dst += stride; - __lsx_vstelm_w(p1, dst, 0, 2); - __lsx_vstelm_h(p3, dst, 4, 2); - dst += stride; - __lsx_vstelm_w(p1, dst, 0, 3); - __lsx_vstelm_h(p3, dst, 4, 3); - dst += stride; - __lsx_vstelm_w(p2, dst, 0, 0); - __lsx_vstelm_h(p3, dst, 4, 4); - dst += stride; - __lsx_vstelm_w(p2, dst, 0, 1); - __lsx_vstelm_h(p3, dst, 4, 5); - dst += stride; - __lsx_vstelm_w(p2, dst, 0, 2); - __lsx_vstelm_h(p3, dst, 4, 6); - dst += stride; - __lsx_vstelm_w(p2, dst, 0, 3); - __lsx_vstelm_h(p3, dst, 4, 7); - } -} - -void vpx_lpf_vertical_8_dual_lsx(uint8_t *dst, int32_t stride, - const uint8_t *b_limit0, const uint8_t *limit0, - const uint8_t *thresh0, - const uint8_t *b_limit1, const uint8_t *limit1, - const uint8_t *thresh1) { - uint8_t *dst_tmp = dst - 4; - __m128i p3, p2, p1, p0, q3, q2, q1, q0; - __m128i p1_out, p0_out, q0_out, q1_out; - __m128i flat, mask, hev, thresh, b_limit, limit; - __m128i row4, row5, row6, row7, row12, row13, row14, row15; - __m128i p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l; - __m128i p3_h, p2_h, p1_h, p0_h, q0_h, q1_h, q2_h, q3_h; - __m128i p2_filt8_l, p1_filt8_l, p0_filt8_l; - __m128i q0_filt8_l, q1_filt8_l, q2_filt8_l; - __m128i p2_filt8_h, p1_filt8_h, p0_filt8_h; - __m128i q0_filt8_h, q1_filt8_h, q2_filt8_h; - int32_t stride2 = stride << 1; - int32_t stride3 = stride2 + stride; - int32_t stride4 = stride2 << 1; - - p0 = __lsx_vld(dst_tmp, 0); - DUP2_ARG2(__lsx_vldx, dst_tmp, stride, dst_tmp, stride2, p1, p2); - p3 = __lsx_vldx(dst_tmp, stride3); - dst_tmp += stride4; - row4 = __lsx_vld(dst_tmp, 0); - DUP2_ARG2(__lsx_vldx, dst_tmp, stride, dst_tmp, stride2, row5, row6); - row7 = __lsx_vldx(dst_tmp, stride3); - dst_tmp += stride4; - - q3 = __lsx_vld(dst_tmp, 0); - DUP2_ARG2(__lsx_vldx, dst_tmp, stride, dst_tmp, stride2, q2, q1); - q0 = __lsx_vldx(dst_tmp, stride3); - dst_tmp += stride4; - row12 = __lsx_vld(dst_tmp, 0); - DUP2_ARG2(__lsx_vldx, dst_tmp, stride, dst_tmp, stride2, row13, row14); - row15 = __lsx_vldx(dst_tmp, stride3); - - /* transpose 16x8 matrix into 8x16 */ - LSX_TRANSPOSE16x8_B(p0, p1, p2, p3, row4, row5, row6, row7, q3, q2, q1, q0, - row12, row13, row14, row15, p3, p2, p1, p0, q0, q1, q2, - q3); - - thresh = __lsx_vldrepl_b(thresh0, 0); - p1_out = __lsx_vldrepl_b(thresh1, 0); - thresh = __lsx_vilvl_d(p1_out, thresh); - - b_limit = __lsx_vldrepl_b(b_limit0, 0); - p1_out = __lsx_vldrepl_b(b_limit1, 0); - b_limit = __lsx_vilvl_d(p1_out, b_limit); - - limit = __lsx_vldrepl_b(limit0, 0); - p1_out = __lsx_vldrepl_b(limit1, 0); - limit = __lsx_vilvl_d(p1_out, limit); - - /* mask and hev */ - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - /* flat4 */ - VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); - /* filter4 */ - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); - /* if flat is zero for all pixels, then no need to calculate other filter */ - if (__lsx_bz_v(flat)) { - DUP2_ARG2(__lsx_vilvl_b, p0_out, p1_out, q1_out, q0_out, p0, p1); - p2 = __lsx_vilvl_h(p1, p0); - p3 = __lsx_vilvh_h(p1, p0); - DUP2_ARG2(__lsx_vilvh_b, p0_out, p1_out, q1_out, q0_out, p0, p1); - q2 = __lsx_vilvl_h(p1, p0); - q3 = __lsx_vilvh_h(p1, p0); - dst -= 2; - __lsx_vstelm_w(p2, dst, 0, 0); - __lsx_vstelm_w(p2, dst + stride, 0, 1); - __lsx_vstelm_w(p2, dst + stride2, 0, 2); - __lsx_vstelm_w(p2, dst + stride3, 0, 3); - dst += stride4; - __lsx_vstelm_w(p3, dst, 0, 0); - __lsx_vstelm_w(p3, dst + stride, 0, 1); - __lsx_vstelm_w(p3, dst + stride2, 0, 2); - __lsx_vstelm_w(p3, dst + stride3, 0, 3); - dst += stride4; - __lsx_vstelm_w(q2, dst, 0, 0); - __lsx_vstelm_w(q2, dst + stride, 0, 1); - __lsx_vstelm_w(q2, dst + stride2, 0, 2); - __lsx_vstelm_w(q2, dst + stride3, 0, 3); - dst += stride4; - __lsx_vstelm_w(q3, dst, 0, 0); - __lsx_vstelm_w(q3, dst + stride, 0, 1); - __lsx_vstelm_w(q3, dst + stride2, 0, 2); - __lsx_vstelm_w(q3, dst + stride3, 0, 3); - } else { - DUP4_ARG2(__lsx_vsllwil_hu_bu, p3, 0, p2, 0, p1, 0, p0, 0, p3_l, p2_l, p1_l, - p0_l); - DUP4_ARG2(__lsx_vsllwil_hu_bu, q0, 0, q1, 0, q2, 0, q3, 0, q0_l, q1_l, q2_l, - q3_l); - VP9_FILTER8(p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l, p2_filt8_l, - p1_filt8_l, p0_filt8_l, q0_filt8_l, q1_filt8_l, q2_filt8_l); - DUP4_ARG1(__lsx_vexth_hu_bu, p3, p2, p1, p0, p3_h, p2_h, p1_h, p0_h); - DUP4_ARG1(__lsx_vexth_hu_bu, q0, q1, q2, q3, q0_h, q1_h, q2_h, q3_h); - - /* filter8 */ - VP9_FILTER8(p3_h, p2_h, p1_h, p0_h, q0_h, q1_h, q2_h, q3_h, p2_filt8_h, - p1_filt8_h, p0_filt8_h, q0_filt8_h, q1_filt8_h, q2_filt8_h); - - /* convert 16 bit output data into 8 bit */ - DUP4_ARG2(__lsx_vpickev_b, p2_filt8_h, p2_filt8_l, p1_filt8_h, p1_filt8_l, - p0_filt8_h, p0_filt8_l, q0_filt8_h, q0_filt8_l, p2_filt8_l, - p1_filt8_l, p0_filt8_l, q0_filt8_l); - DUP2_ARG2(__lsx_vpickev_b, q1_filt8_h, q1_filt8_l, q2_filt8_h, q2_filt8_l, - q1_filt8_l, q2_filt8_l); - - /* store pixel values */ - p2 = __lsx_vbitsel_v(p2, p2_filt8_l, flat); - p1 = __lsx_vbitsel_v(p1_out, p1_filt8_l, flat); - p0 = __lsx_vbitsel_v(p0_out, p0_filt8_l, flat); - q0 = __lsx_vbitsel_v(q0_out, q0_filt8_l, flat); - q1 = __lsx_vbitsel_v(q1_out, q1_filt8_l, flat); - q2 = __lsx_vbitsel_v(q2, q2_filt8_l, flat); - - DUP2_ARG2(__lsx_vilvl_b, p1, p2, q0, p0, p3, q3); - p2_filt8_l = __lsx_vilvl_h(q3, p3); - p2_filt8_h = __lsx_vilvh_h(q3, p3); - DUP2_ARG2(__lsx_vilvh_b, p1, p2, q0, p0, p3, q3); - p0_filt8_l = __lsx_vilvl_h(q3, p3); - p0_filt8_h = __lsx_vilvh_h(q3, p3); - q1_filt8_l = __lsx_vilvl_b(q2, q1); - q1_filt8_h = __lsx_vilvh_b(q2, q1); - - dst -= 3; - __lsx_vstelm_w(p2_filt8_l, dst, 0, 0); - __lsx_vstelm_h(q1_filt8_l, dst, 4, 0); - dst += stride; - __lsx_vstelm_w(p2_filt8_l, dst, 0, 1); - __lsx_vstelm_h(q1_filt8_l, dst, 4, 1); - dst += stride; - __lsx_vstelm_w(p2_filt8_l, dst, 0, 2); - __lsx_vstelm_h(q1_filt8_l, dst, 4, 2); - dst += stride; - __lsx_vstelm_w(p2_filt8_l, dst, 0, 3); - __lsx_vstelm_h(q1_filt8_l, dst, 4, 3); - dst += stride; - __lsx_vstelm_w(p2_filt8_h, dst, 0, 0); - __lsx_vstelm_h(q1_filt8_l, dst, 4, 4); - dst += stride; - __lsx_vstelm_w(p2_filt8_h, dst, 0, 1); - __lsx_vstelm_h(q1_filt8_l, dst, 4, 5); - dst += stride; - __lsx_vstelm_w(p2_filt8_h, dst, 0, 2); - __lsx_vstelm_h(q1_filt8_l, dst, 4, 6); - dst += stride; - __lsx_vstelm_w(p2_filt8_h, dst, 0, 3); - __lsx_vstelm_h(q1_filt8_l, dst, 4, 7); - dst += stride; - __lsx_vstelm_w(p0_filt8_l, dst, 0, 0); - __lsx_vstelm_h(q1_filt8_h, dst, 4, 0); - dst += stride; - __lsx_vstelm_w(p0_filt8_l, dst, 0, 1); - __lsx_vstelm_h(q1_filt8_h, dst, 4, 1); - dst += stride; - __lsx_vstelm_w(p0_filt8_l, dst, 0, 2); - __lsx_vstelm_h(q1_filt8_h, dst, 4, 2); - dst += stride; - __lsx_vstelm_w(p0_filt8_l, dst, 0, 3); - __lsx_vstelm_h(q1_filt8_h, dst, 4, 3); - dst += stride; - __lsx_vstelm_w(p0_filt8_h, dst, 0, 0); - __lsx_vstelm_h(q1_filt8_h, dst, 4, 4); - dst += stride; - __lsx_vstelm_w(p0_filt8_h, dst, 0, 1); - __lsx_vstelm_h(q1_filt8_h, dst, 4, 5); - dst += stride; - __lsx_vstelm_w(p0_filt8_h, dst, 0, 2); - __lsx_vstelm_h(q1_filt8_h, dst, 4, 6); - dst += stride; - __lsx_vstelm_w(p0_filt8_h, dst, 0, 3); - __lsx_vstelm_h(q1_filt8_h, dst, 4, 7); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/loopfilter_lsx.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/loopfilter_lsx.h deleted file mode 100644 index 1c438365..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/loopfilter_lsx.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_LOONGARCH_LOOPFILTER_LSX_H_ -#define VPX_VPX_DSP_LOONGARCH_LOOPFILTER_LSX_H_ - -#include "vpx_util/loongson_intrinsics.h" - -#define LPF_MASK_HEV(p3_in, p2_in, p1_in, p0_in, q0_in, q1_in, q2_in, q3_in, \ - limit_in, b_limit_in, thresh_in, hev_out, mask_out, \ - flat_out) \ - do { \ - __m128i p3_asub_p2_m, p2_asub_p1_m, p1_asub_p0_m, q1_asub_q0_m; \ - __m128i p1_asub_q1_m, p0_asub_q0_m, q3_asub_q2_m, q2_asub_q1_m; \ - \ - /* absolute subtraction of pixel values */ \ - p3_asub_p2_m = __lsx_vabsd_bu(p3_in, p2_in); \ - p2_asub_p1_m = __lsx_vabsd_bu(p2_in, p1_in); \ - p1_asub_p0_m = __lsx_vabsd_bu(p1_in, p0_in); \ - q1_asub_q0_m = __lsx_vabsd_bu(q1_in, q0_in); \ - q2_asub_q1_m = __lsx_vabsd_bu(q2_in, q1_in); \ - q3_asub_q2_m = __lsx_vabsd_bu(q3_in, q2_in); \ - p0_asub_q0_m = __lsx_vabsd_bu(p0_in, q0_in); \ - p1_asub_q1_m = __lsx_vabsd_bu(p1_in, q1_in); \ - \ - /* calculation of hev */ \ - flat_out = __lsx_vmax_bu(p1_asub_p0_m, q1_asub_q0_m); \ - hev_out = __lsx_vslt_bu(thresh_in, flat_out); \ - \ - /* calculation of mask */ \ - p0_asub_q0_m = __lsx_vsadd_bu(p0_asub_q0_m, p0_asub_q0_m); \ - p1_asub_q1_m = __lsx_vsrli_b(p1_asub_q1_m, 1); \ - p0_asub_q0_m = __lsx_vsadd_bu(p0_asub_q0_m, p1_asub_q1_m); \ - mask_out = __lsx_vslt_bu(b_limit_in, p0_asub_q0_m); \ - mask_out = __lsx_vmax_bu(flat_out, mask_out); \ - p3_asub_p2_m = __lsx_vmax_bu(p3_asub_p2_m, p2_asub_p1_m); \ - mask_out = __lsx_vmax_bu(p3_asub_p2_m, mask_out); \ - q2_asub_q1_m = __lsx_vmax_bu(q2_asub_q1_m, q3_asub_q2_m); \ - mask_out = __lsx_vmax_bu(q2_asub_q1_m, mask_out); \ - \ - mask_out = __lsx_vslt_bu(limit_in, mask_out); \ - mask_out = __lsx_vxori_b(mask_out, 0xff); \ - } while (0) - -#define VP9_FLAT4(p3_in, p2_in, p0_in, q0_in, q2_in, q3_in, flat_out) \ - do { \ - __m128i p2_asub_p0, q2_asub_q0, p3_asub_p0, q3_asub_q0; \ - __m128i flat4_tmp = __lsx_vldi(1); \ - \ - DUP4_ARG2(__lsx_vabsd_bu, p2_in, p0_in, q2_in, q0_in, p3_in, p0_in, q3_in, \ - q0_in, p2_asub_p0, q2_asub_q0, p3_asub_p0, q3_asub_q0); \ - p2_asub_p0 = __lsx_vmax_bu(p2_asub_p0, q2_asub_q0); \ - flat_out = __lsx_vmax_bu(p2_asub_p0, flat_out); \ - p3_asub_p0 = __lsx_vmax_bu(p3_asub_p0, q3_asub_q0); \ - flat_out = __lsx_vmax_bu(p3_asub_p0, flat_out); \ - \ - flat_out = __lsx_vslt_bu(flat4_tmp, flat_out); \ - flat_out = __lsx_vxori_b(flat_out, 0xff); \ - flat_out = flat_out & (mask); \ - } while (0) - -#define VP9_FLAT5(p7_in, p6_in, p5_in, p4_in, p0_in, q0_in, q4_in, q5_in, \ - q6_in, q7_in, flat_in, flat2_out) \ - do { \ - __m128i flat5_tmp = __lsx_vldi(1); \ - __m128i p4_asub_p0, q4_asub_q0, p5_asub_p0, q5_asub_q0; \ - __m128i p6_asub_p0, q6_asub_q0, p7_asub_p0, q7_asub_q0; \ - DUP4_ARG2(__lsx_vabsd_bu, p4_in, p0_in, q4_in, q0_in, p5_in, p0_in, q5_in, \ - q0_in, p4_asub_p0, q4_asub_q0, p5_asub_p0, q5_asub_q0); \ - DUP4_ARG2(__lsx_vabsd_bu, p6_in, p0_in, q6_in, q0_in, p7_in, p0_in, q7_in, \ - q0_in, p6_asub_p0, q6_asub_q0, p7_asub_p0, q7_asub_q0); \ - \ - DUP2_ARG2(__lsx_vmax_bu, p4_asub_p0, q4_asub_q0, p5_asub_p0, q5_asub_q0, \ - p4_asub_p0, flat2_out); \ - flat2_out = __lsx_vmax_bu(p4_asub_p0, flat2_out); \ - p6_asub_p0 = __lsx_vmax_bu(p6_asub_p0, q6_asub_q0); \ - flat2_out = __lsx_vmax_bu(p6_asub_p0, flat2_out); \ - p7_asub_p0 = __lsx_vmax_bu(p7_asub_p0, q7_asub_q0); \ - flat2_out = __lsx_vmax_bu(p7_asub_p0, flat2_out); \ - flat2_out = __lsx_vslt_bu(flat5_tmp, flat2_out); \ - flat2_out = __lsx_vxori_b(flat2_out, 0xff); \ - flat2_out = flat2_out & flat_in; \ - } while (0) - -#define VP9_LPF_FILTER4_4W(p1_in, p0_in, q0_in, q1_in, mask, hev, p1_out, \ - p0_out, q0_out, q1_out) \ - do { \ - __m128i p1_m, p0_m, q0_m, q1_m, filt, q0_sub_p0, t1, t2; \ - const __m128i cnst4b = __lsx_vldi(4); \ - const __m128i cnst3b = __lsx_vldi(3); \ - DUP4_ARG2(__lsx_vxori_b, p1_in, 0x80, p0_in, 0x80, q0_in, 0x80, q1_in, \ - 0x80, p1_m, p0_m, q0_m, q1_m); \ - filt = __lsx_vssub_b(p1_m, q1_m); \ - filt &= hev; \ - \ - q0_sub_p0 = __lsx_vssub_b(q0_m, p0_m); \ - filt = __lsx_vsadd_b(filt, q0_sub_p0); \ - filt = __lsx_vsadd_b(filt, q0_sub_p0); \ - filt = __lsx_vsadd_b(filt, q0_sub_p0); \ - filt &= mask; \ - DUP2_ARG2(__lsx_vsadd_b, filt, cnst4b, filt, cnst3b, t1, t2); \ - DUP2_ARG2(__lsx_vsrai_b, t1, 3, t2, 3, t1, t2); \ - \ - q0_m = __lsx_vssub_b(q0_m, t1); \ - p0_m = __lsx_vsadd_b(p0_m, t2); \ - DUP2_ARG2(__lsx_vxori_b, q0_m, 0x80, p0_m, 0x80, q0_out, p0_out); \ - \ - filt = __lsx_vsrari_b(t1, 1); \ - hev = __lsx_vxori_b(hev, 0xff); \ - filt &= hev; \ - q1_m = __lsx_vssub_b(q1_m, filt); \ - p1_m = __lsx_vsadd_b(p1_m, filt); \ - DUP2_ARG2(__lsx_vxori_b, q1_m, 0x80, p1_m, 0x80, q1_out, p1_out); \ - } while (0) - -#define VP9_FILTER8(p3_in, p2_in, p1_in, p0_in, q0_in, q1_in, q2_in, q3_in, \ - p2_filt8_out, p1_filt8_out, p0_filt8_out, q0_filt8_out, \ - q1_filt8_out, q2_filt8_out) \ - do { \ - __m128i tmp_filt8_0, tmp_filt8_1, tmp_filt8_2; \ - \ - tmp_filt8_2 = __lsx_vadd_h(p2_in, p1_in); \ - tmp_filt8_2 = __lsx_vadd_h(tmp_filt8_2, p0_in); \ - tmp_filt8_0 = __lsx_vslli_h(p3_in, 1); \ - \ - tmp_filt8_0 = __lsx_vadd_h(tmp_filt8_0, tmp_filt8_2); \ - tmp_filt8_0 = __lsx_vadd_h(tmp_filt8_0, q0_in); \ - tmp_filt8_1 = __lsx_vadd_h(tmp_filt8_0, p3_in); \ - tmp_filt8_1 = __lsx_vadd_h(tmp_filt8_1, p2_in); \ - p2_filt8_out = __lsx_vsrari_h(tmp_filt8_1, 3); \ - \ - tmp_filt8_1 = __lsx_vadd_h(tmp_filt8_0, p1_in); \ - tmp_filt8_1 = __lsx_vadd_h(tmp_filt8_1, q1_in); \ - p1_filt8_out = __lsx_vsrari_h(tmp_filt8_1, 3); \ - \ - tmp_filt8_1 = __lsx_vadd_h(q2_in, q1_in); \ - tmp_filt8_1 = __lsx_vadd_h(tmp_filt8_1, q0_in); \ - tmp_filt8_2 = __lsx_vadd_h(tmp_filt8_2, tmp_filt8_1); \ - tmp_filt8_0 = __lsx_vadd_h(tmp_filt8_2, p0_in); \ - tmp_filt8_0 = __lsx_vadd_h(tmp_filt8_0, p3_in); \ - p0_filt8_out = __lsx_vsrari_h(tmp_filt8_0, 3); \ - \ - tmp_filt8_0 = __lsx_vadd_h(q2_in, q3_in); \ - tmp_filt8_0 = __lsx_vadd_h(p0_in, tmp_filt8_0); \ - tmp_filt8_0 = __lsx_vadd_h(tmp_filt8_0, tmp_filt8_1); \ - tmp_filt8_1 = __lsx_vadd_h(q3_in, q3_in); \ - tmp_filt8_1 = __lsx_vadd_h(tmp_filt8_1, tmp_filt8_0); \ - q2_filt8_out = __lsx_vsrari_h(tmp_filt8_1, 3); \ - \ - tmp_filt8_0 = __lsx_vadd_h(tmp_filt8_2, q3_in); \ - tmp_filt8_1 = __lsx_vadd_h(tmp_filt8_0, q0_in); \ - q0_filt8_out = __lsx_vsrari_h(tmp_filt8_1, 3); \ - \ - tmp_filt8_1 = __lsx_vsub_h(tmp_filt8_0, p2_in); \ - tmp_filt8_0 = __lsx_vadd_h(q1_in, q3_in); \ - tmp_filt8_1 = __lsx_vadd_h(tmp_filt8_0, tmp_filt8_1); \ - q1_filt8_out = __lsx_vsrari_h(tmp_filt8_1, 3); \ - } while (0) - -#endif // VPX_VPX_DSP_LOONGARCH_LOOPFILTER_LSX_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/quantize_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/quantize_lsx.c deleted file mode 100644 index 9bb1691e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/quantize_lsx.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_util/loongson_intrinsics.h" -#include "vp9/common/vp9_scan.h" -#include "vp9/encoder/vp9_block.h" - -static INLINE __m128i calculate_qcoeff(__m128i coeff, __m128i coeff_abs, - __m128i round, __m128i quant, - __m128i shift, __m128i cmp_mask) { - __m128i rounded, qcoeff; - - rounded = __lsx_vsadd_h(coeff_abs, round); - qcoeff = __lsx_vmuh_h(rounded, quant); - qcoeff = __lsx_vadd_h(rounded, qcoeff); - qcoeff = __lsx_vmuh_h(qcoeff, shift); - qcoeff = __lsx_vsigncov_h(coeff, qcoeff); - qcoeff = __lsx_vand_v(qcoeff, cmp_mask); - - return qcoeff; -} - -static INLINE void calculate_dqcoeff_and_store(__m128i qcoeff, __m128i dequant, - int16_t *dqcoeff) { - __m128i dqcoeff16 = __lsx_vmul_h(qcoeff, dequant); - __lsx_vst(dqcoeff16, dqcoeff, 0); -} - -static INLINE void calculate_dqcoeff_and_store_32x32(__m128i qcoeff, - __m128i dequant, - int16_t *dqcoeff) { - // Un-sign to bias rounding like C. - __m128i low, high, dqcoeff32_0, dqcoeff32_1, res; - __m128i zero = __lsx_vldi(0); - __m128i coeff = __lsx_vabsd_h(qcoeff, zero); - - const __m128i sign_0 = __lsx_vilvl_h(qcoeff, zero); - const __m128i sign_1 = __lsx_vilvh_h(qcoeff, zero); - - low = __lsx_vmul_h(coeff, dequant); - high = __lsx_vmuh_h(coeff, dequant); - dqcoeff32_0 = __lsx_vilvl_h(high, low); - dqcoeff32_1 = __lsx_vilvh_h(high, low); - - // "Divide" by 2. - dqcoeff32_0 = __lsx_vsrai_w(dqcoeff32_0, 1); - dqcoeff32_1 = __lsx_vsrai_w(dqcoeff32_1, 1); - dqcoeff32_0 = __lsx_vsigncov_w(sign_0, dqcoeff32_0); - dqcoeff32_1 = __lsx_vsigncov_w(sign_1, dqcoeff32_1); - res = __lsx_vpickev_h(dqcoeff32_1, dqcoeff32_0); - __lsx_vst(res, dqcoeff, 0); -} - -static INLINE __m128i scan_for_eob(__m128i coeff0, __m128i coeff1, - const int16_t *scan, int index, - __m128i zero) { - const __m128i zero_coeff0 = __lsx_vseq_h(coeff0, zero); - const __m128i zero_coeff1 = __lsx_vseq_h(coeff1, zero); - __m128i scan0 = __lsx_vld(scan + index, 0); - __m128i scan1 = __lsx_vld(scan + index + 8, 0); - __m128i eob0, eob1; - - eob0 = __lsx_vandn_v(zero_coeff0, scan0); - eob1 = __lsx_vandn_v(zero_coeff1, scan1); - return __lsx_vmax_h(eob0, eob1); -} - -static INLINE int16_t accumulate_eob(__m128i eob) { - __m128i eob_shuffled; - int16_t res_m; - - eob_shuffled = __lsx_vshuf4i_w(eob, 0xe); - eob = __lsx_vmax_h(eob, eob_shuffled); - eob_shuffled = __lsx_vshuf4i_h(eob, 0xe); - eob = __lsx_vmax_h(eob, eob_shuffled); - eob_shuffled = __lsx_vshuf4i_h(eob, 0x1); - eob = __lsx_vmax_h(eob, eob_shuffled); - res_m = __lsx_vpickve2gr_h(eob, 1); - - return res_m; -} - -#if !CONFIG_VP9_HIGHBITDEPTH - -void vpx_quantize_b_lsx(const int16_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - __m128i zero = __lsx_vldi(0); - int index = 16; - const int16_t *iscan = scan_order->iscan; - - __m128i zbin, round, quant, dequant, quant_shift; - __m128i coeff0, coeff1; - __m128i qcoeff0, qcoeff1; - __m128i cmp_mask0, cmp_mask1; - __m128i eob, eob0; - - zbin = __lsx_vld(mb_plane->zbin, 0); - round = __lsx_vld(mb_plane->round, 0); - quant = __lsx_vld(mb_plane->quant, 0); - dequant = __lsx_vld(dequant_ptr, 0); - quant_shift = __lsx_vld(mb_plane->quant_shift, 0); - // Handle one DC and first 15 AC. - DUP2_ARG2(__lsx_vld, coeff_ptr, 0, coeff_ptr, 16, coeff0, coeff1); - qcoeff0 = __lsx_vabsd_h(coeff0, zero); - qcoeff1 = __lsx_vabsd_h(coeff1, zero); - - cmp_mask0 = __lsx_vsle_h(zbin, qcoeff0); - zbin = __lsx_vilvh_d(zbin, zbin); - cmp_mask1 = __lsx_vsle_h(zbin, qcoeff1); - - qcoeff0 = - calculate_qcoeff(coeff0, qcoeff0, round, quant, quant_shift, cmp_mask0); - round = __lsx_vilvh_d(round, round); - quant = __lsx_vilvh_d(quant, quant); - quant_shift = __lsx_vilvh_d(quant_shift, quant_shift); - qcoeff1 = - calculate_qcoeff(coeff1, qcoeff1, round, quant, quant_shift, cmp_mask1); - - __lsx_vst(qcoeff0, qcoeff_ptr, 0); - __lsx_vst(qcoeff1, qcoeff_ptr, 16); - - calculate_dqcoeff_and_store(qcoeff0, dequant, dqcoeff_ptr); - dequant = __lsx_vilvh_d(dequant, dequant); - calculate_dqcoeff_and_store(qcoeff1, dequant, dqcoeff_ptr + 8); - - eob = scan_for_eob(qcoeff0, qcoeff1, iscan, 0, zero); - // AC only loop. - while (index < n_coeffs) { - coeff0 = __lsx_vld(coeff_ptr + index, 0); - coeff1 = __lsx_vld(coeff_ptr + index + 8, 0); - - qcoeff0 = __lsx_vabsd_h(coeff0, zero); - qcoeff1 = __lsx_vabsd_h(coeff1, zero); - - cmp_mask0 = __lsx_vsle_h(zbin, qcoeff0); - cmp_mask1 = __lsx_vsle_h(zbin, qcoeff1); - - qcoeff0 = - calculate_qcoeff(coeff0, qcoeff0, round, quant, quant_shift, cmp_mask0); - qcoeff1 = - calculate_qcoeff(coeff1, qcoeff1, round, quant, quant_shift, cmp_mask1); - - __lsx_vst(qcoeff0, qcoeff_ptr + index, 0); - __lsx_vst(qcoeff1, qcoeff_ptr + index + 8, 0); - - calculate_dqcoeff_and_store(qcoeff0, dequant, dqcoeff_ptr + index); - calculate_dqcoeff_and_store(qcoeff1, dequant, dqcoeff_ptr + index + 8); - - eob0 = scan_for_eob(qcoeff0, qcoeff1, iscan, index, zero); - eob = __lsx_vmax_h(eob, eob0); - - index += 16; - } - - *eob_ptr = accumulate_eob(eob); -} - -void vpx_quantize_b_32x32_lsx(const tran_low_t *coeff_ptr, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - __m128i zero = __lsx_vldi(0); - int index; - const int16_t *iscan = scan_order->iscan; - - __m128i zbin, round, quant, dequant, quant_shift; - __m128i coeff0, coeff1, qcoeff0, qcoeff1, cmp_mask0, cmp_mask1; - __m128i eob = zero, eob0; - - zbin = __lsx_vld(mb_plane->zbin, 0); - zbin = __lsx_vsrari_h(zbin, 1); - round = __lsx_vld(mb_plane->round, 0); - round = __lsx_vsrari_h(round, 1); - - quant = __lsx_vld(mb_plane->quant, 0); - dequant = __lsx_vld(dequant_ptr, 0); - quant_shift = __lsx_vld(mb_plane->quant_shift, 0); - quant_shift = __lsx_vslli_h(quant_shift, 1); - // Handle one DC and first 15 AC. - DUP2_ARG2(__lsx_vld, coeff_ptr, 0, coeff_ptr, 16, coeff0, coeff1); - qcoeff0 = __lsx_vabsd_h(coeff0, zero); - qcoeff1 = __lsx_vabsd_h(coeff1, zero); - - cmp_mask0 = __lsx_vsle_h(zbin, qcoeff0); - // remove DC from zbin - zbin = __lsx_vilvh_d(zbin, zbin); - cmp_mask1 = __lsx_vsle_h(zbin, qcoeff1); - - qcoeff0 = - calculate_qcoeff(coeff0, qcoeff0, round, quant, quant_shift, cmp_mask0); - // remove DC in quant_shift, quant, quant_shift - round = __lsx_vilvh_d(round, round); - quant = __lsx_vilvh_d(quant, quant); - quant_shift = __lsx_vilvh_d(quant_shift, quant_shift); - qcoeff1 = - calculate_qcoeff(coeff1, qcoeff1, round, quant, quant_shift, cmp_mask1); - __lsx_vst(qcoeff0, qcoeff_ptr, 0); - __lsx_vst(qcoeff1, qcoeff_ptr, 16); - - calculate_dqcoeff_and_store_32x32(qcoeff0, dequant, dqcoeff_ptr); - dequant = __lsx_vilvh_d(dequant, dequant); - calculate_dqcoeff_and_store_32x32(qcoeff1, dequant, dqcoeff_ptr + 8); - eob = scan_for_eob(qcoeff0, qcoeff1, iscan, 0, zero); - // AC only loop. - for (index = 16; index < 32 * 32; index += 16) { - coeff0 = __lsx_vld(coeff_ptr + index, 0); - coeff1 = __lsx_vld(coeff_ptr + index + 8, 0); - - qcoeff0 = __lsx_vabsd_h(coeff0, zero); - qcoeff1 = __lsx_vabsd_h(coeff1, zero); - - cmp_mask0 = __lsx_vsle_h(zbin, qcoeff0); - cmp_mask1 = __lsx_vsle_h(zbin, qcoeff1); - - qcoeff0 = - calculate_qcoeff(coeff0, qcoeff0, round, quant, quant_shift, cmp_mask0); - qcoeff1 = - calculate_qcoeff(coeff1, qcoeff1, round, quant, quant_shift, cmp_mask1); - __lsx_vst(qcoeff0, qcoeff_ptr + index, 0); - __lsx_vst(qcoeff1, qcoeff_ptr + index + 8, 0); - - calculate_dqcoeff_and_store_32x32(qcoeff0, dequant, dqcoeff_ptr + index); - calculate_dqcoeff_and_store_32x32(qcoeff1, dequant, - dqcoeff_ptr + 8 + index); - eob0 = scan_for_eob(qcoeff0, qcoeff1, iscan, index, zero); - eob = __lsx_vmax_h(eob, eob0); - } - - *eob_ptr = accumulate_eob(eob); -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/sad_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/sad_lsx.c deleted file mode 100644 index b6fbedb0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/sad_lsx.c +++ /dev/null @@ -1,717 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_util/loongson_intrinsics.h" - -static INLINE __m128i sad_ub2_uh(__m128i in0, __m128i in1, __m128i ref0, - __m128i ref1) { - __m128i diff0_m, diff1_m, sad_m0; - __m128i sad_m = __lsx_vldi(0); - - diff0_m = __lsx_vabsd_bu(in0, ref0); - diff1_m = __lsx_vabsd_bu(in1, ref1); - - sad_m0 = __lsx_vhaddw_hu_bu(diff0_m, diff0_m); - sad_m = __lsx_vadd_h(sad_m, sad_m0); - sad_m0 = __lsx_vhaddw_hu_bu(diff1_m, diff1_m); - sad_m = __lsx_vadd_h(sad_m, sad_m0); - - return sad_m; -} - -static INLINE uint32_t hadd_uw_u32(__m128i in) { - __m128i res0_m; - uint32_t sum_m; - - res0_m = __lsx_vhaddw_du_wu(in, in); - res0_m = __lsx_vhaddw_qu_du(res0_m, res0_m); - sum_m = __lsx_vpickve2gr_w(res0_m, 0); - - return sum_m; -} - -static INLINE uint32_t hadd_uh_u32(__m128i in) { - __m128i res_m; - uint32_t sum_m; - - res_m = __lsx_vhaddw_wu_hu(in, in); - sum_m = hadd_uw_u32(res_m); - - return sum_m; -} - -static INLINE int32_t hadd_sw_s32(__m128i in) { - __m128i res0_m; - int32_t sum_m; - - res0_m = __lsx_vhaddw_d_w(in, in); - res0_m = __lsx_vhaddw_q_d(res0_m, res0_m); - sum_m = __lsx_vpickve2gr_w(res0_m, 0); - - return sum_m; -} - -static uint32_t sad_8width_lsx(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - int32_t height) { - int32_t ht_cnt; - uint32_t res; - __m128i src0, src1, src2, src3, ref0, ref1, ref2, ref3, sad_tmp; - __m128i sad = __lsx_vldi(0); - - for (ht_cnt = (height >> 2); ht_cnt--;) { - DUP2_ARG2(__lsx_vld, src, 0, ref, 0, src0, ref0); - src += src_stride; - ref += ref_stride; - DUP2_ARG2(__lsx_vld, src, 0, ref, 0, src1, ref1); - src += src_stride; - ref += ref_stride; - DUP2_ARG2(__lsx_vld, src, 0, ref, 0, src2, ref2); - src += src_stride; - ref += ref_stride; - DUP2_ARG2(__lsx_vld, src, 0, ref, 0, src3, ref3); - src += src_stride; - ref += ref_stride; - DUP4_ARG2(__lsx_vpickev_d, src1, src0, src3, src2, ref1, ref0, ref3, ref2, - src0, src1, ref0, ref1); - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad = __lsx_vadd_h(sad, sad_tmp); - } - res = hadd_uh_u32(sad); - return res; -} - -static uint32_t sad_16width_lsx(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - int32_t height) { - int32_t ht_cnt = (height >> 2); - uint32_t res; - __m128i src0, src1, ref0, ref1, sad_tmp; - __m128i sad = __lsx_vldi(0); - int32_t src_stride2 = src_stride << 1; - int32_t ref_stride2 = ref_stride << 1; - - for (; ht_cnt--;) { - DUP2_ARG2(__lsx_vld, src, 0, ref, 0, src0, ref0); - DUP2_ARG2(__lsx_vldx, src, src_stride, ref, ref_stride, src1, ref1); - src += src_stride2; - ref += ref_stride2; - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad = __lsx_vadd_h(sad, sad_tmp); - - DUP2_ARG2(__lsx_vld, src, 0, ref, 0, src0, ref0); - DUP2_ARG2(__lsx_vldx, src, src_stride, ref, ref_stride, src1, ref1); - src += src_stride2; - ref += ref_stride2; - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad = __lsx_vadd_h(sad, sad_tmp); - } - - res = hadd_uh_u32(sad); - return res; -} - -static uint32_t sad_32width_lsx(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - int32_t height) { - int32_t ht_cnt = (height >> 2); - uint32_t res; - __m128i src0, src1, ref0, ref1; - __m128i sad_tmp; - __m128i sad = __lsx_vldi(0); - - for (; ht_cnt--;) { - DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src1); - src += src_stride; - DUP2_ARG2(__lsx_vld, ref, 0, ref, 16, ref0, ref1); - ref += ref_stride; - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad = __lsx_vadd_h(sad, sad_tmp); - - DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src1); - src += src_stride; - DUP2_ARG2(__lsx_vld, ref, 0, ref, 16, ref0, ref1); - ref += ref_stride; - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad = __lsx_vadd_h(sad, sad_tmp); - - DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src1); - src += src_stride; - DUP2_ARG2(__lsx_vld, ref, 0, ref, 16, ref0, ref1); - ref += ref_stride; - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad = __lsx_vadd_h(sad, sad_tmp); - - DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src1); - src += src_stride; - DUP2_ARG2(__lsx_vld, ref, 0, ref, 16, ref0, ref1); - ref += ref_stride; - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad = __lsx_vadd_h(sad, sad_tmp); - } - res = hadd_uh_u32(sad); - return res; -} - -static uint32_t sad_64width_lsx(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - int32_t height) { - int32_t ht_cnt = (height >> 1); - uint32_t sad = 0; - __m128i src0, src1, src2, src3; - __m128i ref0, ref1, ref2, ref3; - __m128i sad_tmp; - __m128i sad0 = __lsx_vldi(0); - __m128i sad1 = sad0; - - for (; ht_cnt--;) { - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src0, src1, src2, - src3); - src += src_stride; - DUP4_ARG2(__lsx_vld, ref, 0, ref, 16, ref, 32, ref, 48, ref0, ref1, ref2, - ref3); - ref += ref_stride; - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad0 = __lsx_vadd_h(sad0, sad_tmp); - sad_tmp = sad_ub2_uh(src2, src3, ref2, ref3); - sad1 = __lsx_vadd_h(sad1, sad_tmp); - - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src0, src1, src2, - src3); - src += src_stride; - DUP4_ARG2(__lsx_vld, ref, 0, ref, 16, ref, 32, ref, 48, ref0, ref1, ref2, - ref3); - ref += ref_stride; - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad0 = __lsx_vadd_h(sad0, sad_tmp); - sad_tmp = sad_ub2_uh(src2, src3, ref2, ref3); - sad1 = __lsx_vadd_h(sad1, sad_tmp); - } - - sad = hadd_uh_u32(sad0); - sad += hadd_uh_u32(sad1); - - return sad; -} - -static void sad_8width_x4d_lsx(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *const aref_ptr[], - int32_t ref_stride, int32_t height, - uint32_t *sad_array) { - int32_t ht_cnt = (height >> 2); - const uint8_t *ref0_ptr, *ref1_ptr, *ref2_ptr, *ref3_ptr; - __m128i src0, src1, src2, src3, sad_tmp; - __m128i ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7; - __m128i ref8, ref9, ref10, ref11, ref12, ref13, ref14, ref15; - __m128i sad0 = __lsx_vldi(0); - __m128i sad1 = sad0; - __m128i sad2 = sad0; - __m128i sad3 = sad0; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - int32_t ref_stride2 = ref_stride << 1; - int32_t ref_stride3 = ref_stride2 + ref_stride; - int32_t ref_stride4 = ref_stride2 << 1; - - ref0_ptr = aref_ptr[0]; - ref1_ptr = aref_ptr[1]; - ref2_ptr = aref_ptr[2]; - ref3_ptr = aref_ptr[3]; - - for (; ht_cnt--;) { - src0 = __lsx_vld(src_ptr, 0); - DUP2_ARG2(__lsx_vldx, src_ptr, src_stride, src_ptr, src_stride2, src1, - src2); - src3 = __lsx_vldx(src_ptr, src_stride3); - src_ptr += src_stride4; - ref0 = __lsx_vld(ref0_ptr, 0); - DUP2_ARG2(__lsx_vldx, ref0_ptr, ref_stride, ref0_ptr, ref_stride2, ref1, - ref2); - ref3 = __lsx_vldx(ref0_ptr, ref_stride3); - ref0_ptr += ref_stride4; - ref4 = __lsx_vld(ref1_ptr, 0); - DUP2_ARG2(__lsx_vldx, ref1_ptr, ref_stride, ref1_ptr, ref_stride2, ref5, - ref6); - ref7 = __lsx_vldx(ref1_ptr, ref_stride3); - ref1_ptr += ref_stride4; - ref8 = __lsx_vld(ref2_ptr, 0); - DUP2_ARG2(__lsx_vldx, ref2_ptr, ref_stride, ref2_ptr, ref_stride2, ref9, - ref10); - ref11 = __lsx_vldx(ref2_ptr, ref_stride3); - ref2_ptr += ref_stride4; - ref12 = __lsx_vld(ref3_ptr, 0); - DUP2_ARG2(__lsx_vldx, ref3_ptr, ref_stride, ref3_ptr, ref_stride2, ref13, - ref14); - ref15 = __lsx_vldx(ref3_ptr, ref_stride3); - ref3_ptr += ref_stride4; - - DUP2_ARG2(__lsx_vpickev_d, src1, src0, src3, src2, src0, src1); - DUP2_ARG2(__lsx_vpickev_d, ref1, ref0, ref3, ref2, ref0, ref1); - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad0 = __lsx_vadd_h(sad0, sad_tmp); - - DUP2_ARG2(__lsx_vpickev_d, ref5, ref4, ref7, ref6, ref0, ref1); - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad1 = __lsx_vadd_h(sad1, sad_tmp); - - DUP2_ARG2(__lsx_vpickev_d, ref9, ref8, ref11, ref10, ref0, ref1); - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad2 = __lsx_vadd_h(sad2, sad_tmp); - - DUP2_ARG2(__lsx_vpickev_d, ref13, ref12, ref15, ref14, ref0, ref1); - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad3 = __lsx_vadd_h(sad3, sad_tmp); - } - sad_array[0] = hadd_uh_u32(sad0); - sad_array[1] = hadd_uh_u32(sad1); - sad_array[2] = hadd_uh_u32(sad2); - sad_array[3] = hadd_uh_u32(sad3); -} - -static void sad_16width_x4d_lsx(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *const aref_ptr[], - int32_t ref_stride, int32_t height, - uint32_t *sad_array) { - int32_t ht_cnt = (height >> 1); - const uint8_t *ref0_ptr, *ref1_ptr, *ref2_ptr, *ref3_ptr; - __m128i src, ref0, ref1, ref2, ref3, diff, sad_tmp; - __m128i sad0 = __lsx_vldi(0); - __m128i sad1 = sad0; - __m128i sad2 = sad0; - __m128i sad3 = sad0; - - ref0_ptr = aref_ptr[0]; - ref1_ptr = aref_ptr[1]; - ref2_ptr = aref_ptr[2]; - ref3_ptr = aref_ptr[3]; - - for (; ht_cnt--;) { - src = __lsx_vld(src_ptr, 0); - src_ptr += src_stride; - ref0 = __lsx_vld(ref0_ptr, 0); - ref0_ptr += ref_stride; - ref1 = __lsx_vld(ref1_ptr, 0); - ref1_ptr += ref_stride; - ref2 = __lsx_vld(ref2_ptr, 0); - ref2_ptr += ref_stride; - ref3 = __lsx_vld(ref3_ptr, 0); - ref3_ptr += ref_stride; - - diff = __lsx_vabsd_bu(src, ref0); - sad_tmp = __lsx_vhaddw_hu_bu(diff, diff); - sad0 = __lsx_vadd_h(sad0, sad_tmp); - diff = __lsx_vabsd_bu(src, ref1); - sad_tmp = __lsx_vhaddw_hu_bu(diff, diff); - sad1 = __lsx_vadd_h(sad1, sad_tmp); - diff = __lsx_vabsd_bu(src, ref2); - sad_tmp = __lsx_vhaddw_hu_bu(diff, diff); - sad2 = __lsx_vadd_h(sad2, sad_tmp); - diff = __lsx_vabsd_bu(src, ref3); - sad_tmp = __lsx_vhaddw_hu_bu(diff, diff); - sad3 = __lsx_vadd_h(sad3, sad_tmp); - - src = __lsx_vld(src_ptr, 0); - src_ptr += src_stride; - ref0 = __lsx_vld(ref0_ptr, 0); - ref0_ptr += ref_stride; - ref1 = __lsx_vld(ref1_ptr, 0); - ref1_ptr += ref_stride; - ref2 = __lsx_vld(ref2_ptr, 0); - ref2_ptr += ref_stride; - ref3 = __lsx_vld(ref3_ptr, 0); - ref3_ptr += ref_stride; - - diff = __lsx_vabsd_bu(src, ref0); - sad_tmp = __lsx_vhaddw_hu_bu(diff, diff); - sad0 = __lsx_vadd_h(sad0, sad_tmp); - diff = __lsx_vabsd_bu(src, ref1); - sad_tmp = __lsx_vhaddw_hu_bu(diff, diff); - sad1 = __lsx_vadd_h(sad1, sad_tmp); - diff = __lsx_vabsd_bu(src, ref2); - sad_tmp = __lsx_vhaddw_hu_bu(diff, diff); - sad2 = __lsx_vadd_h(sad2, sad_tmp); - diff = __lsx_vabsd_bu(src, ref3); - sad_tmp = __lsx_vhaddw_hu_bu(diff, diff); - sad3 = __lsx_vadd_h(sad3, sad_tmp); - } - sad_array[0] = hadd_uh_u32(sad0); - sad_array[1] = hadd_uh_u32(sad1); - sad_array[2] = hadd_uh_u32(sad2); - sad_array[3] = hadd_uh_u32(sad3); -} - -static void sad_32width_x4d_lsx(const uint8_t *src, int32_t src_stride, - const uint8_t *const aref_ptr[], - int32_t ref_stride, int32_t height, - uint32_t *sad_array) { - const uint8_t *ref0_ptr, *ref1_ptr, *ref2_ptr, *ref3_ptr; - int32_t ht_cnt = height; - __m128i src0, src1, ref0, ref1, sad_tmp; - __m128i sad0 = __lsx_vldi(0); - __m128i sad1 = sad0; - __m128i sad2 = sad0; - __m128i sad3 = sad0; - - ref0_ptr = aref_ptr[0]; - ref1_ptr = aref_ptr[1]; - ref2_ptr = aref_ptr[2]; - ref3_ptr = aref_ptr[3]; - - for (; ht_cnt--;) { - DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src1); - src += src_stride; - - DUP2_ARG2(__lsx_vld, ref0_ptr, 0, ref0_ptr, 16, ref0, ref1); - ref0_ptr += ref_stride; - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad0 = __lsx_vadd_h(sad0, sad_tmp); - - DUP2_ARG2(__lsx_vld, ref1_ptr, 0, ref1_ptr, 16, ref0, ref1); - ref1_ptr += ref_stride; - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad1 = __lsx_vadd_h(sad1, sad_tmp); - - DUP2_ARG2(__lsx_vld, ref2_ptr, 0, ref2_ptr, 16, ref0, ref1); - ref2_ptr += ref_stride; - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad2 = __lsx_vadd_h(sad2, sad_tmp); - - DUP2_ARG2(__lsx_vld, ref3_ptr, 0, ref3_ptr, 16, ref0, ref1); - ref3_ptr += ref_stride; - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad3 = __lsx_vadd_h(sad3, sad_tmp); - } - sad_array[0] = hadd_uh_u32(sad0); - sad_array[1] = hadd_uh_u32(sad1); - sad_array[2] = hadd_uh_u32(sad2); - sad_array[3] = hadd_uh_u32(sad3); -} - -static void sad_64width_x4d_lsx(const uint8_t *src, int32_t src_stride, - const uint8_t *const aref_ptr[], - int32_t ref_stride, int32_t height, - uint32_t *sad_array) { - const uint8_t *ref0_ptr, *ref1_ptr, *ref2_ptr, *ref3_ptr; - int32_t ht_cnt = height; - __m128i src0, src1, src2, src3; - __m128i ref0, ref1, ref2, ref3; - __m128i sad, sad_tmp; - - __m128i sad0_0 = __lsx_vldi(0); - __m128i sad0_1 = sad0_0; - __m128i sad1_0 = sad0_0; - __m128i sad1_1 = sad0_0; - __m128i sad2_0 = sad0_0; - __m128i sad2_1 = sad0_0; - __m128i sad3_0 = sad0_0; - __m128i sad3_1 = sad0_0; - - ref0_ptr = aref_ptr[0]; - ref1_ptr = aref_ptr[1]; - ref2_ptr = aref_ptr[2]; - ref3_ptr = aref_ptr[3]; - - for (; ht_cnt--;) { - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src0, src1, src2, - src3); - src += src_stride; - - DUP4_ARG2(__lsx_vld, ref0_ptr, 0, ref0_ptr, 16, ref0_ptr, 32, ref0_ptr, 48, - ref0, ref1, ref2, ref3); - ref0_ptr += ref_stride; - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad0_0 = __lsx_vadd_h(sad0_0, sad_tmp); - sad_tmp = sad_ub2_uh(src2, src3, ref2, ref3); - sad0_1 = __lsx_vadd_h(sad0_1, sad_tmp); - - DUP4_ARG2(__lsx_vld, ref1_ptr, 0, ref1_ptr, 16, ref1_ptr, 32, ref1_ptr, 48, - ref0, ref1, ref2, ref3); - ref1_ptr += ref_stride; - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad1_0 = __lsx_vadd_h(sad1_0, sad_tmp); - sad_tmp = sad_ub2_uh(src2, src3, ref2, ref3); - sad1_1 = __lsx_vadd_h(sad1_1, sad_tmp); - - DUP4_ARG2(__lsx_vld, ref2_ptr, 0, ref2_ptr, 16, ref2_ptr, 32, ref2_ptr, 48, - ref0, ref1, ref2, ref3); - ref2_ptr += ref_stride; - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad2_0 = __lsx_vadd_h(sad2_0, sad_tmp); - sad_tmp = sad_ub2_uh(src2, src3, ref2, ref3); - sad2_1 = __lsx_vadd_h(sad2_1, sad_tmp); - - DUP4_ARG2(__lsx_vld, ref3_ptr, 0, ref3_ptr, 16, ref3_ptr, 32, ref3_ptr, 48, - ref0, ref1, ref2, ref3); - ref3_ptr += ref_stride; - sad_tmp = sad_ub2_uh(src0, src1, ref0, ref1); - sad3_0 = __lsx_vadd_h(sad3_0, sad_tmp); - sad_tmp = sad_ub2_uh(src2, src3, ref2, ref3); - sad3_1 = __lsx_vadd_h(sad3_1, sad_tmp); - } - sad = __lsx_vhaddw_wu_hu(sad0_0, sad0_0); - sad_tmp = __lsx_vhaddw_wu_hu(sad0_1, sad0_1); - sad = __lsx_vadd_w(sad, sad_tmp); - sad_array[0] = hadd_uw_u32(sad); - - sad = __lsx_vhaddw_wu_hu(sad1_0, sad1_0); - sad_tmp = __lsx_vhaddw_wu_hu(sad1_1, sad1_1); - sad = __lsx_vadd_w(sad, sad_tmp); - sad_array[1] = hadd_uw_u32(sad); - - sad = __lsx_vhaddw_wu_hu(sad2_0, sad2_0); - sad_tmp = __lsx_vhaddw_wu_hu(sad2_1, sad2_1); - sad = __lsx_vadd_w(sad, sad_tmp); - sad_array[2] = hadd_uw_u32(sad); - - sad = __lsx_vhaddw_wu_hu(sad3_0, sad3_0); - sad_tmp = __lsx_vhaddw_wu_hu(sad3_1, sad3_1); - sad = __lsx_vadd_w(sad, sad_tmp); - sad_array[3] = hadd_uw_u32(sad); -} - -static uint32_t avgsad_32width_lsx(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - int32_t height, const uint8_t *sec_pred) { - int32_t res, ht_cnt = (height >> 2); - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - __m128i ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7; - __m128i pred0, pred1, pred2, pred3, pred4, pred5, pred6, pred7; - __m128i comp0, comp1, sad_tmp; - __m128i sad = __lsx_vldi(0); - uint8_t *src_tmp, *ref_tmp; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - int32_t ref_stride2 = ref_stride << 1; - int32_t ref_stride3 = ref_stride2 + ref_stride; - int32_t ref_stride4 = ref_stride2 << 1; - - for (; ht_cnt--;) { - src_tmp = (uint8_t *)src + 16; - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src2, src4); - src6 = __lsx_vldx(src, src_stride3); - src1 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src3, - src5); - src7 = __lsx_vldx(src_tmp, src_stride3); - src += src_stride4; - - ref_tmp = (uint8_t *)ref + 16; - ref0 = __lsx_vld(ref, 0); - DUP2_ARG2(__lsx_vldx, ref, ref_stride, ref, ref_stride2, ref2, ref4); - ref6 = __lsx_vldx(ref, ref_stride3); - ref1 = __lsx_vld(ref_tmp, 0); - DUP2_ARG2(__lsx_vldx, ref_tmp, ref_stride, ref_tmp, ref_stride2, ref3, - ref5); - ref7 = __lsx_vldx(ref_tmp, ref_stride3); - ref += ref_stride4; - - DUP4_ARG2(__lsx_vld, sec_pred, 0, sec_pred, 32, sec_pred, 64, sec_pred, 96, - pred0, pred2, pred4, pred6); - DUP4_ARG2(__lsx_vld, sec_pred, 16, sec_pred, 48, sec_pred, 80, sec_pred, - 112, pred1, pred3, pred5, pred7); - sec_pred += 128; - - DUP2_ARG2(__lsx_vavgr_bu, pred0, ref0, pred1, ref1, comp0, comp1); - sad_tmp = sad_ub2_uh(src0, src1, comp0, comp1); - sad = __lsx_vadd_h(sad, sad_tmp); - DUP2_ARG2(__lsx_vavgr_bu, pred2, ref2, pred3, ref3, comp0, comp1); - sad_tmp = sad_ub2_uh(src2, src3, comp0, comp1); - sad = __lsx_vadd_h(sad, sad_tmp); - DUP2_ARG2(__lsx_vavgr_bu, pred4, ref4, pred5, ref5, comp0, comp1); - sad_tmp = sad_ub2_uh(src4, src5, comp0, comp1); - sad = __lsx_vadd_h(sad, sad_tmp); - DUP2_ARG2(__lsx_vavgr_bu, pred6, ref6, pred7, ref7, comp0, comp1); - sad_tmp = sad_ub2_uh(src6, src7, comp0, comp1); - sad = __lsx_vadd_h(sad, sad_tmp); - } - res = hadd_uh_u32(sad); - return res; -} - -static uint32_t avgsad_64width_lsx(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - int32_t height, const uint8_t *sec_pred) { - int32_t res, ht_cnt = (height >> 2); - __m128i src0, src1, src2, src3, ref0, ref1, ref2, ref3; - __m128i comp0, comp1, comp2, comp3, pred0, pred1, pred2, pred3; - __m128i sad, sad_tmp; - __m128i sad0 = __lsx_vldi(0); - __m128i sad1 = sad0; - - for (; ht_cnt--;) { - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src0, src1, src2, - src3); - src += src_stride; - DUP4_ARG2(__lsx_vld, ref, 0, ref, 16, ref, 32, ref, 48, ref0, ref1, ref2, - ref3); - ref += ref_stride; - DUP4_ARG2(__lsx_vld, sec_pred, 0, sec_pred, 16, sec_pred, 32, sec_pred, 48, - pred0, pred1, pred2, pred3); - sec_pred += 64; - DUP4_ARG2(__lsx_vavgr_bu, pred0, ref0, pred1, ref1, pred2, ref2, pred3, - ref3, comp0, comp1, comp2, comp3); - sad_tmp = sad_ub2_uh(src0, src1, comp0, comp1); - sad0 = __lsx_vadd_h(sad0, sad_tmp); - sad_tmp = sad_ub2_uh(src2, src3, comp2, comp3); - sad1 = __lsx_vadd_h(sad1, sad_tmp); - - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src0, src1, src2, - src3); - src += src_stride; - DUP4_ARG2(__lsx_vld, ref, 0, ref, 16, ref, 32, ref, 48, ref0, ref1, ref2, - ref3); - ref += ref_stride; - DUP4_ARG2(__lsx_vld, sec_pred, 0, sec_pred, 16, sec_pred, 32, sec_pred, 48, - pred0, pred1, pred2, pred3); - sec_pred += 64; - DUP4_ARG2(__lsx_vavgr_bu, pred0, ref0, pred1, ref1, pred2, ref2, pred3, - ref3, comp0, comp1, comp2, comp3); - sad_tmp = sad_ub2_uh(src0, src1, comp0, comp1); - sad0 = __lsx_vadd_h(sad0, sad_tmp); - sad_tmp = sad_ub2_uh(src2, src3, comp2, comp3); - sad1 = __lsx_vadd_h(sad1, sad_tmp); - - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src0, src1, src2, - src3); - src += src_stride; - DUP4_ARG2(__lsx_vld, ref, 0, ref, 16, ref, 32, ref, 48, ref0, ref1, ref2, - ref3); - ref += ref_stride; - DUP4_ARG2(__lsx_vld, sec_pred, 0, sec_pred, 16, sec_pred, 32, sec_pred, 48, - pred0, pred1, pred2, pred3); - sec_pred += 64; - DUP4_ARG2(__lsx_vavgr_bu, pred0, ref0, pred1, ref1, pred2, ref2, pred3, - ref3, comp0, comp1, comp2, comp3); - sad_tmp = sad_ub2_uh(src0, src1, comp0, comp1); - sad0 = __lsx_vadd_h(sad0, sad_tmp); - sad_tmp = sad_ub2_uh(src2, src3, comp2, comp3); - sad1 = __lsx_vadd_h(sad1, sad_tmp); - - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src0, src1, src2, - src3); - src += src_stride; - DUP4_ARG2(__lsx_vld, ref, 0, ref, 16, ref, 32, ref, 48, ref0, ref1, ref2, - ref3); - ref += ref_stride; - DUP4_ARG2(__lsx_vld, sec_pred, 0, sec_pred, 16, sec_pred, 32, sec_pred, 48, - pred0, pred1, pred2, pred3); - sec_pred += 64; - DUP4_ARG2(__lsx_vavgr_bu, pred0, ref0, pred1, ref1, pred2, ref2, pred3, - ref3, comp0, comp1, comp2, comp3); - sad_tmp = sad_ub2_uh(src0, src1, comp0, comp1); - sad0 = __lsx_vadd_h(sad0, sad_tmp); - sad_tmp = sad_ub2_uh(src2, src3, comp2, comp3); - sad1 = __lsx_vadd_h(sad1, sad_tmp); - } - sad = __lsx_vhaddw_wu_hu(sad0, sad0); - sad_tmp = __lsx_vhaddw_wu_hu(sad1, sad1); - sad = __lsx_vadd_w(sad, sad_tmp); - - res = hadd_sw_s32(sad); - return res; -} - -#define VPX_SAD_8xHT_LSX(height) \ - uint32_t vpx_sad8x##height##_lsx(const uint8_t *src, int32_t src_stride, \ - const uint8_t *ref, int32_t ref_stride) { \ - return sad_8width_lsx(src, src_stride, ref, ref_stride, height); \ - } - -#define VPX_SAD_16xHT_LSX(height) \ - uint32_t vpx_sad16x##height##_lsx(const uint8_t *src, int32_t src_stride, \ - const uint8_t *ref, int32_t ref_stride) { \ - return sad_16width_lsx(src, src_stride, ref, ref_stride, height); \ - } - -#define VPX_SAD_32xHT_LSX(height) \ - uint32_t vpx_sad32x##height##_lsx(const uint8_t *src, int32_t src_stride, \ - const uint8_t *ref, int32_t ref_stride) { \ - return sad_32width_lsx(src, src_stride, ref, ref_stride, height); \ - } - -#define VPX_SAD_64xHT_LSX(height) \ - uint32_t vpx_sad64x##height##_lsx(const uint8_t *src, int32_t src_stride, \ - const uint8_t *ref, int32_t ref_stride) { \ - return sad_64width_lsx(src, src_stride, ref, ref_stride, height); \ - } - -#define VPX_SAD_8xHTx4D_LSX(height) \ - void vpx_sad8x##height##x4d_lsx(const uint8_t *src, int32_t src_stride, \ - const uint8_t *const refs[4], \ - int32_t ref_stride, uint32_t sads[4]) { \ - sad_8width_x4d_lsx(src, src_stride, refs, ref_stride, height, sads); \ - } - -#define VPX_SAD_16xHTx4D_LSX(height) \ - void vpx_sad16x##height##x4d_lsx(const uint8_t *src, int32_t src_stride, \ - const uint8_t *const refs[], \ - int32_t ref_stride, uint32_t *sads) { \ - sad_16width_x4d_lsx(src, src_stride, refs, ref_stride, height, sads); \ - } - -#define VPX_SAD_32xHTx4D_LSX(height) \ - void vpx_sad32x##height##x4d_lsx(const uint8_t *src, int32_t src_stride, \ - const uint8_t *const refs[], \ - int32_t ref_stride, uint32_t *sads) { \ - sad_32width_x4d_lsx(src, src_stride, refs, ref_stride, height, sads); \ - } - -#define VPX_SAD_64xHTx4D_LSX(height) \ - void vpx_sad64x##height##x4d_lsx(const uint8_t *src, int32_t src_stride, \ - const uint8_t *const refs[], \ - int32_t ref_stride, uint32_t *sads) { \ - sad_64width_x4d_lsx(src, src_stride, refs, ref_stride, height, sads); \ - } - -#define VPX_AVGSAD_32xHT_LSX(height) \ - uint32_t vpx_sad32x##height##_avg_lsx( \ - const uint8_t *src, int32_t src_stride, const uint8_t *ref, \ - int32_t ref_stride, const uint8_t *second_pred) { \ - return avgsad_32width_lsx(src, src_stride, ref, ref_stride, height, \ - second_pred); \ - } - -#define VPX_AVGSAD_64xHT_LSX(height) \ - uint32_t vpx_sad64x##height##_avg_lsx( \ - const uint8_t *src, int32_t src_stride, const uint8_t *ref, \ - int32_t ref_stride, const uint8_t *second_pred) { \ - return avgsad_64width_lsx(src, src_stride, ref, ref_stride, height, \ - second_pred); \ - } - -#define SAD64 \ - VPX_SAD_64xHT_LSX(64) VPX_SAD_64xHTx4D_LSX(64) VPX_SAD_64xHTx4D_LSX(32) \ - VPX_AVGSAD_64xHT_LSX(64) - -SAD64 - -#define SAD32 \ - VPX_SAD_32xHT_LSX(32) VPX_SAD_32xHTx4D_LSX(32) VPX_SAD_32xHTx4D_LSX(64) \ - VPX_AVGSAD_32xHT_LSX(32) - -SAD32 - -#define SAD16 VPX_SAD_16xHT_LSX(16) VPX_SAD_16xHTx4D_LSX(16) - -SAD16 - -#define SAD8 VPX_SAD_8xHT_LSX(8) VPX_SAD_8xHTx4D_LSX(8) - -SAD8 - -#undef SAD64 -#undef SAD32 -#undef SAD16 -#undef SAD8 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/sub_pixel_variance_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/sub_pixel_variance_lsx.c deleted file mode 100644 index 70079353..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/sub_pixel_variance_lsx.c +++ /dev/null @@ -1,874 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_ports/mem.h" -#include "vpx_dsp/loongarch/variance_lsx.h" -#include "vpx_dsp/variance.h" - -static const uint8_t bilinear_filters_lsx[8][2] = { - { 128, 0 }, { 112, 16 }, { 96, 32 }, { 80, 48 }, - { 64, 64 }, { 48, 80 }, { 32, 96 }, { 16, 112 }, -}; - -#define VARIANCE_WxH(sse, diff, shift) \ - (sse) - (((uint32_t)(diff) * (diff)) >> (shift)) - -#define VARIANCE_LARGE_WxH(sse, diff, shift) \ - (sse) - (((int64_t)(diff) * (diff)) >> (shift)) - -static uint32_t avg_sse_diff_64x64_lsx(const uint8_t *src_ptr, - int32_t src_stride, - const uint8_t *ref_ptr, - int32_t ref_stride, - const uint8_t *sec_pred, int32_t *diff) { - int32_t res, ht_cnt = 32; - __m128i src0, src1, src2, src3, ref0, ref1, ref2, ref3; - __m128i pred0, pred1, pred2, pred3, vec, vec_tmp; - __m128i avg0, avg1, avg2, avg3; - __m128i var = __lsx_vldi(0); - - avg0 = var; - avg1 = var; - avg2 = var; - avg3 = var; - - for (; ht_cnt--;) { - DUP4_ARG2(__lsx_vld, sec_pred, 0, sec_pred, 16, sec_pred, 32, sec_pred, 48, - pred0, pred1, pred2, pred3); - sec_pred += 64; - DUP4_ARG2(__lsx_vld, src_ptr, 0, src_ptr, 16, src_ptr, 32, src_ptr, 48, - src0, src1, src2, src3); - src_ptr += src_stride; - DUP4_ARG2(__lsx_vld, ref_ptr, 0, ref_ptr, 16, ref_ptr, 32, ref_ptr, 48, - ref0, ref1, ref2, ref3); - ref_ptr += ref_stride; - - DUP4_ARG2(__lsx_vavgr_bu, src0, pred0, src1, pred1, src2, pred2, src3, - pred3, src0, src1, src2, src3); - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - CALC_MSE_AVG_B(src2, ref2, var, avg2); - CALC_MSE_AVG_B(src3, ref3, var, avg3); - - DUP4_ARG2(__lsx_vld, sec_pred, 0, sec_pred, 16, sec_pred, 32, sec_pred, 48, - pred0, pred1, pred2, pred3); - sec_pred += 64; - DUP4_ARG2(__lsx_vld, src_ptr, 0, src_ptr, 16, src_ptr, 32, src_ptr, 48, - src0, src1, src2, src3); - src_ptr += src_stride; - DUP4_ARG2(__lsx_vld, ref_ptr, 0, ref_ptr, 16, ref_ptr, 32, ref_ptr, 48, - ref0, ref1, ref2, ref3); - ref_ptr += ref_stride; - - DUP4_ARG2(__lsx_vavgr_bu, src0, pred0, src1, pred1, src2, pred2, src3, - pred3, src0, src1, src2, src3); - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - CALC_MSE_AVG_B(src2, ref2, var, avg2); - CALC_MSE_AVG_B(src3, ref3, var, avg3); - } - vec = __lsx_vhaddw_w_h(avg0, avg0); - vec_tmp = __lsx_vhaddw_w_h(avg1, avg1); - vec = __lsx_vadd_w(vec, vec_tmp); - vec_tmp = __lsx_vhaddw_w_h(avg2, avg2); - vec = __lsx_vadd_w(vec, vec_tmp); - vec_tmp = __lsx_vhaddw_w_h(avg3, avg3); - vec = __lsx_vadd_w(vec, vec_tmp); - HADD_SW_S32(vec, *diff); - HADD_SW_S32(var, res); - - return res; -} - -static uint32_t sub_pixel_sse_diff_8width_h_lsx( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter, int32_t height, int32_t *diff) { - uint32_t loop_cnt = (height >> 2); - int32_t res; - __m128i src0, src1, src2, src3, ref0, ref1, ref2, ref3; - __m128i vec0, vec1, vec2, vec3, filt0, out, vec; - __m128i mask = { 0x0403030202010100, 0x0807070606050504 }; - __m128i avg = __lsx_vldi(0); - __m128i var = avg; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - int32_t dst_stride4 = dst_stride2 << 1; - - filt0 = __lsx_vldrepl_h(filter, 0); - for (; loop_cnt--;) { - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - src += src_stride4; - ref0 = __lsx_vld(dst, 0); - DUP2_ARG2(__lsx_vldx, dst, dst_stride, dst, dst_stride2, ref1, ref2); - ref3 = __lsx_vldx(dst, dst_stride3); - dst += dst_stride4; - - DUP2_ARG2(__lsx_vpickev_d, ref1, ref0, ref3, ref2, ref0, ref1); - DUP2_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, vec0, vec1); - DUP2_ARG3(__lsx_vshuf_b, src2, src2, mask, src3, src3, mask, vec2, vec3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, - filt0, vec0, vec1, vec2, vec3); - DUP4_ARG3(__lsx_vssrarni_bu_h, vec0, vec0, FILTER_BITS, vec1, vec1, - FILTER_BITS, vec2, vec2, FILTER_BITS, vec3, vec3, FILTER_BITS, - src0, src1, src2, src3); - out = __lsx_vpackev_d(src1, src0); - CALC_MSE_AVG_B(out, ref0, var, avg); - out = __lsx_vpackev_d(src3, src2); - CALC_MSE_AVG_B(out, ref1, var, avg); - } - vec = __lsx_vhaddw_w_h(avg, avg); - HADD_SW_S32(vec, *diff); - HADD_SW_S32(var, res); - return res; -} - -static uint32_t sub_pixel_sse_diff_16width_h_lsx( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter, int32_t height, int32_t *diff) { - uint32_t loop_cnt = (height >> 2); - int32_t res; - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - __m128i dst0, dst1, dst2, dst3, filt0; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - __m128i out0, out1, out2, out3, out4, out5, out6, out7; - __m128i vec, var = __lsx_vldi(0); - __m128i avg = var; - __m128i mask = { 0x0403030202010100, 0x0807070606050504 }; - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - int32_t dst_stride4 = dst_stride2 << 1; - - filt0 = __lsx_vldrepl_h(filter, 0); - - for (; loop_cnt--;) { - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src0, src1); - src += src_stride; - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src2, src3); - src += src_stride; - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src4, src5); - src += src_stride; - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src6, src7); - src += src_stride; - - dst0 = __lsx_vld(dst, 0); - DUP2_ARG2(__lsx_vldx, dst, dst_stride, dst, dst_stride2, dst1, dst2); - dst3 = __lsx_vldx(dst, dst_stride3); - dst += dst_stride4; - - DUP2_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, vec0, vec1); - DUP2_ARG3(__lsx_vshuf_b, src2, src2, mask, src3, src3, mask, vec2, vec3); - DUP2_ARG3(__lsx_vshuf_b, src4, src4, mask, src5, src5, mask, vec4, vec5); - DUP2_ARG3(__lsx_vshuf_b, src6, src6, mask, src7, src7, mask, vec6, vec7); - - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, - filt0, out0, out1, out2, out3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, vec6, filt0, vec7, - filt0, out4, out5, out6, out7); - DUP4_ARG3(__lsx_vssrarni_bu_h, out1, out0, FILTER_BITS, out3, out2, - FILTER_BITS, out5, out4, FILTER_BITS, out7, out6, FILTER_BITS, - src0, src1, src2, src3); - CALC_MSE_AVG_B(src0, dst0, var, avg); - CALC_MSE_AVG_B(src1, dst1, var, avg); - CALC_MSE_AVG_B(src2, dst2, var, avg); - CALC_MSE_AVG_B(src3, dst3, var, avg); - } - vec = __lsx_vhaddw_w_h(avg, avg); - HADD_SW_S32(vec, *diff); - HADD_SW_S32(var, res); - return res; -} - -static uint32_t sub_pixel_sse_diff_32width_h_lsx( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter, int32_t height, int32_t *diff) { - uint32_t sse = 0; - int32_t diff0[2]; - - sse += sub_pixel_sse_diff_16width_h_lsx(src, src_stride, dst, dst_stride, - filter, height, &diff0[0]); - src += 16; - dst += 16; - - sse += sub_pixel_sse_diff_16width_h_lsx(src, src_stride, dst, dst_stride, - filter, height, &diff0[1]); - - *diff = diff0[0] + diff0[1]; - - return sse; -} - -static uint32_t sub_pixel_sse_diff_8width_v_lsx( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter, int32_t height, int32_t *diff) { - uint32_t loop_cnt = (height >> 2); - int32_t res; - __m128i ref0, ref1, ref2, ref3, src0, src1, src2, src3, src4; - __m128i vec, vec0, vec1, vec2, vec3, tmp0, tmp1, tmp2, tmp3, filt0; - __m128i avg = __lsx_vldi(0); - __m128i var = avg; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - int32_t dst_stride4 = dst_stride2 << 1; - - filt0 = __lsx_vldrepl_h(filter, 0); - src0 = __lsx_vld(src, 0); - src += src_stride; - - for (; loop_cnt--;) { - src1 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src2, src3); - src4 = __lsx_vldx(src, src_stride3); - src += src_stride4; - ref0 = __lsx_vld(dst, 0); - DUP2_ARG2(__lsx_vldx, dst, dst_stride, dst, dst_stride2, ref1, ref2); - ref3 = __lsx_vldx(dst, dst_stride3); - dst += dst_stride4; - - DUP2_ARG2(__lsx_vpickev_d, ref1, ref0, ref3, ref2, ref0, ref1); - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, src3, src2, src4, src3, - vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, - filt0, tmp0, tmp1, tmp2, tmp3); - DUP2_ARG3(__lsx_vssrarni_bu_h, tmp1, tmp0, FILTER_BITS, tmp3, tmp2, - FILTER_BITS, src0, src1); - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - - src0 = src4; - } - vec = __lsx_vhaddw_w_h(avg, avg); - HADD_SW_S32(vec, *diff); - HADD_SW_S32(var, res); - return res; -} - -static uint32_t sub_pixel_sse_diff_16width_v_lsx( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter, int32_t height, int32_t *diff) { - uint32_t loop_cnt = (height >> 2); - int32_t res; - __m128i ref0, ref1, ref2, ref3, src0, src1, src2, src3, src4; - __m128i out0, out1, out2, out3, tmp0, tmp1, filt0, vec; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - __m128i var = __lsx_vldi(0); - __m128i avg = var; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - int32_t dst_stride4 = dst_stride2 << 1; - - filt0 = __lsx_vldrepl_h(filter, 0); - - src0 = __lsx_vld(src, 0); - src += src_stride; - - for (; loop_cnt--;) { - src1 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src2, src3); - src4 = __lsx_vldx(src, src_stride3); - src += src_stride4; - ref0 = __lsx_vld(dst, 0); - DUP2_ARG2(__lsx_vldx, dst, dst_stride, dst, dst_stride2, ref1, ref2); - ref3 = __lsx_vldx(dst, dst_stride3); - dst += dst_stride4; - - DUP2_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, vec0, vec2); - DUP2_ARG2(__lsx_vilvh_b, src1, src0, src2, src1, vec1, vec3); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, tmp0, tmp1); - out0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - - DUP2_ARG2(__lsx_vilvl_b, src3, src2, src4, src3, vec4, vec6); - DUP2_ARG2(__lsx_vilvh_b, src3, src2, src4, src3, vec5, vec7); - DUP2_ARG2(__lsx_vdp2_h_bu, vec2, filt0, vec3, filt0, tmp0, tmp1); - out1 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - - DUP2_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, tmp0, tmp1); - out2 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - DUP2_ARG2(__lsx_vdp2_h_bu, vec6, filt0, vec7, filt0, tmp0, tmp1); - out3 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - - src0 = src4; - - CALC_MSE_AVG_B(out0, ref0, var, avg); - CALC_MSE_AVG_B(out1, ref1, var, avg); - CALC_MSE_AVG_B(out2, ref2, var, avg); - CALC_MSE_AVG_B(out3, ref3, var, avg); - } - vec = __lsx_vhaddw_w_h(avg, avg); - HADD_SW_S32(vec, *diff); - HADD_SW_S32(var, res); - return res; -} - -static uint32_t sub_pixel_sse_diff_32width_v_lsx( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter, int32_t height, int32_t *diff) { - uint32_t sse = 0; - int32_t diff0[2]; - - sse += sub_pixel_sse_diff_16width_v_lsx(src, src_stride, dst, dst_stride, - filter, height, &diff0[0]); - src += 16; - dst += 16; - - sse += sub_pixel_sse_diff_16width_v_lsx(src, src_stride, dst, dst_stride, - filter, height, &diff0[1]); - - *diff = diff0[0] + diff0[1]; - - return sse; -} - -static uint32_t sub_pixel_sse_diff_8width_hv_lsx( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter_horiz, const uint8_t *filter_vert, - int32_t height, int32_t *diff) { - uint32_t loop_cnt = (height >> 2); - int32_t res; - __m128i ref0, ref1, ref2, ref3, src0, src1, src2, src3, src4, out0, out1; - __m128i hz_out0, hz_out1, tmp0, tmp1, tmp2, tmp3, vec, vec0, filt_hz, filt_vt; - __m128i mask = { 0x0403030202010100, 0x0807070606050504 }; - __m128i avg = __lsx_vldi(0); - __m128i var = avg; - - filt_hz = __lsx_vldrepl_h(filter_horiz, 0); - filt_vt = __lsx_vldrepl_h(filter_vert, 0); - - src0 = __lsx_vld(src, 0); - src += src_stride; - HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS, hz_out0); - - for (; loop_cnt--;) { - DUP2_ARG2(__lsx_vld, src, 0, dst, 0, src1, ref0); - src += src_stride; - dst += dst_stride; - DUP2_ARG2(__lsx_vld, src, 0, dst, 0, src2, ref1); - src += src_stride; - dst += dst_stride; - DUP2_ARG2(__lsx_vld, src, 0, dst, 0, src3, ref2); - src += src_stride; - dst += dst_stride; - DUP2_ARG2(__lsx_vld, src, 0, dst, 0, src4, ref3); - src += src_stride; - dst += dst_stride; - - DUP2_ARG2(__lsx_vpickev_d, ref1, ref0, ref3, ref2, ref0, ref1); - HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS, hz_out1); - vec0 = __lsx_vpackev_b(hz_out1, hz_out0); - tmp0 = __lsx_vdp2_h_bu(vec0, filt_vt); - HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, FILTER_BITS, hz_out0); - vec0 = __lsx_vpackev_b(hz_out0, hz_out1); - tmp1 = __lsx_vdp2_h_bu(vec0, filt_vt); - - HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, FILTER_BITS, hz_out1); - vec0 = __lsx_vpackev_b(hz_out1, hz_out0); - tmp2 = __lsx_vdp2_h_bu(vec0, filt_vt); - HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS, hz_out0); - vec0 = __lsx_vpackev_b(hz_out0, hz_out1); - tmp3 = __lsx_vdp2_h_bu(vec0, filt_vt); - DUP2_ARG3(__lsx_vssrarni_bu_h, tmp1, tmp0, FILTER_BITS, tmp3, tmp2, - FILTER_BITS, out0, out1); - CALC_MSE_AVG_B(out0, ref0, var, avg); - CALC_MSE_AVG_B(out1, ref1, var, avg); - } - vec = __lsx_vhaddw_w_h(avg, avg); - HADD_SW_S32(vec, *diff); - HADD_SW_S32(var, res); - return res; -} - -static uint32_t sub_pixel_sse_diff_16width_hv_lsx( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter_horiz, const uint8_t *filter_vert, - int32_t height, int32_t *diff) { - uint32_t loop_cnt = (height >> 2); - int32_t res; - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - __m128i ref0, ref1, ref2, ref3, filt_hz, filt_vt, vec0, vec1; - __m128i hz_out0, hz_out1, hz_out2, hz_out3, tmp0, tmp1, vec; - __m128i var = __lsx_vldi(0); - __m128i avg = var; - __m128i mask = { 0x0403030202010100, 0x0807070606050504 }; - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - int32_t dst_stride4 = dst_stride2 << 1; - - filt_hz = __lsx_vldrepl_h(filter_horiz, 0); - filt_vt = __lsx_vldrepl_h(filter_vert, 0); - - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src0, src1); - src += src_stride; - - HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS, hz_out0); - HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS, hz_out2); - - for (; loop_cnt--;) { - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src0, src1); - src += src_stride; - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src2, src3); - src += src_stride; - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src4, src5); - src += src_stride; - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src6, src7); - src += src_stride; - - ref0 = __lsx_vld(dst, 0); - DUP2_ARG2(__lsx_vldx, dst, dst_stride, dst, dst_stride2, ref1, ref2); - ref3 = __lsx_vldx(dst, dst_stride3); - dst += dst_stride4; - - HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS, hz_out1); - HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS, hz_out3); - DUP2_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp0, tmp1); - src0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - - HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, FILTER_BITS, hz_out0); - HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, FILTER_BITS, hz_out2); - DUP2_ARG2(__lsx_vpackev_b, hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp0, tmp1); - src1 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - - HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS, hz_out1); - HORIZ_2TAP_FILT_UH(src5, src5, mask, filt_hz, FILTER_BITS, hz_out3); - DUP2_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp0, tmp1); - src2 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - - HORIZ_2TAP_FILT_UH(src6, src6, mask, filt_hz, FILTER_BITS, hz_out0); - HORIZ_2TAP_FILT_UH(src7, src7, mask, filt_hz, FILTER_BITS, hz_out2); - DUP2_ARG2(__lsx_vpackev_b, hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp0, tmp1); - src3 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - CALC_MSE_AVG_B(src2, ref2, var, avg); - CALC_MSE_AVG_B(src3, ref3, var, avg); - } - vec = __lsx_vhaddw_w_h(avg, avg); - HADD_SW_S32(vec, *diff); - HADD_SW_S32(var, res); - - return res; -} - -static uint32_t sub_pixel_sse_diff_32width_hv_lsx( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter_horiz, const uint8_t *filter_vert, - int32_t height, int32_t *diff) { - uint32_t sse = 0; - int32_t diff0[2]; - - sse += sub_pixel_sse_diff_16width_hv_lsx(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height, - &diff0[0]); - src += 16; - dst += 16; - - sse += sub_pixel_sse_diff_16width_hv_lsx(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height, - &diff0[1]); - - *diff = diff0[0] + diff0[1]; - - return sse; -} - -static uint32_t subpel_avg_ssediff_16w_h_lsx( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter, - int32_t height, int32_t *diff, int32_t width) { - uint32_t loop_cnt = (height >> 2); - int32_t res; - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - __m128i dst0, dst1, dst2, dst3, tmp0, tmp1, tmp2, tmp3; - __m128i pred0, pred1, pred2, pred3, filt0, vec; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - __m128i out0, out1, out2, out3, out4, out5, out6, out7; - __m128i mask = { 0x403030202010100, 0x807070606050504 }; - __m128i avg = __lsx_vldi(0); - __m128i var = avg; - - filt0 = __lsx_vldrepl_h(filter, 0); - - for (; loop_cnt--;) { - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src0, src1); - src += src_stride; - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src2, src3); - src += src_stride; - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src4, src5); - src += src_stride; - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src6, src7); - src += src_stride; - - dst0 = __lsx_vld(dst, 0); - dst += dst_stride; - dst1 = __lsx_vld(dst, 0); - dst += dst_stride; - dst2 = __lsx_vld(dst, 0); - dst += dst_stride; - dst3 = __lsx_vld(dst, 0); - dst += dst_stride; - - pred0 = __lsx_vld(sec_pred, 0); - sec_pred += width; - pred1 = __lsx_vld(sec_pred, 0); - sec_pred += width; - pred2 = __lsx_vld(sec_pred, 0); - sec_pred += width; - pred3 = __lsx_vld(sec_pred, 0); - sec_pred += width; - - DUP2_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, vec0, vec1); - DUP2_ARG3(__lsx_vshuf_b, src2, src2, mask, src3, src3, mask, vec2, vec3); - DUP2_ARG3(__lsx_vshuf_b, src4, src4, mask, src5, src5, mask, vec4, vec5); - DUP2_ARG3(__lsx_vshuf_b, src6, src6, mask, src7, src7, mask, vec6, vec7); - - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, - filt0, out0, out1, out2, out3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, vec6, filt0, vec7, - filt0, out4, out5, out6, out7); - DUP4_ARG3(__lsx_vssrarni_bu_h, out1, out0, FILTER_BITS, out3, out2, - FILTER_BITS, out5, out4, FILTER_BITS, out7, out6, FILTER_BITS, - tmp0, tmp1, tmp2, tmp3); - DUP4_ARG2(__lsx_vavgr_bu, tmp0, pred0, tmp1, pred1, tmp2, pred2, tmp3, - pred3, tmp0, tmp1, tmp2, tmp3); - - CALC_MSE_AVG_B(tmp0, dst0, var, avg); - CALC_MSE_AVG_B(tmp1, dst1, var, avg); - CALC_MSE_AVG_B(tmp2, dst2, var, avg); - CALC_MSE_AVG_B(tmp3, dst3, var, avg); - } - vec = __lsx_vhaddw_w_h(avg, avg); - HADD_SW_S32(vec, *diff); - HADD_SW_S32(var, res); - - return res; -} - -static uint32_t subpel_avg_ssediff_16w_v_lsx( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter, - int32_t height, int32_t *diff, int32_t width) { - uint32_t loop_cnt = (height >> 2); - int32_t res; - __m128i ref0, ref1, ref2, ref3, pred0, pred1, pred2, pred3; - __m128i src0, src1, src2, src3, src4, out0, out1, out2, out3; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - __m128i tmp0, tmp1, vec, filt0; - __m128i avg = __lsx_vldi(0); - __m128i var = avg; - - filt0 = __lsx_vldrepl_h(filter, 0); - - src0 = __lsx_vld(src, 0); - src += src_stride; - - for (; loop_cnt--;) { - src1 = __lsx_vld(src, 0); - src += src_stride; - src2 = __lsx_vld(src, 0); - src += src_stride; - src3 = __lsx_vld(src, 0); - src += src_stride; - src4 = __lsx_vld(src, 0); - src += src_stride; - - pred0 = __lsx_vld(sec_pred, 0); - sec_pred += width; - pred1 = __lsx_vld(sec_pred, 0); - sec_pred += width; - pred2 = __lsx_vld(sec_pred, 0); - sec_pred += width; - pred3 = __lsx_vld(sec_pred, 0); - sec_pred += width; - - DUP2_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, vec0, vec2); - DUP2_ARG2(__lsx_vilvh_b, src1, src0, src2, src1, vec1, vec3); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, tmp0, tmp1); - out0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - - DUP2_ARG2(__lsx_vilvl_b, src3, src2, src4, src3, vec4, vec6); - DUP2_ARG2(__lsx_vilvh_b, src3, src2, src4, src3, vec5, vec7); - DUP2_ARG2(__lsx_vdp2_h_bu, vec2, filt0, vec3, filt0, tmp0, tmp1); - out1 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - - DUP2_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, tmp0, tmp1); - out2 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - - DUP2_ARG2(__lsx_vdp2_h_bu, vec6, filt0, vec7, filt0, tmp0, tmp1); - out3 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - - src0 = src4; - ref0 = __lsx_vld(dst, 0); - dst += dst_stride; - ref1 = __lsx_vld(dst, 0); - dst += dst_stride; - ref2 = __lsx_vld(dst, 0); - dst += dst_stride; - ref3 = __lsx_vld(dst, 0); - dst += dst_stride; - - DUP4_ARG2(__lsx_vavgr_bu, out0, pred0, out1, pred1, out2, pred2, out3, - pred3, out0, out1, out2, out3); - - CALC_MSE_AVG_B(out0, ref0, var, avg); - CALC_MSE_AVG_B(out1, ref1, var, avg); - CALC_MSE_AVG_B(out2, ref2, var, avg); - CALC_MSE_AVG_B(out3, ref3, var, avg); - } - vec = __lsx_vhaddw_w_h(avg, avg); - HADD_SW_S32(vec, *diff); - HADD_SW_S32(var, res); - return res; -} - -static uint32_t subpel_avg_ssediff_16w_hv_lsx( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter_horiz, - const uint8_t *filter_vert, int32_t height, int32_t *diff, int32_t width) { - uint32_t loop_cnt = (height >> 2); - int32_t res; - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - __m128i ref0, ref1, ref2, ref3, pred0, pred1, pred2, pred3; - __m128i hz_out0, hz_out1, hz_out2, hz_out3, tmp0, tmp1; - __m128i out0, out1, out2, out3, filt_hz, filt_vt, vec, vec0, vec1; - __m128i mask = { 0x403030202010100, 0x807070606050504 }; - __m128i avg = __lsx_vldi(0); - __m128i var = avg; - - filt_hz = __lsx_vldrepl_h(filter_horiz, 0); - filt_vt = __lsx_vldrepl_h(filter_vert, 0); - - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src0, src1); - src += src_stride; - - HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS, hz_out0); - HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS, hz_out2); - - for (; loop_cnt--;) { - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src0, src1); - src += src_stride; - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src2, src3); - src += src_stride; - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src4, src5); - src += src_stride; - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src6, src7); - src += src_stride; - - pred0 = __lsx_vld(sec_pred, 0); - sec_pred += width; - pred1 = __lsx_vld(sec_pred, 0); - sec_pred += width; - pred2 = __lsx_vld(sec_pred, 0); - sec_pred += width; - pred3 = __lsx_vld(sec_pred, 0); - sec_pred += width; - - HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS, hz_out1); - HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS, hz_out3); - DUP2_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp0, tmp1); - out0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - - HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, FILTER_BITS, hz_out0); - HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, FILTER_BITS, hz_out2); - DUP2_ARG2(__lsx_vpackev_b, hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp0, tmp1); - out1 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - - HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS, hz_out1); - HORIZ_2TAP_FILT_UH(src5, src5, mask, filt_hz, FILTER_BITS, hz_out3); - DUP2_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp0, tmp1); - out2 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - - HORIZ_2TAP_FILT_UH(src6, src6, mask, filt_hz, FILTER_BITS, hz_out0); - HORIZ_2TAP_FILT_UH(src7, src7, mask, filt_hz, FILTER_BITS, hz_out2); - DUP2_ARG2(__lsx_vpackev_b, hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp0, tmp1); - out3 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - - ref0 = __lsx_vld(dst, 0); - dst += dst_stride; - ref1 = __lsx_vld(dst, 0); - dst += dst_stride; - ref2 = __lsx_vld(dst, 0); - dst += dst_stride; - ref3 = __lsx_vld(dst, 0); - dst += dst_stride; - - DUP4_ARG2(__lsx_vavgr_bu, out0, pred0, out1, pred1, out2, pred2, out3, - pred3, out0, out1, out2, out3); - - CALC_MSE_AVG_B(out0, ref0, var, avg); - CALC_MSE_AVG_B(out1, ref1, var, avg); - CALC_MSE_AVG_B(out2, ref2, var, avg); - CALC_MSE_AVG_B(out3, ref3, var, avg); - } - vec = __lsx_vhaddw_w_h(avg, avg); - HADD_SW_S32(vec, *diff); - HADD_SW_S32(var, res); - return res; -} - -static uint32_t sub_pixel_avg_sse_diff_64width_h_lsx( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter, - int32_t height, int32_t *diff) { - uint32_t loop_cnt, sse = 0; - int32_t diff0[4]; - - for (loop_cnt = 0; loop_cnt < 4; ++loop_cnt) { - sse += - subpel_avg_ssediff_16w_h_lsx(src, src_stride, dst, dst_stride, sec_pred, - filter, height, &diff0[loop_cnt], 64); - src += 16; - dst += 16; - sec_pred += 16; - } - - *diff = diff0[0] + diff0[1] + diff0[2] + diff0[3]; - - return sse; -} - -static uint32_t sub_pixel_avg_sse_diff_64width_v_lsx( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter, - int32_t height, int32_t *diff) { - uint32_t loop_cnt, sse = 0; - int32_t diff0[4]; - - for (loop_cnt = 0; loop_cnt < 4; ++loop_cnt) { - sse += - subpel_avg_ssediff_16w_v_lsx(src, src_stride, dst, dst_stride, sec_pred, - filter, height, &diff0[loop_cnt], 64); - src += 16; - dst += 16; - sec_pred += 16; - } - - *diff = diff0[0] + diff0[1] + diff0[2] + diff0[3]; - - return sse; -} - -static uint32_t sub_pixel_avg_sse_diff_64width_hv_lsx( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter_horiz, - const uint8_t *filter_vert, int32_t height, int32_t *diff) { - uint32_t loop_cnt, sse = 0; - int32_t diff0[4]; - - for (loop_cnt = 0; loop_cnt < 4; ++loop_cnt) { - sse += subpel_avg_ssediff_16w_hv_lsx(src, src_stride, dst, dst_stride, - sec_pred, filter_horiz, filter_vert, - height, &diff0[loop_cnt], 64); - src += 16; - dst += 16; - sec_pred += 16; - } - - *diff = diff0[0] + diff0[1] + diff0[2] + diff0[3]; - - return sse; -} - -#define VARIANCE_8Wx8H(sse, diff) VARIANCE_WxH(sse, diff, 6) -#define VARIANCE_16Wx16H(sse, diff) VARIANCE_WxH(sse, diff, 8) -#define VARIANCE_32Wx32H(sse, diff) VARIANCE_LARGE_WxH(sse, diff, 10) -#define VARIANCE_64Wx64H(sse, diff) VARIANCE_LARGE_WxH(sse, diff, 12) - -#define VPX_SUB_PIXEL_VARIANCE_WDXHT_LSX(wd, ht) \ - uint32_t vpx_sub_pixel_variance##wd##x##ht##_lsx( \ - const uint8_t *src, int32_t src_stride, int32_t x_offset, \ - int32_t y_offset, const uint8_t *ref, int32_t ref_stride, \ - uint32_t *sse) { \ - int32_t diff; \ - uint32_t var; \ - const uint8_t *h_filter = bilinear_filters_lsx[x_offset]; \ - const uint8_t *v_filter = bilinear_filters_lsx[y_offset]; \ - \ - if (y_offset) { \ - if (x_offset) { \ - *sse = sub_pixel_sse_diff_##wd##width_hv_lsx( \ - src, src_stride, ref, ref_stride, h_filter, v_filter, ht, &diff); \ - } else { \ - *sse = sub_pixel_sse_diff_##wd##width_v_lsx( \ - src, src_stride, ref, ref_stride, v_filter, ht, &diff); \ - } \ - \ - var = VARIANCE_##wd##Wx##ht##H(*sse, diff); \ - } else { \ - if (x_offset) { \ - *sse = sub_pixel_sse_diff_##wd##width_h_lsx( \ - src, src_stride, ref, ref_stride, h_filter, ht, &diff); \ - \ - var = VARIANCE_##wd##Wx##ht##H(*sse, diff); \ - } else { \ - var = vpx_variance##wd##x##ht##_lsx(src, src_stride, ref, ref_stride, \ - sse); \ - } \ - } \ - \ - return var; \ - } - -VPX_SUB_PIXEL_VARIANCE_WDXHT_LSX(8, 8) -VPX_SUB_PIXEL_VARIANCE_WDXHT_LSX(16, 16) -VPX_SUB_PIXEL_VARIANCE_WDXHT_LSX(32, 32) - -#define VPX_SUB_PIXEL_AVG_VARIANCE64XHEIGHT_LSX(ht) \ - uint32_t vpx_sub_pixel_avg_variance64x##ht##_lsx( \ - const uint8_t *src_ptr, int32_t src_stride, int32_t x_offset, \ - int32_t y_offset, const uint8_t *ref_ptr, int32_t ref_stride, \ - uint32_t *sse, const uint8_t *sec_pred) { \ - int32_t diff; \ - const uint8_t *h_filter = bilinear_filters_lsx[x_offset]; \ - const uint8_t *v_filter = bilinear_filters_lsx[y_offset]; \ - \ - if (y_offset) { \ - if (x_offset) { \ - *sse = sub_pixel_avg_sse_diff_64width_hv_lsx( \ - src_ptr, src_stride, ref_ptr, ref_stride, sec_pred, h_filter, \ - v_filter, ht, &diff); \ - } else { \ - *sse = sub_pixel_avg_sse_diff_64width_v_lsx( \ - src_ptr, src_stride, ref_ptr, ref_stride, sec_pred, v_filter, ht, \ - &diff); \ - } \ - } else { \ - if (x_offset) { \ - *sse = sub_pixel_avg_sse_diff_64width_h_lsx( \ - src_ptr, src_stride, ref_ptr, ref_stride, sec_pred, h_filter, ht, \ - &diff); \ - } else { \ - *sse = avg_sse_diff_64x##ht##_lsx(src_ptr, src_stride, ref_ptr, \ - ref_stride, sec_pred, &diff); \ - } \ - } \ - \ - return VARIANCE_64Wx##ht##H(*sse, diff); \ - } - -VPX_SUB_PIXEL_AVG_VARIANCE64XHEIGHT_LSX(64) diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/subtract_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/subtract_lsx.c deleted file mode 100644 index 943a5c5a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/subtract_lsx.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_util/loongson_intrinsics.h" - -static void sub_blk_4x4_lsx(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *pred_ptr, int32_t pred_stride, - int16_t *diff_ptr, int32_t diff_stride) { - __m128i src0, src1, src2, src3; - __m128i pred0, pred1, pred2, pred3; - __m128i diff0, diff1; - __m128i reg0, reg1; - int32_t src_stride2 = src_stride << 1; - int32_t pred_stride2 = pred_stride << 1; - int32_t diff_stride2 = diff_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t pred_stride3 = pred_stride2 + pred_stride; - int32_t diff_stride3 = diff_stride2 + diff_stride; - - DUP4_ARG2(__lsx_vldrepl_w, src_ptr, 0, src_ptr + src_stride, 0, - src_ptr + src_stride2, 0, src_ptr + src_stride3, 0, src0, src1, - src2, src3); - DUP4_ARG2(__lsx_vldrepl_w, pred_ptr, 0, pred_ptr + pred_stride, 0, - pred_ptr + pred_stride2, 0, pred_ptr + pred_stride3, 0, pred0, - pred1, pred2, pred3); - DUP4_ARG2(__lsx_vilvl_w, src1, src0, src3, src2, pred1, pred0, pred3, pred2, - src0, src2, pred0, pred2); - DUP2_ARG2(__lsx_vilvl_d, src2, src0, pred2, pred0, src0, pred0); - reg0 = __lsx_vilvl_b(src0, pred0); - reg1 = __lsx_vilvh_b(src0, pred0); - DUP2_ARG2(__lsx_vhsubw_hu_bu, reg0, reg0, reg1, reg1, diff0, diff1); - __lsx_vstelm_d(diff0, diff_ptr, 0, 0); - __lsx_vstelm_d(diff0, diff_ptr + diff_stride, 0, 1); - __lsx_vstelm_d(diff1, diff_ptr + diff_stride2, 0, 0); - __lsx_vstelm_d(diff1, diff_ptr + diff_stride3, 0, 1); -} - -static void sub_blk_8x8_lsx(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *pred_ptr, int32_t pred_stride, - int16_t *diff_ptr, int32_t diff_stride) { - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - __m128i pred0, pred1, pred2, pred3, pred4, pred5, pred6, pred7; - __m128i reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; - int32_t src_stride2 = src_stride << 1; - int32_t pred_stride2 = pred_stride << 1; - int32_t dst_stride = diff_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t pred_stride3 = pred_stride2 + pred_stride; - int32_t dst_stride2 = dst_stride << 1; - int32_t src_stride4 = src_stride2 << 1; - int32_t pred_stride4 = pred_stride2 << 1; - int32_t dst_stride3 = dst_stride + dst_stride2; - - DUP4_ARG2(__lsx_vldrepl_d, src_ptr, 0, src_ptr + src_stride, 0, - src_ptr + src_stride2, 0, src_ptr + src_stride3, 0, src0, src1, - src2, src3); - DUP4_ARG2(__lsx_vldrepl_d, pred_ptr, 0, pred_ptr + pred_stride, 0, - pred_ptr + pred_stride2, 0, pred_ptr + pred_stride3, 0, pred0, - pred1, pred2, pred3); - src_ptr += src_stride4; - pred_ptr += pred_stride4; - - DUP4_ARG2(__lsx_vldrepl_d, src_ptr, 0, src_ptr + src_stride, 0, - src_ptr + src_stride2, 0, src_ptr + src_stride3, 0, src4, src5, - src6, src7); - DUP4_ARG2(__lsx_vldrepl_d, pred_ptr, 0, pred_ptr + pred_stride, 0, - pred_ptr + pred_stride2, 0, pred_ptr + pred_stride3, 0, pred4, - pred5, pred6, pred7); - - DUP4_ARG2(__lsx_vilvl_b, src0, pred0, src1, pred1, src2, pred2, src3, pred3, - reg0, reg1, reg2, reg3); - DUP4_ARG2(__lsx_vilvl_b, src4, pred4, src5, pred5, src6, pred6, src7, pred7, - reg4, reg5, reg6, reg7); - DUP4_ARG2(__lsx_vhsubw_hu_bu, reg0, reg0, reg1, reg1, reg2, reg2, reg3, reg3, - src0, src1, src2, src3); - DUP4_ARG2(__lsx_vhsubw_hu_bu, reg4, reg4, reg5, reg5, reg6, reg6, reg7, reg7, - src4, src5, src6, src7); - __lsx_vst(src0, diff_ptr, 0); - __lsx_vstx(src1, diff_ptr, dst_stride); - __lsx_vstx(src2, diff_ptr, dst_stride2); - __lsx_vstx(src3, diff_ptr, dst_stride3); - diff_ptr += dst_stride2; - __lsx_vst(src4, diff_ptr, 0); - __lsx_vstx(src5, diff_ptr, dst_stride); - __lsx_vstx(src6, diff_ptr, dst_stride2); - __lsx_vstx(src7, diff_ptr, dst_stride3); -} - -static void sub_blk_16x16_lsx(const uint8_t *src, int32_t src_stride, - const uint8_t *pred, int32_t pred_stride, - int16_t *diff, int32_t diff_stride) { - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - __m128i pred0, pred1, pred2, pred3, pred4, pred5, pred6, pred7; - __m128i reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - int32_t src_stride2 = src_stride << 1; - int32_t pred_stride2 = pred_stride << 1; - int32_t dst_stride = diff_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t pred_stride3 = pred_stride2 + pred_stride; - int32_t dst_stride2 = dst_stride << 1; - int32_t src_stride4 = src_stride2 << 1; - int32_t pred_stride4 = pred_stride2 << 1; - int32_t dst_stride3 = dst_stride + dst_stride2; - int16_t *diff_tmp = diff + 8; - - DUP2_ARG2(__lsx_vld, src, 0, pred, 0, src0, pred0); - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src1, src2, src3, src4); - DUP4_ARG2(__lsx_vldx, pred, pred_stride, pred, pred_stride2, pred, - pred_stride3, pred, pred_stride4, pred1, pred2, pred3, pred4); - src += src_stride4; - pred += pred_stride4; - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - pred, pred_stride, src5, src6, src7, pred5); - DUP2_ARG2(__lsx_vldx, pred, pred_stride2, pred, pred_stride3, pred6, pred7); - src += src_stride4; - pred += pred_stride4; - DUP4_ARG2(__lsx_vilvl_b, src0, pred0, src1, pred1, src2, pred2, src3, pred3, - reg0, reg2, reg4, reg6); - DUP4_ARG2(__lsx_vilvh_b, src0, pred0, src1, pred1, src2, pred2, src3, pred3, - reg1, reg3, reg5, reg7); - DUP4_ARG2(__lsx_vilvl_b, src4, pred4, src5, pred5, src6, pred6, src7, pred7, - tmp0, tmp2, tmp4, tmp6); - DUP4_ARG2(__lsx_vilvh_b, src4, pred4, src5, pred5, src6, pred6, src7, pred7, - tmp1, tmp3, tmp5, tmp7); - DUP4_ARG2(__lsx_vhsubw_hu_bu, reg0, reg0, reg1, reg1, reg2, reg2, reg3, reg3, - src0, src1, src2, src3); - DUP4_ARG2(__lsx_vhsubw_hu_bu, reg4, reg4, reg5, reg5, reg6, reg6, reg7, reg7, - src4, src5, src6, src7); - DUP4_ARG2(__lsx_vhsubw_hu_bu, tmp0, tmp0, tmp1, tmp1, tmp2, tmp2, tmp3, tmp3, - pred0, pred1, pred2, pred3); - DUP4_ARG2(__lsx_vhsubw_hu_bu, tmp4, tmp4, tmp5, tmp5, tmp6, tmp6, tmp7, tmp7, - pred4, pred5, pred6, pred7); - __lsx_vst(src0, diff, 0); - __lsx_vstx(src2, diff, dst_stride); - __lsx_vstx(src4, diff, dst_stride2); - __lsx_vstx(src6, diff, dst_stride3); - __lsx_vst(src1, diff_tmp, 0); - __lsx_vstx(src3, diff_tmp, dst_stride); - __lsx_vstx(src5, diff_tmp, dst_stride2); - __lsx_vstx(src7, diff_tmp, dst_stride3); - diff += dst_stride2; - diff_tmp += dst_stride2; - __lsx_vst(pred0, diff, 0); - __lsx_vstx(pred2, diff, dst_stride); - __lsx_vstx(pred4, diff, dst_stride2); - __lsx_vstx(pred6, diff, dst_stride3); - __lsx_vst(pred1, diff_tmp, 0); - __lsx_vstx(pred3, diff_tmp, dst_stride); - __lsx_vstx(pred5, diff_tmp, dst_stride2); - __lsx_vstx(pred7, diff_tmp, dst_stride3); - diff += dst_stride2; - diff_tmp += dst_stride2; - DUP2_ARG2(__lsx_vld, src, 0, pred, 0, src0, pred0); - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src1, src2, src3, src4); - DUP4_ARG2(__lsx_vldx, pred, pred_stride, pred, pred_stride2, pred, - pred_stride3, pred, pred_stride4, pred1, pred2, pred3, pred4); - src += src_stride4; - pred += pred_stride4; - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - pred, pred_stride, src5, src6, src7, pred5); - DUP2_ARG2(__lsx_vldx, pred, pred_stride2, pred, pred_stride3, pred6, pred7); - DUP4_ARG2(__lsx_vilvl_b, src0, pred0, src1, pred1, src2, pred2, src3, pred3, - reg0, reg2, reg4, reg6); - DUP4_ARG2(__lsx_vilvh_b, src0, pred0, src1, pred1, src2, pred2, src3, pred3, - reg1, reg3, reg5, reg7); - DUP4_ARG2(__lsx_vilvl_b, src4, pred4, src5, pred5, src6, pred6, src7, pred7, - tmp0, tmp2, tmp4, tmp6); - DUP4_ARG2(__lsx_vilvh_b, src4, pred4, src5, pred5, src6, pred6, src7, pred7, - tmp1, tmp3, tmp5, tmp7); - DUP4_ARG2(__lsx_vhsubw_hu_bu, reg0, reg0, reg1, reg1, reg2, reg2, reg3, reg3, - src0, src1, src2, src3); - DUP4_ARG2(__lsx_vhsubw_hu_bu, reg4, reg4, reg5, reg5, reg6, reg6, reg7, reg7, - src4, src5, src6, src7); - DUP4_ARG2(__lsx_vhsubw_hu_bu, tmp0, tmp0, tmp1, tmp1, tmp2, tmp2, tmp3, tmp3, - pred0, pred1, pred2, pred3); - DUP4_ARG2(__lsx_vhsubw_hu_bu, tmp4, tmp4, tmp5, tmp5, tmp6, tmp6, tmp7, tmp7, - pred4, pred5, pred6, pred7); - __lsx_vst(src0, diff, 0); - __lsx_vstx(src2, diff, dst_stride); - __lsx_vstx(src4, diff, dst_stride2); - __lsx_vstx(src6, diff, dst_stride3); - __lsx_vst(src1, diff_tmp, 0); - __lsx_vstx(src3, diff_tmp, dst_stride); - __lsx_vstx(src5, diff_tmp, dst_stride2); - __lsx_vstx(src7, diff_tmp, dst_stride3); - diff += dst_stride2; - diff_tmp += dst_stride2; - __lsx_vst(pred0, diff, 0); - __lsx_vstx(pred2, diff, dst_stride); - __lsx_vstx(pred4, diff, dst_stride2); - __lsx_vstx(pred6, diff, dst_stride3); - __lsx_vst(pred1, diff_tmp, 0); - __lsx_vstx(pred3, diff_tmp, dst_stride); - __lsx_vstx(pred5, diff_tmp, dst_stride2); - __lsx_vstx(pred7, diff_tmp, dst_stride3); -} - -static void sub_blk_32x32_lsx(const uint8_t *src, int32_t src_stride, - const uint8_t *pred, int32_t pred_stride, - int16_t *diff, int32_t diff_stride) { - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - __m128i pred0, pred1, pred2, pred3, pred4, pred5, pred6, pred7; - __m128i reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - uint32_t loop_cnt; - int32_t src_stride2 = src_stride << 1; - int32_t pred_stride2 = pred_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t pred_stride3 = pred_stride2 + pred_stride; - int32_t src_stride4 = src_stride2 << 1; - int32_t pred_stride4 = pred_stride2 << 1; - - for (loop_cnt = 8; loop_cnt--;) { - const uint8_t *src_tmp = src + 16; - const uint8_t *pred_tmp = pred + 16; - DUP4_ARG2(__lsx_vld, src, 0, src_tmp, 0, pred, 0, pred_tmp, 0, src0, src1, - pred0, pred1); - DUP4_ARG2(__lsx_vldx, src, src_stride, src_tmp, src_stride, src, - src_stride2, src_tmp, src_stride2, src2, src3, src4, src5); - DUP4_ARG2(__lsx_vldx, src, src_stride3, src_tmp, src_stride3, pred, - pred_stride, pred_tmp, pred_stride, src6, src7, pred2, pred3); - DUP4_ARG2(__lsx_vldx, pred, pred_stride2, pred_tmp, pred_stride2, pred, - pred_stride3, pred_tmp, pred_stride3, pred4, pred5, pred6, pred7); - DUP4_ARG2(__lsx_vilvl_b, src0, pred0, src1, pred1, src2, pred2, src3, pred3, - reg0, reg2, reg4, reg6); - DUP4_ARG2(__lsx_vilvh_b, src0, pred0, src1, pred1, src2, pred2, src3, pred3, - reg1, reg3, reg5, reg7); - DUP4_ARG2(__lsx_vilvl_b, src4, pred4, src5, pred5, src6, pred6, src7, pred7, - tmp0, tmp2, tmp4, tmp6); - DUP4_ARG2(__lsx_vilvh_b, src4, pred4, src5, pred5, src6, pred6, src7, pred7, - tmp1, tmp3, tmp5, tmp7); - DUP4_ARG2(__lsx_vhsubw_hu_bu, reg0, reg0, reg1, reg1, reg2, reg2, reg3, - reg3, src0, src1, src2, src3); - DUP4_ARG2(__lsx_vhsubw_hu_bu, reg4, reg4, reg5, reg5, reg6, reg6, reg7, - reg7, src4, src5, src6, src7); - DUP4_ARG2(__lsx_vhsubw_hu_bu, tmp0, tmp0, tmp1, tmp1, tmp2, tmp2, tmp3, - tmp3, pred0, pred1, pred2, pred3); - DUP4_ARG2(__lsx_vhsubw_hu_bu, tmp4, tmp4, tmp5, tmp5, tmp6, tmp6, tmp7, - tmp7, pred4, pred5, pred6, pred7); - src += src_stride4; - pred += pred_stride4; - __lsx_vst(src0, diff, 0); - __lsx_vst(src1, diff, 16); - __lsx_vst(src2, diff, 32); - __lsx_vst(src3, diff, 48); - diff += diff_stride; - __lsx_vst(src4, diff, 0); - __lsx_vst(src5, diff, 16); - __lsx_vst(src6, diff, 32); - __lsx_vst(src7, diff, 48); - diff += diff_stride; - __lsx_vst(pred0, diff, 0); - __lsx_vst(pred1, diff, 16); - __lsx_vst(pred2, diff, 32); - __lsx_vst(pred3, diff, 48); - diff += diff_stride; - __lsx_vst(pred4, diff, 0); - __lsx_vst(pred5, diff, 16); - __lsx_vst(pred6, diff, 32); - __lsx_vst(pred7, diff, 48); - diff += diff_stride; - } -} - -static void sub_blk_64x64_lsx(const uint8_t *src, int32_t src_stride, - const uint8_t *pred, int32_t pred_stride, - int16_t *diff, int32_t diff_stride) { - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - __m128i pred0, pred1, pred2, pred3, pred4, pred5, pred6, pred7; - __m128i reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - uint32_t loop_cnt; - - for (loop_cnt = 32; loop_cnt--;) { - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src0, src1, src2, - src3); - DUP4_ARG2(__lsx_vld, pred, 0, pred, 16, pred, 32, pred, 48, pred0, pred1, - pred2, pred3); - src += src_stride; - pred += pred_stride; - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src4, src5, src6, - src7); - DUP4_ARG2(__lsx_vld, pred, 0, pred, 16, pred, 32, pred, 48, pred4, pred5, - pred6, pred7); - src += src_stride; - pred += pred_stride; - - DUP4_ARG2(__lsx_vilvl_b, src0, pred0, src1, pred1, src2, pred2, src3, pred3, - reg0, reg2, reg4, reg6); - DUP4_ARG2(__lsx_vilvh_b, src0, pred0, src1, pred1, src2, pred2, src3, pred3, - reg1, reg3, reg5, reg7); - DUP4_ARG2(__lsx_vilvl_b, src4, pred4, src5, pred5, src6, pred6, src7, pred7, - tmp0, tmp2, tmp4, tmp6); - DUP4_ARG2(__lsx_vilvh_b, src4, pred4, src5, pred5, src6, pred6, src7, pred7, - tmp1, tmp3, tmp5, tmp7); - DUP4_ARG2(__lsx_vhsubw_hu_bu, reg0, reg0, reg1, reg1, reg2, reg2, reg3, - reg3, src0, src1, src2, src3); - DUP4_ARG2(__lsx_vhsubw_hu_bu, reg4, reg4, reg5, reg5, reg6, reg6, reg7, - reg7, src4, src5, src6, src7); - DUP4_ARG2(__lsx_vhsubw_hu_bu, tmp0, tmp0, tmp1, tmp1, tmp2, tmp2, tmp3, - tmp3, pred0, pred1, pred2, pred3); - DUP4_ARG2(__lsx_vhsubw_hu_bu, tmp4, tmp4, tmp5, tmp5, tmp6, tmp6, tmp7, - tmp7, pred4, pred5, pred6, pred7); - __lsx_vst(src0, diff, 0); - __lsx_vst(src1, diff, 16); - __lsx_vst(src2, diff, 32); - __lsx_vst(src3, diff, 48); - __lsx_vst(src4, diff, 64); - __lsx_vst(src5, diff, 80); - __lsx_vst(src6, diff, 96); - __lsx_vst(src7, diff, 112); - diff += diff_stride; - __lsx_vst(pred0, diff, 0); - __lsx_vst(pred1, diff, 16); - __lsx_vst(pred2, diff, 32); - __lsx_vst(pred3, diff, 48); - __lsx_vst(pred4, diff, 64); - __lsx_vst(pred5, diff, 80); - __lsx_vst(pred6, diff, 96); - __lsx_vst(pred7, diff, 112); - diff += diff_stride; - } -} - -void vpx_subtract_block_lsx(int32_t rows, int32_t cols, int16_t *diff_ptr, - ptrdiff_t diff_stride, const uint8_t *src_ptr, - ptrdiff_t src_stride, const uint8_t *pred_ptr, - ptrdiff_t pred_stride) { - if (rows == cols) { - switch (rows) { - case 4: - sub_blk_4x4_lsx(src_ptr, src_stride, pred_ptr, pred_stride, diff_ptr, - diff_stride); - break; - case 8: - sub_blk_8x8_lsx(src_ptr, src_stride, pred_ptr, pred_stride, diff_ptr, - diff_stride); - break; - case 16: - sub_blk_16x16_lsx(src_ptr, src_stride, pred_ptr, pred_stride, diff_ptr, - diff_stride); - break; - case 32: - sub_blk_32x32_lsx(src_ptr, src_stride, pred_ptr, pred_stride, diff_ptr, - diff_stride); - break; - case 64: - sub_blk_64x64_lsx(src_ptr, src_stride, pred_ptr, pred_stride, diff_ptr, - diff_stride); - break; - default: - vpx_subtract_block_c(rows, cols, diff_ptr, diff_stride, src_ptr, - src_stride, pred_ptr, pred_stride); - break; - } - } else { - vpx_subtract_block_c(rows, cols, diff_ptr, diff_stride, src_ptr, src_stride, - pred_ptr, pred_stride); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/txfm_macros_lsx.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/txfm_macros_lsx.h deleted file mode 100644 index bd514831..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/txfm_macros_lsx.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_LOONGARCH_TXFM_MACROS_LSX_H_ -#define VPX_VPX_DSP_LOONGARCH_TXFM_MACROS_LSX_H_ - -#include "vpx_util/loongson_intrinsics.h" - -#define DOTP_CONST_PAIR(reg0, reg1, cnst0, cnst1, out0, out1) \ - do { \ - __m128i s0_m, s1_m, s2_m, s3_m, s4_m, s5_m; \ - __m128i k0_m, k1_m, k2_m, k3_m; \ - \ - k0_m = __lsx_vreplgr2vr_h(cnst0); \ - k1_m = __lsx_vreplgr2vr_h(cnst1); \ - k2_m = __lsx_vpackev_h(k1_m, k0_m); \ - \ - DUP2_ARG2(__lsx_vilvl_h, reg1, reg0, reg0, reg1, s5_m, s3_m); \ - DUP2_ARG2(__lsx_vilvh_h, reg1, reg0, reg0, reg1, s4_m, s2_m); \ - \ - DUP2_ARG2(__lsx_vmulwev_w_h, s5_m, k0_m, s4_m, k0_m, s1_m, s0_m); \ - k3_m = __lsx_vmulwod_w_h(s5_m, k1_m); \ - s1_m = __lsx_vsub_w(s1_m, k3_m); \ - k3_m = __lsx_vmulwod_w_h(s4_m, k1_m); \ - s0_m = __lsx_vsub_w(s0_m, k3_m); \ - \ - out0 = __lsx_vssrarni_h_w(s0_m, s1_m, DCT_CONST_BITS); \ - \ - DUP2_ARG2(__lsx_vdp2_w_h, s3_m, k2_m, s2_m, k2_m, s1_m, s0_m); \ - out1 = __lsx_vssrarni_h_w(s0_m, s1_m, DCT_CONST_BITS); \ - } while (0) - -#define DOT_SHIFT_RIGHT_PCK_H(in0, in1, in2, in3) \ - do { \ - __m128i tp0_m, tp1_m; \ - \ - DUP2_ARG2(__lsx_vdp2_w_h, in0, in2, in1, in2, tp1_m, tp0_m); \ - in3 = __lsx_vssrarni_h_w(tp1_m, tp0_m, DCT_CONST_BITS); \ - } while (0) - -#endif // VPX_VPX_DSP_LOONGARCH_TXFM_MACROS_LSX_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/variance_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/variance_lsx.c deleted file mode 100644 index 8fad342c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/variance_lsx.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/loongarch/variance_lsx.h" - -#define VARIANCE_WxH(sse, diff, shift) \ - (sse) - (((uint32_t)(diff) * (diff)) >> (shift)) - -#define VARIANCE_LARGE_WxH(sse, diff, shift) \ - (sse) - (((int64_t)(diff) * (diff)) >> (shift)) - -static uint32_t sse_diff_8width_lsx(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t height, int32_t *diff) { - int32_t res, ht_cnt = (height >> 2); - __m128i src0, src1, src2, src3, ref0, ref1, ref2, ref3, vec; - __m128i avg = __lsx_vldi(0); - __m128i var = avg; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - int32_t ref_stride2 = ref_stride << 1; - int32_t ref_stride3 = ref_stride2 + ref_stride; - int32_t ref_stride4 = ref_stride2 << 1; - - for (; ht_cnt--;) { - DUP4_ARG2(__lsx_vld, src_ptr, 0, src_ptr + src_stride, 0, - src_ptr + src_stride2, 0, src_ptr + src_stride3, 0, src0, src1, - src2, src3); - src_ptr += src_stride4; - DUP4_ARG2(__lsx_vld, ref_ptr, 0, ref_ptr + ref_stride, 0, - ref_ptr + ref_stride2, 0, ref_ptr + ref_stride3, 0, ref0, ref1, - ref2, ref3); - ref_ptr += ref_stride4; - - DUP4_ARG2(__lsx_vpickev_d, src1, src0, src3, src2, ref1, ref0, ref3, ref2, - src0, src1, ref0, ref1); - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - } - - vec = __lsx_vhaddw_w_h(avg, avg); - HADD_SW_S32(vec, *diff); - HADD_SW_S32(var, res); - return res; -} - -static uint32_t sse_diff_16width_lsx(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t height, int32_t *diff) { - int32_t res, ht_cnt = (height >> 2); - __m128i src, ref, vec; - __m128i avg = __lsx_vldi(0); - __m128i var = avg; - - for (; ht_cnt--;) { - src = __lsx_vld(src_ptr, 0); - src_ptr += src_stride; - ref = __lsx_vld(ref_ptr, 0); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src, ref, var, avg); - - src = __lsx_vld(src_ptr, 0); - src_ptr += src_stride; - ref = __lsx_vld(ref_ptr, 0); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src, ref, var, avg); - src = __lsx_vld(src_ptr, 0); - src_ptr += src_stride; - ref = __lsx_vld(ref_ptr, 0); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src, ref, var, avg); - - src = __lsx_vld(src_ptr, 0); - src_ptr += src_stride; - ref = __lsx_vld(ref_ptr, 0); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src, ref, var, avg); - } - vec = __lsx_vhaddw_w_h(avg, avg); - HADD_SW_S32(vec, *diff); - HADD_SW_S32(var, res); - return res; -} - -static uint32_t sse_diff_32width_lsx(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t height, int32_t *diff) { - int32_t res, ht_cnt = (height >> 2); - __m128i avg = __lsx_vldi(0); - __m128i src0, src1, ref0, ref1; - __m128i vec; - __m128i var = avg; - - for (; ht_cnt--;) { - DUP2_ARG2(__lsx_vld, src_ptr, 0, src_ptr, 16, src0, src1); - src_ptr += src_stride; - DUP2_ARG2(__lsx_vld, ref_ptr, 0, ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - - DUP2_ARG2(__lsx_vld, src_ptr, 0, src_ptr, 16, src0, src1); - src_ptr += src_stride; - DUP2_ARG2(__lsx_vld, ref_ptr, 0, ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - - DUP2_ARG2(__lsx_vld, src_ptr, 0, src_ptr, 16, src0, src1); - src_ptr += src_stride; - DUP2_ARG2(__lsx_vld, ref_ptr, 0, ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - - DUP2_ARG2(__lsx_vld, src_ptr, 0, src_ptr, 16, src0, src1); - src_ptr += src_stride; - DUP2_ARG2(__lsx_vld, ref_ptr, 0, ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - } - - vec = __lsx_vhaddw_w_h(avg, avg); - HADD_SW_S32(vec, *diff); - HADD_SW_S32(var, res); - return res; -} - -static uint32_t sse_diff_64x64_lsx(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t *diff) { - int32_t res, ht_cnt = 32; - __m128i avg0 = __lsx_vldi(0); - __m128i src0, src1, src2, src3; - __m128i ref0, ref1, ref2, ref3; - __m128i vec0, vec1; - __m128i avg1 = avg0; - __m128i avg2 = avg0; - __m128i avg3 = avg0; - __m128i var = avg0; - - for (; ht_cnt--;) { - DUP4_ARG2(__lsx_vld, src_ptr, 0, src_ptr, 16, src_ptr, 32, src_ptr, 48, - src0, src1, src2, src3); - src_ptr += src_stride; - DUP4_ARG2(__lsx_vld, ref_ptr, 0, ref_ptr, 16, ref_ptr, 32, ref_ptr, 48, - ref0, ref1, ref2, ref3); - ref_ptr += ref_stride; - - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - CALC_MSE_AVG_B(src2, ref2, var, avg2); - CALC_MSE_AVG_B(src3, ref3, var, avg3); - DUP4_ARG2(__lsx_vld, src_ptr, 0, src_ptr, 16, src_ptr, 32, src_ptr, 48, - src0, src1, src2, src3); - src_ptr += src_stride; - DUP4_ARG2(__lsx_vld, ref_ptr, 0, ref_ptr, 16, ref_ptr, 32, ref_ptr, 48, - ref0, ref1, ref2, ref3); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - CALC_MSE_AVG_B(src2, ref2, var, avg2); - CALC_MSE_AVG_B(src3, ref3, var, avg3); - } - vec0 = __lsx_vhaddw_w_h(avg0, avg0); - vec1 = __lsx_vhaddw_w_h(avg1, avg1); - vec0 = __lsx_vadd_w(vec0, vec1); - vec1 = __lsx_vhaddw_w_h(avg2, avg2); - vec0 = __lsx_vadd_w(vec0, vec1); - vec1 = __lsx_vhaddw_w_h(avg3, avg3); - vec0 = __lsx_vadd_w(vec0, vec1); - HADD_SW_S32(vec0, *diff); - HADD_SW_S32(var, res); - return res; -} - -#define VARIANCE_8Wx8H(sse, diff) VARIANCE_WxH(sse, diff, 6) -#define VARIANCE_16Wx16H(sse, diff) VARIANCE_WxH(sse, diff, 8) - -#define VARIANCE_32Wx32H(sse, diff) VARIANCE_LARGE_WxH(sse, diff, 10) -#define VARIANCE_64Wx64H(sse, diff) VARIANCE_LARGE_WxH(sse, diff, 12) - -#define VPX_VARIANCE_WDXHT_LSX(wd, ht) \ - uint32_t vpx_variance##wd##x##ht##_lsx( \ - const uint8_t *src, int32_t src_stride, const uint8_t *ref, \ - int32_t ref_stride, uint32_t *sse) { \ - int32_t diff; \ - \ - *sse = \ - sse_diff_##wd##width_lsx(src, src_stride, ref, ref_stride, ht, &diff); \ - \ - return VARIANCE_##wd##Wx##ht##H(*sse, diff); \ - } - -static uint32_t sse_16width_lsx(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t height) { - int32_t res, ht_cnt = (height >> 2); - __m128i src, ref; - __m128i var = __lsx_vldi(0); - - for (; ht_cnt--;) { - DUP2_ARG2(__lsx_vld, src_ptr, 0, ref_ptr, 0, src, ref); - src_ptr += src_stride; - ref_ptr += ref_stride; - CALC_MSE_B(src, ref, var); - - DUP2_ARG2(__lsx_vld, src_ptr, 0, ref_ptr, 0, src, ref); - src_ptr += src_stride; - ref_ptr += ref_stride; - CALC_MSE_B(src, ref, var); - - DUP2_ARG2(__lsx_vld, src_ptr, 0, ref_ptr, 0, src, ref); - src_ptr += src_stride; - ref_ptr += ref_stride; - CALC_MSE_B(src, ref, var); - - DUP2_ARG2(__lsx_vld, src_ptr, 0, ref_ptr, 0, src, ref); - src_ptr += src_stride; - ref_ptr += ref_stride; - CALC_MSE_B(src, ref, var); - } - HADD_SW_S32(var, res); - return res; -} - -VPX_VARIANCE_WDXHT_LSX(8, 8) -VPX_VARIANCE_WDXHT_LSX(16, 16) -VPX_VARIANCE_WDXHT_LSX(32, 32) - -uint32_t vpx_variance64x64_lsx(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - uint32_t *sse) { - int32_t diff; - - *sse = sse_diff_64x64_lsx(src, src_stride, ref, ref_stride, &diff); - - return VARIANCE_64Wx64H(*sse, diff); -} - -uint32_t vpx_mse16x16_lsx(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - uint32_t *sse) { - *sse = sse_16width_lsx(src, src_stride, ref, ref_stride, 16); - - return *sse; -} - -void vpx_get16x16var_lsx(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, uint32_t *sse, - int32_t *sum) { - *sse = sse_diff_16width_lsx(src, src_stride, ref, ref_stride, 16, sum); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/variance_lsx.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/variance_lsx.h deleted file mode 100644 index cf9e9890..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/variance_lsx.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_LOONGARCH_VARIANCE_LSX_H_ -#define VPX_VPX_DSP_LOONGARCH_VARIANCE_LSX_H_ - -#include "vpx_util/loongson_intrinsics.h" - -#define HADD_SW_S32(in0, in1) \ - do { \ - __m128i res0_m; \ - \ - res0_m = __lsx_vhaddw_d_w(in0, in0); \ - res0_m = __lsx_vhaddw_q_d(res0_m, res0_m); \ - in1 = __lsx_vpickve2gr_w(res0_m, 0); \ - } while (0) - -#define HORIZ_2TAP_FILT_UH(in0, in1, mask, coeff, shift, in2) \ - do { \ - __m128i tmp0_m, tmp1_m; \ - \ - tmp0_m = __lsx_vshuf_b(in1, in0, mask); \ - tmp1_m = __lsx_vdp2_h_bu(tmp0_m, coeff); \ - in2 = __lsx_vsrari_h(tmp1_m, shift); \ - } while (0) - -#define CALC_MSE_B(src, ref, var) \ - do { \ - __m128i src_l0_m, src_l1_m; \ - __m128i res_l0_m, res_l1_m; \ - \ - src_l0_m = __lsx_vilvl_b(src, ref); \ - src_l1_m = __lsx_vilvh_b(src, ref); \ - DUP2_ARG2(__lsx_vhsubw_hu_bu, src_l0_m, src_l0_m, src_l1_m, src_l1_m, \ - res_l0_m, res_l1_m); \ - var = __lsx_vdp2add_w_h(var, res_l0_m, res_l0_m); \ - var = __lsx_vdp2add_w_h(var, res_l1_m, res_l1_m); \ - } while (0) - -#define CALC_MSE_AVG_B(src, ref, var, sub) \ - do { \ - __m128i src_l0_m, src_l1_m; \ - __m128i res_l0_m, res_l1_m; \ - \ - src_l0_m = __lsx_vilvl_b(src, ref); \ - src_l1_m = __lsx_vilvh_b(src, ref); \ - DUP2_ARG2(__lsx_vhsubw_hu_bu, src_l0_m, src_l0_m, src_l1_m, src_l1_m, \ - res_l0_m, res_l1_m); \ - var = __lsx_vdp2add_w_h(var, res_l0_m, res_l0_m); \ - var = __lsx_vdp2add_w_h(var, res_l1_m, res_l1_m); \ - sub = __lsx_vadd_h(sub, res_l0_m); \ - sub = __lsx_vadd_h(sub, res_l1_m); \ - } while (0) - -#endif // VPX_VPX_DSP_LOONGARCH_VARIANCE_LSX_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_avg_horiz_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_avg_horiz_lsx.c deleted file mode 100644 index 1c592288..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_avg_horiz_lsx.c +++ /dev/null @@ -1,972 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/loongarch/vpx_convolve_lsx.h" - -static const uint8_t mc_filt_mask_arr[16 * 3] = { - /* 8 width cases */ - 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, - /* 4 width cases */ - 0, 1, 1, 2, 2, 3, 3, 4, 16, 17, 17, 18, 18, 19, 19, 20, - /* 4 width cases */ - 8, 9, 9, 10, 10, 11, 11, 12, 24, 25, 25, 26, 26, 27, 27, 28 -}; - -static void common_hz_8t_and_aver_dst_4x4_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter) { - uint8_t *dst_tmp = dst; - __m128i src0, src1, src2, src3; - __m128i filter0, filter1, filter2, filter3; - __m128i mask0, mask1, mask2, mask3; - __m128i tmp0, tmp1; - __m128i dst0, dst1, dst2, dst3; - - mask0 = __lsx_vld(mc_filt_mask_arr, 16); - src -= 3; - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - mask3 = __lsx_vaddi_bu(mask0, 6); - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - LSX_LD_4(src, src_stride, src0, src1, src2, src3); - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, - filter0, filter1, filter2, filter3, tmp0, tmp1); - dst0 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst1 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_w(dst_tmp, 0); - dst0 = __lsx_vilvl_w(dst1, dst0); - dst1 = __lsx_vilvl_w(dst3, dst2); - dst0 = __lsx_vilvl_d(dst1, dst0); - tmp0 = __lsx_vssrarni_b_h(tmp1, tmp0, 7); - tmp0 = __lsx_vxori_b(tmp0, 128); - dst0 = __lsx_vavgr_bu(tmp0, dst0); - __lsx_vstelm_w(dst0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(dst0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(dst0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(dst0, dst, 0, 3); -} - -static void common_hz_8t_and_aver_dst_4x8_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter) { - uint8_t *dst_tmp = dst; - __m128i src0, src1, src2, src3, filter0, filter1, filter2, filter3; - __m128i mask0, mask1, mask2, mask3, tmp0, tmp1, tmp2, tmp3; - __m128i dst0, dst1; - - mask0 = __lsx_vld(mc_filt_mask_arr, 16); - src -= 3; - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - mask3 = __lsx_vaddi_bu(mask0, 6); - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - - LSX_LD_4(src, src_stride, src0, src1, src2, src3); - src += src_stride; - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - tmp0 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - tmp1 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - tmp2 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - tmp3 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - tmp0 = __lsx_vilvl_w(tmp1, tmp0); - tmp1 = __lsx_vilvl_w(tmp3, tmp2); - dst0 = __lsx_vilvl_d(tmp1, tmp0); - - tmp0 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - tmp1 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - tmp2 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - tmp3 = __lsx_vldrepl_w(dst_tmp, 0); - tmp0 = __lsx_vilvl_w(tmp1, tmp0); - tmp1 = __lsx_vilvl_w(tmp3, tmp2); - dst1 = __lsx_vilvl_d(tmp1, tmp0); - - HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, - filter0, filter1, filter2, filter3, tmp0, tmp1); - LSX_LD_4(src, src_stride, src0, src1, src2, src3); - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, - filter0, filter1, filter2, filter3, tmp2, tmp3); - DUP4_ARG3(__lsx_vssrarni_b_h, tmp0, tmp0, 7, tmp1, tmp1, 7, tmp2, tmp2, 7, - tmp3, tmp3, 7, tmp0, tmp1, tmp2, tmp3); - DUP2_ARG2(__lsx_vilvl_d, tmp1, tmp0, tmp3, tmp2, tmp0, tmp1); - DUP2_ARG2(__lsx_vxori_b, tmp0, 128, tmp1, 128, tmp0, tmp1); - DUP2_ARG2(__lsx_vavgr_bu, tmp0, dst0, tmp1, dst1, dst0, dst1); - __lsx_vstelm_w(dst0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(dst0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(dst0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(dst0, dst, 0, 3); - dst += dst_stride; - __lsx_vstelm_w(dst1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(dst1, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(dst1, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(dst1, dst, 0, 3); -} - -static void common_hz_8t_and_aver_dst_4w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int8_t *filter, - int32_t height) { - if (height == 4) { - common_hz_8t_and_aver_dst_4x4_lsx(src, src_stride, dst, dst_stride, filter); - } else if (height == 8) { - common_hz_8t_and_aver_dst_4x8_lsx(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_hz_8t_and_aver_dst_8w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int8_t *filter, - int32_t height) { - int32_t loop_cnt = height >> 2; - uint8_t *dst_tmp = dst; - __m128i src0, src1, src2, src3, filter0, filter1, filter2, filter3; - __m128i mask0, mask1, mask2, mask3; - __m128i tmp0, tmp1, tmp2, tmp3; - __m128i dst0, dst1, dst2, dst3; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - uint8_t *_src = (uint8_t *)src - 3; - - mask0 = __lsx_vld(mc_filt_mask_arr, 0); - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - mask3 = __lsx_vaddi_bu(mask0, 6); - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - for (; loop_cnt--;) { - src0 = __lsx_vld(_src, 0); - DUP2_ARG2(__lsx_vldx, _src, src_stride, _src, src_stride2, src1, src2); - src3 = __lsx_vldx(_src, src_stride3); - _src += src_stride4; - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filter0, filter1, filter2, filter3, tmp0, - tmp1, tmp2, tmp3); - dst0 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst1 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - DUP2_ARG2(__lsx_vilvl_d, dst1, dst0, dst3, dst2, dst0, dst1); - DUP2_ARG3(__lsx_vssrarni_b_h, tmp1, tmp0, 7, tmp3, tmp2, 7, tmp0, tmp1); - DUP2_ARG2(__lsx_vxori_b, tmp0, 128, tmp1, 128, tmp0, tmp1); - DUP2_ARG2(__lsx_vavgr_bu, tmp0, dst0, tmp1, dst1, dst0, dst1); - __lsx_vstelm_d(dst0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(dst0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(dst1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(dst1, dst, 0, 1); - dst += dst_stride; - } -} - -static void common_hz_8t_and_aver_dst_16w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - int32_t loop_cnt = height >> 1; - int32_t dst_stride2 = dst_stride << 1; - uint8_t *dst_tmp = dst; - __m128i src0, src1, src2, src3, filter0, filter1, filter2, filter3; - __m128i mask0, mask1, mask2, mask3, dst0, dst1, dst2, dst3; - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - __m128i tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15; - - mask0 = __lsx_vld(mc_filt_mask_arr, 0); - src -= 3; - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - mask3 = __lsx_vaddi_bu(mask0, 6); - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - - for (; loop_cnt--;) { - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src0, src1); - src += src_stride; - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src2, src3); - src += src_stride; - dst0 = __lsx_vld(dst_tmp, 0); - dst1 = __lsx_vldx(dst_tmp, dst_stride); - dst_tmp += dst_stride2; - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - DUP4_ARG3(__lsx_vshuf_b, src0, src0, mask0, src1, src1, mask0, src2, src2, - mask0, src3, src3, mask0, tmp0, tmp1, tmp2, tmp3); - DUP4_ARG3(__lsx_vshuf_b, src0, src0, mask1, src1, src1, mask1, src2, src2, - mask1, src3, src3, mask1, tmp4, tmp5, tmp6, tmp7); - DUP4_ARG3(__lsx_vshuf_b, src0, src0, mask2, src1, src1, mask2, src2, src2, - mask2, src3, src3, mask2, tmp8, tmp9, tmp10, tmp11); - DUP4_ARG3(__lsx_vshuf_b, src0, src0, mask3, src1, src1, mask3, src2, src2, - mask3, src3, src3, mask3, tmp12, tmp13, tmp14, tmp15); - DUP4_ARG2(__lsx_vdp2_h_b, tmp0, filter0, tmp1, filter0, tmp2, filter0, tmp3, - filter0, tmp0, tmp1, tmp2, tmp3); - DUP4_ARG2(__lsx_vdp2_h_b, tmp8, filter2, tmp9, filter2, tmp10, filter2, - tmp11, filter2, tmp8, tmp9, tmp10, tmp11); - DUP4_ARG3(__lsx_vdp2add_h_b, tmp0, tmp4, filter1, tmp1, tmp5, filter1, tmp2, - tmp6, filter1, tmp3, tmp7, filter1, tmp0, tmp1, tmp2, tmp3); - DUP4_ARG3(__lsx_vdp2add_h_b, tmp8, tmp12, filter3, tmp9, tmp13, filter3, - tmp10, tmp14, filter3, tmp11, tmp15, filter3, tmp4, tmp5, tmp6, - tmp7); - DUP4_ARG2(__lsx_vsadd_h, tmp0, tmp4, tmp1, tmp5, tmp2, tmp6, tmp3, tmp7, - tmp0, tmp1, tmp2, tmp3); - DUP2_ARG3(__lsx_vssrarni_b_h, tmp1, tmp0, 7, tmp3, tmp2, 7, dst2, dst3); - DUP2_ARG2(__lsx_vxori_b, dst2, 128, dst3, 128, dst2, dst3); - DUP2_ARG2(__lsx_vavgr_bu, dst0, dst2, dst1, dst3, dst0, dst1); - __lsx_vst(dst0, dst, 0); - __lsx_vstx(dst1, dst, dst_stride); - dst += dst_stride2; - } -} - -static void common_hz_8t_and_aver_dst_32w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = height; - uint8_t *dst_tmp = dst; - __m128i src0, src1, src2, src3, filter0, filter1, filter2, filter3; - __m128i mask0, mask1, mask2, mask3, dst0, dst1; - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - __m128i tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - - mask0 = __lsx_vld(mc_filt_mask_arr, 0); - src -= 3; - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - mask3 = __lsx_vaddi_bu(mask0, 6); - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - for (; loop_cnt--;) { - DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src2); - src3 = __lsx_vld(src, 24); - src1 = __lsx_vshuf_b(src2, src0, shuff); - src += src_stride; - DUP2_ARG2(__lsx_vld, dst_tmp, 0, dst, 16, dst0, dst1); - dst_tmp += dst_stride; - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - DUP4_ARG3(__lsx_vshuf_b, src0, src0, mask0, src1, src1, mask0, src2, src2, - mask0, src3, src3, mask0, tmp0, tmp1, tmp2, tmp3); - DUP4_ARG3(__lsx_vshuf_b, src0, src0, mask1, src1, src1, mask1, src2, src2, - mask1, src3, src3, mask1, tmp4, tmp5, tmp6, tmp7); - DUP4_ARG3(__lsx_vshuf_b, src0, src0, mask2, src1, src1, mask2, src2, src2, - mask2, src3, src3, mask2, tmp8, tmp9, tmp10, tmp11); - DUP4_ARG3(__lsx_vshuf_b, src0, src0, mask3, src1, src1, mask3, src2, src2, - mask3, src3, src3, mask3, tmp12, tmp13, tmp14, tmp15); - DUP4_ARG2(__lsx_vdp2_h_b, tmp0, filter0, tmp1, filter0, tmp2, filter0, tmp3, - filter0, tmp0, tmp1, tmp2, tmp3); - DUP4_ARG2(__lsx_vdp2_h_b, tmp8, filter2, tmp9, filter2, tmp10, filter2, - tmp11, filter2, tmp8, tmp9, tmp10, tmp11); - DUP4_ARG3(__lsx_vdp2add_h_b, tmp0, tmp4, filter1, tmp1, tmp5, filter1, tmp2, - tmp6, filter1, tmp3, tmp7, filter1, tmp0, tmp1, tmp2, tmp3); - DUP4_ARG3(__lsx_vdp2add_h_b, tmp8, tmp12, filter3, tmp9, tmp13, filter3, - tmp10, tmp14, filter3, tmp11, tmp15, filter3, tmp4, tmp5, tmp6, - tmp7); - DUP4_ARG2(__lsx_vsadd_h, tmp0, tmp4, tmp1, tmp5, tmp2, tmp6, tmp3, tmp7, - tmp0, tmp1, tmp2, tmp3); - DUP2_ARG3(__lsx_vssrarni_b_h, tmp1, tmp0, 7, tmp3, tmp2, 7, tmp0, tmp1); - DUP2_ARG2(__lsx_vxori_b, tmp0, 128, tmp1, 128, tmp0, tmp1); - DUP2_ARG2(__lsx_vavgr_bu, dst0, tmp0, dst1, tmp1, dst0, dst1); - __lsx_vst(dst0, dst, 0); - __lsx_vst(dst1, dst, 16); - dst += dst_stride; - } -} - -static void common_hz_8t_and_aver_dst_64w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - int32_t loop_cnt = height; - __m128i src0, src1, src2, src3; - __m128i filter0, filter1, filter2, filter3; - __m128i mask0, mask1, mask2, mask3; - __m128i out0, out1, out2, out3, dst0, dst1; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - - mask0 = __lsx_vld(mc_filt_mask_arr, 0); - src -= 3; - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - mask3 = __lsx_vaddi_bu(mask0, 6); - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - for (; loop_cnt--;) { - DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src2); - src3 = __lsx_vld(src, 24); - src1 = __lsx_vshuf_b(src2, src0, shuff); - DUP2_ARG2(__lsx_vld, dst, 0, dst, 16, dst0, dst1); - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filter0, filter1, filter2, filter3, out0, - out1, out2, out3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, 7, out3, out2, 7, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - DUP2_ARG2(__lsx_vavgr_bu, out0, dst0, out1, dst1, out0, out1); - __lsx_vst(out0, dst, 0); - __lsx_vst(out1, dst, 16); - - DUP2_ARG2(__lsx_vld, src, 32, src, 48, src0, src2); - src3 = __lsx_vld(src, 56); - src1 = __lsx_vshuf_b(src2, src0, shuff); - DUP2_ARG2(__lsx_vld, dst, 32, dst, 48, dst0, dst1); - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filter0, filter1, filter2, filter3, out0, - out1, out2, out3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, 7, out3, out2, 7, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - DUP2_ARG2(__lsx_vavgr_bu, out0, dst0, out1, dst1, out0, out1); - __lsx_vst(out0, dst, 32); - __lsx_vst(out1, dst, 48); - src += src_stride; - dst += dst_stride; - } -} - -static void common_hz_2t_and_aver_dst_4x4_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter) { - __m128i src0, src1, src2, src3, mask; - __m128i dst0, dst1, dst2, dst3, vec0, vec1, filt0; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - uint8_t *dst_tmp = dst; - - mask = __lsx_vld(mc_filt_mask_arr, 16); - - /* rearranging filter */ - filt0 = __lsx_vldrepl_h(filter, 0); - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - dst0 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst1 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - DUP2_ARG2(__lsx_vilvl_w, dst1, dst0, dst3, dst2, dst0, dst1); - dst0 = __lsx_vilvl_d(dst1, dst0); - DUP2_ARG3(__lsx_vshuf_b, src1, src0, mask, src3, src2, mask, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec0, vec1); - vec0 = __lsx_vssrarni_bu_h(vec1, vec0, FILTER_BITS); - vec0 = __lsx_vavgr_bu(vec0, dst0); - __lsx_vstelm_w(vec0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(vec0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(vec0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(vec0, dst, 0, 3); -} - -static void common_hz_2t_and_aver_dst_4x8_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter) { - __m128i src0, src1, src2, src3, src4, src5, src6, src7, mask; - __m128i filt0, vec0, vec1, vec2, vec3, res0, res1, res2, res3; - __m128i dst0, dst1, dst2, dst3, dst4; - __m128i vec4, vec5, vec6, vec7; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - uint8_t *src_tmp1 = (uint8_t *)src + src_stride4; - uint8_t *dst_tmp = dst; - - mask = __lsx_vld(mc_filt_mask_arr, 16); - - /* rearranging filter */ - filt0 = __lsx_vldrepl_h(filter, 0); - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - - src4 = __lsx_vld(src_tmp1, 0); - DUP2_ARG2(__lsx_vldx, src_tmp1, src_stride, src_tmp1, src_stride2, src5, - src6); - src7 = __lsx_vldx(src_tmp1, src_stride3); - - dst0 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst1 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - DUP2_ARG2(__lsx_vilvl_w, dst1, dst0, dst3, dst2, dst0, dst1); - dst0 = __lsx_vilvl_d(dst1, dst0); - - dst1 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst4 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - DUP2_ARG2(__lsx_vilvl_w, dst2, dst1, dst4, dst3, dst1, dst2); - dst1 = __lsx_vilvl_d(dst2, dst1); - - DUP2_ARG3(__lsx_vshuf_b, src1, src0, mask, src3, src2, mask, vec0, vec1); - DUP2_ARG3(__lsx_vshuf_b, src5, src4, mask, src7, src6, mask, vec2, vec3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, filt0, - vec4, vec5, vec6, vec7); - DUP4_ARG3(__lsx_vssrarni_bu_h, vec4, vec4, FILTER_BITS, vec5, vec5, - FILTER_BITS, vec6, vec6, FILTER_BITS, vec7, vec7, FILTER_BITS, res0, - res1, res2, res3); - DUP2_ARG2(__lsx_vilvl_d, res1, res0, res3, res2, res0, res2); - DUP2_ARG2(__lsx_vavgr_bu, res0, dst0, res2, dst1, res0, res2); - - __lsx_vstelm_w(res0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(res0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(res0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(res0, dst, 0, 3); - dst += dst_stride; - - __lsx_vstelm_w(res2, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(res2, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(res2, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(res2, dst, 0, 3); - dst += dst_stride; -} - -static void common_hz_2t_and_aver_dst_4w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int8_t *filter, - int32_t height) { - if (height == 4) { - common_hz_2t_and_aver_dst_4x4_lsx(src, src_stride, dst, dst_stride, filter); - } else if (height == 8) { - common_hz_2t_and_aver_dst_4x8_lsx(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_hz_2t_and_aver_dst_8x4_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter) { - __m128i src0, src1, src2, src3, mask; - __m128i filt0, dst0, dst1, dst2, dst3; - __m128i vec0, vec1, vec2, vec3; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - uint8_t *dst_tmp = dst; - - mask = __lsx_vld(mc_filt_mask_arr, 0); - - /* rearranging filter */ - filt0 = __lsx_vldrepl_h(filter, 0); - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - DUP2_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, vec0, vec1); - DUP2_ARG3(__lsx_vshuf_b, src2, src2, mask, src3, src3, mask, vec2, vec3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, filt0, - vec0, vec1, vec2, vec3); - DUP2_ARG3(__lsx_vssrarni_bu_h, vec1, vec0, FILTER_BITS, vec3, vec2, - FILTER_BITS, vec0, vec1); - dst0 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst1 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - - DUP2_ARG2(__lsx_vilvl_d, dst1, dst0, dst3, dst2, dst0, dst1); - DUP2_ARG2(__lsx_vavgr_bu, vec0, dst0, vec1, dst1, vec0, vec1); - __lsx_vstelm_d(vec0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(vec0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(vec1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(vec1, dst, 0, 1); -} - -static void common_hz_2t_and_aver_dst_8x8mult_lsx( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - __m128i src0, src1, src2, src3, mask; - __m128i filt0, dst0, dst1, dst2, dst3; - __m128i vec0, vec1, vec2, vec3; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - uint8_t *dst_tmp = dst; - - mask = __lsx_vld(mc_filt_mask_arr, 0); - - /* rearranging filter */ - filt0 = __lsx_vldrepl_h(filter, 0); - - LSX_LD_4(src, src_stride, src0, src1, src2, src3); - src += src_stride; - - DUP2_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, vec0, vec1); - DUP2_ARG3(__lsx_vshuf_b, src2, src2, mask, src3, src3, mask, vec2, vec3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, filt0, - vec0, vec1, vec2, vec3); - DUP2_ARG3(__lsx_vssrarni_bu_h, vec1, vec0, FILTER_BITS, vec3, vec2, - FILTER_BITS, vec0, vec2); - dst0 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst1 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - DUP2_ARG2(__lsx_vilvl_d, dst1, dst0, dst3, dst2, dst0, dst1); - - DUP2_ARG2(__lsx_vavgr_bu, vec0, dst0, vec2, dst1, vec0, vec2); - __lsx_vstelm_d(vec0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(vec0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(vec2, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(vec2, dst, 0, 1); - dst += dst_stride; - - LSX_LD_4(src, src_stride, src0, src1, src2, src3); - src += src_stride; - DUP2_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, vec0, vec1); - DUP2_ARG3(__lsx_vshuf_b, src2, src2, mask, src3, src3, mask, vec2, vec3); - - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, filt0, - vec0, vec1, vec2, vec3); - DUP2_ARG3(__lsx_vssrarni_bu_h, vec1, vec0, FILTER_BITS, vec3, vec2, - FILTER_BITS, vec0, vec2); - dst0 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst1 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - DUP2_ARG2(__lsx_vilvl_d, dst1, dst0, dst3, dst2, dst0, dst1); - DUP2_ARG2(__lsx_vavgr_bu, vec0, dst0, vec2, dst1, vec0, vec2); - __lsx_vstelm_d(vec0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(vec0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(vec2, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(vec2, dst, 0, 1); - dst += dst_stride; - - if (height == 16) { - LSX_LD_4(src, src_stride, src0, src1, src2, src3); - src += src_stride; - - DUP2_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, vec0, vec1); - DUP2_ARG3(__lsx_vshuf_b, src2, src2, mask, src3, src3, mask, vec2, vec3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, - filt0, vec0, vec1, vec2, vec3); - DUP2_ARG3(__lsx_vssrarni_bu_h, vec1, vec0, FILTER_BITS, vec3, vec2, - FILTER_BITS, vec0, vec2); - dst0 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst1 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - DUP2_ARG2(__lsx_vilvl_d, dst1, dst0, dst3, dst2, dst0, dst1); - DUP2_ARG2(__lsx_vavgr_bu, vec0, dst0, vec2, dst1, vec0, vec2); - __lsx_vstelm_d(vec0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(vec0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(vec2, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(vec2, dst, 0, 1); - dst += dst_stride; - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - DUP2_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, vec0, vec1); - DUP2_ARG3(__lsx_vshuf_b, src2, src2, mask, src3, src3, mask, vec2, vec3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, - filt0, vec0, vec1, vec2, vec3); - DUP2_ARG3(__lsx_vssrarni_bu_h, vec1, vec0, FILTER_BITS, vec3, vec2, - FILTER_BITS, vec0, vec2); - dst0 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst1 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - DUP2_ARG2(__lsx_vilvl_d, dst1, dst0, dst3, dst2, dst0, dst1); - DUP2_ARG2(__lsx_vavgr_bu, vec0, dst0, vec2, dst1, vec0, vec2); - __lsx_vstelm_d(vec0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(vec0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(vec2, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(vec2, dst, 0, 1); - dst += dst_stride; - } -} - -static void common_hz_2t_and_aver_dst_8w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int8_t *filter, - int32_t height) { - if (height == 4) { - common_hz_2t_and_aver_dst_8x4_lsx(src, src_stride, dst, dst_stride, filter); - } else { - common_hz_2t_and_aver_dst_8x8mult_lsx(src, src_stride, dst, dst_stride, - filter, height); - } -} - -static void common_hz_2t_and_aver_dst_16w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = (height >> 2) - 1; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, mask; - __m128i filt0, dst0; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - __m128i res0, res1, res2, res3, res4, res5, res6, res7; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - uint8_t *src_tmp1 = (uint8_t *)src + 8; - - mask = __lsx_vld(mc_filt_mask_arr, 0); - - /* rearranging filter */ - filt0 = __lsx_vldrepl_h(filter, 0); - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src2, src4); - src6 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - src1 = __lsx_vld(src_tmp1, 0); - DUP2_ARG2(__lsx_vldx, src_tmp1, src_stride, src_tmp1, src_stride2, src3, - src5); - src7 = __lsx_vldx(src_tmp1, src_stride3); - src_tmp1 += src_stride4; - - DUP2_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, vec0, vec1); - DUP2_ARG3(__lsx_vshuf_b, src2, src2, mask, src3, src3, mask, vec2, vec3); - DUP2_ARG3(__lsx_vshuf_b, src4, src4, mask, src5, src5, mask, vec4, vec5); - DUP2_ARG3(__lsx_vshuf_b, src6, src6, mask, src7, src7, mask, vec6, vec7); - - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, filt0, - res0, res1, res2, res3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, vec6, filt0, vec7, filt0, - res4, res5, res6, res7); - DUP4_ARG3(__lsx_vssrarni_bu_h, res1, res0, FILTER_BITS, res3, res2, - FILTER_BITS, res5, res4, FILTER_BITS, res7, res6, FILTER_BITS, res0, - res2, res4, res6); - dst0 = __lsx_vld(dst, 0); - res0 = __lsx_vavgr_bu(res0, dst0); - __lsx_vst(res0, dst, 0); - dst += dst_stride; - - dst0 = __lsx_vld(dst, 0); - res2 = __lsx_vavgr_bu(res2, dst0); - __lsx_vst(res2, dst, 0); - dst += dst_stride; - - dst0 = __lsx_vld(dst, 0); - res4 = __lsx_vavgr_bu(res4, dst0); - __lsx_vst(res4, dst, 0); - dst += dst_stride; - - dst0 = __lsx_vld(dst, 0); - res6 = __lsx_vavgr_bu(res6, dst0); - __lsx_vst(res6, dst, 0); - dst += dst_stride; - - for (; loop_cnt--;) { - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src2, src4); - src6 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - src1 = __lsx_vld(src_tmp1, 0); - DUP2_ARG2(__lsx_vldx, src_tmp1, src_stride, src_tmp1, src_stride2, src3, - src5); - src7 = __lsx_vldx(src_tmp1, src_stride3); - src_tmp1 += src_stride4; - - DUP2_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, vec0, vec1); - DUP2_ARG3(__lsx_vshuf_b, src2, src2, mask, src3, src3, mask, vec2, vec3); - DUP2_ARG3(__lsx_vshuf_b, src4, src4, mask, src5, src5, mask, vec4, vec5); - DUP2_ARG3(__lsx_vshuf_b, src6, src6, mask, src7, src7, mask, vec6, vec7); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, - filt0, res0, res1, res2, res3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, vec6, filt0, vec7, - filt0, res4, res5, res6, res7); - - DUP4_ARG3(__lsx_vssrarni_bu_h, res1, res0, FILTER_BITS, res3, res2, - FILTER_BITS, res5, res4, FILTER_BITS, res7, res6, FILTER_BITS, - res0, res2, res4, res6); - dst0 = __lsx_vld(dst, 0); - res0 = __lsx_vavgr_bu(res0, dst0); - __lsx_vst(res0, dst, 0); - dst += dst_stride; - - dst0 = __lsx_vld(dst, 0); - res2 = __lsx_vavgr_bu(res2, dst0); - __lsx_vst(res2, dst, 0); - dst += dst_stride; - - dst0 = __lsx_vld(dst, 0); - res4 = __lsx_vavgr_bu(res4, dst0); - __lsx_vst(res4, dst, 0); - dst += dst_stride; - - dst0 = __lsx_vld(dst, 0); - res6 = __lsx_vavgr_bu(res6, dst0); - __lsx_vst(res6, dst, 0); - dst += dst_stride; - } -} - -static void common_hz_2t_and_aver_dst_32w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = (height >> 1); - __m128i src0, src1, src2, src3, src4, src5, src6, src7, mask; - __m128i filt0, dst0, dst1; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - __m128i res0, res1, res2, res3, res4, res5, res6, res7; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - - mask = __lsx_vld(mc_filt_mask_arr, 0); - - /* rearranging filter */ - filt0 = __lsx_vldrepl_h(filter, 0); - - for (; loop_cnt--;) { - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vld, src, 16, src, 24, src2, src3); - src1 = __lsx_vshuf_b(src2, src0, shuff); - src += src_stride; - src4 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vld, src, 16, src, 24, src6, src7); - src5 = __lsx_vshuf_b(src6, src4, shuff); - src += src_stride; - - DUP2_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, vec0, vec1); - DUP2_ARG3(__lsx_vshuf_b, src2, src2, mask, src3, src3, mask, vec2, vec3); - DUP2_ARG3(__lsx_vshuf_b, src4, src4, mask, src5, src5, mask, vec4, vec5); - DUP2_ARG3(__lsx_vshuf_b, src6, src6, mask, src7, src7, mask, vec6, vec7); - - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, - filt0, res0, res1, res2, res3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, vec6, filt0, vec7, - filt0, res4, res5, res6, res7); - DUP4_ARG3(__lsx_vssrarni_bu_h, res1, res0, FILTER_BITS, res3, res2, - FILTER_BITS, res5, res4, FILTER_BITS, res7, res6, FILTER_BITS, - res0, res2, res4, res6); - - DUP2_ARG2(__lsx_vld, dst, 0, dst, 16, dst0, dst1); - res0 = __lsx_vavgr_bu(res0, dst0); - __lsx_vst(res0, dst, 0); - res2 = __lsx_vavgr_bu(res2, dst1); - __lsx_vst(res2, dst, 16); - dst += dst_stride; - - DUP2_ARG2(__lsx_vld, dst, 0, dst, 16, dst0, dst1); - res4 = __lsx_vavgr_bu(res4, dst0); - __lsx_vst(res4, dst, 0); - res6 = __lsx_vavgr_bu(res6, dst1); - __lsx_vst(res6, dst, 16); - dst += dst_stride; - } -} - -static void common_hz_2t_and_aver_dst_64w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = height; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, mask; - __m128i filt0, dst0, dst1, dst2, dst3; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - __m128i out0, out1, out2, out3, out4, out5, out6, out7; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - - mask = __lsx_vld(mc_filt_mask_arr, 0); - - /* rearranging filter */ - filt0 = __lsx_vldrepl_h(filter, 0); - - for (; loop_cnt--;) { - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src0, src2, src4, - src6); - src7 = __lsx_vld(src, 56); - DUP2_ARG3(__lsx_vshuf_b, src2, src0, shuff, src4, src2, shuff, src1, src3); - src5 = __lsx_vshuf_b(src6, src4, shuff); - src += src_stride; - - DUP2_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, vec0, vec1); - DUP2_ARG3(__lsx_vshuf_b, src2, src2, mask, src3, src3, mask, vec2, vec3); - DUP2_ARG3(__lsx_vshuf_b, src4, src4, mask, src5, src5, mask, vec4, vec5); - DUP2_ARG3(__lsx_vshuf_b, src6, src6, mask, src7, src7, mask, vec6, vec7); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, - filt0, out0, out1, out2, out3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, vec6, filt0, vec7, - filt0, out4, out5, out6, out7); - - DUP4_ARG3(__lsx_vssrarni_bu_h, out1, out0, FILTER_BITS, out3, out2, - FILTER_BITS, out5, out4, FILTER_BITS, out7, out6, FILTER_BITS, - out0, out2, out4, out6); - - DUP4_ARG2(__lsx_vld, dst, 0, dst, 16, dst, 32, dst, 48, dst0, dst1, dst2, - dst3); - out0 = __lsx_vavgr_bu(out0, dst0); - __lsx_vst(out0, dst, 0); - out2 = __lsx_vavgr_bu(out2, dst1); - __lsx_vst(out2, dst, 16); - out4 = __lsx_vavgr_bu(out4, dst2); - __lsx_vst(out4, dst, 32); - out6 = __lsx_vavgr_bu(out6, dst3); - __lsx_vst(out6, dst, 48); - dst += dst_stride; - } -} - -void vpx_convolve8_avg_horiz_lsx(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - const int16_t *const filter_x = filter[x0_q4]; - int8_t cnt, filt_hor[8]; - - assert(x_step_q4 == 16); - assert(((const int32_t *)filter_x)[1] != 0x800000); - - for (cnt = 0; cnt < 8; ++cnt) { - filt_hor[cnt] = filter_x[cnt]; - } - - if (vpx_get_filter_taps(filter_x) == 2) { - switch (w) { - case 4: - common_hz_2t_and_aver_dst_4w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], h); - break; - case 8: - common_hz_2t_and_aver_dst_8w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], h); - break; - case 16: - common_hz_2t_and_aver_dst_16w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], h); - break; - - case 32: - common_hz_2t_and_aver_dst_32w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], h); - break; - case 64: - common_hz_2t_and_aver_dst_64w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], h); - break; - default: - vpx_convolve8_avg_horiz_c(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } else { - switch (w) { - case 4: - common_hz_8t_and_aver_dst_4w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, h); - break; - case 8: - common_hz_8t_and_aver_dst_8w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, h); - break; - case 16: - common_hz_8t_and_aver_dst_16w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, h); - break; - case 32: - common_hz_8t_and_aver_dst_32w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, h); - break; - case 64: - common_hz_8t_and_aver_dst_64w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, h); - break; - default: - vpx_convolve8_avg_horiz_c(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_avg_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_avg_lsx.c deleted file mode 100644 index d1abf622..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_avg_lsx.c +++ /dev/null @@ -1,737 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/loongarch/vpx_convolve_lsx.h" - -static const uint8_t mc_filt_mask_arr[16 * 3] = { - /* 8 width cases */ - 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, - /* 4 width cases */ - 0, 1, 1, 2, 2, 3, 3, 4, 16, 17, 17, 18, 18, 19, 19, 20, - /* 4 width cases */ - 8, 9, 9, 10, 10, 11, 11, 12, 24, 25, 25, 26, 26, 27, 27, 28 -}; - -static void common_hv_8ht_8vt_and_aver_dst_4w_lsx( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter_horiz, const int8_t *filter_vert, int32_t height) { - uint32_t loop_cnt = height >> 2; - uint8_t *dst_tmp = dst; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - __m128i filt_hz0, filt_hz1, filt_hz2, filt_hz3; - __m128i filt_vt0, filt_vt1, filt_vt2, filt_vt3; - __m128i mask0, mask1, mask2, mask3; - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; - __m128i out0, out1; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride + src_stride2; - int32_t src_stride4 = src_stride2 << 1; - uint8_t *_src = (uint8_t *)src - 3 - src_stride3; - - mask0 = __lsx_vld(mc_filt_mask_arr, 16); - DUP4_ARG2(__lsx_vldrepl_h, filter_horiz, 0, filter_horiz, 2, filter_horiz, 4, - filter_horiz, 6, filt_hz0, filt_hz1, filt_hz2, filt_hz3); - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - mask3 = __lsx_vaddi_bu(mask0, 6); - - src0 = __lsx_vld(_src, 0); - DUP2_ARG2(__lsx_vldx, _src, src_stride, _src, src_stride2, src1, src2); - src3 = __lsx_vldx(_src, src_stride3); - _src += src_stride4; - src4 = __lsx_vld(_src, 0); - DUP2_ARG2(__lsx_vldx, _src, src_stride, _src, src_stride2, src5, src6); - _src += src_stride3; - - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - DUP2_ARG2(__lsx_vxori_b, src4, 128, src5, 128, src4, src5); - src6 = __lsx_vxori_b(src6, 128); - - tmp0 = horiz_8tap_filt(src0, src1, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - tmp2 = horiz_8tap_filt(src2, src3, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - tmp4 = horiz_8tap_filt(src4, src5, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - tmp5 = horiz_8tap_filt(src5, src6, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - DUP2_ARG3(__lsx_vshuf_b, tmp2, tmp0, shuff, tmp4, tmp2, shuff, tmp1, tmp3); - DUP4_ARG2(__lsx_vldrepl_h, filter_vert, 0, filter_vert, 2, filter_vert, 4, - filter_vert, 6, filt_vt0, filt_vt1, filt_vt2, filt_vt3); - DUP2_ARG2(__lsx_vpackev_b, tmp1, tmp0, tmp3, tmp2, tmp0, tmp1); - tmp2 = __lsx_vpackev_b(tmp5, tmp4); - for (; loop_cnt--;) { - src7 = __lsx_vld(_src, 0); - DUP2_ARG2(__lsx_vldx, _src, src_stride, _src, src_stride2, src8, src9); - src10 = __lsx_vldx(_src, src_stride3); - _src += src_stride4; - src2 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - src3 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - src4 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - src5 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - DUP2_ARG2(__lsx_vilvl_w, src3, src2, src5, src4, src2, src3); - src2 = __lsx_vilvl_d(src3, src2); - DUP4_ARG2(__lsx_vxori_b, src7, 128, src8, 128, src9, 128, src10, 128, src7, - src8, src9, src10); - tmp3 = horiz_8tap_filt(src7, src8, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - tmp4 = __lsx_vshuf_b(tmp3, tmp5, shuff); - tmp4 = __lsx_vpackev_b(tmp3, tmp4); - out0 = filt_8tap_dpadd_s_h(tmp0, tmp1, tmp2, tmp4, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - src1 = horiz_8tap_filt(src9, src10, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src0 = __lsx_vshuf_b(src1, tmp3, shuff); - src0 = __lsx_vpackev_b(src1, src0); - out1 = filt_8tap_dpadd_s_h(tmp1, tmp2, tmp4, src0, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - out0 = __lsx_vssrarni_b_h(out1, out0, FILTER_BITS); - out0 = __lsx_vxori_b(out0, 128); - out0 = __lsx_vavgr_bu(out0, src2); - __lsx_vstelm_w(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 3); - dst += dst_stride; - - tmp5 = src1; - tmp0 = tmp2; - tmp1 = tmp4; - tmp2 = src0; - } -} - -static void common_hv_8ht_8vt_and_aver_dst_8w_lsx( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter_horiz, const int8_t *filter_vert, int32_t height) { - uint32_t loop_cnt = height >> 2; - uint8_t *dst_tmp = dst; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - __m128i filt_hz0, filt_hz1, filt_hz2, filt_hz3; - __m128i filt_vt0, filt_vt1, filt_vt2, filt_vt3; - __m128i mask0, mask1, mask2, mask3; - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6; - __m128i out0, out1; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride + src_stride2; - int32_t src_stride4 = src_stride2 << 1; - uint8_t *_src = (uint8_t *)src - 3 - src_stride3; - - mask0 = __lsx_vld(mc_filt_mask_arr, 0); - DUP4_ARG2(__lsx_vldrepl_h, filter_horiz, 0, filter_horiz, 2, filter_horiz, 4, - filter_horiz, 6, filt_hz0, filt_hz1, filt_hz2, filt_hz3); - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - mask3 = __lsx_vaddi_bu(mask0, 6); - - src0 = __lsx_vld(_src, 0); - DUP2_ARG2(__lsx_vldx, _src, src_stride, _src, src_stride2, src1, src2); - src3 = __lsx_vldx(_src, src_stride3); - _src += src_stride4; - src4 = __lsx_vld(_src, 0); - DUP2_ARG2(__lsx_vldx, _src, src_stride, _src, src_stride2, src5, src6); - _src += src_stride3; - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - DUP2_ARG2(__lsx_vxori_b, src4, 128, src5, 128, src4, src5); - src6 = __lsx_vxori_b(src6, 128); - - src0 = horiz_8tap_filt(src0, src0, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src1 = horiz_8tap_filt(src1, src1, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src2 = horiz_8tap_filt(src2, src2, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src3 = horiz_8tap_filt(src3, src3, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src4 = horiz_8tap_filt(src4, src4, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src5 = horiz_8tap_filt(src5, src5, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src6 = horiz_8tap_filt(src6, src6, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - - DUP4_ARG2(__lsx_vldrepl_h, filter_vert, 0, filter_vert, 2, filter_vert, 4, - filter_vert, 6, filt_vt0, filt_vt1, filt_vt2, filt_vt3); - DUP4_ARG2(__lsx_vpackev_b, src1, src0, src3, src2, src5, src4, src2, src1, - tmp0, tmp1, tmp2, tmp4); - DUP2_ARG2(__lsx_vpackev_b, src4, src3, src6, src5, tmp5, tmp6); - - for (; loop_cnt--;) { - src7 = __lsx_vld(_src, 0); - DUP2_ARG2(__lsx_vldx, _src, src_stride, _src, src_stride2, src8, src9); - src10 = __lsx_vldx(_src, src_stride3); - _src += src_stride4; - - DUP4_ARG2(__lsx_vxori_b, src7, 128, src8, 128, src9, 128, src10, 128, src7, - src8, src9, src10); - src7 = horiz_8tap_filt(src7, src7, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - tmp3 = __lsx_vpackev_b(src7, src6); - out0 = filt_8tap_dpadd_s_h(tmp0, tmp1, tmp2, tmp3, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - src8 = horiz_8tap_filt(src8, src8, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src0 = __lsx_vpackev_b(src8, src7); - out1 = filt_8tap_dpadd_s_h(tmp4, tmp5, tmp6, src0, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - src9 = horiz_8tap_filt(src9, src9, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src1 = __lsx_vpackev_b(src9, src8); - src3 = filt_8tap_dpadd_s_h(tmp1, tmp2, tmp3, src1, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - src10 = horiz_8tap_filt(src10, src10, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src2 = __lsx_vpackev_b(src10, src9); - src4 = filt_8tap_dpadd_s_h(tmp5, tmp6, src0, src2, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, FILTER_BITS, src4, src3, - FILTER_BITS, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - src5 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - src7 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - src8 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - src9 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - DUP2_ARG2(__lsx_vilvl_d, src7, src5, src9, src8, src5, src7); - DUP2_ARG2(__lsx_vavgr_bu, out0, src5, out1, src7, out0, out1); - __lsx_vstelm_d(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(out1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(out1, dst, 0, 1); - dst += dst_stride; - - src6 = src10; - tmp0 = tmp2; - tmp1 = tmp3; - tmp2 = src1; - tmp4 = tmp6; - tmp5 = src0; - tmp6 = src2; - } -} - -static void common_hv_8ht_8vt_and_aver_dst_16w_lsx( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter_horiz, const int8_t *filter_vert, int32_t height) { - common_hv_8ht_8vt_and_aver_dst_8w_lsx(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height); - src += 8; - dst += 8; - - common_hv_8ht_8vt_and_aver_dst_8w_lsx(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height); -} - -static void common_hv_8ht_8vt_and_aver_dst_32w_lsx( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter_horiz, const int8_t *filter_vert, int32_t height) { - int32_t multiple8_cnt; - - for (multiple8_cnt = 4; multiple8_cnt--;) { - common_hv_8ht_8vt_and_aver_dst_8w_lsx(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height); - src += 8; - dst += 8; - } -} - -static void common_hv_8ht_8vt_and_aver_dst_64w_lsx( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter_horiz, const int8_t *filter_vert, int32_t height) { - int32_t multiple8_cnt; - - for (multiple8_cnt = 8; multiple8_cnt--;) { - common_hv_8ht_8vt_and_aver_dst_8w_lsx(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height); - - src += 8; - dst += 8; - } -} - -static void common_hv_2ht_2vt_and_aver_dst_4x4_lsx( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert) { - __m128i src0, src1, src2, src3, src4, mask; - __m128i filt_hz, filt_vt, vec0, vec1; - __m128i dst0, dst1, dst2, dst3; - __m128i hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, tmp0, tmp1; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - - mask = __lsx_vld(mc_filt_mask_arr, 16); - /* rearranging filter */ - DUP2_ARG2(__lsx_vldrepl_h, filter_horiz, 0, filter_vert, 0, filt_hz, filt_vt); - - src0 = __lsx_vld(src, 0); - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src1, src2, src3, src4); - - hz_out0 = horiz_2tap_filt_uh(src0, src1, mask, filt_hz); - hz_out2 = horiz_2tap_filt_uh(src2, src3, mask, filt_hz); - hz_out4 = horiz_2tap_filt_uh(src4, src4, mask, filt_hz); - hz_out1 = __lsx_vshuf_b(hz_out2, hz_out0, shuff); - hz_out3 = __lsx_vpickod_d(hz_out4, hz_out2); - DUP2_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - - dst0 = __lsx_vldrepl_w(dst, 0); - dst1 = __lsx_vldrepl_w(dst + dst_stride, 0); - dst2 = __lsx_vldrepl_w(dst + dst_stride2, 0); - dst3 = __lsx_vldrepl_w(dst + dst_stride3, 0); - dst0 = __lsx_vilvl_w(dst1, dst0); - dst1 = __lsx_vilvl_w(dst3, dst2); - dst0 = __lsx_vilvl_d(dst1, dst0); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst0); - __lsx_vstelm_w(tmp0, dst, 0, 0); - __lsx_vstelm_w(tmp0, dst + dst_stride, 0, 1); - __lsx_vstelm_w(tmp0, dst + dst_stride2, 0, 2); - __lsx_vstelm_w(tmp0, dst + dst_stride3, 0, 3); -} - -static void common_hv_2ht_2vt_and_aver_dst_4x8_lsx( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert) { - uint8_t *dst_tmp = dst; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, mask; - __m128i filt_hz, filt_vt, vec0, vec1, vec2, vec3, res0, res1; - __m128i hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; - __m128i hz_out7, hz_out8, tmp0, tmp1, tmp2, tmp3; - __m128i dst0, dst1, dst2, dst3, dst4; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - mask = __lsx_vld(mc_filt_mask_arr, 16); - - /* rearranging filter */ - filt_hz = __lsx_vldrepl_h(filter_horiz, 0); - filt_vt = __lsx_vldrepl_h(filter_vert, 0); - - src0 = __lsx_vld(src, 0); - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src1, src2, src3, src4); - src += src_stride4; - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src5, src6, src7, src8); - src += src_stride4; - - hz_out0 = horiz_2tap_filt_uh(src0, src1, mask, filt_hz); - hz_out2 = horiz_2tap_filt_uh(src2, src3, mask, filt_hz); - hz_out4 = horiz_2tap_filt_uh(src4, src5, mask, filt_hz); - hz_out6 = horiz_2tap_filt_uh(src6, src7, mask, filt_hz); - hz_out8 = horiz_2tap_filt_uh(src8, src8, mask, filt_hz); - DUP2_ARG3(__lsx_vshuf_b, hz_out2, hz_out0, shuff, hz_out4, hz_out2, shuff, - hz_out1, hz_out3); - hz_out5 = __lsx_vshuf_b(hz_out6, hz_out4, shuff); - hz_out7 = __lsx_vpickod_d(hz_out8, hz_out6); - - dst0 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst1 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst0 = __lsx_vilvl_w(dst1, dst0); - dst1 = __lsx_vilvl_w(dst3, dst2); - dst0 = __lsx_vilvl_d(dst1, dst0); - - dst1 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst4 = __lsx_vldrepl_w(dst_tmp, 0); - dst1 = __lsx_vilvl_w(dst2, dst1); - dst2 = __lsx_vilvl_w(dst4, dst3); - dst1 = __lsx_vilvl_d(dst2, dst1); - - DUP4_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out3, hz_out2, hz_out5, - hz_out4, hz_out7, hz_out6, vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, vec2, filt_vt, vec3, - filt_vt, tmp0, tmp1, tmp2, tmp3); - DUP2_ARG3(__lsx_vssrarni_bu_h, tmp1, tmp0, FILTER_BITS, tmp3, tmp2, - FILTER_BITS, res0, res1); - DUP2_ARG2(__lsx_vavgr_bu, res0, dst0, res1, dst1, res0, res1); - - __lsx_vstelm_w(res0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(res0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(res0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(res0, dst, 0, 3); - dst += dst_stride; - - __lsx_vstelm_w(res1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(res1, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(res1, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(res1, dst, 0, 3); -} - -static void common_hv_2ht_2vt_and_aver_dst_4w_lsx( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, int32_t height) { - if (height == 4) { - common_hv_2ht_2vt_and_aver_dst_4x4_lsx(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert); - } else if (height == 8) { - common_hv_2ht_2vt_and_aver_dst_4x8_lsx(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert); - } -} - -static void common_hv_2ht_2vt_and_aver_dst_8x4_lsx( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert) { - __m128i src0, src1, src2, src3, src4, mask; - __m128i filt_hz, filt_vt, vec0, vec1, vec2, vec3; - __m128i hz_out0, hz_out1, tmp0, tmp1, tmp2, tmp3; - __m128i dst0, dst1, dst2, dst3; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - uint8_t *dst_tmp = dst; - mask = __lsx_vld(mc_filt_mask_arr, 0); - /* rearranging filter */ - filt_hz = __lsx_vldrepl_h(filter_horiz, 0); - filt_vt = __lsx_vldrepl_h(filter_vert, 0); - - src0 = __lsx_vld(src, 0); - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src1, src2, src3, src4); - - dst0 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst1 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_d(dst_tmp, 0); - DUP2_ARG2(__lsx_vilvl_d, dst1, dst0, dst3, dst2, dst0, dst1); - hz_out0 = horiz_2tap_filt_uh(src0, src0, mask, filt_hz); - hz_out1 = horiz_2tap_filt_uh(src1, src1, mask, filt_hz); - vec0 = __lsx_vpackev_b(hz_out1, hz_out0); - tmp0 = __lsx_vdp2_h_bu(vec0, filt_vt); - - hz_out0 = horiz_2tap_filt_uh(src2, src2, mask, filt_hz); - vec1 = __lsx_vpackev_b(hz_out0, hz_out1); - tmp1 = __lsx_vdp2_h_bu(vec1, filt_vt); - - hz_out1 = horiz_2tap_filt_uh(src3, src3, mask, filt_hz); - vec2 = __lsx_vpackev_b(hz_out1, hz_out0); - tmp2 = __lsx_vdp2_h_bu(vec2, filt_vt); - - hz_out0 = horiz_2tap_filt_uh(src4, src4, mask, filt_hz); - vec3 = __lsx_vpackev_b(hz_out0, hz_out1); - tmp3 = __lsx_vdp2_h_bu(vec3, filt_vt); - DUP2_ARG3(__lsx_vssrarni_bu_h, tmp1, tmp0, FILTER_BITS, tmp3, tmp2, - FILTER_BITS, tmp0, tmp1); - AVG_ST4_D(tmp0, tmp1, dst0, dst1, dst, dst_stride); -} - -static void common_hv_2ht_2vt_and_aver_dst_8x8mult_lsx( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, int32_t height) { - uint32_t loop_cnt = (height >> 2); - __m128i src0, src1, src2, src3, src4, mask; - __m128i filt_hz, filt_vt, vec0; - __m128i hz_out0, hz_out1, tmp0, tmp1, tmp2, tmp3; - __m128i dst0, dst1, dst2, dst3; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - uint8_t *dst_tmp = dst; - - /* rearranging filter */ - mask = __lsx_vld(mc_filt_mask_arr, 0); - - filt_hz = __lsx_vldrepl_h(filter_horiz, 0); - filt_vt = __lsx_vldrepl_h(filter_vert, 0); - - src0 = __lsx_vld(src, 0); - src += src_stride; - - hz_out0 = horiz_2tap_filt_uh(src0, src0, mask, filt_hz); - - for (; loop_cnt--;) { - src1 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src2, src3); - src4 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - hz_out1 = horiz_2tap_filt_uh(src1, src1, mask, filt_hz); - vec0 = __lsx_vpackev_b(hz_out1, hz_out0); - tmp0 = __lsx_vdp2_h_bu(vec0, filt_vt); - - hz_out0 = horiz_2tap_filt_uh(src2, src2, mask, filt_hz); - vec0 = __lsx_vpackev_b(hz_out0, hz_out1); - tmp1 = __lsx_vdp2_h_bu(vec0, filt_vt); - - hz_out1 = horiz_2tap_filt_uh(src3, src3, mask, filt_hz); - vec0 = __lsx_vpackev_b(hz_out1, hz_out0); - tmp2 = __lsx_vdp2_h_bu(vec0, filt_vt); - - hz_out0 = horiz_2tap_filt_uh(src4, src4, mask, filt_hz); - vec0 = __lsx_vpackev_b(hz_out0, hz_out1); - tmp3 = __lsx_vdp2_h_bu(vec0, filt_vt); - DUP2_ARG3(__lsx_vssrarni_bu_h, tmp1, tmp0, FILTER_BITS, tmp3, tmp2, - FILTER_BITS, tmp0, tmp1); - - dst0 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst1 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - DUP2_ARG2(__lsx_vilvl_d, dst1, dst0, dst3, dst2, dst0, dst1); - AVG_ST4_D(tmp0, tmp1, dst0, dst1, dst, dst_stride); - dst += dst_stride; - } -} - -static void common_hv_2ht_2vt_and_aver_dst_8w_lsx( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, int32_t height) { - if (height == 4) { - common_hv_2ht_2vt_and_aver_dst_8x4_lsx(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert); - } else { - common_hv_2ht_2vt_and_aver_dst_8x8mult_lsx( - src, src_stride, dst, dst_stride, filter_horiz, filter_vert, height); - } -} - -static void common_hv_2ht_2vt_and_aver_dst_16w_lsx( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, int32_t height) { - uint8_t *src_tmp1; - uint32_t loop_cnt = (height >> 2); - __m128i src0, src1, src2, src3, src4, src5, src6, src7, mask; - __m128i filt_hz, filt_vt, vec0, vec1, dst0, dst1, dst2, dst3; - __m128i hz_out0, hz_out1, hz_out2, hz_out3, tmp0, tmp1, tmp3; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - int32_t dst_stride4 = dst_stride << 2; - - mask = __lsx_vld(mc_filt_mask_arr, 0); - /* rearranging filter */ - filt_hz = __lsx_vldrepl_h(filter_horiz, 0); - filt_vt = __lsx_vldrepl_h(filter_vert, 0); - - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src0, src1); - src += src_stride; - - hz_out0 = horiz_2tap_filt_uh(src0, src0, mask, filt_hz); - hz_out2 = horiz_2tap_filt_uh(src1, src1, mask, filt_hz); - - for (; loop_cnt--;) { - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src2, src4); - src6 = __lsx_vldx(src, src_stride3); - src_tmp1 = (uint8_t *)(src + 8); - src1 = __lsx_vld(src_tmp1, 0); - DUP2_ARG2(__lsx_vldx, src_tmp1, src_stride, src_tmp1, src_stride2, src3, - src5); - src7 = __lsx_vldx(src_tmp1, src_stride3); - src += src_stride4; - dst0 = __lsx_vld(dst, 0); - DUP2_ARG2(__lsx_vldx, dst, dst_stride, dst, dst_stride2, dst1, dst2); - dst3 = __lsx_vldx(dst, dst_stride3); - - hz_out1 = horiz_2tap_filt_uh(src0, src0, mask, filt_hz); - hz_out3 = horiz_2tap_filt_uh(src1, src1, mask, filt_hz); - DUP2_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp0, tmp1); - tmp3 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp3 = __lsx_vavgr_bu(tmp3, dst0); - __lsx_vst(tmp3, dst, 0); - - hz_out0 = horiz_2tap_filt_uh(src2, src2, mask, filt_hz); - hz_out2 = horiz_2tap_filt_uh(src3, src3, mask, filt_hz); - DUP2_ARG2(__lsx_vpackev_b, hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp0, tmp1); - tmp3 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp3 = __lsx_vavgr_bu(tmp3, dst1); - __lsx_vstx(tmp3, dst, dst_stride); - - hz_out1 = horiz_2tap_filt_uh(src4, src4, mask, filt_hz); - hz_out3 = horiz_2tap_filt_uh(src5, src5, mask, filt_hz); - DUP2_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp0, tmp1); - tmp3 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp3 = __lsx_vavgr_bu(tmp3, dst2); - __lsx_vstx(tmp3, dst, dst_stride2); - - hz_out0 = horiz_2tap_filt_uh(src6, src6, mask, filt_hz); - hz_out2 = horiz_2tap_filt_uh(src7, src7, mask, filt_hz); - DUP2_ARG2(__lsx_vpackev_b, hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp0, tmp1); - tmp3 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp3 = __lsx_vavgr_bu(tmp3, dst3); - __lsx_vstx(tmp3, dst, dst_stride3); - dst += dst_stride4; - } -} - -static void common_hv_2ht_2vt_and_aver_dst_32w_lsx( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, int32_t height) { - common_hv_2ht_2vt_and_aver_dst_16w_lsx(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height); - src += 16; - dst += 16; - - common_hv_2ht_2vt_and_aver_dst_16w_lsx(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height); -} - -static void common_hv_2ht_2vt_and_aver_dst_64w_lsx( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 4; multiple8_cnt--;) { - common_hv_2ht_2vt_and_aver_dst_16w_lsx(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height); - src += 16; - dst += 16; - } -} - -void vpx_convolve8_avg_lsx(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, int x_step_q4, - int y0_q4, int y_step_q4, int w, int h) { - const int16_t *const filter_x = filter[x0_q4]; - const int16_t *const filter_y = filter[y0_q4]; - int8_t cnt, filt_hor[8], filt_ver[8]; - - assert(x_step_q4 == 16); - assert(y_step_q4 == 16); - assert(((const int32_t *)filter_x)[1] != 0x800000); - assert(((const int32_t *)filter_y)[1] != 0x800000); - - for (cnt = 0; cnt < 8; ++cnt) { - filt_hor[cnt] = filter_x[cnt]; - filt_ver[cnt] = filter_y[cnt]; - } - if (vpx_get_filter_taps(filter_x) == 2 && - vpx_get_filter_taps(filter_y) == 2) { - switch (w) { - case 4: - common_hv_2ht_2vt_and_aver_dst_4w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], - &filt_ver[3], h); - break; - case 8: - common_hv_2ht_2vt_and_aver_dst_8w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], - &filt_ver[3], h); - break; - case 16: - common_hv_2ht_2vt_and_aver_dst_16w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, - &filt_hor[3], &filt_ver[3], h); - break; - case 32: - common_hv_2ht_2vt_and_aver_dst_32w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, - &filt_hor[3], &filt_ver[3], h); - break; - case 64: - common_hv_2ht_2vt_and_aver_dst_64w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, - &filt_hor[3], &filt_ver[3], h); - break; - default: - vpx_convolve8_avg_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } else if (vpx_get_filter_taps(filter_x) == 2 || - vpx_get_filter_taps(filter_y) == 2) { - vpx_convolve8_avg_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - } else { - switch (w) { - case 4: - common_hv_8ht_8vt_and_aver_dst_4w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, - filt_ver, h); - break; - case 8: - common_hv_8ht_8vt_and_aver_dst_8w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, - filt_ver, h); - break; - case 16: - common_hv_8ht_8vt_and_aver_dst_16w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, - filt_ver, h); - break; - case 32: - common_hv_8ht_8vt_and_aver_dst_32w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, - filt_ver, h); - break; - case 64: - common_hv_8ht_8vt_and_aver_dst_64w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, - filt_ver, h); - break; - default: - vpx_convolve8_avg_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_avg_vert_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_avg_vert_lsx.c deleted file mode 100644 index 5c6413df..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_avg_vert_lsx.c +++ /dev/null @@ -1,918 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/loongarch/vpx_convolve_lsx.h" - -static void common_vt_8t_and_aver_dst_4w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - const int8_t *filter, - int32_t height) { - uint32_t loop_cnt = (height >> 2); - uint8_t *dst_tmp = dst; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; - __m128i reg0, reg1, reg2, reg3, reg4; - __m128i filter0, filter1, filter2, filter3; - __m128i out0, out1; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride + src_stride2; - int32_t src_stride4 = src_stride2 << 1; - uint8_t *src_tmp0 = (uint8_t *)src - src_stride3; - - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - src0 = __lsx_vld(src_tmp0, 0); - DUP2_ARG2(__lsx_vldx, src_tmp0, src_stride, src_tmp0, src_stride2, src1, - src2); - src3 = __lsx_vldx(src_tmp0, src_stride3); - src_tmp0 += src_stride4; - src4 = __lsx_vld(src_tmp0, 0); - DUP2_ARG2(__lsx_vldx, src_tmp0, src_stride, src_tmp0, src_stride2, src5, - src6); - src_tmp0 += src_stride3; - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src3, src2, src5, src4, src2, src1, tmp0, - tmp1, tmp2, tmp3); - DUP2_ARG2(__lsx_vilvl_b, src4, src3, src6, src5, tmp4, tmp5); - DUP2_ARG2(__lsx_vilvl_d, tmp3, tmp0, tmp4, tmp1, reg0, reg1); - reg2 = __lsx_vilvl_d(tmp5, tmp2); - DUP2_ARG2(__lsx_vxori_b, reg0, 128, reg1, 128, reg0, reg1); - reg2 = __lsx_vxori_b(reg2, 128); - - for (; loop_cnt--;) { - src7 = __lsx_vld(src_tmp0, 0); - DUP2_ARG2(__lsx_vldx, src_tmp0, src_stride, src_tmp0, src_stride2, src8, - src9); - src10 = __lsx_vldx(src_tmp0, src_stride3); - src_tmp0 += src_stride4; - src0 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - src1 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - src2 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - src3 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - DUP2_ARG2(__lsx_vilvl_w, src1, src0, src3, src2, src0, src1); - src0 = __lsx_vilvl_d(src1, src0); - DUP4_ARG2(__lsx_vilvl_b, src7, src6, src8, src7, src9, src8, src10, src9, - tmp0, tmp1, tmp2, tmp3); - DUP2_ARG2(__lsx_vilvl_d, tmp1, tmp0, tmp3, tmp2, reg3, reg4); - DUP2_ARG2(__lsx_vxori_b, reg3, 128, reg4, 128, reg3, reg4); - out0 = filt_8tap_dpadd_s_h(reg0, reg1, reg2, reg3, filter0, filter1, - filter2, filter3); - out1 = filt_8tap_dpadd_s_h(reg1, reg2, reg3, reg4, filter0, filter1, - filter2, filter3); - out0 = __lsx_vssrarni_b_h(out1, out0, 7); - out0 = __lsx_vxori_b(out0, 128); - out0 = __lsx_vavgr_bu(out0, src0); - __lsx_vstelm_w(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 3); - dst += dst_stride; - reg0 = reg2; - reg1 = reg3; - reg2 = reg4; - src6 = src10; - } -} - -static void common_vt_8t_and_aver_dst_8w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - const int8_t *filter, - int32_t height) { - uint32_t loop_cnt = height >> 2; - uint8_t *dst_tmp = dst; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - __m128i tmp0, tmp1, tmp2, tmp3; - __m128i reg0, reg1, reg2, reg3, reg4, reg5; - __m128i filter0, filter1, filter2, filter3; - __m128i out0, out1, out2, out3; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride + src_stride2; - int32_t src_stride4 = src_stride2 << 1; - uint8_t *src_tmp0 = (uint8_t *)src - src_stride3; - - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - - src0 = __lsx_vld(src_tmp0, 0); - DUP2_ARG2(__lsx_vldx, src_tmp0, src_stride, src_tmp0, src_stride2, src1, - src2); - src3 = __lsx_vldx(src_tmp0, src_stride3); - src_tmp0 += src_stride4; - src4 = __lsx_vld(src_tmp0, 0); - DUP2_ARG2(__lsx_vldx, src_tmp0, src_stride, src_tmp0, src_stride2, src5, - src6); - src_tmp0 += src_stride3; - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - DUP2_ARG2(__lsx_vxori_b, src4, 128, src5, 128, src4, src5); - src6 = __lsx_vxori_b(src6, 128); - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src3, src2, src5, src4, src2, src1, reg0, - reg1, reg2, reg3); - DUP2_ARG2(__lsx_vilvl_b, src4, src3, src6, src5, reg4, reg5); - - for (; loop_cnt--;) { - src7 = __lsx_vld(src_tmp0, 0); - DUP2_ARG2(__lsx_vldx, src_tmp0, src_stride, src_tmp0, src_stride2, src8, - src9); - src10 = __lsx_vldx(src_tmp0, src_stride3); - src_tmp0 += src_stride4; - src0 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - src1 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - src2 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - src3 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - DUP2_ARG2(__lsx_vilvl_d, src1, src0, src3, src2, src0, src1); - DUP4_ARG2(__lsx_vxori_b, src7, 128, src8, 128, src9, 128, src10, 128, src7, - src8, src9, src10); - DUP4_ARG2(__lsx_vilvl_b, src7, src6, src8, src7, src9, src8, src10, src9, - tmp0, tmp1, tmp2, tmp3); - out0 = filt_8tap_dpadd_s_h(reg0, reg1, reg2, tmp0, filter0, filter1, - filter2, filter3); - out1 = filt_8tap_dpadd_s_h(reg3, reg4, reg5, tmp1, filter0, filter1, - filter2, filter3); - out2 = filt_8tap_dpadd_s_h(reg1, reg2, tmp0, tmp2, filter0, filter1, - filter2, filter3); - out3 = filt_8tap_dpadd_s_h(reg4, reg5, tmp1, tmp3, filter0, filter1, - filter2, filter3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, 7, out3, out2, 7, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - DUP2_ARG2(__lsx_vavgr_bu, out0, src0, out1, src1, out0, out1); - __lsx_vstelm_d(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(out1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(out1, dst, 0, 1); - dst += dst_stride; - reg0 = reg2; - reg1 = tmp0; - reg2 = tmp2; - reg3 = reg5; - reg4 = tmp1; - reg5 = tmp3; - src6 = src10; - } -} - -static void common_vt_8t_and_aver_dst_16w_mult_lsx( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height, int32_t width) { - uint8_t *src_tmp; - uint32_t cnt = width >> 4; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - __m128i filter0, filter1, filter2, filter3; - __m128i reg0, reg1, reg2, reg3, reg4, reg5; - __m128i reg6, reg7, reg8, reg9, reg10, reg11; - __m128i tmp0, tmp1, tmp2, tmp3; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride + src_stride2; - int32_t src_stride4 = src_stride2 << 1; - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - int32_t dst_stride4 = dst_stride2 << 1; - uint8_t *src_tmp0 = (uint8_t *)src - src_stride3; - - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - for (; cnt--;) { - uint32_t loop_cnt = height >> 2; - uint8_t *dst_reg = dst; - - src_tmp = src_tmp0; - src0 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src1, - src2); - src3 = __lsx_vldx(src_tmp, src_stride3); - src_tmp += src_stride4; - src4 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src5, - src6); - src_tmp += src_stride3; - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - DUP2_ARG2(__lsx_vxori_b, src4, 128, src5, 128, src4, src5); - src6 = __lsx_vxori_b(src6, 128); - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src3, src2, src5, src4, src2, src1, - reg0, reg1, reg2, reg3); - DUP2_ARG2(__lsx_vilvl_b, src4, src3, src6, src5, reg4, reg5); - DUP4_ARG2(__lsx_vilvh_b, src1, src0, src3, src2, src5, src4, src2, src1, - reg6, reg7, reg8, reg9); - DUP2_ARG2(__lsx_vilvh_b, src4, src3, src6, src5, reg10, reg11); - for (; loop_cnt--;) { - src7 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src8, - src9); - src10 = __lsx_vldx(src_tmp, src_stride3); - src_tmp += src_stride4; - DUP4_ARG2(__lsx_vxori_b, src7, 128, src8, 128, src9, 128, src10, 128, - src7, src8, src9, src10); - DUP4_ARG2(__lsx_vilvl_b, src7, src6, src8, src7, src9, src8, src10, src9, - src0, src1, src2, src3); - DUP4_ARG2(__lsx_vilvh_b, src7, src6, src8, src7, src9, src8, src10, src9, - src4, src5, src7, src8); - tmp0 = filt_8tap_dpadd_s_h(reg0, reg1, reg2, src0, filter0, filter1, - filter2, filter3); - tmp1 = filt_8tap_dpadd_s_h(reg3, reg4, reg5, src1, filter0, filter1, - filter2, filter3); - tmp2 = filt_8tap_dpadd_s_h(reg6, reg7, reg8, src4, filter0, filter1, - filter2, filter3); - tmp3 = filt_8tap_dpadd_s_h(reg9, reg10, reg11, src5, filter0, filter1, - filter2, filter3); - DUP2_ARG3(__lsx_vssrarni_b_h, tmp2, tmp0, 7, tmp3, tmp1, 7, tmp0, tmp1); - DUP2_ARG2(__lsx_vxori_b, tmp0, 128, tmp1, 128, tmp0, tmp1); - tmp2 = __lsx_vld(dst_reg, 0); - tmp3 = __lsx_vldx(dst_reg, dst_stride); - DUP2_ARG2(__lsx_vavgr_bu, tmp0, tmp2, tmp1, tmp3, tmp0, tmp1); - __lsx_vst(tmp0, dst_reg, 0); - __lsx_vstx(tmp1, dst_reg, dst_stride); - tmp0 = filt_8tap_dpadd_s_h(reg1, reg2, src0, src2, filter0, filter1, - filter2, filter3); - tmp1 = filt_8tap_dpadd_s_h(reg4, reg5, src1, src3, filter0, filter1, - filter2, filter3); - tmp2 = filt_8tap_dpadd_s_h(reg7, reg8, src4, src7, filter0, filter1, - filter2, filter3); - tmp3 = filt_8tap_dpadd_s_h(reg10, reg11, src5, src8, filter0, filter1, - filter2, filter3); - DUP2_ARG3(__lsx_vssrarni_b_h, tmp2, tmp0, 7, tmp3, tmp1, 7, tmp0, tmp1); - DUP2_ARG2(__lsx_vxori_b, tmp0, 128, tmp1, 128, tmp0, tmp1); - tmp2 = __lsx_vldx(dst_reg, dst_stride2); - tmp3 = __lsx_vldx(dst_reg, dst_stride3); - DUP2_ARG2(__lsx_vavgr_bu, tmp0, tmp2, tmp1, tmp3, tmp0, tmp1); - __lsx_vstx(tmp0, dst_reg, dst_stride2); - __lsx_vstx(tmp1, dst_reg, dst_stride3); - dst_reg += dst_stride4; - - reg0 = reg2; - reg1 = src0; - reg2 = src2; - reg3 = reg5; - reg4 = src1; - reg5 = src3; - reg6 = reg8; - reg7 = src4; - reg8 = src7; - reg9 = reg11; - reg10 = src5; - reg11 = src8; - src6 = src10; - } - src_tmp0 += 16; - dst += 16; - } -} - -static void common_vt_8t_and_aver_dst_16w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - const int8_t *filter, - int32_t height) { - common_vt_8t_and_aver_dst_16w_mult_lsx(src, src_stride, dst, dst_stride, - filter, height, 16); -} - -static void common_vt_8t_and_aver_dst_32w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - const int8_t *filter, - int32_t height) { - common_vt_8t_and_aver_dst_16w_mult_lsx(src, src_stride, dst, dst_stride, - filter, height, 32); -} - -static void common_vt_8t_and_aver_dst_64w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - const int8_t *filter, - int32_t height) { - common_vt_8t_and_aver_dst_16w_mult_lsx(src, src_stride, dst, dst_stride, - filter, height, 64); -} - -static void common_vt_2t_and_aver_dst_4x4_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter) { - __m128i src0, src1, src2, src3, src4; - __m128i dst0, dst1, dst2, dst3, out, filt0, src2110, src4332; - __m128i src10_r, src32_r, src21_r, src43_r; - __m128i tmp0, tmp1; - uint8_t *dst_tmp = dst; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - filt0 = __lsx_vldrepl_h(filter, 0); - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - src += src_stride4; - src4 = __lsx_vld(src, 0); - src += src_stride; - - dst0 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst1 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_w(dst_tmp, 0); - dst0 = __lsx_vilvl_w(dst1, dst0); - dst1 = __lsx_vilvl_w(dst3, dst2); - dst0 = __lsx_vilvl_d(dst1, dst0); - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, src3, src2, src4, src3, - src10_r, src21_r, src32_r, src43_r); - DUP2_ARG2(__lsx_vilvl_d, src21_r, src10_r, src43_r, src32_r, src2110, - src4332); - DUP2_ARG2(__lsx_vdp2_h_bu, src2110, filt0, src4332, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - out = __lsx_vavgr_bu(tmp0, dst0); - __lsx_vstelm_w(out, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(out, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(out, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(out, dst, 0, 3); - dst += dst_stride; -} - -static void common_vt_2t_and_aver_dst_4x8_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter) { - __m128i dst0, dst1, dst2, dst3, dst4; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, src87_r; - __m128i src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; - __m128i src2110, src4332, src6554, src8776, filt0; - __m128i tmp0, tmp1, tmp2, tmp3; - uint8_t *dst_tmp = dst; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - filt0 = __lsx_vldrepl_h(filter, 0); - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - src += src_stride4; - src4 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src5, src6); - src7 = __lsx_vldx(src, src_stride3); - src += src_stride4; - src8 = __lsx_vld(src, 0); - - dst0 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst1 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst0 = __lsx_vilvl_w(dst1, dst0); - dst1 = __lsx_vilvl_w(dst3, dst2); - dst0 = __lsx_vilvl_d(dst1, dst0); - - dst1 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_w(dst_tmp, 0); - dst_tmp += dst_stride; - dst4 = __lsx_vldrepl_w(dst_tmp, 0); - dst1 = __lsx_vilvl_w(dst2, dst1); - dst2 = __lsx_vilvl_w(dst4, dst3); - dst1 = __lsx_vilvl_d(dst2, dst1); - - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, src3, src2, src4, src3, - src10_r, src21_r, src32_r, src43_r); - DUP4_ARG2(__lsx_vilvl_b, src5, src4, src6, src5, src7, src6, src8, src7, - src54_r, src65_r, src76_r, src87_r); - DUP4_ARG2(__lsx_vilvl_d, src21_r, src10_r, src43_r, src32_r, src65_r, src54_r, - src87_r, src76_r, src2110, src4332, src6554, src8776); - DUP4_ARG2(__lsx_vdp2_h_bu, src2110, filt0, src4332, filt0, src6554, filt0, - src8776, filt0, tmp0, tmp1, tmp2, tmp3); - DUP2_ARG3(__lsx_vssrarni_bu_h, tmp1, tmp0, FILTER_BITS, tmp3, tmp2, - FILTER_BITS, tmp0, tmp2); - DUP2_ARG2(__lsx_vavgr_bu, tmp0, dst0, tmp2, dst1, tmp0, tmp2); - __lsx_vstelm_w(tmp0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(tmp0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(tmp0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(tmp0, dst, 0, 3); - dst += dst_stride; - - __lsx_vstelm_w(tmp2, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(tmp2, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(tmp2, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(tmp2, dst, 0, 3); -} - -static void common_vt_2t_and_aver_dst_4w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int8_t *filter, - int32_t height) { - if (height == 4) { - common_vt_2t_and_aver_dst_4x4_lsx(src, src_stride, dst, dst_stride, filter); - } else if (height == 8) { - common_vt_2t_and_aver_dst_4x8_lsx(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_vt_2t_and_aver_dst_8x4_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter) { - __m128i src0, src1, src2, src3, src4; - __m128i dst0, dst1, dst2, dst3, vec0, vec1, vec2, vec3, filt0; - __m128i tmp0, tmp1, tmp2, tmp3; - uint8_t *dst_tmp = dst; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - filt0 = __lsx_vldrepl_h(filter, 0); - src0 = __lsx_vld(src, 0); - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src1, src2, src3, src4); - dst0 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst1 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - DUP2_ARG2(__lsx_vilvl_d, dst1, dst0, dst3, dst2, dst0, dst1); - DUP2_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, vec0, vec1); - DUP2_ARG2(__lsx_vilvl_b, src3, src2, src4, src3, vec2, vec3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, filt0, - tmp0, tmp1, tmp2, tmp3); - DUP2_ARG3(__lsx_vssrarni_bu_h, tmp1, tmp0, FILTER_BITS, tmp3, tmp2, - FILTER_BITS, tmp0, tmp2); - DUP2_ARG2(__lsx_vavgr_bu, tmp0, dst0, tmp2, dst1, tmp0, tmp2); - __lsx_vstelm_d(tmp0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(tmp0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(tmp2, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(tmp2, dst, 0, 1); -} - -static void common_vt_2t_and_aver_dst_8x8mult_lsx( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = (height >> 3); - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8; - __m128i dst0, dst1, dst2, dst3, dst4, dst5; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, filt0; - __m128i tmp0, tmp1, tmp2, tmp3; - uint8_t *dst_tmp = dst; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - filt0 = __lsx_vldrepl_h(filter, 0); - src0 = __lsx_vld(src, 0); - src += src_stride; - - for (; loop_cnt--;) { - src1 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src2, src3); - src4 = __lsx_vldx(src, src_stride3); - src += src_stride4; - src5 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src6, src7); - src8 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - dst0 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst1 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst2 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - DUP2_ARG2(__lsx_vilvl_d, dst1, dst0, dst3, dst2, dst0, dst1); - - dst2 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst3 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst4 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - dst5 = __lsx_vldrepl_d(dst_tmp, 0); - dst_tmp += dst_stride; - DUP2_ARG2(__lsx_vilvl_d, dst3, dst2, dst5, dst4, dst2, dst3); - - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, src3, src2, src4, src3, - vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vilvl_b, src5, src4, src6, src5, src7, src6, src8, src7, - vec4, vec5, vec6, vec7); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, - filt0, tmp0, tmp1, tmp2, tmp3); - - DUP2_ARG3(__lsx_vssrarni_bu_h, tmp1, tmp0, FILTER_BITS, tmp3, tmp2, - FILTER_BITS, tmp0, tmp2); - DUP2_ARG2(__lsx_vavgr_bu, tmp0, dst0, tmp2, dst1, tmp0, tmp2); - __lsx_vstelm_d(tmp0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(tmp0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(tmp2, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(tmp2, dst, 0, 1); - dst += dst_stride; - - DUP4_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, vec6, filt0, vec7, - filt0, tmp0, tmp1, tmp2, tmp3); - DUP2_ARG3(__lsx_vssrarni_bu_h, tmp1, tmp0, FILTER_BITS, tmp3, tmp2, - FILTER_BITS, tmp0, tmp2); - DUP2_ARG2(__lsx_vavgr_bu, tmp0, dst2, tmp2, dst3, tmp0, tmp2); - __lsx_vstelm_d(tmp0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(tmp0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(tmp2, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(tmp2, dst, 0, 1); - dst += dst_stride; - - src0 = src8; - } -} - -static void common_vt_2t_and_aver_dst_8w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int8_t *filter, - int32_t height) { - if (height == 4) { - common_vt_2t_and_aver_dst_8x4_lsx(src, src_stride, dst, dst_stride, filter); - } else { - common_vt_2t_and_aver_dst_8x8mult_lsx(src, src_stride, dst, dst_stride, - filter, height); - } -} - -static void common_vt_2t_and_aver_dst_16w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = (height >> 2); - __m128i src0, src1, src2, src3, src4, dst0, dst1, dst2, dst3, filt0; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - __m128i tmp0, tmp1; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - - filt0 = __lsx_vldrepl_h(filter, 0); - src0 = __lsx_vld(src, 0); - src += src_stride; - - for (; loop_cnt--;) { - src1 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src2, src3); - src4 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - dst0 = __lsx_vld(dst, 0); - DUP2_ARG2(__lsx_vldx, dst, dst_stride, dst, dst_stride2, dst1, dst2); - dst3 = __lsx_vldx(dst, dst_stride3); - - DUP2_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, vec0, vec2); - DUP2_ARG2(__lsx_vilvh_b, src1, src0, src2, src1, vec1, vec3); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst0); - __lsx_vst(tmp0, dst, 0); - dst += dst_stride; - - DUP2_ARG2(__lsx_vilvl_b, src3, src2, src4, src3, vec4, vec6); - DUP2_ARG2(__lsx_vilvh_b, src3, src2, src4, src3, vec5, vec7); - DUP2_ARG2(__lsx_vdp2_h_bu, vec2, filt0, vec3, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst1); - __lsx_vst(tmp0, dst, 0); - dst += dst_stride; - - DUP2_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst2); - __lsx_vst(tmp0, dst, 0); - dst += dst_stride; - - DUP2_ARG2(__lsx_vdp2_h_bu, vec6, filt0, vec7, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst3); - __lsx_vst(tmp0, dst, 0); - dst += dst_stride; - - src0 = src4; - } -} - -static void common_vt_2t_and_aver_dst_32w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = (height >> 2); - uint8_t *src_tmp1; - uint8_t *dst_tmp1; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, src9; - __m128i dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, filt0; - __m128i tmp0, tmp1; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - - filt0 = __lsx_vldrepl_h(filter, 0); - DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src5); - src += src_stride; - - for (; loop_cnt--;) { - src1 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src2, src3); - src4 = __lsx_vldx(src, src_stride3); - - dst0 = __lsx_vld(dst, 0); - DUP2_ARG2(__lsx_vldx, dst, dst_stride, dst, dst_stride2, dst1, dst2); - dst3 = __lsx_vldx(dst, dst_stride3); - - DUP2_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, vec0, vec2); - DUP2_ARG2(__lsx_vilvh_b, src1, src0, src2, src1, vec1, vec3); - - src_tmp1 = src + 16; - src6 = __lsx_vld(src_tmp1, 0); - DUP2_ARG2(__lsx_vldx, src_tmp1, src_stride, src_tmp1, src_stride2, src7, - src8); - src9 = __lsx_vldx(src_tmp1, src_stride3); - - dst_tmp1 = dst + 16; - dst4 = __lsx_vld(dst_tmp1, 0); - DUP2_ARG2(__lsx_vldx, dst_tmp1, dst_stride, dst_tmp1, dst_stride2, dst5, - dst6); - dst7 = __lsx_vldx(dst_tmp1, dst_stride3); - src += src_stride4; - - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst0); - __lsx_vst(tmp0, dst, 0); - - DUP2_ARG2(__lsx_vdp2_h_bu, vec2, filt0, vec3, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst1); - __lsx_vstx(tmp0, dst, dst_stride); - - DUP2_ARG2(__lsx_vilvl_b, src3, src2, src4, src3, vec4, vec6); - DUP2_ARG2(__lsx_vilvh_b, src3, src2, src4, src3, vec5, vec7); - DUP2_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst2); - __lsx_vstx(tmp0, dst, dst_stride2); - - DUP2_ARG2(__lsx_vdp2_h_bu, vec6, filt0, vec7, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst3); - __lsx_vstx(tmp0, dst, dst_stride3); - - DUP2_ARG2(__lsx_vilvl_b, src6, src5, src7, src6, vec0, vec2); - DUP2_ARG2(__lsx_vilvh_b, src6, src5, src7, src6, vec1, vec3); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst4); - __lsx_vst(tmp0, dst, 16); - - DUP2_ARG2(__lsx_vdp2_h_bu, vec2, filt0, vec3, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst5); - dst += dst_stride; - __lsx_vst(tmp0, dst, 16); - - DUP2_ARG2(__lsx_vilvl_b, src8, src7, src9, src8, vec4, vec6); - DUP2_ARG2(__lsx_vilvh_b, src8, src7, src9, src8, vec5, vec7); - DUP2_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst6); - dst += dst_stride; - __lsx_vst(tmp0, dst, 16); - - DUP2_ARG2(__lsx_vdp2_h_bu, vec6, filt0, vec7, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst7); - dst += dst_stride; - __lsx_vst(tmp0, dst, 16); - dst += dst_stride; - - src0 = src4; - src5 = src9; - } -} - -static void common_vt_2t_and_aver_dst_64w_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = (height >> 1); - int32_t src_stride2 = src_stride << 1; - int32_t dst_stride2 = dst_stride << 1; - uint8_t *src_tmp1; - uint8_t *dst_tmp1; - __m128i src0, src1, src2, src3, src4, src5; - __m128i src6, src7, src8, src9, src10, src11, filt0; - __m128i dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - __m128i tmp0, tmp1; - - filt0 = __lsx_vldrepl_h(filter, 0); - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src0, src3, src6, - src9); - src += src_stride; - - for (; loop_cnt--;) { - src2 = __lsx_vldx(src, src_stride); - dst1 = __lsx_vldx(dst, dst_stride); - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src1, src4, src7, - src10); - DUP4_ARG2(__lsx_vld, dst, 0, dst, 16, dst, 32, dst, 48, dst0, dst2, dst4, - dst6); - src_tmp1 = (uint8_t *)src + 16; - src5 = __lsx_vldx(src_tmp1, src_stride); - src_tmp1 = src_tmp1 + 16; - src8 = __lsx_vldx(src_tmp1, src_stride); - src_tmp1 = src_tmp1 + 16; - src11 = __lsx_vldx(src_tmp1, src_stride); - - dst_tmp1 = dst + 16; - dst3 = __lsx_vldx(dst_tmp1, dst_stride); - dst_tmp1 = dst + 32; - dst5 = __lsx_vldx(dst_tmp1, dst_stride); - dst_tmp1 = dst + 48; - dst7 = __lsx_vldx(dst_tmp1, dst_stride); - src += src_stride2; - - DUP2_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, vec0, vec2); - DUP2_ARG2(__lsx_vilvh_b, src1, src0, src2, src1, vec1, vec3); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst0); - __lsx_vst(tmp0, dst, 0); - - DUP2_ARG2(__lsx_vdp2_h_bu, vec2, filt0, vec3, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst1); - __lsx_vstx(tmp0, dst, dst_stride); - - DUP2_ARG2(__lsx_vilvl_b, src4, src3, src5, src4, vec4, vec6); - DUP2_ARG2(__lsx_vilvh_b, src4, src3, src5, src4, vec5, vec7); - DUP2_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst2); - __lsx_vst(tmp0, dst, 16); - - dst_tmp1 = dst + 16; - DUP2_ARG2(__lsx_vdp2_h_bu, vec6, filt0, vec7, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst3); - __lsx_vstx(tmp0, dst_tmp1, dst_stride); - - DUP2_ARG2(__lsx_vilvl_b, src7, src6, src8, src7, vec0, vec2); - DUP2_ARG2(__lsx_vilvh_b, src7, src6, src8, src7, vec1, vec3); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst4); - __lsx_vst(tmp0, dst, 32); - - dst_tmp1 = dst_tmp1 + 16; - DUP2_ARG2(__lsx_vdp2_h_bu, vec2, filt0, vec3, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst5); - __lsx_vstx(tmp0, dst_tmp1, dst_stride); - - DUP2_ARG2(__lsx_vilvl_b, src10, src9, src11, src10, vec4, vec6); - DUP2_ARG2(__lsx_vilvh_b, src10, src9, src11, src10, vec5, vec7); - DUP2_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst6); - __lsx_vst(tmp0, dst, 48); - - dst_tmp1 = dst_tmp1 + 16; - DUP2_ARG2(__lsx_vdp2_h_bu, vec6, filt0, vec7, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - tmp0 = __lsx_vavgr_bu(tmp0, dst7); - __lsx_vstx(tmp0, dst_tmp1, dst_stride); - dst += dst_stride2; - - src0 = src2; - src3 = src5; - src6 = src8; - src9 = src11; - } -} - -void vpx_convolve8_avg_vert_lsx(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - const int16_t *const filter_y = filter[y0_q4]; - int8_t cnt, filt_ver[8]; - - assert(y_step_q4 == 16); - assert(((const int32_t *)filter_y)[1] != 0x800000); - - for (cnt = 0; cnt < 8; ++cnt) { - filt_ver[cnt] = filter_y[cnt]; - } - - if (vpx_get_filter_taps(filter_y) == 2) { - switch (w) { - case 4: - common_vt_2t_and_aver_dst_4w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_ver[3], h); - break; - case 8: - common_vt_2t_and_aver_dst_8w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_ver[3], h); - break; - case 16: - common_vt_2t_and_aver_dst_16w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_ver[3], h); - break; - case 32: - common_vt_2t_and_aver_dst_32w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_ver[3], h); - break; - case 64: - common_vt_2t_and_aver_dst_64w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_ver[3], h); - break; - default: - vpx_convolve8_avg_vert_c(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } else { - switch (w) { - case 4: - common_vt_8t_and_aver_dst_4w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_ver, h); - break; - case 8: - common_vt_8t_and_aver_dst_8w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_ver, h); - break; - case 16: - common_vt_8t_and_aver_dst_16w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_ver, h); - - break; - case 32: - common_vt_8t_and_aver_dst_32w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_ver, h); - break; - case 64: - common_vt_8t_and_aver_dst_64w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_ver, h); - break; - default: - vpx_convolve8_avg_vert_c(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_horiz_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_horiz_lsx.c deleted file mode 100644 index 2c6459a9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_horiz_lsx.c +++ /dev/null @@ -1,814 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/loongarch/vpx_convolve_lsx.h" - -static const uint8_t mc_filt_mask_arr[16 * 3] = { - /* 8 width cases */ - 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, - /* 4 width cases */ - 0, 1, 1, 2, 2, 3, 3, 4, 16, 17, 17, 18, 18, 19, 19, 20, - /* 4 width cases */ - 8, 9, 9, 10, 10, 11, 11, 12, 24, 25, 25, 26, 26, 27, 27, 28 -}; - -static void common_hz_8t_4x4_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int8_t *filter) { - __m128i src0, src1, src2, src3; - __m128i filter0, filter1, filter2, filter3; - __m128i mask0, mask1, mask2, mask3; - __m128i out, out0, out1; - - mask0 = __lsx_vld(mc_filt_mask_arr, 16); - src -= 3; - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - mask3 = __lsx_vaddi_bu(mask0, 6); - - LSX_LD_4(src, src_stride, src0, src1, src2, src3); - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, - filter0, filter1, filter2, filter3, out0, out1); - out = __lsx_vssrarni_b_h(out1, out0, 7); - out = __lsx_vxori_b(out, 128); - __lsx_vstelm_w(out, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(out, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(out, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(out, dst, 0, 3); -} - -static void common_hz_8t_4x8_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int8_t *filter) { - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride + src_stride2; - int32_t src_stride4 = src_stride2 << 1; - __m128i src0, src1, src2, src3; - __m128i filter0, filter1, filter2, filter3; - __m128i mask0, mask1, mask2, mask3; - __m128i out0, out1, out2, out3; - uint8_t *_src = (uint8_t *)src - 3; - - mask0 = __lsx_vld(mc_filt_mask_arr, 16); - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - mask3 = __lsx_vaddi_bu(mask0, 6); - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - - src0 = __lsx_vld(_src, 0); - DUP2_ARG2(__lsx_vldx, _src, src_stride, _src, src_stride2, src1, src2); - src3 = __lsx_vldx(_src, src_stride3); - _src += src_stride4; - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, - filter0, filter1, filter2, filter3, out0, out1); - src0 = __lsx_vld(_src, 0); - DUP2_ARG2(__lsx_vldx, _src, src_stride, _src, src_stride2, src1, src2); - src3 = __lsx_vldx(_src, src_stride3); - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, - filter0, filter1, filter2, filter3, out2, out3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, 7, out3, out2, 7, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - - __lsx_vstelm_w(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 3); - dst += dst_stride; - __lsx_vstelm_w(out1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(out1, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(out1, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(out1, dst, 0, 3); -} - -static void common_hz_8t_4w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - if (height == 4) { - common_hz_8t_4x4_lsx(src, src_stride, dst, dst_stride, filter); - } else if (height == 8) { - common_hz_8t_4x8_lsx(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_hz_8t_8x4_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int8_t *filter) { - __m128i src0, src1, src2, src3; - __m128i filter0, filter1, filter2, filter3; - __m128i mask0, mask1, mask2, mask3; - __m128i out0, out1, out2, out3; - - mask0 = __lsx_vld(mc_filt_mask_arr, 0); - src -= 3; - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - mask3 = __lsx_vaddi_bu(mask0, 6); - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - - LSX_LD_4(src, src_stride, src0, src1, src2, src3); - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, - filter0, filter1, filter2, filter3, out0, out1, - out2, out3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, 7, out3, out2, 7, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - __lsx_vstelm_d(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(out1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(out1, dst, 0, 1); -} - -static void common_hz_8t_8x8mult_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt = height >> 2; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride + src_stride2; - int32_t src_stride4 = src_stride2 << 1; - __m128i src0, src1, src2, src3; - __m128i filter0, filter1, filter2, filter3; - __m128i mask0, mask1, mask2, mask3; - __m128i out0, out1, out2, out3; - uint8_t *_src = (uint8_t *)src - 3; - - mask0 = __lsx_vld(mc_filt_mask_arr, 0); - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - mask3 = __lsx_vaddi_bu(mask0, 6); - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - - for (; loop_cnt--;) { - src0 = __lsx_vld(_src, 0); - DUP2_ARG2(__lsx_vldx, _src, src_stride, _src, src_stride2, src1, src2); - src3 = __lsx_vldx(_src, src_stride3); - _src += src_stride4; - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filter0, filter1, filter2, filter3, out0, - out1, out2, out3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, 7, out3, out2, 7, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - __lsx_vstelm_d(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(out1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(out1, dst, 0, 1); - dst += dst_stride; - } -} - -static void common_hz_8t_8w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - if (height == 4) { - common_hz_8t_8x4_lsx(src, src_stride, dst, dst_stride, filter); - } else { - common_hz_8t_8x8mult_lsx(src, src_stride, dst, dst_stride, filter, height); - } -} - -static void common_hz_8t_16w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt = height >> 1; - int32_t stride = src_stride << 1; - __m128i src0, src1, src2, src3; - __m128i filter0, filter1, filter2, filter3; - __m128i mask0, mask1, mask2, mask3; - __m128i out0, out1, out2, out3; - - mask0 = __lsx_vld(mc_filt_mask_arr, 0); - src -= 3; - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - mask3 = __lsx_vaddi_bu(mask0, 6); - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - - for (; loop_cnt--;) { - const uint8_t *_src = src + src_stride; - DUP2_ARG2(__lsx_vld, src, 0, _src, 0, src0, src2); - DUP2_ARG2(__lsx_vld, src, 8, _src, 8, src1, src3); - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filter0, filter1, filter2, filter3, out0, - out1, out2, out3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, 7, out3, out2, 7, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - __lsx_vst(out0, dst, 0); - dst += dst_stride; - __lsx_vst(out1, dst, 0); - dst += dst_stride; - src += stride; - } -} - -static void common_hz_8t_32w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - uint32_t loop_cnt = height >> 1; - __m128i src0, src1, src2, src3; - __m128i filter0, filter1, filter2, filter3; - __m128i mask0, mask1, mask2, mask3; - __m128i out0, out1, out2, out3; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - - mask0 = __lsx_vld(mc_filt_mask_arr, 0); - src -= 3; - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - mask3 = __lsx_vaddi_bu(mask0, 6); - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - - for (; loop_cnt--;) { - DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src2); - src3 = __lsx_vld(src, 24); - src1 = __lsx_vshuf_b(src2, src0, shuff); - src += src_stride; - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filter0, filter1, filter2, filter3, out0, - out1, out2, out3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, 7, out3, out2, 7, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - __lsx_vst(out0, dst, 0); - __lsx_vst(out1, dst, 16); - - DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src2); - src3 = __lsx_vld(src, 24); - src1 = __lsx_vshuf_b(src2, src0, shuff); - src += src_stride; - - dst += dst_stride; - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filter0, filter1, filter2, filter3, out0, - out1, out2, out3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, 7, out3, out2, 7, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - __lsx_vst(out0, dst, 0); - __lsx_vst(out1, dst, 16); - dst += dst_stride; - } -} - -static void common_hz_8t_64w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int8_t *filter, int32_t height) { - int32_t loop_cnt = height; - __m128i src0, src1, src2, src3; - __m128i filter0, filter1, filter2, filter3; - __m128i mask0, mask1, mask2, mask3; - __m128i out0, out1, out2, out3; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - - mask0 = __lsx_vld(mc_filt_mask_arr, 0); - src -= 3; - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - mask3 = __lsx_vaddi_bu(mask0, 6); - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - - for (; loop_cnt--;) { - DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src2); - src3 = __lsx_vld(src, 24); - src1 = __lsx_vshuf_b(src2, src0, shuff); - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filter0, filter1, filter2, filter3, out0, - out1, out2, out3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, 7, out3, out2, 7, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - __lsx_vst(out0, dst, 0); - __lsx_vst(out1, dst, 16); - - DUP2_ARG2(__lsx_vld, src, 32, src, 48, src0, src2); - src3 = __lsx_vld(src, 56); - src1 = __lsx_vshuf_b(src2, src0, shuff); - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filter0, filter1, filter2, filter3, out0, - out1, out2, out3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, 7, out3, out2, 7, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - __lsx_vst(out0, dst, 32); - __lsx_vst(out1, dst, 48); - src += src_stride; - dst += dst_stride; - } -} - -static void common_hz_2t_4x4_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter) { - __m128i src0, src1, src2, src3, mask; - __m128i filt0, vec0, vec1, vec2, vec3, res0, res1; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride + src_stride2; - - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride + dst_stride2; - - mask = __lsx_vld(mc_filt_mask_arr, 16); - /* rearranging filter */ - filt0 = __lsx_vldrepl_h(filter, 0); - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - DUP2_ARG3(__lsx_vshuf_b, src1, src0, mask, src3, src2, mask, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, vec3); - DUP2_ARG3(__lsx_vssrarni_bu_h, vec2, vec2, FILTER_BITS, vec3, vec3, - FILTER_BITS, res0, res1); - - __lsx_vstelm_w(res0, dst, 0, 0); - __lsx_vstelm_w(res0, dst + dst_stride, 0, 1); - __lsx_vstelm_w(res1, dst + dst_stride2, 0, 0); - __lsx_vstelm_w(res1, dst + dst_stride3, 0, 1); -} - -static void common_hz_2t_4x8_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter) { - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, mask; - __m128i res0, res1, res2, res3, filt0; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride + src_stride2; - int32_t src_stride4 = src_stride2 << 1; - - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride + dst_stride2; - - uint8_t *src_tmp1 = src + src_stride4; - - mask = __lsx_vld(mc_filt_mask_arr, 16); - - /* rearranging filter */ - filt0 = __lsx_vldrepl_h(filter, 0); - - src0 = __lsx_vld(src, 0); - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src1, src2, src3, src4); - DUP2_ARG2(__lsx_vldx, src_tmp1, src_stride, src_tmp1, src_stride2, src5, - src6); - src7 = __lsx_vldx(src_tmp1, src_stride3); - - DUP4_ARG3(__lsx_vshuf_b, src1, src0, mask, src3, src2, mask, src5, src4, mask, - src7, src6, mask, vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, filt0, - vec4, vec5, vec6, vec7); - DUP4_ARG3(__lsx_vssrarni_bu_h, vec4, vec4, FILTER_BITS, vec5, vec5, - FILTER_BITS, vec6, vec6, FILTER_BITS, vec7, vec7, FILTER_BITS, res0, - res1, res2, res3); - - __lsx_vstelm_w(res0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(res0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(res1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(res1, dst, 0, 1); - dst += dst_stride; - - __lsx_vstelm_w(res2, dst, 0, 0); - __lsx_vstelm_w(res2, dst + dst_stride, 0, 1); - __lsx_vstelm_w(res3, dst + dst_stride2, 0, 0); - __lsx_vstelm_w(res3, dst + dst_stride3, 0, 1); -} - -static void common_hz_2t_4w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - if (height == 4) { - common_hz_2t_4x4_lsx(src, src_stride, dst, dst_stride, filter); - } else if (height == 8) { - common_hz_2t_4x8_lsx(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_hz_2t_8x4_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter) { - __m128i filt0, mask; - __m128i src0, src1, src2, src3; - __m128i vec0, vec1, vec2, vec3; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - - mask = __lsx_vld(mc_filt_mask_arr, 0); - - /* rearranging filter */ - filt0 = __lsx_vldrepl_h(filter, 0); - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - - DUP4_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, src2, src2, mask, - src3, src3, mask, vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, filt0, - vec0, vec1, vec2, vec3); - DUP2_ARG3(__lsx_vssrarni_bu_h, vec1, vec0, FILTER_BITS, vec3, vec2, - FILTER_BITS, vec0, vec1); - - __lsx_vstelm_d(vec0, dst, 0, 0); - __lsx_vstelm_d(vec0, dst + dst_stride, 0, 1); - __lsx_vstelm_d(vec1, dst + dst_stride2, 0, 0); - __lsx_vstelm_d(vec1, dst + dst_stride3, 0, 1); -} - -static void common_hz_2t_8x8mult_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - __m128i filt0, mask; - __m128i src0, src1, src2, src3, out0, out1; - __m128i vec0, vec1, vec2, vec3; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - int32_t dst_stride4 = dst_stride2 << 1; - - mask = __lsx_vld(mc_filt_mask_arr, 0); - - /* rearranging filter */ - filt0 = __lsx_vldrepl_h(filter, 0); - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - DUP4_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, src2, src2, mask, - src3, src3, mask, vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, filt0, - vec0, vec1, vec2, vec3); - DUP2_ARG3(__lsx_vssrarni_bu_h, vec1, vec0, FILTER_BITS, vec3, vec2, - FILTER_BITS, out0, out1); - - __lsx_vstelm_d(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(out1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(out1, dst, 0, 1); - dst += dst_stride; - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - DUP4_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, src2, src2, mask, - src3, src3, mask, vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, filt0, - vec0, vec1, vec2, vec3); - DUP2_ARG3(__lsx_vssrarni_bu_h, vec1, vec0, FILTER_BITS, vec3, vec2, - FILTER_BITS, out0, out1); - - __lsx_vstelm_d(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(out1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(out1, dst, 0, 1); - dst += dst_stride; - - if (height == 16) { - uint8_t *dst_tmp1 = dst + dst_stride4; - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - DUP4_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, src2, src2, - mask, src3, src3, mask, vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, - filt0, vec0, vec1, vec2, vec3); - DUP2_ARG3(__lsx_vssrarni_bu_h, vec1, vec0, FILTER_BITS, vec3, vec2, - FILTER_BITS, out0, out1); - - __lsx_vstelm_d(out0, dst, 0, 0); - __lsx_vstelm_d(out0, dst + dst_stride, 0, 1); - __lsx_vstelm_d(out1, dst + dst_stride2, 0, 0); - __lsx_vstelm_d(out1, dst + dst_stride3, 0, 1); - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - DUP4_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, src2, src2, - mask, src3, src3, mask, vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, - filt0, vec0, vec1, vec2, vec3); - DUP2_ARG3(__lsx_vssrarni_bu_h, vec1, vec0, FILTER_BITS, vec3, vec2, - FILTER_BITS, out0, out1); - - __lsx_vstelm_d(out0, dst_tmp1, 0, 0); - __lsx_vstelm_d(out0, dst_tmp1 + dst_stride, 0, 1); - __lsx_vstelm_d(out1, dst_tmp1 + dst_stride2, 0, 0); - __lsx_vstelm_d(out1, dst_tmp1 + dst_stride3, 0, 1); - } -} - -static void common_hz_2t_8w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - if (height == 4) { - common_hz_2t_8x4_lsx(src, src_stride, dst, dst_stride, filter); - } else { - common_hz_2t_8x8mult_lsx(src, src_stride, dst, dst_stride, filter, height); - } -} - -static void common_hz_2t_16w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = (height >> 2) - 1; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, mask; - __m128i filt0, vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - __m128i out0, out1, out2, out3, out4, out5, out6, out7; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - uint8_t *src_tmp1 = src + 8; - mask = __lsx_vld(mc_filt_mask_arr, 0); - filt0 = __lsx_vldrepl_h(filter, 0); - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src2, src4); - src6 = __lsx_vldx(src, src_stride3); - src1 = __lsx_vld(src_tmp1, 0); - DUP2_ARG2(__lsx_vldx, src_tmp1, src_stride, src_tmp1, src_stride2, src3, - src5); - src7 = __lsx_vldx(src_tmp1, src_stride3); - src += src_stride4; - - DUP4_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, src2, src2, mask, - src3, src3, mask, vec0, vec1, vec2, vec3); - DUP4_ARG3(__lsx_vshuf_b, src4, src4, mask, src5, src5, mask, src6, src6, mask, - src7, src7, mask, vec4, vec5, vec6, vec7); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, filt0, - out0, out1, out2, out3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, vec6, filt0, vec7, filt0, - out4, out5, out6, out7); - DUP4_ARG3(__lsx_vssrarni_bu_h, out1, out0, FILTER_BITS, out3, out2, - FILTER_BITS, out5, out4, FILTER_BITS, out7, out6, FILTER_BITS, out0, - out1, out2, out3); - - __lsx_vst(out0, dst, 0); - dst += dst_stride; - __lsx_vst(out1, dst, 0); - dst += dst_stride; - __lsx_vst(out2, dst, 0); - dst += dst_stride; - __lsx_vst(out3, dst, 0); - dst += dst_stride; - - for (; loop_cnt--;) { - src_tmp1 += src_stride4; - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src2, src4); - src6 = __lsx_vldx(src, src_stride3); - - src1 = __lsx_vld(src_tmp1, 0); - DUP2_ARG2(__lsx_vldx, src_tmp1, src_stride, src_tmp1, src_stride2, src3, - src5); - src7 = __lsx_vldx(src_tmp1, src_stride3); - src += src_stride4; - - DUP4_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, src2, src2, - mask, src3, src3, mask, vec0, vec1, vec2, vec3); - DUP4_ARG3(__lsx_vshuf_b, src4, src4, mask, src5, src5, mask, src6, src6, - mask, src7, src7, mask, vec4, vec5, vec6, vec7); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, - filt0, out0, out1, out2, out3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, vec6, filt0, vec7, - filt0, out4, out5, out6, out7); - DUP4_ARG3(__lsx_vssrarni_bu_h, out1, out0, FILTER_BITS, out3, out2, - FILTER_BITS, out5, out4, FILTER_BITS, out7, out6, FILTER_BITS, - out0, out1, out2, out3); - - __lsx_vst(out0, dst, 0); - dst += dst_stride; - __lsx_vst(out1, dst, 0); - dst += dst_stride; - __lsx_vst(out2, dst, 0); - dst += dst_stride; - __lsx_vst(out3, dst, 0); - dst += dst_stride; - } -} - -static void common_hz_2t_32w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = (height >> 1); - __m128i src0, src1, src2, src3, src4, src5, src6, src7, mask; - __m128i filt0, vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - __m128i out0, out1, out2, out3, out4, out5, out6, out7; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - - mask = __lsx_vld(mc_filt_mask_arr, 0); - /* rearranging filter */ - filt0 = __lsx_vldrepl_h(filter, 0); - - for (; loop_cnt--;) { - DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src2); - src3 = __lsx_vld(src, 24); - src1 = __lsx_vshuf_b(src2, src0, shuff); - src += src_stride; - DUP2_ARG2(__lsx_vld, src, 0, src, 16, src4, src6); - src7 = __lsx_vld(src, 24); - src5 = __lsx_vshuf_b(src6, src4, shuff); - src += src_stride; - - DUP4_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, src2, src2, - mask, src3, src3, mask, vec0, vec1, vec2, vec3); - DUP4_ARG3(__lsx_vshuf_b, src4, src4, mask, src5, src5, mask, src6, src6, - mask, src7, src7, mask, vec4, vec5, vec6, vec7); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, - filt0, out0, out1, out2, out3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, vec6, filt0, vec7, - filt0, out4, out5, out6, out7); - DUP4_ARG3(__lsx_vssrarni_bu_h, out1, out0, FILTER_BITS, out3, out2, - FILTER_BITS, out5, out4, FILTER_BITS, out7, out6, FILTER_BITS, - out0, out1, out2, out3); - - __lsx_vst(out0, dst, 0); - __lsx_vst(out1, dst, 16); - dst += dst_stride; - - __lsx_vst(out2, dst, 0); - __lsx_vst(out3, dst, 16); - dst += dst_stride; - } -} - -static void common_hz_2t_64w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = height; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, mask; - __m128i filt0, vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - __m128i out0, out1, out2, out3, out4, out5, out6, out7; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - - mask = __lsx_vld(mc_filt_mask_arr, 0); - - /* rearranging filter */ - filt0 = __lsx_vldrepl_h(filter, 0); - - for (; loop_cnt--;) { - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src0, src2, src4, - src6); - src7 = __lsx_vld(src, 56); - DUP2_ARG3(__lsx_vshuf_b, src2, src0, shuff, src4, src2, shuff, src1, src3); - src5 = __lsx_vshuf_b(src6, src4, shuff); - src += src_stride; - - DUP4_ARG3(__lsx_vshuf_b, src0, src0, mask, src1, src1, mask, src2, src2, - mask, src3, src3, mask, vec0, vec1, vec2, vec3); - DUP4_ARG3(__lsx_vshuf_b, src4, src4, mask, src5, src5, mask, src6, src6, - mask, src7, src7, mask, vec4, vec5, vec6, vec7); - - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, - filt0, out0, out1, out2, out3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, vec6, filt0, vec7, - filt0, out4, out5, out6, out7); - DUP4_ARG3(__lsx_vssrarni_bu_h, out1, out0, FILTER_BITS, out3, out2, - FILTER_BITS, out5, out4, FILTER_BITS, out7, out6, FILTER_BITS, - out0, out1, out2, out3); - - __lsx_vst(out0, dst, 0); - __lsx_vst(out1, dst, 16); - __lsx_vst(out2, dst, 32); - __lsx_vst(out3, dst, 48); - dst += dst_stride; - } -} - -void vpx_convolve8_horiz_lsx(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - const int16_t *const filter_x = filter[x0_q4]; - int8_t cnt, filt_hor[8]; - - assert(x_step_q4 == 16); - assert(((const int32_t *)filter_x)[1] != 0x800000); - - for (cnt = 0; cnt < 8; ++cnt) { - filt_hor[cnt] = filter_x[cnt]; - } - if (vpx_get_filter_taps(filter_x) == 2) { - switch (w) { - case 4: - common_hz_2t_4w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_hor[3], h); - break; - case 8: - common_hz_2t_8w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_hor[3], h); - break; - case 16: - common_hz_2t_16w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_hor[3], h); - break; - case 32: - common_hz_2t_32w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_hor[3], h); - break; - case 64: - common_hz_2t_64w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_hor[3], h); - break; - default: - vpx_convolve8_horiz_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } else { - switch (w) { - case 4: - common_hz_8t_4w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_hor, h); - break; - case 8: - common_hz_8t_8w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_hor, h); - break; - - case 16: - common_hz_8t_16w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_hor, h); - break; - - case 32: - common_hz_8t_32w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_hor, h); - break; - - case 64: - common_hz_8t_64w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_hor, h); - break; - default: - vpx_convolve8_horiz_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_lsx.c deleted file mode 100644 index 9f5cd6cf..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_lsx.c +++ /dev/null @@ -1,697 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/loongarch/vpx_convolve_lsx.h" - -static const uint8_t mc_filt_mask_arr[16 * 3] = { - /* 8 width cases */ - 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, - /* 4 width cases */ - 0, 1, 1, 2, 2, 3, 3, 4, 16, 17, 17, 18, 18, 19, 19, 20, - /* 4 width cases */ - 8, 9, 9, 10, 10, 11, 11, 12, 24, 25, 25, 26, 26, 27, 27, 28 -}; - -static void common_hv_8ht_8vt_4w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt = (height >> 2); - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - __m128i filt_hz0, filt_hz1, filt_hz2, filt_hz3; - __m128i filt_vt0, filt_vt1, filt_vt2, filt_vt3; - __m128i mask0, mask1, mask2, mask3; - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; - __m128i out0, out1; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - - mask0 = __lsx_vld(mc_filt_mask_arr, 16); - src -= (3 + 3 * src_stride); - DUP4_ARG2(__lsx_vldrepl_h, filter_horiz, 0, filter_horiz, 2, filter_horiz, 4, - filter_horiz, 6, filt_hz0, filt_hz1, filt_hz2, filt_hz3); - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - mask3 = __lsx_vaddi_bu(mask0, 6); - - LSX_LD_4(src, src_stride, src0, src1, src2, src3); - src += src_stride; - src4 = __lsx_vld(src, 0); - src += src_stride; - src5 = __lsx_vld(src, 0); - src += src_stride; - src6 = __lsx_vld(src, 0); - src += src_stride; - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - DUP2_ARG2(__lsx_vxori_b, src4, 128, src5, 128, src4, src5); - src6 = __lsx_vxori_b(src6, 128); - - tmp0 = horiz_8tap_filt(src0, src1, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - tmp2 = horiz_8tap_filt(src2, src3, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - tmp4 = horiz_8tap_filt(src4, src5, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - tmp5 = horiz_8tap_filt(src5, src6, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - DUP2_ARG3(__lsx_vshuf_b, tmp2, tmp0, shuff, tmp4, tmp2, shuff, tmp1, tmp3); - DUP4_ARG2(__lsx_vldrepl_h, filter_vert, 0, filter_vert, 2, filter_vert, 4, - filter_vert, 6, filt_vt0, filt_vt1, filt_vt2, filt_vt3); - DUP2_ARG2(__lsx_vpackev_b, tmp1, tmp0, tmp3, tmp2, tmp0, tmp1); - tmp2 = __lsx_vpackev_b(tmp5, tmp4); - - for (; loop_cnt--;) { - LSX_LD_4(src, src_stride, src7, src8, src9, src10); - src += src_stride; - DUP4_ARG2(__lsx_vxori_b, src7, 128, src8, 128, src9, 128, src10, 128, src7, - src8, src9, src10); - tmp3 = horiz_8tap_filt(src7, src8, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - tmp4 = __lsx_vshuf_b(tmp3, tmp5, shuff); - tmp4 = __lsx_vpackev_b(tmp3, tmp4); - out0 = filt_8tap_dpadd_s_h(tmp0, tmp1, tmp2, tmp4, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - src1 = horiz_8tap_filt(src9, src10, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src0 = __lsx_vshuf_b(src1, tmp3, shuff); - src0 = __lsx_vpackev_b(src1, src0); - out1 = filt_8tap_dpadd_s_h(tmp1, tmp2, tmp4, src0, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - out0 = __lsx_vssrarni_b_h(out1, out0, 7); - out0 = __lsx_vxori_b(out0, 128); - __lsx_vstelm_w(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 3); - dst += dst_stride; - - tmp5 = src1; - tmp0 = tmp2; - tmp1 = tmp4; - tmp2 = src0; - } -} - -static void common_hv_8ht_8vt_8w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt = (height >> 2); - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - __m128i filt_hz0, filt_hz1, filt_hz2, filt_hz3; - __m128i filt_vt0, filt_vt1, filt_vt2, filt_vt3; - __m128i mask0, mask1, mask2, mask3; - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6; - __m128i out0, out1; - - mask0 = __lsx_vld(mc_filt_mask_arr, 0); - src -= (3 + 3 * src_stride); - DUP4_ARG2(__lsx_vldrepl_h, filter_horiz, 0, filter_horiz, 2, filter_horiz, 4, - filter_horiz, 6, filt_hz0, filt_hz1, filt_hz2, filt_hz3); - DUP2_ARG2(__lsx_vaddi_bu, mask0, 2, mask0, 4, mask1, mask2); - mask3 = __lsx_vaddi_bu(mask0, 6); - - LSX_LD_4(src, src_stride, src0, src1, src2, src3); - src += src_stride; - src4 = __lsx_vld(src, 0); - src += src_stride; - src5 = __lsx_vld(src, 0); - src += src_stride; - src6 = __lsx_vld(src, 0); - src += src_stride; - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - DUP2_ARG2(__lsx_vxori_b, src4, 128, src5, 128, src4, src5); - src6 = __lsx_vxori_b(src6, 128); - - src0 = horiz_8tap_filt(src0, src0, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src1 = horiz_8tap_filt(src1, src1, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src2 = horiz_8tap_filt(src2, src2, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src3 = horiz_8tap_filt(src3, src3, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src4 = horiz_8tap_filt(src4, src4, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src5 = horiz_8tap_filt(src5, src5, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src6 = horiz_8tap_filt(src6, src6, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - - DUP4_ARG2(__lsx_vldrepl_h, filter_vert, 0, filter_vert, 2, filter_vert, 4, - filter_vert, 6, filt_vt0, filt_vt1, filt_vt2, filt_vt3); - DUP4_ARG2(__lsx_vpackev_b, src1, src0, src3, src2, src5, src4, src2, src1, - tmp0, tmp1, tmp2, tmp4); - DUP2_ARG2(__lsx_vpackev_b, src4, src3, src6, src5, tmp5, tmp6); - - for (; loop_cnt--;) { - LSX_LD_4(src, src_stride, src7, src8, src9, src10); - src += src_stride; - DUP4_ARG2(__lsx_vxori_b, src7, 128, src8, 128, src9, 128, src10, 128, src7, - src8, src9, src10); - src7 = horiz_8tap_filt(src7, src7, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - tmp3 = __lsx_vpackev_b(src7, src6); - out0 = filt_8tap_dpadd_s_h(tmp0, tmp1, tmp2, tmp3, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - src8 = horiz_8tap_filt(src8, src8, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src0 = __lsx_vpackev_b(src8, src7); - out1 = filt_8tap_dpadd_s_h(tmp4, tmp5, tmp6, src0, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - src9 = horiz_8tap_filt(src9, src9, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src1 = __lsx_vpackev_b(src9, src8); - src3 = filt_8tap_dpadd_s_h(tmp1, tmp2, tmp3, src1, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - src10 = horiz_8tap_filt(src10, src10, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - src2 = __lsx_vpackev_b(src10, src9); - src4 = filt_8tap_dpadd_s_h(tmp5, tmp6, src0, src2, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, 7, src4, src3, 7, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - __lsx_vstelm_d(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(out1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(out1, dst, 0, 1); - dst += dst_stride; - - src6 = src10; - tmp0 = tmp2; - tmp1 = tmp3; - tmp2 = src1; - tmp4 = tmp6; - tmp5 = src0; - tmp6 = src2; - } -} - -static void common_hv_8ht_8vt_16w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - common_hv_8ht_8vt_8w_lsx(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - src += 8; - dst += 8; - - common_hv_8ht_8vt_8w_lsx(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - src += 8; - dst += 8; -} - -static void common_hv_8ht_8vt_32w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 4; multiple8_cnt--;) { - common_hv_8ht_8vt_8w_lsx(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - src += 8; - dst += 8; - } -} - -static void common_hv_8ht_8vt_64w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 8; multiple8_cnt--;) { - common_hv_8ht_8vt_8w_lsx(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - src += 8; - dst += 8; - } -} - -static void common_hv_2ht_2vt_4x4_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, - int8_t *filter_vert) { - __m128i src0, src1, src2, src3, src4, mask; - __m128i filt_vt, filt_hz, vec0, vec1; - __m128i hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, tmp0, tmp1; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride + src_stride2; - int32_t src_stride4 = src_stride2 << 1; - - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - mask = __lsx_vld(mc_filt_mask_arr, 16); - - /* rearranging filter */ - filt_hz = __lsx_vldrepl_h(filter_horiz, 0); - filt_vt = __lsx_vldrepl_h(filter_vert, 0); - - src0 = __lsx_vld(src, 0); - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src1, src2, src3, src4); - hz_out0 = horiz_2tap_filt_uh(src0, src1, mask, filt_hz); - hz_out2 = horiz_2tap_filt_uh(src2, src3, mask, filt_hz); - hz_out4 = horiz_2tap_filt_uh(src4, src4, mask, filt_hz); - - hz_out1 = __lsx_vshuf_b(hz_out2, hz_out0, shuff); - hz_out3 = __lsx_vpickod_d(hz_out4, hz_out2); - - DUP2_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp0, tmp1); - DUP2_ARG3(__lsx_vssrarni_bu_h, tmp0, tmp0, FILTER_BITS, tmp1, tmp1, - FILTER_BITS, tmp0, tmp1); - - __lsx_vstelm_w(tmp0, dst, 0, 0); - __lsx_vstelm_w(tmp0, dst + dst_stride, 0, 1); - __lsx_vstelm_w(tmp1, dst + dst_stride2, 0, 0); - __lsx_vstelm_w(tmp1, dst + dst_stride3, 0, 1); -} - -static void common_hv_2ht_2vt_4x8_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, - int8_t *filter_vert) { - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, mask; - __m128i filt_hz, filt_vt, vec0, vec1, vec2, vec3; - __m128i hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; - __m128i hz_out7, hz_out8, vec4, vec5, vec6, vec7; - __m128i shuff = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - int32_t dst_stride4 = dst_stride2 << 1; - - mask = __lsx_vld(mc_filt_mask_arr, 16); - - /* rearranging filter */ - DUP2_ARG2(__lsx_vldrepl_h, filter_horiz, 0, filter_vert, 0, filt_hz, filt_vt); - - src0 = __lsx_vld(src, 0); - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src1, src2, src3, src4); - src += src_stride4; - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src5, src6, src7, src8); - src += src_stride4; - - hz_out0 = horiz_2tap_filt_uh(src0, src1, mask, filt_hz); - hz_out2 = horiz_2tap_filt_uh(src2, src3, mask, filt_hz); - hz_out4 = horiz_2tap_filt_uh(src4, src5, mask, filt_hz); - hz_out6 = horiz_2tap_filt_uh(src6, src7, mask, filt_hz); - hz_out8 = horiz_2tap_filt_uh(src8, src8, mask, filt_hz); - - DUP2_ARG3(__lsx_vshuf_b, hz_out2, hz_out0, shuff, hz_out4, hz_out2, shuff, - hz_out1, hz_out3); - hz_out5 = __lsx_vshuf_b(hz_out6, hz_out4, shuff); - hz_out7 = __lsx_vpickod_d(hz_out8, hz_out6); - DUP4_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out3, hz_out2, hz_out5, - hz_out4, hz_out7, hz_out6, vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, vec2, filt_vt, vec3, - filt_vt, vec4, vec5, vec6, vec7); - DUP4_ARG3(__lsx_vssrarni_bu_h, vec4, vec4, FILTER_BITS, vec5, vec5, - FILTER_BITS, vec6, vec6, FILTER_BITS, vec7, vec7, FILTER_BITS, vec4, - vec5, vec6, vec7); - - __lsx_vstelm_w(vec4, dst, 0, 0); - __lsx_vstelm_w(vec4, dst + dst_stride, 0, 1); - __lsx_vstelm_w(vec5, dst + dst_stride2, 0, 0); - __lsx_vstelm_w(vec5, dst + dst_stride3, 0, 1); - dst += dst_stride4; - __lsx_vstelm_w(vec6, dst, 0, 0); - __lsx_vstelm_w(vec6, dst + dst_stride, 0, 1); - __lsx_vstelm_w(vec7, dst + dst_stride2, 0, 0); - __lsx_vstelm_w(vec7, dst + dst_stride3, 0, 1); -} - -static void common_hv_2ht_2vt_4w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - if (height == 4) { - common_hv_2ht_2vt_4x4_lsx(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert); - } else if (height == 8) { - common_hv_2ht_2vt_4x8_lsx(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert); - } -} - -static void common_hv_2ht_2vt_8x4_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, - int8_t *filter_vert) { - __m128i src0, src1, src2, src3, src4, mask; - __m128i filt_hz, filt_vt, vec0, vec1, vec2, vec3; - __m128i hz_out0, hz_out1, tmp0, tmp1, tmp2, tmp3; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - - mask = __lsx_vld(mc_filt_mask_arr, 0); - - /* rearranging filter */ - DUP2_ARG2(__lsx_vldrepl_h, filter_horiz, 0, filter_vert, 0, filt_hz, filt_vt); - - src0 = __lsx_vld(src, 0); - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src1, src2, src3, src4); - - hz_out0 = horiz_2tap_filt_uh(src0, src0, mask, filt_hz); - hz_out1 = horiz_2tap_filt_uh(src1, src1, mask, filt_hz); - vec0 = __lsx_vpackev_b(hz_out1, hz_out0); - tmp0 = __lsx_vdp2_h_bu(vec0, filt_vt); - - hz_out0 = horiz_2tap_filt_uh(src2, src2, mask, filt_hz); - vec1 = __lsx_vpackev_b(hz_out0, hz_out1); - tmp1 = __lsx_vdp2_h_bu(vec1, filt_vt); - - hz_out1 = horiz_2tap_filt_uh(src3, src3, mask, filt_hz); - vec2 = __lsx_vpackev_b(hz_out1, hz_out0); - tmp2 = __lsx_vdp2_h_bu(vec2, filt_vt); - - hz_out0 = horiz_2tap_filt_uh(src4, src4, mask, filt_hz); - vec3 = __lsx_vpackev_b(hz_out0, hz_out1); - tmp3 = __lsx_vdp2_h_bu(vec3, filt_vt); - - DUP2_ARG3(__lsx_vssrarni_bu_h, tmp1, tmp0, FILTER_BITS, tmp3, tmp2, - FILTER_BITS, tmp0, tmp1); - - __lsx_vstelm_d(tmp0, dst, 0, 0); - __lsx_vstelm_d(tmp0, dst + dst_stride, 0, 1); - __lsx_vstelm_d(tmp1, dst + dst_stride2, 0, 0); - __lsx_vstelm_d(tmp1, dst + dst_stride3, 0, 1); -} - -static void common_hv_2ht_2vt_8x8mult_lsx(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter_horiz, - int8_t *filter_vert, int32_t height) { - uint32_t loop_cnt = (height >> 3); - __m128i src0, src1, src2, src3, src4, mask; - __m128i filt_hz, filt_vt, vec0; - __m128i hz_out0, hz_out1, tmp1, tmp2, tmp3, tmp4; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - mask = __lsx_vld(mc_filt_mask_arr, 0); - - /* rearranging filter */ - DUP2_ARG2(__lsx_vldrepl_h, filter_horiz, 0, filter_vert, 0, filt_hz, filt_vt); - - src0 = __lsx_vld(src, 0); - src += src_stride; - - hz_out0 = horiz_2tap_filt_uh(src0, src0, mask, filt_hz); - - for (; loop_cnt--;) { - src1 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src2, src3); - src4 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - hz_out1 = horiz_2tap_filt_uh(src1, src1, mask, filt_hz); - vec0 = __lsx_vpackev_b(hz_out1, hz_out0); - tmp1 = __lsx_vdp2_h_bu(vec0, filt_vt); - - hz_out0 = horiz_2tap_filt_uh(src2, src2, mask, filt_hz); - vec0 = __lsx_vpackev_b(hz_out0, hz_out1); - tmp2 = __lsx_vdp2_h_bu(vec0, filt_vt); - - hz_out1 = horiz_2tap_filt_uh(src3, src3, mask, filt_hz); - vec0 = __lsx_vpackev_b(hz_out1, hz_out0); - tmp3 = __lsx_vdp2_h_bu(vec0, filt_vt); - - hz_out0 = horiz_2tap_filt_uh(src4, src4, mask, filt_hz); - src1 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src2, src3); - src4 = __lsx_vldx(src, src_stride3); - src += src_stride4; - vec0 = __lsx_vpackev_b(hz_out0, hz_out1); - tmp4 = __lsx_vdp2_h_bu(vec0, filt_vt); - - DUP2_ARG3(__lsx_vssrarni_bu_h, tmp2, tmp1, FILTER_BITS, tmp4, tmp3, - FILTER_BITS, tmp1, tmp2); - - __lsx_vstelm_d(tmp1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(tmp1, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(tmp2, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(tmp2, dst, 0, 1); - dst += dst_stride; - - hz_out1 = horiz_2tap_filt_uh(src1, src1, mask, filt_hz); - vec0 = __lsx_vpackev_b(hz_out1, hz_out0); - tmp1 = __lsx_vdp2_h_bu(vec0, filt_vt); - - hz_out0 = horiz_2tap_filt_uh(src2, src2, mask, filt_hz); - vec0 = __lsx_vpackev_b(hz_out0, hz_out1); - tmp2 = __lsx_vdp2_h_bu(vec0, filt_vt); - - hz_out1 = horiz_2tap_filt_uh(src3, src3, mask, filt_hz); - vec0 = __lsx_vpackev_b(hz_out1, hz_out0); - tmp3 = __lsx_vdp2_h_bu(vec0, filt_vt); - - hz_out0 = horiz_2tap_filt_uh(src4, src4, mask, filt_hz); - vec0 = __lsx_vpackev_b(hz_out0, hz_out1); - tmp4 = __lsx_vdp2_h_bu(vec0, filt_vt); - - DUP2_ARG3(__lsx_vssrarni_bu_h, tmp2, tmp1, FILTER_BITS, tmp4, tmp3, - FILTER_BITS, tmp1, tmp2); - - __lsx_vstelm_d(tmp1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(tmp1, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(tmp2, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(tmp2, dst, 0, 1); - dst += dst_stride; - } -} - -static void common_hv_2ht_2vt_8w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - if (height == 4) { - common_hv_2ht_2vt_8x4_lsx(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert); - } else { - common_hv_2ht_2vt_8x8mult_lsx(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height); - } -} - -static void common_hv_2ht_2vt_16w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt = (height >> 2); - __m128i src0, src1, src2, src3, src4, src5, src6, src7, mask; - __m128i filt_hz, filt_vt, vec0, vec1; - __m128i tmp, tmp1, tmp2, hz_out0, hz_out1, hz_out2, hz_out3; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - mask = __lsx_vld(mc_filt_mask_arr, 0); - - /* rearranging filter */ - DUP2_ARG2(__lsx_vldrepl_h, filter_horiz, 0, filter_vert, 0, filt_hz, filt_vt); - - DUP2_ARG2(__lsx_vld, src, 0, src, 8, src0, src1); - src += src_stride; - - hz_out0 = horiz_2tap_filt_uh(src0, src0, mask, filt_hz); - hz_out2 = horiz_2tap_filt_uh(src1, src1, mask, filt_hz); - - for (; loop_cnt--;) { - uint8_t *src_tmp0 = src + 8; - - DUP2_ARG2(__lsx_vld, src, 0, src_tmp0, 0, src0, src1); - DUP4_ARG2(__lsx_vldx, src, src_stride, src_tmp0, src_stride, src, - src_stride2, src_tmp0, src_stride2, src2, src3, src4, src5); - DUP2_ARG2(__lsx_vldx, src, src_stride3, src_tmp0, src_stride3, src6, src7); - src += src_stride4; - - hz_out1 = horiz_2tap_filt_uh(src0, src0, mask, filt_hz); - hz_out3 = horiz_2tap_filt_uh(src1, src1, mask, filt_hz); - DUP2_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp1, tmp2); - tmp = __lsx_vssrarni_bu_h(tmp2, tmp1, FILTER_BITS); - __lsx_vst(tmp, dst, 0); - dst += dst_stride; - - hz_out0 = horiz_2tap_filt_uh(src2, src2, mask, filt_hz); - hz_out2 = horiz_2tap_filt_uh(src3, src3, mask, filt_hz); - DUP2_ARG2(__lsx_vpackev_b, hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp1, tmp2); - tmp = __lsx_vssrarni_bu_h(tmp2, tmp1, FILTER_BITS); - __lsx_vst(tmp, dst, 0); - dst += dst_stride; - - hz_out1 = horiz_2tap_filt_uh(src4, src4, mask, filt_hz); - hz_out3 = horiz_2tap_filt_uh(src5, src5, mask, filt_hz); - DUP2_ARG2(__lsx_vpackev_b, hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp1, tmp2); - tmp = __lsx_vssrarni_bu_h(tmp2, tmp1, FILTER_BITS); - __lsx_vst(tmp, dst, 0); - dst += dst_stride; - - hz_out0 = horiz_2tap_filt_uh(src6, src6, mask, filt_hz); - hz_out2 = horiz_2tap_filt_uh(src7, src7, mask, filt_hz); - DUP2_ARG2(__lsx_vpackev_b, hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt_vt, vec1, filt_vt, tmp1, tmp2); - tmp = __lsx_vssrarni_bu_h(tmp2, tmp1, FILTER_BITS); - __lsx_vst(tmp, dst, 0); - dst += dst_stride; - } -} - -static void common_hv_2ht_2vt_32w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - common_hv_2ht_2vt_16w_lsx(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - src += 16; - dst += 16; - - common_hv_2ht_2vt_16w_lsx(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); -} - -static void common_hv_2ht_2vt_64w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 4; multiple8_cnt--;) { - common_hv_2ht_2vt_16w_lsx(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - src += 16; - dst += 16; - } -} - -void vpx_convolve8_lsx(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, - int x0_q4, int32_t x_step_q4, int y0_q4, - int32_t y_step_q4, int32_t w, int32_t h) { - const int16_t *const filter_x = filter[x0_q4]; - const int16_t *const filter_y = filter[y0_q4]; - int8_t cnt, filt_hor[8], filt_ver[8]; - - assert(x_step_q4 == 16); - assert(y_step_q4 == 16); - assert(((const int32_t *)filter_x)[1] != 0x800000); - assert(((const int32_t *)filter_y)[1] != 0x800000); - - for (cnt = 0; cnt < 8; ++cnt) { - filt_hor[cnt] = filter_x[cnt]; - filt_ver[cnt] = filter_y[cnt]; - } - - if (vpx_get_filter_taps(filter_x) == 2 && - vpx_get_filter_taps(filter_y) == 2) { - switch (w) { - case 4: - common_hv_2ht_2vt_4w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], - &filt_ver[3], (int32_t)h); - break; - case 8: - common_hv_2ht_2vt_8w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], - &filt_ver[3], (int32_t)h); - break; - case 16: - common_hv_2ht_2vt_16w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], - &filt_ver[3], (int32_t)h); - break; - case 32: - common_hv_2ht_2vt_32w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], - &filt_ver[3], (int32_t)h); - break; - case 64: - common_hv_2ht_2vt_64w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], - &filt_ver[3], (int32_t)h); - break; - default: - vpx_convolve8_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } else if (vpx_get_filter_taps(filter_x) == 2 || - vpx_get_filter_taps(filter_y) == 2) { - vpx_convolve8_c(src, src_stride, dst, dst_stride, filter, x0_q4, x_step_q4, - y0_q4, y_step_q4, w, h); - } else { - switch (w) { - case 4: - common_hv_8ht_8vt_4w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, filt_ver, - (int32_t)h); - break; - case 8: - common_hv_8ht_8vt_8w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, filt_ver, - (int32_t)h); - break; - case 16: - common_hv_8ht_8vt_16w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, filt_ver, - (int32_t)h); - break; - case 32: - common_hv_8ht_8vt_32w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, filt_ver, - (int32_t)h); - break; - case 64: - common_hv_8ht_8vt_64w_lsx(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, filt_ver, - (int32_t)h); - break; - default: - vpx_convolve8_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_vert_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_vert_lsx.c deleted file mode 100644 index 6022e43c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve8_vert_lsx.c +++ /dev/null @@ -1,825 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/loongarch/vpx_convolve_lsx.h" - -static void common_vt_8t_4w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = height >> 2; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride + src_stride2; - int32_t src_stride4 = src_stride2 << 1; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; - __m128i reg0, reg1, reg2, reg3, reg4; - __m128i filter0, filter1, filter2, filter3; - __m128i out0, out1; - uint8_t *_src = (uint8_t *)src - src_stride3; - - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - src0 = __lsx_vld(_src, 0); - DUP2_ARG2(__lsx_vldx, _src, src_stride, _src, src_stride2, src1, src2); - src3 = __lsx_vldx(_src, src_stride3); - _src += src_stride4; - src4 = __lsx_vld(_src, 0); - DUP2_ARG2(__lsx_vldx, _src, src_stride, _src, src_stride2, src5, src6); - _src += src_stride3; - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src3, src2, src5, src4, src2, src1, tmp0, - tmp1, tmp2, tmp3); - DUP2_ARG2(__lsx_vilvl_b, src4, src3, src6, src5, tmp4, tmp5); - DUP2_ARG2(__lsx_vilvl_d, tmp3, tmp0, tmp4, tmp1, reg0, reg1); - reg2 = __lsx_vilvl_d(tmp5, tmp2); - DUP2_ARG2(__lsx_vxori_b, reg0, 128, reg1, 128, reg0, reg1); - reg2 = __lsx_vxori_b(reg2, 128); - - for (; loop_cnt--;) { - src7 = __lsx_vld(_src, 0); - DUP2_ARG2(__lsx_vldx, _src, src_stride, _src, src_stride2, src8, src9); - src10 = __lsx_vldx(_src, src_stride3); - _src += src_stride4; - DUP4_ARG2(__lsx_vilvl_b, src7, src6, src8, src7, src9, src8, src10, src9, - tmp0, tmp1, tmp2, tmp3); - DUP2_ARG2(__lsx_vilvl_d, tmp1, tmp0, tmp3, tmp2, reg3, reg4); - DUP2_ARG2(__lsx_vxori_b, reg3, 128, reg4, 128, reg3, reg4); - out0 = filt_8tap_dpadd_s_h(reg0, reg1, reg2, reg3, filter0, filter1, - filter2, filter3); - out1 = filt_8tap_dpadd_s_h(reg1, reg2, reg3, reg4, filter0, filter1, - filter2, filter3); - out0 = __lsx_vssrarni_b_h(out1, out0, 7); - out0 = __lsx_vxori_b(out0, 128); - __lsx_vstelm_w(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 2); - dst += dst_stride; - __lsx_vstelm_w(out0, dst, 0, 3); - dst += dst_stride; - - reg0 = reg2; - reg1 = reg3; - reg2 = reg4; - src6 = src10; - } -} - -static void common_vt_8t_8w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = height >> 2; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - __m128i tmp0, tmp1, tmp2, tmp3; - __m128i reg0, reg1, reg2, reg3, reg4, reg5; - __m128i filter0, filter1, filter2, filter3; - __m128i out0, out1, out2, out3; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride + src_stride2; - int32_t src_stride4 = src_stride2 << 1; - src = src - src_stride3; - - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - src += src_stride4; - src4 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src5, src6); - src += src_stride3; - - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - DUP2_ARG2(__lsx_vxori_b, src4, 128, src5, 128, src4, src5); - src6 = __lsx_vxori_b(src6, 128); - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src3, src2, src5, src4, src2, src1, reg0, - reg1, reg2, reg3); - DUP2_ARG2(__lsx_vilvl_b, src4, src3, src6, src5, reg4, reg5); - - for (; loop_cnt--;) { - src7 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src8, src9); - src10 = __lsx_vldx(src, src_stride3); - src += src_stride4; - DUP4_ARG2(__lsx_vxori_b, src7, 128, src8, 128, src9, 128, src10, 128, src7, - src8, src9, src10); - DUP4_ARG2(__lsx_vilvl_b, src7, src6, src8, src7, src9, src8, src10, src9, - tmp0, tmp1, tmp2, tmp3); - out0 = filt_8tap_dpadd_s_h(reg0, reg1, reg2, tmp0, filter0, filter1, - filter2, filter3); - out1 = filt_8tap_dpadd_s_h(reg3, reg4, reg5, tmp1, filter0, filter1, - filter2, filter3); - out2 = filt_8tap_dpadd_s_h(reg1, reg2, tmp0, tmp2, filter0, filter1, - filter2, filter3); - out3 = filt_8tap_dpadd_s_h(reg4, reg5, tmp1, tmp3, filter0, filter1, - filter2, filter3); - DUP2_ARG3(__lsx_vssrarni_b_h, out1, out0, 7, out3, out2, 7, out0, out1); - DUP2_ARG2(__lsx_vxori_b, out0, 128, out1, 128, out0, out1); - __lsx_vstelm_d(out0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(out0, dst, 0, 1); - dst += dst_stride; - __lsx_vstelm_d(out1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(out1, dst, 0, 1); - dst += dst_stride; - - reg0 = reg2; - reg1 = tmp0; - reg2 = tmp2; - reg3 = reg5; - reg4 = tmp1; - reg5 = tmp3; - src6 = src10; - } -} - -static void common_vt_8t_16w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = height >> 2; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - __m128i filter0, filter1, filter2, filter3; - __m128i reg0, reg1, reg2, reg3, reg4, reg5; - __m128i reg6, reg7, reg8, reg9, reg10, reg11; - __m128i tmp0, tmp1, tmp2, tmp3; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride + src_stride2; - int32_t src_stride4 = src_stride2 << 1; - // uint8_t *_src = (uint8_t *)src - src_stride3; - src -= src_stride3; - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - - src0 = __lsx_vld(src, 0); - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src1, src2, src3, src4); - src += src_stride4; - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src5, src6); - src += src_stride3; - - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - DUP2_ARG2(__lsx_vxori_b, src4, 128, src5, 128, src4, src5); - src6 = __lsx_vxori_b(src6, 128); - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src3, src2, src5, src4, src2, src1, reg0, - reg1, reg2, reg3); - DUP2_ARG2(__lsx_vilvl_b, src4, src3, src6, src5, reg4, reg5); - DUP4_ARG2(__lsx_vilvh_b, src1, src0, src3, src2, src5, src4, src2, src1, reg6, - reg7, reg8, reg9); - DUP2_ARG2(__lsx_vilvh_b, src4, src3, src6, src5, reg10, reg11); - - for (; loop_cnt--;) { - src7 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src8, src9); - src10 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - DUP4_ARG2(__lsx_vxori_b, src7, 128, src8, 128, src9, 128, src10, 128, src7, - src8, src9, src10); - DUP4_ARG2(__lsx_vilvl_b, src7, src6, src8, src7, src9, src8, src10, src9, - src0, src1, src2, src3); - DUP4_ARG2(__lsx_vilvh_b, src7, src6, src8, src7, src9, src8, src10, src9, - src4, src5, src7, src8); - tmp0 = filt_8tap_dpadd_s_h(reg0, reg1, reg2, src0, filter0, filter1, - filter2, filter3); - tmp1 = filt_8tap_dpadd_s_h(reg3, reg4, reg5, src1, filter0, filter1, - filter2, filter3); - tmp2 = filt_8tap_dpadd_s_h(reg6, reg7, reg8, src4, filter0, filter1, - filter2, filter3); - tmp3 = filt_8tap_dpadd_s_h(reg9, reg10, reg11, src5, filter0, filter1, - filter2, filter3); - DUP2_ARG3(__lsx_vssrarni_b_h, tmp2, tmp0, 7, tmp3, tmp1, 7, tmp0, tmp1); - DUP2_ARG2(__lsx_vxori_b, tmp0, 128, tmp1, 128, tmp0, tmp1); - __lsx_vst(tmp0, dst, 0); - dst += dst_stride; - __lsx_vst(tmp1, dst, 0); - dst += dst_stride; - tmp0 = filt_8tap_dpadd_s_h(reg1, reg2, src0, src2, filter0, filter1, - filter2, filter3); - tmp1 = filt_8tap_dpadd_s_h(reg4, reg5, src1, src3, filter0, filter1, - filter2, filter3); - tmp2 = filt_8tap_dpadd_s_h(reg7, reg8, src4, src7, filter0, filter1, - filter2, filter3); - tmp3 = filt_8tap_dpadd_s_h(reg10, reg11, src5, src8, filter0, filter1, - filter2, filter3); - DUP2_ARG3(__lsx_vssrarni_b_h, tmp2, tmp0, 7, tmp3, tmp1, 7, tmp0, tmp1); - DUP2_ARG2(__lsx_vxori_b, tmp0, 128, tmp1, 128, tmp0, tmp1); - __lsx_vst(tmp0, dst, 0); - dst += dst_stride; - __lsx_vst(tmp1, dst, 0); - dst += dst_stride; - - reg0 = reg2; - reg1 = src0; - reg2 = src2; - reg3 = reg5; - reg4 = src1; - reg5 = src3; - reg6 = reg8; - reg7 = src4; - reg8 = src7; - reg9 = reg11; - reg10 = src5; - reg11 = src8; - src6 = src10; - } -} - -static void common_vt_8t_16w_mult_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height, - int32_t width) { - uint8_t *src_tmp; - uint8_t *dst_tmp; - uint32_t cnt = width >> 4; - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - __m128i filter0, filter1, filter2, filter3; - __m128i reg0, reg1, reg2, reg3, reg4, reg5; - __m128i reg6, reg7, reg8, reg9, reg10, reg11; - __m128i tmp0, tmp1, tmp2, tmp3; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride + src_stride2; - int32_t src_stride4 = src_stride2 << 1; - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - int32_t dst_stride4 = dst_stride2 << 1; - src -= src_stride3; - DUP4_ARG2(__lsx_vldrepl_h, filter, 0, filter, 2, filter, 4, filter, 6, - filter0, filter1, filter2, filter3); - - for (; cnt--;) { - uint32_t loop_cnt = height >> 2; - - src_tmp = src; - dst_tmp = dst; - - src0 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src1, - src2); - src3 = __lsx_vldx(src_tmp, src_stride3); - src_tmp += src_stride4; - src4 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src5, - src6); - src_tmp += src_stride3; - - DUP4_ARG2(__lsx_vxori_b, src0, 128, src1, 128, src2, 128, src3, 128, src0, - src1, src2, src3); - DUP2_ARG2(__lsx_vxori_b, src4, 128, src5, 128, src4, src5); - src6 = __lsx_vxori_b(src6, 128); - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src3, src2, src5, src4, src2, src1, - reg0, reg1, reg2, reg3); - DUP2_ARG2(__lsx_vilvl_b, src4, src3, src6, src5, reg4, reg5); - DUP4_ARG2(__lsx_vilvh_b, src1, src0, src3, src2, src5, src4, src2, src1, - reg6, reg7, reg8, reg9); - DUP2_ARG2(__lsx_vilvh_b, src4, src3, src6, src5, reg10, reg11); - - for (; loop_cnt--;) { - src7 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src8, - src9); - src10 = __lsx_vldx(src_tmp, src_stride3); - src_tmp += src_stride4; - DUP4_ARG2(__lsx_vxori_b, src7, 128, src8, 128, src9, 128, src10, 128, - src7, src8, src9, src10); - DUP4_ARG2(__lsx_vilvl_b, src7, src6, src8, src7, src9, src8, src10, src9, - src0, src1, src2, src3); - DUP4_ARG2(__lsx_vilvh_b, src7, src6, src8, src7, src9, src8, src10, src9, - src4, src5, src7, src8); - tmp0 = filt_8tap_dpadd_s_h(reg0, reg1, reg2, src0, filter0, filter1, - filter2, filter3); - tmp1 = filt_8tap_dpadd_s_h(reg3, reg4, reg5, src1, filter0, filter1, - filter2, filter3); - tmp2 = filt_8tap_dpadd_s_h(reg6, reg7, reg8, src4, filter0, filter1, - filter2, filter3); - tmp3 = filt_8tap_dpadd_s_h(reg9, reg10, reg11, src5, filter0, filter1, - filter2, filter3); - DUP2_ARG3(__lsx_vssrarni_b_h, tmp2, tmp0, 7, tmp3, tmp1, 7, tmp0, tmp1); - DUP2_ARG2(__lsx_vxori_b, tmp0, 128, tmp1, 128, tmp0, tmp1); - __lsx_vst(tmp0, dst_tmp, 0); - __lsx_vstx(tmp1, dst_tmp, dst_stride); - tmp0 = filt_8tap_dpadd_s_h(reg1, reg2, src0, src2, filter0, filter1, - filter2, filter3); - tmp1 = filt_8tap_dpadd_s_h(reg4, reg5, src1, src3, filter0, filter1, - filter2, filter3); - tmp2 = filt_8tap_dpadd_s_h(reg7, reg8, src4, src7, filter0, filter1, - filter2, filter3); - tmp3 = filt_8tap_dpadd_s_h(reg10, reg11, src5, src8, filter0, filter1, - filter2, filter3); - DUP2_ARG3(__lsx_vssrarni_b_h, tmp2, tmp0, 7, tmp3, tmp1, 7, tmp0, tmp1); - DUP2_ARG2(__lsx_vxori_b, tmp0, 128, tmp1, 128, tmp0, tmp1); - __lsx_vstx(tmp0, dst_tmp, dst_stride2); - __lsx_vstx(tmp1, dst_tmp, dst_stride3); - dst_tmp += dst_stride4; - - reg0 = reg2; - reg1 = src0; - reg2 = src2; - reg3 = reg5; - reg4 = src1; - reg5 = src3; - reg6 = reg8; - reg7 = src4; - reg8 = src7; - reg9 = reg11; - reg10 = src5; - reg11 = src8; - src6 = src10; - } - src += 16; - dst += 16; - } -} - -static void common_vt_8t_32w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - common_vt_8t_16w_mult_lsx(src, src_stride, dst, dst_stride, filter, height, - 32); -} - -static void common_vt_8t_64w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - common_vt_8t_16w_mult_lsx(src, src_stride, dst, dst_stride, filter, height, - 64); -} - -static void common_vt_2t_4x4_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter) { - __m128i src0, src1, src2, src3, src4; - __m128i vec0, vec1, vec2, vec3, vec4, vec5; - __m128i filt0, tmp0, tmp1; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - - filt0 = __lsx_vldrepl_h(filter, 0); - - src0 = __lsx_vld(src, 0); - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src1, src2, src3, src4); - src += (src_stride4 + src_stride); - - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, src3, src2, src4, src3, vec0, - vec1, vec2, vec3); - DUP2_ARG2(__lsx_vilvl_d, vec1, vec0, vec3, vec2, vec4, vec5); - DUP2_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, tmp0, tmp1); - tmp0 = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - - __lsx_vstelm_w(tmp0, dst, 0, 0); - __lsx_vstelm_w(tmp0, dst + dst_stride, 0, 1); - __lsx_vstelm_w(tmp0, dst + dst_stride2, 0, 2); - __lsx_vstelm_w(tmp0, dst + dst_stride3, 0, 3); -} - -static void common_vt_2t_4x8_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter) { - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8; - __m128i vec0, vec1, vec2, vec3, vec4, vec5; - __m128i vec6, vec7, vec8, vec9, vec10, vec11; - __m128i tmp0, tmp1, tmp2, tmp3; - __m128i filt0; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - int32_t dst_stride4 = dst_stride2 << 1; - uint8_t *dst_tmp1 = dst + dst_stride4; - - filt0 = __lsx_vldrepl_h(filter, 0); - src0 = __lsx_vld(src, 0); - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src1, src2, src3, src4); - src += src_stride4; - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src5, src6, src7, src8); - src += (src_stride4 + src_stride); - - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, src3, src2, src4, src3, vec0, - vec1, vec2, vec3); - DUP4_ARG2(__lsx_vilvl_b, src5, src4, src6, src5, src7, src6, src8, src7, vec4, - vec5, vec6, vec7); - DUP4_ARG2(__lsx_vilvl_d, vec1, vec0, vec3, vec2, vec5, vec4, vec7, vec6, vec8, - vec9, vec10, vec11); - - DUP4_ARG2(__lsx_vdp2_h_bu, vec8, filt0, vec9, filt0, vec10, filt0, vec11, - filt0, tmp0, tmp1, tmp2, tmp3); - DUP2_ARG3(__lsx_vssrarni_bu_h, tmp1, tmp0, FILTER_BITS, tmp3, tmp2, - FILTER_BITS, tmp0, tmp1); - - __lsx_vstelm_w(tmp0, dst, 0, 0); - __lsx_vstelm_w(tmp0, dst + dst_stride, 0, 1); - __lsx_vstelm_w(tmp0, dst + dst_stride2, 0, 2); - __lsx_vstelm_w(tmp0, dst + dst_stride3, 0, 3); - - __lsx_vstelm_w(tmp1, dst_tmp1, 0, 0); - __lsx_vstelm_w(tmp1, dst_tmp1 + dst_stride, 0, 1); - __lsx_vstelm_w(tmp1, dst_tmp1 + dst_stride2, 0, 2); - __lsx_vstelm_w(tmp1, dst_tmp1 + dst_stride3, 0, 3); -} - -static void common_vt_2t_4w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - if (height == 4) { - common_vt_2t_4x4_lsx(src, src_stride, dst, dst_stride, filter); - } else if (height == 8) { - common_vt_2t_4x8_lsx(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_vt_2t_8x4_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter) { - __m128i src0, src1, src2, src3, src4, vec0, vec1, vec2, vec3, filt0; - __m128i out0, out1, tmp0, tmp1, tmp2, tmp3; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - - filt0 = __lsx_vldrepl_h(filter, 0); - - src0 = __lsx_vld(src, 0); - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src1, src2, src3, src4); - - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, src3, src2, src4, src3, vec0, - vec1, vec2, vec3); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, filt0, - tmp0, tmp1, tmp2, tmp3); - DUP2_ARG3(__lsx_vssrarni_bu_h, tmp1, tmp0, FILTER_BITS, tmp3, tmp2, - FILTER_BITS, out0, out1); - - __lsx_vstelm_d(out0, dst, 0, 0); - __lsx_vstelm_d(out0, dst + dst_stride, 0, 1); - __lsx_vstelm_d(out1, dst + dst_stride2, 0, 0); - __lsx_vstelm_d(out1, dst + dst_stride3, 0, 1); -} - -static void common_vt_2t_8x8mult_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = (height >> 3); - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, filt0; - __m128i out0, out1, tmp0, tmp1, tmp2, tmp3; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - int32_t dst_stride4 = dst_stride2 << 1; - - filt0 = __lsx_vldrepl_h(filter, 0); - src0 = __lsx_vld(src, 0); - src += src_stride; - - for (; loop_cnt--;) { - src1 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src2, src3); - src4 = __lsx_vldx(src, src_stride3); - src += src_stride4; - src5 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src6, src7) - src8 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - DUP4_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, src3, src2, src4, src3, - vec0, vec1, vec2, vec3); - DUP4_ARG2(__lsx_vilvl_b, src5, src4, src6, src5, src7, src6, src8, src7, - vec4, vec5, vec6, vec7); - DUP4_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, vec2, filt0, vec3, - filt0, tmp0, tmp1, tmp2, tmp3); - DUP2_ARG3(__lsx_vssrarni_bu_h, tmp1, tmp0, FILTER_BITS, tmp3, tmp2, - FILTER_BITS, out0, out1); - - __lsx_vstelm_d(out0, dst, 0, 0); - __lsx_vstelm_d(out0, dst + dst_stride, 0, 1); - __lsx_vstelm_d(out1, dst + dst_stride2, 0, 0); - __lsx_vstelm_d(out1, dst + dst_stride3, 0, 1); - dst += dst_stride4; - - DUP4_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, vec6, filt0, vec7, - filt0, tmp0, tmp1, tmp2, tmp3); - DUP2_ARG3(__lsx_vssrarni_bu_h, tmp1, tmp0, FILTER_BITS, tmp3, tmp2, - FILTER_BITS, out0, out1); - - __lsx_vstelm_d(out0, dst, 0, 0); - __lsx_vstelm_d(out0, dst + dst_stride, 0, 1); - __lsx_vstelm_d(out1, dst + dst_stride2, 0, 0); - __lsx_vstelm_d(out1, dst + dst_stride3, 0, 1); - dst += dst_stride4; - - src0 = src8; - } -} - -static void common_vt_2t_8w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - if (height == 4) { - common_vt_2t_8x4_lsx(src, src_stride, dst, dst_stride, filter); - } else { - common_vt_2t_8x8mult_lsx(src, src_stride, dst, dst_stride, filter, height); - } -} - -static void common_vt_2t_16w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = (height >> 2); - __m128i src0, src1, src2, src3, src4, tmp, tmp0, tmp1; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, filt0; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - filt0 = __lsx_vldrepl_h(filter, 0); - - src0 = __lsx_vld(src, 0); - src += src_stride; - - for (; loop_cnt--;) { - src1 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src2, src3); - src4 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - DUP2_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, vec0, vec2); - DUP2_ARG2(__lsx_vilvh_b, src1, src0, src2, src1, vec1, vec3); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - __lsx_vst(tmp, dst, 0); - dst += dst_stride; - - DUP2_ARG2(__lsx_vilvl_b, src3, src2, src4, src3, vec4, vec6); - DUP2_ARG2(__lsx_vilvh_b, src3, src2, src4, src3, vec5, vec7); - DUP2_ARG2(__lsx_vdp2_h_bu, vec2, filt0, vec3, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - __lsx_vst(tmp, dst, 0); - dst += dst_stride; - - DUP2_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - __lsx_vst(tmp, dst, 0); - dst += dst_stride; - - DUP2_ARG2(__lsx_vdp2_h_bu, vec6, filt0, vec7, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - __lsx_vst(tmp, dst, 0); - dst += dst_stride; - - src0 = src4; - } -} - -static void common_vt_2t_32w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = (height >> 2); - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, src9; - __m128i vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, filt0; - __m128i tmp, tmp0, tmp1; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - uint8_t *src_tmp; - - filt0 = __lsx_vldrepl_h(filter, 0); - - DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src5); - src += src_stride; - src_tmp = src + 16; - - for (; loop_cnt--;) { - DUP2_ARG2(__lsx_vld, src, 0, src_tmp, 0, src1, src6); - DUP4_ARG2(__lsx_vldx, src, src_stride, src_tmp, src_stride, src, - src_stride2, src_tmp, src_stride2, src2, src7, src3, src8); - DUP2_ARG2(__lsx_vldx, src, src_stride3, src_tmp, src_stride3, src4, src9); - DUP2_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, vec0, vec2); - DUP2_ARG2(__lsx_vilvh_b, src1, src0, src2, src1, vec1, vec3); - src += src_stride4; - src_tmp += src_stride4; - - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - __lsx_vst(tmp, dst, 0); - - DUP2_ARG2(__lsx_vdp2_h_bu, vec2, filt0, vec3, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - __lsx_vstx(tmp, dst, dst_stride); - - DUP2_ARG2(__lsx_vilvl_b, src3, src2, src4, src3, vec4, vec6); - DUP2_ARG2(__lsx_vilvh_b, src3, src2, src4, src3, vec5, vec7); - DUP2_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - __lsx_vstx(tmp, dst, dst_stride2); - - DUP2_ARG2(__lsx_vdp2_h_bu, vec6, filt0, vec7, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - __lsx_vstx(tmp, dst, dst_stride3); - - DUP2_ARG2(__lsx_vilvl_b, src6, src5, src7, src6, vec0, vec2); - DUP2_ARG2(__lsx_vilvh_b, src6, src5, src7, src6, vec1, vec3); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - __lsx_vst(tmp, dst, 16); - - DUP2_ARG2(__lsx_vdp2_h_bu, vec2, filt0, vec3, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - dst += dst_stride; - __lsx_vst(tmp, dst, 16); - - DUP2_ARG2(__lsx_vilvl_b, src8, src7, src9, src8, vec4, vec6); - DUP2_ARG2(__lsx_vilvh_b, src8, src7, src9, src8, vec5, vec7); - DUP2_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - dst += dst_stride; - __lsx_vst(tmp, dst, 16); - - DUP2_ARG2(__lsx_vdp2_h_bu, vec6, filt0, vec7, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - dst += dst_stride; - __lsx_vst(tmp, dst, 16); - - dst += dst_stride; - - src0 = src4; - src5 = src9; - } -} - -static void common_vt_2t_64w_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt = (height >> 1); - __m128i src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - __m128i src11, vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, filt0; - __m128i tmp, tmp0, tmp1; - - int32_t src_stride2 = src_stride << 1; - int32_t dst_stride2 = dst_stride << 1; - uint8_t *dst_tmp1 = dst + dst_stride; - - filt0 = __lsx_vldrepl_h(filter, 0); - - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src0, src3, src6, - src9); - src += src_stride; - - for (; loop_cnt--;) { - uint8_t *src_tmp0 = src + src_stride; - - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src1, src4, src7, - src10); - DUP4_ARG2(__lsx_vld, src_tmp0, 0, src_tmp0, 16, src_tmp0, 32, src_tmp0, 48, - src2, src5, src8, src11); - src += src_stride2; - - DUP2_ARG2(__lsx_vilvl_b, src1, src0, src2, src1, vec0, vec2); - DUP2_ARG2(__lsx_vilvh_b, src1, src0, src2, src1, vec1, vec3); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - __lsx_vst(tmp, dst, 0); - - DUP2_ARG2(__lsx_vdp2_h_bu, vec2, filt0, vec3, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - __lsx_vst(tmp, dst_tmp1, 0); - - DUP2_ARG2(__lsx_vilvl_b, src4, src3, src5, src4, vec4, vec6); - DUP2_ARG2(__lsx_vilvh_b, src4, src3, src5, src4, vec5, vec7); - DUP2_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - __lsx_vst(tmp, dst, 16); - - DUP2_ARG2(__lsx_vdp2_h_bu, vec6, filt0, vec7, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - __lsx_vst(tmp, dst_tmp1, 16); - - DUP2_ARG2(__lsx_vilvl_b, src7, src6, src8, src7, vec0, vec2); - DUP2_ARG2(__lsx_vilvh_b, src7, src6, src8, src7, vec1, vec3); - DUP2_ARG2(__lsx_vdp2_h_bu, vec0, filt0, vec1, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - __lsx_vst(tmp, dst, 32); - - DUP2_ARG2(__lsx_vdp2_h_bu, vec2, filt0, vec3, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - __lsx_vst(tmp, dst_tmp1, 32); - - DUP2_ARG2(__lsx_vilvl_b, src10, src9, src11, src10, vec4, vec6); - DUP2_ARG2(__lsx_vilvh_b, src10, src9, src11, src10, vec5, vec7); - DUP2_ARG2(__lsx_vdp2_h_bu, vec4, filt0, vec5, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - __lsx_vst(tmp, dst, 48); - - DUP2_ARG2(__lsx_vdp2_h_bu, vec6, filt0, vec7, filt0, tmp0, tmp1); - tmp = __lsx_vssrarni_bu_h(tmp1, tmp0, FILTER_BITS); - __lsx_vst(tmp, dst_tmp1, 48); - dst += dst_stride2; - dst_tmp1 += dst_stride2; - - src0 = src2; - src3 = src5; - src6 = src8; - src9 = src11; - } -} - -void vpx_convolve8_vert_lsx(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - const int16_t *const filter_y = filter[y0_q4]; - int8_t cnt, filt_ver[8]; - - assert(y_step_q4 == 16); - assert(((const int32_t *)filter_y)[1] != 0x800000); - - for (cnt = 8; cnt--;) { - filt_ver[cnt] = filter_y[cnt]; - } - - if (vpx_get_filter_taps(filter_y) == 2) { - switch (w) { - case 4: - common_vt_2t_4w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_ver[3], h); - break; - case 8: - common_vt_2t_8w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_ver[3], h); - break; - case 16: - common_vt_2t_16w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_ver[3], h); - break; - case 32: - common_vt_2t_32w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_ver[3], h); - break; - case 64: - common_vt_2t_64w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_ver[3], h); - break; - default: - vpx_convolve8_vert_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } else { - switch (w) { - case 4: - common_vt_8t_4w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_ver, h); - break; - case 8: - common_vt_8t_8w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_ver, h); - break; - case 16: - common_vt_8t_16w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_ver, h); - break; - case 32: - common_vt_8t_32w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_ver, h); - break; - case 64: - common_vt_8t_64w_lsx(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_ver, h); - break; - default: - vpx_convolve8_vert_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve_avg_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve_avg_lsx.c deleted file mode 100644 index 1dad29ee..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve_avg_lsx.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_util/loongson_intrinsics.h" - -static void avg_width4_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int32_t height) { - int32_t cnt; - __m128i src0, src1; - __m128i dst0, dst1; - - int32_t src_stride2 = src_stride << 1; - - if ((height % 2) == 0) { - for (cnt = (height / 2); cnt--;) { - src0 = __lsx_vld(src, 0); - src1 = __lsx_vldx(src, src_stride); - src += src_stride2; - - dst0 = __lsx_vld(dst, 0); - dst1 = __lsx_vldx(dst, dst_stride); - DUP2_ARG2(__lsx_vavgr_bu, src0, dst0, src1, dst1, dst0, dst1); - - __lsx_vstelm_w(dst0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_w(dst1, dst, 0, 0); - dst += dst_stride; - } - } -} - -static void avg_width8_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int32_t height) { - int32_t cnt = (height / 4); - __m128i src0, src1, src2, src3; - __m128i dst0, dst1, dst2, dst3; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - - for (; cnt--;) { - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - dst0 = __lsx_vld(dst, 0); - DUP2_ARG2(__lsx_vldx, dst, dst_stride, dst, dst_stride2, dst1, dst2); - dst3 = __lsx_vldx(dst, dst_stride3); - - DUP4_ARG2(__lsx_vavgr_bu, src0, dst0, src1, dst1, src2, dst2, src3, dst3, - dst0, dst1, dst2, dst3); - - __lsx_vstelm_d(dst0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(dst1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(dst2, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(dst3, dst, 0, 0); - dst += dst_stride; - } -} - -static void avg_width16_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, int32_t height) { - int32_t cnt = (height / 8); - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - __m128i dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - int32_t dst_stride4 = dst_stride2 << 1; - - for (; cnt--;) { - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - src += src_stride4; - src4 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src5, src6); - src7 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - dst0 = __lsx_vld(dst, 0); - DUP2_ARG2(__lsx_vldx, dst, dst_stride, dst, dst_stride2, dst1, dst2); - dst3 = __lsx_vldx(dst, dst_stride3); - dst += dst_stride4; - dst4 = __lsx_vld(dst, 0); - DUP2_ARG2(__lsx_vldx, dst, dst_stride, dst, dst_stride2, dst5, dst6); - dst7 = __lsx_vldx(dst, dst_stride3); - dst -= dst_stride4; - - DUP4_ARG2(__lsx_vavgr_bu, src0, dst0, src1, dst1, src2, dst2, src3, dst3, - dst0, dst1, dst2, dst3); - DUP4_ARG2(__lsx_vavgr_bu, src4, dst4, src5, dst5, src6, dst6, src7, dst7, - dst4, dst5, dst6, dst7); - - __lsx_vst(dst0, dst, 0); - __lsx_vstx(dst1, dst, dst_stride); - __lsx_vstx(dst2, dst, dst_stride2); - __lsx_vstx(dst3, dst, dst_stride3); - dst += dst_stride4; - __lsx_vst(dst4, dst, 0); - __lsx_vstx(dst5, dst, dst_stride); - __lsx_vstx(dst6, dst, dst_stride2); - __lsx_vstx(dst7, dst, dst_stride3); - dst += dst_stride4; - } -} - -static void avg_width32_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, int32_t height) { - int32_t cnt = (height / 8); - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - __m128i src8, src9, src10, src11, src12, src13, src14, src15; - __m128i dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; - __m128i dst8, dst9, dst10, dst11, dst12, dst13, dst14, dst15; - - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - int32_t dst_stride2 = dst_stride << 1; - int32_t dst_stride3 = dst_stride2 + dst_stride; - int32_t dst_stride4 = dst_stride2 << 1; - - for (; cnt--;) { - uint8_t *dst_tmp = dst; - uint8_t *dst_tmp1 = dst_tmp + 16; - uint8_t *src_tmp = src + 16; - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vld, src, 0, src_tmp, 0, src0, src1); - DUP4_ARG2(__lsx_vldx, src, src_stride, src_tmp, src_stride, src, - src_stride2, src_tmp, src_stride2, src2, src3, src4, src5); - DUP2_ARG2(__lsx_vldx, src, src_stride3, src_tmp, src_stride3, src6, src7); - src += src_stride4; - - DUP2_ARG2(__lsx_vld, dst_tmp, 0, dst_tmp1, 0, dst0, dst1); - DUP4_ARG2(__lsx_vldx, dst_tmp, dst_stride, dst_tmp1, dst_stride, dst_tmp, - dst_stride2, dst_tmp1, dst_stride2, dst2, dst3, dst4, dst5); - DUP2_ARG2(__lsx_vldx, dst_tmp, dst_stride3, dst_tmp1, dst_stride3, dst6, - dst7); - dst_tmp += dst_stride4; - dst_tmp1 += dst_stride4; - - src_tmp = src + 16; - DUP2_ARG2(__lsx_vld, src, 0, src_tmp, 0, src8, src9); - DUP4_ARG2(__lsx_vldx, src, src_stride, src_tmp, src_stride, src, - src_stride2, src_tmp, src_stride2, src10, src11, src12, src13); - DUP2_ARG2(__lsx_vldx, src, src_stride3, src_tmp, src_stride3, src14, src15); - src += src_stride4; - - DUP2_ARG2(__lsx_vld, dst_tmp, 0, dst_tmp1, 0, dst8, dst9); - DUP4_ARG2(__lsx_vldx, dst_tmp, dst_stride, dst_tmp1, dst_stride, dst_tmp, - dst_stride2, dst_tmp1, dst_stride2, dst10, dst11, dst12, dst13); - DUP2_ARG2(__lsx_vldx, dst_tmp, dst_stride3, dst_tmp1, dst_stride3, dst14, - dst15); - DUP4_ARG2(__lsx_vavgr_bu, src0, dst0, src1, dst1, src2, dst2, src3, dst3, - dst0, dst1, dst2, dst3); - DUP4_ARG2(__lsx_vavgr_bu, src4, dst4, src5, dst5, src6, dst6, src7, dst7, - dst4, dst5, dst6, dst7); - DUP4_ARG2(__lsx_vavgr_bu, src8, dst8, src9, dst9, src10, dst10, src11, - dst11, dst8, dst9, dst10, dst11); - DUP4_ARG2(__lsx_vavgr_bu, src12, dst12, src13, dst13, src14, dst14, src15, - dst15, dst12, dst13, dst14, dst15); - - dst_tmp = dst + 16; - __lsx_vst(dst0, dst, 0); - __lsx_vstx(dst2, dst, dst_stride); - __lsx_vstx(dst4, dst, dst_stride2); - __lsx_vstx(dst6, dst, dst_stride3); - __lsx_vst(dst1, dst_tmp, 0); - __lsx_vstx(dst3, dst_tmp, dst_stride); - __lsx_vstx(dst5, dst_tmp, dst_stride2); - __lsx_vstx(dst7, dst_tmp, dst_stride3); - dst += dst_stride4; - - __lsx_vst(dst8, dst, 0); - __lsx_vstx(dst10, dst, dst_stride); - __lsx_vstx(dst12, dst, dst_stride2); - __lsx_vstx(dst14, dst, dst_stride3); - __lsx_vst(dst9, dst_tmp1, 0); - __lsx_vstx(dst11, dst_tmp1, dst_stride); - __lsx_vstx(dst13, dst_tmp1, dst_stride2); - __lsx_vstx(dst15, dst_tmp1, dst_stride3); - dst += dst_stride4; - } -} - -static void avg_width64_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, int32_t height) { - int32_t cnt = (height / 4); - uint8_t *dst_tmp = dst; - - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - __m128i src8, src9, src10, src11, src12, src13, src14, src15; - __m128i dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; - __m128i dst8, dst9, dst10, dst11, dst12, dst13, dst14, dst15; - - for (; cnt--;) { - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src0, src1, src2, - src3); - src += src_stride; - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src4, src5, src6, - src7); - src += src_stride; - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src8, src9, src10, - src11); - src += src_stride; - DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src12, src13, src14, - src15); - src += src_stride; - - DUP4_ARG2(__lsx_vld, dst_tmp, 0, dst_tmp, 16, dst_tmp, 32, dst_tmp, 48, - dst0, dst1, dst2, dst3); - dst_tmp += dst_stride; - DUP4_ARG2(__lsx_vld, dst_tmp, 0, dst_tmp, 16, dst_tmp, 32, dst_tmp, 48, - dst4, dst5, dst6, dst7); - dst_tmp += dst_stride; - DUP4_ARG2(__lsx_vld, dst_tmp, 0, dst_tmp, 16, dst_tmp, 32, dst_tmp, 48, - dst8, dst9, dst10, dst11); - dst_tmp += dst_stride; - DUP4_ARG2(__lsx_vld, dst_tmp, 0, dst_tmp, 16, dst_tmp, 32, dst_tmp, 48, - dst12, dst13, dst14, dst15); - dst_tmp += dst_stride; - - DUP4_ARG2(__lsx_vavgr_bu, src0, dst0, src1, dst1, src2, dst2, src3, dst3, - dst0, dst1, dst2, dst3); - DUP4_ARG2(__lsx_vavgr_bu, src4, dst4, src5, dst5, src6, dst6, src7, dst7, - dst4, dst5, dst6, dst7); - DUP4_ARG2(__lsx_vavgr_bu, src8, dst8, src9, dst9, src10, dst10, src11, - dst11, dst8, dst9, dst10, dst11); - DUP4_ARG2(__lsx_vavgr_bu, src12, dst12, src13, dst13, src14, dst14, src15, - dst15, dst12, dst13, dst14, dst15); - - __lsx_vst(dst0, dst, 0); - __lsx_vst(dst1, dst, 16); - __lsx_vst(dst2, dst, 32); - __lsx_vst(dst3, dst, 48); - dst += dst_stride; - __lsx_vst(dst4, dst, 0); - __lsx_vst(dst5, dst, 16); - __lsx_vst(dst6, dst, 32); - __lsx_vst(dst7, dst, 48); - dst += dst_stride; - __lsx_vst(dst8, dst, 0); - __lsx_vst(dst9, dst, 16); - __lsx_vst(dst10, dst, 32); - __lsx_vst(dst11, dst, 48); - dst += dst_stride; - __lsx_vst(dst12, dst, 0); - __lsx_vst(dst13, dst, 16); - __lsx_vst(dst14, dst, 32); - __lsx_vst(dst15, dst, 48); - dst += dst_stride; - } -} - -void vpx_convolve_avg_lsx(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int32_t y_step_q4, - int32_t w, int32_t h) { - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - switch (w) { - case 4: { - avg_width4_lsx(src, src_stride, dst, dst_stride, h); - break; - } - - case 8: { - avg_width8_lsx(src, src_stride, dst, dst_stride, h); - break; - } - case 16: { - avg_width16_lsx(src, src_stride, dst, dst_stride, h); - break; - } - case 32: { - avg_width32_lsx(src, src_stride, dst, dst_stride, h); - break; - } - case 64: { - avg_width64_lsx(src, src_stride, dst, dst_stride, h); - break; - } - default: { - int32_t lp, cnt; - for (cnt = h; cnt--;) { - for (lp = 0; lp < w; ++lp) { - dst[lp] = (((dst[lp] + src[lp]) + 1) >> 1); - } - src += src_stride; - dst += dst_stride; - } - break; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve_copy_lsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve_copy_lsx.c deleted file mode 100644 index 53dc7097..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve_copy_lsx.c +++ /dev/null @@ -1,437 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_util/loongson_intrinsics.h" - -static void copy_width8_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, int32_t height) { - int32_t cnt; - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - if ((height % 12) == 0) { - for (cnt = (height / 12); cnt--;) { - src0 = __lsx_vld(src, 0); - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src1, src2, src3, src4); - src += src_stride4; - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src5, src6); - src += src_stride2; - src7 = __lsx_vldx(src, src_stride); - src += src_stride2; - - __lsx_vstelm_d(src0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src2, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src3, dst, 0, 0); - dst += dst_stride; - - __lsx_vstelm_d(src4, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src5, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src6, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src7, dst, 0, 0); - dst += dst_stride; - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - __lsx_vstelm_d(src0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src2, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src3, dst, 0, 0); - dst += dst_stride; - } - } else if ((height % 8) == 0) { - for (cnt = height >> 3; cnt--;) { - src0 = __lsx_vld(src, 0); - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src1, src2, src3, src4); - src += src_stride4; - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src5, src6); - src += src_stride2; - src7 = __lsx_vldx(src, src_stride); - src += src_stride2; - - __lsx_vstelm_d(src0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src2, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src3, dst, 0, 0); - dst += dst_stride; - - __lsx_vstelm_d(src4, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src5, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src6, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src7, dst, 0, 0); - dst += dst_stride; - } - } else if ((height % 4) == 0) { - for (cnt = (height / 4); cnt--;) { - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - __lsx_vstelm_d(src0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src1, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src2, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src3, dst, 0, 0); - dst += dst_stride; - } - } else if ((height % 2) == 0) { - for (cnt = (height / 2); cnt--;) { - src0 = __lsx_vld(src, 0); - src1 = __lsx_vldx(src, src_stride); - src += src_stride2; - - __lsx_vstelm_d(src0, dst, 0, 0); - dst += dst_stride; - __lsx_vstelm_d(src1, dst, 0, 0); - dst += dst_stride; - } - } -} - -static void copy_16multx8mult_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, int32_t width) { - int32_t cnt, loop_cnt; - uint8_t *src_tmp; - uint8_t *dst_tmp; - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - for (cnt = (width >> 4); cnt--;) { - src_tmp = (uint8_t *)src; - dst_tmp = dst; - - for (loop_cnt = (height >> 3); loop_cnt--;) { - src0 = __lsx_vld(src_tmp, 0); - DUP4_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src_tmp, - src_stride3, src_tmp, src_stride4, src1, src2, src3, src4); - src_tmp += src_stride4; - DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src5, - src6); - src_tmp += src_stride2; - src7 = __lsx_vldx(src_tmp, src_stride); - src_tmp += src_stride2; - - __lsx_vst(src0, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src1, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src2, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src3, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src4, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src5, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src6, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src7, dst_tmp, 0); - dst_tmp += dst_stride; - } - src += 16; - dst += 16; - } -} - -static void copy_width16_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, int32_t height) { - int32_t cnt; - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - if ((height % 12) == 0) { - for (cnt = (height / 12); cnt--;) { - src0 = __lsx_vld(src, 0); - DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3, - src, src_stride4, src1, src2, src3, src4); - src += src_stride4; - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src5, src6); - src += src_stride2; - src7 = __lsx_vldx(src, src_stride); - src += src_stride2; - - __lsx_vst(src0, dst, 0); - dst += dst_stride; - __lsx_vst(src1, dst, 0); - dst += dst_stride; - __lsx_vst(src2, dst, 0); - dst += dst_stride; - __lsx_vst(src3, dst, 0); - dst += dst_stride; - __lsx_vst(src4, dst, 0); - dst += dst_stride; - __lsx_vst(src5, dst, 0); - dst += dst_stride; - __lsx_vst(src6, dst, 0); - dst += dst_stride; - __lsx_vst(src7, dst, 0); - dst += dst_stride; - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - __lsx_vst(src0, dst, 0); - dst += dst_stride; - __lsx_vst(src1, dst, 0); - dst += dst_stride; - __lsx_vst(src2, dst, 0); - dst += dst_stride; - __lsx_vst(src3, dst, 0); - dst += dst_stride; - } - } else if ((height % 8) == 0) { - copy_16multx8mult_lsx(src, src_stride, dst, dst_stride, height, 16); - } else if ((height % 4) == 0) { - for (cnt = (height >> 2); cnt--;) { - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - src += src_stride4; - - __lsx_vst(src0, dst, 0); - dst += dst_stride; - __lsx_vst(src1, dst, 0); - dst += dst_stride; - __lsx_vst(src2, dst, 0); - dst += dst_stride; - __lsx_vst(src3, dst, 0); - dst += dst_stride; - } - } -} - -static void copy_width32_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, int32_t height) { - int32_t cnt; - uint8_t *src_tmp; - uint8_t *dst_tmp; - __m128i src0, src1, src2, src3, src4, src5, src6, src7; - int32_t src_stride2 = src_stride << 1; - int32_t src_stride3 = src_stride2 + src_stride; - int32_t src_stride4 = src_stride2 << 1; - - if ((height % 12) == 0) { - for (cnt = (height / 12); cnt--;) { - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - - src_tmp = (uint8_t *)src + 16; - src4 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src5, - src6); - src7 = __lsx_vldx(src_tmp, src_stride3); - src += src_stride4; - - __lsx_vst(src0, dst, 0); - dst += dst_stride; - __lsx_vst(src1, dst, 0); - dst += dst_stride; - __lsx_vst(src2, dst, 0); - dst += dst_stride; - __lsx_vst(src3, dst, 0); - dst += dst_stride; - - dst_tmp = dst + 16; - __lsx_vst(src4, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src5, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src6, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src7, dst_tmp, 0); - dst_tmp += dst_stride; - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - - src_tmp = (uint8_t *)src + 16; - src4 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src5, - src6); - src7 = __lsx_vldx(src_tmp, src_stride3); - src += src_stride4; - - __lsx_vst(src0, dst, 0); - dst += dst_stride; - __lsx_vst(src1, dst, 0); - dst += dst_stride; - __lsx_vst(src2, dst, 0); - dst += dst_stride; - __lsx_vst(src3, dst, 0); - dst += dst_stride; - - dst_tmp = dst + 16; - __lsx_vst(src4, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src5, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src6, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src7, dst_tmp, 0); - dst_tmp += dst_stride; - - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - - src_tmp = (uint8_t *)src + 16; - src4 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src5, - src6); - src7 = __lsx_vldx(src_tmp, src_stride3); - src += src_stride4; - - __lsx_vst(src0, dst, 0); - dst += dst_stride; - __lsx_vst(src1, dst, 0); - dst += dst_stride; - __lsx_vst(src2, dst, 0); - dst += dst_stride; - __lsx_vst(src3, dst, 0); - dst += dst_stride; - - dst_tmp = dst + 16; - __lsx_vst(src4, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src5, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src6, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src7, dst_tmp, 0); - dst_tmp += dst_stride; - } - } else if ((height % 8) == 0) { - copy_16multx8mult_lsx(src, src_stride, dst, dst_stride, height, 32); - } else if ((height % 4) == 0) { - for (cnt = (height >> 2); cnt--;) { - src0 = __lsx_vld(src, 0); - DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2); - src3 = __lsx_vldx(src, src_stride3); - - src_tmp = (uint8_t *)src + 16; - src4 = __lsx_vld(src_tmp, 0); - DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src5, - src6); - src7 = __lsx_vldx(src_tmp, src_stride3); - src += src_stride4; - - __lsx_vst(src0, dst, 0); - dst += dst_stride; - __lsx_vst(src1, dst, 0); - dst += dst_stride; - __lsx_vst(src2, dst, 0); - dst += dst_stride; - __lsx_vst(src3, dst, 0); - dst += dst_stride; - - dst_tmp = dst + 16; - __lsx_vst(src4, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src5, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src6, dst_tmp, 0); - dst_tmp += dst_stride; - __lsx_vst(src7, dst_tmp, 0); - dst_tmp += dst_stride; - } - } -} - -static void copy_width64_lsx(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, int32_t height) { - copy_16multx8mult_lsx(src, src_stride, dst, dst_stride, height, 64); -} - -void vpx_convolve_copy_lsx(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int32_t y_step_q4, - int32_t w, int32_t h) { - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - switch (w) { - case 4: { - uint32_t cnt; - __m128i tmp; - for (cnt = h; cnt--;) { - tmp = __lsx_vldrepl_w(src, 0); - __lsx_vstelm_w(tmp, dst, 0, 0); - src += src_stride; - dst += dst_stride; - } - break; - } - case 8: { - copy_width8_lsx(src, src_stride, dst, dst_stride, h); - break; - } - case 16: { - copy_width16_lsx(src, src_stride, dst, dst_stride, h); - break; - } - case 32: { - copy_width32_lsx(src, src_stride, dst, dst_stride, h); - break; - } - case 64: { - copy_width64_lsx(src, src_stride, dst, dst_stride, h); - break; - } - default: { - uint32_t cnt; - for (cnt = h; cnt--;) { - memcpy(dst, src, w); - src += src_stride; - dst += dst_stride; - } - break; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve_lsx.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve_lsx.h deleted file mode 100644 index d886b001..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loongarch/vpx_convolve_lsx.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_LOONGARCH_VPX_CONVOLVE_LSX_H_ -#define VPX_VPX_DSP_LOONGARCH_VPX_CONVOLVE_LSX_H_ - -#include "./vpx_config.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_util/loongson_intrinsics.h" - -static INLINE __m128i filt_8tap_dpadd_s_h(__m128i _reg0, __m128i _reg1, - __m128i _reg2, __m128i _reg3, - __m128i _filter0, __m128i _filter1, - __m128i _filter2, __m128i _filter3) { - __m128i _vec0, _vec1; - - _vec0 = __lsx_vdp2_h_b(_reg0, _filter0); - _vec0 = __lsx_vdp2add_h_b(_vec0, _reg1, _filter1); - _vec1 = __lsx_vdp2_h_b(_reg2, _filter2); - _vec1 = __lsx_vdp2add_h_b(_vec1, _reg3, _filter3); - return __lsx_vsadd_h(_vec0, _vec1); -} - -static INLINE __m128i horiz_8tap_filt(__m128i _src0, __m128i _src1, - __m128i _mask0, __m128i _mask1, - __m128i _mask2, __m128i _mask3, - __m128i _filt_h0, __m128i _filt_h1, - __m128i _filt_h2, __m128i _filt_h3) { - __m128i _tmp0, _tmp1, _tmp2, _tmp3; - __m128i _out; - - DUP4_ARG3(__lsx_vshuf_b, _src1, _src0, _mask0, _src1, _src0, _mask1, _src1, - _src0, _mask2, _src1, _src0, _mask3, _tmp0, _tmp1, _tmp2, _tmp3); - _out = filt_8tap_dpadd_s_h(_tmp0, _tmp1, _tmp2, _tmp3, _filt_h0, _filt_h1, - _filt_h2, _filt_h3); - _out = __lsx_vsrari_h(_out, FILTER_BITS); - return __lsx_vsat_h(_out, 7); -} - -static INLINE __m128i horiz_2tap_filt_uh(__m128i in0, __m128i in1, __m128i mask, - __m128i coeff) { - __m128i tmp0_m, tmp1_m; - - tmp0_m = __lsx_vshuf_b(in1, in0, mask); - tmp1_m = __lsx_vdp2_h_bu(tmp0_m, coeff); - return __lsx_vsrari_h(tmp1_m, FILTER_BITS); -} - -#define LSX_LD_4(_src, _stride, _src0, _src1, _src2, _src3) \ - do { \ - _src0 = __lsx_vld(_src, 0); \ - _src += _stride; \ - _src1 = __lsx_vld(_src, 0); \ - _src += _stride; \ - _src2 = __lsx_vld(_src, 0); \ - _src += _stride; \ - _src3 = __lsx_vld(_src, 0); \ - } while (0) - -#define HORIZ_8TAP_4WID_4VECS_FILT(_src0, _src1, _src2, _src3, _mask0, _mask1, \ - _mask2, _mask3, _filter0, _filter1, \ - _filter2, _filter3, _out0, _out1) \ - do { \ - __m128i _tmp0, _tmp1, _tmp2, _tmp3, _tmp4, _tmp5, _tmp6, _tmp7; \ - __m128i _reg0, _reg1, _reg2, _reg3; \ - \ - DUP2_ARG3(__lsx_vshuf_b, _src1, _src0, _mask0, _src3, _src2, _mask0, \ - _tmp0, _tmp1); \ - DUP2_ARG2(__lsx_vdp2_h_b, _tmp0, _filter0, _tmp1, _filter0, _reg0, _reg1); \ - DUP2_ARG3(__lsx_vshuf_b, _src1, _src0, _mask1, _src3, _src2, _mask1, \ - _tmp2, _tmp3); \ - DUP2_ARG3(__lsx_vdp2add_h_b, _reg0, _tmp2, _filter1, _reg1, _tmp3, \ - _filter1, _reg0, _reg1); \ - DUP2_ARG3(__lsx_vshuf_b, _src1, _src0, _mask2, _src3, _src2, _mask2, \ - _tmp4, _tmp5); \ - DUP2_ARG2(__lsx_vdp2_h_b, _tmp4, _filter2, _tmp5, _filter2, _reg2, _reg3); \ - DUP2_ARG3(__lsx_vshuf_b, _src1, _src0, _mask3, _src3, _src2, _mask3, \ - _tmp6, _tmp7); \ - DUP2_ARG3(__lsx_vdp2add_h_b, _reg2, _tmp6, _filter3, _reg3, _tmp7, \ - _filter3, _reg2, _reg3); \ - DUP2_ARG2(__lsx_vsadd_h, _reg0, _reg2, _reg1, _reg3, _out0, _out1); \ - } while (0) - -#define HORIZ_8TAP_8WID_4VECS_FILT( \ - _src0, _src1, _src2, _src3, _mask0, _mask1, _mask2, _mask3, _filter0, \ - _filter1, _filter2, _filter3, _out0, _out1, _out2, _out3) \ - do { \ - __m128i _tmp0, _tmp1, _tmp2, _tmp3, _tmp4, _tmp5, _tmp6, _tmp7; \ - __m128i _reg0, _reg1, _reg2, _reg3, _reg4, _reg5, _reg6, _reg7; \ - \ - DUP4_ARG3(__lsx_vshuf_b, _src0, _src0, _mask0, _src1, _src1, _mask0, \ - _src2, _src2, _mask0, _src3, _src3, _mask0, _tmp0, _tmp1, _tmp2, \ - _tmp3); \ - DUP4_ARG2(__lsx_vdp2_h_b, _tmp0, _filter0, _tmp1, _filter0, _tmp2, \ - _filter0, _tmp3, _filter0, _reg0, _reg1, _reg2, _reg3); \ - DUP4_ARG3(__lsx_vshuf_b, _src0, _src0, _mask2, _src1, _src1, _mask2, \ - _src2, _src2, _mask2, _src3, _src3, _mask2, _tmp0, _tmp1, _tmp2, \ - _tmp3); \ - DUP4_ARG2(__lsx_vdp2_h_b, _tmp0, _filter2, _tmp1, _filter2, _tmp2, \ - _filter2, _tmp3, _filter2, _reg4, _reg5, _reg6, _reg7); \ - DUP4_ARG3(__lsx_vshuf_b, _src0, _src0, _mask1, _src1, _src1, _mask1, \ - _src2, _src2, _mask1, _src3, _src3, _mask1, _tmp4, _tmp5, _tmp6, \ - _tmp7); \ - DUP4_ARG3(__lsx_vdp2add_h_b, _reg0, _tmp4, _filter1, _reg1, _tmp5, \ - _filter1, _reg2, _tmp6, _filter1, _reg3, _tmp7, _filter1, _reg0, \ - _reg1, _reg2, _reg3); \ - DUP4_ARG3(__lsx_vshuf_b, _src0, _src0, _mask3, _src1, _src1, _mask3, \ - _src2, _src2, _mask3, _src3, _src3, _mask3, _tmp4, _tmp5, _tmp6, \ - _tmp7); \ - DUP4_ARG3(__lsx_vdp2add_h_b, _reg4, _tmp4, _filter3, _reg5, _tmp5, \ - _filter3, _reg6, _tmp6, _filter3, _reg7, _tmp7, _filter3, _reg4, \ - _reg5, _reg6, _reg7); \ - DUP4_ARG2(__lsx_vsadd_h, _reg0, _reg4, _reg1, _reg5, _reg2, _reg6, _reg3, \ - _reg7, _out0, _out1, _out2, _out3); \ - } while (0) - -#define AVG_ST4_D(in0, in1, dst0, dst1, pdst, stride) \ - do { \ - __m128i tmp0_m, tmp1_m; \ - \ - DUP2_ARG2(__lsx_vavgr_bu, in0, dst0, in1, dst1, tmp0_m, tmp1_m); \ - __lsx_vstelm_d(tmp0_m, pdst, 0, 0); \ - pdst += stride; \ - __lsx_vstelm_d(tmp0_m, pdst, 0, 1); \ - pdst += stride; \ - __lsx_vstelm_d(tmp1_m, pdst, 0, 0); \ - pdst += stride; \ - __lsx_vstelm_d(tmp1_m, pdst, 0, 1); \ - } while (0) - -#endif // VPX_VPX_DSP_LOONGARCH_VPX_CONVOLVE_LSX_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loopfilter.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loopfilter.c deleted file mode 100644 index d6504aab..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/loopfilter.c +++ /dev/null @@ -1,743 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_ports/mem.h" - -static INLINE int8_t signed_char_clamp(int t) { - return (int8_t)clamp(t, -128, 127); -} - -#if CONFIG_VP9_HIGHBITDEPTH -static INLINE int16_t signed_char_clamp_high(int t, int bd) { - switch (bd) { - case 10: return (int16_t)clamp(t, -128 * 4, 128 * 4 - 1); - case 12: return (int16_t)clamp(t, -128 * 16, 128 * 16 - 1); - case 8: - default: return (int16_t)clamp(t, -128, 128 - 1); - } -} -#endif - -// Should we apply any filter at all: 11111111 yes, 00000000 no -static INLINE int8_t filter_mask(uint8_t limit, uint8_t blimit, uint8_t p3, - uint8_t p2, uint8_t p1, uint8_t p0, uint8_t q0, - uint8_t q1, uint8_t q2, uint8_t q3) { - int8_t mask = 0; - mask |= (abs(p3 - p2) > limit) * -1; - mask |= (abs(p2 - p1) > limit) * -1; - mask |= (abs(p1 - p0) > limit) * -1; - mask |= (abs(q1 - q0) > limit) * -1; - mask |= (abs(q2 - q1) > limit) * -1; - mask |= (abs(q3 - q2) > limit) * -1; - mask |= (abs(p0 - q0) * 2 + abs(p1 - q1) / 2 > blimit) * -1; - return ~mask; -} - -static INLINE int8_t flat_mask4(uint8_t thresh, uint8_t p3, uint8_t p2, - uint8_t p1, uint8_t p0, uint8_t q0, uint8_t q1, - uint8_t q2, uint8_t q3) { - int8_t mask = 0; - mask |= (abs(p1 - p0) > thresh) * -1; - mask |= (abs(q1 - q0) > thresh) * -1; - mask |= (abs(p2 - p0) > thresh) * -1; - mask |= (abs(q2 - q0) > thresh) * -1; - mask |= (abs(p3 - p0) > thresh) * -1; - mask |= (abs(q3 - q0) > thresh) * -1; - return ~mask; -} - -static INLINE int8_t flat_mask5(uint8_t thresh, uint8_t p4, uint8_t p3, - uint8_t p2, uint8_t p1, uint8_t p0, uint8_t q0, - uint8_t q1, uint8_t q2, uint8_t q3, - uint8_t q4) { - int8_t mask = ~flat_mask4(thresh, p3, p2, p1, p0, q0, q1, q2, q3); - mask |= (abs(p4 - p0) > thresh) * -1; - mask |= (abs(q4 - q0) > thresh) * -1; - return ~mask; -} - -// Is there high edge variance internal edge: 11111111 yes, 00000000 no -static INLINE int8_t hev_mask(uint8_t thresh, uint8_t p1, uint8_t p0, - uint8_t q0, uint8_t q1) { - int8_t hev = 0; - hev |= (abs(p1 - p0) > thresh) * -1; - hev |= (abs(q1 - q0) > thresh) * -1; - return hev; -} - -static INLINE void filter4(int8_t mask, uint8_t thresh, uint8_t *op1, - uint8_t *op0, uint8_t *oq0, uint8_t *oq1) { - int8_t filter1, filter2; - - const int8_t ps1 = (int8_t)(*op1 ^ 0x80); - const int8_t ps0 = (int8_t)(*op0 ^ 0x80); - const int8_t qs0 = (int8_t)(*oq0 ^ 0x80); - const int8_t qs1 = (int8_t)(*oq1 ^ 0x80); - const int8_t hev = hev_mask(thresh, *op1, *op0, *oq0, *oq1); - - // add outer taps if we have high edge variance - int8_t filter = signed_char_clamp(ps1 - qs1) & hev; - - // inner taps - filter = signed_char_clamp(filter + 3 * (qs0 - ps0)) & mask; - - // save bottom 3 bits so that we round one side +4 and the other +3 - // if it equals 4 we'll set it to adjust by -1 to account for the fact - // we'd round it by 3 the other way - filter1 = signed_char_clamp(filter + 4) >> 3; - filter2 = signed_char_clamp(filter + 3) >> 3; - - *oq0 = (uint8_t)(signed_char_clamp(qs0 - filter1) ^ 0x80); - *op0 = (uint8_t)(signed_char_clamp(ps0 + filter2) ^ 0x80); - - // outer tap adjustments - filter = ROUND_POWER_OF_TWO(filter1, 1) & ~hev; - - *oq1 = (uint8_t)(signed_char_clamp(qs1 - filter) ^ 0x80); - *op1 = (uint8_t)(signed_char_clamp(ps1 + filter) ^ 0x80); -} - -void vpx_lpf_horizontal_4_c(uint8_t *s, int pitch, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh) { - int i; - - // loop filter designed to work using chars so that we can make maximum use - // of 8 bit simd instructions. - for (i = 0; i < 8; ++i) { - const uint8_t p3 = s[-4 * pitch], p2 = s[-3 * pitch], p1 = s[-2 * pitch], - p0 = s[-pitch]; - const uint8_t q0 = s[0 * pitch], q1 = s[1 * pitch], q2 = s[2 * pitch], - q3 = s[3 * pitch]; - const int8_t mask = - filter_mask(*limit, *blimit, p3, p2, p1, p0, q0, q1, q2, q3); - filter4(mask, *thresh, s - 2 * pitch, s - 1 * pitch, s, s + 1 * pitch); - ++s; - } -} - -void vpx_lpf_horizontal_4_dual_c(uint8_t *s, int pitch, const uint8_t *blimit0, - const uint8_t *limit0, const uint8_t *thresh0, - const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1) { - vpx_lpf_horizontal_4_c(s, pitch, blimit0, limit0, thresh0); - vpx_lpf_horizontal_4_c(s + 8, pitch, blimit1, limit1, thresh1); -} - -void vpx_lpf_vertical_4_c(uint8_t *s, int pitch, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh) { - int i; - - // loop filter designed to work using chars so that we can make maximum use - // of 8 bit simd instructions. - for (i = 0; i < 8; ++i) { - const uint8_t p3 = s[-4], p2 = s[-3], p1 = s[-2], p0 = s[-1]; - const uint8_t q0 = s[0], q1 = s[1], q2 = s[2], q3 = s[3]; - const int8_t mask = - filter_mask(*limit, *blimit, p3, p2, p1, p0, q0, q1, q2, q3); - filter4(mask, *thresh, s - 2, s - 1, s, s + 1); - s += pitch; - } -} - -void vpx_lpf_vertical_4_dual_c(uint8_t *s, int pitch, const uint8_t *blimit0, - const uint8_t *limit0, const uint8_t *thresh0, - const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1) { - vpx_lpf_vertical_4_c(s, pitch, blimit0, limit0, thresh0); - vpx_lpf_vertical_4_c(s + 8 * pitch, pitch, blimit1, limit1, thresh1); -} - -static INLINE void filter8(int8_t mask, uint8_t thresh, int8_t flat, - uint8_t *op3, uint8_t *op2, uint8_t *op1, - uint8_t *op0, uint8_t *oq0, uint8_t *oq1, - uint8_t *oq2, uint8_t *oq3) { - if (flat && mask) { - const uint8_t p3 = *op3, p2 = *op2, p1 = *op1, p0 = *op0; - const uint8_t q0 = *oq0, q1 = *oq1, q2 = *oq2, q3 = *oq3; - - // 7-tap filter [1, 1, 1, 2, 1, 1, 1] - *op2 = ROUND_POWER_OF_TWO(p3 + p3 + p3 + 2 * p2 + p1 + p0 + q0, 3); - *op1 = ROUND_POWER_OF_TWO(p3 + p3 + p2 + 2 * p1 + p0 + q0 + q1, 3); - *op0 = ROUND_POWER_OF_TWO(p3 + p2 + p1 + 2 * p0 + q0 + q1 + q2, 3); - *oq0 = ROUND_POWER_OF_TWO(p2 + p1 + p0 + 2 * q0 + q1 + q2 + q3, 3); - *oq1 = ROUND_POWER_OF_TWO(p1 + p0 + q0 + 2 * q1 + q2 + q3 + q3, 3); - *oq2 = ROUND_POWER_OF_TWO(p0 + q0 + q1 + 2 * q2 + q3 + q3 + q3, 3); - } else { - filter4(mask, thresh, op1, op0, oq0, oq1); - } -} - -void vpx_lpf_horizontal_8_c(uint8_t *s, int pitch, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh) { - int i; - - // loop filter designed to work using chars so that we can make maximum use - // of 8 bit simd instructions. - for (i = 0; i < 8; ++i) { - const uint8_t p3 = s[-4 * pitch], p2 = s[-3 * pitch], p1 = s[-2 * pitch], - p0 = s[-pitch]; - const uint8_t q0 = s[0 * pitch], q1 = s[1 * pitch], q2 = s[2 * pitch], - q3 = s[3 * pitch]; - - const int8_t mask = - filter_mask(*limit, *blimit, p3, p2, p1, p0, q0, q1, q2, q3); - const int8_t flat = flat_mask4(1, p3, p2, p1, p0, q0, q1, q2, q3); - filter8(mask, *thresh, flat, s - 4 * pitch, s - 3 * pitch, s - 2 * pitch, - s - 1 * pitch, s, s + 1 * pitch, s + 2 * pitch, s + 3 * pitch); - ++s; - } -} - -void vpx_lpf_horizontal_8_dual_c(uint8_t *s, int pitch, const uint8_t *blimit0, - const uint8_t *limit0, const uint8_t *thresh0, - const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1) { - vpx_lpf_horizontal_8_c(s, pitch, blimit0, limit0, thresh0); - vpx_lpf_horizontal_8_c(s + 8, pitch, blimit1, limit1, thresh1); -} - -void vpx_lpf_vertical_8_c(uint8_t *s, int pitch, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh) { - int i; - - for (i = 0; i < 8; ++i) { - const uint8_t p3 = s[-4], p2 = s[-3], p1 = s[-2], p0 = s[-1]; - const uint8_t q0 = s[0], q1 = s[1], q2 = s[2], q3 = s[3]; - const int8_t mask = - filter_mask(*limit, *blimit, p3, p2, p1, p0, q0, q1, q2, q3); - const int8_t flat = flat_mask4(1, p3, p2, p1, p0, q0, q1, q2, q3); - filter8(mask, *thresh, flat, s - 4, s - 3, s - 2, s - 1, s, s + 1, s + 2, - s + 3); - s += pitch; - } -} - -void vpx_lpf_vertical_8_dual_c(uint8_t *s, int pitch, const uint8_t *blimit0, - const uint8_t *limit0, const uint8_t *thresh0, - const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1) { - vpx_lpf_vertical_8_c(s, pitch, blimit0, limit0, thresh0); - vpx_lpf_vertical_8_c(s + 8 * pitch, pitch, blimit1, limit1, thresh1); -} - -static INLINE void filter16(int8_t mask, uint8_t thresh, int8_t flat, - int8_t flat2, uint8_t *op7, uint8_t *op6, - uint8_t *op5, uint8_t *op4, uint8_t *op3, - uint8_t *op2, uint8_t *op1, uint8_t *op0, - uint8_t *oq0, uint8_t *oq1, uint8_t *oq2, - uint8_t *oq3, uint8_t *oq4, uint8_t *oq5, - uint8_t *oq6, uint8_t *oq7) { - if (flat2 && flat && mask) { - const uint8_t p7 = *op7, p6 = *op6, p5 = *op5, p4 = *op4, p3 = *op3, - p2 = *op2, p1 = *op1, p0 = *op0; - - const uint8_t q0 = *oq0, q1 = *oq1, q2 = *oq2, q3 = *oq3, q4 = *oq4, - q5 = *oq5, q6 = *oq6, q7 = *oq7; - - // 15-tap filter [1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1] - *op6 = ROUND_POWER_OF_TWO( - p7 * 7 + p6 * 2 + p5 + p4 + p3 + p2 + p1 + p0 + q0, 4); - *op5 = ROUND_POWER_OF_TWO( - p7 * 6 + p6 + p5 * 2 + p4 + p3 + p2 + p1 + p0 + q0 + q1, 4); - *op4 = ROUND_POWER_OF_TWO( - p7 * 5 + p6 + p5 + p4 * 2 + p3 + p2 + p1 + p0 + q0 + q1 + q2, 4); - *op3 = ROUND_POWER_OF_TWO( - p7 * 4 + p6 + p5 + p4 + p3 * 2 + p2 + p1 + p0 + q0 + q1 + q2 + q3, 4); - *op2 = ROUND_POWER_OF_TWO( - p7 * 3 + p6 + p5 + p4 + p3 + p2 * 2 + p1 + p0 + q0 + q1 + q2 + q3 + q4, - 4); - *op1 = ROUND_POWER_OF_TWO(p7 * 2 + p6 + p5 + p4 + p3 + p2 + p1 * 2 + p0 + - q0 + q1 + q2 + q3 + q4 + q5, - 4); - *op0 = ROUND_POWER_OF_TWO(p7 + p6 + p5 + p4 + p3 + p2 + p1 + p0 * 2 + q0 + - q1 + q2 + q3 + q4 + q5 + q6, - 4); - *oq0 = ROUND_POWER_OF_TWO(p6 + p5 + p4 + p3 + p2 + p1 + p0 + q0 * 2 + q1 + - q2 + q3 + q4 + q5 + q6 + q7, - 4); - *oq1 = ROUND_POWER_OF_TWO(p5 + p4 + p3 + p2 + p1 + p0 + q0 + q1 * 2 + q2 + - q3 + q4 + q5 + q6 + q7 * 2, - 4); - *oq2 = ROUND_POWER_OF_TWO( - p4 + p3 + p2 + p1 + p0 + q0 + q1 + q2 * 2 + q3 + q4 + q5 + q6 + q7 * 3, - 4); - *oq3 = ROUND_POWER_OF_TWO( - p3 + p2 + p1 + p0 + q0 + q1 + q2 + q3 * 2 + q4 + q5 + q6 + q7 * 4, 4); - *oq4 = ROUND_POWER_OF_TWO( - p2 + p1 + p0 + q0 + q1 + q2 + q3 + q4 * 2 + q5 + q6 + q7 * 5, 4); - *oq5 = ROUND_POWER_OF_TWO( - p1 + p0 + q0 + q1 + q2 + q3 + q4 + q5 * 2 + q6 + q7 * 6, 4); - *oq6 = ROUND_POWER_OF_TWO( - p0 + q0 + q1 + q2 + q3 + q4 + q5 + q6 * 2 + q7 * 7, 4); - } else { - filter8(mask, thresh, flat, op3, op2, op1, op0, oq0, oq1, oq2, oq3); - } -} - -static void mb_lpf_horizontal_edge_w(uint8_t *s, int pitch, - const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh, int count) { - int i; - - // loop filter designed to work using chars so that we can make maximum use - // of 8 bit simd instructions. - for (i = 0; i < 8 * count; ++i) { - const uint8_t p3 = s[-4 * pitch], p2 = s[-3 * pitch], p1 = s[-2 * pitch], - p0 = s[-pitch]; - const uint8_t q0 = s[0 * pitch], q1 = s[1 * pitch], q2 = s[2 * pitch], - q3 = s[3 * pitch]; - const int8_t mask = - filter_mask(*limit, *blimit, p3, p2, p1, p0, q0, q1, q2, q3); - const int8_t flat = flat_mask4(1, p3, p2, p1, p0, q0, q1, q2, q3); - const int8_t flat2 = flat_mask5( - 1, s[-8 * pitch], s[-7 * pitch], s[-6 * pitch], s[-5 * pitch], p0, q0, - s[4 * pitch], s[5 * pitch], s[6 * pitch], s[7 * pitch]); - - filter16(mask, *thresh, flat, flat2, s - 8 * pitch, s - 7 * pitch, - s - 6 * pitch, s - 5 * pitch, s - 4 * pitch, s - 3 * pitch, - s - 2 * pitch, s - 1 * pitch, s, s + 1 * pitch, s + 2 * pitch, - s + 3 * pitch, s + 4 * pitch, s + 5 * pitch, s + 6 * pitch, - s + 7 * pitch); - ++s; - } -} - -void vpx_lpf_horizontal_16_c(uint8_t *s, int pitch, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh) { - mb_lpf_horizontal_edge_w(s, pitch, blimit, limit, thresh, 1); -} - -void vpx_lpf_horizontal_16_dual_c(uint8_t *s, int pitch, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh) { - mb_lpf_horizontal_edge_w(s, pitch, blimit, limit, thresh, 2); -} - -static void mb_lpf_vertical_edge_w(uint8_t *s, int pitch, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh, - int count) { - int i; - - for (i = 0; i < count; ++i) { - const uint8_t p3 = s[-4], p2 = s[-3], p1 = s[-2], p0 = s[-1]; - const uint8_t q0 = s[0], q1 = s[1], q2 = s[2], q3 = s[3]; - const int8_t mask = - filter_mask(*limit, *blimit, p3, p2, p1, p0, q0, q1, q2, q3); - const int8_t flat = flat_mask4(1, p3, p2, p1, p0, q0, q1, q2, q3); - const int8_t flat2 = flat_mask5(1, s[-8], s[-7], s[-6], s[-5], p0, q0, s[4], - s[5], s[6], s[7]); - - filter16(mask, *thresh, flat, flat2, s - 8, s - 7, s - 6, s - 5, s - 4, - s - 3, s - 2, s - 1, s, s + 1, s + 2, s + 3, s + 4, s + 5, s + 6, - s + 7); - s += pitch; - } -} - -void vpx_lpf_vertical_16_c(uint8_t *s, int pitch, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh) { - mb_lpf_vertical_edge_w(s, pitch, blimit, limit, thresh, 8); -} - -void vpx_lpf_vertical_16_dual_c(uint8_t *s, int pitch, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh) { - mb_lpf_vertical_edge_w(s, pitch, blimit, limit, thresh, 16); -} - -#if CONFIG_VP9_HIGHBITDEPTH -// Should we apply any filter at all: 11111111 yes, 00000000 no ? -static INLINE int8_t highbd_filter_mask(uint8_t limit, uint8_t blimit, - uint16_t p3, uint16_t p2, uint16_t p1, - uint16_t p0, uint16_t q0, uint16_t q1, - uint16_t q2, uint16_t q3, int bd) { - int8_t mask = 0; - int16_t limit16 = (uint16_t)limit << (bd - 8); - int16_t blimit16 = (uint16_t)blimit << (bd - 8); - mask |= (abs(p3 - p2) > limit16) * -1; - mask |= (abs(p2 - p1) > limit16) * -1; - mask |= (abs(p1 - p0) > limit16) * -1; - mask |= (abs(q1 - q0) > limit16) * -1; - mask |= (abs(q2 - q1) > limit16) * -1; - mask |= (abs(q3 - q2) > limit16) * -1; - mask |= (abs(p0 - q0) * 2 + abs(p1 - q1) / 2 > blimit16) * -1; - return ~mask; -} - -static INLINE int8_t highbd_flat_mask4(uint8_t thresh, uint16_t p3, uint16_t p2, - uint16_t p1, uint16_t p0, uint16_t q0, - uint16_t q1, uint16_t q2, uint16_t q3, - int bd) { - int8_t mask = 0; - int16_t thresh16 = (uint16_t)thresh << (bd - 8); - mask |= (abs(p1 - p0) > thresh16) * -1; - mask |= (abs(q1 - q0) > thresh16) * -1; - mask |= (abs(p2 - p0) > thresh16) * -1; - mask |= (abs(q2 - q0) > thresh16) * -1; - mask |= (abs(p3 - p0) > thresh16) * -1; - mask |= (abs(q3 - q0) > thresh16) * -1; - return ~mask; -} - -static INLINE int8_t highbd_flat_mask5(uint8_t thresh, uint16_t p4, uint16_t p3, - uint16_t p2, uint16_t p1, uint16_t p0, - uint16_t q0, uint16_t q1, uint16_t q2, - uint16_t q3, uint16_t q4, int bd) { - int8_t mask = ~highbd_flat_mask4(thresh, p3, p2, p1, p0, q0, q1, q2, q3, bd); - int16_t thresh16 = (uint16_t)thresh << (bd - 8); - mask |= (abs(p4 - p0) > thresh16) * -1; - mask |= (abs(q4 - q0) > thresh16) * -1; - return ~mask; -} - -// Is there high edge variance internal edge: -// 11111111_11111111 yes, 00000000_00000000 no ? -static INLINE int16_t highbd_hev_mask(uint8_t thresh, uint16_t p1, uint16_t p0, - uint16_t q0, uint16_t q1, int bd) { - int16_t hev = 0; - int16_t thresh16 = (uint16_t)thresh << (bd - 8); - hev |= (abs(p1 - p0) > thresh16) * -1; - hev |= (abs(q1 - q0) > thresh16) * -1; - return hev; -} - -static INLINE void highbd_filter4(int8_t mask, uint8_t thresh, uint16_t *op1, - uint16_t *op0, uint16_t *oq0, uint16_t *oq1, - int bd) { - int16_t filter1, filter2; - // ^0x80 equivalent to subtracting 0x80 from the values to turn them - // into -128 to +127 instead of 0 to 255. - int shift = bd - 8; - const int16_t ps1 = (int16_t)*op1 - (0x80 << shift); - const int16_t ps0 = (int16_t)*op0 - (0x80 << shift); - const int16_t qs0 = (int16_t)*oq0 - (0x80 << shift); - const int16_t qs1 = (int16_t)*oq1 - (0x80 << shift); - const int16_t hev = highbd_hev_mask(thresh, *op1, *op0, *oq0, *oq1, bd); - - // Add outer taps if we have high edge variance. - int16_t filter = signed_char_clamp_high(ps1 - qs1, bd) & hev; - - // Inner taps. - filter = signed_char_clamp_high(filter + 3 * (qs0 - ps0), bd) & mask; - - // Save bottom 3 bits so that we round one side +4 and the other +3 - // if it equals 4 we'll set it to adjust by -1 to account for the fact - // we'd round it by 3 the other way. - filter1 = signed_char_clamp_high(filter + 4, bd) >> 3; - filter2 = signed_char_clamp_high(filter + 3, bd) >> 3; - - *oq0 = signed_char_clamp_high(qs0 - filter1, bd) + (0x80 << shift); - *op0 = signed_char_clamp_high(ps0 + filter2, bd) + (0x80 << shift); - - // Outer tap adjustments. - filter = ROUND_POWER_OF_TWO(filter1, 1) & ~hev; - - *oq1 = signed_char_clamp_high(qs1 - filter, bd) + (0x80 << shift); - *op1 = signed_char_clamp_high(ps1 + filter, bd) + (0x80 << shift); -} - -void vpx_highbd_lpf_horizontal_4_c(uint16_t *s, int pitch, - const uint8_t *blimit, const uint8_t *limit, - const uint8_t *thresh, int bd) { - int i; - - // loop filter designed to work using chars so that we can make maximum use - // of 8 bit simd instructions. - for (i = 0; i < 8; ++i) { - const uint16_t p3 = s[-4 * pitch]; - const uint16_t p2 = s[-3 * pitch]; - const uint16_t p1 = s[-2 * pitch]; - const uint16_t p0 = s[-pitch]; - const uint16_t q0 = s[0 * pitch]; - const uint16_t q1 = s[1 * pitch]; - const uint16_t q2 = s[2 * pitch]; - const uint16_t q3 = s[3 * pitch]; - const int8_t mask = - highbd_filter_mask(*limit, *blimit, p3, p2, p1, p0, q0, q1, q2, q3, bd); - highbd_filter4(mask, *thresh, s - 2 * pitch, s - 1 * pitch, s, - s + 1 * pitch, bd); - ++s; - } -} - -void vpx_highbd_lpf_horizontal_4_dual_c( - uint16_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, - const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1, int bd) { - vpx_highbd_lpf_horizontal_4_c(s, pitch, blimit0, limit0, thresh0, bd); - vpx_highbd_lpf_horizontal_4_c(s + 8, pitch, blimit1, limit1, thresh1, bd); -} - -void vpx_highbd_lpf_vertical_4_c(uint16_t *s, int pitch, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh, - int bd) { - int i; - - // loop filter designed to work using chars so that we can make maximum use - // of 8 bit simd instructions. - for (i = 0; i < 8; ++i) { - const uint16_t p3 = s[-4], p2 = s[-3], p1 = s[-2], p0 = s[-1]; - const uint16_t q0 = s[0], q1 = s[1], q2 = s[2], q3 = s[3]; - const int8_t mask = - highbd_filter_mask(*limit, *blimit, p3, p2, p1, p0, q0, q1, q2, q3, bd); - highbd_filter4(mask, *thresh, s - 2, s - 1, s, s + 1, bd); - s += pitch; - } -} - -void vpx_highbd_lpf_vertical_4_dual_c( - uint16_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, - const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1, int bd) { - vpx_highbd_lpf_vertical_4_c(s, pitch, blimit0, limit0, thresh0, bd); - vpx_highbd_lpf_vertical_4_c(s + 8 * pitch, pitch, blimit1, limit1, thresh1, - bd); -} - -static INLINE void highbd_filter8(int8_t mask, uint8_t thresh, int8_t flat, - uint16_t *op3, uint16_t *op2, uint16_t *op1, - uint16_t *op0, uint16_t *oq0, uint16_t *oq1, - uint16_t *oq2, uint16_t *oq3, int bd) { - if (flat && mask) { - const uint16_t p3 = *op3, p2 = *op2, p1 = *op1, p0 = *op0; - const uint16_t q0 = *oq0, q1 = *oq1, q2 = *oq2, q3 = *oq3; - - // 7-tap filter [1, 1, 1, 2, 1, 1, 1] - *op2 = ROUND_POWER_OF_TWO(p3 + p3 + p3 + 2 * p2 + p1 + p0 + q0, 3); - *op1 = ROUND_POWER_OF_TWO(p3 + p3 + p2 + 2 * p1 + p0 + q0 + q1, 3); - *op0 = ROUND_POWER_OF_TWO(p3 + p2 + p1 + 2 * p0 + q0 + q1 + q2, 3); - *oq0 = ROUND_POWER_OF_TWO(p2 + p1 + p0 + 2 * q0 + q1 + q2 + q3, 3); - *oq1 = ROUND_POWER_OF_TWO(p1 + p0 + q0 + 2 * q1 + q2 + q3 + q3, 3); - *oq2 = ROUND_POWER_OF_TWO(p0 + q0 + q1 + 2 * q2 + q3 + q3 + q3, 3); - } else { - highbd_filter4(mask, thresh, op1, op0, oq0, oq1, bd); - } -} - -void vpx_highbd_lpf_horizontal_8_c(uint16_t *s, int pitch, - const uint8_t *blimit, const uint8_t *limit, - const uint8_t *thresh, int bd) { - int i; - - // loop filter designed to work using chars so that we can make maximum use - // of 8 bit simd instructions. - for (i = 0; i < 8; ++i) { - const uint16_t p3 = s[-4 * pitch], p2 = s[-3 * pitch], p1 = s[-2 * pitch], - p0 = s[-pitch]; - const uint16_t q0 = s[0 * pitch], q1 = s[1 * pitch], q2 = s[2 * pitch], - q3 = s[3 * pitch]; - - const int8_t mask = - highbd_filter_mask(*limit, *blimit, p3, p2, p1, p0, q0, q1, q2, q3, bd); - const int8_t flat = - highbd_flat_mask4(1, p3, p2, p1, p0, q0, q1, q2, q3, bd); - highbd_filter8(mask, *thresh, flat, s - 4 * pitch, s - 3 * pitch, - s - 2 * pitch, s - 1 * pitch, s, s + 1 * pitch, - s + 2 * pitch, s + 3 * pitch, bd); - ++s; - } -} - -void vpx_highbd_lpf_horizontal_8_dual_c( - uint16_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, - const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1, int bd) { - vpx_highbd_lpf_horizontal_8_c(s, pitch, blimit0, limit0, thresh0, bd); - vpx_highbd_lpf_horizontal_8_c(s + 8, pitch, blimit1, limit1, thresh1, bd); -} - -void vpx_highbd_lpf_vertical_8_c(uint16_t *s, int pitch, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh, - int bd) { - int i; - - for (i = 0; i < 8; ++i) { - const uint16_t p3 = s[-4], p2 = s[-3], p1 = s[-2], p0 = s[-1]; - const uint16_t q0 = s[0], q1 = s[1], q2 = s[2], q3 = s[3]; - const int8_t mask = - highbd_filter_mask(*limit, *blimit, p3, p2, p1, p0, q0, q1, q2, q3, bd); - const int8_t flat = - highbd_flat_mask4(1, p3, p2, p1, p0, q0, q1, q2, q3, bd); - highbd_filter8(mask, *thresh, flat, s - 4, s - 3, s - 2, s - 1, s, s + 1, - s + 2, s + 3, bd); - s += pitch; - } -} - -void vpx_highbd_lpf_vertical_8_dual_c( - uint16_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, - const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1, int bd) { - vpx_highbd_lpf_vertical_8_c(s, pitch, blimit0, limit0, thresh0, bd); - vpx_highbd_lpf_vertical_8_c(s + 8 * pitch, pitch, blimit1, limit1, thresh1, - bd); -} - -static INLINE void highbd_filter16(int8_t mask, uint8_t thresh, int8_t flat, - int8_t flat2, uint16_t *op7, uint16_t *op6, - uint16_t *op5, uint16_t *op4, uint16_t *op3, - uint16_t *op2, uint16_t *op1, uint16_t *op0, - uint16_t *oq0, uint16_t *oq1, uint16_t *oq2, - uint16_t *oq3, uint16_t *oq4, uint16_t *oq5, - uint16_t *oq6, uint16_t *oq7, int bd) { - if (flat2 && flat && mask) { - const uint16_t p7 = *op7; - const uint16_t p6 = *op6; - const uint16_t p5 = *op5; - const uint16_t p4 = *op4; - const uint16_t p3 = *op3; - const uint16_t p2 = *op2; - const uint16_t p1 = *op1; - const uint16_t p0 = *op0; - const uint16_t q0 = *oq0; - const uint16_t q1 = *oq1; - const uint16_t q2 = *oq2; - const uint16_t q3 = *oq3; - const uint16_t q4 = *oq4; - const uint16_t q5 = *oq5; - const uint16_t q6 = *oq6; - const uint16_t q7 = *oq7; - - // 15-tap filter [1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1] - *op6 = ROUND_POWER_OF_TWO( - p7 * 7 + p6 * 2 + p5 + p4 + p3 + p2 + p1 + p0 + q0, 4); - *op5 = ROUND_POWER_OF_TWO( - p7 * 6 + p6 + p5 * 2 + p4 + p3 + p2 + p1 + p0 + q0 + q1, 4); - *op4 = ROUND_POWER_OF_TWO( - p7 * 5 + p6 + p5 + p4 * 2 + p3 + p2 + p1 + p0 + q0 + q1 + q2, 4); - *op3 = ROUND_POWER_OF_TWO( - p7 * 4 + p6 + p5 + p4 + p3 * 2 + p2 + p1 + p0 + q0 + q1 + q2 + q3, 4); - *op2 = ROUND_POWER_OF_TWO( - p7 * 3 + p6 + p5 + p4 + p3 + p2 * 2 + p1 + p0 + q0 + q1 + q2 + q3 + q4, - 4); - *op1 = ROUND_POWER_OF_TWO(p7 * 2 + p6 + p5 + p4 + p3 + p2 + p1 * 2 + p0 + - q0 + q1 + q2 + q3 + q4 + q5, - 4); - *op0 = ROUND_POWER_OF_TWO(p7 + p6 + p5 + p4 + p3 + p2 + p1 + p0 * 2 + q0 + - q1 + q2 + q3 + q4 + q5 + q6, - 4); - *oq0 = ROUND_POWER_OF_TWO(p6 + p5 + p4 + p3 + p2 + p1 + p0 + q0 * 2 + q1 + - q2 + q3 + q4 + q5 + q6 + q7, - 4); - *oq1 = ROUND_POWER_OF_TWO(p5 + p4 + p3 + p2 + p1 + p0 + q0 + q1 * 2 + q2 + - q3 + q4 + q5 + q6 + q7 * 2, - 4); - *oq2 = ROUND_POWER_OF_TWO( - p4 + p3 + p2 + p1 + p0 + q0 + q1 + q2 * 2 + q3 + q4 + q5 + q6 + q7 * 3, - 4); - *oq3 = ROUND_POWER_OF_TWO( - p3 + p2 + p1 + p0 + q0 + q1 + q2 + q3 * 2 + q4 + q5 + q6 + q7 * 4, 4); - *oq4 = ROUND_POWER_OF_TWO( - p2 + p1 + p0 + q0 + q1 + q2 + q3 + q4 * 2 + q5 + q6 + q7 * 5, 4); - *oq5 = ROUND_POWER_OF_TWO( - p1 + p0 + q0 + q1 + q2 + q3 + q4 + q5 * 2 + q6 + q7 * 6, 4); - *oq6 = ROUND_POWER_OF_TWO( - p0 + q0 + q1 + q2 + q3 + q4 + q5 + q6 * 2 + q7 * 7, 4); - } else { - highbd_filter8(mask, thresh, flat, op3, op2, op1, op0, oq0, oq1, oq2, oq3, - bd); - } -} - -static void highbd_mb_lpf_horizontal_edge_w(uint16_t *s, int pitch, - const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh, int count, - int bd) { - int i; - - // loop filter designed to work using chars so that we can make maximum use - // of 8 bit simd instructions. - for (i = 0; i < 8 * count; ++i) { - const uint16_t p3 = s[-4 * pitch]; - const uint16_t p2 = s[-3 * pitch]; - const uint16_t p1 = s[-2 * pitch]; - const uint16_t p0 = s[-pitch]; - const uint16_t q0 = s[0 * pitch]; - const uint16_t q1 = s[1 * pitch]; - const uint16_t q2 = s[2 * pitch]; - const uint16_t q3 = s[3 * pitch]; - const int8_t mask = - highbd_filter_mask(*limit, *blimit, p3, p2, p1, p0, q0, q1, q2, q3, bd); - const int8_t flat = - highbd_flat_mask4(1, p3, p2, p1, p0, q0, q1, q2, q3, bd); - const int8_t flat2 = highbd_flat_mask5( - 1, s[-8 * pitch], s[-7 * pitch], s[-6 * pitch], s[-5 * pitch], p0, q0, - s[4 * pitch], s[5 * pitch], s[6 * pitch], s[7 * pitch], bd); - - highbd_filter16(mask, *thresh, flat, flat2, s - 8 * pitch, s - 7 * pitch, - s - 6 * pitch, s - 5 * pitch, s - 4 * pitch, s - 3 * pitch, - s - 2 * pitch, s - 1 * pitch, s, s + 1 * pitch, - s + 2 * pitch, s + 3 * pitch, s + 4 * pitch, s + 5 * pitch, - s + 6 * pitch, s + 7 * pitch, bd); - ++s; - } -} - -void vpx_highbd_lpf_horizontal_16_c(uint16_t *s, int pitch, - const uint8_t *blimit, const uint8_t *limit, - const uint8_t *thresh, int bd) { - highbd_mb_lpf_horizontal_edge_w(s, pitch, blimit, limit, thresh, 1, bd); -} - -void vpx_highbd_lpf_horizontal_16_dual_c(uint16_t *s, int pitch, - const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh, int bd) { - highbd_mb_lpf_horizontal_edge_w(s, pitch, blimit, limit, thresh, 2, bd); -} - -static void highbd_mb_lpf_vertical_edge_w(uint16_t *s, int pitch, - const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh, int count, - int bd) { - int i; - - for (i = 0; i < count; ++i) { - const uint16_t p3 = s[-4]; - const uint16_t p2 = s[-3]; - const uint16_t p1 = s[-2]; - const uint16_t p0 = s[-1]; - const uint16_t q0 = s[0]; - const uint16_t q1 = s[1]; - const uint16_t q2 = s[2]; - const uint16_t q3 = s[3]; - const int8_t mask = - highbd_filter_mask(*limit, *blimit, p3, p2, p1, p0, q0, q1, q2, q3, bd); - const int8_t flat = - highbd_flat_mask4(1, p3, p2, p1, p0, q0, q1, q2, q3, bd); - const int8_t flat2 = highbd_flat_mask5(1, s[-8], s[-7], s[-6], s[-5], p0, - q0, s[4], s[5], s[6], s[7], bd); - - highbd_filter16(mask, *thresh, flat, flat2, s - 8, s - 7, s - 6, s - 5, - s - 4, s - 3, s - 2, s - 1, s, s + 1, s + 2, s + 3, s + 4, - s + 5, s + 6, s + 7, bd); - s += pitch; - } -} - -void vpx_highbd_lpf_vertical_16_c(uint16_t *s, int pitch, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh, - int bd) { - highbd_mb_lpf_vertical_edge_w(s, pitch, blimit, limit, thresh, 8, bd); -} - -void vpx_highbd_lpf_vertical_16_dual_c(uint16_t *s, int pitch, - const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh, int bd) { - highbd_mb_lpf_vertical_edge_w(s, pitch, blimit, limit, thresh, 16, bd); -} -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/add_noise_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/add_noise_msa.c deleted file mode 100644 index 97541411..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/add_noise_msa.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/macros_msa.h" - -void vpx_plane_add_noise_msa(uint8_t *start_ptr, const int8_t *noise, - int blackclamp, int whiteclamp, int width, - int height, int32_t pitch) { - int i, j; - v16u8 pos0, pos1, ref0, ref1; - v16i8 black_clamp, white_clamp, both_clamp; - - black_clamp = __msa_fill_b(blackclamp); - white_clamp = __msa_fill_b(whiteclamp); - both_clamp = black_clamp + white_clamp; - both_clamp = -both_clamp; - - for (i = 0; i < height / 2; ++i) { - uint8_t *pos0_ptr = start_ptr + (2 * i) * pitch; - const int8_t *ref0_ptr = noise + (rand() & 0xff); - uint8_t *pos1_ptr = start_ptr + (2 * i + 1) * pitch; - const int8_t *ref1_ptr = noise + (rand() & 0xff); - for (j = width / 16; j--;) { - pos0 = LD_UB(pos0_ptr); - ref0 = LD_UB(ref0_ptr); - pos1 = LD_UB(pos1_ptr); - ref1 = LD_UB(ref1_ptr); - pos0 = __msa_subsus_u_b(pos0, black_clamp); - pos1 = __msa_subsus_u_b(pos1, black_clamp); - pos0 = __msa_subsus_u_b(pos0, both_clamp); - pos1 = __msa_subsus_u_b(pos1, both_clamp); - pos0 = __msa_subsus_u_b(pos0, white_clamp); - pos1 = __msa_subsus_u_b(pos1, white_clamp); - pos0 += ref0; - ST_UB(pos0, pos0_ptr); - pos1 += ref1; - ST_UB(pos1, pos1_ptr); - pos0_ptr += 16; - pos1_ptr += 16; - ref0_ptr += 16; - ref1_ptr += 16; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/avg_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/avg_msa.c deleted file mode 100644 index 3fd18dec..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/avg_msa.c +++ /dev/null @@ -1,731 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/macros_msa.h" - -uint32_t vpx_avg_8x8_msa(const uint8_t *src, int32_t src_stride) { - uint32_t sum_out; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v8u16 sum0, sum1, sum2, sum3, sum4, sum5, sum6, sum7; - v4u32 sum = { 0 }; - - LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - HADD_UB4_UH(src0, src1, src2, src3, sum0, sum1, sum2, sum3); - HADD_UB4_UH(src4, src5, src6, src7, sum4, sum5, sum6, sum7); - ADD4(sum0, sum1, sum2, sum3, sum4, sum5, sum6, sum7, sum0, sum2, sum4, sum6); - ADD2(sum0, sum2, sum4, sum6, sum0, sum4); - sum0 += sum4; - - sum = __msa_hadd_u_w(sum0, sum0); - sum0 = (v8u16)__msa_pckev_h((v8i16)sum, (v8i16)sum); - sum = __msa_hadd_u_w(sum0, sum0); - sum = (v4u32)__msa_srari_w((v4i32)sum, 6); - sum_out = __msa_copy_u_w((v4i32)sum, 0); - - return sum_out; -} - -uint32_t vpx_avg_4x4_msa(const uint8_t *src, int32_t src_stride) { - uint32_t sum_out; - uint32_t src0, src1, src2, src3; - v16u8 vec = { 0 }; - v8u16 sum0; - v4u32 sum1; - v2u64 sum2; - - LW4(src, src_stride, src0, src1, src2, src3); - INSERT_W4_UB(src0, src1, src2, src3, vec); - - sum0 = __msa_hadd_u_h(vec, vec); - sum1 = __msa_hadd_u_w(sum0, sum0); - sum0 = (v8u16)__msa_pckev_h((v8i16)sum1, (v8i16)sum1); - sum1 = __msa_hadd_u_w(sum0, sum0); - sum2 = __msa_hadd_u_d(sum1, sum1); - sum1 = (v4u32)__msa_srari_w((v4i32)sum2, 4); - sum_out = __msa_copy_u_w((v4i32)sum1, 0); - - return sum_out; -} - -#if !CONFIG_VP9_HIGHBITDEPTH -void vpx_hadamard_8x8_msa(const int16_t *src, ptrdiff_t src_stride, - int16_t *dst) { - v8i16 src0, src1, src2, src3, src4, src5, src6, src7; - v8i16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - - LD_SH8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - BUTTERFLY_8(src0, src2, src4, src6, src7, src5, src3, src1, tmp0, tmp2, tmp4, - tmp6, tmp7, tmp5, tmp3, tmp1); - BUTTERFLY_8(tmp0, tmp1, tmp4, tmp5, tmp7, tmp6, tmp3, tmp2, src0, src1, src4, - src5, src7, src6, src3, src2); - BUTTERFLY_8(src0, src1, src2, src3, src7, src6, src5, src4, tmp0, tmp7, tmp3, - tmp4, tmp5, tmp1, tmp6, tmp2); - TRANSPOSE8x8_SH_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, src0, src1, - src2, src3, src4, src5, src6, src7); - BUTTERFLY_8(src0, src2, src4, src6, src7, src5, src3, src1, tmp0, tmp2, tmp4, - tmp6, tmp7, tmp5, tmp3, tmp1); - BUTTERFLY_8(tmp0, tmp1, tmp4, tmp5, tmp7, tmp6, tmp3, tmp2, src0, src1, src4, - src5, src7, src6, src3, src2); - BUTTERFLY_8(src0, src1, src2, src3, src7, src6, src5, src4, tmp0, tmp7, tmp3, - tmp4, tmp5, tmp1, tmp6, tmp2); - TRANSPOSE8x8_SH_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, src0, src1, - src2, src3, src4, src5, src6, src7); - ST_SH8(src0, src1, src2, src3, src4, src5, src6, src7, dst, 8); -} - -void vpx_hadamard_16x16_msa(const int16_t *src, ptrdiff_t src_stride, - int16_t *dst) { - v8i16 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - v8i16 src11, src12, src13, src14, src15, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; - v8i16 tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15; - v8i16 res0, res1, res2, res3, res4, res5, res6, res7; - - LD_SH2(src, 8, src0, src8); - src += src_stride; - LD_SH2(src, 8, src1, src9); - src += src_stride; - LD_SH2(src, 8, src2, src10); - src += src_stride; - LD_SH2(src, 8, src3, src11); - src += src_stride; - LD_SH2(src, 8, src4, src12); - src += src_stride; - LD_SH2(src, 8, src5, src13); - src += src_stride; - LD_SH2(src, 8, src6, src14); - src += src_stride; - LD_SH2(src, 8, src7, src15); - src += src_stride; - - BUTTERFLY_8(src0, src2, src4, src6, src7, src5, src3, src1, tmp0, tmp2, tmp4, - tmp6, tmp7, tmp5, tmp3, tmp1); - BUTTERFLY_8(src8, src10, src12, src14, src15, src13, src11, src9, tmp8, tmp10, - tmp12, tmp14, tmp15, tmp13, tmp11, tmp9); - - BUTTERFLY_8(tmp0, tmp1, tmp4, tmp5, tmp7, tmp6, tmp3, tmp2, src0, src1, src4, - src5, src7, src6, src3, src2); - BUTTERFLY_8(src0, src1, src2, src3, src7, src6, src5, src4, tmp0, tmp7, tmp3, - tmp4, tmp5, tmp1, tmp6, tmp2); - TRANSPOSE8x8_SH_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, src0, src1, - src2, src3, src4, src5, src6, src7); - BUTTERFLY_8(src0, src2, src4, src6, src7, src5, src3, src1, tmp0, tmp2, tmp4, - tmp6, tmp7, tmp5, tmp3, tmp1); - BUTTERFLY_8(tmp0, tmp1, tmp4, tmp5, tmp7, tmp6, tmp3, tmp2, src0, src1, src4, - src5, src7, src6, src3, src2); - BUTTERFLY_8(src0, src1, src2, src3, src7, src6, src5, src4, tmp0, tmp7, tmp3, - tmp4, tmp5, tmp1, tmp6, tmp2); - TRANSPOSE8x8_SH_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, src0, src1, - src2, src11, src4, src5, src6, src7); - ST_SH8(src0, src1, src2, src11, src4, src5, src6, src7, dst, 8); - - BUTTERFLY_8(tmp8, tmp9, tmp12, tmp13, tmp15, tmp14, tmp11, tmp10, src8, src9, - src12, src13, src15, src14, src11, src10); - BUTTERFLY_8(src8, src9, src10, src11, src15, src14, src13, src12, tmp8, tmp15, - tmp11, tmp12, tmp13, tmp9, tmp14, tmp10); - TRANSPOSE8x8_SH_SH(tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, src8, - src9, src10, src11, src12, src13, src14, src15); - BUTTERFLY_8(src8, src10, src12, src14, src15, src13, src11, src9, tmp8, tmp10, - tmp12, tmp14, tmp15, tmp13, tmp11, tmp9); - BUTTERFLY_8(tmp8, tmp9, tmp12, tmp13, tmp15, tmp14, tmp11, tmp10, src8, src9, - src12, src13, src15, src14, src11, src10); - BUTTERFLY_8(src8, src9, src10, src11, src15, src14, src13, src12, tmp8, tmp15, - tmp11, tmp12, tmp13, tmp9, tmp14, tmp10); - TRANSPOSE8x8_SH_SH(tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, res0, - res1, res2, res3, res4, res5, res6, res7); - - LD_SH2(src, 8, src0, src8); - src += src_stride; - LD_SH2(src, 8, src1, src9); - src += src_stride; - LD_SH2(src, 8, src2, src10); - src += src_stride; - LD_SH2(src, 8, src3, src11); - src += src_stride; - - ST_SH8(res0, res1, res2, res3, res4, res5, res6, res7, dst + 64, 8); - - LD_SH2(src, 8, src4, src12); - src += src_stride; - LD_SH2(src, 8, src5, src13); - src += src_stride; - LD_SH2(src, 8, src6, src14); - src += src_stride; - LD_SH2(src, 8, src7, src15); - src += src_stride; - - BUTTERFLY_8(src0, src2, src4, src6, src7, src5, src3, src1, tmp0, tmp2, tmp4, - tmp6, tmp7, tmp5, tmp3, tmp1); - BUTTERFLY_8(src8, src10, src12, src14, src15, src13, src11, src9, tmp8, tmp10, - tmp12, tmp14, tmp15, tmp13, tmp11, tmp9); - - BUTTERFLY_8(tmp0, tmp1, tmp4, tmp5, tmp7, tmp6, tmp3, tmp2, src0, src1, src4, - src5, src7, src6, src3, src2); - BUTTERFLY_8(src0, src1, src2, src3, src7, src6, src5, src4, tmp0, tmp7, tmp3, - tmp4, tmp5, tmp1, tmp6, tmp2); - TRANSPOSE8x8_SH_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, src0, src1, - src2, src3, src4, src5, src6, src7); - BUTTERFLY_8(src0, src2, src4, src6, src7, src5, src3, src1, tmp0, tmp2, tmp4, - tmp6, tmp7, tmp5, tmp3, tmp1); - BUTTERFLY_8(tmp0, tmp1, tmp4, tmp5, tmp7, tmp6, tmp3, tmp2, src0, src1, src4, - src5, src7, src6, src3, src2); - BUTTERFLY_8(src0, src1, src2, src3, src7, src6, src5, src4, tmp0, tmp7, tmp3, - tmp4, tmp5, tmp1, tmp6, tmp2); - TRANSPOSE8x8_SH_SH(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, src0, src1, - src2, src3, src4, src5, src6, src7); - ST_SH8(src0, src1, src2, src3, src4, src5, src6, src7, dst + 2 * 64, 8); - - BUTTERFLY_8(tmp8, tmp9, tmp12, tmp13, tmp15, tmp14, tmp11, tmp10, src8, src9, - src12, src13, src15, src14, src11, src10); - BUTTERFLY_8(src8, src9, src10, src11, src15, src14, src13, src12, tmp8, tmp15, - tmp11, tmp12, tmp13, tmp9, tmp14, tmp10); - TRANSPOSE8x8_SH_SH(tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, src8, - src9, src10, src11, src12, src13, src14, src15); - BUTTERFLY_8(src8, src10, src12, src14, src15, src13, src11, src9, tmp8, tmp10, - tmp12, tmp14, tmp15, tmp13, tmp11, tmp9); - BUTTERFLY_8(tmp8, tmp9, tmp12, tmp13, tmp15, tmp14, tmp11, tmp10, src8, src9, - src12, src13, src15, src14, src11, src10); - BUTTERFLY_8(src8, src9, src10, src11, src15, src14, src13, src12, tmp8, tmp15, - tmp11, tmp12, tmp13, tmp9, tmp14, tmp10); - TRANSPOSE8x8_SH_SH(tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, res0, - res1, res2, res3, res4, res5, res6, res7); - ST_SH8(res0, res1, res2, res3, res4, res5, res6, res7, dst + 3 * 64, 8); - - LD_SH4(dst, 64, src0, src1, src2, src3); - LD_SH4(dst + 8, 64, src4, src5, src6, src7); - - BUTTERFLY_8(src0, src2, src4, src6, src7, src5, src3, src1, tmp0, tmp2, tmp4, - tmp6, tmp7, tmp5, tmp3, tmp1); - SRA_4V(tmp0, tmp1, tmp2, tmp3, 1); - SRA_4V(tmp4, tmp5, tmp6, tmp7, 1); - BUTTERFLY_8(tmp0, tmp1, tmp4, tmp5, tmp7, tmp6, tmp3, tmp2, src0, src1, src4, - src5, src7, src6, src3, src2); - - ST_SH4(src0, src1, src2, src3, dst, 64); - ST_SH4(src4, src5, src6, src7, dst + 8, 64); - dst += 16; - - LD_SH4(dst, 64, src0, src1, src2, src3); - LD_SH4(dst + 8, 64, src4, src5, src6, src7); - - BUTTERFLY_8(src0, src2, src4, src6, src7, src5, src3, src1, tmp0, tmp2, tmp4, - tmp6, tmp7, tmp5, tmp3, tmp1); - SRA_4V(tmp0, tmp1, tmp2, tmp3, 1); - SRA_4V(tmp4, tmp5, tmp6, tmp7, 1); - BUTTERFLY_8(tmp0, tmp1, tmp4, tmp5, tmp7, tmp6, tmp3, tmp2, src0, src1, src4, - src5, src7, src6, src3, src2); - - ST_SH4(src0, src1, src2, src3, dst, 64); - ST_SH4(src4, src5, src6, src7, dst + 8, 64); - dst += 16; - - LD_SH4(dst, 64, src0, src1, src2, src3); - LD_SH4(dst + 8, 64, src4, src5, src6, src7); - - BUTTERFLY_8(src0, src2, src4, src6, src7, src5, src3, src1, tmp0, tmp2, tmp4, - tmp6, tmp7, tmp5, tmp3, tmp1); - SRA_4V(tmp0, tmp1, tmp2, tmp3, 1); - SRA_4V(tmp4, tmp5, tmp6, tmp7, 1); - BUTTERFLY_8(tmp0, tmp1, tmp4, tmp5, tmp7, tmp6, tmp3, tmp2, src0, src1, src4, - src5, src7, src6, src3, src2); - - ST_SH4(src0, src1, src2, src3, dst, 64); - ST_SH4(src4, src5, src6, src7, dst + 8, 64); - dst += 16; - - LD_SH4(dst, 64, src0, src1, src2, src3); - LD_SH4(dst + 8, 64, src4, src5, src6, src7); - - BUTTERFLY_8(src0, src2, src4, src6, src7, src5, src3, src1, tmp0, tmp2, tmp4, - tmp6, tmp7, tmp5, tmp3, tmp1); - SRA_4V(tmp0, tmp1, tmp2, tmp3, 1); - SRA_4V(tmp4, tmp5, tmp6, tmp7, 1); - BUTTERFLY_8(tmp0, tmp1, tmp4, tmp5, tmp7, tmp6, tmp3, tmp2, src0, src1, src4, - src5, src7, src6, src3, src2); - - ST_SH4(src0, src1, src2, src3, dst, 64); - ST_SH4(src4, src5, src6, src7, dst + 8, 64); -} - -int vpx_satd_msa(const int16_t *data, int length) { - int i, satd; - v8i16 src0, src1, src2, src3, src4, src5, src6, src7; - v8i16 src8, src9, src10, src11, src12, src13, src14, src15; - v8i16 zero = { 0 }; - v8u16 tmp0_h, tmp1_h, tmp2_h, tmp3_h, tmp4_h, tmp5_h, tmp6_h, tmp7_h; - v4u32 tmp0_w = { 0 }; - - if (16 == length) { - LD_SH2(data, 8, src0, src1); - tmp0_h = (v8u16)__msa_asub_s_h(src0, zero); - tmp1_h = (v8u16)__msa_asub_s_h(src1, zero); - tmp0_w = __msa_hadd_u_w(tmp0_h, tmp0_h); - tmp0_w += __msa_hadd_u_w(tmp1_h, tmp1_h); - satd = HADD_UW_U32(tmp0_w); - } else if (64 == length) { - LD_SH8(data, 8, src0, src1, src2, src3, src4, src5, src6, src7); - - tmp0_h = (v8u16)__msa_asub_s_h(src0, zero); - tmp1_h = (v8u16)__msa_asub_s_h(src1, zero); - tmp2_h = (v8u16)__msa_asub_s_h(src2, zero); - tmp3_h = (v8u16)__msa_asub_s_h(src3, zero); - tmp4_h = (v8u16)__msa_asub_s_h(src4, zero); - tmp5_h = (v8u16)__msa_asub_s_h(src5, zero); - tmp6_h = (v8u16)__msa_asub_s_h(src6, zero); - tmp7_h = (v8u16)__msa_asub_s_h(src7, zero); - - tmp0_w = __msa_hadd_u_w(tmp0_h, tmp0_h); - tmp0_w += __msa_hadd_u_w(tmp1_h, tmp1_h); - tmp0_w += __msa_hadd_u_w(tmp2_h, tmp2_h); - tmp0_w += __msa_hadd_u_w(tmp3_h, tmp3_h); - tmp0_w += __msa_hadd_u_w(tmp4_h, tmp4_h); - tmp0_w += __msa_hadd_u_w(tmp5_h, tmp5_h); - tmp0_w += __msa_hadd_u_w(tmp6_h, tmp6_h); - tmp0_w += __msa_hadd_u_w(tmp7_h, tmp7_h); - - satd = HADD_UW_U32(tmp0_w); - } else if (256 == length) { - for (i = 0; i < 2; ++i) { - LD_SH8(data, 8, src0, src1, src2, src3, src4, src5, src6, src7); - data += 8 * 8; - LD_SH8(data, 8, src8, src9, src10, src11, src12, src13, src14, src15); - data += 8 * 8; - - tmp0_h = (v8u16)__msa_asub_s_h(src0, zero); - tmp1_h = (v8u16)__msa_asub_s_h(src1, zero); - tmp2_h = (v8u16)__msa_asub_s_h(src2, zero); - tmp3_h = (v8u16)__msa_asub_s_h(src3, zero); - tmp4_h = (v8u16)__msa_asub_s_h(src4, zero); - tmp5_h = (v8u16)__msa_asub_s_h(src5, zero); - tmp6_h = (v8u16)__msa_asub_s_h(src6, zero); - tmp7_h = (v8u16)__msa_asub_s_h(src7, zero); - - tmp0_w += __msa_hadd_u_w(tmp0_h, tmp0_h); - tmp0_w += __msa_hadd_u_w(tmp1_h, tmp1_h); - tmp0_w += __msa_hadd_u_w(tmp2_h, tmp2_h); - tmp0_w += __msa_hadd_u_w(tmp3_h, tmp3_h); - tmp0_w += __msa_hadd_u_w(tmp4_h, tmp4_h); - tmp0_w += __msa_hadd_u_w(tmp5_h, tmp5_h); - tmp0_w += __msa_hadd_u_w(tmp6_h, tmp6_h); - tmp0_w += __msa_hadd_u_w(tmp7_h, tmp7_h); - - tmp0_h = (v8u16)__msa_asub_s_h(src8, zero); - tmp1_h = (v8u16)__msa_asub_s_h(src9, zero); - tmp2_h = (v8u16)__msa_asub_s_h(src10, zero); - tmp3_h = (v8u16)__msa_asub_s_h(src11, zero); - tmp4_h = (v8u16)__msa_asub_s_h(src12, zero); - tmp5_h = (v8u16)__msa_asub_s_h(src13, zero); - tmp6_h = (v8u16)__msa_asub_s_h(src14, zero); - tmp7_h = (v8u16)__msa_asub_s_h(src15, zero); - - tmp0_w += __msa_hadd_u_w(tmp0_h, tmp0_h); - tmp0_w += __msa_hadd_u_w(tmp1_h, tmp1_h); - tmp0_w += __msa_hadd_u_w(tmp2_h, tmp2_h); - tmp0_w += __msa_hadd_u_w(tmp3_h, tmp3_h); - tmp0_w += __msa_hadd_u_w(tmp4_h, tmp4_h); - tmp0_w += __msa_hadd_u_w(tmp5_h, tmp5_h); - tmp0_w += __msa_hadd_u_w(tmp6_h, tmp6_h); - tmp0_w += __msa_hadd_u_w(tmp7_h, tmp7_h); - } - - satd = HADD_UW_U32(tmp0_w); - } else if (1024 == length) { - for (i = 0; i < 8; ++i) { - LD_SH8(data, 8, src0, src1, src2, src3, src4, src5, src6, src7); - data += 8 * 8; - LD_SH8(data, 8, src8, src9, src10, src11, src12, src13, src14, src15); - data += 8 * 8; - - tmp0_h = (v8u16)__msa_asub_s_h(src0, zero); - tmp1_h = (v8u16)__msa_asub_s_h(src1, zero); - tmp2_h = (v8u16)__msa_asub_s_h(src2, zero); - tmp3_h = (v8u16)__msa_asub_s_h(src3, zero); - tmp4_h = (v8u16)__msa_asub_s_h(src4, zero); - tmp5_h = (v8u16)__msa_asub_s_h(src5, zero); - tmp6_h = (v8u16)__msa_asub_s_h(src6, zero); - tmp7_h = (v8u16)__msa_asub_s_h(src7, zero); - - tmp0_w += __msa_hadd_u_w(tmp0_h, tmp0_h); - tmp0_w += __msa_hadd_u_w(tmp1_h, tmp1_h); - tmp0_w += __msa_hadd_u_w(tmp2_h, tmp2_h); - tmp0_w += __msa_hadd_u_w(tmp3_h, tmp3_h); - tmp0_w += __msa_hadd_u_w(tmp4_h, tmp4_h); - tmp0_w += __msa_hadd_u_w(tmp5_h, tmp5_h); - tmp0_w += __msa_hadd_u_w(tmp6_h, tmp6_h); - tmp0_w += __msa_hadd_u_w(tmp7_h, tmp7_h); - - tmp0_h = (v8u16)__msa_asub_s_h(src8, zero); - tmp1_h = (v8u16)__msa_asub_s_h(src9, zero); - tmp2_h = (v8u16)__msa_asub_s_h(src10, zero); - tmp3_h = (v8u16)__msa_asub_s_h(src11, zero); - tmp4_h = (v8u16)__msa_asub_s_h(src12, zero); - tmp5_h = (v8u16)__msa_asub_s_h(src13, zero); - tmp6_h = (v8u16)__msa_asub_s_h(src14, zero); - tmp7_h = (v8u16)__msa_asub_s_h(src15, zero); - - tmp0_w += __msa_hadd_u_w(tmp0_h, tmp0_h); - tmp0_w += __msa_hadd_u_w(tmp1_h, tmp1_h); - tmp0_w += __msa_hadd_u_w(tmp2_h, tmp2_h); - tmp0_w += __msa_hadd_u_w(tmp3_h, tmp3_h); - tmp0_w += __msa_hadd_u_w(tmp4_h, tmp4_h); - tmp0_w += __msa_hadd_u_w(tmp5_h, tmp5_h); - tmp0_w += __msa_hadd_u_w(tmp6_h, tmp6_h); - tmp0_w += __msa_hadd_u_w(tmp7_h, tmp7_h); - } - - satd = HADD_UW_U32(tmp0_w); - } else { - satd = 0; - - for (i = 0; i < length; ++i) { - satd += abs(data[i]); - } - } - - return satd; -} -#endif // !CONFIG_VP9_HIGHBITDEPTH - -void vpx_int_pro_row_msa(int16_t hbuf[16], const uint8_t *ref, - const int ref_stride, const int height) { - int i; - v16u8 ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7; - v8i16 hbuf_r = { 0 }; - v8i16 hbuf_l = { 0 }; - v8i16 ref0_r, ref0_l, ref1_r, ref1_l, ref2_r, ref2_l, ref3_r, ref3_l; - v8i16 ref4_r, ref4_l, ref5_r, ref5_l, ref6_r, ref6_l, ref7_r, ref7_l; - - if (16 == height) { - for (i = 2; i--;) { - LD_UB8(ref, ref_stride, ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7); - ref += 8 * ref_stride; - UNPCK_UB_SH(ref0, ref0_r, ref0_l); - UNPCK_UB_SH(ref1, ref1_r, ref1_l); - UNPCK_UB_SH(ref2, ref2_r, ref2_l); - UNPCK_UB_SH(ref3, ref3_r, ref3_l); - UNPCK_UB_SH(ref4, ref4_r, ref4_l); - UNPCK_UB_SH(ref5, ref5_r, ref5_l); - UNPCK_UB_SH(ref6, ref6_r, ref6_l); - UNPCK_UB_SH(ref7, ref7_r, ref7_l); - ADD4(hbuf_r, ref0_r, hbuf_l, ref0_l, hbuf_r, ref1_r, hbuf_l, ref1_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - ADD4(hbuf_r, ref2_r, hbuf_l, ref2_l, hbuf_r, ref3_r, hbuf_l, ref3_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - ADD4(hbuf_r, ref4_r, hbuf_l, ref4_l, hbuf_r, ref5_r, hbuf_l, ref5_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - ADD4(hbuf_r, ref6_r, hbuf_l, ref6_l, hbuf_r, ref7_r, hbuf_l, ref7_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - } - - SRA_2V(hbuf_r, hbuf_l, 3); - ST_SH2(hbuf_r, hbuf_l, hbuf, 8); - } else if (32 == height) { - for (i = 2; i--;) { - LD_UB8(ref, ref_stride, ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7); - ref += 8 * ref_stride; - UNPCK_UB_SH(ref0, ref0_r, ref0_l); - UNPCK_UB_SH(ref1, ref1_r, ref1_l); - UNPCK_UB_SH(ref2, ref2_r, ref2_l); - UNPCK_UB_SH(ref3, ref3_r, ref3_l); - UNPCK_UB_SH(ref4, ref4_r, ref4_l); - UNPCK_UB_SH(ref5, ref5_r, ref5_l); - UNPCK_UB_SH(ref6, ref6_r, ref6_l); - UNPCK_UB_SH(ref7, ref7_r, ref7_l); - ADD4(hbuf_r, ref0_r, hbuf_l, ref0_l, hbuf_r, ref1_r, hbuf_l, ref1_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - ADD4(hbuf_r, ref2_r, hbuf_l, ref2_l, hbuf_r, ref3_r, hbuf_l, ref3_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - ADD4(hbuf_r, ref4_r, hbuf_l, ref4_l, hbuf_r, ref5_r, hbuf_l, ref5_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - ADD4(hbuf_r, ref6_r, hbuf_l, ref6_l, hbuf_r, ref7_r, hbuf_l, ref7_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - LD_UB8(ref, ref_stride, ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7); - ref += 8 * ref_stride; - UNPCK_UB_SH(ref0, ref0_r, ref0_l); - UNPCK_UB_SH(ref1, ref1_r, ref1_l); - UNPCK_UB_SH(ref2, ref2_r, ref2_l); - UNPCK_UB_SH(ref3, ref3_r, ref3_l); - UNPCK_UB_SH(ref4, ref4_r, ref4_l); - UNPCK_UB_SH(ref5, ref5_r, ref5_l); - UNPCK_UB_SH(ref6, ref6_r, ref6_l); - UNPCK_UB_SH(ref7, ref7_r, ref7_l); - ADD4(hbuf_r, ref0_r, hbuf_l, ref0_l, hbuf_r, ref1_r, hbuf_l, ref1_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - ADD4(hbuf_r, ref2_r, hbuf_l, ref2_l, hbuf_r, ref3_r, hbuf_l, ref3_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - ADD4(hbuf_r, ref4_r, hbuf_l, ref4_l, hbuf_r, ref5_r, hbuf_l, ref5_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - ADD4(hbuf_r, ref6_r, hbuf_l, ref6_l, hbuf_r, ref7_r, hbuf_l, ref7_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - } - - SRA_2V(hbuf_r, hbuf_l, 4); - ST_SH2(hbuf_r, hbuf_l, hbuf, 8); - } else if (64 == height) { - for (i = 4; i--;) { - LD_UB8(ref, ref_stride, ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7); - ref += 8 * ref_stride; - UNPCK_UB_SH(ref0, ref0_r, ref0_l); - UNPCK_UB_SH(ref1, ref1_r, ref1_l); - UNPCK_UB_SH(ref2, ref2_r, ref2_l); - UNPCK_UB_SH(ref3, ref3_r, ref3_l); - UNPCK_UB_SH(ref4, ref4_r, ref4_l); - UNPCK_UB_SH(ref5, ref5_r, ref5_l); - UNPCK_UB_SH(ref6, ref6_r, ref6_l); - UNPCK_UB_SH(ref7, ref7_r, ref7_l); - ADD4(hbuf_r, ref0_r, hbuf_l, ref0_l, hbuf_r, ref1_r, hbuf_l, ref1_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - ADD4(hbuf_r, ref2_r, hbuf_l, ref2_l, hbuf_r, ref3_r, hbuf_l, ref3_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - ADD4(hbuf_r, ref4_r, hbuf_l, ref4_l, hbuf_r, ref5_r, hbuf_l, ref5_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - ADD4(hbuf_r, ref6_r, hbuf_l, ref6_l, hbuf_r, ref7_r, hbuf_l, ref7_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - LD_UB8(ref, ref_stride, ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7); - ref += 8 * ref_stride; - UNPCK_UB_SH(ref0, ref0_r, ref0_l); - UNPCK_UB_SH(ref1, ref1_r, ref1_l); - UNPCK_UB_SH(ref2, ref2_r, ref2_l); - UNPCK_UB_SH(ref3, ref3_r, ref3_l); - UNPCK_UB_SH(ref4, ref4_r, ref4_l); - UNPCK_UB_SH(ref5, ref5_r, ref5_l); - UNPCK_UB_SH(ref6, ref6_r, ref6_l); - UNPCK_UB_SH(ref7, ref7_r, ref7_l); - ADD4(hbuf_r, ref0_r, hbuf_l, ref0_l, hbuf_r, ref1_r, hbuf_l, ref1_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - ADD4(hbuf_r, ref2_r, hbuf_l, ref2_l, hbuf_r, ref3_r, hbuf_l, ref3_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - ADD4(hbuf_r, ref4_r, hbuf_l, ref4_l, hbuf_r, ref5_r, hbuf_l, ref5_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - ADD4(hbuf_r, ref6_r, hbuf_l, ref6_l, hbuf_r, ref7_r, hbuf_l, ref7_l, - hbuf_r, hbuf_l, hbuf_r, hbuf_l); - } - - SRA_2V(hbuf_r, hbuf_l, 5); - ST_SH2(hbuf_r, hbuf_l, hbuf, 8); - } else { - const int norm_factor = height >> 1; - int cnt; - - for (cnt = 0; cnt < 16; cnt++) { - hbuf[cnt] = 0; - } - - for (i = 0; i < height; ++i) { - for (cnt = 0; cnt < 16; cnt++) { - hbuf[cnt] += ref[cnt]; - } - - ref += ref_stride; - } - - for (cnt = 0; cnt < 16; cnt++) { - hbuf[cnt] /= norm_factor; - } - } -} - -int16_t vpx_int_pro_col_msa(const uint8_t *ref, const int width) { - int16_t sum; - v16u8 ref0, ref1, ref2, ref3; - v8u16 ref0_h; - - if (16 == width) { - ref0 = LD_UB(ref); - ref0_h = __msa_hadd_u_h(ref0, ref0); - sum = HADD_UH_U32(ref0_h); - } else if (32 == width) { - LD_UB2(ref, 16, ref0, ref1); - ref0_h = __msa_hadd_u_h(ref0, ref0); - ref0_h += __msa_hadd_u_h(ref1, ref1); - sum = HADD_UH_U32(ref0_h); - } else if (64 == width) { - LD_UB4(ref, 16, ref0, ref1, ref2, ref3); - ref0_h = __msa_hadd_u_h(ref0, ref0); - ref0_h += __msa_hadd_u_h(ref1, ref1); - ref0_h += __msa_hadd_u_h(ref2, ref2); - ref0_h += __msa_hadd_u_h(ref3, ref3); - sum = HADD_UH_U32(ref0_h); - } else { - int idx; - - sum = 0; - for (idx = 0; idx < width; ++idx) { - sum += ref[idx]; - } - } - - return sum; -} - -int vpx_vector_var_msa(const int16_t *ref, const int16_t *src, const int bwl) { - int sse, mean, var; - v8i16 src0, src1, src2, src3, src4, src5, src6, src7, ref0, ref1, ref2; - v8i16 ref3, ref4, ref5, ref6, ref7, src_l0_m, src_l1_m, src_l2_m, src_l3_m; - v8i16 src_l4_m, src_l5_m, src_l6_m, src_l7_m; - v4i32 res_l0_m, res_l1_m, res_l2_m, res_l3_m, res_l4_m, res_l5_m, res_l6_m; - v4i32 res_l7_m, mean_v; - v2i64 sse_v; - - if (2 == bwl) { - LD_SH2(src, 8, src0, src1); - LD_SH2(ref, 8, ref0, ref1); - - ILVRL_H2_SH(src0, ref0, src_l0_m, src_l1_m); - ILVRL_H2_SH(src1, ref1, src_l2_m, src_l3_m); - HSUB_UH2_SW(src_l0_m, src_l1_m, res_l0_m, res_l1_m); - HSUB_UH2_SW(src_l2_m, src_l3_m, res_l2_m, res_l3_m); - sse_v = __msa_dotp_s_d(res_l0_m, res_l0_m); - sse_v = __msa_dpadd_s_d(sse_v, res_l1_m, res_l1_m); - DPADD_SD2_SD(res_l2_m, res_l3_m, sse_v, sse_v); - mean_v = res_l0_m + res_l1_m; - mean_v += res_l2_m + res_l3_m; - - sse_v += __msa_splati_d(sse_v, 1); - sse = __msa_copy_s_w((v4i32)sse_v, 0); - - mean = HADD_SW_S32(mean_v); - } else if (3 == bwl) { - LD_SH4(src, 8, src0, src1, src2, src3); - LD_SH4(ref, 8, ref0, ref1, ref2, ref3); - - ILVRL_H2_SH(src0, ref0, src_l0_m, src_l1_m); - ILVRL_H2_SH(src1, ref1, src_l2_m, src_l3_m); - ILVRL_H2_SH(src2, ref2, src_l4_m, src_l5_m); - ILVRL_H2_SH(src3, ref3, src_l6_m, src_l7_m); - HSUB_UH2_SW(src_l0_m, src_l1_m, res_l0_m, res_l1_m); - HSUB_UH2_SW(src_l2_m, src_l3_m, res_l2_m, res_l3_m); - HSUB_UH2_SW(src_l4_m, src_l5_m, res_l4_m, res_l5_m); - HSUB_UH2_SW(src_l6_m, src_l7_m, res_l6_m, res_l7_m); - sse_v = __msa_dotp_s_d(res_l0_m, res_l0_m); - sse_v = __msa_dpadd_s_d(sse_v, res_l1_m, res_l1_m); - DPADD_SD2_SD(res_l2_m, res_l3_m, sse_v, sse_v); - DPADD_SD2_SD(res_l4_m, res_l5_m, sse_v, sse_v); - DPADD_SD2_SD(res_l6_m, res_l7_m, sse_v, sse_v); - mean_v = res_l0_m + res_l1_m; - mean_v += res_l2_m + res_l3_m; - mean_v += res_l4_m + res_l5_m; - mean_v += res_l6_m + res_l7_m; - - sse_v += __msa_splati_d(sse_v, 1); - sse = __msa_copy_s_w((v4i32)sse_v, 0); - - mean = HADD_SW_S32(mean_v); - } else if (4 == bwl) { - LD_SH8(src, 8, src0, src1, src2, src3, src4, src5, src6, src7); - LD_SH8(ref, 8, ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7); - - ILVRL_H2_SH(src0, ref0, src_l0_m, src_l1_m); - ILVRL_H2_SH(src1, ref1, src_l2_m, src_l3_m); - ILVRL_H2_SH(src2, ref2, src_l4_m, src_l5_m); - ILVRL_H2_SH(src3, ref3, src_l6_m, src_l7_m); - HSUB_UH2_SW(src_l0_m, src_l1_m, res_l0_m, res_l1_m); - HSUB_UH2_SW(src_l2_m, src_l3_m, res_l2_m, res_l3_m); - HSUB_UH2_SW(src_l4_m, src_l5_m, res_l4_m, res_l5_m); - HSUB_UH2_SW(src_l6_m, src_l7_m, res_l6_m, res_l7_m); - sse_v = __msa_dotp_s_d(res_l0_m, res_l0_m); - sse_v = __msa_dpadd_s_d(sse_v, res_l1_m, res_l1_m); - DPADD_SD2_SD(res_l2_m, res_l3_m, sse_v, sse_v); - DPADD_SD2_SD(res_l4_m, res_l5_m, sse_v, sse_v); - DPADD_SD2_SD(res_l6_m, res_l7_m, sse_v, sse_v); - mean_v = res_l0_m + res_l1_m; - mean_v += res_l2_m + res_l3_m; - mean_v += res_l4_m + res_l5_m; - mean_v += res_l6_m + res_l7_m; - - ILVRL_H2_SH(src4, ref4, src_l0_m, src_l1_m); - ILVRL_H2_SH(src5, ref5, src_l2_m, src_l3_m); - ILVRL_H2_SH(src6, ref6, src_l4_m, src_l5_m); - ILVRL_H2_SH(src7, ref7, src_l6_m, src_l7_m); - HSUB_UH2_SW(src_l0_m, src_l1_m, res_l0_m, res_l1_m); - HSUB_UH2_SW(src_l2_m, src_l3_m, res_l2_m, res_l3_m); - HSUB_UH2_SW(src_l4_m, src_l5_m, res_l4_m, res_l5_m); - HSUB_UH2_SW(src_l6_m, src_l7_m, res_l6_m, res_l7_m); - DPADD_SD2_SD(res_l0_m, res_l1_m, sse_v, sse_v); - DPADD_SD2_SD(res_l2_m, res_l3_m, sse_v, sse_v); - DPADD_SD2_SD(res_l4_m, res_l5_m, sse_v, sse_v); - DPADD_SD2_SD(res_l6_m, res_l7_m, sse_v, sse_v); - mean_v += res_l0_m + res_l1_m; - mean_v += res_l2_m + res_l3_m; - mean_v += res_l4_m + res_l5_m; - mean_v += res_l6_m + res_l7_m; - - sse_v += __msa_splati_d(sse_v, 1); - sse = __msa_copy_s_w((v4i32)sse_v, 0); - - mean = HADD_SW_S32(mean_v); - } else { - int i; - const int width = 4 << bwl; - - sse = 0; - mean = 0; - - for (i = 0; i < width; ++i) { - const int diff = ref[i] - src[i]; - - mean += diff; - sse += diff * diff; - } - } - - var = sse - ((mean * mean) >> (bwl + 2)); - - return var; -} - -void vpx_minmax_8x8_msa(const uint8_t *s, int p, const uint8_t *d, int dp, - int *min, int *max) { - v16u8 s0, s1, s2, s3, s4, s5, s6, s7, d0, d1, d2, d3, d4, d5, d6, d7; - v16u8 diff0, diff1, diff2, diff3, min0, min1, max0, max1; - - LD_UB8(s, p, s0, s1, s2, s3, s4, s5, s6, s7); - LD_UB8(d, dp, d0, d1, d2, d3, d4, d5, d6, d7); - PCKEV_D4_UB(s1, s0, s3, s2, s5, s4, s7, s6, s0, s1, s2, s3); - PCKEV_D4_UB(d1, d0, d3, d2, d5, d4, d7, d6, d0, d1, d2, d3); - - diff0 = __msa_asub_u_b(s0, d0); - diff1 = __msa_asub_u_b(s1, d1); - diff2 = __msa_asub_u_b(s2, d2); - diff3 = __msa_asub_u_b(s3, d3); - - min0 = __msa_min_u_b(diff0, diff1); - min1 = __msa_min_u_b(diff2, diff3); - min0 = __msa_min_u_b(min0, min1); - - max0 = __msa_max_u_b(diff0, diff1); - max1 = __msa_max_u_b(diff2, diff3); - max0 = __msa_max_u_b(max0, max1); - - min1 = (v16u8)__msa_sldi_b((v16i8)min1, (v16i8)min0, 8); - min0 = __msa_min_u_b(min0, min1); - max1 = (v16u8)__msa_sldi_b((v16i8)max1, (v16i8)max0, 8); - max0 = __msa_max_u_b(max0, max1); - - min1 = (v16u8)__msa_sldi_b((v16i8)min1, (v16i8)min0, 4); - min0 = __msa_min_u_b(min0, min1); - max1 = (v16u8)__msa_sldi_b((v16i8)max1, (v16i8)max0, 4); - max0 = __msa_max_u_b(max0, max1); - - min1 = (v16u8)__msa_sldi_b((v16i8)min1, (v16i8)min0, 2); - min0 = __msa_min_u_b(min0, min1); - max1 = (v16u8)__msa_sldi_b((v16i8)max1, (v16i8)max0, 2); - max0 = __msa_max_u_b(max0, max1); - - min1 = (v16u8)__msa_sldi_b((v16i8)min1, (v16i8)min0, 1); - min0 = __msa_min_u_b(min0, min1); - max1 = (v16u8)__msa_sldi_b((v16i8)max1, (v16i8)max0, 1); - max0 = __msa_max_u_b(max0, max1); - - *min = min0[0]; - *max = max0[0]; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/common_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/common_dspr2.c deleted file mode 100644 index b22f084a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/common_dspr2.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_dsp/mips/common_dspr2.h" - -#if HAVE_DSPR2 -uint8_t vpx_ff_cropTbl_a[256 + 2 * CROP_WIDTH]; -uint8_t *vpx_ff_cropTbl; - -void vpx_dsputil_static_init(void) { - int i; - - for (i = 0; i < 256; i++) vpx_ff_cropTbl_a[i + CROP_WIDTH] = i; - - for (i = 0; i < CROP_WIDTH; i++) { - vpx_ff_cropTbl_a[i] = 0; - vpx_ff_cropTbl_a[i + CROP_WIDTH + 256] = 255; - } - - vpx_ff_cropTbl = &vpx_ff_cropTbl_a[CROP_WIDTH]; -} - -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/common_dspr2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/common_dspr2.h deleted file mode 100644 index 87a5bbab..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/common_dspr2.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_MIPS_COMMON_DSPR2_H_ -#define VPX_VPX_DSP_MIPS_COMMON_DSPR2_H_ - -#include -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif -#if HAVE_DSPR2 -#define CROP_WIDTH 512 - -extern uint8_t *vpx_ff_cropTbl; // From "vpx_dsp/mips/intrapred4_dspr2.c" - -static INLINE void prefetch_load(const unsigned char *src) { - __asm__ __volatile__("pref 0, 0(%[src]) \n\t" : : [src] "r"(src)); -} - -/* prefetch data for store */ -static INLINE void prefetch_store(unsigned char *dst) { - __asm__ __volatile__("pref 1, 0(%[dst]) \n\t" : : [dst] "r"(dst)); -} - -static INLINE void prefetch_load_streamed(const unsigned char *src) { - __asm__ __volatile__("pref 4, 0(%[src]) \n\t" : : [src] "r"(src)); -} - -/* prefetch data for store */ -static INLINE void prefetch_store_streamed(unsigned char *dst) { - __asm__ __volatile__("pref 5, 0(%[dst]) \n\t" : : [dst] "r"(dst)); -} -#endif // #if HAVE_DSPR2 -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_MIPS_COMMON_DSPR2_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve2_avg_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve2_avg_dspr2.c deleted file mode 100644 index 18e7d537..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve2_avg_dspr2.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/convolve_common_dspr2.h" -#include "vpx_dsp/vpx_convolve.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_ports/mem.h" - -#if HAVE_DSPR2 -static void convolve_bi_avg_vert_4_dspr2(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int16_t *filter_y, int32_t w, - int32_t h) { - int32_t x, y; - const uint8_t *src_ptr; - uint8_t *dst_ptr; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector4a = 64; - uint32_t load1, load2; - uint32_t p1, p2; - uint32_t scratch1, scratch2; - uint32_t store1, store2; - int32_t Temp1, Temp2; - const int16_t *filter = &filter_y[3]; - uint32_t filter45; - - filter45 = ((const int32_t *)filter)[0]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_store(dst + dst_stride); - - for (x = 0; x < w; x += 4) { - src_ptr = src + x; - dst_ptr = dst + x; - - __asm__ __volatile__( - "ulw %[load1], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load2], 0(%[src_ptr]) \n\t" - - "mtlo %[vector4a], $ac0 \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac0 \n\t" - "mthi $zero, $ac1 \n\t" - "mthi $zero, $ac2 \n\t" - "mthi $zero, $ac3 \n\t" - - "preceu.ph.qbr %[scratch1], %[load1] \n\t" - "preceu.ph.qbr %[p1], %[load2] \n\t" - "precrq.ph.w %[p2], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac0, %[p1], %[filter45] \n\t" - "dpa.w.ph $ac1, %[p2], %[filter45] \n\t" - - "preceu.ph.qbl %[scratch1], %[load1] \n\t" - "preceu.ph.qbl %[p1], %[load2] \n\t" - "precrq.ph.w %[p2], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac2, %[p1], %[filter45] \n\t" - "dpa.w.ph $ac3, %[p2], %[filter45] \n\t" - - "extp %[Temp1], $ac0, 31 \n\t" - "extp %[Temp2], $ac1, 31 \n\t" - - "lbu %[scratch1], 0(%[dst_ptr]) \n\t" - "lbu %[scratch2], 1(%[dst_ptr]) \n\t" - - "lbux %[store1], %[Temp1](%[cm]) \n\t" - "addqh_r.w %[store1], %[store1], %[scratch1] \n\t" /* pixel 1 */ - "extp %[Temp1], $ac2, 31 \n\t" - - "lbux %[store2], %[Temp2](%[cm]) \n\t" - "addqh_r.w %[store2], %[store2], %[scratch2] \n\t" /* pixel 2 */ - "extp %[Temp2], $ac3, 31 \n\t" - "lbu %[scratch1], 2(%[dst_ptr]) \n\t" - - "sb %[store1], 0(%[dst_ptr]) \n\t" - "sb %[store2], 1(%[dst_ptr]) \n\t" - "lbu %[scratch2], 3(%[dst_ptr]) \n\t" - - "lbux %[store1], %[Temp1](%[cm]) \n\t" - "lbux %[store2], %[Temp2](%[cm]) \n\t" - "addqh_r.w %[store1], %[store1], %[scratch1] \n\t" /* pixel 3 */ - "addqh_r.w %[store2], %[store2], %[scratch2] \n\t" /* pixel 4 */ - - "sb %[store1], 2(%[dst_ptr]) \n\t" - "sb %[store2], 3(%[dst_ptr]) \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [p1] "=&r"(p1), - [p2] "=&r"(p2), [scratch1] "=&r"(scratch1), - [scratch2] "=&r"(scratch2), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [store1] "=&r"(store1), - [store2] "=&r"(store2), [src_ptr] "+r"(src_ptr) - : [filter45] "r"(filter45), [vector4a] "r"(vector4a), - [src_stride] "r"(src_stride), [cm] "r"(cm), [dst_ptr] "r"(dst_ptr)); - } - - /* Next row... */ - src += src_stride; - dst += dst_stride; - } -} - -static void convolve_bi_avg_vert_64_dspr2(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - const int16_t *filter_y, int32_t h) { - int32_t x, y; - const uint8_t *src_ptr; - uint8_t *dst_ptr; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector4a = 64; - uint32_t load1, load2; - uint32_t p1, p2; - uint32_t scratch1, scratch2; - uint32_t store1, store2; - int32_t Temp1, Temp2; - const int16_t *filter = &filter_y[3]; - uint32_t filter45; - - filter45 = ((const int32_t *)filter)[0]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_store(dst + dst_stride); - prefetch_store(dst + dst_stride + 32); - - for (x = 0; x < 64; x += 4) { - src_ptr = src + x; - dst_ptr = dst + x; - - __asm__ __volatile__( - "ulw %[load1], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load2], 0(%[src_ptr]) \n\t" - - "mtlo %[vector4a], $ac0 \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac0 \n\t" - "mthi $zero, $ac1 \n\t" - "mthi $zero, $ac2 \n\t" - "mthi $zero, $ac3 \n\t" - - "preceu.ph.qbr %[scratch1], %[load1] \n\t" - "preceu.ph.qbr %[p1], %[load2] \n\t" - "precrq.ph.w %[p2], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac0, %[p1], %[filter45] \n\t" - "dpa.w.ph $ac1, %[p2], %[filter45] \n\t" - - "preceu.ph.qbl %[scratch1], %[load1] \n\t" - "preceu.ph.qbl %[p1], %[load2] \n\t" - "precrq.ph.w %[p2], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac2, %[p1], %[filter45] \n\t" - "dpa.w.ph $ac3, %[p2], %[filter45] \n\t" - - "extp %[Temp1], $ac0, 31 \n\t" - "extp %[Temp2], $ac1, 31 \n\t" - - "lbu %[scratch1], 0(%[dst_ptr]) \n\t" - "lbu %[scratch2], 1(%[dst_ptr]) \n\t" - - "lbux %[store1], %[Temp1](%[cm]) \n\t" - "addqh_r.w %[store1], %[store1], %[scratch1] \n\t" /* pixel 1 */ - "extp %[Temp1], $ac2, 31 \n\t" - - "lbux %[store2], %[Temp2](%[cm]) \n\t" - "addqh_r.w %[store2], %[store2], %[scratch2] \n\t" /* pixel 2 */ - "extp %[Temp2], $ac3, 31 \n\t" - "lbu %[scratch1], 2(%[dst_ptr]) \n\t" - - "sb %[store1], 0(%[dst_ptr]) \n\t" - "sb %[store2], 1(%[dst_ptr]) \n\t" - "lbu %[scratch2], 3(%[dst_ptr]) \n\t" - - "lbux %[store1], %[Temp1](%[cm]) \n\t" - "lbux %[store2], %[Temp2](%[cm]) \n\t" - "addqh_r.w %[store1], %[store1], %[scratch1] \n\t" /* pixel 3 */ - "addqh_r.w %[store2], %[store2], %[scratch2] \n\t" /* pixel 4 */ - - "sb %[store1], 2(%[dst_ptr]) \n\t" - "sb %[store2], 3(%[dst_ptr]) \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [p1] "=&r"(p1), - [p2] "=&r"(p2), [scratch1] "=&r"(scratch1), - [scratch2] "=&r"(scratch2), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [store1] "=&r"(store1), - [store2] "=&r"(store2), [src_ptr] "+r"(src_ptr) - : [filter45] "r"(filter45), [vector4a] "r"(vector4a), - [src_stride] "r"(src_stride), [cm] "r"(cm), [dst_ptr] "r"(dst_ptr)); - } - - /* Next row... */ - src += src_stride; - dst += dst_stride; - } -} - -void vpx_convolve2_avg_vert_dspr2(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - const int16_t *const filter_y = filter[y0_q4]; - uint32_t pos = 38; - - assert(y_step_q4 == 16); - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - prefetch_store(dst); - - switch (w) { - case 4: - case 8: - case 16: - case 32: - convolve_bi_avg_vert_4_dspr2(src, src_stride, dst, dst_stride, filter_y, - w, h); - break; - case 64: - prefetch_store(dst + 32); - convolve_bi_avg_vert_64_dspr2(src, src_stride, dst, dst_stride, filter_y, - h); - break; - default: - vpx_convolve8_avg_vert_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve2_avg_horiz_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve2_avg_horiz_dspr2.c deleted file mode 100644 index 7dcb662d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve2_avg_horiz_dspr2.c +++ /dev/null @@ -1,802 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/convolve_common_dspr2.h" -#include "vpx_dsp/vpx_convolve.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_ports/mem.h" - -#if HAVE_DSPR2 -static void convolve_bi_avg_horiz_4_dspr2(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - const int16_t *filter_x0, int32_t h) { - int32_t y; - uint8_t *cm = vpx_ff_cropTbl; - int32_t Temp1, Temp2, Temp3, Temp4; - uint32_t vector4a = 64; - uint32_t tp1, tp2; - uint32_t p1, p2, p3; - uint32_t tn1, tn2; - const int16_t *filter = &filter_x0[3]; - uint32_t filter45; - - filter45 = ((const int32_t *)filter)[0]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_store(dst + dst_stride); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p1], %[tp1] \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "dpa.w.ph $ac3, %[p1], %[filter45] \n\t" - "extp %[Temp1], $ac3, 31 \n\t" - - /* even 2. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "balign %[tp2], %[tp1], 3 \n\t" - "dpa.w.ph $ac2, %[p2], %[filter45] \n\t" - "extp %[Temp3], $ac2, 31 \n\t" - - "lbu %[p2], 3(%[dst]) \n\t" /* load odd 2 */ - - /* odd 1. pixel */ - "lbux %[tp1], %[Temp1](%[cm]) \n\t" /* even 1 */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "lbu %[Temp1], 1(%[dst]) \n\t" /* load odd 1 */ - "preceu.ph.qbr %[p1], %[tp2] \n\t" - "preceu.ph.qbl %[p3], %[tp2] \n\t" - "dpa.w.ph $ac3, %[p1], %[filter45] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - "lbu %[tn2], 0(%[dst]) \n\t" /* load even 1 */ - - /* odd 2. pixel */ - "lbux %[tp2], %[Temp3](%[cm]) \n\t" /* even 2 */ - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "lbux %[tn1], %[Temp2](%[cm]) \n\t" /* odd 1 */ - "addqh_r.w %[tn2], %[tn2], %[tp1] \n\t" /* average even 1 */ - "dpa.w.ph $ac2, %[p3], %[filter45] \n\t" - "extp %[Temp4], $ac2, 31 \n\t" - - "lbu %[tp1], 2(%[dst]) \n\t" /* load even 2 */ - "sb %[tn2], 0(%[dst]) \n\t" /* store even 1 */ - - /* clamp */ - "addqh_r.w %[Temp1], %[Temp1], %[tn1] \n\t" /* average odd 1 */ - "lbux %[p3], %[Temp4](%[cm]) \n\t" /* odd 2 */ - "sb %[Temp1], 1(%[dst]) \n\t" /* store odd 1 */ - - "addqh_r.w %[tp1], %[tp1], %[tp2] \n\t" /* average even 2 */ - "sb %[tp1], 2(%[dst]) \n\t" /* store even 2 */ - - "addqh_r.w %[p2], %[p2], %[p3] \n\t" /* average odd 2 */ - "sb %[p2], 3(%[dst]) \n\t" /* store odd 2 */ - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tn1] "=&r"(tn1), - [tn2] "=&r"(tn2), [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), - [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [Temp4] "=&r"(Temp4) - : [filter45] "r"(filter45), [vector4a] "r"(vector4a), [cm] "r"(cm), - [dst] "r"(dst), [src] "r"(src)); - - /* Next row... */ - src += src_stride; - dst += dst_stride; - } -} - -static void convolve_bi_avg_horiz_8_dspr2(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - const int16_t *filter_x0, int32_t h) { - int32_t y; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector4a = 64; - int32_t Temp1, Temp2, Temp3; - uint32_t tp1, tp2, tp3, tp4; - uint32_t p1, p2, p3, p4, n1; - uint32_t st0, st1; - const int16_t *filter = &filter_x0[3]; - uint32_t filter45; - - filter45 = ((const int32_t *)filter)[0]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_store(dst + dst_stride); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[tp1] \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "preceu.ph.qbr %[p3], %[tp2] \n\t" - "preceu.ph.qbl %[p4], %[tp2] \n\t" - "ulw %[tp3], 8(%[src]) \n\t" - "dpa.w.ph $ac3, %[p1], %[filter45] \n\t" - "extp %[Temp1], $ac3, 31 \n\t" - "lbu %[Temp2], 0(%[dst]) \n\t" - "lbu %[tp4], 2(%[dst]) \n\t" - - /* even 2. pixel */ - "dpa.w.ph $ac2, %[p2], %[filter45] \n\t" - "extp %[Temp3], $ac2, 31 \n\t" - - /* even 3. pixel */ - "lbux %[st0], %[Temp1](%[cm]) \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "lbux %[st1], %[Temp3](%[cm]) \n\t" - "dpa.w.ph $ac1, %[p3], %[filter45] \n\t" - "extp %[Temp1], $ac1, 31 \n\t" - - "addqh_r.w %[Temp2], %[Temp2], %[st0] \n\t" - "addqh_r.w %[tp4], %[tp4], %[st1] \n\t" - "sb %[Temp2], 0(%[dst]) \n\t" - "sb %[tp4], 2(%[dst]) \n\t" - - /* even 4. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "balign %[tp3], %[tp2], 3 \n\t" - "balign %[tp2], %[tp1], 3 \n\t" - - "lbux %[st0], %[Temp1](%[cm]) \n\t" - "lbu %[Temp2], 4(%[dst]) \n\t" - "addqh_r.w %[Temp2], %[Temp2], %[st0] \n\t" - - "dpa.w.ph $ac2, %[p4], %[filter45] \n\t" - "extp %[Temp3], $ac2, 31 \n\t" - - /* odd 1. pixel */ - "mtlo %[vector4a], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "sb %[Temp2], 4(%[dst]) \n\t" - "preceu.ph.qbr %[p1], %[tp2] \n\t" - "preceu.ph.qbl %[p2], %[tp2] \n\t" - "preceu.ph.qbr %[p3], %[tp3] \n\t" - "preceu.ph.qbl %[p4], %[tp3] \n\t" - "dpa.w.ph $ac3, %[p1], %[filter45] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - "lbu %[tp1], 6(%[dst]) \n\t" - - /* odd 2. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "lbux %[st0], %[Temp3](%[cm]) \n\t" - "dpa.w.ph $ac1, %[p2], %[filter45] \n\t" - "extp %[Temp3], $ac1, 31 \n\t" - - "lbu %[tp2], 1(%[dst]) \n\t" - "lbu %[tp3], 3(%[dst]) \n\t" - "addqh_r.w %[tp1], %[tp1], %[st0] \n\t" - - /* odd 3. pixel */ - "lbux %[st1], %[Temp2](%[cm]) \n\t" - "dpa.w.ph $ac3, %[p3], %[filter45] \n\t" - "addqh_r.w %[tp2], %[tp2], %[st1] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - "lbu %[tp4], 5(%[dst]) \n\t" - - /* odd 4. pixel */ - "sb %[tp2], 1(%[dst]) \n\t" - "sb %[tp1], 6(%[dst]) \n\t" - "dpa.w.ph $ac2, %[p4], %[filter45] \n\t" - "extp %[Temp1], $ac2, 31 \n\t" - - "lbu %[tp1], 7(%[dst]) \n\t" - - /* clamp */ - "lbux %[p4], %[Temp3](%[cm]) \n\t" - "addqh_r.w %[tp3], %[tp3], %[p4] \n\t" - - "lbux %[p2], %[Temp2](%[cm]) \n\t" - "addqh_r.w %[tp4], %[tp4], %[p2] \n\t" - - "lbux %[p1], %[Temp1](%[cm]) \n\t" - "addqh_r.w %[tp1], %[tp1], %[p1] \n\t" - - /* store bytes */ - "sb %[tp3], 3(%[dst]) \n\t" - "sb %[tp4], 5(%[dst]) \n\t" - "sb %[tp1], 7(%[dst]) \n\t" - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tp3] "=&r"(tp3), - [tp4] "=&r"(tp4), [st0] "=&r"(st0), [st1] "=&r"(st1), [p1] "=&r"(p1), - [p2] "=&r"(p2), [p3] "=&r"(p3), [p4] "=&r"(p4), [n1] "=&r"(n1), - [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3) - : [filter45] "r"(filter45), [vector4a] "r"(vector4a), [cm] "r"(cm), - [dst] "r"(dst), [src] "r"(src)); - - /* Next row... */ - src += src_stride; - dst += dst_stride; - } -} - -static void convolve_bi_avg_horiz_16_dspr2(const uint8_t *src_ptr, - int32_t src_stride, uint8_t *dst_ptr, - int32_t dst_stride, - const int16_t *filter_x0, int32_t h, - int32_t count) { - int32_t y, c; - const uint8_t *src; - uint8_t *dst; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector_64 = 64; - int32_t Temp1, Temp2, Temp3; - uint32_t qload1, qload2, qload3; - uint32_t p1, p2, p3, p4, p5; - uint32_t st1, st2, st3; - const int16_t *filter = &filter_x0[3]; - uint32_t filter45; - - filter45 = ((const int32_t *)filter)[0]; - - for (y = h; y--;) { - src = src_ptr; - dst = dst_ptr; - - /* prefetch data to cache memory */ - prefetch_load(src_ptr + src_stride); - prefetch_load(src_ptr + src_stride + 32); - prefetch_store(dst_ptr + dst_stride); - - for (c = 0; c < count; c++) { - __asm__ __volatile__( - "ulw %[qload1], 0(%[src]) \n\t" - "ulw %[qload2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 1 */ - "mthi $zero, $ac1 \n\t" - "mtlo %[vector_64], $ac2 \n\t" /* even 2 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[qload1] \n\t" - "preceu.ph.qbl %[p2], %[qload1] \n\t" - "preceu.ph.qbr %[p3], %[qload2] \n\t" - "preceu.ph.qbl %[p4], %[qload2] \n\t" - "ulw %[qload3], 8(%[src]) \n\t" - "dpa.w.ph $ac1, %[p1], %[filter45] \n\t" /* even 1 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 1 */ - "lbu %[st2], 0(%[dst]) \n\t" /* load even 1 from dst */ - - /* even 2. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* even 3 */ - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p1], %[qload3] \n\t" - "preceu.ph.qbl %[p5], %[qload3] \n\t" - "ulw %[qload1], 12(%[src]) \n\t" - "dpa.w.ph $ac2, %[p2], %[filter45] \n\t" /* even 1 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 1 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 1 */ - - "lbu %[qload3], 2(%[dst]) \n\t" /* load even 2 from dst */ - - /* even 3. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 4 */ - "mthi $zero, $ac1 \n\t" - "addqh_r.w %[st2], %[st2], %[st1] \n\t" /* average even 1 */ - "preceu.ph.qbr %[p2], %[qload1] \n\t" - "sb %[st2], 0(%[dst]) \n\t" /* store even 1 to dst */ - "dpa.w.ph $ac3, %[p3], %[filter45] \n\t" /* even 3 */ - "extp %[Temp3], $ac3, 31 \n\t" /* even 3 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 1 */ - - /* even 4. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* even 5 */ - "mthi $zero, $ac2 \n\t" - "addqh_r.w %[qload3], %[qload3], %[st2] \n\t" /* average even 2 */ - "preceu.ph.qbl %[p3], %[qload1] \n\t" - "sb %[qload3], 2(%[dst]) \n\t" /* store even 2 to dst */ - "lbu %[qload3], 4(%[dst]) \n\t" /* load even 3 from dst */ - "lbu %[qload1], 6(%[dst]) \n\t" /* load even 4 from dst */ - "dpa.w.ph $ac1, %[p4], %[filter45] \n\t" /* even 4 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 4 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* even 3 */ - - /* even 5. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* even 6 */ - "mthi $zero, $ac3 \n\t" - "addqh_r.w %[qload3], %[qload3], %[st3] \n\t" /* average even 3 */ - "sb %[qload3], 4(%[dst]) \n\t" /* store even 3 to dst */ - "dpa.w.ph $ac2, %[p1], %[filter45] \n\t" /* even 5 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 5 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 4 */ - - /* even 6. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 7 */ - "mthi $zero, $ac1 \n\t" - "addqh_r.w %[qload1], %[qload1], %[st1] \n\t" /* average even 4 */ - "sb %[qload1], 6(%[dst]) \n\t" /* store even 4 to dst */ - "dpa.w.ph $ac3, %[p5], %[filter45] \n\t" /* even 6 */ - "lbu %[qload2], 8(%[dst]) \n\t" /* load even 5 from dst */ - "extp %[Temp3], $ac3, 31 \n\t" /* even 6 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 5 */ - - /* even 7. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* even 8 */ - "mthi $zero, $ac2 \n\t" - "addqh_r.w %[qload2], %[qload2], %[st2] \n\t" /* average even 5 */ - "sb %[qload2], 8(%[dst]) \n\t" /* store even 5 to dst */ - "dpa.w.ph $ac1, %[p2], %[filter45] \n\t" /* even 7 */ - "lbu %[qload3], 10(%[dst]) \n\t" /* load even 6 from dst */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 7 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* even 6 */ - - "lbu %[st2], 12(%[dst]) \n\t" /* load even 7 from dst */ - - /* even 8. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 1 */ - "mthi $zero, $ac3 \n\t" - "addqh_r.w %[qload3], %[qload3], %[st3] \n\t" /* average even 6 */ - "dpa.w.ph $ac2, %[p3], %[filter45] \n\t" /* even 8 */ - "sb %[qload3], 10(%[dst]) \n\t" /* store even 6 to dst */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 8 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 7 */ - - /* ODD pixels */ - "ulw %[qload1], 1(%[src]) \n\t" - "ulw %[qload2], 5(%[src]) \n\t" - - "addqh_r.w %[st2], %[st2], %[st1] \n\t" /* average even 7 */ - - /* odd 1. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 2 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p1], %[qload1] \n\t" - "preceu.ph.qbl %[p2], %[qload1] \n\t" - "preceu.ph.qbr %[p3], %[qload2] \n\t" - "preceu.ph.qbl %[p4], %[qload2] \n\t" - "sb %[st2], 12(%[dst]) \n\t" /* store even 7 to dst */ - "ulw %[qload3], 9(%[src]) \n\t" - "dpa.w.ph $ac3, %[p1], %[filter45] \n\t" /* odd 1 */ - "lbu %[qload2], 14(%[dst]) \n\t" /* load even 8 from dst */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 1 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 8 */ - - "lbu %[st1], 1(%[dst]) \n\t" /* load odd 1 from dst */ - - /* odd 2. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* odd 3 */ - "mthi $zero, $ac2 \n\t" - "addqh_r.w %[qload2], %[qload2], %[st2] \n\t" /* average even 8 */ - "preceu.ph.qbr %[p1], %[qload3] \n\t" - "preceu.ph.qbl %[p5], %[qload3] \n\t" - "sb %[qload2], 14(%[dst]) \n\t" /* store even 8 to dst */ - "ulw %[qload1], 13(%[src]) \n\t" - "dpa.w.ph $ac1, %[p2], %[filter45] \n\t" /* odd 2 */ - "lbu %[qload3], 3(%[dst]) \n\t" /* load odd 2 from dst */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 2 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 1 */ - - /* odd 3. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 4 */ - "mthi $zero, $ac3 \n\t" - "addqh_r.w %[st3], %[st3], %[st1] \n\t" /* average odd 1 */ - "preceu.ph.qbr %[p2], %[qload1] \n\t" - "dpa.w.ph $ac2, %[p3], %[filter45] \n\t" /* odd 3 */ - "sb %[st3], 1(%[dst]) \n\t" /* store odd 1 to dst */ - "extp %[Temp2], $ac2, 31 \n\t" /* odd 3 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 2 */ - - /* odd 4. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 5 */ - "mthi $zero, $ac1 \n\t" - "addqh_r.w %[qload3], %[qload3], %[st1] \n\t" /* average odd 2 */ - "preceu.ph.qbl %[p3], %[qload1] \n\t" - "sb %[qload3], 3(%[dst]) \n\t" /* store odd 2 to dst */ - "lbu %[qload1], 5(%[dst]) \n\t" /* load odd 3 from dst */ - "dpa.w.ph $ac3, %[p4], %[filter45] \n\t" /* odd 4 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 4 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* odd 3 */ - - "lbu %[st1], 7(%[dst]) \n\t" /* load odd 4 from dst */ - - /* odd 5. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* odd 6 */ - "mthi $zero, $ac2 \n\t" - "addqh_r.w %[qload1], %[qload1], %[st2] \n\t" /* average odd 3 */ - "sb %[qload1], 5(%[dst]) \n\t" /* store odd 3 to dst */ - "dpa.w.ph $ac1, %[p1], %[filter45] \n\t" /* odd 5 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 5 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 4 */ - - "lbu %[qload1], 9(%[dst]) \n\t" /* load odd 5 from dst */ - - /* odd 6. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 7 */ - "mthi $zero, $ac3 \n\t" - "addqh_r.w %[st1], %[st1], %[st3] \n\t" /* average odd 4 */ - "sb %[st1], 7(%[dst]) \n\t" /* store odd 4 to dst */ - "dpa.w.ph $ac2, %[p5], %[filter45] \n\t" /* odd 6 */ - "extp %[Temp2], $ac2, 31 \n\t" /* odd 6 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 5 */ - - /* odd 7. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 8 */ - "mthi $zero, $ac1 \n\t" - "addqh_r.w %[qload1], %[qload1], %[st1] \n\t" /* average odd 5 */ - "sb %[qload1], 9(%[dst]) \n\t" /* store odd 5 to dst */ - "lbu %[qload2], 11(%[dst]) \n\t" /* load odd 6 from dst */ - "dpa.w.ph $ac3, %[p2], %[filter45] \n\t" /* odd 7 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 7 */ - - "lbu %[qload3], 13(%[dst]) \n\t" /* load odd 7 from dst */ - - /* odd 8. pixel */ - "dpa.w.ph $ac1, %[p3], %[filter45] \n\t" /* odd 8 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 8 */ - - "lbu %[qload1], 15(%[dst]) \n\t" /* load odd 8 from dst */ - - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* odd 6 */ - "addqh_r.w %[qload2], %[qload2], %[st2] \n\t" /* average odd 6 */ - - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 7 */ - "addqh_r.w %[qload3], %[qload3], %[st3] \n\t" /* average odd 7 */ - - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 8 */ - "addqh_r.w %[qload1], %[qload1], %[st1] \n\t" /* average odd 8 */ - - "sb %[qload2], 11(%[dst]) \n\t" /* store odd 6 to dst */ - "sb %[qload3], 13(%[dst]) \n\t" /* store odd 7 to dst */ - "sb %[qload1], 15(%[dst]) \n\t" /* store odd 8 to dst */ - - : [qload1] "=&r"(qload1), [qload2] "=&r"(qload2), [st1] "=&r"(st1), - [st2] "=&r"(st2), [st3] "=&r"(st3), [p1] "=&r"(p1), [p2] "=&r"(p2), - [p3] "=&r"(p3), [p4] "=&r"(p4), [qload3] "=&r"(qload3), - [p5] "=&r"(p5), [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), - [Temp3] "=&r"(Temp3) - : [filter45] "r"(filter45), [vector_64] "r"(vector_64), [cm] "r"(cm), - [dst] "r"(dst), [src] "r"(src)); - - src += 16; - dst += 16; - } - - /* Next row... */ - src_ptr += src_stride; - dst_ptr += dst_stride; - } -} - -static void convolve_bi_avg_horiz_64_dspr2(const uint8_t *src_ptr, - int32_t src_stride, uint8_t *dst_ptr, - int32_t dst_stride, - const int16_t *filter_x0, - int32_t h) { - int32_t y, c; - const uint8_t *src; - uint8_t *dst; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector_64 = 64; - int32_t Temp1, Temp2, Temp3; - uint32_t qload1, qload2, qload3; - uint32_t p1, p2, p3, p4, p5; - uint32_t st1, st2, st3; - const int16_t *filter = &filter_x0[3]; - uint32_t filter45; - - filter45 = ((const int32_t *)filter)[0]; - - for (y = h; y--;) { - src = src_ptr; - dst = dst_ptr; - - /* prefetch data to cache memory */ - prefetch_load(src_ptr + src_stride); - prefetch_load(src_ptr + src_stride + 32); - prefetch_load(src_ptr + src_stride + 64); - prefetch_store(dst_ptr + dst_stride); - prefetch_store(dst_ptr + dst_stride + 32); - - for (c = 0; c < 4; c++) { - __asm__ __volatile__( - "ulw %[qload1], 0(%[src]) \n\t" - "ulw %[qload2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 1 */ - "mthi $zero, $ac1 \n\t" - "mtlo %[vector_64], $ac2 \n\t" /* even 2 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[qload1] \n\t" - "preceu.ph.qbl %[p2], %[qload1] \n\t" - "preceu.ph.qbr %[p3], %[qload2] \n\t" - "preceu.ph.qbl %[p4], %[qload2] \n\t" - "ulw %[qload3], 8(%[src]) \n\t" - "dpa.w.ph $ac1, %[p1], %[filter45] \n\t" /* even 1 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 1 */ - "lbu %[st2], 0(%[dst]) \n\t" /* load even 1 from dst */ - - /* even 2. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* even 3 */ - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p1], %[qload3] \n\t" - "preceu.ph.qbl %[p5], %[qload3] \n\t" - "ulw %[qload1], 12(%[src]) \n\t" - "dpa.w.ph $ac2, %[p2], %[filter45] \n\t" /* even 1 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 1 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 1 */ - - "lbu %[qload3], 2(%[dst]) \n\t" /* load even 2 from dst */ - - /* even 3. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 4 */ - "mthi $zero, $ac1 \n\t" - "addqh_r.w %[st2], %[st2], %[st1] \n\t" /* average even 1 */ - "preceu.ph.qbr %[p2], %[qload1] \n\t" - "sb %[st2], 0(%[dst]) \n\t" /* store even 1 to dst */ - "dpa.w.ph $ac3, %[p3], %[filter45] \n\t" /* even 3 */ - "extp %[Temp3], $ac3, 31 \n\t" /* even 3 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 1 */ - - /* even 4. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* even 5 */ - "mthi $zero, $ac2 \n\t" - "addqh_r.w %[qload3], %[qload3], %[st2] \n\t" /* average even 2 */ - "preceu.ph.qbl %[p3], %[qload1] \n\t" - "sb %[qload3], 2(%[dst]) \n\t" /* store even 2 to dst */ - "lbu %[qload3], 4(%[dst]) \n\t" /* load even 3 from dst */ - "lbu %[qload1], 6(%[dst]) \n\t" /* load even 4 from dst */ - "dpa.w.ph $ac1, %[p4], %[filter45] \n\t" /* even 4 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 4 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* even 3 */ - - /* even 5. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* even 6 */ - "mthi $zero, $ac3 \n\t" - "addqh_r.w %[qload3], %[qload3], %[st3] \n\t" /* average even 3 */ - "sb %[qload3], 4(%[dst]) \n\t" /* store even 3 to dst */ - "dpa.w.ph $ac2, %[p1], %[filter45] \n\t" /* even 5 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 5 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 4 */ - - /* even 6. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 7 */ - "mthi $zero, $ac1 \n\t" - "addqh_r.w %[qload1], %[qload1], %[st1] \n\t" /* average even 4 */ - "sb %[qload1], 6(%[dst]) \n\t" /* store even 4 to dst */ - "dpa.w.ph $ac3, %[p5], %[filter45] \n\t" /* even 6 */ - "lbu %[qload2], 8(%[dst]) \n\t" /* load even 5 from dst */ - "extp %[Temp3], $ac3, 31 \n\t" /* even 6 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 5 */ - - /* even 7. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* even 8 */ - "mthi $zero, $ac2 \n\t" - "addqh_r.w %[qload2], %[qload2], %[st2] \n\t" /* average even 5 */ - "sb %[qload2], 8(%[dst]) \n\t" /* store even 5 to dst */ - "dpa.w.ph $ac1, %[p2], %[filter45] \n\t" /* even 7 */ - "lbu %[qload3], 10(%[dst]) \n\t" /* load even 6 from dst */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 7 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* even 6 */ - - "lbu %[st2], 12(%[dst]) \n\t" /* load even 7 from dst */ - - /* even 8. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 1 */ - "mthi $zero, $ac3 \n\t" - "addqh_r.w %[qload3], %[qload3], %[st3] \n\t" /* average even 6 */ - "dpa.w.ph $ac2, %[p3], %[filter45] \n\t" /* even 8 */ - "sb %[qload3], 10(%[dst]) \n\t" /* store even 6 to dst */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 8 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 7 */ - - /* ODD pixels */ - "ulw %[qload1], 1(%[src]) \n\t" - "ulw %[qload2], 5(%[src]) \n\t" - - "addqh_r.w %[st2], %[st2], %[st1] \n\t" /* average even 7 */ - - /* odd 1. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 2 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p1], %[qload1] \n\t" - "preceu.ph.qbl %[p2], %[qload1] \n\t" - "preceu.ph.qbr %[p3], %[qload2] \n\t" - "preceu.ph.qbl %[p4], %[qload2] \n\t" - "sb %[st2], 12(%[dst]) \n\t" /* store even 7 to dst */ - "ulw %[qload3], 9(%[src]) \n\t" - "dpa.w.ph $ac3, %[p1], %[filter45] \n\t" /* odd 1 */ - "lbu %[qload2], 14(%[dst]) \n\t" /* load even 8 from dst */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 1 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 8 */ - - "lbu %[st1], 1(%[dst]) \n\t" /* load odd 1 from dst */ - - /* odd 2. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* odd 3 */ - "mthi $zero, $ac2 \n\t" - "addqh_r.w %[qload2], %[qload2], %[st2] \n\t" /* average even 8 */ - "preceu.ph.qbr %[p1], %[qload3] \n\t" - "preceu.ph.qbl %[p5], %[qload3] \n\t" - "sb %[qload2], 14(%[dst]) \n\t" /* store even 8 to dst */ - "ulw %[qload1], 13(%[src]) \n\t" - "dpa.w.ph $ac1, %[p2], %[filter45] \n\t" /* odd 2 */ - "lbu %[qload3], 3(%[dst]) \n\t" /* load odd 2 from dst */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 2 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 1 */ - - /* odd 3. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 4 */ - "mthi $zero, $ac3 \n\t" - "addqh_r.w %[st3], %[st3], %[st1] \n\t" /* average odd 1 */ - "preceu.ph.qbr %[p2], %[qload1] \n\t" - "dpa.w.ph $ac2, %[p3], %[filter45] \n\t" /* odd 3 */ - "sb %[st3], 1(%[dst]) \n\t" /* store odd 1 to dst */ - "extp %[Temp2], $ac2, 31 \n\t" /* odd 3 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 2 */ - - /* odd 4. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 5 */ - "mthi $zero, $ac1 \n\t" - "addqh_r.w %[qload3], %[qload3], %[st1] \n\t" /* average odd 2 */ - "preceu.ph.qbl %[p3], %[qload1] \n\t" - "sb %[qload3], 3(%[dst]) \n\t" /* store odd 2 to dst */ - "lbu %[qload1], 5(%[dst]) \n\t" /* load odd 3 from dst */ - "dpa.w.ph $ac3, %[p4], %[filter45] \n\t" /* odd 4 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 4 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* odd 3 */ - - "lbu %[st1], 7(%[dst]) \n\t" /* load odd 4 from dst */ - - /* odd 5. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* odd 6 */ - "mthi $zero, $ac2 \n\t" - "addqh_r.w %[qload1], %[qload1], %[st2] \n\t" /* average odd 3 */ - "sb %[qload1], 5(%[dst]) \n\t" /* store odd 3 to dst */ - "dpa.w.ph $ac1, %[p1], %[filter45] \n\t" /* odd 5 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 5 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 4 */ - - "lbu %[qload1], 9(%[dst]) \n\t" /* load odd 5 from dst */ - - /* odd 6. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 7 */ - "mthi $zero, $ac3 \n\t" - "addqh_r.w %[st1], %[st1], %[st3] \n\t" /* average odd 4 */ - "sb %[st1], 7(%[dst]) \n\t" /* store odd 4 to dst */ - "dpa.w.ph $ac2, %[p5], %[filter45] \n\t" /* odd 6 */ - "extp %[Temp2], $ac2, 31 \n\t" /* odd 6 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 5 */ - - /* odd 7. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 8 */ - "mthi $zero, $ac1 \n\t" - "addqh_r.w %[qload1], %[qload1], %[st1] \n\t" /* average odd 5 */ - "sb %[qload1], 9(%[dst]) \n\t" /* store odd 5 to dst */ - "lbu %[qload2], 11(%[dst]) \n\t" /* load odd 6 from dst */ - "dpa.w.ph $ac3, %[p2], %[filter45] \n\t" /* odd 7 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 7 */ - - "lbu %[qload3], 13(%[dst]) \n\t" /* load odd 7 from dst */ - - /* odd 8. pixel */ - "dpa.w.ph $ac1, %[p3], %[filter45] \n\t" /* odd 8 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 8 */ - - "lbu %[qload1], 15(%[dst]) \n\t" /* load odd 8 from dst */ - - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* odd 6 */ - "addqh_r.w %[qload2], %[qload2], %[st2] \n\t" /* average odd 6 */ - - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 7 */ - "addqh_r.w %[qload3], %[qload3], %[st3] \n\t" /* average odd 7 */ - - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 8 */ - "addqh_r.w %[qload1], %[qload1], %[st1] \n\t" /* average odd 8 */ - - "sb %[qload2], 11(%[dst]) \n\t" /* store odd 6 to dst */ - "sb %[qload3], 13(%[dst]) \n\t" /* store odd 7 to dst */ - "sb %[qload1], 15(%[dst]) \n\t" /* store odd 8 to dst */ - - : [qload1] "=&r"(qload1), [qload2] "=&r"(qload2), [st1] "=&r"(st1), - [st2] "=&r"(st2), [st3] "=&r"(st3), [p1] "=&r"(p1), [p2] "=&r"(p2), - [p3] "=&r"(p3), [p4] "=&r"(p4), [qload3] "=&r"(qload3), - [p5] "=&r"(p5), [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), - [Temp3] "=&r"(Temp3) - : [filter45] "r"(filter45), [vector_64] "r"(vector_64), [cm] "r"(cm), - [dst] "r"(dst), [src] "r"(src)); - - src += 16; - dst += 16; - } - - /* Next row... */ - src_ptr += src_stride; - dst_ptr += dst_stride; - } -} - -void vpx_convolve2_avg_horiz_dspr2(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - const int16_t *const filter_x = filter[x0_q4]; - uint32_t pos = 38; - - assert(x_step_q4 == 16); - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - /* prefetch data to cache memory */ - prefetch_load(src); - prefetch_load(src + 32); - prefetch_store(dst); - - switch (w) { - case 4: - convolve_bi_avg_horiz_4_dspr2(src, src_stride, dst, dst_stride, filter_x, - h); - break; - case 8: - convolve_bi_avg_horiz_8_dspr2(src, src_stride, dst, dst_stride, filter_x, - h); - break; - case 16: - convolve_bi_avg_horiz_16_dspr2(src, src_stride, dst, dst_stride, filter_x, - h, 1); - break; - case 32: - convolve_bi_avg_horiz_16_dspr2(src, src_stride, dst, dst_stride, filter_x, - h, 2); - break; - case 64: - prefetch_load(src + 64); - prefetch_store(dst + 32); - - convolve_bi_avg_horiz_64_dspr2(src, src_stride, dst, dst_stride, filter_x, - h); - break; - default: - vpx_convolve8_avg_horiz_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve2_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve2_dspr2.c deleted file mode 100644 index e355ba3a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve2_dspr2.c +++ /dev/null @@ -1,1029 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/convolve_common_dspr2.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_ports/mem.h" - -#if HAVE_DSPR2 -static void convolve_bi_horiz_4_transposed_dspr2( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int16_t *filter_x0, int32_t h) { - int32_t y; - uint8_t *cm = vpx_ff_cropTbl; - uint8_t *dst_ptr; - int32_t Temp1, Temp2; - uint32_t vector4a = 64; - uint32_t tp1, tp2; - uint32_t p1, p2; - const int16_t *filter = &filter_x0[3]; - uint32_t filter45; - - filter45 = ((const int32_t *)filter)[0]; - - for (y = h; y--;) { - dst_ptr = dst; - /* prefetch data to cache memory */ - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p1], %[tp1] \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "dpa.w.ph $ac3, %[p1], %[filter45] \n\t" - "extp %[Temp1], $ac3, 31 \n\t" - - /* even 2. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "balign %[tp2], %[tp1], 3 \n\t" - "dpa.w.ph $ac2, %[p2], %[filter45] \n\t" - "extp %[Temp2], $ac2, 31 \n\t" - - /* odd 1. pixel */ - "lbux %[tp1], %[Temp1](%[cm]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p1], %[tp2] \n\t" - "preceu.ph.qbl %[p2], %[tp2] \n\t" - "dpa.w.ph $ac3, %[p1], %[filter45] \n\t" - "extp %[Temp1], $ac3, 31 \n\t" - - /* odd 2. pixel */ - "lbux %[tp2], %[Temp2](%[cm]) \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "dpa.w.ph $ac2, %[p2], %[filter45] \n\t" - "extp %[Temp2], $ac2, 31 \n\t" - - /* clamp */ - "lbux %[p1], %[Temp1](%[cm]) \n\t" - "lbux %[p2], %[Temp2](%[cm]) \n\t" - - /* store bytes */ - "sb %[tp1], 0(%[dst_ptr]) \n\t" - "addu %[dst_ptr], %[dst_ptr], %[dst_stride] \n\t" - - "sb %[p1], 0(%[dst_ptr]) \n\t" - "addu %[dst_ptr], %[dst_ptr], %[dst_stride] \n\t" - - "sb %[tp2], 0(%[dst_ptr]) \n\t" - "addu %[dst_ptr], %[dst_ptr], %[dst_stride] \n\t" - - "sb %[p2], 0(%[dst_ptr]) \n\t" - "addu %[dst_ptr], %[dst_ptr], %[dst_stride] \n\t" - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [p1] "=&r"(p1), [p2] "=&r"(p2), - [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [dst_ptr] "+r"(dst_ptr) - : [filter45] "r"(filter45), [vector4a] "r"(vector4a), [cm] "r"(cm), - [src] "r"(src), [dst_stride] "r"(dst_stride)); - - /* Next row... */ - src += src_stride; - dst += 1; - } -} - -static void convolve_bi_horiz_8_transposed_dspr2( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - const int16_t *filter_x0, int32_t h) { - int32_t y; - uint8_t *cm = vpx_ff_cropTbl; - uint8_t *dst_ptr; - uint32_t vector4a = 64; - int32_t Temp1, Temp2, Temp3; - uint32_t tp1, tp2, tp3; - uint32_t p1, p2, p3, p4; - uint8_t *odd_dst; - uint32_t dst_pitch_2 = (dst_stride << 1); - const int16_t *filter = &filter_x0[3]; - uint32_t filter45; - - filter45 = ((const int32_t *)filter)[0]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - - dst_ptr = dst; - odd_dst = (dst_ptr + dst_stride); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[tp1] \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "preceu.ph.qbr %[p3], %[tp2] \n\t" - "preceu.ph.qbl %[p4], %[tp2] \n\t" - "ulw %[tp3], 8(%[src]) \n\t" - "dpa.w.ph $ac3, %[p1], %[filter45] \n\t" - "extp %[Temp1], $ac3, 31 \n\t" - - /* even 2. pixel */ - "dpa.w.ph $ac2, %[p2], %[filter45] \n\t" - "extp %[Temp3], $ac2, 31 \n\t" - - /* even 3. pixel */ - "lbux %[Temp2], %[Temp1](%[cm]) \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "balign %[tp3], %[tp2], 3 \n\t" - "balign %[tp2], %[tp1], 3 \n\t" - "dpa.w.ph $ac1, %[p3], %[filter45] \n\t" - "lbux %[tp1], %[Temp3](%[cm]) \n\t" - "extp %[p3], $ac1, 31 \n\t" - - /* even 4. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "sb %[Temp2], 0(%[dst_ptr]) \n\t" - "addu %[dst_ptr], %[dst_ptr], %[dst_pitch_2] \n\t" - "sb %[tp1], 0(%[dst_ptr]) \n\t" - "addu %[dst_ptr], %[dst_ptr], %[dst_pitch_2] \n\t" - - "dpa.w.ph $ac2, %[p4], %[filter45] \n\t" - "extp %[Temp3], $ac2, 31 \n\t" - - "lbux %[Temp1], %[p3](%[cm]) " - "\n\t" - - /* odd 1. pixel */ - "mtlo %[vector4a], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p1], %[tp2] \n\t" - "preceu.ph.qbl %[p2], %[tp2] \n\t" - "preceu.ph.qbr %[p3], %[tp3] \n\t" - "preceu.ph.qbl %[p4], %[tp3] \n\t" - "sb %[Temp1], 0(%[dst_ptr]) \n\t" - "addu %[dst_ptr], %[dst_ptr], %[dst_pitch_2] \n\t" - - "dpa.w.ph $ac3, %[p1], %[filter45] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - /* odd 2. pixel */ - "lbux %[tp1], %[Temp3](%[cm]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "dpa.w.ph $ac1, %[p2], %[filter45] \n\t" - "sb %[tp1], 0(%[dst_ptr]) \n\t" - "addu %[dst_ptr], %[dst_ptr], %[dst_pitch_2] \n\t" - "extp %[Temp3], $ac1, 31 \n\t" - - /* odd 3. pixel */ - "lbux %[tp3], %[Temp2](%[cm]) \n\t" - "dpa.w.ph $ac3, %[p3], %[filter45] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - /* odd 4. pixel */ - "sb %[tp3], 0(%[odd_dst]) \n\t" - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] \n\t" - "dpa.w.ph $ac2, %[p4], %[filter45] \n\t" - "extp %[Temp1], $ac2, 31 \n\t" - - /* clamp */ - "lbux %[p4], %[Temp3](%[cm]) \n\t" - "lbux %[p2], %[Temp2](%[cm]) \n\t" - "lbux %[p1], %[Temp1](%[cm]) \n\t" - - /* store bytes */ - "sb %[p4], 0(%[odd_dst]) \n\t" - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] \n\t" - - "sb %[p2], 0(%[odd_dst]) \n\t" - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] \n\t" - - "sb %[p1], 0(%[odd_dst]) \n\t" - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tp3] "=&r"(tp3), [p1] "=&r"(p1), - [p2] "=&r"(p2), [p3] "=&r"(p3), [p4] "=&r"(p4), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), [dst_ptr] "+r"(dst_ptr), - [odd_dst] "+r"(odd_dst) - : [filter45] "r"(filter45), [vector4a] "r"(vector4a), [cm] "r"(cm), - [src] "r"(src), [dst_pitch_2] "r"(dst_pitch_2)); - - /* Next row... */ - src += src_stride; - dst += 1; - } -} - -static void convolve_bi_horiz_16_transposed_dspr2( - const uint8_t *src_ptr, int32_t src_stride, uint8_t *dst_ptr, - int32_t dst_stride, const int16_t *filter_x0, int32_t h, int32_t count) { - int32_t c, y; - const uint8_t *src; - uint8_t *dst; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector_64 = 64; - int32_t Temp1, Temp2, Temp3; - uint32_t qload1, qload2; - uint32_t p1, p2, p3, p4, p5; - uint32_t st1, st2, st3; - uint32_t dst_pitch_2 = (dst_stride << 1); - uint8_t *odd_dst; - const int16_t *filter = &filter_x0[3]; - uint32_t filter45; - - filter45 = ((const int32_t *)filter)[0]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_load(src_ptr + src_stride); - prefetch_load(src_ptr + src_stride + 32); - - src = src_ptr; - dst = dst_ptr; - - odd_dst = (dst + dst_stride); - - for (c = 0; c < count; c++) { - __asm__ __volatile__( - "ulw %[qload1], 0(%[src]) " - "\n\t" - "ulw %[qload2], 4(%[src]) " - "\n\t" - - /* even 1. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* even 1 */ - "mthi $zero, $ac1 " - "\n\t" - "mtlo %[vector_64], $ac2 " - "\n\t" /* even 2 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbr %[p1], %[qload1] " - "\n\t" - "preceu.ph.qbl %[p2], %[qload1] " - "\n\t" - "preceu.ph.qbr %[p3], %[qload2] " - "\n\t" - "preceu.ph.qbl %[p4], %[qload2] " - "\n\t" - "ulw %[qload1], 8(%[src]) " - "\n\t" - "dpa.w.ph $ac1, %[p1], %[filter45] " - "\n\t" /* even 1 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* even 1 */ - - /* even 2. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* even 3 */ - "mthi $zero, $ac3 " - "\n\t" - "preceu.ph.qbr %[p1], %[qload1] " - "\n\t" - "preceu.ph.qbl %[p5], %[qload1] " - "\n\t" - "ulw %[qload2], 12(%[src]) " - "\n\t" - "dpa.w.ph $ac2, %[p2], %[filter45] " - "\n\t" /* even 1 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* even 1 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* even 1 */ - - /* even 3. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* even 4 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbr %[p2], %[qload2] " - "\n\t" - "sb %[st1], 0(%[dst]) " - "\n\t" /* even 1 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - " \n\t" - "dpa.w.ph $ac3, %[p3], %[filter45] " - "\n\t" /* even 3 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* even 3 */ - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* even 1 */ - - /* even 4. pixel */ - "mtlo %[vector_64], $ac2 " - "\n\t" /* even 5 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbl %[p3], %[qload2] " - "\n\t" - "sb %[st2], 0(%[dst]) " - "\n\t" /* even 2 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac1, %[p4], %[filter45] " - "\n\t" /* even 4 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* even 4 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* even 3 */ - - /* even 5. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* even 6 */ - "mthi $zero, $ac3 " - "\n\t" - "sb %[st3], 0(%[dst]) " - "\n\t" /* even 3 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac2, %[p1], %[filter45] " - "\n\t" /* even 5 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* even 5 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* even 4 */ - - /* even 6. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* even 7 */ - "mthi $zero, $ac1 " - "\n\t" - "sb %[st1], 0(%[dst]) " - "\n\t" /* even 4 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "ulw %[qload1], 20(%[src]) " - "\n\t" - "dpa.w.ph $ac3, %[p5], %[filter45] " - "\n\t" /* even 6 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* even 6 */ - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* even 5 */ - - /* even 7. pixel */ - "mtlo %[vector_64], $ac2 " - "\n\t" /* even 8 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbr %[p5], %[qload1] " - "\n\t" - "sb %[st2], 0(%[dst]) " - "\n\t" /* even 5 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac1, %[p2], %[filter45] " - "\n\t" /* even 7 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* even 7 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* even 6 */ - - /* even 8. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* odd 1 */ - "mthi $zero, $ac3 " - "\n\t" - "dpa.w.ph $ac2, %[p3], %[filter45] " - "\n\t" /* even 8 */ - "sb %[st3], 0(%[dst]) " - "\n\t" /* even 6 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "extp %[Temp2], $ac2, 31 " - "\n\t" /* even 8 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* even 7 */ - - /* ODD pixels */ - "ulw %[qload1], 1(%[src]) " - "\n\t" - "ulw %[qload2], 5(%[src]) " - "\n\t" - - /* odd 1. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* odd 2 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbr %[p1], %[qload1] " - "\n\t" - "preceu.ph.qbl %[p2], %[qload1] " - "\n\t" - "preceu.ph.qbr %[p3], %[qload2] " - "\n\t" - "preceu.ph.qbl %[p4], %[qload2] " - "\n\t" - "sb %[st1], 0(%[dst]) " - "\n\t" /* even 7 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "ulw %[qload2], 9(%[src]) " - "\n\t" - "dpa.w.ph $ac3, %[p1], %[filter45] " - "\n\t" /* odd 1 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* odd 1 */ - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* even 8 */ - - /* odd 2. pixel */ - "mtlo %[vector_64], $ac2 " - "\n\t" /* odd 3 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbr %[p1], %[qload2] " - "\n\t" - "preceu.ph.qbl %[p5], %[qload2] " - "\n\t" - "sb %[st2], 0(%[dst]) " - "\n\t" /* even 8 */ - "ulw %[qload1], 13(%[src]) " - "\n\t" - "dpa.w.ph $ac1, %[p2], %[filter45] " - "\n\t" /* odd 2 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* odd 2 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* odd 1 */ - - /* odd 3. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* odd 4 */ - "mthi $zero, $ac3 " - "\n\t" - "preceu.ph.qbr %[p2], %[qload1] " - "\n\t" - "sb %[st3], 0(%[odd_dst]) " - "\n\t" /* odd 1 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac2, %[p3], %[filter45] " - "\n\t" /* odd 3 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* odd 3 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* odd 2 */ - - /* odd 4. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* odd 5 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbl %[p3], %[qload1] " - "\n\t" - "sb %[st1], 0(%[odd_dst]) " - "\n\t" /* odd 2 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac3, %[p4], %[filter45] " - "\n\t" /* odd 4 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* odd 4 */ - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* odd 3 */ - - /* odd 5. pixel */ - "mtlo %[vector_64], $ac2 " - "\n\t" /* odd 6 */ - "mthi $zero, $ac2 " - "\n\t" - "sb %[st2], 0(%[odd_dst]) " - "\n\t" /* odd 3 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac1, %[p1], %[filter45] " - "\n\t" /* odd 5 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* odd 5 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* odd 4 */ - - /* odd 6. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* odd 7 */ - "mthi $zero, $ac3 " - "\n\t" - "sb %[st3], 0(%[odd_dst]) " - "\n\t" /* odd 4 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "ulw %[qload1], 21(%[src]) " - "\n\t" - "dpa.w.ph $ac2, %[p5], %[filter45] " - "\n\t" /* odd 6 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* odd 6 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* odd 5 */ - - /* odd 7. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* odd 8 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbr %[p5], %[qload1] " - "\n\t" - "sb %[st1], 0(%[odd_dst]) " - "\n\t" /* odd 5 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac3, %[p2], %[filter45] " - "\n\t" /* odd 7 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* odd 7 */ - - /* odd 8. pixel */ - "dpa.w.ph $ac1, %[p3], %[filter45] " - "\n\t" /* odd 8 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* odd 8 */ - - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* odd 6 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* odd 7 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* odd 8 */ - - "sb %[st2], 0(%[odd_dst]) " - "\n\t" /* odd 6 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - - "sb %[st3], 0(%[odd_dst]) " - "\n\t" /* odd 7 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - - "sb %[st1], 0(%[odd_dst]) " - "\n\t" /* odd 8 */ - - : [qload1] "=&r"(qload1), [qload2] "=&r"(qload2), [p5] "=&r"(p5), - [st1] "=&r"(st1), [st2] "=&r"(st2), [st3] "=&r"(st3), - [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), [p4] "=&r"(p4), - [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [dst] "+r"(dst), [odd_dst] "+r"(odd_dst) - : [filter45] "r"(filter45), [vector_64] "r"(vector_64), [cm] "r"(cm), - [src] "r"(src), [dst_pitch_2] "r"(dst_pitch_2)); - - src += 16; - dst = (dst_ptr + ((c + 1) * 16 * dst_stride)); - odd_dst = (dst + dst_stride); - } - - /* Next row... */ - src_ptr += src_stride; - dst_ptr += 1; - } -} - -static void convolve_bi_horiz_64_transposed_dspr2( - const uint8_t *src_ptr, int32_t src_stride, uint8_t *dst_ptr, - int32_t dst_stride, const int16_t *filter_x0, int32_t h) { - int32_t c, y; - const uint8_t *src; - uint8_t *dst; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector_64 = 64; - int32_t Temp1, Temp2, Temp3; - uint32_t qload1, qload2; - uint32_t p1, p2, p3, p4, p5; - uint32_t st1, st2, st3; - uint32_t dst_pitch_2 = (dst_stride << 1); - uint8_t *odd_dst; - const int16_t *filter = &filter_x0[3]; - uint32_t filter45; - - filter45 = ((const int32_t *)filter)[0]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_load(src_ptr + src_stride); - prefetch_load(src_ptr + src_stride + 32); - prefetch_load(src_ptr + src_stride + 64); - - src = src_ptr; - dst = dst_ptr; - - odd_dst = (dst + dst_stride); - - for (c = 0; c < 4; c++) { - __asm__ __volatile__( - "ulw %[qload1], 0(%[src]) " - "\n\t" - "ulw %[qload2], 4(%[src]) " - "\n\t" - - /* even 1. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* even 1 */ - "mthi $zero, $ac1 " - "\n\t" - "mtlo %[vector_64], $ac2 " - "\n\t" /* even 2 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbr %[p1], %[qload1] " - "\n\t" - "preceu.ph.qbl %[p2], %[qload1] " - "\n\t" - "preceu.ph.qbr %[p3], %[qload2] " - "\n\t" - "preceu.ph.qbl %[p4], %[qload2] " - "\n\t" - "ulw %[qload1], 8(%[src]) " - "\n\t" - "dpa.w.ph $ac1, %[p1], %[filter45] " - "\n\t" /* even 1 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* even 1 */ - - /* even 2. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* even 3 */ - "mthi $zero, $ac3 " - "\n\t" - "preceu.ph.qbr %[p1], %[qload1] " - "\n\t" - "preceu.ph.qbl %[p5], %[qload1] " - "\n\t" - "ulw %[qload2], 12(%[src]) " - "\n\t" - "dpa.w.ph $ac2, %[p2], %[filter45] " - "\n\t" /* even 1 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* even 1 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* even 1 */ - - /* even 3. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* even 4 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbr %[p2], %[qload2] " - "\n\t" - "sb %[st1], 0(%[dst]) " - "\n\t" /* even 1 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - " \n\t" - "dpa.w.ph $ac3, %[p3], %[filter45] " - "\n\t" /* even 3 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* even 3 */ - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* even 1 */ - - /* even 4. pixel */ - "mtlo %[vector_64], $ac2 " - "\n\t" /* even 5 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbl %[p3], %[qload2] " - "\n\t" - "sb %[st2], 0(%[dst]) " - "\n\t" /* even 2 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac1, %[p4], %[filter45] " - "\n\t" /* even 4 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* even 4 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* even 3 */ - - /* even 5. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* even 6 */ - "mthi $zero, $ac3 " - "\n\t" - "sb %[st3], 0(%[dst]) " - "\n\t" /* even 3 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac2, %[p1], %[filter45] " - "\n\t" /* even 5 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* even 5 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* even 4 */ - - /* even 6. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* even 7 */ - "mthi $zero, $ac1 " - "\n\t" - "sb %[st1], 0(%[dst]) " - "\n\t" /* even 4 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "ulw %[qload1], 20(%[src]) " - "\n\t" - "dpa.w.ph $ac3, %[p5], %[filter45] " - "\n\t" /* even 6 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* even 6 */ - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* even 5 */ - - /* even 7. pixel */ - "mtlo %[vector_64], $ac2 " - "\n\t" /* even 8 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbr %[p5], %[qload1] " - "\n\t" - "sb %[st2], 0(%[dst]) " - "\n\t" /* even 5 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac1, %[p2], %[filter45] " - "\n\t" /* even 7 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* even 7 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* even 6 */ - - /* even 8. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* odd 1 */ - "mthi $zero, $ac3 " - "\n\t" - "dpa.w.ph $ac2, %[p3], %[filter45] " - "\n\t" /* even 8 */ - "sb %[st3], 0(%[dst]) " - "\n\t" /* even 6 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "extp %[Temp2], $ac2, 31 " - "\n\t" /* even 8 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* even 7 */ - - /* ODD pixels */ - "ulw %[qload1], 1(%[src]) " - "\n\t" - "ulw %[qload2], 5(%[src]) " - "\n\t" - - /* odd 1. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* odd 2 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbr %[p1], %[qload1] " - "\n\t" - "preceu.ph.qbl %[p2], %[qload1] " - "\n\t" - "preceu.ph.qbr %[p3], %[qload2] " - "\n\t" - "preceu.ph.qbl %[p4], %[qload2] " - "\n\t" - "sb %[st1], 0(%[dst]) " - "\n\t" /* even 7 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "ulw %[qload2], 9(%[src]) " - "\n\t" - "dpa.w.ph $ac3, %[p1], %[filter45] " - "\n\t" /* odd 1 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* odd 1 */ - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* even 8 */ - - /* odd 2. pixel */ - "mtlo %[vector_64], $ac2 " - "\n\t" /* odd 3 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbr %[p1], %[qload2] " - "\n\t" - "preceu.ph.qbl %[p5], %[qload2] " - "\n\t" - "sb %[st2], 0(%[dst]) " - "\n\t" /* even 8 */ - "ulw %[qload1], 13(%[src]) " - "\n\t" - "dpa.w.ph $ac1, %[p2], %[filter45] " - "\n\t" /* odd 2 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* odd 2 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* odd 1 */ - - /* odd 3. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* odd 4 */ - "mthi $zero, $ac3 " - "\n\t" - "preceu.ph.qbr %[p2], %[qload1] " - "\n\t" - "sb %[st3], 0(%[odd_dst]) " - "\n\t" /* odd 1 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac2, %[p3], %[filter45] " - "\n\t" /* odd 3 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* odd 3 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* odd 2 */ - - /* odd 4. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* odd 5 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbl %[p3], %[qload1] " - "\n\t" - "sb %[st1], 0(%[odd_dst]) " - "\n\t" /* odd 2 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac3, %[p4], %[filter45] " - "\n\t" /* odd 4 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* odd 4 */ - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* odd 3 */ - - /* odd 5. pixel */ - "mtlo %[vector_64], $ac2 " - "\n\t" /* odd 6 */ - "mthi $zero, $ac2 " - "\n\t" - "sb %[st2], 0(%[odd_dst]) " - "\n\t" /* odd 3 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac1, %[p1], %[filter45] " - "\n\t" /* odd 5 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* odd 5 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* odd 4 */ - - /* odd 6. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* odd 7 */ - "mthi $zero, $ac3 " - "\n\t" - "sb %[st3], 0(%[odd_dst]) " - "\n\t" /* odd 4 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "ulw %[qload1], 21(%[src]) " - "\n\t" - "dpa.w.ph $ac2, %[p5], %[filter45] " - "\n\t" /* odd 6 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* odd 6 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* odd 5 */ - - /* odd 7. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* odd 8 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbr %[p5], %[qload1] " - "\n\t" - "sb %[st1], 0(%[odd_dst]) " - "\n\t" /* odd 5 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac3, %[p2], %[filter45] " - "\n\t" /* odd 7 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* odd 7 */ - - /* odd 8. pixel */ - "dpa.w.ph $ac1, %[p3], %[filter45] " - "\n\t" /* odd 8 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* odd 8 */ - - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* odd 6 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* odd 7 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* odd 8 */ - - "sb %[st2], 0(%[odd_dst]) " - "\n\t" /* odd 6 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - - "sb %[st3], 0(%[odd_dst]) " - "\n\t" /* odd 7 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - - "sb %[st1], 0(%[odd_dst]) " - "\n\t" /* odd 8 */ - - : [qload1] "=&r"(qload1), [qload2] "=&r"(qload2), [p5] "=&r"(p5), - [st1] "=&r"(st1), [st2] "=&r"(st2), [st3] "=&r"(st3), - [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), [p4] "=&r"(p4), - [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [dst] "+r"(dst), [odd_dst] "+r"(odd_dst) - : [filter45] "r"(filter45), [vector_64] "r"(vector_64), [cm] "r"(cm), - [src] "r"(src), [dst_pitch_2] "r"(dst_pitch_2)); - - src += 16; - dst = (dst_ptr + ((c + 1) * 16 * dst_stride)); - odd_dst = (dst + dst_stride); - } - - /* Next row... */ - src_ptr += src_stride; - dst_ptr += 1; - } -} - -void convolve_bi_horiz_transposed(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const int16_t *filter, int w, int h) { - int x, y; - - for (y = 0; y < h; ++y) { - for (x = 0; x < w; ++x) { - int sum = 0; - - sum += src[x] * filter[3]; - sum += src[x + 1] * filter[4]; - - dst[x * dst_stride] = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)); - } - - src += src_stride; - dst += 1; - } -} - -void vpx_convolve2_dspr2(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const int16_t *filter, int w, - int h) { - uint32_t pos = 38; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - /* prefetch data to cache memory */ - prefetch_load(src); - prefetch_load(src + 32); - - switch (w) { - case 4: - convolve_bi_horiz_4_transposed_dspr2(src, src_stride, dst, dst_stride, - filter, h); - break; - case 8: - convolve_bi_horiz_8_transposed_dspr2(src, src_stride, dst, dst_stride, - filter, h); - break; - case 16: - case 32: - convolve_bi_horiz_16_transposed_dspr2(src, src_stride, dst, dst_stride, - filter, h, (w / 16)); - break; - case 64: - prefetch_load(src + 32); - convolve_bi_horiz_64_transposed_dspr2(src, src_stride, dst, dst_stride, - filter, h); - break; - default: - convolve_bi_horiz_transposed(src, src_stride, dst, dst_stride, filter, w, - h); - break; - } -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve2_horiz_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve2_horiz_dspr2.c deleted file mode 100644 index 9e65a8f5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve2_horiz_dspr2.c +++ /dev/null @@ -1,681 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/convolve_common_dspr2.h" -#include "vpx_dsp/vpx_convolve.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_ports/mem.h" - -#if HAVE_DSPR2 -static void convolve_bi_horiz_4_dspr2(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int16_t *filter_x0, int32_t h) { - int32_t y; - uint8_t *cm = vpx_ff_cropTbl; - int32_t Temp1, Temp2, Temp3, Temp4; - uint32_t vector4a = 64; - uint32_t tp1, tp2; - uint32_t p1, p2; - const int16_t *filter = &filter_x0[3]; - uint32_t filter45; - - filter45 = ((const int32_t *)filter)[0]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_store(dst + dst_stride); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p1], %[tp1] \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "dpa.w.ph $ac3, %[p1], %[filter45] \n\t" - "extp %[Temp1], $ac3, 31 \n\t" - - /* even 2. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "balign %[tp2], %[tp1], 3 \n\t" - "dpa.w.ph $ac2, %[p2], %[filter45] \n\t" - "extp %[Temp3], $ac2, 31 \n\t" - - /* odd 1. pixel */ - "lbux %[tp1], %[Temp1](%[cm]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p1], %[tp2] \n\t" - "preceu.ph.qbl %[p2], %[tp2] \n\t" - "dpa.w.ph $ac3, %[p1], %[filter45] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - /* odd 2. pixel */ - "lbux %[tp2], %[Temp3](%[cm]) \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "dpa.w.ph $ac2, %[p2], %[filter45] \n\t" - "extp %[Temp4], $ac2, 31 \n\t" - - /* clamp */ - "lbux %[p1], %[Temp2](%[cm]) \n\t" - "lbux %[p2], %[Temp4](%[cm]) \n\t" - - /* store bytes */ - "sb %[tp1], 0(%[dst]) \n\t" - "sb %[p1], 1(%[dst]) \n\t" - "sb %[tp2], 2(%[dst]) \n\t" - "sb %[p2], 3(%[dst]) \n\t" - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [p1] "=&r"(p1), [p2] "=&r"(p2), - [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [Temp4] "=&r"(Temp4) - : [filter45] "r"(filter45), [vector4a] "r"(vector4a), [cm] "r"(cm), - [dst] "r"(dst), [src] "r"(src)); - - /* Next row... */ - src += src_stride; - dst += dst_stride; - } -} - -static void convolve_bi_horiz_8_dspr2(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int16_t *filter_x0, int32_t h) { - int32_t y; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector4a = 64; - int32_t Temp1, Temp2, Temp3; - uint32_t tp1, tp2, tp3; - uint32_t p1, p2, p3, p4; - uint32_t st0, st1; - const int16_t *filter = &filter_x0[3]; - uint32_t filter45; - - filter45 = ((const int32_t *)filter)[0]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_store(dst + dst_stride); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[tp1] \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "preceu.ph.qbr %[p3], %[tp2] \n\t" - "preceu.ph.qbl %[p4], %[tp2] \n\t" - "ulw %[tp3], 8(%[src]) \n\t" - "dpa.w.ph $ac3, %[p1], %[filter45] \n\t" - "extp %[Temp1], $ac3, 31 \n\t" - - /* even 2. pixel */ - "dpa.w.ph $ac2, %[p2], %[filter45] \n\t" - "extp %[Temp3], $ac2, 31 \n\t" - - /* even 3. pixel */ - "lbux %[st0], %[Temp1](%[cm]) \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "dpa.w.ph $ac1, %[p3], %[filter45] \n\t" - "extp %[Temp1], $ac1, 31 \n\t" - - /* even 4. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "sb %[st0], 0(%[dst]) \n\t" - "lbux %[st1], %[Temp3](%[cm]) \n\t" - - "balign %[tp3], %[tp2], 3 \n\t" - "balign %[tp2], %[tp1], 3 \n\t" - - "dpa.w.ph $ac2, %[p4], %[filter45] \n\t" - "extp %[Temp3], $ac2, 31 \n\t" - - "lbux %[st0], %[Temp1](%[cm]) \n\t" - - /* odd 1. pixel */ - "mtlo %[vector4a], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "sb %[st1], 2(%[dst]) \n\t" - "preceu.ph.qbr %[p1], %[tp2] \n\t" - "preceu.ph.qbl %[p2], %[tp2] \n\t" - "preceu.ph.qbr %[p3], %[tp3] \n\t" - "preceu.ph.qbl %[p4], %[tp3] \n\t" - "sb %[st0], 4(%[dst]) \n\t" - "dpa.w.ph $ac3, %[p1], %[filter45] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - /* odd 2. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "lbux %[st0], %[Temp3](%[cm]) \n\t" - "dpa.w.ph $ac1, %[p2], %[filter45] \n\t" - "extp %[Temp3], $ac1, 31 \n\t" - - /* odd 3. pixel */ - "lbux %[st1], %[Temp2](%[cm]) \n\t" - "dpa.w.ph $ac3, %[p3], %[filter45] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - /* odd 4. pixel */ - "sb %[st1], 1(%[dst]) \n\t" - "sb %[st0], 6(%[dst]) \n\t" - "dpa.w.ph $ac2, %[p4], %[filter45] \n\t" - "extp %[Temp1], $ac2, 31 \n\t" - - /* clamp */ - "lbux %[p4], %[Temp3](%[cm]) \n\t" - "lbux %[p2], %[Temp2](%[cm]) \n\t" - "lbux %[p1], %[Temp1](%[cm]) \n\t" - - /* store bytes */ - "sb %[p4], 3(%[dst]) \n\t" - "sb %[p2], 5(%[dst]) \n\t" - "sb %[p1], 7(%[dst]) \n\t" - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tp3] "=&r"(tp3), - [st0] "=&r"(st0), [st1] "=&r"(st1), [p1] "=&r"(p1), [p2] "=&r"(p2), - [p3] "=&r"(p3), [p4] "=&r"(p4), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3) - : [filter45] "r"(filter45), [vector4a] "r"(vector4a), [cm] "r"(cm), - [dst] "r"(dst), [src] "r"(src)); - - /* Next row... */ - src += src_stride; - dst += dst_stride; - } -} - -static void convolve_bi_horiz_16_dspr2(const uint8_t *src_ptr, - int32_t src_stride, uint8_t *dst_ptr, - int32_t dst_stride, - const int16_t *filter_x0, int32_t h, - int32_t count) { - int32_t y, c; - const uint8_t *src; - uint8_t *dst; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector_64 = 64; - int32_t Temp1, Temp2, Temp3; - uint32_t qload1, qload2, qload3; - uint32_t p1, p2, p3, p4, p5; - uint32_t st1, st2, st3; - const int16_t *filter = &filter_x0[3]; - uint32_t filter45; - - filter45 = ((const int32_t *)filter)[0]; - - for (y = h; y--;) { - src = src_ptr; - dst = dst_ptr; - - /* prefetch data to cache memory */ - prefetch_load(src_ptr + src_stride); - prefetch_load(src_ptr + src_stride + 32); - prefetch_store(dst_ptr + dst_stride); - - for (c = 0; c < count; c++) { - __asm__ __volatile__( - "ulw %[qload1], 0(%[src]) \n\t" - "ulw %[qload2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 1 */ - "mthi $zero, $ac1 \n\t" - "mtlo %[vector_64], $ac2 \n\t" /* even 2 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[qload1] \n\t" - "preceu.ph.qbl %[p2], %[qload1] \n\t" - "preceu.ph.qbr %[p3], %[qload2] \n\t" - "preceu.ph.qbl %[p4], %[qload2] \n\t" - "ulw %[qload3], 8(%[src]) \n\t" - "dpa.w.ph $ac1, %[p1], %[filter45] \n\t" /* even 1 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 1 */ - - /* even 2. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* even 3 */ - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p1], %[qload3] \n\t" - "preceu.ph.qbl %[p5], %[qload3] \n\t" - "ulw %[qload1], 12(%[src]) \n\t" - "dpa.w.ph $ac2, %[p2], %[filter45] \n\t" /* even 1 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 1 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 1 */ - - /* even 3. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 4 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p2], %[qload1] \n\t" - "sb %[st1], 0(%[dst]) \n\t" /* even 1 */ - "dpa.w.ph $ac3, %[p3], %[filter45] \n\t" /* even 3 */ - "extp %[Temp3], $ac3, 31 \n\t" /* even 3 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 1 */ - - /* even 4. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* even 5 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbl %[p3], %[qload1] \n\t" - "sb %[st2], 2(%[dst]) \n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p4], %[filter45] \n\t" /* even 4 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 4 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* even 3 */ - - /* even 5. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* even 6 */ - "mthi $zero, $ac3 \n\t" - "sb %[st3], 4(%[dst]) \n\t" /* even 3 */ - "dpa.w.ph $ac2, %[p1], %[filter45] \n\t" /* even 5 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 5 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 4 */ - - /* even 6. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 7 */ - "mthi $zero, $ac1 \n\t" - "sb %[st1], 6(%[dst]) \n\t" /* even 4 */ - "dpa.w.ph $ac3, %[p5], %[filter45] \n\t" /* even 6 */ - "extp %[Temp3], $ac3, 31 \n\t" /* even 6 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 5 */ - - /* even 7. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* even 8 */ - "mthi $zero, $ac2 \n\t" - "sb %[st2], 8(%[dst]) \n\t" /* even 5 */ - "dpa.w.ph $ac1, %[p2], %[filter45] \n\t" /* even 7 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 7 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* even 6 */ - - /* even 8. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 1 */ - "mthi $zero, $ac3 \n\t" - "dpa.w.ph $ac2, %[p3], %[filter45] \n\t" /* even 8 */ - "sb %[st3], 10(%[dst]) \n\t" /* even 6 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 8 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 7 */ - - /* ODD pixels */ - "ulw %[qload1], 1(%[src]) \n\t" - "ulw %[qload2], 5(%[src]) \n\t" - - /* odd 1. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 2 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p1], %[qload1] \n\t" - "preceu.ph.qbl %[p2], %[qload1] \n\t" - "preceu.ph.qbr %[p3], %[qload2] \n\t" - "preceu.ph.qbl %[p4], %[qload2] \n\t" - "sb %[st1], 12(%[dst]) \n\t" /* even 7 */ - "ulw %[qload3], 9(%[src]) \n\t" - "dpa.w.ph $ac3, %[p1], %[filter45] \n\t" /* odd 1 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 1 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 8 */ - - /* odd 2. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* odd 3 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[qload3] \n\t" - "preceu.ph.qbl %[p5], %[qload3] \n\t" - "sb %[st2], 14(%[dst]) \n\t" /* even 8 */ - "ulw %[qload1], 13(%[src]) \n\t" - "dpa.w.ph $ac1, %[p2], %[filter45] \n\t" /* odd 2 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 2 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 1 */ - - /* odd 3. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 4 */ - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p2], %[qload1] \n\t" - "sb %[st3], 1(%[dst]) \n\t" /* odd 1 */ - "dpa.w.ph $ac2, %[p3], %[filter45] \n\t" /* odd 3 */ - "extp %[Temp2], $ac2, 31 \n\t" /* odd 3 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 2 */ - - /* odd 4. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 5 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbl %[p3], %[qload1] \n\t" - "sb %[st1], 3(%[dst]) \n\t" /* odd 2 */ - "dpa.w.ph $ac3, %[p4], %[filter45] \n\t" /* odd 4 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 4 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* odd 3 */ - - /* odd 5. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* odd 6 */ - "mthi $zero, $ac2 \n\t" - "sb %[st2], 5(%[dst]) \n\t" /* odd 3 */ - "dpa.w.ph $ac1, %[p1], %[filter45] \n\t" /* odd 5 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 5 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 4 */ - - /* odd 6. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 7 */ - "mthi $zero, $ac3 \n\t" - "sb %[st3], 7(%[dst]) \n\t" /* odd 4 */ - "dpa.w.ph $ac2, %[p5], %[filter45] \n\t" /* odd 6 */ - "extp %[Temp2], $ac2, 31 \n\t" /* odd 6 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 5 */ - - /* odd 7. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 8 */ - "mthi $zero, $ac1 \n\t" - "sb %[st1], 9(%[dst]) \n\t" /* odd 5 */ - "dpa.w.ph $ac3, %[p2], %[filter45] \n\t" /* odd 7 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 7 */ - - /* odd 8. pixel */ - "dpa.w.ph $ac1, %[p3], %[filter45] \n\t" /* odd 8 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 8 */ - - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* odd 6 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 7 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 8 */ - - "sb %[st2], 11(%[dst]) \n\t" /* odd 6 */ - "sb %[st3], 13(%[dst]) \n\t" /* odd 7 */ - "sb %[st1], 15(%[dst]) \n\t" /* odd 8 */ - - : [qload1] "=&r"(qload1), [qload2] "=&r"(qload2), - [qload3] "=&r"(qload3), [st1] "=&r"(st1), [st2] "=&r"(st2), - [st3] "=&r"(st3), [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), - [p4] "=&r"(p4), [p5] "=&r"(p5), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3) - : [filter45] "r"(filter45), [vector_64] "r"(vector_64), [cm] "r"(cm), - [dst] "r"(dst), [src] "r"(src)); - - src += 16; - dst += 16; - } - - /* Next row... */ - src_ptr += src_stride; - dst_ptr += dst_stride; - } -} - -static void convolve_bi_horiz_64_dspr2(const uint8_t *src_ptr, - int32_t src_stride, uint8_t *dst_ptr, - int32_t dst_stride, - const int16_t *filter_x0, int32_t h) { - int32_t y, c; - const uint8_t *src; - uint8_t *dst; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector_64 = 64; - int32_t Temp1, Temp2, Temp3; - uint32_t qload1, qload2, qload3; - uint32_t p1, p2, p3, p4, p5; - uint32_t st1, st2, st3; - const int16_t *filter = &filter_x0[3]; - uint32_t filter45; - - filter45 = ((const int32_t *)filter)[0]; - - for (y = h; y--;) { - src = src_ptr; - dst = dst_ptr; - - /* prefetch data to cache memory */ - prefetch_load(src_ptr + src_stride); - prefetch_load(src_ptr + src_stride + 32); - prefetch_load(src_ptr + src_stride + 64); - prefetch_store(dst_ptr + dst_stride); - prefetch_store(dst_ptr + dst_stride + 32); - - for (c = 0; c < 4; c++) { - __asm__ __volatile__( - "ulw %[qload1], 0(%[src]) \n\t" - "ulw %[qload2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 1 */ - "mthi $zero, $ac1 \n\t" - "mtlo %[vector_64], $ac2 \n\t" /* even 2 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[qload1] \n\t" - "preceu.ph.qbl %[p2], %[qload1] \n\t" - "preceu.ph.qbr %[p3], %[qload2] \n\t" - "preceu.ph.qbl %[p4], %[qload2] \n\t" - "ulw %[qload3], 8(%[src]) \n\t" - "dpa.w.ph $ac1, %[p1], %[filter45] \n\t" /* even 1 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 1 */ - - /* even 2. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* even 3 */ - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p1], %[qload3] \n\t" - "preceu.ph.qbl %[p5], %[qload3] \n\t" - "ulw %[qload1], 12(%[src]) \n\t" - "dpa.w.ph $ac2, %[p2], %[filter45] \n\t" /* even 1 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 1 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 1 */ - - /* even 3. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 4 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p2], %[qload1] \n\t" - "sb %[st1], 0(%[dst]) \n\t" /* even 1 */ - "dpa.w.ph $ac3, %[p3], %[filter45] \n\t" /* even 3 */ - "extp %[Temp3], $ac3, 31 \n\t" /* even 3 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 1 */ - - /* even 4. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* even 5 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbl %[p3], %[qload1] \n\t" - "sb %[st2], 2(%[dst]) \n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p4], %[filter45] \n\t" /* even 4 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 4 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* even 3 */ - - /* even 5. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* even 6 */ - "mthi $zero, $ac3 \n\t" - "sb %[st3], 4(%[dst]) \n\t" /* even 3 */ - "dpa.w.ph $ac2, %[p1], %[filter45] \n\t" /* even 5 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 5 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 4 */ - - /* even 6. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 7 */ - "mthi $zero, $ac1 \n\t" - "sb %[st1], 6(%[dst]) \n\t" /* even 4 */ - "dpa.w.ph $ac3, %[p5], %[filter45] \n\t" /* even 6 */ - "extp %[Temp3], $ac3, 31 \n\t" /* even 6 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 5 */ - - /* even 7. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* even 8 */ - "mthi $zero, $ac2 \n\t" - "sb %[st2], 8(%[dst]) \n\t" /* even 5 */ - "dpa.w.ph $ac1, %[p2], %[filter45] \n\t" /* even 7 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 7 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* even 6 */ - - /* even 8. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 1 */ - "mthi $zero, $ac3 \n\t" - "dpa.w.ph $ac2, %[p3], %[filter45] \n\t" /* even 8 */ - "sb %[st3], 10(%[dst]) \n\t" /* even 6 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 8 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 7 */ - - /* ODD pixels */ - "ulw %[qload1], 1(%[src]) \n\t" - "ulw %[qload2], 5(%[src]) \n\t" - - /* odd 1. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 2 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p1], %[qload1] \n\t" - "preceu.ph.qbl %[p2], %[qload1] \n\t" - "preceu.ph.qbr %[p3], %[qload2] \n\t" - "preceu.ph.qbl %[p4], %[qload2] \n\t" - "sb %[st1], 12(%[dst]) \n\t" /* even 7 */ - "ulw %[qload3], 9(%[src]) \n\t" - "dpa.w.ph $ac3, %[p1], %[filter45] \n\t" /* odd 1 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 1 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 8 */ - - /* odd 2. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* odd 3 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[qload3] \n\t" - "preceu.ph.qbl %[p5], %[qload3] \n\t" - "sb %[st2], 14(%[dst]) \n\t" /* even 8 */ - "ulw %[qload1], 13(%[src]) \n\t" - "dpa.w.ph $ac1, %[p2], %[filter45] \n\t" /* odd 2 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 2 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 1 */ - - /* odd 3. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 4 */ - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p2], %[qload1] \n\t" - "sb %[st3], 1(%[dst]) \n\t" /* odd 1 */ - "dpa.w.ph $ac2, %[p3], %[filter45] \n\t" /* odd 3 */ - "extp %[Temp2], $ac2, 31 \n\t" /* odd 3 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 2 */ - - /* odd 4. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 5 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbl %[p3], %[qload1] \n\t" - "sb %[st1], 3(%[dst]) \n\t" /* odd 2 */ - "dpa.w.ph $ac3, %[p4], %[filter45] \n\t" /* odd 4 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 4 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* odd 3 */ - - /* odd 5. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* odd 6 */ - "mthi $zero, $ac2 \n\t" - "sb %[st2], 5(%[dst]) \n\t" /* odd 3 */ - "dpa.w.ph $ac1, %[p1], %[filter45] \n\t" /* odd 5 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 5 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 4 */ - - /* odd 6. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 7 */ - "mthi $zero, $ac3 \n\t" - "sb %[st3], 7(%[dst]) \n\t" /* odd 4 */ - "dpa.w.ph $ac2, %[p5], %[filter45] \n\t" /* odd 6 */ - "extp %[Temp2], $ac2, 31 \n\t" /* odd 6 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 5 */ - - /* odd 7. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 8 */ - "mthi $zero, $ac1 \n\t" - "sb %[st1], 9(%[dst]) \n\t" /* odd 5 */ - "dpa.w.ph $ac3, %[p2], %[filter45] \n\t" /* odd 7 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 7 */ - - /* odd 8. pixel */ - "dpa.w.ph $ac1, %[p3], %[filter45] \n\t" /* odd 8 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 8 */ - - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* odd 6 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 7 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 8 */ - - "sb %[st2], 11(%[dst]) \n\t" /* odd 6 */ - "sb %[st3], 13(%[dst]) \n\t" /* odd 7 */ - "sb %[st1], 15(%[dst]) \n\t" /* odd 8 */ - - : [qload1] "=&r"(qload1), [qload2] "=&r"(qload2), - [qload3] "=&r"(qload3), [st1] "=&r"(st1), [st2] "=&r"(st2), - [st3] "=&r"(st3), [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), - [p4] "=&r"(p4), [p5] "=&r"(p5), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3) - : [filter45] "r"(filter45), [vector_64] "r"(vector_64), [cm] "r"(cm), - [dst] "r"(dst), [src] "r"(src)); - - src += 16; - dst += 16; - } - - /* Next row... */ - src_ptr += src_stride; - dst_ptr += dst_stride; - } -} - -void vpx_convolve2_horiz_dspr2(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - const int16_t *const filter_x = filter[x0_q4]; - uint32_t pos = 38; - - assert(x_step_q4 == 16); - - prefetch_load((const uint8_t *)filter_x); - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - /* prefetch data to cache memory */ - prefetch_load(src); - prefetch_load(src + 32); - prefetch_store(dst); - - switch (w) { - case 4: - convolve_bi_horiz_4_dspr2(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filter_x, (int32_t)h); - break; - case 8: - convolve_bi_horiz_8_dspr2(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filter_x, (int32_t)h); - break; - case 16: - convolve_bi_horiz_16_dspr2(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filter_x, (int32_t)h, 1); - break; - case 32: - convolve_bi_horiz_16_dspr2(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filter_x, (int32_t)h, 2); - break; - case 64: - prefetch_load(src + 64); - prefetch_store(dst + 32); - - convolve_bi_horiz_64_dspr2(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filter_x, (int32_t)h); - break; - default: - vpx_convolve8_horiz_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve2_vert_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve2_vert_dspr2.c deleted file mode 100644 index a3e967b4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve2_vert_dspr2.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/convolve_common_dspr2.h" -#include "vpx_dsp/vpx_convolve.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_ports/mem.h" - -#if HAVE_DSPR2 -static void convolve_bi_vert_4_dspr2(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int16_t *filter_y, int32_t w, - int32_t h) { - int32_t x, y; - const uint8_t *src_ptr; - uint8_t *dst_ptr; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector4a = 64; - uint32_t load1, load2; - uint32_t p1, p2; - uint32_t scratch1; - uint32_t store1, store2; - int32_t Temp1, Temp2; - const int16_t *filter = &filter_y[3]; - uint32_t filter45; - - filter45 = ((const int32_t *)filter)[0]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_store(dst + dst_stride); - - for (x = 0; x < w; x += 4) { - src_ptr = src + x; - dst_ptr = dst + x; - - __asm__ __volatile__( - "ulw %[load1], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load2], 0(%[src_ptr]) \n\t" - - "mtlo %[vector4a], $ac0 \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac0 \n\t" - "mthi $zero, $ac1 \n\t" - "mthi $zero, $ac2 \n\t" - "mthi $zero, $ac3 \n\t" - - "preceu.ph.qbr %[scratch1], %[load1] \n\t" - "preceu.ph.qbr %[p1], %[load2] \n\t" - - "precrq.ph.w %[p2], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac0, %[p1], %[filter45] \n\t" - "dpa.w.ph $ac1, %[p2], %[filter45] \n\t" - - "preceu.ph.qbl %[scratch1], %[load1] \n\t" - "preceu.ph.qbl %[p1], %[load2] \n\t" - - "precrq.ph.w %[p2], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac2, %[p1], %[filter45] \n\t" - "dpa.w.ph $ac3, %[p2], %[filter45] \n\t" - - "extp %[Temp1], $ac0, 31 \n\t" - "extp %[Temp2], $ac1, 31 \n\t" - - "lbux %[store1], %[Temp1](%[cm]) \n\t" - "extp %[Temp1], $ac2, 31 \n\t" - - "lbux %[store2], %[Temp2](%[cm]) \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - "sb %[store1], 0(%[dst_ptr]) \n\t" - "sb %[store2], 1(%[dst_ptr]) \n\t" - - "lbux %[store1], %[Temp1](%[cm]) \n\t" - "lbux %[store2], %[Temp2](%[cm]) \n\t" - - "sb %[store1], 2(%[dst_ptr]) \n\t" - "sb %[store2], 3(%[dst_ptr]) \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [p1] "=&r"(p1), - [p2] "=&r"(p2), [scratch1] "=&r"(scratch1), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [store1] "=&r"(store1), - [store2] "=&r"(store2), [src_ptr] "+r"(src_ptr) - : [filter45] "r"(filter45), [vector4a] "r"(vector4a), - [src_stride] "r"(src_stride), [cm] "r"(cm), [dst_ptr] "r"(dst_ptr)); - } - - /* Next row... */ - src += src_stride; - dst += dst_stride; - } -} - -static void convolve_bi_vert_64_dspr2(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int16_t *filter_y, int32_t h) { - int32_t x, y; - const uint8_t *src_ptr; - uint8_t *dst_ptr; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector4a = 64; - uint32_t load1, load2; - uint32_t p1, p2; - uint32_t scratch1; - uint32_t store1, store2; - int32_t Temp1, Temp2; - const int16_t *filter = &filter_y[3]; - uint32_t filter45; - - filter45 = ((const int32_t *)filter)[0]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_store(dst + dst_stride); - - for (x = 0; x < 64; x += 4) { - src_ptr = src + x; - dst_ptr = dst + x; - - __asm__ __volatile__( - "ulw %[load1], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load2], 0(%[src_ptr]) \n\t" - - "mtlo %[vector4a], $ac0 \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac0 \n\t" - "mthi $zero, $ac1 \n\t" - "mthi $zero, $ac2 \n\t" - "mthi $zero, $ac3 \n\t" - - "preceu.ph.qbr %[scratch1], %[load1] \n\t" - "preceu.ph.qbr %[p1], %[load2] \n\t" - - "precrq.ph.w %[p2], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac0, %[p1], %[filter45] \n\t" - "dpa.w.ph $ac1, %[p2], %[filter45] \n\t" - - "preceu.ph.qbl %[scratch1], %[load1] \n\t" - "preceu.ph.qbl %[p1], %[load2] \n\t" - - "precrq.ph.w %[p2], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac2, %[p1], %[filter45] \n\t" - "dpa.w.ph $ac3, %[p2], %[filter45] \n\t" - - "extp %[Temp1], $ac0, 31 \n\t" - "extp %[Temp2], $ac1, 31 \n\t" - - "lbux %[store1], %[Temp1](%[cm]) \n\t" - "extp %[Temp1], $ac2, 31 \n\t" - - "lbux %[store2], %[Temp2](%[cm]) \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - "sb %[store1], 0(%[dst_ptr]) \n\t" - "sb %[store2], 1(%[dst_ptr]) \n\t" - - "lbux %[store1], %[Temp1](%[cm]) \n\t" - "lbux %[store2], %[Temp2](%[cm]) \n\t" - - "sb %[store1], 2(%[dst_ptr]) \n\t" - "sb %[store2], 3(%[dst_ptr]) \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [p1] "=&r"(p1), - [p2] "=&r"(p2), [scratch1] "=&r"(scratch1), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [store1] "=&r"(store1), - [store2] "=&r"(store2), [src_ptr] "+r"(src_ptr) - : [filter45] "r"(filter45), [vector4a] "r"(vector4a), - [src_stride] "r"(src_stride), [cm] "r"(cm), [dst_ptr] "r"(dst_ptr)); - } - - /* Next row... */ - src += src_stride; - dst += dst_stride; - } -} - -void vpx_convolve2_vert_dspr2(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - const int16_t *const filter_y = filter[y0_q4]; - uint32_t pos = 38; - - assert(y_step_q4 == 16); - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - prefetch_store(dst); - - switch (w) { - case 4: - case 8: - case 16: - case 32: - convolve_bi_vert_4_dspr2(src, src_stride, dst, dst_stride, filter_y, w, - h); - break; - case 64: - prefetch_store(dst + 32); - convolve_bi_vert_64_dspr2(src, src_stride, dst, dst_stride, filter_y, h); - break; - default: - vpx_convolve8_vert_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve8_avg_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve8_avg_dspr2.c deleted file mode 100644 index cc458c86..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve8_avg_dspr2.c +++ /dev/null @@ -1,647 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/convolve_common_dspr2.h" -#include "vpx_dsp/vpx_convolve.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_ports/mem.h" - -#if HAVE_DSPR2 -static void convolve_avg_vert_4_dspr2(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int16_t *filter_y, int32_t w, - int32_t h) { - int32_t x, y; - const uint8_t *src_ptr; - uint8_t *dst_ptr; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector4a = 64; - uint32_t load1, load2, load3, load4; - uint32_t p1, p2; - uint32_t n1, n2; - uint32_t scratch1, scratch2; - uint32_t store1, store2; - int32_t vector1b, vector2b, vector3b, vector4b; - int32_t Temp1, Temp2; - - vector1b = ((const int32_t *)filter_y)[0]; - vector2b = ((const int32_t *)filter_y)[1]; - vector3b = ((const int32_t *)filter_y)[2]; - vector4b = ((const int32_t *)filter_y)[3]; - - src -= 3 * src_stride; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_store(dst + dst_stride); - - for (x = 0; x < w; x += 4) { - src_ptr = src + x; - dst_ptr = dst + x; - - __asm__ __volatile__( - "ulw %[load1], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load2], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load3], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load4], 0(%[src_ptr]) \n\t" - - "mtlo %[vector4a], $ac0 \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac0 \n\t" - "mthi $zero, $ac1 \n\t" - "mthi $zero, $ac2 \n\t" - "mthi $zero, $ac3 \n\t" - - "preceu.ph.qbr %[scratch1], %[load1] \n\t" - "preceu.ph.qbr %[p1], %[load2] \n\t" - "precrq.ph.w %[n1], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - "preceu.ph.qbr %[scratch2], %[load3] \n\t" - "preceu.ph.qbr %[p2], %[load4] \n\t" - "precrq.ph.w %[n2], %[p2], %[scratch2] \n\t" /* pixel 2 */ - "append %[p2], %[scratch2], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac0, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac0, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac1, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac1, %[n2], %[vector2b] \n\t" - - "preceu.ph.qbl %[scratch1], %[load1] \n\t" - "preceu.ph.qbl %[p1], %[load2] \n\t" - "precrq.ph.w %[n1], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - "preceu.ph.qbl %[scratch2], %[load3] \n\t" - "preceu.ph.qbl %[p2], %[load4] \n\t" - "precrq.ph.w %[n2], %[p2], %[scratch2] \n\t" /* pixel 2 */ - "append %[p2], %[scratch2], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac2, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector2b] \n\t" - - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load1], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load2], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load3], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load4], 0(%[src_ptr]) \n\t" - - "preceu.ph.qbr %[scratch1], %[load1] \n\t" - "preceu.ph.qbr %[p1], %[load2] \n\t" - "precrq.ph.w %[n1], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - "preceu.ph.qbr %[scratch2], %[load3] \n\t" - "preceu.ph.qbr %[p2], %[load4] \n\t" - "precrq.ph.w %[n2], %[p2], %[scratch2] \n\t" /* pixel 2 */ - "append %[p2], %[scratch2], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac0, %[p1], %[vector3b] \n\t" - "dpa.w.ph $ac0, %[p2], %[vector4b] \n\t" - "extp %[Temp1], $ac0, 31 \n\t" - "dpa.w.ph $ac1, %[n1], %[vector3b] \n\t" - "dpa.w.ph $ac1, %[n2], %[vector4b] \n\t" - "extp %[Temp2], $ac1, 31 \n\t" - - "preceu.ph.qbl %[scratch1], %[load1] \n\t" - "preceu.ph.qbl %[p1], %[load2] \n\t" - "precrq.ph.w %[n1], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - "lbu %[scratch1], 0(%[dst_ptr]) \n\t" - "preceu.ph.qbl %[scratch2], %[load3] \n\t" - "preceu.ph.qbl %[p2], %[load4] \n\t" - "precrq.ph.w %[n2], %[p2], %[scratch2] \n\t" /* pixel 2 */ - "append %[p2], %[scratch2], 16 \n\t" /* pixel 1 */ - "lbu %[scratch2], 1(%[dst_ptr]) \n\t" - - "lbux %[store1], %[Temp1](%[cm]) \n\t" - "dpa.w.ph $ac2, %[p1], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector4b] \n\t" - "addqh_r.w %[store1], %[store1], %[scratch1] \n\t" /* pixel 1 */ - "extp %[Temp1], $ac2, 31 \n\t" - - "lbux %[store2], %[Temp2](%[cm]) \n\t" - "dpa.w.ph $ac3, %[n1], %[vector3b] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector4b] \n\t" - "addqh_r.w %[store2], %[store2], %[scratch2] \n\t" /* pixel 2 */ - "extp %[Temp2], $ac3, 31 \n\t" - "lbu %[scratch1], 2(%[dst_ptr]) \n\t" - - "sb %[store1], 0(%[dst_ptr]) \n\t" - "sb %[store2], 1(%[dst_ptr]) \n\t" - "lbu %[scratch2], 3(%[dst_ptr]) \n\t" - - "lbux %[store1], %[Temp1](%[cm]) \n\t" - "lbux %[store2], %[Temp2](%[cm]) \n\t" - "addqh_r.w %[store1], %[store1], %[scratch1] \n\t" /* pixel 3 */ - "addqh_r.w %[store2], %[store2], %[scratch2] \n\t" /* pixel 4 */ - - "sb %[store1], 2(%[dst_ptr]) \n\t" - "sb %[store2], 3(%[dst_ptr]) \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [p1] "=&r"(p1), [p2] "=&r"(p2), - [n1] "=&r"(n1), [n2] "=&r"(n2), [scratch1] "=&r"(scratch1), - [scratch2] "=&r"(scratch2), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [store1] "=&r"(store1), - [store2] "=&r"(store2), [src_ptr] "+r"(src_ptr) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector3b] "r"(vector3b), [vector4b] "r"(vector4b), - [vector4a] "r"(vector4a), [src_stride] "r"(src_stride), - [cm] "r"(cm), [dst_ptr] "r"(dst_ptr)); - } - - /* Next row... */ - src += src_stride; - dst += dst_stride; - } -} - -static void convolve_avg_vert_64_dspr2(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int16_t *filter_y, int32_t h) { - int32_t x, y; - const uint8_t *src_ptr; - uint8_t *dst_ptr; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector4a = 64; - uint32_t load1, load2, load3, load4; - uint32_t p1, p2; - uint32_t n1, n2; - uint32_t scratch1, scratch2; - uint32_t store1, store2; - int32_t vector1b, vector2b, vector3b, vector4b; - int32_t Temp1, Temp2; - - vector1b = ((const int32_t *)filter_y)[0]; - vector2b = ((const int32_t *)filter_y)[1]; - vector3b = ((const int32_t *)filter_y)[2]; - vector4b = ((const int32_t *)filter_y)[3]; - - src -= 3 * src_stride; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_store(dst + dst_stride); - prefetch_store(dst + dst_stride + 32); - - for (x = 0; x < 64; x += 4) { - src_ptr = src + x; - dst_ptr = dst + x; - - __asm__ __volatile__( - "ulw %[load1], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load2], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load3], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load4], 0(%[src_ptr]) \n\t" - - "mtlo %[vector4a], $ac0 \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac0 \n\t" - "mthi $zero, $ac1 \n\t" - "mthi $zero, $ac2 \n\t" - "mthi $zero, $ac3 \n\t" - - "preceu.ph.qbr %[scratch1], %[load1] \n\t" - "preceu.ph.qbr %[p1], %[load2] \n\t" - "precrq.ph.w %[n1], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - "preceu.ph.qbr %[scratch2], %[load3] \n\t" - "preceu.ph.qbr %[p2], %[load4] \n\t" - "precrq.ph.w %[n2], %[p2], %[scratch2] \n\t" /* pixel 2 */ - "append %[p2], %[scratch2], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac0, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac0, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac1, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac1, %[n2], %[vector2b] \n\t" - - "preceu.ph.qbl %[scratch1], %[load1] \n\t" - "preceu.ph.qbl %[p1], %[load2] \n\t" - "precrq.ph.w %[n1], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - "preceu.ph.qbl %[scratch2], %[load3] \n\t" - "preceu.ph.qbl %[p2], %[load4] \n\t" - "precrq.ph.w %[n2], %[p2], %[scratch2] \n\t" /* pixel 2 */ - "append %[p2], %[scratch2], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac2, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector2b] \n\t" - - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load1], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load2], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load3], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load4], 0(%[src_ptr]) \n\t" - - "preceu.ph.qbr %[scratch1], %[load1] \n\t" - "preceu.ph.qbr %[p1], %[load2] \n\t" - "precrq.ph.w %[n1], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - "preceu.ph.qbr %[scratch2], %[load3] \n\t" - "preceu.ph.qbr %[p2], %[load4] \n\t" - "precrq.ph.w %[n2], %[p2], %[scratch2] \n\t" /* pixel 2 */ - "append %[p2], %[scratch2], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac0, %[p1], %[vector3b] \n\t" - "dpa.w.ph $ac0, %[p2], %[vector4b] \n\t" - "extp %[Temp1], $ac0, 31 \n\t" - "dpa.w.ph $ac1, %[n1], %[vector3b] \n\t" - "dpa.w.ph $ac1, %[n2], %[vector4b] \n\t" - "extp %[Temp2], $ac1, 31 \n\t" - - "preceu.ph.qbl %[scratch1], %[load1] \n\t" - "preceu.ph.qbl %[p1], %[load2] \n\t" - "precrq.ph.w %[n1], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - "lbu %[scratch1], 0(%[dst_ptr]) \n\t" - "preceu.ph.qbl %[scratch2], %[load3] \n\t" - "preceu.ph.qbl %[p2], %[load4] \n\t" - "precrq.ph.w %[n2], %[p2], %[scratch2] \n\t" /* pixel 2 */ - "append %[p2], %[scratch2], 16 \n\t" /* pixel 1 */ - "lbu %[scratch2], 1(%[dst_ptr]) \n\t" - - "lbux %[store1], %[Temp1](%[cm]) \n\t" - "dpa.w.ph $ac2, %[p1], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector4b] \n\t" - "addqh_r.w %[store1], %[store1], %[scratch1] \n\t" /* pixel 1 */ - "extp %[Temp1], $ac2, 31 \n\t" - - "lbux %[store2], %[Temp2](%[cm]) \n\t" - "dpa.w.ph $ac3, %[n1], %[vector3b] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector4b] \n\t" - "addqh_r.w %[store2], %[store2], %[scratch2] \n\t" /* pixel 2 */ - "extp %[Temp2], $ac3, 31 \n\t" - "lbu %[scratch1], 2(%[dst_ptr]) \n\t" - - "sb %[store1], 0(%[dst_ptr]) \n\t" - "sb %[store2], 1(%[dst_ptr]) \n\t" - "lbu %[scratch2], 3(%[dst_ptr]) \n\t" - - "lbux %[store1], %[Temp1](%[cm]) \n\t" - "lbux %[store2], %[Temp2](%[cm]) \n\t" - "addqh_r.w %[store1], %[store1], %[scratch1] \n\t" /* pixel 3 */ - "addqh_r.w %[store2], %[store2], %[scratch2] \n\t" /* pixel 4 */ - - "sb %[store1], 2(%[dst_ptr]) \n\t" - "sb %[store2], 3(%[dst_ptr]) \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [p1] "=&r"(p1), [p2] "=&r"(p2), - [n1] "=&r"(n1), [n2] "=&r"(n2), [scratch1] "=&r"(scratch1), - [scratch2] "=&r"(scratch2), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [store1] "=&r"(store1), - [store2] "=&r"(store2), [src_ptr] "+r"(src_ptr) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector3b] "r"(vector3b), [vector4b] "r"(vector4b), - [vector4a] "r"(vector4a), [src_stride] "r"(src_stride), - [cm] "r"(cm), [dst_ptr] "r"(dst_ptr)); - } - - /* Next row... */ - src += src_stride; - dst += dst_stride; - } -} - -void vpx_convolve8_avg_vert_dspr2(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - const int16_t *const filter_y = filter[y0_q4]; - assert(y_step_q4 == 16); - assert(((const int32_t *)filter_y)[1] != 0x800000); - - if (vpx_get_filter_taps(filter_y) == 2) { - vpx_convolve2_avg_vert_dspr2(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h); - } else { - uint32_t pos = 38; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - prefetch_store(dst); - - switch (w) { - case 4: - case 8: - case 16: - case 32: - convolve_avg_vert_4_dspr2(src, src_stride, dst, dst_stride, filter_y, w, - h); - break; - case 64: - prefetch_store(dst + 32); - convolve_avg_vert_64_dspr2(src, src_stride, dst, dst_stride, filter_y, - h); - break; - default: - vpx_convolve8_avg_vert_c(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } -} - -void vpx_convolve8_avg_dspr2(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - /* Fixed size intermediate buffer places limits on parameters. */ - DECLARE_ALIGNED(32, uint8_t, temp[64 * 135]); - int32_t intermediate_height = ((h * y_step_q4) >> 4) + 7; - - assert(w <= 64); - assert(h <= 64); - assert(x_step_q4 == 16); - assert(y_step_q4 == 16); - - if (intermediate_height < h) intermediate_height = h; - - vpx_convolve8_horiz(src - (src_stride * 3), src_stride, temp, 64, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, - intermediate_height); - - vpx_convolve8_avg_vert(temp + 64 * 3, 64, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); -} - -void vpx_convolve_avg_dspr2(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - int x, y; - uint32_t tp1, tp2, tn1, tp3, tp4, tn2; - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - /* prefetch data to cache memory */ - prefetch_load(src); - prefetch_load(src + 32); - prefetch_store(dst); - - switch (w) { - case 4: - /* 1 word storage */ - for (y = h; y--;) { - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_store(dst + dst_stride); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 0(%[dst]) \n\t" - "adduh_r.qb %[tn1], %[tp2], %[tp1] \n\t" /* average */ - "sw %[tn1], 0(%[dst]) \n\t" /* store */ - - : [tn1] "=&r"(tn1), [tp1] "=&r"(tp1), [tp2] "=&r"(tp2) - : [src] "r"(src), [dst] "r"(dst)); - - src += src_stride; - dst += dst_stride; - } - break; - case 8: - /* 2 word storage */ - for (y = h; y--;) { - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_store(dst + dst_stride); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 0(%[dst]) \n\t" - "ulw %[tp3], 4(%[src]) \n\t" - "ulw %[tp4], 4(%[dst]) \n\t" - "adduh_r.qb %[tn1], %[tp2], %[tp1] \n\t" /* average */ - "sw %[tn1], 0(%[dst]) \n\t" /* store */ - "adduh_r.qb %[tn2], %[tp3], %[tp4] \n\t" /* average */ - "sw %[tn2], 4(%[dst]) \n\t" /* store */ - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tp3] "=&r"(tp3), - [tp4] "=&r"(tp4), [tn1] "=&r"(tn1), [tn2] "=&r"(tn2) - : [src] "r"(src), [dst] "r"(dst)); - - src += src_stride; - dst += dst_stride; - } - break; - case 16: - /* 4 word storage */ - for (y = h; y--;) { - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_store(dst + dst_stride); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 0(%[dst]) \n\t" - "ulw %[tp3], 4(%[src]) \n\t" - "ulw %[tp4], 4(%[dst]) \n\t" - "adduh_r.qb %[tn1], %[tp2], %[tp1] \n\t" /* average */ - "ulw %[tp1], 8(%[src]) \n\t" - "ulw %[tp2], 8(%[dst]) \n\t" - "sw %[tn1], 0(%[dst]) \n\t" /* store */ - "adduh_r.qb %[tn2], %[tp3], %[tp4] \n\t" /* average */ - "sw %[tn2], 4(%[dst]) \n\t" /* store */ - "ulw %[tp3], 12(%[src]) \n\t" - "ulw %[tp4], 12(%[dst]) \n\t" - "adduh_r.qb %[tn1], %[tp2], %[tp1] \n\t" /* average */ - "sw %[tn1], 8(%[dst]) \n\t" /* store */ - "adduh_r.qb %[tn2], %[tp3], %[tp4] \n\t" /* average */ - "sw %[tn2], 12(%[dst]) \n\t" /* store */ - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tp3] "=&r"(tp3), - [tp4] "=&r"(tp4), [tn1] "=&r"(tn1), [tn2] "=&r"(tn2) - : [src] "r"(src), [dst] "r"(dst)); - - src += src_stride; - dst += dst_stride; - } - break; - case 32: - /* 8 word storage */ - for (y = h; y--;) { - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_store(dst + dst_stride); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 0(%[dst]) \n\t" - "ulw %[tp3], 4(%[src]) \n\t" - "ulw %[tp4], 4(%[dst]) \n\t" - "adduh_r.qb %[tn1], %[tp2], %[tp1] \n\t" /* average */ - "ulw %[tp1], 8(%[src]) \n\t" - "ulw %[tp2], 8(%[dst]) \n\t" - "sw %[tn1], 0(%[dst]) \n\t" /* store */ - "adduh_r.qb %[tn2], %[tp3], %[tp4] \n\t" /* average */ - "sw %[tn2], 4(%[dst]) \n\t" /* store */ - "ulw %[tp3], 12(%[src]) \n\t" - "ulw %[tp4], 12(%[dst]) \n\t" - "adduh_r.qb %[tn1], %[tp2], %[tp1] \n\t" /* average */ - "ulw %[tp1], 16(%[src]) \n\t" - "ulw %[tp2], 16(%[dst]) \n\t" - "sw %[tn1], 8(%[dst]) \n\t" /* store */ - "adduh_r.qb %[tn2], %[tp3], %[tp4] \n\t" /* average */ - "sw %[tn2], 12(%[dst]) \n\t" /* store */ - "ulw %[tp3], 20(%[src]) \n\t" - "ulw %[tp4], 20(%[dst]) \n\t" - "adduh_r.qb %[tn1], %[tp2], %[tp1] \n\t" /* average */ - "ulw %[tp1], 24(%[src]) \n\t" - "ulw %[tp2], 24(%[dst]) \n\t" - "sw %[tn1], 16(%[dst]) \n\t" /* store */ - "adduh_r.qb %[tn2], %[tp3], %[tp4] \n\t" /* average */ - "sw %[tn2], 20(%[dst]) \n\t" /* store */ - "ulw %[tp3], 28(%[src]) \n\t" - "ulw %[tp4], 28(%[dst]) \n\t" - "adduh_r.qb %[tn1], %[tp2], %[tp1] \n\t" /* average */ - "sw %[tn1], 24(%[dst]) \n\t" /* store */ - "adduh_r.qb %[tn2], %[tp3], %[tp4] \n\t" /* average */ - "sw %[tn2], 28(%[dst]) \n\t" /* store */ - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tp3] "=&r"(tp3), - [tp4] "=&r"(tp4), [tn1] "=&r"(tn1), [tn2] "=&r"(tn2) - : [src] "r"(src), [dst] "r"(dst)); - - src += src_stride; - dst += dst_stride; - } - break; - case 64: - prefetch_load(src + 64); - prefetch_store(dst + 32); - - /* 16 word storage */ - for (y = h; y--;) { - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_load(src + src_stride + 64); - prefetch_store(dst + dst_stride); - prefetch_store(dst + dst_stride + 32); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 0(%[dst]) \n\t" - "ulw %[tp3], 4(%[src]) \n\t" - "ulw %[tp4], 4(%[dst]) \n\t" - "adduh_r.qb %[tn1], %[tp2], %[tp1] \n\t" /* average */ - "ulw %[tp1], 8(%[src]) \n\t" - "ulw %[tp2], 8(%[dst]) \n\t" - "sw %[tn1], 0(%[dst]) \n\t" /* store */ - "adduh_r.qb %[tn2], %[tp3], %[tp4] \n\t" /* average */ - "sw %[tn2], 4(%[dst]) \n\t" /* store */ - "ulw %[tp3], 12(%[src]) \n\t" - "ulw %[tp4], 12(%[dst]) \n\t" - "adduh_r.qb %[tn1], %[tp2], %[tp1] \n\t" /* average */ - "ulw %[tp1], 16(%[src]) \n\t" - "ulw %[tp2], 16(%[dst]) \n\t" - "sw %[tn1], 8(%[dst]) \n\t" /* store */ - "adduh_r.qb %[tn2], %[tp3], %[tp4] \n\t" /* average */ - "sw %[tn2], 12(%[dst]) \n\t" /* store */ - "ulw %[tp3], 20(%[src]) \n\t" - "ulw %[tp4], 20(%[dst]) \n\t" - "adduh_r.qb %[tn1], %[tp2], %[tp1] \n\t" /* average */ - "ulw %[tp1], 24(%[src]) \n\t" - "ulw %[tp2], 24(%[dst]) \n\t" - "sw %[tn1], 16(%[dst]) \n\t" /* store */ - "adduh_r.qb %[tn2], %[tp3], %[tp4] \n\t" /* average */ - "sw %[tn2], 20(%[dst]) \n\t" /* store */ - "ulw %[tp3], 28(%[src]) \n\t" - "ulw %[tp4], 28(%[dst]) \n\t" - "adduh_r.qb %[tn1], %[tp2], %[tp1] \n\t" /* average */ - "ulw %[tp1], 32(%[src]) \n\t" - "ulw %[tp2], 32(%[dst]) \n\t" - "sw %[tn1], 24(%[dst]) \n\t" /* store */ - "adduh_r.qb %[tn2], %[tp3], %[tp4] \n\t" /* average */ - "sw %[tn2], 28(%[dst]) \n\t" /* store */ - "ulw %[tp3], 36(%[src]) \n\t" - "ulw %[tp4], 36(%[dst]) \n\t" - "adduh_r.qb %[tn1], %[tp2], %[tp1] \n\t" /* average */ - "ulw %[tp1], 40(%[src]) \n\t" - "ulw %[tp2], 40(%[dst]) \n\t" - "sw %[tn1], 32(%[dst]) \n\t" /* store */ - "adduh_r.qb %[tn2], %[tp3], %[tp4] \n\t" /* average */ - "sw %[tn2], 36(%[dst]) \n\t" /* store */ - "ulw %[tp3], 44(%[src]) \n\t" - "ulw %[tp4], 44(%[dst]) \n\t" - "adduh_r.qb %[tn1], %[tp2], %[tp1] \n\t" /* average */ - "ulw %[tp1], 48(%[src]) \n\t" - "ulw %[tp2], 48(%[dst]) \n\t" - "sw %[tn1], 40(%[dst]) \n\t" /* store */ - "adduh_r.qb %[tn2], %[tp3], %[tp4] \n\t" /* average */ - "sw %[tn2], 44(%[dst]) \n\t" /* store */ - "ulw %[tp3], 52(%[src]) \n\t" - "ulw %[tp4], 52(%[dst]) \n\t" - "adduh_r.qb %[tn1], %[tp2], %[tp1] \n\t" /* average */ - "ulw %[tp1], 56(%[src]) \n\t" - "ulw %[tp2], 56(%[dst]) \n\t" - "sw %[tn1], 48(%[dst]) \n\t" /* store */ - "adduh_r.qb %[tn2], %[tp3], %[tp4] \n\t" /* average */ - "sw %[tn2], 52(%[dst]) \n\t" /* store */ - "ulw %[tp3], 60(%[src]) \n\t" - "ulw %[tp4], 60(%[dst]) \n\t" - "adduh_r.qb %[tn1], %[tp2], %[tp1] \n\t" /* average */ - "sw %[tn1], 56(%[dst]) \n\t" /* store */ - "adduh_r.qb %[tn2], %[tp3], %[tp4] \n\t" /* average */ - "sw %[tn2], 60(%[dst]) \n\t" /* store */ - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tp3] "=&r"(tp3), - [tp4] "=&r"(tp4), [tn1] "=&r"(tn1), [tn2] "=&r"(tn2) - : [src] "r"(src), [dst] "r"(dst)); - - src += src_stride; - dst += dst_stride; - } - break; - default: - for (y = h; y > 0; --y) { - for (x = 0; x < w; ++x) { - dst[x] = (dst[x] + src[x] + 1) >> 1; - } - - src += src_stride; - dst += dst_stride; - } - break; - } -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve8_avg_horiz_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve8_avg_horiz_dspr2.c deleted file mode 100644 index 7a9aa49d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve8_avg_horiz_dspr2.c +++ /dev/null @@ -1,998 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/convolve_common_dspr2.h" -#include "vpx_dsp/vpx_convolve.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_ports/mem.h" - -#if HAVE_DSPR2 -static void convolve_avg_horiz_4_dspr2(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int16_t *filter_x0, int32_t h) { - int32_t y; - uint8_t *cm = vpx_ff_cropTbl; - int32_t vector1b, vector2b, vector3b, vector4b; - int32_t Temp1, Temp2, Temp3, Temp4; - uint32_t vector4a = 64; - uint32_t tp1, tp2; - uint32_t p1, p2, p3, p4; - uint32_t n1, n2, n3, n4; - uint32_t tn1, tn2; - - vector1b = ((const int32_t *)filter_x0)[0]; - vector2b = ((const int32_t *)filter_x0)[1]; - vector3b = ((const int32_t *)filter_x0)[2]; - vector4b = ((const int32_t *)filter_x0)[3]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_store(dst + dst_stride); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p1], %[tp1] \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "preceu.ph.qbr %[p3], %[tp2] \n\t" - "preceu.ph.qbl %[p4], %[tp2] \n\t" - "dpa.w.ph $ac3, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p3], %[vector3b] \n\t" - "ulw %[tn2], 8(%[src]) \n\t" - "dpa.w.ph $ac3, %[p4], %[vector4b] \n\t" - "extp %[Temp1], $ac3, 31 \n\t" - - /* even 2. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[tn2] \n\t" - "balign %[tn1], %[tn2], 3 \n\t" - "balign %[tn2], %[tp2], 3 \n\t" - "balign %[tp2], %[tp1], 3 \n\t" - "dpa.w.ph $ac2, %[p2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p3], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[p4], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector4b] \n\t" - "extp %[Temp3], $ac2, 31 \n\t" - - "lbu %[p2], 3(%[dst]) \n\t" /* load odd 2 */ - - /* odd 1. pixel */ - "lbux %[tp1], %[Temp1](%[cm]) \n\t" /* even 1 */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "lbu %[Temp1], 1(%[dst]) \n\t" /* load odd 1 */ - "preceu.ph.qbr %[n1], %[tp2] \n\t" - "preceu.ph.qbl %[n2], %[tp2] \n\t" - "preceu.ph.qbr %[n3], %[tn2] \n\t" - "preceu.ph.qbl %[n4], %[tn2] \n\t" - "dpa.w.ph $ac3, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[n3], %[vector3b] \n\t" - "dpa.w.ph $ac3, %[n4], %[vector4b] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - "lbu %[tn2], 0(%[dst]) \n\t" /* load even 1 */ - - /* odd 2. pixel */ - "lbux %[tp2], %[Temp3](%[cm]) \n\t" /* even 2 */ - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[n1], %[tn1] \n\t" - "lbux %[tn1], %[Temp2](%[cm]) \n\t" /* odd 1 */ - "addqh_r.w %[tn2], %[tn2], %[tp1] \n\t" /* average even 1 */ - "dpa.w.ph $ac2, %[n2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[n3], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[n4], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[n1], %[vector4b] \n\t" - "extp %[Temp4], $ac2, 31 \n\t" - - "lbu %[tp1], 2(%[dst]) \n\t" /* load even 2 */ - "sb %[tn2], 0(%[dst]) \n\t" /* store even 1 */ - - /* clamp */ - "addqh_r.w %[Temp1], %[Temp1], %[tn1] \n\t" /* average odd 1 */ - "lbux %[n2], %[Temp4](%[cm]) \n\t" /* odd 2 */ - "sb %[Temp1], 1(%[dst]) \n\t" /* store odd 1 */ - - "addqh_r.w %[tp1], %[tp1], %[tp2] \n\t" /* average even 2 */ - "sb %[tp1], 2(%[dst]) \n\t" /* store even 2 */ - - "addqh_r.w %[p2], %[p2], %[n2] \n\t" /* average odd 2 */ - "sb %[p2], 3(%[dst]) \n\t" /* store odd 2 */ - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tn1] "=&r"(tn1), - [tn2] "=&r"(tn2), [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), - [p4] "=&r"(p4), [n1] "=&r"(n1), [n2] "=&r"(n2), [n3] "=&r"(n3), - [n4] "=&r"(n4), [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), - [Temp3] "=&r"(Temp3), [Temp4] "=&r"(Temp4) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector3b] "r"(vector3b), [vector4b] "r"(vector4b), - [vector4a] "r"(vector4a), [cm] "r"(cm), [dst] "r"(dst), - [src] "r"(src)); - - /* Next row... */ - src += src_stride; - dst += dst_stride; - } -} - -static void convolve_avg_horiz_8_dspr2(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int16_t *filter_x0, int32_t h) { - int32_t y; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector4a = 64; - int32_t vector1b, vector2b, vector3b, vector4b; - int32_t Temp1, Temp2, Temp3; - uint32_t tp1, tp2; - uint32_t p1, p2, p3, p4, n1; - uint32_t tn1, tn2, tn3; - uint32_t st0, st1; - - vector1b = ((const int32_t *)filter_x0)[0]; - vector2b = ((const int32_t *)filter_x0)[1]; - vector3b = ((const int32_t *)filter_x0)[2]; - vector4b = ((const int32_t *)filter_x0)[3]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_store(dst + dst_stride); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[tp1] \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "preceu.ph.qbr %[p3], %[tp2] \n\t" - "preceu.ph.qbl %[p4], %[tp2] \n\t" - "ulw %[tn2], 8(%[src]) \n\t" - "dpa.w.ph $ac3, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p3], %[vector3b] \n\t" - "dpa.w.ph $ac3, %[p4], %[vector4b] \n\t" - "extp %[Temp1], $ac3, 31 \n\t" - "lbu %[Temp2], 0(%[dst]) \n\t" - "lbu %[tn3], 2(%[dst]) \n\t" - - /* even 2. pixel */ - "preceu.ph.qbr %[p1], %[tn2] \n\t" - "preceu.ph.qbl %[n1], %[tn2] \n\t" - "ulw %[tn1], 12(%[src]) \n\t" - "dpa.w.ph $ac2, %[p2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p3], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[p4], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector4b] \n\t" - "extp %[Temp3], $ac2, 31 \n\t" - - /* even 3. pixel */ - "lbux %[st0], %[Temp1](%[cm]) \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p2], %[tn1] \n\t" - "lbux %[st1], %[Temp3](%[cm]) \n\t" - "dpa.w.ph $ac1, %[p3], %[vector1b] \n\t" - "dpa.w.ph $ac1, %[p4], %[vector2b] \n\t" - "dpa.w.ph $ac1, %[p1], %[vector3b] \n\t" - "dpa.w.ph $ac1, %[n1], %[vector4b] \n\t" - "extp %[Temp1], $ac1, 31 \n\t" - - "addqh_r.w %[Temp2], %[Temp2], %[st0] \n\t" - "addqh_r.w %[tn3], %[tn3], %[st1] \n\t" - "sb %[Temp2], 0(%[dst]) \n\t" - "sb %[tn3], 2(%[dst]) \n\t" - - /* even 4. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "balign %[tn3], %[tn1], 3 \n\t" - "balign %[tn1], %[tn2], 3 \n\t" - "balign %[tn2], %[tp2], 3 \n\t" - "balign %[tp2], %[tp1], 3 \n\t" - - "lbux %[st0], %[Temp1](%[cm]) \n\t" - "lbu %[Temp2], 4(%[dst]) \n\t" - "addqh_r.w %[Temp2], %[Temp2], %[st0] \n\t" - - "dpa.w.ph $ac2, %[p4], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[n1], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector4b] \n\t" - "extp %[Temp3], $ac2, 31 \n\t" - - /* odd 1. pixel */ - "mtlo %[vector4a], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "sb %[Temp2], 4(%[dst]) \n\t" - "preceu.ph.qbr %[p1], %[tp2] \n\t" - "preceu.ph.qbl %[p2], %[tp2] \n\t" - "preceu.ph.qbr %[p3], %[tn2] \n\t" - "preceu.ph.qbl %[p4], %[tn2] \n\t" - "dpa.w.ph $ac3, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p3], %[vector3b] \n\t" - "dpa.w.ph $ac3, %[p4], %[vector4b] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - "lbu %[tp1], 6(%[dst]) \n\t" - - /* odd 2. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[tn1] \n\t" - "preceu.ph.qbl %[n1], %[tn1] \n\t" - "lbux %[st0], %[Temp3](%[cm]) \n\t" - "dpa.w.ph $ac1, %[p2], %[vector1b] \n\t" - "dpa.w.ph $ac1, %[p3], %[vector2b] \n\t" - "dpa.w.ph $ac1, %[p4], %[vector3b] \n\t" - "dpa.w.ph $ac1, %[p1], %[vector4b] \n\t" - "extp %[Temp3], $ac1, 31 \n\t" - - "lbu %[tp2], 1(%[dst]) \n\t" - "lbu %[tn2], 3(%[dst]) \n\t" - "addqh_r.w %[tp1], %[tp1], %[st0] \n\t" - - /* odd 3. pixel */ - "lbux %[st1], %[Temp2](%[cm]) \n\t" - "preceu.ph.qbr %[p2], %[tn3] \n\t" - "dpa.w.ph $ac3, %[p3], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p4], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p1], %[vector3b] \n\t" - "dpa.w.ph $ac3, %[n1], %[vector4b] \n\t" - "addqh_r.w %[tp2], %[tp2], %[st1] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - "lbu %[tn3], 5(%[dst]) \n\t" - - /* odd 4. pixel */ - "sb %[tp2], 1(%[dst]) \n\t" - "sb %[tp1], 6(%[dst]) \n\t" - "dpa.w.ph $ac2, %[p4], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[n1], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector4b] \n\t" - "extp %[Temp1], $ac2, 31 \n\t" - - "lbu %[tn1], 7(%[dst]) \n\t" - - /* clamp */ - "lbux %[p4], %[Temp3](%[cm]) \n\t" - "addqh_r.w %[tn2], %[tn2], %[p4] \n\t" - - "lbux %[p2], %[Temp2](%[cm]) \n\t" - "addqh_r.w %[tn3], %[tn3], %[p2] \n\t" - - "lbux %[n1], %[Temp1](%[cm]) \n\t" - "addqh_r.w %[tn1], %[tn1], %[n1] \n\t" - - /* store bytes */ - "sb %[tn2], 3(%[dst]) \n\t" - "sb %[tn3], 5(%[dst]) \n\t" - "sb %[tn1], 7(%[dst]) \n\t" - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tn1] "=&r"(tn1), - [tn2] "=&r"(tn2), [tn3] "=&r"(tn3), [st0] "=&r"(st0), - [st1] "=&r"(st1), [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), - [p4] "=&r"(p4), [n1] "=&r"(n1), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector3b] "r"(vector3b), [vector4b] "r"(vector4b), - [vector4a] "r"(vector4a), [cm] "r"(cm), [dst] "r"(dst), - [src] "r"(src)); - - /* Next row... */ - src += src_stride; - dst += dst_stride; - } -} - -static void convolve_avg_horiz_16_dspr2(const uint8_t *src_ptr, - int32_t src_stride, uint8_t *dst_ptr, - int32_t dst_stride, - const int16_t *filter_x0, int32_t h, - int32_t count) { - int32_t y, c; - const uint8_t *src; - uint8_t *dst; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector_64 = 64; - int32_t filter12, filter34, filter56, filter78; - int32_t Temp1, Temp2, Temp3; - uint32_t qload1, qload2, qload3; - uint32_t p1, p2, p3, p4, p5; - uint32_t st1, st2, st3; - - filter12 = ((const int32_t *)filter_x0)[0]; - filter34 = ((const int32_t *)filter_x0)[1]; - filter56 = ((const int32_t *)filter_x0)[2]; - filter78 = ((const int32_t *)filter_x0)[3]; - - for (y = h; y--;) { - src = src_ptr; - dst = dst_ptr; - - /* prefetch data to cache memory */ - prefetch_load(src_ptr + src_stride); - prefetch_load(src_ptr + src_stride + 32); - prefetch_store(dst_ptr + dst_stride); - - for (c = 0; c < count; c++) { - __asm__ __volatile__( - "ulw %[qload1], 0(%[src]) \n\t" - "ulw %[qload2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 1 */ - "mthi $zero, $ac1 \n\t" - "mtlo %[vector_64], $ac2 \n\t" /* even 2 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[qload1] \n\t" - "preceu.ph.qbl %[p2], %[qload1] \n\t" - "preceu.ph.qbr %[p3], %[qload2] \n\t" - "preceu.ph.qbl %[p4], %[qload2] \n\t" - "ulw %[qload3], 8(%[src]) \n\t" - "dpa.w.ph $ac1, %[p1], %[filter12] \n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p2], %[filter34] \n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p3], %[filter56] \n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p4], %[filter78] \n\t" /* even 1 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 1 */ - "lbu %[st2], 0(%[dst]) \n\t" /* load even 1 from dst */ - - /* even 2. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* even 3 */ - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p1], %[qload3] \n\t" - "preceu.ph.qbl %[p5], %[qload3] \n\t" - "ulw %[qload1], 12(%[src]) \n\t" - "dpa.w.ph $ac2, %[p2], %[filter12] \n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p3], %[filter34] \n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p4], %[filter56] \n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p1], %[filter78] \n\t" /* even 1 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 1 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 1 */ - - "lbu %[qload3], 2(%[dst]) \n\t" /* load even 2 from dst */ - - /* even 3. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 4 */ - "mthi $zero, $ac1 \n\t" - "addqh_r.w %[st2], %[st2], %[st1] \n\t" /* average even 1 */ - "preceu.ph.qbr %[p2], %[qload1] \n\t" - "sb %[st2], 0(%[dst]) \n\t" /* store even 1 to dst */ - "dpa.w.ph $ac3, %[p3], %[filter12] \n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p4], %[filter34] \n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p1], %[filter56] \n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p5], %[filter78] \n\t" /* even 3 */ - "extp %[Temp3], $ac3, 31 \n\t" /* even 3 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 1 */ - - /* even 4. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* even 5 */ - "mthi $zero, $ac2 \n\t" - "addqh_r.w %[qload3], %[qload3], %[st2] \n\t" /* average even 2 */ - "preceu.ph.qbl %[p3], %[qload1] \n\t" - "sb %[qload3], 2(%[dst]) \n\t" /* store even 2 to dst */ - "ulw %[qload2], 16(%[src]) \n\t" - "lbu %[qload3], 4(%[dst]) \n\t" /* load even 3 from dst */ - "lbu %[qload1], 6(%[dst]) \n\t" /* load even 4 from dst */ - "dpa.w.ph $ac1, %[p4], %[filter12] \n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p1], %[filter34] \n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p5], %[filter56] \n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p2], %[filter78] \n\t" /* even 4 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 4 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* even 3 */ - - /* even 5. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* even 6 */ - "mthi $zero, $ac3 \n\t" - "addqh_r.w %[qload3], %[qload3], %[st3] \n\t" /* average even 3 */ - "preceu.ph.qbr %[p4], %[qload2] \n\t" - "sb %[qload3], 4(%[dst]) \n\t" /* store even 3 to dst */ - "dpa.w.ph $ac2, %[p1], %[filter12] \n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p5], %[filter34] \n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p2], %[filter56] \n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p3], %[filter78] \n\t" /* even 5 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 5 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 4 */ - - /* even 6. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 7 */ - "mthi $zero, $ac1 \n\t" - "addqh_r.w %[qload1], %[qload1], %[st1] \n\t" /* average even 4 */ - "preceu.ph.qbl %[p1], %[qload2] \n\t" - "sb %[qload1], 6(%[dst]) \n\t" /* store even 4 to dst */ - "ulw %[qload3], 20(%[src]) \n\t" - "dpa.w.ph $ac3, %[p5], %[filter12] \n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p2], %[filter34] \n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p3], %[filter56] \n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p4], %[filter78] \n\t" /* even 6 */ - "lbu %[qload2], 8(%[dst]) \n\t" /* load even 5 from dst */ - "extp %[Temp3], $ac3, 31 \n\t" /* even 6 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 5 */ - - /* even 7. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* even 8 */ - "mthi $zero, $ac2 \n\t" - "addqh_r.w %[qload2], %[qload2], %[st2] \n\t" /* average even 5 */ - "preceu.ph.qbr %[p5], %[qload3] \n\t" - "sb %[qload2], 8(%[dst]) \n\t" /* store even 5 to dst */ - "dpa.w.ph $ac1, %[p2], %[filter12] \n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p3], %[filter34] \n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p4], %[filter56] \n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p1], %[filter78] \n\t" /* even 7 */ - "lbu %[qload3], 10(%[dst]) \n\t" /* load even 6 from dst */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 7 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* even 6 */ - - "lbu %[st2], 12(%[dst]) \n\t" /* load even 7 from dst */ - - /* even 8. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 1 */ - "mthi $zero, $ac3 \n\t" - "addqh_r.w %[qload3], %[qload3], %[st3] \n\t" /* average even 6 */ - "dpa.w.ph $ac2, %[p3], %[filter12] \n\t" /* even 8 */ - "dpa.w.ph $ac2, %[p4], %[filter34] \n\t" /* even 8 */ - "sb %[qload3], 10(%[dst]) \n\t" /* store even 6 to dst */ - "dpa.w.ph $ac2, %[p1], %[filter56] \n\t" /* even 8 */ - "dpa.w.ph $ac2, %[p5], %[filter78] \n\t" /* even 8 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 8 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 7 */ - - /* ODD pixels */ - "ulw %[qload1], 1(%[src]) \n\t" - "ulw %[qload2], 5(%[src]) \n\t" - - "addqh_r.w %[st2], %[st2], %[st1] \n\t" /* average even 7 */ - - /* odd 1. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 2 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p1], %[qload1] \n\t" - "preceu.ph.qbl %[p2], %[qload1] \n\t" - "preceu.ph.qbr %[p3], %[qload2] \n\t" - "preceu.ph.qbl %[p4], %[qload2] \n\t" - "sb %[st2], 12(%[dst]) \n\t" /* store even 7 to dst */ - "ulw %[qload3], 9(%[src]) \n\t" - "dpa.w.ph $ac3, %[p1], %[filter12] \n\t" /* odd 1 */ - "dpa.w.ph $ac3, %[p2], %[filter34] \n\t" /* odd 1 */ - "lbu %[qload2], 14(%[dst]) \n\t" /* load even 8 from dst */ - "dpa.w.ph $ac3, %[p3], %[filter56] \n\t" /* odd 1 */ - "dpa.w.ph $ac3, %[p4], %[filter78] \n\t" /* odd 1 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 1 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 8 */ - - "lbu %[st1], 1(%[dst]) \n\t" /* load odd 1 from dst */ - - /* odd 2. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* odd 3 */ - "mthi $zero, $ac2 \n\t" - "addqh_r.w %[qload2], %[qload2], %[st2] \n\t" /* average even 8 */ - "preceu.ph.qbr %[p1], %[qload3] \n\t" - "preceu.ph.qbl %[p5], %[qload3] \n\t" - "sb %[qload2], 14(%[dst]) \n\t" /* store even 8 to dst */ - "ulw %[qload1], 13(%[src]) \n\t" - "dpa.w.ph $ac1, %[p2], %[filter12] \n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p3], %[filter34] \n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p4], %[filter56] \n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p1], %[filter78] \n\t" /* odd 2 */ - "lbu %[qload3], 3(%[dst]) \n\t" /* load odd 2 from dst */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 2 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 1 */ - - /* odd 3. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 4 */ - "mthi $zero, $ac3 \n\t" - "addqh_r.w %[st3], %[st3], %[st1] \n\t" /* average odd 1 */ - "preceu.ph.qbr %[p2], %[qload1] \n\t" - "dpa.w.ph $ac2, %[p3], %[filter12] \n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p4], %[filter34] \n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p1], %[filter56] \n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p5], %[filter78] \n\t" /* odd 3 */ - "sb %[st3], 1(%[dst]) \n\t" /* store odd 1 to dst */ - "extp %[Temp2], $ac2, 31 \n\t" /* odd 3 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 2 */ - - /* odd 4. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 5 */ - "mthi $zero, $ac1 \n\t" - "addqh_r.w %[qload3], %[qload3], %[st1] \n\t" /* average odd 2 */ - "preceu.ph.qbl %[p3], %[qload1] \n\t" - "sb %[qload3], 3(%[dst]) \n\t" /* store odd 2 to dst */ - "lbu %[qload1], 5(%[dst]) \n\t" /* load odd 3 from dst */ - "ulw %[qload2], 17(%[src]) \n\t" - "dpa.w.ph $ac3, %[p4], %[filter12] \n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p1], %[filter34] \n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p5], %[filter56] \n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p2], %[filter78] \n\t" /* odd 4 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 4 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* odd 3 */ - - "lbu %[st1], 7(%[dst]) \n\t" /* load odd 4 from dst */ - - /* odd 5. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* odd 6 */ - "mthi $zero, $ac2 \n\t" - "addqh_r.w %[qload1], %[qload1], %[st2] \n\t" /* average odd 3 */ - "preceu.ph.qbr %[p4], %[qload2] \n\t" - "sb %[qload1], 5(%[dst]) \n\t" /* store odd 3 to dst */ - "dpa.w.ph $ac1, %[p1], %[filter12] \n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p5], %[filter34] \n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p2], %[filter56] \n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p3], %[filter78] \n\t" /* odd 5 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 5 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 4 */ - - "lbu %[qload1], 9(%[dst]) \n\t" /* load odd 5 from dst */ - - /* odd 6. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 7 */ - "mthi $zero, $ac3 \n\t" - "addqh_r.w %[st1], %[st1], %[st3] \n\t" /* average odd 4 */ - "preceu.ph.qbl %[p1], %[qload2] \n\t" - "sb %[st1], 7(%[dst]) \n\t" /* store odd 4 to dst */ - "ulw %[qload3], 21(%[src]) \n\t" - "dpa.w.ph $ac2, %[p5], %[filter12] \n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p2], %[filter34] \n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p3], %[filter56] \n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p4], %[filter78] \n\t" /* odd 6 */ - "extp %[Temp2], $ac2, 31 \n\t" /* odd 6 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 5 */ - - /* odd 7. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 8 */ - "mthi $zero, $ac1 \n\t" - "addqh_r.w %[qload1], %[qload1], %[st1] \n\t" /* average odd 5 */ - "preceu.ph.qbr %[p5], %[qload3] \n\t" - "sb %[qload1], 9(%[dst]) \n\t" /* store odd 5 to dst */ - "lbu %[qload2], 11(%[dst]) \n\t" /* load odd 6 from dst */ - "dpa.w.ph $ac3, %[p2], %[filter12] \n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p3], %[filter34] \n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p4], %[filter56] \n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p1], %[filter78] \n\t" /* odd 7 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 7 */ - - "lbu %[qload3], 13(%[dst]) \n\t" /* load odd 7 from dst */ - - /* odd 8. pixel */ - "dpa.w.ph $ac1, %[p3], %[filter12] \n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p4], %[filter34] \n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p1], %[filter56] \n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p5], %[filter78] \n\t" /* odd 8 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 8 */ - - "lbu %[qload1], 15(%[dst]) \n\t" /* load odd 8 from dst */ - - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* odd 6 */ - "addqh_r.w %[qload2], %[qload2], %[st2] \n\t" /* average odd 6 */ - - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 7 */ - "addqh_r.w %[qload3], %[qload3], %[st3] \n\t" /* average odd 7 */ - - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 8 */ - "addqh_r.w %[qload1], %[qload1], %[st1] \n\t" /* average odd 8 */ - - "sb %[qload2], 11(%[dst]) \n\t" /* store odd 6 to dst */ - "sb %[qload3], 13(%[dst]) \n\t" /* store odd 7 to dst */ - "sb %[qload1], 15(%[dst]) \n\t" /* store odd 8 to dst */ - - : [qload1] "=&r"(qload1), [qload2] "=&r"(qload2), [st1] "=&r"(st1), - [st2] "=&r"(st2), [st3] "=&r"(st3), [p1] "=&r"(p1), [p2] "=&r"(p2), - [p3] "=&r"(p3), [p4] "=&r"(p4), [qload3] "=&r"(qload3), - [p5] "=&r"(p5), [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), - [Temp3] "=&r"(Temp3) - : [filter12] "r"(filter12), [filter34] "r"(filter34), - [filter56] "r"(filter56), [filter78] "r"(filter78), - [vector_64] "r"(vector_64), [cm] "r"(cm), [dst] "r"(dst), - [src] "r"(src)); - - src += 16; - dst += 16; - } - - /* Next row... */ - src_ptr += src_stride; - dst_ptr += dst_stride; - } -} - -static void convolve_avg_horiz_64_dspr2(const uint8_t *src_ptr, - int32_t src_stride, uint8_t *dst_ptr, - int32_t dst_stride, - const int16_t *filter_x0, int32_t h) { - int32_t y, c; - const uint8_t *src; - uint8_t *dst; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector_64 = 64; - int32_t filter12, filter34, filter56, filter78; - int32_t Temp1, Temp2, Temp3; - uint32_t qload1, qload2, qload3; - uint32_t p1, p2, p3, p4, p5; - uint32_t st1, st2, st3; - - filter12 = ((const int32_t *)filter_x0)[0]; - filter34 = ((const int32_t *)filter_x0)[1]; - filter56 = ((const int32_t *)filter_x0)[2]; - filter78 = ((const int32_t *)filter_x0)[3]; - - for (y = h; y--;) { - src = src_ptr; - dst = dst_ptr; - - /* prefetch data to cache memory */ - prefetch_load(src_ptr + src_stride); - prefetch_load(src_ptr + src_stride + 32); - prefetch_load(src_ptr + src_stride + 64); - prefetch_store(dst_ptr + dst_stride); - prefetch_store(dst_ptr + dst_stride + 32); - - for (c = 0; c < 4; c++) { - __asm__ __volatile__( - "ulw %[qload1], 0(%[src]) \n\t" - "ulw %[qload2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 1 */ - "mthi $zero, $ac1 \n\t" - "mtlo %[vector_64], $ac2 \n\t" /* even 2 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[qload1] \n\t" - "preceu.ph.qbl %[p2], %[qload1] \n\t" - "preceu.ph.qbr %[p3], %[qload2] \n\t" - "preceu.ph.qbl %[p4], %[qload2] \n\t" - "ulw %[qload3], 8(%[src]) \n\t" - "dpa.w.ph $ac1, %[p1], %[filter12] \n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p2], %[filter34] \n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p3], %[filter56] \n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p4], %[filter78] \n\t" /* even 1 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 1 */ - "lbu %[st2], 0(%[dst]) \n\t" /* load even 1 from dst */ - - /* even 2. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* even 3 */ - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p1], %[qload3] \n\t" - "preceu.ph.qbl %[p5], %[qload3] \n\t" - "ulw %[qload1], 12(%[src]) \n\t" - "dpa.w.ph $ac2, %[p2], %[filter12] \n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p3], %[filter34] \n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p4], %[filter56] \n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p1], %[filter78] \n\t" /* even 1 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 1 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 1 */ - - "lbu %[qload3], 2(%[dst]) \n\t" /* load even 2 from dst */ - - /* even 3. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 4 */ - "mthi $zero, $ac1 \n\t" - "addqh_r.w %[st2], %[st2], %[st1] \n\t" /* average even 1 */ - "preceu.ph.qbr %[p2], %[qload1] \n\t" - "sb %[st2], 0(%[dst]) \n\t" /* store even 1 to dst */ - "dpa.w.ph $ac3, %[p3], %[filter12] \n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p4], %[filter34] \n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p1], %[filter56] \n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p5], %[filter78] \n\t" /* even 3 */ - "extp %[Temp3], $ac3, 31 \n\t" /* even 3 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 1 */ - - /* even 4. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* even 5 */ - "mthi $zero, $ac2 \n\t" - "addqh_r.w %[qload3], %[qload3], %[st2] \n\t" /* average even 2 */ - "preceu.ph.qbl %[p3], %[qload1] \n\t" - "sb %[qload3], 2(%[dst]) \n\t" /* store even 2 to dst */ - "ulw %[qload2], 16(%[src]) \n\t" - "lbu %[qload3], 4(%[dst]) \n\t" /* load even 3 from dst */ - "lbu %[qload1], 6(%[dst]) \n\t" /* load even 4 from dst */ - "dpa.w.ph $ac1, %[p4], %[filter12] \n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p1], %[filter34] \n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p5], %[filter56] \n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p2], %[filter78] \n\t" /* even 4 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 4 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* even 3 */ - - /* even 5. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* even 6 */ - "mthi $zero, $ac3 \n\t" - "addqh_r.w %[qload3], %[qload3], %[st3] \n\t" /* average even 3 */ - "preceu.ph.qbr %[p4], %[qload2] \n\t" - "sb %[qload3], 4(%[dst]) \n\t" /* store even 3 to dst */ - "dpa.w.ph $ac2, %[p1], %[filter12] \n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p5], %[filter34] \n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p2], %[filter56] \n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p3], %[filter78] \n\t" /* even 5 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 5 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 4 */ - - /* even 6. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 7 */ - "mthi $zero, $ac1 \n\t" - "addqh_r.w %[qload1], %[qload1], %[st1] \n\t" /* average even 4 */ - "preceu.ph.qbl %[p1], %[qload2] \n\t" - "sb %[qload1], 6(%[dst]) \n\t" /* store even 4 to dst */ - "ulw %[qload3], 20(%[src]) \n\t" - "dpa.w.ph $ac3, %[p5], %[filter12] \n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p2], %[filter34] \n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p3], %[filter56] \n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p4], %[filter78] \n\t" /* even 6 */ - "lbu %[qload2], 8(%[dst]) \n\t" /* load even 5 from dst */ - "extp %[Temp3], $ac3, 31 \n\t" /* even 6 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 5 */ - - /* even 7. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* even 8 */ - "mthi $zero, $ac2 \n\t" - "addqh_r.w %[qload2], %[qload2], %[st2] \n\t" /* average even 5 */ - "preceu.ph.qbr %[p5], %[qload3] \n\t" - "sb %[qload2], 8(%[dst]) \n\t" /* store even 5 to dst */ - "dpa.w.ph $ac1, %[p2], %[filter12] \n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p3], %[filter34] \n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p4], %[filter56] \n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p1], %[filter78] \n\t" /* even 7 */ - "lbu %[qload3], 10(%[dst]) \n\t" /* load even 6 from dst */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 7 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* even 6 */ - - "lbu %[st2], 12(%[dst]) \n\t" /* load even 7 from dst */ - - /* even 8. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 1 */ - "mthi $zero, $ac3 \n\t" - "addqh_r.w %[qload3], %[qload3], %[st3] \n\t" /* average even 6 */ - "dpa.w.ph $ac2, %[p3], %[filter12] \n\t" /* even 8 */ - "dpa.w.ph $ac2, %[p4], %[filter34] \n\t" /* even 8 */ - "sb %[qload3], 10(%[dst]) \n\t" /* store even 6 to dst */ - "dpa.w.ph $ac2, %[p1], %[filter56] \n\t" /* even 8 */ - "dpa.w.ph $ac2, %[p5], %[filter78] \n\t" /* even 8 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 8 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 7 */ - - /* ODD pixels */ - "ulw %[qload1], 1(%[src]) \n\t" - "ulw %[qload2], 5(%[src]) \n\t" - - "addqh_r.w %[st2], %[st2], %[st1] \n\t" /* average even 7 */ - - /* odd 1. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 2 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p1], %[qload1] \n\t" - "preceu.ph.qbl %[p2], %[qload1] \n\t" - "preceu.ph.qbr %[p3], %[qload2] \n\t" - "preceu.ph.qbl %[p4], %[qload2] \n\t" - "sb %[st2], 12(%[dst]) \n\t" /* store even 7 to dst */ - "ulw %[qload3], 9(%[src]) \n\t" - "dpa.w.ph $ac3, %[p1], %[filter12] \n\t" /* odd 1 */ - "dpa.w.ph $ac3, %[p2], %[filter34] \n\t" /* odd 1 */ - "lbu %[qload2], 14(%[dst]) \n\t" /* load even 8 from dst */ - "dpa.w.ph $ac3, %[p3], %[filter56] \n\t" /* odd 1 */ - "dpa.w.ph $ac3, %[p4], %[filter78] \n\t" /* odd 1 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 1 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 8 */ - - "lbu %[st1], 1(%[dst]) \n\t" /* load odd 1 from dst */ - - /* odd 2. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* odd 3 */ - "mthi $zero, $ac2 \n\t" - "addqh_r.w %[qload2], %[qload2], %[st2] \n\t" /* average even 8 */ - "preceu.ph.qbr %[p1], %[qload3] \n\t" - "preceu.ph.qbl %[p5], %[qload3] \n\t" - "sb %[qload2], 14(%[dst]) \n\t" /* store even 8 to dst */ - "ulw %[qload1], 13(%[src]) \n\t" - "dpa.w.ph $ac1, %[p2], %[filter12] \n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p3], %[filter34] \n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p4], %[filter56] \n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p1], %[filter78] \n\t" /* odd 2 */ - "lbu %[qload3], 3(%[dst]) \n\t" /* load odd 2 from dst */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 2 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 1 */ - - /* odd 3. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 4 */ - "mthi $zero, $ac3 \n\t" - "addqh_r.w %[st3], %[st3], %[st1] \n\t" /* average odd 1 */ - "preceu.ph.qbr %[p2], %[qload1] \n\t" - "dpa.w.ph $ac2, %[p3], %[filter12] \n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p4], %[filter34] \n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p1], %[filter56] \n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p5], %[filter78] \n\t" /* odd 3 */ - "sb %[st3], 1(%[dst]) \n\t" /* store odd 1 to dst */ - "extp %[Temp2], $ac2, 31 \n\t" /* odd 3 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 2 */ - - /* odd 4. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 5 */ - "mthi $zero, $ac1 \n\t" - "addqh_r.w %[qload3], %[qload3], %[st1] \n\t" /* average odd 2 */ - "preceu.ph.qbl %[p3], %[qload1] \n\t" - "sb %[qload3], 3(%[dst]) \n\t" /* store odd 2 to dst */ - "lbu %[qload1], 5(%[dst]) \n\t" /* load odd 3 from dst */ - "ulw %[qload2], 17(%[src]) \n\t" - "dpa.w.ph $ac3, %[p4], %[filter12] \n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p1], %[filter34] \n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p5], %[filter56] \n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p2], %[filter78] \n\t" /* odd 4 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 4 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* odd 3 */ - - "lbu %[st1], 7(%[dst]) \n\t" /* load odd 4 from dst */ - - /* odd 5. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* odd 6 */ - "mthi $zero, $ac2 \n\t" - "addqh_r.w %[qload1], %[qload1], %[st2] \n\t" /* average odd 3 */ - "preceu.ph.qbr %[p4], %[qload2] \n\t" - "sb %[qload1], 5(%[dst]) \n\t" /* store odd 3 to dst */ - "dpa.w.ph $ac1, %[p1], %[filter12] \n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p5], %[filter34] \n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p2], %[filter56] \n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p3], %[filter78] \n\t" /* odd 5 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 5 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 4 */ - - "lbu %[qload1], 9(%[dst]) \n\t" /* load odd 5 from dst */ - - /* odd 6. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 7 */ - "mthi $zero, $ac3 \n\t" - "addqh_r.w %[st1], %[st1], %[st3] \n\t" /* average odd 4 */ - "preceu.ph.qbl %[p1], %[qload2] \n\t" - "sb %[st1], 7(%[dst]) \n\t" /* store odd 4 to dst */ - "ulw %[qload3], 21(%[src]) \n\t" - "dpa.w.ph $ac2, %[p5], %[filter12] \n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p2], %[filter34] \n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p3], %[filter56] \n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p4], %[filter78] \n\t" /* odd 6 */ - "extp %[Temp2], $ac2, 31 \n\t" /* odd 6 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 5 */ - - /* odd 7. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 8 */ - "mthi $zero, $ac1 \n\t" - "addqh_r.w %[qload1], %[qload1], %[st1] \n\t" /* average odd 5 */ - "preceu.ph.qbr %[p5], %[qload3] \n\t" - "sb %[qload1], 9(%[dst]) \n\t" /* store odd 5 to dst */ - "lbu %[qload2], 11(%[dst]) \n\t" /* load odd 6 from dst */ - "dpa.w.ph $ac3, %[p2], %[filter12] \n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p3], %[filter34] \n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p4], %[filter56] \n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p1], %[filter78] \n\t" /* odd 7 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 7 */ - - "lbu %[qload3], 13(%[dst]) \n\t" /* load odd 7 from dst */ - - /* odd 8. pixel */ - "dpa.w.ph $ac1, %[p3], %[filter12] \n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p4], %[filter34] \n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p1], %[filter56] \n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p5], %[filter78] \n\t" /* odd 8 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 8 */ - - "lbu %[qload1], 15(%[dst]) \n\t" /* load odd 8 from dst */ - - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* odd 6 */ - "addqh_r.w %[qload2], %[qload2], %[st2] \n\t" /* average odd 6 */ - - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 7 */ - "addqh_r.w %[qload3], %[qload3], %[st3] \n\t" /* average odd 7 */ - - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 8 */ - "addqh_r.w %[qload1], %[qload1], %[st1] \n\t" /* average odd 8 */ - - "sb %[qload2], 11(%[dst]) \n\t" /* store odd 6 to dst */ - "sb %[qload3], 13(%[dst]) \n\t" /* store odd 7 to dst */ - "sb %[qload1], 15(%[dst]) \n\t" /* store odd 8 to dst */ - - : [qload1] "=&r"(qload1), [qload2] "=&r"(qload2), [st1] "=&r"(st1), - [st2] "=&r"(st2), [st3] "=&r"(st3), [p1] "=&r"(p1), [p2] "=&r"(p2), - [p3] "=&r"(p3), [p4] "=&r"(p4), [qload3] "=&r"(qload3), - [p5] "=&r"(p5), [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), - [Temp3] "=&r"(Temp3) - : [filter12] "r"(filter12), [filter34] "r"(filter34), - [filter56] "r"(filter56), [filter78] "r"(filter78), - [vector_64] "r"(vector_64), [cm] "r"(cm), [dst] "r"(dst), - [src] "r"(src)); - - src += 16; - dst += 16; - } - - /* Next row... */ - src_ptr += src_stride; - dst_ptr += dst_stride; - } -} - -void vpx_convolve8_avg_horiz_dspr2(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - const int16_t *const filter_x = filter[x0_q4]; - assert(x_step_q4 == 16); - assert(((const int32_t *)filter_x)[1] != 0x800000); - - if (vpx_get_filter_taps(filter_x) == 2) { - vpx_convolve2_avg_horiz_dspr2(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h); - } else { - uint32_t pos = 38; - - src -= 3; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - /* prefetch data to cache memory */ - prefetch_load(src); - prefetch_load(src + 32); - prefetch_store(dst); - - switch (w) { - case 4: - convolve_avg_horiz_4_dspr2(src, src_stride, dst, dst_stride, filter_x, - h); - break; - case 8: - convolve_avg_horiz_8_dspr2(src, src_stride, dst, dst_stride, filter_x, - h); - break; - case 16: - convolve_avg_horiz_16_dspr2(src, src_stride, dst, dst_stride, filter_x, - h, 1); - break; - case 32: - convolve_avg_horiz_16_dspr2(src, src_stride, dst, dst_stride, filter_x, - h, 2); - break; - case 64: - prefetch_load(src + 64); - prefetch_store(dst + 32); - - convolve_avg_horiz_64_dspr2(src, src_stride, dst, dst_stride, filter_x, - h); - break; - default: - vpx_convolve8_avg_horiz_c(src + 3, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve8_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve8_dspr2.c deleted file mode 100644 index 1e7052f6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve8_dspr2.c +++ /dev/null @@ -1,1602 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/convolve_common_dspr2.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_ports/mem.h" - -#if HAVE_DSPR2 -static void convolve_horiz_4_transposed_dspr2(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - const int16_t *filter_x0, - int32_t h) { - int32_t y; - uint8_t *cm = vpx_ff_cropTbl; - uint8_t *dst_ptr; - int32_t vector1b, vector2b, vector3b, vector4b; - int32_t Temp1, Temp2, Temp3, Temp4; - uint32_t vector4a = 64; - uint32_t tp1, tp2; - uint32_t p1, p2, p3, p4; - uint32_t tn1, tn2; - - vector1b = ((const int32_t *)filter_x0)[0]; - vector2b = ((const int32_t *)filter_x0)[1]; - vector3b = ((const int32_t *)filter_x0)[2]; - vector4b = ((const int32_t *)filter_x0)[3]; - - for (y = h; y--;) { - dst_ptr = dst; - /* prefetch data to cache memory */ - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p1], %[tp1] \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "preceu.ph.qbr %[p3], %[tp2] \n\t" - "preceu.ph.qbl %[p4], %[tp2] \n\t" - "dpa.w.ph $ac3, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p3], %[vector3b] \n\t" - "ulw %[tn2], 8(%[src]) \n\t" - "dpa.w.ph $ac3, %[p4], %[vector4b] \n\t" - "extp %[Temp1], $ac3, 31 \n\t" - - /* even 2. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[tn2] \n\t" - "balign %[tn1], %[tn2], 3 \n\t" - "balign %[tn2], %[tp2], 3 \n\t" - "balign %[tp2], %[tp1], 3 \n\t" - "dpa.w.ph $ac2, %[p2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p3], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[p4], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector4b] \n\t" - "extp %[Temp3], $ac2, 31 \n\t" - - /* odd 1. pixel */ - "lbux %[tp1], %[Temp1](%[cm]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p1], %[tp2] \n\t" - "preceu.ph.qbl %[p2], %[tp2] \n\t" - "preceu.ph.qbr %[p3], %[tn2] \n\t" - "preceu.ph.qbl %[p4], %[tn2] \n\t" - "dpa.w.ph $ac3, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p3], %[vector3b] \n\t" - "dpa.w.ph $ac3, %[p4], %[vector4b] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - /* odd 2. pixel */ - "lbux %[tp2], %[Temp3](%[cm]) \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[tn1] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p3], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[p4], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector4b] \n\t" - "extp %[Temp4], $ac2, 31 \n\t" - - /* clamp */ - "lbux %[tn1], %[Temp2](%[cm]) \n\t" - "lbux %[p2], %[Temp4](%[cm]) \n\t" - - /* store bytes */ - "sb %[tp1], 0(%[dst_ptr]) \n\t" - "addu %[dst_ptr], %[dst_ptr], %[dst_stride] \n\t" - - "sb %[tn1], 0(%[dst_ptr]) \n\t" - "addu %[dst_ptr], %[dst_ptr], %[dst_stride] \n\t" - - "sb %[tp2], 0(%[dst_ptr]) \n\t" - "addu %[dst_ptr], %[dst_ptr], %[dst_stride] \n\t" - - "sb %[p2], 0(%[dst_ptr]) \n\t" - "addu %[dst_ptr], %[dst_ptr], %[dst_stride] \n\t" - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tn1] "=&r"(tn1), - [tn2] "=&r"(tn2), [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), - [p4] "=&r"(p4), [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), - [Temp3] "=&r"(Temp3), [Temp4] "=&r"(Temp4), [dst_ptr] "+r"(dst_ptr) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector3b] "r"(vector3b), [vector4b] "r"(vector4b), - [vector4a] "r"(vector4a), [cm] "r"(cm), [src] "r"(src), - [dst_stride] "r"(dst_stride)); - - /* Next row... */ - src += src_stride; - dst += 1; - } -} - -static void convolve_horiz_8_transposed_dspr2(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - const int16_t *filter_x0, - int32_t h) { - int32_t y; - uint8_t *cm = vpx_ff_cropTbl; - uint8_t *dst_ptr; - uint32_t vector4a = 64; - int32_t vector1b, vector2b, vector3b, vector4b; - int32_t Temp1, Temp2, Temp3; - uint32_t tp1, tp2, tp3; - uint32_t p1, p2, p3, p4, n1; - uint8_t *odd_dst; - uint32_t dst_pitch_2 = (dst_stride << 1); - - vector1b = ((const int32_t *)filter_x0)[0]; - vector2b = ((const int32_t *)filter_x0)[1]; - vector3b = ((const int32_t *)filter_x0)[2]; - vector4b = ((const int32_t *)filter_x0)[3]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - - dst_ptr = dst; - odd_dst = (dst_ptr + dst_stride); - - __asm__ __volatile__( - "ulw %[tp2], 0(%[src]) \n\t" - "ulw %[tp1], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[tp2] \n\t" - "preceu.ph.qbl %[p2], %[tp2] \n\t" - "preceu.ph.qbr %[p3], %[tp1] \n\t" - "preceu.ph.qbl %[p4], %[tp1] \n\t" - "ulw %[tp3], 8(%[src]) \n\t" - "dpa.w.ph $ac3, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p3], %[vector3b] \n\t" - "dpa.w.ph $ac3, %[p4], %[vector4b] \n\t" - "extp %[Temp1], $ac3, 31 \n\t" - - /* even 2. pixel */ - "preceu.ph.qbr %[p1], %[tp3] \n\t" - "preceu.ph.qbl %[n1], %[tp3] \n\t" - "ulw %[tp2], 12(%[src]) \n\t" - "dpa.w.ph $ac2, %[p2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p3], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[p4], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector4b] \n\t" - "extp %[Temp3], $ac2, 31 \n\t" - - /* even 3. pixel */ - "lbux %[Temp2], %[Temp1](%[cm]) \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p2], %[tp2] \n\t" - "dpa.w.ph $ac1, %[p3], %[vector1b] \n\t" - "dpa.w.ph $ac1, %[p4], %[vector2b] \n\t" - "dpa.w.ph $ac1, %[p1], %[vector3b] \n\t" - "lbux %[tp3], %[Temp3](%[cm]) \n\t" - "dpa.w.ph $ac1, %[n1], %[vector4b] \n\t" - "extp %[p3], $ac1, 31 \n\t" - - /* even 4. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "sb %[Temp2], 0(%[dst_ptr]) \n\t" - "addu %[dst_ptr], %[dst_ptr], %[dst_pitch_2] \n\t" - "sb %[tp3], 0(%[dst_ptr]) \n\t" - "addu %[dst_ptr], %[dst_ptr], %[dst_pitch_2] \n\t" - - "ulw %[tp1], 1(%[src]) \n\t" - "ulw %[tp3], 5(%[src]) \n\t" - - "dpa.w.ph $ac2, %[p4], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[n1], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector4b] \n\t" - "extp %[Temp3], $ac2, 31 \n\t" - - "lbux %[tp2], %[p3](%[cm]) \n\t" - - /* odd 1. pixel */ - "mtlo %[vector4a], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p1], %[tp1] \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "preceu.ph.qbr %[p3], %[tp3] \n\t" - "preceu.ph.qbl %[p4], %[tp3] \n\t" - "sb %[tp2], 0(%[dst_ptr]) \n\t" - "addu %[dst_ptr], %[dst_ptr], %[dst_pitch_2] \n\t" - "ulw %[tp2], 9(%[src]) \n\t" - - "dpa.w.ph $ac3, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p3], %[vector3b] \n\t" - "dpa.w.ph $ac3, %[p4], %[vector4b] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - /* odd 2. pixel */ - "lbux %[tp1], %[Temp3](%[cm]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[tp2] \n\t" - "preceu.ph.qbl %[n1], %[tp2] \n\t" - "ulw %[Temp1], 13(%[src]) \n\t" - "dpa.w.ph $ac1, %[p2], %[vector1b] \n\t" - "sb %[tp1], 0(%[dst_ptr]) \n\t" - "addu %[dst_ptr], %[dst_ptr], %[dst_pitch_2] \n\t" - "dpa.w.ph $ac1, %[p3], %[vector2b] \n\t" - "dpa.w.ph $ac1, %[p4], %[vector3b] \n\t" - "dpa.w.ph $ac1, %[p1], %[vector4b] \n\t" - "extp %[Temp3], $ac1, 31 \n\t" - - /* odd 3. pixel */ - "lbux %[tp3], %[Temp2](%[cm]) \n\t" - "preceu.ph.qbr %[p2], %[Temp1] \n\t" - "dpa.w.ph $ac3, %[p3], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p4], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p1], %[vector3b] \n\t" - "dpa.w.ph $ac3, %[n1], %[vector4b] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - /* odd 4. pixel */ - "sb %[tp3], 0(%[odd_dst]) \n\t" - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] \n\t" - "dpa.w.ph $ac2, %[p4], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[n1], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector4b] \n\t" - "extp %[Temp1], $ac2, 31 \n\t" - - /* clamp */ - "lbux %[p4], %[Temp3](%[cm]) \n\t" - "lbux %[p2], %[Temp2](%[cm]) \n\t" - "lbux %[n1], %[Temp1](%[cm]) \n\t" - - /* store bytes */ - "sb %[p4], 0(%[odd_dst]) \n\t" - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] \n\t" - - "sb %[p2], 0(%[odd_dst]) \n\t" - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] \n\t" - - "sb %[n1], 0(%[odd_dst]) \n\t" - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tp3] "=&r"(tp3), [p1] "=&r"(p1), - [p2] "=&r"(p2), [p3] "=&r"(p3), [p4] "=&r"(p4), [n1] "=&r"(n1), - [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [dst_ptr] "+r"(dst_ptr), [odd_dst] "+r"(odd_dst) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector3b] "r"(vector3b), [vector4b] "r"(vector4b), - [vector4a] "r"(vector4a), [cm] "r"(cm), [src] "r"(src), - [dst_pitch_2] "r"(dst_pitch_2)); - - /* Next row... */ - src += src_stride; - dst += 1; - } -} - -static void convolve_horiz_16_transposed_dspr2( - const uint8_t *src_ptr, int32_t src_stride, uint8_t *dst_ptr, - int32_t dst_stride, const int16_t *filter_x0, int32_t h, int32_t count) { - int32_t c, y; - const uint8_t *src; - uint8_t *dst; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector_64 = 64; - int32_t filter12, filter34, filter56, filter78; - int32_t Temp1, Temp2, Temp3; - uint32_t qload1, qload2; - uint32_t p1, p2, p3, p4, p5; - uint32_t st1, st2, st3; - uint32_t dst_pitch_2 = (dst_stride << 1); - uint8_t *odd_dst; - - filter12 = ((const int32_t *)filter_x0)[0]; - filter34 = ((const int32_t *)filter_x0)[1]; - filter56 = ((const int32_t *)filter_x0)[2]; - filter78 = ((const int32_t *)filter_x0)[3]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_load(src_ptr + src_stride); - prefetch_load(src_ptr + src_stride + 32); - - src = src_ptr; - dst = dst_ptr; - - odd_dst = (dst + dst_stride); - - for (c = 0; c < count; c++) { - __asm__ __volatile__( - "ulw %[qload1], 0(%[src]) " - "\n\t" - "ulw %[qload2], 4(%[src]) " - "\n\t" - - /* even 1. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* even 1 */ - "mthi $zero, $ac1 " - "\n\t" - "mtlo %[vector_64], $ac2 " - "\n\t" /* even 2 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbr %[p3], %[qload2] " - "\n\t" - "preceu.ph.qbl %[p4], %[qload2] " - "\n\t" - "preceu.ph.qbr %[p1], %[qload1] " - "\n\t" - "preceu.ph.qbl %[p2], %[qload1] " - "\n\t" - "ulw %[qload2], 8(%[src]) " - "\n\t" - "dpa.w.ph $ac1, %[p1], %[filter12] " - "\n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p2], %[filter34] " - "\n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p3], %[filter56] " - "\n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p4], %[filter78] " - "\n\t" /* even 1 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* even 1 */ - - /* even 2. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* even 3 */ - "mthi $zero, $ac3 " - "\n\t" - "preceu.ph.qbr %[p1], %[qload2] " - "\n\t" - "preceu.ph.qbl %[p5], %[qload2] " - "\n\t" - "ulw %[qload1], 12(%[src]) " - "\n\t" - "dpa.w.ph $ac2, %[p2], %[filter12] " - "\n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p3], %[filter34] " - "\n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p4], %[filter56] " - "\n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p1], %[filter78] " - "\n\t" /* even 1 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* even 1 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* even 1 */ - - /* even 3. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* even 4 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbr %[p2], %[qload1] " - "\n\t" - "sb %[st1], 0(%[dst]) " - "\n\t" /* even 1 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - " \n\t" - "dpa.w.ph $ac3, %[p3], %[filter12] " - "\n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p4], %[filter34] " - "\n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p1], %[filter56] " - "\n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p5], %[filter78] " - "\n\t" /* even 3 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* even 3 */ - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* even 1 */ - - /* even 4. pixel */ - "mtlo %[vector_64], $ac2 " - "\n\t" /* even 5 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbl %[p3], %[qload1] " - "\n\t" - "sb %[st2], 0(%[dst]) " - "\n\t" /* even 2 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "ulw %[qload2], 16(%[src]) " - "\n\t" - "dpa.w.ph $ac1, %[p4], %[filter12] " - "\n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p1], %[filter34] " - "\n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p5], %[filter56] " - "\n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p2], %[filter78] " - "\n\t" /* even 4 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* even 4 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* even 3 */ - - /* even 5. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* even 6 */ - "mthi $zero, $ac3 " - "\n\t" - "preceu.ph.qbr %[p4], %[qload2] " - "\n\t" - "sb %[st3], 0(%[dst]) " - "\n\t" /* even 3 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac2, %[p1], %[filter12] " - "\n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p5], %[filter34] " - "\n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p2], %[filter56] " - "\n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p3], %[filter78] " - "\n\t" /* even 5 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* even 5 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* even 4 */ - - /* even 6. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* even 7 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbl %[p1], %[qload2] " - "\n\t" - "sb %[st1], 0(%[dst]) " - "\n\t" /* even 4 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "ulw %[qload1], 20(%[src]) " - "\n\t" - "dpa.w.ph $ac3, %[p5], %[filter12] " - "\n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p2], %[filter34] " - "\n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p3], %[filter56] " - "\n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p4], %[filter78] " - "\n\t" /* even 6 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* even 6 */ - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* even 5 */ - - /* even 7. pixel */ - "mtlo %[vector_64], $ac2 " - "\n\t" /* even 8 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbr %[p5], %[qload1] " - "\n\t" - "sb %[st2], 0(%[dst]) " - "\n\t" /* even 5 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac1, %[p2], %[filter12] " - "\n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p3], %[filter34] " - "\n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p4], %[filter56] " - "\n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p1], %[filter78] " - "\n\t" /* even 7 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* even 7 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* even 6 */ - - /* even 8. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* odd 1 */ - "mthi $zero, $ac3 " - "\n\t" - "dpa.w.ph $ac2, %[p3], %[filter12] " - "\n\t" /* even 8 */ - "dpa.w.ph $ac2, %[p4], %[filter34] " - "\n\t" /* even 8 */ - "sb %[st3], 0(%[dst]) " - "\n\t" /* even 6 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac2, %[p1], %[filter56] " - "\n\t" /* even 8 */ - "dpa.w.ph $ac2, %[p5], %[filter78] " - "\n\t" /* even 8 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* even 8 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* even 7 */ - - /* ODD pixels */ - "ulw %[qload1], 1(%[src]) " - "\n\t" - "ulw %[qload2], 5(%[src]) " - "\n\t" - - /* odd 1. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* odd 2 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbr %[p1], %[qload1] " - "\n\t" - "preceu.ph.qbl %[p2], %[qload1] " - "\n\t" - "preceu.ph.qbr %[p3], %[qload2] " - "\n\t" - "preceu.ph.qbl %[p4], %[qload2] " - "\n\t" - "sb %[st1], 0(%[dst]) " - "\n\t" /* even 7 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "ulw %[qload2], 9(%[src]) " - "\n\t" - "dpa.w.ph $ac3, %[p1], %[filter12] " - "\n\t" /* odd 1 */ - "dpa.w.ph $ac3, %[p2], %[filter34] " - "\n\t" /* odd 1 */ - "dpa.w.ph $ac3, %[p3], %[filter56] " - "\n\t" /* odd 1 */ - "dpa.w.ph $ac3, %[p4], %[filter78] " - "\n\t" /* odd 1 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* odd 1 */ - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* even 8 */ - - /* odd 2. pixel */ - "mtlo %[vector_64], $ac2 " - "\n\t" /* odd 3 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbr %[p1], %[qload2] " - "\n\t" - "preceu.ph.qbl %[p5], %[qload2] " - "\n\t" - "sb %[st2], 0(%[dst]) " - "\n\t" /* even 8 */ - "ulw %[qload1], 13(%[src]) " - "\n\t" - "dpa.w.ph $ac1, %[p2], %[filter12] " - "\n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p3], %[filter34] " - "\n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p4], %[filter56] " - "\n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p1], %[filter78] " - "\n\t" /* odd 2 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* odd 2 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* odd 1 */ - - /* odd 3. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* odd 4 */ - "mthi $zero, $ac3 " - "\n\t" - "preceu.ph.qbr %[p2], %[qload1] " - "\n\t" - "sb %[st3], 0(%[odd_dst]) " - "\n\t" /* odd 1 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac2, %[p3], %[filter12] " - "\n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p4], %[filter34] " - "\n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p1], %[filter56] " - "\n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p5], %[filter78] " - "\n\t" /* odd 3 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* odd 3 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* odd 2 */ - - /* odd 4. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* odd 5 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbl %[p3], %[qload1] " - "\n\t" - "sb %[st1], 0(%[odd_dst]) " - "\n\t" /* odd 2 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "ulw %[qload2], 17(%[src]) " - "\n\t" - "dpa.w.ph $ac3, %[p4], %[filter12] " - "\n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p1], %[filter34] " - "\n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p5], %[filter56] " - "\n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p2], %[filter78] " - "\n\t" /* odd 4 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* odd 4 */ - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* odd 3 */ - - /* odd 5. pixel */ - "mtlo %[vector_64], $ac2 " - "\n\t" /* odd 6 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbr %[p4], %[qload2] " - "\n\t" - "sb %[st2], 0(%[odd_dst]) " - "\n\t" /* odd 3 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac1, %[p1], %[filter12] " - "\n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p5], %[filter34] " - "\n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p2], %[filter56] " - "\n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p3], %[filter78] " - "\n\t" /* odd 5 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* odd 5 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* odd 4 */ - - /* odd 6. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* odd 7 */ - "mthi $zero, $ac3 " - "\n\t" - "preceu.ph.qbl %[p1], %[qload2] " - "\n\t" - "sb %[st3], 0(%[odd_dst]) " - "\n\t" /* odd 4 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "ulw %[qload1], 21(%[src]) " - "\n\t" - "dpa.w.ph $ac2, %[p5], %[filter12] " - "\n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p2], %[filter34] " - "\n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p3], %[filter56] " - "\n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p4], %[filter78] " - "\n\t" /* odd 6 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* odd 6 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* odd 5 */ - - /* odd 7. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* odd 8 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbr %[p5], %[qload1] " - "\n\t" - "sb %[st1], 0(%[odd_dst]) " - "\n\t" /* odd 5 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac3, %[p2], %[filter12] " - "\n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p3], %[filter34] " - "\n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p4], %[filter56] " - "\n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p1], %[filter78] " - "\n\t" /* odd 7 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* odd 7 */ - - /* odd 8. pixel */ - "dpa.w.ph $ac1, %[p3], %[filter12] " - "\n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p4], %[filter34] " - "\n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p1], %[filter56] " - "\n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p5], %[filter78] " - "\n\t" /* odd 8 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* odd 8 */ - - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* odd 6 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* odd 7 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* odd 8 */ - - "sb %[st2], 0(%[odd_dst]) " - "\n\t" /* odd 6 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - - "sb %[st3], 0(%[odd_dst]) " - "\n\t" /* odd 7 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - - "sb %[st1], 0(%[odd_dst]) " - "\n\t" /* odd 8 */ - - : [qload1] "=&r"(qload1), [qload2] "=&r"(qload2), [p5] "=&r"(p5), - [st1] "=&r"(st1), [st2] "=&r"(st2), [st3] "=&r"(st3), - [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), [p4] "=&r"(p4), - [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [dst] "+r"(dst), [odd_dst] "+r"(odd_dst) - : [filter12] "r"(filter12), [filter34] "r"(filter34), - [filter56] "r"(filter56), [filter78] "r"(filter78), - [vector_64] "r"(vector_64), [cm] "r"(cm), [src] "r"(src), - [dst_pitch_2] "r"(dst_pitch_2)); - - src += 16; - dst = (dst_ptr + ((c + 1) * 16 * dst_stride)); - odd_dst = (dst + dst_stride); - } - - /* Next row... */ - src_ptr += src_stride; - - dst_ptr += 1; - } -} - -static void convolve_horiz_64_transposed_dspr2( - const uint8_t *src_ptr, int32_t src_stride, uint8_t *dst_ptr, - int32_t dst_stride, const int16_t *filter_x0, int32_t h) { - int32_t c, y; - const uint8_t *src; - uint8_t *dst; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector_64 = 64; - int32_t filter12, filter34, filter56, filter78; - int32_t Temp1, Temp2, Temp3; - uint32_t qload1, qload2; - uint32_t p1, p2, p3, p4, p5; - uint32_t st1, st2, st3; - uint32_t dst_pitch_2 = (dst_stride << 1); - uint8_t *odd_dst; - - filter12 = ((const int32_t *)filter_x0)[0]; - filter34 = ((const int32_t *)filter_x0)[1]; - filter56 = ((const int32_t *)filter_x0)[2]; - filter78 = ((const int32_t *)filter_x0)[3]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_load(src_ptr + src_stride); - prefetch_load(src_ptr + src_stride + 32); - prefetch_load(src_ptr + src_stride + 64); - - src = src_ptr; - dst = dst_ptr; - - odd_dst = (dst + dst_stride); - - for (c = 0; c < 4; c++) { - __asm__ __volatile__( - "ulw %[qload1], 0(%[src]) " - "\n\t" - "ulw %[qload2], 4(%[src]) " - "\n\t" - - /* even 1. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* even 1 */ - "mthi $zero, $ac1 " - "\n\t" - "mtlo %[vector_64], $ac2 " - "\n\t" /* even 2 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbr %[p3], %[qload2] " - "\n\t" - "preceu.ph.qbl %[p4], %[qload2] " - "\n\t" - "preceu.ph.qbr %[p1], %[qload1] " - "\n\t" - "preceu.ph.qbl %[p2], %[qload1] " - "\n\t" - "ulw %[qload2], 8(%[src]) " - "\n\t" - "dpa.w.ph $ac1, %[p1], %[filter12] " - "\n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p2], %[filter34] " - "\n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p3], %[filter56] " - "\n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p4], %[filter78] " - "\n\t" /* even 1 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* even 1 */ - - /* even 2. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* even 3 */ - "mthi $zero, $ac3 " - "\n\t" - "preceu.ph.qbr %[p1], %[qload2] " - "\n\t" - "preceu.ph.qbl %[p5], %[qload2] " - "\n\t" - "ulw %[qload1], 12(%[src]) " - "\n\t" - "dpa.w.ph $ac2, %[p2], %[filter12] " - "\n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p3], %[filter34] " - "\n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p4], %[filter56] " - "\n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p1], %[filter78] " - "\n\t" /* even 1 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* even 1 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* even 1 */ - - /* even 3. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* even 4 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbr %[p2], %[qload1] " - "\n\t" - "sb %[st1], 0(%[dst]) " - "\n\t" /* even 1 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - " \n\t" - "dpa.w.ph $ac3, %[p3], %[filter12] " - "\n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p4], %[filter34] " - "\n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p1], %[filter56] " - "\n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p5], %[filter78] " - "\n\t" /* even 3 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* even 3 */ - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* even 1 */ - - /* even 4. pixel */ - "mtlo %[vector_64], $ac2 " - "\n\t" /* even 5 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbl %[p3], %[qload1] " - "\n\t" - "sb %[st2], 0(%[dst]) " - "\n\t" /* even 2 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "ulw %[qload2], 16(%[src]) " - "\n\t" - "dpa.w.ph $ac1, %[p4], %[filter12] " - "\n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p1], %[filter34] " - "\n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p5], %[filter56] " - "\n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p2], %[filter78] " - "\n\t" /* even 4 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* even 4 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* even 3 */ - - /* even 5. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* even 6 */ - "mthi $zero, $ac3 " - "\n\t" - "preceu.ph.qbr %[p4], %[qload2] " - "\n\t" - "sb %[st3], 0(%[dst]) " - "\n\t" /* even 3 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac2, %[p1], %[filter12] " - "\n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p5], %[filter34] " - "\n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p2], %[filter56] " - "\n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p3], %[filter78] " - "\n\t" /* even 5 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* even 5 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* even 4 */ - - /* even 6. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* even 7 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbl %[p1], %[qload2] " - "\n\t" - "sb %[st1], 0(%[dst]) " - "\n\t" /* even 4 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "ulw %[qload1], 20(%[src]) " - "\n\t" - "dpa.w.ph $ac3, %[p5], %[filter12] " - "\n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p2], %[filter34] " - "\n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p3], %[filter56] " - "\n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p4], %[filter78] " - "\n\t" /* even 6 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* even 6 */ - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* even 5 */ - - /* even 7. pixel */ - "mtlo %[vector_64], $ac2 " - "\n\t" /* even 8 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbr %[p5], %[qload1] " - "\n\t" - "sb %[st2], 0(%[dst]) " - "\n\t" /* even 5 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac1, %[p2], %[filter12] " - "\n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p3], %[filter34] " - "\n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p4], %[filter56] " - "\n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p1], %[filter78] " - "\n\t" /* even 7 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* even 7 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* even 6 */ - - /* even 8. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* odd 1 */ - "mthi $zero, $ac3 " - "\n\t" - "dpa.w.ph $ac2, %[p3], %[filter12] " - "\n\t" /* even 8 */ - "dpa.w.ph $ac2, %[p4], %[filter34] " - "\n\t" /* even 8 */ - "sb %[st3], 0(%[dst]) " - "\n\t" /* even 6 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac2, %[p1], %[filter56] " - "\n\t" /* even 8 */ - "dpa.w.ph $ac2, %[p5], %[filter78] " - "\n\t" /* even 8 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* even 8 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* even 7 */ - - /* ODD pixels */ - "ulw %[qload1], 1(%[src]) " - "\n\t" - "ulw %[qload2], 5(%[src]) " - "\n\t" - - /* odd 1. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* odd 2 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbr %[p1], %[qload1] " - "\n\t" - "preceu.ph.qbl %[p2], %[qload1] " - "\n\t" - "preceu.ph.qbr %[p3], %[qload2] " - "\n\t" - "preceu.ph.qbl %[p4], %[qload2] " - "\n\t" - "sb %[st1], 0(%[dst]) " - "\n\t" /* even 7 */ - "addu %[dst], %[dst], %[dst_pitch_2] " - "\n\t" - "ulw %[qload2], 9(%[src]) " - "\n\t" - "dpa.w.ph $ac3, %[p1], %[filter12] " - "\n\t" /* odd 1 */ - "dpa.w.ph $ac3, %[p2], %[filter34] " - "\n\t" /* odd 1 */ - "dpa.w.ph $ac3, %[p3], %[filter56] " - "\n\t" /* odd 1 */ - "dpa.w.ph $ac3, %[p4], %[filter78] " - "\n\t" /* odd 1 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* odd 1 */ - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* even 8 */ - - /* odd 2. pixel */ - "mtlo %[vector_64], $ac2 " - "\n\t" /* odd 3 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbr %[p1], %[qload2] " - "\n\t" - "preceu.ph.qbl %[p5], %[qload2] " - "\n\t" - "sb %[st2], 0(%[dst]) " - "\n\t" /* even 8 */ - "ulw %[qload1], 13(%[src]) " - "\n\t" - "dpa.w.ph $ac1, %[p2], %[filter12] " - "\n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p3], %[filter34] " - "\n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p4], %[filter56] " - "\n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p1], %[filter78] " - "\n\t" /* odd 2 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* odd 2 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* odd 1 */ - - /* odd 3. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* odd 4 */ - "mthi $zero, $ac3 " - "\n\t" - "preceu.ph.qbr %[p2], %[qload1] " - "\n\t" - "sb %[st3], 0(%[odd_dst]) " - "\n\t" /* odd 1 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac2, %[p3], %[filter12] " - "\n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p4], %[filter34] " - "\n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p1], %[filter56] " - "\n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p5], %[filter78] " - "\n\t" /* odd 3 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* odd 3 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* odd 2 */ - - /* odd 4. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* odd 5 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbl %[p3], %[qload1] " - "\n\t" - "sb %[st1], 0(%[odd_dst]) " - "\n\t" /* odd 2 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "ulw %[qload2], 17(%[src]) " - "\n\t" - "dpa.w.ph $ac3, %[p4], %[filter12] " - "\n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p1], %[filter34] " - "\n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p5], %[filter56] " - "\n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p2], %[filter78] " - "\n\t" /* odd 4 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* odd 4 */ - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* odd 3 */ - - /* odd 5. pixel */ - "mtlo %[vector_64], $ac2 " - "\n\t" /* odd 6 */ - "mthi $zero, $ac2 " - "\n\t" - "preceu.ph.qbr %[p4], %[qload2] " - "\n\t" - "sb %[st2], 0(%[odd_dst]) " - "\n\t" /* odd 3 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac1, %[p1], %[filter12] " - "\n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p5], %[filter34] " - "\n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p2], %[filter56] " - "\n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p3], %[filter78] " - "\n\t" /* odd 5 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* odd 5 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* odd 4 */ - - /* odd 6. pixel */ - "mtlo %[vector_64], $ac3 " - "\n\t" /* odd 7 */ - "mthi $zero, $ac3 " - "\n\t" - "preceu.ph.qbl %[p1], %[qload2] " - "\n\t" - "sb %[st3], 0(%[odd_dst]) " - "\n\t" /* odd 4 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "ulw %[qload1], 21(%[src]) " - "\n\t" - "dpa.w.ph $ac2, %[p5], %[filter12] " - "\n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p2], %[filter34] " - "\n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p3], %[filter56] " - "\n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p4], %[filter78] " - "\n\t" /* odd 6 */ - "extp %[Temp2], $ac2, 31 " - "\n\t" /* odd 6 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* odd 5 */ - - /* odd 7. pixel */ - "mtlo %[vector_64], $ac1 " - "\n\t" /* odd 8 */ - "mthi $zero, $ac1 " - "\n\t" - "preceu.ph.qbr %[p5], %[qload1] " - "\n\t" - "sb %[st1], 0(%[odd_dst]) " - "\n\t" /* odd 5 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - "dpa.w.ph $ac3, %[p2], %[filter12] " - "\n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p3], %[filter34] " - "\n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p4], %[filter56] " - "\n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p1], %[filter78] " - "\n\t" /* odd 7 */ - "extp %[Temp3], $ac3, 31 " - "\n\t" /* odd 7 */ - - /* odd 8. pixel */ - "dpa.w.ph $ac1, %[p3], %[filter12] " - "\n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p4], %[filter34] " - "\n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p1], %[filter56] " - "\n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p5], %[filter78] " - "\n\t" /* odd 8 */ - "extp %[Temp1], $ac1, 31 " - "\n\t" /* odd 8 */ - - "lbux %[st2], %[Temp2](%[cm]) " - "\n\t" /* odd 6 */ - "lbux %[st3], %[Temp3](%[cm]) " - "\n\t" /* odd 7 */ - "lbux %[st1], %[Temp1](%[cm]) " - "\n\t" /* odd 8 */ - - "sb %[st2], 0(%[odd_dst]) " - "\n\t" /* odd 6 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - - "sb %[st3], 0(%[odd_dst]) " - "\n\t" /* odd 7 */ - "addu %[odd_dst], %[odd_dst], %[dst_pitch_2] " - "\n\t" - - "sb %[st1], 0(%[odd_dst]) " - "\n\t" /* odd 8 */ - - : [qload1] "=&r"(qload1), [qload2] "=&r"(qload2), [p5] "=&r"(p5), - [st1] "=&r"(st1), [st2] "=&r"(st2), [st3] "=&r"(st3), - [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), [p4] "=&r"(p4), - [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3), - [dst] "+r"(dst), [odd_dst] "+r"(odd_dst) - : [filter12] "r"(filter12), [filter34] "r"(filter34), - [filter56] "r"(filter56), [filter78] "r"(filter78), - [vector_64] "r"(vector_64), [cm] "r"(cm), [src] "r"(src), - [dst_pitch_2] "r"(dst_pitch_2)); - - src += 16; - dst = (dst_ptr + ((c + 1) * 16 * dst_stride)); - odd_dst = (dst + dst_stride); - } - - /* Next row... */ - src_ptr += src_stride; - - dst_ptr += 1; - } -} - -void convolve_horiz_transposed(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const int16_t *filter, int w, int h) { - int x, y, k; - - for (y = 0; y < h; ++y) { - for (x = 0; x < w; ++x) { - int sum = 0; - - for (k = 0; k < 8; ++k) sum += src[x + k] * filter[k]; - - dst[x * dst_stride] = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)); - } - - src += src_stride; - dst += 1; - } -} - -void copy_horiz_transposed(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, int w, int h) { - int x, y; - - for (y = 0; y < h; ++y) { - for (x = 0; x < w; ++x) { - dst[x * dst_stride] = src[x]; - } - - src += src_stride; - dst += 1; - } -} - -void vpx_convolve8_dspr2(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, - int x0_q4, int32_t x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - const int16_t *const filter_x = filter[x0_q4]; - const int16_t *const filter_y = filter[y0_q4]; - DECLARE_ALIGNED(32, uint8_t, temp[64 * 135]); - int32_t intermediate_height = ((h * y_step_q4) >> 4) + 7; - uint32_t pos = 38; - - assert(x_step_q4 == 16); - assert(y_step_q4 == 16); - assert(((const int32_t *)filter_x)[1] != 0x800000); - assert(((const int32_t *)filter_y)[1] != 0x800000); - (void)x_step_q4; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - if (intermediate_height < h) intermediate_height = h; - - /* copy the src to dst */ - if (filter_x[3] == 0x80) { - copy_horiz_transposed(src - src_stride * 3, src_stride, temp, - intermediate_height, w, intermediate_height); - } else if (vpx_get_filter_taps(filter_x) == 2) { - vpx_convolve2_dspr2(src - src_stride * 3, src_stride, temp, - intermediate_height, filter_x, w, intermediate_height); - } else { - src -= (src_stride * 3 + 3); - - /* prefetch data to cache memory */ - prefetch_load(src); - prefetch_load(src + 32); - - switch (w) { - case 4: - convolve_horiz_4_transposed_dspr2(src, src_stride, temp, - intermediate_height, filter_x, - intermediate_height); - break; - case 8: - convolve_horiz_8_transposed_dspr2(src, src_stride, temp, - intermediate_height, filter_x, - intermediate_height); - break; - case 16: - case 32: - convolve_horiz_16_transposed_dspr2(src, src_stride, temp, - intermediate_height, filter_x, - intermediate_height, (w / 16)); - break; - case 64: - prefetch_load(src + 32); - convolve_horiz_64_transposed_dspr2(src, src_stride, temp, - intermediate_height, filter_x, - intermediate_height); - break; - default: - convolve_horiz_transposed(src, src_stride, temp, intermediate_height, - filter_x, w, intermediate_height); - break; - } - } - - /* copy the src to dst */ - if (filter_y[3] == 0x80) { - copy_horiz_transposed(temp + 3, intermediate_height, dst, dst_stride, h, w); - } else if (vpx_get_filter_taps(filter_y) == 2) { - vpx_convolve2_dspr2(temp + 3, intermediate_height, dst, dst_stride, - filter_y, h, w); - } else { - switch (h) { - case 4: - convolve_horiz_4_transposed_dspr2(temp, intermediate_height, dst, - dst_stride, filter_y, w); - break; - case 8: - convolve_horiz_8_transposed_dspr2(temp, intermediate_height, dst, - dst_stride, filter_y, w); - break; - case 16: - case 32: - convolve_horiz_16_transposed_dspr2(temp, intermediate_height, dst, - dst_stride, filter_y, w, (h / 16)); - break; - case 64: - convolve_horiz_64_transposed_dspr2(temp, intermediate_height, dst, - dst_stride, filter_y, w); - break; - default: - convolve_horiz_transposed(temp, intermediate_height, dst, dst_stride, - filter_y, h, w); - break; - } - } -} - -void vpx_convolve_copy_dspr2(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - int x, y; - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - /* prefetch data to cache memory */ - prefetch_load(src); - prefetch_load(src + 32); - prefetch_store(dst); - - switch (w) { - case 4: { - uint32_t tp1; - - /* 1 word storage */ - for (y = h; y--;) { - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_store(dst + dst_stride); - - __asm__ __volatile__( - "ulw %[tp1], (%[src]) \n\t" - "sw %[tp1], (%[dst]) \n\t" /* store */ - - : [tp1] "=&r"(tp1) - : [src] "r"(src), [dst] "r"(dst)); - - src += src_stride; - dst += dst_stride; - } - break; - } - case 8: { - uint32_t tp1, tp2; - - /* 2 word storage */ - for (y = h; y--;) { - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_store(dst + dst_stride); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 4(%[src]) \n\t" - "sw %[tp1], 0(%[dst]) \n\t" /* store */ - "sw %[tp2], 4(%[dst]) \n\t" /* store */ - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2) - : [src] "r"(src), [dst] "r"(dst)); - - src += src_stride; - dst += dst_stride; - } - break; - } - case 16: { - uint32_t tp1, tp2, tp3, tp4; - - /* 4 word storage */ - for (y = h; y--;) { - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_store(dst + dst_stride); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 4(%[src]) \n\t" - "ulw %[tp3], 8(%[src]) \n\t" - "ulw %[tp4], 12(%[src]) \n\t" - - "sw %[tp1], 0(%[dst]) \n\t" /* store */ - "sw %[tp2], 4(%[dst]) \n\t" /* store */ - "sw %[tp3], 8(%[dst]) \n\t" /* store */ - "sw %[tp4], 12(%[dst]) \n\t" /* store */ - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tp3] "=&r"(tp3), - [tp4] "=&r"(tp4) - : [src] "r"(src), [dst] "r"(dst)); - - src += src_stride; - dst += dst_stride; - } - break; - } - case 32: { - uint32_t tp1, tp2, tp3, tp4; - uint32_t tp5, tp6, tp7, tp8; - - /* 8 word storage */ - for (y = h; y--;) { - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_store(dst + dst_stride); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 4(%[src]) \n\t" - "ulw %[tp3], 8(%[src]) \n\t" - "ulw %[tp4], 12(%[src]) \n\t" - "ulw %[tp5], 16(%[src]) \n\t" - "ulw %[tp6], 20(%[src]) \n\t" - "ulw %[tp7], 24(%[src]) \n\t" - "ulw %[tp8], 28(%[src]) \n\t" - - "sw %[tp1], 0(%[dst]) \n\t" /* store */ - "sw %[tp2], 4(%[dst]) \n\t" /* store */ - "sw %[tp3], 8(%[dst]) \n\t" /* store */ - "sw %[tp4], 12(%[dst]) \n\t" /* store */ - "sw %[tp5], 16(%[dst]) \n\t" /* store */ - "sw %[tp6], 20(%[dst]) \n\t" /* store */ - "sw %[tp7], 24(%[dst]) \n\t" /* store */ - "sw %[tp8], 28(%[dst]) \n\t" /* store */ - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tp3] "=&r"(tp3), - [tp4] "=&r"(tp4), [tp5] "=&r"(tp5), [tp6] "=&r"(tp6), - [tp7] "=&r"(tp7), [tp8] "=&r"(tp8) - : [src] "r"(src), [dst] "r"(dst)); - - src += src_stride; - dst += dst_stride; - } - break; - } - case 64: { - uint32_t tp1, tp2, tp3, tp4; - uint32_t tp5, tp6, tp7, tp8; - - prefetch_load(src + 64); - prefetch_store(dst + 32); - - /* 16 word storage */ - for (y = h; y--;) { - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_load(src + src_stride + 64); - prefetch_store(dst + dst_stride); - prefetch_store(dst + dst_stride + 32); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 4(%[src]) \n\t" - "ulw %[tp3], 8(%[src]) \n\t" - "ulw %[tp4], 12(%[src]) \n\t" - "ulw %[tp5], 16(%[src]) \n\t" - "ulw %[tp6], 20(%[src]) \n\t" - "ulw %[tp7], 24(%[src]) \n\t" - "ulw %[tp8], 28(%[src]) \n\t" - - "sw %[tp1], 0(%[dst]) \n\t" /* store */ - "sw %[tp2], 4(%[dst]) \n\t" /* store */ - "sw %[tp3], 8(%[dst]) \n\t" /* store */ - "sw %[tp4], 12(%[dst]) \n\t" /* store */ - "sw %[tp5], 16(%[dst]) \n\t" /* store */ - "sw %[tp6], 20(%[dst]) \n\t" /* store */ - "sw %[tp7], 24(%[dst]) \n\t" /* store */ - "sw %[tp8], 28(%[dst]) \n\t" /* store */ - - "ulw %[tp1], 32(%[src]) \n\t" - "ulw %[tp2], 36(%[src]) \n\t" - "ulw %[tp3], 40(%[src]) \n\t" - "ulw %[tp4], 44(%[src]) \n\t" - "ulw %[tp5], 48(%[src]) \n\t" - "ulw %[tp6], 52(%[src]) \n\t" - "ulw %[tp7], 56(%[src]) \n\t" - "ulw %[tp8], 60(%[src]) \n\t" - - "sw %[tp1], 32(%[dst]) \n\t" /* store */ - "sw %[tp2], 36(%[dst]) \n\t" /* store */ - "sw %[tp3], 40(%[dst]) \n\t" /* store */ - "sw %[tp4], 44(%[dst]) \n\t" /* store */ - "sw %[tp5], 48(%[dst]) \n\t" /* store */ - "sw %[tp6], 52(%[dst]) \n\t" /* store */ - "sw %[tp7], 56(%[dst]) \n\t" /* store */ - "sw %[tp8], 60(%[dst]) \n\t" /* store */ - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tp3] "=&r"(tp3), - [tp4] "=&r"(tp4), [tp5] "=&r"(tp5), [tp6] "=&r"(tp6), - [tp7] "=&r"(tp7), [tp8] "=&r"(tp8) - : [src] "r"(src), [dst] "r"(dst)); - - src += src_stride; - dst += dst_stride; - } - break; - } - default: - for (y = h; y--;) { - for (x = 0; x < w; ++x) { - dst[x] = src[x]; - } - - src += src_stride; - dst += dst_stride; - } - break; - } -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve8_horiz_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve8_horiz_dspr2.c deleted file mode 100644 index 09d6f36e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve8_horiz_dspr2.c +++ /dev/null @@ -1,878 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/convolve_common_dspr2.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_ports/mem.h" - -#if HAVE_DSPR2 -static void convolve_horiz_4_dspr2(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int16_t *filter_x0, int32_t h) { - int32_t y; - uint8_t *cm = vpx_ff_cropTbl; - int32_t vector1b, vector2b, vector3b, vector4b; - int32_t Temp1, Temp2, Temp3, Temp4; - uint32_t vector4a = 64; - uint32_t tp1, tp2; - uint32_t p1, p2, p3, p4; - uint32_t n1, n2, n3, n4; - uint32_t tn1, tn2; - - vector1b = ((const int32_t *)filter_x0)[0]; - vector2b = ((const int32_t *)filter_x0)[1]; - vector3b = ((const int32_t *)filter_x0)[2]; - vector4b = ((const int32_t *)filter_x0)[3]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_store(dst + dst_stride); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p1], %[tp1] \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "preceu.ph.qbr %[p3], %[tp2] \n\t" - "preceu.ph.qbl %[p4], %[tp2] \n\t" - "dpa.w.ph $ac3, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p3], %[vector3b] \n\t" - "ulw %[tn2], 8(%[src]) \n\t" - "dpa.w.ph $ac3, %[p4], %[vector4b] \n\t" - "extp %[Temp1], $ac3, 31 \n\t" - - /* even 2. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[tn2] \n\t" - "balign %[tn1], %[tn2], 3 \n\t" - "balign %[tn2], %[tp2], 3 \n\t" - "balign %[tp2], %[tp1], 3 \n\t" - "dpa.w.ph $ac2, %[p2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p3], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[p4], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector4b] \n\t" - "extp %[Temp3], $ac2, 31 \n\t" - - /* odd 1. pixel */ - "lbux %[tp1], %[Temp1](%[cm]) \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[n1], %[tp2] \n\t" - "preceu.ph.qbl %[n2], %[tp2] \n\t" - "preceu.ph.qbr %[n3], %[tn2] \n\t" - "preceu.ph.qbl %[n4], %[tn2] \n\t" - "dpa.w.ph $ac3, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[n3], %[vector3b] \n\t" - "dpa.w.ph $ac3, %[n4], %[vector4b] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - /* odd 2. pixel */ - "lbux %[tp2], %[Temp3](%[cm]) \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[n1], %[tn1] \n\t" - "dpa.w.ph $ac2, %[n2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[n3], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[n4], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[n1], %[vector4b] \n\t" - "extp %[Temp4], $ac2, 31 \n\t" - - /* clamp */ - "lbux %[tn1], %[Temp2](%[cm]) \n\t" - "lbux %[n2], %[Temp4](%[cm]) \n\t" - - /* store bytes */ - "sb %[tp1], 0(%[dst]) \n\t" - "sb %[tn1], 1(%[dst]) \n\t" - "sb %[tp2], 2(%[dst]) \n\t" - "sb %[n2], 3(%[dst]) \n\t" - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tn1] "=&r"(tn1), - [tn2] "=&r"(tn2), [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), - [p4] "=&r"(p4), [n1] "=&r"(n1), [n2] "=&r"(n2), [n3] "=&r"(n3), - [n4] "=&r"(n4), [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), - [Temp3] "=&r"(Temp3), [Temp4] "=&r"(Temp4) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector3b] "r"(vector3b), [vector4b] "r"(vector4b), - [vector4a] "r"(vector4a), [cm] "r"(cm), [dst] "r"(dst), - [src] "r"(src)); - - /* Next row... */ - src += src_stride; - dst += dst_stride; - } -} - -static void convolve_horiz_8_dspr2(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int16_t *filter_x0, int32_t h) { - int32_t y; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector4a = 64; - int32_t vector1b, vector2b, vector3b, vector4b; - int32_t Temp1, Temp2, Temp3; - uint32_t tp1, tp2; - uint32_t p1, p2, p3, p4, n1; - uint32_t tn1, tn2, tn3; - uint32_t st0, st1; - - vector1b = ((const int32_t *)filter_x0)[0]; - vector2b = ((const int32_t *)filter_x0)[1]; - vector3b = ((const int32_t *)filter_x0)[2]; - vector4b = ((const int32_t *)filter_x0)[3]; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_load(src + src_stride); - prefetch_load(src + src_stride + 32); - prefetch_store(dst + dst_stride); - - __asm__ __volatile__( - "ulw %[tp1], 0(%[src]) \n\t" - "ulw %[tp2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[tp1] \n\t" - "preceu.ph.qbl %[p2], %[tp1] \n\t" - "preceu.ph.qbr %[p3], %[tp2] \n\t" - "preceu.ph.qbl %[p4], %[tp2] \n\t" - "ulw %[tn2], 8(%[src]) \n\t" - "dpa.w.ph $ac3, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p3], %[vector3b] \n\t" - "dpa.w.ph $ac3, %[p4], %[vector4b] \n\t" - "extp %[Temp1], $ac3, 31 \n\t" - - /* even 2. pixel */ - "preceu.ph.qbr %[p1], %[tn2] \n\t" - "preceu.ph.qbl %[n1], %[tn2] \n\t" - "ulw %[tn1], 12(%[src]) \n\t" - "dpa.w.ph $ac2, %[p2], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p3], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[p4], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector4b] \n\t" - "extp %[Temp3], $ac2, 31 \n\t" - - /* even 3. pixel */ - "lbux %[st0], %[Temp1](%[cm]) \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p2], %[tn1] \n\t" - "dpa.w.ph $ac1, %[p3], %[vector1b] \n\t" - "dpa.w.ph $ac1, %[p4], %[vector2b] \n\t" - "dpa.w.ph $ac1, %[p1], %[vector3b] \n\t" - "dpa.w.ph $ac1, %[n1], %[vector4b] \n\t" - "extp %[Temp1], $ac1, 31 \n\t" - - /* even 4. pixel */ - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "sb %[st0], 0(%[dst]) \n\t" - "lbux %[st1], %[Temp3](%[cm]) \n\t" - - "balign %[tn3], %[tn1], 3 \n\t" - "balign %[tn1], %[tn2], 3 \n\t" - "balign %[tn2], %[tp2], 3 \n\t" - "balign %[tp2], %[tp1], 3 \n\t" - - "dpa.w.ph $ac2, %[p4], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[n1], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector4b] \n\t" - "extp %[Temp3], $ac2, 31 \n\t" - - "lbux %[st0], %[Temp1](%[cm]) \n\t" - - /* odd 1. pixel */ - "mtlo %[vector4a], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "sb %[st1], 2(%[dst]) \n\t" - "preceu.ph.qbr %[p1], %[tp2] \n\t" - "preceu.ph.qbl %[p2], %[tp2] \n\t" - "preceu.ph.qbr %[p3], %[tn2] \n\t" - "preceu.ph.qbl %[p4], %[tn2] \n\t" - "sb %[st0], 4(%[dst]) \n\t" - "dpa.w.ph $ac3, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p3], %[vector3b] \n\t" - "dpa.w.ph $ac3, %[p4], %[vector4b] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - /* odd 2. pixel */ - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[tn1] \n\t" - "preceu.ph.qbl %[n1], %[tn1] \n\t" - "lbux %[st0], %[Temp3](%[cm]) \n\t" - "dpa.w.ph $ac1, %[p2], %[vector1b] \n\t" - "dpa.w.ph $ac1, %[p3], %[vector2b] \n\t" - "dpa.w.ph $ac1, %[p4], %[vector3b] \n\t" - "dpa.w.ph $ac1, %[p1], %[vector4b] \n\t" - "extp %[Temp3], $ac1, 31 \n\t" - - /* odd 3. pixel */ - "lbux %[st1], %[Temp2](%[cm]) \n\t" - "preceu.ph.qbr %[p2], %[tn3] \n\t" - "dpa.w.ph $ac3, %[p3], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[p4], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[p1], %[vector3b] \n\t" - "dpa.w.ph $ac3, %[n1], %[vector4b] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - /* odd 4. pixel */ - "sb %[st1], 1(%[dst]) \n\t" - "sb %[st0], 6(%[dst]) \n\t" - "dpa.w.ph $ac2, %[p4], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p1], %[vector2b] \n\t" - "dpa.w.ph $ac2, %[n1], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector4b] \n\t" - "extp %[Temp1], $ac2, 31 \n\t" - - /* clamp */ - "lbux %[p4], %[Temp3](%[cm]) \n\t" - "lbux %[p2], %[Temp2](%[cm]) \n\t" - "lbux %[n1], %[Temp1](%[cm]) \n\t" - - /* store bytes */ - "sb %[p4], 3(%[dst]) \n\t" - "sb %[p2], 5(%[dst]) \n\t" - "sb %[n1], 7(%[dst]) \n\t" - - : [tp1] "=&r"(tp1), [tp2] "=&r"(tp2), [tn1] "=&r"(tn1), - [tn2] "=&r"(tn2), [tn3] "=&r"(tn3), [st0] "=&r"(st0), - [st1] "=&r"(st1), [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), - [p4] "=&r"(p4), [n1] "=&r"(n1), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector3b] "r"(vector3b), [vector4b] "r"(vector4b), - [vector4a] "r"(vector4a), [cm] "r"(cm), [dst] "r"(dst), - [src] "r"(src)); - - /* Next row... */ - src += src_stride; - dst += dst_stride; - } -} - -static void convolve_horiz_16_dspr2(const uint8_t *src_ptr, int32_t src_stride, - uint8_t *dst_ptr, int32_t dst_stride, - const int16_t *filter_x0, int32_t h, - int32_t count) { - int32_t y, c; - const uint8_t *src; - uint8_t *dst; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector_64 = 64; - int32_t filter12, filter34, filter56, filter78; - int32_t Temp1, Temp2, Temp3; - uint32_t qload1, qload2, qload3; - uint32_t p1, p2, p3, p4, p5; - uint32_t st1, st2, st3; - - filter12 = ((const int32_t *)filter_x0)[0]; - filter34 = ((const int32_t *)filter_x0)[1]; - filter56 = ((const int32_t *)filter_x0)[2]; - filter78 = ((const int32_t *)filter_x0)[3]; - - for (y = h; y--;) { - src = src_ptr; - dst = dst_ptr; - - /* prefetch data to cache memory */ - prefetch_load(src_ptr + src_stride); - prefetch_load(src_ptr + src_stride + 32); - prefetch_store(dst_ptr + dst_stride); - - for (c = 0; c < count; c++) { - __asm__ __volatile__( - "ulw %[qload1], 0(%[src]) \n\t" - "ulw %[qload2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 1 */ - "mthi $zero, $ac1 \n\t" - "mtlo %[vector_64], $ac2 \n\t" /* even 2 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[qload1] \n\t" - "preceu.ph.qbl %[p2], %[qload1] \n\t" - "preceu.ph.qbr %[p3], %[qload2] \n\t" - "preceu.ph.qbl %[p4], %[qload2] \n\t" - "ulw %[qload3], 8(%[src]) \n\t" - "dpa.w.ph $ac1, %[p1], %[filter12] \n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p2], %[filter34] \n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p3], %[filter56] \n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p4], %[filter78] \n\t" /* even 1 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 1 */ - - /* even 2. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* even 3 */ - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p1], %[qload3] \n\t" - "preceu.ph.qbl %[p5], %[qload3] \n\t" - "ulw %[qload1], 12(%[src]) \n\t" - "dpa.w.ph $ac2, %[p2], %[filter12] \n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p3], %[filter34] \n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p4], %[filter56] \n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p1], %[filter78] \n\t" /* even 1 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 1 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 1 */ - - /* even 3. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 4 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p2], %[qload1] \n\t" - "sb %[st1], 0(%[dst]) \n\t" /* even 1 */ - "dpa.w.ph $ac3, %[p3], %[filter12] \n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p4], %[filter34] \n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p1], %[filter56] \n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p5], %[filter78] \n\t" /* even 3 */ - "extp %[Temp3], $ac3, 31 \n\t" /* even 3 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 1 */ - - /* even 4. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* even 5 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbl %[p3], %[qload1] \n\t" - "sb %[st2], 2(%[dst]) \n\t" /* even 1 */ - "ulw %[qload2], 16(%[src]) \n\t" - "dpa.w.ph $ac1, %[p4], %[filter12] \n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p1], %[filter34] \n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p5], %[filter56] \n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p2], %[filter78] \n\t" /* even 4 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 4 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* even 3 */ - - /* even 5. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* even 6 */ - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p4], %[qload2] \n\t" - "sb %[st3], 4(%[dst]) \n\t" /* even 3 */ - "dpa.w.ph $ac2, %[p1], %[filter12] \n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p5], %[filter34] \n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p2], %[filter56] \n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p3], %[filter78] \n\t" /* even 5 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 5 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 4 */ - - /* even 6. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 7 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbl %[p1], %[qload2] \n\t" - "sb %[st1], 6(%[dst]) \n\t" /* even 4 */ - "ulw %[qload3], 20(%[src]) \n\t" - "dpa.w.ph $ac3, %[p5], %[filter12] \n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p2], %[filter34] \n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p3], %[filter56] \n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p4], %[filter78] \n\t" /* even 6 */ - "extp %[Temp3], $ac3, 31 \n\t" /* even 6 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 5 */ - - /* even 7. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* even 8 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p5], %[qload3] \n\t" - "sb %[st2], 8(%[dst]) \n\t" /* even 5 */ - "dpa.w.ph $ac1, %[p2], %[filter12] \n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p3], %[filter34] \n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p4], %[filter56] \n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p1], %[filter78] \n\t" /* even 7 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 7 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* even 6 */ - - /* even 8. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 1 */ - "mthi $zero, $ac3 \n\t" - "dpa.w.ph $ac2, %[p3], %[filter12] \n\t" /* even 8 */ - "dpa.w.ph $ac2, %[p4], %[filter34] \n\t" /* even 8 */ - "sb %[st3], 10(%[dst]) \n\t" /* even 6 */ - "dpa.w.ph $ac2, %[p1], %[filter56] \n\t" /* even 8 */ - "dpa.w.ph $ac2, %[p5], %[filter78] \n\t" /* even 8 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 8 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 7 */ - - /* ODD pixels */ - "ulw %[qload1], 1(%[src]) \n\t" - "ulw %[qload2], 5(%[src]) \n\t" - - /* odd 1. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 2 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p1], %[qload1] \n\t" - "preceu.ph.qbl %[p2], %[qload1] \n\t" - "preceu.ph.qbr %[p3], %[qload2] \n\t" - "preceu.ph.qbl %[p4], %[qload2] \n\t" - "sb %[st1], 12(%[dst]) \n\t" /* even 7 */ - "ulw %[qload3], 9(%[src]) \n\t" - "dpa.w.ph $ac3, %[p1], %[filter12] \n\t" /* odd 1 */ - "dpa.w.ph $ac3, %[p2], %[filter34] \n\t" /* odd 1 */ - "dpa.w.ph $ac3, %[p3], %[filter56] \n\t" /* odd 1 */ - "dpa.w.ph $ac3, %[p4], %[filter78] \n\t" /* odd 1 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 1 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 8 */ - - /* odd 2. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* odd 3 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[qload3] \n\t" - "preceu.ph.qbl %[p5], %[qload3] \n\t" - "sb %[st2], 14(%[dst]) \n\t" /* even 8 */ - "ulw %[qload1], 13(%[src]) \n\t" - "dpa.w.ph $ac1, %[p2], %[filter12] \n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p3], %[filter34] \n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p4], %[filter56] \n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p1], %[filter78] \n\t" /* odd 2 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 2 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 1 */ - - /* odd 3. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 4 */ - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p2], %[qload1] \n\t" - "sb %[st3], 1(%[dst]) \n\t" /* odd 1 */ - "dpa.w.ph $ac2, %[p3], %[filter12] \n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p4], %[filter34] \n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p1], %[filter56] \n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p5], %[filter78] \n\t" /* odd 3 */ - "extp %[Temp2], $ac2, 31 \n\t" /* odd 3 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 2 */ - - /* odd 4. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 5 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbl %[p3], %[qload1] \n\t" - "sb %[st1], 3(%[dst]) \n\t" /* odd 2 */ - "ulw %[qload2], 17(%[src]) \n\t" - "dpa.w.ph $ac3, %[p4], %[filter12] \n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p1], %[filter34] \n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p5], %[filter56] \n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p2], %[filter78] \n\t" /* odd 4 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 4 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* odd 3 */ - - /* odd 5. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* odd 6 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p4], %[qload2] \n\t" - "sb %[st2], 5(%[dst]) \n\t" /* odd 3 */ - "dpa.w.ph $ac1, %[p1], %[filter12] \n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p5], %[filter34] \n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p2], %[filter56] \n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p3], %[filter78] \n\t" /* odd 5 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 5 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 4 */ - - /* odd 6. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 7 */ - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbl %[p1], %[qload2] \n\t" - "sb %[st3], 7(%[dst]) \n\t" /* odd 4 */ - "ulw %[qload3], 21(%[src]) \n\t" - "dpa.w.ph $ac2, %[p5], %[filter12] \n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p2], %[filter34] \n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p3], %[filter56] \n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p4], %[filter78] \n\t" /* odd 6 */ - "extp %[Temp2], $ac2, 31 \n\t" /* odd 6 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 5 */ - - /* odd 7. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 8 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p5], %[qload3] \n\t" - "sb %[st1], 9(%[dst]) \n\t" /* odd 5 */ - "dpa.w.ph $ac3, %[p2], %[filter12] \n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p3], %[filter34] \n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p4], %[filter56] \n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p1], %[filter78] \n\t" /* odd 7 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 7 */ - - /* odd 8. pixel */ - "dpa.w.ph $ac1, %[p3], %[filter12] \n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p4], %[filter34] \n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p1], %[filter56] \n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p5], %[filter78] \n\t" /* odd 8 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 8 */ - - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* odd 6 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 7 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 8 */ - - "sb %[st2], 11(%[dst]) \n\t" /* odd 6 */ - "sb %[st3], 13(%[dst]) \n\t" /* odd 7 */ - "sb %[st1], 15(%[dst]) \n\t" /* odd 8 */ - - : [qload1] "=&r"(qload1), [qload2] "=&r"(qload2), - [qload3] "=&r"(qload3), [st1] "=&r"(st1), [st2] "=&r"(st2), - [st3] "=&r"(st3), [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), - [p4] "=&r"(p4), [p5] "=&r"(p5), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3) - : [filter12] "r"(filter12), [filter34] "r"(filter34), - [filter56] "r"(filter56), [filter78] "r"(filter78), - [vector_64] "r"(vector_64), [cm] "r"(cm), [dst] "r"(dst), - [src] "r"(src)); - - src += 16; - dst += 16; - } - - /* Next row... */ - src_ptr += src_stride; - dst_ptr += dst_stride; - } -} - -static void convolve_horiz_64_dspr2(const uint8_t *src_ptr, int32_t src_stride, - uint8_t *dst_ptr, int32_t dst_stride, - const int16_t *filter_x0, int32_t h) { - int32_t y, c; - const uint8_t *src; - uint8_t *dst; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector_64 = 64; - int32_t filter12, filter34, filter56, filter78; - int32_t Temp1, Temp2, Temp3; - uint32_t qload1, qload2, qload3; - uint32_t p1, p2, p3, p4, p5; - uint32_t st1, st2, st3; - - filter12 = ((const int32_t *)filter_x0)[0]; - filter34 = ((const int32_t *)filter_x0)[1]; - filter56 = ((const int32_t *)filter_x0)[2]; - filter78 = ((const int32_t *)filter_x0)[3]; - - for (y = h; y--;) { - src = src_ptr; - dst = dst_ptr; - - /* prefetch data to cache memory */ - prefetch_load(src_ptr + src_stride); - prefetch_load(src_ptr + src_stride + 32); - prefetch_load(src_ptr + src_stride + 64); - prefetch_store(dst_ptr + dst_stride); - prefetch_store(dst_ptr + dst_stride + 32); - - for (c = 0; c < 4; c++) { - __asm__ __volatile__( - "ulw %[qload1], 0(%[src]) \n\t" - "ulw %[qload2], 4(%[src]) \n\t" - - /* even 1. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 1 */ - "mthi $zero, $ac1 \n\t" - "mtlo %[vector_64], $ac2 \n\t" /* even 2 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[qload1] \n\t" - "preceu.ph.qbl %[p2], %[qload1] \n\t" - "preceu.ph.qbr %[p3], %[qload2] \n\t" - "preceu.ph.qbl %[p4], %[qload2] \n\t" - "ulw %[qload3], 8(%[src]) \n\t" - "dpa.w.ph $ac1, %[p1], %[filter12] \n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p2], %[filter34] \n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p3], %[filter56] \n\t" /* even 1 */ - "dpa.w.ph $ac1, %[p4], %[filter78] \n\t" /* even 1 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 1 */ - - /* even 2. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* even 3 */ - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p1], %[qload3] \n\t" - "preceu.ph.qbl %[p5], %[qload3] \n\t" - "ulw %[qload1], 12(%[src]) \n\t" - "dpa.w.ph $ac2, %[p2], %[filter12] \n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p3], %[filter34] \n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p4], %[filter56] \n\t" /* even 1 */ - "dpa.w.ph $ac2, %[p1], %[filter78] \n\t" /* even 1 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 1 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 1 */ - - /* even 3. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 4 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p2], %[qload1] \n\t" - "sb %[st1], 0(%[dst]) \n\t" /* even 1 */ - "dpa.w.ph $ac3, %[p3], %[filter12] \n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p4], %[filter34] \n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p1], %[filter56] \n\t" /* even 3 */ - "dpa.w.ph $ac3, %[p5], %[filter78] \n\t" /* even 3 */ - "extp %[Temp3], $ac3, 31 \n\t" /* even 3 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 1 */ - - /* even 4. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* even 5 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbl %[p3], %[qload1] \n\t" - "sb %[st2], 2(%[dst]) \n\t" /* even 1 */ - "ulw %[qload2], 16(%[src]) \n\t" - "dpa.w.ph $ac1, %[p4], %[filter12] \n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p1], %[filter34] \n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p5], %[filter56] \n\t" /* even 4 */ - "dpa.w.ph $ac1, %[p2], %[filter78] \n\t" /* even 4 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 4 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* even 3 */ - - /* even 5. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* even 6 */ - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p4], %[qload2] \n\t" - "sb %[st3], 4(%[dst]) \n\t" /* even 3 */ - "dpa.w.ph $ac2, %[p1], %[filter12] \n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p5], %[filter34] \n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p2], %[filter56] \n\t" /* even 5 */ - "dpa.w.ph $ac2, %[p3], %[filter78] \n\t" /* even 5 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 5 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 4 */ - - /* even 6. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* even 7 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbl %[p1], %[qload2] \n\t" - "sb %[st1], 6(%[dst]) \n\t" /* even 4 */ - "ulw %[qload3], 20(%[src]) \n\t" - "dpa.w.ph $ac3, %[p5], %[filter12] \n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p2], %[filter34] \n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p3], %[filter56] \n\t" /* even 6 */ - "dpa.w.ph $ac3, %[p4], %[filter78] \n\t" /* even 6 */ - "extp %[Temp3], $ac3, 31 \n\t" /* even 6 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 5 */ - - /* even 7. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* even 8 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p5], %[qload3] \n\t" - "sb %[st2], 8(%[dst]) \n\t" /* even 5 */ - "dpa.w.ph $ac1, %[p2], %[filter12] \n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p3], %[filter34] \n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p4], %[filter56] \n\t" /* even 7 */ - "dpa.w.ph $ac1, %[p1], %[filter78] \n\t" /* even 7 */ - "extp %[Temp1], $ac1, 31 \n\t" /* even 7 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* even 6 */ - - /* even 8. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 1 */ - "mthi $zero, $ac3 \n\t" - "dpa.w.ph $ac2, %[p3], %[filter12] \n\t" /* even 8 */ - "dpa.w.ph $ac2, %[p4], %[filter34] \n\t" /* even 8 */ - "sb %[st3], 10(%[dst]) \n\t" /* even 6 */ - "dpa.w.ph $ac2, %[p1], %[filter56] \n\t" /* even 8 */ - "dpa.w.ph $ac2, %[p5], %[filter78] \n\t" /* even 8 */ - "extp %[Temp2], $ac2, 31 \n\t" /* even 8 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* even 7 */ - - /* ODD pixels */ - "ulw %[qload1], 1(%[src]) \n\t" - "ulw %[qload2], 5(%[src]) \n\t" - - /* odd 1. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 2 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p1], %[qload1] \n\t" - "preceu.ph.qbl %[p2], %[qload1] \n\t" - "preceu.ph.qbr %[p3], %[qload2] \n\t" - "preceu.ph.qbl %[p4], %[qload2] \n\t" - "sb %[st1], 12(%[dst]) \n\t" /* even 7 */ - "ulw %[qload3], 9(%[src]) \n\t" - "dpa.w.ph $ac3, %[p1], %[filter12] \n\t" /* odd 1 */ - "dpa.w.ph $ac3, %[p2], %[filter34] \n\t" /* odd 1 */ - "dpa.w.ph $ac3, %[p3], %[filter56] \n\t" /* odd 1 */ - "dpa.w.ph $ac3, %[p4], %[filter78] \n\t" /* odd 1 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 1 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* even 8 */ - - /* odd 2. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* odd 3 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p1], %[qload3] \n\t" - "preceu.ph.qbl %[p5], %[qload3] \n\t" - "sb %[st2], 14(%[dst]) \n\t" /* even 8 */ - "ulw %[qload1], 13(%[src]) \n\t" - "dpa.w.ph $ac1, %[p2], %[filter12] \n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p3], %[filter34] \n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p4], %[filter56] \n\t" /* odd 2 */ - "dpa.w.ph $ac1, %[p1], %[filter78] \n\t" /* odd 2 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 2 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 1 */ - - /* odd 3. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 4 */ - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbr %[p2], %[qload1] \n\t" - "sb %[st3], 1(%[dst]) \n\t" /* odd 1 */ - "dpa.w.ph $ac2, %[p3], %[filter12] \n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p4], %[filter34] \n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p1], %[filter56] \n\t" /* odd 3 */ - "dpa.w.ph $ac2, %[p5], %[filter78] \n\t" /* odd 3 */ - "extp %[Temp2], $ac2, 31 \n\t" /* odd 3 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 2 */ - - /* odd 4. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 5 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbl %[p3], %[qload1] \n\t" - "sb %[st1], 3(%[dst]) \n\t" /* odd 2 */ - "ulw %[qload2], 17(%[src]) \n\t" - "dpa.w.ph $ac3, %[p4], %[filter12] \n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p1], %[filter34] \n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p5], %[filter56] \n\t" /* odd 4 */ - "dpa.w.ph $ac3, %[p2], %[filter78] \n\t" /* odd 4 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 4 */ - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* odd 3 */ - - /* odd 5. pixel */ - "mtlo %[vector_64], $ac2 \n\t" /* odd 6 */ - "mthi $zero, $ac2 \n\t" - "preceu.ph.qbr %[p4], %[qload2] \n\t" - "sb %[st2], 5(%[dst]) \n\t" /* odd 3 */ - "dpa.w.ph $ac1, %[p1], %[filter12] \n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p5], %[filter34] \n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p2], %[filter56] \n\t" /* odd 5 */ - "dpa.w.ph $ac1, %[p3], %[filter78] \n\t" /* odd 5 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 5 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 4 */ - - /* odd 6. pixel */ - "mtlo %[vector_64], $ac3 \n\t" /* odd 7 */ - "mthi $zero, $ac3 \n\t" - "preceu.ph.qbl %[p1], %[qload2] \n\t" - "sb %[st3], 7(%[dst]) \n\t" /* odd 4 */ - "ulw %[qload3], 21(%[src]) \n\t" - "dpa.w.ph $ac2, %[p5], %[filter12] \n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p2], %[filter34] \n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p3], %[filter56] \n\t" /* odd 6 */ - "dpa.w.ph $ac2, %[p4], %[filter78] \n\t" /* odd 6 */ - "extp %[Temp2], $ac2, 31 \n\t" /* odd 6 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 5 */ - - /* odd 7. pixel */ - "mtlo %[vector_64], $ac1 \n\t" /* odd 8 */ - "mthi $zero, $ac1 \n\t" - "preceu.ph.qbr %[p5], %[qload3] \n\t" - "sb %[st1], 9(%[dst]) \n\t" /* odd 5 */ - "dpa.w.ph $ac3, %[p2], %[filter12] \n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p3], %[filter34] \n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p4], %[filter56] \n\t" /* odd 7 */ - "dpa.w.ph $ac3, %[p1], %[filter78] \n\t" /* odd 7 */ - "extp %[Temp3], $ac3, 31 \n\t" /* odd 7 */ - - /* odd 8. pixel */ - "dpa.w.ph $ac1, %[p3], %[filter12] \n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p4], %[filter34] \n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p1], %[filter56] \n\t" /* odd 8 */ - "dpa.w.ph $ac1, %[p5], %[filter78] \n\t" /* odd 8 */ - "extp %[Temp1], $ac1, 31 \n\t" /* odd 8 */ - - "lbux %[st2], %[Temp2](%[cm]) \n\t" /* odd 6 */ - "lbux %[st3], %[Temp3](%[cm]) \n\t" /* odd 7 */ - "lbux %[st1], %[Temp1](%[cm]) \n\t" /* odd 8 */ - - "sb %[st2], 11(%[dst]) \n\t" /* odd 6 */ - "sb %[st3], 13(%[dst]) \n\t" /* odd 7 */ - "sb %[st1], 15(%[dst]) \n\t" /* odd 8 */ - - : [qload1] "=&r"(qload1), [qload2] "=&r"(qload2), - [qload3] "=&r"(qload3), [st1] "=&r"(st1), [st2] "=&r"(st2), - [st3] "=&r"(st3), [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), - [p4] "=&r"(p4), [p5] "=&r"(p5), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [Temp3] "=&r"(Temp3) - : [filter12] "r"(filter12), [filter34] "r"(filter34), - [filter56] "r"(filter56), [filter78] "r"(filter78), - [vector_64] "r"(vector_64), [cm] "r"(cm), [dst] "r"(dst), - [src] "r"(src)); - - src += 16; - dst += 16; - } - - /* Next row... */ - src_ptr += src_stride; - dst_ptr += dst_stride; - } -} - -void vpx_convolve8_horiz_dspr2(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - const int16_t *const filter_x = filter[x0_q4]; - assert(x_step_q4 == 16); - assert(((const int32_t *)filter_x)[1] != 0x800000); - - if (vpx_get_filter_taps(filter_x) == 2) { - vpx_convolve2_horiz_dspr2(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - } else { - uint32_t pos = 38; - - prefetch_load((const uint8_t *)filter_x); - src -= 3; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - /* prefetch data to cache memory */ - prefetch_load(src); - prefetch_load(src + 32); - prefetch_store(dst); - - switch (w) { - case 4: - convolve_horiz_4_dspr2(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filter_x, (int32_t)h); - break; - case 8: - convolve_horiz_8_dspr2(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filter_x, (int32_t)h); - break; - case 16: - convolve_horiz_16_dspr2(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filter_x, (int32_t)h, 1); - break; - case 32: - convolve_horiz_16_dspr2(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filter_x, (int32_t)h, 2); - break; - case 64: - prefetch_load(src + 64); - prefetch_store(dst + 32); - - convolve_horiz_64_dspr2(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filter_x, (int32_t)h); - break; - default: - vpx_convolve8_horiz_c(src + 3, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve8_vert_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve8_vert_dspr2.c deleted file mode 100644 index fd977b53..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve8_vert_dspr2.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/convolve_common_dspr2.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_ports/mem.h" - -#if HAVE_DSPR2 -static void convolve_vert_4_dspr2(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int16_t *filter_y, int32_t w, - int32_t h) { - int32_t x, y; - const uint8_t *src_ptr; - uint8_t *dst_ptr; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector4a = 64; - uint32_t load1, load2, load3, load4; - uint32_t p1, p2; - uint32_t n1, n2; - uint32_t scratch1, scratch2; - uint32_t store1, store2; - int32_t vector1b, vector2b, vector3b, vector4b; - int32_t Temp1, Temp2; - - vector1b = ((const int32_t *)filter_y)[0]; - vector2b = ((const int32_t *)filter_y)[1]; - vector3b = ((const int32_t *)filter_y)[2]; - vector4b = ((const int32_t *)filter_y)[3]; - - src -= 3 * src_stride; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_store(dst + dst_stride); - - for (x = 0; x < w; x += 4) { - src_ptr = src + x; - dst_ptr = dst + x; - - __asm__ __volatile__( - "ulw %[load1], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load2], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load3], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load4], 0(%[src_ptr]) \n\t" - - "mtlo %[vector4a], $ac0 \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac0 \n\t" - "mthi $zero, $ac1 \n\t" - "mthi $zero, $ac2 \n\t" - "mthi $zero, $ac3 \n\t" - - "preceu.ph.qbr %[scratch1], %[load1] \n\t" - "preceu.ph.qbr %[p1], %[load2] \n\t" - "precrq.ph.w %[n1], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - "preceu.ph.qbr %[scratch2], %[load3] \n\t" - "preceu.ph.qbr %[p2], %[load4] \n\t" - "precrq.ph.w %[n2], %[p2], %[scratch2] \n\t" /* pixel 2 */ - "append %[p2], %[scratch2], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac0, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac0, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac1, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac1, %[n2], %[vector2b] \n\t" - - "preceu.ph.qbl %[scratch1], %[load1] \n\t" - "preceu.ph.qbl %[p1], %[load2] \n\t" - "precrq.ph.w %[n1], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - "preceu.ph.qbl %[scratch2], %[load3] \n\t" - "preceu.ph.qbl %[p2], %[load4] \n\t" - "precrq.ph.w %[n2], %[p2], %[scratch2] \n\t" /* pixel 2 */ - "append %[p2], %[scratch2], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac2, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector2b] \n\t" - - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load1], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load2], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load3], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load4], 0(%[src_ptr]) \n\t" - - "preceu.ph.qbr %[scratch1], %[load1] \n\t" - "preceu.ph.qbr %[p1], %[load2] \n\t" - "precrq.ph.w %[n1], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - "preceu.ph.qbr %[scratch2], %[load3] \n\t" - "preceu.ph.qbr %[p2], %[load4] \n\t" - "precrq.ph.w %[n2], %[p2], %[scratch2] \n\t" /* pixel 2 */ - "append %[p2], %[scratch2], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac0, %[p1], %[vector3b] \n\t" - "dpa.w.ph $ac0, %[p2], %[vector4b] \n\t" - "extp %[Temp1], $ac0, 31 \n\t" - "dpa.w.ph $ac1, %[n1], %[vector3b] \n\t" - "dpa.w.ph $ac1, %[n2], %[vector4b] \n\t" - "extp %[Temp2], $ac1, 31 \n\t" - - "preceu.ph.qbl %[scratch1], %[load1] \n\t" - "preceu.ph.qbl %[p1], %[load2] \n\t" - "precrq.ph.w %[n1], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - "preceu.ph.qbl %[scratch2], %[load3] \n\t" - "preceu.ph.qbl %[p2], %[load4] \n\t" - "precrq.ph.w %[n2], %[p2], %[scratch2] \n\t" /* pixel 2 */ - "append %[p2], %[scratch2], 16 \n\t" /* pixel 1 */ - - "lbux %[store1], %[Temp1](%[cm]) \n\t" - "dpa.w.ph $ac2, %[p1], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector4b] \n\t" - "extp %[Temp1], $ac2, 31 \n\t" - - "lbux %[store2], %[Temp2](%[cm]) \n\t" - "dpa.w.ph $ac3, %[n1], %[vector3b] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector4b] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - "sb %[store1], 0(%[dst_ptr]) \n\t" - "sb %[store2], 1(%[dst_ptr]) \n\t" - - "lbux %[store1], %[Temp1](%[cm]) \n\t" - "lbux %[store2], %[Temp2](%[cm]) \n\t" - - "sb %[store1], 2(%[dst_ptr]) \n\t" - "sb %[store2], 3(%[dst_ptr]) \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [p1] "=&r"(p1), [p2] "=&r"(p2), - [n1] "=&r"(n1), [n2] "=&r"(n2), [scratch1] "=&r"(scratch1), - [scratch2] "=&r"(scratch2), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [store1] "=&r"(store1), - [store2] "=&r"(store2), [src_ptr] "+r"(src_ptr) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector3b] "r"(vector3b), [vector4b] "r"(vector4b), - [vector4a] "r"(vector4a), [src_stride] "r"(src_stride), - [cm] "r"(cm), [dst_ptr] "r"(dst_ptr)); - } - - /* Next row... */ - src += src_stride; - dst += dst_stride; - } -} - -static void convolve_vert_64_dspr2(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - const int16_t *filter_y, int32_t h) { - int32_t x, y; - const uint8_t *src_ptr; - uint8_t *dst_ptr; - uint8_t *cm = vpx_ff_cropTbl; - uint32_t vector4a = 64; - uint32_t load1, load2, load3, load4; - uint32_t p1, p2; - uint32_t n1, n2; - uint32_t scratch1, scratch2; - uint32_t store1, store2; - int32_t vector1b, vector2b, vector3b, vector4b; - int32_t Temp1, Temp2; - - vector1b = ((const int32_t *)filter_y)[0]; - vector2b = ((const int32_t *)filter_y)[1]; - vector3b = ((const int32_t *)filter_y)[2]; - vector4b = ((const int32_t *)filter_y)[3]; - - src -= 3 * src_stride; - - for (y = h; y--;) { - /* prefetch data to cache memory */ - prefetch_store(dst + dst_stride); - prefetch_store(dst + dst_stride + 32); - - for (x = 0; x < 64; x += 4) { - src_ptr = src + x; - dst_ptr = dst + x; - - __asm__ __volatile__( - "ulw %[load1], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load2], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load3], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load4], 0(%[src_ptr]) \n\t" - - "mtlo %[vector4a], $ac0 \n\t" - "mtlo %[vector4a], $ac1 \n\t" - "mtlo %[vector4a], $ac2 \n\t" - "mtlo %[vector4a], $ac3 \n\t" - "mthi $zero, $ac0 \n\t" - "mthi $zero, $ac1 \n\t" - "mthi $zero, $ac2 \n\t" - "mthi $zero, $ac3 \n\t" - - "preceu.ph.qbr %[scratch1], %[load1] \n\t" - "preceu.ph.qbr %[p1], %[load2] \n\t" - "precrq.ph.w %[n1], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - "preceu.ph.qbr %[scratch2], %[load3] \n\t" - "preceu.ph.qbr %[p2], %[load4] \n\t" - "precrq.ph.w %[n2], %[p2], %[scratch2] \n\t" /* pixel 2 */ - "append %[p2], %[scratch2], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac0, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac0, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac1, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac1, %[n2], %[vector2b] \n\t" - - "preceu.ph.qbl %[scratch1], %[load1] \n\t" - "preceu.ph.qbl %[p1], %[load2] \n\t" - "precrq.ph.w %[n1], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - "preceu.ph.qbl %[scratch2], %[load3] \n\t" - "preceu.ph.qbl %[p2], %[load4] \n\t" - "precrq.ph.w %[n2], %[p2], %[scratch2] \n\t" /* pixel 2 */ - "append %[p2], %[scratch2], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac2, %[p1], %[vector1b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector2b] \n\t" - "dpa.w.ph $ac3, %[n1], %[vector1b] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector2b] \n\t" - - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load1], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load2], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load3], 0(%[src_ptr]) \n\t" - "add %[src_ptr], %[src_ptr], %[src_stride] \n\t" - "ulw %[load4], 0(%[src_ptr]) \n\t" - - "preceu.ph.qbr %[scratch1], %[load1] \n\t" - "preceu.ph.qbr %[p1], %[load2] \n\t" - "precrq.ph.w %[n1], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - "preceu.ph.qbr %[scratch2], %[load3] \n\t" - "preceu.ph.qbr %[p2], %[load4] \n\t" - "precrq.ph.w %[n2], %[p2], %[scratch2] \n\t" /* pixel 2 */ - "append %[p2], %[scratch2], 16 \n\t" /* pixel 1 */ - - "dpa.w.ph $ac0, %[p1], %[vector3b] \n\t" - "dpa.w.ph $ac0, %[p2], %[vector4b] \n\t" - "extp %[Temp1], $ac0, 31 \n\t" - "dpa.w.ph $ac1, %[n1], %[vector3b] \n\t" - "dpa.w.ph $ac1, %[n2], %[vector4b] \n\t" - "extp %[Temp2], $ac1, 31 \n\t" - - "preceu.ph.qbl %[scratch1], %[load1] \n\t" - "preceu.ph.qbl %[p1], %[load2] \n\t" - "precrq.ph.w %[n1], %[p1], %[scratch1] \n\t" /* pixel 2 */ - "append %[p1], %[scratch1], 16 \n\t" /* pixel 1 */ - "preceu.ph.qbl %[scratch2], %[load3] \n\t" - "preceu.ph.qbl %[p2], %[load4] \n\t" - "precrq.ph.w %[n2], %[p2], %[scratch2] \n\t" /* pixel 2 */ - "append %[p2], %[scratch2], 16 \n\t" /* pixel 1 */ - - "lbux %[store1], %[Temp1](%[cm]) \n\t" - "dpa.w.ph $ac2, %[p1], %[vector3b] \n\t" - "dpa.w.ph $ac2, %[p2], %[vector4b] \n\t" - "extp %[Temp1], $ac2, 31 \n\t" - - "lbux %[store2], %[Temp2](%[cm]) \n\t" - "dpa.w.ph $ac3, %[n1], %[vector3b] \n\t" - "dpa.w.ph $ac3, %[n2], %[vector4b] \n\t" - "extp %[Temp2], $ac3, 31 \n\t" - - "sb %[store1], 0(%[dst_ptr]) \n\t" - "sb %[store2], 1(%[dst_ptr]) \n\t" - - "lbux %[store1], %[Temp1](%[cm]) \n\t" - "lbux %[store2], %[Temp2](%[cm]) \n\t" - - "sb %[store1], 2(%[dst_ptr]) \n\t" - "sb %[store2], 3(%[dst_ptr]) \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [p1] "=&r"(p1), [p2] "=&r"(p2), - [n1] "=&r"(n1), [n2] "=&r"(n2), [scratch1] "=&r"(scratch1), - [scratch2] "=&r"(scratch2), [Temp1] "=&r"(Temp1), - [Temp2] "=&r"(Temp2), [store1] "=&r"(store1), - [store2] "=&r"(store2), [src_ptr] "+r"(src_ptr) - : [vector1b] "r"(vector1b), [vector2b] "r"(vector2b), - [vector3b] "r"(vector3b), [vector4b] "r"(vector4b), - [vector4a] "r"(vector4a), [src_stride] "r"(src_stride), - [cm] "r"(cm), [dst_ptr] "r"(dst_ptr)); - } - - /* Next row... */ - src += src_stride; - dst += dst_stride; - } -} - -void vpx_convolve8_vert_dspr2(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - const int16_t *const filter_y = filter[y0_q4]; - assert(y_step_q4 == 16); - assert(((const int32_t *)filter_y)[1] != 0x800000); - - if (vpx_get_filter_taps(filter_y) == 2) { - vpx_convolve2_vert_dspr2(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - } else { - uint32_t pos = 38; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - prefetch_store(dst); - - switch (w) { - case 4: - case 8: - case 16: - case 32: - convolve_vert_4_dspr2(src, src_stride, dst, dst_stride, filter_y, w, h); - break; - case 64: - prefetch_store(dst + 32); - convolve_vert_64_dspr2(src, src_stride, dst, dst_stride, filter_y, h); - break; - default: - vpx_convolve8_vert_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } -} - -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve_common_dspr2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve_common_dspr2.h deleted file mode 100644 index 14b65bc6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/convolve_common_dspr2.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_MIPS_CONVOLVE_COMMON_DSPR2_H_ -#define VPX_VPX_DSP_MIPS_CONVOLVE_COMMON_DSPR2_H_ - -#include - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/mips/common_dspr2.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if HAVE_DSPR2 -void vpx_convolve2_horiz_dspr2(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int y_step_q4, - int w, int h); - -void vpx_convolve2_avg_horiz_dspr2(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int y_step_q4, - int w, int h); - -void vpx_convolve2_avg_vert_dspr2(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int y_step_q4, - int w, int h); - -void vpx_convolve2_dspr2(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const int16_t *filter, int w, - int h); - -void vpx_convolve2_vert_dspr2(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int y_step_q4, - int w, int h); - -#endif // #if HAVE_DSPR2 -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_MIPS_CONVOLVE_COMMON_DSPR2_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/deblock_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/deblock_msa.c deleted file mode 100644 index 4e93ff59..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/deblock_msa.c +++ /dev/null @@ -1,742 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/macros_msa.h" - -extern const int16_t vpx_rv[]; - -#define VPX_TRANSPOSE8x16_UB_UB( \ - in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, out3, out4, \ - out5, out6, out7, out8, out9, out10, out11, out12, out13, out14, out15) \ - { \ - v8i16 temp0, temp1, temp2, temp3, temp4; \ - v8i16 temp5, temp6, temp7, temp8, temp9; \ - \ - ILVR_B4_SH(in1, in0, in3, in2, in5, in4, in7, in6, temp0, temp1, temp2, \ - temp3); \ - ILVR_H2_SH(temp1, temp0, temp3, temp2, temp4, temp5); \ - ILVRL_W2_SH(temp5, temp4, temp6, temp7); \ - ILVL_H2_SH(temp1, temp0, temp3, temp2, temp4, temp5); \ - ILVRL_W2_SH(temp5, temp4, temp8, temp9); \ - ILVL_B4_SH(in1, in0, in3, in2, in5, in4, in7, in6, temp0, temp1, temp2, \ - temp3); \ - ILVR_H2_SH(temp1, temp0, temp3, temp2, temp4, temp5); \ - ILVRL_W2_UB(temp5, temp4, out8, out10); \ - ILVL_H2_SH(temp1, temp0, temp3, temp2, temp4, temp5); \ - ILVRL_W2_UB(temp5, temp4, out12, out14); \ - out0 = (v16u8)temp6; \ - out2 = (v16u8)temp7; \ - out4 = (v16u8)temp8; \ - out6 = (v16u8)temp9; \ - out9 = (v16u8)__msa_ilvl_d((v2i64)out8, (v2i64)out8); \ - out11 = (v16u8)__msa_ilvl_d((v2i64)out10, (v2i64)out10); \ - out13 = (v16u8)__msa_ilvl_d((v2i64)out12, (v2i64)out12); \ - out15 = (v16u8)__msa_ilvl_d((v2i64)out14, (v2i64)out14); \ - out1 = (v16u8)__msa_ilvl_d((v2i64)out0, (v2i64)out0); \ - out3 = (v16u8)__msa_ilvl_d((v2i64)out2, (v2i64)out2); \ - out5 = (v16u8)__msa_ilvl_d((v2i64)out4, (v2i64)out4); \ - out7 = (v16u8)__msa_ilvl_d((v2i64)out6, (v2i64)out6); \ - } - -#define VPX_AVER_IF_RETAIN(above2_in, above1_in, src_in, below1_in, below2_in, \ - ref, out) \ - { \ - v16u8 temp0, temp1; \ - \ - temp1 = __msa_aver_u_b(above2_in, above1_in); \ - temp0 = __msa_aver_u_b(below2_in, below1_in); \ - temp1 = __msa_aver_u_b(temp1, temp0); \ - out = __msa_aver_u_b(src_in, temp1); \ - temp0 = __msa_asub_u_b(src_in, above2_in); \ - temp1 = __msa_asub_u_b(src_in, above1_in); \ - temp0 = (temp0 < ref); \ - temp1 = (temp1 < ref); \ - temp0 = temp0 & temp1; \ - temp1 = __msa_asub_u_b(src_in, below1_in); \ - temp1 = (temp1 < ref); \ - temp0 = temp0 & temp1; \ - temp1 = __msa_asub_u_b(src_in, below2_in); \ - temp1 = (temp1 < ref); \ - temp0 = temp0 & temp1; \ - out = __msa_bmz_v(out, src_in, temp0); \ - } - -#define TRANSPOSE12x16_B(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, \ - in10, in11, in12, in13, in14, in15) \ - { \ - v8i16 temp0, temp1, temp2, temp3, temp4; \ - v8i16 temp5, temp6, temp7, temp8, temp9; \ - \ - ILVR_B2_SH(in1, in0, in3, in2, temp0, temp1); \ - ILVRL_H2_SH(temp1, temp0, temp2, temp3); \ - ILVR_B2_SH(in5, in4, in7, in6, temp0, temp1); \ - ILVRL_H2_SH(temp1, temp0, temp4, temp5); \ - ILVRL_W2_SH(temp4, temp2, temp0, temp1); \ - ILVRL_W2_SH(temp5, temp3, temp2, temp3); \ - ILVR_B2_SH(in9, in8, in11, in10, temp4, temp5); \ - ILVR_B2_SH(in9, in8, in11, in10, temp4, temp5); \ - ILVRL_H2_SH(temp5, temp4, temp6, temp7); \ - ILVR_B2_SH(in13, in12, in15, in14, temp4, temp5); \ - ILVRL_H2_SH(temp5, temp4, temp8, temp9); \ - ILVRL_W2_SH(temp8, temp6, temp4, temp5); \ - ILVRL_W2_SH(temp9, temp7, temp6, temp7); \ - ILVL_B2_SH(in1, in0, in3, in2, temp8, temp9); \ - ILVR_D2_UB(temp4, temp0, temp5, temp1, in0, in2); \ - in1 = (v16u8)__msa_ilvl_d((v2i64)temp4, (v2i64)temp0); \ - in3 = (v16u8)__msa_ilvl_d((v2i64)temp5, (v2i64)temp1); \ - ILVL_B2_SH(in5, in4, in7, in6, temp0, temp1); \ - ILVR_D2_UB(temp6, temp2, temp7, temp3, in4, in6); \ - in5 = (v16u8)__msa_ilvl_d((v2i64)temp6, (v2i64)temp2); \ - in7 = (v16u8)__msa_ilvl_d((v2i64)temp7, (v2i64)temp3); \ - ILVL_B4_SH(in9, in8, in11, in10, in13, in12, in15, in14, temp2, temp3, \ - temp4, temp5); \ - ILVR_H4_SH(temp9, temp8, temp1, temp0, temp3, temp2, temp5, temp4, temp6, \ - temp7, temp8, temp9); \ - ILVR_W2_SH(temp7, temp6, temp9, temp8, temp0, temp1); \ - in8 = (v16u8)__msa_ilvr_d((v2i64)temp1, (v2i64)temp0); \ - in9 = (v16u8)__msa_ilvl_d((v2i64)temp1, (v2i64)temp0); \ - ILVL_W2_SH(temp7, temp6, temp9, temp8, temp2, temp3); \ - in10 = (v16u8)__msa_ilvr_d((v2i64)temp3, (v2i64)temp2); \ - in11 = (v16u8)__msa_ilvl_d((v2i64)temp3, (v2i64)temp2); \ - } - -#define VPX_TRANSPOSE12x8_UB_UB(in0, in1, in2, in3, in4, in5, in6, in7, in8, \ - in9, in10, in11) \ - { \ - v8i16 temp0, temp1, temp2, temp3; \ - v8i16 temp4, temp5, temp6, temp7; \ - \ - ILVR_B2_SH(in1, in0, in3, in2, temp0, temp1); \ - ILVRL_H2_SH(temp1, temp0, temp2, temp3); \ - ILVR_B2_SH(in5, in4, in7, in6, temp0, temp1); \ - ILVRL_H2_SH(temp1, temp0, temp4, temp5); \ - ILVRL_W2_SH(temp4, temp2, temp0, temp1); \ - ILVRL_W2_SH(temp5, temp3, temp2, temp3); \ - ILVL_B2_SH(in1, in0, in3, in2, temp4, temp5); \ - temp4 = __msa_ilvr_h(temp5, temp4); \ - ILVL_B2_SH(in5, in4, in7, in6, temp6, temp7); \ - temp5 = __msa_ilvr_h(temp7, temp6); \ - ILVRL_W2_SH(temp5, temp4, temp6, temp7); \ - in0 = (v16u8)temp0; \ - in2 = (v16u8)temp1; \ - in4 = (v16u8)temp2; \ - in6 = (v16u8)temp3; \ - in8 = (v16u8)temp6; \ - in10 = (v16u8)temp7; \ - in1 = (v16u8)__msa_ilvl_d((v2i64)temp0, (v2i64)temp0); \ - in3 = (v16u8)__msa_ilvl_d((v2i64)temp1, (v2i64)temp1); \ - in5 = (v16u8)__msa_ilvl_d((v2i64)temp2, (v2i64)temp2); \ - in7 = (v16u8)__msa_ilvl_d((v2i64)temp3, (v2i64)temp3); \ - in9 = (v16u8)__msa_ilvl_d((v2i64)temp6, (v2i64)temp6); \ - in11 = (v16u8)__msa_ilvl_d((v2i64)temp7, (v2i64)temp7); \ - } - -static void postproc_down_across_chroma_msa(uint8_t *src_ptr, uint8_t *dst_ptr, - int32_t src_stride, - int32_t dst_stride, int32_t cols, - uint8_t *f) { - uint8_t *p_src = src_ptr; - uint8_t *p_dst = dst_ptr; - uint8_t *f_orig = f; - uint8_t *p_dst_st = dst_ptr; - uint16_t col; - uint64_t out0, out1, out2, out3; - v16u8 above2, above1, below2, below1, src, ref, ref_temp; - v16u8 inter0, inter1, inter2, inter3, inter4, inter5; - v16u8 inter6, inter7, inter8, inter9, inter10, inter11; - - for (col = (cols / 16); col--;) { - ref = LD_UB(f); - LD_UB2(p_src - 2 * src_stride, src_stride, above2, above1); - src = LD_UB(p_src); - LD_UB2(p_src + 1 * src_stride, src_stride, below1, below2); - VPX_AVER_IF_RETAIN(above2, above1, src, below1, below2, ref, inter0); - above2 = LD_UB(p_src + 3 * src_stride); - VPX_AVER_IF_RETAIN(above1, src, below1, below2, above2, ref, inter1); - above1 = LD_UB(p_src + 4 * src_stride); - VPX_AVER_IF_RETAIN(src, below1, below2, above2, above1, ref, inter2); - src = LD_UB(p_src + 5 * src_stride); - VPX_AVER_IF_RETAIN(below1, below2, above2, above1, src, ref, inter3); - below1 = LD_UB(p_src + 6 * src_stride); - VPX_AVER_IF_RETAIN(below2, above2, above1, src, below1, ref, inter4); - below2 = LD_UB(p_src + 7 * src_stride); - VPX_AVER_IF_RETAIN(above2, above1, src, below1, below2, ref, inter5); - above2 = LD_UB(p_src + 8 * src_stride); - VPX_AVER_IF_RETAIN(above1, src, below1, below2, above2, ref, inter6); - above1 = LD_UB(p_src + 9 * src_stride); - VPX_AVER_IF_RETAIN(src, below1, below2, above2, above1, ref, inter7); - ST_UB8(inter0, inter1, inter2, inter3, inter4, inter5, inter6, inter7, - p_dst, dst_stride); - - p_dst += 16; - p_src += 16; - f += 16; - } - - if (0 != (cols / 16)) { - ref = LD_UB(f); - LD_UB2(p_src - 2 * src_stride, src_stride, above2, above1); - src = LD_UB(p_src); - LD_UB2(p_src + 1 * src_stride, src_stride, below1, below2); - VPX_AVER_IF_RETAIN(above2, above1, src, below1, below2, ref, inter0); - above2 = LD_UB(p_src + 3 * src_stride); - VPX_AVER_IF_RETAIN(above1, src, below1, below2, above2, ref, inter1); - above1 = LD_UB(p_src + 4 * src_stride); - VPX_AVER_IF_RETAIN(src, below1, below2, above2, above1, ref, inter2); - src = LD_UB(p_src + 5 * src_stride); - VPX_AVER_IF_RETAIN(below1, below2, above2, above1, src, ref, inter3); - below1 = LD_UB(p_src + 6 * src_stride); - VPX_AVER_IF_RETAIN(below2, above2, above1, src, below1, ref, inter4); - below2 = LD_UB(p_src + 7 * src_stride); - VPX_AVER_IF_RETAIN(above2, above1, src, below1, below2, ref, inter5); - above2 = LD_UB(p_src + 8 * src_stride); - VPX_AVER_IF_RETAIN(above1, src, below1, below2, above2, ref, inter6); - above1 = LD_UB(p_src + 9 * src_stride); - VPX_AVER_IF_RETAIN(src, below1, below2, above2, above1, ref, inter7); - out0 = __msa_copy_u_d((v2i64)inter0, 0); - out1 = __msa_copy_u_d((v2i64)inter1, 0); - out2 = __msa_copy_u_d((v2i64)inter2, 0); - out3 = __msa_copy_u_d((v2i64)inter3, 0); - SD4(out0, out1, out2, out3, p_dst, dst_stride); - - out0 = __msa_copy_u_d((v2i64)inter4, 0); - out1 = __msa_copy_u_d((v2i64)inter5, 0); - out2 = __msa_copy_u_d((v2i64)inter6, 0); - out3 = __msa_copy_u_d((v2i64)inter7, 0); - SD4(out0, out1, out2, out3, p_dst + 4 * dst_stride, dst_stride); - } - - f = f_orig; - p_dst = dst_ptr - 2; - LD_UB8(p_dst, dst_stride, inter0, inter1, inter2, inter3, inter4, inter5, - inter6, inter7); - - for (col = 0; col < (cols / 8); ++col) { - ref = LD_UB(f); - f += 8; - VPX_TRANSPOSE12x8_UB_UB(inter0, inter1, inter2, inter3, inter4, inter5, - inter6, inter7, inter8, inter9, inter10, inter11); - if (0 == col) { - above2 = inter2; - above1 = inter2; - } else { - above2 = inter0; - above1 = inter1; - } - src = inter2; - below1 = inter3; - below2 = inter4; - ref_temp = (v16u8)__msa_splati_b((v16i8)ref, 0); - VPX_AVER_IF_RETAIN(above2, above1, src, below1, below2, ref_temp, inter2); - above2 = inter5; - ref_temp = (v16u8)__msa_splati_b((v16i8)ref, 1); - VPX_AVER_IF_RETAIN(above1, src, below1, below2, above2, ref_temp, inter3); - above1 = inter6; - ref_temp = (v16u8)__msa_splati_b((v16i8)ref, 2); - VPX_AVER_IF_RETAIN(src, below1, below2, above2, above1, ref_temp, inter4); - src = inter7; - ref_temp = (v16u8)__msa_splati_b((v16i8)ref, 3); - VPX_AVER_IF_RETAIN(below1, below2, above2, above1, src, ref_temp, inter5); - below1 = inter8; - ref_temp = (v16u8)__msa_splati_b((v16i8)ref, 4); - VPX_AVER_IF_RETAIN(below2, above2, above1, src, below1, ref_temp, inter6); - below2 = inter9; - ref_temp = (v16u8)__msa_splati_b((v16i8)ref, 5); - VPX_AVER_IF_RETAIN(above2, above1, src, below1, below2, ref_temp, inter7); - if (col == (cols / 8 - 1)) { - above2 = inter9; - } else { - above2 = inter10; - } - ref_temp = (v16u8)__msa_splati_b((v16i8)ref, 6); - VPX_AVER_IF_RETAIN(above1, src, below1, below2, above2, ref_temp, inter8); - if (col == (cols / 8 - 1)) { - above1 = inter9; - } else { - above1 = inter11; - } - ref_temp = (v16u8)__msa_splati_b((v16i8)ref, 7); - VPX_AVER_IF_RETAIN(src, below1, below2, above2, above1, ref_temp, inter9); - TRANSPOSE8x8_UB_UB(inter2, inter3, inter4, inter5, inter6, inter7, inter8, - inter9, inter2, inter3, inter4, inter5, inter6, inter7, - inter8, inter9); - p_dst += 8; - LD_UB2(p_dst, dst_stride, inter0, inter1); - ST8x1_UB(inter2, p_dst_st); - ST8x1_UB(inter3, (p_dst_st + 1 * dst_stride)); - LD_UB2(p_dst + 2 * dst_stride, dst_stride, inter2, inter3); - ST8x1_UB(inter4, (p_dst_st + 2 * dst_stride)); - ST8x1_UB(inter5, (p_dst_st + 3 * dst_stride)); - LD_UB2(p_dst + 4 * dst_stride, dst_stride, inter4, inter5); - ST8x1_UB(inter6, (p_dst_st + 4 * dst_stride)); - ST8x1_UB(inter7, (p_dst_st + 5 * dst_stride)); - LD_UB2(p_dst + 6 * dst_stride, dst_stride, inter6, inter7); - ST8x1_UB(inter8, (p_dst_st + 6 * dst_stride)); - ST8x1_UB(inter9, (p_dst_st + 7 * dst_stride)); - p_dst_st += 8; - } -} - -static void postproc_down_across_luma_msa(uint8_t *src_ptr, uint8_t *dst_ptr, - int32_t src_stride, - int32_t dst_stride, int32_t cols, - uint8_t *f) { - uint8_t *p_src = src_ptr; - uint8_t *p_dst = dst_ptr; - uint8_t *p_dst_st = dst_ptr; - uint8_t *f_orig = f; - uint16_t col; - uint64_t out0, out1, out2, out3; - v16u8 above2, above1, below2, below1; - v16u8 src, ref, ref_temp; - v16u8 inter0, inter1, inter2, inter3, inter4, inter5, inter6; - v16u8 inter7, inter8, inter9, inter10, inter11; - v16u8 inter12, inter13, inter14, inter15; - - for (col = (cols / 16); col--;) { - ref = LD_UB(f); - LD_UB2(p_src - 2 * src_stride, src_stride, above2, above1); - src = LD_UB(p_src); - LD_UB2(p_src + 1 * src_stride, src_stride, below1, below2); - VPX_AVER_IF_RETAIN(above2, above1, src, below1, below2, ref, inter0); - above2 = LD_UB(p_src + 3 * src_stride); - VPX_AVER_IF_RETAIN(above1, src, below1, below2, above2, ref, inter1); - above1 = LD_UB(p_src + 4 * src_stride); - VPX_AVER_IF_RETAIN(src, below1, below2, above2, above1, ref, inter2); - src = LD_UB(p_src + 5 * src_stride); - VPX_AVER_IF_RETAIN(below1, below2, above2, above1, src, ref, inter3); - below1 = LD_UB(p_src + 6 * src_stride); - VPX_AVER_IF_RETAIN(below2, above2, above1, src, below1, ref, inter4); - below2 = LD_UB(p_src + 7 * src_stride); - VPX_AVER_IF_RETAIN(above2, above1, src, below1, below2, ref, inter5); - above2 = LD_UB(p_src + 8 * src_stride); - VPX_AVER_IF_RETAIN(above1, src, below1, below2, above2, ref, inter6); - above1 = LD_UB(p_src + 9 * src_stride); - VPX_AVER_IF_RETAIN(src, below1, below2, above2, above1, ref, inter7); - src = LD_UB(p_src + 10 * src_stride); - VPX_AVER_IF_RETAIN(below1, below2, above2, above1, src, ref, inter8); - below1 = LD_UB(p_src + 11 * src_stride); - VPX_AVER_IF_RETAIN(below2, above2, above1, src, below1, ref, inter9); - below2 = LD_UB(p_src + 12 * src_stride); - VPX_AVER_IF_RETAIN(above2, above1, src, below1, below2, ref, inter10); - above2 = LD_UB(p_src + 13 * src_stride); - VPX_AVER_IF_RETAIN(above1, src, below1, below2, above2, ref, inter11); - above1 = LD_UB(p_src + 14 * src_stride); - VPX_AVER_IF_RETAIN(src, below1, below2, above2, above1, ref, inter12); - src = LD_UB(p_src + 15 * src_stride); - VPX_AVER_IF_RETAIN(below1, below2, above2, above1, src, ref, inter13); - below1 = LD_UB(p_src + 16 * src_stride); - VPX_AVER_IF_RETAIN(below2, above2, above1, src, below1, ref, inter14); - below2 = LD_UB(p_src + 17 * src_stride); - VPX_AVER_IF_RETAIN(above2, above1, src, below1, below2, ref, inter15); - ST_UB8(inter0, inter1, inter2, inter3, inter4, inter5, inter6, inter7, - p_dst, dst_stride); - ST_UB8(inter8, inter9, inter10, inter11, inter12, inter13, inter14, inter15, - p_dst + 8 * dst_stride, dst_stride); - p_src += 16; - p_dst += 16; - f += 16; - } - - if (0 != (cols / 16)) { - ref = LD_UB(f); - LD_UB2(p_src - 2 * src_stride, src_stride, above2, above1); - src = LD_UB(p_src); - LD_UB2(p_src + 1 * src_stride, src_stride, below1, below2); - VPX_AVER_IF_RETAIN(above2, above1, src, below1, below2, ref, inter0); - above2 = LD_UB(p_src + 3 * src_stride); - VPX_AVER_IF_RETAIN(above1, src, below1, below2, above2, ref, inter1); - above1 = LD_UB(p_src + 4 * src_stride); - VPX_AVER_IF_RETAIN(src, below1, below2, above2, above1, ref, inter2); - src = LD_UB(p_src + 5 * src_stride); - VPX_AVER_IF_RETAIN(below1, below2, above2, above1, src, ref, inter3); - below1 = LD_UB(p_src + 6 * src_stride); - VPX_AVER_IF_RETAIN(below2, above2, above1, src, below1, ref, inter4); - below2 = LD_UB(p_src + 7 * src_stride); - VPX_AVER_IF_RETAIN(above2, above1, src, below1, below2, ref, inter5); - above2 = LD_UB(p_src + 8 * src_stride); - VPX_AVER_IF_RETAIN(above1, src, below1, below2, above2, ref, inter6); - above1 = LD_UB(p_src + 9 * src_stride); - VPX_AVER_IF_RETAIN(src, below1, below2, above2, above1, ref, inter7); - src = LD_UB(p_src + 10 * src_stride); - VPX_AVER_IF_RETAIN(below1, below2, above2, above1, src, ref, inter8); - below1 = LD_UB(p_src + 11 * src_stride); - VPX_AVER_IF_RETAIN(below2, above2, above1, src, below1, ref, inter9); - below2 = LD_UB(p_src + 12 * src_stride); - VPX_AVER_IF_RETAIN(above2, above1, src, below1, below2, ref, inter10); - above2 = LD_UB(p_src + 13 * src_stride); - VPX_AVER_IF_RETAIN(above1, src, below1, below2, above2, ref, inter11); - above1 = LD_UB(p_src + 14 * src_stride); - VPX_AVER_IF_RETAIN(src, below1, below2, above2, above1, ref, inter12); - src = LD_UB(p_src + 15 * src_stride); - VPX_AVER_IF_RETAIN(below1, below2, above2, above1, src, ref, inter13); - below1 = LD_UB(p_src + 16 * src_stride); - VPX_AVER_IF_RETAIN(below2, above2, above1, src, below1, ref, inter14); - below2 = LD_UB(p_src + 17 * src_stride); - VPX_AVER_IF_RETAIN(above2, above1, src, below1, below2, ref, inter15); - out0 = __msa_copy_u_d((v2i64)inter0, 0); - out1 = __msa_copy_u_d((v2i64)inter1, 0); - out2 = __msa_copy_u_d((v2i64)inter2, 0); - out3 = __msa_copy_u_d((v2i64)inter3, 0); - SD4(out0, out1, out2, out3, p_dst, dst_stride); - - out0 = __msa_copy_u_d((v2i64)inter4, 0); - out1 = __msa_copy_u_d((v2i64)inter5, 0); - out2 = __msa_copy_u_d((v2i64)inter6, 0); - out3 = __msa_copy_u_d((v2i64)inter7, 0); - SD4(out0, out1, out2, out3, p_dst + 4 * dst_stride, dst_stride); - - out0 = __msa_copy_u_d((v2i64)inter8, 0); - out1 = __msa_copy_u_d((v2i64)inter9, 0); - out2 = __msa_copy_u_d((v2i64)inter10, 0); - out3 = __msa_copy_u_d((v2i64)inter11, 0); - SD4(out0, out1, out2, out3, p_dst + 8 * dst_stride, dst_stride); - - out0 = __msa_copy_u_d((v2i64)inter12, 0); - out1 = __msa_copy_u_d((v2i64)inter13, 0); - out2 = __msa_copy_u_d((v2i64)inter14, 0); - out3 = __msa_copy_u_d((v2i64)inter15, 0); - SD4(out0, out1, out2, out3, p_dst + 12 * dst_stride, dst_stride); - } - - f = f_orig; - p_dst = dst_ptr - 2; - LD_UB8(p_dst, dst_stride, inter0, inter1, inter2, inter3, inter4, inter5, - inter6, inter7); - LD_UB8(p_dst + 8 * dst_stride, dst_stride, inter8, inter9, inter10, inter11, - inter12, inter13, inter14, inter15); - - for (col = 0; col < cols / 8; ++col) { - ref = LD_UB(f); - f += 8; - TRANSPOSE12x16_B(inter0, inter1, inter2, inter3, inter4, inter5, inter6, - inter7, inter8, inter9, inter10, inter11, inter12, inter13, - inter14, inter15); - if (0 == col) { - above2 = inter2; - above1 = inter2; - } else { - above2 = inter0; - above1 = inter1; - } - - src = inter2; - below1 = inter3; - below2 = inter4; - ref_temp = (v16u8)__msa_splati_b((v16i8)ref, 0); - VPX_AVER_IF_RETAIN(above2, above1, src, below1, below2, ref_temp, inter2); - above2 = inter5; - ref_temp = (v16u8)__msa_splati_b((v16i8)ref, 1); - VPX_AVER_IF_RETAIN(above1, src, below1, below2, above2, ref_temp, inter3); - above1 = inter6; - ref_temp = (v16u8)__msa_splati_b((v16i8)ref, 2); - VPX_AVER_IF_RETAIN(src, below1, below2, above2, above1, ref_temp, inter4); - src = inter7; - ref_temp = (v16u8)__msa_splati_b((v16i8)ref, 3); - VPX_AVER_IF_RETAIN(below1, below2, above2, above1, src, ref_temp, inter5); - below1 = inter8; - ref_temp = (v16u8)__msa_splati_b((v16i8)ref, 4); - VPX_AVER_IF_RETAIN(below2, above2, above1, src, below1, ref_temp, inter6); - below2 = inter9; - ref_temp = (v16u8)__msa_splati_b((v16i8)ref, 5); - VPX_AVER_IF_RETAIN(above2, above1, src, below1, below2, ref_temp, inter7); - if (col == (cols / 8 - 1)) { - above2 = inter9; - } else { - above2 = inter10; - } - ref_temp = (v16u8)__msa_splati_b((v16i8)ref, 6); - VPX_AVER_IF_RETAIN(above1, src, below1, below2, above2, ref_temp, inter8); - if (col == (cols / 8 - 1)) { - above1 = inter9; - } else { - above1 = inter11; - } - ref_temp = (v16u8)__msa_splati_b((v16i8)ref, 7); - VPX_AVER_IF_RETAIN(src, below1, below2, above2, above1, ref_temp, inter9); - VPX_TRANSPOSE8x16_UB_UB(inter2, inter3, inter4, inter5, inter6, inter7, - inter8, inter9, inter2, inter3, inter4, inter5, - inter6, inter7, inter8, inter9, inter10, inter11, - inter12, inter13, inter14, inter15, above2, above1); - - p_dst += 8; - LD_UB2(p_dst, dst_stride, inter0, inter1); - ST8x1_UB(inter2, p_dst_st); - ST8x1_UB(inter3, (p_dst_st + 1 * dst_stride)); - LD_UB2(p_dst + 2 * dst_stride, dst_stride, inter2, inter3); - ST8x1_UB(inter4, (p_dst_st + 2 * dst_stride)); - ST8x1_UB(inter5, (p_dst_st + 3 * dst_stride)); - LD_UB2(p_dst + 4 * dst_stride, dst_stride, inter4, inter5); - ST8x1_UB(inter6, (p_dst_st + 4 * dst_stride)); - ST8x1_UB(inter7, (p_dst_st + 5 * dst_stride)); - LD_UB2(p_dst + 6 * dst_stride, dst_stride, inter6, inter7); - ST8x1_UB(inter8, (p_dst_st + 6 * dst_stride)); - ST8x1_UB(inter9, (p_dst_st + 7 * dst_stride)); - LD_UB2(p_dst + 8 * dst_stride, dst_stride, inter8, inter9); - ST8x1_UB(inter10, (p_dst_st + 8 * dst_stride)); - ST8x1_UB(inter11, (p_dst_st + 9 * dst_stride)); - LD_UB2(p_dst + 10 * dst_stride, dst_stride, inter10, inter11); - ST8x1_UB(inter12, (p_dst_st + 10 * dst_stride)); - ST8x1_UB(inter13, (p_dst_st + 11 * dst_stride)); - LD_UB2(p_dst + 12 * dst_stride, dst_stride, inter12, inter13); - ST8x1_UB(inter14, (p_dst_st + 12 * dst_stride)); - ST8x1_UB(inter15, (p_dst_st + 13 * dst_stride)); - LD_UB2(p_dst + 14 * dst_stride, dst_stride, inter14, inter15); - ST8x1_UB(above2, (p_dst_st + 14 * dst_stride)); - ST8x1_UB(above1, (p_dst_st + 15 * dst_stride)); - p_dst_st += 8; - } -} - -void vpx_post_proc_down_and_across_mb_row_msa(uint8_t *src, uint8_t *dst, - int32_t src_stride, - int32_t dst_stride, int32_t cols, - uint8_t *f, int32_t size) { - if (8 == size) { - postproc_down_across_chroma_msa(src, dst, src_stride, dst_stride, cols, f); - } else if (16 == size) { - postproc_down_across_luma_msa(src, dst, src_stride, dst_stride, cols, f); - } -} - -void vpx_mbpost_proc_across_ip_msa(uint8_t *src, int32_t pitch, int32_t rows, - int32_t cols, int32_t flimit) { - int32_t row, col, cnt; - uint8_t *src_dup = src; - v16u8 src0, src1, tmp_orig; - v16u8 tmp = { 0 }; - v16i8 zero = { 0 }; - v8u16 sum_h, src_r_h, src_l_h; - v4u32 src_r_w; - v4i32 flimit_vec; - - flimit_vec = __msa_fill_w(flimit); - for (row = rows; row--;) { - int32_t sum_sq; - int32_t sum = 0; - src0 = (v16u8)__msa_fill_b(src_dup[0]); - ST8x1_UB(src0, (src_dup - 8)); - - src0 = (v16u8)__msa_fill_b(src_dup[cols - 1]); - ST_UB(src0, src_dup + cols); - src_dup[cols + 16] = src_dup[cols - 1]; - tmp_orig = (v16u8)__msa_ldi_b(0); - tmp_orig[15] = tmp[15]; - src1 = LD_UB(src_dup - 8); - src1[15] = 0; - ILVRL_B2_UH(zero, src1, src_r_h, src_l_h); - src_r_w = __msa_dotp_u_w(src_r_h, src_r_h); - src_r_w += __msa_dotp_u_w(src_l_h, src_l_h); - sum_sq = HADD_SW_S32(src_r_w) + 16; - sum_h = __msa_hadd_u_h(src1, src1); - sum = HADD_UH_U32(sum_h); - { - v16u8 src7, src8, src_r, src_l; - v16i8 mask; - v8u16 add_r, add_l; - v8i16 sub_r, sub_l, sum_r, sum_l, mask0, mask1; - v4i32 sum_sq0, sum_sq1, sum_sq2, sum_sq3; - v4i32 sub0, sub1, sub2, sub3; - v4i32 sum0_w, sum1_w, sum2_w, sum3_w; - v4i32 mul0, mul1, mul2, mul3; - v4i32 total0, total1, total2, total3; - v8i16 const8 = __msa_fill_h(8); - - src7 = LD_UB(src_dup + 7); - src8 = LD_UB(src_dup - 8); - for (col = 0; col < (cols >> 4); ++col) { - ILVRL_B2_UB(src7, src8, src_r, src_l); - HSUB_UB2_SH(src_r, src_l, sub_r, sub_l); - - sum_r[0] = sum + sub_r[0]; - for (cnt = 0; cnt < 7; ++cnt) { - sum_r[cnt + 1] = sum_r[cnt] + sub_r[cnt + 1]; - } - sum_l[0] = sum_r[7] + sub_l[0]; - for (cnt = 0; cnt < 7; ++cnt) { - sum_l[cnt + 1] = sum_l[cnt] + sub_l[cnt + 1]; - } - sum = sum_l[7]; - src1 = LD_UB(src_dup + 16 * col); - ILVRL_B2_UH(zero, src1, src_r_h, src_l_h); - src7 = (v16u8)((const8 + sum_r + (v8i16)src_r_h) >> 4); - src8 = (v16u8)((const8 + sum_l + (v8i16)src_l_h) >> 4); - tmp = (v16u8)__msa_pckev_b((v16i8)src8, (v16i8)src7); - - HADD_UB2_UH(src_r, src_l, add_r, add_l); - UNPCK_SH_SW(sub_r, sub0, sub1); - UNPCK_SH_SW(sub_l, sub2, sub3); - ILVR_H2_SW(zero, add_r, zero, add_l, sum0_w, sum2_w); - ILVL_H2_SW(zero, add_r, zero, add_l, sum1_w, sum3_w); - MUL4(sum0_w, sub0, sum1_w, sub1, sum2_w, sub2, sum3_w, sub3, mul0, mul1, - mul2, mul3); - sum_sq0[0] = sum_sq + mul0[0]; - for (cnt = 0; cnt < 3; ++cnt) { - sum_sq0[cnt + 1] = sum_sq0[cnt] + mul0[cnt + 1]; - } - sum_sq1[0] = sum_sq0[3] + mul1[0]; - for (cnt = 0; cnt < 3; ++cnt) { - sum_sq1[cnt + 1] = sum_sq1[cnt] + mul1[cnt + 1]; - } - sum_sq2[0] = sum_sq1[3] + mul2[0]; - for (cnt = 0; cnt < 3; ++cnt) { - sum_sq2[cnt + 1] = sum_sq2[cnt] + mul2[cnt + 1]; - } - sum_sq3[0] = sum_sq2[3] + mul3[0]; - for (cnt = 0; cnt < 3; ++cnt) { - sum_sq3[cnt + 1] = sum_sq3[cnt] + mul3[cnt + 1]; - } - sum_sq = sum_sq3[3]; - - UNPCK_SH_SW(sum_r, sum0_w, sum1_w); - UNPCK_SH_SW(sum_l, sum2_w, sum3_w); - total0 = sum_sq0 * __msa_ldi_w(15); - total0 -= sum0_w * sum0_w; - total1 = sum_sq1 * __msa_ldi_w(15); - total1 -= sum1_w * sum1_w; - total2 = sum_sq2 * __msa_ldi_w(15); - total2 -= sum2_w * sum2_w; - total3 = sum_sq3 * __msa_ldi_w(15); - total3 -= sum3_w * sum3_w; - total0 = (total0 < flimit_vec); - total1 = (total1 < flimit_vec); - total2 = (total2 < flimit_vec); - total3 = (total3 < flimit_vec); - PCKEV_H2_SH(total1, total0, total3, total2, mask0, mask1); - mask = __msa_pckev_b((v16i8)mask1, (v16i8)mask0); - tmp = __msa_bmz_v(tmp, src1, (v16u8)mask); - - if (col == 0) { - uint64_t src_d; - - src_d = __msa_copy_u_d((v2i64)tmp_orig, 1); - SD(src_d, (src_dup - 8)); - } - - src7 = LD_UB(src_dup + 16 * (col + 1) + 7); - src8 = LD_UB(src_dup + 16 * (col + 1) - 8); - ST_UB(tmp, (src_dup + (16 * col))); - } - - src_dup += pitch; - } - } -} - -void vpx_mbpost_proc_down_msa(uint8_t *dst_ptr, int32_t pitch, int32_t rows, - int32_t cols, int32_t flimit) { - int32_t row, col, cnt, i; - v4i32 flimit_vec; - v16u8 dst7, dst8, dst_r_b, dst_l_b; - v16i8 mask; - v8u16 add_r, add_l; - v8i16 dst_r_h, dst_l_h, sub_r, sub_l, mask0, mask1; - v4i32 sub0, sub1, sub2, sub3, total0, total1, total2, total3; - - flimit_vec = __msa_fill_w(flimit); - - for (col = 0; col < (cols >> 4); ++col) { - uint8_t *dst_tmp = &dst_ptr[col << 4]; - v16u8 dst; - v16i8 zero = { 0 }; - v16u8 tmp[16]; - v8i16 mult0, mult1, rv2_0, rv2_1; - v8i16 sum0_h = { 0 }; - v8i16 sum1_h = { 0 }; - v4i32 mul0 = { 0 }; - v4i32 mul1 = { 0 }; - v4i32 mul2 = { 0 }; - v4i32 mul3 = { 0 }; - v4i32 sum0_w, sum1_w, sum2_w, sum3_w; - v4i32 add0, add1, add2, add3; - const int16_t *rv2[16]; - - dst = LD_UB(dst_tmp); - for (cnt = (col << 4), i = 0; i < 16; ++cnt) { - rv2[i] = vpx_rv + (i & 7); - ++i; - } - for (cnt = -8; cnt < 0; ++cnt) { - ST_UB(dst, dst_tmp + cnt * pitch); - } - - dst = LD_UB((dst_tmp + (rows - 1) * pitch)); - for (cnt = rows; cnt < rows + 17; ++cnt) { - ST_UB(dst, dst_tmp + cnt * pitch); - } - for (cnt = -8; cnt <= 6; ++cnt) { - dst = LD_UB(dst_tmp + (cnt * pitch)); - UNPCK_UB_SH(dst, dst_r_h, dst_l_h); - MUL2(dst_r_h, dst_r_h, dst_l_h, dst_l_h, mult0, mult1); - mul0 += (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)mult0); - mul1 += (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)mult0); - mul2 += (v4i32)__msa_ilvr_h((v8i16)zero, (v8i16)mult1); - mul3 += (v4i32)__msa_ilvl_h((v8i16)zero, (v8i16)mult1); - ADD2(sum0_h, dst_r_h, sum1_h, dst_l_h, sum0_h, sum1_h); - } - - for (row = 0; row < (rows + 8); ++row) { - for (i = 0; i < 8; ++i) { - rv2_0[i] = *(rv2[i] + (row & 127)); - rv2_1[i] = *(rv2[i + 8] + (row & 127)); - } - dst7 = LD_UB(dst_tmp + (7 * pitch)); - dst8 = LD_UB(dst_tmp - (8 * pitch)); - ILVRL_B2_UB(dst7, dst8, dst_r_b, dst_l_b); - - HSUB_UB2_SH(dst_r_b, dst_l_b, sub_r, sub_l); - UNPCK_SH_SW(sub_r, sub0, sub1); - UNPCK_SH_SW(sub_l, sub2, sub3); - sum0_h += sub_r; - sum1_h += sub_l; - - HADD_UB2_UH(dst_r_b, dst_l_b, add_r, add_l); - - ILVRL_H2_SW(zero, add_r, add0, add1); - ILVRL_H2_SW(zero, add_l, add2, add3); - mul0 += add0 * sub0; - mul1 += add1 * sub1; - mul2 += add2 * sub2; - mul3 += add3 * sub3; - dst = LD_UB(dst_tmp); - ILVRL_B2_SH(zero, dst, dst_r_h, dst_l_h); - dst7 = (v16u8)((rv2_0 + sum0_h + dst_r_h) >> 4); - dst8 = (v16u8)((rv2_1 + sum1_h + dst_l_h) >> 4); - tmp[row & 15] = (v16u8)__msa_pckev_b((v16i8)dst8, (v16i8)dst7); - - UNPCK_SH_SW(sum0_h, sum0_w, sum1_w); - UNPCK_SH_SW(sum1_h, sum2_w, sum3_w); - total0 = mul0 * __msa_ldi_w(15); - total0 -= sum0_w * sum0_w; - total1 = mul1 * __msa_ldi_w(15); - total1 -= sum1_w * sum1_w; - total2 = mul2 * __msa_ldi_w(15); - total2 -= sum2_w * sum2_w; - total3 = mul3 * __msa_ldi_w(15); - total3 -= sum3_w * sum3_w; - total0 = (total0 < flimit_vec); - total1 = (total1 < flimit_vec); - total2 = (total2 < flimit_vec); - total3 = (total3 < flimit_vec); - PCKEV_H2_SH(total1, total0, total3, total2, mask0, mask1); - mask = __msa_pckev_b((v16i8)mask1, (v16i8)mask0); - tmp[row & 15] = __msa_bmz_v(tmp[row & 15], dst, (v16u8)mask); - - if (row >= 8) { - ST_UB(tmp[(row - 8) & 15], (dst_tmp - 8 * pitch)); - } - - dst_tmp += pitch; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/fwd_dct32x32_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/fwd_dct32x32_msa.c deleted file mode 100644 index 36583e2d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/fwd_dct32x32_msa.c +++ /dev/null @@ -1,948 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/fwd_txfm_msa.h" - -static void fdct8x32_1d_column_load_butterfly(const int16_t *input, - int32_t src_stride, - int16_t *temp_buff) { - v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - v8i16 step0, step1, step2, step3; - v8i16 in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1; - v8i16 step0_1, step1_1, step2_1, step3_1; - - /* 1st and 2nd set */ - LD_SH4(input, src_stride, in0, in1, in2, in3); - LD_SH4(input + (28 * src_stride), src_stride, in4, in5, in6, in7); - LD_SH4(input + (4 * src_stride), src_stride, in0_1, in1_1, in2_1, in3_1); - LD_SH4(input + (24 * src_stride), src_stride, in4_1, in5_1, in6_1, in7_1); - SLLI_4V(in0, in1, in2, in3, 2); - SLLI_4V(in4, in5, in6, in7, 2); - SLLI_4V(in0_1, in1_1, in2_1, in3_1, 2); - SLLI_4V(in4_1, in5_1, in6_1, in7_1, 2); - BUTTERFLY_8(in0, in1, in2, in3, in4, in5, in6, in7, step0, step1, step2, - step3, in4, in5, in6, in7); - BUTTERFLY_8(in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1, step0_1, - step1_1, step2_1, step3_1, in4_1, in5_1, in6_1, in7_1); - ST_SH4(step0, step1, step2, step3, temp_buff, 8); - ST_SH4(in4, in5, in6, in7, temp_buff + (28 * 8), 8); - ST_SH4(step0_1, step1_1, step2_1, step3_1, temp_buff + (4 * 8), 8); - ST_SH4(in4_1, in5_1, in6_1, in7_1, temp_buff + (24 * 8), 8); - - /* 3rd and 4th set */ - LD_SH4(input + (8 * src_stride), src_stride, in0, in1, in2, in3); - LD_SH4(input + (20 * src_stride), src_stride, in4, in5, in6, in7); - LD_SH4(input + (12 * src_stride), src_stride, in0_1, in1_1, in2_1, in3_1); - LD_SH4(input + (16 * src_stride), src_stride, in4_1, in5_1, in6_1, in7_1); - SLLI_4V(in0, in1, in2, in3, 2); - SLLI_4V(in4, in5, in6, in7, 2); - SLLI_4V(in0_1, in1_1, in2_1, in3_1, 2); - SLLI_4V(in4_1, in5_1, in6_1, in7_1, 2); - BUTTERFLY_8(in0, in1, in2, in3, in4, in5, in6, in7, step0, step1, step2, - step3, in4, in5, in6, in7); - BUTTERFLY_8(in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1, step0_1, - step1_1, step2_1, step3_1, in4_1, in5_1, in6_1, in7_1); - ST_SH4(step0, step1, step2, step3, temp_buff + (8 * 8), 8); - ST_SH4(in4, in5, in6, in7, temp_buff + (20 * 8), 8); - ST_SH4(step0_1, step1_1, step2_1, step3_1, temp_buff + (12 * 8), 8); - ST_SH4(in4_1, in5_1, in6_1, in7_1, temp_buff + (15 * 8) + 8, 8); -} - -static void fdct8x32_1d_column_even_store(int16_t *input, int16_t *temp) { - v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - v8i16 in8, in9, in10, in11, in12, in13, in14, in15; - v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8i16 temp0, temp1; - - /* fdct even */ - LD_SH4(input, 8, in0, in1, in2, in3); - LD_SH4(input + 96, 8, in12, in13, in14, in15); - BUTTERFLY_8(in0, in1, in2, in3, in12, in13, in14, in15, vec0, vec1, vec2, - vec3, in12, in13, in14, in15); - LD_SH4(input + 32, 8, in4, in5, in6, in7); - LD_SH4(input + 64, 8, in8, in9, in10, in11); - BUTTERFLY_8(in4, in5, in6, in7, in8, in9, in10, in11, vec4, vec5, vec6, vec7, - in8, in9, in10, in11); - - /* Stage 3 */ - ADD4(vec0, vec7, vec1, vec6, vec2, vec5, vec3, vec4, in0, in1, in2, in3); - BUTTERFLY_4(in0, in1, in2, in3, temp0, in4, in1, in0); - DOTP_CONST_PAIR(temp0, in4, cospi_16_64, cospi_16_64, temp1, temp0); - FDCT32_POSTPROC_2V_POS_H(temp0, temp1); - ST_SH(temp0, temp); - ST_SH(temp1, temp + 512); - - DOTP_CONST_PAIR(in0, in1, cospi_24_64, cospi_8_64, temp1, temp0); - FDCT32_POSTPROC_2V_POS_H(temp0, temp1); - ST_SH(temp0, temp + 256); - ST_SH(temp1, temp + 768); - - SUB4(vec0, vec7, vec1, vec6, vec2, vec5, vec3, vec4, vec7, vec6, vec5, vec4); - DOTP_CONST_PAIR(vec6, vec5, cospi_16_64, cospi_16_64, vec5, vec6); - ADD2(vec4, vec5, vec7, vec6, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_28_64, cospi_4_64, temp1, temp0); - FDCT32_POSTPROC_2V_POS_H(temp0, temp1); - ST_SH(temp0, temp + 128); - ST_SH(temp1, temp + 896); - - SUB2(vec4, vec5, vec7, vec6, vec4, vec7); - DOTP_CONST_PAIR(vec7, vec4, cospi_12_64, cospi_20_64, temp1, temp0); - FDCT32_POSTPROC_2V_POS_H(temp0, temp1); - ST_SH(temp0, temp + 640); - ST_SH(temp1, temp + 384); - - DOTP_CONST_PAIR(in13, in10, cospi_16_64, cospi_16_64, vec2, vec5); - DOTP_CONST_PAIR(in12, in11, cospi_16_64, cospi_16_64, vec3, vec4); - ADD4(in8, vec3, in9, vec2, in14, vec5, in15, vec4, in0, vec1, vec6, in2); - DOTP_CONST_PAIR(vec6, vec1, cospi_24_64, cospi_8_64, in1, in3); - ADD2(in0, in1, in2, in3, vec0, vec7); - DOTP_CONST_PAIR(vec7, vec0, cospi_30_64, cospi_2_64, temp1, temp0); - FDCT32_POSTPROC_2V_POS_H(temp0, temp1); - ST_SH(temp0, temp + 64); - ST_SH(temp1, temp + 960); - - SUB2(in0, in1, in2, in3, in0, in2); - DOTP_CONST_PAIR(in2, in0, cospi_14_64, cospi_18_64, temp1, temp0); - FDCT32_POSTPROC_2V_POS_H(temp0, temp1); - ST_SH(temp0, temp + 576); - ST_SH(temp1, temp + 448); - - SUB2(in9, vec2, in14, vec5, vec2, vec5); - DOTP_CONST_PAIR((-vec2), vec5, cospi_24_64, cospi_8_64, in2, in1); - SUB4(in8, vec3, in15, vec4, in3, in2, in0, in1, in3, in0, vec2, vec5); - DOTP_CONST_PAIR(vec5, vec2, cospi_22_64, cospi_10_64, temp1, temp0); - FDCT32_POSTPROC_2V_POS_H(temp0, temp1); - ST_SH(temp0, temp + 320); - ST_SH(temp1, temp + 704); - - ADD2(in3, in2, in0, in1, vec3, vec4); - DOTP_CONST_PAIR(vec4, vec3, cospi_6_64, cospi_26_64, temp0, temp1); - FDCT32_POSTPROC_2V_POS_H(temp0, temp1); - ST_SH(temp0, temp + 192); - ST_SH(temp1, temp + 832); -} - -static void fdct8x32_1d_column_odd_store(int16_t *input, int16_t *temp_ptr) { - v8i16 in16, in17, in18, in19, in20, in21, in22, in23; - v8i16 in24, in25, in26, in27, in28, in29, in30, in31, vec4, vec5; - - in20 = LD_SH(input + 32); - in21 = LD_SH(input + 40); - in26 = LD_SH(input + 80); - in27 = LD_SH(input + 88); - - DOTP_CONST_PAIR(in27, in20, cospi_16_64, cospi_16_64, in20, in27); - DOTP_CONST_PAIR(in26, in21, cospi_16_64, cospi_16_64, in21, in26); - - in18 = LD_SH(input + 16); - in19 = LD_SH(input + 24); - in28 = LD_SH(input + 96); - in29 = LD_SH(input + 104); - - vec4 = in19 - in20; - ST_SH(vec4, input + 32); - vec4 = in18 - in21; - ST_SH(vec4, input + 40); - vec4 = in29 - in26; - ST_SH(vec4, input + 80); - vec4 = in28 - in27; - ST_SH(vec4, input + 88); - - in21 = in18 + in21; - in20 = in19 + in20; - in27 = in28 + in27; - in26 = in29 + in26; - - LD_SH4(input + 48, 8, in22, in23, in24, in25); - DOTP_CONST_PAIR(in25, in22, cospi_16_64, cospi_16_64, in22, in25); - DOTP_CONST_PAIR(in24, in23, cospi_16_64, cospi_16_64, in23, in24); - - in16 = LD_SH(input); - in17 = LD_SH(input + 8); - in30 = LD_SH(input + 112); - in31 = LD_SH(input + 120); - - vec4 = in17 - in22; - ST_SH(vec4, input + 16); - vec4 = in16 - in23; - ST_SH(vec4, input + 24); - vec4 = in31 - in24; - ST_SH(vec4, input + 96); - vec4 = in30 - in25; - ST_SH(vec4, input + 104); - - ADD4(in16, in23, in17, in22, in30, in25, in31, in24, in16, in17, in30, in31); - DOTP_CONST_PAIR(in26, in21, cospi_24_64, cospi_8_64, in18, in29); - DOTP_CONST_PAIR(in27, in20, cospi_24_64, cospi_8_64, in19, in28); - ADD4(in16, in19, in17, in18, in30, in29, in31, in28, in27, in22, in21, in25); - DOTP_CONST_PAIR(in21, in22, cospi_28_64, cospi_4_64, in26, in24); - ADD2(in27, in26, in25, in24, in23, in20); - DOTP_CONST_PAIR(in20, in23, cospi_31_64, cospi_1_64, vec4, vec5); - FDCT32_POSTPROC_2V_POS_H(vec5, vec4); - ST_SH(vec5, temp_ptr); - ST_SH(vec4, temp_ptr + 960); - - SUB2(in27, in26, in25, in24, in22, in21); - DOTP_CONST_PAIR(in21, in22, cospi_15_64, cospi_17_64, vec5, vec4); - FDCT32_POSTPROC_2V_POS_H(vec5, vec4); - ST_SH(vec5, temp_ptr + 448); - ST_SH(vec4, temp_ptr + 512); - - SUB4(in17, in18, in16, in19, in31, in28, in30, in29, in23, in26, in24, in20); - DOTP_CONST_PAIR((-in23), in20, cospi_28_64, cospi_4_64, in27, in25); - SUB2(in26, in27, in24, in25, in23, in20); - DOTP_CONST_PAIR(in20, in23, cospi_23_64, cospi_9_64, vec4, vec5); - FDCT32_POSTPROC_2V_POS_H(vec5, vec4); - ST_SH(vec4, temp_ptr + 704); - ST_SH(vec5, temp_ptr + 256); - - ADD2(in26, in27, in24, in25, in22, in21); - DOTP_CONST_PAIR(in21, in22, cospi_7_64, cospi_25_64, vec4, vec5); - FDCT32_POSTPROC_2V_POS_H(vec5, vec4); - ST_SH(vec4, temp_ptr + 192); - ST_SH(vec5, temp_ptr + 768); - - LD_SH4(input + 16, 8, in22, in23, in20, in21); - LD_SH4(input + 80, 8, in26, in27, in24, in25); - in16 = in20; - in17 = in21; - DOTP_CONST_PAIR(-in16, in27, cospi_24_64, cospi_8_64, in20, in27); - DOTP_CONST_PAIR(-in17, in26, cospi_24_64, cospi_8_64, in21, in26); - SUB4(in23, in20, in22, in21, in25, in26, in24, in27, in28, in17, in18, in31); - DOTP_CONST_PAIR(in18, in17, cospi_12_64, cospi_20_64, in29, in30); - ADD2(in28, in29, in31, in30, in16, in19); - DOTP_CONST_PAIR(in19, in16, cospi_27_64, cospi_5_64, vec5, vec4); - FDCT32_POSTPROC_2V_POS_H(vec5, vec4); - ST_SH(vec5, temp_ptr + 832); - ST_SH(vec4, temp_ptr + 128); - - SUB2(in28, in29, in31, in30, in17, in18); - DOTP_CONST_PAIR(in18, in17, cospi_11_64, cospi_21_64, vec5, vec4); - FDCT32_POSTPROC_2V_POS_H(vec5, vec4); - ST_SH(vec5, temp_ptr + 320); - ST_SH(vec4, temp_ptr + 640); - ADD4(in22, in21, in23, in20, in24, in27, in25, in26, in16, in29, in30, in19); - DOTP_CONST_PAIR(-in16, in19, cospi_12_64, cospi_20_64, in28, in31); - SUB2(in29, in28, in30, in31, in16, in19); - DOTP_CONST_PAIR(in19, in16, cospi_19_64, cospi_13_64, vec5, vec4); - FDCT32_POSTPROC_2V_POS_H(vec5, vec4); - ST_SH(vec5, temp_ptr + 576); - ST_SH(vec4, temp_ptr + 384); - - ADD2(in29, in28, in30, in31, in17, in18); - DOTP_CONST_PAIR(in18, in17, cospi_3_64, cospi_29_64, vec5, vec4); - FDCT32_POSTPROC_2V_POS_H(vec5, vec4); - ST_SH(vec5, temp_ptr + 64); - ST_SH(vec4, temp_ptr + 896); -} - -static void fdct8x32_1d_column(const int16_t *input, int32_t src_stride, - int16_t *tmp_buf, int16_t *tmp_buf_big) { - fdct8x32_1d_column_load_butterfly(input, src_stride, tmp_buf); - fdct8x32_1d_column_even_store(tmp_buf, tmp_buf_big); - fdct8x32_1d_column_odd_store(tmp_buf + 128, (tmp_buf_big + 32)); -} - -static void fdct8x32_1d_row_load_butterfly(int16_t *temp_buff, - int16_t *output) { - v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - v8i16 in8, in9, in10, in11, in12, in13, in14, in15; - v8i16 step0, step1, step2, step3, step4, step5, step6, step7; - - LD_SH8(temp_buff, 32, in0, in1, in2, in3, in4, in5, in6, in7); - LD_SH8(temp_buff + 24, 32, in8, in9, in10, in11, in12, in13, in14, in15); - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - TRANSPOSE8x8_SH_SH(in8, in9, in10, in11, in12, in13, in14, in15, in8, in9, - in10, in11, in12, in13, in14, in15); - BUTTERFLY_16(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, in11, - in12, in13, in14, in15, step0, step1, step2, step3, step4, step5, - step6, step7, in8, in9, in10, in11, in12, in13, in14, in15); - ST_SH8(step0, step1, step2, step3, step4, step5, step6, step7, output, 8); - ST_SH8(in8, in9, in10, in11, in12, in13, in14, in15, (output + 24 * 8), 8); - - /* 2nd set */ - LD_SH8(temp_buff + 8, 32, in0, in1, in2, in3, in4, in5, in6, in7); - LD_SH8(temp_buff + 16, 32, in8, in9, in10, in11, in12, in13, in14, in15); - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - TRANSPOSE8x8_SH_SH(in8, in9, in10, in11, in12, in13, in14, in15, in8, in9, - in10, in11, in12, in13, in14, in15); - BUTTERFLY_16(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, in11, - in12, in13, in14, in15, step0, step1, step2, step3, step4, step5, - step6, step7, in8, in9, in10, in11, in12, in13, in14, in15); - ST_SH8(step0, step1, step2, step3, step4, step5, step6, step7, - (output + 8 * 8), 8); - ST_SH8(in8, in9, in10, in11, in12, in13, in14, in15, (output + 16 * 8), 8); -} - -static void fdct8x32_1d_row_even_4x(int16_t *input, int16_t *interm_ptr, - int16_t *out) { - v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - v8i16 in8, in9, in10, in11, in12, in13, in14, in15; - v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v4i32 vec0_l, vec1_l, vec2_l, vec3_l, vec4_l, vec5_l, vec6_l, vec7_l; - v4i32 vec0_r, vec1_r, vec2_r, vec3_r, vec4_r, vec5_r, vec6_r, vec7_r; - v4i32 tmp0_w, tmp1_w, tmp2_w, tmp3_w; - - /* fdct32 even */ - /* stage 2 */ - LD_SH8(input, 8, in0, in1, in2, in3, in4, in5, in6, in7); - LD_SH8(input + 64, 8, in8, in9, in10, in11, in12, in13, in14, in15); - - BUTTERFLY_16(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, in11, - in12, in13, in14, in15, vec0, vec1, vec2, vec3, vec4, vec5, vec6, - vec7, in8, in9, in10, in11, in12, in13, in14, in15); - ST_SH8(vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, interm_ptr, 8); - ST_SH8(in8, in9, in10, in11, in12, in13, in14, in15, interm_ptr + 64, 8); - - /* Stage 3 */ - UNPCK_SH_SW(vec0, vec0_l, vec0_r); - UNPCK_SH_SW(vec1, vec1_l, vec1_r); - UNPCK_SH_SW(vec2, vec2_l, vec2_r); - UNPCK_SH_SW(vec3, vec3_l, vec3_r); - UNPCK_SH_SW(vec4, vec4_l, vec4_r); - UNPCK_SH_SW(vec5, vec5_l, vec5_r); - UNPCK_SH_SW(vec6, vec6_l, vec6_r); - UNPCK_SH_SW(vec7, vec7_l, vec7_r); - ADD4(vec0_r, vec7_r, vec1_r, vec6_r, vec2_r, vec5_r, vec3_r, vec4_r, tmp0_w, - tmp1_w, tmp2_w, tmp3_w); - BUTTERFLY_4(tmp0_w, tmp1_w, tmp2_w, tmp3_w, vec4_r, vec6_r, vec7_r, vec5_r); - ADD4(vec0_l, vec7_l, vec1_l, vec6_l, vec2_l, vec5_l, vec3_l, vec4_l, vec0_r, - vec1_r, vec2_r, vec3_r); - - tmp3_w = vec0_r + vec3_r; - vec0_r = vec0_r - vec3_r; - vec3_r = vec1_r + vec2_r; - vec1_r = vec1_r - vec2_r; - - DOTP_CONST_PAIR_W(vec4_r, vec6_r, tmp3_w, vec3_r, cospi_16_64, cospi_16_64, - vec4_r, tmp3_w, vec6_r, vec3_r); - FDCT32_POSTPROC_NEG_W(vec4_r); - FDCT32_POSTPROC_NEG_W(tmp3_w); - FDCT32_POSTPROC_NEG_W(vec6_r); - FDCT32_POSTPROC_NEG_W(vec3_r); - PCKEV_H2_SH(vec4_r, tmp3_w, vec6_r, vec3_r, vec4, vec5); - ST_SH2(vec5, vec4, out, 8); - - DOTP_CONST_PAIR_W(vec5_r, vec7_r, vec0_r, vec1_r, cospi_24_64, cospi_8_64, - vec4_r, tmp3_w, vec6_r, vec3_r); - FDCT32_POSTPROC_NEG_W(vec4_r); - FDCT32_POSTPROC_NEG_W(tmp3_w); - FDCT32_POSTPROC_NEG_W(vec6_r); - FDCT32_POSTPROC_NEG_W(vec3_r); - PCKEV_H2_SH(vec4_r, tmp3_w, vec6_r, vec3_r, vec4, vec5); - ST_SH2(vec5, vec4, out + 16, 8); - - LD_SH8(interm_ptr, 8, vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7); - SUB4(vec3, vec4, vec2, vec5, vec1, vec6, vec0, vec7, vec4, vec5, vec6, vec7); - DOTP_CONST_PAIR(vec6, vec5, cospi_16_64, cospi_16_64, vec5, vec6); - ADD2(vec4, vec5, vec7, vec6, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_28_64, cospi_4_64, in5, in4); - FDCT_POSTPROC_2V_NEG_H(in4, in5); - ST_SH(in4, out + 32); - ST_SH(in5, out + 56); - - SUB2(vec4, vec5, vec7, vec6, vec4, vec7); - DOTP_CONST_PAIR(vec7, vec4, cospi_12_64, cospi_20_64, in5, in4); - FDCT_POSTPROC_2V_NEG_H(in4, in5); - ST_SH(in4, out + 40); - ST_SH(in5, out + 48); - - LD_SH8(interm_ptr + 64, 8, in8, in9, in10, in11, in12, in13, in14, in15); - DOTP_CONST_PAIR(in13, in10, cospi_16_64, cospi_16_64, vec2, vec5); - DOTP_CONST_PAIR(in12, in11, cospi_16_64, cospi_16_64, vec3, vec4); - ADD4(in8, vec3, in9, vec2, in14, vec5, in15, vec4, in0, vec1, vec6, in2); - DOTP_CONST_PAIR(vec6, vec1, cospi_24_64, cospi_8_64, in1, in3); - ADD2(in0, in1, in2, in3, vec0, vec7); - DOTP_CONST_PAIR(vec7, vec0, cospi_30_64, cospi_2_64, in5, in4); - FDCT_POSTPROC_2V_NEG_H(in4, in5); - ST_SH(in4, out + 64); - ST_SH(in5, out + 120); - - SUB2(in0, in1, in2, in3, in0, in2); - DOTP_CONST_PAIR(in2, in0, cospi_14_64, cospi_18_64, in5, in4); - FDCT_POSTPROC_2V_NEG_H(in4, in5); - ST_SH(in4, out + 72); - ST_SH(in5, out + 112); - - SUB2(in9, vec2, in14, vec5, vec2, vec5); - DOTP_CONST_PAIR((-vec2), vec5, cospi_24_64, cospi_8_64, in2, in1); - SUB4(in8, vec3, in15, vec4, in3, in2, in0, in1, in3, in0, vec2, vec5); - DOTP_CONST_PAIR(vec5, vec2, cospi_22_64, cospi_10_64, in5, in4); - FDCT_POSTPROC_2V_NEG_H(in4, in5); - ST_SH(in4, out + 80); - ST_SH(in5, out + 104); - - ADD2(in3, in2, in0, in1, vec3, vec4); - DOTP_CONST_PAIR(vec4, vec3, cospi_6_64, cospi_26_64, in4, in5); - FDCT_POSTPROC_2V_NEG_H(in4, in5); - ST_SH(in4, out + 96); - ST_SH(in5, out + 88); -} - -static void fdct8x32_1d_row_even(int16_t *temp, int16_t *out) { - v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - v8i16 in8, in9, in10, in11, in12, in13, in14, in15; - v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, temp0, temp1; - - /* fdct32 even */ - /* stage 2 */ - LD_SH8(temp, 8, in0, in1, in2, in3, in4, in5, in6, in7); - LD_SH8(temp + 64, 8, in8, in9, in10, in11, in12, in13, in14, in15); - - BUTTERFLY_16(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, in11, - in12, in13, in14, in15, vec0, vec1, vec2, vec3, vec4, vec5, vec6, - vec7, in8, in9, in10, in11, in12, in13, in14, in15); - - /* Stage 3 */ - ADD4(vec0, vec7, vec1, vec6, vec2, vec5, vec3, vec4, in0, in1, in2, in3); - BUTTERFLY_4(in0, in1, in2, in3, temp0, in4, in1, in0); - DOTP_CONST_PAIR(temp0, in4, cospi_16_64, cospi_16_64, temp1, temp0); - FDCT_POSTPROC_2V_NEG_H(temp0, temp1); - ST_SH(temp0, out); - ST_SH(temp1, out + 8); - - DOTP_CONST_PAIR(in0, in1, cospi_24_64, cospi_8_64, temp1, temp0); - FDCT_POSTPROC_2V_NEG_H(temp0, temp1); - ST_SH(temp0, out + 16); - ST_SH(temp1, out + 24); - - SUB4(vec3, vec4, vec2, vec5, vec1, vec6, vec0, vec7, vec4, vec5, vec6, vec7); - DOTP_CONST_PAIR(vec6, vec5, cospi_16_64, cospi_16_64, vec5, vec6); - ADD2(vec4, vec5, vec7, vec6, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_28_64, cospi_4_64, temp1, temp0); - FDCT_POSTPROC_2V_NEG_H(temp0, temp1); - ST_SH(temp0, out + 32); - ST_SH(temp1, out + 56); - - SUB2(vec4, vec5, vec7, vec6, vec4, vec7); - DOTP_CONST_PAIR(vec7, vec4, cospi_12_64, cospi_20_64, temp1, temp0); - FDCT_POSTPROC_2V_NEG_H(temp0, temp1); - ST_SH(temp0, out + 40); - ST_SH(temp1, out + 48); - - DOTP_CONST_PAIR(in13, in10, cospi_16_64, cospi_16_64, vec2, vec5); - DOTP_CONST_PAIR(in12, in11, cospi_16_64, cospi_16_64, vec3, vec4); - ADD4(in8, vec3, in9, vec2, in14, vec5, in15, vec4, in0, vec1, vec6, in2); - DOTP_CONST_PAIR(vec6, vec1, cospi_24_64, cospi_8_64, in1, in3); - ADD2(in0, in1, in2, in3, vec0, vec7); - DOTP_CONST_PAIR(vec7, vec0, cospi_30_64, cospi_2_64, temp1, temp0); - FDCT_POSTPROC_2V_NEG_H(temp0, temp1); - ST_SH(temp0, out + 64); - ST_SH(temp1, out + 120); - - SUB2(in0, in1, in2, in3, in0, in2); - DOTP_CONST_PAIR(in2, in0, cospi_14_64, cospi_18_64, temp1, temp0); - FDCT_POSTPROC_2V_NEG_H(temp0, temp1); - ST_SH(temp0, out + 72); - ST_SH(temp1, out + 112); - - SUB2(in9, vec2, in14, vec5, vec2, vec5); - DOTP_CONST_PAIR((-vec2), vec5, cospi_24_64, cospi_8_64, in2, in1); - SUB4(in8, vec3, in15, vec4, in3, in2, in0, in1, in3, in0, vec2, vec5) - DOTP_CONST_PAIR(vec5, vec2, cospi_22_64, cospi_10_64, temp1, temp0); - FDCT_POSTPROC_2V_NEG_H(temp0, temp1); - ST_SH(temp0, out + 80); - ST_SH(temp1, out + 104); - - ADD2(in3, in2, in0, in1, vec3, vec4); - DOTP_CONST_PAIR(vec4, vec3, cospi_6_64, cospi_26_64, temp0, temp1); - FDCT_POSTPROC_2V_NEG_H(temp0, temp1); - ST_SH(temp0, out + 96); - ST_SH(temp1, out + 88); -} - -static void fdct8x32_1d_row_odd(int16_t *temp, int16_t *interm_ptr, - int16_t *out) { - v8i16 in16, in17, in18, in19, in20, in21, in22, in23; - v8i16 in24, in25, in26, in27, in28, in29, in30, in31, vec4, vec5; - - in20 = LD_SH(temp + 32); - in21 = LD_SH(temp + 40); - in26 = LD_SH(temp + 80); - in27 = LD_SH(temp + 88); - - DOTP_CONST_PAIR(in27, in20, cospi_16_64, cospi_16_64, in20, in27); - DOTP_CONST_PAIR(in26, in21, cospi_16_64, cospi_16_64, in21, in26); - - in18 = LD_SH(temp + 16); - in19 = LD_SH(temp + 24); - in28 = LD_SH(temp + 96); - in29 = LD_SH(temp + 104); - - vec4 = in19 - in20; - ST_SH(vec4, interm_ptr + 32); - vec4 = in18 - in21; - ST_SH(vec4, interm_ptr + 88); - vec4 = in28 - in27; - ST_SH(vec4, interm_ptr + 56); - vec4 = in29 - in26; - ST_SH(vec4, interm_ptr + 64); - - ADD4(in18, in21, in19, in20, in28, in27, in29, in26, in21, in20, in27, in26); - - in22 = LD_SH(temp + 48); - in23 = LD_SH(temp + 56); - in24 = LD_SH(temp + 64); - in25 = LD_SH(temp + 72); - - DOTP_CONST_PAIR(in25, in22, cospi_16_64, cospi_16_64, in22, in25); - DOTP_CONST_PAIR(in24, in23, cospi_16_64, cospi_16_64, in23, in24); - - in16 = LD_SH(temp); - in17 = LD_SH(temp + 8); - in30 = LD_SH(temp + 112); - in31 = LD_SH(temp + 120); - - vec4 = in17 - in22; - ST_SH(vec4, interm_ptr + 40); - vec4 = in30 - in25; - ST_SH(vec4, interm_ptr + 48); - vec4 = in31 - in24; - ST_SH(vec4, interm_ptr + 72); - vec4 = in16 - in23; - ST_SH(vec4, interm_ptr + 80); - - ADD4(in16, in23, in17, in22, in30, in25, in31, in24, in16, in17, in30, in31); - DOTP_CONST_PAIR(in26, in21, cospi_24_64, cospi_8_64, in18, in29); - DOTP_CONST_PAIR(in27, in20, cospi_24_64, cospi_8_64, in19, in28); - - ADD4(in16, in19, in17, in18, in30, in29, in31, in28, in27, in22, in21, in25); - DOTP_CONST_PAIR(in21, in22, cospi_28_64, cospi_4_64, in26, in24); - ADD2(in27, in26, in25, in24, in23, in20); - - DOTP_CONST_PAIR(in20, in23, cospi_31_64, cospi_1_64, vec4, vec5); - FDCT_POSTPROC_2V_NEG_H(vec5, vec4); - ST_SH(vec5, out); - ST_SH(vec4, out + 120); - - SUB2(in27, in26, in25, in24, in22, in21); - - DOTP_CONST_PAIR(in21, in22, cospi_15_64, cospi_17_64, vec5, vec4); - FDCT_POSTPROC_2V_NEG_H(vec5, vec4); - ST_SH(vec5, out + 112); - ST_SH(vec4, out + 8); - - SUB4(in17, in18, in16, in19, in31, in28, in30, in29, in23, in26, in24, in20); - DOTP_CONST_PAIR((-in23), in20, cospi_28_64, cospi_4_64, in27, in25); - SUB2(in26, in27, in24, in25, in23, in20); - - DOTP_CONST_PAIR(in20, in23, cospi_23_64, cospi_9_64, vec4, vec5); - FDCT_POSTPROC_2V_NEG_H(vec5, vec4); - ST_SH(vec4, out + 16); - ST_SH(vec5, out + 104); - - ADD2(in26, in27, in24, in25, in22, in21); - DOTP_CONST_PAIR(in21, in22, cospi_7_64, cospi_25_64, vec4, vec5); - FDCT_POSTPROC_2V_NEG_H(vec5, vec4); - ST_SH(vec4, out + 24); - ST_SH(vec5, out + 96); - - in20 = LD_SH(interm_ptr + 32); - in21 = LD_SH(interm_ptr + 88); - in27 = LD_SH(interm_ptr + 56); - in26 = LD_SH(interm_ptr + 64); - - in16 = in20; - in17 = in21; - DOTP_CONST_PAIR(-in16, in27, cospi_24_64, cospi_8_64, in20, in27); - DOTP_CONST_PAIR(-in17, in26, cospi_24_64, cospi_8_64, in21, in26); - - in22 = LD_SH(interm_ptr + 40); - in25 = LD_SH(interm_ptr + 48); - in24 = LD_SH(interm_ptr + 72); - in23 = LD_SH(interm_ptr + 80); - - SUB4(in23, in20, in22, in21, in25, in26, in24, in27, in28, in17, in18, in31); - DOTP_CONST_PAIR(in18, in17, cospi_12_64, cospi_20_64, in29, in30); - ADD2(in28, in29, in31, in30, in16, in19); - DOTP_CONST_PAIR(in19, in16, cospi_27_64, cospi_5_64, vec5, vec4); - FDCT_POSTPROC_2V_NEG_H(vec5, vec4); - ST_SH(vec5, out + 32); - ST_SH(vec4, out + 88); - - SUB2(in28, in29, in31, in30, in17, in18); - DOTP_CONST_PAIR(in18, in17, cospi_11_64, cospi_21_64, vec5, vec4); - FDCT_POSTPROC_2V_NEG_H(vec5, vec4); - ST_SH(vec5, out + 40); - ST_SH(vec4, out + 80); - - ADD4(in22, in21, in23, in20, in24, in27, in25, in26, in16, in29, in30, in19); - DOTP_CONST_PAIR(-in16, in19, cospi_12_64, cospi_20_64, in28, in31); - SUB2(in29, in28, in30, in31, in16, in19); - - DOTP_CONST_PAIR(in19, in16, cospi_19_64, cospi_13_64, vec5, vec4); - FDCT_POSTPROC_2V_NEG_H(vec5, vec4); - ST_SH(vec5, out + 72); - ST_SH(vec4, out + 48); - - ADD2(in29, in28, in30, in31, in17, in18); - - DOTP_CONST_PAIR(in18, in17, cospi_3_64, cospi_29_64, vec5, vec4); - FDCT_POSTPROC_2V_NEG_H(vec5, vec4); - ST_SH(vec4, out + 56); - ST_SH(vec5, out + 64); -} - -static void fdct8x32_1d_row_transpose_store(int16_t *temp, int16_t *output) { - v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - v8i16 in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1; - - /* 1st set */ - in0 = LD_SH(temp); - in4 = LD_SH(temp + 32); - in2 = LD_SH(temp + 64); - in6 = LD_SH(temp + 96); - in1 = LD_SH(temp + 128); - in7 = LD_SH(temp + 152); - in3 = LD_SH(temp + 192); - in5 = LD_SH(temp + 216); - - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - - /* 2nd set */ - in0_1 = LD_SH(temp + 16); - in1_1 = LD_SH(temp + 232); - in2_1 = LD_SH(temp + 80); - in3_1 = LD_SH(temp + 168); - in4_1 = LD_SH(temp + 48); - in5_1 = LD_SH(temp + 176); - in6_1 = LD_SH(temp + 112); - in7_1 = LD_SH(temp + 240); - - ST_SH8(in0, in1, in2, in3, in4, in5, in6, in7, output, 32); - TRANSPOSE8x8_SH_SH(in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1, - in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1); - - /* 3rd set */ - in0 = LD_SH(temp + 8); - in1 = LD_SH(temp + 136); - in2 = LD_SH(temp + 72); - in3 = LD_SH(temp + 200); - in4 = LD_SH(temp + 40); - in5 = LD_SH(temp + 208); - in6 = LD_SH(temp + 104); - in7 = LD_SH(temp + 144); - - ST_SH8(in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1, output + 8, - 32); - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - ST_SH8(in0, in1, in2, in3, in4, in5, in6, in7, output + 16, 32); - - /* 4th set */ - in0_1 = LD_SH(temp + 24); - in1_1 = LD_SH(temp + 224); - in2_1 = LD_SH(temp + 88); - in3_1 = LD_SH(temp + 160); - in4_1 = LD_SH(temp + 56); - in5_1 = LD_SH(temp + 184); - in6_1 = LD_SH(temp + 120); - in7_1 = LD_SH(temp + 248); - - TRANSPOSE8x8_SH_SH(in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1, - in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1); - ST_SH8(in0_1, in1_1, in2_1, in3_1, in4_1, in5_1, in6_1, in7_1, output + 24, - 32); -} - -static void fdct32x8_1d_row(int16_t *temp, int16_t *temp_buf, int16_t *output) { - fdct8x32_1d_row_load_butterfly(temp, temp_buf); - fdct8x32_1d_row_even(temp_buf, temp_buf); - fdct8x32_1d_row_odd(temp_buf + 128, temp, temp_buf + 128); - fdct8x32_1d_row_transpose_store(temp_buf, output); -} - -static void fdct32x8_1d_row_4x(int16_t *tmp_buf_big, int16_t *tmp_buf, - int16_t *output) { - fdct8x32_1d_row_load_butterfly(tmp_buf_big, tmp_buf); - fdct8x32_1d_row_even_4x(tmp_buf, tmp_buf_big, tmp_buf); - fdct8x32_1d_row_odd(tmp_buf + 128, tmp_buf_big, tmp_buf + 128); - fdct8x32_1d_row_transpose_store(tmp_buf, output); -} - -void vpx_fdct32x32_msa(const int16_t *input, int16_t *output, - int32_t src_stride) { - int32_t i; - DECLARE_ALIGNED(32, int16_t, tmp_buf_big[1024]); - DECLARE_ALIGNED(32, int16_t, tmp_buf[256]); - - /* column transform */ - for (i = 0; i < 4; ++i) { - fdct8x32_1d_column(input + (8 * i), src_stride, tmp_buf, - tmp_buf_big + (8 * i)); - } - - /* row transform */ - fdct32x8_1d_row_4x(tmp_buf_big, tmp_buf, output); - - /* row transform */ - for (i = 1; i < 4; ++i) { - fdct32x8_1d_row(tmp_buf_big + (i * 256), tmp_buf, output + (i * 256)); - } -} - -static void fdct8x32_1d_row_even_rd(int16_t *temp, int16_t *out) { - v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - v8i16 in8, in9, in10, in11, in12, in13, in14, in15; - v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, temp0, temp1; - - /* fdct32 even */ - /* stage 2 */ - LD_SH8(temp, 8, in0, in1, in2, in3, in4, in5, in6, in7); - LD_SH8(temp + 64, 8, in8, in9, in10, in11, in12, in13, in14, in15); - - BUTTERFLY_16(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, in11, - in12, in13, in14, in15, vec0, vec1, vec2, vec3, vec4, vec5, vec6, - vec7, in8, in9, in10, in11, in12, in13, in14, in15); - FDCT_POSTPROC_2V_NEG_H(vec0, vec1); - FDCT_POSTPROC_2V_NEG_H(vec2, vec3); - FDCT_POSTPROC_2V_NEG_H(vec4, vec5); - FDCT_POSTPROC_2V_NEG_H(vec6, vec7); - FDCT_POSTPROC_2V_NEG_H(in8, in9); - FDCT_POSTPROC_2V_NEG_H(in10, in11); - FDCT_POSTPROC_2V_NEG_H(in12, in13); - FDCT_POSTPROC_2V_NEG_H(in14, in15); - - /* Stage 3 */ - ADD4(vec0, vec7, vec1, vec6, vec2, vec5, vec3, vec4, in0, in1, in2, in3); - - temp0 = in0 + in3; - in0 = in0 - in3; - in3 = in1 + in2; - in1 = in1 - in2; - - DOTP_CONST_PAIR(temp0, in3, cospi_16_64, cospi_16_64, temp1, temp0); - ST_SH(temp0, out); - ST_SH(temp1, out + 8); - - DOTP_CONST_PAIR(in0, in1, cospi_24_64, cospi_8_64, temp1, temp0); - ST_SH(temp0, out + 16); - ST_SH(temp1, out + 24); - - SUB4(vec3, vec4, vec2, vec5, vec1, vec6, vec0, vec7, vec4, vec5, vec6, vec7); - DOTP_CONST_PAIR(vec6, vec5, cospi_16_64, cospi_16_64, vec5, vec6); - ADD2(vec4, vec5, vec7, vec6, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_28_64, cospi_4_64, temp1, temp0); - ST_SH(temp0, out + 32); - ST_SH(temp1, out + 56); - - SUB2(vec4, vec5, vec7, vec6, vec4, vec7); - DOTP_CONST_PAIR(vec7, vec4, cospi_12_64, cospi_20_64, temp1, temp0); - ST_SH(temp0, out + 40); - ST_SH(temp1, out + 48); - - DOTP_CONST_PAIR(in13, in10, cospi_16_64, cospi_16_64, vec2, vec5); - DOTP_CONST_PAIR(in12, in11, cospi_16_64, cospi_16_64, vec3, vec4); - ADD4(in8, vec3, in9, vec2, in14, vec5, in15, vec4, in0, vec1, vec6, in2); - DOTP_CONST_PAIR(vec6, vec1, cospi_24_64, cospi_8_64, in1, in3); - ADD2(in0, in1, in2, in3, vec0, vec7); - DOTP_CONST_PAIR(vec7, vec0, cospi_30_64, cospi_2_64, temp1, temp0); - ST_SH(temp0, out + 64); - ST_SH(temp1, out + 120); - - SUB2(in0, in1, in2, in3, in0, in2); - DOTP_CONST_PAIR(in2, in0, cospi_14_64, cospi_18_64, temp1, temp0); - ST_SH(temp0, out + 72); - ST_SH(temp1, out + 112); - - SUB2(in9, vec2, in14, vec5, vec2, vec5); - DOTP_CONST_PAIR((-vec2), vec5, cospi_24_64, cospi_8_64, in2, in1); - SUB4(in8, vec3, in15, vec4, in3, in2, in0, in1, in3, in0, vec2, vec5); - DOTP_CONST_PAIR(vec5, vec2, cospi_22_64, cospi_10_64, temp1, temp0); - ST_SH(temp0, out + 80); - ST_SH(temp1, out + 104); - - ADD2(in3, in2, in0, in1, vec3, vec4); - DOTP_CONST_PAIR(vec4, vec3, cospi_6_64, cospi_26_64, temp0, temp1); - ST_SH(temp0, out + 96); - ST_SH(temp1, out + 88); -} - -static void fdct8x32_1d_row_odd_rd(int16_t *temp, int16_t *interm_ptr, - int16_t *out) { - v8i16 in16, in17, in18, in19, in20, in21, in22, in23; - v8i16 in24, in25, in26, in27, in28, in29, in30, in31; - v8i16 vec4, vec5; - - in20 = LD_SH(temp + 32); - in21 = LD_SH(temp + 40); - in26 = LD_SH(temp + 80); - in27 = LD_SH(temp + 88); - - DOTP_CONST_PAIR(in27, in20, cospi_16_64, cospi_16_64, in20, in27); - DOTP_CONST_PAIR(in26, in21, cospi_16_64, cospi_16_64, in21, in26); - - FDCT_POSTPROC_2V_NEG_H(in20, in21); - FDCT_POSTPROC_2V_NEG_H(in26, in27); - - in18 = LD_SH(temp + 16); - in19 = LD_SH(temp + 24); - in28 = LD_SH(temp + 96); - in29 = LD_SH(temp + 104); - - FDCT_POSTPROC_2V_NEG_H(in18, in19); - FDCT_POSTPROC_2V_NEG_H(in28, in29); - - vec4 = in19 - in20; - ST_SH(vec4, interm_ptr + 32); - vec4 = in18 - in21; - ST_SH(vec4, interm_ptr + 88); - vec4 = in29 - in26; - ST_SH(vec4, interm_ptr + 64); - vec4 = in28 - in27; - ST_SH(vec4, interm_ptr + 56); - - ADD4(in18, in21, in19, in20, in28, in27, in29, in26, in21, in20, in27, in26); - - in22 = LD_SH(temp + 48); - in23 = LD_SH(temp + 56); - in24 = LD_SH(temp + 64); - in25 = LD_SH(temp + 72); - - DOTP_CONST_PAIR(in25, in22, cospi_16_64, cospi_16_64, in22, in25); - DOTP_CONST_PAIR(in24, in23, cospi_16_64, cospi_16_64, in23, in24); - FDCT_POSTPROC_2V_NEG_H(in22, in23); - FDCT_POSTPROC_2V_NEG_H(in24, in25); - - in16 = LD_SH(temp); - in17 = LD_SH(temp + 8); - in30 = LD_SH(temp + 112); - in31 = LD_SH(temp + 120); - - FDCT_POSTPROC_2V_NEG_H(in16, in17); - FDCT_POSTPROC_2V_NEG_H(in30, in31); - - vec4 = in17 - in22; - ST_SH(vec4, interm_ptr + 40); - vec4 = in30 - in25; - ST_SH(vec4, interm_ptr + 48); - vec4 = in31 - in24; - ST_SH(vec4, interm_ptr + 72); - vec4 = in16 - in23; - ST_SH(vec4, interm_ptr + 80); - - ADD4(in16, in23, in17, in22, in30, in25, in31, in24, in16, in17, in30, in31); - DOTP_CONST_PAIR(in26, in21, cospi_24_64, cospi_8_64, in18, in29); - DOTP_CONST_PAIR(in27, in20, cospi_24_64, cospi_8_64, in19, in28); - ADD4(in16, in19, in17, in18, in30, in29, in31, in28, in27, in22, in21, in25); - DOTP_CONST_PAIR(in21, in22, cospi_28_64, cospi_4_64, in26, in24); - ADD2(in27, in26, in25, in24, in23, in20); - DOTP_CONST_PAIR(in20, in23, cospi_31_64, cospi_1_64, vec4, vec5); - ST_SH(vec5, out); - ST_SH(vec4, out + 120); - - SUB2(in27, in26, in25, in24, in22, in21); - DOTP_CONST_PAIR(in21, in22, cospi_15_64, cospi_17_64, vec5, vec4); - ST_SH(vec5, out + 112); - ST_SH(vec4, out + 8); - - SUB4(in17, in18, in16, in19, in31, in28, in30, in29, in23, in26, in24, in20); - DOTP_CONST_PAIR((-in23), in20, cospi_28_64, cospi_4_64, in27, in25); - SUB2(in26, in27, in24, in25, in23, in20); - DOTP_CONST_PAIR(in20, in23, cospi_23_64, cospi_9_64, vec4, vec5); - ST_SH(vec4, out + 16); - ST_SH(vec5, out + 104); - - ADD2(in26, in27, in24, in25, in22, in21); - DOTP_CONST_PAIR(in21, in22, cospi_7_64, cospi_25_64, vec4, vec5); - ST_SH(vec4, out + 24); - ST_SH(vec5, out + 96); - - in20 = LD_SH(interm_ptr + 32); - in21 = LD_SH(interm_ptr + 88); - in27 = LD_SH(interm_ptr + 56); - in26 = LD_SH(interm_ptr + 64); - - in16 = in20; - in17 = in21; - DOTP_CONST_PAIR(-in16, in27, cospi_24_64, cospi_8_64, in20, in27); - DOTP_CONST_PAIR(-in17, in26, cospi_24_64, cospi_8_64, in21, in26); - - in22 = LD_SH(interm_ptr + 40); - in25 = LD_SH(interm_ptr + 48); - in24 = LD_SH(interm_ptr + 72); - in23 = LD_SH(interm_ptr + 80); - - SUB4(in23, in20, in22, in21, in25, in26, in24, in27, in28, in17, in18, in31); - DOTP_CONST_PAIR(in18, in17, cospi_12_64, cospi_20_64, in29, in30); - in16 = in28 + in29; - in19 = in31 + in30; - DOTP_CONST_PAIR(in19, in16, cospi_27_64, cospi_5_64, vec5, vec4); - ST_SH(vec5, out + 32); - ST_SH(vec4, out + 88); - - SUB2(in28, in29, in31, in30, in17, in18); - DOTP_CONST_PAIR(in18, in17, cospi_11_64, cospi_21_64, vec5, vec4); - ST_SH(vec5, out + 40); - ST_SH(vec4, out + 80); - - ADD4(in22, in21, in23, in20, in24, in27, in25, in26, in16, in29, in30, in19); - DOTP_CONST_PAIR(-in16, in19, cospi_12_64, cospi_20_64, in28, in31); - SUB2(in29, in28, in30, in31, in16, in19); - DOTP_CONST_PAIR(in19, in16, cospi_19_64, cospi_13_64, vec5, vec4); - ST_SH(vec5, out + 72); - ST_SH(vec4, out + 48); - - ADD2(in29, in28, in30, in31, in17, in18); - DOTP_CONST_PAIR(in18, in17, cospi_3_64, cospi_29_64, vec5, vec4); - ST_SH(vec4, out + 56); - ST_SH(vec5, out + 64); -} - -static void fdct32x8_1d_row_rd(int16_t *tmp_buf_big, int16_t *tmp_buf, - int16_t *output) { - fdct8x32_1d_row_load_butterfly(tmp_buf_big, tmp_buf); - fdct8x32_1d_row_even_rd(tmp_buf, tmp_buf); - fdct8x32_1d_row_odd_rd((tmp_buf + 128), tmp_buf_big, (tmp_buf + 128)); - fdct8x32_1d_row_transpose_store(tmp_buf, output); -} - -void vpx_fdct32x32_rd_msa(const int16_t *input, int16_t *out, - int32_t src_stride) { - int32_t i; - DECLARE_ALIGNED(32, int16_t, tmp_buf_big[1024]); - DECLARE_ALIGNED(32, int16_t, tmp_buf[256]); - - /* column transform */ - for (i = 0; i < 4; ++i) { - fdct8x32_1d_column(input + (8 * i), src_stride, &tmp_buf[0], - &tmp_buf_big[0] + (8 * i)); - } - - /* row transform */ - for (i = 0; i < 4; ++i) { - fdct32x8_1d_row_rd(&tmp_buf_big[0] + (8 * i * 32), &tmp_buf[0], - out + (8 * i * 32)); - } -} - -void vpx_fdct32x32_1_msa(const int16_t *input, int16_t *out, int32_t stride) { - int sum, i; - v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - v4i32 vec_w = { 0 }; - - for (i = 0; i < 16; ++i) { - LD_SH4(input, 8, in0, in1, in2, in3); - input += stride; - LD_SH4(input, 8, in4, in5, in6, in7); - input += stride; - ADD4(in0, in1, in2, in3, in4, in5, in6, in7, in0, in2, in4, in6); - ADD2(in0, in2, in4, in6, in0, in4); - vec_w += __msa_hadd_s_w(in0, in0); - vec_w += __msa_hadd_s_w(in4, in4); - } - - sum = HADD_SW_S32(vec_w); - out[0] = (int16_t)(sum >> 3); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/fwd_txfm_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/fwd_txfm_msa.c deleted file mode 100644 index 5a6dfcef..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/fwd_txfm_msa.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/fwd_txfm_msa.h" - -void vpx_fdct8x8_1_msa(const int16_t *input, tran_low_t *out, int32_t stride) { - v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - v4i32 vec_w; - - LD_SH8(input, stride, in0, in1, in2, in3, in4, in5, in6, in7); - ADD4(in0, in1, in2, in3, in4, in5, in6, in7, in0, in2, in4, in6); - ADD2(in0, in2, in4, in6, in0, in4); - vec_w = __msa_hadd_s_w(in0, in0); - vec_w += __msa_hadd_s_w(in4, in4); - out[0] = HADD_SW_S32(vec_w); - out[1] = 0; -} - -#if !CONFIG_VP9_HIGHBITDEPTH -void fdct8x16_1d_column(const int16_t *input, int16_t *tmp_ptr, - int32_t src_stride) { - v8i16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - v8i16 in8, in9, in10, in11, in12, in13, in14, in15; - v8i16 stp21, stp22, stp23, stp24, stp25, stp26, stp30; - v8i16 stp31, stp32, stp33, stp34, stp35, stp36, stp37; - v8i16 vec0, vec1, vec2, vec3, vec4, vec5, cnst0, cnst1, cnst4, cnst5; - v8i16 coeff = { cospi_16_64, -cospi_16_64, cospi_8_64, cospi_24_64, - -cospi_8_64, -cospi_24_64, cospi_12_64, cospi_20_64 }; - v8i16 coeff1 = { cospi_2_64, cospi_30_64, cospi_14_64, cospi_18_64, - cospi_10_64, cospi_22_64, cospi_6_64, cospi_26_64 }; - v8i16 coeff2 = { - -cospi_2_64, -cospi_10_64, -cospi_18_64, -cospi_26_64, 0, 0, 0, 0 - }; - - LD_SH16(input, src_stride, in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, - in10, in11, in12, in13, in14, in15); - SLLI_4V(in0, in1, in2, in3, 2); - SLLI_4V(in4, in5, in6, in7, 2); - SLLI_4V(in8, in9, in10, in11, 2); - SLLI_4V(in12, in13, in14, in15, 2); - ADD4(in0, in15, in1, in14, in2, in13, in3, in12, tmp0, tmp1, tmp2, tmp3); - ADD4(in4, in11, in5, in10, in6, in9, in7, in8, tmp4, tmp5, tmp6, tmp7); - FDCT8x16_EVEN(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp0, tmp1, - tmp2, tmp3, tmp4, tmp5, tmp6, tmp7); - ST_SH8(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp_ptr, 32); - SUB4(in0, in15, in1, in14, in2, in13, in3, in12, in15, in14, in13, in12); - SUB4(in4, in11, in5, in10, in6, in9, in7, in8, in11, in10, in9, in8); - - tmp_ptr += 16; - - /* stp 1 */ - ILVL_H2_SH(in10, in13, in11, in12, vec2, vec4); - ILVR_H2_SH(in10, in13, in11, in12, vec3, vec5); - - cnst4 = __msa_splati_h(coeff, 0); - stp25 = DOT_SHIFT_RIGHT_PCK_H(vec2, vec3, cnst4); - - cnst5 = __msa_splati_h(coeff, 1); - cnst5 = __msa_ilvev_h(cnst5, cnst4); - stp22 = DOT_SHIFT_RIGHT_PCK_H(vec2, vec3, cnst5); - stp24 = DOT_SHIFT_RIGHT_PCK_H(vec4, vec5, cnst4); - stp23 = DOT_SHIFT_RIGHT_PCK_H(vec4, vec5, cnst5); - - /* stp2 */ - BUTTERFLY_4(in8, in9, stp22, stp23, stp30, stp31, stp32, stp33); - BUTTERFLY_4(in15, in14, stp25, stp24, stp37, stp36, stp35, stp34); - ILVL_H2_SH(stp36, stp31, stp35, stp32, vec2, vec4); - ILVR_H2_SH(stp36, stp31, stp35, stp32, vec3, vec5); - SPLATI_H2_SH(coeff, 2, 3, cnst0, cnst1); - cnst0 = __msa_ilvev_h(cnst0, cnst1); - stp26 = DOT_SHIFT_RIGHT_PCK_H(vec2, vec3, cnst0); - - cnst0 = __msa_splati_h(coeff, 4); - cnst1 = __msa_ilvev_h(cnst1, cnst0); - stp21 = DOT_SHIFT_RIGHT_PCK_H(vec2, vec3, cnst1); - - BUTTERFLY_4(stp30, stp37, stp26, stp21, in8, in15, in14, in9); - ILVRL_H2_SH(in15, in8, vec1, vec0); - SPLATI_H2_SH(coeff1, 0, 1, cnst0, cnst1); - cnst0 = __msa_ilvev_h(cnst0, cnst1); - - in8 = DOT_SHIFT_RIGHT_PCK_H(vec0, vec1, cnst0); - ST_SH(in8, tmp_ptr); - - cnst0 = __msa_splati_h(coeff2, 0); - cnst0 = __msa_ilvev_h(cnst1, cnst0); - in8 = DOT_SHIFT_RIGHT_PCK_H(vec0, vec1, cnst0); - ST_SH(in8, tmp_ptr + 224); - - ILVRL_H2_SH(in14, in9, vec1, vec0); - SPLATI_H2_SH(coeff1, 2, 3, cnst0, cnst1); - cnst1 = __msa_ilvev_h(cnst1, cnst0); - - in8 = DOT_SHIFT_RIGHT_PCK_H(vec0, vec1, cnst1); - ST_SH(in8, tmp_ptr + 128); - - cnst1 = __msa_splati_h(coeff2, 2); - cnst0 = __msa_ilvev_h(cnst0, cnst1); - in8 = DOT_SHIFT_RIGHT_PCK_H(vec0, vec1, cnst0); - ST_SH(in8, tmp_ptr + 96); - - SPLATI_H2_SH(coeff, 2, 5, cnst0, cnst1); - cnst1 = __msa_ilvev_h(cnst1, cnst0); - - stp25 = DOT_SHIFT_RIGHT_PCK_H(vec4, vec5, cnst1); - - cnst1 = __msa_splati_h(coeff, 3); - cnst1 = __msa_ilvev_h(cnst0, cnst1); - stp22 = DOT_SHIFT_RIGHT_PCK_H(vec4, vec5, cnst1); - - /* stp4 */ - ADD2(stp34, stp25, stp33, stp22, in13, in10); - - ILVRL_H2_SH(in13, in10, vec1, vec0); - SPLATI_H2_SH(coeff1, 4, 5, cnst0, cnst1); - cnst0 = __msa_ilvev_h(cnst0, cnst1); - in8 = DOT_SHIFT_RIGHT_PCK_H(vec0, vec1, cnst0); - ST_SH(in8, tmp_ptr + 64); - - cnst0 = __msa_splati_h(coeff2, 1); - cnst0 = __msa_ilvev_h(cnst1, cnst0); - in8 = DOT_SHIFT_RIGHT_PCK_H(vec0, vec1, cnst0); - ST_SH(in8, tmp_ptr + 160); - - SUB2(stp34, stp25, stp33, stp22, in12, in11); - ILVRL_H2_SH(in12, in11, vec1, vec0); - SPLATI_H2_SH(coeff1, 6, 7, cnst0, cnst1); - cnst1 = __msa_ilvev_h(cnst1, cnst0); - - in8 = DOT_SHIFT_RIGHT_PCK_H(vec0, vec1, cnst1); - ST_SH(in8, tmp_ptr + 192); - - cnst1 = __msa_splati_h(coeff2, 3); - cnst0 = __msa_ilvev_h(cnst0, cnst1); - in8 = DOT_SHIFT_RIGHT_PCK_H(vec0, vec1, cnst0); - ST_SH(in8, tmp_ptr + 32); -} - -void fdct16x8_1d_row(int16_t *input, int16_t *output) { - v8i16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - v8i16 in8, in9, in10, in11, in12, in13, in14, in15; - - LD_SH8(input, 16, in0, in1, in2, in3, in4, in5, in6, in7); - LD_SH8((input + 8), 16, in8, in9, in10, in11, in12, in13, in14, in15); - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - TRANSPOSE8x8_SH_SH(in8, in9, in10, in11, in12, in13, in14, in15, in8, in9, - in10, in11, in12, in13, in14, in15); - ADD4(in0, 1, in1, 1, in2, 1, in3, 1, in0, in1, in2, in3); - ADD4(in4, 1, in5, 1, in6, 1, in7, 1, in4, in5, in6, in7); - ADD4(in8, 1, in9, 1, in10, 1, in11, 1, in8, in9, in10, in11); - ADD4(in12, 1, in13, 1, in14, 1, in15, 1, in12, in13, in14, in15); - SRA_4V(in0, in1, in2, in3, 2); - SRA_4V(in4, in5, in6, in7, 2); - SRA_4V(in8, in9, in10, in11, 2); - SRA_4V(in12, in13, in14, in15, 2); - BUTTERFLY_16(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, in11, - in12, in13, in14, in15, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, - tmp7, in8, in9, in10, in11, in12, in13, in14, in15); - ST_SH8(in8, in9, in10, in11, in12, in13, in14, in15, input, 16); - FDCT8x16_EVEN(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp0, tmp1, - tmp2, tmp3, tmp4, tmp5, tmp6, tmp7); - LD_SH8(input, 16, in8, in9, in10, in11, in12, in13, in14, in15); - FDCT8x16_ODD(in8, in9, in10, in11, in12, in13, in14, in15, in0, in1, in2, in3, - in4, in5, in6, in7); - TRANSPOSE8x8_SH_SH(tmp0, in0, tmp1, in1, tmp2, in2, tmp3, in3, tmp0, in0, - tmp1, in1, tmp2, in2, tmp3, in3); - ST_SH8(tmp0, in0, tmp1, in1, tmp2, in2, tmp3, in3, output, 16); - TRANSPOSE8x8_SH_SH(tmp4, in4, tmp5, in5, tmp6, in6, tmp7, in7, tmp4, in4, - tmp5, in5, tmp6, in6, tmp7, in7); - ST_SH8(tmp4, in4, tmp5, in5, tmp6, in6, tmp7, in7, output + 8, 16); -} - -void vpx_fdct4x4_msa(const int16_t *input, int16_t *output, - int32_t src_stride) { - v8i16 in0, in1, in2, in3; - - LD_SH4(input, src_stride, in0, in1, in2, in3); - - /* fdct4 pre-process */ - { - v8i16 vec, mask; - v16i8 zero = { 0 }; - v16i8 one = __msa_ldi_b(1); - - mask = (v8i16)__msa_sldi_b(zero, one, 15); - SLLI_4V(in0, in1, in2, in3, 4); - vec = __msa_ceqi_h(in0, 0); - vec = vec ^ 255; - vec = mask & vec; - in0 += vec; - } - - VP9_FDCT4(in0, in1, in2, in3, in0, in1, in2, in3); - TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); - VP9_FDCT4(in0, in1, in2, in3, in0, in1, in2, in3); - TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); - ADD4(in0, 1, in1, 1, in2, 1, in3, 1, in0, in1, in2, in3); - SRA_4V(in0, in1, in2, in3, 2); - PCKEV_D2_SH(in1, in0, in3, in2, in0, in2); - ST_SH2(in0, in2, output, 8); -} - -void vpx_fdct8x8_msa(const int16_t *input, int16_t *output, - int32_t src_stride) { - v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - - LD_SH8(input, src_stride, in0, in1, in2, in3, in4, in5, in6, in7); - SLLI_4V(in0, in1, in2, in3, 2); - SLLI_4V(in4, in5, in6, in7, 2); - VP9_FDCT8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, - in5, in6, in7); - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - VP9_FDCT8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4, - in5, in6, in7); - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - SRLI_AVE_S_4V_H(in0, in1, in2, in3, in4, in5, in6, in7); - ST_SH8(in0, in1, in2, in3, in4, in5, in6, in7, output, 8); -} - -void vpx_fdct16x16_msa(const int16_t *input, int16_t *output, - int32_t src_stride) { - int32_t i; - DECLARE_ALIGNED(32, int16_t, tmp_buf[16 * 16]); - - /* column transform */ - for (i = 0; i < 2; ++i) { - fdct8x16_1d_column((input + 8 * i), (&tmp_buf[0] + 8 * i), src_stride); - } - - /* row transform */ - for (i = 0; i < 2; ++i) { - fdct16x8_1d_row((&tmp_buf[0] + (128 * i)), (output + (128 * i))); - } -} - -void vpx_fdct16x16_1_msa(const int16_t *input, int16_t *out, int32_t stride) { - int sum, i; - v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - v4i32 vec_w = { 0 }; - - for (i = 0; i < 4; ++i) { - LD_SH2(input, 8, in0, in1); - input += stride; - LD_SH2(input, 8, in2, in3); - input += stride; - LD_SH2(input, 8, in4, in5); - input += stride; - LD_SH2(input, 8, in6, in7); - input += stride; - ADD4(in0, in1, in2, in3, in4, in5, in6, in7, in0, in2, in4, in6); - ADD2(in0, in2, in4, in6, in0, in4); - vec_w += __msa_hadd_s_w(in0, in0); - vec_w += __msa_hadd_s_w(in4, in4); - } - - sum = HADD_SW_S32(vec_w); - out[0] = (int16_t)(sum >> 1); -} -#endif // !CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/fwd_txfm_msa.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/fwd_txfm_msa.h deleted file mode 100644 index c0be56b8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/fwd_txfm_msa.h +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_MIPS_FWD_TXFM_MSA_H_ -#define VPX_VPX_DSP_MIPS_FWD_TXFM_MSA_H_ - -#include "vpx_dsp/mips/txfm_macros_msa.h" -#include "vpx_dsp/txfm_common.h" - -#define VP9_FDCT4(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - v8i16 cnst0_m, cnst1_m, cnst2_m, cnst3_m; \ - v8i16 vec0_m, vec1_m, vec2_m, vec3_m; \ - v4i32 vec4_m, vec5_m, vec6_m, vec7_m; \ - v8i16 coeff_m = { \ - cospi_16_64, -cospi_16_64, cospi_8_64, cospi_24_64, -cospi_8_64, 0, 0, 0 \ - }; \ - \ - BUTTERFLY_4(in0, in1, in2, in3, vec0_m, vec1_m, vec2_m, vec3_m); \ - ILVR_H2_SH(vec1_m, vec0_m, vec3_m, vec2_m, vec0_m, vec2_m); \ - SPLATI_H2_SH(coeff_m, 0, 1, cnst0_m, cnst1_m); \ - cnst1_m = __msa_ilvev_h(cnst1_m, cnst0_m); \ - vec5_m = __msa_dotp_s_w(vec0_m, cnst1_m); \ - \ - SPLATI_H2_SH(coeff_m, 4, 3, cnst2_m, cnst3_m); \ - cnst2_m = __msa_ilvev_h(cnst3_m, cnst2_m); \ - vec7_m = __msa_dotp_s_w(vec2_m, cnst2_m); \ - \ - vec4_m = __msa_dotp_s_w(vec0_m, cnst0_m); \ - cnst2_m = __msa_splati_h(coeff_m, 2); \ - cnst2_m = __msa_ilvev_h(cnst2_m, cnst3_m); \ - vec6_m = __msa_dotp_s_w(vec2_m, cnst2_m); \ - \ - SRARI_W4_SW(vec4_m, vec5_m, vec6_m, vec7_m, DCT_CONST_BITS); \ - PCKEV_H4_SH(vec4_m, vec4_m, vec5_m, vec5_m, vec6_m, vec6_m, vec7_m, \ - vec7_m, out0, out2, out1, out3); \ - } - -#define SRLI_AVE_S_4V_H(in0, in1, in2, in3, in4, in5, in6, in7) \ - { \ - v8i16 vec0_m, vec1_m, vec2_m, vec3_m, vec4_m, vec5_m, vec6_m, vec7_m; \ - \ - SRLI_H4_SH(in0, in1, in2, in3, vec0_m, vec1_m, vec2_m, vec3_m, 15); \ - SRLI_H4_SH(in4, in5, in6, in7, vec4_m, vec5_m, vec6_m, vec7_m, 15); \ - AVE_SH4_SH(vec0_m, in0, vec1_m, in1, vec2_m, in2, vec3_m, in3, in0, in1, \ - in2, in3); \ - AVE_SH4_SH(vec4_m, in4, vec5_m, in5, vec6_m, in6, vec7_m, in7, in4, in5, \ - in6, in7); \ - } - -#define VP9_FDCT8(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, \ - out3, out4, out5, out6, out7) \ - { \ - v8i16 s0_m, s1_m, s2_m, s3_m, s4_m, s5_m, s6_m; \ - v8i16 s7_m, x0_m, x1_m, x2_m, x3_m; \ - v8i16 coeff_m = { cospi_16_64, -cospi_16_64, cospi_8_64, cospi_24_64, \ - cospi_4_64, cospi_28_64, cospi_12_64, cospi_20_64 }; \ - \ - /* FDCT stage1 */ \ - BUTTERFLY_8(in0, in1, in2, in3, in4, in5, in6, in7, s0_m, s1_m, s2_m, \ - s3_m, s4_m, s5_m, s6_m, s7_m); \ - BUTTERFLY_4(s0_m, s1_m, s2_m, s3_m, x0_m, x1_m, x2_m, x3_m); \ - ILVL_H2_SH(x1_m, x0_m, x3_m, x2_m, s0_m, s2_m); \ - ILVR_H2_SH(x1_m, x0_m, x3_m, x2_m, s1_m, s3_m); \ - SPLATI_H2_SH(coeff_m, 0, 1, x0_m, x1_m); \ - x1_m = __msa_ilvev_h(x1_m, x0_m); \ - out4 = DOT_SHIFT_RIGHT_PCK_H(s0_m, s1_m, x1_m); \ - \ - SPLATI_H2_SH(coeff_m, 2, 3, x2_m, x3_m); \ - x2_m = -x2_m; \ - x2_m = __msa_ilvev_h(x3_m, x2_m); \ - out6 = DOT_SHIFT_RIGHT_PCK_H(s2_m, s3_m, x2_m); \ - \ - out0 = DOT_SHIFT_RIGHT_PCK_H(s0_m, s1_m, x0_m); \ - x2_m = __msa_splati_h(coeff_m, 2); \ - x2_m = __msa_ilvev_h(x2_m, x3_m); \ - out2 = DOT_SHIFT_RIGHT_PCK_H(s2_m, s3_m, x2_m); \ - \ - /* stage2 */ \ - ILVRL_H2_SH(s5_m, s6_m, s1_m, s0_m); \ - \ - s6_m = DOT_SHIFT_RIGHT_PCK_H(s0_m, s1_m, x0_m); \ - s5_m = DOT_SHIFT_RIGHT_PCK_H(s0_m, s1_m, x1_m); \ - \ - /* stage3 */ \ - BUTTERFLY_4(s4_m, s7_m, s6_m, s5_m, x0_m, x3_m, x2_m, x1_m); \ - \ - /* stage4 */ \ - ILVL_H2_SH(x3_m, x0_m, x2_m, x1_m, s4_m, s6_m); \ - ILVR_H2_SH(x3_m, x0_m, x2_m, x1_m, s5_m, s7_m); \ - \ - SPLATI_H2_SH(coeff_m, 4, 5, x0_m, x1_m); \ - x1_m = __msa_ilvev_h(x0_m, x1_m); \ - out1 = DOT_SHIFT_RIGHT_PCK_H(s4_m, s5_m, x1_m); \ - \ - SPLATI_H2_SH(coeff_m, 6, 7, x2_m, x3_m); \ - x2_m = __msa_ilvev_h(x3_m, x2_m); \ - out5 = DOT_SHIFT_RIGHT_PCK_H(s6_m, s7_m, x2_m); \ - \ - x1_m = __msa_splati_h(coeff_m, 5); \ - x0_m = -x0_m; \ - x0_m = __msa_ilvev_h(x1_m, x0_m); \ - out7 = DOT_SHIFT_RIGHT_PCK_H(s4_m, s5_m, x0_m); \ - \ - x2_m = __msa_splati_h(coeff_m, 6); \ - x3_m = -x3_m; \ - x2_m = __msa_ilvev_h(x2_m, x3_m); \ - out3 = DOT_SHIFT_RIGHT_PCK_H(s6_m, s7_m, x2_m); \ - } - -#define FDCT8x16_EVEN(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3, out4, out5, out6, out7) \ - { \ - v8i16 s0_m, s1_m, s2_m, s3_m, s4_m, s5_m, s6_m, s7_m; \ - v8i16 x0_m, x1_m, x2_m, x3_m; \ - v8i16 coeff_m = { cospi_16_64, -cospi_16_64, cospi_8_64, cospi_24_64, \ - cospi_4_64, cospi_28_64, cospi_12_64, cospi_20_64 }; \ - \ - /* FDCT stage1 */ \ - BUTTERFLY_8(in0, in1, in2, in3, in4, in5, in6, in7, s0_m, s1_m, s2_m, \ - s3_m, s4_m, s5_m, s6_m, s7_m); \ - BUTTERFLY_4(s0_m, s1_m, s2_m, s3_m, x0_m, x1_m, x2_m, x3_m); \ - ILVL_H2_SH(x1_m, x0_m, x3_m, x2_m, s0_m, s2_m); \ - ILVR_H2_SH(x1_m, x0_m, x3_m, x2_m, s1_m, s3_m); \ - SPLATI_H2_SH(coeff_m, 0, 1, x0_m, x1_m); \ - x1_m = __msa_ilvev_h(x1_m, x0_m); \ - out4 = DOT_SHIFT_RIGHT_PCK_H(s0_m, s1_m, x1_m); \ - \ - SPLATI_H2_SH(coeff_m, 2, 3, x2_m, x3_m); \ - x2_m = -x2_m; \ - x2_m = __msa_ilvev_h(x3_m, x2_m); \ - out6 = DOT_SHIFT_RIGHT_PCK_H(s2_m, s3_m, x2_m); \ - \ - out0 = DOT_SHIFT_RIGHT_PCK_H(s0_m, s1_m, x0_m); \ - x2_m = __msa_splati_h(coeff_m, 2); \ - x2_m = __msa_ilvev_h(x2_m, x3_m); \ - out2 = DOT_SHIFT_RIGHT_PCK_H(s2_m, s3_m, x2_m); \ - \ - /* stage2 */ \ - ILVRL_H2_SH(s5_m, s6_m, s1_m, s0_m); \ - \ - s6_m = DOT_SHIFT_RIGHT_PCK_H(s0_m, s1_m, x0_m); \ - s5_m = DOT_SHIFT_RIGHT_PCK_H(s0_m, s1_m, x1_m); \ - \ - /* stage3 */ \ - BUTTERFLY_4(s4_m, s7_m, s6_m, s5_m, x0_m, x3_m, x2_m, x1_m); \ - \ - /* stage4 */ \ - ILVL_H2_SH(x3_m, x0_m, x2_m, x1_m, s4_m, s6_m); \ - ILVR_H2_SH(x3_m, x0_m, x2_m, x1_m, s5_m, s7_m); \ - \ - SPLATI_H2_SH(coeff_m, 4, 5, x0_m, x1_m); \ - x1_m = __msa_ilvev_h(x0_m, x1_m); \ - out1 = DOT_SHIFT_RIGHT_PCK_H(s4_m, s5_m, x1_m); \ - \ - SPLATI_H2_SH(coeff_m, 6, 7, x2_m, x3_m); \ - x2_m = __msa_ilvev_h(x3_m, x2_m); \ - out5 = DOT_SHIFT_RIGHT_PCK_H(s6_m, s7_m, x2_m); \ - \ - x1_m = __msa_splati_h(coeff_m, 5); \ - x0_m = -x0_m; \ - x0_m = __msa_ilvev_h(x1_m, x0_m); \ - out7 = DOT_SHIFT_RIGHT_PCK_H(s4_m, s5_m, x0_m); \ - \ - x2_m = __msa_splati_h(coeff_m, 6); \ - x3_m = -x3_m; \ - x2_m = __msa_ilvev_h(x2_m, x3_m); \ - out3 = DOT_SHIFT_RIGHT_PCK_H(s6_m, s7_m, x2_m); \ - } - -#define FDCT8x16_ODD(input0, input1, input2, input3, input4, input5, input6, \ - input7, out1, out3, out5, out7, out9, out11, out13, \ - out15) \ - { \ - v8i16 stp21_m, stp22_m, stp23_m, stp24_m, stp25_m, stp26_m; \ - v8i16 stp30_m, stp31_m, stp32_m, stp33_m, stp34_m, stp35_m; \ - v8i16 stp36_m, stp37_m, vec0_m, vec1_m; \ - v8i16 vec2_m, vec3_m, vec4_m, vec5_m, vec6_m; \ - v8i16 cnst0_m, cnst1_m, cnst4_m, cnst5_m; \ - v8i16 coeff_m = { cospi_16_64, -cospi_16_64, cospi_8_64, cospi_24_64, \ - -cospi_8_64, -cospi_24_64, cospi_12_64, cospi_20_64 }; \ - v8i16 coeff1_m = { cospi_2_64, cospi_30_64, cospi_14_64, cospi_18_64, \ - cospi_10_64, cospi_22_64, cospi_6_64, cospi_26_64 }; \ - v8i16 coeff2_m = { \ - -cospi_2_64, -cospi_10_64, -cospi_18_64, -cospi_26_64, 0, 0, 0, 0 \ - }; \ - \ - /* stp 1 */ \ - ILVL_H2_SH(input2, input5, input3, input4, vec2_m, vec4_m); \ - ILVR_H2_SH(input2, input5, input3, input4, vec3_m, vec5_m); \ - \ - cnst4_m = __msa_splati_h(coeff_m, 0); \ - stp25_m = DOT_SHIFT_RIGHT_PCK_H(vec2_m, vec3_m, cnst4_m); \ - \ - cnst5_m = __msa_splati_h(coeff_m, 1); \ - cnst5_m = __msa_ilvev_h(cnst5_m, cnst4_m); \ - stp22_m = DOT_SHIFT_RIGHT_PCK_H(vec2_m, vec3_m, cnst5_m); \ - stp24_m = DOT_SHIFT_RIGHT_PCK_H(vec4_m, vec5_m, cnst4_m); \ - stp23_m = DOT_SHIFT_RIGHT_PCK_H(vec4_m, vec5_m, cnst5_m); \ - \ - /* stp2 */ \ - BUTTERFLY_4(input0, input1, stp22_m, stp23_m, stp30_m, stp31_m, stp32_m, \ - stp33_m); \ - BUTTERFLY_4(input7, input6, stp25_m, stp24_m, stp37_m, stp36_m, stp35_m, \ - stp34_m); \ - \ - ILVL_H2_SH(stp36_m, stp31_m, stp35_m, stp32_m, vec2_m, vec4_m); \ - ILVR_H2_SH(stp36_m, stp31_m, stp35_m, stp32_m, vec3_m, vec5_m); \ - \ - SPLATI_H2_SH(coeff_m, 2, 3, cnst0_m, cnst1_m); \ - cnst0_m = __msa_ilvev_h(cnst0_m, cnst1_m); \ - stp26_m = DOT_SHIFT_RIGHT_PCK_H(vec2_m, vec3_m, cnst0_m); \ - \ - cnst0_m = __msa_splati_h(coeff_m, 4); \ - cnst1_m = __msa_ilvev_h(cnst1_m, cnst0_m); \ - stp21_m = DOT_SHIFT_RIGHT_PCK_H(vec2_m, vec3_m, cnst1_m); \ - \ - SPLATI_H2_SH(coeff_m, 5, 2, cnst0_m, cnst1_m); \ - cnst1_m = __msa_ilvev_h(cnst0_m, cnst1_m); \ - stp25_m = DOT_SHIFT_RIGHT_PCK_H(vec4_m, vec5_m, cnst1_m); \ - \ - cnst0_m = __msa_splati_h(coeff_m, 3); \ - cnst1_m = __msa_ilvev_h(cnst1_m, cnst0_m); \ - stp22_m = DOT_SHIFT_RIGHT_PCK_H(vec4_m, vec5_m, cnst1_m); \ - \ - /* stp4 */ \ - BUTTERFLY_4(stp30_m, stp37_m, stp26_m, stp21_m, vec6_m, vec2_m, vec4_m, \ - vec5_m); \ - BUTTERFLY_4(stp33_m, stp34_m, stp25_m, stp22_m, stp21_m, stp23_m, stp24_m, \ - stp31_m); \ - \ - ILVRL_H2_SH(vec2_m, vec6_m, vec1_m, vec0_m); \ - SPLATI_H2_SH(coeff1_m, 0, 1, cnst0_m, cnst1_m); \ - cnst0_m = __msa_ilvev_h(cnst0_m, cnst1_m); \ - \ - out1 = DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst0_m); \ - \ - cnst0_m = __msa_splati_h(coeff2_m, 0); \ - cnst0_m = __msa_ilvev_h(cnst1_m, cnst0_m); \ - out15 = DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst0_m); \ - \ - ILVRL_H2_SH(vec4_m, vec5_m, vec1_m, vec0_m); \ - SPLATI_H2_SH(coeff1_m, 2, 3, cnst0_m, cnst1_m); \ - cnst1_m = __msa_ilvev_h(cnst1_m, cnst0_m); \ - \ - out9 = DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst1_m); \ - \ - cnst1_m = __msa_splati_h(coeff2_m, 2); \ - cnst0_m = __msa_ilvev_h(cnst0_m, cnst1_m); \ - out7 = DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst0_m); \ - \ - ILVRL_H2_SH(stp23_m, stp21_m, vec1_m, vec0_m); \ - SPLATI_H2_SH(coeff1_m, 4, 5, cnst0_m, cnst1_m); \ - cnst0_m = __msa_ilvev_h(cnst0_m, cnst1_m); \ - out5 = DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst0_m); \ - \ - cnst0_m = __msa_splati_h(coeff2_m, 1); \ - cnst0_m = __msa_ilvev_h(cnst1_m, cnst0_m); \ - out11 = DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst0_m); \ - \ - ILVRL_H2_SH(stp24_m, stp31_m, vec1_m, vec0_m); \ - SPLATI_H2_SH(coeff1_m, 6, 7, cnst0_m, cnst1_m); \ - cnst1_m = __msa_ilvev_h(cnst1_m, cnst0_m); \ - \ - out13 = DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst1_m); \ - \ - cnst1_m = __msa_splati_h(coeff2_m, 3); \ - cnst0_m = __msa_ilvev_h(cnst0_m, cnst1_m); \ - out3 = DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst0_m); \ - } - -#define FDCT_POSTPROC_2V_NEG_H(vec0, vec1) \ - { \ - v8i16 tp0_m, tp1_m; \ - v8i16 one_m = __msa_ldi_h(1); \ - \ - tp0_m = __msa_clti_s_h(vec0, 0); \ - tp1_m = __msa_clti_s_h(vec1, 0); \ - vec0 += 1; \ - vec1 += 1; \ - tp0_m = one_m & tp0_m; \ - tp1_m = one_m & tp1_m; \ - vec0 += tp0_m; \ - vec1 += tp1_m; \ - vec0 >>= 2; \ - vec1 >>= 2; \ - } - -#define FDCT32_POSTPROC_NEG_W(vec) \ - { \ - v4i32 temp_m; \ - v4i32 one_m = __msa_ldi_w(1); \ - \ - temp_m = __msa_clti_s_w(vec, 0); \ - vec += 1; \ - temp_m = one_m & temp_m; \ - vec += temp_m; \ - vec >>= 2; \ - } - -#define FDCT32_POSTPROC_2V_POS_H(vec0, vec1) \ - { \ - v8i16 tp0_m, tp1_m; \ - v8i16 one = __msa_ldi_h(1); \ - \ - tp0_m = __msa_clei_s_h(vec0, 0); \ - tp1_m = __msa_clei_s_h(vec1, 0); \ - tp0_m = (v8i16)__msa_xori_b((v16u8)tp0_m, 255); \ - tp1_m = (v8i16)__msa_xori_b((v16u8)tp1_m, 255); \ - vec0 += 1; \ - vec1 += 1; \ - tp0_m = one & tp0_m; \ - tp1_m = one & tp1_m; \ - vec0 += tp0_m; \ - vec1 += tp1_m; \ - vec0 >>= 2; \ - vec1 >>= 2; \ - } - -#define DOTP_CONST_PAIR_W(reg0_left, reg1_left, reg0_right, reg1_right, \ - const0, const1, out0, out1, out2, out3) \ - { \ - v4i32 s0_m, s1_m, s2_m, s3_m, s4_m, s5_m, s6_m, s7_m; \ - v2i64 tp0_m, tp1_m, tp2_m, tp3_m; \ - v4i32 k0_m = __msa_fill_w((int32_t)const0); \ - \ - s0_m = __msa_fill_w((int32_t)const1); \ - k0_m = __msa_ilvev_w(s0_m, k0_m); \ - \ - ILVRL_W2_SW(-reg1_left, reg0_left, s1_m, s0_m); \ - ILVRL_W2_SW(reg0_left, reg1_left, s3_m, s2_m); \ - ILVRL_W2_SW(-reg1_right, reg0_right, s5_m, s4_m); \ - ILVRL_W2_SW(reg0_right, reg1_right, s7_m, s6_m); \ - \ - DOTP_SW2_SD(s0_m, s1_m, k0_m, k0_m, tp0_m, tp1_m); \ - DOTP_SW2_SD(s4_m, s5_m, k0_m, k0_m, tp2_m, tp3_m); \ - tp0_m = __msa_srari_d(tp0_m, DCT_CONST_BITS); \ - tp1_m = __msa_srari_d(tp1_m, DCT_CONST_BITS); \ - tp2_m = __msa_srari_d(tp2_m, DCT_CONST_BITS); \ - tp3_m = __msa_srari_d(tp3_m, DCT_CONST_BITS); \ - out0 = __msa_pckev_w((v4i32)tp0_m, (v4i32)tp1_m); \ - out1 = __msa_pckev_w((v4i32)tp2_m, (v4i32)tp3_m); \ - \ - DOTP_SW2_SD(s2_m, s3_m, k0_m, k0_m, tp0_m, tp1_m); \ - DOTP_SW2_SD(s6_m, s7_m, k0_m, k0_m, tp2_m, tp3_m); \ - tp0_m = __msa_srari_d(tp0_m, DCT_CONST_BITS); \ - tp1_m = __msa_srari_d(tp1_m, DCT_CONST_BITS); \ - tp2_m = __msa_srari_d(tp2_m, DCT_CONST_BITS); \ - tp3_m = __msa_srari_d(tp3_m, DCT_CONST_BITS); \ - out2 = __msa_pckev_w((v4i32)tp0_m, (v4i32)tp1_m); \ - out3 = __msa_pckev_w((v4i32)tp2_m, (v4i32)tp3_m); \ - } - -void fdct8x16_1d_column(const int16_t *input, int16_t *tmp_ptr, - int32_t src_stride); -void fdct16x8_1d_row(int16_t *input, int16_t *output); -#endif // VPX_VPX_DSP_MIPS_FWD_TXFM_MSA_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/idct16x16_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/idct16x16_msa.c deleted file mode 100644 index 7ca61a28..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/idct16x16_msa.c +++ /dev/null @@ -1,486 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/inv_txfm_msa.h" - -void vpx_idct16_1d_rows_msa(const int16_t *input, int16_t *output) { - v8i16 loc0, loc1, loc2, loc3; - v8i16 reg0, reg2, reg4, reg6, reg8, reg10, reg12, reg14; - v8i16 reg3, reg13, reg11, reg5, reg7, reg9, reg1, reg15; - v8i16 tmp5, tmp6, tmp7; - - LD_SH8(input, 16, reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7); - input += 8; - LD_SH8(input, 16, reg8, reg9, reg10, reg11, reg12, reg13, reg14, reg15); - - TRANSPOSE8x8_SH_SH(reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg0, reg1, - reg2, reg3, reg4, reg5, reg6, reg7); - TRANSPOSE8x8_SH_SH(reg8, reg9, reg10, reg11, reg12, reg13, reg14, reg15, reg8, - reg9, reg10, reg11, reg12, reg13, reg14, reg15); - DOTP_CONST_PAIR(reg2, reg14, cospi_28_64, cospi_4_64, reg2, reg14); - DOTP_CONST_PAIR(reg10, reg6, cospi_12_64, cospi_20_64, reg10, reg6); - BUTTERFLY_4(reg2, reg14, reg6, reg10, loc0, loc1, reg14, reg2); - DOTP_CONST_PAIR(reg14, reg2, cospi_16_64, cospi_16_64, loc2, loc3); - DOTP_CONST_PAIR(reg0, reg8, cospi_16_64, cospi_16_64, reg0, reg8); - DOTP_CONST_PAIR(reg4, reg12, cospi_24_64, cospi_8_64, reg4, reg12); - BUTTERFLY_4(reg8, reg0, reg4, reg12, reg2, reg6, reg10, reg14); - SUB4(reg2, loc1, reg14, loc0, reg6, loc3, reg10, loc2, reg0, reg12, reg4, - reg8); - ADD4(reg2, loc1, reg14, loc0, reg6, loc3, reg10, loc2, reg2, reg14, reg6, - reg10); - - /* stage 2 */ - DOTP_CONST_PAIR(reg1, reg15, cospi_30_64, cospi_2_64, reg1, reg15); - DOTP_CONST_PAIR(reg9, reg7, cospi_14_64, cospi_18_64, loc2, loc3); - - reg9 = reg1 - loc2; - reg1 = reg1 + loc2; - reg7 = reg15 - loc3; - reg15 = reg15 + loc3; - - DOTP_CONST_PAIR(reg5, reg11, cospi_22_64, cospi_10_64, reg5, reg11); - DOTP_CONST_PAIR(reg13, reg3, cospi_6_64, cospi_26_64, loc0, loc1); - BUTTERFLY_4(loc0, loc1, reg11, reg5, reg13, reg3, reg11, reg5); - - loc1 = reg15 + reg3; - reg3 = reg15 - reg3; - loc2 = reg2 + loc1; - reg15 = reg2 - loc1; - - loc1 = reg1 + reg13; - reg13 = reg1 - reg13; - loc0 = reg0 + loc1; - loc1 = reg0 - loc1; - tmp6 = loc0; - tmp7 = loc1; - reg0 = loc2; - - DOTP_CONST_PAIR(reg7, reg9, cospi_24_64, cospi_8_64, reg7, reg9); - DOTP_CONST_PAIR((-reg5), (-reg11), cospi_8_64, cospi_24_64, reg5, reg11); - - loc0 = reg9 + reg5; - reg5 = reg9 - reg5; - reg2 = reg6 + loc0; - reg1 = reg6 - loc0; - - loc0 = reg7 + reg11; - reg11 = reg7 - reg11; - loc1 = reg4 + loc0; - loc2 = reg4 - loc0; - tmp5 = loc1; - - DOTP_CONST_PAIR(reg5, reg11, cospi_16_64, cospi_16_64, reg5, reg11); - BUTTERFLY_4(reg8, reg10, reg11, reg5, loc0, reg4, reg9, loc1); - - reg10 = loc0; - reg11 = loc1; - - DOTP_CONST_PAIR(reg3, reg13, cospi_16_64, cospi_16_64, reg3, reg13); - BUTTERFLY_4(reg12, reg14, reg13, reg3, reg8, reg6, reg7, reg5); - - reg13 = loc2; - - /* Transpose and store the output */ - reg12 = tmp5; - reg14 = tmp6; - reg3 = tmp7; - - /* transpose block */ - TRANSPOSE8x8_SH_SH(reg0, reg2, reg4, reg6, reg8, reg10, reg12, reg14, reg0, - reg2, reg4, reg6, reg8, reg10, reg12, reg14); - ST_SH8(reg0, reg2, reg4, reg6, reg8, reg10, reg12, reg14, output, 16); - - /* transpose block */ - TRANSPOSE8x8_SH_SH(reg3, reg13, reg11, reg5, reg7, reg9, reg1, reg15, reg3, - reg13, reg11, reg5, reg7, reg9, reg1, reg15); - ST_SH8(reg3, reg13, reg11, reg5, reg7, reg9, reg1, reg15, (output + 8), 16); -} - -void vpx_idct16_1d_columns_addblk_msa(int16_t *input, uint8_t *dst, - int32_t dst_stride) { - v8i16 loc0, loc1, loc2, loc3; - v8i16 reg0, reg2, reg4, reg6, reg8, reg10, reg12, reg14; - v8i16 reg3, reg13, reg11, reg5, reg7, reg9, reg1, reg15; - v8i16 tmp5, tmp6, tmp7; - - /* load up 8x8 */ - LD_SH8(input, 16, reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7); - input += 8 * 16; - /* load bottom 8x8 */ - LD_SH8(input, 16, reg8, reg9, reg10, reg11, reg12, reg13, reg14, reg15); - - DOTP_CONST_PAIR(reg2, reg14, cospi_28_64, cospi_4_64, reg2, reg14); - DOTP_CONST_PAIR(reg10, reg6, cospi_12_64, cospi_20_64, reg10, reg6); - BUTTERFLY_4(reg2, reg14, reg6, reg10, loc0, loc1, reg14, reg2); - DOTP_CONST_PAIR(reg14, reg2, cospi_16_64, cospi_16_64, loc2, loc3); - DOTP_CONST_PAIR(reg0, reg8, cospi_16_64, cospi_16_64, reg0, reg8); - DOTP_CONST_PAIR(reg4, reg12, cospi_24_64, cospi_8_64, reg4, reg12); - BUTTERFLY_4(reg8, reg0, reg4, reg12, reg2, reg6, reg10, reg14); - - reg0 = reg2 - loc1; - reg2 = reg2 + loc1; - reg12 = reg14 - loc0; - reg14 = reg14 + loc0; - reg4 = reg6 - loc3; - reg6 = reg6 + loc3; - reg8 = reg10 - loc2; - reg10 = reg10 + loc2; - - /* stage 2 */ - DOTP_CONST_PAIR(reg1, reg15, cospi_30_64, cospi_2_64, reg1, reg15); - DOTP_CONST_PAIR(reg9, reg7, cospi_14_64, cospi_18_64, loc2, loc3); - - reg9 = reg1 - loc2; - reg1 = reg1 + loc2; - reg7 = reg15 - loc3; - reg15 = reg15 + loc3; - - DOTP_CONST_PAIR(reg5, reg11, cospi_22_64, cospi_10_64, reg5, reg11); - DOTP_CONST_PAIR(reg13, reg3, cospi_6_64, cospi_26_64, loc0, loc1); - BUTTERFLY_4(loc0, loc1, reg11, reg5, reg13, reg3, reg11, reg5); - - loc1 = reg15 + reg3; - reg3 = reg15 - reg3; - loc2 = reg2 + loc1; - reg15 = reg2 - loc1; - - loc1 = reg1 + reg13; - reg13 = reg1 - reg13; - loc0 = reg0 + loc1; - loc1 = reg0 - loc1; - tmp6 = loc0; - tmp7 = loc1; - reg0 = loc2; - - DOTP_CONST_PAIR(reg7, reg9, cospi_24_64, cospi_8_64, reg7, reg9); - DOTP_CONST_PAIR((-reg5), (-reg11), cospi_8_64, cospi_24_64, reg5, reg11); - - loc0 = reg9 + reg5; - reg5 = reg9 - reg5; - reg2 = reg6 + loc0; - reg1 = reg6 - loc0; - - loc0 = reg7 + reg11; - reg11 = reg7 - reg11; - loc1 = reg4 + loc0; - loc2 = reg4 - loc0; - tmp5 = loc1; - - DOTP_CONST_PAIR(reg5, reg11, cospi_16_64, cospi_16_64, reg5, reg11); - BUTTERFLY_4(reg8, reg10, reg11, reg5, loc0, reg4, reg9, loc1); - - reg10 = loc0; - reg11 = loc1; - - DOTP_CONST_PAIR(reg3, reg13, cospi_16_64, cospi_16_64, reg3, reg13); - BUTTERFLY_4(reg12, reg14, reg13, reg3, reg8, reg6, reg7, reg5); - reg13 = loc2; - - /* Transpose and store the output */ - reg12 = tmp5; - reg14 = tmp6; - reg3 = tmp7; - - SRARI_H4_SH(reg0, reg2, reg4, reg6, 6); - VP9_ADDBLK_ST8x4_UB(dst, dst_stride, reg0, reg2, reg4, reg6); - dst += (4 * dst_stride); - SRARI_H4_SH(reg8, reg10, reg12, reg14, 6); - VP9_ADDBLK_ST8x4_UB(dst, dst_stride, reg8, reg10, reg12, reg14); - dst += (4 * dst_stride); - SRARI_H4_SH(reg3, reg13, reg11, reg5, 6); - VP9_ADDBLK_ST8x4_UB(dst, dst_stride, reg3, reg13, reg11, reg5); - dst += (4 * dst_stride); - SRARI_H4_SH(reg7, reg9, reg1, reg15, 6); - VP9_ADDBLK_ST8x4_UB(dst, dst_stride, reg7, reg9, reg1, reg15); -} - -void vpx_idct16x16_256_add_msa(const int16_t *input, uint8_t *dst, - int32_t dst_stride) { - int32_t i; - DECLARE_ALIGNED(32, int16_t, out_arr[16 * 16]); - int16_t *out = out_arr; - - /* transform rows */ - for (i = 0; i < 2; ++i) { - /* process 16 * 8 block */ - vpx_idct16_1d_rows_msa((input + (i << 7)), (out + (i << 7))); - } - - /* transform columns */ - for (i = 0; i < 2; ++i) { - /* process 8 * 16 block */ - vpx_idct16_1d_columns_addblk_msa((out + (i << 3)), (dst + (i << 3)), - dst_stride); - } -} - -void vpx_idct16x16_10_add_msa(const int16_t *input, uint8_t *dst, - int32_t dst_stride) { - uint8_t i; - DECLARE_ALIGNED(32, int16_t, out_arr[16 * 16]); - int16_t *out = out_arr; - - /* process 16 * 8 block */ - vpx_idct16_1d_rows_msa(input, out); - - /* short case just considers top 4 rows as valid output */ - out += 4 * 16; - for (i = 12; i--;) { - __asm__ __volatile__( - "sw $zero, 0(%[out]) \n\t" - "sw $zero, 4(%[out]) \n\t" - "sw $zero, 8(%[out]) \n\t" - "sw $zero, 12(%[out]) \n\t" - "sw $zero, 16(%[out]) \n\t" - "sw $zero, 20(%[out]) \n\t" - "sw $zero, 24(%[out]) \n\t" - "sw $zero, 28(%[out]) \n\t" - - : - : [out] "r"(out)); - - out += 16; - } - - out = out_arr; - - /* transform columns */ - for (i = 0; i < 2; ++i) { - /* process 8 * 16 block */ - vpx_idct16_1d_columns_addblk_msa((out + (i << 3)), (dst + (i << 3)), - dst_stride); - } -} - -void vpx_idct16x16_1_add_msa(const int16_t *input, uint8_t *dst, - int32_t dst_stride) { - uint8_t i; - int16_t out; - v8i16 vec, res0, res1, res2, res3, res4, res5, res6, res7; - v16u8 dst0, dst1, dst2, dst3, tmp0, tmp1, tmp2, tmp3; - - out = ROUND_POWER_OF_TWO((input[0] * cospi_16_64), DCT_CONST_BITS); - out = ROUND_POWER_OF_TWO((out * cospi_16_64), DCT_CONST_BITS); - out = ROUND_POWER_OF_TWO(out, 6); - - vec = __msa_fill_h(out); - - for (i = 4; i--;) { - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - UNPCK_UB_SH(dst0, res0, res4); - UNPCK_UB_SH(dst1, res1, res5); - UNPCK_UB_SH(dst2, res2, res6); - UNPCK_UB_SH(dst3, res3, res7); - ADD4(res0, vec, res1, vec, res2, vec, res3, vec, res0, res1, res2, res3); - ADD4(res4, vec, res5, vec, res6, vec, res7, vec, res4, res5, res6, res7); - CLIP_SH4_0_255(res0, res1, res2, res3); - CLIP_SH4_0_255(res4, res5, res6, res7); - PCKEV_B4_UB(res4, res0, res5, res1, res6, res2, res7, res3, tmp0, tmp1, - tmp2, tmp3); - ST_UB4(tmp0, tmp1, tmp2, tmp3, dst, dst_stride); - dst += (4 * dst_stride); - } -} - -void vpx_iadst16_1d_rows_msa(const int16_t *input, int16_t *output) { - v8i16 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15; - v8i16 l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15; - - /* load input data */ - LD_SH16(input, 8, l0, l8, l1, l9, l2, l10, l3, l11, l4, l12, l5, l13, l6, l14, - l7, l15); - TRANSPOSE8x8_SH_SH(l0, l1, l2, l3, l4, l5, l6, l7, l0, l1, l2, l3, l4, l5, l6, - l7); - TRANSPOSE8x8_SH_SH(l8, l9, l10, l11, l12, l13, l14, l15, l8, l9, l10, l11, - l12, l13, l14, l15); - - /* ADST in horizontal */ - VP9_IADST8x16_1D(l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, - l14, l15, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, - r12, r13, r14, r15); - - l1 = -r8; - l3 = -r4; - l13 = -r13; - l15 = -r1; - - TRANSPOSE8x8_SH_SH(r0, l1, r12, l3, r6, r14, r10, r2, l0, l1, l2, l3, l4, l5, - l6, l7); - ST_SH8(l0, l1, l2, l3, l4, l5, l6, l7, output, 16); - TRANSPOSE8x8_SH_SH(r3, r11, r15, r7, r5, l13, r9, l15, l8, l9, l10, l11, l12, - l13, l14, l15); - ST_SH8(l8, l9, l10, l11, l12, l13, l14, l15, (output + 8), 16); -} - -void vpx_iadst16_1d_columns_addblk_msa(int16_t *input, uint8_t *dst, - int32_t dst_stride) { - v8i16 v0, v2, v4, v6, k0, k1, k2, k3; - v8i16 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15; - v8i16 out0, out1, out2, out3, out4, out5, out6, out7; - v8i16 out8, out9, out10, out11, out12, out13, out14, out15; - v8i16 g0, g1, g2, g3, g4, g5, g6, g7, g8, g9, g10, g11, g12, g13, g14, g15; - v8i16 h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11; - v8i16 res0, res1, res2, res3, res4, res5, res6, res7; - v8i16 res8, res9, res10, res11, res12, res13, res14, res15; - v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; - v16u8 dst8, dst9, dst10, dst11, dst12, dst13, dst14, dst15; - v16i8 zero = { 0 }; - - r0 = LD_SH(input + 0 * 16); - r3 = LD_SH(input + 3 * 16); - r4 = LD_SH(input + 4 * 16); - r7 = LD_SH(input + 7 * 16); - r8 = LD_SH(input + 8 * 16); - r11 = LD_SH(input + 11 * 16); - r12 = LD_SH(input + 12 * 16); - r15 = LD_SH(input + 15 * 16); - - /* stage 1 */ - k0 = VP9_SET_COSPI_PAIR(cospi_1_64, cospi_31_64); - k1 = VP9_SET_COSPI_PAIR(cospi_31_64, -cospi_1_64); - k2 = VP9_SET_COSPI_PAIR(cospi_17_64, cospi_15_64); - k3 = VP9_SET_COSPI_PAIR(cospi_15_64, -cospi_17_64); - MADD_BF(r15, r0, r7, r8, k0, k1, k2, k3, g0, g1, g2, g3); - k0 = VP9_SET_COSPI_PAIR(cospi_9_64, cospi_23_64); - k1 = VP9_SET_COSPI_PAIR(cospi_23_64, -cospi_9_64); - k2 = VP9_SET_COSPI_PAIR(cospi_25_64, cospi_7_64); - k3 = VP9_SET_COSPI_PAIR(cospi_7_64, -cospi_25_64); - MADD_BF(r11, r4, r3, r12, k0, k1, k2, k3, g8, g9, g10, g11); - BUTTERFLY_4(g0, g2, g10, g8, h8, h9, v2, v0); - k0 = VP9_SET_COSPI_PAIR(cospi_4_64, cospi_28_64); - k1 = VP9_SET_COSPI_PAIR(cospi_28_64, -cospi_4_64); - k2 = VP9_SET_COSPI_PAIR(-cospi_28_64, cospi_4_64); - MADD_BF(g1, g3, g9, g11, k0, k1, k2, k0, h0, h1, h2, h3); - - r1 = LD_SH(input + 1 * 16); - r2 = LD_SH(input + 2 * 16); - r5 = LD_SH(input + 5 * 16); - r6 = LD_SH(input + 6 * 16); - r9 = LD_SH(input + 9 * 16); - r10 = LD_SH(input + 10 * 16); - r13 = LD_SH(input + 13 * 16); - r14 = LD_SH(input + 14 * 16); - - k0 = VP9_SET_COSPI_PAIR(cospi_5_64, cospi_27_64); - k1 = VP9_SET_COSPI_PAIR(cospi_27_64, -cospi_5_64); - k2 = VP9_SET_COSPI_PAIR(cospi_21_64, cospi_11_64); - k3 = VP9_SET_COSPI_PAIR(cospi_11_64, -cospi_21_64); - MADD_BF(r13, r2, r5, r10, k0, k1, k2, k3, g4, g5, g6, g7); - k0 = VP9_SET_COSPI_PAIR(cospi_13_64, cospi_19_64); - k1 = VP9_SET_COSPI_PAIR(cospi_19_64, -cospi_13_64); - k2 = VP9_SET_COSPI_PAIR(cospi_29_64, cospi_3_64); - k3 = VP9_SET_COSPI_PAIR(cospi_3_64, -cospi_29_64); - MADD_BF(r9, r6, r1, r14, k0, k1, k2, k3, g12, g13, g14, g15); - BUTTERFLY_4(g4, g6, g14, g12, h10, h11, v6, v4); - BUTTERFLY_4(h8, h9, h11, h10, out0, out1, h11, h10); - out1 = -out1; - SRARI_H2_SH(out0, out1, 6); - dst0 = LD_UB(dst + 0 * dst_stride); - dst1 = LD_UB(dst + 15 * dst_stride); - ILVR_B2_SH(zero, dst0, zero, dst1, res0, res1); - ADD2(res0, out0, res1, out1, res0, res1); - CLIP_SH2_0_255(res0, res1); - PCKEV_B2_SH(res0, res0, res1, res1, res0, res1); - ST8x1_UB(res0, dst); - ST8x1_UB(res1, dst + 15 * dst_stride); - - k0 = VP9_SET_COSPI_PAIR(cospi_12_64, cospi_20_64); - k1 = VP9_SET_COSPI_PAIR(-cospi_20_64, cospi_12_64); - k2 = VP9_SET_COSPI_PAIR(cospi_20_64, -cospi_12_64); - MADD_BF(g7, g5, g15, g13, k0, k1, k2, k0, h4, h5, h6, h7); - BUTTERFLY_4(h0, h2, h6, h4, out8, out9, out11, out10); - out8 = -out8; - - SRARI_H2_SH(out8, out9, 6); - dst8 = LD_UB(dst + 1 * dst_stride); - dst9 = LD_UB(dst + 14 * dst_stride); - ILVR_B2_SH(zero, dst8, zero, dst9, res8, res9); - ADD2(res8, out8, res9, out9, res8, res9); - CLIP_SH2_0_255(res8, res9); - PCKEV_B2_SH(res8, res8, res9, res9, res8, res9); - ST8x1_UB(res8, dst + dst_stride); - ST8x1_UB(res9, dst + 14 * dst_stride); - - k0 = VP9_SET_COSPI_PAIR(cospi_8_64, cospi_24_64); - k1 = VP9_SET_COSPI_PAIR(cospi_24_64, -cospi_8_64); - k2 = VP9_SET_COSPI_PAIR(-cospi_24_64, cospi_8_64); - MADD_BF(v0, v2, v4, v6, k0, k1, k2, k0, out4, out6, out5, out7); - out4 = -out4; - SRARI_H2_SH(out4, out5, 6); - dst4 = LD_UB(dst + 3 * dst_stride); - dst5 = LD_UB(dst + 12 * dst_stride); - ILVR_B2_SH(zero, dst4, zero, dst5, res4, res5); - ADD2(res4, out4, res5, out5, res4, res5); - CLIP_SH2_0_255(res4, res5); - PCKEV_B2_SH(res4, res4, res5, res5, res4, res5); - ST8x1_UB(res4, dst + 3 * dst_stride); - ST8x1_UB(res5, dst + 12 * dst_stride); - - MADD_BF(h1, h3, h5, h7, k0, k1, k2, k0, out12, out14, out13, out15); - out13 = -out13; - SRARI_H2_SH(out12, out13, 6); - dst12 = LD_UB(dst + 2 * dst_stride); - dst13 = LD_UB(dst + 13 * dst_stride); - ILVR_B2_SH(zero, dst12, zero, dst13, res12, res13); - ADD2(res12, out12, res13, out13, res12, res13); - CLIP_SH2_0_255(res12, res13); - PCKEV_B2_SH(res12, res12, res13, res13, res12, res13); - ST8x1_UB(res12, dst + 2 * dst_stride); - ST8x1_UB(res13, dst + 13 * dst_stride); - - k0 = VP9_SET_COSPI_PAIR(cospi_16_64, cospi_16_64); - k3 = VP9_SET_COSPI_PAIR(-cospi_16_64, cospi_16_64); - MADD_SHORT(out6, out7, k0, k3, out6, out7); - SRARI_H2_SH(out6, out7, 6); - dst6 = LD_UB(dst + 4 * dst_stride); - dst7 = LD_UB(dst + 11 * dst_stride); - ILVR_B2_SH(zero, dst6, zero, dst7, res6, res7); - ADD2(res6, out6, res7, out7, res6, res7); - CLIP_SH2_0_255(res6, res7); - PCKEV_B2_SH(res6, res6, res7, res7, res6, res7); - ST8x1_UB(res6, dst + 4 * dst_stride); - ST8x1_UB(res7, dst + 11 * dst_stride); - - MADD_SHORT(out10, out11, k0, k3, out10, out11); - SRARI_H2_SH(out10, out11, 6); - dst10 = LD_UB(dst + 6 * dst_stride); - dst11 = LD_UB(dst + 9 * dst_stride); - ILVR_B2_SH(zero, dst10, zero, dst11, res10, res11); - ADD2(res10, out10, res11, out11, res10, res11); - CLIP_SH2_0_255(res10, res11); - PCKEV_B2_SH(res10, res10, res11, res11, res10, res11); - ST8x1_UB(res10, dst + 6 * dst_stride); - ST8x1_UB(res11, dst + 9 * dst_stride); - - k1 = VP9_SET_COSPI_PAIR(-cospi_16_64, -cospi_16_64); - k2 = VP9_SET_COSPI_PAIR(cospi_16_64, -cospi_16_64); - MADD_SHORT(h10, h11, k1, k2, out2, out3); - SRARI_H2_SH(out2, out3, 6); - dst2 = LD_UB(dst + 7 * dst_stride); - dst3 = LD_UB(dst + 8 * dst_stride); - ILVR_B2_SH(zero, dst2, zero, dst3, res2, res3); - ADD2(res2, out2, res3, out3, res2, res3); - CLIP_SH2_0_255(res2, res3); - PCKEV_B2_SH(res2, res2, res3, res3, res2, res3); - ST8x1_UB(res2, dst + 7 * dst_stride); - ST8x1_UB(res3, dst + 8 * dst_stride); - - MADD_SHORT(out14, out15, k1, k2, out14, out15); - SRARI_H2_SH(out14, out15, 6); - dst14 = LD_UB(dst + 5 * dst_stride); - dst15 = LD_UB(dst + 10 * dst_stride); - ILVR_B2_SH(zero, dst14, zero, dst15, res14, res15); - ADD2(res14, out14, res15, out15, res14, res15); - CLIP_SH2_0_255(res14, res15); - PCKEV_B2_SH(res14, res14, res15, res15, res14, res15); - ST8x1_UB(res14, dst + 5 * dst_stride); - ST8x1_UB(res15, dst + 10 * dst_stride); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/idct32x32_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/idct32x32_msa.c deleted file mode 100644 index 05394818..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/idct32x32_msa.c +++ /dev/null @@ -1,730 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/inv_txfm_msa.h" - -static void idct32x8_row_transpose_store(const int16_t *input, - int16_t *tmp_buf) { - v8i16 m0, m1, m2, m3, m4, m5, m6, m7, n0, n1, n2, n3, n4, n5, n6, n7; - - /* 1st & 2nd 8x8 */ - LD_SH8(input, 32, m0, n0, m1, n1, m2, n2, m3, n3); - LD_SH8((input + 8), 32, m4, n4, m5, n5, m6, n6, m7, n7); - TRANSPOSE8x8_SH_SH(m0, n0, m1, n1, m2, n2, m3, n3, m0, n0, m1, n1, m2, n2, m3, - n3); - TRANSPOSE8x8_SH_SH(m4, n4, m5, n5, m6, n6, m7, n7, m4, n4, m5, n5, m6, n6, m7, - n7); - ST_SH8(m0, n0, m1, n1, m2, n2, m3, n3, (tmp_buf), 8); - ST_SH4(m4, n4, m5, n5, (tmp_buf + 8 * 8), 8); - ST_SH4(m6, n6, m7, n7, (tmp_buf + 12 * 8), 8); - - /* 3rd & 4th 8x8 */ - LD_SH8((input + 16), 32, m0, n0, m1, n1, m2, n2, m3, n3); - LD_SH8((input + 24), 32, m4, n4, m5, n5, m6, n6, m7, n7); - TRANSPOSE8x8_SH_SH(m0, n0, m1, n1, m2, n2, m3, n3, m0, n0, m1, n1, m2, n2, m3, - n3); - TRANSPOSE8x8_SH_SH(m4, n4, m5, n5, m6, n6, m7, n7, m4, n4, m5, n5, m6, n6, m7, - n7); - ST_SH4(m0, n0, m1, n1, (tmp_buf + 16 * 8), 8); - ST_SH4(m2, n2, m3, n3, (tmp_buf + 20 * 8), 8); - ST_SH4(m4, n4, m5, n5, (tmp_buf + 24 * 8), 8); - ST_SH4(m6, n6, m7, n7, (tmp_buf + 28 * 8), 8); -} - -static void idct32x8_row_even_process_store(int16_t *tmp_buf, - int16_t *tmp_eve_buf) { - v8i16 vec0, vec1, vec2, vec3, loc0, loc1, loc2, loc3; - v8i16 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; - v8i16 stp0, stp1, stp2, stp3, stp4, stp5, stp6, stp7; - - /* Even stage 1 */ - LD_SH8(tmp_buf, 32, reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7); - - DOTP_CONST_PAIR(reg1, reg7, cospi_28_64, cospi_4_64, reg1, reg7); - DOTP_CONST_PAIR(reg5, reg3, cospi_12_64, cospi_20_64, reg5, reg3); - BUTTERFLY_4(reg1, reg7, reg3, reg5, vec1, vec3, vec2, vec0); - DOTP_CONST_PAIR(vec2, vec0, cospi_16_64, cospi_16_64, loc2, loc3); - - loc1 = vec3; - loc0 = vec1; - - DOTP_CONST_PAIR(reg0, reg4, cospi_16_64, cospi_16_64, reg0, reg4); - DOTP_CONST_PAIR(reg2, reg6, cospi_24_64, cospi_8_64, reg2, reg6); - BUTTERFLY_4(reg4, reg0, reg2, reg6, vec1, vec3, vec2, vec0); - BUTTERFLY_4(vec0, vec1, loc1, loc0, stp3, stp0, stp7, stp4); - BUTTERFLY_4(vec2, vec3, loc3, loc2, stp2, stp1, stp6, stp5); - - /* Even stage 2 */ - LD_SH8((tmp_buf + 16), 32, reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7); - DOTP_CONST_PAIR(reg0, reg7, cospi_30_64, cospi_2_64, reg0, reg7); - DOTP_CONST_PAIR(reg4, reg3, cospi_14_64, cospi_18_64, reg4, reg3); - DOTP_CONST_PAIR(reg2, reg5, cospi_22_64, cospi_10_64, reg2, reg5); - DOTP_CONST_PAIR(reg6, reg1, cospi_6_64, cospi_26_64, reg6, reg1); - - vec0 = reg0 + reg4; - reg0 = reg0 - reg4; - reg4 = reg6 + reg2; - reg6 = reg6 - reg2; - reg2 = reg1 + reg5; - reg1 = reg1 - reg5; - reg5 = reg7 + reg3; - reg7 = reg7 - reg3; - reg3 = vec0; - - vec1 = reg2; - reg2 = reg3 + reg4; - reg3 = reg3 - reg4; - reg4 = reg5 - vec1; - reg5 = reg5 + vec1; - - DOTP_CONST_PAIR(reg7, reg0, cospi_24_64, cospi_8_64, reg0, reg7); - DOTP_CONST_PAIR((-reg6), reg1, cospi_24_64, cospi_8_64, reg6, reg1); - - vec0 = reg0 - reg6; - reg0 = reg0 + reg6; - vec1 = reg7 - reg1; - reg7 = reg7 + reg1; - - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, reg6, reg1); - DOTP_CONST_PAIR(reg4, reg3, cospi_16_64, cospi_16_64, reg3, reg4); - - /* Even stage 3 : Dependency on Even stage 1 & Even stage 2 */ - BUTTERFLY_4(stp0, stp1, reg7, reg5, loc1, loc3, loc2, loc0); - ST_SH(loc0, (tmp_eve_buf + 15 * 8)); - ST_SH(loc1, (tmp_eve_buf)); - ST_SH(loc2, (tmp_eve_buf + 14 * 8)); - ST_SH(loc3, (tmp_eve_buf + 8)); - - BUTTERFLY_4(stp2, stp3, reg4, reg1, loc1, loc3, loc2, loc0); - ST_SH(loc0, (tmp_eve_buf + 13 * 8)); - ST_SH(loc1, (tmp_eve_buf + 2 * 8)); - ST_SH(loc2, (tmp_eve_buf + 12 * 8)); - ST_SH(loc3, (tmp_eve_buf + 3 * 8)); - - /* Store 8 */ - BUTTERFLY_4(stp4, stp5, reg6, reg3, loc1, loc3, loc2, loc0); - ST_SH(loc0, (tmp_eve_buf + 11 * 8)); - ST_SH(loc1, (tmp_eve_buf + 4 * 8)); - ST_SH(loc2, (tmp_eve_buf + 10 * 8)); - ST_SH(loc3, (tmp_eve_buf + 5 * 8)); - - BUTTERFLY_4(stp6, stp7, reg2, reg0, loc1, loc3, loc2, loc0); - ST_SH(loc0, (tmp_eve_buf + 9 * 8)); - ST_SH(loc1, (tmp_eve_buf + 6 * 8)); - ST_SH(loc2, (tmp_eve_buf + 8 * 8)); - ST_SH(loc3, (tmp_eve_buf + 7 * 8)); -} - -static void idct32x8_row_odd_process_store(int16_t *tmp_buf, - int16_t *tmp_odd_buf) { - v8i16 vec0, vec1, vec2, vec3, loc0, loc1, loc2, loc3; - v8i16 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; - - /* Odd stage 1 */ - reg0 = LD_SH(tmp_buf + 8); - reg1 = LD_SH(tmp_buf + 7 * 8); - reg2 = LD_SH(tmp_buf + 9 * 8); - reg3 = LD_SH(tmp_buf + 15 * 8); - reg4 = LD_SH(tmp_buf + 17 * 8); - reg5 = LD_SH(tmp_buf + 23 * 8); - reg6 = LD_SH(tmp_buf + 25 * 8); - reg7 = LD_SH(tmp_buf + 31 * 8); - - DOTP_CONST_PAIR(reg0, reg7, cospi_31_64, cospi_1_64, reg0, reg7); - DOTP_CONST_PAIR(reg4, reg3, cospi_15_64, cospi_17_64, reg3, reg4); - DOTP_CONST_PAIR(reg2, reg5, cospi_23_64, cospi_9_64, reg2, reg5); - DOTP_CONST_PAIR(reg6, reg1, cospi_7_64, cospi_25_64, reg1, reg6); - - vec0 = reg0 + reg3; - reg0 = reg0 - reg3; - reg3 = reg7 + reg4; - reg7 = reg7 - reg4; - reg4 = reg1 + reg2; - reg1 = reg1 - reg2; - reg2 = reg6 + reg5; - reg6 = reg6 - reg5; - reg5 = vec0; - - /* 4 Stores */ - ADD2(reg5, reg4, reg3, reg2, vec0, vec1); - ST_SH2(vec0, vec1, (tmp_odd_buf + 4 * 8), 8); - - SUB2(reg5, reg4, reg3, reg2, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_24_64, cospi_8_64, vec0, vec1); - ST_SH2(vec0, vec1, (tmp_odd_buf), 8); - - /* 4 Stores */ - DOTP_CONST_PAIR(reg7, reg0, cospi_28_64, cospi_4_64, reg0, reg7); - DOTP_CONST_PAIR(reg6, reg1, -cospi_4_64, cospi_28_64, reg1, reg6); - BUTTERFLY_4(reg0, reg7, reg6, reg1, vec0, vec1, vec2, vec3); - ST_SH2(vec0, vec1, (tmp_odd_buf + 6 * 8), 8); - - DOTP_CONST_PAIR(vec2, vec3, cospi_24_64, cospi_8_64, vec2, vec3); - ST_SH2(vec2, vec3, (tmp_odd_buf + 2 * 8), 8); - - /* Odd stage 2 */ - /* 8 loads */ - reg0 = LD_SH(tmp_buf + 3 * 8); - reg1 = LD_SH(tmp_buf + 5 * 8); - reg2 = LD_SH(tmp_buf + 11 * 8); - reg3 = LD_SH(tmp_buf + 13 * 8); - reg4 = LD_SH(tmp_buf + 19 * 8); - reg5 = LD_SH(tmp_buf + 21 * 8); - reg6 = LD_SH(tmp_buf + 27 * 8); - reg7 = LD_SH(tmp_buf + 29 * 8); - - DOTP_CONST_PAIR(reg1, reg6, cospi_27_64, cospi_5_64, reg1, reg6); - DOTP_CONST_PAIR(reg5, reg2, cospi_11_64, cospi_21_64, reg2, reg5); - DOTP_CONST_PAIR(reg3, reg4, cospi_19_64, cospi_13_64, reg3, reg4); - DOTP_CONST_PAIR(reg7, reg0, cospi_3_64, cospi_29_64, reg0, reg7); - - /* 4 Stores */ - SUB4(reg1, reg2, reg6, reg5, reg0, reg3, reg7, reg4, vec0, vec1, vec2, vec3); - DOTP_CONST_PAIR(vec1, vec0, cospi_12_64, cospi_20_64, loc0, loc1); - DOTP_CONST_PAIR(vec3, vec2, -cospi_20_64, cospi_12_64, loc2, loc3); - - BUTTERFLY_4(loc3, loc2, loc0, loc1, vec1, vec0, vec2, vec3); - ST_SH2(vec0, vec1, (tmp_odd_buf + 12 * 8), 3 * 8); - - DOTP_CONST_PAIR(vec3, vec2, -cospi_8_64, cospi_24_64, vec0, vec1); - ST_SH2(vec0, vec1, (tmp_odd_buf + 10 * 8), 8); - - /* 4 Stores */ - ADD4(reg1, reg2, reg6, reg5, reg0, reg3, reg7, reg4, vec1, vec2, vec0, vec3); - BUTTERFLY_4(vec0, vec3, vec2, vec1, reg0, reg1, reg3, reg2); - ST_SH(reg0, (tmp_odd_buf + 13 * 8)); - ST_SH(reg1, (tmp_odd_buf + 14 * 8)); - - DOTP_CONST_PAIR(reg3, reg2, -cospi_8_64, cospi_24_64, reg0, reg1); - ST_SH2(reg0, reg1, (tmp_odd_buf + 8 * 8), 8); - - /* Odd stage 3 : Dependency on Odd stage 1 & Odd stage 2 */ - - /* Load 8 & Store 8 */ - LD_SH4(tmp_odd_buf, 8, reg0, reg1, reg2, reg3); - LD_SH4((tmp_odd_buf + 8 * 8), 8, reg4, reg5, reg6, reg7); - - ADD4(reg0, reg4, reg1, reg5, reg2, reg6, reg3, reg7, loc0, loc1, loc2, loc3); - ST_SH4(loc0, loc1, loc2, loc3, tmp_odd_buf, 8); - - SUB2(reg0, reg4, reg1, reg5, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, loc0, loc1); - - SUB2(reg2, reg6, reg3, reg7, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, loc2, loc3); - ST_SH4(loc0, loc1, loc2, loc3, (tmp_odd_buf + 8 * 8), 8); - - /* Load 8 & Store 8 */ - LD_SH4((tmp_odd_buf + 4 * 8), 8, reg1, reg2, reg0, reg3); - LD_SH4((tmp_odd_buf + 12 * 8), 8, reg4, reg5, reg6, reg7); - - ADD4(reg0, reg4, reg1, reg5, reg2, reg6, reg3, reg7, loc0, loc1, loc2, loc3); - ST_SH4(loc0, loc1, loc2, loc3, (tmp_odd_buf + 4 * 8), 8); - - SUB2(reg0, reg4, reg3, reg7, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, loc0, loc1); - - SUB2(reg1, reg5, reg2, reg6, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, loc2, loc3); - ST_SH4(loc0, loc1, loc2, loc3, (tmp_odd_buf + 12 * 8), 8); -} - -static void idct_butterfly_transpose_store(int16_t *tmp_buf, - int16_t *tmp_eve_buf, - int16_t *tmp_odd_buf, int16_t *dst) { - v8i16 vec0, vec1, vec2, vec3, loc0, loc1, loc2, loc3; - v8i16 m0, m1, m2, m3, m4, m5, m6, m7, n0, n1, n2, n3, n4, n5, n6, n7; - - /* FINAL BUTTERFLY : Dependency on Even & Odd */ - vec0 = LD_SH(tmp_odd_buf); - vec1 = LD_SH(tmp_odd_buf + 9 * 8); - vec2 = LD_SH(tmp_odd_buf + 14 * 8); - vec3 = LD_SH(tmp_odd_buf + 6 * 8); - loc0 = LD_SH(tmp_eve_buf); - loc1 = LD_SH(tmp_eve_buf + 8 * 8); - loc2 = LD_SH(tmp_eve_buf + 4 * 8); - loc3 = LD_SH(tmp_eve_buf + 12 * 8); - - ADD4(loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, m0, m4, m2, m6); - - ST_SH((loc0 - vec3), (tmp_buf + 31 * 8)); - ST_SH((loc1 - vec2), (tmp_buf + 23 * 8)); - ST_SH((loc2 - vec1), (tmp_buf + 27 * 8)); - ST_SH((loc3 - vec0), (tmp_buf + 19 * 8)); - - /* Load 8 & Store 8 */ - vec0 = LD_SH(tmp_odd_buf + 4 * 8); - vec1 = LD_SH(tmp_odd_buf + 13 * 8); - vec2 = LD_SH(tmp_odd_buf + 10 * 8); - vec3 = LD_SH(tmp_odd_buf + 3 * 8); - loc0 = LD_SH(tmp_eve_buf + 2 * 8); - loc1 = LD_SH(tmp_eve_buf + 10 * 8); - loc2 = LD_SH(tmp_eve_buf + 6 * 8); - loc3 = LD_SH(tmp_eve_buf + 14 * 8); - - ADD4(loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, m1, m5, m3, m7); - - ST_SH((loc0 - vec3), (tmp_buf + 29 * 8)); - ST_SH((loc1 - vec2), (tmp_buf + 21 * 8)); - ST_SH((loc2 - vec1), (tmp_buf + 25 * 8)); - ST_SH((loc3 - vec0), (tmp_buf + 17 * 8)); - - /* Load 8 & Store 8 */ - vec0 = LD_SH(tmp_odd_buf + 2 * 8); - vec1 = LD_SH(tmp_odd_buf + 11 * 8); - vec2 = LD_SH(tmp_odd_buf + 12 * 8); - vec3 = LD_SH(tmp_odd_buf + 7 * 8); - loc0 = LD_SH(tmp_eve_buf + 1 * 8); - loc1 = LD_SH(tmp_eve_buf + 9 * 8); - loc2 = LD_SH(tmp_eve_buf + 5 * 8); - loc3 = LD_SH(tmp_eve_buf + 13 * 8); - - ADD4(loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, n0, n4, n2, n6); - - ST_SH((loc0 - vec3), (tmp_buf + 30 * 8)); - ST_SH((loc1 - vec2), (tmp_buf + 22 * 8)); - ST_SH((loc2 - vec1), (tmp_buf + 26 * 8)); - ST_SH((loc3 - vec0), (tmp_buf + 18 * 8)); - - /* Load 8 & Store 8 */ - vec0 = LD_SH(tmp_odd_buf + 5 * 8); - vec1 = LD_SH(tmp_odd_buf + 15 * 8); - vec2 = LD_SH(tmp_odd_buf + 8 * 8); - vec3 = LD_SH(tmp_odd_buf + 1 * 8); - loc0 = LD_SH(tmp_eve_buf + 3 * 8); - loc1 = LD_SH(tmp_eve_buf + 11 * 8); - loc2 = LD_SH(tmp_eve_buf + 7 * 8); - loc3 = LD_SH(tmp_eve_buf + 15 * 8); - - ADD4(loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, n1, n5, n3, n7); - - ST_SH((loc0 - vec3), (tmp_buf + 28 * 8)); - ST_SH((loc1 - vec2), (tmp_buf + 20 * 8)); - ST_SH((loc2 - vec1), (tmp_buf + 24 * 8)); - ST_SH((loc3 - vec0), (tmp_buf + 16 * 8)); - - /* Transpose : 16 vectors */ - /* 1st & 2nd 8x8 */ - TRANSPOSE8x8_SH_SH(m0, n0, m1, n1, m2, n2, m3, n3, m0, n0, m1, n1, m2, n2, m3, - n3); - ST_SH4(m0, n0, m1, n1, (dst + 0), 32); - ST_SH4(m2, n2, m3, n3, (dst + 4 * 32), 32); - - TRANSPOSE8x8_SH_SH(m4, n4, m5, n5, m6, n6, m7, n7, m4, n4, m5, n5, m6, n6, m7, - n7); - ST_SH4(m4, n4, m5, n5, (dst + 8), 32); - ST_SH4(m6, n6, m7, n7, (dst + 8 + 4 * 32), 32); - - /* 3rd & 4th 8x8 */ - LD_SH8((tmp_buf + 8 * 16), 8, m0, n0, m1, n1, m2, n2, m3, n3); - LD_SH8((tmp_buf + 12 * 16), 8, m4, n4, m5, n5, m6, n6, m7, n7); - TRANSPOSE8x8_SH_SH(m0, n0, m1, n1, m2, n2, m3, n3, m0, n0, m1, n1, m2, n2, m3, - n3); - ST_SH4(m0, n0, m1, n1, (dst + 16), 32); - ST_SH4(m2, n2, m3, n3, (dst + 16 + 4 * 32), 32); - - TRANSPOSE8x8_SH_SH(m4, n4, m5, n5, m6, n6, m7, n7, m4, n4, m5, n5, m6, n6, m7, - n7); - ST_SH4(m4, n4, m5, n5, (dst + 24), 32); - ST_SH4(m6, n6, m7, n7, (dst + 24 + 4 * 32), 32); -} - -static void idct32x8_1d_rows_msa(const int16_t *input, int16_t *output) { - DECLARE_ALIGNED(32, int16_t, tmp_buf[8 * 32]); - DECLARE_ALIGNED(32, int16_t, tmp_odd_buf[16 * 8]); - DECLARE_ALIGNED(32, int16_t, tmp_eve_buf[16 * 8]); - - idct32x8_row_transpose_store(input, &tmp_buf[0]); - idct32x8_row_even_process_store(&tmp_buf[0], &tmp_eve_buf[0]); - idct32x8_row_odd_process_store(&tmp_buf[0], &tmp_odd_buf[0]); - idct_butterfly_transpose_store(&tmp_buf[0], &tmp_eve_buf[0], &tmp_odd_buf[0], - output); -} - -static void idct8x32_column_even_process_store(int16_t *tmp_buf, - int16_t *tmp_eve_buf) { - v8i16 vec0, vec1, vec2, vec3, loc0, loc1, loc2, loc3; - v8i16 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; - v8i16 stp0, stp1, stp2, stp3, stp4, stp5, stp6, stp7; - - /* Even stage 1 */ - LD_SH8(tmp_buf, (4 * 32), reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7); - tmp_buf += (2 * 32); - - DOTP_CONST_PAIR(reg1, reg7, cospi_28_64, cospi_4_64, reg1, reg7); - DOTP_CONST_PAIR(reg5, reg3, cospi_12_64, cospi_20_64, reg5, reg3); - BUTTERFLY_4(reg1, reg7, reg3, reg5, vec1, vec3, vec2, vec0); - DOTP_CONST_PAIR(vec2, vec0, cospi_16_64, cospi_16_64, loc2, loc3); - - loc1 = vec3; - loc0 = vec1; - - DOTP_CONST_PAIR(reg0, reg4, cospi_16_64, cospi_16_64, reg0, reg4); - DOTP_CONST_PAIR(reg2, reg6, cospi_24_64, cospi_8_64, reg2, reg6); - BUTTERFLY_4(reg4, reg0, reg2, reg6, vec1, vec3, vec2, vec0); - BUTTERFLY_4(vec0, vec1, loc1, loc0, stp3, stp0, stp7, stp4); - BUTTERFLY_4(vec2, vec3, loc3, loc2, stp2, stp1, stp6, stp5); - - /* Even stage 2 */ - /* Load 8 */ - LD_SH8(tmp_buf, (4 * 32), reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7); - - DOTP_CONST_PAIR(reg0, reg7, cospi_30_64, cospi_2_64, reg0, reg7); - DOTP_CONST_PAIR(reg4, reg3, cospi_14_64, cospi_18_64, reg4, reg3); - DOTP_CONST_PAIR(reg2, reg5, cospi_22_64, cospi_10_64, reg2, reg5); - DOTP_CONST_PAIR(reg6, reg1, cospi_6_64, cospi_26_64, reg6, reg1); - - vec0 = reg0 + reg4; - reg0 = reg0 - reg4; - reg4 = reg6 + reg2; - reg6 = reg6 - reg2; - reg2 = reg1 + reg5; - reg1 = reg1 - reg5; - reg5 = reg7 + reg3; - reg7 = reg7 - reg3; - reg3 = vec0; - - vec1 = reg2; - reg2 = reg3 + reg4; - reg3 = reg3 - reg4; - reg4 = reg5 - vec1; - reg5 = reg5 + vec1; - - DOTP_CONST_PAIR(reg7, reg0, cospi_24_64, cospi_8_64, reg0, reg7); - DOTP_CONST_PAIR((-reg6), reg1, cospi_24_64, cospi_8_64, reg6, reg1); - - vec0 = reg0 - reg6; - reg0 = reg0 + reg6; - vec1 = reg7 - reg1; - reg7 = reg7 + reg1; - - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, reg6, reg1); - DOTP_CONST_PAIR(reg4, reg3, cospi_16_64, cospi_16_64, reg3, reg4); - - /* Even stage 3 : Dependency on Even stage 1 & Even stage 2 */ - /* Store 8 */ - BUTTERFLY_4(stp0, stp1, reg7, reg5, loc1, loc3, loc2, loc0); - ST_SH2(loc1, loc3, tmp_eve_buf, 8); - ST_SH2(loc2, loc0, (tmp_eve_buf + 14 * 8), 8); - - BUTTERFLY_4(stp2, stp3, reg4, reg1, loc1, loc3, loc2, loc0); - ST_SH2(loc1, loc3, (tmp_eve_buf + 2 * 8), 8); - ST_SH2(loc2, loc0, (tmp_eve_buf + 12 * 8), 8); - - /* Store 8 */ - BUTTERFLY_4(stp4, stp5, reg6, reg3, loc1, loc3, loc2, loc0); - ST_SH2(loc1, loc3, (tmp_eve_buf + 4 * 8), 8); - ST_SH2(loc2, loc0, (tmp_eve_buf + 10 * 8), 8); - - BUTTERFLY_4(stp6, stp7, reg2, reg0, loc1, loc3, loc2, loc0); - ST_SH2(loc1, loc3, (tmp_eve_buf + 6 * 8), 8); - ST_SH2(loc2, loc0, (tmp_eve_buf + 8 * 8), 8); -} - -static void idct8x32_column_odd_process_store(int16_t *tmp_buf, - int16_t *tmp_odd_buf) { - v8i16 vec0, vec1, vec2, vec3, loc0, loc1, loc2, loc3; - v8i16 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; - - /* Odd stage 1 */ - reg0 = LD_SH(tmp_buf + 32); - reg1 = LD_SH(tmp_buf + 7 * 32); - reg2 = LD_SH(tmp_buf + 9 * 32); - reg3 = LD_SH(tmp_buf + 15 * 32); - reg4 = LD_SH(tmp_buf + 17 * 32); - reg5 = LD_SH(tmp_buf + 23 * 32); - reg6 = LD_SH(tmp_buf + 25 * 32); - reg7 = LD_SH(tmp_buf + 31 * 32); - - DOTP_CONST_PAIR(reg0, reg7, cospi_31_64, cospi_1_64, reg0, reg7); - DOTP_CONST_PAIR(reg4, reg3, cospi_15_64, cospi_17_64, reg3, reg4); - DOTP_CONST_PAIR(reg2, reg5, cospi_23_64, cospi_9_64, reg2, reg5); - DOTP_CONST_PAIR(reg6, reg1, cospi_7_64, cospi_25_64, reg1, reg6); - - vec0 = reg0 + reg3; - reg0 = reg0 - reg3; - reg3 = reg7 + reg4; - reg7 = reg7 - reg4; - reg4 = reg1 + reg2; - reg1 = reg1 - reg2; - reg2 = reg6 + reg5; - reg6 = reg6 - reg5; - reg5 = vec0; - - /* 4 Stores */ - ADD2(reg5, reg4, reg3, reg2, vec0, vec1); - ST_SH2(vec0, vec1, (tmp_odd_buf + 4 * 8), 8); - SUB2(reg5, reg4, reg3, reg2, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_24_64, cospi_8_64, vec0, vec1); - ST_SH2(vec0, vec1, tmp_odd_buf, 8); - - /* 4 Stores */ - DOTP_CONST_PAIR(reg7, reg0, cospi_28_64, cospi_4_64, reg0, reg7); - DOTP_CONST_PAIR(reg6, reg1, -cospi_4_64, cospi_28_64, reg1, reg6); - BUTTERFLY_4(reg0, reg7, reg6, reg1, vec0, vec1, vec2, vec3); - ST_SH2(vec0, vec1, (tmp_odd_buf + 6 * 8), 8); - DOTP_CONST_PAIR(vec2, vec3, cospi_24_64, cospi_8_64, vec2, vec3); - ST_SH2(vec2, vec3, (tmp_odd_buf + 2 * 8), 8); - - /* Odd stage 2 */ - /* 8 loads */ - reg0 = LD_SH(tmp_buf + 3 * 32); - reg1 = LD_SH(tmp_buf + 5 * 32); - reg2 = LD_SH(tmp_buf + 11 * 32); - reg3 = LD_SH(tmp_buf + 13 * 32); - reg4 = LD_SH(tmp_buf + 19 * 32); - reg5 = LD_SH(tmp_buf + 21 * 32); - reg6 = LD_SH(tmp_buf + 27 * 32); - reg7 = LD_SH(tmp_buf + 29 * 32); - - DOTP_CONST_PAIR(reg1, reg6, cospi_27_64, cospi_5_64, reg1, reg6); - DOTP_CONST_PAIR(reg5, reg2, cospi_11_64, cospi_21_64, reg2, reg5); - DOTP_CONST_PAIR(reg3, reg4, cospi_19_64, cospi_13_64, reg3, reg4); - DOTP_CONST_PAIR(reg7, reg0, cospi_3_64, cospi_29_64, reg0, reg7); - - /* 4 Stores */ - SUB4(reg1, reg2, reg6, reg5, reg0, reg3, reg7, reg4, vec0, vec1, vec2, vec3); - DOTP_CONST_PAIR(vec1, vec0, cospi_12_64, cospi_20_64, loc0, loc1); - DOTP_CONST_PAIR(vec3, vec2, -cospi_20_64, cospi_12_64, loc2, loc3); - BUTTERFLY_4(loc2, loc3, loc1, loc0, vec0, vec1, vec3, vec2); - ST_SH2(vec0, vec1, (tmp_odd_buf + 12 * 8), 3 * 8); - DOTP_CONST_PAIR(vec3, vec2, -cospi_8_64, cospi_24_64, vec0, vec1); - ST_SH2(vec0, vec1, (tmp_odd_buf + 10 * 8), 8); - - /* 4 Stores */ - ADD4(reg0, reg3, reg1, reg2, reg5, reg6, reg4, reg7, vec0, vec1, vec2, vec3); - BUTTERFLY_4(vec0, vec3, vec2, vec1, reg0, reg1, reg3, reg2); - ST_SH2(reg0, reg1, (tmp_odd_buf + 13 * 8), 8); - DOTP_CONST_PAIR(reg3, reg2, -cospi_8_64, cospi_24_64, reg0, reg1); - ST_SH2(reg0, reg1, (tmp_odd_buf + 8 * 8), 8); - - /* Odd stage 3 : Dependency on Odd stage 1 & Odd stage 2 */ - /* Load 8 & Store 8 */ - LD_SH4(tmp_odd_buf, 8, reg0, reg1, reg2, reg3); - LD_SH4((tmp_odd_buf + 8 * 8), 8, reg4, reg5, reg6, reg7); - - ADD4(reg0, reg4, reg1, reg5, reg2, reg6, reg3, reg7, loc0, loc1, loc2, loc3); - ST_SH4(loc0, loc1, loc2, loc3, tmp_odd_buf, 8); - - SUB2(reg0, reg4, reg1, reg5, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, loc0, loc1); - - SUB2(reg2, reg6, reg3, reg7, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, loc2, loc3); - ST_SH4(loc0, loc1, loc2, loc3, (tmp_odd_buf + 8 * 8), 8); - - /* Load 8 & Store 8 */ - LD_SH4((tmp_odd_buf + 4 * 8), 8, reg1, reg2, reg0, reg3); - LD_SH4((tmp_odd_buf + 12 * 8), 8, reg4, reg5, reg6, reg7); - - ADD4(reg0, reg4, reg1, reg5, reg2, reg6, reg3, reg7, loc0, loc1, loc2, loc3); - ST_SH4(loc0, loc1, loc2, loc3, (tmp_odd_buf + 4 * 8), 8); - - SUB2(reg0, reg4, reg3, reg7, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, loc0, loc1); - - SUB2(reg1, reg5, reg2, reg6, vec0, vec1); - DOTP_CONST_PAIR(vec1, vec0, cospi_16_64, cospi_16_64, loc2, loc3); - ST_SH4(loc0, loc1, loc2, loc3, (tmp_odd_buf + 12 * 8), 8); -} - -static void idct8x32_column_butterfly_addblk(int16_t *tmp_eve_buf, - int16_t *tmp_odd_buf, uint8_t *dst, - int32_t dst_stride) { - v8i16 vec0, vec1, vec2, vec3, loc0, loc1, loc2, loc3; - v8i16 m0, m1, m2, m3, m4, m5, m6, m7, n0, n1, n2, n3, n4, n5, n6, n7; - - /* FINAL BUTTERFLY : Dependency on Even & Odd */ - vec0 = LD_SH(tmp_odd_buf); - vec1 = LD_SH(tmp_odd_buf + 9 * 8); - vec2 = LD_SH(tmp_odd_buf + 14 * 8); - vec3 = LD_SH(tmp_odd_buf + 6 * 8); - loc0 = LD_SH(tmp_eve_buf); - loc1 = LD_SH(tmp_eve_buf + 8 * 8); - loc2 = LD_SH(tmp_eve_buf + 4 * 8); - loc3 = LD_SH(tmp_eve_buf + 12 * 8); - - ADD4(loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, m0, m4, m2, m6); - SRARI_H4_SH(m0, m2, m4, m6, 6); - VP9_ADDBLK_ST8x4_UB(dst, (4 * dst_stride), m0, m2, m4, m6); - - SUB4(loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, m6, m2, m4, m0); - SRARI_H4_SH(m0, m2, m4, m6, 6); - VP9_ADDBLK_ST8x4_UB((dst + 19 * dst_stride), (4 * dst_stride), m0, m2, m4, - m6); - - /* Load 8 & Store 8 */ - vec0 = LD_SH(tmp_odd_buf + 4 * 8); - vec1 = LD_SH(tmp_odd_buf + 13 * 8); - vec2 = LD_SH(tmp_odd_buf + 10 * 8); - vec3 = LD_SH(tmp_odd_buf + 3 * 8); - loc0 = LD_SH(tmp_eve_buf + 2 * 8); - loc1 = LD_SH(tmp_eve_buf + 10 * 8); - loc2 = LD_SH(tmp_eve_buf + 6 * 8); - loc3 = LD_SH(tmp_eve_buf + 14 * 8); - - ADD4(loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, m1, m5, m3, m7); - SRARI_H4_SH(m1, m3, m5, m7, 6); - VP9_ADDBLK_ST8x4_UB((dst + 2 * dst_stride), (4 * dst_stride), m1, m3, m5, m7); - - SUB4(loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, m7, m3, m5, m1); - SRARI_H4_SH(m1, m3, m5, m7, 6); - VP9_ADDBLK_ST8x4_UB((dst + 17 * dst_stride), (4 * dst_stride), m1, m3, m5, - m7); - - /* Load 8 & Store 8 */ - vec0 = LD_SH(tmp_odd_buf + 2 * 8); - vec1 = LD_SH(tmp_odd_buf + 11 * 8); - vec2 = LD_SH(tmp_odd_buf + 12 * 8); - vec3 = LD_SH(tmp_odd_buf + 7 * 8); - loc0 = LD_SH(tmp_eve_buf + 1 * 8); - loc1 = LD_SH(tmp_eve_buf + 9 * 8); - loc2 = LD_SH(tmp_eve_buf + 5 * 8); - loc3 = LD_SH(tmp_eve_buf + 13 * 8); - - ADD4(loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, n0, n4, n2, n6); - SRARI_H4_SH(n0, n2, n4, n6, 6); - VP9_ADDBLK_ST8x4_UB((dst + 1 * dst_stride), (4 * dst_stride), n0, n2, n4, n6); - - SUB4(loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, n6, n2, n4, n0); - SRARI_H4_SH(n0, n2, n4, n6, 6); - VP9_ADDBLK_ST8x4_UB((dst + 18 * dst_stride), (4 * dst_stride), n0, n2, n4, - n6); - - /* Load 8 & Store 8 */ - vec0 = LD_SH(tmp_odd_buf + 5 * 8); - vec1 = LD_SH(tmp_odd_buf + 15 * 8); - vec2 = LD_SH(tmp_odd_buf + 8 * 8); - vec3 = LD_SH(tmp_odd_buf + 1 * 8); - loc0 = LD_SH(tmp_eve_buf + 3 * 8); - loc1 = LD_SH(tmp_eve_buf + 11 * 8); - loc2 = LD_SH(tmp_eve_buf + 7 * 8); - loc3 = LD_SH(tmp_eve_buf + 15 * 8); - - ADD4(loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, n1, n5, n3, n7); - SRARI_H4_SH(n1, n3, n5, n7, 6); - VP9_ADDBLK_ST8x4_UB((dst + 3 * dst_stride), (4 * dst_stride), n1, n3, n5, n7); - - SUB4(loc0, vec3, loc1, vec2, loc2, vec1, loc3, vec0, n7, n3, n5, n1); - SRARI_H4_SH(n1, n3, n5, n7, 6); - VP9_ADDBLK_ST8x4_UB((dst + 16 * dst_stride), (4 * dst_stride), n1, n3, n5, - n7); -} - -static void idct8x32_1d_columns_addblk_msa(int16_t *input, uint8_t *dst, - int32_t dst_stride) { - DECLARE_ALIGNED(32, int16_t, tmp_odd_buf[16 * 8]); - DECLARE_ALIGNED(32, int16_t, tmp_eve_buf[16 * 8]); - - idct8x32_column_even_process_store(input, &tmp_eve_buf[0]); - idct8x32_column_odd_process_store(input, &tmp_odd_buf[0]); - idct8x32_column_butterfly_addblk(&tmp_eve_buf[0], &tmp_odd_buf[0], dst, - dst_stride); -} - -void vpx_idct32x32_1024_add_msa(const int16_t *input, uint8_t *dst, - int32_t dst_stride) { - int32_t i; - DECLARE_ALIGNED(32, int16_t, out_arr[32 * 32]); - int16_t *out_ptr = out_arr; - - /* transform rows */ - for (i = 0; i < 4; ++i) { - /* process 32 * 8 block */ - idct32x8_1d_rows_msa((input + (i << 8)), (out_ptr + (i << 8))); - } - - /* transform columns */ - for (i = 0; i < 4; ++i) { - /* process 8 * 32 block */ - idct8x32_1d_columns_addblk_msa((out_ptr + (i << 3)), (dst + (i << 3)), - dst_stride); - } -} - -void vpx_idct32x32_34_add_msa(const int16_t *input, uint8_t *dst, - int32_t dst_stride) { - int32_t i; - DECLARE_ALIGNED(32, int16_t, out_arr[32 * 32]); - int16_t *out_ptr = out_arr; - - for (i = 32; i--;) { - __asm__ __volatile__( - "sw $zero, 0(%[out_ptr]) \n\t" - "sw $zero, 4(%[out_ptr]) \n\t" - "sw $zero, 8(%[out_ptr]) \n\t" - "sw $zero, 12(%[out_ptr]) \n\t" - "sw $zero, 16(%[out_ptr]) \n\t" - "sw $zero, 20(%[out_ptr]) \n\t" - "sw $zero, 24(%[out_ptr]) \n\t" - "sw $zero, 28(%[out_ptr]) \n\t" - "sw $zero, 32(%[out_ptr]) \n\t" - "sw $zero, 36(%[out_ptr]) \n\t" - "sw $zero, 40(%[out_ptr]) \n\t" - "sw $zero, 44(%[out_ptr]) \n\t" - "sw $zero, 48(%[out_ptr]) \n\t" - "sw $zero, 52(%[out_ptr]) \n\t" - "sw $zero, 56(%[out_ptr]) \n\t" - "sw $zero, 60(%[out_ptr]) \n\t" - - : - : [out_ptr] "r"(out_ptr)); - - out_ptr += 32; - } - - out_ptr = out_arr; - - /* rows: only upper-left 8x8 has non-zero coeff */ - idct32x8_1d_rows_msa(input, out_ptr); - - /* transform columns */ - for (i = 0; i < 4; ++i) { - /* process 8 * 32 block */ - idct8x32_1d_columns_addblk_msa((out_ptr + (i << 3)), (dst + (i << 3)), - dst_stride); - } -} - -void vpx_idct32x32_1_add_msa(const int16_t *input, uint8_t *dst, - int32_t dst_stride) { - int32_t i; - int16_t out; - v16u8 dst0, dst1, dst2, dst3, tmp0, tmp1, tmp2, tmp3; - v8i16 res0, res1, res2, res3, res4, res5, res6, res7, vec; - - out = ROUND_POWER_OF_TWO((input[0] * cospi_16_64), DCT_CONST_BITS); - out = ROUND_POWER_OF_TWO((out * cospi_16_64), DCT_CONST_BITS); - out = ROUND_POWER_OF_TWO(out, 6); - - vec = __msa_fill_h(out); - - for (i = 16; i--;) { - LD_UB2(dst, 16, dst0, dst1); - LD_UB2(dst + dst_stride, 16, dst2, dst3); - - UNPCK_UB_SH(dst0, res0, res4); - UNPCK_UB_SH(dst1, res1, res5); - UNPCK_UB_SH(dst2, res2, res6); - UNPCK_UB_SH(dst3, res3, res7); - ADD4(res0, vec, res1, vec, res2, vec, res3, vec, res0, res1, res2, res3); - ADD4(res4, vec, res5, vec, res6, vec, res7, vec, res4, res5, res6, res7); - CLIP_SH4_0_255(res0, res1, res2, res3); - CLIP_SH4_0_255(res4, res5, res6, res7); - PCKEV_B4_UB(res4, res0, res5, res1, res6, res2, res7, res3, tmp0, tmp1, - tmp2, tmp3); - - ST_UB2(tmp0, tmp1, dst, 16); - dst += dst_stride; - ST_UB2(tmp2, tmp3, dst, 16); - dst += dst_stride; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/idct4x4_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/idct4x4_msa.c deleted file mode 100644 index 56ffec3c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/idct4x4_msa.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/inv_txfm_msa.h" - -void vpx_iwht4x4_16_add_msa(const int16_t *input, uint8_t *dst, - int32_t dst_stride) { - v8i16 in0, in1, in2, in3; - v4i32 in0_r, in1_r, in2_r, in3_r, in4_r; - - /* load vector elements of 4x4 block */ - LD4x4_SH(input, in0, in2, in3, in1); - TRANSPOSE4x4_SH_SH(in0, in2, in3, in1, in0, in2, in3, in1); - UNPCK_R_SH_SW(in0, in0_r); - UNPCK_R_SH_SW(in2, in2_r); - UNPCK_R_SH_SW(in3, in3_r); - UNPCK_R_SH_SW(in1, in1_r); - SRA_4V(in0_r, in1_r, in2_r, in3_r, UNIT_QUANT_SHIFT); - - in0_r += in2_r; - in3_r -= in1_r; - in4_r = (in0_r - in3_r) >> 1; - in1_r = in4_r - in1_r; - in2_r = in4_r - in2_r; - in0_r -= in1_r; - in3_r += in2_r; - - TRANSPOSE4x4_SW_SW(in0_r, in1_r, in2_r, in3_r, in0_r, in1_r, in2_r, in3_r); - - in0_r += in1_r; - in2_r -= in3_r; - in4_r = (in0_r - in2_r) >> 1; - in3_r = in4_r - in3_r; - in1_r = in4_r - in1_r; - in0_r -= in3_r; - in2_r += in1_r; - - PCKEV_H4_SH(in0_r, in0_r, in1_r, in1_r, in2_r, in2_r, in3_r, in3_r, in0, in1, - in2, in3); - ADDBLK_ST4x4_UB(in0, in3, in1, in2, dst, dst_stride); -} - -void vpx_iwht4x4_1_add_msa(const int16_t *input, uint8_t *dst, - int32_t dst_stride) { - int16_t a1, e1; - v8i16 in1, in0 = { 0 }; - - a1 = input[0] >> UNIT_QUANT_SHIFT; - e1 = a1 >> 1; - a1 -= e1; - - in0 = __msa_insert_h(in0, 0, a1); - in0 = __msa_insert_h(in0, 1, e1); - in0 = __msa_insert_h(in0, 2, e1); - in0 = __msa_insert_h(in0, 3, e1); - - in1 = in0 >> 1; - in0 -= in1; - - ADDBLK_ST4x4_UB(in0, in1, in1, in1, dst, dst_stride); -} - -void vpx_idct4x4_16_add_msa(const int16_t *input, uint8_t *dst, - int32_t dst_stride) { - v8i16 in0, in1, in2, in3; - - /* load vector elements of 4x4 block */ - LD4x4_SH(input, in0, in1, in2, in3); - /* rows */ - TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); - VP9_IDCT4x4(in0, in1, in2, in3, in0, in1, in2, in3); - /* columns */ - TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); - VP9_IDCT4x4(in0, in1, in2, in3, in0, in1, in2, in3); - /* rounding (add 2^3, divide by 2^4) */ - SRARI_H4_SH(in0, in1, in2, in3, 4); - ADDBLK_ST4x4_UB(in0, in1, in2, in3, dst, dst_stride); -} - -void vpx_idct4x4_1_add_msa(const int16_t *input, uint8_t *dst, - int32_t dst_stride) { - int16_t out; - v8i16 vec; - - out = ROUND_POWER_OF_TWO((input[0] * cospi_16_64), DCT_CONST_BITS); - out = ROUND_POWER_OF_TWO((out * cospi_16_64), DCT_CONST_BITS); - out = ROUND_POWER_OF_TWO(out, 4); - vec = __msa_fill_h(out); - - ADDBLK_ST4x4_UB(vec, vec, vec, vec, dst, dst_stride); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/idct8x8_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/idct8x8_msa.c deleted file mode 100644 index a383ff20..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/idct8x8_msa.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/inv_txfm_msa.h" - -void vpx_idct8x8_64_add_msa(const int16_t *input, uint8_t *dst, - int32_t dst_stride) { - v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - - /* load vector elements of 8x8 block */ - LD_SH8(input, 8, in0, in1, in2, in3, in4, in5, in6, in7); - - /* rows transform */ - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - /* 1D idct8x8 */ - VP9_IDCT8x8_1D(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - /* columns transform */ - TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - /* 1D idct8x8 */ - VP9_IDCT8x8_1D(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - /* final rounding (add 2^4, divide by 2^5) and shift */ - SRARI_H4_SH(in0, in1, in2, in3, 5); - SRARI_H4_SH(in4, in5, in6, in7, 5); - /* add block and store 8x8 */ - VP9_ADDBLK_ST8x4_UB(dst, dst_stride, in0, in1, in2, in3); - dst += (4 * dst_stride); - VP9_ADDBLK_ST8x4_UB(dst, dst_stride, in4, in5, in6, in7); -} - -void vpx_idct8x8_12_add_msa(const int16_t *input, uint8_t *dst, - int32_t dst_stride) { - v8i16 in0, in1, in2, in3, in4, in5, in6, in7; - v8i16 s0, s1, s2, s3, s4, s5, s6, s7, k0, k1, k2, k3, m0, m1, m2, m3; - v4i32 tmp0, tmp1, tmp2, tmp3; - v8i16 zero = { 0 }; - - /* load vector elements of 8x8 block */ - LD_SH8(input, 8, in0, in1, in2, in3, in4, in5, in6, in7); - TRANSPOSE8X4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3); - - /* stage1 */ - ILVL_H2_SH(in3, in0, in2, in1, s0, s1); - k0 = VP9_SET_COSPI_PAIR(cospi_28_64, -cospi_4_64); - k1 = VP9_SET_COSPI_PAIR(cospi_4_64, cospi_28_64); - k2 = VP9_SET_COSPI_PAIR(-cospi_20_64, cospi_12_64); - k3 = VP9_SET_COSPI_PAIR(cospi_12_64, cospi_20_64); - DOTP_SH4_SW(s0, s0, s1, s1, k0, k1, k2, k3, tmp0, tmp1, tmp2, tmp3); - SRARI_W4_SW(tmp0, tmp1, tmp2, tmp3, DCT_CONST_BITS); - PCKEV_H2_SH(zero, tmp0, zero, tmp1, s0, s1); - PCKEV_H2_SH(zero, tmp2, zero, tmp3, s2, s3); - BUTTERFLY_4(s0, s1, s3, s2, s4, s7, s6, s5); - - /* stage2 */ - ILVR_H2_SH(in3, in1, in2, in0, s1, s0); - k0 = VP9_SET_COSPI_PAIR(cospi_16_64, cospi_16_64); - k1 = VP9_SET_COSPI_PAIR(cospi_16_64, -cospi_16_64); - k2 = VP9_SET_COSPI_PAIR(cospi_24_64, -cospi_8_64); - k3 = VP9_SET_COSPI_PAIR(cospi_8_64, cospi_24_64); - DOTP_SH4_SW(s0, s0, s1, s1, k0, k1, k2, k3, tmp0, tmp1, tmp2, tmp3); - SRARI_W4_SW(tmp0, tmp1, tmp2, tmp3, DCT_CONST_BITS); - PCKEV_H2_SH(zero, tmp0, zero, tmp1, s0, s1); - PCKEV_H2_SH(zero, tmp2, zero, tmp3, s2, s3); - BUTTERFLY_4(s0, s1, s2, s3, m0, m1, m2, m3); - - /* stage3 */ - s0 = __msa_ilvr_h(s6, s5); - - k1 = VP9_SET_COSPI_PAIR(-cospi_16_64, cospi_16_64); - DOTP_SH2_SW(s0, s0, k1, k0, tmp0, tmp1); - SRARI_W2_SW(tmp0, tmp1, DCT_CONST_BITS); - PCKEV_H2_SH(zero, tmp0, zero, tmp1, s2, s3); - - /* stage4 */ - BUTTERFLY_8(m0, m1, m2, m3, s4, s2, s3, s7, in0, in1, in2, in3, in4, in5, in6, - in7); - TRANSPOSE4X8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - VP9_IDCT8x8_1D(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, - in4, in5, in6, in7); - - /* final rounding (add 2^4, divide by 2^5) and shift */ - SRARI_H4_SH(in0, in1, in2, in3, 5); - SRARI_H4_SH(in4, in5, in6, in7, 5); - - /* add block and store 8x8 */ - VP9_ADDBLK_ST8x4_UB(dst, dst_stride, in0, in1, in2, in3); - dst += (4 * dst_stride); - VP9_ADDBLK_ST8x4_UB(dst, dst_stride, in4, in5, in6, in7); -} - -void vpx_idct8x8_1_add_msa(const int16_t *input, uint8_t *dst, - int32_t dst_stride) { - int16_t out; - int32_t val; - v8i16 vec; - - out = ROUND_POWER_OF_TWO((input[0] * cospi_16_64), DCT_CONST_BITS); - out = ROUND_POWER_OF_TWO((out * cospi_16_64), DCT_CONST_BITS); - val = ROUND_POWER_OF_TWO(out, 5); - vec = __msa_fill_h(val); - - VP9_ADDBLK_ST8x4_UB(dst, dst_stride, vec, vec, vec, vec); - dst += (4 * dst_stride); - VP9_ADDBLK_ST8x4_UB(dst, dst_stride, vec, vec, vec, vec); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/intrapred16_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/intrapred16_dspr2.c deleted file mode 100644 index 835e10e1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/intrapred16_dspr2.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_dsp/mips/common_dspr2.h" - -#if HAVE_DSPR2 -void vpx_h_predictor_16x16_dspr2(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - int32_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; - int32_t tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16; - (void)above; - - __asm__ __volatile__( - "lb %[tmp1], (%[left]) \n\t" - "lb %[tmp2], 1(%[left]) \n\t" - "lb %[tmp3], 2(%[left]) \n\t" - "lb %[tmp4], 3(%[left]) \n\t" - "lb %[tmp5], 4(%[left]) \n\t" - "lb %[tmp6], 5(%[left]) \n\t" - "lb %[tmp7], 6(%[left]) \n\t" - "lb %[tmp8], 7(%[left]) \n\t" - "lb %[tmp9], 8(%[left]) \n\t" - "lb %[tmp10], 9(%[left]) \n\t" - "lb %[tmp11], 10(%[left]) \n\t" - "lb %[tmp12], 11(%[left]) \n\t" - "lb %[tmp13], 12(%[left]) \n\t" - "lb %[tmp14], 13(%[left]) \n\t" - "lb %[tmp15], 14(%[left]) \n\t" - "lb %[tmp16], 15(%[left]) \n\t" - - "replv.qb %[tmp1], %[tmp1] \n\t" - "replv.qb %[tmp2], %[tmp2] \n\t" - "replv.qb %[tmp3], %[tmp3] \n\t" - "replv.qb %[tmp4], %[tmp4] \n\t" - "replv.qb %[tmp5], %[tmp5] \n\t" - "replv.qb %[tmp6], %[tmp6] \n\t" - "replv.qb %[tmp7], %[tmp7] \n\t" - "replv.qb %[tmp8], %[tmp8] \n\t" - "replv.qb %[tmp9], %[tmp9] \n\t" - "replv.qb %[tmp10], %[tmp10] \n\t" - "replv.qb %[tmp11], %[tmp11] \n\t" - "replv.qb %[tmp12], %[tmp12] \n\t" - "replv.qb %[tmp13], %[tmp13] \n\t" - "replv.qb %[tmp14], %[tmp14] \n\t" - "replv.qb %[tmp15], %[tmp15] \n\t" - "replv.qb %[tmp16], %[tmp16] \n\t" - - "sw %[tmp1], (%[dst]) \n\t" - "sw %[tmp1], 4(%[dst]) \n\t" - "sw %[tmp1], 8(%[dst]) \n\t" - "sw %[tmp1], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp2], (%[dst]) \n\t" - "sw %[tmp2], 4(%[dst]) \n\t" - "sw %[tmp2], 8(%[dst]) \n\t" - "sw %[tmp2], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp3], (%[dst]) \n\t" - "sw %[tmp3], 4(%[dst]) \n\t" - "sw %[tmp3], 8(%[dst]) \n\t" - "sw %[tmp3], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp4], (%[dst]) \n\t" - "sw %[tmp4], 4(%[dst]) \n\t" - "sw %[tmp4], 8(%[dst]) \n\t" - "sw %[tmp4], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp5], (%[dst]) \n\t" - "sw %[tmp5], 4(%[dst]) \n\t" - "sw %[tmp5], 8(%[dst]) \n\t" - "sw %[tmp5], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp6], (%[dst]) \n\t" - "sw %[tmp6], 4(%[dst]) \n\t" - "sw %[tmp6], 8(%[dst]) \n\t" - "sw %[tmp6], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp7], (%[dst]) \n\t" - "sw %[tmp7], 4(%[dst]) \n\t" - "sw %[tmp7], 8(%[dst]) \n\t" - "sw %[tmp7], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp8], (%[dst]) \n\t" - "sw %[tmp8], 4(%[dst]) \n\t" - "sw %[tmp8], 8(%[dst]) \n\t" - "sw %[tmp8], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp9], (%[dst]) \n\t" - "sw %[tmp9], 4(%[dst]) \n\t" - "sw %[tmp9], 8(%[dst]) \n\t" - "sw %[tmp9], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp10], (%[dst]) \n\t" - "sw %[tmp10], 4(%[dst]) \n\t" - "sw %[tmp10], 8(%[dst]) \n\t" - "sw %[tmp10], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp11], (%[dst]) \n\t" - "sw %[tmp11], 4(%[dst]) \n\t" - "sw %[tmp11], 8(%[dst]) \n\t" - "sw %[tmp11], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp12], (%[dst]) \n\t" - "sw %[tmp12], 4(%[dst]) \n\t" - "sw %[tmp12], 8(%[dst]) \n\t" - "sw %[tmp12], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp13], (%[dst]) \n\t" - "sw %[tmp13], 4(%[dst]) \n\t" - "sw %[tmp13], 8(%[dst]) \n\t" - "sw %[tmp13], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp14], (%[dst]) \n\t" - "sw %[tmp14], 4(%[dst]) \n\t" - "sw %[tmp14], 8(%[dst]) \n\t" - "sw %[tmp14], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp15], (%[dst]) \n\t" - "sw %[tmp15], 4(%[dst]) \n\t" - "sw %[tmp15], 8(%[dst]) \n\t" - "sw %[tmp15], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp16], (%[dst]) \n\t" - "sw %[tmp16], 4(%[dst]) \n\t" - "sw %[tmp16], 8(%[dst]) \n\t" - "sw %[tmp16], 12(%[dst]) \n\t" - - : [tmp1] "=&r"(tmp1), [tmp2] "=&r"(tmp2), [tmp3] "=&r"(tmp3), - [tmp4] "=&r"(tmp4), [tmp5] "=&r"(tmp5), [tmp7] "=&r"(tmp7), - [tmp6] "=&r"(tmp6), [tmp8] "=&r"(tmp8), [tmp9] "=&r"(tmp9), - [tmp10] "=&r"(tmp10), [tmp11] "=&r"(tmp11), [tmp12] "=&r"(tmp12), - [tmp13] "=&r"(tmp13), [tmp14] "=&r"(tmp14), [tmp15] "=&r"(tmp15), - [tmp16] "=&r"(tmp16) - : [left] "r"(left), [dst] "r"(dst), [stride] "r"(stride)); -} - -void vpx_dc_predictor_16x16_dspr2(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - int32_t expected_dc; - int32_t average; - int32_t tmp, above1, above_l1, above_r1, left1, left_r1, left_l1; - int32_t above2, left2; - - __asm__ __volatile__( - "lw %[above1], (%[above]) \n\t" - "lw %[above2], 4(%[above]) \n\t" - "lw %[left1], (%[left]) \n\t" - "lw %[left2], 4(%[left]) \n\t" - - "preceu.ph.qbl %[above_l1], %[above1] \n\t" - "preceu.ph.qbr %[above_r1], %[above1] \n\t" - "preceu.ph.qbl %[left_l1], %[left1] \n\t" - "preceu.ph.qbr %[left_r1], %[left1] \n\t" - - "addu.ph %[average], %[above_r1], %[above_l1] \n\t" - "addu.ph %[average], %[average], %[left_l1] \n\t" - "addu.ph %[average], %[average], %[left_r1] \n\t" - - "preceu.ph.qbl %[above_l1], %[above2] \n\t" - "preceu.ph.qbr %[above_r1], %[above2] \n\t" - "preceu.ph.qbl %[left_l1], %[left2] \n\t" - "preceu.ph.qbr %[left_r1], %[left2] \n\t" - - "addu.ph %[average], %[average], %[above_l1] \n\t" - "addu.ph %[average], %[average], %[above_r1] \n\t" - "addu.ph %[average], %[average], %[left_l1] \n\t" - "addu.ph %[average], %[average], %[left_r1] \n\t" - - "lw %[above1], 8(%[above]) \n\t" - "lw %[above2], 12(%[above]) \n\t" - "lw %[left1], 8(%[left]) \n\t" - "lw %[left2], 12(%[left]) \n\t" - - "preceu.ph.qbl %[above_l1], %[above1] \n\t" - "preceu.ph.qbr %[above_r1], %[above1] \n\t" - "preceu.ph.qbl %[left_l1], %[left1] \n\t" - "preceu.ph.qbr %[left_r1], %[left1] \n\t" - - "addu.ph %[average], %[average], %[above_l1] \n\t" - "addu.ph %[average], %[average], %[above_r1] \n\t" - "addu.ph %[average], %[average], %[left_l1] \n\t" - "addu.ph %[average], %[average], %[left_r1] \n\t" - - "preceu.ph.qbl %[above_l1], %[above2] \n\t" - "preceu.ph.qbr %[above_r1], %[above2] \n\t" - "preceu.ph.qbl %[left_l1], %[left2] \n\t" - "preceu.ph.qbr %[left_r1], %[left2] \n\t" - - "addu.ph %[average], %[average], %[above_l1] \n\t" - "addu.ph %[average], %[average], %[above_r1] \n\t" - "addu.ph %[average], %[average], %[left_l1] \n\t" - "addu.ph %[average], %[average], %[left_r1] \n\t" - - "addiu %[average], %[average], 16 \n\t" - "srl %[tmp], %[average], 16 \n\t" - "addu.ph %[average], %[tmp], %[average] \n\t" - "srl %[expected_dc], %[average], 5 \n\t" - "replv.qb %[expected_dc], %[expected_dc] \n\t" - - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - "sw %[expected_dc], 8(%[dst]) \n\t" - "sw %[expected_dc], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - "sw %[expected_dc], 8(%[dst]) \n\t" - "sw %[expected_dc], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - "sw %[expected_dc], 8(%[dst]) \n\t" - "sw %[expected_dc], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - "sw %[expected_dc], 8(%[dst]) \n\t" - "sw %[expected_dc], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - "sw %[expected_dc], 8(%[dst]) \n\t" - "sw %[expected_dc], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - "sw %[expected_dc], 8(%[dst]) \n\t" - "sw %[expected_dc], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - "sw %[expected_dc], 8(%[dst]) \n\t" - "sw %[expected_dc], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - "sw %[expected_dc], 8(%[dst]) \n\t" - "sw %[expected_dc], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - "sw %[expected_dc], 8(%[dst]) \n\t" - "sw %[expected_dc], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - "sw %[expected_dc], 8(%[dst]) \n\t" - "sw %[expected_dc], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - "sw %[expected_dc], 8(%[dst]) \n\t" - "sw %[expected_dc], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - "sw %[expected_dc], 8(%[dst]) \n\t" - "sw %[expected_dc], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - "sw %[expected_dc], 8(%[dst]) \n\t" - "sw %[expected_dc], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - "sw %[expected_dc], 8(%[dst]) \n\t" - "sw %[expected_dc], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - "sw %[expected_dc], 8(%[dst]) \n\t" - "sw %[expected_dc], 12(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - "sw %[expected_dc], 8(%[dst]) \n\t" - "sw %[expected_dc], 12(%[dst]) \n\t" - - : [left1] "=&r"(left1), [above1] "=&r"(above1), [left_l1] "=&r"(left_l1), - [above_l1] "=&r"(above_l1), [left_r1] "=&r"(left_r1), - [above_r1] "=&r"(above_r1), [above2] "=&r"(above2), - [left2] "=&r"(left2), [average] "=&r"(average), [tmp] "=&r"(tmp), - [expected_dc] "=&r"(expected_dc) - : [above] "r"(above), [left] "r"(left), [dst] "r"(dst), - [stride] "r"(stride)); -} -#endif // #if HAVE_DSPR2 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/intrapred4_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/intrapred4_dspr2.c deleted file mode 100644 index dce03a2b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/intrapred4_dspr2.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_dsp/mips/common_dspr2.h" - -#if HAVE_DSPR2 -void vpx_h_predictor_4x4_dspr2(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - int32_t tmp1, tmp2, tmp3, tmp4; - (void)above; - - __asm__ __volatile__( - "lb %[tmp1], (%[left]) \n\t" - "lb %[tmp2], 1(%[left]) \n\t" - "lb %[tmp3], 2(%[left]) \n\t" - "lb %[tmp4], 3(%[left]) \n\t" - "replv.qb %[tmp1], %[tmp1] \n\t" - "replv.qb %[tmp2], %[tmp2] \n\t" - "replv.qb %[tmp3], %[tmp3] \n\t" - "replv.qb %[tmp4], %[tmp4] \n\t" - "sw %[tmp1], (%[dst]) \n\t" - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp2], (%[dst]) \n\t" - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp3], (%[dst]) \n\t" - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp4], (%[dst]) \n\t" - - : [tmp1] "=&r"(tmp1), [tmp2] "=&r"(tmp2), [tmp3] "=&r"(tmp3), - [tmp4] "=&r"(tmp4) - : [left] "r"(left), [dst] "r"(dst), [stride] "r"(stride)); -} - -void vpx_dc_predictor_4x4_dspr2(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - int32_t expected_dc; - int32_t average; - int32_t tmp, above_c, above_l, above_r, left_c, left_r, left_l; - - __asm__ __volatile__( - "lw %[above_c], (%[above]) \n\t" - "lw %[left_c], (%[left]) \n\t" - - "preceu.ph.qbl %[above_l], %[above_c] \n\t" - "preceu.ph.qbr %[above_r], %[above_c] \n\t" - "preceu.ph.qbl %[left_l], %[left_c] \n\t" - "preceu.ph.qbr %[left_r], %[left_c] \n\t" - - "addu.ph %[average], %[above_r], %[above_l] \n\t" - "addu.ph %[average], %[average], %[left_l] \n\t" - "addu.ph %[average], %[average], %[left_r] \n\t" - "addiu %[average], %[average], 4 \n\t" - "srl %[tmp], %[average], 16 \n\t" - "addu.ph %[average], %[tmp], %[average] \n\t" - "srl %[expected_dc], %[average], 3 \n\t" - "replv.qb %[expected_dc], %[expected_dc] \n\t" - - "sw %[expected_dc], (%[dst]) \n\t" - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - - : [above_c] "=&r"(above_c), [above_l] "=&r"(above_l), - [above_r] "=&r"(above_r), [left_c] "=&r"(left_c), - [left_l] "=&r"(left_l), [left_r] "=&r"(left_r), - [average] "=&r"(average), [tmp] "=&r"(tmp), - [expected_dc] "=&r"(expected_dc) - : [above] "r"(above), [left] "r"(left), [dst] "r"(dst), - [stride] "r"(stride)); -} - -void vpx_tm_predictor_4x4_dspr2(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - int32_t abovel, abover; - int32_t left0, left1, left2, left3; - int32_t res0, res1; - int32_t resl; - int32_t resr; - int32_t top_left; - uint8_t *cm = vpx_ff_cropTbl; - - __asm__ __volatile__( - "ulw %[resl], (%[above]) \n\t" - - "lbu %[left0], (%[left]) \n\t" - "lbu %[left1], 1(%[left]) \n\t" - "lbu %[left2], 2(%[left]) \n\t" - "lbu %[left3], 3(%[left]) \n\t" - - "lbu %[top_left], -1(%[above]) \n\t" - - "preceu.ph.qbl %[abovel], %[resl] \n\t" - "preceu.ph.qbr %[abover], %[resl] \n\t" - - "replv.ph %[left0], %[left0] \n\t" - "replv.ph %[left1], %[left1] \n\t" - "replv.ph %[left2], %[left2] \n\t" - "replv.ph %[left3], %[left3] \n\t" - - "replv.ph %[top_left], %[top_left] \n\t" - - "addu.ph %[resl], %[abovel], %[left0] \n\t" - "subu.ph %[resl], %[resl], %[top_left] \n\t" - - "addu.ph %[resr], %[abover], %[left0] \n\t" - "subu.ph %[resr], %[resr], %[top_left] \n\t" - - "sll %[res0], %[resr], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "lbux %[res0], %[res0](%[cm]) \n\t" - - "sra %[res1], %[resr], 16 \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "sb %[res0], (%[dst]) \n\t" - - "sll %[res0], %[resl], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "lbux %[res0], %[res0](%[cm]) \n\t" - "sb %[res1], 1(%[dst]) \n\t" - - "sra %[res1], %[resl], 16 \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - - "addu.ph %[resl], %[abovel], %[left1] \n\t" - "subu.ph %[resl], %[resl], %[top_left] \n\t" - - "addu.ph %[resr], %[abover], %[left1] \n\t" - "subu.ph %[resr], %[resr], %[top_left] \n\t" - - "sb %[res0], 2(%[dst]) \n\t" - "sb %[res1], 3(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - - "sll %[res0], %[resr], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "lbux %[res0], %[res0](%[cm]) \n\t" - - "sra %[res1], %[resr], 16 \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "sb %[res0], (%[dst]) \n\t" - - "sll %[res0], %[resl], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "lbux %[res0], %[res0](%[cm]) \n\t" - - "sb %[res1], 1(%[dst]) \n\t" - "sra %[res1], %[resl], 16 \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - - "addu.ph %[resl], %[abovel], %[left2] \n\t" - "subu.ph %[resl], %[resl], %[top_left] \n\t" - - "addu.ph %[resr], %[abover], %[left2] \n\t" - "subu.ph %[resr], %[resr], %[top_left] \n\t" - - "sb %[res0], 2(%[dst]) \n\t" - "sb %[res1], 3(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - - "sll %[res0], %[resr], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "lbux %[res0], %[res0](%[cm]) \n\t" - - "sra %[res1], %[resr], 16 \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "sb %[res0], (%[dst]) \n\t" - - "sll %[res0], %[resl], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "lbux %[res0], %[res0](%[cm]) \n\t" - - "sb %[res1], 1(%[dst]) \n\t" - "sra %[res1], %[resl], 16 \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - - "addu.ph %[resl], %[abovel], %[left3] \n\t" - "subu.ph %[resl], %[resl], %[top_left] \n\t" - - "addu.ph %[resr], %[abover], %[left3] \n\t" - "subu.ph %[resr], %[resr], %[top_left] \n\t" - - "sb %[res0], 2(%[dst]) \n\t" - "sb %[res1], 3(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - - "sll %[res0], %[resr], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "lbux %[res0], %[res0](%[cm]) \n\t" - - "sra %[res1], %[resr], 16 \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "sb %[res0], (%[dst]) \n\t" - - "sll %[res0], %[resl], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "lbux %[res0], %[res0](%[cm]) \n\t" - "sb %[res1], 1(%[dst]) \n\t" - - "sra %[res1], %[resl], 16 \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - - "sb %[res0], 2(%[dst]) \n\t" - "sb %[res1], 3(%[dst]) \n\t" - - : [abovel] "=&r"(abovel), [abover] "=&r"(abover), [left0] "=&r"(left0), - [left1] "=&r"(left1), [left2] "=&r"(left2), [res0] "=&r"(res0), - [res1] "=&r"(res1), [left3] "=&r"(left3), [resl] "=&r"(resl), - [resr] "=&r"(resr), [top_left] "=&r"(top_left) - : [above] "r"(above), [left] "r"(left), [dst] "r"(dst), - [stride] "r"(stride), [cm] "r"(cm)); -} -#endif // #if HAVE_DSPR2 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/intrapred8_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/intrapred8_dspr2.c deleted file mode 100644 index 16e7fc55..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/intrapred8_dspr2.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_dsp/mips/common_dspr2.h" - -#if HAVE_DSPR2 -void vpx_h_predictor_8x8_dspr2(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - int32_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; - (void)above; - - __asm__ __volatile__( - "lb %[tmp1], (%[left]) \n\t" - "lb %[tmp2], 1(%[left]) \n\t" - "lb %[tmp3], 2(%[left]) \n\t" - "lb %[tmp4], 3(%[left]) \n\t" - "lb %[tmp5], 4(%[left]) \n\t" - "lb %[tmp6], 5(%[left]) \n\t" - "lb %[tmp7], 6(%[left]) \n\t" - "lb %[tmp8], 7(%[left]) \n\t" - - "replv.qb %[tmp1], %[tmp1] \n\t" - "replv.qb %[tmp2], %[tmp2] \n\t" - "replv.qb %[tmp3], %[tmp3] \n\t" - "replv.qb %[tmp4], %[tmp4] \n\t" - "replv.qb %[tmp5], %[tmp5] \n\t" - "replv.qb %[tmp6], %[tmp6] \n\t" - "replv.qb %[tmp7], %[tmp7] \n\t" - "replv.qb %[tmp8], %[tmp8] \n\t" - - "sw %[tmp1], (%[dst]) \n\t" - "sw %[tmp1], 4(%[dst]) \n\t" - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp2], (%[dst]) \n\t" - "sw %[tmp2], 4(%[dst]) \n\t" - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp3], (%[dst]) \n\t" - "sw %[tmp3], 4(%[dst]) \n\t" - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp4], (%[dst]) \n\t" - "sw %[tmp4], 4(%[dst]) \n\t" - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp5], (%[dst]) \n\t" - "sw %[tmp5], 4(%[dst]) \n\t" - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp6], (%[dst]) \n\t" - "sw %[tmp6], 4(%[dst]) \n\t" - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp7], (%[dst]) \n\t" - "sw %[tmp7], 4(%[dst]) \n\t" - "add %[dst], %[dst], %[stride] \n\t" - "sw %[tmp8], (%[dst]) \n\t" - "sw %[tmp8], 4(%[dst]) \n\t" - - : [tmp1] "=&r"(tmp1), [tmp2] "=&r"(tmp2), [tmp3] "=&r"(tmp3), - [tmp4] "=&r"(tmp4), [tmp5] "=&r"(tmp5), [tmp7] "=&r"(tmp7), - [tmp6] "=&r"(tmp6), [tmp8] "=&r"(tmp8) - : [left] "r"(left), [dst] "r"(dst), [stride] "r"(stride)); -} - -void vpx_dc_predictor_8x8_dspr2(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - int32_t expected_dc; - int32_t average; - int32_t tmp, above1, above_l1, above_r1, left1, left_r1, left_l1; - int32_t above2, above_l2, above_r2, left2, left_r2, left_l2; - - __asm__ __volatile__( - "lw %[above1], (%[above]) \n\t" - "lw %[above2], 4(%[above]) \n\t" - "lw %[left1], (%[left]) \n\t" - "lw %[left2], 4(%[left]) \n\t" - - "preceu.ph.qbl %[above_l1], %[above1] \n\t" - "preceu.ph.qbr %[above_r1], %[above1] \n\t" - "preceu.ph.qbl %[left_l1], %[left1] \n\t" - "preceu.ph.qbr %[left_r1], %[left1] \n\t" - - "preceu.ph.qbl %[above_l2], %[above2] \n\t" - "preceu.ph.qbr %[above_r2], %[above2] \n\t" - "preceu.ph.qbl %[left_l2], %[left2] \n\t" - "preceu.ph.qbr %[left_r2], %[left2] \n\t" - - "addu.ph %[average], %[above_r1], %[above_l1] \n\t" - "addu.ph %[average], %[average], %[left_l1] \n\t" - "addu.ph %[average], %[average], %[left_r1] \n\t" - - "addu.ph %[average], %[average], %[above_l2] \n\t" - "addu.ph %[average], %[average], %[above_r2] \n\t" - "addu.ph %[average], %[average], %[left_l2] \n\t" - "addu.ph %[average], %[average], %[left_r2] \n\t" - - "addiu %[average], %[average], 8 \n\t" - - "srl %[tmp], %[average], 16 \n\t" - "addu.ph %[average], %[tmp], %[average] \n\t" - "srl %[expected_dc], %[average], 4 \n\t" - "replv.qb %[expected_dc], %[expected_dc] \n\t" - - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - - "add %[dst], %[dst], %[stride] \n\t" - "sw %[expected_dc], (%[dst]) \n\t" - "sw %[expected_dc], 4(%[dst]) \n\t" - - : [above1] "=&r"(above1), [above_l1] "=&r"(above_l1), - [above_r1] "=&r"(above_r1), [left1] "=&r"(left1), - [left_l1] "=&r"(left_l1), [left_r1] "=&r"(left_r1), - [above2] "=&r"(above2), [above_l2] "=&r"(above_l2), - [above_r2] "=&r"(above_r2), [left2] "=&r"(left2), - [left_l2] "=&r"(left_l2), [left_r2] "=&r"(left_r2), - [average] "=&r"(average), [tmp] "=&r"(tmp), - [expected_dc] "=&r"(expected_dc) - : [above] "r"(above), [left] "r"(left), [dst] "r"(dst), - [stride] "r"(stride)); -} - -void vpx_tm_predictor_8x8_dspr2(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - int32_t abovel, abover; - int32_t abovel_1, abover_1; - int32_t left0; - int32_t res0, res1, res2, res3; - int32_t reshw; - int32_t top_left; - uint8_t *cm = vpx_ff_cropTbl; - - __asm__ __volatile__( - "ulw %[reshw], (%[above]) \n\t" - "ulw %[top_left], 4(%[above]) \n\t" - - "lbu %[left0], (%[left]) \n\t" - - "preceu.ph.qbl %[abovel], %[reshw] \n\t" - "preceu.ph.qbr %[abover], %[reshw] \n\t" - "preceu.ph.qbl %[abovel_1], %[top_left] \n\t" - "preceu.ph.qbr %[abover_1], %[top_left] \n\t" - - "lbu %[top_left], -1(%[above]) \n\t" - "replv.ph %[left0], %[left0] \n\t" - - "replv.ph %[top_left], %[top_left] \n\t" - - "addu.ph %[reshw], %[abovel], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res2], %[reshw], 16 \n\t" - "sra %[res2], %[res2], 16 \n\t" - "sra %[res3], %[reshw], 16 \n\t" - - "addu.ph %[reshw], %[abover], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res0], %[reshw], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "sra %[res1], %[reshw], 16 \n\t" - - "lbux %[res0], %[res0](%[cm]) \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "lbux %[res2], %[res2](%[cm]) \n\t" - "lbux %[res3], %[res3](%[cm]) \n\t" - - "sb %[res0], (%[dst]) \n\t" - "sb %[res1], 1(%[dst]) \n\t" - "sb %[res2], 2(%[dst]) \n\t" - "sb %[res3], 3(%[dst]) \n\t" - - "addu.ph %[reshw], %[abovel_1], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res2], %[reshw], 16 \n\t" - "sra %[res2], %[res2], 16 \n\t" - "sra %[res3], %[reshw], 16 \n\t" - - "addu.ph %[reshw], %[abover_1], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res0], %[reshw], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "sra %[res1], %[reshw], 16 \n\t" - - "lbu %[left0], 1(%[left]) \n\t" - - "lbux %[res0], %[res0](%[cm]) \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "lbux %[res2], %[res2](%[cm]) \n\t" - "lbux %[res3], %[res3](%[cm]) \n\t" - - "sb %[res0], 4(%[dst]) \n\t" - "sb %[res1], 5(%[dst]) \n\t" - "sb %[res2], 6(%[dst]) \n\t" - "sb %[res3], 7(%[dst]) \n\t" - - "replv.ph %[left0], %[left0] \n\t" - "add %[dst], %[dst], %[stride] \n\t" - - "addu.ph %[reshw], %[abovel], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res2], %[reshw], 16 \n\t" - "sra %[res2], %[res2], 16 \n\t" - "sra %[res3], %[reshw], 16 \n\t" - - "addu.ph %[reshw], %[abover], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res0], %[reshw], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "sra %[res1], %[reshw], 16 \n\t" - - "lbux %[res0], %[res0](%[cm]) \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "lbux %[res2], %[res2](%[cm]) \n\t" - "lbux %[res3], %[res3](%[cm]) \n\t" - - "sb %[res0], (%[dst]) \n\t" - "sb %[res1], 1(%[dst]) \n\t" - "sb %[res2], 2(%[dst]) \n\t" - "sb %[res3], 3(%[dst]) \n\t" - - "addu.ph %[reshw], %[abovel_1], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res2], %[reshw], 16 \n\t" - "sra %[res2], %[res2], 16 \n\t" - "sra %[res3], %[reshw], 16 \n\t" - - "addu.ph %[reshw], %[abover_1], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res0], %[reshw], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "sra %[res1], %[reshw], 16 \n\t" - - "lbu %[left0], 2(%[left]) \n\t" - - "lbux %[res0], %[res0](%[cm]) \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "lbux %[res2], %[res2](%[cm]) \n\t" - "lbux %[res3], %[res3](%[cm]) \n\t" - - "sb %[res0], 4(%[dst]) \n\t" - "sb %[res1], 5(%[dst]) \n\t" - "sb %[res2], 6(%[dst]) \n\t" - "sb %[res3], 7(%[dst]) \n\t" - - "replv.ph %[left0], %[left0] \n\t" - "add %[dst], %[dst], %[stride] \n\t" - - "addu.ph %[reshw], %[abovel], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res2], %[reshw], 16 \n\t" - "sra %[res2], %[res2], 16 \n\t" - "sra %[res3], %[reshw], 16 \n\t" - - "addu.ph %[reshw], %[abover], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res0], %[reshw], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "sra %[res1], %[reshw], 16 \n\t" - - "lbux %[res0], %[res0](%[cm]) \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "lbux %[res2], %[res2](%[cm]) \n\t" - "lbux %[res3], %[res3](%[cm]) \n\t" - - "sb %[res0], (%[dst]) \n\t" - "sb %[res1], 1(%[dst]) \n\t" - "sb %[res2], 2(%[dst]) \n\t" - "sb %[res3], 3(%[dst]) \n\t" - - "addu.ph %[reshw], %[abovel_1], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res2], %[reshw], 16 \n\t" - "sra %[res2], %[res2], 16 \n\t" - "sra %[res3], %[reshw], 16 \n\t" - - "addu.ph %[reshw], %[abover_1], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res0], %[reshw], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "sra %[res1], %[reshw], 16 \n\t" - - "lbu %[left0], 3(%[left]) \n\t" - - "lbux %[res0], %[res0](%[cm]) \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "lbux %[res2], %[res2](%[cm]) \n\t" - "lbux %[res3], %[res3](%[cm]) \n\t" - - "sb %[res0], 4(%[dst]) \n\t" - "sb %[res1], 5(%[dst]) \n\t" - "sb %[res2], 6(%[dst]) \n\t" - "sb %[res3], 7(%[dst]) \n\t" - - "replv.ph %[left0], %[left0] \n\t" - "add %[dst], %[dst], %[stride] \n\t" - - "addu.ph %[reshw], %[abovel], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res2], %[reshw], 16 \n\t" - "sra %[res2], %[res2], 16 \n\t" - "sra %[res3], %[reshw], 16 \n\t" - - "addu.ph %[reshw], %[abover], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res0], %[reshw], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "sra %[res1], %[reshw], 16 \n\t" - - "lbux %[res0], %[res0](%[cm]) \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "lbux %[res2], %[res2](%[cm]) \n\t" - "lbux %[res3], %[res3](%[cm]) \n\t" - - "sb %[res0], (%[dst]) \n\t" - "sb %[res1], 1(%[dst]) \n\t" - "sb %[res2], 2(%[dst]) \n\t" - "sb %[res3], 3(%[dst]) \n\t" - - "addu.ph %[reshw], %[abovel_1], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res2], %[reshw], 16 \n\t" - "sra %[res2], %[res2], 16 \n\t" - "sra %[res3], %[reshw], 16 \n\t" - - "addu.ph %[reshw], %[abover_1], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res0], %[reshw], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "sra %[res1], %[reshw], 16 \n\t" - - "lbu %[left0], 4(%[left]) \n\t" - - "lbux %[res0], %[res0](%[cm]) \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "lbux %[res2], %[res2](%[cm]) \n\t" - "lbux %[res3], %[res3](%[cm]) \n\t" - - "sb %[res0], 4(%[dst]) \n\t" - "sb %[res1], 5(%[dst]) \n\t" - "sb %[res2], 6(%[dst]) \n\t" - "sb %[res3], 7(%[dst]) \n\t" - - "replv.ph %[left0], %[left0] \n\t" - "add %[dst], %[dst], %[stride] \n\t" - - "addu.ph %[reshw], %[abovel], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res2], %[reshw], 16 \n\t" - "sra %[res2], %[res2], 16 \n\t" - "sra %[res3], %[reshw], 16 \n\t" - - "addu.ph %[reshw], %[abover], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res0], %[reshw], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "sra %[res1], %[reshw], 16 \n\t" - - "lbux %[res0], %[res0](%[cm]) \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "lbux %[res2], %[res2](%[cm]) \n\t" - "lbux %[res3], %[res3](%[cm]) \n\t" - - "sb %[res0], (%[dst]) \n\t" - "sb %[res1], 1(%[dst]) \n\t" - "sb %[res2], 2(%[dst]) \n\t" - "sb %[res3], 3(%[dst]) \n\t" - - "addu.ph %[reshw], %[abovel_1], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res2], %[reshw], 16 \n\t" - "sra %[res2], %[res2], 16 \n\t" - "sra %[res3], %[reshw], 16 \n\t" - - "addu.ph %[reshw], %[abover_1], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res0], %[reshw], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "sra %[res1], %[reshw], 16 \n\t" - - "lbu %[left0], 5(%[left]) \n\t" - - "lbux %[res0], %[res0](%[cm]) \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "lbux %[res2], %[res2](%[cm]) \n\t" - "lbux %[res3], %[res3](%[cm]) \n\t" - - "sb %[res0], 4(%[dst]) \n\t" - "sb %[res1], 5(%[dst]) \n\t" - "sb %[res2], 6(%[dst]) \n\t" - "sb %[res3], 7(%[dst]) \n\t" - - "replv.ph %[left0], %[left0] \n\t" - "add %[dst], %[dst], %[stride] \n\t" - - "addu.ph %[reshw], %[abovel], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res2], %[reshw], 16 \n\t" - "sra %[res2], %[res2], 16 \n\t" - "sra %[res3], %[reshw], 16 \n\t" - - "addu.ph %[reshw], %[abover], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res0], %[reshw], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "sra %[res1], %[reshw], 16 \n\t" - - "lbux %[res0], %[res0](%[cm]) \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "lbux %[res2], %[res2](%[cm]) \n\t" - "lbux %[res3], %[res3](%[cm]) \n\t" - - "sb %[res0], (%[dst]) \n\t" - "sb %[res1], 1(%[dst]) \n\t" - "sb %[res2], 2(%[dst]) \n\t" - "sb %[res3], 3(%[dst]) \n\t" - - "addu.ph %[reshw], %[abovel_1], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res2], %[reshw], 16 \n\t" - "sra %[res2], %[res2], 16 \n\t" - "sra %[res3], %[reshw], 16 \n\t" - - "addu.ph %[reshw], %[abover_1], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res0], %[reshw], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "sra %[res1], %[reshw], 16 \n\t" - - "lbu %[left0], 6(%[left]) \n\t" - - "lbux %[res0], %[res0](%[cm]) \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "lbux %[res2], %[res2](%[cm]) \n\t" - "lbux %[res3], %[res3](%[cm]) \n\t" - - "sb %[res0], 4(%[dst]) \n\t" - "sb %[res1], 5(%[dst]) \n\t" - "sb %[res2], 6(%[dst]) \n\t" - "sb %[res3], 7(%[dst]) \n\t" - - "replv.ph %[left0], %[left0] \n\t" - "add %[dst], %[dst], %[stride] \n\t" - - "addu.ph %[reshw], %[abovel], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res2], %[reshw], 16 \n\t" - "sra %[res2], %[res2], 16 \n\t" - "sra %[res3], %[reshw], 16 \n\t" - - "addu.ph %[reshw], %[abover], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res0], %[reshw], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "sra %[res1], %[reshw], 16 \n\t" - - "lbux %[res0], %[res0](%[cm]) \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "lbux %[res2], %[res2](%[cm]) \n\t" - "lbux %[res3], %[res3](%[cm]) \n\t" - - "sb %[res0], (%[dst]) \n\t" - "sb %[res1], 1(%[dst]) \n\t" - "sb %[res2], 2(%[dst]) \n\t" - "sb %[res3], 3(%[dst]) \n\t" - - "addu.ph %[reshw], %[abovel_1], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res2], %[reshw], 16 \n\t" - "sra %[res2], %[res2], 16 \n\t" - "sra %[res3], %[reshw], 16 \n\t" - - "addu.ph %[reshw], %[abover_1], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res0], %[reshw], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "sra %[res1], %[reshw], 16 \n\t" - - "lbu %[left0], 7(%[left]) \n\t" - - "lbux %[res0], %[res0](%[cm]) \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "lbux %[res2], %[res2](%[cm]) \n\t" - "lbux %[res3], %[res3](%[cm]) \n\t" - - "sb %[res0], 4(%[dst]) \n\t" - "sb %[res1], 5(%[dst]) \n\t" - "sb %[res2], 6(%[dst]) \n\t" - "sb %[res3], 7(%[dst]) \n\t" - - "replv.ph %[left0], %[left0] \n\t" - "add %[dst], %[dst], %[stride] \n\t" - - "addu.ph %[reshw], %[abovel], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res2], %[reshw], 16 \n\t" - "sra %[res2], %[res2], 16 \n\t" - "sra %[res3], %[reshw], 16 \n\t" - - "addu.ph %[reshw], %[abover], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res0], %[reshw], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "sra %[res1], %[reshw], 16 \n\t" - - "lbux %[res0], %[res0](%[cm]) \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "lbux %[res2], %[res2](%[cm]) \n\t" - "lbux %[res3], %[res3](%[cm]) \n\t" - - "sb %[res0], (%[dst]) \n\t" - "sb %[res1], 1(%[dst]) \n\t" - "sb %[res2], 2(%[dst]) \n\t" - "sb %[res3], 3(%[dst]) \n\t" - - "addu.ph %[reshw], %[abovel_1], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res2], %[reshw], 16 \n\t" - "sra %[res2], %[res2], 16 \n\t" - "sra %[res3], %[reshw], 16 \n\t" - - "addu.ph %[reshw], %[abover_1], %[left0] \n\t" - "subu.ph %[reshw], %[reshw], %[top_left] \n\t" - - "sll %[res0], %[reshw], 16 \n\t" - "sra %[res0], %[res0], 16 \n\t" - "sra %[res1], %[reshw], 16 \n\t" - - "lbux %[res0], %[res0](%[cm]) \n\t" - "lbux %[res1], %[res1](%[cm]) \n\t" - "lbux %[res2], %[res2](%[cm]) \n\t" - "lbux %[res3], %[res3](%[cm]) \n\t" - - "sb %[res0], 4(%[dst]) \n\t" - "sb %[res1], 5(%[dst]) \n\t" - "sb %[res2], 6(%[dst]) \n\t" - "sb %[res3], 7(%[dst]) \n\t" - - : [abovel] "=&r"(abovel), [abover] "=&r"(abover), - [abovel_1] "=&r"(abovel_1), [abover_1] "=&r"(abover_1), - [left0] "=&r"(left0), [res2] "=&r"(res2), [res3] "=&r"(res3), - [res0] "=&r"(res0), [res1] "=&r"(res1), [reshw] "=&r"(reshw), - [top_left] "=&r"(top_left) - : [above] "r"(above), [left] "r"(left), [dst] "r"(dst), - [stride] "r"(stride), [cm] "r"(cm)); -} -#endif // #if HAVE_DSPR2 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/intrapred_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/intrapred_msa.c deleted file mode 100644 index b5ee9430..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/intrapred_msa.c +++ /dev/null @@ -1,738 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/macros_msa.h" - -#define IPRED_SUBS_UH2_UH(in0, in1, out0, out1) \ - { \ - out0 = __msa_subs_u_h(out0, in0); \ - out1 = __msa_subs_u_h(out1, in1); \ - } - -static void intra_predict_vert_4x4_msa(const uint8_t *src, uint8_t *dst, - int32_t dst_stride) { - uint32_t src_data; - - src_data = LW(src); - - SW4(src_data, src_data, src_data, src_data, dst, dst_stride); -} - -static void intra_predict_vert_8x8_msa(const uint8_t *src, uint8_t *dst, - int32_t dst_stride) { - uint32_t row; - uint32_t src_data1, src_data2; - - src_data1 = LW(src); - src_data2 = LW(src + 4); - - for (row = 8; row--;) { - SW(src_data1, dst); - SW(src_data2, (dst + 4)); - dst += dst_stride; - } -} - -static void intra_predict_vert_16x16_msa(const uint8_t *src, uint8_t *dst, - int32_t dst_stride) { - uint32_t row; - v16u8 src0; - - src0 = LD_UB(src); - - for (row = 16; row--;) { - ST_UB(src0, dst); - dst += dst_stride; - } -} - -static void intra_predict_vert_32x32_msa(const uint8_t *src, uint8_t *dst, - int32_t dst_stride) { - uint32_t row; - v16u8 src1, src2; - - src1 = LD_UB(src); - src2 = LD_UB(src + 16); - - for (row = 32; row--;) { - ST_UB2(src1, src2, dst, 16); - dst += dst_stride; - } -} - -static void intra_predict_horiz_4x4_msa(const uint8_t *src, uint8_t *dst, - int32_t dst_stride) { - uint32_t out0, out1, out2, out3; - - out0 = src[0] * 0x01010101; - out1 = src[1] * 0x01010101; - out2 = src[2] * 0x01010101; - out3 = src[3] * 0x01010101; - - SW4(out0, out1, out2, out3, dst, dst_stride); -} - -static void intra_predict_horiz_8x8_msa(const uint8_t *src, uint8_t *dst, - int32_t dst_stride) { - uint64_t out0, out1, out2, out3, out4, out5, out6, out7; - - out0 = src[0] * 0x0101010101010101ull; - out1 = src[1] * 0x0101010101010101ull; - out2 = src[2] * 0x0101010101010101ull; - out3 = src[3] * 0x0101010101010101ull; - out4 = src[4] * 0x0101010101010101ull; - out5 = src[5] * 0x0101010101010101ull; - out6 = src[6] * 0x0101010101010101ull; - out7 = src[7] * 0x0101010101010101ull; - - SD4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - SD4(out4, out5, out6, out7, dst, dst_stride); -} - -static void intra_predict_horiz_16x16_msa(const uint8_t *src, uint8_t *dst, - int32_t dst_stride) { - uint32_t row; - uint8_t inp0, inp1, inp2, inp3; - v16u8 src0, src1, src2, src3; - - for (row = 4; row--;) { - inp0 = src[0]; - inp1 = src[1]; - inp2 = src[2]; - inp3 = src[3]; - src += 4; - - src0 = (v16u8)__msa_fill_b(inp0); - src1 = (v16u8)__msa_fill_b(inp1); - src2 = (v16u8)__msa_fill_b(inp2); - src3 = (v16u8)__msa_fill_b(inp3); - - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - dst += (4 * dst_stride); - } -} - -static void intra_predict_horiz_32x32_msa(const uint8_t *src, uint8_t *dst, - int32_t dst_stride) { - uint32_t row; - uint8_t inp0, inp1, inp2, inp3; - v16u8 src0, src1, src2, src3; - - for (row = 8; row--;) { - inp0 = src[0]; - inp1 = src[1]; - inp2 = src[2]; - inp3 = src[3]; - src += 4; - - src0 = (v16u8)__msa_fill_b(inp0); - src1 = (v16u8)__msa_fill_b(inp1); - src2 = (v16u8)__msa_fill_b(inp2); - src3 = (v16u8)__msa_fill_b(inp3); - - ST_UB2(src0, src0, dst, 16); - dst += dst_stride; - ST_UB2(src1, src1, dst, 16); - dst += dst_stride; - ST_UB2(src2, src2, dst, 16); - dst += dst_stride; - ST_UB2(src3, src3, dst, 16); - dst += dst_stride; - } -} - -static void intra_predict_dc_4x4_msa(const uint8_t *src_top, - const uint8_t *src_left, uint8_t *dst, - int32_t dst_stride) { - uint32_t val0, val1; - v16i8 store, src = { 0 }; - v8u16 sum_h; - v4u32 sum_w; - v2u64 sum_d; - - val0 = LW(src_top); - val1 = LW(src_left); - INSERT_W2_SB(val0, val1, src); - sum_h = __msa_hadd_u_h((v16u8)src, (v16u8)src); - sum_w = __msa_hadd_u_w(sum_h, sum_h); - sum_d = __msa_hadd_u_d(sum_w, sum_w); - sum_w = (v4u32)__msa_srari_w((v4i32)sum_d, 3); - store = __msa_splati_b((v16i8)sum_w, 0); - val0 = __msa_copy_u_w((v4i32)store, 0); - - SW4(val0, val0, val0, val0, dst, dst_stride); -} - -static void intra_predict_dc_tl_4x4_msa(const uint8_t *src, uint8_t *dst, - int32_t dst_stride) { - uint32_t val0; - v16i8 store, data = { 0 }; - v8u16 sum_h; - v4u32 sum_w; - - val0 = LW(src); - data = (v16i8)__msa_insert_w((v4i32)data, 0, val0); - sum_h = __msa_hadd_u_h((v16u8)data, (v16u8)data); - sum_w = __msa_hadd_u_w(sum_h, sum_h); - sum_w = (v4u32)__msa_srari_w((v4i32)sum_w, 2); - store = __msa_splati_b((v16i8)sum_w, 0); - val0 = __msa_copy_u_w((v4i32)store, 0); - - SW4(val0, val0, val0, val0, dst, dst_stride); -} - -static void intra_predict_128dc_4x4_msa(uint8_t *dst, int32_t dst_stride) { - uint32_t out; - const v16i8 store = __msa_ldi_b(128); - - out = __msa_copy_u_w((v4i32)store, 0); - - SW4(out, out, out, out, dst, dst_stride); -} - -static void intra_predict_dc_8x8_msa(const uint8_t *src_top, - const uint8_t *src_left, uint8_t *dst, - int32_t dst_stride) { - uint64_t val0, val1; - v16i8 store; - v16u8 src = { 0 }; - v8u16 sum_h; - v4u32 sum_w; - v2u64 sum_d; - - val0 = LD(src_top); - val1 = LD(src_left); - INSERT_D2_UB(val0, val1, src); - sum_h = __msa_hadd_u_h(src, src); - sum_w = __msa_hadd_u_w(sum_h, sum_h); - sum_d = __msa_hadd_u_d(sum_w, sum_w); - sum_w = (v4u32)__msa_pckev_w((v4i32)sum_d, (v4i32)sum_d); - sum_d = __msa_hadd_u_d(sum_w, sum_w); - sum_w = (v4u32)__msa_srari_w((v4i32)sum_d, 4); - store = __msa_splati_b((v16i8)sum_w, 0); - val0 = __msa_copy_u_d((v2i64)store, 0); - - SD4(val0, val0, val0, val0, dst, dst_stride); - dst += (4 * dst_stride); - SD4(val0, val0, val0, val0, dst, dst_stride); -} - -static void intra_predict_dc_tl_8x8_msa(const uint8_t *src, uint8_t *dst, - int32_t dst_stride) { - uint64_t val0; - v16i8 store; - v16u8 data = { 0 }; - v8u16 sum_h; - v4u32 sum_w; - v2u64 sum_d; - - val0 = LD(src); - data = (v16u8)__msa_insert_d((v2i64)data, 0, val0); - sum_h = __msa_hadd_u_h(data, data); - sum_w = __msa_hadd_u_w(sum_h, sum_h); - sum_d = __msa_hadd_u_d(sum_w, sum_w); - sum_w = (v4u32)__msa_srari_w((v4i32)sum_d, 3); - store = __msa_splati_b((v16i8)sum_w, 0); - val0 = __msa_copy_u_d((v2i64)store, 0); - - SD4(val0, val0, val0, val0, dst, dst_stride); - dst += (4 * dst_stride); - SD4(val0, val0, val0, val0, dst, dst_stride); -} - -static void intra_predict_128dc_8x8_msa(uint8_t *dst, int32_t dst_stride) { - uint64_t out; - const v16i8 store = __msa_ldi_b(128); - - out = __msa_copy_u_d((v2i64)store, 0); - - SD4(out, out, out, out, dst, dst_stride); - dst += (4 * dst_stride); - SD4(out, out, out, out, dst, dst_stride); -} - -static void intra_predict_dc_16x16_msa(const uint8_t *src_top, - const uint8_t *src_left, uint8_t *dst, - int32_t dst_stride) { - v16u8 top, left, out; - v8u16 sum_h, sum_top, sum_left; - v4u32 sum_w; - v2u64 sum_d; - - top = LD_UB(src_top); - left = LD_UB(src_left); - HADD_UB2_UH(top, left, sum_top, sum_left); - sum_h = sum_top + sum_left; - sum_w = __msa_hadd_u_w(sum_h, sum_h); - sum_d = __msa_hadd_u_d(sum_w, sum_w); - sum_w = (v4u32)__msa_pckev_w((v4i32)sum_d, (v4i32)sum_d); - sum_d = __msa_hadd_u_d(sum_w, sum_w); - sum_w = (v4u32)__msa_srari_w((v4i32)sum_d, 5); - out = (v16u8)__msa_splati_b((v16i8)sum_w, 0); - - ST_UB8(out, out, out, out, out, out, out, out, dst, dst_stride); - dst += (8 * dst_stride); - ST_UB8(out, out, out, out, out, out, out, out, dst, dst_stride); -} - -static void intra_predict_dc_tl_16x16_msa(const uint8_t *src, uint8_t *dst, - int32_t dst_stride) { - v16u8 data, out; - v8u16 sum_h; - v4u32 sum_w; - v2u64 sum_d; - - data = LD_UB(src); - sum_h = __msa_hadd_u_h(data, data); - sum_w = __msa_hadd_u_w(sum_h, sum_h); - sum_d = __msa_hadd_u_d(sum_w, sum_w); - sum_w = (v4u32)__msa_pckev_w((v4i32)sum_d, (v4i32)sum_d); - sum_d = __msa_hadd_u_d(sum_w, sum_w); - sum_w = (v4u32)__msa_srari_w((v4i32)sum_d, 4); - out = (v16u8)__msa_splati_b((v16i8)sum_w, 0); - - ST_UB8(out, out, out, out, out, out, out, out, dst, dst_stride); - dst += (8 * dst_stride); - ST_UB8(out, out, out, out, out, out, out, out, dst, dst_stride); -} - -static void intra_predict_128dc_16x16_msa(uint8_t *dst, int32_t dst_stride) { - const v16u8 out = (v16u8)__msa_ldi_b(128); - - ST_UB8(out, out, out, out, out, out, out, out, dst, dst_stride); - dst += (8 * dst_stride); - ST_UB8(out, out, out, out, out, out, out, out, dst, dst_stride); -} - -static void intra_predict_dc_32x32_msa(const uint8_t *src_top, - const uint8_t *src_left, uint8_t *dst, - int32_t dst_stride) { - uint32_t row; - v16u8 top0, top1, left0, left1, out; - v8u16 sum_h, sum_top0, sum_top1, sum_left0, sum_left1; - v4u32 sum_w; - v2u64 sum_d; - - LD_UB2(src_top, 16, top0, top1); - LD_UB2(src_left, 16, left0, left1); - HADD_UB2_UH(top0, top1, sum_top0, sum_top1); - HADD_UB2_UH(left0, left1, sum_left0, sum_left1); - sum_h = sum_top0 + sum_top1; - sum_h += sum_left0 + sum_left1; - sum_w = __msa_hadd_u_w(sum_h, sum_h); - sum_d = __msa_hadd_u_d(sum_w, sum_w); - sum_w = (v4u32)__msa_pckev_w((v4i32)sum_d, (v4i32)sum_d); - sum_d = __msa_hadd_u_d(sum_w, sum_w); - sum_w = (v4u32)__msa_srari_w((v4i32)sum_d, 6); - out = (v16u8)__msa_splati_b((v16i8)sum_w, 0); - - for (row = 16; row--;) { - ST_UB2(out, out, dst, 16); - dst += dst_stride; - ST_UB2(out, out, dst, 16); - dst += dst_stride; - } -} - -static void intra_predict_dc_tl_32x32_msa(const uint8_t *src, uint8_t *dst, - int32_t dst_stride) { - uint32_t row; - v16u8 data0, data1, out; - v8u16 sum_h, sum_data0, sum_data1; - v4u32 sum_w; - v2u64 sum_d; - - LD_UB2(src, 16, data0, data1); - HADD_UB2_UH(data0, data1, sum_data0, sum_data1); - sum_h = sum_data0 + sum_data1; - sum_w = __msa_hadd_u_w(sum_h, sum_h); - sum_d = __msa_hadd_u_d(sum_w, sum_w); - sum_w = (v4u32)__msa_pckev_w((v4i32)sum_d, (v4i32)sum_d); - sum_d = __msa_hadd_u_d(sum_w, sum_w); - sum_w = (v4u32)__msa_srari_w((v4i32)sum_d, 5); - out = (v16u8)__msa_splati_b((v16i8)sum_w, 0); - - for (row = 16; row--;) { - ST_UB2(out, out, dst, 16); - dst += dst_stride; - ST_UB2(out, out, dst, 16); - dst += dst_stride; - } -} - -static void intra_predict_128dc_32x32_msa(uint8_t *dst, int32_t dst_stride) { - uint32_t row; - const v16u8 out = (v16u8)__msa_ldi_b(128); - - for (row = 16; row--;) { - ST_UB2(out, out, dst, 16); - dst += dst_stride; - ST_UB2(out, out, dst, 16); - dst += dst_stride; - } -} - -static void intra_predict_tm_4x4_msa(const uint8_t *src_top_ptr, - const uint8_t *src_left, uint8_t *dst, - int32_t dst_stride) { - uint32_t val; - uint8_t top_left = src_top_ptr[-1]; - v16i8 src_left0, src_left1, src_left2, src_left3, tmp0, tmp1, src_top = { 0 }; - v16u8 src0, src1, src2, src3; - v8u16 src_top_left, vec0, vec1, vec2, vec3; - - src_top_left = (v8u16)__msa_fill_h(top_left); - val = LW(src_top_ptr); - src_top = (v16i8)__msa_insert_w((v4i32)src_top, 0, val); - - src_left0 = __msa_fill_b(src_left[0]); - src_left1 = __msa_fill_b(src_left[1]); - src_left2 = __msa_fill_b(src_left[2]); - src_left3 = __msa_fill_b(src_left[3]); - - ILVR_B4_UB(src_left0, src_top, src_left1, src_top, src_left2, src_top, - src_left3, src_top, src0, src1, src2, src3); - HADD_UB4_UH(src0, src1, src2, src3, vec0, vec1, vec2, vec3); - IPRED_SUBS_UH2_UH(src_top_left, src_top_left, vec0, vec1); - IPRED_SUBS_UH2_UH(src_top_left, src_top_left, vec2, vec3); - SAT_UH4_UH(vec0, vec1, vec2, vec3, 7); - PCKEV_B2_SB(vec1, vec0, vec3, vec2, tmp0, tmp1); - ST4x4_UB(tmp0, tmp1, 0, 2, 0, 2, dst, dst_stride); -} - -static void intra_predict_tm_8x8_msa(const uint8_t *src_top_ptr, - const uint8_t *src_left, uint8_t *dst, - int32_t dst_stride) { - uint64_t val; - uint8_t top_left = src_top_ptr[-1]; - uint32_t loop_cnt; - v16i8 src_left0, src_left1, src_left2, src_left3, tmp0, tmp1, src_top = { 0 }; - v8u16 src_top_left, vec0, vec1, vec2, vec3; - v16u8 src0, src1, src2, src3; - - val = LD(src_top_ptr); - src_top = (v16i8)__msa_insert_d((v2i64)src_top, 0, val); - src_top_left = (v8u16)__msa_fill_h(top_left); - - for (loop_cnt = 2; loop_cnt--;) { - src_left0 = __msa_fill_b(src_left[0]); - src_left1 = __msa_fill_b(src_left[1]); - src_left2 = __msa_fill_b(src_left[2]); - src_left3 = __msa_fill_b(src_left[3]); - src_left += 4; - - ILVR_B4_UB(src_left0, src_top, src_left1, src_top, src_left2, src_top, - src_left3, src_top, src0, src1, src2, src3); - HADD_UB4_UH(src0, src1, src2, src3, vec0, vec1, vec2, vec3); - IPRED_SUBS_UH2_UH(src_top_left, src_top_left, vec0, vec1); - IPRED_SUBS_UH2_UH(src_top_left, src_top_left, vec2, vec3); - SAT_UH4_UH(vec0, vec1, vec2, vec3, 7); - PCKEV_B2_SB(vec1, vec0, vec3, vec2, tmp0, tmp1); - ST8x4_UB(tmp0, tmp1, dst, dst_stride); - dst += (4 * dst_stride); - } -} - -static void intra_predict_tm_16x16_msa(const uint8_t *src_top_ptr, - const uint8_t *src_left, uint8_t *dst, - int32_t dst_stride) { - uint8_t top_left = src_top_ptr[-1]; - uint32_t loop_cnt; - v16i8 src_top, src_left0, src_left1, src_left2, src_left3; - v8u16 src_top_left, res_r, res_l; - - src_top = LD_SB(src_top_ptr); - src_top_left = (v8u16)__msa_fill_h(top_left); - - for (loop_cnt = 4; loop_cnt--;) { - src_left0 = __msa_fill_b(src_left[0]); - src_left1 = __msa_fill_b(src_left[1]); - src_left2 = __msa_fill_b(src_left[2]); - src_left3 = __msa_fill_b(src_left[3]); - src_left += 4; - - ILVRL_B2_UH(src_left0, src_top, res_r, res_l); - HADD_UB2_UH(res_r, res_l, res_r, res_l); - IPRED_SUBS_UH2_UH(src_top_left, src_top_left, res_r, res_l); - - SAT_UH2_UH(res_r, res_l, 7); - PCKEV_ST_SB(res_r, res_l, dst); - dst += dst_stride; - - ILVRL_B2_UH(src_left1, src_top, res_r, res_l); - HADD_UB2_UH(res_r, res_l, res_r, res_l); - IPRED_SUBS_UH2_UH(src_top_left, src_top_left, res_r, res_l); - SAT_UH2_UH(res_r, res_l, 7); - PCKEV_ST_SB(res_r, res_l, dst); - dst += dst_stride; - - ILVRL_B2_UH(src_left2, src_top, res_r, res_l); - HADD_UB2_UH(res_r, res_l, res_r, res_l); - IPRED_SUBS_UH2_UH(src_top_left, src_top_left, res_r, res_l); - SAT_UH2_UH(res_r, res_l, 7); - PCKEV_ST_SB(res_r, res_l, dst); - dst += dst_stride; - - ILVRL_B2_UH(src_left3, src_top, res_r, res_l); - HADD_UB2_UH(res_r, res_l, res_r, res_l); - IPRED_SUBS_UH2_UH(src_top_left, src_top_left, res_r, res_l); - SAT_UH2_UH(res_r, res_l, 7); - PCKEV_ST_SB(res_r, res_l, dst); - dst += dst_stride; - } -} - -static void intra_predict_tm_32x32_msa(const uint8_t *src_top, - const uint8_t *src_left, uint8_t *dst, - int32_t dst_stride) { - uint8_t top_left = src_top[-1]; - uint32_t loop_cnt; - v16i8 src_top0, src_top1, src_left0, src_left1, src_left2, src_left3; - v8u16 src_top_left, res_r0, res_r1, res_l0, res_l1; - - LD_SB2(src_top, 16, src_top0, src_top1); - src_top_left = (v8u16)__msa_fill_h(top_left); - - for (loop_cnt = 8; loop_cnt--;) { - src_left0 = __msa_fill_b(src_left[0]); - src_left1 = __msa_fill_b(src_left[1]); - src_left2 = __msa_fill_b(src_left[2]); - src_left3 = __msa_fill_b(src_left[3]); - src_left += 4; - - ILVR_B2_UH(src_left0, src_top0, src_left0, src_top1, res_r0, res_r1); - ILVL_B2_UH(src_left0, src_top0, src_left0, src_top1, res_l0, res_l1); - HADD_UB4_UH(res_r0, res_l0, res_r1, res_l1, res_r0, res_l0, res_r1, res_l1); - IPRED_SUBS_UH2_UH(src_top_left, src_top_left, res_r0, res_l0); - IPRED_SUBS_UH2_UH(src_top_left, src_top_left, res_r1, res_l1); - SAT_UH4_UH(res_r0, res_l0, res_r1, res_l1, 7); - PCKEV_ST_SB(res_r0, res_l0, dst); - PCKEV_ST_SB(res_r1, res_l1, dst + 16); - dst += dst_stride; - - ILVR_B2_UH(src_left1, src_top0, src_left1, src_top1, res_r0, res_r1); - ILVL_B2_UH(src_left1, src_top0, src_left1, src_top1, res_l0, res_l1); - HADD_UB4_UH(res_r0, res_l0, res_r1, res_l1, res_r0, res_l0, res_r1, res_l1); - IPRED_SUBS_UH2_UH(src_top_left, src_top_left, res_r0, res_l0); - IPRED_SUBS_UH2_UH(src_top_left, src_top_left, res_r1, res_l1); - SAT_UH4_UH(res_r0, res_l0, res_r1, res_l1, 7); - PCKEV_ST_SB(res_r0, res_l0, dst); - PCKEV_ST_SB(res_r1, res_l1, dst + 16); - dst += dst_stride; - - ILVR_B2_UH(src_left2, src_top0, src_left2, src_top1, res_r0, res_r1); - ILVL_B2_UH(src_left2, src_top0, src_left2, src_top1, res_l0, res_l1); - HADD_UB4_UH(res_r0, res_l0, res_r1, res_l1, res_r0, res_l0, res_r1, res_l1); - IPRED_SUBS_UH2_UH(src_top_left, src_top_left, res_r0, res_l0); - IPRED_SUBS_UH2_UH(src_top_left, src_top_left, res_r1, res_l1); - SAT_UH4_UH(res_r0, res_l0, res_r1, res_l1, 7); - PCKEV_ST_SB(res_r0, res_l0, dst); - PCKEV_ST_SB(res_r1, res_l1, dst + 16); - dst += dst_stride; - - ILVR_B2_UH(src_left3, src_top0, src_left3, src_top1, res_r0, res_r1); - ILVL_B2_UH(src_left3, src_top0, src_left3, src_top1, res_l0, res_l1); - HADD_UB4_UH(res_r0, res_l0, res_r1, res_l1, res_r0, res_l0, res_r1, res_l1); - IPRED_SUBS_UH2_UH(src_top_left, src_top_left, res_r0, res_l0); - IPRED_SUBS_UH2_UH(src_top_left, src_top_left, res_r1, res_l1); - SAT_UH4_UH(res_r0, res_l0, res_r1, res_l1, 7); - PCKEV_ST_SB(res_r0, res_l0, dst); - PCKEV_ST_SB(res_r1, res_l1, dst + 16); - dst += dst_stride; - } -} - -void vpx_v_predictor_4x4_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)left; - - intra_predict_vert_4x4_msa(above, dst, y_stride); -} - -void vpx_v_predictor_8x8_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)left; - - intra_predict_vert_8x8_msa(above, dst, y_stride); -} - -void vpx_v_predictor_16x16_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)left; - - intra_predict_vert_16x16_msa(above, dst, y_stride); -} - -void vpx_v_predictor_32x32_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)left; - - intra_predict_vert_32x32_msa(above, dst, y_stride); -} - -void vpx_h_predictor_4x4_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)above; - - intra_predict_horiz_4x4_msa(left, dst, y_stride); -} - -void vpx_h_predictor_8x8_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)above; - - intra_predict_horiz_8x8_msa(left, dst, y_stride); -} - -void vpx_h_predictor_16x16_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)above; - - intra_predict_horiz_16x16_msa(left, dst, y_stride); -} - -void vpx_h_predictor_32x32_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)above; - - intra_predict_horiz_32x32_msa(left, dst, y_stride); -} - -void vpx_dc_predictor_4x4_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - intra_predict_dc_4x4_msa(above, left, dst, y_stride); -} - -void vpx_dc_predictor_8x8_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - intra_predict_dc_8x8_msa(above, left, dst, y_stride); -} - -void vpx_dc_predictor_16x16_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - intra_predict_dc_16x16_msa(above, left, dst, y_stride); -} - -void vpx_dc_predictor_32x32_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - intra_predict_dc_32x32_msa(above, left, dst, y_stride); -} - -void vpx_dc_top_predictor_4x4_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)left; - - intra_predict_dc_tl_4x4_msa(above, dst, y_stride); -} - -void vpx_dc_top_predictor_8x8_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)left; - - intra_predict_dc_tl_8x8_msa(above, dst, y_stride); -} - -void vpx_dc_top_predictor_16x16_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)left; - - intra_predict_dc_tl_16x16_msa(above, dst, y_stride); -} - -void vpx_dc_top_predictor_32x32_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)left; - - intra_predict_dc_tl_32x32_msa(above, dst, y_stride); -} - -void vpx_dc_left_predictor_4x4_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)above; - - intra_predict_dc_tl_4x4_msa(left, dst, y_stride); -} - -void vpx_dc_left_predictor_8x8_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)above; - - intra_predict_dc_tl_8x8_msa(left, dst, y_stride); -} - -void vpx_dc_left_predictor_16x16_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, - const uint8_t *left) { - (void)above; - - intra_predict_dc_tl_16x16_msa(left, dst, y_stride); -} - -void vpx_dc_left_predictor_32x32_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, - const uint8_t *left) { - (void)above; - - intra_predict_dc_tl_32x32_msa(left, dst, y_stride); -} - -void vpx_dc_128_predictor_4x4_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)above; - (void)left; - - intra_predict_128dc_4x4_msa(dst, y_stride); -} - -void vpx_dc_128_predictor_8x8_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)above; - (void)left; - - intra_predict_128dc_8x8_msa(dst, y_stride); -} - -void vpx_dc_128_predictor_16x16_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)above; - (void)left; - - intra_predict_128dc_16x16_msa(dst, y_stride); -} - -void vpx_dc_128_predictor_32x32_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - (void)above; - (void)left; - - intra_predict_128dc_32x32_msa(dst, y_stride); -} - -void vpx_tm_predictor_4x4_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - intra_predict_tm_4x4_msa(above, left, dst, y_stride); -} - -void vpx_tm_predictor_8x8_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - intra_predict_tm_8x8_msa(above, left, dst, y_stride); -} - -void vpx_tm_predictor_16x16_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - intra_predict_tm_16x16_msa(above, left, dst, y_stride); -} - -void vpx_tm_predictor_32x32_msa(uint8_t *dst, ptrdiff_t y_stride, - const uint8_t *above, const uint8_t *left) { - intra_predict_tm_32x32_msa(above, left, dst, y_stride); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/inv_txfm_dspr2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/inv_txfm_dspr2.h deleted file mode 100644 index cbea22f2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/inv_txfm_dspr2.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_MIPS_INV_TXFM_DSPR2_H_ -#define VPX_VPX_DSP_MIPS_INV_TXFM_DSPR2_H_ - -#include - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/inv_txfm.h" -#include "vpx_dsp/mips/common_dspr2.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if HAVE_DSPR2 -#define DCT_CONST_ROUND_SHIFT_TWICE_COSPI_16_64(input) \ - ({ \ - int32_t tmp, out; \ - int dct_cost_rounding = DCT_CONST_ROUNDING; \ - int in = input; \ - \ - __asm__ __volatile__(/* out = dct_const_round_shift(dc * cospi_16_64); */ \ - "mtlo %[dct_cost_rounding], $ac1 " \ - " \n\t" \ - "mthi $zero, $ac1 " \ - " \n\t" \ - "madd $ac1, %[in], " \ - "%[cospi_16_64] \n\t" \ - "extp %[tmp], $ac1, " \ - "31 \n\t" \ - \ - /* out = dct_const_round_shift(out * cospi_16_64); */ \ - "mtlo %[dct_cost_rounding], $ac2 " \ - " \n\t" \ - "mthi $zero, $ac2 " \ - " \n\t" \ - "madd $ac2, %[tmp], " \ - "%[cospi_16_64] \n\t" \ - "extp %[out], $ac2, " \ - "31 \n\t" \ - \ - : [tmp] "=&r"(tmp), [out] "=r"(out) \ - : [in] "r"(in), \ - [dct_cost_rounding] "r"(dct_cost_rounding), \ - [cospi_16_64] "r"(cospi_16_64)); \ - out; \ - }) - -void vpx_idct32_cols_add_blk_dspr2(int16_t *input, uint8_t *dest, int stride); -void vpx_idct4_rows_dspr2(const int16_t *input, int16_t *output); -void vpx_idct4_columns_add_blk_dspr2(int16_t *input, uint8_t *dest, int stride); -void iadst4_dspr2(const int16_t *input, int16_t *output); -void idct8_rows_dspr2(const int16_t *input, int16_t *output, uint32_t no_rows); -void idct8_columns_add_blk_dspr2(int16_t *input, uint8_t *dest, int stride); -void iadst8_dspr2(const int16_t *input, int16_t *output); -void idct16_rows_dspr2(const int16_t *input, int16_t *output, uint32_t no_rows); -void idct16_cols_add_blk_dspr2(int16_t *input, uint8_t *dest, int stride); -void iadst16_dspr2(const int16_t *input, int16_t *output); - -#endif // #if HAVE_DSPR2 -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_MIPS_INV_TXFM_DSPR2_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/inv_txfm_msa.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/inv_txfm_msa.h deleted file mode 100644 index 3b66249e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/inv_txfm_msa.h +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_MIPS_INV_TXFM_MSA_H_ -#define VPX_VPX_DSP_MIPS_INV_TXFM_MSA_H_ - -#include "vpx_dsp/mips/macros_msa.h" -#include "vpx_dsp/mips/txfm_macros_msa.h" -#include "vpx_dsp/txfm_common.h" - -#define VP9_ADST8(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, \ - out3, out4, out5, out6, out7) \ - { \ - v8i16 cnst0_m, cnst1_m, cnst2_m, cnst3_m, cnst4_m; \ - v8i16 vec0_m, vec1_m, vec2_m, vec3_m, s0_m, s1_m; \ - v8i16 coeff0_m = { cospi_2_64, cospi_6_64, cospi_10_64, cospi_14_64, \ - cospi_18_64, cospi_22_64, cospi_26_64, cospi_30_64 }; \ - v8i16 coeff1_m = { cospi_8_64, -cospi_8_64, cospi_16_64, -cospi_16_64, \ - cospi_24_64, -cospi_24_64, 0, 0 }; \ - \ - SPLATI_H2_SH(coeff0_m, 0, 7, cnst0_m, cnst1_m); \ - cnst2_m = -cnst0_m; \ - ILVEV_H2_SH(cnst0_m, cnst1_m, cnst1_m, cnst2_m, cnst0_m, cnst1_m); \ - SPLATI_H2_SH(coeff0_m, 4, 3, cnst2_m, cnst3_m); \ - cnst4_m = -cnst2_m; \ - ILVEV_H2_SH(cnst2_m, cnst3_m, cnst3_m, cnst4_m, cnst2_m, cnst3_m); \ - \ - ILVRL_H2_SH(in0, in7, vec1_m, vec0_m); \ - ILVRL_H2_SH(in4, in3, vec3_m, vec2_m); \ - DOT_ADD_SUB_SRARI_PCK(vec0_m, vec1_m, vec2_m, vec3_m, cnst0_m, cnst1_m, \ - cnst2_m, cnst3_m, in7, in0, in4, in3); \ - \ - SPLATI_H2_SH(coeff0_m, 2, 5, cnst0_m, cnst1_m); \ - cnst2_m = -cnst0_m; \ - ILVEV_H2_SH(cnst0_m, cnst1_m, cnst1_m, cnst2_m, cnst0_m, cnst1_m); \ - SPLATI_H2_SH(coeff0_m, 6, 1, cnst2_m, cnst3_m); \ - cnst4_m = -cnst2_m; \ - ILVEV_H2_SH(cnst2_m, cnst3_m, cnst3_m, cnst4_m, cnst2_m, cnst3_m); \ - \ - ILVRL_H2_SH(in2, in5, vec1_m, vec0_m); \ - ILVRL_H2_SH(in6, in1, vec3_m, vec2_m); \ - \ - DOT_ADD_SUB_SRARI_PCK(vec0_m, vec1_m, vec2_m, vec3_m, cnst0_m, cnst1_m, \ - cnst2_m, cnst3_m, in5, in2, in6, in1); \ - BUTTERFLY_4(in7, in0, in2, in5, s1_m, s0_m, in2, in5); \ - out7 = -s0_m; \ - out0 = s1_m; \ - \ - SPLATI_H4_SH(coeff1_m, 0, 4, 1, 5, cnst0_m, cnst1_m, cnst2_m, cnst3_m); \ - \ - ILVEV_H2_SH(cnst3_m, cnst0_m, cnst1_m, cnst2_m, cnst3_m, cnst2_m); \ - cnst0_m = __msa_ilvev_h(cnst1_m, cnst0_m); \ - cnst1_m = cnst0_m; \ - \ - ILVRL_H2_SH(in4, in3, vec1_m, vec0_m); \ - ILVRL_H2_SH(in6, in1, vec3_m, vec2_m); \ - DOT_ADD_SUB_SRARI_PCK(vec0_m, vec1_m, vec2_m, vec3_m, cnst0_m, cnst2_m, \ - cnst3_m, cnst1_m, out1, out6, s0_m, s1_m); \ - \ - SPLATI_H2_SH(coeff1_m, 2, 3, cnst0_m, cnst1_m); \ - cnst1_m = __msa_ilvev_h(cnst1_m, cnst0_m); \ - \ - ILVRL_H2_SH(in2, in5, vec1_m, vec0_m); \ - ILVRL_H2_SH(s0_m, s1_m, vec3_m, vec2_m); \ - out3 = DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst0_m); \ - out4 = DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst1_m); \ - out2 = DOT_SHIFT_RIGHT_PCK_H(vec2_m, vec3_m, cnst0_m); \ - out5 = DOT_SHIFT_RIGHT_PCK_H(vec2_m, vec3_m, cnst1_m); \ - \ - out1 = -out1; \ - out3 = -out3; \ - out5 = -out5; \ - } - -#define VP9_SET_COSPI_PAIR(c0_h, c1_h) \ - ({ \ - v8i16 out0_m, r0_m, r1_m; \ - \ - r0_m = __msa_fill_h(c0_h); \ - r1_m = __msa_fill_h(c1_h); \ - out0_m = __msa_ilvev_h(r1_m, r0_m); \ - \ - out0_m; \ - }) - -#define VP9_ADDBLK_ST8x4_UB(dst, dst_stride, in0, in1, in2, in3) \ - { \ - uint8_t *dst_m = (uint8_t *)(dst); \ - v16u8 dst0_m, dst1_m, dst2_m, dst3_m; \ - v16i8 tmp0_m, tmp1_m; \ - v16i8 zero_m = { 0 }; \ - v8i16 res0_m, res1_m, res2_m, res3_m; \ - \ - LD_UB4(dst_m, dst_stride, dst0_m, dst1_m, dst2_m, dst3_m); \ - ILVR_B4_SH(zero_m, dst0_m, zero_m, dst1_m, zero_m, dst2_m, zero_m, dst3_m, \ - res0_m, res1_m, res2_m, res3_m); \ - ADD4(res0_m, in0, res1_m, in1, res2_m, in2, res3_m, in3, res0_m, res1_m, \ - res2_m, res3_m); \ - CLIP_SH4_0_255(res0_m, res1_m, res2_m, res3_m); \ - PCKEV_B2_SB(res1_m, res0_m, res3_m, res2_m, tmp0_m, tmp1_m); \ - ST8x4_UB(tmp0_m, tmp1_m, dst_m, dst_stride); \ - } - -#define VP9_IDCT4x4(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - v8i16 c0_m, c1_m, c2_m, c3_m; \ - v8i16 step0_m, step1_m; \ - v4i32 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ - \ - c0_m = VP9_SET_COSPI_PAIR(cospi_16_64, cospi_16_64); \ - c1_m = VP9_SET_COSPI_PAIR(cospi_16_64, -cospi_16_64); \ - step0_m = __msa_ilvr_h(in2, in0); \ - DOTP_SH2_SW(step0_m, step0_m, c0_m, c1_m, tmp0_m, tmp1_m); \ - \ - c2_m = VP9_SET_COSPI_PAIR(cospi_24_64, -cospi_8_64); \ - c3_m = VP9_SET_COSPI_PAIR(cospi_8_64, cospi_24_64); \ - step1_m = __msa_ilvr_h(in3, in1); \ - DOTP_SH2_SW(step1_m, step1_m, c2_m, c3_m, tmp2_m, tmp3_m); \ - SRARI_W4_SW(tmp0_m, tmp1_m, tmp2_m, tmp3_m, DCT_CONST_BITS); \ - \ - PCKEV_H2_SW(tmp1_m, tmp0_m, tmp3_m, tmp2_m, tmp0_m, tmp2_m); \ - SLDI_B2_0_SW(tmp0_m, tmp2_m, tmp1_m, tmp3_m, 8); \ - BUTTERFLY_4((v8i16)tmp0_m, (v8i16)tmp1_m, (v8i16)tmp2_m, (v8i16)tmp3_m, \ - out0, out1, out2, out3); \ - } - -#define VP9_IADST4x4(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - v8i16 res0_m, res1_m, c0_m, c1_m; \ - v8i16 k1_m, k2_m, k3_m, k4_m; \ - v8i16 zero_m = { 0 }; \ - v4i32 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ - v4i32 int0_m, int1_m, int2_m, int3_m; \ - v8i16 mask_m = { sinpi_1_9, sinpi_2_9, sinpi_3_9, sinpi_4_9, \ - -sinpi_1_9, -sinpi_2_9, -sinpi_3_9, -sinpi_4_9 }; \ - \ - SPLATI_H4_SH(mask_m, 3, 0, 1, 2, c0_m, c1_m, k1_m, k2_m); \ - ILVEV_H2_SH(c0_m, c1_m, k1_m, k2_m, c0_m, c1_m); \ - ILVR_H2_SH(in0, in2, in1, in3, res0_m, res1_m); \ - DOTP_SH2_SW(res0_m, res1_m, c0_m, c1_m, tmp2_m, tmp1_m); \ - int0_m = tmp2_m + tmp1_m; \ - \ - SPLATI_H2_SH(mask_m, 4, 7, k4_m, k3_m); \ - ILVEV_H2_SH(k4_m, k1_m, k3_m, k2_m, c0_m, c1_m); \ - DOTP_SH2_SW(res0_m, res1_m, c0_m, c1_m, tmp0_m, tmp1_m); \ - int1_m = tmp0_m + tmp1_m; \ - \ - c0_m = __msa_splati_h(mask_m, 6); \ - ILVL_H2_SH(k2_m, c0_m, zero_m, k2_m, c0_m, c1_m); \ - ILVR_H2_SH(in0, in2, in1, in3, res0_m, res1_m); \ - DOTP_SH2_SW(res0_m, res1_m, c0_m, c1_m, tmp0_m, tmp1_m); \ - int2_m = tmp0_m + tmp1_m; \ - \ - c0_m = __msa_splati_h(mask_m, 6); \ - c0_m = __msa_ilvev_h(c0_m, k1_m); \ - \ - res0_m = __msa_ilvr_h((in1), (in3)); \ - tmp0_m = __msa_dotp_s_w(res0_m, c0_m); \ - int3_m = tmp2_m + tmp0_m; \ - \ - res0_m = __msa_ilvr_h((in2), (in3)); \ - c1_m = __msa_ilvev_h(k4_m, k3_m); \ - \ - tmp2_m = __msa_dotp_s_w(res0_m, c1_m); \ - res1_m = __msa_ilvr_h((in0), (in2)); \ - c1_m = __msa_ilvev_h(k1_m, zero_m); \ - \ - tmp3_m = __msa_dotp_s_w(res1_m, c1_m); \ - int3_m += tmp2_m; \ - int3_m += tmp3_m; \ - \ - SRARI_W4_SW(int0_m, int1_m, int2_m, int3_m, DCT_CONST_BITS); \ - PCKEV_H2_SH(int0_m, int0_m, int1_m, int1_m, out0, out1); \ - PCKEV_H2_SH(int2_m, int2_m, int3_m, int3_m, out2, out3); \ - } - -#define VP9_SET_CONST_PAIR(mask_h, idx1_h, idx2_h) \ - ({ \ - v8i16 c0_m, c1_m; \ - \ - SPLATI_H2_SH(mask_h, idx1_h, idx2_h, c0_m, c1_m); \ - c0_m = __msa_ilvev_h(c1_m, c0_m); \ - \ - c0_m; \ - }) - -/* multiply and add macro */ -#define VP9_MADD(inp0, inp1, inp2, inp3, cst0, cst1, cst2, cst3, out0, out1, \ - out2, out3) \ - { \ - v8i16 madd_s0_m, madd_s1_m, madd_s2_m, madd_s3_m; \ - v4i32 tmp0_madd, tmp1_madd, tmp2_madd, tmp3_madd; \ - \ - ILVRL_H2_SH(inp1, inp0, madd_s1_m, madd_s0_m); \ - ILVRL_H2_SH(inp3, inp2, madd_s3_m, madd_s2_m); \ - DOTP_SH4_SW(madd_s1_m, madd_s0_m, madd_s1_m, madd_s0_m, cst0, cst0, cst1, \ - cst1, tmp0_madd, tmp1_madd, tmp2_madd, tmp3_madd); \ - SRARI_W4_SW(tmp0_madd, tmp1_madd, tmp2_madd, tmp3_madd, DCT_CONST_BITS); \ - PCKEV_H2_SH(tmp1_madd, tmp0_madd, tmp3_madd, tmp2_madd, out0, out1); \ - DOTP_SH4_SW(madd_s3_m, madd_s2_m, madd_s3_m, madd_s2_m, cst2, cst2, cst3, \ - cst3, tmp0_madd, tmp1_madd, tmp2_madd, tmp3_madd); \ - SRARI_W4_SW(tmp0_madd, tmp1_madd, tmp2_madd, tmp3_madd, DCT_CONST_BITS); \ - PCKEV_H2_SH(tmp1_madd, tmp0_madd, tmp3_madd, tmp2_madd, out2, out3); \ - } - -/* idct 8x8 macro */ -#define VP9_IDCT8x8_1D(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3, out4, out5, out6, out7) \ - { \ - v8i16 tp0_m, tp1_m, tp2_m, tp3_m, tp4_m, tp5_m, tp6_m, tp7_m; \ - v8i16 k0_m, k1_m, k2_m, k3_m, res0_m, res1_m, res2_m, res3_m; \ - v4i32 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ - v8i16 mask_m = { cospi_28_64, cospi_4_64, cospi_20_64, cospi_12_64, \ - cospi_16_64, -cospi_4_64, -cospi_20_64, -cospi_16_64 }; \ - \ - k0_m = VP9_SET_CONST_PAIR(mask_m, 0, 5); \ - k1_m = VP9_SET_CONST_PAIR(mask_m, 1, 0); \ - k2_m = VP9_SET_CONST_PAIR(mask_m, 6, 3); \ - k3_m = VP9_SET_CONST_PAIR(mask_m, 3, 2); \ - VP9_MADD(in1, in7, in3, in5, k0_m, k1_m, k2_m, k3_m, in1, in7, in3, in5); \ - SUB2(in1, in3, in7, in5, res0_m, res1_m); \ - k0_m = VP9_SET_CONST_PAIR(mask_m, 4, 7); \ - k1_m = __msa_splati_h(mask_m, 4); \ - \ - ILVRL_H2_SH(res0_m, res1_m, res2_m, res3_m); \ - DOTP_SH4_SW(res2_m, res3_m, res2_m, res3_m, k0_m, k0_m, k1_m, k1_m, \ - tmp0_m, tmp1_m, tmp2_m, tmp3_m); \ - SRARI_W4_SW(tmp0_m, tmp1_m, tmp2_m, tmp3_m, DCT_CONST_BITS); \ - tp4_m = in1 + in3; \ - PCKEV_H2_SH(tmp1_m, tmp0_m, tmp3_m, tmp2_m, tp5_m, tp6_m); \ - tp7_m = in7 + in5; \ - k2_m = VP9_SET_COSPI_PAIR(cospi_24_64, -cospi_8_64); \ - k3_m = VP9_SET_COSPI_PAIR(cospi_8_64, cospi_24_64); \ - VP9_MADD(in0, in4, in2, in6, k1_m, k0_m, k2_m, k3_m, in0, in4, in2, in6); \ - BUTTERFLY_4(in0, in4, in2, in6, tp0_m, tp1_m, tp2_m, tp3_m); \ - BUTTERFLY_8(tp0_m, tp1_m, tp2_m, tp3_m, tp4_m, tp5_m, tp6_m, tp7_m, out0, \ - out1, out2, out3, out4, out5, out6, out7); \ - } - -#define VP9_IADST8x8_1D(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3, out4, out5, out6, out7) \ - { \ - v4i32 r0_m, r1_m, r2_m, r3_m, r4_m, r5_m, r6_m, r7_m; \ - v4i32 m0_m, m1_m, m2_m, m3_m, t0_m, t1_m; \ - v8i16 res0_m, res1_m, res2_m, res3_m, k0_m, k1_m, in_s0, in_s1; \ - v8i16 mask1_m = { cospi_2_64, cospi_30_64, -cospi_2_64, cospi_10_64, \ - cospi_22_64, -cospi_10_64, cospi_18_64, cospi_14_64 }; \ - v8i16 mask2_m = { cospi_14_64, -cospi_18_64, cospi_26_64, cospi_6_64, \ - -cospi_26_64, cospi_8_64, cospi_24_64, -cospi_8_64 }; \ - v8i16 mask3_m = { \ - -cospi_24_64, cospi_8_64, cospi_16_64, -cospi_16_64, 0, 0, 0, 0 \ - }; \ - \ - k0_m = VP9_SET_CONST_PAIR(mask1_m, 0, 1); \ - k1_m = VP9_SET_CONST_PAIR(mask1_m, 1, 2); \ - ILVRL_H2_SH(in1, in0, in_s1, in_s0); \ - DOTP_SH4_SW(in_s1, in_s0, in_s1, in_s0, k0_m, k0_m, k1_m, k1_m, r0_m, \ - r1_m, r2_m, r3_m); \ - k0_m = VP9_SET_CONST_PAIR(mask1_m, 6, 7); \ - k1_m = VP9_SET_CONST_PAIR(mask2_m, 0, 1); \ - ILVRL_H2_SH(in5, in4, in_s1, in_s0); \ - DOTP_SH4_SW(in_s1, in_s0, in_s1, in_s0, k0_m, k0_m, k1_m, k1_m, r4_m, \ - r5_m, r6_m, r7_m); \ - ADD4(r0_m, r4_m, r1_m, r5_m, r2_m, r6_m, r3_m, r7_m, m0_m, m1_m, m2_m, \ - m3_m); \ - SRARI_W4_SW(m0_m, m1_m, m2_m, m3_m, DCT_CONST_BITS); \ - PCKEV_H2_SH(m1_m, m0_m, m3_m, m2_m, res0_m, res1_m); \ - SUB4(r0_m, r4_m, r1_m, r5_m, r2_m, r6_m, r3_m, r7_m, m0_m, m1_m, m2_m, \ - m3_m); \ - SRARI_W4_SW(m0_m, m1_m, m2_m, m3_m, DCT_CONST_BITS); \ - PCKEV_H2_SW(m1_m, m0_m, m3_m, m2_m, t0_m, t1_m); \ - k0_m = VP9_SET_CONST_PAIR(mask1_m, 3, 4); \ - k1_m = VP9_SET_CONST_PAIR(mask1_m, 4, 5); \ - ILVRL_H2_SH(in3, in2, in_s1, in_s0); \ - DOTP_SH4_SW(in_s1, in_s0, in_s1, in_s0, k0_m, k0_m, k1_m, k1_m, r0_m, \ - r1_m, r2_m, r3_m); \ - k0_m = VP9_SET_CONST_PAIR(mask2_m, 2, 3); \ - k1_m = VP9_SET_CONST_PAIR(mask2_m, 3, 4); \ - ILVRL_H2_SH(in7, in6, in_s1, in_s0); \ - DOTP_SH4_SW(in_s1, in_s0, in_s1, in_s0, k0_m, k0_m, k1_m, k1_m, r4_m, \ - r5_m, r6_m, r7_m); \ - ADD4(r0_m, r4_m, r1_m, r5_m, r2_m, r6_m, r3_m, r7_m, m0_m, m1_m, m2_m, \ - m3_m); \ - SRARI_W4_SW(m0_m, m1_m, m2_m, m3_m, DCT_CONST_BITS); \ - PCKEV_H2_SH(m1_m, m0_m, m3_m, m2_m, res2_m, res3_m); \ - SUB4(r0_m, r4_m, r1_m, r5_m, r2_m, r6_m, r3_m, r7_m, m0_m, m1_m, m2_m, \ - m3_m); \ - SRARI_W4_SW(m0_m, m1_m, m2_m, m3_m, DCT_CONST_BITS); \ - PCKEV_H2_SW(m1_m, m0_m, m3_m, m2_m, r2_m, r3_m); \ - ILVRL_H2_SW(r3_m, r2_m, m2_m, m3_m); \ - BUTTERFLY_4(res0_m, res1_m, res3_m, res2_m, out0, in7, in4, in3); \ - k0_m = VP9_SET_CONST_PAIR(mask2_m, 5, 6); \ - k1_m = VP9_SET_CONST_PAIR(mask2_m, 6, 7); \ - ILVRL_H2_SH(t1_m, t0_m, in_s1, in_s0); \ - DOTP_SH4_SW(in_s1, in_s0, in_s1, in_s0, k0_m, k0_m, k1_m, k1_m, r0_m, \ - r1_m, r2_m, r3_m); \ - k1_m = VP9_SET_CONST_PAIR(mask3_m, 0, 1); \ - DOTP_SH4_SW(m2_m, m3_m, m2_m, m3_m, k0_m, k0_m, k1_m, k1_m, r4_m, r5_m, \ - r6_m, r7_m); \ - ADD4(r0_m, r6_m, r1_m, r7_m, r2_m, r4_m, r3_m, r5_m, m0_m, m1_m, m2_m, \ - m3_m); \ - SRARI_W4_SW(m0_m, m1_m, m2_m, m3_m, DCT_CONST_BITS); \ - PCKEV_H2_SH(m1_m, m0_m, m3_m, m2_m, in1, out6); \ - SUB4(r0_m, r6_m, r1_m, r7_m, r2_m, r4_m, r3_m, r5_m, m0_m, m1_m, m2_m, \ - m3_m); \ - SRARI_W4_SW(m0_m, m1_m, m2_m, m3_m, DCT_CONST_BITS); \ - PCKEV_H2_SH(m1_m, m0_m, m3_m, m2_m, in2, in5); \ - k0_m = VP9_SET_CONST_PAIR(mask3_m, 2, 2); \ - k1_m = VP9_SET_CONST_PAIR(mask3_m, 2, 3); \ - ILVRL_H2_SH(in4, in3, in_s1, in_s0); \ - DOTP_SH4_SW(in_s1, in_s0, in_s1, in_s0, k0_m, k0_m, k1_m, k1_m, m0_m, \ - m1_m, m2_m, m3_m); \ - SRARI_W4_SW(m0_m, m1_m, m2_m, m3_m, DCT_CONST_BITS); \ - PCKEV_H2_SH(m1_m, m0_m, m3_m, m2_m, in3, out4); \ - ILVRL_H2_SW(in5, in2, m2_m, m3_m); \ - DOTP_SH4_SW(m2_m, m3_m, m2_m, m3_m, k0_m, k0_m, k1_m, k1_m, m0_m, m1_m, \ - m2_m, m3_m); \ - SRARI_W4_SW(m0_m, m1_m, m2_m, m3_m, DCT_CONST_BITS); \ - PCKEV_H2_SH(m1_m, m0_m, m3_m, m2_m, out2, in5); \ - \ - out1 = -in1; \ - out3 = -in3; \ - out5 = -in5; \ - out7 = -in7; \ - } - -#define VP9_IADST8x16_1D(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, \ - r12, r13, r14, r15, out0, out1, out2, out3, out4, \ - out5, out6, out7, out8, out9, out10, out11, out12, \ - out13, out14, out15) \ - { \ - v8i16 g0_m, g1_m, g2_m, g3_m, g4_m, g5_m, g6_m, g7_m; \ - v8i16 g8_m, g9_m, g10_m, g11_m, g12_m, g13_m, g14_m, g15_m; \ - v8i16 h0_m, h1_m, h2_m, h3_m, h4_m, h5_m, h6_m, h7_m; \ - v8i16 h8_m, h9_m, h10_m, h11_m; \ - v8i16 k0_m, k1_m, k2_m, k3_m; \ - \ - /* stage 1 */ \ - k0_m = VP9_SET_COSPI_PAIR(cospi_1_64, cospi_31_64); \ - k1_m = VP9_SET_COSPI_PAIR(cospi_31_64, -cospi_1_64); \ - k2_m = VP9_SET_COSPI_PAIR(cospi_17_64, cospi_15_64); \ - k3_m = VP9_SET_COSPI_PAIR(cospi_15_64, -cospi_17_64); \ - MADD_BF(r15, r0, r7, r8, k0_m, k1_m, k2_m, k3_m, g0_m, g1_m, g2_m, g3_m); \ - k0_m = VP9_SET_COSPI_PAIR(cospi_5_64, cospi_27_64); \ - k1_m = VP9_SET_COSPI_PAIR(cospi_27_64, -cospi_5_64); \ - k2_m = VP9_SET_COSPI_PAIR(cospi_21_64, cospi_11_64); \ - k3_m = VP9_SET_COSPI_PAIR(cospi_11_64, -cospi_21_64); \ - MADD_BF(r13, r2, r5, r10, k0_m, k1_m, k2_m, k3_m, g4_m, g5_m, g6_m, g7_m); \ - k0_m = VP9_SET_COSPI_PAIR(cospi_9_64, cospi_23_64); \ - k1_m = VP9_SET_COSPI_PAIR(cospi_23_64, -cospi_9_64); \ - k2_m = VP9_SET_COSPI_PAIR(cospi_25_64, cospi_7_64); \ - k3_m = VP9_SET_COSPI_PAIR(cospi_7_64, -cospi_25_64); \ - MADD_BF(r11, r4, r3, r12, k0_m, k1_m, k2_m, k3_m, g8_m, g9_m, g10_m, \ - g11_m); \ - k0_m = VP9_SET_COSPI_PAIR(cospi_13_64, cospi_19_64); \ - k1_m = VP9_SET_COSPI_PAIR(cospi_19_64, -cospi_13_64); \ - k2_m = VP9_SET_COSPI_PAIR(cospi_29_64, cospi_3_64); \ - k3_m = VP9_SET_COSPI_PAIR(cospi_3_64, -cospi_29_64); \ - MADD_BF(r9, r6, r1, r14, k0_m, k1_m, k2_m, k3_m, g12_m, g13_m, g14_m, \ - g15_m); \ - \ - /* stage 2 */ \ - k0_m = VP9_SET_COSPI_PAIR(cospi_4_64, cospi_28_64); \ - k1_m = VP9_SET_COSPI_PAIR(cospi_28_64, -cospi_4_64); \ - k2_m = VP9_SET_COSPI_PAIR(-cospi_28_64, cospi_4_64); \ - MADD_BF(g1_m, g3_m, g9_m, g11_m, k0_m, k1_m, k2_m, k0_m, h0_m, h1_m, h2_m, \ - h3_m); \ - k0_m = VP9_SET_COSPI_PAIR(cospi_12_64, cospi_20_64); \ - k1_m = VP9_SET_COSPI_PAIR(-cospi_20_64, cospi_12_64); \ - k2_m = VP9_SET_COSPI_PAIR(cospi_20_64, -cospi_12_64); \ - MADD_BF(g7_m, g5_m, g15_m, g13_m, k0_m, k1_m, k2_m, k0_m, h4_m, h5_m, \ - h6_m, h7_m); \ - BUTTERFLY_4(h0_m, h2_m, h6_m, h4_m, out8, out9, out11, out10); \ - BUTTERFLY_8(g0_m, g2_m, g4_m, g6_m, g14_m, g12_m, g10_m, g8_m, h8_m, h9_m, \ - h10_m, h11_m, h6_m, h4_m, h2_m, h0_m); \ - \ - /* stage 3 */ \ - BUTTERFLY_4(h8_m, h9_m, h11_m, h10_m, out0, out1, h11_m, h10_m); \ - k0_m = VP9_SET_COSPI_PAIR(cospi_8_64, cospi_24_64); \ - k1_m = VP9_SET_COSPI_PAIR(cospi_24_64, -cospi_8_64); \ - k2_m = VP9_SET_COSPI_PAIR(-cospi_24_64, cospi_8_64); \ - MADD_BF(h0_m, h2_m, h4_m, h6_m, k0_m, k1_m, k2_m, k0_m, out4, out6, out5, \ - out7); \ - MADD_BF(h1_m, h3_m, h5_m, h7_m, k0_m, k1_m, k2_m, k0_m, out12, out14, \ - out13, out15); \ - \ - /* stage 4 */ \ - k0_m = VP9_SET_COSPI_PAIR(cospi_16_64, cospi_16_64); \ - k1_m = VP9_SET_COSPI_PAIR(-cospi_16_64, -cospi_16_64); \ - k2_m = VP9_SET_COSPI_PAIR(cospi_16_64, -cospi_16_64); \ - k3_m = VP9_SET_COSPI_PAIR(-cospi_16_64, cospi_16_64); \ - MADD_SHORT(h10_m, h11_m, k1_m, k2_m, out2, out3); \ - MADD_SHORT(out6, out7, k0_m, k3_m, out6, out7); \ - MADD_SHORT(out10, out11, k0_m, k3_m, out10, out11); \ - MADD_SHORT(out14, out15, k1_m, k2_m, out14, out15); \ - } - -void vpx_idct16_1d_columns_addblk_msa(int16_t *input, uint8_t *dst, - int32_t dst_stride); -void vpx_idct16_1d_rows_msa(const int16_t *input, int16_t *output); -void vpx_iadst16_1d_columns_addblk_msa(int16_t *input, uint8_t *dst, - int32_t dst_stride); -void vpx_iadst16_1d_rows_msa(const int16_t *input, int16_t *output); -#endif // VPX_VPX_DSP_MIPS_INV_TXFM_MSA_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/itrans16_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/itrans16_dspr2.c deleted file mode 100644 index 44ba65c7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/itrans16_dspr2.c +++ /dev/null @@ -1,1230 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/inv_txfm_dspr2.h" -#include "vpx_dsp/txfm_common.h" - -#if HAVE_DSPR2 -void idct16_rows_dspr2(const int16_t *input, int16_t *output, - uint32_t no_rows) { - int i; - int step1_0, step1_1, step1_2, step1_3, step1_4, step1_5, step1_6, step1_7; - int step1_10, step1_11, step1_12, step1_13; - int step2_0, step2_1, step2_2, step2_3; - int step2_8, step2_9, step2_10, step2_11; - int step2_12, step2_13, step2_14, step2_15; - int load1, load2, load3, load4, load5, load6, load7, load8; - int result1, result2, result3, result4; - const int const_2_power_13 = 8192; - - for (i = no_rows; i--;) { - /* prefetch row */ - prefetch_load((const uint8_t *)(input + 16)); - - __asm__ __volatile__( - "lh %[load1], 0(%[input]) \n\t" - "lh %[load2], 16(%[input]) \n\t" - "lh %[load3], 8(%[input]) \n\t" - "lh %[load4], 24(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "add %[result1], %[load1], %[load2] \n\t" - "sub %[result2], %[load1], %[load2] \n\t" - "madd $ac1, %[result1], %[cospi_16_64] \n\t" - "madd $ac2, %[result2], %[cospi_16_64] \n\t" - "extp %[step2_0], $ac1, 31 \n\t" - "extp %[step2_1], $ac2, 31 \n\t" - - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "madd $ac3, %[load3], %[cospi_24_64] \n\t" - "msub $ac3, %[load4], %[cospi_8_64] \n\t" - "extp %[step2_2], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "madd $ac1, %[load3], %[cospi_8_64] \n\t" - "madd $ac1, %[load4], %[cospi_24_64] \n\t" - "extp %[step2_3], $ac1, 31 \n\t" - - "add %[step1_0], %[step2_0], %[step2_3] \n\t" - "add %[step1_1], %[step2_1], %[step2_2] \n\t" - "sub %[step1_2], %[step2_1], %[step2_2] \n\t" - "sub %[step1_3], %[step2_0], %[step2_3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [result1] "=&r"(result1), - [result2] "=&r"(result2), [step2_0] "=&r"(step2_0), - [step2_1] "=&r"(step2_1), [step2_2] "=&r"(step2_2), - [step2_3] "=&r"(step2_3), [step1_0] "=r"(step1_0), - [step1_1] "=r"(step1_1), [step1_2] "=r"(step1_2), - [step1_3] "=r"(step1_3) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_24_64] "r"(cospi_24_64), [cospi_8_64] "r"(cospi_8_64), - [cospi_16_64] "r"(cospi_16_64)); - - __asm__ __volatile__( - "lh %[load5], 2(%[input]) \n\t" - "lh %[load6], 30(%[input]) \n\t" - "lh %[load7], 18(%[input]) \n\t" - "lh %[load8], 14(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load5], %[cospi_30_64] \n\t" - "msub $ac1, %[load6], %[cospi_2_64] \n\t" - "extp %[result1], $ac1, 31 \n\t" - - "madd $ac3, %[load7], %[cospi_14_64] \n\t" - "msub $ac3, %[load8], %[cospi_18_64] \n\t" - "extp %[result2], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac1, %[load7], %[cospi_18_64] \n\t" - "madd $ac1, %[load8], %[cospi_14_64] \n\t" - "extp %[result3], $ac1, 31 \n\t" - - "madd $ac2, %[load5], %[cospi_2_64] \n\t" - "madd $ac2, %[load6], %[cospi_30_64] \n\t" - "extp %[result4], $ac2, 31 \n\t" - - "sub %[load5], %[result1], %[result2] \n\t" - "sub %[load6], %[result4], %[result3] \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load6], %[cospi_24_64] \n\t" - "msub $ac1, %[load5], %[cospi_8_64] \n\t" - "madd $ac3, %[load5], %[cospi_24_64] \n\t" - "madd $ac3, %[load6], %[cospi_8_64] \n\t" - - "extp %[step2_9], $ac1, 31 \n\t" - "extp %[step2_14], $ac3, 31 \n\t" - "add %[step2_8], %[result1], %[result2] \n\t" - "add %[step2_15], %[result4], %[result3] \n\t" - - : [load5] "=&r"(load5), [load6] "=&r"(load6), [load7] "=&r"(load7), - [load8] "=&r"(load8), [result1] "=&r"(result1), - [result2] "=&r"(result2), [result3] "=&r"(result3), - [result4] "=&r"(result4), [step2_8] "=r"(step2_8), - [step2_15] "=r"(step2_15), [step2_9] "=r"(step2_9), - [step2_14] "=r"(step2_14) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_30_64] "r"(cospi_30_64), [cospi_2_64] "r"(cospi_2_64), - [cospi_14_64] "r"(cospi_14_64), [cospi_18_64] "r"(cospi_18_64), - [cospi_24_64] "r"(cospi_24_64), [cospi_8_64] "r"(cospi_8_64)); - - __asm__ __volatile__( - "lh %[load1], 10(%[input]) \n\t" - "lh %[load2], 22(%[input]) \n\t" - "lh %[load3], 26(%[input]) \n\t" - "lh %[load4], 6(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load1], %[cospi_22_64] \n\t" - "msub $ac1, %[load2], %[cospi_10_64] \n\t" - "extp %[result1], $ac1, 31 \n\t" - - "madd $ac3, %[load3], %[cospi_6_64] \n\t" - "msub $ac3, %[load4], %[cospi_26_64] \n\t" - "extp %[result2], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac1, %[load1], %[cospi_10_64] \n\t" - "madd $ac1, %[load2], %[cospi_22_64] \n\t" - "extp %[result3], $ac1, 31 \n\t" - - "madd $ac2, %[load3], %[cospi_26_64] \n\t" - "madd $ac2, %[load4], %[cospi_6_64] \n\t" - "extp %[result4], $ac2, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load1], %[result2], %[result1] \n\t" - "sub %[load2], %[result4], %[result3] \n\t" - - "msub $ac1, %[load1], %[cospi_24_64] \n\t" - "msub $ac1, %[load2], %[cospi_8_64] \n\t" - "madd $ac3, %[load2], %[cospi_24_64] \n\t" - "msub $ac3, %[load1], %[cospi_8_64] \n\t" - - "extp %[step2_10], $ac1, 31 \n\t" - "extp %[step2_13], $ac3, 31 \n\t" - "add %[step2_11], %[result1], %[result2] \n\t" - "add %[step2_12], %[result4], %[result3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [result1] "=&r"(result1), - [result2] "=&r"(result2), [result3] "=&r"(result3), - [result4] "=&r"(result4), [step2_10] "=r"(step2_10), - [step2_11] "=r"(step2_11), [step2_12] "=r"(step2_12), - [step2_13] "=r"(step2_13) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_22_64] "r"(cospi_22_64), [cospi_10_64] "r"(cospi_10_64), - [cospi_6_64] "r"(cospi_6_64), [cospi_26_64] "r"(cospi_26_64), - [cospi_24_64] "r"(cospi_24_64), [cospi_8_64] "r"(cospi_8_64)); - - __asm__ __volatile__( - "lh %[load5], 4(%[input]) \n\t" - "lh %[load6], 28(%[input]) \n\t" - "lh %[load7], 20(%[input]) \n\t" - "lh %[load8], 12(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load5], %[cospi_28_64] \n\t" - "msub $ac1, %[load6], %[cospi_4_64] \n\t" - "extp %[result1], $ac1, 31 \n\t" - - "madd $ac3, %[load7], %[cospi_12_64] \n\t" - "msub $ac3, %[load8], %[cospi_20_64] \n\t" - "extp %[result2], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac1, %[load7], %[cospi_20_64] \n\t" - "madd $ac1, %[load8], %[cospi_12_64] \n\t" - "extp %[result3], $ac1, 31 \n\t" - - "madd $ac2, %[load5], %[cospi_4_64] \n\t" - "madd $ac2, %[load6], %[cospi_28_64] \n\t" - "extp %[result4], $ac2, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load5], %[result4], %[result3] \n\t" - "sub %[load5], %[load5], %[result1] \n\t" - "add %[load5], %[load5], %[result2] \n\t" - - "sub %[load6], %[result1], %[result2] \n\t" - "sub %[load6], %[load6], %[result3] \n\t" - "add %[load6], %[load6], %[result4] \n\t" - - "madd $ac1, %[load5], %[cospi_16_64] \n\t" - "madd $ac3, %[load6], %[cospi_16_64] \n\t" - - "extp %[step1_5], $ac1, 31 \n\t" - "extp %[step1_6], $ac3, 31 \n\t" - "add %[step1_4], %[result1], %[result2] \n\t" - "add %[step1_7], %[result4], %[result3] \n\t" - - : [load5] "=&r"(load5), [load6] "=&r"(load6), [load7] "=&r"(load7), - [load8] "=&r"(load8), [result1] "=&r"(result1), - [result2] "=&r"(result2), [result3] "=&r"(result3), - [result4] "=&r"(result4), [step1_4] "=r"(step1_4), - [step1_5] "=r"(step1_5), [step1_6] "=r"(step1_6), - [step1_7] "=r"(step1_7) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_20_64] "r"(cospi_20_64), [cospi_12_64] "r"(cospi_12_64), - [cospi_4_64] "r"(cospi_4_64), [cospi_28_64] "r"(cospi_28_64), - [cospi_16_64] "r"(cospi_16_64)); - - __asm__ __volatile__( - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - - "sub %[load5], %[step2_14], %[step2_13] \n\t" - "sub %[load5], %[load5], %[step2_9] \n\t" - "add %[load5], %[load5], %[step2_10] \n\t" - - "madd $ac0, %[load5], %[cospi_16_64] \n\t" - - "sub %[load6], %[step2_14], %[step2_13] \n\t" - "sub %[load6], %[load6], %[step2_10] \n\t" - "add %[load6], %[load6], %[step2_9] \n\t" - - "madd $ac1, %[load6], %[cospi_16_64] \n\t" - - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load5], %[step2_15], %[step2_12] \n\t" - "sub %[load5], %[load5], %[step2_8] \n\t" - "add %[load5], %[load5], %[step2_11] \n\t" - - "madd $ac2, %[load5], %[cospi_16_64] \n\t" - - "sub %[load6], %[step2_15], %[step2_12] \n\t" - "sub %[load6], %[load6], %[step2_11] \n\t" - "add %[load6], %[load6], %[step2_8] \n\t" - - "madd $ac3, %[load6], %[cospi_16_64] \n\t" - - "extp %[step1_10], $ac0, 31 \n\t" - "extp %[step1_13], $ac1, 31 \n\t" - "extp %[step1_11], $ac2, 31 \n\t" - "extp %[step1_12], $ac3, 31 \n\t" - - : [load5] "=&r"(load5), [load6] "=&r"(load6), [step1_10] "=r"(step1_10), - [step1_11] "=r"(step1_11), [step1_12] "=r"(step1_12), - [step1_13] "=r"(step1_13) - : [const_2_power_13] "r"(const_2_power_13), [step2_14] "r"(step2_14), - [step2_13] "r"(step2_13), [step2_9] "r"(step2_9), - [step2_10] "r"(step2_10), [step2_15] "r"(step2_15), - [step2_12] "r"(step2_12), [step2_8] "r"(step2_8), - [step2_11] "r"(step2_11), [cospi_16_64] "r"(cospi_16_64)); - - __asm__ __volatile__( - "add %[load5], %[step1_0], %[step1_7] \n\t" - "add %[load5], %[load5], %[step2_12] \n\t" - "add %[load5], %[load5], %[step2_15] \n\t" - "add %[load6], %[step1_1], %[step1_6] \n\t" - "add %[load6], %[load6], %[step2_13] \n\t" - "add %[load6], %[load6], %[step2_14] \n\t" - "sh %[load5], 0(%[output]) \n\t" - "sh %[load6], 32(%[output]) \n\t" - "sub %[load5], %[step1_1], %[step1_6] \n\t" - "add %[load5], %[load5], %[step2_9] \n\t" - "add %[load5], %[load5], %[step2_10] \n\t" - "sub %[load6], %[step1_0], %[step1_7] \n\t" - "add %[load6], %[load6], %[step2_8] \n\t" - "add %[load6], %[load6], %[step2_11] \n\t" - "sh %[load5], 192(%[output]) \n\t" - "sh %[load6], 224(%[output]) \n\t" - "sub %[load5], %[step1_0], %[step1_7] \n\t" - "sub %[load5], %[load5], %[step2_8] \n\t" - "sub %[load5], %[load5], %[step2_11] \n\t" - "sub %[load6], %[step1_1], %[step1_6] \n\t" - "sub %[load6], %[load6], %[step2_9] \n\t" - "sub %[load6], %[load6], %[step2_10] \n\t" - "sh %[load5], 256(%[output]) \n\t" - "sh %[load6], 288(%[output]) \n\t" - "add %[load5], %[step1_1], %[step1_6] \n\t" - "sub %[load5], %[load5], %[step2_13] \n\t" - "sub %[load5], %[load5], %[step2_14] \n\t" - "add %[load6], %[step1_0], %[step1_7] \n\t" - "sub %[load6], %[load6], %[step2_12] \n\t" - "sub %[load6], %[load6], %[step2_15] \n\t" - "sh %[load5], 448(%[output]) \n\t" - "sh %[load6], 480(%[output]) \n\t" - - : [load5] "=&r"(load5), [load6] "=&r"(load6) - : [output] "r"(output), [step1_0] "r"(step1_0), [step1_1] "r"(step1_1), - [step1_6] "r"(step1_6), [step1_7] "r"(step1_7), - [step2_8] "r"(step2_8), [step2_9] "r"(step2_9), - [step2_10] "r"(step2_10), [step2_11] "r"(step2_11), - [step2_12] "r"(step2_12), [step2_13] "r"(step2_13), - [step2_14] "r"(step2_14), [step2_15] "r"(step2_15)); - - __asm__ __volatile__( - "add %[load5], %[step1_2], %[step1_5] \n\t" - "add %[load5], %[load5], %[step1_13] \n\t" - "add %[load6], %[step1_3], %[step1_4] \n\t" - "add %[load6], %[load6], %[step1_12] \n\t" - "sh %[load5], 64(%[output]) \n\t" - "sh %[load6], 96(%[output]) \n\t" - "sub %[load5], %[step1_3], %[step1_4] \n\t" - "add %[load5], %[load5], %[step1_11] \n\t" - "sub %[load6], %[step1_2], %[step1_5] \n\t" - "add %[load6], %[load6], %[step1_10] \n\t" - "sh %[load5], 128(%[output]) \n\t" - "sh %[load6], 160(%[output]) \n\t" - "sub %[load5], %[step1_2], %[step1_5] \n\t" - "sub %[load5], %[load5], %[step1_10] \n\t" - "sub %[load6], %[step1_3], %[step1_4] \n\t" - "sub %[load6], %[load6], %[step1_11] \n\t" - "sh %[load5], 320(%[output]) \n\t" - "sh %[load6], 352(%[output]) \n\t" - "add %[load5], %[step1_3], %[step1_4] \n\t" - "sub %[load5], %[load5], %[step1_12] \n\t" - "add %[load6], %[step1_2], %[step1_5] \n\t" - "sub %[load6], %[load6], %[step1_13] \n\t" - "sh %[load5], 384(%[output]) \n\t" - "sh %[load6], 416(%[output]) \n\t" - - : [load5] "=&r"(load5), [load6] "=&r"(load6) - : [output] "r"(output), [step1_2] "r"(step1_2), [step1_3] "r"(step1_3), - [step1_4] "r"(step1_4), [step1_5] "r"(step1_5), - [step1_10] "r"(step1_10), [step1_11] "r"(step1_11), - [step1_12] "r"(step1_12), [step1_13] "r"(step1_13)); - - input += 16; - output += 1; - } -} - -void idct16_cols_add_blk_dspr2(int16_t *input, uint8_t *dest, int stride) { - int i; - int step1_0, step1_1, step1_2, step1_3, step1_4, step1_5, step1_6, step1_7; - int step1_8, step1_9, step1_10, step1_11; - int step1_12, step1_13, step1_14, step1_15; - int step2_0, step2_1, step2_2, step2_3; - int step2_8, step2_9, step2_10, step2_11; - int step2_12, step2_13, step2_14, step2_15; - int load1, load2, load3, load4, load5, load6, load7, load8; - int result1, result2, result3, result4; - const int const_2_power_13 = 8192; - uint8_t *dest_pix; - uint8_t *cm = vpx_ff_cropTbl; - - /* prefetch vpx_ff_cropTbl */ - prefetch_load(vpx_ff_cropTbl); - prefetch_load(vpx_ff_cropTbl + 32); - prefetch_load(vpx_ff_cropTbl + 64); - prefetch_load(vpx_ff_cropTbl + 96); - prefetch_load(vpx_ff_cropTbl + 128); - prefetch_load(vpx_ff_cropTbl + 160); - prefetch_load(vpx_ff_cropTbl + 192); - prefetch_load(vpx_ff_cropTbl + 224); - - for (i = 0; i < 16; ++i) { - dest_pix = (dest + i); - __asm__ __volatile__( - "lh %[load1], 0(%[input]) \n\t" - "lh %[load2], 16(%[input]) \n\t" - "lh %[load3], 8(%[input]) \n\t" - "lh %[load4], 24(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "add %[result1], %[load1], %[load2] \n\t" - "sub %[result2], %[load1], %[load2] \n\t" - "madd $ac1, %[result1], %[cospi_16_64] \n\t" - "madd $ac2, %[result2], %[cospi_16_64] \n\t" - "extp %[step2_0], $ac1, 31 \n\t" - "extp %[step2_1], $ac2, 31 \n\t" - - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "madd $ac3, %[load3], %[cospi_24_64] \n\t" - "msub $ac3, %[load4], %[cospi_8_64] \n\t" - "extp %[step2_2], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "madd $ac1, %[load3], %[cospi_8_64] \n\t" - "madd $ac1, %[load4], %[cospi_24_64] \n\t" - "extp %[step2_3], $ac1, 31 \n\t" - - "add %[step1_0], %[step2_0], %[step2_3] \n\t" - "add %[step1_1], %[step2_1], %[step2_2] \n\t" - "sub %[step1_2], %[step2_1], %[step2_2] \n\t" - "sub %[step1_3], %[step2_0], %[step2_3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [result1] "=&r"(result1), - [result2] "=&r"(result2), [step2_0] "=&r"(step2_0), - [step2_1] "=&r"(step2_1), [step2_2] "=&r"(step2_2), - [step2_3] "=&r"(step2_3), [step1_0] "=r"(step1_0), - [step1_1] "=r"(step1_1), [step1_2] "=r"(step1_2), - [step1_3] "=r"(step1_3) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_24_64] "r"(cospi_24_64), [cospi_8_64] "r"(cospi_8_64), - [cospi_16_64] "r"(cospi_16_64)); - - __asm__ __volatile__( - "lh %[load5], 2(%[input]) \n\t" - "lh %[load6], 30(%[input]) \n\t" - "lh %[load7], 18(%[input]) \n\t" - "lh %[load8], 14(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load5], %[cospi_30_64] \n\t" - "msub $ac1, %[load6], %[cospi_2_64] \n\t" - "extp %[result1], $ac1, 31 \n\t" - - "madd $ac3, %[load7], %[cospi_14_64] \n\t" - "msub $ac3, %[load8], %[cospi_18_64] \n\t" - "extp %[result2], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac1, %[load7], %[cospi_18_64] \n\t" - "madd $ac1, %[load8], %[cospi_14_64] \n\t" - "extp %[result3], $ac1, 31 \n\t" - - "madd $ac2, %[load5], %[cospi_2_64] \n\t" - "madd $ac2, %[load6], %[cospi_30_64] \n\t" - "extp %[result4], $ac2, 31 \n\t" - - "sub %[load5], %[result1], %[result2] \n\t" - "sub %[load6], %[result4], %[result3] \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load6], %[cospi_24_64] \n\t" - "msub $ac1, %[load5], %[cospi_8_64] \n\t" - "madd $ac3, %[load5], %[cospi_24_64] \n\t" - "madd $ac3, %[load6], %[cospi_8_64] \n\t" - - "extp %[step2_9], $ac1, 31 \n\t" - "extp %[step2_14], $ac3, 31 \n\t" - "add %[step2_8], %[result1], %[result2] \n\t" - "add %[step2_15], %[result4], %[result3] \n\t" - - : [load5] "=&r"(load5), [load6] "=&r"(load6), [load7] "=&r"(load7), - [load8] "=&r"(load8), [result1] "=&r"(result1), - [result2] "=&r"(result2), [result3] "=&r"(result3), - [result4] "=&r"(result4), [step2_8] "=r"(step2_8), - [step2_15] "=r"(step2_15), [step2_9] "=r"(step2_9), - [step2_14] "=r"(step2_14) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_30_64] "r"(cospi_30_64), [cospi_2_64] "r"(cospi_2_64), - [cospi_14_64] "r"(cospi_14_64), [cospi_18_64] "r"(cospi_18_64), - [cospi_24_64] "r"(cospi_24_64), [cospi_8_64] "r"(cospi_8_64)); - - __asm__ __volatile__( - "lh %[load1], 10(%[input]) \n\t" - "lh %[load2], 22(%[input]) \n\t" - "lh %[load3], 26(%[input]) \n\t" - "lh %[load4], 6(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load1], %[cospi_22_64] \n\t" - "msub $ac1, %[load2], %[cospi_10_64] \n\t" - "extp %[result1], $ac1, 31 \n\t" - - "madd $ac3, %[load3], %[cospi_6_64] \n\t" - "msub $ac3, %[load4], %[cospi_26_64] \n\t" - "extp %[result2], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac1, %[load1], %[cospi_10_64] \n\t" - "madd $ac1, %[load2], %[cospi_22_64] \n\t" - "extp %[result3], $ac1, 31 \n\t" - - "madd $ac2, %[load3], %[cospi_26_64] \n\t" - "madd $ac2, %[load4], %[cospi_6_64] \n\t" - "extp %[result4], $ac2, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load1], %[result2], %[result1] \n\t" - "sub %[load2], %[result4], %[result3] \n\t" - - "msub $ac1, %[load1], %[cospi_24_64] \n\t" - "msub $ac1, %[load2], %[cospi_8_64] \n\t" - "madd $ac3, %[load2], %[cospi_24_64] \n\t" - "msub $ac3, %[load1], %[cospi_8_64] \n\t" - - "extp %[step2_10], $ac1, 31 \n\t" - "extp %[step2_13], $ac3, 31 \n\t" - "add %[step2_11], %[result1], %[result2] \n\t" - "add %[step2_12], %[result4], %[result3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [result1] "=&r"(result1), - [result2] "=&r"(result2), [result3] "=&r"(result3), - [result4] "=&r"(result4), [step2_10] "=r"(step2_10), - [step2_11] "=r"(step2_11), [step2_12] "=r"(step2_12), - [step2_13] "=r"(step2_13) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_22_64] "r"(cospi_22_64), [cospi_10_64] "r"(cospi_10_64), - [cospi_6_64] "r"(cospi_6_64), [cospi_26_64] "r"(cospi_26_64), - [cospi_24_64] "r"(cospi_24_64), [cospi_8_64] "r"(cospi_8_64)); - - __asm__ __volatile__( - "lh %[load5], 4(%[input]) \n\t" - "lh %[load6], 28(%[input]) \n\t" - "lh %[load7], 20(%[input]) \n\t" - "lh %[load8], 12(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load5], %[cospi_28_64] \n\t" - "msub $ac1, %[load6], %[cospi_4_64] \n\t" - "extp %[result1], $ac1, 31 \n\t" - - "madd $ac3, %[load7], %[cospi_12_64] \n\t" - "msub $ac3, %[load8], %[cospi_20_64] \n\t" - "extp %[result2], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac1, %[load7], %[cospi_20_64] \n\t" - "madd $ac1, %[load8], %[cospi_12_64] \n\t" - "extp %[result3], $ac1, 31 \n\t" - - "madd $ac2, %[load5], %[cospi_4_64] \n\t" - "madd $ac2, %[load6], %[cospi_28_64] \n\t" - "extp %[result4], $ac2, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load5], %[result4], %[result3] \n\t" - "sub %[load5], %[load5], %[result1] \n\t" - "add %[load5], %[load5], %[result2] \n\t" - - "sub %[load6], %[result1], %[result2] \n\t" - "sub %[load6], %[load6], %[result3] \n\t" - "add %[load6], %[load6], %[result4] \n\t" - - "madd $ac1, %[load5], %[cospi_16_64] \n\t" - "madd $ac3, %[load6], %[cospi_16_64] \n\t" - - "extp %[step1_5], $ac1, 31 \n\t" - "extp %[step1_6], $ac3, 31 \n\t" - - "add %[step1_4], %[result1], %[result2] \n\t" - "add %[step1_7], %[result4], %[result3] \n\t" - - : [load5] "=&r"(load5), [load6] "=&r"(load6), [load7] "=&r"(load7), - [load8] "=&r"(load8), [result1] "=&r"(result1), - [result2] "=&r"(result2), [result3] "=&r"(result3), - [result4] "=&r"(result4), [step1_4] "=r"(step1_4), - [step1_5] "=r"(step1_5), [step1_6] "=r"(step1_6), - [step1_7] "=r"(step1_7) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_20_64] "r"(cospi_20_64), [cospi_12_64] "r"(cospi_12_64), - [cospi_4_64] "r"(cospi_4_64), [cospi_28_64] "r"(cospi_28_64), - [cospi_16_64] "r"(cospi_16_64)); - - __asm__ __volatile__( - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - - "sub %[load5], %[step2_14], %[step2_13] \n\t" - "sub %[load5], %[load5], %[step2_9] \n\t" - "add %[load5], %[load5], %[step2_10] \n\t" - - "madd $ac0, %[load5], %[cospi_16_64] \n\t" - - "sub %[load6], %[step2_14], %[step2_13] \n\t" - "sub %[load6], %[load6], %[step2_10] \n\t" - "add %[load6], %[load6], %[step2_9] \n\t" - - "madd $ac1, %[load6], %[cospi_16_64] \n\t" - - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load5], %[step2_15], %[step2_12] \n\t" - "sub %[load5], %[load5], %[step2_8] \n\t" - "add %[load5], %[load5], %[step2_11] \n\t" - - "madd $ac2, %[load5], %[cospi_16_64] \n\t" - - "sub %[load6], %[step2_15], %[step2_12] \n\t" - "sub %[load6], %[load6], %[step2_11] \n\t" - "add %[load6], %[load6], %[step2_8] \n\t" - - "madd $ac3, %[load6], %[cospi_16_64] \n\t" - - "extp %[step1_10], $ac0, 31 \n\t" - "extp %[step1_13], $ac1, 31 \n\t" - "extp %[step1_11], $ac2, 31 \n\t" - "extp %[step1_12], $ac3, 31 \n\t" - - : [load5] "=&r"(load5), [load6] "=&r"(load6), [step1_10] "=r"(step1_10), - [step1_11] "=r"(step1_11), [step1_12] "=r"(step1_12), - [step1_13] "=r"(step1_13) - : [const_2_power_13] "r"(const_2_power_13), [step2_14] "r"(step2_14), - [step2_13] "r"(step2_13), [step2_9] "r"(step2_9), - [step2_10] "r"(step2_10), [step2_15] "r"(step2_15), - [step2_12] "r"(step2_12), [step2_8] "r"(step2_8), - [step2_11] "r"(step2_11), [cospi_16_64] "r"(cospi_16_64)); - - step1_8 = step2_8 + step2_11; - step1_9 = step2_9 + step2_10; - step1_14 = step2_13 + step2_14; - step1_15 = step2_12 + step2_15; - - __asm__ __volatile__( - "lbu %[load7], 0(%[dest_pix]) \n\t" - "add %[load5], %[step1_0], %[step1_7] \n\t" - "add %[load5], %[load5], %[step1_15] \n\t" - "addi %[load5], %[load5], 32 \n\t" - "sra %[load5], %[load5], 6 \n\t" - "add %[load7], %[load7], %[load5] \n\t" - "lbux %[load5], %[load7](%[cm]) \n\t" - "add %[load6], %[step1_1], %[step1_6] \n\t" - "add %[load6], %[load6], %[step1_14] \n\t" - "sb %[load5], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - "lbu %[load8], 0(%[dest_pix]) \n\t" - "addi %[load6], %[load6], 32 \n\t" - "sra %[load6], %[load6], 6 \n\t" - "add %[load8], %[load8], %[load6] \n\t" - "lbux %[load6], %[load8](%[cm]) \n\t" - "sb %[load6], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "lbu %[load7], 0(%[dest_pix]) \n\t" - "add %[load5], %[step1_2], %[step1_5] \n\t" - "add %[load5], %[load5], %[step1_13] \n\t" - "addi %[load5], %[load5], 32 \n\t" - "sra %[load5], %[load5], 6 \n\t" - "add %[load7], %[load7], %[load5] \n\t" - "lbux %[load5], %[load7](%[cm]) \n\t" - "add %[load6], %[step1_3], %[step1_4] \n\t" - "add %[load6], %[load6], %[step1_12] \n\t" - "sb %[load5], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - "lbu %[load8], 0(%[dest_pix]) \n\t" - "addi %[load6], %[load6], 32 \n\t" - "sra %[load6], %[load6], 6 \n\t" - "add %[load8], %[load8], %[load6] \n\t" - "lbux %[load6], %[load8](%[cm]) \n\t" - "sb %[load6], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "lbu %[load7], 0(%[dest_pix]) \n\t" - "sub %[load5], %[step1_3], %[step1_4] \n\t" - "add %[load5], %[load5], %[step1_11] \n\t" - "addi %[load5], %[load5], 32 \n\t" - "sra %[load5], %[load5], 6 \n\t" - "add %[load7], %[load7], %[load5] \n\t" - "lbux %[load5], %[load7](%[cm]) \n\t" - "sub %[load6], %[step1_2], %[step1_5] \n\t" - "add %[load6], %[load6], %[step1_10] \n\t" - "sb %[load5], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - "lbu %[load8], 0(%[dest_pix]) \n\t" - "addi %[load6], %[load6], 32 \n\t" - "sra %[load6], %[load6], 6 \n\t" - "add %[load8], %[load8], %[load6] \n\t" - "lbux %[load6], %[load8](%[cm]) \n\t" - "sb %[load6], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "sub %[load5], %[step1_1], %[step1_6] \n\t" - "lbu %[load7], 0(%[dest_pix]) \n\t" - "add %[load5], %[load5], %[step1_9] \n\t" - "addi %[load5], %[load5], 32 \n\t" - "sra %[load5], %[load5], 6 \n\t" - "add %[load7], %[load7], %[load5] \n\t" - "lbux %[load5], %[load7](%[cm]) \n\t" - "sub %[load6], %[step1_0], %[step1_7] \n\t" - "add %[load6], %[load6], %[step1_8] \n\t" - "sb %[load5], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - "lbu %[load8], 0(%[dest_pix]) \n\t" - "addi %[load6], %[load6], 32 \n\t" - "sra %[load6], %[load6], 6 \n\t" - "add %[load8], %[load8], %[load6] \n\t" - "lbux %[load6], %[load8](%[cm]) \n\t" - "sb %[load6], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "lbu %[load7], 0(%[dest_pix]) \n\t" - "sub %[load5], %[step1_0], %[step1_7] \n\t" - "sub %[load5], %[load5], %[step1_8] \n\t" - "addi %[load5], %[load5], 32 \n\t" - "sra %[load5], %[load5], 6 \n\t" - "add %[load7], %[load7], %[load5] \n\t" - "lbux %[load5], %[load7](%[cm]) \n\t" - "sub %[load6], %[step1_1], %[step1_6] \n\t" - "sub %[load6], %[load6], %[step1_9] \n\t" - "sb %[load5], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - "lbu %[load8], 0(%[dest_pix]) \n\t" - "addi %[load6], %[load6], 32 \n\t" - "sra %[load6], %[load6], 6 \n\t" - "add %[load8], %[load8], %[load6] \n\t" - "lbux %[load6], %[load8](%[cm]) \n\t" - "sb %[load6], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "lbu %[load7], 0(%[dest_pix]) \n\t" - "sub %[load5], %[step1_2], %[step1_5] \n\t" - "sub %[load5], %[load5], %[step1_10] \n\t" - "addi %[load5], %[load5], 32 \n\t" - "sra %[load5], %[load5], 6 \n\t" - "add %[load7], %[load7], %[load5] \n\t" - "lbux %[load5], %[load7](%[cm]) \n\t" - "sub %[load6], %[step1_3], %[step1_4] \n\t" - "sub %[load6], %[load6], %[step1_11] \n\t" - "sb %[load5], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - "lbu %[load8], 0(%[dest_pix]) \n\t" - "addi %[load6], %[load6], 32 \n\t" - "sra %[load6], %[load6], 6 \n\t" - "add %[load8], %[load8], %[load6] \n\t" - "lbux %[load6], %[load8](%[cm]) \n\t" - "sb %[load6], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "lbu %[load7], 0(%[dest_pix]) \n\t" - "add %[load5], %[step1_3], %[step1_4] \n\t" - "sub %[load5], %[load5], %[step1_12] \n\t" - "addi %[load5], %[load5], 32 \n\t" - "sra %[load5], %[load5], 6 \n\t" - "add %[load7], %[load7], %[load5] \n\t" - "lbux %[load5], %[load7](%[cm]) \n\t" - "add %[load6], %[step1_2], %[step1_5] \n\t" - "sub %[load6], %[load6], %[step1_13] \n\t" - "sb %[load5], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - "lbu %[load8], 0(%[dest_pix]) \n\t" - "addi %[load6], %[load6], 32 \n\t" - "sra %[load6], %[load6], 6 \n\t" - "add %[load8], %[load8], %[load6] \n\t" - "lbux %[load6], %[load8](%[cm]) \n\t" - "sb %[load6], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "lbu %[load7], 0(%[dest_pix]) \n\t" - "add %[load5], %[step1_1], %[step1_6] \n\t" - "sub %[load5], %[load5], %[step1_14] \n\t" - "addi %[load5], %[load5], 32 \n\t" - "sra %[load5], %[load5], 6 \n\t" - "add %[load7], %[load7], %[load5] \n\t" - "lbux %[load5], %[load7](%[cm]) \n\t" - "add %[load6], %[step1_0], %[step1_7] \n\t" - "sub %[load6], %[load6], %[step1_15] \n\t" - "sb %[load5], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - "lbu %[load8], 0(%[dest_pix]) \n\t" - "addi %[load6], %[load6], 32 \n\t" - "sra %[load6], %[load6], 6 \n\t" - "add %[load8], %[load8], %[load6] \n\t" - "lbux %[load6], %[load8](%[cm]) \n\t" - "sb %[load6], 0(%[dest_pix]) \n\t" - - : [load5] "=&r"(load5), [load6] "=&r"(load6), [load7] "=&r"(load7), - [load8] "=&r"(load8), [dest_pix] "+r"(dest_pix) - : - [cm] "r"(cm), [stride] "r"(stride), [step1_0] "r"(step1_0), - [step1_1] "r"(step1_1), [step1_2] "r"(step1_2), [step1_3] "r"(step1_3), - [step1_4] "r"(step1_4), [step1_5] "r"(step1_5), [step1_6] "r"(step1_6), - [step1_7] "r"(step1_7), [step1_8] "r"(step1_8), [step1_9] "r"(step1_9), - [step1_10] "r"(step1_10), [step1_11] "r"(step1_11), - [step1_12] "r"(step1_12), [step1_13] "r"(step1_13), - [step1_14] "r"(step1_14), [step1_15] "r"(step1_15)); - - input += 16; - } -} - -void vpx_idct16x16_256_add_dspr2(const int16_t *input, uint8_t *dest, - int stride) { - DECLARE_ALIGNED(32, int16_t, out[16 * 16]); - uint32_t pos = 45; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" : : [pos] "r"(pos)); - - // First transform rows - idct16_rows_dspr2(input, out, 16); - - // Then transform columns and add to dest - idct16_cols_add_blk_dspr2(out, dest, stride); -} - -void vpx_idct16x16_10_add_dspr2(const int16_t *input, uint8_t *dest, - int stride) { - DECLARE_ALIGNED(32, int16_t, out[16 * 16]); - int16_t *outptr = out; - uint32_t i; - uint32_t pos = 45; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" : : [pos] "r"(pos)); - - // First transform rows. Since all non-zero dct coefficients are in - // upper-left 4x4 area, we only need to calculate first 4 rows here. - idct16_rows_dspr2(input, outptr, 4); - - outptr += 4; - for (i = 0; i < 6; ++i) { - __asm__ __volatile__( - "sw $zero, 0(%[outptr]) \n\t" - "sw $zero, 32(%[outptr]) \n\t" - "sw $zero, 64(%[outptr]) \n\t" - "sw $zero, 96(%[outptr]) \n\t" - "sw $zero, 128(%[outptr]) \n\t" - "sw $zero, 160(%[outptr]) \n\t" - "sw $zero, 192(%[outptr]) \n\t" - "sw $zero, 224(%[outptr]) \n\t" - "sw $zero, 256(%[outptr]) \n\t" - "sw $zero, 288(%[outptr]) \n\t" - "sw $zero, 320(%[outptr]) \n\t" - "sw $zero, 352(%[outptr]) \n\t" - "sw $zero, 384(%[outptr]) \n\t" - "sw $zero, 416(%[outptr]) \n\t" - "sw $zero, 448(%[outptr]) \n\t" - "sw $zero, 480(%[outptr]) \n\t" - - : - : [outptr] "r"(outptr)); - - outptr += 2; - } - - // Then transform columns - idct16_cols_add_blk_dspr2(out, dest, stride); -} - -void vpx_idct16x16_1_add_dspr2(const int16_t *input, uint8_t *dest, - int stride) { - uint32_t pos = 45; - int32_t out; - int32_t r; - int32_t a1, absa1; - int32_t vector_a1; - int32_t t1, t2, t3, t4; - int32_t vector_1, vector_2, vector_3, vector_4; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - - : - : [pos] "r"(pos)); - - out = DCT_CONST_ROUND_SHIFT_TWICE_COSPI_16_64(input[0]); - __asm__ __volatile__( - "addi %[out], %[out], 32 \n\t" - "sra %[a1], %[out], 6 \n\t" - - : [out] "+r"(out), [a1] "=r"(a1) - :); - - if (a1 < 0) { - /* use quad-byte - * input and output memory are four byte aligned */ - __asm__ __volatile__( - "abs %[absa1], %[a1] \n\t" - "replv.qb %[vector_a1], %[absa1] \n\t" - - : [absa1] "=r"(absa1), [vector_a1] "=r"(vector_a1) - : [a1] "r"(a1)); - - for (r = 16; r--;) { - __asm__ __volatile__( - "lw %[t1], 0(%[dest]) \n\t" - "lw %[t2], 4(%[dest]) \n\t" - "lw %[t3], 8(%[dest]) \n\t" - "lw %[t4], 12(%[dest]) \n\t" - "subu_s.qb %[vector_1], %[t1], %[vector_a1] \n\t" - "subu_s.qb %[vector_2], %[t2], %[vector_a1] \n\t" - "subu_s.qb %[vector_3], %[t3], %[vector_a1] \n\t" - "subu_s.qb %[vector_4], %[t4], %[vector_a1] \n\t" - "sw %[vector_1], 0(%[dest]) \n\t" - "sw %[vector_2], 4(%[dest]) \n\t" - "sw %[vector_3], 8(%[dest]) \n\t" - "sw %[vector_4], 12(%[dest]) \n\t" - "add %[dest], %[dest], %[stride] \n\t" - - : [t1] "=&r"(t1), [t2] "=&r"(t2), [t3] "=&r"(t3), [t4] "=&r"(t4), - [vector_1] "=&r"(vector_1), [vector_2] "=&r"(vector_2), - [vector_3] "=&r"(vector_3), [vector_4] "=&r"(vector_4), - [dest] "+&r"(dest) - : [stride] "r"(stride), [vector_a1] "r"(vector_a1)); - } - } else if (a1 > 255) { - int32_t a11, a12, vector_a11, vector_a12; - - /* use quad-byte - * input and output memory are four byte aligned */ - a11 = a1 >> 1; - a12 = a1 - a11; - __asm__ __volatile__( - "replv.qb %[vector_a11], %[a11] \n\t" - "replv.qb %[vector_a12], %[a12] \n\t" - - : [vector_a11] "=&r"(vector_a11), [vector_a12] "=&r"(vector_a12) - : [a11] "r"(a11), [a12] "r"(a12)); - - for (r = 16; r--;) { - __asm__ __volatile__( - "lw %[t1], 0(%[dest]) \n\t" - "lw %[t2], 4(%[dest]) \n\t" - "lw %[t3], 8(%[dest]) \n\t" - "lw %[t4], 12(%[dest]) \n\t" - "addu_s.qb %[vector_1], %[t1], %[vector_a11] \n\t" - "addu_s.qb %[vector_2], %[t2], %[vector_a11] \n\t" - "addu_s.qb %[vector_3], %[t3], %[vector_a11] \n\t" - "addu_s.qb %[vector_4], %[t4], %[vector_a11] \n\t" - "addu_s.qb %[vector_1], %[vector_1], %[vector_a12] \n\t" - "addu_s.qb %[vector_2], %[vector_2], %[vector_a12] \n\t" - "addu_s.qb %[vector_3], %[vector_3], %[vector_a12] \n\t" - "addu_s.qb %[vector_4], %[vector_4], %[vector_a12] \n\t" - "sw %[vector_1], 0(%[dest]) \n\t" - "sw %[vector_2], 4(%[dest]) \n\t" - "sw %[vector_3], 8(%[dest]) \n\t" - "sw %[vector_4], 12(%[dest]) \n\t" - "add %[dest], %[dest], %[stride] \n\t" - - : [t1] "=&r"(t1), [t2] "=&r"(t2), [t3] "=&r"(t3), [t4] "=&r"(t4), - [vector_1] "=&r"(vector_1), [vector_2] "=&r"(vector_2), - [vector_3] "=&r"(vector_3), [vector_4] "=&r"(vector_4), - [dest] "+&r"(dest) - : [stride] "r"(stride), [vector_a11] "r"(vector_a11), - [vector_a12] "r"(vector_a12)); - } - } else { - /* use quad-byte - * input and output memory are four byte aligned */ - __asm__ __volatile__("replv.qb %[vector_a1], %[a1] \n\t" - - : [vector_a1] "=r"(vector_a1) - : [a1] "r"(a1)); - - for (r = 16; r--;) { - __asm__ __volatile__( - "lw %[t1], 0(%[dest]) \n\t" - "lw %[t2], 4(%[dest]) \n\t" - "lw %[t3], 8(%[dest]) \n\t" - "lw %[t4], 12(%[dest]) \n\t" - "addu_s.qb %[vector_1], %[t1], %[vector_a1] \n\t" - "addu_s.qb %[vector_2], %[t2], %[vector_a1] \n\t" - "addu_s.qb %[vector_3], %[t3], %[vector_a1] \n\t" - "addu_s.qb %[vector_4], %[t4], %[vector_a1] \n\t" - "sw %[vector_1], 0(%[dest]) \n\t" - "sw %[vector_2], 4(%[dest]) \n\t" - "sw %[vector_3], 8(%[dest]) \n\t" - "sw %[vector_4], 12(%[dest]) \n\t" - "add %[dest], %[dest], %[stride] \n\t" - - : [t1] "=&r"(t1), [t2] "=&r"(t2), [t3] "=&r"(t3), [t4] "=&r"(t4), - [vector_1] "=&r"(vector_1), [vector_2] "=&r"(vector_2), - [vector_3] "=&r"(vector_3), [vector_4] "=&r"(vector_4), - [dest] "+&r"(dest) - : [stride] "r"(stride), [vector_a1] "r"(vector_a1)); - } - } -} - -void iadst16_dspr2(const int16_t *input, int16_t *output) { - int s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15; - - int x0 = input[15]; - int x1 = input[0]; - int x2 = input[13]; - int x3 = input[2]; - int x4 = input[11]; - int x5 = input[4]; - int x6 = input[9]; - int x7 = input[6]; - int x8 = input[7]; - int x9 = input[8]; - int x10 = input[5]; - int x11 = input[10]; - int x12 = input[3]; - int x13 = input[12]; - int x14 = input[1]; - int x15 = input[14]; - - if (!(x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | x11 | x12 | - x13 | x14 | x15)) { - output[0] = output[1] = output[2] = output[3] = output[4] = output[5] = - output[6] = output[7] = output[8] = output[9] = output[10] = - output[11] = output[12] = output[13] = output[14] = output[15] = 0; - return; - } - - // stage 1 - s0 = x0 * cospi_1_64 + x1 * cospi_31_64; - s1 = x0 * cospi_31_64 - x1 * cospi_1_64; - s2 = x2 * cospi_5_64 + x3 * cospi_27_64; - s3 = x2 * cospi_27_64 - x3 * cospi_5_64; - s4 = x4 * cospi_9_64 + x5 * cospi_23_64; - s5 = x4 * cospi_23_64 - x5 * cospi_9_64; - s6 = x6 * cospi_13_64 + x7 * cospi_19_64; - s7 = x6 * cospi_19_64 - x7 * cospi_13_64; - s8 = x8 * cospi_17_64 + x9 * cospi_15_64; - s9 = x8 * cospi_15_64 - x9 * cospi_17_64; - s10 = x10 * cospi_21_64 + x11 * cospi_11_64; - s11 = x10 * cospi_11_64 - x11 * cospi_21_64; - s12 = x12 * cospi_25_64 + x13 * cospi_7_64; - s13 = x12 * cospi_7_64 - x13 * cospi_25_64; - s14 = x14 * cospi_29_64 + x15 * cospi_3_64; - s15 = x14 * cospi_3_64 - x15 * cospi_29_64; - - x0 = dct_const_round_shift(s0 + s8); - x1 = dct_const_round_shift(s1 + s9); - x2 = dct_const_round_shift(s2 + s10); - x3 = dct_const_round_shift(s3 + s11); - x4 = dct_const_round_shift(s4 + s12); - x5 = dct_const_round_shift(s5 + s13); - x6 = dct_const_round_shift(s6 + s14); - x7 = dct_const_round_shift(s7 + s15); - x8 = dct_const_round_shift(s0 - s8); - x9 = dct_const_round_shift(s1 - s9); - x10 = dct_const_round_shift(s2 - s10); - x11 = dct_const_round_shift(s3 - s11); - x12 = dct_const_round_shift(s4 - s12); - x13 = dct_const_round_shift(s5 - s13); - x14 = dct_const_round_shift(s6 - s14); - x15 = dct_const_round_shift(s7 - s15); - - // stage 2 - s0 = x0; - s1 = x1; - s2 = x2; - s3 = x3; - s4 = x4; - s5 = x5; - s6 = x6; - s7 = x7; - s8 = x8 * cospi_4_64 + x9 * cospi_28_64; - s9 = x8 * cospi_28_64 - x9 * cospi_4_64; - s10 = x10 * cospi_20_64 + x11 * cospi_12_64; - s11 = x10 * cospi_12_64 - x11 * cospi_20_64; - s12 = -x12 * cospi_28_64 + x13 * cospi_4_64; - s13 = x12 * cospi_4_64 + x13 * cospi_28_64; - s14 = -x14 * cospi_12_64 + x15 * cospi_20_64; - s15 = x14 * cospi_20_64 + x15 * cospi_12_64; - - x0 = s0 + s4; - x1 = s1 + s5; - x2 = s2 + s6; - x3 = s3 + s7; - x4 = s0 - s4; - x5 = s1 - s5; - x6 = s2 - s6; - x7 = s3 - s7; - x8 = dct_const_round_shift(s8 + s12); - x9 = dct_const_round_shift(s9 + s13); - x10 = dct_const_round_shift(s10 + s14); - x11 = dct_const_round_shift(s11 + s15); - x12 = dct_const_round_shift(s8 - s12); - x13 = dct_const_round_shift(s9 - s13); - x14 = dct_const_round_shift(s10 - s14); - x15 = dct_const_round_shift(s11 - s15); - - // stage 3 - s0 = x0; - s1 = x1; - s2 = x2; - s3 = x3; - s4 = x4 * cospi_8_64 + x5 * cospi_24_64; - s5 = x4 * cospi_24_64 - x5 * cospi_8_64; - s6 = -x6 * cospi_24_64 + x7 * cospi_8_64; - s7 = x6 * cospi_8_64 + x7 * cospi_24_64; - s8 = x8; - s9 = x9; - s10 = x10; - s11 = x11; - s12 = x12 * cospi_8_64 + x13 * cospi_24_64; - s13 = x12 * cospi_24_64 - x13 * cospi_8_64; - s14 = -x14 * cospi_24_64 + x15 * cospi_8_64; - s15 = x14 * cospi_8_64 + x15 * cospi_24_64; - - x0 = s0 + s2; - x1 = s1 + s3; - x2 = s0 - s2; - x3 = s1 - s3; - x4 = dct_const_round_shift(s4 + s6); - x5 = dct_const_round_shift(s5 + s7); - x6 = dct_const_round_shift(s4 - s6); - x7 = dct_const_round_shift(s5 - s7); - x8 = s8 + s10; - x9 = s9 + s11; - x10 = s8 - s10; - x11 = s9 - s11; - x12 = dct_const_round_shift(s12 + s14); - x13 = dct_const_round_shift(s13 + s15); - x14 = dct_const_round_shift(s12 - s14); - x15 = dct_const_round_shift(s13 - s15); - - // stage 4 - s2 = (-cospi_16_64) * (x2 + x3); - s3 = cospi_16_64 * (x2 - x3); - s6 = cospi_16_64 * (x6 + x7); - s7 = cospi_16_64 * (-x6 + x7); - s10 = cospi_16_64 * (x10 + x11); - s11 = cospi_16_64 * (-x10 + x11); - s14 = (-cospi_16_64) * (x14 + x15); - s15 = cospi_16_64 * (x14 - x15); - - x2 = dct_const_round_shift(s2); - x3 = dct_const_round_shift(s3); - x6 = dct_const_round_shift(s6); - x7 = dct_const_round_shift(s7); - x10 = dct_const_round_shift(s10); - x11 = dct_const_round_shift(s11); - x14 = dct_const_round_shift(s14); - x15 = dct_const_round_shift(s15); - - output[0] = x0; - output[1] = -x8; - output[2] = x12; - output[3] = -x4; - output[4] = x6; - output[5] = x14; - output[6] = x10; - output[7] = x2; - output[8] = x3; - output[9] = x11; - output[10] = x15; - output[11] = x7; - output[12] = x5; - output[13] = -x13; - output[14] = x9; - output[15] = -x1; -} - -#endif // HAVE_DSPR2 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/itrans32_cols_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/itrans32_cols_dspr2.c deleted file mode 100644 index 3f043b48..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/itrans32_cols_dspr2.c +++ /dev/null @@ -1,1119 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "vpx_dsp/mips/inv_txfm_dspr2.h" -#include "vpx_dsp/txfm_common.h" - -#if HAVE_DSPR2 -void vpx_idct32_cols_add_blk_dspr2(int16_t *input, uint8_t *dest, int stride) { - int step1_0, step1_1, step1_2, step1_3, step1_4, step1_5, step1_6; - int step1_7, step1_8, step1_9, step1_10, step1_11, step1_12, step1_13; - int step1_14, step1_15, step1_16, step1_17, step1_18, step1_19, step1_20; - int step1_21, step1_22, step1_23, step1_24, step1_25, step1_26, step1_27; - int step1_28, step1_29, step1_30, step1_31; - int step2_0, step2_1, step2_2, step2_3, step2_4, step2_5, step2_6; - int step2_7, step2_8, step2_9, step2_10, step2_11, step2_12, step2_13; - int step2_14, step2_15, step2_16, step2_17, step2_18, step2_19, step2_20; - int step2_21, step2_22, step2_23, step2_24, step2_25, step2_26, step2_27; - int step2_28, step2_29, step2_30, step2_31; - int step3_8, step3_9, step3_10, step3_11, step3_12, step3_13, step3_14; - int step3_15, step3_16, step3_17, step3_18, step3_19, step3_20, step3_21; - int step3_22, step3_23, step3_24, step3_25, step3_26, step3_27, step3_28; - int step3_29, step3_30, step3_31; - int temp0, temp1, temp2, temp3; - int load1, load2, load3, load4; - int result1, result2; - int i; - uint8_t *dest_pix, *dest_pix1; - const int const_2_power_13 = 8192; - uint8_t *cm = vpx_ff_cropTbl; - - /* prefetch vpx_ff_cropTbl */ - prefetch_load(vpx_ff_cropTbl); - prefetch_load(vpx_ff_cropTbl + 32); - prefetch_load(vpx_ff_cropTbl + 64); - prefetch_load(vpx_ff_cropTbl + 96); - prefetch_load(vpx_ff_cropTbl + 128); - prefetch_load(vpx_ff_cropTbl + 160); - prefetch_load(vpx_ff_cropTbl + 192); - prefetch_load(vpx_ff_cropTbl + 224); - - for (i = 0; i < 32; ++i) { - dest_pix = dest + i; - dest_pix1 = dest + i + 31 * stride; - - __asm__ __volatile__( - "lh %[load1], 2(%[input]) \n\t" - "lh %[load2], 62(%[input]) \n\t" - "lh %[load3], 34(%[input]) \n\t" - "lh %[load4], 30(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load1], %[cospi_31_64] \n\t" - "msub $ac1, %[load2], %[cospi_1_64] \n\t" - "extp %[temp0], $ac1, 31 \n\t" - - "madd $ac3, %[load1], %[cospi_1_64] \n\t" - "madd $ac3, %[load2], %[cospi_31_64] \n\t" - "extp %[temp3], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac2, %[load3], %[cospi_15_64] \n\t" - "msub $ac2, %[load4], %[cospi_17_64] \n\t" - "extp %[temp1], $ac2, 31 \n\t" - - "madd $ac1, %[load3], %[cospi_17_64] \n\t" - "madd $ac1, %[load4], %[cospi_15_64] \n\t" - "extp %[temp2], $ac1, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load1], %[temp3], %[temp2] \n\t" - "sub %[load2], %[temp0], %[temp1] \n\t" - - "madd $ac1, %[load1], %[cospi_28_64] \n\t" - "msub $ac1, %[load2], %[cospi_4_64] \n\t" - "madd $ac3, %[load1], %[cospi_4_64] \n\t" - "madd $ac3, %[load2], %[cospi_28_64] \n\t" - - "extp %[step1_17], $ac1, 31 \n\t" - "extp %[step1_30], $ac3, 31 \n\t" - "add %[step1_16], %[temp0], %[temp1] \n\t" - "add %[step1_31], %[temp2], %[temp3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [temp2] "=&r"(temp2), [temp3] "=&r"(temp3), - [step1_16] "=&r"(step1_16), [step1_17] "=&r"(step1_17), - [step1_30] "=&r"(step1_30), [step1_31] "=&r"(step1_31) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_31_64] "r"(cospi_31_64), [cospi_1_64] "r"(cospi_1_64), - [cospi_4_64] "r"(cospi_4_64), [cospi_17_64] "r"(cospi_17_64), - [cospi_15_64] "r"(cospi_15_64), [cospi_28_64] "r"(cospi_28_64)); - - __asm__ __volatile__( - "lh %[load1], 18(%[input]) \n\t" - "lh %[load2], 46(%[input]) \n\t" - "lh %[load3], 50(%[input]) \n\t" - "lh %[load4], 14(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load1], %[cospi_23_64] \n\t" - "msub $ac1, %[load2], %[cospi_9_64] \n\t" - "extp %[temp0], $ac1, 31 \n\t" - - "madd $ac3, %[load1], %[cospi_9_64] \n\t" - "madd $ac3, %[load2], %[cospi_23_64] \n\t" - "extp %[temp3], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac2, %[load3], %[cospi_7_64] \n\t" - "msub $ac2, %[load4], %[cospi_25_64] \n\t" - "extp %[temp1], $ac2, 31 \n\t" - - "madd $ac1, %[load3], %[cospi_25_64] \n\t" - "madd $ac1, %[load4], %[cospi_7_64] \n\t" - "extp %[temp2], $ac1, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load1], %[temp1], %[temp0] \n\t" - "sub %[load2], %[temp2], %[temp3] \n\t" - - "msub $ac1, %[load1], %[cospi_28_64] \n\t" - "msub $ac1, %[load2], %[cospi_4_64] \n\t" - "msub $ac3, %[load1], %[cospi_4_64] \n\t" - "madd $ac3, %[load2], %[cospi_28_64] \n\t" - - "extp %[step1_18], $ac1, 31 \n\t" - "extp %[step1_29], $ac3, 31 \n\t" - "add %[step1_19], %[temp0], %[temp1] \n\t" - "add %[step1_28], %[temp2], %[temp3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [temp2] "=&r"(temp2), [temp3] "=&r"(temp3), - [step1_18] "=&r"(step1_18), [step1_19] "=&r"(step1_19), - [step1_28] "=&r"(step1_28), [step1_29] "=&r"(step1_29) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_23_64] "r"(cospi_23_64), [cospi_9_64] "r"(cospi_9_64), - [cospi_4_64] "r"(cospi_4_64), [cospi_7_64] "r"(cospi_7_64), - [cospi_25_64] "r"(cospi_25_64), [cospi_28_64] "r"(cospi_28_64)); - - __asm__ __volatile__( - "lh %[load1], 10(%[input]) \n\t" - "lh %[load2], 54(%[input]) \n\t" - "lh %[load3], 42(%[input]) \n\t" - "lh %[load4], 22(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load1], %[cospi_27_64] \n\t" - "msub $ac1, %[load2], %[cospi_5_64] \n\t" - "extp %[temp0], $ac1, 31 \n\t" - - "madd $ac3, %[load1], %[cospi_5_64] \n\t" - "madd $ac3, %[load2], %[cospi_27_64] \n\t" - "extp %[temp3], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac2, %[load3], %[cospi_11_64] \n\t" - "msub $ac2, %[load4], %[cospi_21_64] \n\t" - "extp %[temp1], $ac2, 31 \n\t" - - "madd $ac1, %[load3], %[cospi_21_64] \n\t" - "madd $ac1, %[load4], %[cospi_11_64] \n\t" - "extp %[temp2], $ac1, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load1], %[temp0], %[temp1] \n\t" - "sub %[load2], %[temp3], %[temp2] \n\t" - - "madd $ac1, %[load2], %[cospi_12_64] \n\t" - "msub $ac1, %[load1], %[cospi_20_64] \n\t" - "madd $ac3, %[load1], %[cospi_12_64] \n\t" - "madd $ac3, %[load2], %[cospi_20_64] \n\t" - - "extp %[step1_21], $ac1, 31 \n\t" - "extp %[step1_26], $ac3, 31 \n\t" - "add %[step1_20], %[temp0], %[temp1] \n\t" - "add %[step1_27], %[temp2], %[temp3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [temp2] "=&r"(temp2), [temp3] "=&r"(temp3), - [step1_20] "=&r"(step1_20), [step1_21] "=&r"(step1_21), - [step1_26] "=&r"(step1_26), [step1_27] "=&r"(step1_27) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_27_64] "r"(cospi_27_64), [cospi_5_64] "r"(cospi_5_64), - [cospi_11_64] "r"(cospi_11_64), [cospi_21_64] "r"(cospi_21_64), - [cospi_12_64] "r"(cospi_12_64), [cospi_20_64] "r"(cospi_20_64)); - - __asm__ __volatile__( - "lh %[load1], 26(%[input]) \n\t" - "lh %[load2], 38(%[input]) \n\t" - "lh %[load3], 58(%[input]) \n\t" - "lh %[load4], 6(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load1], %[cospi_19_64] \n\t" - "msub $ac1, %[load2], %[cospi_13_64] \n\t" - "extp %[temp0], $ac1, 31 \n\t" - "madd $ac3, %[load1], %[cospi_13_64] \n\t" - "madd $ac3, %[load2], %[cospi_19_64] \n\t" - "extp %[temp3], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac2, %[load3], %[cospi_3_64] \n\t" - "msub $ac2, %[load4], %[cospi_29_64] \n\t" - "extp %[temp1], $ac2, 31 \n\t" - "madd $ac1, %[load3], %[cospi_29_64] \n\t" - "madd $ac1, %[load4], %[cospi_3_64] \n\t" - "extp %[temp2], $ac1, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load1], %[temp1], %[temp0] \n\t" - "sub %[load2], %[temp2], %[temp3] \n\t" - "msub $ac1, %[load1], %[cospi_12_64] \n\t" - "msub $ac1, %[load2], %[cospi_20_64] \n\t" - "msub $ac3, %[load1], %[cospi_20_64] \n\t" - "madd $ac3, %[load2], %[cospi_12_64] \n\t" - "extp %[step1_22], $ac1, 31 \n\t" - "extp %[step1_25], $ac3, 31 \n\t" - "add %[step1_23], %[temp0], %[temp1] \n\t" - "add %[step1_24], %[temp2], %[temp3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [temp2] "=&r"(temp2), [temp3] "=&r"(temp3), - [step1_22] "=&r"(step1_22), [step1_23] "=&r"(step1_23), - [step1_24] "=&r"(step1_24), [step1_25] "=&r"(step1_25) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_19_64] "r"(cospi_19_64), [cospi_13_64] "r"(cospi_13_64), - [cospi_3_64] "r"(cospi_3_64), [cospi_29_64] "r"(cospi_29_64), - [cospi_12_64] "r"(cospi_12_64), [cospi_20_64] "r"(cospi_20_64)); - - __asm__ __volatile__( - "lh %[load1], 4(%[input]) \n\t" - "lh %[load2], 60(%[input]) \n\t" - "lh %[load3], 36(%[input]) \n\t" - "lh %[load4], 28(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load1], %[cospi_30_64] \n\t" - "msub $ac1, %[load2], %[cospi_2_64] \n\t" - "extp %[temp0], $ac1, 31 \n\t" - "madd $ac3, %[load1], %[cospi_2_64] \n\t" - "madd $ac3, %[load2], %[cospi_30_64] \n\t" - "extp %[temp3], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac2, %[load3], %[cospi_14_64] \n\t" - "msub $ac2, %[load4], %[cospi_18_64] \n\t" - "extp %[temp1], $ac2, 31 \n\t" - "madd $ac1, %[load3], %[cospi_18_64] \n\t" - "madd $ac1, %[load4], %[cospi_14_64] \n\t" - "extp %[temp2], $ac1, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load1], %[temp0], %[temp1] \n\t" - "sub %[load2], %[temp3], %[temp2] \n\t" - "msub $ac1, %[load1], %[cospi_8_64] \n\t" - "madd $ac1, %[load2], %[cospi_24_64] \n\t" - "madd $ac3, %[load1], %[cospi_24_64] \n\t" - "madd $ac3, %[load2], %[cospi_8_64] \n\t" - "extp %[step2_9], $ac1, 31 \n\t" - "extp %[step2_14], $ac3, 31 \n\t" - "add %[step2_8], %[temp0], %[temp1] \n\t" - "add %[step2_15], %[temp2], %[temp3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [temp2] "=&r"(temp2), [temp3] "=&r"(temp3), [step2_8] "=&r"(step2_8), - [step2_9] "=&r"(step2_9), [step2_14] "=&r"(step2_14), - [step2_15] "=&r"(step2_15) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_30_64] "r"(cospi_30_64), [cospi_2_64] "r"(cospi_2_64), - [cospi_14_64] "r"(cospi_14_64), [cospi_18_64] "r"(cospi_18_64), - [cospi_8_64] "r"(cospi_8_64), [cospi_24_64] "r"(cospi_24_64)); - - __asm__ __volatile__( - "lh %[load1], 20(%[input]) \n\t" - "lh %[load2], 44(%[input]) \n\t" - "lh %[load3], 52(%[input]) \n\t" - "lh %[load4], 12(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load1], %[cospi_22_64] \n\t" - "msub $ac1, %[load2], %[cospi_10_64] \n\t" - "extp %[temp0], $ac1, 31 \n\t" - "madd $ac3, %[load1], %[cospi_10_64] \n\t" - "madd $ac3, %[load2], %[cospi_22_64] \n\t" - "extp %[temp3], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac2, %[load3], %[cospi_6_64] \n\t" - "msub $ac2, %[load4], %[cospi_26_64] \n\t" - "extp %[temp1], $ac2, 31 \n\t" - "madd $ac1, %[load3], %[cospi_26_64] \n\t" - "madd $ac1, %[load4], %[cospi_6_64] \n\t" - "extp %[temp2], $ac1, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load1], %[temp1], %[temp0] \n\t" - "sub %[load2], %[temp2], %[temp3] \n\t" - "msub $ac1, %[load1], %[cospi_24_64] \n\t" - "msub $ac1, %[load2], %[cospi_8_64] \n\t" - "madd $ac3, %[load2], %[cospi_24_64] \n\t" - "msub $ac3, %[load1], %[cospi_8_64] \n\t" - "extp %[step2_10], $ac1, 31 \n\t" - "extp %[step2_13], $ac3, 31 \n\t" - "add %[step2_11], %[temp0], %[temp1] \n\t" - "add %[step2_12], %[temp2], %[temp3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [temp2] "=&r"(temp2), [temp3] "=&r"(temp3), - [step2_10] "=&r"(step2_10), [step2_11] "=&r"(step2_11), - [step2_12] "=&r"(step2_12), [step2_13] "=&r"(step2_13) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_22_64] "r"(cospi_22_64), [cospi_10_64] "r"(cospi_10_64), - [cospi_6_64] "r"(cospi_6_64), [cospi_26_64] "r"(cospi_26_64), - [cospi_8_64] "r"(cospi_8_64), [cospi_24_64] "r"(cospi_24_64)); - - __asm__ __volatile__( - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "sub %[temp0], %[step2_14], %[step2_13] \n\t" - "sub %[temp0], %[temp0], %[step2_9] \n\t" - "add %[temp0], %[temp0], %[step2_10] \n\t" - "madd $ac0, %[temp0], %[cospi_16_64] \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "sub %[temp1], %[step2_14], %[step2_13] \n\t" - "add %[temp1], %[temp1], %[step2_9] \n\t" - "sub %[temp1], %[temp1], %[step2_10] \n\t" - "madd $ac1, %[temp1], %[cospi_16_64] \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "sub %[temp0], %[step2_15], %[step2_12] \n\t" - "sub %[temp0], %[temp0], %[step2_8] \n\t" - "add %[temp0], %[temp0], %[step2_11] \n\t" - "madd $ac2, %[temp0], %[cospi_16_64] \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "sub %[temp1], %[step2_15], %[step2_12] \n\t" - "add %[temp1], %[temp1], %[step2_8] \n\t" - "sub %[temp1], %[temp1], %[step2_11] \n\t" - "madd $ac3, %[temp1], %[cospi_16_64] \n\t" - - "add %[step3_8], %[step2_8], %[step2_11] \n\t" - "add %[step3_9], %[step2_9], %[step2_10] \n\t" - "add %[step3_14], %[step2_13], %[step2_14] \n\t" - "add %[step3_15], %[step2_12], %[step2_15] \n\t" - "extp %[step3_10], $ac0, 31 \n\t" - "extp %[step3_13], $ac1, 31 \n\t" - "extp %[step3_11], $ac2, 31 \n\t" - "extp %[step3_12], $ac3, 31 \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), [step3_8] "=&r"(step3_8), - [step3_9] "=&r"(step3_9), [step3_10] "=&r"(step3_10), - [step3_11] "=&r"(step3_11), [step3_12] "=&r"(step3_12), - [step3_13] "=&r"(step3_13), [step3_14] "=&r"(step3_14), - [step3_15] "=&r"(step3_15) - : [const_2_power_13] "r"(const_2_power_13), [step2_8] "r"(step2_8), - [step2_9] "r"(step2_9), [step2_10] "r"(step2_10), - [step2_11] "r"(step2_11), [step2_12] "r"(step2_12), - [step2_13] "r"(step2_13), [step2_14] "r"(step2_14), - [step2_15] "r"(step2_15), [cospi_16_64] "r"(cospi_16_64)); - - __asm__ __volatile__( - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "sub %[temp0], %[step1_17], %[step1_18] \n\t" - "sub %[temp1], %[step1_30], %[step1_29] \n\t" - "add %[step3_17], %[step1_17], %[step1_18] \n\t" - "add %[step3_30], %[step1_30], %[step1_29] \n\t" - - "msub $ac0, %[temp0], %[cospi_8_64] \n\t" - "madd $ac0, %[temp1], %[cospi_24_64] \n\t" - "extp %[step3_18], $ac0, 31 \n\t" - "madd $ac1, %[temp0], %[cospi_24_64] \n\t" - "madd $ac1, %[temp1], %[cospi_8_64] \n\t" - "extp %[step3_29], $ac1, 31 \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [step3_18] "=&r"(step3_18), [step3_29] "=&r"(step3_29), - [step3_17] "=&r"(step3_17), [step3_30] "=&r"(step3_30) - : [const_2_power_13] "r"(const_2_power_13), [step1_17] "r"(step1_17), - [step1_18] "r"(step1_18), [step1_30] "r"(step1_30), - [step1_29] "r"(step1_29), [cospi_24_64] "r"(cospi_24_64), - [cospi_8_64] "r"(cospi_8_64)); - - __asm__ __volatile__( - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "sub %[temp0], %[step1_16], %[step1_19] \n\t" - "sub %[temp1], %[step1_31], %[step1_28] \n\t" - "add %[step3_16], %[step1_16], %[step1_19] \n\t" - "add %[step3_31], %[step1_31], %[step1_28] \n\t" - - "msub $ac0, %[temp0], %[cospi_8_64] \n\t" - "madd $ac0, %[temp1], %[cospi_24_64] \n\t" - "extp %[step3_19], $ac0, 31 \n\t" - "madd $ac1, %[temp0], %[cospi_24_64] \n\t" - "madd $ac1, %[temp1], %[cospi_8_64] \n\t" - "extp %[step3_28], $ac1, 31 \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [step3_16] "=&r"(step3_16), [step3_31] "=&r"(step3_31), - [step3_19] "=&r"(step3_19), [step3_28] "=&r"(step3_28) - : [const_2_power_13] "r"(const_2_power_13), [step1_16] "r"(step1_16), - [step1_19] "r"(step1_19), [step1_31] "r"(step1_31), - [step1_28] "r"(step1_28), [cospi_24_64] "r"(cospi_24_64), - [cospi_8_64] "r"(cospi_8_64)); - - __asm__ __volatile__( - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "sub %[temp0], %[step1_23], %[step1_20] \n\t" - "sub %[temp1], %[step1_24], %[step1_27] \n\t" - "add %[step3_23], %[step1_23], %[step1_20] \n\t" - "add %[step3_24], %[step1_24], %[step1_27] \n\t" - - "msub $ac0, %[temp0], %[cospi_8_64] \n\t" - "madd $ac0, %[temp1], %[cospi_24_64] \n\t" - "extp %[step3_27], $ac0, 31 \n\t" - "msub $ac1, %[temp0], %[cospi_24_64] \n\t" - "msub $ac1, %[temp1], %[cospi_8_64] \n\t" - "extp %[step3_20], $ac1, 31 \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [step3_23] "=&r"(step3_23), [step3_24] "=&r"(step3_24), - [step3_20] "=&r"(step3_20), [step3_27] "=&r"(step3_27) - : [const_2_power_13] "r"(const_2_power_13), [step1_23] "r"(step1_23), - [step1_20] "r"(step1_20), [step1_24] "r"(step1_24), - [step1_27] "r"(step1_27), [cospi_24_64] "r"(cospi_24_64), - [cospi_8_64] "r"(cospi_8_64)); - - __asm__ __volatile__( - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "sub %[temp0], %[step1_22], %[step1_21] \n\t" - "sub %[temp1], %[step1_25], %[step1_26] \n\t" - "add %[step3_22], %[step1_22], %[step1_21] \n\t" - "add %[step3_25], %[step1_25], %[step1_26] \n\t" - - "msub $ac0, %[temp0], %[cospi_24_64] \n\t" - "msub $ac0, %[temp1], %[cospi_8_64] \n\t" - "extp %[step3_21], $ac0, 31 \n\t" - "msub $ac1, %[temp0], %[cospi_8_64] \n\t" - "madd $ac1, %[temp1], %[cospi_24_64] \n\t" - "extp %[step3_26], $ac1, 31 \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [step3_22] "=&r"(step3_22), [step3_25] "=&r"(step3_25), - [step3_21] "=&r"(step3_21), [step3_26] "=&r"(step3_26) - : [const_2_power_13] "r"(const_2_power_13), [step1_22] "r"(step1_22), - [step1_21] "r"(step1_21), [step1_25] "r"(step1_25), - [step1_26] "r"(step1_26), [cospi_24_64] "r"(cospi_24_64), - [cospi_8_64] "r"(cospi_8_64)); - - __asm__ __volatile__( - "add %[step2_16], %[step3_16], %[step3_23] \n\t" - "add %[step2_17], %[step3_17], %[step3_22] \n\t" - "add %[step2_18], %[step3_18], %[step3_21] \n\t" - "add %[step2_19], %[step3_19], %[step3_20] \n\t" - "sub %[step2_20], %[step3_19], %[step3_20] \n\t" - "sub %[step2_21], %[step3_18], %[step3_21] \n\t" - "sub %[step2_22], %[step3_17], %[step3_22] \n\t" - "sub %[step2_23], %[step3_16], %[step3_23] \n\t" - - : [step2_16] "=&r"(step2_16), [step2_17] "=&r"(step2_17), - [step2_18] "=&r"(step2_18), [step2_19] "=&r"(step2_19), - [step2_20] "=&r"(step2_20), [step2_21] "=&r"(step2_21), - [step2_22] "=&r"(step2_22), [step2_23] "=&r"(step2_23) - : [step3_16] "r"(step3_16), [step3_23] "r"(step3_23), - [step3_17] "r"(step3_17), [step3_22] "r"(step3_22), - [step3_18] "r"(step3_18), [step3_21] "r"(step3_21), - [step3_19] "r"(step3_19), [step3_20] "r"(step3_20)); - - __asm__ __volatile__( - "sub %[step2_24], %[step3_31], %[step3_24] \n\t" - "sub %[step2_25], %[step3_30], %[step3_25] \n\t" - "sub %[step2_26], %[step3_29], %[step3_26] \n\t" - "sub %[step2_27], %[step3_28], %[step3_27] \n\t" - "add %[step2_28], %[step3_28], %[step3_27] \n\t" - "add %[step2_29], %[step3_29], %[step3_26] \n\t" - "add %[step2_30], %[step3_30], %[step3_25] \n\t" - "add %[step2_31], %[step3_31], %[step3_24] \n\t" - - : [step2_24] "=&r"(step2_24), [step2_28] "=&r"(step2_28), - [step2_25] "=&r"(step2_25), [step2_29] "=&r"(step2_29), - [step2_26] "=&r"(step2_26), [step2_30] "=&r"(step2_30), - [step2_27] "=&r"(step2_27), [step2_31] "=&r"(step2_31) - : [step3_31] "r"(step3_31), [step3_24] "r"(step3_24), - [step3_30] "r"(step3_30), [step3_25] "r"(step3_25), - [step3_29] "r"(step3_29), [step3_26] "r"(step3_26), - [step3_28] "r"(step3_28), [step3_27] "r"(step3_27)); - - __asm__ __volatile__( - "lh %[load1], 0(%[input]) \n\t" - "lh %[load2], 32(%[input]) \n\t" - "lh %[load3], 16(%[input]) \n\t" - "lh %[load4], 48(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "add %[result1], %[load1], %[load2] \n\t" - "sub %[result2], %[load1], %[load2] \n\t" - "madd $ac1, %[result1], %[cospi_16_64] \n\t" - "madd $ac2, %[result2], %[cospi_16_64] \n\t" - "extp %[temp0], $ac1, 31 \n\t" - "extp %[temp1], $ac2, 31 \n\t" - - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "madd $ac3, %[load3], %[cospi_24_64] \n\t" - "msub $ac3, %[load4], %[cospi_8_64] \n\t" - "extp %[temp2], $ac3, 31 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "madd $ac1, %[load3], %[cospi_8_64] \n\t" - "madd $ac1, %[load4], %[cospi_24_64] \n\t" - "extp %[temp3], $ac1, 31 \n\t" - "add %[step1_0], %[temp0], %[temp3] \n\t" - "add %[step1_1], %[temp1], %[temp2] \n\t" - "sub %[step1_2], %[temp1], %[temp2] \n\t" - "sub %[step1_3], %[temp0], %[temp3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [result1] "=&r"(result1), - [result2] "=&r"(result2), [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [temp2] "=&r"(temp2), [temp3] "=&r"(temp3), [step1_0] "=&r"(step1_0), - [step1_1] "=&r"(step1_1), [step1_2] "=&r"(step1_2), - [step1_3] "=&r"(step1_3) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_24_64] "r"(cospi_24_64), [cospi_8_64] "r"(cospi_8_64), - [cospi_16_64] "r"(cospi_16_64)); - - __asm__ __volatile__( - "lh %[load1], 8(%[input]) \n\t" - "lh %[load2], 56(%[input]) \n\t" - "lh %[load3], 40(%[input]) \n\t" - "lh %[load4], 24(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load1], %[cospi_28_64] \n\t" - "msub $ac1, %[load2], %[cospi_4_64] \n\t" - "extp %[temp0], $ac1, 31 \n\t" - "madd $ac3, %[load1], %[cospi_4_64] \n\t" - "madd $ac3, %[load2], %[cospi_28_64] \n\t" - "extp %[temp3], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac2, %[load3], %[cospi_12_64] \n\t" - "msub $ac2, %[load4], %[cospi_20_64] \n\t" - "extp %[temp1], $ac2, 31 \n\t" - "madd $ac1, %[load3], %[cospi_20_64] \n\t" - "madd $ac1, %[load4], %[cospi_12_64] \n\t" - "extp %[temp2], $ac1, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load1], %[temp3], %[temp2] \n\t" - "sub %[load1], %[load1], %[temp0] \n\t" - "add %[load1], %[load1], %[temp1] \n\t" - "sub %[load2], %[temp0], %[temp1] \n\t" - "sub %[load2], %[load2], %[temp2] \n\t" - "add %[load2], %[load2], %[temp3] \n\t" - "madd $ac1, %[load1], %[cospi_16_64] \n\t" - "madd $ac3, %[load2], %[cospi_16_64] \n\t" - - "extp %[step1_5], $ac1, 31 \n\t" - "extp %[step1_6], $ac3, 31 \n\t" - "add %[step1_4], %[temp0], %[temp1] \n\t" - "add %[step1_7], %[temp3], %[temp2] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [temp2] "=&r"(temp2), [temp3] "=&r"(temp3), [step1_4] "=&r"(step1_4), - [step1_5] "=&r"(step1_5), [step1_6] "=&r"(step1_6), - [step1_7] "=&r"(step1_7) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_20_64] "r"(cospi_20_64), [cospi_12_64] "r"(cospi_12_64), - [cospi_4_64] "r"(cospi_4_64), [cospi_28_64] "r"(cospi_28_64), - [cospi_16_64] "r"(cospi_16_64)); - - __asm__ __volatile__( - "add %[step2_0], %[step1_0], %[step1_7] \n\t" - "add %[step2_1], %[step1_1], %[step1_6] \n\t" - "add %[step2_2], %[step1_2], %[step1_5] \n\t" - "add %[step2_3], %[step1_3], %[step1_4] \n\t" - "sub %[step2_4], %[step1_3], %[step1_4] \n\t" - "sub %[step2_5], %[step1_2], %[step1_5] \n\t" - "sub %[step2_6], %[step1_1], %[step1_6] \n\t" - "sub %[step2_7], %[step1_0], %[step1_7] \n\t" - - : [step2_0] "=&r"(step2_0), [step2_4] "=&r"(step2_4), - [step2_1] "=&r"(step2_1), [step2_5] "=&r"(step2_5), - [step2_2] "=&r"(step2_2), [step2_6] "=&r"(step2_6), - [step2_3] "=&r"(step2_3), [step2_7] "=&r"(step2_7) - : [step1_0] "r"(step1_0), [step1_7] "r"(step1_7), - [step1_1] "r"(step1_1), [step1_6] "r"(step1_6), - [step1_2] "r"(step1_2), [step1_5] "r"(step1_5), - [step1_3] "r"(step1_3), [step1_4] "r"(step1_4)); - - // stage 7 - __asm__ __volatile__( - "add %[step1_0], %[step2_0], %[step3_15] \n\t" - "add %[step1_1], %[step2_1], %[step3_14] \n\t" - "add %[step1_2], %[step2_2], %[step3_13] \n\t" - "add %[step1_3], %[step2_3], %[step3_12] \n\t" - "sub %[step1_12], %[step2_3], %[step3_12] \n\t" - "sub %[step1_13], %[step2_2], %[step3_13] \n\t" - "sub %[step1_14], %[step2_1], %[step3_14] \n\t" - "sub %[step1_15], %[step2_0], %[step3_15] \n\t" - - : [step1_0] "=&r"(step1_0), [step1_12] "=&r"(step1_12), - [step1_1] "=&r"(step1_1), [step1_13] "=&r"(step1_13), - [step1_2] "=&r"(step1_2), [step1_14] "=&r"(step1_14), - [step1_3] "=&r"(step1_3), [step1_15] "=&r"(step1_15) - : [step2_0] "r"(step2_0), [step3_15] "r"(step3_15), - [step2_1] "r"(step2_1), [step3_14] "r"(step3_14), - [step2_2] "r"(step2_2), [step3_13] "r"(step3_13), - [step2_3] "r"(step2_3), [step3_12] "r"(step3_12)); - - __asm__ __volatile__( - "add %[step1_4], %[step2_4], %[step3_11] \n\t" - "add %[step1_5], %[step2_5], %[step3_10] \n\t" - "add %[step1_6], %[step2_6], %[step3_9] \n\t" - "add %[step1_7], %[step2_7], %[step3_8] \n\t" - "sub %[step1_8], %[step2_7], %[step3_8] \n\t" - "sub %[step1_9], %[step2_6], %[step3_9] \n\t" - "sub %[step1_10], %[step2_5], %[step3_10] \n\t" - "sub %[step1_11], %[step2_4], %[step3_11] \n\t" - - : [step1_4] "=&r"(step1_4), [step1_8] "=&r"(step1_8), - [step1_5] "=&r"(step1_5), [step1_9] "=&r"(step1_9), - [step1_6] "=&r"(step1_6), [step1_10] "=&r"(step1_10), - [step1_7] "=&r"(step1_7), [step1_11] "=&r"(step1_11) - : [step2_4] "r"(step2_4), [step3_11] "r"(step3_11), - [step2_5] "r"(step2_5), [step3_10] "r"(step3_10), - [step2_6] "r"(step2_6), [step3_9] "r"(step3_9), - [step2_7] "r"(step2_7), [step3_8] "r"(step3_8)); - - __asm__ __volatile__( - "sub %[temp0], %[step2_27], %[step2_20] \n\t" - "add %[temp1], %[step2_27], %[step2_20] \n\t" - "sub %[temp2], %[step2_26], %[step2_21] \n\t" - "add %[temp3], %[step2_26], %[step2_21] \n\t" - - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac0, %[temp0], %[cospi_16_64] \n\t" - "madd $ac1, %[temp1], %[cospi_16_64] \n\t" - "madd $ac2, %[temp2], %[cospi_16_64] \n\t" - "madd $ac3, %[temp3], %[cospi_16_64] \n\t" - - "extp %[step1_20], $ac0, 31 \n\t" - "extp %[step1_27], $ac1, 31 \n\t" - "extp %[step1_21], $ac2, 31 \n\t" - "extp %[step1_26], $ac3, 31 \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), [temp2] "=&r"(temp2), - [temp3] "=&r"(temp3), [step1_20] "=&r"(step1_20), - [step1_27] "=&r"(step1_27), [step1_21] "=&r"(step1_21), - [step1_26] "=&r"(step1_26) - : [const_2_power_13] "r"(const_2_power_13), [step2_20] "r"(step2_20), - [step2_27] "r"(step2_27), [step2_21] "r"(step2_21), - [step2_26] "r"(step2_26), [cospi_16_64] "r"(cospi_16_64)); - - __asm__ __volatile__( - "sub %[temp0], %[step2_25], %[step2_22] \n\t" - "add %[temp1], %[step2_25], %[step2_22] \n\t" - "sub %[temp2], %[step2_24], %[step2_23] \n\t" - "add %[temp3], %[step2_24], %[step2_23] \n\t" - - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac0, %[temp0], %[cospi_16_64] \n\t" - "madd $ac1, %[temp1], %[cospi_16_64] \n\t" - "madd $ac2, %[temp2], %[cospi_16_64] \n\t" - "madd $ac3, %[temp3], %[cospi_16_64] \n\t" - - "extp %[step1_22], $ac0, 31 \n\t" - "extp %[step1_25], $ac1, 31 \n\t" - "extp %[step1_23], $ac2, 31 \n\t" - "extp %[step1_24], $ac3, 31 \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), [temp2] "=&r"(temp2), - [temp3] "=&r"(temp3), [step1_22] "=&r"(step1_22), - [step1_25] "=&r"(step1_25), [step1_23] "=&r"(step1_23), - [step1_24] "=&r"(step1_24) - : [const_2_power_13] "r"(const_2_power_13), [step2_22] "r"(step2_22), - [step2_25] "r"(step2_25), [step2_23] "r"(step2_23), - [step2_24] "r"(step2_24), [cospi_16_64] "r"(cospi_16_64)); - - __asm__ __volatile__( - "lbu %[temp2], 0(%[dest_pix]) \n\t" - "add %[temp0], %[step1_0], %[step2_31] \n\t" - "addi %[temp0], %[temp0], 32 \n\t" - "sra %[temp0], %[temp0], 6 \n\t" - "add %[temp2], %[temp2], %[temp0] \n\t" - "lbux %[temp0], %[temp2](%[cm]) \n\t" - "add %[temp1], %[step1_1], %[step2_30] \n\t" - "sb %[temp0], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - "lbu %[temp3], 0(%[dest_pix]) \n\t" - "addi %[temp1], %[temp1], 32 \n\t" - "sra %[temp1], %[temp1], 6 \n\t" - "add %[temp3], %[temp3], %[temp1] \n\t" - "lbux %[temp1], %[temp3](%[cm]) \n\t" - "sb %[temp1], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "lbu %[temp2], 0(%[dest_pix]) \n\t" - "add %[temp0], %[step1_2], %[step2_29] \n\t" - "addi %[temp0], %[temp0], 32 \n\t" - "sra %[temp0], %[temp0], 6 \n\t" - "add %[temp2], %[temp2], %[temp0] \n\t" - "lbux %[temp0], %[temp2](%[cm]) \n\t" - "add %[temp1], %[step1_3], %[step2_28] \n\t" - "sb %[temp0], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - "lbu %[temp3], 0(%[dest_pix]) \n\t" - "addi %[temp1], %[temp1], 32 \n\t" - "sra %[temp1], %[temp1], 6 \n\t" - "add %[temp3], %[temp3], %[temp1] \n\t" - "lbux %[temp1], %[temp3](%[cm]) \n\t" - "sb %[temp1], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), [temp2] "=&r"(temp2), - [temp3] "=&r"(temp3), [dest_pix] "+r"(dest_pix) - : [cm] "r"(cm), [stride] "r"(stride), [step1_0] "r"(step1_0), - [step1_1] "r"(step1_1), [step1_2] "r"(step1_2), - [step1_3] "r"(step1_3), [step2_28] "r"(step2_28), - [step2_29] "r"(step2_29), [step2_30] "r"(step2_30), - [step2_31] "r"(step2_31)); - - step3_12 = ROUND_POWER_OF_TWO((step1_3 - step2_28), 6); - step3_13 = ROUND_POWER_OF_TWO((step1_2 - step2_29), 6); - step3_14 = ROUND_POWER_OF_TWO((step1_1 - step2_30), 6); - step3_15 = ROUND_POWER_OF_TWO((step1_0 - step2_31), 6); - - __asm__ __volatile__( - "lbu %[temp2], 0(%[dest_pix1]) \n\t" - "add %[temp2], %[temp2], %[step3_15] \n\t" - "lbux %[temp0], %[temp2](%[cm]) \n\t" - "sb %[temp0], 0(%[dest_pix1]) \n\t" - "subu %[dest_pix1], %[dest_pix1], %[stride] \n\t" - "lbu %[temp3], 0(%[dest_pix1]) \n\t" - "add %[temp3], %[temp3], %[step3_14] \n\t" - "lbux %[temp1], %[temp3](%[cm]) \n\t" - "sb %[temp1], 0(%[dest_pix1]) \n\t" - "subu %[dest_pix1], %[dest_pix1], %[stride] \n\t" - - "lbu %[temp2], 0(%[dest_pix1]) \n\t" - "add %[temp2], %[temp2], %[step3_13] \n\t" - "lbux %[temp0], %[temp2](%[cm]) \n\t" - "sb %[temp0], 0(%[dest_pix1]) \n\t" - "subu %[dest_pix1], %[dest_pix1], %[stride] \n\t" - "lbu %[temp3], 0(%[dest_pix1]) \n\t" - "add %[temp3], %[temp3], %[step3_12] \n\t" - "lbux %[temp1], %[temp3](%[cm]) \n\t" - "sb %[temp1], 0(%[dest_pix1]) \n\t" - "subu %[dest_pix1], %[dest_pix1], %[stride] \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), [temp2] "=&r"(temp2), - [temp3] "=&r"(temp3), [dest_pix1] "+r"(dest_pix1) - : [cm] "r"(cm), [stride] "r"(stride), [step3_12] "r"(step3_12), - [step3_13] "r"(step3_13), [step3_14] "r"(step3_14), - [step3_15] "r"(step3_15)); - - __asm__ __volatile__( - "lbu %[temp2], 0(%[dest_pix]) \n\t" - "add %[temp0], %[step1_4], %[step1_27] \n\t" - "addi %[temp0], %[temp0], 32 \n\t" - "sra %[temp0], %[temp0], 6 \n\t" - "add %[temp2], %[temp2], %[temp0] \n\t" - "lbux %[temp0], %[temp2](%[cm]) \n\t" - "add %[temp1], %[step1_5], %[step1_26] \n\t" - "sb %[temp0], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - "lbu %[temp3], 0(%[dest_pix]) \n\t" - "addi %[temp1], %[temp1], 32 \n\t" - "sra %[temp1], %[temp1], 6 \n\t" - "add %[temp3], %[temp3], %[temp1] \n\t" - "lbux %[temp1], %[temp3](%[cm]) \n\t" - "sb %[temp1], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "lbu %[temp2], 0(%[dest_pix]) \n\t" - "add %[temp0], %[step1_6], %[step1_25] \n\t" - "addi %[temp0], %[temp0], 32 \n\t" - "sra %[temp0], %[temp0], 6 \n\t" - "add %[temp2], %[temp2], %[temp0] \n\t" - "lbux %[temp0], %[temp2](%[cm]) \n\t" - "add %[temp1], %[step1_7], %[step1_24] \n\t" - "sb %[temp0], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - "lbu %[temp3], 0(%[dest_pix]) \n\t" - "addi %[temp1], %[temp1], 32 \n\t" - "sra %[temp1], %[temp1], 6 \n\t" - "add %[temp3], %[temp3], %[temp1] \n\t" - "lbux %[temp1], %[temp3](%[cm]) \n\t" - "sb %[temp1], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), [temp2] "=&r"(temp2), - [temp3] "=&r"(temp3), [dest_pix] "+r"(dest_pix) - : [cm] "r"(cm), [stride] "r"(stride), [step1_4] "r"(step1_4), - [step1_5] "r"(step1_5), [step1_6] "r"(step1_6), - [step1_7] "r"(step1_7), [step1_24] "r"(step1_24), - [step1_25] "r"(step1_25), [step1_26] "r"(step1_26), - [step1_27] "r"(step1_27)); - - step3_12 = ROUND_POWER_OF_TWO((step1_7 - step1_24), 6); - step3_13 = ROUND_POWER_OF_TWO((step1_6 - step1_25), 6); - step3_14 = ROUND_POWER_OF_TWO((step1_5 - step1_26), 6); - step3_15 = ROUND_POWER_OF_TWO((step1_4 - step1_27), 6); - - __asm__ __volatile__( - "lbu %[temp2], 0(%[dest_pix1]) \n\t" - "add %[temp2], %[temp2], %[step3_15] \n\t" - "lbux %[temp0], %[temp2](%[cm]) \n\t" - "sb %[temp0], 0(%[dest_pix1]) \n\t" - "subu %[dest_pix1], %[dest_pix1], %[stride] \n\t" - "lbu %[temp3], 0(%[dest_pix1]) \n\t" - "add %[temp3], %[temp3], %[step3_14] \n\t" - "lbux %[temp1], %[temp3](%[cm]) \n\t" - "sb %[temp1], 0(%[dest_pix1]) \n\t" - "subu %[dest_pix1], %[dest_pix1], %[stride] \n\t" - - "lbu %[temp2], 0(%[dest_pix1]) \n\t" - "add %[temp2], %[temp2], %[step3_13] \n\t" - "lbux %[temp0], %[temp2](%[cm]) \n\t" - "sb %[temp0], 0(%[dest_pix1]) \n\t" - "subu %[dest_pix1], %[dest_pix1], %[stride] \n\t" - "lbu %[temp3], 0(%[dest_pix1]) \n\t" - "add %[temp3], %[temp3], %[step3_12] \n\t" - "lbux %[temp1], %[temp3](%[cm]) \n\t" - "sb %[temp1], 0(%[dest_pix1]) \n\t" - "subu %[dest_pix1], %[dest_pix1], %[stride] \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), [temp2] "=&r"(temp2), - [temp3] "=&r"(temp3), [dest_pix1] "+r"(dest_pix1) - : [cm] "r"(cm), [stride] "r"(stride), [step3_12] "r"(step3_12), - [step3_13] "r"(step3_13), [step3_14] "r"(step3_14), - [step3_15] "r"(step3_15)); - - __asm__ __volatile__( - "lbu %[temp2], 0(%[dest_pix]) \n\t" - "add %[temp0], %[step1_8], %[step1_23] \n\t" - "addi %[temp0], %[temp0], 32 \n\t" - "sra %[temp0], %[temp0], 6 \n\t" - "add %[temp2], %[temp2], %[temp0] \n\t" - "lbux %[temp0], %[temp2](%[cm]) \n\t" - "add %[temp1], %[step1_9], %[step1_22] \n\t" - "sb %[temp0], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - "lbu %[temp3], 0(%[dest_pix]) \n\t" - "addi %[temp1], %[temp1], 32 \n\t" - "sra %[temp1], %[temp1], 6 \n\t" - "add %[temp3], %[temp3], %[temp1] \n\t" - "lbux %[temp1], %[temp3](%[cm]) \n\t" - "sb %[temp1], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "lbu %[temp2], 0(%[dest_pix]) \n\t" - "add %[temp0], %[step1_10], %[step1_21] \n\t" - "addi %[temp0], %[temp0], 32 \n\t" - "sra %[temp0], %[temp0], 6 \n\t" - "add %[temp2], %[temp2], %[temp0] \n\t" - "lbux %[temp0], %[temp2](%[cm]) \n\t" - "add %[temp1], %[step1_11], %[step1_20] \n\t" - "sb %[temp0], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - "lbu %[temp3], 0(%[dest_pix]) \n\t" - "addi %[temp1], %[temp1], 32 \n\t" - "sra %[temp1], %[temp1], 6 \n\t" - "add %[temp3], %[temp3], %[temp1] \n\t" - "lbux %[temp1], %[temp3](%[cm]) \n\t" - "sb %[temp1], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), [temp2] "=&r"(temp2), - [temp3] "=&r"(temp3), [dest_pix] "+r"(dest_pix) - : [cm] "r"(cm), [stride] "r"(stride), [step1_8] "r"(step1_8), - [step1_9] "r"(step1_9), [step1_10] "r"(step1_10), - [step1_11] "r"(step1_11), [step1_20] "r"(step1_20), - [step1_21] "r"(step1_21), [step1_22] "r"(step1_22), - [step1_23] "r"(step1_23)); - - step3_12 = ROUND_POWER_OF_TWO((step1_11 - step1_20), 6); - step3_13 = ROUND_POWER_OF_TWO((step1_10 - step1_21), 6); - step3_14 = ROUND_POWER_OF_TWO((step1_9 - step1_22), 6); - step3_15 = ROUND_POWER_OF_TWO((step1_8 - step1_23), 6); - - __asm__ __volatile__( - "lbu %[temp2], 0(%[dest_pix1]) \n\t" - "add %[temp2], %[temp2], %[step3_15] \n\t" - "lbux %[temp0], %[temp2](%[cm]) \n\t" - "sb %[temp0], 0(%[dest_pix1]) \n\t" - "subu %[dest_pix1], %[dest_pix1], %[stride] \n\t" - "lbu %[temp3], 0(%[dest_pix1]) \n\t" - "add %[temp3], %[temp3], %[step3_14] \n\t" - "lbux %[temp1], %[temp3](%[cm]) \n\t" - "sb %[temp1], 0(%[dest_pix1]) \n\t" - "subu %[dest_pix1], %[dest_pix1], %[stride] \n\t" - - "lbu %[temp2], 0(%[dest_pix1]) \n\t" - "add %[temp2], %[temp2], %[step3_13] \n\t" - "lbux %[temp0], %[temp2](%[cm]) \n\t" - "sb %[temp0], 0(%[dest_pix1]) \n\t" - "subu %[dest_pix1], %[dest_pix1], %[stride] \n\t" - "lbu %[temp3], 0(%[dest_pix1]) \n\t" - "add %[temp3], %[temp3], %[step3_12] \n\t" - "lbux %[temp1], %[temp3](%[cm]) \n\t" - "sb %[temp1], 0(%[dest_pix1]) \n\t" - "subu %[dest_pix1], %[dest_pix1], %[stride] \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), [temp2] "=&r"(temp2), - [temp3] "=&r"(temp3), [dest_pix1] "+r"(dest_pix1) - : [cm] "r"(cm), [stride] "r"(stride), [step3_12] "r"(step3_12), - [step3_13] "r"(step3_13), [step3_14] "r"(step3_14), - [step3_15] "r"(step3_15)); - - __asm__ __volatile__( - "lbu %[temp2], 0(%[dest_pix]) \n\t" - "add %[temp0], %[step1_12], %[step2_19] \n\t" - "addi %[temp0], %[temp0], 32 \n\t" - "sra %[temp0], %[temp0], 6 \n\t" - "add %[temp2], %[temp2], %[temp0] \n\t" - "lbux %[temp0], %[temp2](%[cm]) \n\t" - "add %[temp1], %[step1_13], %[step2_18] \n\t" - "sb %[temp0], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - "lbu %[temp3], 0(%[dest_pix]) \n\t" - "addi %[temp1], %[temp1], 32 \n\t" - "sra %[temp1], %[temp1], 6 \n\t" - "add %[temp3], %[temp3], %[temp1] \n\t" - "lbux %[temp1], %[temp3](%[cm]) \n\t" - "sb %[temp1], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "lbu %[temp2], 0(%[dest_pix]) \n\t" - "add %[temp0], %[step1_14], %[step2_17] \n\t" - "addi %[temp0], %[temp0], 32 \n\t" - "sra %[temp0], %[temp0], 6 \n\t" - "add %[temp2], %[temp2], %[temp0] \n\t" - "lbux %[temp0], %[temp2](%[cm]) \n\t" - "add %[temp1], %[step1_15], %[step2_16] \n\t" - "sb %[temp0], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - "lbu %[temp3], 0(%[dest_pix]) \n\t" - "addi %[temp1], %[temp1], 32 \n\t" - "sra %[temp1], %[temp1], 6 \n\t" - "add %[temp3], %[temp3], %[temp1] \n\t" - "lbux %[temp1], %[temp3](%[cm]) \n\t" - "sb %[temp1], 0(%[dest_pix]) \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), [temp2] "=&r"(temp2), - [temp3] "=&r"(temp3), [dest_pix] "+r"(dest_pix) - : [cm] "r"(cm), [stride] "r"(stride), [step1_12] "r"(step1_12), - [step1_13] "r"(step1_13), [step1_14] "r"(step1_14), - [step1_15] "r"(step1_15), [step2_16] "r"(step2_16), - [step2_17] "r"(step2_17), [step2_18] "r"(step2_18), - [step2_19] "r"(step2_19)); - - step3_12 = ROUND_POWER_OF_TWO((step1_15 - step2_16), 6); - step3_13 = ROUND_POWER_OF_TWO((step1_14 - step2_17), 6); - step3_14 = ROUND_POWER_OF_TWO((step1_13 - step2_18), 6); - step3_15 = ROUND_POWER_OF_TWO((step1_12 - step2_19), 6); - - __asm__ __volatile__( - "lbu %[temp2], 0(%[dest_pix1]) \n\t" - "add %[temp2], %[temp2], %[step3_15] \n\t" - "lbux %[temp0], %[temp2](%[cm]) \n\t" - "sb %[temp0], 0(%[dest_pix1]) \n\t" - "subu %[dest_pix1], %[dest_pix1], %[stride] \n\t" - "lbu %[temp3], 0(%[dest_pix1]) \n\t" - "add %[temp3], %[temp3], %[step3_14] \n\t" - "lbux %[temp1], %[temp3](%[cm]) \n\t" - "sb %[temp1], 0(%[dest_pix1]) \n\t" - "subu %[dest_pix1], %[dest_pix1], %[stride] \n\t" - - "lbu %[temp2], 0(%[dest_pix1]) \n\t" - "add %[temp2], %[temp2], %[step3_13] \n\t" - "lbux %[temp0], %[temp2](%[cm]) \n\t" - "sb %[temp0], 0(%[dest_pix1]) \n\t" - "subu %[dest_pix1], %[dest_pix1], %[stride] \n\t" - "lbu %[temp3], 0(%[dest_pix1]) \n\t" - "add %[temp3], %[temp3], %[step3_12] \n\t" - "lbux %[temp1], %[temp3](%[cm]) \n\t" - "sb %[temp1], 0(%[dest_pix1]) \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), [temp2] "=&r"(temp2), - [temp3] "=&r"(temp3), [dest_pix1] "+r"(dest_pix1) - : [cm] "r"(cm), [stride] "r"(stride), [step3_12] "r"(step3_12), - [step3_13] "r"(step3_13), [step3_14] "r"(step3_14), - [step3_15] "r"(step3_15)); - - input += 32; - } -} -#endif // #if HAVE_DSPR2 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/itrans32_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/itrans32_dspr2.c deleted file mode 100644 index 3c0468c0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/itrans32_dspr2.c +++ /dev/null @@ -1,1218 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "vpx_dsp/mips/inv_txfm_dspr2.h" -#include "vpx_dsp/txfm_common.h" - -#if HAVE_DSPR2 -static void idct32_rows_dspr2(const int16_t *input, int16_t *output, - uint32_t no_rows) { - int step1_0, step1_1, step1_2, step1_3, step1_4, step1_5, step1_6; - int step1_7, step1_8, step1_9, step1_10, step1_11, step1_12, step1_13; - int step1_14, step1_15, step1_16, step1_17, step1_18, step1_19, step1_20; - int step1_21, step1_22, step1_23, step1_24, step1_25, step1_26, step1_27; - int step1_28, step1_29, step1_30, step1_31; - int step2_0, step2_1, step2_2, step2_3, step2_4, step2_5, step2_6; - int step2_7, step2_8, step2_9, step2_10, step2_11, step2_12, step2_13; - int step2_14, step2_15, step2_16, step2_17, step2_18, step2_19, step2_20; - int step2_21, step2_22, step2_23, step2_24, step2_25, step2_26, step2_27; - int step2_28, step2_29, step2_30, step2_31; - int step3_8, step3_9, step3_10, step3_11, step3_12, step3_13, step3_14; - int step3_15, step3_16, step3_17, step3_18, step3_19, step3_20, step3_21; - int step3_22, step3_23, step3_24, step3_25, step3_26, step3_27, step3_28; - int step3_29, step3_30, step3_31; - int temp0, temp1, temp2, temp3; - int load1, load2, load3, load4; - int result1, result2; - int i; - const int const_2_power_13 = 8192; - const int32_t *input_int; - - for (i = no_rows; i--;) { - input_int = (const int32_t *)input; - - if (!(input_int[0] | input_int[1] | input_int[2] | input_int[3] | - input_int[4] | input_int[5] | input_int[6] | input_int[7] | - input_int[8] | input_int[9] | input_int[10] | input_int[11] | - input_int[12] | input_int[13] | input_int[14] | input_int[15])) { - input += 32; - - __asm__ __volatile__( - "sh $zero, 0(%[output]) \n\t" - "sh $zero, 64(%[output]) \n\t" - "sh $zero, 128(%[output]) \n\t" - "sh $zero, 192(%[output]) \n\t" - "sh $zero, 256(%[output]) \n\t" - "sh $zero, 320(%[output]) \n\t" - "sh $zero, 384(%[output]) \n\t" - "sh $zero, 448(%[output]) \n\t" - "sh $zero, 512(%[output]) \n\t" - "sh $zero, 576(%[output]) \n\t" - "sh $zero, 640(%[output]) \n\t" - "sh $zero, 704(%[output]) \n\t" - "sh $zero, 768(%[output]) \n\t" - "sh $zero, 832(%[output]) \n\t" - "sh $zero, 896(%[output]) \n\t" - "sh $zero, 960(%[output]) \n\t" - "sh $zero, 1024(%[output]) \n\t" - "sh $zero, 1088(%[output]) \n\t" - "sh $zero, 1152(%[output]) \n\t" - "sh $zero, 1216(%[output]) \n\t" - "sh $zero, 1280(%[output]) \n\t" - "sh $zero, 1344(%[output]) \n\t" - "sh $zero, 1408(%[output]) \n\t" - "sh $zero, 1472(%[output]) \n\t" - "sh $zero, 1536(%[output]) \n\t" - "sh $zero, 1600(%[output]) \n\t" - "sh $zero, 1664(%[output]) \n\t" - "sh $zero, 1728(%[output]) \n\t" - "sh $zero, 1792(%[output]) \n\t" - "sh $zero, 1856(%[output]) \n\t" - "sh $zero, 1920(%[output]) \n\t" - "sh $zero, 1984(%[output]) \n\t" - - : - : [output] "r"(output)); - - output += 1; - - continue; - } - - /* prefetch row */ - prefetch_load((const uint8_t *)(input + 32)); - prefetch_load((const uint8_t *)(input + 48)); - - __asm__ __volatile__( - "lh %[load1], 2(%[input]) \n\t" - "lh %[load2], 62(%[input]) \n\t" - "lh %[load3], 34(%[input]) \n\t" - "lh %[load4], 30(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load1], %[cospi_31_64] \n\t" - "msub $ac1, %[load2], %[cospi_1_64] \n\t" - "extp %[temp0], $ac1, 31 \n\t" - - "madd $ac3, %[load1], %[cospi_1_64] \n\t" - "madd $ac3, %[load2], %[cospi_31_64] \n\t" - "extp %[temp3], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac2, %[load3], %[cospi_15_64] \n\t" - "msub $ac2, %[load4], %[cospi_17_64] \n\t" - "extp %[temp1], $ac2, 31 \n\t" - - "madd $ac1, %[load3], %[cospi_17_64] \n\t" - "madd $ac1, %[load4], %[cospi_15_64] \n\t" - "extp %[temp2], $ac1, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load1], %[temp3], %[temp2] \n\t" - "sub %[load2], %[temp0], %[temp1] \n\t" - - "madd $ac1, %[load1], %[cospi_28_64] \n\t" - "msub $ac1, %[load2], %[cospi_4_64] \n\t" - "madd $ac3, %[load1], %[cospi_4_64] \n\t" - "madd $ac3, %[load2], %[cospi_28_64] \n\t" - - "extp %[step1_17], $ac1, 31 \n\t" - "extp %[step1_30], $ac3, 31 \n\t" - "add %[step1_16], %[temp0], %[temp1] \n\t" - "add %[step1_31], %[temp2], %[temp3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [temp2] "=&r"(temp2), [temp3] "=&r"(temp3), - [step1_16] "=&r"(step1_16), [step1_17] "=&r"(step1_17), - [step1_30] "=&r"(step1_30), [step1_31] "=&r"(step1_31) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_31_64] "r"(cospi_31_64), [cospi_1_64] "r"(cospi_1_64), - [cospi_4_64] "r"(cospi_4_64), [cospi_17_64] "r"(cospi_17_64), - [cospi_15_64] "r"(cospi_15_64), [cospi_28_64] "r"(cospi_28_64)); - - __asm__ __volatile__( - "lh %[load1], 18(%[input]) \n\t" - "lh %[load2], 46(%[input]) \n\t" - "lh %[load3], 50(%[input]) \n\t" - "lh %[load4], 14(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load1], %[cospi_23_64] \n\t" - "msub $ac1, %[load2], %[cospi_9_64] \n\t" - "extp %[temp0], $ac1, 31 \n\t" - - "madd $ac3, %[load1], %[cospi_9_64] \n\t" - "madd $ac3, %[load2], %[cospi_23_64] \n\t" - "extp %[temp3], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac2, %[load3], %[cospi_7_64] \n\t" - "msub $ac2, %[load4], %[cospi_25_64] \n\t" - "extp %[temp1], $ac2, 31 \n\t" - - "madd $ac1, %[load3], %[cospi_25_64] \n\t" - "madd $ac1, %[load4], %[cospi_7_64] \n\t" - "extp %[temp2], $ac1, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load1], %[temp1], %[temp0] \n\t" - "sub %[load2], %[temp2], %[temp3] \n\t" - - "msub $ac1, %[load1], %[cospi_28_64] \n\t" - "msub $ac1, %[load2], %[cospi_4_64] \n\t" - "msub $ac3, %[load1], %[cospi_4_64] \n\t" - "madd $ac3, %[load2], %[cospi_28_64] \n\t" - - "extp %[step1_18], $ac1, 31 \n\t" - "extp %[step1_29], $ac3, 31 \n\t" - "add %[step1_19], %[temp0], %[temp1] \n\t" - "add %[step1_28], %[temp2], %[temp3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [temp2] "=&r"(temp2), [temp3] "=&r"(temp3), - [step1_18] "=&r"(step1_18), [step1_19] "=&r"(step1_19), - [step1_28] "=&r"(step1_28), [step1_29] "=&r"(step1_29) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_23_64] "r"(cospi_23_64), [cospi_9_64] "r"(cospi_9_64), - [cospi_4_64] "r"(cospi_4_64), [cospi_7_64] "r"(cospi_7_64), - [cospi_25_64] "r"(cospi_25_64), [cospi_28_64] "r"(cospi_28_64)); - - __asm__ __volatile__( - "lh %[load1], 10(%[input]) \n\t" - "lh %[load2], 54(%[input]) \n\t" - "lh %[load3], 42(%[input]) \n\t" - "lh %[load4], 22(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load1], %[cospi_27_64] \n\t" - "msub $ac1, %[load2], %[cospi_5_64] \n\t" - "extp %[temp0], $ac1, 31 \n\t" - - "madd $ac3, %[load1], %[cospi_5_64] \n\t" - "madd $ac3, %[load2], %[cospi_27_64] \n\t" - "extp %[temp3], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac2, %[load3], %[cospi_11_64] \n\t" - "msub $ac2, %[load4], %[cospi_21_64] \n\t" - "extp %[temp1], $ac2, 31 \n\t" - - "madd $ac1, %[load3], %[cospi_21_64] \n\t" - "madd $ac1, %[load4], %[cospi_11_64] \n\t" - "extp %[temp2], $ac1, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load1], %[temp0], %[temp1] \n\t" - "sub %[load2], %[temp3], %[temp2] \n\t" - - "madd $ac1, %[load2], %[cospi_12_64] \n\t" - "msub $ac1, %[load1], %[cospi_20_64] \n\t" - "madd $ac3, %[load1], %[cospi_12_64] \n\t" - "madd $ac3, %[load2], %[cospi_20_64] \n\t" - - "extp %[step1_21], $ac1, 31 \n\t" - "extp %[step1_26], $ac3, 31 \n\t" - "add %[step1_20], %[temp0], %[temp1] \n\t" - "add %[step1_27], %[temp2], %[temp3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [temp2] "=&r"(temp2), [temp3] "=&r"(temp3), - [step1_20] "=&r"(step1_20), [step1_21] "=&r"(step1_21), - [step1_26] "=&r"(step1_26), [step1_27] "=&r"(step1_27) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_27_64] "r"(cospi_27_64), [cospi_5_64] "r"(cospi_5_64), - [cospi_11_64] "r"(cospi_11_64), [cospi_21_64] "r"(cospi_21_64), - [cospi_12_64] "r"(cospi_12_64), [cospi_20_64] "r"(cospi_20_64)); - - __asm__ __volatile__( - "lh %[load1], 26(%[input]) \n\t" - "lh %[load2], 38(%[input]) \n\t" - "lh %[load3], 58(%[input]) \n\t" - "lh %[load4], 6(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load1], %[cospi_19_64] \n\t" - "msub $ac1, %[load2], %[cospi_13_64] \n\t" - "extp %[temp0], $ac1, 31 \n\t" - "madd $ac3, %[load1], %[cospi_13_64] \n\t" - "madd $ac3, %[load2], %[cospi_19_64] \n\t" - "extp %[temp3], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac2, %[load3], %[cospi_3_64] \n\t" - "msub $ac2, %[load4], %[cospi_29_64] \n\t" - "extp %[temp1], $ac2, 31 \n\t" - "madd $ac1, %[load3], %[cospi_29_64] \n\t" - "madd $ac1, %[load4], %[cospi_3_64] \n\t" - "extp %[temp2], $ac1, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load1], %[temp1], %[temp0] \n\t" - "sub %[load2], %[temp2], %[temp3] \n\t" - "msub $ac1, %[load1], %[cospi_12_64] \n\t" - "msub $ac1, %[load2], %[cospi_20_64] \n\t" - "msub $ac3, %[load1], %[cospi_20_64] \n\t" - "madd $ac3, %[load2], %[cospi_12_64] \n\t" - "extp %[step1_22], $ac1, 31 \n\t" - "extp %[step1_25], $ac3, 31 \n\t" - "add %[step1_23], %[temp0], %[temp1] \n\t" - "add %[step1_24], %[temp2], %[temp3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [temp2] "=&r"(temp2), [temp3] "=&r"(temp3), - [step1_22] "=&r"(step1_22), [step1_23] "=&r"(step1_23), - [step1_24] "=&r"(step1_24), [step1_25] "=&r"(step1_25) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_19_64] "r"(cospi_19_64), [cospi_13_64] "r"(cospi_13_64), - [cospi_3_64] "r"(cospi_3_64), [cospi_29_64] "r"(cospi_29_64), - [cospi_12_64] "r"(cospi_12_64), [cospi_20_64] "r"(cospi_20_64)); - - __asm__ __volatile__( - "lh %[load1], 4(%[input]) \n\t" - "lh %[load2], 60(%[input]) \n\t" - "lh %[load3], 36(%[input]) \n\t" - "lh %[load4], 28(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load1], %[cospi_30_64] \n\t" - "msub $ac1, %[load2], %[cospi_2_64] \n\t" - "extp %[temp0], $ac1, 31 \n\t" - "madd $ac3, %[load1], %[cospi_2_64] \n\t" - "madd $ac3, %[load2], %[cospi_30_64] \n\t" - "extp %[temp3], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac2, %[load3], %[cospi_14_64] \n\t" - "msub $ac2, %[load4], %[cospi_18_64] \n\t" - "extp %[temp1], $ac2, 31 \n\t" - "madd $ac1, %[load3], %[cospi_18_64] \n\t" - "madd $ac1, %[load4], %[cospi_14_64] \n\t" - "extp %[temp2], $ac1, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load1], %[temp0], %[temp1] \n\t" - "sub %[load2], %[temp3], %[temp2] \n\t" - "msub $ac1, %[load1], %[cospi_8_64] \n\t" - "madd $ac1, %[load2], %[cospi_24_64] \n\t" - "madd $ac3, %[load1], %[cospi_24_64] \n\t" - "madd $ac3, %[load2], %[cospi_8_64] \n\t" - "extp %[step2_9], $ac1, 31 \n\t" - "extp %[step2_14], $ac3, 31 \n\t" - "add %[step2_8], %[temp0], %[temp1] \n\t" - "add %[step2_15], %[temp2], %[temp3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [temp2] "=&r"(temp2), [temp3] "=&r"(temp3), [step2_8] "=&r"(step2_8), - [step2_9] "=&r"(step2_9), [step2_14] "=&r"(step2_14), - [step2_15] "=&r"(step2_15) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_30_64] "r"(cospi_30_64), [cospi_2_64] "r"(cospi_2_64), - [cospi_14_64] "r"(cospi_14_64), [cospi_18_64] "r"(cospi_18_64), - [cospi_8_64] "r"(cospi_8_64), [cospi_24_64] "r"(cospi_24_64)); - - __asm__ __volatile__( - "lh %[load1], 20(%[input]) \n\t" - "lh %[load2], 44(%[input]) \n\t" - "lh %[load3], 52(%[input]) \n\t" - "lh %[load4], 12(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load1], %[cospi_22_64] \n\t" - "msub $ac1, %[load2], %[cospi_10_64] \n\t" - "extp %[temp0], $ac1, 31 \n\t" - "madd $ac3, %[load1], %[cospi_10_64] \n\t" - "madd $ac3, %[load2], %[cospi_22_64] \n\t" - "extp %[temp3], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac2, %[load3], %[cospi_6_64] \n\t" - "msub $ac2, %[load4], %[cospi_26_64] \n\t" - "extp %[temp1], $ac2, 31 \n\t" - "madd $ac1, %[load3], %[cospi_26_64] \n\t" - "madd $ac1, %[load4], %[cospi_6_64] \n\t" - "extp %[temp2], $ac1, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load1], %[temp1], %[temp0] \n\t" - "sub %[load2], %[temp2], %[temp3] \n\t" - "msub $ac1, %[load1], %[cospi_24_64] \n\t" - "msub $ac1, %[load2], %[cospi_8_64] \n\t" - "madd $ac3, %[load2], %[cospi_24_64] \n\t" - "msub $ac3, %[load1], %[cospi_8_64] \n\t" - "extp %[step2_10], $ac1, 31 \n\t" - "extp %[step2_13], $ac3, 31 \n\t" - "add %[step2_11], %[temp0], %[temp1] \n\t" - "add %[step2_12], %[temp2], %[temp3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [temp2] "=&r"(temp2), [temp3] "=&r"(temp3), - [step2_10] "=&r"(step2_10), [step2_11] "=&r"(step2_11), - [step2_12] "=&r"(step2_12), [step2_13] "=&r"(step2_13) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_22_64] "r"(cospi_22_64), [cospi_10_64] "r"(cospi_10_64), - [cospi_6_64] "r"(cospi_6_64), [cospi_26_64] "r"(cospi_26_64), - [cospi_8_64] "r"(cospi_8_64), [cospi_24_64] "r"(cospi_24_64)); - - __asm__ __volatile__( - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "sub %[temp0], %[step2_14], %[step2_13] \n\t" - "sub %[temp0], %[temp0], %[step2_9] \n\t" - "add %[temp0], %[temp0], %[step2_10] \n\t" - "madd $ac0, %[temp0], %[cospi_16_64] \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "sub %[temp1], %[step2_14], %[step2_13] \n\t" - "add %[temp1], %[temp1], %[step2_9] \n\t" - "sub %[temp1], %[temp1], %[step2_10] \n\t" - "madd $ac1, %[temp1], %[cospi_16_64] \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "sub %[temp0], %[step2_15], %[step2_12] \n\t" - "sub %[temp0], %[temp0], %[step2_8] \n\t" - "add %[temp0], %[temp0], %[step2_11] \n\t" - "madd $ac2, %[temp0], %[cospi_16_64] \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "sub %[temp1], %[step2_15], %[step2_12] \n\t" - "add %[temp1], %[temp1], %[step2_8] \n\t" - "sub %[temp1], %[temp1], %[step2_11] \n\t" - "madd $ac3, %[temp1], %[cospi_16_64] \n\t" - - "add %[step3_8], %[step2_8], %[step2_11] \n\t" - "add %[step3_9], %[step2_9], %[step2_10] \n\t" - "add %[step3_14], %[step2_13], %[step2_14] \n\t" - "add %[step3_15], %[step2_12], %[step2_15] \n\t" - "extp %[step3_10], $ac0, 31 \n\t" - "extp %[step3_13], $ac1, 31 \n\t" - "extp %[step3_11], $ac2, 31 \n\t" - "extp %[step3_12], $ac3, 31 \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), [step3_8] "=&r"(step3_8), - [step3_9] "=&r"(step3_9), [step3_10] "=&r"(step3_10), - [step3_11] "=&r"(step3_11), [step3_12] "=&r"(step3_12), - [step3_13] "=&r"(step3_13), [step3_14] "=&r"(step3_14), - [step3_15] "=&r"(step3_15) - : [const_2_power_13] "r"(const_2_power_13), [step2_8] "r"(step2_8), - [step2_9] "r"(step2_9), [step2_10] "r"(step2_10), - [step2_11] "r"(step2_11), [step2_12] "r"(step2_12), - [step2_13] "r"(step2_13), [step2_14] "r"(step2_14), - [step2_15] "r"(step2_15), [cospi_16_64] "r"(cospi_16_64)); - - __asm__ __volatile__( - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "sub %[temp0], %[step1_17], %[step1_18] \n\t" - "sub %[temp1], %[step1_30], %[step1_29] \n\t" - "add %[step3_17], %[step1_17], %[step1_18] \n\t" - "add %[step3_30], %[step1_30], %[step1_29] \n\t" - - "msub $ac0, %[temp0], %[cospi_8_64] \n\t" - "madd $ac0, %[temp1], %[cospi_24_64] \n\t" - "extp %[step3_18], $ac0, 31 \n\t" - "madd $ac1, %[temp0], %[cospi_24_64] \n\t" - "madd $ac1, %[temp1], %[cospi_8_64] \n\t" - "extp %[step3_29], $ac1, 31 \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [step3_18] "=&r"(step3_18), [step3_29] "=&r"(step3_29), - [step3_17] "=&r"(step3_17), [step3_30] "=&r"(step3_30) - : [const_2_power_13] "r"(const_2_power_13), [step1_17] "r"(step1_17), - [step1_18] "r"(step1_18), [step1_30] "r"(step1_30), - [step1_29] "r"(step1_29), [cospi_24_64] "r"(cospi_24_64), - [cospi_8_64] "r"(cospi_8_64)); - - __asm__ __volatile__( - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "sub %[temp0], %[step1_16], %[step1_19] \n\t" - "sub %[temp1], %[step1_31], %[step1_28] \n\t" - "add %[step3_16], %[step1_16], %[step1_19] \n\t" - "add %[step3_31], %[step1_31], %[step1_28] \n\t" - - "msub $ac0, %[temp0], %[cospi_8_64] \n\t" - "madd $ac0, %[temp1], %[cospi_24_64] \n\t" - "extp %[step3_19], $ac0, 31 \n\t" - "madd $ac1, %[temp0], %[cospi_24_64] \n\t" - "madd $ac1, %[temp1], %[cospi_8_64] \n\t" - "extp %[step3_28], $ac1, 31 \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [step3_16] "=&r"(step3_16), [step3_31] "=&r"(step3_31), - [step3_19] "=&r"(step3_19), [step3_28] "=&r"(step3_28) - : [const_2_power_13] "r"(const_2_power_13), [step1_16] "r"(step1_16), - [step1_19] "r"(step1_19), [step1_31] "r"(step1_31), - [step1_28] "r"(step1_28), [cospi_24_64] "r"(cospi_24_64), - [cospi_8_64] "r"(cospi_8_64)); - - __asm__ __volatile__( - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "sub %[temp0], %[step1_23], %[step1_20] \n\t" - "sub %[temp1], %[step1_24], %[step1_27] \n\t" - "add %[step3_23], %[step1_23], %[step1_20] \n\t" - "add %[step3_24], %[step1_24], %[step1_27] \n\t" - - "msub $ac0, %[temp0], %[cospi_8_64] \n\t" - "madd $ac0, %[temp1], %[cospi_24_64] \n\t" - "extp %[step3_27], $ac0, 31 \n\t" - "msub $ac1, %[temp0], %[cospi_24_64] \n\t" - "msub $ac1, %[temp1], %[cospi_8_64] \n\t" - "extp %[step3_20], $ac1, 31 \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [step3_23] "=&r"(step3_23), [step3_24] "=&r"(step3_24), - [step3_20] "=&r"(step3_20), [step3_27] "=&r"(step3_27) - : [const_2_power_13] "r"(const_2_power_13), [step1_23] "r"(step1_23), - [step1_20] "r"(step1_20), [step1_24] "r"(step1_24), - [step1_27] "r"(step1_27), [cospi_24_64] "r"(cospi_24_64), - [cospi_8_64] "r"(cospi_8_64)); - - __asm__ __volatile__( - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "sub %[temp0], %[step1_22], %[step1_21] \n\t" - "sub %[temp1], %[step1_25], %[step1_26] \n\t" - "add %[step3_22], %[step1_22], %[step1_21] \n\t" - "add %[step3_25], %[step1_25], %[step1_26] \n\t" - - "msub $ac0, %[temp0], %[cospi_24_64] \n\t" - "msub $ac0, %[temp1], %[cospi_8_64] \n\t" - "extp %[step3_21], $ac0, 31 \n\t" - "msub $ac1, %[temp0], %[cospi_8_64] \n\t" - "madd $ac1, %[temp1], %[cospi_24_64] \n\t" - "extp %[step3_26], $ac1, 31 \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [step3_22] "=&r"(step3_22), [step3_25] "=&r"(step3_25), - [step3_21] "=&r"(step3_21), [step3_26] "=&r"(step3_26) - : [const_2_power_13] "r"(const_2_power_13), [step1_22] "r"(step1_22), - [step1_21] "r"(step1_21), [step1_25] "r"(step1_25), - [step1_26] "r"(step1_26), [cospi_24_64] "r"(cospi_24_64), - [cospi_8_64] "r"(cospi_8_64)); - - __asm__ __volatile__( - "add %[step2_16], %[step3_16], %[step3_23] \n\t" - "add %[step2_17], %[step3_17], %[step3_22] \n\t" - "add %[step2_18], %[step3_18], %[step3_21] \n\t" - "add %[step2_19], %[step3_19], %[step3_20] \n\t" - "sub %[step2_20], %[step3_19], %[step3_20] \n\t" - "sub %[step2_21], %[step3_18], %[step3_21] \n\t" - "sub %[step2_22], %[step3_17], %[step3_22] \n\t" - "sub %[step2_23], %[step3_16], %[step3_23] \n\t" - - : [step2_16] "=&r"(step2_16), [step2_17] "=&r"(step2_17), - [step2_18] "=&r"(step2_18), [step2_19] "=&r"(step2_19), - [step2_20] "=&r"(step2_20), [step2_21] "=&r"(step2_21), - [step2_22] "=&r"(step2_22), [step2_23] "=&r"(step2_23) - : [step3_16] "r"(step3_16), [step3_23] "r"(step3_23), - [step3_17] "r"(step3_17), [step3_22] "r"(step3_22), - [step3_18] "r"(step3_18), [step3_21] "r"(step3_21), - [step3_19] "r"(step3_19), [step3_20] "r"(step3_20)); - - __asm__ __volatile__( - "sub %[step2_24], %[step3_31], %[step3_24] \n\t" - "sub %[step2_25], %[step3_30], %[step3_25] \n\t" - "sub %[step2_26], %[step3_29], %[step3_26] \n\t" - "sub %[step2_27], %[step3_28], %[step3_27] \n\t" - "add %[step2_28], %[step3_28], %[step3_27] \n\t" - "add %[step2_29], %[step3_29], %[step3_26] \n\t" - "add %[step2_30], %[step3_30], %[step3_25] \n\t" - "add %[step2_31], %[step3_31], %[step3_24] \n\t" - - : [step2_24] "=&r"(step2_24), [step2_28] "=&r"(step2_28), - [step2_25] "=&r"(step2_25), [step2_29] "=&r"(step2_29), - [step2_26] "=&r"(step2_26), [step2_30] "=&r"(step2_30), - [step2_27] "=&r"(step2_27), [step2_31] "=&r"(step2_31) - : [step3_31] "r"(step3_31), [step3_24] "r"(step3_24), - [step3_30] "r"(step3_30), [step3_25] "r"(step3_25), - [step3_29] "r"(step3_29), [step3_26] "r"(step3_26), - [step3_28] "r"(step3_28), [step3_27] "r"(step3_27)); - - __asm__ __volatile__( - "lh %[load1], 0(%[input]) \n\t" - "lh %[load2], 32(%[input]) \n\t" - "lh %[load3], 16(%[input]) \n\t" - "lh %[load4], 48(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "add %[result1], %[load1], %[load2] \n\t" - "sub %[result2], %[load1], %[load2] \n\t" - "madd $ac1, %[result1], %[cospi_16_64] \n\t" - "madd $ac2, %[result2], %[cospi_16_64] \n\t" - "extp %[temp0], $ac1, 31 \n\t" - "extp %[temp1], $ac2, 31 \n\t" - - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - "madd $ac3, %[load3], %[cospi_24_64] \n\t" - "msub $ac3, %[load4], %[cospi_8_64] \n\t" - "extp %[temp2], $ac3, 31 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "madd $ac1, %[load3], %[cospi_8_64] \n\t" - "madd $ac1, %[load4], %[cospi_24_64] \n\t" - "extp %[temp3], $ac1, 31 \n\t" - "add %[step1_0], %[temp0], %[temp3] \n\t" - "add %[step1_1], %[temp1], %[temp2] \n\t" - "sub %[step1_2], %[temp1], %[temp2] \n\t" - "sub %[step1_3], %[temp0], %[temp3] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [result1] "=&r"(result1), - [result2] "=&r"(result2), [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [temp2] "=&r"(temp2), [temp3] "=&r"(temp3), [step1_0] "=&r"(step1_0), - [step1_1] "=&r"(step1_1), [step1_2] "=&r"(step1_2), - [step1_3] "=&r"(step1_3) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_24_64] "r"(cospi_24_64), [cospi_8_64] "r"(cospi_8_64), - [cospi_16_64] "r"(cospi_16_64)); - - __asm__ __volatile__( - "lh %[load1], 8(%[input]) \n\t" - "lh %[load2], 56(%[input]) \n\t" - "lh %[load3], 40(%[input]) \n\t" - "lh %[load4], 24(%[input]) \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac1, %[load1], %[cospi_28_64] \n\t" - "msub $ac1, %[load2], %[cospi_4_64] \n\t" - "extp %[temp0], $ac1, 31 \n\t" - "madd $ac3, %[load1], %[cospi_4_64] \n\t" - "madd $ac3, %[load2], %[cospi_28_64] \n\t" - "extp %[temp3], $ac3, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - - "madd $ac2, %[load3], %[cospi_12_64] \n\t" - "msub $ac2, %[load4], %[cospi_20_64] \n\t" - "extp %[temp1], $ac2, 31 \n\t" - "madd $ac1, %[load3], %[cospi_20_64] \n\t" - "madd $ac1, %[load4], %[cospi_12_64] \n\t" - "extp %[temp2], $ac1, 31 \n\t" - - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "sub %[load1], %[temp3], %[temp2] \n\t" - "sub %[load1], %[load1], %[temp0] \n\t" - "add %[load1], %[load1], %[temp1] \n\t" - "sub %[load2], %[temp0], %[temp1] \n\t" - "sub %[load2], %[load2], %[temp2] \n\t" - "add %[load2], %[load2], %[temp3] \n\t" - "madd $ac1, %[load1], %[cospi_16_64] \n\t" - "madd $ac3, %[load2], %[cospi_16_64] \n\t" - - "extp %[step1_5], $ac1, 31 \n\t" - "extp %[step1_6], $ac3, 31 \n\t" - "add %[step1_4], %[temp0], %[temp1] \n\t" - "add %[step1_7], %[temp3], %[temp2] \n\t" - - : [load1] "=&r"(load1), [load2] "=&r"(load2), [load3] "=&r"(load3), - [load4] "=&r"(load4), [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), - [temp2] "=&r"(temp2), [temp3] "=&r"(temp3), [step1_4] "=&r"(step1_4), - [step1_5] "=&r"(step1_5), [step1_6] "=&r"(step1_6), - [step1_7] "=&r"(step1_7) - : [const_2_power_13] "r"(const_2_power_13), [input] "r"(input), - [cospi_20_64] "r"(cospi_20_64), [cospi_12_64] "r"(cospi_12_64), - [cospi_4_64] "r"(cospi_4_64), [cospi_28_64] "r"(cospi_28_64), - [cospi_16_64] "r"(cospi_16_64)); - - __asm__ __volatile__( - "add %[step2_0], %[step1_0], %[step1_7] \n\t" - "add %[step2_1], %[step1_1], %[step1_6] \n\t" - "add %[step2_2], %[step1_2], %[step1_5] \n\t" - "add %[step2_3], %[step1_3], %[step1_4] \n\t" - "sub %[step2_4], %[step1_3], %[step1_4] \n\t" - "sub %[step2_5], %[step1_2], %[step1_5] \n\t" - "sub %[step2_6], %[step1_1], %[step1_6] \n\t" - "sub %[step2_7], %[step1_0], %[step1_7] \n\t" - - : [step2_0] "=&r"(step2_0), [step2_4] "=&r"(step2_4), - [step2_1] "=&r"(step2_1), [step2_5] "=&r"(step2_5), - [step2_2] "=&r"(step2_2), [step2_6] "=&r"(step2_6), - [step2_3] "=&r"(step2_3), [step2_7] "=&r"(step2_7) - : [step1_0] "r"(step1_0), [step1_7] "r"(step1_7), - [step1_1] "r"(step1_1), [step1_6] "r"(step1_6), - [step1_2] "r"(step1_2), [step1_5] "r"(step1_5), - [step1_3] "r"(step1_3), [step1_4] "r"(step1_4)); - - // stage 7 - __asm__ __volatile__( - "add %[step1_0], %[step2_0], %[step3_15] \n\t" - "add %[step1_1], %[step2_1], %[step3_14] \n\t" - "add %[step1_2], %[step2_2], %[step3_13] \n\t" - "add %[step1_3], %[step2_3], %[step3_12] \n\t" - "sub %[step1_12], %[step2_3], %[step3_12] \n\t" - "sub %[step1_13], %[step2_2], %[step3_13] \n\t" - "sub %[step1_14], %[step2_1], %[step3_14] \n\t" - "sub %[step1_15], %[step2_0], %[step3_15] \n\t" - - : [step1_0] "=&r"(step1_0), [step1_12] "=&r"(step1_12), - [step1_1] "=&r"(step1_1), [step1_13] "=&r"(step1_13), - [step1_2] "=&r"(step1_2), [step1_14] "=&r"(step1_14), - [step1_3] "=&r"(step1_3), [step1_15] "=&r"(step1_15) - : [step2_0] "r"(step2_0), [step3_15] "r"(step3_15), - [step2_1] "r"(step2_1), [step3_14] "r"(step3_14), - [step2_2] "r"(step2_2), [step3_13] "r"(step3_13), - [step2_3] "r"(step2_3), [step3_12] "r"(step3_12)); - - __asm__ __volatile__( - "add %[step1_4], %[step2_4], %[step3_11] \n\t" - "add %[step1_5], %[step2_5], %[step3_10] \n\t" - "add %[step1_6], %[step2_6], %[step3_9] \n\t" - "add %[step1_7], %[step2_7], %[step3_8] \n\t" - "sub %[step1_8], %[step2_7], %[step3_8] \n\t" - "sub %[step1_9], %[step2_6], %[step3_9] \n\t" - "sub %[step1_10], %[step2_5], %[step3_10] \n\t" - "sub %[step1_11], %[step2_4], %[step3_11] \n\t" - - : [step1_4] "=&r"(step1_4), [step1_8] "=&r"(step1_8), - [step1_5] "=&r"(step1_5), [step1_9] "=&r"(step1_9), - [step1_6] "=&r"(step1_6), [step1_10] "=&r"(step1_10), - [step1_7] "=&r"(step1_7), [step1_11] "=&r"(step1_11) - : [step2_4] "r"(step2_4), [step3_11] "r"(step3_11), - [step2_5] "r"(step2_5), [step3_10] "r"(step3_10), - [step2_6] "r"(step2_6), [step3_9] "r"(step3_9), - [step2_7] "r"(step2_7), [step3_8] "r"(step3_8)); - - __asm__ __volatile__( - "sub %[temp0], %[step2_27], %[step2_20] \n\t" - "add %[temp1], %[step2_27], %[step2_20] \n\t" - "sub %[temp2], %[step2_26], %[step2_21] \n\t" - "add %[temp3], %[step2_26], %[step2_21] \n\t" - - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac0, %[temp0], %[cospi_16_64] \n\t" - "madd $ac1, %[temp1], %[cospi_16_64] \n\t" - "madd $ac2, %[temp2], %[cospi_16_64] \n\t" - "madd $ac3, %[temp3], %[cospi_16_64] \n\t" - - "extp %[step1_20], $ac0, 31 \n\t" - "extp %[step1_27], $ac1, 31 \n\t" - "extp %[step1_21], $ac2, 31 \n\t" - "extp %[step1_26], $ac3, 31 \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), [temp2] "=&r"(temp2), - [temp3] "=&r"(temp3), [step1_20] "=&r"(step1_20), - [step1_27] "=&r"(step1_27), [step1_21] "=&r"(step1_21), - [step1_26] "=&r"(step1_26) - : [const_2_power_13] "r"(const_2_power_13), [step2_20] "r"(step2_20), - [step2_27] "r"(step2_27), [step2_21] "r"(step2_21), - [step2_26] "r"(step2_26), [cospi_16_64] "r"(cospi_16_64)); - - __asm__ __volatile__( - "sub %[temp0], %[step2_25], %[step2_22] \n\t" - "add %[temp1], %[step2_25], %[step2_22] \n\t" - "sub %[temp2], %[step2_24], %[step2_23] \n\t" - "add %[temp3], %[step2_24], %[step2_23] \n\t" - - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "mtlo %[const_2_power_13], $ac2 \n\t" - "mthi $zero, $ac2 \n\t" - "mtlo %[const_2_power_13], $ac3 \n\t" - "mthi $zero, $ac3 \n\t" - - "madd $ac0, %[temp0], %[cospi_16_64] \n\t" - "madd $ac1, %[temp1], %[cospi_16_64] \n\t" - "madd $ac2, %[temp2], %[cospi_16_64] \n\t" - "madd $ac3, %[temp3], %[cospi_16_64] \n\t" - - "extp %[step1_22], $ac0, 31 \n\t" - "extp %[step1_25], $ac1, 31 \n\t" - "extp %[step1_23], $ac2, 31 \n\t" - "extp %[step1_24], $ac3, 31 \n\t" - - : [temp0] "=&r"(temp0), [temp1] "=&r"(temp1), [temp2] "=&r"(temp2), - [temp3] "=&r"(temp3), [step1_22] "=&r"(step1_22), - [step1_25] "=&r"(step1_25), [step1_23] "=&r"(step1_23), - [step1_24] "=&r"(step1_24) - : [const_2_power_13] "r"(const_2_power_13), [step2_22] "r"(step2_22), - [step2_25] "r"(step2_25), [step2_23] "r"(step2_23), - [step2_24] "r"(step2_24), [cospi_16_64] "r"(cospi_16_64)); - - // final stage - __asm__ __volatile__( - "add %[temp0], %[step1_0], %[step2_31] \n\t" - "add %[temp1], %[step1_1], %[step2_30] \n\t" - "add %[temp2], %[step1_2], %[step2_29] \n\t" - "add %[temp3], %[step1_3], %[step2_28] \n\t" - "sub %[load1], %[step1_3], %[step2_28] \n\t" - "sub %[load2], %[step1_2], %[step2_29] \n\t" - "sub %[load3], %[step1_1], %[step2_30] \n\t" - "sub %[load4], %[step1_0], %[step2_31] \n\t" - "sh %[temp0], 0(%[output]) \n\t" - "sh %[temp1], 64(%[output]) \n\t" - "sh %[temp2], 128(%[output]) \n\t" - "sh %[temp3], 192(%[output]) \n\t" - "sh %[load1], 1792(%[output]) \n\t" - "sh %[load2], 1856(%[output]) \n\t" - "sh %[load3], 1920(%[output]) \n\t" - "sh %[load4], 1984(%[output]) \n\t" - - : [temp0] "=&r"(temp0), [load1] "=&r"(load1), [temp1] "=&r"(temp1), - [load2] "=&r"(load2), [temp2] "=&r"(temp2), [load3] "=&r"(load3), - [temp3] "=&r"(temp3), [load4] "=&r"(load4) - : [step1_0] "r"(step1_0), [step2_31] "r"(step2_31), - [step1_1] "r"(step1_1), [step2_30] "r"(step2_30), - [step1_2] "r"(step1_2), [step2_29] "r"(step2_29), - [step1_3] "r"(step1_3), [step2_28] "r"(step2_28), - [output] "r"(output)); - - __asm__ __volatile__( - "add %[temp0], %[step1_4], %[step1_27] \n\t" - "add %[temp1], %[step1_5], %[step1_26] \n\t" - "add %[temp2], %[step1_6], %[step1_25] \n\t" - "add %[temp3], %[step1_7], %[step1_24] \n\t" - "sub %[load1], %[step1_7], %[step1_24] \n\t" - "sub %[load2], %[step1_6], %[step1_25] \n\t" - "sub %[load3], %[step1_5], %[step1_26] \n\t" - "sub %[load4], %[step1_4], %[step1_27] \n\t" - "sh %[temp0], 256(%[output]) \n\t" - "sh %[temp1], 320(%[output]) \n\t" - "sh %[temp2], 384(%[output]) \n\t" - "sh %[temp3], 448(%[output]) \n\t" - "sh %[load1], 1536(%[output]) \n\t" - "sh %[load2], 1600(%[output]) \n\t" - "sh %[load3], 1664(%[output]) \n\t" - "sh %[load4], 1728(%[output]) \n\t" - - : [temp0] "=&r"(temp0), [load1] "=&r"(load1), [temp1] "=&r"(temp1), - [load2] "=&r"(load2), [temp2] "=&r"(temp2), [load3] "=&r"(load3), - [temp3] "=&r"(temp3), [load4] "=&r"(load4) - : [step1_4] "r"(step1_4), [step1_27] "r"(step1_27), - [step1_5] "r"(step1_5), [step1_26] "r"(step1_26), - [step1_6] "r"(step1_6), [step1_25] "r"(step1_25), - [step1_7] "r"(step1_7), [step1_24] "r"(step1_24), - [output] "r"(output)); - - __asm__ __volatile__( - "add %[temp0], %[step1_8], %[step1_23] \n\t" - "add %[temp1], %[step1_9], %[step1_22] \n\t" - "add %[temp2], %[step1_10], %[step1_21] \n\t" - "add %[temp3], %[step1_11], %[step1_20] \n\t" - "sub %[load1], %[step1_11], %[step1_20] \n\t" - "sub %[load2], %[step1_10], %[step1_21] \n\t" - "sub %[load3], %[step1_9], %[step1_22] \n\t" - "sub %[load4], %[step1_8], %[step1_23] \n\t" - "sh %[temp0], 512(%[output]) \n\t" - "sh %[temp1], 576(%[output]) \n\t" - "sh %[temp2], 640(%[output]) \n\t" - "sh %[temp3], 704(%[output]) \n\t" - "sh %[load1], 1280(%[output]) \n\t" - "sh %[load2], 1344(%[output]) \n\t" - "sh %[load3], 1408(%[output]) \n\t" - "sh %[load4], 1472(%[output]) \n\t" - - : [temp0] "=&r"(temp0), [load1] "=&r"(load1), [temp1] "=&r"(temp1), - [load2] "=&r"(load2), [temp2] "=&r"(temp2), [load3] "=&r"(load3), - [temp3] "=&r"(temp3), [load4] "=&r"(load4) - : [step1_8] "r"(step1_8), [step1_23] "r"(step1_23), - [step1_9] "r"(step1_9), [step1_22] "r"(step1_22), - [step1_10] "r"(step1_10), [step1_21] "r"(step1_21), - [step1_11] "r"(step1_11), [step1_20] "r"(step1_20), - [output] "r"(output)); - - __asm__ __volatile__( - "add %[temp0], %[step1_12], %[step2_19] \n\t" - "add %[temp1], %[step1_13], %[step2_18] \n\t" - "add %[temp2], %[step1_14], %[step2_17] \n\t" - "add %[temp3], %[step1_15], %[step2_16] \n\t" - "sub %[load1], %[step1_15], %[step2_16] \n\t" - "sub %[load2], %[step1_14], %[step2_17] \n\t" - "sub %[load3], %[step1_13], %[step2_18] \n\t" - "sub %[load4], %[step1_12], %[step2_19] \n\t" - "sh %[temp0], 768(%[output]) \n\t" - "sh %[temp1], 832(%[output]) \n\t" - "sh %[temp2], 896(%[output]) \n\t" - "sh %[temp3], 960(%[output]) \n\t" - "sh %[load1], 1024(%[output]) \n\t" - "sh %[load2], 1088(%[output]) \n\t" - "sh %[load3], 1152(%[output]) \n\t" - "sh %[load4], 1216(%[output]) \n\t" - - : [temp0] "=&r"(temp0), [load1] "=&r"(load1), [temp1] "=&r"(temp1), - [load2] "=&r"(load2), [temp2] "=&r"(temp2), [load3] "=&r"(load3), - [temp3] "=&r"(temp3), [load4] "=&r"(load4) - : [step1_12] "r"(step1_12), [step2_19] "r"(step2_19), - [step1_13] "r"(step1_13), [step2_18] "r"(step2_18), - [step1_14] "r"(step1_14), [step2_17] "r"(step2_17), - [step1_15] "r"(step1_15), [step2_16] "r"(step2_16), - [output] "r"(output)); - - input += 32; - output += 1; - } -} - -void vpx_idct32x32_1024_add_dspr2(const int16_t *input, uint8_t *dest, - int stride) { - DECLARE_ALIGNED(32, int16_t, out[32 * 32]); - int16_t *outptr = out; - uint32_t pos = 45; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - // Rows - idct32_rows_dspr2(input, outptr, 32); - - // Columns - vpx_idct32_cols_add_blk_dspr2(out, dest, stride); -} - -void vpx_idct32x32_34_add_dspr2(const int16_t *input, uint8_t *dest, - int stride) { - DECLARE_ALIGNED(32, int16_t, out[32 * 32]); - int16_t *outptr = out; - uint32_t i; - uint32_t pos = 45; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - // Rows - idct32_rows_dspr2(input, outptr, 8); - - outptr += 8; - __asm__ __volatile__( - "sw $zero, 0(%[outptr]) \n\t" - "sw $zero, 4(%[outptr]) \n\t" - "sw $zero, 8(%[outptr]) \n\t" - "sw $zero, 12(%[outptr]) \n\t" - "sw $zero, 16(%[outptr]) \n\t" - "sw $zero, 20(%[outptr]) \n\t" - "sw $zero, 24(%[outptr]) \n\t" - "sw $zero, 28(%[outptr]) \n\t" - "sw $zero, 32(%[outptr]) \n\t" - "sw $zero, 36(%[outptr]) \n\t" - "sw $zero, 40(%[outptr]) \n\t" - "sw $zero, 44(%[outptr]) \n\t" - - : - : [outptr] "r"(outptr)); - - for (i = 0; i < 31; ++i) { - outptr += 32; - - __asm__ __volatile__( - "sw $zero, 0(%[outptr]) \n\t" - "sw $zero, 4(%[outptr]) \n\t" - "sw $zero, 8(%[outptr]) \n\t" - "sw $zero, 12(%[outptr]) \n\t" - "sw $zero, 16(%[outptr]) \n\t" - "sw $zero, 20(%[outptr]) \n\t" - "sw $zero, 24(%[outptr]) \n\t" - "sw $zero, 28(%[outptr]) \n\t" - "sw $zero, 32(%[outptr]) \n\t" - "sw $zero, 36(%[outptr]) \n\t" - "sw $zero, 40(%[outptr]) \n\t" - "sw $zero, 44(%[outptr]) \n\t" - - : - : [outptr] "r"(outptr)); - } - - // Columns - vpx_idct32_cols_add_blk_dspr2(out, dest, stride); -} - -void vpx_idct32x32_1_add_dspr2(const int16_t *input, uint8_t *dest, - int stride) { - int r, out; - int32_t a1, absa1; - int32_t vector_a1; - int32_t t1, t2, t3, t4; - int32_t vector_1, vector_2, vector_3, vector_4; - uint32_t pos = 45; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - - : - : [pos] "r"(pos)); - - out = DCT_CONST_ROUND_SHIFT_TWICE_COSPI_16_64(input[0]); - __asm__ __volatile__( - "addi %[out], %[out], 32 \n\t" - "sra %[a1], %[out], 6 \n\t" - - : [out] "+r"(out), [a1] "=r"(a1) - :); - - if (a1 < 0) { - /* use quad-byte - * input and output memory are four byte aligned */ - __asm__ __volatile__( - "abs %[absa1], %[a1] \n\t" - "replv.qb %[vector_a1], %[absa1] \n\t" - - : [absa1] "=&r"(absa1), [vector_a1] "=&r"(vector_a1) - : [a1] "r"(a1)); - - for (r = 32; r--;) { - __asm__ __volatile__( - "lw %[t1], 0(%[dest]) \n\t" - "lw %[t2], 4(%[dest]) \n\t" - "lw %[t3], 8(%[dest]) \n\t" - "lw %[t4], 12(%[dest]) \n\t" - "subu_s.qb %[vector_1], %[t1], %[vector_a1] \n\t" - "subu_s.qb %[vector_2], %[t2], %[vector_a1] \n\t" - "subu_s.qb %[vector_3], %[t3], %[vector_a1] \n\t" - "subu_s.qb %[vector_4], %[t4], %[vector_a1] \n\t" - "sw %[vector_1], 0(%[dest]) \n\t" - "sw %[vector_2], 4(%[dest]) \n\t" - "sw %[vector_3], 8(%[dest]) \n\t" - "sw %[vector_4], 12(%[dest]) \n\t" - - "lw %[t1], 16(%[dest]) \n\t" - "lw %[t2], 20(%[dest]) \n\t" - "lw %[t3], 24(%[dest]) \n\t" - "lw %[t4], 28(%[dest]) \n\t" - "subu_s.qb %[vector_1], %[t1], %[vector_a1] \n\t" - "subu_s.qb %[vector_2], %[t2], %[vector_a1] \n\t" - "subu_s.qb %[vector_3], %[t3], %[vector_a1] \n\t" - "subu_s.qb %[vector_4], %[t4], %[vector_a1] \n\t" - "sw %[vector_1], 16(%[dest]) \n\t" - "sw %[vector_2], 20(%[dest]) \n\t" - "sw %[vector_3], 24(%[dest]) \n\t" - "sw %[vector_4], 28(%[dest]) \n\t" - - "add %[dest], %[dest], %[stride] \n\t" - - : [t1] "=&r"(t1), [t2] "=&r"(t2), [t3] "=&r"(t3), [t4] "=&r"(t4), - [vector_1] "=&r"(vector_1), [vector_2] "=&r"(vector_2), - [vector_3] "=&r"(vector_3), [vector_4] "=&r"(vector_4), - [dest] "+&r"(dest) - : [stride] "r"(stride), [vector_a1] "r"(vector_a1)); - } - } else if (a1 > 255) { - int32_t a11, a12, vector_a11, vector_a12; - - /* use quad-byte - * input and output memory are four byte aligned */ - a11 = a1 >> 1; - a12 = a1 - a11; - __asm__ __volatile__( - "replv.qb %[vector_a11], %[a11] \n\t" - "replv.qb %[vector_a12], %[a12] \n\t" - - : [vector_a11] "=&r"(vector_a11), [vector_a12] "=&r"(vector_a12) - : [a11] "r"(a11), [a12] "r"(a12)); - - for (r = 32; r--;) { - __asm__ __volatile__( - "lw %[t1], 0(%[dest]) \n\t" - "lw %[t2], 4(%[dest]) \n\t" - "lw %[t3], 8(%[dest]) \n\t" - "lw %[t4], 12(%[dest]) \n\t" - "addu_s.qb %[vector_1], %[t1], %[vector_a11] \n\t" - "addu_s.qb %[vector_2], %[t2], %[vector_a11] \n\t" - "addu_s.qb %[vector_3], %[t3], %[vector_a11] \n\t" - "addu_s.qb %[vector_4], %[t4], %[vector_a11] \n\t" - "addu_s.qb %[vector_1], %[vector_1], %[vector_a12] \n\t" - "addu_s.qb %[vector_2], %[vector_2], %[vector_a12] \n\t" - "addu_s.qb %[vector_3], %[vector_3], %[vector_a12] \n\t" - "addu_s.qb %[vector_4], %[vector_4], %[vector_a12] \n\t" - "sw %[vector_1], 0(%[dest]) \n\t" - "sw %[vector_2], 4(%[dest]) \n\t" - "sw %[vector_3], 8(%[dest]) \n\t" - "sw %[vector_4], 12(%[dest]) \n\t" - - "lw %[t1], 16(%[dest]) \n\t" - "lw %[t2], 20(%[dest]) \n\t" - "lw %[t3], 24(%[dest]) \n\t" - "lw %[t4], 28(%[dest]) \n\t" - "addu_s.qb %[vector_1], %[t1], %[vector_a11] \n\t" - "addu_s.qb %[vector_2], %[t2], %[vector_a11] \n\t" - "addu_s.qb %[vector_3], %[t3], %[vector_a11] \n\t" - "addu_s.qb %[vector_4], %[t4], %[vector_a11] \n\t" - "addu_s.qb %[vector_1], %[vector_1], %[vector_a12] \n\t" - "addu_s.qb %[vector_2], %[vector_2], %[vector_a12] \n\t" - "addu_s.qb %[vector_3], %[vector_3], %[vector_a12] \n\t" - "addu_s.qb %[vector_4], %[vector_4], %[vector_a12] \n\t" - "sw %[vector_1], 16(%[dest]) \n\t" - "sw %[vector_2], 20(%[dest]) \n\t" - "sw %[vector_3], 24(%[dest]) \n\t" - "sw %[vector_4], 28(%[dest]) \n\t" - - "add %[dest], %[dest], %[stride] \n\t" - - : [t1] "=&r"(t1), [t2] "=&r"(t2), [t3] "=&r"(t3), [t4] "=&r"(t4), - [vector_1] "=&r"(vector_1), [vector_2] "=&r"(vector_2), - [vector_3] "=&r"(vector_3), [vector_4] "=&r"(vector_4), - [dest] "+&r"(dest) - : [stride] "r"(stride), [vector_a11] "r"(vector_a11), - [vector_a12] "r"(vector_a12)); - } - } else { - /* use quad-byte - * input and output memory are four byte aligned */ - __asm__ __volatile__("replv.qb %[vector_a1], %[a1] \n\t" - - : [vector_a1] "=&r"(vector_a1) - : [a1] "r"(a1)); - - for (r = 32; r--;) { - __asm__ __volatile__( - "lw %[t1], 0(%[dest]) \n\t" - "lw %[t2], 4(%[dest]) \n\t" - "lw %[t3], 8(%[dest]) \n\t" - "lw %[t4], 12(%[dest]) \n\t" - "addu_s.qb %[vector_1], %[t1], %[vector_a1] \n\t" - "addu_s.qb %[vector_2], %[t2], %[vector_a1] \n\t" - "addu_s.qb %[vector_3], %[t3], %[vector_a1] \n\t" - "addu_s.qb %[vector_4], %[t4], %[vector_a1] \n\t" - "sw %[vector_1], 0(%[dest]) \n\t" - "sw %[vector_2], 4(%[dest]) \n\t" - "sw %[vector_3], 8(%[dest]) \n\t" - "sw %[vector_4], 12(%[dest]) \n\t" - - "lw %[t1], 16(%[dest]) \n\t" - "lw %[t2], 20(%[dest]) \n\t" - "lw %[t3], 24(%[dest]) \n\t" - "lw %[t4], 28(%[dest]) \n\t" - "addu_s.qb %[vector_1], %[t1], %[vector_a1] \n\t" - "addu_s.qb %[vector_2], %[t2], %[vector_a1] \n\t" - "addu_s.qb %[vector_3], %[t3], %[vector_a1] \n\t" - "addu_s.qb %[vector_4], %[t4], %[vector_a1] \n\t" - "sw %[vector_1], 16(%[dest]) \n\t" - "sw %[vector_2], 20(%[dest]) \n\t" - "sw %[vector_3], 24(%[dest]) \n\t" - "sw %[vector_4], 28(%[dest]) \n\t" - - "add %[dest], %[dest], %[stride] \n\t" - - : [t1] "=&r"(t1), [t2] "=&r"(t2), [t3] "=&r"(t3), [t4] "=&r"(t4), - [vector_1] "=&r"(vector_1), [vector_2] "=&r"(vector_2), - [vector_3] "=&r"(vector_3), [vector_4] "=&r"(vector_4), - [dest] "+&r"(dest) - : [stride] "r"(stride), [vector_a1] "r"(vector_a1)); - } - } -} -#endif // #if HAVE_DSPR2 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/itrans4_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/itrans4_dspr2.c deleted file mode 100644 index e214b538..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/itrans4_dspr2.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/inv_txfm_dspr2.h" -#include "vpx_dsp/txfm_common.h" - -#if HAVE_DSPR2 -void vpx_idct4_rows_dspr2(const int16_t *input, int16_t *output) { - int step_0, step_1, step_2, step_3; - int Temp0, Temp1, Temp2, Temp3; - const int const_2_power_13 = 8192; - int i; - - for (i = 4; i--;) { - __asm__ __volatile__( - /* - temp_1 = (input[0] + input[2]) * cospi_16_64; - step_0 = dct_const_round_shift(temp_1); - - temp_2 = (input[0] - input[2]) * cospi_16_64; - step_1 = dct_const_round_shift(temp_2); - */ - "lh %[Temp0], 0(%[input]) \n\t" - "lh %[Temp1], 4(%[input]) \n\t" - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "add %[Temp2], %[Temp0], %[Temp1] \n\t" - "sub %[Temp3], %[Temp0], %[Temp1] \n\t" - "madd $ac0, %[Temp2], %[cospi_16_64] \n\t" - "lh %[Temp0], 2(%[input]) \n\t" - "lh %[Temp1], 6(%[input]) \n\t" - "extp %[step_0], $ac0, 31 \n\t" - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - - "madd $ac1, %[Temp3], %[cospi_16_64] \n\t" - "extp %[step_1], $ac1, 31 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - - /* - temp1 = input[1] * cospi_24_64 - input[3] * cospi_8_64; - step_2 = dct_const_round_shift(temp1); - */ - "madd $ac0, %[Temp0], %[cospi_24_64] \n\t" - "msub $ac0, %[Temp1], %[cospi_8_64] \n\t" - "extp %[step_2], $ac0, 31 \n\t" - - /* - temp2 = input[1] * cospi_8_64 + input[3] * cospi_24_64; - step_3 = dct_const_round_shift(temp2); - */ - "madd $ac1, %[Temp0], %[cospi_8_64] \n\t" - "madd $ac1, %[Temp1], %[cospi_24_64] \n\t" - "extp %[step_3], $ac1, 31 \n\t" - - /* - output[0] = step_0 + step_3; - output[4] = step_1 + step_2; - output[8] = step_1 - step_2; - output[12] = step_0 - step_3; - */ - "add %[Temp0], %[step_0], %[step_3] \n\t" - "sh %[Temp0], 0(%[output]) \n\t" - - "add %[Temp1], %[step_1], %[step_2] \n\t" - "sh %[Temp1], 8(%[output]) \n\t" - - "sub %[Temp2], %[step_1], %[step_2] \n\t" - "sh %[Temp2], 16(%[output]) \n\t" - - "sub %[Temp3], %[step_0], %[step_3] \n\t" - "sh %[Temp3], 24(%[output]) \n\t" - - : [Temp0] "=&r"(Temp0), [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), - [Temp3] "=&r"(Temp3), [step_0] "=&r"(step_0), [step_1] "=&r"(step_1), - [step_2] "=&r"(step_2), [step_3] "=&r"(step_3), [output] "+r"(output) - : [const_2_power_13] "r"(const_2_power_13), - [cospi_8_64] "r"(cospi_8_64), [cospi_16_64] "r"(cospi_16_64), - [cospi_24_64] "r"(cospi_24_64), [input] "r"(input)); - - input += 4; - output += 1; - } -} - -void vpx_idct4_columns_add_blk_dspr2(int16_t *input, uint8_t *dest, - int stride) { - int step_0, step_1, step_2, step_3; - int Temp0, Temp1, Temp2, Temp3; - const int const_2_power_13 = 8192; - const int const_255 = 255; - int i; - uint8_t *dest_pix; - - for (i = 0; i < 4; ++i) { - dest_pix = (dest + i); - - __asm__ __volatile__( - /* - temp_1 = (input[0] + input[2]) * cospi_16_64; - step_0 = dct_const_round_shift(temp_1); - - temp_2 = (input[0] - input[2]) * cospi_16_64; - step_1 = dct_const_round_shift(temp_2); - */ - "lh %[Temp0], 0(%[input]) \n\t" - "lh %[Temp1], 4(%[input]) \n\t" - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "add %[Temp2], %[Temp0], %[Temp1] \n\t" - "sub %[Temp3], %[Temp0], %[Temp1] \n\t" - "madd $ac0, %[Temp2], %[cospi_16_64] \n\t" - "lh %[Temp0], 2(%[input]) \n\t" - "lh %[Temp1], 6(%[input]) \n\t" - "extp %[step_0], $ac0, 31 \n\t" - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - - "madd $ac1, %[Temp3], %[cospi_16_64] \n\t" - "extp %[step_1], $ac1, 31 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - - /* - temp1 = input[1] * cospi_24_64 - input[3] * cospi_8_64; - step_2 = dct_const_round_shift(temp1); - */ - "madd $ac0, %[Temp0], %[cospi_24_64] \n\t" - "msub $ac0, %[Temp1], %[cospi_8_64] \n\t" - "extp %[step_2], $ac0, 31 \n\t" - - /* - temp2 = input[1] * cospi_8_64 + input[3] * cospi_24_64; - step_3 = dct_const_round_shift(temp2); - */ - "madd $ac1, %[Temp0], %[cospi_8_64] \n\t" - "madd $ac1, %[Temp1], %[cospi_24_64] \n\t" - "extp %[step_3], $ac1, 31 \n\t" - - /* - output[0] = step_0 + step_3; - output[4] = step_1 + step_2; - output[8] = step_1 - step_2; - output[12] = step_0 - step_3; - */ - "add %[Temp0], %[step_0], %[step_3] \n\t" - "addi %[Temp0], %[Temp0], 8 \n\t" - "sra %[Temp0], %[Temp0], 4 \n\t" - "lbu %[Temp1], 0(%[dest_pix]) \n\t" - "add %[Temp1], %[Temp1], %[Temp0] \n\t" - "slt %[Temp2], %[Temp1], %[const_255] \n\t" - "slt %[Temp3], $zero, %[Temp1] \n\t" - "movz %[Temp1], %[const_255], %[Temp2] \n\t" - "movz %[Temp1], $zero, %[Temp3] \n\t" - "sb %[Temp1], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "add %[Temp0], %[step_1], %[step_2] \n\t" - "addi %[Temp0], %[Temp0], 8 \n\t" - "sra %[Temp0], %[Temp0], 4 \n\t" - "lbu %[Temp1], 0(%[dest_pix]) \n\t" - "add %[Temp1], %[Temp1], %[Temp0] \n\t" - "slt %[Temp2], %[Temp1], %[const_255] \n\t" - "slt %[Temp3], $zero, %[Temp1] \n\t" - "movz %[Temp1], %[const_255], %[Temp2] \n\t" - "movz %[Temp1], $zero, %[Temp3] \n\t" - "sb %[Temp1], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "sub %[Temp0], %[step_1], %[step_2] \n\t" - "addi %[Temp0], %[Temp0], 8 \n\t" - "sra %[Temp0], %[Temp0], 4 \n\t" - "lbu %[Temp1], 0(%[dest_pix]) \n\t" - "add %[Temp1], %[Temp1], %[Temp0] \n\t" - "slt %[Temp2], %[Temp1], %[const_255] \n\t" - "slt %[Temp3], $zero, %[Temp1] \n\t" - "movz %[Temp1], %[const_255], %[Temp2] \n\t" - "movz %[Temp1], $zero, %[Temp3] \n\t" - "sb %[Temp1], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "sub %[Temp0], %[step_0], %[step_3] \n\t" - "addi %[Temp0], %[Temp0], 8 \n\t" - "sra %[Temp0], %[Temp0], 4 \n\t" - "lbu %[Temp1], 0(%[dest_pix]) \n\t" - "add %[Temp1], %[Temp1], %[Temp0] \n\t" - "slt %[Temp2], %[Temp1], %[const_255] \n\t" - "slt %[Temp3], $zero, %[Temp1] \n\t" - "movz %[Temp1], %[const_255], %[Temp2] \n\t" - "movz %[Temp1], $zero, %[Temp3] \n\t" - "sb %[Temp1], 0(%[dest_pix]) \n\t" - - : [Temp0] "=&r"(Temp0), [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), - [Temp3] "=&r"(Temp3), [step_0] "=&r"(step_0), [step_1] "=&r"(step_1), - [step_2] "=&r"(step_2), [step_3] "=&r"(step_3), - [dest_pix] "+r"(dest_pix) - : [const_2_power_13] "r"(const_2_power_13), [const_255] "r"(const_255), - [cospi_8_64] "r"(cospi_8_64), [cospi_16_64] "r"(cospi_16_64), - [cospi_24_64] "r"(cospi_24_64), [input] "r"(input), - [stride] "r"(stride)); - - input += 4; - } -} - -void vpx_idct4x4_16_add_dspr2(const int16_t *input, uint8_t *dest, int stride) { - DECLARE_ALIGNED(32, int16_t, out[4 * 4]); - int16_t *outptr = out; - uint32_t pos = 45; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - : - : [pos] "r"(pos)); - - // Rows - vpx_idct4_rows_dspr2(input, outptr); - - // Columns - vpx_idct4_columns_add_blk_dspr2(&out[0], dest, stride); -} - -void vpx_idct4x4_1_add_dspr2(const int16_t *input, uint8_t *dest, int stride) { - int a1, absa1; - int r; - int32_t out; - int t2, vector_a1, vector_a; - uint32_t pos = 45; - int16_t input_dc = input[0]; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - - : - : [pos] "r"(pos)); - - out = DCT_CONST_ROUND_SHIFT_TWICE_COSPI_16_64(input_dc); - __asm__ __volatile__( - "addi %[out], %[out], 8 \n\t" - "sra %[a1], %[out], 4 \n\t" - - : [out] "+r"(out), [a1] "=r"(a1) - :); - - if (a1 < 0) { - /* use quad-byte - * input and output memory are four byte aligned */ - __asm__ __volatile__( - "abs %[absa1], %[a1] \n\t" - "replv.qb %[vector_a1], %[absa1] \n\t" - - : [absa1] "=r"(absa1), [vector_a1] "=r"(vector_a1) - : [a1] "r"(a1)); - - for (r = 4; r--;) { - __asm__ __volatile__( - "lw %[t2], 0(%[dest]) \n\t" - "subu_s.qb %[vector_a], %[t2], %[vector_a1] \n\t" - "sw %[vector_a], 0(%[dest]) \n\t" - "add %[dest], %[dest], %[stride] \n\t" - - : [t2] "=&r"(t2), [vector_a] "=&r"(vector_a), [dest] "+&r"(dest) - : [stride] "r"(stride), [vector_a1] "r"(vector_a1)); - } - } else if (a1 > 255) { - int32_t a11, a12, vector_a11, vector_a12; - - /* use quad-byte - * input and output memory are four byte aligned */ - a11 = a1 >> 3; - a12 = a1 - (a11 * 7); - - __asm__ __volatile__( - "replv.qb %[vector_a11], %[a11] \n\t" - "replv.qb %[vector_a12], %[a12] \n\t" - - : [vector_a11] "=&r"(vector_a11), [vector_a12] "=&r"(vector_a12) - : [a11] "r"(a11), [a12] "r"(a12)); - - for (r = 4; r--;) { - __asm__ __volatile__( - "lw %[t2], 4(%[dest]) \n\t" - "addu_s.qb %[vector_a], %[t2], %[vector_a11] \n\t" - "addu_s.qb %[vector_a], %[vector_a], %[vector_a11] \n\t" - "addu_s.qb %[vector_a], %[vector_a], %[vector_a11] \n\t" - "addu_s.qb %[vector_a], %[vector_a], %[vector_a11] \n\t" - "addu_s.qb %[vector_a], %[vector_a], %[vector_a11] \n\t" - "addu_s.qb %[vector_a], %[vector_a], %[vector_a11] \n\t" - "addu_s.qb %[vector_a], %[vector_a], %[vector_a11] \n\t" - "addu_s.qb %[vector_a], %[vector_a], %[vector_a12] \n\t" - "sw %[vector_a], 0(%[dest]) \n\t" - "add %[dest], %[dest], %[stride] \n\t" - - : [t2] "=&r"(t2), [vector_a] "=&r"(vector_a), [dest] "+&r"(dest) - : [stride] "r"(stride), [vector_a11] "r"(vector_a11), - [vector_a12] "r"(vector_a12)); - } - } else { - /* use quad-byte - * input and output memory are four byte aligned */ - __asm__ __volatile__("replv.qb %[vector_a1], %[a1] \n\t" - : [vector_a1] "=r"(vector_a1) - : [a1] "r"(a1)); - - for (r = 4; r--;) { - __asm__ __volatile__( - "lw %[t2], 0(%[dest]) \n\t" - "addu_s.qb %[vector_a], %[t2], %[vector_a1] \n\t" - "sw %[vector_a], 0(%[dest]) \n\t" - "add %[dest], %[dest], %[stride] \n\t" - - : [t2] "=&r"(t2), [vector_a] "=&r"(vector_a), [dest] "+&r"(dest) - : [stride] "r"(stride), [vector_a1] "r"(vector_a1)); - } - } -} - -void iadst4_dspr2(const int16_t *input, int16_t *output) { - int s0, s1, s2, s3, s4, s5, s6, s7; - int x0, x1, x2, x3; - - x0 = input[0]; - x1 = input[1]; - x2 = input[2]; - x3 = input[3]; - - if (!(x0 | x1 | x2 | x3)) { - output[0] = output[1] = output[2] = output[3] = 0; - return; - } - - // 32-bit result is enough for the following multiplications. - s0 = sinpi_1_9 * x0; - s1 = sinpi_2_9 * x0; - s2 = sinpi_3_9 * x1; - s3 = sinpi_4_9 * x2; - s4 = sinpi_1_9 * x2; - s5 = sinpi_2_9 * x3; - s6 = sinpi_4_9 * x3; - s7 = x0 - x2 + x3; - - x0 = s0 + s3 + s5; - x1 = s1 - s4 - s6; - x2 = sinpi_3_9 * s7; - x3 = s2; - - s0 = x0 + x3; - s1 = x1 + x3; - s2 = x2; - s3 = x0 + x1 - x3; - - // 1-D transform scaling factor is sqrt(2). - // The overall dynamic range is 14b (input) + 14b (multiplication scaling) - // + 1b (addition) = 29b. - // Hence the output bit depth is 15b. - output[0] = dct_const_round_shift(s0); - output[1] = dct_const_round_shift(s1); - output[2] = dct_const_round_shift(s2); - output[3] = dct_const_round_shift(s3); -} -#endif // #if HAVE_DSPR2 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/itrans8_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/itrans8_dspr2.c deleted file mode 100644 index d4d24696..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/itrans8_dspr2.c +++ /dev/null @@ -1,690 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/inv_txfm_dspr2.h" -#include "vpx_dsp/txfm_common.h" - -#if HAVE_DSPR2 -void idct8_rows_dspr2(const int16_t *input, int16_t *output, uint32_t no_rows) { - int step1_0, step1_1, step1_2, step1_3, step1_4, step1_5, step1_6, step1_7; - const int const_2_power_13 = 8192; - int Temp0, Temp1, Temp2, Temp3, Temp4; - int i; - - for (i = no_rows; i--;) { - __asm__ __volatile__( - /* - temp_1 = (input[0] + input[4]) * cospi_16_64; - step2_0 = dct_const_round_shift(temp_1); - - temp_2 = (input[0] - input[4]) * cospi_16_64; - step2_1 = dct_const_round_shift(temp_2); - */ - "lh %[Temp0], 0(%[input]) \n\t" - "lh %[Temp1], 8(%[input]) \n\t" - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "add %[Temp2], %[Temp0], %[Temp1] \n\t" - "madd $ac0, %[Temp2], %[cospi_16_64] \n\t" - "extp %[Temp4], $ac0, 31 \n\t" - - "sub %[Temp3], %[Temp0], %[Temp1] \n\t" - "madd $ac1, %[Temp3], %[cospi_16_64] \n\t" - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "extp %[Temp2], $ac1, 31 \n\t" - - /* - temp_1 = input[2] * cospi_24_64 - input[6] * cospi_8_64; - step2_2 = dct_const_round_shift(temp_1); - */ - "lh %[Temp0], 4(%[input]) \n\t" - "lh %[Temp1], 12(%[input]) \n\t" - "madd $ac0, %[Temp0], %[cospi_24_64] \n\t" - "msub $ac0, %[Temp1], %[cospi_8_64] \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "extp %[Temp3], $ac0, 31 \n\t" - - /* - step1_1 = step2_1 + step2_2; - step1_2 = step2_1 - step2_2; - */ - "add %[step1_1], %[Temp2], %[Temp3] \n\t" - "sub %[step1_2], %[Temp2], %[Temp3] \n\t" - - /* - temp_2 = input[2] * cospi_8_64 + input[6] * cospi_24_64; - step2_3 = dct_const_round_shift(temp_2); - */ - "madd $ac1, %[Temp0], %[cospi_8_64] \n\t" - "madd $ac1, %[Temp1], %[cospi_24_64] \n\t" - "extp %[Temp1], $ac1, 31 \n\t" - - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - - /* - step1_0 = step2_0 + step2_3; - step1_3 = step2_0 - step2_3; - */ - "add %[step1_0], %[Temp4], %[Temp1] \n\t" - "sub %[step1_3], %[Temp4], %[Temp1] \n\t" - - /* - temp_1 = input[1] * cospi_28_64 - input[7] * cospi_4_64; - step1_4 = dct_const_round_shift(temp_1); - */ - "lh %[Temp0], 2(%[input]) \n\t" - "madd $ac0, %[Temp0], %[cospi_28_64] \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "lh %[Temp1], 14(%[input]) \n\t" - "lh %[Temp0], 2(%[input]) \n\t" - "msub $ac0, %[Temp1], %[cospi_4_64] \n\t" - "extp %[step1_4], $ac0, 31 \n\t" - - /* - temp_2 = input[1] * cospi_4_64 + input[7] * cospi_28_64; - step1_7 = dct_const_round_shift(temp_2); - */ - "madd $ac1, %[Temp0], %[cospi_4_64] \n\t" - "madd $ac1, %[Temp1], %[cospi_28_64] \n\t" - "extp %[step1_7], $ac1, 31 \n\t" - - /* - temp_1 = input[5] * cospi_12_64 - input[3] * cospi_20_64; - step1_5 = dct_const_round_shift(temp_1); - */ - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "lh %[Temp0], 10(%[input]) \n\t" - "madd $ac0, %[Temp0], %[cospi_12_64] \n\t" - "lh %[Temp1], 6(%[input]) \n\t" - "msub $ac0, %[Temp1], %[cospi_20_64] \n\t" - "extp %[step1_5], $ac0, 31 \n\t" - - /* - temp_2 = input[5] * cospi_20_64 + input[3] * cospi_12_64; - step1_6 = dct_const_round_shift(temp_2); - */ - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "lh %[Temp0], 10(%[input]) \n\t" - "madd $ac1, %[Temp0], %[cospi_20_64] \n\t" - "lh %[Temp1], 6(%[input]) \n\t" - "madd $ac1, %[Temp1], %[cospi_12_64] \n\t" - "extp %[step1_6], $ac1, 31 \n\t" - - /* - temp_1 = (step1_7 - step1_6 - step1_4 + step1_5) * cospi_16_64; - temp_2 = (step1_4 - step1_5 - step1_6 + step1_7) * cospi_16_64; - */ - "sub %[Temp0], %[step1_7], %[step1_6] \n\t" - "sub %[Temp0], %[Temp0], %[step1_4] \n\t" - "add %[Temp0], %[Temp0], %[step1_5] \n\t" - "sub %[Temp1], %[step1_4], %[step1_5] \n\t" - "sub %[Temp1], %[Temp1], %[step1_6] \n\t" - "add %[Temp1], %[Temp1], %[step1_7] \n\t" - - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - - "madd $ac0, %[Temp0], %[cospi_16_64] \n\t" - "madd $ac1, %[Temp1], %[cospi_16_64] \n\t" - - /* - step1_4 = step1_4 + step1_5; - step1_7 = step1_6 + step1_7; - */ - "add %[step1_4], %[step1_4], %[step1_5] \n\t" - "add %[step1_7], %[step1_7], %[step1_6] \n\t" - - "extp %[step1_5], $ac0, 31 \n\t" - "extp %[step1_6], $ac1, 31 \n\t" - - "add %[Temp0], %[step1_0], %[step1_7] \n\t" - "sh %[Temp0], 0(%[output]) \n\t" - "add %[Temp1], %[step1_1], %[step1_6] \n\t" - "sh %[Temp1], 16(%[output]) \n\t" - "add %[Temp0], %[step1_2], %[step1_5] \n\t" - "sh %[Temp0], 32(%[output]) \n\t" - "add %[Temp1], %[step1_3], %[step1_4] \n\t" - "sh %[Temp1], 48(%[output]) \n\t" - - "sub %[Temp0], %[step1_3], %[step1_4] \n\t" - "sh %[Temp0], 64(%[output]) \n\t" - "sub %[Temp1], %[step1_2], %[step1_5] \n\t" - "sh %[Temp1], 80(%[output]) \n\t" - "sub %[Temp0], %[step1_1], %[step1_6] \n\t" - "sh %[Temp0], 96(%[output]) \n\t" - "sub %[Temp1], %[step1_0], %[step1_7] \n\t" - "sh %[Temp1], 112(%[output]) \n\t" - - : [step1_0] "=&r"(step1_0), [step1_1] "=&r"(step1_1), - [step1_2] "=&r"(step1_2), [step1_3] "=&r"(step1_3), - [step1_4] "=&r"(step1_4), [step1_5] "=&r"(step1_5), - [step1_6] "=&r"(step1_6), [step1_7] "=&r"(step1_7), - [Temp0] "=&r"(Temp0), [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), - [Temp3] "=&r"(Temp3), [Temp4] "=&r"(Temp4) - : [const_2_power_13] "r"(const_2_power_13), - [cospi_16_64] "r"(cospi_16_64), [cospi_28_64] "r"(cospi_28_64), - [cospi_4_64] "r"(cospi_4_64), [cospi_12_64] "r"(cospi_12_64), - [cospi_20_64] "r"(cospi_20_64), [cospi_8_64] "r"(cospi_8_64), - [cospi_24_64] "r"(cospi_24_64), [output] "r"(output), - [input] "r"(input)); - - input += 8; - output += 1; - } -} - -void idct8_columns_add_blk_dspr2(int16_t *input, uint8_t *dest, int stride) { - int step1_0, step1_1, step1_2, step1_3, step1_4, step1_5, step1_6, step1_7; - int Temp0, Temp1, Temp2, Temp3; - int i; - const int const_2_power_13 = 8192; - const int const_255 = 255; - uint8_t *dest_pix; - - for (i = 0; i < 8; ++i) { - dest_pix = (dest + i); - - __asm__ __volatile__( - /* - temp_1 = (input[0] + input[4]) * cospi_16_64; - step2_0 = dct_const_round_shift(temp_1); - - temp_2 = (input[0] - input[4]) * cospi_16_64; - step2_1 = dct_const_round_shift(temp_2); - */ - "lh %[Temp0], 0(%[input]) \n\t" - "lh %[Temp1], 8(%[input]) \n\t" - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "add %[Temp2], %[Temp0], %[Temp1] \n\t" - "madd $ac0, %[Temp2], %[cospi_16_64] \n\t" - "extp %[step1_6], $ac0, 31 \n\t" - - "sub %[Temp3], %[Temp0], %[Temp1] \n\t" - "madd $ac1, %[Temp3], %[cospi_16_64] \n\t" - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "extp %[Temp2], $ac1, 31 \n\t" - - /* - temp_1 = input[2] * cospi_24_64 - input[6] * cospi_8_64; - step2_2 = dct_const_round_shift(temp_1); - */ - "lh %[Temp0], 4(%[input]) \n\t" - "lh %[Temp1], 12(%[input]) \n\t" - "madd $ac0, %[Temp0], %[cospi_24_64] \n\t" - "msub $ac0, %[Temp1], %[cospi_8_64] \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "extp %[Temp3], $ac0, 31 \n\t" - - /* - step1_1 = step2_1 + step2_2; - step1_2 = step2_1 - step2_2; - */ - "add %[step1_1], %[Temp2], %[Temp3] \n\t" - "sub %[step1_2], %[Temp2], %[Temp3] \n\t" - - /* - temp_2 = input[2] * cospi_8_64 + input[6] * cospi_24_64; - step2_3 = dct_const_round_shift(temp_2); - */ - "madd $ac1, %[Temp0], %[cospi_8_64] \n\t" - "madd $ac1, %[Temp1], %[cospi_24_64] \n\t" - "extp %[Temp1], $ac1, 31 \n\t" - - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - - /* - step1_0 = step2_0 + step2_3; - step1_3 = step2_0 - step2_3; - */ - "add %[step1_0], %[step1_6], %[Temp1] \n\t" - "sub %[step1_3], %[step1_6], %[Temp1] \n\t" - - /* - temp_1 = input[1] * cospi_28_64 - input[7] * cospi_4_64; - step1_4 = dct_const_round_shift(temp_1); - */ - "lh %[Temp0], 2(%[input]) \n\t" - "madd $ac0, %[Temp0], %[cospi_28_64] \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "lh %[Temp1], 14(%[input]) \n\t" - "lh %[Temp0], 2(%[input]) \n\t" - "msub $ac0, %[Temp1], %[cospi_4_64] \n\t" - "extp %[step1_4], $ac0, 31 \n\t" - - /* - temp_2 = input[1] * cospi_4_64 + input[7] * cospi_28_64; - step1_7 = dct_const_round_shift(temp_2); - */ - "madd $ac1, %[Temp0], %[cospi_4_64] \n\t" - "madd $ac1, %[Temp1], %[cospi_28_64] \n\t" - "extp %[step1_7], $ac1, 31 \n\t" - - /* - temp_1 = input[5] * cospi_12_64 - input[3] * cospi_20_64; - step1_5 = dct_const_round_shift(temp_1); - */ - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "lh %[Temp0], 10(%[input]) \n\t" - "madd $ac0, %[Temp0], %[cospi_12_64] \n\t" - "lh %[Temp1], 6(%[input]) \n\t" - "msub $ac0, %[Temp1], %[cospi_20_64] \n\t" - "extp %[step1_5], $ac0, 31 \n\t" - - /* - temp_2 = input[5] * cospi_20_64 + input[3] * cospi_12_64; - step1_6 = dct_const_round_shift(temp_2); - */ - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - "lh %[Temp0], 10(%[input]) \n\t" - "madd $ac1, %[Temp0], %[cospi_20_64] \n\t" - "lh %[Temp1], 6(%[input]) \n\t" - "madd $ac1, %[Temp1], %[cospi_12_64] \n\t" - "extp %[step1_6], $ac1, 31 \n\t" - - /* - temp_1 = (step1_7 - step1_6 - step1_4 + step1_5) * cospi_16_64; - temp_2 = (step1_4 - step1_5 - step1_6 + step1_7) * cospi_16_64; - */ - "sub %[Temp0], %[step1_7], %[step1_6] \n\t" - "sub %[Temp0], %[Temp0], %[step1_4] \n\t" - "add %[Temp0], %[Temp0], %[step1_5] \n\t" - "sub %[Temp1], %[step1_4], %[step1_5] \n\t" - "sub %[Temp1], %[Temp1], %[step1_6] \n\t" - "add %[Temp1], %[Temp1], %[step1_7] \n\t" - - "mtlo %[const_2_power_13], $ac0 \n\t" - "mthi $zero, $ac0 \n\t" - "mtlo %[const_2_power_13], $ac1 \n\t" - "mthi $zero, $ac1 \n\t" - - "madd $ac0, %[Temp0], %[cospi_16_64] \n\t" - "madd $ac1, %[Temp1], %[cospi_16_64] \n\t" - - /* - step1_4 = step1_4 + step1_5; - step1_7 = step1_6 + step1_7; - */ - "add %[step1_4], %[step1_4], %[step1_5] \n\t" - "add %[step1_7], %[step1_7], %[step1_6] \n\t" - - "extp %[step1_5], $ac0, 31 \n\t" - "extp %[step1_6], $ac1, 31 \n\t" - - /* add block */ - "lbu %[Temp1], 0(%[dest_pix]) \n\t" - "add %[Temp0], %[step1_0], %[step1_7] \n\t" - "addi %[Temp0], %[Temp0], 16 \n\t" - "sra %[Temp0], %[Temp0], 5 \n\t" - "add %[Temp1], %[Temp1], %[Temp0] \n\t" - "add %[Temp0], %[step1_1], %[step1_6] \n\t" - "slt %[Temp2], %[Temp1], %[const_255] \n\t" - "slt %[Temp3], $zero, %[Temp1] \n\t" - "movz %[Temp1], %[const_255], %[Temp2] \n\t" - "movz %[Temp1], $zero, %[Temp3] \n\t" - "sb %[Temp1], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "lbu %[Temp1], 0(%[dest_pix]) \n\t" - "addi %[Temp0], %[Temp0], 16 \n\t" - "sra %[Temp0], %[Temp0], 5 \n\t" - "add %[Temp1], %[Temp1], %[Temp0] \n\t" - "add %[Temp0], %[step1_2], %[step1_5] \n\t" - "slt %[Temp2], %[Temp1], %[const_255] \n\t" - "slt %[Temp3], $zero, %[Temp1] \n\t" - "movz %[Temp1], %[const_255], %[Temp2] \n\t" - "movz %[Temp1], $zero, %[Temp3] \n\t" - "sb %[Temp1], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "lbu %[Temp1], 0(%[dest_pix]) \n\t" - "addi %[Temp0], %[Temp0], 16 \n\t" - "sra %[Temp0], %[Temp0], 5 \n\t" - "add %[Temp1], %[Temp1], %[Temp0] \n\t" - "add %[Temp0], %[step1_3], %[step1_4] \n\t" - "slt %[Temp2], %[Temp1], %[const_255] \n\t" - "slt %[Temp3], $zero, %[Temp1] \n\t" - "movz %[Temp1], %[const_255], %[Temp2] \n\t" - "movz %[Temp1], $zero, %[Temp3] \n\t" - "sb %[Temp1], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "lbu %[Temp1], 0(%[dest_pix]) \n\t" - "addi %[Temp0], %[Temp0], 16 \n\t" - "sra %[Temp0], %[Temp0], 5 \n\t" - "add %[Temp1], %[Temp1], %[Temp0] \n\t" - "sub %[Temp0], %[step1_3], %[step1_4] \n\t" - "slt %[Temp2], %[Temp1], %[const_255] \n\t" - "slt %[Temp3], $zero, %[Temp1] \n\t" - "movz %[Temp1], %[const_255], %[Temp2] \n\t" - "movz %[Temp1], $zero, %[Temp3] \n\t" - "sb %[Temp1], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "lbu %[Temp1], 0(%[dest_pix]) \n\t" - "addi %[Temp0], %[Temp0], 16 \n\t" - "sra %[Temp0], %[Temp0], 5 \n\t" - "add %[Temp1], %[Temp1], %[Temp0] \n\t" - "sub %[Temp0], %[step1_2], %[step1_5] \n\t" - "slt %[Temp2], %[Temp1], %[const_255] \n\t" - "slt %[Temp3], $zero, %[Temp1] \n\t" - "movz %[Temp1], %[const_255], %[Temp2] \n\t" - "movz %[Temp1], $zero, %[Temp3] \n\t" - "sb %[Temp1], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "lbu %[Temp1], 0(%[dest_pix]) \n\t" - "addi %[Temp0], %[Temp0], 16 \n\t" - "sra %[Temp0], %[Temp0], 5 \n\t" - "add %[Temp1], %[Temp1], %[Temp0] \n\t" - "sub %[Temp0], %[step1_1], %[step1_6] \n\t" - "slt %[Temp2], %[Temp1], %[const_255] \n\t" - "slt %[Temp3], $zero, %[Temp1] \n\t" - "movz %[Temp1], %[const_255], %[Temp2] \n\t" - "movz %[Temp1], $zero, %[Temp3] \n\t" - "sb %[Temp1], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "lbu %[Temp1], 0(%[dest_pix]) \n\t" - "addi %[Temp0], %[Temp0], 16 \n\t" - "sra %[Temp0], %[Temp0], 5 \n\t" - "add %[Temp1], %[Temp1], %[Temp0] \n\t" - "sub %[Temp0], %[step1_0], %[step1_7] \n\t" - "slt %[Temp2], %[Temp1], %[const_255] \n\t" - "slt %[Temp3], $zero, %[Temp1] \n\t" - "movz %[Temp1], %[const_255], %[Temp2] \n\t" - "movz %[Temp1], $zero, %[Temp3] \n\t" - "sb %[Temp1], 0(%[dest_pix]) \n\t" - "addu %[dest_pix], %[dest_pix], %[stride] \n\t" - - "lbu %[Temp1], 0(%[dest_pix]) \n\t" - "addi %[Temp0], %[Temp0], 16 \n\t" - "sra %[Temp0], %[Temp0], 5 \n\t" - "add %[Temp1], %[Temp1], %[Temp0] \n\t" - "slt %[Temp2], %[Temp1], %[const_255] \n\t" - "slt %[Temp3], $zero, %[Temp1] \n\t" - "movz %[Temp1], %[const_255], %[Temp2] \n\t" - "movz %[Temp1], $zero, %[Temp3] \n\t" - "sb %[Temp1], 0(%[dest_pix]) \n\t" - - : [step1_0] "=&r"(step1_0), [step1_1] "=&r"(step1_1), - [step1_2] "=&r"(step1_2), [step1_3] "=&r"(step1_3), - [step1_4] "=&r"(step1_4), [step1_5] "=&r"(step1_5), - [step1_6] "=&r"(step1_6), [step1_7] "=&r"(step1_7), - [Temp0] "=&r"(Temp0), [Temp1] "=&r"(Temp1), [Temp2] "=&r"(Temp2), - [Temp3] "=&r"(Temp3), [dest_pix] "+r"(dest_pix) - : [const_2_power_13] "r"(const_2_power_13), [const_255] "r"(const_255), - [cospi_16_64] "r"(cospi_16_64), [cospi_28_64] "r"(cospi_28_64), - [cospi_4_64] "r"(cospi_4_64), [cospi_12_64] "r"(cospi_12_64), - [cospi_20_64] "r"(cospi_20_64), [cospi_8_64] "r"(cospi_8_64), - [cospi_24_64] "r"(cospi_24_64), [input] "r"(input), - [stride] "r"(stride)); - - input += 8; - } -} - -void vpx_idct8x8_64_add_dspr2(const int16_t *input, uint8_t *dest, int stride) { - DECLARE_ALIGNED(32, int16_t, out[8 * 8]); - int16_t *outptr = out; - uint32_t pos = 45; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" : : [pos] "r"(pos)); - - // First transform rows - idct8_rows_dspr2(input, outptr, 8); - - // Then transform columns and add to dest - idct8_columns_add_blk_dspr2(&out[0], dest, stride); -} - -void vpx_idct8x8_12_add_dspr2(const int16_t *input, uint8_t *dest, int stride) { - DECLARE_ALIGNED(32, int16_t, out[8 * 8]); - int16_t *outptr = out; - uint32_t pos = 45; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" : : [pos] "r"(pos)); - - // First transform rows - idct8_rows_dspr2(input, outptr, 4); - - outptr += 4; - - __asm__ __volatile__( - "sw $zero, 0(%[outptr]) \n\t" - "sw $zero, 4(%[outptr]) \n\t" - "sw $zero, 16(%[outptr]) \n\t" - "sw $zero, 20(%[outptr]) \n\t" - "sw $zero, 32(%[outptr]) \n\t" - "sw $zero, 36(%[outptr]) \n\t" - "sw $zero, 48(%[outptr]) \n\t" - "sw $zero, 52(%[outptr]) \n\t" - "sw $zero, 64(%[outptr]) \n\t" - "sw $zero, 68(%[outptr]) \n\t" - "sw $zero, 80(%[outptr]) \n\t" - "sw $zero, 84(%[outptr]) \n\t" - "sw $zero, 96(%[outptr]) \n\t" - "sw $zero, 100(%[outptr]) \n\t" - "sw $zero, 112(%[outptr]) \n\t" - "sw $zero, 116(%[outptr]) \n\t" - - : - : [outptr] "r"(outptr)); - - // Then transform columns and add to dest - idct8_columns_add_blk_dspr2(&out[0], dest, stride); -} - -void vpx_idct8x8_1_add_dspr2(const int16_t *input, uint8_t *dest, int stride) { - uint32_t pos = 45; - int32_t out; - int32_t r; - int32_t a1, absa1; - int32_t t1, t2, vector_a1, vector_1, vector_2; - - /* bit positon for extract from acc */ - __asm__ __volatile__("wrdsp %[pos], 1 \n\t" - - : - : [pos] "r"(pos)); - - out = DCT_CONST_ROUND_SHIFT_TWICE_COSPI_16_64(input[0]); - __asm__ __volatile__( - "addi %[out], %[out], 16 \n\t" - "sra %[a1], %[out], 5 \n\t" - - : [out] "+r"(out), [a1] "=r"(a1) - :); - - if (a1 < 0) { - /* use quad-byte - * input and output memory are four byte aligned */ - __asm__ __volatile__( - "abs %[absa1], %[a1] \n\t" - "replv.qb %[vector_a1], %[absa1] \n\t" - - : [absa1] "=r"(absa1), [vector_a1] "=r"(vector_a1) - : [a1] "r"(a1)); - - for (r = 8; r--;) { - __asm__ __volatile__( - "lw %[t1], 0(%[dest]) \n\t" - "lw %[t2], 4(%[dest]) \n\t" - "subu_s.qb %[vector_1], %[t1], %[vector_a1] \n\t" - "subu_s.qb %[vector_2], %[t2], %[vector_a1] \n\t" - "sw %[vector_1], 0(%[dest]) \n\t" - "sw %[vector_2], 4(%[dest]) \n\t" - "add %[dest], %[dest], %[stride] \n\t" - - : [t1] "=&r"(t1), [t2] "=&r"(t2), [vector_1] "=&r"(vector_1), - [vector_2] "=&r"(vector_2), [dest] "+&r"(dest) - : [stride] "r"(stride), [vector_a1] "r"(vector_a1)); - } - } else if (a1 > 255) { - int32_t a11, a12, vector_a11, vector_a12; - - /* use quad-byte - * input and output memory are four byte aligned */ - a11 = a1 >> 2; - a12 = a1 - (a11 * 3); - - __asm__ __volatile__( - "replv.qb %[vector_a11], %[a11] \n\t" - "replv.qb %[vector_a12], %[a12] \n\t" - - : [vector_a11] "=&r"(vector_a11), [vector_a12] "=&r"(vector_a12) - : [a11] "r"(a11), [a12] "r"(a12)); - - for (r = 8; r--;) { - __asm__ __volatile__( - "lw %[t1], 0(%[dest]) \n\t" - "lw %[t2], 4(%[dest]) \n\t" - "addu_s.qb %[vector_1], %[t1], %[vector_a11] \n\t" - "addu_s.qb %[vector_2], %[t2], %[vector_a11] \n\t" - "addu_s.qb %[vector_1], %[vector_1], %[vector_a11] \n\t" - "addu_s.qb %[vector_2], %[vector_2], %[vector_a11] \n\t" - "addu_s.qb %[vector_1], %[vector_1], %[vector_a11] \n\t" - "addu_s.qb %[vector_2], %[vector_2], %[vector_a11] \n\t" - "addu_s.qb %[vector_1], %[vector_1], %[vector_a12] \n\t" - "addu_s.qb %[vector_2], %[vector_2], %[vector_a12] \n\t" - "sw %[vector_1], 0(%[dest]) \n\t" - "sw %[vector_2], 4(%[dest]) \n\t" - "add %[dest], %[dest], %[stride] \n\t" - - : [t1] "=&r"(t1), [t2] "=&r"(t2), [vector_1] "=&r"(vector_1), - [vector_2] "=&r"(vector_2), [dest] "+r"(dest) - : [stride] "r"(stride), [vector_a11] "r"(vector_a11), - [vector_a12] "r"(vector_a12)); - } - } else { - /* use quad-byte - * input and output memory are four byte aligned */ - __asm__ __volatile__("replv.qb %[vector_a1], %[a1] \n\t" - - : [vector_a1] "=r"(vector_a1) - : [a1] "r"(a1)); - - for (r = 8; r--;) { - __asm__ __volatile__( - "lw %[t1], 0(%[dest]) \n\t" - "lw %[t2], 4(%[dest]) \n\t" - "addu_s.qb %[vector_1], %[t1], %[vector_a1] \n\t" - "addu_s.qb %[vector_2], %[t2], %[vector_a1] \n\t" - "sw %[vector_1], 0(%[dest]) \n\t" - "sw %[vector_2], 4(%[dest]) \n\t" - "add %[dest], %[dest], %[stride] \n\t" - - : [t1] "=&r"(t1), [t2] "=&r"(t2), [vector_1] "=&r"(vector_1), - [vector_2] "=&r"(vector_2), [dest] "+r"(dest) - : [stride] "r"(stride), [vector_a1] "r"(vector_a1)); - } - } -} - -void iadst8_dspr2(const int16_t *input, int16_t *output) { - int s0, s1, s2, s3, s4, s5, s6, s7; - int x0, x1, x2, x3, x4, x5, x6, x7; - - x0 = input[7]; - x1 = input[0]; - x2 = input[5]; - x3 = input[2]; - x4 = input[3]; - x5 = input[4]; - x6 = input[1]; - x7 = input[6]; - - if (!(x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7)) { - output[0] = output[1] = output[2] = output[3] = output[4] = output[5] = - output[6] = output[7] = 0; - return; - } - - // stage 1 - s0 = cospi_2_64 * x0 + cospi_30_64 * x1; - s1 = cospi_30_64 * x0 - cospi_2_64 * x1; - s2 = cospi_10_64 * x2 + cospi_22_64 * x3; - s3 = cospi_22_64 * x2 - cospi_10_64 * x3; - s4 = cospi_18_64 * x4 + cospi_14_64 * x5; - s5 = cospi_14_64 * x4 - cospi_18_64 * x5; - s6 = cospi_26_64 * x6 + cospi_6_64 * x7; - s7 = cospi_6_64 * x6 - cospi_26_64 * x7; - - x0 = ROUND_POWER_OF_TWO((s0 + s4), DCT_CONST_BITS); - x1 = ROUND_POWER_OF_TWO((s1 + s5), DCT_CONST_BITS); - x2 = ROUND_POWER_OF_TWO((s2 + s6), DCT_CONST_BITS); - x3 = ROUND_POWER_OF_TWO((s3 + s7), DCT_CONST_BITS); - x4 = ROUND_POWER_OF_TWO((s0 - s4), DCT_CONST_BITS); - x5 = ROUND_POWER_OF_TWO((s1 - s5), DCT_CONST_BITS); - x6 = ROUND_POWER_OF_TWO((s2 - s6), DCT_CONST_BITS); - x7 = ROUND_POWER_OF_TWO((s3 - s7), DCT_CONST_BITS); - - // stage 2 - s0 = x0; - s1 = x1; - s2 = x2; - s3 = x3; - s4 = cospi_8_64 * x4 + cospi_24_64 * x5; - s5 = cospi_24_64 * x4 - cospi_8_64 * x5; - s6 = -cospi_24_64 * x6 + cospi_8_64 * x7; - s7 = cospi_8_64 * x6 + cospi_24_64 * x7; - - x0 = s0 + s2; - x1 = s1 + s3; - x2 = s0 - s2; - x3 = s1 - s3; - x4 = ROUND_POWER_OF_TWO((s4 + s6), DCT_CONST_BITS); - x5 = ROUND_POWER_OF_TWO((s5 + s7), DCT_CONST_BITS); - x6 = ROUND_POWER_OF_TWO((s4 - s6), DCT_CONST_BITS); - x7 = ROUND_POWER_OF_TWO((s5 - s7), DCT_CONST_BITS); - - // stage 3 - s2 = cospi_16_64 * (x2 + x3); - s3 = cospi_16_64 * (x2 - x3); - s6 = cospi_16_64 * (x6 + x7); - s7 = cospi_16_64 * (x6 - x7); - - x2 = ROUND_POWER_OF_TWO((s2), DCT_CONST_BITS); - x3 = ROUND_POWER_OF_TWO((s3), DCT_CONST_BITS); - x6 = ROUND_POWER_OF_TWO((s6), DCT_CONST_BITS); - x7 = ROUND_POWER_OF_TWO((s7), DCT_CONST_BITS); - - output[0] = x0; - output[1] = -x4; - output[2] = x6; - output[3] = -x2; - output[4] = x3; - output[5] = -x7; - output[6] = x5; - output[7] = -x1; -} -#endif // HAVE_DSPR2 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_16_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_16_msa.c deleted file mode 100644 index b1731f23..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_16_msa.c +++ /dev/null @@ -1,1489 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/loopfilter_msa.h" -#include "vpx_ports/mem.h" - -static int32_t hz_lpf_t4_and_t8_16w(uint8_t *src, int32_t pitch, - uint8_t *filter48, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - v16u8 p2_out, p1_out, p0_out, q0_out, q1_out, q2_out; - v16u8 flat, mask, hev, thresh, b_limit, limit; - v8u16 p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r; - v8u16 p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l; - v8i16 p2_filt8_r, p1_filt8_r, p0_filt8_r, q0_filt8_r, q1_filt8_r, q2_filt8_r; - v8i16 p2_filt8_l, p1_filt8_l, p0_filt8_l, q0_filt8_l, q1_filt8_l, q2_filt8_l; - v16u8 zero = { 0 }; - - /* load vector elements */ - LD_UB8(src - (4 * pitch), pitch, p3, p2, p1, p0, q0, q1, q2, q3); - - thresh = (v16u8)__msa_fill_b(*thresh_ptr); - b_limit = (v16u8)__msa_fill_b(*b_limit_ptr); - limit = (v16u8)__msa_fill_b(*limit_ptr); - - /* mask and hev */ - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); - - if (__msa_test_bz_v(flat)) { - ST_UB4(p1_out, p0_out, q0_out, q1_out, (src - 2 * pitch), pitch); - - return 1; - } else { - ILVR_B8_UH(zero, p3, zero, p2, zero, p1, zero, p0, zero, q0, zero, q1, zero, - q2, zero, q3, p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r); - VP9_FILTER8(p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r, p2_filt8_r, - p1_filt8_r, p0_filt8_r, q0_filt8_r, q1_filt8_r, q2_filt8_r); - - ILVL_B4_UH(zero, p3, zero, p2, zero, p1, zero, p0, p3_l, p2_l, p1_l, p0_l); - ILVL_B4_UH(zero, q0, zero, q1, zero, q2, zero, q3, q0_l, q1_l, q2_l, q3_l); - VP9_FILTER8(p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l, p2_filt8_l, - p1_filt8_l, p0_filt8_l, q0_filt8_l, q1_filt8_l, q2_filt8_l); - - /* convert 16 bit output data into 8 bit */ - PCKEV_B4_SH(p2_filt8_l, p2_filt8_r, p1_filt8_l, p1_filt8_r, p0_filt8_l, - p0_filt8_r, q0_filt8_l, q0_filt8_r, p2_filt8_r, p1_filt8_r, - p0_filt8_r, q0_filt8_r); - PCKEV_B2_SH(q1_filt8_l, q1_filt8_r, q2_filt8_l, q2_filt8_r, q1_filt8_r, - q2_filt8_r); - - /* store pixel values */ - p2_out = __msa_bmnz_v(p2, (v16u8)p2_filt8_r, flat); - p1_out = __msa_bmnz_v(p1_out, (v16u8)p1_filt8_r, flat); - p0_out = __msa_bmnz_v(p0_out, (v16u8)p0_filt8_r, flat); - q0_out = __msa_bmnz_v(q0_out, (v16u8)q0_filt8_r, flat); - q1_out = __msa_bmnz_v(q1_out, (v16u8)q1_filt8_r, flat); - q2_out = __msa_bmnz_v(q2, (v16u8)q2_filt8_r, flat); - - ST_UB4(p2_out, p1_out, p0_out, q0_out, filter48, 16); - filter48 += (4 * 16); - ST_UB2(q1_out, q2_out, filter48, 16); - filter48 += (2 * 16); - ST_UB(flat, filter48); - - return 0; - } -} - -static void hz_lpf_t16_16w(uint8_t *src, int32_t pitch, uint8_t *filter48) { - v16u8 flat, flat2, filter8; - v16i8 zero = { 0 }; - v16u8 p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7; - v8u16 p7_r_in, p6_r_in, p5_r_in, p4_r_in, p3_r_in, p2_r_in, p1_r_in, p0_r_in; - v8u16 q7_r_in, q6_r_in, q5_r_in, q4_r_in, q3_r_in, q2_r_in, q1_r_in, q0_r_in; - v8u16 p7_l_in, p6_l_in, p5_l_in, p4_l_in, p3_l_in, p2_l_in, p1_l_in, p0_l_in; - v8u16 q7_l_in, q6_l_in, q5_l_in, q4_l_in, q3_l_in, q2_l_in, q1_l_in, q0_l_in; - v8u16 tmp0_r, tmp1_r, tmp0_l, tmp1_l; - v8i16 l_out, r_out; - - flat = LD_UB(filter48 + 96); - - LD_UB8((src - 8 * pitch), pitch, p7, p6, p5, p4, p3, p2, p1, p0); - LD_UB8(src, pitch, q0, q1, q2, q3, q4, q5, q6, q7); - VP9_FLAT5(p7, p6, p5, p4, p0, q0, q4, q5, q6, q7, flat, flat2); - - if (__msa_test_bz_v(flat2)) { - LD_UB4(filter48, 16, p2, p1, p0, q0); - LD_UB2(filter48 + 4 * 16, 16, q1, q2); - - src -= 3 * pitch; - ST_UB4(p2, p1, p0, q0, src, pitch); - src += (4 * pitch); - ST_UB2(q1, q2, src, pitch); - } else { - src -= 7 * pitch; - - ILVR_B8_UH(zero, p7, zero, p6, zero, p5, zero, p4, zero, p3, zero, p2, zero, - p1, zero, p0, p7_r_in, p6_r_in, p5_r_in, p4_r_in, p3_r_in, - p2_r_in, p1_r_in, p0_r_in); - - q0_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q0); - - tmp0_r = p7_r_in << 3; - tmp0_r -= p7_r_in; - tmp0_r += p6_r_in; - tmp0_r += q0_r_in; - tmp1_r = p6_r_in + p5_r_in; - tmp1_r += p4_r_in; - tmp1_r += p3_r_in; - tmp1_r += p2_r_in; - tmp1_r += p1_r_in; - tmp1_r += p0_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - - ILVL_B4_UH(zero, p7, zero, p6, zero, p5, zero, p4, p7_l_in, p6_l_in, - p5_l_in, p4_l_in); - ILVL_B4_UH(zero, p3, zero, p2, zero, p1, zero, p0, p3_l_in, p2_l_in, - p1_l_in, p0_l_in); - q0_l_in = (v8u16)__msa_ilvl_b(zero, (v16i8)q0); - - tmp0_l = p7_l_in << 3; - tmp0_l -= p7_l_in; - tmp0_l += p6_l_in; - tmp0_l += q0_l_in; - tmp1_l = p6_l_in + p5_l_in; - tmp1_l += p4_l_in; - tmp1_l += p3_l_in; - tmp1_l += p2_l_in; - tmp1_l += p1_l_in; - tmp1_l += p0_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - p6 = __msa_bmnz_v(p6, (v16u8)r_out, flat2); - ST_UB(p6, src); - src += pitch; - - /* p5 */ - q1_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q1); - tmp0_r = p5_r_in - p6_r_in; - tmp0_r += q1_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - - q1_l_in = (v8u16)__msa_ilvl_b(zero, (v16i8)q1); - tmp0_l = p5_l_in - p6_l_in; - tmp0_l += q1_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - p5 = __msa_bmnz_v(p5, (v16u8)r_out, flat2); - ST_UB(p5, src); - src += pitch; - - /* p4 */ - q2_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q2); - tmp0_r = p4_r_in - p5_r_in; - tmp0_r += q2_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = (v8i16)__msa_srari_h((v8i16)tmp1_r, 4); - - q2_l_in = (v8u16)__msa_ilvl_b(zero, (v16i8)q2); - tmp0_l = p4_l_in - p5_l_in; - tmp0_l += q2_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - p4 = __msa_bmnz_v(p4, (v16u8)r_out, flat2); - ST_UB(p4, src); - src += pitch; - - /* p3 */ - q3_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q3); - tmp0_r = p3_r_in - p4_r_in; - tmp0_r += q3_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - - q3_l_in = (v8u16)__msa_ilvl_b(zero, (v16i8)q3); - tmp0_l = p3_l_in - p4_l_in; - tmp0_l += q3_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - p3 = __msa_bmnz_v(p3, (v16u8)r_out, flat2); - ST_UB(p3, src); - src += pitch; - - /* p2 */ - q4_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q4); - filter8 = LD_UB(filter48); - tmp0_r = p2_r_in - p3_r_in; - tmp0_r += q4_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - - q4_l_in = (v8u16)__msa_ilvl_b(zero, (v16i8)q4); - tmp0_l = p2_l_in - p3_l_in; - tmp0_l += q4_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST_UB(filter8, src); - src += pitch; - - /* p1 */ - q5_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q5); - filter8 = LD_UB(filter48 + 16); - tmp0_r = p1_r_in - p2_r_in; - tmp0_r += q5_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - - q5_l_in = (v8u16)__msa_ilvl_b(zero, (v16i8)q5); - tmp0_l = p1_l_in - p2_l_in; - tmp0_l += q5_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST_UB(filter8, src); - src += pitch; - - /* p0 */ - q6_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q6); - filter8 = LD_UB(filter48 + 32); - tmp0_r = p0_r_in - p1_r_in; - tmp0_r += q6_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - - q6_l_in = (v8u16)__msa_ilvl_b(zero, (v16i8)q6); - tmp0_l = p0_l_in - p1_l_in; - tmp0_l += q6_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST_UB(filter8, src); - src += pitch; - - /* q0 */ - q7_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q7); - filter8 = LD_UB(filter48 + 48); - tmp0_r = q7_r_in - p0_r_in; - tmp0_r += q0_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - - q7_l_in = (v8u16)__msa_ilvl_b(zero, (v16i8)q7); - tmp0_l = q7_l_in - p0_l_in; - tmp0_l += q0_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST_UB(filter8, src); - src += pitch; - - /* q1 */ - filter8 = LD_UB(filter48 + 64); - tmp0_r = q7_r_in - q0_r_in; - tmp0_r += q1_r_in; - tmp0_r -= p6_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - - tmp0_l = q7_l_in - q0_l_in; - tmp0_l += q1_l_in; - tmp0_l -= p6_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST_UB(filter8, src); - src += pitch; - - /* q2 */ - filter8 = LD_UB(filter48 + 80); - tmp0_r = q7_r_in - q1_r_in; - tmp0_r += q2_r_in; - tmp0_r -= p5_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - - tmp0_l = q7_l_in - q1_l_in; - tmp0_l += q2_l_in; - tmp0_l -= p5_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST_UB(filter8, src); - src += pitch; - - /* q3 */ - tmp0_r = q7_r_in - q2_r_in; - tmp0_r += q3_r_in; - tmp0_r -= p4_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - - tmp0_l = q7_l_in - q2_l_in; - tmp0_l += q3_l_in; - tmp0_l -= p4_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - q3 = __msa_bmnz_v(q3, (v16u8)r_out, flat2); - ST_UB(q3, src); - src += pitch; - - /* q4 */ - tmp0_r = q7_r_in - q3_r_in; - tmp0_r += q4_r_in; - tmp0_r -= p3_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - - tmp0_l = q7_l_in - q3_l_in; - tmp0_l += q4_l_in; - tmp0_l -= p3_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - q4 = __msa_bmnz_v(q4, (v16u8)r_out, flat2); - ST_UB(q4, src); - src += pitch; - - /* q5 */ - tmp0_r = q7_r_in - q4_r_in; - tmp0_r += q5_r_in; - tmp0_r -= p2_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - - tmp0_l = q7_l_in - q4_l_in; - tmp0_l += q5_l_in; - tmp0_l -= p2_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - q5 = __msa_bmnz_v(q5, (v16u8)r_out, flat2); - ST_UB(q5, src); - src += pitch; - - /* q6 */ - tmp0_r = q7_r_in - q5_r_in; - tmp0_r += q6_r_in; - tmp0_r -= p1_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - - tmp0_l = q7_l_in - q5_l_in; - tmp0_l += q6_l_in; - tmp0_l -= p1_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - q6 = __msa_bmnz_v(q6, (v16u8)r_out, flat2); - ST_UB(q6, src); - } -} - -static void mb_lpf_horizontal_edge_dual(uint8_t *src, int32_t pitch, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr, - int32_t count) { - DECLARE_ALIGNED(32, uint8_t, filter48[16 * 8]); - uint8_t early_exit = 0; - - (void)count; - - early_exit = hz_lpf_t4_and_t8_16w(src, pitch, &filter48[0], b_limit_ptr, - limit_ptr, thresh_ptr); - - if (0 == early_exit) { - hz_lpf_t16_16w(src, pitch, filter48); - } -} - -static void mb_lpf_horizontal_edge(uint8_t *src, int32_t pitch, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr, int32_t count) { - if (1 == count) { - uint64_t p2_d, p1_d, p0_d, q0_d, q1_d, q2_d; - uint64_t dword0, dword1; - v16u8 flat2, mask, hev, flat, thresh, b_limit, limit; - v16u8 p3, p2, p1, p0, q3, q2, q1, q0, p7, p6, p5, p4, q4, q5, q6, q7; - v16u8 p2_out, p1_out, p0_out, q0_out, q1_out, q2_out; - v16u8 p0_filter16, p1_filter16; - v8i16 p2_filter8, p1_filter8, p0_filter8; - v8i16 q0_filter8, q1_filter8, q2_filter8; - v8u16 p7_r, p6_r, p5_r, p4_r, q7_r, q6_r, q5_r, q4_r; - v8u16 p3_r, p2_r, p1_r, p0_r, q3_r, q2_r, q1_r, q0_r; - v16i8 zero = { 0 }; - v8u16 tmp0, tmp1, tmp2; - - /* load vector elements */ - LD_UB8((src - 4 * pitch), pitch, p3, p2, p1, p0, q0, q1, q2, q3); - - thresh = (v16u8)__msa_fill_b(*thresh_ptr); - b_limit = (v16u8)__msa_fill_b(*b_limit_ptr); - limit = (v16u8)__msa_fill_b(*limit_ptr); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, - q1_out); - - flat = (v16u8)__msa_ilvr_d((v2i64)zero, (v2i64)flat); - - if (__msa_test_bz_v(flat)) { - p1_d = __msa_copy_u_d((v2i64)p1_out, 0); - p0_d = __msa_copy_u_d((v2i64)p0_out, 0); - q0_d = __msa_copy_u_d((v2i64)q0_out, 0); - q1_d = __msa_copy_u_d((v2i64)q1_out, 0); - SD4(p1_d, p0_d, q0_d, q1_d, src - 2 * pitch, pitch); - } else { - /* convert 8 bit input data into 16 bit */ - ILVR_B8_UH(zero, p3, zero, p2, zero, p1, zero, p0, zero, q0, zero, q1, - zero, q2, zero, q3, p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, - q3_r); - VP9_FILTER8(p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r, p2_filter8, - p1_filter8, p0_filter8, q0_filter8, q1_filter8, q2_filter8); - - /* convert 16 bit output data into 8 bit */ - PCKEV_B4_SH(zero, p2_filter8, zero, p1_filter8, zero, p0_filter8, zero, - q0_filter8, p2_filter8, p1_filter8, p0_filter8, q0_filter8); - PCKEV_B2_SH(zero, q1_filter8, zero, q2_filter8, q1_filter8, q2_filter8); - - /* store pixel values */ - p2_out = __msa_bmnz_v(p2, (v16u8)p2_filter8, flat); - p1_out = __msa_bmnz_v(p1_out, (v16u8)p1_filter8, flat); - p0_out = __msa_bmnz_v(p0_out, (v16u8)p0_filter8, flat); - q0_out = __msa_bmnz_v(q0_out, (v16u8)q0_filter8, flat); - q1_out = __msa_bmnz_v(q1_out, (v16u8)q1_filter8, flat); - q2_out = __msa_bmnz_v(q2, (v16u8)q2_filter8, flat); - - /* load 16 vector elements */ - LD_UB4((src - 8 * pitch), pitch, p7, p6, p5, p4); - LD_UB4(src + (4 * pitch), pitch, q4, q5, q6, q7); - - VP9_FLAT5(p7, p6, p5, p4, p0, q0, q4, q5, q6, q7, flat, flat2); - - if (__msa_test_bz_v(flat2)) { - p2_d = __msa_copy_u_d((v2i64)p2_out, 0); - p1_d = __msa_copy_u_d((v2i64)p1_out, 0); - p0_d = __msa_copy_u_d((v2i64)p0_out, 0); - q0_d = __msa_copy_u_d((v2i64)q0_out, 0); - q1_d = __msa_copy_u_d((v2i64)q1_out, 0); - q2_d = __msa_copy_u_d((v2i64)q2_out, 0); - - SD4(p2_d, p1_d, p0_d, q0_d, src - 3 * pitch, pitch); - SD(q1_d, src + pitch); - SD(q2_d, src + 2 * pitch); - } else { - /* LSB(right) 8 pixel operation */ - ILVR_B8_UH(zero, p7, zero, p6, zero, p5, zero, p4, zero, q4, zero, q5, - zero, q6, zero, q7, p7_r, p6_r, p5_r, p4_r, q4_r, q5_r, q6_r, - q7_r); - - tmp0 = p7_r << 3; - tmp0 -= p7_r; - tmp0 += p6_r; - tmp0 += q0_r; - - src -= 7 * pitch; - - /* calculation of p6 and p5 */ - tmp1 = p6_r + p5_r + p4_r + p3_r; - tmp1 += (p2_r + p1_r + p0_r); - tmp1 += tmp0; - p0_filter16 = (v16u8)__msa_srari_h((v8i16)tmp1, 4); - tmp0 = p5_r - p6_r + q1_r - p7_r; - tmp1 += tmp0; - p1_filter16 = (v16u8)__msa_srari_h((v8i16)tmp1, 4); - PCKEV_B2_UB(zero, p0_filter16, zero, p1_filter16, p0_filter16, - p1_filter16); - p0_filter16 = __msa_bmnz_v(p6, p0_filter16, flat2); - p1_filter16 = __msa_bmnz_v(p5, p1_filter16, flat2); - dword0 = __msa_copy_u_d((v2i64)p0_filter16, 0); - dword1 = __msa_copy_u_d((v2i64)p1_filter16, 0); - SD(dword0, src); - src += pitch; - SD(dword1, src); - src += pitch; - - /* calculation of p4 and p3 */ - tmp0 = p4_r - p5_r + q2_r - p7_r; - tmp2 = p3_r - p4_r + q3_r - p7_r; - tmp1 += tmp0; - p0_filter16 = (v16u8)__msa_srari_h((v8i16)tmp1, 4); - tmp1 += tmp2; - p1_filter16 = (v16u8)__msa_srari_h((v8i16)tmp1, 4); - PCKEV_B2_UB(zero, p0_filter16, zero, p1_filter16, p0_filter16, - p1_filter16); - p0_filter16 = __msa_bmnz_v(p4, p0_filter16, flat2); - p1_filter16 = __msa_bmnz_v(p3, p1_filter16, flat2); - dword0 = __msa_copy_u_d((v2i64)p0_filter16, 0); - dword1 = __msa_copy_u_d((v2i64)p1_filter16, 0); - SD(dword0, src); - src += pitch; - SD(dword1, src); - src += pitch; - - /* calculation of p2 and p1 */ - tmp0 = p2_r - p3_r + q4_r - p7_r; - tmp2 = p1_r - p2_r + q5_r - p7_r; - tmp1 += tmp0; - p0_filter16 = (v16u8)__msa_srari_h((v8i16)tmp1, 4); - tmp1 += tmp2; - p1_filter16 = (v16u8)__msa_srari_h((v8i16)tmp1, 4); - PCKEV_B2_UB(zero, p0_filter16, zero, p1_filter16, p0_filter16, - p1_filter16); - p0_filter16 = __msa_bmnz_v(p2_out, p0_filter16, flat2); - p1_filter16 = __msa_bmnz_v(p1_out, p1_filter16, flat2); - dword0 = __msa_copy_u_d((v2i64)p0_filter16, 0); - dword1 = __msa_copy_u_d((v2i64)p1_filter16, 0); - SD(dword0, src); - src += pitch; - SD(dword1, src); - src += pitch; - - /* calculation of p0 and q0 */ - tmp0 = (p0_r - p1_r) + (q6_r - p7_r); - tmp2 = (q7_r - p0_r) + (q0_r - p7_r); - tmp1 += tmp0; - p0_filter16 = (v16u8)__msa_srari_h((v8i16)tmp1, 4); - tmp1 += tmp2; - p1_filter16 = (v16u8)__msa_srari_h((v8i16)tmp1, 4); - PCKEV_B2_UB(zero, p0_filter16, zero, p1_filter16, p0_filter16, - p1_filter16); - p0_filter16 = __msa_bmnz_v(p0_out, p0_filter16, flat2); - p1_filter16 = __msa_bmnz_v(q0_out, p1_filter16, flat2); - dword0 = __msa_copy_u_d((v2i64)p0_filter16, 0); - dword1 = __msa_copy_u_d((v2i64)p1_filter16, 0); - SD(dword0, src); - src += pitch; - SD(dword1, src); - src += pitch; - - /* calculation of q1 and q2 */ - tmp0 = q7_r - q0_r + q1_r - p6_r; - tmp2 = q7_r - q1_r + q2_r - p5_r; - tmp1 += tmp0; - p0_filter16 = (v16u8)__msa_srari_h((v8i16)tmp1, 4); - tmp1 += tmp2; - p1_filter16 = (v16u8)__msa_srari_h((v8i16)tmp1, 4); - PCKEV_B2_UB(zero, p0_filter16, zero, p1_filter16, p0_filter16, - p1_filter16); - p0_filter16 = __msa_bmnz_v(q1_out, p0_filter16, flat2); - p1_filter16 = __msa_bmnz_v(q2_out, p1_filter16, flat2); - dword0 = __msa_copy_u_d((v2i64)p0_filter16, 0); - dword1 = __msa_copy_u_d((v2i64)p1_filter16, 0); - SD(dword0, src); - src += pitch; - SD(dword1, src); - src += pitch; - - /* calculation of q3 and q4 */ - tmp0 = (q7_r - q2_r) + (q3_r - p4_r); - tmp2 = (q7_r - q3_r) + (q4_r - p3_r); - tmp1 += tmp0; - p0_filter16 = (v16u8)__msa_srari_h((v8i16)tmp1, 4); - tmp1 += tmp2; - p1_filter16 = (v16u8)__msa_srari_h((v8i16)tmp1, 4); - PCKEV_B2_UB(zero, p0_filter16, zero, p1_filter16, p0_filter16, - p1_filter16); - p0_filter16 = __msa_bmnz_v(q3, p0_filter16, flat2); - p1_filter16 = __msa_bmnz_v(q4, p1_filter16, flat2); - dword0 = __msa_copy_u_d((v2i64)p0_filter16, 0); - dword1 = __msa_copy_u_d((v2i64)p1_filter16, 0); - SD(dword0, src); - src += pitch; - SD(dword1, src); - src += pitch; - - /* calculation of q5 and q6 */ - tmp0 = (q7_r - q4_r) + (q5_r - p2_r); - tmp2 = (q7_r - q5_r) + (q6_r - p1_r); - tmp1 += tmp0; - p0_filter16 = (v16u8)__msa_srari_h((v8i16)tmp1, 4); - tmp1 += tmp2; - p1_filter16 = (v16u8)__msa_srari_h((v8i16)tmp1, 4); - PCKEV_B2_UB(zero, p0_filter16, zero, p1_filter16, p0_filter16, - p1_filter16); - p0_filter16 = __msa_bmnz_v(q5, p0_filter16, flat2); - p1_filter16 = __msa_bmnz_v(q6, p1_filter16, flat2); - dword0 = __msa_copy_u_d((v2i64)p0_filter16, 0); - dword1 = __msa_copy_u_d((v2i64)p1_filter16, 0); - SD(dword0, src); - src += pitch; - SD(dword1, src); - } - } - } else { - mb_lpf_horizontal_edge_dual(src, pitch, b_limit_ptr, limit_ptr, thresh_ptr, - count); - } -} - -void vpx_lpf_horizontal_16_msa(uint8_t *src, int32_t pitch, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - mb_lpf_horizontal_edge(src, pitch, b_limit_ptr, limit_ptr, thresh_ptr, 1); -} - -void vpx_lpf_horizontal_16_dual_msa(uint8_t *src, int32_t pitch, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - mb_lpf_horizontal_edge(src, pitch, b_limit_ptr, limit_ptr, thresh_ptr, 2); -} - -static void transpose_16x8_to_8x16(uint8_t *input, int32_t in_pitch, - uint8_t *output, int32_t out_pitch) { - v16u8 p7_org, p6_org, p5_org, p4_org, p3_org, p2_org, p1_org, p0_org; - v16i8 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - v16u8 p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7; - - LD_UB8(input, in_pitch, p7_org, p6_org, p5_org, p4_org, p3_org, p2_org, - p1_org, p0_org); - /* 8x8 transpose */ - TRANSPOSE8x8_UB_UB(p7_org, p6_org, p5_org, p4_org, p3_org, p2_org, p1_org, - p0_org, p7, p6, p5, p4, p3, p2, p1, p0); - /* 8x8 transpose */ - ILVL_B4_SB(p5_org, p7_org, p4_org, p6_org, p1_org, p3_org, p0_org, p2_org, - tmp0, tmp1, tmp2, tmp3); - ILVR_B2_SB(tmp1, tmp0, tmp3, tmp2, tmp4, tmp6); - ILVL_B2_SB(tmp1, tmp0, tmp3, tmp2, tmp5, tmp7); - ILVR_W2_UB(tmp6, tmp4, tmp7, tmp5, q0, q4); - ILVL_W2_UB(tmp6, tmp4, tmp7, tmp5, q2, q6); - SLDI_B4_0_UB(q0, q2, q4, q6, q1, q3, q5, q7, 8); - - ST_UB8(p7, p6, p5, p4, p3, p2, p1, p0, output, out_pitch); - output += (8 * out_pitch); - ST_UB8(q0, q1, q2, q3, q4, q5, q6, q7, output, out_pitch); -} - -static void transpose_8x16_to_16x8(uint8_t *input, int32_t in_pitch, - uint8_t *output, int32_t out_pitch) { - v16u8 p7_o, p6_o, p5_o, p4_o, p3_o, p2_o, p1_o, p0_o; - v16u8 p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7; - - LD_UB8(input, in_pitch, p7, p6, p5, p4, p3, p2, p1, p0); - LD_UB8(input + (8 * in_pitch), in_pitch, q0, q1, q2, q3, q4, q5, q6, q7); - TRANSPOSE16x8_UB_UB(p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, - q6, q7, p7_o, p6_o, p5_o, p4_o, p3_o, p2_o, p1_o, p0_o); - ST_UB8(p7_o, p6_o, p5_o, p4_o, p3_o, p2_o, p1_o, p0_o, output, out_pitch); -} - -static void transpose_16x16(uint8_t *input, int32_t in_pitch, uint8_t *output, - int32_t out_pitch) { - v16u8 row0, row1, row2, row3, row4, row5, row6, row7; - v16u8 row8, row9, row10, row11, row12, row13, row14, row15; - v16u8 p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7; - v8i16 tmp0, tmp1, tmp4, tmp5, tmp6, tmp7; - v4i32 tmp2, tmp3; - - LD_UB8(input, in_pitch, row0, row1, row2, row3, row4, row5, row6, row7); - input += (8 * in_pitch); - LD_UB8(input, in_pitch, row8, row9, row10, row11, row12, row13, row14, row15); - - TRANSPOSE16x8_UB_UB(row0, row1, row2, row3, row4, row5, row6, row7, row8, - row9, row10, row11, row12, row13, row14, row15, p7, p6, - p5, p4, p3, p2, p1, p0); - - /* transpose 16x8 matrix into 8x16 */ - /* total 8 intermediate register and 32 instructions */ - q7 = (v16u8)__msa_ilvod_d((v2i64)row8, (v2i64)row0); - q6 = (v16u8)__msa_ilvod_d((v2i64)row9, (v2i64)row1); - q5 = (v16u8)__msa_ilvod_d((v2i64)row10, (v2i64)row2); - q4 = (v16u8)__msa_ilvod_d((v2i64)row11, (v2i64)row3); - q3 = (v16u8)__msa_ilvod_d((v2i64)row12, (v2i64)row4); - q2 = (v16u8)__msa_ilvod_d((v2i64)row13, (v2i64)row5); - q1 = (v16u8)__msa_ilvod_d((v2i64)row14, (v2i64)row6); - q0 = (v16u8)__msa_ilvod_d((v2i64)row15, (v2i64)row7); - - ILVEV_B2_SH(q7, q6, q5, q4, tmp0, tmp1); - tmp4 = (v8i16)__msa_ilvod_b((v16i8)q6, (v16i8)q7); - tmp5 = (v8i16)__msa_ilvod_b((v16i8)q4, (v16i8)q5); - - ILVEV_B2_UB(q3, q2, q1, q0, q5, q7); - tmp6 = (v8i16)__msa_ilvod_b((v16i8)q2, (v16i8)q3); - tmp7 = (v8i16)__msa_ilvod_b((v16i8)q0, (v16i8)q1); - - ILVEV_H2_SW(tmp0, tmp1, q5, q7, tmp2, tmp3); - q0 = (v16u8)__msa_ilvev_w(tmp3, tmp2); - q4 = (v16u8)__msa_ilvod_w(tmp3, tmp2); - - tmp2 = (v4i32)__msa_ilvod_h(tmp1, tmp0); - tmp3 = (v4i32)__msa_ilvod_h((v8i16)q7, (v8i16)q5); - q2 = (v16u8)__msa_ilvev_w(tmp3, tmp2); - q6 = (v16u8)__msa_ilvod_w(tmp3, tmp2); - - ILVEV_H2_SW(tmp4, tmp5, tmp6, tmp7, tmp2, tmp3); - q1 = (v16u8)__msa_ilvev_w(tmp3, tmp2); - q5 = (v16u8)__msa_ilvod_w(tmp3, tmp2); - - tmp2 = (v4i32)__msa_ilvod_h(tmp5, tmp4); - tmp3 = (v4i32)__msa_ilvod_h(tmp7, tmp6); - q3 = (v16u8)__msa_ilvev_w(tmp3, tmp2); - q7 = (v16u8)__msa_ilvod_w(tmp3, tmp2); - - ST_UB8(p7, p6, p5, p4, p3, p2, p1, p0, output, out_pitch); - output += (8 * out_pitch); - ST_UB8(q0, q1, q2, q3, q4, q5, q6, q7, output, out_pitch); -} - -static int32_t vt_lpf_t4_and_t8_8w(uint8_t *src, uint8_t *filter48, - uint8_t *src_org, int32_t pitch_org, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - v16u8 p2_out, p1_out, p0_out, q0_out, q1_out, q2_out; - v16u8 flat, mask, hev, thresh, b_limit, limit; - v8u16 p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r; - v8i16 p2_filt8_r, p1_filt8_r, p0_filt8_r, q0_filt8_r, q1_filt8_r, q2_filt8_r; - v16i8 zero = { 0 }; - v8i16 vec0, vec1, vec2, vec3; - - /* load vector elements */ - LD_UB8(src - (4 * 16), 16, p3, p2, p1, p0, q0, q1, q2, q3); - - thresh = (v16u8)__msa_fill_b(*thresh_ptr); - b_limit = (v16u8)__msa_fill_b(*b_limit_ptr); - limit = (v16u8)__msa_fill_b(*limit_ptr); - - /* mask and hev */ - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - /* flat4 */ - VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); - /* filter4 */ - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); - - flat = (v16u8)__msa_ilvr_d((v2i64)zero, (v2i64)flat); - - if (__msa_test_bz_v(flat)) { - ILVR_B2_SH(p0_out, p1_out, q1_out, q0_out, vec0, vec1); - ILVRL_H2_SH(vec1, vec0, vec2, vec3); - ST4x8_UB(vec2, vec3, (src_org - 2), pitch_org); - return 1; - } else { - ILVR_B8_UH(zero, p3, zero, p2, zero, p1, zero, p0, zero, q0, zero, q1, zero, - q2, zero, q3, p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r); - VP9_FILTER8(p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r, p2_filt8_r, - p1_filt8_r, p0_filt8_r, q0_filt8_r, q1_filt8_r, q2_filt8_r); - - /* convert 16 bit output data into 8 bit */ - p2_r = (v8u16)__msa_pckev_b((v16i8)p2_filt8_r, (v16i8)p2_filt8_r); - p1_r = (v8u16)__msa_pckev_b((v16i8)p1_filt8_r, (v16i8)p1_filt8_r); - p0_r = (v8u16)__msa_pckev_b((v16i8)p0_filt8_r, (v16i8)p0_filt8_r); - q0_r = (v8u16)__msa_pckev_b((v16i8)q0_filt8_r, (v16i8)q0_filt8_r); - q1_r = (v8u16)__msa_pckev_b((v16i8)q1_filt8_r, (v16i8)q1_filt8_r); - q2_r = (v8u16)__msa_pckev_b((v16i8)q2_filt8_r, (v16i8)q2_filt8_r); - - /* store pixel values */ - p2_out = __msa_bmnz_v(p2, (v16u8)p2_r, flat); - p1_out = __msa_bmnz_v(p1_out, (v16u8)p1_r, flat); - p0_out = __msa_bmnz_v(p0_out, (v16u8)p0_r, flat); - q0_out = __msa_bmnz_v(q0_out, (v16u8)q0_r, flat); - q1_out = __msa_bmnz_v(q1_out, (v16u8)q1_r, flat); - q2_out = __msa_bmnz_v(q2, (v16u8)q2_r, flat); - - ST_UB4(p2_out, p1_out, p0_out, q0_out, filter48, 16); - filter48 += (4 * 16); - ST_UB2(q1_out, q2_out, filter48, 16); - filter48 += (2 * 16); - ST_UB(flat, filter48); - - return 0; - } -} - -static int32_t vt_lpf_t16_8w(uint8_t *src, uint8_t *src_org, int32_t pitch, - uint8_t *filter48) { - v16i8 zero = { 0 }; - v16u8 filter8, flat, flat2; - v16u8 p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7; - v8u16 p7_r_in, p6_r_in, p5_r_in, p4_r_in, p3_r_in, p2_r_in, p1_r_in, p0_r_in; - v8u16 q7_r_in, q6_r_in, q5_r_in, q4_r_in, q3_r_in, q2_r_in, q1_r_in, q0_r_in; - v8u16 tmp0_r, tmp1_r; - v8i16 r_out; - - flat = LD_UB(filter48 + 6 * 16); - - LD_UB8((src - 8 * 16), 16, p7, p6, p5, p4, p3, p2, p1, p0); - LD_UB8(src, 16, q0, q1, q2, q3, q4, q5, q6, q7); - - VP9_FLAT5(p7, p6, p5, p4, p0, q0, q4, q5, q6, q7, flat, flat2); - - if (__msa_test_bz_v(flat2)) { - v8i16 vec0, vec1, vec2, vec3, vec4; - - LD_UB4(filter48, 16, p2, p1, p0, q0); - LD_UB2(filter48 + 4 * 16, 16, q1, q2); - - ILVR_B2_SH(p1, p2, q0, p0, vec0, vec1); - ILVRL_H2_SH(vec1, vec0, vec3, vec4); - vec2 = (v8i16)__msa_ilvr_b((v16i8)q2, (v16i8)q1); - - src_org -= 3; - ST4x4_UB(vec3, vec3, 0, 1, 2, 3, src_org, pitch); - ST2x4_UB(vec2, 0, (src_org + 4), pitch); - src_org += (4 * pitch); - ST4x4_UB(vec4, vec4, 0, 1, 2, 3, src_org, pitch); - ST2x4_UB(vec2, 4, (src_org + 4), pitch); - - return 1; - } else { - src -= 7 * 16; - - ILVR_B8_UH(zero, p7, zero, p6, zero, p5, zero, p4, zero, p3, zero, p2, zero, - p1, zero, p0, p7_r_in, p6_r_in, p5_r_in, p4_r_in, p3_r_in, - p2_r_in, p1_r_in, p0_r_in); - q0_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q0); - - tmp0_r = p7_r_in << 3; - tmp0_r -= p7_r_in; - tmp0_r += p6_r_in; - tmp0_r += q0_r_in; - tmp1_r = p6_r_in + p5_r_in; - tmp1_r += p4_r_in; - tmp1_r += p3_r_in; - tmp1_r += p2_r_in; - tmp1_r += p1_r_in; - tmp1_r += p0_r_in; - tmp1_r += tmp0_r; - - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)r_out, (v16i8)r_out); - p6 = __msa_bmnz_v(p6, (v16u8)r_out, flat2); - ST8x1_UB(p6, src); - src += 16; - - /* p5 */ - q1_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q1); - tmp0_r = p5_r_in - p6_r_in; - tmp0_r += q1_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)r_out, (v16i8)r_out); - p5 = __msa_bmnz_v(p5, (v16u8)r_out, flat2); - ST8x1_UB(p5, src); - src += 16; - - /* p4 */ - q2_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q2); - tmp0_r = p4_r_in - p5_r_in; - tmp0_r += q2_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)r_out, (v16i8)r_out); - p4 = __msa_bmnz_v(p4, (v16u8)r_out, flat2); - ST8x1_UB(p4, src); - src += 16; - - /* p3 */ - q3_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q3); - tmp0_r = p3_r_in - p4_r_in; - tmp0_r += q3_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)r_out, (v16i8)r_out); - p3 = __msa_bmnz_v(p3, (v16u8)r_out, flat2); - ST8x1_UB(p3, src); - src += 16; - - /* p2 */ - q4_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q4); - filter8 = LD_UB(filter48); - tmp0_r = p2_r_in - p3_r_in; - tmp0_r += q4_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)r_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST8x1_UB(filter8, src); - src += 16; - - /* p1 */ - q5_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q5); - filter8 = LD_UB(filter48 + 16); - tmp0_r = p1_r_in - p2_r_in; - tmp0_r += q5_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)r_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST8x1_UB(filter8, src); - src += 16; - - /* p0 */ - q6_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q6); - filter8 = LD_UB(filter48 + 32); - tmp0_r = p0_r_in - p1_r_in; - tmp0_r += q6_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)r_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST8x1_UB(filter8, src); - src += 16; - - /* q0 */ - q7_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q7); - filter8 = LD_UB(filter48 + 48); - tmp0_r = q7_r_in - p0_r_in; - tmp0_r += q0_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)r_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST8x1_UB(filter8, src); - src += 16; - - /* q1 */ - filter8 = LD_UB(filter48 + 64); - tmp0_r = q7_r_in - q0_r_in; - tmp0_r += q1_r_in; - tmp0_r -= p6_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)r_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST8x1_UB(filter8, src); - src += 16; - - /* q2 */ - filter8 = LD_UB(filter48 + 80); - tmp0_r = q7_r_in - q1_r_in; - tmp0_r += q2_r_in; - tmp0_r -= p5_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)r_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST8x1_UB(filter8, src); - src += 16; - - /* q3 */ - tmp0_r = q7_r_in - q2_r_in; - tmp0_r += q3_r_in; - tmp0_r -= p4_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)r_out, (v16i8)r_out); - q3 = __msa_bmnz_v(q3, (v16u8)r_out, flat2); - ST8x1_UB(q3, src); - src += 16; - - /* q4 */ - tmp0_r = q7_r_in - q3_r_in; - tmp0_r += q4_r_in; - tmp0_r -= p3_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)r_out, (v16i8)r_out); - q4 = __msa_bmnz_v(q4, (v16u8)r_out, flat2); - ST8x1_UB(q4, src); - src += 16; - - /* q5 */ - tmp0_r = q7_r_in - q4_r_in; - tmp0_r += q5_r_in; - tmp0_r -= p2_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)r_out, (v16i8)r_out); - q5 = __msa_bmnz_v(q5, (v16u8)r_out, flat2); - ST8x1_UB(q5, src); - src += 16; - - /* q6 */ - tmp0_r = q7_r_in - q5_r_in; - tmp0_r += q6_r_in; - tmp0_r -= p1_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)r_out, (v16i8)r_out); - q6 = __msa_bmnz_v(q6, (v16u8)r_out, flat2); - ST8x1_UB(q6, src); - - return 0; - } -} - -void vpx_lpf_vertical_16_msa(uint8_t *src, int32_t pitch, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - uint8_t early_exit = 0; - DECLARE_ALIGNED(32, uint8_t, transposed_input[16 * 24]); - uint8_t *filter48 = &transposed_input[16 * 16]; - - transpose_16x8_to_8x16(src - 8, pitch, transposed_input, 16); - - early_exit = - vt_lpf_t4_and_t8_8w((transposed_input + 16 * 8), &filter48[0], src, pitch, - b_limit_ptr, limit_ptr, thresh_ptr); - - if (0 == early_exit) { - early_exit = - vt_lpf_t16_8w((transposed_input + 16 * 8), src, pitch, &filter48[0]); - - if (0 == early_exit) { - transpose_8x16_to_16x8(transposed_input, 16, src - 8, pitch); - } - } -} - -static int32_t vt_lpf_t4_and_t8_16w(uint8_t *src, uint8_t *filter48, - uint8_t *src_org, int32_t pitch, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - v16u8 p2_out, p1_out, p0_out, q0_out, q1_out, q2_out; - v16u8 flat, mask, hev, thresh, b_limit, limit; - v8u16 p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r; - v8u16 p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l; - v8i16 p2_filt8_r, p1_filt8_r, p0_filt8_r, q0_filt8_r, q1_filt8_r, q2_filt8_r; - v8i16 p2_filt8_l, p1_filt8_l, p0_filt8_l, q0_filt8_l, q1_filt8_l, q2_filt8_l; - v16i8 zero = { 0 }; - v8i16 vec0, vec1, vec2, vec3, vec4, vec5; - - /* load vector elements */ - LD_UB8(src - (4 * 16), 16, p3, p2, p1, p0, q0, q1, q2, q3); - - thresh = (v16u8)__msa_fill_b(*thresh_ptr); - b_limit = (v16u8)__msa_fill_b(*b_limit_ptr); - limit = (v16u8)__msa_fill_b(*limit_ptr); - - /* mask and hev */ - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - /* flat4 */ - VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); - /* filter4 */ - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); - - if (__msa_test_bz_v(flat)) { - ILVR_B2_SH(p0_out, p1_out, q1_out, q0_out, vec0, vec1); - ILVRL_H2_SH(vec1, vec0, vec2, vec3); - ILVL_B2_SH(p0_out, p1_out, q1_out, q0_out, vec0, vec1); - ILVRL_H2_SH(vec1, vec0, vec4, vec5); - - src_org -= 2; - ST4x8_UB(vec2, vec3, src_org, pitch); - src_org += 8 * pitch; - ST4x8_UB(vec4, vec5, src_org, pitch); - - return 1; - } else { - ILVR_B8_UH(zero, p3, zero, p2, zero, p1, zero, p0, zero, q0, zero, q1, zero, - q2, zero, q3, p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r); - VP9_FILTER8(p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r, p2_filt8_r, - p1_filt8_r, p0_filt8_r, q0_filt8_r, q1_filt8_r, q2_filt8_r); - ILVL_B4_UH(zero, p3, zero, p2, zero, p1, zero, p0, p3_l, p2_l, p1_l, p0_l); - ILVL_B4_UH(zero, q0, zero, q1, zero, q2, zero, q3, q0_l, q1_l, q2_l, q3_l); - VP9_FILTER8(p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l, p2_filt8_l, - p1_filt8_l, p0_filt8_l, q0_filt8_l, q1_filt8_l, q2_filt8_l); - - /* convert 16 bit output data into 8 bit */ - PCKEV_B4_SH(p2_filt8_l, p2_filt8_r, p1_filt8_l, p1_filt8_r, p0_filt8_l, - p0_filt8_r, q0_filt8_l, q0_filt8_r, p2_filt8_r, p1_filt8_r, - p0_filt8_r, q0_filt8_r); - PCKEV_B2_SH(q1_filt8_l, q1_filt8_r, q2_filt8_l, q2_filt8_r, q1_filt8_r, - q2_filt8_r); - - /* store pixel values */ - p2_out = __msa_bmnz_v(p2, (v16u8)p2_filt8_r, flat); - p1_out = __msa_bmnz_v(p1_out, (v16u8)p1_filt8_r, flat); - p0_out = __msa_bmnz_v(p0_out, (v16u8)p0_filt8_r, flat); - q0_out = __msa_bmnz_v(q0_out, (v16u8)q0_filt8_r, flat); - q1_out = __msa_bmnz_v(q1_out, (v16u8)q1_filt8_r, flat); - q2_out = __msa_bmnz_v(q2, (v16u8)q2_filt8_r, flat); - - ST_UB4(p2_out, p1_out, p0_out, q0_out, filter48, 16); - filter48 += (4 * 16); - ST_UB2(q1_out, q2_out, filter48, 16); - filter48 += (2 * 16); - ST_UB(flat, filter48); - - return 0; - } -} - -static int32_t vt_lpf_t16_16w(uint8_t *src, uint8_t *src_org, int32_t pitch, - uint8_t *filter48) { - v16u8 flat, flat2, filter8; - v16i8 zero = { 0 }; - v16u8 p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7; - v8u16 p7_r_in, p6_r_in, p5_r_in, p4_r_in, p3_r_in, p2_r_in, p1_r_in, p0_r_in; - v8u16 q7_r_in, q6_r_in, q5_r_in, q4_r_in, q3_r_in, q2_r_in, q1_r_in, q0_r_in; - v8u16 p7_l_in, p6_l_in, p5_l_in, p4_l_in, p3_l_in, p2_l_in, p1_l_in, p0_l_in; - v8u16 q7_l_in, q6_l_in, q5_l_in, q4_l_in, q3_l_in, q2_l_in, q1_l_in, q0_l_in; - v8u16 tmp0_r, tmp1_r, tmp0_l, tmp1_l; - v8i16 l_out, r_out; - - flat = LD_UB(filter48 + 6 * 16); - - LD_UB8((src - 8 * 16), 16, p7, p6, p5, p4, p3, p2, p1, p0); - LD_UB8(src, 16, q0, q1, q2, q3, q4, q5, q6, q7); - - VP9_FLAT5(p7, p6, p5, p4, p0, q0, q4, q5, q6, q7, flat, flat2); - - if (__msa_test_bz_v(flat2)) { - v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - - LD_UB4(filter48, 16, p2, p1, p0, q0); - LD_UB2(filter48 + 4 * 16, 16, q1, q2); - - ILVR_B2_SH(p1, p2, q0, p0, vec0, vec1); - ILVRL_H2_SH(vec1, vec0, vec3, vec4); - ILVL_B2_SH(p1, p2, q0, p0, vec0, vec1); - ILVRL_H2_SH(vec1, vec0, vec6, vec7); - ILVRL_B2_SH(q2, q1, vec2, vec5); - - src_org -= 3; - ST4x4_UB(vec3, vec3, 0, 1, 2, 3, src_org, pitch); - ST2x4_UB(vec2, 0, (src_org + 4), pitch); - src_org += (4 * pitch); - ST4x4_UB(vec4, vec4, 0, 1, 2, 3, src_org, pitch); - ST2x4_UB(vec2, 4, (src_org + 4), pitch); - src_org += (4 * pitch); - ST4x4_UB(vec6, vec6, 0, 1, 2, 3, src_org, pitch); - ST2x4_UB(vec5, 0, (src_org + 4), pitch); - src_org += (4 * pitch); - ST4x4_UB(vec7, vec7, 0, 1, 2, 3, src_org, pitch); - ST2x4_UB(vec5, 4, (src_org + 4), pitch); - - return 1; - } else { - src -= 7 * 16; - - ILVR_B8_UH(zero, p7, zero, p6, zero, p5, zero, p4, zero, p3, zero, p2, zero, - p1, zero, p0, p7_r_in, p6_r_in, p5_r_in, p4_r_in, p3_r_in, - p2_r_in, p1_r_in, p0_r_in); - q0_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q0); - - tmp0_r = p7_r_in << 3; - tmp0_r -= p7_r_in; - tmp0_r += p6_r_in; - tmp0_r += q0_r_in; - tmp1_r = p6_r_in + p5_r_in; - tmp1_r += p4_r_in; - tmp1_r += p3_r_in; - tmp1_r += p2_r_in; - tmp1_r += p1_r_in; - tmp1_r += p0_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - - ILVL_B4_UH(zero, p7, zero, p6, zero, p5, zero, p4, p7_l_in, p6_l_in, - p5_l_in, p4_l_in); - ILVL_B4_UH(zero, p3, zero, p2, zero, p1, zero, p0, p3_l_in, p2_l_in, - p1_l_in, p0_l_in); - q0_l_in = (v8u16)__msa_ilvl_b(zero, (v16i8)q0); - - tmp0_l = p7_l_in << 3; - tmp0_l -= p7_l_in; - tmp0_l += p6_l_in; - tmp0_l += q0_l_in; - tmp1_l = p6_l_in + p5_l_in; - tmp1_l += p4_l_in; - tmp1_l += p3_l_in; - tmp1_l += p2_l_in; - tmp1_l += p1_l_in; - tmp1_l += p0_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - p6 = __msa_bmnz_v(p6, (v16u8)r_out, flat2); - ST_UB(p6, src); - src += 16; - - /* p5 */ - q1_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q1); - tmp0_r = p5_r_in - p6_r_in; - tmp0_r += q1_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - q1_l_in = (v8u16)__msa_ilvl_b(zero, (v16i8)q1); - tmp0_l = p5_l_in - p6_l_in; - tmp0_l += q1_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - p5 = __msa_bmnz_v(p5, (v16u8)r_out, flat2); - ST_UB(p5, src); - src += 16; - - /* p4 */ - q2_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q2); - tmp0_r = p4_r_in - p5_r_in; - tmp0_r += q2_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - q2_l_in = (v8u16)__msa_ilvl_b(zero, (v16i8)q2); - tmp0_l = p4_l_in - p5_l_in; - tmp0_l += q2_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - p4 = __msa_bmnz_v(p4, (v16u8)r_out, flat2); - ST_UB(p4, src); - src += 16; - - /* p3 */ - q3_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q3); - tmp0_r = p3_r_in - p4_r_in; - tmp0_r += q3_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - q3_l_in = (v8u16)__msa_ilvl_b(zero, (v16i8)q3); - tmp0_l = p3_l_in - p4_l_in; - tmp0_l += q3_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - p3 = __msa_bmnz_v(p3, (v16u8)r_out, flat2); - ST_UB(p3, src); - src += 16; - - /* p2 */ - q4_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q4); - filter8 = LD_UB(filter48); - tmp0_r = p2_r_in - p3_r_in; - tmp0_r += q4_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - q4_l_in = (v8u16)__msa_ilvl_b(zero, (v16i8)q4); - tmp0_l = p2_l_in - p3_l_in; - tmp0_l += q4_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST_UB(filter8, src); - src += 16; - - /* p1 */ - q5_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q5); - filter8 = LD_UB(filter48 + 16); - tmp0_r = p1_r_in - p2_r_in; - tmp0_r += q5_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - q5_l_in = (v8u16)__msa_ilvl_b(zero, (v16i8)q5); - tmp0_l = p1_l_in - p2_l_in; - tmp0_l += q5_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)(tmp1_l), 4); - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST_UB(filter8, src); - src += 16; - - /* p0 */ - q6_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q6); - filter8 = LD_UB(filter48 + 32); - tmp0_r = p0_r_in - p1_r_in; - tmp0_r += q6_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - q6_l_in = (v8u16)__msa_ilvl_b(zero, (v16i8)q6); - tmp0_l = p0_l_in - p1_l_in; - tmp0_l += q6_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST_UB(filter8, src); - src += 16; - - /* q0 */ - q7_r_in = (v8u16)__msa_ilvr_b(zero, (v16i8)q7); - filter8 = LD_UB(filter48 + 48); - tmp0_r = q7_r_in - p0_r_in; - tmp0_r += q0_r_in; - tmp0_r -= p7_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - q7_l_in = (v8u16)__msa_ilvl_b(zero, (v16i8)q7); - tmp0_l = q7_l_in - p0_l_in; - tmp0_l += q0_l_in; - tmp0_l -= p7_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST_UB(filter8, src); - src += 16; - - /* q1 */ - filter8 = LD_UB(filter48 + 64); - tmp0_r = q7_r_in - q0_r_in; - tmp0_r += q1_r_in; - tmp0_r -= p6_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - tmp0_l = q7_l_in - q0_l_in; - tmp0_l += q1_l_in; - tmp0_l -= p6_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST_UB(filter8, src); - src += 16; - - /* q2 */ - filter8 = LD_UB(filter48 + 80); - tmp0_r = q7_r_in - q1_r_in; - tmp0_r += q2_r_in; - tmp0_r -= p5_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - tmp0_l = q7_l_in - q1_l_in; - tmp0_l += q2_l_in; - tmp0_l -= p5_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - filter8 = __msa_bmnz_v(filter8, (v16u8)r_out, flat2); - ST_UB(filter8, src); - src += 16; - - /* q3 */ - tmp0_r = q7_r_in - q2_r_in; - tmp0_r += q3_r_in; - tmp0_r -= p4_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - tmp0_l = q7_l_in - q2_l_in; - tmp0_l += q3_l_in; - tmp0_l -= p4_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - q3 = __msa_bmnz_v(q3, (v16u8)r_out, flat2); - ST_UB(q3, src); - src += 16; - - /* q4 */ - tmp0_r = q7_r_in - q3_r_in; - tmp0_r += q4_r_in; - tmp0_r -= p3_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - tmp0_l = q7_l_in - q3_l_in; - tmp0_l += q4_l_in; - tmp0_l -= p3_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - q4 = __msa_bmnz_v(q4, (v16u8)r_out, flat2); - ST_UB(q4, src); - src += 16; - - /* q5 */ - tmp0_r = q7_r_in - q4_r_in; - tmp0_r += q5_r_in; - tmp0_r -= p2_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - tmp0_l = q7_l_in - q4_l_in; - tmp0_l += q5_l_in; - tmp0_l -= p2_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - q5 = __msa_bmnz_v(q5, (v16u8)r_out, flat2); - ST_UB(q5, src); - src += 16; - - /* q6 */ - tmp0_r = q7_r_in - q5_r_in; - tmp0_r += q6_r_in; - tmp0_r -= p1_r_in; - tmp1_r += tmp0_r; - r_out = __msa_srari_h((v8i16)tmp1_r, 4); - tmp0_l = q7_l_in - q5_l_in; - tmp0_l += q6_l_in; - tmp0_l -= p1_l_in; - tmp1_l += tmp0_l; - l_out = __msa_srari_h((v8i16)tmp1_l, 4); - r_out = (v8i16)__msa_pckev_b((v16i8)l_out, (v16i8)r_out); - q6 = __msa_bmnz_v(q6, (v16u8)r_out, flat2); - ST_UB(q6, src); - - return 0; - } -} - -void vpx_lpf_vertical_16_dual_msa(uint8_t *src, int32_t pitch, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - uint8_t early_exit = 0; - DECLARE_ALIGNED(32, uint8_t, transposed_input[16 * 24]); - uint8_t *filter48 = &transposed_input[16 * 16]; - - transpose_16x16((src - 8), pitch, &transposed_input[0], 16); - - early_exit = - vt_lpf_t4_and_t8_16w((transposed_input + 16 * 8), &filter48[0], src, - pitch, b_limit_ptr, limit_ptr, thresh_ptr); - - if (0 == early_exit) { - early_exit = - vt_lpf_t16_16w((transposed_input + 16 * 8), src, pitch, &filter48[0]); - - if (0 == early_exit) { - transpose_16x16(transposed_input, 16, (src - 8), pitch); - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_4_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_4_msa.c deleted file mode 100644 index 0eff2b6c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_4_msa.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/loopfilter_msa.h" - -void vpx_lpf_horizontal_4_msa(uint8_t *src, int32_t pitch, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - uint64_t p1_d, p0_d, q0_d, q1_d; - v16u8 mask, hev, flat, thresh, b_limit, limit; - v16u8 p3, p2, p1, p0, q3, q2, q1, q0, p1_out, p0_out, q0_out, q1_out; - - /* load vector elements */ - LD_UB8((src - 4 * pitch), pitch, p3, p2, p1, p0, q0, q1, q2, q3); - - thresh = (v16u8)__msa_fill_b(*thresh_ptr); - b_limit = (v16u8)__msa_fill_b(*b_limit_ptr); - limit = (v16u8)__msa_fill_b(*limit_ptr); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); - - p1_d = __msa_copy_u_d((v2i64)p1_out, 0); - p0_d = __msa_copy_u_d((v2i64)p0_out, 0); - q0_d = __msa_copy_u_d((v2i64)q0_out, 0); - q1_d = __msa_copy_u_d((v2i64)q1_out, 0); - SD4(p1_d, p0_d, q0_d, q1_d, (src - 2 * pitch), pitch); -} - -void vpx_lpf_horizontal_4_dual_msa(uint8_t *src, int32_t pitch, - const uint8_t *b_limit0_ptr, - const uint8_t *limit0_ptr, - const uint8_t *thresh0_ptr, - const uint8_t *b_limit1_ptr, - const uint8_t *limit1_ptr, - const uint8_t *thresh1_ptr) { - v16u8 mask, hev, flat, thresh0, b_limit0, limit0, thresh1, b_limit1, limit1; - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - - /* load vector elements */ - LD_UB8((src - 4 * pitch), pitch, p3, p2, p1, p0, q0, q1, q2, q3); - - thresh0 = (v16u8)__msa_fill_b(*thresh0_ptr); - thresh1 = (v16u8)__msa_fill_b(*thresh1_ptr); - thresh0 = (v16u8)__msa_ilvr_d((v2i64)thresh1, (v2i64)thresh0); - - b_limit0 = (v16u8)__msa_fill_b(*b_limit0_ptr); - b_limit1 = (v16u8)__msa_fill_b(*b_limit1_ptr); - b_limit0 = (v16u8)__msa_ilvr_d((v2i64)b_limit1, (v2i64)b_limit0); - - limit0 = (v16u8)__msa_fill_b(*limit0_ptr); - limit1 = (v16u8)__msa_fill_b(*limit1_ptr); - limit0 = (v16u8)__msa_ilvr_d((v2i64)limit1, (v2i64)limit0); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit0, b_limit0, thresh0, hev, - mask, flat); - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1, p0, q0, q1); - - ST_UB4(p1, p0, q0, q1, (src - 2 * pitch), pitch); -} - -void vpx_lpf_vertical_4_msa(uint8_t *src, int32_t pitch, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - v16u8 mask, hev, flat, limit, thresh, b_limit; - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - v8i16 vec0, vec1, vec2, vec3; - - LD_UB8((src - 4), pitch, p3, p2, p1, p0, q0, q1, q2, q3); - - thresh = (v16u8)__msa_fill_b(*thresh_ptr); - b_limit = (v16u8)__msa_fill_b(*b_limit_ptr); - limit = (v16u8)__msa_fill_b(*limit_ptr); - - TRANSPOSE8x8_UB_UB(p3, p2, p1, p0, q0, q1, q2, q3, p3, p2, p1, p0, q0, q1, q2, - q3); - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1, p0, q0, q1); - ILVR_B2_SH(p0, p1, q1, q0, vec0, vec1); - ILVRL_H2_SH(vec1, vec0, vec2, vec3); - - src -= 2; - ST4x4_UB(vec2, vec2, 0, 1, 2, 3, src, pitch); - src += 4 * pitch; - ST4x4_UB(vec3, vec3, 0, 1, 2, 3, src, pitch); -} - -void vpx_lpf_vertical_4_dual_msa(uint8_t *src, int32_t pitch, - const uint8_t *b_limit0_ptr, - const uint8_t *limit0_ptr, - const uint8_t *thresh0_ptr, - const uint8_t *b_limit1_ptr, - const uint8_t *limit1_ptr, - const uint8_t *thresh1_ptr) { - v16u8 mask, hev, flat; - v16u8 thresh0, b_limit0, limit0, thresh1, b_limit1, limit1; - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - v16u8 row0, row1, row2, row3, row4, row5, row6, row7; - v16u8 row8, row9, row10, row11, row12, row13, row14, row15; - v8i16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; - - LD_UB8(src - 4, pitch, row0, row1, row2, row3, row4, row5, row6, row7); - LD_UB8(src - 4 + (8 * pitch), pitch, row8, row9, row10, row11, row12, row13, - row14, row15); - - TRANSPOSE16x8_UB_UB(row0, row1, row2, row3, row4, row5, row6, row7, row8, - row9, row10, row11, row12, row13, row14, row15, p3, p2, - p1, p0, q0, q1, q2, q3); - - thresh0 = (v16u8)__msa_fill_b(*thresh0_ptr); - thresh1 = (v16u8)__msa_fill_b(*thresh1_ptr); - thresh0 = (v16u8)__msa_ilvr_d((v2i64)thresh1, (v2i64)thresh0); - - b_limit0 = (v16u8)__msa_fill_b(*b_limit0_ptr); - b_limit1 = (v16u8)__msa_fill_b(*b_limit1_ptr); - b_limit0 = (v16u8)__msa_ilvr_d((v2i64)b_limit1, (v2i64)b_limit0); - - limit0 = (v16u8)__msa_fill_b(*limit0_ptr); - limit1 = (v16u8)__msa_fill_b(*limit1_ptr); - limit0 = (v16u8)__msa_ilvr_d((v2i64)limit1, (v2i64)limit0); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit0, b_limit0, thresh0, hev, - mask, flat); - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1, p0, q0, q1); - ILVR_B2_SH(p0, p1, q1, q0, tmp0, tmp1); - ILVRL_H2_SH(tmp1, tmp0, tmp2, tmp3); - ILVL_B2_SH(p0, p1, q1, q0, tmp0, tmp1); - ILVRL_H2_SH(tmp1, tmp0, tmp4, tmp5); - - src -= 2; - - ST4x8_UB(tmp2, tmp3, src, pitch); - src += (8 * pitch); - ST4x8_UB(tmp4, tmp5, src, pitch); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_8_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_8_msa.c deleted file mode 100644 index 703fcce8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_8_msa.c +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/loopfilter_msa.h" - -void vpx_lpf_horizontal_8_msa(uint8_t *src, int32_t pitch, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - uint64_t p2_d, p1_d, p0_d, q0_d, q1_d, q2_d; - v16u8 mask, hev, flat, thresh, b_limit, limit; - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - v16u8 p2_out, p1_out, p0_out, q0_out, q1_out, q2_out; - v8i16 p2_filter8, p1_filter8, p0_filter8, q0_filter8, q1_filter8, q2_filter8; - v8u16 p3_r, p2_r, p1_r, p0_r, q3_r, q2_r, q1_r, q0_r; - v16i8 zero = { 0 }; - - /* load vector elements */ - LD_UB8((src - 4 * pitch), pitch, p3, p2, p1, p0, q0, q1, q2, q3); - - thresh = (v16u8)__msa_fill_b(*thresh_ptr); - b_limit = (v16u8)__msa_fill_b(*b_limit_ptr); - limit = (v16u8)__msa_fill_b(*limit_ptr); - - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); - - flat = (v16u8)__msa_ilvr_d((v2i64)zero, (v2i64)flat); - - if (__msa_test_bz_v(flat)) { - p1_d = __msa_copy_u_d((v2i64)p1_out, 0); - p0_d = __msa_copy_u_d((v2i64)p0_out, 0); - q0_d = __msa_copy_u_d((v2i64)q0_out, 0); - q1_d = __msa_copy_u_d((v2i64)q1_out, 0); - SD4(p1_d, p0_d, q0_d, q1_d, (src - 2 * pitch), pitch); - } else { - ILVR_B8_UH(zero, p3, zero, p2, zero, p1, zero, p0, zero, q0, zero, q1, zero, - q2, zero, q3, p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r); - VP9_FILTER8(p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r, p2_filter8, - p1_filter8, p0_filter8, q0_filter8, q1_filter8, q2_filter8); - - /* convert 16 bit output data into 8 bit */ - PCKEV_B4_SH(zero, p2_filter8, zero, p1_filter8, zero, p0_filter8, zero, - q0_filter8, p2_filter8, p1_filter8, p0_filter8, q0_filter8); - PCKEV_B2_SH(zero, q1_filter8, zero, q2_filter8, q1_filter8, q2_filter8); - - /* store pixel values */ - p2_out = __msa_bmnz_v(p2, (v16u8)p2_filter8, flat); - p1_out = __msa_bmnz_v(p1_out, (v16u8)p1_filter8, flat); - p0_out = __msa_bmnz_v(p0_out, (v16u8)p0_filter8, flat); - q0_out = __msa_bmnz_v(q0_out, (v16u8)q0_filter8, flat); - q1_out = __msa_bmnz_v(q1_out, (v16u8)q1_filter8, flat); - q2_out = __msa_bmnz_v(q2, (v16u8)q2_filter8, flat); - - p2_d = __msa_copy_u_d((v2i64)p2_out, 0); - p1_d = __msa_copy_u_d((v2i64)p1_out, 0); - p0_d = __msa_copy_u_d((v2i64)p0_out, 0); - q0_d = __msa_copy_u_d((v2i64)q0_out, 0); - q1_d = __msa_copy_u_d((v2i64)q1_out, 0); - q2_d = __msa_copy_u_d((v2i64)q2_out, 0); - - src -= 3 * pitch; - - SD4(p2_d, p1_d, p0_d, q0_d, src, pitch); - src += (4 * pitch); - SD(q1_d, src); - src += pitch; - SD(q2_d, src); - } -} - -void vpx_lpf_horizontal_8_dual_msa( - uint8_t *src, int32_t pitch, const uint8_t *b_limit0, const uint8_t *limit0, - const uint8_t *thresh0, const uint8_t *b_limit1, const uint8_t *limit1, - const uint8_t *thresh1) { - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - v16u8 p2_out, p1_out, p0_out, q0_out, q1_out, q2_out; - v16u8 flat, mask, hev, tmp, thresh, b_limit, limit; - v8u16 p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r; - v8u16 p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l; - v8i16 p2_filt8_r, p1_filt8_r, p0_filt8_r, q0_filt8_r, q1_filt8_r, q2_filt8_r; - v8i16 p2_filt8_l, p1_filt8_l, p0_filt8_l, q0_filt8_l, q1_filt8_l, q2_filt8_l; - v16u8 zero = { 0 }; - - /* load vector elements */ - LD_UB8(src - (4 * pitch), pitch, p3, p2, p1, p0, q0, q1, q2, q3); - - thresh = (v16u8)__msa_fill_b(*thresh0); - tmp = (v16u8)__msa_fill_b(*thresh1); - thresh = (v16u8)__msa_ilvr_d((v2i64)tmp, (v2i64)thresh); - - b_limit = (v16u8)__msa_fill_b(*b_limit0); - tmp = (v16u8)__msa_fill_b(*b_limit1); - b_limit = (v16u8)__msa_ilvr_d((v2i64)tmp, (v2i64)b_limit); - - limit = (v16u8)__msa_fill_b(*limit0); - tmp = (v16u8)__msa_fill_b(*limit1); - limit = (v16u8)__msa_ilvr_d((v2i64)tmp, (v2i64)limit); - - /* mask and hev */ - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); - - if (__msa_test_bz_v(flat)) { - ST_UB4(p1_out, p0_out, q0_out, q1_out, (src - 2 * pitch), pitch); - } else { - ILVR_B8_UH(zero, p3, zero, p2, zero, p1, zero, p0, zero, q0, zero, q1, zero, - q2, zero, q3, p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r); - VP9_FILTER8(p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r, p2_filt8_r, - p1_filt8_r, p0_filt8_r, q0_filt8_r, q1_filt8_r, q2_filt8_r); - - ILVL_B4_UH(zero, p3, zero, p2, zero, p1, zero, p0, p3_l, p2_l, p1_l, p0_l); - ILVL_B4_UH(zero, q0, zero, q1, zero, q2, zero, q3, q0_l, q1_l, q2_l, q3_l); - VP9_FILTER8(p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l, p2_filt8_l, - p1_filt8_l, p0_filt8_l, q0_filt8_l, q1_filt8_l, q2_filt8_l); - - /* convert 16 bit output data into 8 bit */ - PCKEV_B4_SH(p2_filt8_l, p2_filt8_r, p1_filt8_l, p1_filt8_r, p0_filt8_l, - p0_filt8_r, q0_filt8_l, q0_filt8_r, p2_filt8_r, p1_filt8_r, - p0_filt8_r, q0_filt8_r); - PCKEV_B2_SH(q1_filt8_l, q1_filt8_r, q2_filt8_l, q2_filt8_r, q1_filt8_r, - q2_filt8_r); - - /* store pixel values */ - p2_out = __msa_bmnz_v(p2, (v16u8)p2_filt8_r, flat); - p1_out = __msa_bmnz_v(p1_out, (v16u8)p1_filt8_r, flat); - p0_out = __msa_bmnz_v(p0_out, (v16u8)p0_filt8_r, flat); - q0_out = __msa_bmnz_v(q0_out, (v16u8)q0_filt8_r, flat); - q1_out = __msa_bmnz_v(q1_out, (v16u8)q1_filt8_r, flat); - q2_out = __msa_bmnz_v(q2, (v16u8)q2_filt8_r, flat); - - src -= 3 * pitch; - - ST_UB4(p2_out, p1_out, p0_out, q0_out, src, pitch); - src += (4 * pitch); - ST_UB2(q1_out, q2_out, src, pitch); - src += (2 * pitch); - } -} - -void vpx_lpf_vertical_8_msa(uint8_t *src, int32_t pitch, - const uint8_t *b_limit_ptr, - const uint8_t *limit_ptr, - const uint8_t *thresh_ptr) { - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - v16u8 p1_out, p0_out, q0_out, q1_out; - v16u8 flat, mask, hev, thresh, b_limit, limit; - v8u16 p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r; - v8i16 p2_filt8_r, p1_filt8_r, p0_filt8_r, q0_filt8_r, q1_filt8_r, q2_filt8_r; - v16u8 zero = { 0 }; - v8i16 vec0, vec1, vec2, vec3, vec4; - - /* load vector elements */ - LD_UB8(src - 4, pitch, p3, p2, p1, p0, q0, q1, q2, q3); - - TRANSPOSE8x8_UB_UB(p3, p2, p1, p0, q0, q1, q2, q3, p3, p2, p1, p0, q0, q1, q2, - q3); - - thresh = (v16u8)__msa_fill_b(*thresh_ptr); - b_limit = (v16u8)__msa_fill_b(*b_limit_ptr); - limit = (v16u8)__msa_fill_b(*limit_ptr); - - /* mask and hev */ - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - /* flat4 */ - VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); - /* filter4 */ - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); - - flat = (v16u8)__msa_ilvr_d((v2i64)zero, (v2i64)flat); - - if (__msa_test_bz_v(flat)) { - /* Store 4 pixels p1-_q1 */ - ILVR_B2_SH(p0_out, p1_out, q1_out, q0_out, vec0, vec1); - ILVRL_H2_SH(vec1, vec0, vec2, vec3); - - src -= 2; - ST4x4_UB(vec2, vec2, 0, 1, 2, 3, src, pitch); - src += 4 * pitch; - ST4x4_UB(vec3, vec3, 0, 1, 2, 3, src, pitch); - } else { - ILVR_B8_UH(zero, p3, zero, p2, zero, p1, zero, p0, zero, q0, zero, q1, zero, - q2, zero, q3, p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r); - VP9_FILTER8(p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r, p2_filt8_r, - p1_filt8_r, p0_filt8_r, q0_filt8_r, q1_filt8_r, q2_filt8_r); - /* convert 16 bit output data into 8 bit */ - PCKEV_B4_SH(p2_filt8_r, p2_filt8_r, p1_filt8_r, p1_filt8_r, p0_filt8_r, - p0_filt8_r, q0_filt8_r, q0_filt8_r, p2_filt8_r, p1_filt8_r, - p0_filt8_r, q0_filt8_r); - PCKEV_B2_SH(q1_filt8_r, q1_filt8_r, q2_filt8_r, q2_filt8_r, q1_filt8_r, - q2_filt8_r); - - /* store pixel values */ - p2 = __msa_bmnz_v(p2, (v16u8)p2_filt8_r, flat); - p1 = __msa_bmnz_v(p1_out, (v16u8)p1_filt8_r, flat); - p0 = __msa_bmnz_v(p0_out, (v16u8)p0_filt8_r, flat); - q0 = __msa_bmnz_v(q0_out, (v16u8)q0_filt8_r, flat); - q1 = __msa_bmnz_v(q1_out, (v16u8)q1_filt8_r, flat); - q2 = __msa_bmnz_v(q2, (v16u8)q2_filt8_r, flat); - - /* Store 6 pixels p2-_q2 */ - ILVR_B2_SH(p1, p2, q0, p0, vec0, vec1); - ILVRL_H2_SH(vec1, vec0, vec2, vec3); - vec4 = (v8i16)__msa_ilvr_b((v16i8)q2, (v16i8)q1); - - src -= 3; - ST4x4_UB(vec2, vec2, 0, 1, 2, 3, src, pitch); - ST2x4_UB(vec4, 0, src + 4, pitch); - src += (4 * pitch); - ST4x4_UB(vec3, vec3, 0, 1, 2, 3, src, pitch); - ST2x4_UB(vec4, 4, src + 4, pitch); - } -} - -void vpx_lpf_vertical_8_dual_msa(uint8_t *src, int32_t pitch, - const uint8_t *b_limit0, const uint8_t *limit0, - const uint8_t *thresh0, - const uint8_t *b_limit1, const uint8_t *limit1, - const uint8_t *thresh1) { - uint8_t *temp_src; - v16u8 p3, p2, p1, p0, q3, q2, q1, q0; - v16u8 p1_out, p0_out, q0_out, q1_out; - v16u8 flat, mask, hev, thresh, b_limit, limit; - v16u8 row4, row5, row6, row7, row12, row13, row14, row15; - v8u16 p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r; - v8u16 p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l; - v8i16 p2_filt8_r, p1_filt8_r, p0_filt8_r, q0_filt8_r, q1_filt8_r, q2_filt8_r; - v8i16 p2_filt8_l, p1_filt8_l, p0_filt8_l, q0_filt8_l, q1_filt8_l, q2_filt8_l; - v16u8 zero = { 0 }; - v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - - temp_src = src - 4; - - LD_UB8(temp_src, pitch, p0, p1, p2, p3, row4, row5, row6, row7); - temp_src += (8 * pitch); - LD_UB8(temp_src, pitch, q3, q2, q1, q0, row12, row13, row14, row15); - - /* transpose 16x8 matrix into 8x16 */ - TRANSPOSE16x8_UB_UB(p0, p1, p2, p3, row4, row5, row6, row7, q3, q2, q1, q0, - row12, row13, row14, row15, p3, p2, p1, p0, q0, q1, q2, - q3); - - thresh = (v16u8)__msa_fill_b(*thresh0); - vec0 = (v8i16)__msa_fill_b(*thresh1); - thresh = (v16u8)__msa_ilvr_d((v2i64)vec0, (v2i64)thresh); - - b_limit = (v16u8)__msa_fill_b(*b_limit0); - vec0 = (v8i16)__msa_fill_b(*b_limit1); - b_limit = (v16u8)__msa_ilvr_d((v2i64)vec0, (v2i64)b_limit); - - limit = (v16u8)__msa_fill_b(*limit0); - vec0 = (v8i16)__msa_fill_b(*limit1); - limit = (v16u8)__msa_ilvr_d((v2i64)vec0, (v2i64)limit); - - /* mask and hev */ - LPF_MASK_HEV(p3, p2, p1, p0, q0, q1, q2, q3, limit, b_limit, thresh, hev, - mask, flat); - /* flat4 */ - VP9_FLAT4(p3, p2, p0, q0, q2, q3, flat); - /* filter4 */ - VP9_LPF_FILTER4_4W(p1, p0, q0, q1, mask, hev, p1_out, p0_out, q0_out, q1_out); - - if (__msa_test_bz_v(flat)) { - ILVR_B2_SH(p0_out, p1_out, q1_out, q0_out, vec0, vec1); - ILVRL_H2_SH(vec1, vec0, vec2, vec3); - ILVL_B2_SH(p0_out, p1_out, q1_out, q0_out, vec0, vec1); - ILVRL_H2_SH(vec1, vec0, vec4, vec5); - - src -= 2; - ST4x8_UB(vec2, vec3, src, pitch); - src += 8 * pitch; - ST4x8_UB(vec4, vec5, src, pitch); - } else { - ILVR_B8_UH(zero, p3, zero, p2, zero, p1, zero, p0, zero, q0, zero, q1, zero, - q2, zero, q3, p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r); - VP9_FILTER8(p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r, p2_filt8_r, - p1_filt8_r, p0_filt8_r, q0_filt8_r, q1_filt8_r, q2_filt8_r); - - ILVL_B4_UH(zero, p3, zero, p2, zero, p1, zero, p0, p3_l, p2_l, p1_l, p0_l); - ILVL_B4_UH(zero, q0, zero, q1, zero, q2, zero, q3, q0_l, q1_l, q2_l, q3_l); - - /* filter8 */ - VP9_FILTER8(p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l, p2_filt8_l, - p1_filt8_l, p0_filt8_l, q0_filt8_l, q1_filt8_l, q2_filt8_l); - - /* convert 16 bit output data into 8 bit */ - PCKEV_B4_SH(p2_filt8_l, p2_filt8_r, p1_filt8_l, p1_filt8_r, p0_filt8_l, - p0_filt8_r, q0_filt8_l, q0_filt8_r, p2_filt8_r, p1_filt8_r, - p0_filt8_r, q0_filt8_r); - PCKEV_B2_SH(q1_filt8_l, q1_filt8_r, q2_filt8_l, q2_filt8_r, q1_filt8_r, - q2_filt8_r); - - /* store pixel values */ - p2 = __msa_bmnz_v(p2, (v16u8)p2_filt8_r, flat); - p1 = __msa_bmnz_v(p1_out, (v16u8)p1_filt8_r, flat); - p0 = __msa_bmnz_v(p0_out, (v16u8)p0_filt8_r, flat); - q0 = __msa_bmnz_v(q0_out, (v16u8)q0_filt8_r, flat); - q1 = __msa_bmnz_v(q1_out, (v16u8)q1_filt8_r, flat); - q2 = __msa_bmnz_v(q2, (v16u8)q2_filt8_r, flat); - - ILVR_B2_SH(p1, p2, q0, p0, vec0, vec1); - ILVRL_H2_SH(vec1, vec0, vec3, vec4); - ILVL_B2_SH(p1, p2, q0, p0, vec0, vec1); - ILVRL_H2_SH(vec1, vec0, vec6, vec7); - ILVRL_B2_SH(q2, q1, vec2, vec5); - - src -= 3; - ST4x4_UB(vec3, vec3, 0, 1, 2, 3, src, pitch); - ST2x4_UB(vec2, 0, src + 4, pitch); - src += (4 * pitch); - ST4x4_UB(vec4, vec4, 0, 1, 2, 3, src, pitch); - ST2x4_UB(vec2, 4, src + 4, pitch); - src += (4 * pitch); - ST4x4_UB(vec6, vec6, 0, 1, 2, 3, src, pitch); - ST2x4_UB(vec5, 0, src + 4, pitch); - src += (4 * pitch); - ST4x4_UB(vec7, vec7, 0, 1, 2, 3, src, pitch); - ST2x4_UB(vec5, 4, src + 4, pitch); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_filters_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_filters_dspr2.c deleted file mode 100644 index f1743679..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_filters_dspr2.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/mips/common_dspr2.h" -#include "vpx_dsp/mips/loopfilter_filters_dspr2.h" -#include "vpx_dsp/mips/loopfilter_macros_dspr2.h" -#include "vpx_dsp/mips/loopfilter_masks_dspr2.h" -#include "vpx_mem/vpx_mem.h" - -#if HAVE_DSPR2 -void vpx_lpf_horizontal_4_dspr2(unsigned char *s, int pitch, - const uint8_t *blimit, const uint8_t *limit, - const uint8_t *thresh) { - uint8_t i; - uint32_t mask; - uint32_t hev; - uint32_t pm1, p0, p1, p2, p3, p4, p5, p6; - uint8_t *sm1, *s0, *s1, *s2, *s3, *s4, *s5, *s6; - uint32_t thresh_vec, flimit_vec, limit_vec; - uint32_t uflimit, ulimit, uthresh; - - uflimit = *blimit; - ulimit = *limit; - uthresh = *thresh; - - /* create quad-byte */ - __asm__ __volatile__( - "replv.qb %[thresh_vec], %[uthresh] \n\t" - "replv.qb %[flimit_vec], %[uflimit] \n\t" - "replv.qb %[limit_vec], %[ulimit] \n\t" - - : [thresh_vec] "=&r"(thresh_vec), [flimit_vec] "=&r"(flimit_vec), - [limit_vec] "=r"(limit_vec) - : [uthresh] "r"(uthresh), [uflimit] "r"(uflimit), [ulimit] "r"(ulimit)); - - /* prefetch data for store */ - prefetch_store(s); - - /* loop filter designed to work using chars so that we can make maximum use - of 8 bit simd instructions. */ - for (i = 0; i < 2; i++) { - sm1 = s - (pitch << 2); - s0 = sm1 + pitch; - s1 = s0 + pitch; - s2 = s - pitch; - s3 = s; - s4 = s + pitch; - s5 = s4 + pitch; - s6 = s5 + pitch; - - __asm__ __volatile__( - "lw %[p1], (%[s1]) \n\t" - "lw %[p2], (%[s2]) \n\t" - "lw %[p3], (%[s3]) \n\t" - "lw %[p4], (%[s4]) \n\t" - - : [p1] "=&r"(p1), [p2] "=&r"(p2), [p3] "=&r"(p3), [p4] "=&r"(p4) - : [s1] "r"(s1), [s2] "r"(s2), [s3] "r"(s3), [s4] "r"(s4)); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - mask will be zero and filtering is not needed */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - __asm__ __volatile__( - "lw %[pm1], (%[sm1]) \n\t" - "lw %[p0], (%[s0]) \n\t" - "lw %[p5], (%[s5]) \n\t" - "lw %[p6], (%[s6]) \n\t" - - : [pm1] "=&r"(pm1), [p0] "=&r"(p0), [p5] "=&r"(p5), [p6] "=&r"(p6) - : [sm1] "r"(sm1), [s0] "r"(s0), [s5] "r"(s5), [s6] "r"(s6)); - - filter_hev_mask_dspr2(limit_vec, flimit_vec, p1, p2, pm1, p0, p3, p4, p5, - p6, thresh_vec, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - filter_dspr2(mask, hev, &p1, &p2, &p3, &p4); - - __asm__ __volatile__( - "sw %[p1], (%[s1]) \n\t" - "sw %[p2], (%[s2]) \n\t" - "sw %[p3], (%[s3]) \n\t" - "sw %[p4], (%[s4]) \n\t" - - : - : [p1] "r"(p1), [p2] "r"(p2), [p3] "r"(p3), [p4] "r"(p4), - [s1] "r"(s1), [s2] "r"(s2), [s3] "r"(s3), [s4] "r"(s4)); - } - } - - s = s + 4; - } -} - -void vpx_lpf_vertical_4_dspr2(unsigned char *s, int pitch, - const uint8_t *blimit, const uint8_t *limit, - const uint8_t *thresh) { - uint8_t i; - uint32_t mask, hev; - uint32_t pm1, p0, p1, p2, p3, p4, p5, p6; - uint8_t *s1, *s2, *s3, *s4; - uint32_t prim1, prim2, sec3, sec4, prim3, prim4; - uint32_t thresh_vec, flimit_vec, limit_vec; - uint32_t uflimit, ulimit, uthresh; - - uflimit = *blimit; - ulimit = *limit; - uthresh = *thresh; - - /* create quad-byte */ - __asm__ __volatile__( - "replv.qb %[thresh_vec], %[uthresh] \n\t" - "replv.qb %[flimit_vec], %[uflimit] \n\t" - "replv.qb %[limit_vec], %[ulimit] \n\t" - - : [thresh_vec] "=&r"(thresh_vec), [flimit_vec] "=&r"(flimit_vec), - [limit_vec] "=r"(limit_vec) - : [uthresh] "r"(uthresh), [uflimit] "r"(uflimit), [ulimit] "r"(ulimit)); - - /* prefetch data for store */ - prefetch_store(s + pitch); - - for (i = 0; i < 2; i++) { - s1 = s; - s2 = s + pitch; - s3 = s2 + pitch; - s4 = s3 + pitch; - s = s4 + pitch; - - /* load quad-byte vectors - * memory is 4 byte aligned - */ - p2 = *((uint32_t *)(s1 - 4)); - p6 = *((uint32_t *)(s1)); - p1 = *((uint32_t *)(s2 - 4)); - p5 = *((uint32_t *)(s2)); - p0 = *((uint32_t *)(s3 - 4)); - p4 = *((uint32_t *)(s3)); - pm1 = *((uint32_t *)(s4 - 4)); - p3 = *((uint32_t *)(s4)); - - /* transpose pm1, p0, p1, p2 */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p2], %[p1] \n\t" - "precr.qb.ph %[prim2], %[p2], %[p1] \n\t" - "precrq.qb.ph %[prim3], %[p0], %[pm1] \n\t" - "precr.qb.ph %[prim4], %[p0], %[pm1] \n\t" - - "precrq.qb.ph %[p1], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[pm1], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p2], %[p1], %[sec3] \n\t" - "precrq.ph.w %[p0], %[pm1], %[sec4] \n\t" - "append %[p1], %[sec3], 16 \n\t" - "append %[pm1], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p2] "+r"(p2), [p1] "+r"(p1), [p0] "+r"(p0), - [pm1] "+r"(pm1), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* transpose p3, p4, p5, p6 */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p6], %[p5] \n\t" - "precr.qb.ph %[prim2], %[p6], %[p5] \n\t" - "precrq.qb.ph %[prim3], %[p4], %[p3] \n\t" - "precr.qb.ph %[prim4], %[p4], %[p3] \n\t" - - "precrq.qb.ph %[p5], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[p3], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p6], %[p5], %[sec3] \n\t" - "precrq.ph.w %[p4], %[p3], %[sec4] \n\t" - "append %[p5], %[sec3], 16 \n\t" - "append %[p3], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p6] "+r"(p6), [p5] "+r"(p5), [p4] "+r"(p4), - [p3] "+r"(p3), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* if (p1 - p4 == 0) and (p2 - p3 == 0) - * mask will be zero and filtering is not needed - */ - if (!(((p1 - p4) == 0) && ((p2 - p3) == 0))) { - filter_hev_mask_dspr2(limit_vec, flimit_vec, p1, p2, pm1, p0, p3, p4, p5, - p6, thresh_vec, &hev, &mask); - - /* if mask == 0 do filtering is not needed */ - if (mask) { - /* filtering */ - filter_dspr2(mask, hev, &p1, &p2, &p3, &p4); - - /* unpack processed 4x4 neighborhood - * don't use transpose on output data - * because memory isn't aligned - */ - __asm__ __volatile__( - "sb %[p4], 1(%[s4]) \n\t" - "sb %[p3], 0(%[s4]) \n\t" - "sb %[p2], -1(%[s4]) \n\t" - "sb %[p1], -2(%[s4]) \n\t" - - : - : [p4] "r"(p4), [p3] "r"(p3), [p2] "r"(p2), [p1] "r"(p1), - [s4] "r"(s4)); - - __asm__ __volatile__( - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - - : [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), [p1] "+r"(p1) - :); - - __asm__ __volatile__( - "sb %[p4], 1(%[s3]) \n\t" - "sb %[p3], 0(%[s3]) \n\t" - "sb %[p2], -1(%[s3]) \n\t" - "sb %[p1], -2(%[s3]) \n\t" - - : [p1] "+r"(p1) - : [p4] "r"(p4), [p3] "r"(p3), [p2] "r"(p2), [s3] "r"(s3)); - - __asm__ __volatile__( - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - - : [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), [p1] "+r"(p1) - :); - - __asm__ __volatile__( - "sb %[p4], 1(%[s2]) \n\t" - "sb %[p3], 0(%[s2]) \n\t" - "sb %[p2], -1(%[s2]) \n\t" - "sb %[p1], -2(%[s2]) \n\t" - - : - : [p4] "r"(p4), [p3] "r"(p3), [p2] "r"(p2), [p1] "r"(p1), - [s2] "r"(s2)); - - __asm__ __volatile__( - "srl %[p4], %[p4], 8 \n\t" - "srl %[p3], %[p3], 8 \n\t" - "srl %[p2], %[p2], 8 \n\t" - "srl %[p1], %[p1], 8 \n\t" - - : [p4] "+r"(p4), [p3] "+r"(p3), [p2] "+r"(p2), [p1] "+r"(p1) - :); - - __asm__ __volatile__( - "sb %[p4], 1(%[s1]) \n\t" - "sb %[p3], 0(%[s1]) \n\t" - "sb %[p2], -1(%[s1]) \n\t" - "sb %[p1], -2(%[s1]) \n\t" - - : - : [p4] "r"(p4), [p3] "r"(p3), [p2] "r"(p2), [p1] "r"(p1), - [s1] "r"(s1)); - } - } - } -} - -void vpx_lpf_horizontal_4_dual_dspr2( - uint8_t *s, int p /* pitch */, const uint8_t *blimit0, - const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, - const uint8_t *limit1, const uint8_t *thresh1) { - vpx_lpf_horizontal_4_dspr2(s, p, blimit0, limit0, thresh0); - vpx_lpf_horizontal_4_dspr2(s + 8, p, blimit1, limit1, thresh1); -} - -void vpx_lpf_horizontal_8_dual_dspr2( - uint8_t *s, int p /* pitch */, const uint8_t *blimit0, - const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, - const uint8_t *limit1, const uint8_t *thresh1) { - vpx_lpf_horizontal_8_dspr2(s, p, blimit0, limit0, thresh0); - vpx_lpf_horizontal_8_dspr2(s + 8, p, blimit1, limit1, thresh1); -} - -void vpx_lpf_vertical_4_dual_dspr2(uint8_t *s, int p, const uint8_t *blimit0, - const uint8_t *limit0, - const uint8_t *thresh0, - const uint8_t *blimit1, - const uint8_t *limit1, - const uint8_t *thresh1) { - vpx_lpf_vertical_4_dspr2(s, p, blimit0, limit0, thresh0); - vpx_lpf_vertical_4_dspr2(s + 8 * p, p, blimit1, limit1, thresh1); -} - -void vpx_lpf_vertical_8_dual_dspr2(uint8_t *s, int p, const uint8_t *blimit0, - const uint8_t *limit0, - const uint8_t *thresh0, - const uint8_t *blimit1, - const uint8_t *limit1, - const uint8_t *thresh1) { - vpx_lpf_vertical_8_dspr2(s, p, blimit0, limit0, thresh0); - vpx_lpf_vertical_8_dspr2(s + 8 * p, p, blimit1, limit1, thresh1); -} - -void vpx_lpf_vertical_16_dual_dspr2(uint8_t *s, int p, const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh) { - vpx_lpf_vertical_16_dspr2(s, p, blimit, limit, thresh); - vpx_lpf_vertical_16_dspr2(s + 8 * p, p, blimit, limit, thresh); -} -#endif // #if HAVE_DSPR2 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_filters_dspr2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_filters_dspr2.h deleted file mode 100644 index ec339be8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_filters_dspr2.h +++ /dev/null @@ -1,734 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_MIPS_LOOPFILTER_FILTERS_DSPR2_H_ -#define VPX_VPX_DSP_MIPS_LOOPFILTER_FILTERS_DSPR2_H_ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if HAVE_DSPR2 -/* inputs & outputs are quad-byte vectors */ -static INLINE void filter_dspr2(uint32_t mask, uint32_t hev, uint32_t *ps1, - uint32_t *ps0, uint32_t *qs0, uint32_t *qs1) { - int32_t vpx_filter_l, vpx_filter_r; - int32_t Filter1_l, Filter1_r, Filter2_l, Filter2_r; - int32_t subr_r, subr_l; - uint32_t t1, t2, HWM, t3; - uint32_t hev_l, hev_r, mask_l, mask_r, invhev_l, invhev_r; - int32_t vps1, vps0, vqs0, vqs1; - int32_t vps1_l, vps1_r, vps0_l, vps0_r, vqs0_l, vqs0_r, vqs1_l, vqs1_r; - uint32_t N128; - - N128 = 0x80808080; - t1 = 0x03000300; - t2 = 0x04000400; - t3 = 0x01000100; - HWM = 0xFF00FF00; - - vps0 = (*ps0) ^ N128; - vps1 = (*ps1) ^ N128; - vqs0 = (*qs0) ^ N128; - vqs1 = (*qs1) ^ N128; - - /* use halfword pairs instead quad-bytes because of accuracy */ - vps0_l = vps0 & HWM; - vps0_r = vps0 << 8; - vps0_r = vps0_r & HWM; - - vps1_l = vps1 & HWM; - vps1_r = vps1 << 8; - vps1_r = vps1_r & HWM; - - vqs0_l = vqs0 & HWM; - vqs0_r = vqs0 << 8; - vqs0_r = vqs0_r & HWM; - - vqs1_l = vqs1 & HWM; - vqs1_r = vqs1 << 8; - vqs1_r = vqs1_r & HWM; - - mask_l = mask & HWM; - mask_r = mask << 8; - mask_r = mask_r & HWM; - - hev_l = hev & HWM; - hev_r = hev << 8; - hev_r = hev_r & HWM; - - __asm__ __volatile__( - /* vpx_filter = vp8_signed_char_clamp(ps1 - qs1); */ - "subq_s.ph %[vpx_filter_l], %[vps1_l], %[vqs1_l] \n\t" - "subq_s.ph %[vpx_filter_r], %[vps1_r], %[vqs1_r] \n\t" - - /* qs0 - ps0 */ - "subq_s.ph %[subr_l], %[vqs0_l], %[vps0_l] \n\t" - "subq_s.ph %[subr_r], %[vqs0_r], %[vps0_r] \n\t" - - /* vpx_filter &= hev; */ - "and %[vpx_filter_l], %[vpx_filter_l], %[hev_l] \n\t" - "and %[vpx_filter_r], %[vpx_filter_r], %[hev_r] \n\t" - - /* vpx_filter = vp8_signed_char_clamp(vpx_filter + 3 * (qs0 - ps0)); */ - "addq_s.ph %[vpx_filter_l], %[vpx_filter_l], %[subr_l] \n\t" - "addq_s.ph %[vpx_filter_r], %[vpx_filter_r], %[subr_r] \n\t" - "xor %[invhev_l], %[hev_l], %[HWM] \n\t" - "addq_s.ph %[vpx_filter_l], %[vpx_filter_l], %[subr_l] \n\t" - "addq_s.ph %[vpx_filter_r], %[vpx_filter_r], %[subr_r] \n\t" - "xor %[invhev_r], %[hev_r], %[HWM] \n\t" - "addq_s.ph %[vpx_filter_l], %[vpx_filter_l], %[subr_l] \n\t" - "addq_s.ph %[vpx_filter_r], %[vpx_filter_r], %[subr_r] \n\t" - - /* vpx_filter &= mask; */ - "and %[vpx_filter_l], %[vpx_filter_l], %[mask_l] \n\t" - "and %[vpx_filter_r], %[vpx_filter_r], %[mask_r] \n\t" - - : [vpx_filter_l] "=&r"(vpx_filter_l), [vpx_filter_r] "=&r"(vpx_filter_r), - [subr_l] "=&r"(subr_l), [subr_r] "=&r"(subr_r), - [invhev_l] "=&r"(invhev_l), [invhev_r] "=&r"(invhev_r) - : [vps0_l] "r"(vps0_l), [vps0_r] "r"(vps0_r), [vps1_l] "r"(vps1_l), - [vps1_r] "r"(vps1_r), [vqs0_l] "r"(vqs0_l), [vqs0_r] "r"(vqs0_r), - [vqs1_l] "r"(vqs1_l), [vqs1_r] "r"(vqs1_r), [mask_l] "r"(mask_l), - [mask_r] "r"(mask_r), [hev_l] "r"(hev_l), [hev_r] "r"(hev_r), - [HWM] "r"(HWM)); - - /* save bottom 3 bits so that we round one side +4 and the other +3 */ - __asm__ __volatile__( - /* Filter2 = vp8_signed_char_clamp(vpx_filter + 3) >>= 3; */ - "addq_s.ph %[Filter1_l], %[vpx_filter_l], %[t2] \n\t" - "addq_s.ph %[Filter1_r], %[vpx_filter_r], %[t2] \n\t" - - /* Filter1 = vp8_signed_char_clamp(vpx_filter + 4) >>= 3; */ - "addq_s.ph %[Filter2_l], %[vpx_filter_l], %[t1] \n\t" - "addq_s.ph %[Filter2_r], %[vpx_filter_r], %[t1] \n\t" - "shra.ph %[Filter1_r], %[Filter1_r], 3 \n\t" - "shra.ph %[Filter1_l], %[Filter1_l], 3 \n\t" - - "shra.ph %[Filter2_l], %[Filter2_l], 3 \n\t" - "shra.ph %[Filter2_r], %[Filter2_r], 3 \n\t" - - "and %[Filter1_l], %[Filter1_l], %[HWM] \n\t" - "and %[Filter1_r], %[Filter1_r], %[HWM] \n\t" - - /* vps0 = vp8_signed_char_clamp(ps0 + Filter2); */ - "addq_s.ph %[vps0_l], %[vps0_l], %[Filter2_l] \n\t" - "addq_s.ph %[vps0_r], %[vps0_r], %[Filter2_r] \n\t" - - /* vqs0 = vp8_signed_char_clamp(qs0 - Filter1); */ - "subq_s.ph %[vqs0_l], %[vqs0_l], %[Filter1_l] \n\t" - "subq_s.ph %[vqs0_r], %[vqs0_r], %[Filter1_r] \n\t" - - : [Filter1_l] "=&r"(Filter1_l), [Filter1_r] "=&r"(Filter1_r), - [Filter2_l] "=&r"(Filter2_l), [Filter2_r] "=&r"(Filter2_r), - [vps0_l] "+r"(vps0_l), [vps0_r] "+r"(vps0_r), [vqs0_l] "+r"(vqs0_l), - [vqs0_r] "+r"(vqs0_r) - : [t1] "r"(t1), [t2] "r"(t2), [HWM] "r"(HWM), - [vpx_filter_l] "r"(vpx_filter_l), [vpx_filter_r] "r"(vpx_filter_r)); - - __asm__ __volatile__( - /* (vpx_filter += 1) >>= 1 */ - "addqh.ph %[Filter1_l], %[Filter1_l], %[t3] \n\t" - "addqh.ph %[Filter1_r], %[Filter1_r], %[t3] \n\t" - - /* vpx_filter &= ~hev; */ - "and %[Filter1_l], %[Filter1_l], %[invhev_l] \n\t" - "and %[Filter1_r], %[Filter1_r], %[invhev_r] \n\t" - - /* vps1 = vp8_signed_char_clamp(ps1 + vpx_filter); */ - "addq_s.ph %[vps1_l], %[vps1_l], %[Filter1_l] \n\t" - "addq_s.ph %[vps1_r], %[vps1_r], %[Filter1_r] \n\t" - - /* vqs1 = vp8_signed_char_clamp(qs1 - vpx_filter); */ - "subq_s.ph %[vqs1_l], %[vqs1_l], %[Filter1_l] \n\t" - "subq_s.ph %[vqs1_r], %[vqs1_r], %[Filter1_r] \n\t" - - : [Filter1_l] "+r"(Filter1_l), [Filter1_r] "+r"(Filter1_r), - [vps1_l] "+r"(vps1_l), [vps1_r] "+r"(vps1_r), [vqs1_l] "+r"(vqs1_l), - [vqs1_r] "+r"(vqs1_r) - : [t3] "r"(t3), [invhev_l] "r"(invhev_l), [invhev_r] "r"(invhev_r)); - - /* Create quad-bytes from halfword pairs */ - vqs0_l = vqs0_l & HWM; - vqs1_l = vqs1_l & HWM; - vps0_l = vps0_l & HWM; - vps1_l = vps1_l & HWM; - - __asm__ __volatile__( - "shrl.ph %[vqs0_r], %[vqs0_r], 8 \n\t" - "shrl.ph %[vps0_r], %[vps0_r], 8 \n\t" - "shrl.ph %[vqs1_r], %[vqs1_r], 8 \n\t" - "shrl.ph %[vps1_r], %[vps1_r], 8 \n\t" - - : [vps1_r] "+r"(vps1_r), [vqs1_r] "+r"(vqs1_r), [vps0_r] "+r"(vps0_r), - [vqs0_r] "+r"(vqs0_r) - :); - - vqs0 = vqs0_l | vqs0_r; - vqs1 = vqs1_l | vqs1_r; - vps0 = vps0_l | vps0_r; - vps1 = vps1_l | vps1_r; - - *ps0 = vps0 ^ N128; - *ps1 = vps1 ^ N128; - *qs0 = vqs0 ^ N128; - *qs1 = vqs1 ^ N128; -} - -static INLINE void filter1_dspr2(uint32_t mask, uint32_t hev, uint32_t ps1, - uint32_t ps0, uint32_t qs0, uint32_t qs1, - uint32_t *p1_f0, uint32_t *p0_f0, - uint32_t *q0_f0, uint32_t *q1_f0) { - int32_t vpx_filter_l, vpx_filter_r; - int32_t Filter1_l, Filter1_r, Filter2_l, Filter2_r; - int32_t subr_r, subr_l; - uint32_t t1, t2, HWM, t3; - uint32_t hev_l, hev_r, mask_l, mask_r, invhev_l, invhev_r; - int32_t vps1, vps0, vqs0, vqs1; - int32_t vps1_l, vps1_r, vps0_l, vps0_r, vqs0_l, vqs0_r, vqs1_l, vqs1_r; - uint32_t N128; - - N128 = 0x80808080; - t1 = 0x03000300; - t2 = 0x04000400; - t3 = 0x01000100; - HWM = 0xFF00FF00; - - vps0 = (ps0) ^ N128; - vps1 = (ps1) ^ N128; - vqs0 = (qs0) ^ N128; - vqs1 = (qs1) ^ N128; - - /* use halfword pairs instead quad-bytes because of accuracy */ - vps0_l = vps0 & HWM; - vps0_r = vps0 << 8; - vps0_r = vps0_r & HWM; - - vps1_l = vps1 & HWM; - vps1_r = vps1 << 8; - vps1_r = vps1_r & HWM; - - vqs0_l = vqs0 & HWM; - vqs0_r = vqs0 << 8; - vqs0_r = vqs0_r & HWM; - - vqs1_l = vqs1 & HWM; - vqs1_r = vqs1 << 8; - vqs1_r = vqs1_r & HWM; - - mask_l = mask & HWM; - mask_r = mask << 8; - mask_r = mask_r & HWM; - - hev_l = hev & HWM; - hev_r = hev << 8; - hev_r = hev_r & HWM; - - __asm__ __volatile__( - /* vpx_filter = vp8_signed_char_clamp(ps1 - qs1); */ - "subq_s.ph %[vpx_filter_l], %[vps1_l], %[vqs1_l] \n\t" - "subq_s.ph %[vpx_filter_r], %[vps1_r], %[vqs1_r] \n\t" - - /* qs0 - ps0 */ - "subq_s.ph %[subr_l], %[vqs0_l], %[vps0_l] \n\t" - "subq_s.ph %[subr_r], %[vqs0_r], %[vps0_r] \n\t" - - /* vpx_filter &= hev; */ - "and %[vpx_filter_l], %[vpx_filter_l], %[hev_l] \n\t" - "and %[vpx_filter_r], %[vpx_filter_r], %[hev_r] \n\t" - - /* vpx_filter = vp8_signed_char_clamp(vpx_filter + 3 * (qs0 - ps0)); */ - "addq_s.ph %[vpx_filter_l], %[vpx_filter_l], %[subr_l] \n\t" - "addq_s.ph %[vpx_filter_r], %[vpx_filter_r], %[subr_r] \n\t" - "xor %[invhev_l], %[hev_l], %[HWM] \n\t" - "addq_s.ph %[vpx_filter_l], %[vpx_filter_l], %[subr_l] \n\t" - "addq_s.ph %[vpx_filter_r], %[vpx_filter_r], %[subr_r] \n\t" - "xor %[invhev_r], %[hev_r], %[HWM] \n\t" - "addq_s.ph %[vpx_filter_l], %[vpx_filter_l], %[subr_l] \n\t" - "addq_s.ph %[vpx_filter_r], %[vpx_filter_r], %[subr_r] \n\t" - - /* vpx_filter &= mask; */ - "and %[vpx_filter_l], %[vpx_filter_l], %[mask_l] \n\t" - "and %[vpx_filter_r], %[vpx_filter_r], %[mask_r] \n\t" - - : [vpx_filter_l] "=&r"(vpx_filter_l), [vpx_filter_r] "=&r"(vpx_filter_r), - [subr_l] "=&r"(subr_l), [subr_r] "=&r"(subr_r), - [invhev_l] "=&r"(invhev_l), [invhev_r] "=&r"(invhev_r) - : [vps0_l] "r"(vps0_l), [vps0_r] "r"(vps0_r), [vps1_l] "r"(vps1_l), - [vps1_r] "r"(vps1_r), [vqs0_l] "r"(vqs0_l), [vqs0_r] "r"(vqs0_r), - [vqs1_l] "r"(vqs1_l), [vqs1_r] "r"(vqs1_r), [mask_l] "r"(mask_l), - [mask_r] "r"(mask_r), [hev_l] "r"(hev_l), [hev_r] "r"(hev_r), - [HWM] "r"(HWM)); - - /* save bottom 3 bits so that we round one side +4 and the other +3 */ - __asm__ __volatile__( - /* Filter2 = vp8_signed_char_clamp(vpx_filter + 3) >>= 3; */ - "addq_s.ph %[Filter1_l], %[vpx_filter_l], %[t2] \n\t" - "addq_s.ph %[Filter1_r], %[vpx_filter_r], %[t2] \n\t" - - /* Filter1 = vp8_signed_char_clamp(vpx_filter + 4) >>= 3; */ - "addq_s.ph %[Filter2_l], %[vpx_filter_l], %[t1] \n\t" - "addq_s.ph %[Filter2_r], %[vpx_filter_r], %[t1] \n\t" - "shra.ph %[Filter1_r], %[Filter1_r], 3 \n\t" - "shra.ph %[Filter1_l], %[Filter1_l], 3 \n\t" - - "shra.ph %[Filter2_l], %[Filter2_l], 3 \n\t" - "shra.ph %[Filter2_r], %[Filter2_r], 3 \n\t" - - "and %[Filter1_l], %[Filter1_l], %[HWM] \n\t" - "and %[Filter1_r], %[Filter1_r], %[HWM] \n\t" - - /* vps0 = vp8_signed_char_clamp(ps0 + Filter2); */ - "addq_s.ph %[vps0_l], %[vps0_l], %[Filter2_l] \n\t" - "addq_s.ph %[vps0_r], %[vps0_r], %[Filter2_r] \n\t" - - /* vqs0 = vp8_signed_char_clamp(qs0 - Filter1); */ - "subq_s.ph %[vqs0_l], %[vqs0_l], %[Filter1_l] \n\t" - "subq_s.ph %[vqs0_r], %[vqs0_r], %[Filter1_r] \n\t" - - : [Filter1_l] "=&r"(Filter1_l), [Filter1_r] "=&r"(Filter1_r), - [Filter2_l] "=&r"(Filter2_l), [Filter2_r] "=&r"(Filter2_r), - [vps0_l] "+r"(vps0_l), [vps0_r] "+r"(vps0_r), [vqs0_l] "+r"(vqs0_l), - [vqs0_r] "+r"(vqs0_r) - : [t1] "r"(t1), [t2] "r"(t2), [HWM] "r"(HWM), - [vpx_filter_l] "r"(vpx_filter_l), [vpx_filter_r] "r"(vpx_filter_r)); - - __asm__ __volatile__( - /* (vpx_filter += 1) >>= 1 */ - "addqh.ph %[Filter1_l], %[Filter1_l], %[t3] \n\t" - "addqh.ph %[Filter1_r], %[Filter1_r], %[t3] \n\t" - - /* vpx_filter &= ~hev; */ - "and %[Filter1_l], %[Filter1_l], %[invhev_l] \n\t" - "and %[Filter1_r], %[Filter1_r], %[invhev_r] \n\t" - - /* vps1 = vp8_signed_char_clamp(ps1 + vpx_filter); */ - "addq_s.ph %[vps1_l], %[vps1_l], %[Filter1_l] \n\t" - "addq_s.ph %[vps1_r], %[vps1_r], %[Filter1_r] \n\t" - - /* vqs1 = vp8_signed_char_clamp(qs1 - vpx_filter); */ - "subq_s.ph %[vqs1_l], %[vqs1_l], %[Filter1_l] \n\t" - "subq_s.ph %[vqs1_r], %[vqs1_r], %[Filter1_r] \n\t" - - : [Filter1_l] "+r"(Filter1_l), [Filter1_r] "+r"(Filter1_r), - [vps1_l] "+r"(vps1_l), [vps1_r] "+r"(vps1_r), [vqs1_l] "+r"(vqs1_l), - [vqs1_r] "+r"(vqs1_r) - : [t3] "r"(t3), [invhev_l] "r"(invhev_l), [invhev_r] "r"(invhev_r)); - - /* Create quad-bytes from halfword pairs */ - vqs0_l = vqs0_l & HWM; - vqs1_l = vqs1_l & HWM; - vps0_l = vps0_l & HWM; - vps1_l = vps1_l & HWM; - - __asm__ __volatile__( - "shrl.ph %[vqs0_r], %[vqs0_r], 8 \n\t" - "shrl.ph %[vps0_r], %[vps0_r], 8 \n\t" - "shrl.ph %[vqs1_r], %[vqs1_r], 8 \n\t" - "shrl.ph %[vps1_r], %[vps1_r], 8 \n\t" - - : [vps1_r] "+r"(vps1_r), [vqs1_r] "+r"(vqs1_r), [vps0_r] "+r"(vps0_r), - [vqs0_r] "+r"(vqs0_r) - :); - - vqs0 = vqs0_l | vqs0_r; - vqs1 = vqs1_l | vqs1_r; - vps0 = vps0_l | vps0_r; - vps1 = vps1_l | vps1_r; - - *p0_f0 = vps0 ^ N128; - *p1_f0 = vps1 ^ N128; - *q0_f0 = vqs0 ^ N128; - *q1_f0 = vqs1 ^ N128; -} - -static INLINE void mbfilter_dspr2(uint32_t *op3, uint32_t *op2, uint32_t *op1, - uint32_t *op0, uint32_t *oq0, uint32_t *oq1, - uint32_t *oq2, uint32_t *oq3) { - /* use a 7 tap filter [1, 1, 1, 2, 1, 1, 1] for flat line */ - const uint32_t p3 = *op3, p2 = *op2, p1 = *op1, p0 = *op0; - const uint32_t q0 = *oq0, q1 = *oq1, q2 = *oq2, q3 = *oq3; - uint32_t res_op2, res_op1, res_op0; - uint32_t res_oq0, res_oq1, res_oq2; - uint32_t tmp; - uint32_t add_p210_q012; - uint32_t u32Four = 0x00040004; - - /* *op2 = ROUND_POWER_OF_TWO(p3 + p3 + p3 + p2 + p2 + p1 + p0 + q0, 3) 1 */ - /* *op1 = ROUND_POWER_OF_TWO(p3 + p3 + p2 + p1 + p1 + p0 + q0 + q1, 3) 2 */ - /* *op0 = ROUND_POWER_OF_TWO(p3 + p2 + p1 + p0 + p0 + q0 + q1 + q2, 3) 3 */ - /* *oq0 = ROUND_POWER_OF_TWO(p2 + p1 + p0 + q0 + q0 + q1 + q2 + q3, 3) 4 */ - /* *oq1 = ROUND_POWER_OF_TWO(p1 + p0 + q0 + q1 + q1 + q2 + q3 + q3, 3) 5 */ - /* *oq2 = ROUND_POWER_OF_TWO(p0 + q0 + q1 + q2 + q2 + q3 + q3 + q3, 3) 6 */ - - __asm__ __volatile__( - "addu.ph %[add_p210_q012], %[p2], %[p1] \n\t" - "addu.ph %[add_p210_q012], %[add_p210_q012], %[p0] \n\t" - "addu.ph %[add_p210_q012], %[add_p210_q012], %[q0] \n\t" - "addu.ph %[add_p210_q012], %[add_p210_q012], %[q1] \n\t" - "addu.ph %[add_p210_q012], %[add_p210_q012], %[q2] \n\t" - "addu.ph %[add_p210_q012], %[add_p210_q012], %[u32Four] \n\t" - - "shll.ph %[tmp], %[p3], 1 \n\t" - "addu.ph %[res_op2], %[tmp], %[p3] \n\t" - "addu.ph %[res_op1], %[p3], %[p3] \n\t" - "addu.ph %[res_op2], %[res_op2], %[p2] \n\t" - "addu.ph %[res_op1], %[res_op1], %[p1] \n\t" - "addu.ph %[res_op2], %[res_op2], %[add_p210_q012] \n\t" - "addu.ph %[res_op1], %[res_op1], %[add_p210_q012] \n\t" - "subu.ph %[res_op2], %[res_op2], %[q1] \n\t" - "subu.ph %[res_op1], %[res_op1], %[q2] \n\t" - "subu.ph %[res_op2], %[res_op2], %[q2] \n\t" - "shrl.ph %[res_op1], %[res_op1], 3 \n\t" - "shrl.ph %[res_op2], %[res_op2], 3 \n\t" - "addu.ph %[res_op0], %[p3], %[p0] \n\t" - "addu.ph %[res_oq0], %[q0], %[q3] \n\t" - "addu.ph %[res_op0], %[res_op0], %[add_p210_q012] \n\t" - "addu.ph %[res_oq0], %[res_oq0], %[add_p210_q012] \n\t" - "addu.ph %[res_oq1], %[q3], %[q3] \n\t" - "shll.ph %[tmp], %[q3], 1 \n\t" - "addu.ph %[res_oq1], %[res_oq1], %[q1] \n\t" - "addu.ph %[res_oq2], %[tmp], %[q3] \n\t" - "addu.ph %[res_oq1], %[res_oq1], %[add_p210_q012] \n\t" - "addu.ph %[res_oq2], %[res_oq2], %[add_p210_q012] \n\t" - "subu.ph %[res_oq1], %[res_oq1], %[p2] \n\t" - "addu.ph %[res_oq2], %[res_oq2], %[q2] \n\t" - "shrl.ph %[res_oq1], %[res_oq1], 3 \n\t" - "subu.ph %[res_oq2], %[res_oq2], %[p2] \n\t" - "shrl.ph %[res_oq0], %[res_oq0], 3 \n\t" - "subu.ph %[res_oq2], %[res_oq2], %[p1] \n\t" - "shrl.ph %[res_op0], %[res_op0], 3 \n\t" - "shrl.ph %[res_oq2], %[res_oq2], 3 \n\t" - - : [add_p210_q012] "=&r"(add_p210_q012), [tmp] "=&r"(tmp), - [res_op2] "=&r"(res_op2), [res_op1] "=&r"(res_op1), - [res_op0] "=&r"(res_op0), [res_oq0] "=&r"(res_oq0), - [res_oq1] "=&r"(res_oq1), [res_oq2] "=&r"(res_oq2) - : [p0] "r"(p0), [q0] "r"(q0), [p1] "r"(p1), [q1] "r"(q1), [p2] "r"(p2), - [q2] "r"(q2), [p3] "r"(p3), [q3] "r"(q3), [u32Four] "r"(u32Four)); - - *op2 = res_op2; - *op1 = res_op1; - *op0 = res_op0; - *oq0 = res_oq0; - *oq1 = res_oq1; - *oq2 = res_oq2; -} - -static INLINE void mbfilter1_dspr2(uint32_t p3, uint32_t p2, uint32_t p1, - uint32_t p0, uint32_t q0, uint32_t q1, - uint32_t q2, uint32_t q3, uint32_t *op2_f1, - uint32_t *op1_f1, uint32_t *op0_f1, - uint32_t *oq0_f1, uint32_t *oq1_f1, - uint32_t *oq2_f1) { - /* use a 7 tap filter [1, 1, 1, 2, 1, 1, 1] for flat line */ - uint32_t res_op2, res_op1, res_op0; - uint32_t res_oq0, res_oq1, res_oq2; - uint32_t tmp; - uint32_t add_p210_q012; - uint32_t u32Four = 0x00040004; - - /* *op2 = ROUND_POWER_OF_TWO(p3 + p3 + p3 + p2 + p2 + p1 + p0 + q0, 3) 1 */ - /* *op1 = ROUND_POWER_OF_TWO(p3 + p3 + p2 + p1 + p1 + p0 + q0 + q1, 3) 2 */ - /* *op0 = ROUND_POWER_OF_TWO(p3 + p2 + p1 + p0 + p0 + q0 + q1 + q2, 3) 3 */ - /* *oq0 = ROUND_POWER_OF_TWO(p2 + p1 + p0 + q0 + q0 + q1 + q2 + q3, 3) 4 */ - /* *oq1 = ROUND_POWER_OF_TWO(p1 + p0 + q0 + q1 + q1 + q2 + q3 + q3, 3) 5 */ - /* *oq2 = ROUND_POWER_OF_TWO(p0 + q0 + q1 + q2 + q2 + q3 + q3 + q3, 3) 6 */ - - __asm__ __volatile__( - "addu.ph %[add_p210_q012], %[p2], %[p1] \n\t" - "addu.ph %[add_p210_q012], %[add_p210_q012], %[p0] \n\t" - "addu.ph %[add_p210_q012], %[add_p210_q012], %[q0] \n\t" - "addu.ph %[add_p210_q012], %[add_p210_q012], %[q1] \n\t" - "addu.ph %[add_p210_q012], %[add_p210_q012], %[q2] \n\t" - "addu.ph %[add_p210_q012], %[add_p210_q012], %[u32Four] \n\t" - - "shll.ph %[tmp], %[p3], 1 \n\t" - "addu.ph %[res_op2], %[tmp], %[p3] \n\t" - "addu.ph %[res_op1], %[p3], %[p3] \n\t" - "addu.ph %[res_op2], %[res_op2], %[p2] \n\t" - "addu.ph %[res_op1], %[res_op1], %[p1] \n\t" - "addu.ph %[res_op2], %[res_op2], %[add_p210_q012] \n\t" - "addu.ph %[res_op1], %[res_op1], %[add_p210_q012] \n\t" - "subu.ph %[res_op2], %[res_op2], %[q1] \n\t" - "subu.ph %[res_op1], %[res_op1], %[q2] \n\t" - "subu.ph %[res_op2], %[res_op2], %[q2] \n\t" - "shrl.ph %[res_op1], %[res_op1], 3 \n\t" - "shrl.ph %[res_op2], %[res_op2], 3 \n\t" - "addu.ph %[res_op0], %[p3], %[p0] \n\t" - "addu.ph %[res_oq0], %[q0], %[q3] \n\t" - "addu.ph %[res_op0], %[res_op0], %[add_p210_q012] \n\t" - "addu.ph %[res_oq0], %[res_oq0], %[add_p210_q012] \n\t" - "addu.ph %[res_oq1], %[q3], %[q3] \n\t" - "shll.ph %[tmp], %[q3], 1 \n\t" - "addu.ph %[res_oq1], %[res_oq1], %[q1] \n\t" - "addu.ph %[res_oq2], %[tmp], %[q3] \n\t" - "addu.ph %[res_oq1], %[res_oq1], %[add_p210_q012] \n\t" - "addu.ph %[res_oq2], %[res_oq2], %[add_p210_q012] \n\t" - "subu.ph %[res_oq1], %[res_oq1], %[p2] \n\t" - "addu.ph %[res_oq2], %[res_oq2], %[q2] \n\t" - "shrl.ph %[res_oq1], %[res_oq1], 3 \n\t" - "subu.ph %[res_oq2], %[res_oq2], %[p2] \n\t" - "shrl.ph %[res_oq0], %[res_oq0], 3 \n\t" - "subu.ph %[res_oq2], %[res_oq2], %[p1] \n\t" - "shrl.ph %[res_op0], %[res_op0], 3 \n\t" - "shrl.ph %[res_oq2], %[res_oq2], 3 \n\t" - - : [add_p210_q012] "=&r"(add_p210_q012), [tmp] "=&r"(tmp), - [res_op2] "=&r"(res_op2), [res_op1] "=&r"(res_op1), - [res_op0] "=&r"(res_op0), [res_oq0] "=&r"(res_oq0), - [res_oq1] "=&r"(res_oq1), [res_oq2] "=&r"(res_oq2) - : [p0] "r"(p0), [q0] "r"(q0), [p1] "r"(p1), [q1] "r"(q1), [p2] "r"(p2), - [q2] "r"(q2), [p3] "r"(p3), [q3] "r"(q3), [u32Four] "r"(u32Four)); - - *op2_f1 = res_op2; - *op1_f1 = res_op1; - *op0_f1 = res_op0; - *oq0_f1 = res_oq0; - *oq1_f1 = res_oq1; - *oq2_f1 = res_oq2; -} - -static INLINE void wide_mbfilter_dspr2( - uint32_t *op7, uint32_t *op6, uint32_t *op5, uint32_t *op4, uint32_t *op3, - uint32_t *op2, uint32_t *op1, uint32_t *op0, uint32_t *oq0, uint32_t *oq1, - uint32_t *oq2, uint32_t *oq3, uint32_t *oq4, uint32_t *oq5, uint32_t *oq6, - uint32_t *oq7) { - const uint32_t p7 = *op7, p6 = *op6, p5 = *op5, p4 = *op4; - const uint32_t p3 = *op3, p2 = *op2, p1 = *op1, p0 = *op0; - const uint32_t q0 = *oq0, q1 = *oq1, q2 = *oq2, q3 = *oq3; - const uint32_t q4 = *oq4, q5 = *oq5, q6 = *oq6, q7 = *oq7; - uint32_t res_op6, res_op5, res_op4, res_op3, res_op2, res_op1, res_op0; - uint32_t res_oq0, res_oq1, res_oq2, res_oq3, res_oq4, res_oq5, res_oq6; - uint32_t tmp; - uint32_t add_p6toq6; - uint32_t u32Eight = 0x00080008; - - __asm__ __volatile__( - /* addition of p6,p5,p4,p3,p2,p1,p0,q0,q1,q2,q3,q4,q5,q6 - which is used most of the time */ - "addu.ph %[add_p6toq6], %[p6], %[p5] \n\t" - "addu.ph %[add_p6toq6], %[add_p6toq6], %[p4] \n\t" - "addu.ph %[add_p6toq6], %[add_p6toq6], %[p3] \n\t" - "addu.ph %[add_p6toq6], %[add_p6toq6], %[p2] \n\t" - "addu.ph %[add_p6toq6], %[add_p6toq6], %[p1] \n\t" - "addu.ph %[add_p6toq6], %[add_p6toq6], %[p0] \n\t" - "addu.ph %[add_p6toq6], %[add_p6toq6], %[q0] \n\t" - "addu.ph %[add_p6toq6], %[add_p6toq6], %[q1] \n\t" - "addu.ph %[add_p6toq6], %[add_p6toq6], %[q2] \n\t" - "addu.ph %[add_p6toq6], %[add_p6toq6], %[q3] \n\t" - "addu.ph %[add_p6toq6], %[add_p6toq6], %[q4] \n\t" - "addu.ph %[add_p6toq6], %[add_p6toq6], %[q5] \n\t" - "addu.ph %[add_p6toq6], %[add_p6toq6], %[q6] \n\t" - "addu.ph %[add_p6toq6], %[add_p6toq6], %[u32Eight] \n\t" - - : [add_p6toq6] "=&r"(add_p6toq6) - : [p6] "r"(p6), [p5] "r"(p5), [p4] "r"(p4), [p3] "r"(p3), [p2] "r"(p2), - [p1] "r"(p1), [p0] "r"(p0), [q0] "r"(q0), [q1] "r"(q1), [q2] "r"(q2), - [q3] "r"(q3), [q4] "r"(q4), [q5] "r"(q5), [q6] "r"(q6), - [u32Eight] "r"(u32Eight)); - - __asm__ __volatile__( - /* *op6 = ROUND_POWER_OF_TWO(p7 * 7 + p6 * 2 + p5 + p4 + - p3 + p2 + p1 + p0 + q0, 4) */ - "shll.ph %[tmp], %[p7], 3 \n\t" - "subu.ph %[res_op6], %[tmp], %[p7] \n\t" - "addu.ph %[res_op6], %[res_op6], %[p6] \n\t" - "addu.ph %[res_op6], %[res_op6], %[add_p6toq6] \n\t" - "subu.ph %[res_op6], %[res_op6], %[q1] \n\t" - "subu.ph %[res_op6], %[res_op6], %[q2] \n\t" - "subu.ph %[res_op6], %[res_op6], %[q3] \n\t" - "subu.ph %[res_op6], %[res_op6], %[q4] \n\t" - "subu.ph %[res_op6], %[res_op6], %[q5] \n\t" - "subu.ph %[res_op6], %[res_op6], %[q6] \n\t" - "shrl.ph %[res_op6], %[res_op6], 4 \n\t" - - /* *op5 = ROUND_POWER_OF_TWO(p7 * 6 + p6 + p5 * 2 + p4 + p3 + - p2 + p1 + p0 + q0 + q1, 4) */ - "shll.ph %[tmp], %[p7], 2 \n\t" - "addu.ph %[res_op5], %[tmp], %[p7] \n\t" - "addu.ph %[res_op5], %[res_op5], %[p7] \n\t" - "addu.ph %[res_op5], %[res_op5], %[p5] \n\t" - "addu.ph %[res_op5], %[res_op5], %[add_p6toq6] \n\t" - "subu.ph %[res_op5], %[res_op5], %[q2] \n\t" - "subu.ph %[res_op5], %[res_op5], %[q3] \n\t" - "subu.ph %[res_op5], %[res_op5], %[q4] \n\t" - "subu.ph %[res_op5], %[res_op5], %[q5] \n\t" - "subu.ph %[res_op5], %[res_op5], %[q6] \n\t" - "shrl.ph %[res_op5], %[res_op5], 4 \n\t" - - /* *op4 = ROUND_POWER_OF_TWO(p7 * 5 + p6 + p5 + p4 * 2 + p3 + p2 + - p1 + p0 + q0 + q1 + q2, 4) */ - "shll.ph %[tmp], %[p7], 2 \n\t" - "addu.ph %[res_op4], %[tmp], %[p7] \n\t" - "addu.ph %[res_op4], %[res_op4], %[p4] \n\t" - "addu.ph %[res_op4], %[res_op4], %[add_p6toq6] \n\t" - "subu.ph %[res_op4], %[res_op4], %[q3] \n\t" - "subu.ph %[res_op4], %[res_op4], %[q4] \n\t" - "subu.ph %[res_op4], %[res_op4], %[q5] \n\t" - "subu.ph %[res_op4], %[res_op4], %[q6] \n\t" - "shrl.ph %[res_op4], %[res_op4], 4 \n\t" - - /* *op3 = ROUND_POWER_OF_TWO(p7 * 4 + p6 + p5 + p4 + p3 * 2 + p2 + - p1 + p0 + q0 + q1 + q2 + q3, 4) */ - "shll.ph %[tmp], %[p7], 2 \n\t" - "addu.ph %[res_op3], %[tmp], %[p3] \n\t" - "addu.ph %[res_op3], %[res_op3], %[add_p6toq6] \n\t" - "subu.ph %[res_op3], %[res_op3], %[q4] \n\t" - "subu.ph %[res_op3], %[res_op3], %[q5] \n\t" - "subu.ph %[res_op3], %[res_op3], %[q6] \n\t" - "shrl.ph %[res_op3], %[res_op3], 4 \n\t" - - /* *op2 = ROUND_POWER_OF_TWO(p7 * 3 + p6 + p5 + p4 + p3 + p2 * 2 + p1 + - p0 + q0 + q1 + q2 + q3 + q4, 4) */ - "shll.ph %[tmp], %[p7], 1 \n\t" - "addu.ph %[res_op2], %[tmp], %[p7] \n\t" - "addu.ph %[res_op2], %[res_op2], %[p2] \n\t" - "addu.ph %[res_op2], %[res_op2], %[add_p6toq6] \n\t" - "subu.ph %[res_op2], %[res_op2], %[q5] \n\t" - "subu.ph %[res_op2], %[res_op2], %[q6] \n\t" - "shrl.ph %[res_op2], %[res_op2], 4 \n\t" - - /* *op1 = ROUND_POWER_OF_TWO(p7 * 2 + p6 + p5 + p4 + p3 + p2 + p1 * 2 + - p0 + q0 + q1 + q2 + q3 + q4 + q5, 4); */ - "shll.ph %[tmp], %[p7], 1 \n\t" - "addu.ph %[res_op1], %[tmp], %[p1] \n\t" - "addu.ph %[res_op1], %[res_op1], %[add_p6toq6] \n\t" - "subu.ph %[res_op1], %[res_op1], %[q6] \n\t" - "shrl.ph %[res_op1], %[res_op1], 4 \n\t" - - /* *op0 = ROUND_POWER_OF_TWO(p7 + p6 + p5 + p4 + p3 + p2 + p1 + p0 * 2 + - q0 + q1 + q2 + q3 + q4 + q5 + q6, 4) */ - "addu.ph %[res_op0], %[p7], %[p0] \n\t" - "addu.ph %[res_op0], %[res_op0], %[add_p6toq6] \n\t" - "shrl.ph %[res_op0], %[res_op0], 4 \n\t" - - : [res_op6] "=&r"(res_op6), [res_op5] "=&r"(res_op5), - [res_op4] "=&r"(res_op4), [res_op3] "=&r"(res_op3), - [res_op2] "=&r"(res_op2), [res_op1] "=&r"(res_op1), - [res_op0] "=&r"(res_op0), [tmp] "=&r"(tmp) - : [p7] "r"(p7), [p6] "r"(p6), [p5] "r"(p5), [p4] "r"(p4), [p3] "r"(p3), - [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0), [q2] "r"(q2), [q1] "r"(q1), - [q3] "r"(q3), [q4] "r"(q4), [q5] "r"(q5), [q6] "r"(q6), - [add_p6toq6] "r"(add_p6toq6)); - - *op6 = res_op6; - *op5 = res_op5; - *op4 = res_op4; - *op3 = res_op3; - *op2 = res_op2; - *op1 = res_op1; - *op0 = res_op0; - - __asm__ __volatile__( - /* *oq0 = ROUND_POWER_OF_TWO(p6 + p5 + p4 + p3 + p2 + p1 + p0 + q0 * 2 + - q1 + q2 + q3 + q4 + q5 + q6 + q7, 4); */ - "addu.ph %[res_oq0], %[q7], %[q0] \n\t" - "addu.ph %[res_oq0], %[res_oq0], %[add_p6toq6] \n\t" - "shrl.ph %[res_oq0], %[res_oq0], 4 \n\t" - - /* *oq1 = ROUND_POWER_OF_TWO(p5 + p4 + p3 + p2 + p1 + p0 + q0 + q1 * 2 + - q2 + q3 + q4 + q5 + q6 + q7 * 2, 4) */ - "shll.ph %[tmp], %[q7], 1 \n\t" - "addu.ph %[res_oq1], %[tmp], %[q1] \n\t" - "addu.ph %[res_oq1], %[res_oq1], %[add_p6toq6] \n\t" - "subu.ph %[res_oq1], %[res_oq1], %[p6] \n\t" - "shrl.ph %[res_oq1], %[res_oq1], 4 \n\t" - - /* *oq2 = ROUND_POWER_OF_TWO(p4 + p3 + p2 + p1 + p0 + q0 + q1 + q2 * 2 + - q3 + q4 + q5 + q6 + q7 * 3, 4) */ - "shll.ph %[tmp], %[q7], 1 \n\t" - "addu.ph %[res_oq2], %[tmp], %[q7] \n\t" - "addu.ph %[res_oq2], %[res_oq2], %[q2] \n\t" - "addu.ph %[res_oq2], %[res_oq2], %[add_p6toq6] \n\t" - "subu.ph %[res_oq2], %[res_oq2], %[p5] \n\t" - "subu.ph %[res_oq2], %[res_oq2], %[p6] \n\t" - "shrl.ph %[res_oq2], %[res_oq2], 4 \n\t" - - /* *oq3 = ROUND_POWER_OF_TWO(p3 + p2 + p1 + p0 + q0 + q1 + q2 + - q3 * 2 + q4 + q5 + q6 + q7 * 4, 4) */ - "shll.ph %[tmp], %[q7], 2 \n\t" - "addu.ph %[res_oq3], %[tmp], %[q3] \n\t" - "addu.ph %[res_oq3], %[res_oq3], %[add_p6toq6] \n\t" - "subu.ph %[res_oq3], %[res_oq3], %[p4] \n\t" - "subu.ph %[res_oq3], %[res_oq3], %[p5] \n\t" - "subu.ph %[res_oq3], %[res_oq3], %[p6] \n\t" - "shrl.ph %[res_oq3], %[res_oq3], 4 \n\t" - - /* *oq4 = ROUND_POWER_OF_TWO(p2 + p1 + p0 + q0 + q1 + q2 + q3 + - q4 * 2 + q5 + q6 + q7 * 5, 4) */ - "shll.ph %[tmp], %[q7], 2 \n\t" - "addu.ph %[res_oq4], %[tmp], %[q7] \n\t" - "addu.ph %[res_oq4], %[res_oq4], %[q4] \n\t" - "addu.ph %[res_oq4], %[res_oq4], %[add_p6toq6] \n\t" - "subu.ph %[res_oq4], %[res_oq4], %[p3] \n\t" - "subu.ph %[res_oq4], %[res_oq4], %[p4] \n\t" - "subu.ph %[res_oq4], %[res_oq4], %[p5] \n\t" - "subu.ph %[res_oq4], %[res_oq4], %[p6] \n\t" - "shrl.ph %[res_oq4], %[res_oq4], 4 \n\t" - - /* *oq5 = ROUND_POWER_OF_TWO(p1 + p0 + q0 + q1 + q2 + q3 + q4 + - q5 * 2 + q6 + q7 * 6, 4) */ - "shll.ph %[tmp], %[q7], 2 \n\t" - "addu.ph %[res_oq5], %[tmp], %[q7] \n\t" - "addu.ph %[res_oq5], %[res_oq5], %[q7] \n\t" - "addu.ph %[res_oq5], %[res_oq5], %[q5] \n\t" - "addu.ph %[res_oq5], %[res_oq5], %[add_p6toq6] \n\t" - "subu.ph %[res_oq5], %[res_oq5], %[p2] \n\t" - "subu.ph %[res_oq5], %[res_oq5], %[p3] \n\t" - "subu.ph %[res_oq5], %[res_oq5], %[p4] \n\t" - "subu.ph %[res_oq5], %[res_oq5], %[p5] \n\t" - "subu.ph %[res_oq5], %[res_oq5], %[p6] \n\t" - "shrl.ph %[res_oq5], %[res_oq5], 4 \n\t" - - /* *oq6 = ROUND_POWER_OF_TWO(p0 + q0 + q1 + q2 + q3 + - q4 + q5 + q6 * 2 + q7 * 7, 4) */ - "shll.ph %[tmp], %[q7], 3 \n\t" - "subu.ph %[res_oq6], %[tmp], %[q7] \n\t" - "addu.ph %[res_oq6], %[res_oq6], %[q6] \n\t" - "addu.ph %[res_oq6], %[res_oq6], %[add_p6toq6] \n\t" - "subu.ph %[res_oq6], %[res_oq6], %[p1] \n\t" - "subu.ph %[res_oq6], %[res_oq6], %[p2] \n\t" - "subu.ph %[res_oq6], %[res_oq6], %[p3] \n\t" - "subu.ph %[res_oq6], %[res_oq6], %[p4] \n\t" - "subu.ph %[res_oq6], %[res_oq6], %[p5] \n\t" - "subu.ph %[res_oq6], %[res_oq6], %[p6] \n\t" - "shrl.ph %[res_oq6], %[res_oq6], 4 \n\t" - - : [res_oq6] "=&r"(res_oq6), [res_oq5] "=&r"(res_oq5), - [res_oq4] "=&r"(res_oq4), [res_oq3] "=&r"(res_oq3), - [res_oq2] "=&r"(res_oq2), [res_oq1] "=&r"(res_oq1), - [res_oq0] "=&r"(res_oq0), [tmp] "=&r"(tmp) - : [q7] "r"(q7), [q6] "r"(q6), [q5] "r"(q5), [q4] "r"(q4), [q3] "r"(q3), - [q2] "r"(q2), [q1] "r"(q1), [q0] "r"(q0), [p1] "r"(p1), [p2] "r"(p2), - [p3] "r"(p3), [p4] "r"(p4), [p5] "r"(p5), [p6] "r"(p6), - [add_p6toq6] "r"(add_p6toq6)); - - *oq0 = res_oq0; - *oq1 = res_oq1; - *oq2 = res_oq2; - *oq3 = res_oq3; - *oq4 = res_oq4; - *oq5 = res_oq5; - *oq6 = res_oq6; -} -#endif // #if HAVE_DSPR2 -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_MIPS_LOOPFILTER_FILTERS_DSPR2_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_macros_dspr2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_macros_dspr2.h deleted file mode 100644 index 9af0b423..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_macros_dspr2.h +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_MIPS_LOOPFILTER_MACROS_DSPR2_H_ -#define VPX_VPX_DSP_MIPS_LOOPFILTER_MACROS_DSPR2_H_ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_mem/vpx_mem.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if HAVE_DSPR2 -#define STORE_F0() \ - { \ - __asm__ __volatile__( \ - "sb %[q1_f0], 1(%[s4]) \n\t" \ - "sb %[q0_f0], 0(%[s4]) \n\t" \ - "sb %[p0_f0], -1(%[s4]) \n\t" \ - "sb %[p1_f0], -2(%[s4]) \n\t" \ - \ - : \ - : [q1_f0] "r"(q1_f0), [q0_f0] "r"(q0_f0), [p0_f0] "r"(p0_f0), \ - [p1_f0] "r"(p1_f0), [s4] "r"(s4)); \ - \ - __asm__ __volatile__( \ - "srl %[q1_f0], %[q1_f0], 8 \n\t" \ - "srl %[q0_f0], %[q0_f0], 8 \n\t" \ - "srl %[p0_f0], %[p0_f0], 8 \n\t" \ - "srl %[p1_f0], %[p1_f0], 8 \n\t" \ - \ - : [q1_f0] "+r"(q1_f0), [q0_f0] "+r"(q0_f0), [p0_f0] "+r"(p0_f0), \ - [p1_f0] "+r"(p1_f0) \ - :); \ - \ - __asm__ __volatile__( \ - "sb %[q1_f0], 1(%[s3]) \n\t" \ - "sb %[q0_f0], 0(%[s3]) \n\t" \ - "sb %[p0_f0], -1(%[s3]) \n\t" \ - "sb %[p1_f0], -2(%[s3]) \n\t" \ - \ - : [p1_f0] "+r"(p1_f0) \ - : [q1_f0] "r"(q1_f0), [q0_f0] "r"(q0_f0), [s3] "r"(s3), \ - [p0_f0] "r"(p0_f0)); \ - \ - __asm__ __volatile__( \ - "srl %[q1_f0], %[q1_f0], 8 \n\t" \ - "srl %[q0_f0], %[q0_f0], 8 \n\t" \ - "srl %[p0_f0], %[p0_f0], 8 \n\t" \ - "srl %[p1_f0], %[p1_f0], 8 \n\t" \ - \ - : [q1_f0] "+r"(q1_f0), [q0_f0] "+r"(q0_f0), [p0_f0] "+r"(p0_f0), \ - [p1_f0] "+r"(p1_f0) \ - :); \ - \ - __asm__ __volatile__( \ - "sb %[q1_f0], 1(%[s2]) \n\t" \ - "sb %[q0_f0], 0(%[s2]) \n\t" \ - "sb %[p0_f0], -1(%[s2]) \n\t" \ - "sb %[p1_f0], -2(%[s2]) \n\t" \ - \ - : \ - : [q1_f0] "r"(q1_f0), [q0_f0] "r"(q0_f0), [p0_f0] "r"(p0_f0), \ - [p1_f0] "r"(p1_f0), [s2] "r"(s2)); \ - \ - __asm__ __volatile__( \ - "srl %[q1_f0], %[q1_f0], 8 \n\t" \ - "srl %[q0_f0], %[q0_f0], 8 \n\t" \ - "srl %[p0_f0], %[p0_f0], 8 \n\t" \ - "srl %[p1_f0], %[p1_f0], 8 \n\t" \ - \ - : [q1_f0] "+r"(q1_f0), [q0_f0] "+r"(q0_f0), [p0_f0] "+r"(p0_f0), \ - [p1_f0] "+r"(p1_f0) \ - :); \ - \ - __asm__ __volatile__( \ - "sb %[q1_f0], 1(%[s1]) \n\t" \ - "sb %[q0_f0], 0(%[s1]) \n\t" \ - "sb %[p0_f0], -1(%[s1]) \n\t" \ - "sb %[p1_f0], -2(%[s1]) \n\t" \ - \ - : \ - : [q1_f0] "r"(q1_f0), [q0_f0] "r"(q0_f0), [p0_f0] "r"(p0_f0), \ - [p1_f0] "r"(p1_f0), [s1] "r"(s1)); \ - } - -#define STORE_F1() \ - { \ - __asm__ __volatile__( \ - "sb %[q2_r], 2(%[s4]) \n\t" \ - "sb %[q1_r], 1(%[s4]) \n\t" \ - "sb %[q0_r], 0(%[s4]) \n\t" \ - "sb %[p0_r], -1(%[s4]) \n\t" \ - "sb %[p1_r], -2(%[s4]) \n\t" \ - "sb %[p2_r], -3(%[s4]) \n\t" \ - \ - : \ - : [q2_r] "r"(q2_r), [q1_r] "r"(q1_r), [q0_r] "r"(q0_r), \ - [p0_r] "r"(p0_r), [p1_r] "r"(p1_r), [p2_r] "r"(p2_r), [s4] "r"(s4)); \ - \ - __asm__ __volatile__( \ - "srl %[q2_r], %[q2_r], 16 \n\t" \ - "srl %[q1_r], %[q1_r], 16 \n\t" \ - "srl %[q0_r], %[q0_r], 16 \n\t" \ - "srl %[p0_r], %[p0_r], 16 \n\t" \ - "srl %[p1_r], %[p1_r], 16 \n\t" \ - "srl %[p2_r], %[p2_r], 16 \n\t" \ - \ - : [q2_r] "+r"(q2_r), [q1_r] "+r"(q1_r), [q0_r] "+r"(q0_r), \ - [p0_r] "+r"(p0_r), [p1_r] "+r"(p1_r), [p2_r] "+r"(p2_r) \ - :); \ - \ - __asm__ __volatile__( \ - "sb %[q2_r], 2(%[s3]) \n\t" \ - "sb %[q1_r], 1(%[s3]) \n\t" \ - "sb %[q0_r], 0(%[s3]) \n\t" \ - "sb %[p0_r], -1(%[s3]) \n\t" \ - "sb %[p1_r], -2(%[s3]) \n\t" \ - "sb %[p2_r], -3(%[s3]) \n\t" \ - \ - : \ - : [q2_r] "r"(q2_r), [q1_r] "r"(q1_r), [q0_r] "r"(q0_r), \ - [p0_r] "r"(p0_r), [p1_r] "r"(p1_r), [p2_r] "r"(p2_r), [s3] "r"(s3)); \ - \ - __asm__ __volatile__( \ - "sb %[q2_l], 2(%[s2]) \n\t" \ - "sb %[q1_l], 1(%[s2]) \n\t" \ - "sb %[q0_l], 0(%[s2]) \n\t" \ - "sb %[p0_l], -1(%[s2]) \n\t" \ - "sb %[p1_l], -2(%[s2]) \n\t" \ - "sb %[p2_l], -3(%[s2]) \n\t" \ - \ - : \ - : [q2_l] "r"(q2_l), [q1_l] "r"(q1_l), [q0_l] "r"(q0_l), \ - [p0_l] "r"(p0_l), [p1_l] "r"(p1_l), [p2_l] "r"(p2_l), [s2] "r"(s2)); \ - \ - __asm__ __volatile__( \ - "srl %[q2_l], %[q2_l], 16 \n\t" \ - "srl %[q1_l], %[q1_l], 16 \n\t" \ - "srl %[q0_l], %[q0_l], 16 \n\t" \ - "srl %[p0_l], %[p0_l], 16 \n\t" \ - "srl %[p1_l], %[p1_l], 16 \n\t" \ - "srl %[p2_l], %[p2_l], 16 \n\t" \ - \ - : [q2_l] "+r"(q2_l), [q1_l] "+r"(q1_l), [q0_l] "+r"(q0_l), \ - [p0_l] "+r"(p0_l), [p1_l] "+r"(p1_l), [p2_l] "+r"(p2_l) \ - :); \ - \ - __asm__ __volatile__( \ - "sb %[q2_l], 2(%[s1]) \n\t" \ - "sb %[q1_l], 1(%[s1]) \n\t" \ - "sb %[q0_l], 0(%[s1]) \n\t" \ - "sb %[p0_l], -1(%[s1]) \n\t" \ - "sb %[p1_l], -2(%[s1]) \n\t" \ - "sb %[p2_l], -3(%[s1]) \n\t" \ - \ - : \ - : [q2_l] "r"(q2_l), [q1_l] "r"(q1_l), [q0_l] "r"(q0_l), \ - [p0_l] "r"(p0_l), [p1_l] "r"(p1_l), [p2_l] "r"(p2_l), [s1] "r"(s1)); \ - } - -#define STORE_F2() \ - { \ - __asm__ __volatile__( \ - "sb %[q6_r], 6(%[s4]) \n\t" \ - "sb %[q5_r], 5(%[s4]) \n\t" \ - "sb %[q4_r], 4(%[s4]) \n\t" \ - "sb %[q3_r], 3(%[s4]) \n\t" \ - "sb %[q2_r], 2(%[s4]) \n\t" \ - "sb %[q1_r], 1(%[s4]) \n\t" \ - "sb %[q0_r], 0(%[s4]) \n\t" \ - "sb %[p0_r], -1(%[s4]) \n\t" \ - "sb %[p1_r], -2(%[s4]) \n\t" \ - "sb %[p2_r], -3(%[s4]) \n\t" \ - "sb %[p3_r], -4(%[s4]) \n\t" \ - "sb %[p4_r], -5(%[s4]) \n\t" \ - "sb %[p5_r], -6(%[s4]) \n\t" \ - "sb %[p6_r], -7(%[s4]) \n\t" \ - \ - : \ - : [q6_r] "r"(q6_r), [q5_r] "r"(q5_r), [q4_r] "r"(q4_r), \ - [q3_r] "r"(q3_r), [q2_r] "r"(q2_r), [q1_r] "r"(q1_r), \ - [q0_r] "r"(q0_r), [p0_r] "r"(p0_r), [p1_r] "r"(p1_r), \ - [p2_r] "r"(p2_r), [p3_r] "r"(p3_r), [p4_r] "r"(p4_r), \ - [p5_r] "r"(p5_r), [p6_r] "r"(p6_r), [s4] "r"(s4)); \ - \ - __asm__ __volatile__( \ - "srl %[q6_r], %[q6_r], 16 \n\t" \ - "srl %[q5_r], %[q5_r], 16 \n\t" \ - "srl %[q4_r], %[q4_r], 16 \n\t" \ - "srl %[q3_r], %[q3_r], 16 \n\t" \ - "srl %[q2_r], %[q2_r], 16 \n\t" \ - "srl %[q1_r], %[q1_r], 16 \n\t" \ - "srl %[q0_r], %[q0_r], 16 \n\t" \ - "srl %[p0_r], %[p0_r], 16 \n\t" \ - "srl %[p1_r], %[p1_r], 16 \n\t" \ - "srl %[p2_r], %[p2_r], 16 \n\t" \ - "srl %[p3_r], %[p3_r], 16 \n\t" \ - "srl %[p4_r], %[p4_r], 16 \n\t" \ - "srl %[p5_r], %[p5_r], 16 \n\t" \ - "srl %[p6_r], %[p6_r], 16 \n\t" \ - \ - : [q6_r] "+r"(q6_r), [q5_r] "+r"(q5_r), [q4_r] "+r"(q4_r), \ - [q3_r] "+r"(q3_r), [q2_r] "+r"(q2_r), [q1_r] "+r"(q1_r), \ - [q0_r] "+r"(q0_r), [p0_r] "+r"(p0_r), [p1_r] "+r"(p1_r), \ - [p2_r] "+r"(p2_r), [p3_r] "+r"(p3_r), [p4_r] "+r"(p4_r), \ - [p5_r] "+r"(p5_r), [p6_r] "+r"(p6_r) \ - :); \ - \ - __asm__ __volatile__( \ - "sb %[q6_r], 6(%[s3]) \n\t" \ - "sb %[q5_r], 5(%[s3]) \n\t" \ - "sb %[q4_r], 4(%[s3]) \n\t" \ - "sb %[q3_r], 3(%[s3]) \n\t" \ - "sb %[q2_r], 2(%[s3]) \n\t" \ - "sb %[q1_r], 1(%[s3]) \n\t" \ - "sb %[q0_r], 0(%[s3]) \n\t" \ - "sb %[p0_r], -1(%[s3]) \n\t" \ - "sb %[p1_r], -2(%[s3]) \n\t" \ - "sb %[p2_r], -3(%[s3]) \n\t" \ - "sb %[p3_r], -4(%[s3]) \n\t" \ - "sb %[p4_r], -5(%[s3]) \n\t" \ - "sb %[p5_r], -6(%[s3]) \n\t" \ - "sb %[p6_r], -7(%[s3]) \n\t" \ - \ - : \ - : [q6_r] "r"(q6_r), [q5_r] "r"(q5_r), [q4_r] "r"(q4_r), \ - [q3_r] "r"(q3_r), [q2_r] "r"(q2_r), [q1_r] "r"(q1_r), \ - [q0_r] "r"(q0_r), [p0_r] "r"(p0_r), [p1_r] "r"(p1_r), \ - [p2_r] "r"(p2_r), [p3_r] "r"(p3_r), [p4_r] "r"(p4_r), \ - [p5_r] "r"(p5_r), [p6_r] "r"(p6_r), [s3] "r"(s3)); \ - \ - __asm__ __volatile__( \ - "sb %[q6_l], 6(%[s2]) \n\t" \ - "sb %[q5_l], 5(%[s2]) \n\t" \ - "sb %[q4_l], 4(%[s2]) \n\t" \ - "sb %[q3_l], 3(%[s2]) \n\t" \ - "sb %[q2_l], 2(%[s2]) \n\t" \ - "sb %[q1_l], 1(%[s2]) \n\t" \ - "sb %[q0_l], 0(%[s2]) \n\t" \ - "sb %[p0_l], -1(%[s2]) \n\t" \ - "sb %[p1_l], -2(%[s2]) \n\t" \ - "sb %[p2_l], -3(%[s2]) \n\t" \ - "sb %[p3_l], -4(%[s2]) \n\t" \ - "sb %[p4_l], -5(%[s2]) \n\t" \ - "sb %[p5_l], -6(%[s2]) \n\t" \ - "sb %[p6_l], -7(%[s2]) \n\t" \ - \ - : \ - : [q6_l] "r"(q6_l), [q5_l] "r"(q5_l), [q4_l] "r"(q4_l), \ - [q3_l] "r"(q3_l), [q2_l] "r"(q2_l), [q1_l] "r"(q1_l), \ - [q0_l] "r"(q0_l), [p0_l] "r"(p0_l), [p1_l] "r"(p1_l), \ - [p2_l] "r"(p2_l), [p3_l] "r"(p3_l), [p4_l] "r"(p4_l), \ - [p5_l] "r"(p5_l), [p6_l] "r"(p6_l), [s2] "r"(s2)); \ - \ - __asm__ __volatile__( \ - "srl %[q6_l], %[q6_l], 16 \n\t" \ - "srl %[q5_l], %[q5_l], 16 \n\t" \ - "srl %[q4_l], %[q4_l], 16 \n\t" \ - "srl %[q3_l], %[q3_l], 16 \n\t" \ - "srl %[q2_l], %[q2_l], 16 \n\t" \ - "srl %[q1_l], %[q1_l], 16 \n\t" \ - "srl %[q0_l], %[q0_l], 16 \n\t" \ - "srl %[p0_l], %[p0_l], 16 \n\t" \ - "srl %[p1_l], %[p1_l], 16 \n\t" \ - "srl %[p2_l], %[p2_l], 16 \n\t" \ - "srl %[p3_l], %[p3_l], 16 \n\t" \ - "srl %[p4_l], %[p4_l], 16 \n\t" \ - "srl %[p5_l], %[p5_l], 16 \n\t" \ - "srl %[p6_l], %[p6_l], 16 \n\t" \ - \ - : [q6_l] "+r"(q6_l), [q5_l] "+r"(q5_l), [q4_l] "+r"(q4_l), \ - [q3_l] "+r"(q3_l), [q2_l] "+r"(q2_l), [q1_l] "+r"(q1_l), \ - [q0_l] "+r"(q0_l), [p0_l] "+r"(p0_l), [p1_l] "+r"(p1_l), \ - [p2_l] "+r"(p2_l), [p3_l] "+r"(p3_l), [p4_l] "+r"(p4_l), \ - [p5_l] "+r"(p5_l), [p6_l] "+r"(p6_l) \ - :); \ - \ - __asm__ __volatile__( \ - "sb %[q6_l], 6(%[s1]) \n\t" \ - "sb %[q5_l], 5(%[s1]) \n\t" \ - "sb %[q4_l], 4(%[s1]) \n\t" \ - "sb %[q3_l], 3(%[s1]) \n\t" \ - "sb %[q2_l], 2(%[s1]) \n\t" \ - "sb %[q1_l], 1(%[s1]) \n\t" \ - "sb %[q0_l], 0(%[s1]) \n\t" \ - "sb %[p0_l], -1(%[s1]) \n\t" \ - "sb %[p1_l], -2(%[s1]) \n\t" \ - "sb %[p2_l], -3(%[s1]) \n\t" \ - "sb %[p3_l], -4(%[s1]) \n\t" \ - "sb %[p4_l], -5(%[s1]) \n\t" \ - "sb %[p5_l], -6(%[s1]) \n\t" \ - "sb %[p6_l], -7(%[s1]) \n\t" \ - \ - : \ - : [q6_l] "r"(q6_l), [q5_l] "r"(q5_l), [q4_l] "r"(q4_l), \ - [q3_l] "r"(q3_l), [q2_l] "r"(q2_l), [q1_l] "r"(q1_l), \ - [q0_l] "r"(q0_l), [p0_l] "r"(p0_l), [p1_l] "r"(p1_l), \ - [p2_l] "r"(p2_l), [p3_l] "r"(p3_l), [p4_l] "r"(p4_l), \ - [p5_l] "r"(p5_l), [p6_l] "r"(p6_l), [s1] "r"(s1)); \ - } - -#define PACK_LEFT_0TO3() \ - { \ - __asm__ __volatile__( \ - "preceu.ph.qbl %[p3_l], %[p3] \n\t" \ - "preceu.ph.qbl %[p2_l], %[p2] \n\t" \ - "preceu.ph.qbl %[p1_l], %[p1] \n\t" \ - "preceu.ph.qbl %[p0_l], %[p0] \n\t" \ - "preceu.ph.qbl %[q0_l], %[q0] \n\t" \ - "preceu.ph.qbl %[q1_l], %[q1] \n\t" \ - "preceu.ph.qbl %[q2_l], %[q2] \n\t" \ - "preceu.ph.qbl %[q3_l], %[q3] \n\t" \ - \ - : [p3_l] "=&r"(p3_l), [p2_l] "=&r"(p2_l), [p1_l] "=&r"(p1_l), \ - [p0_l] "=&r"(p0_l), [q0_l] "=&r"(q0_l), [q1_l] "=&r"(q1_l), \ - [q2_l] "=&r"(q2_l), [q3_l] "=&r"(q3_l) \ - : [p3] "r"(p3), [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0), \ - [q0] "r"(q0), [q1] "r"(q1), [q2] "r"(q2), [q3] "r"(q3)); \ - } - -#define PACK_LEFT_4TO7() \ - { \ - __asm__ __volatile__( \ - "preceu.ph.qbl %[p7_l], %[p7] \n\t" \ - "preceu.ph.qbl %[p6_l], %[p6] \n\t" \ - "preceu.ph.qbl %[p5_l], %[p5] \n\t" \ - "preceu.ph.qbl %[p4_l], %[p4] \n\t" \ - "preceu.ph.qbl %[q4_l], %[q4] \n\t" \ - "preceu.ph.qbl %[q5_l], %[q5] \n\t" \ - "preceu.ph.qbl %[q6_l], %[q6] \n\t" \ - "preceu.ph.qbl %[q7_l], %[q7] \n\t" \ - \ - : [p7_l] "=&r"(p7_l), [p6_l] "=&r"(p6_l), [p5_l] "=&r"(p5_l), \ - [p4_l] "=&r"(p4_l), [q4_l] "=&r"(q4_l), [q5_l] "=&r"(q5_l), \ - [q6_l] "=&r"(q6_l), [q7_l] "=&r"(q7_l) \ - : [p7] "r"(p7), [p6] "r"(p6), [p5] "r"(p5), [p4] "r"(p4), \ - [q4] "r"(q4), [q5] "r"(q5), [q6] "r"(q6), [q7] "r"(q7)); \ - } - -#define PACK_RIGHT_0TO3() \ - { \ - __asm__ __volatile__( \ - "preceu.ph.qbr %[p3_r], %[p3] \n\t" \ - "preceu.ph.qbr %[p2_r], %[p2] \n\t" \ - "preceu.ph.qbr %[p1_r], %[p1] \n\t" \ - "preceu.ph.qbr %[p0_r], %[p0] \n\t" \ - "preceu.ph.qbr %[q0_r], %[q0] \n\t" \ - "preceu.ph.qbr %[q1_r], %[q1] \n\t" \ - "preceu.ph.qbr %[q2_r], %[q2] \n\t" \ - "preceu.ph.qbr %[q3_r], %[q3] \n\t" \ - \ - : [p3_r] "=&r"(p3_r), [p2_r] "=&r"(p2_r), [p1_r] "=&r"(p1_r), \ - [p0_r] "=&r"(p0_r), [q0_r] "=&r"(q0_r), [q1_r] "=&r"(q1_r), \ - [q2_r] "=&r"(q2_r), [q3_r] "=&r"(q3_r) \ - : [p3] "r"(p3), [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0), \ - [q0] "r"(q0), [q1] "r"(q1), [q2] "r"(q2), [q3] "r"(q3)); \ - } - -#define PACK_RIGHT_4TO7() \ - { \ - __asm__ __volatile__( \ - "preceu.ph.qbr %[p7_r], %[p7] \n\t" \ - "preceu.ph.qbr %[p6_r], %[p6] \n\t" \ - "preceu.ph.qbr %[p5_r], %[p5] \n\t" \ - "preceu.ph.qbr %[p4_r], %[p4] \n\t" \ - "preceu.ph.qbr %[q4_r], %[q4] \n\t" \ - "preceu.ph.qbr %[q5_r], %[q5] \n\t" \ - "preceu.ph.qbr %[q6_r], %[q6] \n\t" \ - "preceu.ph.qbr %[q7_r], %[q7] \n\t" \ - \ - : [p7_r] "=&r"(p7_r), [p6_r] "=&r"(p6_r), [p5_r] "=&r"(p5_r), \ - [p4_r] "=&r"(p4_r), [q4_r] "=&r"(q4_r), [q5_r] "=&r"(q5_r), \ - [q6_r] "=&r"(q6_r), [q7_r] "=&r"(q7_r) \ - : [p7] "r"(p7), [p6] "r"(p6), [p5] "r"(p5), [p4] "r"(p4), \ - [q4] "r"(q4), [q5] "r"(q5), [q6] "r"(q6), [q7] "r"(q7)); \ - } - -#define COMBINE_LEFT_RIGHT_0TO2() \ - { \ - __asm__ __volatile__( \ - "precr.qb.ph %[p2], %[p2_l], %[p2_r] \n\t" \ - "precr.qb.ph %[p1], %[p1_l], %[p1_r] \n\t" \ - "precr.qb.ph %[p0], %[p0_l], %[p0_r] \n\t" \ - "precr.qb.ph %[q0], %[q0_l], %[q0_r] \n\t" \ - "precr.qb.ph %[q1], %[q1_l], %[q1_r] \n\t" \ - "precr.qb.ph %[q2], %[q2_l], %[q2_r] \n\t" \ - \ - : [p2] "=&r"(p2), [p1] "=&r"(p1), [p0] "=&r"(p0), [q0] "=&r"(q0), \ - [q1] "=&r"(q1), [q2] "=&r"(q2) \ - : [p2_l] "r"(p2_l), [p2_r] "r"(p2_r), [p1_l] "r"(p1_l), \ - [p1_r] "r"(p1_r), [p0_l] "r"(p0_l), [p0_r] "r"(p0_r), \ - [q0_l] "r"(q0_l), [q0_r] "r"(q0_r), [q1_l] "r"(q1_l), \ - [q1_r] "r"(q1_r), [q2_l] "r"(q2_l), [q2_r] "r"(q2_r)); \ - } - -#define COMBINE_LEFT_RIGHT_3TO6() \ - { \ - __asm__ __volatile__( \ - "precr.qb.ph %[p6], %[p6_l], %[p6_r] \n\t" \ - "precr.qb.ph %[p5], %[p5_l], %[p5_r] \n\t" \ - "precr.qb.ph %[p4], %[p4_l], %[p4_r] \n\t" \ - "precr.qb.ph %[p3], %[p3_l], %[p3_r] \n\t" \ - "precr.qb.ph %[q3], %[q3_l], %[q3_r] \n\t" \ - "precr.qb.ph %[q4], %[q4_l], %[q4_r] \n\t" \ - "precr.qb.ph %[q5], %[q5_l], %[q5_r] \n\t" \ - "precr.qb.ph %[q6], %[q6_l], %[q6_r] \n\t" \ - \ - : [p6] "=&r"(p6), [p5] "=&r"(p5), [p4] "=&r"(p4), [p3] "=&r"(p3), \ - [q3] "=&r"(q3), [q4] "=&r"(q4), [q5] "=&r"(q5), [q6] "=&r"(q6) \ - : [p6_l] "r"(p6_l), [p5_l] "r"(p5_l), [p4_l] "r"(p4_l), \ - [p3_l] "r"(p3_l), [p6_r] "r"(p6_r), [p5_r] "r"(p5_r), \ - [p4_r] "r"(p4_r), [p3_r] "r"(p3_r), [q3_l] "r"(q3_l), \ - [q4_l] "r"(q4_l), [q5_l] "r"(q5_l), [q6_l] "r"(q6_l), \ - [q3_r] "r"(q3_r), [q4_r] "r"(q4_r), [q5_r] "r"(q5_r), \ - [q6_r] "r"(q6_r)); \ - } - -#endif // #if HAVE_DSPR2 -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_MIPS_LOOPFILTER_MACROS_DSPR2_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_masks_dspr2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_masks_dspr2.h deleted file mode 100644 index 24c492be..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_masks_dspr2.h +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_MIPS_LOOPFILTER_MASKS_DSPR2_H_ -#define VPX_VPX_DSP_MIPS_LOOPFILTER_MASKS_DSPR2_H_ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_mem/vpx_mem.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if HAVE_DSPR2 -/* processing 4 pixels at the same time - * compute hev and mask in the same function */ -static INLINE void filter_hev_mask_dspr2(uint32_t limit, uint32_t flimit, - uint32_t p1, uint32_t p0, uint32_t p3, - uint32_t p2, uint32_t q0, uint32_t q1, - uint32_t q2, uint32_t q3, - uint32_t thresh, uint32_t *hev, - uint32_t *mask) { - uint32_t c, r, r3, r_k; - uint32_t s1, s2, s3; - uint32_t ones = 0xFFFFFFFF; - uint32_t hev1; - - __asm__ __volatile__( - /* mask |= (abs(p3 - p2) > limit) */ - "subu_s.qb %[c], %[p3], %[p2] \n\t" - "subu_s.qb %[r_k], %[p2], %[p3] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], $0, %[c] \n\t" - - /* mask |= (abs(p2 - p1) > limit) */ - "subu_s.qb %[c], %[p2], %[p1] \n\t" - "subu_s.qb %[r_k], %[p1], %[p2] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], %[r], %[c] \n\t" - - /* mask |= (abs(p1 - p0) > limit) - * hev |= (abs(p1 - p0) > thresh) - */ - "subu_s.qb %[c], %[p1], %[p0] \n\t" - "subu_s.qb %[r_k], %[p0], %[p1] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[thresh], %[r_k] \n\t" - "or %[r3], $0, %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], %[r], %[c] \n\t" - - /* mask |= (abs(q1 - q0) > limit) - * hev |= (abs(q1 - q0) > thresh) - */ - "subu_s.qb %[c], %[q1], %[q0] \n\t" - "subu_s.qb %[r_k], %[q0], %[q1] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[thresh], %[r_k] \n\t" - "or %[r3], %[r3], %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], %[r], %[c] \n\t" - - /* mask |= (abs(q2 - q1) > limit) */ - "subu_s.qb %[c], %[q2], %[q1] \n\t" - "subu_s.qb %[r_k], %[q1], %[q2] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], %[r], %[c] \n\t" - "sll %[r3], %[r3], 24 \n\t" - - /* mask |= (abs(q3 - q2) > limit) */ - "subu_s.qb %[c], %[q3], %[q2] \n\t" - "subu_s.qb %[r_k], %[q2], %[q3] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], %[r], %[c] \n\t" - - : [c] "=&r"(c), [r_k] "=&r"(r_k), [r] "=&r"(r), [r3] "=&r"(r3) - : [limit] "r"(limit), [p3] "r"(p3), [p2] "r"(p2), [p1] "r"(p1), - [p0] "r"(p0), [q1] "r"(q1), [q0] "r"(q0), [q2] "r"(q2), [q3] "r"(q3), - [thresh] "r"(thresh)); - - __asm__ __volatile__( - /* abs(p0 - q0) */ - "subu_s.qb %[c], %[p0], %[q0] \n\t" - "subu_s.qb %[r_k], %[q0], %[p0] \n\t" - "wrdsp %[r3] \n\t" - "or %[s1], %[r_k], %[c] \n\t" - - /* abs(p1 - q1) */ - "subu_s.qb %[c], %[p1], %[q1] \n\t" - "addu_s.qb %[s3], %[s1], %[s1] \n\t" - "pick.qb %[hev1], %[ones], $0 \n\t" - "subu_s.qb %[r_k], %[q1], %[p1] \n\t" - "or %[s2], %[r_k], %[c] \n\t" - - /* abs(p0 - q0) * 2 + abs(p1 - q1) / 2 > flimit * 2 + limit */ - "shrl.qb %[s2], %[s2], 1 \n\t" - "addu_s.qb %[s1], %[s2], %[s3] \n\t" - "cmpgu.lt.qb %[c], %[flimit], %[s1] \n\t" - "or %[r], %[r], %[c] \n\t" - "sll %[r], %[r], 24 \n\t" - - "wrdsp %[r] \n\t" - "pick.qb %[s2], $0, %[ones] \n\t" - - : [c] "=&r"(c), [r_k] "=&r"(r_k), [s1] "=&r"(s1), [hev1] "=&r"(hev1), - [s2] "=&r"(s2), [r] "+r"(r), [s3] "=&r"(s3) - : [p0] "r"(p0), [q0] "r"(q0), [p1] "r"(p1), [r3] "r"(r3), [q1] "r"(q1), - [ones] "r"(ones), [flimit] "r"(flimit)); - - *hev = hev1; - *mask = s2; -} - -static INLINE void filter_hev_mask_flatmask4_dspr2( - uint32_t limit, uint32_t flimit, uint32_t thresh, uint32_t p1, uint32_t p0, - uint32_t p3, uint32_t p2, uint32_t q0, uint32_t q1, uint32_t q2, - uint32_t q3, uint32_t *hev, uint32_t *mask, uint32_t *flat) { - uint32_t c, r, r3, r_k, r_flat; - uint32_t s1, s2, s3; - uint32_t ones = 0xFFFFFFFF; - uint32_t flat_thresh = 0x01010101; - uint32_t hev1; - uint32_t flat1; - - __asm__ __volatile__( - /* mask |= (abs(p3 - p2) > limit) */ - "subu_s.qb %[c], %[p3], %[p2] \n\t" - "subu_s.qb %[r_k], %[p2], %[p3] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], $0, %[c] \n\t" - - /* mask |= (abs(p2 - p1) > limit) */ - "subu_s.qb %[c], %[p2], %[p1] \n\t" - "subu_s.qb %[r_k], %[p1], %[p2] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], %[r], %[c] \n\t" - - /* mask |= (abs(p1 - p0) > limit) - * hev |= (abs(p1 - p0) > thresh) - * flat |= (abs(p1 - p0) > thresh) - */ - "subu_s.qb %[c], %[p1], %[p0] \n\t" - "subu_s.qb %[r_k], %[p0], %[p1] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[thresh], %[r_k] \n\t" - "or %[r3], $0, %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], %[r], %[c] \n\t" - "cmpgu.lt.qb %[c], %[flat_thresh], %[r_k] \n\t" - "or %[r_flat], $0, %[c] \n\t" - - /* mask |= (abs(q1 - q0) > limit) - * hev |= (abs(q1 - q0) > thresh) - * flat |= (abs(q1 - q0) > thresh) - */ - "subu_s.qb %[c], %[q1], %[q0] \n\t" - "subu_s.qb %[r_k], %[q0], %[q1] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[thresh], %[r_k] \n\t" - "or %[r3], %[r3], %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], %[r], %[c] \n\t" - "cmpgu.lt.qb %[c], %[flat_thresh], %[r_k] \n\t" - "or %[r_flat], %[r_flat], %[c] \n\t" - - /* flat |= (abs(p0 - p2) > thresh) */ - "subu_s.qb %[c], %[p0], %[p2] \n\t" - "subu_s.qb %[r_k], %[p2], %[p0] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[flat_thresh], %[r_k] \n\t" - "or %[r_flat], %[r_flat], %[c] \n\t" - - /* flat |= (abs(q0 - q2) > thresh) */ - "subu_s.qb %[c], %[q0], %[q2] \n\t" - "subu_s.qb %[r_k], %[q2], %[q0] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[flat_thresh], %[r_k] \n\t" - "or %[r_flat], %[r_flat], %[c] \n\t" - - /* flat |= (abs(p3 - p0) > thresh) */ - "subu_s.qb %[c], %[p3], %[p0] \n\t" - "subu_s.qb %[r_k], %[p0], %[p3] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[flat_thresh], %[r_k] \n\t" - "or %[r_flat], %[r_flat], %[c] \n\t" - - /* flat |= (abs(q3 - q0) > thresh) */ - "subu_s.qb %[c], %[q3], %[q0] \n\t" - "subu_s.qb %[r_k], %[q0], %[q3] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[flat_thresh], %[r_k] \n\t" - "or %[r_flat], %[r_flat], %[c] \n\t" - "sll %[r_flat], %[r_flat], 24 \n\t" - /* look at stall here */ - "wrdsp %[r_flat] \n\t" - "pick.qb %[flat1], $0, %[ones] \n\t" - - /* mask |= (abs(q2 - q1) > limit) */ - "subu_s.qb %[c], %[q2], %[q1] \n\t" - "subu_s.qb %[r_k], %[q1], %[q2] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], %[r], %[c] \n\t" - "sll %[r3], %[r3], 24 \n\t" - - /* mask |= (abs(q3 - q2) > limit) */ - "subu_s.qb %[c], %[q3], %[q2] \n\t" - "subu_s.qb %[r_k], %[q2], %[q3] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[limit], %[r_k] \n\t" - "or %[r], %[r], %[c] \n\t" - - : [c] "=&r"(c), [r_k] "=&r"(r_k), [r] "=&r"(r), [r3] "=&r"(r3), - [r_flat] "=&r"(r_flat), [flat1] "=&r"(flat1) - : [limit] "r"(limit), [p3] "r"(p3), [p2] "r"(p2), [p1] "r"(p1), - [p0] "r"(p0), [q1] "r"(q1), [q0] "r"(q0), [q2] "r"(q2), [q3] "r"(q3), - [thresh] "r"(thresh), [flat_thresh] "r"(flat_thresh), [ones] "r"(ones)); - - __asm__ __volatile__( - /* abs(p0 - q0) */ - "subu_s.qb %[c], %[p0], %[q0] \n\t" - "subu_s.qb %[r_k], %[q0], %[p0] \n\t" - "wrdsp %[r3] \n\t" - "or %[s1], %[r_k], %[c] \n\t" - - /* abs(p1 - q1) */ - "subu_s.qb %[c], %[p1], %[q1] \n\t" - "addu_s.qb %[s3], %[s1], %[s1] \n\t" - "pick.qb %[hev1], %[ones], $0 \n\t" - "subu_s.qb %[r_k], %[q1], %[p1] \n\t" - "or %[s2], %[r_k], %[c] \n\t" - - /* abs(p0 - q0) * 2 + abs(p1 - q1) / 2 > flimit * 2 + limit */ - "shrl.qb %[s2], %[s2], 1 \n\t" - "addu_s.qb %[s1], %[s2], %[s3] \n\t" - "cmpgu.lt.qb %[c], %[flimit], %[s1] \n\t" - "or %[r], %[r], %[c] \n\t" - "sll %[r], %[r], 24 \n\t" - - "wrdsp %[r] \n\t" - "pick.qb %[s2], $0, %[ones] \n\t" - - : [c] "=&r"(c), [r_k] "=&r"(r_k), [s1] "=&r"(s1), [hev1] "=&r"(hev1), - [s2] "=&r"(s2), [r] "+r"(r), [s3] "=&r"(s3) - : [p0] "r"(p0), [q0] "r"(q0), [p1] "r"(p1), [r3] "r"(r3), [q1] "r"(q1), - [ones] "r"(ones), [flimit] "r"(flimit)); - - *hev = hev1; - *mask = s2; - *flat = flat1; -} - -static INLINE void flatmask5(uint32_t p4, uint32_t p3, uint32_t p2, uint32_t p1, - uint32_t p0, uint32_t q0, uint32_t q1, uint32_t q2, - uint32_t q3, uint32_t q4, uint32_t *flat2) { - uint32_t c, r, r_k, r_flat; - uint32_t ones = 0xFFFFFFFF; - uint32_t flat_thresh = 0x01010101; - uint32_t flat1, flat3; - - __asm__ __volatile__( - /* flat |= (abs(p4 - p0) > thresh) */ - "subu_s.qb %[c], %[p4], %[p0] \n\t" - "subu_s.qb %[r_k], %[p0], %[p4] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[flat_thresh], %[r_k] \n\t" - "or %[r], $0, %[c] \n\t" - - /* flat |= (abs(q4 - q0) > thresh) */ - "subu_s.qb %[c], %[q4], %[q0] \n\t" - "subu_s.qb %[r_k], %[q0], %[q4] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[flat_thresh], %[r_k] \n\t" - "or %[r], %[r], %[c] \n\t" - "sll %[r], %[r], 24 \n\t" - "wrdsp %[r] \n\t" - "pick.qb %[flat3], $0, %[ones] \n\t" - - /* flat |= (abs(p1 - p0) > thresh) */ - "subu_s.qb %[c], %[p1], %[p0] \n\t" - "subu_s.qb %[r_k], %[p0], %[p1] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[flat_thresh], %[r_k] \n\t" - "or %[r_flat], $0, %[c] \n\t" - - /* flat |= (abs(q1 - q0) > thresh) */ - "subu_s.qb %[c], %[q1], %[q0] \n\t" - "subu_s.qb %[r_k], %[q0], %[q1] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[flat_thresh], %[r_k] \n\t" - "or %[r_flat], %[r_flat], %[c] \n\t" - - /* flat |= (abs(p0 - p2) > thresh) */ - "subu_s.qb %[c], %[p0], %[p2] \n\t" - "subu_s.qb %[r_k], %[p2], %[p0] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[flat_thresh], %[r_k] \n\t" - "or %[r_flat], %[r_flat], %[c] \n\t" - - /* flat |= (abs(q0 - q2) > thresh) */ - "subu_s.qb %[c], %[q0], %[q2] \n\t" - "subu_s.qb %[r_k], %[q2], %[q0] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[flat_thresh], %[r_k] \n\t" - "or %[r_flat], %[r_flat], %[c] \n\t" - - /* flat |= (abs(p3 - p0) > thresh) */ - "subu_s.qb %[c], %[p3], %[p0] \n\t" - "subu_s.qb %[r_k], %[p0], %[p3] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[flat_thresh], %[r_k] \n\t" - "or %[r_flat], %[r_flat], %[c] \n\t" - - /* flat |= (abs(q3 - q0) > thresh) */ - "subu_s.qb %[c], %[q3], %[q0] \n\t" - "subu_s.qb %[r_k], %[q0], %[q3] \n\t" - "or %[r_k], %[r_k], %[c] \n\t" - "cmpgu.lt.qb %[c], %[flat_thresh], %[r_k] \n\t" - "or %[r_flat], %[r_flat], %[c] \n\t" - "sll %[r_flat], %[r_flat], 24 \n\t" - "wrdsp %[r_flat] \n\t" - "pick.qb %[flat1], $0, %[ones] \n\t" - /* flat & flatmask4(thresh, p3, p2, p1, p0, q0, q1, q2, q3) */ - "and %[flat1], %[flat3], %[flat1] \n\t" - - : [c] "=&r"(c), [r_k] "=&r"(r_k), [r] "=&r"(r), [r_flat] "=&r"(r_flat), - [flat1] "=&r"(flat1), [flat3] "=&r"(flat3) - : [p4] "r"(p4), [p3] "r"(p3), [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0), - [q0] "r"(q0), [q1] "r"(q1), [q2] "r"(q2), [q3] "r"(q3), [q4] "r"(q4), - [flat_thresh] "r"(flat_thresh), [ones] "r"(ones)); - - *flat2 = flat1; -} -#endif // #if HAVE_DSPR2 -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_MIPS_LOOPFILTER_MASKS_DSPR2_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_mb_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_mb_dspr2.c deleted file mode 100644 index e4247925..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_mb_dspr2.c +++ /dev/null @@ -1,588 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/mips/common_dspr2.h" -#include "vpx_dsp/mips/loopfilter_filters_dspr2.h" -#include "vpx_dsp/mips/loopfilter_macros_dspr2.h" -#include "vpx_dsp/mips/loopfilter_masks_dspr2.h" -#include "vpx_mem/vpx_mem.h" - -#if HAVE_DSPR2 -void vpx_lpf_horizontal_8_dspr2(unsigned char *s, int pitch, - const uint8_t *blimit, const uint8_t *limit, - const uint8_t *thresh) { - uint32_t mask; - uint32_t hev, flat; - uint8_t i; - uint8_t *sp3, *sp2, *sp1, *sp0, *sq0, *sq1, *sq2, *sq3; - uint32_t thresh_vec, flimit_vec, limit_vec; - uint32_t uflimit, ulimit, uthresh; - uint32_t p1_f0, p0_f0, q0_f0, q1_f0; - uint32_t p3, p2, p1, p0, q0, q1, q2, q3; - uint32_t p0_l, p1_l, p2_l, p3_l, q0_l, q1_l, q2_l, q3_l; - uint32_t p0_r, p1_r, p2_r, p3_r, q0_r, q1_r, q2_r, q3_r; - - uflimit = *blimit; - ulimit = *limit; - uthresh = *thresh; - - /* create quad-byte */ - __asm__ __volatile__( - "replv.qb %[thresh_vec], %[uthresh] \n\t" - "replv.qb %[flimit_vec], %[uflimit] \n\t" - "replv.qb %[limit_vec], %[ulimit] \n\t" - - : [thresh_vec] "=&r"(thresh_vec), [flimit_vec] "=&r"(flimit_vec), - [limit_vec] "=r"(limit_vec) - : [uthresh] "r"(uthresh), [uflimit] "r"(uflimit), [ulimit] "r"(ulimit)); - - /* prefetch data for store */ - prefetch_store(s); - - for (i = 0; i < 2; i++) { - sp3 = s - (pitch << 2); - sp2 = sp3 + pitch; - sp1 = sp2 + pitch; - sp0 = sp1 + pitch; - sq0 = s; - sq1 = s + pitch; - sq2 = sq1 + pitch; - sq3 = sq2 + pitch; - - __asm__ __volatile__( - "lw %[p3], (%[sp3]) \n\t" - "lw %[p2], (%[sp2]) \n\t" - "lw %[p1], (%[sp1]) \n\t" - "lw %[p0], (%[sp0]) \n\t" - "lw %[q0], (%[sq0]) \n\t" - "lw %[q1], (%[sq1]) \n\t" - "lw %[q2], (%[sq2]) \n\t" - "lw %[q3], (%[sq3]) \n\t" - - : [p3] "=&r"(p3), [p2] "=&r"(p2), [p1] "=&r"(p1), [p0] "=&r"(p0), - [q3] "=&r"(q3), [q2] "=&r"(q2), [q1] "=&r"(q1), [q0] "=&r"(q0) - : [sp3] "r"(sp3), [sp2] "r"(sp2), [sp1] "r"(sp1), [sp0] "r"(sp0), - [sq3] "r"(sq3), [sq2] "r"(sq2), [sq1] "r"(sq1), [sq0] "r"(sq0)); - - filter_hev_mask_flatmask4_dspr2(limit_vec, flimit_vec, thresh_vec, p1, p0, - p3, p2, q0, q1, q2, q3, &hev, &mask, &flat); - - if ((flat == 0) && (mask != 0)) { - filter1_dspr2(mask, hev, p1, p0, q0, q1, &p1_f0, &p0_f0, &q0_f0, &q1_f0); - - __asm__ __volatile__( - "sw %[p1_f0], (%[sp1]) \n\t" - "sw %[p0_f0], (%[sp0]) \n\t" - "sw %[q0_f0], (%[sq0]) \n\t" - "sw %[q1_f0], (%[sq1]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [sp1] "r"(sp1), [sp0] "r"(sp0), [sq0] "r"(sq0), - [sq1] "r"(sq1)); - } else if ((mask & flat) == 0xFFFFFFFF) { - /* left 2 element operation */ - PACK_LEFT_0TO3() - mbfilter_dspr2(&p3_l, &p2_l, &p1_l, &p0_l, &q0_l, &q1_l, &q2_l, &q3_l); - - /* right 2 element operation */ - PACK_RIGHT_0TO3() - mbfilter_dspr2(&p3_r, &p2_r, &p1_r, &p0_r, &q0_r, &q1_r, &q2_r, &q3_r); - - COMBINE_LEFT_RIGHT_0TO2() - - __asm__ __volatile__( - "sw %[p2], (%[sp2]) \n\t" - "sw %[p1], (%[sp1]) \n\t" - "sw %[p0], (%[sp0]) \n\t" - "sw %[q0], (%[sq0]) \n\t" - "sw %[q1], (%[sq1]) \n\t" - "sw %[q2], (%[sq2]) \n\t" - - : - : [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0), [q0] "r"(q0), - [q1] "r"(q1), [q2] "r"(q2), [sp2] "r"(sp2), [sp1] "r"(sp1), - [sp0] "r"(sp0), [sq0] "r"(sq0), [sq1] "r"(sq1), [sq2] "r"(sq2)); - } else if ((flat != 0) && (mask != 0)) { - /* filtering */ - filter1_dspr2(mask, hev, p1, p0, q0, q1, &p1_f0, &p0_f0, &q0_f0, &q1_f0); - - /* left 2 element operation */ - PACK_LEFT_0TO3() - mbfilter_dspr2(&p3_l, &p2_l, &p1_l, &p0_l, &q0_l, &q1_l, &q2_l, &q3_l); - - /* right 2 element operation */ - PACK_RIGHT_0TO3() - mbfilter_dspr2(&p3_r, &p2_r, &p1_r, &p0_r, &q0_r, &q1_r, &q2_r, &q3_r); - - if (mask & flat & 0x000000FF) { - __asm__ __volatile__( - "sb %[p2_r], (%[sp2]) \n\t" - "sb %[p1_r], (%[sp1]) \n\t" - "sb %[p0_r], (%[sp0]) \n\t" - "sb %[q0_r], (%[sq0]) \n\t" - "sb %[q1_r], (%[sq1]) \n\t" - "sb %[q2_r], (%[sq2]) \n\t" - - : - : [p2_r] "r"(p2_r), [p1_r] "r"(p1_r), [p0_r] "r"(p0_r), - [q0_r] "r"(q0_r), [q1_r] "r"(q1_r), [q2_r] "r"(q2_r), - [sp2] "r"(sp2), [sp1] "r"(sp1), [sp0] "r"(sp0), [sq0] "r"(sq0), - [sq1] "r"(sq1), [sq2] "r"(sq2)); - } else if (mask & 0x000000FF) { - __asm__ __volatile__( - "sb %[p1_f0], (%[sp1]) \n\t" - "sb %[p0_f0], (%[sp0]) \n\t" - "sb %[q0_f0], (%[sq0]) \n\t" - "sb %[q1_f0], (%[sq1]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [sp1] "r"(sp1), [sp0] "r"(sp0), - [sq0] "r"(sq0), [sq1] "r"(sq1)); - } - - __asm__ __volatile__( - "srl %[p2_r], %[p2_r], 16 \n\t" - "srl %[p1_r], %[p1_r], 16 \n\t" - "srl %[p0_r], %[p0_r], 16 \n\t" - "srl %[q0_r], %[q0_r], 16 \n\t" - "srl %[q1_r], %[q1_r], 16 \n\t" - "srl %[q2_r], %[q2_r], 16 \n\t" - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p2_r] "+r"(p2_r), [p1_r] "+r"(p1_r), [p0_r] "+r"(p0_r), - [q0_r] "+r"(q0_r), [q1_r] "+r"(q1_r), [q2_r] "+r"(q2_r), - [p1_f0] "+r"(p1_f0), [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), - [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & 0x0000FF00) { - __asm__ __volatile__( - "sb %[p2_r], +1(%[sp2]) \n\t" - "sb %[p1_r], +1(%[sp1]) \n\t" - "sb %[p0_r], +1(%[sp0]) \n\t" - "sb %[q0_r], +1(%[sq0]) \n\t" - "sb %[q1_r], +1(%[sq1]) \n\t" - "sb %[q2_r], +1(%[sq2]) \n\t" - - : - : [p2_r] "r"(p2_r), [p1_r] "r"(p1_r), [p0_r] "r"(p0_r), - [q0_r] "r"(q0_r), [q1_r] "r"(q1_r), [q2_r] "r"(q2_r), - [sp2] "r"(sp2), [sp1] "r"(sp1), [sp0] "r"(sp0), [sq0] "r"(sq0), - [sq1] "r"(sq1), [sq2] "r"(sq2)); - } else if (mask & 0x0000FF00) { - __asm__ __volatile__( - "sb %[p1_f0], +1(%[sp1]) \n\t" - "sb %[p0_f0], +1(%[sp0]) \n\t" - "sb %[q0_f0], +1(%[sq0]) \n\t" - "sb %[q1_f0], +1(%[sq1]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [sp1] "r"(sp1), [sp0] "r"(sp0), - [sq0] "r"(sq0), [sq1] "r"(sq1)); - } - - __asm__ __volatile__( - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p2] "+r"(p2), [p1] "+r"(p1), [p0] "+r"(p0), [q0] "+r"(q0), - [q1] "+r"(q1), [q2] "+r"(q2), [p1_f0] "+r"(p1_f0), - [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & 0x00FF0000) { - __asm__ __volatile__( - "sb %[p2_l], +2(%[sp2]) \n\t" - "sb %[p1_l], +2(%[sp1]) \n\t" - "sb %[p0_l], +2(%[sp0]) \n\t" - "sb %[q0_l], +2(%[sq0]) \n\t" - "sb %[q1_l], +2(%[sq1]) \n\t" - "sb %[q2_l], +2(%[sq2]) \n\t" - - : - : [p2_l] "r"(p2_l), [p1_l] "r"(p1_l), [p0_l] "r"(p0_l), - [q0_l] "r"(q0_l), [q1_l] "r"(q1_l), [q2_l] "r"(q2_l), - [sp2] "r"(sp2), [sp1] "r"(sp1), [sp0] "r"(sp0), [sq0] "r"(sq0), - [sq1] "r"(sq1), [sq2] "r"(sq2)); - } else if (mask & 0x00FF0000) { - __asm__ __volatile__( - "sb %[p1_f0], +2(%[sp1]) \n\t" - "sb %[p0_f0], +2(%[sp0]) \n\t" - "sb %[q0_f0], +2(%[sq0]) \n\t" - "sb %[q1_f0], +2(%[sq1]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [sp1] "r"(sp1), [sp0] "r"(sp0), - [sq0] "r"(sq0), [sq1] "r"(sq1)); - } - - __asm__ __volatile__( - "srl %[p2_l], %[p2_l], 16 \n\t" - "srl %[p1_l], %[p1_l], 16 \n\t" - "srl %[p0_l], %[p0_l], 16 \n\t" - "srl %[q0_l], %[q0_l], 16 \n\t" - "srl %[q1_l], %[q1_l], 16 \n\t" - "srl %[q2_l], %[q2_l], 16 \n\t" - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p2_l] "+r"(p2_l), [p1_l] "+r"(p1_l), [p0_l] "+r"(p0_l), - [q0_l] "+r"(q0_l), [q1_l] "+r"(q1_l), [q2_l] "+r"(q2_l), - [p1_f0] "+r"(p1_f0), [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), - [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & 0xFF000000) { - __asm__ __volatile__( - "sb %[p2_l], +3(%[sp2]) \n\t" - "sb %[p1_l], +3(%[sp1]) \n\t" - "sb %[p0_l], +3(%[sp0]) \n\t" - "sb %[q0_l], +3(%[sq0]) \n\t" - "sb %[q1_l], +3(%[sq1]) \n\t" - "sb %[q2_l], +3(%[sq2]) \n\t" - - : - : [p2_l] "r"(p2_l), [p1_l] "r"(p1_l), [p0_l] "r"(p0_l), - [q0_l] "r"(q0_l), [q1_l] "r"(q1_l), [q2_l] "r"(q2_l), - [sp2] "r"(sp2), [sp1] "r"(sp1), [sp0] "r"(sp0), [sq0] "r"(sq0), - [sq1] "r"(sq1), [sq2] "r"(sq2)); - } else if (mask & 0xFF000000) { - __asm__ __volatile__( - "sb %[p1_f0], +3(%[sp1]) \n\t" - "sb %[p0_f0], +3(%[sp0]) \n\t" - "sb %[q0_f0], +3(%[sq0]) \n\t" - "sb %[q1_f0], +3(%[sq1]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [sp1] "r"(sp1), [sp0] "r"(sp0), - [sq0] "r"(sq0), [sq1] "r"(sq1)); - } - } - - s = s + 4; - } -} - -void vpx_lpf_vertical_8_dspr2(unsigned char *s, int pitch, - const uint8_t *blimit, const uint8_t *limit, - const uint8_t *thresh) { - uint8_t i; - uint32_t mask, hev, flat; - uint8_t *s1, *s2, *s3, *s4; - uint32_t prim1, prim2, sec3, sec4, prim3, prim4; - uint32_t thresh_vec, flimit_vec, limit_vec; - uint32_t uflimit, ulimit, uthresh; - uint32_t p3, p2, p1, p0, q3, q2, q1, q0; - uint32_t p1_f0, p0_f0, q0_f0, q1_f0; - uint32_t p0_l, p1_l, p2_l, p3_l, q0_l, q1_l, q2_l, q3_l; - uint32_t p0_r, p1_r, p2_r, p3_r, q0_r, q1_r, q2_r, q3_r; - - uflimit = *blimit; - ulimit = *limit; - uthresh = *thresh; - - /* create quad-byte */ - __asm__ __volatile__( - "replv.qb %[thresh_vec], %[uthresh] \n\t" - "replv.qb %[flimit_vec], %[uflimit] \n\t" - "replv.qb %[limit_vec], %[ulimit] \n\t" - - : [thresh_vec] "=&r"(thresh_vec), [flimit_vec] "=&r"(flimit_vec), - [limit_vec] "=r"(limit_vec) - : [uthresh] "r"(uthresh), [uflimit] "r"(uflimit), [ulimit] "r"(ulimit)); - - prefetch_store(s + pitch); - - for (i = 0; i < 2; i++) { - s1 = s; - s2 = s + pitch; - s3 = s2 + pitch; - s4 = s3 + pitch; - s = s4 + pitch; - - __asm__ __volatile__( - "lw %[p0], -4(%[s1]) \n\t" - "lw %[p1], -4(%[s2]) \n\t" - "lw %[p2], -4(%[s3]) \n\t" - "lw %[p3], -4(%[s4]) \n\t" - "lw %[q3], (%[s1]) \n\t" - "lw %[q2], (%[s2]) \n\t" - "lw %[q1], (%[s3]) \n\t" - "lw %[q0], (%[s4]) \n\t" - - : [p3] "=&r"(p3), [p2] "=&r"(p2), [p1] "=&r"(p1), [p0] "=&r"(p0), - [q0] "=&r"(q0), [q1] "=&r"(q1), [q2] "=&r"(q2), [q3] "=&r"(q3) - : [s1] "r"(s1), [s2] "r"(s2), [s3] "r"(s3), [s4] "r"(s4)); - - /* transpose p3, p2, p1, p0 - original (when loaded from memory) - register -4 -3 -2 -1 - p0 p0_0 p0_1 p0_2 p0_3 - p1 p1_0 p1_1 p1_2 p1_3 - p2 p2_0 p2_1 p2_2 p2_3 - p3 p3_0 p3_1 p3_2 p3_3 - - after transpose - register - p0 p3_3 p2_3 p1_3 p0_3 - p1 p3_2 p2_2 p1_2 p0_2 - p2 p3_1 p2_1 p1_1 p0_1 - p3 p3_0 p2_0 p1_0 p0_0 - */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p0], %[p1] \n\t" - "precr.qb.ph %[prim2], %[p0], %[p1] \n\t" - "precrq.qb.ph %[prim3], %[p2], %[p3] \n\t" - "precr.qb.ph %[prim4], %[p2], %[p3] \n\t" - - "precrq.qb.ph %[p1], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[p3], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p0], %[p1], %[sec3] \n\t" - "precrq.ph.w %[p2], %[p3], %[sec4] \n\t" - "append %[p1], %[sec3], 16 \n\t" - "append %[p3], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p0] "+r"(p0), [p1] "+r"(p1), [p2] "+r"(p2), - [p3] "+r"(p3), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* transpose q0, q1, q2, q3 - original (when loaded from memory) - register +1 +2 +3 +4 - q3 q3_0 q3_1 q3_2 q3_3 - q2 q2_0 q2_1 q2_2 q2_3 - q1 q1_0 q1_1 q1_2 q1_3 - q0 q0_0 q0_1 q0_2 q0_3 - - after transpose - register - q3 q0_3 q1_3 q2_3 q3_3 - q2 q0_2 q1_2 q2_2 q3_2 - q1 q0_1 q1_1 q2_1 q3_1 - q0 q0_0 q1_0 q2_0 q3_0 - */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[q3], %[q2] \n\t" - "precr.qb.ph %[prim2], %[q3], %[q2] \n\t" - "precrq.qb.ph %[prim3], %[q1], %[q0] \n\t" - "precr.qb.ph %[prim4], %[q1], %[q0] \n\t" - - "precrq.qb.ph %[q2], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[q0], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[q3], %[q2], %[sec3] \n\t" - "precrq.ph.w %[q1], %[q0], %[sec4] \n\t" - "append %[q2], %[sec3], 16 \n\t" - "append %[q0], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [q3] "+r"(q3), [q2] "+r"(q2), [q1] "+r"(q1), - [q0] "+r"(q0), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - filter_hev_mask_flatmask4_dspr2(limit_vec, flimit_vec, thresh_vec, p1, p0, - p3, p2, q0, q1, q2, q3, &hev, &mask, &flat); - - if ((flat == 0) && (mask != 0)) { - filter1_dspr2(mask, hev, p1, p0, q0, q1, &p1_f0, &p0_f0, &q0_f0, &q1_f0); - STORE_F0() - } else if ((mask & flat) == 0xFFFFFFFF) { - /* left 2 element operation */ - PACK_LEFT_0TO3() - mbfilter_dspr2(&p3_l, &p2_l, &p1_l, &p0_l, &q0_l, &q1_l, &q2_l, &q3_l); - - /* right 2 element operation */ - PACK_RIGHT_0TO3() - mbfilter_dspr2(&p3_r, &p2_r, &p1_r, &p0_r, &q0_r, &q1_r, &q2_r, &q3_r); - - STORE_F1() - } else if ((flat != 0) && (mask != 0)) { - filter1_dspr2(mask, hev, p1, p0, q0, q1, &p1_f0, &p0_f0, &q0_f0, &q1_f0); - - /* left 2 element operation */ - PACK_LEFT_0TO3() - mbfilter_dspr2(&p3_l, &p2_l, &p1_l, &p0_l, &q0_l, &q1_l, &q2_l, &q3_l); - - /* right 2 element operation */ - PACK_RIGHT_0TO3() - mbfilter_dspr2(&p3_r, &p2_r, &p1_r, &p0_r, &q0_r, &q1_r, &q2_r, &q3_r); - - if (mask & flat & 0x000000FF) { - __asm__ __volatile__( - "sb %[p2_r], -3(%[s4]) \n\t" - "sb %[p1_r], -2(%[s4]) \n\t" - "sb %[p0_r], -1(%[s4]) \n\t" - "sb %[q0_r], (%[s4]) \n\t" - "sb %[q1_r], +1(%[s4]) \n\t" - "sb %[q2_r], +2(%[s4]) \n\t" - - : - : [p2_r] "r"(p2_r), [p1_r] "r"(p1_r), [p0_r] "r"(p0_r), - [q0_r] "r"(q0_r), [q1_r] "r"(q1_r), [q2_r] "r"(q2_r), - [s4] "r"(s4)); - } else if (mask & 0x000000FF) { - __asm__ __volatile__( - "sb %[p1_f0], -2(%[s4]) \n\t" - "sb %[p0_f0], -1(%[s4]) \n\t" - "sb %[q0_f0], (%[s4]) \n\t" - "sb %[q1_f0], +1(%[s4]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [s4] "r"(s4)); - } - - __asm__ __volatile__( - "srl %[p2_r], %[p2_r], 16 \n\t" - "srl %[p1_r], %[p1_r], 16 \n\t" - "srl %[p0_r], %[p0_r], 16 \n\t" - "srl %[q0_r], %[q0_r], 16 \n\t" - "srl %[q1_r], %[q1_r], 16 \n\t" - "srl %[q2_r], %[q2_r], 16 \n\t" - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p2_r] "+r"(p2_r), [p1_r] "+r"(p1_r), [p0_r] "+r"(p0_r), - [q0_r] "+r"(q0_r), [q1_r] "+r"(q1_r), [q2_r] "+r"(q2_r), - [p1_f0] "+r"(p1_f0), [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), - [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & 0x0000FF00) { - __asm__ __volatile__( - "sb %[p2_r], -3(%[s3]) \n\t" - "sb %[p1_r], -2(%[s3]) \n\t" - "sb %[p0_r], -1(%[s3]) \n\t" - "sb %[q0_r], (%[s3]) \n\t" - "sb %[q1_r], +1(%[s3]) \n\t" - "sb %[q2_r], +2(%[s3]) \n\t" - - : - : [p2_r] "r"(p2_r), [p1_r] "r"(p1_r), [p0_r] "r"(p0_r), - [q0_r] "r"(q0_r), [q1_r] "r"(q1_r), [q2_r] "r"(q2_r), - [s3] "r"(s3)); - } else if (mask & 0x0000FF00) { - __asm__ __volatile__( - "sb %[p1_f0], -2(%[s3]) \n\t" - "sb %[p0_f0], -1(%[s3]) \n\t" - "sb %[q0_f0], (%[s3]) \n\t" - "sb %[q1_f0], +1(%[s3]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [s3] "r"(s3)); - } - - __asm__ __volatile__( - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p2] "+r"(p2), [p1] "+r"(p1), [p0] "+r"(p0), [q0] "+r"(q0), - [q1] "+r"(q1), [q2] "+r"(q2), [p1_f0] "+r"(p1_f0), - [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & 0x00FF0000) { - __asm__ __volatile__( - "sb %[p2_l], -3(%[s2]) \n\t" - "sb %[p1_l], -2(%[s2]) \n\t" - "sb %[p0_l], -1(%[s2]) \n\t" - "sb %[q0_l], (%[s2]) \n\t" - "sb %[q1_l], +1(%[s2]) \n\t" - "sb %[q2_l], +2(%[s2]) \n\t" - - : - : [p2_l] "r"(p2_l), [p1_l] "r"(p1_l), [p0_l] "r"(p0_l), - [q0_l] "r"(q0_l), [q1_l] "r"(q1_l), [q2_l] "r"(q2_l), - [s2] "r"(s2)); - } else if (mask & 0x00FF0000) { - __asm__ __volatile__( - "sb %[p1_f0], -2(%[s2]) \n\t" - "sb %[p0_f0], -1(%[s2]) \n\t" - "sb %[q0_f0], (%[s2]) \n\t" - "sb %[q1_f0], +1(%[s2]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [s2] "r"(s2)); - } - - __asm__ __volatile__( - "srl %[p2_l], %[p2_l], 16 \n\t" - "srl %[p1_l], %[p1_l], 16 \n\t" - "srl %[p0_l], %[p0_l], 16 \n\t" - "srl %[q0_l], %[q0_l], 16 \n\t" - "srl %[q1_l], %[q1_l], 16 \n\t" - "srl %[q2_l], %[q2_l], 16 \n\t" - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p2_l] "+r"(p2_l), [p1_l] "+r"(p1_l), [p0_l] "+r"(p0_l), - [q0_l] "+r"(q0_l), [q1_l] "+r"(q1_l), [q2_l] "+r"(q2_l), - [p1_f0] "+r"(p1_f0), [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), - [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & 0xFF000000) { - __asm__ __volatile__( - "sb %[p2_l], -3(%[s1]) \n\t" - "sb %[p1_l], -2(%[s1]) \n\t" - "sb %[p0_l], -1(%[s1]) \n\t" - "sb %[q0_l], (%[s1]) \n\t" - "sb %[q1_l], +1(%[s1]) \n\t" - "sb %[q2_l], +2(%[s1]) \n\t" - - : - : [p2_l] "r"(p2_l), [p1_l] "r"(p1_l), [p0_l] "r"(p0_l), - [q0_l] "r"(q0_l), [q1_l] "r"(q1_l), [q2_l] "r"(q2_l), - [s1] "r"(s1)); - } else if (mask & 0xFF000000) { - __asm__ __volatile__( - "sb %[p1_f0], -2(%[s1]) \n\t" - "sb %[p0_f0], -1(%[s1]) \n\t" - "sb %[q0_f0], (%[s1]) \n\t" - "sb %[q1_f0], +1(%[s1]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [s1] "r"(s1)); - } - } - } -} -#endif // #if HAVE_DSPR2 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_mb_horiz_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_mb_horiz_dspr2.c deleted file mode 100644 index 9c1f5143..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_mb_horiz_dspr2.c +++ /dev/null @@ -1,732 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/mips/common_dspr2.h" -#include "vpx_dsp/mips/loopfilter_filters_dspr2.h" -#include "vpx_dsp/mips/loopfilter_macros_dspr2.h" -#include "vpx_dsp/mips/loopfilter_masks_dspr2.h" -#include "vpx_mem/vpx_mem.h" - -#if HAVE_DSPR2 -static void mb_lpf_horizontal_edge(unsigned char *s, int pitch, - const uint8_t *blimit, const uint8_t *limit, - const uint8_t *thresh, int count) { - uint32_t mask; - uint32_t hev, flat, flat2; - uint8_t i; - uint8_t *sp7, *sp6, *sp5, *sp4, *sp3, *sp2, *sp1, *sp0; - uint8_t *sq0, *sq1, *sq2, *sq3, *sq4, *sq5, *sq6, *sq7; - uint32_t thresh_vec, flimit_vec, limit_vec; - uint32_t uflimit, ulimit, uthresh; - uint32_t p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7; - uint32_t p1_f0, p0_f0, q0_f0, q1_f0; - uint32_t p7_l, p6_l, p5_l, p4_l, p3_l, p2_l, p1_l, p0_l; - uint32_t q0_l, q1_l, q2_l, q3_l, q4_l, q5_l, q6_l, q7_l; - uint32_t p7_r, p6_r, p5_r, p4_r, p3_r, p2_r, p1_r, p0_r; - uint32_t q0_r, q1_r, q2_r, q3_r, q4_r, q5_r, q6_r, q7_r; - uint32_t p2_l_f1, p1_l_f1, p0_l_f1, p2_r_f1, p1_r_f1, p0_r_f1; - uint32_t q0_l_f1, q1_l_f1, q2_l_f1, q0_r_f1, q1_r_f1, q2_r_f1; - - uflimit = *blimit; - ulimit = *limit; - uthresh = *thresh; - - /* create quad-byte */ - __asm__ __volatile__( - "replv.qb %[thresh_vec], %[uthresh] \n\t" - "replv.qb %[flimit_vec], %[uflimit] \n\t" - "replv.qb %[limit_vec], %[ulimit] \n\t" - - : [thresh_vec] "=&r"(thresh_vec), [flimit_vec] "=&r"(flimit_vec), - [limit_vec] "=r"(limit_vec) - : [uthresh] "r"(uthresh), [uflimit] "r"(uflimit), [ulimit] "r"(ulimit)); - - /* prefetch data for store */ - prefetch_store(s); - - for (i = 0; i < (2 * count); i++) { - sp7 = s - (pitch << 3); - sp6 = sp7 + pitch; - sp5 = sp6 + pitch; - sp4 = sp5 + pitch; - sp3 = sp4 + pitch; - sp2 = sp3 + pitch; - sp1 = sp2 + pitch; - sp0 = sp1 + pitch; - sq0 = s; - sq1 = s + pitch; - sq2 = sq1 + pitch; - sq3 = sq2 + pitch; - sq4 = sq3 + pitch; - sq5 = sq4 + pitch; - sq6 = sq5 + pitch; - sq7 = sq6 + pitch; - - __asm__ __volatile__( - "lw %[p7], (%[sp7]) \n\t" - "lw %[p6], (%[sp6]) \n\t" - "lw %[p5], (%[sp5]) \n\t" - "lw %[p4], (%[sp4]) \n\t" - "lw %[p3], (%[sp3]) \n\t" - "lw %[p2], (%[sp2]) \n\t" - "lw %[p1], (%[sp1]) \n\t" - "lw %[p0], (%[sp0]) \n\t" - - : [p3] "=&r"(p3), [p2] "=&r"(p2), [p1] "=&r"(p1), [p0] "=&r"(p0), - [p7] "=&r"(p7), [p6] "=&r"(p6), [p5] "=&r"(p5), [p4] "=&r"(p4) - : [sp3] "r"(sp3), [sp2] "r"(sp2), [sp1] "r"(sp1), [sp0] "r"(sp0), - [sp4] "r"(sp4), [sp5] "r"(sp5), [sp6] "r"(sp6), [sp7] "r"(sp7)); - - __asm__ __volatile__( - "lw %[q0], (%[sq0]) \n\t" - "lw %[q1], (%[sq1]) \n\t" - "lw %[q2], (%[sq2]) \n\t" - "lw %[q3], (%[sq3]) \n\t" - "lw %[q4], (%[sq4]) \n\t" - "lw %[q5], (%[sq5]) \n\t" - "lw %[q6], (%[sq6]) \n\t" - "lw %[q7], (%[sq7]) \n\t" - - : [q3] "=&r"(q3), [q2] "=&r"(q2), [q1] "=&r"(q1), [q0] "=&r"(q0), - [q7] "=&r"(q7), [q6] "=&r"(q6), [q5] "=&r"(q5), [q4] "=&r"(q4) - : [sq3] "r"(sq3), [sq2] "r"(sq2), [sq1] "r"(sq1), [sq0] "r"(sq0), - [sq4] "r"(sq4), [sq5] "r"(sq5), [sq6] "r"(sq6), [sq7] "r"(sq7)); - - filter_hev_mask_flatmask4_dspr2(limit_vec, flimit_vec, thresh_vec, p1, p0, - p3, p2, q0, q1, q2, q3, &hev, &mask, &flat); - - flatmask5(p7, p6, p5, p4, p0, q0, q4, q5, q6, q7, &flat2); - - /* f0 */ - if (((flat2 == 0) && (flat == 0) && (mask != 0)) || - ((flat2 != 0) && (flat == 0) && (mask != 0))) { - filter1_dspr2(mask, hev, p1, p0, q0, q1, &p1_f0, &p0_f0, &q0_f0, &q1_f0); - - __asm__ __volatile__( - "sw %[p1_f0], (%[sp1]) \n\t" - "sw %[p0_f0], (%[sp0]) \n\t" - "sw %[q0_f0], (%[sq0]) \n\t" - "sw %[q1_f0], (%[sq1]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [sp1] "r"(sp1), [sp0] "r"(sp0), [sq0] "r"(sq0), - [sq1] "r"(sq1)); - } else if ((flat2 == 0XFFFFFFFF) && (flat == 0xFFFFFFFF) && - (mask == 0xFFFFFFFF)) { - /* f2 */ - PACK_LEFT_0TO3() - PACK_LEFT_4TO7() - wide_mbfilter_dspr2(&p7_l, &p6_l, &p5_l, &p4_l, &p3_l, &p2_l, &p1_l, - &p0_l, &q0_l, &q1_l, &q2_l, &q3_l, &q4_l, &q5_l, - &q6_l, &q7_l); - - PACK_RIGHT_0TO3() - PACK_RIGHT_4TO7() - wide_mbfilter_dspr2(&p7_r, &p6_r, &p5_r, &p4_r, &p3_r, &p2_r, &p1_r, - &p0_r, &q0_r, &q1_r, &q2_r, &q3_r, &q4_r, &q5_r, - &q6_r, &q7_r); - - COMBINE_LEFT_RIGHT_0TO2() - COMBINE_LEFT_RIGHT_3TO6() - - __asm__ __volatile__( - "sw %[p6], (%[sp6]) \n\t" - "sw %[p5], (%[sp5]) \n\t" - "sw %[p4], (%[sp4]) \n\t" - "sw %[p3], (%[sp3]) \n\t" - "sw %[p2], (%[sp2]) \n\t" - "sw %[p1], (%[sp1]) \n\t" - "sw %[p0], (%[sp0]) \n\t" - - : - : [p6] "r"(p6), [p5] "r"(p5), [p4] "r"(p4), [p3] "r"(p3), - [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0), [sp6] "r"(sp6), - [sp5] "r"(sp5), [sp4] "r"(sp4), [sp3] "r"(sp3), [sp2] "r"(sp2), - [sp1] "r"(sp1), [sp0] "r"(sp0)); - - __asm__ __volatile__( - "sw %[q6], (%[sq6]) \n\t" - "sw %[q5], (%[sq5]) \n\t" - "sw %[q4], (%[sq4]) \n\t" - "sw %[q3], (%[sq3]) \n\t" - "sw %[q2], (%[sq2]) \n\t" - "sw %[q1], (%[sq1]) \n\t" - "sw %[q0], (%[sq0]) \n\t" - - : - : [q6] "r"(q6), [q5] "r"(q5), [q4] "r"(q4), [q3] "r"(q3), - [q2] "r"(q2), [q1] "r"(q1), [q0] "r"(q0), [sq6] "r"(sq6), - [sq5] "r"(sq5), [sq4] "r"(sq4), [sq3] "r"(sq3), [sq2] "r"(sq2), - [sq1] "r"(sq1), [sq0] "r"(sq0)); - } else if ((flat2 == 0) && (flat == 0xFFFFFFFF) && (mask == 0xFFFFFFFF)) { - /* f1 */ - /* left 2 element operation */ - PACK_LEFT_0TO3() - mbfilter_dspr2(&p3_l, &p2_l, &p1_l, &p0_l, &q0_l, &q1_l, &q2_l, &q3_l); - - /* right 2 element operation */ - PACK_RIGHT_0TO3() - mbfilter_dspr2(&p3_r, &p2_r, &p1_r, &p0_r, &q0_r, &q1_r, &q2_r, &q3_r); - - COMBINE_LEFT_RIGHT_0TO2() - - __asm__ __volatile__( - "sw %[p2], (%[sp2]) \n\t" - "sw %[p1], (%[sp1]) \n\t" - "sw %[p0], (%[sp0]) \n\t" - "sw %[q0], (%[sq0]) \n\t" - "sw %[q1], (%[sq1]) \n\t" - "sw %[q2], (%[sq2]) \n\t" - - : - : [p2] "r"(p2), [p1] "r"(p1), [p0] "r"(p0), [q0] "r"(q0), - [q1] "r"(q1), [q2] "r"(q2), [sp2] "r"(sp2), [sp1] "r"(sp1), - [sp0] "r"(sp0), [sq0] "r"(sq0), [sq1] "r"(sq1), [sq2] "r"(sq2)); - } else if ((flat2 == 0) && (flat != 0) && (mask != 0)) { - /* f0+f1 */ - filter1_dspr2(mask, hev, p1, p0, q0, q1, &p1_f0, &p0_f0, &q0_f0, &q1_f0); - - /* left 2 element operation */ - PACK_LEFT_0TO3() - mbfilter_dspr2(&p3_l, &p2_l, &p1_l, &p0_l, &q0_l, &q1_l, &q2_l, &q3_l); - - /* right 2 element operation */ - PACK_RIGHT_0TO3() - mbfilter_dspr2(&p3_r, &p2_r, &p1_r, &p0_r, &q0_r, &q1_r, &q2_r, &q3_r); - - if (mask & flat & 0x000000FF) { - __asm__ __volatile__( - "sb %[p2_r], (%[sp2]) \n\t" - "sb %[p1_r], (%[sp1]) \n\t" - "sb %[p0_r], (%[sp0]) \n\t" - "sb %[q0_r], (%[sq0]) \n\t" - "sb %[q1_r], (%[sq1]) \n\t" - "sb %[q2_r], (%[sq2]) \n\t" - - : - : [p2_r] "r"(p2_r), [p1_r] "r"(p1_r), [p0_r] "r"(p0_r), - [q0_r] "r"(q0_r), [q1_r] "r"(q1_r), [q2_r] "r"(q2_r), - [sp2] "r"(sp2), [sp1] "r"(sp1), [sp0] "r"(sp0), [sq0] "r"(sq0), - [sq1] "r"(sq1), [sq2] "r"(sq2)); - } else if (mask & 0x000000FF) { - __asm__ __volatile__( - "sb %[p1_f0], (%[sp1]) \n\t" - "sb %[p0_f0], (%[sp0]) \n\t" - "sb %[q0_f0], (%[sq0]) \n\t" - "sb %[q1_f0], (%[sq1]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [sp1] "r"(sp1), [sp0] "r"(sp0), - [sq0] "r"(sq0), [sq1] "r"(sq1)); - } - - __asm__ __volatile__( - "srl %[p2_r], %[p2_r], 16 \n\t" - "srl %[p1_r], %[p1_r], 16 \n\t" - "srl %[p0_r], %[p0_r], 16 \n\t" - "srl %[q0_r], %[q0_r], 16 \n\t" - "srl %[q1_r], %[q1_r], 16 \n\t" - "srl %[q2_r], %[q2_r], 16 \n\t" - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p2_r] "+r"(p2_r), [p1_r] "+r"(p1_r), [p0_r] "+r"(p0_r), - [q0_r] "+r"(q0_r), [q1_r] "+r"(q1_r), [q2_r] "+r"(q2_r), - [p1_f0] "+r"(p1_f0), [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), - [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & 0x0000FF00) { - __asm__ __volatile__( - "sb %[p2_r], +1(%[sp2]) \n\t" - "sb %[p1_r], +1(%[sp1]) \n\t" - "sb %[p0_r], +1(%[sp0]) \n\t" - "sb %[q0_r], +1(%[sq0]) \n\t" - "sb %[q1_r], +1(%[sq1]) \n\t" - "sb %[q2_r], +1(%[sq2]) \n\t" - - : - : [p2_r] "r"(p2_r), [p1_r] "r"(p1_r), [p0_r] "r"(p0_r), - [q0_r] "r"(q0_r), [q1_r] "r"(q1_r), [q2_r] "r"(q2_r), - [sp2] "r"(sp2), [sp1] "r"(sp1), [sp0] "r"(sp0), [sq0] "r"(sq0), - [sq1] "r"(sq1), [sq2] "r"(sq2)); - } else if (mask & 0x0000FF00) { - __asm__ __volatile__( - "sb %[p1_f0], +1(%[sp1]) \n\t" - "sb %[p0_f0], +1(%[sp0]) \n\t" - "sb %[q0_f0], +1(%[sq0]) \n\t" - "sb %[q1_f0], +1(%[sq1]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [sp1] "r"(sp1), [sp0] "r"(sp0), - [sq0] "r"(sq0), [sq1] "r"(sq1)); - } - - __asm__ __volatile__( - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p1_f0] "+r"(p1_f0), [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), - [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & 0x00FF0000) { - __asm__ __volatile__( - "sb %[p2_l], +2(%[sp2]) \n\t" - "sb %[p1_l], +2(%[sp1]) \n\t" - "sb %[p0_l], +2(%[sp0]) \n\t" - "sb %[q0_l], +2(%[sq0]) \n\t" - "sb %[q1_l], +2(%[sq1]) \n\t" - "sb %[q2_l], +2(%[sq2]) \n\t" - - : - : [p2_l] "r"(p2_l), [p1_l] "r"(p1_l), [p0_l] "r"(p0_l), - [q0_l] "r"(q0_l), [q1_l] "r"(q1_l), [q2_l] "r"(q2_l), - [sp2] "r"(sp2), [sp1] "r"(sp1), [sp0] "r"(sp0), [sq0] "r"(sq0), - [sq1] "r"(sq1), [sq2] "r"(sq2)); - } else if (mask & 0x00FF0000) { - __asm__ __volatile__( - "sb %[p1_f0], +2(%[sp1]) \n\t" - "sb %[p0_f0], +2(%[sp0]) \n\t" - "sb %[q0_f0], +2(%[sq0]) \n\t" - "sb %[q1_f0], +2(%[sq1]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [sp1] "r"(sp1), [sp0] "r"(sp0), - [sq0] "r"(sq0), [sq1] "r"(sq1)); - } - - __asm__ __volatile__( - "srl %[p2_l], %[p2_l], 16 \n\t" - "srl %[p1_l], %[p1_l], 16 \n\t" - "srl %[p0_l], %[p0_l], 16 \n\t" - "srl %[q0_l], %[q0_l], 16 \n\t" - "srl %[q1_l], %[q1_l], 16 \n\t" - "srl %[q2_l], %[q2_l], 16 \n\t" - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p2_l] "+r"(p2_l), [p1_l] "+r"(p1_l), [p0_l] "+r"(p0_l), - [q0_l] "+r"(q0_l), [q1_l] "+r"(q1_l), [q2_l] "+r"(q2_l), - [p1_f0] "+r"(p1_f0), [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), - [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & 0xFF000000) { - __asm__ __volatile__( - "sb %[p2_l], +3(%[sp2]) \n\t" - "sb %[p1_l], +3(%[sp1]) \n\t" - "sb %[p0_l], +3(%[sp0]) \n\t" - "sb %[q0_l], +3(%[sq0]) \n\t" - "sb %[q1_l], +3(%[sq1]) \n\t" - "sb %[q2_l], +3(%[sq2]) \n\t" - - : - : [p2_l] "r"(p2_l), [p1_l] "r"(p1_l), [p0_l] "r"(p0_l), - [q0_l] "r"(q0_l), [q1_l] "r"(q1_l), [q2_l] "r"(q2_l), - [sp2] "r"(sp2), [sp1] "r"(sp1), [sp0] "r"(sp0), [sq0] "r"(sq0), - [sq1] "r"(sq1), [sq2] "r"(sq2)); - } else if (mask & 0xFF000000) { - __asm__ __volatile__( - "sb %[p1_f0], +3(%[sp1]) \n\t" - "sb %[p0_f0], +3(%[sp0]) \n\t" - "sb %[q0_f0], +3(%[sq0]) \n\t" - "sb %[q1_f0], +3(%[sq1]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [sp1] "r"(sp1), [sp0] "r"(sp0), - [sq0] "r"(sq0), [sq1] "r"(sq1)); - } - } else if ((flat2 != 0) && (flat != 0) && (mask != 0)) { - /* f0 + f1 + f2 */ - /* f0 function */ - filter1_dspr2(mask, hev, p1, p0, q0, q1, &p1_f0, &p0_f0, &q0_f0, &q1_f0); - - /* f1 function */ - /* left 2 element operation */ - PACK_LEFT_0TO3() - mbfilter1_dspr2(p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l, &p2_l_f1, - &p1_l_f1, &p0_l_f1, &q0_l_f1, &q1_l_f1, &q2_l_f1); - - /* right 2 element operation */ - PACK_RIGHT_0TO3() - mbfilter1_dspr2(p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r, &p2_r_f1, - &p1_r_f1, &p0_r_f1, &q0_r_f1, &q1_r_f1, &q2_r_f1); - - /* f2 function */ - PACK_LEFT_4TO7() - wide_mbfilter_dspr2(&p7_l, &p6_l, &p5_l, &p4_l, &p3_l, &p2_l, &p1_l, - &p0_l, &q0_l, &q1_l, &q2_l, &q3_l, &q4_l, &q5_l, - &q6_l, &q7_l); - - PACK_RIGHT_4TO7() - wide_mbfilter_dspr2(&p7_r, &p6_r, &p5_r, &p4_r, &p3_r, &p2_r, &p1_r, - &p0_r, &q0_r, &q1_r, &q2_r, &q3_r, &q4_r, &q5_r, - &q6_r, &q7_r); - - if (mask & flat & flat2 & 0x000000FF) { - __asm__ __volatile__( - "sb %[p6_r], (%[sp6]) \n\t" - "sb %[p5_r], (%[sp5]) \n\t" - "sb %[p4_r], (%[sp4]) \n\t" - "sb %[p3_r], (%[sp3]) \n\t" - "sb %[p2_r], (%[sp2]) \n\t" - "sb %[p1_r], (%[sp1]) \n\t" - "sb %[p0_r], (%[sp0]) \n\t" - - : - : [p6_r] "r"(p6_r), [p5_r] "r"(p5_r), [p4_r] "r"(p4_r), - [p3_r] "r"(p3_r), [p2_r] "r"(p2_r), [p1_r] "r"(p1_r), - [sp6] "r"(sp6), [sp5] "r"(sp5), [sp4] "r"(sp4), [sp3] "r"(sp3), - [sp2] "r"(sp2), [sp1] "r"(sp1), [p0_r] "r"(p0_r), [sp0] "r"(sp0)); - - __asm__ __volatile__( - "sb %[q0_r], (%[sq0]) \n\t" - "sb %[q1_r], (%[sq1]) \n\t" - "sb %[q2_r], (%[sq2]) \n\t" - "sb %[q3_r], (%[sq3]) \n\t" - "sb %[q4_r], (%[sq4]) \n\t" - "sb %[q5_r], (%[sq5]) \n\t" - "sb %[q6_r], (%[sq6]) \n\t" - - : - : [q0_r] "r"(q0_r), [q1_r] "r"(q1_r), [q2_r] "r"(q2_r), - [q3_r] "r"(q3_r), [q4_r] "r"(q4_r), [q5_r] "r"(q5_r), - [q6_r] "r"(q6_r), [sq0] "r"(sq0), [sq1] "r"(sq1), [sq2] "r"(sq2), - [sq3] "r"(sq3), [sq4] "r"(sq4), [sq5] "r"(sq5), [sq6] "r"(sq6)); - } else if (mask & flat & 0x000000FF) { - __asm__ __volatile__( - "sb %[p2_r_f1], (%[sp2]) \n\t" - "sb %[p1_r_f1], (%[sp1]) \n\t" - "sb %[p0_r_f1], (%[sp0]) \n\t" - "sb %[q0_r_f1], (%[sq0]) \n\t" - "sb %[q1_r_f1], (%[sq1]) \n\t" - "sb %[q2_r_f1], (%[sq2]) \n\t" - - : - : [p2_r_f1] "r"(p2_r_f1), [p1_r_f1] "r"(p1_r_f1), - [p0_r_f1] "r"(p0_r_f1), [q0_r_f1] "r"(q0_r_f1), - [q1_r_f1] "r"(q1_r_f1), [q2_r_f1] "r"(q2_r_f1), [sp2] "r"(sp2), - [sp1] "r"(sp1), [sp0] "r"(sp0), [sq0] "r"(sq0), [sq1] "r"(sq1), - [sq2] "r"(sq2)); - } else if (mask & 0x000000FF) { - __asm__ __volatile__( - "sb %[p1_f0], (%[sp1]) \n\t" - "sb %[p0_f0], (%[sp0]) \n\t" - "sb %[q0_f0], (%[sq0]) \n\t" - "sb %[q1_f0], (%[sq1]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [sp1] "r"(sp1), [sp0] "r"(sp0), - [sq0] "r"(sq0), [sq1] "r"(sq1)); - } - - __asm__ __volatile__( - "srl %[p6_r], %[p6_r], 16 \n\t" - "srl %[p5_r], %[p5_r], 16 \n\t" - "srl %[p4_r], %[p4_r], 16 \n\t" - "srl %[p3_r], %[p3_r], 16 \n\t" - "srl %[p2_r], %[p2_r], 16 \n\t" - "srl %[p1_r], %[p1_r], 16 \n\t" - "srl %[p0_r], %[p0_r], 16 \n\t" - "srl %[q0_r], %[q0_r], 16 \n\t" - "srl %[q1_r], %[q1_r], 16 \n\t" - "srl %[q2_r], %[q2_r], 16 \n\t" - "srl %[q3_r], %[q3_r], 16 \n\t" - "srl %[q4_r], %[q4_r], 16 \n\t" - "srl %[q5_r], %[q5_r], 16 \n\t" - "srl %[q6_r], %[q6_r], 16 \n\t" - - : [q0_r] "+r"(q0_r), [q1_r] "+r"(q1_r), [q2_r] "+r"(q2_r), - [q3_r] "+r"(q3_r), [q4_r] "+r"(q4_r), [q5_r] "+r"(q5_r), - [p6_r] "+r"(p6_r), [p5_r] "+r"(p5_r), [p4_r] "+r"(p4_r), - [p3_r] "+r"(p3_r), [p2_r] "+r"(p2_r), [p1_r] "+r"(p1_r), - [q6_r] "+r"(q6_r), [p0_r] "+r"(p0_r) - :); - - __asm__ __volatile__( - "srl %[p2_r_f1], %[p2_r_f1], 16 \n\t" - "srl %[p1_r_f1], %[p1_r_f1], 16 \n\t" - "srl %[p0_r_f1], %[p0_r_f1], 16 \n\t" - "srl %[q0_r_f1], %[q0_r_f1], 16 \n\t" - "srl %[q1_r_f1], %[q1_r_f1], 16 \n\t" - "srl %[q2_r_f1], %[q2_r_f1], 16 \n\t" - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p2_r_f1] "+r"(p2_r_f1), [p1_r_f1] "+r"(p1_r_f1), - [p0_r_f1] "+r"(p0_r_f1), [q0_r_f1] "+r"(q0_r_f1), - [q1_r_f1] "+r"(q1_r_f1), [q2_r_f1] "+r"(q2_r_f1), - [p1_f0] "+r"(p1_f0), [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), - [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & flat2 & 0x0000FF00) { - __asm__ __volatile__( - "sb %[p6_r], +1(%[sp6]) \n\t" - "sb %[p5_r], +1(%[sp5]) \n\t" - "sb %[p4_r], +1(%[sp4]) \n\t" - "sb %[p3_r], +1(%[sp3]) \n\t" - "sb %[p2_r], +1(%[sp2]) \n\t" - "sb %[p1_r], +1(%[sp1]) \n\t" - "sb %[p0_r], +1(%[sp0]) \n\t" - - : - : [p6_r] "r"(p6_r), [p5_r] "r"(p5_r), [p4_r] "r"(p4_r), - [p3_r] "r"(p3_r), [p2_r] "r"(p2_r), [p1_r] "r"(p1_r), - [p0_r] "r"(p0_r), [sp6] "r"(sp6), [sp5] "r"(sp5), [sp4] "r"(sp4), - [sp3] "r"(sp3), [sp2] "r"(sp2), [sp1] "r"(sp1), [sp0] "r"(sp0)); - - __asm__ __volatile__( - "sb %[q0_r], +1(%[sq0]) \n\t" - "sb %[q1_r], +1(%[sq1]) \n\t" - "sb %[q2_r], +1(%[sq2]) \n\t" - "sb %[q3_r], +1(%[sq3]) \n\t" - "sb %[q4_r], +1(%[sq4]) \n\t" - "sb %[q5_r], +1(%[sq5]) \n\t" - "sb %[q6_r], +1(%[sq6]) \n\t" - - : - : [q0_r] "r"(q0_r), [q1_r] "r"(q1_r), [q2_r] "r"(q2_r), - [q3_r] "r"(q3_r), [q4_r] "r"(q4_r), [q5_r] "r"(q5_r), - [q6_r] "r"(q6_r), [sq0] "r"(sq0), [sq1] "r"(sq1), [sq2] "r"(sq2), - [sq3] "r"(sq3), [sq4] "r"(sq4), [sq5] "r"(sq5), [sq6] "r"(sq6)); - } else if (mask & flat & 0x0000FF00) { - __asm__ __volatile__( - "sb %[p2_r_f1], +1(%[sp2]) \n\t" - "sb %[p1_r_f1], +1(%[sp1]) \n\t" - "sb %[p0_r_f1], +1(%[sp0]) \n\t" - "sb %[q0_r_f1], +1(%[sq0]) \n\t" - "sb %[q1_r_f1], +1(%[sq1]) \n\t" - "sb %[q2_r_f1], +1(%[sq2]) \n\t" - - : - : [p2_r_f1] "r"(p2_r_f1), [p1_r_f1] "r"(p1_r_f1), - [p0_r_f1] "r"(p0_r_f1), [q0_r_f1] "r"(q0_r_f1), - [q1_r_f1] "r"(q1_r_f1), [q2_r_f1] "r"(q2_r_f1), [sp2] "r"(sp2), - [sp1] "r"(sp1), [sp0] "r"(sp0), [sq0] "r"(sq0), [sq1] "r"(sq1), - [sq2] "r"(sq2)); - } else if (mask & 0x0000FF00) { - __asm__ __volatile__( - "sb %[p1_f0], +1(%[sp1]) \n\t" - "sb %[p0_f0], +1(%[sp0]) \n\t" - "sb %[q0_f0], +1(%[sq0]) \n\t" - "sb %[q1_f0], +1(%[sq1]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [sp1] "r"(sp1), [sp0] "r"(sp0), - [sq0] "r"(sq0), [sq1] "r"(sq1)); - } - - __asm__ __volatile__( - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p1_f0] "+r"(p1_f0), [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), - [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & flat2 & 0x00FF0000) { - __asm__ __volatile__( - "sb %[p6_l], +2(%[sp6]) \n\t" - "sb %[p5_l], +2(%[sp5]) \n\t" - "sb %[p4_l], +2(%[sp4]) \n\t" - "sb %[p3_l], +2(%[sp3]) \n\t" - "sb %[p2_l], +2(%[sp2]) \n\t" - "sb %[p1_l], +2(%[sp1]) \n\t" - "sb %[p0_l], +2(%[sp0]) \n\t" - - : - : [p6_l] "r"(p6_l), [p5_l] "r"(p5_l), [p4_l] "r"(p4_l), - [p3_l] "r"(p3_l), [p2_l] "r"(p2_l), [p1_l] "r"(p1_l), - [p0_l] "r"(p0_l), [sp6] "r"(sp6), [sp5] "r"(sp5), [sp4] "r"(sp4), - [sp3] "r"(sp3), [sp2] "r"(sp2), [sp1] "r"(sp1), [sp0] "r"(sp0)); - - __asm__ __volatile__( - "sb %[q0_l], +2(%[sq0]) \n\t" - "sb %[q1_l], +2(%[sq1]) \n\t" - "sb %[q2_l], +2(%[sq2]) \n\t" - "sb %[q3_l], +2(%[sq3]) \n\t" - "sb %[q4_l], +2(%[sq4]) \n\t" - "sb %[q5_l], +2(%[sq5]) \n\t" - "sb %[q6_l], +2(%[sq6]) \n\t" - - : - : [q0_l] "r"(q0_l), [q1_l] "r"(q1_l), [q2_l] "r"(q2_l), - [q3_l] "r"(q3_l), [q4_l] "r"(q4_l), [q5_l] "r"(q5_l), - [q6_l] "r"(q6_l), [sq0] "r"(sq0), [sq1] "r"(sq1), [sq2] "r"(sq2), - [sq3] "r"(sq3), [sq4] "r"(sq4), [sq5] "r"(sq5), [sq6] "r"(sq6)); - } else if (mask & flat & 0x00FF0000) { - __asm__ __volatile__( - "sb %[p2_l_f1], +2(%[sp2]) \n\t" - "sb %[p1_l_f1], +2(%[sp1]) \n\t" - "sb %[p0_l_f1], +2(%[sp0]) \n\t" - "sb %[q0_l_f1], +2(%[sq0]) \n\t" - "sb %[q1_l_f1], +2(%[sq1]) \n\t" - "sb %[q2_l_f1], +2(%[sq2]) \n\t" - - : - : [p2_l_f1] "r"(p2_l_f1), [p1_l_f1] "r"(p1_l_f1), - [p0_l_f1] "r"(p0_l_f1), [q0_l_f1] "r"(q0_l_f1), - [q1_l_f1] "r"(q1_l_f1), [q2_l_f1] "r"(q2_l_f1), [sp2] "r"(sp2), - [sp1] "r"(sp1), [sp0] "r"(sp0), [sq0] "r"(sq0), [sq1] "r"(sq1), - [sq2] "r"(sq2)); - } else if (mask & 0x00FF0000) { - __asm__ __volatile__( - "sb %[p1_f0], +2(%[sp1]) \n\t" - "sb %[p0_f0], +2(%[sp0]) \n\t" - "sb %[q0_f0], +2(%[sq0]) \n\t" - "sb %[q1_f0], +2(%[sq1]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [sp1] "r"(sp1), [sp0] "r"(sp0), - [sq0] "r"(sq0), [sq1] "r"(sq1)); - } - - __asm__ __volatile__( - "srl %[p6_l], %[p6_l], 16 \n\t" - "srl %[p5_l], %[p5_l], 16 \n\t" - "srl %[p4_l], %[p4_l], 16 \n\t" - "srl %[p3_l], %[p3_l], 16 \n\t" - "srl %[p2_l], %[p2_l], 16 \n\t" - "srl %[p1_l], %[p1_l], 16 \n\t" - "srl %[p0_l], %[p0_l], 16 \n\t" - "srl %[q0_l], %[q0_l], 16 \n\t" - "srl %[q1_l], %[q1_l], 16 \n\t" - "srl %[q2_l], %[q2_l], 16 \n\t" - "srl %[q3_l], %[q3_l], 16 \n\t" - "srl %[q4_l], %[q4_l], 16 \n\t" - "srl %[q5_l], %[q5_l], 16 \n\t" - "srl %[q6_l], %[q6_l], 16 \n\t" - - : [q0_l] "+r"(q0_l), [q1_l] "+r"(q1_l), [q2_l] "+r"(q2_l), - [q3_l] "+r"(q3_l), [q4_l] "+r"(q4_l), [q5_l] "+r"(q5_l), - [q6_l] "+r"(q6_l), [p6_l] "+r"(p6_l), [p5_l] "+r"(p5_l), - [p4_l] "+r"(p4_l), [p3_l] "+r"(p3_l), [p2_l] "+r"(p2_l), - [p1_l] "+r"(p1_l), [p0_l] "+r"(p0_l) - :); - - __asm__ __volatile__( - "srl %[p2_l_f1], %[p2_l_f1], 16 \n\t" - "srl %[p1_l_f1], %[p1_l_f1], 16 \n\t" - "srl %[p0_l_f1], %[p0_l_f1], 16 \n\t" - "srl %[q0_l_f1], %[q0_l_f1], 16 \n\t" - "srl %[q1_l_f1], %[q1_l_f1], 16 \n\t" - "srl %[q2_l_f1], %[q2_l_f1], 16 \n\t" - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p2_l_f1] "+r"(p2_l_f1), [p1_l_f1] "+r"(p1_l_f1), - [p0_l_f1] "+r"(p0_l_f1), [q0_l_f1] "+r"(q0_l_f1), - [q1_l_f1] "+r"(q1_l_f1), [q2_l_f1] "+r"(q2_l_f1), - [p1_f0] "+r"(p1_f0), [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), - [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & flat2 & 0xFF000000) { - __asm__ __volatile__( - "sb %[p6_l], +3(%[sp6]) \n\t" - "sb %[p5_l], +3(%[sp5]) \n\t" - "sb %[p4_l], +3(%[sp4]) \n\t" - "sb %[p3_l], +3(%[sp3]) \n\t" - "sb %[p2_l], +3(%[sp2]) \n\t" - "sb %[p1_l], +3(%[sp1]) \n\t" - "sb %[p0_l], +3(%[sp0]) \n\t" - - : - : [p6_l] "r"(p6_l), [p5_l] "r"(p5_l), [p4_l] "r"(p4_l), - [p3_l] "r"(p3_l), [p2_l] "r"(p2_l), [p1_l] "r"(p1_l), - [p0_l] "r"(p0_l), [sp6] "r"(sp6), [sp5] "r"(sp5), [sp4] "r"(sp4), - [sp3] "r"(sp3), [sp2] "r"(sp2), [sp1] "r"(sp1), [sp0] "r"(sp0)); - - __asm__ __volatile__( - "sb %[q0_l], +3(%[sq0]) \n\t" - "sb %[q1_l], +3(%[sq1]) \n\t" - "sb %[q2_l], +3(%[sq2]) \n\t" - "sb %[q3_l], +3(%[sq3]) \n\t" - "sb %[q4_l], +3(%[sq4]) \n\t" - "sb %[q5_l], +3(%[sq5]) \n\t" - "sb %[q6_l], +3(%[sq6]) \n\t" - - : - : [q0_l] "r"(q0_l), [q1_l] "r"(q1_l), [q2_l] "r"(q2_l), - [q3_l] "r"(q3_l), [q4_l] "r"(q4_l), [q5_l] "r"(q5_l), - [sq0] "r"(sq0), [sq1] "r"(sq1), [sq2] "r"(sq2), [sq3] "r"(sq3), - [sq4] "r"(sq4), [sq5] "r"(sq5), [q6_l] "r"(q6_l), [sq6] "r"(sq6)); - } else if (mask & flat & 0xFF000000) { - __asm__ __volatile__( - "sb %[p2_l_f1], +3(%[sp2]) \n\t" - "sb %[p1_l_f1], +3(%[sp1]) \n\t" - "sb %[p0_l_f1], +3(%[sp0]) \n\t" - "sb %[q0_l_f1], +3(%[sq0]) \n\t" - "sb %[q1_l_f1], +3(%[sq1]) \n\t" - "sb %[q2_l_f1], +3(%[sq2]) \n\t" - - : - : [p2_l_f1] "r"(p2_l_f1), [p1_l_f1] "r"(p1_l_f1), - [p0_l_f1] "r"(p0_l_f1), [q0_l_f1] "r"(q0_l_f1), - [q1_l_f1] "r"(q1_l_f1), [q2_l_f1] "r"(q2_l_f1), [sp2] "r"(sp2), - [sp1] "r"(sp1), [sp0] "r"(sp0), [sq0] "r"(sq0), [sq1] "r"(sq1), - [sq2] "r"(sq2)); - } else if (mask & 0xFF000000) { - __asm__ __volatile__( - "sb %[p1_f0], +3(%[sp1]) \n\t" - "sb %[p0_f0], +3(%[sp0]) \n\t" - "sb %[q0_f0], +3(%[sq0]) \n\t" - "sb %[q1_f0], +3(%[sq1]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [sp1] "r"(sp1), [sp0] "r"(sp0), - [sq0] "r"(sq0), [sq1] "r"(sq1)); - } - } - - s = s + 4; - } -} - -void vpx_lpf_horizontal_16_dspr2(unsigned char *s, int pitch, - const uint8_t *blimit, const uint8_t *limit, - const uint8_t *thresh) { - mb_lpf_horizontal_edge(s, pitch, blimit, limit, thresh, 1); -} - -void vpx_lpf_horizontal_16_dual_dspr2(unsigned char *s, int pitch, - const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh) { - mb_lpf_horizontal_edge(s, pitch, blimit, limit, thresh, 2); -} -#endif // #if HAVE_DSPR2 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_mb_vert_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_mb_vert_dspr2.c deleted file mode 100644 index 96e8d885..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_mb_vert_dspr2.c +++ /dev/null @@ -1,756 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/mips/common_dspr2.h" -#include "vpx_dsp/mips/loopfilter_filters_dspr2.h" -#include "vpx_dsp/mips/loopfilter_macros_dspr2.h" -#include "vpx_dsp/mips/loopfilter_masks_dspr2.h" -#include "vpx_mem/vpx_mem.h" - -#if HAVE_DSPR2 -void vpx_lpf_vertical_16_dspr2(uint8_t *s, int pitch, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh) { - uint8_t i; - uint32_t mask, hev, flat, flat2; - uint8_t *s1, *s2, *s3, *s4; - uint32_t prim1, prim2, sec3, sec4, prim3, prim4; - uint32_t thresh_vec, flimit_vec, limit_vec; - uint32_t uflimit, ulimit, uthresh; - uint32_t p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7; - uint32_t p1_f0, p0_f0, q0_f0, q1_f0; - uint32_t p7_l, p6_l, p5_l, p4_l, p3_l, p2_l, p1_l, p0_l; - uint32_t q0_l, q1_l, q2_l, q3_l, q4_l, q5_l, q6_l, q7_l; - uint32_t p7_r, p6_r, p5_r, p4_r, p3_r, p2_r, p1_r, p0_r; - uint32_t q0_r, q1_r, q2_r, q3_r, q4_r, q5_r, q6_r, q7_r; - uint32_t p2_l_f1, p1_l_f1, p0_l_f1, p2_r_f1, p1_r_f1, p0_r_f1; - uint32_t q0_l_f1, q1_l_f1, q2_l_f1, q0_r_f1, q1_r_f1, q2_r_f1; - - uflimit = *blimit; - ulimit = *limit; - uthresh = *thresh; - - /* create quad-byte */ - __asm__ __volatile__( - "replv.qb %[thresh_vec], %[uthresh] \n\t" - "replv.qb %[flimit_vec], %[uflimit] \n\t" - "replv.qb %[limit_vec], %[ulimit] \n\t" - - : [thresh_vec] "=&r"(thresh_vec), [flimit_vec] "=&r"(flimit_vec), - [limit_vec] "=r"(limit_vec) - : [uthresh] "r"(uthresh), [uflimit] "r"(uflimit), [ulimit] "r"(ulimit)); - - prefetch_store(s + pitch); - - for (i = 0; i < 2; i++) { - s1 = s; - s2 = s + pitch; - s3 = s2 + pitch; - s4 = s3 + pitch; - s = s4 + pitch; - - __asm__ __volatile__( - "lw %[p0], -4(%[s1]) \n\t" - "lw %[p1], -4(%[s2]) \n\t" - "lw %[p2], -4(%[s3]) \n\t" - "lw %[p3], -4(%[s4]) \n\t" - "lw %[p4], -8(%[s1]) \n\t" - "lw %[p5], -8(%[s2]) \n\t" - "lw %[p6], -8(%[s3]) \n\t" - "lw %[p7], -8(%[s4]) \n\t" - - : [p3] "=&r"(p3), [p2] "=&r"(p2), [p1] "=&r"(p1), [p0] "=&r"(p0), - [p7] "=&r"(p7), [p6] "=&r"(p6), [p5] "=&r"(p5), [p4] "=&r"(p4) - : [s1] "r"(s1), [s2] "r"(s2), [s3] "r"(s3), [s4] "r"(s4)); - - __asm__ __volatile__( - "lw %[q3], (%[s1]) \n\t" - "lw %[q2], (%[s2]) \n\t" - "lw %[q1], (%[s3]) \n\t" - "lw %[q0], (%[s4]) \n\t" - "lw %[q7], +4(%[s1]) \n\t" - "lw %[q6], +4(%[s2]) \n\t" - "lw %[q5], +4(%[s3]) \n\t" - "lw %[q4], +4(%[s4]) \n\t" - - : [q3] "=&r"(q3), [q2] "=&r"(q2), [q1] "=&r"(q1), [q0] "=&r"(q0), - [q7] "=&r"(q7), [q6] "=&r"(q6), [q5] "=&r"(q5), [q4] "=&r"(q4) - : [s1] "r"(s1), [s2] "r"(s2), [s3] "r"(s3), [s4] "r"(s4)); - - /* transpose p3, p2, p1, p0 - original (when loaded from memory) - register -4 -3 -2 -1 - p0 p0_0 p0_1 p0_2 p0_3 - p1 p1_0 p1_1 p1_2 p1_3 - p2 p2_0 p2_1 p2_2 p2_3 - p3 p3_0 p3_1 p3_2 p3_3 - - after transpose - register - p0 p3_3 p2_3 p1_3 p0_3 - p1 p3_2 p2_2 p1_2 p0_2 - p2 p3_1 p2_1 p1_1 p0_1 - p3 p3_0 p2_0 p1_0 p0_0 - */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p0], %[p1] \n\t" - "precr.qb.ph %[prim2], %[p0], %[p1] \n\t" - "precrq.qb.ph %[prim3], %[p2], %[p3] \n\t" - "precr.qb.ph %[prim4], %[p2], %[p3] \n\t" - - "precrq.qb.ph %[p1], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[p3], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p0], %[p1], %[sec3] \n\t" - "precrq.ph.w %[p2], %[p3], %[sec4] \n\t" - "append %[p1], %[sec3], 16 \n\t" - "append %[p3], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p0] "+r"(p0), [p1] "+r"(p1), [p2] "+r"(p2), - [p3] "+r"(p3), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* transpose q0, q1, q2, q3 - original (when loaded from memory) - register +1 +2 +3 +4 - q3 q3_0 q3_1 q3_2 q3_3 - q2 q2_0 q2_1 q2_2 q2_3 - q1 q1_0 q1_1 q1_2 q1_3 - q0 q0_0 q0_1 q0_2 q0_3 - - after transpose - register - q3 q0_3 q1_3 q2_3 q3_3 - q2 q0_2 q1_2 q2_2 q3_2 - q1 q0_1 q1_1 q2_1 q3_1 - q0 q0_0 q1_0 q2_0 q3_0 - */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[q3], %[q2] \n\t" - "precr.qb.ph %[prim2], %[q3], %[q2] \n\t" - "precrq.qb.ph %[prim3], %[q1], %[q0] \n\t" - "precr.qb.ph %[prim4], %[q1], %[q0] \n\t" - - "precrq.qb.ph %[q2], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[q0], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[q3], %[q2], %[sec3] \n\t" - "precrq.ph.w %[q1], %[q0], %[sec4] \n\t" - "append %[q2], %[sec3], 16 \n\t" - "append %[q0], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [q3] "+r"(q3), [q2] "+r"(q2), [q1] "+r"(q1), - [q0] "+r"(q0), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* transpose p7, p6, p5, p4 - original (when loaded from memory) - register -8 -7 -6 -5 - p4 p4_0 p4_1 p4_2 p4_3 - p5 p5_0 p5_1 p5_2 p5_3 - p6 p6_0 p6_1 p6_2 p6_3 - p7 p7_0 p7_1 p7_2 p7_3 - - after transpose - register - p4 p7_3 p6_3 p5_3 p4_3 - p5 p7_2 p6_2 p5_2 p4_2 - p6 p7_1 p6_1 p5_1 p4_1 - p7 p7_0 p6_0 p5_0 p4_0 - */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[p4], %[p5] \n\t" - "precr.qb.ph %[prim2], %[p4], %[p5] \n\t" - "precrq.qb.ph %[prim3], %[p6], %[p7] \n\t" - "precr.qb.ph %[prim4], %[p6], %[p7] \n\t" - - "precrq.qb.ph %[p5], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[p7], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[p4], %[p5], %[sec3] \n\t" - "precrq.ph.w %[p6], %[p7], %[sec4] \n\t" - "append %[p5], %[sec3], 16 \n\t" - "append %[p7], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [p4] "+r"(p4), [p5] "+r"(p5), [p6] "+r"(p6), - [p7] "+r"(p7), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - /* transpose q4, q5, q6, q7 - original (when loaded from memory) - register +5 +6 +7 +8 - q7 q7_0 q7_1 q7_2 q7_3 - q6 q6_0 q6_1 q6_2 q6_3 - q5 q5_0 q5_1 q5_2 q5_3 - q4 q4_0 q4_1 q4_2 q4_3 - - after transpose - register - q7 q4_3 q5_3 q26_3 q7_3 - q6 q4_2 q5_2 q26_2 q7_2 - q5 q4_1 q5_1 q26_1 q7_1 - q4 q4_0 q5_0 q26_0 q7_0 - */ - __asm__ __volatile__( - "precrq.qb.ph %[prim1], %[q7], %[q6] \n\t" - "precr.qb.ph %[prim2], %[q7], %[q6] \n\t" - "precrq.qb.ph %[prim3], %[q5], %[q4] \n\t" - "precr.qb.ph %[prim4], %[q5], %[q4] \n\t" - - "precrq.qb.ph %[q6], %[prim1], %[prim2] \n\t" - "precr.qb.ph %[q4], %[prim1], %[prim2] \n\t" - "precrq.qb.ph %[sec3], %[prim3], %[prim4] \n\t" - "precr.qb.ph %[sec4], %[prim3], %[prim4] \n\t" - - "precrq.ph.w %[q7], %[q6], %[sec3] \n\t" - "precrq.ph.w %[q5], %[q4], %[sec4] \n\t" - "append %[q6], %[sec3], 16 \n\t" - "append %[q4], %[sec4], 16 \n\t" - - : [prim1] "=&r"(prim1), [prim2] "=&r"(prim2), [prim3] "=&r"(prim3), - [prim4] "=&r"(prim4), [q7] "+r"(q7), [q6] "+r"(q6), [q5] "+r"(q5), - [q4] "+r"(q4), [sec3] "=&r"(sec3), [sec4] "=&r"(sec4) - :); - - filter_hev_mask_flatmask4_dspr2(limit_vec, flimit_vec, thresh_vec, p1, p0, - p3, p2, q0, q1, q2, q3, &hev, &mask, &flat); - - flatmask5(p7, p6, p5, p4, p0, q0, q4, q5, q6, q7, &flat2); - - /* f0 */ - if (((flat2 == 0) && (flat == 0) && (mask != 0)) || - ((flat2 != 0) && (flat == 0) && (mask != 0))) { - filter1_dspr2(mask, hev, p1, p0, q0, q1, &p1_f0, &p0_f0, &q0_f0, &q1_f0); - STORE_F0() - } else if ((flat2 == 0XFFFFFFFF) && (flat == 0xFFFFFFFF) && - (mask == 0xFFFFFFFF)) { - /* f2 */ - PACK_LEFT_0TO3() - PACK_LEFT_4TO7() - wide_mbfilter_dspr2(&p7_l, &p6_l, &p5_l, &p4_l, &p3_l, &p2_l, &p1_l, - &p0_l, &q0_l, &q1_l, &q2_l, &q3_l, &q4_l, &q5_l, - &q6_l, &q7_l); - - PACK_RIGHT_0TO3() - PACK_RIGHT_4TO7() - wide_mbfilter_dspr2(&p7_r, &p6_r, &p5_r, &p4_r, &p3_r, &p2_r, &p1_r, - &p0_r, &q0_r, &q1_r, &q2_r, &q3_r, &q4_r, &q5_r, - &q6_r, &q7_r); - - STORE_F2() - } else if ((flat2 == 0) && (flat == 0xFFFFFFFF) && (mask == 0xFFFFFFFF)) { - /* f1 */ - PACK_LEFT_0TO3() - mbfilter_dspr2(&p3_l, &p2_l, &p1_l, &p0_l, &q0_l, &q1_l, &q2_l, &q3_l); - - PACK_RIGHT_0TO3() - mbfilter_dspr2(&p3_r, &p2_r, &p1_r, &p0_r, &q0_r, &q1_r, &q2_r, &q3_r); - - STORE_F1() - } else if ((flat2 == 0) && (flat != 0) && (mask != 0)) { - /* f0 + f1 */ - filter1_dspr2(mask, hev, p1, p0, q0, q1, &p1_f0, &p0_f0, &q0_f0, &q1_f0); - - /* left 2 element operation */ - PACK_LEFT_0TO3() - mbfilter_dspr2(&p3_l, &p2_l, &p1_l, &p0_l, &q0_l, &q1_l, &q2_l, &q3_l); - - /* right 2 element operation */ - PACK_RIGHT_0TO3() - mbfilter_dspr2(&p3_r, &p2_r, &p1_r, &p0_r, &q0_r, &q1_r, &q2_r, &q3_r); - - if (mask & flat & 0x000000FF) { - __asm__ __volatile__( - "sb %[p2_r], -3(%[s4]) \n\t" - "sb %[p1_r], -2(%[s4]) \n\t" - "sb %[p0_r], -1(%[s4]) \n\t" - "sb %[q0_r], (%[s4]) \n\t" - "sb %[q1_r], +1(%[s4]) \n\t" - "sb %[q2_r], +2(%[s4]) \n\t" - - : - : [p2_r] "r"(p2_r), [p1_r] "r"(p1_r), [p0_r] "r"(p0_r), - [q0_r] "r"(q0_r), [q1_r] "r"(q1_r), [q2_r] "r"(q2_r), - [s4] "r"(s4)); - } else if (mask & 0x000000FF) { - __asm__ __volatile__( - "sb %[p1_f0], -2(%[s4]) \n\t" - "sb %[p0_f0], -1(%[s4]) \n\t" - "sb %[q0_f0], (%[s4]) \n\t" - "sb %[q1_f0], +1(%[s4]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [s4] "r"(s4)); - } - - __asm__ __volatile__( - "srl %[p2_r], %[p2_r], 16 \n\t" - "srl %[p1_r], %[p1_r], 16 \n\t" - "srl %[p0_r], %[p0_r], 16 \n\t" - "srl %[q0_r], %[q0_r], 16 \n\t" - "srl %[q1_r], %[q1_r], 16 \n\t" - "srl %[q2_r], %[q2_r], 16 \n\t" - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p2_r] "+r"(p2_r), [p1_r] "+r"(p1_r), [p0_r] "+r"(p0_r), - [q0_r] "+r"(q0_r), [q1_r] "+r"(q1_r), [q2_r] "+r"(q2_r), - [p1_f0] "+r"(p1_f0), [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), - [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & 0x0000FF00) { - __asm__ __volatile__( - "sb %[p2_r], -3(%[s3]) \n\t" - "sb %[p1_r], -2(%[s3]) \n\t" - "sb %[p0_r], -1(%[s3]) \n\t" - "sb %[q0_r], (%[s3]) \n\t" - "sb %[q1_r], +1(%[s3]) \n\t" - "sb %[q2_r], +2(%[s3]) \n\t" - - : - : [p2_r] "r"(p2_r), [p1_r] "r"(p1_r), [p0_r] "r"(p0_r), - [q0_r] "r"(q0_r), [q1_r] "r"(q1_r), [q2_r] "r"(q2_r), - [s3] "r"(s3)); - } else if (mask & 0x0000FF00) { - __asm__ __volatile__( - "sb %[p1_f0], -2(%[s3]) \n\t" - "sb %[p0_f0], -1(%[s3]) \n\t" - "sb %[q0_f0], (%[s3]) \n\t" - "sb %[q1_f0], +1(%[s3]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [s3] "r"(s3)); - } - - __asm__ __volatile__( - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p1_f0] "+r"(p1_f0), [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), - [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & 0x00FF0000) { - __asm__ __volatile__( - "sb %[p2_l], -3(%[s2]) \n\t" - "sb %[p1_l], -2(%[s2]) \n\t" - "sb %[p0_l], -1(%[s2]) \n\t" - "sb %[q0_l], (%[s2]) \n\t" - "sb %[q1_l], +1(%[s2]) \n\t" - "sb %[q2_l], +2(%[s2]) \n\t" - - : - : [p2_l] "r"(p2_l), [p1_l] "r"(p1_l), [p0_l] "r"(p0_l), - [q0_l] "r"(q0_l), [q1_l] "r"(q1_l), [q2_l] "r"(q2_l), - [s2] "r"(s2)); - } else if (mask & 0x00FF0000) { - __asm__ __volatile__( - "sb %[p1_f0], -2(%[s2]) \n\t" - "sb %[p0_f0], -1(%[s2]) \n\t" - "sb %[q0_f0], (%[s2]) \n\t" - "sb %[q1_f0], +1(%[s2]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [s2] "r"(s2)); - } - - __asm__ __volatile__( - "srl %[p2_l], %[p2_l], 16 \n\t" - "srl %[p1_l], %[p1_l], 16 \n\t" - "srl %[p0_l], %[p0_l], 16 \n\t" - "srl %[q0_l], %[q0_l], 16 \n\t" - "srl %[q1_l], %[q1_l], 16 \n\t" - "srl %[q2_l], %[q2_l], 16 \n\t" - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p2_l] "+r"(p2_l), [p1_l] "+r"(p1_l), [p0_l] "+r"(p0_l), - [q0_l] "+r"(q0_l), [q1_l] "+r"(q1_l), [q2_l] "+r"(q2_l), - [p1_f0] "+r"(p1_f0), [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), - [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & 0xFF000000) { - __asm__ __volatile__( - "sb %[p2_l], -3(%[s1]) \n\t" - "sb %[p1_l], -2(%[s1]) \n\t" - "sb %[p0_l], -1(%[s1]) \n\t" - "sb %[q0_l], (%[s1]) \n\t" - "sb %[q1_l], +1(%[s1]) \n\t" - "sb %[q2_l], +2(%[s1]) \n\t" - - : - : [p2_l] "r"(p2_l), [p1_l] "r"(p1_l), [p0_l] "r"(p0_l), - [q0_l] "r"(q0_l), [q1_l] "r"(q1_l), [q2_l] "r"(q2_l), - [s1] "r"(s1)); - } else if (mask & 0xFF000000) { - __asm__ __volatile__( - "sb %[p1_f0], -2(%[s1]) \n\t" - "sb %[p0_f0], -1(%[s1]) \n\t" - "sb %[q0_f0], (%[s1]) \n\t" - "sb %[q1_f0], +1(%[s1]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [s1] "r"(s1)); - } - } else if ((flat2 != 0) && (flat != 0) && (mask != 0)) { - /* f0+f1+f2 */ - filter1_dspr2(mask, hev, p1, p0, q0, q1, &p1_f0, &p0_f0, &q0_f0, &q1_f0); - - PACK_LEFT_0TO3() - mbfilter1_dspr2(p3_l, p2_l, p1_l, p0_l, q0_l, q1_l, q2_l, q3_l, &p2_l_f1, - &p1_l_f1, &p0_l_f1, &q0_l_f1, &q1_l_f1, &q2_l_f1); - - PACK_RIGHT_0TO3() - mbfilter1_dspr2(p3_r, p2_r, p1_r, p0_r, q0_r, q1_r, q2_r, q3_r, &p2_r_f1, - &p1_r_f1, &p0_r_f1, &q0_r_f1, &q1_r_f1, &q2_r_f1); - - PACK_LEFT_4TO7() - wide_mbfilter_dspr2(&p7_l, &p6_l, &p5_l, &p4_l, &p3_l, &p2_l, &p1_l, - &p0_l, &q0_l, &q1_l, &q2_l, &q3_l, &q4_l, &q5_l, - &q6_l, &q7_l); - - PACK_RIGHT_4TO7() - wide_mbfilter_dspr2(&p7_r, &p6_r, &p5_r, &p4_r, &p3_r, &p2_r, &p1_r, - &p0_r, &q0_r, &q1_r, &q2_r, &q3_r, &q4_r, &q5_r, - &q6_r, &q7_r); - - if (mask & flat & flat2 & 0x000000FF) { - __asm__ __volatile__( - "sb %[p6_r], -7(%[s4]) \n\t" - "sb %[p5_r], -6(%[s4]) \n\t" - "sb %[p4_r], -5(%[s4]) \n\t" - "sb %[p3_r], -4(%[s4]) \n\t" - "sb %[p2_r], -3(%[s4]) \n\t" - "sb %[p1_r], -2(%[s4]) \n\t" - "sb %[p0_r], -1(%[s4]) \n\t" - - : - : [p6_r] "r"(p6_r), [p5_r] "r"(p5_r), [p4_r] "r"(p4_r), - [p3_r] "r"(p3_r), [p2_r] "r"(p2_r), [p1_r] "r"(p1_r), - [p0_r] "r"(p0_r), [s4] "r"(s4)); - - __asm__ __volatile__( - "sb %[q0_r], (%[s4]) \n\t" - "sb %[q1_r], +1(%[s4]) \n\t" - "sb %[q2_r], +2(%[s4]) \n\t" - "sb %[q3_r], +3(%[s4]) \n\t" - "sb %[q4_r], +4(%[s4]) \n\t" - "sb %[q5_r], +5(%[s4]) \n\t" - "sb %[q6_r], +6(%[s4]) \n\t" - - : - : [q0_r] "r"(q0_r), [q1_r] "r"(q1_r), [q2_r] "r"(q2_r), - [q3_r] "r"(q3_r), [q4_r] "r"(q4_r), [q5_r] "r"(q5_r), - [q6_r] "r"(q6_r), [s4] "r"(s4)); - } else if (mask & flat & 0x000000FF) { - __asm__ __volatile__( - "sb %[p2_r_f1], -3(%[s4]) \n\t" - "sb %[p1_r_f1], -2(%[s4]) \n\t" - "sb %[p0_r_f1], -1(%[s4]) \n\t" - "sb %[q0_r_f1], (%[s4]) \n\t" - "sb %[q1_r_f1], +1(%[s4]) \n\t" - "sb %[q2_r_f1], +2(%[s4]) \n\t" - - : - : [p2_r_f1] "r"(p2_r_f1), [p1_r_f1] "r"(p1_r_f1), - [p0_r_f1] "r"(p0_r_f1), [q0_r_f1] "r"(q0_r_f1), - [q1_r_f1] "r"(q1_r_f1), [q2_r_f1] "r"(q2_r_f1), [s4] "r"(s4)); - } else if (mask & 0x000000FF) { - __asm__ __volatile__( - "sb %[p1_f0], -2(%[s4]) \n\t" - "sb %[p0_f0], -1(%[s4]) \n\t" - "sb %[q0_f0], (%[s4]) \n\t" - "sb %[q1_f0], +1(%[s4]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [s4] "r"(s4)); - } - - __asm__ __volatile__( - "srl %[p6_r], %[p6_r], 16 \n\t" - "srl %[p5_r], %[p5_r], 16 \n\t" - "srl %[p4_r], %[p4_r], 16 \n\t" - "srl %[p3_r], %[p3_r], 16 \n\t" - "srl %[p2_r], %[p2_r], 16 \n\t" - "srl %[p1_r], %[p1_r], 16 \n\t" - "srl %[p0_r], %[p0_r], 16 \n\t" - "srl %[q0_r], %[q0_r], 16 \n\t" - "srl %[q1_r], %[q1_r], 16 \n\t" - "srl %[q2_r], %[q2_r], 16 \n\t" - "srl %[q3_r], %[q3_r], 16 \n\t" - "srl %[q4_r], %[q4_r], 16 \n\t" - "srl %[q5_r], %[q5_r], 16 \n\t" - "srl %[q6_r], %[q6_r], 16 \n\t" - - : [q0_r] "+r"(q0_r), [q1_r] "+r"(q1_r), [q2_r] "+r"(q2_r), - [q3_r] "+r"(q3_r), [q4_r] "+r"(q4_r), [q5_r] "+r"(q5_r), - [q6_r] "+r"(q6_r), [p6_r] "+r"(p6_r), [p5_r] "+r"(p5_r), - [p4_r] "+r"(p4_r), [p3_r] "+r"(p3_r), [p2_r] "+r"(p2_r), - [p1_r] "+r"(p1_r), [p0_r] "+r"(p0_r) - :); - - __asm__ __volatile__( - "srl %[p2_r_f1], %[p2_r_f1], 16 \n\t" - "srl %[p1_r_f1], %[p1_r_f1], 16 \n\t" - "srl %[p0_r_f1], %[p0_r_f1], 16 \n\t" - "srl %[q0_r_f1], %[q0_r_f1], 16 \n\t" - "srl %[q1_r_f1], %[q1_r_f1], 16 \n\t" - "srl %[q2_r_f1], %[q2_r_f1], 16 \n\t" - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p2_r_f1] "+r"(p2_r_f1), [p1_r_f1] "+r"(p1_r_f1), - [p0_r_f1] "+r"(p0_r_f1), [q0_r_f1] "+r"(q0_r_f1), - [q1_r_f1] "+r"(q1_r_f1), [q2_r_f1] "+r"(q2_r_f1), - [p1_f0] "+r"(p1_f0), [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), - [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & flat2 & 0x0000FF00) { - __asm__ __volatile__( - "sb %[p6_r], -7(%[s3]) \n\t" - "sb %[p5_r], -6(%[s3]) \n\t" - "sb %[p4_r], -5(%[s3]) \n\t" - "sb %[p3_r], -4(%[s3]) \n\t" - "sb %[p2_r], -3(%[s3]) \n\t" - "sb %[p1_r], -2(%[s3]) \n\t" - "sb %[p0_r], -1(%[s3]) \n\t" - - : - : [p6_r] "r"(p6_r), [p5_r] "r"(p5_r), [p4_r] "r"(p4_r), - [p3_r] "r"(p3_r), [p2_r] "r"(p2_r), [p1_r] "r"(p1_r), - [p0_r] "r"(p0_r), [s3] "r"(s3)); - - __asm__ __volatile__( - "sb %[q0_r], (%[s3]) \n\t" - "sb %[q1_r], +1(%[s3]) \n\t" - "sb %[q2_r], +2(%[s3]) \n\t" - "sb %[q3_r], +3(%[s3]) \n\t" - "sb %[q4_r], +4(%[s3]) \n\t" - "sb %[q5_r], +5(%[s3]) \n\t" - "sb %[q6_r], +6(%[s3]) \n\t" - - : - : [q0_r] "r"(q0_r), [q1_r] "r"(q1_r), [q2_r] "r"(q2_r), - [q3_r] "r"(q3_r), [q4_r] "r"(q4_r), [q5_r] "r"(q5_r), - [q6_r] "r"(q6_r), [s3] "r"(s3)); - } else if (mask & flat & 0x0000FF00) { - __asm__ __volatile__( - "sb %[p2_r_f1], -3(%[s3]) \n\t" - "sb %[p1_r_f1], -2(%[s3]) \n\t" - "sb %[p0_r_f1], -1(%[s3]) \n\t" - "sb %[q0_r_f1], (%[s3]) \n\t" - "sb %[q1_r_f1], +1(%[s3]) \n\t" - "sb %[q2_r_f1], +2(%[s3]) \n\t" - - : - : [p2_r_f1] "r"(p2_r_f1), [p1_r_f1] "r"(p1_r_f1), - [p0_r_f1] "r"(p0_r_f1), [q0_r_f1] "r"(q0_r_f1), - [q1_r_f1] "r"(q1_r_f1), [q2_r_f1] "r"(q2_r_f1), [s3] "r"(s3)); - } else if (mask & 0x0000FF00) { - __asm__ __volatile__( - "sb %[p1_f0], -2(%[s3]) \n\t" - "sb %[p0_f0], -1(%[s3]) \n\t" - "sb %[q0_f0], (%[s3]) \n\t" - "sb %[q1_f0], +1(%[s3]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [s3] "r"(s3)); - } - - __asm__ __volatile__( - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p1_f0] "+r"(p1_f0), [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), - [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & flat2 & 0x00FF0000) { - __asm__ __volatile__( - "sb %[p6_l], -7(%[s2]) \n\t" - "sb %[p5_l], -6(%[s2]) \n\t" - "sb %[p4_l], -5(%[s2]) \n\t" - "sb %[p3_l], -4(%[s2]) \n\t" - "sb %[p2_l], -3(%[s2]) \n\t" - "sb %[p1_l], -2(%[s2]) \n\t" - "sb %[p0_l], -1(%[s2]) \n\t" - - : - : [p6_l] "r"(p6_l), [p5_l] "r"(p5_l), [p4_l] "r"(p4_l), - [p3_l] "r"(p3_l), [p2_l] "r"(p2_l), [p1_l] "r"(p1_l), - [p0_l] "r"(p0_l), [s2] "r"(s2)); - - __asm__ __volatile__( - "sb %[q0_l], (%[s2]) \n\t" - "sb %[q1_l], +1(%[s2]) \n\t" - "sb %[q2_l], +2(%[s2]) \n\t" - "sb %[q3_l], +3(%[s2]) \n\t" - "sb %[q4_l], +4(%[s2]) \n\t" - "sb %[q5_l], +5(%[s2]) \n\t" - "sb %[q6_l], +6(%[s2]) \n\t" - - : - : [q0_l] "r"(q0_l), [q1_l] "r"(q1_l), [q2_l] "r"(q2_l), - [q3_l] "r"(q3_l), [q4_l] "r"(q4_l), [q5_l] "r"(q5_l), - [q6_l] "r"(q6_l), [s2] "r"(s2)); - } else if (mask & flat & 0x00FF0000) { - __asm__ __volatile__( - "sb %[p2_l_f1], -3(%[s2]) \n\t" - "sb %[p1_l_f1], -2(%[s2]) \n\t" - "sb %[p0_l_f1], -1(%[s2]) \n\t" - "sb %[q0_l_f1], (%[s2]) \n\t" - "sb %[q1_l_f1], +1(%[s2]) \n\t" - "sb %[q2_l_f1], +2(%[s2]) \n\t" - - : - : [p2_l_f1] "r"(p2_l_f1), [p1_l_f1] "r"(p1_l_f1), - [p0_l_f1] "r"(p0_l_f1), [q0_l_f1] "r"(q0_l_f1), - [q1_l_f1] "r"(q1_l_f1), [q2_l_f1] "r"(q2_l_f1), [s2] "r"(s2)); - } else if (mask & 0x00FF0000) { - __asm__ __volatile__( - "sb %[p1_f0], -2(%[s2]) \n\t" - "sb %[p0_f0], -1(%[s2]) \n\t" - "sb %[q0_f0], (%[s2]) \n\t" - "sb %[q1_f0], +1(%[s2]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [s2] "r"(s2)); - } - - __asm__ __volatile__( - "srl %[p6_l], %[p6_l], 16 \n\t" - "srl %[p5_l], %[p5_l], 16 \n\t" - "srl %[p4_l], %[p4_l], 16 \n\t" - "srl %[p3_l], %[p3_l], 16 \n\t" - "srl %[p2_l], %[p2_l], 16 \n\t" - "srl %[p1_l], %[p1_l], 16 \n\t" - "srl %[p0_l], %[p0_l], 16 \n\t" - "srl %[q0_l], %[q0_l], 16 \n\t" - "srl %[q1_l], %[q1_l], 16 \n\t" - "srl %[q2_l], %[q2_l], 16 \n\t" - "srl %[q3_l], %[q3_l], 16 \n\t" - "srl %[q4_l], %[q4_l], 16 \n\t" - "srl %[q5_l], %[q5_l], 16 \n\t" - "srl %[q6_l], %[q6_l], 16 \n\t" - - : [q0_l] "+r"(q0_l), [q1_l] "+r"(q1_l), [q2_l] "+r"(q2_l), - [q3_l] "+r"(q3_l), [q4_l] "+r"(q4_l), [q5_l] "+r"(q5_l), - [q6_l] "+r"(q6_l), [p6_l] "+r"(p6_l), [p5_l] "+r"(p5_l), - [p4_l] "+r"(p4_l), [p3_l] "+r"(p3_l), [p2_l] "+r"(p2_l), - [p1_l] "+r"(p1_l), [p0_l] "+r"(p0_l) - :); - - __asm__ __volatile__( - "srl %[p2_l_f1], %[p2_l_f1], 16 \n\t" - "srl %[p1_l_f1], %[p1_l_f1], 16 \n\t" - "srl %[p0_l_f1], %[p0_l_f1], 16 \n\t" - "srl %[q0_l_f1], %[q0_l_f1], 16 \n\t" - "srl %[q1_l_f1], %[q1_l_f1], 16 \n\t" - "srl %[q2_l_f1], %[q2_l_f1], 16 \n\t" - "srl %[p1_f0], %[p1_f0], 8 \n\t" - "srl %[p0_f0], %[p0_f0], 8 \n\t" - "srl %[q0_f0], %[q0_f0], 8 \n\t" - "srl %[q1_f0], %[q1_f0], 8 \n\t" - - : [p2_l_f1] "+r"(p2_l_f1), [p1_l_f1] "+r"(p1_l_f1), - [p0_l_f1] "+r"(p0_l_f1), [q0_l_f1] "+r"(q0_l_f1), - [q1_l_f1] "+r"(q1_l_f1), [q2_l_f1] "+r"(q2_l_f1), - [p1_f0] "+r"(p1_f0), [p0_f0] "+r"(p0_f0), [q0_f0] "+r"(q0_f0), - [q1_f0] "+r"(q1_f0) - :); - - if (mask & flat & flat2 & 0xFF000000) { - __asm__ __volatile__( - "sb %[p6_l], -7(%[s1]) \n\t" - "sb %[p5_l], -6(%[s1]) \n\t" - "sb %[p4_l], -5(%[s1]) \n\t" - "sb %[p3_l], -4(%[s1]) \n\t" - "sb %[p2_l], -3(%[s1]) \n\t" - "sb %[p1_l], -2(%[s1]) \n\t" - "sb %[p0_l], -1(%[s1]) \n\t" - - : - : [p6_l] "r"(p6_l), [p5_l] "r"(p5_l), [p4_l] "r"(p4_l), - [p3_l] "r"(p3_l), [p2_l] "r"(p2_l), [p1_l] "r"(p1_l), - [p0_l] "r"(p0_l), [s1] "r"(s1)); - - __asm__ __volatile__( - "sb %[q0_l], (%[s1]) \n\t" - "sb %[q1_l], 1(%[s1]) \n\t" - "sb %[q2_l], 2(%[s1]) \n\t" - "sb %[q3_l], 3(%[s1]) \n\t" - "sb %[q4_l], 4(%[s1]) \n\t" - "sb %[q5_l], 5(%[s1]) \n\t" - "sb %[q6_l], 6(%[s1]) \n\t" - - : - : [q0_l] "r"(q0_l), [q1_l] "r"(q1_l), [q2_l] "r"(q2_l), - [q3_l] "r"(q3_l), [q4_l] "r"(q4_l), [q5_l] "r"(q5_l), - [q6_l] "r"(q6_l), [s1] "r"(s1)); - } else if (mask & flat & 0xFF000000) { - __asm__ __volatile__( - "sb %[p2_l_f1], -3(%[s1]) \n\t" - "sb %[p1_l_f1], -2(%[s1]) \n\t" - "sb %[p0_l_f1], -1(%[s1]) \n\t" - "sb %[q0_l_f1], (%[s1]) \n\t" - "sb %[q1_l_f1], +1(%[s1]) \n\t" - "sb %[q2_l_f1], +2(%[s1]) \n\t" - - : - : [p2_l_f1] "r"(p2_l_f1), [p1_l_f1] "r"(p1_l_f1), - [p0_l_f1] "r"(p0_l_f1), [q0_l_f1] "r"(q0_l_f1), - [q1_l_f1] "r"(q1_l_f1), [q2_l_f1] "r"(q2_l_f1), [s1] "r"(s1)); - } else if (mask & 0xFF000000) { - __asm__ __volatile__( - "sb %[p1_f0], -2(%[s1]) \n\t" - "sb %[p0_f0], -1(%[s1]) \n\t" - "sb %[q0_f0], (%[s1]) \n\t" - "sb %[q1_f0], +1(%[s1]) \n\t" - - : - : [p1_f0] "r"(p1_f0), [p0_f0] "r"(p0_f0), [q0_f0] "r"(q0_f0), - [q1_f0] "r"(q1_f0), [s1] "r"(s1)); - } - } - } -} -#endif // #if HAVE_DSPR2 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_msa.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_msa.h deleted file mode 100644 index 1ea05e0b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/loopfilter_msa.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_MIPS_LOOPFILTER_MSA_H_ -#define VPX_VPX_DSP_MIPS_LOOPFILTER_MSA_H_ - -#include "vpx_dsp/mips/macros_msa.h" - -#define VP9_LPF_FILTER4_4W(p1_in, p0_in, q0_in, q1_in, mask, hev, p1_out, \ - p0_out, q0_out, q1_out) \ - { \ - v16i8 p1_m, p0_m, q0_m, q1_m, filt, q0_sub_p0, t1, t2; \ - const v16i8 cnst4b = __msa_ldi_b(4); \ - const v16i8 cnst3b = __msa_ldi_b(3); \ - \ - p1_m = (v16i8)__msa_xori_b(p1_in, 0x80); \ - p0_m = (v16i8)__msa_xori_b(p0_in, 0x80); \ - q0_m = (v16i8)__msa_xori_b(q0_in, 0x80); \ - q1_m = (v16i8)__msa_xori_b(q1_in, 0x80); \ - \ - filt = __msa_subs_s_b(p1_m, q1_m); \ - filt &= hev; \ - q0_sub_p0 = __msa_subs_s_b(q0_m, p0_m); \ - filt = __msa_adds_s_b(filt, q0_sub_p0); \ - filt = __msa_adds_s_b(filt, q0_sub_p0); \ - filt = __msa_adds_s_b(filt, q0_sub_p0); \ - filt &= mask; \ - t1 = __msa_adds_s_b(filt, cnst4b); \ - t1 >>= cnst3b; \ - t2 = __msa_adds_s_b(filt, cnst3b); \ - t2 >>= cnst3b; \ - q0_m = __msa_subs_s_b(q0_m, t1); \ - q0_out = __msa_xori_b((v16u8)q0_m, 0x80); \ - p0_m = __msa_adds_s_b(p0_m, t2); \ - p0_out = __msa_xori_b((v16u8)p0_m, 0x80); \ - filt = __msa_srari_b(t1, 1); \ - hev = __msa_xori_b(hev, 0xff); \ - filt &= hev; \ - q1_m = __msa_subs_s_b(q1_m, filt); \ - q1_out = __msa_xori_b((v16u8)q1_m, 0x80); \ - p1_m = __msa_adds_s_b(p1_m, filt); \ - p1_out = __msa_xori_b((v16u8)p1_m, 0x80); \ - } - -#define VP9_FLAT4(p3_in, p2_in, p0_in, q0_in, q2_in, q3_in, flat_out) \ - { \ - v16u8 tmp_flat4, p2_a_sub_p0, q2_a_sub_q0, p3_a_sub_p0, q3_a_sub_q0; \ - v16u8 zero_in = { 0 }; \ - \ - tmp_flat4 = __msa_ori_b(zero_in, 1); \ - p2_a_sub_p0 = __msa_asub_u_b(p2_in, p0_in); \ - q2_a_sub_q0 = __msa_asub_u_b(q2_in, q0_in); \ - p3_a_sub_p0 = __msa_asub_u_b(p3_in, p0_in); \ - q3_a_sub_q0 = __msa_asub_u_b(q3_in, q0_in); \ - \ - p2_a_sub_p0 = __msa_max_u_b(p2_a_sub_p0, q2_a_sub_q0); \ - flat_out = __msa_max_u_b(p2_a_sub_p0, flat_out); \ - p3_a_sub_p0 = __msa_max_u_b(p3_a_sub_p0, q3_a_sub_q0); \ - flat_out = __msa_max_u_b(p3_a_sub_p0, flat_out); \ - \ - flat_out = (tmp_flat4 < (v16u8)flat_out); \ - flat_out = __msa_xori_b(flat_out, 0xff); \ - flat_out = flat_out & (mask); \ - } - -#define VP9_FLAT5(p7_in, p6_in, p5_in, p4_in, p0_in, q0_in, q4_in, q5_in, \ - q6_in, q7_in, flat_in, flat2_out) \ - { \ - v16u8 tmp_flat5, zero_in = { 0 }; \ - v16u8 p4_a_sub_p0, q4_a_sub_q0, p5_a_sub_p0, q5_a_sub_q0; \ - v16u8 p6_a_sub_p0, q6_a_sub_q0, p7_a_sub_p0, q7_a_sub_q0; \ - \ - tmp_flat5 = __msa_ori_b(zero_in, 1); \ - p4_a_sub_p0 = __msa_asub_u_b(p4_in, p0_in); \ - q4_a_sub_q0 = __msa_asub_u_b(q4_in, q0_in); \ - p5_a_sub_p0 = __msa_asub_u_b(p5_in, p0_in); \ - q5_a_sub_q0 = __msa_asub_u_b(q5_in, q0_in); \ - p6_a_sub_p0 = __msa_asub_u_b(p6_in, p0_in); \ - q6_a_sub_q0 = __msa_asub_u_b(q6_in, q0_in); \ - p7_a_sub_p0 = __msa_asub_u_b(p7_in, p0_in); \ - q7_a_sub_q0 = __msa_asub_u_b(q7_in, q0_in); \ - \ - p4_a_sub_p0 = __msa_max_u_b(p4_a_sub_p0, q4_a_sub_q0); \ - flat2_out = __msa_max_u_b(p5_a_sub_p0, q5_a_sub_q0); \ - flat2_out = __msa_max_u_b(p4_a_sub_p0, flat2_out); \ - p6_a_sub_p0 = __msa_max_u_b(p6_a_sub_p0, q6_a_sub_q0); \ - flat2_out = __msa_max_u_b(p6_a_sub_p0, flat2_out); \ - p7_a_sub_p0 = __msa_max_u_b(p7_a_sub_p0, q7_a_sub_q0); \ - flat2_out = __msa_max_u_b(p7_a_sub_p0, flat2_out); \ - \ - flat2_out = (tmp_flat5 < (v16u8)flat2_out); \ - flat2_out = __msa_xori_b(flat2_out, 0xff); \ - flat2_out = flat2_out & flat_in; \ - } - -#define VP9_FILTER8(p3_in, p2_in, p1_in, p0_in, q0_in, q1_in, q2_in, q3_in, \ - p2_filt8_out, p1_filt8_out, p0_filt8_out, q0_filt8_out, \ - q1_filt8_out, q2_filt8_out) \ - { \ - v8u16 tmp_filt8_0, tmp_filt8_1, tmp_filt8_2; \ - \ - tmp_filt8_2 = p2_in + p1_in + p0_in; \ - tmp_filt8_0 = p3_in << 1; \ - \ - tmp_filt8_0 = tmp_filt8_0 + tmp_filt8_2 + q0_in; \ - tmp_filt8_1 = tmp_filt8_0 + p3_in + p2_in; \ - p2_filt8_out = (v8i16)__msa_srari_h((v8i16)tmp_filt8_1, 3); \ - \ - tmp_filt8_1 = tmp_filt8_0 + p1_in + q1_in; \ - p1_filt8_out = (v8i16)__msa_srari_h((v8i16)tmp_filt8_1, 3); \ - \ - tmp_filt8_1 = q2_in + q1_in + q0_in; \ - tmp_filt8_2 = tmp_filt8_2 + tmp_filt8_1; \ - tmp_filt8_0 = tmp_filt8_2 + (p0_in); \ - tmp_filt8_0 = tmp_filt8_0 + (p3_in); \ - p0_filt8_out = (v8i16)__msa_srari_h((v8i16)tmp_filt8_0, 3); \ - \ - tmp_filt8_0 = q2_in + q3_in; \ - tmp_filt8_0 = p0_in + tmp_filt8_1 + tmp_filt8_0; \ - tmp_filt8_1 = q3_in + q3_in; \ - tmp_filt8_1 = tmp_filt8_1 + tmp_filt8_0; \ - q2_filt8_out = (v8i16)__msa_srari_h((v8i16)tmp_filt8_1, 3); \ - \ - tmp_filt8_0 = tmp_filt8_2 + q3_in; \ - tmp_filt8_1 = tmp_filt8_0 + q0_in; \ - q0_filt8_out = (v8i16)__msa_srari_h((v8i16)tmp_filt8_1, 3); \ - \ - tmp_filt8_1 = tmp_filt8_0 - p2_in; \ - tmp_filt8_0 = q1_in + q3_in; \ - tmp_filt8_1 = tmp_filt8_0 + tmp_filt8_1; \ - q1_filt8_out = (v8i16)__msa_srari_h((v8i16)tmp_filt8_1, 3); \ - } - -#define LPF_MASK_HEV(p3_in, p2_in, p1_in, p0_in, q0_in, q1_in, q2_in, q3_in, \ - limit_in, b_limit_in, thresh_in, hev_out, mask_out, \ - flat_out) \ - { \ - v16u8 p3_asub_p2_m, p2_asub_p1_m, p1_asub_p0_m, q1_asub_q0_m; \ - v16u8 p1_asub_q1_m, p0_asub_q0_m, q3_asub_q2_m, q2_asub_q1_m; \ - \ - /* absolute subtraction of pixel values */ \ - p3_asub_p2_m = __msa_asub_u_b(p3_in, p2_in); \ - p2_asub_p1_m = __msa_asub_u_b(p2_in, p1_in); \ - p1_asub_p0_m = __msa_asub_u_b(p1_in, p0_in); \ - q1_asub_q0_m = __msa_asub_u_b(q1_in, q0_in); \ - q2_asub_q1_m = __msa_asub_u_b(q2_in, q1_in); \ - q3_asub_q2_m = __msa_asub_u_b(q3_in, q2_in); \ - p0_asub_q0_m = __msa_asub_u_b(p0_in, q0_in); \ - p1_asub_q1_m = __msa_asub_u_b(p1_in, q1_in); \ - \ - /* calculation of hev */ \ - flat_out = __msa_max_u_b(p1_asub_p0_m, q1_asub_q0_m); \ - hev_out = thresh_in < (v16u8)flat_out; \ - \ - /* calculation of mask */ \ - p0_asub_q0_m = __msa_adds_u_b(p0_asub_q0_m, p0_asub_q0_m); \ - p1_asub_q1_m >>= 1; \ - p0_asub_q0_m = __msa_adds_u_b(p0_asub_q0_m, p1_asub_q1_m); \ - \ - mask_out = b_limit_in < p0_asub_q0_m; \ - mask_out = __msa_max_u_b(flat_out, mask_out); \ - p3_asub_p2_m = __msa_max_u_b(p3_asub_p2_m, p2_asub_p1_m); \ - mask_out = __msa_max_u_b(p3_asub_p2_m, mask_out); \ - q2_asub_q1_m = __msa_max_u_b(q2_asub_q1_m, q3_asub_q2_m); \ - mask_out = __msa_max_u_b(q2_asub_q1_m, mask_out); \ - \ - mask_out = limit_in < (v16u8)mask_out; \ - mask_out = __msa_xori_b(mask_out, 0xff); \ - } -#endif // VPX_VPX_DSP_MIPS_LOOPFILTER_MSA_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/macros_msa.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/macros_msa.h deleted file mode 100644 index 53462b59..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/macros_msa.h +++ /dev/null @@ -1,1971 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_MIPS_MACROS_MSA_H_ -#define VPX_VPX_DSP_MIPS_MACROS_MSA_H_ - -#include - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" - -#define LD_V(RTYPE, psrc) *((const RTYPE *)(psrc)) -#define LD_UB(...) LD_V(v16u8, __VA_ARGS__) -#define LD_SB(...) LD_V(v16i8, __VA_ARGS__) -#define LD_UH(...) LD_V(v8u16, __VA_ARGS__) -#define LD_SH(...) LD_V(v8i16, __VA_ARGS__) -#define LD_SW(...) LD_V(v4i32, __VA_ARGS__) - -#define ST_V(RTYPE, in, pdst) *((RTYPE *)(pdst)) = (in) -#define ST_UB(...) ST_V(v16u8, __VA_ARGS__) -#define ST_SB(...) ST_V(v16i8, __VA_ARGS__) -#define ST_SH(...) ST_V(v8i16, __VA_ARGS__) -#define ST_SW(...) ST_V(v4i32, __VA_ARGS__) - -#if (__mips_isa_rev >= 6) -#define LH(psrc) \ - ({ \ - uint16_t val_lh_m = *(const uint16_t *)(psrc); \ - val_lh_m; \ - }) - -#define LW(psrc) \ - ({ \ - uint32_t val_lw_m = *(const uint32_t *)(psrc); \ - val_lw_m; \ - }) - -#if (__mips == 64) -#define LD(psrc) \ - ({ \ - uint64_t val_ld_m = *(const uint64_t *)(psrc); \ - val_ld_m; \ - }) -#else // !(__mips == 64) -#define LD(psrc) \ - ({ \ - const uint8_t *psrc_ld_m = (const uint8_t *)(psrc); \ - uint32_t val0_ld_m, val1_ld_m; \ - uint64_t val_ld_m = 0; \ - \ - val0_ld_m = LW(psrc_ld_m); \ - val1_ld_m = LW(psrc_ld_m + 4); \ - \ - val_ld_m = (uint64_t)(val1_ld_m); \ - val_ld_m = (uint64_t)((val_ld_m << 32) & 0xFFFFFFFF00000000); \ - val_ld_m = (uint64_t)(val_ld_m | (uint64_t)val0_ld_m); \ - \ - val_ld_m; \ - }) -#endif // (__mips == 64) - -#define SH(val, pdst) *(uint16_t *)(pdst) = (val); -#define SW(val, pdst) *(uint32_t *)(pdst) = (val); -#define SD(val, pdst) *(uint64_t *)(pdst) = (val); -#else // !(__mips_isa_rev >= 6) -#define LH(psrc) \ - ({ \ - const uint8_t *psrc_lh_m = (const uint8_t *)(psrc); \ - uint16_t val_lh_m; \ - \ - __asm__ __volatile__("ulh %[val_lh_m], %[psrc_lh_m] \n\t" \ - \ - : [val_lh_m] "=r"(val_lh_m) \ - : [psrc_lh_m] "m"(*psrc_lh_m)); \ - \ - val_lh_m; \ - }) - -#define LW(psrc) \ - ({ \ - const uint8_t *psrc_lw_m = (const uint8_t *)(psrc); \ - uint32_t val_lw_m; \ - \ - __asm__ __volatile__( \ - "lwr %[val_lw_m], 0(%[psrc_lw_m]) \n\t" \ - "lwl %[val_lw_m], 3(%[psrc_lw_m]) \n\t" \ - : [val_lw_m] "=&r"(val_lw_m) \ - : [psrc_lw_m] "r"(psrc_lw_m)); \ - \ - val_lw_m; \ - }) - -#if (__mips == 64) -#define LD(psrc) \ - ({ \ - const uint8_t *psrc_ld_m = (const uint8_t *)(psrc); \ - uint64_t val_ld_m = 0; \ - \ - __asm__ __volatile__( \ - "ldr %[val_ld_m], 0(%[psrc_ld_m]) \n\t" \ - "ldl %[val_ld_m], 7(%[psrc_ld_m]) \n\t" \ - : [val_ld_m] "=&r"(val_ld_m) \ - : [psrc_ld_m] "r"(psrc_ld_m)); \ - \ - val_ld_m; \ - }) -#else // !(__mips == 64) -#define LD(psrc) \ - ({ \ - const uint8_t *psrc_ld_m = (const uint8_t *)(psrc); \ - uint32_t val0_ld_m, val1_ld_m; \ - uint64_t val_ld_m = 0; \ - \ - val0_ld_m = LW(psrc_ld_m); \ - val1_ld_m = LW(psrc_ld_m + 4); \ - \ - val_ld_m = (uint64_t)(val1_ld_m); \ - val_ld_m = (uint64_t)((val_ld_m << 32) & 0xFFFFFFFF00000000); \ - val_ld_m = (uint64_t)(val_ld_m | (uint64_t)val0_ld_m); \ - \ - val_ld_m; \ - }) -#endif // (__mips == 64) - -#define SH(val, pdst) \ - { \ - uint8_t *pdst_sh_m = (uint8_t *)(pdst); \ - const uint16_t val_sh_m = (val); \ - \ - __asm__ __volatile__("ush %[val_sh_m], %[pdst_sh_m] \n\t" \ - \ - : [pdst_sh_m] "=m"(*pdst_sh_m) \ - : [val_sh_m] "r"(val_sh_m)); \ - } - -#define SW(val, pdst) \ - { \ - uint8_t *pdst_sw_m = (uint8_t *)(pdst); \ - const uint32_t val_sw_m = (val); \ - \ - __asm__ __volatile__("usw %[val_sw_m], %[pdst_sw_m] \n\t" \ - \ - : [pdst_sw_m] "=m"(*pdst_sw_m) \ - : [val_sw_m] "r"(val_sw_m)); \ - } - -#define SD(val, pdst) \ - { \ - uint8_t *pdst_sd_m = (uint8_t *)(pdst); \ - uint32_t val0_sd_m, val1_sd_m; \ - \ - val0_sd_m = (uint32_t)((val)&0x00000000FFFFFFFF); \ - val1_sd_m = (uint32_t)(((val) >> 32) & 0x00000000FFFFFFFF); \ - \ - SW(val0_sd_m, pdst_sd_m); \ - SW(val1_sd_m, pdst_sd_m + 4); \ - } -#endif // (__mips_isa_rev >= 6) - -/* Description : Load 4 words with stride - Arguments : Inputs - psrc, stride - Outputs - out0, out1, out2, out3 - Details : Load word in 'out0' from (psrc) - Load word in 'out1' from (psrc + stride) - Load word in 'out2' from (psrc + 2 * stride) - Load word in 'out3' from (psrc + 3 * stride) -*/ -#define LW4(psrc, stride, out0, out1, out2, out3) \ - { \ - out0 = LW((psrc)); \ - out1 = LW((psrc) + stride); \ - out2 = LW((psrc) + 2 * stride); \ - out3 = LW((psrc) + 3 * stride); \ - } - -/* Description : Load double words with stride - Arguments : Inputs - psrc, stride - Outputs - out0, out1 - Details : Load double word in 'out0' from (psrc) - Load double word in 'out1' from (psrc + stride) -*/ -#define LD2(psrc, stride, out0, out1) \ - { \ - out0 = LD((psrc)); \ - out1 = LD((psrc) + stride); \ - } -#define LD4(psrc, stride, out0, out1, out2, out3) \ - { \ - LD2((psrc), stride, out0, out1); \ - LD2((psrc) + 2 * stride, stride, out2, out3); \ - } - -/* Description : Store 4 words with stride - Arguments : Inputs - in0, in1, in2, in3, pdst, stride - Details : Store word from 'in0' to (pdst) - Store word from 'in1' to (pdst + stride) - Store word from 'in2' to (pdst + 2 * stride) - Store word from 'in3' to (pdst + 3 * stride) -*/ -#define SW4(in0, in1, in2, in3, pdst, stride) \ - { \ - SW(in0, (pdst)) \ - SW(in1, (pdst) + stride); \ - SW(in2, (pdst) + 2 * stride); \ - SW(in3, (pdst) + 3 * stride); \ - } - -/* Description : Store 4 double words with stride - Arguments : Inputs - in0, in1, in2, in3, pdst, stride - Details : Store double word from 'in0' to (pdst) - Store double word from 'in1' to (pdst + stride) - Store double word from 'in2' to (pdst + 2 * stride) - Store double word from 'in3' to (pdst + 3 * stride) -*/ -#define SD4(in0, in1, in2, in3, pdst, stride) \ - { \ - SD(in0, (pdst)) \ - SD(in1, (pdst) + stride); \ - SD(in2, (pdst) + 2 * stride); \ - SD(in3, (pdst) + 3 * stride); \ - } - -/* Description : Load vector elements with stride - Arguments : Inputs - psrc, stride - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Load 16 byte elements in 'out0' from (psrc) - Load 16 byte elements in 'out1' from (psrc + stride) -*/ -#define LD_V2(RTYPE, psrc, stride, out0, out1) \ - { \ - out0 = LD_V(RTYPE, (psrc)); \ - out1 = LD_V(RTYPE, (psrc) + stride); \ - } -#define LD_UB2(...) LD_V2(v16u8, __VA_ARGS__) -#define LD_SB2(...) LD_V2(v16i8, __VA_ARGS__) -#define LD_SH2(...) LD_V2(v8i16, __VA_ARGS__) -#define LD_SW2(...) LD_V2(v4i32, __VA_ARGS__) - -#define LD_V3(RTYPE, psrc, stride, out0, out1, out2) \ - { \ - LD_V2(RTYPE, (psrc), stride, out0, out1); \ - out2 = LD_V(RTYPE, (psrc) + 2 * stride); \ - } -#define LD_UB3(...) LD_V3(v16u8, __VA_ARGS__) - -#define LD_V4(RTYPE, psrc, stride, out0, out1, out2, out3) \ - { \ - LD_V2(RTYPE, (psrc), stride, out0, out1); \ - LD_V2(RTYPE, (psrc) + 2 * stride, stride, out2, out3); \ - } -#define LD_UB4(...) LD_V4(v16u8, __VA_ARGS__) -#define LD_SB4(...) LD_V4(v16i8, __VA_ARGS__) -#define LD_SH4(...) LD_V4(v8i16, __VA_ARGS__) - -#define LD_V5(RTYPE, psrc, stride, out0, out1, out2, out3, out4) \ - { \ - LD_V4(RTYPE, (psrc), stride, out0, out1, out2, out3); \ - out4 = LD_V(RTYPE, (psrc) + 4 * stride); \ - } -#define LD_UB5(...) LD_V5(v16u8, __VA_ARGS__) -#define LD_SB5(...) LD_V5(v16i8, __VA_ARGS__) - -#define LD_V7(RTYPE, psrc, stride, out0, out1, out2, out3, out4, out5, out6) \ - { \ - LD_V5(RTYPE, (psrc), stride, out0, out1, out2, out3, out4); \ - LD_V2(RTYPE, (psrc) + 5 * stride, stride, out5, out6); \ - } -#define LD_SB7(...) LD_V7(v16i8, __VA_ARGS__) - -#define LD_V8(RTYPE, psrc, stride, out0, out1, out2, out3, out4, out5, out6, \ - out7) \ - { \ - LD_V4(RTYPE, (psrc), stride, out0, out1, out2, out3); \ - LD_V4(RTYPE, (psrc) + 4 * stride, stride, out4, out5, out6, out7); \ - } -#define LD_UB8(...) LD_V8(v16u8, __VA_ARGS__) -#define LD_SB8(...) LD_V8(v16i8, __VA_ARGS__) -#define LD_SH8(...) LD_V8(v8i16, __VA_ARGS__) - -#define LD_V16(RTYPE, psrc, stride, out0, out1, out2, out3, out4, out5, out6, \ - out7, out8, out9, out10, out11, out12, out13, out14, out15) \ - { \ - LD_V8(RTYPE, (psrc), stride, out0, out1, out2, out3, out4, out5, out6, \ - out7); \ - LD_V8(RTYPE, (psrc) + 8 * stride, stride, out8, out9, out10, out11, out12, \ - out13, out14, out15); \ - } -#define LD_SH16(...) LD_V16(v8i16, __VA_ARGS__) - -/* Description : Load 4x4 block of signed halfword elements from 1D source - data into 4 vectors (Each vector with 4 signed halfwords) - Arguments : Input - psrc - Outputs - out0, out1, out2, out3 -*/ -#define LD4x4_SH(psrc, out0, out1, out2, out3) \ - { \ - out0 = LD_SH(psrc); \ - out2 = LD_SH(psrc + 8); \ - out1 = (v8i16)__msa_ilvl_d((v2i64)out0, (v2i64)out0); \ - out3 = (v8i16)__msa_ilvl_d((v2i64)out2, (v2i64)out2); \ - } - -/* Description : Store vectors with stride - Arguments : Inputs - in0, in1, pdst, stride - Details : Store 16 byte elements from 'in0' to (pdst) - Store 16 byte elements from 'in1' to (pdst + stride) -*/ -#define ST_V2(RTYPE, in0, in1, pdst, stride) \ - { \ - ST_V(RTYPE, in0, (pdst)); \ - ST_V(RTYPE, in1, (pdst) + stride); \ - } -#define ST_UB2(...) ST_V2(v16u8, __VA_ARGS__) -#define ST_SH2(...) ST_V2(v8i16, __VA_ARGS__) -#define ST_SW2(...) ST_V2(v4i32, __VA_ARGS__) - -#define ST_V4(RTYPE, in0, in1, in2, in3, pdst, stride) \ - { \ - ST_V2(RTYPE, in0, in1, (pdst), stride); \ - ST_V2(RTYPE, in2, in3, (pdst) + 2 * stride, stride); \ - } -#define ST_UB4(...) ST_V4(v16u8, __VA_ARGS__) -#define ST_SH4(...) ST_V4(v8i16, __VA_ARGS__) - -#define ST_V8(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride) \ - { \ - ST_V4(RTYPE, in0, in1, in2, in3, pdst, stride); \ - ST_V4(RTYPE, in4, in5, in6, in7, (pdst) + 4 * stride, stride); \ - } -#define ST_UB8(...) ST_V8(v16u8, __VA_ARGS__) -#define ST_SH8(...) ST_V8(v8i16, __VA_ARGS__) - -/* Description : Store 2x4 byte block to destination memory from input vector - Arguments : Inputs - in, stidx, pdst, stride - Details : Index 'stidx' halfword element from 'in' vector is copied to - the GP register and stored to (pdst) - Index 'stidx+1' halfword element from 'in' vector is copied to - the GP register and stored to (pdst + stride) - Index 'stidx+2' halfword element from 'in' vector is copied to - the GP register and stored to (pdst + 2 * stride) - Index 'stidx+3' halfword element from 'in' vector is copied to - the GP register and stored to (pdst + 3 * stride) -*/ -#define ST2x4_UB(in, stidx, pdst, stride) \ - { \ - uint16_t out0_m, out1_m, out2_m, out3_m; \ - uint8_t *pblk_2x4_m = (uint8_t *)(pdst); \ - \ - out0_m = __msa_copy_u_h((v8i16)in, (stidx)); \ - out1_m = __msa_copy_u_h((v8i16)in, (stidx + 1)); \ - out2_m = __msa_copy_u_h((v8i16)in, (stidx + 2)); \ - out3_m = __msa_copy_u_h((v8i16)in, (stidx + 3)); \ - \ - SH(out0_m, pblk_2x4_m); \ - SH(out1_m, pblk_2x4_m + stride); \ - SH(out2_m, pblk_2x4_m + 2 * stride); \ - SH(out3_m, pblk_2x4_m + 3 * stride); \ - } - -/* Description : Store 4x2 byte block to destination memory from input vector - Arguments : Inputs - in, pdst, stride - Details : Index 0 word element from 'in' vector is copied to the GP - register and stored to (pdst) - Index 1 word element from 'in' vector is copied to the GP - register and stored to (pdst + stride) -*/ -#define ST4x2_UB(in, pdst, stride) \ - { \ - uint32_t out0_m, out1_m; \ - uint8_t *pblk_4x2_m = (uint8_t *)(pdst); \ - \ - out0_m = __msa_copy_u_w((v4i32)in, 0); \ - out1_m = __msa_copy_u_w((v4i32)in, 1); \ - \ - SW(out0_m, pblk_4x2_m); \ - SW(out1_m, pblk_4x2_m + stride); \ - } - -/* Description : Store 4x4 byte block to destination memory from input vector - Arguments : Inputs - in0, in1, pdst, stride - Details : 'Idx0' word element from input vector 'in0' is copied to the - GP register and stored to (pdst) - 'Idx1' word element from input vector 'in0' is copied to the - GP register and stored to (pdst + stride) - 'Idx2' word element from input vector 'in0' is copied to the - GP register and stored to (pdst + 2 * stride) - 'Idx3' word element from input vector 'in0' is copied to the - GP register and stored to (pdst + 3 * stride) -*/ -#define ST4x4_UB(in0, in1, idx0, idx1, idx2, idx3, pdst, stride) \ - { \ - uint32_t out0_m, out1_m, out2_m, out3_m; \ - uint8_t *pblk_4x4_m = (uint8_t *)(pdst); \ - \ - out0_m = __msa_copy_u_w((v4i32)in0, idx0); \ - out1_m = __msa_copy_u_w((v4i32)in0, idx1); \ - out2_m = __msa_copy_u_w((v4i32)in1, idx2); \ - out3_m = __msa_copy_u_w((v4i32)in1, idx3); \ - \ - SW4(out0_m, out1_m, out2_m, out3_m, pblk_4x4_m, stride); \ - } -#define ST4x8_UB(in0, in1, pdst, stride) \ - { \ - uint8_t *pblk_4x8 = (uint8_t *)(pdst); \ - \ - ST4x4_UB(in0, in0, 0, 1, 2, 3, pblk_4x8, stride); \ - ST4x4_UB(in1, in1, 0, 1, 2, 3, pblk_4x8 + 4 * stride, stride); \ - } - -/* Description : Store 8x1 byte block to destination memory from input vector - Arguments : Inputs - in, pdst - Details : Index 0 double word element from 'in' vector is copied to the - GP register and stored to (pdst) -*/ -#define ST8x1_UB(in, pdst) \ - { \ - uint64_t out0_m; \ - \ - out0_m = __msa_copy_u_d((v2i64)in, 0); \ - SD(out0_m, pdst); \ - } - -/* Description : Store 8x2 byte block to destination memory from input vector - Arguments : Inputs - in, pdst, stride - Details : Index 0 double word element from 'in' vector is copied to the - GP register and stored to (pdst) - Index 1 double word element from 'in' vector is copied to the - GP register and stored to (pdst + stride) -*/ -#define ST8x2_UB(in, pdst, stride) \ - { \ - uint64_t out0_m, out1_m; \ - uint8_t *pblk_8x2_m = (uint8_t *)(pdst); \ - \ - out0_m = __msa_copy_u_d((v2i64)in, 0); \ - out1_m = __msa_copy_u_d((v2i64)in, 1); \ - \ - SD(out0_m, pblk_8x2_m); \ - SD(out1_m, pblk_8x2_m + stride); \ - } - -/* Description : Store 8x4 byte block to destination memory from input - vectors - Arguments : Inputs - in0, in1, pdst, stride - Details : Index 0 double word element from 'in0' vector is copied to the - GP register and stored to (pdst) - Index 1 double word element from 'in0' vector is copied to the - GP register and stored to (pdst + stride) - Index 0 double word element from 'in1' vector is copied to the - GP register and stored to (pdst + 2 * stride) - Index 1 double word element from 'in1' vector is copied to the - GP register and stored to (pdst + 3 * stride) -*/ -#define ST8x4_UB(in0, in1, pdst, stride) \ - { \ - uint64_t out0_m, out1_m, out2_m, out3_m; \ - uint8_t *pblk_8x4_m = (uint8_t *)(pdst); \ - \ - out0_m = __msa_copy_u_d((v2i64)in0, 0); \ - out1_m = __msa_copy_u_d((v2i64)in0, 1); \ - out2_m = __msa_copy_u_d((v2i64)in1, 0); \ - out3_m = __msa_copy_u_d((v2i64)in1, 1); \ - \ - SD4(out0_m, out1_m, out2_m, out3_m, pblk_8x4_m, stride); \ - } - -/* Description : average with rounding (in0 + in1 + 1) / 2. - Arguments : Inputs - in0, in1, in2, in3, - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Each unsigned byte element from 'in0' vector is added with - each unsigned byte element from 'in1' vector. Then the average - with rounding is calculated and written to 'out0' -*/ -#define AVER_UB2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_aver_u_b((v16u8)in0, (v16u8)in1); \ - out1 = (RTYPE)__msa_aver_u_b((v16u8)in2, (v16u8)in3); \ - } -#define AVER_UB2_UB(...) AVER_UB2(v16u8, __VA_ARGS__) - -#define AVER_UB4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3) \ - { \ - AVER_UB2(RTYPE, in0, in1, in2, in3, out0, out1) \ - AVER_UB2(RTYPE, in4, in5, in6, in7, out2, out3) \ - } -#define AVER_UB4_UB(...) AVER_UB4(v16u8, __VA_ARGS__) - -/* Description : Immediate number of elements to slide with zero - Arguments : Inputs - in0, in1, slide_val - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Byte elements from 'zero_m' vector are slid into 'in0' by - value specified in the 'slide_val' -*/ -#define SLDI_B2_0(RTYPE, in0, in1, out0, out1, slide_val) \ - { \ - v16i8 zero_m = { 0 }; \ - out0 = (RTYPE)__msa_sldi_b((v16i8)zero_m, (v16i8)in0, slide_val); \ - out1 = (RTYPE)__msa_sldi_b((v16i8)zero_m, (v16i8)in1, slide_val); \ - } -#define SLDI_B2_0_SW(...) SLDI_B2_0(v4i32, __VA_ARGS__) - -#define SLDI_B4_0(RTYPE, in0, in1, in2, in3, out0, out1, out2, out3, \ - slide_val) \ - { \ - SLDI_B2_0(RTYPE, in0, in1, out0, out1, slide_val); \ - SLDI_B2_0(RTYPE, in2, in3, out2, out3, slide_val); \ - } -#define SLDI_B4_0_UB(...) SLDI_B4_0(v16u8, __VA_ARGS__) - -/* Description : Immediate number of elements to slide - Arguments : Inputs - in0_0, in0_1, in1_0, in1_1, slide_val - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Byte elements from 'in0_0' vector are slid into 'in1_0' by - value specified in the 'slide_val' -*/ -#define SLDI_B2(RTYPE, in0_0, in0_1, in1_0, in1_1, out0, out1, slide_val) \ - { \ - out0 = (RTYPE)__msa_sldi_b((v16i8)in0_0, (v16i8)in1_0, slide_val); \ - out1 = (RTYPE)__msa_sldi_b((v16i8)in0_1, (v16i8)in1_1, slide_val); \ - } -#define SLDI_B2_UB(...) SLDI_B2(v16u8, __VA_ARGS__) -#define SLDI_B2_SH(...) SLDI_B2(v8i16, __VA_ARGS__) - -#define SLDI_B3(RTYPE, in0_0, in0_1, in0_2, in1_0, in1_1, in1_2, out0, out1, \ - out2, slide_val) \ - { \ - SLDI_B2(RTYPE, in0_0, in0_1, in1_0, in1_1, out0, out1, slide_val) \ - out2 = (RTYPE)__msa_sldi_b((v16i8)in0_2, (v16i8)in1_2, slide_val); \ - } -#define SLDI_B3_SB(...) SLDI_B3(v16i8, __VA_ARGS__) -#define SLDI_B3_UH(...) SLDI_B3(v8u16, __VA_ARGS__) - -/* Description : Shuffle byte vector elements as per mask vector - Arguments : Inputs - in0, in1, in2, in3, mask0, mask1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Byte elements from 'in0' & 'in1' are copied selectively to - 'out0' as per control vector 'mask0' -*/ -#define VSHF_B2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_vshf_b((v16i8)mask0, (v16i8)in1, (v16i8)in0); \ - out1 = (RTYPE)__msa_vshf_b((v16i8)mask1, (v16i8)in3, (v16i8)in2); \ - } -#define VSHF_B2_UB(...) VSHF_B2(v16u8, __VA_ARGS__) -#define VSHF_B2_SB(...) VSHF_B2(v16i8, __VA_ARGS__) -#define VSHF_B2_UH(...) VSHF_B2(v8u16, __VA_ARGS__) -#define VSHF_B2_SH(...) VSHF_B2(v8i16, __VA_ARGS__) - -#define VSHF_B4(RTYPE, in0, in1, mask0, mask1, mask2, mask3, out0, out1, out2, \ - out3) \ - { \ - VSHF_B2(RTYPE, in0, in1, in0, in1, mask0, mask1, out0, out1); \ - VSHF_B2(RTYPE, in0, in1, in0, in1, mask2, mask3, out2, out3); \ - } -#define VSHF_B4_SB(...) VSHF_B4(v16i8, __VA_ARGS__) -#define VSHF_B4_SH(...) VSHF_B4(v8i16, __VA_ARGS__) - -/* Description : Dot product of byte vector elements - Arguments : Inputs - mult0, mult1, cnst0, cnst1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Unsigned byte elements from 'mult0' are multiplied with - unsigned byte elements from 'cnst0' producing a result - twice the size of input i.e. unsigned halfword. - The multiplication result of adjacent odd-even elements - are added together and written to the 'out0' vector -*/ -#define DOTP_UB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_dotp_u_h((v16u8)mult0, (v16u8)cnst0); \ - out1 = (RTYPE)__msa_dotp_u_h((v16u8)mult1, (v16u8)cnst1); \ - } -#define DOTP_UB2_UH(...) DOTP_UB2(v8u16, __VA_ARGS__) - -#define DOTP_UB4(RTYPE, mult0, mult1, mult2, mult3, cnst0, cnst1, cnst2, \ - cnst3, out0, out1, out2, out3) \ - { \ - DOTP_UB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1); \ - DOTP_UB2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3); \ - } -#define DOTP_UB4_UH(...) DOTP_UB4(v8u16, __VA_ARGS__) - -/* Description : Dot product of byte vector elements - Arguments : Inputs - mult0, mult1, cnst0, cnst1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Signed byte elements from 'mult0' are multiplied with - signed byte elements from 'cnst0' producing a result - twice the size of input i.e. signed halfword. - The multiplication result of adjacent odd-even elements - are added together and written to the 'out0' vector -*/ -#define DOTP_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_dotp_s_h((v16i8)mult0, (v16i8)cnst0); \ - out1 = (RTYPE)__msa_dotp_s_h((v16i8)mult1, (v16i8)cnst1); \ - } -#define DOTP_SB2_SH(...) DOTP_SB2(v8i16, __VA_ARGS__) - -#define DOTP_SB4(RTYPE, mult0, mult1, mult2, mult3, cnst0, cnst1, cnst2, \ - cnst3, out0, out1, out2, out3) \ - { \ - DOTP_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1); \ - DOTP_SB2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3); \ - } -#define DOTP_SB4_SH(...) DOTP_SB4(v8i16, __VA_ARGS__) - -/* Description : Dot product of halfword vector elements - Arguments : Inputs - mult0, mult1, cnst0, cnst1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Signed halfword elements from 'mult0' are multiplied with - signed halfword elements from 'cnst0' producing a result - twice the size of input i.e. signed word. - The multiplication result of adjacent odd-even elements - are added together and written to the 'out0' vector -*/ -#define DOTP_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_dotp_s_w((v8i16)mult0, (v8i16)cnst0); \ - out1 = (RTYPE)__msa_dotp_s_w((v8i16)mult1, (v8i16)cnst1); \ - } -#define DOTP_SH2_SW(...) DOTP_SH2(v4i32, __VA_ARGS__) - -#define DOTP_SH4(RTYPE, mult0, mult1, mult2, mult3, cnst0, cnst1, cnst2, \ - cnst3, out0, out1, out2, out3) \ - { \ - DOTP_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1); \ - DOTP_SH2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3); \ - } -#define DOTP_SH4_SW(...) DOTP_SH4(v4i32, __VA_ARGS__) - -/* Description : Dot product of word vector elements - Arguments : Inputs - mult0, mult1, cnst0, cnst1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Signed word elements from 'mult0' are multiplied with - signed word elements from 'cnst0' producing a result - twice the size of input i.e. signed double word. - The multiplication result of adjacent odd-even elements - are added together and written to the 'out0' vector -*/ -#define DOTP_SW2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_dotp_s_d((v4i32)mult0, (v4i32)cnst0); \ - out1 = (RTYPE)__msa_dotp_s_d((v4i32)mult1, (v4i32)cnst1); \ - } -#define DOTP_SW2_SD(...) DOTP_SW2(v2i64, __VA_ARGS__) - -/* Description : Dot product & addition of byte vector elements - Arguments : Inputs - mult0, mult1, cnst0, cnst1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Signed byte elements from 'mult0' are multiplied with - signed byte elements from 'cnst0' producing a result - twice the size of input i.e. signed halfword. - The multiplication result of adjacent odd-even elements - are added to the 'out0' vector -*/ -#define DPADD_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_dpadd_s_h((v8i16)out0, (v16i8)mult0, (v16i8)cnst0); \ - out1 = (RTYPE)__msa_dpadd_s_h((v8i16)out1, (v16i8)mult1, (v16i8)cnst1); \ - } -#define DPADD_SB2_SH(...) DPADD_SB2(v8i16, __VA_ARGS__) - -#define DPADD_SB4(RTYPE, mult0, mult1, mult2, mult3, cnst0, cnst1, cnst2, \ - cnst3, out0, out1, out2, out3) \ - { \ - DPADD_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1); \ - DPADD_SB2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3); \ - } -#define DPADD_SB4_SH(...) DPADD_SB4(v8i16, __VA_ARGS__) - -/* Description : Dot product & addition of halfword vector elements - Arguments : Inputs - mult0, mult1, cnst0, cnst1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Signed halfword elements from 'mult0' are multiplied with - signed halfword elements from 'cnst0' producing a result - twice the size of input i.e. signed word. - The multiplication result of adjacent odd-even elements - are added to the 'out0' vector -*/ -#define DPADD_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_dpadd_s_w((v4i32)out0, (v8i16)mult0, (v8i16)cnst0); \ - out1 = (RTYPE)__msa_dpadd_s_w((v4i32)out1, (v8i16)mult1, (v8i16)cnst1); \ - } -#define DPADD_SH2_SW(...) DPADD_SH2(v4i32, __VA_ARGS__) - -/* Description : Dot product & addition of double word vector elements - Arguments : Inputs - mult0, mult1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Each signed word element from 'mult0' is multiplied with itself - producing an intermediate result twice the size of input - i.e. signed double word - The multiplication result of adjacent odd-even elements - are added to the 'out0' vector -*/ -#define DPADD_SD2(RTYPE, mult0, mult1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_dpadd_s_d((v2i64)out0, (v4i32)mult0, (v4i32)mult0); \ - out1 = (RTYPE)__msa_dpadd_s_d((v2i64)out1, (v4i32)mult1, (v4i32)mult1); \ - } -#define DPADD_SD2_SD(...) DPADD_SD2(v2i64, __VA_ARGS__) - -/* Description : Minimum values between unsigned elements of - either vector are copied to the output vector - Arguments : Inputs - in0, in1, min_vec - Outputs - in place operation - Return Type - as per RTYPE - Details : Minimum of unsigned halfword element values from 'in0' and - 'min_vec' are written to output vector 'in0' -*/ -#define MIN_UH2(RTYPE, in0, in1, min_vec) \ - { \ - in0 = (RTYPE)__msa_min_u_h((v8u16)in0, min_vec); \ - in1 = (RTYPE)__msa_min_u_h((v8u16)in1, min_vec); \ - } -#define MIN_UH2_UH(...) MIN_UH2(v8u16, __VA_ARGS__) - -#define MIN_UH4(RTYPE, in0, in1, in2, in3, min_vec) \ - { \ - MIN_UH2(RTYPE, in0, in1, min_vec); \ - MIN_UH2(RTYPE, in2, in3, min_vec); \ - } -#define MIN_UH4_UH(...) MIN_UH4(v8u16, __VA_ARGS__) - -/* Description : Clips all signed halfword elements of input vector - between 0 & 255 - Arguments : Input - in - Output - out_m - Return Type - signed halfword -*/ -#define CLIP_SH_0_255(in) \ - ({ \ - v8i16 max_m = __msa_ldi_h(255); \ - v8i16 out_m; \ - \ - out_m = __msa_maxi_s_h((v8i16)in, 0); \ - out_m = __msa_min_s_h((v8i16)max_m, (v8i16)out_m); \ - out_m; \ - }) -#define CLIP_SH2_0_255(in0, in1) \ - { \ - in0 = CLIP_SH_0_255(in0); \ - in1 = CLIP_SH_0_255(in1); \ - } -#define CLIP_SH4_0_255(in0, in1, in2, in3) \ - { \ - CLIP_SH2_0_255(in0, in1); \ - CLIP_SH2_0_255(in2, in3); \ - } - -/* Description : Horizontal addition of 4 signed word elements of input vector - Arguments : Input - in (signed word vector) - Output - sum_m (i32 sum) - Return Type - signed word (GP) - Details : 4 signed word elements of 'in' vector are added together and - the resulting integer sum is returned -*/ -#define HADD_SW_S32(in) \ - ({ \ - v2i64 hadd_sw_s32_res0_m, hadd_sw_s32_res1_m; \ - int32_t hadd_sw_s32_sum_m; \ - \ - hadd_sw_s32_res0_m = __msa_hadd_s_d((v4i32)in, (v4i32)in); \ - hadd_sw_s32_res1_m = __msa_splati_d(hadd_sw_s32_res0_m, 1); \ - hadd_sw_s32_res0_m = hadd_sw_s32_res0_m + hadd_sw_s32_res1_m; \ - hadd_sw_s32_sum_m = __msa_copy_s_w((v4i32)hadd_sw_s32_res0_m, 0); \ - hadd_sw_s32_sum_m; \ - }) - -/* Description : Horizontal addition of 4 unsigned word elements - Arguments : Input - in (unsigned word vector) - Output - sum_m (u32 sum) - Return Type - unsigned word (GP) - Details : 4 unsigned word elements of 'in' vector are added together and - the resulting integer sum is returned -*/ -#define HADD_UW_U32(in) \ - ({ \ - v2u64 hadd_uw_u32_res0_m, hadd_uw_u32_res1_m; \ - uint32_t hadd_uw_u32_sum_m; \ - \ - hadd_uw_u32_res0_m = __msa_hadd_u_d((v4u32)in, (v4u32)in); \ - hadd_uw_u32_res1_m = (v2u64)__msa_splati_d((v2i64)hadd_uw_u32_res0_m, 1); \ - hadd_uw_u32_res0_m += hadd_uw_u32_res1_m; \ - hadd_uw_u32_sum_m = __msa_copy_u_w((v4i32)hadd_uw_u32_res0_m, 0); \ - hadd_uw_u32_sum_m; \ - }) - -/* Description : Horizontal addition of 8 unsigned halfword elements - Arguments : Input - in (unsigned halfword vector) - Output - sum_m (u32 sum) - Return Type - unsigned word - Details : 8 unsigned halfword elements of 'in' vector are added - together and the resulting integer sum is returned -*/ -#define HADD_UH_U32(in) \ - ({ \ - v4u32 hadd_uh_u32_res_m; \ - uint32_t hadd_uh_u32_sum_m; \ - \ - hadd_uh_u32_res_m = __msa_hadd_u_w((v8u16)in, (v8u16)in); \ - hadd_uh_u32_sum_m = HADD_UW_U32(hadd_uh_u32_res_m); \ - hadd_uh_u32_sum_m; \ - }) - -/* Description : Horizontal addition of unsigned byte vector elements - Arguments : Inputs - in0, in1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Each unsigned odd byte element from 'in0' is added to - even unsigned byte element from 'in0' (pairwise) and the - halfword result is written to 'out0' -*/ -#define HADD_UB2(RTYPE, in0, in1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_hadd_u_h((v16u8)in0, (v16u8)in0); \ - out1 = (RTYPE)__msa_hadd_u_h((v16u8)in1, (v16u8)in1); \ - } -#define HADD_UB2_UH(...) HADD_UB2(v8u16, __VA_ARGS__) - -#define HADD_UB4(RTYPE, in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - HADD_UB2(RTYPE, in0, in1, out0, out1); \ - HADD_UB2(RTYPE, in2, in3, out2, out3); \ - } -#define HADD_UB4_UH(...) HADD_UB4(v8u16, __VA_ARGS__) - -/* Description : Horizontal subtraction of unsigned byte vector elements - Arguments : Inputs - in0, in1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Each unsigned odd byte element from 'in0' is subtracted from - even unsigned byte element from 'in0' (pairwise) and the - halfword result is written to 'out0' -*/ -#define HSUB_UB2(RTYPE, in0, in1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_hsub_u_h((v16u8)in0, (v16u8)in0); \ - out1 = (RTYPE)__msa_hsub_u_h((v16u8)in1, (v16u8)in1); \ - } -#define HSUB_UB2_SH(...) HSUB_UB2(v8i16, __VA_ARGS__) - -/* Description : SAD (Sum of Absolute Difference) - Arguments : Inputs - in0, in1, ref0, ref1 - Outputs - sad_m (halfword vector) - Return Type - unsigned halfword - Details : Absolute difference of all the byte elements from 'in0' with - 'ref0' is calculated and preserved in 'diff0'. Then even-odd - pairs are added together to generate 8 halfword results. -*/ -#define SAD_UB2_UH(in0, in1, ref0, ref1) \ - ({ \ - v16u8 diff0_m, diff1_m; \ - v8u16 sad_m = { 0 }; \ - \ - diff0_m = __msa_asub_u_b((v16u8)in0, (v16u8)ref0); \ - diff1_m = __msa_asub_u_b((v16u8)in1, (v16u8)ref1); \ - \ - sad_m += __msa_hadd_u_h((v16u8)diff0_m, (v16u8)diff0_m); \ - sad_m += __msa_hadd_u_h((v16u8)diff1_m, (v16u8)diff1_m); \ - \ - sad_m; \ - }) - -/* Description : Horizontal subtraction of signed halfword vector elements - Arguments : Inputs - in0, in1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Each signed odd halfword element from 'in0' is subtracted from - even signed halfword element from 'in0' (pairwise) and the - word result is written to 'out0' -*/ -#define HSUB_UH2(RTYPE, in0, in1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_hsub_s_w((v8i16)in0, (v8i16)in0); \ - out1 = (RTYPE)__msa_hsub_s_w((v8i16)in1, (v8i16)in1); \ - } -#define HSUB_UH2_SW(...) HSUB_UH2(v4i32, __VA_ARGS__) - -/* Description : Set element n input vector to GPR value - Arguments : Inputs - in0, in1, in2, in3 - Output - out - Return Type - as per RTYPE - Details : Set element 0 in vector 'out' to value specified in 'in0' -*/ -#define INSERT_W2(RTYPE, in0, in1, out) \ - { \ - out = (RTYPE)__msa_insert_w((v4i32)out, 0, in0); \ - out = (RTYPE)__msa_insert_w((v4i32)out, 1, in1); \ - } -#define INSERT_W2_SB(...) INSERT_W2(v16i8, __VA_ARGS__) - -#define INSERT_W4(RTYPE, in0, in1, in2, in3, out) \ - { \ - out = (RTYPE)__msa_insert_w((v4i32)out, 0, in0); \ - out = (RTYPE)__msa_insert_w((v4i32)out, 1, in1); \ - out = (RTYPE)__msa_insert_w((v4i32)out, 2, in2); \ - out = (RTYPE)__msa_insert_w((v4i32)out, 3, in3); \ - } -#define INSERT_W4_UB(...) INSERT_W4(v16u8, __VA_ARGS__) -#define INSERT_W4_SB(...) INSERT_W4(v16i8, __VA_ARGS__) - -#define INSERT_D2(RTYPE, in0, in1, out) \ - { \ - out = (RTYPE)__msa_insert_d((v2i64)out, 0, in0); \ - out = (RTYPE)__msa_insert_d((v2i64)out, 1, in1); \ - } -#define INSERT_D2_UB(...) INSERT_D2(v16u8, __VA_ARGS__) -#define INSERT_D2_SB(...) INSERT_D2(v16i8, __VA_ARGS__) -#define INSERT_D2_SH(...) INSERT_D2(v8i16, __VA_ARGS__) - -/* Description : Interleave even byte elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Even byte elements of 'in0' and 'in1' are interleaved - and written to 'out0' -*/ -#define ILVEV_B2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvev_b((v16i8)in1, (v16i8)in0); \ - out1 = (RTYPE)__msa_ilvev_b((v16i8)in3, (v16i8)in2); \ - } -#define ILVEV_B2_UB(...) ILVEV_B2(v16u8, __VA_ARGS__) -#define ILVEV_B2_SH(...) ILVEV_B2(v8i16, __VA_ARGS__) - -/* Description : Interleave even halfword elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Even halfword elements of 'in0' and 'in1' are interleaved - and written to 'out0' -*/ -#define ILVEV_H2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvev_h((v8i16)in1, (v8i16)in0); \ - out1 = (RTYPE)__msa_ilvev_h((v8i16)in3, (v8i16)in2); \ - } -#define ILVEV_H2_UB(...) ILVEV_H2(v16u8, __VA_ARGS__) -#define ILVEV_H2_SH(...) ILVEV_H2(v8i16, __VA_ARGS__) -#define ILVEV_H2_SW(...) ILVEV_H2(v4i32, __VA_ARGS__) - -/* Description : Interleave even word elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Even word elements of 'in0' and 'in1' are interleaved - and written to 'out0' -*/ -#define ILVEV_W2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvev_w((v4i32)in1, (v4i32)in0); \ - out1 = (RTYPE)__msa_ilvev_w((v4i32)in3, (v4i32)in2); \ - } -#define ILVEV_W2_SB(...) ILVEV_W2(v16i8, __VA_ARGS__) - -/* Description : Interleave even double word elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Even double word elements of 'in0' and 'in1' are interleaved - and written to 'out0' -*/ -#define ILVEV_D2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvev_d((v2i64)in1, (v2i64)in0); \ - out1 = (RTYPE)__msa_ilvev_d((v2i64)in3, (v2i64)in2); \ - } -#define ILVEV_D2_UB(...) ILVEV_D2(v16u8, __VA_ARGS__) - -/* Description : Interleave left half of byte elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Left half of byte elements of 'in0' and 'in1' are interleaved - and written to 'out0'. -*/ -#define ILVL_B2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvl_b((v16i8)in0, (v16i8)in1); \ - out1 = (RTYPE)__msa_ilvl_b((v16i8)in2, (v16i8)in3); \ - } -#define ILVL_B2_UB(...) ILVL_B2(v16u8, __VA_ARGS__) -#define ILVL_B2_SB(...) ILVL_B2(v16i8, __VA_ARGS__) -#define ILVL_B2_UH(...) ILVL_B2(v8u16, __VA_ARGS__) -#define ILVL_B2_SH(...) ILVL_B2(v8i16, __VA_ARGS__) - -#define ILVL_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3) \ - { \ - ILVL_B2(RTYPE, in0, in1, in2, in3, out0, out1); \ - ILVL_B2(RTYPE, in4, in5, in6, in7, out2, out3); \ - } -#define ILVL_B4_SB(...) ILVL_B4(v16i8, __VA_ARGS__) -#define ILVL_B4_SH(...) ILVL_B4(v8i16, __VA_ARGS__) -#define ILVL_B4_UH(...) ILVL_B4(v8u16, __VA_ARGS__) - -/* Description : Interleave left half of halfword elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Left half of halfword elements of 'in0' and 'in1' are - interleaved and written to 'out0'. -*/ -#define ILVL_H2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvl_h((v8i16)in0, (v8i16)in1); \ - out1 = (RTYPE)__msa_ilvl_h((v8i16)in2, (v8i16)in3); \ - } -#define ILVL_H2_SH(...) ILVL_H2(v8i16, __VA_ARGS__) -#define ILVL_H2_SW(...) ILVL_H2(v4i32, __VA_ARGS__) - -/* Description : Interleave left half of word elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Left half of word elements of 'in0' and 'in1' are interleaved - and written to 'out0'. -*/ -#define ILVL_W2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvl_w((v4i32)in0, (v4i32)in1); \ - out1 = (RTYPE)__msa_ilvl_w((v4i32)in2, (v4i32)in3); \ - } -#define ILVL_W2_UB(...) ILVL_W2(v16u8, __VA_ARGS__) -#define ILVL_W2_SH(...) ILVL_W2(v8i16, __VA_ARGS__) - -/* Description : Interleave right half of byte elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Right half of byte elements of 'in0' and 'in1' are interleaved - and written to out0. -*/ -#define ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvr_b((v16i8)in0, (v16i8)in1); \ - out1 = (RTYPE)__msa_ilvr_b((v16i8)in2, (v16i8)in3); \ - } -#define ILVR_B2_UB(...) ILVR_B2(v16u8, __VA_ARGS__) -#define ILVR_B2_SB(...) ILVR_B2(v16i8, __VA_ARGS__) -#define ILVR_B2_UH(...) ILVR_B2(v8u16, __VA_ARGS__) -#define ILVR_B2_SH(...) ILVR_B2(v8i16, __VA_ARGS__) - -#define ILVR_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3) \ - { \ - ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1); \ - ILVR_B2(RTYPE, in4, in5, in6, in7, out2, out3); \ - } -#define ILVR_B4_UB(...) ILVR_B4(v16u8, __VA_ARGS__) -#define ILVR_B4_SB(...) ILVR_B4(v16i8, __VA_ARGS__) -#define ILVR_B4_UH(...) ILVR_B4(v8u16, __VA_ARGS__) -#define ILVR_B4_SH(...) ILVR_B4(v8i16, __VA_ARGS__) - -#define ILVR_B8(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, \ - in11, in12, in13, in14, in15, out0, out1, out2, out3, out4, \ - out5, out6, out7) \ - { \ - ILVR_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, \ - out3); \ - ILVR_B4(RTYPE, in8, in9, in10, in11, in12, in13, in14, in15, out4, out5, \ - out6, out7); \ - } -#define ILVR_B8_UH(...) ILVR_B8(v8u16, __VA_ARGS__) - -/* Description : Interleave right half of halfword elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Right half of halfword elements of 'in0' and 'in1' are - interleaved and written to 'out0'. -*/ -#define ILVR_H2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvr_h((v8i16)in0, (v8i16)in1); \ - out1 = (RTYPE)__msa_ilvr_h((v8i16)in2, (v8i16)in3); \ - } -#define ILVR_H2_SH(...) ILVR_H2(v8i16, __VA_ARGS__) -#define ILVR_H2_SW(...) ILVR_H2(v4i32, __VA_ARGS__) - -#define ILVR_H4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3) \ - { \ - ILVR_H2(RTYPE, in0, in1, in2, in3, out0, out1); \ - ILVR_H2(RTYPE, in4, in5, in6, in7, out2, out3); \ - } -#define ILVR_H4_SH(...) ILVR_H4(v8i16, __VA_ARGS__) - -#define ILVR_W2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvr_w((v4i32)in0, (v4i32)in1); \ - out1 = (RTYPE)__msa_ilvr_w((v4i32)in2, (v4i32)in3); \ - } -#define ILVR_W2_UB(...) ILVR_W2(v16u8, __VA_ARGS__) -#define ILVR_W2_SH(...) ILVR_W2(v8i16, __VA_ARGS__) - -#define ILVR_W4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3) \ - { \ - ILVR_W2(RTYPE, in0, in1, in2, in3, out0, out1); \ - ILVR_W2(RTYPE, in4, in5, in6, in7, out2, out3); \ - } -#define ILVR_W4_UB(...) ILVR_W4(v16u8, __VA_ARGS__) - -/* Description : Interleave right half of double word elements from vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Right half of double word elements of 'in0' and 'in1' are - interleaved and written to 'out0'. -*/ -#define ILVR_D2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvr_d((v2i64)(in0), (v2i64)(in1)); \ - out1 = (RTYPE)__msa_ilvr_d((v2i64)(in2), (v2i64)(in3)); \ - } -#define ILVR_D2_UB(...) ILVR_D2(v16u8, __VA_ARGS__) -#define ILVR_D2_SB(...) ILVR_D2(v16i8, __VA_ARGS__) -#define ILVR_D2_SH(...) ILVR_D2(v8i16, __VA_ARGS__) - -#define ILVR_D3(RTYPE, in0, in1, in2, in3, in4, in5, out0, out1, out2) \ - { \ - ILVR_D2(RTYPE, in0, in1, in2, in3, out0, out1); \ - out2 = (RTYPE)__msa_ilvr_d((v2i64)(in4), (v2i64)(in5)); \ - } -#define ILVR_D3_SB(...) ILVR_D3(v16i8, __VA_ARGS__) - -#define ILVR_D4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3) \ - { \ - ILVR_D2(RTYPE, in0, in1, in2, in3, out0, out1); \ - ILVR_D2(RTYPE, in4, in5, in6, in7, out2, out3); \ - } -#define ILVR_D4_SB(...) ILVR_D4(v16i8, __VA_ARGS__) -#define ILVR_D4_UB(...) ILVR_D4(v16u8, __VA_ARGS__) - -/* Description : Interleave both left and right half of input vectors - Arguments : Inputs - in0, in1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Right half of byte elements from 'in0' and 'in1' are - interleaved and written to 'out0' -*/ -#define ILVRL_B2(RTYPE, in0, in1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvr_b((v16i8)in0, (v16i8)in1); \ - out1 = (RTYPE)__msa_ilvl_b((v16i8)in0, (v16i8)in1); \ - } -#define ILVRL_B2_UB(...) ILVRL_B2(v16u8, __VA_ARGS__) -#define ILVRL_B2_SB(...) ILVRL_B2(v16i8, __VA_ARGS__) -#define ILVRL_B2_UH(...) ILVRL_B2(v8u16, __VA_ARGS__) -#define ILVRL_B2_SH(...) ILVRL_B2(v8i16, __VA_ARGS__) - -#define ILVRL_H2(RTYPE, in0, in1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvr_h((v8i16)in0, (v8i16)in1); \ - out1 = (RTYPE)__msa_ilvl_h((v8i16)in0, (v8i16)in1); \ - } -#define ILVRL_H2_SH(...) ILVRL_H2(v8i16, __VA_ARGS__) -#define ILVRL_H2_SW(...) ILVRL_H2(v4i32, __VA_ARGS__) - -#define ILVRL_W2(RTYPE, in0, in1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_ilvr_w((v4i32)in0, (v4i32)in1); \ - out1 = (RTYPE)__msa_ilvl_w((v4i32)in0, (v4i32)in1); \ - } -#define ILVRL_W2_UB(...) ILVRL_W2(v16u8, __VA_ARGS__) -#define ILVRL_W2_SB(...) ILVRL_W2(v16i8, __VA_ARGS__) -#define ILVRL_W2_SH(...) ILVRL_W2(v8i16, __VA_ARGS__) -#define ILVRL_W2_SW(...) ILVRL_W2(v4i32, __VA_ARGS__) - -/* Description : Saturate the halfword element values to the max - unsigned value of (sat_val + 1) bits - The element data width remains unchanged - Arguments : Inputs - in0, in1, sat_val - Outputs - in place operation - Return Type - as per RTYPE - Details : Each unsigned halfword element from 'in0' is saturated to the - value generated with (sat_val + 1) bit range. - The results are written in place -*/ -#define SAT_UH2(RTYPE, in0, in1, sat_val) \ - { \ - in0 = (RTYPE)__msa_sat_u_h((v8u16)in0, sat_val); \ - in1 = (RTYPE)__msa_sat_u_h((v8u16)in1, sat_val); \ - } -#define SAT_UH2_UH(...) SAT_UH2(v8u16, __VA_ARGS__) - -#define SAT_UH4(RTYPE, in0, in1, in2, in3, sat_val) \ - { \ - SAT_UH2(RTYPE, in0, in1, sat_val); \ - SAT_UH2(RTYPE, in2, in3, sat_val) \ - } -#define SAT_UH4_UH(...) SAT_UH4(v8u16, __VA_ARGS__) - -/* Description : Saturate the halfword element values to the max - unsigned value of (sat_val + 1) bits - The element data width remains unchanged - Arguments : Inputs - in0, in1, sat_val - Outputs - in place operation - Return Type - as per RTYPE - Details : Each unsigned halfword element from 'in0' is saturated to the - value generated with (sat_val + 1) bit range - The results are written in place -*/ -#define SAT_SH2(RTYPE, in0, in1, sat_val) \ - { \ - in0 = (RTYPE)__msa_sat_s_h((v8i16)in0, sat_val); \ - in1 = (RTYPE)__msa_sat_s_h((v8i16)in1, sat_val); \ - } -#define SAT_SH2_SH(...) SAT_SH2(v8i16, __VA_ARGS__) - -#define SAT_SH4(RTYPE, in0, in1, in2, in3, sat_val) \ - { \ - SAT_SH2(RTYPE, in0, in1, sat_val); \ - SAT_SH2(RTYPE, in2, in3, sat_val); \ - } -#define SAT_SH4_SH(...) SAT_SH4(v8i16, __VA_ARGS__) - -/* Description : Indexed halfword element values are replicated to all - elements in output vector - Arguments : Inputs - in, idx0, idx1 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : 'idx0' element value from 'in' vector is replicated to all - elements in 'out0' vector - Valid index range for halfword operation is 0-7 -*/ -#define SPLATI_H2(RTYPE, in, idx0, idx1, out0, out1) \ - { \ - out0 = (RTYPE)__msa_splati_h((v8i16)in, idx0); \ - out1 = (RTYPE)__msa_splati_h((v8i16)in, idx1); \ - } -#define SPLATI_H2_SH(...) SPLATI_H2(v8i16, __VA_ARGS__) - -#define SPLATI_H4(RTYPE, in, idx0, idx1, idx2, idx3, out0, out1, out2, out3) \ - { \ - SPLATI_H2(RTYPE, in, idx0, idx1, out0, out1); \ - SPLATI_H2(RTYPE, in, idx2, idx3, out2, out3); \ - } -#define SPLATI_H4_SB(...) SPLATI_H4(v16i8, __VA_ARGS__) -#define SPLATI_H4_SH(...) SPLATI_H4(v8i16, __VA_ARGS__) - -/* Description : Pack even byte elements of vector pairs - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Even byte elements of 'in0' are copied to the left half of - 'out0' & even byte elements of 'in1' are copied to the right - half of 'out0'. -*/ -#define PCKEV_B2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_pckev_b((v16i8)in0, (v16i8)in1); \ - out1 = (RTYPE)__msa_pckev_b((v16i8)in2, (v16i8)in3); \ - } -#define PCKEV_B2_SB(...) PCKEV_B2(v16i8, __VA_ARGS__) -#define PCKEV_B2_UB(...) PCKEV_B2(v16u8, __VA_ARGS__) -#define PCKEV_B2_SH(...) PCKEV_B2(v8i16, __VA_ARGS__) - -#define PCKEV_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3) \ - { \ - PCKEV_B2(RTYPE, in0, in1, in2, in3, out0, out1); \ - PCKEV_B2(RTYPE, in4, in5, in6, in7, out2, out3); \ - } -#define PCKEV_B4_SB(...) PCKEV_B4(v16i8, __VA_ARGS__) -#define PCKEV_B4_UB(...) PCKEV_B4(v16u8, __VA_ARGS__) -#define PCKEV_B4_SH(...) PCKEV_B4(v8i16, __VA_ARGS__) - -/* Description : Pack even halfword elements of vector pairs - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Even halfword elements of 'in0' are copied to the left half of - 'out0' & even halfword elements of 'in1' are copied to the - right half of 'out0'. -*/ -#define PCKEV_H2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_pckev_h((v8i16)in0, (v8i16)in1); \ - out1 = (RTYPE)__msa_pckev_h((v8i16)in2, (v8i16)in3); \ - } -#define PCKEV_H2_SH(...) PCKEV_H2(v8i16, __VA_ARGS__) -#define PCKEV_H2_SW(...) PCKEV_H2(v4i32, __VA_ARGS__) - -#define PCKEV_H4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3) \ - { \ - PCKEV_H2(RTYPE, in0, in1, in2, in3, out0, out1); \ - PCKEV_H2(RTYPE, in4, in5, in6, in7, out2, out3); \ - } -#define PCKEV_H4_SH(...) PCKEV_H4(v8i16, __VA_ARGS__) - -/* Description : Pack even double word elements of vector pairs - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Even double elements of 'in0' are copied to the left half of - 'out0' & even double elements of 'in1' are copied to the right - half of 'out0'. -*/ -#define PCKEV_D2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_pckev_d((v2i64)in0, (v2i64)in1); \ - out1 = (RTYPE)__msa_pckev_d((v2i64)in2, (v2i64)in3); \ - } -#define PCKEV_D2_UB(...) PCKEV_D2(v16u8, __VA_ARGS__) -#define PCKEV_D2_SH(...) PCKEV_D2(v8i16, __VA_ARGS__) - -#define PCKEV_D4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3) \ - { \ - PCKEV_D2(RTYPE, in0, in1, in2, in3, out0, out1); \ - PCKEV_D2(RTYPE, in4, in5, in6, in7, out2, out3); \ - } -#define PCKEV_D4_UB(...) PCKEV_D4(v16u8, __VA_ARGS__) - -/* Description : Each byte element is logically xor'ed with immediate 128 - Arguments : Inputs - in0, in1 - Outputs - in place operation - Return Type - as per RTYPE - Details : Each unsigned byte element from input vector 'in0' is - logically xor'ed with 128 and the result is stored in-place. -*/ -#define XORI_B2_128(RTYPE, in0, in1) \ - { \ - in0 = (RTYPE)__msa_xori_b((v16u8)in0, 128); \ - in1 = (RTYPE)__msa_xori_b((v16u8)in1, 128); \ - } -#define XORI_B2_128_UB(...) XORI_B2_128(v16u8, __VA_ARGS__) -#define XORI_B2_128_SB(...) XORI_B2_128(v16i8, __VA_ARGS__) - -#define XORI_B3_128(RTYPE, in0, in1, in2) \ - { \ - XORI_B2_128(RTYPE, in0, in1); \ - in2 = (RTYPE)__msa_xori_b((v16u8)in2, 128); \ - } -#define XORI_B3_128_SB(...) XORI_B3_128(v16i8, __VA_ARGS__) - -#define XORI_B4_128(RTYPE, in0, in1, in2, in3) \ - { \ - XORI_B2_128(RTYPE, in0, in1); \ - XORI_B2_128(RTYPE, in2, in3); \ - } -#define XORI_B4_128_UB(...) XORI_B4_128(v16u8, __VA_ARGS__) -#define XORI_B4_128_SB(...) XORI_B4_128(v16i8, __VA_ARGS__) - -#define XORI_B7_128(RTYPE, in0, in1, in2, in3, in4, in5, in6) \ - { \ - XORI_B4_128(RTYPE, in0, in1, in2, in3); \ - XORI_B3_128(RTYPE, in4, in5, in6); \ - } -#define XORI_B7_128_SB(...) XORI_B7_128(v16i8, __VA_ARGS__) - -/* Description : Average of signed halfword elements -> (a + b) / 2 - Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7 - Outputs - out0, out1, out2, out3 - Return Type - as per RTYPE - Details : Each signed halfword element from 'in0' is added to each - signed halfword element of 'in1' with full precision resulting - in one extra bit in the result. The result is then divided by - 2 and written to 'out0' -*/ -#define AVE_SH4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3) \ - { \ - out0 = (RTYPE)__msa_ave_s_h((v8i16)in0, (v8i16)in1); \ - out1 = (RTYPE)__msa_ave_s_h((v8i16)in2, (v8i16)in3); \ - out2 = (RTYPE)__msa_ave_s_h((v8i16)in4, (v8i16)in5); \ - out3 = (RTYPE)__msa_ave_s_h((v8i16)in6, (v8i16)in7); \ - } -#define AVE_SH4_SH(...) AVE_SH4(v8i16, __VA_ARGS__) - -/* Description : Addition of signed halfword elements and signed saturation - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Return Type - as per RTYPE - Details : Signed halfword elements from 'in0' are added to signed - halfword elements of 'in1'. The result is then signed saturated - between halfword data type range -*/ -#define ADDS_SH2(RTYPE, in0, in1, in2, in3, out0, out1) \ - { \ - out0 = (RTYPE)__msa_adds_s_h((v8i16)in0, (v8i16)in1); \ - out1 = (RTYPE)__msa_adds_s_h((v8i16)in2, (v8i16)in3); \ - } -#define ADDS_SH2_SH(...) ADDS_SH2(v8i16, __VA_ARGS__) - -#define ADDS_SH4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3) \ - { \ - ADDS_SH2(RTYPE, in0, in1, in2, in3, out0, out1); \ - ADDS_SH2(RTYPE, in4, in5, in6, in7, out2, out3); \ - } -#define ADDS_SH4_SH(...) ADDS_SH4(v8i16, __VA_ARGS__) - -/* Description : Shift left all elements of vector (generic for all data types) - Arguments : Inputs - in0, in1, in2, in3, shift - Outputs - in place operation - Return Type - as per input vector RTYPE - Details : Each element of vector 'in0' is left shifted by 'shift' and - the result is written in-place. -*/ -#define SLLI_4V(in0, in1, in2, in3, shift) \ - { \ - in0 = in0 << shift; \ - in1 = in1 << shift; \ - in2 = in2 << shift; \ - in3 = in3 << shift; \ - } - -/* Description : Arithmetic shift right all elements of vector - (generic for all data types) - Arguments : Inputs - in0, in1, in2, in3, shift - Outputs - in place operation - Return Type - as per input vector RTYPE - Details : Each element of vector 'in0' is right shifted by 'shift' and - the result is written in-place. 'shift' is a GP variable. -*/ -#define SRA_2V(in0, in1, shift) \ - { \ - in0 = in0 >> shift; \ - in1 = in1 >> shift; \ - } - -#define SRA_4V(in0, in1, in2, in3, shift) \ - { \ - in0 = in0 >> shift; \ - in1 = in1 >> shift; \ - in2 = in2 >> shift; \ - in3 = in3 >> shift; \ - } - -/* Description : Shift right arithmetic rounded words - Arguments : Inputs - in0, in1, shift - Outputs - in place operation - Return Type - as per RTYPE - Details : Each element of vector 'in0' is shifted right arithmetically by - the number of bits in the corresponding element in the vector - 'shift'. The last discarded bit is added to shifted value for - rounding and the result is written in-place. - 'shift' is a vector. -*/ -#define SRAR_W2(RTYPE, in0, in1, shift) \ - { \ - in0 = (RTYPE)__msa_srar_w((v4i32)in0, (v4i32)shift); \ - in1 = (RTYPE)__msa_srar_w((v4i32)in1, (v4i32)shift); \ - } - -#define SRAR_W4(RTYPE, in0, in1, in2, in3, shift) \ - { \ - SRAR_W2(RTYPE, in0, in1, shift) \ - SRAR_W2(RTYPE, in2, in3, shift) \ - } -#define SRAR_W4_SW(...) SRAR_W4(v4i32, __VA_ARGS__) - -/* Description : Shift right arithmetic rounded (immediate) - Arguments : Inputs - in0, in1, shift - Outputs - in place operation - Return Type - as per RTYPE - Details : Each element of vector 'in0' is shifted right arithmetically by - the value in 'shift'. The last discarded bit is added to the - shifted value for rounding and the result is written in-place. - 'shift' is an immediate value. -*/ -#define SRARI_H2(RTYPE, in0, in1, shift) \ - { \ - in0 = (RTYPE)__msa_srari_h((v8i16)in0, shift); \ - in1 = (RTYPE)__msa_srari_h((v8i16)in1, shift); \ - } -#define SRARI_H2_UH(...) SRARI_H2(v8u16, __VA_ARGS__) -#define SRARI_H2_SH(...) SRARI_H2(v8i16, __VA_ARGS__) - -#define SRARI_H4(RTYPE, in0, in1, in2, in3, shift) \ - { \ - SRARI_H2(RTYPE, in0, in1, shift); \ - SRARI_H2(RTYPE, in2, in3, shift); \ - } -#define SRARI_H4_UH(...) SRARI_H4(v8u16, __VA_ARGS__) -#define SRARI_H4_SH(...) SRARI_H4(v8i16, __VA_ARGS__) - -#define SRARI_W2(RTYPE, in0, in1, shift) \ - { \ - in0 = (RTYPE)__msa_srari_w((v4i32)in0, shift); \ - in1 = (RTYPE)__msa_srari_w((v4i32)in1, shift); \ - } -#define SRARI_W2_SW(...) SRARI_W2(v4i32, __VA_ARGS__) - -#define SRARI_W4(RTYPE, in0, in1, in2, in3, shift) \ - { \ - SRARI_W2(RTYPE, in0, in1, shift); \ - SRARI_W2(RTYPE, in2, in3, shift); \ - } -#define SRARI_W4_SW(...) SRARI_W4(v4i32, __VA_ARGS__) - -/* Description : Logical shift right all elements of vector (immediate) - Arguments : Inputs - in0, in1, in2, in3, shift - Outputs - out0, out1, out2, out3 - Return Type - as per RTYPE - Details : Each element of vector 'in0' is right shifted by 'shift' and - the result is written in-place. 'shift' is an immediate value. -*/ -#define SRLI_H4(RTYPE, in0, in1, in2, in3, out0, out1, out2, out3, shift) \ - { \ - out0 = (RTYPE)__msa_srli_h((v8i16)in0, shift); \ - out1 = (RTYPE)__msa_srli_h((v8i16)in1, shift); \ - out2 = (RTYPE)__msa_srli_h((v8i16)in2, shift); \ - out3 = (RTYPE)__msa_srli_h((v8i16)in3, shift); \ - } -#define SRLI_H4_SH(...) SRLI_H4(v8i16, __VA_ARGS__) - -/* Description : Multiplication of pairs of vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Details : Each element from 'in0' is multiplied with elements from 'in1' - and the result is written to 'out0' -*/ -#define MUL2(in0, in1, in2, in3, out0, out1) \ - { \ - out0 = in0 * in1; \ - out1 = in2 * in3; \ - } -#define MUL4(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, out3) \ - { \ - MUL2(in0, in1, in2, in3, out0, out1); \ - MUL2(in4, in5, in6, in7, out2, out3); \ - } - -/* Description : Addition of 2 pairs of vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Details : Each element in 'in0' is added to 'in1' and result is written - to 'out0'. -*/ -#define ADD2(in0, in1, in2, in3, out0, out1) \ - { \ - out0 = in0 + in1; \ - out1 = in2 + in3; \ - } -#define ADD4(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, out3) \ - { \ - ADD2(in0, in1, in2, in3, out0, out1); \ - ADD2(in4, in5, in6, in7, out2, out3); \ - } - -/* Description : Subtraction of 2 pairs of vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1 - Details : Each element in 'in1' is subtracted from 'in0' and result is - written to 'out0'. -*/ -#define SUB2(in0, in1, in2, in3, out0, out1) \ - { \ - out0 = in0 - in1; \ - out1 = in2 - in3; \ - } -#define SUB4(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, out3) \ - { \ - out0 = in0 - in1; \ - out1 = in2 - in3; \ - out2 = in4 - in5; \ - out3 = in6 - in7; \ - } - -/* Description : Sign extend halfword elements from right half of the vector - Arguments : Input - in (halfword vector) - Output - out (sign extended word vector) - Return Type - signed word - Details : Sign bit of halfword elements from input vector 'in' is - extracted and interleaved with same vector 'in0' to generate - 4 word elements keeping sign intact -*/ -#define UNPCK_R_SH_SW(in, out) \ - { \ - v8i16 sign_m; \ - \ - sign_m = __msa_clti_s_h((v8i16)in, 0); \ - out = (v4i32)__msa_ilvr_h(sign_m, (v8i16)in); \ - } - -/* Description : Sign extend byte elements from input vector and return - halfword results in pair of vectors - Arguments : Input - in (byte vector) - Outputs - out0, out1 (sign extended halfword vectors) - Return Type - signed halfword - Details : Sign bit of byte elements from input vector 'in' is - extracted and interleaved right with same vector 'in0' to - generate 8 signed halfword elements in 'out0' - Then interleaved left with same vector 'in0' to - generate 8 signed halfword elements in 'out1' -*/ -#define UNPCK_SB_SH(in, out0, out1) \ - { \ - v16i8 tmp_m; \ - \ - tmp_m = __msa_clti_s_b((v16i8)in, 0); \ - ILVRL_B2_SH(tmp_m, in, out0, out1); \ - } - -/* Description : Zero extend unsigned byte elements to halfword elements - Arguments : Input - in (unsigned byte vector) - Outputs - out0, out1 (unsigned halfword vectors) - Return Type - signed halfword - Details : Zero extended right half of vector is returned in 'out0' - Zero extended left half of vector is returned in 'out1' -*/ -#define UNPCK_UB_SH(in, out0, out1) \ - { \ - v16i8 zero_m = { 0 }; \ - \ - ILVRL_B2_SH(zero_m, in, out0, out1); \ - } - -/* Description : Sign extend halfword elements from input vector and return - the result in pair of vectors - Arguments : Input - in (halfword vector) - Outputs - out0, out1 (sign extended word vectors) - Return Type - signed word - Details : Sign bit of halfword elements from input vector 'in' is - extracted and interleaved right with same vector 'in0' to - generate 4 signed word elements in 'out0' - Then interleaved left with same vector 'in0' to - generate 4 signed word elements in 'out1' -*/ -#define UNPCK_SH_SW(in, out0, out1) \ - { \ - v8i16 tmp_m; \ - \ - tmp_m = __msa_clti_s_h((v8i16)in, 0); \ - ILVRL_H2_SW(tmp_m, in, out0, out1); \ - } - -/* Description : Butterfly of 4 input vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1, out2, out3 - Details : Butterfly operation -*/ -#define BUTTERFLY_4(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - out0 = in0 + in3; \ - out1 = in1 + in2; \ - \ - out2 = in1 - in2; \ - out3 = in0 - in3; \ - } - -/* Description : Butterfly of 8 input vectors - Arguments : Inputs - in0 ... in7 - Outputs - out0 .. out7 - Details : Butterfly operation -*/ -#define BUTTERFLY_8(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, \ - out3, out4, out5, out6, out7) \ - { \ - out0 = in0 + in7; \ - out1 = in1 + in6; \ - out2 = in2 + in5; \ - out3 = in3 + in4; \ - \ - out4 = in3 - in4; \ - out5 = in2 - in5; \ - out6 = in1 - in6; \ - out7 = in0 - in7; \ - } - -/* Description : Butterfly of 16 input vectors - Arguments : Inputs - in0 ... in15 - Outputs - out0 .. out15 - Details : Butterfly operation -*/ -#define BUTTERFLY_16(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, \ - in11, in12, in13, in14, in15, out0, out1, out2, out3, \ - out4, out5, out6, out7, out8, out9, out10, out11, out12, \ - out13, out14, out15) \ - { \ - out0 = in0 + in15; \ - out1 = in1 + in14; \ - out2 = in2 + in13; \ - out3 = in3 + in12; \ - out4 = in4 + in11; \ - out5 = in5 + in10; \ - out6 = in6 + in9; \ - out7 = in7 + in8; \ - \ - out8 = in7 - in8; \ - out9 = in6 - in9; \ - out10 = in5 - in10; \ - out11 = in4 - in11; \ - out12 = in3 - in12; \ - out13 = in2 - in13; \ - out14 = in1 - in14; \ - out15 = in0 - in15; \ - } - -/* Description : Transpose input 8x8 byte block - Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7 - Outputs - out0, out1, out2, out3, out4, out5, out6, out7 - Return Type - as per RTYPE -*/ -#define TRANSPOSE8x8_UB(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, \ - out1, out2, out3, out4, out5, out6, out7) \ - { \ - v16i8 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ - v16i8 tmp4_m, tmp5_m, tmp6_m, tmp7_m; \ - \ - ILVR_B4_SB(in2, in0, in3, in1, in6, in4, in7, in5, tmp0_m, tmp1_m, tmp2_m, \ - tmp3_m); \ - ILVRL_B2_SB(tmp1_m, tmp0_m, tmp4_m, tmp5_m); \ - ILVRL_B2_SB(tmp3_m, tmp2_m, tmp6_m, tmp7_m); \ - ILVRL_W2(RTYPE, tmp6_m, tmp4_m, out0, out2); \ - ILVRL_W2(RTYPE, tmp7_m, tmp5_m, out4, out6); \ - SLDI_B2_0(RTYPE, out0, out2, out1, out3, 8); \ - SLDI_B2_0(RTYPE, out4, out6, out5, out7, 8); \ - } -#define TRANSPOSE8x8_UB_UB(...) TRANSPOSE8x8_UB(v16u8, __VA_ARGS__) - -/* Description : Transpose 16x8 block into 8x16 with byte elements in vectors - Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7, - in8, in9, in10, in11, in12, in13, in14, in15 - Outputs - out0, out1, out2, out3, out4, out5, out6, out7 - Return Type - unsigned byte -*/ -#define TRANSPOSE16x8_UB_UB(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, \ - in10, in11, in12, in13, in14, in15, out0, out1, \ - out2, out3, out4, out5, out6, out7) \ - { \ - v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ - v16u8 tmp4_m, tmp5_m, tmp6_m, tmp7_m; \ - \ - ILVEV_D2_UB(in0, in8, in1, in9, out7, out6); \ - ILVEV_D2_UB(in2, in10, in3, in11, out5, out4); \ - ILVEV_D2_UB(in4, in12, in5, in13, out3, out2); \ - ILVEV_D2_UB(in6, in14, in7, in15, out1, out0); \ - \ - tmp0_m = (v16u8)__msa_ilvev_b((v16i8)out6, (v16i8)out7); \ - tmp4_m = (v16u8)__msa_ilvod_b((v16i8)out6, (v16i8)out7); \ - tmp1_m = (v16u8)__msa_ilvev_b((v16i8)out4, (v16i8)out5); \ - tmp5_m = (v16u8)__msa_ilvod_b((v16i8)out4, (v16i8)out5); \ - out5 = (v16u8)__msa_ilvev_b((v16i8)out2, (v16i8)out3); \ - tmp6_m = (v16u8)__msa_ilvod_b((v16i8)out2, (v16i8)out3); \ - out7 = (v16u8)__msa_ilvev_b((v16i8)out0, (v16i8)out1); \ - tmp7_m = (v16u8)__msa_ilvod_b((v16i8)out0, (v16i8)out1); \ - \ - ILVEV_H2_UB(tmp0_m, tmp1_m, out5, out7, tmp2_m, tmp3_m); \ - out0 = (v16u8)__msa_ilvev_w((v4i32)tmp3_m, (v4i32)tmp2_m); \ - out4 = (v16u8)__msa_ilvod_w((v4i32)tmp3_m, (v4i32)tmp2_m); \ - \ - tmp2_m = (v16u8)__msa_ilvod_h((v8i16)tmp1_m, (v8i16)tmp0_m); \ - tmp3_m = (v16u8)__msa_ilvod_h((v8i16)out7, (v8i16)out5); \ - out2 = (v16u8)__msa_ilvev_w((v4i32)tmp3_m, (v4i32)tmp2_m); \ - out6 = (v16u8)__msa_ilvod_w((v4i32)tmp3_m, (v4i32)tmp2_m); \ - \ - ILVEV_H2_UB(tmp4_m, tmp5_m, tmp6_m, tmp7_m, tmp2_m, tmp3_m); \ - out1 = (v16u8)__msa_ilvev_w((v4i32)tmp3_m, (v4i32)tmp2_m); \ - out5 = (v16u8)__msa_ilvod_w((v4i32)tmp3_m, (v4i32)tmp2_m); \ - \ - tmp2_m = (v16u8)__msa_ilvod_h((v8i16)tmp5_m, (v8i16)tmp4_m); \ - tmp3_m = (v16u8)__msa_ilvod_h((v8i16)tmp7_m, (v8i16)tmp6_m); \ - out3 = (v16u8)__msa_ilvev_w((v4i32)tmp3_m, (v4i32)tmp2_m); \ - out7 = (v16u8)__msa_ilvod_w((v4i32)tmp3_m, (v4i32)tmp2_m); \ - } - -/* Description : Transpose 4x4 block with half word elements in vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1, out2, out3 - Return Type - signed halfword -*/ -#define TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - v8i16 s0_m, s1_m; \ - \ - ILVR_H2_SH(in1, in0, in3, in2, s0_m, s1_m); \ - ILVRL_W2_SH(s1_m, s0_m, out0, out2); \ - out1 = (v8i16)__msa_ilvl_d((v2i64)out0, (v2i64)out0); \ - out3 = (v8i16)__msa_ilvl_d((v2i64)out0, (v2i64)out2); \ - } - -/* Description : Transpose 4x8 block with half word elements in vectors - Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7 - Outputs - out0, out1, out2, out3, out4, out5, out6, out7 - Return Type - signed halfword -*/ -#define TRANSPOSE4X8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, \ - out2, out3, out4, out5, out6, out7) \ - { \ - v8i16 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ - v8i16 tmp0_n, tmp1_n, tmp2_n, tmp3_n; \ - v8i16 zero_m = { 0 }; \ - \ - ILVR_H4_SH(in1, in0, in3, in2, in5, in4, in7, in6, tmp0_n, tmp1_n, tmp2_n, \ - tmp3_n); \ - ILVRL_W2_SH(tmp1_n, tmp0_n, tmp0_m, tmp2_m); \ - ILVRL_W2_SH(tmp3_n, tmp2_n, tmp1_m, tmp3_m); \ - \ - out0 = (v8i16)__msa_ilvr_d((v2i64)tmp1_m, (v2i64)tmp0_m); \ - out1 = (v8i16)__msa_ilvl_d((v2i64)tmp1_m, (v2i64)tmp0_m); \ - out2 = (v8i16)__msa_ilvr_d((v2i64)tmp3_m, (v2i64)tmp2_m); \ - out3 = (v8i16)__msa_ilvl_d((v2i64)tmp3_m, (v2i64)tmp2_m); \ - \ - out4 = zero_m; \ - out5 = zero_m; \ - out6 = zero_m; \ - out7 = zero_m; \ - } - -/* Description : Transpose 8x4 block with half word elements in vectors - Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7 - Outputs - out0, out1, out2, out3, out4, out5, out6, out7 - Return Type - signed halfword -*/ -#define TRANSPOSE8X4_SH_SH(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - v8i16 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ - \ - ILVR_H2_SH(in1, in0, in3, in2, tmp0_m, tmp1_m); \ - ILVL_H2_SH(in1, in0, in3, in2, tmp2_m, tmp3_m); \ - ILVR_W2_SH(tmp1_m, tmp0_m, tmp3_m, tmp2_m, out0, out2); \ - ILVL_W2_SH(tmp1_m, tmp0_m, tmp3_m, tmp2_m, out1, out3); \ - } - -/* Description : Transpose 8x8 block with half word elements in vectors - Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7 - Outputs - out0, out1, out2, out3, out4, out5, out6, out7 - Return Type - as per RTYPE -*/ -#define TRANSPOSE8x8_H(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, out0, \ - out1, out2, out3, out4, out5, out6, out7) \ - { \ - v8i16 s0_m, s1_m; \ - v8i16 tmp0_m, tmp1_m, tmp2_m, tmp3_m; \ - v8i16 tmp4_m, tmp5_m, tmp6_m, tmp7_m; \ - \ - ILVR_H2_SH(in6, in4, in7, in5, s0_m, s1_m); \ - ILVRL_H2_SH(s1_m, s0_m, tmp0_m, tmp1_m); \ - ILVL_H2_SH(in6, in4, in7, in5, s0_m, s1_m); \ - ILVRL_H2_SH(s1_m, s0_m, tmp2_m, tmp3_m); \ - ILVR_H2_SH(in2, in0, in3, in1, s0_m, s1_m); \ - ILVRL_H2_SH(s1_m, s0_m, tmp4_m, tmp5_m); \ - ILVL_H2_SH(in2, in0, in3, in1, s0_m, s1_m); \ - ILVRL_H2_SH(s1_m, s0_m, tmp6_m, tmp7_m); \ - PCKEV_D4(RTYPE, tmp0_m, tmp4_m, tmp1_m, tmp5_m, tmp2_m, tmp6_m, tmp3_m, \ - tmp7_m, out0, out2, out4, out6); \ - out1 = (RTYPE)__msa_pckod_d((v2i64)tmp0_m, (v2i64)tmp4_m); \ - out3 = (RTYPE)__msa_pckod_d((v2i64)tmp1_m, (v2i64)tmp5_m); \ - out5 = (RTYPE)__msa_pckod_d((v2i64)tmp2_m, (v2i64)tmp6_m); \ - out7 = (RTYPE)__msa_pckod_d((v2i64)tmp3_m, (v2i64)tmp7_m); \ - } -#define TRANSPOSE8x8_SH_SH(...) TRANSPOSE8x8_H(v8i16, __VA_ARGS__) - -/* Description : Transpose 4x4 block with word elements in vectors - Arguments : Inputs - in0, in1, in2, in3 - Outputs - out0, out1, out2, out3 - Return Type - signed word -*/ -#define TRANSPOSE4x4_SW_SW(in0, in1, in2, in3, out0, out1, out2, out3) \ - { \ - v4i32 s0_m, s1_m, s2_m, s3_m; \ - \ - ILVRL_W2_SW(in1, in0, s0_m, s1_m); \ - ILVRL_W2_SW(in3, in2, s2_m, s3_m); \ - \ - out0 = (v4i32)__msa_ilvr_d((v2i64)s2_m, (v2i64)s0_m); \ - out1 = (v4i32)__msa_ilvl_d((v2i64)s2_m, (v2i64)s0_m); \ - out2 = (v4i32)__msa_ilvr_d((v2i64)s3_m, (v2i64)s1_m); \ - out3 = (v4i32)__msa_ilvl_d((v2i64)s3_m, (v2i64)s1_m); \ - } - -/* Description : Add block 4x4 - Arguments : Inputs - in0, in1, in2, in3, pdst, stride - Details : Least significant 4 bytes from each input vector are added to - the destination bytes, clipped between 0-255 and stored. -*/ -#define ADDBLK_ST4x4_UB(in0, in1, in2, in3, pdst, stride) \ - { \ - uint32_t src0_m, src1_m, src2_m, src3_m; \ - v8i16 inp0_m, inp1_m, res0_m, res1_m; \ - v16i8 dst0_m = { 0 }; \ - v16i8 dst1_m = { 0 }; \ - v16i8 zero_m = { 0 }; \ - \ - ILVR_D2_SH(in1, in0, in3, in2, inp0_m, inp1_m) \ - LW4(pdst, stride, src0_m, src1_m, src2_m, src3_m); \ - INSERT_W2_SB(src0_m, src1_m, dst0_m); \ - INSERT_W2_SB(src2_m, src3_m, dst1_m); \ - ILVR_B2_SH(zero_m, dst0_m, zero_m, dst1_m, res0_m, res1_m); \ - ADD2(res0_m, inp0_m, res1_m, inp1_m, res0_m, res1_m); \ - CLIP_SH2_0_255(res0_m, res1_m); \ - PCKEV_B2_SB(res0_m, res0_m, res1_m, res1_m, dst0_m, dst1_m); \ - ST4x4_UB(dst0_m, dst1_m, 0, 1, 0, 1, pdst, stride); \ - } - -/* Description : Pack even elements of input vectors & xor with 128 - Arguments : Inputs - in0, in1 - Output - out_m - Return Type - unsigned byte - Details : Signed byte even elements from 'in0' and 'in1' are packed - together in one vector and the resulting vector is xor'ed with - 128 to shift the range from signed to unsigned byte -*/ -#define PCKEV_XORI128_UB(in0, in1) \ - ({ \ - v16u8 out_m; \ - \ - out_m = (v16u8)__msa_pckev_b((v16i8)in1, (v16i8)in0); \ - out_m = (v16u8)__msa_xori_b((v16u8)out_m, 128); \ - out_m; \ - }) - -/* Description : Converts inputs to unsigned bytes, interleave, average & store - as 8x4 unsigned byte block - Arguments : Inputs - in0, in1, in2, in3, dst0, dst1, pdst, stride -*/ -#define CONVERT_UB_AVG_ST8x4_UB(in0, in1, in2, in3, dst0, dst1, pdst, stride) \ - { \ - v16u8 tmp0_m, tmp1_m; \ - uint8_t *pdst_m = (uint8_t *)(pdst); \ - \ - tmp0_m = PCKEV_XORI128_UB(in0, in1); \ - tmp1_m = PCKEV_XORI128_UB(in2, in3); \ - AVER_UB2_UB(tmp0_m, dst0, tmp1_m, dst1, tmp0_m, tmp1_m); \ - ST8x4_UB(tmp0_m, tmp1_m, pdst_m, stride); \ - } - -/* Description : Pack even byte elements and store byte vector in destination - memory - Arguments : Inputs - in0, in1, pdst -*/ -#define PCKEV_ST_SB(in0, in1, pdst) \ - { \ - v16i8 tmp_m; \ - \ - tmp_m = __msa_pckev_b((v16i8)in1, (v16i8)in0); \ - ST_SB(tmp_m, (pdst)); \ - } - -/* Description : Horizontal 2 tap filter kernel code - Arguments : Inputs - in0, in1, mask, coeff, shift -*/ -#define HORIZ_2TAP_FILT_UH(in0, in1, mask, coeff, shift) \ - ({ \ - v16i8 tmp0_m; \ - v8u16 tmp1_m; \ - \ - tmp0_m = __msa_vshf_b((v16i8)mask, (v16i8)in1, (v16i8)in0); \ - tmp1_m = __msa_dotp_u_h((v16u8)tmp0_m, (v16u8)coeff); \ - tmp1_m = (v8u16)__msa_srari_h((v8i16)tmp1_m, shift); \ - \ - tmp1_m; \ - }) -#endif // VPX_VPX_DSP_MIPS_MACROS_MSA_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/sad_mmi.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/sad_mmi.c deleted file mode 100644 index 7f5882bc..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/sad_mmi.c +++ /dev/null @@ -1,807 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_ports/asmdefs_mmi.h" -#include "vpx/vpx_integer.h" -#include "vpx_ports/mem.h" - -#define SAD_SRC_REF_ABS_SUB_64 \ - "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[src]) \n\t" \ - "gsldlc1 %[ftmp2], 0x0f(%[src]) \n\t" \ - "gsldrc1 %[ftmp2], 0x08(%[src]) \n\t" \ - "gsldlc1 %[ftmp3], 0x07(%[ref]) \n\t" \ - "gsldrc1 %[ftmp3], 0x00(%[ref]) \n\t" \ - "gsldlc1 %[ftmp4], 0x0f(%[ref]) \n\t" \ - "gsldrc1 %[ftmp4], 0x08(%[ref]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp3] \n\t" \ - "pasubub %[ftmp2], %[ftmp2], %[ftmp4] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "biadd %[ftmp2], %[ftmp2] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp1] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \ - "gsldlc1 %[ftmp1], 0x17(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x10(%[src]) \n\t" \ - "gsldlc1 %[ftmp2], 0x1f(%[src]) \n\t" \ - "gsldrc1 %[ftmp2], 0x18(%[src]) \n\t" \ - "gsldlc1 %[ftmp3], 0x17(%[ref]) \n\t" \ - "gsldrc1 %[ftmp3], 0x10(%[ref]) \n\t" \ - "gsldlc1 %[ftmp4], 0x1f(%[ref]) \n\t" \ - "gsldrc1 %[ftmp4], 0x18(%[ref]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp3] \n\t" \ - "pasubub %[ftmp2], %[ftmp2], %[ftmp4] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "biadd %[ftmp2], %[ftmp2] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp1] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \ - "gsldlc1 %[ftmp1], 0x27(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x20(%[src]) \n\t" \ - "gsldlc1 %[ftmp2], 0x2f(%[src]) \n\t" \ - "gsldrc1 %[ftmp2], 0x28(%[src]) \n\t" \ - "gsldlc1 %[ftmp3], 0x27(%[ref]) \n\t" \ - "gsldrc1 %[ftmp3], 0x20(%[ref]) \n\t" \ - "gsldlc1 %[ftmp4], 0x2f(%[ref]) \n\t" \ - "gsldrc1 %[ftmp4], 0x28(%[ref]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp3] \n\t" \ - "pasubub %[ftmp2], %[ftmp2], %[ftmp4] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "biadd %[ftmp2], %[ftmp2] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp1] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \ - "gsldlc1 %[ftmp1], 0x37(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x30(%[src]) \n\t" \ - "gsldlc1 %[ftmp2], 0x3f(%[src]) \n\t" \ - "gsldrc1 %[ftmp2], 0x38(%[src]) \n\t" \ - "gsldlc1 %[ftmp3], 0x37(%[ref]) \n\t" \ - "gsldrc1 %[ftmp3], 0x30(%[ref]) \n\t" \ - "gsldlc1 %[ftmp4], 0x3f(%[ref]) \n\t" \ - "gsldrc1 %[ftmp4], 0x38(%[ref]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp3] \n\t" \ - "pasubub %[ftmp2], %[ftmp2], %[ftmp4] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "biadd %[ftmp2], %[ftmp2] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp1] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp2] \n\t" - -#define SAD_SRC_REF_ABS_SUB_32 \ - "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[src]) \n\t" \ - "gsldlc1 %[ftmp2], 0x0f(%[src]) \n\t" \ - "gsldrc1 %[ftmp2], 0x08(%[src]) \n\t" \ - "gsldlc1 %[ftmp3], 0x07(%[ref]) \n\t" \ - "gsldrc1 %[ftmp3], 0x00(%[ref]) \n\t" \ - "gsldlc1 %[ftmp4], 0x0f(%[ref]) \n\t" \ - "gsldrc1 %[ftmp4], 0x08(%[ref]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp3] \n\t" \ - "pasubub %[ftmp2], %[ftmp2], %[ftmp4] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "biadd %[ftmp2], %[ftmp2] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp1] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \ - "gsldlc1 %[ftmp1], 0x17(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x10(%[src]) \n\t" \ - "gsldlc1 %[ftmp2], 0x1f(%[src]) \n\t" \ - "gsldrc1 %[ftmp2], 0x18(%[src]) \n\t" \ - "gsldlc1 %[ftmp3], 0x17(%[ref]) \n\t" \ - "gsldrc1 %[ftmp3], 0x10(%[ref]) \n\t" \ - "gsldlc1 %[ftmp4], 0x1f(%[ref]) \n\t" \ - "gsldrc1 %[ftmp4], 0x18(%[ref]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp3] \n\t" \ - "pasubub %[ftmp2], %[ftmp2], %[ftmp4] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "biadd %[ftmp2], %[ftmp2] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp1] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp2] \n\t" - -#define SAD_SRC_REF_ABS_SUB_16 \ - "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[src]) \n\t" \ - "gsldlc1 %[ftmp2], 0x0f(%[src]) \n\t" \ - "gsldrc1 %[ftmp2], 0x08(%[src]) \n\t" \ - "gsldlc1 %[ftmp3], 0x07(%[ref]) \n\t" \ - "gsldrc1 %[ftmp3], 0x00(%[ref]) \n\t" \ - "gsldlc1 %[ftmp4], 0x0f(%[ref]) \n\t" \ - "gsldrc1 %[ftmp4], 0x08(%[ref]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp3] \n\t" \ - "pasubub %[ftmp2], %[ftmp2], %[ftmp4] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "biadd %[ftmp2], %[ftmp2] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp1] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp2] \n\t" - -#define SAD_SRC_REF_ABS_SUB_8 \ - "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[src]) \n\t" \ - "gsldlc1 %[ftmp2], 0x07(%[ref]) \n\t" \ - "gsldrc1 %[ftmp2], 0x00(%[ref]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp2] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "paddw %[ftmp3], %[ftmp3], %[ftmp1] \n\t" - -#if _MIPS_SIM == _ABIO32 -#define SAD_SRC_REF_ABS_SUB_4 \ - "ulw %[tmp0], 0x00(%[src]) \n\t" \ - "mtc1 %[tmp0], %[ftmp1] \n\t" \ - "ulw %[tmp0], 0x00(%[ref]) \n\t" \ - "mtc1 %[tmp0], %[ftmp2] \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp2] \n\t" \ - "mthc1 $0, %[ftmp1] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "paddw %[ftmp3], %[ftmp3], %[ftmp1] \n\t" -#else /* _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 */ -#define SAD_SRC_REF_ABS_SUB_4 \ - "gslwlc1 %[ftmp1], 0x03(%[src]) \n\t" \ - "gslwrc1 %[ftmp1], 0x00(%[src]) \n\t" \ - "gslwlc1 %[ftmp2], 0x03(%[ref]) \n\t" \ - "gslwrc1 %[ftmp2], 0x00(%[ref]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp2] \n\t" \ - "mthc1 $0, %[ftmp1] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "paddw %[ftmp3], %[ftmp3], %[ftmp1] \n\t" -#endif /* _MIPS_SIM == _ABIO32 */ - -#define SAD_SRC_AVGREF_ABS_SUB_64 \ - "gsldlc1 %[ftmp1], 0x07(%[second_pred]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[second_pred]) \n\t" \ - "gsldlc1 %[ftmp2], 0x0f(%[second_pred]) \n\t" \ - "gsldrc1 %[ftmp2], 0x08(%[second_pred]) \n\t" \ - "gsldlc1 %[ftmp3], 0x07(%[ref]) \n\t" \ - "gsldrc1 %[ftmp3], 0x00(%[ref]) \n\t" \ - "gsldlc1 %[ftmp4], 0x0f(%[ref]) \n\t" \ - "gsldrc1 %[ftmp4], 0x08(%[ref]) \n\t" \ - "pavgb %[ftmp3], %[ftmp1], %[ftmp3] \n\t" \ - "pavgb %[ftmp4], %[ftmp2], %[ftmp4] \n\t" \ - "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[src]) \n\t" \ - "gsldlc1 %[ftmp2], 0x0f(%[src]) \n\t" \ - "gsldrc1 %[ftmp2], 0x08(%[src]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp3] \n\t" \ - "pasubub %[ftmp2], %[ftmp2], %[ftmp4] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "biadd %[ftmp2], %[ftmp2] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp1] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \ - "gsldlc1 %[ftmp1], 0x17(%[second_pred]) \n\t" \ - "gsldrc1 %[ftmp1], 0x10(%[second_pred]) \n\t" \ - "gsldlc1 %[ftmp2], 0x1f(%[second_pred]) \n\t" \ - "gsldrc1 %[ftmp2], 0x18(%[second_pred]) \n\t" \ - "gsldlc1 %[ftmp3], 0x17(%[ref]) \n\t" \ - "gsldrc1 %[ftmp3], 0x10(%[ref]) \n\t" \ - "gsldlc1 %[ftmp4], 0x1f(%[ref]) \n\t" \ - "gsldrc1 %[ftmp4], 0x18(%[ref]) \n\t" \ - "pavgb %[ftmp3], %[ftmp1], %[ftmp3] \n\t" \ - "pavgb %[ftmp4], %[ftmp2], %[ftmp4] \n\t" \ - "gsldlc1 %[ftmp1], 0x17(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x10(%[src]) \n\t" \ - "gsldlc1 %[ftmp2], 0x1f(%[src]) \n\t" \ - "gsldrc1 %[ftmp2], 0x18(%[src]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp3] \n\t" \ - "pasubub %[ftmp2], %[ftmp2], %[ftmp4] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "biadd %[ftmp2], %[ftmp2] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp1] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \ - "gsldlc1 %[ftmp1], 0x27(%[second_pred]) \n\t" \ - "gsldrc1 %[ftmp1], 0x20(%[second_pred]) \n\t" \ - "gsldlc1 %[ftmp2], 0x2f(%[second_pred]) \n\t" \ - "gsldrc1 %[ftmp2], 0x28(%[second_pred]) \n\t" \ - "gsldlc1 %[ftmp3], 0x27(%[ref]) \n\t" \ - "gsldrc1 %[ftmp3], 0x20(%[ref]) \n\t" \ - "gsldlc1 %[ftmp4], 0x2f(%[ref]) \n\t" \ - "gsldrc1 %[ftmp4], 0x28(%[ref]) \n\t" \ - "pavgb %[ftmp3], %[ftmp1], %[ftmp3] \n\t" \ - "pavgb %[ftmp4], %[ftmp2], %[ftmp4] \n\t" \ - "gsldlc1 %[ftmp1], 0x27(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x20(%[src]) \n\t" \ - "gsldlc1 %[ftmp2], 0x2f(%[src]) \n\t" \ - "gsldrc1 %[ftmp2], 0x28(%[src]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp3] \n\t" \ - "pasubub %[ftmp2], %[ftmp2], %[ftmp4] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "biadd %[ftmp2], %[ftmp2] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp1] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \ - "gsldlc1 %[ftmp1], 0x37(%[second_pred]) \n\t" \ - "gsldrc1 %[ftmp1], 0x30(%[second_pred]) \n\t" \ - "gsldlc1 %[ftmp2], 0x3f(%[second_pred]) \n\t" \ - "gsldrc1 %[ftmp2], 0x38(%[second_pred]) \n\t" \ - "gsldlc1 %[ftmp3], 0x37(%[ref]) \n\t" \ - "gsldrc1 %[ftmp3], 0x30(%[ref]) \n\t" \ - "gsldlc1 %[ftmp4], 0x3f(%[ref]) \n\t" \ - "gsldrc1 %[ftmp4], 0x38(%[ref]) \n\t" \ - "pavgb %[ftmp3], %[ftmp1], %[ftmp3] \n\t" \ - "pavgb %[ftmp4], %[ftmp2], %[ftmp4] \n\t" \ - "gsldlc1 %[ftmp1], 0x37(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x30(%[src]) \n\t" \ - "gsldlc1 %[ftmp2], 0x3f(%[src]) \n\t" \ - "gsldrc1 %[ftmp2], 0x38(%[src]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp3] \n\t" \ - "pasubub %[ftmp2], %[ftmp2], %[ftmp4] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "biadd %[ftmp2], %[ftmp2] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp1] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp2] \n\t" - -#define SAD_SRC_AVGREF_ABS_SUB_32 \ - "gsldlc1 %[ftmp1], 0x07(%[second_pred]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[second_pred]) \n\t" \ - "gsldlc1 %[ftmp2], 0x0f(%[second_pred]) \n\t" \ - "gsldrc1 %[ftmp2], 0x08(%[second_pred]) \n\t" \ - "gsldlc1 %[ftmp3], 0x07(%[ref]) \n\t" \ - "gsldrc1 %[ftmp3], 0x00(%[ref]) \n\t" \ - "gsldlc1 %[ftmp4], 0x0f(%[ref]) \n\t" \ - "gsldrc1 %[ftmp4], 0x08(%[ref]) \n\t" \ - "pavgb %[ftmp3], %[ftmp1], %[ftmp3] \n\t" \ - "pavgb %[ftmp4], %[ftmp2], %[ftmp4] \n\t" \ - "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[src]) \n\t" \ - "gsldlc1 %[ftmp2], 0x0f(%[src]) \n\t" \ - "gsldrc1 %[ftmp2], 0x08(%[src]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp3] \n\t" \ - "pasubub %[ftmp2], %[ftmp2], %[ftmp4] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "biadd %[ftmp2], %[ftmp2] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp1] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp2] \n\t" \ - "gsldlc1 %[ftmp1], 0x17(%[second_pred]) \n\t" \ - "gsldrc1 %[ftmp1], 0x10(%[second_pred]) \n\t" \ - "gsldlc1 %[ftmp2], 0x1f(%[second_pred]) \n\t" \ - "gsldrc1 %[ftmp2], 0x18(%[second_pred]) \n\t" \ - "gsldlc1 %[ftmp3], 0x17(%[ref]) \n\t" \ - "gsldrc1 %[ftmp3], 0x10(%[ref]) \n\t" \ - "gsldlc1 %[ftmp4], 0x1f(%[ref]) \n\t" \ - "gsldrc1 %[ftmp4], 0x18(%[ref]) \n\t" \ - "pavgb %[ftmp3], %[ftmp1], %[ftmp3] \n\t" \ - "pavgb %[ftmp4], %[ftmp2], %[ftmp4] \n\t" \ - "gsldlc1 %[ftmp1], 0x17(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x10(%[src]) \n\t" \ - "gsldlc1 %[ftmp2], 0x1f(%[src]) \n\t" \ - "gsldrc1 %[ftmp2], 0x18(%[src]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp3] \n\t" \ - "pasubub %[ftmp2], %[ftmp2], %[ftmp4] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "biadd %[ftmp2], %[ftmp2] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp1] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp2] \n\t" - -#define SAD_SRC_AVGREF_ABS_SUB_16 \ - "gsldlc1 %[ftmp1], 0x07(%[second_pred]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[second_pred]) \n\t" \ - "gsldlc1 %[ftmp2], 0x0f(%[second_pred]) \n\t" \ - "gsldrc1 %[ftmp2], 0x08(%[second_pred]) \n\t" \ - "gsldlc1 %[ftmp3], 0x07(%[ref]) \n\t" \ - "gsldrc1 %[ftmp3], 0x00(%[ref]) \n\t" \ - "gsldlc1 %[ftmp4], 0x0f(%[ref]) \n\t" \ - "gsldrc1 %[ftmp4], 0x08(%[ref]) \n\t" \ - "pavgb %[ftmp3], %[ftmp1], %[ftmp3] \n\t" \ - "pavgb %[ftmp4], %[ftmp2], %[ftmp4] \n\t" \ - "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[src]) \n\t" \ - "gsldlc1 %[ftmp2], 0x0f(%[src]) \n\t" \ - "gsldrc1 %[ftmp2], 0x08(%[src]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp3] \n\t" \ - "pasubub %[ftmp2], %[ftmp2], %[ftmp4] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "biadd %[ftmp2], %[ftmp2] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp1] \n\t" \ - "paddw %[ftmp5], %[ftmp5], %[ftmp2] \n\t" - -#define SAD_SRC_AVGREF_ABS_SUB_8 \ - "gsldlc1 %[ftmp1], 0x07(%[second_pred]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[second_pred]) \n\t" \ - "gsldlc1 %[ftmp2], 0x07(%[ref]) \n\t" \ - "gsldrc1 %[ftmp2], 0x00(%[ref]) \n\t" \ - "pavgb %[ftmp2], %[ftmp1], %[ftmp2] \n\t" \ - "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[src]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp2] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "paddw %[ftmp3], %[ftmp3], %[ftmp1] \n\t" - -#if _MIPS_SIM == _ABIO32 -#define SAD_SRC_AVGREF_ABS_SUB_4 \ - "ulw %[tmp0], 0x00(%[second_pred]) \n\t" \ - "mtc1 %[tmp0], %[ftmp1] \n\t" \ - "ulw %[tmp0], 0x00(%[ref]) \n\t" \ - "mtc1 %[tmp0], %[ftmp2] \n\t" \ - "pavgb %[ftmp2], %[ftmp1], %[ftmp2] \n\t" \ - "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[src]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp2] \n\t" \ - "mthc1 $0, %[ftmp1] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "paddw %[ftmp3], %[ftmp3], %[ftmp1] \n\t" -#else /* _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 */ -#define SAD_SRC_AVGREF_ABS_SUB_4 \ - "gslwlc1 %[ftmp1], 0x03(%[second_pred]) \n\t" \ - "gslwrc1 %[ftmp1], 0x00(%[second_pred]) \n\t" \ - "gslwlc1 %[ftmp2], 0x03(%[ref]) \n\t" \ - "gslwrc1 %[ftmp2], 0x00(%[ref]) \n\t" \ - "pavgb %[ftmp2], %[ftmp1], %[ftmp2] \n\t" \ - "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[src]) \n\t" \ - "pasubub %[ftmp1], %[ftmp1], %[ftmp2] \n\t" \ - "mthc1 $0, %[ftmp1] \n\t" \ - "biadd %[ftmp1], %[ftmp1] \n\t" \ - "paddw %[ftmp3], %[ftmp3], %[ftmp1] \n\t" -#endif /* _MIPS_SIM == _ABIO32 */ - -#define sadMxNx4D_mmi(m, n) \ - void vpx_sad##m##x##n##x4d_mmi(const uint8_t *src, int src_stride, \ - const uint8_t *const ref_array[], \ - int ref_stride, uint32_t *sad_array) { \ - int i; \ - for (i = 0; i < 4; ++i) \ - sad_array[i] = \ - vpx_sad##m##x##n##_mmi(src, src_stride, ref_array[i], ref_stride); \ - } - -static inline unsigned int vpx_sad64x(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - int counter) { - unsigned int sad; - double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; - mips_reg l_counter = counter; - - /* clang-format off */ - __asm__ volatile ( - "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" - "1: \n\t" - // Include two loop body, to reduce loop time. - SAD_SRC_REF_ABS_SUB_64 - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - SAD_SRC_REF_ABS_SUB_64 - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - MMI_ADDIU(%[counter], %[counter], -0x02) - "bnez %[counter], 1b \n\t" - "mfc1 %[sad], %[ftmp5] \n\t" - : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), - [ftmp4]"=&f"(ftmp4), [ftmp5]"=&f"(ftmp5), [counter]"+&r"(l_counter), - [src]"+&r"(src), [ref]"+&r"(ref), [sad]"=&r"(sad) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride) - ); - /* clang-format on */ - - return sad; -} - -#define vpx_sad64xN(H) \ - unsigned int vpx_sad64x##H##_mmi(const uint8_t *src, int src_stride, \ - const uint8_t *ref, int ref_stride) { \ - return vpx_sad64x(src, src_stride, ref, ref_stride, H); \ - } - -vpx_sad64xN(64); -vpx_sad64xN(32); -sadMxNx4D_mmi(64, 64); -sadMxNx4D_mmi(64, 32); - -static inline unsigned int vpx_sad_avg64x(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - const uint8_t *second_pred, - int counter) { - unsigned int sad; - double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; - mips_reg l_counter = counter; - mips_reg l_second_pred = (mips_reg)second_pred; - - /* clang-format off */ - __asm__ volatile ( - "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" - "1: \n\t" - // Include two loop body, to reduce loop time. - SAD_SRC_AVGREF_ABS_SUB_64 - MMI_ADDIU(%[second_pred], %[second_pred], 0x40) - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - SAD_SRC_AVGREF_ABS_SUB_64 - MMI_ADDIU(%[second_pred], %[second_pred], 0x40) - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - MMI_ADDIU(%[counter], %[counter], -0x02) - "bnez %[counter], 1b \n\t" - "mfc1 %[sad], %[ftmp5] \n\t" - : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), - [ftmp4]"=&f"(ftmp4), [ftmp5]"=&f"(ftmp5), [counter]"+&r"(l_counter), - [src]"+&r"(src), [ref]"+&r"(ref), - [second_pred]"+&r"(l_second_pred), - [sad]"=&r"(sad) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride) - ); - /* clang-format on */ - - return sad; -} - -#define vpx_sad_avg64xN(H) \ - unsigned int vpx_sad64x##H##_avg_mmi(const uint8_t *src, int src_stride, \ - const uint8_t *ref, int ref_stride, \ - const uint8_t *second_pred) { \ - return vpx_sad_avg64x(src, src_stride, ref, ref_stride, second_pred, H); \ - } - -vpx_sad_avg64xN(64); -vpx_sad_avg64xN(32); - -static inline unsigned int vpx_sad32x(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - int counter) { - unsigned int sad; - double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; - mips_reg l_counter = counter; - - /* clang-format off */ - __asm__ volatile ( - "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" - "1: \n\t" - // Include two loop body, to reduce loop time. - SAD_SRC_REF_ABS_SUB_32 - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - SAD_SRC_REF_ABS_SUB_32 - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - MMI_ADDIU(%[counter], %[counter], -0x02) - "bnez %[counter], 1b \n\t" - "mfc1 %[sad], %[ftmp5] \n\t" - : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), - [ftmp4]"=&f"(ftmp4), [ftmp5]"=&f"(ftmp5), [counter]"+&r"(l_counter), - [src]"+&r"(src), [ref]"+&r"(ref), [sad]"=&r"(sad) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride) - ); - /* clang-format on */ - - return sad; -} - -#define vpx_sad32xN(H) \ - unsigned int vpx_sad32x##H##_mmi(const uint8_t *src, int src_stride, \ - const uint8_t *ref, int ref_stride) { \ - return vpx_sad32x(src, src_stride, ref, ref_stride, H); \ - } - -vpx_sad32xN(64); -vpx_sad32xN(32); -vpx_sad32xN(16); -sadMxNx4D_mmi(32, 64); -sadMxNx4D_mmi(32, 32); -sadMxNx4D_mmi(32, 16); - -static inline unsigned int vpx_sad_avg32x(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - const uint8_t *second_pred, - int counter) { - unsigned int sad; - double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; - mips_reg l_counter = counter; - mips_reg l_second_pred = (mips_reg)second_pred; - - /* clang-format off */ - __asm__ volatile ( - "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" - "1: \n\t" - // Include two loop body, to reduce loop time. - SAD_SRC_AVGREF_ABS_SUB_32 - MMI_ADDIU(%[second_pred], %[second_pred], 0x20) - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - SAD_SRC_AVGREF_ABS_SUB_32 - MMI_ADDIU(%[second_pred], %[second_pred], 0x20) - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - MMI_ADDIU(%[counter], %[counter], -0x02) - "bnez %[counter], 1b \n\t" - "mfc1 %[sad], %[ftmp5] \n\t" - : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), - [ftmp4]"=&f"(ftmp4), [ftmp5]"=&f"(ftmp5), [counter]"+&r"(l_counter), - [src]"+&r"(src), [ref]"+&r"(ref), - [second_pred]"+&r"(l_second_pred), - [sad]"=&r"(sad) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride) - ); - /* clang-format on */ - - return sad; -} - -#define vpx_sad_avg32xN(H) \ - unsigned int vpx_sad32x##H##_avg_mmi(const uint8_t *src, int src_stride, \ - const uint8_t *ref, int ref_stride, \ - const uint8_t *second_pred) { \ - return vpx_sad_avg32x(src, src_stride, ref, ref_stride, second_pred, H); \ - } - -vpx_sad_avg32xN(64); -vpx_sad_avg32xN(32); -vpx_sad_avg32xN(16); - -static inline unsigned int vpx_sad16x(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - int counter) { - unsigned int sad; - double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; - mips_reg l_counter = counter; - - /* clang-format off */ - __asm__ volatile ( - "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" - "1: \n\t" - // Include two loop body, to reduce loop time. - SAD_SRC_REF_ABS_SUB_16 - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - SAD_SRC_REF_ABS_SUB_16 - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - MMI_ADDIU(%[counter], %[counter], -0x02) - "bnez %[counter], 1b \n\t" - "mfc1 %[sad], %[ftmp5] \n\t" - : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), - [ftmp4]"=&f"(ftmp4), [ftmp5]"=&f"(ftmp5), [counter]"+&r"(l_counter), - [src]"+&r"(src), [ref]"+&r"(ref), [sad]"=&r"(sad) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride) - ); - /* clang-format on */ - - return sad; -} - -#define vpx_sad16xN(H) \ - unsigned int vpx_sad16x##H##_mmi(const uint8_t *src, int src_stride, \ - const uint8_t *ref, int ref_stride) { \ - return vpx_sad16x(src, src_stride, ref, ref_stride, H); \ - } - -vpx_sad16xN(32); -vpx_sad16xN(16); -vpx_sad16xN(8); -sadMxNx4D_mmi(16, 32); -sadMxNx4D_mmi(16, 16); -sadMxNx4D_mmi(16, 8); - -static inline unsigned int vpx_sad_avg16x(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - const uint8_t *second_pred, - int counter) { - unsigned int sad; - double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; - mips_reg l_counter = counter; - mips_reg l_second_pred = (mips_reg)second_pred; - - /* clang-format off */ - __asm__ volatile ( - "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" - "1: \n\t" - // Include two loop body, to reduce loop time. - SAD_SRC_AVGREF_ABS_SUB_16 - MMI_ADDIU(%[second_pred], %[second_pred], 0x10) - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - SAD_SRC_AVGREF_ABS_SUB_16 - MMI_ADDIU(%[second_pred], %[second_pred], 0x10) - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - MMI_ADDIU(%[counter], %[counter], -0x02) - "bnez %[counter], 1b \n\t" - "mfc1 %[sad], %[ftmp5] \n\t" - : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), - [ftmp4]"=&f"(ftmp4), [ftmp5]"=&f"(ftmp5), [counter]"+&r"(l_counter), - [src]"+&r"(src), [ref]"+&r"(ref), - [second_pred]"+&r"(l_second_pred), - [sad]"=&r"(sad) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride) - ); - /* clang-format on */ - - return sad; -} - -#define vpx_sad_avg16xN(H) \ - unsigned int vpx_sad16x##H##_avg_mmi(const uint8_t *src, int src_stride, \ - const uint8_t *ref, int ref_stride, \ - const uint8_t *second_pred) { \ - return vpx_sad_avg16x(src, src_stride, ref, ref_stride, second_pred, H); \ - } - -vpx_sad_avg16xN(32); -vpx_sad_avg16xN(16); -vpx_sad_avg16xN(8); - -static inline unsigned int vpx_sad8x(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - int counter) { - unsigned int sad; - double ftmp1, ftmp2, ftmp3; - mips_reg l_counter = counter; - - /* clang-format off */ - __asm__ volatile ( - "pxor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" - "1: \n\t" - // Include two loop body, to reduce loop time. - SAD_SRC_REF_ABS_SUB_8 - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - SAD_SRC_REF_ABS_SUB_8 - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - MMI_ADDIU(%[counter], %[counter], -0x02) - "bnez %[counter], 1b \n\t" - "mfc1 %[sad], %[ftmp3] \n\t" - : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), - [counter]"+&r"(l_counter), [src]"+&r"(src), [ref]"+&r"(ref), - [sad]"=&r"(sad) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride) - ); - /* clang-format on */ - - return sad; -} - -#define vpx_sad8xN(H) \ - unsigned int vpx_sad8x##H##_mmi(const uint8_t *src, int src_stride, \ - const uint8_t *ref, int ref_stride) { \ - return vpx_sad8x(src, src_stride, ref, ref_stride, H); \ - } - -vpx_sad8xN(16); -vpx_sad8xN(8); -vpx_sad8xN(4); -sadMxNx4D_mmi(8, 16); -sadMxNx4D_mmi(8, 8); -sadMxNx4D_mmi(8, 4); - -static inline unsigned int vpx_sad_avg8x(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - const uint8_t *second_pred, - int counter) { - unsigned int sad; - double ftmp1, ftmp2, ftmp3; - mips_reg l_counter = counter; - mips_reg l_second_pred = (mips_reg)second_pred; - - /* clang-format off */ - __asm__ volatile ( - "pxor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" - "1: \n\t" - // Include two loop body, to reduce loop time. - SAD_SRC_AVGREF_ABS_SUB_8 - MMI_ADDIU(%[second_pred], %[second_pred], 0x08) - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - SAD_SRC_AVGREF_ABS_SUB_8 - MMI_ADDIU(%[second_pred], %[second_pred], 0x08) - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - MMI_ADDIU(%[counter], %[counter], -0x02) - "bnez %[counter], 1b \n\t" - "mfc1 %[sad], %[ftmp3] \n\t" - : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), - [counter]"+&r"(l_counter), [src]"+&r"(src), [ref]"+&r"(ref), - [second_pred]"+&r"(l_second_pred), - [sad]"=&r"(sad) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride) - ); - /* clang-format on */ - - return sad; -} - -#define vpx_sad_avg8xN(H) \ - unsigned int vpx_sad8x##H##_avg_mmi(const uint8_t *src, int src_stride, \ - const uint8_t *ref, int ref_stride, \ - const uint8_t *second_pred) { \ - return vpx_sad_avg8x(src, src_stride, ref, ref_stride, second_pred, H); \ - } - -vpx_sad_avg8xN(16); -vpx_sad_avg8xN(8); -vpx_sad_avg8xN(4); - -static inline unsigned int vpx_sad4x(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - int counter) { - unsigned int sad; - double ftmp1, ftmp2, ftmp3; - mips_reg l_counter = counter; - - /* clang-format off */ - __asm__ volatile ( - "pxor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" - "1: \n\t" - // Include two loop body, to reduce loop time. - SAD_SRC_REF_ABS_SUB_4 - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - SAD_SRC_REF_ABS_SUB_4 - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - MMI_ADDIU(%[counter], %[counter], -0x02) - "bnez %[counter], 1b \n\t" - "mfc1 %[sad], %[ftmp3] \n\t" - : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), - [counter]"+&r"(l_counter), [src]"+&r"(src), [ref]"+&r"(ref), - [sad]"=&r"(sad) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride) - ); - /* clang-format on */ - - return sad; -} - -#define vpx_sad4xN(H) \ - unsigned int vpx_sad4x##H##_mmi(const uint8_t *src, int src_stride, \ - const uint8_t *ref, int ref_stride) { \ - return vpx_sad4x(src, src_stride, ref, ref_stride, H); \ - } - -vpx_sad4xN(8); -vpx_sad4xN(4); -sadMxNx4D_mmi(4, 8); -sadMxNx4D_mmi(4, 4); - -static inline unsigned int vpx_sad_avg4x(const uint8_t *src, int src_stride, - const uint8_t *ref, int ref_stride, - const uint8_t *second_pred, - int counter) { - unsigned int sad; - double ftmp1, ftmp2, ftmp3; - mips_reg l_counter = counter; - mips_reg l_second_pred = (mips_reg)second_pred; - - /* clang-format off */ - __asm__ volatile ( - "pxor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" - "1: \n\t" - // Include two loop body, to reduce loop time. - SAD_SRC_AVGREF_ABS_SUB_4 - MMI_ADDIU(%[second_pred], %[second_pred], 0x04) - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - SAD_SRC_AVGREF_ABS_SUB_4 - MMI_ADDIU(%[second_pred], %[second_pred], 0x04) - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[ref], %[ref], %[ref_stride]) - MMI_ADDIU(%[counter], %[counter], -0x02) - "bnez %[counter], 1b \n\t" - "mfc1 %[sad], %[ftmp3] \n\t" - : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), - [counter]"+&r"(l_counter), [src]"+&r"(src), [ref]"+&r"(ref), - [second_pred]"+&r"(l_second_pred), - [sad]"=&r"(sad) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride) - ); - /* clang-format on */ - - return sad; -} - -#define vpx_sad_avg4xN(H) \ - unsigned int vpx_sad4x##H##_avg_mmi(const uint8_t *src, int src_stride, \ - const uint8_t *ref, int ref_stride, \ - const uint8_t *second_pred) { \ - return vpx_sad_avg4x(src, src_stride, ref, ref_stride, second_pred, H); \ - } - -vpx_sad_avg4xN(8); -vpx_sad_avg4xN(4); diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/sad_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/sad_msa.c deleted file mode 100644 index b0f8ff1f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/sad_msa.c +++ /dev/null @@ -1,804 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/macros_msa.h" - -#define SAD_INSVE_W4(RTYPE, in0, in1, in2, in3, out) \ - { \ - out = (RTYPE)__msa_insve_w((v4i32)out, 0, (v4i32)in0); \ - out = (RTYPE)__msa_insve_w((v4i32)out, 1, (v4i32)in1); \ - out = (RTYPE)__msa_insve_w((v4i32)out, 2, (v4i32)in2); \ - out = (RTYPE)__msa_insve_w((v4i32)out, 3, (v4i32)in3); \ - } -#define SAD_INSVE_W4_UB(...) SAD_INSVE_W4(v16u8, __VA_ARGS__) - -static uint32_t sad_4width_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t height) { - int32_t ht_cnt; - uint32_t src0, src1, src2, src3, ref0, ref1, ref2, ref3; - v16u8 src = { 0 }; - v16u8 ref = { 0 }; - v16u8 diff; - v8u16 sad = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LW4(src_ptr, src_stride, src0, src1, src2, src3); - src_ptr += (4 * src_stride); - LW4(ref_ptr, ref_stride, ref0, ref1, ref2, ref3); - ref_ptr += (4 * ref_stride); - - INSERT_W4_UB(src0, src1, src2, src3, src); - INSERT_W4_UB(ref0, ref1, ref2, ref3, ref); - - diff = __msa_asub_u_b(src, ref); - sad += __msa_hadd_u_h(diff, diff); - } - - return HADD_UH_U32(sad); -} - -static uint32_t sad_8width_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - int32_t height) { - int32_t ht_cnt; - v16u8 src0, src1, src2, src3, ref0, ref1, ref2, ref3; - v8u16 sad = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - LD_UB4(ref, ref_stride, ref0, ref1, ref2, ref3); - ref += (4 * ref_stride); - - PCKEV_D4_UB(src1, src0, src3, src2, ref1, ref0, ref3, ref2, src0, src1, - ref0, ref1); - sad += SAD_UB2_UH(src0, src1, ref0, ref1); - } - - return HADD_UH_U32(sad); -} - -static uint32_t sad_16width_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - int32_t height) { - int32_t ht_cnt; - v16u8 src0, src1, ref0, ref1; - v8u16 sad = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LD_UB2(src, src_stride, src0, src1); - src += (2 * src_stride); - LD_UB2(ref, ref_stride, ref0, ref1); - ref += (2 * ref_stride); - sad += SAD_UB2_UH(src0, src1, ref0, ref1); - - LD_UB2(src, src_stride, src0, src1); - src += (2 * src_stride); - LD_UB2(ref, ref_stride, ref0, ref1); - ref += (2 * ref_stride); - sad += SAD_UB2_UH(src0, src1, ref0, ref1); - } - - return HADD_UH_U32(sad); -} - -static uint32_t sad_32width_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - int32_t height) { - int32_t ht_cnt; - v16u8 src0, src1, ref0, ref1; - v8u16 sad = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LD_UB2(src, 16, src0, src1); - src += src_stride; - LD_UB2(ref, 16, ref0, ref1); - ref += ref_stride; - sad += SAD_UB2_UH(src0, src1, ref0, ref1); - - LD_UB2(src, 16, src0, src1); - src += src_stride; - LD_UB2(ref, 16, ref0, ref1); - ref += ref_stride; - sad += SAD_UB2_UH(src0, src1, ref0, ref1); - - LD_UB2(src, 16, src0, src1); - src += src_stride; - LD_UB2(ref, 16, ref0, ref1); - ref += ref_stride; - sad += SAD_UB2_UH(src0, src1, ref0, ref1); - - LD_UB2(src, 16, src0, src1); - src += src_stride; - LD_UB2(ref, 16, ref0, ref1); - ref += ref_stride; - sad += SAD_UB2_UH(src0, src1, ref0, ref1); - } - - return HADD_UH_U32(sad); -} - -static uint32_t sad_64width_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - int32_t height) { - int32_t ht_cnt; - uint32_t sad = 0; - v16u8 src0, src1, src2, src3; - v16u8 ref0, ref1, ref2, ref3; - v8u16 sad0 = { 0 }; - v8u16 sad1 = { 0 }; - - for (ht_cnt = (height >> 1); ht_cnt--;) { - LD_UB4(src, 16, src0, src1, src2, src3); - src += src_stride; - LD_UB4(ref, 16, ref0, ref1, ref2, ref3); - ref += ref_stride; - sad0 += SAD_UB2_UH(src0, src1, ref0, ref1); - sad1 += SAD_UB2_UH(src2, src3, ref2, ref3); - - LD_UB4(src, 16, src0, src1, src2, src3); - src += src_stride; - LD_UB4(ref, 16, ref0, ref1, ref2, ref3); - ref += ref_stride; - sad0 += SAD_UB2_UH(src0, src1, ref0, ref1); - sad1 += SAD_UB2_UH(src2, src3, ref2, ref3); - } - - sad = HADD_UH_U32(sad0); - sad += HADD_UH_U32(sad1); - - return sad; -} - -static void sad_4width_x4d_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *const aref_ptr[], - int32_t ref_stride, int32_t height, - uint32_t *sad_array) { - const uint8_t *ref0_ptr, *ref1_ptr, *ref2_ptr, *ref3_ptr; - int32_t ht_cnt; - uint32_t src0, src1, src2, src3; - uint32_t ref0, ref1, ref2, ref3; - v16u8 src = { 0 }; - v16u8 ref = { 0 }; - v16u8 diff; - v8u16 sad0 = { 0 }; - v8u16 sad1 = { 0 }; - v8u16 sad2 = { 0 }; - v8u16 sad3 = { 0 }; - - ref0_ptr = aref_ptr[0]; - ref1_ptr = aref_ptr[1]; - ref2_ptr = aref_ptr[2]; - ref3_ptr = aref_ptr[3]; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LW4(src_ptr, src_stride, src0, src1, src2, src3); - INSERT_W4_UB(src0, src1, src2, src3, src); - src_ptr += (4 * src_stride); - - LW4(ref0_ptr, ref_stride, ref0, ref1, ref2, ref3); - INSERT_W4_UB(ref0, ref1, ref2, ref3, ref); - ref0_ptr += (4 * ref_stride); - - diff = __msa_asub_u_b(src, ref); - sad0 += __msa_hadd_u_h(diff, diff); - - LW4(ref1_ptr, ref_stride, ref0, ref1, ref2, ref3); - INSERT_W4_UB(ref0, ref1, ref2, ref3, ref); - ref1_ptr += (4 * ref_stride); - - diff = __msa_asub_u_b(src, ref); - sad1 += __msa_hadd_u_h(diff, diff); - - LW4(ref2_ptr, ref_stride, ref0, ref1, ref2, ref3); - INSERT_W4_UB(ref0, ref1, ref2, ref3, ref); - ref2_ptr += (4 * ref_stride); - - diff = __msa_asub_u_b(src, ref); - sad2 += __msa_hadd_u_h(diff, diff); - - LW4(ref3_ptr, ref_stride, ref0, ref1, ref2, ref3); - INSERT_W4_UB(ref0, ref1, ref2, ref3, ref); - ref3_ptr += (4 * ref_stride); - - diff = __msa_asub_u_b(src, ref); - sad3 += __msa_hadd_u_h(diff, diff); - } - - sad_array[0] = HADD_UH_U32(sad0); - sad_array[1] = HADD_UH_U32(sad1); - sad_array[2] = HADD_UH_U32(sad2); - sad_array[3] = HADD_UH_U32(sad3); -} - -static void sad_8width_x4d_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *const aref_ptr[], - int32_t ref_stride, int32_t height, - uint32_t *sad_array) { - int32_t ht_cnt; - const uint8_t *ref0_ptr, *ref1_ptr, *ref2_ptr, *ref3_ptr; - v16u8 src0, src1, src2, src3; - v16u8 ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7; - v16u8 ref8, ref9, ref10, ref11, ref12, ref13, ref14, ref15; - v8u16 sad0 = { 0 }; - v8u16 sad1 = { 0 }; - v8u16 sad2 = { 0 }; - v8u16 sad3 = { 0 }; - - ref0_ptr = aref_ptr[0]; - ref1_ptr = aref_ptr[1]; - ref2_ptr = aref_ptr[2]; - ref3_ptr = aref_ptr[3]; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LD_UB4(src_ptr, src_stride, src0, src1, src2, src3); - src_ptr += (4 * src_stride); - LD_UB4(ref0_ptr, ref_stride, ref0, ref1, ref2, ref3); - ref0_ptr += (4 * ref_stride); - LD_UB4(ref1_ptr, ref_stride, ref4, ref5, ref6, ref7); - ref1_ptr += (4 * ref_stride); - LD_UB4(ref2_ptr, ref_stride, ref8, ref9, ref10, ref11); - ref2_ptr += (4 * ref_stride); - LD_UB4(ref3_ptr, ref_stride, ref12, ref13, ref14, ref15); - ref3_ptr += (4 * ref_stride); - - PCKEV_D2_UB(src1, src0, src3, src2, src0, src1); - PCKEV_D2_UB(ref1, ref0, ref3, ref2, ref0, ref1); - sad0 += SAD_UB2_UH(src0, src1, ref0, ref1); - - PCKEV_D2_UB(ref5, ref4, ref7, ref6, ref0, ref1); - sad1 += SAD_UB2_UH(src0, src1, ref0, ref1); - - PCKEV_D2_UB(ref9, ref8, ref11, ref10, ref0, ref1); - sad2 += SAD_UB2_UH(src0, src1, ref0, ref1); - - PCKEV_D2_UB(ref13, ref12, ref15, ref14, ref0, ref1); - sad3 += SAD_UB2_UH(src0, src1, ref0, ref1); - } - - sad_array[0] = HADD_UH_U32(sad0); - sad_array[1] = HADD_UH_U32(sad1); - sad_array[2] = HADD_UH_U32(sad2); - sad_array[3] = HADD_UH_U32(sad3); -} - -static void sad_16width_x4d_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *const aref_ptr[], - int32_t ref_stride, int32_t height, - uint32_t *sad_array) { - int32_t ht_cnt; - const uint8_t *ref0_ptr, *ref1_ptr, *ref2_ptr, *ref3_ptr; - v16u8 src, ref0, ref1, ref2, ref3, diff; - v8u16 sad0 = { 0 }; - v8u16 sad1 = { 0 }; - v8u16 sad2 = { 0 }; - v8u16 sad3 = { 0 }; - - ref0_ptr = aref_ptr[0]; - ref1_ptr = aref_ptr[1]; - ref2_ptr = aref_ptr[2]; - ref3_ptr = aref_ptr[3]; - - for (ht_cnt = (height >> 1); ht_cnt--;) { - src = LD_UB(src_ptr); - src_ptr += src_stride; - ref0 = LD_UB(ref0_ptr); - ref0_ptr += ref_stride; - ref1 = LD_UB(ref1_ptr); - ref1_ptr += ref_stride; - ref2 = LD_UB(ref2_ptr); - ref2_ptr += ref_stride; - ref3 = LD_UB(ref3_ptr); - ref3_ptr += ref_stride; - - diff = __msa_asub_u_b(src, ref0); - sad0 += __msa_hadd_u_h(diff, diff); - diff = __msa_asub_u_b(src, ref1); - sad1 += __msa_hadd_u_h(diff, diff); - diff = __msa_asub_u_b(src, ref2); - sad2 += __msa_hadd_u_h(diff, diff); - diff = __msa_asub_u_b(src, ref3); - sad3 += __msa_hadd_u_h(diff, diff); - - src = LD_UB(src_ptr); - src_ptr += src_stride; - ref0 = LD_UB(ref0_ptr); - ref0_ptr += ref_stride; - ref1 = LD_UB(ref1_ptr); - ref1_ptr += ref_stride; - ref2 = LD_UB(ref2_ptr); - ref2_ptr += ref_stride; - ref3 = LD_UB(ref3_ptr); - ref3_ptr += ref_stride; - - diff = __msa_asub_u_b(src, ref0); - sad0 += __msa_hadd_u_h(diff, diff); - diff = __msa_asub_u_b(src, ref1); - sad1 += __msa_hadd_u_h(diff, diff); - diff = __msa_asub_u_b(src, ref2); - sad2 += __msa_hadd_u_h(diff, diff); - diff = __msa_asub_u_b(src, ref3); - sad3 += __msa_hadd_u_h(diff, diff); - } - - sad_array[0] = HADD_UH_U32(sad0); - sad_array[1] = HADD_UH_U32(sad1); - sad_array[2] = HADD_UH_U32(sad2); - sad_array[3] = HADD_UH_U32(sad3); -} - -static void sad_32width_x4d_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *const aref_ptr[], - int32_t ref_stride, int32_t height, - uint32_t *sad_array) { - const uint8_t *ref0_ptr, *ref1_ptr, *ref2_ptr, *ref3_ptr; - int32_t ht_cnt; - v16u8 src0, src1, ref0, ref1; - v8u16 sad0 = { 0 }; - v8u16 sad1 = { 0 }; - v8u16 sad2 = { 0 }; - v8u16 sad3 = { 0 }; - - ref0_ptr = aref_ptr[0]; - ref1_ptr = aref_ptr[1]; - ref2_ptr = aref_ptr[2]; - ref3_ptr = aref_ptr[3]; - - for (ht_cnt = height; ht_cnt--;) { - LD_UB2(src, 16, src0, src1); - src += src_stride; - - LD_UB2(ref0_ptr, 16, ref0, ref1); - ref0_ptr += ref_stride; - sad0 += SAD_UB2_UH(src0, src1, ref0, ref1); - - LD_UB2(ref1_ptr, 16, ref0, ref1); - ref1_ptr += ref_stride; - sad1 += SAD_UB2_UH(src0, src1, ref0, ref1); - - LD_UB2(ref2_ptr, 16, ref0, ref1); - ref2_ptr += ref_stride; - sad2 += SAD_UB2_UH(src0, src1, ref0, ref1); - - LD_UB2(ref3_ptr, 16, ref0, ref1); - ref3_ptr += ref_stride; - sad3 += SAD_UB2_UH(src0, src1, ref0, ref1); - } - - sad_array[0] = HADD_UH_U32(sad0); - sad_array[1] = HADD_UH_U32(sad1); - sad_array[2] = HADD_UH_U32(sad2); - sad_array[3] = HADD_UH_U32(sad3); -} - -static void sad_64width_x4d_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *const aref_ptr[], - int32_t ref_stride, int32_t height, - uint32_t *sad_array) { - const uint8_t *ref0_ptr, *ref1_ptr, *ref2_ptr, *ref3_ptr; - int32_t ht_cnt; - v16u8 src0, src1, src2, src3; - v16u8 ref0, ref1, ref2, ref3; - v8u16 sad0_0 = { 0 }; - v8u16 sad0_1 = { 0 }; - v8u16 sad1_0 = { 0 }; - v8u16 sad1_1 = { 0 }; - v8u16 sad2_0 = { 0 }; - v8u16 sad2_1 = { 0 }; - v8u16 sad3_0 = { 0 }; - v8u16 sad3_1 = { 0 }; - v4u32 sad; - - ref0_ptr = aref_ptr[0]; - ref1_ptr = aref_ptr[1]; - ref2_ptr = aref_ptr[2]; - ref3_ptr = aref_ptr[3]; - - for (ht_cnt = height; ht_cnt--;) { - LD_UB4(src, 16, src0, src1, src2, src3); - src += src_stride; - - LD_UB4(ref0_ptr, 16, ref0, ref1, ref2, ref3); - ref0_ptr += ref_stride; - sad0_0 += SAD_UB2_UH(src0, src1, ref0, ref1); - sad0_1 += SAD_UB2_UH(src2, src3, ref2, ref3); - - LD_UB4(ref1_ptr, 16, ref0, ref1, ref2, ref3); - ref1_ptr += ref_stride; - sad1_0 += SAD_UB2_UH(src0, src1, ref0, ref1); - sad1_1 += SAD_UB2_UH(src2, src3, ref2, ref3); - - LD_UB4(ref2_ptr, 16, ref0, ref1, ref2, ref3); - ref2_ptr += ref_stride; - sad2_0 += SAD_UB2_UH(src0, src1, ref0, ref1); - sad2_1 += SAD_UB2_UH(src2, src3, ref2, ref3); - - LD_UB4(ref3_ptr, 16, ref0, ref1, ref2, ref3); - ref3_ptr += ref_stride; - sad3_0 += SAD_UB2_UH(src0, src1, ref0, ref1); - sad3_1 += SAD_UB2_UH(src2, src3, ref2, ref3); - } - - sad = __msa_hadd_u_w(sad0_0, sad0_0); - sad += __msa_hadd_u_w(sad0_1, sad0_1); - sad_array[0] = HADD_UW_U32(sad); - - sad = __msa_hadd_u_w(sad1_0, sad1_0); - sad += __msa_hadd_u_w(sad1_1, sad1_1); - sad_array[1] = HADD_UW_U32(sad); - - sad = __msa_hadd_u_w(sad2_0, sad2_0); - sad += __msa_hadd_u_w(sad2_1, sad2_1); - sad_array[2] = HADD_UW_U32(sad); - - sad = __msa_hadd_u_w(sad3_0, sad3_0); - sad += __msa_hadd_u_w(sad3_1, sad3_1); - sad_array[3] = HADD_UW_U32(sad); -} - -static uint32_t avgsad_4width_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t height, const uint8_t *sec_pred) { - int32_t ht_cnt; - uint32_t src0, src1, src2, src3, ref0, ref1, ref2, ref3; - v16u8 src = { 0 }; - v16u8 ref = { 0 }; - v16u8 diff, pred, comp; - v8u16 sad = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LW4(src_ptr, src_stride, src0, src1, src2, src3); - src_ptr += (4 * src_stride); - LW4(ref_ptr, ref_stride, ref0, ref1, ref2, ref3); - ref_ptr += (4 * ref_stride); - pred = LD_UB(sec_pred); - sec_pred += 16; - - INSERT_W4_UB(src0, src1, src2, src3, src); - INSERT_W4_UB(ref0, ref1, ref2, ref3, ref); - - comp = __msa_aver_u_b(pred, ref); - diff = __msa_asub_u_b(src, comp); - sad += __msa_hadd_u_h(diff, diff); - } - - return HADD_UH_U32(sad); -} - -static uint32_t avgsad_8width_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - int32_t height, const uint8_t *sec_pred) { - int32_t ht_cnt; - v16u8 src0, src1, src2, src3, ref0, ref1, ref2, ref3; - v16u8 diff0, diff1, pred0, pred1; - v8u16 sad = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - LD_UB4(ref, ref_stride, ref0, ref1, ref2, ref3); - ref += (4 * ref_stride); - LD_UB2(sec_pred, 16, pred0, pred1); - sec_pred += 32; - PCKEV_D4_UB(src1, src0, src3, src2, ref1, ref0, ref3, ref2, src0, src1, - ref0, ref1); - AVER_UB2_UB(pred0, ref0, pred1, ref1, diff0, diff1); - sad += SAD_UB2_UH(src0, src1, diff0, diff1); - } - - return HADD_UH_U32(sad); -} - -static uint32_t avgsad_16width_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - int32_t height, const uint8_t *sec_pred) { - int32_t ht_cnt; - v16u8 src0, src1, src2, src3, ref0, ref1, ref2, ref3; - v16u8 pred0, pred1, pred2, pred3, comp0, comp1; - v8u16 sad = { 0 }; - - for (ht_cnt = (height >> 3); ht_cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - LD_UB4(ref, ref_stride, ref0, ref1, ref2, ref3); - ref += (4 * ref_stride); - LD_UB4(sec_pred, 16, pred0, pred1, pred2, pred3); - sec_pred += (4 * 16); - AVER_UB2_UB(pred0, ref0, pred1, ref1, comp0, comp1); - sad += SAD_UB2_UH(src0, src1, comp0, comp1); - AVER_UB2_UB(pred2, ref2, pred3, ref3, comp0, comp1); - sad += SAD_UB2_UH(src2, src3, comp0, comp1); - - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - LD_UB4(ref, ref_stride, ref0, ref1, ref2, ref3); - ref += (4 * ref_stride); - LD_UB4(sec_pred, 16, pred0, pred1, pred2, pred3); - sec_pred += (4 * 16); - AVER_UB2_UB(pred0, ref0, pred1, ref1, comp0, comp1); - sad += SAD_UB2_UH(src0, src1, comp0, comp1); - AVER_UB2_UB(pred2, ref2, pred3, ref3, comp0, comp1); - sad += SAD_UB2_UH(src2, src3, comp0, comp1); - } - - return HADD_UH_U32(sad); -} - -static uint32_t avgsad_32width_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - int32_t height, const uint8_t *sec_pred) { - int32_t ht_cnt; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v16u8 ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7; - v16u8 pred0, pred1, pred2, pred3, pred4, pred5, pred6, pred7; - v16u8 comp0, comp1; - v8u16 sad = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LD_UB4(src, src_stride, src0, src2, src4, src6); - LD_UB4(src + 16, src_stride, src1, src3, src5, src7); - src += (4 * src_stride); - - LD_UB4(ref, ref_stride, ref0, ref2, ref4, ref6); - LD_UB4(ref + 16, ref_stride, ref1, ref3, ref5, ref7); - ref += (4 * ref_stride); - - LD_UB4(sec_pred, 32, pred0, pred2, pred4, pred6); - LD_UB4(sec_pred + 16, 32, pred1, pred3, pred5, pred7); - sec_pred += (4 * 32); - - AVER_UB2_UB(pred0, ref0, pred1, ref1, comp0, comp1); - sad += SAD_UB2_UH(src0, src1, comp0, comp1); - AVER_UB2_UB(pred2, ref2, pred3, ref3, comp0, comp1); - sad += SAD_UB2_UH(src2, src3, comp0, comp1); - AVER_UB2_UB(pred4, ref4, pred5, ref5, comp0, comp1); - sad += SAD_UB2_UH(src4, src5, comp0, comp1); - AVER_UB2_UB(pred6, ref6, pred7, ref7, comp0, comp1); - sad += SAD_UB2_UH(src6, src7, comp0, comp1); - } - - return HADD_UH_U32(sad); -} - -static uint32_t avgsad_64width_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - int32_t height, const uint8_t *sec_pred) { - int32_t ht_cnt; - v16u8 src0, src1, src2, src3; - v16u8 ref0, ref1, ref2, ref3; - v16u8 comp0, comp1, comp2, comp3; - v16u8 pred0, pred1, pred2, pred3; - v8u16 sad0 = { 0 }; - v8u16 sad1 = { 0 }; - v4u32 sad; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LD_UB4(src, 16, src0, src1, src2, src3); - src += src_stride; - LD_UB4(ref, 16, ref0, ref1, ref2, ref3); - ref += ref_stride; - LD_UB4(sec_pred, 16, pred0, pred1, pred2, pred3); - sec_pred += 64; - AVER_UB4_UB(pred0, ref0, pred1, ref1, pred2, ref2, pred3, ref3, comp0, - comp1, comp2, comp3); - sad0 += SAD_UB2_UH(src0, src1, comp0, comp1); - sad1 += SAD_UB2_UH(src2, src3, comp2, comp3); - - LD_UB4(src, 16, src0, src1, src2, src3); - src += src_stride; - LD_UB4(ref, 16, ref0, ref1, ref2, ref3); - ref += ref_stride; - LD_UB4(sec_pred, 16, pred0, pred1, pred2, pred3); - sec_pred += 64; - AVER_UB4_UB(pred0, ref0, pred1, ref1, pred2, ref2, pred3, ref3, comp0, - comp1, comp2, comp3); - sad0 += SAD_UB2_UH(src0, src1, comp0, comp1); - sad1 += SAD_UB2_UH(src2, src3, comp2, comp3); - - LD_UB4(src, 16, src0, src1, src2, src3); - src += src_stride; - LD_UB4(ref, 16, ref0, ref1, ref2, ref3); - ref += ref_stride; - LD_UB4(sec_pred, 16, pred0, pred1, pred2, pred3); - sec_pred += 64; - AVER_UB4_UB(pred0, ref0, pred1, ref1, pred2, ref2, pred3, ref3, comp0, - comp1, comp2, comp3); - sad0 += SAD_UB2_UH(src0, src1, comp0, comp1); - sad1 += SAD_UB2_UH(src2, src3, comp2, comp3); - - LD_UB4(src, 16, src0, src1, src2, src3); - src += src_stride; - LD_UB4(ref, 16, ref0, ref1, ref2, ref3); - ref += ref_stride; - LD_UB4(sec_pred, 16, pred0, pred1, pred2, pred3); - sec_pred += 64; - AVER_UB4_UB(pred0, ref0, pred1, ref1, pred2, ref2, pred3, ref3, comp0, - comp1, comp2, comp3); - sad0 += SAD_UB2_UH(src0, src1, comp0, comp1); - sad1 += SAD_UB2_UH(src2, src3, comp2, comp3); - } - - sad = __msa_hadd_u_w(sad0, sad0); - sad += __msa_hadd_u_w(sad1, sad1); - - return HADD_SW_S32(sad); -} - -#define VPX_SAD_4xHEIGHT_MSA(height) \ - uint32_t vpx_sad4x##height##_msa(const uint8_t *src, int32_t src_stride, \ - const uint8_t *ref, int32_t ref_stride) { \ - return sad_4width_msa(src, src_stride, ref, ref_stride, height); \ - } - -#define VPX_SAD_8xHEIGHT_MSA(height) \ - uint32_t vpx_sad8x##height##_msa(const uint8_t *src, int32_t src_stride, \ - const uint8_t *ref, int32_t ref_stride) { \ - return sad_8width_msa(src, src_stride, ref, ref_stride, height); \ - } - -#define VPX_SAD_16xHEIGHT_MSA(height) \ - uint32_t vpx_sad16x##height##_msa(const uint8_t *src, int32_t src_stride, \ - const uint8_t *ref, int32_t ref_stride) { \ - return sad_16width_msa(src, src_stride, ref, ref_stride, height); \ - } - -#define VPX_SAD_32xHEIGHT_MSA(height) \ - uint32_t vpx_sad32x##height##_msa(const uint8_t *src, int32_t src_stride, \ - const uint8_t *ref, int32_t ref_stride) { \ - return sad_32width_msa(src, src_stride, ref, ref_stride, height); \ - } - -#define VPX_SAD_64xHEIGHT_MSA(height) \ - uint32_t vpx_sad64x##height##_msa(const uint8_t *src, int32_t src_stride, \ - const uint8_t *ref, int32_t ref_stride) { \ - return sad_64width_msa(src, src_stride, ref, ref_stride, height); \ - } - -#define VPX_SAD_4xHEIGHTx4D_MSA(height) \ - void vpx_sad4x##height##x4d_msa(const uint8_t *src, int32_t src_stride, \ - const uint8_t *const refs[4], \ - int32_t ref_stride, uint32_t sads[4]) { \ - sad_4width_x4d_msa(src, src_stride, refs, ref_stride, height, sads); \ - } - -#define VPX_SAD_8xHEIGHTx4D_MSA(height) \ - void vpx_sad8x##height##x4d_msa(const uint8_t *src, int32_t src_stride, \ - const uint8_t *const refs[4], \ - int32_t ref_stride, uint32_t sads[4]) { \ - sad_8width_x4d_msa(src, src_stride, refs, ref_stride, height, sads); \ - } - -#define VPX_SAD_16xHEIGHTx4D_MSA(height) \ - void vpx_sad16x##height##x4d_msa(const uint8_t *src, int32_t src_stride, \ - const uint8_t *const refs[4], \ - int32_t ref_stride, uint32_t sads[4]) { \ - sad_16width_x4d_msa(src, src_stride, refs, ref_stride, height, sads); \ - } - -#define VPX_SAD_32xHEIGHTx4D_MSA(height) \ - void vpx_sad32x##height##x4d_msa(const uint8_t *src, int32_t src_stride, \ - const uint8_t *const refs[4], \ - int32_t ref_stride, uint32_t sads[4]) { \ - sad_32width_x4d_msa(src, src_stride, refs, ref_stride, height, sads); \ - } - -#define VPX_SAD_64xHEIGHTx4D_MSA(height) \ - void vpx_sad64x##height##x4d_msa(const uint8_t *src, int32_t src_stride, \ - const uint8_t *const refs[4], \ - int32_t ref_stride, uint32_t sads[4]) { \ - sad_64width_x4d_msa(src, src_stride, refs, ref_stride, height, sads); \ - } - -#define VPX_AVGSAD_4xHEIGHT_MSA(height) \ - uint32_t vpx_sad4x##height##_avg_msa(const uint8_t *src, int32_t src_stride, \ - const uint8_t *ref, int32_t ref_stride, \ - const uint8_t *second_pred) { \ - return avgsad_4width_msa(src, src_stride, ref, ref_stride, height, \ - second_pred); \ - } - -#define VPX_AVGSAD_8xHEIGHT_MSA(height) \ - uint32_t vpx_sad8x##height##_avg_msa(const uint8_t *src, int32_t src_stride, \ - const uint8_t *ref, int32_t ref_stride, \ - const uint8_t *second_pred) { \ - return avgsad_8width_msa(src, src_stride, ref, ref_stride, height, \ - second_pred); \ - } - -#define VPX_AVGSAD_16xHEIGHT_MSA(height) \ - uint32_t vpx_sad16x##height##_avg_msa( \ - const uint8_t *src, int32_t src_stride, const uint8_t *ref, \ - int32_t ref_stride, const uint8_t *second_pred) { \ - return avgsad_16width_msa(src, src_stride, ref, ref_stride, height, \ - second_pred); \ - } - -#define VPX_AVGSAD_32xHEIGHT_MSA(height) \ - uint32_t vpx_sad32x##height##_avg_msa( \ - const uint8_t *src, int32_t src_stride, const uint8_t *ref, \ - int32_t ref_stride, const uint8_t *second_pred) { \ - return avgsad_32width_msa(src, src_stride, ref, ref_stride, height, \ - second_pred); \ - } - -#define VPX_AVGSAD_64xHEIGHT_MSA(height) \ - uint32_t vpx_sad64x##height##_avg_msa( \ - const uint8_t *src, int32_t src_stride, const uint8_t *ref, \ - int32_t ref_stride, const uint8_t *second_pred) { \ - return avgsad_64width_msa(src, src_stride, ref, ref_stride, height, \ - second_pred); \ - } - -// 64x64 -VPX_SAD_64xHEIGHT_MSA(64); -VPX_SAD_64xHEIGHTx4D_MSA(64); -VPX_AVGSAD_64xHEIGHT_MSA(64); - -// 64x32 -VPX_SAD_64xHEIGHT_MSA(32); -VPX_SAD_64xHEIGHTx4D_MSA(32); -VPX_AVGSAD_64xHEIGHT_MSA(32); - -// 32x64 -VPX_SAD_32xHEIGHT_MSA(64); -VPX_SAD_32xHEIGHTx4D_MSA(64); -VPX_AVGSAD_32xHEIGHT_MSA(64); - -// 32x32 -VPX_SAD_32xHEIGHT_MSA(32); -VPX_SAD_32xHEIGHTx4D_MSA(32); -VPX_AVGSAD_32xHEIGHT_MSA(32); - -// 32x16 -VPX_SAD_32xHEIGHT_MSA(16); -VPX_SAD_32xHEIGHTx4D_MSA(16); -VPX_AVGSAD_32xHEIGHT_MSA(16); - -// 16x32 -VPX_SAD_16xHEIGHT_MSA(32); -VPX_SAD_16xHEIGHTx4D_MSA(32); -VPX_AVGSAD_16xHEIGHT_MSA(32); - -// 16x16 -VPX_SAD_16xHEIGHT_MSA(16); -VPX_SAD_16xHEIGHTx4D_MSA(16); -VPX_AVGSAD_16xHEIGHT_MSA(16); - -// 16x8 -VPX_SAD_16xHEIGHT_MSA(8); -VPX_SAD_16xHEIGHTx4D_MSA(8); -VPX_AVGSAD_16xHEIGHT_MSA(8); - -// 8x16 -VPX_SAD_8xHEIGHT_MSA(16); -VPX_SAD_8xHEIGHTx4D_MSA(16); -VPX_AVGSAD_8xHEIGHT_MSA(16); - -// 8x8 -VPX_SAD_8xHEIGHT_MSA(8); -VPX_SAD_8xHEIGHTx4D_MSA(8); -VPX_AVGSAD_8xHEIGHT_MSA(8); - -// 8x4 -VPX_SAD_8xHEIGHT_MSA(4); -VPX_SAD_8xHEIGHTx4D_MSA(4); -VPX_AVGSAD_8xHEIGHT_MSA(4); - -// 4x8 -VPX_SAD_4xHEIGHT_MSA(8); -VPX_SAD_4xHEIGHTx4D_MSA(8); -VPX_AVGSAD_4xHEIGHT_MSA(8); - -// 4x4 -VPX_SAD_4xHEIGHT_MSA(4); -VPX_SAD_4xHEIGHTx4D_MSA(4); -VPX_AVGSAD_4xHEIGHT_MSA(4); diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/sub_pixel_variance_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/sub_pixel_variance_msa.c deleted file mode 100644 index 572fcabf..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/sub_pixel_variance_msa.c +++ /dev/null @@ -1,1789 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_ports/mem.h" -#include "vpx_dsp/mips/macros_msa.h" -#include "vpx_dsp/variance.h" - -static const uint8_t bilinear_filters_msa[8][2] = { - { 128, 0 }, { 112, 16 }, { 96, 32 }, { 80, 48 }, - { 64, 64 }, { 48, 80 }, { 32, 96 }, { 16, 112 }, -}; - -#define CALC_MSE_AVG_B(src, ref, var, sub) \ - { \ - v16u8 src_l0_m, src_l1_m; \ - v8i16 res_l0_m, res_l1_m; \ - \ - ILVRL_B2_UB(src, ref, src_l0_m, src_l1_m); \ - HSUB_UB2_SH(src_l0_m, src_l1_m, res_l0_m, res_l1_m); \ - DPADD_SH2_SW(res_l0_m, res_l1_m, res_l0_m, res_l1_m, var, var); \ - \ - (sub) += res_l0_m + res_l1_m; \ - } - -#define VARIANCE_WxH(sse, diff, shift) \ - (sse) - (((uint32_t)(diff) * (diff)) >> (shift)) - -#define VARIANCE_LARGE_WxH(sse, diff, shift) \ - (sse) - (((int64_t)(diff) * (diff)) >> (shift)) - -static uint32_t avg_sse_diff_4width_msa(const uint8_t *src_ptr, - int32_t src_stride, - const uint8_t *ref_ptr, - int32_t ref_stride, - const uint8_t *sec_pred, int32_t height, - int32_t *diff) { - int32_t ht_cnt; - uint32_t src0, src1, src2, src3; - uint32_t ref0, ref1, ref2, ref3; - v16u8 pred, src = { 0 }; - v16u8 ref = { 0 }; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - pred = LD_UB(sec_pred); - sec_pred += 16; - LW4(src_ptr, src_stride, src0, src1, src2, src3); - src_ptr += (4 * src_stride); - LW4(ref_ptr, ref_stride, ref0, ref1, ref2, ref3); - ref_ptr += (4 * ref_stride); - - INSERT_W4_UB(src0, src1, src2, src3, src); - INSERT_W4_UB(ref0, ref1, ref2, ref3, ref); - - src = __msa_aver_u_b(src, pred); - CALC_MSE_AVG_B(src, ref, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t avg_sse_diff_8width_msa(const uint8_t *src_ptr, - int32_t src_stride, - const uint8_t *ref_ptr, - int32_t ref_stride, - const uint8_t *sec_pred, int32_t height, - int32_t *diff) { - int32_t ht_cnt; - v16u8 src0, src1, src2, src3; - v16u8 ref0, ref1, ref2, ref3; - v16u8 pred0, pred1; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LD_UB2(sec_pred, 16, pred0, pred1); - sec_pred += 32; - LD_UB4(src_ptr, src_stride, src0, src1, src2, src3); - src_ptr += (4 * src_stride); - LD_UB4(ref_ptr, ref_stride, ref0, ref1, ref2, ref3); - ref_ptr += (4 * ref_stride); - - PCKEV_D4_UB(src1, src0, src3, src2, ref1, ref0, ref3, ref2, src0, src1, - ref0, ref1); - AVER_UB2_UB(src0, pred0, src1, pred1, src0, src1); - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t avg_sse_diff_16width_msa(const uint8_t *src_ptr, - int32_t src_stride, - const uint8_t *ref_ptr, - int32_t ref_stride, - const uint8_t *sec_pred, - int32_t height, int32_t *diff) { - int32_t ht_cnt; - v16u8 src, ref, pred; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - pred = LD_UB(sec_pred); - sec_pred += 16; - src = LD_UB(src_ptr); - src_ptr += src_stride; - ref = LD_UB(ref_ptr); - ref_ptr += ref_stride; - src = __msa_aver_u_b(src, pred); - CALC_MSE_AVG_B(src, ref, var, avg); - - pred = LD_UB(sec_pred); - sec_pred += 16; - src = LD_UB(src_ptr); - src_ptr += src_stride; - ref = LD_UB(ref_ptr); - ref_ptr += ref_stride; - src = __msa_aver_u_b(src, pred); - CALC_MSE_AVG_B(src, ref, var, avg); - - pred = LD_UB(sec_pred); - sec_pred += 16; - src = LD_UB(src_ptr); - src_ptr += src_stride; - ref = LD_UB(ref_ptr); - ref_ptr += ref_stride; - src = __msa_aver_u_b(src, pred); - CALC_MSE_AVG_B(src, ref, var, avg); - - pred = LD_UB(sec_pred); - sec_pred += 16; - src = LD_UB(src_ptr); - src_ptr += src_stride; - ref = LD_UB(ref_ptr); - ref_ptr += ref_stride; - src = __msa_aver_u_b(src, pred); - CALC_MSE_AVG_B(src, ref, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t avg_sse_diff_32width_msa(const uint8_t *src_ptr, - int32_t src_stride, - const uint8_t *ref_ptr, - int32_t ref_stride, - const uint8_t *sec_pred, - int32_t height, int32_t *diff) { - int32_t ht_cnt; - v16u8 src0, src1, ref0, ref1, pred0, pred1; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LD_UB2(sec_pred, 16, pred0, pred1); - sec_pred += 32; - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - AVER_UB2_UB(src0, pred0, src1, pred1, src0, src1); - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - - LD_UB2(sec_pred, 16, pred0, pred1); - sec_pred += 32; - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - AVER_UB2_UB(src0, pred0, src1, pred1, src0, src1); - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - - LD_UB2(sec_pred, 16, pred0, pred1); - sec_pred += 32; - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - AVER_UB2_UB(src0, pred0, src1, pred1, src0, src1); - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - - LD_UB2(sec_pred, 16, pred0, pred1); - sec_pred += 32; - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - AVER_UB2_UB(src0, pred0, src1, pred1, src0, src1); - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t avg_sse_diff_32x64_msa(const uint8_t *src_ptr, - int32_t src_stride, - const uint8_t *ref_ptr, - int32_t ref_stride, - const uint8_t *sec_pred, int32_t *diff) { - int32_t ht_cnt; - v16u8 src0, src1, ref0, ref1, pred0, pred1; - v8i16 avg0 = { 0 }; - v8i16 avg1 = { 0 }; - v4i32 vec, var = { 0 }; - - for (ht_cnt = 16; ht_cnt--;) { - LD_UB2(sec_pred, 16, pred0, pred1); - sec_pred += 32; - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - AVER_UB2_UB(src0, pred0, src1, pred1, src0, src1); - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - - LD_UB2(sec_pred, 16, pred0, pred1); - sec_pred += 32; - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - AVER_UB2_UB(src0, pred0, src1, pred1, src0, src1); - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - - LD_UB2(sec_pred, 16, pred0, pred1); - sec_pred += 32; - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - AVER_UB2_UB(src0, pred0, src1, pred1, src0, src1); - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - - LD_UB2(sec_pred, 16, pred0, pred1); - sec_pred += 32; - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - AVER_UB2_UB(src0, pred0, src1, pred1, src0, src1); - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - } - - vec = __msa_hadd_s_w(avg0, avg0); - vec += __msa_hadd_s_w(avg1, avg1); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t avg_sse_diff_64x32_msa(const uint8_t *src_ptr, - int32_t src_stride, - const uint8_t *ref_ptr, - int32_t ref_stride, - const uint8_t *sec_pred, int32_t *diff) { - int32_t ht_cnt; - v16u8 src0, src1, src2, src3; - v16u8 ref0, ref1, ref2, ref3; - v16u8 pred0, pred1, pred2, pred3; - v8i16 avg0 = { 0 }; - v8i16 avg1 = { 0 }; - v4i32 vec, var = { 0 }; - - for (ht_cnt = 16; ht_cnt--;) { - LD_UB4(sec_pred, 16, pred0, pred1, pred2, pred3); - sec_pred += 64; - LD_UB4(src_ptr, 16, src0, src1, src2, src3); - src_ptr += src_stride; - LD_UB4(ref_ptr, 16, ref0, ref1, ref2, ref3); - ref_ptr += ref_stride; - AVER_UB4_UB(src0, pred0, src1, pred1, src2, pred2, src3, pred3, src0, src1, - src2, src3); - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src2, ref2, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - CALC_MSE_AVG_B(src3, ref3, var, avg1); - - LD_UB4(sec_pred, 16, pred0, pred1, pred2, pred3); - sec_pred += 64; - LD_UB4(src_ptr, 16, src0, src1, src2, src3); - src_ptr += src_stride; - LD_UB4(ref_ptr, 16, ref0, ref1, ref2, ref3); - ref_ptr += ref_stride; - AVER_UB4_UB(src0, pred0, src1, pred1, src2, pred2, src3, pred3, src0, src1, - src2, src3); - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src2, ref2, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - CALC_MSE_AVG_B(src3, ref3, var, avg1); - } - - vec = __msa_hadd_s_w(avg0, avg0); - vec += __msa_hadd_s_w(avg1, avg1); - - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t avg_sse_diff_64x64_msa(const uint8_t *src_ptr, - int32_t src_stride, - const uint8_t *ref_ptr, - int32_t ref_stride, - const uint8_t *sec_pred, int32_t *diff) { - int32_t ht_cnt; - v16u8 src0, src1, src2, src3; - v16u8 ref0, ref1, ref2, ref3; - v16u8 pred0, pred1, pred2, pred3; - v8i16 avg0 = { 0 }; - v8i16 avg1 = { 0 }; - v8i16 avg2 = { 0 }; - v8i16 avg3 = { 0 }; - v4i32 vec, var = { 0 }; - - for (ht_cnt = 32; ht_cnt--;) { - LD_UB4(sec_pred, 16, pred0, pred1, pred2, pred3); - sec_pred += 64; - LD_UB4(src_ptr, 16, src0, src1, src2, src3); - src_ptr += src_stride; - LD_UB4(ref_ptr, 16, ref0, ref1, ref2, ref3); - ref_ptr += ref_stride; - AVER_UB4_UB(src0, pred0, src1, pred1, src2, pred2, src3, pred3, src0, src1, - src2, src3); - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - CALC_MSE_AVG_B(src2, ref2, var, avg2); - CALC_MSE_AVG_B(src3, ref3, var, avg3); - - LD_UB4(sec_pred, 16, pred0, pred1, pred2, pred3); - sec_pred += 64; - LD_UB4(src_ptr, 16, src0, src1, src2, src3); - src_ptr += src_stride; - LD_UB4(ref_ptr, 16, ref0, ref1, ref2, ref3); - ref_ptr += ref_stride; - AVER_UB4_UB(src0, pred0, src1, pred1, src2, pred2, src3, pred3, src0, src1, - src2, src3); - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - CALC_MSE_AVG_B(src2, ref2, var, avg2); - CALC_MSE_AVG_B(src3, ref3, var, avg3); - } - - vec = __msa_hadd_s_w(avg0, avg0); - vec += __msa_hadd_s_w(avg1, avg1); - vec += __msa_hadd_s_w(avg2, avg2); - vec += __msa_hadd_s_w(avg3, avg3); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sub_pixel_sse_diff_4width_h_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter, int32_t height, int32_t *diff) { - int16_t filtval; - uint32_t loop_cnt; - uint32_t ref0, ref1, ref2, ref3; - v16u8 filt0, ref = { 0 }; - v16i8 src0, src1, src2, src3; - v16i8 mask = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 }; - v8u16 vec0, vec1, vec2, vec3; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - filtval = LH(filter); - filt0 = (v16u8)__msa_fill_h(filtval); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - LW4(dst, dst_stride, ref0, ref1, ref2, ref3); - dst += (4 * dst_stride); - INSERT_W4_UB(ref0, ref1, ref2, ref3, ref); - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, FILTER_BITS); - PCKEV_B4_SB(vec0, vec0, vec1, vec1, vec2, vec2, vec3, vec3, src0, src1, - src2, src3); - ILVEV_W2_SB(src0, src1, src2, src3, src0, src2); - src0 = (v16i8)__msa_ilvev_d((v2i64)src2, (v2i64)src0); - CALC_MSE_AVG_B(src0, ref, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sub_pixel_sse_diff_8width_h_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter, int32_t height, int32_t *diff) { - int16_t filtval; - uint32_t loop_cnt; - v16u8 filt0, out, ref0, ref1, ref2, ref3; - v16i8 src0, src1, src2, src3; - v16i8 mask = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 }; - v8u16 vec0, vec1, vec2, vec3; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - filtval = LH(filter); - filt0 = (v16u8)__msa_fill_h(filtval); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - LD_UB4(dst, dst_stride, ref0, ref1, ref2, ref3); - dst += (4 * dst_stride); - - PCKEV_D2_UB(ref1, ref0, ref3, ref2, ref0, ref1); - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, FILTER_BITS); - PCKEV_B4_SB(vec0, vec0, vec1, vec1, vec2, vec2, vec3, vec3, src0, src1, - src2, src3); - out = (v16u8)__msa_ilvev_d((v2i64)src1, (v2i64)src0); - CALC_MSE_AVG_B(out, ref0, var, avg); - out = (v16u8)__msa_ilvev_d((v2i64)src3, (v2i64)src2); - CALC_MSE_AVG_B(out, ref1, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sub_pixel_sse_diff_16width_h_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter, int32_t height, int32_t *diff) { - int16_t filtval; - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7; - v16i8 mask = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 }; - v16u8 dst0, dst1, dst2, dst3, filt0; - v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8u16 out0, out1, out2, out3, out4, out5, out6, out7; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - filtval = LH(filter); - filt0 = (v16u8)__msa_fill_h(filtval); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src2, src4, src6); - LD_SB4(src + 8, src_stride, src1, src3, src5, src7); - src += (4 * src_stride); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - dst += (4 * dst_stride); - - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - VSHF_B2_UH(src4, src4, src5, src5, mask, mask, vec4, vec5); - VSHF_B2_UH(src6, src6, src7, src7, mask, mask, vec6, vec7); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, out0, out1, - out2, out3); - DOTP_UB4_UH(vec4, vec5, vec6, vec7, filt0, filt0, filt0, filt0, out4, out5, - out6, out7); - SRARI_H4_UH(out0, out1, out2, out3, FILTER_BITS); - SRARI_H4_UH(out4, out5, out6, out7, FILTER_BITS); - PCKEV_B4_SB(out1, out0, out3, out2, out5, out4, out7, out6, src0, src1, - src2, src3); - CALC_MSE_AVG_B(src0, dst0, var, avg); - CALC_MSE_AVG_B(src1, dst1, var, avg); - CALC_MSE_AVG_B(src2, dst2, var, avg); - CALC_MSE_AVG_B(src3, dst3, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sub_pixel_sse_diff_32width_h_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter, int32_t height, int32_t *diff) { - uint32_t loop_cnt, sse = 0; - int32_t diff0[2]; - - for (loop_cnt = 0; loop_cnt < 2; ++loop_cnt) { - sse += sub_pixel_sse_diff_16width_h_msa(src, src_stride, dst, dst_stride, - filter, height, &diff0[loop_cnt]); - src += 16; - dst += 16; - } - - *diff = diff0[0] + diff0[1]; - - return sse; -} - -static uint32_t sub_pixel_sse_diff_64width_h_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter, int32_t height, int32_t *diff) { - uint32_t loop_cnt, sse = 0; - int32_t diff0[4]; - - for (loop_cnt = 0; loop_cnt < 4; ++loop_cnt) { - sse += sub_pixel_sse_diff_16width_h_msa(src, src_stride, dst, dst_stride, - filter, height, &diff0[loop_cnt]); - src += 16; - dst += 16; - } - - *diff = diff0[0] + diff0[1] + diff0[2] + diff0[3]; - - return sse; -} - -static uint32_t sub_pixel_sse_diff_4width_v_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter, int32_t height, int32_t *diff) { - int16_t filtval; - uint32_t loop_cnt; - uint32_t ref0, ref1, ref2, ref3; - v16u8 src0, src1, src2, src3, src4, out; - v16u8 src10_r, src32_r, src21_r, src43_r; - v16u8 ref = { 0 }; - v16u8 src2110, src4332; - v16u8 filt0; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - v8u16 tmp0, tmp1; - - filtval = LH(filter); - filt0 = (v16u8)__msa_fill_h(filtval); - - src0 = LD_UB(src); - src += src_stride; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - LW4(dst, dst_stride, ref0, ref1, ref2, ref3); - dst += (4 * dst_stride); - - INSERT_W4_UB(ref0, ref1, ref2, ref3, ref); - ILVR_B4_UB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, - src32_r, src43_r); - ILVR_D2_UB(src21_r, src10_r, src43_r, src32_r, src2110, src4332); - DOTP_UB2_UH(src2110, src4332, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - out = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - CALC_MSE_AVG_B(out, ref, var, avg); - src0 = src4; - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sub_pixel_sse_diff_8width_v_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter, int32_t height, int32_t *diff) { - int16_t filtval; - uint32_t loop_cnt; - v16u8 src0, src1, src2, src3, src4; - v16u8 ref0, ref1, ref2, ref3; - v8u16 vec0, vec1, vec2, vec3; - v8u16 tmp0, tmp1, tmp2, tmp3; - v16u8 filt0; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - filtval = LH(filter); - filt0 = (v16u8)__msa_fill_h(filtval); - - src0 = LD_UB(src); - src += src_stride; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - LD_UB4(dst, dst_stride, ref0, ref1, ref2, ref3); - dst += (4 * dst_stride); - - PCKEV_D2_UB(ref1, ref0, ref3, ref2, ref0, ref1); - ILVR_B4_UH(src1, src0, src2, src1, src3, src2, src4, src3, vec0, vec1, vec2, - vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, tmp0, tmp1, - tmp2, tmp3); - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, FILTER_BITS); - PCKEV_B2_UB(tmp1, tmp0, tmp3, tmp2, src0, src1); - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - src0 = src4; - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sub_pixel_sse_diff_16width_v_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter, int32_t height, int32_t *diff) { - int16_t filtval; - uint32_t loop_cnt; - v16u8 ref0, ref1, ref2, ref3; - v16u8 src0, src1, src2, src3, src4; - v16u8 out0, out1, out2, out3; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8u16 tmp0, tmp1, tmp2, tmp3; - v16u8 filt0; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - filtval = LH(filter); - filt0 = (v16u8)__msa_fill_h(filtval); - - src0 = LD_UB(src); - src += src_stride; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - LD_UB4(dst, dst_stride, ref0, ref1, ref2, ref3); - dst += (4 * dst_stride); - - ILVR_B2_UB(src1, src0, src2, src1, vec0, vec2); - ILVL_B2_UB(src1, src0, src2, src1, vec1, vec3); - DOTP_UB2_UH(vec0, vec1, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - out0 = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - - ILVR_B2_UB(src3, src2, src4, src3, vec4, vec6); - ILVL_B2_UB(src3, src2, src4, src3, vec5, vec7); - DOTP_UB2_UH(vec2, vec3, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - out1 = (v16u8)__msa_pckev_b((v16i8)tmp3, (v16i8)tmp2); - - DOTP_UB2_UH(vec4, vec5, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - out2 = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - DOTP_UB2_UH(vec6, vec7, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - out3 = (v16u8)__msa_pckev_b((v16i8)tmp3, (v16i8)tmp2); - - src0 = src4; - - CALC_MSE_AVG_B(out0, ref0, var, avg); - CALC_MSE_AVG_B(out1, ref1, var, avg); - CALC_MSE_AVG_B(out2, ref2, var, avg); - CALC_MSE_AVG_B(out3, ref3, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sub_pixel_sse_diff_32width_v_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter, int32_t height, int32_t *diff) { - uint32_t loop_cnt, sse = 0; - int32_t diff0[2]; - - for (loop_cnt = 0; loop_cnt < 2; ++loop_cnt) { - sse += sub_pixel_sse_diff_16width_v_msa(src, src_stride, dst, dst_stride, - filter, height, &diff0[loop_cnt]); - src += 16; - dst += 16; - } - - *diff = diff0[0] + diff0[1]; - - return sse; -} - -static uint32_t sub_pixel_sse_diff_64width_v_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter, int32_t height, int32_t *diff) { - uint32_t loop_cnt, sse = 0; - int32_t diff0[4]; - - for (loop_cnt = 0; loop_cnt < 4; ++loop_cnt) { - sse += sub_pixel_sse_diff_16width_v_msa(src, src_stride, dst, dst_stride, - filter, height, &diff0[loop_cnt]); - src += 16; - dst += 16; - } - - *diff = diff0[0] + diff0[1] + diff0[2] + diff0[3]; - - return sse; -} - -static uint32_t sub_pixel_sse_diff_4width_hv_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter_horiz, const uint8_t *filter_vert, - int32_t height, int32_t *diff) { - int16_t filtval; - uint32_t loop_cnt; - uint32_t ref0, ref1, ref2, ref3; - v16u8 src0, src1, src2, src3, src4; - v16u8 out, ref = { 0 }; - v16u8 filt_vt, filt_hz, vec0, vec1; - v16u8 mask = { 0, 1, 1, 2, 2, 3, 3, 4, 16, 17, 17, 18, 18, 19, 19, 20 }; - v8u16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4; - v8u16 tmp0, tmp1; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - filtval = LH(filter_horiz); - filt_hz = (v16u8)__msa_fill_h(filtval); - filtval = LH(filter_vert); - filt_vt = (v16u8)__msa_fill_h(filtval); - - src0 = LD_UB(src); - src += src_stride; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - LW4(dst, dst_stride, ref0, ref1, ref2, ref3); - dst += (4 * dst_stride); - INSERT_W4_UB(ref0, ref1, ref2, ref3, ref); - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src1, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src2, src3, mask, filt_hz, FILTER_BITS); - hz_out4 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS); - hz_out1 = (v8u16)__msa_sldi_b((v16i8)hz_out2, (v16i8)hz_out0, 8); - hz_out3 = (v8u16)__msa_pckod_d((v2i64)hz_out4, (v2i64)hz_out2); - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - out = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - CALC_MSE_AVG_B(out, ref, var, avg); - src0 = src4; - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sub_pixel_sse_diff_8width_hv_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter_horiz, const uint8_t *filter_vert, - int32_t height, int32_t *diff) { - int16_t filtval; - uint32_t loop_cnt; - v16u8 ref0, ref1, ref2, ref3; - v16u8 src0, src1, src2, src3, src4; - v16u8 out0, out1; - v16u8 mask = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 }; - v8u16 hz_out0, hz_out1; - v8u16 tmp0, tmp1, tmp2, tmp3; - v16u8 filt_vt, filt_hz, vec0; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - filtval = LH(filter_horiz); - filt_hz = (v16u8)__msa_fill_h(filtval); - filtval = LH(filter_vert); - filt_vt = (v16u8)__msa_fill_h(filtval); - - src0 = LD_UB(src); - src += src_stride; - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - LD_UB4(dst, dst_stride, ref0, ref1, ref2, ref3); - dst += (4 * dst_stride); - - PCKEV_D2_UB(ref1, ref0, ref3, ref2, ref0, ref1); - hz_out1 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp0 = __msa_dotp_u_h(vec0, filt_vt); - hz_out0 = HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, FILTER_BITS); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp1 = __msa_dotp_u_h(vec0, filt_vt); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - hz_out1 = HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, FILTER_BITS); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp2 = __msa_dotp_u_h(vec0, filt_vt); - hz_out0 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp3 = __msa_dotp_u_h(vec0, filt_vt); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_B2_UB(tmp1, tmp0, tmp3, tmp2, out0, out1); - CALC_MSE_AVG_B(out0, ref0, var, avg); - CALC_MSE_AVG_B(out1, ref1, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sub_pixel_sse_diff_16width_hv_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter_horiz, const uint8_t *filter_vert, - int32_t height, int32_t *diff) { - int16_t filtval; - uint32_t loop_cnt; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v16u8 ref0, ref1, ref2, ref3; - v16u8 filt_hz, filt_vt, vec0, vec1; - v16u8 mask = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 }; - v8u16 hz_out0, hz_out1, hz_out2, hz_out3; - v8u16 tmp0, tmp1; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - filtval = LH(filter_horiz); - filt_hz = (v16u8)__msa_fill_h(filtval); - filtval = LH(filter_vert); - filt_vt = (v16u8)__msa_fill_h(filtval); - - LD_UB2(src, 8, src0, src1); - src += src_stride; - - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_UB4(src, src_stride, src0, src2, src4, src6); - LD_UB4(src + 8, src_stride, src1, src3, src5, src7); - src += (4 * src_stride); - LD_UB4(dst, dst_stride, ref0, ref1, ref2, ref3); - dst += (4 * dst_stride); - - hz_out1 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS); - hz_out3 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS); - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - src0 = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - - hz_out0 = HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, FILTER_BITS); - ILVEV_B2_UB(hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - src1 = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - - hz_out1 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS); - hz_out3 = HORIZ_2TAP_FILT_UH(src5, src5, mask, filt_hz, FILTER_BITS); - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - src2 = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - - hz_out0 = HORIZ_2TAP_FILT_UH(src6, src6, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src7, src7, mask, filt_hz, FILTER_BITS); - ILVEV_B2_UB(hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - src3 = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - CALC_MSE_AVG_B(src2, ref2, var, avg); - CALC_MSE_AVG_B(src3, ref3, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sub_pixel_sse_diff_32width_hv_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter_horiz, const uint8_t *filter_vert, - int32_t height, int32_t *diff) { - uint32_t loop_cnt, sse = 0; - int32_t diff0[2]; - - for (loop_cnt = 0; loop_cnt < 2; ++loop_cnt) { - sse += sub_pixel_sse_diff_16width_hv_msa(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height, - &diff0[loop_cnt]); - src += 16; - dst += 16; - } - - *diff = diff0[0] + diff0[1]; - - return sse; -} - -static uint32_t sub_pixel_sse_diff_64width_hv_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *filter_horiz, const uint8_t *filter_vert, - int32_t height, int32_t *diff) { - uint32_t loop_cnt, sse = 0; - int32_t diff0[4]; - - for (loop_cnt = 0; loop_cnt < 4; ++loop_cnt) { - sse += sub_pixel_sse_diff_16width_hv_msa(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height, - &diff0[loop_cnt]); - src += 16; - dst += 16; - } - - *diff = diff0[0] + diff0[1] + diff0[2] + diff0[3]; - - return sse; -} - -static uint32_t sub_pixel_avg_sse_diff_4width_h_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter, - int32_t height, int32_t *diff) { - int16_t filtval; - uint32_t loop_cnt; - uint32_t ref0, ref1, ref2, ref3; - v16u8 out, pred, filt0, ref = { 0 }; - v16i8 src0, src1, src2, src3; - v16i8 mask = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 }; - v8u16 vec0, vec1, vec2, vec3; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - filtval = LH(filter); - filt0 = (v16u8)__msa_fill_h(filtval); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - pred = LD_UB(sec_pred); - sec_pred += 16; - LW4(dst, dst_stride, ref0, ref1, ref2, ref3); - dst += (4 * dst_stride); - - INSERT_W4_UB(ref0, ref1, ref2, ref3, ref); - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, FILTER_BITS); - PCKEV_B4_SB(vec0, vec0, vec1, vec1, vec2, vec2, vec3, vec3, src0, src1, - src2, src3); - ILVEV_W2_SB(src0, src1, src2, src3, src0, src2); - out = (v16u8)__msa_ilvev_d((v2i64)src2, (v2i64)src0); - out = __msa_aver_u_b(out, pred); - CALC_MSE_AVG_B(out, ref, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sub_pixel_avg_sse_diff_8width_h_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter, - int32_t height, int32_t *diff) { - int16_t filtval; - uint32_t loop_cnt; - v16u8 out, pred, filt0; - v16u8 ref0, ref1, ref2, ref3; - v16i8 src0, src1, src2, src3; - v16i8 mask = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 }; - v8u16 vec0, vec1, vec2, vec3; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - filtval = LH(filter); - filt0 = (v16u8)__msa_fill_h(filtval); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - LD_UB4(dst, dst_stride, ref0, ref1, ref2, ref3); - dst += (4 * dst_stride); - - PCKEV_D2_UB(ref1, ref0, ref3, ref2, ref0, ref1); - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, FILTER_BITS); - PCKEV_B4_SB(vec0, vec0, vec1, vec1, vec2, vec2, vec3, vec3, src0, src1, - src2, src3); - out = (v16u8)__msa_ilvev_d((v2i64)src1, (v2i64)src0); - - pred = LD_UB(sec_pred); - sec_pred += 16; - out = __msa_aver_u_b(out, pred); - CALC_MSE_AVG_B(out, ref0, var, avg); - out = (v16u8)__msa_ilvev_d((v2i64)src3, (v2i64)src2); - pred = LD_UB(sec_pred); - sec_pred += 16; - out = __msa_aver_u_b(out, pred); - CALC_MSE_AVG_B(out, ref1, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t subpel_avg_ssediff_16w_h_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter, - int32_t height, int32_t *diff, int32_t width) { - int16_t filtval; - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7; - v16i8 mask = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 }; - v16u8 dst0, dst1, dst2, dst3; - v16u8 tmp0, tmp1, tmp2, tmp3; - v16u8 pred0, pred1, pred2, pred3, filt0; - v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8u16 out0, out1, out2, out3, out4, out5, out6, out7; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - filtval = LH(filter); - filt0 = (v16u8)__msa_fill_h(filtval); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src2, src4, src6); - LD_SB4(src + 8, src_stride, src1, src3, src5, src7); - src += (4 * src_stride); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - dst += (4 * dst_stride); - LD_UB4(sec_pred, width, pred0, pred1, pred2, pred3); - sec_pred += (4 * width); - - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - VSHF_B2_UH(src4, src4, src5, src5, mask, mask, vec4, vec5); - VSHF_B2_UH(src6, src6, src7, src7, mask, mask, vec6, vec7); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, out0, out1, - out2, out3); - DOTP_UB4_UH(vec4, vec5, vec6, vec7, filt0, filt0, filt0, filt0, out4, out5, - out6, out7); - SRARI_H4_UH(out0, out1, out2, out3, FILTER_BITS); - SRARI_H4_UH(out4, out5, out6, out7, FILTER_BITS); - PCKEV_B4_UB(out1, out0, out3, out2, out5, out4, out7, out6, tmp0, tmp1, - tmp2, tmp3); - AVER_UB4_UB(tmp0, pred0, tmp1, pred1, tmp2, pred2, tmp3, pred3, tmp0, tmp1, - tmp2, tmp3); - - CALC_MSE_AVG_B(tmp0, dst0, var, avg); - CALC_MSE_AVG_B(tmp1, dst1, var, avg); - CALC_MSE_AVG_B(tmp2, dst2, var, avg); - CALC_MSE_AVG_B(tmp3, dst3, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sub_pixel_avg_sse_diff_16width_h_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter, - int32_t height, int32_t *diff) { - return subpel_avg_ssediff_16w_h_msa(src, src_stride, dst, dst_stride, - sec_pred, filter, height, diff, 16); -} - -static uint32_t sub_pixel_avg_sse_diff_32width_h_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter, - int32_t height, int32_t *diff) { - uint32_t loop_cnt, sse = 0; - int32_t diff0[2]; - - for (loop_cnt = 0; loop_cnt < 2; ++loop_cnt) { - sse += - subpel_avg_ssediff_16w_h_msa(src, src_stride, dst, dst_stride, sec_pred, - filter, height, &diff0[loop_cnt], 32); - src += 16; - dst += 16; - sec_pred += 16; - } - - *diff = diff0[0] + diff0[1]; - - return sse; -} - -static uint32_t sub_pixel_avg_sse_diff_64width_h_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter, - int32_t height, int32_t *diff) { - uint32_t loop_cnt, sse = 0; - int32_t diff0[4]; - - for (loop_cnt = 0; loop_cnt < 4; ++loop_cnt) { - sse += - subpel_avg_ssediff_16w_h_msa(src, src_stride, dst, dst_stride, sec_pred, - filter, height, &diff0[loop_cnt], 64); - src += 16; - dst += 16; - sec_pred += 16; - } - - *diff = diff0[0] + diff0[1] + diff0[2] + diff0[3]; - - return sse; -} - -static uint32_t sub_pixel_avg_sse_diff_4width_v_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter, - int32_t height, int32_t *diff) { - int16_t filtval; - uint32_t loop_cnt; - uint32_t ref0, ref1, ref2, ref3; - v16u8 src0, src1, src2, src3, src4; - v16u8 src10_r, src32_r, src21_r, src43_r; - v16u8 out, pred, ref = { 0 }; - v16u8 src2110, src4332, filt0; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - v8u16 tmp0, tmp1; - - filtval = LH(filter); - filt0 = (v16u8)__msa_fill_h(filtval); - - src0 = LD_UB(src); - src += src_stride; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - pred = LD_UB(sec_pred); - sec_pred += 16; - LW4(dst, dst_stride, ref0, ref1, ref2, ref3); - dst += (4 * dst_stride); - - INSERT_W4_UB(ref0, ref1, ref2, ref3, ref); - ILVR_B4_UB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, - src32_r, src43_r); - ILVR_D2_UB(src21_r, src10_r, src43_r, src32_r, src2110, src4332); - DOTP_UB2_UH(src2110, src4332, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - - out = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - out = __msa_aver_u_b(out, pred); - CALC_MSE_AVG_B(out, ref, var, avg); - src0 = src4; - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sub_pixel_avg_sse_diff_8width_v_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter, - int32_t height, int32_t *diff) { - int16_t filtval; - uint32_t loop_cnt; - v16u8 src0, src1, src2, src3, src4; - v16u8 ref0, ref1, ref2, ref3; - v16u8 pred0, pred1, filt0; - v8u16 vec0, vec1, vec2, vec3; - v8u16 tmp0, tmp1, tmp2, tmp3; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - filtval = LH(filter); - filt0 = (v16u8)__msa_fill_h(filtval); - - src0 = LD_UB(src); - src += src_stride; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - LD_UB2(sec_pred, 16, pred0, pred1); - sec_pred += 32; - LD_UB4(dst, dst_stride, ref0, ref1, ref2, ref3); - dst += (4 * dst_stride); - PCKEV_D2_UB(ref1, ref0, ref3, ref2, ref0, ref1); - ILVR_B4_UH(src1, src0, src2, src1, src3, src2, src4, src3, vec0, vec1, vec2, - vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, tmp0, tmp1, - tmp2, tmp3); - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, FILTER_BITS); - PCKEV_B2_UB(tmp1, tmp0, tmp3, tmp2, src0, src1); - AVER_UB2_UB(src0, pred0, src1, pred1, src0, src1); - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - - src0 = src4; - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t subpel_avg_ssediff_16w_v_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter, - int32_t height, int32_t *diff, int32_t width) { - int16_t filtval; - uint32_t loop_cnt; - v16u8 ref0, ref1, ref2, ref3; - v16u8 pred0, pred1, pred2, pred3; - v16u8 src0, src1, src2, src3, src4; - v16u8 out0, out1, out2, out3, filt0; - v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8u16 tmp0, tmp1, tmp2, tmp3; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - filtval = LH(filter); - filt0 = (v16u8)__msa_fill_h(filtval); - - src0 = LD_UB(src); - src += src_stride; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - LD_UB4(sec_pred, width, pred0, pred1, pred2, pred3); - sec_pred += (4 * width); - - ILVR_B2_UH(src1, src0, src2, src1, vec0, vec2); - ILVL_B2_UH(src1, src0, src2, src1, vec1, vec3); - DOTP_UB2_UH(vec0, vec1, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - out0 = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - - ILVR_B2_UH(src3, src2, src4, src3, vec4, vec6); - ILVL_B2_UH(src3, src2, src4, src3, vec5, vec7); - DOTP_UB2_UH(vec2, vec3, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - out1 = (v16u8)__msa_pckev_b((v16i8)tmp3, (v16i8)tmp2); - - DOTP_UB2_UH(vec4, vec5, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - out2 = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - - DOTP_UB2_UH(vec6, vec7, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - out3 = (v16u8)__msa_pckev_b((v16i8)tmp3, (v16i8)tmp2); - - src0 = src4; - LD_UB4(dst, dst_stride, ref0, ref1, ref2, ref3); - dst += (4 * dst_stride); - - AVER_UB4_UB(out0, pred0, out1, pred1, out2, pred2, out3, pred3, out0, out1, - out2, out3); - - CALC_MSE_AVG_B(out0, ref0, var, avg); - CALC_MSE_AVG_B(out1, ref1, var, avg); - CALC_MSE_AVG_B(out2, ref2, var, avg); - CALC_MSE_AVG_B(out3, ref3, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sub_pixel_avg_sse_diff_16width_v_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter, - int32_t height, int32_t *diff) { - return subpel_avg_ssediff_16w_v_msa(src, src_stride, dst, dst_stride, - sec_pred, filter, height, diff, 16); -} - -static uint32_t sub_pixel_avg_sse_diff_32width_v_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter, - int32_t height, int32_t *diff) { - uint32_t loop_cnt, sse = 0; - int32_t diff0[2]; - - for (loop_cnt = 0; loop_cnt < 2; ++loop_cnt) { - sse += - subpel_avg_ssediff_16w_v_msa(src, src_stride, dst, dst_stride, sec_pred, - filter, height, &diff0[loop_cnt], 32); - src += 16; - dst += 16; - sec_pred += 16; - } - - *diff = diff0[0] + diff0[1]; - - return sse; -} - -static uint32_t sub_pixel_avg_sse_diff_64width_v_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter, - int32_t height, int32_t *diff) { - uint32_t loop_cnt, sse = 0; - int32_t diff0[4]; - - for (loop_cnt = 0; loop_cnt < 4; ++loop_cnt) { - sse += - subpel_avg_ssediff_16w_v_msa(src, src_stride, dst, dst_stride, sec_pred, - filter, height, &diff0[loop_cnt], 64); - src += 16; - dst += 16; - sec_pred += 16; - } - - *diff = diff0[0] + diff0[1] + diff0[2] + diff0[3]; - - return sse; -} - -static uint32_t sub_pixel_avg_sse_diff_4width_hv_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter_horiz, - const uint8_t *filter_vert, int32_t height, int32_t *diff) { - int16_t filtval; - uint32_t loop_cnt; - uint32_t ref0, ref1, ref2, ref3; - v16u8 src0, src1, src2, src3, src4; - v16u8 mask = { 0, 1, 1, 2, 2, 3, 3, 4, 16, 17, 17, 18, 18, 19, 19, 20 }; - v16u8 filt_hz, filt_vt, vec0, vec1; - v16u8 out, pred, ref = { 0 }; - v8u16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, tmp0, tmp1; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - filtval = LH(filter_horiz); - filt_hz = (v16u8)__msa_fill_h(filtval); - filtval = LH(filter_vert); - filt_vt = (v16u8)__msa_fill_h(filtval); - - src0 = LD_UB(src); - src += src_stride; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - pred = LD_UB(sec_pred); - sec_pred += 16; - LW4(dst, dst_stride, ref0, ref1, ref2, ref3); - dst += (4 * dst_stride); - INSERT_W4_UB(ref0, ref1, ref2, ref3, ref); - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src1, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src2, src3, mask, filt_hz, FILTER_BITS); - hz_out4 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS); - hz_out1 = (v8u16)__msa_sldi_b((v16i8)hz_out2, (v16i8)hz_out0, 8); - hz_out3 = (v8u16)__msa_pckod_d((v2i64)hz_out4, (v2i64)hz_out2); - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - out = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - out = __msa_aver_u_b(out, pred); - CALC_MSE_AVG_B(out, ref, var, avg); - src0 = src4; - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sub_pixel_avg_sse_diff_8width_hv_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter_horiz, - const uint8_t *filter_vert, int32_t height, int32_t *diff) { - int16_t filtval; - uint32_t loop_cnt; - v16u8 ref0, ref1, ref2, ref3; - v16u8 src0, src1, src2, src3, src4; - v16u8 pred0, pred1, out0, out1; - v16u8 filt_hz, filt_vt, vec0; - v16u8 mask = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 }; - v8u16 hz_out0, hz_out1, tmp0, tmp1, tmp2, tmp3; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - filtval = LH(filter_horiz); - filt_hz = (v16u8)__msa_fill_h(filtval); - filtval = LH(filter_vert); - filt_vt = (v16u8)__msa_fill_h(filtval); - - src0 = LD_UB(src); - src += src_stride; - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - LD_UB2(sec_pred, 16, pred0, pred1); - sec_pred += 32; - LD_UB4(dst, dst_stride, ref0, ref1, ref2, ref3); - dst += (4 * dst_stride); - - PCKEV_D2_UB(ref1, ref0, ref3, ref2, ref0, ref1); - hz_out1 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS); - - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp0 = __msa_dotp_u_h(vec0, filt_vt); - hz_out0 = HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, FILTER_BITS); - - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp1 = __msa_dotp_u_h(vec0, filt_vt); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - hz_out1 = HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, FILTER_BITS); - - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp2 = __msa_dotp_u_h(vec0, filt_vt); - hz_out0 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS); - - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp3 = __msa_dotp_u_h(vec0, filt_vt); - - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_B2_UB(tmp1, tmp0, tmp3, tmp2, out0, out1); - AVER_UB2_UB(out0, pred0, out1, pred1, out0, out1); - - CALC_MSE_AVG_B(out0, ref0, var, avg); - CALC_MSE_AVG_B(out1, ref1, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t subpel_avg_ssediff_16w_hv_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter_horiz, - const uint8_t *filter_vert, int32_t height, int32_t *diff, int32_t width) { - int16_t filtval; - uint32_t loop_cnt; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v16u8 ref0, ref1, ref2, ref3; - v16u8 pred0, pred1, pred2, pred3; - v16u8 out0, out1, out2, out3; - v16u8 filt_hz, filt_vt, vec0, vec1; - v16u8 mask = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 }; - v8u16 hz_out0, hz_out1, hz_out2, hz_out3, tmp0, tmp1; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - filtval = LH(filter_horiz); - filt_hz = (v16u8)__msa_fill_h(filtval); - filtval = LH(filter_vert); - filt_vt = (v16u8)__msa_fill_h(filtval); - - LD_UB2(src, 8, src0, src1); - src += src_stride; - - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_UB4(src, src_stride, src0, src2, src4, src6); - LD_UB4(src + 8, src_stride, src1, src3, src5, src7); - src += (4 * src_stride); - LD_UB4(sec_pred, width, pred0, pred1, pred2, pred3); - sec_pred += (4 * width); - - hz_out1 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS); - hz_out3 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS); - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - out0 = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - - hz_out0 = HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, FILTER_BITS); - ILVEV_B2_UB(hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - out1 = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - - hz_out1 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS); - hz_out3 = HORIZ_2TAP_FILT_UH(src5, src5, mask, filt_hz, FILTER_BITS); - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - out2 = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - - hz_out0 = HORIZ_2TAP_FILT_UH(src6, src6, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src7, src7, mask, filt_hz, FILTER_BITS); - ILVEV_B2_UB(hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - out3 = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - - LD_UB4(dst, dst_stride, ref0, ref1, ref2, ref3); - dst += (4 * dst_stride); - - AVER_UB4_UB(out0, pred0, out1, pred1, out2, pred2, out3, pred3, out0, out1, - out2, out3); - - CALC_MSE_AVG_B(out0, ref0, var, avg); - CALC_MSE_AVG_B(out1, ref1, var, avg); - CALC_MSE_AVG_B(out2, ref2, var, avg); - CALC_MSE_AVG_B(out3, ref3, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sub_pixel_avg_sse_diff_16width_hv_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter_horiz, - const uint8_t *filter_vert, int32_t height, int32_t *diff) { - return subpel_avg_ssediff_16w_hv_msa(src, src_stride, dst, dst_stride, - sec_pred, filter_horiz, filter_vert, - height, diff, 16); -} - -static uint32_t sub_pixel_avg_sse_diff_32width_hv_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter_horiz, - const uint8_t *filter_vert, int32_t height, int32_t *diff) { - uint32_t loop_cnt, sse = 0; - int32_t diff0[2]; - - for (loop_cnt = 0; loop_cnt < 2; ++loop_cnt) { - sse += subpel_avg_ssediff_16w_hv_msa(src, src_stride, dst, dst_stride, - sec_pred, filter_horiz, filter_vert, - height, &diff0[loop_cnt], 32); - src += 16; - dst += 16; - sec_pred += 16; - } - - *diff = diff0[0] + diff0[1]; - - return sse; -} - -static uint32_t sub_pixel_avg_sse_diff_64width_hv_msa( - const uint8_t *src, int32_t src_stride, const uint8_t *dst, - int32_t dst_stride, const uint8_t *sec_pred, const uint8_t *filter_horiz, - const uint8_t *filter_vert, int32_t height, int32_t *diff) { - uint32_t loop_cnt, sse = 0; - int32_t diff0[4]; - - for (loop_cnt = 0; loop_cnt < 4; ++loop_cnt) { - sse += subpel_avg_ssediff_16w_hv_msa(src, src_stride, dst, dst_stride, - sec_pred, filter_horiz, filter_vert, - height, &diff0[loop_cnt], 64); - src += 16; - dst += 16; - sec_pred += 16; - } - - *diff = diff0[0] + diff0[1] + diff0[2] + diff0[3]; - - return sse; -} - -#define VARIANCE_4Wx4H(sse, diff) VARIANCE_WxH(sse, diff, 4); -#define VARIANCE_4Wx8H(sse, diff) VARIANCE_WxH(sse, diff, 5); -#define VARIANCE_8Wx4H(sse, diff) VARIANCE_WxH(sse, diff, 5); -#define VARIANCE_8Wx8H(sse, diff) VARIANCE_WxH(sse, diff, 6); -#define VARIANCE_8Wx16H(sse, diff) VARIANCE_WxH(sse, diff, 7); -#define VARIANCE_16Wx8H(sse, diff) VARIANCE_WxH(sse, diff, 7); -#define VARIANCE_16Wx16H(sse, diff) VARIANCE_WxH(sse, diff, 8); - -#define VARIANCE_16Wx32H(sse, diff) VARIANCE_LARGE_WxH(sse, diff, 9); -#define VARIANCE_32Wx16H(sse, diff) VARIANCE_LARGE_WxH(sse, diff, 9); -#define VARIANCE_32Wx32H(sse, diff) VARIANCE_LARGE_WxH(sse, diff, 10); -#define VARIANCE_32Wx64H(sse, diff) VARIANCE_LARGE_WxH(sse, diff, 11); -#define VARIANCE_64Wx32H(sse, diff) VARIANCE_LARGE_WxH(sse, diff, 11); -#define VARIANCE_64Wx64H(sse, diff) VARIANCE_LARGE_WxH(sse, diff, 12); - -#define VPX_SUB_PIXEL_VARIANCE_WDXHT_MSA(wd, ht) \ - uint32_t vpx_sub_pixel_variance##wd##x##ht##_msa( \ - const uint8_t *src, int32_t src_stride, int32_t x_offset, \ - int32_t y_offset, const uint8_t *ref, int32_t ref_stride, \ - uint32_t *sse) { \ - int32_t diff; \ - uint32_t var; \ - const uint8_t *h_filter = bilinear_filters_msa[x_offset]; \ - const uint8_t *v_filter = bilinear_filters_msa[y_offset]; \ - \ - if (y_offset) { \ - if (x_offset) { \ - *sse = sub_pixel_sse_diff_##wd##width_hv_msa( \ - src, src_stride, ref, ref_stride, h_filter, v_filter, ht, &diff); \ - } else { \ - *sse = sub_pixel_sse_diff_##wd##width_v_msa( \ - src, src_stride, ref, ref_stride, v_filter, ht, &diff); \ - } \ - \ - var = VARIANCE_##wd##Wx##ht##H(*sse, diff); \ - } else { \ - if (x_offset) { \ - *sse = sub_pixel_sse_diff_##wd##width_h_msa( \ - src, src_stride, ref, ref_stride, h_filter, ht, &diff); \ - \ - var = VARIANCE_##wd##Wx##ht##H(*sse, diff); \ - } else { \ - var = vpx_variance##wd##x##ht##_msa(src, src_stride, ref, ref_stride, \ - sse); \ - } \ - } \ - \ - return var; \ - } - -VPX_SUB_PIXEL_VARIANCE_WDXHT_MSA(4, 4); -VPX_SUB_PIXEL_VARIANCE_WDXHT_MSA(4, 8); - -VPX_SUB_PIXEL_VARIANCE_WDXHT_MSA(8, 4); -VPX_SUB_PIXEL_VARIANCE_WDXHT_MSA(8, 8); -VPX_SUB_PIXEL_VARIANCE_WDXHT_MSA(8, 16); - -VPX_SUB_PIXEL_VARIANCE_WDXHT_MSA(16, 8); -VPX_SUB_PIXEL_VARIANCE_WDXHT_MSA(16, 16); -VPX_SUB_PIXEL_VARIANCE_WDXHT_MSA(16, 32); - -VPX_SUB_PIXEL_VARIANCE_WDXHT_MSA(32, 16); -VPX_SUB_PIXEL_VARIANCE_WDXHT_MSA(32, 32); -VPX_SUB_PIXEL_VARIANCE_WDXHT_MSA(32, 64); - -VPX_SUB_PIXEL_VARIANCE_WDXHT_MSA(64, 32); -VPX_SUB_PIXEL_VARIANCE_WDXHT_MSA(64, 64); - -#define VPX_SUB_PIXEL_AVG_VARIANCE_WDXHT_MSA(wd, ht) \ - uint32_t vpx_sub_pixel_avg_variance##wd##x##ht##_msa( \ - const uint8_t *src_ptr, int32_t src_stride, int32_t x_offset, \ - int32_t y_offset, const uint8_t *ref_ptr, int32_t ref_stride, \ - uint32_t *sse, const uint8_t *sec_pred) { \ - int32_t diff; \ - const uint8_t *h_filter = bilinear_filters_msa[x_offset]; \ - const uint8_t *v_filter = bilinear_filters_msa[y_offset]; \ - \ - if (y_offset) { \ - if (x_offset) { \ - *sse = sub_pixel_avg_sse_diff_##wd##width_hv_msa( \ - src_ptr, src_stride, ref_ptr, ref_stride, sec_pred, h_filter, \ - v_filter, ht, &diff); \ - } else { \ - *sse = sub_pixel_avg_sse_diff_##wd##width_v_msa( \ - src_ptr, src_stride, ref_ptr, ref_stride, sec_pred, v_filter, ht, \ - &diff); \ - } \ - } else { \ - if (x_offset) { \ - *sse = sub_pixel_avg_sse_diff_##wd##width_h_msa( \ - src_ptr, src_stride, ref_ptr, ref_stride, sec_pred, h_filter, ht, \ - &diff); \ - } else { \ - *sse = avg_sse_diff_##wd##width_msa(src_ptr, src_stride, ref_ptr, \ - ref_stride, sec_pred, ht, &diff); \ - } \ - } \ - \ - return VARIANCE_##wd##Wx##ht##H(*sse, diff); \ - } - -VPX_SUB_PIXEL_AVG_VARIANCE_WDXHT_MSA(4, 4); -VPX_SUB_PIXEL_AVG_VARIANCE_WDXHT_MSA(4, 8); - -VPX_SUB_PIXEL_AVG_VARIANCE_WDXHT_MSA(8, 4); -VPX_SUB_PIXEL_AVG_VARIANCE_WDXHT_MSA(8, 8); -VPX_SUB_PIXEL_AVG_VARIANCE_WDXHT_MSA(8, 16); - -VPX_SUB_PIXEL_AVG_VARIANCE_WDXHT_MSA(16, 8); -VPX_SUB_PIXEL_AVG_VARIANCE_WDXHT_MSA(16, 16); -VPX_SUB_PIXEL_AVG_VARIANCE_WDXHT_MSA(16, 32); - -VPX_SUB_PIXEL_AVG_VARIANCE_WDXHT_MSA(32, 16); -VPX_SUB_PIXEL_AVG_VARIANCE_WDXHT_MSA(32, 32); - -uint32_t vpx_sub_pixel_avg_variance32x64_msa(const uint8_t *src_ptr, - int32_t src_stride, - int32_t x_offset, int32_t y_offset, - const uint8_t *ref_ptr, - int32_t ref_stride, uint32_t *sse, - const uint8_t *sec_pred) { - int32_t diff; - const uint8_t *h_filter = bilinear_filters_msa[x_offset]; - const uint8_t *v_filter = bilinear_filters_msa[y_offset]; - - if (y_offset) { - if (x_offset) { - *sse = sub_pixel_avg_sse_diff_32width_hv_msa( - src_ptr, src_stride, ref_ptr, ref_stride, sec_pred, h_filter, - v_filter, 64, &diff); - } else { - *sse = sub_pixel_avg_sse_diff_32width_v_msa(src_ptr, src_stride, ref_ptr, - ref_stride, sec_pred, - v_filter, 64, &diff); - } - } else { - if (x_offset) { - *sse = sub_pixel_avg_sse_diff_32width_h_msa(src_ptr, src_stride, ref_ptr, - ref_stride, sec_pred, - h_filter, 64, &diff); - } else { - *sse = avg_sse_diff_32x64_msa(src_ptr, src_stride, ref_ptr, ref_stride, - sec_pred, &diff); - } - } - - return VARIANCE_32Wx64H(*sse, diff); -} - -#define VPX_SUB_PIXEL_AVG_VARIANCE64XHEIGHT_MSA(ht) \ - uint32_t vpx_sub_pixel_avg_variance64x##ht##_msa( \ - const uint8_t *src_ptr, int32_t src_stride, int32_t x_offset, \ - int32_t y_offset, const uint8_t *ref_ptr, int32_t ref_stride, \ - uint32_t *sse, const uint8_t *sec_pred) { \ - int32_t diff; \ - const uint8_t *h_filter = bilinear_filters_msa[x_offset]; \ - const uint8_t *v_filter = bilinear_filters_msa[y_offset]; \ - \ - if (y_offset) { \ - if (x_offset) { \ - *sse = sub_pixel_avg_sse_diff_64width_hv_msa( \ - src_ptr, src_stride, ref_ptr, ref_stride, sec_pred, h_filter, \ - v_filter, ht, &diff); \ - } else { \ - *sse = sub_pixel_avg_sse_diff_64width_v_msa( \ - src_ptr, src_stride, ref_ptr, ref_stride, sec_pred, v_filter, ht, \ - &diff); \ - } \ - } else { \ - if (x_offset) { \ - *sse = sub_pixel_avg_sse_diff_64width_h_msa( \ - src_ptr, src_stride, ref_ptr, ref_stride, sec_pred, h_filter, ht, \ - &diff); \ - } else { \ - *sse = avg_sse_diff_64x##ht##_msa(src_ptr, src_stride, ref_ptr, \ - ref_stride, sec_pred, &diff); \ - } \ - } \ - \ - return VARIANCE_64Wx##ht##H(*sse, diff); \ - } - -VPX_SUB_PIXEL_AVG_VARIANCE64XHEIGHT_MSA(32); -VPX_SUB_PIXEL_AVG_VARIANCE64XHEIGHT_MSA(64); diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/subtract_mmi.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/subtract_mmi.c deleted file mode 100644 index 8bd7e697..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/subtract_mmi.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/asmdefs_mmi.h" - -void vpx_subtract_block_mmi(int rows, int cols, int16_t *diff, - ptrdiff_t diff_stride, const uint8_t *src, - ptrdiff_t src_stride, const uint8_t *pred, - ptrdiff_t pred_stride) { - double ftmp[13]; - uint32_t tmp[1]; - - if (rows == cols) { - switch (rows) { - case 4: - __asm__ volatile( - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" -#if _MIPS_SIM == _ABIO32 - "ulw %[tmp0], 0x00(%[src]) \n\t" - "mtc1 %[tmp0], %[ftmp1] \n\t" - "ulw %[tmp0], 0x00(%[pred]) \n\t" - "mtc1 %[tmp0], %[ftmp2] \n\t" -#else - "gslwlc1 %[ftmp1], 0x03(%[src]) \n\t" - "gslwrc1 %[ftmp1], 0x00(%[src]) \n\t" - "gslwlc1 %[ftmp2], 0x03(%[pred]) \n\t" - "gslwrc1 %[ftmp2], 0x00(%[pred]) \n\t" -#endif - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[pred], %[pred], %[pred_stride]) - -#if _MIPS_SIM == _ABIO32 - "ulw %[tmp0], 0x00(%[src]) \n\t" - "mtc1 %[tmp0], %[ftmp3] \n\t" - "ulw %[tmp0], 0x00(%[pred]) \n\t" - "mtc1 %[tmp0], %[ftmp4] \n\t" -#else - "gslwlc1 %[ftmp3], 0x03(%[src]) \n\t" - "gslwrc1 %[ftmp3], 0x00(%[src]) \n\t" - "gslwlc1 %[ftmp4], 0x03(%[pred]) \n\t" - "gslwrc1 %[ftmp4], 0x00(%[pred]) \n\t" -#endif - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[pred], %[pred], %[pred_stride]) - -#if _MIPS_SIM == _ABIO32 - "ulw %[tmp0], 0x00(%[src]) \n\t" - "mtc1 %[tmp0], %[ftmp5] \n\t" - "ulw %[tmp0], 0x00(%[pred]) \n\t" - "mtc1 %[tmp0], %[ftmp6] \n\t" -#else - "gslwlc1 %[ftmp5], 0x03(%[src]) \n\t" - "gslwrc1 %[ftmp5], 0x00(%[src]) \n\t" - "gslwlc1 %[ftmp6], 0x03(%[pred]) \n\t" - "gslwrc1 %[ftmp6], 0x00(%[pred]) \n\t" -#endif - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[pred], %[pred], %[pred_stride]) - -#if _MIPS_SIM == _ABIO32 - "ulw %[tmp0], 0x00(%[src]) \n\t" - "mtc1 %[tmp0], %[ftmp7] \n\t" - "ulw %[tmp0], 0x00(%[pred]) \n\t" - "mtc1 %[tmp0], %[ftmp8] \n\t" -#else - "gslwlc1 %[ftmp7], 0x03(%[src]) \n\t" - "gslwrc1 %[ftmp7], 0x00(%[src]) \n\t" - "gslwlc1 %[ftmp8], 0x03(%[pred]) \n\t" - "gslwrc1 %[ftmp8], 0x00(%[pred]) \n\t" -#endif - "punpcklbh %[ftmp9], %[ftmp1], %[ftmp0] \n\t" - "punpcklbh %[ftmp10], %[ftmp2], %[ftmp0] \n\t" - "psubh %[ftmp11], %[ftmp9], %[ftmp10] \n\t" - "gssdlc1 %[ftmp11], 0x07(%[diff]) \n\t" - "gssdrc1 %[ftmp11], 0x00(%[diff]) \n\t" - MMI_ADDU(%[diff], %[diff], %[diff_stride]) - "punpcklbh %[ftmp9], %[ftmp3], %[ftmp0] \n\t" - "punpcklbh %[ftmp10], %[ftmp4], %[ftmp0] \n\t" - "psubh %[ftmp11], %[ftmp9], %[ftmp10] \n\t" - "gssdlc1 %[ftmp11], 0x07(%[diff]) \n\t" - "gssdrc1 %[ftmp11], 0x00(%[diff]) \n\t" - MMI_ADDU(%[diff], %[diff], %[diff_stride]) - "punpcklbh %[ftmp9], %[ftmp5], %[ftmp0] \n\t" - "punpcklbh %[ftmp10], %[ftmp6], %[ftmp0] \n\t" - "psubh %[ftmp11], %[ftmp9], %[ftmp10] \n\t" - "gssdlc1 %[ftmp11], 0x07(%[diff]) \n\t" - "gssdrc1 %[ftmp11], 0x00(%[diff]) \n\t" - MMI_ADDU(%[diff], %[diff], %[diff_stride]) - "punpcklbh %[ftmp9], %[ftmp7], %[ftmp0] \n\t" - "punpcklbh %[ftmp10], %[ftmp8], %[ftmp0] \n\t" - "psubh %[ftmp11], %[ftmp9], %[ftmp10] \n\t" - "gssdlc1 %[ftmp11], 0x07(%[diff]) \n\t" - "gssdrc1 %[ftmp11], 0x00(%[diff]) \n\t" - : [ftmp0] "=&f"(ftmp[0]), [ftmp1] "=&f"(ftmp[1]), - [ftmp2] "=&f"(ftmp[2]), [ftmp3] "=&f"(ftmp[3]), - [ftmp4] "=&f"(ftmp[4]), [ftmp5] "=&f"(ftmp[5]), - [ftmp6] "=&f"(ftmp[6]), [ftmp7] "=&f"(ftmp[7]), - [ftmp8] "=&f"(ftmp[8]), [ftmp9] "=&f"(ftmp[9]), - [ftmp10] "=&f"(ftmp[10]), [ftmp11] "=&f"(ftmp[11]), -#if _MIPS_SIM == _ABIO32 - [tmp0] "=&r"(tmp[0]), -#endif - [src] "+&r"(src), [pred] "+&r"(pred), [diff] "+&r"(diff) - : [src_stride] "r"((mips_reg)src_stride), - [pred_stride] "r"((mips_reg)pred_stride), - [diff_stride] "r"((mips_reg)(diff_stride * 2)) - : "memory"); - break; - case 8: - __asm__ volatile( - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "li %[tmp0], 0x02 \n\t" - "1: \n\t" - "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" - "gsldrc1 %[ftmp1], 0x00(%[src]) \n\t" - "gsldlc1 %[ftmp2], 0x07(%[pred]) \n\t" - "gsldrc1 %[ftmp2], 0x00(%[pred]) \n\t" - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[pred], %[pred], %[pred_stride]) - "gsldlc1 %[ftmp3], 0x07(%[src]) \n\t" - "gsldrc1 %[ftmp3], 0x00(%[src]) \n\t" - "gsldlc1 %[ftmp4], 0x07(%[pred]) \n\t" - "gsldrc1 %[ftmp4], 0x00(%[pred]) \n\t" - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[pred], %[pred], %[pred_stride]) - "gsldlc1 %[ftmp5], 0x07(%[src]) \n\t" - "gsldrc1 %[ftmp5], 0x00(%[src]) \n\t" - "gsldlc1 %[ftmp6], 0x07(%[pred]) \n\t" - "gsldrc1 %[ftmp6], 0x00(%[pred]) \n\t" - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[pred], %[pred], %[pred_stride]) - "gsldlc1 %[ftmp7], 0x07(%[src]) \n\t" - "gsldrc1 %[ftmp7], 0x00(%[src]) \n\t" - "gsldlc1 %[ftmp8], 0x07(%[pred]) \n\t" - "gsldrc1 %[ftmp8], 0x00(%[pred]) \n\t" - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[pred], %[pred], %[pred_stride]) - "punpcklbh %[ftmp9], %[ftmp1], %[ftmp0] \n\t" - "punpckhbh %[ftmp10], %[ftmp1], %[ftmp0] \n\t" - "punpcklbh %[ftmp11], %[ftmp2], %[ftmp0] \n\t" - "punpckhbh %[ftmp12], %[ftmp2], %[ftmp0] \n\t" - "psubsh %[ftmp9], %[ftmp9], %[ftmp11] \n\t" - "psubsh %[ftmp10], %[ftmp10], %[ftmp12] \n\t" - "gssdlc1 %[ftmp9], 0x07(%[diff]) \n\t" - "gssdrc1 %[ftmp9], 0x00(%[diff]) \n\t" - "gssdlc1 %[ftmp10], 0x0f(%[diff]) \n\t" - "gssdrc1 %[ftmp10], 0x08(%[diff]) \n\t" - MMI_ADDU(%[diff], %[diff], %[diff_stride]) - "punpcklbh %[ftmp9], %[ftmp3], %[ftmp0] \n\t" - "punpckhbh %[ftmp10], %[ftmp3], %[ftmp0] \n\t" - "punpcklbh %[ftmp11], %[ftmp4], %[ftmp0] \n\t" - "punpckhbh %[ftmp12], %[ftmp4], %[ftmp0] \n\t" - "psubsh %[ftmp9], %[ftmp9], %[ftmp11] \n\t" - "psubsh %[ftmp10], %[ftmp10], %[ftmp12] \n\t" - "gssdlc1 %[ftmp9], 0x07(%[diff]) \n\t" - "gssdrc1 %[ftmp9], 0x00(%[diff]) \n\t" - "gssdlc1 %[ftmp10], 0x0f(%[diff]) \n\t" - "gssdrc1 %[ftmp10], 0x08(%[diff]) \n\t" - MMI_ADDU(%[diff], %[diff], %[diff_stride]) - "punpcklbh %[ftmp9], %[ftmp5], %[ftmp0] \n\t" - "punpckhbh %[ftmp10], %[ftmp5], %[ftmp0] \n\t" - "punpcklbh %[ftmp11], %[ftmp6], %[ftmp0] \n\t" - "punpckhbh %[ftmp12], %[ftmp6], %[ftmp0] \n\t" - "psubsh %[ftmp9], %[ftmp9], %[ftmp11] \n\t" - "psubsh %[ftmp10], %[ftmp10], %[ftmp12] \n\t" - "gssdlc1 %[ftmp9], 0x07(%[diff]) \n\t" - "gssdrc1 %[ftmp9], 0x00(%[diff]) \n\t" - "gssdlc1 %[ftmp10], 0x0f(%[diff]) \n\t" - "gssdrc1 %[ftmp10], 0x08(%[diff]) \n\t" - MMI_ADDU(%[diff], %[diff], %[diff_stride]) - "punpcklbh %[ftmp9], %[ftmp7], %[ftmp0] \n\t" - "punpckhbh %[ftmp10], %[ftmp7], %[ftmp0] \n\t" - "punpcklbh %[ftmp11], %[ftmp8], %[ftmp0] \n\t" - "punpckhbh %[ftmp12], %[ftmp8], %[ftmp0] \n\t" - "psubsh %[ftmp9], %[ftmp9], %[ftmp11] \n\t" - "psubsh %[ftmp10], %[ftmp10], %[ftmp12] \n\t" - "gssdlc1 %[ftmp9], 0x07(%[diff]) \n\t" - "gssdrc1 %[ftmp9], 0x00(%[diff]) \n\t" - "gssdlc1 %[ftmp10], 0x0f(%[diff]) \n\t" - "gssdrc1 %[ftmp10], 0x08(%[diff]) \n\t" - MMI_ADDU(%[diff], %[diff], %[diff_stride]) - "addiu %[tmp0], %[tmp0], -0x01 \n\t" - "bnez %[tmp0], 1b \n\t" - : [ftmp0] "=&f"(ftmp[0]), [ftmp1] "=&f"(ftmp[1]), - [ftmp2] "=&f"(ftmp[2]), [ftmp3] "=&f"(ftmp[3]), - [ftmp4] "=&f"(ftmp[4]), [ftmp5] "=&f"(ftmp[5]), - [ftmp6] "=&f"(ftmp[6]), [ftmp7] "=&f"(ftmp[7]), - [ftmp8] "=&f"(ftmp[8]), [ftmp9] "=&f"(ftmp[9]), - [ftmp10] "=&f"(ftmp[10]), [ftmp11] "=&f"(ftmp[11]), - [ftmp12] "=&f"(ftmp[12]), [tmp0] "=&r"(tmp[0]), [src] "+&r"(src), - [pred] "+&r"(pred), [diff] "+&r"(diff) - : [pred_stride] "r"((mips_reg)pred_stride), - [src_stride] "r"((mips_reg)src_stride), - [diff_stride] "r"((mips_reg)(diff_stride * 2)) - : "memory"); - break; - case 16: - __asm__ volatile( - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "li %[tmp0], 0x08 \n\t" - "1: \n\t" - "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" - "gsldrc1 %[ftmp1], 0x00(%[src]) \n\t" - "gsldlc1 %[ftmp2], 0x07(%[pred]) \n\t" - "gsldrc1 %[ftmp2], 0x00(%[pred]) \n\t" - "gsldlc1 %[ftmp3], 0x0f(%[src]) \n\t" - "gsldrc1 %[ftmp3], 0x08(%[src]) \n\t" - "gsldlc1 %[ftmp4], 0x0f(%[pred]) \n\t" - "gsldrc1 %[ftmp4], 0x08(%[pred]) \n\t" - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[pred], %[pred], %[pred_stride]) - "gsldlc1 %[ftmp5], 0x07(%[src]) \n\t" - "gsldrc1 %[ftmp5], 0x00(%[src]) \n\t" - "gsldlc1 %[ftmp6], 0x07(%[pred]) \n\t" - "gsldrc1 %[ftmp6], 0x00(%[pred]) \n\t" - "gsldlc1 %[ftmp7], 0x0f(%[src]) \n\t" - "gsldrc1 %[ftmp7], 0x08(%[src]) \n\t" - "gsldlc1 %[ftmp8], 0x0f(%[pred]) \n\t" - "gsldrc1 %[ftmp8], 0x08(%[pred]) \n\t" - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[pred], %[pred], %[pred_stride]) - "punpcklbh %[ftmp9], %[ftmp1], %[ftmp0] \n\t" - "punpckhbh %[ftmp10], %[ftmp1], %[ftmp0] \n\t" - "punpcklbh %[ftmp11], %[ftmp2], %[ftmp0] \n\t" - "punpckhbh %[ftmp12], %[ftmp2], %[ftmp0] \n\t" - "psubsh %[ftmp9], %[ftmp9], %[ftmp11] \n\t" - "psubsh %[ftmp10], %[ftmp10], %[ftmp12] \n\t" - "gssdlc1 %[ftmp9], 0x07(%[diff]) \n\t" - "gssdrc1 %[ftmp9], 0x00(%[diff]) \n\t" - "gssdlc1 %[ftmp10], 0x0f(%[diff]) \n\t" - "gssdrc1 %[ftmp10], 0x08(%[diff]) \n\t" - "punpcklbh %[ftmp9], %[ftmp3], %[ftmp0] \n\t" - "punpckhbh %[ftmp10], %[ftmp3], %[ftmp0] \n\t" - "punpcklbh %[ftmp11], %[ftmp4], %[ftmp0] \n\t" - "punpckhbh %[ftmp12], %[ftmp4], %[ftmp0] \n\t" - "psubsh %[ftmp9], %[ftmp9], %[ftmp11] \n\t" - "psubsh %[ftmp10], %[ftmp10], %[ftmp12] \n\t" - "gssdlc1 %[ftmp9], 0x17(%[diff]) \n\t" - "gssdrc1 %[ftmp9], 0x10(%[diff]) \n\t" - "gssdlc1 %[ftmp10], 0x1f(%[diff]) \n\t" - "gssdrc1 %[ftmp10], 0x18(%[diff]) \n\t" - MMI_ADDU(%[diff], %[diff], %[diff_stride]) - "punpcklbh %[ftmp9], %[ftmp5], %[ftmp0] \n\t" - "punpckhbh %[ftmp10], %[ftmp5], %[ftmp0] \n\t" - "punpcklbh %[ftmp11], %[ftmp6], %[ftmp0] \n\t" - "punpckhbh %[ftmp12], %[ftmp6], %[ftmp0] \n\t" - "psubsh %[ftmp9], %[ftmp9], %[ftmp11] \n\t" - "psubsh %[ftmp10], %[ftmp10], %[ftmp12] \n\t" - "gssdlc1 %[ftmp9], 0x07(%[diff]) \n\t" - "gssdrc1 %[ftmp9], 0x00(%[diff]) \n\t" - "gssdlc1 %[ftmp10], 0x0f(%[diff]) \n\t" - "gssdrc1 %[ftmp10], 0x08(%[diff]) \n\t" - "punpcklbh %[ftmp9], %[ftmp7], %[ftmp0] \n\t" - "punpckhbh %[ftmp10], %[ftmp7], %[ftmp0] \n\t" - "punpcklbh %[ftmp11], %[ftmp8], %[ftmp0] \n\t" - "punpckhbh %[ftmp12], %[ftmp8], %[ftmp0] \n\t" - "psubsh %[ftmp9], %[ftmp9], %[ftmp11] \n\t" - "psubsh %[ftmp10], %[ftmp10], %[ftmp12] \n\t" - "gssdlc1 %[ftmp9], 0x17(%[diff]) \n\t" - "gssdrc1 %[ftmp9], 0x10(%[diff]) \n\t" - "gssdlc1 %[ftmp10], 0x1f(%[diff]) \n\t" - "gssdrc1 %[ftmp10], 0x18(%[diff]) \n\t" - MMI_ADDU(%[diff], %[diff], %[diff_stride]) - "addiu %[tmp0], %[tmp0], -0x01 \n\t" - "bnez %[tmp0], 1b \n\t" - : [ftmp0] "=&f"(ftmp[0]), [ftmp1] "=&f"(ftmp[1]), - [ftmp2] "=&f"(ftmp[2]), [ftmp3] "=&f"(ftmp[3]), - [ftmp4] "=&f"(ftmp[4]), [ftmp5] "=&f"(ftmp[5]), - [ftmp6] "=&f"(ftmp[6]), [ftmp7] "=&f"(ftmp[7]), - [ftmp8] "=&f"(ftmp[8]), [ftmp9] "=&f"(ftmp[9]), - [ftmp10] "=&f"(ftmp[10]), [ftmp11] "=&f"(ftmp[11]), - [ftmp12] "=&f"(ftmp[12]), [tmp0] "=&r"(tmp[0]), [src] "+&r"(src), - [pred] "+&r"(pred), [diff] "+&r"(diff) - : [pred_stride] "r"((mips_reg)pred_stride), - [src_stride] "r"((mips_reg)src_stride), - [diff_stride] "r"((mips_reg)(diff_stride * 2)) - : "memory"); - break; - case 32: - vpx_subtract_block_c(rows, cols, diff, diff_stride, src, src_stride, - pred, pred_stride); - break; - case 64: - vpx_subtract_block_c(rows, cols, diff, diff_stride, src, src_stride, - pred, pred_stride); - break; - default: - vpx_subtract_block_c(rows, cols, diff, diff_stride, src, src_stride, - pred, pred_stride); - break; - } - } else { - vpx_subtract_block_c(rows, cols, diff, diff_stride, src, src_stride, pred, - pred_stride); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/subtract_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/subtract_msa.c deleted file mode 100644 index 391a7ebf..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/subtract_msa.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/macros_msa.h" - -static void sub_blk_4x4_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *pred_ptr, int32_t pred_stride, - int16_t *diff_ptr, int32_t diff_stride) { - uint32_t src0, src1, src2, src3; - uint32_t pred0, pred1, pred2, pred3; - v16i8 src = { 0 }; - v16i8 pred = { 0 }; - v16u8 src_l0, src_l1; - v8i16 diff0, diff1; - - LW4(src_ptr, src_stride, src0, src1, src2, src3); - LW4(pred_ptr, pred_stride, pred0, pred1, pred2, pred3); - INSERT_W4_SB(src0, src1, src2, src3, src); - INSERT_W4_SB(pred0, pred1, pred2, pred3, pred); - ILVRL_B2_UB(src, pred, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST8x4_UB(diff0, diff1, diff_ptr, (2 * diff_stride)); -} - -static void sub_blk_8x8_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *pred_ptr, int32_t pred_stride, - int16_t *diff_ptr, int32_t diff_stride) { - uint32_t loop_cnt; - uint64_t src0, src1, pred0, pred1; - v16i8 src = { 0 }; - v16i8 pred = { 0 }; - v16u8 src_l0, src_l1; - v8i16 diff0, diff1; - - for (loop_cnt = 4; loop_cnt--;) { - LD2(src_ptr, src_stride, src0, src1); - src_ptr += (2 * src_stride); - LD2(pred_ptr, pred_stride, pred0, pred1); - pred_ptr += (2 * pred_stride); - - INSERT_D2_SB(src0, src1, src); - INSERT_D2_SB(pred0, pred1, pred); - ILVRL_B2_UB(src, pred, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff_ptr, diff_stride); - diff_ptr += (2 * diff_stride); - } -} - -static void sub_blk_16x16_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *pred, int32_t pred_stride, - int16_t *diff, int32_t diff_stride) { - int8_t count; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7; - v16i8 pred0, pred1, pred2, pred3, pred4, pred5, pred6, pred7; - v16u8 src_l0, src_l1; - v8i16 diff0, diff1; - - for (count = 2; count--;) { - LD_SB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - - LD_SB8(pred, pred_stride, pred0, pred1, pred2, pred3, pred4, pred5, pred6, - pred7); - pred += (8 * pred_stride); - - ILVRL_B2_UB(src0, pred0, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff, 8); - diff += diff_stride; - - ILVRL_B2_UB(src1, pred1, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff, 8); - diff += diff_stride; - - ILVRL_B2_UB(src2, pred2, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff, 8); - diff += diff_stride; - - ILVRL_B2_UB(src3, pred3, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff, 8); - diff += diff_stride; - - ILVRL_B2_UB(src4, pred4, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff, 8); - diff += diff_stride; - - ILVRL_B2_UB(src5, pred5, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff, 8); - diff += diff_stride; - - ILVRL_B2_UB(src6, pred6, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff, 8); - diff += diff_stride; - - ILVRL_B2_UB(src7, pred7, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff, 8); - diff += diff_stride; - } -} - -static void sub_blk_32x32_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *pred, int32_t pred_stride, - int16_t *diff, int32_t diff_stride) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7; - v16i8 pred0, pred1, pred2, pred3, pred4, pred5, pred6, pred7; - v16u8 src_l0, src_l1; - v8i16 diff0, diff1; - - for (loop_cnt = 8; loop_cnt--;) { - LD_SB2(src, 16, src0, src1); - src += src_stride; - LD_SB2(src, 16, src2, src3); - src += src_stride; - LD_SB2(src, 16, src4, src5); - src += src_stride; - LD_SB2(src, 16, src6, src7); - src += src_stride; - - LD_SB2(pred, 16, pred0, pred1); - pred += pred_stride; - LD_SB2(pred, 16, pred2, pred3); - pred += pred_stride; - LD_SB2(pred, 16, pred4, pred5); - pred += pred_stride; - LD_SB2(pred, 16, pred6, pred7); - pred += pred_stride; - - ILVRL_B2_UB(src0, pred0, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff, 8); - ILVRL_B2_UB(src1, pred1, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff + 16, 8); - diff += diff_stride; - - ILVRL_B2_UB(src2, pred2, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff, 8); - ILVRL_B2_UB(src3, pred3, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff + 16, 8); - diff += diff_stride; - - ILVRL_B2_UB(src4, pred4, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff, 8); - ILVRL_B2_UB(src5, pred5, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff + 16, 8); - diff += diff_stride; - - ILVRL_B2_UB(src6, pred6, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff, 8); - ILVRL_B2_UB(src7, pred7, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff + 16, 8); - diff += diff_stride; - } -} - -static void sub_blk_64x64_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *pred, int32_t pred_stride, - int16_t *diff, int32_t diff_stride) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7; - v16i8 pred0, pred1, pred2, pred3, pred4, pred5, pred6, pred7; - v16u8 src_l0, src_l1; - v8i16 diff0, diff1; - - for (loop_cnt = 32; loop_cnt--;) { - LD_SB4(src, 16, src0, src1, src2, src3); - src += src_stride; - LD_SB4(src, 16, src4, src5, src6, src7); - src += src_stride; - - LD_SB4(pred, 16, pred0, pred1, pred2, pred3); - pred += pred_stride; - LD_SB4(pred, 16, pred4, pred5, pred6, pred7); - pred += pred_stride; - - ILVRL_B2_UB(src0, pred0, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff, 8); - ILVRL_B2_UB(src1, pred1, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff + 16, 8); - ILVRL_B2_UB(src2, pred2, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff + 32, 8); - ILVRL_B2_UB(src3, pred3, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff + 48, 8); - diff += diff_stride; - - ILVRL_B2_UB(src4, pred4, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff, 8); - ILVRL_B2_UB(src5, pred5, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff + 16, 8); - ILVRL_B2_UB(src6, pred6, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff + 32, 8); - ILVRL_B2_UB(src7, pred7, src_l0, src_l1); - HSUB_UB2_SH(src_l0, src_l1, diff0, diff1); - ST_SH2(diff0, diff1, diff + 48, 8); - diff += diff_stride; - } -} - -void vpx_subtract_block_msa(int32_t rows, int32_t cols, int16_t *diff_ptr, - ptrdiff_t diff_stride, const uint8_t *src_ptr, - ptrdiff_t src_stride, const uint8_t *pred_ptr, - ptrdiff_t pred_stride) { - if (rows == cols) { - switch (rows) { - case 4: - sub_blk_4x4_msa(src_ptr, src_stride, pred_ptr, pred_stride, diff_ptr, - diff_stride); - break; - case 8: - sub_blk_8x8_msa(src_ptr, src_stride, pred_ptr, pred_stride, diff_ptr, - diff_stride); - break; - case 16: - sub_blk_16x16_msa(src_ptr, src_stride, pred_ptr, pred_stride, diff_ptr, - diff_stride); - break; - case 32: - sub_blk_32x32_msa(src_ptr, src_stride, pred_ptr, pred_stride, diff_ptr, - diff_stride); - break; - case 64: - sub_blk_64x64_msa(src_ptr, src_stride, pred_ptr, pred_stride, diff_ptr, - diff_stride); - break; - default: - vpx_subtract_block_c(rows, cols, diff_ptr, diff_stride, src_ptr, - src_stride, pred_ptr, pred_stride); - break; - } - } else { - vpx_subtract_block_c(rows, cols, diff_ptr, diff_stride, src_ptr, src_stride, - pred_ptr, pred_stride); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/sum_squares_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/sum_squares_msa.c deleted file mode 100644 index d4563dc4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/sum_squares_msa.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "./macros_msa.h" - -uint64_t vpx_sum_squares_2d_i16_msa(const int16_t *src, int src_stride, - int size) { - int row, col; - uint64_t ss_res = 0; - v4i32 mul0, mul1; - v2i64 res0 = { 0 }; - - if (4 == size) { - uint64_t src0, src1, src2, src3; - v8i16 diff0 = { 0 }; - v8i16 diff1 = { 0 }; - - LD4(src, src_stride, src0, src1, src2, src3); - INSERT_D2_SH(src0, src1, diff0); - INSERT_D2_SH(src2, src3, diff1); - DOTP_SH2_SW(diff0, diff1, diff0, diff1, mul0, mul1); - mul0 += mul1; - res0 = __msa_hadd_s_d(mul0, mul0); - res0 += __msa_splati_d(res0, 1); - ss_res = (uint64_t)__msa_copy_s_d(res0, 0); - } else if (8 == size) { - v8i16 src0, src1, src2, src3, src4, src5, src6, src7; - - LD_SH8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - DOTP_SH2_SW(src0, src1, src0, src1, mul0, mul1); - DPADD_SH2_SW(src2, src3, src2, src3, mul0, mul1); - DPADD_SH2_SW(src4, src5, src4, src5, mul0, mul1); - DPADD_SH2_SW(src6, src7, src6, src7, mul0, mul1); - mul0 += mul1; - res0 = __msa_hadd_s_d(mul0, mul0); - res0 += __msa_splati_d(res0, 1); - ss_res = (uint64_t)__msa_copy_s_d(res0, 0); - } else if (16 == size) { - v8i16 src0, src1, src2, src3, src4, src5, src6, src7; - - LD_SH8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - DOTP_SH2_SW(src0, src1, src0, src1, mul0, mul1); - DPADD_SH2_SW(src2, src3, src2, src3, mul0, mul1); - DPADD_SH2_SW(src4, src5, src4, src5, mul0, mul1); - DPADD_SH2_SW(src6, src7, src6, src7, mul0, mul1); - LD_SH8(src + 8, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - src += 8 * src_stride; - DPADD_SH2_SW(src0, src1, src0, src1, mul0, mul1); - DPADD_SH2_SW(src2, src3, src2, src3, mul0, mul1); - DPADD_SH2_SW(src4, src5, src4, src5, mul0, mul1); - DPADD_SH2_SW(src6, src7, src6, src7, mul0, mul1); - LD_SH8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - DPADD_SH2_SW(src0, src1, src0, src1, mul0, mul1); - DPADD_SH2_SW(src2, src3, src2, src3, mul0, mul1); - DPADD_SH2_SW(src4, src5, src4, src5, mul0, mul1); - DPADD_SH2_SW(src6, src7, src6, src7, mul0, mul1); - LD_SH8(src + 8, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - DPADD_SH2_SW(src0, src1, src0, src1, mul0, mul1); - DPADD_SH2_SW(src2, src3, src2, src3, mul0, mul1); - DPADD_SH2_SW(src4, src5, src4, src5, mul0, mul1); - DPADD_SH2_SW(src6, src7, src6, src7, mul0, mul1); - mul0 += mul1; - res0 += __msa_hadd_s_d(mul0, mul0); - - res0 += __msa_splati_d(res0, 1); - ss_res = (uint64_t)__msa_copy_s_d(res0, 0); - } else if (0 == (size % 16)) { - v8i16 src0, src1, src2, src3, src4, src5, src6, src7; - - for (row = 0; row < (size >> 4); row++) { - for (col = 0; col < size; col += 16) { - const int16_t *src_ptr = src + col; - LD_SH8(src_ptr, src_stride, src0, src1, src2, src3, src4, src5, src6, - src7); - DOTP_SH2_SW(src0, src1, src0, src1, mul0, mul1); - DPADD_SH2_SW(src2, src3, src2, src3, mul0, mul1); - DPADD_SH2_SW(src4, src5, src4, src5, mul0, mul1); - DPADD_SH2_SW(src6, src7, src6, src7, mul0, mul1); - LD_SH8(src_ptr + 8, src_stride, src0, src1, src2, src3, src4, src5, - src6, src7); - src_ptr += 8 * src_stride; - DPADD_SH2_SW(src0, src1, src0, src1, mul0, mul1); - DPADD_SH2_SW(src2, src3, src2, src3, mul0, mul1); - DPADD_SH2_SW(src4, src5, src4, src5, mul0, mul1); - DPADD_SH2_SW(src6, src7, src6, src7, mul0, mul1); - LD_SH8(src_ptr, src_stride, src0, src1, src2, src3, src4, src5, src6, - src7); - DPADD_SH2_SW(src0, src1, src0, src1, mul0, mul1); - DPADD_SH2_SW(src2, src3, src2, src3, mul0, mul1); - DPADD_SH2_SW(src4, src5, src4, src5, mul0, mul1); - DPADD_SH2_SW(src6, src7, src6, src7, mul0, mul1); - LD_SH8(src_ptr + 8, src_stride, src0, src1, src2, src3, src4, src5, - src6, src7); - DPADD_SH2_SW(src0, src1, src0, src1, mul0, mul1); - DPADD_SH2_SW(src2, src3, src2, src3, mul0, mul1); - DPADD_SH2_SW(src4, src5, src4, src5, mul0, mul1); - DPADD_SH2_SW(src6, src7, src6, src7, mul0, mul1); - mul0 += mul1; - res0 += __msa_hadd_s_d(mul0, mul0); - } - - src += 16 * src_stride; - } - - res0 += __msa_splati_d(res0, 1); - ss_res = (uint64_t)__msa_copy_s_d(res0, 0); - } else { - int16_t val; - - for (row = 0; row < size; row++) { - for (col = 0; col < size; col++) { - val = src[col]; - ss_res += val * val; - } - - src += src_stride; - } - } - - return ss_res; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/txfm_macros_msa.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/txfm_macros_msa.h deleted file mode 100644 index f27504a2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/txfm_macros_msa.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_MIPS_TXFM_MACROS_MSA_H_ -#define VPX_VPX_DSP_MIPS_TXFM_MACROS_MSA_H_ - -#include "vpx_dsp/mips/macros_msa.h" - -#define DOTP_CONST_PAIR(reg0, reg1, cnst0, cnst1, out0, out1) \ - { \ - v4i32 s0_m, s1_m, s2_m, s3_m, s4_m, s5_m; \ - v8i16 k0_m, k1_m, k2_m, zero = { 0 }; \ - \ - k0_m = __msa_fill_h(cnst0); \ - k1_m = __msa_fill_h(cnst1); \ - k2_m = __msa_ilvev_h((v8i16)k1_m, k0_m); \ - k0_m = __msa_ilvev_h((v8i16)zero, k0_m); \ - k1_m = __msa_ilvev_h(k1_m, (v8i16)zero); \ - \ - ILVRL_H2_SW(reg1, reg0, s5_m, s4_m); \ - ILVRL_H2_SW(reg0, reg1, s3_m, s2_m); \ - DOTP_SH2_SW(s5_m, s4_m, k0_m, k0_m, s1_m, s0_m); \ - s1_m = __msa_dpsub_s_w(s1_m, (v8i16)s5_m, k1_m); \ - s0_m = __msa_dpsub_s_w(s0_m, (v8i16)s4_m, k1_m); \ - SRARI_W2_SW(s1_m, s0_m, DCT_CONST_BITS); \ - out0 = __msa_pckev_h((v8i16)s0_m, (v8i16)s1_m); \ - \ - DOTP_SH2_SW(s3_m, s2_m, k2_m, k2_m, s1_m, s0_m); \ - SRARI_W2_SW(s1_m, s0_m, DCT_CONST_BITS); \ - out1 = __msa_pckev_h((v8i16)s0_m, (v8i16)s1_m); \ - } - -#define DOT_ADD_SUB_SRARI_PCK(in0, in1, in2, in3, in4, in5, in6, in7, dst0, \ - dst1, dst2, dst3) \ - { \ - v4i32 tp0_m, tp1_m, tp2_m, tp3_m, tp4_m; \ - v4i32 tp5_m, tp6_m, tp7_m, tp8_m, tp9_m; \ - \ - DOTP_SH4_SW(in0, in1, in0, in1, in4, in4, in5, in5, tp0_m, tp2_m, tp3_m, \ - tp4_m); \ - DOTP_SH4_SW(in2, in3, in2, in3, in6, in6, in7, in7, tp5_m, tp6_m, tp7_m, \ - tp8_m); \ - BUTTERFLY_4(tp0_m, tp3_m, tp7_m, tp5_m, tp1_m, tp9_m, tp7_m, tp5_m); \ - BUTTERFLY_4(tp2_m, tp4_m, tp8_m, tp6_m, tp3_m, tp0_m, tp4_m, tp2_m); \ - SRARI_W4_SW(tp1_m, tp9_m, tp7_m, tp5_m, DCT_CONST_BITS); \ - SRARI_W4_SW(tp3_m, tp0_m, tp4_m, tp2_m, DCT_CONST_BITS); \ - PCKEV_H4_SH(tp1_m, tp3_m, tp9_m, tp0_m, tp7_m, tp4_m, tp5_m, tp2_m, dst0, \ - dst1, dst2, dst3); \ - } - -#define DOT_SHIFT_RIGHT_PCK_H(in0, in1, in2) \ - ({ \ - v8i16 dst_m; \ - v4i32 tp0_m, tp1_m; \ - \ - DOTP_SH2_SW(in0, in1, in2, in2, tp1_m, tp0_m); \ - SRARI_W2_SW(tp1_m, tp0_m, DCT_CONST_BITS); \ - dst_m = __msa_pckev_h((v8i16)tp1_m, (v8i16)tp0_m); \ - \ - dst_m; \ - }) - -#define MADD_SHORT(m0, m1, c0, c1, res0, res1) \ - { \ - v4i32 madd0_m, madd1_m, madd2_m, madd3_m; \ - v8i16 madd_s0_m, madd_s1_m; \ - \ - ILVRL_H2_SH(m1, m0, madd_s0_m, madd_s1_m); \ - DOTP_SH4_SW(madd_s0_m, madd_s1_m, madd_s0_m, madd_s1_m, c0, c0, c1, c1, \ - madd0_m, madd1_m, madd2_m, madd3_m); \ - SRARI_W4_SW(madd0_m, madd1_m, madd2_m, madd3_m, DCT_CONST_BITS); \ - PCKEV_H2_SH(madd1_m, madd0_m, madd3_m, madd2_m, res0, res1); \ - } - -#define MADD_BF(inp0, inp1, inp2, inp3, cst0, cst1, cst2, cst3, out0, out1, \ - out2, out3) \ - { \ - v8i16 madd_s0_m, madd_s1_m, madd_s2_m, madd_s3_m; \ - v4i32 tmp0_m, tmp1_m, tmp2_m, tmp3_m, m4_m, m5_m; \ - \ - ILVRL_H2_SH(inp1, inp0, madd_s0_m, madd_s1_m); \ - ILVRL_H2_SH(inp3, inp2, madd_s2_m, madd_s3_m); \ - DOTP_SH4_SW(madd_s0_m, madd_s1_m, madd_s2_m, madd_s3_m, cst0, cst0, cst2, \ - cst2, tmp0_m, tmp1_m, tmp2_m, tmp3_m); \ - BUTTERFLY_4(tmp0_m, tmp1_m, tmp3_m, tmp2_m, m4_m, m5_m, tmp3_m, tmp2_m); \ - SRARI_W4_SW(m4_m, m5_m, tmp2_m, tmp3_m, DCT_CONST_BITS); \ - PCKEV_H2_SH(m5_m, m4_m, tmp3_m, tmp2_m, out0, out1); \ - DOTP_SH4_SW(madd_s0_m, madd_s1_m, madd_s2_m, madd_s3_m, cst1, cst1, cst3, \ - cst3, tmp0_m, tmp1_m, tmp2_m, tmp3_m); \ - BUTTERFLY_4(tmp0_m, tmp1_m, tmp3_m, tmp2_m, m4_m, m5_m, tmp3_m, tmp2_m); \ - SRARI_W4_SW(m4_m, m5_m, tmp2_m, tmp3_m, DCT_CONST_BITS); \ - PCKEV_H2_SH(m5_m, m4_m, tmp3_m, tmp2_m, out2, out3); \ - } -#endif // VPX_VPX_DSP_MIPS_TXFM_MACROS_MSA_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/variance_mmi.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/variance_mmi.c deleted file mode 100644 index c2adcfa0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/variance_mmi.c +++ /dev/null @@ -1,1357 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/variance.h" -#include "vpx_ports/mem.h" -#include "vpx/vpx_integer.h" -#include "vpx_ports/asmdefs_mmi.h" - -static const uint8_t bilinear_filters[8][2] = { - { 128, 0 }, { 112, 16 }, { 96, 32 }, { 80, 48 }, - { 64, 64 }, { 48, 80 }, { 32, 96 }, { 16, 112 }, -}; - -/* Use VARIANCE_SSE_SUM_8_FOR_W64 in vpx_variance64x64,vpx_variance64x32, - vpx_variance32x64. VARIANCE_SSE_SUM_8 will lead to sum overflow. */ -#define VARIANCE_SSE_SUM_8_FOR_W64 \ - /* sse */ \ - "pasubub %[ftmp3], %[ftmp1], %[ftmp2] \n\t" \ - "punpcklbh %[ftmp4], %[ftmp3], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp5], %[ftmp3], %[ftmp0] \n\t" \ - "pmaddhw %[ftmp6], %[ftmp4], %[ftmp4] \n\t" \ - "pmaddhw %[ftmp7], %[ftmp5], %[ftmp5] \n\t" \ - "paddw %[ftmp10], %[ftmp10], %[ftmp6] \n\t" \ - "paddw %[ftmp10], %[ftmp10], %[ftmp7] \n\t" \ - \ - /* sum */ \ - "punpcklbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp4], %[ftmp1], %[ftmp0] \n\t" \ - "punpcklbh %[ftmp5], %[ftmp2], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp6], %[ftmp2], %[ftmp0] \n\t" \ - "punpcklhw %[ftmp1], %[ftmp3], %[ftmp0] \n\t" \ - "punpckhhw %[ftmp2], %[ftmp3], %[ftmp0] \n\t" \ - "punpcklhw %[ftmp7], %[ftmp5], %[ftmp0] \n\t" \ - "punpckhhw %[ftmp8], %[ftmp5], %[ftmp0] \n\t" \ - "psubw %[ftmp3], %[ftmp1], %[ftmp7] \n\t" \ - "psubw %[ftmp5], %[ftmp2], %[ftmp8] \n\t" \ - "punpcklhw %[ftmp1], %[ftmp4], %[ftmp0] \n\t" \ - "punpckhhw %[ftmp2], %[ftmp4], %[ftmp0] \n\t" \ - "punpcklhw %[ftmp7], %[ftmp6], %[ftmp0] \n\t" \ - "punpckhhw %[ftmp8], %[ftmp6], %[ftmp0] \n\t" \ - "psubw %[ftmp4], %[ftmp1], %[ftmp7] \n\t" \ - "psubw %[ftmp6], %[ftmp2], %[ftmp8] \n\t" \ - "paddw %[ftmp9], %[ftmp9], %[ftmp3] \n\t" \ - "paddw %[ftmp9], %[ftmp9], %[ftmp4] \n\t" \ - "paddw %[ftmp9], %[ftmp9], %[ftmp5] \n\t" \ - "paddw %[ftmp9], %[ftmp9], %[ftmp6] \n\t" - -#define VARIANCE_SSE_SUM_4 \ - /* sse */ \ - "pasubub %[ftmp3], %[ftmp1], %[ftmp2] \n\t" \ - "punpcklbh %[ftmp4], %[ftmp3], %[ftmp0] \n\t" \ - "pmaddhw %[ftmp5], %[ftmp4], %[ftmp4] \n\t" \ - "paddw %[ftmp6], %[ftmp6], %[ftmp5] \n\t" \ - \ - /* sum */ \ - "punpcklbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \ - "punpcklbh %[ftmp4], %[ftmp2], %[ftmp0] \n\t" \ - "paddh %[ftmp7], %[ftmp7], %[ftmp3] \n\t" \ - "paddh %[ftmp8], %[ftmp8], %[ftmp4] \n\t" - -#define VARIANCE_SSE_SUM_8 \ - /* sse */ \ - "pasubub %[ftmp3], %[ftmp1], %[ftmp2] \n\t" \ - "punpcklbh %[ftmp4], %[ftmp3], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp5], %[ftmp3], %[ftmp0] \n\t" \ - "pmaddhw %[ftmp6], %[ftmp4], %[ftmp4] \n\t" \ - "pmaddhw %[ftmp7], %[ftmp5], %[ftmp5] \n\t" \ - "paddw %[ftmp8], %[ftmp8], %[ftmp6] \n\t" \ - "paddw %[ftmp8], %[ftmp8], %[ftmp7] \n\t" \ - \ - /* sum */ \ - "punpcklbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp4], %[ftmp1], %[ftmp0] \n\t" \ - "punpcklbh %[ftmp5], %[ftmp2], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp6], %[ftmp2], %[ftmp0] \n\t" \ - "paddh %[ftmp10], %[ftmp10], %[ftmp3] \n\t" \ - "paddh %[ftmp10], %[ftmp10], %[ftmp4] \n\t" \ - "paddh %[ftmp12], %[ftmp12], %[ftmp5] \n\t" \ - "paddh %[ftmp12], %[ftmp12], %[ftmp6] \n\t" - -#define VARIANCE_SSE_8 \ - "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" \ - "gsldlc1 %[ftmp2], 0x07(%[ref_ptr]) \n\t" \ - "gsldrc1 %[ftmp2], 0x00(%[ref_ptr]) \n\t" \ - "pasubub %[ftmp3], %[ftmp1], %[ftmp2] \n\t" \ - "punpcklbh %[ftmp4], %[ftmp3], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp5], %[ftmp3], %[ftmp0] \n\t" \ - "pmaddhw %[ftmp6], %[ftmp4], %[ftmp4] \n\t" \ - "pmaddhw %[ftmp7], %[ftmp5], %[ftmp5] \n\t" \ - "paddw %[ftmp8], %[ftmp8], %[ftmp6] \n\t" \ - "paddw %[ftmp8], %[ftmp8], %[ftmp7] \n\t" - -#define VARIANCE_SSE_16 \ - VARIANCE_SSE_8 \ - "gsldlc1 %[ftmp1], 0x0f(%[src_ptr]) \n\t" \ - "gsldrc1 %[ftmp1], 0x08(%[src_ptr]) \n\t" \ - "gsldlc1 %[ftmp2], 0x0f(%[ref_ptr]) \n\t" \ - "gsldrc1 %[ftmp2], 0x08(%[ref_ptr]) \n\t" \ - "pasubub %[ftmp3], %[ftmp1], %[ftmp2] \n\t" \ - "punpcklbh %[ftmp4], %[ftmp3], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp5], %[ftmp3], %[ftmp0] \n\t" \ - "pmaddhw %[ftmp6], %[ftmp4], %[ftmp4] \n\t" \ - "pmaddhw %[ftmp7], %[ftmp5], %[ftmp5] \n\t" \ - "paddw %[ftmp8], %[ftmp8], %[ftmp6] \n\t" \ - "paddw %[ftmp8], %[ftmp8], %[ftmp7] \n\t" - -#define VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_4_A \ - /* calculate fdata3[0]~fdata3[3], store at ftmp2*/ \ - "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" \ - "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \ - "gsldlc1 %[ftmp1], 0x08(%[src_ptr]) \n\t" \ - "gsldrc1 %[ftmp1], 0x01(%[src_ptr]) \n\t" \ - "punpcklbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \ - "pmullh %[ftmp2], %[ftmp2], %[filter_x0] \n\t" \ - "paddh %[ftmp2], %[ftmp2], %[ff_ph_40] \n\t" \ - "pmullh %[ftmp3], %[ftmp3], %[filter_x1] \n\t" \ - "paddh %[ftmp2], %[ftmp2], %[ftmp3] \n\t" \ - "psrlh %[ftmp2], %[ftmp2], %[ftmp6] \n\t" - -#define VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_4_B \ - /* calculate fdata3[0]~fdata3[3], store at ftmp4*/ \ - "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" \ - "punpcklbh %[ftmp4], %[ftmp1], %[ftmp0] \n\t" \ - "gsldlc1 %[ftmp1], 0x08(%[src_ptr]) \n\t" \ - "gsldrc1 %[ftmp1], 0x01(%[src_ptr]) \n\t" \ - "punpcklbh %[ftmp5], %[ftmp1], %[ftmp0] \n\t" \ - "pmullh %[ftmp4], %[ftmp4], %[filter_x0] \n\t" \ - "paddh %[ftmp4], %[ftmp4], %[ff_ph_40] \n\t" \ - "pmullh %[ftmp5], %[ftmp5], %[filter_x1] \n\t" \ - "paddh %[ftmp4], %[ftmp4], %[ftmp5] \n\t" \ - "psrlh %[ftmp4], %[ftmp4], %[ftmp6] \n\t" - -#define VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_4_A \ - /* calculate: temp2[0] ~ temp2[3] */ \ - "pmullh %[ftmp2], %[ftmp2], %[filter_y0] \n\t" \ - "paddh %[ftmp2], %[ftmp2], %[ff_ph_40] \n\t" \ - "pmullh %[ftmp1], %[ftmp4], %[filter_y1] \n\t" \ - "paddh %[ftmp2], %[ftmp2], %[ftmp1] \n\t" \ - "psrlh %[ftmp2], %[ftmp2], %[ftmp6] \n\t" \ - \ - /* store: temp2[0] ~ temp2[3] */ \ - "pand %[ftmp2], %[ftmp2], %[mask] \n\t" \ - "packushb %[ftmp2], %[ftmp2], %[ftmp0] \n\t" \ - "gssdrc1 %[ftmp2], 0x00(%[temp2_ptr]) \n\t" - -#define VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_4_B \ - /* calculate: temp2[0] ~ temp2[3] */ \ - "pmullh %[ftmp4], %[ftmp4], %[filter_y0] \n\t" \ - "paddh %[ftmp4], %[ftmp4], %[ff_ph_40] \n\t" \ - "pmullh %[ftmp1], %[ftmp2], %[filter_y1] \n\t" \ - "paddh %[ftmp4], %[ftmp4], %[ftmp1] \n\t" \ - "psrlh %[ftmp4], %[ftmp4], %[ftmp6] \n\t" \ - \ - /* store: temp2[0] ~ temp2[3] */ \ - "pand %[ftmp4], %[ftmp4], %[mask] \n\t" \ - "packushb %[ftmp4], %[ftmp4], %[ftmp0] \n\t" \ - "gssdrc1 %[ftmp4], 0x00(%[temp2_ptr]) \n\t" - -#define VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_8_A \ - /* calculate fdata3[0]~fdata3[7], store at ftmp2 and ftmp3*/ \ - "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" \ - "punpcklbh %[ftmp2], %[ftmp1], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp3], %[ftmp1], %[ftmp0] \n\t" \ - "gsldlc1 %[ftmp1], 0x08(%[src_ptr]) \n\t" \ - "gsldrc1 %[ftmp1], 0x01(%[src_ptr]) \n\t" \ - "punpcklbh %[ftmp4], %[ftmp1], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp5], %[ftmp1], %[ftmp0] \n\t" \ - "pmullh %[ftmp2], %[ftmp2], %[filter_x0] \n\t" \ - "pmullh %[ftmp3], %[ftmp3], %[filter_x0] \n\t" \ - "paddh %[ftmp2], %[ftmp2], %[ff_ph_40] \n\t" \ - "paddh %[ftmp3], %[ftmp3], %[ff_ph_40] \n\t" \ - "pmullh %[ftmp4], %[ftmp4], %[filter_x1] \n\t" \ - "pmullh %[ftmp5], %[ftmp5], %[filter_x1] \n\t" \ - "paddh %[ftmp2], %[ftmp2], %[ftmp4] \n\t" \ - "paddh %[ftmp3], %[ftmp3], %[ftmp5] \n\t" \ - "psrlh %[ftmp2], %[ftmp2], %[ftmp14] \n\t" \ - "psrlh %[ftmp3], %[ftmp3], %[ftmp14] \n\t" - -#define VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_8_B \ - /* calculate fdata3[0]~fdata3[7], store at ftmp8 and ftmp9*/ \ - "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" \ - "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" \ - "punpcklbh %[ftmp8], %[ftmp1], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp9], %[ftmp1], %[ftmp0] \n\t" \ - "gsldlc1 %[ftmp1], 0x08(%[src_ptr]) \n\t" \ - "gsldrc1 %[ftmp1], 0x01(%[src_ptr]) \n\t" \ - "punpcklbh %[ftmp10], %[ftmp1], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp11], %[ftmp1], %[ftmp0] \n\t" \ - "pmullh %[ftmp8], %[ftmp8], %[filter_x0] \n\t" \ - "pmullh %[ftmp9], %[ftmp9], %[filter_x0] \n\t" \ - "paddh %[ftmp8], %[ftmp8], %[ff_ph_40] \n\t" \ - "paddh %[ftmp9], %[ftmp9], %[ff_ph_40] \n\t" \ - "pmullh %[ftmp10], %[ftmp10], %[filter_x1] \n\t" \ - "pmullh %[ftmp11], %[ftmp11], %[filter_x1] \n\t" \ - "paddh %[ftmp8], %[ftmp8], %[ftmp10] \n\t" \ - "paddh %[ftmp9], %[ftmp9], %[ftmp11] \n\t" \ - "psrlh %[ftmp8], %[ftmp8], %[ftmp14] \n\t" \ - "psrlh %[ftmp9], %[ftmp9], %[ftmp14] \n\t" - -#define VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_8_A \ - /* calculate: temp2[0] ~ temp2[3] */ \ - "pmullh %[ftmp2], %[ftmp2], %[filter_y0] \n\t" \ - "paddh %[ftmp2], %[ftmp2], %[ff_ph_40] \n\t" \ - "pmullh %[ftmp1], %[ftmp8], %[filter_y1] \n\t" \ - "paddh %[ftmp2], %[ftmp2], %[ftmp1] \n\t" \ - "psrlh %[ftmp2], %[ftmp2], %[ftmp14] \n\t" \ - \ - /* calculate: temp2[4] ~ temp2[7] */ \ - "pmullh %[ftmp3], %[ftmp3], %[filter_y0] \n\t" \ - "paddh %[ftmp3], %[ftmp3], %[ff_ph_40] \n\t" \ - "pmullh %[ftmp1], %[ftmp9], %[filter_y1] \n\t" \ - "paddh %[ftmp3], %[ftmp3], %[ftmp1] \n\t" \ - "psrlh %[ftmp3], %[ftmp3], %[ftmp14] \n\t" \ - \ - /* store: temp2[0] ~ temp2[7] */ \ - "pand %[ftmp2], %[ftmp2], %[mask] \n\t" \ - "pand %[ftmp3], %[ftmp3], %[mask] \n\t" \ - "packushb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" \ - "gssdlc1 %[ftmp2], 0x07(%[temp2_ptr]) \n\t" \ - "gssdrc1 %[ftmp2], 0x00(%[temp2_ptr]) \n\t" - -#define VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_8_B \ - /* calculate: temp2[0] ~ temp2[3] */ \ - "pmullh %[ftmp8], %[ftmp8], %[filter_y0] \n\t" \ - "paddh %[ftmp8], %[ftmp8], %[ff_ph_40] \n\t" \ - "pmullh %[ftmp1], %[ftmp2], %[filter_y1] \n\t" \ - "paddh %[ftmp8], %[ftmp8], %[ftmp1] \n\t" \ - "psrlh %[ftmp8], %[ftmp8], %[ftmp14] \n\t" \ - \ - /* calculate: temp2[4] ~ temp2[7] */ \ - "pmullh %[ftmp9], %[ftmp9], %[filter_y0] \n\t" \ - "paddh %[ftmp9], %[ftmp9], %[ff_ph_40] \n\t" \ - "pmullh %[ftmp1], %[ftmp3], %[filter_y1] \n\t" \ - "paddh %[ftmp9], %[ftmp9], %[ftmp1] \n\t" \ - "psrlh %[ftmp9], %[ftmp9], %[ftmp14] \n\t" \ - \ - /* store: temp2[0] ~ temp2[7] */ \ - "pand %[ftmp8], %[ftmp8], %[mask] \n\t" \ - "pand %[ftmp9], %[ftmp9], %[mask] \n\t" \ - "packushb %[ftmp8], %[ftmp8], %[ftmp9] \n\t" \ - "gssdlc1 %[ftmp8], 0x07(%[temp2_ptr]) \n\t" \ - "gssdrc1 %[ftmp8], 0x00(%[temp2_ptr]) \n\t" - -#define VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_16_A \ - /* calculate fdata3[0]~fdata3[7], store at ftmp2 and ftmp3*/ \ - VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_8_A \ - \ - /* calculate fdata3[8]~fdata3[15], store at ftmp4 and ftmp5*/ \ - "gsldlc1 %[ftmp1], 0x0f(%[src_ptr]) \n\t" \ - "gsldrc1 %[ftmp1], 0x08(%[src_ptr]) \n\t" \ - "punpcklbh %[ftmp4], %[ftmp1], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp5], %[ftmp1], %[ftmp0] \n\t" \ - "gsldlc1 %[ftmp1], 0x10(%[src_ptr]) \n\t" \ - "gsldrc1 %[ftmp1], 0x09(%[src_ptr]) \n\t" \ - "punpcklbh %[ftmp6], %[ftmp1], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp7], %[ftmp1], %[ftmp0] \n\t" \ - "pmullh %[ftmp4], %[ftmp4], %[filter_x0] \n\t" \ - "pmullh %[ftmp5], %[ftmp5], %[filter_x0] \n\t" \ - "paddh %[ftmp4], %[ftmp4], %[ff_ph_40] \n\t" \ - "paddh %[ftmp5], %[ftmp5], %[ff_ph_40] \n\t" \ - "pmullh %[ftmp6], %[ftmp6], %[filter_x1] \n\t" \ - "pmullh %[ftmp7], %[ftmp7], %[filter_x1] \n\t" \ - "paddh %[ftmp4], %[ftmp4], %[ftmp6] \n\t" \ - "paddh %[ftmp5], %[ftmp5], %[ftmp7] \n\t" \ - "psrlh %[ftmp4], %[ftmp4], %[ftmp14] \n\t" \ - "psrlh %[ftmp5], %[ftmp5], %[ftmp14] \n\t" - -#define VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_16_B \ - /* calculate fdata3[0]~fdata3[7], store at ftmp8 and ftmp9*/ \ - VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_8_B \ - \ - /* calculate fdata3[8]~fdata3[15], store at ftmp10 and ftmp11*/ \ - "gsldlc1 %[ftmp1], 0x0f(%[src_ptr]) \n\t" \ - "gsldrc1 %[ftmp1], 0x08(%[src_ptr]) \n\t" \ - "punpcklbh %[ftmp10], %[ftmp1], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp11], %[ftmp1], %[ftmp0] \n\t" \ - "gsldlc1 %[ftmp1], 0x10(%[src_ptr]) \n\t" \ - "gsldrc1 %[ftmp1], 0x09(%[src_ptr]) \n\t" \ - "punpcklbh %[ftmp12], %[ftmp1], %[ftmp0] \n\t" \ - "punpckhbh %[ftmp13], %[ftmp1], %[ftmp0] \n\t" \ - "pmullh %[ftmp10], %[ftmp10], %[filter_x0] \n\t" \ - "pmullh %[ftmp11], %[ftmp11], %[filter_x0] \n\t" \ - "paddh %[ftmp10], %[ftmp10], %[ff_ph_40] \n\t" \ - "paddh %[ftmp11], %[ftmp11], %[ff_ph_40] \n\t" \ - "pmullh %[ftmp12], %[ftmp12], %[filter_x1] \n\t" \ - "pmullh %[ftmp13], %[ftmp13], %[filter_x1] \n\t" \ - "paddh %[ftmp10], %[ftmp10], %[ftmp12] \n\t" \ - "paddh %[ftmp11], %[ftmp11], %[ftmp13] \n\t" \ - "psrlh %[ftmp10], %[ftmp10], %[ftmp14] \n\t" \ - "psrlh %[ftmp11], %[ftmp11], %[ftmp14] \n\t" - -#define VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_16_A \ - VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_8_A \ - \ - /* calculate: temp2[8] ~ temp2[11] */ \ - "pmullh %[ftmp4], %[ftmp4], %[filter_y0] \n\t" \ - "paddh %[ftmp4], %[ftmp4], %[ff_ph_40] \n\t" \ - "pmullh %[ftmp1], %[ftmp10], %[filter_y1] \n\t" \ - "paddh %[ftmp4], %[ftmp4], %[ftmp1] \n\t" \ - "psrlh %[ftmp4], %[ftmp4], %[ftmp14] \n\t" \ - \ - /* calculate: temp2[12] ~ temp2[15] */ \ - "pmullh %[ftmp5], %[ftmp5], %[filter_y0] \n\t" \ - "paddh %[ftmp5], %[ftmp5], %[ff_ph_40] \n\t" \ - "pmullh %[ftmp1], %[ftmp11], %[filter_y1] \n\t" \ - "paddh %[ftmp5], %[ftmp5], %[ftmp1] \n\t" \ - "psrlh %[ftmp5], %[ftmp5], %[ftmp14] \n\t" \ - \ - /* store: temp2[8] ~ temp2[15] */ \ - "pand %[ftmp4], %[ftmp4], %[mask] \n\t" \ - "pand %[ftmp5], %[ftmp5], %[mask] \n\t" \ - "packushb %[ftmp4], %[ftmp4], %[ftmp5] \n\t" \ - "gssdlc1 %[ftmp4], 0x0f(%[temp2_ptr]) \n\t" \ - "gssdrc1 %[ftmp4], 0x08(%[temp2_ptr]) \n\t" - -#define VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_16_B \ - VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_8_B \ - \ - /* calculate: temp2[8] ~ temp2[11] */ \ - "pmullh %[ftmp10], %[ftmp10], %[filter_y0] \n\t" \ - "paddh %[ftmp10], %[ftmp10], %[ff_ph_40] \n\t" \ - "pmullh %[ftmp1], %[ftmp4], %[filter_y1] \n\t" \ - "paddh %[ftmp10], %[ftmp10], %[ftmp1] \n\t" \ - "psrlh %[ftmp10], %[ftmp10], %[ftmp14] \n\t" \ - \ - /* calculate: temp2[12] ~ temp2[15] */ \ - "pmullh %[ftmp11], %[ftmp11], %[filter_y0] \n\t" \ - "paddh %[ftmp11], %[ftmp11], %[ff_ph_40] \n\t" \ - "pmullh %[ftmp1], %[ftmp5], %[filter_y1] \n\t" \ - "paddh %[ftmp11], %[ftmp11], %[ftmp1] \n\t" \ - "psrlh %[ftmp11], %[ftmp11], %[ftmp14] \n\t" \ - \ - /* store: temp2[8] ~ temp2[15] */ \ - "pand %[ftmp10], %[ftmp10], %[mask] \n\t" \ - "pand %[ftmp11], %[ftmp11], %[mask] \n\t" \ - "packushb %[ftmp10], %[ftmp10], %[ftmp11] \n\t" \ - "gssdlc1 %[ftmp10], 0x0f(%[temp2_ptr]) \n\t" \ - "gssdrc1 %[ftmp10], 0x08(%[temp2_ptr]) \n\t" - -// Applies a 1-D 2-tap bilinear filter to the source block in either horizontal -// or vertical direction to produce the filtered output block. Used to implement -// the first-pass of 2-D separable filter. -// -// Produces int16_t output to retain precision for the next pass. Two filter -// taps should sum to FILTER_WEIGHT. pixel_step defines whether the filter is -// applied horizontally (pixel_step = 1) or vertically (pixel_step = stride). -// It defines the offset required to move from one input to the next. -static void var_filter_block2d_bil_first_pass( - const uint8_t *src_ptr, uint16_t *ref_ptr, unsigned int src_pixels_per_line, - int pixel_step, unsigned int output_height, unsigned int output_width, - const uint8_t *filter) { - unsigned int i, j; - - for (i = 0; i < output_height; ++i) { - for (j = 0; j < output_width; ++j) { - ref_ptr[j] = ROUND_POWER_OF_TWO( - (int)src_ptr[0] * filter[0] + (int)src_ptr[pixel_step] * filter[1], - FILTER_BITS); - - ++src_ptr; - } - - src_ptr += src_pixels_per_line - output_width; - ref_ptr += output_width; - } -} - -// Applies a 1-D 2-tap bilinear filter to the source block in either horizontal -// or vertical direction to produce the filtered output block. Used to implement -// the second-pass of 2-D separable filter. -// -// Requires 16-bit input as produced by filter_block2d_bil_first_pass. Two -// filter taps should sum to FILTER_WEIGHT. pixel_step defines whether the -// filter is applied horizontally (pixel_step = 1) or vertically -// (pixel_step = stride). It defines the offset required to move from one input -// to the next. Output is 8-bit. -static void var_filter_block2d_bil_second_pass( - const uint16_t *src_ptr, uint8_t *ref_ptr, unsigned int src_pixels_per_line, - unsigned int pixel_step, unsigned int output_height, - unsigned int output_width, const uint8_t *filter) { - unsigned int i, j; - - for (i = 0; i < output_height; ++i) { - for (j = 0; j < output_width; ++j) { - ref_ptr[j] = ROUND_POWER_OF_TWO( - (int)src_ptr[0] * filter[0] + (int)src_ptr[pixel_step] * filter[1], - FILTER_BITS); - ++src_ptr; - } - - src_ptr += src_pixels_per_line - output_width; - ref_ptr += output_width; - } -} - -static inline uint32_t vpx_variance64x(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - uint32_t *sse, int high) { - int sum; - double ftmp[12]; - uint32_t tmp[3]; - - *sse = 0; - - /* clang-format off */ - __asm__ volatile ( - "li %[tmp0], 0x20 \n\t" - "mtc1 %[tmp0], %[ftmp11] \n\t" - MMI_L(%[tmp0], %[high], 0x00) - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "pxor %[ftmp9], %[ftmp9], %[ftmp9] \n\t" - "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" - "1: \n\t" - "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x07(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x00(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8_FOR_W64 - - "gsldlc1 %[ftmp1], 0x0f(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x08(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x0f(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x08(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8_FOR_W64 - - "gsldlc1 %[ftmp1], 0x17(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x10(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x17(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x10(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8_FOR_W64 - - "gsldlc1 %[ftmp1], 0x1f(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x18(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x1f(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x18(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8_FOR_W64 - - "gsldlc1 %[ftmp1], 0x27(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x20(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x27(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x20(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8_FOR_W64 - - "gsldlc1 %[ftmp1], 0x2f(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x28(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x2f(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x28(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8_FOR_W64 - - "gsldlc1 %[ftmp1], 0x37(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x30(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x37(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x30(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8_FOR_W64 - - "gsldlc1 %[ftmp1], 0x3f(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x38(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x3f(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x38(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8_FOR_W64 - - "addiu %[tmp0], %[tmp0], -0x01 \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) - "bnez %[tmp0], 1b \n\t" - - "mfc1 %[tmp1], %[ftmp9] \n\t" - "mfhc1 %[tmp2], %[ftmp9] \n\t" - "addu %[sum], %[tmp1], %[tmp2] \n\t" - "ssrld %[ftmp1], %[ftmp10], %[ftmp11] \n\t" - "paddw %[ftmp1], %[ftmp1], %[ftmp10] \n\t" - "swc1 %[ftmp1], 0x00(%[sse]) \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), - [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), - [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), - [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), - [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), - [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]), - [tmp2]"=&r"(tmp[2]), - [src_ptr]"+&r"(src_ptr), [ref_ptr]"+&r"(ref_ptr), - [sum]"=&r"(sum) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride), - [high]"r"(&high), [sse]"r"(sse) - : "memory" - ); - /* clang-format on */ - - return *sse - (((int64_t)sum * sum) / (64 * high)); -} - -#define VPX_VARIANCE64XN(n) \ - uint32_t vpx_variance64x##n##_mmi(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *ref_ptr, int ref_stride, \ - uint32_t *sse) { \ - return vpx_variance64x(src_ptr, src_stride, ref_ptr, ref_stride, sse, n); \ - } - -VPX_VARIANCE64XN(64) -VPX_VARIANCE64XN(32) - -uint32_t vpx_variance32x64_mmi(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - uint32_t *sse) { - int sum; - double ftmp[12]; - uint32_t tmp[3]; - - *sse = 0; - - /* clang-format off */ - __asm__ volatile ( - "li %[tmp0], 0x20 \n\t" - "mtc1 %[tmp0], %[ftmp11] \n\t" - "li %[tmp0], 0x40 \n\t" - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "pxor %[ftmp9], %[ftmp9], %[ftmp9] \n\t" - "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" - "1: \n\t" - "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x07(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x00(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8_FOR_W64 - - "gsldlc1 %[ftmp1], 0x0f(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x08(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x0f(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x08(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8_FOR_W64 - - "gsldlc1 %[ftmp1], 0x17(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x10(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x17(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x10(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8_FOR_W64 - - "gsldlc1 %[ftmp1], 0x1f(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x18(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x1f(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x18(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8_FOR_W64 - - "addiu %[tmp0], %[tmp0], -0x01 \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) - "bnez %[tmp0], 1b \n\t" - - "mfc1 %[tmp1], %[ftmp9] \n\t" - "mfhc1 %[tmp2], %[ftmp9] \n\t" - "addu %[sum], %[tmp1], %[tmp2] \n\t" - "ssrld %[ftmp1], %[ftmp10], %[ftmp11] \n\t" - "paddw %[ftmp1], %[ftmp1], %[ftmp10] \n\t" - "swc1 %[ftmp1], 0x00(%[sse]) \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), - [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), - [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), - [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), - [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), - [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]), - [tmp2]"=&r"(tmp[2]), - [src_ptr]"+&r"(src_ptr), [ref_ptr]"+&r"(ref_ptr), - [sum]"=&r"(sum) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride), - [sse]"r"(sse) - : "memory" - ); - /* clang-format on */ - - return *sse - (((int64_t)sum * sum) / 2048); -} - -static inline uint32_t vpx_variance32x(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - uint32_t *sse, int high) { - int sum; - double ftmp[13]; - uint32_t tmp[3]; - - *sse = 0; - - /* clang-format off */ - __asm__ volatile ( - "li %[tmp0], 0x20 \n\t" - "mtc1 %[tmp0], %[ftmp11] \n\t" - MMI_L(%[tmp0], %[high], 0x00) - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" - "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" - "pxor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" - "1: \n\t" - "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x07(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x00(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8 - "gsldlc1 %[ftmp1], 0x0f(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x08(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x0f(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x08(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8 - "gsldlc1 %[ftmp1], 0x17(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x10(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x17(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x10(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8 - "gsldlc1 %[ftmp1], 0x1f(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x18(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x1f(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x18(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8 - - "addiu %[tmp0], %[tmp0], -0x01 \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) - "bnez %[tmp0], 1b \n\t" - - "ssrld %[ftmp9], %[ftmp8], %[ftmp11] \n\t" - "paddw %[ftmp9], %[ftmp9], %[ftmp8] \n\t" - "swc1 %[ftmp9], 0x00(%[sse]) \n\t" - - "punpcklhw %[ftmp3], %[ftmp10], %[ftmp0] \n\t" - "punpckhhw %[ftmp4], %[ftmp10], %[ftmp0] \n\t" - "punpcklhw %[ftmp5], %[ftmp12], %[ftmp0] \n\t" - "punpckhhw %[ftmp6], %[ftmp12], %[ftmp0] \n\t" - "paddw %[ftmp3], %[ftmp3], %[ftmp4] \n\t" - "psubw %[ftmp3], %[ftmp3], %[ftmp5] \n\t" - "psubw %[ftmp3], %[ftmp3], %[ftmp6] \n\t" - "ssrld %[ftmp0], %[ftmp3], %[ftmp11] \n\t" - "paddw %[ftmp0], %[ftmp0], %[ftmp3] \n\t" - "swc1 %[ftmp0], 0x00(%[sum]) \n\t" - - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), - [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), - [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), - [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), - [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), - [ftmp12]"=&f"(ftmp[12]), [tmp0]"=&r"(tmp[0]), - [src_ptr]"+&r"(src_ptr), [ref_ptr]"+&r"(ref_ptr) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride), - [high]"r"(&high), [sse]"r"(sse), [sum]"r"(&sum) - : "memory" - ); - /* clang-format on */ - - return *sse - (((int64_t)sum * sum) / (32 * high)); -} - -#define VPX_VARIANCE32XN(n) \ - uint32_t vpx_variance32x##n##_mmi(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *ref_ptr, int ref_stride, \ - uint32_t *sse) { \ - return vpx_variance32x(src_ptr, src_stride, ref_ptr, ref_stride, sse, n); \ - } - -VPX_VARIANCE32XN(32) -VPX_VARIANCE32XN(16) - -static inline uint32_t vpx_variance16x(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - uint32_t *sse, int high) { - int sum; - double ftmp[13]; - uint32_t tmp[3]; - - *sse = 0; - - /* clang-format off */ - __asm__ volatile ( - "li %[tmp0], 0x20 \n\t" - "mtc1 %[tmp0], %[ftmp11] \n\t" - MMI_L(%[tmp0], %[high], 0x00) - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" - "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" - "pxor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" - "1: \n\t" - "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x07(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x00(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8 - "gsldlc1 %[ftmp1], 0x0f(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x08(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x0f(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x08(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8 - - "addiu %[tmp0], %[tmp0], -0x01 \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) - "bnez %[tmp0], 1b \n\t" - - "ssrld %[ftmp9], %[ftmp8], %[ftmp11] \n\t" - "paddw %[ftmp9], %[ftmp9], %[ftmp8] \n\t" - "swc1 %[ftmp9], 0x00(%[sse]) \n\t" - - "punpcklhw %[ftmp3], %[ftmp10], %[ftmp0] \n\t" - "punpckhhw %[ftmp4], %[ftmp10], %[ftmp0] \n\t" - "punpcklhw %[ftmp5], %[ftmp12], %[ftmp0] \n\t" - "punpckhhw %[ftmp6], %[ftmp12], %[ftmp0] \n\t" - "paddw %[ftmp3], %[ftmp3], %[ftmp4] \n\t" - "psubw %[ftmp3], %[ftmp3], %[ftmp5] \n\t" - "psubw %[ftmp3], %[ftmp3], %[ftmp6] \n\t" - "ssrld %[ftmp0], %[ftmp3], %[ftmp11] \n\t" - "paddw %[ftmp0], %[ftmp0], %[ftmp3] \n\t" - "swc1 %[ftmp0], 0x00(%[sum]) \n\t" - - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), - [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), - [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), - [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), - [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), - [ftmp12]"=&f"(ftmp[12]), [tmp0]"=&r"(tmp[0]), - [src_ptr]"+&r"(src_ptr), [ref_ptr]"+&r"(ref_ptr) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride), - [high]"r"(&high), [sse]"r"(sse), [sum]"r"(&sum) - : "memory" - ); - /* clang-format on */ - - return *sse - (((int64_t)sum * sum) / (16 * high)); -} - -#define VPX_VARIANCE16XN(n) \ - uint32_t vpx_variance16x##n##_mmi(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *ref_ptr, int ref_stride, \ - uint32_t *sse) { \ - return vpx_variance16x(src_ptr, src_stride, ref_ptr, ref_stride, sse, n); \ - } - -VPX_VARIANCE16XN(32) -VPX_VARIANCE16XN(16) -VPX_VARIANCE16XN(8) - -static inline uint32_t vpx_variance8x(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - uint32_t *sse, int high) { - int sum; - double ftmp[13]; - uint32_t tmp[3]; - - *sse = 0; - - /* clang-format off */ - __asm__ volatile ( - "li %[tmp0], 0x20 \n\t" - "mtc1 %[tmp0], %[ftmp11] \n\t" - MMI_L(%[tmp0], %[high], 0x00) - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" - "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" - "pxor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" - "1: \n\t" - "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x07(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x00(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_8 - - "addiu %[tmp0], %[tmp0], -0x01 \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) - "bnez %[tmp0], 1b \n\t" - - "ssrld %[ftmp9], %[ftmp8], %[ftmp11] \n\t" - "paddw %[ftmp9], %[ftmp9], %[ftmp8] \n\t" - "swc1 %[ftmp9], 0x00(%[sse]) \n\t" - - "punpcklhw %[ftmp3], %[ftmp10], %[ftmp0] \n\t" - "punpckhhw %[ftmp4], %[ftmp10], %[ftmp0] \n\t" - "punpcklhw %[ftmp5], %[ftmp12], %[ftmp0] \n\t" - "punpckhhw %[ftmp6], %[ftmp12], %[ftmp0] \n\t" - "paddw %[ftmp3], %[ftmp3], %[ftmp4] \n\t" - "psubw %[ftmp3], %[ftmp3], %[ftmp5] \n\t" - "psubw %[ftmp3], %[ftmp3], %[ftmp6] \n\t" - "ssrld %[ftmp0], %[ftmp3], %[ftmp11] \n\t" - "paddw %[ftmp0], %[ftmp0], %[ftmp3] \n\t" - "swc1 %[ftmp0], 0x00(%[sum]) \n\t" - - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), - [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), - [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), - [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), - [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), - [ftmp12]"=&f"(ftmp[12]), [tmp0]"=&r"(tmp[0]), - [src_ptr]"+&r"(src_ptr), [ref_ptr]"+&r"(ref_ptr) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride), - [high]"r"(&high), [sse]"r"(sse), [sum]"r"(&sum) - : "memory" - ); - /* clang-format on */ - - return *sse - (((int64_t)sum * sum) / (8 * high)); -} - -#define VPX_VARIANCE8XN(n) \ - uint32_t vpx_variance8x##n##_mmi(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *ref_ptr, int ref_stride, \ - uint32_t *sse) { \ - return vpx_variance8x(src_ptr, src_stride, ref_ptr, ref_stride, sse, n); \ - } - -VPX_VARIANCE8XN(16) -VPX_VARIANCE8XN(8) -VPX_VARIANCE8XN(4) - -static inline uint32_t vpx_variance4x(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - uint32_t *sse, int high) { - int sum; - double ftmp[12]; - uint32_t tmp[3]; - - *sse = 0; - - /* clang-format off */ - __asm__ volatile ( - "li %[tmp0], 0x20 \n\t" - "mtc1 %[tmp0], %[ftmp10] \n\t" - MMI_L(%[tmp0], %[high], 0x00) - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "pxor %[ftmp6], %[ftmp6], %[ftmp6] \n\t" - "pxor %[ftmp7], %[ftmp7], %[ftmp7] \n\t" - "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" - "1: \n\t" - "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" - "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" - "gsldlc1 %[ftmp2], 0x07(%[ref_ptr]) \n\t" - "gsldrc1 %[ftmp2], 0x00(%[ref_ptr]) \n\t" - VARIANCE_SSE_SUM_4 - - "addiu %[tmp0], %[tmp0], -0x01 \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) - "bnez %[tmp0], 1b \n\t" - - "ssrld %[ftmp9], %[ftmp6], %[ftmp10] \n\t" - "paddw %[ftmp9], %[ftmp9], %[ftmp6] \n\t" - "swc1 %[ftmp9], 0x00(%[sse]) \n\t" - - "punpcklhw %[ftmp3], %[ftmp7], %[ftmp0] \n\t" - "punpckhhw %[ftmp4], %[ftmp7], %[ftmp0] \n\t" - "punpcklhw %[ftmp5], %[ftmp8], %[ftmp0] \n\t" - "punpckhhw %[ftmp6], %[ftmp8], %[ftmp0] \n\t" - "paddw %[ftmp3], %[ftmp3], %[ftmp4] \n\t" - "psubw %[ftmp3], %[ftmp3], %[ftmp5] \n\t" - "psubw %[ftmp3], %[ftmp3], %[ftmp6] \n\t" - "ssrld %[ftmp0], %[ftmp3], %[ftmp10] \n\t" - "paddw %[ftmp0], %[ftmp0], %[ftmp3] \n\t" - "swc1 %[ftmp0], 0x00(%[sum]) \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), - [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), - [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), - [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), - [ftmp10]"=&f"(ftmp[10]), - [tmp0]"=&r"(tmp[0]), - [src_ptr]"+&r"(src_ptr), [ref_ptr]"+&r"(ref_ptr) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride), - [high]"r"(&high), [sse]"r"(sse), [sum]"r"(&sum) - : "memory" - ); - /* clang-format on */ - - return *sse - (((int64_t)sum * sum) / (4 * high)); -} - -#define VPX_VARIANCE4XN(n) \ - uint32_t vpx_variance4x##n##_mmi(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *ref_ptr, int ref_stride, \ - uint32_t *sse) { \ - return vpx_variance4x(src_ptr, src_stride, ref_ptr, ref_stride, sse, n); \ - } - -VPX_VARIANCE4XN(8) -VPX_VARIANCE4XN(4) - -static inline uint32_t vpx_mse16x(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - uint32_t *sse, uint64_t high) { - double ftmp[12]; - uint32_t tmp[1]; - - *sse = 0; - - /* clang-format off */ - __asm__ volatile ( - "li %[tmp0], 0x20 \n\t" - "mtc1 %[tmp0], %[ftmp11] \n\t" - MMI_L(%[tmp0], %[high], 0x00) - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" - - "1: \n\t" - VARIANCE_SSE_16 - - "addiu %[tmp0], %[tmp0], -0x01 \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) - "bnez %[tmp0], 1b \n\t" - - "ssrld %[ftmp9], %[ftmp8], %[ftmp11] \n\t" - "paddw %[ftmp9], %[ftmp9], %[ftmp8] \n\t" - "swc1 %[ftmp9], 0x00(%[sse]) \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), - [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), - [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), - [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), - [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), - [tmp0]"=&r"(tmp[0]), - [src_ptr]"+&r"(src_ptr), [ref_ptr]"+&r"(ref_ptr) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride), - [high]"r"(&high), [sse]"r"(sse) - : "memory" - ); - /* clang-format on */ - - return *sse; -} - -#define vpx_mse16xN(n) \ - uint32_t vpx_mse16x##n##_mmi(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *ref_ptr, int ref_stride, \ - uint32_t *sse) { \ - return vpx_mse16x(src_ptr, src_stride, ref_ptr, ref_stride, sse, n); \ - } - -vpx_mse16xN(16); -vpx_mse16xN(8); - -static inline uint32_t vpx_mse8x(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - uint32_t *sse, uint64_t high) { - double ftmp[12]; - uint32_t tmp[1]; - - *sse = 0; - - /* clang-format off */ - __asm__ volatile ( - "li %[tmp0], 0x20 \n\t" - "mtc1 %[tmp0], %[ftmp11] \n\t" - MMI_L(%[tmp0], %[high], 0x00) - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" - - "1: \n\t" - VARIANCE_SSE_8 - - "addiu %[tmp0], %[tmp0], -0x01 \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) - "bnez %[tmp0], 1b \n\t" - - "ssrld %[ftmp9], %[ftmp8], %[ftmp11] \n\t" - "paddw %[ftmp9], %[ftmp9], %[ftmp8] \n\t" - "swc1 %[ftmp9], 0x00(%[sse]) \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), - [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), - [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), - [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), - [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), - [tmp0]"=&r"(tmp[0]), - [src_ptr]"+&r"(src_ptr), [ref_ptr]"+&r"(ref_ptr) - : [src_stride]"r"((mips_reg)src_stride), - [ref_stride]"r"((mips_reg)ref_stride), - [high]"r"(&high), [sse]"r"(sse) - : "memory" - ); - /* clang-format on */ - - return *sse; -} - -#define vpx_mse8xN(n) \ - uint32_t vpx_mse8x##n##_mmi(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *ref_ptr, int ref_stride, \ - uint32_t *sse) { \ - return vpx_mse8x(src_ptr, src_stride, ref_ptr, ref_stride, sse, n); \ - } - -vpx_mse8xN(16); -vpx_mse8xN(8); - -#define SUBPIX_VAR(W, H) \ - uint32_t vpx_sub_pixel_variance##W##x##H##_mmi( \ - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref_ptr, int ref_stride, uint32_t *sse) { \ - uint16_t fdata3[((H) + 1) * (W)]; \ - uint8_t temp2[(H) * (W)]; \ - \ - var_filter_block2d_bil_first_pass(src_ptr, fdata3, src_stride, 1, (H) + 1, \ - W, bilinear_filters[x_offset]); \ - var_filter_block2d_bil_second_pass(fdata3, temp2, W, W, H, W, \ - bilinear_filters[y_offset]); \ - \ - return vpx_variance##W##x##H##_mmi(temp2, W, ref_ptr, ref_stride, sse); \ - } - -SUBPIX_VAR(64, 64) -SUBPIX_VAR(64, 32) -SUBPIX_VAR(32, 64) -SUBPIX_VAR(32, 32) -SUBPIX_VAR(32, 16) -SUBPIX_VAR(16, 32) - -static inline void var_filter_block2d_bil_16x(const uint8_t *src_ptr, - int src_stride, int x_offset, - int y_offset, uint8_t *temp2, - int counter) { - uint8_t *temp2_ptr = temp2; - mips_reg l_counter = counter; - double ftmp[15]; - double ff_ph_40, mask; - double filter_x0, filter_x1, filter_y0, filter_y1; - mips_reg tmp[2]; - uint64_t x0, x1, y0, y1, all; - - const uint8_t *filter_x = bilinear_filters[x_offset]; - const uint8_t *filter_y = bilinear_filters[y_offset]; - x0 = (uint64_t)filter_x[0]; - x1 = (uint64_t)filter_x[1]; - y0 = (uint64_t)filter_y[0]; - y1 = (uint64_t)filter_y[1]; - all = x0 | x1 << 8 | y0 << 16 | y1 << 24; - - /* clang-format off */ - __asm__ volatile ( - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - MMI_MTC1(%[all], %[ftmp14]) - "punpcklbh %[ftmp14], %[ftmp14], %[ftmp0] \n\t" - "pshufh %[filter_x0], %[ftmp14], %[ftmp0] \n\t" - MMI_LI(%[tmp0], 0x10) - MMI_MTC1(%[tmp0], %[mask]) - "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" - "pshufh %[filter_x1], %[ftmp14], %[ftmp0] \n\t" - "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" - "pshufh %[filter_y0], %[ftmp14], %[ftmp0] \n\t" - "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" - "pshufh %[filter_y1], %[ftmp14], %[ftmp0] \n\t" - MMI_LI(%[tmp0], 0x07) - MMI_MTC1(%[tmp0], %[ftmp14]) - MMI_LI(%[tmp0], 0x0040004000400040) - MMI_MTC1(%[tmp0], %[ff_ph_40]) - MMI_LI(%[tmp0], 0x00ff00ff00ff00ff) - MMI_MTC1(%[tmp0], %[mask]) - // fdata3: fdata3[0] ~ fdata3[15] - VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_16_A - - // fdata3 +src_stride*1: fdata3[0] ~ fdata3[15] - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_16_B - // temp2: temp2[0] ~ temp2[15] - VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_16_A - - // fdata3 +src_stride*2: fdata3[0] ~ fdata3[15] - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_16_A - // temp2+16*1: temp2[0] ~ temp2[15] - MMI_ADDIU(%[temp2_ptr], %[temp2_ptr], 0x10) - VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_16_B - - "1: \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_16_B - MMI_ADDIU(%[temp2_ptr], %[temp2_ptr], 0x10) - VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_16_A - - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_16_A - MMI_ADDIU(%[temp2_ptr], %[temp2_ptr], 0x10) - VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_16_B - "addiu %[counter], %[counter], -0x01 \n\t" - "bnez %[counter], 1b \n\t" - : [ftmp0] "=&f"(ftmp[0]), [ftmp1] "=&f"(ftmp[1]), [ftmp2] "=&f"(ftmp[2]), - [ftmp3] "=&f"(ftmp[3]), [ftmp4] "=&f"(ftmp[4]), [ftmp5] "=&f"(ftmp[5]), - [ftmp6] "=&f"(ftmp[6]), [ftmp7] "=&f"(ftmp[7]), [ftmp8] "=&f"(ftmp[8]), - [ftmp9] "=&f"(ftmp[9]), [ftmp10] "=&f"(ftmp[10]), - [ftmp11] "=&f"(ftmp[11]), [ftmp12] "=&f"(ftmp[12]), - [ftmp13] "=&f"(ftmp[13]), [ftmp14] "=&f"(ftmp[14]), - [tmp0] "=&r"(tmp[0]), [src_ptr] "+&r"(src_ptr), [temp2_ptr] "+&r"(temp2_ptr), - [counter]"+&r"(l_counter), [ff_ph_40] "=&f"(ff_ph_40), [mask] "=&f"(mask), - [filter_x0] "=&f"(filter_x0), [filter_x1] "=&f"(filter_x1), - [filter_y0] "=&f"(filter_y0), [filter_y1] "=&f"(filter_y1) - : [src_stride] "r"((mips_reg)src_stride), [all] "r"(all) - : "memory" - ); - /* clang-format on */ -} - -#define SUBPIX_VAR16XN(H) \ - uint32_t vpx_sub_pixel_variance16x##H##_mmi( \ - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref_ptr, int ref_stride, uint32_t *sse) { \ - uint8_t temp2[16 * (H)]; \ - var_filter_block2d_bil_16x(src_ptr, src_stride, x_offset, y_offset, temp2, \ - ((H)-2) / 2); \ - \ - return vpx_variance16x##H##_mmi(temp2, 16, ref_ptr, ref_stride, sse); \ - } - -SUBPIX_VAR16XN(16) -SUBPIX_VAR16XN(8) - -static inline void var_filter_block2d_bil_8x(const uint8_t *src_ptr, - int src_stride, int x_offset, - int y_offset, uint8_t *temp2, - int counter) { - uint8_t *temp2_ptr = temp2; - mips_reg l_counter = counter; - double ftmp[15]; - mips_reg tmp[2]; - double ff_ph_40, mask; - uint64_t x0, x1, y0, y1, all; - double filter_x0, filter_x1, filter_y0, filter_y1; - const uint8_t *filter_x = bilinear_filters[x_offset]; - const uint8_t *filter_y = bilinear_filters[y_offset]; - x0 = (uint64_t)filter_x[0]; - x1 = (uint64_t)filter_x[1]; - y0 = (uint64_t)filter_y[0]; - y1 = (uint64_t)filter_y[1]; - all = x0 | x1 << 8 | y0 << 16 | y1 << 24; - - /* clang-format off */ - __asm__ volatile ( - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - MMI_MTC1(%[all], %[ftmp14]) - "punpcklbh %[ftmp14], %[ftmp14], %[ftmp0] \n\t" - "pshufh %[filter_x0], %[ftmp14], %[ftmp0] \n\t" - MMI_LI(%[tmp0], 0x10) - MMI_MTC1(%[tmp0], %[mask]) - "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" - "pshufh %[filter_x1], %[ftmp14], %[ftmp0] \n\t" - "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" - "pshufh %[filter_y0], %[ftmp14], %[ftmp0] \n\t" - "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" - "pshufh %[filter_y1], %[ftmp14], %[ftmp0] \n\t" - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - MMI_LI(%[tmp0], 0x07) - MMI_MTC1(%[tmp0], %[ftmp14]) - MMI_LI(%[tmp0], 0x0040004000400040) - MMI_MTC1(%[tmp0], %[ff_ph_40]) - MMI_LI(%[tmp0], 0x00ff00ff00ff00ff) - MMI_MTC1(%[tmp0], %[mask]) - - // fdata3: fdata3[0] ~ fdata3[7] - VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_8_A - - // fdata3 +src_stride*1: fdata3[0] ~ fdata3[7] - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_8_B - // temp2: temp2[0] ~ temp2[7] - VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_8_A - - // fdata3 +src_stride*2: fdata3[0] ~ fdata3[7] - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_8_A - // temp2+8*1: temp2[0] ~ temp2[7] - MMI_ADDIU(%[temp2_ptr], %[temp2_ptr], 0x08) - VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_8_B - - "1: \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_8_B - MMI_ADDIU(%[temp2_ptr], %[temp2_ptr], 0x08) - VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_8_A - - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_8_A - MMI_ADDIU(%[temp2_ptr], %[temp2_ptr], 0x08) - VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_8_B - "addiu %[counter], %[counter], -0x01 \n\t" - "bnez %[counter], 1b \n\t" - : [ftmp0] "=&f"(ftmp[0]), [ftmp1] "=&f"(ftmp[1]), [ftmp2] "=&f"(ftmp[2]), - [ftmp3] "=&f"(ftmp[3]), [ftmp4] "=&f"(ftmp[4]), [ftmp5] "=&f"(ftmp[5]), - [ftmp6] "=&f"(ftmp[6]), [ftmp7] "=&f"(ftmp[7]), [ftmp8] "=&f"(ftmp[8]), - [ftmp9] "=&f"(ftmp[9]), [ftmp10] "=&f"(ftmp[10]), - [ftmp11] "=&f"(ftmp[11]), [ftmp12] "=&f"(ftmp[12]), - [ftmp13] "=&f"(ftmp[13]), [ftmp14] "=&f"(ftmp[14]), - [tmp0] "=&r"(tmp[0]), [src_ptr] "+&r"(src_ptr), [temp2_ptr] "+&r"(temp2_ptr), - [counter]"+&r"(l_counter), [ff_ph_40] "=&f"(ff_ph_40), [mask] "=&f"(mask), - [filter_x0] "=&f"(filter_x0), [filter_x1] "=&f"(filter_x1), - [filter_y0] "=&f"(filter_y0), [filter_y1] "=&f"(filter_y1) - : [src_stride] "r"((mips_reg)src_stride), [all] "r"(all) - : "memory" - ); - /* clang-format on */ -} - -#define SUBPIX_VAR8XN(H) \ - uint32_t vpx_sub_pixel_variance8x##H##_mmi( \ - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref_ptr, int ref_stride, uint32_t *sse) { \ - uint8_t temp2[8 * (H)]; \ - var_filter_block2d_bil_8x(src_ptr, src_stride, x_offset, y_offset, temp2, \ - ((H)-2) / 2); \ - \ - return vpx_variance8x##H##_mmi(temp2, 8, ref_ptr, ref_stride, sse); \ - } - -SUBPIX_VAR8XN(16) -SUBPIX_VAR8XN(8) -SUBPIX_VAR8XN(4) - -static inline void var_filter_block2d_bil_4x(const uint8_t *src_ptr, - int src_stride, int x_offset, - int y_offset, uint8_t *temp2, - int counter) { - uint8_t *temp2_ptr = temp2; - mips_reg l_counter = counter; - double ftmp[7]; - mips_reg tmp[2]; - double ff_ph_40, mask; - uint64_t x0, x1, y0, y1, all; - double filter_x0, filter_x1, filter_y0, filter_y1; - const uint8_t *filter_x = bilinear_filters[x_offset]; - const uint8_t *filter_y = bilinear_filters[y_offset]; - x0 = (uint64_t)filter_x[0]; - x1 = (uint64_t)filter_x[1]; - y0 = (uint64_t)filter_y[0]; - y1 = (uint64_t)filter_y[1]; - all = x0 | x1 << 8 | y0 << 16 | y1 << 24; - - /* clang-format off */ - __asm__ volatile ( - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - MMI_MTC1(%[all], %[ftmp6]) - "punpcklbh %[ftmp6], %[ftmp6], %[ftmp0] \n\t" - "pshufh %[filter_x0], %[ftmp6], %[ftmp0] \n\t" - MMI_LI(%[tmp0], 0x10) - MMI_MTC1(%[tmp0], %[mask]) - "ssrld %[ftmp6], %[ftmp6], %[mask] \n\t" - "pshufh %[filter_x1], %[ftmp6], %[ftmp0] \n\t" - "ssrld %[ftmp6], %[ftmp6], %[mask] \n\t" - "pshufh %[filter_y0], %[ftmp6], %[ftmp0] \n\t" - "ssrld %[ftmp6], %[ftmp6], %[mask] \n\t" - "pshufh %[filter_y1], %[ftmp6], %[ftmp0] \n\t" - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - MMI_LI(%[tmp0], 0x07) - MMI_MTC1(%[tmp0], %[ftmp6]) - MMI_LI(%[tmp0], 0x0040004000400040) - MMI_MTC1(%[tmp0], %[ff_ph_40]) - MMI_LI(%[tmp0], 0x00ff00ff00ff00ff) - MMI_MTC1(%[tmp0], %[mask]) - // fdata3: fdata3[0] ~ fdata3[3] - VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_4_A - - // fdata3 +src_stride*1: fdata3[0] ~ fdata3[3] - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_4_B - // temp2: temp2[0] ~ temp2[7] - VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_4_A - - // fdata3 +src_stride*2: fdata3[0] ~ fdata3[3] - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_4_A - // temp2+4*1: temp2[0] ~ temp2[7] - MMI_ADDIU(%[temp2_ptr], %[temp2_ptr], 0x04) - VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_4_B - - "1: \n\t" - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_4_B - MMI_ADDIU(%[temp2_ptr], %[temp2_ptr], 0x04) - VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_4_A - - MMI_ADDU(%[src_ptr], %[src_ptr], %[src_stride]) - VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_4_A - MMI_ADDIU(%[temp2_ptr], %[temp2_ptr], 0x04) - VAR_FILTER_BLOCK2D_BIL_SECOND_PASS_4_B - "addiu %[counter], %[counter], -0x01 \n\t" - "bnez %[counter], 1b \n\t" - : [ftmp0] "=&f"(ftmp[0]), [ftmp1] "=&f"(ftmp[1]), [ftmp2] "=&f"(ftmp[2]), - [ftmp3] "=&f"(ftmp[3]), [ftmp4] "=&f"(ftmp[4]), [ftmp5] "=&f"(ftmp[5]), - [ftmp6] "=&f"(ftmp[6]), [tmp0] "=&r"(tmp[0]), [src_ptr] "+&r"(src_ptr), - [temp2_ptr] "+&r"(temp2_ptr), [counter]"+&r"(l_counter), - [ff_ph_40] "=&f"(ff_ph_40), [mask] "=&f"(mask), - [filter_x0] "=&f"(filter_x0), [filter_x1] "=&f"(filter_x1), - [filter_y0] "=&f"(filter_y0), [filter_y1] "=&f"(filter_y1) - : [src_stride] "r"((mips_reg)src_stride), [all] "r"(all) - : "memory" - ); - /* clang-format on */ -} - -#define SUBPIX_VAR4XN(H) \ - uint32_t vpx_sub_pixel_variance4x##H##_mmi( \ - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref_ptr, int ref_stride, uint32_t *sse) { \ - uint8_t temp2[4 * (H)]; \ - var_filter_block2d_bil_4x(src_ptr, src_stride, x_offset, y_offset, temp2, \ - ((H)-2) / 2); \ - \ - return vpx_variance4x##H##_mmi(temp2, 4, ref_ptr, ref_stride, sse); \ - } - -SUBPIX_VAR4XN(8) -SUBPIX_VAR4XN(4) - -#define SUBPIX_AVG_VAR(W, H) \ - uint32_t vpx_sub_pixel_avg_variance##W##x##H##_mmi( \ - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, \ - const uint8_t *second_pred) { \ - uint16_t fdata3[((H) + 1) * (W)]; \ - uint8_t temp2[(H) * (W)]; \ - DECLARE_ALIGNED(16, uint8_t, temp3[(H) * (W)]); \ - \ - var_filter_block2d_bil_first_pass(src_ptr, fdata3, src_stride, 1, (H) + 1, \ - W, bilinear_filters[x_offset]); \ - var_filter_block2d_bil_second_pass(fdata3, temp2, W, W, H, W, \ - bilinear_filters[y_offset]); \ - \ - vpx_comp_avg_pred_c(temp3, second_pred, W, H, temp2, W); \ - \ - return vpx_variance##W##x##H##_mmi(temp3, W, ref_ptr, ref_stride, sse); \ - } - -SUBPIX_AVG_VAR(64, 64) -SUBPIX_AVG_VAR(64, 32) -SUBPIX_AVG_VAR(32, 64) -SUBPIX_AVG_VAR(32, 32) -SUBPIX_AVG_VAR(32, 16) -SUBPIX_AVG_VAR(16, 32) -SUBPIX_AVG_VAR(16, 16) -SUBPIX_AVG_VAR(16, 8) -SUBPIX_AVG_VAR(8, 16) -SUBPIX_AVG_VAR(8, 8) -SUBPIX_AVG_VAR(8, 4) -SUBPIX_AVG_VAR(4, 8) -SUBPIX_AVG_VAR(4, 4) diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/variance_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/variance_msa.c deleted file mode 100644 index 444b086a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/variance_msa.c +++ /dev/null @@ -1,622 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/macros_msa.h" - -#define CALC_MSE_B(src, ref, var) \ - { \ - v16u8 src_l0_m, src_l1_m; \ - v8i16 res_l0_m, res_l1_m; \ - \ - ILVRL_B2_UB(src, ref, src_l0_m, src_l1_m); \ - HSUB_UB2_SH(src_l0_m, src_l1_m, res_l0_m, res_l1_m); \ - DPADD_SH2_SW(res_l0_m, res_l1_m, res_l0_m, res_l1_m, var, var); \ - } - -#define CALC_MSE_AVG_B(src, ref, var, sub) \ - { \ - v16u8 src_l0_m, src_l1_m; \ - v8i16 res_l0_m, res_l1_m; \ - \ - ILVRL_B2_UB(src, ref, src_l0_m, src_l1_m); \ - HSUB_UB2_SH(src_l0_m, src_l1_m, res_l0_m, res_l1_m); \ - DPADD_SH2_SW(res_l0_m, res_l1_m, res_l0_m, res_l1_m, var, var); \ - \ - sub += res_l0_m + res_l1_m; \ - } - -#define VARIANCE_WxH(sse, diff, shift) \ - (sse) - (((uint32_t)(diff) * (diff)) >> (shift)) - -#define VARIANCE_LARGE_WxH(sse, diff, shift) \ - (sse) - (((int64_t)(diff) * (diff)) >> (shift)) - -static uint32_t sse_diff_4width_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t height, int32_t *diff) { - uint32_t src0, src1, src2, src3; - uint32_t ref0, ref1, ref2, ref3; - int32_t ht_cnt; - v16u8 src = { 0 }; - v16u8 ref = { 0 }; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LW4(src_ptr, src_stride, src0, src1, src2, src3); - src_ptr += (4 * src_stride); - LW4(ref_ptr, ref_stride, ref0, ref1, ref2, ref3); - ref_ptr += (4 * ref_stride); - - INSERT_W4_UB(src0, src1, src2, src3, src); - INSERT_W4_UB(ref0, ref1, ref2, ref3, ref); - CALC_MSE_AVG_B(src, ref, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sse_diff_8width_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t height, int32_t *diff) { - int32_t ht_cnt; - v16u8 src0, src1, src2, src3; - v16u8 ref0, ref1, ref2, ref3; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LD_UB4(src_ptr, src_stride, src0, src1, src2, src3); - src_ptr += (4 * src_stride); - LD_UB4(ref_ptr, ref_stride, ref0, ref1, ref2, ref3); - ref_ptr += (4 * ref_stride); - - PCKEV_D4_UB(src1, src0, src3, src2, ref1, ref0, ref3, ref2, src0, src1, - ref0, ref1); - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sse_diff_16width_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t height, int32_t *diff) { - int32_t ht_cnt; - v16u8 src, ref; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - src = LD_UB(src_ptr); - src_ptr += src_stride; - ref = LD_UB(ref_ptr); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src, ref, var, avg); - - src = LD_UB(src_ptr); - src_ptr += src_stride; - ref = LD_UB(ref_ptr); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src, ref, var, avg); - - src = LD_UB(src_ptr); - src_ptr += src_stride; - ref = LD_UB(ref_ptr); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src, ref, var, avg); - - src = LD_UB(src_ptr); - src_ptr += src_stride; - ref = LD_UB(ref_ptr); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src, ref, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sse_diff_32width_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t height, int32_t *diff) { - int32_t ht_cnt; - v16u8 src0, src1, ref0, ref1; - v8i16 avg = { 0 }; - v4i32 vec, var = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src0, ref0, var, avg); - CALC_MSE_AVG_B(src1, ref1, var, avg); - } - - vec = __msa_hadd_s_w(avg, avg); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sse_diff_32x64_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t *diff) { - int32_t ht_cnt; - v16u8 src0, src1, ref0, ref1; - v8i16 avg0 = { 0 }; - v8i16 avg1 = { 0 }; - v4i32 vec, var = { 0 }; - - for (ht_cnt = 16; ht_cnt--;) { - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - } - - vec = __msa_hadd_s_w(avg0, avg0); - vec += __msa_hadd_s_w(avg1, avg1); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sse_diff_64x32_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t *diff) { - int32_t ht_cnt; - v16u8 src0, src1, src2, src3; - v16u8 ref0, ref1, ref2, ref3; - v8i16 avg0 = { 0 }; - v8i16 avg1 = { 0 }; - v4i32 vec, var = { 0 }; - - for (ht_cnt = 16; ht_cnt--;) { - LD_UB4(src_ptr, 16, src0, src1, src2, src3); - src_ptr += src_stride; - LD_UB4(ref_ptr, 16, ref0, ref1, ref2, ref3); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src2, ref2, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - CALC_MSE_AVG_B(src3, ref3, var, avg1); - - LD_UB4(src_ptr, 16, src0, src1, src2, src3); - src_ptr += src_stride; - LD_UB4(ref_ptr, 16, ref0, ref1, ref2, ref3); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src2, ref2, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - CALC_MSE_AVG_B(src3, ref3, var, avg1); - } - - vec = __msa_hadd_s_w(avg0, avg0); - vec += __msa_hadd_s_w(avg1, avg1); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t sse_diff_64x64_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t *diff) { - int32_t ht_cnt; - v16u8 src0, src1, src2, src3; - v16u8 ref0, ref1, ref2, ref3; - v8i16 avg0 = { 0 }; - v8i16 avg1 = { 0 }; - v8i16 avg2 = { 0 }; - v8i16 avg3 = { 0 }; - v4i32 vec, var = { 0 }; - - for (ht_cnt = 32; ht_cnt--;) { - LD_UB4(src_ptr, 16, src0, src1, src2, src3); - src_ptr += src_stride; - LD_UB4(ref_ptr, 16, ref0, ref1, ref2, ref3); - ref_ptr += ref_stride; - - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - CALC_MSE_AVG_B(src2, ref2, var, avg2); - CALC_MSE_AVG_B(src3, ref3, var, avg3); - LD_UB4(src_ptr, 16, src0, src1, src2, src3); - src_ptr += src_stride; - LD_UB4(ref_ptr, 16, ref0, ref1, ref2, ref3); - ref_ptr += ref_stride; - CALC_MSE_AVG_B(src0, ref0, var, avg0); - CALC_MSE_AVG_B(src1, ref1, var, avg1); - CALC_MSE_AVG_B(src2, ref2, var, avg2); - CALC_MSE_AVG_B(src3, ref3, var, avg3); - } - - vec = __msa_hadd_s_w(avg0, avg0); - vec += __msa_hadd_s_w(avg1, avg1); - vec += __msa_hadd_s_w(avg2, avg2); - vec += __msa_hadd_s_w(avg3, avg3); - *diff = HADD_SW_S32(vec); - - return HADD_SW_S32(var); -} - -static uint32_t get_mb_ss_msa(const int16_t *src) { - uint32_t sum, cnt; - v8i16 src0, src1, src2, src3; - v4i32 src0_l, src1_l, src2_l, src3_l; - v4i32 src0_r, src1_r, src2_r, src3_r; - v2i64 sq_src_l = { 0 }; - v2i64 sq_src_r = { 0 }; - - for (cnt = 8; cnt--;) { - LD_SH4(src, 8, src0, src1, src2, src3); - src += 4 * 8; - - UNPCK_SH_SW(src0, src0_l, src0_r); - UNPCK_SH_SW(src1, src1_l, src1_r); - UNPCK_SH_SW(src2, src2_l, src2_r); - UNPCK_SH_SW(src3, src3_l, src3_r); - - DPADD_SD2_SD(src0_l, src0_r, sq_src_l, sq_src_r); - DPADD_SD2_SD(src1_l, src1_r, sq_src_l, sq_src_r); - DPADD_SD2_SD(src2_l, src2_r, sq_src_l, sq_src_r); - DPADD_SD2_SD(src3_l, src3_r, sq_src_l, sq_src_r); - } - - sq_src_l += __msa_splati_d(sq_src_l, 1); - sq_src_r += __msa_splati_d(sq_src_r, 1); - - sum = __msa_copy_s_d(sq_src_l, 0); - sum += __msa_copy_s_d(sq_src_r, 0); - - return sum; -} - -static uint32_t sse_4width_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t height) { - int32_t ht_cnt; - uint32_t src0, src1, src2, src3; - uint32_t ref0, ref1, ref2, ref3; - v16u8 src = { 0 }; - v16u8 ref = { 0 }; - v4i32 var = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LW4(src_ptr, src_stride, src0, src1, src2, src3); - src_ptr += (4 * src_stride); - LW4(ref_ptr, ref_stride, ref0, ref1, ref2, ref3); - ref_ptr += (4 * ref_stride); - - INSERT_W4_UB(src0, src1, src2, src3, src); - INSERT_W4_UB(ref0, ref1, ref2, ref3, ref); - CALC_MSE_B(src, ref, var); - } - - return HADD_SW_S32(var); -} - -static uint32_t sse_8width_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t height) { - int32_t ht_cnt; - v16u8 src0, src1, src2, src3; - v16u8 ref0, ref1, ref2, ref3; - v4i32 var = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LD_UB4(src_ptr, src_stride, src0, src1, src2, src3); - src_ptr += (4 * src_stride); - LD_UB4(ref_ptr, ref_stride, ref0, ref1, ref2, ref3); - ref_ptr += (4 * ref_stride); - - PCKEV_D4_UB(src1, src0, src3, src2, ref1, ref0, ref3, ref2, src0, src1, - ref0, ref1); - CALC_MSE_B(src0, ref0, var); - CALC_MSE_B(src1, ref1, var); - } - - return HADD_SW_S32(var); -} - -static uint32_t sse_16width_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t height) { - int32_t ht_cnt; - v16u8 src, ref; - v4i32 var = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - src = LD_UB(src_ptr); - src_ptr += src_stride; - ref = LD_UB(ref_ptr); - ref_ptr += ref_stride; - CALC_MSE_B(src, ref, var); - - src = LD_UB(src_ptr); - src_ptr += src_stride; - ref = LD_UB(ref_ptr); - ref_ptr += ref_stride; - CALC_MSE_B(src, ref, var); - - src = LD_UB(src_ptr); - src_ptr += src_stride; - ref = LD_UB(ref_ptr); - ref_ptr += ref_stride; - CALC_MSE_B(src, ref, var); - - src = LD_UB(src_ptr); - src_ptr += src_stride; - ref = LD_UB(ref_ptr); - ref_ptr += ref_stride; - CALC_MSE_B(src, ref, var); - } - - return HADD_SW_S32(var); -} - -static uint32_t sse_32width_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t height) { - int32_t ht_cnt; - v16u8 src0, src1, ref0, ref1; - v4i32 var = { 0 }; - - for (ht_cnt = (height >> 2); ht_cnt--;) { - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - CALC_MSE_B(src0, ref0, var); - CALC_MSE_B(src1, ref1, var); - - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - CALC_MSE_B(src0, ref0, var); - CALC_MSE_B(src1, ref1, var); - - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - CALC_MSE_B(src0, ref0, var); - CALC_MSE_B(src1, ref1, var); - - LD_UB2(src_ptr, 16, src0, src1); - src_ptr += src_stride; - LD_UB2(ref_ptr, 16, ref0, ref1); - ref_ptr += ref_stride; - CALC_MSE_B(src0, ref0, var); - CALC_MSE_B(src1, ref1, var); - } - - return HADD_SW_S32(var); -} - -static uint32_t sse_64width_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride, - int32_t height) { - int32_t ht_cnt; - v16u8 src0, src1, src2, src3; - v16u8 ref0, ref1, ref2, ref3; - v4i32 var = { 0 }; - - for (ht_cnt = height >> 1; ht_cnt--;) { - LD_UB4(src_ptr, 16, src0, src1, src2, src3); - src_ptr += src_stride; - LD_UB4(ref_ptr, 16, ref0, ref1, ref2, ref3); - ref_ptr += ref_stride; - CALC_MSE_B(src0, ref0, var); - CALC_MSE_B(src2, ref2, var); - CALC_MSE_B(src1, ref1, var); - CALC_MSE_B(src3, ref3, var); - - LD_UB4(src_ptr, 16, src0, src1, src2, src3); - src_ptr += src_stride; - LD_UB4(ref_ptr, 16, ref0, ref1, ref2, ref3); - ref_ptr += ref_stride; - CALC_MSE_B(src0, ref0, var); - CALC_MSE_B(src2, ref2, var); - CALC_MSE_B(src1, ref1, var); - CALC_MSE_B(src3, ref3, var); - } - - return HADD_SW_S32(var); -} - -uint32_t vpx_get4x4sse_cs_msa(const uint8_t *src_ptr, int32_t src_stride, - const uint8_t *ref_ptr, int32_t ref_stride) { - uint32_t src0, src1, src2, src3; - uint32_t ref0, ref1, ref2, ref3; - v16i8 src = { 0 }; - v16i8 ref = { 0 }; - v4i32 err0 = { 0 }; - - LW4(src_ptr, src_stride, src0, src1, src2, src3); - LW4(ref_ptr, ref_stride, ref0, ref1, ref2, ref3); - INSERT_W4_SB(src0, src1, src2, src3, src); - INSERT_W4_SB(ref0, ref1, ref2, ref3, ref); - CALC_MSE_B(src, ref, err0); - - return HADD_SW_S32(err0); -} - -#define VARIANCE_4Wx4H(sse, diff) VARIANCE_WxH(sse, diff, 4); -#define VARIANCE_4Wx8H(sse, diff) VARIANCE_WxH(sse, diff, 5); -#define VARIANCE_8Wx4H(sse, diff) VARIANCE_WxH(sse, diff, 5); -#define VARIANCE_8Wx8H(sse, diff) VARIANCE_WxH(sse, diff, 6); -#define VARIANCE_8Wx16H(sse, diff) VARIANCE_WxH(sse, diff, 7); -#define VARIANCE_16Wx8H(sse, diff) VARIANCE_WxH(sse, diff, 7); -#define VARIANCE_16Wx16H(sse, diff) VARIANCE_WxH(sse, diff, 8); - -#define VARIANCE_16Wx32H(sse, diff) VARIANCE_LARGE_WxH(sse, diff, 9); -#define VARIANCE_32Wx16H(sse, diff) VARIANCE_LARGE_WxH(sse, diff, 9); -#define VARIANCE_32Wx32H(sse, diff) VARIANCE_LARGE_WxH(sse, diff, 10); -#define VARIANCE_32Wx64H(sse, diff) VARIANCE_LARGE_WxH(sse, diff, 11); -#define VARIANCE_64Wx32H(sse, diff) VARIANCE_LARGE_WxH(sse, diff, 11); -#define VARIANCE_64Wx64H(sse, diff) VARIANCE_LARGE_WxH(sse, diff, 12); - -#define VPX_VARIANCE_WDXHT_MSA(wd, ht) \ - uint32_t vpx_variance##wd##x##ht##_msa( \ - const uint8_t *src, int32_t src_stride, const uint8_t *ref, \ - int32_t ref_stride, uint32_t *sse) { \ - int32_t diff; \ - \ - *sse = \ - sse_diff_##wd##width_msa(src, src_stride, ref, ref_stride, ht, &diff); \ - \ - return VARIANCE_##wd##Wx##ht##H(*sse, diff); \ - } - -VPX_VARIANCE_WDXHT_MSA(4, 4); -VPX_VARIANCE_WDXHT_MSA(4, 8); - -VPX_VARIANCE_WDXHT_MSA(8, 4) -VPX_VARIANCE_WDXHT_MSA(8, 8) -VPX_VARIANCE_WDXHT_MSA(8, 16) - -VPX_VARIANCE_WDXHT_MSA(16, 8) -VPX_VARIANCE_WDXHT_MSA(16, 16) -VPX_VARIANCE_WDXHT_MSA(16, 32) - -VPX_VARIANCE_WDXHT_MSA(32, 16) -VPX_VARIANCE_WDXHT_MSA(32, 32) - -uint32_t vpx_variance32x64_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - uint32_t *sse) { - int32_t diff; - - *sse = sse_diff_32x64_msa(src, src_stride, ref, ref_stride, &diff); - - return VARIANCE_32Wx64H(*sse, diff); -} - -uint32_t vpx_variance64x32_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - uint32_t *sse) { - int32_t diff; - - *sse = sse_diff_64x32_msa(src, src_stride, ref, ref_stride, &diff); - - return VARIANCE_64Wx32H(*sse, diff); -} - -uint32_t vpx_variance64x64_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - uint32_t *sse) { - int32_t diff; - - *sse = sse_diff_64x64_msa(src, src_stride, ref, ref_stride, &diff); - - return VARIANCE_64Wx64H(*sse, diff); -} - -uint32_t vpx_mse8x8_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, uint32_t *sse) { - *sse = sse_8width_msa(src, src_stride, ref, ref_stride, 8); - - return *sse; -} - -uint32_t vpx_mse8x16_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - uint32_t *sse) { - *sse = sse_8width_msa(src, src_stride, ref, ref_stride, 16); - - return *sse; -} - -uint32_t vpx_mse16x8_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - uint32_t *sse) { - *sse = sse_16width_msa(src, src_stride, ref, ref_stride, 8); - - return *sse; -} - -uint32_t vpx_mse16x16_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, - uint32_t *sse) { - *sse = sse_16width_msa(src, src_stride, ref, ref_stride, 16); - - return *sse; -} - -void vpx_get8x8var_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, uint32_t *sse, - int32_t *sum) { - *sse = sse_diff_8width_msa(src, src_stride, ref, ref_stride, 8, sum); -} - -void vpx_get16x16var_msa(const uint8_t *src, int32_t src_stride, - const uint8_t *ref, int32_t ref_stride, uint32_t *sse, - int32_t *sum) { - *sse = sse_diff_16width_msa(src, src_stride, ref, ref_stride, 16, sum); -} - -uint32_t vpx_get_mb_ss_msa(const int16_t *src) { return get_mb_ss_msa(src); } diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_avg_horiz_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_avg_horiz_msa.c deleted file mode 100644 index 5b5a1cbc..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_avg_horiz_msa.c +++ /dev/null @@ -1,716 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/vpx_convolve_msa.h" - -static void common_hz_8t_and_aver_dst_4x4_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter) { - uint32_t tp0, tp1, tp2, tp3; - v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; - v16u8 dst0 = { 0 }, res; - v16u8 mask0, mask1, mask2, mask3; - v8i16 filt, res0, res1; - - mask0 = LD_UB(&mc_filt_mask_arr[16]); - src -= 3; - - /* rearranging filter */ - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, - filt0, filt1, filt2, filt3, res0, res1); - LW4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); - SRARI_H2_SH(res0, res1, FILTER_BITS); - SAT_SH2_SH(res0, res1, 7); - res = PCKEV_XORI128_UB(res0, res1); - res = (v16u8)__msa_aver_u_b(res, dst0); - ST4x4_UB(res, res, 0, 1, 2, 3, dst, dst_stride); -} - -static void common_hz_8t_and_aver_dst_4x8_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter) { - uint32_t tp0, tp1, tp2, tp3; - v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; - v16u8 mask0, mask1, mask2, mask3, res0, res1, res2, res3; - v16u8 dst0 = { 0 }, dst1 = { 0 }; - v8i16 filt, vec0, vec1, vec2, vec3; - - mask0 = LD_UB(&mc_filt_mask_arr[16]); - src -= 3; - - /* rearranging filter */ - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - src += (4 * src_stride); - LW4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); - LW4(dst + 4 * dst_stride, dst_stride, tp0, tp1, tp2, tp3); - INSERT_W4_UB(tp0, tp1, tp2, tp3, dst1); - HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, - filt0, filt1, filt2, filt3, vec0, vec1); - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, - filt0, filt1, filt2, filt3, vec2, vec3); - SRARI_H4_SH(vec0, vec1, vec2, vec3, FILTER_BITS); - SAT_SH4_SH(vec0, vec1, vec2, vec3, 7); - PCKEV_B4_UB(vec0, vec0, vec1, vec1, vec2, vec2, vec3, vec3, res0, res1, res2, - res3); - ILVR_D2_UB(res1, res0, res3, res2, res0, res2); - XORI_B2_128_UB(res0, res2); - AVER_UB2_UB(res0, dst0, res2, dst1, res0, res2); - ST4x8_UB(res0, res2, dst, dst_stride); -} - -static void common_hz_8t_and_aver_dst_4w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int8_t *filter, - int32_t height) { - if (4 == height) { - common_hz_8t_and_aver_dst_4x4_msa(src, src_stride, dst, dst_stride, filter); - } else if (8 == height) { - common_hz_8t_and_aver_dst_4x8_msa(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_hz_8t_and_aver_dst_8w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int8_t *filter, - int32_t height) { - int32_t loop_cnt; - int64_t tp0, tp1, tp2, tp3; - v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; - v16u8 mask0, mask1, mask2, mask3, dst0 = { 0 }, dst1 = { 0 }; - v8i16 filt, out0, out1, out2, out3; - - mask0 = LD_UB(&mc_filt_mask_arr[0]); - src -= 3; - - /* rearranging filter */ - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - src += (4 * src_stride); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filt0, filt1, filt2, filt3, out0, out1, - out2, out3); - LD4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_D2_UB(tp0, tp1, dst0); - INSERT_D2_UB(tp2, tp3, dst1); - SRARI_H4_SH(out0, out1, out2, out3, FILTER_BITS); - SAT_SH4_SH(out0, out1, out2, out3, 7); - CONVERT_UB_AVG_ST8x4_UB(out0, out1, out2, out3, dst0, dst1, dst, - dst_stride); - dst += (4 * dst_stride); - } -} - -static void common_hz_8t_and_aver_dst_16w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - int32_t loop_cnt; - v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; - v16u8 mask0, mask1, mask2, mask3, dst0, dst1; - v8i16 filt, out0, out1, out2, out3; - v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8i16 vec8, vec9, vec10, vec11, vec12, vec13, vec14, vec15; - - mask0 = LD_UB(&mc_filt_mask_arr[0]); - src -= 3; - - /* rearranging filter */ - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - for (loop_cnt = height >> 1; loop_cnt--;) { - LD_SB2(src, src_stride, src0, src2); - LD_SB2(src + 8, src_stride, src1, src3); - src += (2 * src_stride); - - XORI_B4_128_SB(src0, src1, src2, src3); - VSHF_B4_SH(src0, src0, mask0, mask1, mask2, mask3, vec0, vec4, vec8, vec12); - VSHF_B4_SH(src1, src1, mask0, mask1, mask2, mask3, vec1, vec5, vec9, vec13); - VSHF_B4_SH(src2, src2, mask0, mask1, mask2, mask3, vec2, vec6, vec10, - vec14); - VSHF_B4_SH(src3, src3, mask0, mask1, mask2, mask3, vec3, vec7, vec11, - vec15); - DOTP_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - DOTP_SB4_SH(vec8, vec9, vec10, vec11, filt2, filt2, filt2, filt2, vec8, - vec9, vec10, vec11); - DPADD_SB4_SH(vec4, vec5, vec6, vec7, filt1, filt1, filt1, filt1, vec0, vec1, - vec2, vec3); - DPADD_SB4_SH(vec12, vec13, vec14, vec15, filt3, filt3, filt3, filt3, vec8, - vec9, vec10, vec11); - ADDS_SH4_SH(vec0, vec8, vec1, vec9, vec2, vec10, vec3, vec11, out0, out1, - out2, out3); - LD_UB2(dst, dst_stride, dst0, dst1); - SRARI_H4_SH(out0, out1, out2, out3, FILTER_BITS); - SAT_SH4_SH(out0, out1, out2, out3, 7); - PCKEV_XORI128_AVG_ST_UB(out1, out0, dst0, dst); - dst += dst_stride; - PCKEV_XORI128_AVG_ST_UB(out3, out2, dst1, dst); - dst += dst_stride; - } -} - -static void common_hz_8t_and_aver_dst_32w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; - v16u8 dst1, dst2, mask0, mask1, mask2, mask3; - v8i16 filt, out0, out1, out2, out3; - v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8i16 vec8, vec9, vec10, vec11, vec12, vec13, vec14, vec15; - - mask0 = LD_UB(&mc_filt_mask_arr[0]); - src -= 3; - - /* rearranging filter */ - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - for (loop_cnt = height; loop_cnt--;) { - src0 = LD_SB(src); - src2 = LD_SB(src + 16); - src3 = LD_SB(src + 24); - src1 = __msa_sldi_b(src2, src0, 8); - src += src_stride; - - XORI_B4_128_SB(src0, src1, src2, src3); - VSHF_B4_SH(src0, src0, mask0, mask1, mask2, mask3, vec0, vec4, vec8, vec12); - VSHF_B4_SH(src1, src1, mask0, mask1, mask2, mask3, vec1, vec5, vec9, vec13); - VSHF_B4_SH(src2, src2, mask0, mask1, mask2, mask3, vec2, vec6, vec10, - vec14); - VSHF_B4_SH(src3, src3, mask0, mask1, mask2, mask3, vec3, vec7, vec11, - vec15); - DOTP_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - DOTP_SB4_SH(vec8, vec9, vec10, vec11, filt2, filt2, filt2, filt2, vec8, - vec9, vec10, vec11); - DPADD_SB4_SH(vec4, vec5, vec6, vec7, filt1, filt1, filt1, filt1, vec0, vec1, - vec2, vec3); - DPADD_SB4_SH(vec12, vec13, vec14, vec15, filt3, filt3, filt3, filt3, vec8, - vec9, vec10, vec11); - ADDS_SH4_SH(vec0, vec8, vec1, vec9, vec2, vec10, vec3, vec11, out0, out1, - out2, out3); - SRARI_H4_SH(out0, out1, out2, out3, FILTER_BITS); - SAT_SH4_SH(out0, out1, out2, out3, 7); - LD_UB2(dst, 16, dst1, dst2); - PCKEV_XORI128_AVG_ST_UB(out1, out0, dst1, dst); - PCKEV_XORI128_AVG_ST_UB(out3, out2, dst2, dst + 16); - dst += dst_stride; - } -} - -static void common_hz_8t_and_aver_dst_64w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt, cnt; - v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; - v16u8 dst1, dst2, mask0, mask1, mask2, mask3; - v8i16 filt, out0, out1, out2, out3; - v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8i16 vec8, vec9, vec10, vec11, vec12, vec13, vec14, vec15; - - mask0 = LD_UB(&mc_filt_mask_arr[0]); - src -= 3; - - /* rearranging filter */ - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - for (loop_cnt = height; loop_cnt--;) { - for (cnt = 0; cnt < 2; ++cnt) { - src0 = LD_SB(&src[cnt << 5]); - src2 = LD_SB(&src[16 + (cnt << 5)]); - src3 = LD_SB(&src[24 + (cnt << 5)]); - src1 = __msa_sldi_b(src2, src0, 8); - - XORI_B4_128_SB(src0, src1, src2, src3); - VSHF_B4_SH(src0, src0, mask0, mask1, mask2, mask3, vec0, vec4, vec8, - vec12); - VSHF_B4_SH(src1, src1, mask0, mask1, mask2, mask3, vec1, vec5, vec9, - vec13); - VSHF_B4_SH(src2, src2, mask0, mask1, mask2, mask3, vec2, vec6, vec10, - vec14); - VSHF_B4_SH(src3, src3, mask0, mask1, mask2, mask3, vec3, vec7, vec11, - vec15); - DOTP_SB4_SH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, - vec1, vec2, vec3); - DOTP_SB4_SH(vec8, vec9, vec10, vec11, filt2, filt2, filt2, filt2, vec8, - vec9, vec10, vec11); - DPADD_SB4_SH(vec4, vec5, vec6, vec7, filt1, filt1, filt1, filt1, vec0, - vec1, vec2, vec3); - DPADD_SB4_SH(vec12, vec13, vec14, vec15, filt3, filt3, filt3, filt3, vec8, - vec9, vec10, vec11); - ADDS_SH4_SH(vec0, vec8, vec1, vec9, vec2, vec10, vec3, vec11, out0, out1, - out2, out3); - SRARI_H4_SH(out0, out1, out2, out3, FILTER_BITS); - SAT_SH4_SH(out0, out1, out2, out3, 7); - LD_UB2(&dst[cnt << 5], 16, dst1, dst2); - PCKEV_XORI128_AVG_ST_UB(out1, out0, dst1, &dst[cnt << 5]); - PCKEV_XORI128_AVG_ST_UB(out3, out2, dst2, &dst[16 + (cnt << 5)]); - } - - src += src_stride; - dst += dst_stride; - } -} - -static void common_hz_2t_and_aver_dst_4x4_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter) { - uint32_t tp0, tp1, tp2, tp3; - v16i8 src0, src1, src2, src3, mask; - v16u8 filt0, dst0 = { 0 }, vec0, vec1, res; - v8u16 vec2, vec3, filt; - - mask = LD_SB(&mc_filt_mask_arr[16]); - - /* rearranging filter */ - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB4(src, src_stride, src0, src1, src2, src3); - LW4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); - VSHF_B2_UB(src0, src1, src2, src3, mask, mask, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt0, filt0, vec2, vec3); - SRARI_H2_UH(vec2, vec3, FILTER_BITS); - res = (v16u8)__msa_pckev_b((v16i8)vec3, (v16i8)vec2); - res = (v16u8)__msa_aver_u_b(res, dst0); - ST4x4_UB(res, res, 0, 1, 2, 3, dst, dst_stride); -} - -static void common_hz_2t_and_aver_dst_4x8_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter) { - uint32_t tp0, tp1, tp2, tp3; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask; - v16u8 filt0, vec0, vec1, vec2, vec3, res0, res1, res2, res3; - v16u8 dst0 = { 0 }, dst1 = { 0 }; - v8u16 vec4, vec5, vec6, vec7, filt; - - mask = LD_SB(&mc_filt_mask_arr[16]); - - /* rearranging filter */ - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - LW4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); - LW4(dst + 4 * dst_stride, dst_stride, tp0, tp1, tp2, tp3); - INSERT_W4_UB(tp0, tp1, tp2, tp3, dst1); - VSHF_B2_UB(src0, src1, src2, src3, mask, mask, vec0, vec1); - VSHF_B2_UB(src4, src5, src6, src7, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec4, vec5, - vec6, vec7); - SRARI_H4_UH(vec4, vec5, vec6, vec7, FILTER_BITS); - PCKEV_B4_UB(vec4, vec4, vec5, vec5, vec6, vec6, vec7, vec7, res0, res1, res2, - res3); - ILVR_D2_UB(res1, res0, res3, res2, res0, res2); - AVER_UB2_UB(res0, dst0, res2, dst1, res0, res2); - ST4x8_UB(res0, res2, dst, dst_stride); -} - -static void common_hz_2t_and_aver_dst_4w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int8_t *filter, - int32_t height) { - if (4 == height) { - common_hz_2t_and_aver_dst_4x4_msa(src, src_stride, dst, dst_stride, filter); - } else if (8 == height) { - common_hz_2t_and_aver_dst_4x8_msa(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_hz_2t_and_aver_dst_8x4_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter) { - int64_t tp0, tp1, tp2, tp3; - v16i8 src0, src1, src2, src3, mask; - v16u8 filt0, dst0 = { 0 }, dst1 = { 0 }; - v8u16 vec0, vec1, vec2, vec3, filt; - - mask = LD_SB(&mc_filt_mask_arr[0]); - - /* rearranging filter */ - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB4(src, src_stride, src0, src1, src2, src3); - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, FILTER_BITS); - LD4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_D2_UB(tp0, tp1, dst0); - INSERT_D2_UB(tp2, tp3, dst1); - PCKEV_AVG_ST8x4_UB(vec0, vec1, vec2, vec3, dst0, dst1, dst, dst_stride); -} - -static void common_hz_2t_and_aver_dst_8x8mult_msa( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - int64_t tp0, tp1, tp2, tp3; - v16i8 src0, src1, src2, src3, mask; - v16u8 filt0, dst0 = { 0 }, dst1 = { 0 }; - v8u16 vec0, vec1, vec2, vec3, filt; - - mask = LD_SB(&mc_filt_mask_arr[0]); - - /* rearranging filter */ - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, FILTER_BITS); - LD4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_D2_UB(tp0, tp1, dst0); - INSERT_D2_UB(tp2, tp3, dst1); - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - PCKEV_AVG_ST8x4_UB(vec0, vec1, vec2, vec3, dst0, dst1, dst, dst_stride); - dst += (4 * dst_stride); - - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, FILTER_BITS); - LD4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_D2_UB(tp0, tp1, dst0); - INSERT_D2_UB(tp2, tp3, dst1); - PCKEV_AVG_ST8x4_UB(vec0, vec1, vec2, vec3, dst0, dst1, dst, dst_stride); - dst += (4 * dst_stride); - - if (16 == height) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, FILTER_BITS); - LD4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_D2_UB(tp0, tp1, dst0); - INSERT_D2_UB(tp2, tp3, dst1); - LD_SB4(src, src_stride, src0, src1, src2, src3); - PCKEV_AVG_ST8x4_UB(vec0, vec1, vec2, vec3, dst0, dst1, dst, dst_stride); - dst += (4 * dst_stride); - - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, FILTER_BITS); - LD4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_D2_UB(tp0, tp1, dst0); - INSERT_D2_UB(tp2, tp3, dst1); - PCKEV_AVG_ST8x4_UB(vec0, vec1, vec2, vec3, dst0, dst1, dst, dst_stride); - } -} - -static void common_hz_2t_and_aver_dst_8w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int8_t *filter, - int32_t height) { - if (4 == height) { - common_hz_2t_and_aver_dst_8x4_msa(src, src_stride, dst, dst_stride, filter); - } else { - common_hz_2t_and_aver_dst_8x8mult_msa(src, src_stride, dst, dst_stride, - filter, height); - } -} - -static void common_hz_2t_and_aver_dst_16w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask; - v16u8 filt0, dst0, dst1, dst2, dst3; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8u16 res0, res1, res2, res3, res4, res5, res6, res7, filt; - - mask = LD_SB(&mc_filt_mask_arr[0]); - - /* rearranging filter */ - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB4(src, src_stride, src0, src2, src4, src6); - LD_SB4(src + 8, src_stride, src1, src3, src5, src7); - src += (4 * src_stride); - - VSHF_B2_UB(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UB(src2, src2, src3, src3, mask, mask, vec2, vec3); - VSHF_B2_UB(src4, src4, src5, src5, mask, mask, vec4, vec5); - VSHF_B2_UB(src6, src6, src7, src7, mask, mask, vec6, vec7); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, res0, res1, - res2, res3); - DOTP_UB4_UH(vec4, vec5, vec6, vec7, filt0, filt0, filt0, filt0, res4, res5, - res6, res7); - SRARI_H4_UH(res0, res1, res2, res3, FILTER_BITS); - SRARI_H4_UH(res4, res5, res6, res7, FILTER_BITS); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - PCKEV_AVG_ST_UB(res1, res0, dst0, dst); - dst += dst_stride; - PCKEV_AVG_ST_UB(res3, res2, dst1, dst); - dst += dst_stride; - PCKEV_AVG_ST_UB(res5, res4, dst2, dst); - dst += dst_stride; - PCKEV_AVG_ST_UB(res7, res6, dst3, dst); - dst += dst_stride; - - for (loop_cnt = (height >> 2) - 1; loop_cnt--;) { - LD_SB4(src, src_stride, src0, src2, src4, src6); - LD_SB4(src + 8, src_stride, src1, src3, src5, src7); - src += (4 * src_stride); - - VSHF_B2_UB(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UB(src2, src2, src3, src3, mask, mask, vec2, vec3); - VSHF_B2_UB(src4, src4, src5, src5, mask, mask, vec4, vec5); - VSHF_B2_UB(src6, src6, src7, src7, mask, mask, vec6, vec7); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, res0, res1, - res2, res3); - DOTP_UB4_UH(vec4, vec5, vec6, vec7, filt0, filt0, filt0, filt0, res4, res5, - res6, res7); - SRARI_H4_UH(res0, res1, res2, res3, FILTER_BITS); - SRARI_H4_UH(res4, res5, res6, res7, FILTER_BITS); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - PCKEV_AVG_ST_UB(res1, res0, dst0, dst); - dst += dst_stride; - PCKEV_AVG_ST_UB(res3, res2, dst1, dst); - dst += dst_stride; - PCKEV_AVG_ST_UB(res5, res4, dst2, dst); - dst += dst_stride; - PCKEV_AVG_ST_UB(res7, res6, dst3, dst); - dst += dst_stride; - } -} - -static void common_hz_2t_and_aver_dst_32w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask; - v16u8 filt0, dst0, dst1, dst2, dst3; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8u16 res0, res1, res2, res3, res4, res5, res6, res7, filt; - - mask = LD_SB(&mc_filt_mask_arr[0]); - - /* rearranging filter */ - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - for (loop_cnt = (height >> 1); loop_cnt--;) { - src0 = LD_SB(src); - src2 = LD_SB(src + 16); - src3 = LD_SB(src + 24); - src1 = __msa_sldi_b(src2, src0, 8); - src += src_stride; - src4 = LD_SB(src); - src6 = LD_SB(src + 16); - src7 = LD_SB(src + 24); - src5 = __msa_sldi_b(src6, src4, 8); - src += src_stride; - - VSHF_B2_UB(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UB(src2, src2, src3, src3, mask, mask, vec2, vec3); - VSHF_B2_UB(src4, src4, src5, src5, mask, mask, vec4, vec5); - VSHF_B2_UB(src6, src6, src7, src7, mask, mask, vec6, vec7); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, res0, res1, - res2, res3); - DOTP_UB4_UH(vec4, vec5, vec6, vec7, filt0, filt0, filt0, filt0, res4, res5, - res6, res7); - SRARI_H4_UH(res0, res1, res2, res3, FILTER_BITS); - SRARI_H4_UH(res4, res5, res6, res7, FILTER_BITS); - LD_UB2(dst, 16, dst0, dst1); - PCKEV_AVG_ST_UB(res1, res0, dst0, dst); - PCKEV_AVG_ST_UB(res3, res2, dst1, (dst + 16)); - dst += dst_stride; - LD_UB2(dst, 16, dst2, dst3); - PCKEV_AVG_ST_UB(res5, res4, dst2, dst); - PCKEV_AVG_ST_UB(res7, res6, dst3, (dst + 16)); - dst += dst_stride; - } -} - -static void common_hz_2t_and_aver_dst_64w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask; - v16u8 filt0, dst0, dst1, dst2, dst3; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8u16 out0, out1, out2, out3, out4, out5, out6, out7, filt; - - mask = LD_SB(&mc_filt_mask_arr[0]); - - /* rearranging filter */ - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - for (loop_cnt = height; loop_cnt--;) { - LD_SB4(src, 16, src0, src2, src4, src6); - src7 = LD_SB(src + 56); - SLDI_B3_SB(src2, src4, src6, src0, src2, src4, src1, src3, src5, 8); - src += src_stride; - - VSHF_B2_UB(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UB(src2, src2, src3, src3, mask, mask, vec2, vec3); - VSHF_B2_UB(src4, src4, src5, src5, mask, mask, vec4, vec5); - VSHF_B2_UB(src6, src6, src7, src7, mask, mask, vec6, vec7); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, out0, out1, - out2, out3); - DOTP_UB4_UH(vec4, vec5, vec6, vec7, filt0, filt0, filt0, filt0, out4, out5, - out6, out7); - SRARI_H4_UH(out0, out1, out2, out3, FILTER_BITS); - SRARI_H4_UH(out4, out5, out6, out7, FILTER_BITS); - LD_UB4(dst, 16, dst0, dst1, dst2, dst3); - PCKEV_AVG_ST_UB(out1, out0, dst0, dst); - PCKEV_AVG_ST_UB(out3, out2, dst1, dst + 16); - PCKEV_AVG_ST_UB(out5, out4, dst2, dst + 32); - PCKEV_AVG_ST_UB(out7, out6, dst3, dst + 48); - dst += dst_stride; - } -} - -void vpx_convolve8_avg_horiz_msa(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - const int16_t *const filter_x = filter[x0_q4]; - int8_t cnt, filt_hor[8]; - - assert(x_step_q4 == 16); - assert(((const int32_t *)filter_x)[1] != 0x800000); - - for (cnt = 0; cnt < 8; ++cnt) { - filt_hor[cnt] = filter_x[cnt]; - } - - if (vpx_get_filter_taps(filter_x) == 2) { - switch (w) { - case 4: - common_hz_2t_and_aver_dst_4w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], h); - break; - case 8: - common_hz_2t_and_aver_dst_8w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], h); - break; - case 16: - common_hz_2t_and_aver_dst_16w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], h); - break; - case 32: - common_hz_2t_and_aver_dst_32w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], h); - break; - case 64: - common_hz_2t_and_aver_dst_64w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], h); - break; - default: - vpx_convolve8_avg_horiz_c(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } else { - switch (w) { - case 4: - common_hz_8t_and_aver_dst_4w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, h); - break; - case 8: - common_hz_8t_and_aver_dst_8w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, h); - break; - case 16: - common_hz_8t_and_aver_dst_16w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, h); - break; - case 32: - common_hz_8t_and_aver_dst_32w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, h); - break; - case 64: - common_hz_8t_and_aver_dst_64w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, h); - break; - default: - vpx_convolve8_avg_horiz_c(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_avg_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_avg_msa.c deleted file mode 100644 index ba816192..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_avg_msa.c +++ /dev/null @@ -1,611 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/vpx_convolve_msa.h" - -static void common_hv_8ht_8vt_and_aver_dst_4w_msa( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, int32_t height) { - uint32_t loop_cnt; - uint32_t tp0, tp1, tp2, tp3; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - v16u8 dst0 = { 0 }, mask0, mask1, mask2, mask3, res; - v16i8 filt_hz0, filt_hz1, filt_hz2, filt_hz3; - v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; - v8i16 hz_out7, hz_out8, hz_out9, res0, res1, vec0, vec1, vec2, vec3, vec4; - v8i16 filt, filt_vt0, filt_vt1, filt_vt2, filt_vt3; - - mask0 = LD_UB(&mc_filt_mask_arr[16]); - src -= (3 + 3 * src_stride); - - /* rearranging filter */ - filt = LD_SH(filter_horiz); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt_hz0, filt_hz1, filt_hz2, filt_hz3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - LD_SB7(src, src_stride, src0, src1, src2, src3, src4, src5, src6); - XORI_B7_128_SB(src0, src1, src2, src3, src4, src5, src6); - src += (7 * src_stride); - - hz_out0 = HORIZ_8TAP_FILT(src0, src1, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out2 = HORIZ_8TAP_FILT(src2, src3, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out4 = HORIZ_8TAP_FILT(src4, src5, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out5 = HORIZ_8TAP_FILT(src5, src6, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - SLDI_B2_SH(hz_out2, hz_out4, hz_out0, hz_out2, hz_out1, hz_out3, 8); - - filt = LD_SH(filter_vert); - SPLATI_H4_SH(filt, 0, 1, 2, 3, filt_vt0, filt_vt1, filt_vt2, filt_vt3); - - ILVEV_B2_SH(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - vec2 = (v8i16)__msa_ilvev_b((v16i8)hz_out5, (v16i8)hz_out4); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src7, src8, src9, src10); - XORI_B4_128_SB(src7, src8, src9, src10); - src += (4 * src_stride); - - LW4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); - hz_out7 = HORIZ_8TAP_FILT(src7, src8, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out6 = (v8i16)__msa_sldi_b((v16i8)hz_out7, (v16i8)hz_out5, 8); - vec3 = (v8i16)__msa_ilvev_b((v16i8)hz_out7, (v16i8)hz_out6); - res0 = FILT_8TAP_DPADD_S_H(vec0, vec1, vec2, vec3, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - - hz_out9 = HORIZ_8TAP_FILT(src9, src10, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out8 = (v8i16)__msa_sldi_b((v16i8)hz_out9, (v16i8)hz_out7, 8); - vec4 = (v8i16)__msa_ilvev_b((v16i8)hz_out9, (v16i8)hz_out8); - res1 = FILT_8TAP_DPADD_S_H(vec1, vec2, vec3, vec4, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - - SRARI_H2_SH(res0, res1, FILTER_BITS); - SAT_SH2_SH(res0, res1, 7); - res = PCKEV_XORI128_UB(res0, res1); - res = (v16u8)__msa_aver_u_b(res, dst0); - ST4x4_UB(res, res, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - - hz_out5 = hz_out9; - vec0 = vec2; - vec1 = vec3; - vec2 = vec4; - } -} - -static void common_hv_8ht_8vt_and_aver_dst_8w_msa( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, int32_t height) { - uint32_t loop_cnt; - uint64_t tp0, tp1, tp2, tp3; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - v16i8 filt_hz0, filt_hz1, filt_hz2, filt_hz3; - v8i16 filt, filt_vt0, filt_vt1, filt_vt2, filt_vt3; - v16u8 dst0 = { 0 }, dst1 = { 0 }, mask0, mask1, mask2, mask3; - v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; - v8i16 hz_out7, hz_out8, hz_out9, hz_out10, tmp0, tmp1, tmp2, tmp3; - v8i16 out0, out1, out2, out3, out4, out5, out6, out7, out8, out9; - - mask0 = LD_UB(&mc_filt_mask_arr[0]); - src -= (3 + 3 * src_stride); - - /* rearranging filter */ - filt = LD_SH(filter_horiz); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt_hz0, filt_hz1, filt_hz2, filt_hz3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - LD_SB7(src, src_stride, src0, src1, src2, src3, src4, src5, src6); - src += (7 * src_stride); - - XORI_B7_128_SB(src0, src1, src2, src3, src4, src5, src6); - hz_out0 = HORIZ_8TAP_FILT(src0, src0, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out1 = HORIZ_8TAP_FILT(src1, src1, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out2 = HORIZ_8TAP_FILT(src2, src2, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out3 = HORIZ_8TAP_FILT(src3, src3, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out4 = HORIZ_8TAP_FILT(src4, src4, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out5 = HORIZ_8TAP_FILT(src5, src5, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out6 = HORIZ_8TAP_FILT(src6, src6, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - - filt = LD_SH(filter_vert); - SPLATI_H4_SH(filt, 0, 1, 2, 3, filt_vt0, filt_vt1, filt_vt2, filt_vt3); - - ILVEV_B2_SH(hz_out0, hz_out1, hz_out2, hz_out3, out0, out1); - ILVEV_B2_SH(hz_out4, hz_out5, hz_out1, hz_out2, out2, out4); - ILVEV_B2_SH(hz_out3, hz_out4, hz_out5, hz_out6, out5, out6); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src7, src8, src9, src10); - XORI_B4_128_SB(src7, src8, src9, src10); - src += (4 * src_stride); - - LD4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_D2_UB(tp0, tp1, dst0); - INSERT_D2_UB(tp2, tp3, dst1); - - hz_out7 = HORIZ_8TAP_FILT(src7, src7, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - out3 = (v8i16)__msa_ilvev_b((v16i8)hz_out7, (v16i8)hz_out6); - tmp0 = FILT_8TAP_DPADD_S_H(out0, out1, out2, out3, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - - hz_out8 = HORIZ_8TAP_FILT(src8, src8, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - out7 = (v8i16)__msa_ilvev_b((v16i8)hz_out8, (v16i8)hz_out7); - tmp1 = FILT_8TAP_DPADD_S_H(out4, out5, out6, out7, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - - hz_out9 = HORIZ_8TAP_FILT(src9, src9, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - out8 = (v8i16)__msa_ilvev_b((v16i8)hz_out9, (v16i8)hz_out8); - tmp2 = FILT_8TAP_DPADD_S_H(out1, out2, out3, out8, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - - hz_out10 = HORIZ_8TAP_FILT(src10, src10, mask0, mask1, mask2, mask3, - filt_hz0, filt_hz1, filt_hz2, filt_hz3); - out9 = (v8i16)__msa_ilvev_b((v16i8)hz_out10, (v16i8)hz_out9); - tmp3 = FILT_8TAP_DPADD_S_H(out5, out6, out7, out9, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - - SRARI_H4_SH(tmp0, tmp1, tmp2, tmp3, FILTER_BITS); - SAT_SH4_SH(tmp0, tmp1, tmp2, tmp3, 7); - CONVERT_UB_AVG_ST8x4_UB(tmp0, tmp1, tmp2, tmp3, dst0, dst1, dst, - dst_stride); - dst += (4 * dst_stride); - - hz_out6 = hz_out10; - out0 = out2; - out1 = out3; - out2 = out8; - out4 = out6; - out5 = out7; - out6 = out9; - } -} - -static void common_hv_8ht_8vt_and_aver_dst_16w_msa( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 2; multiple8_cnt--;) { - common_hv_8ht_8vt_and_aver_dst_8w_msa(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height); - src += 8; - dst += 8; - } -} - -static void common_hv_8ht_8vt_and_aver_dst_32w_msa( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 4; multiple8_cnt--;) { - common_hv_8ht_8vt_and_aver_dst_8w_msa(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height); - src += 8; - dst += 8; - } -} - -static void common_hv_8ht_8vt_and_aver_dst_64w_msa( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 8; multiple8_cnt--;) { - common_hv_8ht_8vt_and_aver_dst_8w_msa(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height); - src += 8; - dst += 8; - } -} - -static void common_hv_2ht_2vt_and_aver_dst_4x4_msa( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert) { - uint32_t tp0, tp1, tp2, tp3; - v16i8 src0, src1, src2, src3, src4, mask; - v16u8 filt_hz, filt_vt, vec0, vec1; - v16u8 dst0 = { 0 }, out; - v8u16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, tmp0, tmp1, filt; - - mask = LD_SB(&mc_filt_mask_arr[16]); - - /* rearranging filter */ - filt = LD_UH(filter_horiz); - filt_hz = (v16u8)__msa_splati_h((v8i16)filt, 0); - - filt = LD_UH(filter_vert); - filt_vt = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src1, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src2, src3, mask, filt_hz, FILTER_BITS); - hz_out4 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS); - hz_out1 = (v8u16)__msa_sldi_b((v16i8)hz_out2, (v16i8)hz_out0, 8); - hz_out3 = (v8u16)__msa_pckod_d((v2i64)hz_out4, (v2i64)hz_out2); - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - - LW4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - out = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - out = __msa_aver_u_b(out, dst0); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); -} - -static void common_hv_2ht_2vt_and_aver_dst_4x8_msa( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert) { - uint32_t tp0, tp1, tp2, tp3; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, mask; - v16u8 filt_hz, filt_vt, vec0, vec1, vec2, vec3, res0, res1; - v16u8 dst0 = { 0 }, dst1 = { 0 }; - v8u16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; - v8u16 hz_out7, hz_out8, tmp0, tmp1, tmp2, tmp3; - v8i16 filt; - - mask = LD_SB(&mc_filt_mask_arr[16]); - - /* rearranging filter */ - filt = LD_SH(filter_horiz); - filt_hz = (v16u8)__msa_splati_h(filt, 0); - - filt = LD_SH(filter_vert); - filt_vt = (v16u8)__msa_splati_h(filt, 0); - - LD_SB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - src8 = LD_SB(src); - - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src1, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src2, src3, mask, filt_hz, FILTER_BITS); - hz_out4 = HORIZ_2TAP_FILT_UH(src4, src5, mask, filt_hz, FILTER_BITS); - hz_out6 = HORIZ_2TAP_FILT_UH(src6, src7, mask, filt_hz, FILTER_BITS); - hz_out8 = HORIZ_2TAP_FILT_UH(src8, src8, mask, filt_hz, FILTER_BITS); - SLDI_B3_UH(hz_out2, hz_out4, hz_out6, hz_out0, hz_out2, hz_out4, hz_out1, - hz_out3, hz_out5, 8); - hz_out7 = (v8u16)__msa_pckod_d((v2i64)hz_out8, (v2i64)hz_out6); - - LW4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); - LW4(dst + 4 * dst_stride, dst_stride, tp0, tp1, tp2, tp3); - INSERT_W4_UB(tp0, tp1, tp2, tp3, dst1); - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - ILVEV_B2_UB(hz_out4, hz_out5, hz_out6, hz_out7, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt_vt, filt_vt, filt_vt, filt_vt, tmp0, - tmp1, tmp2, tmp3); - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, FILTER_BITS); - PCKEV_B2_UB(tmp1, tmp0, tmp3, tmp2, res0, res1); - AVER_UB2_UB(res0, dst0, res1, dst1, res0, res1); - ST4x8_UB(res0, res1, dst, dst_stride); -} - -static void common_hv_2ht_2vt_and_aver_dst_4w_msa( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, int32_t height) { - if (4 == height) { - common_hv_2ht_2vt_and_aver_dst_4x4_msa(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert); - } else if (8 == height) { - common_hv_2ht_2vt_and_aver_dst_4x8_msa(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert); - } -} - -static void common_hv_2ht_2vt_and_aver_dst_8x4_msa( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert) { - uint64_t tp0, tp1, tp2, tp3; - v16i8 src0, src1, src2, src3, src4, mask; - v16u8 filt_hz, filt_vt, dst0 = { 0 }, dst1 = { 0 }, vec0, vec1, vec2, vec3; - v8u16 hz_out0, hz_out1, tmp0, tmp1, tmp2, tmp3; - v8i16 filt; - - mask = LD_SB(&mc_filt_mask_arr[0]); - - /* rearranging filter */ - filt = LD_SH(filter_horiz); - filt_hz = (v16u8)__msa_splati_h(filt, 0); - - filt = LD_SH(filter_vert); - filt_vt = (v16u8)__msa_splati_h(filt, 0); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - - LD4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_D2_UB(tp0, tp1, dst0); - INSERT_D2_UB(tp2, tp3, dst1); - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS); - hz_out1 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp0 = __msa_dotp_u_h(vec0, filt_vt); - - hz_out0 = HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, FILTER_BITS); - vec1 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp1 = __msa_dotp_u_h(vec1, filt_vt); - - hz_out1 = HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, FILTER_BITS); - vec2 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp2 = __msa_dotp_u_h(vec2, filt_vt); - - hz_out0 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS); - vec3 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp3 = __msa_dotp_u_h(vec3, filt_vt); - - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, FILTER_BITS); - PCKEV_AVG_ST8x4_UB(tmp0, tmp1, tmp2, tmp3, dst0, dst1, dst, dst_stride); -} - -static void common_hv_2ht_2vt_and_aver_dst_8x8mult_msa( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, int32_t height) { - uint32_t loop_cnt; - uint64_t tp0, tp1, tp2, tp3; - v16i8 src0, src1, src2, src3, src4, mask; - v16u8 filt_hz, filt_vt, vec0, dst0 = { 0 }, dst1 = { 0 }; - v8u16 hz_out0, hz_out1, tmp0, tmp1, tmp2, tmp3; - v8i16 filt; - - mask = LD_SB(&mc_filt_mask_arr[0]); - - /* rearranging filter */ - filt = LD_SH(filter_horiz); - filt_hz = (v16u8)__msa_splati_h(filt, 0); - - filt = LD_SH(filter_vert); - filt_vt = (v16u8)__msa_splati_h(filt, 0); - - src0 = LD_SB(src); - src += src_stride; - - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - - hz_out1 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp0 = __msa_dotp_u_h(vec0, filt_vt); - - hz_out0 = HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, FILTER_BITS); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp1 = __msa_dotp_u_h(vec0, filt_vt); - - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - - hz_out1 = HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, FILTER_BITS); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp2 = __msa_dotp_u_h(vec0, filt_vt); - - hz_out0 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp3 = __msa_dotp_u_h(vec0, filt_vt); - - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - LD4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_D2_UB(tp0, tp1, dst0); - INSERT_D2_UB(tp2, tp3, dst1); - PCKEV_AVG_ST8x4_UB(tmp0, tmp1, tmp2, tmp3, dst0, dst1, dst, dst_stride); - dst += (4 * dst_stride); - } -} - -static void common_hv_2ht_2vt_and_aver_dst_8w_msa( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, int32_t height) { - if (4 == height) { - common_hv_2ht_2vt_and_aver_dst_8x4_msa(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert); - } else { - common_hv_2ht_2vt_and_aver_dst_8x8mult_msa( - src, src_stride, dst, dst_stride, filter_horiz, filter_vert, height); - } -} - -static void common_hv_2ht_2vt_and_aver_dst_16w_msa( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask; - v16u8 filt_hz, filt_vt, vec0, vec1, dst0, dst1, dst2, dst3; - v8u16 hz_out0, hz_out1, hz_out2, hz_out3, tmp0, tmp1; - v8i16 filt; - - mask = LD_SB(&mc_filt_mask_arr[0]); - - /* rearranging filter */ - filt = LD_SH(filter_horiz); - filt_hz = (v16u8)__msa_splati_h(filt, 0); - - filt = LD_SH(filter_vert); - filt_vt = (v16u8)__msa_splati_h(filt, 0); - - LD_SB2(src, 8, src0, src1); - src += src_stride; - - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src2, src4, src6); - LD_SB4(src + 8, src_stride, src1, src3, src5, src7); - src += (4 * src_stride); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - - hz_out1 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS); - hz_out3 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS); - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp1, tmp0, dst0, dst); - dst += dst_stride; - - hz_out0 = HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, FILTER_BITS); - ILVEV_B2_UB(hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp1, tmp0, dst1, dst); - dst += dst_stride; - - hz_out1 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS); - hz_out3 = HORIZ_2TAP_FILT_UH(src5, src5, mask, filt_hz, FILTER_BITS); - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp1, tmp0, dst2, dst); - dst += dst_stride; - - hz_out0 = HORIZ_2TAP_FILT_UH(src6, src6, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src7, src7, mask, filt_hz, FILTER_BITS); - ILVEV_B2_UB(hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp1, tmp0, dst3, dst); - dst += dst_stride; - } -} - -static void common_hv_2ht_2vt_and_aver_dst_32w_msa( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 2; multiple8_cnt--;) { - common_hv_2ht_2vt_and_aver_dst_16w_msa(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height); - src += 16; - dst += 16; - } -} - -static void common_hv_2ht_2vt_and_aver_dst_64w_msa( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 4; multiple8_cnt--;) { - common_hv_2ht_2vt_and_aver_dst_16w_msa(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height); - src += 16; - dst += 16; - } -} - -void vpx_convolve8_avg_msa(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, int x_step_q4, - int y0_q4, int y_step_q4, int w, int h) { - const int16_t *const filter_x = filter[x0_q4]; - const int16_t *const filter_y = filter[y0_q4]; - int8_t cnt, filt_hor[8], filt_ver[8]; - - assert(x_step_q4 == 16); - assert(y_step_q4 == 16); - assert(((const int32_t *)filter_x)[1] != 0x800000); - assert(((const int32_t *)filter_y)[1] != 0x800000); - - for (cnt = 0; cnt < 8; ++cnt) { - filt_hor[cnt] = filter_x[cnt]; - filt_ver[cnt] = filter_y[cnt]; - } - - if (vpx_get_filter_taps(filter_x) == 2 && - vpx_get_filter_taps(filter_y) == 2) { - switch (w) { - case 4: - common_hv_2ht_2vt_and_aver_dst_4w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], - &filt_ver[3], h); - break; - case 8: - common_hv_2ht_2vt_and_aver_dst_8w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], - &filt_ver[3], h); - break; - case 16: - common_hv_2ht_2vt_and_aver_dst_16w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, - &filt_hor[3], &filt_ver[3], h); - break; - case 32: - common_hv_2ht_2vt_and_aver_dst_32w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, - &filt_hor[3], &filt_ver[3], h); - break; - case 64: - common_hv_2ht_2vt_and_aver_dst_64w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, - &filt_hor[3], &filt_ver[3], h); - break; - default: - vpx_convolve8_avg_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } else if (vpx_get_filter_taps(filter_x) == 2 || - vpx_get_filter_taps(filter_y) == 2) { - vpx_convolve8_avg_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - } else { - switch (w) { - case 4: - common_hv_8ht_8vt_and_aver_dst_4w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, - filt_ver, h); - break; - case 8: - common_hv_8ht_8vt_and_aver_dst_8w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, - filt_ver, h); - break; - case 16: - common_hv_8ht_8vt_and_aver_dst_16w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, - filt_ver, h); - break; - case 32: - common_hv_8ht_8vt_and_aver_dst_32w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, - filt_ver, h); - break; - case 64: - common_hv_8ht_8vt_and_aver_dst_64w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, - filt_ver, h); - break; - default: - vpx_convolve8_avg_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_avg_vert_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_avg_vert_msa.c deleted file mode 100644 index e6a790df..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_avg_vert_msa.c +++ /dev/null @@ -1,684 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/vpx_convolve_msa.h" - -static void common_vt_8t_and_aver_dst_4w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int8_t *filter, - int32_t height) { - uint32_t loop_cnt; - uint32_t tp0, tp1, tp2, tp3; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - v16u8 dst0 = { 0 }, out; - v16i8 src10_r, src32_r, src54_r, src76_r, src98_r, src21_r, src43_r; - v16i8 src65_r, src87_r, src109_r, src2110, src4332, src6554, src8776; - v16i8 src10998, filt0, filt1, filt2, filt3; - v8i16 filt, out10, out32; - - src -= (3 * src_stride); - - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - LD_SB7(src, src_stride, src0, src1, src2, src3, src4, src5, src6); - src += (7 * src_stride); - - ILVR_B4_SB(src1, src0, src3, src2, src5, src4, src2, src1, src10_r, src32_r, - src54_r, src21_r); - ILVR_B2_SB(src4, src3, src6, src5, src43_r, src65_r); - ILVR_D3_SB(src21_r, src10_r, src43_r, src32_r, src65_r, src54_r, src2110, - src4332, src6554); - XORI_B3_128_SB(src2110, src4332, src6554); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src7, src8, src9, src10); - src += (4 * src_stride); - - LW4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); - ILVR_B4_SB(src7, src6, src8, src7, src9, src8, src10, src9, src76_r, - src87_r, src98_r, src109_r); - ILVR_D2_SB(src87_r, src76_r, src109_r, src98_r, src8776, src10998); - XORI_B2_128_SB(src8776, src10998); - out10 = FILT_8TAP_DPADD_S_H(src2110, src4332, src6554, src8776, filt0, - filt1, filt2, filt3); - out32 = FILT_8TAP_DPADD_S_H(src4332, src6554, src8776, src10998, filt0, - filt1, filt2, filt3); - SRARI_H2_SH(out10, out32, FILTER_BITS); - SAT_SH2_SH(out10, out32, 7); - out = PCKEV_XORI128_UB(out10, out32); - out = __msa_aver_u_b(out, dst0); - - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - - src2110 = src6554; - src4332 = src8776; - src6554 = src10998; - src6 = src10; - } -} - -static void common_vt_8t_and_aver_dst_8w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int8_t *filter, - int32_t height) { - uint32_t loop_cnt; - uint64_t tp0, tp1, tp2, tp3; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - v16u8 dst0 = { 0 }, dst1 = { 0 }; - v16i8 src10_r, src32_r, src54_r, src76_r, src98_r, src21_r, src43_r; - v16i8 src65_r, src87_r, src109_r, filt0, filt1, filt2, filt3; - v8i16 filt, out0, out1, out2, out3; - - src -= (3 * src_stride); - - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - LD_SB7(src, src_stride, src0, src1, src2, src3, src4, src5, src6); - src += (7 * src_stride); - - XORI_B7_128_SB(src0, src1, src2, src3, src4, src5, src6); - ILVR_B4_SB(src1, src0, src3, src2, src5, src4, src2, src1, src10_r, src32_r, - src54_r, src21_r); - ILVR_B2_SB(src4, src3, src6, src5, src43_r, src65_r); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src7, src8, src9, src10); - src += (4 * src_stride); - - LD4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_D2_UB(tp0, tp1, dst0); - INSERT_D2_UB(tp2, tp3, dst1); - XORI_B4_128_SB(src7, src8, src9, src10); - ILVR_B4_SB(src7, src6, src8, src7, src9, src8, src10, src9, src76_r, - src87_r, src98_r, src109_r); - out0 = FILT_8TAP_DPADD_S_H(src10_r, src32_r, src54_r, src76_r, filt0, filt1, - filt2, filt3); - out1 = FILT_8TAP_DPADD_S_H(src21_r, src43_r, src65_r, src87_r, filt0, filt1, - filt2, filt3); - out2 = FILT_8TAP_DPADD_S_H(src32_r, src54_r, src76_r, src98_r, filt0, filt1, - filt2, filt3); - out3 = FILT_8TAP_DPADD_S_H(src43_r, src65_r, src87_r, src109_r, filt0, - filt1, filt2, filt3); - SRARI_H4_SH(out0, out1, out2, out3, FILTER_BITS); - SAT_SH4_SH(out0, out1, out2, out3, 7); - CONVERT_UB_AVG_ST8x4_UB(out0, out1, out2, out3, dst0, dst1, dst, - dst_stride); - dst += (4 * dst_stride); - - src10_r = src54_r; - src32_r = src76_r; - src54_r = src98_r; - src21_r = src65_r; - src43_r = src87_r; - src65_r = src109_r; - src6 = src10; - } -} - -static void common_vt_8t_and_aver_dst_16w_mult_msa( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height, int32_t width) { - const uint8_t *src_tmp; - uint8_t *dst_tmp; - uint32_t loop_cnt, cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - v16i8 src10_r, src32_r, src54_r, src76_r, src98_r, src21_r, src43_r; - v16i8 src65_r, src87_r, src109_r, src10_l, src32_l, src54_l, src76_l; - v16i8 src98_l, src21_l, src43_l, src65_l, src87_l, src109_l; - v16i8 filt0, filt1, filt2, filt3; - v16u8 dst0, dst1, dst2, dst3, tmp0, tmp1, tmp2, tmp3; - v8i16 out0_r, out1_r, out2_r, out3_r, out0_l, out1_l, out2_l, out3_l, filt; - - src -= (3 * src_stride); - - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - for (cnt = (width >> 4); cnt--;) { - src_tmp = src; - dst_tmp = dst; - - LD_SB7(src_tmp, src_stride, src0, src1, src2, src3, src4, src5, src6); - XORI_B7_128_SB(src0, src1, src2, src3, src4, src5, src6); - src_tmp += (7 * src_stride); - - ILVR_B4_SB(src1, src0, src3, src2, src5, src4, src2, src1, src10_r, src32_r, - src54_r, src21_r); - ILVR_B2_SB(src4, src3, src6, src5, src43_r, src65_r); - ILVL_B4_SB(src1, src0, src3, src2, src5, src4, src2, src1, src10_l, src32_l, - src54_l, src21_l); - ILVL_B2_SB(src4, src3, src6, src5, src43_l, src65_l); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src_tmp, src_stride, src7, src8, src9, src10); - src_tmp += (4 * src_stride); - - LD_UB4(dst_tmp, dst_stride, dst0, dst1, dst2, dst3); - XORI_B4_128_SB(src7, src8, src9, src10); - ILVR_B4_SB(src7, src6, src8, src7, src9, src8, src10, src9, src76_r, - src87_r, src98_r, src109_r); - ILVL_B4_SB(src7, src6, src8, src7, src9, src8, src10, src9, src76_l, - src87_l, src98_l, src109_l); - out0_r = FILT_8TAP_DPADD_S_H(src10_r, src32_r, src54_r, src76_r, filt0, - filt1, filt2, filt3); - out1_r = FILT_8TAP_DPADD_S_H(src21_r, src43_r, src65_r, src87_r, filt0, - filt1, filt2, filt3); - out2_r = FILT_8TAP_DPADD_S_H(src32_r, src54_r, src76_r, src98_r, filt0, - filt1, filt2, filt3); - out3_r = FILT_8TAP_DPADD_S_H(src43_r, src65_r, src87_r, src109_r, filt0, - filt1, filt2, filt3); - out0_l = FILT_8TAP_DPADD_S_H(src10_l, src32_l, src54_l, src76_l, filt0, - filt1, filt2, filt3); - out1_l = FILT_8TAP_DPADD_S_H(src21_l, src43_l, src65_l, src87_l, filt0, - filt1, filt2, filt3); - out2_l = FILT_8TAP_DPADD_S_H(src32_l, src54_l, src76_l, src98_l, filt0, - filt1, filt2, filt3); - out3_l = FILT_8TAP_DPADD_S_H(src43_l, src65_l, src87_l, src109_l, filt0, - filt1, filt2, filt3); - SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, FILTER_BITS); - SRARI_H4_SH(out0_l, out1_l, out2_l, out3_l, FILTER_BITS); - SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); - SAT_SH4_SH(out0_l, out1_l, out2_l, out3_l, 7); - PCKEV_B4_UB(out0_l, out0_r, out1_l, out1_r, out2_l, out2_r, out3_l, - out3_r, tmp0, tmp1, tmp2, tmp3); - XORI_B4_128_UB(tmp0, tmp1, tmp2, tmp3); - AVER_UB4_UB(tmp0, dst0, tmp1, dst1, tmp2, dst2, tmp3, dst3, dst0, dst1, - dst2, dst3); - ST_UB4(dst0, dst1, dst2, dst3, dst_tmp, dst_stride); - dst_tmp += (4 * dst_stride); - - src10_r = src54_r; - src32_r = src76_r; - src54_r = src98_r; - src21_r = src65_r; - src43_r = src87_r; - src65_r = src109_r; - src10_l = src54_l; - src32_l = src76_l; - src54_l = src98_l; - src21_l = src65_l; - src43_l = src87_l; - src65_l = src109_l; - src6 = src10; - } - - src += 16; - dst += 16; - } -} - -static void common_vt_8t_and_aver_dst_16w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - common_vt_8t_and_aver_dst_16w_mult_msa(src, src_stride, dst, dst_stride, - filter, height, 16); -} - -static void common_vt_8t_and_aver_dst_32w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - common_vt_8t_and_aver_dst_16w_mult_msa(src, src_stride, dst, dst_stride, - filter, height, 32); -} - -static void common_vt_8t_and_aver_dst_64w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - common_vt_8t_and_aver_dst_16w_mult_msa(src, src_stride, dst, dst_stride, - filter, height, 64); -} - -static void common_vt_2t_and_aver_dst_4x4_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter) { - uint32_t tp0, tp1, tp2, tp3; - v16i8 src0, src1, src2, src3, src4; - v16u8 dst0 = { 0 }, out, filt0, src2110, src4332; - v16i8 src10_r, src32_r, src21_r, src43_r; - v8i16 filt; - v8u16 tmp0, tmp1; - - filt = LD_SH(filter); - filt0 = (v16u8)__msa_splati_h(filt, 0); - - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - src4 = LD_SB(src); - src += src_stride; - - LW4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); - ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, - src32_r, src43_r); - ILVR_D2_UB(src21_r, src10_r, src43_r, src32_r, src2110, src4332); - DOTP_UB2_UH(src2110, src4332, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - - out = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - out = __msa_aver_u_b(out, dst0); - - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); -} - -static void common_vt_2t_and_aver_dst_4x8_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter) { - uint32_t tp0, tp1, tp2, tp3; - v16u8 dst0 = { 0 }, dst1 = { 0 }; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src87_r; - v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; - v16u8 src2110, src4332, src6554, src8776, filt0; - v8u16 tmp0, tmp1, tmp2, tmp3; - v8i16 filt; - - filt = LD_SH(filter); - filt0 = (v16u8)__msa_splati_h(filt, 0); - - LD_SB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - src8 = LD_SB(src); - - LW4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_W4_UB(tp0, tp1, tp2, tp3, dst0); - LW4(dst + 4 * dst_stride, dst_stride, tp0, tp1, tp2, tp3); - INSERT_W4_UB(tp0, tp1, tp2, tp3, dst1); - ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, - src32_r, src43_r); - ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_r, src65_r, - src76_r, src87_r); - ILVR_D4_UB(src21_r, src10_r, src43_r, src32_r, src65_r, src54_r, src87_r, - src76_r, src2110, src4332, src6554, src8776); - DOTP_UB4_UH(src2110, src4332, src6554, src8776, filt0, filt0, filt0, filt0, - tmp0, tmp1, tmp2, tmp3); - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, FILTER_BITS); - PCKEV_B2_UB(tmp1, tmp0, tmp3, tmp2, src2110, src4332); - AVER_UB2_UB(src2110, dst0, src4332, dst1, src2110, src4332); - ST4x8_UB(src2110, src4332, dst, dst_stride); -} - -static void common_vt_2t_and_aver_dst_4w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int8_t *filter, - int32_t height) { - if (4 == height) { - common_vt_2t_and_aver_dst_4x4_msa(src, src_stride, dst, dst_stride, filter); - } else if (8 == height) { - common_vt_2t_and_aver_dst_4x8_msa(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_vt_2t_and_aver_dst_8x4_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter) { - int64_t tp0, tp1, tp2, tp3; - v16u8 src0, src1, src2, src3, src4; - v16u8 dst0 = { 0 }, dst1 = { 0 }, vec0, vec1, vec2, vec3, filt0; - v8u16 tmp0, tmp1, tmp2, tmp3; - v8i16 filt; - - /* rearranging filter_y */ - filt = LD_SH(filter); - filt0 = (v16u8)__msa_splati_h(filt, 0); - - LD_UB5(src, src_stride, src0, src1, src2, src3, src4); - LD4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_D2_UB(tp0, tp1, dst0); - INSERT_D2_UB(tp2, tp3, dst1); - ILVR_B2_UB(src1, src0, src2, src1, vec0, vec1); - ILVR_B2_UB(src3, src2, src4, src3, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, tmp0, tmp1, - tmp2, tmp3); - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, FILTER_BITS); - PCKEV_AVG_ST8x4_UB(tmp0, tmp1, tmp2, tmp3, dst0, dst1, dst, dst_stride); -} - -static void common_vt_2t_and_aver_dst_8x8mult_msa( - const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - int64_t tp0, tp1, tp2, tp3; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16u8 dst0 = { 0 }, dst1 = { 0 }, dst2 = { 0 }, dst3 = { 0 }; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, filt0; - v8u16 tmp0, tmp1, tmp2, tmp3; - v8i16 filt; - - /* rearranging filter_y */ - filt = LD_SH(filter); - filt0 = (v16u8)__msa_splati_h(filt, 0); - - src0 = LD_UB(src); - src += src_stride; - - for (loop_cnt = (height >> 3); loop_cnt--;) { - LD_UB8(src, src_stride, src1, src2, src3, src4, src5, src6, src7, src8); - src += (8 * src_stride); - LD4(dst, dst_stride, tp0, tp1, tp2, tp3); - INSERT_D2_UB(tp0, tp1, dst0); - INSERT_D2_UB(tp2, tp3, dst1); - LD4(dst + 4 * dst_stride, dst_stride, tp0, tp1, tp2, tp3); - INSERT_D2_UB(tp0, tp1, dst2); - INSERT_D2_UB(tp2, tp3, dst3); - - ILVR_B4_UB(src1, src0, src2, src1, src3, src2, src4, src3, vec0, vec1, vec2, - vec3); - ILVR_B4_UB(src5, src4, src6, src5, src7, src6, src8, src7, vec4, vec5, vec6, - vec7); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, tmp0, tmp1, - tmp2, tmp3); - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, FILTER_BITS); - PCKEV_AVG_ST8x4_UB(tmp0, tmp1, tmp2, tmp3, dst0, dst1, dst, dst_stride); - dst += (4 * dst_stride); - - DOTP_UB4_UH(vec4, vec5, vec6, vec7, filt0, filt0, filt0, filt0, tmp0, tmp1, - tmp2, tmp3); - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, FILTER_BITS); - PCKEV_AVG_ST8x4_UB(tmp0, tmp1, tmp2, tmp3, dst2, dst3, dst, dst_stride); - dst += (4 * dst_stride); - - src0 = src8; - } -} - -static void common_vt_2t_and_aver_dst_8w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int8_t *filter, - int32_t height) { - if (4 == height) { - common_vt_2t_and_aver_dst_8x4_msa(src, src_stride, dst, dst_stride, filter); - } else { - common_vt_2t_and_aver_dst_8x8mult_msa(src, src_stride, dst, dst_stride, - filter, height); - } -} - -static void common_vt_2t_and_aver_dst_16w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16u8 src0, src1, src2, src3, src4, dst0, dst1, dst2, dst3, filt0; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8u16 tmp0, tmp1, tmp2, tmp3, filt; - - /* rearranging filter_y */ - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - src0 = LD_UB(src); - src += src_stride; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - ILVR_B2_UB(src1, src0, src2, src1, vec0, vec2); - ILVL_B2_UB(src1, src0, src2, src1, vec1, vec3); - DOTP_UB2_UH(vec0, vec1, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp1, tmp0, dst0, dst); - dst += dst_stride; - - ILVR_B2_UB(src3, src2, src4, src3, vec4, vec6); - ILVL_B2_UB(src3, src2, src4, src3, vec5, vec7); - DOTP_UB2_UH(vec2, vec3, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp3, tmp2, dst1, dst); - dst += dst_stride; - - DOTP_UB2_UH(vec4, vec5, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp1, tmp0, dst2, dst); - dst += dst_stride; - - DOTP_UB2_UH(vec6, vec7, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp3, tmp2, dst3, dst); - dst += dst_stride; - - src0 = src4; - } -} - -static void common_vt_2t_and_aver_dst_32w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9; - v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, filt0; - v8u16 tmp0, tmp1, tmp2, tmp3, filt; - - /* rearranging filter_y */ - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_UB2(src, 16, src0, src5); - src += src_stride; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - ILVR_B2_UB(src1, src0, src2, src1, vec0, vec2); - ILVL_B2_UB(src1, src0, src2, src1, vec1, vec3); - - LD_UB4(src + 16, src_stride, src6, src7, src8, src9); - LD_UB4(dst + 16, dst_stride, dst4, dst5, dst6, dst7); - src += (4 * src_stride); - - DOTP_UB2_UH(vec0, vec1, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp1, tmp0, dst0, dst); - - DOTP_UB2_UH(vec2, vec3, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp3, tmp2, dst1, dst + dst_stride); - - ILVR_B2_UB(src3, src2, src4, src3, vec4, vec6); - ILVL_B2_UB(src3, src2, src4, src3, vec5, vec7); - DOTP_UB2_UH(vec4, vec5, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp1, tmp0, dst2, dst + 2 * dst_stride); - - DOTP_UB2_UH(vec6, vec7, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp3, tmp2, dst3, dst + 3 * dst_stride); - - ILVR_B2_UB(src6, src5, src7, src6, vec0, vec2); - ILVL_B2_UB(src6, src5, src7, src6, vec1, vec3); - DOTP_UB2_UH(vec0, vec1, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp1, tmp0, dst4, dst + 16); - - DOTP_UB2_UH(vec2, vec3, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp3, tmp2, dst5, dst + 16 + dst_stride); - - ILVR_B2_UB(src8, src7, src9, src8, vec4, vec6); - ILVL_B2_UB(src8, src7, src9, src8, vec5, vec7); - DOTP_UB2_UH(vec4, vec5, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp1, tmp0, dst6, dst + 16 + 2 * dst_stride); - - DOTP_UB2_UH(vec6, vec7, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp3, tmp2, dst7, dst + 16 + 3 * dst_stride); - dst += (4 * dst_stride); - - src0 = src4; - src5 = src9; - } -} - -static void common_vt_2t_and_aver_dst_64w_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16u8 src0, src1, src2, src3, src4, src5; - v16u8 src6, src7, src8, src9, src10, src11, filt0; - v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8u16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - v8u16 filt; - - /* rearranging filter_y */ - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_UB4(src, 16, src0, src3, src6, src9); - src += src_stride; - - for (loop_cnt = (height >> 1); loop_cnt--;) { - LD_UB2(src, src_stride, src1, src2); - LD_UB2(dst, dst_stride, dst0, dst1); - LD_UB2(src + 16, src_stride, src4, src5); - LD_UB2(dst + 16, dst_stride, dst2, dst3); - LD_UB2(src + 32, src_stride, src7, src8); - LD_UB2(dst + 32, dst_stride, dst4, dst5); - LD_UB2(src + 48, src_stride, src10, src11); - LD_UB2(dst + 48, dst_stride, dst6, dst7); - src += (2 * src_stride); - - ILVR_B2_UB(src1, src0, src2, src1, vec0, vec2); - ILVL_B2_UB(src1, src0, src2, src1, vec1, vec3); - DOTP_UB2_UH(vec0, vec1, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp1, tmp0, dst0, dst); - - DOTP_UB2_UH(vec2, vec3, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp3, tmp2, dst1, dst + dst_stride); - - ILVR_B2_UB(src4, src3, src5, src4, vec4, vec6); - ILVL_B2_UB(src4, src3, src5, src4, vec5, vec7); - DOTP_UB2_UH(vec4, vec5, filt0, filt0, tmp4, tmp5); - SRARI_H2_UH(tmp4, tmp5, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp5, tmp4, dst2, dst + 16); - - DOTP_UB2_UH(vec6, vec7, filt0, filt0, tmp6, tmp7); - SRARI_H2_UH(tmp6, tmp7, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp7, tmp6, dst3, dst + 16 + dst_stride); - - ILVR_B2_UB(src7, src6, src8, src7, vec0, vec2); - ILVL_B2_UB(src7, src6, src8, src7, vec1, vec3); - DOTP_UB2_UH(vec0, vec1, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp1, tmp0, dst4, dst + 32); - - DOTP_UB2_UH(vec2, vec3, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp3, tmp2, dst5, dst + 32 + dst_stride); - - ILVR_B2_UB(src10, src9, src11, src10, vec4, vec6); - ILVL_B2_UB(src10, src9, src11, src10, vec5, vec7); - DOTP_UB2_UH(vec4, vec5, filt0, filt0, tmp4, tmp5); - SRARI_H2_UH(tmp4, tmp5, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp5, tmp4, dst6, (dst + 48)); - - DOTP_UB2_UH(vec6, vec7, filt0, filt0, tmp6, tmp7); - SRARI_H2_UH(tmp6, tmp7, FILTER_BITS); - PCKEV_AVG_ST_UB(tmp7, tmp6, dst7, dst + 48 + dst_stride); - dst += (2 * dst_stride); - - src0 = src2; - src3 = src5; - src6 = src8; - src9 = src11; - } -} - -void vpx_convolve8_avg_vert_msa(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - const int16_t *const filter_y = filter[y0_q4]; - int8_t cnt, filt_ver[8]; - - assert(y_step_q4 == 16); - assert(((const int32_t *)filter_y)[1] != 0x800000); - - for (cnt = 0; cnt < 8; ++cnt) { - filt_ver[cnt] = filter_y[cnt]; - } - - if (vpx_get_filter_taps(filter_y) == 2) { - switch (w) { - case 4: - common_vt_2t_and_aver_dst_4w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_ver[3], h); - break; - case 8: - common_vt_2t_and_aver_dst_8w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_ver[3], h); - break; - case 16: - common_vt_2t_and_aver_dst_16w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_ver[3], h); - break; - case 32: - common_vt_2t_and_aver_dst_32w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_ver[3], h); - break; - case 64: - common_vt_2t_and_aver_dst_64w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_ver[3], h); - break; - default: - vpx_convolve8_avg_vert_c(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } else { - switch (w) { - case 4: - common_vt_8t_and_aver_dst_4w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_ver, h); - break; - case 8: - common_vt_8t_and_aver_dst_8w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_ver, h); - break; - case 16: - common_vt_8t_and_aver_dst_16w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_ver, h); - - break; - case 32: - common_vt_8t_and_aver_dst_32w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_ver, h); - break; - case 64: - common_vt_8t_and_aver_dst_64w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_ver, h); - break; - default: - vpx_convolve8_avg_vert_c(src, src_stride, dst, dst_stride, filter, - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_horiz_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_horiz_msa.c deleted file mode 100644 index 792c0f70..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_horiz_msa.c +++ /dev/null @@ -1,692 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/vpx_convolve_msa.h" - -static void common_hz_8t_4x4_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter) { - v16u8 mask0, mask1, mask2, mask3, out; - v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; - v8i16 filt, out0, out1; - - mask0 = LD_UB(&mc_filt_mask_arr[16]); - src -= 3; - - /* rearranging filter */ - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, - filt0, filt1, filt2, filt3, out0, out1); - SRARI_H2_SH(out0, out1, FILTER_BITS); - SAT_SH2_SH(out0, out1, 7); - out = PCKEV_XORI128_UB(out0, out1); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); -} - -static void common_hz_8t_4x8_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter) { - v16i8 filt0, filt1, filt2, filt3; - v16i8 src0, src1, src2, src3; - v16u8 mask0, mask1, mask2, mask3, out; - v8i16 filt, out0, out1, out2, out3; - - mask0 = LD_UB(&mc_filt_mask_arr[16]); - src -= 3; - - /* rearranging filter */ - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - src += (4 * src_stride); - HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, - filt0, filt1, filt2, filt3, out0, out1); - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, - filt0, filt1, filt2, filt3, out2, out3); - SRARI_H4_SH(out0, out1, out2, out3, FILTER_BITS); - SAT_SH4_SH(out0, out1, out2, out3, 7); - out = PCKEV_XORI128_UB(out0, out1); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - out = PCKEV_XORI128_UB(out2, out3); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); -} - -static void common_hz_8t_4w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - if (4 == height) { - common_hz_8t_4x4_msa(src, src_stride, dst, dst_stride, filter); - } else if (8 == height) { - common_hz_8t_4x8_msa(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_hz_8t_8x4_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter) { - v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; - v16u8 mask0, mask1, mask2, mask3, tmp0, tmp1; - v8i16 filt, out0, out1, out2, out3; - - mask0 = LD_UB(&mc_filt_mask_arr[0]); - src -= 3; - - /* rearranging filter */ - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, mask3, - filt0, filt1, filt2, filt3, out0, out1, out2, - out3); - SRARI_H4_SH(out0, out1, out2, out3, FILTER_BITS); - SAT_SH4_SH(out0, out1, out2, out3, 7); - tmp0 = PCKEV_XORI128_UB(out0, out1); - tmp1 = PCKEV_XORI128_UB(out2, out3); - ST8x4_UB(tmp0, tmp1, dst, dst_stride); -} - -static void common_hz_8t_8x8mult_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; - v16u8 mask0, mask1, mask2, mask3, tmp0, tmp1; - v8i16 filt, out0, out1, out2, out3; - - mask0 = LD_UB(&mc_filt_mask_arr[0]); - src -= 3; - - /* rearranging filter */ - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - src += (4 * src_stride); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filt0, filt1, filt2, filt3, out0, out1, - out2, out3); - SRARI_H4_SH(out0, out1, out2, out3, FILTER_BITS); - SAT_SH4_SH(out0, out1, out2, out3, 7); - tmp0 = PCKEV_XORI128_UB(out0, out1); - tmp1 = PCKEV_XORI128_UB(out2, out3); - ST8x4_UB(tmp0, tmp1, dst, dst_stride); - dst += (4 * dst_stride); - } -} - -static void common_hz_8t_8w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - if (4 == height) { - common_hz_8t_8x4_msa(src, src_stride, dst, dst_stride, filter); - } else { - common_hz_8t_8x8mult_msa(src, src_stride, dst, dst_stride, filter, height); - } -} - -static void common_hz_8t_16w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; - v16u8 mask0, mask1, mask2, mask3, out; - v8i16 filt, out0, out1, out2, out3; - - mask0 = LD_UB(&mc_filt_mask_arr[0]); - src -= 3; - - /* rearranging filter */ - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - for (loop_cnt = (height >> 1); loop_cnt--;) { - LD_SB2(src, src_stride, src0, src2); - LD_SB2(src + 8, src_stride, src1, src3); - XORI_B4_128_SB(src0, src1, src2, src3); - src += (2 * src_stride); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filt0, filt1, filt2, filt3, out0, out1, - out2, out3); - SRARI_H4_SH(out0, out1, out2, out3, FILTER_BITS); - SAT_SH4_SH(out0, out1, out2, out3, 7); - out = PCKEV_XORI128_UB(out0, out1); - ST_UB(out, dst); - dst += dst_stride; - out = PCKEV_XORI128_UB(out2, out3); - ST_UB(out, dst); - dst += dst_stride; - } -} - -static void common_hz_8t_32w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; - v16u8 mask0, mask1, mask2, mask3, out; - v8i16 filt, out0, out1, out2, out3; - - mask0 = LD_UB(&mc_filt_mask_arr[0]); - src -= 3; - - /* rearranging filter */ - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - for (loop_cnt = (height >> 1); loop_cnt--;) { - src0 = LD_SB(src); - src2 = LD_SB(src + 16); - src3 = LD_SB(src + 24); - src1 = __msa_sldi_b(src2, src0, 8); - src += src_stride; - XORI_B4_128_SB(src0, src1, src2, src3); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filt0, filt1, filt2, filt3, out0, out1, - out2, out3); - SRARI_H4_SH(out0, out1, out2, out3, FILTER_BITS); - SAT_SH4_SH(out0, out1, out2, out3, 7); - - src0 = LD_SB(src); - src2 = LD_SB(src + 16); - src3 = LD_SB(src + 24); - src1 = __msa_sldi_b(src2, src0, 8); - src += src_stride; - - out = PCKEV_XORI128_UB(out0, out1); - ST_UB(out, dst); - out = PCKEV_XORI128_UB(out2, out3); - ST_UB(out, dst + 16); - dst += dst_stride; - - XORI_B4_128_SB(src0, src1, src2, src3); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filt0, filt1, filt2, filt3, out0, out1, - out2, out3); - SRARI_H4_SH(out0, out1, out2, out3, FILTER_BITS); - SAT_SH4_SH(out0, out1, out2, out3, 7); - out = PCKEV_XORI128_UB(out0, out1); - ST_UB(out, dst); - out = PCKEV_XORI128_UB(out2, out3); - ST_UB(out, dst + 16); - dst += dst_stride; - } -} - -static void common_hz_8t_64w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - int32_t loop_cnt; - v16i8 src0, src1, src2, src3, filt0, filt1, filt2, filt3; - v16u8 mask0, mask1, mask2, mask3, out; - v8i16 filt, out0, out1, out2, out3; - - mask0 = LD_UB(&mc_filt_mask_arr[0]); - src -= 3; - - /* rearranging filter */ - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - for (loop_cnt = height; loop_cnt--;) { - src0 = LD_SB(src); - src2 = LD_SB(src + 16); - src3 = LD_SB(src + 24); - src1 = __msa_sldi_b(src2, src0, 8); - - XORI_B4_128_SB(src0, src1, src2, src3); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filt0, filt1, filt2, filt3, out0, out1, - out2, out3); - SRARI_H4_SH(out0, out1, out2, out3, FILTER_BITS); - SAT_SH4_SH(out0, out1, out2, out3, 7); - out = PCKEV_XORI128_UB(out0, out1); - ST_UB(out, dst); - out = PCKEV_XORI128_UB(out2, out3); - ST_UB(out, dst + 16); - - src0 = LD_SB(src + 32); - src2 = LD_SB(src + 48); - src3 = LD_SB(src + 56); - src1 = __msa_sldi_b(src2, src0, 8); - src += src_stride; - - XORI_B4_128_SB(src0, src1, src2, src3); - HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, mask2, - mask3, filt0, filt1, filt2, filt3, out0, out1, - out2, out3); - SRARI_H4_SH(out0, out1, out2, out3, FILTER_BITS); - SAT_SH4_SH(out0, out1, out2, out3, 7); - out = PCKEV_XORI128_UB(out0, out1); - ST_UB(out, dst + 32); - out = PCKEV_XORI128_UB(out2, out3); - ST_UB(out, dst + 48); - dst += dst_stride; - } -} - -static void common_hz_2t_4x4_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter) { - v16i8 src0, src1, src2, src3, mask; - v16u8 filt0, vec0, vec1, res0, res1; - v8u16 vec2, vec3, filt; - - mask = LD_SB(&mc_filt_mask_arr[16]); - - /* rearranging filter */ - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB4(src, src_stride, src0, src1, src2, src3); - VSHF_B2_UB(src0, src1, src2, src3, mask, mask, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt0, filt0, vec2, vec3); - SRARI_H2_UH(vec2, vec3, FILTER_BITS); - PCKEV_B2_UB(vec2, vec2, vec3, vec3, res0, res1); - ST4x4_UB(res0, res1, 0, 1, 0, 1, dst, dst_stride); -} - -static void common_hz_2t_4x8_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter) { - v16u8 vec0, vec1, vec2, vec3, filt0; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask; - v16i8 res0, res1, res2, res3; - v8u16 vec4, vec5, vec6, vec7, filt; - - mask = LD_SB(&mc_filt_mask_arr[16]); - - /* rearranging filter */ - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - VSHF_B2_UB(src0, src1, src2, src3, mask, mask, vec0, vec1); - VSHF_B2_UB(src4, src5, src6, src7, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec4, vec5, - vec6, vec7); - SRARI_H4_UH(vec4, vec5, vec6, vec7, FILTER_BITS); - PCKEV_B4_SB(vec4, vec4, vec5, vec5, vec6, vec6, vec7, vec7, res0, res1, res2, - res3); - ST4x4_UB(res0, res1, 0, 1, 0, 1, dst, dst_stride); - dst += (4 * dst_stride); - ST4x4_UB(res2, res3, 0, 1, 0, 1, dst, dst_stride); -} - -static void common_hz_2t_4w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - if (4 == height) { - common_hz_2t_4x4_msa(src, src_stride, dst, dst_stride, filter); - } else if (8 == height) { - common_hz_2t_4x8_msa(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_hz_2t_8x4_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter) { - v16u8 filt0; - v16i8 src0, src1, src2, src3, mask; - v8u16 vec0, vec1, vec2, vec3, filt; - - mask = LD_SB(&mc_filt_mask_arr[0]); - - /* rearranging filter */ - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB4(src, src_stride, src0, src1, src2, src3); - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, FILTER_BITS); - PCKEV_B2_SB(vec1, vec0, vec3, vec2, src0, src1); - ST8x4_UB(src0, src1, dst, dst_stride); -} - -static void common_hz_2t_8x8mult_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - v16u8 filt0; - v16i8 src0, src1, src2, src3, mask, out0, out1; - v8u16 vec0, vec1, vec2, vec3, filt; - - mask = LD_SB(&mc_filt_mask_arr[0]); - - /* rearranging filter */ - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, FILTER_BITS); - - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - PCKEV_B2_SB(vec1, vec0, vec3, vec2, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += (4 * dst_stride); - - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, FILTER_BITS); - PCKEV_B2_SB(vec1, vec0, vec3, vec2, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += (4 * dst_stride); - - if (16 == height) { - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, FILTER_BITS); - LD_SB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - PCKEV_B2_SB(vec1, vec0, vec3, vec2, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); - - VSHF_B2_UH(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UH(src2, src2, src3, src3, mask, mask, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, vec0, vec1, - vec2, vec3); - SRARI_H4_UH(vec0, vec1, vec2, vec3, FILTER_BITS); - PCKEV_B2_SB(vec1, vec0, vec3, vec2, out0, out1); - ST8x4_UB(out0, out1, dst + 4 * dst_stride, dst_stride); - } -} - -static void common_hz_2t_8w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - if (4 == height) { - common_hz_2t_8x4_msa(src, src_stride, dst, dst_stride, filter); - } else { - common_hz_2t_8x8mult_msa(src, src_stride, dst, dst_stride, filter, height); - } -} - -static void common_hz_2t_16w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask; - v16u8 filt0, vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8u16 out0, out1, out2, out3, out4, out5, out6, out7, filt; - - mask = LD_SB(&mc_filt_mask_arr[0]); - - loop_cnt = (height >> 2) - 1; - - /* rearranging filter */ - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB4(src, src_stride, src0, src2, src4, src6); - LD_SB4(src + 8, src_stride, src1, src3, src5, src7); - src += (4 * src_stride); - - VSHF_B2_UB(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UB(src2, src2, src3, src3, mask, mask, vec2, vec3); - VSHF_B2_UB(src4, src4, src5, src5, mask, mask, vec4, vec5); - VSHF_B2_UB(src6, src6, src7, src7, mask, mask, vec6, vec7); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, out0, out1, - out2, out3); - DOTP_UB4_UH(vec4, vec5, vec6, vec7, filt0, filt0, filt0, filt0, out4, out5, - out6, out7); - SRARI_H4_UH(out0, out1, out2, out3, FILTER_BITS); - SRARI_H4_UH(out4, out5, out6, out7, FILTER_BITS); - PCKEV_ST_SB(out0, out1, dst); - dst += dst_stride; - PCKEV_ST_SB(out2, out3, dst); - dst += dst_stride; - PCKEV_ST_SB(out4, out5, dst); - dst += dst_stride; - PCKEV_ST_SB(out6, out7, dst); - dst += dst_stride; - - for (; loop_cnt--;) { - LD_SB4(src, src_stride, src0, src2, src4, src6); - LD_SB4(src + 8, src_stride, src1, src3, src5, src7); - src += (4 * src_stride); - - VSHF_B2_UB(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UB(src2, src2, src3, src3, mask, mask, vec2, vec3); - VSHF_B2_UB(src4, src4, src5, src5, mask, mask, vec4, vec5); - VSHF_B2_UB(src6, src6, src7, src7, mask, mask, vec6, vec7); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, out0, out1, - out2, out3); - DOTP_UB4_UH(vec4, vec5, vec6, vec7, filt0, filt0, filt0, filt0, out4, out5, - out6, out7); - SRARI_H4_UH(out0, out1, out2, out3, FILTER_BITS); - SRARI_H4_UH(out4, out5, out6, out7, FILTER_BITS); - PCKEV_ST_SB(out0, out1, dst); - dst += dst_stride; - PCKEV_ST_SB(out2, out3, dst); - dst += dst_stride; - PCKEV_ST_SB(out4, out5, dst); - dst += dst_stride; - PCKEV_ST_SB(out6, out7, dst); - dst += dst_stride; - } -} - -static void common_hz_2t_32w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask; - v16u8 filt0, vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8u16 out0, out1, out2, out3, out4, out5, out6, out7, filt; - - mask = LD_SB(&mc_filt_mask_arr[0]); - - /* rearranging filter */ - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - for (loop_cnt = height >> 1; loop_cnt--;) { - src0 = LD_SB(src); - src2 = LD_SB(src + 16); - src3 = LD_SB(src + 24); - src1 = __msa_sldi_b(src2, src0, 8); - src += src_stride; - src4 = LD_SB(src); - src6 = LD_SB(src + 16); - src7 = LD_SB(src + 24); - src5 = __msa_sldi_b(src6, src4, 8); - src += src_stride; - - VSHF_B2_UB(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UB(src2, src2, src3, src3, mask, mask, vec2, vec3); - VSHF_B2_UB(src4, src4, src5, src5, mask, mask, vec4, vec5); - VSHF_B2_UB(src6, src6, src7, src7, mask, mask, vec6, vec7); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, out0, out1, - out2, out3); - DOTP_UB4_UH(vec4, vec5, vec6, vec7, filt0, filt0, filt0, filt0, out4, out5, - out6, out7); - SRARI_H4_UH(out0, out1, out2, out3, FILTER_BITS); - SRARI_H4_UH(out4, out5, out6, out7, FILTER_BITS); - PCKEV_ST_SB(out0, out1, dst); - PCKEV_ST_SB(out2, out3, dst + 16); - dst += dst_stride; - PCKEV_ST_SB(out4, out5, dst); - PCKEV_ST_SB(out6, out7, dst + 16); - dst += dst_stride; - } -} - -static void common_hz_2t_64w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask; - v16u8 filt0, vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7; - v8u16 out0, out1, out2, out3, out4, out5, out6, out7, filt; - - mask = LD_SB(&mc_filt_mask_arr[0]); - - /* rearranging filter */ - filt = LD_UH(filter); - filt0 = (v16u8)__msa_splati_h((v8i16)filt, 0); - - for (loop_cnt = height; loop_cnt--;) { - src0 = LD_SB(src); - src2 = LD_SB(src + 16); - src4 = LD_SB(src + 32); - src6 = LD_SB(src + 48); - src7 = LD_SB(src + 56); - SLDI_B3_SB(src2, src4, src6, src0, src2, src4, src1, src3, src5, 8); - src += src_stride; - - VSHF_B2_UB(src0, src0, src1, src1, mask, mask, vec0, vec1); - VSHF_B2_UB(src2, src2, src3, src3, mask, mask, vec2, vec3); - VSHF_B2_UB(src4, src4, src5, src5, mask, mask, vec4, vec5); - VSHF_B2_UB(src6, src6, src7, src7, mask, mask, vec6, vec7); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, out0, out1, - out2, out3); - DOTP_UB4_UH(vec4, vec5, vec6, vec7, filt0, filt0, filt0, filt0, out4, out5, - out6, out7); - SRARI_H4_UH(out0, out1, out2, out3, FILTER_BITS); - SRARI_H4_UH(out4, out5, out6, out7, FILTER_BITS); - PCKEV_ST_SB(out0, out1, dst); - PCKEV_ST_SB(out2, out3, dst + 16); - PCKEV_ST_SB(out4, out5, dst + 32); - PCKEV_ST_SB(out6, out7, dst + 48); - dst += dst_stride; - } -} - -void vpx_convolve8_horiz_msa(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - const int16_t *const filter_x = filter[x0_q4]; - int8_t cnt, filt_hor[8]; - - assert(x_step_q4 == 16); - assert(((const int32_t *)filter_x)[1] != 0x800000); - - for (cnt = 0; cnt < 8; ++cnt) { - filt_hor[cnt] = filter_x[cnt]; - } - - if (vpx_get_filter_taps(filter_x) == 2) { - switch (w) { - case 4: - common_hz_2t_4w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_hor[3], h); - break; - case 8: - common_hz_2t_8w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_hor[3], h); - break; - case 16: - common_hz_2t_16w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_hor[3], h); - break; - case 32: - common_hz_2t_32w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_hor[3], h); - break; - case 64: - common_hz_2t_64w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_hor[3], h); - break; - default: - vpx_convolve8_horiz_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } else { - switch (w) { - case 4: - common_hz_8t_4w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_hor, h); - break; - case 8: - common_hz_8t_8w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_hor, h); - break; - case 16: - common_hz_8t_16w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_hor, h); - break; - case 32: - common_hz_8t_32w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_hor, h); - break; - case 64: - common_hz_8t_64w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_hor, h); - break; - default: - vpx_convolve8_horiz_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_mmi.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_mmi.c deleted file mode 100644 index cb7bca55..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_mmi.c +++ /dev/null @@ -1,716 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_ports/asmdefs_mmi.h" -#include "vpx_ports/mem.h" - -#define GET_DATA_H_MMI \ - "pmaddhw %[ftmp4], %[ftmp4], %[filter1] \n\t" \ - "pmaddhw %[ftmp5], %[ftmp5], %[filter2] \n\t" \ - "paddw %[ftmp4], %[ftmp4], %[ftmp5] \n\t" \ - "punpckhwd %[ftmp5], %[ftmp4], %[ftmp0] \n\t" \ - "paddw %[ftmp4], %[ftmp4], %[ftmp5] \n\t" \ - "pmaddhw %[ftmp6], %[ftmp6], %[filter1] \n\t" \ - "pmaddhw %[ftmp7], %[ftmp7], %[filter2] \n\t" \ - "paddw %[ftmp6], %[ftmp6], %[ftmp7] \n\t" \ - "punpckhwd %[ftmp7], %[ftmp6], %[ftmp0] \n\t" \ - "paddw %[ftmp6], %[ftmp6], %[ftmp7] \n\t" \ - "punpcklwd %[srcl], %[ftmp4], %[ftmp6] \n\t" \ - "pmaddhw %[ftmp8], %[ftmp8], %[filter1] \n\t" \ - "pmaddhw %[ftmp9], %[ftmp9], %[filter2] \n\t" \ - "paddw %[ftmp8], %[ftmp8], %[ftmp9] \n\t" \ - "punpckhwd %[ftmp9], %[ftmp8], %[ftmp0] \n\t" \ - "paddw %[ftmp8], %[ftmp8], %[ftmp9] \n\t" \ - "pmaddhw %[ftmp10], %[ftmp10], %[filter1] \n\t" \ - "pmaddhw %[ftmp11], %[ftmp11], %[filter2] \n\t" \ - "paddw %[ftmp10], %[ftmp10], %[ftmp11] \n\t" \ - "punpckhwd %[ftmp11], %[ftmp10], %[ftmp0] \n\t" \ - "paddw %[ftmp10], %[ftmp10], %[ftmp11] \n\t" \ - "punpcklwd %[srch], %[ftmp8], %[ftmp10] \n\t" - -#define GET_DATA_V_MMI \ - "punpcklhw %[srcl], %[ftmp4], %[ftmp5] \n\t" \ - "pmaddhw %[srcl], %[srcl], %[filter10] \n\t" \ - "punpcklhw %[ftmp12], %[ftmp6], %[ftmp7] \n\t" \ - "pmaddhw %[ftmp12], %[ftmp12], %[filter32] \n\t" \ - "paddw %[srcl], %[srcl], %[ftmp12] \n\t" \ - "punpcklhw %[ftmp12], %[ftmp8], %[ftmp9] \n\t" \ - "pmaddhw %[ftmp12], %[ftmp12], %[filter54] \n\t" \ - "paddw %[srcl], %[srcl], %[ftmp12] \n\t" \ - "punpcklhw %[ftmp12], %[ftmp10], %[ftmp11] \n\t" \ - "pmaddhw %[ftmp12], %[ftmp12], %[filter76] \n\t" \ - "paddw %[srcl], %[srcl], %[ftmp12] \n\t" \ - "punpckhhw %[srch], %[ftmp4], %[ftmp5] \n\t" \ - "pmaddhw %[srch], %[srch], %[filter10] \n\t" \ - "punpckhhw %[ftmp12], %[ftmp6], %[ftmp7] \n\t" \ - "pmaddhw %[ftmp12], %[ftmp12], %[filter32] \n\t" \ - "paddw %[srch], %[srch], %[ftmp12] \n\t" \ - "punpckhhw %[ftmp12], %[ftmp8], %[ftmp9] \n\t" \ - "pmaddhw %[ftmp12], %[ftmp12], %[filter54] \n\t" \ - "paddw %[srch], %[srch], %[ftmp12] \n\t" \ - "punpckhhw %[ftmp12], %[ftmp10], %[ftmp11] \n\t" \ - "pmaddhw %[ftmp12], %[ftmp12], %[filter76] \n\t" \ - "paddw %[srch], %[srch], %[ftmp12] \n\t" - -/* clang-format off */ -#define ROUND_POWER_OF_TWO_MMI \ - /* Add para[0] */ \ - "lw %[tmp0], 0x00(%[para]) \n\t" \ - MMI_MTC1(%[tmp0], %[ftmp6]) \ - "punpcklwd %[ftmp6], %[ftmp6], %[ftmp6] \n\t" \ - "paddw %[srcl], %[srcl], %[ftmp6] \n\t" \ - "paddw %[srch], %[srch], %[ftmp6] \n\t" \ - /* Arithmetic right shift para[1] bits */ \ - "lw %[tmp0], 0x04(%[para]) \n\t" \ - MMI_MTC1(%[tmp0], %[ftmp5]) \ - "psraw %[srcl], %[srcl], %[ftmp5] \n\t" \ - "psraw %[srch], %[srch], %[ftmp5] \n\t" -/* clang-format on */ - -#define CLIP_PIXEL_MMI \ - /* Staturated operation */ \ - "packsswh %[srcl], %[srcl], %[srch] \n\t" \ - "packushb %[ftmp12], %[srcl], %[ftmp0] \n\t" - -static void convolve_horiz_mmi(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int32_t w, int32_t h) { - const int16_t *filter_x = filter[x0_q4]; - double ftmp[14]; - uint32_t tmp[2]; - uint32_t para[5]; - para[0] = (1 << ((FILTER_BITS)-1)); - para[1] = FILTER_BITS; - src -= SUBPEL_TAPS / 2 - 1; - src_stride -= w; - dst_stride -= w; - (void)x_step_q4; - - /* clang-format off */ - __asm__ volatile( - "move %[tmp1], %[width] \n\t" - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "gsldlc1 %[filter1], 0x03(%[filter]) \n\t" - "gsldrc1 %[filter1], 0x00(%[filter]) \n\t" - "gsldlc1 %[filter2], 0x0b(%[filter]) \n\t" - "gsldrc1 %[filter2], 0x08(%[filter]) \n\t" - "1: \n\t" - /* Get 8 data per row */ - "gsldlc1 %[ftmp5], 0x07(%[src]) \n\t" - "gsldrc1 %[ftmp5], 0x00(%[src]) \n\t" - "gsldlc1 %[ftmp7], 0x08(%[src]) \n\t" - "gsldrc1 %[ftmp7], 0x01(%[src]) \n\t" - "gsldlc1 %[ftmp9], 0x09(%[src]) \n\t" - "gsldrc1 %[ftmp9], 0x02(%[src]) \n\t" - "gsldlc1 %[ftmp11], 0x0A(%[src]) \n\t" - "gsldrc1 %[ftmp11], 0x03(%[src]) \n\t" - "punpcklbh %[ftmp4], %[ftmp5], %[ftmp0] \n\t" - "punpckhbh %[ftmp5], %[ftmp5], %[ftmp0] \n\t" - "punpcklbh %[ftmp6], %[ftmp7], %[ftmp0] \n\t" - "punpckhbh %[ftmp7], %[ftmp7], %[ftmp0] \n\t" - "punpcklbh %[ftmp8], %[ftmp9], %[ftmp0] \n\t" - "punpckhbh %[ftmp9], %[ftmp9], %[ftmp0] \n\t" - "punpcklbh %[ftmp10], %[ftmp11], %[ftmp0] \n\t" - "punpckhbh %[ftmp11], %[ftmp11], %[ftmp0] \n\t" - MMI_ADDIU(%[width], %[width], -0x04) - /* Get raw data */ - GET_DATA_H_MMI - ROUND_POWER_OF_TWO_MMI - CLIP_PIXEL_MMI - "swc1 %[ftmp12], 0x00(%[dst]) \n\t" - MMI_ADDIU(%[dst], %[dst], 0x04) - MMI_ADDIU(%[src], %[src], 0x04) - /* Loop count */ - "bnez %[width], 1b \n\t" - "move %[width], %[tmp1] \n\t" - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[dst], %[dst], %[dst_stride]) - MMI_ADDIU(%[height], %[height], -0x01) - "bnez %[height], 1b \n\t" - : [srcl]"=&f"(ftmp[0]), [srch]"=&f"(ftmp[1]), - [filter1]"=&f"(ftmp[2]), [filter2]"=&f"(ftmp[3]), - [ftmp0]"=&f"(ftmp[4]), [ftmp4]"=&f"(ftmp[5]), - [ftmp5]"=&f"(ftmp[6]), [ftmp6]"=&f"(ftmp[7]), - [ftmp7]"=&f"(ftmp[8]), [ftmp8]"=&f"(ftmp[9]), - [ftmp9]"=&f"(ftmp[10]), [ftmp10]"=&f"(ftmp[11]), - [ftmp11]"=&f"(ftmp[12]), [ftmp12]"=&f"(ftmp[13]), - [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]), - [src]"+&r"(src), [width]"+&r"(w), - [dst]"+&r"(dst), [height]"+&r"(h) - : [filter]"r"(filter_x), [para]"r"(para), - [src_stride]"r"((mips_reg)src_stride), - [dst_stride]"r"((mips_reg)dst_stride) - : "memory" - ); - /* clang-format on */ -} - -static void convolve_vert_mmi(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int y0_q4, - int y_step_q4, int32_t w, int32_t h) { - const int16_t *filter_y = filter[y0_q4]; - double ftmp[16]; - uint32_t tmp[1]; - uint32_t para[2]; - ptrdiff_t addr = src_stride; - para[0] = (1 << ((FILTER_BITS)-1)); - para[1] = FILTER_BITS; - src -= src_stride * (SUBPEL_TAPS / 2 - 1); - src_stride -= w; - dst_stride -= w; - (void)y_step_q4; - - __asm__ volatile( - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "gsldlc1 %[ftmp4], 0x03(%[filter]) \n\t" - "gsldrc1 %[ftmp4], 0x00(%[filter]) \n\t" - "gsldlc1 %[ftmp5], 0x0b(%[filter]) \n\t" - "gsldrc1 %[ftmp5], 0x08(%[filter]) \n\t" - "punpcklwd %[filter10], %[ftmp4], %[ftmp4] \n\t" - "punpckhwd %[filter32], %[ftmp4], %[ftmp4] \n\t" - "punpcklwd %[filter54], %[ftmp5], %[ftmp5] \n\t" - "punpckhwd %[filter76], %[ftmp5], %[ftmp5] \n\t" - "1: \n\t" - /* Get 8 data per column */ - "gsldlc1 %[ftmp4], 0x07(%[src]) \n\t" - "gsldrc1 %[ftmp4], 0x00(%[src]) \n\t" - MMI_ADDU(%[tmp0], %[src], %[addr]) - "gsldlc1 %[ftmp5], 0x07(%[tmp0]) \n\t" - "gsldrc1 %[ftmp5], 0x00(%[tmp0]) \n\t" - MMI_ADDU(%[tmp0], %[tmp0], %[addr]) - "gsldlc1 %[ftmp6], 0x07(%[tmp0]) \n\t" - "gsldrc1 %[ftmp6], 0x00(%[tmp0]) \n\t" - MMI_ADDU(%[tmp0], %[tmp0], %[addr]) - "gsldlc1 %[ftmp7], 0x07(%[tmp0]) \n\t" - "gsldrc1 %[ftmp7], 0x00(%[tmp0]) \n\t" - MMI_ADDU(%[tmp0], %[tmp0], %[addr]) - "gsldlc1 %[ftmp8], 0x07(%[tmp0]) \n\t" - "gsldrc1 %[ftmp8], 0x00(%[tmp0]) \n\t" - MMI_ADDU(%[tmp0], %[tmp0], %[addr]) - "gsldlc1 %[ftmp9], 0x07(%[tmp0]) \n\t" - "gsldrc1 %[ftmp9], 0x00(%[tmp0]) \n\t" - MMI_ADDU(%[tmp0], %[tmp0], %[addr]) - "gsldlc1 %[ftmp10], 0x07(%[tmp0]) \n\t" - "gsldrc1 %[ftmp10], 0x00(%[tmp0]) \n\t" - MMI_ADDU(%[tmp0], %[tmp0], %[addr]) - "gsldlc1 %[ftmp11], 0x07(%[tmp0]) \n\t" - "gsldrc1 %[ftmp11], 0x00(%[tmp0]) \n\t" - "punpcklbh %[ftmp4], %[ftmp4], %[ftmp0] \n\t" - "punpcklbh %[ftmp5], %[ftmp5], %[ftmp0] \n\t" - "punpcklbh %[ftmp6], %[ftmp6], %[ftmp0] \n\t" - "punpcklbh %[ftmp7], %[ftmp7], %[ftmp0] \n\t" - "punpcklbh %[ftmp8], %[ftmp8], %[ftmp0] \n\t" - "punpcklbh %[ftmp9], %[ftmp9], %[ftmp0] \n\t" - "punpcklbh %[ftmp10], %[ftmp10], %[ftmp0] \n\t" - "punpcklbh %[ftmp11], %[ftmp11], %[ftmp0] \n\t" - MMI_ADDIU(%[width], %[width], -0x04) - /* Get raw data */ - GET_DATA_V_MMI - ROUND_POWER_OF_TWO_MMI - CLIP_PIXEL_MMI - "swc1 %[ftmp12], 0x00(%[dst]) \n\t" - MMI_ADDIU(%[dst], %[dst], 0x04) - MMI_ADDIU(%[src], %[src], 0x04) - /* Loop count */ - "bnez %[width], 1b \n\t" - MMI_SUBU(%[width], %[addr], %[src_stride]) - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[dst], %[dst], %[dst_stride]) - MMI_ADDIU(%[height], %[height], -0x01) - "bnez %[height], 1b \n\t" - : [srcl]"=&f"(ftmp[0]), [srch]"=&f"(ftmp[1]), - [filter10]"=&f"(ftmp[2]), [filter32]"=&f"(ftmp[3]), - [filter54]"=&f"(ftmp[4]), [filter76]"=&f"(ftmp[5]), - [ftmp0]"=&f"(ftmp[6]), [ftmp4]"=&f"(ftmp[7]), - [ftmp5]"=&f"(ftmp[8]), [ftmp6]"=&f"(ftmp[9]), - [ftmp7]"=&f"(ftmp[10]), [ftmp8]"=&f"(ftmp[11]), - [ftmp9]"=&f"(ftmp[12]), [ftmp10]"=&f"(ftmp[13]), - [ftmp11]"=&f"(ftmp[14]), [ftmp12]"=&f"(ftmp[15]), - [src]"+&r"(src), [dst]"+&r"(dst), - [width]"+&r"(w), [height]"+&r"(h), - [tmp0]"=&r"(tmp[0]) - : [filter]"r"(filter_y), [para]"r"(para), - [src_stride]"r"((mips_reg)src_stride), - [dst_stride]"r"((mips_reg)dst_stride), - [addr]"r"((mips_reg)addr) - : "memory" - ); -} - -static void convolve_avg_horiz_mmi(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int32_t w, int32_t h) { - const int16_t *filter_x = filter[x0_q4]; - double ftmp[14]; - uint32_t tmp[2]; - uint32_t para[2]; - para[0] = (1 << ((FILTER_BITS)-1)); - para[1] = FILTER_BITS; - src -= SUBPEL_TAPS / 2 - 1; - src_stride -= w; - dst_stride -= w; - (void)x_step_q4; - - __asm__ volatile( - "move %[tmp1], %[width] \n\t" - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "gsldlc1 %[filter1], 0x03(%[filter]) \n\t" - "gsldrc1 %[filter1], 0x00(%[filter]) \n\t" - "gsldlc1 %[filter2], 0x0b(%[filter]) \n\t" - "gsldrc1 %[filter2], 0x08(%[filter]) \n\t" - "1: \n\t" - /* Get 8 data per row */ - "gsldlc1 %[ftmp5], 0x07(%[src]) \n\t" - "gsldrc1 %[ftmp5], 0x00(%[src]) \n\t" - "gsldlc1 %[ftmp7], 0x08(%[src]) \n\t" - "gsldrc1 %[ftmp7], 0x01(%[src]) \n\t" - "gsldlc1 %[ftmp9], 0x09(%[src]) \n\t" - "gsldrc1 %[ftmp9], 0x02(%[src]) \n\t" - "gsldlc1 %[ftmp11], 0x0A(%[src]) \n\t" - "gsldrc1 %[ftmp11], 0x03(%[src]) \n\t" - "punpcklbh %[ftmp4], %[ftmp5], %[ftmp0] \n\t" - "punpckhbh %[ftmp5], %[ftmp5], %[ftmp0] \n\t" - "punpcklbh %[ftmp6], %[ftmp7], %[ftmp0] \n\t" - "punpckhbh %[ftmp7], %[ftmp7], %[ftmp0] \n\t" - "punpcklbh %[ftmp8], %[ftmp9], %[ftmp0] \n\t" - "punpckhbh %[ftmp9], %[ftmp9], %[ftmp0] \n\t" - "punpcklbh %[ftmp10], %[ftmp11], %[ftmp0] \n\t" - "punpckhbh %[ftmp11], %[ftmp11], %[ftmp0] \n\t" - MMI_ADDIU(%[width], %[width], -0x04) - /* Get raw data */ - GET_DATA_H_MMI - ROUND_POWER_OF_TWO_MMI - CLIP_PIXEL_MMI - "punpcklbh %[ftmp12], %[ftmp12], %[ftmp0] \n\t" - "gsldlc1 %[ftmp4], 0x07(%[dst]) \n\t" - "gsldrc1 %[ftmp4], 0x00(%[dst]) \n\t" - "punpcklbh %[ftmp4], %[ftmp4], %[ftmp0] \n\t" - "paddh %[ftmp12], %[ftmp12], %[ftmp4] \n\t" - "li %[tmp0], 0x10001 \n\t" - MMI_MTC1(%[tmp0], %[ftmp5]) - "punpcklhw %[ftmp5], %[ftmp5], %[ftmp5] \n\t" - "paddh %[ftmp12], %[ftmp12], %[ftmp5] \n\t" - "psrah %[ftmp12], %[ftmp12], %[ftmp5] \n\t" - "packushb %[ftmp12], %[ftmp12], %[ftmp0] \n\t" - "swc1 %[ftmp12], 0x00(%[dst]) \n\t" - MMI_ADDIU(%[dst], %[dst], 0x04) - MMI_ADDIU(%[src], %[src], 0x04) - /* Loop count */ - "bnez %[width], 1b \n\t" - "move %[width], %[tmp1] \n\t" - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[dst], %[dst], %[dst_stride]) - MMI_ADDIU(%[height], %[height], -0x01) - "bnez %[height], 1b \n\t" - : [srcl]"=&f"(ftmp[0]), [srch]"=&f"(ftmp[1]), - [filter1]"=&f"(ftmp[2]), [filter2]"=&f"(ftmp[3]), - [ftmp0]"=&f"(ftmp[4]), [ftmp4]"=&f"(ftmp[5]), - [ftmp5]"=&f"(ftmp[6]), [ftmp6]"=&f"(ftmp[7]), - [ftmp7]"=&f"(ftmp[8]), [ftmp8]"=&f"(ftmp[9]), - [ftmp9]"=&f"(ftmp[10]), [ftmp10]"=&f"(ftmp[11]), - [ftmp11]"=&f"(ftmp[12]), [ftmp12]"=&f"(ftmp[13]), - [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]), - [src]"+&r"(src), [width]"+&r"(w), - [dst]"+&r"(dst), [height]"+&r"(h) - : [filter]"r"(filter_x), [para]"r"(para), - [src_stride]"r"((mips_reg)src_stride), - [dst_stride]"r"((mips_reg)dst_stride) - : "memory" - ); -} - -static void convolve_avg_vert_mmi(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int y0_q4, - int y_step_q4, int32_t w, int32_t h) { - const int16_t *filter_y = filter[y0_q4]; - double ftmp[16]; - uint32_t tmp[1]; - uint32_t para[2]; - ptrdiff_t addr = src_stride; - para[0] = (1 << ((FILTER_BITS)-1)); - para[1] = FILTER_BITS; - src -= src_stride * (SUBPEL_TAPS / 2 - 1); - src_stride -= w; - dst_stride -= w; - (void)y_step_q4; - - __asm__ volatile( - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "gsldlc1 %[ftmp4], 0x03(%[filter]) \n\t" - "gsldrc1 %[ftmp4], 0x00(%[filter]) \n\t" - "gsldlc1 %[ftmp5], 0x0b(%[filter]) \n\t" - "gsldrc1 %[ftmp5], 0x08(%[filter]) \n\t" - "punpcklwd %[filter10], %[ftmp4], %[ftmp4] \n\t" - "punpckhwd %[filter32], %[ftmp4], %[ftmp4] \n\t" - "punpcklwd %[filter54], %[ftmp5], %[ftmp5] \n\t" - "punpckhwd %[filter76], %[ftmp5], %[ftmp5] \n\t" - "1: \n\t" - /* Get 8 data per column */ - "gsldlc1 %[ftmp4], 0x07(%[src]) \n\t" - "gsldrc1 %[ftmp4], 0x00(%[src]) \n\t" - MMI_ADDU(%[tmp0], %[src], %[addr]) - "gsldlc1 %[ftmp5], 0x07(%[tmp0]) \n\t" - "gsldrc1 %[ftmp5], 0x00(%[tmp0]) \n\t" - MMI_ADDU(%[tmp0], %[tmp0], %[addr]) - "gsldlc1 %[ftmp6], 0x07(%[tmp0]) \n\t" - "gsldrc1 %[ftmp6], 0x00(%[tmp0]) \n\t" - MMI_ADDU(%[tmp0], %[tmp0], %[addr]) - "gsldlc1 %[ftmp7], 0x07(%[tmp0]) \n\t" - "gsldrc1 %[ftmp7], 0x00(%[tmp0]) \n\t" - MMI_ADDU(%[tmp0], %[tmp0], %[addr]) - "gsldlc1 %[ftmp8], 0x07(%[tmp0]) \n\t" - "gsldrc1 %[ftmp8], 0x00(%[tmp0]) \n\t" - MMI_ADDU(%[tmp0], %[tmp0], %[addr]) - "gsldlc1 %[ftmp9], 0x07(%[tmp0]) \n\t" - "gsldrc1 %[ftmp9], 0x00(%[tmp0]) \n\t" - MMI_ADDU(%[tmp0], %[tmp0], %[addr]) - "gsldlc1 %[ftmp10], 0x07(%[tmp0]) \n\t" - "gsldrc1 %[ftmp10], 0x00(%[tmp0]) \n\t" - MMI_ADDU(%[tmp0], %[tmp0], %[addr]) - "gsldlc1 %[ftmp11], 0x07(%[tmp0]) \n\t" - "gsldrc1 %[ftmp11], 0x00(%[tmp0]) \n\t" - "punpcklbh %[ftmp4], %[ftmp4], %[ftmp0] \n\t" - "punpcklbh %[ftmp5], %[ftmp5], %[ftmp0] \n\t" - "punpcklbh %[ftmp6], %[ftmp6], %[ftmp0] \n\t" - "punpcklbh %[ftmp7], %[ftmp7], %[ftmp0] \n\t" - "punpcklbh %[ftmp8], %[ftmp8], %[ftmp0] \n\t" - "punpcklbh %[ftmp9], %[ftmp9], %[ftmp0] \n\t" - "punpcklbh %[ftmp10], %[ftmp10], %[ftmp0] \n\t" - "punpcklbh %[ftmp11], %[ftmp11], %[ftmp0] \n\t" - MMI_ADDIU(%[width], %[width], -0x04) - /* Get raw data */ - GET_DATA_V_MMI - ROUND_POWER_OF_TWO_MMI - CLIP_PIXEL_MMI - "punpcklbh %[ftmp12], %[ftmp12], %[ftmp0] \n\t" - "gsldlc1 %[ftmp4], 0x07(%[dst]) \n\t" - "gsldrc1 %[ftmp4], 0x00(%[dst]) \n\t" - "punpcklbh %[ftmp4], %[ftmp4], %[ftmp0] \n\t" - "paddh %[ftmp12], %[ftmp12], %[ftmp4] \n\t" - "li %[tmp0], 0x10001 \n\t" - MMI_MTC1(%[tmp0], %[ftmp5]) - "punpcklhw %[ftmp5], %[ftmp5], %[ftmp5] \n\t" - "paddh %[ftmp12], %[ftmp12], %[ftmp5] \n\t" - "psrah %[ftmp12], %[ftmp12], %[ftmp5] \n\t" - "packushb %[ftmp12], %[ftmp12], %[ftmp0] \n\t" - "swc1 %[ftmp12], 0x00(%[dst]) \n\t" - MMI_ADDIU(%[dst], %[dst], 0x04) - MMI_ADDIU(%[src], %[src], 0x04) - /* Loop count */ - "bnez %[width], 1b \n\t" - MMI_SUBU(%[width], %[addr], %[src_stride]) - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDU(%[dst], %[dst], %[dst_stride]) - MMI_ADDIU(%[height], %[height], -0x01) - "bnez %[height], 1b \n\t" - : [srcl]"=&f"(ftmp[0]), [srch]"=&f"(ftmp[1]), - [filter10]"=&f"(ftmp[2]), [filter32]"=&f"(ftmp[3]), - [filter54]"=&f"(ftmp[4]), [filter76]"=&f"(ftmp[5]), - [ftmp0]"=&f"(ftmp[6]), [ftmp4]"=&f"(ftmp[7]), - [ftmp5]"=&f"(ftmp[8]), [ftmp6]"=&f"(ftmp[9]), - [ftmp7]"=&f"(ftmp[10]), [ftmp8]"=&f"(ftmp[11]), - [ftmp9]"=&f"(ftmp[12]), [ftmp10]"=&f"(ftmp[13]), - [ftmp11]"=&f"(ftmp[14]), [ftmp12]"=&f"(ftmp[15]), - [src]"+&r"(src), [dst]"+&r"(dst), - [width]"+&r"(w), [height]"+&r"(h), - [tmp0]"=&r"(tmp[0]) - : [filter]"r"(filter_y), [para]"r"(para), - [src_stride]"r"((mips_reg)src_stride), - [dst_stride]"r"((mips_reg)dst_stride), - [addr]"r"((mips_reg)addr) - : "memory" - ); -} - -void vpx_convolve_avg_mmi(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, int x_step_q4, - int y0_q4, int y_step_q4, int w, int h) { - int x, y; - - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - if (w & 0x03) { - for (y = 0; y < h; ++y) { - for (x = 0; x < w; ++x) dst[x] = ROUND_POWER_OF_TWO(dst[x] + src[x], 1); - src += src_stride; - dst += dst_stride; - } - } else { - double ftmp[4]; - uint32_t tmp[2]; - src_stride -= w; - dst_stride -= w; - - __asm__ volatile( - "move %[tmp1], %[width] \n\t" - "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" - "li %[tmp0], 0x10001 \n\t" - MMI_MTC1(%[tmp0], %[ftmp3]) - "punpcklhw %[ftmp3], %[ftmp3], %[ftmp3] \n\t" - "1: \n\t" - "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" - "gsldrc1 %[ftmp1], 0x00(%[src]) \n\t" - "gsldlc1 %[ftmp2], 0x07(%[dst]) \n\t" - "gsldrc1 %[ftmp2], 0x00(%[dst]) \n\t" - "punpcklbh %[ftmp1], %[ftmp1], %[ftmp0] \n\t" - "punpcklbh %[ftmp2], %[ftmp2], %[ftmp0] \n\t" - "paddh %[ftmp1], %[ftmp1], %[ftmp2] \n\t" - "paddh %[ftmp1], %[ftmp1], %[ftmp3] \n\t" - "psrah %[ftmp1], %[ftmp1], %[ftmp3] \n\t" - "packushb %[ftmp1], %[ftmp1], %[ftmp0] \n\t" - "swc1 %[ftmp1], 0x00(%[dst]) \n\t" - MMI_ADDIU(%[width], %[width], -0x04) - MMI_ADDIU(%[dst], %[dst], 0x04) - MMI_ADDIU(%[src], %[src], 0x04) - "bnez %[width], 1b \n\t" - "move %[width], %[tmp1] \n\t" - MMI_ADDU(%[dst], %[dst], %[dst_stride]) - MMI_ADDU(%[src], %[src], %[src_stride]) - MMI_ADDIU(%[height], %[height], -0x01) - "bnez %[height], 1b \n\t" - : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), - [ftmp2]"=&f"(ftmp[2]), [ftmp3]"=&f"(ftmp[3]), - [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]), - [src]"+&r"(src), [dst]"+&r"(dst), - [width]"+&r"(w), [height]"+&r"(h) - : [src_stride]"r"((mips_reg)src_stride), - [dst_stride]"r"((mips_reg)dst_stride) - : "memory" - ); - } -} - -static void convolve_horiz(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *x_filters, int x0_q4, - int x_step_q4, int w, int h) { - int x, y; - src -= SUBPEL_TAPS / 2 - 1; - - for (y = 0; y < h; ++y) { - int x_q4 = x0_q4; - for (x = 0; x < w; ++x) { - const uint8_t *const src_x = &src[x_q4 >> SUBPEL_BITS]; - const int16_t *const x_filter = x_filters[x_q4 & SUBPEL_MASK]; - int k, sum = 0; - for (k = 0; k < SUBPEL_TAPS; ++k) sum += src_x[k] * x_filter[k]; - dst[x] = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)); - x_q4 += x_step_q4; - } - src += src_stride; - dst += dst_stride; - } -} - -static void convolve_vert(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *y_filters, int y0_q4, - int y_step_q4, int w, int h) { - int x, y; - src -= src_stride * (SUBPEL_TAPS / 2 - 1); - - for (x = 0; x < w; ++x) { - int y_q4 = y0_q4; - for (y = 0; y < h; ++y) { - const uint8_t *src_y = &src[(y_q4 >> SUBPEL_BITS) * src_stride]; - const int16_t *const y_filter = y_filters[y_q4 & SUBPEL_MASK]; - int k, sum = 0; - for (k = 0; k < SUBPEL_TAPS; ++k) - sum += src_y[k * src_stride] * y_filter[k]; - dst[y * dst_stride] = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)); - y_q4 += y_step_q4; - } - ++src; - ++dst; - } -} - -static void convolve_avg_vert(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *y_filters, int y0_q4, - int y_step_q4, int w, int h) { - int x, y; - src -= src_stride * (SUBPEL_TAPS / 2 - 1); - - for (x = 0; x < w; ++x) { - int y_q4 = y0_q4; - for (y = 0; y < h; ++y) { - const uint8_t *src_y = &src[(y_q4 >> SUBPEL_BITS) * src_stride]; - const int16_t *const y_filter = y_filters[y_q4 & SUBPEL_MASK]; - int k, sum = 0; - for (k = 0; k < SUBPEL_TAPS; ++k) - sum += src_y[k * src_stride] * y_filter[k]; - dst[y * dst_stride] = ROUND_POWER_OF_TWO( - dst[y * dst_stride] + - clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)), - 1); - y_q4 += y_step_q4; - } - ++src; - ++dst; - } -} - -static void convolve_avg_horiz(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *x_filters, int x0_q4, - int x_step_q4, int w, int h) { - int x, y; - src -= SUBPEL_TAPS / 2 - 1; - - for (y = 0; y < h; ++y) { - int x_q4 = x0_q4; - for (x = 0; x < w; ++x) { - const uint8_t *const src_x = &src[x_q4 >> SUBPEL_BITS]; - const int16_t *const x_filter = x_filters[x_q4 & SUBPEL_MASK]; - int k, sum = 0; - for (k = 0; k < SUBPEL_TAPS; ++k) sum += src_x[k] * x_filter[k]; - dst[x] = ROUND_POWER_OF_TWO( - dst[x] + clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)), 1); - x_q4 += x_step_q4; - } - src += src_stride; - dst += dst_stride; - } -} - -void vpx_convolve8_mmi(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, - int x0_q4, int32_t x_step_q4, int y0_q4, - int32_t y_step_q4, int32_t w, int32_t h) { - // Note: Fixed size intermediate buffer, temp, places limits on parameters. - // 2d filtering proceeds in 2 steps: - // (1) Interpolate horizontally into an intermediate buffer, temp. - // (2) Interpolate temp vertically to derive the sub-pixel result. - // Deriving the maximum number of rows in the temp buffer (135): - // --Smallest scaling factor is x1/2 ==> y_step_q4 = 32 (Normative). - // --Largest block size is 64x64 pixels. - // --64 rows in the downscaled frame span a distance of (64 - 1) * 32 in the - // original frame (in 1/16th pixel units). - // --Must round-up because block may be located at sub-pixel position. - // --Require an additional SUBPEL_TAPS rows for the 8-tap filter tails. - // --((64 - 1) * 32 + 15) >> 4 + 8 = 135. - // When calling in frame scaling function, the smallest scaling factor is x1/4 - // ==> y_step_q4 = 64. Since w and h are at most 16, the temp buffer is still - // big enough. - uint8_t temp[64 * 135]; - const int intermediate_height = - (((h - 1) * y_step_q4 + y0_q4) >> SUBPEL_BITS) + SUBPEL_TAPS; - - assert(w <= 64); - assert(h <= 64); - assert(y_step_q4 <= 32 || (y_step_q4 <= 64 && h <= 32)); - assert(x_step_q4 <= 64); - - if (w & 0x03) { - convolve_horiz(src - src_stride * (SUBPEL_TAPS / 2 - 1), src_stride, temp, - 64, filter, x0_q4, x_step_q4, w, intermediate_height); - convolve_vert(temp + 64 * (SUBPEL_TAPS / 2 - 1), 64, dst, dst_stride, - filter, y0_q4, y_step_q4, w, h); - } else { - convolve_horiz_mmi(src - src_stride * (SUBPEL_TAPS / 2 - 1), src_stride, - temp, 64, filter, x0_q4, x_step_q4, w, - intermediate_height); - convolve_vert_mmi(temp + 64 * (SUBPEL_TAPS / 2 - 1), 64, dst, dst_stride, - filter, y0_q4, y_step_q4, w, h); - } -} - -void vpx_convolve8_horiz_mmi(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int32_t y_step_q4, - int32_t w, int32_t h) { - (void)y0_q4; - (void)y_step_q4; - if (w & 0x03) - convolve_horiz(src, src_stride, dst, dst_stride, filter, x0_q4, x_step_q4, - w, h); - else - convolve_horiz_mmi(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, w, h); -} - -void vpx_convolve8_vert_mmi(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - (void)x0_q4; - (void)x_step_q4; - if (w & 0x03) - convolve_vert(src, src_stride, dst, dst_stride, filter, y0_q4, y_step_q4, w, - h); - else - convolve_vert_mmi(src, src_stride, dst, dst_stride, filter, y0_q4, - y_step_q4, w, h); -} - -void vpx_convolve8_avg_horiz_mmi(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - (void)y0_q4; - (void)y_step_q4; - if (w & 0x03) - convolve_avg_horiz(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, w, h); - else - convolve_avg_horiz_mmi(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, w, h); -} - -void vpx_convolve8_avg_vert_mmi(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - (void)x0_q4; - (void)x_step_q4; - if (w & 0x03) - convolve_avg_vert(src, src_stride, dst, dst_stride, filter, y0_q4, - y_step_q4, w, h); - else - convolve_avg_vert_mmi(src, src_stride, dst, dst_stride, filter, y0_q4, - y_step_q4, w, h); -} - -void vpx_convolve8_avg_mmi(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int32_t y_step_q4, - int32_t w, int32_t h) { - // Fixed size intermediate buffer places limits on parameters. - DECLARE_ALIGNED(16, uint8_t, temp[64 * 64]); - assert(w <= 64); - assert(h <= 64); - - vpx_convolve8_mmi(src, src_stride, temp, 64, filter, x0_q4, x_step_q4, y0_q4, - y_step_q4, w, h); - vpx_convolve_avg_mmi(temp, 64, dst, dst_stride, NULL, 0, 0, 0, 0, w, h); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_msa.c deleted file mode 100644 index c9421675..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_msa.c +++ /dev/null @@ -1,1227 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/vpx_convolve_msa.h" - -const uint8_t mc_filt_mask_arr[16 * 3] = { - /* 8 width cases */ - 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, - /* 4 width cases */ - 0, 1, 1, 2, 2, 3, 3, 4, 16, 17, 17, 18, 18, 19, 19, 20, - /* 4 width cases */ - 8, 9, 9, 10, 10, 11, 11, 12, 24, 25, 25, 26, 26, 27, 27, 28 -}; - -static void common_hv_8ht_8vt_4w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - v16i8 filt_hz0, filt_hz1, filt_hz2, filt_hz3; - v16u8 mask0, mask1, mask2, mask3, out; - v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; - v8i16 hz_out7, hz_out8, hz_out9, tmp0, tmp1, out0, out1, out2, out3, out4; - v8i16 filt, filt_vt0, filt_vt1, filt_vt2, filt_vt3; - - mask0 = LD_UB(&mc_filt_mask_arr[16]); - src -= (3 + 3 * src_stride); - - /* rearranging filter */ - filt = LD_SH(filter_horiz); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt_hz0, filt_hz1, filt_hz2, filt_hz3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - LD_SB7(src, src_stride, src0, src1, src2, src3, src4, src5, src6); - XORI_B7_128_SB(src0, src1, src2, src3, src4, src5, src6); - src += (7 * src_stride); - - hz_out0 = HORIZ_8TAP_FILT(src0, src1, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out2 = HORIZ_8TAP_FILT(src2, src3, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out4 = HORIZ_8TAP_FILT(src4, src5, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out5 = HORIZ_8TAP_FILT(src5, src6, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - SLDI_B2_SH(hz_out2, hz_out4, hz_out0, hz_out2, hz_out1, hz_out3, 8); - - filt = LD_SH(filter_vert); - SPLATI_H4_SH(filt, 0, 1, 2, 3, filt_vt0, filt_vt1, filt_vt2, filt_vt3); - - ILVEV_B2_SH(hz_out0, hz_out1, hz_out2, hz_out3, out0, out1); - out2 = (v8i16)__msa_ilvev_b((v16i8)hz_out5, (v16i8)hz_out4); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src7, src8, src9, src10); - XORI_B4_128_SB(src7, src8, src9, src10); - src += (4 * src_stride); - - hz_out7 = HORIZ_8TAP_FILT(src7, src8, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out6 = (v8i16)__msa_sldi_b((v16i8)hz_out7, (v16i8)hz_out5, 8); - out3 = (v8i16)__msa_ilvev_b((v16i8)hz_out7, (v16i8)hz_out6); - tmp0 = FILT_8TAP_DPADD_S_H(out0, out1, out2, out3, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - - hz_out9 = HORIZ_8TAP_FILT(src9, src10, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out8 = (v8i16)__msa_sldi_b((v16i8)hz_out9, (v16i8)hz_out7, 8); - out4 = (v8i16)__msa_ilvev_b((v16i8)hz_out9, (v16i8)hz_out8); - tmp1 = FILT_8TAP_DPADD_S_H(out1, out2, out3, out4, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - SRARI_H2_SH(tmp0, tmp1, FILTER_BITS); - SAT_SH2_SH(tmp0, tmp1, 7); - out = PCKEV_XORI128_UB(tmp0, tmp1); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - - hz_out5 = hz_out9; - out0 = out2; - out1 = out3; - out2 = out4; - } -} - -static void common_hv_8ht_8vt_8w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - v16i8 filt_hz0, filt_hz1, filt_hz2, filt_hz3; - v16u8 mask0, mask1, mask2, mask3, vec0, vec1; - v8i16 filt, filt_vt0, filt_vt1, filt_vt2, filt_vt3; - v8i16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; - v8i16 hz_out7, hz_out8, hz_out9, hz_out10, tmp0, tmp1, tmp2, tmp3; - v8i16 out0, out1, out2, out3, out4, out5, out6, out7, out8, out9; - - mask0 = LD_UB(&mc_filt_mask_arr[0]); - src -= (3 + 3 * src_stride); - - /* rearranging filter */ - filt = LD_SH(filter_horiz); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt_hz0, filt_hz1, filt_hz2, filt_hz3); - - mask1 = mask0 + 2; - mask2 = mask0 + 4; - mask3 = mask0 + 6; - - LD_SB7(src, src_stride, src0, src1, src2, src3, src4, src5, src6); - src += (7 * src_stride); - - XORI_B7_128_SB(src0, src1, src2, src3, src4, src5, src6); - hz_out0 = HORIZ_8TAP_FILT(src0, src0, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out1 = HORIZ_8TAP_FILT(src1, src1, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out2 = HORIZ_8TAP_FILT(src2, src2, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out3 = HORIZ_8TAP_FILT(src3, src3, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out4 = HORIZ_8TAP_FILT(src4, src4, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out5 = HORIZ_8TAP_FILT(src5, src5, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - hz_out6 = HORIZ_8TAP_FILT(src6, src6, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - - filt = LD_SH(filter_vert); - SPLATI_H4_SH(filt, 0, 1, 2, 3, filt_vt0, filt_vt1, filt_vt2, filt_vt3); - - ILVEV_B2_SH(hz_out0, hz_out1, hz_out2, hz_out3, out0, out1); - ILVEV_B2_SH(hz_out4, hz_out5, hz_out1, hz_out2, out2, out4); - ILVEV_B2_SH(hz_out3, hz_out4, hz_out5, hz_out6, out5, out6); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src7, src8, src9, src10); - src += (4 * src_stride); - - XORI_B4_128_SB(src7, src8, src9, src10); - - hz_out7 = HORIZ_8TAP_FILT(src7, src7, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - out3 = (v8i16)__msa_ilvev_b((v16i8)hz_out7, (v16i8)hz_out6); - tmp0 = FILT_8TAP_DPADD_S_H(out0, out1, out2, out3, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - - hz_out8 = HORIZ_8TAP_FILT(src8, src8, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - out7 = (v8i16)__msa_ilvev_b((v16i8)hz_out8, (v16i8)hz_out7); - tmp1 = FILT_8TAP_DPADD_S_H(out4, out5, out6, out7, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - - hz_out9 = HORIZ_8TAP_FILT(src9, src9, mask0, mask1, mask2, mask3, filt_hz0, - filt_hz1, filt_hz2, filt_hz3); - out8 = (v8i16)__msa_ilvev_b((v16i8)hz_out9, (v16i8)hz_out8); - tmp2 = FILT_8TAP_DPADD_S_H(out1, out2, out3, out8, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - - hz_out10 = HORIZ_8TAP_FILT(src10, src10, mask0, mask1, mask2, mask3, - filt_hz0, filt_hz1, filt_hz2, filt_hz3); - out9 = (v8i16)__msa_ilvev_b((v16i8)hz_out10, (v16i8)hz_out9); - tmp3 = FILT_8TAP_DPADD_S_H(out5, out6, out7, out9, filt_vt0, filt_vt1, - filt_vt2, filt_vt3); - SRARI_H4_SH(tmp0, tmp1, tmp2, tmp3, FILTER_BITS); - SAT_SH4_SH(tmp0, tmp1, tmp2, tmp3, 7); - vec0 = PCKEV_XORI128_UB(tmp0, tmp1); - vec1 = PCKEV_XORI128_UB(tmp2, tmp3); - ST8x4_UB(vec0, vec1, dst, dst_stride); - dst += (4 * dst_stride); - - hz_out6 = hz_out10; - out0 = out2; - out1 = out3; - out2 = out8; - out4 = out6; - out5 = out7; - out6 = out9; - } -} - -static void common_hv_8ht_8vt_16w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 2; multiple8_cnt--;) { - common_hv_8ht_8vt_8w_msa(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - src += 8; - dst += 8; - } -} - -static void common_hv_8ht_8vt_32w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 4; multiple8_cnt--;) { - common_hv_8ht_8vt_8w_msa(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - src += 8; - dst += 8; - } -} - -static void common_hv_8ht_8vt_64w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 8; multiple8_cnt--;) { - common_hv_8ht_8vt_8w_msa(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - src += 8; - dst += 8; - } -} - -static void common_hv_2ht_2vt_4x4_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, - int8_t *filter_vert) { - v16i8 src0, src1, src2, src3, src4, mask; - v16u8 filt_vt, filt_hz, vec0, vec1, res0, res1; - v8u16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, filt, tmp0, tmp1; - - mask = LD_SB(&mc_filt_mask_arr[16]); - - /* rearranging filter */ - filt = LD_UH(filter_horiz); - filt_hz = (v16u8)__msa_splati_h((v8i16)filt, 0); - - filt = LD_UH(filter_vert); - filt_vt = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src1, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src2, src3, mask, filt_hz, FILTER_BITS); - hz_out4 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS); - hz_out1 = (v8u16)__msa_sldi_b((v16i8)hz_out2, (v16i8)hz_out0, 8); - hz_out3 = (v8u16)__msa_pckod_d((v2i64)hz_out4, (v2i64)hz_out2); - - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_B2_UB(tmp0, tmp0, tmp1, tmp1, res0, res1); - ST4x4_UB(res0, res1, 0, 1, 0, 1, dst, dst_stride); -} - -static void common_hv_2ht_2vt_4x8_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, - int8_t *filter_vert) { - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, mask; - v16i8 res0, res1, res2, res3; - v16u8 filt_hz, filt_vt, vec0, vec1, vec2, vec3; - v8u16 hz_out0, hz_out1, hz_out2, hz_out3, hz_out4, hz_out5, hz_out6; - v8u16 hz_out7, hz_out8, vec4, vec5, vec6, vec7, filt; - - mask = LD_SB(&mc_filt_mask_arr[16]); - - /* rearranging filter */ - filt = LD_UH(filter_horiz); - filt_hz = (v16u8)__msa_splati_h((v8i16)filt, 0); - - filt = LD_UH(filter_vert); - filt_vt = (v16u8)__msa_splati_h((v8i16)filt, 0); - - LD_SB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - src8 = LD_SB(src); - - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src1, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src2, src3, mask, filt_hz, FILTER_BITS); - hz_out4 = HORIZ_2TAP_FILT_UH(src4, src5, mask, filt_hz, FILTER_BITS); - hz_out6 = HORIZ_2TAP_FILT_UH(src6, src7, mask, filt_hz, FILTER_BITS); - hz_out8 = HORIZ_2TAP_FILT_UH(src8, src8, mask, filt_hz, FILTER_BITS); - SLDI_B3_UH(hz_out2, hz_out4, hz_out6, hz_out0, hz_out2, hz_out4, hz_out1, - hz_out3, hz_out5, 8); - hz_out7 = (v8u16)__msa_pckod_d((v2i64)hz_out8, (v2i64)hz_out6); - - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - ILVEV_B2_UB(hz_out4, hz_out5, hz_out6, hz_out7, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt_vt, filt_vt, filt_vt, filt_vt, vec4, - vec5, vec6, vec7); - SRARI_H4_UH(vec4, vec5, vec6, vec7, FILTER_BITS); - PCKEV_B4_SB(vec4, vec4, vec5, vec5, vec6, vec6, vec7, vec7, res0, res1, res2, - res3); - ST4x4_UB(res0, res1, 0, 1, 0, 1, dst, dst_stride); - dst += (4 * dst_stride); - ST4x4_UB(res2, res3, 0, 1, 0, 1, dst, dst_stride); -} - -static void common_hv_2ht_2vt_4w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - if (4 == height) { - common_hv_2ht_2vt_4x4_msa(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert); - } else if (8 == height) { - common_hv_2ht_2vt_4x8_msa(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert); - } -} - -static void common_hv_2ht_2vt_8x4_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, - int8_t *filter_vert) { - v16i8 src0, src1, src2, src3, src4, mask, out0, out1; - v16u8 filt_hz, filt_vt, vec0, vec1, vec2, vec3; - v8u16 hz_out0, hz_out1, tmp0, tmp1, tmp2, tmp3; - v8i16 filt; - - mask = LD_SB(&mc_filt_mask_arr[0]); - - /* rearranging filter */ - filt = LD_SH(filter_horiz); - filt_hz = (v16u8)__msa_splati_h(filt, 0); - - filt = LD_SH(filter_vert); - filt_vt = (v16u8)__msa_splati_h(filt, 0); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS); - hz_out1 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp0 = __msa_dotp_u_h(vec0, filt_vt); - - hz_out0 = HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, FILTER_BITS); - vec1 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp1 = __msa_dotp_u_h(vec1, filt_vt); - - hz_out1 = HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, FILTER_BITS); - vec2 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp2 = __msa_dotp_u_h(vec2, filt_vt); - - hz_out0 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS); - vec3 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp3 = __msa_dotp_u_h(vec3, filt_vt); - - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, FILTER_BITS); - PCKEV_B2_SB(tmp1, tmp0, tmp3, tmp2, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); -} - -static void common_hv_2ht_2vt_8x8mult_msa(const uint8_t *src, - int32_t src_stride, uint8_t *dst, - int32_t dst_stride, - int8_t *filter_horiz, - int8_t *filter_vert, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, mask, out0, out1; - v16u8 filt_hz, filt_vt, vec0; - v8u16 hz_out0, hz_out1, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; - v8i16 filt; - - mask = LD_SB(&mc_filt_mask_arr[0]); - - /* rearranging filter */ - filt = LD_SH(filter_horiz); - filt_hz = (v16u8)__msa_splati_h(filt, 0); - - filt = LD_SH(filter_vert); - filt_vt = (v16u8)__msa_splati_h(filt, 0); - - src0 = LD_SB(src); - src += src_stride; - - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS); - - for (loop_cnt = (height >> 3); loop_cnt--;) { - LD_SB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - - hz_out1 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp1 = __msa_dotp_u_h(vec0, filt_vt); - - hz_out0 = HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, FILTER_BITS); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp2 = __msa_dotp_u_h(vec0, filt_vt); - - SRARI_H2_UH(tmp1, tmp2, FILTER_BITS); - - hz_out1 = HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, FILTER_BITS); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp3 = __msa_dotp_u_h(vec0, filt_vt); - - hz_out0 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS); - LD_SB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp4 = __msa_dotp_u_h(vec0, filt_vt); - - SRARI_H2_UH(tmp3, tmp4, FILTER_BITS); - PCKEV_B2_SB(tmp2, tmp1, tmp4, tmp3, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += (4 * dst_stride); - - hz_out1 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp5 = __msa_dotp_u_h(vec0, filt_vt); - - hz_out0 = HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, FILTER_BITS); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp6 = __msa_dotp_u_h(vec0, filt_vt); - - hz_out1 = HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, FILTER_BITS); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out1, (v16i8)hz_out0); - tmp7 = __msa_dotp_u_h(vec0, filt_vt); - - hz_out0 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS); - vec0 = (v16u8)__msa_ilvev_b((v16i8)hz_out0, (v16i8)hz_out1); - tmp8 = __msa_dotp_u_h(vec0, filt_vt); - - SRARI_H4_UH(tmp5, tmp6, tmp7, tmp8, FILTER_BITS); - PCKEV_B2_SB(tmp6, tmp5, tmp8, tmp7, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += (4 * dst_stride); - } -} - -static void common_hv_2ht_2vt_8w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - if (4 == height) { - common_hv_2ht_2vt_8x4_msa(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert); - } else { - common_hv_2ht_2vt_8x8mult_msa(src, src_stride, dst, dst_stride, - filter_horiz, filter_vert, height); - } -} - -static void common_hv_2ht_2vt_16w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, mask; - v16u8 filt_hz, filt_vt, vec0, vec1; - v8u16 tmp1, tmp2, hz_out0, hz_out1, hz_out2, hz_out3; - v8i16 filt; - - mask = LD_SB(&mc_filt_mask_arr[0]); - - /* rearranging filter */ - filt = LD_SH(filter_horiz); - filt_hz = (v16u8)__msa_splati_h(filt, 0); - - filt = LD_SH(filter_vert); - filt_vt = (v16u8)__msa_splati_h(filt, 0); - - LD_SB2(src, 8, src0, src1); - src += src_stride; - - hz_out0 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src0, src2, src4, src6); - LD_SB4(src + 8, src_stride, src1, src3, src5, src7); - src += (4 * src_stride); - - hz_out1 = HORIZ_2TAP_FILT_UH(src0, src0, mask, filt_hz, FILTER_BITS); - hz_out3 = HORIZ_2TAP_FILT_UH(src1, src1, mask, filt_hz, FILTER_BITS); - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp1, tmp2); - SRARI_H2_UH(tmp1, tmp2, FILTER_BITS); - PCKEV_ST_SB(tmp1, tmp2, dst); - dst += dst_stride; - - hz_out0 = HORIZ_2TAP_FILT_UH(src2, src2, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src3, src3, mask, filt_hz, FILTER_BITS); - ILVEV_B2_UB(hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp1, tmp2); - SRARI_H2_UH(tmp1, tmp2, FILTER_BITS); - PCKEV_ST_SB(tmp1, tmp2, dst); - dst += dst_stride; - - hz_out1 = HORIZ_2TAP_FILT_UH(src4, src4, mask, filt_hz, FILTER_BITS); - hz_out3 = HORIZ_2TAP_FILT_UH(src5, src5, mask, filt_hz, FILTER_BITS); - ILVEV_B2_UB(hz_out0, hz_out1, hz_out2, hz_out3, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp1, tmp2); - SRARI_H2_UH(tmp1, tmp2, FILTER_BITS); - PCKEV_ST_SB(tmp1, tmp2, dst); - dst += dst_stride; - - hz_out0 = HORIZ_2TAP_FILT_UH(src6, src6, mask, filt_hz, FILTER_BITS); - hz_out2 = HORIZ_2TAP_FILT_UH(src7, src7, mask, filt_hz, FILTER_BITS); - ILVEV_B2_UB(hz_out1, hz_out0, hz_out3, hz_out2, vec0, vec1); - DOTP_UB2_UH(vec0, vec1, filt_vt, filt_vt, tmp1, tmp2); - SRARI_H2_UH(tmp1, tmp2, FILTER_BITS); - PCKEV_ST_SB(tmp1, tmp2, dst); - dst += dst_stride; - } -} - -static void common_hv_2ht_2vt_32w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 2; multiple8_cnt--;) { - common_hv_2ht_2vt_16w_msa(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - src += 16; - dst += 16; - } -} - -static void common_hv_2ht_2vt_64w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter_horiz, int8_t *filter_vert, - int32_t height) { - int32_t multiple8_cnt; - for (multiple8_cnt = 4; multiple8_cnt--;) { - common_hv_2ht_2vt_16w_msa(src, src_stride, dst, dst_stride, filter_horiz, - filter_vert, height); - src += 16; - dst += 16; - } -} - -void vpx_convolve8_msa(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, - int x0_q4, int32_t x_step_q4, int y0_q4, - int32_t y_step_q4, int32_t w, int32_t h) { - const int16_t *const filter_x = filter[x0_q4]; - const int16_t *const filter_y = filter[y0_q4]; - int8_t cnt, filt_hor[8], filt_ver[8]; - - assert(x_step_q4 == 16); - assert(y_step_q4 == 16); - assert(((const int32_t *)filter_x)[1] != 0x800000); - assert(((const int32_t *)filter_y)[1] != 0x800000); - - for (cnt = 0; cnt < 8; ++cnt) { - filt_hor[cnt] = filter_x[cnt]; - filt_ver[cnt] = filter_y[cnt]; - } - - if (vpx_get_filter_taps(filter_x) == 2 && - vpx_get_filter_taps(filter_y) == 2) { - switch (w) { - case 4: - common_hv_2ht_2vt_4w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], - &filt_ver[3], (int32_t)h); - break; - case 8: - common_hv_2ht_2vt_8w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], - &filt_ver[3], (int32_t)h); - break; - case 16: - common_hv_2ht_2vt_16w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], - &filt_ver[3], (int32_t)h); - break; - case 32: - common_hv_2ht_2vt_32w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], - &filt_ver[3], (int32_t)h); - break; - case 64: - common_hv_2ht_2vt_64w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, &filt_hor[3], - &filt_ver[3], (int32_t)h); - break; - default: - vpx_convolve8_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } else if (vpx_get_filter_taps(filter_x) == 2 || - vpx_get_filter_taps(filter_y) == 2) { - vpx_convolve8_c(src, src_stride, dst, dst_stride, filter, x0_q4, x_step_q4, - y0_q4, y_step_q4, w, h); - } else { - switch (w) { - case 4: - common_hv_8ht_8vt_4w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, filt_ver, - (int32_t)h); - break; - case 8: - common_hv_8ht_8vt_8w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, filt_ver, - (int32_t)h); - break; - case 16: - common_hv_8ht_8vt_16w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, filt_ver, - (int32_t)h); - break; - case 32: - common_hv_8ht_8vt_32w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, filt_ver, - (int32_t)h); - break; - case 64: - common_hv_8ht_8vt_64w_msa(src, (int32_t)src_stride, dst, - (int32_t)dst_stride, filt_hor, filt_ver, - (int32_t)h); - break; - default: - vpx_convolve8_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } -} - -static void filter_horiz_w4_msa(const uint8_t *src_x, ptrdiff_t src_pitch, - uint8_t *dst, const int16_t *x_filter) { - uint64_t srcd0, srcd1, srcd2, srcd3; - uint32_t res; - v16u8 src0 = { 0 }, src1 = { 0 }, dst0; - v16i8 out0, out1; - v16i8 shf1 = { 0, 8, 16, 24, 4, 12, 20, 28, 1, 9, 17, 25, 5, 13, 21, 29 }; - v16i8 shf2 = shf1 + 2; - v16i8 filt_shf0 = { 0, 1, 0, 1, 0, 1, 0, 1, 8, 9, 8, 9, 8, 9, 8, 9 }; - v16i8 filt_shf1 = filt_shf0 + 2; - v16i8 filt_shf2 = filt_shf0 + 4; - v16i8 filt_shf3 = filt_shf0 + 6; - v8i16 filt, src0_h, src1_h, src2_h, src3_h, filt0, filt1, filt2, filt3; - - LD4(src_x, src_pitch, srcd0, srcd1, srcd2, srcd3); - INSERT_D2_UB(srcd0, srcd1, src0); - INSERT_D2_UB(srcd2, srcd3, src1); - VSHF_B2_SB(src0, src1, src0, src1, shf1, shf2, out0, out1); - XORI_B2_128_SB(out0, out1); - UNPCK_SB_SH(out0, src0_h, src1_h); - UNPCK_SB_SH(out1, src2_h, src3_h); - - filt = LD_SH(x_filter); - VSHF_B2_SH(filt, filt, filt, filt, filt_shf0, filt_shf1, filt0, filt1); - VSHF_B2_SH(filt, filt, filt, filt, filt_shf2, filt_shf3, filt2, filt3); - - src0_h *= filt0; - src0_h += src1_h * filt1; - src0_h += src2_h * filt2; - src0_h += src3_h * filt3; - - src1_h = (v8i16)__msa_sldi_b((v16i8)src0_h, (v16i8)src0_h, 8); - - src0_h = __msa_adds_s_h(src0_h, src1_h); - src0_h = __msa_srari_h(src0_h, FILTER_BITS); - src0_h = __msa_sat_s_h(src0_h, 7); - dst0 = PCKEV_XORI128_UB(src0_h, src0_h); - res = __msa_copy_u_w((v4i32)dst0, 0); - SW(res, dst); -} - -static void filter_horiz_w8_msa(const uint8_t *src_x, ptrdiff_t src_pitch, - uint8_t *dst, const int16_t *x_filter) { - uint64_t srcd0, srcd1, srcd2, srcd3; - v16u8 src0 = { 0 }, src1 = { 0 }, src2 = { 0 }, src3 = { 0 }; - v16u8 tmp0, tmp1, tmp2, tmp3, dst0; - v16i8 out0, out1, out2, out3; - v16i8 shf1 = { 0, 8, 16, 24, 1, 9, 17, 25, 2, 10, 18, 26, 3, 11, 19, 27 }; - v16i8 shf2 = shf1 + 4; - v8i16 filt, src0_h, src1_h, src2_h, src3_h, src4_h, src5_h, src6_h, src7_h; - v8i16 filt0, filt1, filt2, filt3, filt4, filt5, filt6, filt7; - - LD4(src_x, src_pitch, srcd0, srcd1, srcd2, srcd3); - INSERT_D2_UB(srcd0, srcd1, src0); - INSERT_D2_UB(srcd2, srcd3, src1); - LD4(src_x + 4 * src_pitch, src_pitch, srcd0, srcd1, srcd2, srcd3); - INSERT_D2_UB(srcd0, srcd1, src2); - INSERT_D2_UB(srcd2, srcd3, src3); - - filt = LD_SH(x_filter); - SPLATI_H4_SH(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - SPLATI_H4_SH(filt, 4, 5, 6, 7, filt4, filt5, filt6, filt7); - - // transpose - VSHF_B2_UB(src0, src1, src0, src1, shf1, shf2, tmp0, tmp1); - VSHF_B2_UB(src2, src3, src2, src3, shf1, shf2, tmp2, tmp3); - ILVRL_W2_SB(tmp2, tmp0, out0, out1); - ILVRL_W2_SB(tmp3, tmp1, out2, out3); - - XORI_B4_128_SB(out0, out1, out2, out3); - UNPCK_SB_SH(out0, src0_h, src1_h); - UNPCK_SB_SH(out1, src2_h, src3_h); - UNPCK_SB_SH(out2, src4_h, src5_h); - UNPCK_SB_SH(out3, src6_h, src7_h); - - src0_h *= filt0; - src4_h *= filt4; - src0_h += src1_h * filt1; - src4_h += src5_h * filt5; - src0_h += src2_h * filt2; - src4_h += src6_h * filt6; - src0_h += src3_h * filt3; - src4_h += src7_h * filt7; - - src0_h = __msa_adds_s_h(src0_h, src4_h); - src0_h = __msa_srari_h(src0_h, FILTER_BITS); - src0_h = __msa_sat_s_h(src0_h, 7); - dst0 = PCKEV_XORI128_UB(src0_h, src0_h); - ST8x1_UB(dst0, dst); -} - -static void filter_horiz_w16_msa(const uint8_t *src_x, ptrdiff_t src_pitch, - uint8_t *dst, const int16_t *x_filter) { - uint64_t srcd0, srcd1, srcd2, srcd3; - v16u8 src0 = { 0 }, src1 = { 0 }, src2 = { 0 }, src3 = { 0 }; - v16u8 src4 = { 0 }, src5 = { 0 }, src6 = { 0 }, src7 = { 0 }; - v16u8 tmp0, tmp1, tmp2, tmp3, dst0; - v16i8 out0, out1, out2, out3, out4, out5, out6, out7; - v16i8 shf1 = { 0, 8, 16, 24, 1, 9, 17, 25, 2, 10, 18, 26, 3, 11, 19, 27 }; - v16i8 shf2 = shf1 + 4; - v8i16 filt, src0_h, src1_h, src2_h, src3_h, src4_h, src5_h, src6_h, src7_h; - v8i16 filt0, filt1, filt2, filt3, filt4, filt5, filt6, filt7; - v8i16 dst0_h, dst1_h, dst2_h, dst3_h; - - LD4(src_x, src_pitch, srcd0, srcd1, srcd2, srcd3); - INSERT_D2_UB(srcd0, srcd1, src0); - INSERT_D2_UB(srcd2, srcd3, src1); - LD4(src_x + 4 * src_pitch, src_pitch, srcd0, srcd1, srcd2, srcd3); - INSERT_D2_UB(srcd0, srcd1, src2); - INSERT_D2_UB(srcd2, srcd3, src3); - LD4(src_x + 8 * src_pitch, src_pitch, srcd0, srcd1, srcd2, srcd3); - INSERT_D2_UB(srcd0, srcd1, src4); - INSERT_D2_UB(srcd2, srcd3, src5); - LD4(src_x + 12 * src_pitch, src_pitch, srcd0, srcd1, srcd2, srcd3); - INSERT_D2_UB(srcd0, srcd1, src6); - INSERT_D2_UB(srcd2, srcd3, src7); - - filt = LD_SH(x_filter); - SPLATI_H4_SH(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - SPLATI_H4_SH(filt, 4, 5, 6, 7, filt4, filt5, filt6, filt7); - - // transpose - VSHF_B2_UB(src0, src1, src0, src1, shf1, shf2, tmp0, tmp1); - VSHF_B2_UB(src2, src3, src2, src3, shf1, shf2, tmp2, tmp3); - ILVRL_W2_SB(tmp2, tmp0, out0, out1); - ILVRL_W2_SB(tmp3, tmp1, out2, out3); - XORI_B4_128_SB(out0, out1, out2, out3); - - UNPCK_SB_SH(out0, src0_h, src1_h); - UNPCK_SB_SH(out1, src2_h, src3_h); - UNPCK_SB_SH(out2, src4_h, src5_h); - UNPCK_SB_SH(out3, src6_h, src7_h); - - VSHF_B2_UB(src4, src5, src4, src5, shf1, shf2, tmp0, tmp1); - VSHF_B2_UB(src6, src7, src6, src7, shf1, shf2, tmp2, tmp3); - ILVRL_W2_SB(tmp2, tmp0, out4, out5); - ILVRL_W2_SB(tmp3, tmp1, out6, out7); - XORI_B4_128_SB(out4, out5, out6, out7); - - dst0_h = src0_h * filt0; - dst1_h = src4_h * filt4; - dst0_h += src1_h * filt1; - dst1_h += src5_h * filt5; - dst0_h += src2_h * filt2; - dst1_h += src6_h * filt6; - dst0_h += src3_h * filt3; - dst1_h += src7_h * filt7; - - UNPCK_SB_SH(out4, src0_h, src1_h); - UNPCK_SB_SH(out5, src2_h, src3_h); - UNPCK_SB_SH(out6, src4_h, src5_h); - UNPCK_SB_SH(out7, src6_h, src7_h); - - dst2_h = src0_h * filt0; - dst3_h = src4_h * filt4; - dst2_h += src1_h * filt1; - dst3_h += src5_h * filt5; - dst2_h += src2_h * filt2; - dst3_h += src6_h * filt6; - dst2_h += src3_h * filt3; - dst3_h += src7_h * filt7; - - ADDS_SH2_SH(dst0_h, dst1_h, dst2_h, dst3_h, dst0_h, dst2_h); - SRARI_H2_SH(dst0_h, dst2_h, FILTER_BITS); - SAT_SH2_SH(dst0_h, dst2_h, 7); - dst0 = PCKEV_XORI128_UB(dst0_h, dst2_h); - ST_UB(dst0, dst); -} - -static void transpose4x4_to_dst(const uint8_t *src, uint8_t *dst, - ptrdiff_t dst_stride) { - v16u8 in0; - v16i8 out0 = { 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15 }; - - in0 = LD_UB(src); - out0 = __msa_vshf_b(out0, (v16i8)in0, (v16i8)in0); - ST4x4_UB(out0, out0, 0, 1, 2, 3, dst, dst_stride); -} - -static void transpose8x8_to_dst(const uint8_t *src, uint8_t *dst, - ptrdiff_t dst_stride) { - v16u8 in0, in1, in2, in3, out0, out1, out2, out3, tmp0, tmp1, tmp2, tmp3; - v16i8 shf1 = { 0, 8, 16, 24, 1, 9, 17, 25, 2, 10, 18, 26, 3, 11, 19, 27 }; - v16i8 shf2 = shf1 + 4; - - LD_UB4(src, 16, in0, in1, in2, in3); - VSHF_B2_UB(in0, in1, in0, in1, shf1, shf2, tmp0, tmp1); - VSHF_B2_UB(in2, in3, in2, in3, shf1, shf2, tmp2, tmp3); - ILVRL_W2_UB(tmp2, tmp0, out0, out1); - ILVRL_W2_UB(tmp3, tmp1, out2, out3); - ST8x4_UB(out0, out1, dst, dst_stride); - ST8x4_UB(out2, out3, dst + 4 * dst_stride, dst_stride); -} - -static void transpose16x16_to_dst(const uint8_t *src, uint8_t *dst, - ptrdiff_t dst_stride) { - v16u8 in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, in11, in12; - v16u8 in13, in14, in15, out0, out1, out2, out3, out4, out5, out6, out7, out8; - v16u8 out9, out10, out11, out12, out13, out14, out15; - - LD_UB8(src, 16, in0, in1, in2, in3, in4, in5, in6, in7); - LD_UB8(src + 16 * 8, 16, in8, in9, in10, in11, in12, in13, in14, in15); - - TRANSPOSE16x8_UB_UB(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, - in11, in12, in13, in14, in15, out0, out1, out2, out3, - out4, out5, out6, out7); - ST_UB8(out0, out1, out2, out3, out4, out5, out6, out7, dst, dst_stride); - dst += 8 * dst_stride; - - SLDI_B4_0_UB(in0, in1, in2, in3, in0, in1, in2, in3, 8); - SLDI_B4_0_UB(in4, in5, in6, in7, in4, in5, in6, in7, 8); - SLDI_B4_0_UB(in8, in9, in10, in11, in8, in9, in10, in11, 8); - SLDI_B4_0_UB(in12, in13, in14, in15, in12, in13, in14, in15, 8); - - TRANSPOSE16x8_UB_UB(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, - in11, in12, in13, in14, in15, out8, out9, out10, out11, - out12, out13, out14, out15); - ST_UB8(out8, out9, out10, out11, out12, out13, out14, out15, dst, dst_stride); -} - -static void scaledconvolve_horiz_w4(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *x_filters, int x0_q4, - int x_step_q4, int h) { - DECLARE_ALIGNED(16, uint8_t, temp[4 * 4]); - int y, z, i; - src -= SUBPEL_TAPS / 2 - 1; - - for (y = 0; y < h; y += 4) { - int x_q4 = x0_q4; - for (z = 0; z < 4; ++z) { - const uint8_t *const src_x = &src[x_q4 >> SUBPEL_BITS]; - const int16_t *const x_filter = x_filters[x_q4 & SUBPEL_MASK]; - - if (x_q4 & SUBPEL_MASK) { - filter_horiz_w4_msa(src_x, src_stride, temp + (z * 4), x_filter); - } else { - for (i = 0; i < 4; ++i) { - temp[z * 4 + i] = src_x[i * src_stride + 3]; - } - } - - x_q4 += x_step_q4; - } - - transpose4x4_to_dst(temp, dst, dst_stride); - - src += src_stride * 4; - dst += dst_stride * 4; - } -} - -static void scaledconvolve_horiz_w8(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *x_filters, int x0_q4, - int x_step_q4, int h) { - DECLARE_ALIGNED(16, uint8_t, temp[8 * 8]); - int y, z, i; - src -= SUBPEL_TAPS / 2 - 1; - - // This function processes 8x8 areas. The intermediate height is not always - // a multiple of 8, so force it to be a multiple of 8 here. - y = h + (8 - (h & 0x7)); - - do { - int x_q4 = x0_q4; - for (z = 0; z < 8; ++z) { - const uint8_t *const src_x = &src[x_q4 >> SUBPEL_BITS]; - const int16_t *const x_filter = x_filters[x_q4 & SUBPEL_MASK]; - - if (x_q4 & SUBPEL_MASK) { - filter_horiz_w8_msa(src_x, src_stride, temp + (z * 8), x_filter); - } else { - for (i = 0; i < 8; ++i) { - temp[z * 8 + i] = src_x[3 + i * src_stride]; - } - } - - x_q4 += x_step_q4; - } - - transpose8x8_to_dst(temp, dst, dst_stride); - - src += src_stride * 8; - dst += dst_stride * 8; - } while (y -= 8); -} - -static void scaledconvolve_horiz_mul16(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *x_filters, int x0_q4, - int x_step_q4, int w, int h) { - DECLARE_ALIGNED(16, uint8_t, temp[16 * 16]); - int x, y, z, i; - - src -= SUBPEL_TAPS / 2 - 1; - - // This function processes 16x16 areas. The intermediate height is not always - // a multiple of 16, so force it to be a multiple of 8 here. - y = h + (16 - (h & 0xF)); - - do { - int x_q4 = x0_q4; - for (x = 0; x < w; x += 16) { - for (z = 0; z < 16; ++z) { - const uint8_t *const src_x = &src[x_q4 >> SUBPEL_BITS]; - const int16_t *const x_filter = x_filters[x_q4 & SUBPEL_MASK]; - - if (x_q4 & SUBPEL_MASK) { - filter_horiz_w16_msa(src_x, src_stride, temp + (z * 16), x_filter); - } else { - for (i = 0; i < 16; ++i) { - temp[z * 16 + i] = src_x[3 + i * src_stride]; - } - } - - x_q4 += x_step_q4; - } - - transpose16x16_to_dst(temp, dst + x, dst_stride); - } - - src += src_stride * 16; - dst += dst_stride * 16; - } while (y -= 16); -} - -static void filter_vert_w4_msa(const uint8_t *src_y, ptrdiff_t src_pitch, - uint8_t *dst, const int16_t *y_filter) { - uint32_t srcw0, srcw1, srcw2, srcw3, srcw4, srcw5, srcw6, srcw7; - uint32_t res; - v16u8 src0 = { 0 }, src1 = { 0 }, dst0; - v16i8 out0, out1; - v16i8 shf1 = { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 }; - v16i8 shf2 = shf1 + 8; - v16i8 filt_shf0 = { 0, 1, 0, 1, 0, 1, 0, 1, 8, 9, 8, 9, 8, 9, 8, 9 }; - v16i8 filt_shf1 = filt_shf0 + 2; - v16i8 filt_shf2 = filt_shf0 + 4; - v16i8 filt_shf3 = filt_shf0 + 6; - v8i16 filt, src0_h, src1_h, src2_h, src3_h; - v8i16 filt0, filt1, filt2, filt3; - - LW4(src_y, src_pitch, srcw0, srcw1, srcw2, srcw3); - LW4(src_y + 4 * src_pitch, src_pitch, srcw4, srcw5, srcw6, srcw7); - INSERT_W4_UB(srcw0, srcw1, srcw2, srcw3, src0); - INSERT_W4_UB(srcw4, srcw5, srcw6, srcw7, src1); - VSHF_B2_SB(src0, src1, src0, src1, shf1, shf2, out0, out1); - XORI_B2_128_SB(out0, out1); - UNPCK_SB_SH(out0, src0_h, src1_h); - UNPCK_SB_SH(out1, src2_h, src3_h); - - filt = LD_SH(y_filter); - VSHF_B2_SH(filt, filt, filt, filt, filt_shf0, filt_shf1, filt0, filt1); - VSHF_B2_SH(filt, filt, filt, filt, filt_shf2, filt_shf3, filt2, filt3); - - src0_h *= filt0; - src0_h += src1_h * filt1; - src0_h += src2_h * filt2; - src0_h += src3_h * filt3; - - src1_h = (v8i16)__msa_sldi_b((v16i8)src0_h, (v16i8)src0_h, 8); - - src0_h = __msa_adds_s_h(src0_h, src1_h); - src0_h = __msa_srari_h(src0_h, FILTER_BITS); - src0_h = __msa_sat_s_h(src0_h, 7); - dst0 = PCKEV_XORI128_UB(src0_h, src0_h); - res = __msa_copy_u_w((v4i32)dst0, 0); - SW(res, dst); -} - -static void filter_vert_w8_msa(const uint8_t *src_y, ptrdiff_t src_pitch, - uint8_t *dst, const int16_t *y_filter) { - uint64_t srcd0, srcd1, srcd2, srcd3; - v16u8 dst0; - v16i8 src0 = { 0 }, src1 = { 0 }, src2 = { 0 }, src3 = { 0 }; - v8i16 filt, src0_h, src1_h, src2_h, src3_h, src4_h, src5_h, src6_h, src7_h; - v8i16 filt0, filt1, filt2, filt3, filt4, filt5, filt6, filt7; - - LD4(src_y, src_pitch, srcd0, srcd1, srcd2, srcd3); - INSERT_D2_SB(srcd0, srcd1, src0); - INSERT_D2_SB(srcd2, srcd3, src1); - LD4(src_y + 4 * src_pitch, src_pitch, srcd0, srcd1, srcd2, srcd3); - INSERT_D2_SB(srcd0, srcd1, src2); - INSERT_D2_SB(srcd2, srcd3, src3); - - filt = LD_SH(y_filter); - SPLATI_H4_SH(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - SPLATI_H4_SH(filt, 4, 5, 6, 7, filt4, filt5, filt6, filt7); - - XORI_B4_128_SB(src0, src1, src2, src3); - UNPCK_SB_SH(src0, src0_h, src1_h); - UNPCK_SB_SH(src1, src2_h, src3_h); - UNPCK_SB_SH(src2, src4_h, src5_h); - UNPCK_SB_SH(src3, src6_h, src7_h); - - src0_h *= filt0; - src4_h *= filt4; - src0_h += src1_h * filt1; - src4_h += src5_h * filt5; - src0_h += src2_h * filt2; - src4_h += src6_h * filt6; - src0_h += src3_h * filt3; - src4_h += src7_h * filt7; - - src0_h = __msa_adds_s_h(src0_h, src4_h); - src0_h = __msa_srari_h(src0_h, FILTER_BITS); - src0_h = __msa_sat_s_h(src0_h, 7); - dst0 = PCKEV_XORI128_UB(src0_h, src0_h); - ST8x1_UB(dst0, dst); -} - -static void filter_vert_mul_w16_msa(const uint8_t *src_y, ptrdiff_t src_pitch, - uint8_t *dst, const int16_t *y_filter, - int w) { - int x; - v16u8 dst0; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7; - v8i16 filt, src0_h, src1_h, src2_h, src3_h, src4_h, src5_h, src6_h, src7_h; - v8i16 src8_h, src9_h, src10_h, src11_h, src12_h, src13_h, src14_h, src15_h; - v8i16 filt0, filt1, filt2, filt3, filt4, filt5, filt6, filt7; - - filt = LD_SH(y_filter); - SPLATI_H4_SH(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - SPLATI_H4_SH(filt, 4, 5, 6, 7, filt4, filt5, filt6, filt7); - - for (x = 0; x < w; x += 16) { - LD_SB8(src_y, src_pitch, src0, src1, src2, src3, src4, src5, src6, src7); - src_y += 16; - - XORI_B4_128_SB(src0, src1, src2, src3); - XORI_B4_128_SB(src4, src5, src6, src7); - UNPCK_SB_SH(src0, src0_h, src1_h); - UNPCK_SB_SH(src1, src2_h, src3_h); - UNPCK_SB_SH(src2, src4_h, src5_h); - UNPCK_SB_SH(src3, src6_h, src7_h); - UNPCK_SB_SH(src4, src8_h, src9_h); - UNPCK_SB_SH(src5, src10_h, src11_h); - UNPCK_SB_SH(src6, src12_h, src13_h); - UNPCK_SB_SH(src7, src14_h, src15_h); - - src0_h *= filt0; - src1_h *= filt0; - src8_h *= filt4; - src9_h *= filt4; - src0_h += src2_h * filt1; - src1_h += src3_h * filt1; - src8_h += src10_h * filt5; - src9_h += src11_h * filt5; - src0_h += src4_h * filt2; - src1_h += src5_h * filt2; - src8_h += src12_h * filt6; - src9_h += src13_h * filt6; - src0_h += src6_h * filt3; - src1_h += src7_h * filt3; - src8_h += src14_h * filt7; - src9_h += src15_h * filt7; - - ADDS_SH2_SH(src0_h, src8_h, src1_h, src9_h, src0_h, src1_h); - SRARI_H2_SH(src0_h, src1_h, FILTER_BITS); - SAT_SH2_SH(src0_h, src1_h, 7); - dst0 = PCKEV_XORI128_UB(src0_h, src1_h); - ST_UB(dst0, dst); - dst += 16; - } -} - -static void scaledconvolve_vert_w4(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *y_filters, int y0_q4, - int y_step_q4, int h) { - int y; - int y_q4 = y0_q4; - - src -= src_stride * (SUBPEL_TAPS / 2 - 1); - - for (y = 0; y < h; ++y) { - const uint8_t *src_y = &src[(y_q4 >> SUBPEL_BITS) * src_stride]; - const int16_t *const y_filter = y_filters[y_q4 & SUBPEL_MASK]; - - if (y_q4 & SUBPEL_MASK) { - filter_vert_w4_msa(src_y, src_stride, &dst[y * dst_stride], y_filter); - } else { - uint32_t srcd = LW(src_y + 3 * src_stride); - SW(srcd, dst + y * dst_stride); - } - - y_q4 += y_step_q4; - } -} - -static void scaledconvolve_vert_w8(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *y_filters, int y0_q4, - int y_step_q4, int h) { - int y; - int y_q4 = y0_q4; - - src -= src_stride * (SUBPEL_TAPS / 2 - 1); - - for (y = 0; y < h; ++y) { - const uint8_t *src_y = &src[(y_q4 >> SUBPEL_BITS) * src_stride]; - const int16_t *const y_filter = y_filters[y_q4 & SUBPEL_MASK]; - - if (y_q4 & SUBPEL_MASK) { - filter_vert_w8_msa(src_y, src_stride, &dst[y * dst_stride], y_filter); - } else { - uint64_t srcd = LD(src_y + 3 * src_stride); - SD(srcd, dst + y * dst_stride); - } - - y_q4 += y_step_q4; - } -} - -static void scaledconvolve_vert_mul16(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *y_filters, int y0_q4, - int y_step_q4, int w, int h) { - int x, y; - int y_q4 = y0_q4; - src -= src_stride * (SUBPEL_TAPS / 2 - 1); - - for (y = 0; y < h; ++y) { - const uint8_t *src_y = &src[(y_q4 >> SUBPEL_BITS) * src_stride]; - const int16_t *const y_filter = y_filters[y_q4 & SUBPEL_MASK]; - - if (y_q4 & SUBPEL_MASK) { - filter_vert_mul_w16_msa(src_y, src_stride, &dst[y * dst_stride], y_filter, - w); - } else { - for (x = 0; x < w; ++x) { - dst[x + y * dst_stride] = src_y[x + 3 * src_stride]; - } - } - - y_q4 += y_step_q4; - } -} - -void vpx_scaled_2d_msa(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, - int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - // Note: Fixed size intermediate buffer, temp, places limits on parameters. - // 2d filtering proceeds in 2 steps: - // (1) Interpolate horizontally into an intermediate buffer, temp. - // (2) Interpolate temp vertically to derive the sub-pixel result. - // Deriving the maximum number of rows in the temp buffer (135): - // --Smallest scaling factor is x1/2 ==> y_step_q4 = 32 (Normative). - // --Largest block size is 64x64 pixels. - // --64 rows in the downscaled frame span a distance of (64 - 1) * 32 in the - // original frame (in 1/16th pixel units). - // --Must round-up because block may be located at sub-pixel position. - // --Require an additional SUBPEL_TAPS rows for the 8-tap filter tails. - // --((64 - 1) * 32 + 15) >> 4 + 8 = 135. - // --Require an additional 8 rows for the horiz_w8 transpose tail. - DECLARE_ALIGNED(16, uint8_t, temp[(135 + 8) * 64]); - const int intermediate_height = - (((h - 1) * y_step_q4 + y0_q4) >> SUBPEL_BITS) + SUBPEL_TAPS; - - assert(w <= 64); - assert(h <= 64); - assert(y_step_q4 <= 32 || (y_step_q4 <= 64 && h <= 32)); - assert(x_step_q4 <= 64); - - if ((0 == x0_q4) && (16 == x_step_q4) && (0 == y0_q4) && (16 == y_step_q4)) { - vpx_convolve_copy_msa(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - } else { - if (w >= 16) { - scaledconvolve_horiz_mul16(src - src_stride * (SUBPEL_TAPS / 2 - 1), - src_stride, temp, 64, filter, x0_q4, x_step_q4, - w, intermediate_height); - } else if (w == 8) { - scaledconvolve_horiz_w8(src - src_stride * (SUBPEL_TAPS / 2 - 1), - src_stride, temp, 64, filter, x0_q4, x_step_q4, - intermediate_height); - } else { - scaledconvolve_horiz_w4(src - src_stride * (SUBPEL_TAPS / 2 - 1), - src_stride, temp, 64, filter, x0_q4, x_step_q4, - intermediate_height); - } - - if (w >= 16) { - scaledconvolve_vert_mul16(temp + 64 * (SUBPEL_TAPS / 2 - 1), 64, dst, - dst_stride, filter, y0_q4, y_step_q4, w, h); - } else if (w == 8) { - scaledconvolve_vert_w8(temp + 64 * (SUBPEL_TAPS / 2 - 1), 64, dst, - dst_stride, filter, y0_q4, y_step_q4, h); - } else { - scaledconvolve_vert_w4(temp + 64 * (SUBPEL_TAPS / 2 - 1), 64, dst, - dst_stride, filter, y0_q4, y_step_q4, h); - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_vert_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_vert_msa.c deleted file mode 100644 index 19522868..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve8_vert_msa.c +++ /dev/null @@ -1,699 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/vpx_convolve_msa.h" - -static void common_vt_8t_4w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - v16i8 src10_r, src32_r, src54_r, src76_r, src98_r, src21_r, src43_r; - v16i8 src65_r, src87_r, src109_r, src2110, src4332, src6554, src8776; - v16i8 src10998, filt0, filt1, filt2, filt3; - v16u8 out; - v8i16 filt, out10, out32; - - src -= (3 * src_stride); - - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - LD_SB7(src, src_stride, src0, src1, src2, src3, src4, src5, src6); - src += (7 * src_stride); - - ILVR_B4_SB(src1, src0, src3, src2, src5, src4, src2, src1, src10_r, src32_r, - src54_r, src21_r); - ILVR_B2_SB(src4, src3, src6, src5, src43_r, src65_r); - ILVR_D3_SB(src21_r, src10_r, src43_r, src32_r, src65_r, src54_r, src2110, - src4332, src6554); - XORI_B3_128_SB(src2110, src4332, src6554); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src7, src8, src9, src10); - src += (4 * src_stride); - - ILVR_B4_SB(src7, src6, src8, src7, src9, src8, src10, src9, src76_r, - src87_r, src98_r, src109_r); - ILVR_D2_SB(src87_r, src76_r, src109_r, src98_r, src8776, src10998); - XORI_B2_128_SB(src8776, src10998); - out10 = FILT_8TAP_DPADD_S_H(src2110, src4332, src6554, src8776, filt0, - filt1, filt2, filt3); - out32 = FILT_8TAP_DPADD_S_H(src4332, src6554, src8776, src10998, filt0, - filt1, filt2, filt3); - SRARI_H2_SH(out10, out32, FILTER_BITS); - SAT_SH2_SH(out10, out32, 7); - out = PCKEV_XORI128_UB(out10, out32); - ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); - dst += (4 * dst_stride); - - src2110 = src6554; - src4332 = src8776; - src6554 = src10998; - src6 = src10; - } -} - -static void common_vt_8t_8w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - v16i8 src10_r, src32_r, src54_r, src76_r, src98_r, src21_r, src43_r; - v16i8 src65_r, src87_r, src109_r, filt0, filt1, filt2, filt3; - v16u8 tmp0, tmp1; - v8i16 filt, out0_r, out1_r, out2_r, out3_r; - - src -= (3 * src_stride); - - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - LD_SB7(src, src_stride, src0, src1, src2, src3, src4, src5, src6); - XORI_B7_128_SB(src0, src1, src2, src3, src4, src5, src6); - src += (7 * src_stride); - ILVR_B4_SB(src1, src0, src3, src2, src5, src4, src2, src1, src10_r, src32_r, - src54_r, src21_r); - ILVR_B2_SB(src4, src3, src6, src5, src43_r, src65_r); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src7, src8, src9, src10); - XORI_B4_128_SB(src7, src8, src9, src10); - src += (4 * src_stride); - - ILVR_B4_SB(src7, src6, src8, src7, src9, src8, src10, src9, src76_r, - src87_r, src98_r, src109_r); - out0_r = FILT_8TAP_DPADD_S_H(src10_r, src32_r, src54_r, src76_r, filt0, - filt1, filt2, filt3); - out1_r = FILT_8TAP_DPADD_S_H(src21_r, src43_r, src65_r, src87_r, filt0, - filt1, filt2, filt3); - out2_r = FILT_8TAP_DPADD_S_H(src32_r, src54_r, src76_r, src98_r, filt0, - filt1, filt2, filt3); - out3_r = FILT_8TAP_DPADD_S_H(src43_r, src65_r, src87_r, src109_r, filt0, - filt1, filt2, filt3); - SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, FILTER_BITS); - SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); - tmp0 = PCKEV_XORI128_UB(out0_r, out1_r); - tmp1 = PCKEV_XORI128_UB(out2_r, out3_r); - ST8x4_UB(tmp0, tmp1, dst, dst_stride); - dst += (4 * dst_stride); - - src10_r = src54_r; - src32_r = src76_r; - src54_r = src98_r; - src21_r = src65_r; - src43_r = src87_r; - src65_r = src109_r; - src6 = src10; - } -} - -static void common_vt_8t_16w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - v16i8 filt0, filt1, filt2, filt3; - v16i8 src10_r, src32_r, src54_r, src76_r, src98_r, src21_r, src43_r; - v16i8 src65_r, src87_r, src109_r, src10_l, src32_l, src54_l, src76_l; - v16i8 src98_l, src21_l, src43_l, src65_l, src87_l, src109_l; - v16u8 tmp0, tmp1, tmp2, tmp3; - v8i16 filt, out0_r, out1_r, out2_r, out3_r, out0_l, out1_l, out2_l, out3_l; - - src -= (3 * src_stride); - - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - LD_SB7(src, src_stride, src0, src1, src2, src3, src4, src5, src6); - XORI_B7_128_SB(src0, src1, src2, src3, src4, src5, src6); - src += (7 * src_stride); - ILVR_B4_SB(src1, src0, src3, src2, src5, src4, src2, src1, src10_r, src32_r, - src54_r, src21_r); - ILVR_B2_SB(src4, src3, src6, src5, src43_r, src65_r); - ILVL_B4_SB(src1, src0, src3, src2, src5, src4, src2, src1, src10_l, src32_l, - src54_l, src21_l); - ILVL_B2_SB(src4, src3, src6, src5, src43_l, src65_l); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src, src_stride, src7, src8, src9, src10); - XORI_B4_128_SB(src7, src8, src9, src10); - src += (4 * src_stride); - - ILVR_B4_SB(src7, src6, src8, src7, src9, src8, src10, src9, src76_r, - src87_r, src98_r, src109_r); - ILVL_B4_SB(src7, src6, src8, src7, src9, src8, src10, src9, src76_l, - src87_l, src98_l, src109_l); - out0_r = FILT_8TAP_DPADD_S_H(src10_r, src32_r, src54_r, src76_r, filt0, - filt1, filt2, filt3); - out1_r = FILT_8TAP_DPADD_S_H(src21_r, src43_r, src65_r, src87_r, filt0, - filt1, filt2, filt3); - out2_r = FILT_8TAP_DPADD_S_H(src32_r, src54_r, src76_r, src98_r, filt0, - filt1, filt2, filt3); - out3_r = FILT_8TAP_DPADD_S_H(src43_r, src65_r, src87_r, src109_r, filt0, - filt1, filt2, filt3); - out0_l = FILT_8TAP_DPADD_S_H(src10_l, src32_l, src54_l, src76_l, filt0, - filt1, filt2, filt3); - out1_l = FILT_8TAP_DPADD_S_H(src21_l, src43_l, src65_l, src87_l, filt0, - filt1, filt2, filt3); - out2_l = FILT_8TAP_DPADD_S_H(src32_l, src54_l, src76_l, src98_l, filt0, - filt1, filt2, filt3); - out3_l = FILT_8TAP_DPADD_S_H(src43_l, src65_l, src87_l, src109_l, filt0, - filt1, filt2, filt3); - SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, FILTER_BITS); - SRARI_H4_SH(out0_l, out1_l, out2_l, out3_l, FILTER_BITS); - SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); - SAT_SH4_SH(out0_l, out1_l, out2_l, out3_l, 7); - PCKEV_B4_UB(out0_l, out0_r, out1_l, out1_r, out2_l, out2_r, out3_l, out3_r, - tmp0, tmp1, tmp2, tmp3); - XORI_B4_128_UB(tmp0, tmp1, tmp2, tmp3); - ST_UB4(tmp0, tmp1, tmp2, tmp3, dst, dst_stride); - dst += (4 * dst_stride); - - src10_r = src54_r; - src32_r = src76_r; - src54_r = src98_r; - src21_r = src65_r; - src43_r = src87_r; - src65_r = src109_r; - src10_l = src54_l; - src32_l = src76_l; - src54_l = src98_l; - src21_l = src65_l; - src43_l = src87_l; - src65_l = src109_l; - src6 = src10; - } -} - -static void common_vt_8t_16w_mult_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height, - int32_t width) { - const uint8_t *src_tmp; - uint8_t *dst_tmp; - uint32_t loop_cnt, cnt; - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - v16i8 filt0, filt1, filt2, filt3; - v16i8 src10_r, src32_r, src54_r, src76_r, src98_r, src21_r, src43_r; - v16i8 src65_r, src87_r, src109_r, src10_l, src32_l, src54_l, src76_l; - v16i8 src98_l, src21_l, src43_l, src65_l, src87_l, src109_l; - v16u8 tmp0, tmp1, tmp2, tmp3; - v8i16 filt, out0_r, out1_r, out2_r, out3_r, out0_l, out1_l, out2_l, out3_l; - - src -= (3 * src_stride); - - filt = LD_SH(filter); - SPLATI_H4_SB(filt, 0, 1, 2, 3, filt0, filt1, filt2, filt3); - - for (cnt = (width >> 4); cnt--;) { - src_tmp = src; - dst_tmp = dst; - - LD_SB7(src_tmp, src_stride, src0, src1, src2, src3, src4, src5, src6); - XORI_B7_128_SB(src0, src1, src2, src3, src4, src5, src6); - src_tmp += (7 * src_stride); - ILVR_B4_SB(src1, src0, src3, src2, src5, src4, src2, src1, src10_r, src32_r, - src54_r, src21_r); - ILVR_B2_SB(src4, src3, src6, src5, src43_r, src65_r); - ILVL_B4_SB(src1, src0, src3, src2, src5, src4, src2, src1, src10_l, src32_l, - src54_l, src21_l); - ILVL_B2_SB(src4, src3, src6, src5, src43_l, src65_l); - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_SB4(src_tmp, src_stride, src7, src8, src9, src10); - XORI_B4_128_SB(src7, src8, src9, src10); - src_tmp += (4 * src_stride); - ILVR_B4_SB(src7, src6, src8, src7, src9, src8, src10, src9, src76_r, - src87_r, src98_r, src109_r); - ILVL_B4_SB(src7, src6, src8, src7, src9, src8, src10, src9, src76_l, - src87_l, src98_l, src109_l); - out0_r = FILT_8TAP_DPADD_S_H(src10_r, src32_r, src54_r, src76_r, filt0, - filt1, filt2, filt3); - out1_r = FILT_8TAP_DPADD_S_H(src21_r, src43_r, src65_r, src87_r, filt0, - filt1, filt2, filt3); - out2_r = FILT_8TAP_DPADD_S_H(src32_r, src54_r, src76_r, src98_r, filt0, - filt1, filt2, filt3); - out3_r = FILT_8TAP_DPADD_S_H(src43_r, src65_r, src87_r, src109_r, filt0, - filt1, filt2, filt3); - out0_l = FILT_8TAP_DPADD_S_H(src10_l, src32_l, src54_l, src76_l, filt0, - filt1, filt2, filt3); - out1_l = FILT_8TAP_DPADD_S_H(src21_l, src43_l, src65_l, src87_l, filt0, - filt1, filt2, filt3); - out2_l = FILT_8TAP_DPADD_S_H(src32_l, src54_l, src76_l, src98_l, filt0, - filt1, filt2, filt3); - out3_l = FILT_8TAP_DPADD_S_H(src43_l, src65_l, src87_l, src109_l, filt0, - filt1, filt2, filt3); - SRARI_H4_SH(out0_r, out1_r, out2_r, out3_r, FILTER_BITS); - SRARI_H4_SH(out0_l, out1_l, out2_l, out3_l, FILTER_BITS); - SAT_SH4_SH(out0_r, out1_r, out2_r, out3_r, 7); - SAT_SH4_SH(out0_l, out1_l, out2_l, out3_l, 7); - PCKEV_B4_UB(out0_l, out0_r, out1_l, out1_r, out2_l, out2_r, out3_l, - out3_r, tmp0, tmp1, tmp2, tmp3); - XORI_B4_128_UB(tmp0, tmp1, tmp2, tmp3); - ST_UB4(tmp0, tmp1, tmp2, tmp3, dst_tmp, dst_stride); - dst_tmp += (4 * dst_stride); - - src10_r = src54_r; - src32_r = src76_r; - src54_r = src98_r; - src21_r = src65_r; - src43_r = src87_r; - src65_r = src109_r; - src10_l = src54_l; - src32_l = src76_l; - src54_l = src98_l; - src21_l = src65_l; - src43_l = src87_l; - src65_l = src109_l; - src6 = src10; - } - - src += 16; - dst += 16; - } -} - -static void common_vt_8t_32w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - common_vt_8t_16w_mult_msa(src, src_stride, dst, dst_stride, filter, height, - 32); -} - -static void common_vt_8t_64w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - common_vt_8t_16w_mult_msa(src, src_stride, dst, dst_stride, filter, height, - 64); -} - -static void common_vt_2t_4x4_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter) { - v16i8 src0, src1, src2, src3, src4; - v16i8 src10_r, src32_r, src21_r, src43_r, src2110, src4332; - v16u8 filt0; - v8i16 filt; - v8u16 tmp0, tmp1; - - filt = LD_SH(filter); - filt0 = (v16u8)__msa_splati_h(filt, 0); - - LD_SB5(src, src_stride, src0, src1, src2, src3, src4); - src += (5 * src_stride); - - ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, - src32_r, src43_r); - ILVR_D2_SB(src21_r, src10_r, src43_r, src32_r, src2110, src4332); - DOTP_UB2_UH(src2110, src4332, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - src2110 = __msa_pckev_b((v16i8)tmp1, (v16i8)tmp0); - ST4x4_UB(src2110, src2110, 0, 1, 2, 3, dst, dst_stride); -} - -static void common_vt_2t_4x8_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter) { - v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r; - v16i8 src65_r, src87_r, src2110, src4332, src6554, src8776; - v8u16 tmp0, tmp1, tmp2, tmp3; - v16u8 filt0; - v8i16 filt; - - filt = LD_SH(filter); - filt0 = (v16u8)__msa_splati_h(filt, 0); - - LD_SB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - - src8 = LD_SB(src); - src += src_stride; - - ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, - src32_r, src43_r); - ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_r, src65_r, - src76_r, src87_r); - ILVR_D4_SB(src21_r, src10_r, src43_r, src32_r, src65_r, src54_r, src87_r, - src76_r, src2110, src4332, src6554, src8776); - DOTP_UB4_UH(src2110, src4332, src6554, src8776, filt0, filt0, filt0, filt0, - tmp0, tmp1, tmp2, tmp3); - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, FILTER_BITS); - PCKEV_B2_SB(tmp1, tmp0, tmp3, tmp2, src2110, src4332); - ST4x4_UB(src2110, src2110, 0, 1, 2, 3, dst, dst_stride); - ST4x4_UB(src4332, src4332, 0, 1, 2, 3, dst + 4 * dst_stride, dst_stride); -} - -static void common_vt_2t_4w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - if (4 == height) { - common_vt_2t_4x4_msa(src, src_stride, dst, dst_stride, filter); - } else if (8 == height) { - common_vt_2t_4x8_msa(src, src_stride, dst, dst_stride, filter); - } -} - -static void common_vt_2t_8x4_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter) { - v16u8 src0, src1, src2, src3, src4, vec0, vec1, vec2, vec3, filt0; - v16i8 out0, out1; - v8u16 tmp0, tmp1, tmp2, tmp3; - v8i16 filt; - - /* rearranging filter_y */ - filt = LD_SH(filter); - filt0 = (v16u8)__msa_splati_h(filt, 0); - - LD_UB5(src, src_stride, src0, src1, src2, src3, src4); - ILVR_B2_UB(src1, src0, src2, src1, vec0, vec1); - ILVR_B2_UB(src3, src2, src4, src3, vec2, vec3); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, tmp0, tmp1, - tmp2, tmp3); - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, FILTER_BITS); - PCKEV_B2_SB(tmp1, tmp0, tmp3, tmp2, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); -} - -static void common_vt_2t_8x8mult_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, filt0; - v16i8 out0, out1; - v8u16 tmp0, tmp1, tmp2, tmp3; - v8i16 filt; - - /* rearranging filter_y */ - filt = LD_SH(filter); - filt0 = (v16u8)__msa_splati_h(filt, 0); - - src0 = LD_UB(src); - src += src_stride; - - for (loop_cnt = (height >> 3); loop_cnt--;) { - LD_UB8(src, src_stride, src1, src2, src3, src4, src5, src6, src7, src8); - src += (8 * src_stride); - - ILVR_B4_UB(src1, src0, src2, src1, src3, src2, src4, src3, vec0, vec1, vec2, - vec3); - ILVR_B4_UB(src5, src4, src6, src5, src7, src6, src8, src7, vec4, vec5, vec6, - vec7); - DOTP_UB4_UH(vec0, vec1, vec2, vec3, filt0, filt0, filt0, filt0, tmp0, tmp1, - tmp2, tmp3); - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, FILTER_BITS); - PCKEV_B2_SB(tmp1, tmp0, tmp3, tmp2, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += (4 * dst_stride); - - DOTP_UB4_UH(vec4, vec5, vec6, vec7, filt0, filt0, filt0, filt0, tmp0, tmp1, - tmp2, tmp3); - SRARI_H4_UH(tmp0, tmp1, tmp2, tmp3, FILTER_BITS); - PCKEV_B2_SB(tmp1, tmp0, tmp3, tmp2, out0, out1); - ST8x4_UB(out0, out1, dst, dst_stride); - dst += (4 * dst_stride); - - src0 = src8; - } -} - -static void common_vt_2t_8w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - if (4 == height) { - common_vt_2t_8x4_msa(src, src_stride, dst, dst_stride, filter); - } else { - common_vt_2t_8x8mult_msa(src, src_stride, dst, dst_stride, filter, height); - } -} - -static void common_vt_2t_16w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16u8 src0, src1, src2, src3, src4; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, filt0; - v8u16 tmp0, tmp1, tmp2, tmp3; - v8i16 filt; - - /* rearranging filter_y */ - filt = LD_SH(filter); - filt0 = (v16u8)__msa_splati_h(filt, 0); - - src0 = LD_UB(src); - src += src_stride; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - src += (4 * src_stride); - - ILVR_B2_UB(src1, src0, src2, src1, vec0, vec2); - ILVL_B2_UB(src1, src0, src2, src1, vec1, vec3); - DOTP_UB2_UH(vec0, vec1, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_ST_SB(tmp0, tmp1, dst); - dst += dst_stride; - - ILVR_B2_UB(src3, src2, src4, src3, vec4, vec6); - ILVL_B2_UB(src3, src2, src4, src3, vec5, vec7); - DOTP_UB2_UH(vec2, vec3, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_ST_SB(tmp2, tmp3, dst); - dst += dst_stride; - - DOTP_UB2_UH(vec4, vec5, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_ST_SB(tmp0, tmp1, dst); - dst += dst_stride; - - DOTP_UB2_UH(vec6, vec7, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_ST_SB(tmp2, tmp3, dst); - dst += dst_stride; - - src0 = src4; - } -} - -static void common_vt_2t_32w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9; - v16u8 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, filt0; - v8u16 tmp0, tmp1, tmp2, tmp3; - v8i16 filt; - - /* rearranging filter_y */ - filt = LD_SH(filter); - filt0 = (v16u8)__msa_splati_h(filt, 0); - - src0 = LD_UB(src); - src5 = LD_UB(src + 16); - src += src_stride; - - for (loop_cnt = (height >> 2); loop_cnt--;) { - LD_UB4(src, src_stride, src1, src2, src3, src4); - ILVR_B2_UB(src1, src0, src2, src1, vec0, vec2); - ILVL_B2_UB(src1, src0, src2, src1, vec1, vec3); - - LD_UB4(src + 16, src_stride, src6, src7, src8, src9); - src += (4 * src_stride); - - DOTP_UB2_UH(vec0, vec1, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_ST_SB(tmp0, tmp1, dst); - DOTP_UB2_UH(vec2, vec3, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_ST_SB(tmp2, tmp3, dst + dst_stride); - - ILVR_B2_UB(src3, src2, src4, src3, vec4, vec6); - ILVL_B2_UB(src3, src2, src4, src3, vec5, vec7); - DOTP_UB2_UH(vec4, vec5, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_ST_SB(tmp0, tmp1, dst + 2 * dst_stride); - - DOTP_UB2_UH(vec6, vec7, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_ST_SB(tmp2, tmp3, dst + 3 * dst_stride); - - ILVR_B2_UB(src6, src5, src7, src6, vec0, vec2); - ILVL_B2_UB(src6, src5, src7, src6, vec1, vec3); - DOTP_UB2_UH(vec0, vec1, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_ST_SB(tmp0, tmp1, dst + 16); - - DOTP_UB2_UH(vec2, vec3, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_ST_SB(tmp2, tmp3, dst + 16 + dst_stride); - - ILVR_B2_UB(src8, src7, src9, src8, vec4, vec6); - ILVL_B2_UB(src8, src7, src9, src8, vec5, vec7); - DOTP_UB2_UH(vec4, vec5, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_ST_SB(tmp0, tmp1, dst + 16 + 2 * dst_stride); - - DOTP_UB2_UH(vec6, vec7, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_ST_SB(tmp2, tmp3, dst + 16 + 3 * dst_stride); - dst += (4 * dst_stride); - - src0 = src4; - src5 = src9; - } -} - -static void common_vt_2t_64w_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int8_t *filter, int32_t height) { - uint32_t loop_cnt; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10; - v16u8 src11, vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, filt0; - v8u16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - v8i16 filt; - - /* rearranging filter_y */ - filt = LD_SH(filter); - filt0 = (v16u8)__msa_splati_h(filt, 0); - - LD_UB4(src, 16, src0, src3, src6, src9); - src += src_stride; - - for (loop_cnt = (height >> 1); loop_cnt--;) { - LD_UB2(src, src_stride, src1, src2); - LD_UB2(src + 16, src_stride, src4, src5); - LD_UB2(src + 32, src_stride, src7, src8); - LD_UB2(src + 48, src_stride, src10, src11); - src += (2 * src_stride); - - ILVR_B2_UB(src1, src0, src2, src1, vec0, vec2); - ILVL_B2_UB(src1, src0, src2, src1, vec1, vec3); - DOTP_UB2_UH(vec0, vec1, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_ST_SB(tmp0, tmp1, dst); - - DOTP_UB2_UH(vec2, vec3, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_ST_SB(tmp2, tmp3, dst + dst_stride); - - ILVR_B2_UB(src4, src3, src5, src4, vec4, vec6); - ILVL_B2_UB(src4, src3, src5, src4, vec5, vec7); - DOTP_UB2_UH(vec4, vec5, filt0, filt0, tmp4, tmp5); - SRARI_H2_UH(tmp4, tmp5, FILTER_BITS); - PCKEV_ST_SB(tmp4, tmp5, dst + 16); - - DOTP_UB2_UH(vec6, vec7, filt0, filt0, tmp6, tmp7); - SRARI_H2_UH(tmp6, tmp7, FILTER_BITS); - PCKEV_ST_SB(tmp6, tmp7, dst + 16 + dst_stride); - - ILVR_B2_UB(src7, src6, src8, src7, vec0, vec2); - ILVL_B2_UB(src7, src6, src8, src7, vec1, vec3); - DOTP_UB2_UH(vec0, vec1, filt0, filt0, tmp0, tmp1); - SRARI_H2_UH(tmp0, tmp1, FILTER_BITS); - PCKEV_ST_SB(tmp0, tmp1, dst + 32); - - DOTP_UB2_UH(vec2, vec3, filt0, filt0, tmp2, tmp3); - SRARI_H2_UH(tmp2, tmp3, FILTER_BITS); - PCKEV_ST_SB(tmp2, tmp3, dst + 32 + dst_stride); - - ILVR_B2_UB(src10, src9, src11, src10, vec4, vec6); - ILVL_B2_UB(src10, src9, src11, src10, vec5, vec7); - DOTP_UB2_UH(vec4, vec5, filt0, filt0, tmp4, tmp5); - SRARI_H2_UH(tmp4, tmp5, FILTER_BITS); - PCKEV_ST_SB(tmp4, tmp5, dst + 48); - - DOTP_UB2_UH(vec6, vec7, filt0, filt0, tmp6, tmp7); - SRARI_H2_UH(tmp6, tmp7, FILTER_BITS); - PCKEV_ST_SB(tmp6, tmp7, dst + 48 + dst_stride); - dst += (2 * dst_stride); - - src0 = src2; - src3 = src5; - src6 = src8; - src9 = src11; - } -} - -void vpx_convolve8_vert_msa(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - const int16_t *const filter_y = filter[y0_q4]; - int8_t cnt, filt_ver[8]; - - assert(y_step_q4 == 16); - assert(((const int32_t *)filter_y)[1] != 0x800000); - - for (cnt = 8; cnt--;) { - filt_ver[cnt] = filter_y[cnt]; - } - - if (vpx_get_filter_taps(filter_y) == 2) { - switch (w) { - case 4: - common_vt_2t_4w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_ver[3], h); - break; - case 8: - common_vt_2t_8w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_ver[3], h); - break; - case 16: - common_vt_2t_16w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_ver[3], h); - break; - case 32: - common_vt_2t_32w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_ver[3], h); - break; - case 64: - common_vt_2t_64w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - &filt_ver[3], h); - break; - default: - vpx_convolve8_vert_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } else { - switch (w) { - case 4: - common_vt_8t_4w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_ver, h); - break; - case 8: - common_vt_8t_8w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_ver, h); - break; - case 16: - common_vt_8t_16w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_ver, h); - break; - case 32: - common_vt_8t_32w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_ver, h); - break; - case 64: - common_vt_8t_64w_msa(src, (int32_t)src_stride, dst, (int32_t)dst_stride, - filt_ver, h); - break; - default: - vpx_convolve8_vert_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve_avg_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve_avg_msa.c deleted file mode 100644 index ce649935..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve_avg_msa.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/macros_msa.h" - -static void avg_width4_msa(const uint8_t *src, int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int32_t height) { - int32_t cnt; - uint32_t out0, out1, out2, out3; - v16u8 src0, src1, src2, src3; - v16u8 dst0, dst1, dst2, dst3; - - if (0 == (height % 4)) { - for (cnt = (height / 4); cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - - AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1, - dst2, dst3); - - out0 = __msa_copy_u_w((v4i32)dst0, 0); - out1 = __msa_copy_u_w((v4i32)dst1, 0); - out2 = __msa_copy_u_w((v4i32)dst2, 0); - out3 = __msa_copy_u_w((v4i32)dst3, 0); - SW4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - } - } else if (0 == (height % 2)) { - for (cnt = (height / 2); cnt--;) { - LD_UB2(src, src_stride, src0, src1); - src += (2 * src_stride); - - LD_UB2(dst, dst_stride, dst0, dst1); - - AVER_UB2_UB(src0, dst0, src1, dst1, dst0, dst1); - - out0 = __msa_copy_u_w((v4i32)dst0, 0); - out1 = __msa_copy_u_w((v4i32)dst1, 0); - SW(out0, dst); - dst += dst_stride; - SW(out1, dst); - dst += dst_stride; - } - } -} - -static void avg_width8_msa(const uint8_t *src, int32_t src_stride, uint8_t *dst, - int32_t dst_stride, int32_t height) { - int32_t cnt; - uint64_t out0, out1, out2, out3; - v16u8 src0, src1, src2, src3; - v16u8 dst0, dst1, dst2, dst3; - - for (cnt = (height / 4); cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); - - AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1, - dst2, dst3); - - out0 = __msa_copy_u_d((v2i64)dst0, 0); - out1 = __msa_copy_u_d((v2i64)dst1, 0); - out2 = __msa_copy_u_d((v2i64)dst2, 0); - out3 = __msa_copy_u_d((v2i64)dst3, 0); - SD4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - } -} - -static void avg_width16_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, int32_t height) { - int32_t cnt; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; - - for (cnt = (height / 8); cnt--;) { - LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - LD_UB8(dst, dst_stride, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7); - - AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1, - dst2, dst3); - AVER_UB4_UB(src4, dst4, src5, dst5, src6, dst6, src7, dst7, dst4, dst5, - dst6, dst7); - ST_UB8(dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, dst, dst_stride); - dst += (8 * dst_stride); - } -} - -static void avg_width32_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, int32_t height) { - int32_t cnt; - uint8_t *dst_dup = dst; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v16u8 src8, src9, src10, src11, src12, src13, src14, src15; - v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; - v16u8 dst8, dst9, dst10, dst11, dst12, dst13, dst14, dst15; - - for (cnt = (height / 8); cnt--;) { - LD_UB4(src, src_stride, src0, src2, src4, src6); - LD_UB4(src + 16, src_stride, src1, src3, src5, src7); - src += (4 * src_stride); - LD_UB4(dst_dup, dst_stride, dst0, dst2, dst4, dst6); - LD_UB4(dst_dup + 16, dst_stride, dst1, dst3, dst5, dst7); - dst_dup += (4 * dst_stride); - LD_UB4(src, src_stride, src8, src10, src12, src14); - LD_UB4(src + 16, src_stride, src9, src11, src13, src15); - src += (4 * src_stride); - LD_UB4(dst_dup, dst_stride, dst8, dst10, dst12, dst14); - LD_UB4(dst_dup + 16, dst_stride, dst9, dst11, dst13, dst15); - dst_dup += (4 * dst_stride); - - AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1, - dst2, dst3); - AVER_UB4_UB(src4, dst4, src5, dst5, src6, dst6, src7, dst7, dst4, dst5, - dst6, dst7); - AVER_UB4_UB(src8, dst8, src9, dst9, src10, dst10, src11, dst11, dst8, dst9, - dst10, dst11); - AVER_UB4_UB(src12, dst12, src13, dst13, src14, dst14, src15, dst15, dst12, - dst13, dst14, dst15); - - ST_UB4(dst0, dst2, dst4, dst6, dst, dst_stride); - ST_UB4(dst1, dst3, dst5, dst7, dst + 16, dst_stride); - dst += (4 * dst_stride); - ST_UB4(dst8, dst10, dst12, dst14, dst, dst_stride); - ST_UB4(dst9, dst11, dst13, dst15, dst + 16, dst_stride); - dst += (4 * dst_stride); - } -} - -static void avg_width64_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, int32_t height) { - int32_t cnt; - uint8_t *dst_dup = dst; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - v16u8 src8, src9, src10, src11, src12, src13, src14, src15; - v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; - v16u8 dst8, dst9, dst10, dst11, dst12, dst13, dst14, dst15; - - for (cnt = (height / 4); cnt--;) { - LD_UB4(src, 16, src0, src1, src2, src3); - src += src_stride; - LD_UB4(src, 16, src4, src5, src6, src7); - src += src_stride; - LD_UB4(src, 16, src8, src9, src10, src11); - src += src_stride; - LD_UB4(src, 16, src12, src13, src14, src15); - src += src_stride; - - LD_UB4(dst_dup, 16, dst0, dst1, dst2, dst3); - dst_dup += dst_stride; - LD_UB4(dst_dup, 16, dst4, dst5, dst6, dst7); - dst_dup += dst_stride; - LD_UB4(dst_dup, 16, dst8, dst9, dst10, dst11); - dst_dup += dst_stride; - LD_UB4(dst_dup, 16, dst12, dst13, dst14, dst15); - dst_dup += dst_stride; - - AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1, - dst2, dst3); - AVER_UB4_UB(src4, dst4, src5, dst5, src6, dst6, src7, dst7, dst4, dst5, - dst6, dst7); - AVER_UB4_UB(src8, dst8, src9, dst9, src10, dst10, src11, dst11, dst8, dst9, - dst10, dst11); - AVER_UB4_UB(src12, dst12, src13, dst13, src14, dst14, src15, dst15, dst12, - dst13, dst14, dst15); - - ST_UB4(dst0, dst1, dst2, dst3, dst, 16); - dst += dst_stride; - ST_UB4(dst4, dst5, dst6, dst7, dst, 16); - dst += dst_stride; - ST_UB4(dst8, dst9, dst10, dst11, dst, 16); - dst += dst_stride; - ST_UB4(dst12, dst13, dst14, dst15, dst, 16); - dst += dst_stride; - } -} - -void vpx_convolve_avg_msa(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int32_t y_step_q4, - int32_t w, int32_t h) { - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - switch (w) { - case 4: { - avg_width4_msa(src, src_stride, dst, dst_stride, h); - break; - } - case 8: { - avg_width8_msa(src, src_stride, dst, dst_stride, h); - break; - } - case 16: { - avg_width16_msa(src, src_stride, dst, dst_stride, h); - break; - } - case 32: { - avg_width32_msa(src, src_stride, dst, dst_stride, h); - break; - } - case 64: { - avg_width64_msa(src, src_stride, dst, dst_stride, h); - break; - } - default: { - int32_t lp, cnt; - for (cnt = h; cnt--;) { - for (lp = 0; lp < w; ++lp) { - dst[lp] = (((dst[lp] + src[lp]) + 1) >> 1); - } - src += src_stride; - dst += dst_stride; - } - break; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve_copy_msa.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve_copy_msa.c deleted file mode 100644 index c2ab33a2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve_copy_msa.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/mips/macros_msa.h" - -static void copy_width8_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, int32_t height) { - int32_t cnt; - uint64_t out0, out1, out2, out3, out4, out5, out6, out7; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - - if (0 == height % 12) { - for (cnt = (height / 12); cnt--;) { - LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - - out0 = __msa_copy_u_d((v2i64)src0, 0); - out1 = __msa_copy_u_d((v2i64)src1, 0); - out2 = __msa_copy_u_d((v2i64)src2, 0); - out3 = __msa_copy_u_d((v2i64)src3, 0); - out4 = __msa_copy_u_d((v2i64)src4, 0); - out5 = __msa_copy_u_d((v2i64)src5, 0); - out6 = __msa_copy_u_d((v2i64)src6, 0); - out7 = __msa_copy_u_d((v2i64)src7, 0); - - SD4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - SD4(out4, out5, out6, out7, dst, dst_stride); - dst += (4 * dst_stride); - - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - out0 = __msa_copy_u_d((v2i64)src0, 0); - out1 = __msa_copy_u_d((v2i64)src1, 0); - out2 = __msa_copy_u_d((v2i64)src2, 0); - out3 = __msa_copy_u_d((v2i64)src3, 0); - SD4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - } - } else if (0 == height % 8) { - for (cnt = height >> 3; cnt--;) { - LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - - out0 = __msa_copy_u_d((v2i64)src0, 0); - out1 = __msa_copy_u_d((v2i64)src1, 0); - out2 = __msa_copy_u_d((v2i64)src2, 0); - out3 = __msa_copy_u_d((v2i64)src3, 0); - out4 = __msa_copy_u_d((v2i64)src4, 0); - out5 = __msa_copy_u_d((v2i64)src5, 0); - out6 = __msa_copy_u_d((v2i64)src6, 0); - out7 = __msa_copy_u_d((v2i64)src7, 0); - - SD4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - SD4(out4, out5, out6, out7, dst, dst_stride); - dst += (4 * dst_stride); - } - } else if (0 == height % 4) { - for (cnt = (height / 4); cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - out0 = __msa_copy_u_d((v2i64)src0, 0); - out1 = __msa_copy_u_d((v2i64)src1, 0); - out2 = __msa_copy_u_d((v2i64)src2, 0); - out3 = __msa_copy_u_d((v2i64)src3, 0); - - SD4(out0, out1, out2, out3, dst, dst_stride); - dst += (4 * dst_stride); - } - } else if (0 == height % 2) { - for (cnt = (height / 2); cnt--;) { - LD_UB2(src, src_stride, src0, src1); - src += (2 * src_stride); - out0 = __msa_copy_u_d((v2i64)src0, 0); - out1 = __msa_copy_u_d((v2i64)src1, 0); - - SD(out0, dst); - dst += dst_stride; - SD(out1, dst); - dst += dst_stride; - } - } -} - -static void copy_16multx8mult_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, - int32_t height, int32_t width) { - int32_t cnt, loop_cnt; - const uint8_t *src_tmp; - uint8_t *dst_tmp; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - - for (cnt = (width >> 4); cnt--;) { - src_tmp = src; - dst_tmp = dst; - - for (loop_cnt = (height >> 3); loop_cnt--;) { - LD_UB8(src_tmp, src_stride, src0, src1, src2, src3, src4, src5, src6, - src7); - src_tmp += (8 * src_stride); - - ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst_tmp, - dst_stride); - dst_tmp += (8 * dst_stride); - } - - src += 16; - dst += 16; - } -} - -static void copy_width16_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, int32_t height) { - int32_t cnt; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - - if (0 == height % 12) { - for (cnt = (height / 12); cnt--;) { - LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); - src += (8 * src_stride); - ST_UB8(src0, src1, src2, src3, src4, src5, src6, src7, dst, dst_stride); - dst += (8 * dst_stride); - - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - dst += (4 * dst_stride); - } - } else if (0 == height % 8) { - copy_16multx8mult_msa(src, src_stride, dst, dst_stride, height, 16); - } else if (0 == height % 4) { - for (cnt = (height >> 2); cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - src += (4 * src_stride); - - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - dst += (4 * dst_stride); - } - } -} - -static void copy_width32_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, int32_t height) { - int32_t cnt; - v16u8 src0, src1, src2, src3, src4, src5, src6, src7; - - if (0 == height % 12) { - for (cnt = (height / 12); cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - LD_UB4(src + 16, src_stride, src4, src5, src6, src7); - src += (4 * src_stride); - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - ST_UB4(src4, src5, src6, src7, dst + 16, dst_stride); - dst += (4 * dst_stride); - - LD_UB4(src, src_stride, src0, src1, src2, src3); - LD_UB4(src + 16, src_stride, src4, src5, src6, src7); - src += (4 * src_stride); - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - ST_UB4(src4, src5, src6, src7, dst + 16, dst_stride); - dst += (4 * dst_stride); - - LD_UB4(src, src_stride, src0, src1, src2, src3); - LD_UB4(src + 16, src_stride, src4, src5, src6, src7); - src += (4 * src_stride); - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - ST_UB4(src4, src5, src6, src7, dst + 16, dst_stride); - dst += (4 * dst_stride); - } - } else if (0 == height % 8) { - copy_16multx8mult_msa(src, src_stride, dst, dst_stride, height, 32); - } else if (0 == height % 4) { - for (cnt = (height >> 2); cnt--;) { - LD_UB4(src, src_stride, src0, src1, src2, src3); - LD_UB4(src + 16, src_stride, src4, src5, src6, src7); - src += (4 * src_stride); - ST_UB4(src0, src1, src2, src3, dst, dst_stride); - ST_UB4(src4, src5, src6, src7, dst + 16, dst_stride); - dst += (4 * dst_stride); - } - } -} - -static void copy_width64_msa(const uint8_t *src, int32_t src_stride, - uint8_t *dst, int32_t dst_stride, int32_t height) { - copy_16multx8mult_msa(src, src_stride, dst, dst_stride, height, 64); -} - -void vpx_convolve_copy_msa(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int32_t x_step_q4, int y0_q4, int32_t y_step_q4, - int32_t w, int32_t h) { - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - switch (w) { - case 4: { - uint32_t cnt, tmp; - /* 1 word storage */ - for (cnt = h; cnt--;) { - tmp = LW(src); - SW(tmp, dst); - src += src_stride; - dst += dst_stride; - } - break; - } - case 8: { - copy_width8_msa(src, src_stride, dst, dst_stride, h); - break; - } - case 16: { - copy_width16_msa(src, src_stride, dst, dst_stride, h); - break; - } - case 32: { - copy_width32_msa(src, src_stride, dst, dst_stride, h); - break; - } - case 64: { - copy_width64_msa(src, src_stride, dst, dst_stride, h); - break; - } - default: { - uint32_t cnt; - for (cnt = h; cnt--;) { - memcpy(dst, src, w); - src += src_stride; - dst += dst_stride; - } - break; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve_msa.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve_msa.h deleted file mode 100644 index a0280c54..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/mips/vpx_convolve_msa.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_MIPS_VPX_CONVOLVE_MSA_H_ -#define VPX_VPX_DSP_MIPS_VPX_CONVOLVE_MSA_H_ - -#include "vpx_dsp/mips/macros_msa.h" -#include "vpx_dsp/vpx_filter.h" - -extern const uint8_t mc_filt_mask_arr[16 * 3]; - -#define FILT_8TAP_DPADD_S_H(vec0, vec1, vec2, vec3, filt0, filt1, filt2, \ - filt3) \ - ({ \ - v8i16 tmp_dpadd_0, tmp_dpadd_1; \ - \ - tmp_dpadd_0 = __msa_dotp_s_h((v16i8)vec0, (v16i8)filt0); \ - tmp_dpadd_0 = __msa_dpadd_s_h(tmp_dpadd_0, (v16i8)vec1, (v16i8)filt1); \ - tmp_dpadd_1 = __msa_dotp_s_h((v16i8)vec2, (v16i8)filt2); \ - tmp_dpadd_1 = __msa_dpadd_s_h(tmp_dpadd_1, (v16i8)vec3, (v16i8)filt3); \ - tmp_dpadd_0 = __msa_adds_s_h(tmp_dpadd_0, tmp_dpadd_1); \ - \ - tmp_dpadd_0; \ - }) - -#define HORIZ_8TAP_FILT(src0, src1, mask0, mask1, mask2, mask3, filt_h0, \ - filt_h1, filt_h2, filt_h3) \ - ({ \ - v16i8 vec0_m, vec1_m, vec2_m, vec3_m; \ - v8i16 hz_out_m; \ - \ - VSHF_B4_SB(src0, src1, mask0, mask1, mask2, mask3, vec0_m, vec1_m, vec2_m, \ - vec3_m); \ - hz_out_m = FILT_8TAP_DPADD_S_H(vec0_m, vec1_m, vec2_m, vec3_m, filt_h0, \ - filt_h1, filt_h2, filt_h3); \ - \ - hz_out_m = __msa_srari_h(hz_out_m, FILTER_BITS); \ - hz_out_m = __msa_sat_s_h(hz_out_m, 7); \ - \ - hz_out_m; \ - }) - -#define HORIZ_8TAP_4WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, \ - mask2, mask3, filt0, filt1, filt2, filt3, \ - out0, out1) \ - { \ - v16i8 vec0_m, vec1_m, vec2_m, vec3_m, vec4_m, vec5_m, vec6_m, vec7_m; \ - v8i16 res0_m, res1_m, res2_m, res3_m; \ - \ - VSHF_B2_SB(src0, src1, src2, src3, mask0, mask0, vec0_m, vec1_m); \ - DOTP_SB2_SH(vec0_m, vec1_m, filt0, filt0, res0_m, res1_m); \ - VSHF_B2_SB(src0, src1, src2, src3, mask1, mask1, vec2_m, vec3_m); \ - DPADD_SB2_SH(vec2_m, vec3_m, filt1, filt1, res0_m, res1_m); \ - VSHF_B2_SB(src0, src1, src2, src3, mask2, mask2, vec4_m, vec5_m); \ - DOTP_SB2_SH(vec4_m, vec5_m, filt2, filt2, res2_m, res3_m); \ - VSHF_B2_SB(src0, src1, src2, src3, mask3, mask3, vec6_m, vec7_m); \ - DPADD_SB2_SH(vec6_m, vec7_m, filt3, filt3, res2_m, res3_m); \ - ADDS_SH2_SH(res0_m, res2_m, res1_m, res3_m, out0, out1); \ - } - -#define HORIZ_8TAP_8WID_4VECS_FILT(src0, src1, src2, src3, mask0, mask1, \ - mask2, mask3, filt0, filt1, filt2, filt3, \ - out0, out1, out2, out3) \ - { \ - v16i8 vec0_m, vec1_m, vec2_m, vec3_m, vec4_m, vec5_m, vec6_m, vec7_m; \ - v8i16 res0_m, res1_m, res2_m, res3_m, res4_m, res5_m, res6_m, res7_m; \ - \ - VSHF_B2_SB(src0, src0, src1, src1, mask0, mask0, vec0_m, vec1_m); \ - VSHF_B2_SB(src2, src2, src3, src3, mask0, mask0, vec2_m, vec3_m); \ - DOTP_SB4_SH(vec0_m, vec1_m, vec2_m, vec3_m, filt0, filt0, filt0, filt0, \ - res0_m, res1_m, res2_m, res3_m); \ - VSHF_B2_SB(src0, src0, src1, src1, mask2, mask2, vec0_m, vec1_m); \ - VSHF_B2_SB(src2, src2, src3, src3, mask2, mask2, vec2_m, vec3_m); \ - DOTP_SB4_SH(vec0_m, vec1_m, vec2_m, vec3_m, filt2, filt2, filt2, filt2, \ - res4_m, res5_m, res6_m, res7_m); \ - VSHF_B2_SB(src0, src0, src1, src1, mask1, mask1, vec4_m, vec5_m); \ - VSHF_B2_SB(src2, src2, src3, src3, mask1, mask1, vec6_m, vec7_m); \ - DPADD_SB4_SH(vec4_m, vec5_m, vec6_m, vec7_m, filt1, filt1, filt1, filt1, \ - res0_m, res1_m, res2_m, res3_m); \ - VSHF_B2_SB(src0, src0, src1, src1, mask3, mask3, vec4_m, vec5_m); \ - VSHF_B2_SB(src2, src2, src3, src3, mask3, mask3, vec6_m, vec7_m); \ - DPADD_SB4_SH(vec4_m, vec5_m, vec6_m, vec7_m, filt3, filt3, filt3, filt3, \ - res4_m, res5_m, res6_m, res7_m); \ - ADDS_SH4_SH(res0_m, res4_m, res1_m, res5_m, res2_m, res6_m, res3_m, \ - res7_m, out0, out1, out2, out3); \ - } - -#define PCKEV_XORI128_AVG_ST_UB(in0, in1, dst, pdst) \ - { \ - v16u8 tmp_m; \ - \ - tmp_m = PCKEV_XORI128_UB(in1, in0); \ - tmp_m = __msa_aver_u_b(tmp_m, (v16u8)dst); \ - ST_UB(tmp_m, (pdst)); \ - } - -#define PCKEV_AVG_ST_UB(in0, in1, dst, pdst) \ - { \ - v16u8 tmp_m; \ - \ - tmp_m = (v16u8)__msa_pckev_b((v16i8)in0, (v16i8)in1); \ - tmp_m = __msa_aver_u_b(tmp_m, (v16u8)dst); \ - ST_UB(tmp_m, (pdst)); \ - } - -#define PCKEV_AVG_ST8x4_UB(in0, in1, in2, in3, dst0, dst1, pdst, stride) \ - { \ - v16u8 tmp0_m, tmp1_m; \ - uint8_t *pdst_m = (uint8_t *)(pdst); \ - \ - PCKEV_B2_UB(in1, in0, in3, in2, tmp0_m, tmp1_m); \ - AVER_UB2_UB(tmp0_m, dst0, tmp1_m, dst1, tmp0_m, tmp1_m); \ - ST8x4_UB(tmp0_m, tmp1_m, pdst_m, stride); \ - } -#endif // VPX_VPX_DSP_MIPS_VPX_CONVOLVE_MSA_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/postproc.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/postproc.h deleted file mode 100644 index 37f993f8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/postproc.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_POSTPROC_H_ -#define VPX_VPX_DSP_POSTPROC_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -// Fills a noise buffer with gaussian noise strength determined by sigma. -int vpx_setup_noise(double sigma, int8_t *noise, int size); - -#ifdef __cplusplus -} -#endif - -#endif // VPX_VPX_DSP_POSTPROC_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/bitdepth_conversion_vsx.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/bitdepth_conversion_vsx.h deleted file mode 100644 index 7ac873f9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/bitdepth_conversion_vsx.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_PPC_BITDEPTH_CONVERSION_VSX_H_ -#define VPX_VPX_DSP_PPC_BITDEPTH_CONVERSION_VSX_H_ - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/ppc/types_vsx.h" - -// Load 8 16 bit values. If the source is 32 bits then pack down with -// saturation. -static INLINE int16x8_t load_tran_low(int32_t c, const tran_low_t *s) { -#if CONFIG_VP9_HIGHBITDEPTH - int32x4_t u = vec_vsx_ld(c, s); - int32x4_t v = vec_vsx_ld(c, s + 4); - return vec_packs(u, v); -#else - return vec_vsx_ld(c, s); -#endif -} - -// Store 8 16 bit values. If the destination is 32 bits then sign extend the -// values by multiplying by 1. -static INLINE void store_tran_low(int16x8_t v, int32_t c, tran_low_t *s) { -#if CONFIG_VP9_HIGHBITDEPTH - const int16x8_t one = vec_splat_s16(1); - const int32x4_t even = vec_mule(v, one); - const int32x4_t odd = vec_mulo(v, one); - const int32x4_t high = vec_mergeh(even, odd); - const int32x4_t low = vec_mergel(even, odd); - vec_vsx_st(high, c, s); - vec_vsx_st(low, c, s + 4); -#else - vec_vsx_st(v, c, s); -#endif -} - -#endif // VPX_VPX_DSP_PPC_BITDEPTH_CONVERSION_VSX_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/deblock_vsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/deblock_vsx.c deleted file mode 100644 index 21299116..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/deblock_vsx.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/ppc/types_vsx.h" - -extern const int16_t vpx_rv[]; - -static const uint8x16_t load_merge = { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, - 0x0C, 0x0E, 0x18, 0x19, 0x1A, 0x1B, - 0x1C, 0x1D, 0x1E, 0x1F }; - -static const uint8x16_t st8_perm = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x18, 0x19, 0x1A, 0x1B, - 0x1C, 0x1D, 0x1E, 0x1F }; - -static INLINE uint8x16_t apply_filter(uint8x16_t ctx[4], uint8x16_t v, - uint8x16_t filter) { - const uint8x16_t k1 = vec_avg(ctx[0], ctx[1]); - const uint8x16_t k2 = vec_avg(ctx[3], ctx[2]); - const uint8x16_t k3 = vec_avg(k1, k2); - const uint8x16_t f_a = vec_max(vec_absd(v, ctx[0]), vec_absd(v, ctx[1])); - const uint8x16_t f_b = vec_max(vec_absd(v, ctx[2]), vec_absd(v, ctx[3])); - const bool8x16_t mask = vec_cmplt(vec_max(f_a, f_b), filter); - return vec_sel(v, vec_avg(k3, v), mask); -} - -static INLINE void vert_ctx(uint8x16_t ctx[4], int col, uint8_t *src, - int stride) { - ctx[0] = vec_vsx_ld(col - 2 * stride, src); - ctx[1] = vec_vsx_ld(col - stride, src); - ctx[2] = vec_vsx_ld(col + stride, src); - ctx[3] = vec_vsx_ld(col + 2 * stride, src); -} - -static INLINE void horz_ctx(uint8x16_t ctx[4], uint8x16_t left_ctx, - uint8x16_t v, uint8x16_t right_ctx) { - static const uint8x16_t l2_perm = { 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D }; - - static const uint8x16_t l1_perm = { 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, - 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, - 0x1B, 0x1C, 0x1D, 0x1E }; - - static const uint8x16_t r1_perm = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10 }; - - static const uint8x16_t r2_perm = { 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x10, 0x11 }; - ctx[0] = vec_perm(left_ctx, v, l2_perm); - ctx[1] = vec_perm(left_ctx, v, l1_perm); - ctx[2] = vec_perm(v, right_ctx, r1_perm); - ctx[3] = vec_perm(v, right_ctx, r2_perm); -} -void vpx_post_proc_down_and_across_mb_row_vsx(unsigned char *src_ptr, - unsigned char *dst_ptr, - int src_pixels_per_line, - int dst_pixels_per_line, int cols, - unsigned char *f, int size) { - int row, col; - uint8x16_t ctx[4], out, v, left_ctx; - - for (row = 0; row < size; row++) { - for (col = 0; col < cols - 8; col += 16) { - const uint8x16_t filter = vec_vsx_ld(col, f); - v = vec_vsx_ld(col, src_ptr); - vert_ctx(ctx, col, src_ptr, src_pixels_per_line); - vec_vsx_st(apply_filter(ctx, v, filter), col, dst_ptr); - } - - if (col != cols) { - const uint8x16_t filter = vec_vsx_ld(col, f); - v = vec_vsx_ld(col, src_ptr); - vert_ctx(ctx, col, src_ptr, src_pixels_per_line); - out = apply_filter(ctx, v, filter); - vec_vsx_st(vec_perm(out, v, st8_perm), col, dst_ptr); - } - - /* now post_proc_across */ - left_ctx = vec_splats(dst_ptr[0]); - v = vec_vsx_ld(0, dst_ptr); - for (col = 0; col < cols - 8; col += 16) { - const uint8x16_t filter = vec_vsx_ld(col, f); - const uint8x16_t right_ctx = (col + 16 == cols) - ? vec_splats(dst_ptr[cols - 1]) - : vec_vsx_ld(col, dst_ptr + 16); - horz_ctx(ctx, left_ctx, v, right_ctx); - vec_vsx_st(apply_filter(ctx, v, filter), col, dst_ptr); - left_ctx = v; - v = right_ctx; - } - - if (col != cols) { - const uint8x16_t filter = vec_vsx_ld(col, f); - const uint8x16_t right_ctx = vec_splats(dst_ptr[cols - 1]); - horz_ctx(ctx, left_ctx, v, right_ctx); - out = apply_filter(ctx, v, filter); - vec_vsx_st(vec_perm(out, v, st8_perm), col, dst_ptr); - } - - src_ptr += src_pixels_per_line; - dst_ptr += dst_pixels_per_line; - } -} - -// C: s[c + 7] -static INLINE int16x8_t next7l_s16(uint8x16_t c) { - static const uint8x16_t next7_perm = { - 0x07, 0x10, 0x08, 0x11, 0x09, 0x12, 0x0A, 0x13, - 0x0B, 0x14, 0x0C, 0x15, 0x0D, 0x16, 0x0E, 0x17, - }; - return (int16x8_t)vec_perm(c, vec_zeros_u8, next7_perm); -} - -// Slide across window and add. -static INLINE int16x8_t slide_sum_s16(int16x8_t x) { - // x = A B C D E F G H - // - // 0 A B C D E F G - const int16x8_t sum1 = vec_add(x, vec_slo(x, vec_splats((int8_t)(2 << 3)))); - // 0 0 A B C D E F - const int16x8_t sum2 = vec_add(vec_slo(x, vec_splats((int8_t)(4 << 3))), - // 0 0 0 A B C D E - vec_slo(x, vec_splats((int8_t)(6 << 3)))); - // 0 0 0 0 A B C D - const int16x8_t sum3 = vec_add(vec_slo(x, vec_splats((int8_t)(8 << 3))), - // 0 0 0 0 0 A B C - vec_slo(x, vec_splats((int8_t)(10 << 3)))); - // 0 0 0 0 0 0 A B - const int16x8_t sum4 = vec_add(vec_slo(x, vec_splats((int8_t)(12 << 3))), - // 0 0 0 0 0 0 0 A - vec_slo(x, vec_splats((int8_t)(14 << 3)))); - return vec_add(vec_add(sum1, sum2), vec_add(sum3, sum4)); -} - -// Slide across window and add. -static INLINE int32x4_t slide_sumsq_s32(int32x4_t xsq_even, int32x4_t xsq_odd) { - // 0 A C E - // + 0 B D F - int32x4_t sumsq_1 = vec_add(vec_slo(xsq_even, vec_splats((int8_t)(4 << 3))), - vec_slo(xsq_odd, vec_splats((int8_t)(4 << 3)))); - // 0 0 A C - // + 0 0 B D - int32x4_t sumsq_2 = vec_add(vec_slo(xsq_even, vec_splats((int8_t)(8 << 3))), - vec_slo(xsq_odd, vec_splats((int8_t)(8 << 3)))); - // 0 0 0 A - // + 0 0 0 B - int32x4_t sumsq_3 = vec_add(vec_slo(xsq_even, vec_splats((int8_t)(12 << 3))), - vec_slo(xsq_odd, vec_splats((int8_t)(12 << 3)))); - sumsq_1 = vec_add(sumsq_1, xsq_even); - sumsq_2 = vec_add(sumsq_2, sumsq_3); - return vec_add(sumsq_1, sumsq_2); -} - -// C: (b + sum + val) >> 4 -static INLINE int16x8_t filter_s16(int16x8_t b, int16x8_t sum, int16x8_t val) { - return vec_sra(vec_add(vec_add(b, sum), val), vec_splats((uint16_t)4)); -} - -// C: sumsq * 15 - sum * sum -static INLINE bool16x8_t mask_s16(int32x4_t sumsq_even, int32x4_t sumsq_odd, - int16x8_t sum, int32x4_t lim) { - static const uint8x16_t mask_merge = { 0x00, 0x01, 0x10, 0x11, 0x04, 0x05, - 0x14, 0x15, 0x08, 0x09, 0x18, 0x19, - 0x0C, 0x0D, 0x1C, 0x1D }; - const int32x4_t sumsq_odd_scaled = - vec_mul(sumsq_odd, vec_splats((int32_t)15)); - const int32x4_t sumsq_even_scaled = - vec_mul(sumsq_even, vec_splats((int32_t)15)); - const int32x4_t thres_odd = vec_sub(sumsq_odd_scaled, vec_mulo(sum, sum)); - const int32x4_t thres_even = vec_sub(sumsq_even_scaled, vec_mule(sum, sum)); - - const bool32x4_t mask_odd = vec_cmplt(thres_odd, lim); - const bool32x4_t mask_even = vec_cmplt(thres_even, lim); - return vec_perm((bool16x8_t)mask_even, (bool16x8_t)mask_odd, mask_merge); -} - -void vpx_mbpost_proc_across_ip_vsx(unsigned char *src, int pitch, int rows, - int cols, int flimit) { - int row, col; - const int32x4_t lim = vec_splats(flimit); - - // 8 columns are processed at a time. - assert(cols % 8 == 0); - - for (row = 0; row < rows; row++) { - // The sum is signed and requires at most 13 bits. - // (8 bits + sign) * 15 (4 bits) - int16x8_t sum; - // The sum of squares requires at most 20 bits. - // (16 bits + sign) * 15 (4 bits) - int32x4_t sumsq_even, sumsq_odd; - - // Fill left context with first col. - int16x8_t left_ctx = vec_splats((int16_t)src[0]); - int16_t s = src[0] * 9; - int32_t ssq = src[0] * src[0] * 9 + 16; - - // Fill the next 6 columns of the sliding window with cols 2 to 7. - for (col = 1; col <= 6; ++col) { - s += src[col]; - ssq += src[col] * src[col]; - } - // Set this sum to every element in the window. - sum = vec_splats(s); - sumsq_even = vec_splats(ssq); - sumsq_odd = vec_splats(ssq); - - for (col = 0; col < cols; col += 8) { - bool16x8_t mask; - int16x8_t filtered, masked; - uint8x16_t out; - - const uint8x16_t val = vec_vsx_ld(0, src + col); - const int16x8_t val_high = unpack_to_s16_h(val); - - // C: s[c + 7] - const int16x8_t right_ctx = (col + 8 == cols) - ? vec_splats((int16_t)src[col + 7]) - : next7l_s16(val); - - // C: x = s[c + 7] - s[c - 8]; - const int16x8_t x = vec_sub(right_ctx, left_ctx); - const int32x4_t xsq_even = - vec_sub(vec_mule(right_ctx, right_ctx), vec_mule(left_ctx, left_ctx)); - const int32x4_t xsq_odd = - vec_sub(vec_mulo(right_ctx, right_ctx), vec_mulo(left_ctx, left_ctx)); - - const int32x4_t sumsq_tmp = slide_sumsq_s32(xsq_even, xsq_odd); - // A C E G - // 0 B D F - // 0 A C E - // 0 0 B D - // 0 0 A C - // 0 0 0 B - // 0 0 0 A - sumsq_even = vec_add(sumsq_even, sumsq_tmp); - // B D F G - // A C E G - // 0 B D F - // 0 A C E - // 0 0 B D - // 0 0 A C - // 0 0 0 B - // 0 0 0 A - sumsq_odd = vec_add(sumsq_odd, vec_add(sumsq_tmp, xsq_odd)); - - sum = vec_add(sum, slide_sum_s16(x)); - - // C: (8 + sum + s[c]) >> 4 - filtered = filter_s16(vec_splats((int16_t)8), sum, val_high); - // C: sumsq * 15 - sum * sum - mask = mask_s16(sumsq_even, sumsq_odd, sum, lim); - masked = vec_sel(val_high, filtered, mask); - - out = vec_perm((uint8x16_t)masked, vec_vsx_ld(0, src + col), load_merge); - vec_vsx_st(out, 0, src + col); - - // Update window sum and square sum - sum = vec_splat(sum, 7); - sumsq_even = vec_splat(sumsq_odd, 3); - sumsq_odd = vec_splat(sumsq_odd, 3); - - // C: s[c - 8] (for next iteration) - left_ctx = val_high; - } - src += pitch; - } -} - -void vpx_mbpost_proc_down_vsx(uint8_t *dst, int pitch, int rows, int cols, - int flimit) { - int col, row, i; - int16x8_t window[16]; - const int32x4_t lim = vec_splats(flimit); - - // 8 columns are processed at a time. - assert(cols % 8 == 0); - // If rows is less than 8 the bottom border extension fails. - assert(rows >= 8); - - for (col = 0; col < cols; col += 8) { - // The sum is signed and requires at most 13 bits. - // (8 bits + sign) * 15 (4 bits) - int16x8_t r1, sum; - // The sum of squares requires at most 20 bits. - // (16 bits + sign) * 15 (4 bits) - int32x4_t sumsq_even, sumsq_odd; - - r1 = unpack_to_s16_h(vec_vsx_ld(0, dst)); - // Fill sliding window with first row. - for (i = 0; i <= 8; i++) { - window[i] = r1; - } - // First 9 rows of the sliding window are the same. - // sum = r1 * 9 - sum = vec_mladd(r1, vec_splats((int16_t)9), vec_zeros_s16); - - // sumsq = r1 * r1 * 9 - sumsq_even = vec_mule(sum, r1); - sumsq_odd = vec_mulo(sum, r1); - - // Fill the next 6 rows of the sliding window with rows 2 to 7. - for (i = 1; i <= 6; ++i) { - const int16x8_t next_row = unpack_to_s16_h(vec_vsx_ld(i * pitch, dst)); - window[i + 8] = next_row; - sum = vec_add(sum, next_row); - sumsq_odd = vec_add(sumsq_odd, vec_mulo(next_row, next_row)); - sumsq_even = vec_add(sumsq_even, vec_mule(next_row, next_row)); - } - - for (row = 0; row < rows; row++) { - int32x4_t d15_even, d15_odd, d0_even, d0_odd; - bool16x8_t mask; - int16x8_t filtered, masked; - uint8x16_t out; - - const int16x8_t rv = vec_vsx_ld(0, vpx_rv + (row & 127)); - - // Move the sliding window - if (row + 7 < rows) { - window[15] = unpack_to_s16_h(vec_vsx_ld((row + 7) * pitch, dst)); - } else { - window[15] = window[14]; - } - - // C: sum += s[7 * pitch] - s[-8 * pitch]; - sum = vec_add(sum, vec_sub(window[15], window[0])); - - // C: sumsq += s[7 * pitch] * s[7 * pitch] - s[-8 * pitch] * s[-8 * - // pitch]; - // Optimization Note: Caching a squared-window for odd and even is - // slower than just repeating the multiplies. - d15_odd = vec_mulo(window[15], window[15]); - d15_even = vec_mule(window[15], window[15]); - d0_odd = vec_mulo(window[0], window[0]); - d0_even = vec_mule(window[0], window[0]); - sumsq_odd = vec_add(sumsq_odd, vec_sub(d15_odd, d0_odd)); - sumsq_even = vec_add(sumsq_even, vec_sub(d15_even, d0_even)); - - // C: (vpx_rv[(r & 127) + (c & 7)] + sum + s[0]) >> 4 - filtered = filter_s16(rv, sum, window[8]); - - // C: sumsq * 15 - sum * sum - mask = mask_s16(sumsq_even, sumsq_odd, sum, lim); - masked = vec_sel(window[8], filtered, mask); - - // TODO(ltrudeau) If cols % 16 == 0, we could just process 16 per - // iteration - out = vec_perm((uint8x16_t)masked, vec_vsx_ld(0, dst + row * pitch), - load_merge); - vec_vsx_st(out, 0, dst + row * pitch); - - // Optimization Note: Turns out that the following loop is faster than - // using pointers to manage the sliding window. - for (i = 1; i < 16; i++) { - window[i - 1] = window[i]; - } - } - dst += 8; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/fdct32x32_vsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/fdct32x32_vsx.c deleted file mode 100644 index 328b0e31..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/fdct32x32_vsx.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx_dsp/ppc/transpose_vsx.h" -#include "vpx_dsp/ppc/txfm_common_vsx.h" -#include "vpx_dsp/ppc/types_vsx.h" - -// Returns ((a +/- b) * cospi16 + (2 << 13)) >> 14. -static INLINE void single_butterfly(int16x8_t a, int16x8_t b, int16x8_t *add, - int16x8_t *sub) { - // Since a + b can overflow 16 bits, the multiplication is distributed - // (a * c +/- b * c). - const int32x4_t ac_e = vec_mule(a, cospi16_v); - const int32x4_t ac_o = vec_mulo(a, cospi16_v); - const int32x4_t bc_e = vec_mule(b, cospi16_v); - const int32x4_t bc_o = vec_mulo(b, cospi16_v); - - // Reuse the same multiplies for sum and difference. - const int32x4_t sum_e = vec_add(ac_e, bc_e); - const int32x4_t sum_o = vec_add(ac_o, bc_o); - const int32x4_t diff_e = vec_sub(ac_e, bc_e); - const int32x4_t diff_o = vec_sub(ac_o, bc_o); - - // Add rounding offset - const int32x4_t rsum_o = vec_add(sum_o, vec_dct_const_rounding); - const int32x4_t rsum_e = vec_add(sum_e, vec_dct_const_rounding); - const int32x4_t rdiff_o = vec_add(diff_o, vec_dct_const_rounding); - const int32x4_t rdiff_e = vec_add(diff_e, vec_dct_const_rounding); - - const int32x4_t ssum_o = vec_sra(rsum_o, vec_dct_const_bits); - const int32x4_t ssum_e = vec_sra(rsum_e, vec_dct_const_bits); - const int32x4_t sdiff_o = vec_sra(rdiff_o, vec_dct_const_bits); - const int32x4_t sdiff_e = vec_sra(rdiff_e, vec_dct_const_bits); - - // There's no pack operation for even and odd, so we need to permute. - *add = (int16x8_t)vec_perm(ssum_e, ssum_o, vec_perm_odd_even_pack); - *sub = (int16x8_t)vec_perm(sdiff_e, sdiff_o, vec_perm_odd_even_pack); -} - -// Returns (a * c1 +/- b * c2 + (2 << 13)) >> 14 -static INLINE void double_butterfly(int16x8_t a, int16x8_t c1, int16x8_t b, - int16x8_t c2, int16x8_t *add, - int16x8_t *sub) { - const int32x4_t ac1_o = vec_mulo(a, c1); - const int32x4_t ac1_e = vec_mule(a, c1); - const int32x4_t ac2_o = vec_mulo(a, c2); - const int32x4_t ac2_e = vec_mule(a, c2); - - const int32x4_t bc1_o = vec_mulo(b, c1); - const int32x4_t bc1_e = vec_mule(b, c1); - const int32x4_t bc2_o = vec_mulo(b, c2); - const int32x4_t bc2_e = vec_mule(b, c2); - - const int32x4_t sum_o = vec_add(ac1_o, bc2_o); - const int32x4_t sum_e = vec_add(ac1_e, bc2_e); - const int32x4_t diff_o = vec_sub(ac2_o, bc1_o); - const int32x4_t diff_e = vec_sub(ac2_e, bc1_e); - - // Add rounding offset - const int32x4_t rsum_o = vec_add(sum_o, vec_dct_const_rounding); - const int32x4_t rsum_e = vec_add(sum_e, vec_dct_const_rounding); - const int32x4_t rdiff_o = vec_add(diff_o, vec_dct_const_rounding); - const int32x4_t rdiff_e = vec_add(diff_e, vec_dct_const_rounding); - - const int32x4_t ssum_o = vec_sra(rsum_o, vec_dct_const_bits); - const int32x4_t ssum_e = vec_sra(rsum_e, vec_dct_const_bits); - const int32x4_t sdiff_o = vec_sra(rdiff_o, vec_dct_const_bits); - const int32x4_t sdiff_e = vec_sra(rdiff_e, vec_dct_const_bits); - - // There's no pack operation for even and odd, so we need to permute. - *add = (int16x8_t)vec_perm(ssum_e, ssum_o, vec_perm_odd_even_pack); - *sub = (int16x8_t)vec_perm(sdiff_e, sdiff_o, vec_perm_odd_even_pack); -} - -// While other architecture combine the load and the stage 1 operations, Power9 -// benchmarking show no benefit in such an approach. -static INLINE void load(const int16_t *a, int stride, int16x8_t *b) { - // Tried out different combinations of load and shift instructions, this is - // the fastest one. - { - const int16x8_t l0 = vec_vsx_ld(0, a); - const int16x8_t l1 = vec_vsx_ld(0, a + stride); - const int16x8_t l2 = vec_vsx_ld(0, a + 2 * stride); - const int16x8_t l3 = vec_vsx_ld(0, a + 3 * stride); - const int16x8_t l4 = vec_vsx_ld(0, a + 4 * stride); - const int16x8_t l5 = vec_vsx_ld(0, a + 5 * stride); - const int16x8_t l6 = vec_vsx_ld(0, a + 6 * stride); - const int16x8_t l7 = vec_vsx_ld(0, a + 7 * stride); - - const int16x8_t l8 = vec_vsx_ld(0, a + 8 * stride); - const int16x8_t l9 = vec_vsx_ld(0, a + 9 * stride); - const int16x8_t l10 = vec_vsx_ld(0, a + 10 * stride); - const int16x8_t l11 = vec_vsx_ld(0, a + 11 * stride); - const int16x8_t l12 = vec_vsx_ld(0, a + 12 * stride); - const int16x8_t l13 = vec_vsx_ld(0, a + 13 * stride); - const int16x8_t l14 = vec_vsx_ld(0, a + 14 * stride); - const int16x8_t l15 = vec_vsx_ld(0, a + 15 * stride); - - b[0] = vec_sl(l0, vec_dct_scale_log2); - b[1] = vec_sl(l1, vec_dct_scale_log2); - b[2] = vec_sl(l2, vec_dct_scale_log2); - b[3] = vec_sl(l3, vec_dct_scale_log2); - b[4] = vec_sl(l4, vec_dct_scale_log2); - b[5] = vec_sl(l5, vec_dct_scale_log2); - b[6] = vec_sl(l6, vec_dct_scale_log2); - b[7] = vec_sl(l7, vec_dct_scale_log2); - - b[8] = vec_sl(l8, vec_dct_scale_log2); - b[9] = vec_sl(l9, vec_dct_scale_log2); - b[10] = vec_sl(l10, vec_dct_scale_log2); - b[11] = vec_sl(l11, vec_dct_scale_log2); - b[12] = vec_sl(l12, vec_dct_scale_log2); - b[13] = vec_sl(l13, vec_dct_scale_log2); - b[14] = vec_sl(l14, vec_dct_scale_log2); - b[15] = vec_sl(l15, vec_dct_scale_log2); - } - { - const int16x8_t l16 = vec_vsx_ld(0, a + 16 * stride); - const int16x8_t l17 = vec_vsx_ld(0, a + 17 * stride); - const int16x8_t l18 = vec_vsx_ld(0, a + 18 * stride); - const int16x8_t l19 = vec_vsx_ld(0, a + 19 * stride); - const int16x8_t l20 = vec_vsx_ld(0, a + 20 * stride); - const int16x8_t l21 = vec_vsx_ld(0, a + 21 * stride); - const int16x8_t l22 = vec_vsx_ld(0, a + 22 * stride); - const int16x8_t l23 = vec_vsx_ld(0, a + 23 * stride); - - const int16x8_t l24 = vec_vsx_ld(0, a + 24 * stride); - const int16x8_t l25 = vec_vsx_ld(0, a + 25 * stride); - const int16x8_t l26 = vec_vsx_ld(0, a + 26 * stride); - const int16x8_t l27 = vec_vsx_ld(0, a + 27 * stride); - const int16x8_t l28 = vec_vsx_ld(0, a + 28 * stride); - const int16x8_t l29 = vec_vsx_ld(0, a + 29 * stride); - const int16x8_t l30 = vec_vsx_ld(0, a + 30 * stride); - const int16x8_t l31 = vec_vsx_ld(0, a + 31 * stride); - - b[16] = vec_sl(l16, vec_dct_scale_log2); - b[17] = vec_sl(l17, vec_dct_scale_log2); - b[18] = vec_sl(l18, vec_dct_scale_log2); - b[19] = vec_sl(l19, vec_dct_scale_log2); - b[20] = vec_sl(l20, vec_dct_scale_log2); - b[21] = vec_sl(l21, vec_dct_scale_log2); - b[22] = vec_sl(l22, vec_dct_scale_log2); - b[23] = vec_sl(l23, vec_dct_scale_log2); - - b[24] = vec_sl(l24, vec_dct_scale_log2); - b[25] = vec_sl(l25, vec_dct_scale_log2); - b[26] = vec_sl(l26, vec_dct_scale_log2); - b[27] = vec_sl(l27, vec_dct_scale_log2); - b[28] = vec_sl(l28, vec_dct_scale_log2); - b[29] = vec_sl(l29, vec_dct_scale_log2); - b[30] = vec_sl(l30, vec_dct_scale_log2); - b[31] = vec_sl(l31, vec_dct_scale_log2); - } -} - -static INLINE void store(tran_low_t *a, const int16x8_t *b) { - vec_vsx_st(b[0], 0, a); - vec_vsx_st(b[8], 0, a + 8); - vec_vsx_st(b[16], 0, a + 16); - vec_vsx_st(b[24], 0, a + 24); - - vec_vsx_st(b[1], 0, a + 32); - vec_vsx_st(b[9], 0, a + 40); - vec_vsx_st(b[17], 0, a + 48); - vec_vsx_st(b[25], 0, a + 56); - - vec_vsx_st(b[2], 0, a + 64); - vec_vsx_st(b[10], 0, a + 72); - vec_vsx_st(b[18], 0, a + 80); - vec_vsx_st(b[26], 0, a + 88); - - vec_vsx_st(b[3], 0, a + 96); - vec_vsx_st(b[11], 0, a + 104); - vec_vsx_st(b[19], 0, a + 112); - vec_vsx_st(b[27], 0, a + 120); - - vec_vsx_st(b[4], 0, a + 128); - vec_vsx_st(b[12], 0, a + 136); - vec_vsx_st(b[20], 0, a + 144); - vec_vsx_st(b[28], 0, a + 152); - - vec_vsx_st(b[5], 0, a + 160); - vec_vsx_st(b[13], 0, a + 168); - vec_vsx_st(b[21], 0, a + 176); - vec_vsx_st(b[29], 0, a + 184); - - vec_vsx_st(b[6], 0, a + 192); - vec_vsx_st(b[14], 0, a + 200); - vec_vsx_st(b[22], 0, a + 208); - vec_vsx_st(b[30], 0, a + 216); - - vec_vsx_st(b[7], 0, a + 224); - vec_vsx_st(b[15], 0, a + 232); - vec_vsx_st(b[23], 0, a + 240); - vec_vsx_st(b[31], 0, a + 248); -} - -// Returns 1 if negative 0 if positive -static INLINE int16x8_t vec_sign_s16(int16x8_t a) { - return vec_sr(a, vec_shift_sign_s16); -} - -// Add 2 if positive, 1 if negative, and shift by 2. -static INLINE int16x8_t sub_round_shift(const int16x8_t a) { - const int16x8_t sign = vec_sign_s16(a); - return vec_sra(vec_sub(vec_add(a, vec_twos_s16), sign), vec_dct_scale_log2); -} - -// Add 1 if positive, 2 if negative, and shift by 2. -// In practice, add 1, then add the sign bit, then shift without rounding. -static INLINE int16x8_t add_round_shift_s16(const int16x8_t a) { - const int16x8_t sign = vec_sign_s16(a); - return vec_sra(vec_add(vec_add(a, vec_ones_s16), sign), vec_dct_scale_log2); -} - -static void fdct32_vsx(const int16x8_t *in, int16x8_t *out, int pass) { - int16x8_t temp0[32]; // Hold stages: 1, 4, 7 - int16x8_t temp1[32]; // Hold stages: 2, 5 - int16x8_t temp2[32]; // Hold stages: 3, 6 - int i; - - // Stage 1 - // Unrolling this loops actually slows down Power9 benchmarks - for (i = 0; i < 16; i++) { - temp0[i] = vec_add(in[i], in[31 - i]); - // pass through to stage 3. - temp1[i + 16] = vec_sub(in[15 - i], in[i + 16]); - } - - // Stage 2 - // Unrolling this loops actually slows down Power9 benchmarks - for (i = 0; i < 8; i++) { - temp1[i] = vec_add(temp0[i], temp0[15 - i]); - temp1[i + 8] = vec_sub(temp0[7 - i], temp0[i + 8]); - } - - // Apply butterflies (in place) on pass through to stage 3. - single_butterfly(temp1[27], temp1[20], &temp1[27], &temp1[20]); - single_butterfly(temp1[26], temp1[21], &temp1[26], &temp1[21]); - single_butterfly(temp1[25], temp1[22], &temp1[25], &temp1[22]); - single_butterfly(temp1[24], temp1[23], &temp1[24], &temp1[23]); - - // dump the magnitude by 4, hence the intermediate values are within - // the range of 16 bits. - if (pass) { - temp1[0] = add_round_shift_s16(temp1[0]); - temp1[1] = add_round_shift_s16(temp1[1]); - temp1[2] = add_round_shift_s16(temp1[2]); - temp1[3] = add_round_shift_s16(temp1[3]); - temp1[4] = add_round_shift_s16(temp1[4]); - temp1[5] = add_round_shift_s16(temp1[5]); - temp1[6] = add_round_shift_s16(temp1[6]); - temp1[7] = add_round_shift_s16(temp1[7]); - temp1[8] = add_round_shift_s16(temp1[8]); - temp1[9] = add_round_shift_s16(temp1[9]); - temp1[10] = add_round_shift_s16(temp1[10]); - temp1[11] = add_round_shift_s16(temp1[11]); - temp1[12] = add_round_shift_s16(temp1[12]); - temp1[13] = add_round_shift_s16(temp1[13]); - temp1[14] = add_round_shift_s16(temp1[14]); - temp1[15] = add_round_shift_s16(temp1[15]); - - temp1[16] = add_round_shift_s16(temp1[16]); - temp1[17] = add_round_shift_s16(temp1[17]); - temp1[18] = add_round_shift_s16(temp1[18]); - temp1[19] = add_round_shift_s16(temp1[19]); - temp1[20] = add_round_shift_s16(temp1[20]); - temp1[21] = add_round_shift_s16(temp1[21]); - temp1[22] = add_round_shift_s16(temp1[22]); - temp1[23] = add_round_shift_s16(temp1[23]); - temp1[24] = add_round_shift_s16(temp1[24]); - temp1[25] = add_round_shift_s16(temp1[25]); - temp1[26] = add_round_shift_s16(temp1[26]); - temp1[27] = add_round_shift_s16(temp1[27]); - temp1[28] = add_round_shift_s16(temp1[28]); - temp1[29] = add_round_shift_s16(temp1[29]); - temp1[30] = add_round_shift_s16(temp1[30]); - temp1[31] = add_round_shift_s16(temp1[31]); - } - - // Stage 3 - temp2[0] = vec_add(temp1[0], temp1[7]); - temp2[1] = vec_add(temp1[1], temp1[6]); - temp2[2] = vec_add(temp1[2], temp1[5]); - temp2[3] = vec_add(temp1[3], temp1[4]); - temp2[5] = vec_sub(temp1[2], temp1[5]); - temp2[6] = vec_sub(temp1[1], temp1[6]); - temp2[8] = temp1[8]; - temp2[9] = temp1[9]; - - single_butterfly(temp1[13], temp1[10], &temp2[13], &temp2[10]); - single_butterfly(temp1[12], temp1[11], &temp2[12], &temp2[11]); - temp2[14] = temp1[14]; - temp2[15] = temp1[15]; - - temp2[18] = vec_add(temp1[18], temp1[21]); - temp2[19] = vec_add(temp1[19], temp1[20]); - - temp2[20] = vec_sub(temp1[19], temp1[20]); - temp2[21] = vec_sub(temp1[18], temp1[21]); - - temp2[26] = vec_sub(temp1[29], temp1[26]); - temp2[27] = vec_sub(temp1[28], temp1[27]); - - temp2[28] = vec_add(temp1[28], temp1[27]); - temp2[29] = vec_add(temp1[29], temp1[26]); - - // Pass through Stage 4 - temp0[7] = vec_sub(temp1[0], temp1[7]); - temp0[4] = vec_sub(temp1[3], temp1[4]); - temp0[16] = vec_add(temp1[16], temp1[23]); - temp0[17] = vec_add(temp1[17], temp1[22]); - temp0[22] = vec_sub(temp1[17], temp1[22]); - temp0[23] = vec_sub(temp1[16], temp1[23]); - temp0[24] = vec_sub(temp1[31], temp1[24]); - temp0[25] = vec_sub(temp1[30], temp1[25]); - temp0[30] = vec_add(temp1[30], temp1[25]); - temp0[31] = vec_add(temp1[31], temp1[24]); - - // Stage 4 - temp0[0] = vec_add(temp2[0], temp2[3]); - temp0[1] = vec_add(temp2[1], temp2[2]); - temp0[2] = vec_sub(temp2[1], temp2[2]); - temp0[3] = vec_sub(temp2[0], temp2[3]); - single_butterfly(temp2[6], temp2[5], &temp0[6], &temp0[5]); - - temp0[9] = vec_add(temp2[9], temp2[10]); - temp0[10] = vec_sub(temp2[9], temp2[10]); - temp0[13] = vec_sub(temp2[14], temp2[13]); - temp0[14] = vec_add(temp2[14], temp2[13]); - - double_butterfly(temp2[29], cospi8_v, temp2[18], cospi24_v, &temp0[29], - &temp0[18]); - double_butterfly(temp2[28], cospi8_v, temp2[19], cospi24_v, &temp0[28], - &temp0[19]); - double_butterfly(temp2[27], cospi24_v, temp2[20], cospi8m_v, &temp0[27], - &temp0[20]); - double_butterfly(temp2[26], cospi24_v, temp2[21], cospi8m_v, &temp0[26], - &temp0[21]); - - // Pass through Stage 5 - temp1[8] = vec_add(temp2[8], temp2[11]); - temp1[11] = vec_sub(temp2[8], temp2[11]); - temp1[12] = vec_sub(temp2[15], temp2[12]); - temp1[15] = vec_add(temp2[15], temp2[12]); - - // Stage 5 - // 0 and 1 pass through to 0 and 16 at the end - single_butterfly(temp0[0], temp0[1], &out[0], &out[16]); - - // 2 and 3 pass through to 8 and 24 at the end - double_butterfly(temp0[3], cospi8_v, temp0[2], cospi24_v, &out[8], &out[24]); - - temp1[4] = vec_add(temp0[4], temp0[5]); - temp1[5] = vec_sub(temp0[4], temp0[5]); - temp1[6] = vec_sub(temp0[7], temp0[6]); - temp1[7] = vec_add(temp0[7], temp0[6]); - - double_butterfly(temp0[14], cospi8_v, temp0[9], cospi24_v, &temp1[14], - &temp1[9]); - double_butterfly(temp0[13], cospi24_v, temp0[10], cospi8m_v, &temp1[13], - &temp1[10]); - - temp1[17] = vec_add(temp0[17], temp0[18]); - temp1[18] = vec_sub(temp0[17], temp0[18]); - - temp1[21] = vec_sub(temp0[22], temp0[21]); - temp1[22] = vec_add(temp0[22], temp0[21]); - - temp1[25] = vec_add(temp0[25], temp0[26]); - temp1[26] = vec_sub(temp0[25], temp0[26]); - - temp1[29] = vec_sub(temp0[30], temp0[29]); - temp1[30] = vec_add(temp0[30], temp0[29]); - - // Pass through Stage 6 - temp2[16] = vec_add(temp0[16], temp0[19]); - temp2[19] = vec_sub(temp0[16], temp0[19]); - temp2[20] = vec_sub(temp0[23], temp0[20]); - temp2[23] = vec_add(temp0[23], temp0[20]); - temp2[24] = vec_add(temp0[24], temp0[27]); - temp2[27] = vec_sub(temp0[24], temp0[27]); - temp2[28] = vec_sub(temp0[31], temp0[28]); - temp2[31] = vec_add(temp0[31], temp0[28]); - - // Stage 6 - // 4 and 7 pass through to 4 and 28 at the end - double_butterfly(temp1[7], cospi4_v, temp1[4], cospi28_v, &out[4], &out[28]); - // 5 and 6 pass through to 20 and 12 at the end - double_butterfly(temp1[6], cospi20_v, temp1[5], cospi12_v, &out[20], - &out[12]); - temp2[8] = vec_add(temp1[8], temp1[9]); - temp2[9] = vec_sub(temp1[8], temp1[9]); - temp2[10] = vec_sub(temp1[11], temp1[10]); - temp2[11] = vec_add(temp1[11], temp1[10]); - temp2[12] = vec_add(temp1[12], temp1[13]); - temp2[13] = vec_sub(temp1[12], temp1[13]); - temp2[14] = vec_sub(temp1[15], temp1[14]); - temp2[15] = vec_add(temp1[15], temp1[14]); - - double_butterfly(temp1[30], cospi4_v, temp1[17], cospi28_v, &temp2[30], - &temp2[17]); - double_butterfly(temp1[29], cospi28_v, temp1[18], cospi4m_v, &temp2[29], - &temp2[18]); - double_butterfly(temp1[26], cospi20_v, temp1[21], cospi12_v, &temp2[26], - &temp2[21]); - double_butterfly(temp1[25], cospi12_v, temp1[22], cospi20m_v, &temp2[25], - &temp2[22]); - - // Stage 7 - double_butterfly(temp2[15], cospi2_v, temp2[8], cospi30_v, &out[2], &out[30]); - double_butterfly(temp2[14], cospi18_v, temp2[9], cospi14_v, &out[18], - &out[14]); - double_butterfly(temp2[13], cospi10_v, temp2[10], cospi22_v, &out[10], - &out[22]); - double_butterfly(temp2[12], cospi26_v, temp2[11], cospi6_v, &out[26], - &out[6]); - - temp0[16] = vec_add(temp2[16], temp2[17]); - temp0[17] = vec_sub(temp2[16], temp2[17]); - temp0[18] = vec_sub(temp2[19], temp2[18]); - temp0[19] = vec_add(temp2[19], temp2[18]); - temp0[20] = vec_add(temp2[20], temp2[21]); - temp0[21] = vec_sub(temp2[20], temp2[21]); - temp0[22] = vec_sub(temp2[23], temp2[22]); - temp0[23] = vec_add(temp2[23], temp2[22]); - temp0[24] = vec_add(temp2[24], temp2[25]); - temp0[25] = vec_sub(temp2[24], temp2[25]); - temp0[26] = vec_sub(temp2[27], temp2[26]); - temp0[27] = vec_add(temp2[27], temp2[26]); - temp0[28] = vec_add(temp2[28], temp2[29]); - temp0[29] = vec_sub(temp2[28], temp2[29]); - temp0[30] = vec_sub(temp2[31], temp2[30]); - temp0[31] = vec_add(temp2[31], temp2[30]); - - // Final stage --- outputs indices are bit-reversed. - double_butterfly(temp0[31], cospi1_v, temp0[16], cospi31_v, &out[1], - &out[31]); - double_butterfly(temp0[30], cospi17_v, temp0[17], cospi15_v, &out[17], - &out[15]); - double_butterfly(temp0[29], cospi9_v, temp0[18], cospi23_v, &out[9], - &out[23]); - double_butterfly(temp0[28], cospi25_v, temp0[19], cospi7_v, &out[25], - &out[7]); - double_butterfly(temp0[27], cospi5_v, temp0[20], cospi27_v, &out[5], - &out[27]); - double_butterfly(temp0[26], cospi21_v, temp0[21], cospi11_v, &out[21], - &out[11]); - double_butterfly(temp0[25], cospi13_v, temp0[22], cospi19_v, &out[13], - &out[19]); - double_butterfly(temp0[24], cospi29_v, temp0[23], cospi3_v, &out[29], - &out[3]); - - if (pass == 0) { - for (i = 0; i < 32; i++) { - out[i] = sub_round_shift(out[i]); - } - } -} - -void vpx_fdct32x32_rd_vsx(const int16_t *input, tran_low_t *out, int stride) { - int16x8_t temp0[32]; - int16x8_t temp1[32]; - int16x8_t temp2[32]; - int16x8_t temp3[32]; - int16x8_t temp4[32]; - int16x8_t temp5[32]; - int16x8_t temp6[32]; - - // Process in 8x32 columns. - load(input, stride, temp0); - fdct32_vsx(temp0, temp1, 0); - - load(input + 8, stride, temp0); - fdct32_vsx(temp0, temp2, 0); - - load(input + 16, stride, temp0); - fdct32_vsx(temp0, temp3, 0); - - load(input + 24, stride, temp0); - fdct32_vsx(temp0, temp4, 0); - - // Generate the top row by munging the first set of 8 from each one - // together. - transpose_8x8(&temp1[0], &temp0[0]); - transpose_8x8(&temp2[0], &temp0[8]); - transpose_8x8(&temp3[0], &temp0[16]); - transpose_8x8(&temp4[0], &temp0[24]); - - fdct32_vsx(temp0, temp5, 1); - - transpose_8x8(&temp5[0], &temp6[0]); - transpose_8x8(&temp5[8], &temp6[8]); - transpose_8x8(&temp5[16], &temp6[16]); - transpose_8x8(&temp5[24], &temp6[24]); - - store(out, temp6); - - // Second row of 8x32. - transpose_8x8(&temp1[8], &temp0[0]); - transpose_8x8(&temp2[8], &temp0[8]); - transpose_8x8(&temp3[8], &temp0[16]); - transpose_8x8(&temp4[8], &temp0[24]); - - fdct32_vsx(temp0, temp5, 1); - - transpose_8x8(&temp5[0], &temp6[0]); - transpose_8x8(&temp5[8], &temp6[8]); - transpose_8x8(&temp5[16], &temp6[16]); - transpose_8x8(&temp5[24], &temp6[24]); - - store(out + 8 * 32, temp6); - - // Third row of 8x32 - transpose_8x8(&temp1[16], &temp0[0]); - transpose_8x8(&temp2[16], &temp0[8]); - transpose_8x8(&temp3[16], &temp0[16]); - transpose_8x8(&temp4[16], &temp0[24]); - - fdct32_vsx(temp0, temp5, 1); - - transpose_8x8(&temp5[0], &temp6[0]); - transpose_8x8(&temp5[8], &temp6[8]); - transpose_8x8(&temp5[16], &temp6[16]); - transpose_8x8(&temp5[24], &temp6[24]); - - store(out + 16 * 32, temp6); - - // Final row of 8x32. - transpose_8x8(&temp1[24], &temp0[0]); - transpose_8x8(&temp2[24], &temp0[8]); - transpose_8x8(&temp3[24], &temp0[16]); - transpose_8x8(&temp4[24], &temp0[24]); - - fdct32_vsx(temp0, temp5, 1); - - transpose_8x8(&temp5[0], &temp6[0]); - transpose_8x8(&temp5[8], &temp6[8]); - transpose_8x8(&temp5[16], &temp6[16]); - transpose_8x8(&temp5[24], &temp6[24]); - - store(out + 24 * 32, temp6); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/hadamard_vsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/hadamard_vsx.c deleted file mode 100644 index e279b304..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/hadamard_vsx.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/ppc/types_vsx.h" -#include "vpx_dsp/ppc/transpose_vsx.h" -#include "vpx_dsp/ppc/bitdepth_conversion_vsx.h" - -static void vpx_hadamard_s16_8x8_one_pass(int16x8_t v[8]) { - const int16x8_t b0 = vec_add(v[0], v[1]); - const int16x8_t b1 = vec_sub(v[0], v[1]); - const int16x8_t b2 = vec_add(v[2], v[3]); - const int16x8_t b3 = vec_sub(v[2], v[3]); - const int16x8_t b4 = vec_add(v[4], v[5]); - const int16x8_t b5 = vec_sub(v[4], v[5]); - const int16x8_t b6 = vec_add(v[6], v[7]); - const int16x8_t b7 = vec_sub(v[6], v[7]); - - const int16x8_t c0 = vec_add(b0, b2); - const int16x8_t c1 = vec_add(b1, b3); - const int16x8_t c2 = vec_sub(b0, b2); - const int16x8_t c3 = vec_sub(b1, b3); - const int16x8_t c4 = vec_add(b4, b6); - const int16x8_t c5 = vec_add(b5, b7); - const int16x8_t c6 = vec_sub(b4, b6); - const int16x8_t c7 = vec_sub(b5, b7); - - v[0] = vec_add(c0, c4); - v[1] = vec_sub(c2, c6); - v[2] = vec_sub(c0, c4); - v[3] = vec_add(c2, c6); - v[4] = vec_add(c3, c7); - v[5] = vec_sub(c3, c7); - v[6] = vec_sub(c1, c5); - v[7] = vec_add(c1, c5); -} - -void vpx_hadamard_8x8_vsx(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { - int16x8_t v[8]; - - v[0] = vec_vsx_ld(0, src_diff); - v[1] = vec_vsx_ld(0, src_diff + src_stride); - v[2] = vec_vsx_ld(0, src_diff + (2 * src_stride)); - v[3] = vec_vsx_ld(0, src_diff + (3 * src_stride)); - v[4] = vec_vsx_ld(0, src_diff + (4 * src_stride)); - v[5] = vec_vsx_ld(0, src_diff + (5 * src_stride)); - v[6] = vec_vsx_ld(0, src_diff + (6 * src_stride)); - v[7] = vec_vsx_ld(0, src_diff + (7 * src_stride)); - - vpx_hadamard_s16_8x8_one_pass(v); - - vpx_transpose_s16_8x8(v); - - vpx_hadamard_s16_8x8_one_pass(v); - - store_tran_low(v[0], 0, coeff); - store_tran_low(v[1], 0, coeff + 8); - store_tran_low(v[2], 0, coeff + 16); - store_tran_low(v[3], 0, coeff + 24); - store_tran_low(v[4], 0, coeff + 32); - store_tran_low(v[5], 0, coeff + 40); - store_tran_low(v[6], 0, coeff + 48); - store_tran_low(v[7], 0, coeff + 56); -} - -void vpx_hadamard_16x16_vsx(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { - int i; - const uint16x8_t ones = vec_splat_u16(1); - - /* Rearrange 16x16 to 8x32 and remove stride. - * Top left first. */ - vpx_hadamard_8x8_vsx(src_diff, src_stride, coeff); - /* Top right. */ - vpx_hadamard_8x8_vsx(src_diff + 8 + 0 * src_stride, src_stride, coeff + 64); - /* Bottom left. */ - vpx_hadamard_8x8_vsx(src_diff + 0 + 8 * src_stride, src_stride, coeff + 128); - /* Bottom right. */ - vpx_hadamard_8x8_vsx(src_diff + 8 + 8 * src_stride, src_stride, coeff + 192); - - /* Overlay the 8x8 blocks and combine. */ - for (i = 0; i < 64; i += 8) { - const int16x8_t a0 = load_tran_low(0, coeff); - const int16x8_t a1 = load_tran_low(0, coeff + 64); - const int16x8_t a2 = load_tran_low(0, coeff + 128); - const int16x8_t a3 = load_tran_low(0, coeff + 192); - - /* Prevent the result from escaping int16_t. */ - const int16x8_t b0 = vec_sra(a0, ones); - const int16x8_t b1 = vec_sra(a1, ones); - const int16x8_t b2 = vec_sra(a2, ones); - const int16x8_t b3 = vec_sra(a3, ones); - - const int16x8_t c0 = vec_add(b0, b1); - const int16x8_t c2 = vec_add(b2, b3); - const int16x8_t c1 = vec_sub(b0, b1); - const int16x8_t c3 = vec_sub(b2, b3); - - const int16x8_t d0 = vec_add(c0, c2); - const int16x8_t d1 = vec_add(c1, c3); - const int16x8_t d2 = vec_sub(c0, c2); - const int16x8_t d3 = vec_sub(c1, c3); - - store_tran_low(d0, 0, coeff); - store_tran_low(d1, 0, coeff + 64); - store_tran_low(d2, 0, coeff + 128); - store_tran_low(d3, 0, coeff + 192); - - coeff += 8; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/intrapred_vsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/intrapred_vsx.c deleted file mode 100644 index a4c8322f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/intrapred_vsx.c +++ /dev/null @@ -1,767 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/ppc/types_vsx.h" - -void vpx_v_predictor_16x16_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t d = vec_vsx_ld(0, above); - int i; - (void)left; - - for (i = 0; i < 16; i++, dst += stride) { - vec_vsx_st(d, 0, dst); - } -} - -void vpx_v_predictor_32x32_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t d0 = vec_vsx_ld(0, above); - const uint8x16_t d1 = vec_vsx_ld(16, above); - int i; - (void)left; - - for (i = 0; i < 32; i++, dst += stride) { - vec_vsx_st(d0, 0, dst); - vec_vsx_st(d1, 16, dst); - } -} - -// TODO(crbug.com/webm/1522): Fix test failures. -#if 0 -static const uint32x4_t mask4 = { 0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; - -void vpx_h_predictor_4x4_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t d = vec_vsx_ld(0, left); - const uint8x16_t v0 = vec_splat(d, 0); - const uint8x16_t v1 = vec_splat(d, 1); - const uint8x16_t v2 = vec_splat(d, 2); - const uint8x16_t v3 = vec_splat(d, 3); - - (void)above; - - vec_vsx_st(vec_sel(v0, vec_vsx_ld(0, dst), (uint8x16_t)mask4), 0, dst); - dst += stride; - vec_vsx_st(vec_sel(v1, vec_vsx_ld(0, dst), (uint8x16_t)mask4), 0, dst); - dst += stride; - vec_vsx_st(vec_sel(v2, vec_vsx_ld(0, dst), (uint8x16_t)mask4), 0, dst); - dst += stride; - vec_vsx_st(vec_sel(v3, vec_vsx_ld(0, dst), (uint8x16_t)mask4), 0, dst); -} - -void vpx_h_predictor_8x8_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t d = vec_vsx_ld(0, left); - const uint8x16_t v0 = vec_splat(d, 0); - const uint8x16_t v1 = vec_splat(d, 1); - const uint8x16_t v2 = vec_splat(d, 2); - const uint8x16_t v3 = vec_splat(d, 3); - - const uint8x16_t v4 = vec_splat(d, 4); - const uint8x16_t v5 = vec_splat(d, 5); - const uint8x16_t v6 = vec_splat(d, 6); - const uint8x16_t v7 = vec_splat(d, 7); - - (void)above; - - vec_vsx_st(xxpermdi(v0, vec_vsx_ld(0, dst), 1), 0, dst); - dst += stride; - vec_vsx_st(xxpermdi(v1, vec_vsx_ld(0, dst), 1), 0, dst); - dst += stride; - vec_vsx_st(xxpermdi(v2, vec_vsx_ld(0, dst), 1), 0, dst); - dst += stride; - vec_vsx_st(xxpermdi(v3, vec_vsx_ld(0, dst), 1), 0, dst); - dst += stride; - vec_vsx_st(xxpermdi(v4, vec_vsx_ld(0, dst), 1), 0, dst); - dst += stride; - vec_vsx_st(xxpermdi(v5, vec_vsx_ld(0, dst), 1), 0, dst); - dst += stride; - vec_vsx_st(xxpermdi(v6, vec_vsx_ld(0, dst), 1), 0, dst); - dst += stride; - vec_vsx_st(xxpermdi(v7, vec_vsx_ld(0, dst), 1), 0, dst); -} -#endif - -void vpx_h_predictor_16x16_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t d = vec_vsx_ld(0, left); - const uint8x16_t v0 = vec_splat(d, 0); - const uint8x16_t v1 = vec_splat(d, 1); - const uint8x16_t v2 = vec_splat(d, 2); - const uint8x16_t v3 = vec_splat(d, 3); - - const uint8x16_t v4 = vec_splat(d, 4); - const uint8x16_t v5 = vec_splat(d, 5); - const uint8x16_t v6 = vec_splat(d, 6); - const uint8x16_t v7 = vec_splat(d, 7); - - const uint8x16_t v8 = vec_splat(d, 8); - const uint8x16_t v9 = vec_splat(d, 9); - const uint8x16_t v10 = vec_splat(d, 10); - const uint8x16_t v11 = vec_splat(d, 11); - - const uint8x16_t v12 = vec_splat(d, 12); - const uint8x16_t v13 = vec_splat(d, 13); - const uint8x16_t v14 = vec_splat(d, 14); - const uint8x16_t v15 = vec_splat(d, 15); - - (void)above; - - vec_vsx_st(v0, 0, dst); - dst += stride; - vec_vsx_st(v1, 0, dst); - dst += stride; - vec_vsx_st(v2, 0, dst); - dst += stride; - vec_vsx_st(v3, 0, dst); - dst += stride; - vec_vsx_st(v4, 0, dst); - dst += stride; - vec_vsx_st(v5, 0, dst); - dst += stride; - vec_vsx_st(v6, 0, dst); - dst += stride; - vec_vsx_st(v7, 0, dst); - dst += stride; - vec_vsx_st(v8, 0, dst); - dst += stride; - vec_vsx_st(v9, 0, dst); - dst += stride; - vec_vsx_st(v10, 0, dst); - dst += stride; - vec_vsx_st(v11, 0, dst); - dst += stride; - vec_vsx_st(v12, 0, dst); - dst += stride; - vec_vsx_st(v13, 0, dst); - dst += stride; - vec_vsx_st(v14, 0, dst); - dst += stride; - vec_vsx_st(v15, 0, dst); -} - -#define H_PREDICTOR_32(v) \ - vec_vsx_st(v, 0, dst); \ - vec_vsx_st(v, 16, dst); \ - dst += stride - -void vpx_h_predictor_32x32_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t d0 = vec_vsx_ld(0, left); - const uint8x16_t d1 = vec_vsx_ld(16, left); - - const uint8x16_t v0_0 = vec_splat(d0, 0); - const uint8x16_t v1_0 = vec_splat(d0, 1); - const uint8x16_t v2_0 = vec_splat(d0, 2); - const uint8x16_t v3_0 = vec_splat(d0, 3); - const uint8x16_t v4_0 = vec_splat(d0, 4); - const uint8x16_t v5_0 = vec_splat(d0, 5); - const uint8x16_t v6_0 = vec_splat(d0, 6); - const uint8x16_t v7_0 = vec_splat(d0, 7); - const uint8x16_t v8_0 = vec_splat(d0, 8); - const uint8x16_t v9_0 = vec_splat(d0, 9); - const uint8x16_t v10_0 = vec_splat(d0, 10); - const uint8x16_t v11_0 = vec_splat(d0, 11); - const uint8x16_t v12_0 = vec_splat(d0, 12); - const uint8x16_t v13_0 = vec_splat(d0, 13); - const uint8x16_t v14_0 = vec_splat(d0, 14); - const uint8x16_t v15_0 = vec_splat(d0, 15); - - const uint8x16_t v0_1 = vec_splat(d1, 0); - const uint8x16_t v1_1 = vec_splat(d1, 1); - const uint8x16_t v2_1 = vec_splat(d1, 2); - const uint8x16_t v3_1 = vec_splat(d1, 3); - const uint8x16_t v4_1 = vec_splat(d1, 4); - const uint8x16_t v5_1 = vec_splat(d1, 5); - const uint8x16_t v6_1 = vec_splat(d1, 6); - const uint8x16_t v7_1 = vec_splat(d1, 7); - const uint8x16_t v8_1 = vec_splat(d1, 8); - const uint8x16_t v9_1 = vec_splat(d1, 9); - const uint8x16_t v10_1 = vec_splat(d1, 10); - const uint8x16_t v11_1 = vec_splat(d1, 11); - const uint8x16_t v12_1 = vec_splat(d1, 12); - const uint8x16_t v13_1 = vec_splat(d1, 13); - const uint8x16_t v14_1 = vec_splat(d1, 14); - const uint8x16_t v15_1 = vec_splat(d1, 15); - - (void)above; - - H_PREDICTOR_32(v0_0); - H_PREDICTOR_32(v1_0); - H_PREDICTOR_32(v2_0); - H_PREDICTOR_32(v3_0); - - H_PREDICTOR_32(v4_0); - H_PREDICTOR_32(v5_0); - H_PREDICTOR_32(v6_0); - H_PREDICTOR_32(v7_0); - - H_PREDICTOR_32(v8_0); - H_PREDICTOR_32(v9_0); - H_PREDICTOR_32(v10_0); - H_PREDICTOR_32(v11_0); - - H_PREDICTOR_32(v12_0); - H_PREDICTOR_32(v13_0); - H_PREDICTOR_32(v14_0); - H_PREDICTOR_32(v15_0); - - H_PREDICTOR_32(v0_1); - H_PREDICTOR_32(v1_1); - H_PREDICTOR_32(v2_1); - H_PREDICTOR_32(v3_1); - - H_PREDICTOR_32(v4_1); - H_PREDICTOR_32(v5_1); - H_PREDICTOR_32(v6_1); - H_PREDICTOR_32(v7_1); - - H_PREDICTOR_32(v8_1); - H_PREDICTOR_32(v9_1); - H_PREDICTOR_32(v10_1); - H_PREDICTOR_32(v11_1); - - H_PREDICTOR_32(v12_1); - H_PREDICTOR_32(v13_1); - H_PREDICTOR_32(v14_1); - H_PREDICTOR_32(v15_1); -} - -// TODO(crbug.com/webm/1522): Fix test failures. -#if 0 -void vpx_tm_predictor_4x4_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const int16x8_t tl = unpack_to_s16_h(vec_splat(vec_vsx_ld(-1, above), 0)); - const int16x8_t l = unpack_to_s16_h(vec_vsx_ld(0, left)); - const int16x8_t a = unpack_to_s16_h(vec_vsx_ld(0, above)); - int16x8_t tmp, val; - uint8x16_t d; - - d = vec_vsx_ld(0, dst); - tmp = unpack_to_s16_l(d); - val = vec_sub(vec_add(vec_splat(l, 0), a), tl); - vec_vsx_st(vec_sel(vec_packsu(val, tmp), d, (uint8x16_t)mask4), 0, dst); - dst += stride; - - d = vec_vsx_ld(0, dst); - tmp = unpack_to_s16_l(d); - val = vec_sub(vec_add(vec_splat(l, 1), a), tl); - vec_vsx_st(vec_sel(vec_packsu(val, tmp), d, (uint8x16_t)mask4), 0, dst); - dst += stride; - - d = vec_vsx_ld(0, dst); - tmp = unpack_to_s16_l(d); - val = vec_sub(vec_add(vec_splat(l, 2), a), tl); - vec_vsx_st(vec_sel(vec_packsu(val, tmp), d, (uint8x16_t)mask4), 0, dst); - dst += stride; - - d = vec_vsx_ld(0, dst); - tmp = unpack_to_s16_l(d); - val = vec_sub(vec_add(vec_splat(l, 3), a), tl); - vec_vsx_st(vec_sel(vec_packsu(val, tmp), d, (uint8x16_t)mask4), 0, dst); -} - -void vpx_tm_predictor_8x8_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const int16x8_t tl = unpack_to_s16_h(vec_splat(vec_vsx_ld(-1, above), 0)); - const int16x8_t l = unpack_to_s16_h(vec_vsx_ld(0, left)); - const int16x8_t a = unpack_to_s16_h(vec_vsx_ld(0, above)); - int16x8_t tmp, val; - - tmp = unpack_to_s16_l(vec_vsx_ld(0, dst)); - val = vec_sub(vec_add(vec_splat(l, 0), a), tl); - vec_vsx_st(vec_packsu(val, tmp), 0, dst); - dst += stride; - - tmp = unpack_to_s16_l(vec_vsx_ld(0, dst)); - val = vec_sub(vec_add(vec_splat(l, 1), a), tl); - vec_vsx_st(vec_packsu(val, tmp), 0, dst); - dst += stride; - - tmp = unpack_to_s16_l(vec_vsx_ld(0, dst)); - val = vec_sub(vec_add(vec_splat(l, 2), a), tl); - vec_vsx_st(vec_packsu(val, tmp), 0, dst); - dst += stride; - - tmp = unpack_to_s16_l(vec_vsx_ld(0, dst)); - val = vec_sub(vec_add(vec_splat(l, 3), a), tl); - vec_vsx_st(vec_packsu(val, tmp), 0, dst); - dst += stride; - - tmp = unpack_to_s16_l(vec_vsx_ld(0, dst)); - val = vec_sub(vec_add(vec_splat(l, 4), a), tl); - vec_vsx_st(vec_packsu(val, tmp), 0, dst); - dst += stride; - - tmp = unpack_to_s16_l(vec_vsx_ld(0, dst)); - val = vec_sub(vec_add(vec_splat(l, 5), a), tl); - vec_vsx_st(vec_packsu(val, tmp), 0, dst); - dst += stride; - - tmp = unpack_to_s16_l(vec_vsx_ld(0, dst)); - val = vec_sub(vec_add(vec_splat(l, 6), a), tl); - vec_vsx_st(vec_packsu(val, tmp), 0, dst); - dst += stride; - - tmp = unpack_to_s16_l(vec_vsx_ld(0, dst)); - val = vec_sub(vec_add(vec_splat(l, 7), a), tl); - vec_vsx_st(vec_packsu(val, tmp), 0, dst); -} -#endif - -static void tm_predictor_16x8(uint8_t *dst, const ptrdiff_t stride, int16x8_t l, - int16x8_t ah, int16x8_t al, int16x8_t tl) { - int16x8_t vh, vl, ls; - - ls = vec_splat(l, 0); - vh = vec_sub(vec_add(ls, ah), tl); - vl = vec_sub(vec_add(ls, al), tl); - vec_vsx_st(vec_packsu(vh, vl), 0, dst); - dst += stride; - - ls = vec_splat(l, 1); - vh = vec_sub(vec_add(ls, ah), tl); - vl = vec_sub(vec_add(ls, al), tl); - vec_vsx_st(vec_packsu(vh, vl), 0, dst); - dst += stride; - - ls = vec_splat(l, 2); - vh = vec_sub(vec_add(ls, ah), tl); - vl = vec_sub(vec_add(ls, al), tl); - vec_vsx_st(vec_packsu(vh, vl), 0, dst); - dst += stride; - - ls = vec_splat(l, 3); - vh = vec_sub(vec_add(ls, ah), tl); - vl = vec_sub(vec_add(ls, al), tl); - vec_vsx_st(vec_packsu(vh, vl), 0, dst); - dst += stride; - - ls = vec_splat(l, 4); - vh = vec_sub(vec_add(ls, ah), tl); - vl = vec_sub(vec_add(ls, al), tl); - vec_vsx_st(vec_packsu(vh, vl), 0, dst); - dst += stride; - - ls = vec_splat(l, 5); - vh = vec_sub(vec_add(ls, ah), tl); - vl = vec_sub(vec_add(ls, al), tl); - vec_vsx_st(vec_packsu(vh, vl), 0, dst); - dst += stride; - - ls = vec_splat(l, 6); - vh = vec_sub(vec_add(ls, ah), tl); - vl = vec_sub(vec_add(ls, al), tl); - vec_vsx_st(vec_packsu(vh, vl), 0, dst); - dst += stride; - - ls = vec_splat(l, 7); - vh = vec_sub(vec_add(ls, ah), tl); - vl = vec_sub(vec_add(ls, al), tl); - vec_vsx_st(vec_packsu(vh, vl), 0, dst); -} - -void vpx_tm_predictor_16x16_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const int16x8_t tl = unpack_to_s16_h(vec_splat(vec_vsx_ld(-1, above), 0)); - const uint8x16_t l = vec_vsx_ld(0, left); - const int16x8_t lh = unpack_to_s16_h(l); - const int16x8_t ll = unpack_to_s16_l(l); - const uint8x16_t a = vec_vsx_ld(0, above); - const int16x8_t ah = unpack_to_s16_h(a); - const int16x8_t al = unpack_to_s16_l(a); - - tm_predictor_16x8(dst, stride, lh, ah, al, tl); - - dst += stride * 8; - - tm_predictor_16x8(dst, stride, ll, ah, al, tl); -} - -static INLINE void tm_predictor_32x1(uint8_t *dst, const int16x8_t ls, - const int16x8_t a0h, const int16x8_t a0l, - const int16x8_t a1h, const int16x8_t a1l, - const int16x8_t tl) { - int16x8_t vh, vl; - - vh = vec_sub(vec_add(ls, a0h), tl); - vl = vec_sub(vec_add(ls, a0l), tl); - vec_vsx_st(vec_packsu(vh, vl), 0, dst); - vh = vec_sub(vec_add(ls, a1h), tl); - vl = vec_sub(vec_add(ls, a1l), tl); - vec_vsx_st(vec_packsu(vh, vl), 16, dst); -} - -static void tm_predictor_32x8(uint8_t *dst, const ptrdiff_t stride, - const int16x8_t l, const uint8x16_t a0, - const uint8x16_t a1, const int16x8_t tl) { - const int16x8_t a0h = unpack_to_s16_h(a0); - const int16x8_t a0l = unpack_to_s16_l(a0); - const int16x8_t a1h = unpack_to_s16_h(a1); - const int16x8_t a1l = unpack_to_s16_l(a1); - - tm_predictor_32x1(dst, vec_splat(l, 0), a0h, a0l, a1h, a1l, tl); - dst += stride; - - tm_predictor_32x1(dst, vec_splat(l, 1), a0h, a0l, a1h, a1l, tl); - dst += stride; - - tm_predictor_32x1(dst, vec_splat(l, 2), a0h, a0l, a1h, a1l, tl); - dst += stride; - - tm_predictor_32x1(dst, vec_splat(l, 3), a0h, a0l, a1h, a1l, tl); - dst += stride; - - tm_predictor_32x1(dst, vec_splat(l, 4), a0h, a0l, a1h, a1l, tl); - dst += stride; - - tm_predictor_32x1(dst, vec_splat(l, 5), a0h, a0l, a1h, a1l, tl); - dst += stride; - - tm_predictor_32x1(dst, vec_splat(l, 6), a0h, a0l, a1h, a1l, tl); - dst += stride; - - tm_predictor_32x1(dst, vec_splat(l, 7), a0h, a0l, a1h, a1l, tl); -} - -void vpx_tm_predictor_32x32_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const int16x8_t tl = unpack_to_s16_h(vec_splat(vec_vsx_ld(-1, above), 0)); - const uint8x16_t l0 = vec_vsx_ld(0, left); - const uint8x16_t l1 = vec_vsx_ld(16, left); - const uint8x16_t a0 = vec_vsx_ld(0, above); - const uint8x16_t a1 = vec_vsx_ld(16, above); - - tm_predictor_32x8(dst, stride, unpack_to_s16_h(l0), a0, a1, tl); - dst += stride * 8; - - tm_predictor_32x8(dst, stride, unpack_to_s16_l(l0), a0, a1, tl); - dst += stride * 8; - - tm_predictor_32x8(dst, stride, unpack_to_s16_h(l1), a0, a1, tl); - dst += stride * 8; - - tm_predictor_32x8(dst, stride, unpack_to_s16_l(l1), a0, a1, tl); -} - -static INLINE void dc_fill_predictor_8x8(uint8_t *dst, const ptrdiff_t stride, - const uint8x16_t val) { - int i; - - for (i = 0; i < 8; i++, dst += stride) { - const uint8x16_t d = vec_vsx_ld(0, dst); - vec_vsx_st(xxpermdi(val, d, 1), 0, dst); - } -} - -static INLINE void dc_fill_predictor_16x16(uint8_t *dst, const ptrdiff_t stride, - const uint8x16_t val) { - int i; - - for (i = 0; i < 16; i++, dst += stride) { - vec_vsx_st(val, 0, dst); - } -} - -void vpx_dc_128_predictor_16x16_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t v128 = vec_sl(vec_splat_u8(1), vec_splat_u8(7)); - (void)above; - (void)left; - - dc_fill_predictor_16x16(dst, stride, v128); -} - -static INLINE void dc_fill_predictor_32x32(uint8_t *dst, const ptrdiff_t stride, - const uint8x16_t val) { - int i; - - for (i = 0; i < 32; i++, dst += stride) { - vec_vsx_st(val, 0, dst); - vec_vsx_st(val, 16, dst); - } -} - -void vpx_dc_128_predictor_32x32_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t v128 = vec_sl(vec_splat_u8(1), vec_splat_u8(7)); - (void)above; - (void)left; - - dc_fill_predictor_32x32(dst, stride, v128); -} - -static uint8x16_t avg16(const uint8_t *values) { - const int32x4_t sum4s = - (int32x4_t)vec_sum4s(vec_vsx_ld(0, values), vec_splat_u32(0)); - const uint32x4_t sum = (uint32x4_t)vec_sums(sum4s, vec_splat_s32(8)); - const uint32x4_t avg = (uint32x4_t)vec_sr(sum, vec_splat_u32(4)); - - return vec_splat(vec_pack(vec_pack(avg, vec_splat_u32(0)), vec_splat_u16(0)), - 3); -} - -void vpx_dc_left_predictor_16x16_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, - const uint8_t *left) { - (void)above; - - dc_fill_predictor_16x16(dst, stride, avg16(left)); -} - -void vpx_dc_top_predictor_16x16_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - (void)left; - - dc_fill_predictor_16x16(dst, stride, avg16(above)); -} - -static uint8x16_t avg32(const uint8_t *values) { - const uint8x16_t v0 = vec_vsx_ld(0, values); - const uint8x16_t v1 = vec_vsx_ld(16, values); - const int32x4_t v16 = vec_sl(vec_splat_s32(1), vec_splat_u32(4)); - const int32x4_t sum4s = - (int32x4_t)vec_sum4s(v0, vec_sum4s(v1, vec_splat_u32(0))); - const uint32x4_t sum = (uint32x4_t)vec_sums(sum4s, v16); - const uint32x4_t avg = (uint32x4_t)vec_sr(sum, vec_splat_u32(5)); - - return vec_splat(vec_pack(vec_pack(avg, vec_splat_u32(0)), vec_splat_u16(0)), - 3); -} - -void vpx_dc_left_predictor_32x32_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, - const uint8_t *left) { - (void)above; - - dc_fill_predictor_32x32(dst, stride, avg32(left)); -} - -void vpx_dc_top_predictor_32x32_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - (void)left; - - dc_fill_predictor_32x32(dst, stride, avg32(above)); -} - -// TODO(crbug.com/webm/1522): Fix test failures. -#if 0 -static uint8x16_t dc_avg8(const uint8_t *above, const uint8_t *left) { - const uint8x16_t a0 = vec_vsx_ld(0, above); - const uint8x16_t l0 = vec_vsx_ld(0, left); - const int32x4_t sum4s = - (int32x4_t)vec_sum4s(l0, vec_sum4s(a0, vec_splat_u32(0))); - const int32x4_t sum4s8 = xxpermdi(sum4s, vec_splat_s32(0), 1); - const uint32x4_t sum = (uint32x4_t)vec_sums(sum4s8, vec_splat_s32(8)); - const uint32x4_t avg = (uint32x4_t)vec_sr(sum, vec_splat_u32(4)); - - return vec_splat(vec_pack(vec_pack(avg, vec_splat_u32(0)), vec_splat_u16(0)), - 3); -} -#endif - -static uint8x16_t dc_avg16(const uint8_t *above, const uint8_t *left) { - const uint8x16_t a0 = vec_vsx_ld(0, above); - const uint8x16_t l0 = vec_vsx_ld(0, left); - const int32x4_t v16 = vec_sl(vec_splat_s32(1), vec_splat_u32(4)); - const int32x4_t sum4s = - (int32x4_t)vec_sum4s(l0, vec_sum4s(a0, vec_splat_u32(0))); - const uint32x4_t sum = (uint32x4_t)vec_sums(sum4s, v16); - const uint32x4_t avg = (uint32x4_t)vec_sr(sum, vec_splat_u32(5)); - - return vec_splat(vec_pack(vec_pack(avg, vec_splat_u32(0)), vec_splat_u16(0)), - 3); -} - -// TODO(crbug.com/webm/1522): Fix test failures. -#if 0 -void vpx_dc_predictor_8x8_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - dc_fill_predictor_8x8(dst, stride, dc_avg8(above, left)); -} -#endif - -void vpx_dc_predictor_16x16_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - dc_fill_predictor_16x16(dst, stride, dc_avg16(above, left)); -} - -static uint8x16_t dc_avg32(const uint8_t *above, const uint8_t *left) { - const uint8x16_t a0 = vec_vsx_ld(0, above); - const uint8x16_t a1 = vec_vsx_ld(16, above); - const uint8x16_t l0 = vec_vsx_ld(0, left); - const uint8x16_t l1 = vec_vsx_ld(16, left); - const int32x4_t v32 = vec_sl(vec_splat_s32(1), vec_splat_u32(5)); - const uint32x4_t a_sum = vec_sum4s(a0, vec_sum4s(a1, vec_splat_u32(0))); - const int32x4_t sum4s = (int32x4_t)vec_sum4s(l0, vec_sum4s(l1, a_sum)); - const uint32x4_t sum = (uint32x4_t)vec_sums(sum4s, v32); - const uint32x4_t avg = (uint32x4_t)vec_sr(sum, vec_splat_u32(6)); - - return vec_splat(vec_pack(vec_pack(avg, vec_splat_u32(0)), vec_splat_u16(0)), - 3); -} - -void vpx_dc_predictor_32x32_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - dc_fill_predictor_32x32(dst, stride, dc_avg32(above, left)); -} - -static uint8x16_t avg3(const uint8x16_t a, const uint8x16_t b, - const uint8x16_t c) { - const uint8x16_t ac = - vec_adds(vec_and(a, c), vec_sr(vec_xor(a, c), vec_splat_u8(1))); - - return vec_avg(ac, b); -} - -// Workaround vec_sld/vec_xxsldi/vec_lsdoi being missing or broken. -static const uint8x16_t sl1 = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, - 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10 }; - -// TODO(crbug.com/webm/1522): Fix test failures. -#if 0 -void vpx_d45_predictor_8x8_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t af = vec_vsx_ld(0, above); - const uint8x16_t above_right = vec_splat(af, 7); - const uint8x16_t a = xxpermdi(af, above_right, 1); - const uint8x16_t b = vec_perm(a, above_right, sl1); - const uint8x16_t c = vec_perm(b, above_right, sl1); - uint8x16_t row = avg3(a, b, c); - int i; - (void)left; - - for (i = 0; i < 8; i++) { - const uint8x16_t d = vec_vsx_ld(0, dst); - vec_vsx_st(xxpermdi(row, d, 1), 0, dst); - dst += stride; - row = vec_perm(row, above_right, sl1); - } -} -#endif - -void vpx_d45_predictor_16x16_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t a = vec_vsx_ld(0, above); - const uint8x16_t above_right = vec_splat(a, 15); - const uint8x16_t b = vec_perm(a, above_right, sl1); - const uint8x16_t c = vec_perm(b, above_right, sl1); - uint8x16_t row = avg3(a, b, c); - int i; - (void)left; - - for (i = 0; i < 16; i++) { - vec_vsx_st(row, 0, dst); - dst += stride; - row = vec_perm(row, above_right, sl1); - } -} - -void vpx_d45_predictor_32x32_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t a0 = vec_vsx_ld(0, above); - const uint8x16_t a1 = vec_vsx_ld(16, above); - const uint8x16_t above_right = vec_splat(a1, 15); - const uint8x16_t b0 = vec_perm(a0, a1, sl1); - const uint8x16_t b1 = vec_perm(a1, above_right, sl1); - const uint8x16_t c0 = vec_perm(b0, b1, sl1); - const uint8x16_t c1 = vec_perm(b1, above_right, sl1); - uint8x16_t row0 = avg3(a0, b0, c0); - uint8x16_t row1 = avg3(a1, b1, c1); - int i; - (void)left; - - for (i = 0; i < 32; i++) { - vec_vsx_st(row0, 0, dst); - vec_vsx_st(row1, 16, dst); - dst += stride; - row0 = vec_perm(row0, row1, sl1); - row1 = vec_perm(row1, above_right, sl1); - } -} - -// TODO(crbug.com/webm/1522): Fix test failures. -#if 0 -void vpx_d63_predictor_8x8_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t af = vec_vsx_ld(0, above); - const uint8x16_t above_right = vec_splat(af, 9); - const uint8x16_t a = xxpermdi(af, above_right, 1); - const uint8x16_t b = vec_perm(a, above_right, sl1); - const uint8x16_t c = vec_perm(b, above_right, sl1); - uint8x16_t row0 = vec_avg(a, b); - uint8x16_t row1 = avg3(a, b, c); - int i; - (void)left; - - for (i = 0; i < 4; i++) { - const uint8x16_t d0 = vec_vsx_ld(0, dst); - const uint8x16_t d1 = vec_vsx_ld(0, dst + stride); - vec_vsx_st(xxpermdi(row0, d0, 1), 0, dst); - vec_vsx_st(xxpermdi(row1, d1, 1), 0, dst + stride); - dst += stride * 2; - row0 = vec_perm(row0, above_right, sl1); - row1 = vec_perm(row1, above_right, sl1); - } -} -#endif - -void vpx_d63_predictor_16x16_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t a0 = vec_vsx_ld(0, above); - const uint8x16_t a1 = vec_vsx_ld(16, above); - const uint8x16_t above_right = vec_splat(a1, 0); - const uint8x16_t b = vec_perm(a0, above_right, sl1); - const uint8x16_t c = vec_perm(b, above_right, sl1); - uint8x16_t row0 = vec_avg(a0, b); - uint8x16_t row1 = avg3(a0, b, c); - int i; - (void)left; - - for (i = 0; i < 8; i++) { - vec_vsx_st(row0, 0, dst); - vec_vsx_st(row1, 0, dst + stride); - dst += stride * 2; - row0 = vec_perm(row0, above_right, sl1); - row1 = vec_perm(row1, above_right, sl1); - } -} - -void vpx_d63_predictor_32x32_vsx(uint8_t *dst, ptrdiff_t stride, - const uint8_t *above, const uint8_t *left) { - const uint8x16_t a0 = vec_vsx_ld(0, above); - const uint8x16_t a1 = vec_vsx_ld(16, above); - const uint8x16_t a2 = vec_vsx_ld(32, above); - const uint8x16_t above_right = vec_splat(a2, 0); - const uint8x16_t b0 = vec_perm(a0, a1, sl1); - const uint8x16_t b1 = vec_perm(a1, above_right, sl1); - const uint8x16_t c0 = vec_perm(b0, b1, sl1); - const uint8x16_t c1 = vec_perm(b1, above_right, sl1); - uint8x16_t row0_0 = vec_avg(a0, b0); - uint8x16_t row0_1 = vec_avg(a1, b1); - uint8x16_t row1_0 = avg3(a0, b0, c0); - uint8x16_t row1_1 = avg3(a1, b1, c1); - int i; - (void)left; - - for (i = 0; i < 16; i++) { - vec_vsx_st(row0_0, 0, dst); - vec_vsx_st(row0_1, 16, dst); - vec_vsx_st(row1_0, 0, dst + stride); - vec_vsx_st(row1_1, 16, dst + stride); - dst += stride * 2; - row0_0 = vec_perm(row0_0, row0_1, sl1); - row0_1 = vec_perm(row0_1, above_right, sl1); - row1_0 = vec_perm(row1_0, row1_1, sl1); - row1_1 = vec_perm(row1_1, above_right, sl1); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/inv_txfm_vsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/inv_txfm_vsx.c deleted file mode 100644 index e99412ec..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/inv_txfm_vsx.c +++ /dev/null @@ -1,1828 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "vpx_dsp/ppc/bitdepth_conversion_vsx.h" -#include "vpx_dsp/ppc/types_vsx.h" -#include "vpx_dsp/ppc/inv_txfm_vsx.h" - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/inv_txfm.h" - -static const int16x8_t cospi1_v = { 16364, 16364, 16364, 16364, - 16364, 16364, 16364, 16364 }; -static const int16x8_t cospi1m_v = { -16364, -16364, -16364, -16364, - -16364, -16364, -16364, -16364 }; -static const int16x8_t cospi2_v = { 16305, 16305, 16305, 16305, - 16305, 16305, 16305, 16305 }; -static const int16x8_t cospi2m_v = { -16305, -16305, -16305, -16305, - -16305, -16305, -16305, -16305 }; -static const int16x8_t cospi3_v = { 16207, 16207, 16207, 16207, - 16207, 16207, 16207, 16207 }; -static const int16x8_t cospi4_v = { 16069, 16069, 16069, 16069, - 16069, 16069, 16069, 16069 }; -static const int16x8_t cospi4m_v = { -16069, -16069, -16069, -16069, - -16069, -16069, -16069, -16069 }; -static const int16x8_t cospi5_v = { 15893, 15893, 15893, 15893, - 15893, 15893, 15893, 15893 }; -static const int16x8_t cospi5m_v = { -15893, -15893, -15893, -15893, - -15893, -15893, -15893, -15893 }; -static const int16x8_t cospi6_v = { 15679, 15679, 15679, 15679, - 15679, 15679, 15679, 15679 }; -static const int16x8_t cospi7_v = { 15426, 15426, 15426, 15426, - 15426, 15426, 15426, 15426 }; -static const int16x8_t cospi8_v = { 15137, 15137, 15137, 15137, - 15137, 15137, 15137, 15137 }; -static const int16x8_t cospi8m_v = { -15137, -15137, -15137, -15137, - -15137, -15137, -15137, -15137 }; -static const int16x8_t cospi9_v = { 14811, 14811, 14811, 14811, - 14811, 14811, 14811, 14811 }; -static const int16x8_t cospi9m_v = { -14811, -14811, -14811, -14811, - -14811, -14811, -14811, -14811 }; -static const int16x8_t cospi10_v = { 14449, 14449, 14449, 14449, - 14449, 14449, 14449, 14449 }; -static const int16x8_t cospi10m_v = { -14449, -14449, -14449, -14449, - -14449, -14449, -14449, -14449 }; -static const int16x8_t cospi11_v = { 14053, 14053, 14053, 14053, - 14053, 14053, 14053, 14053 }; -static const int16x8_t cospi12_v = { 13623, 13623, 13623, 13623, - 13623, 13623, 13623, 13623 }; -static const int16x8_t cospi12m_v = { -13623, -13623, -13623, -13623, - -13623, -13623, -13623, -13623 }; -static const int16x8_t cospi13_v = { 13160, 13160, 13160, 13160, - 13160, 13160, 13160, 13160 }; -static const int16x8_t cospi13m_v = { -13160, -13160, -13160, -13160, - -13160, -13160, -13160, -13160 }; -static const int16x8_t cospi14_v = { 12665, 12665, 12665, 12665, - 12665, 12665, 12665, 12665 }; -static const int16x8_t cospi15_v = { 12140, 12140, 12140, 12140, - 12140, 12140, 12140, 12140 }; -static const int16x8_t cospi16_v = { 11585, 11585, 11585, 11585, - 11585, 11585, 11585, 11585 }; -static const int16x8_t cospi16m_v = { -11585, -11585, -11585, -11585, - -11585, -11585, -11585, -11585 }; -static const int16x8_t cospi17_v = { 11003, 11003, 11003, 11003, - 11003, 11003, 11003, 11003 }; -static const int16x8_t cospi17m_v = { -11003, -11003, -11003, -11003, - -11003, -11003, -11003, -11003 }; -static const int16x8_t cospi18_v = { 10394, 10394, 10394, 10394, - 10394, 10394, 10394, 10394 }; -static const int16x8_t cospi18m_v = { -10394, -10394, -10394, -10394, - -10394, -10394, -10394, -10394 }; -static const int16x8_t cospi19_v = { 9760, 9760, 9760, 9760, - 9760, 9760, 9760, 9760 }; -static const int16x8_t cospi20_v = { 9102, 9102, 9102, 9102, - 9102, 9102, 9102, 9102 }; -static const int16x8_t cospi20m_v = { -9102, -9102, -9102, -9102, - -9102, -9102, -9102, -9102 }; -static const int16x8_t cospi21_v = { 8423, 8423, 8423, 8423, - 8423, 8423, 8423, 8423 }; -static const int16x8_t cospi21m_v = { -8423, -8423, -8423, -8423, - -8423, -8423, -8423, -8423 }; -static const int16x8_t cospi22_v = { 7723, 7723, 7723, 7723, - 7723, 7723, 7723, 7723 }; -static const int16x8_t cospi23_v = { 7005, 7005, 7005, 7005, - 7005, 7005, 7005, 7005 }; -static const int16x8_t cospi24_v = { 6270, 6270, 6270, 6270, - 6270, 6270, 6270, 6270 }; -static const int16x8_t cospi24m_v = { -6270, -6270, -6270, -6270, - -6270, -6270, -6270, -6270 }; -static const int16x8_t cospi25_v = { 5520, 5520, 5520, 5520, - 5520, 5520, 5520, 5520 }; -static const int16x8_t cospi25m_v = { -5520, -5520, -5520, -5520, - -5520, -5520, -5520, -5520 }; -static const int16x8_t cospi26_v = { 4756, 4756, 4756, 4756, - 4756, 4756, 4756, 4756 }; -static const int16x8_t cospi26m_v = { -4756, -4756, -4756, -4756, - -4756, -4756, -4756, -4756 }; -static const int16x8_t cospi27_v = { 3981, 3981, 3981, 3981, - 3981, 3981, 3981, 3981 }; -static const int16x8_t cospi28_v = { 3196, 3196, 3196, 3196, - 3196, 3196, 3196, 3196 }; -static const int16x8_t cospi28m_v = { -3196, -3196, -3196, -3196, - -3196, -3196, -3196, -3196 }; -static const int16x8_t cospi29_v = { 2404, 2404, 2404, 2404, - 2404, 2404, 2404, 2404 }; -static const int16x8_t cospi29m_v = { -2404, -2404, -2404, -2404, - -2404, -2404, -2404, -2404 }; -static const int16x8_t cospi30_v = { 1606, 1606, 1606, 1606, - 1606, 1606, 1606, 1606 }; -static const int16x8_t cospi31_v = { 804, 804, 804, 804, 804, 804, 804, 804 }; - -static const int16x8_t sinpi_1_9_v = { 5283, 5283, 5283, 5283, - 5283, 5283, 5283, 5283 }; -static const int16x8_t sinpi_2_9_v = { 9929, 9929, 9929, 9929, - 9929, 9929, 9929, 9929 }; -static const int16x8_t sinpi_3_9_v = { 13377, 13377, 13377, 13377, - 13377, 13377, 13377, 13377 }; -static const int16x8_t sinpi_4_9_v = { 15212, 15212, 15212, 15212, - 15212, 15212, 15212, 15212 }; - -static uint8x16_t tr8_mask0 = { - 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 -}; - -static uint8x16_t tr8_mask1 = { - 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F -}; - -#define ROUND_SHIFT_INIT \ - const int32x4_t shift = vec_sl(vec_splat_s32(1), vec_splat_u32(13)); \ - const uint32x4_t shift14 = vec_splat_u32(14); - -#define DCT_CONST_ROUND_SHIFT(vec) vec = vec_sra(vec_add(vec, shift), shift14); - -#define PIXEL_ADD_INIT \ - int16x8_t add8 = vec_splat_s16(8); \ - uint16x8_t shift4 = vec_splat_u16(4); - -#define PIXEL_ADD4(out, in) out = vec_sra(vec_add(in, add8), shift4); - -#define IDCT4(in0, in1, out0, out1) \ - t0 = vec_add(in0, in1); \ - t1 = vec_sub(in0, in1); \ - tmp16_0 = vec_mergeh(t0, t1); \ - temp1 = vec_sra(vec_add(vec_mule(tmp16_0, cospi16_v), shift), shift14); \ - temp2 = vec_sra(vec_add(vec_mulo(tmp16_0, cospi16_v), shift), shift14); \ - \ - tmp16_0 = vec_mergel(in0, in1); \ - temp3 = vec_sub(vec_mule(tmp16_0, cospi24_v), vec_mulo(tmp16_0, cospi8_v)); \ - DCT_CONST_ROUND_SHIFT(temp3); \ - temp4 = vec_add(vec_mule(tmp16_0, cospi8_v), vec_mulo(tmp16_0, cospi24_v)); \ - DCT_CONST_ROUND_SHIFT(temp4); \ - \ - step0 = vec_packs(temp1, temp2); \ - step1 = vec_packs(temp4, temp3); \ - out0 = vec_add(step0, step1); \ - out1 = vec_sub(step0, step1); \ - out1 = vec_perm(out1, out1, mask0); - -#define PACK_STORE(v0, v1) \ - tmp16_0 = vec_add(vec_perm(d_u0, d_u1, tr8_mask0), v0); \ - tmp16_1 = vec_add(vec_perm(d_u2, d_u3, tr8_mask0), v1); \ - output_v = vec_packsu(tmp16_0, tmp16_1); \ - \ - vec_vsx_st(output_v, 0, tmp_dest); \ - for (i = 0; i < 4; i++) \ - for (j = 0; j < 4; j++) dest[j * stride + i] = tmp_dest[j * 4 + i]; - -void vpx_round_store4x4_vsx(int16x8_t *in, int16x8_t *out, uint8_t *dest, - int stride) { - int i, j; - uint8x16_t dest0 = vec_vsx_ld(0, dest); - uint8x16_t dest1 = vec_vsx_ld(stride, dest); - uint8x16_t dest2 = vec_vsx_ld(2 * stride, dest); - uint8x16_t dest3 = vec_vsx_ld(3 * stride, dest); - uint8x16_t zerov = vec_splat_u8(0); - int16x8_t d_u0 = (int16x8_t)vec_mergeh(dest0, zerov); - int16x8_t d_u1 = (int16x8_t)vec_mergeh(dest1, zerov); - int16x8_t d_u2 = (int16x8_t)vec_mergeh(dest2, zerov); - int16x8_t d_u3 = (int16x8_t)vec_mergeh(dest3, zerov); - int16x8_t tmp16_0, tmp16_1; - uint8x16_t output_v; - uint8_t tmp_dest[16]; - PIXEL_ADD_INIT; - - PIXEL_ADD4(out[0], in[0]); - PIXEL_ADD4(out[1], in[1]); - - PACK_STORE(out[0], out[1]); -} - -void vpx_idct4_vsx(int16x8_t *in, int16x8_t *out) { - int32x4_t temp1, temp2, temp3, temp4; - int16x8_t step0, step1, tmp16_0; - uint8x16_t mask0 = { 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, - 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; - int16x8_t t0 = vec_mergeh(in[0], in[1]); - int16x8_t t1 = vec_mergel(in[0], in[1]); - ROUND_SHIFT_INIT - - in[0] = vec_mergeh(t0, t1); - in[1] = vec_mergel(t0, t1); - - IDCT4(in[0], in[1], out[0], out[1]); -} - -void vpx_idct4x4_16_add_vsx(const tran_low_t *input, uint8_t *dest, - int stride) { - int16x8_t in[2], out[2]; - - in[0] = load_tran_low(0, input); - in[1] = load_tran_low(8 * sizeof(*input), input); - // Rows - vpx_idct4_vsx(in, out); - - // Columns - vpx_idct4_vsx(out, in); - - vpx_round_store4x4_vsx(in, out, dest, stride); -} - -#define TRANSPOSE8x8(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, \ - out3, out4, out5, out6, out7) \ - out0 = vec_mergeh(in0, in1); \ - out1 = vec_mergel(in0, in1); \ - out2 = vec_mergeh(in2, in3); \ - out3 = vec_mergel(in2, in3); \ - out4 = vec_mergeh(in4, in5); \ - out5 = vec_mergel(in4, in5); \ - out6 = vec_mergeh(in6, in7); \ - out7 = vec_mergel(in6, in7); \ - in0 = (int16x8_t)vec_mergeh((int32x4_t)out0, (int32x4_t)out2); \ - in1 = (int16x8_t)vec_mergel((int32x4_t)out0, (int32x4_t)out2); \ - in2 = (int16x8_t)vec_mergeh((int32x4_t)out1, (int32x4_t)out3); \ - in3 = (int16x8_t)vec_mergel((int32x4_t)out1, (int32x4_t)out3); \ - in4 = (int16x8_t)vec_mergeh((int32x4_t)out4, (int32x4_t)out6); \ - in5 = (int16x8_t)vec_mergel((int32x4_t)out4, (int32x4_t)out6); \ - in6 = (int16x8_t)vec_mergeh((int32x4_t)out5, (int32x4_t)out7); \ - in7 = (int16x8_t)vec_mergel((int32x4_t)out5, (int32x4_t)out7); \ - out0 = vec_perm(in0, in4, tr8_mask0); \ - out1 = vec_perm(in0, in4, tr8_mask1); \ - out2 = vec_perm(in1, in5, tr8_mask0); \ - out3 = vec_perm(in1, in5, tr8_mask1); \ - out4 = vec_perm(in2, in6, tr8_mask0); \ - out5 = vec_perm(in2, in6, tr8_mask1); \ - out6 = vec_perm(in3, in7, tr8_mask0); \ - out7 = vec_perm(in3, in7, tr8_mask1); - -/* for the: temp1 = step[x] * cospi_q - step[y] * cospi_z - * temp2 = step[x] * cospi_z + step[y] * cospi_q */ -#define STEP8_0(inpt0, inpt1, outpt0, outpt1, cospi0, cospi1) \ - tmp16_0 = vec_mergeh(inpt0, inpt1); \ - tmp16_1 = vec_mergel(inpt0, inpt1); \ - temp10 = vec_sub(vec_mule(tmp16_0, cospi0), vec_mulo(tmp16_0, cospi1)); \ - temp11 = vec_sub(vec_mule(tmp16_1, cospi0), vec_mulo(tmp16_1, cospi1)); \ - DCT_CONST_ROUND_SHIFT(temp10); \ - DCT_CONST_ROUND_SHIFT(temp11); \ - outpt0 = vec_packs(temp10, temp11); \ - temp10 = vec_add(vec_mule(tmp16_0, cospi1), vec_mulo(tmp16_0, cospi0)); \ - temp11 = vec_add(vec_mule(tmp16_1, cospi1), vec_mulo(tmp16_1, cospi0)); \ - DCT_CONST_ROUND_SHIFT(temp10); \ - DCT_CONST_ROUND_SHIFT(temp11); \ - outpt1 = vec_packs(temp10, temp11); - -#define STEP8_1(inpt0, inpt1, outpt0, outpt1, cospi) \ - tmp16_2 = vec_sub(inpt0, inpt1); \ - tmp16_3 = vec_add(inpt0, inpt1); \ - tmp16_0 = vec_mergeh(tmp16_2, tmp16_3); \ - tmp16_1 = vec_mergel(tmp16_2, tmp16_3); \ - temp10 = vec_mule(tmp16_0, cospi); \ - temp11 = vec_mule(tmp16_1, cospi); \ - DCT_CONST_ROUND_SHIFT(temp10); \ - DCT_CONST_ROUND_SHIFT(temp11); \ - outpt0 = vec_packs(temp10, temp11); \ - temp10 = vec_mulo(tmp16_0, cospi); \ - temp11 = vec_mulo(tmp16_1, cospi); \ - DCT_CONST_ROUND_SHIFT(temp10); \ - DCT_CONST_ROUND_SHIFT(temp11); \ - outpt1 = vec_packs(temp10, temp11); - -#define IDCT8(in0, in1, in2, in3, in4, in5, in6, in7) \ - /* stage 1 */ \ - step0 = in0; \ - step2 = in4; \ - step1 = in2; \ - step3 = in6; \ - \ - STEP8_0(in1, in7, step4, step7, cospi28_v, cospi4_v); \ - STEP8_0(in5, in3, step5, step6, cospi12_v, cospi20_v); \ - \ - /* stage 2 */ \ - STEP8_1(step0, step2, in1, in0, cospi16_v); \ - STEP8_0(step1, step3, in2, in3, cospi24_v, cospi8_v); \ - in4 = vec_add(step4, step5); \ - in5 = vec_sub(step4, step5); \ - in6 = vec_sub(step7, step6); \ - in7 = vec_add(step6, step7); \ - \ - /* stage 3 */ \ - step0 = vec_add(in0, in3); \ - step1 = vec_add(in1, in2); \ - step2 = vec_sub(in1, in2); \ - step3 = vec_sub(in0, in3); \ - step4 = in4; \ - STEP8_1(in6, in5, step5, step6, cospi16_v); \ - step7 = in7; \ - \ - /* stage 4 */ \ - in0 = vec_add(step0, step7); \ - in1 = vec_add(step1, step6); \ - in2 = vec_add(step2, step5); \ - in3 = vec_add(step3, step4); \ - in4 = vec_sub(step3, step4); \ - in5 = vec_sub(step2, step5); \ - in6 = vec_sub(step1, step6); \ - in7 = vec_sub(step0, step7); - -#define PIXEL_ADD(in, out, add, shiftx) \ - out = vec_add(vec_sra(vec_add(in, add), shiftx), out); - -void vpx_idct8_vsx(int16x8_t *in, int16x8_t *out) { - int16x8_t step0, step1, step2, step3, step4, step5, step6, step7; - int16x8_t tmp16_0, tmp16_1, tmp16_2, tmp16_3; - int32x4_t temp10, temp11; - ROUND_SHIFT_INIT; - - TRANSPOSE8x8(in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7], out[0], - out[1], out[2], out[3], out[4], out[5], out[6], out[7]); - - IDCT8(out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7]); -} - -void vpx_round_store8x8_vsx(int16x8_t *in, uint8_t *dest, int stride) { - uint8x16_t zerov = vec_splat_u8(0); - uint8x16_t dest0 = vec_vsx_ld(0, dest); - uint8x16_t dest1 = vec_vsx_ld(stride, dest); - uint8x16_t dest2 = vec_vsx_ld(2 * stride, dest); - uint8x16_t dest3 = vec_vsx_ld(3 * stride, dest); - uint8x16_t dest4 = vec_vsx_ld(4 * stride, dest); - uint8x16_t dest5 = vec_vsx_ld(5 * stride, dest); - uint8x16_t dest6 = vec_vsx_ld(6 * stride, dest); - uint8x16_t dest7 = vec_vsx_ld(7 * stride, dest); - int16x8_t d_u0 = (int16x8_t)vec_mergeh(dest0, zerov); - int16x8_t d_u1 = (int16x8_t)vec_mergeh(dest1, zerov); - int16x8_t d_u2 = (int16x8_t)vec_mergeh(dest2, zerov); - int16x8_t d_u3 = (int16x8_t)vec_mergeh(dest3, zerov); - int16x8_t d_u4 = (int16x8_t)vec_mergeh(dest4, zerov); - int16x8_t d_u5 = (int16x8_t)vec_mergeh(dest5, zerov); - int16x8_t d_u6 = (int16x8_t)vec_mergeh(dest6, zerov); - int16x8_t d_u7 = (int16x8_t)vec_mergeh(dest7, zerov); - int16x8_t add = vec_sl(vec_splat_s16(8), vec_splat_u16(1)); - uint16x8_t shift5 = vec_splat_u16(5); - uint8x16_t output0, output1, output2, output3; - - PIXEL_ADD(in[0], d_u0, add, shift5); - PIXEL_ADD(in[1], d_u1, add, shift5); - PIXEL_ADD(in[2], d_u2, add, shift5); - PIXEL_ADD(in[3], d_u3, add, shift5); - PIXEL_ADD(in[4], d_u4, add, shift5); - PIXEL_ADD(in[5], d_u5, add, shift5); - PIXEL_ADD(in[6], d_u6, add, shift5); - PIXEL_ADD(in[7], d_u7, add, shift5); - output0 = vec_packsu(d_u0, d_u1); - output1 = vec_packsu(d_u2, d_u3); - output2 = vec_packsu(d_u4, d_u5); - output3 = vec_packsu(d_u6, d_u7); - - vec_vsx_st(xxpermdi(output0, dest0, 1), 0, dest); - vec_vsx_st(xxpermdi(output0, dest1, 3), stride, dest); - vec_vsx_st(xxpermdi(output1, dest2, 1), 2 * stride, dest); - vec_vsx_st(xxpermdi(output1, dest3, 3), 3 * stride, dest); - vec_vsx_st(xxpermdi(output2, dest4, 1), 4 * stride, dest); - vec_vsx_st(xxpermdi(output2, dest5, 3), 5 * stride, dest); - vec_vsx_st(xxpermdi(output3, dest6, 1), 6 * stride, dest); - vec_vsx_st(xxpermdi(output3, dest7, 3), 7 * stride, dest); -} - -void vpx_idct8x8_64_add_vsx(const tran_low_t *input, uint8_t *dest, - int stride) { - int16x8_t src[8], tmp[8]; - - src[0] = load_tran_low(0, input); - src[1] = load_tran_low(8 * sizeof(*input), input); - src[2] = load_tran_low(16 * sizeof(*input), input); - src[3] = load_tran_low(24 * sizeof(*input), input); - src[4] = load_tran_low(32 * sizeof(*input), input); - src[5] = load_tran_low(40 * sizeof(*input), input); - src[6] = load_tran_low(48 * sizeof(*input), input); - src[7] = load_tran_low(56 * sizeof(*input), input); - - vpx_idct8_vsx(src, tmp); - vpx_idct8_vsx(tmp, src); - - vpx_round_store8x8_vsx(src, dest, stride); -} - -#define STEP16_1(inpt0, inpt1, outpt0, outpt1, cospi) \ - tmp16_0 = vec_mergeh(inpt0, inpt1); \ - tmp16_1 = vec_mergel(inpt0, inpt1); \ - temp10 = vec_mule(tmp16_0, cospi); \ - temp11 = vec_mule(tmp16_1, cospi); \ - temp20 = vec_mulo(tmp16_0, cospi); \ - temp21 = vec_mulo(tmp16_1, cospi); \ - temp30 = vec_sub(temp10, temp20); \ - temp10 = vec_add(temp10, temp20); \ - temp20 = vec_sub(temp11, temp21); \ - temp21 = vec_add(temp11, temp21); \ - DCT_CONST_ROUND_SHIFT(temp30); \ - DCT_CONST_ROUND_SHIFT(temp20); \ - outpt0 = vec_packs(temp30, temp20); \ - DCT_CONST_ROUND_SHIFT(temp10); \ - DCT_CONST_ROUND_SHIFT(temp21); \ - outpt1 = vec_packs(temp10, temp21); - -#define IDCT16(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, inA, inB, \ - inC, inD, inE, inF, out0, out1, out2, out3, out4, out5, out6, \ - out7, out8, out9, outA, outB, outC, outD, outE, outF) \ - /* stage 1 */ \ - /* out0 = in0; */ \ - out1 = in8; \ - out2 = in4; \ - out3 = inC; \ - out4 = in2; \ - out5 = inA; \ - out6 = in6; \ - out7 = inE; \ - out8 = in1; \ - out9 = in9; \ - outA = in5; \ - outB = inD; \ - outC = in3; \ - outD = inB; \ - outE = in7; \ - outF = inF; \ - \ - /* stage 2 */ \ - /* in0 = out0; */ \ - in1 = out1; \ - in2 = out2; \ - in3 = out3; \ - in4 = out4; \ - in5 = out5; \ - in6 = out6; \ - in7 = out7; \ - \ - STEP8_0(out8, outF, in8, inF, cospi30_v, cospi2_v); \ - STEP8_0(out9, outE, in9, inE, cospi14_v, cospi18_v); \ - STEP8_0(outA, outD, inA, inD, cospi22_v, cospi10_v); \ - STEP8_0(outB, outC, inB, inC, cospi6_v, cospi26_v); \ - \ - /* stage 3 */ \ - out0 = in0; \ - out1 = in1; \ - out2 = in2; \ - out3 = in3; \ - \ - STEP8_0(in4, in7, out4, out7, cospi28_v, cospi4_v); \ - STEP8_0(in5, in6, out5, out6, cospi12_v, cospi20_v); \ - \ - out8 = vec_add(in8, in9); \ - out9 = vec_sub(in8, in9); \ - outA = vec_sub(inB, inA); \ - outB = vec_add(inA, inB); \ - outC = vec_add(inC, inD); \ - outD = vec_sub(inC, inD); \ - outE = vec_sub(inF, inE); \ - outF = vec_add(inE, inF); \ - \ - /* stage 4 */ \ - STEP16_1(out0, out1, in1, in0, cospi16_v); \ - STEP8_0(out2, out3, in2, in3, cospi24_v, cospi8_v); \ - in4 = vec_add(out4, out5); \ - in5 = vec_sub(out4, out5); \ - in6 = vec_sub(out7, out6); \ - in7 = vec_add(out6, out7); \ - \ - in8 = out8; \ - inF = outF; \ - tmp16_0 = vec_mergeh(out9, outE); \ - tmp16_1 = vec_mergel(out9, outE); \ - temp10 = vec_sub(vec_mulo(tmp16_0, cospi24_v), vec_mule(tmp16_0, cospi8_v)); \ - temp11 = vec_sub(vec_mulo(tmp16_1, cospi24_v), vec_mule(tmp16_1, cospi8_v)); \ - DCT_CONST_ROUND_SHIFT(temp10); \ - DCT_CONST_ROUND_SHIFT(temp11); \ - in9 = vec_packs(temp10, temp11); \ - temp10 = vec_add(vec_mule(tmp16_0, cospi24_v), vec_mulo(tmp16_0, cospi8_v)); \ - temp11 = vec_add(vec_mule(tmp16_1, cospi24_v), vec_mulo(tmp16_1, cospi8_v)); \ - DCT_CONST_ROUND_SHIFT(temp10); \ - DCT_CONST_ROUND_SHIFT(temp11); \ - inE = vec_packs(temp10, temp11); \ - \ - tmp16_0 = vec_mergeh(outA, outD); \ - tmp16_1 = vec_mergel(outA, outD); \ - temp10 = \ - vec_sub(vec_mule(tmp16_0, cospi24m_v), vec_mulo(tmp16_0, cospi8_v)); \ - temp11 = \ - vec_sub(vec_mule(tmp16_1, cospi24m_v), vec_mulo(tmp16_1, cospi8_v)); \ - DCT_CONST_ROUND_SHIFT(temp10); \ - DCT_CONST_ROUND_SHIFT(temp11); \ - inA = vec_packs(temp10, temp11); \ - temp10 = vec_sub(vec_mulo(tmp16_0, cospi24_v), vec_mule(tmp16_0, cospi8_v)); \ - temp11 = vec_sub(vec_mulo(tmp16_1, cospi24_v), vec_mule(tmp16_1, cospi8_v)); \ - DCT_CONST_ROUND_SHIFT(temp10); \ - DCT_CONST_ROUND_SHIFT(temp11); \ - inD = vec_packs(temp10, temp11); \ - \ - inB = outB; \ - inC = outC; \ - \ - /* stage 5 */ \ - out0 = vec_add(in0, in3); \ - out1 = vec_add(in1, in2); \ - out2 = vec_sub(in1, in2); \ - out3 = vec_sub(in0, in3); \ - out4 = in4; \ - STEP16_1(in6, in5, out5, out6, cospi16_v); \ - out7 = in7; \ - \ - out8 = vec_add(in8, inB); \ - out9 = vec_add(in9, inA); \ - outA = vec_sub(in9, inA); \ - outB = vec_sub(in8, inB); \ - outC = vec_sub(inF, inC); \ - outD = vec_sub(inE, inD); \ - outE = vec_add(inD, inE); \ - outF = vec_add(inC, inF); \ - \ - /* stage 6 */ \ - in0 = vec_add(out0, out7); \ - in1 = vec_add(out1, out6); \ - in2 = vec_add(out2, out5); \ - in3 = vec_add(out3, out4); \ - in4 = vec_sub(out3, out4); \ - in5 = vec_sub(out2, out5); \ - in6 = vec_sub(out1, out6); \ - in7 = vec_sub(out0, out7); \ - in8 = out8; \ - in9 = out9; \ - STEP16_1(outD, outA, inA, inD, cospi16_v); \ - STEP16_1(outC, outB, inB, inC, cospi16_v); \ - inE = outE; \ - inF = outF; \ - \ - /* stage 7 */ \ - out0 = vec_add(in0, inF); \ - out1 = vec_add(in1, inE); \ - out2 = vec_add(in2, inD); \ - out3 = vec_add(in3, inC); \ - out4 = vec_add(in4, inB); \ - out5 = vec_add(in5, inA); \ - out6 = vec_add(in6, in9); \ - out7 = vec_add(in7, in8); \ - out8 = vec_sub(in7, in8); \ - out9 = vec_sub(in6, in9); \ - outA = vec_sub(in5, inA); \ - outB = vec_sub(in4, inB); \ - outC = vec_sub(in3, inC); \ - outD = vec_sub(in2, inD); \ - outE = vec_sub(in1, inE); \ - outF = vec_sub(in0, inF); - -#define PIXEL_ADD_STORE16(in0, in1, dst, offset) \ - d_uh = (int16x8_t)vec_mergeh(dst, zerov); \ - d_ul = (int16x8_t)vec_mergel(dst, zerov); \ - PIXEL_ADD(in0, d_uh, add, shift6); \ - PIXEL_ADD(in1, d_ul, add, shift6); \ - vec_vsx_st(vec_packsu(d_uh, d_ul), offset, dest); - -static void half_idct16x8_vsx(int16x8_t *src) { - int16x8_t tmp0[8], tmp1[8]; - int32x4_t temp10, temp11, temp20, temp21, temp30; - int16x8_t tmp16_0, tmp16_1; - ROUND_SHIFT_INIT; - - TRANSPOSE8x8(src[0], src[2], src[4], src[6], src[8], src[10], src[12], - src[14], tmp0[0], tmp0[1], tmp0[2], tmp0[3], tmp0[4], tmp0[5], - tmp0[6], tmp0[7]); - TRANSPOSE8x8(src[1], src[3], src[5], src[7], src[9], src[11], src[13], - src[15], tmp1[0], tmp1[1], tmp1[2], tmp1[3], tmp1[4], tmp1[5], - tmp1[6], tmp1[7]); - IDCT16(tmp0[0], tmp0[1], tmp0[2], tmp0[3], tmp0[4], tmp0[5], tmp0[6], tmp0[7], - tmp1[0], tmp1[1], tmp1[2], tmp1[3], tmp1[4], tmp1[5], tmp1[6], tmp1[7], - src[0], src[2], src[4], src[6], src[8], src[10], src[12], src[14], - src[1], src[3], src[5], src[7], src[9], src[11], src[13], src[15]); -} - -void vpx_idct16_vsx(int16x8_t *src0, int16x8_t *src1) { - int16x8_t tmp0[8], tmp1[8], tmp2[8], tmp3[8]; - int32x4_t temp10, temp11, temp20, temp21, temp30; - int16x8_t tmp16_0, tmp16_1; - ROUND_SHIFT_INIT; - - TRANSPOSE8x8(src0[0], src0[2], src0[4], src0[6], src0[8], src0[10], src0[12], - src0[14], tmp0[0], tmp0[1], tmp0[2], tmp0[3], tmp0[4], tmp0[5], - tmp0[6], tmp0[7]); - TRANSPOSE8x8(src0[1], src0[3], src0[5], src0[7], src0[9], src0[11], src0[13], - src0[15], tmp1[0], tmp1[1], tmp1[2], tmp1[3], tmp1[4], tmp1[5], - tmp1[6], tmp1[7]); - TRANSPOSE8x8(src1[0], src1[2], src1[4], src1[6], src1[8], src1[10], src1[12], - src1[14], tmp2[0], tmp2[1], tmp2[2], tmp2[3], tmp2[4], tmp2[5], - tmp2[6], tmp2[7]); - TRANSPOSE8x8(src1[1], src1[3], src1[5], src1[7], src1[9], src1[11], src1[13], - src1[15], tmp3[0], tmp3[1], tmp3[2], tmp3[3], tmp3[4], tmp3[5], - tmp3[6], tmp3[7]); - - IDCT16(tmp0[0], tmp0[1], tmp0[2], tmp0[3], tmp0[4], tmp0[5], tmp0[6], tmp0[7], - tmp1[0], tmp1[1], tmp1[2], tmp1[3], tmp1[4], tmp1[5], tmp1[6], tmp1[7], - src0[0], src0[2], src0[4], src0[6], src0[8], src0[10], src0[12], - src0[14], src1[0], src1[2], src1[4], src1[6], src1[8], src1[10], - src1[12], src1[14]); - - IDCT16(tmp2[0], tmp2[1], tmp2[2], tmp2[3], tmp2[4], tmp2[5], tmp2[6], tmp2[7], - tmp3[0], tmp3[1], tmp3[2], tmp3[3], tmp3[4], tmp3[5], tmp3[6], tmp3[7], - src0[1], src0[3], src0[5], src0[7], src0[9], src0[11], src0[13], - src0[15], src1[1], src1[3], src1[5], src1[7], src1[9], src1[11], - src1[13], src1[15]); -} - -void vpx_round_store16x16_vsx(int16x8_t *src0, int16x8_t *src1, uint8_t *dest, - int stride) { - uint8x16_t destv[16]; - int16x8_t d_uh, d_ul; - uint8x16_t zerov = vec_splat_u8(0); - uint16x8_t shift6 = vec_splat_u16(6); - int16x8_t add = vec_sl(vec_splat_s16(8), vec_splat_u16(2)); - - // load dest - LOAD_INPUT16(vec_vsx_ld, dest, 0, stride, destv); - - PIXEL_ADD_STORE16(src0[0], src0[1], destv[0], 0); - PIXEL_ADD_STORE16(src0[2], src0[3], destv[1], stride); - PIXEL_ADD_STORE16(src0[4], src0[5], destv[2], 2 * stride); - PIXEL_ADD_STORE16(src0[6], src0[7], destv[3], 3 * stride); - PIXEL_ADD_STORE16(src0[8], src0[9], destv[4], 4 * stride); - PIXEL_ADD_STORE16(src0[10], src0[11], destv[5], 5 * stride); - PIXEL_ADD_STORE16(src0[12], src0[13], destv[6], 6 * stride); - PIXEL_ADD_STORE16(src0[14], src0[15], destv[7], 7 * stride); - - PIXEL_ADD_STORE16(src1[0], src1[1], destv[8], 8 * stride); - PIXEL_ADD_STORE16(src1[2], src1[3], destv[9], 9 * stride); - PIXEL_ADD_STORE16(src1[4], src1[5], destv[10], 10 * stride); - PIXEL_ADD_STORE16(src1[6], src1[7], destv[11], 11 * stride); - PIXEL_ADD_STORE16(src1[8], src1[9], destv[12], 12 * stride); - PIXEL_ADD_STORE16(src1[10], src1[11], destv[13], 13 * stride); - PIXEL_ADD_STORE16(src1[12], src1[13], destv[14], 14 * stride); - PIXEL_ADD_STORE16(src1[14], src1[15], destv[15], 15 * stride); -} -void vpx_idct16x16_256_add_vsx(const tran_low_t *input, uint8_t *dest, - int stride) { - int16x8_t src0[16], src1[16]; - int16x8_t tmp0[8], tmp1[8], tmp2[8], tmp3[8]; - int32x4_t temp10, temp11, temp20, temp21, temp30; - int16x8_t tmp16_0, tmp16_1; - ROUND_SHIFT_INIT; - - LOAD_INPUT16(load_tran_low, input, 0, 8 * sizeof(*input), src0); - LOAD_INPUT16(load_tran_low, input, 8 * 8 * 2 * sizeof(*input), - 8 * sizeof(*input), src1); - - // transform rows - // transform the upper half of 16x16 matrix - half_idct16x8_vsx(src0); - TRANSPOSE8x8(src0[0], src0[2], src0[4], src0[6], src0[8], src0[10], src0[12], - src0[14], tmp0[0], tmp0[1], tmp0[2], tmp0[3], tmp0[4], tmp0[5], - tmp0[6], tmp0[7]); - TRANSPOSE8x8(src0[1], src0[3], src0[5], src0[7], src0[9], src0[11], src0[13], - src0[15], tmp1[0], tmp1[1], tmp1[2], tmp1[3], tmp1[4], tmp1[5], - tmp1[6], tmp1[7]); - - // transform the lower half of 16x16 matrix - half_idct16x8_vsx(src1); - TRANSPOSE8x8(src1[0], src1[2], src1[4], src1[6], src1[8], src1[10], src1[12], - src1[14], tmp2[0], tmp2[1], tmp2[2], tmp2[3], tmp2[4], tmp2[5], - tmp2[6], tmp2[7]); - TRANSPOSE8x8(src1[1], src1[3], src1[5], src1[7], src1[9], src1[11], src1[13], - src1[15], tmp3[0], tmp3[1], tmp3[2], tmp3[3], tmp3[4], tmp3[5], - tmp3[6], tmp3[7]); - - // transform columns - // left half first - IDCT16(tmp0[0], tmp0[1], tmp0[2], tmp0[3], tmp0[4], tmp0[5], tmp0[6], tmp0[7], - tmp2[0], tmp2[1], tmp2[2], tmp2[3], tmp2[4], tmp2[5], tmp2[6], tmp2[7], - src0[0], src0[2], src0[4], src0[6], src0[8], src0[10], src0[12], - src0[14], src1[0], src1[2], src1[4], src1[6], src1[8], src1[10], - src1[12], src1[14]); - // right half - IDCT16(tmp1[0], tmp1[1], tmp1[2], tmp1[3], tmp1[4], tmp1[5], tmp1[6], tmp1[7], - tmp3[0], tmp3[1], tmp3[2], tmp3[3], tmp3[4], tmp3[5], tmp3[6], tmp3[7], - src0[1], src0[3], src0[5], src0[7], src0[9], src0[11], src0[13], - src0[15], src1[1], src1[3], src1[5], src1[7], src1[9], src1[11], - src1[13], src1[15]); - - vpx_round_store16x16_vsx(src0, src1, dest, stride); -} - -#define LOAD_8x32(load, in00, in01, in02, in03, in10, in11, in12, in13, in20, \ - in21, in22, in23, in30, in31, in32, in33, in40, in41, in42, \ - in43, in50, in51, in52, in53, in60, in61, in62, in63, in70, \ - in71, in72, in73, offset) \ - /* load the first row from the 8x32 block*/ \ - in00 = load(offset, input); \ - in01 = load(offset + 16, input); \ - in02 = load(offset + 2 * 16, input); \ - in03 = load(offset + 3 * 16, input); \ - \ - in10 = load(offset + 4 * 16, input); \ - in11 = load(offset + 5 * 16, input); \ - in12 = load(offset + 6 * 16, input); \ - in13 = load(offset + 7 * 16, input); \ - \ - in20 = load(offset + 8 * 16, input); \ - in21 = load(offset + 9 * 16, input); \ - in22 = load(offset + 10 * 16, input); \ - in23 = load(offset + 11 * 16, input); \ - \ - in30 = load(offset + 12 * 16, input); \ - in31 = load(offset + 13 * 16, input); \ - in32 = load(offset + 14 * 16, input); \ - in33 = load(offset + 15 * 16, input); \ - \ - in40 = load(offset + 16 * 16, input); \ - in41 = load(offset + 17 * 16, input); \ - in42 = load(offset + 18 * 16, input); \ - in43 = load(offset + 19 * 16, input); \ - \ - in50 = load(offset + 20 * 16, input); \ - in51 = load(offset + 21 * 16, input); \ - in52 = load(offset + 22 * 16, input); \ - in53 = load(offset + 23 * 16, input); \ - \ - in60 = load(offset + 24 * 16, input); \ - in61 = load(offset + 25 * 16, input); \ - in62 = load(offset + 26 * 16, input); \ - in63 = load(offset + 27 * 16, input); \ - \ - /* load the last row from the 8x32 block*/ \ - in70 = load(offset + 28 * 16, input); \ - in71 = load(offset + 29 * 16, input); \ - in72 = load(offset + 30 * 16, input); \ - in73 = load(offset + 31 * 16, input); - -/* for the: temp1 = -step[x] * cospi_q + step[y] * cospi_z - * temp2 = step[x] * cospi_z + step[y] * cospi_q */ -#define STEP32(inpt0, inpt1, outpt0, outpt1, cospi0, cospi1) \ - tmp16_0 = vec_mergeh(inpt0, inpt1); \ - tmp16_1 = vec_mergel(inpt0, inpt1); \ - temp10 = vec_sub(vec_mulo(tmp16_0, cospi1), vec_mule(tmp16_0, cospi0)); \ - temp11 = vec_sub(vec_mulo(tmp16_1, cospi1), vec_mule(tmp16_1, cospi0)); \ - DCT_CONST_ROUND_SHIFT(temp10); \ - DCT_CONST_ROUND_SHIFT(temp11); \ - outpt0 = vec_packs(temp10, temp11); \ - temp10 = vec_add(vec_mule(tmp16_0, cospi1), vec_mulo(tmp16_0, cospi0)); \ - temp11 = vec_add(vec_mule(tmp16_1, cospi1), vec_mulo(tmp16_1, cospi0)); \ - DCT_CONST_ROUND_SHIFT(temp10); \ - DCT_CONST_ROUND_SHIFT(temp11); \ - outpt1 = vec_packs(temp10, temp11); - -/* for the: temp1 = -step[x] * cospi_q - step[y] * cospi_z - * temp2 = -step[x] * cospi_z + step[y] * cospi_q */ -#define STEP32_1(inpt0, inpt1, outpt0, outpt1, cospi0, cospi1, cospi1m) \ - tmp16_0 = vec_mergeh(inpt0, inpt1); \ - tmp16_1 = vec_mergel(inpt0, inpt1); \ - temp10 = vec_sub(vec_mulo(tmp16_0, cospi1m), vec_mule(tmp16_0, cospi0)); \ - temp11 = vec_sub(vec_mulo(tmp16_1, cospi1m), vec_mule(tmp16_1, cospi0)); \ - DCT_CONST_ROUND_SHIFT(temp10); \ - DCT_CONST_ROUND_SHIFT(temp11); \ - outpt0 = vec_packs(temp10, temp11); \ - temp10 = vec_sub(vec_mulo(tmp16_0, cospi0), vec_mule(tmp16_0, cospi1)); \ - temp11 = vec_sub(vec_mulo(tmp16_1, cospi0), vec_mule(tmp16_1, cospi1)); \ - DCT_CONST_ROUND_SHIFT(temp10); \ - DCT_CONST_ROUND_SHIFT(temp11); \ - outpt1 = vec_packs(temp10, temp11); - -#define IDCT32(in0, in1, in2, in3, out) \ - \ - /* stage 1 */ \ - /* out[0][0] = in[0][0]; */ \ - out[0][1] = in2[0]; \ - out[0][2] = in1[0]; \ - out[0][3] = in3[0]; \ - out[0][4] = in0[4]; \ - out[0][5] = in2[4]; \ - out[0][6] = in1[4]; \ - out[0][7] = in3[4]; \ - out[1][0] = in0[2]; \ - out[1][1] = in2[2]; \ - out[1][2] = in1[2]; \ - out[1][3] = in3[2]; \ - out[1][4] = in0[6]; \ - out[1][5] = in2[6]; \ - out[1][6] = in1[6]; \ - out[1][7] = in3[6]; \ - \ - STEP8_0(in0[1], in3[7], out[2][0], out[3][7], cospi31_v, cospi1_v); \ - STEP8_0(in2[1], in1[7], out[2][1], out[3][6], cospi15_v, cospi17_v); \ - STEP8_0(in1[1], in2[7], out[2][2], out[3][5], cospi23_v, cospi9_v); \ - STEP8_0(in3[1], in0[7], out[2][3], out[3][4], cospi7_v, cospi25_v); \ - STEP8_0(in0[5], in3[3], out[2][4], out[3][3], cospi27_v, cospi5_v); \ - STEP8_0(in2[5], in1[3], out[2][5], out[3][2], cospi11_v, cospi21_v); \ - STEP8_0(in1[5], in2[3], out[2][6], out[3][1], cospi19_v, cospi13_v); \ - STEP8_0(in3[5], in0[3], out[2][7], out[3][0], cospi3_v, cospi29_v); \ - \ - /* stage 2 */ \ - /* in0[0] = out[0][0]; */ \ - in0[1] = out[0][1]; \ - in0[2] = out[0][2]; \ - in0[3] = out[0][3]; \ - in0[4] = out[0][4]; \ - in0[5] = out[0][5]; \ - in0[6] = out[0][6]; \ - in0[7] = out[0][7]; \ - \ - STEP8_0(out[1][0], out[1][7], in1[0], in1[7], cospi30_v, cospi2_v); \ - STEP8_0(out[1][1], out[1][6], in1[1], in1[6], cospi14_v, cospi18_v); \ - STEP8_0(out[1][2], out[1][5], in1[2], in1[5], cospi22_v, cospi10_v); \ - STEP8_0(out[1][3], out[1][4], in1[3], in1[4], cospi6_v, cospi26_v); \ - \ - in2[0] = vec_add(out[2][0], out[2][1]); \ - in2[1] = vec_sub(out[2][0], out[2][1]); \ - in2[2] = vec_sub(out[2][3], out[2][2]); \ - in2[3] = vec_add(out[2][3], out[2][2]); \ - in2[4] = vec_add(out[2][4], out[2][5]); \ - in2[5] = vec_sub(out[2][4], out[2][5]); \ - in2[6] = vec_sub(out[2][7], out[2][6]); \ - in2[7] = vec_add(out[2][7], out[2][6]); \ - in3[0] = vec_add(out[3][0], out[3][1]); \ - in3[1] = vec_sub(out[3][0], out[3][1]); \ - in3[2] = vec_sub(out[3][3], out[3][2]); \ - in3[3] = vec_add(out[3][3], out[3][2]); \ - in3[4] = vec_add(out[3][4], out[3][5]); \ - in3[5] = vec_sub(out[3][4], out[3][5]); \ - in3[6] = vec_sub(out[3][7], out[3][6]); \ - in3[7] = vec_add(out[3][6], out[3][7]); \ - \ - /* stage 3 */ \ - out[0][0] = in0[0]; \ - out[0][1] = in0[1]; \ - out[0][2] = in0[2]; \ - out[0][3] = in0[3]; \ - \ - STEP8_0(in0[4], in0[7], out[0][4], out[0][7], cospi28_v, cospi4_v); \ - STEP8_0(in0[5], in0[6], out[0][5], out[0][6], cospi12_v, cospi20_v); \ - \ - out[1][0] = vec_add(in1[0], in1[1]); \ - out[1][1] = vec_sub(in1[0], in1[1]); \ - out[1][2] = vec_sub(in1[3], in1[2]); \ - out[1][3] = vec_add(in1[2], in1[3]); \ - out[1][4] = vec_add(in1[4], in1[5]); \ - out[1][5] = vec_sub(in1[4], in1[5]); \ - out[1][6] = vec_sub(in1[7], in1[6]); \ - out[1][7] = vec_add(in1[6], in1[7]); \ - \ - out[2][0] = in2[0]; \ - out[3][7] = in3[7]; \ - STEP32(in2[1], in3[6], out[2][1], out[3][6], cospi4_v, cospi28_v); \ - STEP32_1(in2[2], in3[5], out[2][2], out[3][5], cospi28_v, cospi4_v, \ - cospi4m_v); \ - out[2][3] = in2[3]; \ - out[2][4] = in2[4]; \ - STEP32(in2[5], in3[2], out[2][5], out[3][2], cospi20_v, cospi12_v); \ - STEP32_1(in2[6], in3[1], out[2][6], out[3][1], cospi12_v, cospi20_v, \ - cospi20m_v); \ - out[2][7] = in2[7]; \ - out[3][0] = in3[0]; \ - out[3][3] = in3[3]; \ - out[3][4] = in3[4]; \ - \ - /* stage 4 */ \ - STEP16_1(out[0][0], out[0][1], in0[1], in0[0], cospi16_v); \ - STEP8_0(out[0][2], out[0][3], in0[2], in0[3], cospi24_v, cospi8_v); \ - in0[4] = vec_add(out[0][4], out[0][5]); \ - in0[5] = vec_sub(out[0][4], out[0][5]); \ - in0[6] = vec_sub(out[0][7], out[0][6]); \ - in0[7] = vec_add(out[0][7], out[0][6]); \ - \ - in1[0] = out[1][0]; \ - in1[7] = out[1][7]; \ - STEP32(out[1][1], out[1][6], in1[1], in1[6], cospi8_v, cospi24_v); \ - STEP32_1(out[1][2], out[1][5], in1[2], in1[5], cospi24_v, cospi8_v, \ - cospi8m_v); \ - in1[3] = out[1][3]; \ - in1[4] = out[1][4]; \ - \ - in2[0] = vec_add(out[2][0], out[2][3]); \ - in2[1] = vec_add(out[2][1], out[2][2]); \ - in2[2] = vec_sub(out[2][1], out[2][2]); \ - in2[3] = vec_sub(out[2][0], out[2][3]); \ - in2[4] = vec_sub(out[2][7], out[2][4]); \ - in2[5] = vec_sub(out[2][6], out[2][5]); \ - in2[6] = vec_add(out[2][5], out[2][6]); \ - in2[7] = vec_add(out[2][4], out[2][7]); \ - \ - in3[0] = vec_add(out[3][0], out[3][3]); \ - in3[1] = vec_add(out[3][1], out[3][2]); \ - in3[2] = vec_sub(out[3][1], out[3][2]); \ - in3[3] = vec_sub(out[3][0], out[3][3]); \ - in3[4] = vec_sub(out[3][7], out[3][4]); \ - in3[5] = vec_sub(out[3][6], out[3][5]); \ - in3[6] = vec_add(out[3][5], out[3][6]); \ - in3[7] = vec_add(out[3][4], out[3][7]); \ - \ - /* stage 5 */ \ - out[0][0] = vec_add(in0[0], in0[3]); \ - out[0][1] = vec_add(in0[1], in0[2]); \ - out[0][2] = vec_sub(in0[1], in0[2]); \ - out[0][3] = vec_sub(in0[0], in0[3]); \ - out[0][4] = in0[4]; \ - STEP16_1(in0[6], in0[5], out[0][5], out[0][6], cospi16_v); \ - out[0][7] = in0[7]; \ - \ - out[1][0] = vec_add(in1[0], in1[3]); \ - out[1][1] = vec_add(in1[1], in1[2]); \ - out[1][2] = vec_sub(in1[1], in1[2]); \ - out[1][3] = vec_sub(in1[0], in1[3]); \ - out[1][4] = vec_sub(in1[7], in1[4]); \ - out[1][5] = vec_sub(in1[6], in1[5]); \ - out[1][6] = vec_add(in1[5], in1[6]); \ - out[1][7] = vec_add(in1[4], in1[7]); \ - \ - out[2][0] = in2[0]; \ - out[2][1] = in2[1]; \ - STEP32(in2[2], in3[5], out[2][2], out[3][5], cospi8_v, cospi24_v); \ - STEP32(in2[3], in3[4], out[2][3], out[3][4], cospi8_v, cospi24_v); \ - STEP32_1(in2[4], in3[3], out[2][4], out[3][3], cospi24_v, cospi8_v, \ - cospi8m_v); \ - STEP32_1(in2[5], in3[2], out[2][5], out[3][2], cospi24_v, cospi8_v, \ - cospi8m_v); \ - out[2][6] = in2[6]; \ - out[2][7] = in2[7]; \ - out[3][0] = in3[0]; \ - out[3][1] = in3[1]; \ - out[3][6] = in3[6]; \ - out[3][7] = in3[7]; \ - \ - /* stage 6 */ \ - in0[0] = vec_add(out[0][0], out[0][7]); \ - in0[1] = vec_add(out[0][1], out[0][6]); \ - in0[2] = vec_add(out[0][2], out[0][5]); \ - in0[3] = vec_add(out[0][3], out[0][4]); \ - in0[4] = vec_sub(out[0][3], out[0][4]); \ - in0[5] = vec_sub(out[0][2], out[0][5]); \ - in0[6] = vec_sub(out[0][1], out[0][6]); \ - in0[7] = vec_sub(out[0][0], out[0][7]); \ - in1[0] = out[1][0]; \ - in1[1] = out[1][1]; \ - STEP16_1(out[1][5], out[1][2], in1[2], in1[5], cospi16_v); \ - STEP16_1(out[1][4], out[1][3], in1[3], in1[4], cospi16_v); \ - in1[6] = out[1][6]; \ - in1[7] = out[1][7]; \ - \ - in2[0] = vec_add(out[2][0], out[2][7]); \ - in2[1] = vec_add(out[2][1], out[2][6]); \ - in2[2] = vec_add(out[2][2], out[2][5]); \ - in2[3] = vec_add(out[2][3], out[2][4]); \ - in2[4] = vec_sub(out[2][3], out[2][4]); \ - in2[5] = vec_sub(out[2][2], out[2][5]); \ - in2[6] = vec_sub(out[2][1], out[2][6]); \ - in2[7] = vec_sub(out[2][0], out[2][7]); \ - \ - in3[0] = vec_sub(out[3][7], out[3][0]); \ - in3[1] = vec_sub(out[3][6], out[3][1]); \ - in3[2] = vec_sub(out[3][5], out[3][2]); \ - in3[3] = vec_sub(out[3][4], out[3][3]); \ - in3[4] = vec_add(out[3][4], out[3][3]); \ - in3[5] = vec_add(out[3][5], out[3][2]); \ - in3[6] = vec_add(out[3][6], out[3][1]); \ - in3[7] = vec_add(out[3][7], out[3][0]); \ - \ - /* stage 7 */ \ - out[0][0] = vec_add(in0[0], in1[7]); \ - out[0][1] = vec_add(in0[1], in1[6]); \ - out[0][2] = vec_add(in0[2], in1[5]); \ - out[0][3] = vec_add(in0[3], in1[4]); \ - out[0][4] = vec_add(in0[4], in1[3]); \ - out[0][5] = vec_add(in0[5], in1[2]); \ - out[0][6] = vec_add(in0[6], in1[1]); \ - out[0][7] = vec_add(in0[7], in1[0]); \ - out[1][0] = vec_sub(in0[7], in1[0]); \ - out[1][1] = vec_sub(in0[6], in1[1]); \ - out[1][2] = vec_sub(in0[5], in1[2]); \ - out[1][3] = vec_sub(in0[4], in1[3]); \ - out[1][4] = vec_sub(in0[3], in1[4]); \ - out[1][5] = vec_sub(in0[2], in1[5]); \ - out[1][6] = vec_sub(in0[1], in1[6]); \ - out[1][7] = vec_sub(in0[0], in1[7]); \ - \ - out[2][0] = in2[0]; \ - out[2][1] = in2[1]; \ - out[2][2] = in2[2]; \ - out[2][3] = in2[3]; \ - STEP16_1(in3[3], in2[4], out[2][4], out[3][3], cospi16_v); \ - STEP16_1(in3[2], in2[5], out[2][5], out[3][2], cospi16_v); \ - STEP16_1(in3[1], in2[6], out[2][6], out[3][1], cospi16_v); \ - STEP16_1(in3[0], in2[7], out[2][7], out[3][0], cospi16_v); \ - out[3][4] = in3[4]; \ - out[3][5] = in3[5]; \ - out[3][6] = in3[6]; \ - out[3][7] = in3[7]; \ - \ - /* final */ \ - in0[0] = vec_add(out[0][0], out[3][7]); \ - in0[1] = vec_add(out[0][1], out[3][6]); \ - in0[2] = vec_add(out[0][2], out[3][5]); \ - in0[3] = vec_add(out[0][3], out[3][4]); \ - in0[4] = vec_add(out[0][4], out[3][3]); \ - in0[5] = vec_add(out[0][5], out[3][2]); \ - in0[6] = vec_add(out[0][6], out[3][1]); \ - in0[7] = vec_add(out[0][7], out[3][0]); \ - in1[0] = vec_add(out[1][0], out[2][7]); \ - in1[1] = vec_add(out[1][1], out[2][6]); \ - in1[2] = vec_add(out[1][2], out[2][5]); \ - in1[3] = vec_add(out[1][3], out[2][4]); \ - in1[4] = vec_add(out[1][4], out[2][3]); \ - in1[5] = vec_add(out[1][5], out[2][2]); \ - in1[6] = vec_add(out[1][6], out[2][1]); \ - in1[7] = vec_add(out[1][7], out[2][0]); \ - in2[0] = vec_sub(out[1][7], out[2][0]); \ - in2[1] = vec_sub(out[1][6], out[2][1]); \ - in2[2] = vec_sub(out[1][5], out[2][2]); \ - in2[3] = vec_sub(out[1][4], out[2][3]); \ - in2[4] = vec_sub(out[1][3], out[2][4]); \ - in2[5] = vec_sub(out[1][2], out[2][5]); \ - in2[6] = vec_sub(out[1][1], out[2][6]); \ - in2[7] = vec_sub(out[1][0], out[2][7]); \ - in3[0] = vec_sub(out[0][7], out[3][0]); \ - in3[1] = vec_sub(out[0][6], out[3][1]); \ - in3[2] = vec_sub(out[0][5], out[3][2]); \ - in3[3] = vec_sub(out[0][4], out[3][3]); \ - in3[4] = vec_sub(out[0][3], out[3][4]); \ - in3[5] = vec_sub(out[0][2], out[3][5]); \ - in3[6] = vec_sub(out[0][1], out[3][6]); \ - in3[7] = vec_sub(out[0][0], out[3][7]); - -// NOT A FULL TRANSPOSE! Transposes just each 8x8 block in each row, -// does not transpose rows -#define TRANSPOSE_8x32(in, out) \ - /* transpose 4 of 8x8 blocks */ \ - TRANSPOSE8x8(in[0][0], in[0][1], in[0][2], in[0][3], in[0][4], in[0][5], \ - in[0][6], in[0][7], out[0][0], out[0][1], out[0][2], out[0][3], \ - out[0][4], out[0][5], out[0][6], out[0][7]); \ - TRANSPOSE8x8(in[1][0], in[1][1], in[1][2], in[1][3], in[1][4], in[1][5], \ - in[1][6], in[1][7], out[1][0], out[1][1], out[1][2], out[1][3], \ - out[1][4], out[1][5], out[1][6], out[1][7]); \ - TRANSPOSE8x8(in[2][0], in[2][1], in[2][2], in[2][3], in[2][4], in[2][5], \ - in[2][6], in[2][7], out[2][0], out[2][1], out[2][2], out[2][3], \ - out[2][4], out[2][5], out[2][6], out[2][7]); \ - TRANSPOSE8x8(in[3][0], in[3][1], in[3][2], in[3][3], in[3][4], in[3][5], \ - in[3][6], in[3][7], out[3][0], out[3][1], out[3][2], out[3][3], \ - out[3][4], out[3][5], out[3][6], out[3][7]); - -#define PIXEL_ADD_STORE32(in0, in1, in2, in3, step) \ - dst = vec_vsx_ld((step)*stride, dest); \ - d_uh = (int16x8_t)vec_mergeh(dst, zerov); \ - d_ul = (int16x8_t)vec_mergel(dst, zerov); \ - PIXEL_ADD(in0, d_uh, add, shift6); \ - PIXEL_ADD(in1, d_ul, add, shift6); \ - vec_vsx_st(vec_packsu(d_uh, d_ul), (step)*stride, dest); \ - dst = vec_vsx_ld((step)*stride + 16, dest); \ - d_uh = (int16x8_t)vec_mergeh(dst, zerov); \ - d_ul = (int16x8_t)vec_mergel(dst, zerov); \ - PIXEL_ADD(in2, d_uh, add, shift6); \ - PIXEL_ADD(in3, d_ul, add, shift6); \ - vec_vsx_st(vec_packsu(d_uh, d_ul), (step)*stride + 16, dest); - -#define ADD_STORE_BLOCK(in, offset) \ - PIXEL_ADD_STORE32(in[0][0], in[1][0], in[2][0], in[3][0], (offset) + 0); \ - PIXEL_ADD_STORE32(in[0][1], in[1][1], in[2][1], in[3][1], (offset) + 1); \ - PIXEL_ADD_STORE32(in[0][2], in[1][2], in[2][2], in[3][2], (offset) + 2); \ - PIXEL_ADD_STORE32(in[0][3], in[1][3], in[2][3], in[3][3], (offset) + 3); \ - PIXEL_ADD_STORE32(in[0][4], in[1][4], in[2][4], in[3][4], (offset) + 4); \ - PIXEL_ADD_STORE32(in[0][5], in[1][5], in[2][5], in[3][5], (offset) + 5); \ - PIXEL_ADD_STORE32(in[0][6], in[1][6], in[2][6], in[3][6], (offset) + 6); \ - PIXEL_ADD_STORE32(in[0][7], in[1][7], in[2][7], in[3][7], (offset) + 7); - -void vpx_idct32x32_1024_add_vsx(const tran_low_t *input, uint8_t *dest, - int stride) { - int16x8_t src0[4][8], src1[4][8], src2[4][8], src3[4][8], tmp[4][8]; - int16x8_t tmp16_0, tmp16_1; - int32x4_t temp10, temp11, temp20, temp21, temp30; - uint8x16_t dst; - int16x8_t d_uh, d_ul; - int16x8_t add = vec_sl(vec_splat_s16(8), vec_splat_u16(2)); - uint16x8_t shift6 = vec_splat_u16(6); - uint8x16_t zerov = vec_splat_u8(0); - - ROUND_SHIFT_INIT; - - LOAD_8x32(load_tran_low, src0[0][0], src0[1][0], src0[2][0], src0[3][0], - src0[0][1], src0[1][1], src0[2][1], src0[3][1], src0[0][2], - src0[1][2], src0[2][2], src0[3][2], src0[0][3], src0[1][3], - src0[2][3], src0[3][3], src0[0][4], src0[1][4], src0[2][4], - src0[3][4], src0[0][5], src0[1][5], src0[2][5], src0[3][5], - src0[0][6], src0[1][6], src0[2][6], src0[3][6], src0[0][7], - src0[1][7], src0[2][7], src0[3][7], 0); - // Rows - // transpose the first row of 8x8 blocks - TRANSPOSE_8x32(src0, tmp); - // transform the 32x8 column - IDCT32(tmp[0], tmp[1], tmp[2], tmp[3], src0); - TRANSPOSE_8x32(tmp, src0); - - LOAD_8x32(load_tran_low, src1[0][0], src1[1][0], src1[2][0], src1[3][0], - src1[0][1], src1[1][1], src1[2][1], src1[3][1], src1[0][2], - src1[1][2], src1[2][2], src1[3][2], src1[0][3], src1[1][3], - src1[2][3], src1[3][3], src1[0][4], src1[1][4], src1[2][4], - src1[3][4], src1[0][5], src1[1][5], src1[2][5], src1[3][5], - src1[0][6], src1[1][6], src1[2][6], src1[3][6], src1[0][7], - src1[1][7], src1[2][7], src1[3][7], 512); - TRANSPOSE_8x32(src1, tmp); - IDCT32(tmp[0], tmp[1], tmp[2], tmp[3], src1); - TRANSPOSE_8x32(tmp, src1); - - LOAD_8x32(load_tran_low, src2[0][0], src2[1][0], src2[2][0], src2[3][0], - src2[0][1], src2[1][1], src2[2][1], src2[3][1], src2[0][2], - src2[1][2], src2[2][2], src2[3][2], src2[0][3], src2[1][3], - src2[2][3], src2[3][3], src2[0][4], src2[1][4], src2[2][4], - src2[3][4], src2[0][5], src2[1][5], src2[2][5], src2[3][5], - src2[0][6], src2[1][6], src2[2][6], src2[3][6], src2[0][7], - src2[1][7], src2[2][7], src2[3][7], 1024); - TRANSPOSE_8x32(src2, tmp); - IDCT32(tmp[0], tmp[1], tmp[2], tmp[3], src2); - TRANSPOSE_8x32(tmp, src2); - - LOAD_8x32(load_tran_low, src3[0][0], src3[1][0], src3[2][0], src3[3][0], - src3[0][1], src3[1][1], src3[2][1], src3[3][1], src3[0][2], - src3[1][2], src3[2][2], src3[3][2], src3[0][3], src3[1][3], - src3[2][3], src3[3][3], src3[0][4], src3[1][4], src3[2][4], - src3[3][4], src3[0][5], src3[1][5], src3[2][5], src3[3][5], - src3[0][6], src3[1][6], src3[2][6], src3[3][6], src3[0][7], - src3[1][7], src3[2][7], src3[3][7], 1536); - TRANSPOSE_8x32(src3, tmp); - IDCT32(tmp[0], tmp[1], tmp[2], tmp[3], src3); - TRANSPOSE_8x32(tmp, src3); - - // Columns - IDCT32(src0[0], src1[0], src2[0], src3[0], tmp); - IDCT32(src0[1], src1[1], src2[1], src3[1], tmp); - IDCT32(src0[2], src1[2], src2[2], src3[2], tmp); - IDCT32(src0[3], src1[3], src2[3], src3[3], tmp); - - ADD_STORE_BLOCK(src0, 0); - ADD_STORE_BLOCK(src1, 8); - ADD_STORE_BLOCK(src2, 16); - ADD_STORE_BLOCK(src3, 24); -} - -#define TRANSFORM_COLS \ - v32_a = vec_add(v32_a, v32_c); \ - v32_d = vec_sub(v32_d, v32_b); \ - v32_e = vec_sub(v32_a, v32_d); \ - v32_e = vec_sra(v32_e, one); \ - v32_b = vec_sub(v32_e, v32_b); \ - v32_c = vec_sub(v32_e, v32_c); \ - v32_a = vec_sub(v32_a, v32_b); \ - v32_d = vec_add(v32_d, v32_c); \ - v_a = vec_packs(v32_a, v32_b); \ - v_c = vec_packs(v32_c, v32_d); - -#define TRANSPOSE_WHT \ - tmp_a = vec_mergeh(v_a, v_c); \ - tmp_c = vec_mergel(v_a, v_c); \ - v_a = vec_mergeh(tmp_a, tmp_c); \ - v_c = vec_mergel(tmp_a, tmp_c); - -void vpx_iwht4x4_16_add_vsx(const tran_low_t *input, uint8_t *dest, - int stride) { - int16x8_t v_a = load_tran_low(0, input); - int16x8_t v_c = load_tran_low(8 * sizeof(*input), input); - int16x8_t tmp_a, tmp_c; - uint16x8_t two = vec_splat_u16(2); - uint32x4_t one = vec_splat_u32(1); - int16x8_t tmp16_0, tmp16_1; - int32x4_t v32_a, v32_c, v32_d, v32_b, v32_e; - uint8x16_t dest0 = vec_vsx_ld(0, dest); - uint8x16_t dest1 = vec_vsx_ld(stride, dest); - uint8x16_t dest2 = vec_vsx_ld(2 * stride, dest); - uint8x16_t dest3 = vec_vsx_ld(3 * stride, dest); - int16x8_t d_u0 = (int16x8_t)unpack_to_u16_h(dest0); - int16x8_t d_u1 = (int16x8_t)unpack_to_u16_h(dest1); - int16x8_t d_u2 = (int16x8_t)unpack_to_u16_h(dest2); - int16x8_t d_u3 = (int16x8_t)unpack_to_u16_h(dest3); - uint8x16_t output_v; - uint8_t tmp_dest[16]; - int i, j; - - v_a = vec_sra(v_a, two); - v_c = vec_sra(v_c, two); - - TRANSPOSE_WHT; - - v32_a = vec_unpackh(v_a); - v32_c = vec_unpackl(v_a); - - v32_d = vec_unpackh(v_c); - v32_b = vec_unpackl(v_c); - - TRANSFORM_COLS; - - TRANSPOSE_WHT; - - v32_a = vec_unpackh(v_a); - v32_c = vec_unpackl(v_a); - v32_d = vec_unpackh(v_c); - v32_b = vec_unpackl(v_c); - - TRANSFORM_COLS; - - PACK_STORE(v_a, v_c); -} - -void vp9_iadst4_vsx(int16x8_t *in, int16x8_t *out) { - int16x8_t sinpi_1_3_v, sinpi_4_2_v, sinpi_2_3_v, sinpi_1_4_v, sinpi_12_n3_v; - int32x4_t v_v[5], u_v[4]; - int32x4_t zerov = vec_splat_s32(0); - int16x8_t tmp0, tmp1; - int16x8_t zero16v = vec_splat_s16(0); - uint32x4_t shift16 = vec_sl(vec_splat_u32(8), vec_splat_u32(1)); - ROUND_SHIFT_INIT; - - sinpi_1_3_v = vec_mergel(sinpi_1_9_v, sinpi_3_9_v); - sinpi_4_2_v = vec_mergel(sinpi_4_9_v, sinpi_2_9_v); - sinpi_2_3_v = vec_mergel(sinpi_2_9_v, sinpi_3_9_v); - sinpi_1_4_v = vec_mergel(sinpi_1_9_v, sinpi_4_9_v); - sinpi_12_n3_v = vec_mergel(vec_add(sinpi_1_9_v, sinpi_2_9_v), - vec_sub(zero16v, sinpi_3_9_v)); - - tmp0 = (int16x8_t)vec_mergeh((int32x4_t)in[0], (int32x4_t)in[1]); - tmp1 = (int16x8_t)vec_mergel((int32x4_t)in[0], (int32x4_t)in[1]); - in[0] = (int16x8_t)vec_mergeh((int32x4_t)tmp0, (int32x4_t)tmp1); - in[1] = (int16x8_t)vec_mergel((int32x4_t)tmp0, (int32x4_t)tmp1); - - v_v[0] = vec_msum(in[0], sinpi_1_3_v, zerov); - v_v[1] = vec_msum(in[1], sinpi_4_2_v, zerov); - v_v[2] = vec_msum(in[0], sinpi_2_3_v, zerov); - v_v[3] = vec_msum(in[1], sinpi_1_4_v, zerov); - v_v[4] = vec_msum(in[0], sinpi_12_n3_v, zerov); - - in[0] = vec_sub(in[0], in[1]); - in[1] = (int16x8_t)vec_sra((int32x4_t)in[1], shift16); - in[0] = vec_add(in[0], in[1]); - in[0] = (int16x8_t)vec_sl((int32x4_t)in[0], shift16); - - u_v[0] = vec_add(v_v[0], v_v[1]); - u_v[1] = vec_sub(v_v[2], v_v[3]); - u_v[2] = vec_msum(in[0], sinpi_1_3_v, zerov); - u_v[3] = vec_sub(v_v[1], v_v[3]); - u_v[3] = vec_add(u_v[3], v_v[4]); - - DCT_CONST_ROUND_SHIFT(u_v[0]); - DCT_CONST_ROUND_SHIFT(u_v[1]); - DCT_CONST_ROUND_SHIFT(u_v[2]); - DCT_CONST_ROUND_SHIFT(u_v[3]); - - out[0] = vec_packs(u_v[0], u_v[1]); - out[1] = vec_packs(u_v[2], u_v[3]); -} - -#define MSUM_ROUND_SHIFT(a, b, cospi) \ - b = vec_msums(a, cospi, zerov); \ - DCT_CONST_ROUND_SHIFT(b); - -#define IADST_WRAPLOW(in0, in1, tmp0, tmp1, out, cospi) \ - MSUM_ROUND_SHIFT(in0, tmp0, cospi); \ - MSUM_ROUND_SHIFT(in1, tmp1, cospi); \ - out = vec_packs(tmp0, tmp1); - -void vp9_iadst8_vsx(int16x8_t *in, int16x8_t *out) { - int32x4_t tmp0[16], tmp1[16]; - - int32x4_t zerov = vec_splat_s32(0); - int16x8_t zero16v = vec_splat_s16(0); - int16x8_t cospi_p02_p30_v = vec_mergel(cospi2_v, cospi30_v); - int16x8_t cospi_p30_m02_v = vec_mergel(cospi30_v, cospi2m_v); - int16x8_t cospi_p10_p22_v = vec_mergel(cospi10_v, cospi22_v); - int16x8_t cospi_p22_m10_v = vec_mergel(cospi22_v, cospi10m_v); - int16x8_t cospi_p18_p14_v = vec_mergel(cospi18_v, cospi14_v); - int16x8_t cospi_p14_m18_v = vec_mergel(cospi14_v, cospi18m_v); - int16x8_t cospi_p26_p06_v = vec_mergel(cospi26_v, cospi6_v); - int16x8_t cospi_p06_m26_v = vec_mergel(cospi6_v, cospi26m_v); - int16x8_t cospi_p08_p24_v = vec_mergel(cospi8_v, cospi24_v); - int16x8_t cospi_p24_m08_v = vec_mergel(cospi24_v, cospi8m_v); - int16x8_t cospi_m24_p08_v = vec_mergel(cospi24m_v, cospi8_v); - int16x8_t cospi_p16_m16_v = vec_mergel(cospi16_v, cospi16m_v); - ROUND_SHIFT_INIT; - - TRANSPOSE8x8(in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7], out[0], - out[1], out[2], out[3], out[4], out[5], out[6], out[7]); - - // stage 1 - // interleave and multiply/add into 32-bit integer - in[0] = vec_mergeh(out[7], out[0]); - in[1] = vec_mergel(out[7], out[0]); - in[2] = vec_mergeh(out[5], out[2]); - in[3] = vec_mergel(out[5], out[2]); - in[4] = vec_mergeh(out[3], out[4]); - in[5] = vec_mergel(out[3], out[4]); - in[6] = vec_mergeh(out[1], out[6]); - in[7] = vec_mergel(out[1], out[6]); - - tmp1[0] = vec_msum(in[0], cospi_p02_p30_v, zerov); - tmp1[1] = vec_msum(in[1], cospi_p02_p30_v, zerov); - tmp1[2] = vec_msum(in[0], cospi_p30_m02_v, zerov); - tmp1[3] = vec_msum(in[1], cospi_p30_m02_v, zerov); - tmp1[4] = vec_msum(in[2], cospi_p10_p22_v, zerov); - tmp1[5] = vec_msum(in[3], cospi_p10_p22_v, zerov); - tmp1[6] = vec_msum(in[2], cospi_p22_m10_v, zerov); - tmp1[7] = vec_msum(in[3], cospi_p22_m10_v, zerov); - tmp1[8] = vec_msum(in[4], cospi_p18_p14_v, zerov); - tmp1[9] = vec_msum(in[5], cospi_p18_p14_v, zerov); - tmp1[10] = vec_msum(in[4], cospi_p14_m18_v, zerov); - tmp1[11] = vec_msum(in[5], cospi_p14_m18_v, zerov); - tmp1[12] = vec_msum(in[6], cospi_p26_p06_v, zerov); - tmp1[13] = vec_msum(in[7], cospi_p26_p06_v, zerov); - tmp1[14] = vec_msum(in[6], cospi_p06_m26_v, zerov); - tmp1[15] = vec_msum(in[7], cospi_p06_m26_v, zerov); - - tmp0[0] = vec_add(tmp1[0], tmp1[8]); - tmp0[1] = vec_add(tmp1[1], tmp1[9]); - tmp0[2] = vec_add(tmp1[2], tmp1[10]); - tmp0[3] = vec_add(tmp1[3], tmp1[11]); - tmp0[4] = vec_add(tmp1[4], tmp1[12]); - tmp0[5] = vec_add(tmp1[5], tmp1[13]); - tmp0[6] = vec_add(tmp1[6], tmp1[14]); - tmp0[7] = vec_add(tmp1[7], tmp1[15]); - tmp0[8] = vec_sub(tmp1[0], tmp1[8]); - tmp0[9] = vec_sub(tmp1[1], tmp1[9]); - tmp0[10] = vec_sub(tmp1[2], tmp1[10]); - tmp0[11] = vec_sub(tmp1[3], tmp1[11]); - tmp0[12] = vec_sub(tmp1[4], tmp1[12]); - tmp0[13] = vec_sub(tmp1[5], tmp1[13]); - tmp0[14] = vec_sub(tmp1[6], tmp1[14]); - tmp0[15] = vec_sub(tmp1[7], tmp1[15]); - - // shift and rounding - DCT_CONST_ROUND_SHIFT(tmp0[0]); - DCT_CONST_ROUND_SHIFT(tmp0[1]); - DCT_CONST_ROUND_SHIFT(tmp0[2]); - DCT_CONST_ROUND_SHIFT(tmp0[3]); - DCT_CONST_ROUND_SHIFT(tmp0[4]); - DCT_CONST_ROUND_SHIFT(tmp0[5]); - DCT_CONST_ROUND_SHIFT(tmp0[6]); - DCT_CONST_ROUND_SHIFT(tmp0[7]); - DCT_CONST_ROUND_SHIFT(tmp0[8]); - DCT_CONST_ROUND_SHIFT(tmp0[9]); - DCT_CONST_ROUND_SHIFT(tmp0[10]); - DCT_CONST_ROUND_SHIFT(tmp0[11]); - DCT_CONST_ROUND_SHIFT(tmp0[12]); - DCT_CONST_ROUND_SHIFT(tmp0[13]); - DCT_CONST_ROUND_SHIFT(tmp0[14]); - DCT_CONST_ROUND_SHIFT(tmp0[15]); - - // back to 16-bit - out[0] = vec_packs(tmp0[0], tmp0[1]); - out[1] = vec_packs(tmp0[2], tmp0[3]); - out[2] = vec_packs(tmp0[4], tmp0[5]); - out[3] = vec_packs(tmp0[6], tmp0[7]); - out[4] = vec_packs(tmp0[8], tmp0[9]); - out[5] = vec_packs(tmp0[10], tmp0[11]); - out[6] = vec_packs(tmp0[12], tmp0[13]); - out[7] = vec_packs(tmp0[14], tmp0[15]); - - // stage 2 - in[0] = vec_add(out[0], out[2]); - in[1] = vec_add(out[1], out[3]); - in[2] = vec_sub(out[0], out[2]); - in[3] = vec_sub(out[1], out[3]); - in[4] = vec_mergeh(out[4], out[5]); - in[5] = vec_mergel(out[4], out[5]); - in[6] = vec_mergeh(out[6], out[7]); - in[7] = vec_mergel(out[6], out[7]); - - tmp1[0] = vec_msum(in[4], cospi_p08_p24_v, zerov); - tmp1[1] = vec_msum(in[5], cospi_p08_p24_v, zerov); - tmp1[2] = vec_msum(in[4], cospi_p24_m08_v, zerov); - tmp1[3] = vec_msum(in[5], cospi_p24_m08_v, zerov); - tmp1[4] = vec_msum(in[6], cospi_m24_p08_v, zerov); - tmp1[5] = vec_msum(in[7], cospi_m24_p08_v, zerov); - tmp1[6] = vec_msum(in[6], cospi_p08_p24_v, zerov); - tmp1[7] = vec_msum(in[7], cospi_p08_p24_v, zerov); - - tmp0[0] = vec_add(tmp1[0], tmp1[4]); - tmp0[1] = vec_add(tmp1[1], tmp1[5]); - tmp0[2] = vec_add(tmp1[2], tmp1[6]); - tmp0[3] = vec_add(tmp1[3], tmp1[7]); - tmp0[4] = vec_sub(tmp1[0], tmp1[4]); - tmp0[5] = vec_sub(tmp1[1], tmp1[5]); - tmp0[6] = vec_sub(tmp1[2], tmp1[6]); - tmp0[7] = vec_sub(tmp1[3], tmp1[7]); - - DCT_CONST_ROUND_SHIFT(tmp0[0]); - DCT_CONST_ROUND_SHIFT(tmp0[1]); - DCT_CONST_ROUND_SHIFT(tmp0[2]); - DCT_CONST_ROUND_SHIFT(tmp0[3]); - DCT_CONST_ROUND_SHIFT(tmp0[4]); - DCT_CONST_ROUND_SHIFT(tmp0[5]); - DCT_CONST_ROUND_SHIFT(tmp0[6]); - DCT_CONST_ROUND_SHIFT(tmp0[7]); - - in[4] = vec_packs(tmp0[0], tmp0[1]); - in[5] = vec_packs(tmp0[2], tmp0[3]); - in[6] = vec_packs(tmp0[4], tmp0[5]); - in[7] = vec_packs(tmp0[6], tmp0[7]); - - // stage 3 - out[0] = vec_mergeh(in[2], in[3]); - out[1] = vec_mergel(in[2], in[3]); - out[2] = vec_mergeh(in[6], in[7]); - out[3] = vec_mergel(in[6], in[7]); - - IADST_WRAPLOW(out[0], out[1], tmp0[0], tmp0[1], in[2], cospi16_v); - IADST_WRAPLOW(out[0], out[1], tmp0[0], tmp0[1], in[3], cospi_p16_m16_v); - IADST_WRAPLOW(out[2], out[3], tmp0[0], tmp0[1], in[6], cospi16_v); - IADST_WRAPLOW(out[2], out[3], tmp0[0], tmp0[1], in[7], cospi_p16_m16_v); - - out[0] = in[0]; - out[2] = in[6]; - out[4] = in[3]; - out[6] = in[5]; - - out[1] = vec_sub(zero16v, in[4]); - out[3] = vec_sub(zero16v, in[2]); - out[5] = vec_sub(zero16v, in[7]); - out[7] = vec_sub(zero16v, in[1]); -} - -static void iadst16x8_vsx(int16x8_t *in, int16x8_t *out) { - int32x4_t tmp0[32], tmp1[32]; - int16x8_t tmp16_0[8]; - int16x8_t cospi_p01_p31 = vec_mergel(cospi1_v, cospi31_v); - int16x8_t cospi_p31_m01 = vec_mergel(cospi31_v, cospi1m_v); - int16x8_t cospi_p05_p27 = vec_mergel(cospi5_v, cospi27_v); - int16x8_t cospi_p27_m05 = vec_mergel(cospi27_v, cospi5m_v); - int16x8_t cospi_p09_p23 = vec_mergel(cospi9_v, cospi23_v); - int16x8_t cospi_p23_m09 = vec_mergel(cospi23_v, cospi9m_v); - int16x8_t cospi_p13_p19 = vec_mergel(cospi13_v, cospi19_v); - int16x8_t cospi_p19_m13 = vec_mergel(cospi19_v, cospi13m_v); - int16x8_t cospi_p17_p15 = vec_mergel(cospi17_v, cospi15_v); - int16x8_t cospi_p15_m17 = vec_mergel(cospi15_v, cospi17m_v); - int16x8_t cospi_p21_p11 = vec_mergel(cospi21_v, cospi11_v); - int16x8_t cospi_p11_m21 = vec_mergel(cospi11_v, cospi21m_v); - int16x8_t cospi_p25_p07 = vec_mergel(cospi25_v, cospi7_v); - int16x8_t cospi_p07_m25 = vec_mergel(cospi7_v, cospi25m_v); - int16x8_t cospi_p29_p03 = vec_mergel(cospi29_v, cospi3_v); - int16x8_t cospi_p03_m29 = vec_mergel(cospi3_v, cospi29m_v); - int16x8_t cospi_p04_p28 = vec_mergel(cospi4_v, cospi28_v); - int16x8_t cospi_p28_m04 = vec_mergel(cospi28_v, cospi4m_v); - int16x8_t cospi_p20_p12 = vec_mergel(cospi20_v, cospi12_v); - int16x8_t cospi_p12_m20 = vec_mergel(cospi12_v, cospi20m_v); - int16x8_t cospi_m28_p04 = vec_mergel(cospi28m_v, cospi4_v); - int16x8_t cospi_m12_p20 = vec_mergel(cospi12m_v, cospi20_v); - int16x8_t cospi_p08_p24 = vec_mergel(cospi8_v, cospi24_v); - int16x8_t cospi_p24_m08 = vec_mergel(cospi24_v, cospi8m_v); - int16x8_t cospi_m24_p08 = vec_mergel(cospi24m_v, cospi8_v); - int32x4_t zerov = vec_splat_s32(0); - ROUND_SHIFT_INIT; - - tmp16_0[0] = vec_mergeh(in[15], in[0]); - tmp16_0[1] = vec_mergel(in[15], in[0]); - tmp16_0[2] = vec_mergeh(in[13], in[2]); - tmp16_0[3] = vec_mergel(in[13], in[2]); - tmp16_0[4] = vec_mergeh(in[11], in[4]); - tmp16_0[5] = vec_mergel(in[11], in[4]); - tmp16_0[6] = vec_mergeh(in[9], in[6]); - tmp16_0[7] = vec_mergel(in[9], in[6]); - tmp16_0[8] = vec_mergeh(in[7], in[8]); - tmp16_0[9] = vec_mergel(in[7], in[8]); - tmp16_0[10] = vec_mergeh(in[5], in[10]); - tmp16_0[11] = vec_mergel(in[5], in[10]); - tmp16_0[12] = vec_mergeh(in[3], in[12]); - tmp16_0[13] = vec_mergel(in[3], in[12]); - tmp16_0[14] = vec_mergeh(in[1], in[14]); - tmp16_0[15] = vec_mergel(in[1], in[14]); - - tmp0[0] = vec_msum(tmp16_0[0], cospi_p01_p31, zerov); - tmp0[1] = vec_msum(tmp16_0[1], cospi_p01_p31, zerov); - tmp0[2] = vec_msum(tmp16_0[0], cospi_p31_m01, zerov); - tmp0[3] = vec_msum(tmp16_0[1], cospi_p31_m01, zerov); - tmp0[4] = vec_msum(tmp16_0[2], cospi_p05_p27, zerov); - tmp0[5] = vec_msum(tmp16_0[3], cospi_p05_p27, zerov); - tmp0[6] = vec_msum(tmp16_0[2], cospi_p27_m05, zerov); - tmp0[7] = vec_msum(tmp16_0[3], cospi_p27_m05, zerov); - tmp0[8] = vec_msum(tmp16_0[4], cospi_p09_p23, zerov); - tmp0[9] = vec_msum(tmp16_0[5], cospi_p09_p23, zerov); - tmp0[10] = vec_msum(tmp16_0[4], cospi_p23_m09, zerov); - tmp0[11] = vec_msum(tmp16_0[5], cospi_p23_m09, zerov); - tmp0[12] = vec_msum(tmp16_0[6], cospi_p13_p19, zerov); - tmp0[13] = vec_msum(tmp16_0[7], cospi_p13_p19, zerov); - tmp0[14] = vec_msum(tmp16_0[6], cospi_p19_m13, zerov); - tmp0[15] = vec_msum(tmp16_0[7], cospi_p19_m13, zerov); - tmp0[16] = vec_msum(tmp16_0[8], cospi_p17_p15, zerov); - tmp0[17] = vec_msum(tmp16_0[9], cospi_p17_p15, zerov); - tmp0[18] = vec_msum(tmp16_0[8], cospi_p15_m17, zerov); - tmp0[19] = vec_msum(tmp16_0[9], cospi_p15_m17, zerov); - tmp0[20] = vec_msum(tmp16_0[10], cospi_p21_p11, zerov); - tmp0[21] = vec_msum(tmp16_0[11], cospi_p21_p11, zerov); - tmp0[22] = vec_msum(tmp16_0[10], cospi_p11_m21, zerov); - tmp0[23] = vec_msum(tmp16_0[11], cospi_p11_m21, zerov); - tmp0[24] = vec_msum(tmp16_0[12], cospi_p25_p07, zerov); - tmp0[25] = vec_msum(tmp16_0[13], cospi_p25_p07, zerov); - tmp0[26] = vec_msum(tmp16_0[12], cospi_p07_m25, zerov); - tmp0[27] = vec_msum(tmp16_0[13], cospi_p07_m25, zerov); - tmp0[28] = vec_msum(tmp16_0[14], cospi_p29_p03, zerov); - tmp0[29] = vec_msum(tmp16_0[15], cospi_p29_p03, zerov); - tmp0[30] = vec_msum(tmp16_0[14], cospi_p03_m29, zerov); - tmp0[31] = vec_msum(tmp16_0[15], cospi_p03_m29, zerov); - - tmp1[0] = vec_add(tmp0[0], tmp0[16]); - tmp1[1] = vec_add(tmp0[1], tmp0[17]); - tmp1[2] = vec_add(tmp0[2], tmp0[18]); - tmp1[3] = vec_add(tmp0[3], tmp0[19]); - tmp1[4] = vec_add(tmp0[4], tmp0[20]); - tmp1[5] = vec_add(tmp0[5], tmp0[21]); - tmp1[6] = vec_add(tmp0[6], tmp0[22]); - tmp1[7] = vec_add(tmp0[7], tmp0[23]); - tmp1[8] = vec_add(tmp0[8], tmp0[24]); - tmp1[9] = vec_add(tmp0[9], tmp0[25]); - tmp1[10] = vec_add(tmp0[10], tmp0[26]); - tmp1[11] = vec_add(tmp0[11], tmp0[27]); - tmp1[12] = vec_add(tmp0[12], tmp0[28]); - tmp1[13] = vec_add(tmp0[13], tmp0[29]); - tmp1[14] = vec_add(tmp0[14], tmp0[30]); - tmp1[15] = vec_add(tmp0[15], tmp0[31]); - tmp1[16] = vec_sub(tmp0[0], tmp0[16]); - tmp1[17] = vec_sub(tmp0[1], tmp0[17]); - tmp1[18] = vec_sub(tmp0[2], tmp0[18]); - tmp1[19] = vec_sub(tmp0[3], tmp0[19]); - tmp1[20] = vec_sub(tmp0[4], tmp0[20]); - tmp1[21] = vec_sub(tmp0[5], tmp0[21]); - tmp1[22] = vec_sub(tmp0[6], tmp0[22]); - tmp1[23] = vec_sub(tmp0[7], tmp0[23]); - tmp1[24] = vec_sub(tmp0[8], tmp0[24]); - tmp1[25] = vec_sub(tmp0[9], tmp0[25]); - tmp1[26] = vec_sub(tmp0[10], tmp0[26]); - tmp1[27] = vec_sub(tmp0[11], tmp0[27]); - tmp1[28] = vec_sub(tmp0[12], tmp0[28]); - tmp1[29] = vec_sub(tmp0[13], tmp0[29]); - tmp1[30] = vec_sub(tmp0[14], tmp0[30]); - tmp1[31] = vec_sub(tmp0[15], tmp0[31]); - - DCT_CONST_ROUND_SHIFT(tmp1[0]); - DCT_CONST_ROUND_SHIFT(tmp1[1]); - DCT_CONST_ROUND_SHIFT(tmp1[2]); - DCT_CONST_ROUND_SHIFT(tmp1[3]); - DCT_CONST_ROUND_SHIFT(tmp1[4]); - DCT_CONST_ROUND_SHIFT(tmp1[5]); - DCT_CONST_ROUND_SHIFT(tmp1[6]); - DCT_CONST_ROUND_SHIFT(tmp1[7]); - DCT_CONST_ROUND_SHIFT(tmp1[8]); - DCT_CONST_ROUND_SHIFT(tmp1[9]); - DCT_CONST_ROUND_SHIFT(tmp1[10]); - DCT_CONST_ROUND_SHIFT(tmp1[11]); - DCT_CONST_ROUND_SHIFT(tmp1[12]); - DCT_CONST_ROUND_SHIFT(tmp1[13]); - DCT_CONST_ROUND_SHIFT(tmp1[14]); - DCT_CONST_ROUND_SHIFT(tmp1[15]); - DCT_CONST_ROUND_SHIFT(tmp1[16]); - DCT_CONST_ROUND_SHIFT(tmp1[17]); - DCT_CONST_ROUND_SHIFT(tmp1[18]); - DCT_CONST_ROUND_SHIFT(tmp1[19]); - DCT_CONST_ROUND_SHIFT(tmp1[20]); - DCT_CONST_ROUND_SHIFT(tmp1[21]); - DCT_CONST_ROUND_SHIFT(tmp1[22]); - DCT_CONST_ROUND_SHIFT(tmp1[23]); - DCT_CONST_ROUND_SHIFT(tmp1[24]); - DCT_CONST_ROUND_SHIFT(tmp1[25]); - DCT_CONST_ROUND_SHIFT(tmp1[26]); - DCT_CONST_ROUND_SHIFT(tmp1[27]); - DCT_CONST_ROUND_SHIFT(tmp1[28]); - DCT_CONST_ROUND_SHIFT(tmp1[29]); - DCT_CONST_ROUND_SHIFT(tmp1[30]); - DCT_CONST_ROUND_SHIFT(tmp1[31]); - - in[0] = vec_packs(tmp1[0], tmp1[1]); - in[1] = vec_packs(tmp1[2], tmp1[3]); - in[2] = vec_packs(tmp1[4], tmp1[5]); - in[3] = vec_packs(tmp1[6], tmp1[7]); - in[4] = vec_packs(tmp1[8], tmp1[9]); - in[5] = vec_packs(tmp1[10], tmp1[11]); - in[6] = vec_packs(tmp1[12], tmp1[13]); - in[7] = vec_packs(tmp1[14], tmp1[15]); - in[8] = vec_packs(tmp1[16], tmp1[17]); - in[9] = vec_packs(tmp1[18], tmp1[19]); - in[10] = vec_packs(tmp1[20], tmp1[21]); - in[11] = vec_packs(tmp1[22], tmp1[23]); - in[12] = vec_packs(tmp1[24], tmp1[25]); - in[13] = vec_packs(tmp1[26], tmp1[27]); - in[14] = vec_packs(tmp1[28], tmp1[29]); - in[15] = vec_packs(tmp1[30], tmp1[31]); - - // stage 2 - tmp16_0[0] = vec_mergeh(in[8], in[9]); - tmp16_0[1] = vec_mergel(in[8], in[9]); - tmp16_0[2] = vec_mergeh(in[10], in[11]); - tmp16_0[3] = vec_mergel(in[10], in[11]); - tmp16_0[4] = vec_mergeh(in[12], in[13]); - tmp16_0[5] = vec_mergel(in[12], in[13]); - tmp16_0[6] = vec_mergeh(in[14], in[15]); - tmp16_0[7] = vec_mergel(in[14], in[15]); - - tmp0[0] = vec_msum(tmp16_0[0], cospi_p04_p28, zerov); - tmp0[1] = vec_msum(tmp16_0[1], cospi_p04_p28, zerov); - tmp0[2] = vec_msum(tmp16_0[0], cospi_p28_m04, zerov); - tmp0[3] = vec_msum(tmp16_0[1], cospi_p28_m04, zerov); - tmp0[4] = vec_msum(tmp16_0[2], cospi_p20_p12, zerov); - tmp0[5] = vec_msum(tmp16_0[3], cospi_p20_p12, zerov); - tmp0[6] = vec_msum(tmp16_0[2], cospi_p12_m20, zerov); - tmp0[7] = vec_msum(tmp16_0[3], cospi_p12_m20, zerov); - tmp0[8] = vec_msum(tmp16_0[4], cospi_m28_p04, zerov); - tmp0[9] = vec_msum(tmp16_0[5], cospi_m28_p04, zerov); - tmp0[10] = vec_msum(tmp16_0[4], cospi_p04_p28, zerov); - tmp0[11] = vec_msum(tmp16_0[5], cospi_p04_p28, zerov); - tmp0[12] = vec_msum(tmp16_0[6], cospi_m12_p20, zerov); - tmp0[13] = vec_msum(tmp16_0[7], cospi_m12_p20, zerov); - tmp0[14] = vec_msum(tmp16_0[6], cospi_p20_p12, zerov); - tmp0[15] = vec_msum(tmp16_0[7], cospi_p20_p12, zerov); - - tmp1[0] = vec_add(tmp0[0], tmp0[8]); - tmp1[1] = vec_add(tmp0[1], tmp0[9]); - tmp1[2] = vec_add(tmp0[2], tmp0[10]); - tmp1[3] = vec_add(tmp0[3], tmp0[11]); - tmp1[4] = vec_add(tmp0[4], tmp0[12]); - tmp1[5] = vec_add(tmp0[5], tmp0[13]); - tmp1[6] = vec_add(tmp0[6], tmp0[14]); - tmp1[7] = vec_add(tmp0[7], tmp0[15]); - tmp1[8] = vec_sub(tmp0[0], tmp0[8]); - tmp1[9] = vec_sub(tmp0[1], tmp0[9]); - tmp1[10] = vec_sub(tmp0[2], tmp0[10]); - tmp1[11] = vec_sub(tmp0[3], tmp0[11]); - tmp1[12] = vec_sub(tmp0[4], tmp0[12]); - tmp1[13] = vec_sub(tmp0[5], tmp0[13]); - tmp1[14] = vec_sub(tmp0[6], tmp0[14]); - tmp1[15] = vec_sub(tmp0[7], tmp0[15]); - - DCT_CONST_ROUND_SHIFT(tmp1[0]); - DCT_CONST_ROUND_SHIFT(tmp1[1]); - DCT_CONST_ROUND_SHIFT(tmp1[2]); - DCT_CONST_ROUND_SHIFT(tmp1[3]); - DCT_CONST_ROUND_SHIFT(tmp1[4]); - DCT_CONST_ROUND_SHIFT(tmp1[5]); - DCT_CONST_ROUND_SHIFT(tmp1[6]); - DCT_CONST_ROUND_SHIFT(tmp1[7]); - DCT_CONST_ROUND_SHIFT(tmp1[8]); - DCT_CONST_ROUND_SHIFT(tmp1[9]); - DCT_CONST_ROUND_SHIFT(tmp1[10]); - DCT_CONST_ROUND_SHIFT(tmp1[11]); - DCT_CONST_ROUND_SHIFT(tmp1[12]); - DCT_CONST_ROUND_SHIFT(tmp1[13]); - DCT_CONST_ROUND_SHIFT(tmp1[14]); - DCT_CONST_ROUND_SHIFT(tmp1[15]); - - tmp16_0[0] = vec_add(in[0], in[4]); - tmp16_0[1] = vec_add(in[1], in[5]); - tmp16_0[2] = vec_add(in[2], in[6]); - tmp16_0[3] = vec_add(in[3], in[7]); - tmp16_0[4] = vec_sub(in[0], in[4]); - tmp16_0[5] = vec_sub(in[1], in[5]); - tmp16_0[6] = vec_sub(in[2], in[6]); - tmp16_0[7] = vec_sub(in[3], in[7]); - tmp16_0[8] = vec_packs(tmp1[0], tmp1[1]); - tmp16_0[9] = vec_packs(tmp1[2], tmp1[3]); - tmp16_0[10] = vec_packs(tmp1[4], tmp1[5]); - tmp16_0[11] = vec_packs(tmp1[6], tmp1[7]); - tmp16_0[12] = vec_packs(tmp1[8], tmp1[9]); - tmp16_0[13] = vec_packs(tmp1[10], tmp1[11]); - tmp16_0[14] = vec_packs(tmp1[12], tmp1[13]); - tmp16_0[15] = vec_packs(tmp1[14], tmp1[15]); - - // stage 3 - in[0] = vec_mergeh(tmp16_0[4], tmp16_0[5]); - in[1] = vec_mergel(tmp16_0[4], tmp16_0[5]); - in[2] = vec_mergeh(tmp16_0[6], tmp16_0[7]); - in[3] = vec_mergel(tmp16_0[6], tmp16_0[7]); - in[4] = vec_mergeh(tmp16_0[12], tmp16_0[13]); - in[5] = vec_mergel(tmp16_0[12], tmp16_0[13]); - in[6] = vec_mergeh(tmp16_0[14], tmp16_0[15]); - in[7] = vec_mergel(tmp16_0[14], tmp16_0[15]); - - tmp0[0] = vec_msum(in[0], cospi_p08_p24, zerov); - tmp0[1] = vec_msum(in[1], cospi_p08_p24, zerov); - tmp0[2] = vec_msum(in[0], cospi_p24_m08, zerov); - tmp0[3] = vec_msum(in[1], cospi_p24_m08, zerov); - tmp0[4] = vec_msum(in[2], cospi_m24_p08, zerov); - tmp0[5] = vec_msum(in[3], cospi_m24_p08, zerov); - tmp0[6] = vec_msum(in[2], cospi_p08_p24, zerov); - tmp0[7] = vec_msum(in[3], cospi_p08_p24, zerov); - tmp0[8] = vec_msum(in[4], cospi_p08_p24, zerov); - tmp0[9] = vec_msum(in[5], cospi_p08_p24, zerov); - tmp0[10] = vec_msum(in[4], cospi_p24_m08, zerov); - tmp0[11] = vec_msum(in[5], cospi_p24_m08, zerov); - tmp0[12] = vec_msum(in[6], cospi_m24_p08, zerov); - tmp0[13] = vec_msum(in[7], cospi_m24_p08, zerov); - tmp0[14] = vec_msum(in[6], cospi_p08_p24, zerov); - tmp0[15] = vec_msum(in[7], cospi_p08_p24, zerov); - - tmp1[0] = vec_add(tmp0[0], tmp0[4]); - tmp1[1] = vec_add(tmp0[1], tmp0[5]); - tmp1[2] = vec_add(tmp0[2], tmp0[6]); - tmp1[3] = vec_add(tmp0[3], tmp0[7]); - tmp1[4] = vec_sub(tmp0[0], tmp0[4]); - tmp1[5] = vec_sub(tmp0[1], tmp0[5]); - tmp1[6] = vec_sub(tmp0[2], tmp0[6]); - tmp1[7] = vec_sub(tmp0[3], tmp0[7]); - tmp1[8] = vec_add(tmp0[8], tmp0[12]); - tmp1[9] = vec_add(tmp0[9], tmp0[13]); - tmp1[10] = vec_add(tmp0[10], tmp0[14]); - tmp1[11] = vec_add(tmp0[11], tmp0[15]); - tmp1[12] = vec_sub(tmp0[8], tmp0[12]); - tmp1[13] = vec_sub(tmp0[9], tmp0[13]); - tmp1[14] = vec_sub(tmp0[10], tmp0[14]); - tmp1[15] = vec_sub(tmp0[11], tmp0[15]); - - DCT_CONST_ROUND_SHIFT(tmp1[0]); - DCT_CONST_ROUND_SHIFT(tmp1[1]); - DCT_CONST_ROUND_SHIFT(tmp1[2]); - DCT_CONST_ROUND_SHIFT(tmp1[3]); - DCT_CONST_ROUND_SHIFT(tmp1[4]); - DCT_CONST_ROUND_SHIFT(tmp1[5]); - DCT_CONST_ROUND_SHIFT(tmp1[6]); - DCT_CONST_ROUND_SHIFT(tmp1[7]); - DCT_CONST_ROUND_SHIFT(tmp1[8]); - DCT_CONST_ROUND_SHIFT(tmp1[9]); - DCT_CONST_ROUND_SHIFT(tmp1[10]); - DCT_CONST_ROUND_SHIFT(tmp1[11]); - DCT_CONST_ROUND_SHIFT(tmp1[12]); - DCT_CONST_ROUND_SHIFT(tmp1[13]); - DCT_CONST_ROUND_SHIFT(tmp1[14]); - DCT_CONST_ROUND_SHIFT(tmp1[15]); - - in[0] = vec_add(tmp16_0[0], tmp16_0[2]); - in[1] = vec_add(tmp16_0[1], tmp16_0[3]); - in[2] = vec_sub(tmp16_0[0], tmp16_0[2]); - in[3] = vec_sub(tmp16_0[1], tmp16_0[3]); - in[4] = vec_packs(tmp1[0], tmp1[1]); - in[5] = vec_packs(tmp1[2], tmp1[3]); - in[6] = vec_packs(tmp1[4], tmp1[5]); - in[7] = vec_packs(tmp1[6], tmp1[7]); - in[8] = vec_add(tmp16_0[8], tmp16_0[10]); - in[9] = vec_add(tmp16_0[9], tmp16_0[11]); - in[10] = vec_sub(tmp16_0[8], tmp16_0[10]); - in[11] = vec_sub(tmp16_0[9], tmp16_0[11]); - in[12] = vec_packs(tmp1[8], tmp1[9]); - in[13] = vec_packs(tmp1[10], tmp1[11]); - in[14] = vec_packs(tmp1[12], tmp1[13]); - in[15] = vec_packs(tmp1[14], tmp1[15]); - - // stage 4 - out[0] = vec_mergeh(in[2], in[3]); - out[1] = vec_mergel(in[2], in[3]); - out[2] = vec_mergeh(in[6], in[7]); - out[3] = vec_mergel(in[6], in[7]); - out[4] = vec_mergeh(in[10], in[11]); - out[5] = vec_mergel(in[10], in[11]); - out[6] = vec_mergeh(in[14], in[15]); - out[7] = vec_mergel(in[14], in[15]); -} - -void vpx_iadst16_vsx(int16x8_t *src0, int16x8_t *src1) { - int16x8_t tmp0[16], tmp1[16], tmp2[8]; - int32x4_t tmp3, tmp4; - int16x8_t zero16v = vec_splat_s16(0); - int32x4_t zerov = vec_splat_s32(0); - int16x8_t cospi_p16_m16 = vec_mergel(cospi16_v, cospi16m_v); - int16x8_t cospi_m16_p16 = vec_mergel(cospi16m_v, cospi16_v); - ROUND_SHIFT_INIT; - - TRANSPOSE8x8(src0[0], src0[2], src0[4], src0[6], src0[8], src0[10], src0[12], - src0[14], tmp0[0], tmp0[1], tmp0[2], tmp0[3], tmp0[4], tmp0[5], - tmp0[6], tmp0[7]); - TRANSPOSE8x8(src1[0], src1[2], src1[4], src1[6], src1[8], src1[10], src1[12], - src1[14], tmp1[0], tmp1[1], tmp1[2], tmp1[3], tmp1[4], tmp1[5], - tmp1[6], tmp1[7]); - TRANSPOSE8x8(src0[1], src0[3], src0[5], src0[7], src0[9], src0[11], src0[13], - src0[15], tmp0[8], tmp0[9], tmp0[10], tmp0[11], tmp0[12], - tmp0[13], tmp0[14], tmp0[15]); - TRANSPOSE8x8(src1[1], src1[3], src1[5], src1[7], src1[9], src1[11], src1[13], - src1[15], tmp1[8], tmp1[9], tmp1[10], tmp1[11], tmp1[12], - tmp1[13], tmp1[14], tmp1[15]); - - iadst16x8_vsx(tmp0, tmp2); - IADST_WRAPLOW(tmp2[0], tmp2[1], tmp3, tmp4, src0[14], cospi16m_v); - IADST_WRAPLOW(tmp2[0], tmp2[1], tmp3, tmp4, src1[0], cospi_p16_m16); - IADST_WRAPLOW(tmp2[2], tmp2[3], tmp3, tmp4, src0[8], cospi16_v); - IADST_WRAPLOW(tmp2[2], tmp2[3], tmp3, tmp4, src1[6], cospi_m16_p16); - IADST_WRAPLOW(tmp2[4], tmp2[5], tmp3, tmp4, src0[12], cospi16_v); - IADST_WRAPLOW(tmp2[4], tmp2[5], tmp3, tmp4, src1[2], cospi_m16_p16); - IADST_WRAPLOW(tmp2[6], tmp2[7], tmp3, tmp4, src0[10], cospi16m_v); - IADST_WRAPLOW(tmp2[6], tmp2[7], tmp3, tmp4, src1[4], cospi_p16_m16); - - src0[0] = tmp0[0]; - src0[2] = vec_sub(zero16v, tmp0[8]); - src0[4] = tmp0[12]; - src0[6] = vec_sub(zero16v, tmp0[4]); - src1[8] = tmp0[5]; - src1[10] = vec_sub(zero16v, tmp0[13]); - src1[12] = tmp0[9]; - src1[14] = vec_sub(zero16v, tmp0[1]); - - iadst16x8_vsx(tmp1, tmp2); - IADST_WRAPLOW(tmp2[0], tmp2[1], tmp3, tmp4, src0[15], cospi16m_v); - IADST_WRAPLOW(tmp2[0], tmp2[1], tmp3, tmp4, src1[1], cospi_p16_m16); - IADST_WRAPLOW(tmp2[2], tmp2[3], tmp3, tmp4, src0[9], cospi16_v); - IADST_WRAPLOW(tmp2[2], tmp2[3], tmp3, tmp4, src1[7], cospi_m16_p16); - IADST_WRAPLOW(tmp2[4], tmp2[5], tmp3, tmp4, src0[13], cospi16_v); - IADST_WRAPLOW(tmp2[4], tmp2[5], tmp3, tmp4, src1[3], cospi_m16_p16); - IADST_WRAPLOW(tmp2[6], tmp2[7], tmp3, tmp4, src0[11], cospi16m_v); - IADST_WRAPLOW(tmp2[6], tmp2[7], tmp3, tmp4, src1[5], cospi_p16_m16); - - src0[1] = tmp1[0]; - src0[3] = vec_sub(zero16v, tmp1[8]); - src0[5] = tmp1[12]; - src0[7] = vec_sub(zero16v, tmp1[4]); - src1[9] = tmp1[5]; - src1[11] = vec_sub(zero16v, tmp1[13]); - src1[13] = tmp1[9]; - src1[15] = vec_sub(zero16v, tmp1[1]); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/inv_txfm_vsx.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/inv_txfm_vsx.h deleted file mode 100644 index 7031742c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/inv_txfm_vsx.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_PPC_INV_TXFM_VSX_H_ -#define VPX_VPX_DSP_PPC_INV_TXFM_VSX_H_ - -#include "vpx_dsp/ppc/types_vsx.h" - -void vpx_round_store4x4_vsx(int16x8_t *in, int16x8_t *out, uint8_t *dest, - int stride); -void vpx_idct4_vsx(int16x8_t *in, int16x8_t *out); -void vp9_iadst4_vsx(int16x8_t *in, int16x8_t *out); - -void vpx_round_store8x8_vsx(int16x8_t *in, uint8_t *dest, int stride); -void vpx_idct8_vsx(int16x8_t *in, int16x8_t *out); -void vp9_iadst8_vsx(int16x8_t *in, int16x8_t *out); - -#define LOAD_INPUT16(load, source, offset, step, in) \ - in[0] = load(offset, source); \ - in[1] = load((step) + (offset), source); \ - in[2] = load(2 * (step) + (offset), source); \ - in[3] = load(3 * (step) + (offset), source); \ - in[4] = load(4 * (step) + (offset), source); \ - in[5] = load(5 * (step) + (offset), source); \ - in[6] = load(6 * (step) + (offset), source); \ - in[7] = load(7 * (step) + (offset), source); \ - in[8] = load(8 * (step) + (offset), source); \ - in[9] = load(9 * (step) + (offset), source); \ - in[10] = load(10 * (step) + (offset), source); \ - in[11] = load(11 * (step) + (offset), source); \ - in[12] = load(12 * (step) + (offset), source); \ - in[13] = load(13 * (step) + (offset), source); \ - in[14] = load(14 * (step) + (offset), source); \ - in[15] = load(15 * (step) + (offset), source); - -void vpx_round_store16x16_vsx(int16x8_t *src0, int16x8_t *src1, uint8_t *dest, - int stride); -void vpx_idct16_vsx(int16x8_t *src0, int16x8_t *src1); -void vpx_iadst16_vsx(int16x8_t *src0, int16x8_t *src1); - -#endif // VPX_VPX_DSP_PPC_INV_TXFM_VSX_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/quantize_vsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/quantize_vsx.c deleted file mode 100644 index ab71f6e2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/quantize_vsx.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/ppc/types_vsx.h" - -// Negate 16-bit integers in a when the corresponding signed 16-bit -// integer in b is negative. -static INLINE int16x8_t vec_sign(int16x8_t a, int16x8_t b) { - const int16x8_t mask = vec_sra(b, vec_shift_sign_s16); - return vec_xor(vec_add(a, mask), mask); -} - -// Sets the value of a 32-bit integers to 1 when the corresponding value in a is -// negative. -static INLINE int32x4_t vec_is_neg(int32x4_t a) { - return vec_sr(a, vec_shift_sign_s32); -} - -// Multiply the packed 16-bit integers in a and b, producing intermediate 32-bit -// integers, and return the high 16 bits of the intermediate integers. -// (a * b) >> 16 -static INLINE int16x8_t vec_mulhi(int16x8_t a, int16x8_t b) { - // madds does ((A * B) >>15) + C, we need >> 16, so we perform an extra right - // shift. - return vec_sra(vec_madds(a, b, vec_zeros_s16), vec_ones_u16); -} - -// Quantization function used for 4x4, 8x8 and 16x16 blocks. -static INLINE int16x8_t quantize_coeff(int16x8_t coeff, int16x8_t coeff_abs, - int16x8_t round, int16x8_t quant, - int16x8_t quant_shift, bool16x8_t mask) { - const int16x8_t rounded = vec_vaddshs(coeff_abs, round); - int16x8_t qcoeff = vec_mulhi(rounded, quant); - qcoeff = vec_add(qcoeff, rounded); - qcoeff = vec_mulhi(qcoeff, quant_shift); - qcoeff = vec_sign(qcoeff, coeff); - return vec_and(qcoeff, mask); -} - -// Quantization function used for 32x32 blocks. -static INLINE int16x8_t quantize_coeff_32(int16x8_t coeff, int16x8_t coeff_abs, - int16x8_t round, int16x8_t quant, - int16x8_t quant_shift, - bool16x8_t mask) { - const int16x8_t rounded = vec_vaddshs(coeff_abs, round); - int16x8_t qcoeff = vec_mulhi(rounded, quant); - qcoeff = vec_add(qcoeff, rounded); - // 32x32 blocks require an extra multiplication by 2, this compensates for the - // extra right shift added in vec_mulhi, as such vec_madds can be used - // directly instead of vec_mulhi (((a * b) >> 15) >> 1) << 1 == (a * b >> 15) - qcoeff = vec_madds(qcoeff, quant_shift, vec_zeros_s16); - qcoeff = vec_sign(qcoeff, coeff); - return vec_and(qcoeff, mask); -} - -// DeQuantization function used for 32x32 blocks. Quantized coeff of 32x32 -// blocks are twice as big as for other block sizes. As such, using -// vec_mladd results in overflow. -static INLINE int16x8_t dequantize_coeff_32(int16x8_t qcoeff, - int16x8_t dequant) { - int32x4_t dqcoeffe = vec_mule(qcoeff, dequant); - int32x4_t dqcoeffo = vec_mulo(qcoeff, dequant); - // Add 1 if negative to round towards zero because the C uses division. - dqcoeffe = vec_add(dqcoeffe, vec_is_neg(dqcoeffe)); - dqcoeffo = vec_add(dqcoeffo, vec_is_neg(dqcoeffo)); - dqcoeffe = vec_sra(dqcoeffe, vec_ones_u32); - dqcoeffo = vec_sra(dqcoeffo, vec_ones_u32); - return (int16x8_t)vec_perm(dqcoeffe, dqcoeffo, vec_perm_odd_even_pack); -} - -static INLINE int16x8_t nonzero_scanindex(int16x8_t qcoeff, - const int16_t *iscan_ptr, int index) { - int16x8_t scan = vec_vsx_ld(index, iscan_ptr); - bool16x8_t zero_coeff = vec_cmpeq(qcoeff, vec_zeros_s16); - return vec_andc(scan, zero_coeff); -} - -// Compare packed 16-bit integers across a, and return the maximum value in -// every element. Returns a vector containing the biggest value across vector a. -static INLINE int16x8_t vec_max_across(int16x8_t a) { - a = vec_max(a, vec_perm(a, a, vec_perm64)); - a = vec_max(a, vec_perm(a, a, vec_perm32)); - return vec_max(a, vec_perm(a, a, vec_perm16)); -} - -void vpx_quantize_b_vsx(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const int16_t *zbin_ptr, const int16_t *round_ptr, - const int16_t *quant_ptr, - const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, - uint16_t *eob_ptr, const int16_t *scan_ptr, - const int16_t *iscan_ptr) { - int16x8_t qcoeff0, qcoeff1, dqcoeff0, dqcoeff1, eob; - bool16x8_t zero_mask0, zero_mask1; - - // First set of 8 coeff starts with DC + 7 AC - int16x8_t zbin = vec_vsx_ld(0, zbin_ptr); - int16x8_t round = vec_vsx_ld(0, round_ptr); - int16x8_t quant = vec_vsx_ld(0, quant_ptr); - int16x8_t dequant = vec_vsx_ld(0, dequant_ptr); - int16x8_t quant_shift = vec_vsx_ld(0, quant_shift_ptr); - - int16x8_t coeff0 = vec_vsx_ld(0, coeff_ptr); - int16x8_t coeff1 = vec_vsx_ld(16, coeff_ptr); - - int16x8_t coeff0_abs = vec_abs(coeff0); - int16x8_t coeff1_abs = vec_abs(coeff1); - - zero_mask0 = vec_cmpge(coeff0_abs, zbin); - zbin = vec_splat(zbin, 1); - zero_mask1 = vec_cmpge(coeff1_abs, zbin); - - (void)scan_ptr; - - qcoeff0 = - quantize_coeff(coeff0, coeff0_abs, round, quant, quant_shift, zero_mask0); - vec_vsx_st(qcoeff0, 0, qcoeff_ptr); - round = vec_splat(round, 1); - quant = vec_splat(quant, 1); - quant_shift = vec_splat(quant_shift, 1); - qcoeff1 = - quantize_coeff(coeff1, coeff1_abs, round, quant, quant_shift, zero_mask1); - vec_vsx_st(qcoeff1, 16, qcoeff_ptr); - - dqcoeff0 = vec_mladd(qcoeff0, dequant, vec_zeros_s16); - vec_vsx_st(dqcoeff0, 0, dqcoeff_ptr); - dequant = vec_splat(dequant, 1); - dqcoeff1 = vec_mladd(qcoeff1, dequant, vec_zeros_s16); - vec_vsx_st(dqcoeff1, 16, dqcoeff_ptr); - - eob = vec_max(nonzero_scanindex(qcoeff0, iscan_ptr, 0), - nonzero_scanindex(qcoeff1, iscan_ptr, 16)); - - if (n_coeffs > 16) { - int index = 16; - int off0 = 32; - int off1 = 48; - int off2 = 64; - do { - int16x8_t coeff2, coeff2_abs, qcoeff2, dqcoeff2, eob2; - bool16x8_t zero_mask2; - coeff0 = vec_vsx_ld(off0, coeff_ptr); - coeff1 = vec_vsx_ld(off1, coeff_ptr); - coeff2 = vec_vsx_ld(off2, coeff_ptr); - coeff0_abs = vec_abs(coeff0); - coeff1_abs = vec_abs(coeff1); - coeff2_abs = vec_abs(coeff2); - zero_mask0 = vec_cmpge(coeff0_abs, zbin); - zero_mask1 = vec_cmpge(coeff1_abs, zbin); - zero_mask2 = vec_cmpge(coeff2_abs, zbin); - qcoeff0 = quantize_coeff(coeff0, coeff0_abs, round, quant, quant_shift, - zero_mask0); - qcoeff1 = quantize_coeff(coeff1, coeff1_abs, round, quant, quant_shift, - zero_mask1); - qcoeff2 = quantize_coeff(coeff2, coeff2_abs, round, quant, quant_shift, - zero_mask2); - vec_vsx_st(qcoeff0, off0, qcoeff_ptr); - vec_vsx_st(qcoeff1, off1, qcoeff_ptr); - vec_vsx_st(qcoeff2, off2, qcoeff_ptr); - - dqcoeff0 = vec_mladd(qcoeff0, dequant, vec_zeros_s16); - dqcoeff1 = vec_mladd(qcoeff1, dequant, vec_zeros_s16); - dqcoeff2 = vec_mladd(qcoeff2, dequant, vec_zeros_s16); - - vec_vsx_st(dqcoeff0, off0, dqcoeff_ptr); - vec_vsx_st(dqcoeff1, off1, dqcoeff_ptr); - vec_vsx_st(dqcoeff2, off2, dqcoeff_ptr); - - eob = vec_max(eob, nonzero_scanindex(qcoeff0, iscan_ptr, off0)); - eob2 = vec_max(nonzero_scanindex(qcoeff1, iscan_ptr, off1), - nonzero_scanindex(qcoeff2, iscan_ptr, off2)); - eob = vec_max(eob, eob2); - - index += 24; - off0 += 48; - off1 += 48; - off2 += 48; - } while (index < n_coeffs); - } - - eob = vec_max_across(eob); - *eob_ptr = eob[0]; -} - -void vpx_quantize_b_32x32_vsx(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const int16_t *zbin_ptr, const int16_t *round_ptr, - const int16_t *quant_ptr, - const int16_t *quant_shift_ptr, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const int16_t *scan_ptr, - const int16_t *iscan_ptr) { - // In stage 1, we quantize 16 coeffs (DC + 15 AC) - // In stage 2, we loop 42 times and quantize 24 coeffs per iteration - // (32 * 32 - 16) / 24 = 42 - int num_itr = 42; - // Offsets are in bytes, 16 coeffs = 32 bytes - int off0 = 32; - int off1 = 48; - int off2 = 64; - - int16x8_t qcoeff0, qcoeff1, eob; - bool16x8_t zero_mask0, zero_mask1; - - int16x8_t zbin = vec_vsx_ld(0, zbin_ptr); - int16x8_t round = vec_vsx_ld(0, round_ptr); - int16x8_t quant = vec_vsx_ld(0, quant_ptr); - int16x8_t dequant = vec_vsx_ld(0, dequant_ptr); - int16x8_t quant_shift = vec_vsx_ld(0, quant_shift_ptr); - - int16x8_t coeff0 = vec_vsx_ld(0, coeff_ptr); - int16x8_t coeff1 = vec_vsx_ld(16, coeff_ptr); - - int16x8_t coeff0_abs = vec_abs(coeff0); - int16x8_t coeff1_abs = vec_abs(coeff1); - - (void)scan_ptr; - (void)n_coeffs; - - // 32x32 quantization requires that zbin and round be divided by 2 - zbin = vec_sra(vec_add(zbin, vec_ones_s16), vec_ones_u16); - round = vec_sra(vec_add(round, vec_ones_s16), vec_ones_u16); - - zero_mask0 = vec_cmpge(coeff0_abs, zbin); - zbin = vec_splat(zbin, 1); // remove DC from zbin - zero_mask1 = vec_cmpge(coeff1_abs, zbin); - - qcoeff0 = quantize_coeff_32(coeff0, coeff0_abs, round, quant, quant_shift, - zero_mask0); - round = vec_splat(round, 1); // remove DC from round - quant = vec_splat(quant, 1); // remove DC from quant - quant_shift = vec_splat(quant_shift, 1); // remove DC from quant_shift - qcoeff1 = quantize_coeff_32(coeff1, coeff1_abs, round, quant, quant_shift, - zero_mask1); - - vec_vsx_st(qcoeff0, 0, qcoeff_ptr); - vec_vsx_st(qcoeff1, 16, qcoeff_ptr); - - vec_vsx_st(dequantize_coeff_32(qcoeff0, dequant), 0, dqcoeff_ptr); - dequant = vec_splat(dequant, 1); // remove DC from dequant - vec_vsx_st(dequantize_coeff_32(qcoeff1, dequant), 16, dqcoeff_ptr); - - eob = vec_max(nonzero_scanindex(qcoeff0, iscan_ptr, 0), - nonzero_scanindex(qcoeff1, iscan_ptr, 16)); - - do { - int16x8_t coeff2, coeff2_abs, qcoeff2, eob2; - bool16x8_t zero_mask2; - - coeff0 = vec_vsx_ld(off0, coeff_ptr); - coeff1 = vec_vsx_ld(off1, coeff_ptr); - coeff2 = vec_vsx_ld(off2, coeff_ptr); - - coeff0_abs = vec_abs(coeff0); - coeff1_abs = vec_abs(coeff1); - coeff2_abs = vec_abs(coeff2); - - zero_mask0 = vec_cmpge(coeff0_abs, zbin); - zero_mask1 = vec_cmpge(coeff1_abs, zbin); - zero_mask2 = vec_cmpge(coeff2_abs, zbin); - - qcoeff0 = quantize_coeff_32(coeff0, coeff0_abs, round, quant, quant_shift, - zero_mask0); - qcoeff1 = quantize_coeff_32(coeff1, coeff1_abs, round, quant, quant_shift, - zero_mask1); - qcoeff2 = quantize_coeff_32(coeff2, coeff2_abs, round, quant, quant_shift, - zero_mask2); - - vec_vsx_st(qcoeff0, off0, qcoeff_ptr); - vec_vsx_st(qcoeff1, off1, qcoeff_ptr); - vec_vsx_st(qcoeff2, off2, qcoeff_ptr); - - vec_vsx_st(dequantize_coeff_32(qcoeff0, dequant), off0, dqcoeff_ptr); - vec_vsx_st(dequantize_coeff_32(qcoeff1, dequant), off1, dqcoeff_ptr); - vec_vsx_st(dequantize_coeff_32(qcoeff2, dequant), off2, dqcoeff_ptr); - - eob = vec_max(eob, nonzero_scanindex(qcoeff0, iscan_ptr, off0)); - eob2 = vec_max(nonzero_scanindex(qcoeff1, iscan_ptr, off1), - nonzero_scanindex(qcoeff2, iscan_ptr, off2)); - eob = vec_max(eob, eob2); - - // 24 int16_t is 48 bytes - off0 += 48; - off1 += 48; - off2 += 48; - num_itr--; - } while (num_itr != 0); - - eob = vec_max_across(eob); - *eob_ptr = eob[0]; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/sad_vsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/sad_vsx.c deleted file mode 100644 index a08ae124..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/sad_vsx.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" - -#include "vpx_dsp/ppc/types_vsx.h" - -#include "vpx/vpx_integer.h" -#include "vpx_ports/mem.h" - -#define PROCESS16(offset) \ - v_a = vec_vsx_ld(offset, a); \ - v_b = vec_vsx_ld(offset, b); \ - v_abs = vec_absd(v_a, v_b); \ - v_sad = vec_sum4s(v_abs, v_sad); - -#define SAD8(height) \ - unsigned int vpx_sad8x##height##_vsx(const uint8_t *a, int a_stride, \ - const uint8_t *b, int b_stride) { \ - int y = 0; \ - uint8x16_t v_a, v_b, v_abs; \ - uint32x4_t v_sad = vec_zeros_u32; \ - \ - do { \ - PROCESS16(0) \ - \ - a += a_stride; \ - b += b_stride; \ - y++; \ - } while (y < height); \ - \ - return v_sad[1] + v_sad[0]; \ - } - -#define SAD16(height) \ - unsigned int vpx_sad16x##height##_vsx(const uint8_t *a, int a_stride, \ - const uint8_t *b, int b_stride) { \ - int y = 0; \ - uint8x16_t v_a, v_b, v_abs; \ - uint32x4_t v_sad = vec_zeros_u32; \ - \ - do { \ - PROCESS16(0); \ - \ - a += a_stride; \ - b += b_stride; \ - y++; \ - } while (y < height); \ - \ - return v_sad[3] + v_sad[2] + v_sad[1] + v_sad[0]; \ - } - -#define SAD32(height) \ - unsigned int vpx_sad32x##height##_vsx(const uint8_t *a, int a_stride, \ - const uint8_t *b, int b_stride) { \ - int y = 0; \ - uint8x16_t v_a, v_b, v_abs; \ - uint32x4_t v_sad = vec_zeros_u32; \ - \ - do { \ - PROCESS16(0); \ - PROCESS16(16); \ - \ - a += a_stride; \ - b += b_stride; \ - y++; \ - } while (y < height); \ - \ - return v_sad[3] + v_sad[2] + v_sad[1] + v_sad[0]; \ - } - -#define SAD64(height) \ - unsigned int vpx_sad64x##height##_vsx(const uint8_t *a, int a_stride, \ - const uint8_t *b, int b_stride) { \ - int y = 0; \ - uint8x16_t v_a, v_b, v_abs; \ - uint32x4_t v_sad = vec_zeros_u32; \ - \ - do { \ - PROCESS16(0); \ - PROCESS16(16); \ - PROCESS16(32); \ - PROCESS16(48); \ - \ - a += a_stride; \ - b += b_stride; \ - y++; \ - } while (y < height); \ - \ - return v_sad[3] + v_sad[2] + v_sad[1] + v_sad[0]; \ - } - -SAD8(4); -SAD8(8); -SAD8(16); -SAD16(8); -SAD16(16); -SAD16(32); -SAD32(16); -SAD32(32); -SAD32(64); -SAD64(32); -SAD64(64); - -#define SAD16AVG(height) \ - unsigned int vpx_sad16x##height##_avg_vsx( \ - const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride, \ - const uint8_t *second_pred) { \ - DECLARE_ALIGNED(16, uint8_t, comp_pred[16 * (height)]); \ - vpx_comp_avg_pred_vsx(comp_pred, second_pred, 16, height, ref, \ - ref_stride); \ - \ - return vpx_sad16x##height##_vsx(src, src_stride, comp_pred, 16); \ - } - -#define SAD32AVG(height) \ - unsigned int vpx_sad32x##height##_avg_vsx( \ - const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride, \ - const uint8_t *second_pred) { \ - DECLARE_ALIGNED(32, uint8_t, comp_pred[32 * (height)]); \ - vpx_comp_avg_pred_vsx(comp_pred, second_pred, 32, height, ref, \ - ref_stride); \ - \ - return vpx_sad32x##height##_vsx(src, src_stride, comp_pred, 32); \ - } - -#define SAD64AVG(height) \ - unsigned int vpx_sad64x##height##_avg_vsx( \ - const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride, \ - const uint8_t *second_pred) { \ - DECLARE_ALIGNED(64, uint8_t, comp_pred[64 * (height)]); \ - vpx_comp_avg_pred_vsx(comp_pred, second_pred, 64, height, ref, \ - ref_stride); \ - return vpx_sad64x##height##_vsx(src, src_stride, comp_pred, 64); \ - } - -SAD16AVG(8); -SAD16AVG(16); -SAD16AVG(32); -SAD32AVG(16); -SAD32AVG(32); -SAD32AVG(64); -SAD64AVG(32); -SAD64AVG(64); - -#define PROCESS16_4D(offset, ref, v_h, v_l) \ - v_b = vec_vsx_ld(offset, ref); \ - v_bh = unpack_to_s16_h(v_b); \ - v_bl = unpack_to_s16_l(v_b); \ - v_subh = vec_sub(v_h, v_bh); \ - v_subl = vec_sub(v_l, v_bl); \ - v_absh = vec_abs(v_subh); \ - v_absl = vec_abs(v_subl); \ - v_sad = vec_sum4s(v_absh, v_sad); \ - v_sad = vec_sum4s(v_absl, v_sad); - -#define UNPACK_SRC(offset, srcv_h, srcv_l) \ - v_a = vec_vsx_ld(offset, src); \ - srcv_h = unpack_to_s16_h(v_a); \ - srcv_l = unpack_to_s16_l(v_a); - -#define SAD16_4D(height) \ - void vpx_sad16x##height##x4d_vsx(const uint8_t *src, int src_stride, \ - const uint8_t *const ref_array[], \ - int ref_stride, uint32_t *sad_array) { \ - int i; \ - int y; \ - unsigned int sad[4]; \ - uint8x16_t v_a, v_b; \ - int16x8_t v_ah, v_al, v_bh, v_bl, v_absh, v_absl, v_subh, v_subl; \ - \ - for (i = 0; i < 4; i++) sad_array[i] = 0; \ - \ - for (y = 0; y < height; y++) { \ - UNPACK_SRC(y *src_stride, v_ah, v_al); \ - for (i = 0; i < 4; i++) { \ - int32x4_t v_sad = vec_splat_s32(0); \ - PROCESS16_4D(y *ref_stride, ref_array[i], v_ah, v_al); \ - \ - vec_vsx_st((uint32x4_t)v_sad, 0, sad); \ - sad_array[i] += (sad[3] + sad[2] + sad[1] + sad[0]); \ - } \ - } \ - } - -#define SAD32_4D(height) \ - void vpx_sad32x##height##x4d_vsx(const uint8_t *src, int src_stride, \ - const uint8_t *const ref_array[], \ - int ref_stride, uint32_t *sad_array) { \ - int i; \ - int y; \ - unsigned int sad[4]; \ - uint8x16_t v_a, v_b; \ - int16x8_t v_ah1, v_al1, v_ah2, v_al2, v_bh, v_bl; \ - int16x8_t v_absh, v_absl, v_subh, v_subl; \ - \ - for (i = 0; i < 4; i++) sad_array[i] = 0; \ - \ - for (y = 0; y < height; y++) { \ - UNPACK_SRC(y *src_stride, v_ah1, v_al1); \ - UNPACK_SRC(y *src_stride + 16, v_ah2, v_al2); \ - for (i = 0; i < 4; i++) { \ - int32x4_t v_sad = vec_splat_s32(0); \ - PROCESS16_4D(y *ref_stride, ref_array[i], v_ah1, v_al1); \ - PROCESS16_4D(y *ref_stride + 16, ref_array[i], v_ah2, v_al2); \ - \ - vec_vsx_st((uint32x4_t)v_sad, 0, sad); \ - sad_array[i] += (sad[3] + sad[2] + sad[1] + sad[0]); \ - } \ - } \ - } - -#define SAD64_4D(height) \ - void vpx_sad64x##height##x4d_vsx(const uint8_t *src, int src_stride, \ - const uint8_t *const ref_array[], \ - int ref_stride, uint32_t *sad_array) { \ - int i; \ - int y; \ - unsigned int sad[4]; \ - uint8x16_t v_a, v_b; \ - int16x8_t v_ah1, v_al1, v_ah2, v_al2, v_bh, v_bl; \ - int16x8_t v_ah3, v_al3, v_ah4, v_al4; \ - int16x8_t v_absh, v_absl, v_subh, v_subl; \ - \ - for (i = 0; i < 4; i++) sad_array[i] = 0; \ - \ - for (y = 0; y < height; y++) { \ - UNPACK_SRC(y *src_stride, v_ah1, v_al1); \ - UNPACK_SRC(y *src_stride + 16, v_ah2, v_al2); \ - UNPACK_SRC(y *src_stride + 32, v_ah3, v_al3); \ - UNPACK_SRC(y *src_stride + 48, v_ah4, v_al4); \ - for (i = 0; i < 4; i++) { \ - int32x4_t v_sad = vec_splat_s32(0); \ - PROCESS16_4D(y *ref_stride, ref_array[i], v_ah1, v_al1); \ - PROCESS16_4D(y *ref_stride + 16, ref_array[i], v_ah2, v_al2); \ - PROCESS16_4D(y *ref_stride + 32, ref_array[i], v_ah3, v_al3); \ - PROCESS16_4D(y *ref_stride + 48, ref_array[i], v_ah4, v_al4); \ - \ - vec_vsx_st((uint32x4_t)v_sad, 0, sad); \ - sad_array[i] += (sad[3] + sad[2] + sad[1] + sad[0]); \ - } \ - } \ - } - -SAD16_4D(8); -SAD16_4D(16); -SAD16_4D(32); -SAD32_4D(16); -SAD32_4D(32); -SAD32_4D(64); -SAD64_4D(32); -SAD64_4D(64); diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/subtract_vsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/subtract_vsx.c deleted file mode 100644 index 76ad302d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/subtract_vsx.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/ppc/types_vsx.h" - -static VPX_FORCE_INLINE void subtract_block4x4( - int16_t *diff, ptrdiff_t diff_stride, const uint8_t *src, - ptrdiff_t src_stride, const uint8_t *pred, ptrdiff_t pred_stride) { - int16_t *diff1 = diff + 2 * diff_stride; - const uint8_t *src1 = src + 2 * src_stride; - const uint8_t *pred1 = pred + 2 * pred_stride; - - const int16x8_t d0 = vec_vsx_ld(0, diff); - const int16x8_t d1 = vec_vsx_ld(0, diff + diff_stride); - const int16x8_t d2 = vec_vsx_ld(0, diff1); - const int16x8_t d3 = vec_vsx_ld(0, diff1 + diff_stride); - - const uint8x16_t s0 = read4x2(src, (int)src_stride); - const uint8x16_t p0 = read4x2(pred, (int)pred_stride); - const uint8x16_t s1 = read4x2(src1, (int)src_stride); - const uint8x16_t p1 = read4x2(pred1, (int)pred_stride); - - const int16x8_t da = vec_sub(unpack_to_s16_h(s0), unpack_to_s16_h(p0)); - const int16x8_t db = vec_sub(unpack_to_s16_h(s1), unpack_to_s16_h(p1)); - - vec_vsx_st(xxpermdi(da, d0, 1), 0, diff); - vec_vsx_st(xxpermdi(da, d1, 3), 0, diff + diff_stride); - vec_vsx_st(xxpermdi(db, d2, 1), 0, diff1); - vec_vsx_st(xxpermdi(db, d3, 3), 0, diff1 + diff_stride); -} - -void vpx_subtract_block_vsx(int rows, int cols, int16_t *diff, - ptrdiff_t diff_stride, const uint8_t *src, - ptrdiff_t src_stride, const uint8_t *pred, - ptrdiff_t pred_stride) { - int r = rows, c; - - switch (cols) { - case 64: - case 32: - do { - for (c = 0; c < cols; c += 32) { - const uint8x16_t s0 = vec_vsx_ld(0, src + c); - const uint8x16_t s1 = vec_vsx_ld(16, src + c); - const uint8x16_t p0 = vec_vsx_ld(0, pred + c); - const uint8x16_t p1 = vec_vsx_ld(16, pred + c); - const int16x8_t d0l = - vec_sub(unpack_to_s16_l(s0), unpack_to_s16_l(p0)); - const int16x8_t d0h = - vec_sub(unpack_to_s16_h(s0), unpack_to_s16_h(p0)); - const int16x8_t d1l = - vec_sub(unpack_to_s16_l(s1), unpack_to_s16_l(p1)); - const int16x8_t d1h = - vec_sub(unpack_to_s16_h(s1), unpack_to_s16_h(p1)); - vec_vsx_st(d0h, 0, diff + c); - vec_vsx_st(d0l, 16, diff + c); - vec_vsx_st(d1h, 0, diff + c + 16); - vec_vsx_st(d1l, 16, diff + c + 16); - } - diff += diff_stride; - pred += pred_stride; - src += src_stride; - } while (--r); - break; - case 16: - do { - const uint8x16_t s0 = vec_vsx_ld(0, src); - const uint8x16_t p0 = vec_vsx_ld(0, pred); - const int16x8_t d0l = vec_sub(unpack_to_s16_l(s0), unpack_to_s16_l(p0)); - const int16x8_t d0h = vec_sub(unpack_to_s16_h(s0), unpack_to_s16_h(p0)); - vec_vsx_st(d0h, 0, diff); - vec_vsx_st(d0l, 16, diff); - diff += diff_stride; - pred += pred_stride; - src += src_stride; - } while (--r); - break; - case 8: - do { - const uint8x16_t s0 = vec_vsx_ld(0, src); - const uint8x16_t p0 = vec_vsx_ld(0, pred); - const int16x8_t d0h = vec_sub(unpack_to_s16_h(s0), unpack_to_s16_h(p0)); - vec_vsx_st(d0h, 0, diff); - diff += diff_stride; - pred += pred_stride; - src += src_stride; - } while (--r); - break; - case 4: - subtract_block4x4(diff, diff_stride, src, src_stride, pred, pred_stride); - if (r > 4) { - diff += 4 * diff_stride; - pred += 4 * pred_stride; - src += 4 * src_stride; - - subtract_block4x4(diff, diff_stride, - - src, src_stride, - - pred, pred_stride); - } - break; - default: assert(0); // unreachable - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/transpose_vsx.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/transpose_vsx.h deleted file mode 100644 index 4883b734..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/transpose_vsx.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_PPC_TRANSPOSE_VSX_H_ -#define VPX_VPX_DSP_PPC_TRANSPOSE_VSX_H_ - -#include "./vpx_config.h" -#include "vpx_dsp/ppc/types_vsx.h" - -static INLINE void vpx_transpose_s16_8x8(int16x8_t v[8]) { - // d = vec_mergeh(a,b): - // The even elements of the result are obtained left-to-right, - // from the high elements of a. - // The odd elements of the result are obtained left-to-right, - // from the high elements of b. - // - // d = vec_mergel(a,b): - // The even elements of the result are obtained left-to-right, - // from the low elements of a. - // The odd elements of the result are obtained left-to-right, - // from the low elements of b. - - // Example, starting with: - // v[0]: 00 01 02 03 04 05 06 07 - // v[1]: 10 11 12 13 14 15 16 17 - // v[2]: 20 21 22 23 24 25 26 27 - // v[3]: 30 31 32 33 34 35 36 37 - // v[4]: 40 41 42 43 44 45 46 47 - // v[5]: 50 51 52 53 54 55 56 57 - // v[6]: 60 61 62 63 64 65 66 67 - // v[7]: 70 71 72 73 74 75 76 77 - - int16x8_t b0, b1, b2, b3, b4, b5, b6, b7; - int16x8_t c0, c1, c2, c3, c4, c5, c6, c7; - - b0 = vec_mergeh(v[0], v[4]); - b1 = vec_mergel(v[0], v[4]); - b2 = vec_mergeh(v[1], v[5]); - b3 = vec_mergel(v[1], v[5]); - b4 = vec_mergeh(v[2], v[6]); - b5 = vec_mergel(v[2], v[6]); - b6 = vec_mergeh(v[3], v[7]); - b7 = vec_mergel(v[3], v[7]); - - // After first merge operation - // b0: 00 40 01 41 02 42 03 43 - // b1: 04 44 05 45 06 46 07 47 - // b2: 10 50 11 51 12 52 13 53 - // b3: 14 54 15 55 16 56 17 57 - // b4: 20 60 21 61 22 62 23 63 - // b5: 24 64 25 65 26 66 27 67 - // b6: 30 70 31 71 32 62 33 73 - // b7: 34 74 35 75 36 76 37 77 - - c0 = vec_mergeh(b0, b4); - c1 = vec_mergel(b0, b4); - c2 = vec_mergeh(b1, b5); - c3 = vec_mergel(b1, b5); - c4 = vec_mergeh(b2, b6); - c5 = vec_mergel(b2, b6); - c6 = vec_mergeh(b3, b7); - c7 = vec_mergel(b3, b7); - - // After second merge operation - // c0: 00 20 40 60 01 21 41 61 - // c1: 02 22 42 62 03 23 43 63 - // c2: 04 24 44 64 05 25 45 65 - // c3: 06 26 46 66 07 27 47 67 - // c4: 10 30 50 70 11 31 51 71 - // c5: 12 32 52 72 13 33 53 73 - // c6: 14 34 54 74 15 35 55 75 - // c7: 16 36 56 76 17 37 57 77 - - v[0] = vec_mergeh(c0, c4); - v[1] = vec_mergel(c0, c4); - v[2] = vec_mergeh(c1, c5); - v[3] = vec_mergel(c1, c5); - v[4] = vec_mergeh(c2, c6); - v[5] = vec_mergel(c2, c6); - v[6] = vec_mergeh(c3, c7); - v[7] = vec_mergel(c3, c7); - - // After last merge operation - // v[0]: 00 10 20 30 40 50 60 70 - // v[1]: 01 11 21 31 41 51 61 71 - // v[2]: 02 12 22 32 42 52 62 72 - // v[3]: 03 13 23 33 43 53 63 73 - // v[4]: 04 14 24 34 44 54 64 74 - // v[5]: 05 15 25 35 45 55 65 75 - // v[6]: 06 16 26 36 46 56 66 76 - // v[7]: 07 17 27 37 47 57 67 77 -} - -static INLINE void transpose_8x8(const int16x8_t *a, int16x8_t *b) { - // Stage 1 - const int16x8_t s1_0 = vec_mergeh(a[0], a[4]); - const int16x8_t s1_1 = vec_mergel(a[0], a[4]); - const int16x8_t s1_2 = vec_mergeh(a[1], a[5]); - const int16x8_t s1_3 = vec_mergel(a[1], a[5]); - const int16x8_t s1_4 = vec_mergeh(a[2], a[6]); - const int16x8_t s1_5 = vec_mergel(a[2], a[6]); - const int16x8_t s1_6 = vec_mergeh(a[3], a[7]); - const int16x8_t s1_7 = vec_mergel(a[3], a[7]); - - // Stage 2 - const int16x8_t s2_0 = vec_mergeh(s1_0, s1_4); - const int16x8_t s2_1 = vec_mergel(s1_0, s1_4); - const int16x8_t s2_2 = vec_mergeh(s1_1, s1_5); - const int16x8_t s2_3 = vec_mergel(s1_1, s1_5); - const int16x8_t s2_4 = vec_mergeh(s1_2, s1_6); - const int16x8_t s2_5 = vec_mergel(s1_2, s1_6); - const int16x8_t s2_6 = vec_mergeh(s1_3, s1_7); - const int16x8_t s2_7 = vec_mergel(s1_3, s1_7); - - // Stage 2 - b[0] = vec_mergeh(s2_0, s2_4); - b[1] = vec_mergel(s2_0, s2_4); - b[2] = vec_mergeh(s2_1, s2_5); - b[3] = vec_mergel(s2_1, s2_5); - b[4] = vec_mergeh(s2_2, s2_6); - b[5] = vec_mergel(s2_2, s2_6); - b[6] = vec_mergeh(s2_3, s2_7); - b[7] = vec_mergel(s2_3, s2_7); -} - -#endif // VPX_VPX_DSP_PPC_TRANSPOSE_VSX_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/txfm_common_vsx.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/txfm_common_vsx.h deleted file mode 100644 index 2907a1fe..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/txfm_common_vsx.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_PPC_TXFM_COMMON_VSX_H_ -#define VPX_VPX_DSP_PPC_TXFM_COMMON_VSX_H_ - -#include "vpx_dsp/ppc/types_vsx.h" - -static const int32x4_t vec_dct_const_rounding = { 8192, 8192, 8192, 8192 }; - -static const uint32x4_t vec_dct_const_bits = { 14, 14, 14, 14 }; - -static const uint16x8_t vec_dct_scale_log2 = { 2, 2, 2, 2, 2, 2, 2, 2 }; - -static const int16x8_t cospi1_v = { 16364, 16364, 16364, 16364, - 16364, 16364, 16364, 16364 }; -static const int16x8_t cospi2_v = { 16305, 16305, 16305, 16305, - 16305, 16305, 16305, 16305 }; -static const int16x8_t cospi3_v = { 16207, 16207, 16207, 16207, - 16207, 16207, 16207, 16207 }; -static const int16x8_t cospi4_v = { 16069, 16069, 16069, 16069, - 16069, 16069, 16069, 16069 }; -static const int16x8_t cospi4m_v = { -16069, -16069, -16069, -16069, - -16069, -16069, -16069, -16069 }; -static const int16x8_t cospi5_v = { 15893, 15893, 15893, 15893, - 15893, 15893, 15893, 15893 }; -static const int16x8_t cospi6_v = { 15679, 15679, 15679, 15679, - 15679, 15679, 15679, 15679 }; -static const int16x8_t cospi7_v = { 15426, 15426, 15426, 15426, - 15426, 15426, 15426, 15426 }; -static const int16x8_t cospi8_v = { 15137, 15137, 15137, 15137, - 15137, 15137, 15137, 15137 }; -static const int16x8_t cospi8m_v = { -15137, -15137, -15137, -15137, - -15137, -15137, -15137, -15137 }; -static const int16x8_t cospi9_v = { 14811, 14811, 14811, 14811, - 14811, 14811, 14811, 14811 }; -static const int16x8_t cospi10_v = { 14449, 14449, 14449, 14449, - 14449, 14449, 14449, 14449 }; -static const int16x8_t cospi11_v = { 14053, 14053, 14053, 14053, - 14053, 14053, 14053, 14053 }; -static const int16x8_t cospi12_v = { 13623, 13623, 13623, 13623, - 13623, 13623, 13623, 13623 }; -static const int16x8_t cospi13_v = { 13160, 13160, 13160, 13160, - 13160, 13160, 13160, 13160 }; -static const int16x8_t cospi14_v = { 12665, 12665, 12665, 12665, - 12665, 12665, 12665, 12665 }; -static const int16x8_t cospi15_v = { 12140, 12140, 12140, 12140, - 12140, 12140, 12140, 12140 }; -static const int16x8_t cospi16_v = { 11585, 11585, 11585, 11585, - 11585, 11585, 11585, 11585 }; -static const int16x8_t cospi17_v = { 11003, 11003, 11003, 11003, - 11003, 11003, 11003, 11003 }; -static const int16x8_t cospi18_v = { 10394, 10394, 10394, 10394, - 10394, 10394, 10394, 10394 }; -static const int16x8_t cospi19_v = { 9760, 9760, 9760, 9760, - 9760, 9760, 9760, 9760 }; -static const int16x8_t cospi20_v = { 9102, 9102, 9102, 9102, - 9102, 9102, 9102, 9102 }; -static const int16x8_t cospi20m_v = { -9102, -9102, -9102, -9102, - -9102, -9102, -9102, -9102 }; -static const int16x8_t cospi21_v = { 8423, 8423, 8423, 8423, - 8423, 8423, 8423, 8423 }; -static const int16x8_t cospi22_v = { 7723, 7723, 7723, 7723, - 7723, 7723, 7723, 7723 }; -static const int16x8_t cospi23_v = { 7005, 7005, 7005, 7005, - 7005, 7005, 7005, 7005 }; -static const int16x8_t cospi24_v = { 6270, 6270, 6270, 6270, - 6270, 6270, 6270, 6270 }; -static const int16x8_t cospi25_v = { 5520, 5520, 5520, 5520, - 5520, 5520, 5520, 5520 }; -static const int16x8_t cospi26_v = { 4756, 4756, 4756, 4756, - 4756, 4756, 4756, 4756 }; -static const int16x8_t cospi27_v = { 3981, 3981, 3981, 3981, - 3981, 3981, 3981, 3981 }; -static const int16x8_t cospi28_v = { 3196, 3196, 3196, 3196, - 3196, 3196, 3196, 3196 }; -static const int16x8_t cospi29_v = { 2404, 2404, 2404, 2404, - 2404, 2404, 2404, 2404 }; -static const int16x8_t cospi30_v = { 1606, 1606, 1606, 1606, - 1606, 1606, 1606, 1606 }; -static const int16x8_t cospi31_v = { 804, 804, 804, 804, 804, 804, 804, 804 }; - -#endif // VPX_VPX_DSP_PPC_TXFM_COMMON_VSX_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/types_vsx.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/types_vsx.h deleted file mode 100644 index b8911692..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/types_vsx.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_PPC_TYPES_VSX_H_ -#define VPX_VPX_DSP_PPC_TYPES_VSX_H_ - -#include - -typedef vector signed char int8x16_t; -typedef vector unsigned char uint8x16_t; -typedef vector signed short int16x8_t; -typedef vector unsigned short uint16x8_t; -typedef vector signed int int32x4_t; -typedef vector unsigned int uint32x4_t; -typedef vector bool char bool8x16_t; -typedef vector bool short bool16x8_t; -typedef vector bool int bool32x4_t; - -#if defined(__clang__) && __clang_major__ < 6 -static const uint8x16_t xxpermdi0_perm = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17 }; -static const uint8x16_t xxpermdi1_perm = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x18, 0x19, 0x1A, 0x1B, - 0x1C, 0x1D, 0x1E, 0x1F }; -static const uint8x16_t xxpermdi2_perm = { 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17 }; -static const uint8x16_t xxpermdi3_perm = { 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x18, 0x19, 0x1A, 0x1B, - 0x1C, 0x1D, 0x1E, 0x1F }; -#define xxpermdi(a, b, c) vec_perm(a, b, xxpermdi##c##_perm) -#elif defined(__GNUC__) && \ - (__GNUC__ > 6 || (__GNUC__ == 6 && __GNUC_MINOR__ >= 3)) -#define xxpermdi(a, b, c) vec_xxpermdi(a, b, c) -#endif - -#ifdef WORDS_BIGENDIAN -#define unpack_to_u16_h(v) \ - (uint16x8_t) vec_mergeh(vec_splat_u8(0), (uint8x16_t)v) -#define unpack_to_u16_l(v) \ - (uint16x8_t) vec_mergel(vec_splat_u8(0), (uint8x16_t)v) -#define unpack_to_s16_h(v) \ - (int16x8_t) vec_mergeh(vec_splat_u8(0), (uint8x16_t)v) -#define unpack_to_s16_l(v) \ - (int16x8_t) vec_mergel(vec_splat_u8(0), (uint8x16_t)v) -#ifndef xxpermdi -#define xxpermdi(a, b, c) vec_xxpermdi(a, b, c) -#endif -#else -#define unpack_to_u16_h(v) \ - (uint16x8_t) vec_mergeh((uint8x16_t)v, vec_splat_u8(0)) -#define unpack_to_u16_l(v) \ - (uint16x8_t) vec_mergel((uint8x16_t)v, vec_splat_u8(0)) -#define unpack_to_s16_h(v) \ - (int16x8_t) vec_mergeh((uint8x16_t)v, vec_splat_u8(0)) -#define unpack_to_s16_l(v) \ - (int16x8_t) vec_mergel((uint8x16_t)v, vec_splat_u8(0)) -#ifndef xxpermdi -#define xxpermdi(a, b, c) vec_xxpermdi(b, a, (((c) >> 1) | ((c)&1) << 1) ^ 3) -#endif -#endif - -static INLINE uint8x16_t read4x2(const uint8_t *a, int stride) { - const uint32x4_t a0 = (uint32x4_t)vec_vsx_ld(0, a); - const uint32x4_t a1 = (uint32x4_t)vec_vsx_ld(0, a + stride); - - return (uint8x16_t)vec_mergeh(a0, a1); -} - -#ifndef __POWER9_VECTOR__ -#define vec_absd(a, b) vec_sub(vec_max(a, b), vec_min(a, b)) -#endif - -static const uint8x16_t vec_zeros_u8 = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 }; -static const int16x8_t vec_zeros_s16 = { 0, 0, 0, 0, 0, 0, 0, 0 }; -static const int16x8_t vec_ones_s16 = { 1, 1, 1, 1, 1, 1, 1, 1 }; -static const int16x8_t vec_twos_s16 = { 2, 2, 2, 2, 2, 2, 2, 2 }; -static const uint16x8_t vec_ones_u16 = { 1, 1, 1, 1, 1, 1, 1, 1 }; -static const uint32x4_t vec_ones_u32 = { 1, 1, 1, 1 }; -static const int32x4_t vec_zeros_s32 = { 0, 0, 0, 0 }; -static const uint32x4_t vec_zeros_u32 = { 0, 0, 0, 0 }; -static const uint16x8_t vec_shift_sign_s16 = { 15, 15, 15, 15, 15, 15, 15, 15 }; -static const uint32x4_t vec_shift_sign_s32 = { 31, 31, 31, 31 }; -static const uint8x16_t vec_perm64 = { 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07 }; -static const uint8x16_t vec_perm32 = { 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x00, 0x01, 0x02, 0x03 }; -static const uint8x16_t vec_perm16 = { 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0E, 0x0D, - 0x0E, 0x0F, 0x00, 0x01 }; - -static const uint8x16_t vec_perm_odd_even_pack = { 0x00, 0x01, 0x10, 0x11, - 0x04, 0x05, 0x14, 0x15, - 0x08, 0x09, 0x18, 0x19, - 0x0C, 0x0D, 0x1C, 0x1D }; - -#endif // VPX_VPX_DSP_PPC_TYPES_VSX_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/variance_vsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/variance_vsx.c deleted file mode 100644 index 6c6bc9a3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/variance_vsx.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/ppc/types_vsx.h" - -uint32_t vpx_get4x4sse_cs_vsx(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride) { - int distortion; - - const int16x8_t a0 = unpack_to_s16_h(read4x2(src_ptr, src_stride)); - const int16x8_t a1 = - unpack_to_s16_h(read4x2(src_ptr + src_stride * 2, src_stride)); - const int16x8_t b0 = unpack_to_s16_h(read4x2(ref_ptr, ref_stride)); - const int16x8_t b1 = - unpack_to_s16_h(read4x2(ref_ptr + ref_stride * 2, ref_stride)); - const int16x8_t d0 = vec_sub(a0, b0); - const int16x8_t d1 = vec_sub(a1, b1); - const int32x4_t ds = vec_msum(d1, d1, vec_msum(d0, d0, vec_splat_s32(0))); - const int32x4_t d = vec_splat(vec_sums(ds, vec_splat_s32(0)), 3); - - vec_ste(d, 0, &distortion); - - return distortion; -} - -// TODO(lu_zero): Unroll -uint32_t vpx_get_mb_ss_vsx(const int16_t *src_ptr) { - unsigned int i, sum = 0; - int32x4_t s = vec_splat_s32(0); - - for (i = 0; i < 256; i += 8) { - const int16x8_t v = vec_vsx_ld(0, src_ptr + i); - s = vec_msum(v, v, s); - } - - s = vec_splat(vec_sums(s, vec_splat_s32(0)), 3); - - vec_ste((uint32x4_t)s, 0, &sum); - - return sum; -} - -void vpx_comp_avg_pred_vsx(uint8_t *comp_pred, const uint8_t *pred, int width, - int height, const uint8_t *ref, int ref_stride) { - int i, j; - /* comp_pred and pred must be 16 byte aligned. */ - assert(((intptr_t)comp_pred & 0xf) == 0); - assert(((intptr_t)pred & 0xf) == 0); - if (width >= 16) { - for (i = 0; i < height; ++i) { - for (j = 0; j < width; j += 16) { - const uint8x16_t v = vec_avg(vec_vsx_ld(j, pred), vec_vsx_ld(j, ref)); - vec_vsx_st(v, j, comp_pred); - } - comp_pred += width; - pred += width; - ref += ref_stride; - } - } else if (width == 8) { - // Process 2 lines at time - for (i = 0; i < height / 2; ++i) { - const uint8x16_t r0 = vec_vsx_ld(0, ref); - const uint8x16_t r1 = vec_vsx_ld(0, ref + ref_stride); - const uint8x16_t r = xxpermdi(r0, r1, 0); - const uint8x16_t v = vec_avg(vec_vsx_ld(0, pred), r); - vec_vsx_st(v, 0, comp_pred); - comp_pred += 16; // width * 2; - pred += 16; // width * 2; - ref += ref_stride * 2; - } - } else { - assert(width == 4); - // process 4 lines at time - for (i = 0; i < height / 4; ++i) { - const uint32x4_t r0 = (uint32x4_t)vec_vsx_ld(0, ref); - const uint32x4_t r1 = (uint32x4_t)vec_vsx_ld(0, ref + ref_stride); - const uint32x4_t r2 = (uint32x4_t)vec_vsx_ld(0, ref + ref_stride * 2); - const uint32x4_t r3 = (uint32x4_t)vec_vsx_ld(0, ref + ref_stride * 3); - const uint8x16_t r = - (uint8x16_t)xxpermdi(vec_mergeh(r0, r1), vec_mergeh(r2, r3), 0); - const uint8x16_t v = vec_avg(vec_vsx_ld(0, pred), r); - vec_vsx_st(v, 0, comp_pred); - comp_pred += 16; // width * 4; - pred += 16; // width * 4; - ref += ref_stride * 4; - } - } -} - -static INLINE void variance_inner_32(const uint8_t *src_ptr, - const uint8_t *ref_ptr, - int32x4_t *sum_squared, int32x4_t *sum) { - int32x4_t s = *sum; - int32x4_t ss = *sum_squared; - - const uint8x16_t va0 = vec_vsx_ld(0, src_ptr); - const uint8x16_t vb0 = vec_vsx_ld(0, ref_ptr); - const uint8x16_t va1 = vec_vsx_ld(16, src_ptr); - const uint8x16_t vb1 = vec_vsx_ld(16, ref_ptr); - - const int16x8_t a0 = unpack_to_s16_h(va0); - const int16x8_t b0 = unpack_to_s16_h(vb0); - const int16x8_t a1 = unpack_to_s16_l(va0); - const int16x8_t b1 = unpack_to_s16_l(vb0); - const int16x8_t a2 = unpack_to_s16_h(va1); - const int16x8_t b2 = unpack_to_s16_h(vb1); - const int16x8_t a3 = unpack_to_s16_l(va1); - const int16x8_t b3 = unpack_to_s16_l(vb1); - const int16x8_t d0 = vec_sub(a0, b0); - const int16x8_t d1 = vec_sub(a1, b1); - const int16x8_t d2 = vec_sub(a2, b2); - const int16x8_t d3 = vec_sub(a3, b3); - - s = vec_sum4s(d0, s); - ss = vec_msum(d0, d0, ss); - s = vec_sum4s(d1, s); - ss = vec_msum(d1, d1, ss); - s = vec_sum4s(d2, s); - ss = vec_msum(d2, d2, ss); - s = vec_sum4s(d3, s); - ss = vec_msum(d3, d3, ss); - *sum = s; - *sum_squared = ss; -} - -static INLINE void variance(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, int w, - int h, uint32_t *sse, int *sum) { - int i; - - int32x4_t s = vec_splat_s32(0); - int32x4_t ss = vec_splat_s32(0); - - switch (w) { - case 4: - for (i = 0; i < h / 2; ++i) { - const int16x8_t a0 = unpack_to_s16_h(read4x2(src_ptr, src_stride)); - const int16x8_t b0 = unpack_to_s16_h(read4x2(ref_ptr, ref_stride)); - const int16x8_t d = vec_sub(a0, b0); - s = vec_sum4s(d, s); - ss = vec_msum(d, d, ss); - src_ptr += src_stride * 2; - ref_ptr += ref_stride * 2; - } - break; - case 8: - for (i = 0; i < h; ++i) { - const int16x8_t a0 = unpack_to_s16_h(vec_vsx_ld(0, src_ptr)); - const int16x8_t b0 = unpack_to_s16_h(vec_vsx_ld(0, ref_ptr)); - const int16x8_t d = vec_sub(a0, b0); - - s = vec_sum4s(d, s); - ss = vec_msum(d, d, ss); - src_ptr += src_stride; - ref_ptr += ref_stride; - } - break; - case 16: - for (i = 0; i < h; ++i) { - const uint8x16_t va = vec_vsx_ld(0, src_ptr); - const uint8x16_t vb = vec_vsx_ld(0, ref_ptr); - const int16x8_t a0 = unpack_to_s16_h(va); - const int16x8_t b0 = unpack_to_s16_h(vb); - const int16x8_t a1 = unpack_to_s16_l(va); - const int16x8_t b1 = unpack_to_s16_l(vb); - const int16x8_t d0 = vec_sub(a0, b0); - const int16x8_t d1 = vec_sub(a1, b1); - - s = vec_sum4s(d0, s); - ss = vec_msum(d0, d0, ss); - s = vec_sum4s(d1, s); - ss = vec_msum(d1, d1, ss); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } - break; - case 32: - for (i = 0; i < h; ++i) { - variance_inner_32(src_ptr, ref_ptr, &ss, &s); - src_ptr += src_stride; - ref_ptr += ref_stride; - } - break; - case 64: - for (i = 0; i < h; ++i) { - variance_inner_32(src_ptr, ref_ptr, &ss, &s); - variance_inner_32(src_ptr + 32, ref_ptr + 32, &ss, &s); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } - break; - } - - s = vec_splat(vec_sums(s, vec_splat_s32(0)), 3); - - vec_ste(s, 0, sum); - - ss = vec_splat(vec_sums(ss, vec_splat_s32(0)), 3); - - vec_ste((uint32x4_t)ss, 0, sse); -} - -/* Identical to the variance call except it takes an additional parameter, sum, - * and returns that value using pass-by-reference instead of returning - * sse - sum^2 / w*h - */ -#define GET_VAR(W, H) \ - void vpx_get##W##x##H##var_vsx(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *ref_ptr, int ref_stride, \ - uint32_t *sse, int *sum) { \ - variance(src_ptr, src_stride, ref_ptr, ref_stride, W, H, sse, sum); \ - } - -/* Identical to the variance call except it does not calculate the - * sse - sum^2 / w*h and returns sse in addition to modifying the passed in - * variable. - */ -#define MSE(W, H) \ - uint32_t vpx_mse##W##x##H##_vsx(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *ref_ptr, int ref_stride, \ - uint32_t *sse) { \ - int sum; \ - variance(src_ptr, src_stride, ref_ptr, ref_stride, W, H, sse, &sum); \ - return *sse; \ - } - -#define VAR(W, H) \ - uint32_t vpx_variance##W##x##H##_vsx(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *ref_ptr, int ref_stride, \ - uint32_t *sse) { \ - int sum; \ - variance(src_ptr, src_stride, ref_ptr, ref_stride, W, H, sse, &sum); \ - return *sse - (uint32_t)(((int64_t)sum * sum) / ((W) * (H))); \ - } - -#define VARIANCES(W, H) VAR(W, H) - -VARIANCES(64, 64) -VARIANCES(64, 32) -VARIANCES(32, 64) -VARIANCES(32, 32) -VARIANCES(32, 16) -VARIANCES(16, 32) -VARIANCES(16, 16) -VARIANCES(16, 8) -VARIANCES(8, 16) -VARIANCES(8, 8) -VARIANCES(8, 4) -VARIANCES(4, 8) -VARIANCES(4, 4) - -GET_VAR(16, 16) -GET_VAR(8, 8) - -MSE(16, 16) -MSE(16, 8) -MSE(8, 16) -MSE(8, 8) diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/vpx_convolve_vsx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/vpx_convolve_vsx.c deleted file mode 100644 index 2dc66055..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ppc/vpx_convolve_vsx.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/ppc/types_vsx.h" -#include "vpx_dsp/vpx_filter.h" - -// TODO(lu_zero): unroll -static VPX_FORCE_INLINE void copy_w16(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - int32_t h) { - int i; - - for (i = h; i--;) { - vec_vsx_st(vec_vsx_ld(0, src), 0, dst); - src += src_stride; - dst += dst_stride; - } -} - -static VPX_FORCE_INLINE void copy_w32(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - int32_t h) { - int i; - - for (i = h; i--;) { - vec_vsx_st(vec_vsx_ld(0, src), 0, dst); - vec_vsx_st(vec_vsx_ld(16, src), 16, dst); - src += src_stride; - dst += dst_stride; - } -} - -static VPX_FORCE_INLINE void copy_w64(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - int32_t h) { - int i; - - for (i = h; i--;) { - vec_vsx_st(vec_vsx_ld(0, src), 0, dst); - vec_vsx_st(vec_vsx_ld(16, src), 16, dst); - vec_vsx_st(vec_vsx_ld(32, src), 32, dst); - vec_vsx_st(vec_vsx_ld(48, src), 48, dst); - src += src_stride; - dst += dst_stride; - } -} - -void vpx_convolve_copy_vsx(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, int x_step_q4, - int y0_q4, int32_t y_step_q4, int32_t w, int32_t h) { - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - switch (w) { - case 16: { - copy_w16(src, src_stride, dst, dst_stride, h); - break; - } - case 32: { - copy_w32(src, src_stride, dst, dst_stride, h); - break; - } - case 64: { - copy_w64(src, src_stride, dst, dst_stride, h); - break; - } - default: { - int i; - for (i = h; i--;) { - memcpy(dst, src, w); - src += src_stride; - dst += dst_stride; - } - break; - } - } -} - -static VPX_FORCE_INLINE void avg_w16(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - int32_t h) { - int i; - - for (i = h; i--;) { - const uint8x16_t v = vec_avg(vec_vsx_ld(0, src), vec_vsx_ld(0, dst)); - vec_vsx_st(v, 0, dst); - src += src_stride; - dst += dst_stride; - } -} - -static VPX_FORCE_INLINE void avg_w32(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - int32_t h) { - int i; - - for (i = h; i--;) { - const uint8x16_t v0 = vec_avg(vec_vsx_ld(0, src), vec_vsx_ld(0, dst)); - const uint8x16_t v1 = vec_avg(vec_vsx_ld(16, src), vec_vsx_ld(16, dst)); - vec_vsx_st(v0, 0, dst); - vec_vsx_st(v1, 16, dst); - src += src_stride; - dst += dst_stride; - } -} - -static VPX_FORCE_INLINE void avg_w64(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - int32_t h) { - int i; - - for (i = h; i--;) { - const uint8x16_t v0 = vec_avg(vec_vsx_ld(0, src), vec_vsx_ld(0, dst)); - const uint8x16_t v1 = vec_avg(vec_vsx_ld(16, src), vec_vsx_ld(16, dst)); - const uint8x16_t v2 = vec_avg(vec_vsx_ld(32, src), vec_vsx_ld(32, dst)); - const uint8x16_t v3 = vec_avg(vec_vsx_ld(48, src), vec_vsx_ld(48, dst)); - vec_vsx_st(v0, 0, dst); - vec_vsx_st(v1, 16, dst); - vec_vsx_st(v2, 32, dst); - vec_vsx_st(v3, 48, dst); - src += src_stride; - dst += dst_stride; - } -} - -void vpx_convolve_avg_vsx(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, int x_step_q4, - int y0_q4, int32_t y_step_q4, int32_t w, int32_t h) { - switch (w) { - case 16: { - avg_w16(src, src_stride, dst, dst_stride, h); - break; - } - case 32: { - avg_w32(src, src_stride, dst, dst_stride, h); - break; - } - case 64: { - avg_w64(src, src_stride, dst, dst_stride, h); - break; - } - default: { - vpx_convolve_avg_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); - break; - } - } -} - -static VPX_FORCE_INLINE void convolve_line(uint8_t *dst, const int16x8_t s, - const int16x8_t f) { - const int32x4_t sum = vec_msum(s, f, vec_splat_s32(0)); - const int32x4_t bias = - vec_sl(vec_splat_s32(1), vec_splat_u32(FILTER_BITS - 1)); - const int32x4_t avg = vec_sr(vec_sums(sum, bias), vec_splat_u32(FILTER_BITS)); - const uint8x16_t v = vec_splat( - vec_packsu(vec_pack(avg, vec_splat_s32(0)), vec_splat_s16(0)), 3); - vec_ste(v, 0, dst); -} - -static VPX_FORCE_INLINE void convolve_line_h(uint8_t *dst, - const uint8_t *const src_x, - const int16_t *const x_filter) { - const int16x8_t s = unpack_to_s16_h(vec_vsx_ld(0, src_x)); - const int16x8_t f = vec_vsx_ld(0, x_filter); - - convolve_line(dst, s, f); -} - -// TODO(lu_zero): Implement 8x8 and bigger block special cases -static VPX_FORCE_INLINE void convolve_horiz(const uint8_t *src, - ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, - const InterpKernel *x_filters, - int x0_q4, int x_step_q4, int w, - int h) { - int x, y; - src -= SUBPEL_TAPS / 2 - 1; - - for (y = 0; y < h; ++y) { - int x_q4 = x0_q4; - for (x = 0; x < w; ++x) { - convolve_line_h(dst + x, &src[x_q4 >> SUBPEL_BITS], - x_filters[x_q4 & SUBPEL_MASK]); - x_q4 += x_step_q4; - } - src += src_stride; - dst += dst_stride; - } -} - -static VPX_FORCE_INLINE void convolve_avg_horiz( - const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *x_filters, int x0_q4, - int x_step_q4, int w, int h) { - int x, y; - src -= SUBPEL_TAPS / 2 - 1; - - for (y = 0; y < h; ++y) { - int x_q4 = x0_q4; - for (x = 0; x < w; ++x) { - uint8_t v; - convolve_line_h(&v, &src[x_q4 >> SUBPEL_BITS], - x_filters[x_q4 & SUBPEL_MASK]); - dst[x] = ROUND_POWER_OF_TWO(dst[x] + v, 1); - x_q4 += x_step_q4; - } - src += src_stride; - dst += dst_stride; - } -} - -static uint8x16_t transpose_line_u8_8x8(uint8x16_t a, uint8x16_t b, - uint8x16_t c, uint8x16_t d, - uint8x16_t e, uint8x16_t f, - uint8x16_t g, uint8x16_t h) { - uint16x8_t ab = (uint16x8_t)vec_mergeh(a, b); - uint16x8_t cd = (uint16x8_t)vec_mergeh(c, d); - uint16x8_t ef = (uint16x8_t)vec_mergeh(e, f); - uint16x8_t gh = (uint16x8_t)vec_mergeh(g, h); - - uint32x4_t abcd = (uint32x4_t)vec_mergeh(ab, cd); - uint32x4_t efgh = (uint32x4_t)vec_mergeh(ef, gh); - - return (uint8x16_t)vec_mergeh(abcd, efgh); -} - -static VPX_FORCE_INLINE void convolve_line_v(uint8_t *dst, - const uint8_t *const src_y, - ptrdiff_t src_stride, - const int16_t *const y_filter) { - uint8x16_t s0 = vec_vsx_ld(0, src_y + 0 * src_stride); - uint8x16_t s1 = vec_vsx_ld(0, src_y + 1 * src_stride); - uint8x16_t s2 = vec_vsx_ld(0, src_y + 2 * src_stride); - uint8x16_t s3 = vec_vsx_ld(0, src_y + 3 * src_stride); - uint8x16_t s4 = vec_vsx_ld(0, src_y + 4 * src_stride); - uint8x16_t s5 = vec_vsx_ld(0, src_y + 5 * src_stride); - uint8x16_t s6 = vec_vsx_ld(0, src_y + 6 * src_stride); - uint8x16_t s7 = vec_vsx_ld(0, src_y + 7 * src_stride); - const int16x8_t f = vec_vsx_ld(0, y_filter); - uint8_t buf[16]; - const uint8x16_t s = transpose_line_u8_8x8(s0, s1, s2, s3, s4, s5, s6, s7); - - vec_vsx_st(s, 0, buf); - - convolve_line(dst, unpack_to_s16_h(s), f); -} - -static VPX_FORCE_INLINE void convolve_vert(const uint8_t *src, - ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, - const InterpKernel *y_filters, - int y0_q4, int y_step_q4, int w, - int h) { - int x, y; - src -= src_stride * (SUBPEL_TAPS / 2 - 1); - - for (x = 0; x < w; ++x) { - int y_q4 = y0_q4; - for (y = 0; y < h; ++y) { - convolve_line_v(dst + y * dst_stride, - &src[(y_q4 >> SUBPEL_BITS) * src_stride], src_stride, - y_filters[y_q4 & SUBPEL_MASK]); - y_q4 += y_step_q4; - } - ++src; - ++dst; - } -} - -static VPX_FORCE_INLINE void convolve_avg_vert( - const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *y_filters, int y0_q4, - int y_step_q4, int w, int h) { - int x, y; - src -= src_stride * (SUBPEL_TAPS / 2 - 1); - - for (x = 0; x < w; ++x) { - int y_q4 = y0_q4; - for (y = 0; y < h; ++y) { - uint8_t v; - convolve_line_v(&v, &src[(y_q4 >> SUBPEL_BITS) * src_stride], src_stride, - y_filters[y_q4 & SUBPEL_MASK]); - dst[y * dst_stride] = ROUND_POWER_OF_TWO(dst[y * dst_stride] + v, 1); - y_q4 += y_step_q4; - } - ++src; - ++dst; - } -} - -static VPX_FORCE_INLINE void convolve(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *const filter, - int x0_q4, int x_step_q4, int y0_q4, - int y_step_q4, int w, int h) { - // Note: Fixed size intermediate buffer, temp, places limits on parameters. - // 2d filtering proceeds in 2 steps: - // (1) Interpolate horizontally into an intermediate buffer, temp. - // (2) Interpolate temp vertically to derive the sub-pixel result. - // Deriving the maximum number of rows in the temp buffer (135): - // --Smallest scaling factor is x1/2 ==> y_step_q4 = 32 (Normative). - // --Largest block size is 64x64 pixels. - // --64 rows in the downscaled frame span a distance of (64 - 1) * 32 in the - // original frame (in 1/16th pixel units). - // --Must round-up because block may be located at sub-pixel position. - // --Require an additional SUBPEL_TAPS rows for the 8-tap filter tails. - // --((64 - 1) * 32 + 15) >> 4 + 8 = 135. - DECLARE_ALIGNED(16, uint8_t, temp[64 * 135]); - const int intermediate_height = - (((h - 1) * y_step_q4 + y0_q4) >> SUBPEL_BITS) + SUBPEL_TAPS; - - assert(w <= 64); - assert(h <= 64); - assert(y_step_q4 <= 32); - assert(x_step_q4 <= 32); - - convolve_horiz(src - src_stride * (SUBPEL_TAPS / 2 - 1), src_stride, temp, 64, - filter, x0_q4, x_step_q4, w, intermediate_height); - convolve_vert(temp + 64 * (SUBPEL_TAPS / 2 - 1), 64, dst, dst_stride, filter, - y0_q4, y_step_q4, w, h); -} - -void vpx_convolve8_horiz_vsx(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - (void)y0_q4; - (void)y_step_q4; - - convolve_horiz(src, src_stride, dst, dst_stride, filter, x0_q4, x_step_q4, w, - h); -} - -void vpx_convolve8_avg_horiz_vsx(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - (void)y0_q4; - (void)y_step_q4; - - convolve_avg_horiz(src, src_stride, dst, dst_stride, filter, x0_q4, x_step_q4, - w, h); -} - -void vpx_convolve8_vert_vsx(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - (void)x0_q4; - (void)x_step_q4; - - convolve_vert(src, src_stride, dst, dst_stride, filter, y0_q4, y_step_q4, w, - h); -} - -void vpx_convolve8_avg_vert_vsx(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - (void)x0_q4; - (void)x_step_q4; - - convolve_avg_vert(src, src_stride, dst, dst_stride, filter, y0_q4, y_step_q4, - w, h); -} - -void vpx_convolve8_vsx(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, - int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - convolve(src, src_stride, dst, dst_stride, filter, x0_q4, x_step_q4, y0_q4, - y_step_q4, w, h); -} - -void vpx_convolve8_avg_vsx(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, int x_step_q4, - int y0_q4, int y_step_q4, int w, int h) { - // Fixed size intermediate buffer places limits on parameters. - DECLARE_ALIGNED(16, uint8_t, temp[64 * 64]); - assert(w <= 64); - assert(h <= 64); - - vpx_convolve8_vsx(src, src_stride, temp, 64, filter, x0_q4, x_step_q4, y0_q4, - y_step_q4, w, h); - vpx_convolve_avg_vsx(temp, 64, dst, dst_stride, NULL, 0, 0, 0, 0, w, h); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/prob.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/prob.c deleted file mode 100644 index 819e9506..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/prob.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./prob.h" - -const uint8_t vpx_norm[256] = { - 0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static unsigned int tree_merge_probs_impl(unsigned int i, - const vpx_tree_index *tree, - const vpx_prob *pre_probs, - const unsigned int *counts, - vpx_prob *probs) { - const int l = tree[i]; - const unsigned int left_count = - (l <= 0) ? counts[-l] - : tree_merge_probs_impl(l, tree, pre_probs, counts, probs); - const int r = tree[i + 1]; - const unsigned int right_count = - (r <= 0) ? counts[-r] - : tree_merge_probs_impl(r, tree, pre_probs, counts, probs); - const unsigned int ct[2] = { left_count, right_count }; - probs[i >> 1] = mode_mv_merge_probs(pre_probs[i >> 1], ct); - return left_count + right_count; -} - -void vpx_tree_merge_probs(const vpx_tree_index *tree, const vpx_prob *pre_probs, - const unsigned int *counts, vpx_prob *probs) { - tree_merge_probs_impl(0, tree, pre_probs, counts, probs); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/prob.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/prob.h deleted file mode 100644 index 7a71c004..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/prob.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_PROB_H_ -#define VPX_VPX_DSP_PROB_H_ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_common.h" - -#include "vpx_ports/mem.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef uint8_t vpx_prob; - -#define MAX_PROB 255 - -#define vpx_prob_half ((vpx_prob)128) - -typedef int8_t vpx_tree_index; - -#define TREE_SIZE(leaf_count) (2 * (leaf_count)-2) - -#define vpx_complement(x) (255 - (x)) - -#define MODE_MV_COUNT_SAT 20 - -/* We build coding trees compactly in arrays. - Each node of the tree is a pair of vpx_tree_indices. - Array index often references a corresponding probability table. - Index <= 0 means done encoding/decoding and value = -Index, - Index > 0 means need another bit, specification at index. - Nonnegative indices are always even; processing begins at node 0. */ - -typedef const vpx_tree_index vpx_tree[]; - -static INLINE vpx_prob get_prob(unsigned int num, unsigned int den) { - assert(den != 0); - { - const int p = (int)(((uint64_t)num * 256 + (den >> 1)) / den); - // (p > 255) ? 255 : (p < 1) ? 1 : p; - const int clipped_prob = p | ((255 - p) >> 23) | (p == 0); - return (vpx_prob)clipped_prob; - } -} - -static INLINE vpx_prob get_binary_prob(unsigned int n0, unsigned int n1) { - const unsigned int den = n0 + n1; - if (den == 0) return 128u; - return get_prob(n0, den); -} - -/* This function assumes prob1 and prob2 are already within [1,255] range. */ -static INLINE vpx_prob weighted_prob(int prob1, int prob2, int factor) { - return ROUND_POWER_OF_TWO(prob1 * (256 - factor) + prob2 * factor, 8); -} - -static INLINE vpx_prob merge_probs(vpx_prob pre_prob, const unsigned int ct[2], - unsigned int count_sat, - unsigned int max_update_factor) { - const vpx_prob prob = get_binary_prob(ct[0], ct[1]); - const unsigned int count = VPXMIN(ct[0] + ct[1], count_sat); - const unsigned int factor = max_update_factor * count / count_sat; - return weighted_prob(pre_prob, prob, factor); -} - -// MODE_MV_MAX_UPDATE_FACTOR (128) * count / MODE_MV_COUNT_SAT; -static const int count_to_update_factor[MODE_MV_COUNT_SAT + 1] = { - 0, 6, 12, 19, 25, 32, 38, 44, 51, 57, 64, - 70, 76, 83, 89, 96, 102, 108, 115, 121, 128 -}; - -static INLINE vpx_prob mode_mv_merge_probs(vpx_prob pre_prob, - const unsigned int ct[2]) { - const unsigned int den = ct[0] + ct[1]; - if (den == 0) { - return pre_prob; - } else { - const unsigned int count = VPXMIN(den, MODE_MV_COUNT_SAT); - const unsigned int factor = count_to_update_factor[count]; - const vpx_prob prob = get_prob(ct[0], den); - return weighted_prob(pre_prob, prob, factor); - } -} - -void vpx_tree_merge_probs(const vpx_tree_index *tree, const vpx_prob *pre_probs, - const unsigned int *counts, vpx_prob *probs); - -DECLARE_ALIGNED(16, extern const uint8_t, vpx_norm[256]); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_PROB_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/psnr.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/psnr.c deleted file mode 100644 index 4ee4130a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/psnr.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/psnr.h" -#include "vpx_scale/yv12config.h" - -double vpx_sse_to_psnr(double samples, double peak, double sse) { - if (sse > 0.0) { - const double psnr = 10.0 * log10(samples * peak * peak / sse); - return psnr > MAX_PSNR ? MAX_PSNR : psnr; - } else { - return MAX_PSNR; - } -} - -/* TODO(yaowu): The block_variance calls the unoptimized versions of variance() - * and highbd_8_variance(). It should not. - */ -static int64_t encoder_sse(const uint8_t *a, int a_stride, const uint8_t *b, - int b_stride, int w, int h) { - int i, j; - int64_t sse = 0; - - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - const int diff = a[j] - b[j]; - sse += diff * diff; - } - - a += a_stride; - b += b_stride; - } - - return sse; -} - -#if CONFIG_VP9_HIGHBITDEPTH -static int64_t encoder_highbd_sse(const uint8_t *a8, int a_stride, - const uint8_t *b8, int b_stride, int w, - int h) { - int i, j; - int64_t sse = 0; - - const uint16_t *a = CONVERT_TO_SHORTPTR(a8); - const uint16_t *b = CONVERT_TO_SHORTPTR(b8); - - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - const int diff = a[j] - b[j]; - sse += diff * diff; - } - a += a_stride; - b += b_stride; - } - - return sse; -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static int64_t get_sse(const uint8_t *a, int a_stride, const uint8_t *b, - int b_stride, int width, int height) { - const int dw = width % 16; - const int dh = height % 16; - int64_t total_sse = 0; - int x, y; - - if (dw > 0) { - total_sse += encoder_sse(&a[width - dw], a_stride, &b[width - dw], b_stride, - dw, height); - } - - if (dh > 0) { - total_sse += - encoder_sse(&a[(height - dh) * a_stride], a_stride, - &b[(height - dh) * b_stride], b_stride, width - dw, dh); - } - - for (y = 0; y < height / 16; ++y) { - const uint8_t *pa = a; - const uint8_t *pb = b; - for (x = 0; x < width / 16; ++x) { - total_sse += vpx_sse(pa, a_stride, pb, b_stride, 16, 16); - - pa += 16; - pb += 16; - } - - a += 16 * a_stride; - b += 16 * b_stride; - } - - return total_sse; -} - -#if CONFIG_VP9_HIGHBITDEPTH -static int64_t highbd_get_sse_shift(const uint8_t *a8, int a_stride, - const uint8_t *b8, int b_stride, int width, - int height, unsigned int input_shift) { - const uint16_t *a = CONVERT_TO_SHORTPTR(a8); - const uint16_t *b = CONVERT_TO_SHORTPTR(b8); - int64_t total_sse = 0; - int x, y; - for (y = 0; y < height; ++y) { - for (x = 0; x < width; ++x) { - int64_t diff; - diff = (a[x] >> input_shift) - (b[x] >> input_shift); - total_sse += diff * diff; - } - a += a_stride; - b += b_stride; - } - return total_sse; -} - -static int64_t highbd_get_sse(const uint8_t *a, int a_stride, const uint8_t *b, - int b_stride, int width, int height) { - int64_t total_sse = 0; - int x, y; - const int dw = width % 16; - const int dh = height % 16; - if (dw > 0) { - total_sse += encoder_highbd_sse(&a[width - dw], a_stride, &b[width - dw], - b_stride, dw, height); - } - if (dh > 0) { - total_sse += encoder_highbd_sse(&a[(height - dh) * a_stride], a_stride, - &b[(height - dh) * b_stride], b_stride, - width - dw, dh); - } - for (y = 0; y < height / 16; ++y) { - const uint8_t *pa = a; - const uint8_t *pb = b; - for (x = 0; x < width / 16; ++x) { - total_sse += vpx_highbd_sse(pa, a_stride, pb, b_stride, 16, 16); - pa += 16; - pb += 16; - } - a += 16 * a_stride; - b += 16 * b_stride; - } - return total_sse; -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -int64_t vpx_get_y_sse(const YV12_BUFFER_CONFIG *a, - const YV12_BUFFER_CONFIG *b) { - assert(a->y_crop_width == b->y_crop_width); - assert(a->y_crop_height == b->y_crop_height); - - return get_sse(a->y_buffer, a->y_stride, b->y_buffer, b->y_stride, - a->y_crop_width, a->y_crop_height); -} - -#if CONFIG_VP9_HIGHBITDEPTH -int64_t vpx_highbd_get_y_sse(const YV12_BUFFER_CONFIG *a, - const YV12_BUFFER_CONFIG *b) { - assert(a->y_crop_width == b->y_crop_width); - assert(a->y_crop_height == b->y_crop_height); - assert((a->flags & YV12_FLAG_HIGHBITDEPTH) != 0); - assert((b->flags & YV12_FLAG_HIGHBITDEPTH) != 0); - - return highbd_get_sse(a->y_buffer, a->y_stride, b->y_buffer, b->y_stride, - a->y_crop_width, a->y_crop_height); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -#if CONFIG_VP9_HIGHBITDEPTH -void vpx_calc_highbd_psnr(const YV12_BUFFER_CONFIG *a, - const YV12_BUFFER_CONFIG *b, PSNR_STATS *psnr, - uint32_t bit_depth, uint32_t in_bit_depth) { - const int widths[3] = { a->y_crop_width, a->uv_crop_width, a->uv_crop_width }; - const int heights[3] = { a->y_crop_height, a->uv_crop_height, - a->uv_crop_height }; - const uint8_t *a_planes[3] = { a->y_buffer, a->u_buffer, a->v_buffer }; - const int a_strides[3] = { a->y_stride, a->uv_stride, a->uv_stride }; - const uint8_t *b_planes[3] = { b->y_buffer, b->u_buffer, b->v_buffer }; - const int b_strides[3] = { b->y_stride, b->uv_stride, b->uv_stride }; - int i; - uint64_t total_sse = 0; - uint32_t total_samples = 0; - const double peak = (double)((1 << in_bit_depth) - 1); - const unsigned int input_shift = bit_depth - in_bit_depth; - - for (i = 0; i < 3; ++i) { - const int w = widths[i]; - const int h = heights[i]; - const uint32_t samples = w * h; - uint64_t sse; - if (a->flags & YV12_FLAG_HIGHBITDEPTH) { - if (input_shift) { - sse = highbd_get_sse_shift(a_planes[i], a_strides[i], b_planes[i], - b_strides[i], w, h, input_shift); - } else { - sse = highbd_get_sse(a_planes[i], a_strides[i], b_planes[i], - b_strides[i], w, h); - } - } else { - sse = get_sse(a_planes[i], a_strides[i], b_planes[i], b_strides[i], w, h); - } - psnr->sse[1 + i] = sse; - psnr->samples[1 + i] = samples; - psnr->psnr[1 + i] = vpx_sse_to_psnr(samples, peak, (double)sse); - - total_sse += sse; - total_samples += samples; - } - - psnr->sse[0] = total_sse; - psnr->samples[0] = total_samples; - psnr->psnr[0] = - vpx_sse_to_psnr((double)total_samples, peak, (double)total_sse); -} - -#endif // !CONFIG_VP9_HIGHBITDEPTH - -void vpx_calc_psnr(const YV12_BUFFER_CONFIG *a, const YV12_BUFFER_CONFIG *b, - PSNR_STATS *psnr) { - static const double peak = 255.0; - const int widths[3] = { a->y_crop_width, a->uv_crop_width, a->uv_crop_width }; - const int heights[3] = { a->y_crop_height, a->uv_crop_height, - a->uv_crop_height }; - const uint8_t *a_planes[3] = { a->y_buffer, a->u_buffer, a->v_buffer }; - const int a_strides[3] = { a->y_stride, a->uv_stride, a->uv_stride }; - const uint8_t *b_planes[3] = { b->y_buffer, b->u_buffer, b->v_buffer }; - const int b_strides[3] = { b->y_stride, b->uv_stride, b->uv_stride }; - int i; - uint64_t total_sse = 0; - uint32_t total_samples = 0; - - for (i = 0; i < 3; ++i) { - const int w = widths[i]; - const int h = heights[i]; - const uint32_t samples = w * h; - const uint64_t sse = - get_sse(a_planes[i], a_strides[i], b_planes[i], b_strides[i], w, h); - psnr->sse[1 + i] = sse; - psnr->samples[1 + i] = samples; - psnr->psnr[1 + i] = vpx_sse_to_psnr(samples, peak, (double)sse); - - total_sse += sse; - total_samples += samples; - } - - psnr->sse[0] = total_sse; - psnr->samples[0] = total_samples; - psnr->psnr[0] = - vpx_sse_to_psnr((double)total_samples, peak, (double)total_sse); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/psnr.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/psnr.h deleted file mode 100644 index 7c57aa42..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/psnr.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_PSNR_H_ -#define VPX_VPX_DSP_PSNR_H_ - -#include "vpx_scale/yv12config.h" -#include "vpx/vpx_encoder.h" - -#define MAX_PSNR 100.0 - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct vpx_psnr_pkt PSNR_STATS; - -// TODO(dkovalev) change vpx_sse_to_psnr signature: double -> int64_t - -/*!\brief Converts SSE to PSNR - * - * Converts sum of squared errros (SSE) to peak signal-to-noise ratio (PSNR). - * - * \param[in] samples Number of samples - * \param[in] peak Max sample value - * \param[in] sse Sum of squared errors - */ -double vpx_sse_to_psnr(double samples, double peak, double sse); -int64_t vpx_get_y_sse(const YV12_BUFFER_CONFIG *a, const YV12_BUFFER_CONFIG *b); -#if CONFIG_VP9_HIGHBITDEPTH -int64_t vpx_highbd_get_y_sse(const YV12_BUFFER_CONFIG *a, - const YV12_BUFFER_CONFIG *b); -void vpx_calc_highbd_psnr(const YV12_BUFFER_CONFIG *a, - const YV12_BUFFER_CONFIG *b, PSNR_STATS *psnr, - unsigned int bit_depth, unsigned int in_bit_depth); -#endif -void vpx_calc_psnr(const YV12_BUFFER_CONFIG *a, const YV12_BUFFER_CONFIG *b, - PSNR_STATS *psnr); - -double vpx_psnrhvs(const YV12_BUFFER_CONFIG *source, - const YV12_BUFFER_CONFIG *dest, double *phvs_y, - double *phvs_u, double *phvs_v, uint32_t bd, uint32_t in_bd); - -#ifdef __cplusplus -} // extern "C" -#endif -#endif // VPX_VPX_DSP_PSNR_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/psnrhvs.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/psnrhvs.c deleted file mode 100644 index d7ec1a42..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/psnrhvs.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - * - * This code was originally written by: Gregory Maxwell, at the Daala - * project. - */ -#include -#include -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/ssim.h" -#include "vpx_ports/system_state.h" -#include "vpx_dsp/psnr.h" - -#if !defined(M_PI) -#define M_PI (3.141592653589793238462643) -#endif -#include - -static void od_bin_fdct8x8(tran_low_t *y, int ystride, const int16_t *x, - int xstride) { - int i, j; - (void)xstride; - vpx_fdct8x8(x, y, ystride); - for (i = 0; i < 8; i++) - for (j = 0; j < 8; j++) - *(y + ystride * i + j) = (*(y + ystride * i + j) + 4) >> 3; -} -#if CONFIG_VP9_HIGHBITDEPTH -static void hbd_od_bin_fdct8x8(tran_low_t *y, int ystride, const int16_t *x, - int xstride) { - int i, j; - (void)xstride; - vpx_highbd_fdct8x8(x, y, ystride); - for (i = 0; i < 8; i++) - for (j = 0; j < 8; j++) - *(y + ystride * i + j) = (*(y + ystride * i + j) + 4) >> 3; -} -#endif - -/* Normalized inverse quantization matrix for 8x8 DCT at the point of - * transparency. This is not the JPEG based matrix from the paper, - this one gives a slightly higher MOS agreement.*/ -static const double csf_y[8][8] = { - { 1.6193873005, 2.2901594831, 2.08509755623, 1.48366094411, 1.00227514334, - 0.678296995242, 0.466224900598, 0.3265091542 }, - { 2.2901594831, 1.94321815382, 2.04793073064, 1.68731108984, 1.2305666963, - 0.868920337363, 0.61280991668, 0.436405793551 }, - { 2.08509755623, 2.04793073064, 1.34329019223, 1.09205635862, 0.875748795257, - 0.670882927016, 0.501731932449, 0.372504254596 }, - { 1.48366094411, 1.68731108984, 1.09205635862, 0.772819797575, 0.605636379554, - 0.48309405692, 0.380429446972, 0.295774038565 }, - { 1.00227514334, 1.2305666963, 0.875748795257, 0.605636379554, 0.448996256676, - 0.352889268808, 0.283006984131, 0.226951348204 }, - { 0.678296995242, 0.868920337363, 0.670882927016, 0.48309405692, - 0.352889268808, 0.27032073436, 0.215017739696, 0.17408067321 }, - { 0.466224900598, 0.61280991668, 0.501731932449, 0.380429446972, - 0.283006984131, 0.215017739696, 0.168869545842, 0.136153931001 }, - { 0.3265091542, 0.436405793551, 0.372504254596, 0.295774038565, - 0.226951348204, 0.17408067321, 0.136153931001, 0.109083846276 } -}; -static const double csf_cb420[8][8] = { - { 1.91113096927, 2.46074210438, 1.18284184739, 1.14982565193, 1.05017074788, - 0.898018824055, 0.74725392039, 0.615105596242 }, - { 2.46074210438, 1.58529308355, 1.21363250036, 1.38190029285, 1.33100189972, - 1.17428548929, 0.996404342439, 0.830890433625 }, - { 1.18284184739, 1.21363250036, 0.978712413627, 1.02624506078, 1.03145147362, - 0.960060382087, 0.849823426169, 0.731221236837 }, - { 1.14982565193, 1.38190029285, 1.02624506078, 0.861317501629, 0.801821139099, - 0.751437590932, 0.685398513368, 0.608694761374 }, - { 1.05017074788, 1.33100189972, 1.03145147362, 0.801821139099, 0.676555426187, - 0.605503172737, 0.55002013668, 0.495804539034 }, - { 0.898018824055, 1.17428548929, 0.960060382087, 0.751437590932, - 0.605503172737, 0.514674450957, 0.454353482512, 0.407050308965 }, - { 0.74725392039, 0.996404342439, 0.849823426169, 0.685398513368, - 0.55002013668, 0.454353482512, 0.389234902883, 0.342353999733 }, - { 0.615105596242, 0.830890433625, 0.731221236837, 0.608694761374, - 0.495804539034, 0.407050308965, 0.342353999733, 0.295530605237 } -}; -static const double csf_cr420[8][8] = { - { 2.03871978502, 2.62502345193, 1.26180942886, 1.11019789803, 1.01397751469, - 0.867069376285, 0.721500455585, 0.593906509971 }, - { 2.62502345193, 1.69112867013, 1.17180569821, 1.3342742857, 1.28513006198, - 1.13381474809, 0.962064122248, 0.802254508198 }, - { 1.26180942886, 1.17180569821, 0.944981930573, 0.990876405848, - 0.995903384143, 0.926972725286, 0.820534991409, 0.706020324706 }, - { 1.11019789803, 1.3342742857, 0.990876405848, 0.831632933426, 0.77418706195, - 0.725539939514, 0.661776842059, 0.587716619023 }, - { 1.01397751469, 1.28513006198, 0.995903384143, 0.77418706195, 0.653238524286, - 0.584635025748, 0.531064164893, 0.478717061273 }, - { 0.867069376285, 1.13381474809, 0.926972725286, 0.725539939514, - 0.584635025748, 0.496936637883, 0.438694579826, 0.393021669543 }, - { 0.721500455585, 0.962064122248, 0.820534991409, 0.661776842059, - 0.531064164893, 0.438694579826, 0.375820256136, 0.330555063063 }, - { 0.593906509971, 0.802254508198, 0.706020324706, 0.587716619023, - 0.478717061273, 0.393021669543, 0.330555063063, 0.285345396658 } -}; - -static double convert_score_db(double _score, double _weight, int bit_depth) { - int16_t pix_max = 255; - assert(_score * _weight >= 0.0); - if (bit_depth == 10) - pix_max = 1023; - else if (bit_depth == 12) - pix_max = 4095; - - if (_weight * _score < pix_max * pix_max * 1e-10) return MAX_PSNR; - return 10 * (log10(pix_max * pix_max) - log10(_weight * _score)); -} - -static double calc_psnrhvs(const unsigned char *src, int _systride, - const unsigned char *dst, int _dystride, double _par, - int _w, int _h, int _step, const double _csf[8][8], - uint32_t bit_depth, uint32_t _shift) { - double ret; - const uint8_t *_src8 = src; - const uint8_t *_dst8 = dst; - const uint16_t *_src16 = CONVERT_TO_SHORTPTR(src); - const uint16_t *_dst16 = CONVERT_TO_SHORTPTR(dst); - DECLARE_ALIGNED(16, int16_t, dct_s[8 * 8]); - DECLARE_ALIGNED(16, int16_t, dct_d[8 * 8]); - DECLARE_ALIGNED(16, tran_low_t, dct_s_coef[8 * 8]); - DECLARE_ALIGNED(16, tran_low_t, dct_d_coef[8 * 8]); - double mask[8][8]; - int pixels; - int x; - int y; - (void)_par; - ret = pixels = 0; - - /*In the PSNR-HVS-M paper[1] the authors describe the construction of - their masking table as "we have used the quantization table for the - color component Y of JPEG [6] that has been also obtained on the - basis of CSF. Note that the values in quantization table JPEG have - been normalized and then squared." Their CSF matrix (from PSNR-HVS) - was also constructed from the JPEG matrices. I can not find any obvious - scheme of normalizing to produce their table, but if I multiply their - CSF by 0.3885746225901003 and square the result I get their masking table. - I have no idea where this constant comes from, but deviating from it - too greatly hurts MOS agreement. - - [1] Nikolay Ponomarenko, Flavia Silvestri, Karen Egiazarian, Marco Carli, - Jaakko Astola, Vladimir Lukin, "On between-coefficient contrast masking - of DCT basis functions", CD-ROM Proceedings of the Third - International Workshop on Video Processing and Quality Metrics for Consumer - Electronics VPQM-07, Scottsdale, Arizona, USA, 25-26 January, 2007, 4 p. - - Suggested in aomedia issue #2363: - 0.3885746225901003 is a reciprocal of the maximum coefficient (2.573509) - of the old JPEG based matrix from the paper. Since you are not using that, - divide by actual maximum coefficient. */ - for (x = 0; x < 8; x++) - for (y = 0; y < 8; y++) - mask[x][y] = (_csf[x][y] / _csf[1][0]) * (_csf[x][y] / _csf[1][0]); - for (y = 0; y < _h - 7; y += _step) { - for (x = 0; x < _w - 7; x += _step) { - int i; - int j; - double s_means[4]; - double d_means[4]; - double s_vars[4]; - double d_vars[4]; - double s_gmean = 0; - double d_gmean = 0; - double s_gvar = 0; - double d_gvar = 0; - double s_mask = 0; - double d_mask = 0; - for (i = 0; i < 4; i++) - s_means[i] = d_means[i] = s_vars[i] = d_vars[i] = 0; - for (i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) { - int sub = ((i & 12) >> 2) + ((j & 12) >> 1); - if (bit_depth == 8 && _shift == 0) { - dct_s[i * 8 + j] = _src8[(y + i) * _systride + (j + x)]; - dct_d[i * 8 + j] = _dst8[(y + i) * _dystride + (j + x)]; - } else if (bit_depth == 10 || bit_depth == 12) { - dct_s[i * 8 + j] = _src16[(y + i) * _systride + (j + x)] >> _shift; - dct_d[i * 8 + j] = _dst16[(y + i) * _dystride + (j + x)] >> _shift; - } - s_gmean += dct_s[i * 8 + j]; - d_gmean += dct_d[i * 8 + j]; - s_means[sub] += dct_s[i * 8 + j]; - d_means[sub] += dct_d[i * 8 + j]; - } - } - s_gmean /= 64.f; - d_gmean /= 64.f; - for (i = 0; i < 4; i++) s_means[i] /= 16.f; - for (i = 0; i < 4; i++) d_means[i] /= 16.f; - for (i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) { - int sub = ((i & 12) >> 2) + ((j & 12) >> 1); - s_gvar += (dct_s[i * 8 + j] - s_gmean) * (dct_s[i * 8 + j] - s_gmean); - d_gvar += (dct_d[i * 8 + j] - d_gmean) * (dct_d[i * 8 + j] - d_gmean); - s_vars[sub] += (dct_s[i * 8 + j] - s_means[sub]) * - (dct_s[i * 8 + j] - s_means[sub]); - d_vars[sub] += (dct_d[i * 8 + j] - d_means[sub]) * - (dct_d[i * 8 + j] - d_means[sub]); - } - } - s_gvar *= 1 / 63.f * 64; - d_gvar *= 1 / 63.f * 64; - for (i = 0; i < 4; i++) s_vars[i] *= 1 / 15.f * 16; - for (i = 0; i < 4; i++) d_vars[i] *= 1 / 15.f * 16; - if (s_gvar > 0) - s_gvar = (s_vars[0] + s_vars[1] + s_vars[2] + s_vars[3]) / s_gvar; - if (d_gvar > 0) - d_gvar = (d_vars[0] + d_vars[1] + d_vars[2] + d_vars[3]) / d_gvar; -#if CONFIG_VP9_HIGHBITDEPTH - if (bit_depth == 10 || bit_depth == 12) { - hbd_od_bin_fdct8x8(dct_s_coef, 8, dct_s, 8); - hbd_od_bin_fdct8x8(dct_d_coef, 8, dct_d, 8); - } -#endif - if (bit_depth == 8) { - od_bin_fdct8x8(dct_s_coef, 8, dct_s, 8); - od_bin_fdct8x8(dct_d_coef, 8, dct_d, 8); - } - for (i = 0; i < 8; i++) - for (j = (i == 0); j < 8; j++) - s_mask += dct_s_coef[i * 8 + j] * dct_s_coef[i * 8 + j] * mask[i][j]; - for (i = 0; i < 8; i++) - for (j = (i == 0); j < 8; j++) - d_mask += dct_d_coef[i * 8 + j] * dct_d_coef[i * 8 + j] * mask[i][j]; - s_mask = sqrt(s_mask * s_gvar) / 32.f; - d_mask = sqrt(d_mask * d_gvar) / 32.f; - if (d_mask > s_mask) s_mask = d_mask; - for (i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) { - double err; - err = fabs((double)(dct_s_coef[i * 8 + j] - dct_d_coef[i * 8 + j])); - if (i != 0 || j != 0) - err = err < s_mask / mask[i][j] ? 0 : err - s_mask / mask[i][j]; - ret += (err * _csf[i][j]) * (err * _csf[i][j]); - pixels++; - } - } - } - } - if (pixels <= 0) return 0; - ret /= pixels; - return ret; -} - -double vpx_psnrhvs(const YV12_BUFFER_CONFIG *src, - const YV12_BUFFER_CONFIG *dest, double *y_psnrhvs, - double *u_psnrhvs, double *v_psnrhvs, uint32_t bd, - uint32_t in_bd) { - double psnrhvs; - const double par = 1.0; - const int step = 7; - uint32_t bd_shift = 0; - vpx_clear_system_state(); - - assert(bd == 8 || bd == 10 || bd == 12); - assert(bd >= in_bd); - - bd_shift = bd - in_bd; - - *y_psnrhvs = calc_psnrhvs(src->y_buffer, src->y_stride, dest->y_buffer, - dest->y_stride, par, src->y_crop_width, - src->y_crop_height, step, csf_y, bd, bd_shift); - *u_psnrhvs = calc_psnrhvs(src->u_buffer, src->uv_stride, dest->u_buffer, - dest->uv_stride, par, src->uv_crop_width, - src->uv_crop_height, step, csf_cb420, bd, bd_shift); - *v_psnrhvs = calc_psnrhvs(src->v_buffer, src->uv_stride, dest->v_buffer, - dest->uv_stride, par, src->uv_crop_width, - src->uv_crop_height, step, csf_cr420, bd, bd_shift); - psnrhvs = (*y_psnrhvs) * .8 + .1 * ((*u_psnrhvs) + (*v_psnrhvs)); - return convert_score_db(psnrhvs, 1.0, in_bd); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/quantize.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/quantize.c deleted file mode 100644 index fac9136f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/quantize.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/quantize.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vp9/common/vp9_scan.h" -#include "vp9/encoder/vp9_block.h" - -void vpx_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, - const int16_t *round_ptr, const int16_t quant, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t dequant, uint16_t *eob_ptr) { - const int rc = 0; - const int coeff = coeff_ptr[rc]; - const int coeff_sign = (coeff >> 31); - const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; - int tmp, eob = -1; - - memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); - memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); - - tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX); - tmp = (tmp * quant) >> 16; - qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; - dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant; - if (tmp) eob = 0; - - *eob_ptr = eob + 1; -} - -#if CONFIG_VP9_HIGHBITDEPTH -void vpx_highbd_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, - const int16_t *round_ptr, const int16_t quant, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t dequant, uint16_t *eob_ptr) { - int eob = -1; - - memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); - memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); - - { - const int coeff = coeff_ptr[0]; - const int coeff_sign = (coeff >> 31); - const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; - const int64_t tmp = abs_coeff + round_ptr[0]; - const int abs_qcoeff = (int)((tmp * quant) >> 16); - qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign); - dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant; - if (abs_qcoeff) eob = 0; - } - - *eob_ptr = eob + 1; -} -#endif - -void vpx_quantize_dc_32x32(const tran_low_t *coeff_ptr, - const int16_t *round_ptr, const int16_t quant, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t dequant, uint16_t *eob_ptr) { - const int n_coeffs = 1024; - const int rc = 0; - const int coeff = coeff_ptr[rc]; - const int coeff_sign = (coeff >> 31); - const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; - int tmp, eob = -1; - - memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); - memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); - - tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1), INT16_MIN, - INT16_MAX); - tmp = (tmp * quant) >> 15; - qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; - dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant / 2; - if (tmp) eob = 0; - - *eob_ptr = eob + 1; -} - -#if CONFIG_VP9_HIGHBITDEPTH -void vpx_highbd_quantize_dc_32x32(const tran_low_t *coeff_ptr, - const int16_t *round_ptr, const int16_t quant, - tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, - const int16_t dequant, uint16_t *eob_ptr) { - const int n_coeffs = 1024; - int eob = -1; - - memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); - memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); - - { - const int coeff = coeff_ptr[0]; - const int coeff_sign = (coeff >> 31); - const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; - const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], 1); - const int abs_qcoeff = (int)((tmp * quant) >> 15); - qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign); - dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant / 2; - if (abs_qcoeff) eob = 0; - } - - *eob_ptr = eob + 1; -} -#endif - -void vpx_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - int i, non_zero_count = (int)n_coeffs, eob = -1; - const int zbins[2] = { mb_plane->zbin[0], mb_plane->zbin[1] }; - const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 }; - const int16_t *round_ptr = mb_plane->round; - const int16_t *quant_ptr = mb_plane->quant; - const int16_t *quant_shift_ptr = mb_plane->quant_shift; - const int16_t *scan = scan_order->scan; - - memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); - memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); - - // Pre-scan pass - for (i = (int)n_coeffs - 1; i >= 0; i--) { - const int rc = scan[i]; - const int coeff = coeff_ptr[rc]; - - if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0]) - non_zero_count--; - else - break; - } - - // Quantization pass: All coefficients with index >= zero_flag are - // skippable. Note: zero_flag can be zero. - for (i = 0; i < non_zero_count; i++) { - const int rc = scan[i]; - const int coeff = coeff_ptr[rc]; - const int coeff_sign = (coeff >> 31); - const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; - - if (abs_coeff >= zbins[rc != 0]) { - int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX); - tmp = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) * - quant_shift_ptr[rc != 0]) >> - 16; // quantization - qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; - dqcoeff_ptr[rc] = (tran_low_t)(qcoeff_ptr[rc] * dequant_ptr[rc != 0]); - - if (tmp) eob = i; - } - } - *eob_ptr = eob + 1; -} - -#if CONFIG_VP9_HIGHBITDEPTH -void vpx_highbd_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - int i, non_zero_count = (int)n_coeffs, eob = -1; - const int zbins[2] = { mb_plane->zbin[0], mb_plane->zbin[1] }; - const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 }; - const int16_t *round_ptr = mb_plane->round; - const int16_t *quant_ptr = mb_plane->quant; - const int16_t *quant_shift_ptr = mb_plane->quant_shift; - const int16_t *scan = scan_order->scan; - - memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); - memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); - - // Pre-scan pass - for (i = (int)n_coeffs - 1; i >= 0; i--) { - const int rc = scan[i]; - const int coeff = coeff_ptr[rc]; - - if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0]) - non_zero_count--; - else - break; - } - - // Quantization pass: All coefficients with index >= zero_flag are - // skippable. Note: zero_flag can be zero. - for (i = 0; i < non_zero_count; i++) { - const int rc = scan[i]; - const int coeff = coeff_ptr[rc]; - const int coeff_sign = (coeff >> 31); - const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; - - if (abs_coeff >= zbins[rc != 0]) { - const int64_t tmp1 = abs_coeff + round_ptr[rc != 0]; - const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1; - const int abs_qcoeff = (int)((tmp2 * quant_shift_ptr[rc != 0]) >> 16); - qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign); - dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0]; - if (abs_qcoeff) eob = i; - } - } - *eob_ptr = eob + 1; -} -#endif - -void vpx_quantize_b_32x32_c(const tran_low_t *coeff_ptr, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - const int n_coeffs = 32 * 32; - const int zbins[2] = { ROUND_POWER_OF_TWO(mb_plane->zbin[0], 1), - ROUND_POWER_OF_TWO(mb_plane->zbin[1], 1) }; - const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 }; - const int16_t *round_ptr = mb_plane->round; - const int16_t *quant_ptr = mb_plane->quant; - const int16_t *quant_shift_ptr = mb_plane->quant_shift; - const int16_t *scan = scan_order->scan; - - int idx = 0; - int idx_arr[32 * 32 /* n_coeffs */]; - int i, eob = -1; - - memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); - memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); - - // Pre-scan pass - for (i = 0; i < n_coeffs; i++) { - const int rc = scan[i]; - const int coeff = coeff_ptr[rc]; - - // If the coefficient is out of the base ZBIN range, keep it for - // quantization. - if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0]) idx_arr[idx++] = i; - } - - // Quantization pass: only process the coefficients selected in - // pre-scan pass. Note: idx can be zero. - for (i = 0; i < idx; i++) { - const int rc = scan[idx_arr[i]]; - const int coeff = coeff_ptr[rc]; - const int coeff_sign = (coeff >> 31); - int tmp; - int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; - abs_coeff += ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1); - abs_coeff = clamp(abs_coeff, INT16_MIN, INT16_MAX); - tmp = ((((abs_coeff * quant_ptr[rc != 0]) >> 16) + abs_coeff) * - quant_shift_ptr[rc != 0]) >> - 15; - - qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; -#if (VPX_ARCH_X86 || VPX_ARCH_X86_64) && !CONFIG_VP9_HIGHBITDEPTH - // When tran_low_t is only 16 bits dqcoeff can outrange it. Rather than - // truncating with a cast, saturate the value. This is easier to implement - // on x86 and preserves the sign of the value. - dqcoeff_ptr[rc] = - clamp(qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2, INT16_MIN, INT16_MAX); -#else - dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2; -#endif // VPX_ARCH_X86 && CONFIG_VP9_HIGHBITDEPTH - - if (tmp) eob = idx_arr[i]; - } - *eob_ptr = eob + 1; -} - -#if CONFIG_VP9_HIGHBITDEPTH -void vpx_highbd_quantize_b_32x32_c( - const tran_low_t *coeff_ptr, const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, - uint16_t *eob_ptr, const struct ScanOrder *const scan_order) { - const intptr_t n_coeffs = 32 * 32; - const int zbins[2] = { ROUND_POWER_OF_TWO(mb_plane->zbin[0], 1), - ROUND_POWER_OF_TWO(mb_plane->zbin[1], 1) }; - const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 }; - const int16_t *round_ptr = mb_plane->round; - const int16_t *quant_ptr = mb_plane->quant; - const int16_t *quant_shift_ptr = mb_plane->quant_shift; - const int16_t *scan = scan_order->scan; - - int idx = 0; - int idx_arr[1024]; - int i, eob = -1; - - memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); - memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); - - // Pre-scan pass - for (i = 0; i < n_coeffs; i++) { - const int rc = scan[i]; - const int coeff = coeff_ptr[rc]; - - // If the coefficient is out of the base ZBIN range, keep it for - // quantization. - if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0]) idx_arr[idx++] = i; - } - - // Quantization pass: only process the coefficients selected in - // pre-scan pass. Note: idx can be zero. - for (i = 0; i < idx; i++) { - const int rc = scan[idx_arr[i]]; - const int coeff = coeff_ptr[rc]; - const int coeff_sign = (coeff >> 31); - const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; - const int64_t tmp1 = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1); - const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1; - const int abs_qcoeff = (int)((tmp2 * quant_shift_ptr[rc != 0]) >> 15); - qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign); - dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2; - if (abs_qcoeff) eob = idx_arr[i]; - } - *eob_ptr = eob + 1; -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/quantize.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/quantize.h deleted file mode 100644 index 8e138445..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/quantize.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_QUANTIZE_H_ -#define VPX_VPX_DSP_QUANTIZE_H_ - -#include "./vpx_config.h" -#include "vpx_dsp/vpx_dsp_common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vpx_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, - const int16_t *round_ptr, const int16_t quant, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t dequant, uint16_t *eob_ptr); -void vpx_quantize_dc_32x32(const tran_low_t *coeff_ptr, - const int16_t *round_ptr, const int16_t quant, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t dequant, uint16_t *eob_ptr); - -#if CONFIG_VP9_HIGHBITDEPTH -void vpx_highbd_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, - const int16_t *round_ptr, const int16_t quant, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t dequant, uint16_t *eob_ptr); -void vpx_highbd_quantize_dc_32x32(const tran_low_t *coeff_ptr, - const int16_t *round_ptr, const int16_t quant, - tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, - const int16_t dequant, uint16_t *eob_ptr); -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_QUANTIZE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/sad.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/sad.c deleted file mode 100644 index 2a4c81d5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/sad.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx/vpx_integer.h" -#include "vpx_ports/mem.h" - -/* Sum the difference between every corresponding element of the buffers. */ -static INLINE unsigned int sad(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - int width, int height) { - int y, x; - unsigned int sad = 0; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) sad += abs(src_ptr[x] - ref_ptr[x]); - - src_ptr += src_stride; - ref_ptr += ref_stride; - } - return sad; -} - -#define sadMxN(m, n) \ - unsigned int vpx_sad##m##x##n##_c(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *ref_ptr, int ref_stride) { \ - return sad(src_ptr, src_stride, ref_ptr, ref_stride, m, n); \ - } \ - unsigned int vpx_sad##m##x##n##_avg_c( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, const uint8_t *second_pred) { \ - DECLARE_ALIGNED(32, uint8_t, comp_pred[m * n]); \ - vpx_comp_avg_pred_c(comp_pred, second_pred, m, n, ref_ptr, ref_stride); \ - return sad(src_ptr, src_stride, comp_pred, m, m, n); \ - } \ - unsigned int vpx_sad_skip_##m##x##n##_c( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride) { \ - return 2 * sad(src_ptr, 2 * src_stride, ref_ptr, 2 * ref_stride, (m), \ - (n / 2)); \ - } - -// Compare |src_ptr| to 4 distinct references in |ref_array[4]| -#define sadMxNx4D(m, n) \ - void vpx_sad##m##x##n##x4d_c(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *const ref_array[4], \ - int ref_stride, uint32_t sad_array[4]) { \ - int i; \ - for (i = 0; i < 4; ++i) \ - sad_array[i] = \ - vpx_sad##m##x##n##_c(src_ptr, src_stride, ref_array[i], ref_stride); \ - } \ - void vpx_sad_skip_##m##x##n##x4d_c(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *const ref_array[4], \ - int ref_stride, uint32_t sad_array[4]) { \ - int i; \ - for (i = 0; i < 4; ++i) { \ - sad_array[i] = 2 * sad(src_ptr, 2 * src_stride, ref_array[i], \ - 2 * ref_stride, (m), (n / 2)); \ - } \ - } - -/* clang-format off */ -// 64x64 -sadMxN(64, 64) -sadMxNx4D(64, 64) - -// 64x32 -sadMxN(64, 32) -sadMxNx4D(64, 32) - -// 32x64 -sadMxN(32, 64) -sadMxNx4D(32, 64) - -// 32x32 -sadMxN(32, 32) -sadMxNx4D(32, 32) - -// 32x16 -sadMxN(32, 16) -sadMxNx4D(32, 16) - -// 16x32 -sadMxN(16, 32) -sadMxNx4D(16, 32) - -// 16x16 -sadMxN(16, 16) -sadMxNx4D(16, 16) - -// 16x8 -sadMxN(16, 8) -sadMxNx4D(16, 8) - -// 8x16 -sadMxN(8, 16) -sadMxNx4D(8, 16) - -// 8x8 -sadMxN(8, 8) -sadMxNx4D(8, 8) - -// 8x4 -sadMxN(8, 4) -sadMxNx4D(8, 4) - -// 4x8 -sadMxN(4, 8) -sadMxNx4D(4, 8) - -// 4x4 -sadMxN(4, 4) -sadMxNx4D(4, 4) -/* clang-format on */ - -#if CONFIG_VP9_HIGHBITDEPTH - static INLINE - unsigned int highbd_sad(const uint8_t *src8_ptr, int src_stride, - const uint8_t *ref8_ptr, int ref_stride, int width, - int height) { - int y, x; - unsigned int sad = 0; - const uint16_t *src = CONVERT_TO_SHORTPTR(src8_ptr); - const uint16_t *ref_ptr = CONVERT_TO_SHORTPTR(ref8_ptr); - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) sad += abs(src[x] - ref_ptr[x]); - - src += src_stride; - ref_ptr += ref_stride; - } - return sad; -} - -static INLINE unsigned int highbd_sadb(const uint8_t *src8_ptr, int src_stride, - const uint16_t *ref_ptr, int ref_stride, - int width, int height) { - int y, x; - unsigned int sad = 0; - const uint16_t *src = CONVERT_TO_SHORTPTR(src8_ptr); - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) sad += abs(src[x] - ref_ptr[x]); - - src += src_stride; - ref_ptr += ref_stride; - } - return sad; -} - -#define highbd_sadMxN(m, n) \ - unsigned int vpx_highbd_sad##m##x##n##_c( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride) { \ - return highbd_sad(src_ptr, src_stride, ref_ptr, ref_stride, m, n); \ - } \ - unsigned int vpx_highbd_sad##m##x##n##_avg_c( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, const uint8_t *second_pred) { \ - DECLARE_ALIGNED(16, uint16_t, comp_pred[m * n]); \ - vpx_highbd_comp_avg_pred_c(comp_pred, CONVERT_TO_SHORTPTR(second_pred), m, \ - n, CONVERT_TO_SHORTPTR(ref_ptr), ref_stride); \ - return highbd_sadb(src_ptr, src_stride, comp_pred, m, m, n); \ - } \ - unsigned int vpx_highbd_sad_skip_##m##x##n##_c( \ - const uint8_t *src, int src_stride, const uint8_t *ref, \ - int ref_stride) { \ - return 2 * \ - highbd_sad(src, 2 * src_stride, ref, 2 * ref_stride, (m), (n / 2)); \ - } - -#define highbd_sadMxNx4D(m, n) \ - void vpx_highbd_sad##m##x##n##x4d_c(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *const ref_array[4], \ - int ref_stride, uint32_t sad_array[4]) { \ - int i; \ - for (i = 0; i < 4; ++i) { \ - sad_array[i] = vpx_highbd_sad##m##x##n##_c(src_ptr, src_stride, \ - ref_array[i], ref_stride); \ - } \ - } \ - void vpx_highbd_sad_skip_##m##x##n##x4d_c( \ - const uint8_t *src, int src_stride, const uint8_t *const ref_array[4], \ - int ref_stride, uint32_t sad_array[4]) { \ - int i; \ - for (i = 0; i < 4; ++i) { \ - sad_array[i] = vpx_highbd_sad_skip_##m##x##n##_c( \ - src, src_stride, ref_array[i], ref_stride); \ - } \ - } - -/* clang-format off */ -// 64x64 -highbd_sadMxN(64, 64) -highbd_sadMxNx4D(64, 64) - -// 64x32 -highbd_sadMxN(64, 32) -highbd_sadMxNx4D(64, 32) - -// 32x64 -highbd_sadMxN(32, 64) -highbd_sadMxNx4D(32, 64) - -// 32x32 -highbd_sadMxN(32, 32) -highbd_sadMxNx4D(32, 32) - -// 32x16 -highbd_sadMxN(32, 16) -highbd_sadMxNx4D(32, 16) - -// 16x32 -highbd_sadMxN(16, 32) -highbd_sadMxNx4D(16, 32) - -// 16x16 -highbd_sadMxN(16, 16) -highbd_sadMxNx4D(16, 16) - -// 16x8 -highbd_sadMxN(16, 8) -highbd_sadMxNx4D(16, 8) - -// 8x16 -highbd_sadMxN(8, 16) -highbd_sadMxNx4D(8, 16) - -// 8x8 -highbd_sadMxN(8, 8) -highbd_sadMxNx4D(8, 8) - -// 8x4 -highbd_sadMxN(8, 4) -highbd_sadMxNx4D(8, 4) - -// 4x8 -highbd_sadMxN(4, 8) -highbd_sadMxNx4D(4, 8) - -// 4x4 -highbd_sadMxN(4, 4) -highbd_sadMxNx4D(4, 4) -/* clang-format on */ - -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/skin_detection.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/skin_detection.c deleted file mode 100644 index bbbb6c3a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/skin_detection.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_dsp/skin_detection.h" - -#define MODEL_MODE 1 - -// Fixed-point skin color model parameters. -static const int skin_mean[5][2] = { { 7463, 9614 }, - { 6400, 10240 }, - { 7040, 10240 }, - { 8320, 9280 }, - { 6800, 9614 } }; -static const int skin_inv_cov[4] = { 4107, 1663, 1663, 2157 }; // q16 -static const int skin_threshold[6] = { 1570636, 1400000, 800000, - 800000, 800000, 800000 }; // q18 -// Thresholds on luminance. -static const int y_low = 40; -static const int y_high = 220; - -// Evaluates the Mahalanobis distance measure for the input CbCr values. -static int vpx_evaluate_skin_color_difference(const int cb, const int cr, - const int idx) { - const int cb_q6 = cb << 6; - const int cr_q6 = cr << 6; - const int cb_diff_q12 = - (cb_q6 - skin_mean[idx][0]) * (cb_q6 - skin_mean[idx][0]); - const int cbcr_diff_q12 = - (cb_q6 - skin_mean[idx][0]) * (cr_q6 - skin_mean[idx][1]); - const int cr_diff_q12 = - (cr_q6 - skin_mean[idx][1]) * (cr_q6 - skin_mean[idx][1]); - const int cb_diff_q2 = (cb_diff_q12 + (1 << 9)) >> 10; - const int cbcr_diff_q2 = (cbcr_diff_q12 + (1 << 9)) >> 10; - const int cr_diff_q2 = (cr_diff_q12 + (1 << 9)) >> 10; - const int skin_diff = - skin_inv_cov[0] * cb_diff_q2 + skin_inv_cov[1] * cbcr_diff_q2 + - skin_inv_cov[2] * cbcr_diff_q2 + skin_inv_cov[3] * cr_diff_q2; - return skin_diff; -} - -// Checks if the input yCbCr values corresponds to skin color. -int vpx_skin_pixel(const int y, const int cb, const int cr, int motion) { - if (y < y_low || y > y_high) { - return 0; - } else if (MODEL_MODE == 0) { - return (vpx_evaluate_skin_color_difference(cb, cr, 0) < skin_threshold[0]); - } else { - int i = 0; - // Exit on grey. - if (cb == 128 && cr == 128) return 0; - // Exit on very strong cb. - if (cb > 150 && cr < 110) return 0; - for (; i < 5; ++i) { - int skin_color_diff = vpx_evaluate_skin_color_difference(cb, cr, i); - if (skin_color_diff < skin_threshold[i + 1]) { - if (y < 60 && skin_color_diff > 3 * (skin_threshold[i + 1] >> 2)) { - return 0; - } else if (motion == 0 && - skin_color_diff > (skin_threshold[i + 1] >> 1)) { - return 0; - } else { - return 1; - } - } - // Exit if difference is much large than the threshold. - if (skin_color_diff > (skin_threshold[i + 1] << 3)) { - return 0; - } - } - return 0; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/skin_detection.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/skin_detection.h deleted file mode 100644 index 91640c33..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/skin_detection.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_SKIN_DETECTION_H_ -#define VPX_VPX_DSP_SKIN_DETECTION_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -int vpx_skin_pixel(const int y, const int cb, const int cr, int motion); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_SKIN_DETECTION_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/sse.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/sse.c deleted file mode 100644 index c9d75185..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/sse.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * Sum the square of the difference between every corresponding element of the - * buffers. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx/vpx_integer.h" -#include "vpx_ports/mem.h" - -int64_t vpx_sse_c(const uint8_t *a, int a_stride, const uint8_t *b, - int b_stride, int width, int height) { - int y, x; - int64_t sse = 0; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - const int32_t diff = abs(a[x] - b[x]); - sse += diff * diff; - } - - a += a_stride; - b += b_stride; - } - return sse; -} - -#if CONFIG_VP9_HIGHBITDEPTH -int64_t vpx_highbd_sse_c(const uint8_t *a8, int a_stride, const uint8_t *b8, - int b_stride, int width, int height) { - int y, x; - int64_t sse = 0; - uint16_t *a = CONVERT_TO_SHORTPTR(a8); - uint16_t *b = CONVERT_TO_SHORTPTR(b8); - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - const int32_t diff = (int32_t)(a[x]) - (int32_t)(b[x]); - sse += diff * diff; - } - - a += a_stride; - b += b_stride; - } - return sse; -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ssim.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ssim.c deleted file mode 100644 index 4a31f3d2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ssim.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/ssim.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/system_state.h" - -void vpx_ssim_parms_8x8_c(const uint8_t *s, int sp, const uint8_t *r, int rp, - uint32_t *sum_s, uint32_t *sum_r, uint32_t *sum_sq_s, - uint32_t *sum_sq_r, uint32_t *sum_sxr) { - int i, j; - for (i = 0; i < 8; i++, s += sp, r += rp) { - for (j = 0; j < 8; j++) { - *sum_s += s[j]; - *sum_r += r[j]; - *sum_sq_s += s[j] * s[j]; - *sum_sq_r += r[j] * r[j]; - *sum_sxr += s[j] * r[j]; - } - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -void vpx_highbd_ssim_parms_8x8_c(const uint16_t *s, int sp, const uint16_t *r, - int rp, uint32_t *sum_s, uint32_t *sum_r, - uint32_t *sum_sq_s, uint32_t *sum_sq_r, - uint32_t *sum_sxr) { - int i, j; - for (i = 0; i < 8; i++, s += sp, r += rp) { - for (j = 0; j < 8; j++) { - *sum_s += s[j]; - *sum_r += r[j]; - *sum_sq_s += s[j] * s[j]; - *sum_sq_r += r[j] * r[j]; - *sum_sxr += s[j] * r[j]; - } - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static const int64_t cc1 = 26634; // (64^2*(.01*255)^2 -static const int64_t cc2 = 239708; // (64^2*(.03*255)^2 -static const int64_t cc1_10 = 428658; // (64^2*(.01*1023)^2 -static const int64_t cc2_10 = 3857925; // (64^2*(.03*1023)^2 -static const int64_t cc1_12 = 6868593; // (64^2*(.01*4095)^2 -static const int64_t cc2_12 = 61817334; // (64^2*(.03*4095)^2 - -static double similarity(uint32_t sum_s, uint32_t sum_r, uint32_t sum_sq_s, - uint32_t sum_sq_r, uint32_t sum_sxr, int count, - uint32_t bd) { - double ssim_n, ssim_d; - int64_t c1, c2; - if (bd == 8) { - // scale the constants by number of pixels - c1 = (cc1 * count * count) >> 12; - c2 = (cc2 * count * count) >> 12; - } else if (bd == 10) { - c1 = (cc1_10 * count * count) >> 12; - c2 = (cc2_10 * count * count) >> 12; - } else if (bd == 12) { - c1 = (cc1_12 * count * count) >> 12; - c2 = (cc2_12 * count * count) >> 12; - } else { - c1 = c2 = 0; - assert(0); - } - - ssim_n = (2.0 * sum_s * sum_r + c1) * - (2.0 * count * sum_sxr - 2.0 * sum_s * sum_r + c2); - - ssim_d = ((double)sum_s * sum_s + (double)sum_r * sum_r + c1) * - ((double)count * sum_sq_s - (double)sum_s * sum_s + - (double)count * sum_sq_r - (double)sum_r * sum_r + c2); - - return ssim_n / ssim_d; -} - -static double ssim_8x8(const uint8_t *s, int sp, const uint8_t *r, int rp) { - uint32_t sum_s = 0, sum_r = 0, sum_sq_s = 0, sum_sq_r = 0, sum_sxr = 0; - vpx_ssim_parms_8x8(s, sp, r, rp, &sum_s, &sum_r, &sum_sq_s, &sum_sq_r, - &sum_sxr); - return similarity(sum_s, sum_r, sum_sq_s, sum_sq_r, sum_sxr, 64, 8); -} - -#if CONFIG_VP9_HIGHBITDEPTH -static double highbd_ssim_8x8(const uint16_t *s, int sp, const uint16_t *r, - int rp, uint32_t bd, uint32_t shift) { - uint32_t sum_s = 0, sum_r = 0, sum_sq_s = 0, sum_sq_r = 0, sum_sxr = 0; - vpx_highbd_ssim_parms_8x8(s, sp, r, rp, &sum_s, &sum_r, &sum_sq_s, &sum_sq_r, - &sum_sxr); - return similarity(sum_s >> shift, sum_r >> shift, sum_sq_s >> (2 * shift), - sum_sq_r >> (2 * shift), sum_sxr >> (2 * shift), 64, bd); -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -// We are using a 8x8 moving window with starting location of each 8x8 window -// on the 4x4 pixel grid. Such arrangement allows the windows to overlap -// block boundaries to penalize blocking artifacts. -static double vpx_ssim2(const uint8_t *img1, const uint8_t *img2, - int stride_img1, int stride_img2, int width, - int height) { - int i, j; - int samples = 0; - double ssim_total = 0; - - // sample point start with each 4x4 location - for (i = 0; i <= height - 8; - i += 4, img1 += stride_img1 * 4, img2 += stride_img2 * 4) { - for (j = 0; j <= width - 8; j += 4) { - double v = ssim_8x8(img1 + j, stride_img1, img2 + j, stride_img2); - ssim_total += v; - samples++; - } - } - ssim_total /= samples; - return ssim_total; -} - -#if CONFIG_VP9_HIGHBITDEPTH -static double vpx_highbd_ssim2(const uint8_t *img1, const uint8_t *img2, - int stride_img1, int stride_img2, int width, - int height, uint32_t bd, uint32_t shift) { - int i, j; - int samples = 0; - double ssim_total = 0; - - // sample point start with each 4x4 location - for (i = 0; i <= height - 8; - i += 4, img1 += stride_img1 * 4, img2 += stride_img2 * 4) { - for (j = 0; j <= width - 8; j += 4) { - double v = highbd_ssim_8x8(CONVERT_TO_SHORTPTR(img1 + j), stride_img1, - CONVERT_TO_SHORTPTR(img2 + j), stride_img2, bd, - shift); - ssim_total += v; - samples++; - } - } - ssim_total /= samples; - return ssim_total; -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -double vpx_calc_ssim(const YV12_BUFFER_CONFIG *source, - const YV12_BUFFER_CONFIG *dest, double *weight) { - double a, b, c; - double ssimv; - - a = vpx_ssim2(source->y_buffer, dest->y_buffer, source->y_stride, - dest->y_stride, source->y_crop_width, source->y_crop_height); - - b = vpx_ssim2(source->u_buffer, dest->u_buffer, source->uv_stride, - dest->uv_stride, source->uv_crop_width, source->uv_crop_height); - - c = vpx_ssim2(source->v_buffer, dest->v_buffer, source->uv_stride, - dest->uv_stride, source->uv_crop_width, source->uv_crop_height); - - ssimv = a * .8 + .1 * (b + c); - - *weight = 1; - - return ssimv; -} - -// traditional ssim as per: http://en.wikipedia.org/wiki/Structural_similarity -// -// Re working out the math -> -// -// ssim(x,y) = (2*mean(x)*mean(y) + c1)*(2*cov(x,y)+c2) / -// ((mean(x)^2+mean(y)^2+c1)*(var(x)+var(y)+c2)) -// -// mean(x) = sum(x) / n -// -// cov(x,y) = (n*sum(xi*yi)-sum(x)*sum(y))/(n*n) -// -// var(x) = (n*sum(xi*xi)-sum(xi)*sum(xi))/(n*n) -// -// ssim(x,y) = -// (2*sum(x)*sum(y)/(n*n) + c1)*(2*(n*sum(xi*yi)-sum(x)*sum(y))/(n*n)+c2) / -// (((sum(x)*sum(x)+sum(y)*sum(y))/(n*n) +c1) * -// ((n*sum(xi*xi) - sum(xi)*sum(xi))/(n*n)+ -// (n*sum(yi*yi) - sum(yi)*sum(yi))/(n*n)+c2))) -// -// factoring out n*n -// -// ssim(x,y) = -// (2*sum(x)*sum(y) + n*n*c1)*(2*(n*sum(xi*yi)-sum(x)*sum(y))+n*n*c2) / -// (((sum(x)*sum(x)+sum(y)*sum(y)) + n*n*c1) * -// (n*sum(xi*xi)-sum(xi)*sum(xi)+n*sum(yi*yi)-sum(yi)*sum(yi)+n*n*c2)) -// -// Replace c1 with n*n * c1 for the final step that leads to this code: -// The final step scales by 12 bits so we don't lose precision in the constants. - -static double ssimv_similarity(const Ssimv *sv, int64_t n) { - // Scale the constants by number of pixels. - const int64_t c1 = (cc1 * n * n) >> 12; - const int64_t c2 = (cc2 * n * n) >> 12; - - const double l = 1.0 * (2 * sv->sum_s * sv->sum_r + c1) / - (sv->sum_s * sv->sum_s + sv->sum_r * sv->sum_r + c1); - - // Since these variables are unsigned sums, convert to double so - // math is done in double arithmetic. - const double v = (2.0 * n * sv->sum_sxr - 2 * sv->sum_s * sv->sum_r + c2) / - (n * sv->sum_sq_s - sv->sum_s * sv->sum_s + - n * sv->sum_sq_r - sv->sum_r * sv->sum_r + c2); - - return l * v; -} - -// The first term of the ssim metric is a luminance factor. -// -// (2*mean(x)*mean(y) + c1)/ (mean(x)^2+mean(y)^2+c1) -// -// This luminance factor is super sensitive to the dark side of luminance -// values and completely insensitive on the white side. check out 2 sets -// (1,3) and (250,252) the term gives ( 2*1*3/(1+9) = .60 -// 2*250*252/ (250^2+252^2) => .99999997 -// -// As a result in this tweaked version of the calculation in which the -// luminance is taken as percentage off from peak possible. -// -// 255 * 255 - (sum_s - sum_r) / count * (sum_s - sum_r) / count -// -static double ssimv_similarity2(const Ssimv *sv, int64_t n) { - // Scale the constants by number of pixels. - const int64_t c1 = (cc1 * n * n) >> 12; - const int64_t c2 = (cc2 * n * n) >> 12; - - const double mean_diff = (1.0 * sv->sum_s - sv->sum_r) / n; - const double l = (255 * 255 - mean_diff * mean_diff + c1) / (255 * 255 + c1); - - // Since these variables are unsigned, sums convert to double so - // math is done in double arithmetic. - const double v = (2.0 * n * sv->sum_sxr - 2 * sv->sum_s * sv->sum_r + c2) / - (n * sv->sum_sq_s - sv->sum_s * sv->sum_s + - n * sv->sum_sq_r - sv->sum_r * sv->sum_r + c2); - - return l * v; -} -static void ssimv_parms(uint8_t *img1, int img1_pitch, uint8_t *img2, - int img2_pitch, Ssimv *sv) { - vpx_ssim_parms_8x8(img1, img1_pitch, img2, img2_pitch, &sv->sum_s, &sv->sum_r, - &sv->sum_sq_s, &sv->sum_sq_r, &sv->sum_sxr); -} - -double vpx_get_ssim_metrics(uint8_t *img1, int img1_pitch, uint8_t *img2, - int img2_pitch, int width, int height, Ssimv *sv2, - Metrics *m, int do_inconsistency) { - double dssim_total = 0; - double ssim_total = 0; - double ssim2_total = 0; - double inconsistency_total = 0; - int i, j; - int c = 0; - double norm; - double old_ssim_total = 0; - vpx_clear_system_state(); - // We can sample points as frequently as we like start with 1 per 4x4. - for (i = 0; i < height; - i += 4, img1 += img1_pitch * 4, img2 += img2_pitch * 4) { - for (j = 0; j < width; j += 4, ++c) { - Ssimv sv = { 0, 0, 0, 0, 0, 0 }; - double ssim; - double ssim2; - double dssim; - uint32_t var_new; - uint32_t var_old; - uint32_t mean_new; - uint32_t mean_old; - double ssim_new; - double ssim_old; - - // Not sure there's a great way to handle the edge pixels - // in ssim when using a window. Seems biased against edge pixels - // however you handle this. This uses only samples that are - // fully in the frame. - if (j + 8 <= width && i + 8 <= height) { - ssimv_parms(img1 + j, img1_pitch, img2 + j, img2_pitch, &sv); - } - - ssim = ssimv_similarity(&sv, 64); - ssim2 = ssimv_similarity2(&sv, 64); - - sv.ssim = ssim2; - - // dssim is calculated to use as an actual error metric and - // is scaled up to the same range as sum square error. - // Since we are subsampling every 16th point maybe this should be - // *16 ? - dssim = 255 * 255 * (1 - ssim2) / 2; - - // Here I introduce a new error metric: consistency-weighted - // SSIM-inconsistency. This metric isolates frames where the - // SSIM 'suddenly' changes, e.g. if one frame in every 8 is much - // sharper or blurrier than the others. Higher values indicate a - // temporally inconsistent SSIM. There are two ideas at work: - // - // 1) 'SSIM-inconsistency': the total inconsistency value - // reflects how much SSIM values are changing between this - // source / reference frame pair and the previous pair. - // - // 2) 'consistency-weighted': weights de-emphasize areas in the - // frame where the scene content has changed. Changes in scene - // content are detected via changes in local variance and local - // mean. - // - // Thus the overall measure reflects how inconsistent the SSIM - // values are, over consistent regions of the frame. - // - // The metric has three terms: - // - // term 1 -> uses change in scene Variance to weight error score - // 2 * var(Fi)*var(Fi-1) / (var(Fi)^2+var(Fi-1)^2) - // larger changes from one frame to the next mean we care - // less about consistency. - // - // term 2 -> uses change in local scene luminance to weight error - // 2 * avg(Fi)*avg(Fi-1) / (avg(Fi)^2+avg(Fi-1)^2) - // larger changes from one frame to the next mean we care - // less about consistency. - // - // term3 -> measures inconsistency in ssim scores between frames - // 1 - ( 2 * ssim(Fi)*ssim(Fi-1)/(ssim(Fi)^2+sssim(Fi-1)^2). - // - // This term compares the ssim score for the same location in 2 - // subsequent frames. - var_new = sv.sum_sq_s - sv.sum_s * sv.sum_s / 64; - var_old = sv2[c].sum_sq_s - sv2[c].sum_s * sv2[c].sum_s / 64; - mean_new = sv.sum_s; - mean_old = sv2[c].sum_s; - ssim_new = sv.ssim; - ssim_old = sv2[c].ssim; - - if (do_inconsistency) { - // We do the metric once for every 4x4 block in the image. Since - // we are scaling the error to SSE for use in a psnr calculation - // 1.0 = 4x4x255x255 the worst error we can possibly have. - static const double kScaling = 4. * 4 * 255 * 255; - - // The constants have to be non 0 to avoid potential divide by 0 - // issues other than that they affect kind of a weighting between - // the terms. No testing of what the right terms should be has been - // done. - static const double c1 = 1, c2 = 1, c3 = 1; - - // This measures how much consistent variance is in two consecutive - // source frames. 1.0 means they have exactly the same variance. - const double variance_term = - (2.0 * var_old * var_new + c1) / - (1.0 * var_old * var_old + 1.0 * var_new * var_new + c1); - - // This measures how consistent the local mean are between two - // consecutive frames. 1.0 means they have exactly the same mean. - const double mean_term = - (2.0 * mean_old * mean_new + c2) / - (1.0 * mean_old * mean_old + 1.0 * mean_new * mean_new + c2); - - // This measures how consistent the ssims of two - // consecutive frames is. 1.0 means they are exactly the same. - double ssim_term = - pow((2.0 * ssim_old * ssim_new + c3) / - (ssim_old * ssim_old + ssim_new * ssim_new + c3), - 5); - - double this_inconsistency; - - // Floating point math sometimes makes this > 1 by a tiny bit. - // We want the metric to scale between 0 and 1.0 so we can convert - // it to an snr scaled value. - if (ssim_term > 1) ssim_term = 1; - - // This converts the consistency metric to an inconsistency metric - // ( so we can scale it like psnr to something like sum square error. - // The reason for the variance and mean terms is the assumption that - // if there are big changes in the source we shouldn't penalize - // inconsistency in ssim scores a bit less as it will be less visible - // to the user. - this_inconsistency = (1 - ssim_term) * variance_term * mean_term; - - this_inconsistency *= kScaling; - inconsistency_total += this_inconsistency; - } - sv2[c] = sv; - ssim_total += ssim; - ssim2_total += ssim2; - dssim_total += dssim; - - old_ssim_total += ssim_old; - } - old_ssim_total += 0; - } - - norm = 1. / (width / 4) / (height / 4); - ssim_total *= norm; - ssim2_total *= norm; - m->ssim2 = ssim2_total; - m->ssim = ssim_total; - if (old_ssim_total == 0) inconsistency_total = 0; - - m->ssimc = inconsistency_total; - - m->dssim = dssim_total; - return inconsistency_total; -} - -#if CONFIG_VP9_HIGHBITDEPTH -double vpx_highbd_calc_ssim(const YV12_BUFFER_CONFIG *source, - const YV12_BUFFER_CONFIG *dest, double *weight, - uint32_t bd, uint32_t in_bd) { - double a, b, c; - double ssimv; - uint32_t shift = 0; - - assert(bd >= in_bd); - shift = bd - in_bd; - - a = vpx_highbd_ssim2(source->y_buffer, dest->y_buffer, source->y_stride, - dest->y_stride, source->y_crop_width, - source->y_crop_height, in_bd, shift); - - b = vpx_highbd_ssim2(source->u_buffer, dest->u_buffer, source->uv_stride, - dest->uv_stride, source->uv_crop_width, - source->uv_crop_height, in_bd, shift); - - c = vpx_highbd_ssim2(source->v_buffer, dest->v_buffer, source->uv_stride, - dest->uv_stride, source->uv_crop_width, - source->uv_crop_height, in_bd, shift); - - ssimv = a * .8 + .1 * (b + c); - - *weight = 1; - - return ssimv; -} - -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ssim.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ssim.h deleted file mode 100644 index c382237f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/ssim.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_SSIM_H_ -#define VPX_VPX_DSP_SSIM_H_ - -#define MAX_SSIM_DB 100.0; - -#ifdef __cplusplus -extern "C" { -#endif - -#include "./vpx_config.h" -#include "vpx_scale/yv12config.h" - -// metrics used for calculating ssim, ssim2, dssim, and ssimc -typedef struct { - // source sum ( over 8x8 region ) - uint32_t sum_s; - - // reference sum (over 8x8 region ) - uint32_t sum_r; - - // source sum squared ( over 8x8 region ) - uint32_t sum_sq_s; - - // reference sum squared (over 8x8 region ) - uint32_t sum_sq_r; - - // sum of source times reference (over 8x8 region) - uint32_t sum_sxr; - - // calculated ssim score between source and reference - double ssim; -} Ssimv; - -// metrics collected on a frame basis -typedef struct { - // ssim consistency error metric ( see code for explanation ) - double ssimc; - - // standard ssim - double ssim; - - // revised ssim ( see code for explanation) - double ssim2; - - // ssim restated as an error metric like sse - double dssim; - - // dssim converted to decibels - double dssimd; - - // ssimc converted to decibels - double ssimcd; -} Metrics; - -double vpx_get_ssim_metrics(uint8_t *img1, int img1_pitch, uint8_t *img2, - int img2_pitch, int width, int height, Ssimv *sv2, - Metrics *m, int do_inconsistency); - -double vpx_calc_ssim(const YV12_BUFFER_CONFIG *source, - const YV12_BUFFER_CONFIG *dest, double *weight); - -double vpx_calc_fastssim(const YV12_BUFFER_CONFIG *source, - const YV12_BUFFER_CONFIG *dest, double *ssim_y, - double *ssim_u, double *ssim_v, uint32_t bd, - uint32_t in_bd); - -#if CONFIG_VP9_HIGHBITDEPTH -double vpx_highbd_calc_ssim(const YV12_BUFFER_CONFIG *source, - const YV12_BUFFER_CONFIG *dest, double *weight, - uint32_t bd, uint32_t in_bd); -#endif // CONFIG_VP9_HIGHBITDEPTH - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_SSIM_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/subtract.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/subtract.c deleted file mode 100644 index 45c819e6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/subtract.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx/vpx_integer.h" -#include "vpx_ports/mem.h" - -void vpx_subtract_block_c(int rows, int cols, int16_t *diff_ptr, - ptrdiff_t diff_stride, const uint8_t *src_ptr, - ptrdiff_t src_stride, const uint8_t *pred_ptr, - ptrdiff_t pred_stride) { - int r, c; - - for (r = 0; r < rows; r++) { - for (c = 0; c < cols; c++) diff_ptr[c] = src_ptr[c] - pred_ptr[c]; - - diff_ptr += diff_stride; - pred_ptr += pred_stride; - src_ptr += src_stride; - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -void vpx_highbd_subtract_block_c(int rows, int cols, int16_t *diff_ptr, - ptrdiff_t diff_stride, const uint8_t *src8_ptr, - ptrdiff_t src_stride, const uint8_t *pred8_ptr, - ptrdiff_t pred_stride, int bd) { - int r, c; - uint16_t *src = CONVERT_TO_SHORTPTR(src8_ptr); - uint16_t *pred = CONVERT_TO_SHORTPTR(pred8_ptr); - (void)bd; - - for (r = 0; r < rows; r++) { - for (c = 0; c < cols; c++) { - diff_ptr[c] = src[c] - pred[c]; - } - - diff_ptr += diff_stride; - pred += pred_stride; - src += src_stride; - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/sum_squares.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/sum_squares.c deleted file mode 100644 index b80cd588..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/sum_squares.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" - -uint64_t vpx_sum_squares_2d_i16_c(const int16_t *src, int stride, int size) { - int r, c; - uint64_t ss = 0; - - for (r = 0; r < size; r++) { - for (c = 0; c < size; c++) { - const int16_t v = src[c]; - ss += v * v; - } - src += stride; - } - - return ss; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/txfm_common.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/txfm_common.h deleted file mode 100644 index 25f4fdb3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/txfm_common.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_TXFM_COMMON_H_ -#define VPX_VPX_DSP_TXFM_COMMON_H_ - -#include "vpx_dsp/vpx_dsp_common.h" - -// Constants and Macros used by all idct/dct functions -#define DCT_CONST_BITS 14 -#define DCT_CONST_ROUNDING (1 << (DCT_CONST_BITS - 1)) - -#define UNIT_QUANT_SHIFT 2 -#define UNIT_QUANT_FACTOR (1 << UNIT_QUANT_SHIFT) - -// Constants: -// for (int i = 1; i< 32; ++i) -// printf("static const int cospi_%d_64 = %.0f;\n", i, -// round(16384 * cos(i*M_PI/64))); -// Note: sin(k*Pi/64) = cos((32-k)*Pi/64) -static const tran_coef_t cospi_1_64 = 16364; -static const tran_coef_t cospi_2_64 = 16305; -static const tran_coef_t cospi_3_64 = 16207; -static const tran_coef_t cospi_4_64 = 16069; -static const tran_coef_t cospi_5_64 = 15893; -static const tran_coef_t cospi_6_64 = 15679; -static const tran_coef_t cospi_7_64 = 15426; -static const tran_coef_t cospi_8_64 = 15137; -static const tran_coef_t cospi_9_64 = 14811; -static const tran_coef_t cospi_10_64 = 14449; -static const tran_coef_t cospi_11_64 = 14053; -static const tran_coef_t cospi_12_64 = 13623; -static const tran_coef_t cospi_13_64 = 13160; -static const tran_coef_t cospi_14_64 = 12665; -static const tran_coef_t cospi_15_64 = 12140; -static const tran_coef_t cospi_16_64 = 11585; -static const tran_coef_t cospi_17_64 = 11003; -static const tran_coef_t cospi_18_64 = 10394; -static const tran_coef_t cospi_19_64 = 9760; -static const tran_coef_t cospi_20_64 = 9102; -static const tran_coef_t cospi_21_64 = 8423; -static const tran_coef_t cospi_22_64 = 7723; -static const tran_coef_t cospi_23_64 = 7005; -static const tran_coef_t cospi_24_64 = 6270; -static const tran_coef_t cospi_25_64 = 5520; -static const tran_coef_t cospi_26_64 = 4756; -static const tran_coef_t cospi_27_64 = 3981; -static const tran_coef_t cospi_28_64 = 3196; -static const tran_coef_t cospi_29_64 = 2404; -static const tran_coef_t cospi_30_64 = 1606; -static const tran_coef_t cospi_31_64 = 804; - -// 16384 * sqrt(2) * sin(kPi/9) * 2 / 3 -static const tran_coef_t sinpi_1_9 = 5283; -static const tran_coef_t sinpi_2_9 = 9929; -static const tran_coef_t sinpi_3_9 = 13377; -static const tran_coef_t sinpi_4_9 = 15212; - -#endif // VPX_VPX_DSP_TXFM_COMMON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/variance.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/variance.c deleted file mode 100644 index 1c476542..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/variance.c +++ /dev/null @@ -1,566 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx_ports/mem.h" -#include "vpx/vpx_integer.h" - -#include "vpx_dsp/variance.h" - -static const uint8_t bilinear_filters[8][2] = { - { 128, 0 }, { 112, 16 }, { 96, 32 }, { 80, 48 }, - { 64, 64 }, { 48, 80 }, { 32, 96 }, { 16, 112 }, -}; - -uint32_t vpx_get4x4sse_cs_c(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride) { - int distortion = 0; - int r, c; - - for (r = 0; r < 4; ++r) { - for (c = 0; c < 4; ++c) { - int diff = src_ptr[c] - ref_ptr[c]; - distortion += diff * diff; - } - - src_ptr += src_stride; - ref_ptr += ref_stride; - } - - return distortion; -} - -uint32_t vpx_get_mb_ss_c(const int16_t *src_ptr) { - unsigned int i, sum = 0; - - for (i = 0; i < 256; ++i) { - sum += src_ptr[i] * src_ptr[i]; - } - - return sum; -} - -static void variance(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, int w, int h, - uint32_t *sse, int *sum) { - int i, j; - - *sum = 0; - *sse = 0; - - for (i = 0; i < h; ++i) { - for (j = 0; j < w; ++j) { - const int diff = src_ptr[j] - ref_ptr[j]; - *sum += diff; - *sse += diff * diff; - } - - src_ptr += src_stride; - ref_ptr += ref_stride; - } -} - -// Applies a 1-D 2-tap bilinear filter to the source block in either horizontal -// or vertical direction to produce the filtered output block. Used to implement -// the first-pass of 2-D separable filter. -// -// Produces int16_t output to retain precision for the next pass. Two filter -// taps should sum to FILTER_WEIGHT. pixel_step defines whether the filter is -// applied horizontally (pixel_step = 1) or vertically (pixel_step = stride). -// It defines the offset required to move from one input to the next. -static void var_filter_block2d_bil_first_pass( - const uint8_t *src_ptr, uint16_t *ref_ptr, unsigned int src_pixels_per_line, - int pixel_step, unsigned int output_height, unsigned int output_width, - const uint8_t *filter) { - unsigned int i, j; - - for (i = 0; i < output_height; ++i) { - for (j = 0; j < output_width; ++j) { - ref_ptr[j] = ROUND_POWER_OF_TWO( - (int)src_ptr[0] * filter[0] + (int)src_ptr[pixel_step] * filter[1], - FILTER_BITS); - - ++src_ptr; - } - - src_ptr += src_pixels_per_line - output_width; - ref_ptr += output_width; - } -} - -// Applies a 1-D 2-tap bilinear filter to the source block in either horizontal -// or vertical direction to produce the filtered output block. Used to implement -// the second-pass of 2-D separable filter. -// -// Requires 16-bit input as produced by filter_block2d_bil_first_pass. Two -// filter taps should sum to FILTER_WEIGHT. pixel_step defines whether the -// filter is applied horizontally (pixel_step = 1) or vertically -// (pixel_step = stride). It defines the offset required to move from one input -// to the next. Output is 8-bit. -static void var_filter_block2d_bil_second_pass( - const uint16_t *src_ptr, uint8_t *ref_ptr, unsigned int src_pixels_per_line, - unsigned int pixel_step, unsigned int output_height, - unsigned int output_width, const uint8_t *filter) { - unsigned int i, j; - - for (i = 0; i < output_height; ++i) { - for (j = 0; j < output_width; ++j) { - ref_ptr[j] = ROUND_POWER_OF_TWO( - (int)src_ptr[0] * filter[0] + (int)src_ptr[pixel_step] * filter[1], - FILTER_BITS); - ++src_ptr; - } - - src_ptr += src_pixels_per_line - output_width; - ref_ptr += output_width; - } -} - -#define VAR(W, H) \ - uint32_t vpx_variance##W##x##H##_c(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *ref_ptr, int ref_stride, \ - uint32_t *sse) { \ - int sum; \ - variance(src_ptr, src_stride, ref_ptr, ref_stride, W, H, sse, &sum); \ - return *sse - (uint32_t)(((int64_t)sum * sum) / (W * H)); \ - } - -#define SUBPIX_VAR(W, H) \ - uint32_t vpx_sub_pixel_variance##W##x##H##_c( \ - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref_ptr, int ref_stride, uint32_t *sse) { \ - uint16_t fdata3[(H + 1) * W]; \ - uint8_t temp2[H * W]; \ - \ - var_filter_block2d_bil_first_pass(src_ptr, fdata3, src_stride, 1, H + 1, \ - W, bilinear_filters[x_offset]); \ - var_filter_block2d_bil_second_pass(fdata3, temp2, W, W, H, W, \ - bilinear_filters[y_offset]); \ - \ - return vpx_variance##W##x##H##_c(temp2, W, ref_ptr, ref_stride, sse); \ - } - -#define SUBPIX_AVG_VAR(W, H) \ - uint32_t vpx_sub_pixel_avg_variance##W##x##H##_c( \ - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, \ - const uint8_t *second_pred) { \ - uint16_t fdata3[(H + 1) * W]; \ - uint8_t temp2[H * W]; \ - DECLARE_ALIGNED(32, uint8_t, temp3[H * W]); \ - \ - var_filter_block2d_bil_first_pass(src_ptr, fdata3, src_stride, 1, H + 1, \ - W, bilinear_filters[x_offset]); \ - var_filter_block2d_bil_second_pass(fdata3, temp2, W, W, H, W, \ - bilinear_filters[y_offset]); \ - \ - vpx_comp_avg_pred_c(temp3, second_pred, W, H, temp2, W); \ - \ - return vpx_variance##W##x##H##_c(temp3, W, ref_ptr, ref_stride, sse); \ - } - -/* Identical to the variance call except it takes an additional parameter, sum, - * and returns that value using pass-by-reference instead of returning - * sse - sum^2 / w*h - */ -#define GET_VAR(W, H) \ - void vpx_get##W##x##H##var_c(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *ref_ptr, int ref_stride, \ - uint32_t *sse, int *sum) { \ - variance(src_ptr, src_stride, ref_ptr, ref_stride, W, H, sse, sum); \ - } - -/* Identical to the variance call except it does not calculate the - * sse - sum^2 / w*h and returns sse in addition to modifying the passed in - * variable. - */ -#define MSE(W, H) \ - uint32_t vpx_mse##W##x##H##_c(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *ref_ptr, int ref_stride, \ - uint32_t *sse) { \ - int sum; \ - variance(src_ptr, src_stride, ref_ptr, ref_stride, W, H, sse, &sum); \ - return *sse; \ - } - -/* All three forms of the variance are available in the same sizes. */ -#define VARIANCES(W, H) \ - VAR(W, H) \ - SUBPIX_VAR(W, H) \ - SUBPIX_AVG_VAR(W, H) - -VARIANCES(64, 64) -VARIANCES(64, 32) -VARIANCES(32, 64) -VARIANCES(32, 32) -VARIANCES(32, 16) -VARIANCES(16, 32) -VARIANCES(16, 16) -VARIANCES(16, 8) -VARIANCES(8, 16) -VARIANCES(8, 8) -VARIANCES(8, 4) -VARIANCES(4, 8) -VARIANCES(4, 4) - -GET_VAR(16, 16) -GET_VAR(8, 8) - -MSE(16, 16) -MSE(16, 8) -MSE(8, 16) -MSE(8, 8) - -void vpx_comp_avg_pred_c(uint8_t *comp_pred, const uint8_t *pred, int width, - int height, const uint8_t *ref, int ref_stride) { - int i, j; - - for (i = 0; i < height; ++i) { - for (j = 0; j < width; ++j) { - const int tmp = pred[j] + ref[j]; - comp_pred[j] = ROUND_POWER_OF_TWO(tmp, 1); - } - comp_pred += width; - pred += width; - ref += ref_stride; - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -static void highbd_variance64(const uint8_t *src8_ptr, int src_stride, - const uint8_t *ref8_ptr, int ref_stride, int w, - int h, uint64_t *sse, int64_t *sum) { - int i, j; - - uint16_t *src_ptr = CONVERT_TO_SHORTPTR(src8_ptr); - uint16_t *ref_ptr = CONVERT_TO_SHORTPTR(ref8_ptr); - *sum = 0; - *sse = 0; - - for (i = 0; i < h; ++i) { - for (j = 0; j < w; ++j) { - const int diff = src_ptr[j] - ref_ptr[j]; - *sum += diff; - *sse += diff * diff; - } - src_ptr += src_stride; - ref_ptr += ref_stride; - } -} - -static void highbd_8_variance(const uint8_t *src8_ptr, int src_stride, - const uint8_t *ref8_ptr, int ref_stride, int w, - int h, uint32_t *sse, int *sum) { - uint64_t sse_long = 0; - int64_t sum_long = 0; - highbd_variance64(src8_ptr, src_stride, ref8_ptr, ref_stride, w, h, &sse_long, - &sum_long); - *sse = (uint32_t)sse_long; - *sum = (int)sum_long; -} - -static void highbd_10_variance(const uint8_t *src8_ptr, int src_stride, - const uint8_t *ref8_ptr, int ref_stride, int w, - int h, uint32_t *sse, int *sum) { - uint64_t sse_long = 0; - int64_t sum_long = 0; - highbd_variance64(src8_ptr, src_stride, ref8_ptr, ref_stride, w, h, &sse_long, - &sum_long); - *sse = (uint32_t)ROUND_POWER_OF_TWO(sse_long, 4); - *sum = (int)ROUND_POWER_OF_TWO(sum_long, 2); -} - -static void highbd_12_variance(const uint8_t *src8_ptr, int src_stride, - const uint8_t *ref8_ptr, int ref_stride, int w, - int h, uint32_t *sse, int *sum) { - uint64_t sse_long = 0; - int64_t sum_long = 0; - highbd_variance64(src8_ptr, src_stride, ref8_ptr, ref_stride, w, h, &sse_long, - &sum_long); - *sse = (uint32_t)ROUND_POWER_OF_TWO(sse_long, 8); - *sum = (int)ROUND_POWER_OF_TWO(sum_long, 4); -} - -#define HIGHBD_VAR(W, H) \ - uint32_t vpx_highbd_8_variance##W##x##H##_c( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - int sum; \ - highbd_8_variance(src_ptr, src_stride, ref_ptr, ref_stride, W, H, sse, \ - &sum); \ - return *sse - (uint32_t)(((int64_t)sum * sum) / (W * H)); \ - } \ - \ - uint32_t vpx_highbd_10_variance##W##x##H##_c( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - int sum; \ - int64_t var; \ - highbd_10_variance(src_ptr, src_stride, ref_ptr, ref_stride, W, H, sse, \ - &sum); \ - var = (int64_t)(*sse) - (((int64_t)sum * sum) / (W * H)); \ - return (var >= 0) ? (uint32_t)var : 0; \ - } \ - \ - uint32_t vpx_highbd_12_variance##W##x##H##_c( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - int sum; \ - int64_t var; \ - highbd_12_variance(src_ptr, src_stride, ref_ptr, ref_stride, W, H, sse, \ - &sum); \ - var = (int64_t)(*sse) - (((int64_t)sum * sum) / (W * H)); \ - return (var >= 0) ? (uint32_t)var : 0; \ - } - -#define HIGHBD_GET_VAR(S) \ - void vpx_highbd_8_get##S##x##S##var_c( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse, int *sum) { \ - highbd_8_variance(src_ptr, src_stride, ref_ptr, ref_stride, S, S, sse, \ - sum); \ - } \ - \ - void vpx_highbd_10_get##S##x##S##var_c( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse, int *sum) { \ - highbd_10_variance(src_ptr, src_stride, ref_ptr, ref_stride, S, S, sse, \ - sum); \ - } \ - \ - void vpx_highbd_12_get##S##x##S##var_c( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse, int *sum) { \ - highbd_12_variance(src_ptr, src_stride, ref_ptr, ref_stride, S, S, sse, \ - sum); \ - } - -#define HIGHBD_MSE(W, H) \ - uint32_t vpx_highbd_8_mse##W##x##H##_c( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - int sum; \ - highbd_8_variance(src_ptr, src_stride, ref_ptr, ref_stride, W, H, sse, \ - &sum); \ - return *sse; \ - } \ - \ - uint32_t vpx_highbd_10_mse##W##x##H##_c( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - int sum; \ - highbd_10_variance(src_ptr, src_stride, ref_ptr, ref_stride, W, H, sse, \ - &sum); \ - return *sse; \ - } \ - \ - uint32_t vpx_highbd_12_mse##W##x##H##_c( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, uint32_t *sse) { \ - int sum; \ - highbd_12_variance(src_ptr, src_stride, ref_ptr, ref_stride, W, H, sse, \ - &sum); \ - return *sse; \ - } - -static void highbd_var_filter_block2d_bil_first_pass( - const uint8_t *src_ptr8, uint16_t *output_ptr, - unsigned int src_pixels_per_line, int pixel_step, - unsigned int output_height, unsigned int output_width, - const uint8_t *filter) { - unsigned int i, j; - uint16_t *src_ptr = CONVERT_TO_SHORTPTR(src_ptr8); - for (i = 0; i < output_height; ++i) { - for (j = 0; j < output_width; ++j) { - output_ptr[j] = ROUND_POWER_OF_TWO( - (int)src_ptr[0] * filter[0] + (int)src_ptr[pixel_step] * filter[1], - FILTER_BITS); - - ++src_ptr; - } - - // Next row... - src_ptr += src_pixels_per_line - output_width; - output_ptr += output_width; - } -} - -static void highbd_var_filter_block2d_bil_second_pass( - const uint16_t *src_ptr, uint16_t *output_ptr, - unsigned int src_pixels_per_line, unsigned int pixel_step, - unsigned int output_height, unsigned int output_width, - const uint8_t *filter) { - unsigned int i, j; - - for (i = 0; i < output_height; ++i) { - for (j = 0; j < output_width; ++j) { - output_ptr[j] = ROUND_POWER_OF_TWO( - (int)src_ptr[0] * filter[0] + (int)src_ptr[pixel_step] * filter[1], - FILTER_BITS); - ++src_ptr; - } - - src_ptr += src_pixels_per_line - output_width; - output_ptr += output_width; - } -} - -#define HIGHBD_SUBPIX_VAR(W, H) \ - uint32_t vpx_highbd_8_sub_pixel_variance##W##x##H##_c( \ - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref_ptr, int ref_stride, uint32_t *sse) { \ - uint16_t fdata3[(H + 1) * W]; \ - uint16_t temp2[H * W]; \ - \ - highbd_var_filter_block2d_bil_first_pass( \ - src_ptr, fdata3, src_stride, 1, H + 1, W, bilinear_filters[x_offset]); \ - highbd_var_filter_block2d_bil_second_pass(fdata3, temp2, W, W, H, W, \ - bilinear_filters[y_offset]); \ - \ - return vpx_highbd_8_variance##W##x##H##_c(CONVERT_TO_BYTEPTR(temp2), W, \ - ref_ptr, ref_stride, sse); \ - } \ - \ - uint32_t vpx_highbd_10_sub_pixel_variance##W##x##H##_c( \ - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref_ptr, int ref_stride, uint32_t *sse) { \ - uint16_t fdata3[(H + 1) * W]; \ - uint16_t temp2[H * W]; \ - \ - highbd_var_filter_block2d_bil_first_pass( \ - src_ptr, fdata3, src_stride, 1, H + 1, W, bilinear_filters[x_offset]); \ - highbd_var_filter_block2d_bil_second_pass(fdata3, temp2, W, W, H, W, \ - bilinear_filters[y_offset]); \ - \ - return vpx_highbd_10_variance##W##x##H##_c(CONVERT_TO_BYTEPTR(temp2), W, \ - ref_ptr, ref_stride, sse); \ - } \ - \ - uint32_t vpx_highbd_12_sub_pixel_variance##W##x##H##_c( \ - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref_ptr, int ref_stride, uint32_t *sse) { \ - uint16_t fdata3[(H + 1) * W]; \ - uint16_t temp2[H * W]; \ - \ - highbd_var_filter_block2d_bil_first_pass( \ - src_ptr, fdata3, src_stride, 1, H + 1, W, bilinear_filters[x_offset]); \ - highbd_var_filter_block2d_bil_second_pass(fdata3, temp2, W, W, H, W, \ - bilinear_filters[y_offset]); \ - \ - return vpx_highbd_12_variance##W##x##H##_c(CONVERT_TO_BYTEPTR(temp2), W, \ - ref_ptr, ref_stride, sse); \ - } - -#define HIGHBD_SUBPIX_AVG_VAR(W, H) \ - uint32_t vpx_highbd_8_sub_pixel_avg_variance##W##x##H##_c( \ - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, \ - const uint8_t *second_pred) { \ - uint16_t fdata3[(H + 1) * W]; \ - uint16_t temp2[H * W]; \ - DECLARE_ALIGNED(16, uint16_t, temp3[H * W]); \ - \ - highbd_var_filter_block2d_bil_first_pass( \ - src_ptr, fdata3, src_stride, 1, H + 1, W, bilinear_filters[x_offset]); \ - highbd_var_filter_block2d_bil_second_pass(fdata3, temp2, W, W, H, W, \ - bilinear_filters[y_offset]); \ - \ - vpx_highbd_comp_avg_pred_c(temp3, CONVERT_TO_SHORTPTR(second_pred), W, H, \ - temp2, W); \ - \ - return vpx_highbd_8_variance##W##x##H##_c(CONVERT_TO_BYTEPTR(temp3), W, \ - ref_ptr, ref_stride, sse); \ - } \ - \ - uint32_t vpx_highbd_10_sub_pixel_avg_variance##W##x##H##_c( \ - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, \ - const uint8_t *second_pred) { \ - uint16_t fdata3[(H + 1) * W]; \ - uint16_t temp2[H * W]; \ - DECLARE_ALIGNED(16, uint16_t, temp3[H * W]); \ - \ - highbd_var_filter_block2d_bil_first_pass( \ - src_ptr, fdata3, src_stride, 1, H + 1, W, bilinear_filters[x_offset]); \ - highbd_var_filter_block2d_bil_second_pass(fdata3, temp2, W, W, H, W, \ - bilinear_filters[y_offset]); \ - \ - vpx_highbd_comp_avg_pred_c(temp3, CONVERT_TO_SHORTPTR(second_pred), W, H, \ - temp2, W); \ - \ - return vpx_highbd_10_variance##W##x##H##_c(CONVERT_TO_BYTEPTR(temp3), W, \ - ref_ptr, ref_stride, sse); \ - } \ - \ - uint32_t vpx_highbd_12_sub_pixel_avg_variance##W##x##H##_c( \ - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, \ - const uint8_t *second_pred) { \ - uint16_t fdata3[(H + 1) * W]; \ - uint16_t temp2[H * W]; \ - DECLARE_ALIGNED(16, uint16_t, temp3[H * W]); \ - \ - highbd_var_filter_block2d_bil_first_pass( \ - src_ptr, fdata3, src_stride, 1, H + 1, W, bilinear_filters[x_offset]); \ - highbd_var_filter_block2d_bil_second_pass(fdata3, temp2, W, W, H, W, \ - bilinear_filters[y_offset]); \ - \ - vpx_highbd_comp_avg_pred_c(temp3, CONVERT_TO_SHORTPTR(second_pred), W, H, \ - temp2, W); \ - \ - return vpx_highbd_12_variance##W##x##H##_c(CONVERT_TO_BYTEPTR(temp3), W, \ - ref_ptr, ref_stride, sse); \ - } - -/* All three forms of the variance are available in the same sizes. */ -#define HIGHBD_VARIANCES(W, H) \ - HIGHBD_VAR(W, H) \ - HIGHBD_SUBPIX_VAR(W, H) \ - HIGHBD_SUBPIX_AVG_VAR(W, H) - -HIGHBD_VARIANCES(64, 64) -HIGHBD_VARIANCES(64, 32) -HIGHBD_VARIANCES(32, 64) -HIGHBD_VARIANCES(32, 32) -HIGHBD_VARIANCES(32, 16) -HIGHBD_VARIANCES(16, 32) -HIGHBD_VARIANCES(16, 16) -HIGHBD_VARIANCES(16, 8) -HIGHBD_VARIANCES(8, 16) -HIGHBD_VARIANCES(8, 8) -HIGHBD_VARIANCES(8, 4) -HIGHBD_VARIANCES(4, 8) -HIGHBD_VARIANCES(4, 4) - -HIGHBD_GET_VAR(8) -HIGHBD_GET_VAR(16) - -HIGHBD_MSE(16, 16) -HIGHBD_MSE(16, 8) -HIGHBD_MSE(8, 16) -HIGHBD_MSE(8, 8) - -void vpx_highbd_comp_avg_pred_c(uint16_t *comp_pred, const uint16_t *pred, - int width, int height, const uint16_t *ref, - int ref_stride) { - int i, j; - for (i = 0; i < height; ++i) { - for (j = 0; j < width; ++j) { - const int tmp = pred[j] + ref[j]; - comp_pred[j] = ROUND_POWER_OF_TWO(tmp, 1); - } - comp_pred += width; - pred += width; - ref += ref_stride; - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/variance.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/variance.h deleted file mode 100644 index ccdb2f90..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/variance.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_VARIANCE_H_ -#define VPX_VPX_DSP_VARIANCE_H_ - -#include "./vpx_config.h" - -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define FILTER_BITS 7 -#define FILTER_WEIGHT 128 - -typedef unsigned int (*vpx_sad_fn_t)(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride); - -typedef unsigned int (*vpx_sad_avg_fn_t)(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - const uint8_t *second_pred); - -typedef void (*vp8_copy32xn_fn_t)(const uint8_t *src_ptr, int src_stride, - uint8_t *ref_ptr, int ref_stride, int n); - -typedef void (*vpx_sad_multi_fn_t)(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sad_array); - -typedef void (*vpx_sad_multi_d_fn_t)(const uint8_t *src_ptr, int src_stride, - const uint8_t *const b_array[], - int ref_stride, unsigned int *sad_array); - -typedef unsigned int (*vpx_variance_fn_t)(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, unsigned int *sse); - -typedef unsigned int (*vpx_subpixvariance_fn_t)( - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, - const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); - -typedef unsigned int (*vpx_subp_avg_variance_fn_t)( - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, - const uint8_t *ref_ptr, int ref_stride, unsigned int *sse, - const uint8_t *second_pred); - -#if CONFIG_VP8 -typedef struct variance_vtable { - vpx_sad_fn_t sdf; - vpx_variance_fn_t vf; - vpx_subpixvariance_fn_t svf; - vpx_sad_multi_d_fn_t sdx4df; -#if VPX_ARCH_X86 || VPX_ARCH_X86_64 - vp8_copy32xn_fn_t copymem; -#endif -} vp8_variance_fn_ptr_t; -#endif // CONFIG_VP8 - -#if CONFIG_VP9 -typedef struct vp9_variance_vtable { - vpx_sad_fn_t sdf; - // Same as normal sad, but downsample the rows by a factor of 2. - vpx_sad_fn_t sdsf; - vpx_sad_avg_fn_t sdaf; - vpx_variance_fn_t vf; - vpx_subpixvariance_fn_t svf; - vpx_subp_avg_variance_fn_t svaf; - vpx_sad_multi_d_fn_t sdx4df; - // Same as sadx4, but downsample the rows by a factor of 2. - vpx_sad_multi_d_fn_t sdsx4df; -} vp9_variance_fn_ptr_t; -#endif // CONFIG_VP9 - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_VARIANCE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_convolve.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_convolve.c deleted file mode 100644 index e55a963f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_convolve.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/vpx_convolve.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_ports/mem.h" - -static void convolve_horiz(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *x_filters, int x0_q4, - int x_step_q4, int w, int h) { - int x, y; - src -= SUBPEL_TAPS / 2 - 1; - - for (y = 0; y < h; ++y) { - int x_q4 = x0_q4; - for (x = 0; x < w; ++x) { - const uint8_t *const src_x = &src[x_q4 >> SUBPEL_BITS]; - const int16_t *const x_filter = x_filters[x_q4 & SUBPEL_MASK]; - int k, sum = 0; - for (k = 0; k < SUBPEL_TAPS; ++k) sum += src_x[k] * x_filter[k]; - dst[x] = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)); - x_q4 += x_step_q4; - } - src += src_stride; - dst += dst_stride; - } -} - -static void convolve_avg_horiz(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *x_filters, int x0_q4, - int x_step_q4, int w, int h) { - int x, y; - src -= SUBPEL_TAPS / 2 - 1; - - for (y = 0; y < h; ++y) { - int x_q4 = x0_q4; - for (x = 0; x < w; ++x) { - const uint8_t *const src_x = &src[x_q4 >> SUBPEL_BITS]; - const int16_t *const x_filter = x_filters[x_q4 & SUBPEL_MASK]; - int k, sum = 0; - for (k = 0; k < SUBPEL_TAPS; ++k) sum += src_x[k] * x_filter[k]; - dst[x] = ROUND_POWER_OF_TWO( - dst[x] + clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)), 1); - x_q4 += x_step_q4; - } - src += src_stride; - dst += dst_stride; - } -} - -static void convolve_vert(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *y_filters, int y0_q4, - int y_step_q4, int w, int h) { - int x, y; - src -= src_stride * (SUBPEL_TAPS / 2 - 1); - - for (x = 0; x < w; ++x) { - int y_q4 = y0_q4; - for (y = 0; y < h; ++y) { - const uint8_t *src_y = &src[(y_q4 >> SUBPEL_BITS) * src_stride]; - const int16_t *const y_filter = y_filters[y_q4 & SUBPEL_MASK]; - int k, sum = 0; - for (k = 0; k < SUBPEL_TAPS; ++k) - sum += src_y[k * src_stride] * y_filter[k]; - dst[y * dst_stride] = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)); - y_q4 += y_step_q4; - } - ++src; - ++dst; - } -} - -static void convolve_avg_vert(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *y_filters, int y0_q4, - int y_step_q4, int w, int h) { - int x, y; - src -= src_stride * (SUBPEL_TAPS / 2 - 1); - - for (x = 0; x < w; ++x) { - int y_q4 = y0_q4; - for (y = 0; y < h; ++y) { - const uint8_t *src_y = &src[(y_q4 >> SUBPEL_BITS) * src_stride]; - const int16_t *const y_filter = y_filters[y_q4 & SUBPEL_MASK]; - int k, sum = 0; - for (k = 0; k < SUBPEL_TAPS; ++k) - sum += src_y[k * src_stride] * y_filter[k]; - dst[y * dst_stride] = ROUND_POWER_OF_TWO( - dst[y * dst_stride] + - clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)), - 1); - y_q4 += y_step_q4; - } - ++src; - ++dst; - } -} - -void vpx_convolve8_horiz_c(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, int x_step_q4, - int y0_q4, int y_step_q4, int w, int h) { - (void)y0_q4; - (void)y_step_q4; - convolve_horiz(src, src_stride, dst, dst_stride, filter, x0_q4, x_step_q4, w, - h); -} - -void vpx_convolve8_avg_horiz_c(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - (void)y0_q4; - (void)y_step_q4; - convolve_avg_horiz(src, src_stride, dst, dst_stride, filter, x0_q4, x_step_q4, - w, h); -} - -void vpx_convolve8_vert_c(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, int x_step_q4, - int y0_q4, int y_step_q4, int w, int h) { - (void)x0_q4; - (void)x_step_q4; - convolve_vert(src, src_stride, dst, dst_stride, filter, y0_q4, y_step_q4, w, - h); -} - -void vpx_convolve8_avg_vert_c(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - (void)x0_q4; - (void)x_step_q4; - convolve_avg_vert(src, src_stride, dst, dst_stride, filter, y0_q4, y_step_q4, - w, h); -} - -void vpx_convolve8_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, - int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - // Note: Fixed size intermediate buffer, temp, places limits on parameters. - // 2d filtering proceeds in 2 steps: - // (1) Interpolate horizontally into an intermediate buffer, temp. - // (2) Interpolate temp vertically to derive the sub-pixel result. - // Deriving the maximum number of rows in the temp buffer (135): - // --Smallest scaling factor is x1/2 ==> y_step_q4 = 32 (Normative). - // --Largest block size is 64x64 pixels. - // --64 rows in the downscaled frame span a distance of (64 - 1) * 32 in the - // original frame (in 1/16th pixel units). - // --Must round-up because block may be located at sub-pixel position. - // --Require an additional SUBPEL_TAPS rows for the 8-tap filter tails. - // --((64 - 1) * 32 + 15) >> 4 + 8 = 135. - // When calling in frame scaling function, the smallest scaling factor is x1/4 - // ==> y_step_q4 = 64. Since w and h are at most 16, the temp buffer is still - // big enough. - uint8_t temp[64 * 135]; - const int intermediate_height = - (((h - 1) * y_step_q4 + y0_q4) >> SUBPEL_BITS) + SUBPEL_TAPS; - - assert(w <= 64); - assert(h <= 64); - assert(y_step_q4 <= 32 || (y_step_q4 <= 64 && h <= 32)); - assert(x_step_q4 <= 64); - - convolve_horiz(src - src_stride * (SUBPEL_TAPS / 2 - 1), src_stride, temp, 64, - filter, x0_q4, x_step_q4, w, intermediate_height); - convolve_vert(temp + 64 * (SUBPEL_TAPS / 2 - 1), 64, dst, dst_stride, filter, - y0_q4, y_step_q4, w, h); -} - -void vpx_convolve8_avg_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, - int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - // Fixed size intermediate buffer places limits on parameters. - DECLARE_ALIGNED(16, uint8_t, temp[64 * 64]); - assert(w <= 64); - assert(h <= 64); - - vpx_convolve8_c(src, src_stride, temp, 64, filter, x0_q4, x_step_q4, y0_q4, - y_step_q4, w, h); - vpx_convolve_avg_c(temp, 64, dst, dst_stride, NULL, 0, 0, 0, 0, w, h); -} - -void vpx_convolve_copy_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, - int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - int r; - - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - for (r = h; r > 0; --r) { - memcpy(dst, src, w); - src += src_stride; - dst += dst_stride; - } -} - -void vpx_convolve_avg_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, - int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - int x, y; - - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - - for (y = 0; y < h; ++y) { - for (x = 0; x < w; ++x) dst[x] = ROUND_POWER_OF_TWO(dst[x] + src[x], 1); - src += src_stride; - dst += dst_stride; - } -} - -void vpx_scaled_horiz_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, - int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - vpx_convolve8_horiz_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); -} - -void vpx_scaled_vert_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, - int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - vpx_convolve8_vert_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); -} - -void vpx_scaled_2d_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, - int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - vpx_convolve8_c(src, src_stride, dst, dst_stride, filter, x0_q4, x_step_q4, - y0_q4, y_step_q4, w, h); -} - -void vpx_scaled_avg_horiz_c(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h) { - vpx_convolve8_avg_horiz_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); -} - -void vpx_scaled_avg_vert_c(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, int x_step_q4, - int y0_q4, int y_step_q4, int w, int h) { - vpx_convolve8_avg_vert_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); -} - -void vpx_scaled_avg_2d_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, - int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - vpx_convolve8_avg_c(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, y0_q4, y_step_q4, w, h); -} - -#if CONFIG_VP9_HIGHBITDEPTH -static void highbd_convolve_horiz(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *x_filters, int x0_q4, - int x_step_q4, int w, int h, int bd) { - int x, y; - src -= SUBPEL_TAPS / 2 - 1; - - for (y = 0; y < h; ++y) { - int x_q4 = x0_q4; - for (x = 0; x < w; ++x) { - const uint16_t *const src_x = &src[x_q4 >> SUBPEL_BITS]; - const int16_t *const x_filter = x_filters[x_q4 & SUBPEL_MASK]; - int k, sum = 0; - for (k = 0; k < SUBPEL_TAPS; ++k) sum += src_x[k] * x_filter[k]; - dst[x] = clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd); - x_q4 += x_step_q4; - } - src += src_stride; - dst += dst_stride; - } -} - -static void highbd_convolve_avg_horiz(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *x_filters, int x0_q4, - int x_step_q4, int w, int h, int bd) { - int x, y; - src -= SUBPEL_TAPS / 2 - 1; - - for (y = 0; y < h; ++y) { - int x_q4 = x0_q4; - for (x = 0; x < w; ++x) { - const uint16_t *const src_x = &src[x_q4 >> SUBPEL_BITS]; - const int16_t *const x_filter = x_filters[x_q4 & SUBPEL_MASK]; - int k, sum = 0; - for (k = 0; k < SUBPEL_TAPS; ++k) sum += src_x[k] * x_filter[k]; - dst[x] = ROUND_POWER_OF_TWO( - dst[x] + clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd), - 1); - x_q4 += x_step_q4; - } - src += src_stride; - dst += dst_stride; - } -} - -static void highbd_convolve_vert(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *y_filters, int y0_q4, - int y_step_q4, int w, int h, int bd) { - int x, y; - src -= src_stride * (SUBPEL_TAPS / 2 - 1); - - for (x = 0; x < w; ++x) { - int y_q4 = y0_q4; - for (y = 0; y < h; ++y) { - const uint16_t *src_y = &src[(y_q4 >> SUBPEL_BITS) * src_stride]; - const int16_t *const y_filter = y_filters[y_q4 & SUBPEL_MASK]; - int k, sum = 0; - for (k = 0; k < SUBPEL_TAPS; ++k) - sum += src_y[k * src_stride] * y_filter[k]; - dst[y * dst_stride] = - clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd); - y_q4 += y_step_q4; - } - ++src; - ++dst; - } -} - -static void highbd_convolve_avg_vert(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *y_filters, int y0_q4, - int y_step_q4, int w, int h, int bd) { - int x, y; - src -= src_stride * (SUBPEL_TAPS / 2 - 1); - - for (x = 0; x < w; ++x) { - int y_q4 = y0_q4; - for (y = 0; y < h; ++y) { - const uint16_t *src_y = &src[(y_q4 >> SUBPEL_BITS) * src_stride]; - const int16_t *const y_filter = y_filters[y_q4 & SUBPEL_MASK]; - int k, sum = 0; - for (k = 0; k < SUBPEL_TAPS; ++k) - sum += src_y[k * src_stride] * y_filter[k]; - dst[y * dst_stride] = ROUND_POWER_OF_TWO( - dst[y * dst_stride] + - clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd), - 1); - y_q4 += y_step_q4; - } - ++src; - ++dst; - } -} - -static void highbd_convolve(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h, int bd) { - // Note: Fixed size intermediate buffer, temp, places limits on parameters. - // 2d filtering proceeds in 2 steps: - // (1) Interpolate horizontally into an intermediate buffer, temp. - // (2) Interpolate temp vertically to derive the sub-pixel result. - // Deriving the maximum number of rows in the temp buffer (135): - // --Smallest scaling factor is x1/2 ==> y_step_q4 = 32 (Normative). - // --Largest block size is 64x64 pixels. - // --64 rows in the downscaled frame span a distance of (64 - 1) * 32 in the - // original frame (in 1/16th pixel units). - // --Must round-up because block may be located at sub-pixel position. - // --Require an additional SUBPEL_TAPS rows for the 8-tap filter tails. - // --((64 - 1) * 32 + 15) >> 4 + 8 = 135. - uint16_t temp[64 * 135]; - const int intermediate_height = - (((h - 1) * y_step_q4 + y0_q4) >> SUBPEL_BITS) + SUBPEL_TAPS; - - assert(w <= 64); - assert(h <= 64); - assert(y_step_q4 <= 32); - assert(x_step_q4 <= 32); - - highbd_convolve_horiz(src - src_stride * (SUBPEL_TAPS / 2 - 1), src_stride, - temp, 64, filter, x0_q4, x_step_q4, w, - intermediate_height, bd); - highbd_convolve_vert(temp + 64 * (SUBPEL_TAPS / 2 - 1), 64, dst, dst_stride, - filter, y0_q4, y_step_q4, w, h, bd); -} - -void vpx_highbd_convolve8_horiz_c(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd) { - (void)y0_q4; - (void)y_step_q4; - - highbd_convolve_horiz(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, w, h, bd); -} - -void vpx_highbd_convolve8_avg_horiz_c(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd) { - (void)y0_q4; - (void)y_step_q4; - - highbd_convolve_avg_horiz(src, src_stride, dst, dst_stride, filter, x0_q4, - x_step_q4, w, h, bd); -} - -void vpx_highbd_convolve8_vert_c(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h, int bd) { - (void)x0_q4; - (void)x_step_q4; - - highbd_convolve_vert(src, src_stride, dst, dst_stride, filter, y0_q4, - y_step_q4, w, h, bd); -} - -void vpx_highbd_convolve8_avg_vert_c(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd) { - (void)x0_q4; - (void)x_step_q4; - - highbd_convolve_avg_vert(src, src_stride, dst, dst_stride, filter, y0_q4, - y_step_q4, w, h, bd); -} - -void vpx_highbd_convolve8_c(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h, int bd) { - highbd_convolve(src, src_stride, dst, dst_stride, filter, x0_q4, x_step_q4, - y0_q4, y_step_q4, w, h, bd); -} - -void vpx_highbd_convolve8_avg_c(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h, int bd) { - // Fixed size intermediate buffer places limits on parameters. - DECLARE_ALIGNED(16, uint16_t, temp[64 * 64]); - assert(w <= 64); - assert(h <= 64); - - vpx_highbd_convolve8_c(src, src_stride, temp, 64, filter, x0_q4, x_step_q4, - y0_q4, y_step_q4, w, h, bd); - vpx_highbd_convolve_avg_c(temp, 64, dst, dst_stride, NULL, 0, 0, 0, 0, w, h, - bd); -} - -void vpx_highbd_convolve_copy_c(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h, int bd) { - int r; - - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - (void)bd; - - for (r = h; r > 0; --r) { - memcpy(dst, src, w * sizeof(uint16_t)); - src += src_stride; - dst += dst_stride; - } -} - -void vpx_highbd_convolve_avg_c(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h, int bd) { - int x, y; - - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - (void)bd; - - for (y = 0; y < h; ++y) { - for (x = 0; x < w; ++x) dst[x] = ROUND_POWER_OF_TWO(dst[x] + src[x], 1); - src += src_stride; - dst += dst_stride; - } -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_convolve.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_convolve.h deleted file mode 100644 index d5793e17..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_convolve.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_VPX_DSP_VPX_CONVOLVE_H_ -#define VPX_VPX_DSP_VPX_CONVOLVE_H_ - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*convolve_fn_t)(const uint8_t *src, ptrdiff_t src_stride, - uint8_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, int w, - int h); - -#if CONFIG_VP9_HIGHBITDEPTH -typedef void (*highbd_convolve_fn_t)(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd); -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_VPX_CONVOLVE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_dsp.mk b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_dsp.mk deleted file mode 100644 index e3de5bc8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_dsp.mk +++ /dev/null @@ -1,487 +0,0 @@ -## -## Copyright (c) 2015 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -DSP_SRCS-yes += vpx_dsp.mk -DSP_SRCS-yes += vpx_dsp_common.h - -DSP_SRCS-$(HAVE_MSA) += mips/macros_msa.h - -DSP_SRCS-$(HAVE_AVX2) += x86/bitdepth_conversion_avx2.h -DSP_SRCS-$(HAVE_SSE2) += x86/bitdepth_conversion_sse2.h -# This file is included in libs.mk. Including it here would cause it to be -# compiled into an object. Even as an empty file, this would create an -# executable section on the stack. -#DSP_SRCS-$(HAVE_SSE2) += x86/bitdepth_conversion_sse2$(ASM) - -# bit reader -DSP_SRCS-yes += prob.h -DSP_SRCS-yes += prob.c - -ifeq ($(CONFIG_ENCODERS),yes) -DSP_SRCS-yes += bitwriter.h -DSP_SRCS-yes += bitwriter.c -DSP_SRCS-yes += bitwriter_buffer.c -DSP_SRCS-yes += bitwriter_buffer.h -DSP_SRCS-yes += psnr.c -DSP_SRCS-yes += psnr.h -DSP_SRCS-yes += sse.c -DSP_SRCS-$(CONFIG_INTERNAL_STATS) += ssim.c -DSP_SRCS-$(CONFIG_INTERNAL_STATS) += ssim.h -DSP_SRCS-$(CONFIG_INTERNAL_STATS) += psnrhvs.c -DSP_SRCS-$(CONFIG_INTERNAL_STATS) += fastssim.c -DSP_SRCS-$(HAVE_NEON) += arm/sse_neon.c -DSP_SRCS-$(HAVE_NEON_DOTPROD) += arm/sse_neon_dotprod.c -DSP_SRCS-$(HAVE_SSE4_1) += x86/sse_sse4.c -DSP_SRCS-$(HAVE_AVX2) += x86/sse_avx2.c -endif - -ifeq ($(CONFIG_DECODERS),yes) -DSP_SRCS-yes += bitreader.h -DSP_SRCS-yes += bitreader.c -DSP_SRCS-yes += bitreader_buffer.c -DSP_SRCS-yes += bitreader_buffer.h -endif - -# intra predictions -DSP_SRCS-yes += intrapred.c - -DSP_SRCS-$(HAVE_SSE2) += x86/intrapred_sse2.asm -DSP_SRCS-$(HAVE_SSSE3) += x86/intrapred_ssse3.asm -DSP_SRCS-$(HAVE_VSX) += ppc/intrapred_vsx.c - -ifeq ($(CONFIG_VP9_HIGHBITDEPTH),yes) -DSP_SRCS-$(HAVE_SSE2) += x86/highbd_intrapred_sse2.asm -DSP_SRCS-$(HAVE_SSE2) += x86/highbd_intrapred_intrin_sse2.c -DSP_SRCS-$(HAVE_SSSE3) += x86/highbd_intrapred_intrin_ssse3.c -DSP_SRCS-$(HAVE_NEON) += arm/highbd_intrapred_neon.c -endif # CONFIG_VP9_HIGHBITDEPTH - -ifneq ($(filter yes,$(CONFIG_POSTPROC) $(CONFIG_VP9_POSTPROC)),) -DSP_SRCS-yes += add_noise.c -DSP_SRCS-yes += deblock.c -DSP_SRCS-yes += postproc.h -DSP_SRCS-$(HAVE_MSA) += mips/add_noise_msa.c -DSP_SRCS-$(HAVE_MSA) += mips/deblock_msa.c -DSP_SRCS-$(HAVE_NEON) += arm/deblock_neon.c -DSP_SRCS-$(HAVE_SSE2) += x86/add_noise_sse2.asm -DSP_SRCS-$(HAVE_SSE2) += x86/deblock_sse2.asm -DSP_SRCS-$(HAVE_SSE2) += x86/post_proc_sse2.c -DSP_SRCS-$(HAVE_VSX) += ppc/deblock_vsx.c -endif # CONFIG_POSTPROC - -DSP_SRCS-$(HAVE_NEON_ASM) += arm/intrapred_neon_asm$(ASM) -DSP_SRCS-$(HAVE_NEON) += arm/intrapred_neon.c -DSP_SRCS-$(HAVE_MSA) += mips/intrapred_msa.c -DSP_SRCS-$(HAVE_LSX) += loongarch/intrapred_lsx.c -DSP_SRCS-$(HAVE_DSPR2) += mips/intrapred4_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/intrapred8_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/intrapred16_dspr2.c - -DSP_SRCS-$(HAVE_DSPR2) += mips/common_dspr2.h -DSP_SRCS-$(HAVE_DSPR2) += mips/common_dspr2.c - -DSP_SRCS-yes += vpx_filter.h -ifeq ($(CONFIG_VP9),yes) -# interpolation filters -DSP_SRCS-yes += vpx_convolve.c -DSP_SRCS-yes += vpx_convolve.h - -DSP_SRCS-$(VPX_ARCH_X86)$(VPX_ARCH_X86_64) += x86/convolve.h - -DSP_SRCS-$(HAVE_SSE2) += x86/convolve_sse2.h -DSP_SRCS-$(HAVE_SSSE3) += x86/convolve_ssse3.h -DSP_SRCS-$(HAVE_AVX2) += x86/convolve_avx2.h -DSP_SRCS-$(HAVE_SSE2) += x86/vpx_subpixel_8t_sse2.asm -DSP_SRCS-$(HAVE_SSE2) += x86/vpx_subpixel_4t_intrin_sse2.c -DSP_SRCS-$(HAVE_SSE2) += x86/vpx_subpixel_bilinear_sse2.asm -DSP_SRCS-$(HAVE_SSSE3) += x86/vpx_subpixel_8t_ssse3.asm -DSP_SRCS-$(HAVE_SSSE3) += x86/vpx_subpixel_bilinear_ssse3.asm -DSP_SRCS-$(HAVE_AVX2) += x86/vpx_subpixel_8t_intrin_avx2.c -DSP_SRCS-$(HAVE_SSSE3) += x86/vpx_subpixel_8t_intrin_ssse3.c -ifeq ($(CONFIG_VP9_HIGHBITDEPTH),yes) -DSP_SRCS-$(HAVE_SSE2) += x86/vpx_high_subpixel_8t_sse2.asm -DSP_SRCS-$(HAVE_SSE2) += x86/vpx_high_subpixel_bilinear_sse2.asm -DSP_SRCS-$(HAVE_AVX2) += x86/highbd_convolve_avx2.c -DSP_SRCS-$(HAVE_NEON) += arm/highbd_vpx_convolve_copy_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/highbd_vpx_convolve_avg_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/highbd_vpx_convolve8_neon.c -DSP_SRCS-$(HAVE_SVE) += arm/highbd_vpx_convolve8_sve.c -DSP_SRCS-$(HAVE_SVE2) += arm/highbd_vpx_convolve8_sve2.c -endif - -DSP_SRCS-$(HAVE_SSE2) += x86/vpx_convolve_copy_sse2.asm -DSP_SRCS-$(HAVE_NEON) += arm/vpx_scaled_convolve8_neon.c - -ifeq ($(HAVE_NEON_ASM),yes) -DSP_SRCS-yes += arm/vpx_convolve_copy_neon_asm$(ASM) -DSP_SRCS-yes += arm/vpx_convolve8_horiz_filter_type2_neon$(ASM) -DSP_SRCS-yes += arm/vpx_convolve8_vert_filter_type2_neon$(ASM) -DSP_SRCS-yes += arm/vpx_convolve8_horiz_filter_type1_neon$(ASM) -DSP_SRCS-yes += arm/vpx_convolve8_vert_filter_type1_neon$(ASM) -DSP_SRCS-yes += arm/vpx_convolve8_avg_horiz_filter_type2_neon$(ASM) -DSP_SRCS-yes += arm/vpx_convolve8_avg_vert_filter_type2_neon$(ASM) -DSP_SRCS-yes += arm/vpx_convolve8_avg_horiz_filter_type1_neon$(ASM) -DSP_SRCS-yes += arm/vpx_convolve8_avg_vert_filter_type1_neon$(ASM) -DSP_SRCS-yes += arm/vpx_convolve_avg_neon_asm$(ASM) -DSP_SRCS-yes += arm/vpx_convolve8_neon_asm.c -DSP_SRCS-yes += arm/vpx_convolve8_neon_asm.h -DSP_SRCS-yes += arm/vpx_convolve_neon.c -else -ifeq ($(HAVE_NEON),yes) -DSP_SRCS-yes += arm/vpx_convolve_copy_neon.c -DSP_SRCS-yes += arm/vpx_convolve8_neon.c -DSP_SRCS-yes += arm/vpx_convolve_avg_neon.c -DSP_SRCS-yes += arm/vpx_convolve_neon.c -DSP_SRCS-$(HAVE_NEON_DOTPROD) += arm/vpx_convolve8_neon_dotprod.c -DSP_SRCS-$(HAVE_NEON_I8MM) += arm/vpx_convolve8_neon_i8mm.c -endif # HAVE_NEON -endif # HAVE_NEON_ASM - -# common (msa) -DSP_SRCS-$(HAVE_MSA) += mips/vpx_convolve8_avg_horiz_msa.c -DSP_SRCS-$(HAVE_MSA) += mips/vpx_convolve8_avg_msa.c -DSP_SRCS-$(HAVE_MSA) += mips/vpx_convolve8_avg_vert_msa.c -DSP_SRCS-$(HAVE_MSA) += mips/vpx_convolve8_horiz_msa.c -DSP_SRCS-$(HAVE_MSA) += mips/vpx_convolve8_msa.c -DSP_SRCS-$(HAVE_MSA) += mips/vpx_convolve8_vert_msa.c -DSP_SRCS-$(HAVE_MSA) += mips/vpx_convolve_avg_msa.c -DSP_SRCS-$(HAVE_MSA) += mips/vpx_convolve_copy_msa.c -DSP_SRCS-$(HAVE_MSA) += mips/vpx_convolve_msa.h -DSP_SRCS-$(HAVE_MMI) += mips/vpx_convolve8_mmi.c - -# common (dspr2) -DSP_SRCS-$(HAVE_DSPR2) += mips/convolve_common_dspr2.h -DSP_SRCS-$(HAVE_DSPR2) += mips/convolve2_avg_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/convolve2_avg_horiz_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/convolve2_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/convolve2_horiz_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/convolve2_vert_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/convolve8_avg_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/convolve8_avg_horiz_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/convolve8_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/convolve8_horiz_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/convolve8_vert_dspr2.c - -DSP_SRCS-$(HAVE_VSX) += ppc/vpx_convolve_vsx.c - -# common (lsx) -DSP_SRCS-$(HAVE_LSX) += loongarch/vpx_convolve8_avg_horiz_lsx.c -DSP_SRCS-$(HAVE_LSX) += loongarch/vpx_convolve8_avg_vert_lsx.c -DSP_SRCS-$(HAVE_LSX) += loongarch/vpx_convolve8_horiz_lsx.c -DSP_SRCS-$(HAVE_LSX) += loongarch/vpx_convolve8_vert_lsx.c -DSP_SRCS-$(HAVE_LSX) += loongarch/vpx_convolve8_lsx.c -DSP_SRCS-$(HAVE_LSX) += loongarch/vpx_convolve8_avg_lsx.c -DSP_SRCS-$(HAVE_LSX) += loongarch/vpx_convolve_avg_lsx.c -DSP_SRCS-$(HAVE_LSX) += loongarch/vpx_convolve_copy_lsx.c -DSP_SRCS-$(HAVE_LSX) += loongarch/vpx_convolve_lsx.h - -# loop filters -DSP_SRCS-yes += loopfilter.c - -DSP_SRCS-$(HAVE_SSE2) += x86/loopfilter_sse2.c -DSP_SRCS-$(HAVE_AVX2) += x86/loopfilter_avx2.c - -ifeq ($(HAVE_NEON_ASM),yes) -DSP_SRCS-yes += arm/loopfilter_16_neon$(ASM) -DSP_SRCS-yes += arm/loopfilter_8_neon$(ASM) -DSP_SRCS-yes += arm/loopfilter_4_neon$(ASM) -else -DSP_SRCS-$(HAVE_NEON) += arm/loopfilter_neon.c -endif # HAVE_NEON_ASM - -DSP_SRCS-$(HAVE_MSA) += mips/loopfilter_msa.h -DSP_SRCS-$(HAVE_MSA) += mips/loopfilter_16_msa.c -DSP_SRCS-$(HAVE_MSA) += mips/loopfilter_8_msa.c -DSP_SRCS-$(HAVE_MSA) += mips/loopfilter_4_msa.c -DSP_SRCS-$(HAVE_DSPR2) += mips/loopfilter_filters_dspr2.h -DSP_SRCS-$(HAVE_DSPR2) += mips/loopfilter_filters_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/loopfilter_macros_dspr2.h -DSP_SRCS-$(HAVE_DSPR2) += mips/loopfilter_masks_dspr2.h -DSP_SRCS-$(HAVE_DSPR2) += mips/loopfilter_mb_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/loopfilter_mb_horiz_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/loopfilter_mb_vert_dspr2.c - -DSP_SRCS-$(HAVE_LSX) += loongarch/loopfilter_lsx.h -DSP_SRCS-$(HAVE_LSX) += loongarch/loopfilter_16_lsx.c -DSP_SRCS-$(HAVE_LSX) += loongarch/loopfilter_8_lsx.c -DSP_SRCS-$(HAVE_LSX) += loongarch/loopfilter_4_lsx.c - -ifeq ($(CONFIG_VP9_HIGHBITDEPTH),yes) -DSP_SRCS-$(HAVE_NEON) += arm/highbd_loopfilter_neon.c -DSP_SRCS-$(HAVE_SSE2) += x86/highbd_loopfilter_sse2.c -endif # CONFIG_VP9_HIGHBITDEPTH -endif # CONFIG_VP9 - -DSP_SRCS-yes += txfm_common.h -DSP_SRCS-$(HAVE_SSE2) += x86/txfm_common_sse2.h -DSP_SRCS-$(HAVE_MSA) += mips/txfm_macros_msa.h -DSP_SRCS-$(HAVE_LSX) += loongarch/txfm_macros_lsx.h -# forward transform -ifeq ($(CONFIG_VP9_ENCODER),yes) -DSP_SRCS-yes += fwd_txfm.c -DSP_SRCS-yes += fwd_txfm.h -DSP_SRCS-$(HAVE_SSE2) += x86/fwd_txfm_sse2.h -DSP_SRCS-$(HAVE_SSE2) += x86/fwd_txfm_sse2.c -DSP_SRCS-$(HAVE_SSE2) += x86/fwd_txfm_impl_sse2.h -DSP_SRCS-$(HAVE_SSE2) += x86/fwd_dct32x32_impl_sse2.h -ifeq ($(VPX_ARCH_X86_64),yes) -DSP_SRCS-$(HAVE_SSSE3) += x86/fwd_txfm_ssse3_x86_64.asm -endif -DSP_SRCS-$(HAVE_AVX2) += x86/fwd_dct32x32_impl_avx2.h -DSP_SRCS-$(HAVE_NEON) += arm/fdct4x4_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/fdct8x8_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/fdct16x16_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/fdct32x32_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/fdct_partial_neon.c -DSP_SRCS-$(HAVE_MSA) += mips/fwd_txfm_msa.h -DSP_SRCS-$(HAVE_MSA) += mips/fwd_txfm_msa.c -DSP_SRCS-$(HAVE_LSX) += loongarch/fwd_txfm_lsx.h -DSP_SRCS-$(HAVE_LSX) += loongarch/fwd_txfm_lsx.c - -ifneq ($(CONFIG_VP9_HIGHBITDEPTH),yes) -DSP_SRCS-$(HAVE_AVX2) += x86/fwd_txfm_avx2.c -DSP_SRCS-$(HAVE_MSA) += mips/fwd_dct32x32_msa.c -DSP_SRCS-$(HAVE_LSX) += loongarch/fwd_dct32x32_lsx.c -endif # !CONFIG_VP9_HIGHBITDEPTH - -DSP_SRCS-$(HAVE_VSX) += ppc/fdct32x32_vsx.c -endif # CONFIG_VP9_ENCODER - -# inverse transform -ifeq ($(CONFIG_VP9),yes) -DSP_SRCS-yes += inv_txfm.h -DSP_SRCS-yes += inv_txfm.c -DSP_SRCS-$(HAVE_SSE2) += x86/inv_txfm_sse2.h -DSP_SRCS-$(HAVE_SSE2) += x86/inv_txfm_sse2.c -DSP_SRCS-$(HAVE_AVX2) += x86/inv_txfm_avx2.c -DSP_SRCS-$(HAVE_SSE2) += x86/inv_wht_sse2.asm -DSP_SRCS-$(HAVE_SSSE3) += x86/inv_txfm_ssse3.h -DSP_SRCS-$(HAVE_SSSE3) += x86/inv_txfm_ssse3.c - -DSP_SRCS-$(HAVE_NEON_ASM) += arm/save_reg_neon$(ASM) - -DSP_SRCS-$(HAVE_VSX) += ppc/inv_txfm_vsx.c - -ifneq ($(CONFIG_VP9_HIGHBITDEPTH),yes) -DSP_SRCS-$(HAVE_MSA) += mips/inv_txfm_msa.h -DSP_SRCS-$(HAVE_MSA) += mips/idct4x4_msa.c -DSP_SRCS-$(HAVE_MSA) += mips/idct8x8_msa.c -DSP_SRCS-$(HAVE_MSA) += mips/idct16x16_msa.c -DSP_SRCS-$(HAVE_MSA) += mips/idct32x32_msa.c - -DSP_SRCS-$(HAVE_DSPR2) += mips/inv_txfm_dspr2.h -DSP_SRCS-$(HAVE_DSPR2) += mips/itrans4_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/itrans8_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/itrans16_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/itrans32_dspr2.c -DSP_SRCS-$(HAVE_DSPR2) += mips/itrans32_cols_dspr2.c - -DSP_SRCS-$(HAVE_LSX) += loongarch/idct32x32_lsx.c -else # CONFIG_VP9_HIGHBITDEPTH -DSP_SRCS-$(HAVE_NEON) += arm/highbd_idct4x4_add_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/highbd_idct8x8_add_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/highbd_idct16x16_add_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/highbd_idct32x32_add_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/highbd_idct32x32_34_add_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/highbd_idct32x32_135_add_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/highbd_idct32x32_1024_add_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/highbd_idct_neon.h -DSP_SRCS-$(HAVE_SSE2) += x86/highbd_inv_txfm_sse2.h -DSP_SRCS-$(HAVE_SSE2) += x86/highbd_idct4x4_add_sse2.c -DSP_SRCS-$(HAVE_SSE2) += x86/highbd_idct8x8_add_sse2.c -DSP_SRCS-$(HAVE_SSE2) += x86/highbd_idct16x16_add_sse2.c -DSP_SRCS-$(HAVE_SSE2) += x86/highbd_idct32x32_add_sse2.c -DSP_SRCS-$(HAVE_SSE4_1) += x86/highbd_inv_txfm_sse4.h -DSP_SRCS-$(HAVE_SSE4_1) += x86/highbd_idct4x4_add_sse4.c -DSP_SRCS-$(HAVE_SSE4_1) += x86/highbd_idct8x8_add_sse4.c -DSP_SRCS-$(HAVE_SSE4_1) += x86/highbd_idct16x16_add_sse4.c -DSP_SRCS-$(HAVE_SSE4_1) += x86/highbd_idct32x32_add_sse4.c -endif # !CONFIG_VP9_HIGHBITDEPTH - -ifeq ($(HAVE_NEON_ASM),yes) -DSP_SRCS-yes += arm/idct_neon$(ASM) -DSP_SRCS-yes += arm/idct4x4_1_add_neon$(ASM) -DSP_SRCS-yes += arm/idct4x4_add_neon$(ASM) -else -DSP_SRCS-$(HAVE_NEON) += arm/idct4x4_1_add_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/idct4x4_add_neon.c -endif # HAVE_NEON_ASM -DSP_SRCS-$(HAVE_NEON) += arm/idct_neon.h -DSP_SRCS-$(HAVE_NEON) += arm/idct8x8_1_add_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/idct8x8_add_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/idct16x16_1_add_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/idct16x16_add_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/idct32x32_1_add_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/idct32x32_34_add_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/idct32x32_135_add_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/idct32x32_add_neon.c - -endif # CONFIG_VP9 - -# quantization -ifeq ($(CONFIG_VP9_ENCODER),yes) -DSP_SRCS-yes += quantize.c -DSP_SRCS-yes += quantize.h - -DSP_SRCS-$(HAVE_SSE2) += x86/quantize_sse2.c -DSP_SRCS-$(HAVE_SSE2) += x86/quantize_sse2.h -DSP_SRCS-$(HAVE_SSSE3) += x86/quantize_ssse3.c -DSP_SRCS-$(HAVE_SSSE3) += x86/quantize_ssse3.h -DSP_SRCS-$(HAVE_AVX) += x86/quantize_avx.c -DSP_SRCS-$(HAVE_AVX2) += x86/quantize_avx2.c -DSP_SRCS-$(HAVE_NEON) += arm/quantize_neon.c -DSP_SRCS-$(HAVE_VSX) += ppc/quantize_vsx.c -DSP_SRCS-$(HAVE_LSX) += loongarch/quantize_lsx.c -ifeq ($(CONFIG_VP9_HIGHBITDEPTH),yes) -DSP_SRCS-$(HAVE_SSE2) += x86/highbd_quantize_intrin_sse2.c -DSP_SRCS-$(HAVE_AVX2) += x86/highbd_quantize_intrin_avx2.c -DSP_SRCS-$(HAVE_NEON) += arm/highbd_quantize_neon.c -endif - -# avg -DSP_SRCS-yes += avg.c -DSP_SRCS-$(HAVE_SSE2) += x86/avg_intrin_sse2.c -DSP_SRCS-$(HAVE_AVX2) += x86/avg_intrin_avx2.c -DSP_SRCS-$(HAVE_NEON) += arm/avg_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/hadamard_neon.c -ifeq ($(CONFIG_VP9_HIGHBITDEPTH),yes) -DSP_SRCS-$(HAVE_NEON) += arm/highbd_hadamard_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/highbd_avg_neon.c -endif -DSP_SRCS-$(HAVE_MSA) += mips/avg_msa.c -DSP_SRCS-$(HAVE_LSX) += loongarch/avg_lsx.c -ifeq ($(VPX_ARCH_X86_64),yes) -DSP_SRCS-$(HAVE_SSSE3) += x86/avg_ssse3_x86_64.asm -endif -DSP_SRCS-$(HAVE_VSX) += ppc/hadamard_vsx.c - -endif # CONFIG_VP9_ENCODER - -# skin detection -DSP_SRCS-yes += skin_detection.h -DSP_SRCS-yes += skin_detection.c - -ifeq ($(CONFIG_ENCODERS),yes) -DSP_SRCS-yes += sad.c -DSP_SRCS-yes += subtract.c -DSP_SRCS-yes += sum_squares.c -DSP_SRCS-$(HAVE_NEON) += arm/sum_squares_neon.c -DSP_SRCS-$(HAVE_SVE) += arm/sum_squares_sve.c -DSP_SRCS-$(HAVE_SSE2) += x86/sum_squares_sse2.c -DSP_SRCS-$(HAVE_MSA) += mips/sum_squares_msa.c - -DSP_SRCS-$(HAVE_NEON) += arm/sad4d_neon.c -DSP_SRCS-$(HAVE_NEON_DOTPROD) += arm/sad4d_neon_dotprod.c -DSP_SRCS-$(HAVE_NEON) += arm/sad_neon.c -DSP_SRCS-$(HAVE_NEON_DOTPROD) += arm/sad_neon_dotprod.c -DSP_SRCS-$(HAVE_NEON) += arm/subtract_neon.c - -DSP_SRCS-$(HAVE_MSA) += mips/sad_msa.c -DSP_SRCS-$(HAVE_MSA) += mips/subtract_msa.c - -DSP_SRCS-$(HAVE_LSX) += loongarch/sad_lsx.c - -DSP_SRCS-$(HAVE_MMI) += mips/sad_mmi.c -DSP_SRCS-$(HAVE_MMI) += mips/subtract_mmi.c - -DSP_SRCS-$(HAVE_AVX2) += x86/sad4d_avx2.c -DSP_SRCS-$(HAVE_AVX2) += x86/sad_avx2.c -DSP_SRCS-$(HAVE_AVX2) += x86/subtract_avx2.c -DSP_SRCS-$(HAVE_AVX512) += x86/sad4d_avx512.c - -DSP_SRCS-$(HAVE_SSE2) += x86/sad4d_sse2.asm -DSP_SRCS-$(HAVE_SSE2) += x86/sad_sse2.asm -DSP_SRCS-$(HAVE_SSE2) += x86/subtract_sse2.asm - -DSP_SRCS-$(HAVE_VSX) += ppc/sad_vsx.c -DSP_SRCS-$(HAVE_VSX) += ppc/subtract_vsx.c - -DSP_SRCS-$(HAVE_LSX) += loongarch/subtract_lsx.c - -ifeq ($(CONFIG_VP9_HIGHBITDEPTH),yes) -DSP_SRCS-$(HAVE_SSE2) += x86/highbd_sad4d_sse2.asm -DSP_SRCS-$(HAVE_SSE2) += x86/highbd_sad_sse2.asm -DSP_SRCS-$(HAVE_NEON) += arm/highbd_sad4d_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/highbd_sad_neon.c -DSP_SRCS-$(HAVE_AVX2) += x86/highbd_sad4d_avx2.c -DSP_SRCS-$(HAVE_AVX2) += x86/highbd_sad_avx2.c -endif # CONFIG_VP9_HIGHBITDEPTH - -endif # CONFIG_ENCODERS - -ifneq ($(filter yes,$(CONFIG_ENCODERS) $(CONFIG_POSTPROC) $(CONFIG_VP9_POSTPROC)),) -DSP_SRCS-yes += variance.c -DSP_SRCS-yes += variance.h - -DSP_SRCS-$(HAVE_NEON) += arm/avg_pred_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/subpel_variance_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/variance_neon.c -DSP_SRCS-$(HAVE_NEON_DOTPROD) += arm/variance_neon_dotprod.c - -DSP_SRCS-$(HAVE_MSA) += mips/variance_msa.c -DSP_SRCS-$(HAVE_MSA) += mips/sub_pixel_variance_msa.c - -DSP_SRCS-$(HAVE_LSX) += loongarch/variance_lsx.h -DSP_SRCS-$(HAVE_LSX) += loongarch/variance_lsx.c -DSP_SRCS-$(HAVE_LSX) += loongarch/sub_pixel_variance_lsx.c -DSP_SRCS-$(HAVE_LSX) += loongarch/avg_pred_lsx.c - -DSP_SRCS-$(HAVE_MMI) += mips/variance_mmi.c - -DSP_SRCS-$(HAVE_SSE2) += x86/avg_pred_sse2.c -DSP_SRCS-$(HAVE_AVX2) += x86/avg_pred_avx2.c -DSP_SRCS-$(HAVE_SSE2) += x86/variance_sse2.c # Contains SSE2 and SSSE3 -DSP_SRCS-$(HAVE_AVX2) += x86/variance_avx2.c -DSP_SRCS-$(HAVE_VSX) += ppc/variance_vsx.c - -ifeq ($(VPX_ARCH_X86_64),yes) -DSP_SRCS-$(HAVE_SSE2) += x86/ssim_opt_x86_64.asm -endif # VPX_ARCH_X86_64 - -DSP_SRCS-$(HAVE_SSE2) += x86/subpel_variance_sse2.asm # Contains SSE2 and SSSE3 - -ifeq ($(CONFIG_VP9_HIGHBITDEPTH),yes) -DSP_SRCS-$(HAVE_SSE2) += x86/highbd_variance_sse2.c -DSP_SRCS-$(HAVE_SSE2) += x86/highbd_variance_impl_sse2.asm -DSP_SRCS-$(HAVE_SSE2) += x86/highbd_subpel_variance_impl_sse2.asm -DSP_SRCS-$(HAVE_NEON) += arm/highbd_avg_pred_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/highbd_sse_neon.c -DSP_SRCS-$(HAVE_NEON) += arm/highbd_variance_neon.c -DSP_SRCS-$(HAVE_NEON_DOTPROD) += arm/highbd_variance_neon_dotprod.c -DSP_SRCS-$(HAVE_SVE) += arm/highbd_variance_sve.c -DSP_SRCS-$(HAVE_NEON) += arm/highbd_subpel_variance_neon.c -endif # CONFIG_VP9_HIGHBITDEPTH -endif # CONFIG_ENCODERS || CONFIG_POSTPROC || CONFIG_VP9_POSTPROC - -# Neon utilities -DSP_SRCS-$(HAVE_NEON) += arm/mem_neon.h -DSP_SRCS-$(HAVE_NEON) += arm/sum_neon.h -DSP_SRCS-$(HAVE_NEON) += arm/transpose_neon.h -DSP_SRCS-$(HAVE_NEON) += arm/vpx_convolve8_neon.h - -# PPC VSX utilities -DSP_SRCS-$(HAVE_VSX) += ppc/types_vsx.h -DSP_SRCS-$(HAVE_VSX) += ppc/txfm_common_vsx.h -DSP_SRCS-$(HAVE_VSX) += ppc/transpose_vsx.h -DSP_SRCS-$(HAVE_VSX) += ppc/bitdepth_conversion_vsx.h - -# X86 utilities -DSP_SRCS-$(HAVE_SSE2) += x86/mem_sse2.h -DSP_SRCS-$(HAVE_SSE2) += x86/transpose_sse2.h - -# LSX utilities -DSP_SRCS-$(HAVE_LSX) += loongarch/bitdepth_conversion_lsx.h - -DSP_SRCS-no += $(DSP_SRCS_REMOVE-yes) - -DSP_SRCS-yes += vpx_dsp_rtcd.c -DSP_SRCS-yes += vpx_dsp_rtcd_defs.pl - -$(eval $(call rtcd_h_template,vpx_dsp_rtcd,vpx_dsp/vpx_dsp_rtcd_defs.pl)) diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_dsp_common.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_dsp_common.h deleted file mode 100644 index 528f33f9..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_dsp_common.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_VPX_DSP_COMMON_H_ -#define VPX_VPX_DSP_VPX_DSP_COMMON_H_ - -#include - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vpx_ports/mem.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define VPXMIN(x, y) (((x) < (y)) ? (x) : (y)) -#define VPXMAX(x, y) (((x) > (y)) ? (x) : (y)) - -#define VPX_SWAP(type, a, b) \ - do { \ - type c = (b); \ - (b) = a; \ - (a) = c; \ - } while (0) - -#if CONFIG_VP9_HIGHBITDEPTH -// Note: -// tran_low_t is the datatype used for final transform coefficients. -// tran_high_t is the datatype used for intermediate transform stages. -typedef int64_t tran_high_t; -typedef int32_t tran_low_t; -#else -// Note: -// tran_low_t is the datatype used for final transform coefficients. -// tran_high_t is the datatype used for intermediate transform stages. -typedef int32_t tran_high_t; -typedef int16_t tran_low_t; -#endif // CONFIG_VP9_HIGHBITDEPTH - -typedef int16_t tran_coef_t; - -// Visual Studio 2022 (cl.exe) targeting AArch64 with optimizations enabled -// produces invalid code for clip_pixel() when the return type is uint8_t. -// See: -// https://developercommunity.visualstudio.com/t/Misoptimization-for-ARM64-in-VS-2022-17/10363361 -// TODO(jzern): check the compiler version after a fix for the issue is -// released. -#if defined(_MSC_VER) && defined(_M_ARM64) && !defined(__clang__) -static INLINE int clip_pixel(int val) { - return (val > 255) ? 255 : (val < 0) ? 0 : val; -} -#else -static INLINE uint8_t clip_pixel(int val) { - return (val > 255) ? 255 : (val < 0) ? 0 : val; -} -#endif - -static INLINE int clamp(int value, int low, int high) { - return value < low ? low : (value > high ? high : value); -} - -static INLINE double fclamp(double value, double low, double high) { - return value < low ? low : (value > high ? high : value); -} - -static INLINE int64_t lclamp(int64_t value, int64_t low, int64_t high) { - return value < low ? low : (value > high ? high : value); -} - -static INLINE uint16_t clip_pixel_highbd(int val, int bd) { - switch (bd) { - case 8: - default: return (uint16_t)clamp(val, 0, 255); - case 10: return (uint16_t)clamp(val, 0, 1023); - case 12: return (uint16_t)clamp(val, 0, 4095); - } -} - -// Returns the saturating cast of a double value to int. -static INLINE int saturate_cast_double_to_int(double d) { - if (d > INT_MAX) return INT_MAX; - return (int)d; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_VPX_DSP_COMMON_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_dsp_rtcd.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_dsp_rtcd.c deleted file mode 100644 index 2b8c656a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_dsp_rtcd.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "./vpx_config.h" -#define RTCD_C -#include "./vpx_dsp_rtcd.h" -#include "vpx_ports/vpx_once.h" - -void vpx_dsp_rtcd(void) { once(setup_rtcd_internal); } diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_dsp_rtcd_defs.pl b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_dsp_rtcd_defs.pl deleted file mode 100644 index d8458307..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/vpx_dsp_rtcd_defs.pl +++ /dev/null @@ -1,1825 +0,0 @@ -## -## Copyright (c) 2017 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -sub vpx_dsp_forward_decls() { -print < -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define FILTER_BITS 7 - -#define SUBPEL_BITS 4 -#define SUBPEL_MASK ((1 << SUBPEL_BITS) - 1) -#define SUBPEL_SHIFTS (1 << SUBPEL_BITS) -#define SUBPEL_TAPS 8 - -typedef int16_t InterpKernel[SUBPEL_TAPS]; - -static INLINE int vpx_get_filter_taps(const int16_t *const filter) { - if (filter[0] | filter[7]) { - return 8; - } - if (filter[1] | filter[6]) { - return 6; - } - if (filter[2] | filter[5]) { - return 4; - } - return 2; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_VPX_FILTER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/add_noise_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/add_noise_sse2.asm deleted file mode 100644 index f51718cf..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/add_noise_sse2.asm +++ /dev/null @@ -1,88 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -SECTION .text - -;void vpx_plane_add_noise_sse2(uint8_t *start, const int8_t *noise, -; int blackclamp, int whiteclamp, -; int width, int height, int pitch) -globalsym(vpx_plane_add_noise_sse2) -sym(vpx_plane_add_noise_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - GET_GOT rbx - push rsi - push rdi - - mov rdx, 0x01010101 - mov rax, arg(2) - mul rdx - movq xmm3, rax - pshufd xmm3, xmm3, 0 ; xmm3 is 16 copies of char in blackclamp - - mov rdx, 0x01010101 - mov rax, arg(3) - mul rdx - movq xmm4, rax - pshufd xmm4, xmm4, 0 ; xmm4 is 16 copies of char in whiteclamp - - movdqu xmm5, xmm3 ; both clamp = black clamp + white clamp - paddusb xmm5, xmm4 - -.addnoise_loop: - call sym(LIBVPX_RAND) WRT_PLT - mov rcx, arg(1) ;noise - and rax, 0xff - add rcx, rax - - mov rdi, rcx - movsxd rcx, dword arg(4) ;[Width] - mov rsi, arg(0) ;Pos - xor rax, rax - -.addnoise_nextset: - movdqu xmm1,[rsi+rax] ; get the source - - psubusb xmm1, xmm3 ; subtract black clamp - paddusb xmm1, xmm5 ; add both clamp - psubusb xmm1, xmm4 ; subtract whiteclamp - - movdqu xmm2,[rdi+rax] ; get the noise for this line - paddb xmm1,xmm2 ; add it in - movdqu [rsi+rax],xmm1 ; store the result - - add rax,16 ; move to the next line - - cmp rax, rcx - jl .addnoise_nextset - - movsxd rax, dword arg(6) ; Pitch - add arg(0), rax ; Start += Pitch - sub dword arg(5), 1 ; Height -= 1 - jg .addnoise_loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_GOT - UNSHADOW_ARGS - pop rbp - ret - -SECTION_RODATA -align 16 -rd42: - times 8 dw 0x04 -four8s: - times 4 dd 8 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/avg_intrin_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/avg_intrin_avx2.c deleted file mode 100644 index 61e4e73c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/avg_intrin_avx2.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/x86/bitdepth_conversion_avx2.h" -#include "vpx_ports/mem.h" - -#if CONFIG_VP9_HIGHBITDEPTH -static void highbd_hadamard_col8_avx2(__m256i *in, int iter) { - __m256i a0 = in[0]; - __m256i a1 = in[1]; - __m256i a2 = in[2]; - __m256i a3 = in[3]; - __m256i a4 = in[4]; - __m256i a5 = in[5]; - __m256i a6 = in[6]; - __m256i a7 = in[7]; - - __m256i b0 = _mm256_add_epi32(a0, a1); - __m256i b1 = _mm256_sub_epi32(a0, a1); - __m256i b2 = _mm256_add_epi32(a2, a3); - __m256i b3 = _mm256_sub_epi32(a2, a3); - __m256i b4 = _mm256_add_epi32(a4, a5); - __m256i b5 = _mm256_sub_epi32(a4, a5); - __m256i b6 = _mm256_add_epi32(a6, a7); - __m256i b7 = _mm256_sub_epi32(a6, a7); - - a0 = _mm256_add_epi32(b0, b2); - a1 = _mm256_add_epi32(b1, b3); - a2 = _mm256_sub_epi32(b0, b2); - a3 = _mm256_sub_epi32(b1, b3); - a4 = _mm256_add_epi32(b4, b6); - a5 = _mm256_add_epi32(b5, b7); - a6 = _mm256_sub_epi32(b4, b6); - a7 = _mm256_sub_epi32(b5, b7); - - if (iter == 0) { - b0 = _mm256_add_epi32(a0, a4); - b7 = _mm256_add_epi32(a1, a5); - b3 = _mm256_add_epi32(a2, a6); - b4 = _mm256_add_epi32(a3, a7); - b2 = _mm256_sub_epi32(a0, a4); - b6 = _mm256_sub_epi32(a1, a5); - b1 = _mm256_sub_epi32(a2, a6); - b5 = _mm256_sub_epi32(a3, a7); - - a0 = _mm256_unpacklo_epi32(b0, b1); - a1 = _mm256_unpacklo_epi32(b2, b3); - a2 = _mm256_unpackhi_epi32(b0, b1); - a3 = _mm256_unpackhi_epi32(b2, b3); - a4 = _mm256_unpacklo_epi32(b4, b5); - a5 = _mm256_unpacklo_epi32(b6, b7); - a6 = _mm256_unpackhi_epi32(b4, b5); - a7 = _mm256_unpackhi_epi32(b6, b7); - - b0 = _mm256_unpacklo_epi64(a0, a1); - b1 = _mm256_unpacklo_epi64(a4, a5); - b2 = _mm256_unpackhi_epi64(a0, a1); - b3 = _mm256_unpackhi_epi64(a4, a5); - b4 = _mm256_unpacklo_epi64(a2, a3); - b5 = _mm256_unpacklo_epi64(a6, a7); - b6 = _mm256_unpackhi_epi64(a2, a3); - b7 = _mm256_unpackhi_epi64(a6, a7); - - in[0] = _mm256_permute2x128_si256(b0, b1, 0x20); - in[1] = _mm256_permute2x128_si256(b0, b1, 0x31); - in[2] = _mm256_permute2x128_si256(b2, b3, 0x20); - in[3] = _mm256_permute2x128_si256(b2, b3, 0x31); - in[4] = _mm256_permute2x128_si256(b4, b5, 0x20); - in[5] = _mm256_permute2x128_si256(b4, b5, 0x31); - in[6] = _mm256_permute2x128_si256(b6, b7, 0x20); - in[7] = _mm256_permute2x128_si256(b6, b7, 0x31); - } else { - in[0] = _mm256_add_epi32(a0, a4); - in[7] = _mm256_add_epi32(a1, a5); - in[3] = _mm256_add_epi32(a2, a6); - in[4] = _mm256_add_epi32(a3, a7); - in[2] = _mm256_sub_epi32(a0, a4); - in[6] = _mm256_sub_epi32(a1, a5); - in[1] = _mm256_sub_epi32(a2, a6); - in[5] = _mm256_sub_epi32(a3, a7); - } -} - -void vpx_highbd_hadamard_8x8_avx2(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { - __m128i src16[8]; - __m256i src32[8]; - - src16[0] = _mm_loadu_si128((const __m128i *)src_diff); - src16[1] = _mm_loadu_si128((const __m128i *)(src_diff += src_stride)); - src16[2] = _mm_loadu_si128((const __m128i *)(src_diff += src_stride)); - src16[3] = _mm_loadu_si128((const __m128i *)(src_diff += src_stride)); - src16[4] = _mm_loadu_si128((const __m128i *)(src_diff += src_stride)); - src16[5] = _mm_loadu_si128((const __m128i *)(src_diff += src_stride)); - src16[6] = _mm_loadu_si128((const __m128i *)(src_diff += src_stride)); - src16[7] = _mm_loadu_si128((const __m128i *)(src_diff + src_stride)); - - src32[0] = _mm256_cvtepi16_epi32(src16[0]); - src32[1] = _mm256_cvtepi16_epi32(src16[1]); - src32[2] = _mm256_cvtepi16_epi32(src16[2]); - src32[3] = _mm256_cvtepi16_epi32(src16[3]); - src32[4] = _mm256_cvtepi16_epi32(src16[4]); - src32[5] = _mm256_cvtepi16_epi32(src16[5]); - src32[6] = _mm256_cvtepi16_epi32(src16[6]); - src32[7] = _mm256_cvtepi16_epi32(src16[7]); - - highbd_hadamard_col8_avx2(src32, 0); - highbd_hadamard_col8_avx2(src32, 1); - - _mm256_storeu_si256((__m256i *)coeff, src32[0]); - coeff += 8; - _mm256_storeu_si256((__m256i *)coeff, src32[1]); - coeff += 8; - _mm256_storeu_si256((__m256i *)coeff, src32[2]); - coeff += 8; - _mm256_storeu_si256((__m256i *)coeff, src32[3]); - coeff += 8; - _mm256_storeu_si256((__m256i *)coeff, src32[4]); - coeff += 8; - _mm256_storeu_si256((__m256i *)coeff, src32[5]); - coeff += 8; - _mm256_storeu_si256((__m256i *)coeff, src32[6]); - coeff += 8; - _mm256_storeu_si256((__m256i *)coeff, src32[7]); -} - -void vpx_highbd_hadamard_16x16_avx2(const int16_t *src_diff, - ptrdiff_t src_stride, tran_low_t *coeff) { - int idx; - tran_low_t *t_coeff = coeff; - for (idx = 0; idx < 4; ++idx) { - const int16_t *src_ptr = - src_diff + (idx >> 1) * 8 * src_stride + (idx & 0x01) * 8; - vpx_highbd_hadamard_8x8_avx2(src_ptr, src_stride, t_coeff + idx * 64); - } - - for (idx = 0; idx < 64; idx += 8) { - __m256i coeff0 = _mm256_loadu_si256((const __m256i *)t_coeff); - __m256i coeff1 = _mm256_loadu_si256((const __m256i *)(t_coeff + 64)); - __m256i coeff2 = _mm256_loadu_si256((const __m256i *)(t_coeff + 128)); - __m256i coeff3 = _mm256_loadu_si256((const __m256i *)(t_coeff + 192)); - - __m256i b0 = _mm256_add_epi32(coeff0, coeff1); - __m256i b1 = _mm256_sub_epi32(coeff0, coeff1); - __m256i b2 = _mm256_add_epi32(coeff2, coeff3); - __m256i b3 = _mm256_sub_epi32(coeff2, coeff3); - - b0 = _mm256_srai_epi32(b0, 1); - b1 = _mm256_srai_epi32(b1, 1); - b2 = _mm256_srai_epi32(b2, 1); - b3 = _mm256_srai_epi32(b3, 1); - - coeff0 = _mm256_add_epi32(b0, b2); - coeff1 = _mm256_add_epi32(b1, b3); - coeff2 = _mm256_sub_epi32(b0, b2); - coeff3 = _mm256_sub_epi32(b1, b3); - - _mm256_storeu_si256((__m256i *)coeff, coeff0); - _mm256_storeu_si256((__m256i *)(coeff + 64), coeff1); - _mm256_storeu_si256((__m256i *)(coeff + 128), coeff2); - _mm256_storeu_si256((__m256i *)(coeff + 192), coeff3); - - coeff += 8; - t_coeff += 8; - } -} - -void vpx_highbd_hadamard_32x32_avx2(const int16_t *src_diff, - ptrdiff_t src_stride, tran_low_t *coeff) { - int idx; - tran_low_t *t_coeff = coeff; - for (idx = 0; idx < 4; ++idx) { - const int16_t *src_ptr = - src_diff + (idx >> 1) * 16 * src_stride + (idx & 0x01) * 16; - vpx_highbd_hadamard_16x16_avx2(src_ptr, src_stride, t_coeff + idx * 256); - } - - for (idx = 0; idx < 256; idx += 8) { - __m256i coeff0 = _mm256_loadu_si256((const __m256i *)t_coeff); - __m256i coeff1 = _mm256_loadu_si256((const __m256i *)(t_coeff + 256)); - __m256i coeff2 = _mm256_loadu_si256((const __m256i *)(t_coeff + 512)); - __m256i coeff3 = _mm256_loadu_si256((const __m256i *)(t_coeff + 768)); - - __m256i b0 = _mm256_add_epi32(coeff0, coeff1); - __m256i b1 = _mm256_sub_epi32(coeff0, coeff1); - __m256i b2 = _mm256_add_epi32(coeff2, coeff3); - __m256i b3 = _mm256_sub_epi32(coeff2, coeff3); - - b0 = _mm256_srai_epi32(b0, 2); - b1 = _mm256_srai_epi32(b1, 2); - b2 = _mm256_srai_epi32(b2, 2); - b3 = _mm256_srai_epi32(b3, 2); - - coeff0 = _mm256_add_epi32(b0, b2); - coeff1 = _mm256_add_epi32(b1, b3); - coeff2 = _mm256_sub_epi32(b0, b2); - coeff3 = _mm256_sub_epi32(b1, b3); - - _mm256_storeu_si256((__m256i *)coeff, coeff0); - _mm256_storeu_si256((__m256i *)(coeff + 256), coeff1); - _mm256_storeu_si256((__m256i *)(coeff + 512), coeff2); - _mm256_storeu_si256((__m256i *)(coeff + 768), coeff3); - - coeff += 8; - t_coeff += 8; - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static INLINE void sign_extend_16bit_to_32bit_avx2(__m256i in, __m256i zero, - __m256i *out_lo, - __m256i *out_hi) { - const __m256i sign_bits = _mm256_cmpgt_epi16(zero, in); - *out_lo = _mm256_unpacklo_epi16(in, sign_bits); - *out_hi = _mm256_unpackhi_epi16(in, sign_bits); -} - -static void hadamard_col8x2_avx2(__m256i *in, int iter) { - __m256i a0 = in[0]; - __m256i a1 = in[1]; - __m256i a2 = in[2]; - __m256i a3 = in[3]; - __m256i a4 = in[4]; - __m256i a5 = in[5]; - __m256i a6 = in[6]; - __m256i a7 = in[7]; - - __m256i b0 = _mm256_add_epi16(a0, a1); - __m256i b1 = _mm256_sub_epi16(a0, a1); - __m256i b2 = _mm256_add_epi16(a2, a3); - __m256i b3 = _mm256_sub_epi16(a2, a3); - __m256i b4 = _mm256_add_epi16(a4, a5); - __m256i b5 = _mm256_sub_epi16(a4, a5); - __m256i b6 = _mm256_add_epi16(a6, a7); - __m256i b7 = _mm256_sub_epi16(a6, a7); - - a0 = _mm256_add_epi16(b0, b2); - a1 = _mm256_add_epi16(b1, b3); - a2 = _mm256_sub_epi16(b0, b2); - a3 = _mm256_sub_epi16(b1, b3); - a4 = _mm256_add_epi16(b4, b6); - a5 = _mm256_add_epi16(b5, b7); - a6 = _mm256_sub_epi16(b4, b6); - a7 = _mm256_sub_epi16(b5, b7); - - if (iter == 0) { - b0 = _mm256_add_epi16(a0, a4); - b7 = _mm256_add_epi16(a1, a5); - b3 = _mm256_add_epi16(a2, a6); - b4 = _mm256_add_epi16(a3, a7); - b2 = _mm256_sub_epi16(a0, a4); - b6 = _mm256_sub_epi16(a1, a5); - b1 = _mm256_sub_epi16(a2, a6); - b5 = _mm256_sub_epi16(a3, a7); - - a0 = _mm256_unpacklo_epi16(b0, b1); - a1 = _mm256_unpacklo_epi16(b2, b3); - a2 = _mm256_unpackhi_epi16(b0, b1); - a3 = _mm256_unpackhi_epi16(b2, b3); - a4 = _mm256_unpacklo_epi16(b4, b5); - a5 = _mm256_unpacklo_epi16(b6, b7); - a6 = _mm256_unpackhi_epi16(b4, b5); - a7 = _mm256_unpackhi_epi16(b6, b7); - - b0 = _mm256_unpacklo_epi32(a0, a1); - b1 = _mm256_unpacklo_epi32(a4, a5); - b2 = _mm256_unpackhi_epi32(a0, a1); - b3 = _mm256_unpackhi_epi32(a4, a5); - b4 = _mm256_unpacklo_epi32(a2, a3); - b5 = _mm256_unpacklo_epi32(a6, a7); - b6 = _mm256_unpackhi_epi32(a2, a3); - b7 = _mm256_unpackhi_epi32(a6, a7); - - in[0] = _mm256_unpacklo_epi64(b0, b1); - in[1] = _mm256_unpackhi_epi64(b0, b1); - in[2] = _mm256_unpacklo_epi64(b2, b3); - in[3] = _mm256_unpackhi_epi64(b2, b3); - in[4] = _mm256_unpacklo_epi64(b4, b5); - in[5] = _mm256_unpackhi_epi64(b4, b5); - in[6] = _mm256_unpacklo_epi64(b6, b7); - in[7] = _mm256_unpackhi_epi64(b6, b7); - } else { - in[0] = _mm256_add_epi16(a0, a4); - in[7] = _mm256_add_epi16(a1, a5); - in[3] = _mm256_add_epi16(a2, a6); - in[4] = _mm256_add_epi16(a3, a7); - in[2] = _mm256_sub_epi16(a0, a4); - in[6] = _mm256_sub_epi16(a1, a5); - in[1] = _mm256_sub_epi16(a2, a6); - in[5] = _mm256_sub_epi16(a3, a7); - } -} - -static void hadamard_8x8x2_avx2(const int16_t *src_diff, ptrdiff_t src_stride, - int16_t *coeff) { - __m256i src[8]; - src[0] = _mm256_loadu_si256((const __m256i *)src_diff); - src[1] = _mm256_loadu_si256((const __m256i *)(src_diff += src_stride)); - src[2] = _mm256_loadu_si256((const __m256i *)(src_diff += src_stride)); - src[3] = _mm256_loadu_si256((const __m256i *)(src_diff += src_stride)); - src[4] = _mm256_loadu_si256((const __m256i *)(src_diff += src_stride)); - src[5] = _mm256_loadu_si256((const __m256i *)(src_diff += src_stride)); - src[6] = _mm256_loadu_si256((const __m256i *)(src_diff += src_stride)); - src[7] = _mm256_loadu_si256((const __m256i *)(src_diff + src_stride)); - - hadamard_col8x2_avx2(src, 0); - hadamard_col8x2_avx2(src, 1); - - _mm256_storeu_si256((__m256i *)coeff, - _mm256_permute2x128_si256(src[0], src[1], 0x20)); - coeff += 16; - _mm256_storeu_si256((__m256i *)coeff, - _mm256_permute2x128_si256(src[2], src[3], 0x20)); - coeff += 16; - _mm256_storeu_si256((__m256i *)coeff, - _mm256_permute2x128_si256(src[4], src[5], 0x20)); - coeff += 16; - _mm256_storeu_si256((__m256i *)coeff, - _mm256_permute2x128_si256(src[6], src[7], 0x20)); - coeff += 16; - _mm256_storeu_si256((__m256i *)coeff, - _mm256_permute2x128_si256(src[0], src[1], 0x31)); - coeff += 16; - _mm256_storeu_si256((__m256i *)coeff, - _mm256_permute2x128_si256(src[2], src[3], 0x31)); - coeff += 16; - _mm256_storeu_si256((__m256i *)coeff, - _mm256_permute2x128_si256(src[4], src[5], 0x31)); - coeff += 16; - _mm256_storeu_si256((__m256i *)coeff, - _mm256_permute2x128_si256(src[6], src[7], 0x31)); -} - -static INLINE void hadamard_16x16_avx2(const int16_t *src_diff, - ptrdiff_t src_stride, tran_low_t *coeff, - int is_final) { -#if CONFIG_VP9_HIGHBITDEPTH - DECLARE_ALIGNED(32, int16_t, temp_coeff[16 * 16]); - int16_t *t_coeff = temp_coeff; -#else - int16_t *t_coeff = coeff; -#endif - int16_t *coeff16 = (int16_t *)coeff; - int idx; - for (idx = 0; idx < 2; ++idx) { - const int16_t *src_ptr = src_diff + idx * 8 * src_stride; - hadamard_8x8x2_avx2(src_ptr, src_stride, t_coeff + (idx * 64 * 2)); - } - - for (idx = 0; idx < 64; idx += 16) { - const __m256i coeff0 = _mm256_loadu_si256((const __m256i *)t_coeff); - const __m256i coeff1 = _mm256_loadu_si256((const __m256i *)(t_coeff + 64)); - const __m256i coeff2 = _mm256_loadu_si256((const __m256i *)(t_coeff + 128)); - const __m256i coeff3 = _mm256_loadu_si256((const __m256i *)(t_coeff + 192)); - - __m256i b0 = _mm256_add_epi16(coeff0, coeff1); - __m256i b1 = _mm256_sub_epi16(coeff0, coeff1); - __m256i b2 = _mm256_add_epi16(coeff2, coeff3); - __m256i b3 = _mm256_sub_epi16(coeff2, coeff3); - - b0 = _mm256_srai_epi16(b0, 1); - b1 = _mm256_srai_epi16(b1, 1); - b2 = _mm256_srai_epi16(b2, 1); - b3 = _mm256_srai_epi16(b3, 1); - if (is_final) { - store_tran_low(_mm256_add_epi16(b0, b2), coeff); - store_tran_low(_mm256_add_epi16(b1, b3), coeff + 64); - store_tran_low(_mm256_sub_epi16(b0, b2), coeff + 128); - store_tran_low(_mm256_sub_epi16(b1, b3), coeff + 192); - coeff += 16; - } else { - _mm256_storeu_si256((__m256i *)coeff16, _mm256_add_epi16(b0, b2)); - _mm256_storeu_si256((__m256i *)(coeff16 + 64), _mm256_add_epi16(b1, b3)); - _mm256_storeu_si256((__m256i *)(coeff16 + 128), _mm256_sub_epi16(b0, b2)); - _mm256_storeu_si256((__m256i *)(coeff16 + 192), _mm256_sub_epi16(b1, b3)); - coeff16 += 16; - } - t_coeff += 16; - } -} - -void vpx_hadamard_16x16_avx2(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { - hadamard_16x16_avx2(src_diff, src_stride, coeff, 1); -} - -void vpx_hadamard_32x32_avx2(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { -#if CONFIG_VP9_HIGHBITDEPTH - // For high bitdepths, it is unnecessary to store_tran_low - // (mult/unpack/store), then load_tran_low (load/pack) the same memory in the - // next stage. Output to an intermediate buffer first, then store_tran_low() - // in the final stage. - DECLARE_ALIGNED(32, int16_t, temp_coeff[32 * 32]); - int16_t *t_coeff = temp_coeff; -#else - int16_t *t_coeff = coeff; -#endif - int idx; - __m256i coeff0_lo, coeff1_lo, coeff2_lo, coeff3_lo, b0_lo, b1_lo, b2_lo, - b3_lo; - __m256i coeff0_hi, coeff1_hi, coeff2_hi, coeff3_hi, b0_hi, b1_hi, b2_hi, - b3_hi; - __m256i b0, b1, b2, b3; - const __m256i zero = _mm256_setzero_si256(); - for (idx = 0; idx < 4; ++idx) { - // src_diff: 9 bit, dynamic range [-255, 255] - const int16_t *src_ptr = - src_diff + (idx >> 1) * 16 * src_stride + (idx & 0x01) * 16; - hadamard_16x16_avx2(src_ptr, src_stride, - (tran_low_t *)(t_coeff + idx * 256), 0); - } - - for (idx = 0; idx < 256; idx += 16) { - const __m256i coeff0 = _mm256_loadu_si256((const __m256i *)t_coeff); - const __m256i coeff1 = _mm256_loadu_si256((const __m256i *)(t_coeff + 256)); - const __m256i coeff2 = _mm256_loadu_si256((const __m256i *)(t_coeff + 512)); - const __m256i coeff3 = _mm256_loadu_si256((const __m256i *)(t_coeff + 768)); - - // Sign extend 16 bit to 32 bit. - sign_extend_16bit_to_32bit_avx2(coeff0, zero, &coeff0_lo, &coeff0_hi); - sign_extend_16bit_to_32bit_avx2(coeff1, zero, &coeff1_lo, &coeff1_hi); - sign_extend_16bit_to_32bit_avx2(coeff2, zero, &coeff2_lo, &coeff2_hi); - sign_extend_16bit_to_32bit_avx2(coeff3, zero, &coeff3_lo, &coeff3_hi); - - b0_lo = _mm256_add_epi32(coeff0_lo, coeff1_lo); - b0_hi = _mm256_add_epi32(coeff0_hi, coeff1_hi); - - b1_lo = _mm256_sub_epi32(coeff0_lo, coeff1_lo); - b1_hi = _mm256_sub_epi32(coeff0_hi, coeff1_hi); - - b2_lo = _mm256_add_epi32(coeff2_lo, coeff3_lo); - b2_hi = _mm256_add_epi32(coeff2_hi, coeff3_hi); - - b3_lo = _mm256_sub_epi32(coeff2_lo, coeff3_lo); - b3_hi = _mm256_sub_epi32(coeff2_hi, coeff3_hi); - - b0_lo = _mm256_srai_epi32(b0_lo, 2); - b1_lo = _mm256_srai_epi32(b1_lo, 2); - b2_lo = _mm256_srai_epi32(b2_lo, 2); - b3_lo = _mm256_srai_epi32(b3_lo, 2); - - b0_hi = _mm256_srai_epi32(b0_hi, 2); - b1_hi = _mm256_srai_epi32(b1_hi, 2); - b2_hi = _mm256_srai_epi32(b2_hi, 2); - b3_hi = _mm256_srai_epi32(b3_hi, 2); - - b0 = _mm256_packs_epi32(b0_lo, b0_hi); - b1 = _mm256_packs_epi32(b1_lo, b1_hi); - b2 = _mm256_packs_epi32(b2_lo, b2_hi); - b3 = _mm256_packs_epi32(b3_lo, b3_hi); - - store_tran_low(_mm256_add_epi16(b0, b2), coeff); - store_tran_low(_mm256_add_epi16(b1, b3), coeff + 256); - store_tran_low(_mm256_sub_epi16(b0, b2), coeff + 512); - store_tran_low(_mm256_sub_epi16(b1, b3), coeff + 768); - - coeff += 16; - t_coeff += 16; - } -} - -int vpx_satd_avx2(const tran_low_t *coeff, int length) { - const __m256i one = _mm256_set1_epi16(1); - __m256i accum = _mm256_setzero_si256(); - int i; - - for (i = 0; i < length; i += 16) { - const __m256i src_line = load_tran_low(coeff); - const __m256i abs = _mm256_abs_epi16(src_line); - const __m256i sum = _mm256_madd_epi16(abs, one); - accum = _mm256_add_epi32(accum, sum); - coeff += 16; - } - - { // 32 bit horizontal add - const __m256i a = _mm256_srli_si256(accum, 8); - const __m256i b = _mm256_add_epi32(accum, a); - const __m256i c = _mm256_srli_epi64(b, 32); - const __m256i d = _mm256_add_epi32(b, c); - const __m128i accum_128 = _mm_add_epi32(_mm256_castsi256_si128(d), - _mm256_extractf128_si256(d, 1)); - return _mm_cvtsi128_si32(accum_128); - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -int vpx_highbd_satd_avx2(const tran_low_t *coeff, int length) { - __m256i accum = _mm256_setzero_si256(); - int i; - - for (i = 0; i < length; i += 8, coeff += 8) { - const __m256i src_line = _mm256_loadu_si256((const __m256i *)coeff); - const __m256i abs = _mm256_abs_epi32(src_line); - accum = _mm256_add_epi32(accum, abs); - } - - { // 32 bit horizontal add - const __m256i a = _mm256_srli_si256(accum, 8); - const __m256i b = _mm256_add_epi32(accum, a); - const __m256i c = _mm256_srli_epi64(b, 32); - const __m256i d = _mm256_add_epi32(b, c); - const __m128i accum_128 = _mm_add_epi32(_mm256_castsi256_si128(d), - _mm256_extractf128_si256(d, 1)); - return _mm_cvtsi128_si32(accum_128); - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/avg_intrin_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/avg_intrin_sse2.c deleted file mode 100644 index 4447dfab..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/avg_intrin_sse2.c +++ /dev/null @@ -1,614 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/x86/bitdepth_conversion_sse2.h" -#include "vpx_ports/mem.h" - -static INLINE void sign_extend_16bit_to_32bit_sse2(__m128i in, __m128i zero, - __m128i *out_lo, - __m128i *out_hi) { - const __m128i sign_bits = _mm_cmplt_epi16(in, zero); - *out_lo = _mm_unpacklo_epi16(in, sign_bits); - *out_hi = _mm_unpackhi_epi16(in, sign_bits); -} - -void vpx_minmax_8x8_sse2(const uint8_t *s, int p, const uint8_t *d, int dp, - int *min, int *max) { - __m128i u0, s0, d0, diff, maxabsdiff, minabsdiff, negdiff, absdiff0, absdiff; - u0 = _mm_setzero_si128(); - // Row 0 - s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s)), u0); - d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d)), u0); - diff = _mm_subs_epi16(s0, d0); - negdiff = _mm_subs_epi16(u0, diff); - absdiff0 = _mm_max_epi16(diff, negdiff); - // Row 1 - s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + p)), u0); - d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + dp)), u0); - diff = _mm_subs_epi16(s0, d0); - negdiff = _mm_subs_epi16(u0, diff); - absdiff = _mm_max_epi16(diff, negdiff); - maxabsdiff = _mm_max_epi16(absdiff0, absdiff); - minabsdiff = _mm_min_epi16(absdiff0, absdiff); - // Row 2 - s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 2 * p)), u0); - d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 2 * dp)), u0); - diff = _mm_subs_epi16(s0, d0); - negdiff = _mm_subs_epi16(u0, diff); - absdiff = _mm_max_epi16(diff, negdiff); - maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff); - minabsdiff = _mm_min_epi16(minabsdiff, absdiff); - // Row 3 - s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 3 * p)), u0); - d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 3 * dp)), u0); - diff = _mm_subs_epi16(s0, d0); - negdiff = _mm_subs_epi16(u0, diff); - absdiff = _mm_max_epi16(diff, negdiff); - maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff); - minabsdiff = _mm_min_epi16(minabsdiff, absdiff); - // Row 4 - s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 4 * p)), u0); - d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 4 * dp)), u0); - diff = _mm_subs_epi16(s0, d0); - negdiff = _mm_subs_epi16(u0, diff); - absdiff = _mm_max_epi16(diff, negdiff); - maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff); - minabsdiff = _mm_min_epi16(minabsdiff, absdiff); - // Row 5 - s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 5 * p)), u0); - d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 5 * dp)), u0); - diff = _mm_subs_epi16(s0, d0); - negdiff = _mm_subs_epi16(u0, diff); - absdiff = _mm_max_epi16(diff, negdiff); - maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff); - minabsdiff = _mm_min_epi16(minabsdiff, absdiff); - // Row 6 - s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 6 * p)), u0); - d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 6 * dp)), u0); - diff = _mm_subs_epi16(s0, d0); - negdiff = _mm_subs_epi16(u0, diff); - absdiff = _mm_max_epi16(diff, negdiff); - maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff); - minabsdiff = _mm_min_epi16(minabsdiff, absdiff); - // Row 7 - s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 7 * p)), u0); - d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 7 * dp)), u0); - diff = _mm_subs_epi16(s0, d0); - negdiff = _mm_subs_epi16(u0, diff); - absdiff = _mm_max_epi16(diff, negdiff); - maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff); - minabsdiff = _mm_min_epi16(minabsdiff, absdiff); - - maxabsdiff = _mm_max_epi16(maxabsdiff, _mm_srli_si128(maxabsdiff, 8)); - maxabsdiff = _mm_max_epi16(maxabsdiff, _mm_srli_epi64(maxabsdiff, 32)); - maxabsdiff = _mm_max_epi16(maxabsdiff, _mm_srli_epi64(maxabsdiff, 16)); - *max = _mm_extract_epi16(maxabsdiff, 0); - - minabsdiff = _mm_min_epi16(minabsdiff, _mm_srli_si128(minabsdiff, 8)); - minabsdiff = _mm_min_epi16(minabsdiff, _mm_srli_epi64(minabsdiff, 32)); - minabsdiff = _mm_min_epi16(minabsdiff, _mm_srli_epi64(minabsdiff, 16)); - *min = _mm_extract_epi16(minabsdiff, 0); -} - -unsigned int vpx_avg_8x8_sse2(const uint8_t *s, int p) { - __m128i s0, s1, u0; - unsigned int avg = 0; - u0 = _mm_setzero_si128(); - s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s)), u0); - s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + p)), u0); - s0 = _mm_adds_epu16(s0, s1); - s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 2 * p)), u0); - s0 = _mm_adds_epu16(s0, s1); - s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 3 * p)), u0); - s0 = _mm_adds_epu16(s0, s1); - s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 4 * p)), u0); - s0 = _mm_adds_epu16(s0, s1); - s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 5 * p)), u0); - s0 = _mm_adds_epu16(s0, s1); - s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 6 * p)), u0); - s0 = _mm_adds_epu16(s0, s1); - s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 7 * p)), u0); - s0 = _mm_adds_epu16(s0, s1); - - s0 = _mm_adds_epu16(s0, _mm_srli_si128(s0, 8)); - s0 = _mm_adds_epu16(s0, _mm_srli_epi64(s0, 32)); - s0 = _mm_adds_epu16(s0, _mm_srli_epi64(s0, 16)); - avg = _mm_extract_epi16(s0, 0); - return (avg + 32) >> 6; -} - -unsigned int vpx_avg_4x4_sse2(const uint8_t *s, int p) { - __m128i s0, s1, u0; - unsigned int avg = 0; - u0 = _mm_setzero_si128(); - s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s)), u0); - s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + p)), u0); - s0 = _mm_adds_epu16(s0, s1); - s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 2 * p)), u0); - s0 = _mm_adds_epu16(s0, s1); - s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 3 * p)), u0); - s0 = _mm_adds_epu16(s0, s1); - - s0 = _mm_adds_epu16(s0, _mm_srli_si128(s0, 4)); - s0 = _mm_adds_epu16(s0, _mm_srli_epi64(s0, 16)); - avg = _mm_extract_epi16(s0, 0); - return (avg + 8) >> 4; -} - -#if CONFIG_VP9_HIGHBITDEPTH -unsigned int vpx_highbd_avg_8x8_sse2(const uint8_t *s8, int p) { - __m128i s0, s1; - unsigned int avg; - const uint16_t *s = CONVERT_TO_SHORTPTR(s8); - const __m128i zero = _mm_setzero_si128(); - s0 = _mm_loadu_si128((const __m128i *)(s)); - s1 = _mm_loadu_si128((const __m128i *)(s + p)); - s0 = _mm_adds_epu16(s0, s1); - s1 = _mm_loadu_si128((const __m128i *)(s + 2 * p)); - s0 = _mm_adds_epu16(s0, s1); - s1 = _mm_loadu_si128((const __m128i *)(s + 3 * p)); - s0 = _mm_adds_epu16(s0, s1); - s1 = _mm_loadu_si128((const __m128i *)(s + 4 * p)); - s0 = _mm_adds_epu16(s0, s1); - s1 = _mm_loadu_si128((const __m128i *)(s + 5 * p)); - s0 = _mm_adds_epu16(s0, s1); - s1 = _mm_loadu_si128((const __m128i *)(s + 6 * p)); - s0 = _mm_adds_epu16(s0, s1); - s1 = _mm_loadu_si128((const __m128i *)(s + 7 * p)); - s0 = _mm_adds_epu16(s0, s1); - s1 = _mm_unpackhi_epi16(s0, zero); - s0 = _mm_unpacklo_epi16(s0, zero); - s0 = _mm_add_epi32(s0, s1); - s0 = _mm_add_epi32(s0, _mm_srli_si128(s0, 8)); - s0 = _mm_add_epi32(s0, _mm_srli_si128(s0, 4)); - avg = (unsigned int)_mm_cvtsi128_si32(s0); - - return (avg + 32) >> 6; -} - -unsigned int vpx_highbd_avg_4x4_sse2(const uint8_t *s8, int p) { - __m128i s0, s1; - unsigned int avg; - const uint16_t *s = CONVERT_TO_SHORTPTR(s8); - s0 = _mm_loadl_epi64((const __m128i *)(s)); - s1 = _mm_loadl_epi64((const __m128i *)(s + p)); - s0 = _mm_adds_epu16(s0, s1); - s1 = _mm_loadl_epi64((const __m128i *)(s + 2 * p)); - s0 = _mm_adds_epu16(s0, s1); - s1 = _mm_loadl_epi64((const __m128i *)(s + 3 * p)); - s0 = _mm_adds_epu16(s0, s1); - s0 = _mm_add_epi16(s0, _mm_srli_si128(s0, 4)); - s0 = _mm_add_epi16(s0, _mm_srli_si128(s0, 2)); - avg = _mm_extract_epi16(s0, 0); - - return (avg + 8) >> 4; -} -#endif // CONFIG_VP9_HIGHBITDEPTH - -static void hadamard_col8_sse2(__m128i *in, int iter) { - __m128i a0 = in[0]; - __m128i a1 = in[1]; - __m128i a2 = in[2]; - __m128i a3 = in[3]; - __m128i a4 = in[4]; - __m128i a5 = in[5]; - __m128i a6 = in[6]; - __m128i a7 = in[7]; - - __m128i b0 = _mm_add_epi16(a0, a1); - __m128i b1 = _mm_sub_epi16(a0, a1); - __m128i b2 = _mm_add_epi16(a2, a3); - __m128i b3 = _mm_sub_epi16(a2, a3); - __m128i b4 = _mm_add_epi16(a4, a5); - __m128i b5 = _mm_sub_epi16(a4, a5); - __m128i b6 = _mm_add_epi16(a6, a7); - __m128i b7 = _mm_sub_epi16(a6, a7); - - a0 = _mm_add_epi16(b0, b2); - a1 = _mm_add_epi16(b1, b3); - a2 = _mm_sub_epi16(b0, b2); - a3 = _mm_sub_epi16(b1, b3); - a4 = _mm_add_epi16(b4, b6); - a5 = _mm_add_epi16(b5, b7); - a6 = _mm_sub_epi16(b4, b6); - a7 = _mm_sub_epi16(b5, b7); - - if (iter == 0) { - b0 = _mm_add_epi16(a0, a4); - b7 = _mm_add_epi16(a1, a5); - b3 = _mm_add_epi16(a2, a6); - b4 = _mm_add_epi16(a3, a7); - b2 = _mm_sub_epi16(a0, a4); - b6 = _mm_sub_epi16(a1, a5); - b1 = _mm_sub_epi16(a2, a6); - b5 = _mm_sub_epi16(a3, a7); - - a0 = _mm_unpacklo_epi16(b0, b1); - a1 = _mm_unpacklo_epi16(b2, b3); - a2 = _mm_unpackhi_epi16(b0, b1); - a3 = _mm_unpackhi_epi16(b2, b3); - a4 = _mm_unpacklo_epi16(b4, b5); - a5 = _mm_unpacklo_epi16(b6, b7); - a6 = _mm_unpackhi_epi16(b4, b5); - a7 = _mm_unpackhi_epi16(b6, b7); - - b0 = _mm_unpacklo_epi32(a0, a1); - b1 = _mm_unpacklo_epi32(a4, a5); - b2 = _mm_unpackhi_epi32(a0, a1); - b3 = _mm_unpackhi_epi32(a4, a5); - b4 = _mm_unpacklo_epi32(a2, a3); - b5 = _mm_unpacklo_epi32(a6, a7); - b6 = _mm_unpackhi_epi32(a2, a3); - b7 = _mm_unpackhi_epi32(a6, a7); - - in[0] = _mm_unpacklo_epi64(b0, b1); - in[1] = _mm_unpackhi_epi64(b0, b1); - in[2] = _mm_unpacklo_epi64(b2, b3); - in[3] = _mm_unpackhi_epi64(b2, b3); - in[4] = _mm_unpacklo_epi64(b4, b5); - in[5] = _mm_unpackhi_epi64(b4, b5); - in[6] = _mm_unpacklo_epi64(b6, b7); - in[7] = _mm_unpackhi_epi64(b6, b7); - } else { - in[0] = _mm_add_epi16(a0, a4); - in[7] = _mm_add_epi16(a1, a5); - in[3] = _mm_add_epi16(a2, a6); - in[4] = _mm_add_epi16(a3, a7); - in[2] = _mm_sub_epi16(a0, a4); - in[6] = _mm_sub_epi16(a1, a5); - in[1] = _mm_sub_epi16(a2, a6); - in[5] = _mm_sub_epi16(a3, a7); - } -} - -static INLINE void hadamard_8x8_sse2(const int16_t *src_diff, - ptrdiff_t src_stride, tran_low_t *coeff, - int is_final) { - __m128i src[8]; - src[0] = _mm_load_si128((const __m128i *)src_diff); - src[1] = _mm_load_si128((const __m128i *)(src_diff += src_stride)); - src[2] = _mm_load_si128((const __m128i *)(src_diff += src_stride)); - src[3] = _mm_load_si128((const __m128i *)(src_diff += src_stride)); - src[4] = _mm_load_si128((const __m128i *)(src_diff += src_stride)); - src[5] = _mm_load_si128((const __m128i *)(src_diff += src_stride)); - src[6] = _mm_load_si128((const __m128i *)(src_diff += src_stride)); - src[7] = _mm_load_si128((const __m128i *)(src_diff + src_stride)); - - hadamard_col8_sse2(src, 0); - hadamard_col8_sse2(src, 1); - - if (is_final) { - store_tran_low(src[0], coeff); - coeff += 8; - store_tran_low(src[1], coeff); - coeff += 8; - store_tran_low(src[2], coeff); - coeff += 8; - store_tran_low(src[3], coeff); - coeff += 8; - store_tran_low(src[4], coeff); - coeff += 8; - store_tran_low(src[5], coeff); - coeff += 8; - store_tran_low(src[6], coeff); - coeff += 8; - store_tran_low(src[7], coeff); - } else { - int16_t *coeff16 = (int16_t *)coeff; - _mm_store_si128((__m128i *)coeff16, src[0]); - coeff16 += 8; - _mm_store_si128((__m128i *)coeff16, src[1]); - coeff16 += 8; - _mm_store_si128((__m128i *)coeff16, src[2]); - coeff16 += 8; - _mm_store_si128((__m128i *)coeff16, src[3]); - coeff16 += 8; - _mm_store_si128((__m128i *)coeff16, src[4]); - coeff16 += 8; - _mm_store_si128((__m128i *)coeff16, src[5]); - coeff16 += 8; - _mm_store_si128((__m128i *)coeff16, src[6]); - coeff16 += 8; - _mm_store_si128((__m128i *)coeff16, src[7]); - } -} - -void vpx_hadamard_8x8_sse2(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { - hadamard_8x8_sse2(src_diff, src_stride, coeff, 1); -} - -static INLINE void hadamard_16x16_sse2(const int16_t *src_diff, - ptrdiff_t src_stride, tran_low_t *coeff, - int is_final) { -#if CONFIG_VP9_HIGHBITDEPTH - // For high bitdepths, it is unnecessary to store_tran_low - // (mult/unpack/store), then load_tran_low (load/pack) the same memory in the - // next stage. Output to an intermediate buffer first, then store_tran_low() - // in the final stage. - DECLARE_ALIGNED(32, int16_t, temp_coeff[16 * 16]); - int16_t *t_coeff = temp_coeff; -#else - int16_t *t_coeff = coeff; -#endif - int16_t *coeff16 = (int16_t *)coeff; - int idx; - for (idx = 0; idx < 4; ++idx) { - const int16_t *src_ptr = - src_diff + (idx >> 1) * 8 * src_stride + (idx & 0x01) * 8; - hadamard_8x8_sse2(src_ptr, src_stride, (tran_low_t *)(t_coeff + idx * 64), - 0); - } - - for (idx = 0; idx < 64; idx += 8) { - __m128i coeff0 = _mm_load_si128((const __m128i *)t_coeff); - __m128i coeff1 = _mm_load_si128((const __m128i *)(t_coeff + 64)); - __m128i coeff2 = _mm_load_si128((const __m128i *)(t_coeff + 128)); - __m128i coeff3 = _mm_load_si128((const __m128i *)(t_coeff + 192)); - - __m128i b0 = _mm_add_epi16(coeff0, coeff1); - __m128i b1 = _mm_sub_epi16(coeff0, coeff1); - __m128i b2 = _mm_add_epi16(coeff2, coeff3); - __m128i b3 = _mm_sub_epi16(coeff2, coeff3); - - b0 = _mm_srai_epi16(b0, 1); - b1 = _mm_srai_epi16(b1, 1); - b2 = _mm_srai_epi16(b2, 1); - b3 = _mm_srai_epi16(b3, 1); - - coeff0 = _mm_add_epi16(b0, b2); - coeff1 = _mm_add_epi16(b1, b3); - coeff2 = _mm_sub_epi16(b0, b2); - coeff3 = _mm_sub_epi16(b1, b3); - - if (is_final) { - store_tran_low(coeff0, coeff); - store_tran_low(coeff1, coeff + 64); - store_tran_low(coeff2, coeff + 128); - store_tran_low(coeff3, coeff + 192); - coeff += 8; - } else { - _mm_store_si128((__m128i *)coeff16, coeff0); - _mm_store_si128((__m128i *)(coeff16 + 64), coeff1); - _mm_store_si128((__m128i *)(coeff16 + 128), coeff2); - _mm_store_si128((__m128i *)(coeff16 + 192), coeff3); - coeff16 += 8; - } - - t_coeff += 8; - } -} - -void vpx_hadamard_16x16_sse2(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { - hadamard_16x16_sse2(src_diff, src_stride, coeff, 1); -} - -void vpx_hadamard_32x32_sse2(const int16_t *src_diff, ptrdiff_t src_stride, - tran_low_t *coeff) { -#if CONFIG_VP9_HIGHBITDEPTH - // For high bitdepths, it is unnecessary to store_tran_low - // (mult/unpack/store), then load_tran_low (load/pack) the same memory in the - // next stage. Output to an intermediate buffer first, then store_tran_low() - // in the final stage. - DECLARE_ALIGNED(32, int16_t, temp_coeff[32 * 32]); - int16_t *t_coeff = temp_coeff; -#else - int16_t *t_coeff = coeff; -#endif - int idx; - __m128i coeff0_lo, coeff1_lo, coeff2_lo, coeff3_lo, b0_lo, b1_lo, b2_lo, - b3_lo; - __m128i coeff0_hi, coeff1_hi, coeff2_hi, coeff3_hi, b0_hi, b1_hi, b2_hi, - b3_hi; - __m128i b0, b1, b2, b3; - const __m128i zero = _mm_setzero_si128(); - for (idx = 0; idx < 4; ++idx) { - const int16_t *src_ptr = - src_diff + (idx >> 1) * 16 * src_stride + (idx & 0x01) * 16; - hadamard_16x16_sse2(src_ptr, src_stride, - (tran_low_t *)(t_coeff + idx * 256), 0); - } - - for (idx = 0; idx < 256; idx += 8) { - __m128i coeff0 = _mm_load_si128((const __m128i *)t_coeff); - __m128i coeff1 = _mm_load_si128((const __m128i *)(t_coeff + 256)); - __m128i coeff2 = _mm_load_si128((const __m128i *)(t_coeff + 512)); - __m128i coeff3 = _mm_load_si128((const __m128i *)(t_coeff + 768)); - - // Sign extend 16 bit to 32 bit. - sign_extend_16bit_to_32bit_sse2(coeff0, zero, &coeff0_lo, &coeff0_hi); - sign_extend_16bit_to_32bit_sse2(coeff1, zero, &coeff1_lo, &coeff1_hi); - sign_extend_16bit_to_32bit_sse2(coeff2, zero, &coeff2_lo, &coeff2_hi); - sign_extend_16bit_to_32bit_sse2(coeff3, zero, &coeff3_lo, &coeff3_hi); - - b0_lo = _mm_add_epi32(coeff0_lo, coeff1_lo); - b0_hi = _mm_add_epi32(coeff0_hi, coeff1_hi); - - b1_lo = _mm_sub_epi32(coeff0_lo, coeff1_lo); - b1_hi = _mm_sub_epi32(coeff0_hi, coeff1_hi); - - b2_lo = _mm_add_epi32(coeff2_lo, coeff3_lo); - b2_hi = _mm_add_epi32(coeff2_hi, coeff3_hi); - - b3_lo = _mm_sub_epi32(coeff2_lo, coeff3_lo); - b3_hi = _mm_sub_epi32(coeff2_hi, coeff3_hi); - - b0_lo = _mm_srai_epi32(b0_lo, 2); - b1_lo = _mm_srai_epi32(b1_lo, 2); - b2_lo = _mm_srai_epi32(b2_lo, 2); - b3_lo = _mm_srai_epi32(b3_lo, 2); - - b0_hi = _mm_srai_epi32(b0_hi, 2); - b1_hi = _mm_srai_epi32(b1_hi, 2); - b2_hi = _mm_srai_epi32(b2_hi, 2); - b3_hi = _mm_srai_epi32(b3_hi, 2); - - b0 = _mm_packs_epi32(b0_lo, b0_hi); - b1 = _mm_packs_epi32(b1_lo, b1_hi); - b2 = _mm_packs_epi32(b2_lo, b2_hi); - b3 = _mm_packs_epi32(b3_lo, b3_hi); - - coeff0 = _mm_add_epi16(b0, b2); - coeff1 = _mm_add_epi16(b1, b3); - store_tran_low(coeff0, coeff); - store_tran_low(coeff1, coeff + 256); - - coeff2 = _mm_sub_epi16(b0, b2); - coeff3 = _mm_sub_epi16(b1, b3); - store_tran_low(coeff2, coeff + 512); - store_tran_low(coeff3, coeff + 768); - - coeff += 8; - t_coeff += 8; - } -} - -int vpx_satd_sse2(const tran_low_t *coeff, int length) { - int i; - const __m128i zero = _mm_setzero_si128(); - __m128i accum = zero; - - for (i = 0; i < length; i += 8) { - const __m128i src_line = load_tran_low(coeff); - const __m128i inv = _mm_sub_epi16(zero, src_line); - const __m128i abs = _mm_max_epi16(src_line, inv); // abs(src_line) - const __m128i abs_lo = _mm_unpacklo_epi16(abs, zero); - const __m128i abs_hi = _mm_unpackhi_epi16(abs, zero); - const __m128i sum = _mm_add_epi32(abs_lo, abs_hi); - accum = _mm_add_epi32(accum, sum); - coeff += 8; - } - - { // cascading summation of accum - __m128i hi = _mm_srli_si128(accum, 8); - accum = _mm_add_epi32(accum, hi); - hi = _mm_srli_epi64(accum, 32); - accum = _mm_add_epi32(accum, hi); - } - - return _mm_cvtsi128_si32(accum); -} - -void vpx_int_pro_row_sse2(int16_t hbuf[16], const uint8_t *ref, - const int ref_stride, const int height) { - int idx; - __m128i zero = _mm_setzero_si128(); - __m128i src_line = _mm_loadu_si128((const __m128i *)ref); - __m128i s0 = _mm_unpacklo_epi8(src_line, zero); - __m128i s1 = _mm_unpackhi_epi8(src_line, zero); - __m128i t0, t1; - int height_1 = height - 1; - ref += ref_stride; - - for (idx = 1; idx < height_1; idx += 2) { - src_line = _mm_loadu_si128((const __m128i *)ref); - t0 = _mm_unpacklo_epi8(src_line, zero); - t1 = _mm_unpackhi_epi8(src_line, zero); - s0 = _mm_adds_epu16(s0, t0); - s1 = _mm_adds_epu16(s1, t1); - ref += ref_stride; - - src_line = _mm_loadu_si128((const __m128i *)ref); - t0 = _mm_unpacklo_epi8(src_line, zero); - t1 = _mm_unpackhi_epi8(src_line, zero); - s0 = _mm_adds_epu16(s0, t0); - s1 = _mm_adds_epu16(s1, t1); - ref += ref_stride; - } - - src_line = _mm_loadu_si128((const __m128i *)ref); - t0 = _mm_unpacklo_epi8(src_line, zero); - t1 = _mm_unpackhi_epi8(src_line, zero); - s0 = _mm_adds_epu16(s0, t0); - s1 = _mm_adds_epu16(s1, t1); - - if (height == 64) { - s0 = _mm_srai_epi16(s0, 5); - s1 = _mm_srai_epi16(s1, 5); - } else if (height == 32) { - s0 = _mm_srai_epi16(s0, 4); - s1 = _mm_srai_epi16(s1, 4); - } else { - s0 = _mm_srai_epi16(s0, 3); - s1 = _mm_srai_epi16(s1, 3); - } - - _mm_storeu_si128((__m128i *)hbuf, s0); - hbuf += 8; - _mm_storeu_si128((__m128i *)hbuf, s1); -} - -int16_t vpx_int_pro_col_sse2(const uint8_t *ref, const int width) { - __m128i zero = _mm_setzero_si128(); - __m128i src_line = _mm_loadu_si128((const __m128i *)ref); - __m128i s0 = _mm_sad_epu8(src_line, zero); - __m128i s1; - int i; - - for (i = 16; i < width; i += 16) { - ref += 16; - src_line = _mm_loadu_si128((const __m128i *)ref); - s1 = _mm_sad_epu8(src_line, zero); - s0 = _mm_adds_epu16(s0, s1); - } - - s1 = _mm_srli_si128(s0, 8); - s0 = _mm_adds_epu16(s0, s1); - - return _mm_extract_epi16(s0, 0); -} - -int vpx_vector_var_sse2(const int16_t *ref, const int16_t *src, const int bwl) { - int idx; - int width = 4 << bwl; - int16_t mean; - __m128i v0 = _mm_loadu_si128((const __m128i *)ref); - __m128i v1 = _mm_load_si128((const __m128i *)src); - __m128i diff = _mm_subs_epi16(v0, v1); - __m128i sum = diff; - __m128i sse = _mm_madd_epi16(diff, diff); - - ref += 8; - src += 8; - - for (idx = 8; idx < width; idx += 8) { - v0 = _mm_loadu_si128((const __m128i *)ref); - v1 = _mm_load_si128((const __m128i *)src); - diff = _mm_subs_epi16(v0, v1); - - sum = _mm_add_epi16(sum, diff); - v0 = _mm_madd_epi16(diff, diff); - sse = _mm_add_epi32(sse, v0); - - ref += 8; - src += 8; - } - - v0 = _mm_srli_si128(sum, 8); - sum = _mm_add_epi16(sum, v0); - v0 = _mm_srli_epi64(sum, 32); - sum = _mm_add_epi16(sum, v0); - v0 = _mm_srli_epi32(sum, 16); - sum = _mm_add_epi16(sum, v0); - - v1 = _mm_srli_si128(sse, 8); - sse = _mm_add_epi32(sse, v1); - v1 = _mm_srli_epi64(sse, 32); - sse = _mm_add_epi32(sse, v1); - - mean = (int16_t)_mm_extract_epi16(sum, 0); - - return _mm_cvtsi128_si32(sse) - ((mean * mean) >> (bwl + 2)); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/avg_pred_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/avg_pred_avx2.c deleted file mode 100644 index f4357998..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/avg_pred_avx2.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" - -void vpx_comp_avg_pred_avx2(uint8_t *comp_pred, const uint8_t *pred, int width, - int height, const uint8_t *ref, int ref_stride) { - int row = 0; - // comp_pred and pred must be 32 byte aligned. - assert(((intptr_t)comp_pred % 32) == 0); - assert(((intptr_t)pred % 32) == 0); - - if (width == 8) { - assert(height % 4 == 0); - do { - const __m256i p = _mm256_load_si256((const __m256i *)pred); - const __m128i r_0 = _mm_loadl_epi64((const __m128i *)ref); - const __m128i r_1 = - _mm_loadl_epi64((const __m128i *)(ref + 2 * ref_stride)); - - const __m128i r1 = _mm_castps_si128(_mm_loadh_pi( - _mm_castsi128_ps(r_0), (const __m64 *)(ref + ref_stride))); - const __m128i r2 = _mm_castps_si128(_mm_loadh_pi( - _mm_castsi128_ps(r_1), (const __m64 *)(ref + 3 * ref_stride))); - - const __m256i ref_0123 = - _mm256_inserti128_si256(_mm256_castsi128_si256(r1), r2, 1); - const __m256i avg = _mm256_avg_epu8(p, ref_0123); - - _mm256_store_si256((__m256i *)comp_pred, avg); - - row += 4; - pred += 32; - comp_pred += 32; - ref += 4 * ref_stride; - } while (row < height); - } else if (width == 16) { - assert(height % 4 == 0); - do { - const __m256i pred_0 = _mm256_load_si256((const __m256i *)pred); - const __m256i pred_1 = _mm256_load_si256((const __m256i *)(pred + 32)); - const __m256i tmp0 = - _mm256_castsi128_si256(_mm_loadu_si128((const __m128i *)ref)); - const __m256i ref_0 = _mm256_inserti128_si256( - tmp0, _mm_loadu_si128((const __m128i *)(ref + ref_stride)), 1); - const __m256i tmp1 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(ref + 2 * ref_stride))); - const __m256i ref_1 = _mm256_inserti128_si256( - tmp1, _mm_loadu_si128((const __m128i *)(ref + 3 * ref_stride)), 1); - const __m256i average_0 = _mm256_avg_epu8(pred_0, ref_0); - const __m256i average_1 = _mm256_avg_epu8(pred_1, ref_1); - _mm256_store_si256((__m256i *)comp_pred, average_0); - _mm256_store_si256((__m256i *)(comp_pred + 32), average_1); - - row += 4; - pred += 64; - comp_pred += 64; - ref += 4 * ref_stride; - } while (row < height); - } else if (width == 32) { - assert(height % 2 == 0); - do { - const __m256i pred_0 = _mm256_load_si256((const __m256i *)pred); - const __m256i pred_1 = _mm256_load_si256((const __m256i *)(pred + 32)); - const __m256i ref_0 = _mm256_loadu_si256((const __m256i *)ref); - const __m256i ref_1 = - _mm256_loadu_si256((const __m256i *)(ref + ref_stride)); - const __m256i average_0 = _mm256_avg_epu8(pred_0, ref_0); - const __m256i average_1 = _mm256_avg_epu8(pred_1, ref_1); - _mm256_store_si256((__m256i *)comp_pred, average_0); - _mm256_store_si256((__m256i *)(comp_pred + 32), average_1); - - row += 2; - pred += 64; - comp_pred += 64; - ref += 2 * ref_stride; - } while (row < height); - } else if (width % 64 == 0) { - do { - int x; - for (x = 0; x < width; x += 64) { - const __m256i pred_0 = _mm256_load_si256((const __m256i *)(pred + x)); - const __m256i pred_1 = - _mm256_load_si256((const __m256i *)(pred + x + 32)); - const __m256i ref_0 = _mm256_loadu_si256((const __m256i *)(ref + x)); - const __m256i ref_1 = - _mm256_loadu_si256((const __m256i *)(ref + x + 32)); - const __m256i average_0 = _mm256_avg_epu8(pred_0, ref_0); - const __m256i average_1 = _mm256_avg_epu8(pred_1, ref_1); - _mm256_store_si256((__m256i *)(comp_pred + x), average_0); - _mm256_store_si256((__m256i *)(comp_pred + x + 32), average_1); - } - row++; - pred += width; - comp_pred += width; - ref += ref_stride; - } while (row < height); - } else { - vpx_comp_avg_pred_sse2(comp_pred, pred, width, height, ref, ref_stride); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/avg_pred_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/avg_pred_sse2.c deleted file mode 100644 index c6e70f74..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/avg_pred_sse2.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/x86/mem_sse2.h" - -void vpx_comp_avg_pred_sse2(uint8_t *comp_pred, const uint8_t *pred, int width, - int height, const uint8_t *ref, int ref_stride) { - /* comp_pred and pred must be 16 byte aligned. */ - assert(((intptr_t)comp_pred & 0xf) == 0); - assert(((intptr_t)pred & 0xf) == 0); - if (width > 8) { - int x, y; - for (y = 0; y < height; ++y) { - for (x = 0; x < width; x += 16) { - const __m128i p = _mm_load_si128((const __m128i *)(pred + x)); - const __m128i r = _mm_loadu_si128((const __m128i *)(ref + x)); - const __m128i avg = _mm_avg_epu8(p, r); - _mm_store_si128((__m128i *)(comp_pred + x), avg); - } - comp_pred += width; - pred += width; - ref += ref_stride; - } - } else { // width must be 4 or 8. - int i; - // Process 16 elements at a time. comp_pred and pred have width == stride - // and therefore live in contigious memory. 4*4, 4*8, 8*4, 8*8, and 8*16 are - // all divisible by 16 so just ref needs to be massaged when loading. - for (i = 0; i < width * height; i += 16) { - const __m128i p = _mm_load_si128((const __m128i *)pred); - __m128i r; - __m128i avg; - if (width == ref_stride) { - r = _mm_loadu_si128((const __m128i *)ref); - ref += 16; - } else if (width == 4) { - r = _mm_set_epi32(loadu_int32(ref + 3 * ref_stride), - loadu_int32(ref + 2 * ref_stride), - loadu_int32(ref + ref_stride), loadu_int32(ref)); - - ref += 4 * ref_stride; - } else { - const __m128i r_0 = _mm_loadl_epi64((const __m128i *)ref); - assert(width == 8); - r = _mm_castps_si128(_mm_loadh_pi(_mm_castsi128_ps(r_0), - (const __m64 *)(ref + ref_stride))); - - ref += 2 * ref_stride; - } - avg = _mm_avg_epu8(p, r); - _mm_store_si128((__m128i *)comp_pred, avg); - - pred += 16; - comp_pred += 16; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/avg_ssse3_x86_64.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/avg_ssse3_x86_64.asm deleted file mode 100644 index 9122b5a4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/avg_ssse3_x86_64.asm +++ /dev/null @@ -1,130 +0,0 @@ -; -; Copyright (c) 2014 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "third_party/x86inc/x86inc.asm" -%include "vpx_dsp/x86/bitdepth_conversion_sse2.asm" - -SECTION .text - -%if VPX_ARCH_X86_64 -; matrix transpose -%macro TRANSPOSE8X8 10 - ; stage 1 - punpcklwd m%9, m%1, m%2 - punpcklwd m%10, m%3, m%4 - punpckhwd m%1, m%2 - punpckhwd m%3, m%4 - - punpcklwd m%2, m%5, m%6 - punpcklwd m%4, m%7, m%8 - punpckhwd m%5, m%6 - punpckhwd m%7, m%8 - - ; stage 2 - punpckldq m%6, m%9, m%10 - punpckldq m%8, m%1, m%3 - punpckhdq m%9, m%10 - punpckhdq m%1, m%3 - - punpckldq m%10, m%2, m%4 - punpckldq m%3, m%5, m%7 - punpckhdq m%2, m%4 - punpckhdq m%5, m%7 - - ; stage 3 - punpckhqdq m%4, m%9, m%2 ; out3 - punpcklqdq m%9, m%2 ; out2 - punpcklqdq m%7, m%1, m%5 ; out6 - punpckhqdq m%1, m%5 ; out7 - - punpckhqdq m%2, m%6, m%10 ; out1 - punpcklqdq m%6, m%10 ; out0 - punpcklqdq m%5, m%8, m%3 ; out4 - punpckhqdq m%8, m%3 ; out5 - - SWAP %6, %1 - SWAP %3, %9 - SWAP %8, %6 -%endmacro - -%macro HMD8_1D 0 - psubw m8, m0, m1 - psubw m9, m2, m3 - paddw m0, m1 - paddw m2, m3 - SWAP 1, 8 - SWAP 3, 9 - psubw m8, m4, m5 - psubw m9, m6, m7 - paddw m4, m5 - paddw m6, m7 - SWAP 5, 8 - SWAP 7, 9 - - psubw m8, m0, m2 - psubw m9, m1, m3 - paddw m0, m2 - paddw m1, m3 - SWAP 2, 8 - SWAP 3, 9 - psubw m8, m4, m6 - psubw m9, m5, m7 - paddw m4, m6 - paddw m5, m7 - SWAP 6, 8 - SWAP 7, 9 - - psubw m8, m0, m4 - psubw m9, m1, m5 - paddw m0, m4 - paddw m1, m5 - SWAP 4, 8 - SWAP 5, 9 - psubw m8, m2, m6 - psubw m9, m3, m7 - paddw m2, m6 - paddw m3, m7 - SWAP 6, 8 - SWAP 7, 9 -%endmacro - - -INIT_XMM ssse3 -cglobal hadamard_8x8, 3, 5, 11, input, stride, output - lea r3, [2 * strideq] - lea r4, [4 * strideq] - - mova m0, [inputq] - mova m1, [inputq + r3] - lea inputq, [inputq + r4] - mova m2, [inputq] - mova m3, [inputq + r3] - lea inputq, [inputq + r4] - mova m4, [inputq] - mova m5, [inputq + r3] - lea inputq, [inputq + r4] - mova m6, [inputq] - mova m7, [inputq + r3] - - HMD8_1D - TRANSPOSE8X8 0, 1, 2, 3, 4, 5, 6, 7, 9, 10 - HMD8_1D - - STORE_TRAN_LOW 0, outputq, 0, 8, 9 - STORE_TRAN_LOW 1, outputq, 8, 8, 9 - STORE_TRAN_LOW 2, outputq, 16, 8, 9 - STORE_TRAN_LOW 3, outputq, 24, 8, 9 - STORE_TRAN_LOW 4, outputq, 32, 8, 9 - STORE_TRAN_LOW 5, outputq, 40, 8, 9 - STORE_TRAN_LOW 6, outputq, 48, 8, 9 - STORE_TRAN_LOW 7, outputq, 56, 8, 9 - - RET -%endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/bitdepth_conversion_avx2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/bitdepth_conversion_avx2.h deleted file mode 100644 index c02b47a3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/bitdepth_conversion_avx2.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_VPX_DSP_X86_BITDEPTH_CONVERSION_AVX2_H_ -#define VPX_VPX_DSP_X86_BITDEPTH_CONVERSION_AVX2_H_ - -#include - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/vpx_dsp_common.h" - -// Load 16 16 bit values. If the source is 32 bits then pack down with -// saturation. -static INLINE __m256i load_tran_low(const tran_low_t *a) { -#if CONFIG_VP9_HIGHBITDEPTH - const __m256i a_low = _mm256_loadu_si256((const __m256i *)a); - const __m256i a_high = _mm256_loadu_si256((const __m256i *)(a + 8)); - return _mm256_packs_epi32(a_low, a_high); -#else - return _mm256_loadu_si256((const __m256i *)a); -#endif -} - -static INLINE void store_tran_low(__m256i a, tran_low_t *b) { -#if CONFIG_VP9_HIGHBITDEPTH - const __m256i one = _mm256_set1_epi16(1); - const __m256i a_hi = _mm256_mulhi_epi16(a, one); - const __m256i a_lo = _mm256_mullo_epi16(a, one); - const __m256i a_1 = _mm256_unpacklo_epi16(a_lo, a_hi); - const __m256i a_2 = _mm256_unpackhi_epi16(a_lo, a_hi); - _mm256_storeu_si256((__m256i *)b, a_1); - _mm256_storeu_si256((__m256i *)(b + 8), a_2); -#else - _mm256_storeu_si256((__m256i *)b, a); -#endif -} -#endif // VPX_VPX_DSP_X86_BITDEPTH_CONVERSION_AVX2_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/bitdepth_conversion_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/bitdepth_conversion_sse2.asm deleted file mode 100644 index aacf71f7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/bitdepth_conversion_sse2.asm +++ /dev/null @@ -1,90 +0,0 @@ -; -; Copyright (c) 2017 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -; TODO(johannkoenig): Add the necessary include guards to vpx_config.asm. -; vpx_config.asm is not guarded so can not be included twice. Because this will -; be used in conjunction with x86_abi_support.asm or x86inc.asm, it must be -; included after those files. - -; Increment register by sizeof() tran_low_t * 8. -%macro INCREMENT_TRAN_LOW 1 -%if CONFIG_VP9_HIGHBITDEPTH - add %1, 32 -%else - add %1, 16 -%endif -%endmacro - -; Increment %1 by sizeof() tran_low_t * %2. -%macro INCREMENT_ELEMENTS_TRAN_LOW 2 -%if CONFIG_VP9_HIGHBITDEPTH - lea %1, [%1 + %2 * 4] -%else - lea %1, [%1 + %2 * 2] -%endif -%endmacro - -; Load %2 + %3 into m%1. -; %3 is the offset in elements, not bytes. -; If tran_low_t is 16 bits (low bit depth configuration) then load the value -; directly. If tran_low_t is 32 bits (high bit depth configuration) then pack -; the values down to 16 bits. -%macro LOAD_TRAN_LOW 3 -%if CONFIG_VP9_HIGHBITDEPTH - mova m%1, [%2 + (%3) * 4] - packssdw m%1, [%2 + (%3) * 4 + 16] -%else - mova m%1, [%2 + (%3) * 2] -%endif -%endmacro - -; Store m%1 to %2 + %3. -; %3 is the offset in elements, not bytes. -; If 5 arguments are provided then m%1 is corrupted. -; If 6 arguments are provided then m%1 is preserved. -; If tran_low_t is 16 bits (low bit depth configuration) then store the value -; directly. If tran_low_t is 32 bits (high bit depth configuration) then sign -; extend the values first. -; Uses m%4-m%6 as scratch registers for high bit depth. -%macro STORE_TRAN_LOW 5-6 -%if CONFIG_VP9_HIGHBITDEPTH - pxor m%4, m%4 - mova m%5, m%1 - %if %0 == 6 - mova m%6, m%1 - %endif - pcmpgtw m%4, m%1 - punpcklwd m%5, m%4 - %if %0 == 5 - punpckhwd m%1, m%4 - %else - punpckhwd m%6, m%4 - %endif - mova [%2 + (%3) * 4 + 0], m%5 - %if %0 == 5 - mova [%2 + (%3) * 4 + 16], m%1 - %else - mova [%2 + (%3) * 4 + 16], m%6 - %endif -%else - mova [%2 + (%3) * 2], m%1 -%endif -%endmacro - -; Store zeros (in m%1) to %2 + %3. -; %3 is the offset in elements, not bytes. -%macro STORE_ZERO_TRAN_LOW 3 -%if CONFIG_VP9_HIGHBITDEPTH - mova [%2 + (%3) * 4 + 0], m%1 - mova [%2 + (%3) * 4 + 16], m%1 -%else - mova [%2 + (%3) * 2], m%1 -%endif -%endmacro diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/bitdepth_conversion_sse2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/bitdepth_conversion_sse2.h deleted file mode 100644 index 74dde656..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/bitdepth_conversion_sse2.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_VPX_DSP_X86_BITDEPTH_CONVERSION_SSE2_H_ -#define VPX_VPX_DSP_X86_BITDEPTH_CONVERSION_SSE2_H_ - -#include - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/vpx_dsp_common.h" - -// Load 8 16 bit values. If the source is 32 bits then pack down with -// saturation. -static INLINE __m128i load_tran_low(const tran_low_t *a) { -#if CONFIG_VP9_HIGHBITDEPTH - const __m128i a_low = _mm_load_si128((const __m128i *)a); - return _mm_packs_epi32(a_low, *(const __m128i *)(a + 4)); -#else - return _mm_load_si128((const __m128i *)a); -#endif -} - -// Store 8 16 bit values. If the destination is 32 bits then sign extend the -// values by multiplying by 1. -static INLINE void store_tran_low(__m128i a, tran_low_t *b) { -#if CONFIG_VP9_HIGHBITDEPTH - const __m128i one = _mm_set1_epi16(1); - const __m128i a_hi = _mm_mulhi_epi16(a, one); - const __m128i a_lo = _mm_mullo_epi16(a, one); - const __m128i a_1 = _mm_unpacklo_epi16(a_lo, a_hi); - const __m128i a_2 = _mm_unpackhi_epi16(a_lo, a_hi); - _mm_store_si128((__m128i *)(b), a_1); - _mm_store_si128((__m128i *)(b + 4), a_2); -#else - _mm_store_si128((__m128i *)(b), a); -#endif -} - -// Zero fill 8 positions in the output buffer. -static INLINE void store_zero_tran_low(tran_low_t *a) { - const __m128i zero = _mm_setzero_si128(); -#if CONFIG_VP9_HIGHBITDEPTH - _mm_store_si128((__m128i *)(a), zero); - _mm_store_si128((__m128i *)(a + 4), zero); -#else - _mm_store_si128((__m128i *)(a), zero); -#endif -} -#endif // VPX_VPX_DSP_X86_BITDEPTH_CONVERSION_SSE2_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/convolve.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/convolve.h deleted file mode 100644 index c3396005..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/convolve.h +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_VPX_DSP_X86_CONVOLVE_H_ -#define VPX_VPX_DSP_X86_CONVOLVE_H_ - -#include - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vpx_ports/compiler_attributes.h" - -// TODO(chiyotsai@google.com): Refactor the code here. Currently this is pretty -// hacky and awful to read. Note that there is a filter_x[3] == 128 check in -// HIGHBD_FUN_CONV_2D to avoid seg fault due to the fact that the c function -// assumes the filter is always 8 tap. -typedef void filter8_1dfunction(const uint8_t *src_ptr, ptrdiff_t src_pitch, - uint8_t *output_ptr, ptrdiff_t out_pitch, - uint32_t output_height, const int16_t *filter); - -// TODO(chiyotsai@google.com): Remove the is_avg argument to the MACROS once we -// have 4-tap vert avg filter. -#define FUN_CONV_1D(name, offset, step_q4, dir, src_start, avg, opt, is_avg) \ - void vpx_convolve8_##name##_##opt( \ - const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, \ - ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, \ - int x_step_q4, int y0_q4, int y_step_q4, int w, int h) { \ - const int16_t *filter_row = filter[offset]; \ - (void)x0_q4; \ - (void)x_step_q4; \ - (void)y0_q4; \ - (void)y_step_q4; \ - assert(filter_row[3] != 128); \ - assert(step_q4 == 16); \ - if (filter_row[0] | filter_row[1] | filter_row[6] | filter_row[7]) { \ - const int num_taps = 8; \ - while (w >= 16) { \ - vpx_filter_block1d16_##dir##8_##avg##opt(src_start, src_stride, dst, \ - dst_stride, h, filter_row); \ - src += 16; \ - dst += 16; \ - w -= 16; \ - } \ - if (w == 8) { \ - vpx_filter_block1d8_##dir##8_##avg##opt(src_start, src_stride, dst, \ - dst_stride, h, filter_row); \ - } else if (w == 4) { \ - vpx_filter_block1d4_##dir##8_##avg##opt(src_start, src_stride, dst, \ - dst_stride, h, filter_row); \ - } \ - (void)num_taps; \ - } else if (filter_row[2] | filter_row[5]) { \ - const int num_taps = is_avg ? 8 : 4; \ - while (w >= 16) { \ - vpx_filter_block1d16_##dir##4_##avg##opt(src_start, src_stride, dst, \ - dst_stride, h, filter_row); \ - src += 16; \ - dst += 16; \ - w -= 16; \ - } \ - if (w == 8) { \ - vpx_filter_block1d8_##dir##4_##avg##opt(src_start, src_stride, dst, \ - dst_stride, h, filter_row); \ - } else if (w == 4) { \ - vpx_filter_block1d4_##dir##4_##avg##opt(src_start, src_stride, dst, \ - dst_stride, h, filter_row); \ - } \ - (void)num_taps; \ - } else { \ - const int num_taps = 2; \ - while (w >= 16) { \ - vpx_filter_block1d16_##dir##2_##avg##opt(src_start, src_stride, dst, \ - dst_stride, h, filter_row); \ - src += 16; \ - dst += 16; \ - w -= 16; \ - } \ - if (w == 8) { \ - vpx_filter_block1d8_##dir##2_##avg##opt(src_start, src_stride, dst, \ - dst_stride, h, filter_row); \ - } else if (w == 4) { \ - vpx_filter_block1d4_##dir##2_##avg##opt(src_start, src_stride, dst, \ - dst_stride, h, filter_row); \ - } \ - (void)num_taps; \ - } \ - } - -#define FUN_CONV_2D(avg, opt, is_avg) \ - void vpx_convolve8_##avg##opt( \ - const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, \ - ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, \ - int x_step_q4, int y0_q4, int y_step_q4, int w, int h) { \ - const int16_t *filter_x = filter[x0_q4]; \ - const int16_t *filter_y = filter[y0_q4]; \ - (void)filter_y; \ - assert(filter_x[3] != 128); \ - assert(filter_y[3] != 128); \ - assert(w <= 64); \ - assert(h <= 64); \ - assert(x_step_q4 == 16); \ - assert(y_step_q4 == 16); \ - if (filter_x[0] | filter_x[1] | filter_x[6] | filter_x[7]) { \ - DECLARE_ALIGNED(16, uint8_t, fdata2[64 * 71] VPX_UNINITIALIZED); \ - vpx_convolve8_horiz_##opt(src - 3 * src_stride, src_stride, fdata2, 64, \ - filter, x0_q4, x_step_q4, y0_q4, y_step_q4, w, \ - h + 7); \ - vpx_convolve8_##avg##vert_##opt(fdata2 + 3 * 64, 64, dst, dst_stride, \ - filter, x0_q4, x_step_q4, y0_q4, \ - y_step_q4, w, h); \ - } else if (filter_x[2] | filter_x[5]) { \ - const int num_taps = is_avg ? 8 : 4; \ - DECLARE_ALIGNED(16, uint8_t, fdata2[64 * 71] VPX_UNINITIALIZED); \ - vpx_convolve8_horiz_##opt( \ - src - (num_taps / 2 - 1) * src_stride, src_stride, fdata2, 64, \ - filter, x0_q4, x_step_q4, y0_q4, y_step_q4, w, h + num_taps - 1); \ - vpx_convolve8_##avg##vert_##opt(fdata2 + 64 * (num_taps / 2 - 1), 64, \ - dst, dst_stride, filter, x0_q4, \ - x_step_q4, y0_q4, y_step_q4, w, h); \ - } else { \ - DECLARE_ALIGNED(16, uint8_t, fdata2[64 * 65] VPX_UNINITIALIZED); \ - vpx_convolve8_horiz_##opt(src, src_stride, fdata2, 64, filter, x0_q4, \ - x_step_q4, y0_q4, y_step_q4, w, h + 1); \ - vpx_convolve8_##avg##vert_##opt(fdata2, 64, dst, dst_stride, filter, \ - x0_q4, x_step_q4, y0_q4, y_step_q4, w, \ - h); \ - } \ - } - -#if CONFIG_VP9_HIGHBITDEPTH - -typedef void highbd_filter8_1dfunction(const uint16_t *src_ptr, - const ptrdiff_t src_pitch, - uint16_t *output_ptr, - ptrdiff_t out_pitch, - unsigned int output_height, - const int16_t *filter, int bd); - -#define HIGH_FUN_CONV_1D(name, offset, step_q4, dir, src_start, avg, opt, \ - is_avg) \ - void vpx_highbd_convolve8_##name##_##opt( \ - const uint16_t *src, ptrdiff_t src_stride, uint16_t *dst, \ - ptrdiff_t dst_stride, const InterpKernel *filter_kernel, int x0_q4, \ - int x_step_q4, int y0_q4, int y_step_q4, int w, int h, int bd) { \ - const int16_t *filter_row = filter_kernel[offset]; \ - if (step_q4 == 16 && filter_row[3] != 128) { \ - if (filter_row[0] | filter_row[1] | filter_row[6] | filter_row[7]) { \ - const int num_taps = 8; \ - while (w >= 16) { \ - vpx_highbd_filter_block1d16_##dir##8_##avg##opt( \ - src_start, src_stride, dst, dst_stride, h, filter_row, bd); \ - src += 16; \ - dst += 16; \ - w -= 16; \ - } \ - while (w >= 8) { \ - vpx_highbd_filter_block1d8_##dir##8_##avg##opt( \ - src_start, src_stride, dst, dst_stride, h, filter_row, bd); \ - src += 8; \ - dst += 8; \ - w -= 8; \ - } \ - while (w >= 4) { \ - vpx_highbd_filter_block1d4_##dir##8_##avg##opt( \ - src_start, src_stride, dst, dst_stride, h, filter_row, bd); \ - src += 4; \ - dst += 4; \ - w -= 4; \ - } \ - (void)num_taps; \ - } else if (filter_row[2] | filter_row[5]) { \ - const int num_taps = is_avg ? 8 : 4; \ - while (w >= 16) { \ - vpx_highbd_filter_block1d16_##dir##4_##avg##opt( \ - src_start, src_stride, dst, dst_stride, h, filter_row, bd); \ - src += 16; \ - dst += 16; \ - w -= 16; \ - } \ - while (w >= 8) { \ - vpx_highbd_filter_block1d8_##dir##4_##avg##opt( \ - src_start, src_stride, dst, dst_stride, h, filter_row, bd); \ - src += 8; \ - dst += 8; \ - w -= 8; \ - } \ - while (w >= 4) { \ - vpx_highbd_filter_block1d4_##dir##4_##avg##opt( \ - src_start, src_stride, dst, dst_stride, h, filter_row, bd); \ - src += 4; \ - dst += 4; \ - w -= 4; \ - } \ - (void)num_taps; \ - } else { \ - const int num_taps = 2; \ - while (w >= 16) { \ - vpx_highbd_filter_block1d16_##dir##2_##avg##opt( \ - src_start, src_stride, dst, dst_stride, h, filter_row, bd); \ - src += 16; \ - dst += 16; \ - w -= 16; \ - } \ - while (w >= 8) { \ - vpx_highbd_filter_block1d8_##dir##2_##avg##opt( \ - src_start, src_stride, dst, dst_stride, h, filter_row, bd); \ - src += 8; \ - dst += 8; \ - w -= 8; \ - } \ - while (w >= 4) { \ - vpx_highbd_filter_block1d4_##dir##2_##avg##opt( \ - src_start, src_stride, dst, dst_stride, h, filter_row, bd); \ - src += 4; \ - dst += 4; \ - w -= 4; \ - } \ - (void)num_taps; \ - } \ - } \ - if (w) { \ - vpx_highbd_convolve8_##name##_c(src, src_stride, dst, dst_stride, \ - filter_kernel, x0_q4, x_step_q4, y0_q4, \ - y_step_q4, w, h, bd); \ - } \ - } - -#define HIGH_FUN_CONV_2D(avg, opt, is_avg) \ - void vpx_highbd_convolve8_##avg##opt( \ - const uint16_t *src, ptrdiff_t src_stride, uint16_t *dst, \ - ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, \ - int x_step_q4, int y0_q4, int y_step_q4, int w, int h, int bd) { \ - const int16_t *filter_x = filter[x0_q4]; \ - assert(w <= 64); \ - assert(h <= 64); \ - if (x_step_q4 == 16 && y_step_q4 == 16) { \ - if ((filter_x[0] | filter_x[1] | filter_x[6] | filter_x[7]) || \ - filter_x[3] == 128) { \ - DECLARE_ALIGNED(16, uint16_t, fdata2[64 * 71] VPX_UNINITIALIZED); \ - vpx_highbd_convolve8_horiz_##opt(src - 3 * src_stride, src_stride, \ - fdata2, 64, filter, x0_q4, x_step_q4, \ - y0_q4, y_step_q4, w, h + 7, bd); \ - vpx_highbd_convolve8_##avg##vert_##opt( \ - fdata2 + 192, 64, dst, dst_stride, filter, x0_q4, x_step_q4, \ - y0_q4, y_step_q4, w, h, bd); \ - } else if (filter_x[2] | filter_x[5]) { \ - const int num_taps = is_avg ? 8 : 4; \ - DECLARE_ALIGNED(16, uint16_t, fdata2[64 * 71] VPX_UNINITIALIZED); \ - vpx_highbd_convolve8_horiz_##opt( \ - src - (num_taps / 2 - 1) * src_stride, src_stride, fdata2, 64, \ - filter, x0_q4, x_step_q4, y0_q4, y_step_q4, w, h + num_taps - 1, \ - bd); \ - vpx_highbd_convolve8_##avg##vert_##opt( \ - fdata2 + 64 * (num_taps / 2 - 1), 64, dst, dst_stride, filter, \ - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h, bd); \ - } else { \ - DECLARE_ALIGNED(16, uint16_t, fdata2[64 * 65] VPX_UNINITIALIZED); \ - vpx_highbd_convolve8_horiz_##opt(src, src_stride, fdata2, 64, filter, \ - x0_q4, x_step_q4, y0_q4, y_step_q4, \ - w, h + 1, bd); \ - vpx_highbd_convolve8_##avg##vert_##opt(fdata2, 64, dst, dst_stride, \ - filter, x0_q4, x_step_q4, \ - y0_q4, y_step_q4, w, h, bd); \ - } \ - } else { \ - vpx_highbd_convolve8_##avg##c(src, src_stride, dst, dst_stride, filter, \ - x0_q4, x_step_q4, y0_q4, y_step_q4, w, h, \ - bd); \ - } \ - } - -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif // VPX_VPX_DSP_X86_CONVOLVE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/convolve_avx2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/convolve_avx2.h deleted file mode 100644 index ebee964b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/convolve_avx2.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_X86_CONVOLVE_AVX2_H_ -#define VPX_VPX_DSP_X86_CONVOLVE_AVX2_H_ - -#include // AVX2 - -#include "./vpx_config.h" - -#if defined(__clang__) -#if (__clang_major__ > 0 && __clang_major__ < 3) || \ - (__clang_major__ == 3 && __clang_minor__ <= 3) || \ - (defined(__APPLE__) && defined(__apple_build_version__) && \ - ((__clang_major__ == 4 && __clang_minor__ <= 2) || \ - (__clang_major__ == 5 && __clang_minor__ == 0))) -#define MM256_BROADCASTSI128_SI256(x) \ - _mm_broadcastsi128_si256((__m128i const *)&(x)) -#else // clang > 3.3, and not 5.0 on macosx. -#define MM256_BROADCASTSI128_SI256(x) _mm256_broadcastsi128_si256(x) -#endif // clang <= 3.3 -#elif defined(__GNUC__) -#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ <= 6) -#define MM256_BROADCASTSI128_SI256(x) \ - _mm_broadcastsi128_si256((__m128i const *)&(x)) -#elif __GNUC__ == 4 && __GNUC_MINOR__ == 7 -#define MM256_BROADCASTSI128_SI256(x) _mm_broadcastsi128_si256(x) -#else // gcc > 4.7 -#define MM256_BROADCASTSI128_SI256(x) _mm256_broadcastsi128_si256(x) -#endif // gcc <= 4.6 -#else // !(gcc || clang) -#define MM256_BROADCASTSI128_SI256(x) _mm256_broadcastsi128_si256(x) -#endif // __clang__ - -static INLINE void shuffle_filter_avx2(const int16_t *const filter, - __m256i *const f) { - const __m256i f_values = - MM256_BROADCASTSI128_SI256(_mm_load_si128((const __m128i *)filter)); - // pack and duplicate the filter values - f[0] = _mm256_shuffle_epi8(f_values, _mm256_set1_epi16(0x0200u)); - f[1] = _mm256_shuffle_epi8(f_values, _mm256_set1_epi16(0x0604u)); - f[2] = _mm256_shuffle_epi8(f_values, _mm256_set1_epi16(0x0a08u)); - f[3] = _mm256_shuffle_epi8(f_values, _mm256_set1_epi16(0x0e0cu)); -} - -static INLINE __m256i convolve8_16_avx2(const __m256i *const s, - const __m256i *const f) { - // multiply 2 adjacent elements with the filter and add the result - const __m256i k_64 = _mm256_set1_epi16(1 << 6); - const __m256i x0 = _mm256_maddubs_epi16(s[0], f[0]); - const __m256i x1 = _mm256_maddubs_epi16(s[1], f[1]); - const __m256i x2 = _mm256_maddubs_epi16(s[2], f[2]); - const __m256i x3 = _mm256_maddubs_epi16(s[3], f[3]); - __m256i sum1, sum2; - - // sum the results together, saturating only on the final step - // adding x0 with x2 and x1 with x3 is the only order that prevents - // outranges for all filters - sum1 = _mm256_add_epi16(x0, x2); - sum2 = _mm256_add_epi16(x1, x3); - // add the rounding offset early to avoid another saturated add - sum1 = _mm256_add_epi16(sum1, k_64); - sum1 = _mm256_adds_epi16(sum1, sum2); - // round and shift by 7 bit each 16 bit - sum1 = _mm256_srai_epi16(sum1, 7); - return sum1; -} - -static INLINE __m128i convolve8_8_avx2(const __m256i *const s, - const __m256i *const f) { - // multiply 2 adjacent elements with the filter and add the result - const __m128i k_64 = _mm_set1_epi16(1 << 6); - const __m128i x0 = _mm_maddubs_epi16(_mm256_castsi256_si128(s[0]), - _mm256_castsi256_si128(f[0])); - const __m128i x1 = _mm_maddubs_epi16(_mm256_castsi256_si128(s[1]), - _mm256_castsi256_si128(f[1])); - const __m128i x2 = _mm_maddubs_epi16(_mm256_castsi256_si128(s[2]), - _mm256_castsi256_si128(f[2])); - const __m128i x3 = _mm_maddubs_epi16(_mm256_castsi256_si128(s[3]), - _mm256_castsi256_si128(f[3])); - __m128i sum1, sum2; - - // sum the results together, saturating only on the final step - // adding x0 with x2 and x1 with x3 is the only order that prevents - // outranges for all filters - sum1 = _mm_add_epi16(x0, x2); - sum2 = _mm_add_epi16(x1, x3); - // add the rounding offset early to avoid another saturated add - sum1 = _mm_add_epi16(sum1, k_64); - sum1 = _mm_adds_epi16(sum1, sum2); - // shift by 7 bit each 16 bit - sum1 = _mm_srai_epi16(sum1, 7); - return sum1; -} - -static INLINE __m256i mm256_loadu2_si128(const void *lo, const void *hi) { - const __m256i tmp = - _mm256_castsi128_si256(_mm_loadu_si128((const __m128i *)lo)); - return _mm256_inserti128_si256(tmp, _mm_loadu_si128((const __m128i *)hi), 1); -} - -static INLINE __m256i mm256_loadu2_epi64(const void *lo, const void *hi) { - const __m256i tmp = - _mm256_castsi128_si256(_mm_loadl_epi64((const __m128i *)lo)); - return _mm256_inserti128_si256(tmp, _mm_loadl_epi64((const __m128i *)hi), 1); -} - -static INLINE void mm256_store2_si128(__m128i *const dst_ptr_1, - __m128i *const dst_ptr_2, - const __m256i *const src) { - _mm_store_si128(dst_ptr_1, _mm256_castsi256_si128(*src)); - _mm_store_si128(dst_ptr_2, _mm256_extractf128_si256(*src, 1)); -} - -static INLINE void mm256_storeu2_epi64(__m128i *const dst_ptr_1, - __m128i *const dst_ptr_2, - const __m256i *const src) { - _mm_storel_epi64(dst_ptr_1, _mm256_castsi256_si128(*src)); - _mm_storel_epi64(dst_ptr_2, _mm256_extractf128_si256(*src, 1)); -} - -static INLINE void mm256_storeu2_epi32(__m128i *const dst_ptr_1, - __m128i *const dst_ptr_2, - const __m256i *const src) { - *((int *)(dst_ptr_1)) = _mm_cvtsi128_si32(_mm256_castsi256_si128(*src)); - *((int *)(dst_ptr_2)) = _mm_cvtsi128_si32(_mm256_extractf128_si256(*src, 1)); -} - -static INLINE __m256i mm256_round_epi32(const __m256i *const src, - const __m256i *const half_depth, - const int depth) { - const __m256i nearest_src = _mm256_add_epi32(*src, *half_depth); - return _mm256_srai_epi32(nearest_src, depth); -} - -static INLINE __m256i mm256_round_epi16(const __m256i *const src, - const __m256i *const half_depth, - const int depth) { - const __m256i nearest_src = _mm256_adds_epi16(*src, *half_depth); - return _mm256_srai_epi16(nearest_src, depth); -} - -static INLINE __m256i mm256_madd_add_epi32(const __m256i *const src_0, - const __m256i *const src_1, - const __m256i *const ker_0, - const __m256i *const ker_1) { - const __m256i tmp_0 = _mm256_madd_epi16(*src_0, *ker_0); - const __m256i tmp_1 = _mm256_madd_epi16(*src_1, *ker_1); - return _mm256_add_epi32(tmp_0, tmp_1); -} - -#undef MM256_BROADCASTSI128_SI256 - -#endif // VPX_VPX_DSP_X86_CONVOLVE_AVX2_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/convolve_sse2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/convolve_sse2.h deleted file mode 100644 index 84435463..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/convolve_sse2.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_X86_CONVOLVE_SSE2_H_ -#define VPX_VPX_DSP_X86_CONVOLVE_SSE2_H_ - -#include // SSE2 - -#include "./vpx_config.h" - -// Interprets the input register as 16-bit words 7 6 5 4 3 2 1 0, then returns -// values at index 2 and 3 to return 3 2 3 2 3 2 3 2 as 16-bit words -static INLINE __m128i extract_quarter_2_epi16_sse2(const __m128i *const reg) { - __m128i tmp = _mm_unpacklo_epi32(*reg, *reg); - return _mm_unpackhi_epi64(tmp, tmp); -} - -// Interprets the input register as 16-bit words 7 6 5 4 3 2 1 0, then returns -// values at index 2 and 3 to return 5 4 5 4 5 4 5 4 as 16-bit words. -static INLINE __m128i extract_quarter_3_epi16_sse2(const __m128i *const reg) { - __m128i tmp = _mm_unpackhi_epi32(*reg, *reg); - return _mm_unpacklo_epi64(tmp, tmp); -} - -// Interprets src as 8-bit words, zero extends to form 16-bit words, then -// multiplies with ker and add the adjacent results to form 32-bit words. -// Finally adds the result from 1 and 2 together. -static INLINE __m128i mm_madd_add_epi8_sse2(const __m128i *const src_1, - const __m128i *const src_2, - const __m128i *const ker_1, - const __m128i *const ker_2) { - const __m128i src_1_half = _mm_unpacklo_epi8(*src_1, _mm_setzero_si128()); - const __m128i src_2_half = _mm_unpacklo_epi8(*src_2, _mm_setzero_si128()); - const __m128i madd_1 = _mm_madd_epi16(src_1_half, *ker_1); - const __m128i madd_2 = _mm_madd_epi16(src_2_half, *ker_2); - return _mm_add_epi32(madd_1, madd_2); -} - -// Interprets src as 16-bit words, then multiplies with ker and add the -// adjacent results to form 32-bit words. Finally adds the result from 1 and 2 -// together. -static INLINE __m128i mm_madd_add_epi16_sse2(const __m128i *const src_1, - const __m128i *const src_2, - const __m128i *const ker_1, - const __m128i *const ker_2) { - const __m128i madd_1 = _mm_madd_epi16(*src_1, *ker_1); - const __m128i madd_2 = _mm_madd_epi16(*src_2, *ker_2); - return _mm_add_epi32(madd_1, madd_2); -} - -static INLINE __m128i mm_madd_packs_epi16_sse2(const __m128i *const src_0, - const __m128i *const src_1, - const __m128i *const ker) { - const __m128i madd_1 = _mm_madd_epi16(*src_0, *ker); - const __m128i madd_2 = _mm_madd_epi16(*src_1, *ker); - return _mm_packs_epi32(madd_1, madd_2); -} - -// Interleaves src_1 and src_2 -static INLINE __m128i mm_zip_epi32_sse2(const __m128i *const src_1, - const __m128i *const src_2) { - const __m128i tmp_1 = _mm_unpacklo_epi32(*src_1, *src_2); - const __m128i tmp_2 = _mm_unpackhi_epi32(*src_1, *src_2); - return _mm_packs_epi32(tmp_1, tmp_2); -} - -static INLINE __m128i mm_round_epi32_sse2(const __m128i *const src, - const __m128i *const half_depth, - const int depth) { - const __m128i nearest_src = _mm_add_epi32(*src, *half_depth); - return _mm_srai_epi32(nearest_src, depth); -} - -static INLINE __m128i mm_round_epi16_sse2(const __m128i *const src, - const __m128i *const half_depth, - const int depth) { - const __m128i nearest_src = _mm_adds_epi16(*src, *half_depth); - return _mm_srai_epi16(nearest_src, depth); -} - -#endif // VPX_VPX_DSP_X86_CONVOLVE_SSE2_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/convolve_ssse3.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/convolve_ssse3.h deleted file mode 100644 index 8a4b1651..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/convolve_ssse3.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_X86_CONVOLVE_SSSE3_H_ -#define VPX_VPX_DSP_X86_CONVOLVE_SSSE3_H_ - -#include -#include // SSSE3 - -#include "./vpx_config.h" - -static INLINE void shuffle_filter_ssse3(const int16_t *const filter, - __m128i *const f) { - const __m128i f_values = _mm_load_si128((const __m128i *)filter); - // pack and duplicate the filter values - f[0] = _mm_shuffle_epi8(f_values, _mm_set1_epi16(0x0200u)); - f[1] = _mm_shuffle_epi8(f_values, _mm_set1_epi16(0x0604u)); - f[2] = _mm_shuffle_epi8(f_values, _mm_set1_epi16(0x0a08u)); - f[3] = _mm_shuffle_epi8(f_values, _mm_set1_epi16(0x0e0cu)); -} - -static INLINE void shuffle_filter_odd_ssse3(const int16_t *const filter, - __m128i *const f) { - const __m128i f_values = _mm_load_si128((const __m128i *)filter); - // pack and duplicate the filter values - // It utilizes the fact that the high byte of filter[3] is always 0 to clean - // half of f[0] and f[4]. - assert(filter[3] >= 0 && filter[3] < 256); - f[0] = _mm_shuffle_epi8(f_values, _mm_set1_epi16(0x0007u)); - f[1] = _mm_shuffle_epi8(f_values, _mm_set1_epi16(0x0402u)); - f[2] = _mm_shuffle_epi8(f_values, _mm_set1_epi16(0x0806u)); - f[3] = _mm_shuffle_epi8(f_values, _mm_set1_epi16(0x0c0au)); - f[4] = _mm_shuffle_epi8(f_values, _mm_set1_epi16(0x070eu)); -} - -static INLINE __m128i convolve8_8_ssse3(const __m128i *const s, - const __m128i *const f) { - // multiply 2 adjacent elements with the filter and add the result - const __m128i k_64 = _mm_set1_epi16(1 << 6); - const __m128i x0 = _mm_maddubs_epi16(s[0], f[0]); - const __m128i x1 = _mm_maddubs_epi16(s[1], f[1]); - const __m128i x2 = _mm_maddubs_epi16(s[2], f[2]); - const __m128i x3 = _mm_maddubs_epi16(s[3], f[3]); - __m128i sum1, sum2; - - // sum the results together, saturating only on the final step - // adding x0 with x2 and x1 with x3 is the only order that prevents - // outranges for all filters - sum1 = _mm_add_epi16(x0, x2); - sum2 = _mm_add_epi16(x1, x3); - // add the rounding offset early to avoid another saturated add - sum1 = _mm_add_epi16(sum1, k_64); - sum1 = _mm_adds_epi16(sum1, sum2); - // shift by 7 bit each 16 bit - sum1 = _mm_srai_epi16(sum1, 7); - return sum1; -} - -static INLINE __m128i convolve8_8_even_offset_ssse3(const __m128i *const s, - const __m128i *const f) { - // multiply 2 adjacent elements with the filter and add the result - const __m128i k_64 = _mm_set1_epi16(1 << 6); - const __m128i x0 = _mm_maddubs_epi16(s[0], f[0]); - const __m128i x1 = _mm_maddubs_epi16(s[1], f[1]); - const __m128i x2 = _mm_maddubs_epi16(s[2], f[2]); - const __m128i x3 = _mm_maddubs_epi16(s[3], f[3]); - // compensate the subtracted 64 in f[1]. x4 is always non negative. - const __m128i x4 = _mm_maddubs_epi16(s[1], _mm_set1_epi8(64)); - // add and saturate the results together - __m128i temp = _mm_adds_epi16(x0, x3); - temp = _mm_adds_epi16(temp, x1); - temp = _mm_adds_epi16(temp, x2); - temp = _mm_adds_epi16(temp, x4); - // round and shift by 7 bit each 16 bit - temp = _mm_adds_epi16(temp, k_64); - temp = _mm_srai_epi16(temp, 7); - return temp; -} - -static INLINE __m128i convolve8_8_odd_offset_ssse3(const __m128i *const s, - const __m128i *const f) { - // multiply 2 adjacent elements with the filter and add the result - const __m128i k_64 = _mm_set1_epi16(1 << 6); - const __m128i x0 = _mm_maddubs_epi16(s[0], f[0]); - const __m128i x1 = _mm_maddubs_epi16(s[1], f[1]); - const __m128i x2 = _mm_maddubs_epi16(s[2], f[2]); - const __m128i x3 = _mm_maddubs_epi16(s[3], f[3]); - const __m128i x4 = _mm_maddubs_epi16(s[4], f[4]); - // compensate the subtracted 64 in f[2]. x5 is always non negative. - const __m128i x5 = _mm_maddubs_epi16(s[2], _mm_set1_epi8(64)); - __m128i temp; - - // add and saturate the results together - temp = _mm_adds_epi16(x0, x1); - temp = _mm_adds_epi16(temp, x2); - temp = _mm_adds_epi16(temp, x3); - temp = _mm_adds_epi16(temp, x4); - temp = _mm_adds_epi16(temp, x5); - // round and shift by 7 bit each 16 bit - temp = _mm_adds_epi16(temp, k_64); - temp = _mm_srai_epi16(temp, 7); - return temp; -} - -#endif // VPX_VPX_DSP_X86_CONVOLVE_SSSE3_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/deblock_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/deblock_sse2.asm deleted file mode 100644 index b3af677d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/deblock_sse2.asm +++ /dev/null @@ -1,432 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -;macro in deblock functions -%macro FIRST_2_ROWS 0 - movdqa xmm4, xmm0 - movdqa xmm6, xmm0 - movdqa xmm5, xmm1 - pavgb xmm5, xmm3 - - ;calculate absolute value - psubusb xmm4, xmm1 - psubusb xmm1, xmm0 - psubusb xmm6, xmm3 - psubusb xmm3, xmm0 - paddusb xmm4, xmm1 - paddusb xmm6, xmm3 - - ;get threshold - movdqa xmm2, flimit - pxor xmm1, xmm1 - movdqa xmm7, xmm2 - - ;get mask - psubusb xmm2, xmm4 - psubusb xmm7, xmm6 - pcmpeqb xmm2, xmm1 - pcmpeqb xmm7, xmm1 - por xmm7, xmm2 -%endmacro - -%macro SECOND_2_ROWS 0 - movdqa xmm6, xmm0 - movdqa xmm4, xmm0 - movdqa xmm2, xmm1 - pavgb xmm1, xmm3 - - ;calculate absolute value - psubusb xmm6, xmm2 - psubusb xmm2, xmm0 - psubusb xmm4, xmm3 - psubusb xmm3, xmm0 - paddusb xmm6, xmm2 - paddusb xmm4, xmm3 - - pavgb xmm5, xmm1 - - ;get threshold - movdqa xmm2, flimit - pxor xmm1, xmm1 - movdqa xmm3, xmm2 - - ;get mask - psubusb xmm2, xmm6 - psubusb xmm3, xmm4 - pcmpeqb xmm2, xmm1 - pcmpeqb xmm3, xmm1 - - por xmm7, xmm2 - por xmm7, xmm3 - - pavgb xmm5, xmm0 - - ;decide if or not to use filtered value - pand xmm0, xmm7 - pandn xmm7, xmm5 - paddusb xmm0, xmm7 -%endmacro - -%macro UPDATE_FLIMIT 0 - movdqu xmm2, XMMWORD PTR [rbx] - movdqu [rsp], xmm2 - add rbx, 16 -%endmacro - -SECTION .text - -;void vpx_post_proc_down_and_across_mb_row_sse2 -;( -; unsigned char *src_ptr, -; unsigned char *dst_ptr, -; int src_pixels_per_line, -; int dst_pixels_per_line, -; int cols, -; int *flimits, -; int size -;) -globalsym(vpx_post_proc_down_and_across_mb_row_sse2) -sym(vpx_post_proc_down_and_across_mb_row_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 7 - push rbx - push rsi - push rdi - ; end prolog - ALIGN_STACK 16, rax - sub rsp, 16 - - ; put flimit on stack - mov rbx, arg(5) ;flimits ptr - UPDATE_FLIMIT - -%define flimit [rsp] - - mov rsi, arg(0) ;src_ptr - mov rdi, arg(1) ;dst_ptr - - movsxd rax, DWORD PTR arg(2) ;src_pixels_per_line - movsxd rcx, DWORD PTR arg(6) ;rows in a macroblock -.nextrow: - xor rdx, rdx ;col -.nextcol: - ;load current and next 2 rows - movdqu xmm0, XMMWORD PTR [rsi] - movdqu xmm1, XMMWORD PTR [rsi + rax] - movdqu xmm3, XMMWORD PTR [rsi + 2*rax] - - FIRST_2_ROWS - - ;load above 2 rows - neg rax - movdqu xmm1, XMMWORD PTR [rsi + 2*rax] - movdqu xmm3, XMMWORD PTR [rsi + rax] - - SECOND_2_ROWS - - movdqu XMMWORD PTR [rdi], xmm0 - - neg rax ; positive stride - add rsi, 16 - add rdi, 16 - - add rdx, 16 - cmp edx, dword arg(4) ;cols - jge .downdone - UPDATE_FLIMIT - jmp .nextcol - -.downdone: - ; done with the all cols, start the across filtering in place - sub rsi, rdx - sub rdi, rdx - - mov rbx, arg(5) ; flimits - UPDATE_FLIMIT - - ; dup the first byte into the left border 8 times - movq mm1, [rdi] - punpcklbw mm1, mm1 - punpcklwd mm1, mm1 - punpckldq mm1, mm1 - mov rdx, -8 - movq [rdi+rdx], mm1 - - ; dup the last byte into the right border - movsxd rdx, dword arg(4) - movq mm1, [rdi + rdx + -1] - punpcklbw mm1, mm1 - punpcklwd mm1, mm1 - punpckldq mm1, mm1 - movq [rdi+rdx], mm1 - - xor rdx, rdx - movq mm0, QWORD PTR [rdi-16]; - movq mm1, QWORD PTR [rdi-8]; - -.acrossnextcol: - movdqu xmm0, XMMWORD PTR [rdi + rdx] - movdqu xmm1, XMMWORD PTR [rdi + rdx -2] - movdqu xmm3, XMMWORD PTR [rdi + rdx -1] - - FIRST_2_ROWS - - movdqu xmm1, XMMWORD PTR [rdi + rdx +1] - movdqu xmm3, XMMWORD PTR [rdi + rdx +2] - - SECOND_2_ROWS - - movq QWORD PTR [rdi+rdx-16], mm0 ; store previous 8 bytes - movq QWORD PTR [rdi+rdx-8], mm1 ; store previous 8 bytes - movdq2q mm0, xmm0 - psrldq xmm0, 8 - movdq2q mm1, xmm0 - - add rdx, 16 - cmp edx, dword arg(4) ;cols - jge .acrossdone - UPDATE_FLIMIT - jmp .acrossnextcol - -.acrossdone: - ; last 16 pixels - movq QWORD PTR [rdi+rdx-16], mm0 - - cmp edx, dword arg(4) - jne .throw_last_8 - movq QWORD PTR [rdi+rdx-8], mm1 -.throw_last_8: - ; done with this rwo - add rsi,rax ;next src line - mov eax, dword arg(3) ;dst_pixels_per_line - add rdi,rax ;next destination - mov eax, dword arg(2) ;src_pixels_per_line - - mov rbx, arg(5) ;flimits - UPDATE_FLIMIT - - dec rcx ;decrement count - jnz .nextrow ;next row - - add rsp, 16 - pop rsp - ; begin epilog - pop rdi - pop rsi - pop rbx - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret -%undef flimit - - -;void vpx_mbpost_proc_across_ip_sse2(unsigned char *src, -; int pitch, int rows, int cols,int flimit) -globalsym(vpx_mbpost_proc_across_ip_sse2) -sym(vpx_mbpost_proc_across_ip_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 5 - SAVE_XMM 7 - GET_GOT rbx - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 - - ; create flimit4 at [rsp] - mov eax, dword ptr arg(4) ;flimit - mov [rsp], eax - mov [rsp+4], eax - mov [rsp+8], eax - mov [rsp+12], eax -%define flimit4 [rsp] - - - ;for(r=0;r // AVX2 - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/txfm_common.h" - -#define pair256_set_epi16(a, b) \ - _mm256_set_epi16((int16_t)(b), (int16_t)(a), (int16_t)(b), (int16_t)(a), \ - (int16_t)(b), (int16_t)(a), (int16_t)(b), (int16_t)(a), \ - (int16_t)(b), (int16_t)(a), (int16_t)(b), (int16_t)(a), \ - (int16_t)(b), (int16_t)(a), (int16_t)(b), (int16_t)(a)) - -#define pair256_set_epi32(a, b) \ - _mm256_set_epi32((int)(b), (int)(a), (int)(b), (int)(a), (int)(b), (int)(a), \ - (int)(b), (int)(a)) - -#if FDCT32x32_HIGH_PRECISION -static INLINE __m256i k_madd_epi32_avx2(__m256i a, __m256i b) { - __m256i buf0, buf1; - buf0 = _mm256_mul_epu32(a, b); - a = _mm256_srli_epi64(a, 32); - b = _mm256_srli_epi64(b, 32); - buf1 = _mm256_mul_epu32(a, b); - return _mm256_add_epi64(buf0, buf1); -} - -static INLINE __m256i k_packs_epi64_avx2(__m256i a, __m256i b) { - __m256i buf0 = _mm256_shuffle_epi32(a, _MM_SHUFFLE(0, 0, 2, 0)); - __m256i buf1 = _mm256_shuffle_epi32(b, _MM_SHUFFLE(0, 0, 2, 0)); - return _mm256_unpacklo_epi64(buf0, buf1); -} -#endif - -void FDCT32x32_2D_AVX2(const int16_t *input, int16_t *output_org, int stride) { - // Calculate pre-multiplied strides - const int str1 = stride; - const int str2 = 2 * stride; - const int str3 = 2 * stride + str1; - // We need an intermediate buffer between passes. - DECLARE_ALIGNED(32, int16_t, intermediate[32 * 32]); - // Constants - // When we use them, in one case, they are all the same. In all others - // it's a pair of them that we need to repeat four times. This is done - // by constructing the 32 bit constant corresponding to that pair. - const __m256i k__cospi_p16_p16 = _mm256_set1_epi16(cospi_16_64); - const __m256i k__cospi_p16_m16 = - pair256_set_epi16(+cospi_16_64, -cospi_16_64); - const __m256i k__cospi_m08_p24 = pair256_set_epi16(-cospi_8_64, cospi_24_64); - const __m256i k__cospi_m24_m08 = pair256_set_epi16(-cospi_24_64, -cospi_8_64); - const __m256i k__cospi_p24_p08 = pair256_set_epi16(+cospi_24_64, cospi_8_64); - const __m256i k__cospi_p12_p20 = pair256_set_epi16(+cospi_12_64, cospi_20_64); - const __m256i k__cospi_m20_p12 = pair256_set_epi16(-cospi_20_64, cospi_12_64); - const __m256i k__cospi_m04_p28 = pair256_set_epi16(-cospi_4_64, cospi_28_64); - const __m256i k__cospi_p28_p04 = pair256_set_epi16(+cospi_28_64, cospi_4_64); - const __m256i k__cospi_m28_m04 = pair256_set_epi16(-cospi_28_64, -cospi_4_64); - const __m256i k__cospi_m12_m20 = - pair256_set_epi16(-cospi_12_64, -cospi_20_64); - const __m256i k__cospi_p30_p02 = pair256_set_epi16(+cospi_30_64, cospi_2_64); - const __m256i k__cospi_p14_p18 = pair256_set_epi16(+cospi_14_64, cospi_18_64); - const __m256i k__cospi_p22_p10 = pair256_set_epi16(+cospi_22_64, cospi_10_64); - const __m256i k__cospi_p06_p26 = pair256_set_epi16(+cospi_6_64, cospi_26_64); - const __m256i k__cospi_m26_p06 = pair256_set_epi16(-cospi_26_64, cospi_6_64); - const __m256i k__cospi_m10_p22 = pair256_set_epi16(-cospi_10_64, cospi_22_64); - const __m256i k__cospi_m18_p14 = pair256_set_epi16(-cospi_18_64, cospi_14_64); - const __m256i k__cospi_m02_p30 = pair256_set_epi16(-cospi_2_64, cospi_30_64); - const __m256i k__cospi_p31_p01 = pair256_set_epi16(+cospi_31_64, cospi_1_64); - const __m256i k__cospi_p15_p17 = pair256_set_epi16(+cospi_15_64, cospi_17_64); - const __m256i k__cospi_p23_p09 = pair256_set_epi16(+cospi_23_64, cospi_9_64); - const __m256i k__cospi_p07_p25 = pair256_set_epi16(+cospi_7_64, cospi_25_64); - const __m256i k__cospi_m25_p07 = pair256_set_epi16(-cospi_25_64, cospi_7_64); - const __m256i k__cospi_m09_p23 = pair256_set_epi16(-cospi_9_64, cospi_23_64); - const __m256i k__cospi_m17_p15 = pair256_set_epi16(-cospi_17_64, cospi_15_64); - const __m256i k__cospi_m01_p31 = pair256_set_epi16(-cospi_1_64, cospi_31_64); - const __m256i k__cospi_p27_p05 = pair256_set_epi16(+cospi_27_64, cospi_5_64); - const __m256i k__cospi_p11_p21 = pair256_set_epi16(+cospi_11_64, cospi_21_64); - const __m256i k__cospi_p19_p13 = pair256_set_epi16(+cospi_19_64, cospi_13_64); - const __m256i k__cospi_p03_p29 = pair256_set_epi16(+cospi_3_64, cospi_29_64); - const __m256i k__cospi_m29_p03 = pair256_set_epi16(-cospi_29_64, cospi_3_64); - const __m256i k__cospi_m13_p19 = pair256_set_epi16(-cospi_13_64, cospi_19_64); - const __m256i k__cospi_m21_p11 = pair256_set_epi16(-cospi_21_64, cospi_11_64); - const __m256i k__cospi_m05_p27 = pair256_set_epi16(-cospi_5_64, cospi_27_64); - const __m256i k__DCT_CONST_ROUNDING = _mm256_set1_epi32(DCT_CONST_ROUNDING); - const __m256i kZero = _mm256_setzero_si256(); - const __m256i kOne = _mm256_set1_epi16(1); - // Do the two transform/transpose passes - int pass; - for (pass = 0; pass < 2; ++pass) { - // We process sixteen columns (transposed rows in second pass) at a time. - int column_start; - for (column_start = 0; column_start < 32; column_start += 16) { - __m256i step1[32]; - __m256i step2[32]; - __m256i step3[32]; - __m256i out[32]; - // Stage 1 - // Note: even though all the loads below are aligned, using the aligned - // intrinsic make the code slightly slower. - if (0 == pass) { - const int16_t *in = &input[column_start]; - // step1[i] = (in[ 0 * stride] + in[(32 - 1) * stride]) << 2; - // Note: the next four blocks could be in a loop. That would help the - // instruction cache but is actually slower. - { - const int16_t *ina = in + 0 * str1; - const int16_t *inb = in + 31 * str1; - __m256i *step1a = &step1[0]; - __m256i *step1b = &step1[31]; - const __m256i ina0 = _mm256_loadu_si256((const __m256i *)(ina)); - const __m256i ina1 = - _mm256_loadu_si256((const __m256i *)(ina + str1)); - const __m256i ina2 = - _mm256_loadu_si256((const __m256i *)(ina + str2)); - const __m256i ina3 = - _mm256_loadu_si256((const __m256i *)(ina + str3)); - const __m256i inb3 = - _mm256_loadu_si256((const __m256i *)(inb - str3)); - const __m256i inb2 = - _mm256_loadu_si256((const __m256i *)(inb - str2)); - const __m256i inb1 = - _mm256_loadu_si256((const __m256i *)(inb - str1)); - const __m256i inb0 = _mm256_loadu_si256((const __m256i *)(inb)); - step1a[0] = _mm256_add_epi16(ina0, inb0); - step1a[1] = _mm256_add_epi16(ina1, inb1); - step1a[2] = _mm256_add_epi16(ina2, inb2); - step1a[3] = _mm256_add_epi16(ina3, inb3); - step1b[-3] = _mm256_sub_epi16(ina3, inb3); - step1b[-2] = _mm256_sub_epi16(ina2, inb2); - step1b[-1] = _mm256_sub_epi16(ina1, inb1); - step1b[-0] = _mm256_sub_epi16(ina0, inb0); - step1a[0] = _mm256_slli_epi16(step1a[0], 2); - step1a[1] = _mm256_slli_epi16(step1a[1], 2); - step1a[2] = _mm256_slli_epi16(step1a[2], 2); - step1a[3] = _mm256_slli_epi16(step1a[3], 2); - step1b[-3] = _mm256_slli_epi16(step1b[-3], 2); - step1b[-2] = _mm256_slli_epi16(step1b[-2], 2); - step1b[-1] = _mm256_slli_epi16(step1b[-1], 2); - step1b[-0] = _mm256_slli_epi16(step1b[-0], 2); - } - { - const int16_t *ina = in + 4 * str1; - const int16_t *inb = in + 27 * str1; - __m256i *step1a = &step1[4]; - __m256i *step1b = &step1[27]; - const __m256i ina0 = _mm256_loadu_si256((const __m256i *)(ina)); - const __m256i ina1 = - _mm256_loadu_si256((const __m256i *)(ina + str1)); - const __m256i ina2 = - _mm256_loadu_si256((const __m256i *)(ina + str2)); - const __m256i ina3 = - _mm256_loadu_si256((const __m256i *)(ina + str3)); - const __m256i inb3 = - _mm256_loadu_si256((const __m256i *)(inb - str3)); - const __m256i inb2 = - _mm256_loadu_si256((const __m256i *)(inb - str2)); - const __m256i inb1 = - _mm256_loadu_si256((const __m256i *)(inb - str1)); - const __m256i inb0 = _mm256_loadu_si256((const __m256i *)(inb)); - step1a[0] = _mm256_add_epi16(ina0, inb0); - step1a[1] = _mm256_add_epi16(ina1, inb1); - step1a[2] = _mm256_add_epi16(ina2, inb2); - step1a[3] = _mm256_add_epi16(ina3, inb3); - step1b[-3] = _mm256_sub_epi16(ina3, inb3); - step1b[-2] = _mm256_sub_epi16(ina2, inb2); - step1b[-1] = _mm256_sub_epi16(ina1, inb1); - step1b[-0] = _mm256_sub_epi16(ina0, inb0); - step1a[0] = _mm256_slli_epi16(step1a[0], 2); - step1a[1] = _mm256_slli_epi16(step1a[1], 2); - step1a[2] = _mm256_slli_epi16(step1a[2], 2); - step1a[3] = _mm256_slli_epi16(step1a[3], 2); - step1b[-3] = _mm256_slli_epi16(step1b[-3], 2); - step1b[-2] = _mm256_slli_epi16(step1b[-2], 2); - step1b[-1] = _mm256_slli_epi16(step1b[-1], 2); - step1b[-0] = _mm256_slli_epi16(step1b[-0], 2); - } - { - const int16_t *ina = in + 8 * str1; - const int16_t *inb = in + 23 * str1; - __m256i *step1a = &step1[8]; - __m256i *step1b = &step1[23]; - const __m256i ina0 = _mm256_loadu_si256((const __m256i *)(ina)); - const __m256i ina1 = - _mm256_loadu_si256((const __m256i *)(ina + str1)); - const __m256i ina2 = - _mm256_loadu_si256((const __m256i *)(ina + str2)); - const __m256i ina3 = - _mm256_loadu_si256((const __m256i *)(ina + str3)); - const __m256i inb3 = - _mm256_loadu_si256((const __m256i *)(inb - str3)); - const __m256i inb2 = - _mm256_loadu_si256((const __m256i *)(inb - str2)); - const __m256i inb1 = - _mm256_loadu_si256((const __m256i *)(inb - str1)); - const __m256i inb0 = _mm256_loadu_si256((const __m256i *)(inb)); - step1a[0] = _mm256_add_epi16(ina0, inb0); - step1a[1] = _mm256_add_epi16(ina1, inb1); - step1a[2] = _mm256_add_epi16(ina2, inb2); - step1a[3] = _mm256_add_epi16(ina3, inb3); - step1b[-3] = _mm256_sub_epi16(ina3, inb3); - step1b[-2] = _mm256_sub_epi16(ina2, inb2); - step1b[-1] = _mm256_sub_epi16(ina1, inb1); - step1b[-0] = _mm256_sub_epi16(ina0, inb0); - step1a[0] = _mm256_slli_epi16(step1a[0], 2); - step1a[1] = _mm256_slli_epi16(step1a[1], 2); - step1a[2] = _mm256_slli_epi16(step1a[2], 2); - step1a[3] = _mm256_slli_epi16(step1a[3], 2); - step1b[-3] = _mm256_slli_epi16(step1b[-3], 2); - step1b[-2] = _mm256_slli_epi16(step1b[-2], 2); - step1b[-1] = _mm256_slli_epi16(step1b[-1], 2); - step1b[-0] = _mm256_slli_epi16(step1b[-0], 2); - } - { - const int16_t *ina = in + 12 * str1; - const int16_t *inb = in + 19 * str1; - __m256i *step1a = &step1[12]; - __m256i *step1b = &step1[19]; - const __m256i ina0 = _mm256_loadu_si256((const __m256i *)(ina)); - const __m256i ina1 = - _mm256_loadu_si256((const __m256i *)(ina + str1)); - const __m256i ina2 = - _mm256_loadu_si256((const __m256i *)(ina + str2)); - const __m256i ina3 = - _mm256_loadu_si256((const __m256i *)(ina + str3)); - const __m256i inb3 = - _mm256_loadu_si256((const __m256i *)(inb - str3)); - const __m256i inb2 = - _mm256_loadu_si256((const __m256i *)(inb - str2)); - const __m256i inb1 = - _mm256_loadu_si256((const __m256i *)(inb - str1)); - const __m256i inb0 = _mm256_loadu_si256((const __m256i *)(inb)); - step1a[0] = _mm256_add_epi16(ina0, inb0); - step1a[1] = _mm256_add_epi16(ina1, inb1); - step1a[2] = _mm256_add_epi16(ina2, inb2); - step1a[3] = _mm256_add_epi16(ina3, inb3); - step1b[-3] = _mm256_sub_epi16(ina3, inb3); - step1b[-2] = _mm256_sub_epi16(ina2, inb2); - step1b[-1] = _mm256_sub_epi16(ina1, inb1); - step1b[-0] = _mm256_sub_epi16(ina0, inb0); - step1a[0] = _mm256_slli_epi16(step1a[0], 2); - step1a[1] = _mm256_slli_epi16(step1a[1], 2); - step1a[2] = _mm256_slli_epi16(step1a[2], 2); - step1a[3] = _mm256_slli_epi16(step1a[3], 2); - step1b[-3] = _mm256_slli_epi16(step1b[-3], 2); - step1b[-2] = _mm256_slli_epi16(step1b[-2], 2); - step1b[-1] = _mm256_slli_epi16(step1b[-1], 2); - step1b[-0] = _mm256_slli_epi16(step1b[-0], 2); - } - } else { - int16_t *in = &intermediate[column_start]; - // step1[i] = in[ 0 * 32] + in[(32 - 1) * 32]; - // Note: using the same approach as above to have common offset is - // counter-productive as all offsets can be calculated at compile - // time. - // Note: the next four blocks could be in a loop. That would help the - // instruction cache but is actually slower. - { - __m256i in00 = _mm256_loadu_si256((const __m256i *)(in + 0 * 32)); - __m256i in01 = _mm256_loadu_si256((const __m256i *)(in + 1 * 32)); - __m256i in02 = _mm256_loadu_si256((const __m256i *)(in + 2 * 32)); - __m256i in03 = _mm256_loadu_si256((const __m256i *)(in + 3 * 32)); - __m256i in28 = _mm256_loadu_si256((const __m256i *)(in + 28 * 32)); - __m256i in29 = _mm256_loadu_si256((const __m256i *)(in + 29 * 32)); - __m256i in30 = _mm256_loadu_si256((const __m256i *)(in + 30 * 32)); - __m256i in31 = _mm256_loadu_si256((const __m256i *)(in + 31 * 32)); - step1[0] = _mm256_add_epi16(in00, in31); - step1[1] = _mm256_add_epi16(in01, in30); - step1[2] = _mm256_add_epi16(in02, in29); - step1[3] = _mm256_add_epi16(in03, in28); - step1[28] = _mm256_sub_epi16(in03, in28); - step1[29] = _mm256_sub_epi16(in02, in29); - step1[30] = _mm256_sub_epi16(in01, in30); - step1[31] = _mm256_sub_epi16(in00, in31); - } - { - __m256i in04 = _mm256_loadu_si256((const __m256i *)(in + 4 * 32)); - __m256i in05 = _mm256_loadu_si256((const __m256i *)(in + 5 * 32)); - __m256i in06 = _mm256_loadu_si256((const __m256i *)(in + 6 * 32)); - __m256i in07 = _mm256_loadu_si256((const __m256i *)(in + 7 * 32)); - __m256i in24 = _mm256_loadu_si256((const __m256i *)(in + 24 * 32)); - __m256i in25 = _mm256_loadu_si256((const __m256i *)(in + 25 * 32)); - __m256i in26 = _mm256_loadu_si256((const __m256i *)(in + 26 * 32)); - __m256i in27 = _mm256_loadu_si256((const __m256i *)(in + 27 * 32)); - step1[4] = _mm256_add_epi16(in04, in27); - step1[5] = _mm256_add_epi16(in05, in26); - step1[6] = _mm256_add_epi16(in06, in25); - step1[7] = _mm256_add_epi16(in07, in24); - step1[24] = _mm256_sub_epi16(in07, in24); - step1[25] = _mm256_sub_epi16(in06, in25); - step1[26] = _mm256_sub_epi16(in05, in26); - step1[27] = _mm256_sub_epi16(in04, in27); - } - { - __m256i in08 = _mm256_loadu_si256((const __m256i *)(in + 8 * 32)); - __m256i in09 = _mm256_loadu_si256((const __m256i *)(in + 9 * 32)); - __m256i in10 = _mm256_loadu_si256((const __m256i *)(in + 10 * 32)); - __m256i in11 = _mm256_loadu_si256((const __m256i *)(in + 11 * 32)); - __m256i in20 = _mm256_loadu_si256((const __m256i *)(in + 20 * 32)); - __m256i in21 = _mm256_loadu_si256((const __m256i *)(in + 21 * 32)); - __m256i in22 = _mm256_loadu_si256((const __m256i *)(in + 22 * 32)); - __m256i in23 = _mm256_loadu_si256((const __m256i *)(in + 23 * 32)); - step1[8] = _mm256_add_epi16(in08, in23); - step1[9] = _mm256_add_epi16(in09, in22); - step1[10] = _mm256_add_epi16(in10, in21); - step1[11] = _mm256_add_epi16(in11, in20); - step1[20] = _mm256_sub_epi16(in11, in20); - step1[21] = _mm256_sub_epi16(in10, in21); - step1[22] = _mm256_sub_epi16(in09, in22); - step1[23] = _mm256_sub_epi16(in08, in23); - } - { - __m256i in12 = _mm256_loadu_si256((const __m256i *)(in + 12 * 32)); - __m256i in13 = _mm256_loadu_si256((const __m256i *)(in + 13 * 32)); - __m256i in14 = _mm256_loadu_si256((const __m256i *)(in + 14 * 32)); - __m256i in15 = _mm256_loadu_si256((const __m256i *)(in + 15 * 32)); - __m256i in16 = _mm256_loadu_si256((const __m256i *)(in + 16 * 32)); - __m256i in17 = _mm256_loadu_si256((const __m256i *)(in + 17 * 32)); - __m256i in18 = _mm256_loadu_si256((const __m256i *)(in + 18 * 32)); - __m256i in19 = _mm256_loadu_si256((const __m256i *)(in + 19 * 32)); - step1[12] = _mm256_add_epi16(in12, in19); - step1[13] = _mm256_add_epi16(in13, in18); - step1[14] = _mm256_add_epi16(in14, in17); - step1[15] = _mm256_add_epi16(in15, in16); - step1[16] = _mm256_sub_epi16(in15, in16); - step1[17] = _mm256_sub_epi16(in14, in17); - step1[18] = _mm256_sub_epi16(in13, in18); - step1[19] = _mm256_sub_epi16(in12, in19); - } - } - // Stage 2 - { - step2[0] = _mm256_add_epi16(step1[0], step1[15]); - step2[1] = _mm256_add_epi16(step1[1], step1[14]); - step2[2] = _mm256_add_epi16(step1[2], step1[13]); - step2[3] = _mm256_add_epi16(step1[3], step1[12]); - step2[4] = _mm256_add_epi16(step1[4], step1[11]); - step2[5] = _mm256_add_epi16(step1[5], step1[10]); - step2[6] = _mm256_add_epi16(step1[6], step1[9]); - step2[7] = _mm256_add_epi16(step1[7], step1[8]); - step2[8] = _mm256_sub_epi16(step1[7], step1[8]); - step2[9] = _mm256_sub_epi16(step1[6], step1[9]); - step2[10] = _mm256_sub_epi16(step1[5], step1[10]); - step2[11] = _mm256_sub_epi16(step1[4], step1[11]); - step2[12] = _mm256_sub_epi16(step1[3], step1[12]); - step2[13] = _mm256_sub_epi16(step1[2], step1[13]); - step2[14] = _mm256_sub_epi16(step1[1], step1[14]); - step2[15] = _mm256_sub_epi16(step1[0], step1[15]); - } - { - const __m256i s2_20_0 = _mm256_unpacklo_epi16(step1[27], step1[20]); - const __m256i s2_20_1 = _mm256_unpackhi_epi16(step1[27], step1[20]); - const __m256i s2_21_0 = _mm256_unpacklo_epi16(step1[26], step1[21]); - const __m256i s2_21_1 = _mm256_unpackhi_epi16(step1[26], step1[21]); - const __m256i s2_22_0 = _mm256_unpacklo_epi16(step1[25], step1[22]); - const __m256i s2_22_1 = _mm256_unpackhi_epi16(step1[25], step1[22]); - const __m256i s2_23_0 = _mm256_unpacklo_epi16(step1[24], step1[23]); - const __m256i s2_23_1 = _mm256_unpackhi_epi16(step1[24], step1[23]); - const __m256i s2_20_2 = _mm256_madd_epi16(s2_20_0, k__cospi_p16_m16); - const __m256i s2_20_3 = _mm256_madd_epi16(s2_20_1, k__cospi_p16_m16); - const __m256i s2_21_2 = _mm256_madd_epi16(s2_21_0, k__cospi_p16_m16); - const __m256i s2_21_3 = _mm256_madd_epi16(s2_21_1, k__cospi_p16_m16); - const __m256i s2_22_2 = _mm256_madd_epi16(s2_22_0, k__cospi_p16_m16); - const __m256i s2_22_3 = _mm256_madd_epi16(s2_22_1, k__cospi_p16_m16); - const __m256i s2_23_2 = _mm256_madd_epi16(s2_23_0, k__cospi_p16_m16); - const __m256i s2_23_3 = _mm256_madd_epi16(s2_23_1, k__cospi_p16_m16); - const __m256i s2_24_2 = _mm256_madd_epi16(s2_23_0, k__cospi_p16_p16); - const __m256i s2_24_3 = _mm256_madd_epi16(s2_23_1, k__cospi_p16_p16); - const __m256i s2_25_2 = _mm256_madd_epi16(s2_22_0, k__cospi_p16_p16); - const __m256i s2_25_3 = _mm256_madd_epi16(s2_22_1, k__cospi_p16_p16); - const __m256i s2_26_2 = _mm256_madd_epi16(s2_21_0, k__cospi_p16_p16); - const __m256i s2_26_3 = _mm256_madd_epi16(s2_21_1, k__cospi_p16_p16); - const __m256i s2_27_2 = _mm256_madd_epi16(s2_20_0, k__cospi_p16_p16); - const __m256i s2_27_3 = _mm256_madd_epi16(s2_20_1, k__cospi_p16_p16); - // dct_const_round_shift - const __m256i s2_20_4 = - _mm256_add_epi32(s2_20_2, k__DCT_CONST_ROUNDING); - const __m256i s2_20_5 = - _mm256_add_epi32(s2_20_3, k__DCT_CONST_ROUNDING); - const __m256i s2_21_4 = - _mm256_add_epi32(s2_21_2, k__DCT_CONST_ROUNDING); - const __m256i s2_21_5 = - _mm256_add_epi32(s2_21_3, k__DCT_CONST_ROUNDING); - const __m256i s2_22_4 = - _mm256_add_epi32(s2_22_2, k__DCT_CONST_ROUNDING); - const __m256i s2_22_5 = - _mm256_add_epi32(s2_22_3, k__DCT_CONST_ROUNDING); - const __m256i s2_23_4 = - _mm256_add_epi32(s2_23_2, k__DCT_CONST_ROUNDING); - const __m256i s2_23_5 = - _mm256_add_epi32(s2_23_3, k__DCT_CONST_ROUNDING); - const __m256i s2_24_4 = - _mm256_add_epi32(s2_24_2, k__DCT_CONST_ROUNDING); - const __m256i s2_24_5 = - _mm256_add_epi32(s2_24_3, k__DCT_CONST_ROUNDING); - const __m256i s2_25_4 = - _mm256_add_epi32(s2_25_2, k__DCT_CONST_ROUNDING); - const __m256i s2_25_5 = - _mm256_add_epi32(s2_25_3, k__DCT_CONST_ROUNDING); - const __m256i s2_26_4 = - _mm256_add_epi32(s2_26_2, k__DCT_CONST_ROUNDING); - const __m256i s2_26_5 = - _mm256_add_epi32(s2_26_3, k__DCT_CONST_ROUNDING); - const __m256i s2_27_4 = - _mm256_add_epi32(s2_27_2, k__DCT_CONST_ROUNDING); - const __m256i s2_27_5 = - _mm256_add_epi32(s2_27_3, k__DCT_CONST_ROUNDING); - const __m256i s2_20_6 = _mm256_srai_epi32(s2_20_4, DCT_CONST_BITS); - const __m256i s2_20_7 = _mm256_srai_epi32(s2_20_5, DCT_CONST_BITS); - const __m256i s2_21_6 = _mm256_srai_epi32(s2_21_4, DCT_CONST_BITS); - const __m256i s2_21_7 = _mm256_srai_epi32(s2_21_5, DCT_CONST_BITS); - const __m256i s2_22_6 = _mm256_srai_epi32(s2_22_4, DCT_CONST_BITS); - const __m256i s2_22_7 = _mm256_srai_epi32(s2_22_5, DCT_CONST_BITS); - const __m256i s2_23_6 = _mm256_srai_epi32(s2_23_4, DCT_CONST_BITS); - const __m256i s2_23_7 = _mm256_srai_epi32(s2_23_5, DCT_CONST_BITS); - const __m256i s2_24_6 = _mm256_srai_epi32(s2_24_4, DCT_CONST_BITS); - const __m256i s2_24_7 = _mm256_srai_epi32(s2_24_5, DCT_CONST_BITS); - const __m256i s2_25_6 = _mm256_srai_epi32(s2_25_4, DCT_CONST_BITS); - const __m256i s2_25_7 = _mm256_srai_epi32(s2_25_5, DCT_CONST_BITS); - const __m256i s2_26_6 = _mm256_srai_epi32(s2_26_4, DCT_CONST_BITS); - const __m256i s2_26_7 = _mm256_srai_epi32(s2_26_5, DCT_CONST_BITS); - const __m256i s2_27_6 = _mm256_srai_epi32(s2_27_4, DCT_CONST_BITS); - const __m256i s2_27_7 = _mm256_srai_epi32(s2_27_5, DCT_CONST_BITS); - // Combine - step2[20] = _mm256_packs_epi32(s2_20_6, s2_20_7); - step2[21] = _mm256_packs_epi32(s2_21_6, s2_21_7); - step2[22] = _mm256_packs_epi32(s2_22_6, s2_22_7); - step2[23] = _mm256_packs_epi32(s2_23_6, s2_23_7); - step2[24] = _mm256_packs_epi32(s2_24_6, s2_24_7); - step2[25] = _mm256_packs_epi32(s2_25_6, s2_25_7); - step2[26] = _mm256_packs_epi32(s2_26_6, s2_26_7); - step2[27] = _mm256_packs_epi32(s2_27_6, s2_27_7); - } - -#if !FDCT32x32_HIGH_PRECISION - // dump the magnitude by half, hence the intermediate values are within - // the range of 16 bits. - if (1 == pass) { - __m256i s3_00_0 = _mm256_cmpgt_epi16(kZero, step2[0]); - __m256i s3_01_0 = _mm256_cmpgt_epi16(kZero, step2[1]); - __m256i s3_02_0 = _mm256_cmpgt_epi16(kZero, step2[2]); - __m256i s3_03_0 = _mm256_cmpgt_epi16(kZero, step2[3]); - __m256i s3_04_0 = _mm256_cmpgt_epi16(kZero, step2[4]); - __m256i s3_05_0 = _mm256_cmpgt_epi16(kZero, step2[5]); - __m256i s3_06_0 = _mm256_cmpgt_epi16(kZero, step2[6]); - __m256i s3_07_0 = _mm256_cmpgt_epi16(kZero, step2[7]); - __m256i s2_08_0 = _mm256_cmpgt_epi16(kZero, step2[8]); - __m256i s2_09_0 = _mm256_cmpgt_epi16(kZero, step2[9]); - __m256i s3_10_0 = _mm256_cmpgt_epi16(kZero, step2[10]); - __m256i s3_11_0 = _mm256_cmpgt_epi16(kZero, step2[11]); - __m256i s3_12_0 = _mm256_cmpgt_epi16(kZero, step2[12]); - __m256i s3_13_0 = _mm256_cmpgt_epi16(kZero, step2[13]); - __m256i s2_14_0 = _mm256_cmpgt_epi16(kZero, step2[14]); - __m256i s2_15_0 = _mm256_cmpgt_epi16(kZero, step2[15]); - __m256i s3_16_0 = _mm256_cmpgt_epi16(kZero, step1[16]); - __m256i s3_17_0 = _mm256_cmpgt_epi16(kZero, step1[17]); - __m256i s3_18_0 = _mm256_cmpgt_epi16(kZero, step1[18]); - __m256i s3_19_0 = _mm256_cmpgt_epi16(kZero, step1[19]); - __m256i s3_20_0 = _mm256_cmpgt_epi16(kZero, step2[20]); - __m256i s3_21_0 = _mm256_cmpgt_epi16(kZero, step2[21]); - __m256i s3_22_0 = _mm256_cmpgt_epi16(kZero, step2[22]); - __m256i s3_23_0 = _mm256_cmpgt_epi16(kZero, step2[23]); - __m256i s3_24_0 = _mm256_cmpgt_epi16(kZero, step2[24]); - __m256i s3_25_0 = _mm256_cmpgt_epi16(kZero, step2[25]); - __m256i s3_26_0 = _mm256_cmpgt_epi16(kZero, step2[26]); - __m256i s3_27_0 = _mm256_cmpgt_epi16(kZero, step2[27]); - __m256i s3_28_0 = _mm256_cmpgt_epi16(kZero, step1[28]); - __m256i s3_29_0 = _mm256_cmpgt_epi16(kZero, step1[29]); - __m256i s3_30_0 = _mm256_cmpgt_epi16(kZero, step1[30]); - __m256i s3_31_0 = _mm256_cmpgt_epi16(kZero, step1[31]); - - step2[0] = _mm256_sub_epi16(step2[0], s3_00_0); - step2[1] = _mm256_sub_epi16(step2[1], s3_01_0); - step2[2] = _mm256_sub_epi16(step2[2], s3_02_0); - step2[3] = _mm256_sub_epi16(step2[3], s3_03_0); - step2[4] = _mm256_sub_epi16(step2[4], s3_04_0); - step2[5] = _mm256_sub_epi16(step2[5], s3_05_0); - step2[6] = _mm256_sub_epi16(step2[6], s3_06_0); - step2[7] = _mm256_sub_epi16(step2[7], s3_07_0); - step2[8] = _mm256_sub_epi16(step2[8], s2_08_0); - step2[9] = _mm256_sub_epi16(step2[9], s2_09_0); - step2[10] = _mm256_sub_epi16(step2[10], s3_10_0); - step2[11] = _mm256_sub_epi16(step2[11], s3_11_0); - step2[12] = _mm256_sub_epi16(step2[12], s3_12_0); - step2[13] = _mm256_sub_epi16(step2[13], s3_13_0); - step2[14] = _mm256_sub_epi16(step2[14], s2_14_0); - step2[15] = _mm256_sub_epi16(step2[15], s2_15_0); - step1[16] = _mm256_sub_epi16(step1[16], s3_16_0); - step1[17] = _mm256_sub_epi16(step1[17], s3_17_0); - step1[18] = _mm256_sub_epi16(step1[18], s3_18_0); - step1[19] = _mm256_sub_epi16(step1[19], s3_19_0); - step2[20] = _mm256_sub_epi16(step2[20], s3_20_0); - step2[21] = _mm256_sub_epi16(step2[21], s3_21_0); - step2[22] = _mm256_sub_epi16(step2[22], s3_22_0); - step2[23] = _mm256_sub_epi16(step2[23], s3_23_0); - step2[24] = _mm256_sub_epi16(step2[24], s3_24_0); - step2[25] = _mm256_sub_epi16(step2[25], s3_25_0); - step2[26] = _mm256_sub_epi16(step2[26], s3_26_0); - step2[27] = _mm256_sub_epi16(step2[27], s3_27_0); - step1[28] = _mm256_sub_epi16(step1[28], s3_28_0); - step1[29] = _mm256_sub_epi16(step1[29], s3_29_0); - step1[30] = _mm256_sub_epi16(step1[30], s3_30_0); - step1[31] = _mm256_sub_epi16(step1[31], s3_31_0); - - step2[0] = _mm256_add_epi16(step2[0], kOne); - step2[1] = _mm256_add_epi16(step2[1], kOne); - step2[2] = _mm256_add_epi16(step2[2], kOne); - step2[3] = _mm256_add_epi16(step2[3], kOne); - step2[4] = _mm256_add_epi16(step2[4], kOne); - step2[5] = _mm256_add_epi16(step2[5], kOne); - step2[6] = _mm256_add_epi16(step2[6], kOne); - step2[7] = _mm256_add_epi16(step2[7], kOne); - step2[8] = _mm256_add_epi16(step2[8], kOne); - step2[9] = _mm256_add_epi16(step2[9], kOne); - step2[10] = _mm256_add_epi16(step2[10], kOne); - step2[11] = _mm256_add_epi16(step2[11], kOne); - step2[12] = _mm256_add_epi16(step2[12], kOne); - step2[13] = _mm256_add_epi16(step2[13], kOne); - step2[14] = _mm256_add_epi16(step2[14], kOne); - step2[15] = _mm256_add_epi16(step2[15], kOne); - step1[16] = _mm256_add_epi16(step1[16], kOne); - step1[17] = _mm256_add_epi16(step1[17], kOne); - step1[18] = _mm256_add_epi16(step1[18], kOne); - step1[19] = _mm256_add_epi16(step1[19], kOne); - step2[20] = _mm256_add_epi16(step2[20], kOne); - step2[21] = _mm256_add_epi16(step2[21], kOne); - step2[22] = _mm256_add_epi16(step2[22], kOne); - step2[23] = _mm256_add_epi16(step2[23], kOne); - step2[24] = _mm256_add_epi16(step2[24], kOne); - step2[25] = _mm256_add_epi16(step2[25], kOne); - step2[26] = _mm256_add_epi16(step2[26], kOne); - step2[27] = _mm256_add_epi16(step2[27], kOne); - step1[28] = _mm256_add_epi16(step1[28], kOne); - step1[29] = _mm256_add_epi16(step1[29], kOne); - step1[30] = _mm256_add_epi16(step1[30], kOne); - step1[31] = _mm256_add_epi16(step1[31], kOne); - - step2[0] = _mm256_srai_epi16(step2[0], 2); - step2[1] = _mm256_srai_epi16(step2[1], 2); - step2[2] = _mm256_srai_epi16(step2[2], 2); - step2[3] = _mm256_srai_epi16(step2[3], 2); - step2[4] = _mm256_srai_epi16(step2[4], 2); - step2[5] = _mm256_srai_epi16(step2[5], 2); - step2[6] = _mm256_srai_epi16(step2[6], 2); - step2[7] = _mm256_srai_epi16(step2[7], 2); - step2[8] = _mm256_srai_epi16(step2[8], 2); - step2[9] = _mm256_srai_epi16(step2[9], 2); - step2[10] = _mm256_srai_epi16(step2[10], 2); - step2[11] = _mm256_srai_epi16(step2[11], 2); - step2[12] = _mm256_srai_epi16(step2[12], 2); - step2[13] = _mm256_srai_epi16(step2[13], 2); - step2[14] = _mm256_srai_epi16(step2[14], 2); - step2[15] = _mm256_srai_epi16(step2[15], 2); - step1[16] = _mm256_srai_epi16(step1[16], 2); - step1[17] = _mm256_srai_epi16(step1[17], 2); - step1[18] = _mm256_srai_epi16(step1[18], 2); - step1[19] = _mm256_srai_epi16(step1[19], 2); - step2[20] = _mm256_srai_epi16(step2[20], 2); - step2[21] = _mm256_srai_epi16(step2[21], 2); - step2[22] = _mm256_srai_epi16(step2[22], 2); - step2[23] = _mm256_srai_epi16(step2[23], 2); - step2[24] = _mm256_srai_epi16(step2[24], 2); - step2[25] = _mm256_srai_epi16(step2[25], 2); - step2[26] = _mm256_srai_epi16(step2[26], 2); - step2[27] = _mm256_srai_epi16(step2[27], 2); - step1[28] = _mm256_srai_epi16(step1[28], 2); - step1[29] = _mm256_srai_epi16(step1[29], 2); - step1[30] = _mm256_srai_epi16(step1[30], 2); - step1[31] = _mm256_srai_epi16(step1[31], 2); - } -#endif - -#if FDCT32x32_HIGH_PRECISION - if (pass == 0) { -#endif - // Stage 3 - { - step3[0] = _mm256_add_epi16(step2[(8 - 1)], step2[0]); - step3[1] = _mm256_add_epi16(step2[(8 - 2)], step2[1]); - step3[2] = _mm256_add_epi16(step2[(8 - 3)], step2[2]); - step3[3] = _mm256_add_epi16(step2[(8 - 4)], step2[3]); - step3[4] = _mm256_sub_epi16(step2[(8 - 5)], step2[4]); - step3[5] = _mm256_sub_epi16(step2[(8 - 6)], step2[5]); - step3[6] = _mm256_sub_epi16(step2[(8 - 7)], step2[6]); - step3[7] = _mm256_sub_epi16(step2[(8 - 8)], step2[7]); - } - { - const __m256i s3_10_0 = _mm256_unpacklo_epi16(step2[13], step2[10]); - const __m256i s3_10_1 = _mm256_unpackhi_epi16(step2[13], step2[10]); - const __m256i s3_11_0 = _mm256_unpacklo_epi16(step2[12], step2[11]); - const __m256i s3_11_1 = _mm256_unpackhi_epi16(step2[12], step2[11]); - const __m256i s3_10_2 = _mm256_madd_epi16(s3_10_0, k__cospi_p16_m16); - const __m256i s3_10_3 = _mm256_madd_epi16(s3_10_1, k__cospi_p16_m16); - const __m256i s3_11_2 = _mm256_madd_epi16(s3_11_0, k__cospi_p16_m16); - const __m256i s3_11_3 = _mm256_madd_epi16(s3_11_1, k__cospi_p16_m16); - const __m256i s3_12_2 = _mm256_madd_epi16(s3_11_0, k__cospi_p16_p16); - const __m256i s3_12_3 = _mm256_madd_epi16(s3_11_1, k__cospi_p16_p16); - const __m256i s3_13_2 = _mm256_madd_epi16(s3_10_0, k__cospi_p16_p16); - const __m256i s3_13_3 = _mm256_madd_epi16(s3_10_1, k__cospi_p16_p16); - // dct_const_round_shift - const __m256i s3_10_4 = - _mm256_add_epi32(s3_10_2, k__DCT_CONST_ROUNDING); - const __m256i s3_10_5 = - _mm256_add_epi32(s3_10_3, k__DCT_CONST_ROUNDING); - const __m256i s3_11_4 = - _mm256_add_epi32(s3_11_2, k__DCT_CONST_ROUNDING); - const __m256i s3_11_5 = - _mm256_add_epi32(s3_11_3, k__DCT_CONST_ROUNDING); - const __m256i s3_12_4 = - _mm256_add_epi32(s3_12_2, k__DCT_CONST_ROUNDING); - const __m256i s3_12_5 = - _mm256_add_epi32(s3_12_3, k__DCT_CONST_ROUNDING); - const __m256i s3_13_4 = - _mm256_add_epi32(s3_13_2, k__DCT_CONST_ROUNDING); - const __m256i s3_13_5 = - _mm256_add_epi32(s3_13_3, k__DCT_CONST_ROUNDING); - const __m256i s3_10_6 = _mm256_srai_epi32(s3_10_4, DCT_CONST_BITS); - const __m256i s3_10_7 = _mm256_srai_epi32(s3_10_5, DCT_CONST_BITS); - const __m256i s3_11_6 = _mm256_srai_epi32(s3_11_4, DCT_CONST_BITS); - const __m256i s3_11_7 = _mm256_srai_epi32(s3_11_5, DCT_CONST_BITS); - const __m256i s3_12_6 = _mm256_srai_epi32(s3_12_4, DCT_CONST_BITS); - const __m256i s3_12_7 = _mm256_srai_epi32(s3_12_5, DCT_CONST_BITS); - const __m256i s3_13_6 = _mm256_srai_epi32(s3_13_4, DCT_CONST_BITS); - const __m256i s3_13_7 = _mm256_srai_epi32(s3_13_5, DCT_CONST_BITS); - // Combine - step3[10] = _mm256_packs_epi32(s3_10_6, s3_10_7); - step3[11] = _mm256_packs_epi32(s3_11_6, s3_11_7); - step3[12] = _mm256_packs_epi32(s3_12_6, s3_12_7); - step3[13] = _mm256_packs_epi32(s3_13_6, s3_13_7); - } - { - step3[16] = _mm256_add_epi16(step2[23], step1[16]); - step3[17] = _mm256_add_epi16(step2[22], step1[17]); - step3[18] = _mm256_add_epi16(step2[21], step1[18]); - step3[19] = _mm256_add_epi16(step2[20], step1[19]); - step3[20] = _mm256_sub_epi16(step1[19], step2[20]); - step3[21] = _mm256_sub_epi16(step1[18], step2[21]); - step3[22] = _mm256_sub_epi16(step1[17], step2[22]); - step3[23] = _mm256_sub_epi16(step1[16], step2[23]); - step3[24] = _mm256_sub_epi16(step1[31], step2[24]); - step3[25] = _mm256_sub_epi16(step1[30], step2[25]); - step3[26] = _mm256_sub_epi16(step1[29], step2[26]); - step3[27] = _mm256_sub_epi16(step1[28], step2[27]); - step3[28] = _mm256_add_epi16(step2[27], step1[28]); - step3[29] = _mm256_add_epi16(step2[26], step1[29]); - step3[30] = _mm256_add_epi16(step2[25], step1[30]); - step3[31] = _mm256_add_epi16(step2[24], step1[31]); - } - - // Stage 4 - { - step1[0] = _mm256_add_epi16(step3[3], step3[0]); - step1[1] = _mm256_add_epi16(step3[2], step3[1]); - step1[2] = _mm256_sub_epi16(step3[1], step3[2]); - step1[3] = _mm256_sub_epi16(step3[0], step3[3]); - step1[8] = _mm256_add_epi16(step3[11], step2[8]); - step1[9] = _mm256_add_epi16(step3[10], step2[9]); - step1[10] = _mm256_sub_epi16(step2[9], step3[10]); - step1[11] = _mm256_sub_epi16(step2[8], step3[11]); - step1[12] = _mm256_sub_epi16(step2[15], step3[12]); - step1[13] = _mm256_sub_epi16(step2[14], step3[13]); - step1[14] = _mm256_add_epi16(step3[13], step2[14]); - step1[15] = _mm256_add_epi16(step3[12], step2[15]); - } - { - const __m256i s1_05_0 = _mm256_unpacklo_epi16(step3[6], step3[5]); - const __m256i s1_05_1 = _mm256_unpackhi_epi16(step3[6], step3[5]); - const __m256i s1_05_2 = _mm256_madd_epi16(s1_05_0, k__cospi_p16_m16); - const __m256i s1_05_3 = _mm256_madd_epi16(s1_05_1, k__cospi_p16_m16); - const __m256i s1_06_2 = _mm256_madd_epi16(s1_05_0, k__cospi_p16_p16); - const __m256i s1_06_3 = _mm256_madd_epi16(s1_05_1, k__cospi_p16_p16); - // dct_const_round_shift - const __m256i s1_05_4 = - _mm256_add_epi32(s1_05_2, k__DCT_CONST_ROUNDING); - const __m256i s1_05_5 = - _mm256_add_epi32(s1_05_3, k__DCT_CONST_ROUNDING); - const __m256i s1_06_4 = - _mm256_add_epi32(s1_06_2, k__DCT_CONST_ROUNDING); - const __m256i s1_06_5 = - _mm256_add_epi32(s1_06_3, k__DCT_CONST_ROUNDING); - const __m256i s1_05_6 = _mm256_srai_epi32(s1_05_4, DCT_CONST_BITS); - const __m256i s1_05_7 = _mm256_srai_epi32(s1_05_5, DCT_CONST_BITS); - const __m256i s1_06_6 = _mm256_srai_epi32(s1_06_4, DCT_CONST_BITS); - const __m256i s1_06_7 = _mm256_srai_epi32(s1_06_5, DCT_CONST_BITS); - // Combine - step1[5] = _mm256_packs_epi32(s1_05_6, s1_05_7); - step1[6] = _mm256_packs_epi32(s1_06_6, s1_06_7); - } - { - const __m256i s1_18_0 = _mm256_unpacklo_epi16(step3[18], step3[29]); - const __m256i s1_18_1 = _mm256_unpackhi_epi16(step3[18], step3[29]); - const __m256i s1_19_0 = _mm256_unpacklo_epi16(step3[19], step3[28]); - const __m256i s1_19_1 = _mm256_unpackhi_epi16(step3[19], step3[28]); - const __m256i s1_20_0 = _mm256_unpacklo_epi16(step3[20], step3[27]); - const __m256i s1_20_1 = _mm256_unpackhi_epi16(step3[20], step3[27]); - const __m256i s1_21_0 = _mm256_unpacklo_epi16(step3[21], step3[26]); - const __m256i s1_21_1 = _mm256_unpackhi_epi16(step3[21], step3[26]); - const __m256i s1_18_2 = _mm256_madd_epi16(s1_18_0, k__cospi_m08_p24); - const __m256i s1_18_3 = _mm256_madd_epi16(s1_18_1, k__cospi_m08_p24); - const __m256i s1_19_2 = _mm256_madd_epi16(s1_19_0, k__cospi_m08_p24); - const __m256i s1_19_3 = _mm256_madd_epi16(s1_19_1, k__cospi_m08_p24); - const __m256i s1_20_2 = _mm256_madd_epi16(s1_20_0, k__cospi_m24_m08); - const __m256i s1_20_3 = _mm256_madd_epi16(s1_20_1, k__cospi_m24_m08); - const __m256i s1_21_2 = _mm256_madd_epi16(s1_21_0, k__cospi_m24_m08); - const __m256i s1_21_3 = _mm256_madd_epi16(s1_21_1, k__cospi_m24_m08); - const __m256i s1_26_2 = _mm256_madd_epi16(s1_21_0, k__cospi_m08_p24); - const __m256i s1_26_3 = _mm256_madd_epi16(s1_21_1, k__cospi_m08_p24); - const __m256i s1_27_2 = _mm256_madd_epi16(s1_20_0, k__cospi_m08_p24); - const __m256i s1_27_3 = _mm256_madd_epi16(s1_20_1, k__cospi_m08_p24); - const __m256i s1_28_2 = _mm256_madd_epi16(s1_19_0, k__cospi_p24_p08); - const __m256i s1_28_3 = _mm256_madd_epi16(s1_19_1, k__cospi_p24_p08); - const __m256i s1_29_2 = _mm256_madd_epi16(s1_18_0, k__cospi_p24_p08); - const __m256i s1_29_3 = _mm256_madd_epi16(s1_18_1, k__cospi_p24_p08); - // dct_const_round_shift - const __m256i s1_18_4 = - _mm256_add_epi32(s1_18_2, k__DCT_CONST_ROUNDING); - const __m256i s1_18_5 = - _mm256_add_epi32(s1_18_3, k__DCT_CONST_ROUNDING); - const __m256i s1_19_4 = - _mm256_add_epi32(s1_19_2, k__DCT_CONST_ROUNDING); - const __m256i s1_19_5 = - _mm256_add_epi32(s1_19_3, k__DCT_CONST_ROUNDING); - const __m256i s1_20_4 = - _mm256_add_epi32(s1_20_2, k__DCT_CONST_ROUNDING); - const __m256i s1_20_5 = - _mm256_add_epi32(s1_20_3, k__DCT_CONST_ROUNDING); - const __m256i s1_21_4 = - _mm256_add_epi32(s1_21_2, k__DCT_CONST_ROUNDING); - const __m256i s1_21_5 = - _mm256_add_epi32(s1_21_3, k__DCT_CONST_ROUNDING); - const __m256i s1_26_4 = - _mm256_add_epi32(s1_26_2, k__DCT_CONST_ROUNDING); - const __m256i s1_26_5 = - _mm256_add_epi32(s1_26_3, k__DCT_CONST_ROUNDING); - const __m256i s1_27_4 = - _mm256_add_epi32(s1_27_2, k__DCT_CONST_ROUNDING); - const __m256i s1_27_5 = - _mm256_add_epi32(s1_27_3, k__DCT_CONST_ROUNDING); - const __m256i s1_28_4 = - _mm256_add_epi32(s1_28_2, k__DCT_CONST_ROUNDING); - const __m256i s1_28_5 = - _mm256_add_epi32(s1_28_3, k__DCT_CONST_ROUNDING); - const __m256i s1_29_4 = - _mm256_add_epi32(s1_29_2, k__DCT_CONST_ROUNDING); - const __m256i s1_29_5 = - _mm256_add_epi32(s1_29_3, k__DCT_CONST_ROUNDING); - const __m256i s1_18_6 = _mm256_srai_epi32(s1_18_4, DCT_CONST_BITS); - const __m256i s1_18_7 = _mm256_srai_epi32(s1_18_5, DCT_CONST_BITS); - const __m256i s1_19_6 = _mm256_srai_epi32(s1_19_4, DCT_CONST_BITS); - const __m256i s1_19_7 = _mm256_srai_epi32(s1_19_5, DCT_CONST_BITS); - const __m256i s1_20_6 = _mm256_srai_epi32(s1_20_4, DCT_CONST_BITS); - const __m256i s1_20_7 = _mm256_srai_epi32(s1_20_5, DCT_CONST_BITS); - const __m256i s1_21_6 = _mm256_srai_epi32(s1_21_4, DCT_CONST_BITS); - const __m256i s1_21_7 = _mm256_srai_epi32(s1_21_5, DCT_CONST_BITS); - const __m256i s1_26_6 = _mm256_srai_epi32(s1_26_4, DCT_CONST_BITS); - const __m256i s1_26_7 = _mm256_srai_epi32(s1_26_5, DCT_CONST_BITS); - const __m256i s1_27_6 = _mm256_srai_epi32(s1_27_4, DCT_CONST_BITS); - const __m256i s1_27_7 = _mm256_srai_epi32(s1_27_5, DCT_CONST_BITS); - const __m256i s1_28_6 = _mm256_srai_epi32(s1_28_4, DCT_CONST_BITS); - const __m256i s1_28_7 = _mm256_srai_epi32(s1_28_5, DCT_CONST_BITS); - const __m256i s1_29_6 = _mm256_srai_epi32(s1_29_4, DCT_CONST_BITS); - const __m256i s1_29_7 = _mm256_srai_epi32(s1_29_5, DCT_CONST_BITS); - // Combine - step1[18] = _mm256_packs_epi32(s1_18_6, s1_18_7); - step1[19] = _mm256_packs_epi32(s1_19_6, s1_19_7); - step1[20] = _mm256_packs_epi32(s1_20_6, s1_20_7); - step1[21] = _mm256_packs_epi32(s1_21_6, s1_21_7); - step1[26] = _mm256_packs_epi32(s1_26_6, s1_26_7); - step1[27] = _mm256_packs_epi32(s1_27_6, s1_27_7); - step1[28] = _mm256_packs_epi32(s1_28_6, s1_28_7); - step1[29] = _mm256_packs_epi32(s1_29_6, s1_29_7); - } - // Stage 5 - { - step2[4] = _mm256_add_epi16(step1[5], step3[4]); - step2[5] = _mm256_sub_epi16(step3[4], step1[5]); - step2[6] = _mm256_sub_epi16(step3[7], step1[6]); - step2[7] = _mm256_add_epi16(step1[6], step3[7]); - } - { - const __m256i out_00_0 = _mm256_unpacklo_epi16(step1[0], step1[1]); - const __m256i out_00_1 = _mm256_unpackhi_epi16(step1[0], step1[1]); - const __m256i out_08_0 = _mm256_unpacklo_epi16(step1[2], step1[3]); - const __m256i out_08_1 = _mm256_unpackhi_epi16(step1[2], step1[3]); - const __m256i out_00_2 = - _mm256_madd_epi16(out_00_0, k__cospi_p16_p16); - const __m256i out_00_3 = - _mm256_madd_epi16(out_00_1, k__cospi_p16_p16); - const __m256i out_16_2 = - _mm256_madd_epi16(out_00_0, k__cospi_p16_m16); - const __m256i out_16_3 = - _mm256_madd_epi16(out_00_1, k__cospi_p16_m16); - const __m256i out_08_2 = - _mm256_madd_epi16(out_08_0, k__cospi_p24_p08); - const __m256i out_08_3 = - _mm256_madd_epi16(out_08_1, k__cospi_p24_p08); - const __m256i out_24_2 = - _mm256_madd_epi16(out_08_0, k__cospi_m08_p24); - const __m256i out_24_3 = - _mm256_madd_epi16(out_08_1, k__cospi_m08_p24); - // dct_const_round_shift - const __m256i out_00_4 = - _mm256_add_epi32(out_00_2, k__DCT_CONST_ROUNDING); - const __m256i out_00_5 = - _mm256_add_epi32(out_00_3, k__DCT_CONST_ROUNDING); - const __m256i out_16_4 = - _mm256_add_epi32(out_16_2, k__DCT_CONST_ROUNDING); - const __m256i out_16_5 = - _mm256_add_epi32(out_16_3, k__DCT_CONST_ROUNDING); - const __m256i out_08_4 = - _mm256_add_epi32(out_08_2, k__DCT_CONST_ROUNDING); - const __m256i out_08_5 = - _mm256_add_epi32(out_08_3, k__DCT_CONST_ROUNDING); - const __m256i out_24_4 = - _mm256_add_epi32(out_24_2, k__DCT_CONST_ROUNDING); - const __m256i out_24_5 = - _mm256_add_epi32(out_24_3, k__DCT_CONST_ROUNDING); - const __m256i out_00_6 = _mm256_srai_epi32(out_00_4, DCT_CONST_BITS); - const __m256i out_00_7 = _mm256_srai_epi32(out_00_5, DCT_CONST_BITS); - const __m256i out_16_6 = _mm256_srai_epi32(out_16_4, DCT_CONST_BITS); - const __m256i out_16_7 = _mm256_srai_epi32(out_16_5, DCT_CONST_BITS); - const __m256i out_08_6 = _mm256_srai_epi32(out_08_4, DCT_CONST_BITS); - const __m256i out_08_7 = _mm256_srai_epi32(out_08_5, DCT_CONST_BITS); - const __m256i out_24_6 = _mm256_srai_epi32(out_24_4, DCT_CONST_BITS); - const __m256i out_24_7 = _mm256_srai_epi32(out_24_5, DCT_CONST_BITS); - // Combine - out[0] = _mm256_packs_epi32(out_00_6, out_00_7); - out[16] = _mm256_packs_epi32(out_16_6, out_16_7); - out[8] = _mm256_packs_epi32(out_08_6, out_08_7); - out[24] = _mm256_packs_epi32(out_24_6, out_24_7); - } - { - const __m256i s2_09_0 = _mm256_unpacklo_epi16(step1[9], step1[14]); - const __m256i s2_09_1 = _mm256_unpackhi_epi16(step1[9], step1[14]); - const __m256i s2_10_0 = _mm256_unpacklo_epi16(step1[10], step1[13]); - const __m256i s2_10_1 = _mm256_unpackhi_epi16(step1[10], step1[13]); - const __m256i s2_09_2 = _mm256_madd_epi16(s2_09_0, k__cospi_m08_p24); - const __m256i s2_09_3 = _mm256_madd_epi16(s2_09_1, k__cospi_m08_p24); - const __m256i s2_10_2 = _mm256_madd_epi16(s2_10_0, k__cospi_m24_m08); - const __m256i s2_10_3 = _mm256_madd_epi16(s2_10_1, k__cospi_m24_m08); - const __m256i s2_13_2 = _mm256_madd_epi16(s2_10_0, k__cospi_m08_p24); - const __m256i s2_13_3 = _mm256_madd_epi16(s2_10_1, k__cospi_m08_p24); - const __m256i s2_14_2 = _mm256_madd_epi16(s2_09_0, k__cospi_p24_p08); - const __m256i s2_14_3 = _mm256_madd_epi16(s2_09_1, k__cospi_p24_p08); - // dct_const_round_shift - const __m256i s2_09_4 = - _mm256_add_epi32(s2_09_2, k__DCT_CONST_ROUNDING); - const __m256i s2_09_5 = - _mm256_add_epi32(s2_09_3, k__DCT_CONST_ROUNDING); - const __m256i s2_10_4 = - _mm256_add_epi32(s2_10_2, k__DCT_CONST_ROUNDING); - const __m256i s2_10_5 = - _mm256_add_epi32(s2_10_3, k__DCT_CONST_ROUNDING); - const __m256i s2_13_4 = - _mm256_add_epi32(s2_13_2, k__DCT_CONST_ROUNDING); - const __m256i s2_13_5 = - _mm256_add_epi32(s2_13_3, k__DCT_CONST_ROUNDING); - const __m256i s2_14_4 = - _mm256_add_epi32(s2_14_2, k__DCT_CONST_ROUNDING); - const __m256i s2_14_5 = - _mm256_add_epi32(s2_14_3, k__DCT_CONST_ROUNDING); - const __m256i s2_09_6 = _mm256_srai_epi32(s2_09_4, DCT_CONST_BITS); - const __m256i s2_09_7 = _mm256_srai_epi32(s2_09_5, DCT_CONST_BITS); - const __m256i s2_10_6 = _mm256_srai_epi32(s2_10_4, DCT_CONST_BITS); - const __m256i s2_10_7 = _mm256_srai_epi32(s2_10_5, DCT_CONST_BITS); - const __m256i s2_13_6 = _mm256_srai_epi32(s2_13_4, DCT_CONST_BITS); - const __m256i s2_13_7 = _mm256_srai_epi32(s2_13_5, DCT_CONST_BITS); - const __m256i s2_14_6 = _mm256_srai_epi32(s2_14_4, DCT_CONST_BITS); - const __m256i s2_14_7 = _mm256_srai_epi32(s2_14_5, DCT_CONST_BITS); - // Combine - step2[9] = _mm256_packs_epi32(s2_09_6, s2_09_7); - step2[10] = _mm256_packs_epi32(s2_10_6, s2_10_7); - step2[13] = _mm256_packs_epi32(s2_13_6, s2_13_7); - step2[14] = _mm256_packs_epi32(s2_14_6, s2_14_7); - } - { - step2[16] = _mm256_add_epi16(step1[19], step3[16]); - step2[17] = _mm256_add_epi16(step1[18], step3[17]); - step2[18] = _mm256_sub_epi16(step3[17], step1[18]); - step2[19] = _mm256_sub_epi16(step3[16], step1[19]); - step2[20] = _mm256_sub_epi16(step3[23], step1[20]); - step2[21] = _mm256_sub_epi16(step3[22], step1[21]); - step2[22] = _mm256_add_epi16(step1[21], step3[22]); - step2[23] = _mm256_add_epi16(step1[20], step3[23]); - step2[24] = _mm256_add_epi16(step1[27], step3[24]); - step2[25] = _mm256_add_epi16(step1[26], step3[25]); - step2[26] = _mm256_sub_epi16(step3[25], step1[26]); - step2[27] = _mm256_sub_epi16(step3[24], step1[27]); - step2[28] = _mm256_sub_epi16(step3[31], step1[28]); - step2[29] = _mm256_sub_epi16(step3[30], step1[29]); - step2[30] = _mm256_add_epi16(step1[29], step3[30]); - step2[31] = _mm256_add_epi16(step1[28], step3[31]); - } - // Stage 6 - { - const __m256i out_04_0 = _mm256_unpacklo_epi16(step2[4], step2[7]); - const __m256i out_04_1 = _mm256_unpackhi_epi16(step2[4], step2[7]); - const __m256i out_20_0 = _mm256_unpacklo_epi16(step2[5], step2[6]); - const __m256i out_20_1 = _mm256_unpackhi_epi16(step2[5], step2[6]); - const __m256i out_12_0 = _mm256_unpacklo_epi16(step2[5], step2[6]); - const __m256i out_12_1 = _mm256_unpackhi_epi16(step2[5], step2[6]); - const __m256i out_28_0 = _mm256_unpacklo_epi16(step2[4], step2[7]); - const __m256i out_28_1 = _mm256_unpackhi_epi16(step2[4], step2[7]); - const __m256i out_04_2 = - _mm256_madd_epi16(out_04_0, k__cospi_p28_p04); - const __m256i out_04_3 = - _mm256_madd_epi16(out_04_1, k__cospi_p28_p04); - const __m256i out_20_2 = - _mm256_madd_epi16(out_20_0, k__cospi_p12_p20); - const __m256i out_20_3 = - _mm256_madd_epi16(out_20_1, k__cospi_p12_p20); - const __m256i out_12_2 = - _mm256_madd_epi16(out_12_0, k__cospi_m20_p12); - const __m256i out_12_3 = - _mm256_madd_epi16(out_12_1, k__cospi_m20_p12); - const __m256i out_28_2 = - _mm256_madd_epi16(out_28_0, k__cospi_m04_p28); - const __m256i out_28_3 = - _mm256_madd_epi16(out_28_1, k__cospi_m04_p28); - // dct_const_round_shift - const __m256i out_04_4 = - _mm256_add_epi32(out_04_2, k__DCT_CONST_ROUNDING); - const __m256i out_04_5 = - _mm256_add_epi32(out_04_3, k__DCT_CONST_ROUNDING); - const __m256i out_20_4 = - _mm256_add_epi32(out_20_2, k__DCT_CONST_ROUNDING); - const __m256i out_20_5 = - _mm256_add_epi32(out_20_3, k__DCT_CONST_ROUNDING); - const __m256i out_12_4 = - _mm256_add_epi32(out_12_2, k__DCT_CONST_ROUNDING); - const __m256i out_12_5 = - _mm256_add_epi32(out_12_3, k__DCT_CONST_ROUNDING); - const __m256i out_28_4 = - _mm256_add_epi32(out_28_2, k__DCT_CONST_ROUNDING); - const __m256i out_28_5 = - _mm256_add_epi32(out_28_3, k__DCT_CONST_ROUNDING); - const __m256i out_04_6 = _mm256_srai_epi32(out_04_4, DCT_CONST_BITS); - const __m256i out_04_7 = _mm256_srai_epi32(out_04_5, DCT_CONST_BITS); - const __m256i out_20_6 = _mm256_srai_epi32(out_20_4, DCT_CONST_BITS); - const __m256i out_20_7 = _mm256_srai_epi32(out_20_5, DCT_CONST_BITS); - const __m256i out_12_6 = _mm256_srai_epi32(out_12_4, DCT_CONST_BITS); - const __m256i out_12_7 = _mm256_srai_epi32(out_12_5, DCT_CONST_BITS); - const __m256i out_28_6 = _mm256_srai_epi32(out_28_4, DCT_CONST_BITS); - const __m256i out_28_7 = _mm256_srai_epi32(out_28_5, DCT_CONST_BITS); - // Combine - out[4] = _mm256_packs_epi32(out_04_6, out_04_7); - out[20] = _mm256_packs_epi32(out_20_6, out_20_7); - out[12] = _mm256_packs_epi32(out_12_6, out_12_7); - out[28] = _mm256_packs_epi32(out_28_6, out_28_7); - } - { - step3[8] = _mm256_add_epi16(step2[9], step1[8]); - step3[9] = _mm256_sub_epi16(step1[8], step2[9]); - step3[10] = _mm256_sub_epi16(step1[11], step2[10]); - step3[11] = _mm256_add_epi16(step2[10], step1[11]); - step3[12] = _mm256_add_epi16(step2[13], step1[12]); - step3[13] = _mm256_sub_epi16(step1[12], step2[13]); - step3[14] = _mm256_sub_epi16(step1[15], step2[14]); - step3[15] = _mm256_add_epi16(step2[14], step1[15]); - } - { - const __m256i s3_17_0 = _mm256_unpacklo_epi16(step2[17], step2[30]); - const __m256i s3_17_1 = _mm256_unpackhi_epi16(step2[17], step2[30]); - const __m256i s3_18_0 = _mm256_unpacklo_epi16(step2[18], step2[29]); - const __m256i s3_18_1 = _mm256_unpackhi_epi16(step2[18], step2[29]); - const __m256i s3_21_0 = _mm256_unpacklo_epi16(step2[21], step2[26]); - const __m256i s3_21_1 = _mm256_unpackhi_epi16(step2[21], step2[26]); - const __m256i s3_22_0 = _mm256_unpacklo_epi16(step2[22], step2[25]); - const __m256i s3_22_1 = _mm256_unpackhi_epi16(step2[22], step2[25]); - const __m256i s3_17_2 = _mm256_madd_epi16(s3_17_0, k__cospi_m04_p28); - const __m256i s3_17_3 = _mm256_madd_epi16(s3_17_1, k__cospi_m04_p28); - const __m256i s3_18_2 = _mm256_madd_epi16(s3_18_0, k__cospi_m28_m04); - const __m256i s3_18_3 = _mm256_madd_epi16(s3_18_1, k__cospi_m28_m04); - const __m256i s3_21_2 = _mm256_madd_epi16(s3_21_0, k__cospi_m20_p12); - const __m256i s3_21_3 = _mm256_madd_epi16(s3_21_1, k__cospi_m20_p12); - const __m256i s3_22_2 = _mm256_madd_epi16(s3_22_0, k__cospi_m12_m20); - const __m256i s3_22_3 = _mm256_madd_epi16(s3_22_1, k__cospi_m12_m20); - const __m256i s3_25_2 = _mm256_madd_epi16(s3_22_0, k__cospi_m20_p12); - const __m256i s3_25_3 = _mm256_madd_epi16(s3_22_1, k__cospi_m20_p12); - const __m256i s3_26_2 = _mm256_madd_epi16(s3_21_0, k__cospi_p12_p20); - const __m256i s3_26_3 = _mm256_madd_epi16(s3_21_1, k__cospi_p12_p20); - const __m256i s3_29_2 = _mm256_madd_epi16(s3_18_0, k__cospi_m04_p28); - const __m256i s3_29_3 = _mm256_madd_epi16(s3_18_1, k__cospi_m04_p28); - const __m256i s3_30_2 = _mm256_madd_epi16(s3_17_0, k__cospi_p28_p04); - const __m256i s3_30_3 = _mm256_madd_epi16(s3_17_1, k__cospi_p28_p04); - // dct_const_round_shift - const __m256i s3_17_4 = - _mm256_add_epi32(s3_17_2, k__DCT_CONST_ROUNDING); - const __m256i s3_17_5 = - _mm256_add_epi32(s3_17_3, k__DCT_CONST_ROUNDING); - const __m256i s3_18_4 = - _mm256_add_epi32(s3_18_2, k__DCT_CONST_ROUNDING); - const __m256i s3_18_5 = - _mm256_add_epi32(s3_18_3, k__DCT_CONST_ROUNDING); - const __m256i s3_21_4 = - _mm256_add_epi32(s3_21_2, k__DCT_CONST_ROUNDING); - const __m256i s3_21_5 = - _mm256_add_epi32(s3_21_3, k__DCT_CONST_ROUNDING); - const __m256i s3_22_4 = - _mm256_add_epi32(s3_22_2, k__DCT_CONST_ROUNDING); - const __m256i s3_22_5 = - _mm256_add_epi32(s3_22_3, k__DCT_CONST_ROUNDING); - const __m256i s3_17_6 = _mm256_srai_epi32(s3_17_4, DCT_CONST_BITS); - const __m256i s3_17_7 = _mm256_srai_epi32(s3_17_5, DCT_CONST_BITS); - const __m256i s3_18_6 = _mm256_srai_epi32(s3_18_4, DCT_CONST_BITS); - const __m256i s3_18_7 = _mm256_srai_epi32(s3_18_5, DCT_CONST_BITS); - const __m256i s3_21_6 = _mm256_srai_epi32(s3_21_4, DCT_CONST_BITS); - const __m256i s3_21_7 = _mm256_srai_epi32(s3_21_5, DCT_CONST_BITS); - const __m256i s3_22_6 = _mm256_srai_epi32(s3_22_4, DCT_CONST_BITS); - const __m256i s3_22_7 = _mm256_srai_epi32(s3_22_5, DCT_CONST_BITS); - const __m256i s3_25_4 = - _mm256_add_epi32(s3_25_2, k__DCT_CONST_ROUNDING); - const __m256i s3_25_5 = - _mm256_add_epi32(s3_25_3, k__DCT_CONST_ROUNDING); - const __m256i s3_26_4 = - _mm256_add_epi32(s3_26_2, k__DCT_CONST_ROUNDING); - const __m256i s3_26_5 = - _mm256_add_epi32(s3_26_3, k__DCT_CONST_ROUNDING); - const __m256i s3_29_4 = - _mm256_add_epi32(s3_29_2, k__DCT_CONST_ROUNDING); - const __m256i s3_29_5 = - _mm256_add_epi32(s3_29_3, k__DCT_CONST_ROUNDING); - const __m256i s3_30_4 = - _mm256_add_epi32(s3_30_2, k__DCT_CONST_ROUNDING); - const __m256i s3_30_5 = - _mm256_add_epi32(s3_30_3, k__DCT_CONST_ROUNDING); - const __m256i s3_25_6 = _mm256_srai_epi32(s3_25_4, DCT_CONST_BITS); - const __m256i s3_25_7 = _mm256_srai_epi32(s3_25_5, DCT_CONST_BITS); - const __m256i s3_26_6 = _mm256_srai_epi32(s3_26_4, DCT_CONST_BITS); - const __m256i s3_26_7 = _mm256_srai_epi32(s3_26_5, DCT_CONST_BITS); - const __m256i s3_29_6 = _mm256_srai_epi32(s3_29_4, DCT_CONST_BITS); - const __m256i s3_29_7 = _mm256_srai_epi32(s3_29_5, DCT_CONST_BITS); - const __m256i s3_30_6 = _mm256_srai_epi32(s3_30_4, DCT_CONST_BITS); - const __m256i s3_30_7 = _mm256_srai_epi32(s3_30_5, DCT_CONST_BITS); - // Combine - step3[17] = _mm256_packs_epi32(s3_17_6, s3_17_7); - step3[18] = _mm256_packs_epi32(s3_18_6, s3_18_7); - step3[21] = _mm256_packs_epi32(s3_21_6, s3_21_7); - step3[22] = _mm256_packs_epi32(s3_22_6, s3_22_7); - // Combine - step3[25] = _mm256_packs_epi32(s3_25_6, s3_25_7); - step3[26] = _mm256_packs_epi32(s3_26_6, s3_26_7); - step3[29] = _mm256_packs_epi32(s3_29_6, s3_29_7); - step3[30] = _mm256_packs_epi32(s3_30_6, s3_30_7); - } - // Stage 7 - { - const __m256i out_02_0 = _mm256_unpacklo_epi16(step3[8], step3[15]); - const __m256i out_02_1 = _mm256_unpackhi_epi16(step3[8], step3[15]); - const __m256i out_18_0 = _mm256_unpacklo_epi16(step3[9], step3[14]); - const __m256i out_18_1 = _mm256_unpackhi_epi16(step3[9], step3[14]); - const __m256i out_10_0 = _mm256_unpacklo_epi16(step3[10], step3[13]); - const __m256i out_10_1 = _mm256_unpackhi_epi16(step3[10], step3[13]); - const __m256i out_26_0 = _mm256_unpacklo_epi16(step3[11], step3[12]); - const __m256i out_26_1 = _mm256_unpackhi_epi16(step3[11], step3[12]); - const __m256i out_02_2 = - _mm256_madd_epi16(out_02_0, k__cospi_p30_p02); - const __m256i out_02_3 = - _mm256_madd_epi16(out_02_1, k__cospi_p30_p02); - const __m256i out_18_2 = - _mm256_madd_epi16(out_18_0, k__cospi_p14_p18); - const __m256i out_18_3 = - _mm256_madd_epi16(out_18_1, k__cospi_p14_p18); - const __m256i out_10_2 = - _mm256_madd_epi16(out_10_0, k__cospi_p22_p10); - const __m256i out_10_3 = - _mm256_madd_epi16(out_10_1, k__cospi_p22_p10); - const __m256i out_26_2 = - _mm256_madd_epi16(out_26_0, k__cospi_p06_p26); - const __m256i out_26_3 = - _mm256_madd_epi16(out_26_1, k__cospi_p06_p26); - const __m256i out_06_2 = - _mm256_madd_epi16(out_26_0, k__cospi_m26_p06); - const __m256i out_06_3 = - _mm256_madd_epi16(out_26_1, k__cospi_m26_p06); - const __m256i out_22_2 = - _mm256_madd_epi16(out_10_0, k__cospi_m10_p22); - const __m256i out_22_3 = - _mm256_madd_epi16(out_10_1, k__cospi_m10_p22); - const __m256i out_14_2 = - _mm256_madd_epi16(out_18_0, k__cospi_m18_p14); - const __m256i out_14_3 = - _mm256_madd_epi16(out_18_1, k__cospi_m18_p14); - const __m256i out_30_2 = - _mm256_madd_epi16(out_02_0, k__cospi_m02_p30); - const __m256i out_30_3 = - _mm256_madd_epi16(out_02_1, k__cospi_m02_p30); - // dct_const_round_shift - const __m256i out_02_4 = - _mm256_add_epi32(out_02_2, k__DCT_CONST_ROUNDING); - const __m256i out_02_5 = - _mm256_add_epi32(out_02_3, k__DCT_CONST_ROUNDING); - const __m256i out_18_4 = - _mm256_add_epi32(out_18_2, k__DCT_CONST_ROUNDING); - const __m256i out_18_5 = - _mm256_add_epi32(out_18_3, k__DCT_CONST_ROUNDING); - const __m256i out_10_4 = - _mm256_add_epi32(out_10_2, k__DCT_CONST_ROUNDING); - const __m256i out_10_5 = - _mm256_add_epi32(out_10_3, k__DCT_CONST_ROUNDING); - const __m256i out_26_4 = - _mm256_add_epi32(out_26_2, k__DCT_CONST_ROUNDING); - const __m256i out_26_5 = - _mm256_add_epi32(out_26_3, k__DCT_CONST_ROUNDING); - const __m256i out_06_4 = - _mm256_add_epi32(out_06_2, k__DCT_CONST_ROUNDING); - const __m256i out_06_5 = - _mm256_add_epi32(out_06_3, k__DCT_CONST_ROUNDING); - const __m256i out_22_4 = - _mm256_add_epi32(out_22_2, k__DCT_CONST_ROUNDING); - const __m256i out_22_5 = - _mm256_add_epi32(out_22_3, k__DCT_CONST_ROUNDING); - const __m256i out_14_4 = - _mm256_add_epi32(out_14_2, k__DCT_CONST_ROUNDING); - const __m256i out_14_5 = - _mm256_add_epi32(out_14_3, k__DCT_CONST_ROUNDING); - const __m256i out_30_4 = - _mm256_add_epi32(out_30_2, k__DCT_CONST_ROUNDING); - const __m256i out_30_5 = - _mm256_add_epi32(out_30_3, k__DCT_CONST_ROUNDING); - const __m256i out_02_6 = _mm256_srai_epi32(out_02_4, DCT_CONST_BITS); - const __m256i out_02_7 = _mm256_srai_epi32(out_02_5, DCT_CONST_BITS); - const __m256i out_18_6 = _mm256_srai_epi32(out_18_4, DCT_CONST_BITS); - const __m256i out_18_7 = _mm256_srai_epi32(out_18_5, DCT_CONST_BITS); - const __m256i out_10_6 = _mm256_srai_epi32(out_10_4, DCT_CONST_BITS); - const __m256i out_10_7 = _mm256_srai_epi32(out_10_5, DCT_CONST_BITS); - const __m256i out_26_6 = _mm256_srai_epi32(out_26_4, DCT_CONST_BITS); - const __m256i out_26_7 = _mm256_srai_epi32(out_26_5, DCT_CONST_BITS); - const __m256i out_06_6 = _mm256_srai_epi32(out_06_4, DCT_CONST_BITS); - const __m256i out_06_7 = _mm256_srai_epi32(out_06_5, DCT_CONST_BITS); - const __m256i out_22_6 = _mm256_srai_epi32(out_22_4, DCT_CONST_BITS); - const __m256i out_22_7 = _mm256_srai_epi32(out_22_5, DCT_CONST_BITS); - const __m256i out_14_6 = _mm256_srai_epi32(out_14_4, DCT_CONST_BITS); - const __m256i out_14_7 = _mm256_srai_epi32(out_14_5, DCT_CONST_BITS); - const __m256i out_30_6 = _mm256_srai_epi32(out_30_4, DCT_CONST_BITS); - const __m256i out_30_7 = _mm256_srai_epi32(out_30_5, DCT_CONST_BITS); - // Combine - out[2] = _mm256_packs_epi32(out_02_6, out_02_7); - out[18] = _mm256_packs_epi32(out_18_6, out_18_7); - out[10] = _mm256_packs_epi32(out_10_6, out_10_7); - out[26] = _mm256_packs_epi32(out_26_6, out_26_7); - out[6] = _mm256_packs_epi32(out_06_6, out_06_7); - out[22] = _mm256_packs_epi32(out_22_6, out_22_7); - out[14] = _mm256_packs_epi32(out_14_6, out_14_7); - out[30] = _mm256_packs_epi32(out_30_6, out_30_7); - } - { - step1[16] = _mm256_add_epi16(step3[17], step2[16]); - step1[17] = _mm256_sub_epi16(step2[16], step3[17]); - step1[18] = _mm256_sub_epi16(step2[19], step3[18]); - step1[19] = _mm256_add_epi16(step3[18], step2[19]); - step1[20] = _mm256_add_epi16(step3[21], step2[20]); - step1[21] = _mm256_sub_epi16(step2[20], step3[21]); - step1[22] = _mm256_sub_epi16(step2[23], step3[22]); - step1[23] = _mm256_add_epi16(step3[22], step2[23]); - step1[24] = _mm256_add_epi16(step3[25], step2[24]); - step1[25] = _mm256_sub_epi16(step2[24], step3[25]); - step1[26] = _mm256_sub_epi16(step2[27], step3[26]); - step1[27] = _mm256_add_epi16(step3[26], step2[27]); - step1[28] = _mm256_add_epi16(step3[29], step2[28]); - step1[29] = _mm256_sub_epi16(step2[28], step3[29]); - step1[30] = _mm256_sub_epi16(step2[31], step3[30]); - step1[31] = _mm256_add_epi16(step3[30], step2[31]); - } - // Final stage --- outputs indices are bit-reversed. - { - const __m256i out_01_0 = _mm256_unpacklo_epi16(step1[16], step1[31]); - const __m256i out_01_1 = _mm256_unpackhi_epi16(step1[16], step1[31]); - const __m256i out_17_0 = _mm256_unpacklo_epi16(step1[17], step1[30]); - const __m256i out_17_1 = _mm256_unpackhi_epi16(step1[17], step1[30]); - const __m256i out_09_0 = _mm256_unpacklo_epi16(step1[18], step1[29]); - const __m256i out_09_1 = _mm256_unpackhi_epi16(step1[18], step1[29]); - const __m256i out_25_0 = _mm256_unpacklo_epi16(step1[19], step1[28]); - const __m256i out_25_1 = _mm256_unpackhi_epi16(step1[19], step1[28]); - const __m256i out_01_2 = - _mm256_madd_epi16(out_01_0, k__cospi_p31_p01); - const __m256i out_01_3 = - _mm256_madd_epi16(out_01_1, k__cospi_p31_p01); - const __m256i out_17_2 = - _mm256_madd_epi16(out_17_0, k__cospi_p15_p17); - const __m256i out_17_3 = - _mm256_madd_epi16(out_17_1, k__cospi_p15_p17); - const __m256i out_09_2 = - _mm256_madd_epi16(out_09_0, k__cospi_p23_p09); - const __m256i out_09_3 = - _mm256_madd_epi16(out_09_1, k__cospi_p23_p09); - const __m256i out_25_2 = - _mm256_madd_epi16(out_25_0, k__cospi_p07_p25); - const __m256i out_25_3 = - _mm256_madd_epi16(out_25_1, k__cospi_p07_p25); - const __m256i out_07_2 = - _mm256_madd_epi16(out_25_0, k__cospi_m25_p07); - const __m256i out_07_3 = - _mm256_madd_epi16(out_25_1, k__cospi_m25_p07); - const __m256i out_23_2 = - _mm256_madd_epi16(out_09_0, k__cospi_m09_p23); - const __m256i out_23_3 = - _mm256_madd_epi16(out_09_1, k__cospi_m09_p23); - const __m256i out_15_2 = - _mm256_madd_epi16(out_17_0, k__cospi_m17_p15); - const __m256i out_15_3 = - _mm256_madd_epi16(out_17_1, k__cospi_m17_p15); - const __m256i out_31_2 = - _mm256_madd_epi16(out_01_0, k__cospi_m01_p31); - const __m256i out_31_3 = - _mm256_madd_epi16(out_01_1, k__cospi_m01_p31); - // dct_const_round_shift - const __m256i out_01_4 = - _mm256_add_epi32(out_01_2, k__DCT_CONST_ROUNDING); - const __m256i out_01_5 = - _mm256_add_epi32(out_01_3, k__DCT_CONST_ROUNDING); - const __m256i out_17_4 = - _mm256_add_epi32(out_17_2, k__DCT_CONST_ROUNDING); - const __m256i out_17_5 = - _mm256_add_epi32(out_17_3, k__DCT_CONST_ROUNDING); - const __m256i out_09_4 = - _mm256_add_epi32(out_09_2, k__DCT_CONST_ROUNDING); - const __m256i out_09_5 = - _mm256_add_epi32(out_09_3, k__DCT_CONST_ROUNDING); - const __m256i out_25_4 = - _mm256_add_epi32(out_25_2, k__DCT_CONST_ROUNDING); - const __m256i out_25_5 = - _mm256_add_epi32(out_25_3, k__DCT_CONST_ROUNDING); - const __m256i out_07_4 = - _mm256_add_epi32(out_07_2, k__DCT_CONST_ROUNDING); - const __m256i out_07_5 = - _mm256_add_epi32(out_07_3, k__DCT_CONST_ROUNDING); - const __m256i out_23_4 = - _mm256_add_epi32(out_23_2, k__DCT_CONST_ROUNDING); - const __m256i out_23_5 = - _mm256_add_epi32(out_23_3, k__DCT_CONST_ROUNDING); - const __m256i out_15_4 = - _mm256_add_epi32(out_15_2, k__DCT_CONST_ROUNDING); - const __m256i out_15_5 = - _mm256_add_epi32(out_15_3, k__DCT_CONST_ROUNDING); - const __m256i out_31_4 = - _mm256_add_epi32(out_31_2, k__DCT_CONST_ROUNDING); - const __m256i out_31_5 = - _mm256_add_epi32(out_31_3, k__DCT_CONST_ROUNDING); - const __m256i out_01_6 = _mm256_srai_epi32(out_01_4, DCT_CONST_BITS); - const __m256i out_01_7 = _mm256_srai_epi32(out_01_5, DCT_CONST_BITS); - const __m256i out_17_6 = _mm256_srai_epi32(out_17_4, DCT_CONST_BITS); - const __m256i out_17_7 = _mm256_srai_epi32(out_17_5, DCT_CONST_BITS); - const __m256i out_09_6 = _mm256_srai_epi32(out_09_4, DCT_CONST_BITS); - const __m256i out_09_7 = _mm256_srai_epi32(out_09_5, DCT_CONST_BITS); - const __m256i out_25_6 = _mm256_srai_epi32(out_25_4, DCT_CONST_BITS); - const __m256i out_25_7 = _mm256_srai_epi32(out_25_5, DCT_CONST_BITS); - const __m256i out_07_6 = _mm256_srai_epi32(out_07_4, DCT_CONST_BITS); - const __m256i out_07_7 = _mm256_srai_epi32(out_07_5, DCT_CONST_BITS); - const __m256i out_23_6 = _mm256_srai_epi32(out_23_4, DCT_CONST_BITS); - const __m256i out_23_7 = _mm256_srai_epi32(out_23_5, DCT_CONST_BITS); - const __m256i out_15_6 = _mm256_srai_epi32(out_15_4, DCT_CONST_BITS); - const __m256i out_15_7 = _mm256_srai_epi32(out_15_5, DCT_CONST_BITS); - const __m256i out_31_6 = _mm256_srai_epi32(out_31_4, DCT_CONST_BITS); - const __m256i out_31_7 = _mm256_srai_epi32(out_31_5, DCT_CONST_BITS); - // Combine - out[1] = _mm256_packs_epi32(out_01_6, out_01_7); - out[17] = _mm256_packs_epi32(out_17_6, out_17_7); - out[9] = _mm256_packs_epi32(out_09_6, out_09_7); - out[25] = _mm256_packs_epi32(out_25_6, out_25_7); - out[7] = _mm256_packs_epi32(out_07_6, out_07_7); - out[23] = _mm256_packs_epi32(out_23_6, out_23_7); - out[15] = _mm256_packs_epi32(out_15_6, out_15_7); - out[31] = _mm256_packs_epi32(out_31_6, out_31_7); - } - { - const __m256i out_05_0 = _mm256_unpacklo_epi16(step1[20], step1[27]); - const __m256i out_05_1 = _mm256_unpackhi_epi16(step1[20], step1[27]); - const __m256i out_21_0 = _mm256_unpacklo_epi16(step1[21], step1[26]); - const __m256i out_21_1 = _mm256_unpackhi_epi16(step1[21], step1[26]); - const __m256i out_13_0 = _mm256_unpacklo_epi16(step1[22], step1[25]); - const __m256i out_13_1 = _mm256_unpackhi_epi16(step1[22], step1[25]); - const __m256i out_29_0 = _mm256_unpacklo_epi16(step1[23], step1[24]); - const __m256i out_29_1 = _mm256_unpackhi_epi16(step1[23], step1[24]); - const __m256i out_05_2 = - _mm256_madd_epi16(out_05_0, k__cospi_p27_p05); - const __m256i out_05_3 = - _mm256_madd_epi16(out_05_1, k__cospi_p27_p05); - const __m256i out_21_2 = - _mm256_madd_epi16(out_21_0, k__cospi_p11_p21); - const __m256i out_21_3 = - _mm256_madd_epi16(out_21_1, k__cospi_p11_p21); - const __m256i out_13_2 = - _mm256_madd_epi16(out_13_0, k__cospi_p19_p13); - const __m256i out_13_3 = - _mm256_madd_epi16(out_13_1, k__cospi_p19_p13); - const __m256i out_29_2 = - _mm256_madd_epi16(out_29_0, k__cospi_p03_p29); - const __m256i out_29_3 = - _mm256_madd_epi16(out_29_1, k__cospi_p03_p29); - const __m256i out_03_2 = - _mm256_madd_epi16(out_29_0, k__cospi_m29_p03); - const __m256i out_03_3 = - _mm256_madd_epi16(out_29_1, k__cospi_m29_p03); - const __m256i out_19_2 = - _mm256_madd_epi16(out_13_0, k__cospi_m13_p19); - const __m256i out_19_3 = - _mm256_madd_epi16(out_13_1, k__cospi_m13_p19); - const __m256i out_11_2 = - _mm256_madd_epi16(out_21_0, k__cospi_m21_p11); - const __m256i out_11_3 = - _mm256_madd_epi16(out_21_1, k__cospi_m21_p11); - const __m256i out_27_2 = - _mm256_madd_epi16(out_05_0, k__cospi_m05_p27); - const __m256i out_27_3 = - _mm256_madd_epi16(out_05_1, k__cospi_m05_p27); - // dct_const_round_shift - const __m256i out_05_4 = - _mm256_add_epi32(out_05_2, k__DCT_CONST_ROUNDING); - const __m256i out_05_5 = - _mm256_add_epi32(out_05_3, k__DCT_CONST_ROUNDING); - const __m256i out_21_4 = - _mm256_add_epi32(out_21_2, k__DCT_CONST_ROUNDING); - const __m256i out_21_5 = - _mm256_add_epi32(out_21_3, k__DCT_CONST_ROUNDING); - const __m256i out_13_4 = - _mm256_add_epi32(out_13_2, k__DCT_CONST_ROUNDING); - const __m256i out_13_5 = - _mm256_add_epi32(out_13_3, k__DCT_CONST_ROUNDING); - const __m256i out_29_4 = - _mm256_add_epi32(out_29_2, k__DCT_CONST_ROUNDING); - const __m256i out_29_5 = - _mm256_add_epi32(out_29_3, k__DCT_CONST_ROUNDING); - const __m256i out_03_4 = - _mm256_add_epi32(out_03_2, k__DCT_CONST_ROUNDING); - const __m256i out_03_5 = - _mm256_add_epi32(out_03_3, k__DCT_CONST_ROUNDING); - const __m256i out_19_4 = - _mm256_add_epi32(out_19_2, k__DCT_CONST_ROUNDING); - const __m256i out_19_5 = - _mm256_add_epi32(out_19_3, k__DCT_CONST_ROUNDING); - const __m256i out_11_4 = - _mm256_add_epi32(out_11_2, k__DCT_CONST_ROUNDING); - const __m256i out_11_5 = - _mm256_add_epi32(out_11_3, k__DCT_CONST_ROUNDING); - const __m256i out_27_4 = - _mm256_add_epi32(out_27_2, k__DCT_CONST_ROUNDING); - const __m256i out_27_5 = - _mm256_add_epi32(out_27_3, k__DCT_CONST_ROUNDING); - const __m256i out_05_6 = _mm256_srai_epi32(out_05_4, DCT_CONST_BITS); - const __m256i out_05_7 = _mm256_srai_epi32(out_05_5, DCT_CONST_BITS); - const __m256i out_21_6 = _mm256_srai_epi32(out_21_4, DCT_CONST_BITS); - const __m256i out_21_7 = _mm256_srai_epi32(out_21_5, DCT_CONST_BITS); - const __m256i out_13_6 = _mm256_srai_epi32(out_13_4, DCT_CONST_BITS); - const __m256i out_13_7 = _mm256_srai_epi32(out_13_5, DCT_CONST_BITS); - const __m256i out_29_6 = _mm256_srai_epi32(out_29_4, DCT_CONST_BITS); - const __m256i out_29_7 = _mm256_srai_epi32(out_29_5, DCT_CONST_BITS); - const __m256i out_03_6 = _mm256_srai_epi32(out_03_4, DCT_CONST_BITS); - const __m256i out_03_7 = _mm256_srai_epi32(out_03_5, DCT_CONST_BITS); - const __m256i out_19_6 = _mm256_srai_epi32(out_19_4, DCT_CONST_BITS); - const __m256i out_19_7 = _mm256_srai_epi32(out_19_5, DCT_CONST_BITS); - const __m256i out_11_6 = _mm256_srai_epi32(out_11_4, DCT_CONST_BITS); - const __m256i out_11_7 = _mm256_srai_epi32(out_11_5, DCT_CONST_BITS); - const __m256i out_27_6 = _mm256_srai_epi32(out_27_4, DCT_CONST_BITS); - const __m256i out_27_7 = _mm256_srai_epi32(out_27_5, DCT_CONST_BITS); - // Combine - out[5] = _mm256_packs_epi32(out_05_6, out_05_7); - out[21] = _mm256_packs_epi32(out_21_6, out_21_7); - out[13] = _mm256_packs_epi32(out_13_6, out_13_7); - out[29] = _mm256_packs_epi32(out_29_6, out_29_7); - out[3] = _mm256_packs_epi32(out_03_6, out_03_7); - out[19] = _mm256_packs_epi32(out_19_6, out_19_7); - out[11] = _mm256_packs_epi32(out_11_6, out_11_7); - out[27] = _mm256_packs_epi32(out_27_6, out_27_7); - } -#if FDCT32x32_HIGH_PRECISION - } else { - __m256i lstep1[64], lstep2[64], lstep3[64]; - __m256i u[32], v[32], sign[16]; - const __m256i K32One = _mm256_set_epi32(1, 1, 1, 1, 1, 1, 1, 1); - const __m256i k__pOne_mOne = pair256_set_epi16(1, -1); - // start using 32-bit operations - // stage 3 - { - // expanding to 32-bit length while adding and subtracting - lstep2[0] = _mm256_unpacklo_epi16(step2[0], step2[7]); - lstep2[1] = _mm256_unpackhi_epi16(step2[0], step2[7]); - lstep2[2] = _mm256_unpacklo_epi16(step2[1], step2[6]); - lstep2[3] = _mm256_unpackhi_epi16(step2[1], step2[6]); - lstep2[4] = _mm256_unpacklo_epi16(step2[2], step2[5]); - lstep2[5] = _mm256_unpackhi_epi16(step2[2], step2[5]); - lstep2[6] = _mm256_unpacklo_epi16(step2[3], step2[4]); - lstep2[7] = _mm256_unpackhi_epi16(step2[3], step2[4]); - - lstep3[0] = _mm256_madd_epi16(lstep2[0], kOne); - lstep3[1] = _mm256_madd_epi16(lstep2[1], kOne); - lstep3[2] = _mm256_madd_epi16(lstep2[2], kOne); - lstep3[3] = _mm256_madd_epi16(lstep2[3], kOne); - lstep3[4] = _mm256_madd_epi16(lstep2[4], kOne); - lstep3[5] = _mm256_madd_epi16(lstep2[5], kOne); - lstep3[6] = _mm256_madd_epi16(lstep2[6], kOne); - lstep3[7] = _mm256_madd_epi16(lstep2[7], kOne); - - lstep3[8] = _mm256_madd_epi16(lstep2[6], k__pOne_mOne); - lstep3[9] = _mm256_madd_epi16(lstep2[7], k__pOne_mOne); - lstep3[10] = _mm256_madd_epi16(lstep2[4], k__pOne_mOne); - lstep3[11] = _mm256_madd_epi16(lstep2[5], k__pOne_mOne); - lstep3[12] = _mm256_madd_epi16(lstep2[2], k__pOne_mOne); - lstep3[13] = _mm256_madd_epi16(lstep2[3], k__pOne_mOne); - lstep3[14] = _mm256_madd_epi16(lstep2[0], k__pOne_mOne); - lstep3[15] = _mm256_madd_epi16(lstep2[1], k__pOne_mOne); - } - { - const __m256i s3_10_0 = _mm256_unpacklo_epi16(step2[13], step2[10]); - const __m256i s3_10_1 = _mm256_unpackhi_epi16(step2[13], step2[10]); - const __m256i s3_11_0 = _mm256_unpacklo_epi16(step2[12], step2[11]); - const __m256i s3_11_1 = _mm256_unpackhi_epi16(step2[12], step2[11]); - const __m256i s3_10_2 = _mm256_madd_epi16(s3_10_0, k__cospi_p16_m16); - const __m256i s3_10_3 = _mm256_madd_epi16(s3_10_1, k__cospi_p16_m16); - const __m256i s3_11_2 = _mm256_madd_epi16(s3_11_0, k__cospi_p16_m16); - const __m256i s3_11_3 = _mm256_madd_epi16(s3_11_1, k__cospi_p16_m16); - const __m256i s3_12_2 = _mm256_madd_epi16(s3_11_0, k__cospi_p16_p16); - const __m256i s3_12_3 = _mm256_madd_epi16(s3_11_1, k__cospi_p16_p16); - const __m256i s3_13_2 = _mm256_madd_epi16(s3_10_0, k__cospi_p16_p16); - const __m256i s3_13_3 = _mm256_madd_epi16(s3_10_1, k__cospi_p16_p16); - // dct_const_round_shift - const __m256i s3_10_4 = - _mm256_add_epi32(s3_10_2, k__DCT_CONST_ROUNDING); - const __m256i s3_10_5 = - _mm256_add_epi32(s3_10_3, k__DCT_CONST_ROUNDING); - const __m256i s3_11_4 = - _mm256_add_epi32(s3_11_2, k__DCT_CONST_ROUNDING); - const __m256i s3_11_5 = - _mm256_add_epi32(s3_11_3, k__DCT_CONST_ROUNDING); - const __m256i s3_12_4 = - _mm256_add_epi32(s3_12_2, k__DCT_CONST_ROUNDING); - const __m256i s3_12_5 = - _mm256_add_epi32(s3_12_3, k__DCT_CONST_ROUNDING); - const __m256i s3_13_4 = - _mm256_add_epi32(s3_13_2, k__DCT_CONST_ROUNDING); - const __m256i s3_13_5 = - _mm256_add_epi32(s3_13_3, k__DCT_CONST_ROUNDING); - lstep3[20] = _mm256_srai_epi32(s3_10_4, DCT_CONST_BITS); - lstep3[21] = _mm256_srai_epi32(s3_10_5, DCT_CONST_BITS); - lstep3[22] = _mm256_srai_epi32(s3_11_4, DCT_CONST_BITS); - lstep3[23] = _mm256_srai_epi32(s3_11_5, DCT_CONST_BITS); - lstep3[24] = _mm256_srai_epi32(s3_12_4, DCT_CONST_BITS); - lstep3[25] = _mm256_srai_epi32(s3_12_5, DCT_CONST_BITS); - lstep3[26] = _mm256_srai_epi32(s3_13_4, DCT_CONST_BITS); - lstep3[27] = _mm256_srai_epi32(s3_13_5, DCT_CONST_BITS); - } - { - lstep1[32] = _mm256_unpacklo_epi16(step1[16], step2[23]); - lstep1[33] = _mm256_unpackhi_epi16(step1[16], step2[23]); - lstep1[34] = _mm256_unpacklo_epi16(step1[17], step2[22]); - lstep1[35] = _mm256_unpackhi_epi16(step1[17], step2[22]); - lstep1[36] = _mm256_unpacklo_epi16(step1[18], step2[21]); - lstep1[37] = _mm256_unpackhi_epi16(step1[18], step2[21]); - lstep1[38] = _mm256_unpacklo_epi16(step1[19], step2[20]); - lstep1[39] = _mm256_unpackhi_epi16(step1[19], step2[20]); - - lstep1[56] = _mm256_unpacklo_epi16(step1[28], step2[27]); - lstep1[57] = _mm256_unpackhi_epi16(step1[28], step2[27]); - lstep1[58] = _mm256_unpacklo_epi16(step1[29], step2[26]); - lstep1[59] = _mm256_unpackhi_epi16(step1[29], step2[26]); - lstep1[60] = _mm256_unpacklo_epi16(step1[30], step2[25]); - lstep1[61] = _mm256_unpackhi_epi16(step1[30], step2[25]); - lstep1[62] = _mm256_unpacklo_epi16(step1[31], step2[24]); - lstep1[63] = _mm256_unpackhi_epi16(step1[31], step2[24]); - - lstep3[32] = _mm256_madd_epi16(lstep1[32], kOne); - lstep3[33] = _mm256_madd_epi16(lstep1[33], kOne); - lstep3[34] = _mm256_madd_epi16(lstep1[34], kOne); - lstep3[35] = _mm256_madd_epi16(lstep1[35], kOne); - lstep3[36] = _mm256_madd_epi16(lstep1[36], kOne); - lstep3[37] = _mm256_madd_epi16(lstep1[37], kOne); - lstep3[38] = _mm256_madd_epi16(lstep1[38], kOne); - lstep3[39] = _mm256_madd_epi16(lstep1[39], kOne); - - lstep3[40] = _mm256_madd_epi16(lstep1[38], k__pOne_mOne); - lstep3[41] = _mm256_madd_epi16(lstep1[39], k__pOne_mOne); - lstep3[42] = _mm256_madd_epi16(lstep1[36], k__pOne_mOne); - lstep3[43] = _mm256_madd_epi16(lstep1[37], k__pOne_mOne); - lstep3[44] = _mm256_madd_epi16(lstep1[34], k__pOne_mOne); - lstep3[45] = _mm256_madd_epi16(lstep1[35], k__pOne_mOne); - lstep3[46] = _mm256_madd_epi16(lstep1[32], k__pOne_mOne); - lstep3[47] = _mm256_madd_epi16(lstep1[33], k__pOne_mOne); - - lstep3[48] = _mm256_madd_epi16(lstep1[62], k__pOne_mOne); - lstep3[49] = _mm256_madd_epi16(lstep1[63], k__pOne_mOne); - lstep3[50] = _mm256_madd_epi16(lstep1[60], k__pOne_mOne); - lstep3[51] = _mm256_madd_epi16(lstep1[61], k__pOne_mOne); - lstep3[52] = _mm256_madd_epi16(lstep1[58], k__pOne_mOne); - lstep3[53] = _mm256_madd_epi16(lstep1[59], k__pOne_mOne); - lstep3[54] = _mm256_madd_epi16(lstep1[56], k__pOne_mOne); - lstep3[55] = _mm256_madd_epi16(lstep1[57], k__pOne_mOne); - - lstep3[56] = _mm256_madd_epi16(lstep1[56], kOne); - lstep3[57] = _mm256_madd_epi16(lstep1[57], kOne); - lstep3[58] = _mm256_madd_epi16(lstep1[58], kOne); - lstep3[59] = _mm256_madd_epi16(lstep1[59], kOne); - lstep3[60] = _mm256_madd_epi16(lstep1[60], kOne); - lstep3[61] = _mm256_madd_epi16(lstep1[61], kOne); - lstep3[62] = _mm256_madd_epi16(lstep1[62], kOne); - lstep3[63] = _mm256_madd_epi16(lstep1[63], kOne); - } - - // stage 4 - { - // expanding to 32-bit length prior to addition operations - sign[0] = _mm256_cmpgt_epi16(kZero, step2[8]); - sign[1] = _mm256_cmpgt_epi16(kZero, step2[9]); - sign[2] = _mm256_cmpgt_epi16(kZero, step2[14]); - sign[3] = _mm256_cmpgt_epi16(kZero, step2[15]); - lstep2[16] = _mm256_unpacklo_epi16(step2[8], sign[0]); - lstep2[17] = _mm256_unpackhi_epi16(step2[8], sign[0]); - lstep2[18] = _mm256_unpacklo_epi16(step2[9], sign[1]); - lstep2[19] = _mm256_unpackhi_epi16(step2[9], sign[1]); - lstep2[28] = _mm256_unpacklo_epi16(step2[14], sign[2]); - lstep2[29] = _mm256_unpackhi_epi16(step2[14], sign[2]); - lstep2[30] = _mm256_unpacklo_epi16(step2[15], sign[3]); - lstep2[31] = _mm256_unpackhi_epi16(step2[15], sign[3]); - - lstep1[0] = _mm256_add_epi32(lstep3[6], lstep3[0]); - lstep1[1] = _mm256_add_epi32(lstep3[7], lstep3[1]); - lstep1[2] = _mm256_add_epi32(lstep3[4], lstep3[2]); - lstep1[3] = _mm256_add_epi32(lstep3[5], lstep3[3]); - lstep1[4] = _mm256_sub_epi32(lstep3[2], lstep3[4]); - lstep1[5] = _mm256_sub_epi32(lstep3[3], lstep3[5]); - lstep1[6] = _mm256_sub_epi32(lstep3[0], lstep3[6]); - lstep1[7] = _mm256_sub_epi32(lstep3[1], lstep3[7]); - lstep1[16] = _mm256_add_epi32(lstep3[22], lstep2[16]); - lstep1[17] = _mm256_add_epi32(lstep3[23], lstep2[17]); - lstep1[18] = _mm256_add_epi32(lstep3[20], lstep2[18]); - lstep1[19] = _mm256_add_epi32(lstep3[21], lstep2[19]); - lstep1[20] = _mm256_sub_epi32(lstep2[18], lstep3[20]); - lstep1[21] = _mm256_sub_epi32(lstep2[19], lstep3[21]); - lstep1[22] = _mm256_sub_epi32(lstep2[16], lstep3[22]); - lstep1[23] = _mm256_sub_epi32(lstep2[17], lstep3[23]); - lstep1[24] = _mm256_sub_epi32(lstep2[30], lstep3[24]); - lstep1[25] = _mm256_sub_epi32(lstep2[31], lstep3[25]); - lstep1[26] = _mm256_sub_epi32(lstep2[28], lstep3[26]); - lstep1[27] = _mm256_sub_epi32(lstep2[29], lstep3[27]); - lstep1[28] = _mm256_add_epi32(lstep3[26], lstep2[28]); - lstep1[29] = _mm256_add_epi32(lstep3[27], lstep2[29]); - lstep1[30] = _mm256_add_epi32(lstep3[24], lstep2[30]); - lstep1[31] = _mm256_add_epi32(lstep3[25], lstep2[31]); - } - { - // to be continued... - // - const __m256i k32_p16_p16 = - pair256_set_epi32(cospi_16_64, cospi_16_64); - const __m256i k32_p16_m16 = - pair256_set_epi32(cospi_16_64, -cospi_16_64); - - u[0] = _mm256_unpacklo_epi32(lstep3[12], lstep3[10]); - u[1] = _mm256_unpackhi_epi32(lstep3[12], lstep3[10]); - u[2] = _mm256_unpacklo_epi32(lstep3[13], lstep3[11]); - u[3] = _mm256_unpackhi_epi32(lstep3[13], lstep3[11]); - - // TODO(jingning): manually inline k_madd_epi32_avx2_ to further hide - // instruction latency. - v[0] = k_madd_epi32_avx2(u[0], k32_p16_m16); - v[1] = k_madd_epi32_avx2(u[1], k32_p16_m16); - v[2] = k_madd_epi32_avx2(u[2], k32_p16_m16); - v[3] = k_madd_epi32_avx2(u[3], k32_p16_m16); - v[4] = k_madd_epi32_avx2(u[0], k32_p16_p16); - v[5] = k_madd_epi32_avx2(u[1], k32_p16_p16); - v[6] = k_madd_epi32_avx2(u[2], k32_p16_p16); - v[7] = k_madd_epi32_avx2(u[3], k32_p16_p16); - - u[0] = k_packs_epi64_avx2(v[0], v[1]); - u[1] = k_packs_epi64_avx2(v[2], v[3]); - u[2] = k_packs_epi64_avx2(v[4], v[5]); - u[3] = k_packs_epi64_avx2(v[6], v[7]); - - v[0] = _mm256_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm256_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm256_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm256_add_epi32(u[3], k__DCT_CONST_ROUNDING); - - lstep1[10] = _mm256_srai_epi32(v[0], DCT_CONST_BITS); - lstep1[11] = _mm256_srai_epi32(v[1], DCT_CONST_BITS); - lstep1[12] = _mm256_srai_epi32(v[2], DCT_CONST_BITS); - lstep1[13] = _mm256_srai_epi32(v[3], DCT_CONST_BITS); - } - { - const __m256i k32_m08_p24 = - pair256_set_epi32(-cospi_8_64, cospi_24_64); - const __m256i k32_m24_m08 = - pair256_set_epi32(-cospi_24_64, -cospi_8_64); - const __m256i k32_p24_p08 = - pair256_set_epi32(cospi_24_64, cospi_8_64); - - u[0] = _mm256_unpacklo_epi32(lstep3[36], lstep3[58]); - u[1] = _mm256_unpackhi_epi32(lstep3[36], lstep3[58]); - u[2] = _mm256_unpacklo_epi32(lstep3[37], lstep3[59]); - u[3] = _mm256_unpackhi_epi32(lstep3[37], lstep3[59]); - u[4] = _mm256_unpacklo_epi32(lstep3[38], lstep3[56]); - u[5] = _mm256_unpackhi_epi32(lstep3[38], lstep3[56]); - u[6] = _mm256_unpacklo_epi32(lstep3[39], lstep3[57]); - u[7] = _mm256_unpackhi_epi32(lstep3[39], lstep3[57]); - u[8] = _mm256_unpacklo_epi32(lstep3[40], lstep3[54]); - u[9] = _mm256_unpackhi_epi32(lstep3[40], lstep3[54]); - u[10] = _mm256_unpacklo_epi32(lstep3[41], lstep3[55]); - u[11] = _mm256_unpackhi_epi32(lstep3[41], lstep3[55]); - u[12] = _mm256_unpacklo_epi32(lstep3[42], lstep3[52]); - u[13] = _mm256_unpackhi_epi32(lstep3[42], lstep3[52]); - u[14] = _mm256_unpacklo_epi32(lstep3[43], lstep3[53]); - u[15] = _mm256_unpackhi_epi32(lstep3[43], lstep3[53]); - - v[0] = k_madd_epi32_avx2(u[0], k32_m08_p24); - v[1] = k_madd_epi32_avx2(u[1], k32_m08_p24); - v[2] = k_madd_epi32_avx2(u[2], k32_m08_p24); - v[3] = k_madd_epi32_avx2(u[3], k32_m08_p24); - v[4] = k_madd_epi32_avx2(u[4], k32_m08_p24); - v[5] = k_madd_epi32_avx2(u[5], k32_m08_p24); - v[6] = k_madd_epi32_avx2(u[6], k32_m08_p24); - v[7] = k_madd_epi32_avx2(u[7], k32_m08_p24); - v[8] = k_madd_epi32_avx2(u[8], k32_m24_m08); - v[9] = k_madd_epi32_avx2(u[9], k32_m24_m08); - v[10] = k_madd_epi32_avx2(u[10], k32_m24_m08); - v[11] = k_madd_epi32_avx2(u[11], k32_m24_m08); - v[12] = k_madd_epi32_avx2(u[12], k32_m24_m08); - v[13] = k_madd_epi32_avx2(u[13], k32_m24_m08); - v[14] = k_madd_epi32_avx2(u[14], k32_m24_m08); - v[15] = k_madd_epi32_avx2(u[15], k32_m24_m08); - v[16] = k_madd_epi32_avx2(u[12], k32_m08_p24); - v[17] = k_madd_epi32_avx2(u[13], k32_m08_p24); - v[18] = k_madd_epi32_avx2(u[14], k32_m08_p24); - v[19] = k_madd_epi32_avx2(u[15], k32_m08_p24); - v[20] = k_madd_epi32_avx2(u[8], k32_m08_p24); - v[21] = k_madd_epi32_avx2(u[9], k32_m08_p24); - v[22] = k_madd_epi32_avx2(u[10], k32_m08_p24); - v[23] = k_madd_epi32_avx2(u[11], k32_m08_p24); - v[24] = k_madd_epi32_avx2(u[4], k32_p24_p08); - v[25] = k_madd_epi32_avx2(u[5], k32_p24_p08); - v[26] = k_madd_epi32_avx2(u[6], k32_p24_p08); - v[27] = k_madd_epi32_avx2(u[7], k32_p24_p08); - v[28] = k_madd_epi32_avx2(u[0], k32_p24_p08); - v[29] = k_madd_epi32_avx2(u[1], k32_p24_p08); - v[30] = k_madd_epi32_avx2(u[2], k32_p24_p08); - v[31] = k_madd_epi32_avx2(u[3], k32_p24_p08); - - u[0] = k_packs_epi64_avx2(v[0], v[1]); - u[1] = k_packs_epi64_avx2(v[2], v[3]); - u[2] = k_packs_epi64_avx2(v[4], v[5]); - u[3] = k_packs_epi64_avx2(v[6], v[7]); - u[4] = k_packs_epi64_avx2(v[8], v[9]); - u[5] = k_packs_epi64_avx2(v[10], v[11]); - u[6] = k_packs_epi64_avx2(v[12], v[13]); - u[7] = k_packs_epi64_avx2(v[14], v[15]); - u[8] = k_packs_epi64_avx2(v[16], v[17]); - u[9] = k_packs_epi64_avx2(v[18], v[19]); - u[10] = k_packs_epi64_avx2(v[20], v[21]); - u[11] = k_packs_epi64_avx2(v[22], v[23]); - u[12] = k_packs_epi64_avx2(v[24], v[25]); - u[13] = k_packs_epi64_avx2(v[26], v[27]); - u[14] = k_packs_epi64_avx2(v[28], v[29]); - u[15] = k_packs_epi64_avx2(v[30], v[31]); - - v[0] = _mm256_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm256_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm256_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm256_add_epi32(u[3], k__DCT_CONST_ROUNDING); - v[4] = _mm256_add_epi32(u[4], k__DCT_CONST_ROUNDING); - v[5] = _mm256_add_epi32(u[5], k__DCT_CONST_ROUNDING); - v[6] = _mm256_add_epi32(u[6], k__DCT_CONST_ROUNDING); - v[7] = _mm256_add_epi32(u[7], k__DCT_CONST_ROUNDING); - v[8] = _mm256_add_epi32(u[8], k__DCT_CONST_ROUNDING); - v[9] = _mm256_add_epi32(u[9], k__DCT_CONST_ROUNDING); - v[10] = _mm256_add_epi32(u[10], k__DCT_CONST_ROUNDING); - v[11] = _mm256_add_epi32(u[11], k__DCT_CONST_ROUNDING); - v[12] = _mm256_add_epi32(u[12], k__DCT_CONST_ROUNDING); - v[13] = _mm256_add_epi32(u[13], k__DCT_CONST_ROUNDING); - v[14] = _mm256_add_epi32(u[14], k__DCT_CONST_ROUNDING); - v[15] = _mm256_add_epi32(u[15], k__DCT_CONST_ROUNDING); - - lstep1[36] = _mm256_srai_epi32(v[0], DCT_CONST_BITS); - lstep1[37] = _mm256_srai_epi32(v[1], DCT_CONST_BITS); - lstep1[38] = _mm256_srai_epi32(v[2], DCT_CONST_BITS); - lstep1[39] = _mm256_srai_epi32(v[3], DCT_CONST_BITS); - lstep1[40] = _mm256_srai_epi32(v[4], DCT_CONST_BITS); - lstep1[41] = _mm256_srai_epi32(v[5], DCT_CONST_BITS); - lstep1[42] = _mm256_srai_epi32(v[6], DCT_CONST_BITS); - lstep1[43] = _mm256_srai_epi32(v[7], DCT_CONST_BITS); - lstep1[52] = _mm256_srai_epi32(v[8], DCT_CONST_BITS); - lstep1[53] = _mm256_srai_epi32(v[9], DCT_CONST_BITS); - lstep1[54] = _mm256_srai_epi32(v[10], DCT_CONST_BITS); - lstep1[55] = _mm256_srai_epi32(v[11], DCT_CONST_BITS); - lstep1[56] = _mm256_srai_epi32(v[12], DCT_CONST_BITS); - lstep1[57] = _mm256_srai_epi32(v[13], DCT_CONST_BITS); - lstep1[58] = _mm256_srai_epi32(v[14], DCT_CONST_BITS); - lstep1[59] = _mm256_srai_epi32(v[15], DCT_CONST_BITS); - } - // stage 5 - { - lstep2[8] = _mm256_add_epi32(lstep1[10], lstep3[8]); - lstep2[9] = _mm256_add_epi32(lstep1[11], lstep3[9]); - lstep2[10] = _mm256_sub_epi32(lstep3[8], lstep1[10]); - lstep2[11] = _mm256_sub_epi32(lstep3[9], lstep1[11]); - lstep2[12] = _mm256_sub_epi32(lstep3[14], lstep1[12]); - lstep2[13] = _mm256_sub_epi32(lstep3[15], lstep1[13]); - lstep2[14] = _mm256_add_epi32(lstep1[12], lstep3[14]); - lstep2[15] = _mm256_add_epi32(lstep1[13], lstep3[15]); - } - { - const __m256i k32_p16_p16 = - pair256_set_epi32(cospi_16_64, cospi_16_64); - const __m256i k32_p16_m16 = - pair256_set_epi32(cospi_16_64, -cospi_16_64); - const __m256i k32_p24_p08 = - pair256_set_epi32(cospi_24_64, cospi_8_64); - const __m256i k32_m08_p24 = - pair256_set_epi32(-cospi_8_64, cospi_24_64); - - u[0] = _mm256_unpacklo_epi32(lstep1[0], lstep1[2]); - u[1] = _mm256_unpackhi_epi32(lstep1[0], lstep1[2]); - u[2] = _mm256_unpacklo_epi32(lstep1[1], lstep1[3]); - u[3] = _mm256_unpackhi_epi32(lstep1[1], lstep1[3]); - u[4] = _mm256_unpacklo_epi32(lstep1[4], lstep1[6]); - u[5] = _mm256_unpackhi_epi32(lstep1[4], lstep1[6]); - u[6] = _mm256_unpacklo_epi32(lstep1[5], lstep1[7]); - u[7] = _mm256_unpackhi_epi32(lstep1[5], lstep1[7]); - - // TODO(jingning): manually inline k_madd_epi32_avx2_ to further hide - // instruction latency. - v[0] = k_madd_epi32_avx2(u[0], k32_p16_p16); - v[1] = k_madd_epi32_avx2(u[1], k32_p16_p16); - v[2] = k_madd_epi32_avx2(u[2], k32_p16_p16); - v[3] = k_madd_epi32_avx2(u[3], k32_p16_p16); - v[4] = k_madd_epi32_avx2(u[0], k32_p16_m16); - v[5] = k_madd_epi32_avx2(u[1], k32_p16_m16); - v[6] = k_madd_epi32_avx2(u[2], k32_p16_m16); - v[7] = k_madd_epi32_avx2(u[3], k32_p16_m16); - v[8] = k_madd_epi32_avx2(u[4], k32_p24_p08); - v[9] = k_madd_epi32_avx2(u[5], k32_p24_p08); - v[10] = k_madd_epi32_avx2(u[6], k32_p24_p08); - v[11] = k_madd_epi32_avx2(u[7], k32_p24_p08); - v[12] = k_madd_epi32_avx2(u[4], k32_m08_p24); - v[13] = k_madd_epi32_avx2(u[5], k32_m08_p24); - v[14] = k_madd_epi32_avx2(u[6], k32_m08_p24); - v[15] = k_madd_epi32_avx2(u[7], k32_m08_p24); - - u[0] = k_packs_epi64_avx2(v[0], v[1]); - u[1] = k_packs_epi64_avx2(v[2], v[3]); - u[2] = k_packs_epi64_avx2(v[4], v[5]); - u[3] = k_packs_epi64_avx2(v[6], v[7]); - u[4] = k_packs_epi64_avx2(v[8], v[9]); - u[5] = k_packs_epi64_avx2(v[10], v[11]); - u[6] = k_packs_epi64_avx2(v[12], v[13]); - u[7] = k_packs_epi64_avx2(v[14], v[15]); - - v[0] = _mm256_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm256_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm256_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm256_add_epi32(u[3], k__DCT_CONST_ROUNDING); - v[4] = _mm256_add_epi32(u[4], k__DCT_CONST_ROUNDING); - v[5] = _mm256_add_epi32(u[5], k__DCT_CONST_ROUNDING); - v[6] = _mm256_add_epi32(u[6], k__DCT_CONST_ROUNDING); - v[7] = _mm256_add_epi32(u[7], k__DCT_CONST_ROUNDING); - - u[0] = _mm256_srai_epi32(v[0], DCT_CONST_BITS); - u[1] = _mm256_srai_epi32(v[1], DCT_CONST_BITS); - u[2] = _mm256_srai_epi32(v[2], DCT_CONST_BITS); - u[3] = _mm256_srai_epi32(v[3], DCT_CONST_BITS); - u[4] = _mm256_srai_epi32(v[4], DCT_CONST_BITS); - u[5] = _mm256_srai_epi32(v[5], DCT_CONST_BITS); - u[6] = _mm256_srai_epi32(v[6], DCT_CONST_BITS); - u[7] = _mm256_srai_epi32(v[7], DCT_CONST_BITS); - - sign[0] = _mm256_cmpgt_epi32(kZero, u[0]); - sign[1] = _mm256_cmpgt_epi32(kZero, u[1]); - sign[2] = _mm256_cmpgt_epi32(kZero, u[2]); - sign[3] = _mm256_cmpgt_epi32(kZero, u[3]); - sign[4] = _mm256_cmpgt_epi32(kZero, u[4]); - sign[5] = _mm256_cmpgt_epi32(kZero, u[5]); - sign[6] = _mm256_cmpgt_epi32(kZero, u[6]); - sign[7] = _mm256_cmpgt_epi32(kZero, u[7]); - - u[0] = _mm256_sub_epi32(u[0], sign[0]); - u[1] = _mm256_sub_epi32(u[1], sign[1]); - u[2] = _mm256_sub_epi32(u[2], sign[2]); - u[3] = _mm256_sub_epi32(u[3], sign[3]); - u[4] = _mm256_sub_epi32(u[4], sign[4]); - u[5] = _mm256_sub_epi32(u[5], sign[5]); - u[6] = _mm256_sub_epi32(u[6], sign[6]); - u[7] = _mm256_sub_epi32(u[7], sign[7]); - - u[0] = _mm256_add_epi32(u[0], K32One); - u[1] = _mm256_add_epi32(u[1], K32One); - u[2] = _mm256_add_epi32(u[2], K32One); - u[3] = _mm256_add_epi32(u[3], K32One); - u[4] = _mm256_add_epi32(u[4], K32One); - u[5] = _mm256_add_epi32(u[5], K32One); - u[6] = _mm256_add_epi32(u[6], K32One); - u[7] = _mm256_add_epi32(u[7], K32One); - - u[0] = _mm256_srai_epi32(u[0], 2); - u[1] = _mm256_srai_epi32(u[1], 2); - u[2] = _mm256_srai_epi32(u[2], 2); - u[3] = _mm256_srai_epi32(u[3], 2); - u[4] = _mm256_srai_epi32(u[4], 2); - u[5] = _mm256_srai_epi32(u[5], 2); - u[6] = _mm256_srai_epi32(u[6], 2); - u[7] = _mm256_srai_epi32(u[7], 2); - - // Combine - out[0] = _mm256_packs_epi32(u[0], u[1]); - out[16] = _mm256_packs_epi32(u[2], u[3]); - out[8] = _mm256_packs_epi32(u[4], u[5]); - out[24] = _mm256_packs_epi32(u[6], u[7]); - } - { - const __m256i k32_m08_p24 = - pair256_set_epi32(-cospi_8_64, cospi_24_64); - const __m256i k32_m24_m08 = - pair256_set_epi32(-cospi_24_64, -cospi_8_64); - const __m256i k32_p24_p08 = - pair256_set_epi32(cospi_24_64, cospi_8_64); - - u[0] = _mm256_unpacklo_epi32(lstep1[18], lstep1[28]); - u[1] = _mm256_unpackhi_epi32(lstep1[18], lstep1[28]); - u[2] = _mm256_unpacklo_epi32(lstep1[19], lstep1[29]); - u[3] = _mm256_unpackhi_epi32(lstep1[19], lstep1[29]); - u[4] = _mm256_unpacklo_epi32(lstep1[20], lstep1[26]); - u[5] = _mm256_unpackhi_epi32(lstep1[20], lstep1[26]); - u[6] = _mm256_unpacklo_epi32(lstep1[21], lstep1[27]); - u[7] = _mm256_unpackhi_epi32(lstep1[21], lstep1[27]); - - v[0] = k_madd_epi32_avx2(u[0], k32_m08_p24); - v[1] = k_madd_epi32_avx2(u[1], k32_m08_p24); - v[2] = k_madd_epi32_avx2(u[2], k32_m08_p24); - v[3] = k_madd_epi32_avx2(u[3], k32_m08_p24); - v[4] = k_madd_epi32_avx2(u[4], k32_m24_m08); - v[5] = k_madd_epi32_avx2(u[5], k32_m24_m08); - v[6] = k_madd_epi32_avx2(u[6], k32_m24_m08); - v[7] = k_madd_epi32_avx2(u[7], k32_m24_m08); - v[8] = k_madd_epi32_avx2(u[4], k32_m08_p24); - v[9] = k_madd_epi32_avx2(u[5], k32_m08_p24); - v[10] = k_madd_epi32_avx2(u[6], k32_m08_p24); - v[11] = k_madd_epi32_avx2(u[7], k32_m08_p24); - v[12] = k_madd_epi32_avx2(u[0], k32_p24_p08); - v[13] = k_madd_epi32_avx2(u[1], k32_p24_p08); - v[14] = k_madd_epi32_avx2(u[2], k32_p24_p08); - v[15] = k_madd_epi32_avx2(u[3], k32_p24_p08); - - u[0] = k_packs_epi64_avx2(v[0], v[1]); - u[1] = k_packs_epi64_avx2(v[2], v[3]); - u[2] = k_packs_epi64_avx2(v[4], v[5]); - u[3] = k_packs_epi64_avx2(v[6], v[7]); - u[4] = k_packs_epi64_avx2(v[8], v[9]); - u[5] = k_packs_epi64_avx2(v[10], v[11]); - u[6] = k_packs_epi64_avx2(v[12], v[13]); - u[7] = k_packs_epi64_avx2(v[14], v[15]); - - u[0] = _mm256_add_epi32(u[0], k__DCT_CONST_ROUNDING); - u[1] = _mm256_add_epi32(u[1], k__DCT_CONST_ROUNDING); - u[2] = _mm256_add_epi32(u[2], k__DCT_CONST_ROUNDING); - u[3] = _mm256_add_epi32(u[3], k__DCT_CONST_ROUNDING); - u[4] = _mm256_add_epi32(u[4], k__DCT_CONST_ROUNDING); - u[5] = _mm256_add_epi32(u[5], k__DCT_CONST_ROUNDING); - u[6] = _mm256_add_epi32(u[6], k__DCT_CONST_ROUNDING); - u[7] = _mm256_add_epi32(u[7], k__DCT_CONST_ROUNDING); - - lstep2[18] = _mm256_srai_epi32(u[0], DCT_CONST_BITS); - lstep2[19] = _mm256_srai_epi32(u[1], DCT_CONST_BITS); - lstep2[20] = _mm256_srai_epi32(u[2], DCT_CONST_BITS); - lstep2[21] = _mm256_srai_epi32(u[3], DCT_CONST_BITS); - lstep2[26] = _mm256_srai_epi32(u[4], DCT_CONST_BITS); - lstep2[27] = _mm256_srai_epi32(u[5], DCT_CONST_BITS); - lstep2[28] = _mm256_srai_epi32(u[6], DCT_CONST_BITS); - lstep2[29] = _mm256_srai_epi32(u[7], DCT_CONST_BITS); - } - { - lstep2[32] = _mm256_add_epi32(lstep1[38], lstep3[32]); - lstep2[33] = _mm256_add_epi32(lstep1[39], lstep3[33]); - lstep2[34] = _mm256_add_epi32(lstep1[36], lstep3[34]); - lstep2[35] = _mm256_add_epi32(lstep1[37], lstep3[35]); - lstep2[36] = _mm256_sub_epi32(lstep3[34], lstep1[36]); - lstep2[37] = _mm256_sub_epi32(lstep3[35], lstep1[37]); - lstep2[38] = _mm256_sub_epi32(lstep3[32], lstep1[38]); - lstep2[39] = _mm256_sub_epi32(lstep3[33], lstep1[39]); - lstep2[40] = _mm256_sub_epi32(lstep3[46], lstep1[40]); - lstep2[41] = _mm256_sub_epi32(lstep3[47], lstep1[41]); - lstep2[42] = _mm256_sub_epi32(lstep3[44], lstep1[42]); - lstep2[43] = _mm256_sub_epi32(lstep3[45], lstep1[43]); - lstep2[44] = _mm256_add_epi32(lstep1[42], lstep3[44]); - lstep2[45] = _mm256_add_epi32(lstep1[43], lstep3[45]); - lstep2[46] = _mm256_add_epi32(lstep1[40], lstep3[46]); - lstep2[47] = _mm256_add_epi32(lstep1[41], lstep3[47]); - lstep2[48] = _mm256_add_epi32(lstep1[54], lstep3[48]); - lstep2[49] = _mm256_add_epi32(lstep1[55], lstep3[49]); - lstep2[50] = _mm256_add_epi32(lstep1[52], lstep3[50]); - lstep2[51] = _mm256_add_epi32(lstep1[53], lstep3[51]); - lstep2[52] = _mm256_sub_epi32(lstep3[50], lstep1[52]); - lstep2[53] = _mm256_sub_epi32(lstep3[51], lstep1[53]); - lstep2[54] = _mm256_sub_epi32(lstep3[48], lstep1[54]); - lstep2[55] = _mm256_sub_epi32(lstep3[49], lstep1[55]); - lstep2[56] = _mm256_sub_epi32(lstep3[62], lstep1[56]); - lstep2[57] = _mm256_sub_epi32(lstep3[63], lstep1[57]); - lstep2[58] = _mm256_sub_epi32(lstep3[60], lstep1[58]); - lstep2[59] = _mm256_sub_epi32(lstep3[61], lstep1[59]); - lstep2[60] = _mm256_add_epi32(lstep1[58], lstep3[60]); - lstep2[61] = _mm256_add_epi32(lstep1[59], lstep3[61]); - lstep2[62] = _mm256_add_epi32(lstep1[56], lstep3[62]); - lstep2[63] = _mm256_add_epi32(lstep1[57], lstep3[63]); - } - // stage 6 - { - const __m256i k32_p28_p04 = - pair256_set_epi32(cospi_28_64, cospi_4_64); - const __m256i k32_p12_p20 = - pair256_set_epi32(cospi_12_64, cospi_20_64); - const __m256i k32_m20_p12 = - pair256_set_epi32(-cospi_20_64, cospi_12_64); - const __m256i k32_m04_p28 = - pair256_set_epi32(-cospi_4_64, cospi_28_64); - - u[0] = _mm256_unpacklo_epi32(lstep2[8], lstep2[14]); - u[1] = _mm256_unpackhi_epi32(lstep2[8], lstep2[14]); - u[2] = _mm256_unpacklo_epi32(lstep2[9], lstep2[15]); - u[3] = _mm256_unpackhi_epi32(lstep2[9], lstep2[15]); - u[4] = _mm256_unpacklo_epi32(lstep2[10], lstep2[12]); - u[5] = _mm256_unpackhi_epi32(lstep2[10], lstep2[12]); - u[6] = _mm256_unpacklo_epi32(lstep2[11], lstep2[13]); - u[7] = _mm256_unpackhi_epi32(lstep2[11], lstep2[13]); - u[8] = _mm256_unpacklo_epi32(lstep2[10], lstep2[12]); - u[9] = _mm256_unpackhi_epi32(lstep2[10], lstep2[12]); - u[10] = _mm256_unpacklo_epi32(lstep2[11], lstep2[13]); - u[11] = _mm256_unpackhi_epi32(lstep2[11], lstep2[13]); - u[12] = _mm256_unpacklo_epi32(lstep2[8], lstep2[14]); - u[13] = _mm256_unpackhi_epi32(lstep2[8], lstep2[14]); - u[14] = _mm256_unpacklo_epi32(lstep2[9], lstep2[15]); - u[15] = _mm256_unpackhi_epi32(lstep2[9], lstep2[15]); - - v[0] = k_madd_epi32_avx2(u[0], k32_p28_p04); - v[1] = k_madd_epi32_avx2(u[1], k32_p28_p04); - v[2] = k_madd_epi32_avx2(u[2], k32_p28_p04); - v[3] = k_madd_epi32_avx2(u[3], k32_p28_p04); - v[4] = k_madd_epi32_avx2(u[4], k32_p12_p20); - v[5] = k_madd_epi32_avx2(u[5], k32_p12_p20); - v[6] = k_madd_epi32_avx2(u[6], k32_p12_p20); - v[7] = k_madd_epi32_avx2(u[7], k32_p12_p20); - v[8] = k_madd_epi32_avx2(u[8], k32_m20_p12); - v[9] = k_madd_epi32_avx2(u[9], k32_m20_p12); - v[10] = k_madd_epi32_avx2(u[10], k32_m20_p12); - v[11] = k_madd_epi32_avx2(u[11], k32_m20_p12); - v[12] = k_madd_epi32_avx2(u[12], k32_m04_p28); - v[13] = k_madd_epi32_avx2(u[13], k32_m04_p28); - v[14] = k_madd_epi32_avx2(u[14], k32_m04_p28); - v[15] = k_madd_epi32_avx2(u[15], k32_m04_p28); - - u[0] = k_packs_epi64_avx2(v[0], v[1]); - u[1] = k_packs_epi64_avx2(v[2], v[3]); - u[2] = k_packs_epi64_avx2(v[4], v[5]); - u[3] = k_packs_epi64_avx2(v[6], v[7]); - u[4] = k_packs_epi64_avx2(v[8], v[9]); - u[5] = k_packs_epi64_avx2(v[10], v[11]); - u[6] = k_packs_epi64_avx2(v[12], v[13]); - u[7] = k_packs_epi64_avx2(v[14], v[15]); - - v[0] = _mm256_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm256_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm256_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm256_add_epi32(u[3], k__DCT_CONST_ROUNDING); - v[4] = _mm256_add_epi32(u[4], k__DCT_CONST_ROUNDING); - v[5] = _mm256_add_epi32(u[5], k__DCT_CONST_ROUNDING); - v[6] = _mm256_add_epi32(u[6], k__DCT_CONST_ROUNDING); - v[7] = _mm256_add_epi32(u[7], k__DCT_CONST_ROUNDING); - - u[0] = _mm256_srai_epi32(v[0], DCT_CONST_BITS); - u[1] = _mm256_srai_epi32(v[1], DCT_CONST_BITS); - u[2] = _mm256_srai_epi32(v[2], DCT_CONST_BITS); - u[3] = _mm256_srai_epi32(v[3], DCT_CONST_BITS); - u[4] = _mm256_srai_epi32(v[4], DCT_CONST_BITS); - u[5] = _mm256_srai_epi32(v[5], DCT_CONST_BITS); - u[6] = _mm256_srai_epi32(v[6], DCT_CONST_BITS); - u[7] = _mm256_srai_epi32(v[7], DCT_CONST_BITS); - - sign[0] = _mm256_cmpgt_epi32(kZero, u[0]); - sign[1] = _mm256_cmpgt_epi32(kZero, u[1]); - sign[2] = _mm256_cmpgt_epi32(kZero, u[2]); - sign[3] = _mm256_cmpgt_epi32(kZero, u[3]); - sign[4] = _mm256_cmpgt_epi32(kZero, u[4]); - sign[5] = _mm256_cmpgt_epi32(kZero, u[5]); - sign[6] = _mm256_cmpgt_epi32(kZero, u[6]); - sign[7] = _mm256_cmpgt_epi32(kZero, u[7]); - - u[0] = _mm256_sub_epi32(u[0], sign[0]); - u[1] = _mm256_sub_epi32(u[1], sign[1]); - u[2] = _mm256_sub_epi32(u[2], sign[2]); - u[3] = _mm256_sub_epi32(u[3], sign[3]); - u[4] = _mm256_sub_epi32(u[4], sign[4]); - u[5] = _mm256_sub_epi32(u[5], sign[5]); - u[6] = _mm256_sub_epi32(u[6], sign[6]); - u[7] = _mm256_sub_epi32(u[7], sign[7]); - - u[0] = _mm256_add_epi32(u[0], K32One); - u[1] = _mm256_add_epi32(u[1], K32One); - u[2] = _mm256_add_epi32(u[2], K32One); - u[3] = _mm256_add_epi32(u[3], K32One); - u[4] = _mm256_add_epi32(u[4], K32One); - u[5] = _mm256_add_epi32(u[5], K32One); - u[6] = _mm256_add_epi32(u[6], K32One); - u[7] = _mm256_add_epi32(u[7], K32One); - - u[0] = _mm256_srai_epi32(u[0], 2); - u[1] = _mm256_srai_epi32(u[1], 2); - u[2] = _mm256_srai_epi32(u[2], 2); - u[3] = _mm256_srai_epi32(u[3], 2); - u[4] = _mm256_srai_epi32(u[4], 2); - u[5] = _mm256_srai_epi32(u[5], 2); - u[6] = _mm256_srai_epi32(u[6], 2); - u[7] = _mm256_srai_epi32(u[7], 2); - - out[4] = _mm256_packs_epi32(u[0], u[1]); - out[20] = _mm256_packs_epi32(u[2], u[3]); - out[12] = _mm256_packs_epi32(u[4], u[5]); - out[28] = _mm256_packs_epi32(u[6], u[7]); - } - { - lstep3[16] = _mm256_add_epi32(lstep2[18], lstep1[16]); - lstep3[17] = _mm256_add_epi32(lstep2[19], lstep1[17]); - lstep3[18] = _mm256_sub_epi32(lstep1[16], lstep2[18]); - lstep3[19] = _mm256_sub_epi32(lstep1[17], lstep2[19]); - lstep3[20] = _mm256_sub_epi32(lstep1[22], lstep2[20]); - lstep3[21] = _mm256_sub_epi32(lstep1[23], lstep2[21]); - lstep3[22] = _mm256_add_epi32(lstep2[20], lstep1[22]); - lstep3[23] = _mm256_add_epi32(lstep2[21], lstep1[23]); - lstep3[24] = _mm256_add_epi32(lstep2[26], lstep1[24]); - lstep3[25] = _mm256_add_epi32(lstep2[27], lstep1[25]); - lstep3[26] = _mm256_sub_epi32(lstep1[24], lstep2[26]); - lstep3[27] = _mm256_sub_epi32(lstep1[25], lstep2[27]); - lstep3[28] = _mm256_sub_epi32(lstep1[30], lstep2[28]); - lstep3[29] = _mm256_sub_epi32(lstep1[31], lstep2[29]); - lstep3[30] = _mm256_add_epi32(lstep2[28], lstep1[30]); - lstep3[31] = _mm256_add_epi32(lstep2[29], lstep1[31]); - } - { - const __m256i k32_m04_p28 = - pair256_set_epi32(-cospi_4_64, cospi_28_64); - const __m256i k32_m28_m04 = - pair256_set_epi32(-cospi_28_64, -cospi_4_64); - const __m256i k32_m20_p12 = - pair256_set_epi32(-cospi_20_64, cospi_12_64); - const __m256i k32_m12_m20 = - pair256_set_epi32(-cospi_12_64, -cospi_20_64); - const __m256i k32_p12_p20 = - pair256_set_epi32(cospi_12_64, cospi_20_64); - const __m256i k32_p28_p04 = - pair256_set_epi32(cospi_28_64, cospi_4_64); - - u[0] = _mm256_unpacklo_epi32(lstep2[34], lstep2[60]); - u[1] = _mm256_unpackhi_epi32(lstep2[34], lstep2[60]); - u[2] = _mm256_unpacklo_epi32(lstep2[35], lstep2[61]); - u[3] = _mm256_unpackhi_epi32(lstep2[35], lstep2[61]); - u[4] = _mm256_unpacklo_epi32(lstep2[36], lstep2[58]); - u[5] = _mm256_unpackhi_epi32(lstep2[36], lstep2[58]); - u[6] = _mm256_unpacklo_epi32(lstep2[37], lstep2[59]); - u[7] = _mm256_unpackhi_epi32(lstep2[37], lstep2[59]); - u[8] = _mm256_unpacklo_epi32(lstep2[42], lstep2[52]); - u[9] = _mm256_unpackhi_epi32(lstep2[42], lstep2[52]); - u[10] = _mm256_unpacklo_epi32(lstep2[43], lstep2[53]); - u[11] = _mm256_unpackhi_epi32(lstep2[43], lstep2[53]); - u[12] = _mm256_unpacklo_epi32(lstep2[44], lstep2[50]); - u[13] = _mm256_unpackhi_epi32(lstep2[44], lstep2[50]); - u[14] = _mm256_unpacklo_epi32(lstep2[45], lstep2[51]); - u[15] = _mm256_unpackhi_epi32(lstep2[45], lstep2[51]); - - v[0] = k_madd_epi32_avx2(u[0], k32_m04_p28); - v[1] = k_madd_epi32_avx2(u[1], k32_m04_p28); - v[2] = k_madd_epi32_avx2(u[2], k32_m04_p28); - v[3] = k_madd_epi32_avx2(u[3], k32_m04_p28); - v[4] = k_madd_epi32_avx2(u[4], k32_m28_m04); - v[5] = k_madd_epi32_avx2(u[5], k32_m28_m04); - v[6] = k_madd_epi32_avx2(u[6], k32_m28_m04); - v[7] = k_madd_epi32_avx2(u[7], k32_m28_m04); - v[8] = k_madd_epi32_avx2(u[8], k32_m20_p12); - v[9] = k_madd_epi32_avx2(u[9], k32_m20_p12); - v[10] = k_madd_epi32_avx2(u[10], k32_m20_p12); - v[11] = k_madd_epi32_avx2(u[11], k32_m20_p12); - v[12] = k_madd_epi32_avx2(u[12], k32_m12_m20); - v[13] = k_madd_epi32_avx2(u[13], k32_m12_m20); - v[14] = k_madd_epi32_avx2(u[14], k32_m12_m20); - v[15] = k_madd_epi32_avx2(u[15], k32_m12_m20); - v[16] = k_madd_epi32_avx2(u[12], k32_m20_p12); - v[17] = k_madd_epi32_avx2(u[13], k32_m20_p12); - v[18] = k_madd_epi32_avx2(u[14], k32_m20_p12); - v[19] = k_madd_epi32_avx2(u[15], k32_m20_p12); - v[20] = k_madd_epi32_avx2(u[8], k32_p12_p20); - v[21] = k_madd_epi32_avx2(u[9], k32_p12_p20); - v[22] = k_madd_epi32_avx2(u[10], k32_p12_p20); - v[23] = k_madd_epi32_avx2(u[11], k32_p12_p20); - v[24] = k_madd_epi32_avx2(u[4], k32_m04_p28); - v[25] = k_madd_epi32_avx2(u[5], k32_m04_p28); - v[26] = k_madd_epi32_avx2(u[6], k32_m04_p28); - v[27] = k_madd_epi32_avx2(u[7], k32_m04_p28); - v[28] = k_madd_epi32_avx2(u[0], k32_p28_p04); - v[29] = k_madd_epi32_avx2(u[1], k32_p28_p04); - v[30] = k_madd_epi32_avx2(u[2], k32_p28_p04); - v[31] = k_madd_epi32_avx2(u[3], k32_p28_p04); - - u[0] = k_packs_epi64_avx2(v[0], v[1]); - u[1] = k_packs_epi64_avx2(v[2], v[3]); - u[2] = k_packs_epi64_avx2(v[4], v[5]); - u[3] = k_packs_epi64_avx2(v[6], v[7]); - u[4] = k_packs_epi64_avx2(v[8], v[9]); - u[5] = k_packs_epi64_avx2(v[10], v[11]); - u[6] = k_packs_epi64_avx2(v[12], v[13]); - u[7] = k_packs_epi64_avx2(v[14], v[15]); - u[8] = k_packs_epi64_avx2(v[16], v[17]); - u[9] = k_packs_epi64_avx2(v[18], v[19]); - u[10] = k_packs_epi64_avx2(v[20], v[21]); - u[11] = k_packs_epi64_avx2(v[22], v[23]); - u[12] = k_packs_epi64_avx2(v[24], v[25]); - u[13] = k_packs_epi64_avx2(v[26], v[27]); - u[14] = k_packs_epi64_avx2(v[28], v[29]); - u[15] = k_packs_epi64_avx2(v[30], v[31]); - - v[0] = _mm256_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm256_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm256_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm256_add_epi32(u[3], k__DCT_CONST_ROUNDING); - v[4] = _mm256_add_epi32(u[4], k__DCT_CONST_ROUNDING); - v[5] = _mm256_add_epi32(u[5], k__DCT_CONST_ROUNDING); - v[6] = _mm256_add_epi32(u[6], k__DCT_CONST_ROUNDING); - v[7] = _mm256_add_epi32(u[7], k__DCT_CONST_ROUNDING); - v[8] = _mm256_add_epi32(u[8], k__DCT_CONST_ROUNDING); - v[9] = _mm256_add_epi32(u[9], k__DCT_CONST_ROUNDING); - v[10] = _mm256_add_epi32(u[10], k__DCT_CONST_ROUNDING); - v[11] = _mm256_add_epi32(u[11], k__DCT_CONST_ROUNDING); - v[12] = _mm256_add_epi32(u[12], k__DCT_CONST_ROUNDING); - v[13] = _mm256_add_epi32(u[13], k__DCT_CONST_ROUNDING); - v[14] = _mm256_add_epi32(u[14], k__DCT_CONST_ROUNDING); - v[15] = _mm256_add_epi32(u[15], k__DCT_CONST_ROUNDING); - - lstep3[34] = _mm256_srai_epi32(v[0], DCT_CONST_BITS); - lstep3[35] = _mm256_srai_epi32(v[1], DCT_CONST_BITS); - lstep3[36] = _mm256_srai_epi32(v[2], DCT_CONST_BITS); - lstep3[37] = _mm256_srai_epi32(v[3], DCT_CONST_BITS); - lstep3[42] = _mm256_srai_epi32(v[4], DCT_CONST_BITS); - lstep3[43] = _mm256_srai_epi32(v[5], DCT_CONST_BITS); - lstep3[44] = _mm256_srai_epi32(v[6], DCT_CONST_BITS); - lstep3[45] = _mm256_srai_epi32(v[7], DCT_CONST_BITS); - lstep3[50] = _mm256_srai_epi32(v[8], DCT_CONST_BITS); - lstep3[51] = _mm256_srai_epi32(v[9], DCT_CONST_BITS); - lstep3[52] = _mm256_srai_epi32(v[10], DCT_CONST_BITS); - lstep3[53] = _mm256_srai_epi32(v[11], DCT_CONST_BITS); - lstep3[58] = _mm256_srai_epi32(v[12], DCT_CONST_BITS); - lstep3[59] = _mm256_srai_epi32(v[13], DCT_CONST_BITS); - lstep3[60] = _mm256_srai_epi32(v[14], DCT_CONST_BITS); - lstep3[61] = _mm256_srai_epi32(v[15], DCT_CONST_BITS); - } - // stage 7 - { - const __m256i k32_p30_p02 = - pair256_set_epi32(cospi_30_64, cospi_2_64); - const __m256i k32_p14_p18 = - pair256_set_epi32(cospi_14_64, cospi_18_64); - const __m256i k32_p22_p10 = - pair256_set_epi32(cospi_22_64, cospi_10_64); - const __m256i k32_p06_p26 = - pair256_set_epi32(cospi_6_64, cospi_26_64); - const __m256i k32_m26_p06 = - pair256_set_epi32(-cospi_26_64, cospi_6_64); - const __m256i k32_m10_p22 = - pair256_set_epi32(-cospi_10_64, cospi_22_64); - const __m256i k32_m18_p14 = - pair256_set_epi32(-cospi_18_64, cospi_14_64); - const __m256i k32_m02_p30 = - pair256_set_epi32(-cospi_2_64, cospi_30_64); - - u[0] = _mm256_unpacklo_epi32(lstep3[16], lstep3[30]); - u[1] = _mm256_unpackhi_epi32(lstep3[16], lstep3[30]); - u[2] = _mm256_unpacklo_epi32(lstep3[17], lstep3[31]); - u[3] = _mm256_unpackhi_epi32(lstep3[17], lstep3[31]); - u[4] = _mm256_unpacklo_epi32(lstep3[18], lstep3[28]); - u[5] = _mm256_unpackhi_epi32(lstep3[18], lstep3[28]); - u[6] = _mm256_unpacklo_epi32(lstep3[19], lstep3[29]); - u[7] = _mm256_unpackhi_epi32(lstep3[19], lstep3[29]); - u[8] = _mm256_unpacklo_epi32(lstep3[20], lstep3[26]); - u[9] = _mm256_unpackhi_epi32(lstep3[20], lstep3[26]); - u[10] = _mm256_unpacklo_epi32(lstep3[21], lstep3[27]); - u[11] = _mm256_unpackhi_epi32(lstep3[21], lstep3[27]); - u[12] = _mm256_unpacklo_epi32(lstep3[22], lstep3[24]); - u[13] = _mm256_unpackhi_epi32(lstep3[22], lstep3[24]); - u[14] = _mm256_unpacklo_epi32(lstep3[23], lstep3[25]); - u[15] = _mm256_unpackhi_epi32(lstep3[23], lstep3[25]); - - v[0] = k_madd_epi32_avx2(u[0], k32_p30_p02); - v[1] = k_madd_epi32_avx2(u[1], k32_p30_p02); - v[2] = k_madd_epi32_avx2(u[2], k32_p30_p02); - v[3] = k_madd_epi32_avx2(u[3], k32_p30_p02); - v[4] = k_madd_epi32_avx2(u[4], k32_p14_p18); - v[5] = k_madd_epi32_avx2(u[5], k32_p14_p18); - v[6] = k_madd_epi32_avx2(u[6], k32_p14_p18); - v[7] = k_madd_epi32_avx2(u[7], k32_p14_p18); - v[8] = k_madd_epi32_avx2(u[8], k32_p22_p10); - v[9] = k_madd_epi32_avx2(u[9], k32_p22_p10); - v[10] = k_madd_epi32_avx2(u[10], k32_p22_p10); - v[11] = k_madd_epi32_avx2(u[11], k32_p22_p10); - v[12] = k_madd_epi32_avx2(u[12], k32_p06_p26); - v[13] = k_madd_epi32_avx2(u[13], k32_p06_p26); - v[14] = k_madd_epi32_avx2(u[14], k32_p06_p26); - v[15] = k_madd_epi32_avx2(u[15], k32_p06_p26); - v[16] = k_madd_epi32_avx2(u[12], k32_m26_p06); - v[17] = k_madd_epi32_avx2(u[13], k32_m26_p06); - v[18] = k_madd_epi32_avx2(u[14], k32_m26_p06); - v[19] = k_madd_epi32_avx2(u[15], k32_m26_p06); - v[20] = k_madd_epi32_avx2(u[8], k32_m10_p22); - v[21] = k_madd_epi32_avx2(u[9], k32_m10_p22); - v[22] = k_madd_epi32_avx2(u[10], k32_m10_p22); - v[23] = k_madd_epi32_avx2(u[11], k32_m10_p22); - v[24] = k_madd_epi32_avx2(u[4], k32_m18_p14); - v[25] = k_madd_epi32_avx2(u[5], k32_m18_p14); - v[26] = k_madd_epi32_avx2(u[6], k32_m18_p14); - v[27] = k_madd_epi32_avx2(u[7], k32_m18_p14); - v[28] = k_madd_epi32_avx2(u[0], k32_m02_p30); - v[29] = k_madd_epi32_avx2(u[1], k32_m02_p30); - v[30] = k_madd_epi32_avx2(u[2], k32_m02_p30); - v[31] = k_madd_epi32_avx2(u[3], k32_m02_p30); - - u[0] = k_packs_epi64_avx2(v[0], v[1]); - u[1] = k_packs_epi64_avx2(v[2], v[3]); - u[2] = k_packs_epi64_avx2(v[4], v[5]); - u[3] = k_packs_epi64_avx2(v[6], v[7]); - u[4] = k_packs_epi64_avx2(v[8], v[9]); - u[5] = k_packs_epi64_avx2(v[10], v[11]); - u[6] = k_packs_epi64_avx2(v[12], v[13]); - u[7] = k_packs_epi64_avx2(v[14], v[15]); - u[8] = k_packs_epi64_avx2(v[16], v[17]); - u[9] = k_packs_epi64_avx2(v[18], v[19]); - u[10] = k_packs_epi64_avx2(v[20], v[21]); - u[11] = k_packs_epi64_avx2(v[22], v[23]); - u[12] = k_packs_epi64_avx2(v[24], v[25]); - u[13] = k_packs_epi64_avx2(v[26], v[27]); - u[14] = k_packs_epi64_avx2(v[28], v[29]); - u[15] = k_packs_epi64_avx2(v[30], v[31]); - - v[0] = _mm256_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm256_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm256_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm256_add_epi32(u[3], k__DCT_CONST_ROUNDING); - v[4] = _mm256_add_epi32(u[4], k__DCT_CONST_ROUNDING); - v[5] = _mm256_add_epi32(u[5], k__DCT_CONST_ROUNDING); - v[6] = _mm256_add_epi32(u[6], k__DCT_CONST_ROUNDING); - v[7] = _mm256_add_epi32(u[7], k__DCT_CONST_ROUNDING); - v[8] = _mm256_add_epi32(u[8], k__DCT_CONST_ROUNDING); - v[9] = _mm256_add_epi32(u[9], k__DCT_CONST_ROUNDING); - v[10] = _mm256_add_epi32(u[10], k__DCT_CONST_ROUNDING); - v[11] = _mm256_add_epi32(u[11], k__DCT_CONST_ROUNDING); - v[12] = _mm256_add_epi32(u[12], k__DCT_CONST_ROUNDING); - v[13] = _mm256_add_epi32(u[13], k__DCT_CONST_ROUNDING); - v[14] = _mm256_add_epi32(u[14], k__DCT_CONST_ROUNDING); - v[15] = _mm256_add_epi32(u[15], k__DCT_CONST_ROUNDING); - - u[0] = _mm256_srai_epi32(v[0], DCT_CONST_BITS); - u[1] = _mm256_srai_epi32(v[1], DCT_CONST_BITS); - u[2] = _mm256_srai_epi32(v[2], DCT_CONST_BITS); - u[3] = _mm256_srai_epi32(v[3], DCT_CONST_BITS); - u[4] = _mm256_srai_epi32(v[4], DCT_CONST_BITS); - u[5] = _mm256_srai_epi32(v[5], DCT_CONST_BITS); - u[6] = _mm256_srai_epi32(v[6], DCT_CONST_BITS); - u[7] = _mm256_srai_epi32(v[7], DCT_CONST_BITS); - u[8] = _mm256_srai_epi32(v[8], DCT_CONST_BITS); - u[9] = _mm256_srai_epi32(v[9], DCT_CONST_BITS); - u[10] = _mm256_srai_epi32(v[10], DCT_CONST_BITS); - u[11] = _mm256_srai_epi32(v[11], DCT_CONST_BITS); - u[12] = _mm256_srai_epi32(v[12], DCT_CONST_BITS); - u[13] = _mm256_srai_epi32(v[13], DCT_CONST_BITS); - u[14] = _mm256_srai_epi32(v[14], DCT_CONST_BITS); - u[15] = _mm256_srai_epi32(v[15], DCT_CONST_BITS); - - v[0] = _mm256_cmpgt_epi32(kZero, u[0]); - v[1] = _mm256_cmpgt_epi32(kZero, u[1]); - v[2] = _mm256_cmpgt_epi32(kZero, u[2]); - v[3] = _mm256_cmpgt_epi32(kZero, u[3]); - v[4] = _mm256_cmpgt_epi32(kZero, u[4]); - v[5] = _mm256_cmpgt_epi32(kZero, u[5]); - v[6] = _mm256_cmpgt_epi32(kZero, u[6]); - v[7] = _mm256_cmpgt_epi32(kZero, u[7]); - v[8] = _mm256_cmpgt_epi32(kZero, u[8]); - v[9] = _mm256_cmpgt_epi32(kZero, u[9]); - v[10] = _mm256_cmpgt_epi32(kZero, u[10]); - v[11] = _mm256_cmpgt_epi32(kZero, u[11]); - v[12] = _mm256_cmpgt_epi32(kZero, u[12]); - v[13] = _mm256_cmpgt_epi32(kZero, u[13]); - v[14] = _mm256_cmpgt_epi32(kZero, u[14]); - v[15] = _mm256_cmpgt_epi32(kZero, u[15]); - - u[0] = _mm256_sub_epi32(u[0], v[0]); - u[1] = _mm256_sub_epi32(u[1], v[1]); - u[2] = _mm256_sub_epi32(u[2], v[2]); - u[3] = _mm256_sub_epi32(u[3], v[3]); - u[4] = _mm256_sub_epi32(u[4], v[4]); - u[5] = _mm256_sub_epi32(u[5], v[5]); - u[6] = _mm256_sub_epi32(u[6], v[6]); - u[7] = _mm256_sub_epi32(u[7], v[7]); - u[8] = _mm256_sub_epi32(u[8], v[8]); - u[9] = _mm256_sub_epi32(u[9], v[9]); - u[10] = _mm256_sub_epi32(u[10], v[10]); - u[11] = _mm256_sub_epi32(u[11], v[11]); - u[12] = _mm256_sub_epi32(u[12], v[12]); - u[13] = _mm256_sub_epi32(u[13], v[13]); - u[14] = _mm256_sub_epi32(u[14], v[14]); - u[15] = _mm256_sub_epi32(u[15], v[15]); - - v[0] = _mm256_add_epi32(u[0], K32One); - v[1] = _mm256_add_epi32(u[1], K32One); - v[2] = _mm256_add_epi32(u[2], K32One); - v[3] = _mm256_add_epi32(u[3], K32One); - v[4] = _mm256_add_epi32(u[4], K32One); - v[5] = _mm256_add_epi32(u[5], K32One); - v[6] = _mm256_add_epi32(u[6], K32One); - v[7] = _mm256_add_epi32(u[7], K32One); - v[8] = _mm256_add_epi32(u[8], K32One); - v[9] = _mm256_add_epi32(u[9], K32One); - v[10] = _mm256_add_epi32(u[10], K32One); - v[11] = _mm256_add_epi32(u[11], K32One); - v[12] = _mm256_add_epi32(u[12], K32One); - v[13] = _mm256_add_epi32(u[13], K32One); - v[14] = _mm256_add_epi32(u[14], K32One); - v[15] = _mm256_add_epi32(u[15], K32One); - - u[0] = _mm256_srai_epi32(v[0], 2); - u[1] = _mm256_srai_epi32(v[1], 2); - u[2] = _mm256_srai_epi32(v[2], 2); - u[3] = _mm256_srai_epi32(v[3], 2); - u[4] = _mm256_srai_epi32(v[4], 2); - u[5] = _mm256_srai_epi32(v[5], 2); - u[6] = _mm256_srai_epi32(v[6], 2); - u[7] = _mm256_srai_epi32(v[7], 2); - u[8] = _mm256_srai_epi32(v[8], 2); - u[9] = _mm256_srai_epi32(v[9], 2); - u[10] = _mm256_srai_epi32(v[10], 2); - u[11] = _mm256_srai_epi32(v[11], 2); - u[12] = _mm256_srai_epi32(v[12], 2); - u[13] = _mm256_srai_epi32(v[13], 2); - u[14] = _mm256_srai_epi32(v[14], 2); - u[15] = _mm256_srai_epi32(v[15], 2); - - out[2] = _mm256_packs_epi32(u[0], u[1]); - out[18] = _mm256_packs_epi32(u[2], u[3]); - out[10] = _mm256_packs_epi32(u[4], u[5]); - out[26] = _mm256_packs_epi32(u[6], u[7]); - out[6] = _mm256_packs_epi32(u[8], u[9]); - out[22] = _mm256_packs_epi32(u[10], u[11]); - out[14] = _mm256_packs_epi32(u[12], u[13]); - out[30] = _mm256_packs_epi32(u[14], u[15]); - } - { - lstep1[32] = _mm256_add_epi32(lstep3[34], lstep2[32]); - lstep1[33] = _mm256_add_epi32(lstep3[35], lstep2[33]); - lstep1[34] = _mm256_sub_epi32(lstep2[32], lstep3[34]); - lstep1[35] = _mm256_sub_epi32(lstep2[33], lstep3[35]); - lstep1[36] = _mm256_sub_epi32(lstep2[38], lstep3[36]); - lstep1[37] = _mm256_sub_epi32(lstep2[39], lstep3[37]); - lstep1[38] = _mm256_add_epi32(lstep3[36], lstep2[38]); - lstep1[39] = _mm256_add_epi32(lstep3[37], lstep2[39]); - lstep1[40] = _mm256_add_epi32(lstep3[42], lstep2[40]); - lstep1[41] = _mm256_add_epi32(lstep3[43], lstep2[41]); - lstep1[42] = _mm256_sub_epi32(lstep2[40], lstep3[42]); - lstep1[43] = _mm256_sub_epi32(lstep2[41], lstep3[43]); - lstep1[44] = _mm256_sub_epi32(lstep2[46], lstep3[44]); - lstep1[45] = _mm256_sub_epi32(lstep2[47], lstep3[45]); - lstep1[46] = _mm256_add_epi32(lstep3[44], lstep2[46]); - lstep1[47] = _mm256_add_epi32(lstep3[45], lstep2[47]); - lstep1[48] = _mm256_add_epi32(lstep3[50], lstep2[48]); - lstep1[49] = _mm256_add_epi32(lstep3[51], lstep2[49]); - lstep1[50] = _mm256_sub_epi32(lstep2[48], lstep3[50]); - lstep1[51] = _mm256_sub_epi32(lstep2[49], lstep3[51]); - lstep1[52] = _mm256_sub_epi32(lstep2[54], lstep3[52]); - lstep1[53] = _mm256_sub_epi32(lstep2[55], lstep3[53]); - lstep1[54] = _mm256_add_epi32(lstep3[52], lstep2[54]); - lstep1[55] = _mm256_add_epi32(lstep3[53], lstep2[55]); - lstep1[56] = _mm256_add_epi32(lstep3[58], lstep2[56]); - lstep1[57] = _mm256_add_epi32(lstep3[59], lstep2[57]); - lstep1[58] = _mm256_sub_epi32(lstep2[56], lstep3[58]); - lstep1[59] = _mm256_sub_epi32(lstep2[57], lstep3[59]); - lstep1[60] = _mm256_sub_epi32(lstep2[62], lstep3[60]); - lstep1[61] = _mm256_sub_epi32(lstep2[63], lstep3[61]); - lstep1[62] = _mm256_add_epi32(lstep3[60], lstep2[62]); - lstep1[63] = _mm256_add_epi32(lstep3[61], lstep2[63]); - } - // stage 8 - { - const __m256i k32_p31_p01 = - pair256_set_epi32(cospi_31_64, cospi_1_64); - const __m256i k32_p15_p17 = - pair256_set_epi32(cospi_15_64, cospi_17_64); - const __m256i k32_p23_p09 = - pair256_set_epi32(cospi_23_64, cospi_9_64); - const __m256i k32_p07_p25 = - pair256_set_epi32(cospi_7_64, cospi_25_64); - const __m256i k32_m25_p07 = - pair256_set_epi32(-cospi_25_64, cospi_7_64); - const __m256i k32_m09_p23 = - pair256_set_epi32(-cospi_9_64, cospi_23_64); - const __m256i k32_m17_p15 = - pair256_set_epi32(-cospi_17_64, cospi_15_64); - const __m256i k32_m01_p31 = - pair256_set_epi32(-cospi_1_64, cospi_31_64); - - u[0] = _mm256_unpacklo_epi32(lstep1[32], lstep1[62]); - u[1] = _mm256_unpackhi_epi32(lstep1[32], lstep1[62]); - u[2] = _mm256_unpacklo_epi32(lstep1[33], lstep1[63]); - u[3] = _mm256_unpackhi_epi32(lstep1[33], lstep1[63]); - u[4] = _mm256_unpacklo_epi32(lstep1[34], lstep1[60]); - u[5] = _mm256_unpackhi_epi32(lstep1[34], lstep1[60]); - u[6] = _mm256_unpacklo_epi32(lstep1[35], lstep1[61]); - u[7] = _mm256_unpackhi_epi32(lstep1[35], lstep1[61]); - u[8] = _mm256_unpacklo_epi32(lstep1[36], lstep1[58]); - u[9] = _mm256_unpackhi_epi32(lstep1[36], lstep1[58]); - u[10] = _mm256_unpacklo_epi32(lstep1[37], lstep1[59]); - u[11] = _mm256_unpackhi_epi32(lstep1[37], lstep1[59]); - u[12] = _mm256_unpacklo_epi32(lstep1[38], lstep1[56]); - u[13] = _mm256_unpackhi_epi32(lstep1[38], lstep1[56]); - u[14] = _mm256_unpacklo_epi32(lstep1[39], lstep1[57]); - u[15] = _mm256_unpackhi_epi32(lstep1[39], lstep1[57]); - - v[0] = k_madd_epi32_avx2(u[0], k32_p31_p01); - v[1] = k_madd_epi32_avx2(u[1], k32_p31_p01); - v[2] = k_madd_epi32_avx2(u[2], k32_p31_p01); - v[3] = k_madd_epi32_avx2(u[3], k32_p31_p01); - v[4] = k_madd_epi32_avx2(u[4], k32_p15_p17); - v[5] = k_madd_epi32_avx2(u[5], k32_p15_p17); - v[6] = k_madd_epi32_avx2(u[6], k32_p15_p17); - v[7] = k_madd_epi32_avx2(u[7], k32_p15_p17); - v[8] = k_madd_epi32_avx2(u[8], k32_p23_p09); - v[9] = k_madd_epi32_avx2(u[9], k32_p23_p09); - v[10] = k_madd_epi32_avx2(u[10], k32_p23_p09); - v[11] = k_madd_epi32_avx2(u[11], k32_p23_p09); - v[12] = k_madd_epi32_avx2(u[12], k32_p07_p25); - v[13] = k_madd_epi32_avx2(u[13], k32_p07_p25); - v[14] = k_madd_epi32_avx2(u[14], k32_p07_p25); - v[15] = k_madd_epi32_avx2(u[15], k32_p07_p25); - v[16] = k_madd_epi32_avx2(u[12], k32_m25_p07); - v[17] = k_madd_epi32_avx2(u[13], k32_m25_p07); - v[18] = k_madd_epi32_avx2(u[14], k32_m25_p07); - v[19] = k_madd_epi32_avx2(u[15], k32_m25_p07); - v[20] = k_madd_epi32_avx2(u[8], k32_m09_p23); - v[21] = k_madd_epi32_avx2(u[9], k32_m09_p23); - v[22] = k_madd_epi32_avx2(u[10], k32_m09_p23); - v[23] = k_madd_epi32_avx2(u[11], k32_m09_p23); - v[24] = k_madd_epi32_avx2(u[4], k32_m17_p15); - v[25] = k_madd_epi32_avx2(u[5], k32_m17_p15); - v[26] = k_madd_epi32_avx2(u[6], k32_m17_p15); - v[27] = k_madd_epi32_avx2(u[7], k32_m17_p15); - v[28] = k_madd_epi32_avx2(u[0], k32_m01_p31); - v[29] = k_madd_epi32_avx2(u[1], k32_m01_p31); - v[30] = k_madd_epi32_avx2(u[2], k32_m01_p31); - v[31] = k_madd_epi32_avx2(u[3], k32_m01_p31); - - u[0] = k_packs_epi64_avx2(v[0], v[1]); - u[1] = k_packs_epi64_avx2(v[2], v[3]); - u[2] = k_packs_epi64_avx2(v[4], v[5]); - u[3] = k_packs_epi64_avx2(v[6], v[7]); - u[4] = k_packs_epi64_avx2(v[8], v[9]); - u[5] = k_packs_epi64_avx2(v[10], v[11]); - u[6] = k_packs_epi64_avx2(v[12], v[13]); - u[7] = k_packs_epi64_avx2(v[14], v[15]); - u[8] = k_packs_epi64_avx2(v[16], v[17]); - u[9] = k_packs_epi64_avx2(v[18], v[19]); - u[10] = k_packs_epi64_avx2(v[20], v[21]); - u[11] = k_packs_epi64_avx2(v[22], v[23]); - u[12] = k_packs_epi64_avx2(v[24], v[25]); - u[13] = k_packs_epi64_avx2(v[26], v[27]); - u[14] = k_packs_epi64_avx2(v[28], v[29]); - u[15] = k_packs_epi64_avx2(v[30], v[31]); - - v[0] = _mm256_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm256_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm256_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm256_add_epi32(u[3], k__DCT_CONST_ROUNDING); - v[4] = _mm256_add_epi32(u[4], k__DCT_CONST_ROUNDING); - v[5] = _mm256_add_epi32(u[5], k__DCT_CONST_ROUNDING); - v[6] = _mm256_add_epi32(u[6], k__DCT_CONST_ROUNDING); - v[7] = _mm256_add_epi32(u[7], k__DCT_CONST_ROUNDING); - v[8] = _mm256_add_epi32(u[8], k__DCT_CONST_ROUNDING); - v[9] = _mm256_add_epi32(u[9], k__DCT_CONST_ROUNDING); - v[10] = _mm256_add_epi32(u[10], k__DCT_CONST_ROUNDING); - v[11] = _mm256_add_epi32(u[11], k__DCT_CONST_ROUNDING); - v[12] = _mm256_add_epi32(u[12], k__DCT_CONST_ROUNDING); - v[13] = _mm256_add_epi32(u[13], k__DCT_CONST_ROUNDING); - v[14] = _mm256_add_epi32(u[14], k__DCT_CONST_ROUNDING); - v[15] = _mm256_add_epi32(u[15], k__DCT_CONST_ROUNDING); - - u[0] = _mm256_srai_epi32(v[0], DCT_CONST_BITS); - u[1] = _mm256_srai_epi32(v[1], DCT_CONST_BITS); - u[2] = _mm256_srai_epi32(v[2], DCT_CONST_BITS); - u[3] = _mm256_srai_epi32(v[3], DCT_CONST_BITS); - u[4] = _mm256_srai_epi32(v[4], DCT_CONST_BITS); - u[5] = _mm256_srai_epi32(v[5], DCT_CONST_BITS); - u[6] = _mm256_srai_epi32(v[6], DCT_CONST_BITS); - u[7] = _mm256_srai_epi32(v[7], DCT_CONST_BITS); - u[8] = _mm256_srai_epi32(v[8], DCT_CONST_BITS); - u[9] = _mm256_srai_epi32(v[9], DCT_CONST_BITS); - u[10] = _mm256_srai_epi32(v[10], DCT_CONST_BITS); - u[11] = _mm256_srai_epi32(v[11], DCT_CONST_BITS); - u[12] = _mm256_srai_epi32(v[12], DCT_CONST_BITS); - u[13] = _mm256_srai_epi32(v[13], DCT_CONST_BITS); - u[14] = _mm256_srai_epi32(v[14], DCT_CONST_BITS); - u[15] = _mm256_srai_epi32(v[15], DCT_CONST_BITS); - - v[0] = _mm256_cmpgt_epi32(kZero, u[0]); - v[1] = _mm256_cmpgt_epi32(kZero, u[1]); - v[2] = _mm256_cmpgt_epi32(kZero, u[2]); - v[3] = _mm256_cmpgt_epi32(kZero, u[3]); - v[4] = _mm256_cmpgt_epi32(kZero, u[4]); - v[5] = _mm256_cmpgt_epi32(kZero, u[5]); - v[6] = _mm256_cmpgt_epi32(kZero, u[6]); - v[7] = _mm256_cmpgt_epi32(kZero, u[7]); - v[8] = _mm256_cmpgt_epi32(kZero, u[8]); - v[9] = _mm256_cmpgt_epi32(kZero, u[9]); - v[10] = _mm256_cmpgt_epi32(kZero, u[10]); - v[11] = _mm256_cmpgt_epi32(kZero, u[11]); - v[12] = _mm256_cmpgt_epi32(kZero, u[12]); - v[13] = _mm256_cmpgt_epi32(kZero, u[13]); - v[14] = _mm256_cmpgt_epi32(kZero, u[14]); - v[15] = _mm256_cmpgt_epi32(kZero, u[15]); - - u[0] = _mm256_sub_epi32(u[0], v[0]); - u[1] = _mm256_sub_epi32(u[1], v[1]); - u[2] = _mm256_sub_epi32(u[2], v[2]); - u[3] = _mm256_sub_epi32(u[3], v[3]); - u[4] = _mm256_sub_epi32(u[4], v[4]); - u[5] = _mm256_sub_epi32(u[5], v[5]); - u[6] = _mm256_sub_epi32(u[6], v[6]); - u[7] = _mm256_sub_epi32(u[7], v[7]); - u[8] = _mm256_sub_epi32(u[8], v[8]); - u[9] = _mm256_sub_epi32(u[9], v[9]); - u[10] = _mm256_sub_epi32(u[10], v[10]); - u[11] = _mm256_sub_epi32(u[11], v[11]); - u[12] = _mm256_sub_epi32(u[12], v[12]); - u[13] = _mm256_sub_epi32(u[13], v[13]); - u[14] = _mm256_sub_epi32(u[14], v[14]); - u[15] = _mm256_sub_epi32(u[15], v[15]); - - v[0] = _mm256_add_epi32(u[0], K32One); - v[1] = _mm256_add_epi32(u[1], K32One); - v[2] = _mm256_add_epi32(u[2], K32One); - v[3] = _mm256_add_epi32(u[3], K32One); - v[4] = _mm256_add_epi32(u[4], K32One); - v[5] = _mm256_add_epi32(u[5], K32One); - v[6] = _mm256_add_epi32(u[6], K32One); - v[7] = _mm256_add_epi32(u[7], K32One); - v[8] = _mm256_add_epi32(u[8], K32One); - v[9] = _mm256_add_epi32(u[9], K32One); - v[10] = _mm256_add_epi32(u[10], K32One); - v[11] = _mm256_add_epi32(u[11], K32One); - v[12] = _mm256_add_epi32(u[12], K32One); - v[13] = _mm256_add_epi32(u[13], K32One); - v[14] = _mm256_add_epi32(u[14], K32One); - v[15] = _mm256_add_epi32(u[15], K32One); - - u[0] = _mm256_srai_epi32(v[0], 2); - u[1] = _mm256_srai_epi32(v[1], 2); - u[2] = _mm256_srai_epi32(v[2], 2); - u[3] = _mm256_srai_epi32(v[3], 2); - u[4] = _mm256_srai_epi32(v[4], 2); - u[5] = _mm256_srai_epi32(v[5], 2); - u[6] = _mm256_srai_epi32(v[6], 2); - u[7] = _mm256_srai_epi32(v[7], 2); - u[8] = _mm256_srai_epi32(v[8], 2); - u[9] = _mm256_srai_epi32(v[9], 2); - u[10] = _mm256_srai_epi32(v[10], 2); - u[11] = _mm256_srai_epi32(v[11], 2); - u[12] = _mm256_srai_epi32(v[12], 2); - u[13] = _mm256_srai_epi32(v[13], 2); - u[14] = _mm256_srai_epi32(v[14], 2); - u[15] = _mm256_srai_epi32(v[15], 2); - - out[1] = _mm256_packs_epi32(u[0], u[1]); - out[17] = _mm256_packs_epi32(u[2], u[3]); - out[9] = _mm256_packs_epi32(u[4], u[5]); - out[25] = _mm256_packs_epi32(u[6], u[7]); - out[7] = _mm256_packs_epi32(u[8], u[9]); - out[23] = _mm256_packs_epi32(u[10], u[11]); - out[15] = _mm256_packs_epi32(u[12], u[13]); - out[31] = _mm256_packs_epi32(u[14], u[15]); - } - { - const __m256i k32_p27_p05 = - pair256_set_epi32(cospi_27_64, cospi_5_64); - const __m256i k32_p11_p21 = - pair256_set_epi32(cospi_11_64, cospi_21_64); - const __m256i k32_p19_p13 = - pair256_set_epi32(cospi_19_64, cospi_13_64); - const __m256i k32_p03_p29 = - pair256_set_epi32(cospi_3_64, cospi_29_64); - const __m256i k32_m29_p03 = - pair256_set_epi32(-cospi_29_64, cospi_3_64); - const __m256i k32_m13_p19 = - pair256_set_epi32(-cospi_13_64, cospi_19_64); - const __m256i k32_m21_p11 = - pair256_set_epi32(-cospi_21_64, cospi_11_64); - const __m256i k32_m05_p27 = - pair256_set_epi32(-cospi_5_64, cospi_27_64); - - u[0] = _mm256_unpacklo_epi32(lstep1[40], lstep1[54]); - u[1] = _mm256_unpackhi_epi32(lstep1[40], lstep1[54]); - u[2] = _mm256_unpacklo_epi32(lstep1[41], lstep1[55]); - u[3] = _mm256_unpackhi_epi32(lstep1[41], lstep1[55]); - u[4] = _mm256_unpacklo_epi32(lstep1[42], lstep1[52]); - u[5] = _mm256_unpackhi_epi32(lstep1[42], lstep1[52]); - u[6] = _mm256_unpacklo_epi32(lstep1[43], lstep1[53]); - u[7] = _mm256_unpackhi_epi32(lstep1[43], lstep1[53]); - u[8] = _mm256_unpacklo_epi32(lstep1[44], lstep1[50]); - u[9] = _mm256_unpackhi_epi32(lstep1[44], lstep1[50]); - u[10] = _mm256_unpacklo_epi32(lstep1[45], lstep1[51]); - u[11] = _mm256_unpackhi_epi32(lstep1[45], lstep1[51]); - u[12] = _mm256_unpacklo_epi32(lstep1[46], lstep1[48]); - u[13] = _mm256_unpackhi_epi32(lstep1[46], lstep1[48]); - u[14] = _mm256_unpacklo_epi32(lstep1[47], lstep1[49]); - u[15] = _mm256_unpackhi_epi32(lstep1[47], lstep1[49]); - - v[0] = k_madd_epi32_avx2(u[0], k32_p27_p05); - v[1] = k_madd_epi32_avx2(u[1], k32_p27_p05); - v[2] = k_madd_epi32_avx2(u[2], k32_p27_p05); - v[3] = k_madd_epi32_avx2(u[3], k32_p27_p05); - v[4] = k_madd_epi32_avx2(u[4], k32_p11_p21); - v[5] = k_madd_epi32_avx2(u[5], k32_p11_p21); - v[6] = k_madd_epi32_avx2(u[6], k32_p11_p21); - v[7] = k_madd_epi32_avx2(u[7], k32_p11_p21); - v[8] = k_madd_epi32_avx2(u[8], k32_p19_p13); - v[9] = k_madd_epi32_avx2(u[9], k32_p19_p13); - v[10] = k_madd_epi32_avx2(u[10], k32_p19_p13); - v[11] = k_madd_epi32_avx2(u[11], k32_p19_p13); - v[12] = k_madd_epi32_avx2(u[12], k32_p03_p29); - v[13] = k_madd_epi32_avx2(u[13], k32_p03_p29); - v[14] = k_madd_epi32_avx2(u[14], k32_p03_p29); - v[15] = k_madd_epi32_avx2(u[15], k32_p03_p29); - v[16] = k_madd_epi32_avx2(u[12], k32_m29_p03); - v[17] = k_madd_epi32_avx2(u[13], k32_m29_p03); - v[18] = k_madd_epi32_avx2(u[14], k32_m29_p03); - v[19] = k_madd_epi32_avx2(u[15], k32_m29_p03); - v[20] = k_madd_epi32_avx2(u[8], k32_m13_p19); - v[21] = k_madd_epi32_avx2(u[9], k32_m13_p19); - v[22] = k_madd_epi32_avx2(u[10], k32_m13_p19); - v[23] = k_madd_epi32_avx2(u[11], k32_m13_p19); - v[24] = k_madd_epi32_avx2(u[4], k32_m21_p11); - v[25] = k_madd_epi32_avx2(u[5], k32_m21_p11); - v[26] = k_madd_epi32_avx2(u[6], k32_m21_p11); - v[27] = k_madd_epi32_avx2(u[7], k32_m21_p11); - v[28] = k_madd_epi32_avx2(u[0], k32_m05_p27); - v[29] = k_madd_epi32_avx2(u[1], k32_m05_p27); - v[30] = k_madd_epi32_avx2(u[2], k32_m05_p27); - v[31] = k_madd_epi32_avx2(u[3], k32_m05_p27); - - u[0] = k_packs_epi64_avx2(v[0], v[1]); - u[1] = k_packs_epi64_avx2(v[2], v[3]); - u[2] = k_packs_epi64_avx2(v[4], v[5]); - u[3] = k_packs_epi64_avx2(v[6], v[7]); - u[4] = k_packs_epi64_avx2(v[8], v[9]); - u[5] = k_packs_epi64_avx2(v[10], v[11]); - u[6] = k_packs_epi64_avx2(v[12], v[13]); - u[7] = k_packs_epi64_avx2(v[14], v[15]); - u[8] = k_packs_epi64_avx2(v[16], v[17]); - u[9] = k_packs_epi64_avx2(v[18], v[19]); - u[10] = k_packs_epi64_avx2(v[20], v[21]); - u[11] = k_packs_epi64_avx2(v[22], v[23]); - u[12] = k_packs_epi64_avx2(v[24], v[25]); - u[13] = k_packs_epi64_avx2(v[26], v[27]); - u[14] = k_packs_epi64_avx2(v[28], v[29]); - u[15] = k_packs_epi64_avx2(v[30], v[31]); - - v[0] = _mm256_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm256_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm256_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm256_add_epi32(u[3], k__DCT_CONST_ROUNDING); - v[4] = _mm256_add_epi32(u[4], k__DCT_CONST_ROUNDING); - v[5] = _mm256_add_epi32(u[5], k__DCT_CONST_ROUNDING); - v[6] = _mm256_add_epi32(u[6], k__DCT_CONST_ROUNDING); - v[7] = _mm256_add_epi32(u[7], k__DCT_CONST_ROUNDING); - v[8] = _mm256_add_epi32(u[8], k__DCT_CONST_ROUNDING); - v[9] = _mm256_add_epi32(u[9], k__DCT_CONST_ROUNDING); - v[10] = _mm256_add_epi32(u[10], k__DCT_CONST_ROUNDING); - v[11] = _mm256_add_epi32(u[11], k__DCT_CONST_ROUNDING); - v[12] = _mm256_add_epi32(u[12], k__DCT_CONST_ROUNDING); - v[13] = _mm256_add_epi32(u[13], k__DCT_CONST_ROUNDING); - v[14] = _mm256_add_epi32(u[14], k__DCT_CONST_ROUNDING); - v[15] = _mm256_add_epi32(u[15], k__DCT_CONST_ROUNDING); - - u[0] = _mm256_srai_epi32(v[0], DCT_CONST_BITS); - u[1] = _mm256_srai_epi32(v[1], DCT_CONST_BITS); - u[2] = _mm256_srai_epi32(v[2], DCT_CONST_BITS); - u[3] = _mm256_srai_epi32(v[3], DCT_CONST_BITS); - u[4] = _mm256_srai_epi32(v[4], DCT_CONST_BITS); - u[5] = _mm256_srai_epi32(v[5], DCT_CONST_BITS); - u[6] = _mm256_srai_epi32(v[6], DCT_CONST_BITS); - u[7] = _mm256_srai_epi32(v[7], DCT_CONST_BITS); - u[8] = _mm256_srai_epi32(v[8], DCT_CONST_BITS); - u[9] = _mm256_srai_epi32(v[9], DCT_CONST_BITS); - u[10] = _mm256_srai_epi32(v[10], DCT_CONST_BITS); - u[11] = _mm256_srai_epi32(v[11], DCT_CONST_BITS); - u[12] = _mm256_srai_epi32(v[12], DCT_CONST_BITS); - u[13] = _mm256_srai_epi32(v[13], DCT_CONST_BITS); - u[14] = _mm256_srai_epi32(v[14], DCT_CONST_BITS); - u[15] = _mm256_srai_epi32(v[15], DCT_CONST_BITS); - - v[0] = _mm256_cmpgt_epi32(kZero, u[0]); - v[1] = _mm256_cmpgt_epi32(kZero, u[1]); - v[2] = _mm256_cmpgt_epi32(kZero, u[2]); - v[3] = _mm256_cmpgt_epi32(kZero, u[3]); - v[4] = _mm256_cmpgt_epi32(kZero, u[4]); - v[5] = _mm256_cmpgt_epi32(kZero, u[5]); - v[6] = _mm256_cmpgt_epi32(kZero, u[6]); - v[7] = _mm256_cmpgt_epi32(kZero, u[7]); - v[8] = _mm256_cmpgt_epi32(kZero, u[8]); - v[9] = _mm256_cmpgt_epi32(kZero, u[9]); - v[10] = _mm256_cmpgt_epi32(kZero, u[10]); - v[11] = _mm256_cmpgt_epi32(kZero, u[11]); - v[12] = _mm256_cmpgt_epi32(kZero, u[12]); - v[13] = _mm256_cmpgt_epi32(kZero, u[13]); - v[14] = _mm256_cmpgt_epi32(kZero, u[14]); - v[15] = _mm256_cmpgt_epi32(kZero, u[15]); - - u[0] = _mm256_sub_epi32(u[0], v[0]); - u[1] = _mm256_sub_epi32(u[1], v[1]); - u[2] = _mm256_sub_epi32(u[2], v[2]); - u[3] = _mm256_sub_epi32(u[3], v[3]); - u[4] = _mm256_sub_epi32(u[4], v[4]); - u[5] = _mm256_sub_epi32(u[5], v[5]); - u[6] = _mm256_sub_epi32(u[6], v[6]); - u[7] = _mm256_sub_epi32(u[7], v[7]); - u[8] = _mm256_sub_epi32(u[8], v[8]); - u[9] = _mm256_sub_epi32(u[9], v[9]); - u[10] = _mm256_sub_epi32(u[10], v[10]); - u[11] = _mm256_sub_epi32(u[11], v[11]); - u[12] = _mm256_sub_epi32(u[12], v[12]); - u[13] = _mm256_sub_epi32(u[13], v[13]); - u[14] = _mm256_sub_epi32(u[14], v[14]); - u[15] = _mm256_sub_epi32(u[15], v[15]); - - v[0] = _mm256_add_epi32(u[0], K32One); - v[1] = _mm256_add_epi32(u[1], K32One); - v[2] = _mm256_add_epi32(u[2], K32One); - v[3] = _mm256_add_epi32(u[3], K32One); - v[4] = _mm256_add_epi32(u[4], K32One); - v[5] = _mm256_add_epi32(u[5], K32One); - v[6] = _mm256_add_epi32(u[6], K32One); - v[7] = _mm256_add_epi32(u[7], K32One); - v[8] = _mm256_add_epi32(u[8], K32One); - v[9] = _mm256_add_epi32(u[9], K32One); - v[10] = _mm256_add_epi32(u[10], K32One); - v[11] = _mm256_add_epi32(u[11], K32One); - v[12] = _mm256_add_epi32(u[12], K32One); - v[13] = _mm256_add_epi32(u[13], K32One); - v[14] = _mm256_add_epi32(u[14], K32One); - v[15] = _mm256_add_epi32(u[15], K32One); - - u[0] = _mm256_srai_epi32(v[0], 2); - u[1] = _mm256_srai_epi32(v[1], 2); - u[2] = _mm256_srai_epi32(v[2], 2); - u[3] = _mm256_srai_epi32(v[3], 2); - u[4] = _mm256_srai_epi32(v[4], 2); - u[5] = _mm256_srai_epi32(v[5], 2); - u[6] = _mm256_srai_epi32(v[6], 2); - u[7] = _mm256_srai_epi32(v[7], 2); - u[8] = _mm256_srai_epi32(v[8], 2); - u[9] = _mm256_srai_epi32(v[9], 2); - u[10] = _mm256_srai_epi32(v[10], 2); - u[11] = _mm256_srai_epi32(v[11], 2); - u[12] = _mm256_srai_epi32(v[12], 2); - u[13] = _mm256_srai_epi32(v[13], 2); - u[14] = _mm256_srai_epi32(v[14], 2); - u[15] = _mm256_srai_epi32(v[15], 2); - - out[5] = _mm256_packs_epi32(u[0], u[1]); - out[21] = _mm256_packs_epi32(u[2], u[3]); - out[13] = _mm256_packs_epi32(u[4], u[5]); - out[29] = _mm256_packs_epi32(u[6], u[7]); - out[3] = _mm256_packs_epi32(u[8], u[9]); - out[19] = _mm256_packs_epi32(u[10], u[11]); - out[11] = _mm256_packs_epi32(u[12], u[13]); - out[27] = _mm256_packs_epi32(u[14], u[15]); - } - } -#endif - // Transpose the results, do it as four 8x8 transposes. - { - int transpose_block; - int16_t *output_currStep, *output_nextStep; - if (0 == pass) { - output_currStep = &intermediate[column_start * 32]; - output_nextStep = &intermediate[(column_start + 8) * 32]; - } else { - output_currStep = &output_org[column_start * 32]; - output_nextStep = &output_org[(column_start + 8) * 32]; - } - for (transpose_block = 0; transpose_block < 4; ++transpose_block) { - __m256i *this_out = &out[8 * transpose_block]; - // 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 - // 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 - // 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 - // 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 - // 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 - // 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 - // 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 - // 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 - const __m256i tr0_0 = _mm256_unpacklo_epi16(this_out[0], this_out[1]); - const __m256i tr0_1 = _mm256_unpacklo_epi16(this_out[2], this_out[3]); - const __m256i tr0_2 = _mm256_unpackhi_epi16(this_out[0], this_out[1]); - const __m256i tr0_3 = _mm256_unpackhi_epi16(this_out[2], this_out[3]); - const __m256i tr0_4 = _mm256_unpacklo_epi16(this_out[4], this_out[5]); - const __m256i tr0_5 = _mm256_unpacklo_epi16(this_out[6], this_out[7]); - const __m256i tr0_6 = _mm256_unpackhi_epi16(this_out[4], this_out[5]); - const __m256i tr0_7 = _mm256_unpackhi_epi16(this_out[6], this_out[7]); - // 00 20 01 21 02 22 03 23 08 28 09 29 10 30 11 31 - // 40 60 41 61 42 62 43 63 48 68 49 69 50 70 51 71 - // 04 24 05 25 06 26 07 27 12 32 13 33 14 34 15 35 - // 44 64 45 65 46 66 47 67 52 72 53 73 54 74 55 75 - // 80 100 81 101 82 102 83 103 88 108 89 109 90 110 91 101 - // 120 140 121 141 122 142 123 143 128 148 129 149 130 150 131 151 - // 84 104 85 105 86 106 87 107 92 112 93 113 94 114 95 115 - // 124 144 125 145 126 146 127 147 132 152 133 153 134 154 135 155 - - const __m256i tr1_0 = _mm256_unpacklo_epi32(tr0_0, tr0_1); - const __m256i tr1_1 = _mm256_unpacklo_epi32(tr0_2, tr0_3); - const __m256i tr1_2 = _mm256_unpackhi_epi32(tr0_0, tr0_1); - const __m256i tr1_3 = _mm256_unpackhi_epi32(tr0_2, tr0_3); - const __m256i tr1_4 = _mm256_unpacklo_epi32(tr0_4, tr0_5); - const __m256i tr1_5 = _mm256_unpacklo_epi32(tr0_6, tr0_7); - const __m256i tr1_6 = _mm256_unpackhi_epi32(tr0_4, tr0_5); - const __m256i tr1_7 = _mm256_unpackhi_epi32(tr0_6, tr0_7); - // 00 20 40 60 01 21 41 61 08 28 48 68 09 29 49 69 - // 04 24 44 64 05 25 45 65 12 32 52 72 13 33 53 73 - // 02 22 42 62 03 23 43 63 10 30 50 70 11 31 51 71 - // 06 26 46 66 07 27 47 67 14 34 54 74 15 35 55 75 - // 80 100 120 140 81 101 121 141 88 108 128 148 89 109 129 149 - // 84 104 124 144 85 105 125 145 92 112 132 152 93 113 133 153 - // 82 102 122 142 83 103 123 143 90 110 130 150 91 101 131 151 - // 86 106 126 146 87 107 127 147 94 114 134 154 95 115 135 155 - __m256i tr2_0 = _mm256_unpacklo_epi64(tr1_0, tr1_4); - __m256i tr2_1 = _mm256_unpackhi_epi64(tr1_0, tr1_4); - __m256i tr2_2 = _mm256_unpacklo_epi64(tr1_2, tr1_6); - __m256i tr2_3 = _mm256_unpackhi_epi64(tr1_2, tr1_6); - __m256i tr2_4 = _mm256_unpacklo_epi64(tr1_1, tr1_5); - __m256i tr2_5 = _mm256_unpackhi_epi64(tr1_1, tr1_5); - __m256i tr2_6 = _mm256_unpacklo_epi64(tr1_3, tr1_7); - __m256i tr2_7 = _mm256_unpackhi_epi64(tr1_3, tr1_7); - // 00 20 40 60 80 100 120 140 08 28 48 68 88 108 128 148 - // 01 21 41 61 81 101 121 141 09 29 49 69 89 109 129 149 - // 02 22 42 62 82 102 122 142 10 30 50 70 90 110 130 150 - // 03 23 43 63 83 103 123 143 11 31 51 71 91 101 131 151 - // 04 24 44 64 84 104 124 144 12 32 52 72 92 112 132 152 - // 05 25 45 65 85 105 125 145 13 33 53 73 93 113 133 153 - // 06 26 46 66 86 106 126 146 14 34 54 74 94 114 134 154 - // 07 27 47 67 87 107 127 147 15 35 55 75 95 115 135 155 - if (0 == pass) { - // output[j] = (output[j] + 1 + (output[j] > 0)) >> 2; - // TODO(cd): see quality impact of only doing - // output[j] = (output[j] + 1) >> 2; - // which would remove the code between here ... - __m256i tr2_0_0 = _mm256_cmpgt_epi16(tr2_0, kZero); - __m256i tr2_1_0 = _mm256_cmpgt_epi16(tr2_1, kZero); - __m256i tr2_2_0 = _mm256_cmpgt_epi16(tr2_2, kZero); - __m256i tr2_3_0 = _mm256_cmpgt_epi16(tr2_3, kZero); - __m256i tr2_4_0 = _mm256_cmpgt_epi16(tr2_4, kZero); - __m256i tr2_5_0 = _mm256_cmpgt_epi16(tr2_5, kZero); - __m256i tr2_6_0 = _mm256_cmpgt_epi16(tr2_6, kZero); - __m256i tr2_7_0 = _mm256_cmpgt_epi16(tr2_7, kZero); - tr2_0 = _mm256_sub_epi16(tr2_0, tr2_0_0); - tr2_1 = _mm256_sub_epi16(tr2_1, tr2_1_0); - tr2_2 = _mm256_sub_epi16(tr2_2, tr2_2_0); - tr2_3 = _mm256_sub_epi16(tr2_3, tr2_3_0); - tr2_4 = _mm256_sub_epi16(tr2_4, tr2_4_0); - tr2_5 = _mm256_sub_epi16(tr2_5, tr2_5_0); - tr2_6 = _mm256_sub_epi16(tr2_6, tr2_6_0); - tr2_7 = _mm256_sub_epi16(tr2_7, tr2_7_0); - // ... and here. - // PS: also change code in vp9/encoder/vp9_dct.c - tr2_0 = _mm256_add_epi16(tr2_0, kOne); - tr2_1 = _mm256_add_epi16(tr2_1, kOne); - tr2_2 = _mm256_add_epi16(tr2_2, kOne); - tr2_3 = _mm256_add_epi16(tr2_3, kOne); - tr2_4 = _mm256_add_epi16(tr2_4, kOne); - tr2_5 = _mm256_add_epi16(tr2_5, kOne); - tr2_6 = _mm256_add_epi16(tr2_6, kOne); - tr2_7 = _mm256_add_epi16(tr2_7, kOne); - tr2_0 = _mm256_srai_epi16(tr2_0, 2); - tr2_1 = _mm256_srai_epi16(tr2_1, 2); - tr2_2 = _mm256_srai_epi16(tr2_2, 2); - tr2_3 = _mm256_srai_epi16(tr2_3, 2); - tr2_4 = _mm256_srai_epi16(tr2_4, 2); - tr2_5 = _mm256_srai_epi16(tr2_5, 2); - tr2_6 = _mm256_srai_epi16(tr2_6, 2); - tr2_7 = _mm256_srai_epi16(tr2_7, 2); - } - // Note: even though all these stores are aligned, using the aligned - // intrinsic make the code slightly slower. - _mm_storeu_si128((__m128i *)(output_currStep + 0 * 32), - _mm256_castsi256_si128(tr2_0)); - _mm_storeu_si128((__m128i *)(output_currStep + 1 * 32), - _mm256_castsi256_si128(tr2_1)); - _mm_storeu_si128((__m128i *)(output_currStep + 2 * 32), - _mm256_castsi256_si128(tr2_2)); - _mm_storeu_si128((__m128i *)(output_currStep + 3 * 32), - _mm256_castsi256_si128(tr2_3)); - _mm_storeu_si128((__m128i *)(output_currStep + 4 * 32), - _mm256_castsi256_si128(tr2_4)); - _mm_storeu_si128((__m128i *)(output_currStep + 5 * 32), - _mm256_castsi256_si128(tr2_5)); - _mm_storeu_si128((__m128i *)(output_currStep + 6 * 32), - _mm256_castsi256_si128(tr2_6)); - _mm_storeu_si128((__m128i *)(output_currStep + 7 * 32), - _mm256_castsi256_si128(tr2_7)); - - _mm_storeu_si128((__m128i *)(output_nextStep + 0 * 32), - _mm256_extractf128_si256(tr2_0, 1)); - _mm_storeu_si128((__m128i *)(output_nextStep + 1 * 32), - _mm256_extractf128_si256(tr2_1, 1)); - _mm_storeu_si128((__m128i *)(output_nextStep + 2 * 32), - _mm256_extractf128_si256(tr2_2, 1)); - _mm_storeu_si128((__m128i *)(output_nextStep + 3 * 32), - _mm256_extractf128_si256(tr2_3, 1)); - _mm_storeu_si128((__m128i *)(output_nextStep + 4 * 32), - _mm256_extractf128_si256(tr2_4, 1)); - _mm_storeu_si128((__m128i *)(output_nextStep + 5 * 32), - _mm256_extractf128_si256(tr2_5, 1)); - _mm_storeu_si128((__m128i *)(output_nextStep + 6 * 32), - _mm256_extractf128_si256(tr2_6, 1)); - _mm_storeu_si128((__m128i *)(output_nextStep + 7 * 32), - _mm256_extractf128_si256(tr2_7, 1)); - // Process next 8x8 - output_currStep += 8; - output_nextStep += 8; - } - } - } - } -} // NOLINT diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_dct32x32_impl_sse2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_dct32x32_impl_sse2.h deleted file mode 100644 index bf350b6d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_dct32x32_impl_sse2.h +++ /dev/null @@ -1,3130 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // SSE2 - -#include "vpx_dsp/fwd_txfm.h" -#include "vpx_dsp/txfm_common.h" -#include "vpx_dsp/x86/txfm_common_sse2.h" - -// TODO(jingning) The high bit-depth version needs re-work for performance. -// The current SSE2 implementation also causes cross reference to the static -// functions in the C implementation file. -#if DCT_HIGH_BIT_DEPTH -#define ADD_EPI16 _mm_adds_epi16 -#define SUB_EPI16 _mm_subs_epi16 -#if FDCT32x32_HIGH_PRECISION -static void vpx_fdct32x32_rows_c(const int16_t *intermediate, tran_low_t *out) { - int i, j; - for (i = 0; i < 32; ++i) { - tran_high_t temp_in[32], temp_out[32]; - for (j = 0; j < 32; ++j) temp_in[j] = intermediate[j * 32 + i]; - vpx_fdct32(temp_in, temp_out, 0); - for (j = 0; j < 32; ++j) - out[j + i * 32] = - (tran_low_t)((temp_out[j] + 1 + (temp_out[j] < 0)) >> 2); - } -} -#define HIGH_FDCT32x32_2D_C vpx_highbd_fdct32x32_c -#define HIGH_FDCT32x32_2D_ROWS_C vpx_fdct32x32_rows_c -#else -static void vpx_fdct32x32_rd_rows_c(const int16_t *intermediate, - tran_low_t *out) { - int i, j; - for (i = 0; i < 32; ++i) { - tran_high_t temp_in[32], temp_out[32]; - for (j = 0; j < 32; ++j) temp_in[j] = intermediate[j * 32 + i]; - vpx_fdct32(temp_in, temp_out, 1); - for (j = 0; j < 32; ++j) out[j + i * 32] = (tran_low_t)temp_out[j]; - } -} -#define HIGH_FDCT32x32_2D_C vpx_highbd_fdct32x32_rd_c -#define HIGH_FDCT32x32_2D_ROWS_C vpx_fdct32x32_rd_rows_c -#endif // FDCT32x32_HIGH_PRECISION -#else -#define ADD_EPI16 _mm_add_epi16 -#define SUB_EPI16 _mm_sub_epi16 -#endif // DCT_HIGH_BIT_DEPTH - -void FDCT32x32_2D(const int16_t *input, tran_low_t *output_org, int stride) { - // Calculate pre-multiplied strides - const int str1 = stride; - const int str2 = 2 * stride; - const int str3 = 2 * stride + str1; - // We need an intermediate buffer between passes. - DECLARE_ALIGNED(16, int16_t, intermediate[32 * 32]); - // Constants - // When we use them, in one case, they are all the same. In all others - // it's a pair of them that we need to repeat four times. This is done - // by constructing the 32 bit constant corresponding to that pair. - const __m128i k__cospi_p16_p16 = _mm_set1_epi16(cospi_16_64); - const __m128i k__cospi_p16_m16 = pair_set_epi16(+cospi_16_64, -cospi_16_64); - const __m128i k__cospi_m08_p24 = pair_set_epi16(-cospi_8_64, cospi_24_64); - const __m128i k__cospi_m24_m08 = pair_set_epi16(-cospi_24_64, -cospi_8_64); - const __m128i k__cospi_p24_p08 = pair_set_epi16(+cospi_24_64, cospi_8_64); - const __m128i k__cospi_p12_p20 = pair_set_epi16(+cospi_12_64, cospi_20_64); - const __m128i k__cospi_m20_p12 = pair_set_epi16(-cospi_20_64, cospi_12_64); - const __m128i k__cospi_m04_p28 = pair_set_epi16(-cospi_4_64, cospi_28_64); - const __m128i k__cospi_p28_p04 = pair_set_epi16(+cospi_28_64, cospi_4_64); - const __m128i k__cospi_m28_m04 = pair_set_epi16(-cospi_28_64, -cospi_4_64); - const __m128i k__cospi_m12_m20 = pair_set_epi16(-cospi_12_64, -cospi_20_64); - const __m128i k__cospi_p30_p02 = pair_set_epi16(+cospi_30_64, cospi_2_64); - const __m128i k__cospi_p14_p18 = pair_set_epi16(+cospi_14_64, cospi_18_64); - const __m128i k__cospi_p22_p10 = pair_set_epi16(+cospi_22_64, cospi_10_64); - const __m128i k__cospi_p06_p26 = pair_set_epi16(+cospi_6_64, cospi_26_64); - const __m128i k__cospi_m26_p06 = pair_set_epi16(-cospi_26_64, cospi_6_64); - const __m128i k__cospi_m10_p22 = pair_set_epi16(-cospi_10_64, cospi_22_64); - const __m128i k__cospi_m18_p14 = pair_set_epi16(-cospi_18_64, cospi_14_64); - const __m128i k__cospi_m02_p30 = pair_set_epi16(-cospi_2_64, cospi_30_64); - const __m128i k__cospi_p31_p01 = pair_set_epi16(+cospi_31_64, cospi_1_64); - const __m128i k__cospi_p15_p17 = pair_set_epi16(+cospi_15_64, cospi_17_64); - const __m128i k__cospi_p23_p09 = pair_set_epi16(+cospi_23_64, cospi_9_64); - const __m128i k__cospi_p07_p25 = pair_set_epi16(+cospi_7_64, cospi_25_64); - const __m128i k__cospi_m25_p07 = pair_set_epi16(-cospi_25_64, cospi_7_64); - const __m128i k__cospi_m09_p23 = pair_set_epi16(-cospi_9_64, cospi_23_64); - const __m128i k__cospi_m17_p15 = pair_set_epi16(-cospi_17_64, cospi_15_64); - const __m128i k__cospi_m01_p31 = pair_set_epi16(-cospi_1_64, cospi_31_64); - const __m128i k__cospi_p27_p05 = pair_set_epi16(+cospi_27_64, cospi_5_64); - const __m128i k__cospi_p11_p21 = pair_set_epi16(+cospi_11_64, cospi_21_64); - const __m128i k__cospi_p19_p13 = pair_set_epi16(+cospi_19_64, cospi_13_64); - const __m128i k__cospi_p03_p29 = pair_set_epi16(+cospi_3_64, cospi_29_64); - const __m128i k__cospi_m29_p03 = pair_set_epi16(-cospi_29_64, cospi_3_64); - const __m128i k__cospi_m13_p19 = pair_set_epi16(-cospi_13_64, cospi_19_64); - const __m128i k__cospi_m21_p11 = pair_set_epi16(-cospi_21_64, cospi_11_64); - const __m128i k__cospi_m05_p27 = pair_set_epi16(-cospi_5_64, cospi_27_64); - const __m128i k__DCT_CONST_ROUNDING = _mm_set1_epi32(DCT_CONST_ROUNDING); - const __m128i kZero = _mm_setzero_si128(); - const __m128i kOne = _mm_set1_epi16(1); - - // Do the two transform/transpose passes - int pass; -#if DCT_HIGH_BIT_DEPTH - int overflow; -#endif - for (pass = 0; pass < 2; ++pass) { - // We process eight columns (transposed rows in second pass) at a time. - int column_start; - for (column_start = 0; column_start < 32; column_start += 8) { - __m128i step1[32]; - __m128i step2[32]; - __m128i step3[32]; - __m128i out[32]; - // Stage 1 - // Note: even though all the loads below are aligned, using the aligned - // intrinsic make the code slightly slower. - if (0 == pass) { - const int16_t *in = &input[column_start]; - // step1[i] = (in[ 0 * stride] + in[(32 - 1) * stride]) << 2; - // Note: the next four blocks could be in a loop. That would help the - // instruction cache but is actually slower. - { - const int16_t *ina = in + 0 * str1; - const int16_t *inb = in + 31 * str1; - __m128i *step1a = &step1[0]; - __m128i *step1b = &step1[31]; - const __m128i ina0 = _mm_loadu_si128((const __m128i *)(ina)); - const __m128i ina1 = _mm_loadu_si128((const __m128i *)(ina + str1)); - const __m128i ina2 = _mm_loadu_si128((const __m128i *)(ina + str2)); - const __m128i ina3 = _mm_loadu_si128((const __m128i *)(ina + str3)); - const __m128i inb3 = _mm_loadu_si128((const __m128i *)(inb - str3)); - const __m128i inb2 = _mm_loadu_si128((const __m128i *)(inb - str2)); - const __m128i inb1 = _mm_loadu_si128((const __m128i *)(inb - str1)); - const __m128i inb0 = _mm_loadu_si128((const __m128i *)(inb)); - step1a[0] = _mm_add_epi16(ina0, inb0); - step1a[1] = _mm_add_epi16(ina1, inb1); - step1a[2] = _mm_add_epi16(ina2, inb2); - step1a[3] = _mm_add_epi16(ina3, inb3); - step1b[-3] = _mm_sub_epi16(ina3, inb3); - step1b[-2] = _mm_sub_epi16(ina2, inb2); - step1b[-1] = _mm_sub_epi16(ina1, inb1); - step1b[-0] = _mm_sub_epi16(ina0, inb0); - step1a[0] = _mm_slli_epi16(step1a[0], 2); - step1a[1] = _mm_slli_epi16(step1a[1], 2); - step1a[2] = _mm_slli_epi16(step1a[2], 2); - step1a[3] = _mm_slli_epi16(step1a[3], 2); - step1b[-3] = _mm_slli_epi16(step1b[-3], 2); - step1b[-2] = _mm_slli_epi16(step1b[-2], 2); - step1b[-1] = _mm_slli_epi16(step1b[-1], 2); - step1b[-0] = _mm_slli_epi16(step1b[-0], 2); - } - { - const int16_t *ina = in + 4 * str1; - const int16_t *inb = in + 27 * str1; - __m128i *step1a = &step1[4]; - __m128i *step1b = &step1[27]; - const __m128i ina0 = _mm_loadu_si128((const __m128i *)(ina)); - const __m128i ina1 = _mm_loadu_si128((const __m128i *)(ina + str1)); - const __m128i ina2 = _mm_loadu_si128((const __m128i *)(ina + str2)); - const __m128i ina3 = _mm_loadu_si128((const __m128i *)(ina + str3)); - const __m128i inb3 = _mm_loadu_si128((const __m128i *)(inb - str3)); - const __m128i inb2 = _mm_loadu_si128((const __m128i *)(inb - str2)); - const __m128i inb1 = _mm_loadu_si128((const __m128i *)(inb - str1)); - const __m128i inb0 = _mm_loadu_si128((const __m128i *)(inb)); - step1a[0] = _mm_add_epi16(ina0, inb0); - step1a[1] = _mm_add_epi16(ina1, inb1); - step1a[2] = _mm_add_epi16(ina2, inb2); - step1a[3] = _mm_add_epi16(ina3, inb3); - step1b[-3] = _mm_sub_epi16(ina3, inb3); - step1b[-2] = _mm_sub_epi16(ina2, inb2); - step1b[-1] = _mm_sub_epi16(ina1, inb1); - step1b[-0] = _mm_sub_epi16(ina0, inb0); - step1a[0] = _mm_slli_epi16(step1a[0], 2); - step1a[1] = _mm_slli_epi16(step1a[1], 2); - step1a[2] = _mm_slli_epi16(step1a[2], 2); - step1a[3] = _mm_slli_epi16(step1a[3], 2); - step1b[-3] = _mm_slli_epi16(step1b[-3], 2); - step1b[-2] = _mm_slli_epi16(step1b[-2], 2); - step1b[-1] = _mm_slli_epi16(step1b[-1], 2); - step1b[-0] = _mm_slli_epi16(step1b[-0], 2); - } - { - const int16_t *ina = in + 8 * str1; - const int16_t *inb = in + 23 * str1; - __m128i *step1a = &step1[8]; - __m128i *step1b = &step1[23]; - const __m128i ina0 = _mm_loadu_si128((const __m128i *)(ina)); - const __m128i ina1 = _mm_loadu_si128((const __m128i *)(ina + str1)); - const __m128i ina2 = _mm_loadu_si128((const __m128i *)(ina + str2)); - const __m128i ina3 = _mm_loadu_si128((const __m128i *)(ina + str3)); - const __m128i inb3 = _mm_loadu_si128((const __m128i *)(inb - str3)); - const __m128i inb2 = _mm_loadu_si128((const __m128i *)(inb - str2)); - const __m128i inb1 = _mm_loadu_si128((const __m128i *)(inb - str1)); - const __m128i inb0 = _mm_loadu_si128((const __m128i *)(inb)); - step1a[0] = _mm_add_epi16(ina0, inb0); - step1a[1] = _mm_add_epi16(ina1, inb1); - step1a[2] = _mm_add_epi16(ina2, inb2); - step1a[3] = _mm_add_epi16(ina3, inb3); - step1b[-3] = _mm_sub_epi16(ina3, inb3); - step1b[-2] = _mm_sub_epi16(ina2, inb2); - step1b[-1] = _mm_sub_epi16(ina1, inb1); - step1b[-0] = _mm_sub_epi16(ina0, inb0); - step1a[0] = _mm_slli_epi16(step1a[0], 2); - step1a[1] = _mm_slli_epi16(step1a[1], 2); - step1a[2] = _mm_slli_epi16(step1a[2], 2); - step1a[3] = _mm_slli_epi16(step1a[3], 2); - step1b[-3] = _mm_slli_epi16(step1b[-3], 2); - step1b[-2] = _mm_slli_epi16(step1b[-2], 2); - step1b[-1] = _mm_slli_epi16(step1b[-1], 2); - step1b[-0] = _mm_slli_epi16(step1b[-0], 2); - } - { - const int16_t *ina = in + 12 * str1; - const int16_t *inb = in + 19 * str1; - __m128i *step1a = &step1[12]; - __m128i *step1b = &step1[19]; - const __m128i ina0 = _mm_loadu_si128((const __m128i *)(ina)); - const __m128i ina1 = _mm_loadu_si128((const __m128i *)(ina + str1)); - const __m128i ina2 = _mm_loadu_si128((const __m128i *)(ina + str2)); - const __m128i ina3 = _mm_loadu_si128((const __m128i *)(ina + str3)); - const __m128i inb3 = _mm_loadu_si128((const __m128i *)(inb - str3)); - const __m128i inb2 = _mm_loadu_si128((const __m128i *)(inb - str2)); - const __m128i inb1 = _mm_loadu_si128((const __m128i *)(inb - str1)); - const __m128i inb0 = _mm_loadu_si128((const __m128i *)(inb)); - step1a[0] = _mm_add_epi16(ina0, inb0); - step1a[1] = _mm_add_epi16(ina1, inb1); - step1a[2] = _mm_add_epi16(ina2, inb2); - step1a[3] = _mm_add_epi16(ina3, inb3); - step1b[-3] = _mm_sub_epi16(ina3, inb3); - step1b[-2] = _mm_sub_epi16(ina2, inb2); - step1b[-1] = _mm_sub_epi16(ina1, inb1); - step1b[-0] = _mm_sub_epi16(ina0, inb0); - step1a[0] = _mm_slli_epi16(step1a[0], 2); - step1a[1] = _mm_slli_epi16(step1a[1], 2); - step1a[2] = _mm_slli_epi16(step1a[2], 2); - step1a[3] = _mm_slli_epi16(step1a[3], 2); - step1b[-3] = _mm_slli_epi16(step1b[-3], 2); - step1b[-2] = _mm_slli_epi16(step1b[-2], 2); - step1b[-1] = _mm_slli_epi16(step1b[-1], 2); - step1b[-0] = _mm_slli_epi16(step1b[-0], 2); - } - } else { - int16_t *in = &intermediate[column_start]; - // step1[i] = in[ 0 * 32] + in[(32 - 1) * 32]; - // Note: using the same approach as above to have common offset is - // counter-productive as all offsets can be calculated at compile - // time. - // Note: the next four blocks could be in a loop. That would help the - // instruction cache but is actually slower. - { - __m128i in00 = _mm_loadu_si128((const __m128i *)(in + 0 * 32)); - __m128i in01 = _mm_loadu_si128((const __m128i *)(in + 1 * 32)); - __m128i in02 = _mm_loadu_si128((const __m128i *)(in + 2 * 32)); - __m128i in03 = _mm_loadu_si128((const __m128i *)(in + 3 * 32)); - __m128i in28 = _mm_loadu_si128((const __m128i *)(in + 28 * 32)); - __m128i in29 = _mm_loadu_si128((const __m128i *)(in + 29 * 32)); - __m128i in30 = _mm_loadu_si128((const __m128i *)(in + 30 * 32)); - __m128i in31 = _mm_loadu_si128((const __m128i *)(in + 31 * 32)); - step1[0] = ADD_EPI16(in00, in31); - step1[1] = ADD_EPI16(in01, in30); - step1[2] = ADD_EPI16(in02, in29); - step1[3] = ADD_EPI16(in03, in28); - step1[28] = SUB_EPI16(in03, in28); - step1[29] = SUB_EPI16(in02, in29); - step1[30] = SUB_EPI16(in01, in30); - step1[31] = SUB_EPI16(in00, in31); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x8(&step1[0], &step1[1], &step1[2], - &step1[3], &step1[28], &step1[29], - &step1[30], &step1[31]); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - __m128i in04 = _mm_loadu_si128((const __m128i *)(in + 4 * 32)); - __m128i in05 = _mm_loadu_si128((const __m128i *)(in + 5 * 32)); - __m128i in06 = _mm_loadu_si128((const __m128i *)(in + 6 * 32)); - __m128i in07 = _mm_loadu_si128((const __m128i *)(in + 7 * 32)); - __m128i in24 = _mm_loadu_si128((const __m128i *)(in + 24 * 32)); - __m128i in25 = _mm_loadu_si128((const __m128i *)(in + 25 * 32)); - __m128i in26 = _mm_loadu_si128((const __m128i *)(in + 26 * 32)); - __m128i in27 = _mm_loadu_si128((const __m128i *)(in + 27 * 32)); - step1[4] = ADD_EPI16(in04, in27); - step1[5] = ADD_EPI16(in05, in26); - step1[6] = ADD_EPI16(in06, in25); - step1[7] = ADD_EPI16(in07, in24); - step1[24] = SUB_EPI16(in07, in24); - step1[25] = SUB_EPI16(in06, in25); - step1[26] = SUB_EPI16(in05, in26); - step1[27] = SUB_EPI16(in04, in27); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x8(&step1[4], &step1[5], &step1[6], - &step1[7], &step1[24], &step1[25], - &step1[26], &step1[27]); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - __m128i in08 = _mm_loadu_si128((const __m128i *)(in + 8 * 32)); - __m128i in09 = _mm_loadu_si128((const __m128i *)(in + 9 * 32)); - __m128i in10 = _mm_loadu_si128((const __m128i *)(in + 10 * 32)); - __m128i in11 = _mm_loadu_si128((const __m128i *)(in + 11 * 32)); - __m128i in20 = _mm_loadu_si128((const __m128i *)(in + 20 * 32)); - __m128i in21 = _mm_loadu_si128((const __m128i *)(in + 21 * 32)); - __m128i in22 = _mm_loadu_si128((const __m128i *)(in + 22 * 32)); - __m128i in23 = _mm_loadu_si128((const __m128i *)(in + 23 * 32)); - step1[8] = ADD_EPI16(in08, in23); - step1[9] = ADD_EPI16(in09, in22); - step1[10] = ADD_EPI16(in10, in21); - step1[11] = ADD_EPI16(in11, in20); - step1[20] = SUB_EPI16(in11, in20); - step1[21] = SUB_EPI16(in10, in21); - step1[22] = SUB_EPI16(in09, in22); - step1[23] = SUB_EPI16(in08, in23); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x8(&step1[8], &step1[9], &step1[10], - &step1[11], &step1[20], &step1[21], - &step1[22], &step1[23]); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - __m128i in12 = _mm_loadu_si128((const __m128i *)(in + 12 * 32)); - __m128i in13 = _mm_loadu_si128((const __m128i *)(in + 13 * 32)); - __m128i in14 = _mm_loadu_si128((const __m128i *)(in + 14 * 32)); - __m128i in15 = _mm_loadu_si128((const __m128i *)(in + 15 * 32)); - __m128i in16 = _mm_loadu_si128((const __m128i *)(in + 16 * 32)); - __m128i in17 = _mm_loadu_si128((const __m128i *)(in + 17 * 32)); - __m128i in18 = _mm_loadu_si128((const __m128i *)(in + 18 * 32)); - __m128i in19 = _mm_loadu_si128((const __m128i *)(in + 19 * 32)); - step1[12] = ADD_EPI16(in12, in19); - step1[13] = ADD_EPI16(in13, in18); - step1[14] = ADD_EPI16(in14, in17); - step1[15] = ADD_EPI16(in15, in16); - step1[16] = SUB_EPI16(in15, in16); - step1[17] = SUB_EPI16(in14, in17); - step1[18] = SUB_EPI16(in13, in18); - step1[19] = SUB_EPI16(in12, in19); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x8(&step1[12], &step1[13], &step1[14], - &step1[15], &step1[16], &step1[17], - &step1[18], &step1[19]); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - } - // Stage 2 - { - step2[0] = ADD_EPI16(step1[0], step1[15]); - step2[1] = ADD_EPI16(step1[1], step1[14]); - step2[2] = ADD_EPI16(step1[2], step1[13]); - step2[3] = ADD_EPI16(step1[3], step1[12]); - step2[4] = ADD_EPI16(step1[4], step1[11]); - step2[5] = ADD_EPI16(step1[5], step1[10]); - step2[6] = ADD_EPI16(step1[6], step1[9]); - step2[7] = ADD_EPI16(step1[7], step1[8]); - step2[8] = SUB_EPI16(step1[7], step1[8]); - step2[9] = SUB_EPI16(step1[6], step1[9]); - step2[10] = SUB_EPI16(step1[5], step1[10]); - step2[11] = SUB_EPI16(step1[4], step1[11]); - step2[12] = SUB_EPI16(step1[3], step1[12]); - step2[13] = SUB_EPI16(step1[2], step1[13]); - step2[14] = SUB_EPI16(step1[1], step1[14]); - step2[15] = SUB_EPI16(step1[0], step1[15]); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x16( - &step2[0], &step2[1], &step2[2], &step2[3], &step2[4], &step2[5], - &step2[6], &step2[7], &step2[8], &step2[9], &step2[10], &step2[11], - &step2[12], &step2[13], &step2[14], &step2[15]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - const __m128i s2_20_0 = _mm_unpacklo_epi16(step1[27], step1[20]); - const __m128i s2_20_1 = _mm_unpackhi_epi16(step1[27], step1[20]); - const __m128i s2_21_0 = _mm_unpacklo_epi16(step1[26], step1[21]); - const __m128i s2_21_1 = _mm_unpackhi_epi16(step1[26], step1[21]); - const __m128i s2_22_0 = _mm_unpacklo_epi16(step1[25], step1[22]); - const __m128i s2_22_1 = _mm_unpackhi_epi16(step1[25], step1[22]); - const __m128i s2_23_0 = _mm_unpacklo_epi16(step1[24], step1[23]); - const __m128i s2_23_1 = _mm_unpackhi_epi16(step1[24], step1[23]); - const __m128i s2_20_2 = _mm_madd_epi16(s2_20_0, k__cospi_p16_m16); - const __m128i s2_20_3 = _mm_madd_epi16(s2_20_1, k__cospi_p16_m16); - const __m128i s2_21_2 = _mm_madd_epi16(s2_21_0, k__cospi_p16_m16); - const __m128i s2_21_3 = _mm_madd_epi16(s2_21_1, k__cospi_p16_m16); - const __m128i s2_22_2 = _mm_madd_epi16(s2_22_0, k__cospi_p16_m16); - const __m128i s2_22_3 = _mm_madd_epi16(s2_22_1, k__cospi_p16_m16); - const __m128i s2_23_2 = _mm_madd_epi16(s2_23_0, k__cospi_p16_m16); - const __m128i s2_23_3 = _mm_madd_epi16(s2_23_1, k__cospi_p16_m16); - const __m128i s2_24_2 = _mm_madd_epi16(s2_23_0, k__cospi_p16_p16); - const __m128i s2_24_3 = _mm_madd_epi16(s2_23_1, k__cospi_p16_p16); - const __m128i s2_25_2 = _mm_madd_epi16(s2_22_0, k__cospi_p16_p16); - const __m128i s2_25_3 = _mm_madd_epi16(s2_22_1, k__cospi_p16_p16); - const __m128i s2_26_2 = _mm_madd_epi16(s2_21_0, k__cospi_p16_p16); - const __m128i s2_26_3 = _mm_madd_epi16(s2_21_1, k__cospi_p16_p16); - const __m128i s2_27_2 = _mm_madd_epi16(s2_20_0, k__cospi_p16_p16); - const __m128i s2_27_3 = _mm_madd_epi16(s2_20_1, k__cospi_p16_p16); - // dct_const_round_shift - const __m128i s2_20_4 = _mm_add_epi32(s2_20_2, k__DCT_CONST_ROUNDING); - const __m128i s2_20_5 = _mm_add_epi32(s2_20_3, k__DCT_CONST_ROUNDING); - const __m128i s2_21_4 = _mm_add_epi32(s2_21_2, k__DCT_CONST_ROUNDING); - const __m128i s2_21_5 = _mm_add_epi32(s2_21_3, k__DCT_CONST_ROUNDING); - const __m128i s2_22_4 = _mm_add_epi32(s2_22_2, k__DCT_CONST_ROUNDING); - const __m128i s2_22_5 = _mm_add_epi32(s2_22_3, k__DCT_CONST_ROUNDING); - const __m128i s2_23_4 = _mm_add_epi32(s2_23_2, k__DCT_CONST_ROUNDING); - const __m128i s2_23_5 = _mm_add_epi32(s2_23_3, k__DCT_CONST_ROUNDING); - const __m128i s2_24_4 = _mm_add_epi32(s2_24_2, k__DCT_CONST_ROUNDING); - const __m128i s2_24_5 = _mm_add_epi32(s2_24_3, k__DCT_CONST_ROUNDING); - const __m128i s2_25_4 = _mm_add_epi32(s2_25_2, k__DCT_CONST_ROUNDING); - const __m128i s2_25_5 = _mm_add_epi32(s2_25_3, k__DCT_CONST_ROUNDING); - const __m128i s2_26_4 = _mm_add_epi32(s2_26_2, k__DCT_CONST_ROUNDING); - const __m128i s2_26_5 = _mm_add_epi32(s2_26_3, k__DCT_CONST_ROUNDING); - const __m128i s2_27_4 = _mm_add_epi32(s2_27_2, k__DCT_CONST_ROUNDING); - const __m128i s2_27_5 = _mm_add_epi32(s2_27_3, k__DCT_CONST_ROUNDING); - const __m128i s2_20_6 = _mm_srai_epi32(s2_20_4, DCT_CONST_BITS); - const __m128i s2_20_7 = _mm_srai_epi32(s2_20_5, DCT_CONST_BITS); - const __m128i s2_21_6 = _mm_srai_epi32(s2_21_4, DCT_CONST_BITS); - const __m128i s2_21_7 = _mm_srai_epi32(s2_21_5, DCT_CONST_BITS); - const __m128i s2_22_6 = _mm_srai_epi32(s2_22_4, DCT_CONST_BITS); - const __m128i s2_22_7 = _mm_srai_epi32(s2_22_5, DCT_CONST_BITS); - const __m128i s2_23_6 = _mm_srai_epi32(s2_23_4, DCT_CONST_BITS); - const __m128i s2_23_7 = _mm_srai_epi32(s2_23_5, DCT_CONST_BITS); - const __m128i s2_24_6 = _mm_srai_epi32(s2_24_4, DCT_CONST_BITS); - const __m128i s2_24_7 = _mm_srai_epi32(s2_24_5, DCT_CONST_BITS); - const __m128i s2_25_6 = _mm_srai_epi32(s2_25_4, DCT_CONST_BITS); - const __m128i s2_25_7 = _mm_srai_epi32(s2_25_5, DCT_CONST_BITS); - const __m128i s2_26_6 = _mm_srai_epi32(s2_26_4, DCT_CONST_BITS); - const __m128i s2_26_7 = _mm_srai_epi32(s2_26_5, DCT_CONST_BITS); - const __m128i s2_27_6 = _mm_srai_epi32(s2_27_4, DCT_CONST_BITS); - const __m128i s2_27_7 = _mm_srai_epi32(s2_27_5, DCT_CONST_BITS); - // Combine - step2[20] = _mm_packs_epi32(s2_20_6, s2_20_7); - step2[21] = _mm_packs_epi32(s2_21_6, s2_21_7); - step2[22] = _mm_packs_epi32(s2_22_6, s2_22_7); - step2[23] = _mm_packs_epi32(s2_23_6, s2_23_7); - step2[24] = _mm_packs_epi32(s2_24_6, s2_24_7); - step2[25] = _mm_packs_epi32(s2_25_6, s2_25_7); - step2[26] = _mm_packs_epi32(s2_26_6, s2_26_7); - step2[27] = _mm_packs_epi32(s2_27_6, s2_27_7); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x8(&step2[20], &step2[21], &step2[22], - &step2[23], &step2[24], &step2[25], - &step2[26], &step2[27]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - -#if !FDCT32x32_HIGH_PRECISION - // dump the magnitude by half, hence the intermediate values are within - // the range of 16 bits. - if (1 == pass) { - __m128i s3_00_0 = _mm_cmplt_epi16(step2[0], kZero); - __m128i s3_01_0 = _mm_cmplt_epi16(step2[1], kZero); - __m128i s3_02_0 = _mm_cmplt_epi16(step2[2], kZero); - __m128i s3_03_0 = _mm_cmplt_epi16(step2[3], kZero); - __m128i s3_04_0 = _mm_cmplt_epi16(step2[4], kZero); - __m128i s3_05_0 = _mm_cmplt_epi16(step2[5], kZero); - __m128i s3_06_0 = _mm_cmplt_epi16(step2[6], kZero); - __m128i s3_07_0 = _mm_cmplt_epi16(step2[7], kZero); - __m128i s2_08_0 = _mm_cmplt_epi16(step2[8], kZero); - __m128i s2_09_0 = _mm_cmplt_epi16(step2[9], kZero); - __m128i s3_10_0 = _mm_cmplt_epi16(step2[10], kZero); - __m128i s3_11_0 = _mm_cmplt_epi16(step2[11], kZero); - __m128i s3_12_0 = _mm_cmplt_epi16(step2[12], kZero); - __m128i s3_13_0 = _mm_cmplt_epi16(step2[13], kZero); - __m128i s2_14_0 = _mm_cmplt_epi16(step2[14], kZero); - __m128i s2_15_0 = _mm_cmplt_epi16(step2[15], kZero); - __m128i s3_16_0 = _mm_cmplt_epi16(step1[16], kZero); - __m128i s3_17_0 = _mm_cmplt_epi16(step1[17], kZero); - __m128i s3_18_0 = _mm_cmplt_epi16(step1[18], kZero); - __m128i s3_19_0 = _mm_cmplt_epi16(step1[19], kZero); - __m128i s3_20_0 = _mm_cmplt_epi16(step2[20], kZero); - __m128i s3_21_0 = _mm_cmplt_epi16(step2[21], kZero); - __m128i s3_22_0 = _mm_cmplt_epi16(step2[22], kZero); - __m128i s3_23_0 = _mm_cmplt_epi16(step2[23], kZero); - __m128i s3_24_0 = _mm_cmplt_epi16(step2[24], kZero); - __m128i s3_25_0 = _mm_cmplt_epi16(step2[25], kZero); - __m128i s3_26_0 = _mm_cmplt_epi16(step2[26], kZero); - __m128i s3_27_0 = _mm_cmplt_epi16(step2[27], kZero); - __m128i s3_28_0 = _mm_cmplt_epi16(step1[28], kZero); - __m128i s3_29_0 = _mm_cmplt_epi16(step1[29], kZero); - __m128i s3_30_0 = _mm_cmplt_epi16(step1[30], kZero); - __m128i s3_31_0 = _mm_cmplt_epi16(step1[31], kZero); - - step2[0] = SUB_EPI16(step2[0], s3_00_0); - step2[1] = SUB_EPI16(step2[1], s3_01_0); - step2[2] = SUB_EPI16(step2[2], s3_02_0); - step2[3] = SUB_EPI16(step2[3], s3_03_0); - step2[4] = SUB_EPI16(step2[4], s3_04_0); - step2[5] = SUB_EPI16(step2[5], s3_05_0); - step2[6] = SUB_EPI16(step2[6], s3_06_0); - step2[7] = SUB_EPI16(step2[7], s3_07_0); - step2[8] = SUB_EPI16(step2[8], s2_08_0); - step2[9] = SUB_EPI16(step2[9], s2_09_0); - step2[10] = SUB_EPI16(step2[10], s3_10_0); - step2[11] = SUB_EPI16(step2[11], s3_11_0); - step2[12] = SUB_EPI16(step2[12], s3_12_0); - step2[13] = SUB_EPI16(step2[13], s3_13_0); - step2[14] = SUB_EPI16(step2[14], s2_14_0); - step2[15] = SUB_EPI16(step2[15], s2_15_0); - step1[16] = SUB_EPI16(step1[16], s3_16_0); - step1[17] = SUB_EPI16(step1[17], s3_17_0); - step1[18] = SUB_EPI16(step1[18], s3_18_0); - step1[19] = SUB_EPI16(step1[19], s3_19_0); - step2[20] = SUB_EPI16(step2[20], s3_20_0); - step2[21] = SUB_EPI16(step2[21], s3_21_0); - step2[22] = SUB_EPI16(step2[22], s3_22_0); - step2[23] = SUB_EPI16(step2[23], s3_23_0); - step2[24] = SUB_EPI16(step2[24], s3_24_0); - step2[25] = SUB_EPI16(step2[25], s3_25_0); - step2[26] = SUB_EPI16(step2[26], s3_26_0); - step2[27] = SUB_EPI16(step2[27], s3_27_0); - step1[28] = SUB_EPI16(step1[28], s3_28_0); - step1[29] = SUB_EPI16(step1[29], s3_29_0); - step1[30] = SUB_EPI16(step1[30], s3_30_0); - step1[31] = SUB_EPI16(step1[31], s3_31_0); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x32( - &step2[0], &step2[1], &step2[2], &step2[3], &step2[4], &step2[5], - &step2[6], &step2[7], &step2[8], &step2[9], &step2[10], &step2[11], - &step2[12], &step2[13], &step2[14], &step2[15], &step1[16], - &step1[17], &step1[18], &step1[19], &step2[20], &step2[21], - &step2[22], &step2[23], &step2[24], &step2[25], &step2[26], - &step2[27], &step1[28], &step1[29], &step1[30], &step1[31]); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - step2[0] = _mm_add_epi16(step2[0], kOne); - step2[1] = _mm_add_epi16(step2[1], kOne); - step2[2] = _mm_add_epi16(step2[2], kOne); - step2[3] = _mm_add_epi16(step2[3], kOne); - step2[4] = _mm_add_epi16(step2[4], kOne); - step2[5] = _mm_add_epi16(step2[5], kOne); - step2[6] = _mm_add_epi16(step2[6], kOne); - step2[7] = _mm_add_epi16(step2[7], kOne); - step2[8] = _mm_add_epi16(step2[8], kOne); - step2[9] = _mm_add_epi16(step2[9], kOne); - step2[10] = _mm_add_epi16(step2[10], kOne); - step2[11] = _mm_add_epi16(step2[11], kOne); - step2[12] = _mm_add_epi16(step2[12], kOne); - step2[13] = _mm_add_epi16(step2[13], kOne); - step2[14] = _mm_add_epi16(step2[14], kOne); - step2[15] = _mm_add_epi16(step2[15], kOne); - step1[16] = _mm_add_epi16(step1[16], kOne); - step1[17] = _mm_add_epi16(step1[17], kOne); - step1[18] = _mm_add_epi16(step1[18], kOne); - step1[19] = _mm_add_epi16(step1[19], kOne); - step2[20] = _mm_add_epi16(step2[20], kOne); - step2[21] = _mm_add_epi16(step2[21], kOne); - step2[22] = _mm_add_epi16(step2[22], kOne); - step2[23] = _mm_add_epi16(step2[23], kOne); - step2[24] = _mm_add_epi16(step2[24], kOne); - step2[25] = _mm_add_epi16(step2[25], kOne); - step2[26] = _mm_add_epi16(step2[26], kOne); - step2[27] = _mm_add_epi16(step2[27], kOne); - step1[28] = _mm_add_epi16(step1[28], kOne); - step1[29] = _mm_add_epi16(step1[29], kOne); - step1[30] = _mm_add_epi16(step1[30], kOne); - step1[31] = _mm_add_epi16(step1[31], kOne); - - step2[0] = _mm_srai_epi16(step2[0], 2); - step2[1] = _mm_srai_epi16(step2[1], 2); - step2[2] = _mm_srai_epi16(step2[2], 2); - step2[3] = _mm_srai_epi16(step2[3], 2); - step2[4] = _mm_srai_epi16(step2[4], 2); - step2[5] = _mm_srai_epi16(step2[5], 2); - step2[6] = _mm_srai_epi16(step2[6], 2); - step2[7] = _mm_srai_epi16(step2[7], 2); - step2[8] = _mm_srai_epi16(step2[8], 2); - step2[9] = _mm_srai_epi16(step2[9], 2); - step2[10] = _mm_srai_epi16(step2[10], 2); - step2[11] = _mm_srai_epi16(step2[11], 2); - step2[12] = _mm_srai_epi16(step2[12], 2); - step2[13] = _mm_srai_epi16(step2[13], 2); - step2[14] = _mm_srai_epi16(step2[14], 2); - step2[15] = _mm_srai_epi16(step2[15], 2); - step1[16] = _mm_srai_epi16(step1[16], 2); - step1[17] = _mm_srai_epi16(step1[17], 2); - step1[18] = _mm_srai_epi16(step1[18], 2); - step1[19] = _mm_srai_epi16(step1[19], 2); - step2[20] = _mm_srai_epi16(step2[20], 2); - step2[21] = _mm_srai_epi16(step2[21], 2); - step2[22] = _mm_srai_epi16(step2[22], 2); - step2[23] = _mm_srai_epi16(step2[23], 2); - step2[24] = _mm_srai_epi16(step2[24], 2); - step2[25] = _mm_srai_epi16(step2[25], 2); - step2[26] = _mm_srai_epi16(step2[26], 2); - step2[27] = _mm_srai_epi16(step2[27], 2); - step1[28] = _mm_srai_epi16(step1[28], 2); - step1[29] = _mm_srai_epi16(step1[29], 2); - step1[30] = _mm_srai_epi16(step1[30], 2); - step1[31] = _mm_srai_epi16(step1[31], 2); - } -#endif // !FDCT32x32_HIGH_PRECISION - -#if FDCT32x32_HIGH_PRECISION - if (pass == 0) { -#endif - // Stage 3 - { - step3[0] = ADD_EPI16(step2[(8 - 1)], step2[0]); - step3[1] = ADD_EPI16(step2[(8 - 2)], step2[1]); - step3[2] = ADD_EPI16(step2[(8 - 3)], step2[2]); - step3[3] = ADD_EPI16(step2[(8 - 4)], step2[3]); - step3[4] = SUB_EPI16(step2[(8 - 5)], step2[4]); - step3[5] = SUB_EPI16(step2[(8 - 6)], step2[5]); - step3[6] = SUB_EPI16(step2[(8 - 7)], step2[6]); - step3[7] = SUB_EPI16(step2[(8 - 8)], step2[7]); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x8(&step3[0], &step3[1], &step3[2], - &step3[3], &step3[4], &step3[5], - &step3[6], &step3[7]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - const __m128i s3_10_0 = _mm_unpacklo_epi16(step2[13], step2[10]); - const __m128i s3_10_1 = _mm_unpackhi_epi16(step2[13], step2[10]); - const __m128i s3_11_0 = _mm_unpacklo_epi16(step2[12], step2[11]); - const __m128i s3_11_1 = _mm_unpackhi_epi16(step2[12], step2[11]); - const __m128i s3_10_2 = _mm_madd_epi16(s3_10_0, k__cospi_p16_m16); - const __m128i s3_10_3 = _mm_madd_epi16(s3_10_1, k__cospi_p16_m16); - const __m128i s3_11_2 = _mm_madd_epi16(s3_11_0, k__cospi_p16_m16); - const __m128i s3_11_3 = _mm_madd_epi16(s3_11_1, k__cospi_p16_m16); - const __m128i s3_12_2 = _mm_madd_epi16(s3_11_0, k__cospi_p16_p16); - const __m128i s3_12_3 = _mm_madd_epi16(s3_11_1, k__cospi_p16_p16); - const __m128i s3_13_2 = _mm_madd_epi16(s3_10_0, k__cospi_p16_p16); - const __m128i s3_13_3 = _mm_madd_epi16(s3_10_1, k__cospi_p16_p16); - // dct_const_round_shift - const __m128i s3_10_4 = _mm_add_epi32(s3_10_2, k__DCT_CONST_ROUNDING); - const __m128i s3_10_5 = _mm_add_epi32(s3_10_3, k__DCT_CONST_ROUNDING); - const __m128i s3_11_4 = _mm_add_epi32(s3_11_2, k__DCT_CONST_ROUNDING); - const __m128i s3_11_5 = _mm_add_epi32(s3_11_3, k__DCT_CONST_ROUNDING); - const __m128i s3_12_4 = _mm_add_epi32(s3_12_2, k__DCT_CONST_ROUNDING); - const __m128i s3_12_5 = _mm_add_epi32(s3_12_3, k__DCT_CONST_ROUNDING); - const __m128i s3_13_4 = _mm_add_epi32(s3_13_2, k__DCT_CONST_ROUNDING); - const __m128i s3_13_5 = _mm_add_epi32(s3_13_3, k__DCT_CONST_ROUNDING); - const __m128i s3_10_6 = _mm_srai_epi32(s3_10_4, DCT_CONST_BITS); - const __m128i s3_10_7 = _mm_srai_epi32(s3_10_5, DCT_CONST_BITS); - const __m128i s3_11_6 = _mm_srai_epi32(s3_11_4, DCT_CONST_BITS); - const __m128i s3_11_7 = _mm_srai_epi32(s3_11_5, DCT_CONST_BITS); - const __m128i s3_12_6 = _mm_srai_epi32(s3_12_4, DCT_CONST_BITS); - const __m128i s3_12_7 = _mm_srai_epi32(s3_12_5, DCT_CONST_BITS); - const __m128i s3_13_6 = _mm_srai_epi32(s3_13_4, DCT_CONST_BITS); - const __m128i s3_13_7 = _mm_srai_epi32(s3_13_5, DCT_CONST_BITS); - // Combine - step3[10] = _mm_packs_epi32(s3_10_6, s3_10_7); - step3[11] = _mm_packs_epi32(s3_11_6, s3_11_7); - step3[12] = _mm_packs_epi32(s3_12_6, s3_12_7); - step3[13] = _mm_packs_epi32(s3_13_6, s3_13_7); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x4(&step3[10], &step3[11], &step3[12], - &step3[13]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - step3[16] = ADD_EPI16(step2[23], step1[16]); - step3[17] = ADD_EPI16(step2[22], step1[17]); - step3[18] = ADD_EPI16(step2[21], step1[18]); - step3[19] = ADD_EPI16(step2[20], step1[19]); - step3[20] = SUB_EPI16(step1[19], step2[20]); - step3[21] = SUB_EPI16(step1[18], step2[21]); - step3[22] = SUB_EPI16(step1[17], step2[22]); - step3[23] = SUB_EPI16(step1[16], step2[23]); - step3[24] = SUB_EPI16(step1[31], step2[24]); - step3[25] = SUB_EPI16(step1[30], step2[25]); - step3[26] = SUB_EPI16(step1[29], step2[26]); - step3[27] = SUB_EPI16(step1[28], step2[27]); - step3[28] = ADD_EPI16(step2[27], step1[28]); - step3[29] = ADD_EPI16(step2[26], step1[29]); - step3[30] = ADD_EPI16(step2[25], step1[30]); - step3[31] = ADD_EPI16(step2[24], step1[31]); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x16( - &step3[16], &step3[17], &step3[18], &step3[19], &step3[20], - &step3[21], &step3[22], &step3[23], &step3[24], &step3[25], - &step3[26], &step3[27], &step3[28], &step3[29], &step3[30], - &step3[31]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - - // Stage 4 - { - step1[0] = ADD_EPI16(step3[3], step3[0]); - step1[1] = ADD_EPI16(step3[2], step3[1]); - step1[2] = SUB_EPI16(step3[1], step3[2]); - step1[3] = SUB_EPI16(step3[0], step3[3]); - step1[8] = ADD_EPI16(step3[11], step2[8]); - step1[9] = ADD_EPI16(step3[10], step2[9]); - step1[10] = SUB_EPI16(step2[9], step3[10]); - step1[11] = SUB_EPI16(step2[8], step3[11]); - step1[12] = SUB_EPI16(step2[15], step3[12]); - step1[13] = SUB_EPI16(step2[14], step3[13]); - step1[14] = ADD_EPI16(step3[13], step2[14]); - step1[15] = ADD_EPI16(step3[12], step2[15]); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x16( - &step1[0], &step1[1], &step1[2], &step1[3], &step1[4], &step1[5], - &step1[6], &step1[7], &step1[8], &step1[9], &step1[10], - &step1[11], &step1[12], &step1[13], &step1[14], &step1[15]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - const __m128i s1_05_0 = _mm_unpacklo_epi16(step3[6], step3[5]); - const __m128i s1_05_1 = _mm_unpackhi_epi16(step3[6], step3[5]); - const __m128i s1_05_2 = _mm_madd_epi16(s1_05_0, k__cospi_p16_m16); - const __m128i s1_05_3 = _mm_madd_epi16(s1_05_1, k__cospi_p16_m16); - const __m128i s1_06_2 = _mm_madd_epi16(s1_05_0, k__cospi_p16_p16); - const __m128i s1_06_3 = _mm_madd_epi16(s1_05_1, k__cospi_p16_p16); - // dct_const_round_shift - const __m128i s1_05_4 = _mm_add_epi32(s1_05_2, k__DCT_CONST_ROUNDING); - const __m128i s1_05_5 = _mm_add_epi32(s1_05_3, k__DCT_CONST_ROUNDING); - const __m128i s1_06_4 = _mm_add_epi32(s1_06_2, k__DCT_CONST_ROUNDING); - const __m128i s1_06_5 = _mm_add_epi32(s1_06_3, k__DCT_CONST_ROUNDING); - const __m128i s1_05_6 = _mm_srai_epi32(s1_05_4, DCT_CONST_BITS); - const __m128i s1_05_7 = _mm_srai_epi32(s1_05_5, DCT_CONST_BITS); - const __m128i s1_06_6 = _mm_srai_epi32(s1_06_4, DCT_CONST_BITS); - const __m128i s1_06_7 = _mm_srai_epi32(s1_06_5, DCT_CONST_BITS); - // Combine - step1[5] = _mm_packs_epi32(s1_05_6, s1_05_7); - step1[6] = _mm_packs_epi32(s1_06_6, s1_06_7); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x2(&step1[5], &step1[6]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - const __m128i s1_18_0 = _mm_unpacklo_epi16(step3[18], step3[29]); - const __m128i s1_18_1 = _mm_unpackhi_epi16(step3[18], step3[29]); - const __m128i s1_19_0 = _mm_unpacklo_epi16(step3[19], step3[28]); - const __m128i s1_19_1 = _mm_unpackhi_epi16(step3[19], step3[28]); - const __m128i s1_20_0 = _mm_unpacklo_epi16(step3[20], step3[27]); - const __m128i s1_20_1 = _mm_unpackhi_epi16(step3[20], step3[27]); - const __m128i s1_21_0 = _mm_unpacklo_epi16(step3[21], step3[26]); - const __m128i s1_21_1 = _mm_unpackhi_epi16(step3[21], step3[26]); - const __m128i s1_18_2 = _mm_madd_epi16(s1_18_0, k__cospi_m08_p24); - const __m128i s1_18_3 = _mm_madd_epi16(s1_18_1, k__cospi_m08_p24); - const __m128i s1_19_2 = _mm_madd_epi16(s1_19_0, k__cospi_m08_p24); - const __m128i s1_19_3 = _mm_madd_epi16(s1_19_1, k__cospi_m08_p24); - const __m128i s1_20_2 = _mm_madd_epi16(s1_20_0, k__cospi_m24_m08); - const __m128i s1_20_3 = _mm_madd_epi16(s1_20_1, k__cospi_m24_m08); - const __m128i s1_21_2 = _mm_madd_epi16(s1_21_0, k__cospi_m24_m08); - const __m128i s1_21_3 = _mm_madd_epi16(s1_21_1, k__cospi_m24_m08); - const __m128i s1_26_2 = _mm_madd_epi16(s1_21_0, k__cospi_m08_p24); - const __m128i s1_26_3 = _mm_madd_epi16(s1_21_1, k__cospi_m08_p24); - const __m128i s1_27_2 = _mm_madd_epi16(s1_20_0, k__cospi_m08_p24); - const __m128i s1_27_3 = _mm_madd_epi16(s1_20_1, k__cospi_m08_p24); - const __m128i s1_28_2 = _mm_madd_epi16(s1_19_0, k__cospi_p24_p08); - const __m128i s1_28_3 = _mm_madd_epi16(s1_19_1, k__cospi_p24_p08); - const __m128i s1_29_2 = _mm_madd_epi16(s1_18_0, k__cospi_p24_p08); - const __m128i s1_29_3 = _mm_madd_epi16(s1_18_1, k__cospi_p24_p08); - // dct_const_round_shift - const __m128i s1_18_4 = _mm_add_epi32(s1_18_2, k__DCT_CONST_ROUNDING); - const __m128i s1_18_5 = _mm_add_epi32(s1_18_3, k__DCT_CONST_ROUNDING); - const __m128i s1_19_4 = _mm_add_epi32(s1_19_2, k__DCT_CONST_ROUNDING); - const __m128i s1_19_5 = _mm_add_epi32(s1_19_3, k__DCT_CONST_ROUNDING); - const __m128i s1_20_4 = _mm_add_epi32(s1_20_2, k__DCT_CONST_ROUNDING); - const __m128i s1_20_5 = _mm_add_epi32(s1_20_3, k__DCT_CONST_ROUNDING); - const __m128i s1_21_4 = _mm_add_epi32(s1_21_2, k__DCT_CONST_ROUNDING); - const __m128i s1_21_5 = _mm_add_epi32(s1_21_3, k__DCT_CONST_ROUNDING); - const __m128i s1_26_4 = _mm_add_epi32(s1_26_2, k__DCT_CONST_ROUNDING); - const __m128i s1_26_5 = _mm_add_epi32(s1_26_3, k__DCT_CONST_ROUNDING); - const __m128i s1_27_4 = _mm_add_epi32(s1_27_2, k__DCT_CONST_ROUNDING); - const __m128i s1_27_5 = _mm_add_epi32(s1_27_3, k__DCT_CONST_ROUNDING); - const __m128i s1_28_4 = _mm_add_epi32(s1_28_2, k__DCT_CONST_ROUNDING); - const __m128i s1_28_5 = _mm_add_epi32(s1_28_3, k__DCT_CONST_ROUNDING); - const __m128i s1_29_4 = _mm_add_epi32(s1_29_2, k__DCT_CONST_ROUNDING); - const __m128i s1_29_5 = _mm_add_epi32(s1_29_3, k__DCT_CONST_ROUNDING); - const __m128i s1_18_6 = _mm_srai_epi32(s1_18_4, DCT_CONST_BITS); - const __m128i s1_18_7 = _mm_srai_epi32(s1_18_5, DCT_CONST_BITS); - const __m128i s1_19_6 = _mm_srai_epi32(s1_19_4, DCT_CONST_BITS); - const __m128i s1_19_7 = _mm_srai_epi32(s1_19_5, DCT_CONST_BITS); - const __m128i s1_20_6 = _mm_srai_epi32(s1_20_4, DCT_CONST_BITS); - const __m128i s1_20_7 = _mm_srai_epi32(s1_20_5, DCT_CONST_BITS); - const __m128i s1_21_6 = _mm_srai_epi32(s1_21_4, DCT_CONST_BITS); - const __m128i s1_21_7 = _mm_srai_epi32(s1_21_5, DCT_CONST_BITS); - const __m128i s1_26_6 = _mm_srai_epi32(s1_26_4, DCT_CONST_BITS); - const __m128i s1_26_7 = _mm_srai_epi32(s1_26_5, DCT_CONST_BITS); - const __m128i s1_27_6 = _mm_srai_epi32(s1_27_4, DCT_CONST_BITS); - const __m128i s1_27_7 = _mm_srai_epi32(s1_27_5, DCT_CONST_BITS); - const __m128i s1_28_6 = _mm_srai_epi32(s1_28_4, DCT_CONST_BITS); - const __m128i s1_28_7 = _mm_srai_epi32(s1_28_5, DCT_CONST_BITS); - const __m128i s1_29_6 = _mm_srai_epi32(s1_29_4, DCT_CONST_BITS); - const __m128i s1_29_7 = _mm_srai_epi32(s1_29_5, DCT_CONST_BITS); - // Combine - step1[18] = _mm_packs_epi32(s1_18_6, s1_18_7); - step1[19] = _mm_packs_epi32(s1_19_6, s1_19_7); - step1[20] = _mm_packs_epi32(s1_20_6, s1_20_7); - step1[21] = _mm_packs_epi32(s1_21_6, s1_21_7); - step1[26] = _mm_packs_epi32(s1_26_6, s1_26_7); - step1[27] = _mm_packs_epi32(s1_27_6, s1_27_7); - step1[28] = _mm_packs_epi32(s1_28_6, s1_28_7); - step1[29] = _mm_packs_epi32(s1_29_6, s1_29_7); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x8(&step1[18], &step1[19], &step1[20], - &step1[21], &step1[26], &step1[27], - &step1[28], &step1[29]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - // Stage 5 - { - step2[4] = ADD_EPI16(step1[5], step3[4]); - step2[5] = SUB_EPI16(step3[4], step1[5]); - step2[6] = SUB_EPI16(step3[7], step1[6]); - step2[7] = ADD_EPI16(step1[6], step3[7]); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x4(&step2[4], &step2[5], &step2[6], - &step2[7]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - const __m128i out_00_0 = _mm_unpacklo_epi16(step1[0], step1[1]); - const __m128i out_00_1 = _mm_unpackhi_epi16(step1[0], step1[1]); - const __m128i out_08_0 = _mm_unpacklo_epi16(step1[2], step1[3]); - const __m128i out_08_1 = _mm_unpackhi_epi16(step1[2], step1[3]); - const __m128i out_00_2 = _mm_madd_epi16(out_00_0, k__cospi_p16_p16); - const __m128i out_00_3 = _mm_madd_epi16(out_00_1, k__cospi_p16_p16); - const __m128i out_16_2 = _mm_madd_epi16(out_00_0, k__cospi_p16_m16); - const __m128i out_16_3 = _mm_madd_epi16(out_00_1, k__cospi_p16_m16); - const __m128i out_08_2 = _mm_madd_epi16(out_08_0, k__cospi_p24_p08); - const __m128i out_08_3 = _mm_madd_epi16(out_08_1, k__cospi_p24_p08); - const __m128i out_24_2 = _mm_madd_epi16(out_08_0, k__cospi_m08_p24); - const __m128i out_24_3 = _mm_madd_epi16(out_08_1, k__cospi_m08_p24); - // dct_const_round_shift - const __m128i out_00_4 = - _mm_add_epi32(out_00_2, k__DCT_CONST_ROUNDING); - const __m128i out_00_5 = - _mm_add_epi32(out_00_3, k__DCT_CONST_ROUNDING); - const __m128i out_16_4 = - _mm_add_epi32(out_16_2, k__DCT_CONST_ROUNDING); - const __m128i out_16_5 = - _mm_add_epi32(out_16_3, k__DCT_CONST_ROUNDING); - const __m128i out_08_4 = - _mm_add_epi32(out_08_2, k__DCT_CONST_ROUNDING); - const __m128i out_08_5 = - _mm_add_epi32(out_08_3, k__DCT_CONST_ROUNDING); - const __m128i out_24_4 = - _mm_add_epi32(out_24_2, k__DCT_CONST_ROUNDING); - const __m128i out_24_5 = - _mm_add_epi32(out_24_3, k__DCT_CONST_ROUNDING); - const __m128i out_00_6 = _mm_srai_epi32(out_00_4, DCT_CONST_BITS); - const __m128i out_00_7 = _mm_srai_epi32(out_00_5, DCT_CONST_BITS); - const __m128i out_16_6 = _mm_srai_epi32(out_16_4, DCT_CONST_BITS); - const __m128i out_16_7 = _mm_srai_epi32(out_16_5, DCT_CONST_BITS); - const __m128i out_08_6 = _mm_srai_epi32(out_08_4, DCT_CONST_BITS); - const __m128i out_08_7 = _mm_srai_epi32(out_08_5, DCT_CONST_BITS); - const __m128i out_24_6 = _mm_srai_epi32(out_24_4, DCT_CONST_BITS); - const __m128i out_24_7 = _mm_srai_epi32(out_24_5, DCT_CONST_BITS); - // Combine - out[0] = _mm_packs_epi32(out_00_6, out_00_7); - out[16] = _mm_packs_epi32(out_16_6, out_16_7); - out[8] = _mm_packs_epi32(out_08_6, out_08_7); - out[24] = _mm_packs_epi32(out_24_6, out_24_7); -#if DCT_HIGH_BIT_DEPTH - overflow = - check_epi16_overflow_x4(&out[0], &out[16], &out[8], &out[24]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - const __m128i s2_09_0 = _mm_unpacklo_epi16(step1[9], step1[14]); - const __m128i s2_09_1 = _mm_unpackhi_epi16(step1[9], step1[14]); - const __m128i s2_10_0 = _mm_unpacklo_epi16(step1[10], step1[13]); - const __m128i s2_10_1 = _mm_unpackhi_epi16(step1[10], step1[13]); - const __m128i s2_09_2 = _mm_madd_epi16(s2_09_0, k__cospi_m08_p24); - const __m128i s2_09_3 = _mm_madd_epi16(s2_09_1, k__cospi_m08_p24); - const __m128i s2_10_2 = _mm_madd_epi16(s2_10_0, k__cospi_m24_m08); - const __m128i s2_10_3 = _mm_madd_epi16(s2_10_1, k__cospi_m24_m08); - const __m128i s2_13_2 = _mm_madd_epi16(s2_10_0, k__cospi_m08_p24); - const __m128i s2_13_3 = _mm_madd_epi16(s2_10_1, k__cospi_m08_p24); - const __m128i s2_14_2 = _mm_madd_epi16(s2_09_0, k__cospi_p24_p08); - const __m128i s2_14_3 = _mm_madd_epi16(s2_09_1, k__cospi_p24_p08); - // dct_const_round_shift - const __m128i s2_09_4 = _mm_add_epi32(s2_09_2, k__DCT_CONST_ROUNDING); - const __m128i s2_09_5 = _mm_add_epi32(s2_09_3, k__DCT_CONST_ROUNDING); - const __m128i s2_10_4 = _mm_add_epi32(s2_10_2, k__DCT_CONST_ROUNDING); - const __m128i s2_10_5 = _mm_add_epi32(s2_10_3, k__DCT_CONST_ROUNDING); - const __m128i s2_13_4 = _mm_add_epi32(s2_13_2, k__DCT_CONST_ROUNDING); - const __m128i s2_13_5 = _mm_add_epi32(s2_13_3, k__DCT_CONST_ROUNDING); - const __m128i s2_14_4 = _mm_add_epi32(s2_14_2, k__DCT_CONST_ROUNDING); - const __m128i s2_14_5 = _mm_add_epi32(s2_14_3, k__DCT_CONST_ROUNDING); - const __m128i s2_09_6 = _mm_srai_epi32(s2_09_4, DCT_CONST_BITS); - const __m128i s2_09_7 = _mm_srai_epi32(s2_09_5, DCT_CONST_BITS); - const __m128i s2_10_6 = _mm_srai_epi32(s2_10_4, DCT_CONST_BITS); - const __m128i s2_10_7 = _mm_srai_epi32(s2_10_5, DCT_CONST_BITS); - const __m128i s2_13_6 = _mm_srai_epi32(s2_13_4, DCT_CONST_BITS); - const __m128i s2_13_7 = _mm_srai_epi32(s2_13_5, DCT_CONST_BITS); - const __m128i s2_14_6 = _mm_srai_epi32(s2_14_4, DCT_CONST_BITS); - const __m128i s2_14_7 = _mm_srai_epi32(s2_14_5, DCT_CONST_BITS); - // Combine - step2[9] = _mm_packs_epi32(s2_09_6, s2_09_7); - step2[10] = _mm_packs_epi32(s2_10_6, s2_10_7); - step2[13] = _mm_packs_epi32(s2_13_6, s2_13_7); - step2[14] = _mm_packs_epi32(s2_14_6, s2_14_7); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x4(&step2[9], &step2[10], &step2[13], - &step2[14]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - step2[16] = ADD_EPI16(step1[19], step3[16]); - step2[17] = ADD_EPI16(step1[18], step3[17]); - step2[18] = SUB_EPI16(step3[17], step1[18]); - step2[19] = SUB_EPI16(step3[16], step1[19]); - step2[20] = SUB_EPI16(step3[23], step1[20]); - step2[21] = SUB_EPI16(step3[22], step1[21]); - step2[22] = ADD_EPI16(step1[21], step3[22]); - step2[23] = ADD_EPI16(step1[20], step3[23]); - step2[24] = ADD_EPI16(step1[27], step3[24]); - step2[25] = ADD_EPI16(step1[26], step3[25]); - step2[26] = SUB_EPI16(step3[25], step1[26]); - step2[27] = SUB_EPI16(step3[24], step1[27]); - step2[28] = SUB_EPI16(step3[31], step1[28]); - step2[29] = SUB_EPI16(step3[30], step1[29]); - step2[30] = ADD_EPI16(step1[29], step3[30]); - step2[31] = ADD_EPI16(step1[28], step3[31]); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x16( - &step2[16], &step2[17], &step2[18], &step2[19], &step2[20], - &step2[21], &step2[22], &step2[23], &step2[24], &step2[25], - &step2[26], &step2[27], &step2[28], &step2[29], &step2[30], - &step2[31]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - // Stage 6 - { - const __m128i out_04_0 = _mm_unpacklo_epi16(step2[4], step2[7]); - const __m128i out_04_1 = _mm_unpackhi_epi16(step2[4], step2[7]); - const __m128i out_20_0 = _mm_unpacklo_epi16(step2[5], step2[6]); - const __m128i out_20_1 = _mm_unpackhi_epi16(step2[5], step2[6]); - const __m128i out_12_0 = _mm_unpacklo_epi16(step2[5], step2[6]); - const __m128i out_12_1 = _mm_unpackhi_epi16(step2[5], step2[6]); - const __m128i out_28_0 = _mm_unpacklo_epi16(step2[4], step2[7]); - const __m128i out_28_1 = _mm_unpackhi_epi16(step2[4], step2[7]); - const __m128i out_04_2 = _mm_madd_epi16(out_04_0, k__cospi_p28_p04); - const __m128i out_04_3 = _mm_madd_epi16(out_04_1, k__cospi_p28_p04); - const __m128i out_20_2 = _mm_madd_epi16(out_20_0, k__cospi_p12_p20); - const __m128i out_20_3 = _mm_madd_epi16(out_20_1, k__cospi_p12_p20); - const __m128i out_12_2 = _mm_madd_epi16(out_12_0, k__cospi_m20_p12); - const __m128i out_12_3 = _mm_madd_epi16(out_12_1, k__cospi_m20_p12); - const __m128i out_28_2 = _mm_madd_epi16(out_28_0, k__cospi_m04_p28); - const __m128i out_28_3 = _mm_madd_epi16(out_28_1, k__cospi_m04_p28); - // dct_const_round_shift - const __m128i out_04_4 = - _mm_add_epi32(out_04_2, k__DCT_CONST_ROUNDING); - const __m128i out_04_5 = - _mm_add_epi32(out_04_3, k__DCT_CONST_ROUNDING); - const __m128i out_20_4 = - _mm_add_epi32(out_20_2, k__DCT_CONST_ROUNDING); - const __m128i out_20_5 = - _mm_add_epi32(out_20_3, k__DCT_CONST_ROUNDING); - const __m128i out_12_4 = - _mm_add_epi32(out_12_2, k__DCT_CONST_ROUNDING); - const __m128i out_12_5 = - _mm_add_epi32(out_12_3, k__DCT_CONST_ROUNDING); - const __m128i out_28_4 = - _mm_add_epi32(out_28_2, k__DCT_CONST_ROUNDING); - const __m128i out_28_5 = - _mm_add_epi32(out_28_3, k__DCT_CONST_ROUNDING); - const __m128i out_04_6 = _mm_srai_epi32(out_04_4, DCT_CONST_BITS); - const __m128i out_04_7 = _mm_srai_epi32(out_04_5, DCT_CONST_BITS); - const __m128i out_20_6 = _mm_srai_epi32(out_20_4, DCT_CONST_BITS); - const __m128i out_20_7 = _mm_srai_epi32(out_20_5, DCT_CONST_BITS); - const __m128i out_12_6 = _mm_srai_epi32(out_12_4, DCT_CONST_BITS); - const __m128i out_12_7 = _mm_srai_epi32(out_12_5, DCT_CONST_BITS); - const __m128i out_28_6 = _mm_srai_epi32(out_28_4, DCT_CONST_BITS); - const __m128i out_28_7 = _mm_srai_epi32(out_28_5, DCT_CONST_BITS); - // Combine - out[4] = _mm_packs_epi32(out_04_6, out_04_7); - out[20] = _mm_packs_epi32(out_20_6, out_20_7); - out[12] = _mm_packs_epi32(out_12_6, out_12_7); - out[28] = _mm_packs_epi32(out_28_6, out_28_7); -#if DCT_HIGH_BIT_DEPTH - overflow = - check_epi16_overflow_x4(&out[4], &out[20], &out[12], &out[28]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - step3[8] = ADD_EPI16(step2[9], step1[8]); - step3[9] = SUB_EPI16(step1[8], step2[9]); - step3[10] = SUB_EPI16(step1[11], step2[10]); - step3[11] = ADD_EPI16(step2[10], step1[11]); - step3[12] = ADD_EPI16(step2[13], step1[12]); - step3[13] = SUB_EPI16(step1[12], step2[13]); - step3[14] = SUB_EPI16(step1[15], step2[14]); - step3[15] = ADD_EPI16(step2[14], step1[15]); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x8(&step3[8], &step3[9], &step3[10], - &step3[11], &step3[12], &step3[13], - &step3[14], &step3[15]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - const __m128i s3_17_0 = _mm_unpacklo_epi16(step2[17], step2[30]); - const __m128i s3_17_1 = _mm_unpackhi_epi16(step2[17], step2[30]); - const __m128i s3_18_0 = _mm_unpacklo_epi16(step2[18], step2[29]); - const __m128i s3_18_1 = _mm_unpackhi_epi16(step2[18], step2[29]); - const __m128i s3_21_0 = _mm_unpacklo_epi16(step2[21], step2[26]); - const __m128i s3_21_1 = _mm_unpackhi_epi16(step2[21], step2[26]); - const __m128i s3_22_0 = _mm_unpacklo_epi16(step2[22], step2[25]); - const __m128i s3_22_1 = _mm_unpackhi_epi16(step2[22], step2[25]); - const __m128i s3_17_2 = _mm_madd_epi16(s3_17_0, k__cospi_m04_p28); - const __m128i s3_17_3 = _mm_madd_epi16(s3_17_1, k__cospi_m04_p28); - const __m128i s3_18_2 = _mm_madd_epi16(s3_18_0, k__cospi_m28_m04); - const __m128i s3_18_3 = _mm_madd_epi16(s3_18_1, k__cospi_m28_m04); - const __m128i s3_21_2 = _mm_madd_epi16(s3_21_0, k__cospi_m20_p12); - const __m128i s3_21_3 = _mm_madd_epi16(s3_21_1, k__cospi_m20_p12); - const __m128i s3_22_2 = _mm_madd_epi16(s3_22_0, k__cospi_m12_m20); - const __m128i s3_22_3 = _mm_madd_epi16(s3_22_1, k__cospi_m12_m20); - const __m128i s3_25_2 = _mm_madd_epi16(s3_22_0, k__cospi_m20_p12); - const __m128i s3_25_3 = _mm_madd_epi16(s3_22_1, k__cospi_m20_p12); - const __m128i s3_26_2 = _mm_madd_epi16(s3_21_0, k__cospi_p12_p20); - const __m128i s3_26_3 = _mm_madd_epi16(s3_21_1, k__cospi_p12_p20); - const __m128i s3_29_2 = _mm_madd_epi16(s3_18_0, k__cospi_m04_p28); - const __m128i s3_29_3 = _mm_madd_epi16(s3_18_1, k__cospi_m04_p28); - const __m128i s3_30_2 = _mm_madd_epi16(s3_17_0, k__cospi_p28_p04); - const __m128i s3_30_3 = _mm_madd_epi16(s3_17_1, k__cospi_p28_p04); - // dct_const_round_shift - const __m128i s3_17_4 = _mm_add_epi32(s3_17_2, k__DCT_CONST_ROUNDING); - const __m128i s3_17_5 = _mm_add_epi32(s3_17_3, k__DCT_CONST_ROUNDING); - const __m128i s3_18_4 = _mm_add_epi32(s3_18_2, k__DCT_CONST_ROUNDING); - const __m128i s3_18_5 = _mm_add_epi32(s3_18_3, k__DCT_CONST_ROUNDING); - const __m128i s3_21_4 = _mm_add_epi32(s3_21_2, k__DCT_CONST_ROUNDING); - const __m128i s3_21_5 = _mm_add_epi32(s3_21_3, k__DCT_CONST_ROUNDING); - const __m128i s3_22_4 = _mm_add_epi32(s3_22_2, k__DCT_CONST_ROUNDING); - const __m128i s3_22_5 = _mm_add_epi32(s3_22_3, k__DCT_CONST_ROUNDING); - const __m128i s3_17_6 = _mm_srai_epi32(s3_17_4, DCT_CONST_BITS); - const __m128i s3_17_7 = _mm_srai_epi32(s3_17_5, DCT_CONST_BITS); - const __m128i s3_18_6 = _mm_srai_epi32(s3_18_4, DCT_CONST_BITS); - const __m128i s3_18_7 = _mm_srai_epi32(s3_18_5, DCT_CONST_BITS); - const __m128i s3_21_6 = _mm_srai_epi32(s3_21_4, DCT_CONST_BITS); - const __m128i s3_21_7 = _mm_srai_epi32(s3_21_5, DCT_CONST_BITS); - const __m128i s3_22_6 = _mm_srai_epi32(s3_22_4, DCT_CONST_BITS); - const __m128i s3_22_7 = _mm_srai_epi32(s3_22_5, DCT_CONST_BITS); - const __m128i s3_25_4 = _mm_add_epi32(s3_25_2, k__DCT_CONST_ROUNDING); - const __m128i s3_25_5 = _mm_add_epi32(s3_25_3, k__DCT_CONST_ROUNDING); - const __m128i s3_26_4 = _mm_add_epi32(s3_26_2, k__DCT_CONST_ROUNDING); - const __m128i s3_26_5 = _mm_add_epi32(s3_26_3, k__DCT_CONST_ROUNDING); - const __m128i s3_29_4 = _mm_add_epi32(s3_29_2, k__DCT_CONST_ROUNDING); - const __m128i s3_29_5 = _mm_add_epi32(s3_29_3, k__DCT_CONST_ROUNDING); - const __m128i s3_30_4 = _mm_add_epi32(s3_30_2, k__DCT_CONST_ROUNDING); - const __m128i s3_30_5 = _mm_add_epi32(s3_30_3, k__DCT_CONST_ROUNDING); - const __m128i s3_25_6 = _mm_srai_epi32(s3_25_4, DCT_CONST_BITS); - const __m128i s3_25_7 = _mm_srai_epi32(s3_25_5, DCT_CONST_BITS); - const __m128i s3_26_6 = _mm_srai_epi32(s3_26_4, DCT_CONST_BITS); - const __m128i s3_26_7 = _mm_srai_epi32(s3_26_5, DCT_CONST_BITS); - const __m128i s3_29_6 = _mm_srai_epi32(s3_29_4, DCT_CONST_BITS); - const __m128i s3_29_7 = _mm_srai_epi32(s3_29_5, DCT_CONST_BITS); - const __m128i s3_30_6 = _mm_srai_epi32(s3_30_4, DCT_CONST_BITS); - const __m128i s3_30_7 = _mm_srai_epi32(s3_30_5, DCT_CONST_BITS); - // Combine - step3[17] = _mm_packs_epi32(s3_17_6, s3_17_7); - step3[18] = _mm_packs_epi32(s3_18_6, s3_18_7); - step3[21] = _mm_packs_epi32(s3_21_6, s3_21_7); - step3[22] = _mm_packs_epi32(s3_22_6, s3_22_7); - // Combine - step3[25] = _mm_packs_epi32(s3_25_6, s3_25_7); - step3[26] = _mm_packs_epi32(s3_26_6, s3_26_7); - step3[29] = _mm_packs_epi32(s3_29_6, s3_29_7); - step3[30] = _mm_packs_epi32(s3_30_6, s3_30_7); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x8(&step3[17], &step3[18], &step3[21], - &step3[22], &step3[25], &step3[26], - &step3[29], &step3[30]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - // Stage 7 - { - const __m128i out_02_0 = _mm_unpacklo_epi16(step3[8], step3[15]); - const __m128i out_02_1 = _mm_unpackhi_epi16(step3[8], step3[15]); - const __m128i out_18_0 = _mm_unpacklo_epi16(step3[9], step3[14]); - const __m128i out_18_1 = _mm_unpackhi_epi16(step3[9], step3[14]); - const __m128i out_10_0 = _mm_unpacklo_epi16(step3[10], step3[13]); - const __m128i out_10_1 = _mm_unpackhi_epi16(step3[10], step3[13]); - const __m128i out_26_0 = _mm_unpacklo_epi16(step3[11], step3[12]); - const __m128i out_26_1 = _mm_unpackhi_epi16(step3[11], step3[12]); - const __m128i out_02_2 = _mm_madd_epi16(out_02_0, k__cospi_p30_p02); - const __m128i out_02_3 = _mm_madd_epi16(out_02_1, k__cospi_p30_p02); - const __m128i out_18_2 = _mm_madd_epi16(out_18_0, k__cospi_p14_p18); - const __m128i out_18_3 = _mm_madd_epi16(out_18_1, k__cospi_p14_p18); - const __m128i out_10_2 = _mm_madd_epi16(out_10_0, k__cospi_p22_p10); - const __m128i out_10_3 = _mm_madd_epi16(out_10_1, k__cospi_p22_p10); - const __m128i out_26_2 = _mm_madd_epi16(out_26_0, k__cospi_p06_p26); - const __m128i out_26_3 = _mm_madd_epi16(out_26_1, k__cospi_p06_p26); - const __m128i out_06_2 = _mm_madd_epi16(out_26_0, k__cospi_m26_p06); - const __m128i out_06_3 = _mm_madd_epi16(out_26_1, k__cospi_m26_p06); - const __m128i out_22_2 = _mm_madd_epi16(out_10_0, k__cospi_m10_p22); - const __m128i out_22_3 = _mm_madd_epi16(out_10_1, k__cospi_m10_p22); - const __m128i out_14_2 = _mm_madd_epi16(out_18_0, k__cospi_m18_p14); - const __m128i out_14_3 = _mm_madd_epi16(out_18_1, k__cospi_m18_p14); - const __m128i out_30_2 = _mm_madd_epi16(out_02_0, k__cospi_m02_p30); - const __m128i out_30_3 = _mm_madd_epi16(out_02_1, k__cospi_m02_p30); - // dct_const_round_shift - const __m128i out_02_4 = - _mm_add_epi32(out_02_2, k__DCT_CONST_ROUNDING); - const __m128i out_02_5 = - _mm_add_epi32(out_02_3, k__DCT_CONST_ROUNDING); - const __m128i out_18_4 = - _mm_add_epi32(out_18_2, k__DCT_CONST_ROUNDING); - const __m128i out_18_5 = - _mm_add_epi32(out_18_3, k__DCT_CONST_ROUNDING); - const __m128i out_10_4 = - _mm_add_epi32(out_10_2, k__DCT_CONST_ROUNDING); - const __m128i out_10_5 = - _mm_add_epi32(out_10_3, k__DCT_CONST_ROUNDING); - const __m128i out_26_4 = - _mm_add_epi32(out_26_2, k__DCT_CONST_ROUNDING); - const __m128i out_26_5 = - _mm_add_epi32(out_26_3, k__DCT_CONST_ROUNDING); - const __m128i out_06_4 = - _mm_add_epi32(out_06_2, k__DCT_CONST_ROUNDING); - const __m128i out_06_5 = - _mm_add_epi32(out_06_3, k__DCT_CONST_ROUNDING); - const __m128i out_22_4 = - _mm_add_epi32(out_22_2, k__DCT_CONST_ROUNDING); - const __m128i out_22_5 = - _mm_add_epi32(out_22_3, k__DCT_CONST_ROUNDING); - const __m128i out_14_4 = - _mm_add_epi32(out_14_2, k__DCT_CONST_ROUNDING); - const __m128i out_14_5 = - _mm_add_epi32(out_14_3, k__DCT_CONST_ROUNDING); - const __m128i out_30_4 = - _mm_add_epi32(out_30_2, k__DCT_CONST_ROUNDING); - const __m128i out_30_5 = - _mm_add_epi32(out_30_3, k__DCT_CONST_ROUNDING); - const __m128i out_02_6 = _mm_srai_epi32(out_02_4, DCT_CONST_BITS); - const __m128i out_02_7 = _mm_srai_epi32(out_02_5, DCT_CONST_BITS); - const __m128i out_18_6 = _mm_srai_epi32(out_18_4, DCT_CONST_BITS); - const __m128i out_18_7 = _mm_srai_epi32(out_18_5, DCT_CONST_BITS); - const __m128i out_10_6 = _mm_srai_epi32(out_10_4, DCT_CONST_BITS); - const __m128i out_10_7 = _mm_srai_epi32(out_10_5, DCT_CONST_BITS); - const __m128i out_26_6 = _mm_srai_epi32(out_26_4, DCT_CONST_BITS); - const __m128i out_26_7 = _mm_srai_epi32(out_26_5, DCT_CONST_BITS); - const __m128i out_06_6 = _mm_srai_epi32(out_06_4, DCT_CONST_BITS); - const __m128i out_06_7 = _mm_srai_epi32(out_06_5, DCT_CONST_BITS); - const __m128i out_22_6 = _mm_srai_epi32(out_22_4, DCT_CONST_BITS); - const __m128i out_22_7 = _mm_srai_epi32(out_22_5, DCT_CONST_BITS); - const __m128i out_14_6 = _mm_srai_epi32(out_14_4, DCT_CONST_BITS); - const __m128i out_14_7 = _mm_srai_epi32(out_14_5, DCT_CONST_BITS); - const __m128i out_30_6 = _mm_srai_epi32(out_30_4, DCT_CONST_BITS); - const __m128i out_30_7 = _mm_srai_epi32(out_30_5, DCT_CONST_BITS); - // Combine - out[2] = _mm_packs_epi32(out_02_6, out_02_7); - out[18] = _mm_packs_epi32(out_18_6, out_18_7); - out[10] = _mm_packs_epi32(out_10_6, out_10_7); - out[26] = _mm_packs_epi32(out_26_6, out_26_7); - out[6] = _mm_packs_epi32(out_06_6, out_06_7); - out[22] = _mm_packs_epi32(out_22_6, out_22_7); - out[14] = _mm_packs_epi32(out_14_6, out_14_7); - out[30] = _mm_packs_epi32(out_30_6, out_30_7); -#if DCT_HIGH_BIT_DEPTH - overflow = - check_epi16_overflow_x8(&out[2], &out[18], &out[10], &out[26], - &out[6], &out[22], &out[14], &out[30]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - step1[16] = ADD_EPI16(step3[17], step2[16]); - step1[17] = SUB_EPI16(step2[16], step3[17]); - step1[18] = SUB_EPI16(step2[19], step3[18]); - step1[19] = ADD_EPI16(step3[18], step2[19]); - step1[20] = ADD_EPI16(step3[21], step2[20]); - step1[21] = SUB_EPI16(step2[20], step3[21]); - step1[22] = SUB_EPI16(step2[23], step3[22]); - step1[23] = ADD_EPI16(step3[22], step2[23]); - step1[24] = ADD_EPI16(step3[25], step2[24]); - step1[25] = SUB_EPI16(step2[24], step3[25]); - step1[26] = SUB_EPI16(step2[27], step3[26]); - step1[27] = ADD_EPI16(step3[26], step2[27]); - step1[28] = ADD_EPI16(step3[29], step2[28]); - step1[29] = SUB_EPI16(step2[28], step3[29]); - step1[30] = SUB_EPI16(step2[31], step3[30]); - step1[31] = ADD_EPI16(step3[30], step2[31]); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x16( - &step1[16], &step1[17], &step1[18], &step1[19], &step1[20], - &step1[21], &step1[22], &step1[23], &step1[24], &step1[25], - &step1[26], &step1[27], &step1[28], &step1[29], &step1[30], - &step1[31]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - // Final stage --- outputs indices are bit-reversed. - { - const __m128i out_01_0 = _mm_unpacklo_epi16(step1[16], step1[31]); - const __m128i out_01_1 = _mm_unpackhi_epi16(step1[16], step1[31]); - const __m128i out_17_0 = _mm_unpacklo_epi16(step1[17], step1[30]); - const __m128i out_17_1 = _mm_unpackhi_epi16(step1[17], step1[30]); - const __m128i out_09_0 = _mm_unpacklo_epi16(step1[18], step1[29]); - const __m128i out_09_1 = _mm_unpackhi_epi16(step1[18], step1[29]); - const __m128i out_25_0 = _mm_unpacklo_epi16(step1[19], step1[28]); - const __m128i out_25_1 = _mm_unpackhi_epi16(step1[19], step1[28]); - const __m128i out_01_2 = _mm_madd_epi16(out_01_0, k__cospi_p31_p01); - const __m128i out_01_3 = _mm_madd_epi16(out_01_1, k__cospi_p31_p01); - const __m128i out_17_2 = _mm_madd_epi16(out_17_0, k__cospi_p15_p17); - const __m128i out_17_3 = _mm_madd_epi16(out_17_1, k__cospi_p15_p17); - const __m128i out_09_2 = _mm_madd_epi16(out_09_0, k__cospi_p23_p09); - const __m128i out_09_3 = _mm_madd_epi16(out_09_1, k__cospi_p23_p09); - const __m128i out_25_2 = _mm_madd_epi16(out_25_0, k__cospi_p07_p25); - const __m128i out_25_3 = _mm_madd_epi16(out_25_1, k__cospi_p07_p25); - const __m128i out_07_2 = _mm_madd_epi16(out_25_0, k__cospi_m25_p07); - const __m128i out_07_3 = _mm_madd_epi16(out_25_1, k__cospi_m25_p07); - const __m128i out_23_2 = _mm_madd_epi16(out_09_0, k__cospi_m09_p23); - const __m128i out_23_3 = _mm_madd_epi16(out_09_1, k__cospi_m09_p23); - const __m128i out_15_2 = _mm_madd_epi16(out_17_0, k__cospi_m17_p15); - const __m128i out_15_3 = _mm_madd_epi16(out_17_1, k__cospi_m17_p15); - const __m128i out_31_2 = _mm_madd_epi16(out_01_0, k__cospi_m01_p31); - const __m128i out_31_3 = _mm_madd_epi16(out_01_1, k__cospi_m01_p31); - // dct_const_round_shift - const __m128i out_01_4 = - _mm_add_epi32(out_01_2, k__DCT_CONST_ROUNDING); - const __m128i out_01_5 = - _mm_add_epi32(out_01_3, k__DCT_CONST_ROUNDING); - const __m128i out_17_4 = - _mm_add_epi32(out_17_2, k__DCT_CONST_ROUNDING); - const __m128i out_17_5 = - _mm_add_epi32(out_17_3, k__DCT_CONST_ROUNDING); - const __m128i out_09_4 = - _mm_add_epi32(out_09_2, k__DCT_CONST_ROUNDING); - const __m128i out_09_5 = - _mm_add_epi32(out_09_3, k__DCT_CONST_ROUNDING); - const __m128i out_25_4 = - _mm_add_epi32(out_25_2, k__DCT_CONST_ROUNDING); - const __m128i out_25_5 = - _mm_add_epi32(out_25_3, k__DCT_CONST_ROUNDING); - const __m128i out_07_4 = - _mm_add_epi32(out_07_2, k__DCT_CONST_ROUNDING); - const __m128i out_07_5 = - _mm_add_epi32(out_07_3, k__DCT_CONST_ROUNDING); - const __m128i out_23_4 = - _mm_add_epi32(out_23_2, k__DCT_CONST_ROUNDING); - const __m128i out_23_5 = - _mm_add_epi32(out_23_3, k__DCT_CONST_ROUNDING); - const __m128i out_15_4 = - _mm_add_epi32(out_15_2, k__DCT_CONST_ROUNDING); - const __m128i out_15_5 = - _mm_add_epi32(out_15_3, k__DCT_CONST_ROUNDING); - const __m128i out_31_4 = - _mm_add_epi32(out_31_2, k__DCT_CONST_ROUNDING); - const __m128i out_31_5 = - _mm_add_epi32(out_31_3, k__DCT_CONST_ROUNDING); - const __m128i out_01_6 = _mm_srai_epi32(out_01_4, DCT_CONST_BITS); - const __m128i out_01_7 = _mm_srai_epi32(out_01_5, DCT_CONST_BITS); - const __m128i out_17_6 = _mm_srai_epi32(out_17_4, DCT_CONST_BITS); - const __m128i out_17_7 = _mm_srai_epi32(out_17_5, DCT_CONST_BITS); - const __m128i out_09_6 = _mm_srai_epi32(out_09_4, DCT_CONST_BITS); - const __m128i out_09_7 = _mm_srai_epi32(out_09_5, DCT_CONST_BITS); - const __m128i out_25_6 = _mm_srai_epi32(out_25_4, DCT_CONST_BITS); - const __m128i out_25_7 = _mm_srai_epi32(out_25_5, DCT_CONST_BITS); - const __m128i out_07_6 = _mm_srai_epi32(out_07_4, DCT_CONST_BITS); - const __m128i out_07_7 = _mm_srai_epi32(out_07_5, DCT_CONST_BITS); - const __m128i out_23_6 = _mm_srai_epi32(out_23_4, DCT_CONST_BITS); - const __m128i out_23_7 = _mm_srai_epi32(out_23_5, DCT_CONST_BITS); - const __m128i out_15_6 = _mm_srai_epi32(out_15_4, DCT_CONST_BITS); - const __m128i out_15_7 = _mm_srai_epi32(out_15_5, DCT_CONST_BITS); - const __m128i out_31_6 = _mm_srai_epi32(out_31_4, DCT_CONST_BITS); - const __m128i out_31_7 = _mm_srai_epi32(out_31_5, DCT_CONST_BITS); - // Combine - out[1] = _mm_packs_epi32(out_01_6, out_01_7); - out[17] = _mm_packs_epi32(out_17_6, out_17_7); - out[9] = _mm_packs_epi32(out_09_6, out_09_7); - out[25] = _mm_packs_epi32(out_25_6, out_25_7); - out[7] = _mm_packs_epi32(out_07_6, out_07_7); - out[23] = _mm_packs_epi32(out_23_6, out_23_7); - out[15] = _mm_packs_epi32(out_15_6, out_15_7); - out[31] = _mm_packs_epi32(out_31_6, out_31_7); -#if DCT_HIGH_BIT_DEPTH - overflow = - check_epi16_overflow_x8(&out[1], &out[17], &out[9], &out[25], - &out[7], &out[23], &out[15], &out[31]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - const __m128i out_05_0 = _mm_unpacklo_epi16(step1[20], step1[27]); - const __m128i out_05_1 = _mm_unpackhi_epi16(step1[20], step1[27]); - const __m128i out_21_0 = _mm_unpacklo_epi16(step1[21], step1[26]); - const __m128i out_21_1 = _mm_unpackhi_epi16(step1[21], step1[26]); - const __m128i out_13_0 = _mm_unpacklo_epi16(step1[22], step1[25]); - const __m128i out_13_1 = _mm_unpackhi_epi16(step1[22], step1[25]); - const __m128i out_29_0 = _mm_unpacklo_epi16(step1[23], step1[24]); - const __m128i out_29_1 = _mm_unpackhi_epi16(step1[23], step1[24]); - const __m128i out_05_2 = _mm_madd_epi16(out_05_0, k__cospi_p27_p05); - const __m128i out_05_3 = _mm_madd_epi16(out_05_1, k__cospi_p27_p05); - const __m128i out_21_2 = _mm_madd_epi16(out_21_0, k__cospi_p11_p21); - const __m128i out_21_3 = _mm_madd_epi16(out_21_1, k__cospi_p11_p21); - const __m128i out_13_2 = _mm_madd_epi16(out_13_0, k__cospi_p19_p13); - const __m128i out_13_3 = _mm_madd_epi16(out_13_1, k__cospi_p19_p13); - const __m128i out_29_2 = _mm_madd_epi16(out_29_0, k__cospi_p03_p29); - const __m128i out_29_3 = _mm_madd_epi16(out_29_1, k__cospi_p03_p29); - const __m128i out_03_2 = _mm_madd_epi16(out_29_0, k__cospi_m29_p03); - const __m128i out_03_3 = _mm_madd_epi16(out_29_1, k__cospi_m29_p03); - const __m128i out_19_2 = _mm_madd_epi16(out_13_0, k__cospi_m13_p19); - const __m128i out_19_3 = _mm_madd_epi16(out_13_1, k__cospi_m13_p19); - const __m128i out_11_2 = _mm_madd_epi16(out_21_0, k__cospi_m21_p11); - const __m128i out_11_3 = _mm_madd_epi16(out_21_1, k__cospi_m21_p11); - const __m128i out_27_2 = _mm_madd_epi16(out_05_0, k__cospi_m05_p27); - const __m128i out_27_3 = _mm_madd_epi16(out_05_1, k__cospi_m05_p27); - // dct_const_round_shift - const __m128i out_05_4 = - _mm_add_epi32(out_05_2, k__DCT_CONST_ROUNDING); - const __m128i out_05_5 = - _mm_add_epi32(out_05_3, k__DCT_CONST_ROUNDING); - const __m128i out_21_4 = - _mm_add_epi32(out_21_2, k__DCT_CONST_ROUNDING); - const __m128i out_21_5 = - _mm_add_epi32(out_21_3, k__DCT_CONST_ROUNDING); - const __m128i out_13_4 = - _mm_add_epi32(out_13_2, k__DCT_CONST_ROUNDING); - const __m128i out_13_5 = - _mm_add_epi32(out_13_3, k__DCT_CONST_ROUNDING); - const __m128i out_29_4 = - _mm_add_epi32(out_29_2, k__DCT_CONST_ROUNDING); - const __m128i out_29_5 = - _mm_add_epi32(out_29_3, k__DCT_CONST_ROUNDING); - const __m128i out_03_4 = - _mm_add_epi32(out_03_2, k__DCT_CONST_ROUNDING); - const __m128i out_03_5 = - _mm_add_epi32(out_03_3, k__DCT_CONST_ROUNDING); - const __m128i out_19_4 = - _mm_add_epi32(out_19_2, k__DCT_CONST_ROUNDING); - const __m128i out_19_5 = - _mm_add_epi32(out_19_3, k__DCT_CONST_ROUNDING); - const __m128i out_11_4 = - _mm_add_epi32(out_11_2, k__DCT_CONST_ROUNDING); - const __m128i out_11_5 = - _mm_add_epi32(out_11_3, k__DCT_CONST_ROUNDING); - const __m128i out_27_4 = - _mm_add_epi32(out_27_2, k__DCT_CONST_ROUNDING); - const __m128i out_27_5 = - _mm_add_epi32(out_27_3, k__DCT_CONST_ROUNDING); - const __m128i out_05_6 = _mm_srai_epi32(out_05_4, DCT_CONST_BITS); - const __m128i out_05_7 = _mm_srai_epi32(out_05_5, DCT_CONST_BITS); - const __m128i out_21_6 = _mm_srai_epi32(out_21_4, DCT_CONST_BITS); - const __m128i out_21_7 = _mm_srai_epi32(out_21_5, DCT_CONST_BITS); - const __m128i out_13_6 = _mm_srai_epi32(out_13_4, DCT_CONST_BITS); - const __m128i out_13_7 = _mm_srai_epi32(out_13_5, DCT_CONST_BITS); - const __m128i out_29_6 = _mm_srai_epi32(out_29_4, DCT_CONST_BITS); - const __m128i out_29_7 = _mm_srai_epi32(out_29_5, DCT_CONST_BITS); - const __m128i out_03_6 = _mm_srai_epi32(out_03_4, DCT_CONST_BITS); - const __m128i out_03_7 = _mm_srai_epi32(out_03_5, DCT_CONST_BITS); - const __m128i out_19_6 = _mm_srai_epi32(out_19_4, DCT_CONST_BITS); - const __m128i out_19_7 = _mm_srai_epi32(out_19_5, DCT_CONST_BITS); - const __m128i out_11_6 = _mm_srai_epi32(out_11_4, DCT_CONST_BITS); - const __m128i out_11_7 = _mm_srai_epi32(out_11_5, DCT_CONST_BITS); - const __m128i out_27_6 = _mm_srai_epi32(out_27_4, DCT_CONST_BITS); - const __m128i out_27_7 = _mm_srai_epi32(out_27_5, DCT_CONST_BITS); - // Combine - out[5] = _mm_packs_epi32(out_05_6, out_05_7); - out[21] = _mm_packs_epi32(out_21_6, out_21_7); - out[13] = _mm_packs_epi32(out_13_6, out_13_7); - out[29] = _mm_packs_epi32(out_29_6, out_29_7); - out[3] = _mm_packs_epi32(out_03_6, out_03_7); - out[19] = _mm_packs_epi32(out_19_6, out_19_7); - out[11] = _mm_packs_epi32(out_11_6, out_11_7); - out[27] = _mm_packs_epi32(out_27_6, out_27_7); -#if DCT_HIGH_BIT_DEPTH - overflow = - check_epi16_overflow_x8(&out[5], &out[21], &out[13], &out[29], - &out[3], &out[19], &out[11], &out[27]); - if (overflow) { - if (pass == 0) - HIGH_FDCT32x32_2D_C(input, output_org, stride); - else - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } -#if FDCT32x32_HIGH_PRECISION - } else { - __m128i lstep1[64], lstep2[64], lstep3[64]; - __m128i u[32], v[32], sign[16]; - const __m128i K32One = _mm_set_epi32(1, 1, 1, 1); - const __m128i k__pOne_mOne = pair_set_epi16(1, -1); - // start using 32-bit operations - // stage 3 - { - // expanding to 32-bit length while adding and subtracting - lstep2[0] = _mm_unpacklo_epi16(step2[0], step2[7]); - lstep2[1] = _mm_unpackhi_epi16(step2[0], step2[7]); - lstep2[2] = _mm_unpacklo_epi16(step2[1], step2[6]); - lstep2[3] = _mm_unpackhi_epi16(step2[1], step2[6]); - lstep2[4] = _mm_unpacklo_epi16(step2[2], step2[5]); - lstep2[5] = _mm_unpackhi_epi16(step2[2], step2[5]); - lstep2[6] = _mm_unpacklo_epi16(step2[3], step2[4]); - lstep2[7] = _mm_unpackhi_epi16(step2[3], step2[4]); - - lstep3[0] = _mm_madd_epi16(lstep2[0], kOne); - lstep3[1] = _mm_madd_epi16(lstep2[1], kOne); - lstep3[2] = _mm_madd_epi16(lstep2[2], kOne); - lstep3[3] = _mm_madd_epi16(lstep2[3], kOne); - lstep3[4] = _mm_madd_epi16(lstep2[4], kOne); - lstep3[5] = _mm_madd_epi16(lstep2[5], kOne); - lstep3[6] = _mm_madd_epi16(lstep2[6], kOne); - lstep3[7] = _mm_madd_epi16(lstep2[7], kOne); - - lstep3[8] = _mm_madd_epi16(lstep2[6], k__pOne_mOne); - lstep3[9] = _mm_madd_epi16(lstep2[7], k__pOne_mOne); - lstep3[10] = _mm_madd_epi16(lstep2[4], k__pOne_mOne); - lstep3[11] = _mm_madd_epi16(lstep2[5], k__pOne_mOne); - lstep3[12] = _mm_madd_epi16(lstep2[2], k__pOne_mOne); - lstep3[13] = _mm_madd_epi16(lstep2[3], k__pOne_mOne); - lstep3[14] = _mm_madd_epi16(lstep2[0], k__pOne_mOne); - lstep3[15] = _mm_madd_epi16(lstep2[1], k__pOne_mOne); - } - { - const __m128i s3_10_0 = _mm_unpacklo_epi16(step2[13], step2[10]); - const __m128i s3_10_1 = _mm_unpackhi_epi16(step2[13], step2[10]); - const __m128i s3_11_0 = _mm_unpacklo_epi16(step2[12], step2[11]); - const __m128i s3_11_1 = _mm_unpackhi_epi16(step2[12], step2[11]); - const __m128i s3_10_2 = _mm_madd_epi16(s3_10_0, k__cospi_p16_m16); - const __m128i s3_10_3 = _mm_madd_epi16(s3_10_1, k__cospi_p16_m16); - const __m128i s3_11_2 = _mm_madd_epi16(s3_11_0, k__cospi_p16_m16); - const __m128i s3_11_3 = _mm_madd_epi16(s3_11_1, k__cospi_p16_m16); - const __m128i s3_12_2 = _mm_madd_epi16(s3_11_0, k__cospi_p16_p16); - const __m128i s3_12_3 = _mm_madd_epi16(s3_11_1, k__cospi_p16_p16); - const __m128i s3_13_2 = _mm_madd_epi16(s3_10_0, k__cospi_p16_p16); - const __m128i s3_13_3 = _mm_madd_epi16(s3_10_1, k__cospi_p16_p16); - // dct_const_round_shift - const __m128i s3_10_4 = _mm_add_epi32(s3_10_2, k__DCT_CONST_ROUNDING); - const __m128i s3_10_5 = _mm_add_epi32(s3_10_3, k__DCT_CONST_ROUNDING); - const __m128i s3_11_4 = _mm_add_epi32(s3_11_2, k__DCT_CONST_ROUNDING); - const __m128i s3_11_5 = _mm_add_epi32(s3_11_3, k__DCT_CONST_ROUNDING); - const __m128i s3_12_4 = _mm_add_epi32(s3_12_2, k__DCT_CONST_ROUNDING); - const __m128i s3_12_5 = _mm_add_epi32(s3_12_3, k__DCT_CONST_ROUNDING); - const __m128i s3_13_4 = _mm_add_epi32(s3_13_2, k__DCT_CONST_ROUNDING); - const __m128i s3_13_5 = _mm_add_epi32(s3_13_3, k__DCT_CONST_ROUNDING); - lstep3[20] = _mm_srai_epi32(s3_10_4, DCT_CONST_BITS); - lstep3[21] = _mm_srai_epi32(s3_10_5, DCT_CONST_BITS); - lstep3[22] = _mm_srai_epi32(s3_11_4, DCT_CONST_BITS); - lstep3[23] = _mm_srai_epi32(s3_11_5, DCT_CONST_BITS); - lstep3[24] = _mm_srai_epi32(s3_12_4, DCT_CONST_BITS); - lstep3[25] = _mm_srai_epi32(s3_12_5, DCT_CONST_BITS); - lstep3[26] = _mm_srai_epi32(s3_13_4, DCT_CONST_BITS); - lstep3[27] = _mm_srai_epi32(s3_13_5, DCT_CONST_BITS); - } - { - lstep1[32] = _mm_unpacklo_epi16(step1[16], step2[23]); - lstep1[33] = _mm_unpackhi_epi16(step1[16], step2[23]); - lstep1[34] = _mm_unpacklo_epi16(step1[17], step2[22]); - lstep1[35] = _mm_unpackhi_epi16(step1[17], step2[22]); - lstep1[36] = _mm_unpacklo_epi16(step1[18], step2[21]); - lstep1[37] = _mm_unpackhi_epi16(step1[18], step2[21]); - lstep1[38] = _mm_unpacklo_epi16(step1[19], step2[20]); - lstep1[39] = _mm_unpackhi_epi16(step1[19], step2[20]); - - lstep1[56] = _mm_unpacklo_epi16(step1[28], step2[27]); - lstep1[57] = _mm_unpackhi_epi16(step1[28], step2[27]); - lstep1[58] = _mm_unpacklo_epi16(step1[29], step2[26]); - lstep1[59] = _mm_unpackhi_epi16(step1[29], step2[26]); - lstep1[60] = _mm_unpacklo_epi16(step1[30], step2[25]); - lstep1[61] = _mm_unpackhi_epi16(step1[30], step2[25]); - lstep1[62] = _mm_unpacklo_epi16(step1[31], step2[24]); - lstep1[63] = _mm_unpackhi_epi16(step1[31], step2[24]); - - lstep3[32] = _mm_madd_epi16(lstep1[32], kOne); - lstep3[33] = _mm_madd_epi16(lstep1[33], kOne); - lstep3[34] = _mm_madd_epi16(lstep1[34], kOne); - lstep3[35] = _mm_madd_epi16(lstep1[35], kOne); - lstep3[36] = _mm_madd_epi16(lstep1[36], kOne); - lstep3[37] = _mm_madd_epi16(lstep1[37], kOne); - lstep3[38] = _mm_madd_epi16(lstep1[38], kOne); - lstep3[39] = _mm_madd_epi16(lstep1[39], kOne); - - lstep3[40] = _mm_madd_epi16(lstep1[38], k__pOne_mOne); - lstep3[41] = _mm_madd_epi16(lstep1[39], k__pOne_mOne); - lstep3[42] = _mm_madd_epi16(lstep1[36], k__pOne_mOne); - lstep3[43] = _mm_madd_epi16(lstep1[37], k__pOne_mOne); - lstep3[44] = _mm_madd_epi16(lstep1[34], k__pOne_mOne); - lstep3[45] = _mm_madd_epi16(lstep1[35], k__pOne_mOne); - lstep3[46] = _mm_madd_epi16(lstep1[32], k__pOne_mOne); - lstep3[47] = _mm_madd_epi16(lstep1[33], k__pOne_mOne); - - lstep3[48] = _mm_madd_epi16(lstep1[62], k__pOne_mOne); - lstep3[49] = _mm_madd_epi16(lstep1[63], k__pOne_mOne); - lstep3[50] = _mm_madd_epi16(lstep1[60], k__pOne_mOne); - lstep3[51] = _mm_madd_epi16(lstep1[61], k__pOne_mOne); - lstep3[52] = _mm_madd_epi16(lstep1[58], k__pOne_mOne); - lstep3[53] = _mm_madd_epi16(lstep1[59], k__pOne_mOne); - lstep3[54] = _mm_madd_epi16(lstep1[56], k__pOne_mOne); - lstep3[55] = _mm_madd_epi16(lstep1[57], k__pOne_mOne); - - lstep3[56] = _mm_madd_epi16(lstep1[56], kOne); - lstep3[57] = _mm_madd_epi16(lstep1[57], kOne); - lstep3[58] = _mm_madd_epi16(lstep1[58], kOne); - lstep3[59] = _mm_madd_epi16(lstep1[59], kOne); - lstep3[60] = _mm_madd_epi16(lstep1[60], kOne); - lstep3[61] = _mm_madd_epi16(lstep1[61], kOne); - lstep3[62] = _mm_madd_epi16(lstep1[62], kOne); - lstep3[63] = _mm_madd_epi16(lstep1[63], kOne); - } - - // stage 4 - { - // expanding to 32-bit length prior to addition operations - sign[0] = _mm_cmpgt_epi16(kZero, step2[8]); - sign[1] = _mm_cmpgt_epi16(kZero, step2[9]); - sign[2] = _mm_cmpgt_epi16(kZero, step2[14]); - sign[3] = _mm_cmpgt_epi16(kZero, step2[15]); - lstep2[16] = _mm_unpacklo_epi16(step2[8], sign[0]); - lstep2[17] = _mm_unpackhi_epi16(step2[8], sign[0]); - lstep2[18] = _mm_unpacklo_epi16(step2[9], sign[1]); - lstep2[19] = _mm_unpackhi_epi16(step2[9], sign[1]); - lstep2[28] = _mm_unpacklo_epi16(step2[14], sign[2]); - lstep2[29] = _mm_unpackhi_epi16(step2[14], sign[2]); - lstep2[30] = _mm_unpacklo_epi16(step2[15], sign[3]); - lstep2[31] = _mm_unpackhi_epi16(step2[15], sign[3]); - - lstep1[0] = _mm_add_epi32(lstep3[6], lstep3[0]); - lstep1[1] = _mm_add_epi32(lstep3[7], lstep3[1]); - lstep1[2] = _mm_add_epi32(lstep3[4], lstep3[2]); - lstep1[3] = _mm_add_epi32(lstep3[5], lstep3[3]); - lstep1[4] = _mm_sub_epi32(lstep3[2], lstep3[4]); - lstep1[5] = _mm_sub_epi32(lstep3[3], lstep3[5]); - lstep1[6] = _mm_sub_epi32(lstep3[0], lstep3[6]); - lstep1[7] = _mm_sub_epi32(lstep3[1], lstep3[7]); - lstep1[16] = _mm_add_epi32(lstep3[22], lstep2[16]); - lstep1[17] = _mm_add_epi32(lstep3[23], lstep2[17]); - lstep1[18] = _mm_add_epi32(lstep3[20], lstep2[18]); - lstep1[19] = _mm_add_epi32(lstep3[21], lstep2[19]); - lstep1[20] = _mm_sub_epi32(lstep2[18], lstep3[20]); - lstep1[21] = _mm_sub_epi32(lstep2[19], lstep3[21]); - lstep1[22] = _mm_sub_epi32(lstep2[16], lstep3[22]); - lstep1[23] = _mm_sub_epi32(lstep2[17], lstep3[23]); - lstep1[24] = _mm_sub_epi32(lstep2[30], lstep3[24]); - lstep1[25] = _mm_sub_epi32(lstep2[31], lstep3[25]); - lstep1[26] = _mm_sub_epi32(lstep2[28], lstep3[26]); - lstep1[27] = _mm_sub_epi32(lstep2[29], lstep3[27]); - lstep1[28] = _mm_add_epi32(lstep3[26], lstep2[28]); - lstep1[29] = _mm_add_epi32(lstep3[27], lstep2[29]); - lstep1[30] = _mm_add_epi32(lstep3[24], lstep2[30]); - lstep1[31] = _mm_add_epi32(lstep3[25], lstep2[31]); - } - { - // to be continued... - // - const __m128i k32_p16_p16 = pair_set_epi32(cospi_16_64, cospi_16_64); - const __m128i k32_p16_m16 = pair_set_epi32(cospi_16_64, -cospi_16_64); - - u[0] = _mm_unpacklo_epi32(lstep3[12], lstep3[10]); - u[1] = _mm_unpackhi_epi32(lstep3[12], lstep3[10]); - u[2] = _mm_unpacklo_epi32(lstep3[13], lstep3[11]); - u[3] = _mm_unpackhi_epi32(lstep3[13], lstep3[11]); - - // TODO(jingning): manually inline k_madd_epi32_ to further hide - // instruction latency. - v[0] = k_madd_epi32(u[0], k32_p16_m16); - v[1] = k_madd_epi32(u[1], k32_p16_m16); - v[2] = k_madd_epi32(u[2], k32_p16_m16); - v[3] = k_madd_epi32(u[3], k32_p16_m16); - v[4] = k_madd_epi32(u[0], k32_p16_p16); - v[5] = k_madd_epi32(u[1], k32_p16_p16); - v[6] = k_madd_epi32(u[2], k32_p16_p16); - v[7] = k_madd_epi32(u[3], k32_p16_p16); -#if DCT_HIGH_BIT_DEPTH - overflow = k_check_epi32_overflow_8(&v[0], &v[1], &v[2], &v[3], &v[4], - &v[5], &v[6], &v[7], &kZero); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - u[0] = k_packs_epi64(v[0], v[1]); - u[1] = k_packs_epi64(v[2], v[3]); - u[2] = k_packs_epi64(v[4], v[5]); - u[3] = k_packs_epi64(v[6], v[7]); - - v[0] = _mm_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm_add_epi32(u[3], k__DCT_CONST_ROUNDING); - - lstep1[10] = _mm_srai_epi32(v[0], DCT_CONST_BITS); - lstep1[11] = _mm_srai_epi32(v[1], DCT_CONST_BITS); - lstep1[12] = _mm_srai_epi32(v[2], DCT_CONST_BITS); - lstep1[13] = _mm_srai_epi32(v[3], DCT_CONST_BITS); - } - { - const __m128i k32_m08_p24 = pair_set_epi32(-cospi_8_64, cospi_24_64); - const __m128i k32_m24_m08 = pair_set_epi32(-cospi_24_64, -cospi_8_64); - const __m128i k32_p24_p08 = pair_set_epi32(cospi_24_64, cospi_8_64); - - u[0] = _mm_unpacklo_epi32(lstep3[36], lstep3[58]); - u[1] = _mm_unpackhi_epi32(lstep3[36], lstep3[58]); - u[2] = _mm_unpacklo_epi32(lstep3[37], lstep3[59]); - u[3] = _mm_unpackhi_epi32(lstep3[37], lstep3[59]); - u[4] = _mm_unpacklo_epi32(lstep3[38], lstep3[56]); - u[5] = _mm_unpackhi_epi32(lstep3[38], lstep3[56]); - u[6] = _mm_unpacklo_epi32(lstep3[39], lstep3[57]); - u[7] = _mm_unpackhi_epi32(lstep3[39], lstep3[57]); - u[8] = _mm_unpacklo_epi32(lstep3[40], lstep3[54]); - u[9] = _mm_unpackhi_epi32(lstep3[40], lstep3[54]); - u[10] = _mm_unpacklo_epi32(lstep3[41], lstep3[55]); - u[11] = _mm_unpackhi_epi32(lstep3[41], lstep3[55]); - u[12] = _mm_unpacklo_epi32(lstep3[42], lstep3[52]); - u[13] = _mm_unpackhi_epi32(lstep3[42], lstep3[52]); - u[14] = _mm_unpacklo_epi32(lstep3[43], lstep3[53]); - u[15] = _mm_unpackhi_epi32(lstep3[43], lstep3[53]); - - v[0] = k_madd_epi32(u[0], k32_m08_p24); - v[1] = k_madd_epi32(u[1], k32_m08_p24); - v[2] = k_madd_epi32(u[2], k32_m08_p24); - v[3] = k_madd_epi32(u[3], k32_m08_p24); - v[4] = k_madd_epi32(u[4], k32_m08_p24); - v[5] = k_madd_epi32(u[5], k32_m08_p24); - v[6] = k_madd_epi32(u[6], k32_m08_p24); - v[7] = k_madd_epi32(u[7], k32_m08_p24); - v[8] = k_madd_epi32(u[8], k32_m24_m08); - v[9] = k_madd_epi32(u[9], k32_m24_m08); - v[10] = k_madd_epi32(u[10], k32_m24_m08); - v[11] = k_madd_epi32(u[11], k32_m24_m08); - v[12] = k_madd_epi32(u[12], k32_m24_m08); - v[13] = k_madd_epi32(u[13], k32_m24_m08); - v[14] = k_madd_epi32(u[14], k32_m24_m08); - v[15] = k_madd_epi32(u[15], k32_m24_m08); - v[16] = k_madd_epi32(u[12], k32_m08_p24); - v[17] = k_madd_epi32(u[13], k32_m08_p24); - v[18] = k_madd_epi32(u[14], k32_m08_p24); - v[19] = k_madd_epi32(u[15], k32_m08_p24); - v[20] = k_madd_epi32(u[8], k32_m08_p24); - v[21] = k_madd_epi32(u[9], k32_m08_p24); - v[22] = k_madd_epi32(u[10], k32_m08_p24); - v[23] = k_madd_epi32(u[11], k32_m08_p24); - v[24] = k_madd_epi32(u[4], k32_p24_p08); - v[25] = k_madd_epi32(u[5], k32_p24_p08); - v[26] = k_madd_epi32(u[6], k32_p24_p08); - v[27] = k_madd_epi32(u[7], k32_p24_p08); - v[28] = k_madd_epi32(u[0], k32_p24_p08); - v[29] = k_madd_epi32(u[1], k32_p24_p08); - v[30] = k_madd_epi32(u[2], k32_p24_p08); - v[31] = k_madd_epi32(u[3], k32_p24_p08); - -#if DCT_HIGH_BIT_DEPTH - overflow = k_check_epi32_overflow_32( - &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &v[6], &v[7], &v[8], - &v[9], &v[10], &v[11], &v[12], &v[13], &v[14], &v[15], &v[16], - &v[17], &v[18], &v[19], &v[20], &v[21], &v[22], &v[23], &v[24], - &v[25], &v[26], &v[27], &v[28], &v[29], &v[30], &v[31], &kZero); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - u[0] = k_packs_epi64(v[0], v[1]); - u[1] = k_packs_epi64(v[2], v[3]); - u[2] = k_packs_epi64(v[4], v[5]); - u[3] = k_packs_epi64(v[6], v[7]); - u[4] = k_packs_epi64(v[8], v[9]); - u[5] = k_packs_epi64(v[10], v[11]); - u[6] = k_packs_epi64(v[12], v[13]); - u[7] = k_packs_epi64(v[14], v[15]); - u[8] = k_packs_epi64(v[16], v[17]); - u[9] = k_packs_epi64(v[18], v[19]); - u[10] = k_packs_epi64(v[20], v[21]); - u[11] = k_packs_epi64(v[22], v[23]); - u[12] = k_packs_epi64(v[24], v[25]); - u[13] = k_packs_epi64(v[26], v[27]); - u[14] = k_packs_epi64(v[28], v[29]); - u[15] = k_packs_epi64(v[30], v[31]); - - v[0] = _mm_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm_add_epi32(u[3], k__DCT_CONST_ROUNDING); - v[4] = _mm_add_epi32(u[4], k__DCT_CONST_ROUNDING); - v[5] = _mm_add_epi32(u[5], k__DCT_CONST_ROUNDING); - v[6] = _mm_add_epi32(u[6], k__DCT_CONST_ROUNDING); - v[7] = _mm_add_epi32(u[7], k__DCT_CONST_ROUNDING); - v[8] = _mm_add_epi32(u[8], k__DCT_CONST_ROUNDING); - v[9] = _mm_add_epi32(u[9], k__DCT_CONST_ROUNDING); - v[10] = _mm_add_epi32(u[10], k__DCT_CONST_ROUNDING); - v[11] = _mm_add_epi32(u[11], k__DCT_CONST_ROUNDING); - v[12] = _mm_add_epi32(u[12], k__DCT_CONST_ROUNDING); - v[13] = _mm_add_epi32(u[13], k__DCT_CONST_ROUNDING); - v[14] = _mm_add_epi32(u[14], k__DCT_CONST_ROUNDING); - v[15] = _mm_add_epi32(u[15], k__DCT_CONST_ROUNDING); - - lstep1[36] = _mm_srai_epi32(v[0], DCT_CONST_BITS); - lstep1[37] = _mm_srai_epi32(v[1], DCT_CONST_BITS); - lstep1[38] = _mm_srai_epi32(v[2], DCT_CONST_BITS); - lstep1[39] = _mm_srai_epi32(v[3], DCT_CONST_BITS); - lstep1[40] = _mm_srai_epi32(v[4], DCT_CONST_BITS); - lstep1[41] = _mm_srai_epi32(v[5], DCT_CONST_BITS); - lstep1[42] = _mm_srai_epi32(v[6], DCT_CONST_BITS); - lstep1[43] = _mm_srai_epi32(v[7], DCT_CONST_BITS); - lstep1[52] = _mm_srai_epi32(v[8], DCT_CONST_BITS); - lstep1[53] = _mm_srai_epi32(v[9], DCT_CONST_BITS); - lstep1[54] = _mm_srai_epi32(v[10], DCT_CONST_BITS); - lstep1[55] = _mm_srai_epi32(v[11], DCT_CONST_BITS); - lstep1[56] = _mm_srai_epi32(v[12], DCT_CONST_BITS); - lstep1[57] = _mm_srai_epi32(v[13], DCT_CONST_BITS); - lstep1[58] = _mm_srai_epi32(v[14], DCT_CONST_BITS); - lstep1[59] = _mm_srai_epi32(v[15], DCT_CONST_BITS); - } - // stage 5 - { - lstep2[8] = _mm_add_epi32(lstep1[10], lstep3[8]); - lstep2[9] = _mm_add_epi32(lstep1[11], lstep3[9]); - lstep2[10] = _mm_sub_epi32(lstep3[8], lstep1[10]); - lstep2[11] = _mm_sub_epi32(lstep3[9], lstep1[11]); - lstep2[12] = _mm_sub_epi32(lstep3[14], lstep1[12]); - lstep2[13] = _mm_sub_epi32(lstep3[15], lstep1[13]); - lstep2[14] = _mm_add_epi32(lstep1[12], lstep3[14]); - lstep2[15] = _mm_add_epi32(lstep1[13], lstep3[15]); - } - { - const __m128i k32_p16_p16 = pair_set_epi32(cospi_16_64, cospi_16_64); - const __m128i k32_p16_m16 = pair_set_epi32(cospi_16_64, -cospi_16_64); - const __m128i k32_p24_p08 = pair_set_epi32(cospi_24_64, cospi_8_64); - const __m128i k32_m08_p24 = pair_set_epi32(-cospi_8_64, cospi_24_64); - - u[0] = _mm_unpacklo_epi32(lstep1[0], lstep1[2]); - u[1] = _mm_unpackhi_epi32(lstep1[0], lstep1[2]); - u[2] = _mm_unpacklo_epi32(lstep1[1], lstep1[3]); - u[3] = _mm_unpackhi_epi32(lstep1[1], lstep1[3]); - u[4] = _mm_unpacklo_epi32(lstep1[4], lstep1[6]); - u[5] = _mm_unpackhi_epi32(lstep1[4], lstep1[6]); - u[6] = _mm_unpacklo_epi32(lstep1[5], lstep1[7]); - u[7] = _mm_unpackhi_epi32(lstep1[5], lstep1[7]); - - // TODO(jingning): manually inline k_madd_epi32_ to further hide - // instruction latency. - v[0] = k_madd_epi32(u[0], k32_p16_p16); - v[1] = k_madd_epi32(u[1], k32_p16_p16); - v[2] = k_madd_epi32(u[2], k32_p16_p16); - v[3] = k_madd_epi32(u[3], k32_p16_p16); - v[4] = k_madd_epi32(u[0], k32_p16_m16); - v[5] = k_madd_epi32(u[1], k32_p16_m16); - v[6] = k_madd_epi32(u[2], k32_p16_m16); - v[7] = k_madd_epi32(u[3], k32_p16_m16); - v[8] = k_madd_epi32(u[4], k32_p24_p08); - v[9] = k_madd_epi32(u[5], k32_p24_p08); - v[10] = k_madd_epi32(u[6], k32_p24_p08); - v[11] = k_madd_epi32(u[7], k32_p24_p08); - v[12] = k_madd_epi32(u[4], k32_m08_p24); - v[13] = k_madd_epi32(u[5], k32_m08_p24); - v[14] = k_madd_epi32(u[6], k32_m08_p24); - v[15] = k_madd_epi32(u[7], k32_m08_p24); - -#if DCT_HIGH_BIT_DEPTH - overflow = k_check_epi32_overflow_16( - &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &v[6], &v[7], &v[8], - &v[9], &v[10], &v[11], &v[12], &v[13], &v[14], &v[15], &kZero); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - u[0] = k_packs_epi64(v[0], v[1]); - u[1] = k_packs_epi64(v[2], v[3]); - u[2] = k_packs_epi64(v[4], v[5]); - u[3] = k_packs_epi64(v[6], v[7]); - u[4] = k_packs_epi64(v[8], v[9]); - u[5] = k_packs_epi64(v[10], v[11]); - u[6] = k_packs_epi64(v[12], v[13]); - u[7] = k_packs_epi64(v[14], v[15]); - - v[0] = _mm_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm_add_epi32(u[3], k__DCT_CONST_ROUNDING); - v[4] = _mm_add_epi32(u[4], k__DCT_CONST_ROUNDING); - v[5] = _mm_add_epi32(u[5], k__DCT_CONST_ROUNDING); - v[6] = _mm_add_epi32(u[6], k__DCT_CONST_ROUNDING); - v[7] = _mm_add_epi32(u[7], k__DCT_CONST_ROUNDING); - - u[0] = _mm_srai_epi32(v[0], DCT_CONST_BITS); - u[1] = _mm_srai_epi32(v[1], DCT_CONST_BITS); - u[2] = _mm_srai_epi32(v[2], DCT_CONST_BITS); - u[3] = _mm_srai_epi32(v[3], DCT_CONST_BITS); - u[4] = _mm_srai_epi32(v[4], DCT_CONST_BITS); - u[5] = _mm_srai_epi32(v[5], DCT_CONST_BITS); - u[6] = _mm_srai_epi32(v[6], DCT_CONST_BITS); - u[7] = _mm_srai_epi32(v[7], DCT_CONST_BITS); - - sign[0] = _mm_cmplt_epi32(u[0], kZero); - sign[1] = _mm_cmplt_epi32(u[1], kZero); - sign[2] = _mm_cmplt_epi32(u[2], kZero); - sign[3] = _mm_cmplt_epi32(u[3], kZero); - sign[4] = _mm_cmplt_epi32(u[4], kZero); - sign[5] = _mm_cmplt_epi32(u[5], kZero); - sign[6] = _mm_cmplt_epi32(u[6], kZero); - sign[7] = _mm_cmplt_epi32(u[7], kZero); - - u[0] = _mm_sub_epi32(u[0], sign[0]); - u[1] = _mm_sub_epi32(u[1], sign[1]); - u[2] = _mm_sub_epi32(u[2], sign[2]); - u[3] = _mm_sub_epi32(u[3], sign[3]); - u[4] = _mm_sub_epi32(u[4], sign[4]); - u[5] = _mm_sub_epi32(u[5], sign[5]); - u[6] = _mm_sub_epi32(u[6], sign[6]); - u[7] = _mm_sub_epi32(u[7], sign[7]); - - u[0] = _mm_add_epi32(u[0], K32One); - u[1] = _mm_add_epi32(u[1], K32One); - u[2] = _mm_add_epi32(u[2], K32One); - u[3] = _mm_add_epi32(u[3], K32One); - u[4] = _mm_add_epi32(u[4], K32One); - u[5] = _mm_add_epi32(u[5], K32One); - u[6] = _mm_add_epi32(u[6], K32One); - u[7] = _mm_add_epi32(u[7], K32One); - - u[0] = _mm_srai_epi32(u[0], 2); - u[1] = _mm_srai_epi32(u[1], 2); - u[2] = _mm_srai_epi32(u[2], 2); - u[3] = _mm_srai_epi32(u[3], 2); - u[4] = _mm_srai_epi32(u[4], 2); - u[5] = _mm_srai_epi32(u[5], 2); - u[6] = _mm_srai_epi32(u[6], 2); - u[7] = _mm_srai_epi32(u[7], 2); - - // Combine - out[0] = _mm_packs_epi32(u[0], u[1]); - out[16] = _mm_packs_epi32(u[2], u[3]); - out[8] = _mm_packs_epi32(u[4], u[5]); - out[24] = _mm_packs_epi32(u[6], u[7]); -#if DCT_HIGH_BIT_DEPTH - overflow = - check_epi16_overflow_x4(&out[0], &out[16], &out[8], &out[24]); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - const __m128i k32_m08_p24 = pair_set_epi32(-cospi_8_64, cospi_24_64); - const __m128i k32_m24_m08 = pair_set_epi32(-cospi_24_64, -cospi_8_64); - const __m128i k32_p24_p08 = pair_set_epi32(cospi_24_64, cospi_8_64); - - u[0] = _mm_unpacklo_epi32(lstep1[18], lstep1[28]); - u[1] = _mm_unpackhi_epi32(lstep1[18], lstep1[28]); - u[2] = _mm_unpacklo_epi32(lstep1[19], lstep1[29]); - u[3] = _mm_unpackhi_epi32(lstep1[19], lstep1[29]); - u[4] = _mm_unpacklo_epi32(lstep1[20], lstep1[26]); - u[5] = _mm_unpackhi_epi32(lstep1[20], lstep1[26]); - u[6] = _mm_unpacklo_epi32(lstep1[21], lstep1[27]); - u[7] = _mm_unpackhi_epi32(lstep1[21], lstep1[27]); - - v[0] = k_madd_epi32(u[0], k32_m08_p24); - v[1] = k_madd_epi32(u[1], k32_m08_p24); - v[2] = k_madd_epi32(u[2], k32_m08_p24); - v[3] = k_madd_epi32(u[3], k32_m08_p24); - v[4] = k_madd_epi32(u[4], k32_m24_m08); - v[5] = k_madd_epi32(u[5], k32_m24_m08); - v[6] = k_madd_epi32(u[6], k32_m24_m08); - v[7] = k_madd_epi32(u[7], k32_m24_m08); - v[8] = k_madd_epi32(u[4], k32_m08_p24); - v[9] = k_madd_epi32(u[5], k32_m08_p24); - v[10] = k_madd_epi32(u[6], k32_m08_p24); - v[11] = k_madd_epi32(u[7], k32_m08_p24); - v[12] = k_madd_epi32(u[0], k32_p24_p08); - v[13] = k_madd_epi32(u[1], k32_p24_p08); - v[14] = k_madd_epi32(u[2], k32_p24_p08); - v[15] = k_madd_epi32(u[3], k32_p24_p08); - -#if DCT_HIGH_BIT_DEPTH - overflow = k_check_epi32_overflow_16( - &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &v[6], &v[7], &v[8], - &v[9], &v[10], &v[11], &v[12], &v[13], &v[14], &v[15], &kZero); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - u[0] = k_packs_epi64(v[0], v[1]); - u[1] = k_packs_epi64(v[2], v[3]); - u[2] = k_packs_epi64(v[4], v[5]); - u[3] = k_packs_epi64(v[6], v[7]); - u[4] = k_packs_epi64(v[8], v[9]); - u[5] = k_packs_epi64(v[10], v[11]); - u[6] = k_packs_epi64(v[12], v[13]); - u[7] = k_packs_epi64(v[14], v[15]); - - u[0] = _mm_add_epi32(u[0], k__DCT_CONST_ROUNDING); - u[1] = _mm_add_epi32(u[1], k__DCT_CONST_ROUNDING); - u[2] = _mm_add_epi32(u[2], k__DCT_CONST_ROUNDING); - u[3] = _mm_add_epi32(u[3], k__DCT_CONST_ROUNDING); - u[4] = _mm_add_epi32(u[4], k__DCT_CONST_ROUNDING); - u[5] = _mm_add_epi32(u[5], k__DCT_CONST_ROUNDING); - u[6] = _mm_add_epi32(u[6], k__DCT_CONST_ROUNDING); - u[7] = _mm_add_epi32(u[7], k__DCT_CONST_ROUNDING); - - lstep2[18] = _mm_srai_epi32(u[0], DCT_CONST_BITS); - lstep2[19] = _mm_srai_epi32(u[1], DCT_CONST_BITS); - lstep2[20] = _mm_srai_epi32(u[2], DCT_CONST_BITS); - lstep2[21] = _mm_srai_epi32(u[3], DCT_CONST_BITS); - lstep2[26] = _mm_srai_epi32(u[4], DCT_CONST_BITS); - lstep2[27] = _mm_srai_epi32(u[5], DCT_CONST_BITS); - lstep2[28] = _mm_srai_epi32(u[6], DCT_CONST_BITS); - lstep2[29] = _mm_srai_epi32(u[7], DCT_CONST_BITS); - } - { - lstep2[32] = _mm_add_epi32(lstep1[38], lstep3[32]); - lstep2[33] = _mm_add_epi32(lstep1[39], lstep3[33]); - lstep2[34] = _mm_add_epi32(lstep1[36], lstep3[34]); - lstep2[35] = _mm_add_epi32(lstep1[37], lstep3[35]); - lstep2[36] = _mm_sub_epi32(lstep3[34], lstep1[36]); - lstep2[37] = _mm_sub_epi32(lstep3[35], lstep1[37]); - lstep2[38] = _mm_sub_epi32(lstep3[32], lstep1[38]); - lstep2[39] = _mm_sub_epi32(lstep3[33], lstep1[39]); - lstep2[40] = _mm_sub_epi32(lstep3[46], lstep1[40]); - lstep2[41] = _mm_sub_epi32(lstep3[47], lstep1[41]); - lstep2[42] = _mm_sub_epi32(lstep3[44], lstep1[42]); - lstep2[43] = _mm_sub_epi32(lstep3[45], lstep1[43]); - lstep2[44] = _mm_add_epi32(lstep1[42], lstep3[44]); - lstep2[45] = _mm_add_epi32(lstep1[43], lstep3[45]); - lstep2[46] = _mm_add_epi32(lstep1[40], lstep3[46]); - lstep2[47] = _mm_add_epi32(lstep1[41], lstep3[47]); - lstep2[48] = _mm_add_epi32(lstep1[54], lstep3[48]); - lstep2[49] = _mm_add_epi32(lstep1[55], lstep3[49]); - lstep2[50] = _mm_add_epi32(lstep1[52], lstep3[50]); - lstep2[51] = _mm_add_epi32(lstep1[53], lstep3[51]); - lstep2[52] = _mm_sub_epi32(lstep3[50], lstep1[52]); - lstep2[53] = _mm_sub_epi32(lstep3[51], lstep1[53]); - lstep2[54] = _mm_sub_epi32(lstep3[48], lstep1[54]); - lstep2[55] = _mm_sub_epi32(lstep3[49], lstep1[55]); - lstep2[56] = _mm_sub_epi32(lstep3[62], lstep1[56]); - lstep2[57] = _mm_sub_epi32(lstep3[63], lstep1[57]); - lstep2[58] = _mm_sub_epi32(lstep3[60], lstep1[58]); - lstep2[59] = _mm_sub_epi32(lstep3[61], lstep1[59]); - lstep2[60] = _mm_add_epi32(lstep1[58], lstep3[60]); - lstep2[61] = _mm_add_epi32(lstep1[59], lstep3[61]); - lstep2[62] = _mm_add_epi32(lstep1[56], lstep3[62]); - lstep2[63] = _mm_add_epi32(lstep1[57], lstep3[63]); - } - // stage 6 - { - const __m128i k32_p28_p04 = pair_set_epi32(cospi_28_64, cospi_4_64); - const __m128i k32_p12_p20 = pair_set_epi32(cospi_12_64, cospi_20_64); - const __m128i k32_m20_p12 = pair_set_epi32(-cospi_20_64, cospi_12_64); - const __m128i k32_m04_p28 = pair_set_epi32(-cospi_4_64, cospi_28_64); - - u[0] = _mm_unpacklo_epi32(lstep2[8], lstep2[14]); - u[1] = _mm_unpackhi_epi32(lstep2[8], lstep2[14]); - u[2] = _mm_unpacklo_epi32(lstep2[9], lstep2[15]); - u[3] = _mm_unpackhi_epi32(lstep2[9], lstep2[15]); - u[4] = _mm_unpacklo_epi32(lstep2[10], lstep2[12]); - u[5] = _mm_unpackhi_epi32(lstep2[10], lstep2[12]); - u[6] = _mm_unpacklo_epi32(lstep2[11], lstep2[13]); - u[7] = _mm_unpackhi_epi32(lstep2[11], lstep2[13]); - u[8] = _mm_unpacklo_epi32(lstep2[10], lstep2[12]); - u[9] = _mm_unpackhi_epi32(lstep2[10], lstep2[12]); - u[10] = _mm_unpacklo_epi32(lstep2[11], lstep2[13]); - u[11] = _mm_unpackhi_epi32(lstep2[11], lstep2[13]); - u[12] = _mm_unpacklo_epi32(lstep2[8], lstep2[14]); - u[13] = _mm_unpackhi_epi32(lstep2[8], lstep2[14]); - u[14] = _mm_unpacklo_epi32(lstep2[9], lstep2[15]); - u[15] = _mm_unpackhi_epi32(lstep2[9], lstep2[15]); - - v[0] = k_madd_epi32(u[0], k32_p28_p04); - v[1] = k_madd_epi32(u[1], k32_p28_p04); - v[2] = k_madd_epi32(u[2], k32_p28_p04); - v[3] = k_madd_epi32(u[3], k32_p28_p04); - v[4] = k_madd_epi32(u[4], k32_p12_p20); - v[5] = k_madd_epi32(u[5], k32_p12_p20); - v[6] = k_madd_epi32(u[6], k32_p12_p20); - v[7] = k_madd_epi32(u[7], k32_p12_p20); - v[8] = k_madd_epi32(u[8], k32_m20_p12); - v[9] = k_madd_epi32(u[9], k32_m20_p12); - v[10] = k_madd_epi32(u[10], k32_m20_p12); - v[11] = k_madd_epi32(u[11], k32_m20_p12); - v[12] = k_madd_epi32(u[12], k32_m04_p28); - v[13] = k_madd_epi32(u[13], k32_m04_p28); - v[14] = k_madd_epi32(u[14], k32_m04_p28); - v[15] = k_madd_epi32(u[15], k32_m04_p28); - -#if DCT_HIGH_BIT_DEPTH - overflow = k_check_epi32_overflow_16( - &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &v[6], &v[7], &v[8], - &v[9], &v[10], &v[11], &v[12], &v[13], &v[14], &v[15], &kZero); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - u[0] = k_packs_epi64(v[0], v[1]); - u[1] = k_packs_epi64(v[2], v[3]); - u[2] = k_packs_epi64(v[4], v[5]); - u[3] = k_packs_epi64(v[6], v[7]); - u[4] = k_packs_epi64(v[8], v[9]); - u[5] = k_packs_epi64(v[10], v[11]); - u[6] = k_packs_epi64(v[12], v[13]); - u[7] = k_packs_epi64(v[14], v[15]); - - v[0] = _mm_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm_add_epi32(u[3], k__DCT_CONST_ROUNDING); - v[4] = _mm_add_epi32(u[4], k__DCT_CONST_ROUNDING); - v[5] = _mm_add_epi32(u[5], k__DCT_CONST_ROUNDING); - v[6] = _mm_add_epi32(u[6], k__DCT_CONST_ROUNDING); - v[7] = _mm_add_epi32(u[7], k__DCT_CONST_ROUNDING); - - u[0] = _mm_srai_epi32(v[0], DCT_CONST_BITS); - u[1] = _mm_srai_epi32(v[1], DCT_CONST_BITS); - u[2] = _mm_srai_epi32(v[2], DCT_CONST_BITS); - u[3] = _mm_srai_epi32(v[3], DCT_CONST_BITS); - u[4] = _mm_srai_epi32(v[4], DCT_CONST_BITS); - u[5] = _mm_srai_epi32(v[5], DCT_CONST_BITS); - u[6] = _mm_srai_epi32(v[6], DCT_CONST_BITS); - u[7] = _mm_srai_epi32(v[7], DCT_CONST_BITS); - - sign[0] = _mm_cmplt_epi32(u[0], kZero); - sign[1] = _mm_cmplt_epi32(u[1], kZero); - sign[2] = _mm_cmplt_epi32(u[2], kZero); - sign[3] = _mm_cmplt_epi32(u[3], kZero); - sign[4] = _mm_cmplt_epi32(u[4], kZero); - sign[5] = _mm_cmplt_epi32(u[5], kZero); - sign[6] = _mm_cmplt_epi32(u[6], kZero); - sign[7] = _mm_cmplt_epi32(u[7], kZero); - - u[0] = _mm_sub_epi32(u[0], sign[0]); - u[1] = _mm_sub_epi32(u[1], sign[1]); - u[2] = _mm_sub_epi32(u[2], sign[2]); - u[3] = _mm_sub_epi32(u[3], sign[3]); - u[4] = _mm_sub_epi32(u[4], sign[4]); - u[5] = _mm_sub_epi32(u[5], sign[5]); - u[6] = _mm_sub_epi32(u[6], sign[6]); - u[7] = _mm_sub_epi32(u[7], sign[7]); - - u[0] = _mm_add_epi32(u[0], K32One); - u[1] = _mm_add_epi32(u[1], K32One); - u[2] = _mm_add_epi32(u[2], K32One); - u[3] = _mm_add_epi32(u[3], K32One); - u[4] = _mm_add_epi32(u[4], K32One); - u[5] = _mm_add_epi32(u[5], K32One); - u[6] = _mm_add_epi32(u[6], K32One); - u[7] = _mm_add_epi32(u[7], K32One); - - u[0] = _mm_srai_epi32(u[0], 2); - u[1] = _mm_srai_epi32(u[1], 2); - u[2] = _mm_srai_epi32(u[2], 2); - u[3] = _mm_srai_epi32(u[3], 2); - u[4] = _mm_srai_epi32(u[4], 2); - u[5] = _mm_srai_epi32(u[5], 2); - u[6] = _mm_srai_epi32(u[6], 2); - u[7] = _mm_srai_epi32(u[7], 2); - - out[4] = _mm_packs_epi32(u[0], u[1]); - out[20] = _mm_packs_epi32(u[2], u[3]); - out[12] = _mm_packs_epi32(u[4], u[5]); - out[28] = _mm_packs_epi32(u[6], u[7]); -#if DCT_HIGH_BIT_DEPTH - overflow = - check_epi16_overflow_x4(&out[4], &out[20], &out[12], &out[28]); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - lstep3[16] = _mm_add_epi32(lstep2[18], lstep1[16]); - lstep3[17] = _mm_add_epi32(lstep2[19], lstep1[17]); - lstep3[18] = _mm_sub_epi32(lstep1[16], lstep2[18]); - lstep3[19] = _mm_sub_epi32(lstep1[17], lstep2[19]); - lstep3[20] = _mm_sub_epi32(lstep1[22], lstep2[20]); - lstep3[21] = _mm_sub_epi32(lstep1[23], lstep2[21]); - lstep3[22] = _mm_add_epi32(lstep2[20], lstep1[22]); - lstep3[23] = _mm_add_epi32(lstep2[21], lstep1[23]); - lstep3[24] = _mm_add_epi32(lstep2[26], lstep1[24]); - lstep3[25] = _mm_add_epi32(lstep2[27], lstep1[25]); - lstep3[26] = _mm_sub_epi32(lstep1[24], lstep2[26]); - lstep3[27] = _mm_sub_epi32(lstep1[25], lstep2[27]); - lstep3[28] = _mm_sub_epi32(lstep1[30], lstep2[28]); - lstep3[29] = _mm_sub_epi32(lstep1[31], lstep2[29]); - lstep3[30] = _mm_add_epi32(lstep2[28], lstep1[30]); - lstep3[31] = _mm_add_epi32(lstep2[29], lstep1[31]); - } - { - const __m128i k32_m04_p28 = pair_set_epi32(-cospi_4_64, cospi_28_64); - const __m128i k32_m28_m04 = pair_set_epi32(-cospi_28_64, -cospi_4_64); - const __m128i k32_m20_p12 = pair_set_epi32(-cospi_20_64, cospi_12_64); - const __m128i k32_m12_m20 = - pair_set_epi32(-cospi_12_64, -cospi_20_64); - const __m128i k32_p12_p20 = pair_set_epi32(cospi_12_64, cospi_20_64); - const __m128i k32_p28_p04 = pair_set_epi32(cospi_28_64, cospi_4_64); - - u[0] = _mm_unpacklo_epi32(lstep2[34], lstep2[60]); - u[1] = _mm_unpackhi_epi32(lstep2[34], lstep2[60]); - u[2] = _mm_unpacklo_epi32(lstep2[35], lstep2[61]); - u[3] = _mm_unpackhi_epi32(lstep2[35], lstep2[61]); - u[4] = _mm_unpacklo_epi32(lstep2[36], lstep2[58]); - u[5] = _mm_unpackhi_epi32(lstep2[36], lstep2[58]); - u[6] = _mm_unpacklo_epi32(lstep2[37], lstep2[59]); - u[7] = _mm_unpackhi_epi32(lstep2[37], lstep2[59]); - u[8] = _mm_unpacklo_epi32(lstep2[42], lstep2[52]); - u[9] = _mm_unpackhi_epi32(lstep2[42], lstep2[52]); - u[10] = _mm_unpacklo_epi32(lstep2[43], lstep2[53]); - u[11] = _mm_unpackhi_epi32(lstep2[43], lstep2[53]); - u[12] = _mm_unpacklo_epi32(lstep2[44], lstep2[50]); - u[13] = _mm_unpackhi_epi32(lstep2[44], lstep2[50]); - u[14] = _mm_unpacklo_epi32(lstep2[45], lstep2[51]); - u[15] = _mm_unpackhi_epi32(lstep2[45], lstep2[51]); - - v[0] = k_madd_epi32(u[0], k32_m04_p28); - v[1] = k_madd_epi32(u[1], k32_m04_p28); - v[2] = k_madd_epi32(u[2], k32_m04_p28); - v[3] = k_madd_epi32(u[3], k32_m04_p28); - v[4] = k_madd_epi32(u[4], k32_m28_m04); - v[5] = k_madd_epi32(u[5], k32_m28_m04); - v[6] = k_madd_epi32(u[6], k32_m28_m04); - v[7] = k_madd_epi32(u[7], k32_m28_m04); - v[8] = k_madd_epi32(u[8], k32_m20_p12); - v[9] = k_madd_epi32(u[9], k32_m20_p12); - v[10] = k_madd_epi32(u[10], k32_m20_p12); - v[11] = k_madd_epi32(u[11], k32_m20_p12); - v[12] = k_madd_epi32(u[12], k32_m12_m20); - v[13] = k_madd_epi32(u[13], k32_m12_m20); - v[14] = k_madd_epi32(u[14], k32_m12_m20); - v[15] = k_madd_epi32(u[15], k32_m12_m20); - v[16] = k_madd_epi32(u[12], k32_m20_p12); - v[17] = k_madd_epi32(u[13], k32_m20_p12); - v[18] = k_madd_epi32(u[14], k32_m20_p12); - v[19] = k_madd_epi32(u[15], k32_m20_p12); - v[20] = k_madd_epi32(u[8], k32_p12_p20); - v[21] = k_madd_epi32(u[9], k32_p12_p20); - v[22] = k_madd_epi32(u[10], k32_p12_p20); - v[23] = k_madd_epi32(u[11], k32_p12_p20); - v[24] = k_madd_epi32(u[4], k32_m04_p28); - v[25] = k_madd_epi32(u[5], k32_m04_p28); - v[26] = k_madd_epi32(u[6], k32_m04_p28); - v[27] = k_madd_epi32(u[7], k32_m04_p28); - v[28] = k_madd_epi32(u[0], k32_p28_p04); - v[29] = k_madd_epi32(u[1], k32_p28_p04); - v[30] = k_madd_epi32(u[2], k32_p28_p04); - v[31] = k_madd_epi32(u[3], k32_p28_p04); - -#if DCT_HIGH_BIT_DEPTH - overflow = k_check_epi32_overflow_32( - &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &v[6], &v[7], &v[8], - &v[9], &v[10], &v[11], &v[12], &v[13], &v[14], &v[15], &v[16], - &v[17], &v[18], &v[19], &v[20], &v[21], &v[22], &v[23], &v[24], - &v[25], &v[26], &v[27], &v[28], &v[29], &v[30], &v[31], &kZero); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - u[0] = k_packs_epi64(v[0], v[1]); - u[1] = k_packs_epi64(v[2], v[3]); - u[2] = k_packs_epi64(v[4], v[5]); - u[3] = k_packs_epi64(v[6], v[7]); - u[4] = k_packs_epi64(v[8], v[9]); - u[5] = k_packs_epi64(v[10], v[11]); - u[6] = k_packs_epi64(v[12], v[13]); - u[7] = k_packs_epi64(v[14], v[15]); - u[8] = k_packs_epi64(v[16], v[17]); - u[9] = k_packs_epi64(v[18], v[19]); - u[10] = k_packs_epi64(v[20], v[21]); - u[11] = k_packs_epi64(v[22], v[23]); - u[12] = k_packs_epi64(v[24], v[25]); - u[13] = k_packs_epi64(v[26], v[27]); - u[14] = k_packs_epi64(v[28], v[29]); - u[15] = k_packs_epi64(v[30], v[31]); - - v[0] = _mm_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm_add_epi32(u[3], k__DCT_CONST_ROUNDING); - v[4] = _mm_add_epi32(u[4], k__DCT_CONST_ROUNDING); - v[5] = _mm_add_epi32(u[5], k__DCT_CONST_ROUNDING); - v[6] = _mm_add_epi32(u[6], k__DCT_CONST_ROUNDING); - v[7] = _mm_add_epi32(u[7], k__DCT_CONST_ROUNDING); - v[8] = _mm_add_epi32(u[8], k__DCT_CONST_ROUNDING); - v[9] = _mm_add_epi32(u[9], k__DCT_CONST_ROUNDING); - v[10] = _mm_add_epi32(u[10], k__DCT_CONST_ROUNDING); - v[11] = _mm_add_epi32(u[11], k__DCT_CONST_ROUNDING); - v[12] = _mm_add_epi32(u[12], k__DCT_CONST_ROUNDING); - v[13] = _mm_add_epi32(u[13], k__DCT_CONST_ROUNDING); - v[14] = _mm_add_epi32(u[14], k__DCT_CONST_ROUNDING); - v[15] = _mm_add_epi32(u[15], k__DCT_CONST_ROUNDING); - - lstep3[34] = _mm_srai_epi32(v[0], DCT_CONST_BITS); - lstep3[35] = _mm_srai_epi32(v[1], DCT_CONST_BITS); - lstep3[36] = _mm_srai_epi32(v[2], DCT_CONST_BITS); - lstep3[37] = _mm_srai_epi32(v[3], DCT_CONST_BITS); - lstep3[42] = _mm_srai_epi32(v[4], DCT_CONST_BITS); - lstep3[43] = _mm_srai_epi32(v[5], DCT_CONST_BITS); - lstep3[44] = _mm_srai_epi32(v[6], DCT_CONST_BITS); - lstep3[45] = _mm_srai_epi32(v[7], DCT_CONST_BITS); - lstep3[50] = _mm_srai_epi32(v[8], DCT_CONST_BITS); - lstep3[51] = _mm_srai_epi32(v[9], DCT_CONST_BITS); - lstep3[52] = _mm_srai_epi32(v[10], DCT_CONST_BITS); - lstep3[53] = _mm_srai_epi32(v[11], DCT_CONST_BITS); - lstep3[58] = _mm_srai_epi32(v[12], DCT_CONST_BITS); - lstep3[59] = _mm_srai_epi32(v[13], DCT_CONST_BITS); - lstep3[60] = _mm_srai_epi32(v[14], DCT_CONST_BITS); - lstep3[61] = _mm_srai_epi32(v[15], DCT_CONST_BITS); - } - // stage 7 - { - const __m128i k32_p30_p02 = pair_set_epi32(cospi_30_64, cospi_2_64); - const __m128i k32_p14_p18 = pair_set_epi32(cospi_14_64, cospi_18_64); - const __m128i k32_p22_p10 = pair_set_epi32(cospi_22_64, cospi_10_64); - const __m128i k32_p06_p26 = pair_set_epi32(cospi_6_64, cospi_26_64); - const __m128i k32_m26_p06 = pair_set_epi32(-cospi_26_64, cospi_6_64); - const __m128i k32_m10_p22 = pair_set_epi32(-cospi_10_64, cospi_22_64); - const __m128i k32_m18_p14 = pair_set_epi32(-cospi_18_64, cospi_14_64); - const __m128i k32_m02_p30 = pair_set_epi32(-cospi_2_64, cospi_30_64); - - u[0] = _mm_unpacklo_epi32(lstep3[16], lstep3[30]); - u[1] = _mm_unpackhi_epi32(lstep3[16], lstep3[30]); - u[2] = _mm_unpacklo_epi32(lstep3[17], lstep3[31]); - u[3] = _mm_unpackhi_epi32(lstep3[17], lstep3[31]); - u[4] = _mm_unpacklo_epi32(lstep3[18], lstep3[28]); - u[5] = _mm_unpackhi_epi32(lstep3[18], lstep3[28]); - u[6] = _mm_unpacklo_epi32(lstep3[19], lstep3[29]); - u[7] = _mm_unpackhi_epi32(lstep3[19], lstep3[29]); - u[8] = _mm_unpacklo_epi32(lstep3[20], lstep3[26]); - u[9] = _mm_unpackhi_epi32(lstep3[20], lstep3[26]); - u[10] = _mm_unpacklo_epi32(lstep3[21], lstep3[27]); - u[11] = _mm_unpackhi_epi32(lstep3[21], lstep3[27]); - u[12] = _mm_unpacklo_epi32(lstep3[22], lstep3[24]); - u[13] = _mm_unpackhi_epi32(lstep3[22], lstep3[24]); - u[14] = _mm_unpacklo_epi32(lstep3[23], lstep3[25]); - u[15] = _mm_unpackhi_epi32(lstep3[23], lstep3[25]); - - v[0] = k_madd_epi32(u[0], k32_p30_p02); - v[1] = k_madd_epi32(u[1], k32_p30_p02); - v[2] = k_madd_epi32(u[2], k32_p30_p02); - v[3] = k_madd_epi32(u[3], k32_p30_p02); - v[4] = k_madd_epi32(u[4], k32_p14_p18); - v[5] = k_madd_epi32(u[5], k32_p14_p18); - v[6] = k_madd_epi32(u[6], k32_p14_p18); - v[7] = k_madd_epi32(u[7], k32_p14_p18); - v[8] = k_madd_epi32(u[8], k32_p22_p10); - v[9] = k_madd_epi32(u[9], k32_p22_p10); - v[10] = k_madd_epi32(u[10], k32_p22_p10); - v[11] = k_madd_epi32(u[11], k32_p22_p10); - v[12] = k_madd_epi32(u[12], k32_p06_p26); - v[13] = k_madd_epi32(u[13], k32_p06_p26); - v[14] = k_madd_epi32(u[14], k32_p06_p26); - v[15] = k_madd_epi32(u[15], k32_p06_p26); - v[16] = k_madd_epi32(u[12], k32_m26_p06); - v[17] = k_madd_epi32(u[13], k32_m26_p06); - v[18] = k_madd_epi32(u[14], k32_m26_p06); - v[19] = k_madd_epi32(u[15], k32_m26_p06); - v[20] = k_madd_epi32(u[8], k32_m10_p22); - v[21] = k_madd_epi32(u[9], k32_m10_p22); - v[22] = k_madd_epi32(u[10], k32_m10_p22); - v[23] = k_madd_epi32(u[11], k32_m10_p22); - v[24] = k_madd_epi32(u[4], k32_m18_p14); - v[25] = k_madd_epi32(u[5], k32_m18_p14); - v[26] = k_madd_epi32(u[6], k32_m18_p14); - v[27] = k_madd_epi32(u[7], k32_m18_p14); - v[28] = k_madd_epi32(u[0], k32_m02_p30); - v[29] = k_madd_epi32(u[1], k32_m02_p30); - v[30] = k_madd_epi32(u[2], k32_m02_p30); - v[31] = k_madd_epi32(u[3], k32_m02_p30); - -#if DCT_HIGH_BIT_DEPTH - overflow = k_check_epi32_overflow_32( - &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &v[6], &v[7], &v[8], - &v[9], &v[10], &v[11], &v[12], &v[13], &v[14], &v[15], &v[16], - &v[17], &v[18], &v[19], &v[20], &v[21], &v[22], &v[23], &v[24], - &v[25], &v[26], &v[27], &v[28], &v[29], &v[30], &v[31], &kZero); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - u[0] = k_packs_epi64(v[0], v[1]); - u[1] = k_packs_epi64(v[2], v[3]); - u[2] = k_packs_epi64(v[4], v[5]); - u[3] = k_packs_epi64(v[6], v[7]); - u[4] = k_packs_epi64(v[8], v[9]); - u[5] = k_packs_epi64(v[10], v[11]); - u[6] = k_packs_epi64(v[12], v[13]); - u[7] = k_packs_epi64(v[14], v[15]); - u[8] = k_packs_epi64(v[16], v[17]); - u[9] = k_packs_epi64(v[18], v[19]); - u[10] = k_packs_epi64(v[20], v[21]); - u[11] = k_packs_epi64(v[22], v[23]); - u[12] = k_packs_epi64(v[24], v[25]); - u[13] = k_packs_epi64(v[26], v[27]); - u[14] = k_packs_epi64(v[28], v[29]); - u[15] = k_packs_epi64(v[30], v[31]); - - v[0] = _mm_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm_add_epi32(u[3], k__DCT_CONST_ROUNDING); - v[4] = _mm_add_epi32(u[4], k__DCT_CONST_ROUNDING); - v[5] = _mm_add_epi32(u[5], k__DCT_CONST_ROUNDING); - v[6] = _mm_add_epi32(u[6], k__DCT_CONST_ROUNDING); - v[7] = _mm_add_epi32(u[7], k__DCT_CONST_ROUNDING); - v[8] = _mm_add_epi32(u[8], k__DCT_CONST_ROUNDING); - v[9] = _mm_add_epi32(u[9], k__DCT_CONST_ROUNDING); - v[10] = _mm_add_epi32(u[10], k__DCT_CONST_ROUNDING); - v[11] = _mm_add_epi32(u[11], k__DCT_CONST_ROUNDING); - v[12] = _mm_add_epi32(u[12], k__DCT_CONST_ROUNDING); - v[13] = _mm_add_epi32(u[13], k__DCT_CONST_ROUNDING); - v[14] = _mm_add_epi32(u[14], k__DCT_CONST_ROUNDING); - v[15] = _mm_add_epi32(u[15], k__DCT_CONST_ROUNDING); - - u[0] = _mm_srai_epi32(v[0], DCT_CONST_BITS); - u[1] = _mm_srai_epi32(v[1], DCT_CONST_BITS); - u[2] = _mm_srai_epi32(v[2], DCT_CONST_BITS); - u[3] = _mm_srai_epi32(v[3], DCT_CONST_BITS); - u[4] = _mm_srai_epi32(v[4], DCT_CONST_BITS); - u[5] = _mm_srai_epi32(v[5], DCT_CONST_BITS); - u[6] = _mm_srai_epi32(v[6], DCT_CONST_BITS); - u[7] = _mm_srai_epi32(v[7], DCT_CONST_BITS); - u[8] = _mm_srai_epi32(v[8], DCT_CONST_BITS); - u[9] = _mm_srai_epi32(v[9], DCT_CONST_BITS); - u[10] = _mm_srai_epi32(v[10], DCT_CONST_BITS); - u[11] = _mm_srai_epi32(v[11], DCT_CONST_BITS); - u[12] = _mm_srai_epi32(v[12], DCT_CONST_BITS); - u[13] = _mm_srai_epi32(v[13], DCT_CONST_BITS); - u[14] = _mm_srai_epi32(v[14], DCT_CONST_BITS); - u[15] = _mm_srai_epi32(v[15], DCT_CONST_BITS); - - v[0] = _mm_cmplt_epi32(u[0], kZero); - v[1] = _mm_cmplt_epi32(u[1], kZero); - v[2] = _mm_cmplt_epi32(u[2], kZero); - v[3] = _mm_cmplt_epi32(u[3], kZero); - v[4] = _mm_cmplt_epi32(u[4], kZero); - v[5] = _mm_cmplt_epi32(u[5], kZero); - v[6] = _mm_cmplt_epi32(u[6], kZero); - v[7] = _mm_cmplt_epi32(u[7], kZero); - v[8] = _mm_cmplt_epi32(u[8], kZero); - v[9] = _mm_cmplt_epi32(u[9], kZero); - v[10] = _mm_cmplt_epi32(u[10], kZero); - v[11] = _mm_cmplt_epi32(u[11], kZero); - v[12] = _mm_cmplt_epi32(u[12], kZero); - v[13] = _mm_cmplt_epi32(u[13], kZero); - v[14] = _mm_cmplt_epi32(u[14], kZero); - v[15] = _mm_cmplt_epi32(u[15], kZero); - - u[0] = _mm_sub_epi32(u[0], v[0]); - u[1] = _mm_sub_epi32(u[1], v[1]); - u[2] = _mm_sub_epi32(u[2], v[2]); - u[3] = _mm_sub_epi32(u[3], v[3]); - u[4] = _mm_sub_epi32(u[4], v[4]); - u[5] = _mm_sub_epi32(u[5], v[5]); - u[6] = _mm_sub_epi32(u[6], v[6]); - u[7] = _mm_sub_epi32(u[7], v[7]); - u[8] = _mm_sub_epi32(u[8], v[8]); - u[9] = _mm_sub_epi32(u[9], v[9]); - u[10] = _mm_sub_epi32(u[10], v[10]); - u[11] = _mm_sub_epi32(u[11], v[11]); - u[12] = _mm_sub_epi32(u[12], v[12]); - u[13] = _mm_sub_epi32(u[13], v[13]); - u[14] = _mm_sub_epi32(u[14], v[14]); - u[15] = _mm_sub_epi32(u[15], v[15]); - - v[0] = _mm_add_epi32(u[0], K32One); - v[1] = _mm_add_epi32(u[1], K32One); - v[2] = _mm_add_epi32(u[2], K32One); - v[3] = _mm_add_epi32(u[3], K32One); - v[4] = _mm_add_epi32(u[4], K32One); - v[5] = _mm_add_epi32(u[5], K32One); - v[6] = _mm_add_epi32(u[6], K32One); - v[7] = _mm_add_epi32(u[7], K32One); - v[8] = _mm_add_epi32(u[8], K32One); - v[9] = _mm_add_epi32(u[9], K32One); - v[10] = _mm_add_epi32(u[10], K32One); - v[11] = _mm_add_epi32(u[11], K32One); - v[12] = _mm_add_epi32(u[12], K32One); - v[13] = _mm_add_epi32(u[13], K32One); - v[14] = _mm_add_epi32(u[14], K32One); - v[15] = _mm_add_epi32(u[15], K32One); - - u[0] = _mm_srai_epi32(v[0], 2); - u[1] = _mm_srai_epi32(v[1], 2); - u[2] = _mm_srai_epi32(v[2], 2); - u[3] = _mm_srai_epi32(v[3], 2); - u[4] = _mm_srai_epi32(v[4], 2); - u[5] = _mm_srai_epi32(v[5], 2); - u[6] = _mm_srai_epi32(v[6], 2); - u[7] = _mm_srai_epi32(v[7], 2); - u[8] = _mm_srai_epi32(v[8], 2); - u[9] = _mm_srai_epi32(v[9], 2); - u[10] = _mm_srai_epi32(v[10], 2); - u[11] = _mm_srai_epi32(v[11], 2); - u[12] = _mm_srai_epi32(v[12], 2); - u[13] = _mm_srai_epi32(v[13], 2); - u[14] = _mm_srai_epi32(v[14], 2); - u[15] = _mm_srai_epi32(v[15], 2); - - out[2] = _mm_packs_epi32(u[0], u[1]); - out[18] = _mm_packs_epi32(u[2], u[3]); - out[10] = _mm_packs_epi32(u[4], u[5]); - out[26] = _mm_packs_epi32(u[6], u[7]); - out[6] = _mm_packs_epi32(u[8], u[9]); - out[22] = _mm_packs_epi32(u[10], u[11]); - out[14] = _mm_packs_epi32(u[12], u[13]); - out[30] = _mm_packs_epi32(u[14], u[15]); -#if DCT_HIGH_BIT_DEPTH - overflow = - check_epi16_overflow_x8(&out[2], &out[18], &out[10], &out[26], - &out[6], &out[22], &out[14], &out[30]); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - lstep1[32] = _mm_add_epi32(lstep3[34], lstep2[32]); - lstep1[33] = _mm_add_epi32(lstep3[35], lstep2[33]); - lstep1[34] = _mm_sub_epi32(lstep2[32], lstep3[34]); - lstep1[35] = _mm_sub_epi32(lstep2[33], lstep3[35]); - lstep1[36] = _mm_sub_epi32(lstep2[38], lstep3[36]); - lstep1[37] = _mm_sub_epi32(lstep2[39], lstep3[37]); - lstep1[38] = _mm_add_epi32(lstep3[36], lstep2[38]); - lstep1[39] = _mm_add_epi32(lstep3[37], lstep2[39]); - lstep1[40] = _mm_add_epi32(lstep3[42], lstep2[40]); - lstep1[41] = _mm_add_epi32(lstep3[43], lstep2[41]); - lstep1[42] = _mm_sub_epi32(lstep2[40], lstep3[42]); - lstep1[43] = _mm_sub_epi32(lstep2[41], lstep3[43]); - lstep1[44] = _mm_sub_epi32(lstep2[46], lstep3[44]); - lstep1[45] = _mm_sub_epi32(lstep2[47], lstep3[45]); - lstep1[46] = _mm_add_epi32(lstep3[44], lstep2[46]); - lstep1[47] = _mm_add_epi32(lstep3[45], lstep2[47]); - lstep1[48] = _mm_add_epi32(lstep3[50], lstep2[48]); - lstep1[49] = _mm_add_epi32(lstep3[51], lstep2[49]); - lstep1[50] = _mm_sub_epi32(lstep2[48], lstep3[50]); - lstep1[51] = _mm_sub_epi32(lstep2[49], lstep3[51]); - lstep1[52] = _mm_sub_epi32(lstep2[54], lstep3[52]); - lstep1[53] = _mm_sub_epi32(lstep2[55], lstep3[53]); - lstep1[54] = _mm_add_epi32(lstep3[52], lstep2[54]); - lstep1[55] = _mm_add_epi32(lstep3[53], lstep2[55]); - lstep1[56] = _mm_add_epi32(lstep3[58], lstep2[56]); - lstep1[57] = _mm_add_epi32(lstep3[59], lstep2[57]); - lstep1[58] = _mm_sub_epi32(lstep2[56], lstep3[58]); - lstep1[59] = _mm_sub_epi32(lstep2[57], lstep3[59]); - lstep1[60] = _mm_sub_epi32(lstep2[62], lstep3[60]); - lstep1[61] = _mm_sub_epi32(lstep2[63], lstep3[61]); - lstep1[62] = _mm_add_epi32(lstep3[60], lstep2[62]); - lstep1[63] = _mm_add_epi32(lstep3[61], lstep2[63]); - } - // stage 8 - { - const __m128i k32_p31_p01 = pair_set_epi32(cospi_31_64, cospi_1_64); - const __m128i k32_p15_p17 = pair_set_epi32(cospi_15_64, cospi_17_64); - const __m128i k32_p23_p09 = pair_set_epi32(cospi_23_64, cospi_9_64); - const __m128i k32_p07_p25 = pair_set_epi32(cospi_7_64, cospi_25_64); - const __m128i k32_m25_p07 = pair_set_epi32(-cospi_25_64, cospi_7_64); - const __m128i k32_m09_p23 = pair_set_epi32(-cospi_9_64, cospi_23_64); - const __m128i k32_m17_p15 = pair_set_epi32(-cospi_17_64, cospi_15_64); - const __m128i k32_m01_p31 = pair_set_epi32(-cospi_1_64, cospi_31_64); - - u[0] = _mm_unpacklo_epi32(lstep1[32], lstep1[62]); - u[1] = _mm_unpackhi_epi32(lstep1[32], lstep1[62]); - u[2] = _mm_unpacklo_epi32(lstep1[33], lstep1[63]); - u[3] = _mm_unpackhi_epi32(lstep1[33], lstep1[63]); - u[4] = _mm_unpacklo_epi32(lstep1[34], lstep1[60]); - u[5] = _mm_unpackhi_epi32(lstep1[34], lstep1[60]); - u[6] = _mm_unpacklo_epi32(lstep1[35], lstep1[61]); - u[7] = _mm_unpackhi_epi32(lstep1[35], lstep1[61]); - u[8] = _mm_unpacklo_epi32(lstep1[36], lstep1[58]); - u[9] = _mm_unpackhi_epi32(lstep1[36], lstep1[58]); - u[10] = _mm_unpacklo_epi32(lstep1[37], lstep1[59]); - u[11] = _mm_unpackhi_epi32(lstep1[37], lstep1[59]); - u[12] = _mm_unpacklo_epi32(lstep1[38], lstep1[56]); - u[13] = _mm_unpackhi_epi32(lstep1[38], lstep1[56]); - u[14] = _mm_unpacklo_epi32(lstep1[39], lstep1[57]); - u[15] = _mm_unpackhi_epi32(lstep1[39], lstep1[57]); - - v[0] = k_madd_epi32(u[0], k32_p31_p01); - v[1] = k_madd_epi32(u[1], k32_p31_p01); - v[2] = k_madd_epi32(u[2], k32_p31_p01); - v[3] = k_madd_epi32(u[3], k32_p31_p01); - v[4] = k_madd_epi32(u[4], k32_p15_p17); - v[5] = k_madd_epi32(u[5], k32_p15_p17); - v[6] = k_madd_epi32(u[6], k32_p15_p17); - v[7] = k_madd_epi32(u[7], k32_p15_p17); - v[8] = k_madd_epi32(u[8], k32_p23_p09); - v[9] = k_madd_epi32(u[9], k32_p23_p09); - v[10] = k_madd_epi32(u[10], k32_p23_p09); - v[11] = k_madd_epi32(u[11], k32_p23_p09); - v[12] = k_madd_epi32(u[12], k32_p07_p25); - v[13] = k_madd_epi32(u[13], k32_p07_p25); - v[14] = k_madd_epi32(u[14], k32_p07_p25); - v[15] = k_madd_epi32(u[15], k32_p07_p25); - v[16] = k_madd_epi32(u[12], k32_m25_p07); - v[17] = k_madd_epi32(u[13], k32_m25_p07); - v[18] = k_madd_epi32(u[14], k32_m25_p07); - v[19] = k_madd_epi32(u[15], k32_m25_p07); - v[20] = k_madd_epi32(u[8], k32_m09_p23); - v[21] = k_madd_epi32(u[9], k32_m09_p23); - v[22] = k_madd_epi32(u[10], k32_m09_p23); - v[23] = k_madd_epi32(u[11], k32_m09_p23); - v[24] = k_madd_epi32(u[4], k32_m17_p15); - v[25] = k_madd_epi32(u[5], k32_m17_p15); - v[26] = k_madd_epi32(u[6], k32_m17_p15); - v[27] = k_madd_epi32(u[7], k32_m17_p15); - v[28] = k_madd_epi32(u[0], k32_m01_p31); - v[29] = k_madd_epi32(u[1], k32_m01_p31); - v[30] = k_madd_epi32(u[2], k32_m01_p31); - v[31] = k_madd_epi32(u[3], k32_m01_p31); - -#if DCT_HIGH_BIT_DEPTH - overflow = k_check_epi32_overflow_32( - &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &v[6], &v[7], &v[8], - &v[9], &v[10], &v[11], &v[12], &v[13], &v[14], &v[15], &v[16], - &v[17], &v[18], &v[19], &v[20], &v[21], &v[22], &v[23], &v[24], - &v[25], &v[26], &v[27], &v[28], &v[29], &v[30], &v[31], &kZero); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - u[0] = k_packs_epi64(v[0], v[1]); - u[1] = k_packs_epi64(v[2], v[3]); - u[2] = k_packs_epi64(v[4], v[5]); - u[3] = k_packs_epi64(v[6], v[7]); - u[4] = k_packs_epi64(v[8], v[9]); - u[5] = k_packs_epi64(v[10], v[11]); - u[6] = k_packs_epi64(v[12], v[13]); - u[7] = k_packs_epi64(v[14], v[15]); - u[8] = k_packs_epi64(v[16], v[17]); - u[9] = k_packs_epi64(v[18], v[19]); - u[10] = k_packs_epi64(v[20], v[21]); - u[11] = k_packs_epi64(v[22], v[23]); - u[12] = k_packs_epi64(v[24], v[25]); - u[13] = k_packs_epi64(v[26], v[27]); - u[14] = k_packs_epi64(v[28], v[29]); - u[15] = k_packs_epi64(v[30], v[31]); - - v[0] = _mm_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm_add_epi32(u[3], k__DCT_CONST_ROUNDING); - v[4] = _mm_add_epi32(u[4], k__DCT_CONST_ROUNDING); - v[5] = _mm_add_epi32(u[5], k__DCT_CONST_ROUNDING); - v[6] = _mm_add_epi32(u[6], k__DCT_CONST_ROUNDING); - v[7] = _mm_add_epi32(u[7], k__DCT_CONST_ROUNDING); - v[8] = _mm_add_epi32(u[8], k__DCT_CONST_ROUNDING); - v[9] = _mm_add_epi32(u[9], k__DCT_CONST_ROUNDING); - v[10] = _mm_add_epi32(u[10], k__DCT_CONST_ROUNDING); - v[11] = _mm_add_epi32(u[11], k__DCT_CONST_ROUNDING); - v[12] = _mm_add_epi32(u[12], k__DCT_CONST_ROUNDING); - v[13] = _mm_add_epi32(u[13], k__DCT_CONST_ROUNDING); - v[14] = _mm_add_epi32(u[14], k__DCT_CONST_ROUNDING); - v[15] = _mm_add_epi32(u[15], k__DCT_CONST_ROUNDING); - - u[0] = _mm_srai_epi32(v[0], DCT_CONST_BITS); - u[1] = _mm_srai_epi32(v[1], DCT_CONST_BITS); - u[2] = _mm_srai_epi32(v[2], DCT_CONST_BITS); - u[3] = _mm_srai_epi32(v[3], DCT_CONST_BITS); - u[4] = _mm_srai_epi32(v[4], DCT_CONST_BITS); - u[5] = _mm_srai_epi32(v[5], DCT_CONST_BITS); - u[6] = _mm_srai_epi32(v[6], DCT_CONST_BITS); - u[7] = _mm_srai_epi32(v[7], DCT_CONST_BITS); - u[8] = _mm_srai_epi32(v[8], DCT_CONST_BITS); - u[9] = _mm_srai_epi32(v[9], DCT_CONST_BITS); - u[10] = _mm_srai_epi32(v[10], DCT_CONST_BITS); - u[11] = _mm_srai_epi32(v[11], DCT_CONST_BITS); - u[12] = _mm_srai_epi32(v[12], DCT_CONST_BITS); - u[13] = _mm_srai_epi32(v[13], DCT_CONST_BITS); - u[14] = _mm_srai_epi32(v[14], DCT_CONST_BITS); - u[15] = _mm_srai_epi32(v[15], DCT_CONST_BITS); - - v[0] = _mm_cmplt_epi32(u[0], kZero); - v[1] = _mm_cmplt_epi32(u[1], kZero); - v[2] = _mm_cmplt_epi32(u[2], kZero); - v[3] = _mm_cmplt_epi32(u[3], kZero); - v[4] = _mm_cmplt_epi32(u[4], kZero); - v[5] = _mm_cmplt_epi32(u[5], kZero); - v[6] = _mm_cmplt_epi32(u[6], kZero); - v[7] = _mm_cmplt_epi32(u[7], kZero); - v[8] = _mm_cmplt_epi32(u[8], kZero); - v[9] = _mm_cmplt_epi32(u[9], kZero); - v[10] = _mm_cmplt_epi32(u[10], kZero); - v[11] = _mm_cmplt_epi32(u[11], kZero); - v[12] = _mm_cmplt_epi32(u[12], kZero); - v[13] = _mm_cmplt_epi32(u[13], kZero); - v[14] = _mm_cmplt_epi32(u[14], kZero); - v[15] = _mm_cmplt_epi32(u[15], kZero); - - u[0] = _mm_sub_epi32(u[0], v[0]); - u[1] = _mm_sub_epi32(u[1], v[1]); - u[2] = _mm_sub_epi32(u[2], v[2]); - u[3] = _mm_sub_epi32(u[3], v[3]); - u[4] = _mm_sub_epi32(u[4], v[4]); - u[5] = _mm_sub_epi32(u[5], v[5]); - u[6] = _mm_sub_epi32(u[6], v[6]); - u[7] = _mm_sub_epi32(u[7], v[7]); - u[8] = _mm_sub_epi32(u[8], v[8]); - u[9] = _mm_sub_epi32(u[9], v[9]); - u[10] = _mm_sub_epi32(u[10], v[10]); - u[11] = _mm_sub_epi32(u[11], v[11]); - u[12] = _mm_sub_epi32(u[12], v[12]); - u[13] = _mm_sub_epi32(u[13], v[13]); - u[14] = _mm_sub_epi32(u[14], v[14]); - u[15] = _mm_sub_epi32(u[15], v[15]); - - v[0] = _mm_add_epi32(u[0], K32One); - v[1] = _mm_add_epi32(u[1], K32One); - v[2] = _mm_add_epi32(u[2], K32One); - v[3] = _mm_add_epi32(u[3], K32One); - v[4] = _mm_add_epi32(u[4], K32One); - v[5] = _mm_add_epi32(u[5], K32One); - v[6] = _mm_add_epi32(u[6], K32One); - v[7] = _mm_add_epi32(u[7], K32One); - v[8] = _mm_add_epi32(u[8], K32One); - v[9] = _mm_add_epi32(u[9], K32One); - v[10] = _mm_add_epi32(u[10], K32One); - v[11] = _mm_add_epi32(u[11], K32One); - v[12] = _mm_add_epi32(u[12], K32One); - v[13] = _mm_add_epi32(u[13], K32One); - v[14] = _mm_add_epi32(u[14], K32One); - v[15] = _mm_add_epi32(u[15], K32One); - - u[0] = _mm_srai_epi32(v[0], 2); - u[1] = _mm_srai_epi32(v[1], 2); - u[2] = _mm_srai_epi32(v[2], 2); - u[3] = _mm_srai_epi32(v[3], 2); - u[4] = _mm_srai_epi32(v[4], 2); - u[5] = _mm_srai_epi32(v[5], 2); - u[6] = _mm_srai_epi32(v[6], 2); - u[7] = _mm_srai_epi32(v[7], 2); - u[8] = _mm_srai_epi32(v[8], 2); - u[9] = _mm_srai_epi32(v[9], 2); - u[10] = _mm_srai_epi32(v[10], 2); - u[11] = _mm_srai_epi32(v[11], 2); - u[12] = _mm_srai_epi32(v[12], 2); - u[13] = _mm_srai_epi32(v[13], 2); - u[14] = _mm_srai_epi32(v[14], 2); - u[15] = _mm_srai_epi32(v[15], 2); - - out[1] = _mm_packs_epi32(u[0], u[1]); - out[17] = _mm_packs_epi32(u[2], u[3]); - out[9] = _mm_packs_epi32(u[4], u[5]); - out[25] = _mm_packs_epi32(u[6], u[7]); - out[7] = _mm_packs_epi32(u[8], u[9]); - out[23] = _mm_packs_epi32(u[10], u[11]); - out[15] = _mm_packs_epi32(u[12], u[13]); - out[31] = _mm_packs_epi32(u[14], u[15]); -#if DCT_HIGH_BIT_DEPTH - overflow = - check_epi16_overflow_x8(&out[1], &out[17], &out[9], &out[25], - &out[7], &out[23], &out[15], &out[31]); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - const __m128i k32_p27_p05 = pair_set_epi32(cospi_27_64, cospi_5_64); - const __m128i k32_p11_p21 = pair_set_epi32(cospi_11_64, cospi_21_64); - const __m128i k32_p19_p13 = pair_set_epi32(cospi_19_64, cospi_13_64); - const __m128i k32_p03_p29 = pair_set_epi32(cospi_3_64, cospi_29_64); - const __m128i k32_m29_p03 = pair_set_epi32(-cospi_29_64, cospi_3_64); - const __m128i k32_m13_p19 = pair_set_epi32(-cospi_13_64, cospi_19_64); - const __m128i k32_m21_p11 = pair_set_epi32(-cospi_21_64, cospi_11_64); - const __m128i k32_m05_p27 = pair_set_epi32(-cospi_5_64, cospi_27_64); - - u[0] = _mm_unpacklo_epi32(lstep1[40], lstep1[54]); - u[1] = _mm_unpackhi_epi32(lstep1[40], lstep1[54]); - u[2] = _mm_unpacklo_epi32(lstep1[41], lstep1[55]); - u[3] = _mm_unpackhi_epi32(lstep1[41], lstep1[55]); - u[4] = _mm_unpacklo_epi32(lstep1[42], lstep1[52]); - u[5] = _mm_unpackhi_epi32(lstep1[42], lstep1[52]); - u[6] = _mm_unpacklo_epi32(lstep1[43], lstep1[53]); - u[7] = _mm_unpackhi_epi32(lstep1[43], lstep1[53]); - u[8] = _mm_unpacklo_epi32(lstep1[44], lstep1[50]); - u[9] = _mm_unpackhi_epi32(lstep1[44], lstep1[50]); - u[10] = _mm_unpacklo_epi32(lstep1[45], lstep1[51]); - u[11] = _mm_unpackhi_epi32(lstep1[45], lstep1[51]); - u[12] = _mm_unpacklo_epi32(lstep1[46], lstep1[48]); - u[13] = _mm_unpackhi_epi32(lstep1[46], lstep1[48]); - u[14] = _mm_unpacklo_epi32(lstep1[47], lstep1[49]); - u[15] = _mm_unpackhi_epi32(lstep1[47], lstep1[49]); - - v[0] = k_madd_epi32(u[0], k32_p27_p05); - v[1] = k_madd_epi32(u[1], k32_p27_p05); - v[2] = k_madd_epi32(u[2], k32_p27_p05); - v[3] = k_madd_epi32(u[3], k32_p27_p05); - v[4] = k_madd_epi32(u[4], k32_p11_p21); - v[5] = k_madd_epi32(u[5], k32_p11_p21); - v[6] = k_madd_epi32(u[6], k32_p11_p21); - v[7] = k_madd_epi32(u[7], k32_p11_p21); - v[8] = k_madd_epi32(u[8], k32_p19_p13); - v[9] = k_madd_epi32(u[9], k32_p19_p13); - v[10] = k_madd_epi32(u[10], k32_p19_p13); - v[11] = k_madd_epi32(u[11], k32_p19_p13); - v[12] = k_madd_epi32(u[12], k32_p03_p29); - v[13] = k_madd_epi32(u[13], k32_p03_p29); - v[14] = k_madd_epi32(u[14], k32_p03_p29); - v[15] = k_madd_epi32(u[15], k32_p03_p29); - v[16] = k_madd_epi32(u[12], k32_m29_p03); - v[17] = k_madd_epi32(u[13], k32_m29_p03); - v[18] = k_madd_epi32(u[14], k32_m29_p03); - v[19] = k_madd_epi32(u[15], k32_m29_p03); - v[20] = k_madd_epi32(u[8], k32_m13_p19); - v[21] = k_madd_epi32(u[9], k32_m13_p19); - v[22] = k_madd_epi32(u[10], k32_m13_p19); - v[23] = k_madd_epi32(u[11], k32_m13_p19); - v[24] = k_madd_epi32(u[4], k32_m21_p11); - v[25] = k_madd_epi32(u[5], k32_m21_p11); - v[26] = k_madd_epi32(u[6], k32_m21_p11); - v[27] = k_madd_epi32(u[7], k32_m21_p11); - v[28] = k_madd_epi32(u[0], k32_m05_p27); - v[29] = k_madd_epi32(u[1], k32_m05_p27); - v[30] = k_madd_epi32(u[2], k32_m05_p27); - v[31] = k_madd_epi32(u[3], k32_m05_p27); - -#if DCT_HIGH_BIT_DEPTH - overflow = k_check_epi32_overflow_32( - &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &v[6], &v[7], &v[8], - &v[9], &v[10], &v[11], &v[12], &v[13], &v[14], &v[15], &v[16], - &v[17], &v[18], &v[19], &v[20], &v[21], &v[22], &v[23], &v[24], - &v[25], &v[26], &v[27], &v[28], &v[29], &v[30], &v[31], &kZero); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - u[0] = k_packs_epi64(v[0], v[1]); - u[1] = k_packs_epi64(v[2], v[3]); - u[2] = k_packs_epi64(v[4], v[5]); - u[3] = k_packs_epi64(v[6], v[7]); - u[4] = k_packs_epi64(v[8], v[9]); - u[5] = k_packs_epi64(v[10], v[11]); - u[6] = k_packs_epi64(v[12], v[13]); - u[7] = k_packs_epi64(v[14], v[15]); - u[8] = k_packs_epi64(v[16], v[17]); - u[9] = k_packs_epi64(v[18], v[19]); - u[10] = k_packs_epi64(v[20], v[21]); - u[11] = k_packs_epi64(v[22], v[23]); - u[12] = k_packs_epi64(v[24], v[25]); - u[13] = k_packs_epi64(v[26], v[27]); - u[14] = k_packs_epi64(v[28], v[29]); - u[15] = k_packs_epi64(v[30], v[31]); - - v[0] = _mm_add_epi32(u[0], k__DCT_CONST_ROUNDING); - v[1] = _mm_add_epi32(u[1], k__DCT_CONST_ROUNDING); - v[2] = _mm_add_epi32(u[2], k__DCT_CONST_ROUNDING); - v[3] = _mm_add_epi32(u[3], k__DCT_CONST_ROUNDING); - v[4] = _mm_add_epi32(u[4], k__DCT_CONST_ROUNDING); - v[5] = _mm_add_epi32(u[5], k__DCT_CONST_ROUNDING); - v[6] = _mm_add_epi32(u[6], k__DCT_CONST_ROUNDING); - v[7] = _mm_add_epi32(u[7], k__DCT_CONST_ROUNDING); - v[8] = _mm_add_epi32(u[8], k__DCT_CONST_ROUNDING); - v[9] = _mm_add_epi32(u[9], k__DCT_CONST_ROUNDING); - v[10] = _mm_add_epi32(u[10], k__DCT_CONST_ROUNDING); - v[11] = _mm_add_epi32(u[11], k__DCT_CONST_ROUNDING); - v[12] = _mm_add_epi32(u[12], k__DCT_CONST_ROUNDING); - v[13] = _mm_add_epi32(u[13], k__DCT_CONST_ROUNDING); - v[14] = _mm_add_epi32(u[14], k__DCT_CONST_ROUNDING); - v[15] = _mm_add_epi32(u[15], k__DCT_CONST_ROUNDING); - - u[0] = _mm_srai_epi32(v[0], DCT_CONST_BITS); - u[1] = _mm_srai_epi32(v[1], DCT_CONST_BITS); - u[2] = _mm_srai_epi32(v[2], DCT_CONST_BITS); - u[3] = _mm_srai_epi32(v[3], DCT_CONST_BITS); - u[4] = _mm_srai_epi32(v[4], DCT_CONST_BITS); - u[5] = _mm_srai_epi32(v[5], DCT_CONST_BITS); - u[6] = _mm_srai_epi32(v[6], DCT_CONST_BITS); - u[7] = _mm_srai_epi32(v[7], DCT_CONST_BITS); - u[8] = _mm_srai_epi32(v[8], DCT_CONST_BITS); - u[9] = _mm_srai_epi32(v[9], DCT_CONST_BITS); - u[10] = _mm_srai_epi32(v[10], DCT_CONST_BITS); - u[11] = _mm_srai_epi32(v[11], DCT_CONST_BITS); - u[12] = _mm_srai_epi32(v[12], DCT_CONST_BITS); - u[13] = _mm_srai_epi32(v[13], DCT_CONST_BITS); - u[14] = _mm_srai_epi32(v[14], DCT_CONST_BITS); - u[15] = _mm_srai_epi32(v[15], DCT_CONST_BITS); - - v[0] = _mm_cmplt_epi32(u[0], kZero); - v[1] = _mm_cmplt_epi32(u[1], kZero); - v[2] = _mm_cmplt_epi32(u[2], kZero); - v[3] = _mm_cmplt_epi32(u[3], kZero); - v[4] = _mm_cmplt_epi32(u[4], kZero); - v[5] = _mm_cmplt_epi32(u[5], kZero); - v[6] = _mm_cmplt_epi32(u[6], kZero); - v[7] = _mm_cmplt_epi32(u[7], kZero); - v[8] = _mm_cmplt_epi32(u[8], kZero); - v[9] = _mm_cmplt_epi32(u[9], kZero); - v[10] = _mm_cmplt_epi32(u[10], kZero); - v[11] = _mm_cmplt_epi32(u[11], kZero); - v[12] = _mm_cmplt_epi32(u[12], kZero); - v[13] = _mm_cmplt_epi32(u[13], kZero); - v[14] = _mm_cmplt_epi32(u[14], kZero); - v[15] = _mm_cmplt_epi32(u[15], kZero); - - u[0] = _mm_sub_epi32(u[0], v[0]); - u[1] = _mm_sub_epi32(u[1], v[1]); - u[2] = _mm_sub_epi32(u[2], v[2]); - u[3] = _mm_sub_epi32(u[3], v[3]); - u[4] = _mm_sub_epi32(u[4], v[4]); - u[5] = _mm_sub_epi32(u[5], v[5]); - u[6] = _mm_sub_epi32(u[6], v[6]); - u[7] = _mm_sub_epi32(u[7], v[7]); - u[8] = _mm_sub_epi32(u[8], v[8]); - u[9] = _mm_sub_epi32(u[9], v[9]); - u[10] = _mm_sub_epi32(u[10], v[10]); - u[11] = _mm_sub_epi32(u[11], v[11]); - u[12] = _mm_sub_epi32(u[12], v[12]); - u[13] = _mm_sub_epi32(u[13], v[13]); - u[14] = _mm_sub_epi32(u[14], v[14]); - u[15] = _mm_sub_epi32(u[15], v[15]); - - v[0] = _mm_add_epi32(u[0], K32One); - v[1] = _mm_add_epi32(u[1], K32One); - v[2] = _mm_add_epi32(u[2], K32One); - v[3] = _mm_add_epi32(u[3], K32One); - v[4] = _mm_add_epi32(u[4], K32One); - v[5] = _mm_add_epi32(u[5], K32One); - v[6] = _mm_add_epi32(u[6], K32One); - v[7] = _mm_add_epi32(u[7], K32One); - v[8] = _mm_add_epi32(u[8], K32One); - v[9] = _mm_add_epi32(u[9], K32One); - v[10] = _mm_add_epi32(u[10], K32One); - v[11] = _mm_add_epi32(u[11], K32One); - v[12] = _mm_add_epi32(u[12], K32One); - v[13] = _mm_add_epi32(u[13], K32One); - v[14] = _mm_add_epi32(u[14], K32One); - v[15] = _mm_add_epi32(u[15], K32One); - - u[0] = _mm_srai_epi32(v[0], 2); - u[1] = _mm_srai_epi32(v[1], 2); - u[2] = _mm_srai_epi32(v[2], 2); - u[3] = _mm_srai_epi32(v[3], 2); - u[4] = _mm_srai_epi32(v[4], 2); - u[5] = _mm_srai_epi32(v[5], 2); - u[6] = _mm_srai_epi32(v[6], 2); - u[7] = _mm_srai_epi32(v[7], 2); - u[8] = _mm_srai_epi32(v[8], 2); - u[9] = _mm_srai_epi32(v[9], 2); - u[10] = _mm_srai_epi32(v[10], 2); - u[11] = _mm_srai_epi32(v[11], 2); - u[12] = _mm_srai_epi32(v[12], 2); - u[13] = _mm_srai_epi32(v[13], 2); - u[14] = _mm_srai_epi32(v[14], 2); - u[15] = _mm_srai_epi32(v[15], 2); - - out[5] = _mm_packs_epi32(u[0], u[1]); - out[21] = _mm_packs_epi32(u[2], u[3]); - out[13] = _mm_packs_epi32(u[4], u[5]); - out[29] = _mm_packs_epi32(u[6], u[7]); - out[3] = _mm_packs_epi32(u[8], u[9]); - out[19] = _mm_packs_epi32(u[10], u[11]); - out[11] = _mm_packs_epi32(u[12], u[13]); - out[27] = _mm_packs_epi32(u[14], u[15]); -#if DCT_HIGH_BIT_DEPTH - overflow = - check_epi16_overflow_x8(&out[5], &out[21], &out[13], &out[29], - &out[3], &out[19], &out[11], &out[27]); - if (overflow) { - HIGH_FDCT32x32_2D_ROWS_C(intermediate, output_org); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - } -#endif // FDCT32x32_HIGH_PRECISION - // Transpose the results, do it as four 8x8 transposes. - { - int transpose_block; - int16_t *output0 = &intermediate[column_start * 32]; - tran_low_t *output1 = &output_org[column_start * 32]; - for (transpose_block = 0; transpose_block < 4; ++transpose_block) { - __m128i *this_out = &out[8 * transpose_block]; - // 00 01 02 03 04 05 06 07 - // 10 11 12 13 14 15 16 17 - // 20 21 22 23 24 25 26 27 - // 30 31 32 33 34 35 36 37 - // 40 41 42 43 44 45 46 47 - // 50 51 52 53 54 55 56 57 - // 60 61 62 63 64 65 66 67 - // 70 71 72 73 74 75 76 77 - const __m128i tr0_0 = _mm_unpacklo_epi16(this_out[0], this_out[1]); - const __m128i tr0_1 = _mm_unpacklo_epi16(this_out[2], this_out[3]); - const __m128i tr0_2 = _mm_unpackhi_epi16(this_out[0], this_out[1]); - const __m128i tr0_3 = _mm_unpackhi_epi16(this_out[2], this_out[3]); - const __m128i tr0_4 = _mm_unpacklo_epi16(this_out[4], this_out[5]); - const __m128i tr0_5 = _mm_unpacklo_epi16(this_out[6], this_out[7]); - const __m128i tr0_6 = _mm_unpackhi_epi16(this_out[4], this_out[5]); - const __m128i tr0_7 = _mm_unpackhi_epi16(this_out[6], this_out[7]); - // 00 10 01 11 02 12 03 13 - // 20 30 21 31 22 32 23 33 - // 04 14 05 15 06 16 07 17 - // 24 34 25 35 26 36 27 37 - // 40 50 41 51 42 52 43 53 - // 60 70 61 71 62 72 63 73 - // 54 54 55 55 56 56 57 57 - // 64 74 65 75 66 76 67 77 - const __m128i tr1_0 = _mm_unpacklo_epi32(tr0_0, tr0_1); - const __m128i tr1_1 = _mm_unpacklo_epi32(tr0_2, tr0_3); - const __m128i tr1_2 = _mm_unpackhi_epi32(tr0_0, tr0_1); - const __m128i tr1_3 = _mm_unpackhi_epi32(tr0_2, tr0_3); - const __m128i tr1_4 = _mm_unpacklo_epi32(tr0_4, tr0_5); - const __m128i tr1_5 = _mm_unpacklo_epi32(tr0_6, tr0_7); - const __m128i tr1_6 = _mm_unpackhi_epi32(tr0_4, tr0_5); - const __m128i tr1_7 = _mm_unpackhi_epi32(tr0_6, tr0_7); - // 00 10 20 30 01 11 21 31 - // 40 50 60 70 41 51 61 71 - // 02 12 22 32 03 13 23 33 - // 42 52 62 72 43 53 63 73 - // 04 14 24 34 05 15 21 36 - // 44 54 64 74 45 55 61 76 - // 06 16 26 36 07 17 27 37 - // 46 56 66 76 47 57 67 77 - __m128i tr2_0 = _mm_unpacklo_epi64(tr1_0, tr1_4); - __m128i tr2_1 = _mm_unpackhi_epi64(tr1_0, tr1_4); - __m128i tr2_2 = _mm_unpacklo_epi64(tr1_2, tr1_6); - __m128i tr2_3 = _mm_unpackhi_epi64(tr1_2, tr1_6); - __m128i tr2_4 = _mm_unpacklo_epi64(tr1_1, tr1_5); - __m128i tr2_5 = _mm_unpackhi_epi64(tr1_1, tr1_5); - __m128i tr2_6 = _mm_unpacklo_epi64(tr1_3, tr1_7); - __m128i tr2_7 = _mm_unpackhi_epi64(tr1_3, tr1_7); - // 00 10 20 30 40 50 60 70 - // 01 11 21 31 41 51 61 71 - // 02 12 22 32 42 52 62 72 - // 03 13 23 33 43 53 63 73 - // 04 14 24 34 44 54 64 74 - // 05 15 25 35 45 55 65 75 - // 06 16 26 36 46 56 66 76 - // 07 17 27 37 47 57 67 77 - if (0 == pass) { - // output[j] = (output[j] + 1 + (output[j] > 0)) >> 2; - // TODO(cd): see quality impact of only doing - // output[j] = (output[j] + 1) >> 2; - // which would remove the code between here ... - __m128i tr2_0_0 = _mm_cmpgt_epi16(tr2_0, kZero); - __m128i tr2_1_0 = _mm_cmpgt_epi16(tr2_1, kZero); - __m128i tr2_2_0 = _mm_cmpgt_epi16(tr2_2, kZero); - __m128i tr2_3_0 = _mm_cmpgt_epi16(tr2_3, kZero); - __m128i tr2_4_0 = _mm_cmpgt_epi16(tr2_4, kZero); - __m128i tr2_5_0 = _mm_cmpgt_epi16(tr2_5, kZero); - __m128i tr2_6_0 = _mm_cmpgt_epi16(tr2_6, kZero); - __m128i tr2_7_0 = _mm_cmpgt_epi16(tr2_7, kZero); - tr2_0 = _mm_sub_epi16(tr2_0, tr2_0_0); - tr2_1 = _mm_sub_epi16(tr2_1, tr2_1_0); - tr2_2 = _mm_sub_epi16(tr2_2, tr2_2_0); - tr2_3 = _mm_sub_epi16(tr2_3, tr2_3_0); - tr2_4 = _mm_sub_epi16(tr2_4, tr2_4_0); - tr2_5 = _mm_sub_epi16(tr2_5, tr2_5_0); - tr2_6 = _mm_sub_epi16(tr2_6, tr2_6_0); - tr2_7 = _mm_sub_epi16(tr2_7, tr2_7_0); - // ... and here. - // PS: also change code in vp9/encoder/vp9_dct.c - tr2_0 = _mm_add_epi16(tr2_0, kOne); - tr2_1 = _mm_add_epi16(tr2_1, kOne); - tr2_2 = _mm_add_epi16(tr2_2, kOne); - tr2_3 = _mm_add_epi16(tr2_3, kOne); - tr2_4 = _mm_add_epi16(tr2_4, kOne); - tr2_5 = _mm_add_epi16(tr2_5, kOne); - tr2_6 = _mm_add_epi16(tr2_6, kOne); - tr2_7 = _mm_add_epi16(tr2_7, kOne); - tr2_0 = _mm_srai_epi16(tr2_0, 2); - tr2_1 = _mm_srai_epi16(tr2_1, 2); - tr2_2 = _mm_srai_epi16(tr2_2, 2); - tr2_3 = _mm_srai_epi16(tr2_3, 2); - tr2_4 = _mm_srai_epi16(tr2_4, 2); - tr2_5 = _mm_srai_epi16(tr2_5, 2); - tr2_6 = _mm_srai_epi16(tr2_6, 2); - tr2_7 = _mm_srai_epi16(tr2_7, 2); - } - // Note: even though all these stores are aligned, using the aligned - // intrinsic make the code slightly slower. - if (pass == 0) { - _mm_storeu_si128((__m128i *)(output0 + 0 * 32), tr2_0); - _mm_storeu_si128((__m128i *)(output0 + 1 * 32), tr2_1); - _mm_storeu_si128((__m128i *)(output0 + 2 * 32), tr2_2); - _mm_storeu_si128((__m128i *)(output0 + 3 * 32), tr2_3); - _mm_storeu_si128((__m128i *)(output0 + 4 * 32), tr2_4); - _mm_storeu_si128((__m128i *)(output0 + 5 * 32), tr2_5); - _mm_storeu_si128((__m128i *)(output0 + 6 * 32), tr2_6); - _mm_storeu_si128((__m128i *)(output0 + 7 * 32), tr2_7); - // Process next 8x8 - output0 += 8; - } else { - storeu_output(&tr2_0, (output1 + 0 * 32)); - storeu_output(&tr2_1, (output1 + 1 * 32)); - storeu_output(&tr2_2, (output1 + 2 * 32)); - storeu_output(&tr2_3, (output1 + 3 * 32)); - storeu_output(&tr2_4, (output1 + 4 * 32)); - storeu_output(&tr2_5, (output1 + 5 * 32)); - storeu_output(&tr2_6, (output1 + 6 * 32)); - storeu_output(&tr2_7, (output1 + 7 * 32)); - // Process next 8x8 - output1 += 8; - } - } - } - } - } -} // NOLINT - -#undef ADD_EPI16 -#undef SUB_EPI16 -#undef HIGH_FDCT32x32_2D_C -#undef HIGH_FDCT32x32_2D_ROWS_C diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_txfm_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_txfm_avx2.c deleted file mode 100644 index 1eb6f411..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_txfm_avx2.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // AVX2 -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx_dsp/txfm_common.h" -#define ADD256_EPI16 _mm256_add_epi16 -#define SUB256_EPI16 _mm256_sub_epi16 - -static INLINE void load_buffer_16bit_to_16bit_avx2(const int16_t *in, - int stride, __m256i *out, - int out_size, int pass) { - int i; - const __m256i kOne = _mm256_set1_epi16(1); - if (pass == 0) { - for (i = 0; i < out_size; i++) { - out[i] = _mm256_loadu_si256((const __m256i *)(in + i * stride)); - // x = x << 2 - out[i] = _mm256_slli_epi16(out[i], 2); - } - } else { - for (i = 0; i < out_size; i++) { - out[i] = _mm256_loadu_si256((const __m256i *)(in + i * 16)); - // x = (x + 1) >> 2 - out[i] = _mm256_add_epi16(out[i], kOne); - out[i] = _mm256_srai_epi16(out[i], 2); - } - } -} - -static INLINE void transpose2_8x8_avx2(const __m256i *const in, - __m256i *const out) { - int i; - __m256i t[16], u[16]; - // (1st, 2nd) ==> (lo, hi) - // (0, 1) ==> (0, 1) - // (2, 3) ==> (2, 3) - // (4, 5) ==> (4, 5) - // (6, 7) ==> (6, 7) - for (i = 0; i < 4; i++) { - t[2 * i] = _mm256_unpacklo_epi16(in[2 * i], in[2 * i + 1]); - t[2 * i + 1] = _mm256_unpackhi_epi16(in[2 * i], in[2 * i + 1]); - } - - // (1st, 2nd) ==> (lo, hi) - // (0, 2) ==> (0, 2) - // (1, 3) ==> (1, 3) - // (4, 6) ==> (4, 6) - // (5, 7) ==> (5, 7) - for (i = 0; i < 2; i++) { - u[i] = _mm256_unpacklo_epi32(t[i], t[i + 2]); - u[i + 2] = _mm256_unpackhi_epi32(t[i], t[i + 2]); - - u[i + 4] = _mm256_unpacklo_epi32(t[i + 4], t[i + 6]); - u[i + 6] = _mm256_unpackhi_epi32(t[i + 4], t[i + 6]); - } - - // (1st, 2nd) ==> (lo, hi) - // (0, 4) ==> (0, 1) - // (1, 5) ==> (4, 5) - // (2, 6) ==> (2, 3) - // (3, 7) ==> (6, 7) - for (i = 0; i < 2; i++) { - out[2 * i] = _mm256_unpacklo_epi64(u[2 * i], u[2 * i + 4]); - out[2 * i + 1] = _mm256_unpackhi_epi64(u[2 * i], u[2 * i + 4]); - - out[2 * i + 4] = _mm256_unpacklo_epi64(u[2 * i + 1], u[2 * i + 5]); - out[2 * i + 5] = _mm256_unpackhi_epi64(u[2 * i + 1], u[2 * i + 5]); - } -} - -static INLINE void transpose_16bit_16x16_avx2(const __m256i *const in, - __m256i *const out) { - __m256i t[16]; - -#define LOADL(idx) \ - t[idx] = _mm256_castsi128_si256(_mm_load_si128((__m128i const *)&in[idx])); \ - t[idx] = _mm256_inserti128_si256( \ - t[idx], _mm_load_si128((__m128i const *)&in[idx + 8]), 1); - -#define LOADR(idx) \ - t[8 + idx] = \ - _mm256_castsi128_si256(_mm_load_si128((__m128i const *)&in[idx] + 1)); \ - t[8 + idx] = _mm256_inserti128_si256( \ - t[8 + idx], _mm_load_si128((__m128i const *)&in[idx + 8] + 1), 1); - - // load left 8x16 - LOADL(0) - LOADL(1) - LOADL(2) - LOADL(3) - LOADL(4) - LOADL(5) - LOADL(6) - LOADL(7) - - // load right 8x16 - LOADR(0) - LOADR(1) - LOADR(2) - LOADR(3) - LOADR(4) - LOADR(5) - LOADR(6) - LOADR(7) - - // get the top 16x8 result - transpose2_8x8_avx2(t, out); - // get the bottom 16x8 result - transpose2_8x8_avx2(&t[8], &out[8]); -} - -// Store 8 16-bit values. Sign extend the values. -static INLINE void store_buffer_16bit_to_32bit_w16_avx2(const __m256i *const in, - tran_low_t *out, - const int stride, - const int out_size) { - int i; - for (i = 0; i < out_size; ++i) { - _mm256_storeu_si256((__m256i *)(out), in[i]); - out += stride; - } -} - -#define PAIR256_SET_EPI16(a, b) \ - _mm256_set_epi16((int16_t)(b), (int16_t)(a), (int16_t)(b), (int16_t)(a), \ - (int16_t)(b), (int16_t)(a), (int16_t)(b), (int16_t)(a), \ - (int16_t)(b), (int16_t)(a), (int16_t)(b), (int16_t)(a), \ - (int16_t)(b), (int16_t)(a), (int16_t)(b), (int16_t)(a)) - -static INLINE __m256i mult256_round_shift(const __m256i *pin0, - const __m256i *pin1, - const __m256i *pmultiplier, - const __m256i *prounding, - const int shift) { - const __m256i u0 = _mm256_madd_epi16(*pin0, *pmultiplier); - const __m256i u1 = _mm256_madd_epi16(*pin1, *pmultiplier); - const __m256i v0 = _mm256_add_epi32(u0, *prounding); - const __m256i v1 = _mm256_add_epi32(u1, *prounding); - const __m256i w0 = _mm256_srai_epi32(v0, shift); - const __m256i w1 = _mm256_srai_epi32(v1, shift); - return _mm256_packs_epi32(w0, w1); -} - -static INLINE void fdct16x16_1D_avx2(__m256i *input, __m256i *output) { - int i; - __m256i step2[4]; - __m256i in[8]; - __m256i step1[8]; - __m256i step3[8]; - - const __m256i k__cospi_p16_p16 = _mm256_set1_epi16(cospi_16_64); - const __m256i k__cospi_p16_m16 = PAIR256_SET_EPI16(cospi_16_64, -cospi_16_64); - const __m256i k__cospi_p24_p08 = PAIR256_SET_EPI16(cospi_24_64, cospi_8_64); - const __m256i k__cospi_p08_m24 = PAIR256_SET_EPI16(cospi_8_64, -cospi_24_64); - const __m256i k__cospi_m08_p24 = PAIR256_SET_EPI16(-cospi_8_64, cospi_24_64); - const __m256i k__cospi_p28_p04 = PAIR256_SET_EPI16(cospi_28_64, cospi_4_64); - const __m256i k__cospi_m04_p28 = PAIR256_SET_EPI16(-cospi_4_64, cospi_28_64); - const __m256i k__cospi_p12_p20 = PAIR256_SET_EPI16(cospi_12_64, cospi_20_64); - const __m256i k__cospi_m20_p12 = PAIR256_SET_EPI16(-cospi_20_64, cospi_12_64); - const __m256i k__cospi_p30_p02 = PAIR256_SET_EPI16(cospi_30_64, cospi_2_64); - const __m256i k__cospi_p14_p18 = PAIR256_SET_EPI16(cospi_14_64, cospi_18_64); - const __m256i k__cospi_m02_p30 = PAIR256_SET_EPI16(-cospi_2_64, cospi_30_64); - const __m256i k__cospi_m18_p14 = PAIR256_SET_EPI16(-cospi_18_64, cospi_14_64); - const __m256i k__cospi_p22_p10 = PAIR256_SET_EPI16(cospi_22_64, cospi_10_64); - const __m256i k__cospi_p06_p26 = PAIR256_SET_EPI16(cospi_6_64, cospi_26_64); - const __m256i k__cospi_m10_p22 = PAIR256_SET_EPI16(-cospi_10_64, cospi_22_64); - const __m256i k__cospi_m26_p06 = PAIR256_SET_EPI16(-cospi_26_64, cospi_6_64); - const __m256i k__DCT_CONST_ROUNDING = _mm256_set1_epi32(DCT_CONST_ROUNDING); - - // Calculate input for the first 8 results. - for (i = 0; i < 8; i++) { - in[i] = ADD256_EPI16(input[i], input[15 - i]); - } - - // Calculate input for the next 8 results. - for (i = 0; i < 8; i++) { - step1[i] = SUB256_EPI16(input[7 - i], input[8 + i]); - } - - // Work on the first eight values; fdct8(input, even_results); - { - // Add/subtract - const __m256i q0 = ADD256_EPI16(in[0], in[7]); - const __m256i q1 = ADD256_EPI16(in[1], in[6]); - const __m256i q2 = ADD256_EPI16(in[2], in[5]); - const __m256i q3 = ADD256_EPI16(in[3], in[4]); - const __m256i q4 = SUB256_EPI16(in[3], in[4]); - const __m256i q5 = SUB256_EPI16(in[2], in[5]); - const __m256i q6 = SUB256_EPI16(in[1], in[6]); - const __m256i q7 = SUB256_EPI16(in[0], in[7]); - - // Work on first four results - { - // Add/subtract - const __m256i r0 = ADD256_EPI16(q0, q3); - const __m256i r1 = ADD256_EPI16(q1, q2); - const __m256i r2 = SUB256_EPI16(q1, q2); - const __m256i r3 = SUB256_EPI16(q0, q3); - - // Interleave to do the multiply by constants which gets us - // into 32 bits. - { - const __m256i t0 = _mm256_unpacklo_epi16(r0, r1); - const __m256i t1 = _mm256_unpackhi_epi16(r0, r1); - const __m256i t2 = _mm256_unpacklo_epi16(r2, r3); - const __m256i t3 = _mm256_unpackhi_epi16(r2, r3); - - output[0] = mult256_round_shift(&t0, &t1, &k__cospi_p16_p16, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - output[8] = mult256_round_shift(&t0, &t1, &k__cospi_p16_m16, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - output[4] = mult256_round_shift(&t2, &t3, &k__cospi_p24_p08, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - output[12] = - mult256_round_shift(&t2, &t3, &k__cospi_m08_p24, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - } - } - - // Work on next four results - { - // Interleave to do the multiply by constants which gets us - // into 32 bits. - const __m256i d0 = _mm256_unpacklo_epi16(q6, q5); - const __m256i d1 = _mm256_unpackhi_epi16(q6, q5); - const __m256i r0 = mult256_round_shift( - &d0, &d1, &k__cospi_p16_m16, &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - const __m256i r1 = mult256_round_shift( - &d0, &d1, &k__cospi_p16_p16, &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - - { - // Add/subtract - const __m256i x0 = ADD256_EPI16(q4, r0); - const __m256i x1 = SUB256_EPI16(q4, r0); - const __m256i x2 = SUB256_EPI16(q7, r1); - const __m256i x3 = ADD256_EPI16(q7, r1); - - // Interleave to do the multiply by constants which gets us - // into 32 bits. - { - const __m256i t0 = _mm256_unpacklo_epi16(x0, x3); - const __m256i t1 = _mm256_unpackhi_epi16(x0, x3); - const __m256i t2 = _mm256_unpacklo_epi16(x1, x2); - const __m256i t3 = _mm256_unpackhi_epi16(x1, x2); - output[2] = - mult256_round_shift(&t0, &t1, &k__cospi_p28_p04, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - output[14] = - mult256_round_shift(&t0, &t1, &k__cospi_m04_p28, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - output[10] = - mult256_round_shift(&t2, &t3, &k__cospi_p12_p20, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - output[6] = - mult256_round_shift(&t2, &t3, &k__cospi_m20_p12, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - } - } - } - } - // Work on the next eight values; step1 -> odd_results - { // step 2 - { - const __m256i t0 = _mm256_unpacklo_epi16(step1[5], step1[2]); - const __m256i t1 = _mm256_unpackhi_epi16(step1[5], step1[2]); - const __m256i t2 = _mm256_unpacklo_epi16(step1[4], step1[3]); - const __m256i t3 = _mm256_unpackhi_epi16(step1[4], step1[3]); - step2[0] = mult256_round_shift(&t0, &t1, &k__cospi_p16_m16, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - step2[1] = mult256_round_shift(&t2, &t3, &k__cospi_p16_m16, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - step2[2] = mult256_round_shift(&t0, &t1, &k__cospi_p16_p16, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - step2[3] = mult256_round_shift(&t2, &t3, &k__cospi_p16_p16, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - } - // step 3 - { - step3[0] = ADD256_EPI16(step1[0], step2[1]); - step3[1] = ADD256_EPI16(step1[1], step2[0]); - step3[2] = SUB256_EPI16(step1[1], step2[0]); - step3[3] = SUB256_EPI16(step1[0], step2[1]); - step3[4] = SUB256_EPI16(step1[7], step2[3]); - step3[5] = SUB256_EPI16(step1[6], step2[2]); - step3[6] = ADD256_EPI16(step1[6], step2[2]); - step3[7] = ADD256_EPI16(step1[7], step2[3]); - } - // step 4 - { - const __m256i t0 = _mm256_unpacklo_epi16(step3[1], step3[6]); - const __m256i t1 = _mm256_unpackhi_epi16(step3[1], step3[6]); - const __m256i t2 = _mm256_unpacklo_epi16(step3[2], step3[5]); - const __m256i t3 = _mm256_unpackhi_epi16(step3[2], step3[5]); - step2[0] = mult256_round_shift(&t0, &t1, &k__cospi_m08_p24, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - step2[1] = mult256_round_shift(&t2, &t3, &k__cospi_p24_p08, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - step2[2] = mult256_round_shift(&t0, &t1, &k__cospi_p24_p08, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - step2[3] = mult256_round_shift(&t2, &t3, &k__cospi_p08_m24, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - } - // step 5 - { - step1[0] = ADD256_EPI16(step3[0], step2[0]); - step1[1] = SUB256_EPI16(step3[0], step2[0]); - step1[2] = ADD256_EPI16(step3[3], step2[1]); - step1[3] = SUB256_EPI16(step3[3], step2[1]); - step1[4] = SUB256_EPI16(step3[4], step2[3]); - step1[5] = ADD256_EPI16(step3[4], step2[3]); - step1[6] = SUB256_EPI16(step3[7], step2[2]); - step1[7] = ADD256_EPI16(step3[7], step2[2]); - } - // step 6 - { - const __m256i t0 = _mm256_unpacklo_epi16(step1[0], step1[7]); - const __m256i t1 = _mm256_unpackhi_epi16(step1[0], step1[7]); - const __m256i t2 = _mm256_unpacklo_epi16(step1[1], step1[6]); - const __m256i t3 = _mm256_unpackhi_epi16(step1[1], step1[6]); - output[1] = mult256_round_shift(&t0, &t1, &k__cospi_p30_p02, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - output[9] = mult256_round_shift(&t2, &t3, &k__cospi_p14_p18, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - output[15] = mult256_round_shift(&t0, &t1, &k__cospi_m02_p30, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - output[7] = mult256_round_shift(&t2, &t3, &k__cospi_m18_p14, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - } - { - const __m256i t0 = _mm256_unpacklo_epi16(step1[2], step1[5]); - const __m256i t1 = _mm256_unpackhi_epi16(step1[2], step1[5]); - const __m256i t2 = _mm256_unpacklo_epi16(step1[3], step1[4]); - const __m256i t3 = _mm256_unpackhi_epi16(step1[3], step1[4]); - output[5] = mult256_round_shift(&t0, &t1, &k__cospi_p22_p10, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - output[13] = mult256_round_shift(&t2, &t3, &k__cospi_p06_p26, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - output[11] = mult256_round_shift(&t0, &t1, &k__cospi_m10_p22, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - output[3] = mult256_round_shift(&t2, &t3, &k__cospi_m26_p06, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - } - } -} - -void vpx_fdct16x16_avx2(const int16_t *input, tran_low_t *output, int stride) { - int pass; - DECLARE_ALIGNED(32, int16_t, intermediate[256]); - int16_t *out0 = intermediate; - tran_low_t *out1 = output; - const int width = 16; - const int height = 16; - __m256i buf0[16], buf1[16]; - - // Two transform and transpose passes - // Process 16 columns (transposed rows in second pass) at a time. - for (pass = 0; pass < 2; ++pass) { - // Load and pre-condition input. - load_buffer_16bit_to_16bit_avx2(input, stride, buf1, height, pass); - - // Calculate dct for 16x16 values - fdct16x16_1D_avx2(buf1, buf0); - - // Transpose the results. - transpose_16bit_16x16_avx2(buf0, buf1); - - if (pass == 0) { - store_buffer_16bit_to_32bit_w16_avx2(buf1, (tran_low_t *)out0, width, - height); - } else { - store_buffer_16bit_to_32bit_w16_avx2(buf1, out1, width, height); - } - // Setup in/out for next pass. - input = intermediate; - } -} - -#if !CONFIG_VP9_HIGHBITDEPTH -#define FDCT32x32_2D_AVX2 vpx_fdct32x32_rd_avx2 -#define FDCT32x32_HIGH_PRECISION 0 -#include "vpx_dsp/x86/fwd_dct32x32_impl_avx2.h" -#undef FDCT32x32_2D_AVX2 -#undef FDCT32x32_HIGH_PRECISION - -#define FDCT32x32_2D_AVX2 vpx_fdct32x32_avx2 -#define FDCT32x32_HIGH_PRECISION 1 -#include "vpx_dsp/x86/fwd_dct32x32_impl_avx2.h" // NOLINT -#undef FDCT32x32_2D_AVX2 -#undef FDCT32x32_HIGH_PRECISION -#endif // !CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_txfm_impl_sse2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_txfm_impl_sse2.h deleted file mode 100644 index d546f02a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_txfm_impl_sse2.h +++ /dev/null @@ -1,1015 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // SSE2 - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/txfm_common.h" -#include "vpx_dsp/x86/fwd_txfm_sse2.h" -#include "vpx_dsp/x86/txfm_common_sse2.h" -#include "vpx_ports/mem.h" - -// TODO(jingning) The high bit-depth functions need rework for performance. -// After we properly fix the high bit-depth function implementations, this -// file's dependency should be substantially simplified. -#if DCT_HIGH_BIT_DEPTH -#define ADD_EPI16 _mm_adds_epi16 -#define SUB_EPI16 _mm_subs_epi16 - -#else -#define ADD_EPI16 _mm_add_epi16 -#define SUB_EPI16 _mm_sub_epi16 -#endif - -void FDCT4x4_2D(const int16_t *input, tran_low_t *output, int stride) { - // This 2D transform implements 4 vertical 1D transforms followed - // by 4 horizontal 1D transforms. The multiplies and adds are as given - // by Chen, Smith and Fralick ('77). The commands for moving the data - // around have been minimized by hand. - // For the purposes of the comments, the 16 inputs are referred to at i0 - // through iF (in raster order), intermediate variables are a0, b0, c0 - // through f, and correspond to the in-place computations mapped to input - // locations. The outputs, o0 through oF are labeled according to the - // output locations. - - // Constants - // These are the coefficients used for the multiplies. - // In the comments, pN means cos(N pi /64) and mN is -cos(N pi /64), - // where cospi_N_64 = cos(N pi /64) - const __m128i k__cospi_A = - octa_set_epi16(cospi_16_64, cospi_16_64, cospi_16_64, cospi_16_64, - cospi_16_64, -cospi_16_64, cospi_16_64, -cospi_16_64); - const __m128i k__cospi_B = - octa_set_epi16(cospi_16_64, -cospi_16_64, cospi_16_64, -cospi_16_64, - cospi_16_64, cospi_16_64, cospi_16_64, cospi_16_64); - const __m128i k__cospi_C = - octa_set_epi16(cospi_8_64, cospi_24_64, cospi_8_64, cospi_24_64, - cospi_24_64, -cospi_8_64, cospi_24_64, -cospi_8_64); - const __m128i k__cospi_D = - octa_set_epi16(cospi_24_64, -cospi_8_64, cospi_24_64, -cospi_8_64, - cospi_8_64, cospi_24_64, cospi_8_64, cospi_24_64); - const __m128i k__cospi_E = - octa_set_epi16(cospi_16_64, cospi_16_64, cospi_16_64, cospi_16_64, - cospi_16_64, cospi_16_64, cospi_16_64, cospi_16_64); - const __m128i k__cospi_F = - octa_set_epi16(cospi_16_64, -cospi_16_64, cospi_16_64, -cospi_16_64, - cospi_16_64, -cospi_16_64, cospi_16_64, -cospi_16_64); - const __m128i k__cospi_G = - octa_set_epi16(cospi_8_64, cospi_24_64, cospi_8_64, cospi_24_64, - -cospi_8_64, -cospi_24_64, -cospi_8_64, -cospi_24_64); - const __m128i k__cospi_H = - octa_set_epi16(cospi_24_64, -cospi_8_64, cospi_24_64, -cospi_8_64, - -cospi_24_64, cospi_8_64, -cospi_24_64, cospi_8_64); - - const __m128i k__DCT_CONST_ROUNDING = _mm_set1_epi32(DCT_CONST_ROUNDING); - // This second rounding constant saves doing some extra adds at the end - const __m128i k__DCT_CONST_ROUNDING2 = - _mm_set1_epi32(DCT_CONST_ROUNDING + (DCT_CONST_ROUNDING << 1)); - const int DCT_CONST_BITS2 = DCT_CONST_BITS + 2; - const __m128i k__nonzero_bias_a = _mm_setr_epi16(0, 1, 1, 1, 1, 1, 1, 1); - const __m128i k__nonzero_bias_b = _mm_setr_epi16(1, 0, 0, 0, 0, 0, 0, 0); - __m128i in0, in1; -#if DCT_HIGH_BIT_DEPTH - __m128i cmp0, cmp1; - int test, overflow; -#endif - - // Load inputs. - in0 = _mm_loadl_epi64((const __m128i *)(input + 0 * stride)); - in1 = _mm_loadl_epi64((const __m128i *)(input + 1 * stride)); - in1 = _mm_unpacklo_epi64( - in1, _mm_loadl_epi64((const __m128i *)(input + 2 * stride))); - in0 = _mm_unpacklo_epi64( - in0, _mm_loadl_epi64((const __m128i *)(input + 3 * stride))); -// in0 = [i0 i1 i2 i3 iC iD iE iF] -// in1 = [i4 i5 i6 i7 i8 i9 iA iB] -#if DCT_HIGH_BIT_DEPTH - // Check inputs small enough to use optimised code - cmp0 = _mm_xor_si128(_mm_cmpgt_epi16(in0, _mm_set1_epi16(0x3ff)), - _mm_cmplt_epi16(in0, _mm_set1_epi16((int16_t)0xfc00))); - cmp1 = _mm_xor_si128(_mm_cmpgt_epi16(in1, _mm_set1_epi16(0x3ff)), - _mm_cmplt_epi16(in1, _mm_set1_epi16((int16_t)0xfc00))); - test = _mm_movemask_epi8(_mm_or_si128(cmp0, cmp1)); - if (test) { - vpx_highbd_fdct4x4_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - - // multiply by 16 to give some extra precision - in0 = _mm_slli_epi16(in0, 4); - in1 = _mm_slli_epi16(in1, 4); - // if (i == 0 && input[0]) input[0] += 1; - // add 1 to the upper left pixel if it is non-zero, which helps reduce - // the round-trip error - { - // The mask will only contain whether the first value is zero, all - // other comparison will fail as something shifted by 4 (above << 4) - // can never be equal to one. To increment in the non-zero case, we - // add the mask and one for the first element: - // - if zero, mask = -1, v = v - 1 + 1 = v - // - if non-zero, mask = 0, v = v + 0 + 1 = v + 1 - __m128i mask = _mm_cmpeq_epi16(in0, k__nonzero_bias_a); - in0 = _mm_add_epi16(in0, mask); - in0 = _mm_add_epi16(in0, k__nonzero_bias_b); - } - // There are 4 total stages, alternating between an add/subtract stage - // followed by an multiply-and-add stage. - { - // Stage 1: Add/subtract - - // in0 = [i0 i1 i2 i3 iC iD iE iF] - // in1 = [i4 i5 i6 i7 i8 i9 iA iB] - const __m128i r0 = _mm_unpacklo_epi16(in0, in1); - const __m128i r1 = _mm_unpackhi_epi16(in0, in1); - // r0 = [i0 i4 i1 i5 i2 i6 i3 i7] - // r1 = [iC i8 iD i9 iE iA iF iB] - const __m128i r2 = _mm_shuffle_epi32(r0, 0xB4); - const __m128i r3 = _mm_shuffle_epi32(r1, 0xB4); - // r2 = [i0 i4 i1 i5 i3 i7 i2 i6] - // r3 = [iC i8 iD i9 iF iB iE iA] - - const __m128i t0 = _mm_add_epi16(r2, r3); - const __m128i t1 = _mm_sub_epi16(r2, r3); - // t0 = [a0 a4 a1 a5 a3 a7 a2 a6] - // t1 = [aC a8 aD a9 aF aB aE aA] - - // Stage 2: multiply by constants (which gets us into 32 bits). - // The constants needed here are: - // k__cospi_A = [p16 p16 p16 p16 p16 m16 p16 m16] - // k__cospi_B = [p16 m16 p16 m16 p16 p16 p16 p16] - // k__cospi_C = [p08 p24 p08 p24 p24 m08 p24 m08] - // k__cospi_D = [p24 m08 p24 m08 p08 p24 p08 p24] - const __m128i u0 = _mm_madd_epi16(t0, k__cospi_A); - const __m128i u2 = _mm_madd_epi16(t0, k__cospi_B); - const __m128i u1 = _mm_madd_epi16(t1, k__cospi_C); - const __m128i u3 = _mm_madd_epi16(t1, k__cospi_D); - // Then add and right-shift to get back to 16-bit range - const __m128i v0 = _mm_add_epi32(u0, k__DCT_CONST_ROUNDING); - const __m128i v1 = _mm_add_epi32(u1, k__DCT_CONST_ROUNDING); - const __m128i v2 = _mm_add_epi32(u2, k__DCT_CONST_ROUNDING); - const __m128i v3 = _mm_add_epi32(u3, k__DCT_CONST_ROUNDING); - const __m128i w0 = _mm_srai_epi32(v0, DCT_CONST_BITS); - const __m128i w1 = _mm_srai_epi32(v1, DCT_CONST_BITS); - const __m128i w2 = _mm_srai_epi32(v2, DCT_CONST_BITS); - const __m128i w3 = _mm_srai_epi32(v3, DCT_CONST_BITS); - // w0 = [b0 b1 b7 b6] - // w1 = [b8 b9 bF bE] - // w2 = [b4 b5 b3 b2] - // w3 = [bC bD bB bA] - const __m128i x0 = _mm_packs_epi32(w0, w1); - const __m128i x1 = _mm_packs_epi32(w2, w3); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x2(&x0, &x1); - if (overflow) { - vpx_highbd_fdct4x4_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - // x0 = [b0 b1 b7 b6 b8 b9 bF bE] - // x1 = [b4 b5 b3 b2 bC bD bB bA] - in0 = _mm_shuffle_epi32(x0, 0xD8); - in1 = _mm_shuffle_epi32(x1, 0x8D); - // in0 = [b0 b1 b8 b9 b7 b6 bF bE] - // in1 = [b3 b2 bB bA b4 b5 bC bD] - } - { - // vertical DCTs finished. Now we do the horizontal DCTs. - // Stage 3: Add/subtract - - const __m128i t0 = ADD_EPI16(in0, in1); - const __m128i t1 = SUB_EPI16(in0, in1); -// t0 = [c0 c1 c8 c9 c4 c5 cC cD] -// t1 = [c3 c2 cB cA -c7 -c6 -cF -cE] -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x2(&t0, &t1); - if (overflow) { - vpx_highbd_fdct4x4_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - - // Stage 4: multiply by constants (which gets us into 32 bits). - { - // The constants needed here are: - // k__cospi_E = [p16 p16 p16 p16 p16 p16 p16 p16] - // k__cospi_F = [p16 m16 p16 m16 p16 m16 p16 m16] - // k__cospi_G = [p08 p24 p08 p24 m08 m24 m08 m24] - // k__cospi_H = [p24 m08 p24 m08 m24 p08 m24 p08] - const __m128i u0 = _mm_madd_epi16(t0, k__cospi_E); - const __m128i u1 = _mm_madd_epi16(t0, k__cospi_F); - const __m128i u2 = _mm_madd_epi16(t1, k__cospi_G); - const __m128i u3 = _mm_madd_epi16(t1, k__cospi_H); - // Then add and right-shift to get back to 16-bit range - // but this combines the final right-shift as well to save operations - // This unusual rounding operations is to maintain bit-accurate - // compatibility with the c version of this function which has two - // rounding steps in a row. - const __m128i v0 = _mm_add_epi32(u0, k__DCT_CONST_ROUNDING2); - const __m128i v1 = _mm_add_epi32(u1, k__DCT_CONST_ROUNDING2); - const __m128i v2 = _mm_add_epi32(u2, k__DCT_CONST_ROUNDING2); - const __m128i v3 = _mm_add_epi32(u3, k__DCT_CONST_ROUNDING2); - const __m128i w0 = _mm_srai_epi32(v0, DCT_CONST_BITS2); - const __m128i w1 = _mm_srai_epi32(v1, DCT_CONST_BITS2); - const __m128i w2 = _mm_srai_epi32(v2, DCT_CONST_BITS2); - const __m128i w3 = _mm_srai_epi32(v3, DCT_CONST_BITS2); - // w0 = [o0 o4 o8 oC] - // w1 = [o2 o6 oA oE] - // w2 = [o1 o5 o9 oD] - // w3 = [o3 o7 oB oF] - // remember the o's are numbered according to the correct output location - const __m128i x0 = _mm_packs_epi32(w0, w1); - const __m128i x1 = _mm_packs_epi32(w2, w3); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x2(&x0, &x1); - if (overflow) { - vpx_highbd_fdct4x4_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - { - // x0 = [o0 o4 o8 oC o2 o6 oA oE] - // x1 = [o1 o5 o9 oD o3 o7 oB oF] - const __m128i y0 = _mm_unpacklo_epi16(x0, x1); - const __m128i y1 = _mm_unpackhi_epi16(x0, x1); - // y0 = [o0 o1 o4 o5 o8 o9 oC oD] - // y1 = [o2 o3 o6 o7 oA oB oE oF] - in0 = _mm_unpacklo_epi32(y0, y1); - // in0 = [o0 o1 o2 o3 o4 o5 o6 o7] - in1 = _mm_unpackhi_epi32(y0, y1); - // in1 = [o8 o9 oA oB oC oD oE oF] - } - } - } - // Post-condition (v + 1) >> 2 is now incorporated into previous - // add and right-shift commands. Only 2 store instructions needed - // because we are using the fact that 1/3 are stored just after 0/2. - storeu_output(&in0, output + 0 * 4); - storeu_output(&in1, output + 2 * 4); -} - -void FDCT8x8_2D(const int16_t *input, tran_low_t *output, int stride) { - int pass; - // Constants - // When we use them, in one case, they are all the same. In all others - // it's a pair of them that we need to repeat four times. This is done - // by constructing the 32 bit constant corresponding to that pair. - const __m128i k__cospi_p16_p16 = _mm_set1_epi16(cospi_16_64); - const __m128i k__cospi_p16_m16 = pair_set_epi16(cospi_16_64, -cospi_16_64); - const __m128i k__cospi_p24_p08 = pair_set_epi16(cospi_24_64, cospi_8_64); - const __m128i k__cospi_m08_p24 = pair_set_epi16(-cospi_8_64, cospi_24_64); - const __m128i k__cospi_p28_p04 = pair_set_epi16(cospi_28_64, cospi_4_64); - const __m128i k__cospi_m04_p28 = pair_set_epi16(-cospi_4_64, cospi_28_64); - const __m128i k__cospi_p12_p20 = pair_set_epi16(cospi_12_64, cospi_20_64); - const __m128i k__cospi_m20_p12 = pair_set_epi16(-cospi_20_64, cospi_12_64); - const __m128i k__DCT_CONST_ROUNDING = _mm_set1_epi32(DCT_CONST_ROUNDING); -#if DCT_HIGH_BIT_DEPTH - int overflow; -#endif - // Load input - __m128i in0 = _mm_load_si128((const __m128i *)(input + 0 * stride)); - __m128i in1 = _mm_load_si128((const __m128i *)(input + 1 * stride)); - __m128i in2 = _mm_load_si128((const __m128i *)(input + 2 * stride)); - __m128i in3 = _mm_load_si128((const __m128i *)(input + 3 * stride)); - __m128i in4 = _mm_load_si128((const __m128i *)(input + 4 * stride)); - __m128i in5 = _mm_load_si128((const __m128i *)(input + 5 * stride)); - __m128i in6 = _mm_load_si128((const __m128i *)(input + 6 * stride)); - __m128i in7 = _mm_load_si128((const __m128i *)(input + 7 * stride)); - // Pre-condition input (shift by two) - in0 = _mm_slli_epi16(in0, 2); - in1 = _mm_slli_epi16(in1, 2); - in2 = _mm_slli_epi16(in2, 2); - in3 = _mm_slli_epi16(in3, 2); - in4 = _mm_slli_epi16(in4, 2); - in5 = _mm_slli_epi16(in5, 2); - in6 = _mm_slli_epi16(in6, 2); - in7 = _mm_slli_epi16(in7, 2); - - // We do two passes, first the columns, then the rows. The results of the - // first pass are transposed so that the same column code can be reused. The - // results of the second pass are also transposed so that the rows (processed - // as columns) are put back in row positions. - for (pass = 0; pass < 2; pass++) { - // To store results of each pass before the transpose. - __m128i res0, res1, res2, res3, res4, res5, res6, res7; - // Add/subtract - const __m128i q0 = ADD_EPI16(in0, in7); - const __m128i q1 = ADD_EPI16(in1, in6); - const __m128i q2 = ADD_EPI16(in2, in5); - const __m128i q3 = ADD_EPI16(in3, in4); - const __m128i q4 = SUB_EPI16(in3, in4); - const __m128i q5 = SUB_EPI16(in2, in5); - const __m128i q6 = SUB_EPI16(in1, in6); - const __m128i q7 = SUB_EPI16(in0, in7); -#if DCT_HIGH_BIT_DEPTH - if (pass == 1) { - overflow = - check_epi16_overflow_x8(&q0, &q1, &q2, &q3, &q4, &q5, &q6, &q7); - if (overflow) { - vpx_highbd_fdct8x8_c(input, output, stride); - return; - } - } -#endif // DCT_HIGH_BIT_DEPTH - // Work on first four results - { - // Add/subtract - const __m128i r0 = ADD_EPI16(q0, q3); - const __m128i r1 = ADD_EPI16(q1, q2); - const __m128i r2 = SUB_EPI16(q1, q2); - const __m128i r3 = SUB_EPI16(q0, q3); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x4(&r0, &r1, &r2, &r3); - if (overflow) { - vpx_highbd_fdct8x8_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - // Interleave to do the multiply by constants which gets us into 32bits - { - const __m128i t0 = _mm_unpacklo_epi16(r0, r1); - const __m128i t1 = _mm_unpackhi_epi16(r0, r1); - const __m128i t2 = _mm_unpacklo_epi16(r2, r3); - const __m128i t3 = _mm_unpackhi_epi16(r2, r3); - const __m128i u0 = _mm_madd_epi16(t0, k__cospi_p16_p16); - const __m128i u1 = _mm_madd_epi16(t1, k__cospi_p16_p16); - const __m128i u2 = _mm_madd_epi16(t0, k__cospi_p16_m16); - const __m128i u3 = _mm_madd_epi16(t1, k__cospi_p16_m16); - const __m128i u4 = _mm_madd_epi16(t2, k__cospi_p24_p08); - const __m128i u5 = _mm_madd_epi16(t3, k__cospi_p24_p08); - const __m128i u6 = _mm_madd_epi16(t2, k__cospi_m08_p24); - const __m128i u7 = _mm_madd_epi16(t3, k__cospi_m08_p24); - // dct_const_round_shift - const __m128i v0 = _mm_add_epi32(u0, k__DCT_CONST_ROUNDING); - const __m128i v1 = _mm_add_epi32(u1, k__DCT_CONST_ROUNDING); - const __m128i v2 = _mm_add_epi32(u2, k__DCT_CONST_ROUNDING); - const __m128i v3 = _mm_add_epi32(u3, k__DCT_CONST_ROUNDING); - const __m128i v4 = _mm_add_epi32(u4, k__DCT_CONST_ROUNDING); - const __m128i v5 = _mm_add_epi32(u5, k__DCT_CONST_ROUNDING); - const __m128i v6 = _mm_add_epi32(u6, k__DCT_CONST_ROUNDING); - const __m128i v7 = _mm_add_epi32(u7, k__DCT_CONST_ROUNDING); - const __m128i w0 = _mm_srai_epi32(v0, DCT_CONST_BITS); - const __m128i w1 = _mm_srai_epi32(v1, DCT_CONST_BITS); - const __m128i w2 = _mm_srai_epi32(v2, DCT_CONST_BITS); - const __m128i w3 = _mm_srai_epi32(v3, DCT_CONST_BITS); - const __m128i w4 = _mm_srai_epi32(v4, DCT_CONST_BITS); - const __m128i w5 = _mm_srai_epi32(v5, DCT_CONST_BITS); - const __m128i w6 = _mm_srai_epi32(v6, DCT_CONST_BITS); - const __m128i w7 = _mm_srai_epi32(v7, DCT_CONST_BITS); - // Combine - res0 = _mm_packs_epi32(w0, w1); - res4 = _mm_packs_epi32(w2, w3); - res2 = _mm_packs_epi32(w4, w5); - res6 = _mm_packs_epi32(w6, w7); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x4(&res0, &res4, &res2, &res6); - if (overflow) { - vpx_highbd_fdct8x8_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - } - // Work on next four results - { - // Interleave to do the multiply by constants which gets us into 32bits - const __m128i d0 = _mm_unpacklo_epi16(q6, q5); - const __m128i d1 = _mm_unpackhi_epi16(q6, q5); - const __m128i e0 = _mm_madd_epi16(d0, k__cospi_p16_m16); - const __m128i e1 = _mm_madd_epi16(d1, k__cospi_p16_m16); - const __m128i e2 = _mm_madd_epi16(d0, k__cospi_p16_p16); - const __m128i e3 = _mm_madd_epi16(d1, k__cospi_p16_p16); - // dct_const_round_shift - const __m128i f0 = _mm_add_epi32(e0, k__DCT_CONST_ROUNDING); - const __m128i f1 = _mm_add_epi32(e1, k__DCT_CONST_ROUNDING); - const __m128i f2 = _mm_add_epi32(e2, k__DCT_CONST_ROUNDING); - const __m128i f3 = _mm_add_epi32(e3, k__DCT_CONST_ROUNDING); - const __m128i s0 = _mm_srai_epi32(f0, DCT_CONST_BITS); - const __m128i s1 = _mm_srai_epi32(f1, DCT_CONST_BITS); - const __m128i s2 = _mm_srai_epi32(f2, DCT_CONST_BITS); - const __m128i s3 = _mm_srai_epi32(f3, DCT_CONST_BITS); - // Combine - const __m128i r0 = _mm_packs_epi32(s0, s1); - const __m128i r1 = _mm_packs_epi32(s2, s3); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x2(&r0, &r1); - if (overflow) { - vpx_highbd_fdct8x8_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - { - // Add/subtract - const __m128i x0 = ADD_EPI16(q4, r0); - const __m128i x1 = SUB_EPI16(q4, r0); - const __m128i x2 = SUB_EPI16(q7, r1); - const __m128i x3 = ADD_EPI16(q7, r1); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x4(&x0, &x1, &x2, &x3); - if (overflow) { - vpx_highbd_fdct8x8_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - // Interleave to do the multiply by constants which gets us into 32bits - { - const __m128i t0 = _mm_unpacklo_epi16(x0, x3); - const __m128i t1 = _mm_unpackhi_epi16(x0, x3); - const __m128i t2 = _mm_unpacklo_epi16(x1, x2); - const __m128i t3 = _mm_unpackhi_epi16(x1, x2); - const __m128i u0 = _mm_madd_epi16(t0, k__cospi_p28_p04); - const __m128i u1 = _mm_madd_epi16(t1, k__cospi_p28_p04); - const __m128i u2 = _mm_madd_epi16(t0, k__cospi_m04_p28); - const __m128i u3 = _mm_madd_epi16(t1, k__cospi_m04_p28); - const __m128i u4 = _mm_madd_epi16(t2, k__cospi_p12_p20); - const __m128i u5 = _mm_madd_epi16(t3, k__cospi_p12_p20); - const __m128i u6 = _mm_madd_epi16(t2, k__cospi_m20_p12); - const __m128i u7 = _mm_madd_epi16(t3, k__cospi_m20_p12); - // dct_const_round_shift - const __m128i v0 = _mm_add_epi32(u0, k__DCT_CONST_ROUNDING); - const __m128i v1 = _mm_add_epi32(u1, k__DCT_CONST_ROUNDING); - const __m128i v2 = _mm_add_epi32(u2, k__DCT_CONST_ROUNDING); - const __m128i v3 = _mm_add_epi32(u3, k__DCT_CONST_ROUNDING); - const __m128i v4 = _mm_add_epi32(u4, k__DCT_CONST_ROUNDING); - const __m128i v5 = _mm_add_epi32(u5, k__DCT_CONST_ROUNDING); - const __m128i v6 = _mm_add_epi32(u6, k__DCT_CONST_ROUNDING); - const __m128i v7 = _mm_add_epi32(u7, k__DCT_CONST_ROUNDING); - const __m128i w0 = _mm_srai_epi32(v0, DCT_CONST_BITS); - const __m128i w1 = _mm_srai_epi32(v1, DCT_CONST_BITS); - const __m128i w2 = _mm_srai_epi32(v2, DCT_CONST_BITS); - const __m128i w3 = _mm_srai_epi32(v3, DCT_CONST_BITS); - const __m128i w4 = _mm_srai_epi32(v4, DCT_CONST_BITS); - const __m128i w5 = _mm_srai_epi32(v5, DCT_CONST_BITS); - const __m128i w6 = _mm_srai_epi32(v6, DCT_CONST_BITS); - const __m128i w7 = _mm_srai_epi32(v7, DCT_CONST_BITS); - // Combine - res1 = _mm_packs_epi32(w0, w1); - res7 = _mm_packs_epi32(w2, w3); - res5 = _mm_packs_epi32(w4, w5); - res3 = _mm_packs_epi32(w6, w7); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x4(&res1, &res7, &res5, &res3); - if (overflow) { - vpx_highbd_fdct8x8_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - } - } - // Transpose the 8x8. - { - // 00 01 02 03 04 05 06 07 - // 10 11 12 13 14 15 16 17 - // 20 21 22 23 24 25 26 27 - // 30 31 32 33 34 35 36 37 - // 40 41 42 43 44 45 46 47 - // 50 51 52 53 54 55 56 57 - // 60 61 62 63 64 65 66 67 - // 70 71 72 73 74 75 76 77 - const __m128i tr0_0 = _mm_unpacklo_epi16(res0, res1); - const __m128i tr0_1 = _mm_unpacklo_epi16(res2, res3); - const __m128i tr0_2 = _mm_unpackhi_epi16(res0, res1); - const __m128i tr0_3 = _mm_unpackhi_epi16(res2, res3); - const __m128i tr0_4 = _mm_unpacklo_epi16(res4, res5); - const __m128i tr0_5 = _mm_unpacklo_epi16(res6, res7); - const __m128i tr0_6 = _mm_unpackhi_epi16(res4, res5); - const __m128i tr0_7 = _mm_unpackhi_epi16(res6, res7); - // 00 10 01 11 02 12 03 13 - // 20 30 21 31 22 32 23 33 - // 04 14 05 15 06 16 07 17 - // 24 34 25 35 26 36 27 37 - // 40 50 41 51 42 52 43 53 - // 60 70 61 71 62 72 63 73 - // 54 54 55 55 56 56 57 57 - // 64 74 65 75 66 76 67 77 - const __m128i tr1_0 = _mm_unpacklo_epi32(tr0_0, tr0_1); - const __m128i tr1_1 = _mm_unpacklo_epi32(tr0_2, tr0_3); - const __m128i tr1_2 = _mm_unpackhi_epi32(tr0_0, tr0_1); - const __m128i tr1_3 = _mm_unpackhi_epi32(tr0_2, tr0_3); - const __m128i tr1_4 = _mm_unpacklo_epi32(tr0_4, tr0_5); - const __m128i tr1_5 = _mm_unpacklo_epi32(tr0_6, tr0_7); - const __m128i tr1_6 = _mm_unpackhi_epi32(tr0_4, tr0_5); - const __m128i tr1_7 = _mm_unpackhi_epi32(tr0_6, tr0_7); - // 00 10 20 30 01 11 21 31 - // 40 50 60 70 41 51 61 71 - // 02 12 22 32 03 13 23 33 - // 42 52 62 72 43 53 63 73 - // 04 14 24 34 05 15 21 36 - // 44 54 64 74 45 55 61 76 - // 06 16 26 36 07 17 27 37 - // 46 56 66 76 47 57 67 77 - in0 = _mm_unpacklo_epi64(tr1_0, tr1_4); - in1 = _mm_unpackhi_epi64(tr1_0, tr1_4); - in2 = _mm_unpacklo_epi64(tr1_2, tr1_6); - in3 = _mm_unpackhi_epi64(tr1_2, tr1_6); - in4 = _mm_unpacklo_epi64(tr1_1, tr1_5); - in5 = _mm_unpackhi_epi64(tr1_1, tr1_5); - in6 = _mm_unpacklo_epi64(tr1_3, tr1_7); - in7 = _mm_unpackhi_epi64(tr1_3, tr1_7); - // 00 10 20 30 40 50 60 70 - // 01 11 21 31 41 51 61 71 - // 02 12 22 32 42 52 62 72 - // 03 13 23 33 43 53 63 73 - // 04 14 24 34 44 54 64 74 - // 05 15 25 35 45 55 65 75 - // 06 16 26 36 46 56 66 76 - // 07 17 27 37 47 57 67 77 - } - } - // Post-condition output and store it - { - // Post-condition (division by two) - // division of two 16 bits signed numbers using shifts - // n / 2 = (n - (n >> 15)) >> 1 - const __m128i sign_in0 = _mm_srai_epi16(in0, 15); - const __m128i sign_in1 = _mm_srai_epi16(in1, 15); - const __m128i sign_in2 = _mm_srai_epi16(in2, 15); - const __m128i sign_in3 = _mm_srai_epi16(in3, 15); - const __m128i sign_in4 = _mm_srai_epi16(in4, 15); - const __m128i sign_in5 = _mm_srai_epi16(in5, 15); - const __m128i sign_in6 = _mm_srai_epi16(in6, 15); - const __m128i sign_in7 = _mm_srai_epi16(in7, 15); - in0 = _mm_sub_epi16(in0, sign_in0); - in1 = _mm_sub_epi16(in1, sign_in1); - in2 = _mm_sub_epi16(in2, sign_in2); - in3 = _mm_sub_epi16(in3, sign_in3); - in4 = _mm_sub_epi16(in4, sign_in4); - in5 = _mm_sub_epi16(in5, sign_in5); - in6 = _mm_sub_epi16(in6, sign_in6); - in7 = _mm_sub_epi16(in7, sign_in7); - in0 = _mm_srai_epi16(in0, 1); - in1 = _mm_srai_epi16(in1, 1); - in2 = _mm_srai_epi16(in2, 1); - in3 = _mm_srai_epi16(in3, 1); - in4 = _mm_srai_epi16(in4, 1); - in5 = _mm_srai_epi16(in5, 1); - in6 = _mm_srai_epi16(in6, 1); - in7 = _mm_srai_epi16(in7, 1); - // store results - store_output(&in0, (output + 0 * 8)); - store_output(&in1, (output + 1 * 8)); - store_output(&in2, (output + 2 * 8)); - store_output(&in3, (output + 3 * 8)); - store_output(&in4, (output + 4 * 8)); - store_output(&in5, (output + 5 * 8)); - store_output(&in6, (output + 6 * 8)); - store_output(&in7, (output + 7 * 8)); - } -} - -void FDCT16x16_2D(const int16_t *input, tran_low_t *output, int stride) { - // The 2D transform is done with two passes which are actually pretty - // similar. In the first one, we transform the columns and transpose - // the results. In the second one, we transform the rows. To achieve that, - // as the first pass results are transposed, we transpose the columns (that - // is the transposed rows) and transpose the results (so that it goes back - // in normal/row positions). - int pass; - // We need an intermediate buffer between passes. - DECLARE_ALIGNED(16, int16_t, intermediate[256]); - const int16_t *in = input; - int16_t *out0 = intermediate; - tran_low_t *out1 = output; - // Constants - // When we use them, in one case, they are all the same. In all others - // it's a pair of them that we need to repeat four times. This is done - // by constructing the 32 bit constant corresponding to that pair. - const __m128i k__cospi_p16_p16 = _mm_set1_epi16(cospi_16_64); - const __m128i k__cospi_p16_m16 = pair_set_epi16(cospi_16_64, -cospi_16_64); - const __m128i k__cospi_p24_p08 = pair_set_epi16(cospi_24_64, cospi_8_64); - const __m128i k__cospi_p08_m24 = pair_set_epi16(cospi_8_64, -cospi_24_64); - const __m128i k__cospi_m08_p24 = pair_set_epi16(-cospi_8_64, cospi_24_64); - const __m128i k__cospi_p28_p04 = pair_set_epi16(cospi_28_64, cospi_4_64); - const __m128i k__cospi_m04_p28 = pair_set_epi16(-cospi_4_64, cospi_28_64); - const __m128i k__cospi_p12_p20 = pair_set_epi16(cospi_12_64, cospi_20_64); - const __m128i k__cospi_m20_p12 = pair_set_epi16(-cospi_20_64, cospi_12_64); - const __m128i k__cospi_p30_p02 = pair_set_epi16(cospi_30_64, cospi_2_64); - const __m128i k__cospi_p14_p18 = pair_set_epi16(cospi_14_64, cospi_18_64); - const __m128i k__cospi_m02_p30 = pair_set_epi16(-cospi_2_64, cospi_30_64); - const __m128i k__cospi_m18_p14 = pair_set_epi16(-cospi_18_64, cospi_14_64); - const __m128i k__cospi_p22_p10 = pair_set_epi16(cospi_22_64, cospi_10_64); - const __m128i k__cospi_p06_p26 = pair_set_epi16(cospi_6_64, cospi_26_64); - const __m128i k__cospi_m10_p22 = pair_set_epi16(-cospi_10_64, cospi_22_64); - const __m128i k__cospi_m26_p06 = pair_set_epi16(-cospi_26_64, cospi_6_64); - const __m128i k__DCT_CONST_ROUNDING = _mm_set1_epi32(DCT_CONST_ROUNDING); - const __m128i kOne = _mm_set1_epi16(1); - // Do the two transform/transpose passes - for (pass = 0; pass < 2; ++pass) { - // We process eight columns (transposed rows in second pass) at a time. - int column_start; -#if DCT_HIGH_BIT_DEPTH - int overflow; -#endif - for (column_start = 0; column_start < 16; column_start += 8) { - __m128i in00, in01, in02, in03, in04, in05, in06, in07; - __m128i in08, in09, in10, in11, in12, in13, in14, in15; - __m128i input0, input1, input2, input3, input4, input5, input6, input7; - __m128i step1_0, step1_1, step1_2, step1_3; - __m128i step1_4, step1_5, step1_6, step1_7; - __m128i step2_1, step2_2, step2_3, step2_4, step2_5, step2_6; - __m128i step3_0, step3_1, step3_2, step3_3; - __m128i step3_4, step3_5, step3_6, step3_7; - __m128i res00, res01, res02, res03, res04, res05, res06, res07; - __m128i res08, res09, res10, res11, res12, res13, res14, res15; - // Load and pre-condition input. - if (0 == pass) { - in00 = _mm_load_si128((const __m128i *)(in + 0 * stride)); - in01 = _mm_load_si128((const __m128i *)(in + 1 * stride)); - in02 = _mm_load_si128((const __m128i *)(in + 2 * stride)); - in03 = _mm_load_si128((const __m128i *)(in + 3 * stride)); - in04 = _mm_load_si128((const __m128i *)(in + 4 * stride)); - in05 = _mm_load_si128((const __m128i *)(in + 5 * stride)); - in06 = _mm_load_si128((const __m128i *)(in + 6 * stride)); - in07 = _mm_load_si128((const __m128i *)(in + 7 * stride)); - in08 = _mm_load_si128((const __m128i *)(in + 8 * stride)); - in09 = _mm_load_si128((const __m128i *)(in + 9 * stride)); - in10 = _mm_load_si128((const __m128i *)(in + 10 * stride)); - in11 = _mm_load_si128((const __m128i *)(in + 11 * stride)); - in12 = _mm_load_si128((const __m128i *)(in + 12 * stride)); - in13 = _mm_load_si128((const __m128i *)(in + 13 * stride)); - in14 = _mm_load_si128((const __m128i *)(in + 14 * stride)); - in15 = _mm_load_si128((const __m128i *)(in + 15 * stride)); - // x = x << 2 - in00 = _mm_slli_epi16(in00, 2); - in01 = _mm_slli_epi16(in01, 2); - in02 = _mm_slli_epi16(in02, 2); - in03 = _mm_slli_epi16(in03, 2); - in04 = _mm_slli_epi16(in04, 2); - in05 = _mm_slli_epi16(in05, 2); - in06 = _mm_slli_epi16(in06, 2); - in07 = _mm_slli_epi16(in07, 2); - in08 = _mm_slli_epi16(in08, 2); - in09 = _mm_slli_epi16(in09, 2); - in10 = _mm_slli_epi16(in10, 2); - in11 = _mm_slli_epi16(in11, 2); - in12 = _mm_slli_epi16(in12, 2); - in13 = _mm_slli_epi16(in13, 2); - in14 = _mm_slli_epi16(in14, 2); - in15 = _mm_slli_epi16(in15, 2); - } else { - in00 = _mm_load_si128((const __m128i *)(in + 0 * 16)); - in01 = _mm_load_si128((const __m128i *)(in + 1 * 16)); - in02 = _mm_load_si128((const __m128i *)(in + 2 * 16)); - in03 = _mm_load_si128((const __m128i *)(in + 3 * 16)); - in04 = _mm_load_si128((const __m128i *)(in + 4 * 16)); - in05 = _mm_load_si128((const __m128i *)(in + 5 * 16)); - in06 = _mm_load_si128((const __m128i *)(in + 6 * 16)); - in07 = _mm_load_si128((const __m128i *)(in + 7 * 16)); - in08 = _mm_load_si128((const __m128i *)(in + 8 * 16)); - in09 = _mm_load_si128((const __m128i *)(in + 9 * 16)); - in10 = _mm_load_si128((const __m128i *)(in + 10 * 16)); - in11 = _mm_load_si128((const __m128i *)(in + 11 * 16)); - in12 = _mm_load_si128((const __m128i *)(in + 12 * 16)); - in13 = _mm_load_si128((const __m128i *)(in + 13 * 16)); - in14 = _mm_load_si128((const __m128i *)(in + 14 * 16)); - in15 = _mm_load_si128((const __m128i *)(in + 15 * 16)); - // x = (x + 1) >> 2 - in00 = _mm_add_epi16(in00, kOne); - in01 = _mm_add_epi16(in01, kOne); - in02 = _mm_add_epi16(in02, kOne); - in03 = _mm_add_epi16(in03, kOne); - in04 = _mm_add_epi16(in04, kOne); - in05 = _mm_add_epi16(in05, kOne); - in06 = _mm_add_epi16(in06, kOne); - in07 = _mm_add_epi16(in07, kOne); - in08 = _mm_add_epi16(in08, kOne); - in09 = _mm_add_epi16(in09, kOne); - in10 = _mm_add_epi16(in10, kOne); - in11 = _mm_add_epi16(in11, kOne); - in12 = _mm_add_epi16(in12, kOne); - in13 = _mm_add_epi16(in13, kOne); - in14 = _mm_add_epi16(in14, kOne); - in15 = _mm_add_epi16(in15, kOne); - in00 = _mm_srai_epi16(in00, 2); - in01 = _mm_srai_epi16(in01, 2); - in02 = _mm_srai_epi16(in02, 2); - in03 = _mm_srai_epi16(in03, 2); - in04 = _mm_srai_epi16(in04, 2); - in05 = _mm_srai_epi16(in05, 2); - in06 = _mm_srai_epi16(in06, 2); - in07 = _mm_srai_epi16(in07, 2); - in08 = _mm_srai_epi16(in08, 2); - in09 = _mm_srai_epi16(in09, 2); - in10 = _mm_srai_epi16(in10, 2); - in11 = _mm_srai_epi16(in11, 2); - in12 = _mm_srai_epi16(in12, 2); - in13 = _mm_srai_epi16(in13, 2); - in14 = _mm_srai_epi16(in14, 2); - in15 = _mm_srai_epi16(in15, 2); - } - in += 8; - // Calculate input for the first 8 results. - { - input0 = ADD_EPI16(in00, in15); - input1 = ADD_EPI16(in01, in14); - input2 = ADD_EPI16(in02, in13); - input3 = ADD_EPI16(in03, in12); - input4 = ADD_EPI16(in04, in11); - input5 = ADD_EPI16(in05, in10); - input6 = ADD_EPI16(in06, in09); - input7 = ADD_EPI16(in07, in08); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x8(&input0, &input1, &input2, &input3, - &input4, &input5, &input6, &input7); - if (overflow) { - vpx_highbd_fdct16x16_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - // Calculate input for the next 8 results. - { - step1_0 = SUB_EPI16(in07, in08); - step1_1 = SUB_EPI16(in06, in09); - step1_2 = SUB_EPI16(in05, in10); - step1_3 = SUB_EPI16(in04, in11); - step1_4 = SUB_EPI16(in03, in12); - step1_5 = SUB_EPI16(in02, in13); - step1_6 = SUB_EPI16(in01, in14); - step1_7 = SUB_EPI16(in00, in15); -#if DCT_HIGH_BIT_DEPTH - overflow = - check_epi16_overflow_x8(&step1_0, &step1_1, &step1_2, &step1_3, - &step1_4, &step1_5, &step1_6, &step1_7); - if (overflow) { - vpx_highbd_fdct16x16_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - // Work on the first eight values; fdct8(input, even_results); - { - // Add/subtract - const __m128i q0 = ADD_EPI16(input0, input7); - const __m128i q1 = ADD_EPI16(input1, input6); - const __m128i q2 = ADD_EPI16(input2, input5); - const __m128i q3 = ADD_EPI16(input3, input4); - const __m128i q4 = SUB_EPI16(input3, input4); - const __m128i q5 = SUB_EPI16(input2, input5); - const __m128i q6 = SUB_EPI16(input1, input6); - const __m128i q7 = SUB_EPI16(input0, input7); -#if DCT_HIGH_BIT_DEPTH - overflow = - check_epi16_overflow_x8(&q0, &q1, &q2, &q3, &q4, &q5, &q6, &q7); - if (overflow) { - vpx_highbd_fdct16x16_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - // Work on first four results - { - // Add/subtract - const __m128i r0 = ADD_EPI16(q0, q3); - const __m128i r1 = ADD_EPI16(q1, q2); - const __m128i r2 = SUB_EPI16(q1, q2); - const __m128i r3 = SUB_EPI16(q0, q3); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x4(&r0, &r1, &r2, &r3); - if (overflow) { - vpx_highbd_fdct16x16_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - - // Interleave to do the multiply by constants which gets us - // into 32 bits. - { - const __m128i t0 = _mm_unpacklo_epi16(r0, r1); - const __m128i t1 = _mm_unpackhi_epi16(r0, r1); - const __m128i t2 = _mm_unpacklo_epi16(r2, r3); - const __m128i t3 = _mm_unpackhi_epi16(r2, r3); - res00 = mult_round_shift(&t0, &t1, &k__cospi_p16_p16, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - res08 = mult_round_shift(&t0, &t1, &k__cospi_p16_m16, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - res04 = mult_round_shift(&t2, &t3, &k__cospi_p24_p08, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - res12 = mult_round_shift(&t2, &t3, &k__cospi_m08_p24, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x4(&res00, &res08, &res04, &res12); - if (overflow) { - vpx_highbd_fdct16x16_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - } - // Work on next four results - { - // Interleave to do the multiply by constants which gets us - // into 32 bits. - const __m128i d0 = _mm_unpacklo_epi16(q6, q5); - const __m128i d1 = _mm_unpackhi_epi16(q6, q5); - const __m128i r0 = - mult_round_shift(&d0, &d1, &k__cospi_p16_m16, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - const __m128i r1 = - mult_round_shift(&d0, &d1, &k__cospi_p16_p16, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x2(&r0, &r1); - if (overflow) { - vpx_highbd_fdct16x16_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - { - // Add/subtract - const __m128i x0 = ADD_EPI16(q4, r0); - const __m128i x1 = SUB_EPI16(q4, r0); - const __m128i x2 = SUB_EPI16(q7, r1); - const __m128i x3 = ADD_EPI16(q7, r1); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x4(&x0, &x1, &x2, &x3); - if (overflow) { - vpx_highbd_fdct16x16_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - - // Interleave to do the multiply by constants which gets us - // into 32 bits. - { - const __m128i t0 = _mm_unpacklo_epi16(x0, x3); - const __m128i t1 = _mm_unpackhi_epi16(x0, x3); - const __m128i t2 = _mm_unpacklo_epi16(x1, x2); - const __m128i t3 = _mm_unpackhi_epi16(x1, x2); - res02 = mult_round_shift(&t0, &t1, &k__cospi_p28_p04, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - res14 = mult_round_shift(&t0, &t1, &k__cospi_m04_p28, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - res10 = mult_round_shift(&t2, &t3, &k__cospi_p12_p20, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - res06 = mult_round_shift(&t2, &t3, &k__cospi_m20_p12, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); -#if DCT_HIGH_BIT_DEPTH - overflow = - check_epi16_overflow_x4(&res02, &res14, &res10, &res06); - if (overflow) { - vpx_highbd_fdct16x16_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - } - } - } - // Work on the next eight values; step1 -> odd_results - { - // step 2 - { - const __m128i t0 = _mm_unpacklo_epi16(step1_5, step1_2); - const __m128i t1 = _mm_unpackhi_epi16(step1_5, step1_2); - const __m128i t2 = _mm_unpacklo_epi16(step1_4, step1_3); - const __m128i t3 = _mm_unpackhi_epi16(step1_4, step1_3); - step2_2 = mult_round_shift(&t0, &t1, &k__cospi_p16_m16, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - step2_3 = mult_round_shift(&t2, &t3, &k__cospi_p16_m16, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - step2_5 = mult_round_shift(&t0, &t1, &k__cospi_p16_p16, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - step2_4 = mult_round_shift(&t2, &t3, &k__cospi_p16_p16, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); -#if DCT_HIGH_BIT_DEPTH - overflow = - check_epi16_overflow_x4(&step2_2, &step2_3, &step2_5, &step2_4); - if (overflow) { - vpx_highbd_fdct16x16_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - // step 3 - { - step3_0 = ADD_EPI16(step1_0, step2_3); - step3_1 = ADD_EPI16(step1_1, step2_2); - step3_2 = SUB_EPI16(step1_1, step2_2); - step3_3 = SUB_EPI16(step1_0, step2_3); - step3_4 = SUB_EPI16(step1_7, step2_4); - step3_5 = SUB_EPI16(step1_6, step2_5); - step3_6 = ADD_EPI16(step1_6, step2_5); - step3_7 = ADD_EPI16(step1_7, step2_4); -#if DCT_HIGH_BIT_DEPTH - overflow = - check_epi16_overflow_x8(&step3_0, &step3_1, &step3_2, &step3_3, - &step3_4, &step3_5, &step3_6, &step3_7); - if (overflow) { - vpx_highbd_fdct16x16_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - // step 4 - { - const __m128i t0 = _mm_unpacklo_epi16(step3_1, step3_6); - const __m128i t1 = _mm_unpackhi_epi16(step3_1, step3_6); - const __m128i t2 = _mm_unpacklo_epi16(step3_2, step3_5); - const __m128i t3 = _mm_unpackhi_epi16(step3_2, step3_5); - step2_1 = mult_round_shift(&t0, &t1, &k__cospi_m08_p24, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - step2_2 = mult_round_shift(&t2, &t3, &k__cospi_p24_p08, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - step2_6 = mult_round_shift(&t0, &t1, &k__cospi_p24_p08, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - step2_5 = mult_round_shift(&t2, &t3, &k__cospi_p08_m24, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); -#if DCT_HIGH_BIT_DEPTH - overflow = - check_epi16_overflow_x4(&step2_1, &step2_2, &step2_6, &step2_5); - if (overflow) { - vpx_highbd_fdct16x16_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - // step 5 - { - step1_0 = ADD_EPI16(step3_0, step2_1); - step1_1 = SUB_EPI16(step3_0, step2_1); - step1_2 = ADD_EPI16(step3_3, step2_2); - step1_3 = SUB_EPI16(step3_3, step2_2); - step1_4 = SUB_EPI16(step3_4, step2_5); - step1_5 = ADD_EPI16(step3_4, step2_5); - step1_6 = SUB_EPI16(step3_7, step2_6); - step1_7 = ADD_EPI16(step3_7, step2_6); -#if DCT_HIGH_BIT_DEPTH - overflow = - check_epi16_overflow_x8(&step1_0, &step1_1, &step1_2, &step1_3, - &step1_4, &step1_5, &step1_6, &step1_7); - if (overflow) { - vpx_highbd_fdct16x16_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - // step 6 - { - const __m128i t0 = _mm_unpacklo_epi16(step1_0, step1_7); - const __m128i t1 = _mm_unpackhi_epi16(step1_0, step1_7); - const __m128i t2 = _mm_unpacklo_epi16(step1_1, step1_6); - const __m128i t3 = _mm_unpackhi_epi16(step1_1, step1_6); - res01 = mult_round_shift(&t0, &t1, &k__cospi_p30_p02, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - res09 = mult_round_shift(&t2, &t3, &k__cospi_p14_p18, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - res15 = mult_round_shift(&t0, &t1, &k__cospi_m02_p30, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - res07 = mult_round_shift(&t2, &t3, &k__cospi_m18_p14, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x4(&res01, &res09, &res15, &res07); - if (overflow) { - vpx_highbd_fdct16x16_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - { - const __m128i t0 = _mm_unpacklo_epi16(step1_2, step1_5); - const __m128i t1 = _mm_unpackhi_epi16(step1_2, step1_5); - const __m128i t2 = _mm_unpacklo_epi16(step1_3, step1_4); - const __m128i t3 = _mm_unpackhi_epi16(step1_3, step1_4); - res05 = mult_round_shift(&t0, &t1, &k__cospi_p22_p10, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - res13 = mult_round_shift(&t2, &t3, &k__cospi_p06_p26, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - res11 = mult_round_shift(&t0, &t1, &k__cospi_m10_p22, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); - res03 = mult_round_shift(&t2, &t3, &k__cospi_m26_p06, - &k__DCT_CONST_ROUNDING, DCT_CONST_BITS); -#if DCT_HIGH_BIT_DEPTH - overflow = check_epi16_overflow_x4(&res05, &res13, &res11, &res03); - if (overflow) { - vpx_highbd_fdct16x16_c(input, output, stride); - return; - } -#endif // DCT_HIGH_BIT_DEPTH - } - } - // Transpose the results, do it as two 8x8 transposes. - transpose_and_output8x8(&res00, &res01, &res02, &res03, &res04, &res05, - &res06, &res07, pass, out0, out1); - transpose_and_output8x8(&res08, &res09, &res10, &res11, &res12, &res13, - &res14, &res15, pass, out0 + 8, out1 + 8); - if (pass == 0) { - out0 += 8 * 16; - } else { - out1 += 8 * 16; - } - } - // Setup in/out for next pass. - in = intermediate; - } -} - -#undef ADD_EPI16 -#undef SUB_EPI16 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_txfm_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_txfm_sse2.c deleted file mode 100644 index e14b9919..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_txfm_sse2.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // SSE2 - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_dsp/x86/fwd_txfm_sse2.h" - -void vpx_fdct4x4_1_sse2(const int16_t *input, tran_low_t *output, int stride) { - __m128i in0, in1; - __m128i tmp; - const __m128i zero = _mm_setzero_si128(); - in0 = _mm_loadl_epi64((const __m128i *)(input + 0 * stride)); - in1 = _mm_loadl_epi64((const __m128i *)(input + 1 * stride)); - in1 = _mm_unpacklo_epi64( - in1, _mm_loadl_epi64((const __m128i *)(input + 2 * stride))); - in0 = _mm_unpacklo_epi64( - in0, _mm_loadl_epi64((const __m128i *)(input + 3 * stride))); - - tmp = _mm_add_epi16(in0, in1); - in0 = _mm_unpacklo_epi16(zero, tmp); - in1 = _mm_unpackhi_epi16(zero, tmp); - in0 = _mm_srai_epi32(in0, 16); - in1 = _mm_srai_epi32(in1, 16); - - tmp = _mm_add_epi32(in0, in1); - in0 = _mm_unpacklo_epi32(tmp, zero); - in1 = _mm_unpackhi_epi32(tmp, zero); - - tmp = _mm_add_epi32(in0, in1); - in0 = _mm_srli_si128(tmp, 8); - - in1 = _mm_add_epi32(tmp, in0); - in0 = _mm_slli_epi32(in1, 1); - output[0] = (tran_low_t)_mm_cvtsi128_si32(in0); -} - -void vpx_fdct8x8_1_sse2(const int16_t *input, tran_low_t *output, int stride) { - __m128i in0 = _mm_load_si128((const __m128i *)(input + 0 * stride)); - __m128i in1 = _mm_load_si128((const __m128i *)(input + 1 * stride)); - __m128i in2 = _mm_load_si128((const __m128i *)(input + 2 * stride)); - __m128i in3 = _mm_load_si128((const __m128i *)(input + 3 * stride)); - __m128i u0, u1, sum; - - u0 = _mm_add_epi16(in0, in1); - u1 = _mm_add_epi16(in2, in3); - - in0 = _mm_load_si128((const __m128i *)(input + 4 * stride)); - in1 = _mm_load_si128((const __m128i *)(input + 5 * stride)); - in2 = _mm_load_si128((const __m128i *)(input + 6 * stride)); - in3 = _mm_load_si128((const __m128i *)(input + 7 * stride)); - - sum = _mm_add_epi16(u0, u1); - - in0 = _mm_add_epi16(in0, in1); - in2 = _mm_add_epi16(in2, in3); - sum = _mm_add_epi16(sum, in0); - - u0 = _mm_setzero_si128(); - sum = _mm_add_epi16(sum, in2); - - in0 = _mm_unpacklo_epi16(u0, sum); - in1 = _mm_unpackhi_epi16(u0, sum); - in0 = _mm_srai_epi32(in0, 16); - in1 = _mm_srai_epi32(in1, 16); - - sum = _mm_add_epi32(in0, in1); - in0 = _mm_unpacklo_epi32(sum, u0); - in1 = _mm_unpackhi_epi32(sum, u0); - - sum = _mm_add_epi32(in0, in1); - in0 = _mm_srli_si128(sum, 8); - - in1 = _mm_add_epi32(sum, in0); - output[0] = (tran_low_t)_mm_cvtsi128_si32(in1); -} - -void vpx_fdct16x16_1_sse2(const int16_t *input, tran_low_t *output, - int stride) { - __m128i in0, in1, in2, in3; - __m128i u0, u1; - __m128i sum = _mm_setzero_si128(); - int i; - - for (i = 0; i < 2; ++i) { - in0 = _mm_load_si128((const __m128i *)(input + 0 * stride + 0)); - in1 = _mm_load_si128((const __m128i *)(input + 0 * stride + 8)); - in2 = _mm_load_si128((const __m128i *)(input + 1 * stride + 0)); - in3 = _mm_load_si128((const __m128i *)(input + 1 * stride + 8)); - - u0 = _mm_add_epi16(in0, in1); - u1 = _mm_add_epi16(in2, in3); - sum = _mm_add_epi16(sum, u0); - - in0 = _mm_load_si128((const __m128i *)(input + 2 * stride + 0)); - in1 = _mm_load_si128((const __m128i *)(input + 2 * stride + 8)); - in2 = _mm_load_si128((const __m128i *)(input + 3 * stride + 0)); - in3 = _mm_load_si128((const __m128i *)(input + 3 * stride + 8)); - - sum = _mm_add_epi16(sum, u1); - u0 = _mm_add_epi16(in0, in1); - u1 = _mm_add_epi16(in2, in3); - sum = _mm_add_epi16(sum, u0); - - in0 = _mm_load_si128((const __m128i *)(input + 4 * stride + 0)); - in1 = _mm_load_si128((const __m128i *)(input + 4 * stride + 8)); - in2 = _mm_load_si128((const __m128i *)(input + 5 * stride + 0)); - in3 = _mm_load_si128((const __m128i *)(input + 5 * stride + 8)); - - sum = _mm_add_epi16(sum, u1); - u0 = _mm_add_epi16(in0, in1); - u1 = _mm_add_epi16(in2, in3); - sum = _mm_add_epi16(sum, u0); - - in0 = _mm_load_si128((const __m128i *)(input + 6 * stride + 0)); - in1 = _mm_load_si128((const __m128i *)(input + 6 * stride + 8)); - in2 = _mm_load_si128((const __m128i *)(input + 7 * stride + 0)); - in3 = _mm_load_si128((const __m128i *)(input + 7 * stride + 8)); - - sum = _mm_add_epi16(sum, u1); - u0 = _mm_add_epi16(in0, in1); - u1 = _mm_add_epi16(in2, in3); - sum = _mm_add_epi16(sum, u0); - - sum = _mm_add_epi16(sum, u1); - input += 8 * stride; - } - - u0 = _mm_setzero_si128(); - in0 = _mm_unpacklo_epi16(u0, sum); - in1 = _mm_unpackhi_epi16(u0, sum); - in0 = _mm_srai_epi32(in0, 16); - in1 = _mm_srai_epi32(in1, 16); - - sum = _mm_add_epi32(in0, in1); - in0 = _mm_unpacklo_epi32(sum, u0); - in1 = _mm_unpackhi_epi32(sum, u0); - - sum = _mm_add_epi32(in0, in1); - in0 = _mm_srli_si128(sum, 8); - - in1 = _mm_add_epi32(sum, in0); - in1 = _mm_srai_epi32(in1, 1); - output[0] = (tran_low_t)_mm_cvtsi128_si32(in1); -} - -void vpx_fdct32x32_1_sse2(const int16_t *input, tran_low_t *output, - int stride) { - __m128i in0, in1, in2, in3; - __m128i u0, u1; - __m128i sum = _mm_setzero_si128(); - int i; - - for (i = 0; i < 8; ++i) { - in0 = _mm_load_si128((const __m128i *)(input + 0)); - in1 = _mm_load_si128((const __m128i *)(input + 8)); - in2 = _mm_load_si128((const __m128i *)(input + 16)); - in3 = _mm_load_si128((const __m128i *)(input + 24)); - - input += stride; - u0 = _mm_add_epi16(in0, in1); - u1 = _mm_add_epi16(in2, in3); - sum = _mm_add_epi16(sum, u0); - - in0 = _mm_load_si128((const __m128i *)(input + 0)); - in1 = _mm_load_si128((const __m128i *)(input + 8)); - in2 = _mm_load_si128((const __m128i *)(input + 16)); - in3 = _mm_load_si128((const __m128i *)(input + 24)); - - input += stride; - sum = _mm_add_epi16(sum, u1); - u0 = _mm_add_epi16(in0, in1); - u1 = _mm_add_epi16(in2, in3); - sum = _mm_add_epi16(sum, u0); - - in0 = _mm_load_si128((const __m128i *)(input + 0)); - in1 = _mm_load_si128((const __m128i *)(input + 8)); - in2 = _mm_load_si128((const __m128i *)(input + 16)); - in3 = _mm_load_si128((const __m128i *)(input + 24)); - - input += stride; - sum = _mm_add_epi16(sum, u1); - u0 = _mm_add_epi16(in0, in1); - u1 = _mm_add_epi16(in2, in3); - sum = _mm_add_epi16(sum, u0); - - in0 = _mm_load_si128((const __m128i *)(input + 0)); - in1 = _mm_load_si128((const __m128i *)(input + 8)); - in2 = _mm_load_si128((const __m128i *)(input + 16)); - in3 = _mm_load_si128((const __m128i *)(input + 24)); - - input += stride; - sum = _mm_add_epi16(sum, u1); - u0 = _mm_add_epi16(in0, in1); - u1 = _mm_add_epi16(in2, in3); - sum = _mm_add_epi16(sum, u0); - - sum = _mm_add_epi16(sum, u1); - } - - u0 = _mm_setzero_si128(); - in0 = _mm_unpacklo_epi16(u0, sum); - in1 = _mm_unpackhi_epi16(u0, sum); - in0 = _mm_srai_epi32(in0, 16); - in1 = _mm_srai_epi32(in1, 16); - - sum = _mm_add_epi32(in0, in1); - in0 = _mm_unpacklo_epi32(sum, u0); - in1 = _mm_unpackhi_epi32(sum, u0); - - sum = _mm_add_epi32(in0, in1); - in0 = _mm_srli_si128(sum, 8); - - in1 = _mm_add_epi32(sum, in0); - in1 = _mm_srai_epi32(in1, 3); - output[0] = (tran_low_t)_mm_cvtsi128_si32(in1); -} - -#define DCT_HIGH_BIT_DEPTH 0 -#define FDCT4x4_2D vpx_fdct4x4_sse2 -#define FDCT8x8_2D vpx_fdct8x8_sse2 -#define FDCT16x16_2D vpx_fdct16x16_sse2 -#include "vpx_dsp/x86/fwd_txfm_impl_sse2.h" -#undef FDCT4x4_2D -#undef FDCT8x8_2D -#undef FDCT16x16_2D - -#define FDCT32x32_2D vpx_fdct32x32_rd_sse2 -#define FDCT32x32_HIGH_PRECISION 0 -#include "vpx_dsp/x86/fwd_dct32x32_impl_sse2.h" -#undef FDCT32x32_2D -#undef FDCT32x32_HIGH_PRECISION - -#define FDCT32x32_2D vpx_fdct32x32_sse2 -#define FDCT32x32_HIGH_PRECISION 1 -#include "vpx_dsp/x86/fwd_dct32x32_impl_sse2.h" // NOLINT -#undef FDCT32x32_2D -#undef FDCT32x32_HIGH_PRECISION -#undef DCT_HIGH_BIT_DEPTH - -#if CONFIG_VP9_HIGHBITDEPTH -#define DCT_HIGH_BIT_DEPTH 1 -#define FDCT4x4_2D vpx_highbd_fdct4x4_sse2 -#define FDCT8x8_2D vpx_highbd_fdct8x8_sse2 -#define FDCT16x16_2D vpx_highbd_fdct16x16_sse2 -#include "vpx_dsp/x86/fwd_txfm_impl_sse2.h" // NOLINT -#undef FDCT4x4_2D -#undef FDCT8x8_2D -#undef FDCT16x16_2D - -#define FDCT32x32_2D vpx_highbd_fdct32x32_rd_sse2 -#define FDCT32x32_HIGH_PRECISION 0 -#include "vpx_dsp/x86/fwd_dct32x32_impl_sse2.h" // NOLINT -#undef FDCT32x32_2D -#undef FDCT32x32_HIGH_PRECISION - -#define FDCT32x32_2D vpx_highbd_fdct32x32_sse2 -#define FDCT32x32_HIGH_PRECISION 1 -#include "vpx_dsp/x86/fwd_dct32x32_impl_sse2.h" // NOLINT -#undef FDCT32x32_2D -#undef FDCT32x32_HIGH_PRECISION -#undef DCT_HIGH_BIT_DEPTH -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_txfm_sse2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_txfm_sse2.h deleted file mode 100644 index 5aa27797..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_txfm_sse2.h +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_X86_FWD_TXFM_SSE2_H_ -#define VPX_VPX_DSP_X86_FWD_TXFM_SSE2_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define pair_set_epi32(a, b) \ - _mm_set_epi32((int)(b), (int)(a), (int)(b), (int)(a)) - -static INLINE __m128i k_madd_epi32(__m128i a, __m128i b) { - __m128i buf0, buf1; - buf0 = _mm_mul_epu32(a, b); - a = _mm_srli_epi64(a, 32); - b = _mm_srli_epi64(b, 32); - buf1 = _mm_mul_epu32(a, b); - return _mm_add_epi64(buf0, buf1); -} - -static INLINE __m128i k_packs_epi64(__m128i a, __m128i b) { - __m128i buf0 = _mm_shuffle_epi32(a, _MM_SHUFFLE(0, 0, 2, 0)); - __m128i buf1 = _mm_shuffle_epi32(b, _MM_SHUFFLE(0, 0, 2, 0)); - return _mm_unpacklo_epi64(buf0, buf1); -} - -static INLINE int check_epi16_overflow_x2(const __m128i *preg0, - const __m128i *preg1) { - const __m128i max_overflow = _mm_set1_epi16(0x7fff); - const __m128i min_overflow = _mm_set1_epi16((short)0x8000); - __m128i cmp0 = _mm_or_si128(_mm_cmpeq_epi16(*preg0, max_overflow), - _mm_cmpeq_epi16(*preg0, min_overflow)); - __m128i cmp1 = _mm_or_si128(_mm_cmpeq_epi16(*preg1, max_overflow), - _mm_cmpeq_epi16(*preg1, min_overflow)); - cmp0 = _mm_or_si128(cmp0, cmp1); - return _mm_movemask_epi8(cmp0); -} - -static INLINE int check_epi16_overflow_x4(const __m128i *preg0, - const __m128i *preg1, - const __m128i *preg2, - const __m128i *preg3) { - const __m128i max_overflow = _mm_set1_epi16(0x7fff); - const __m128i min_overflow = _mm_set1_epi16((short)0x8000); - __m128i cmp0 = _mm_or_si128(_mm_cmpeq_epi16(*preg0, max_overflow), - _mm_cmpeq_epi16(*preg0, min_overflow)); - __m128i cmp1 = _mm_or_si128(_mm_cmpeq_epi16(*preg1, max_overflow), - _mm_cmpeq_epi16(*preg1, min_overflow)); - __m128i cmp2 = _mm_or_si128(_mm_cmpeq_epi16(*preg2, max_overflow), - _mm_cmpeq_epi16(*preg2, min_overflow)); - __m128i cmp3 = _mm_or_si128(_mm_cmpeq_epi16(*preg3, max_overflow), - _mm_cmpeq_epi16(*preg3, min_overflow)); - cmp0 = _mm_or_si128(_mm_or_si128(cmp0, cmp1), _mm_or_si128(cmp2, cmp3)); - return _mm_movemask_epi8(cmp0); -} - -static INLINE int check_epi16_overflow_x8( - const __m128i *preg0, const __m128i *preg1, const __m128i *preg2, - const __m128i *preg3, const __m128i *preg4, const __m128i *preg5, - const __m128i *preg6, const __m128i *preg7) { - int res0, res1; - res0 = check_epi16_overflow_x4(preg0, preg1, preg2, preg3); - res1 = check_epi16_overflow_x4(preg4, preg5, preg6, preg7); - return res0 + res1; -} - -static INLINE int check_epi16_overflow_x12( - const __m128i *preg0, const __m128i *preg1, const __m128i *preg2, - const __m128i *preg3, const __m128i *preg4, const __m128i *preg5, - const __m128i *preg6, const __m128i *preg7, const __m128i *preg8, - const __m128i *preg9, const __m128i *preg10, const __m128i *preg11) { - int res0, res1; - res0 = check_epi16_overflow_x4(preg0, preg1, preg2, preg3); - res1 = check_epi16_overflow_x4(preg4, preg5, preg6, preg7); - if (!res0) res0 = check_epi16_overflow_x4(preg8, preg9, preg10, preg11); - return res0 + res1; -} - -static INLINE int check_epi16_overflow_x16( - const __m128i *preg0, const __m128i *preg1, const __m128i *preg2, - const __m128i *preg3, const __m128i *preg4, const __m128i *preg5, - const __m128i *preg6, const __m128i *preg7, const __m128i *preg8, - const __m128i *preg9, const __m128i *preg10, const __m128i *preg11, - const __m128i *preg12, const __m128i *preg13, const __m128i *preg14, - const __m128i *preg15) { - int res0, res1; - res0 = check_epi16_overflow_x4(preg0, preg1, preg2, preg3); - res1 = check_epi16_overflow_x4(preg4, preg5, preg6, preg7); - if (!res0) { - res0 = check_epi16_overflow_x4(preg8, preg9, preg10, preg11); - if (!res1) res1 = check_epi16_overflow_x4(preg12, preg13, preg14, preg15); - } - return res0 + res1; -} - -static INLINE int check_epi16_overflow_x32( - const __m128i *preg0, const __m128i *preg1, const __m128i *preg2, - const __m128i *preg3, const __m128i *preg4, const __m128i *preg5, - const __m128i *preg6, const __m128i *preg7, const __m128i *preg8, - const __m128i *preg9, const __m128i *preg10, const __m128i *preg11, - const __m128i *preg12, const __m128i *preg13, const __m128i *preg14, - const __m128i *preg15, const __m128i *preg16, const __m128i *preg17, - const __m128i *preg18, const __m128i *preg19, const __m128i *preg20, - const __m128i *preg21, const __m128i *preg22, const __m128i *preg23, - const __m128i *preg24, const __m128i *preg25, const __m128i *preg26, - const __m128i *preg27, const __m128i *preg28, const __m128i *preg29, - const __m128i *preg30, const __m128i *preg31) { - int res0, res1; - res0 = check_epi16_overflow_x4(preg0, preg1, preg2, preg3); - res1 = check_epi16_overflow_x4(preg4, preg5, preg6, preg7); - if (!res0) { - res0 = check_epi16_overflow_x4(preg8, preg9, preg10, preg11); - if (!res1) { - res1 = check_epi16_overflow_x4(preg12, preg13, preg14, preg15); - if (!res0) { - res0 = check_epi16_overflow_x4(preg16, preg17, preg18, preg19); - if (!res1) { - res1 = check_epi16_overflow_x4(preg20, preg21, preg22, preg23); - if (!res0) { - res0 = check_epi16_overflow_x4(preg24, preg25, preg26, preg27); - if (!res1) - res1 = check_epi16_overflow_x4(preg28, preg29, preg30, preg31); - } - } - } - } - } - return res0 + res1; -} - -static INLINE int k_check_epi32_overflow_4(const __m128i *preg0, - const __m128i *preg1, - const __m128i *preg2, - const __m128i *preg3, - const __m128i *zero) { - __m128i minus_one = _mm_set1_epi32(-1); - // Check for overflows - __m128i reg0_shifted = _mm_slli_epi64(*preg0, 1); - __m128i reg1_shifted = _mm_slli_epi64(*preg1, 1); - __m128i reg2_shifted = _mm_slli_epi64(*preg2, 1); - __m128i reg3_shifted = _mm_slli_epi64(*preg3, 1); - __m128i reg0_top_dwords = - _mm_shuffle_epi32(reg0_shifted, _MM_SHUFFLE(0, 0, 3, 1)); - __m128i reg1_top_dwords = - _mm_shuffle_epi32(reg1_shifted, _MM_SHUFFLE(0, 0, 3, 1)); - __m128i reg2_top_dwords = - _mm_shuffle_epi32(reg2_shifted, _MM_SHUFFLE(0, 0, 3, 1)); - __m128i reg3_top_dwords = - _mm_shuffle_epi32(reg3_shifted, _MM_SHUFFLE(0, 0, 3, 1)); - __m128i top_dwords_01 = _mm_unpacklo_epi64(reg0_top_dwords, reg1_top_dwords); - __m128i top_dwords_23 = _mm_unpacklo_epi64(reg2_top_dwords, reg3_top_dwords); - __m128i valid_positve_01 = _mm_cmpeq_epi32(top_dwords_01, *zero); - __m128i valid_positve_23 = _mm_cmpeq_epi32(top_dwords_23, *zero); - __m128i valid_negative_01 = _mm_cmpeq_epi32(top_dwords_01, minus_one); - __m128i valid_negative_23 = _mm_cmpeq_epi32(top_dwords_23, minus_one); - int overflow_01 = - _mm_movemask_epi8(_mm_cmpeq_epi32(valid_positve_01, valid_negative_01)); - int overflow_23 = - _mm_movemask_epi8(_mm_cmpeq_epi32(valid_positve_23, valid_negative_23)); - return (overflow_01 + overflow_23); -} - -static INLINE int k_check_epi32_overflow_8( - const __m128i *preg0, const __m128i *preg1, const __m128i *preg2, - const __m128i *preg3, const __m128i *preg4, const __m128i *preg5, - const __m128i *preg6, const __m128i *preg7, const __m128i *zero) { - int overflow = k_check_epi32_overflow_4(preg0, preg1, preg2, preg3, zero); - if (!overflow) { - overflow = k_check_epi32_overflow_4(preg4, preg5, preg6, preg7, zero); - } - return overflow; -} - -static INLINE int k_check_epi32_overflow_16( - const __m128i *preg0, const __m128i *preg1, const __m128i *preg2, - const __m128i *preg3, const __m128i *preg4, const __m128i *preg5, - const __m128i *preg6, const __m128i *preg7, const __m128i *preg8, - const __m128i *preg9, const __m128i *preg10, const __m128i *preg11, - const __m128i *preg12, const __m128i *preg13, const __m128i *preg14, - const __m128i *preg15, const __m128i *zero) { - int overflow = k_check_epi32_overflow_4(preg0, preg1, preg2, preg3, zero); - if (!overflow) { - overflow = k_check_epi32_overflow_4(preg4, preg5, preg6, preg7, zero); - if (!overflow) { - overflow = k_check_epi32_overflow_4(preg8, preg9, preg10, preg11, zero); - if (!overflow) { - overflow = - k_check_epi32_overflow_4(preg12, preg13, preg14, preg15, zero); - } - } - } - return overflow; -} - -static INLINE int k_check_epi32_overflow_32( - const __m128i *preg0, const __m128i *preg1, const __m128i *preg2, - const __m128i *preg3, const __m128i *preg4, const __m128i *preg5, - const __m128i *preg6, const __m128i *preg7, const __m128i *preg8, - const __m128i *preg9, const __m128i *preg10, const __m128i *preg11, - const __m128i *preg12, const __m128i *preg13, const __m128i *preg14, - const __m128i *preg15, const __m128i *preg16, const __m128i *preg17, - const __m128i *preg18, const __m128i *preg19, const __m128i *preg20, - const __m128i *preg21, const __m128i *preg22, const __m128i *preg23, - const __m128i *preg24, const __m128i *preg25, const __m128i *preg26, - const __m128i *preg27, const __m128i *preg28, const __m128i *preg29, - const __m128i *preg30, const __m128i *preg31, const __m128i *zero) { - int overflow = k_check_epi32_overflow_4(preg0, preg1, preg2, preg3, zero); - if (!overflow) { - overflow = k_check_epi32_overflow_4(preg4, preg5, preg6, preg7, zero); - if (!overflow) { - overflow = k_check_epi32_overflow_4(preg8, preg9, preg10, preg11, zero); - if (!overflow) { - overflow = - k_check_epi32_overflow_4(preg12, preg13, preg14, preg15, zero); - if (!overflow) { - overflow = - k_check_epi32_overflow_4(preg16, preg17, preg18, preg19, zero); - if (!overflow) { - overflow = - k_check_epi32_overflow_4(preg20, preg21, preg22, preg23, zero); - if (!overflow) { - overflow = k_check_epi32_overflow_4(preg24, preg25, preg26, - preg27, zero); - if (!overflow) { - overflow = k_check_epi32_overflow_4(preg28, preg29, preg30, - preg31, zero); - } - } - } - } - } - } - } - return overflow; -} - -static INLINE void store_output(const __m128i *poutput, tran_low_t *dst_ptr) { -#if CONFIG_VP9_HIGHBITDEPTH - const __m128i zero = _mm_setzero_si128(); - const __m128i sign_bits = _mm_cmplt_epi16(*poutput, zero); - __m128i out0 = _mm_unpacklo_epi16(*poutput, sign_bits); - __m128i out1 = _mm_unpackhi_epi16(*poutput, sign_bits); - _mm_store_si128((__m128i *)(dst_ptr), out0); - _mm_store_si128((__m128i *)(dst_ptr + 4), out1); -#else - _mm_store_si128((__m128i *)(dst_ptr), *poutput); -#endif // CONFIG_VP9_HIGHBITDEPTH -} - -static INLINE void storeu_output(const __m128i *poutput, tran_low_t *dst_ptr) { -#if CONFIG_VP9_HIGHBITDEPTH - const __m128i zero = _mm_setzero_si128(); - const __m128i sign_bits = _mm_cmplt_epi16(*poutput, zero); - __m128i out0 = _mm_unpacklo_epi16(*poutput, sign_bits); - __m128i out1 = _mm_unpackhi_epi16(*poutput, sign_bits); - _mm_storeu_si128((__m128i *)(dst_ptr), out0); - _mm_storeu_si128((__m128i *)(dst_ptr + 4), out1); -#else - _mm_storeu_si128((__m128i *)(dst_ptr), *poutput); -#endif // CONFIG_VP9_HIGHBITDEPTH -} - -static INLINE __m128i mult_round_shift(const __m128i *pin0, const __m128i *pin1, - const __m128i *pmultiplier, - const __m128i *prounding, - const int shift) { - const __m128i u0 = _mm_madd_epi16(*pin0, *pmultiplier); - const __m128i u1 = _mm_madd_epi16(*pin1, *pmultiplier); - const __m128i v0 = _mm_add_epi32(u0, *prounding); - const __m128i v1 = _mm_add_epi32(u1, *prounding); - const __m128i w0 = _mm_srai_epi32(v0, shift); - const __m128i w1 = _mm_srai_epi32(v1, shift); - return _mm_packs_epi32(w0, w1); -} - -static INLINE void transpose_and_output8x8( - const __m128i *pin00, const __m128i *pin01, const __m128i *pin02, - const __m128i *pin03, const __m128i *pin04, const __m128i *pin05, - const __m128i *pin06, const __m128i *pin07, const int pass, - int16_t *out0_ptr, tran_low_t *out1_ptr) { - // 00 01 02 03 04 05 06 07 - // 10 11 12 13 14 15 16 17 - // 20 21 22 23 24 25 26 27 - // 30 31 32 33 34 35 36 37 - // 40 41 42 43 44 45 46 47 - // 50 51 52 53 54 55 56 57 - // 60 61 62 63 64 65 66 67 - // 70 71 72 73 74 75 76 77 - const __m128i tr0_0 = _mm_unpacklo_epi16(*pin00, *pin01); - const __m128i tr0_1 = _mm_unpacklo_epi16(*pin02, *pin03); - const __m128i tr0_2 = _mm_unpackhi_epi16(*pin00, *pin01); - const __m128i tr0_3 = _mm_unpackhi_epi16(*pin02, *pin03); - const __m128i tr0_4 = _mm_unpacklo_epi16(*pin04, *pin05); - const __m128i tr0_5 = _mm_unpacklo_epi16(*pin06, *pin07); - const __m128i tr0_6 = _mm_unpackhi_epi16(*pin04, *pin05); - const __m128i tr0_7 = _mm_unpackhi_epi16(*pin06, *pin07); - // 00 10 01 11 02 12 03 13 - // 20 30 21 31 22 32 23 33 - // 04 14 05 15 06 16 07 17 - // 24 34 25 35 26 36 27 37 - // 40 50 41 51 42 52 43 53 - // 60 70 61 71 62 72 63 73 - // 54 54 55 55 56 56 57 57 - // 64 74 65 75 66 76 67 77 - const __m128i tr1_0 = _mm_unpacklo_epi32(tr0_0, tr0_1); - const __m128i tr1_1 = _mm_unpacklo_epi32(tr0_2, tr0_3); - const __m128i tr1_2 = _mm_unpackhi_epi32(tr0_0, tr0_1); - const __m128i tr1_3 = _mm_unpackhi_epi32(tr0_2, tr0_3); - const __m128i tr1_4 = _mm_unpacklo_epi32(tr0_4, tr0_5); - const __m128i tr1_5 = _mm_unpacklo_epi32(tr0_6, tr0_7); - const __m128i tr1_6 = _mm_unpackhi_epi32(tr0_4, tr0_5); - const __m128i tr1_7 = _mm_unpackhi_epi32(tr0_6, tr0_7); - // 00 10 20 30 01 11 21 31 - // 40 50 60 70 41 51 61 71 - // 02 12 22 32 03 13 23 33 - // 42 52 62 72 43 53 63 73 - // 04 14 24 34 05 15 21 36 - // 44 54 64 74 45 55 61 76 - // 06 16 26 36 07 17 27 37 - // 46 56 66 76 47 57 67 77 - const __m128i tr2_0 = _mm_unpacklo_epi64(tr1_0, tr1_4); - const __m128i tr2_1 = _mm_unpackhi_epi64(tr1_0, tr1_4); - const __m128i tr2_2 = _mm_unpacklo_epi64(tr1_2, tr1_6); - const __m128i tr2_3 = _mm_unpackhi_epi64(tr1_2, tr1_6); - const __m128i tr2_4 = _mm_unpacklo_epi64(tr1_1, tr1_5); - const __m128i tr2_5 = _mm_unpackhi_epi64(tr1_1, tr1_5); - const __m128i tr2_6 = _mm_unpacklo_epi64(tr1_3, tr1_7); - const __m128i tr2_7 = _mm_unpackhi_epi64(tr1_3, tr1_7); - // 00 10 20 30 40 50 60 70 - // 01 11 21 31 41 51 61 71 - // 02 12 22 32 42 52 62 72 - // 03 13 23 33 43 53 63 73 - // 04 14 24 34 44 54 64 74 - // 05 15 25 35 45 55 65 75 - // 06 16 26 36 46 56 66 76 - // 07 17 27 37 47 57 67 77 - if (pass == 0) { - _mm_storeu_si128((__m128i *)(out0_ptr + 0 * 16), tr2_0); - _mm_storeu_si128((__m128i *)(out0_ptr + 1 * 16), tr2_1); - _mm_storeu_si128((__m128i *)(out0_ptr + 2 * 16), tr2_2); - _mm_storeu_si128((__m128i *)(out0_ptr + 3 * 16), tr2_3); - _mm_storeu_si128((__m128i *)(out0_ptr + 4 * 16), tr2_4); - _mm_storeu_si128((__m128i *)(out0_ptr + 5 * 16), tr2_5); - _mm_storeu_si128((__m128i *)(out0_ptr + 6 * 16), tr2_6); - _mm_storeu_si128((__m128i *)(out0_ptr + 7 * 16), tr2_7); - } else { - storeu_output(&tr2_0, (out1_ptr + 0 * 16)); - storeu_output(&tr2_1, (out1_ptr + 1 * 16)); - storeu_output(&tr2_2, (out1_ptr + 2 * 16)); - storeu_output(&tr2_3, (out1_ptr + 3 * 16)); - storeu_output(&tr2_4, (out1_ptr + 4 * 16)); - storeu_output(&tr2_5, (out1_ptr + 5 * 16)); - storeu_output(&tr2_6, (out1_ptr + 6 * 16)); - storeu_output(&tr2_7, (out1_ptr + 7 * 16)); - } -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_DSP_X86_FWD_TXFM_SSE2_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_txfm_ssse3_x86_64.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_txfm_ssse3_x86_64.asm deleted file mode 100644 index 2c338fb5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/fwd_txfm_ssse3_x86_64.asm +++ /dev/null @@ -1,361 +0,0 @@ -; -; Copyright (c) 2015 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "third_party/x86inc/x86inc.asm" - -SECTION_RODATA - -pw_11585x2: times 8 dw 23170 -pd_8192: times 4 dd 8192 - -%macro TRANSFORM_COEFFS 2 -pw_%1_%2: dw %1, %2, %1, %2, %1, %2, %1, %2 -pw_%2_m%1: dw %2, -%1, %2, -%1, %2, -%1, %2, -%1 -%endmacro - -TRANSFORM_COEFFS 11585, 11585 -TRANSFORM_COEFFS 15137, 6270 -TRANSFORM_COEFFS 16069, 3196 -TRANSFORM_COEFFS 9102, 13623 - -SECTION .text - -%if VPX_ARCH_X86_64 -INIT_XMM ssse3 -cglobal fdct8x8, 3, 5, 13, input, output, stride - - mova m8, [GLOBAL(pd_8192)] - mova m12, [GLOBAL(pw_11585x2)] - - lea r3, [2 * strideq] - lea r4, [4 * strideq] - mova m0, [inputq] - mova m1, [inputq + r3] - lea inputq, [inputq + r4] - mova m2, [inputq] - mova m3, [inputq + r3] - lea inputq, [inputq + r4] - mova m4, [inputq] - mova m5, [inputq + r3] - lea inputq, [inputq + r4] - mova m6, [inputq] - mova m7, [inputq + r3] - - ; left shift by 2 to increase forward transformation precision - psllw m0, 2 - psllw m1, 2 - psllw m2, 2 - psllw m3, 2 - psllw m4, 2 - psllw m5, 2 - psllw m6, 2 - psllw m7, 2 - - ; column transform - ; stage 1 - paddw m10, m0, m7 - psubw m0, m7 - - paddw m9, m1, m6 - psubw m1, m6 - - paddw m7, m2, m5 - psubw m2, m5 - - paddw m6, m3, m4 - psubw m3, m4 - - ; stage 2 - paddw m5, m9, m7 - psubw m9, m7 - - paddw m4, m10, m6 - psubw m10, m6 - - paddw m7, m1, m2 - psubw m1, m2 - - ; stage 3 - paddw m6, m4, m5 - psubw m4, m5 - - pmulhrsw m1, m12 - pmulhrsw m7, m12 - - ; sin(pi / 8), cos(pi / 8) - punpcklwd m2, m10, m9 - punpckhwd m10, m9 - pmaddwd m5, m2, [GLOBAL(pw_15137_6270)] - pmaddwd m2, [GLOBAL(pw_6270_m15137)] - pmaddwd m9, m10, [GLOBAL(pw_15137_6270)] - pmaddwd m10, [GLOBAL(pw_6270_m15137)] - paddd m5, m8 - paddd m2, m8 - paddd m9, m8 - paddd m10, m8 - psrad m5, 14 - psrad m2, 14 - psrad m9, 14 - psrad m10, 14 - packssdw m5, m9 - packssdw m2, m10 - - pmulhrsw m6, m12 - pmulhrsw m4, m12 - - paddw m9, m3, m1 - psubw m3, m1 - - paddw m10, m0, m7 - psubw m0, m7 - - ; stage 4 - ; sin(pi / 16), cos(pi / 16) - punpcklwd m1, m10, m9 - punpckhwd m10, m9 - pmaddwd m7, m1, [GLOBAL(pw_16069_3196)] - pmaddwd m1, [GLOBAL(pw_3196_m16069)] - pmaddwd m9, m10, [GLOBAL(pw_16069_3196)] - pmaddwd m10, [GLOBAL(pw_3196_m16069)] - paddd m7, m8 - paddd m1, m8 - paddd m9, m8 - paddd m10, m8 - psrad m7, 14 - psrad m1, 14 - psrad m9, 14 - psrad m10, 14 - packssdw m7, m9 - packssdw m1, m10 - - ; sin(3 * pi / 16), cos(3 * pi / 16) - punpcklwd m11, m0, m3 - punpckhwd m0, m3 - pmaddwd m9, m11, [GLOBAL(pw_9102_13623)] - pmaddwd m11, [GLOBAL(pw_13623_m9102)] - pmaddwd m3, m0, [GLOBAL(pw_9102_13623)] - pmaddwd m0, [GLOBAL(pw_13623_m9102)] - paddd m9, m8 - paddd m11, m8 - paddd m3, m8 - paddd m0, m8 - psrad m9, 14 - psrad m11, 14 - psrad m3, 14 - psrad m0, 14 - packssdw m9, m3 - packssdw m11, m0 - - ; transpose - ; stage 1 - punpcklwd m0, m6, m7 - punpcklwd m3, m5, m11 - punpckhwd m6, m7 - punpckhwd m5, m11 - punpcklwd m7, m4, m9 - punpcklwd m10, m2, m1 - punpckhwd m4, m9 - punpckhwd m2, m1 - - ; stage 2 - punpckldq m9, m0, m3 - punpckldq m1, m6, m5 - punpckhdq m0, m3 - punpckhdq m6, m5 - punpckldq m3, m7, m10 - punpckldq m5, m4, m2 - punpckhdq m7, m10 - punpckhdq m4, m2 - - ; stage 3 - punpcklqdq m10, m9, m3 - punpckhqdq m9, m3 - punpcklqdq m2, m0, m7 - punpckhqdq m0, m7 - punpcklqdq m3, m1, m5 - punpckhqdq m1, m5 - punpcklqdq m7, m6, m4 - punpckhqdq m6, m4 - - ; row transform - ; stage 1 - paddw m5, m10, m6 - psubw m10, m6 - - paddw m4, m9, m7 - psubw m9, m7 - - paddw m6, m2, m1 - psubw m2, m1 - - paddw m7, m0, m3 - psubw m0, m3 - - ;stage 2 - paddw m1, m5, m7 - psubw m5, m7 - - paddw m3, m4, m6 - psubw m4, m6 - - paddw m7, m9, m2 - psubw m9, m2 - - ; stage 3 - punpcklwd m6, m1, m3 - punpckhwd m1, m3 - pmaddwd m2, m6, [GLOBAL(pw_11585_11585)] - pmaddwd m6, [GLOBAL(pw_11585_m11585)] - pmaddwd m3, m1, [GLOBAL(pw_11585_11585)] - pmaddwd m1, [GLOBAL(pw_11585_m11585)] - paddd m2, m8 - paddd m6, m8 - paddd m3, m8 - paddd m1, m8 - psrad m2, 14 - psrad m6, 14 - psrad m3, 14 - psrad m1, 14 - packssdw m2, m3 - packssdw m6, m1 - - pmulhrsw m7, m12 - pmulhrsw m9, m12 - - punpcklwd m3, m5, m4 - punpckhwd m5, m4 - pmaddwd m1, m3, [GLOBAL(pw_15137_6270)] - pmaddwd m3, [GLOBAL(pw_6270_m15137)] - pmaddwd m4, m5, [GLOBAL(pw_15137_6270)] - pmaddwd m5, [GLOBAL(pw_6270_m15137)] - paddd m1, m8 - paddd m3, m8 - paddd m4, m8 - paddd m5, m8 - psrad m1, 14 - psrad m3, 14 - psrad m4, 14 - psrad m5, 14 - packssdw m1, m4 - packssdw m3, m5 - - paddw m4, m0, m9 - psubw m0, m9 - - paddw m5, m10, m7 - psubw m10, m7 - - ; stage 4 - punpcklwd m9, m5, m4 - punpckhwd m5, m4 - pmaddwd m7, m9, [GLOBAL(pw_16069_3196)] - pmaddwd m9, [GLOBAL(pw_3196_m16069)] - pmaddwd m4, m5, [GLOBAL(pw_16069_3196)] - pmaddwd m5, [GLOBAL(pw_3196_m16069)] - paddd m7, m8 - paddd m9, m8 - paddd m4, m8 - paddd m5, m8 - psrad m7, 14 - psrad m9, 14 - psrad m4, 14 - psrad m5, 14 - packssdw m7, m4 - packssdw m9, m5 - - punpcklwd m4, m10, m0 - punpckhwd m10, m0 - pmaddwd m5, m4, [GLOBAL(pw_9102_13623)] - pmaddwd m4, [GLOBAL(pw_13623_m9102)] - pmaddwd m0, m10, [GLOBAL(pw_9102_13623)] - pmaddwd m10, [GLOBAL(pw_13623_m9102)] - paddd m5, m8 - paddd m4, m8 - paddd m0, m8 - paddd m10, m8 - psrad m5, 14 - psrad m4, 14 - psrad m0, 14 - psrad m10, 14 - packssdw m5, m0 - packssdw m4, m10 - - ; transpose - ; stage 1 - punpcklwd m0, m2, m7 - punpcklwd m10, m1, m4 - punpckhwd m2, m7 - punpckhwd m1, m4 - punpcklwd m7, m6, m5 - punpcklwd m4, m3, m9 - punpckhwd m6, m5 - punpckhwd m3, m9 - - ; stage 2 - punpckldq m5, m0, m10 - punpckldq m9, m2, m1 - punpckhdq m0, m10 - punpckhdq m2, m1 - punpckldq m10, m7, m4 - punpckldq m1, m6, m3 - punpckhdq m7, m4 - punpckhdq m6, m3 - - ; stage 3 - punpcklqdq m4, m5, m10 - punpckhqdq m5, m10 - punpcklqdq m3, m0, m7 - punpckhqdq m0, m7 - punpcklqdq m10, m9, m1 - punpckhqdq m9, m1 - punpcklqdq m7, m2, m6 - punpckhqdq m2, m6 - - psraw m1, m4, 15 - psraw m6, m5, 15 - psraw m8, m3, 15 - psraw m11, m0, 15 - - psubw m4, m1 - psubw m5, m6 - psubw m3, m8 - psubw m0, m11 - - psraw m4, 1 - psraw m5, 1 - psraw m3, 1 - psraw m0, 1 - - psraw m1, m10, 15 - psraw m6, m9, 15 - psraw m8, m7, 15 - psraw m11, m2, 15 - - psubw m10, m1 - psubw m9, m6 - psubw m7, m8 - psubw m2, m11 - - psraw m10, 1 - psraw m9, 1 - psraw m7, 1 - psraw m2, 1 - - mova [outputq + 0], m4 - mova [outputq + 16], m5 - mova [outputq + 32], m3 - mova [outputq + 48], m0 - mova [outputq + 64], m10 - mova [outputq + 80], m9 - mova [outputq + 96], m7 - mova [outputq + 112], m2 - - RET -%endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_convolve_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_convolve_avx2.c deleted file mode 100644 index 01a52ec8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_convolve_avx2.c +++ /dev/null @@ -1,1495 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/x86/convolve.h" -#include "vpx_dsp/x86/convolve_avx2.h" - -// ----------------------------------------------------------------------------- -// Copy and average - -void vpx_highbd_convolve_copy_avx2(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd) { - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - (void)bd; - - assert(w % 4 == 0); - if (w > 32) { // w = 64 - do { - const __m256i p0 = _mm256_loadu_si256((const __m256i *)src); - const __m256i p1 = _mm256_loadu_si256((const __m256i *)(src + 16)); - const __m256i p2 = _mm256_loadu_si256((const __m256i *)(src + 32)); - const __m256i p3 = _mm256_loadu_si256((const __m256i *)(src + 48)); - src += src_stride; - _mm256_storeu_si256((__m256i *)dst, p0); - _mm256_storeu_si256((__m256i *)(dst + 16), p1); - _mm256_storeu_si256((__m256i *)(dst + 32), p2); - _mm256_storeu_si256((__m256i *)(dst + 48), p3); - dst += dst_stride; - h--; - } while (h > 0); - } else if (w > 16) { // w = 32 - do { - const __m256i p0 = _mm256_loadu_si256((const __m256i *)src); - const __m256i p1 = _mm256_loadu_si256((const __m256i *)(src + 16)); - src += src_stride; - _mm256_storeu_si256((__m256i *)dst, p0); - _mm256_storeu_si256((__m256i *)(dst + 16), p1); - dst += dst_stride; - h--; - } while (h > 0); - } else if (w > 8) { // w = 16 - __m256i p0, p1; - do { - p0 = _mm256_loadu_si256((const __m256i *)src); - src += src_stride; - p1 = _mm256_loadu_si256((const __m256i *)src); - src += src_stride; - - _mm256_storeu_si256((__m256i *)dst, p0); - dst += dst_stride; - _mm256_storeu_si256((__m256i *)dst, p1); - dst += dst_stride; - h -= 2; - } while (h > 0); - } else if (w > 4) { // w = 8 - __m128i p0, p1; - do { - p0 = _mm_loadu_si128((const __m128i *)src); - src += src_stride; - p1 = _mm_loadu_si128((const __m128i *)src); - src += src_stride; - - _mm_storeu_si128((__m128i *)dst, p0); - dst += dst_stride; - _mm_storeu_si128((__m128i *)dst, p1); - dst += dst_stride; - h -= 2; - } while (h > 0); - } else { // w = 4 - __m128i p0, p1; - do { - p0 = _mm_loadl_epi64((const __m128i *)src); - src += src_stride; - p1 = _mm_loadl_epi64((const __m128i *)src); - src += src_stride; - - _mm_storel_epi64((__m128i *)dst, p0); - dst += dst_stride; - _mm_storel_epi64((__m128i *)dst, p1); - dst += dst_stride; - h -= 2; - } while (h > 0); - } -} - -void vpx_highbd_convolve_avg_avx2(const uint16_t *src, ptrdiff_t src_stride, - uint16_t *dst, ptrdiff_t dst_stride, - const InterpKernel *filter, int x0_q4, - int x_step_q4, int y0_q4, int y_step_q4, - int w, int h, int bd) { - (void)filter; - (void)x0_q4; - (void)x_step_q4; - (void)y0_q4; - (void)y_step_q4; - (void)bd; - - assert(w % 4 == 0); - if (w > 32) { // w = 64 - __m256i p0, p1, p2, p3, u0, u1, u2, u3; - do { - p0 = _mm256_loadu_si256((const __m256i *)src); - p1 = _mm256_loadu_si256((const __m256i *)(src + 16)); - p2 = _mm256_loadu_si256((const __m256i *)(src + 32)); - p3 = _mm256_loadu_si256((const __m256i *)(src + 48)); - src += src_stride; - u0 = _mm256_loadu_si256((const __m256i *)dst); - u1 = _mm256_loadu_si256((const __m256i *)(dst + 16)); - u2 = _mm256_loadu_si256((const __m256i *)(dst + 32)); - u3 = _mm256_loadu_si256((const __m256i *)(dst + 48)); - _mm256_storeu_si256((__m256i *)dst, _mm256_avg_epu16(p0, u0)); - _mm256_storeu_si256((__m256i *)(dst + 16), _mm256_avg_epu16(p1, u1)); - _mm256_storeu_si256((__m256i *)(dst + 32), _mm256_avg_epu16(p2, u2)); - _mm256_storeu_si256((__m256i *)(dst + 48), _mm256_avg_epu16(p3, u3)); - dst += dst_stride; - h--; - } while (h > 0); - } else if (w > 16) { // w = 32 - __m256i p0, p1, u0, u1; - do { - p0 = _mm256_loadu_si256((const __m256i *)src); - p1 = _mm256_loadu_si256((const __m256i *)(src + 16)); - src += src_stride; - u0 = _mm256_loadu_si256((const __m256i *)dst); - u1 = _mm256_loadu_si256((const __m256i *)(dst + 16)); - _mm256_storeu_si256((__m256i *)dst, _mm256_avg_epu16(p0, u0)); - _mm256_storeu_si256((__m256i *)(dst + 16), _mm256_avg_epu16(p1, u1)); - dst += dst_stride; - h--; - } while (h > 0); - } else if (w > 8) { // w = 16 - __m256i p0, p1, u0, u1; - do { - p0 = _mm256_loadu_si256((const __m256i *)src); - p1 = _mm256_loadu_si256((const __m256i *)(src + src_stride)); - src += src_stride << 1; - u0 = _mm256_loadu_si256((const __m256i *)dst); - u1 = _mm256_loadu_si256((const __m256i *)(dst + dst_stride)); - - _mm256_storeu_si256((__m256i *)dst, _mm256_avg_epu16(p0, u0)); - _mm256_storeu_si256((__m256i *)(dst + dst_stride), - _mm256_avg_epu16(p1, u1)); - dst += dst_stride << 1; - h -= 2; - } while (h > 0); - } else if (w > 4) { // w = 8 - __m128i p0, p1, u0, u1; - do { - p0 = _mm_loadu_si128((const __m128i *)src); - p1 = _mm_loadu_si128((const __m128i *)(src + src_stride)); - src += src_stride << 1; - u0 = _mm_loadu_si128((const __m128i *)dst); - u1 = _mm_loadu_si128((const __m128i *)(dst + dst_stride)); - - _mm_storeu_si128((__m128i *)dst, _mm_avg_epu16(p0, u0)); - _mm_storeu_si128((__m128i *)(dst + dst_stride), _mm_avg_epu16(p1, u1)); - dst += dst_stride << 1; - h -= 2; - } while (h > 0); - } else { // w = 4 - __m128i p0, p1, u0, u1; - do { - p0 = _mm_loadl_epi64((const __m128i *)src); - p1 = _mm_loadl_epi64((const __m128i *)(src + src_stride)); - src += src_stride << 1; - u0 = _mm_loadl_epi64((const __m128i *)dst); - u1 = _mm_loadl_epi64((const __m128i *)(dst + dst_stride)); - - _mm_storel_epi64((__m128i *)dst, _mm_avg_epu16(u0, p0)); - _mm_storel_epi64((__m128i *)(dst + dst_stride), _mm_avg_epu16(u1, p1)); - dst += dst_stride << 1; - h -= 2; - } while (h > 0); - } -} - -// ----------------------------------------------------------------------------- -// Horizontal and vertical filtering - -static const uint8_t signal_pattern_0[32] = { 0, 1, 2, 3, 2, 3, 4, 5, 4, 5, 6, - 7, 6, 7, 8, 9, 0, 1, 2, 3, 2, 3, - 4, 5, 4, 5, 6, 7, 6, 7, 8, 9 }; - -static const uint8_t signal_pattern_1[32] = { 4, 5, 6, 7, 6, 7, 8, 9, - 8, 9, 10, 11, 10, 11, 12, 13, - 4, 5, 6, 7, 6, 7, 8, 9, - 8, 9, 10, 11, 10, 11, 12, 13 }; - -static const uint8_t signal_pattern_2[32] = { 6, 7, 8, 9, 8, 9, 10, 11, - 10, 11, 12, 13, 12, 13, 14, 15, - 6, 7, 8, 9, 8, 9, 10, 11, - 10, 11, 12, 13, 12, 13, 14, 15 }; - -static const uint32_t signal_index[8] = { 2, 3, 4, 5, 2, 3, 4, 5 }; - -#define CONV8_ROUNDING_BITS (7) -#define CONV8_ROUNDING_NUM (1 << (CONV8_ROUNDING_BITS - 1)) - -// ----------------------------------------------------------------------------- -// Horizontal Filtering - -static INLINE void pack_pixels(const __m256i *s, __m256i *p /*p[4]*/) { - const __m256i idx = _mm256_loadu_si256((const __m256i *)signal_index); - const __m256i sf0 = _mm256_loadu_si256((const __m256i *)signal_pattern_0); - const __m256i sf1 = _mm256_loadu_si256((const __m256i *)signal_pattern_1); - const __m256i c = _mm256_permutevar8x32_epi32(*s, idx); - - p[0] = _mm256_shuffle_epi8(*s, sf0); // x0x6 - p[1] = _mm256_shuffle_epi8(*s, sf1); // x1x7 - p[2] = _mm256_shuffle_epi8(c, sf0); // x2x4 - p[3] = _mm256_shuffle_epi8(c, sf1); // x3x5 -} - -// Note: -// Shared by 8x2 and 16x1 block -static INLINE void pack_16_pixels(const __m256i *s0, const __m256i *s1, - __m256i *x /*x[8]*/) { - __m256i pp[8]; - pack_pixels(s0, pp); - pack_pixels(s1, &pp[4]); - x[0] = _mm256_permute2x128_si256(pp[0], pp[4], 0x20); - x[1] = _mm256_permute2x128_si256(pp[1], pp[5], 0x20); - x[2] = _mm256_permute2x128_si256(pp[2], pp[6], 0x20); - x[3] = _mm256_permute2x128_si256(pp[3], pp[7], 0x20); - x[4] = x[2]; - x[5] = x[3]; - x[6] = _mm256_permute2x128_si256(pp[0], pp[4], 0x31); - x[7] = _mm256_permute2x128_si256(pp[1], pp[5], 0x31); -} - -static INLINE void pack_8x1_pixels(const uint16_t *src, __m256i *x) { - __m256i pp[8]; - __m256i s0; - s0 = _mm256_loadu_si256((const __m256i *)src); - pack_pixels(&s0, pp); - x[0] = _mm256_permute2x128_si256(pp[0], pp[2], 0x30); - x[1] = _mm256_permute2x128_si256(pp[1], pp[3], 0x30); - x[2] = _mm256_permute2x128_si256(pp[2], pp[0], 0x30); - x[3] = _mm256_permute2x128_si256(pp[3], pp[1], 0x30); -} - -static INLINE void pack_8x2_pixels(const uint16_t *src, ptrdiff_t stride, - __m256i *x) { - __m256i s0, s1; - s0 = _mm256_loadu_si256((const __m256i *)src); - s1 = _mm256_loadu_si256((const __m256i *)(src + stride)); - pack_16_pixels(&s0, &s1, x); -} - -static INLINE void pack_16x1_pixels(const uint16_t *src, __m256i *x) { - __m256i s0, s1; - s0 = _mm256_loadu_si256((const __m256i *)src); - s1 = _mm256_loadu_si256((const __m256i *)(src + 8)); - pack_16_pixels(&s0, &s1, x); -} - -// Note: -// Shared by horizontal and vertical filtering -static INLINE void pack_filters(const int16_t *filter, __m256i *f /*f[4]*/) { - const __m128i h = _mm_loadu_si128((const __m128i *)filter); - const __m256i hh = _mm256_insertf128_si256(_mm256_castsi128_si256(h), h, 1); - const __m256i p0 = _mm256_set1_epi32(0x03020100); - const __m256i p1 = _mm256_set1_epi32(0x07060504); - const __m256i p2 = _mm256_set1_epi32(0x0b0a0908); - const __m256i p3 = _mm256_set1_epi32(0x0f0e0d0c); - f[0] = _mm256_shuffle_epi8(hh, p0); - f[1] = _mm256_shuffle_epi8(hh, p1); - f[2] = _mm256_shuffle_epi8(hh, p2); - f[3] = _mm256_shuffle_epi8(hh, p3); -} - -static INLINE void filter_8x1_pixels(const __m256i *sig /*sig[4]*/, - const __m256i *fil /*fil[4]*/, - __m256i *y) { - __m256i a, a0, a1; - - a0 = _mm256_madd_epi16(fil[0], sig[0]); - a1 = _mm256_madd_epi16(fil[3], sig[3]); - a = _mm256_add_epi32(a0, a1); - - a0 = _mm256_madd_epi16(fil[1], sig[1]); - a1 = _mm256_madd_epi16(fil[2], sig[2]); - - { - const __m256i min = _mm256_min_epi32(a0, a1); - a = _mm256_add_epi32(a, min); - } - { - const __m256i max = _mm256_max_epi32(a0, a1); - a = _mm256_add_epi32(a, max); - } - { - const __m256i rounding = _mm256_set1_epi32(1 << (CONV8_ROUNDING_BITS - 1)); - a = _mm256_add_epi32(a, rounding); - *y = _mm256_srai_epi32(a, CONV8_ROUNDING_BITS); - } -} - -static INLINE void store_8x1_pixels(const __m256i *y, const __m256i *mask, - uint16_t *dst) { - const __m128i a0 = _mm256_castsi256_si128(*y); - const __m128i a1 = _mm256_extractf128_si256(*y, 1); - __m128i res = _mm_packus_epi32(a0, a1); - res = _mm_min_epi16(res, _mm256_castsi256_si128(*mask)); - _mm_storeu_si128((__m128i *)dst, res); -} - -static INLINE void store_8x2_pixels(const __m256i *y0, const __m256i *y1, - const __m256i *mask, uint16_t *dst, - ptrdiff_t pitch) { - __m256i a = _mm256_packus_epi32(*y0, *y1); - a = _mm256_min_epi16(a, *mask); - _mm_storeu_si128((__m128i *)dst, _mm256_castsi256_si128(a)); - _mm_storeu_si128((__m128i *)(dst + pitch), _mm256_extractf128_si256(a, 1)); -} - -static INLINE void store_16x1_pixels(const __m256i *y0, const __m256i *y1, - const __m256i *mask, uint16_t *dst) { - __m256i a = _mm256_packus_epi32(*y0, *y1); - a = _mm256_min_epi16(a, *mask); - _mm256_storeu_si256((__m256i *)dst, a); -} - -static void vpx_highbd_filter_block1d8_h8_avx2( - const uint16_t *src_ptr, ptrdiff_t src_pitch, uint16_t *dst_ptr, - ptrdiff_t dst_pitch, uint32_t height, const int16_t *filter, int bd) { - __m256i signal[8], res0, res1; - const __m256i max = _mm256_set1_epi16((1 << bd) - 1); - - __m256i ff[4]; - pack_filters(filter, ff); - - src_ptr -= 3; - do { - pack_8x2_pixels(src_ptr, src_pitch, signal); - filter_8x1_pixels(signal, ff, &res0); - filter_8x1_pixels(&signal[4], ff, &res1); - store_8x2_pixels(&res0, &res1, &max, dst_ptr, dst_pitch); - height -= 2; - src_ptr += src_pitch << 1; - dst_ptr += dst_pitch << 1; - } while (height > 1); - - if (height > 0) { - pack_8x1_pixels(src_ptr, signal); - filter_8x1_pixels(signal, ff, &res0); - store_8x1_pixels(&res0, &max, dst_ptr); - } -} - -static void vpx_highbd_filter_block1d16_h8_avx2( - const uint16_t *src_ptr, ptrdiff_t src_pitch, uint16_t *dst_ptr, - ptrdiff_t dst_pitch, uint32_t height, const int16_t *filter, int bd) { - __m256i signal[8], res0, res1; - const __m256i max = _mm256_set1_epi16((1 << bd) - 1); - - __m256i ff[4]; - pack_filters(filter, ff); - - src_ptr -= 3; - do { - pack_16x1_pixels(src_ptr, signal); - filter_8x1_pixels(signal, ff, &res0); - filter_8x1_pixels(&signal[4], ff, &res1); - store_16x1_pixels(&res0, &res1, &max, dst_ptr); - height -= 1; - src_ptr += src_pitch; - dst_ptr += dst_pitch; - } while (height > 0); -} - -// ----------------------------------------------------------------------------- -// 2-tap horizontal filtering - -static INLINE void pack_2t_filter(const int16_t *filter, __m256i *f) { - const __m128i h = _mm_loadu_si128((const __m128i *)filter); - const __m256i hh = _mm256_insertf128_si256(_mm256_castsi128_si256(h), h, 1); - const __m256i p = _mm256_set1_epi32(0x09080706); - f[0] = _mm256_shuffle_epi8(hh, p); -} - -// can be used by pack_8x2_2t_pixels() and pack_16x1_2t_pixels() -// the difference is s0/s1 specifies first and second rows or, -// first 16 samples and 8-sample shifted 16 samples -static INLINE void pack_16_2t_pixels(const __m256i *s0, const __m256i *s1, - __m256i *sig) { - const __m256i idx = _mm256_loadu_si256((const __m256i *)signal_index); - const __m256i sf2 = _mm256_loadu_si256((const __m256i *)signal_pattern_2); - __m256i x0 = _mm256_shuffle_epi8(*s0, sf2); - __m256i x1 = _mm256_shuffle_epi8(*s1, sf2); - __m256i r0 = _mm256_permutevar8x32_epi32(*s0, idx); - __m256i r1 = _mm256_permutevar8x32_epi32(*s1, idx); - r0 = _mm256_shuffle_epi8(r0, sf2); - r1 = _mm256_shuffle_epi8(r1, sf2); - sig[0] = _mm256_permute2x128_si256(x0, x1, 0x20); - sig[1] = _mm256_permute2x128_si256(r0, r1, 0x20); -} - -static INLINE void pack_8x2_2t_pixels(const uint16_t *src, - const ptrdiff_t pitch, __m256i *sig) { - const __m256i r0 = _mm256_loadu_si256((const __m256i *)src); - const __m256i r1 = _mm256_loadu_si256((const __m256i *)(src + pitch)); - pack_16_2t_pixels(&r0, &r1, sig); -} - -static INLINE void pack_16x1_2t_pixels(const uint16_t *src, - __m256i *sig /*sig[2]*/) { - const __m256i r0 = _mm256_loadu_si256((const __m256i *)src); - const __m256i r1 = _mm256_loadu_si256((const __m256i *)(src + 8)); - pack_16_2t_pixels(&r0, &r1, sig); -} - -static INLINE void pack_8x1_2t_pixels(const uint16_t *src, - __m256i *sig /*sig[2]*/) { - const __m256i idx = _mm256_loadu_si256((const __m256i *)signal_index); - const __m256i sf2 = _mm256_loadu_si256((const __m256i *)signal_pattern_2); - __m256i r0 = _mm256_loadu_si256((const __m256i *)src); - __m256i x0 = _mm256_shuffle_epi8(r0, sf2); - r0 = _mm256_permutevar8x32_epi32(r0, idx); - r0 = _mm256_shuffle_epi8(r0, sf2); - sig[0] = _mm256_permute2x128_si256(x0, r0, 0x20); -} - -// can be used by filter_8x2_2t_pixels() and filter_16x1_2t_pixels() -static INLINE void filter_16_2t_pixels(const __m256i *sig, const __m256i *f, - __m256i *y0, __m256i *y1) { - const __m256i rounding = _mm256_set1_epi32(1 << (CONV8_ROUNDING_BITS - 1)); - __m256i x0 = _mm256_madd_epi16(sig[0], *f); - __m256i x1 = _mm256_madd_epi16(sig[1], *f); - x0 = _mm256_add_epi32(x0, rounding); - x1 = _mm256_add_epi32(x1, rounding); - *y0 = _mm256_srai_epi32(x0, CONV8_ROUNDING_BITS); - *y1 = _mm256_srai_epi32(x1, CONV8_ROUNDING_BITS); -} - -static INLINE void filter_8x1_2t_pixels(const __m256i *sig, const __m256i *f, - __m256i *y0) { - const __m256i rounding = _mm256_set1_epi32(1 << (CONV8_ROUNDING_BITS - 1)); - __m256i x0 = _mm256_madd_epi16(sig[0], *f); - x0 = _mm256_add_epi32(x0, rounding); - *y0 = _mm256_srai_epi32(x0, CONV8_ROUNDING_BITS); -} - -static void vpx_highbd_filter_block1d8_h2_avx2( - const uint16_t *src_ptr, ptrdiff_t src_pitch, uint16_t *dst_ptr, - ptrdiff_t dst_pitch, uint32_t height, const int16_t *filter, int bd) { - __m256i signal[2], res0, res1; - const __m256i max = _mm256_set1_epi16((1 << bd) - 1); - - __m256i ff; - pack_2t_filter(filter, &ff); - - src_ptr -= 3; - do { - pack_8x2_2t_pixels(src_ptr, src_pitch, signal); - filter_16_2t_pixels(signal, &ff, &res0, &res1); - store_8x2_pixels(&res0, &res1, &max, dst_ptr, dst_pitch); - height -= 2; - src_ptr += src_pitch << 1; - dst_ptr += dst_pitch << 1; - } while (height > 1); - - if (height > 0) { - pack_8x1_2t_pixels(src_ptr, signal); - filter_8x1_2t_pixels(signal, &ff, &res0); - store_8x1_pixels(&res0, &max, dst_ptr); - } -} - -static void vpx_highbd_filter_block1d16_h2_avx2( - const uint16_t *src_ptr, ptrdiff_t src_pitch, uint16_t *dst_ptr, - ptrdiff_t dst_pitch, uint32_t height, const int16_t *filter, int bd) { - __m256i signal[2], res0, res1; - const __m256i max = _mm256_set1_epi16((1 << bd) - 1); - - __m256i ff; - pack_2t_filter(filter, &ff); - - src_ptr -= 3; - do { - pack_16x1_2t_pixels(src_ptr, signal); - filter_16_2t_pixels(signal, &ff, &res0, &res1); - store_16x1_pixels(&res0, &res1, &max, dst_ptr); - height -= 1; - src_ptr += src_pitch; - dst_ptr += dst_pitch; - } while (height > 0); -} - -// ----------------------------------------------------------------------------- -// Vertical Filtering - -static void pack_8x9_init(const uint16_t *src, ptrdiff_t pitch, __m256i *sig) { - __m256i s0 = _mm256_castsi128_si256(_mm_loadu_si128((const __m128i *)src)); - __m256i s1 = - _mm256_castsi128_si256(_mm_loadu_si128((const __m128i *)(src + pitch))); - __m256i s2 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src + 2 * pitch))); - __m256i s3 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src + 3 * pitch))); - __m256i s4 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src + 4 * pitch))); - __m256i s5 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src + 5 * pitch))); - __m256i s6 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src + 6 * pitch))); - - s0 = _mm256_inserti128_si256(s0, _mm256_castsi256_si128(s1), 1); - s1 = _mm256_inserti128_si256(s1, _mm256_castsi256_si128(s2), 1); - s2 = _mm256_inserti128_si256(s2, _mm256_castsi256_si128(s3), 1); - s3 = _mm256_inserti128_si256(s3, _mm256_castsi256_si128(s4), 1); - s4 = _mm256_inserti128_si256(s4, _mm256_castsi256_si128(s5), 1); - s5 = _mm256_inserti128_si256(s5, _mm256_castsi256_si128(s6), 1); - - sig[0] = _mm256_unpacklo_epi16(s0, s1); - sig[4] = _mm256_unpackhi_epi16(s0, s1); - sig[1] = _mm256_unpacklo_epi16(s2, s3); - sig[5] = _mm256_unpackhi_epi16(s2, s3); - sig[2] = _mm256_unpacklo_epi16(s4, s5); - sig[6] = _mm256_unpackhi_epi16(s4, s5); - sig[8] = s6; -} - -static INLINE void pack_8x9_pixels(const uint16_t *src, ptrdiff_t pitch, - __m256i *sig) { - // base + 7th row - __m256i s0 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src + 7 * pitch))); - // base + 8th row - __m256i s1 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src + 8 * pitch))); - __m256i s2 = _mm256_inserti128_si256(sig[8], _mm256_castsi256_si128(s0), 1); - __m256i s3 = _mm256_inserti128_si256(s0, _mm256_castsi256_si128(s1), 1); - sig[3] = _mm256_unpacklo_epi16(s2, s3); - sig[7] = _mm256_unpackhi_epi16(s2, s3); - sig[8] = s1; -} - -static INLINE void filter_8x9_pixels(const __m256i *sig, const __m256i *f, - __m256i *y0, __m256i *y1) { - filter_8x1_pixels(sig, f, y0); - filter_8x1_pixels(&sig[4], f, y1); -} - -static INLINE void update_pixels(__m256i *sig) { - int i; - for (i = 0; i < 3; ++i) { - sig[i] = sig[i + 1]; - sig[i + 4] = sig[i + 5]; - } -} - -static void vpx_highbd_filter_block1d8_v8_avx2( - const uint16_t *src_ptr, ptrdiff_t src_pitch, uint16_t *dst_ptr, - ptrdiff_t dst_pitch, uint32_t height, const int16_t *filter, int bd) { - __m256i signal[9], res0, res1; - const __m256i max = _mm256_set1_epi16((1 << bd) - 1); - - __m256i ff[4]; - pack_filters(filter, ff); - - pack_8x9_init(src_ptr, src_pitch, signal); - - do { - pack_8x9_pixels(src_ptr, src_pitch, signal); - - filter_8x9_pixels(signal, ff, &res0, &res1); - store_8x2_pixels(&res0, &res1, &max, dst_ptr, dst_pitch); - update_pixels(signal); - - src_ptr += src_pitch << 1; - dst_ptr += dst_pitch << 1; - height -= 2; - } while (height > 0); -} - -static void pack_16x9_init(const uint16_t *src, ptrdiff_t pitch, __m256i *sig) { - __m256i u0, u1, u2, u3; - // load 0-6 rows - const __m256i s0 = _mm256_loadu_si256((const __m256i *)src); - const __m256i s1 = _mm256_loadu_si256((const __m256i *)(src + pitch)); - const __m256i s2 = _mm256_loadu_si256((const __m256i *)(src + 2 * pitch)); - const __m256i s3 = _mm256_loadu_si256((const __m256i *)(src + 3 * pitch)); - const __m256i s4 = _mm256_loadu_si256((const __m256i *)(src + 4 * pitch)); - const __m256i s5 = _mm256_loadu_si256((const __m256i *)(src + 5 * pitch)); - const __m256i s6 = _mm256_loadu_si256((const __m256i *)(src + 6 * pitch)); - - u0 = _mm256_permute2x128_si256(s0, s1, 0x20); // 0, 1 low - u1 = _mm256_permute2x128_si256(s0, s1, 0x31); // 0, 1 high - - u2 = _mm256_permute2x128_si256(s1, s2, 0x20); // 1, 2 low - u3 = _mm256_permute2x128_si256(s1, s2, 0x31); // 1, 2 high - - sig[0] = _mm256_unpacklo_epi16(u0, u2); - sig[4] = _mm256_unpackhi_epi16(u0, u2); - - sig[8] = _mm256_unpacklo_epi16(u1, u3); - sig[12] = _mm256_unpackhi_epi16(u1, u3); - - u0 = _mm256_permute2x128_si256(s2, s3, 0x20); - u1 = _mm256_permute2x128_si256(s2, s3, 0x31); - - u2 = _mm256_permute2x128_si256(s3, s4, 0x20); - u3 = _mm256_permute2x128_si256(s3, s4, 0x31); - - sig[1] = _mm256_unpacklo_epi16(u0, u2); - sig[5] = _mm256_unpackhi_epi16(u0, u2); - - sig[9] = _mm256_unpacklo_epi16(u1, u3); - sig[13] = _mm256_unpackhi_epi16(u1, u3); - - u0 = _mm256_permute2x128_si256(s4, s5, 0x20); - u1 = _mm256_permute2x128_si256(s4, s5, 0x31); - - u2 = _mm256_permute2x128_si256(s5, s6, 0x20); - u3 = _mm256_permute2x128_si256(s5, s6, 0x31); - - sig[2] = _mm256_unpacklo_epi16(u0, u2); - sig[6] = _mm256_unpackhi_epi16(u0, u2); - - sig[10] = _mm256_unpacklo_epi16(u1, u3); - sig[14] = _mm256_unpackhi_epi16(u1, u3); - - sig[16] = s6; -} - -static void pack_16x9_pixels(const uint16_t *src, ptrdiff_t pitch, - __m256i *sig) { - // base + 7th row - const __m256i s7 = _mm256_loadu_si256((const __m256i *)(src + 7 * pitch)); - // base + 8th row - const __m256i s8 = _mm256_loadu_si256((const __m256i *)(src + 8 * pitch)); - - __m256i u0, u1, u2, u3; - u0 = _mm256_permute2x128_si256(sig[16], s7, 0x20); - u1 = _mm256_permute2x128_si256(sig[16], s7, 0x31); - - u2 = _mm256_permute2x128_si256(s7, s8, 0x20); - u3 = _mm256_permute2x128_si256(s7, s8, 0x31); - - sig[3] = _mm256_unpacklo_epi16(u0, u2); - sig[7] = _mm256_unpackhi_epi16(u0, u2); - - sig[11] = _mm256_unpacklo_epi16(u1, u3); - sig[15] = _mm256_unpackhi_epi16(u1, u3); - - sig[16] = s8; -} - -static INLINE void filter_16x9_pixels(const __m256i *sig, const __m256i *f, - __m256i *y0, __m256i *y1) { - __m256i res[4]; - int i; - for (i = 0; i < 4; ++i) { - filter_8x1_pixels(&sig[i << 2], f, &res[i]); - } - - { - const __m256i l0l1 = _mm256_packus_epi32(res[0], res[1]); - const __m256i h0h1 = _mm256_packus_epi32(res[2], res[3]); - *y0 = _mm256_permute2x128_si256(l0l1, h0h1, 0x20); - *y1 = _mm256_permute2x128_si256(l0l1, h0h1, 0x31); - } -} - -static INLINE void store_16x2_pixels(const __m256i *y0, const __m256i *y1, - const __m256i *mask, uint16_t *dst, - ptrdiff_t pitch) { - __m256i p = _mm256_min_epi16(*y0, *mask); - _mm256_storeu_si256((__m256i *)dst, p); - p = _mm256_min_epi16(*y1, *mask); - _mm256_storeu_si256((__m256i *)(dst + pitch), p); -} - -static void update_16x9_pixels(__m256i *sig) { - update_pixels(&sig[0]); - update_pixels(&sig[8]); -} - -static void vpx_highbd_filter_block1d16_v8_avx2( - const uint16_t *src_ptr, ptrdiff_t src_pitch, uint16_t *dst_ptr, - ptrdiff_t dst_pitch, uint32_t height, const int16_t *filter, int bd) { - __m256i signal[17], res0, res1; - const __m256i max = _mm256_set1_epi16((1 << bd) - 1); - - __m256i ff[4]; - pack_filters(filter, ff); - - pack_16x9_init(src_ptr, src_pitch, signal); - - do { - pack_16x9_pixels(src_ptr, src_pitch, signal); - filter_16x9_pixels(signal, ff, &res0, &res1); - store_16x2_pixels(&res0, &res1, &max, dst_ptr, dst_pitch); - update_16x9_pixels(signal); - - src_ptr += src_pitch << 1; - dst_ptr += dst_pitch << 1; - height -= 2; - } while (height > 0); -} - -// ----------------------------------------------------------------------------- -// 2-tap vertical filtering - -static void pack_16x2_init(const uint16_t *src, __m256i *sig) { - sig[2] = _mm256_loadu_si256((const __m256i *)src); -} - -static INLINE void pack_16x2_2t_pixels(const uint16_t *src, ptrdiff_t pitch, - __m256i *sig) { - // load the next row - const __m256i u = _mm256_loadu_si256((const __m256i *)(src + pitch)); - sig[0] = _mm256_unpacklo_epi16(sig[2], u); - sig[1] = _mm256_unpackhi_epi16(sig[2], u); - sig[2] = u; -} - -static INLINE void filter_16x2_2t_pixels(const __m256i *sig, const __m256i *f, - __m256i *y0, __m256i *y1) { - filter_16_2t_pixels(sig, f, y0, y1); -} - -static void vpx_highbd_filter_block1d16_v2_avx2( - const uint16_t *src_ptr, ptrdiff_t src_pitch, uint16_t *dst_ptr, - ptrdiff_t dst_pitch, uint32_t height, const int16_t *filter, int bd) { - __m256i signal[3], res0, res1; - const __m256i max = _mm256_set1_epi16((1 << bd) - 1); - __m256i ff; - - pack_2t_filter(filter, &ff); - pack_16x2_init(src_ptr, signal); - - do { - pack_16x2_2t_pixels(src_ptr, src_pitch, signal); - filter_16x2_2t_pixels(signal, &ff, &res0, &res1); - store_16x1_pixels(&res0, &res1, &max, dst_ptr); - - src_ptr += src_pitch; - dst_ptr += dst_pitch; - height -= 1; - } while (height > 0); -} - -static INLINE void pack_8x1_2t_filter(const int16_t *filter, __m128i *f) { - const __m128i h = _mm_loadu_si128((const __m128i *)filter); - const __m128i p = _mm_set1_epi32(0x09080706); - f[0] = _mm_shuffle_epi8(h, p); -} - -static void pack_8x2_init(const uint16_t *src, __m128i *sig) { - sig[2] = _mm_loadu_si128((const __m128i *)src); -} - -static INLINE void pack_8x2_2t_pixels_ver(const uint16_t *src, ptrdiff_t pitch, - __m128i *sig) { - // load the next row - const __m128i u = _mm_loadu_si128((const __m128i *)(src + pitch)); - sig[0] = _mm_unpacklo_epi16(sig[2], u); - sig[1] = _mm_unpackhi_epi16(sig[2], u); - sig[2] = u; -} - -static INLINE void filter_8_2t_pixels(const __m128i *sig, const __m128i *f, - __m128i *y0, __m128i *y1) { - const __m128i rounding = _mm_set1_epi32(1 << (CONV8_ROUNDING_BITS - 1)); - __m128i x0 = _mm_madd_epi16(sig[0], *f); - __m128i x1 = _mm_madd_epi16(sig[1], *f); - x0 = _mm_add_epi32(x0, rounding); - x1 = _mm_add_epi32(x1, rounding); - *y0 = _mm_srai_epi32(x0, CONV8_ROUNDING_BITS); - *y1 = _mm_srai_epi32(x1, CONV8_ROUNDING_BITS); -} - -static INLINE void store_8x1_2t_pixels_ver(const __m128i *y0, const __m128i *y1, - const __m128i *mask, uint16_t *dst) { - __m128i res = _mm_packus_epi32(*y0, *y1); - res = _mm_min_epi16(res, *mask); - _mm_storeu_si128((__m128i *)dst, res); -} - -static void vpx_highbd_filter_block1d8_v2_avx2( - const uint16_t *src_ptr, ptrdiff_t src_pitch, uint16_t *dst_ptr, - ptrdiff_t dst_pitch, uint32_t height, const int16_t *filter, int bd) { - __m128i signal[3], res0, res1; - const __m128i max = _mm_set1_epi16((1 << bd) - 1); - __m128i ff; - - pack_8x1_2t_filter(filter, &ff); - pack_8x2_init(src_ptr, signal); - - do { - pack_8x2_2t_pixels_ver(src_ptr, src_pitch, signal); - filter_8_2t_pixels(signal, &ff, &res0, &res1); - store_8x1_2t_pixels_ver(&res0, &res1, &max, dst_ptr); - - src_ptr += src_pitch; - dst_ptr += dst_pitch; - height -= 1; - } while (height > 0); -} - -// Calculation with averaging the input pixels - -static INLINE void store_8x1_avg_pixels(const __m256i *y0, const __m256i *mask, - uint16_t *dst) { - const __m128i a0 = _mm256_castsi256_si128(*y0); - const __m128i a1 = _mm256_extractf128_si256(*y0, 1); - __m128i res = _mm_packus_epi32(a0, a1); - const __m128i pix = _mm_loadu_si128((const __m128i *)dst); - res = _mm_min_epi16(res, _mm256_castsi256_si128(*mask)); - res = _mm_avg_epu16(res, pix); - _mm_storeu_si128((__m128i *)dst, res); -} - -static INLINE void store_8x2_avg_pixels(const __m256i *y0, const __m256i *y1, - const __m256i *mask, uint16_t *dst, - ptrdiff_t pitch) { - __m256i a = _mm256_packus_epi32(*y0, *y1); - const __m128i pix0 = _mm_loadu_si128((const __m128i *)dst); - const __m128i pix1 = _mm_loadu_si128((const __m128i *)(dst + pitch)); - const __m256i pix = - _mm256_insertf128_si256(_mm256_castsi128_si256(pix0), pix1, 1); - a = _mm256_min_epi16(a, *mask); - a = _mm256_avg_epu16(a, pix); - _mm_storeu_si128((__m128i *)dst, _mm256_castsi256_si128(a)); - _mm_storeu_si128((__m128i *)(dst + pitch), _mm256_extractf128_si256(a, 1)); -} - -static INLINE void store_16x1_avg_pixels(const __m256i *y0, const __m256i *y1, - const __m256i *mask, uint16_t *dst) { - __m256i a = _mm256_packus_epi32(*y0, *y1); - const __m256i pix = _mm256_loadu_si256((const __m256i *)dst); - a = _mm256_min_epi16(a, *mask); - a = _mm256_avg_epu16(a, pix); - _mm256_storeu_si256((__m256i *)dst, a); -} - -static INLINE void store_16x2_avg_pixels(const __m256i *y0, const __m256i *y1, - const __m256i *mask, uint16_t *dst, - ptrdiff_t pitch) { - const __m256i pix0 = _mm256_loadu_si256((const __m256i *)dst); - const __m256i pix1 = _mm256_loadu_si256((const __m256i *)(dst + pitch)); - __m256i p = _mm256_min_epi16(*y0, *mask); - p = _mm256_avg_epu16(p, pix0); - _mm256_storeu_si256((__m256i *)dst, p); - - p = _mm256_min_epi16(*y1, *mask); - p = _mm256_avg_epu16(p, pix1); - _mm256_storeu_si256((__m256i *)(dst + pitch), p); -} - -static INLINE void store_8x1_2t_avg_pixels_ver(const __m128i *y0, - const __m128i *y1, - const __m128i *mask, - uint16_t *dst) { - __m128i res = _mm_packus_epi32(*y0, *y1); - const __m128i pix = _mm_loadu_si128((const __m128i *)dst); - res = _mm_min_epi16(res, *mask); - res = _mm_avg_epu16(res, pix); - _mm_storeu_si128((__m128i *)dst, res); -} - -static void vpx_highbd_filter_block1d8_h8_avg_avx2( - const uint16_t *src_ptr, ptrdiff_t src_pitch, uint16_t *dst_ptr, - ptrdiff_t dst_pitch, uint32_t height, const int16_t *filter, int bd) { - __m256i signal[8], res0, res1; - const __m256i max = _mm256_set1_epi16((1 << bd) - 1); - - __m256i ff[4]; - pack_filters(filter, ff); - - src_ptr -= 3; - do { - pack_8x2_pixels(src_ptr, src_pitch, signal); - filter_8x1_pixels(signal, ff, &res0); - filter_8x1_pixels(&signal[4], ff, &res1); - store_8x2_avg_pixels(&res0, &res1, &max, dst_ptr, dst_pitch); - height -= 2; - src_ptr += src_pitch << 1; - dst_ptr += dst_pitch << 1; - } while (height > 1); - - if (height > 0) { - pack_8x1_pixels(src_ptr, signal); - filter_8x1_pixels(signal, ff, &res0); - store_8x1_avg_pixels(&res0, &max, dst_ptr); - } -} - -static void vpx_highbd_filter_block1d16_h8_avg_avx2( - const uint16_t *src_ptr, ptrdiff_t src_pitch, uint16_t *dst_ptr, - ptrdiff_t dst_pitch, uint32_t height, const int16_t *filter, int bd) { - __m256i signal[8], res0, res1; - const __m256i max = _mm256_set1_epi16((1 << bd) - 1); - - __m256i ff[4]; - pack_filters(filter, ff); - - src_ptr -= 3; - do { - pack_16x1_pixels(src_ptr, signal); - filter_8x1_pixels(signal, ff, &res0); - filter_8x1_pixels(&signal[4], ff, &res1); - store_16x1_avg_pixels(&res0, &res1, &max, dst_ptr); - height -= 1; - src_ptr += src_pitch; - dst_ptr += dst_pitch; - } while (height > 0); -} - -static void vpx_highbd_filter_block1d4_h4_avx2( - const uint16_t *src_ptr, ptrdiff_t src_stride, uint16_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, const int16_t *kernel, int bd) { - // We extract the middle four elements of the kernel into two registers in - // the form - // ... k[3] k[2] k[3] k[2] - // ... k[5] k[4] k[5] k[4] - // Then we shuffle the source into - // ... s[1] s[0] s[0] s[-1] - // ... s[3] s[2] s[2] s[1] - // Calling multiply and add gives us half of the sum. Calling add on the two - // halves gives us the output. Since avx2 allows us to use 256-bit buffer, we - // can do this two rows at a time. - - __m256i src_reg, src_reg_shift_0, src_reg_shift_2; - __m256i res_reg; - __m256i idx_shift_0 = - _mm256_setr_epi8(0, 1, 2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 6, 7, 8, 9, 0, 1, 2, - 3, 2, 3, 4, 5, 4, 5, 6, 7, 6, 7, 8, 9); - __m256i idx_shift_2 = - _mm256_setr_epi8(4, 5, 6, 7, 6, 7, 8, 9, 8, 9, 10, 11, 10, 11, 12, 13, 4, - 5, 6, 7, 6, 7, 8, 9, 8, 9, 10, 11, 10, 11, 12, 13); - - __m128i kernel_reg_128; // Kernel - __m256i kernel_reg, kernel_reg_23, - kernel_reg_45; // Segments of the kernel used - const __m256i reg_round = - _mm256_set1_epi32(CONV8_ROUNDING_NUM); // Used for rounding - const __m256i reg_max = _mm256_set1_epi16((1 << bd) - 1); - const ptrdiff_t unrolled_src_stride = src_stride << 1; - const ptrdiff_t unrolled_dst_stride = dst_stride << 1; - int h; - - // Start one pixel before as we need tap/2 - 1 = 1 sample from the past - src_ptr -= 1; - - // Load Kernel - kernel_reg_128 = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm256_broadcastsi128_si256(kernel_reg_128); - kernel_reg_23 = _mm256_shuffle_epi32(kernel_reg, 0x55); - kernel_reg_45 = _mm256_shuffle_epi32(kernel_reg, 0xaa); - - for (h = height; h >= 2; h -= 2) { - // Load the source - src_reg = mm256_loadu2_si128(src_ptr, src_ptr + src_stride); - src_reg_shift_0 = _mm256_shuffle_epi8(src_reg, idx_shift_0); - src_reg_shift_2 = _mm256_shuffle_epi8(src_reg, idx_shift_2); - - // Get the output - res_reg = mm256_madd_add_epi32(&src_reg_shift_0, &src_reg_shift_2, - &kernel_reg_23, &kernel_reg_45); - - // Round the result - res_reg = mm256_round_epi32(&res_reg, ®_round, CONV8_ROUNDING_BITS); - - // Finally combine to get the final dst - res_reg = _mm256_packus_epi32(res_reg, res_reg); - res_reg = _mm256_min_epi16(res_reg, reg_max); - mm256_storeu2_epi64((__m128i *)dst_ptr, (__m128i *)(dst_ptr + dst_stride), - &res_reg); - - src_ptr += unrolled_src_stride; - dst_ptr += unrolled_dst_stride; - } - - // Repeat for the last row if needed - if (h > 0) { - // Load the source - src_reg = mm256_loadu2_si128(src_ptr, src_ptr + 4); - src_reg_shift_0 = _mm256_shuffle_epi8(src_reg, idx_shift_0); - src_reg_shift_2 = _mm256_shuffle_epi8(src_reg, idx_shift_2); - - // Get the output - res_reg = mm256_madd_add_epi32(&src_reg_shift_0, &src_reg_shift_2, - &kernel_reg_23, &kernel_reg_45); - - // Round the result - res_reg = mm256_round_epi32(&res_reg, ®_round, CONV8_ROUNDING_BITS); - - // Finally combine to get the final dst - res_reg = _mm256_packus_epi32(res_reg, res_reg); - res_reg = _mm256_min_epi16(res_reg, reg_max); - _mm_storel_epi64((__m128i *)dst_ptr, _mm256_castsi256_si128(res_reg)); - } -} - -static void vpx_highbd_filter_block1d8_h4_avx2( - const uint16_t *src_ptr, ptrdiff_t src_stride, uint16_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, const int16_t *kernel, int bd) { - // We will extract the middle four elements of the kernel into two registers - // in the form - // ... k[3] k[2] k[3] k[2] - // ... k[5] k[4] k[5] k[4] - // Then we shuffle the source into - // ... s[1] s[0] s[0] s[-1] - // ... s[3] s[2] s[2] s[1] - // Calling multiply and add gives us half of the sum of the first half. - // Calling add gives us first half of the output. Repat again to get the whole - // output. Since avx2 allows us to use 256-bit buffer, we can do this two rows - // at a time. - - __m256i src_reg, src_reg_shift_0, src_reg_shift_2; - __m256i res_reg, res_first, res_last; - __m256i idx_shift_0 = - _mm256_setr_epi8(0, 1, 2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 6, 7, 8, 9, 0, 1, 2, - 3, 2, 3, 4, 5, 4, 5, 6, 7, 6, 7, 8, 9); - __m256i idx_shift_2 = - _mm256_setr_epi8(4, 5, 6, 7, 6, 7, 8, 9, 8, 9, 10, 11, 10, 11, 12, 13, 4, - 5, 6, 7, 6, 7, 8, 9, 8, 9, 10, 11, 10, 11, 12, 13); - - __m128i kernel_reg_128; // Kernel - __m256i kernel_reg, kernel_reg_23, - kernel_reg_45; // Segments of the kernel used - const __m256i reg_round = - _mm256_set1_epi32(CONV8_ROUNDING_NUM); // Used for rounding - const __m256i reg_max = _mm256_set1_epi16((1 << bd) - 1); - const ptrdiff_t unrolled_src_stride = src_stride << 1; - const ptrdiff_t unrolled_dst_stride = dst_stride << 1; - int h; - - // Start one pixel before as we need tap/2 - 1 = 1 sample from the past - src_ptr -= 1; - - // Load Kernel - kernel_reg_128 = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm256_broadcastsi128_si256(kernel_reg_128); - kernel_reg_23 = _mm256_shuffle_epi32(kernel_reg, 0x55); - kernel_reg_45 = _mm256_shuffle_epi32(kernel_reg, 0xaa); - - for (h = height; h >= 2; h -= 2) { - // Load the source - src_reg = mm256_loadu2_si128(src_ptr, src_ptr + src_stride); - src_reg_shift_0 = _mm256_shuffle_epi8(src_reg, idx_shift_0); - src_reg_shift_2 = _mm256_shuffle_epi8(src_reg, idx_shift_2); - - // Result for first half - res_first = mm256_madd_add_epi32(&src_reg_shift_0, &src_reg_shift_2, - &kernel_reg_23, &kernel_reg_45); - - // Do again to get the second half of dst - // Load the source - src_reg = mm256_loadu2_si128(src_ptr + 4, src_ptr + src_stride + 4); - src_reg_shift_0 = _mm256_shuffle_epi8(src_reg, idx_shift_0); - src_reg_shift_2 = _mm256_shuffle_epi8(src_reg, idx_shift_2); - - // Result for second half - res_last = mm256_madd_add_epi32(&src_reg_shift_0, &src_reg_shift_2, - &kernel_reg_23, &kernel_reg_45); - - // Round each result - res_first = mm256_round_epi32(&res_first, ®_round, CONV8_ROUNDING_BITS); - res_last = mm256_round_epi32(&res_last, ®_round, CONV8_ROUNDING_BITS); - - // Finally combine to get the final dst - res_reg = _mm256_packus_epi32(res_first, res_last); - res_reg = _mm256_min_epi16(res_reg, reg_max); - mm256_store2_si128((__m128i *)dst_ptr, (__m128i *)(dst_ptr + dst_stride), - &res_reg); - - src_ptr += unrolled_src_stride; - dst_ptr += unrolled_dst_stride; - } - - // Repeat for the last row if needed - if (h > 0) { - src_reg = mm256_loadu2_si128(src_ptr, src_ptr + 4); - src_reg_shift_0 = _mm256_shuffle_epi8(src_reg, idx_shift_0); - src_reg_shift_2 = _mm256_shuffle_epi8(src_reg, idx_shift_2); - - res_reg = mm256_madd_add_epi32(&src_reg_shift_0, &src_reg_shift_2, - &kernel_reg_23, &kernel_reg_45); - - res_reg = mm256_round_epi32(&res_reg, ®_round, CONV8_ROUNDING_BITS); - - res_reg = _mm256_packus_epi32(res_reg, res_reg); - res_reg = _mm256_min_epi16(res_reg, reg_max); - - mm256_storeu2_epi64((__m128i *)dst_ptr, (__m128i *)(dst_ptr + 4), &res_reg); - } -} - -static void vpx_highbd_filter_block1d16_h4_avx2( - const uint16_t *src_ptr, ptrdiff_t src_stride, uint16_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, const int16_t *kernel, int bd) { - vpx_highbd_filter_block1d8_h4_avx2(src_ptr, src_stride, dst_ptr, dst_stride, - height, kernel, bd); - vpx_highbd_filter_block1d8_h4_avx2(src_ptr + 8, src_stride, dst_ptr + 8, - dst_stride, height, kernel, bd); -} - -static void vpx_highbd_filter_block1d8_v8_avg_avx2( - const uint16_t *src_ptr, ptrdiff_t src_pitch, uint16_t *dst_ptr, - ptrdiff_t dst_pitch, uint32_t height, const int16_t *filter, int bd) { - __m256i signal[9], res0, res1; - const __m256i max = _mm256_set1_epi16((1 << bd) - 1); - - __m256i ff[4]; - pack_filters(filter, ff); - - pack_8x9_init(src_ptr, src_pitch, signal); - - do { - pack_8x9_pixels(src_ptr, src_pitch, signal); - - filter_8x9_pixels(signal, ff, &res0, &res1); - store_8x2_avg_pixels(&res0, &res1, &max, dst_ptr, dst_pitch); - update_pixels(signal); - - src_ptr += src_pitch << 1; - dst_ptr += dst_pitch << 1; - height -= 2; - } while (height > 0); -} - -static void vpx_highbd_filter_block1d16_v8_avg_avx2( - const uint16_t *src_ptr, ptrdiff_t src_pitch, uint16_t *dst_ptr, - ptrdiff_t dst_pitch, uint32_t height, const int16_t *filter, int bd) { - __m256i signal[17], res0, res1; - const __m256i max = _mm256_set1_epi16((1 << bd) - 1); - - __m256i ff[4]; - pack_filters(filter, ff); - - pack_16x9_init(src_ptr, src_pitch, signal); - - do { - pack_16x9_pixels(src_ptr, src_pitch, signal); - filter_16x9_pixels(signal, ff, &res0, &res1); - store_16x2_avg_pixels(&res0, &res1, &max, dst_ptr, dst_pitch); - update_16x9_pixels(signal); - - src_ptr += src_pitch << 1; - dst_ptr += dst_pitch << 1; - height -= 2; - } while (height > 0); -} - -static void vpx_highbd_filter_block1d8_h2_avg_avx2( - const uint16_t *src_ptr, ptrdiff_t src_pitch, uint16_t *dst_ptr, - ptrdiff_t dst_pitch, uint32_t height, const int16_t *filter, int bd) { - __m256i signal[2], res0, res1; - const __m256i max = _mm256_set1_epi16((1 << bd) - 1); - - __m256i ff; - pack_2t_filter(filter, &ff); - - src_ptr -= 3; - do { - pack_8x2_2t_pixels(src_ptr, src_pitch, signal); - filter_16_2t_pixels(signal, &ff, &res0, &res1); - store_8x2_avg_pixels(&res0, &res1, &max, dst_ptr, dst_pitch); - height -= 2; - src_ptr += src_pitch << 1; - dst_ptr += dst_pitch << 1; - } while (height > 1); - - if (height > 0) { - pack_8x1_2t_pixels(src_ptr, signal); - filter_8x1_2t_pixels(signal, &ff, &res0); - store_8x1_avg_pixels(&res0, &max, dst_ptr); - } -} - -static void vpx_highbd_filter_block1d16_h2_avg_avx2( - const uint16_t *src_ptr, ptrdiff_t src_pitch, uint16_t *dst_ptr, - ptrdiff_t dst_pitch, uint32_t height, const int16_t *filter, int bd) { - __m256i signal[2], res0, res1; - const __m256i max = _mm256_set1_epi16((1 << bd) - 1); - - __m256i ff; - pack_2t_filter(filter, &ff); - - src_ptr -= 3; - do { - pack_16x1_2t_pixels(src_ptr, signal); - filter_16_2t_pixels(signal, &ff, &res0, &res1); - store_16x1_avg_pixels(&res0, &res1, &max, dst_ptr); - height -= 1; - src_ptr += src_pitch; - dst_ptr += dst_pitch; - } while (height > 0); -} - -static void vpx_highbd_filter_block1d16_v2_avg_avx2( - const uint16_t *src_ptr, ptrdiff_t src_pitch, uint16_t *dst_ptr, - ptrdiff_t dst_pitch, uint32_t height, const int16_t *filter, int bd) { - __m256i signal[3], res0, res1; - const __m256i max = _mm256_set1_epi16((1 << bd) - 1); - __m256i ff; - - pack_2t_filter(filter, &ff); - pack_16x2_init(src_ptr, signal); - - do { - pack_16x2_2t_pixels(src_ptr, src_pitch, signal); - filter_16x2_2t_pixels(signal, &ff, &res0, &res1); - store_16x1_avg_pixels(&res0, &res1, &max, dst_ptr); - - src_ptr += src_pitch; - dst_ptr += dst_pitch; - height -= 1; - } while (height > 0); -} - -static void vpx_highbd_filter_block1d8_v2_avg_avx2( - const uint16_t *src_ptr, ptrdiff_t src_pitch, uint16_t *dst_ptr, - ptrdiff_t dst_pitch, uint32_t height, const int16_t *filter, int bd) { - __m128i signal[3], res0, res1; - const __m128i max = _mm_set1_epi16((1 << bd) - 1); - __m128i ff; - - pack_8x1_2t_filter(filter, &ff); - pack_8x2_init(src_ptr, signal); - - do { - pack_8x2_2t_pixels_ver(src_ptr, src_pitch, signal); - filter_8_2t_pixels(signal, &ff, &res0, &res1); - store_8x1_2t_avg_pixels_ver(&res0, &res1, &max, dst_ptr); - - src_ptr += src_pitch; - dst_ptr += dst_pitch; - height -= 1; - } while (height > 0); -} - -static void vpx_highbd_filter_block1d4_v4_avx2( - const uint16_t *src_ptr, ptrdiff_t src_stride, uint16_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, const int16_t *kernel, int bd) { - // We will load two rows of pixels and rearrange them into the form - // ... s[1,0] s[0,0] s[0,0] s[-1,0] - // so that we can call multiply and add with the kernel partial output. Then - // we can call add with another row to get the output. - - // Register for source s[-1:3, :] - __m256i src_reg_1, src_reg_2, src_reg_3; - // Interleaved rows of the source. lo is first half, hi second - __m256i src_reg_m10, src_reg_01, src_reg_12, src_reg_23; - __m256i src_reg_m1001, src_reg_1223; - - // Result after multiply and add - __m256i res_reg; - - __m128i kernel_reg_128; // Kernel - __m256i kernel_reg, kernel_reg_23, kernel_reg_45; // Segments of kernel used - - const __m256i reg_round = - _mm256_set1_epi32(CONV8_ROUNDING_NUM); // Used for rounding - const __m256i reg_max = _mm256_set1_epi16((1 << bd) - 1); - const ptrdiff_t src_stride_unrolled = src_stride << 1; - const ptrdiff_t dst_stride_unrolled = dst_stride << 1; - int h; - - // Load Kernel - kernel_reg_128 = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm256_broadcastsi128_si256(kernel_reg_128); - kernel_reg_23 = _mm256_shuffle_epi32(kernel_reg, 0x55); - kernel_reg_45 = _mm256_shuffle_epi32(kernel_reg, 0xaa); - - // Row -1 to row 0 - src_reg_m10 = mm256_loadu2_epi64((const __m128i *)src_ptr, - (const __m128i *)(src_ptr + src_stride)); - - // Row 0 to row 1 - src_reg_1 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 2))); - src_reg_01 = _mm256_permute2x128_si256(src_reg_m10, src_reg_1, 0x21); - - // First three rows - src_reg_m1001 = _mm256_unpacklo_epi16(src_reg_m10, src_reg_01); - - for (h = height; h > 1; h -= 2) { - src_reg_2 = _mm256_castsi128_si256( - _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride * 3))); - - src_reg_12 = _mm256_inserti128_si256(src_reg_1, - _mm256_castsi256_si128(src_reg_2), 1); - - src_reg_3 = _mm256_castsi128_si256( - _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride * 4))); - - src_reg_23 = _mm256_inserti128_si256(src_reg_2, - _mm256_castsi256_si128(src_reg_3), 1); - - // Last three rows - src_reg_1223 = _mm256_unpacklo_epi16(src_reg_12, src_reg_23); - - // Output - res_reg = mm256_madd_add_epi32(&src_reg_m1001, &src_reg_1223, - &kernel_reg_23, &kernel_reg_45); - - // Round the words - res_reg = mm256_round_epi32(&res_reg, ®_round, CONV8_ROUNDING_BITS); - - // Combine to get the result - res_reg = _mm256_packus_epi32(res_reg, res_reg); - res_reg = _mm256_min_epi16(res_reg, reg_max); - - // Save the result - mm256_storeu2_epi64((__m128i *)dst_ptr, (__m128i *)(dst_ptr + dst_stride), - &res_reg); - - // Update the source by two rows - src_ptr += src_stride_unrolled; - dst_ptr += dst_stride_unrolled; - - src_reg_m1001 = src_reg_1223; - src_reg_1 = src_reg_3; - } -} - -static void vpx_highbd_filter_block1d8_v4_avx2( - const uint16_t *src_ptr, ptrdiff_t src_stride, uint16_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, const int16_t *kernel, int bd) { - // We will load two rows of pixels and rearrange them into the form - // ... s[1,0] s[0,0] s[0,0] s[-1,0] - // so that we can call multiply and add with the kernel partial output. Then - // we can call add with another row to get the output. - - // Register for source s[-1:3, :] - __m256i src_reg_1, src_reg_2, src_reg_3; - // Interleaved rows of the source. lo is first half, hi second - __m256i src_reg_m10, src_reg_01, src_reg_12, src_reg_23; - __m256i src_reg_m1001_lo, src_reg_m1001_hi, src_reg_1223_lo, src_reg_1223_hi; - - __m128i kernel_reg_128; // Kernel - __m256i kernel_reg, kernel_reg_23, kernel_reg_45; // Segments of kernel - - // Result after multiply and add - __m256i res_reg, res_reg_lo, res_reg_hi; - - const __m256i reg_round = - _mm256_set1_epi32(CONV8_ROUNDING_NUM); // Used for rounding - const __m256i reg_max = _mm256_set1_epi16((1 << bd) - 1); - const ptrdiff_t src_stride_unrolled = src_stride << 1; - const ptrdiff_t dst_stride_unrolled = dst_stride << 1; - int h; - - // Load Kernel - kernel_reg_128 = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm256_broadcastsi128_si256(kernel_reg_128); - kernel_reg_23 = _mm256_shuffle_epi32(kernel_reg, 0x55); - kernel_reg_45 = _mm256_shuffle_epi32(kernel_reg, 0xaa); - - // Row -1 to row 0 - src_reg_m10 = mm256_loadu2_si128((const __m128i *)src_ptr, - (const __m128i *)(src_ptr + src_stride)); - - // Row 0 to row 1 - src_reg_1 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 2))); - src_reg_01 = _mm256_permute2x128_si256(src_reg_m10, src_reg_1, 0x21); - - // First three rows - src_reg_m1001_lo = _mm256_unpacklo_epi16(src_reg_m10, src_reg_01); - src_reg_m1001_hi = _mm256_unpackhi_epi16(src_reg_m10, src_reg_01); - - for (h = height; h > 1; h -= 2) { - src_reg_2 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 3))); - - src_reg_12 = _mm256_inserti128_si256(src_reg_1, - _mm256_castsi256_si128(src_reg_2), 1); - - src_reg_3 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 4))); - - src_reg_23 = _mm256_inserti128_si256(src_reg_2, - _mm256_castsi256_si128(src_reg_3), 1); - - // Last three rows - src_reg_1223_lo = _mm256_unpacklo_epi16(src_reg_12, src_reg_23); - src_reg_1223_hi = _mm256_unpackhi_epi16(src_reg_12, src_reg_23); - - // Output from first half - res_reg_lo = mm256_madd_add_epi32(&src_reg_m1001_lo, &src_reg_1223_lo, - &kernel_reg_23, &kernel_reg_45); - - // Output from second half - res_reg_hi = mm256_madd_add_epi32(&src_reg_m1001_hi, &src_reg_1223_hi, - &kernel_reg_23, &kernel_reg_45); - - // Round the words - res_reg_lo = - mm256_round_epi32(&res_reg_lo, ®_round, CONV8_ROUNDING_BITS); - res_reg_hi = - mm256_round_epi32(&res_reg_hi, ®_round, CONV8_ROUNDING_BITS); - - // Combine to get the result - res_reg = _mm256_packus_epi32(res_reg_lo, res_reg_hi); - res_reg = _mm256_min_epi16(res_reg, reg_max); - - // Save the result - mm256_store2_si128((__m128i *)dst_ptr, (__m128i *)(dst_ptr + dst_stride), - &res_reg); - - // Update the source by two rows - src_ptr += src_stride_unrolled; - dst_ptr += dst_stride_unrolled; - - src_reg_m1001_lo = src_reg_1223_lo; - src_reg_m1001_hi = src_reg_1223_hi; - src_reg_1 = src_reg_3; - } -} - -static void vpx_highbd_filter_block1d16_v4_avx2( - const uint16_t *src_ptr, ptrdiff_t src_stride, uint16_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, const int16_t *kernel, int bd) { - vpx_highbd_filter_block1d8_v4_avx2(src_ptr, src_stride, dst_ptr, dst_stride, - height, kernel, bd); - vpx_highbd_filter_block1d8_v4_avx2(src_ptr + 8, src_stride, dst_ptr + 8, - dst_stride, height, kernel, bd); -} - -// From vpx_dsp/x86/vpx_high_subpixel_8t_sse2.asm. -highbd_filter8_1dfunction vpx_highbd_filter_block1d4_h8_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d4_v8_sse2; - -// From vpx_dsp/x86/vpx_high_subpixel_bilinear_sse2.asm. -highbd_filter8_1dfunction vpx_highbd_filter_block1d4_h2_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d4_v2_sse2; - -#define vpx_highbd_filter_block1d4_h8_avx2 vpx_highbd_filter_block1d4_h8_sse2 -#define vpx_highbd_filter_block1d4_h2_avx2 vpx_highbd_filter_block1d4_h2_sse2 -#define vpx_highbd_filter_block1d4_v8_avx2 vpx_highbd_filter_block1d4_v8_sse2 -#define vpx_highbd_filter_block1d4_v2_avx2 vpx_highbd_filter_block1d4_v2_sse2 - -// Use the [vh]8 version because there is no [vh]4 implementation. -#define vpx_highbd_filter_block1d16_v4_avg_avx2 \ - vpx_highbd_filter_block1d16_v8_avg_avx2 -#define vpx_highbd_filter_block1d16_h4_avg_avx2 \ - vpx_highbd_filter_block1d16_h8_avg_avx2 -#define vpx_highbd_filter_block1d8_v4_avg_avx2 \ - vpx_highbd_filter_block1d8_v8_avg_avx2 -#define vpx_highbd_filter_block1d8_h4_avg_avx2 \ - vpx_highbd_filter_block1d8_h8_avg_avx2 -#define vpx_highbd_filter_block1d4_v4_avg_avx2 \ - vpx_highbd_filter_block1d4_v8_avg_avx2 -#define vpx_highbd_filter_block1d4_h4_avg_avx2 \ - vpx_highbd_filter_block1d4_h8_avg_avx2 - -HIGH_FUN_CONV_1D(horiz, x0_q4, x_step_q4, h, src, , avx2, 0) -HIGH_FUN_CONV_1D(vert, y0_q4, y_step_q4, v, - src - src_stride * (num_taps / 2 - 1), , avx2, 0) -HIGH_FUN_CONV_2D(, avx2, 0) - -// From vpx_dsp/x86/vpx_high_subpixel_8t_sse2.asm. -highbd_filter8_1dfunction vpx_highbd_filter_block1d4_h8_avg_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d4_v8_avg_sse2; - -// From vpx_dsp/x86/vpx_high_subpixel_bilinear_sse2.asm. -highbd_filter8_1dfunction vpx_highbd_filter_block1d4_h2_avg_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d4_v2_avg_sse2; - -#define vpx_highbd_filter_block1d4_h8_avg_avx2 \ - vpx_highbd_filter_block1d4_h8_avg_sse2 -#define vpx_highbd_filter_block1d4_h2_avg_avx2 \ - vpx_highbd_filter_block1d4_h2_avg_sse2 -#define vpx_highbd_filter_block1d4_v8_avg_avx2 \ - vpx_highbd_filter_block1d4_v8_avg_sse2 -#define vpx_highbd_filter_block1d4_v2_avg_avx2 \ - vpx_highbd_filter_block1d4_v2_avg_sse2 - -HIGH_FUN_CONV_1D(avg_horiz, x0_q4, x_step_q4, h, src, avg_, avx2, 1) -HIGH_FUN_CONV_1D(avg_vert, y0_q4, y_step_q4, v, - src - src_stride * (num_taps / 2 - 1), avg_, avx2, 1) -HIGH_FUN_CONV_2D(avg_, avx2, 1) - -#undef HIGHBD_FUNC diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct16x16_add_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct16x16_add_sse2.c deleted file mode 100644 index f4f7235d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct16x16_add_sse2.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // SSE2 - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/x86/highbd_inv_txfm_sse2.h" -#include "vpx_dsp/x86/inv_txfm_sse2.h" -#include "vpx_dsp/x86/transpose_sse2.h" -#include "vpx_dsp/x86/txfm_common_sse2.h" - -static INLINE void highbd_idct16_4col_stage5(const __m128i *const in, - __m128i *const out) { - // stage 5 - out[0] = _mm_add_epi32(in[0], in[3]); - out[1] = _mm_add_epi32(in[1], in[2]); - out[2] = _mm_sub_epi32(in[1], in[2]); - out[3] = _mm_sub_epi32(in[0], in[3]); - highbd_butterfly_cospi16_sse2(in[6], in[5], &out[6], &out[5]); - out[8] = _mm_add_epi32(in[8], in[11]); - out[9] = _mm_add_epi32(in[9], in[10]); - out[10] = _mm_sub_epi32(in[9], in[10]); - out[11] = _mm_sub_epi32(in[8], in[11]); - out[12] = _mm_sub_epi32(in[15], in[12]); - out[13] = _mm_sub_epi32(in[14], in[13]); - out[14] = _mm_add_epi32(in[14], in[13]); - out[15] = _mm_add_epi32(in[15], in[12]); -} - -static INLINE void highbd_idct16_4col_stage6(const __m128i *const in, - __m128i *const out) { - out[0] = _mm_add_epi32(in[0], in[7]); - out[1] = _mm_add_epi32(in[1], in[6]); - out[2] = _mm_add_epi32(in[2], in[5]); - out[3] = _mm_add_epi32(in[3], in[4]); - out[4] = _mm_sub_epi32(in[3], in[4]); - out[5] = _mm_sub_epi32(in[2], in[5]); - out[6] = _mm_sub_epi32(in[1], in[6]); - out[7] = _mm_sub_epi32(in[0], in[7]); - out[8] = in[8]; - out[9] = in[9]; - highbd_butterfly_cospi16_sse2(in[13], in[10], &out[13], &out[10]); - highbd_butterfly_cospi16_sse2(in[12], in[11], &out[12], &out[11]); - out[14] = in[14]; - out[15] = in[15]; -} - -static INLINE void highbd_idct16_4col(__m128i *const io /*io[16]*/) { - __m128i step1[16], step2[16]; - - // stage 2 - highbd_butterfly_sse2(io[1], io[15], cospi_30_64, cospi_2_64, &step2[8], - &step2[15]); - highbd_butterfly_sse2(io[9], io[7], cospi_14_64, cospi_18_64, &step2[9], - &step2[14]); - highbd_butterfly_sse2(io[5], io[11], cospi_22_64, cospi_10_64, &step2[10], - &step2[13]); - highbd_butterfly_sse2(io[13], io[3], cospi_6_64, cospi_26_64, &step2[11], - &step2[12]); - - // stage 3 - highbd_butterfly_sse2(io[2], io[14], cospi_28_64, cospi_4_64, &step1[4], - &step1[7]); - highbd_butterfly_sse2(io[10], io[6], cospi_12_64, cospi_20_64, &step1[5], - &step1[6]); - step1[8] = _mm_add_epi32(step2[8], step2[9]); - step1[9] = _mm_sub_epi32(step2[8], step2[9]); - step1[10] = _mm_sub_epi32(step2[10], step2[11]); // step1[10] = -step1[10] - step1[11] = _mm_add_epi32(step2[10], step2[11]); - step1[12] = _mm_add_epi32(step2[13], step2[12]); - step1[13] = _mm_sub_epi32(step2[13], step2[12]); // step1[13] = -step1[13] - step1[14] = _mm_sub_epi32(step2[15], step2[14]); - step1[15] = _mm_add_epi32(step2[15], step2[14]); - - // stage 4 - highbd_butterfly_cospi16_sse2(io[0], io[8], &step2[0], &step2[1]); - highbd_butterfly_sse2(io[4], io[12], cospi_24_64, cospi_8_64, &step2[2], - &step2[3]); - highbd_butterfly_sse2(step1[14], step1[9], cospi_24_64, cospi_8_64, &step2[9], - &step2[14]); - highbd_butterfly_sse2(step1[10], step1[13], cospi_8_64, cospi_24_64, - &step2[13], &step2[10]); - step2[5] = _mm_sub_epi32(step1[4], step1[5]); - step1[4] = _mm_add_epi32(step1[4], step1[5]); - step2[6] = _mm_sub_epi32(step1[7], step1[6]); - step1[7] = _mm_add_epi32(step1[7], step1[6]); - step2[8] = step1[8]; - step2[11] = step1[11]; - step2[12] = step1[12]; - step2[15] = step1[15]; - - highbd_idct16_4col_stage5(step2, step1); - highbd_idct16_4col_stage6(step1, step2); - highbd_idct16_4col_stage7(step2, io); -} - -static INLINE void highbd_idct16x16_38_4col(__m128i *const io /*io[16]*/) { - __m128i step1[16], step2[16]; - __m128i temp1[2], sign[2]; - - // stage 2 - highbd_partial_butterfly_sse2(io[1], cospi_30_64, cospi_2_64, &step2[8], - &step2[15]); - highbd_partial_butterfly_neg_sse2(io[7], cospi_14_64, cospi_18_64, &step2[9], - &step2[14]); - highbd_partial_butterfly_sse2(io[5], cospi_22_64, cospi_10_64, &step2[10], - &step2[13]); - highbd_partial_butterfly_neg_sse2(io[3], cospi_6_64, cospi_26_64, &step2[11], - &step2[12]); - - // stage 3 - highbd_partial_butterfly_sse2(io[2], cospi_28_64, cospi_4_64, &step1[4], - &step1[7]); - highbd_partial_butterfly_neg_sse2(io[6], cospi_12_64, cospi_20_64, &step1[5], - &step1[6]); - step1[8] = _mm_add_epi32(step2[8], step2[9]); - step1[9] = _mm_sub_epi32(step2[8], step2[9]); - step1[10] = _mm_sub_epi32(step2[10], step2[11]); // step1[10] = -step1[10] - step1[11] = _mm_add_epi32(step2[10], step2[11]); - step1[12] = _mm_add_epi32(step2[13], step2[12]); - step1[13] = _mm_sub_epi32(step2[13], step2[12]); // step1[13] = -step1[13] - step1[14] = _mm_sub_epi32(step2[15], step2[14]); - step1[15] = _mm_add_epi32(step2[15], step2[14]); - - // stage 4 - abs_extend_64bit_sse2(io[0], temp1, sign); - step2[0] = multiplication_round_shift_sse2(temp1, sign, cospi_16_64); - step2[1] = step2[0]; - highbd_partial_butterfly_sse2(io[4], cospi_24_64, cospi_8_64, &step2[2], - &step2[3]); - highbd_butterfly_sse2(step1[14], step1[9], cospi_24_64, cospi_8_64, &step2[9], - &step2[14]); - highbd_butterfly_sse2(step1[10], step1[13], cospi_8_64, cospi_24_64, - &step2[13], &step2[10]); - step2[5] = _mm_sub_epi32(step1[4], step1[5]); - step1[4] = _mm_add_epi32(step1[4], step1[5]); - step2[6] = _mm_sub_epi32(step1[7], step1[6]); - step1[7] = _mm_add_epi32(step1[7], step1[6]); - step2[8] = step1[8]; - step2[11] = step1[11]; - step2[12] = step1[12]; - step2[15] = step1[15]; - - highbd_idct16_4col_stage5(step2, step1); - highbd_idct16_4col_stage6(step1, step2); - highbd_idct16_4col_stage7(step2, io); -} - -static INLINE void highbd_idct16x16_10_4col(__m128i *const io /*io[16]*/) { - __m128i step1[16], step2[16]; - __m128i temp[2], sign[2]; - - // stage 2 - highbd_partial_butterfly_sse2(io[1], cospi_30_64, cospi_2_64, &step2[8], - &step2[15]); - highbd_partial_butterfly_neg_sse2(io[3], cospi_6_64, cospi_26_64, &step2[11], - &step2[12]); - - // stage 3 - highbd_partial_butterfly_sse2(io[2], cospi_28_64, cospi_4_64, &step1[4], - &step1[7]); - step1[8] = step2[8]; - step1[9] = step2[8]; - step1[10] = - _mm_sub_epi32(_mm_setzero_si128(), step2[11]); // step1[10] = -step1[10] - step1[11] = step2[11]; - step1[12] = step2[12]; - step1[13] = - _mm_sub_epi32(_mm_setzero_si128(), step2[12]); // step1[13] = -step1[13] - step1[14] = step2[15]; - step1[15] = step2[15]; - - // stage 4 - abs_extend_64bit_sse2(io[0], temp, sign); - step2[0] = multiplication_round_shift_sse2(temp, sign, cospi_16_64); - step2[1] = step2[0]; - step2[2] = _mm_setzero_si128(); - step2[3] = _mm_setzero_si128(); - highbd_butterfly_sse2(step1[14], step1[9], cospi_24_64, cospi_8_64, &step2[9], - &step2[14]); - highbd_butterfly_sse2(step1[10], step1[13], cospi_8_64, cospi_24_64, - &step2[13], &step2[10]); - step2[5] = step1[4]; - step2[6] = step1[7]; - step2[8] = step1[8]; - step2[11] = step1[11]; - step2[12] = step1[12]; - step2[15] = step1[15]; - - highbd_idct16_4col_stage5(step2, step1); - highbd_idct16_4col_stage6(step1, step2); - highbd_idct16_4col_stage7(step2, io); -} - -void vpx_highbd_idct16x16_256_add_sse2(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i; - __m128i out[16], *in; - - if (bd == 8) { - __m128i l[16], r[16]; - - in = l; - for (i = 0; i < 2; i++) { - highbd_load_pack_transpose_32bit_8x8(&input[0], 16, &in[0]); - highbd_load_pack_transpose_32bit_8x8(&input[8], 16, &in[8]); - idct16_8col(in, in); - in = r; - input += 128; - } - - for (i = 0; i < 16; i += 8) { - int j; - transpose_16bit_8x8(l + i, out); - transpose_16bit_8x8(r + i, out + 8); - idct16_8col(out, out); - - for (j = 0; j < 16; ++j) { - highbd_write_buffer_8(dest + j * stride, out[j], bd); - } - dest += 8; - } - } else { - __m128i all[4][16]; - - for (i = 0; i < 4; i++) { - in = all[i]; - highbd_load_transpose_32bit_8x4(&input[0], 16, &in[0]); - highbd_load_transpose_32bit_8x4(&input[8], 16, &in[8]); - highbd_idct16_4col(in); - input += 4 * 16; - } - - for (i = 0; i < 16; i += 4) { - int j; - transpose_32bit_4x4(all[0] + i, out + 0); - transpose_32bit_4x4(all[1] + i, out + 4); - transpose_32bit_4x4(all[2] + i, out + 8); - transpose_32bit_4x4(all[3] + i, out + 12); - highbd_idct16_4col(out); - - for (j = 0; j < 16; ++j) { - highbd_write_buffer_4(dest + j * stride, out[j], bd); - } - dest += 4; - } - } -} - -void vpx_highbd_idct16x16_38_add_sse2(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i; - __m128i out[16]; - - if (bd == 8) { - __m128i in[16], temp[16]; - - highbd_load_pack_transpose_32bit_8x8(input, 16, in); - for (i = 8; i < 16; i++) { - in[i] = _mm_setzero_si128(); - } - idct16_8col(in, temp); - - for (i = 0; i < 16; i += 8) { - int j; - transpose_16bit_8x8(temp + i, in); - idct16_8col(in, out); - - for (j = 0; j < 16; ++j) { - highbd_write_buffer_8(dest + j * stride, out[j], bd); - } - dest += 8; - } - } else { - __m128i all[2][16], *in; - - for (i = 0; i < 2; i++) { - in = all[i]; - highbd_load_transpose_32bit_8x4(input, 16, in); - highbd_idct16x16_38_4col(in); - input += 4 * 16; - } - - for (i = 0; i < 16; i += 4) { - int j; - transpose_32bit_4x4(all[0] + i, out + 0); - transpose_32bit_4x4(all[1] + i, out + 4); - highbd_idct16x16_38_4col(out); - - for (j = 0; j < 16; ++j) { - highbd_write_buffer_4(dest + j * stride, out[j], bd); - } - dest += 4; - } - } -} - -void vpx_highbd_idct16x16_10_add_sse2(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i; - __m128i out[16]; - - if (bd == 8) { - __m128i in[16], l[16]; - - in[0] = load_pack_8_32bit(input + 0 * 16); - in[1] = load_pack_8_32bit(input + 1 * 16); - in[2] = load_pack_8_32bit(input + 2 * 16); - in[3] = load_pack_8_32bit(input + 3 * 16); - - idct16x16_10_pass1(in, l); - - for (i = 0; i < 16; i += 8) { - int j; - idct16x16_10_pass2(l + i, in); - - for (j = 0; j < 16; ++j) { - highbd_write_buffer_8(dest + j * stride, in[j], bd); - } - dest += 8; - } - } else { - __m128i all[2][16], *in; - - for (i = 0; i < 2; i++) { - in = all[i]; - highbd_load_transpose_32bit_4x4(input, 16, in); - highbd_idct16x16_10_4col(in); - input += 4 * 16; - } - - for (i = 0; i < 16; i += 4) { - int j; - transpose_32bit_4x4(&all[0][i], out); - highbd_idct16x16_10_4col(out); - - for (j = 0; j < 16; ++j) { - highbd_write_buffer_4(dest + j * stride, out[j], bd); - } - dest += 4; - } - } -} - -void vpx_highbd_idct16x16_1_add_sse2(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - highbd_idct_1_add_kernel(input, dest, stride, bd, 16); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct16x16_add_sse4.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct16x16_add_sse4.c deleted file mode 100644 index 7898ee12..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct16x16_add_sse4.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // SSE4.1 - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/x86/highbd_inv_txfm_sse2.h" -#include "vpx_dsp/x86/highbd_inv_txfm_sse4.h" -#include "vpx_dsp/x86/inv_txfm_sse2.h" -#include "vpx_dsp/x86/transpose_sse2.h" -#include "vpx_dsp/x86/txfm_common_sse2.h" - -static INLINE void highbd_idct16_4col_stage5(const __m128i *const in, - __m128i *const out) { - // stage 5 - out[0] = _mm_add_epi32(in[0], in[3]); - out[1] = _mm_add_epi32(in[1], in[2]); - out[2] = _mm_sub_epi32(in[1], in[2]); - out[3] = _mm_sub_epi32(in[0], in[3]); - highbd_butterfly_cospi16_sse4_1(in[6], in[5], &out[6], &out[5]); - out[8] = _mm_add_epi32(in[8], in[11]); - out[9] = _mm_add_epi32(in[9], in[10]); - out[10] = _mm_sub_epi32(in[9], in[10]); - out[11] = _mm_sub_epi32(in[8], in[11]); - out[12] = _mm_sub_epi32(in[15], in[12]); - out[13] = _mm_sub_epi32(in[14], in[13]); - out[14] = _mm_add_epi32(in[14], in[13]); - out[15] = _mm_add_epi32(in[15], in[12]); -} - -static INLINE void highbd_idct16_4col_stage6(const __m128i *const in, - __m128i *const out) { - out[0] = _mm_add_epi32(in[0], in[7]); - out[1] = _mm_add_epi32(in[1], in[6]); - out[2] = _mm_add_epi32(in[2], in[5]); - out[3] = _mm_add_epi32(in[3], in[4]); - out[4] = _mm_sub_epi32(in[3], in[4]); - out[5] = _mm_sub_epi32(in[2], in[5]); - out[6] = _mm_sub_epi32(in[1], in[6]); - out[7] = _mm_sub_epi32(in[0], in[7]); - out[8] = in[8]; - out[9] = in[9]; - highbd_butterfly_cospi16_sse4_1(in[13], in[10], &out[13], &out[10]); - highbd_butterfly_cospi16_sse4_1(in[12], in[11], &out[12], &out[11]); - out[14] = in[14]; - out[15] = in[15]; -} - -void vpx_highbd_idct16_4col_sse4_1(__m128i *const io /*io[16]*/) { - __m128i step1[16], step2[16]; - - // stage 2 - highbd_butterfly_sse4_1(io[1], io[15], cospi_30_64, cospi_2_64, &step2[8], - &step2[15]); - highbd_butterfly_sse4_1(io[9], io[7], cospi_14_64, cospi_18_64, &step2[9], - &step2[14]); - highbd_butterfly_sse4_1(io[5], io[11], cospi_22_64, cospi_10_64, &step2[10], - &step2[13]); - highbd_butterfly_sse4_1(io[13], io[3], cospi_6_64, cospi_26_64, &step2[11], - &step2[12]); - - // stage 3 - highbd_butterfly_sse4_1(io[2], io[14], cospi_28_64, cospi_4_64, &step1[4], - &step1[7]); - highbd_butterfly_sse4_1(io[10], io[6], cospi_12_64, cospi_20_64, &step1[5], - &step1[6]); - step1[8] = _mm_add_epi32(step2[8], step2[9]); - step1[9] = _mm_sub_epi32(step2[8], step2[9]); - step1[10] = _mm_sub_epi32(step2[11], step2[10]); - step1[11] = _mm_add_epi32(step2[11], step2[10]); - step1[12] = _mm_add_epi32(step2[12], step2[13]); - step1[13] = _mm_sub_epi32(step2[12], step2[13]); - step1[14] = _mm_sub_epi32(step2[15], step2[14]); - step1[15] = _mm_add_epi32(step2[15], step2[14]); - - // stage 4 - highbd_butterfly_cospi16_sse4_1(io[0], io[8], &step2[0], &step2[1]); - highbd_butterfly_sse4_1(io[4], io[12], cospi_24_64, cospi_8_64, &step2[2], - &step2[3]); - highbd_butterfly_sse4_1(step1[14], step1[9], cospi_24_64, cospi_8_64, - &step2[9], &step2[14]); - highbd_butterfly_sse4_1(step1[10], step1[13], -cospi_8_64, -cospi_24_64, - &step2[13], &step2[10]); - step2[5] = _mm_sub_epi32(step1[4], step1[5]); - step1[4] = _mm_add_epi32(step1[4], step1[5]); - step2[6] = _mm_sub_epi32(step1[7], step1[6]); - step1[7] = _mm_add_epi32(step1[7], step1[6]); - step2[8] = step1[8]; - step2[11] = step1[11]; - step2[12] = step1[12]; - step2[15] = step1[15]; - - highbd_idct16_4col_stage5(step2, step1); - highbd_idct16_4col_stage6(step1, step2); - highbd_idct16_4col_stage7(step2, io); -} - -static INLINE void highbd_idct16x16_38_4col(__m128i *const io /*io[16]*/) { - __m128i step1[16], step2[16]; - __m128i temp1[2]; - - // stage 2 - highbd_partial_butterfly_sse4_1(io[1], cospi_30_64, cospi_2_64, &step2[8], - &step2[15]); - highbd_partial_butterfly_sse4_1(io[7], -cospi_18_64, cospi_14_64, &step2[9], - &step2[14]); - highbd_partial_butterfly_sse4_1(io[5], cospi_22_64, cospi_10_64, &step2[10], - &step2[13]); - highbd_partial_butterfly_sse4_1(io[3], -cospi_26_64, cospi_6_64, &step2[11], - &step2[12]); - - // stage 3 - highbd_partial_butterfly_sse4_1(io[2], cospi_28_64, cospi_4_64, &step1[4], - &step1[7]); - highbd_partial_butterfly_sse4_1(io[6], -cospi_20_64, cospi_12_64, &step1[5], - &step1[6]); - step1[8] = _mm_add_epi32(step2[8], step2[9]); - step1[9] = _mm_sub_epi32(step2[8], step2[9]); - step1[10] = _mm_sub_epi32(step2[11], step2[10]); - step1[11] = _mm_add_epi32(step2[11], step2[10]); - step1[12] = _mm_add_epi32(step2[12], step2[13]); - step1[13] = _mm_sub_epi32(step2[12], step2[13]); - step1[14] = _mm_sub_epi32(step2[15], step2[14]); - step1[15] = _mm_add_epi32(step2[15], step2[14]); - - // stage 4 - extend_64bit(io[0], temp1); - step2[0] = multiplication_round_shift_sse4_1(temp1, cospi_16_64); - step2[1] = step2[0]; - highbd_partial_butterfly_sse4_1(io[4], cospi_24_64, cospi_8_64, &step2[2], - &step2[3]); - highbd_butterfly_sse4_1(step1[14], step1[9], cospi_24_64, cospi_8_64, - &step2[9], &step2[14]); - highbd_butterfly_sse4_1(step1[10], step1[13], -cospi_8_64, -cospi_24_64, - &step2[13], &step2[10]); - step2[5] = _mm_sub_epi32(step1[4], step1[5]); - step1[4] = _mm_add_epi32(step1[4], step1[5]); - step2[6] = _mm_sub_epi32(step1[7], step1[6]); - step1[7] = _mm_add_epi32(step1[7], step1[6]); - step2[8] = step1[8]; - step2[11] = step1[11]; - step2[12] = step1[12]; - step2[15] = step1[15]; - - highbd_idct16_4col_stage5(step2, step1); - highbd_idct16_4col_stage6(step1, step2); - highbd_idct16_4col_stage7(step2, io); -} - -static INLINE void highbd_idct16x16_10_4col(__m128i *const io /*io[16]*/) { - __m128i step1[16], step2[16]; - __m128i temp[2]; - - // stage 2 - highbd_partial_butterfly_sse4_1(io[1], cospi_30_64, cospi_2_64, &step2[8], - &step2[15]); - highbd_partial_butterfly_sse4_1(io[3], -cospi_26_64, cospi_6_64, &step2[11], - &step2[12]); - - // stage 3 - highbd_partial_butterfly_sse4_1(io[2], cospi_28_64, cospi_4_64, &step1[4], - &step1[7]); - step1[8] = step2[8]; - step1[9] = step2[8]; - step1[10] = step2[11]; - step1[11] = step2[11]; - step1[12] = step2[12]; - step1[13] = step2[12]; - step1[14] = step2[15]; - step1[15] = step2[15]; - - // stage 4 - extend_64bit(io[0], temp); - step2[0] = multiplication_round_shift_sse4_1(temp, cospi_16_64); - step2[1] = step2[0]; - step2[2] = _mm_setzero_si128(); - step2[3] = _mm_setzero_si128(); - highbd_butterfly_sse4_1(step1[14], step1[9], cospi_24_64, cospi_8_64, - &step2[9], &step2[14]); - highbd_butterfly_sse4_1(step1[10], step1[13], -cospi_8_64, -cospi_24_64, - &step2[13], &step2[10]); - step2[5] = step1[4]; - step2[6] = step1[7]; - step2[8] = step1[8]; - step2[11] = step1[11]; - step2[12] = step1[12]; - step2[15] = step1[15]; - - highbd_idct16_4col_stage5(step2, step1); - highbd_idct16_4col_stage6(step1, step2); - highbd_idct16_4col_stage7(step2, io); -} - -void vpx_highbd_idct16x16_256_add_sse4_1(const tran_low_t *input, - uint16_t *dest, int stride, int bd) { - int i; - __m128i out[16], *in; - - if (bd == 8) { - __m128i l[16], r[16]; - - in = l; - for (i = 0; i < 2; i++) { - highbd_load_pack_transpose_32bit_8x8(&input[0], 16, &in[0]); - highbd_load_pack_transpose_32bit_8x8(&input[8], 16, &in[8]); - idct16_8col(in, in); - in = r; - input += 128; - } - - for (i = 0; i < 16; i += 8) { - int j; - transpose_16bit_8x8(l + i, out); - transpose_16bit_8x8(r + i, out + 8); - idct16_8col(out, out); - - for (j = 0; j < 16; ++j) { - highbd_write_buffer_8(dest + j * stride, out[j], bd); - } - dest += 8; - } - } else { - __m128i all[4][16]; - - for (i = 0; i < 4; i++) { - in = all[i]; - highbd_load_transpose_32bit_8x4(&input[0], 16, &in[0]); - highbd_load_transpose_32bit_8x4(&input[8], 16, &in[8]); - vpx_highbd_idct16_4col_sse4_1(in); - input += 4 * 16; - } - - for (i = 0; i < 16; i += 4) { - int j; - transpose_32bit_4x4(all[0] + i, out + 0); - transpose_32bit_4x4(all[1] + i, out + 4); - transpose_32bit_4x4(all[2] + i, out + 8); - transpose_32bit_4x4(all[3] + i, out + 12); - vpx_highbd_idct16_4col_sse4_1(out); - - for (j = 0; j < 16; ++j) { - highbd_write_buffer_4(dest + j * stride, out[j], bd); - } - dest += 4; - } - } -} - -void vpx_highbd_idct16x16_38_add_sse4_1(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i; - __m128i out[16]; - - if (bd == 8) { - __m128i in[16], temp[16]; - - highbd_load_pack_transpose_32bit_8x8(&input[0], 16, &in[0]); - for (i = 8; i < 16; i++) { - in[i] = _mm_setzero_si128(); - } - idct16_8col(in, temp); - - for (i = 0; i < 16; i += 8) { - int j; - transpose_16bit_8x8(temp + i, in); - idct16_8col(in, out); - - for (j = 0; j < 16; ++j) { - highbd_write_buffer_8(dest + j * stride, out[j], bd); - } - dest += 8; - } - } else { - __m128i all[2][16], *in; - - for (i = 0; i < 2; i++) { - in = all[i]; - highbd_load_transpose_32bit_8x4(input, 16, in); - highbd_idct16x16_38_4col(in); - input += 4 * 16; - } - - for (i = 0; i < 16; i += 4) { - int j; - transpose_32bit_4x4(all[0] + i, out + 0); - transpose_32bit_4x4(all[1] + i, out + 4); - highbd_idct16x16_38_4col(out); - - for (j = 0; j < 16; ++j) { - highbd_write_buffer_4(dest + j * stride, out[j], bd); - } - dest += 4; - } - } -} - -void vpx_highbd_idct16x16_10_add_sse4_1(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i; - __m128i out[16]; - - if (bd == 8) { - __m128i in[16], l[16]; - - in[0] = load_pack_8_32bit(input + 0 * 16); - in[1] = load_pack_8_32bit(input + 1 * 16); - in[2] = load_pack_8_32bit(input + 2 * 16); - in[3] = load_pack_8_32bit(input + 3 * 16); - - idct16x16_10_pass1(in, l); - - for (i = 0; i < 16; i += 8) { - int j; - idct16x16_10_pass2(l + i, in); - - for (j = 0; j < 16; ++j) { - highbd_write_buffer_8(dest + j * stride, in[j], bd); - } - dest += 8; - } - } else { - __m128i all[2][16], *in; - - for (i = 0; i < 2; i++) { - in = all[i]; - highbd_load_transpose_32bit_4x4(input, 16, in); - highbd_idct16x16_10_4col(in); - input += 4 * 16; - } - - for (i = 0; i < 16; i += 4) { - int j; - transpose_32bit_4x4(&all[0][i], out); - highbd_idct16x16_10_4col(out); - - for (j = 0; j < 16; ++j) { - highbd_write_buffer_4(dest + j * stride, out[j], bd); - } - dest += 4; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct32x32_add_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct32x32_add_sse2.c deleted file mode 100644 index c710e899..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct32x32_add_sse2.c +++ /dev/null @@ -1,782 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/x86/highbd_inv_txfm_sse2.h" -#include "vpx_dsp/x86/inv_txfm_sse2.h" -#include "vpx_dsp/x86/transpose_sse2.h" -#include "vpx_dsp/x86/txfm_common_sse2.h" - -static INLINE void highbd_idct32_4x32_quarter_2_stage_4_to_6( - __m128i *const step1 /*step1[16]*/, __m128i *const out /*out[16]*/) { - __m128i step2[32]; - - // stage 4 - step2[8] = step1[8]; - step2[15] = step1[15]; - highbd_butterfly_sse2(step1[14], step1[9], cospi_24_64, cospi_8_64, &step2[9], - &step2[14]); - highbd_butterfly_sse2(step1[10], step1[13], cospi_8_64, cospi_24_64, - &step2[13], &step2[10]); - step2[11] = step1[11]; - step2[12] = step1[12]; - - // stage 5 - step1[8] = _mm_add_epi32(step2[8], step2[11]); - step1[9] = _mm_add_epi32(step2[9], step2[10]); - step1[10] = _mm_sub_epi32(step2[9], step2[10]); - step1[11] = _mm_sub_epi32(step2[8], step2[11]); - step1[12] = _mm_sub_epi32(step2[15], step2[12]); - step1[13] = _mm_sub_epi32(step2[14], step2[13]); - step1[14] = _mm_add_epi32(step2[14], step2[13]); - step1[15] = _mm_add_epi32(step2[15], step2[12]); - - // stage 6 - out[8] = step1[8]; - out[9] = step1[9]; - highbd_butterfly_sse2(step1[13], step1[10], cospi_16_64, cospi_16_64, - &out[10], &out[13]); - highbd_butterfly_sse2(step1[12], step1[11], cospi_16_64, cospi_16_64, - &out[11], &out[12]); - out[14] = step1[14]; - out[15] = step1[15]; -} - -static INLINE void highbd_idct32_4x32_quarter_3_4_stage_4_to_7( - __m128i *const step1 /*step1[32]*/, __m128i *const out /*out[32]*/) { - __m128i step2[32]; - - // stage 4 - step2[16] = _mm_add_epi32(step1[16], step1[19]); - step2[17] = _mm_add_epi32(step1[17], step1[18]); - step2[18] = _mm_sub_epi32(step1[17], step1[18]); - step2[19] = _mm_sub_epi32(step1[16], step1[19]); - step2[20] = _mm_sub_epi32(step1[20], step1[23]); // step2[20] = -step2[20] - step2[21] = _mm_sub_epi32(step1[21], step1[22]); // step2[21] = -step2[21] - step2[22] = _mm_add_epi32(step1[21], step1[22]); - step2[23] = _mm_add_epi32(step1[20], step1[23]); - - step2[24] = _mm_add_epi32(step1[27], step1[24]); - step2[25] = _mm_add_epi32(step1[26], step1[25]); - step2[26] = _mm_sub_epi32(step1[26], step1[25]); // step2[26] = -step2[26] - step2[27] = _mm_sub_epi32(step1[27], step1[24]); // step2[27] = -step2[27] - step2[28] = _mm_sub_epi32(step1[31], step1[28]); - step2[29] = _mm_sub_epi32(step1[30], step1[29]); - step2[30] = _mm_add_epi32(step1[29], step1[30]); - step2[31] = _mm_add_epi32(step1[28], step1[31]); - - // stage 5 - step1[16] = step2[16]; - step1[17] = step2[17]; - highbd_butterfly_sse2(step2[29], step2[18], cospi_24_64, cospi_8_64, - &step1[18], &step1[29]); - highbd_butterfly_sse2(step2[28], step2[19], cospi_24_64, cospi_8_64, - &step1[19], &step1[28]); - highbd_butterfly_sse2(step2[20], step2[27], cospi_8_64, cospi_24_64, - &step1[27], &step1[20]); - highbd_butterfly_sse2(step2[21], step2[26], cospi_8_64, cospi_24_64, - &step1[26], &step1[21]); - step1[22] = step2[22]; - step1[23] = step2[23]; - step1[24] = step2[24]; - step1[25] = step2[25]; - step1[30] = step2[30]; - step1[31] = step2[31]; - - // stage 6 - step2[16] = _mm_add_epi32(step1[16], step1[23]); - step2[17] = _mm_add_epi32(step1[17], step1[22]); - step2[18] = _mm_add_epi32(step1[18], step1[21]); - step2[19] = _mm_add_epi32(step1[19], step1[20]); - step2[20] = _mm_sub_epi32(step1[19], step1[20]); - step2[21] = _mm_sub_epi32(step1[18], step1[21]); - step2[22] = _mm_sub_epi32(step1[17], step1[22]); - step2[23] = _mm_sub_epi32(step1[16], step1[23]); - - step2[24] = _mm_sub_epi32(step1[31], step1[24]); - step2[25] = _mm_sub_epi32(step1[30], step1[25]); - step2[26] = _mm_sub_epi32(step1[29], step1[26]); - step2[27] = _mm_sub_epi32(step1[28], step1[27]); - step2[28] = _mm_add_epi32(step1[27], step1[28]); - step2[29] = _mm_add_epi32(step1[26], step1[29]); - step2[30] = _mm_add_epi32(step1[25], step1[30]); - step2[31] = _mm_add_epi32(step1[24], step1[31]); - - // stage 7 - out[16] = step2[16]; - out[17] = step2[17]; - out[18] = step2[18]; - out[19] = step2[19]; - highbd_butterfly_sse2(step2[27], step2[20], cospi_16_64, cospi_16_64, - &out[20], &out[27]); - highbd_butterfly_sse2(step2[26], step2[21], cospi_16_64, cospi_16_64, - &out[21], &out[26]); - highbd_butterfly_sse2(step2[25], step2[22], cospi_16_64, cospi_16_64, - &out[22], &out[25]); - highbd_butterfly_sse2(step2[24], step2[23], cospi_16_64, cospi_16_64, - &out[23], &out[24]); - out[28] = step2[28]; - out[29] = step2[29]; - out[30] = step2[30]; - out[31] = step2[31]; -} - -// Group the coefficient calculation into smaller functions to prevent stack -// spillover in 32x32 idct optimizations: -// quarter_1: 0-7 -// quarter_2: 8-15 -// quarter_3_4: 16-23, 24-31 - -// For each 4x32 block __m128i in[32], -// Input with index, 0, 4, 8, 12, 16, 20, 24, 28 -// output pixels: 0-7 in __m128i out[32] -static INLINE void highbd_idct32_1024_4x32_quarter_1( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[8]*/) { - __m128i step1[8], step2[8]; - - // stage 3 - highbd_butterfly_sse2(in[4], in[28], cospi_28_64, cospi_4_64, &step1[4], - &step1[7]); - highbd_butterfly_sse2(in[20], in[12], cospi_12_64, cospi_20_64, &step1[5], - &step1[6]); - - // stage 4 - highbd_butterfly_sse2(in[0], in[16], cospi_16_64, cospi_16_64, &step2[1], - &step2[0]); - highbd_butterfly_sse2(in[8], in[24], cospi_24_64, cospi_8_64, &step2[2], - &step2[3]); - step2[4] = _mm_add_epi32(step1[4], step1[5]); - step2[5] = _mm_sub_epi32(step1[4], step1[5]); - step2[6] = _mm_sub_epi32(step1[7], step1[6]); - step2[7] = _mm_add_epi32(step1[7], step1[6]); - - // stage 5 - step1[0] = _mm_add_epi32(step2[0], step2[3]); - step1[1] = _mm_add_epi32(step2[1], step2[2]); - step1[2] = _mm_sub_epi32(step2[1], step2[2]); - step1[3] = _mm_sub_epi32(step2[0], step2[3]); - step1[4] = step2[4]; - highbd_butterfly_sse2(step2[6], step2[5], cospi_16_64, cospi_16_64, &step1[5], - &step1[6]); - step1[7] = step2[7]; - - // stage 6 - out[0] = _mm_add_epi32(step1[0], step1[7]); - out[1] = _mm_add_epi32(step1[1], step1[6]); - out[2] = _mm_add_epi32(step1[2], step1[5]); - out[3] = _mm_add_epi32(step1[3], step1[4]); - out[4] = _mm_sub_epi32(step1[3], step1[4]); - out[5] = _mm_sub_epi32(step1[2], step1[5]); - out[6] = _mm_sub_epi32(step1[1], step1[6]); - out[7] = _mm_sub_epi32(step1[0], step1[7]); -} - -// For each 4x32 block __m128i in[32], -// Input with index, 2, 6, 10, 14, 18, 22, 26, 30 -// output pixels: 8-15 in __m128i out[32] -static INLINE void highbd_idct32_1024_4x32_quarter_2( - const __m128i *in /*in[32]*/, __m128i *out /*out[16]*/) { - __m128i step1[32], step2[32]; - - // stage 2 - highbd_butterfly_sse2(in[2], in[30], cospi_30_64, cospi_2_64, &step2[8], - &step2[15]); - highbd_butterfly_sse2(in[18], in[14], cospi_14_64, cospi_18_64, &step2[9], - &step2[14]); - highbd_butterfly_sse2(in[10], in[22], cospi_22_64, cospi_10_64, &step2[10], - &step2[13]); - highbd_butterfly_sse2(in[26], in[6], cospi_6_64, cospi_26_64, &step2[11], - &step2[12]); - - // stage 3 - step1[8] = _mm_add_epi32(step2[8], step2[9]); - step1[9] = _mm_sub_epi32(step2[8], step2[9]); - step1[14] = _mm_sub_epi32(step2[15], step2[14]); - step1[15] = _mm_add_epi32(step2[15], step2[14]); - step1[10] = _mm_sub_epi32(step2[10], step2[11]); // step1[10] = -step1[10] - step1[11] = _mm_add_epi32(step2[10], step2[11]); - step1[12] = _mm_add_epi32(step2[13], step2[12]); - step1[13] = _mm_sub_epi32(step2[13], step2[12]); // step1[13] = -step1[13] - - highbd_idct32_4x32_quarter_2_stage_4_to_6(step1, out); -} - -static INLINE void highbd_idct32_1024_4x32_quarter_1_2( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i temp[16]; - highbd_idct32_1024_4x32_quarter_1(in, temp); - highbd_idct32_1024_4x32_quarter_2(in, temp); - // stage 7 - highbd_add_sub_butterfly(temp, out, 16); -} - -// For each 4x32 block __m128i in[32], -// Input with odd index, -// 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 -// output pixels: 16-23, 24-31 in __m128i out[32] -static INLINE void highbd_idct32_1024_4x32_quarter_3_4( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i step1[32], step2[32]; - - // stage 1 - highbd_butterfly_sse2(in[1], in[31], cospi_31_64, cospi_1_64, &step1[16], - &step1[31]); - highbd_butterfly_sse2(in[17], in[15], cospi_15_64, cospi_17_64, &step1[17], - &step1[30]); - highbd_butterfly_sse2(in[9], in[23], cospi_23_64, cospi_9_64, &step1[18], - &step1[29]); - highbd_butterfly_sse2(in[25], in[7], cospi_7_64, cospi_25_64, &step1[19], - &step1[28]); - - highbd_butterfly_sse2(in[5], in[27], cospi_27_64, cospi_5_64, &step1[20], - &step1[27]); - highbd_butterfly_sse2(in[21], in[11], cospi_11_64, cospi_21_64, &step1[21], - &step1[26]); - - highbd_butterfly_sse2(in[13], in[19], cospi_19_64, cospi_13_64, &step1[22], - &step1[25]); - highbd_butterfly_sse2(in[29], in[3], cospi_3_64, cospi_29_64, &step1[23], - &step1[24]); - - // stage 2 - step2[16] = _mm_add_epi32(step1[16], step1[17]); - step2[17] = _mm_sub_epi32(step1[16], step1[17]); - step2[18] = _mm_sub_epi32(step1[18], step1[19]); // step2[18] = -step2[18] - step2[19] = _mm_add_epi32(step1[18], step1[19]); - step2[20] = _mm_add_epi32(step1[20], step1[21]); - step2[21] = _mm_sub_epi32(step1[20], step1[21]); - step2[22] = _mm_sub_epi32(step1[22], step1[23]); // step2[22] = -step2[22] - step2[23] = _mm_add_epi32(step1[22], step1[23]); - - step2[24] = _mm_add_epi32(step1[25], step1[24]); - step2[25] = _mm_sub_epi32(step1[25], step1[24]); // step2[25] = -step2[25] - step2[26] = _mm_sub_epi32(step1[27], step1[26]); - step2[27] = _mm_add_epi32(step1[27], step1[26]); - step2[28] = _mm_add_epi32(step1[29], step1[28]); - step2[29] = _mm_sub_epi32(step1[29], step1[28]); // step2[29] = -step2[29] - step2[30] = _mm_sub_epi32(step1[31], step1[30]); - step2[31] = _mm_add_epi32(step1[31], step1[30]); - - // stage 3 - step1[16] = step2[16]; - step1[31] = step2[31]; - highbd_butterfly_sse2(step2[30], step2[17], cospi_28_64, cospi_4_64, - &step1[17], &step1[30]); - highbd_butterfly_sse2(step2[18], step2[29], cospi_4_64, cospi_28_64, - &step1[29], &step1[18]); - step1[19] = step2[19]; - step1[20] = step2[20]; - highbd_butterfly_sse2(step2[26], step2[21], cospi_12_64, cospi_20_64, - &step1[21], &step1[26]); - highbd_butterfly_sse2(step2[22], step2[25], cospi_20_64, cospi_12_64, - &step1[25], &step1[22]); - step1[23] = step2[23]; - step1[24] = step2[24]; - step1[27] = step2[27]; - step1[28] = step2[28]; - - highbd_idct32_4x32_quarter_3_4_stage_4_to_7(step1, out); -} - -static void highbd_idct32_1024_4x32(__m128i *const io /*io[32]*/) { - __m128i temp[32]; - - highbd_idct32_1024_4x32_quarter_1_2(io, temp); - highbd_idct32_1024_4x32_quarter_3_4(io, temp); - // final stage - highbd_add_sub_butterfly(temp, io, 32); -} - -void vpx_highbd_idct32x32_1024_add_sse2(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i, j; - - if (bd == 8) { - __m128i col[4][32], io[32]; - - // rows - for (i = 0; i < 4; i++) { - highbd_load_pack_transpose_32bit_8x8(&input[0], 32, &io[0]); - highbd_load_pack_transpose_32bit_8x8(&input[8], 32, &io[8]); - highbd_load_pack_transpose_32bit_8x8(&input[16], 32, &io[16]); - highbd_load_pack_transpose_32bit_8x8(&input[24], 32, &io[24]); - idct32_1024_8x32(io, col[i]); - input += 32 << 3; - } - - // columns - for (i = 0; i < 32; i += 8) { - // Transpose 32x8 block to 8x32 block - transpose_16bit_8x8(col[0] + i, io); - transpose_16bit_8x8(col[1] + i, io + 8); - transpose_16bit_8x8(col[2] + i, io + 16); - transpose_16bit_8x8(col[3] + i, io + 24); - idct32_1024_8x32(io, io); - for (j = 0; j < 32; ++j) { - highbd_write_buffer_8(dest + j * stride, io[j], bd); - } - dest += 8; - } - } else { - __m128i all[8][32], out[32], *in; - - for (i = 0; i < 8; i++) { - in = all[i]; - highbd_load_transpose_32bit_8x4(&input[0], 32, &in[0]); - highbd_load_transpose_32bit_8x4(&input[8], 32, &in[8]); - highbd_load_transpose_32bit_8x4(&input[16], 32, &in[16]); - highbd_load_transpose_32bit_8x4(&input[24], 32, &in[24]); - highbd_idct32_1024_4x32(in); - input += 4 * 32; - } - - for (i = 0; i < 32; i += 4) { - transpose_32bit_4x4(all[0] + i, out + 0); - transpose_32bit_4x4(all[1] + i, out + 4); - transpose_32bit_4x4(all[2] + i, out + 8); - transpose_32bit_4x4(all[3] + i, out + 12); - transpose_32bit_4x4(all[4] + i, out + 16); - transpose_32bit_4x4(all[5] + i, out + 20); - transpose_32bit_4x4(all[6] + i, out + 24); - transpose_32bit_4x4(all[7] + i, out + 28); - highbd_idct32_1024_4x32(out); - - for (j = 0; j < 32; ++j) { - highbd_write_buffer_4(dest + j * stride, out[j], bd); - } - dest += 4; - } - } -} - -// ----------------------------------------------------------------------------- - -// For each 4x32 block __m128i in[32], -// Input with index, 0, 4, 8, 12 -// output pixels: 0-7 in __m128i out[32] -static INLINE void highbd_idct32_135_4x32_quarter_1( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[8]*/) { - __m128i step1[8], step2[8]; - - // stage 3 - highbd_partial_butterfly_sse2(in[4], cospi_28_64, cospi_4_64, &step1[4], - &step1[7]); - highbd_partial_butterfly_neg_sse2(in[12], cospi_12_64, cospi_20_64, &step1[5], - &step1[6]); - - // stage 4 - highbd_partial_butterfly_sse2(in[0], cospi_16_64, cospi_16_64, &step2[1], - &step2[0]); - highbd_partial_butterfly_sse2(in[8], cospi_24_64, cospi_8_64, &step2[2], - &step2[3]); - step2[4] = _mm_add_epi32(step1[4], step1[5]); - step2[5] = _mm_sub_epi32(step1[4], step1[5]); - step2[6] = _mm_sub_epi32(step1[7], step1[6]); - step2[7] = _mm_add_epi32(step1[7], step1[6]); - - // stage 5 - step1[0] = _mm_add_epi32(step2[0], step2[3]); - step1[1] = _mm_add_epi32(step2[1], step2[2]); - step1[2] = _mm_sub_epi32(step2[1], step2[2]); - step1[3] = _mm_sub_epi32(step2[0], step2[3]); - step1[4] = step2[4]; - highbd_butterfly_sse2(step2[6], step2[5], cospi_16_64, cospi_16_64, &step1[5], - &step1[6]); - step1[7] = step2[7]; - - // stage 6 - out[0] = _mm_add_epi32(step1[0], step1[7]); - out[1] = _mm_add_epi32(step1[1], step1[6]); - out[2] = _mm_add_epi32(step1[2], step1[5]); - out[3] = _mm_add_epi32(step1[3], step1[4]); - out[4] = _mm_sub_epi32(step1[3], step1[4]); - out[5] = _mm_sub_epi32(step1[2], step1[5]); - out[6] = _mm_sub_epi32(step1[1], step1[6]); - out[7] = _mm_sub_epi32(step1[0], step1[7]); -} - -// For each 4x32 block __m128i in[32], -// Input with index, 2, 6, 10, 14 -// output pixels: 8-15 in __m128i out[32] -static INLINE void highbd_idct32_135_4x32_quarter_2( - const __m128i *in /*in[32]*/, __m128i *out /*out[16]*/) { - __m128i step1[32], step2[32]; - - // stage 2 - highbd_partial_butterfly_sse2(in[2], cospi_30_64, cospi_2_64, &step2[8], - &step2[15]); - highbd_partial_butterfly_neg_sse2(in[14], cospi_14_64, cospi_18_64, &step2[9], - &step2[14]); - highbd_partial_butterfly_sse2(in[10], cospi_22_64, cospi_10_64, &step2[10], - &step2[13]); - highbd_partial_butterfly_neg_sse2(in[6], cospi_6_64, cospi_26_64, &step2[11], - &step2[12]); - - // stage 3 - step1[8] = _mm_add_epi32(step2[8], step2[9]); - step1[9] = _mm_sub_epi32(step2[8], step2[9]); - step1[14] = _mm_sub_epi32(step2[15], step2[14]); - step1[15] = _mm_add_epi32(step2[15], step2[14]); - step1[10] = _mm_sub_epi32(step2[10], step2[11]); // step1[10] = -step1[10] - step1[11] = _mm_add_epi32(step2[10], step2[11]); - step1[12] = _mm_add_epi32(step2[13], step2[12]); - step1[13] = _mm_sub_epi32(step2[13], step2[12]); // step1[13] = -step1[13] - - highbd_idct32_4x32_quarter_2_stage_4_to_6(step1, out); -} - -static INLINE void highbd_idct32_135_4x32_quarter_1_2( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i temp[16]; - highbd_idct32_135_4x32_quarter_1(in, temp); - highbd_idct32_135_4x32_quarter_2(in, temp); - // stage 7 - highbd_add_sub_butterfly(temp, out, 16); -} - -// For each 4x32 block __m128i in[32], -// Input with odd index, -// 1, 3, 5, 7, 9, 11, 13, 15 -// output pixels: 16-23, 24-31 in __m128i out[32] -static INLINE void highbd_idct32_135_4x32_quarter_3_4( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i step1[32], step2[32]; - - // stage 1 - highbd_partial_butterfly_sse2(in[1], cospi_31_64, cospi_1_64, &step1[16], - &step1[31]); - highbd_partial_butterfly_neg_sse2(in[15], cospi_15_64, cospi_17_64, - &step1[17], &step1[30]); - highbd_partial_butterfly_sse2(in[9], cospi_23_64, cospi_9_64, &step1[18], - &step1[29]); - highbd_partial_butterfly_neg_sse2(in[7], cospi_7_64, cospi_25_64, &step1[19], - &step1[28]); - - highbd_partial_butterfly_sse2(in[5], cospi_27_64, cospi_5_64, &step1[20], - &step1[27]); - highbd_partial_butterfly_neg_sse2(in[11], cospi_11_64, cospi_21_64, - &step1[21], &step1[26]); - - highbd_partial_butterfly_sse2(in[13], cospi_19_64, cospi_13_64, &step1[22], - &step1[25]); - highbd_partial_butterfly_neg_sse2(in[3], cospi_3_64, cospi_29_64, &step1[23], - &step1[24]); - - // stage 2 - step2[16] = _mm_add_epi32(step1[16], step1[17]); - step2[17] = _mm_sub_epi32(step1[16], step1[17]); - step2[18] = _mm_sub_epi32(step1[18], step1[19]); // step2[18] = -step2[18] - step2[19] = _mm_add_epi32(step1[18], step1[19]); - step2[20] = _mm_add_epi32(step1[20], step1[21]); - step2[21] = _mm_sub_epi32(step1[20], step1[21]); - step2[22] = _mm_sub_epi32(step1[22], step1[23]); // step2[22] = -step2[22] - step2[23] = _mm_add_epi32(step1[22], step1[23]); - - step2[24] = _mm_add_epi32(step1[25], step1[24]); - step2[25] = _mm_sub_epi32(step1[25], step1[24]); // step2[25] = -step2[25] - step2[26] = _mm_sub_epi32(step1[27], step1[26]); - step2[27] = _mm_add_epi32(step1[27], step1[26]); - step2[28] = _mm_add_epi32(step1[29], step1[28]); - step2[29] = _mm_sub_epi32(step1[29], step1[28]); // step2[29] = -step2[29] - step2[30] = _mm_sub_epi32(step1[31], step1[30]); - step2[31] = _mm_add_epi32(step1[31], step1[30]); - - // stage 3 - step1[16] = step2[16]; - step1[31] = step2[31]; - highbd_butterfly_sse2(step2[30], step2[17], cospi_28_64, cospi_4_64, - &step1[17], &step1[30]); - highbd_butterfly_sse2(step2[18], step2[29], cospi_4_64, cospi_28_64, - &step1[29], &step1[18]); - step1[19] = step2[19]; - step1[20] = step2[20]; - highbd_butterfly_sse2(step2[26], step2[21], cospi_12_64, cospi_20_64, - &step1[21], &step1[26]); - highbd_butterfly_sse2(step2[22], step2[25], cospi_20_64, cospi_12_64, - &step1[25], &step1[22]); - step1[23] = step2[23]; - step1[24] = step2[24]; - step1[27] = step2[27]; - step1[28] = step2[28]; - - highbd_idct32_4x32_quarter_3_4_stage_4_to_7(step1, out); -} - -static void highbd_idct32_135_4x32(__m128i *const io /*io[32]*/) { - __m128i temp[32]; - - highbd_idct32_135_4x32_quarter_1_2(io, temp); - highbd_idct32_135_4x32_quarter_3_4(io, temp); - // final stage - highbd_add_sub_butterfly(temp, io, 32); -} - -void vpx_highbd_idct32x32_135_add_sse2(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i, j; - - if (bd == 8) { - __m128i col[2][32], in[32], out[32]; - - for (i = 16; i < 32; i++) { - in[i] = _mm_setzero_si128(); - } - - // rows - for (i = 0; i < 2; i++) { - highbd_load_pack_transpose_32bit_8x8(&input[0], 32, &in[0]); - highbd_load_pack_transpose_32bit_8x8(&input[8], 32, &in[8]); - idct32_1024_8x32(in, col[i]); - input += 32 << 3; - } - - // columns - for (i = 0; i < 32; i += 8) { - transpose_16bit_8x8(col[0] + i, in); - transpose_16bit_8x8(col[1] + i, in + 8); - idct32_1024_8x32(in, out); - for (j = 0; j < 32; ++j) { - highbd_write_buffer_8(dest + j * stride, out[j], bd); - } - dest += 8; - } - } else { - __m128i all[8][32], out[32], *in; - - for (i = 0; i < 4; i++) { - in = all[i]; - highbd_load_transpose_32bit_8x4(&input[0], 32, &in[0]); - highbd_load_transpose_32bit_8x4(&input[8], 32, &in[8]); - highbd_idct32_135_4x32(in); - input += 4 * 32; - } - - for (i = 0; i < 32; i += 4) { - transpose_32bit_4x4(all[0] + i, out + 0); - transpose_32bit_4x4(all[1] + i, out + 4); - transpose_32bit_4x4(all[2] + i, out + 8); - transpose_32bit_4x4(all[3] + i, out + 12); - highbd_idct32_135_4x32(out); - - for (j = 0; j < 32; ++j) { - highbd_write_buffer_4(dest + j * stride, out[j], bd); - } - dest += 4; - } - } -} - -// ----------------------------------------------------------------------------- - -// For each 4x32 block __m128i in[32], -// Input with index, 0, 4 -// output pixels: 0-7 in __m128i out[32] -static INLINE void highbd_idct32_34_4x32_quarter_1( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[8]*/) { - __m128i step1[8], step2[8]; - - // stage 3 - highbd_partial_butterfly_sse2(in[4], cospi_28_64, cospi_4_64, &step1[4], - &step1[7]); - - // stage 4 - highbd_partial_butterfly_sse2(in[0], cospi_16_64, cospi_16_64, &step2[1], - &step2[0]); - step2[4] = step1[4]; - step2[5] = step1[4]; - step2[6] = step1[7]; - step2[7] = step1[7]; - - // stage 5 - step1[0] = step2[0]; - step1[1] = step2[1]; - step1[2] = step2[1]; - step1[3] = step2[0]; - step1[4] = step2[4]; - highbd_butterfly_sse2(step2[6], step2[5], cospi_16_64, cospi_16_64, &step1[5], - &step1[6]); - step1[7] = step2[7]; - - // stage 6 - out[0] = _mm_add_epi32(step1[0], step1[7]); - out[1] = _mm_add_epi32(step1[1], step1[6]); - out[2] = _mm_add_epi32(step1[2], step1[5]); - out[3] = _mm_add_epi32(step1[3], step1[4]); - out[4] = _mm_sub_epi32(step1[3], step1[4]); - out[5] = _mm_sub_epi32(step1[2], step1[5]); - out[6] = _mm_sub_epi32(step1[1], step1[6]); - out[7] = _mm_sub_epi32(step1[0], step1[7]); -} - -// For each 4x32 block __m128i in[32], -// Input with index, 2, 6 -// output pixels: 8-15 in __m128i out[32] -static INLINE void highbd_idct32_34_4x32_quarter_2(const __m128i *in /*in[32]*/, - __m128i *out /*out[16]*/) { - __m128i step1[32], step2[32]; - - // stage 2 - highbd_partial_butterfly_sse2(in[2], cospi_30_64, cospi_2_64, &step2[8], - &step2[15]); - highbd_partial_butterfly_neg_sse2(in[6], cospi_6_64, cospi_26_64, &step2[11], - &step2[12]); - - // stage 3 - step1[8] = step2[8]; - step1[9] = step2[8]; - step1[14] = step2[15]; - step1[15] = step2[15]; - step1[10] = step2[11]; - step1[11] = step2[11]; - step1[12] = step2[12]; - step1[13] = step2[12]; - - step1[10] = - _mm_sub_epi32(_mm_setzero_si128(), step1[10]); // step1[10] = -step1[10] - step1[13] = - _mm_sub_epi32(_mm_setzero_si128(), step1[13]); // step1[13] = -step1[13] - highbd_idct32_4x32_quarter_2_stage_4_to_6(step1, out); -} - -static INLINE void highbd_idct32_34_4x32_quarter_1_2( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i temp[16]; - highbd_idct32_34_4x32_quarter_1(in, temp); - highbd_idct32_34_4x32_quarter_2(in, temp); - // stage 7 - highbd_add_sub_butterfly(temp, out, 16); -} - -// For each 4x32 block __m128i in[32], -// Input with odd index, -// 1, 3, 5, 7 -// output pixels: 16-23, 24-31 in __m128i out[32] -static INLINE void highbd_idct32_34_4x32_quarter_3_4( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i step1[32], step2[32]; - - // stage 1 - highbd_partial_butterfly_sse2(in[1], cospi_31_64, cospi_1_64, &step1[16], - &step1[31]); - highbd_partial_butterfly_neg_sse2(in[7], cospi_7_64, cospi_25_64, &step1[19], - &step1[28]); - - highbd_partial_butterfly_sse2(in[5], cospi_27_64, cospi_5_64, &step1[20], - &step1[27]); - highbd_partial_butterfly_neg_sse2(in[3], cospi_3_64, cospi_29_64, &step1[23], - &step1[24]); - - // stage 2 - step2[16] = step1[16]; - step2[17] = step1[16]; - step2[18] = step1[19]; - step2[19] = step1[19]; - step2[20] = step1[20]; - step2[21] = step1[20]; - step2[22] = step1[23]; - step2[23] = step1[23]; - - step2[24] = step1[24]; - step2[25] = step1[24]; - step2[26] = step1[27]; - step2[27] = step1[27]; - step2[28] = step1[28]; - step2[29] = step1[28]; - step2[30] = step1[31]; - step2[31] = step1[31]; - - // stage 3 - step2[18] = - _mm_sub_epi32(_mm_setzero_si128(), step2[18]); // step2[18] = -step2[18] - step2[22] = - _mm_sub_epi32(_mm_setzero_si128(), step2[22]); // step2[22] = -step2[22] - step2[25] = - _mm_sub_epi32(_mm_setzero_si128(), step2[25]); // step2[25] = -step2[25] - step2[29] = - _mm_sub_epi32(_mm_setzero_si128(), step2[29]); // step2[29] = -step2[29] - step1[16] = step2[16]; - step1[31] = step2[31]; - highbd_butterfly_sse2(step2[30], step2[17], cospi_28_64, cospi_4_64, - &step1[17], &step1[30]); - highbd_butterfly_sse2(step2[18], step2[29], cospi_4_64, cospi_28_64, - &step1[29], &step1[18]); - step1[19] = step2[19]; - step1[20] = step2[20]; - highbd_butterfly_sse2(step2[26], step2[21], cospi_12_64, cospi_20_64, - &step1[21], &step1[26]); - highbd_butterfly_sse2(step2[22], step2[25], cospi_20_64, cospi_12_64, - &step1[25], &step1[22]); - step1[23] = step2[23]; - step1[24] = step2[24]; - step1[27] = step2[27]; - step1[28] = step2[28]; - - highbd_idct32_4x32_quarter_3_4_stage_4_to_7(step1, out); -} - -static void highbd_idct32_34_4x32(__m128i *const io /*io[32]*/) { - __m128i temp[32]; - - highbd_idct32_34_4x32_quarter_1_2(io, temp); - highbd_idct32_34_4x32_quarter_3_4(io, temp); - // final stage - highbd_add_sub_butterfly(temp, io, 32); -} - -void vpx_highbd_idct32x32_34_add_sse2(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i, j; - - if (bd == 8) { - __m128i col[32], in[32], out[32]; - - // rows - highbd_load_pack_transpose_32bit_8x8(&input[0], 32, &in[0]); - idct32_34_8x32_sse2(in, col); - - // columns - for (i = 0; i < 32; i += 8) { - transpose_16bit_8x8(col + i, in); - idct32_34_8x32_sse2(in, out); - for (j = 0; j < 32; ++j) { - highbd_write_buffer_8(dest + j * stride, out[j], bd); - } - dest += 8; - } - } else { - __m128i all[8][32], out[32], *in; - - for (i = 0; i < 4; i++) { - in = all[i]; - highbd_load_transpose_32bit_8x4(&input[0], 32, &in[0]); - highbd_load_transpose_32bit_8x4(&input[8], 32, &in[8]); - highbd_idct32_34_4x32(in); - input += 4 * 32; - } - - for (i = 0; i < 32; i += 4) { - transpose_32bit_4x4(all[0] + i, out + 0); - transpose_32bit_4x4(all[1] + i, out + 4); - transpose_32bit_4x4(all[2] + i, out + 8); - transpose_32bit_4x4(all[3] + i, out + 12); - highbd_idct32_34_4x32(out); - - for (j = 0; j < 32; ++j) { - highbd_write_buffer_4(dest + j * stride, out[j], bd); - } - dest += 4; - } - } -} - -void vpx_highbd_idct32x32_1_add_sse2(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - highbd_idct_1_add_kernel(input, dest, stride, bd, 32); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct32x32_add_sse4.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct32x32_add_sse4.c deleted file mode 100644 index 2d0a53ac..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct32x32_add_sse4.c +++ /dev/null @@ -1,765 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // SSE4.1 - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/x86/highbd_inv_txfm_sse2.h" -#include "vpx_dsp/x86/highbd_inv_txfm_sse4.h" -#include "vpx_dsp/x86/inv_txfm_sse2.h" -#include "vpx_dsp/x86/inv_txfm_ssse3.h" -#include "vpx_dsp/x86/transpose_sse2.h" -#include "vpx_dsp/x86/txfm_common_sse2.h" - -static INLINE void highbd_idct32_4x32_quarter_2_stage_4_to_6( - __m128i *const step1 /*step1[16]*/, __m128i *const out /*out[16]*/) { - __m128i step2[32]; - - // stage 4 - step2[8] = step1[8]; - step2[15] = step1[15]; - highbd_butterfly_sse4_1(step1[14], step1[9], cospi_24_64, cospi_8_64, - &step2[9], &step2[14]); - highbd_butterfly_sse4_1(step1[13], step1[10], -cospi_8_64, cospi_24_64, - &step2[10], &step2[13]); - step2[11] = step1[11]; - step2[12] = step1[12]; - - // stage 5 - step1[8] = _mm_add_epi32(step2[8], step2[11]); - step1[9] = _mm_add_epi32(step2[9], step2[10]); - step1[10] = _mm_sub_epi32(step2[9], step2[10]); - step1[11] = _mm_sub_epi32(step2[8], step2[11]); - step1[12] = _mm_sub_epi32(step2[15], step2[12]); - step1[13] = _mm_sub_epi32(step2[14], step2[13]); - step1[14] = _mm_add_epi32(step2[14], step2[13]); - step1[15] = _mm_add_epi32(step2[15], step2[12]); - - // stage 6 - out[8] = step1[8]; - out[9] = step1[9]; - highbd_butterfly_sse4_1(step1[13], step1[10], cospi_16_64, cospi_16_64, - &out[10], &out[13]); - highbd_butterfly_sse4_1(step1[12], step1[11], cospi_16_64, cospi_16_64, - &out[11], &out[12]); - out[14] = step1[14]; - out[15] = step1[15]; -} - -static INLINE void highbd_idct32_4x32_quarter_3_4_stage_4_to_7( - __m128i *const step1 /*step1[32]*/, __m128i *const out /*out[32]*/) { - __m128i step2[32]; - - // stage 4 - step2[16] = _mm_add_epi32(step1[16], step1[19]); - step2[17] = _mm_add_epi32(step1[17], step1[18]); - step2[18] = _mm_sub_epi32(step1[17], step1[18]); - step2[19] = _mm_sub_epi32(step1[16], step1[19]); - step2[20] = _mm_sub_epi32(step1[23], step1[20]); - step2[21] = _mm_sub_epi32(step1[22], step1[21]); - step2[22] = _mm_add_epi32(step1[22], step1[21]); - step2[23] = _mm_add_epi32(step1[23], step1[20]); - - step2[24] = _mm_add_epi32(step1[24], step1[27]); - step2[25] = _mm_add_epi32(step1[25], step1[26]); - step2[26] = _mm_sub_epi32(step1[25], step1[26]); - step2[27] = _mm_sub_epi32(step1[24], step1[27]); - step2[28] = _mm_sub_epi32(step1[31], step1[28]); - step2[29] = _mm_sub_epi32(step1[30], step1[29]); - step2[30] = _mm_add_epi32(step1[29], step1[30]); - step2[31] = _mm_add_epi32(step1[28], step1[31]); - - // stage 5 - step1[16] = step2[16]; - step1[17] = step2[17]; - highbd_butterfly_sse4_1(step2[29], step2[18], cospi_24_64, cospi_8_64, - &step1[18], &step1[29]); - highbd_butterfly_sse4_1(step2[28], step2[19], cospi_24_64, cospi_8_64, - &step1[19], &step1[28]); - highbd_butterfly_sse4_1(step2[27], step2[20], -cospi_8_64, cospi_24_64, - &step1[20], &step1[27]); - highbd_butterfly_sse4_1(step2[26], step2[21], -cospi_8_64, cospi_24_64, - &step1[21], &step1[26]); - step1[22] = step2[22]; - step1[23] = step2[23]; - step1[24] = step2[24]; - step1[25] = step2[25]; - step1[30] = step2[30]; - step1[31] = step2[31]; - - // stage 6 - step2[16] = _mm_add_epi32(step1[16], step1[23]); - step2[17] = _mm_add_epi32(step1[17], step1[22]); - step2[18] = _mm_add_epi32(step1[18], step1[21]); - step2[19] = _mm_add_epi32(step1[19], step1[20]); - step2[20] = _mm_sub_epi32(step1[19], step1[20]); - step2[21] = _mm_sub_epi32(step1[18], step1[21]); - step2[22] = _mm_sub_epi32(step1[17], step1[22]); - step2[23] = _mm_sub_epi32(step1[16], step1[23]); - - step2[24] = _mm_sub_epi32(step1[31], step1[24]); - step2[25] = _mm_sub_epi32(step1[30], step1[25]); - step2[26] = _mm_sub_epi32(step1[29], step1[26]); - step2[27] = _mm_sub_epi32(step1[28], step1[27]); - step2[28] = _mm_add_epi32(step1[27], step1[28]); - step2[29] = _mm_add_epi32(step1[26], step1[29]); - step2[30] = _mm_add_epi32(step1[25], step1[30]); - step2[31] = _mm_add_epi32(step1[24], step1[31]); - - // stage 7 - out[16] = step2[16]; - out[17] = step2[17]; - out[18] = step2[18]; - out[19] = step2[19]; - highbd_butterfly_sse4_1(step2[27], step2[20], cospi_16_64, cospi_16_64, - &out[20], &out[27]); - highbd_butterfly_sse4_1(step2[26], step2[21], cospi_16_64, cospi_16_64, - &out[21], &out[26]); - highbd_butterfly_sse4_1(step2[25], step2[22], cospi_16_64, cospi_16_64, - &out[22], &out[25]); - highbd_butterfly_sse4_1(step2[24], step2[23], cospi_16_64, cospi_16_64, - &out[23], &out[24]); - out[28] = step2[28]; - out[29] = step2[29]; - out[30] = step2[30]; - out[31] = step2[31]; -} - -// Group the coefficient calculation into smaller functions to prevent stack -// spillover in 32x32 idct optimizations: -// quarter_1: 0-7 -// quarter_2: 8-15 -// quarter_3_4: 16-23, 24-31 - -// For each 4x32 block __m128i in[32], -// Input with index, 0, 4, 8, 12, 16, 20, 24, 28 -// output pixels: 0-7 in __m128i out[32] -static INLINE void highbd_idct32_1024_4x32_quarter_1( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[8]*/) { - __m128i step1[8], step2[8]; - - // stage 3 - highbd_butterfly_sse4_1(in[4], in[28], cospi_28_64, cospi_4_64, &step1[4], - &step1[7]); - highbd_butterfly_sse4_1(in[20], in[12], cospi_12_64, cospi_20_64, &step1[5], - &step1[6]); - - // stage 4 - highbd_butterfly_sse4_1(in[0], in[16], cospi_16_64, cospi_16_64, &step2[1], - &step2[0]); - highbd_butterfly_sse4_1(in[8], in[24], cospi_24_64, cospi_8_64, &step2[2], - &step2[3]); - step2[4] = _mm_add_epi32(step1[4], step1[5]); - step2[5] = _mm_sub_epi32(step1[4], step1[5]); - step2[6] = _mm_sub_epi32(step1[7], step1[6]); - step2[7] = _mm_add_epi32(step1[7], step1[6]); - - // stage 5 - step1[0] = _mm_add_epi32(step2[0], step2[3]); - step1[1] = _mm_add_epi32(step2[1], step2[2]); - step1[2] = _mm_sub_epi32(step2[1], step2[2]); - step1[3] = _mm_sub_epi32(step2[0], step2[3]); - step1[4] = step2[4]; - highbd_butterfly_sse4_1(step2[6], step2[5], cospi_16_64, cospi_16_64, - &step1[5], &step1[6]); - step1[7] = step2[7]; - - // stage 6 - out[0] = _mm_add_epi32(step1[0], step1[7]); - out[1] = _mm_add_epi32(step1[1], step1[6]); - out[2] = _mm_add_epi32(step1[2], step1[5]); - out[3] = _mm_add_epi32(step1[3], step1[4]); - out[4] = _mm_sub_epi32(step1[3], step1[4]); - out[5] = _mm_sub_epi32(step1[2], step1[5]); - out[6] = _mm_sub_epi32(step1[1], step1[6]); - out[7] = _mm_sub_epi32(step1[0], step1[7]); -} - -// For each 4x32 block __m128i in[32], -// Input with index, 2, 6, 10, 14, 18, 22, 26, 30 -// output pixels: 8-15 in __m128i out[32] -static INLINE void highbd_idct32_1024_4x32_quarter_2( - const __m128i *in /*in[32]*/, __m128i *out /*out[16]*/) { - __m128i step1[32], step2[32]; - - // stage 2 - highbd_butterfly_sse4_1(in[2], in[30], cospi_30_64, cospi_2_64, &step2[8], - &step2[15]); - highbd_butterfly_sse4_1(in[18], in[14], cospi_14_64, cospi_18_64, &step2[9], - &step2[14]); - highbd_butterfly_sse4_1(in[10], in[22], cospi_22_64, cospi_10_64, &step2[10], - &step2[13]); - highbd_butterfly_sse4_1(in[26], in[6], cospi_6_64, cospi_26_64, &step2[11], - &step2[12]); - - // stage 3 - step1[8] = _mm_add_epi32(step2[8], step2[9]); - step1[9] = _mm_sub_epi32(step2[8], step2[9]); - step1[14] = _mm_sub_epi32(step2[15], step2[14]); - step1[15] = _mm_add_epi32(step2[15], step2[14]); - step1[10] = _mm_sub_epi32(step2[11], step2[10]); - step1[11] = _mm_add_epi32(step2[11], step2[10]); - step1[12] = _mm_add_epi32(step2[12], step2[13]); - step1[13] = _mm_sub_epi32(step2[12], step2[13]); - - highbd_idct32_4x32_quarter_2_stage_4_to_6(step1, out); -} - -static INLINE void highbd_idct32_1024_4x32_quarter_1_2( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i temp[16]; - highbd_idct32_1024_4x32_quarter_1(in, temp); - highbd_idct32_1024_4x32_quarter_2(in, temp); - // stage 7 - highbd_add_sub_butterfly(temp, out, 16); -} - -// For each 4x32 block __m128i in[32], -// Input with odd index, -// 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 -// output pixels: 16-23, 24-31 in __m128i out[32] -static INLINE void highbd_idct32_1024_4x32_quarter_3_4( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i step1[32], step2[32]; - - // stage 1 - highbd_butterfly_sse4_1(in[1], in[31], cospi_31_64, cospi_1_64, &step1[16], - &step1[31]); - highbd_butterfly_sse4_1(in[17], in[15], cospi_15_64, cospi_17_64, &step1[17], - &step1[30]); - highbd_butterfly_sse4_1(in[9], in[23], cospi_23_64, cospi_9_64, &step1[18], - &step1[29]); - highbd_butterfly_sse4_1(in[25], in[7], cospi_7_64, cospi_25_64, &step1[19], - &step1[28]); - - highbd_butterfly_sse4_1(in[5], in[27], cospi_27_64, cospi_5_64, &step1[20], - &step1[27]); - highbd_butterfly_sse4_1(in[21], in[11], cospi_11_64, cospi_21_64, &step1[21], - &step1[26]); - - highbd_butterfly_sse4_1(in[13], in[19], cospi_19_64, cospi_13_64, &step1[22], - &step1[25]); - highbd_butterfly_sse4_1(in[29], in[3], cospi_3_64, cospi_29_64, &step1[23], - &step1[24]); - - // stage 2 - step2[16] = _mm_add_epi32(step1[16], step1[17]); - step2[17] = _mm_sub_epi32(step1[16], step1[17]); - step2[18] = _mm_sub_epi32(step1[19], step1[18]); - step2[19] = _mm_add_epi32(step1[19], step1[18]); - step2[20] = _mm_add_epi32(step1[20], step1[21]); - step2[21] = _mm_sub_epi32(step1[20], step1[21]); - step2[22] = _mm_sub_epi32(step1[23], step1[22]); - step2[23] = _mm_add_epi32(step1[23], step1[22]); - - step2[24] = _mm_add_epi32(step1[24], step1[25]); - step2[25] = _mm_sub_epi32(step1[24], step1[25]); - step2[26] = _mm_sub_epi32(step1[27], step1[26]); - step2[27] = _mm_add_epi32(step1[27], step1[26]); - step2[28] = _mm_add_epi32(step1[28], step1[29]); - step2[29] = _mm_sub_epi32(step1[28], step1[29]); - step2[30] = _mm_sub_epi32(step1[31], step1[30]); - step2[31] = _mm_add_epi32(step1[31], step1[30]); - - // stage 3 - step1[16] = step2[16]; - step1[31] = step2[31]; - highbd_butterfly_sse4_1(step2[30], step2[17], cospi_28_64, cospi_4_64, - &step1[17], &step1[30]); - highbd_butterfly_sse4_1(step2[29], step2[18], -cospi_4_64, cospi_28_64, - &step1[18], &step1[29]); - step1[19] = step2[19]; - step1[20] = step2[20]; - highbd_butterfly_sse4_1(step2[26], step2[21], cospi_12_64, cospi_20_64, - &step1[21], &step1[26]); - highbd_butterfly_sse4_1(step2[25], step2[22], -cospi_20_64, cospi_12_64, - &step1[22], &step1[25]); - step1[23] = step2[23]; - step1[24] = step2[24]; - step1[27] = step2[27]; - step1[28] = step2[28]; - - highbd_idct32_4x32_quarter_3_4_stage_4_to_7(step1, out); -} - -static void highbd_idct32_1024_4x32(__m128i *const io /*io[32]*/) { - __m128i temp[32]; - - highbd_idct32_1024_4x32_quarter_1_2(io, temp); - highbd_idct32_1024_4x32_quarter_3_4(io, temp); - // final stage - highbd_add_sub_butterfly(temp, io, 32); -} - -void vpx_highbd_idct32x32_1024_add_sse4_1(const tran_low_t *input, - uint16_t *dest, int stride, int bd) { - int i, j; - - if (bd == 8) { - __m128i col[4][32], io[32]; - - // rows - for (i = 0; i < 4; i++) { - highbd_load_pack_transpose_32bit_8x8(&input[0], 32, &io[0]); - highbd_load_pack_transpose_32bit_8x8(&input[8], 32, &io[8]); - highbd_load_pack_transpose_32bit_8x8(&input[16], 32, &io[16]); - highbd_load_pack_transpose_32bit_8x8(&input[24], 32, &io[24]); - idct32_1024_8x32(io, col[i]); - input += 32 << 3; - } - - // columns - for (i = 0; i < 32; i += 8) { - // Transpose 32x8 block to 8x32 block - transpose_16bit_8x8(col[0] + i, io); - transpose_16bit_8x8(col[1] + i, io + 8); - transpose_16bit_8x8(col[2] + i, io + 16); - transpose_16bit_8x8(col[3] + i, io + 24); - idct32_1024_8x32(io, io); - for (j = 0; j < 32; ++j) { - highbd_write_buffer_8(dest + j * stride, io[j], bd); - } - dest += 8; - } - } else { - __m128i all[8][32], out[32], *in; - - for (i = 0; i < 8; i++) { - in = all[i]; - highbd_load_transpose_32bit_8x4(&input[0], 32, &in[0]); - highbd_load_transpose_32bit_8x4(&input[8], 32, &in[8]); - highbd_load_transpose_32bit_8x4(&input[16], 32, &in[16]); - highbd_load_transpose_32bit_8x4(&input[24], 32, &in[24]); - highbd_idct32_1024_4x32(in); - input += 4 * 32; - } - - for (i = 0; i < 32; i += 4) { - transpose_32bit_4x4(all[0] + i, out + 0); - transpose_32bit_4x4(all[1] + i, out + 4); - transpose_32bit_4x4(all[2] + i, out + 8); - transpose_32bit_4x4(all[3] + i, out + 12); - transpose_32bit_4x4(all[4] + i, out + 16); - transpose_32bit_4x4(all[5] + i, out + 20); - transpose_32bit_4x4(all[6] + i, out + 24); - transpose_32bit_4x4(all[7] + i, out + 28); - highbd_idct32_1024_4x32(out); - - for (j = 0; j < 32; ++j) { - highbd_write_buffer_4(dest + j * stride, out[j], bd); - } - dest += 4; - } - } -} - -// ----------------------------------------------------------------------------- - -// For each 4x32 block __m128i in[32], -// Input with index, 0, 4, 8, 12 -// output pixels: 0-7 in __m128i out[32] -static INLINE void highbd_idct32_135_4x32_quarter_1( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[8]*/) { - __m128i step1[8], step2[8]; - - // stage 3 - highbd_partial_butterfly_sse4_1(in[4], cospi_28_64, cospi_4_64, &step1[4], - &step1[7]); - highbd_partial_butterfly_sse4_1(in[12], -cospi_20_64, cospi_12_64, &step1[5], - &step1[6]); - - // stage 4 - highbd_partial_butterfly_sse4_1(in[0], cospi_16_64, cospi_16_64, &step2[1], - &step2[0]); - highbd_partial_butterfly_sse4_1(in[8], cospi_24_64, cospi_8_64, &step2[2], - &step2[3]); - step2[4] = _mm_add_epi32(step1[4], step1[5]); - step2[5] = _mm_sub_epi32(step1[4], step1[5]); - step2[6] = _mm_sub_epi32(step1[7], step1[6]); - step2[7] = _mm_add_epi32(step1[7], step1[6]); - - // stage 5 - step1[0] = _mm_add_epi32(step2[0], step2[3]); - step1[1] = _mm_add_epi32(step2[1], step2[2]); - step1[2] = _mm_sub_epi32(step2[1], step2[2]); - step1[3] = _mm_sub_epi32(step2[0], step2[3]); - step1[4] = step2[4]; - highbd_butterfly_sse4_1(step2[6], step2[5], cospi_16_64, cospi_16_64, - &step1[5], &step1[6]); - step1[7] = step2[7]; - - // stage 6 - out[0] = _mm_add_epi32(step1[0], step1[7]); - out[1] = _mm_add_epi32(step1[1], step1[6]); - out[2] = _mm_add_epi32(step1[2], step1[5]); - out[3] = _mm_add_epi32(step1[3], step1[4]); - out[4] = _mm_sub_epi32(step1[3], step1[4]); - out[5] = _mm_sub_epi32(step1[2], step1[5]); - out[6] = _mm_sub_epi32(step1[1], step1[6]); - out[7] = _mm_sub_epi32(step1[0], step1[7]); -} - -// For each 4x32 block __m128i in[32], -// Input with index, 2, 6, 10, 14 -// output pixels: 8-15 in __m128i out[32] -static INLINE void highbd_idct32_135_4x32_quarter_2( - const __m128i *in /*in[32]*/, __m128i *out /*out[16]*/) { - __m128i step1[32], step2[32]; - - // stage 2 - highbd_partial_butterfly_sse4_1(in[2], cospi_30_64, cospi_2_64, &step2[8], - &step2[15]); - highbd_partial_butterfly_sse4_1(in[14], -cospi_18_64, cospi_14_64, &step2[9], - &step2[14]); - highbd_partial_butterfly_sse4_1(in[10], cospi_22_64, cospi_10_64, &step2[10], - &step2[13]); - highbd_partial_butterfly_sse4_1(in[6], -cospi_26_64, cospi_6_64, &step2[11], - &step2[12]); - - // stage 3 - step1[8] = _mm_add_epi32(step2[8], step2[9]); - step1[9] = _mm_sub_epi32(step2[8], step2[9]); - step1[14] = _mm_sub_epi32(step2[15], step2[14]); - step1[15] = _mm_add_epi32(step2[15], step2[14]); - step1[10] = _mm_sub_epi32(step2[11], step2[10]); - step1[11] = _mm_add_epi32(step2[11], step2[10]); - step1[12] = _mm_add_epi32(step2[12], step2[13]); - step1[13] = _mm_sub_epi32(step2[12], step2[13]); - - highbd_idct32_4x32_quarter_2_stage_4_to_6(step1, out); -} - -static INLINE void highbd_idct32_135_4x32_quarter_1_2( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i temp[16]; - highbd_idct32_135_4x32_quarter_1(in, temp); - highbd_idct32_135_4x32_quarter_2(in, temp); - // stage 7 - highbd_add_sub_butterfly(temp, out, 16); -} - -// For each 4x32 block __m128i in[32], -// Input with odd index, -// 1, 3, 5, 7, 9, 11, 13, 15 -// output pixels: 16-23, 24-31 in __m128i out[32] -static INLINE void highbd_idct32_135_4x32_quarter_3_4( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i step1[32], step2[32]; - - // stage 1 - highbd_partial_butterfly_sse4_1(in[1], cospi_31_64, cospi_1_64, &step1[16], - &step1[31]); - highbd_partial_butterfly_sse4_1(in[15], -cospi_17_64, cospi_15_64, &step1[17], - &step1[30]); - highbd_partial_butterfly_sse4_1(in[9], cospi_23_64, cospi_9_64, &step1[18], - &step1[29]); - highbd_partial_butterfly_sse4_1(in[7], -cospi_25_64, cospi_7_64, &step1[19], - &step1[28]); - - highbd_partial_butterfly_sse4_1(in[5], cospi_27_64, cospi_5_64, &step1[20], - &step1[27]); - highbd_partial_butterfly_sse4_1(in[11], -cospi_21_64, cospi_11_64, &step1[21], - &step1[26]); - - highbd_partial_butterfly_sse4_1(in[13], cospi_19_64, cospi_13_64, &step1[22], - &step1[25]); - highbd_partial_butterfly_sse4_1(in[3], -cospi_29_64, cospi_3_64, &step1[23], - &step1[24]); - - // stage 2 - step2[16] = _mm_add_epi32(step1[16], step1[17]); - step2[17] = _mm_sub_epi32(step1[16], step1[17]); - step2[18] = _mm_sub_epi32(step1[19], step1[18]); - step2[19] = _mm_add_epi32(step1[19], step1[18]); - step2[20] = _mm_add_epi32(step1[20], step1[21]); - step2[21] = _mm_sub_epi32(step1[20], step1[21]); - step2[22] = _mm_sub_epi32(step1[23], step1[22]); - step2[23] = _mm_add_epi32(step1[23], step1[22]); - - step2[24] = _mm_add_epi32(step1[24], step1[25]); - step2[25] = _mm_sub_epi32(step1[24], step1[25]); - step2[26] = _mm_sub_epi32(step1[27], step1[26]); - step2[27] = _mm_add_epi32(step1[27], step1[26]); - step2[28] = _mm_add_epi32(step1[28], step1[29]); - step2[29] = _mm_sub_epi32(step1[28], step1[29]); - step2[30] = _mm_sub_epi32(step1[31], step1[30]); - step2[31] = _mm_add_epi32(step1[31], step1[30]); - - // stage 3 - step1[16] = step2[16]; - step1[31] = step2[31]; - highbd_butterfly_sse4_1(step2[30], step2[17], cospi_28_64, cospi_4_64, - &step1[17], &step1[30]); - highbd_butterfly_sse4_1(step2[29], step2[18], -cospi_4_64, cospi_28_64, - &step1[18], &step1[29]); - step1[19] = step2[19]; - step1[20] = step2[20]; - highbd_butterfly_sse4_1(step2[26], step2[21], cospi_12_64, cospi_20_64, - &step1[21], &step1[26]); - highbd_butterfly_sse4_1(step2[25], step2[22], -cospi_20_64, cospi_12_64, - &step1[22], &step1[25]); - step1[23] = step2[23]; - step1[24] = step2[24]; - step1[27] = step2[27]; - step1[28] = step2[28]; - - highbd_idct32_4x32_quarter_3_4_stage_4_to_7(step1, out); -} - -static void highbd_idct32_135_4x32(__m128i *const io /*io[32]*/) { - __m128i temp[32]; - - highbd_idct32_135_4x32_quarter_1_2(io, temp); - highbd_idct32_135_4x32_quarter_3_4(io, temp); - // final stage - highbd_add_sub_butterfly(temp, io, 32); -} - -void vpx_highbd_idct32x32_135_add_sse4_1(const tran_low_t *input, - uint16_t *dest, int stride, int bd) { - int i, j; - - if (bd == 8) { - __m128i col[2][32], in[32], out[32]; - - // rows - for (i = 0; i < 2; i++) { - highbd_load_pack_transpose_32bit_8x8(&input[0], 32, &in[0]); - highbd_load_pack_transpose_32bit_8x8(&input[8], 32, &in[8]); - idct32_135_8x32_ssse3(in, col[i]); - input += 32 << 3; - } - - // columns - for (i = 0; i < 32; i += 8) { - transpose_16bit_8x8(col[0] + i, in); - transpose_16bit_8x8(col[1] + i, in + 8); - idct32_135_8x32_ssse3(in, out); - for (j = 0; j < 32; ++j) { - highbd_write_buffer_8(dest + j * stride, out[j], bd); - } - dest += 8; - } - } else { - __m128i all[8][32], out[32], *in; - - for (i = 0; i < 4; i++) { - in = all[i]; - highbd_load_transpose_32bit_8x4(&input[0], 32, &in[0]); - highbd_load_transpose_32bit_8x4(&input[8], 32, &in[8]); - highbd_idct32_135_4x32(in); - input += 4 * 32; - } - - for (i = 0; i < 32; i += 4) { - transpose_32bit_4x4(all[0] + i, out + 0); - transpose_32bit_4x4(all[1] + i, out + 4); - transpose_32bit_4x4(all[2] + i, out + 8); - transpose_32bit_4x4(all[3] + i, out + 12); - highbd_idct32_135_4x32(out); - - for (j = 0; j < 32; ++j) { - highbd_write_buffer_4(dest + j * stride, out[j], bd); - } - dest += 4; - } - } -} - -// ----------------------------------------------------------------------------- - -// For each 4x32 block __m128i in[32], -// Input with index, 0, 4 -// output pixels: 0-7 in __m128i out[32] -static INLINE void highbd_idct32_34_4x32_quarter_1( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[8]*/) { - __m128i step1[8], step2[8]; - - // stage 3 - highbd_partial_butterfly_sse4_1(in[4], cospi_28_64, cospi_4_64, &step1[4], - &step1[7]); - - // stage 4 - highbd_partial_butterfly_sse4_1(in[0], cospi_16_64, cospi_16_64, &step2[1], - &step2[0]); - step2[4] = step1[4]; - step2[5] = step1[4]; - step2[6] = step1[7]; - step2[7] = step1[7]; - - // stage 5 - step1[0] = step2[0]; - step1[1] = step2[1]; - step1[2] = step2[1]; - step1[3] = step2[0]; - step1[4] = step2[4]; - highbd_butterfly_sse4_1(step2[6], step2[5], cospi_16_64, cospi_16_64, - &step1[5], &step1[6]); - step1[7] = step2[7]; - - // stage 6 - out[0] = _mm_add_epi32(step1[0], step1[7]); - out[1] = _mm_add_epi32(step1[1], step1[6]); - out[2] = _mm_add_epi32(step1[2], step1[5]); - out[3] = _mm_add_epi32(step1[3], step1[4]); - out[4] = _mm_sub_epi32(step1[3], step1[4]); - out[5] = _mm_sub_epi32(step1[2], step1[5]); - out[6] = _mm_sub_epi32(step1[1], step1[6]); - out[7] = _mm_sub_epi32(step1[0], step1[7]); -} - -// For each 4x32 block __m128i in[32], -// Input with index, 2, 6 -// output pixels: 8-15 in __m128i out[32] -static INLINE void highbd_idct32_34_4x32_quarter_2(const __m128i *in /*in[32]*/, - __m128i *out /*out[16]*/) { - __m128i step1[32], step2[32]; - - // stage 2 - highbd_partial_butterfly_sse4_1(in[2], cospi_30_64, cospi_2_64, &step2[8], - &step2[15]); - highbd_partial_butterfly_sse4_1(in[6], -cospi_26_64, cospi_6_64, &step2[11], - &step2[12]); - - // stage 3 - step1[8] = step2[8]; - step1[9] = step2[8]; - step1[14] = step2[15]; - step1[15] = step2[15]; - step1[10] = step2[11]; - step1[11] = step2[11]; - step1[12] = step2[12]; - step1[13] = step2[12]; - - highbd_idct32_4x32_quarter_2_stage_4_to_6(step1, out); -} - -static INLINE void highbd_idct32_34_4x32_quarter_1_2( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i temp[16]; - highbd_idct32_34_4x32_quarter_1(in, temp); - highbd_idct32_34_4x32_quarter_2(in, temp); - // stage 7 - highbd_add_sub_butterfly(temp, out, 16); -} - -// For each 4x32 block __m128i in[32], -// Input with odd index, -// 1, 3, 5, 7 -// output pixels: 16-23, 24-31 in __m128i out[32] -static INLINE void highbd_idct32_34_4x32_quarter_3_4( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i step1[32], step2[32]; - - // stage 1 - highbd_partial_butterfly_sse4_1(in[1], cospi_31_64, cospi_1_64, &step1[16], - &step1[31]); - highbd_partial_butterfly_sse4_1(in[7], -cospi_25_64, cospi_7_64, &step1[19], - &step1[28]); - - highbd_partial_butterfly_sse4_1(in[5], cospi_27_64, cospi_5_64, &step1[20], - &step1[27]); - highbd_partial_butterfly_sse4_1(in[3], -cospi_29_64, cospi_3_64, &step1[23], - &step1[24]); - - // stage 2 - step2[16] = step1[16]; - step2[17] = step1[16]; - step2[18] = step1[19]; - step2[19] = step1[19]; - step2[20] = step1[20]; - step2[21] = step1[20]; - step2[22] = step1[23]; - step2[23] = step1[23]; - - step2[24] = step1[24]; - step2[25] = step1[24]; - step2[26] = step1[27]; - step2[27] = step1[27]; - step2[28] = step1[28]; - step2[29] = step1[28]; - step2[30] = step1[31]; - step2[31] = step1[31]; - - // stage 3 - step1[16] = step2[16]; - step1[31] = step2[31]; - highbd_butterfly_sse4_1(step2[30], step2[17], cospi_28_64, cospi_4_64, - &step1[17], &step1[30]); - highbd_butterfly_sse4_1(step2[29], step2[18], -cospi_4_64, cospi_28_64, - &step1[18], &step1[29]); - step1[19] = step2[19]; - step1[20] = step2[20]; - highbd_butterfly_sse4_1(step2[26], step2[21], cospi_12_64, cospi_20_64, - &step1[21], &step1[26]); - highbd_butterfly_sse4_1(step2[25], step2[22], -cospi_20_64, cospi_12_64, - &step1[22], &step1[25]); - step1[23] = step2[23]; - step1[24] = step2[24]; - step1[27] = step2[27]; - step1[28] = step2[28]; - - highbd_idct32_4x32_quarter_3_4_stage_4_to_7(step1, out); -} - -static void highbd_idct32_34_4x32(__m128i *const io /*io[32]*/) { - __m128i temp[32]; - - highbd_idct32_34_4x32_quarter_1_2(io, temp); - highbd_idct32_34_4x32_quarter_3_4(io, temp); - // final stage - highbd_add_sub_butterfly(temp, io, 32); -} - -void vpx_highbd_idct32x32_34_add_sse4_1(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int i, j; - - if (bd == 8) { - __m128i col[32], in[32], out[32]; - - // rows - highbd_load_pack_transpose_32bit_8x8(&input[0], 32, &in[0]); - idct32_34_8x32_ssse3(in, col); - - // columns - for (i = 0; i < 32; i += 8) { - transpose_16bit_8x8(col + i, in); - idct32_34_8x32_ssse3(in, out); - for (j = 0; j < 32; ++j) { - highbd_write_buffer_8(dest + j * stride, out[j], bd); - } - dest += 8; - } - } else { - __m128i all[8][32], out[32], *in; - - for (i = 0; i < 4; i++) { - in = all[i]; - highbd_load_transpose_32bit_8x4(&input[0], 32, &in[0]); - highbd_load_transpose_32bit_8x4(&input[8], 32, &in[8]); - highbd_idct32_34_4x32(in); - input += 4 * 32; - } - - for (i = 0; i < 32; i += 4) { - transpose_32bit_4x4(all[0] + i, out + 0); - transpose_32bit_4x4(all[1] + i, out + 4); - transpose_32bit_4x4(all[2] + i, out + 8); - transpose_32bit_4x4(all[3] + i, out + 12); - highbd_idct32_34_4x32(out); - - for (j = 0; j < 32; ++j) { - highbd_write_buffer_4(dest + j * stride, out[j], bd); - } - dest += 4; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct4x4_add_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct4x4_add_sse2.c deleted file mode 100644 index b9c8884f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct4x4_add_sse2.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // SSE2 - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/x86/highbd_inv_txfm_sse2.h" -#include "vpx_dsp/x86/inv_txfm_sse2.h" -#include "vpx_dsp/x86/transpose_sse2.h" - -static INLINE __m128i dct_const_round_shift_4_sse2(const __m128i in0, - const __m128i in1) { - const __m128i t0 = _mm_unpacklo_epi32(in0, in1); // 0, 1 - const __m128i t1 = _mm_unpackhi_epi32(in0, in1); // 2, 3 - const __m128i t2 = _mm_unpacklo_epi64(t0, t1); // 0, 1, 2, 3 - return dct_const_round_shift_sse2(t2); -} - -static INLINE void highbd_idct4_small_sse2(__m128i *const io) { - const __m128i cospi_p16_p16 = _mm_setr_epi32(cospi_16_64, 0, cospi_16_64, 0); - const __m128i cospi_p08_p08 = _mm_setr_epi32(cospi_8_64, 0, cospi_8_64, 0); - const __m128i cospi_p24_p24 = _mm_setr_epi32(cospi_24_64, 0, cospi_24_64, 0); - __m128i temp1[4], temp2[4], step[4]; - - transpose_32bit_4x4(io, io); - - // Note: There is no 32-bit signed multiply SIMD instruction in SSE2. - // _mm_mul_epu32() is used which can only guarantee the lower 32-bit - // (signed) result is meaningful, which is enough in this function. - - // stage 1 - temp1[0] = _mm_add_epi32(io[0], io[2]); // input[0] + input[2] - temp2[0] = _mm_sub_epi32(io[0], io[2]); // input[0] - input[2] - temp1[1] = _mm_srli_si128(temp1[0], 4); // 1, 3 - temp2[1] = _mm_srli_si128(temp2[0], 4); // 1, 3 - temp1[0] = _mm_mul_epu32(temp1[0], cospi_p16_p16); // ([0] + [2])*cospi_16_64 - temp1[1] = _mm_mul_epu32(temp1[1], cospi_p16_p16); // ([0] + [2])*cospi_16_64 - temp2[0] = _mm_mul_epu32(temp2[0], cospi_p16_p16); // ([0] - [2])*cospi_16_64 - temp2[1] = _mm_mul_epu32(temp2[1], cospi_p16_p16); // ([0] - [2])*cospi_16_64 - step[0] = dct_const_round_shift_4_sse2(temp1[0], temp1[1]); - step[1] = dct_const_round_shift_4_sse2(temp2[0], temp2[1]); - - temp1[3] = _mm_srli_si128(io[1], 4); - temp2[3] = _mm_srli_si128(io[3], 4); - temp1[0] = _mm_mul_epu32(io[1], cospi_p24_p24); // input[1] * cospi_24_64 - temp1[1] = _mm_mul_epu32(temp1[3], cospi_p24_p24); // input[1] * cospi_24_64 - temp2[0] = _mm_mul_epu32(io[1], cospi_p08_p08); // input[1] * cospi_8_64 - temp2[1] = _mm_mul_epu32(temp1[3], cospi_p08_p08); // input[1] * cospi_8_64 - temp1[2] = _mm_mul_epu32(io[3], cospi_p08_p08); // input[3] * cospi_8_64 - temp1[3] = _mm_mul_epu32(temp2[3], cospi_p08_p08); // input[3] * cospi_8_64 - temp2[2] = _mm_mul_epu32(io[3], cospi_p24_p24); // input[3] * cospi_24_64 - temp2[3] = _mm_mul_epu32(temp2[3], cospi_p24_p24); // input[3] * cospi_24_64 - temp1[0] = _mm_sub_epi64(temp1[0], temp1[2]); // [1]*cospi_24 - [3]*cospi_8 - temp1[1] = _mm_sub_epi64(temp1[1], temp1[3]); // [1]*cospi_24 - [3]*cospi_8 - temp2[0] = _mm_add_epi64(temp2[0], temp2[2]); // [1]*cospi_8 + [3]*cospi_24 - temp2[1] = _mm_add_epi64(temp2[1], temp2[3]); // [1]*cospi_8 + [3]*cospi_24 - step[2] = dct_const_round_shift_4_sse2(temp1[0], temp1[1]); - step[3] = dct_const_round_shift_4_sse2(temp2[0], temp2[1]); - - // stage 2 - io[0] = _mm_add_epi32(step[0], step[3]); // step[0] + step[3] - io[1] = _mm_add_epi32(step[1], step[2]); // step[1] + step[2] - io[2] = _mm_sub_epi32(step[1], step[2]); // step[1] - step[2] - io[3] = _mm_sub_epi32(step[0], step[3]); // step[0] - step[3] -} - -static INLINE void highbd_idct4_large_sse2(__m128i *const io) { - __m128i step[4]; - - transpose_32bit_4x4(io, io); - - // stage 1 - highbd_butterfly_cospi16_sse2(io[0], io[2], &step[0], &step[1]); - highbd_butterfly_sse2(io[1], io[3], cospi_24_64, cospi_8_64, &step[2], - &step[3]); - - // stage 2 - io[0] = _mm_add_epi32(step[0], step[3]); // step[0] + step[3] - io[1] = _mm_add_epi32(step[1], step[2]); // step[1] + step[2] - io[2] = _mm_sub_epi32(step[1], step[2]); // step[1] - step[2] - io[3] = _mm_sub_epi32(step[0], step[3]); // step[0] - step[3] -} - -void vpx_highbd_idct4x4_16_add_sse2(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int16_t max = 0, min = 0; - __m128i io[4], io_short[2]; - - io[0] = _mm_load_si128((const __m128i *)(input + 0)); - io[1] = _mm_load_si128((const __m128i *)(input + 4)); - io[2] = _mm_load_si128((const __m128i *)(input + 8)); - io[3] = _mm_load_si128((const __m128i *)(input + 12)); - - io_short[0] = _mm_packs_epi32(io[0], io[1]); - io_short[1] = _mm_packs_epi32(io[2], io[3]); - - if (bd != 8) { - __m128i max_input, min_input; - - max_input = _mm_max_epi16(io_short[0], io_short[1]); - min_input = _mm_min_epi16(io_short[0], io_short[1]); - max_input = _mm_max_epi16(max_input, _mm_srli_si128(max_input, 8)); - min_input = _mm_min_epi16(min_input, _mm_srli_si128(min_input, 8)); - max_input = _mm_max_epi16(max_input, _mm_srli_si128(max_input, 4)); - min_input = _mm_min_epi16(min_input, _mm_srli_si128(min_input, 4)); - max_input = _mm_max_epi16(max_input, _mm_srli_si128(max_input, 2)); - min_input = _mm_min_epi16(min_input, _mm_srli_si128(min_input, 2)); - max = (int16_t)_mm_extract_epi16(max_input, 0); - min = (int16_t)_mm_extract_epi16(min_input, 0); - } - - if (bd == 8 || (max < 4096 && min >= -4096)) { - idct4_sse2(io_short); - idct4_sse2(io_short); - io_short[0] = _mm_add_epi16(io_short[0], _mm_set1_epi16(8)); - io_short[1] = _mm_add_epi16(io_short[1], _mm_set1_epi16(8)); - io[0] = _mm_srai_epi16(io_short[0], 4); - io[1] = _mm_srai_epi16(io_short[1], 4); - } else { - if (max < 32767 && min > -32768) { - highbd_idct4_small_sse2(io); - highbd_idct4_small_sse2(io); - } else { - highbd_idct4_large_sse2(io); - highbd_idct4_large_sse2(io); - } - io[0] = wraplow_16bit_shift4(io[0], io[1], _mm_set1_epi32(8)); - io[1] = wraplow_16bit_shift4(io[2], io[3], _mm_set1_epi32(8)); - } - - recon_and_store_4x4(io, dest, stride, bd); -} - -void vpx_highbd_idct4x4_1_add_sse2(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - int a1, i; - tran_low_t out; - __m128i dc, d; - - out = HIGHBD_WRAPLOW( - dct_const_round_shift(input[0] * (tran_high_t)cospi_16_64), bd); - out = - HIGHBD_WRAPLOW(dct_const_round_shift(out * (tran_high_t)cospi_16_64), bd); - a1 = ROUND_POWER_OF_TWO(out, 4); - dc = _mm_set1_epi16(a1); - - for (i = 0; i < 4; ++i) { - d = _mm_loadl_epi64((const __m128i *)dest); - d = add_clamp(d, dc, bd); - _mm_storel_epi64((__m128i *)dest, d); - dest += stride; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct4x4_add_sse4.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct4x4_add_sse4.c deleted file mode 100644 index fe74d272..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct4x4_add_sse4.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // SSE4.1 - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/x86/highbd_inv_txfm_sse2.h" -#include "vpx_dsp/x86/highbd_inv_txfm_sse4.h" -#include "vpx_dsp/x86/inv_txfm_sse2.h" -#include "vpx_dsp/x86/transpose_sse2.h" - -void vpx_highbd_idct4x4_16_add_sse4_1(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - __m128i io[4]; - - io[0] = _mm_load_si128((const __m128i *)(input + 0)); - io[1] = _mm_load_si128((const __m128i *)(input + 4)); - io[2] = _mm_load_si128((const __m128i *)(input + 8)); - io[3] = _mm_load_si128((const __m128i *)(input + 12)); - - if (bd == 8) { - __m128i io_short[2]; - - io_short[0] = _mm_packs_epi32(io[0], io[1]); - io_short[1] = _mm_packs_epi32(io[2], io[3]); - idct4_sse2(io_short); - idct4_sse2(io_short); - io_short[0] = _mm_add_epi16(io_short[0], _mm_set1_epi16(8)); - io_short[1] = _mm_add_epi16(io_short[1], _mm_set1_epi16(8)); - io[0] = _mm_srai_epi16(io_short[0], 4); - io[1] = _mm_srai_epi16(io_short[1], 4); - } else { - highbd_idct4_sse4_1(io); - highbd_idct4_sse4_1(io); - io[0] = wraplow_16bit_shift4(io[0], io[1], _mm_set1_epi32(8)); - io[1] = wraplow_16bit_shift4(io[2], io[3], _mm_set1_epi32(8)); - } - - recon_and_store_4x4(io, dest, stride, bd); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct8x8_add_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct8x8_add_sse2.c deleted file mode 100644 index bb7a510e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct8x8_add_sse2.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // SSE2 - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/x86/highbd_inv_txfm_sse2.h" -#include "vpx_dsp/x86/inv_txfm_sse2.h" -#include "vpx_dsp/x86/transpose_sse2.h" - -static void highbd_idct8x8_half1d(__m128i *const io) { - __m128i step1[8], step2[8]; - - transpose_32bit_4x4x2(io, io); - - // stage 1 - step1[0] = io[0]; - step1[2] = io[4]; - step1[1] = io[2]; - step1[3] = io[6]; - highbd_butterfly_sse2(io[1], io[7], cospi_28_64, cospi_4_64, &step1[4], - &step1[7]); - highbd_butterfly_sse2(io[5], io[3], cospi_12_64, cospi_20_64, &step1[5], - &step1[6]); - - // stage 2 - highbd_butterfly_cospi16_sse2(step1[0], step1[2], &step2[0], &step2[1]); - highbd_butterfly_sse2(step1[1], step1[3], cospi_24_64, cospi_8_64, &step2[2], - &step2[3]); - step2[4] = _mm_add_epi32(step1[4], step1[5]); - step2[5] = _mm_sub_epi32(step1[4], step1[5]); - step2[6] = _mm_sub_epi32(step1[7], step1[6]); - step2[7] = _mm_add_epi32(step1[7], step1[6]); - - // stage 3 - step1[0] = _mm_add_epi32(step2[0], step2[3]); - step1[1] = _mm_add_epi32(step2[1], step2[2]); - step1[2] = _mm_sub_epi32(step2[1], step2[2]); - step1[3] = _mm_sub_epi32(step2[0], step2[3]); - step1[4] = step2[4]; - highbd_butterfly_cospi16_sse2(step2[6], step2[5], &step1[6], &step1[5]); - step1[7] = step2[7]; - - // stage 4 - highbd_idct8_stage4(step1, io); -} - -static void highbd_idct8x8_12_half1d(__m128i *const io) { - __m128i temp1[4], sign[2], step1[8], step2[8]; - - transpose_32bit_4x4(io, io); - - // stage 1 - step1[0] = io[0]; - step1[1] = io[2]; - abs_extend_64bit_sse2(io[1], temp1, sign); - step1[4] = multiplication_round_shift_sse2(temp1, sign, cospi_28_64); - step1[7] = multiplication_round_shift_sse2(temp1, sign, cospi_4_64); - abs_extend_64bit_sse2(io[3], temp1, sign); - step1[5] = multiplication_neg_round_shift_sse2(temp1, sign, cospi_20_64); - step1[6] = multiplication_round_shift_sse2(temp1, sign, cospi_12_64); - - // stage 2 - abs_extend_64bit_sse2(step1[0], temp1, sign); - step2[0] = multiplication_round_shift_sse2(temp1, sign, cospi_16_64); - abs_extend_64bit_sse2(step1[1], temp1, sign); - step2[2] = multiplication_round_shift_sse2(temp1, sign, cospi_24_64); - step2[3] = multiplication_round_shift_sse2(temp1, sign, cospi_8_64); - step2[4] = _mm_add_epi32(step1[4], step1[5]); - step2[5] = _mm_sub_epi32(step1[4], step1[5]); - step2[6] = _mm_sub_epi32(step1[7], step1[6]); - step2[7] = _mm_add_epi32(step1[7], step1[6]); - - // stage 3 - step1[0] = _mm_add_epi32(step2[0], step2[3]); - step1[1] = _mm_add_epi32(step2[0], step2[2]); - step1[2] = _mm_sub_epi32(step2[0], step2[2]); - step1[3] = _mm_sub_epi32(step2[0], step2[3]); - step1[4] = step2[4]; - highbd_butterfly_cospi16_sse2(step2[6], step2[5], &step1[6], &step1[5]); - step1[7] = step2[7]; - - // stage 4 - highbd_idct8_stage4(step1, io); -} - -void vpx_highbd_idct8x8_64_add_sse2(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - __m128i io[16]; - - io[0] = _mm_load_si128((const __m128i *)(input + 0 * 8 + 0)); - io[4] = _mm_load_si128((const __m128i *)(input + 0 * 8 + 4)); - io[1] = _mm_load_si128((const __m128i *)(input + 1 * 8 + 0)); - io[5] = _mm_load_si128((const __m128i *)(input + 1 * 8 + 4)); - io[2] = _mm_load_si128((const __m128i *)(input + 2 * 8 + 0)); - io[6] = _mm_load_si128((const __m128i *)(input + 2 * 8 + 4)); - io[3] = _mm_load_si128((const __m128i *)(input + 3 * 8 + 0)); - io[7] = _mm_load_si128((const __m128i *)(input + 3 * 8 + 4)); - - if (bd == 8) { - __m128i io_short[8]; - - io_short[0] = _mm_packs_epi32(io[0], io[4]); - io_short[1] = _mm_packs_epi32(io[1], io[5]); - io_short[2] = _mm_packs_epi32(io[2], io[6]); - io_short[3] = _mm_packs_epi32(io[3], io[7]); - io[8] = _mm_load_si128((const __m128i *)(input + 4 * 8 + 0)); - io[12] = _mm_load_si128((const __m128i *)(input + 4 * 8 + 4)); - io[9] = _mm_load_si128((const __m128i *)(input + 5 * 8 + 0)); - io[13] = _mm_load_si128((const __m128i *)(input + 5 * 8 + 4)); - io[10] = _mm_load_si128((const __m128i *)(input + 6 * 8 + 0)); - io[14] = _mm_load_si128((const __m128i *)(input + 6 * 8 + 4)); - io[11] = _mm_load_si128((const __m128i *)(input + 7 * 8 + 0)); - io[15] = _mm_load_si128((const __m128i *)(input + 7 * 8 + 4)); - io_short[4] = _mm_packs_epi32(io[8], io[12]); - io_short[5] = _mm_packs_epi32(io[9], io[13]); - io_short[6] = _mm_packs_epi32(io[10], io[14]); - io_short[7] = _mm_packs_epi32(io[11], io[15]); - - vpx_idct8_sse2(io_short); - vpx_idct8_sse2(io_short); - round_shift_8x8(io_short, io); - } else { - __m128i temp[4]; - - highbd_idct8x8_half1d(io); - - io[8] = _mm_load_si128((const __m128i *)(input + 4 * 8 + 0)); - io[12] = _mm_load_si128((const __m128i *)(input + 4 * 8 + 4)); - io[9] = _mm_load_si128((const __m128i *)(input + 5 * 8 + 0)); - io[13] = _mm_load_si128((const __m128i *)(input + 5 * 8 + 4)); - io[10] = _mm_load_si128((const __m128i *)(input + 6 * 8 + 0)); - io[14] = _mm_load_si128((const __m128i *)(input + 6 * 8 + 4)); - io[11] = _mm_load_si128((const __m128i *)(input + 7 * 8 + 0)); - io[15] = _mm_load_si128((const __m128i *)(input + 7 * 8 + 4)); - highbd_idct8x8_half1d(&io[8]); - - temp[0] = io[4]; - temp[1] = io[5]; - temp[2] = io[6]; - temp[3] = io[7]; - io[4] = io[8]; - io[5] = io[9]; - io[6] = io[10]; - io[7] = io[11]; - highbd_idct8x8_half1d(io); - - io[8] = temp[0]; - io[9] = temp[1]; - io[10] = temp[2]; - io[11] = temp[3]; - highbd_idct8x8_half1d(&io[8]); - - highbd_idct8x8_final_round(io); - } - - recon_and_store_8x8(io, dest, stride, bd); -} - -void vpx_highbd_idct8x8_12_add_sse2(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - const __m128i zero = _mm_setzero_si128(); - __m128i io[16]; - - io[0] = _mm_load_si128((const __m128i *)(input + 0 * 8 + 0)); - io[1] = _mm_load_si128((const __m128i *)(input + 1 * 8 + 0)); - io[2] = _mm_load_si128((const __m128i *)(input + 2 * 8 + 0)); - io[3] = _mm_load_si128((const __m128i *)(input + 3 * 8 + 0)); - - if (bd == 8) { - __m128i io_short[8]; - - io_short[0] = _mm_packs_epi32(io[0], zero); - io_short[1] = _mm_packs_epi32(io[1], zero); - io_short[2] = _mm_packs_epi32(io[2], zero); - io_short[3] = _mm_packs_epi32(io[3], zero); - - idct8x8_12_add_kernel_sse2(io_short); - round_shift_8x8(io_short, io); - } else { - __m128i temp[4]; - - highbd_idct8x8_12_half1d(io); - - temp[0] = io[4]; - temp[1] = io[5]; - temp[2] = io[6]; - temp[3] = io[7]; - highbd_idct8x8_12_half1d(io); - - io[8] = temp[0]; - io[9] = temp[1]; - io[10] = temp[2]; - io[11] = temp[3]; - highbd_idct8x8_12_half1d(&io[8]); - - highbd_idct8x8_final_round(io); - } - - recon_and_store_8x8(io, dest, stride, bd); -} - -void vpx_highbd_idct8x8_1_add_sse2(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - highbd_idct_1_add_kernel(input, dest, stride, bd, 8); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct8x8_add_sse4.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct8x8_add_sse4.c deleted file mode 100644 index 8b2e3d24..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_idct8x8_add_sse4.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // SSE4.1 - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/x86/highbd_inv_txfm_sse2.h" -#include "vpx_dsp/x86/highbd_inv_txfm_sse4.h" -#include "vpx_dsp/x86/inv_txfm_sse2.h" -#include "vpx_dsp/x86/inv_txfm_ssse3.h" -#include "vpx_dsp/x86/transpose_sse2.h" - -void vpx_highbd_idct8x8_half1d_sse4_1(__m128i *const io) { - __m128i step1[8], step2[8]; - - transpose_32bit_4x4x2(io, io); - - // stage 1 - step1[0] = io[0]; - step1[2] = io[4]; - step1[1] = io[2]; - step1[3] = io[6]; - highbd_butterfly_sse4_1(io[1], io[7], cospi_28_64, cospi_4_64, &step1[4], - &step1[7]); - highbd_butterfly_sse4_1(io[5], io[3], cospi_12_64, cospi_20_64, &step1[5], - &step1[6]); - - // stage 2 - highbd_butterfly_cospi16_sse4_1(step1[0], step1[2], &step2[0], &step2[1]); - highbd_butterfly_sse4_1(step1[1], step1[3], cospi_24_64, cospi_8_64, - &step2[2], &step2[3]); - step2[4] = _mm_add_epi32(step1[4], step1[5]); - step2[5] = _mm_sub_epi32(step1[4], step1[5]); - step2[6] = _mm_sub_epi32(step1[7], step1[6]); - step2[7] = _mm_add_epi32(step1[7], step1[6]); - - // stage 3 - step1[0] = _mm_add_epi32(step2[0], step2[3]); - step1[1] = _mm_add_epi32(step2[1], step2[2]); - step1[2] = _mm_sub_epi32(step2[1], step2[2]); - step1[3] = _mm_sub_epi32(step2[0], step2[3]); - step1[4] = step2[4]; - highbd_butterfly_cospi16_sse4_1(step2[6], step2[5], &step1[6], &step1[5]); - step1[7] = step2[7]; - - // stage 4 - highbd_idct8_stage4(step1, io); -} - -static void highbd_idct8x8_12_half1d(__m128i *const io) { - __m128i temp1[2], step1[8], step2[8]; - - transpose_32bit_4x4(io, io); - - // stage 1 - step1[0] = io[0]; - step1[1] = io[2]; - extend_64bit(io[1], temp1); - step1[4] = multiplication_round_shift_sse4_1(temp1, cospi_28_64); - step1[7] = multiplication_round_shift_sse4_1(temp1, cospi_4_64); - extend_64bit(io[3], temp1); - step1[5] = multiplication_round_shift_sse4_1(temp1, -cospi_20_64); - step1[6] = multiplication_round_shift_sse4_1(temp1, cospi_12_64); - - // stage 2 - extend_64bit(step1[0], temp1); - step2[0] = multiplication_round_shift_sse4_1(temp1, cospi_16_64); - extend_64bit(step1[1], temp1); - step2[2] = multiplication_round_shift_sse4_1(temp1, cospi_24_64); - step2[3] = multiplication_round_shift_sse4_1(temp1, cospi_8_64); - step2[4] = _mm_add_epi32(step1[4], step1[5]); - step2[5] = _mm_sub_epi32(step1[4], step1[5]); - step2[6] = _mm_sub_epi32(step1[7], step1[6]); - step2[7] = _mm_add_epi32(step1[7], step1[6]); - - // stage 3 - step1[0] = _mm_add_epi32(step2[0], step2[3]); - step1[1] = _mm_add_epi32(step2[0], step2[2]); - step1[2] = _mm_sub_epi32(step2[0], step2[2]); - step1[3] = _mm_sub_epi32(step2[0], step2[3]); - step1[4] = step2[4]; - highbd_butterfly_cospi16_sse4_1(step2[6], step2[5], &step1[6], &step1[5]); - step1[7] = step2[7]; - - // stage 4 - highbd_idct8_stage4(step1, io); -} - -void vpx_highbd_idct8x8_64_add_sse4_1(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - __m128i io[16]; - - io[0] = _mm_load_si128((const __m128i *)(input + 0 * 8 + 0)); - io[4] = _mm_load_si128((const __m128i *)(input + 0 * 8 + 4)); - io[1] = _mm_load_si128((const __m128i *)(input + 1 * 8 + 0)); - io[5] = _mm_load_si128((const __m128i *)(input + 1 * 8 + 4)); - io[2] = _mm_load_si128((const __m128i *)(input + 2 * 8 + 0)); - io[6] = _mm_load_si128((const __m128i *)(input + 2 * 8 + 4)); - io[3] = _mm_load_si128((const __m128i *)(input + 3 * 8 + 0)); - io[7] = _mm_load_si128((const __m128i *)(input + 3 * 8 + 4)); - - if (bd == 8) { - __m128i io_short[8]; - - io_short[0] = _mm_packs_epi32(io[0], io[4]); - io_short[1] = _mm_packs_epi32(io[1], io[5]); - io_short[2] = _mm_packs_epi32(io[2], io[6]); - io_short[3] = _mm_packs_epi32(io[3], io[7]); - io[8] = _mm_load_si128((const __m128i *)(input + 4 * 8 + 0)); - io[12] = _mm_load_si128((const __m128i *)(input + 4 * 8 + 4)); - io[9] = _mm_load_si128((const __m128i *)(input + 5 * 8 + 0)); - io[13] = _mm_load_si128((const __m128i *)(input + 5 * 8 + 4)); - io[10] = _mm_load_si128((const __m128i *)(input + 6 * 8 + 0)); - io[14] = _mm_load_si128((const __m128i *)(input + 6 * 8 + 4)); - io[11] = _mm_load_si128((const __m128i *)(input + 7 * 8 + 0)); - io[15] = _mm_load_si128((const __m128i *)(input + 7 * 8 + 4)); - io_short[4] = _mm_packs_epi32(io[8], io[12]); - io_short[5] = _mm_packs_epi32(io[9], io[13]); - io_short[6] = _mm_packs_epi32(io[10], io[14]); - io_short[7] = _mm_packs_epi32(io[11], io[15]); - - vpx_idct8_sse2(io_short); - vpx_idct8_sse2(io_short); - round_shift_8x8(io_short, io); - } else { - __m128i temp[4]; - - vpx_highbd_idct8x8_half1d_sse4_1(io); - - io[8] = _mm_load_si128((const __m128i *)(input + 4 * 8 + 0)); - io[12] = _mm_load_si128((const __m128i *)(input + 4 * 8 + 4)); - io[9] = _mm_load_si128((const __m128i *)(input + 5 * 8 + 0)); - io[13] = _mm_load_si128((const __m128i *)(input + 5 * 8 + 4)); - io[10] = _mm_load_si128((const __m128i *)(input + 6 * 8 + 0)); - io[14] = _mm_load_si128((const __m128i *)(input + 6 * 8 + 4)); - io[11] = _mm_load_si128((const __m128i *)(input + 7 * 8 + 0)); - io[15] = _mm_load_si128((const __m128i *)(input + 7 * 8 + 4)); - vpx_highbd_idct8x8_half1d_sse4_1(&io[8]); - - temp[0] = io[4]; - temp[1] = io[5]; - temp[2] = io[6]; - temp[3] = io[7]; - io[4] = io[8]; - io[5] = io[9]; - io[6] = io[10]; - io[7] = io[11]; - vpx_highbd_idct8x8_half1d_sse4_1(io); - - io[8] = temp[0]; - io[9] = temp[1]; - io[10] = temp[2]; - io[11] = temp[3]; - vpx_highbd_idct8x8_half1d_sse4_1(&io[8]); - - highbd_idct8x8_final_round(io); - } - - recon_and_store_8x8(io, dest, stride, bd); -} - -void vpx_highbd_idct8x8_12_add_sse4_1(const tran_low_t *input, uint16_t *dest, - int stride, int bd) { - const __m128i zero = _mm_setzero_si128(); - __m128i io[16]; - - io[0] = _mm_load_si128((const __m128i *)(input + 0 * 8 + 0)); - io[1] = _mm_load_si128((const __m128i *)(input + 1 * 8 + 0)); - io[2] = _mm_load_si128((const __m128i *)(input + 2 * 8 + 0)); - io[3] = _mm_load_si128((const __m128i *)(input + 3 * 8 + 0)); - - if (bd == 8) { - __m128i io_short[8]; - - io_short[0] = _mm_packs_epi32(io[0], zero); - io_short[1] = _mm_packs_epi32(io[1], zero); - io_short[2] = _mm_packs_epi32(io[2], zero); - io_short[3] = _mm_packs_epi32(io[3], zero); - - idct8x8_12_add_kernel_ssse3(io_short); - round_shift_8x8(io_short, io); - } else { - __m128i temp[4]; - - highbd_idct8x8_12_half1d(io); - - temp[0] = io[4]; - temp[1] = io[5]; - temp[2] = io[6]; - temp[3] = io[7]; - highbd_idct8x8_12_half1d(io); - - io[8] = temp[0]; - io[9] = temp[1]; - io[10] = temp[2]; - io[11] = temp[3]; - highbd_idct8x8_12_half1d(&io[8]); - - highbd_idct8x8_final_round(io); - } - - recon_and_store_8x8(io, dest, stride, bd); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_intrapred_intrin_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_intrapred_intrin_sse2.c deleted file mode 100644 index 43634aea..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_intrapred_intrin_sse2.c +++ /dev/null @@ -1,534 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // SSE2 - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" - -// ----------------------------------------------------------------------------- - -void vpx_highbd_h_predictor_4x4_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i left_u16 = _mm_loadl_epi64((const __m128i *)left); - const __m128i row0 = _mm_shufflelo_epi16(left_u16, 0x0); - const __m128i row1 = _mm_shufflelo_epi16(left_u16, 0x55); - const __m128i row2 = _mm_shufflelo_epi16(left_u16, 0xaa); - const __m128i row3 = _mm_shufflelo_epi16(left_u16, 0xff); - (void)above; - (void)bd; - _mm_storel_epi64((__m128i *)dst, row0); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row1); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row2); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row3); -} - -void vpx_highbd_h_predictor_8x8_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i left_u16 = _mm_load_si128((const __m128i *)left); - const __m128i row0 = _mm_shufflelo_epi16(left_u16, 0x0); - const __m128i row1 = _mm_shufflelo_epi16(left_u16, 0x55); - const __m128i row2 = _mm_shufflelo_epi16(left_u16, 0xaa); - const __m128i row3 = _mm_shufflelo_epi16(left_u16, 0xff); - const __m128i row4 = _mm_shufflehi_epi16(left_u16, 0x0); - const __m128i row5 = _mm_shufflehi_epi16(left_u16, 0x55); - const __m128i row6 = _mm_shufflehi_epi16(left_u16, 0xaa); - const __m128i row7 = _mm_shufflehi_epi16(left_u16, 0xff); - (void)above; - (void)bd; - _mm_store_si128((__m128i *)dst, _mm_unpacklo_epi64(row0, row0)); - dst += stride; - _mm_store_si128((__m128i *)dst, _mm_unpacklo_epi64(row1, row1)); - dst += stride; - _mm_store_si128((__m128i *)dst, _mm_unpacklo_epi64(row2, row2)); - dst += stride; - _mm_store_si128((__m128i *)dst, _mm_unpacklo_epi64(row3, row3)); - dst += stride; - _mm_store_si128((__m128i *)dst, _mm_unpackhi_epi64(row4, row4)); - dst += stride; - _mm_store_si128((__m128i *)dst, _mm_unpackhi_epi64(row5, row5)); - dst += stride; - _mm_store_si128((__m128i *)dst, _mm_unpackhi_epi64(row6, row6)); - dst += stride; - _mm_store_si128((__m128i *)dst, _mm_unpackhi_epi64(row7, row7)); -} - -static INLINE void h_store_16_unpacklo(uint16_t **dst, const ptrdiff_t stride, - const __m128i *row) { - const __m128i val = _mm_unpacklo_epi64(*row, *row); - _mm_store_si128((__m128i *)*dst, val); - _mm_store_si128((__m128i *)(*dst + 8), val); - *dst += stride; -} - -static INLINE void h_store_16_unpackhi(uint16_t **dst, const ptrdiff_t stride, - const __m128i *row) { - const __m128i val = _mm_unpackhi_epi64(*row, *row); - _mm_store_si128((__m128i *)(*dst), val); - _mm_store_si128((__m128i *)(*dst + 8), val); - *dst += stride; -} - -void vpx_highbd_h_predictor_16x16_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - int i; - (void)above; - (void)bd; - - for (i = 0; i < 2; i++, left += 8) { - const __m128i left_u16 = _mm_load_si128((const __m128i *)left); - const __m128i row0 = _mm_shufflelo_epi16(left_u16, 0x0); - const __m128i row1 = _mm_shufflelo_epi16(left_u16, 0x55); - const __m128i row2 = _mm_shufflelo_epi16(left_u16, 0xaa); - const __m128i row3 = _mm_shufflelo_epi16(left_u16, 0xff); - const __m128i row4 = _mm_shufflehi_epi16(left_u16, 0x0); - const __m128i row5 = _mm_shufflehi_epi16(left_u16, 0x55); - const __m128i row6 = _mm_shufflehi_epi16(left_u16, 0xaa); - const __m128i row7 = _mm_shufflehi_epi16(left_u16, 0xff); - h_store_16_unpacklo(&dst, stride, &row0); - h_store_16_unpacklo(&dst, stride, &row1); - h_store_16_unpacklo(&dst, stride, &row2); - h_store_16_unpacklo(&dst, stride, &row3); - h_store_16_unpackhi(&dst, stride, &row4); - h_store_16_unpackhi(&dst, stride, &row5); - h_store_16_unpackhi(&dst, stride, &row6); - h_store_16_unpackhi(&dst, stride, &row7); - } -} - -static INLINE void h_store_32_unpacklo(uint16_t **dst, const ptrdiff_t stride, - const __m128i *row) { - const __m128i val = _mm_unpacklo_epi64(*row, *row); - _mm_store_si128((__m128i *)(*dst), val); - _mm_store_si128((__m128i *)(*dst + 8), val); - _mm_store_si128((__m128i *)(*dst + 16), val); - _mm_store_si128((__m128i *)(*dst + 24), val); - *dst += stride; -} - -static INLINE void h_store_32_unpackhi(uint16_t **dst, const ptrdiff_t stride, - const __m128i *row) { - const __m128i val = _mm_unpackhi_epi64(*row, *row); - _mm_store_si128((__m128i *)(*dst), val); - _mm_store_si128((__m128i *)(*dst + 8), val); - _mm_store_si128((__m128i *)(*dst + 16), val); - _mm_store_si128((__m128i *)(*dst + 24), val); - *dst += stride; -} - -void vpx_highbd_h_predictor_32x32_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - int i; - (void)above; - (void)bd; - - for (i = 0; i < 4; i++, left += 8) { - const __m128i left_u16 = _mm_load_si128((const __m128i *)left); - const __m128i row0 = _mm_shufflelo_epi16(left_u16, 0x0); - const __m128i row1 = _mm_shufflelo_epi16(left_u16, 0x55); - const __m128i row2 = _mm_shufflelo_epi16(left_u16, 0xaa); - const __m128i row3 = _mm_shufflelo_epi16(left_u16, 0xff); - const __m128i row4 = _mm_shufflehi_epi16(left_u16, 0x0); - const __m128i row5 = _mm_shufflehi_epi16(left_u16, 0x55); - const __m128i row6 = _mm_shufflehi_epi16(left_u16, 0xaa); - const __m128i row7 = _mm_shufflehi_epi16(left_u16, 0xff); - h_store_32_unpacklo(&dst, stride, &row0); - h_store_32_unpacklo(&dst, stride, &row1); - h_store_32_unpacklo(&dst, stride, &row2); - h_store_32_unpacklo(&dst, stride, &row3); - h_store_32_unpackhi(&dst, stride, &row4); - h_store_32_unpackhi(&dst, stride, &row5); - h_store_32_unpackhi(&dst, stride, &row6); - h_store_32_unpackhi(&dst, stride, &row7); - } -} - -//------------------------------------------------------------------------------ -// DC 4x4 - -static INLINE __m128i dc_sum_4(const uint16_t *ref) { - const __m128i _dcba = _mm_loadl_epi64((const __m128i *)ref); - const __m128i _xxdc = _mm_shufflelo_epi16(_dcba, 0xe); - const __m128i a = _mm_add_epi16(_dcba, _xxdc); - return _mm_add_epi16(a, _mm_shufflelo_epi16(a, 0x1)); -} - -static INLINE void dc_store_4x4(uint16_t *dst, ptrdiff_t stride, - const __m128i *dc) { - const __m128i dc_dup = _mm_shufflelo_epi16(*dc, 0x0); - int i; - for (i = 0; i < 4; ++i, dst += stride) { - _mm_storel_epi64((__m128i *)dst, dc_dup); - } -} - -void vpx_highbd_dc_left_predictor_4x4_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i two = _mm_cvtsi32_si128(2); - const __m128i sum = dc_sum_4(left); - const __m128i dc = _mm_srli_epi16(_mm_add_epi16(sum, two), 2); - (void)above; - (void)bd; - dc_store_4x4(dst, stride, &dc); -} - -void vpx_highbd_dc_top_predictor_4x4_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i two = _mm_cvtsi32_si128(2); - const __m128i sum = dc_sum_4(above); - const __m128i dc = _mm_srli_epi16(_mm_add_epi16(sum, two), 2); - (void)left; - (void)bd; - dc_store_4x4(dst, stride, &dc); -} - -void vpx_highbd_dc_128_predictor_4x4_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i dc = _mm_cvtsi32_si128(1 << (bd - 1)); - const __m128i dc_dup = _mm_shufflelo_epi16(dc, 0x0); - (void)above; - (void)left; - dc_store_4x4(dst, stride, &dc_dup); -} - -//------------------------------------------------------------------------------ -// DC 8x8 - -static INLINE __m128i dc_sum_8(const uint16_t *ref) { - const __m128i ref_u16 = _mm_load_si128((const __m128i *)ref); - const __m128i _dcba = _mm_add_epi16(ref_u16, _mm_srli_si128(ref_u16, 8)); - const __m128i _xxdc = _mm_shufflelo_epi16(_dcba, 0xe); - const __m128i a = _mm_add_epi16(_dcba, _xxdc); - - return _mm_add_epi16(a, _mm_shufflelo_epi16(a, 0x1)); -} - -static INLINE void dc_store_8x8(uint16_t *dst, ptrdiff_t stride, - const __m128i *dc) { - const __m128i dc_dup_lo = _mm_shufflelo_epi16(*dc, 0); - const __m128i dc_dup = _mm_unpacklo_epi64(dc_dup_lo, dc_dup_lo); - int i; - for (i = 0; i < 8; ++i, dst += stride) { - _mm_store_si128((__m128i *)dst, dc_dup); - } -} - -void vpx_highbd_dc_left_predictor_8x8_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i four = _mm_cvtsi32_si128(4); - const __m128i sum = dc_sum_8(left); - const __m128i dc = _mm_srli_epi16(_mm_add_epi16(sum, four), 3); - (void)above; - (void)bd; - dc_store_8x8(dst, stride, &dc); -} - -void vpx_highbd_dc_top_predictor_8x8_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i four = _mm_cvtsi32_si128(4); - const __m128i sum = dc_sum_8(above); - const __m128i dc = _mm_srli_epi16(_mm_add_epi16(sum, four), 3); - (void)left; - (void)bd; - dc_store_8x8(dst, stride, &dc); -} - -void vpx_highbd_dc_128_predictor_8x8_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i dc = _mm_cvtsi32_si128(1 << (bd - 1)); - const __m128i dc_dup = _mm_shufflelo_epi16(dc, 0x0); - (void)above; - (void)left; - dc_store_8x8(dst, stride, &dc_dup); -} - -//------------------------------------------------------------------------------ -// DC 16x16 - -static INLINE __m128i dc_sum_16(const uint16_t *ref) { - const __m128i sum_lo = dc_sum_8(ref); - const __m128i sum_hi = dc_sum_8(ref + 8); - return _mm_add_epi16(sum_lo, sum_hi); -} - -static INLINE void dc_store_16x16(uint16_t *dst, ptrdiff_t stride, - const __m128i *dc) { - const __m128i dc_dup_lo = _mm_shufflelo_epi16(*dc, 0); - const __m128i dc_dup = _mm_unpacklo_epi64(dc_dup_lo, dc_dup_lo); - int i; - for (i = 0; i < 16; ++i, dst += stride) { - _mm_store_si128((__m128i *)dst, dc_dup); - _mm_store_si128((__m128i *)(dst + 8), dc_dup); - } -} - -void vpx_highbd_dc_left_predictor_16x16_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i eight = _mm_cvtsi32_si128(8); - const __m128i sum = dc_sum_16(left); - const __m128i dc = _mm_srli_epi16(_mm_add_epi16(sum, eight), 4); - (void)above; - (void)bd; - dc_store_16x16(dst, stride, &dc); -} - -void vpx_highbd_dc_top_predictor_16x16_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i eight = _mm_cvtsi32_si128(8); - const __m128i sum = dc_sum_16(above); - const __m128i dc = _mm_srli_epi16(_mm_add_epi16(sum, eight), 4); - (void)left; - (void)bd; - dc_store_16x16(dst, stride, &dc); -} - -void vpx_highbd_dc_128_predictor_16x16_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i dc = _mm_cvtsi32_si128(1 << (bd - 1)); - const __m128i dc_dup = _mm_shufflelo_epi16(dc, 0x0); - (void)above; - (void)left; - dc_store_16x16(dst, stride, &dc_dup); -} - -//------------------------------------------------------------------------------ -// DC 32x32 - -static INLINE __m128i dc_sum_32(const uint16_t *ref) { - const __m128i zero = _mm_setzero_si128(); - const __m128i sum_a = dc_sum_16(ref); - const __m128i sum_b = dc_sum_16(ref + 16); - // 12 bit bd will outrange, so expand to 32 bit before adding final total - return _mm_add_epi32(_mm_unpacklo_epi16(sum_a, zero), - _mm_unpacklo_epi16(sum_b, zero)); -} - -static INLINE void dc_store_32x32(uint16_t *dst, ptrdiff_t stride, - const __m128i *dc) { - const __m128i dc_dup_lo = _mm_shufflelo_epi16(*dc, 0); - const __m128i dc_dup = _mm_unpacklo_epi64(dc_dup_lo, dc_dup_lo); - int i; - for (i = 0; i < 32; ++i, dst += stride) { - _mm_store_si128((__m128i *)dst, dc_dup); - _mm_store_si128((__m128i *)(dst + 8), dc_dup); - _mm_store_si128((__m128i *)(dst + 16), dc_dup); - _mm_store_si128((__m128i *)(dst + 24), dc_dup); - } -} - -void vpx_highbd_dc_left_predictor_32x32_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i sixteen = _mm_cvtsi32_si128(16); - const __m128i sum = dc_sum_32(left); - const __m128i dc = _mm_srli_epi32(_mm_add_epi32(sum, sixteen), 5); - (void)above; - (void)bd; - dc_store_32x32(dst, stride, &dc); -} - -void vpx_highbd_dc_top_predictor_32x32_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i sixteen = _mm_cvtsi32_si128(16); - const __m128i sum = dc_sum_32(above); - const __m128i dc = _mm_srli_epi32(_mm_add_epi32(sum, sixteen), 5); - (void)left; - (void)bd; - dc_store_32x32(dst, stride, &dc); -} - -void vpx_highbd_dc_128_predictor_32x32_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i dc = _mm_cvtsi32_si128(1 << (bd - 1)); - const __m128i dc_dup = _mm_shufflelo_epi16(dc, 0x0); - (void)above; - (void)left; - dc_store_32x32(dst, stride, &dc_dup); -} - -// ----------------------------------------------------------------------------- -/* -; ------------------------------------------ -; input: x, y, z, result -; -; trick from pascal -; (x+2y+z+2)>>2 can be calculated as: -; result = avg(x,z) -; result -= xor(x,z) & 1 -; result = avg(result,y) -; ------------------------------------------ -*/ -static INLINE __m128i avg3_epu16(const __m128i *x, const __m128i *y, - const __m128i *z) { - const __m128i one = _mm_set1_epi16(1); - const __m128i a = _mm_avg_epu16(*x, *z); - const __m128i b = - _mm_subs_epu16(a, _mm_and_si128(_mm_xor_si128(*x, *z), one)); - return _mm_avg_epu16(b, *y); -} - -void vpx_highbd_d117_predictor_4x4_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const int I = left[0]; - const int J = left[1]; - const int K = left[2]; - const __m128i XXXXABCD = _mm_loadu_si128((const __m128i *)(above - 4)); - const __m128i KXXXABCD = _mm_insert_epi16(XXXXABCD, K, 0); - const __m128i KJXXABCD = _mm_insert_epi16(KXXXABCD, J, 1); - const __m128i KJIXABCD = _mm_insert_epi16(KJXXABCD, I, 2); - const __m128i JIXABCD0 = _mm_srli_si128(KJIXABCD, 2); - const __m128i IXABCD00 = _mm_srli_si128(KJIXABCD, 4); - const __m128i avg2 = _mm_avg_epu16(KJIXABCD, JIXABCD0); - const __m128i avg3 = avg3_epu16(&KJIXABCD, &JIXABCD0, &IXABCD00); - const __m128i row0 = _mm_srli_si128(avg2, 6); - const __m128i row1 = _mm_srli_si128(avg3, 4); - const __m128i row2 = _mm_srli_si128(avg2, 4); - const __m128i row3 = _mm_srli_si128(avg3, 2); - (void)bd; - _mm_storel_epi64((__m128i *)dst, row0); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row1); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row2); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row3); - - dst -= stride; - dst[0] = _mm_extract_epi16(avg3, 1); - dst[stride] = _mm_extract_epi16(avg3, 0); -} - -void vpx_highbd_d135_predictor_4x4_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const int I = left[0]; - const int J = left[1]; - const int K = left[2]; - const int L = left[3]; - const __m128i XXXXABCD = _mm_loadu_si128((const __m128i *)(above - 4)); - const __m128i KXXXABCD = _mm_insert_epi16(XXXXABCD, K, 0); - const __m128i KJXXABCD = _mm_insert_epi16(KXXXABCD, J, 1); - const __m128i KJIXABCD = _mm_insert_epi16(KJXXABCD, I, 2); - const __m128i JIXABCD0 = _mm_srli_si128(KJIXABCD, 2); - const __m128i LKJIXABC = _mm_insert_epi16(_mm_slli_si128(KJIXABCD, 2), L, 0); - const __m128i avg3 = avg3_epu16(&JIXABCD0, &KJIXABCD, &LKJIXABC); - const __m128i row0 = _mm_srli_si128(avg3, 6); - const __m128i row1 = _mm_srli_si128(avg3, 4); - const __m128i row2 = _mm_srli_si128(avg3, 2); - const __m128i row3 = avg3; - (void)bd; - _mm_storel_epi64((__m128i *)dst, row0); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row1); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row2); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row3); -} - -void vpx_highbd_d153_predictor_4x4_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const int I = left[0]; - const int J = left[1]; - const int K = left[2]; - const int L = left[3]; - const __m128i XXXXXABC = _mm_castps_si128( - _mm_loadh_pi(_mm_setzero_ps(), (const __m64 *)(above - 1))); - const __m128i LXXXXABC = _mm_insert_epi16(XXXXXABC, L, 0); - const __m128i LKXXXABC = _mm_insert_epi16(LXXXXABC, K, 1); - const __m128i LKJXXABC = _mm_insert_epi16(LKXXXABC, J, 2); - const __m128i LKJIXABC = _mm_insert_epi16(LKJXXABC, I, 3); - const __m128i KJIXABC0 = _mm_srli_si128(LKJIXABC, 2); - const __m128i JIXABC00 = _mm_srli_si128(LKJIXABC, 4); - const __m128i avg3 = avg3_epu16(&LKJIXABC, &KJIXABC0, &JIXABC00); - const __m128i avg2 = _mm_avg_epu16(LKJIXABC, KJIXABC0); - const __m128i row3 = _mm_unpacklo_epi16(avg2, avg3); - const __m128i row2 = _mm_srli_si128(row3, 4); - const __m128i row1 = _mm_srli_si128(row3, 8); - const __m128i row0 = _mm_srli_si128(avg3, 4); - (void)bd; - _mm_storel_epi64((__m128i *)dst, row0); - dst[0] = _mm_extract_epi16(avg2, 3); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row1); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row2); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row3); -} - -void vpx_highbd_d207_predictor_4x4_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i IJKL0000 = _mm_load_si128((const __m128i *)left); - const __m128i LLLL0000 = _mm_shufflelo_epi16(IJKL0000, 0xff); - const __m128i IJKLLLLL = _mm_unpacklo_epi64(IJKL0000, LLLL0000); - const __m128i JKLLLLL0 = _mm_srli_si128(IJKLLLLL, 2); - const __m128i KLLLLL00 = _mm_srli_si128(IJKLLLLL, 4); - const __m128i avg3 = avg3_epu16(&IJKLLLLL, &JKLLLLL0, &KLLLLL00); - const __m128i avg2 = _mm_avg_epu16(IJKLLLLL, JKLLLLL0); - const __m128i row0 = _mm_unpacklo_epi16(avg2, avg3); - const __m128i row1 = _mm_srli_si128(row0, 4); - const __m128i row2 = _mm_srli_si128(row0, 8); - const __m128i row3 = LLLL0000; - (void)above; - (void)bd; - _mm_storel_epi64((__m128i *)dst, row0); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row1); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row2); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row3); -} - -void vpx_highbd_d63_predictor_4x4_sse2(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i ABCDEFGH = _mm_loadu_si128((const __m128i *)above); - const __m128i BCDEFGH0 = _mm_srli_si128(ABCDEFGH, 2); - const __m128i CDEFGH00 = _mm_srli_si128(ABCDEFGH, 4); - const __m128i avg3 = avg3_epu16(&ABCDEFGH, &BCDEFGH0, &CDEFGH00); - const __m128i avg2 = _mm_avg_epu16(ABCDEFGH, BCDEFGH0); - const __m128i row0 = avg2; - const __m128i row1 = avg3; - const __m128i row2 = _mm_srli_si128(avg2, 2); - const __m128i row3 = _mm_srli_si128(avg3, 2); - (void)left; - (void)bd; - _mm_storel_epi64((__m128i *)dst, row0); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row1); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row2); - dst += stride; - _mm_storel_epi64((__m128i *)dst, row3); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_intrapred_intrin_ssse3.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_intrapred_intrin_ssse3.c deleted file mode 100644 index d673fac4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_intrapred_intrin_ssse3.c +++ /dev/null @@ -1,930 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" - -// ----------------------------------------------------------------------------- -/* -; ------------------------------------------ -; input: x, y, z, result -; -; trick from pascal -; (x+2y+z+2)>>2 can be calculated as: -; result = avg(x,z) -; result -= xor(x,z) & 1 -; result = avg(result,y) -; ------------------------------------------ -*/ -static INLINE __m128i avg3_epu16(const __m128i *x, const __m128i *y, - const __m128i *z) { - const __m128i one = _mm_set1_epi16(1); - const __m128i a = _mm_avg_epu16(*x, *z); - const __m128i b = - _mm_subs_epu16(a, _mm_and_si128(_mm_xor_si128(*x, *z), one)); - return _mm_avg_epu16(b, *y); -} - -void vpx_highbd_d45_predictor_4x4_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i ABCDEFGH = _mm_loadu_si128((const __m128i *)above); - const __m128i BCDEFGH0 = _mm_srli_si128(ABCDEFGH, 2); - const __m128i CDEFGH00 = _mm_srli_si128(ABCDEFGH, 4); - const __m128i avg3 = avg3_epu16(&ABCDEFGH, &BCDEFGH0, &CDEFGH00); - (void)left; - (void)bd; - _mm_storel_epi64((__m128i *)dst, avg3); - dst += stride; - _mm_storel_epi64((__m128i *)dst, _mm_srli_si128(avg3, 2)); - dst += stride; - _mm_storel_epi64((__m128i *)dst, _mm_srli_si128(avg3, 4)); - dst += stride; - _mm_storel_epi64((__m128i *)dst, _mm_srli_si128(avg3, 6)); - dst[3] = above[7]; // aka H -} - -static INLINE void d45_store_8(uint16_t **dst, const ptrdiff_t stride, - __m128i *row, const __m128i *ar) { - *row = _mm_alignr_epi8(*ar, *row, 2); - _mm_store_si128((__m128i *)*dst, *row); - *dst += stride; -} - -void vpx_highbd_d45_predictor_8x8_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i ABCDEFGH = _mm_load_si128((const __m128i *)above); - const __m128i ABCDHHHH = _mm_shufflehi_epi16(ABCDEFGH, 0xff); - const __m128i HHHHHHHH = _mm_unpackhi_epi64(ABCDHHHH, ABCDHHHH); - const __m128i BCDEFGHH = _mm_alignr_epi8(HHHHHHHH, ABCDEFGH, 2); - const __m128i CDEFGHHH = _mm_alignr_epi8(HHHHHHHH, ABCDEFGH, 4); - __m128i avg3 = avg3_epu16(&ABCDEFGH, &BCDEFGHH, &CDEFGHHH); - (void)left; - (void)bd; - _mm_store_si128((__m128i *)dst, avg3); - dst += stride; - d45_store_8(&dst, stride, &avg3, &HHHHHHHH); - d45_store_8(&dst, stride, &avg3, &HHHHHHHH); - d45_store_8(&dst, stride, &avg3, &HHHHHHHH); - d45_store_8(&dst, stride, &avg3, &HHHHHHHH); - d45_store_8(&dst, stride, &avg3, &HHHHHHHH); - d45_store_8(&dst, stride, &avg3, &HHHHHHHH); - d45_store_8(&dst, stride, &avg3, &HHHHHHHH); -} - -static INLINE void d45_store_16(uint16_t **dst, const ptrdiff_t stride, - __m128i *row_0, __m128i *row_1, - const __m128i *ar) { - *row_0 = _mm_alignr_epi8(*row_1, *row_0, 2); - *row_1 = _mm_alignr_epi8(*ar, *row_1, 2); - _mm_store_si128((__m128i *)*dst, *row_0); - _mm_store_si128((__m128i *)(*dst + 8), *row_1); - *dst += stride; -} - -void vpx_highbd_d45_predictor_16x16_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i A0 = _mm_load_si128((const __m128i *)above); - const __m128i A1 = _mm_load_si128((const __m128i *)(above + 8)); - const __m128i AR0 = _mm_shufflehi_epi16(A1, 0xff); - const __m128i AR = _mm_unpackhi_epi64(AR0, AR0); - const __m128i B0 = _mm_alignr_epi8(A1, A0, 2); - const __m128i B1 = _mm_alignr_epi8(AR, A1, 2); - const __m128i C0 = _mm_alignr_epi8(A1, A0, 4); - const __m128i C1 = _mm_alignr_epi8(AR, A1, 4); - __m128i avg3_0 = avg3_epu16(&A0, &B0, &C0); - __m128i avg3_1 = avg3_epu16(&A1, &B1, &C1); - (void)left; - (void)bd; - _mm_store_si128((__m128i *)dst, avg3_0); - _mm_store_si128((__m128i *)(dst + 8), avg3_1); - dst += stride; - d45_store_16(&dst, stride, &avg3_0, &avg3_1, &AR); - d45_store_16(&dst, stride, &avg3_0, &avg3_1, &AR); - d45_store_16(&dst, stride, &avg3_0, &avg3_1, &AR); - d45_store_16(&dst, stride, &avg3_0, &avg3_1, &AR); - d45_store_16(&dst, stride, &avg3_0, &avg3_1, &AR); - d45_store_16(&dst, stride, &avg3_0, &avg3_1, &AR); - d45_store_16(&dst, stride, &avg3_0, &avg3_1, &AR); - d45_store_16(&dst, stride, &avg3_0, &avg3_1, &AR); - d45_store_16(&dst, stride, &avg3_0, &avg3_1, &AR); - d45_store_16(&dst, stride, &avg3_0, &avg3_1, &AR); - d45_store_16(&dst, stride, &avg3_0, &avg3_1, &AR); - d45_store_16(&dst, stride, &avg3_0, &avg3_1, &AR); - d45_store_16(&dst, stride, &avg3_0, &avg3_1, &AR); - d45_store_16(&dst, stride, &avg3_0, &avg3_1, &AR); - d45_store_16(&dst, stride, &avg3_0, &avg3_1, &AR); -} - -void vpx_highbd_d45_predictor_32x32_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i A0 = _mm_load_si128((const __m128i *)above); - const __m128i A1 = _mm_load_si128((const __m128i *)(above + 8)); - const __m128i A2 = _mm_load_si128((const __m128i *)(above + 16)); - const __m128i A3 = _mm_load_si128((const __m128i *)(above + 24)); - const __m128i AR0 = _mm_shufflehi_epi16(A3, 0xff); - const __m128i AR = _mm_unpackhi_epi64(AR0, AR0); - const __m128i B0 = _mm_alignr_epi8(A1, A0, 2); - const __m128i B1 = _mm_alignr_epi8(A2, A1, 2); - const __m128i B2 = _mm_alignr_epi8(A3, A2, 2); - const __m128i B3 = _mm_alignr_epi8(AR, A3, 2); - const __m128i C0 = _mm_alignr_epi8(A1, A0, 4); - const __m128i C1 = _mm_alignr_epi8(A2, A1, 4); - const __m128i C2 = _mm_alignr_epi8(A3, A2, 4); - const __m128i C3 = _mm_alignr_epi8(AR, A3, 4); - __m128i avg3_0 = avg3_epu16(&A0, &B0, &C0); - __m128i avg3_1 = avg3_epu16(&A1, &B1, &C1); - __m128i avg3_2 = avg3_epu16(&A2, &B2, &C2); - __m128i avg3_3 = avg3_epu16(&A3, &B3, &C3); - int i; - (void)left; - (void)bd; - _mm_store_si128((__m128i *)dst, avg3_0); - _mm_store_si128((__m128i *)(dst + 8), avg3_1); - _mm_store_si128((__m128i *)(dst + 16), avg3_2); - _mm_store_si128((__m128i *)(dst + 24), avg3_3); - dst += stride; - for (i = 1; i < 32; ++i) { - avg3_0 = _mm_alignr_epi8(avg3_1, avg3_0, 2); - avg3_1 = _mm_alignr_epi8(avg3_2, avg3_1, 2); - avg3_2 = _mm_alignr_epi8(avg3_3, avg3_2, 2); - avg3_3 = _mm_alignr_epi8(AR, avg3_3, 2); - _mm_store_si128((__m128i *)dst, avg3_0); - _mm_store_si128((__m128i *)(dst + 8), avg3_1); - _mm_store_si128((__m128i *)(dst + 16), avg3_2); - _mm_store_si128((__m128i *)(dst + 24), avg3_3); - dst += stride; - } -} - -DECLARE_ALIGNED(16, static const uint8_t, - rotate_right_epu16[16]) = { 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 0, 1 }; - -static INLINE __m128i rotr_epu16(__m128i *a, const __m128i *rotrw) { - *a = _mm_shuffle_epi8(*a, *rotrw); - return *a; -} - -void vpx_highbd_d117_predictor_8x8_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i rotrw = _mm_load_si128((const __m128i *)rotate_right_epu16); - const __m128i XABCDEFG = _mm_loadu_si128((const __m128i *)(above - 1)); - const __m128i ABCDEFGH = _mm_load_si128((const __m128i *)above); - const __m128i IJKLMNOP = _mm_load_si128((const __m128i *)left); - const __m128i IXABCDEF = - _mm_alignr_epi8(XABCDEFG, _mm_slli_si128(IJKLMNOP, 14), 14); - const __m128i avg3 = avg3_epu16(&ABCDEFGH, &XABCDEFG, &IXABCDEF); - const __m128i avg2 = _mm_avg_epu16(ABCDEFGH, XABCDEFG); - const __m128i XIJKLMNO = - _mm_alignr_epi8(IJKLMNOP, _mm_slli_si128(XABCDEFG, 14), 14); - const __m128i JKLMNOP0 = _mm_srli_si128(IJKLMNOP, 2); - __m128i avg3_left = avg3_epu16(&XIJKLMNO, &IJKLMNOP, &JKLMNOP0); - __m128i rowa = avg2; - __m128i rowb = avg3; - int i; - (void)bd; - for (i = 0; i < 8; i += 2) { - _mm_store_si128((__m128i *)dst, rowa); - dst += stride; - _mm_store_si128((__m128i *)dst, rowb); - dst += stride; - rowa = _mm_alignr_epi8(rowa, rotr_epu16(&avg3_left, &rotrw), 14); - rowb = _mm_alignr_epi8(rowb, rotr_epu16(&avg3_left, &rotrw), 14); - } -} - -void vpx_highbd_d117_predictor_16x16_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i rotrw = _mm_load_si128((const __m128i *)rotate_right_epu16); - const __m128i B0 = _mm_loadu_si128((const __m128i *)(above - 1)); - const __m128i A0 = _mm_load_si128((const __m128i *)above); - const __m128i B1 = _mm_loadu_si128((const __m128i *)(above + 7)); - const __m128i A1 = _mm_load_si128((const __m128i *)(above + 8)); - const __m128i avg2_0 = _mm_avg_epu16(A0, B0); - const __m128i avg2_1 = _mm_avg_epu16(A1, B1); - const __m128i L0 = _mm_load_si128((const __m128i *)left); - const __m128i L1 = _mm_load_si128((const __m128i *)(left + 8)); - const __m128i C0 = _mm_alignr_epi8(B0, _mm_slli_si128(L0, 14), 14); - const __m128i C1 = _mm_alignr_epi8(B1, B0, 14); - const __m128i avg3_0 = avg3_epu16(&A0, &B0, &C0); - const __m128i avg3_1 = avg3_epu16(&A1, &B1, &C1); - const __m128i XL0 = _mm_alignr_epi8(L0, _mm_slli_si128(B0, 14), 14); - const __m128i XL1 = _mm_alignr_epi8(L1, L0, 14); - const __m128i L0_ = _mm_alignr_epi8(L1, L0, 2); - const __m128i L1_ = _mm_srli_si128(L1, 2); - __m128i rowa_0 = avg2_0; - __m128i rowa_1 = avg2_1; - __m128i rowb_0 = avg3_0; - __m128i rowb_1 = avg3_1; - __m128i avg3_left[2]; - int i, j; - (void)bd; - avg3_left[0] = avg3_epu16(&XL0, &L0, &L0_); - avg3_left[1] = avg3_epu16(&XL1, &L1, &L1_); - for (i = 0; i < 2; ++i) { - __m128i avg_left = avg3_left[i]; - for (j = 0; j < 8; j += 2) { - _mm_store_si128((__m128i *)dst, rowa_0); - _mm_store_si128((__m128i *)(dst + 8), rowa_1); - dst += stride; - _mm_store_si128((__m128i *)dst, rowb_0); - _mm_store_si128((__m128i *)(dst + 8), rowb_1); - dst += stride; - rowa_1 = _mm_alignr_epi8(rowa_1, rowa_0, 14); - rowa_0 = _mm_alignr_epi8(rowa_0, rotr_epu16(&avg_left, &rotrw), 14); - rowb_1 = _mm_alignr_epi8(rowb_1, rowb_0, 14); - rowb_0 = _mm_alignr_epi8(rowb_0, rotr_epu16(&avg_left, &rotrw), 14); - } - } -} - -void vpx_highbd_d117_predictor_32x32_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i rotrw = _mm_load_si128((const __m128i *)rotate_right_epu16); - const __m128i A0 = _mm_load_si128((const __m128i *)above); - const __m128i A1 = _mm_load_si128((const __m128i *)(above + 8)); - const __m128i A2 = _mm_load_si128((const __m128i *)(above + 16)); - const __m128i A3 = _mm_load_si128((const __m128i *)(above + 24)); - const __m128i B0 = _mm_loadu_si128((const __m128i *)(above - 1)); - const __m128i B1 = _mm_loadu_si128((const __m128i *)(above + 7)); - const __m128i B2 = _mm_loadu_si128((const __m128i *)(above + 15)); - const __m128i B3 = _mm_loadu_si128((const __m128i *)(above + 23)); - const __m128i avg2_0 = _mm_avg_epu16(A0, B0); - const __m128i avg2_1 = _mm_avg_epu16(A1, B1); - const __m128i avg2_2 = _mm_avg_epu16(A2, B2); - const __m128i avg2_3 = _mm_avg_epu16(A3, B3); - const __m128i L0 = _mm_load_si128((const __m128i *)left); - const __m128i L1 = _mm_load_si128((const __m128i *)(left + 8)); - const __m128i L2 = _mm_load_si128((const __m128i *)(left + 16)); - const __m128i L3 = _mm_load_si128((const __m128i *)(left + 24)); - const __m128i C0 = _mm_alignr_epi8(B0, _mm_slli_si128(L0, 14), 14); - const __m128i C1 = _mm_alignr_epi8(B1, B0, 14); - const __m128i C2 = _mm_alignr_epi8(B2, B1, 14); - const __m128i C3 = _mm_alignr_epi8(B3, B2, 14); - const __m128i avg3_0 = avg3_epu16(&A0, &B0, &C0); - const __m128i avg3_1 = avg3_epu16(&A1, &B1, &C1); - const __m128i avg3_2 = avg3_epu16(&A2, &B2, &C2); - const __m128i avg3_3 = avg3_epu16(&A3, &B3, &C3); - const __m128i XL0 = _mm_alignr_epi8(L0, _mm_slli_si128(B0, 14), 14); - const __m128i XL1 = _mm_alignr_epi8(L1, L0, 14); - const __m128i XL2 = _mm_alignr_epi8(L2, L1, 14); - const __m128i XL3 = _mm_alignr_epi8(L3, L2, 14); - const __m128i L0_ = _mm_alignr_epi8(L1, L0, 2); - const __m128i L1_ = _mm_alignr_epi8(L2, L1, 2); - const __m128i L2_ = _mm_alignr_epi8(L3, L2, 2); - const __m128i L3_ = _mm_srli_si128(L3, 2); - __m128i rowa_0 = avg2_0; - __m128i rowa_1 = avg2_1; - __m128i rowa_2 = avg2_2; - __m128i rowa_3 = avg2_3; - __m128i rowb_0 = avg3_0; - __m128i rowb_1 = avg3_1; - __m128i rowb_2 = avg3_2; - __m128i rowb_3 = avg3_3; - __m128i avg3_left[4]; - int i, j; - (void)bd; - avg3_left[0] = avg3_epu16(&XL0, &L0, &L0_); - avg3_left[1] = avg3_epu16(&XL1, &L1, &L1_); - avg3_left[2] = avg3_epu16(&XL2, &L2, &L2_); - avg3_left[3] = avg3_epu16(&XL3, &L3, &L3_); - for (i = 0; i < 4; ++i) { - __m128i avg_left = avg3_left[i]; - for (j = 0; j < 8; j += 2) { - _mm_store_si128((__m128i *)dst, rowa_0); - _mm_store_si128((__m128i *)(dst + 8), rowa_1); - _mm_store_si128((__m128i *)(dst + 16), rowa_2); - _mm_store_si128((__m128i *)(dst + 24), rowa_3); - dst += stride; - _mm_store_si128((__m128i *)dst, rowb_0); - _mm_store_si128((__m128i *)(dst + 8), rowb_1); - _mm_store_si128((__m128i *)(dst + 16), rowb_2); - _mm_store_si128((__m128i *)(dst + 24), rowb_3); - dst += stride; - rowa_3 = _mm_alignr_epi8(rowa_3, rowa_2, 14); - rowa_2 = _mm_alignr_epi8(rowa_2, rowa_1, 14); - rowa_1 = _mm_alignr_epi8(rowa_1, rowa_0, 14); - rowa_0 = _mm_alignr_epi8(rowa_0, rotr_epu16(&avg_left, &rotrw), 14); - rowb_3 = _mm_alignr_epi8(rowb_3, rowb_2, 14); - rowb_2 = _mm_alignr_epi8(rowb_2, rowb_1, 14); - rowb_1 = _mm_alignr_epi8(rowb_1, rowb_0, 14); - rowb_0 = _mm_alignr_epi8(rowb_0, rotr_epu16(&avg_left, &rotrw), 14); - } - } -} - -void vpx_highbd_d135_predictor_8x8_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i rotrw = _mm_load_si128((const __m128i *)rotate_right_epu16); - const __m128i XABCDEFG = _mm_loadu_si128((const __m128i *)(above - 1)); - const __m128i ABCDEFGH = _mm_load_si128((const __m128i *)above); - const __m128i BCDEFGH0 = _mm_srli_si128(ABCDEFGH, 2); - const __m128i IJKLMNOP = _mm_load_si128((const __m128i *)left); - const __m128i XIJKLMNO = - _mm_alignr_epi8(IJKLMNOP, _mm_slli_si128(XABCDEFG, 14), 14); - const __m128i AXIJKLMN = - _mm_alignr_epi8(XIJKLMNO, _mm_slli_si128(ABCDEFGH, 14), 14); - const __m128i avg3 = avg3_epu16(&XABCDEFG, &ABCDEFGH, &BCDEFGH0); - __m128i avg3_left = avg3_epu16(&IJKLMNOP, &XIJKLMNO, &AXIJKLMN); - __m128i rowa = avg3; - int i; - (void)bd; - for (i = 0; i < 8; ++i) { - rowa = _mm_alignr_epi8(rowa, rotr_epu16(&avg3_left, &rotrw), 14); - _mm_store_si128((__m128i *)dst, rowa); - dst += stride; - } -} - -void vpx_highbd_d135_predictor_16x16_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i rotrw = _mm_load_si128((const __m128i *)rotate_right_epu16); - const __m128i A0 = _mm_loadu_si128((const __m128i *)(above - 1)); - const __m128i B0 = _mm_load_si128((const __m128i *)above); - const __m128i A1 = _mm_loadu_si128((const __m128i *)(above + 7)); - const __m128i B1 = _mm_load_si128((const __m128i *)(above + 8)); - const __m128i L0 = _mm_load_si128((const __m128i *)left); - const __m128i L1 = _mm_load_si128((const __m128i *)(left + 8)); - const __m128i C0 = _mm_alignr_epi8(B1, B0, 2); - const __m128i C1 = _mm_srli_si128(B1, 2); - const __m128i avg3_0 = avg3_epu16(&A0, &B0, &C0); - const __m128i avg3_1 = avg3_epu16(&A1, &B1, &C1); - const __m128i XL0 = _mm_alignr_epi8(L0, _mm_slli_si128(A0, 14), 14); - const __m128i XL1 = _mm_alignr_epi8(L1, L0, 14); - const __m128i L0_ = _mm_alignr_epi8(XL0, _mm_slli_si128(B0, 14), 14); - const __m128i L1_ = _mm_alignr_epi8(XL1, XL0, 14); - __m128i rowa_0 = avg3_0; - __m128i rowa_1 = avg3_1; - __m128i avg3_left[2]; - int i, j; - (void)bd; - avg3_left[0] = avg3_epu16(&L0, &XL0, &L0_); - avg3_left[1] = avg3_epu16(&L1, &XL1, &L1_); - for (i = 0; i < 2; ++i) { - __m128i avg_left = avg3_left[i]; - for (j = 0; j < 8; ++j) { - rowa_1 = _mm_alignr_epi8(rowa_1, rowa_0, 14); - rowa_0 = _mm_alignr_epi8(rowa_0, rotr_epu16(&avg_left, &rotrw), 14); - _mm_store_si128((__m128i *)dst, rowa_0); - _mm_store_si128((__m128i *)(dst + 8), rowa_1); - dst += stride; - } - } -} - -void vpx_highbd_d135_predictor_32x32_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i rotrw = _mm_load_si128((const __m128i *)rotate_right_epu16); - const __m128i A0 = _mm_loadu_si128((const __m128i *)(above - 1)); - const __m128i A1 = _mm_loadu_si128((const __m128i *)(above + 7)); - const __m128i A2 = _mm_loadu_si128((const __m128i *)(above + 15)); - const __m128i A3 = _mm_loadu_si128((const __m128i *)(above + 23)); - const __m128i B0 = _mm_load_si128((const __m128i *)above); - const __m128i B1 = _mm_load_si128((const __m128i *)(above + 8)); - const __m128i B2 = _mm_load_si128((const __m128i *)(above + 16)); - const __m128i B3 = _mm_load_si128((const __m128i *)(above + 24)); - const __m128i L0 = _mm_load_si128((const __m128i *)left); - const __m128i L1 = _mm_load_si128((const __m128i *)(left + 8)); - const __m128i L2 = _mm_load_si128((const __m128i *)(left + 16)); - const __m128i L3 = _mm_load_si128((const __m128i *)(left + 24)); - const __m128i C0 = _mm_alignr_epi8(B1, B0, 2); - const __m128i C1 = _mm_alignr_epi8(B2, B1, 2); - const __m128i C2 = _mm_alignr_epi8(B3, B2, 2); - const __m128i C3 = _mm_srli_si128(B3, 2); - const __m128i avg3_0 = avg3_epu16(&A0, &B0, &C0); - const __m128i avg3_1 = avg3_epu16(&A1, &B1, &C1); - const __m128i avg3_2 = avg3_epu16(&A2, &B2, &C2); - const __m128i avg3_3 = avg3_epu16(&A3, &B3, &C3); - const __m128i XL0 = _mm_alignr_epi8(L0, _mm_slli_si128(A0, 14), 14); - const __m128i XL1 = _mm_alignr_epi8(L1, L0, 14); - const __m128i XL2 = _mm_alignr_epi8(L2, L1, 14); - const __m128i XL3 = _mm_alignr_epi8(L3, L2, 14); - const __m128i L0_ = _mm_alignr_epi8(XL0, _mm_slli_si128(B0, 14), 14); - const __m128i L1_ = _mm_alignr_epi8(XL1, XL0, 14); - const __m128i L2_ = _mm_alignr_epi8(XL2, XL1, 14); - const __m128i L3_ = _mm_alignr_epi8(XL3, XL2, 14); - __m128i rowa_0 = avg3_0; - __m128i rowa_1 = avg3_1; - __m128i rowa_2 = avg3_2; - __m128i rowa_3 = avg3_3; - __m128i avg3_left[4]; - int i, j; - (void)bd; - avg3_left[0] = avg3_epu16(&L0, &XL0, &L0_); - avg3_left[1] = avg3_epu16(&L1, &XL1, &L1_); - avg3_left[2] = avg3_epu16(&L2, &XL2, &L2_); - avg3_left[3] = avg3_epu16(&L3, &XL3, &L3_); - for (i = 0; i < 4; ++i) { - __m128i avg_left = avg3_left[i]; - for (j = 0; j < 8; ++j) { - rowa_3 = _mm_alignr_epi8(rowa_3, rowa_2, 14); - rowa_2 = _mm_alignr_epi8(rowa_2, rowa_1, 14); - rowa_1 = _mm_alignr_epi8(rowa_1, rowa_0, 14); - rowa_0 = _mm_alignr_epi8(rowa_0, rotr_epu16(&avg_left, &rotrw), 14); - _mm_store_si128((__m128i *)dst, rowa_0); - _mm_store_si128((__m128i *)(dst + 8), rowa_1); - _mm_store_si128((__m128i *)(dst + 16), rowa_2); - _mm_store_si128((__m128i *)(dst + 24), rowa_3); - dst += stride; - } - } -} - -void vpx_highbd_d153_predictor_8x8_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i XABCDEFG = _mm_loadu_si128((const __m128i *)(above - 1)); - const __m128i ABCDEFG0 = _mm_srli_si128(XABCDEFG, 2); - const __m128i BCDEFG00 = _mm_srli_si128(XABCDEFG, 4); - const __m128i avg3 = avg3_epu16(&BCDEFG00, &ABCDEFG0, &XABCDEFG); - const __m128i IJKLMNOP = _mm_load_si128((const __m128i *)left); - const __m128i XIJKLMNO = - _mm_alignr_epi8(IJKLMNOP, _mm_slli_si128(XABCDEFG, 14), 14); - const __m128i AXIJKLMN = - _mm_alignr_epi8(XIJKLMNO, _mm_slli_si128(XABCDEFG, 12), 14); - const __m128i avg3_left = avg3_epu16(&IJKLMNOP, &XIJKLMNO, &AXIJKLMN); - const __m128i avg2_left = _mm_avg_epu16(IJKLMNOP, XIJKLMNO); - const __m128i avg2_avg3_lo = _mm_unpacklo_epi16(avg2_left, avg3_left); - const __m128i avg2_avg3_hi = _mm_unpackhi_epi16(avg2_left, avg3_left); - const __m128i row0 = - _mm_alignr_epi8(avg3, _mm_slli_si128(avg2_avg3_lo, 12), 12); - const __m128i row1 = - _mm_alignr_epi8(row0, _mm_slli_si128(avg2_avg3_lo, 8), 12); - const __m128i row2 = - _mm_alignr_epi8(row1, _mm_slli_si128(avg2_avg3_lo, 4), 12); - const __m128i row3 = _mm_alignr_epi8(row2, avg2_avg3_lo, 12); - const __m128i row4 = - _mm_alignr_epi8(row3, _mm_slli_si128(avg2_avg3_hi, 12), 12); - const __m128i row5 = - _mm_alignr_epi8(row4, _mm_slli_si128(avg2_avg3_hi, 8), 12); - const __m128i row6 = - _mm_alignr_epi8(row5, _mm_slli_si128(avg2_avg3_hi, 4), 12); - const __m128i row7 = _mm_alignr_epi8(row6, avg2_avg3_hi, 12); - (void)bd; - _mm_store_si128((__m128i *)dst, row0); - dst += stride; - _mm_store_si128((__m128i *)dst, row1); - dst += stride; - _mm_store_si128((__m128i *)dst, row2); - dst += stride; - _mm_store_si128((__m128i *)dst, row3); - dst += stride; - _mm_store_si128((__m128i *)dst, row4); - dst += stride; - _mm_store_si128((__m128i *)dst, row5); - dst += stride; - _mm_store_si128((__m128i *)dst, row6); - dst += stride; - _mm_store_si128((__m128i *)dst, row7); -} - -void vpx_highbd_d153_predictor_16x16_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i A0 = _mm_loadu_si128((const __m128i *)(above - 1)); - const __m128i A1 = _mm_loadu_si128((const __m128i *)(above + 7)); - const __m128i B0 = _mm_alignr_epi8(A1, A0, 2); - const __m128i B1 = _mm_srli_si128(A1, 2); - const __m128i C0 = _mm_alignr_epi8(A1, A0, 4); - const __m128i C1 = _mm_srli_si128(A1, 4); - const __m128i avg3_0 = avg3_epu16(&A0, &B0, &C0); - const __m128i avg3_1 = avg3_epu16(&A1, &B1, &C1); - const __m128i L0 = _mm_load_si128((const __m128i *)left); - const __m128i L1 = _mm_load_si128((const __m128i *)(left + 8)); - const __m128i XL0 = _mm_alignr_epi8(L0, _mm_slli_si128(A0, 14), 14); - const __m128i AXL0 = _mm_alignr_epi8(XL0, _mm_slli_si128(A0, 12), 14); - const __m128i XL1 = _mm_alignr_epi8(L1, L0, 14); - const __m128i AXL1 = _mm_alignr_epi8(L1, L0, 12); - const __m128i avg3_left_0 = avg3_epu16(&L0, &XL0, &AXL0); - const __m128i avg2_left_0 = _mm_avg_epu16(L0, XL0); - const __m128i avg3_left_1 = avg3_epu16(&L1, &XL1, &AXL1); - const __m128i avg2_left_1 = _mm_avg_epu16(L1, XL1); - __m128i row_0 = avg3_0; - __m128i row_1 = avg3_1; - __m128i avg2_avg3_left[2][2]; - int i, j; - (void)bd; - - avg2_avg3_left[0][0] = _mm_unpacklo_epi16(avg2_left_0, avg3_left_0); - avg2_avg3_left[0][1] = _mm_unpackhi_epi16(avg2_left_0, avg3_left_0); - avg2_avg3_left[1][0] = _mm_unpacklo_epi16(avg2_left_1, avg3_left_1); - avg2_avg3_left[1][1] = _mm_unpackhi_epi16(avg2_left_1, avg3_left_1); - - for (j = 0; j < 2; ++j) { - for (i = 0; i < 2; ++i) { - const __m128i avg2_avg3 = avg2_avg3_left[j][i]; - row_1 = _mm_alignr_epi8(row_1, row_0, 12); - row_0 = _mm_alignr_epi8(row_0, _mm_slli_si128(avg2_avg3, 12), 12); - _mm_store_si128((__m128i *)dst, row_0); - _mm_store_si128((__m128i *)(dst + 8), row_1); - dst += stride; - row_1 = _mm_alignr_epi8(row_1, row_0, 12); - row_0 = _mm_alignr_epi8(row_0, _mm_slli_si128(avg2_avg3, 8), 12); - _mm_store_si128((__m128i *)dst, row_0); - _mm_store_si128((__m128i *)(dst + 8), row_1); - dst += stride; - row_1 = _mm_alignr_epi8(row_1, row_0, 12); - row_0 = _mm_alignr_epi8(row_0, _mm_slli_si128(avg2_avg3, 4), 12); - _mm_store_si128((__m128i *)dst, row_0); - _mm_store_si128((__m128i *)(dst + 8), row_1); - dst += stride; - row_1 = _mm_alignr_epi8(row_1, row_0, 12); - row_0 = _mm_alignr_epi8(row_0, avg2_avg3, 12); - _mm_store_si128((__m128i *)dst, row_0); - _mm_store_si128((__m128i *)(dst + 8), row_1); - dst += stride; - } - } -} - -void vpx_highbd_d153_predictor_32x32_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i A0 = _mm_loadu_si128((const __m128i *)(above - 1)); - const __m128i A1 = _mm_loadu_si128((const __m128i *)(above + 7)); - const __m128i A2 = _mm_loadu_si128((const __m128i *)(above + 15)); - const __m128i A3 = _mm_loadu_si128((const __m128i *)(above + 23)); - const __m128i B0 = _mm_alignr_epi8(A1, A0, 2); - const __m128i B1 = _mm_alignr_epi8(A2, A1, 2); - const __m128i B2 = _mm_alignr_epi8(A3, A2, 2); - const __m128i B3 = _mm_srli_si128(A3, 2); - const __m128i C0 = _mm_alignr_epi8(A1, A0, 4); - const __m128i C1 = _mm_alignr_epi8(A2, A1, 4); - const __m128i C2 = _mm_alignr_epi8(A3, A2, 4); - const __m128i C3 = _mm_srli_si128(A3, 4); - const __m128i avg3_0 = avg3_epu16(&A0, &B0, &C0); - const __m128i avg3_1 = avg3_epu16(&A1, &B1, &C1); - const __m128i avg3_2 = avg3_epu16(&A2, &B2, &C2); - const __m128i avg3_3 = avg3_epu16(&A3, &B3, &C3); - const __m128i L0 = _mm_load_si128((const __m128i *)left); - const __m128i L1 = _mm_load_si128((const __m128i *)(left + 8)); - const __m128i L2 = _mm_load_si128((const __m128i *)(left + 16)); - const __m128i L3 = _mm_load_si128((const __m128i *)(left + 24)); - const __m128i XL0 = _mm_alignr_epi8(L0, _mm_slli_si128(A0, 14), 14); - const __m128i XL1 = _mm_alignr_epi8(L1, L0, 14); - const __m128i XL2 = _mm_alignr_epi8(L2, L1, 14); - const __m128i XL3 = _mm_alignr_epi8(L3, L2, 14); - const __m128i AXL0 = _mm_alignr_epi8(XL0, _mm_slli_si128(A0, 12), 14); - const __m128i AXL1 = _mm_alignr_epi8(L1, L0, 12); - const __m128i AXL2 = _mm_alignr_epi8(L2, L1, 12); - const __m128i AXL3 = _mm_alignr_epi8(L3, L2, 12); - const __m128i avg3_left_0 = avg3_epu16(&L0, &XL0, &AXL0); - const __m128i avg3_left_1 = avg3_epu16(&L1, &XL1, &AXL1); - const __m128i avg3_left_2 = avg3_epu16(&L2, &XL2, &AXL2); - const __m128i avg3_left_3 = avg3_epu16(&L3, &XL3, &AXL3); - const __m128i avg2_left_0 = _mm_avg_epu16(L0, XL0); - const __m128i avg2_left_1 = _mm_avg_epu16(L1, XL1); - const __m128i avg2_left_2 = _mm_avg_epu16(L2, XL2); - const __m128i avg2_left_3 = _mm_avg_epu16(L3, XL3); - __m128i row_0 = avg3_0; - __m128i row_1 = avg3_1; - __m128i row_2 = avg3_2; - __m128i row_3 = avg3_3; - __m128i avg2_avg3_left[4][2]; - int i, j; - (void)bd; - - avg2_avg3_left[0][0] = _mm_unpacklo_epi16(avg2_left_0, avg3_left_0); - avg2_avg3_left[0][1] = _mm_unpackhi_epi16(avg2_left_0, avg3_left_0); - avg2_avg3_left[1][0] = _mm_unpacklo_epi16(avg2_left_1, avg3_left_1); - avg2_avg3_left[1][1] = _mm_unpackhi_epi16(avg2_left_1, avg3_left_1); - avg2_avg3_left[2][0] = _mm_unpacklo_epi16(avg2_left_2, avg3_left_2); - avg2_avg3_left[2][1] = _mm_unpackhi_epi16(avg2_left_2, avg3_left_2); - avg2_avg3_left[3][0] = _mm_unpacklo_epi16(avg2_left_3, avg3_left_3); - avg2_avg3_left[3][1] = _mm_unpackhi_epi16(avg2_left_3, avg3_left_3); - - for (j = 0; j < 4; ++j) { - for (i = 0; i < 2; ++i) { - const __m128i avg2_avg3 = avg2_avg3_left[j][i]; - row_3 = _mm_alignr_epi8(row_3, row_2, 12); - row_2 = _mm_alignr_epi8(row_2, row_1, 12); - row_1 = _mm_alignr_epi8(row_1, row_0, 12); - row_0 = _mm_alignr_epi8(row_0, _mm_slli_si128(avg2_avg3, 12), 12); - _mm_store_si128((__m128i *)dst, row_0); - _mm_store_si128((__m128i *)(dst + 8), row_1); - _mm_store_si128((__m128i *)(dst + 16), row_2); - _mm_store_si128((__m128i *)(dst + 24), row_3); - dst += stride; - row_3 = _mm_alignr_epi8(row_3, row_2, 12); - row_2 = _mm_alignr_epi8(row_2, row_1, 12); - row_1 = _mm_alignr_epi8(row_1, row_0, 12); - row_0 = _mm_alignr_epi8(row_0, _mm_slli_si128(avg2_avg3, 8), 12); - _mm_store_si128((__m128i *)dst, row_0); - _mm_store_si128((__m128i *)(dst + 8), row_1); - _mm_store_si128((__m128i *)(dst + 16), row_2); - _mm_store_si128((__m128i *)(dst + 24), row_3); - dst += stride; - row_3 = _mm_alignr_epi8(row_3, row_2, 12); - row_2 = _mm_alignr_epi8(row_2, row_1, 12); - row_1 = _mm_alignr_epi8(row_1, row_0, 12); - row_0 = _mm_alignr_epi8(row_0, _mm_slli_si128(avg2_avg3, 4), 12); - _mm_store_si128((__m128i *)dst, row_0); - _mm_store_si128((__m128i *)(dst + 8), row_1); - _mm_store_si128((__m128i *)(dst + 16), row_2); - _mm_store_si128((__m128i *)(dst + 24), row_3); - dst += stride; - row_3 = _mm_alignr_epi8(row_3, row_2, 12); - row_2 = _mm_alignr_epi8(row_2, row_1, 12); - row_1 = _mm_alignr_epi8(row_1, row_0, 12); - row_0 = _mm_alignr_epi8(row_0, avg2_avg3, 12); - _mm_store_si128((__m128i *)dst, row_0); - _mm_store_si128((__m128i *)(dst + 8), row_1); - _mm_store_si128((__m128i *)(dst + 16), row_2); - _mm_store_si128((__m128i *)(dst + 24), row_3); - dst += stride; - } - } -} - -static INLINE void d207_store_4x8(uint16_t **dst, const ptrdiff_t stride, - const __m128i *a, const __m128i *b) { - _mm_store_si128((__m128i *)*dst, *a); - *dst += stride; - _mm_store_si128((__m128i *)*dst, _mm_alignr_epi8(*b, *a, 4)); - *dst += stride; - _mm_store_si128((__m128i *)*dst, _mm_alignr_epi8(*b, *a, 8)); - *dst += stride; - _mm_store_si128((__m128i *)*dst, _mm_alignr_epi8(*b, *a, 12)); - *dst += stride; -} - -void vpx_highbd_d207_predictor_8x8_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i ABCDEFGH = _mm_load_si128((const __m128i *)left); - const __m128i ABCDHHHH = _mm_shufflehi_epi16(ABCDEFGH, 0xff); - const __m128i HHHHHHHH = _mm_unpackhi_epi64(ABCDHHHH, ABCDHHHH); - const __m128i BCDEFGHH = _mm_alignr_epi8(HHHHHHHH, ABCDEFGH, 2); - const __m128i CDEFGHHH = _mm_alignr_epi8(HHHHHHHH, ABCDEFGH, 4); - const __m128i avg3 = avg3_epu16(&ABCDEFGH, &BCDEFGHH, &CDEFGHHH); - const __m128i avg2 = _mm_avg_epu16(ABCDEFGH, BCDEFGHH); - const __m128i out_a = _mm_unpacklo_epi16(avg2, avg3); - const __m128i out_b = _mm_unpackhi_epi16(avg2, avg3); - (void)above; - (void)bd; - d207_store_4x8(&dst, stride, &out_a, &out_b); - d207_store_4x8(&dst, stride, &out_b, &HHHHHHHH); -} - -static INLINE void d207_store_4x16(uint16_t **dst, const ptrdiff_t stride, - const __m128i *a, const __m128i *b, - const __m128i *c) { - _mm_store_si128((__m128i *)*dst, *a); - _mm_store_si128((__m128i *)(*dst + 8), *b); - *dst += stride; - _mm_store_si128((__m128i *)*dst, _mm_alignr_epi8(*b, *a, 4)); - _mm_store_si128((__m128i *)(*dst + 8), _mm_alignr_epi8(*c, *b, 4)); - *dst += stride; - _mm_store_si128((__m128i *)*dst, _mm_alignr_epi8(*b, *a, 8)); - _mm_store_si128((__m128i *)(*dst + 8), _mm_alignr_epi8(*c, *b, 8)); - *dst += stride; - _mm_store_si128((__m128i *)*dst, _mm_alignr_epi8(*b, *a, 12)); - _mm_store_si128((__m128i *)(*dst + 8), _mm_alignr_epi8(*c, *b, 12)); - *dst += stride; -} - -void vpx_highbd_d207_predictor_16x16_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i A0 = _mm_load_si128((const __m128i *)left); - const __m128i A1 = _mm_load_si128((const __m128i *)(left + 8)); - const __m128i LR0 = _mm_shufflehi_epi16(A1, 0xff); - const __m128i LR = _mm_unpackhi_epi64(LR0, LR0); - const __m128i B0 = _mm_alignr_epi8(A1, A0, 2); - const __m128i B1 = _mm_alignr_epi8(LR, A1, 2); - const __m128i C0 = _mm_alignr_epi8(A1, A0, 4); - const __m128i C1 = _mm_alignr_epi8(LR, A1, 4); - const __m128i avg3_0 = avg3_epu16(&A0, &B0, &C0); - const __m128i avg3_1 = avg3_epu16(&A1, &B1, &C1); - const __m128i avg2_0 = _mm_avg_epu16(A0, B0); - const __m128i avg2_1 = _mm_avg_epu16(A1, B1); - const __m128i out_a = _mm_unpacklo_epi16(avg2_0, avg3_0); - const __m128i out_b = _mm_unpackhi_epi16(avg2_0, avg3_0); - const __m128i out_c = _mm_unpacklo_epi16(avg2_1, avg3_1); - const __m128i out_d = _mm_unpackhi_epi16(avg2_1, avg3_1); - (void)above; - (void)bd; - d207_store_4x16(&dst, stride, &out_a, &out_b, &out_c); - d207_store_4x16(&dst, stride, &out_b, &out_c, &out_d); - d207_store_4x16(&dst, stride, &out_c, &out_d, &LR); - d207_store_4x16(&dst, stride, &out_d, &LR, &LR); -} - -static INLINE void d207_store_4x32(uint16_t **dst, const ptrdiff_t stride, - const __m128i *a, const __m128i *b, - const __m128i *c, const __m128i *d, - const __m128i *e) { - _mm_store_si128((__m128i *)*dst, *a); - _mm_store_si128((__m128i *)(*dst + 8), *b); - _mm_store_si128((__m128i *)(*dst + 16), *c); - _mm_store_si128((__m128i *)(*dst + 24), *d); - *dst += stride; - _mm_store_si128((__m128i *)*dst, _mm_alignr_epi8(*b, *a, 4)); - _mm_store_si128((__m128i *)(*dst + 8), _mm_alignr_epi8(*c, *b, 4)); - _mm_store_si128((__m128i *)(*dst + 16), _mm_alignr_epi8(*d, *c, 4)); - _mm_store_si128((__m128i *)(*dst + 24), _mm_alignr_epi8(*e, *d, 4)); - *dst += stride; - _mm_store_si128((__m128i *)*dst, _mm_alignr_epi8(*b, *a, 8)); - _mm_store_si128((__m128i *)(*dst + 8), _mm_alignr_epi8(*c, *b, 8)); - _mm_store_si128((__m128i *)(*dst + 16), _mm_alignr_epi8(*d, *c, 8)); - _mm_store_si128((__m128i *)(*dst + 24), _mm_alignr_epi8(*e, *d, 8)); - *dst += stride; - _mm_store_si128((__m128i *)*dst, _mm_alignr_epi8(*b, *a, 12)); - _mm_store_si128((__m128i *)(*dst + 8), _mm_alignr_epi8(*c, *b, 12)); - _mm_store_si128((__m128i *)(*dst + 16), _mm_alignr_epi8(*d, *c, 12)); - _mm_store_si128((__m128i *)(*dst + 24), _mm_alignr_epi8(*e, *d, 12)); - *dst += stride; -} - -void vpx_highbd_d207_predictor_32x32_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i A0 = _mm_load_si128((const __m128i *)left); - const __m128i A1 = _mm_load_si128((const __m128i *)(left + 8)); - const __m128i A2 = _mm_load_si128((const __m128i *)(left + 16)); - const __m128i A3 = _mm_load_si128((const __m128i *)(left + 24)); - const __m128i LR0 = _mm_shufflehi_epi16(A3, 0xff); - const __m128i LR = _mm_unpackhi_epi64(LR0, LR0); - const __m128i B0 = _mm_alignr_epi8(A1, A0, 2); - const __m128i B1 = _mm_alignr_epi8(A2, A1, 2); - const __m128i B2 = _mm_alignr_epi8(A3, A2, 2); - const __m128i B3 = _mm_alignr_epi8(LR, A3, 2); - const __m128i C0 = _mm_alignr_epi8(A1, A0, 4); - const __m128i C1 = _mm_alignr_epi8(A2, A1, 4); - const __m128i C2 = _mm_alignr_epi8(A3, A2, 4); - const __m128i C3 = _mm_alignr_epi8(LR, A3, 4); - const __m128i avg3_0 = avg3_epu16(&A0, &B0, &C0); - const __m128i avg3_1 = avg3_epu16(&A1, &B1, &C1); - const __m128i avg3_2 = avg3_epu16(&A2, &B2, &C2); - const __m128i avg3_3 = avg3_epu16(&A3, &B3, &C3); - const __m128i avg2_0 = _mm_avg_epu16(A0, B0); - const __m128i avg2_1 = _mm_avg_epu16(A1, B1); - const __m128i avg2_2 = _mm_avg_epu16(A2, B2); - const __m128i avg2_3 = _mm_avg_epu16(A3, B3); - const __m128i out_a = _mm_unpacklo_epi16(avg2_0, avg3_0); - const __m128i out_b = _mm_unpackhi_epi16(avg2_0, avg3_0); - const __m128i out_c = _mm_unpacklo_epi16(avg2_1, avg3_1); - const __m128i out_d = _mm_unpackhi_epi16(avg2_1, avg3_1); - const __m128i out_e = _mm_unpacklo_epi16(avg2_2, avg3_2); - const __m128i out_f = _mm_unpackhi_epi16(avg2_2, avg3_2); - const __m128i out_g = _mm_unpacklo_epi16(avg2_3, avg3_3); - const __m128i out_h = _mm_unpackhi_epi16(avg2_3, avg3_3); - (void)above; - (void)bd; - d207_store_4x32(&dst, stride, &out_a, &out_b, &out_c, &out_d, &out_e); - d207_store_4x32(&dst, stride, &out_b, &out_c, &out_d, &out_e, &out_f); - d207_store_4x32(&dst, stride, &out_c, &out_d, &out_e, &out_f, &out_g); - d207_store_4x32(&dst, stride, &out_d, &out_e, &out_f, &out_g, &out_h); - d207_store_4x32(&dst, stride, &out_e, &out_f, &out_g, &out_h, &LR); - d207_store_4x32(&dst, stride, &out_f, &out_g, &out_h, &LR, &LR); - d207_store_4x32(&dst, stride, &out_g, &out_h, &LR, &LR, &LR); - d207_store_4x32(&dst, stride, &out_h, &LR, &LR, &LR, &LR); -} - -static INLINE void d63_store_4x8(uint16_t **dst, const ptrdiff_t stride, - __m128i *a, __m128i *b, const __m128i *ar) { - _mm_store_si128((__m128i *)*dst, *a); - *dst += stride; - _mm_store_si128((__m128i *)*dst, *b); - *dst += stride; - *a = _mm_alignr_epi8(*ar, *a, 2); - *b = _mm_alignr_epi8(*ar, *b, 2); - _mm_store_si128((__m128i *)*dst, *a); - *dst += stride; - _mm_store_si128((__m128i *)*dst, *b); - *dst += stride; - *a = _mm_alignr_epi8(*ar, *a, 2); - *b = _mm_alignr_epi8(*ar, *b, 2); -} - -void vpx_highbd_d63_predictor_8x8_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i ABCDEFGH = _mm_load_si128((const __m128i *)above); - const __m128i ABCDHHHH = _mm_shufflehi_epi16(ABCDEFGH, 0xff); - const __m128i HHHHHHHH = _mm_unpackhi_epi64(ABCDHHHH, ABCDHHHH); - const __m128i BCDEFGHH = _mm_alignr_epi8(HHHHHHHH, ABCDEFGH, 2); - const __m128i CDEFGHHH = _mm_alignr_epi8(HHHHHHHH, ABCDEFGH, 4); - __m128i avg3 = avg3_epu16(&ABCDEFGH, &BCDEFGHH, &CDEFGHHH); - __m128i avg2 = _mm_avg_epu16(ABCDEFGH, BCDEFGHH); - (void)left; - (void)bd; - d63_store_4x8(&dst, stride, &avg2, &avg3, &HHHHHHHH); - d63_store_4x8(&dst, stride, &avg2, &avg3, &HHHHHHHH); -} - -void vpx_highbd_d63_predictor_16x16_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i A0 = _mm_load_si128((const __m128i *)above); - const __m128i A1 = _mm_load_si128((const __m128i *)(above + 8)); - const __m128i AR0 = _mm_shufflehi_epi16(A1, 0xff); - const __m128i AR = _mm_unpackhi_epi64(AR0, AR0); - const __m128i B0 = _mm_alignr_epi8(A1, A0, 2); - const __m128i B1 = _mm_alignr_epi8(AR, A1, 2); - const __m128i C0 = _mm_alignr_epi8(A1, A0, 4); - const __m128i C1 = _mm_alignr_epi8(AR, A1, 4); - __m128i avg3_0 = avg3_epu16(&A0, &B0, &C0); - __m128i avg3_1 = avg3_epu16(&A1, &B1, &C1); - __m128i avg2_0 = _mm_avg_epu16(A0, B0); - __m128i avg2_1 = _mm_avg_epu16(A1, B1); - int i; - (void)left; - (void)bd; - for (i = 0; i < 14; i += 2) { - _mm_store_si128((__m128i *)dst, avg2_0); - _mm_store_si128((__m128i *)(dst + 8), avg2_1); - dst += stride; - _mm_store_si128((__m128i *)dst, avg3_0); - _mm_store_si128((__m128i *)(dst + 8), avg3_1); - dst += stride; - avg2_0 = _mm_alignr_epi8(avg2_1, avg2_0, 2); - avg2_1 = _mm_alignr_epi8(AR, avg2_1, 2); - avg3_0 = _mm_alignr_epi8(avg3_1, avg3_0, 2); - avg3_1 = _mm_alignr_epi8(AR, avg3_1, 2); - } - _mm_store_si128((__m128i *)dst, avg2_0); - _mm_store_si128((__m128i *)(dst + 8), avg2_1); - dst += stride; - _mm_store_si128((__m128i *)dst, avg3_0); - _mm_store_si128((__m128i *)(dst + 8), avg3_1); -} - -void vpx_highbd_d63_predictor_32x32_ssse3(uint16_t *dst, ptrdiff_t stride, - const uint16_t *above, - const uint16_t *left, int bd) { - const __m128i A0 = _mm_load_si128((const __m128i *)above); - const __m128i A1 = _mm_load_si128((const __m128i *)(above + 8)); - const __m128i A2 = _mm_load_si128((const __m128i *)(above + 16)); - const __m128i A3 = _mm_load_si128((const __m128i *)(above + 24)); - const __m128i AR0 = _mm_shufflehi_epi16(A3, 0xff); - const __m128i AR = _mm_unpackhi_epi64(AR0, AR0); - const __m128i B0 = _mm_alignr_epi8(A1, A0, 2); - const __m128i B1 = _mm_alignr_epi8(A2, A1, 2); - const __m128i B2 = _mm_alignr_epi8(A3, A2, 2); - const __m128i B3 = _mm_alignr_epi8(AR, A3, 2); - const __m128i C0 = _mm_alignr_epi8(A1, A0, 4); - const __m128i C1 = _mm_alignr_epi8(A2, A1, 4); - const __m128i C2 = _mm_alignr_epi8(A3, A2, 4); - const __m128i C3 = _mm_alignr_epi8(AR, A3, 4); - __m128i avg3_0 = avg3_epu16(&A0, &B0, &C0); - __m128i avg3_1 = avg3_epu16(&A1, &B1, &C1); - __m128i avg3_2 = avg3_epu16(&A2, &B2, &C2); - __m128i avg3_3 = avg3_epu16(&A3, &B3, &C3); - __m128i avg2_0 = _mm_avg_epu16(A0, B0); - __m128i avg2_1 = _mm_avg_epu16(A1, B1); - __m128i avg2_2 = _mm_avg_epu16(A2, B2); - __m128i avg2_3 = _mm_avg_epu16(A3, B3); - int i; - (void)left; - (void)bd; - for (i = 0; i < 30; i += 2) { - _mm_store_si128((__m128i *)dst, avg2_0); - _mm_store_si128((__m128i *)(dst + 8), avg2_1); - _mm_store_si128((__m128i *)(dst + 16), avg2_2); - _mm_store_si128((__m128i *)(dst + 24), avg2_3); - dst += stride; - _mm_store_si128((__m128i *)dst, avg3_0); - _mm_store_si128((__m128i *)(dst + 8), avg3_1); - _mm_store_si128((__m128i *)(dst + 16), avg3_2); - _mm_store_si128((__m128i *)(dst + 24), avg3_3); - dst += stride; - avg2_0 = _mm_alignr_epi8(avg2_1, avg2_0, 2); - avg2_1 = _mm_alignr_epi8(avg2_2, avg2_1, 2); - avg2_2 = _mm_alignr_epi8(avg2_3, avg2_2, 2); - avg2_3 = _mm_alignr_epi8(AR, avg2_3, 2); - avg3_0 = _mm_alignr_epi8(avg3_1, avg3_0, 2); - avg3_1 = _mm_alignr_epi8(avg3_2, avg3_1, 2); - avg3_2 = _mm_alignr_epi8(avg3_3, avg3_2, 2); - avg3_3 = _mm_alignr_epi8(AR, avg3_3, 2); - } - _mm_store_si128((__m128i *)dst, avg2_0); - _mm_store_si128((__m128i *)(dst + 8), avg2_1); - _mm_store_si128((__m128i *)(dst + 16), avg2_2); - _mm_store_si128((__m128i *)(dst + 24), avg2_3); - dst += stride; - _mm_store_si128((__m128i *)dst, avg3_0); - _mm_store_si128((__m128i *)(dst + 8), avg3_1); - _mm_store_si128((__m128i *)(dst + 16), avg3_2); - _mm_store_si128((__m128i *)(dst + 24), avg3_3); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_intrapred_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_intrapred_sse2.asm deleted file mode 100644 index caf506ac..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_intrapred_sse2.asm +++ /dev/null @@ -1,453 +0,0 @@ -; -; Copyright (c) 2014 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "third_party/x86inc/x86inc.asm" - -SECTION_RODATA -pw_4: times 8 dw 4 -pw_8: times 8 dw 8 -pw_16: times 4 dd 16 -pw_32: times 4 dd 32 - -SECTION .text -INIT_XMM sse2 -cglobal highbd_dc_predictor_4x4, 4, 5, 4, dst, stride, above, left, goffset - GET_GOT goffsetq - - movq m0, [aboveq] - movq m2, [leftq] - paddw m0, m2 - pshuflw m1, m0, 0xe - paddw m0, m1 - pshuflw m1, m0, 0x1 - paddw m0, m1 - paddw m0, [GLOBAL(pw_4)] - psraw m0, 3 - pshuflw m0, m0, 0x0 - movq [dstq ], m0 - movq [dstq+strideq*2], m0 - lea dstq, [dstq+strideq*4] - movq [dstq ], m0 - movq [dstq+strideq*2], m0 - - RESTORE_GOT - RET - -INIT_XMM sse2 -cglobal highbd_dc_predictor_8x8, 4, 5, 4, dst, stride, above, left, goffset - GET_GOT goffsetq - - pxor m1, m1 - mova m0, [aboveq] - mova m2, [leftq] - DEFINE_ARGS dst, stride, stride3, one - mov oned, 0x00010001 - lea stride3q, [strideq*3] - movd m3, oned - pshufd m3, m3, 0x0 - paddw m0, m2 - pmaddwd m0, m3 - packssdw m0, m1 - pmaddwd m0, m3 - packssdw m0, m1 - pmaddwd m0, m3 - paddw m0, [GLOBAL(pw_8)] - psrlw m0, 4 - pshuflw m0, m0, 0x0 - punpcklqdq m0, m0 - mova [dstq ], m0 - mova [dstq+strideq*2 ], m0 - mova [dstq+strideq*4 ], m0 - mova [dstq+stride3q*2], m0 - lea dstq, [dstq+strideq*8] - mova [dstq ], m0 - mova [dstq+strideq*2 ], m0 - mova [dstq+strideq*4 ], m0 - mova [dstq+stride3q*2], m0 - - RESTORE_GOT - RET - -INIT_XMM sse2 -cglobal highbd_dc_predictor_16x16, 4, 5, 5, dst, stride, above, left, goffset - GET_GOT goffsetq - - pxor m1, m1 - mova m0, [aboveq] - mova m3, [aboveq+16] - mova m2, [leftq] - mova m4, [leftq+16] - DEFINE_ARGS dst, stride, stride3, lines4 - lea stride3q, [strideq*3] - mov lines4d, 4 - paddw m0, m2 - paddw m0, m3 - paddw m0, m4 - movhlps m2, m0 - paddw m0, m2 - punpcklwd m0, m1 - movhlps m2, m0 - paddd m0, m2 - punpckldq m0, m1 - movhlps m2, m0 - paddd m0, m2 - paddd m0, [GLOBAL(pw_16)] - psrad m0, 5 - pshuflw m0, m0, 0x0 - punpcklqdq m0, m0 -.loop: - mova [dstq ], m0 - mova [dstq +16], m0 - mova [dstq+strideq*2 ], m0 - mova [dstq+strideq*2 +16], m0 - mova [dstq+strideq*4 ], m0 - mova [dstq+strideq*4 +16], m0 - mova [dstq+stride3q*2 ], m0 - mova [dstq+stride3q*2+16], m0 - lea dstq, [dstq+strideq*8] - dec lines4d - jnz .loop - - RESTORE_GOT - REP_RET - -INIT_XMM sse2 -cglobal highbd_dc_predictor_32x32, 4, 5, 7, dst, stride, above, left, goffset - GET_GOT goffsetq - - mova m0, [aboveq] - mova m2, [aboveq+16] - mova m3, [aboveq+32] - mova m4, [aboveq+48] - paddw m0, m2 - paddw m3, m4 - mova m2, [leftq] - mova m4, [leftq+16] - mova m5, [leftq+32] - mova m6, [leftq+48] - paddw m2, m4 - paddw m5, m6 - paddw m0, m3 - paddw m2, m5 - pxor m1, m1 - paddw m0, m2 - DEFINE_ARGS dst, stride, stride3, lines4 - lea stride3q, [strideq*3] - mov lines4d, 8 - movhlps m2, m0 - paddw m0, m2 - punpcklwd m0, m1 - movhlps m2, m0 - paddd m0, m2 - punpckldq m0, m1 - movhlps m2, m0 - paddd m0, m2 - paddd m0, [GLOBAL(pw_32)] - psrad m0, 6 - pshuflw m0, m0, 0x0 - punpcklqdq m0, m0 -.loop: - mova [dstq ], m0 - mova [dstq +16 ], m0 - mova [dstq +32 ], m0 - mova [dstq +48 ], m0 - mova [dstq+strideq*2 ], m0 - mova [dstq+strideq*2+16 ], m0 - mova [dstq+strideq*2+32 ], m0 - mova [dstq+strideq*2+48 ], m0 - mova [dstq+strideq*4 ], m0 - mova [dstq+strideq*4+16 ], m0 - mova [dstq+strideq*4+32 ], m0 - mova [dstq+strideq*4+48 ], m0 - mova [dstq+stride3q*2 ], m0 - mova [dstq+stride3q*2 +16], m0 - mova [dstq+stride3q*2 +32], m0 - mova [dstq+stride3q*2 +48], m0 - lea dstq, [dstq+strideq*8] - dec lines4d - jnz .loop - - RESTORE_GOT - REP_RET - -INIT_XMM sse2 -cglobal highbd_v_predictor_4x4, 3, 3, 1, dst, stride, above - movq m0, [aboveq] - movq [dstq ], m0 - movq [dstq+strideq*2], m0 - lea dstq, [dstq+strideq*4] - movq [dstq ], m0 - movq [dstq+strideq*2], m0 - RET - -INIT_XMM sse2 -cglobal highbd_v_predictor_8x8, 3, 3, 1, dst, stride, above - mova m0, [aboveq] - DEFINE_ARGS dst, stride, stride3 - lea stride3q, [strideq*3] - mova [dstq ], m0 - mova [dstq+strideq*2 ], m0 - mova [dstq+strideq*4 ], m0 - mova [dstq+stride3q*2], m0 - lea dstq, [dstq+strideq*8] - mova [dstq ], m0 - mova [dstq+strideq*2 ], m0 - mova [dstq+strideq*4 ], m0 - mova [dstq+stride3q*2], m0 - RET - -INIT_XMM sse2 -cglobal highbd_v_predictor_16x16, 3, 4, 2, dst, stride, above - mova m0, [aboveq] - mova m1, [aboveq+16] - DEFINE_ARGS dst, stride, stride3, nlines4 - lea stride3q, [strideq*3] - mov nlines4d, 4 -.loop: - mova [dstq ], m0 - mova [dstq +16], m1 - mova [dstq+strideq*2 ], m0 - mova [dstq+strideq*2 +16], m1 - mova [dstq+strideq*4 ], m0 - mova [dstq+strideq*4 +16], m1 - mova [dstq+stride3q*2 ], m0 - mova [dstq+stride3q*2+16], m1 - lea dstq, [dstq+strideq*8] - dec nlines4d - jnz .loop - REP_RET - -INIT_XMM sse2 -cglobal highbd_v_predictor_32x32, 3, 4, 4, dst, stride, above - mova m0, [aboveq] - mova m1, [aboveq+16] - mova m2, [aboveq+32] - mova m3, [aboveq+48] - DEFINE_ARGS dst, stride, stride3, nlines4 - lea stride3q, [strideq*3] - mov nlines4d, 8 -.loop: - mova [dstq ], m0 - mova [dstq +16], m1 - mova [dstq +32], m2 - mova [dstq +48], m3 - mova [dstq+strideq*2 ], m0 - mova [dstq+strideq*2 +16], m1 - mova [dstq+strideq*2 +32], m2 - mova [dstq+strideq*2 +48], m3 - mova [dstq+strideq*4 ], m0 - mova [dstq+strideq*4 +16], m1 - mova [dstq+strideq*4 +32], m2 - mova [dstq+strideq*4 +48], m3 - mova [dstq+stride3q*2 ], m0 - mova [dstq+stride3q*2 +16], m1 - mova [dstq+stride3q*2 +32], m2 - mova [dstq+stride3q*2 +48], m3 - lea dstq, [dstq+strideq*8] - dec nlines4d - jnz .loop - REP_RET - -INIT_XMM sse2 -cglobal highbd_tm_predictor_4x4, 5, 5, 6, dst, stride, above, left, bd - movd m1, [aboveq-2] - movq m0, [aboveq] - pshuflw m1, m1, 0x0 - movlhps m0, m0 ; t1 t2 t3 t4 t1 t2 t3 t4 - movlhps m1, m1 ; tl tl tl tl tl tl tl tl - ; Get the values to compute the maximum value at this bit depth - pcmpeqw m3, m3 - movd m4, bdd - psubw m0, m1 ; t1-tl t2-tl t3-tl t4-tl - psllw m3, m4 - pcmpeqw m2, m2 - pxor m4, m4 ; min possible value - pxor m3, m2 ; max possible value - mova m1, [leftq] - pshuflw m2, m1, 0x0 - pshuflw m5, m1, 0x55 - movlhps m2, m5 ; l1 l1 l1 l1 l2 l2 l2 l2 - paddw m2, m0 - ;Clamp to the bit-depth - pminsw m2, m3 - pmaxsw m2, m4 - ;Store the values - movq [dstq ], m2 - movhpd [dstq+strideq*2], m2 - lea dstq, [dstq+strideq*4] - pshuflw m2, m1, 0xaa - pshuflw m5, m1, 0xff - movlhps m2, m5 - paddw m2, m0 - ;Clamp to the bit-depth - pminsw m2, m3 - pmaxsw m2, m4 - ;Store the values - movq [dstq ], m2 - movhpd [dstq+strideq*2], m2 - RET - -INIT_XMM sse2 -cglobal highbd_tm_predictor_8x8, 5, 6, 5, dst, stride, above, left, bd, one - movd m1, [aboveq-2] - mova m0, [aboveq] - pshuflw m1, m1, 0x0 - ; Get the values to compute the maximum value at this bit depth - mov oned, 1 - pxor m3, m3 - pxor m4, m4 - pinsrw m3, oned, 0 - pinsrw m4, bdd, 0 - pshuflw m3, m3, 0x0 - DEFINE_ARGS dst, stride, line, left - punpcklqdq m3, m3 - mov lineq, -4 - mova m2, m3 - punpcklqdq m1, m1 - psllw m3, m4 - add leftq, 16 - psubw m3, m2 ; max possible value - pxor m4, m4 ; min possible value - psubw m0, m1 -.loop: - movd m1, [leftq+lineq*4] - movd m2, [leftq+lineq*4+2] - pshuflw m1, m1, 0x0 - pshuflw m2, m2, 0x0 - punpcklqdq m1, m1 - punpcklqdq m2, m2 - paddw m1, m0 - paddw m2, m0 - ;Clamp to the bit-depth - pminsw m1, m3 - pminsw m2, m3 - pmaxsw m1, m4 - pmaxsw m2, m4 - ;Store the values - mova [dstq ], m1 - mova [dstq+strideq*2], m2 - lea dstq, [dstq+strideq*4] - inc lineq - jnz .loop - REP_RET - -INIT_XMM sse2 -cglobal highbd_tm_predictor_16x16, 5, 5, 8, dst, stride, above, left, bd - movd m2, [aboveq-2] - mova m0, [aboveq] - mova m1, [aboveq+16] - pshuflw m2, m2, 0x0 - ; Get the values to compute the maximum value at this bit depth - pcmpeqw m3, m3 - movd m4, bdd - punpcklqdq m2, m2 - psllw m3, m4 - pcmpeqw m5, m5 - pxor m4, m4 ; min possible value - pxor m3, m5 ; max possible value - DEFINE_ARGS dst, stride, line, left - mov lineq, -8 - psubw m0, m2 - psubw m1, m2 -.loop: - movd m7, [leftq] - pshuflw m5, m7, 0x0 - pshuflw m2, m7, 0x55 - punpcklqdq m5, m5 ; l1 l1 l1 l1 l1 l1 l1 l1 - punpcklqdq m2, m2 ; l2 l2 l2 l2 l2 l2 l2 l2 - paddw m6, m5, m0 ; t1-tl+l1 to t4-tl+l1 - paddw m5, m1 ; t5-tl+l1 to t8-tl+l1 - pminsw m6, m3 - pminsw m5, m3 - pmaxsw m6, m4 ; Clamp to the bit-depth - pmaxsw m5, m4 - mova [dstq ], m6 - mova [dstq +16], m5 - paddw m6, m2, m0 - paddw m2, m1 - pminsw m6, m3 - pminsw m2, m3 - pmaxsw m6, m4 - pmaxsw m2, m4 - mova [dstq+strideq*2 ], m6 - mova [dstq+strideq*2+16], m2 - lea dstq, [dstq+strideq*4] - inc lineq - lea leftq, [leftq+4] - - jnz .loop - REP_RET - -INIT_XMM sse2 -cglobal highbd_tm_predictor_32x32, 5, 5, 8, dst, stride, above, left, bd - movd m0, [aboveq-2] - mova m1, [aboveq] - mova m2, [aboveq+16] - mova m3, [aboveq+32] - mova m4, [aboveq+48] - pshuflw m0, m0, 0x0 - ; Get the values to compute the maximum value at this bit depth - pcmpeqw m5, m5 - movd m6, bdd - psllw m5, m6 - pcmpeqw m7, m7 - pxor m6, m6 ; min possible value - pxor m5, m7 ; max possible value - punpcklqdq m0, m0 - DEFINE_ARGS dst, stride, line, left - mov lineq, -16 - psubw m1, m0 - psubw m2, m0 - psubw m3, m0 - psubw m4, m0 -.loop: - movd m7, [leftq] - pshuflw m7, m7, 0x0 - punpcklqdq m7, m7 ; l1 l1 l1 l1 l1 l1 l1 l1 - paddw m0, m7, m1 - pminsw m0, m5 - pmaxsw m0, m6 - mova [dstq ], m0 - paddw m0, m7, m2 - pminsw m0, m5 - pmaxsw m0, m6 - mova [dstq +16], m0 - paddw m0, m7, m3 - pminsw m0, m5 - pmaxsw m0, m6 - mova [dstq +32], m0 - paddw m0, m7, m4 - pminsw m0, m5 - pmaxsw m0, m6 - mova [dstq +48], m0 - movd m7, [leftq+2] - pshuflw m7, m7, 0x0 - punpcklqdq m7, m7 ; l2 l2 l2 l2 l2 l2 l2 l2 - paddw m0, m7, m1 - pminsw m0, m5 - pmaxsw m0, m6 - mova [dstq+strideq*2 ], m0 - paddw m0, m7, m2 - pminsw m0, m5 - pmaxsw m0, m6 - mova [dstq+strideq*2+16], m0 - paddw m0, m7, m3 - pminsw m0, m5 - pmaxsw m0, m6 - mova [dstq+strideq*2+32], m0 - paddw m0, m7, m4 - pminsw m0, m5 - pmaxsw m0, m6 - mova [dstq+strideq*2+48], m0 - lea dstq, [dstq+strideq*4] - lea leftq, [leftq+4] - inc lineq - jnz .loop - REP_RET diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_inv_txfm_sse2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_inv_txfm_sse2.h deleted file mode 100644 index 1d07391b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_inv_txfm_sse2.h +++ /dev/null @@ -1,404 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_X86_HIGHBD_INV_TXFM_SSE2_H_ -#define VPX_VPX_DSP_X86_HIGHBD_INV_TXFM_SSE2_H_ - -#include // SSE2 - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/inv_txfm.h" -#include "vpx_dsp/x86/transpose_sse2.h" -#include "vpx_dsp/x86/txfm_common_sse2.h" - -// Note: There is no 64-bit bit-level shifting SIMD instruction. All -// coefficients are left shifted by 2, so that dct_const_round_shift() can be -// done by right shifting 2 bytes. - -static INLINE void extend_64bit(const __m128i in, - __m128i *const out /*out[2]*/) { - out[0] = _mm_unpacklo_epi32(in, in); // 0, 0, 1, 1 - out[1] = _mm_unpackhi_epi32(in, in); // 2, 2, 3, 3 -} - -static INLINE __m128i wraplow_16bit_shift4(const __m128i in0, const __m128i in1, - const __m128i rounding) { - __m128i temp[2]; - temp[0] = _mm_add_epi32(in0, rounding); - temp[1] = _mm_add_epi32(in1, rounding); - temp[0] = _mm_srai_epi32(temp[0], 4); - temp[1] = _mm_srai_epi32(temp[1], 4); - return _mm_packs_epi32(temp[0], temp[1]); -} - -static INLINE __m128i wraplow_16bit_shift5(const __m128i in0, const __m128i in1, - const __m128i rounding) { - __m128i temp[2]; - temp[0] = _mm_add_epi32(in0, rounding); - temp[1] = _mm_add_epi32(in1, rounding); - temp[0] = _mm_srai_epi32(temp[0], 5); - temp[1] = _mm_srai_epi32(temp[1], 5); - return _mm_packs_epi32(temp[0], temp[1]); -} - -static INLINE __m128i dct_const_round_shift_64bit(const __m128i in) { - const __m128i t = - _mm_add_epi64(in, pair_set_epi32(DCT_CONST_ROUNDING << 2, 0)); - return _mm_srli_si128(t, 2); -} - -static INLINE __m128i pack_4(const __m128i in0, const __m128i in1) { - const __m128i t0 = _mm_unpacklo_epi32(in0, in1); // 0, 2 - const __m128i t1 = _mm_unpackhi_epi32(in0, in1); // 1, 3 - return _mm_unpacklo_epi32(t0, t1); // 0, 1, 2, 3 -} - -static INLINE void abs_extend_64bit_sse2(const __m128i in, - __m128i *const out /*out[2]*/, - __m128i *const sign /*sign[2]*/) { - sign[0] = _mm_srai_epi32(in, 31); - out[0] = _mm_xor_si128(in, sign[0]); - out[0] = _mm_sub_epi32(out[0], sign[0]); - sign[1] = _mm_unpackhi_epi32(sign[0], sign[0]); // 64-bit sign of 2, 3 - sign[0] = _mm_unpacklo_epi32(sign[0], sign[0]); // 64-bit sign of 0, 1 - out[1] = _mm_unpackhi_epi32(out[0], out[0]); // 2, 3 - out[0] = _mm_unpacklo_epi32(out[0], out[0]); // 0, 1 -} - -// Note: cospi must be non negative. -static INLINE __m128i multiply_apply_sign_sse2(const __m128i in, - const __m128i sign, - const __m128i cospi) { - __m128i out = _mm_mul_epu32(in, cospi); - out = _mm_xor_si128(out, sign); - return _mm_sub_epi64(out, sign); -} - -// Note: c must be non negative. -static INLINE __m128i multiplication_round_shift_sse2( - const __m128i *const in /*in[2]*/, const __m128i *const sign /*sign[2]*/, - const int c) { - const __m128i pair_c = pair_set_epi32(c << 2, 0); - __m128i t0, t1; - - assert(c >= 0); - t0 = multiply_apply_sign_sse2(in[0], sign[0], pair_c); - t1 = multiply_apply_sign_sse2(in[1], sign[1], pair_c); - t0 = dct_const_round_shift_64bit(t0); - t1 = dct_const_round_shift_64bit(t1); - - return pack_4(t0, t1); -} - -// Note: c must be non negative. -static INLINE __m128i multiplication_neg_round_shift_sse2( - const __m128i *const in /*in[2]*/, const __m128i *const sign /*sign[2]*/, - const int c) { - const __m128i pair_c = pair_set_epi32(c << 2, 0); - __m128i t0, t1; - - assert(c >= 0); - t0 = multiply_apply_sign_sse2(in[0], sign[0], pair_c); - t1 = multiply_apply_sign_sse2(in[1], sign[1], pair_c); - t0 = _mm_sub_epi64(_mm_setzero_si128(), t0); - t1 = _mm_sub_epi64(_mm_setzero_si128(), t1); - t0 = dct_const_round_shift_64bit(t0); - t1 = dct_const_round_shift_64bit(t1); - - return pack_4(t0, t1); -} - -// Note: c0 and c1 must be non negative. -static INLINE void highbd_butterfly_sse2(const __m128i in0, const __m128i in1, - const int c0, const int c1, - __m128i *const out0, - __m128i *const out1) { - const __m128i pair_c0 = pair_set_epi32(c0 << 2, 0); - const __m128i pair_c1 = pair_set_epi32(c1 << 2, 0); - __m128i temp1[4], temp2[4], sign1[2], sign2[2]; - - assert(c0 >= 0); - assert(c1 >= 0); - abs_extend_64bit_sse2(in0, temp1, sign1); - abs_extend_64bit_sse2(in1, temp2, sign2); - temp1[2] = multiply_apply_sign_sse2(temp1[0], sign1[0], pair_c1); - temp1[3] = multiply_apply_sign_sse2(temp1[1], sign1[1], pair_c1); - temp1[0] = multiply_apply_sign_sse2(temp1[0], sign1[0], pair_c0); - temp1[1] = multiply_apply_sign_sse2(temp1[1], sign1[1], pair_c0); - temp2[2] = multiply_apply_sign_sse2(temp2[0], sign2[0], pair_c0); - temp2[3] = multiply_apply_sign_sse2(temp2[1], sign2[1], pair_c0); - temp2[0] = multiply_apply_sign_sse2(temp2[0], sign2[0], pair_c1); - temp2[1] = multiply_apply_sign_sse2(temp2[1], sign2[1], pair_c1); - temp1[0] = _mm_sub_epi64(temp1[0], temp2[0]); - temp1[1] = _mm_sub_epi64(temp1[1], temp2[1]); - temp2[0] = _mm_add_epi64(temp1[2], temp2[2]); - temp2[1] = _mm_add_epi64(temp1[3], temp2[3]); - temp1[0] = dct_const_round_shift_64bit(temp1[0]); - temp1[1] = dct_const_round_shift_64bit(temp1[1]); - temp2[0] = dct_const_round_shift_64bit(temp2[0]); - temp2[1] = dct_const_round_shift_64bit(temp2[1]); - *out0 = pack_4(temp1[0], temp1[1]); - *out1 = pack_4(temp2[0], temp2[1]); -} - -// Note: c0 and c1 must be non negative. -static INLINE void highbd_partial_butterfly_sse2(const __m128i in, const int c0, - const int c1, - __m128i *const out0, - __m128i *const out1) { - __m128i temp[2], sign[2]; - - assert(c0 >= 0); - assert(c1 >= 0); - abs_extend_64bit_sse2(in, temp, sign); - *out0 = multiplication_round_shift_sse2(temp, sign, c0); - *out1 = multiplication_round_shift_sse2(temp, sign, c1); -} - -// Note: c0 and c1 must be non negative. -static INLINE void highbd_partial_butterfly_neg_sse2(const __m128i in, - const int c0, const int c1, - __m128i *const out0, - __m128i *const out1) { - __m128i temp[2], sign[2]; - - assert(c0 >= 0); - assert(c1 >= 0); - abs_extend_64bit_sse2(in, temp, sign); - *out0 = multiplication_neg_round_shift_sse2(temp, sign, c1); - *out1 = multiplication_round_shift_sse2(temp, sign, c0); -} - -static INLINE void highbd_butterfly_cospi16_sse2(const __m128i in0, - const __m128i in1, - __m128i *const out0, - __m128i *const out1) { - __m128i temp1[2], temp2, sign[2]; - - temp2 = _mm_add_epi32(in0, in1); - abs_extend_64bit_sse2(temp2, temp1, sign); - *out0 = multiplication_round_shift_sse2(temp1, sign, cospi_16_64); - temp2 = _mm_sub_epi32(in0, in1); - abs_extend_64bit_sse2(temp2, temp1, sign); - *out1 = multiplication_round_shift_sse2(temp1, sign, cospi_16_64); -} - -// Only do addition and subtraction butterfly, size = 16, 32 -static INLINE void highbd_add_sub_butterfly(const __m128i *in, __m128i *out, - int size) { - int i = 0; - const int num = size >> 1; - const int bound = size - 1; - while (i < num) { - out[i] = _mm_add_epi32(in[i], in[bound - i]); - out[bound - i] = _mm_sub_epi32(in[i], in[bound - i]); - i++; - } -} - -static INLINE void highbd_idct8_stage4(const __m128i *const in, - __m128i *const out) { - out[0] = _mm_add_epi32(in[0], in[7]); - out[1] = _mm_add_epi32(in[1], in[6]); - out[2] = _mm_add_epi32(in[2], in[5]); - out[3] = _mm_add_epi32(in[3], in[4]); - out[4] = _mm_sub_epi32(in[3], in[4]); - out[5] = _mm_sub_epi32(in[2], in[5]); - out[6] = _mm_sub_epi32(in[1], in[6]); - out[7] = _mm_sub_epi32(in[0], in[7]); -} - -static INLINE void highbd_idct8x8_final_round(__m128i *const io) { - io[0] = wraplow_16bit_shift5(io[0], io[8], _mm_set1_epi32(16)); - io[1] = wraplow_16bit_shift5(io[1], io[9], _mm_set1_epi32(16)); - io[2] = wraplow_16bit_shift5(io[2], io[10], _mm_set1_epi32(16)); - io[3] = wraplow_16bit_shift5(io[3], io[11], _mm_set1_epi32(16)); - io[4] = wraplow_16bit_shift5(io[4], io[12], _mm_set1_epi32(16)); - io[5] = wraplow_16bit_shift5(io[5], io[13], _mm_set1_epi32(16)); - io[6] = wraplow_16bit_shift5(io[6], io[14], _mm_set1_epi32(16)); - io[7] = wraplow_16bit_shift5(io[7], io[15], _mm_set1_epi32(16)); -} - -static INLINE void highbd_idct16_4col_stage7(const __m128i *const in, - __m128i *const out) { - out[0] = _mm_add_epi32(in[0], in[15]); - out[1] = _mm_add_epi32(in[1], in[14]); - out[2] = _mm_add_epi32(in[2], in[13]); - out[3] = _mm_add_epi32(in[3], in[12]); - out[4] = _mm_add_epi32(in[4], in[11]); - out[5] = _mm_add_epi32(in[5], in[10]); - out[6] = _mm_add_epi32(in[6], in[9]); - out[7] = _mm_add_epi32(in[7], in[8]); - out[8] = _mm_sub_epi32(in[7], in[8]); - out[9] = _mm_sub_epi32(in[6], in[9]); - out[10] = _mm_sub_epi32(in[5], in[10]); - out[11] = _mm_sub_epi32(in[4], in[11]); - out[12] = _mm_sub_epi32(in[3], in[12]); - out[13] = _mm_sub_epi32(in[2], in[13]); - out[14] = _mm_sub_epi32(in[1], in[14]); - out[15] = _mm_sub_epi32(in[0], in[15]); -} - -static INLINE __m128i add_clamp(const __m128i in0, const __m128i in1, - const int bd) { - const __m128i zero = _mm_setzero_si128(); - // Faster than _mm_set1_epi16((1 << bd) - 1). - const __m128i one = _mm_set1_epi16(1); - const __m128i max = _mm_sub_epi16(_mm_slli_epi16(one, bd), one); - __m128i d; - - d = _mm_adds_epi16(in0, in1); - d = _mm_max_epi16(d, zero); - d = _mm_min_epi16(d, max); - - return d; -} - -static INLINE void highbd_idct_1_add_kernel(const tran_low_t *input, - uint16_t *dest, int stride, int bd, - const int size) { - int a1, i, j; - tran_low_t out; - __m128i dc, d; - - out = HIGHBD_WRAPLOW( - dct_const_round_shift(input[0] * (tran_high_t)cospi_16_64), bd); - out = - HIGHBD_WRAPLOW(dct_const_round_shift(out * (tran_high_t)cospi_16_64), bd); - a1 = ROUND_POWER_OF_TWO(out, (size == 8) ? 5 : 6); - dc = _mm_set1_epi16(a1); - - for (i = 0; i < size; ++i) { - for (j = 0; j < size; j += 8) { - d = _mm_load_si128((const __m128i *)(&dest[j])); - d = add_clamp(d, dc, bd); - _mm_store_si128((__m128i *)(&dest[j]), d); - } - dest += stride; - } -} - -static INLINE void recon_and_store_4(const __m128i in, uint16_t *const dest, - const int bd) { - __m128i d; - - d = _mm_loadl_epi64((const __m128i *)dest); - d = add_clamp(d, in, bd); - _mm_storel_epi64((__m128i *)dest, d); -} - -static INLINE void recon_and_store_4x2(const __m128i in, uint16_t *const dest, - const int stride, const int bd) { - __m128i d; - - d = _mm_loadl_epi64((const __m128i *)(dest + 0 * stride)); - d = _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(d), (const __m64 *)(dest + 1 * stride))); - d = add_clamp(d, in, bd); - _mm_storel_epi64((__m128i *)(dest + 0 * stride), d); - _mm_storeh_pi((__m64 *)(dest + 1 * stride), _mm_castsi128_ps(d)); -} - -static INLINE void recon_and_store_4x4(const __m128i *const in, uint16_t *dest, - const int stride, const int bd) { - recon_and_store_4x2(in[0], dest, stride, bd); - dest += 2 * stride; - recon_and_store_4x2(in[1], dest, stride, bd); -} - -static INLINE void recon_and_store_8(const __m128i in, uint16_t **const dest, - const int stride, const int bd) { - __m128i d; - - d = _mm_load_si128((const __m128i *)(*dest)); - d = add_clamp(d, in, bd); - _mm_store_si128((__m128i *)(*dest), d); - *dest += stride; -} - -static INLINE void recon_and_store_8x8(const __m128i *const in, uint16_t *dest, - const int stride, const int bd) { - recon_and_store_8(in[0], &dest, stride, bd); - recon_and_store_8(in[1], &dest, stride, bd); - recon_and_store_8(in[2], &dest, stride, bd); - recon_and_store_8(in[3], &dest, stride, bd); - recon_and_store_8(in[4], &dest, stride, bd); - recon_and_store_8(in[5], &dest, stride, bd); - recon_and_store_8(in[6], &dest, stride, bd); - recon_and_store_8(in[7], &dest, stride, bd); -} - -static INLINE __m128i load_pack_8_32bit(const tran_low_t *const input) { - const __m128i t0 = _mm_load_si128((const __m128i *)(input + 0)); - const __m128i t1 = _mm_load_si128((const __m128i *)(input + 4)); - return _mm_packs_epi32(t0, t1); -} - -static INLINE void highbd_load_pack_transpose_32bit_8x8(const tran_low_t *input, - const int stride, - __m128i *const in) { - in[0] = load_pack_8_32bit(input + 0 * stride); - in[1] = load_pack_8_32bit(input + 1 * stride); - in[2] = load_pack_8_32bit(input + 2 * stride); - in[3] = load_pack_8_32bit(input + 3 * stride); - in[4] = load_pack_8_32bit(input + 4 * stride); - in[5] = load_pack_8_32bit(input + 5 * stride); - in[6] = load_pack_8_32bit(input + 6 * stride); - in[7] = load_pack_8_32bit(input + 7 * stride); - transpose_16bit_8x8(in, in); -} - -static INLINE void highbd_load_transpose_32bit_8x4(const tran_low_t *input, - const int stride, - __m128i *in) { - in[0] = _mm_load_si128((const __m128i *)(input + 0 * stride + 0)); - in[1] = _mm_load_si128((const __m128i *)(input + 0 * stride + 4)); - in[2] = _mm_load_si128((const __m128i *)(input + 1 * stride + 0)); - in[3] = _mm_load_si128((const __m128i *)(input + 1 * stride + 4)); - in[4] = _mm_load_si128((const __m128i *)(input + 2 * stride + 0)); - in[5] = _mm_load_si128((const __m128i *)(input + 2 * stride + 4)); - in[6] = _mm_load_si128((const __m128i *)(input + 3 * stride + 0)); - in[7] = _mm_load_si128((const __m128i *)(input + 3 * stride + 4)); - transpose_32bit_8x4(in, in); -} - -static INLINE void highbd_load_transpose_32bit_4x4(const tran_low_t *input, - const int stride, - __m128i *in) { - in[0] = _mm_load_si128((const __m128i *)(input + 0 * stride)); - in[1] = _mm_load_si128((const __m128i *)(input + 1 * stride)); - in[2] = _mm_load_si128((const __m128i *)(input + 2 * stride)); - in[3] = _mm_load_si128((const __m128i *)(input + 3 * stride)); - transpose_32bit_4x4(in, in); -} - -static INLINE void highbd_write_buffer_8(uint16_t *dest, const __m128i in, - const int bd) { - const __m128i final_rounding = _mm_set1_epi16(1 << 5); - __m128i out; - - out = _mm_adds_epi16(in, final_rounding); - out = _mm_srai_epi16(out, 6); - recon_and_store_8(out, &dest, 0, bd); -} - -static INLINE void highbd_write_buffer_4(uint16_t *const dest, const __m128i in, - const int bd) { - const __m128i final_rounding = _mm_set1_epi32(1 << 5); - __m128i out; - - out = _mm_add_epi32(in, final_rounding); - out = _mm_srai_epi32(out, 6); - out = _mm_packs_epi32(out, out); - recon_and_store_4(out, dest, bd); -} - -#endif // VPX_VPX_DSP_X86_HIGHBD_INV_TXFM_SSE2_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_inv_txfm_sse4.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_inv_txfm_sse4.h deleted file mode 100644 index f446bb13..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_inv_txfm_sse4.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_X86_HIGHBD_INV_TXFM_SSE4_H_ -#define VPX_VPX_DSP_X86_HIGHBD_INV_TXFM_SSE4_H_ - -#include // SSE4.1 - -#include "./vpx_config.h" -#include "vpx_dsp/x86/highbd_inv_txfm_sse2.h" - -static INLINE __m128i multiplication_round_shift_sse4_1( - const __m128i *const in /*in[2]*/, const int c) { - const __m128i pair_c = pair_set_epi32(c * 4, 0); - __m128i t0, t1; - - t0 = _mm_mul_epi32(in[0], pair_c); - t1 = _mm_mul_epi32(in[1], pair_c); - t0 = dct_const_round_shift_64bit(t0); - t1 = dct_const_round_shift_64bit(t1); - - return pack_4(t0, t1); -} - -static INLINE void highbd_butterfly_sse4_1(const __m128i in0, const __m128i in1, - const int c0, const int c1, - __m128i *const out0, - __m128i *const out1) { - const __m128i pair_c0 = pair_set_epi32(4 * c0, 0); - const __m128i pair_c1 = pair_set_epi32(4 * c1, 0); - __m128i temp1[4], temp2[4]; - - extend_64bit(in0, temp1); - extend_64bit(in1, temp2); - temp1[2] = _mm_mul_epi32(temp1[0], pair_c1); - temp1[3] = _mm_mul_epi32(temp1[1], pair_c1); - temp1[0] = _mm_mul_epi32(temp1[0], pair_c0); - temp1[1] = _mm_mul_epi32(temp1[1], pair_c0); - temp2[2] = _mm_mul_epi32(temp2[0], pair_c0); - temp2[3] = _mm_mul_epi32(temp2[1], pair_c0); - temp2[0] = _mm_mul_epi32(temp2[0], pair_c1); - temp2[1] = _mm_mul_epi32(temp2[1], pair_c1); - temp1[0] = _mm_sub_epi64(temp1[0], temp2[0]); - temp1[1] = _mm_sub_epi64(temp1[1], temp2[1]); - temp2[0] = _mm_add_epi64(temp1[2], temp2[2]); - temp2[1] = _mm_add_epi64(temp1[3], temp2[3]); - temp1[0] = dct_const_round_shift_64bit(temp1[0]); - temp1[1] = dct_const_round_shift_64bit(temp1[1]); - temp2[0] = dct_const_round_shift_64bit(temp2[0]); - temp2[1] = dct_const_round_shift_64bit(temp2[1]); - *out0 = pack_4(temp1[0], temp1[1]); - *out1 = pack_4(temp2[0], temp2[1]); -} - -static INLINE void highbd_butterfly_cospi16_sse4_1(const __m128i in0, - const __m128i in1, - __m128i *const out0, - __m128i *const out1) { - __m128i temp1[2], temp2; - - temp2 = _mm_add_epi32(in0, in1); - extend_64bit(temp2, temp1); - *out0 = multiplication_round_shift_sse4_1(temp1, cospi_16_64); - temp2 = _mm_sub_epi32(in0, in1); - extend_64bit(temp2, temp1); - *out1 = multiplication_round_shift_sse4_1(temp1, cospi_16_64); -} - -static INLINE void highbd_partial_butterfly_sse4_1(const __m128i in, - const int c0, const int c1, - __m128i *const out0, - __m128i *const out1) { - __m128i temp[2]; - - extend_64bit(in, temp); - *out0 = multiplication_round_shift_sse4_1(temp, c0); - *out1 = multiplication_round_shift_sse4_1(temp, c1); -} - -static INLINE void highbd_idct4_sse4_1(__m128i *const io) { - __m128i temp[2], step[4]; - - transpose_32bit_4x4(io, io); - - // stage 1 - temp[0] = _mm_add_epi32(io[0], io[2]); // input[0] + input[2] - extend_64bit(temp[0], temp); - step[0] = multiplication_round_shift_sse4_1(temp, cospi_16_64); - temp[0] = _mm_sub_epi32(io[0], io[2]); // input[0] - input[2] - extend_64bit(temp[0], temp); - step[1] = multiplication_round_shift_sse4_1(temp, cospi_16_64); - highbd_butterfly_sse4_1(io[1], io[3], cospi_24_64, cospi_8_64, &step[2], - &step[3]); - - // stage 2 - io[0] = _mm_add_epi32(step[0], step[3]); // step[0] + step[3] - io[1] = _mm_add_epi32(step[1], step[2]); // step[1] + step[2] - io[2] = _mm_sub_epi32(step[1], step[2]); // step[1] - step[2] - io[3] = _mm_sub_epi32(step[0], step[3]); // step[0] - step[3] -} - -void vpx_highbd_idct8x8_half1d_sse4_1(__m128i *const io); -void vpx_highbd_idct16_4col_sse4_1(__m128i *const io /*io[16]*/); - -#endif // VPX_VPX_DSP_X86_HIGHBD_INV_TXFM_SSE4_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_loopfilter_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_loopfilter_sse2.c deleted file mode 100644 index 9f45623d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_loopfilter_sse2.c +++ /dev/null @@ -1,1140 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // SSE2 - -#include "./vpx_dsp_rtcd.h" -#include "vpx_ports/mem.h" - -static INLINE __m128i signed_char_clamp_bd_sse2(__m128i value, int bd) { - __m128i ubounded; - __m128i lbounded; - __m128i retval; - - const __m128i zero = _mm_setzero_si128(); - const __m128i one = _mm_set1_epi16(1); - __m128i t80, max, min; - - if (bd == 8) { - t80 = _mm_set1_epi16(0x80); - max = _mm_subs_epi16(_mm_subs_epi16(_mm_slli_epi16(one, 8), one), t80); - } else if (bd == 10) { - t80 = _mm_set1_epi16(0x200); - max = _mm_subs_epi16(_mm_subs_epi16(_mm_slli_epi16(one, 10), one), t80); - } else { // bd == 12 - t80 = _mm_set1_epi16(0x800); - max = _mm_subs_epi16(_mm_subs_epi16(_mm_slli_epi16(one, 12), one), t80); - } - - min = _mm_subs_epi16(zero, t80); - - ubounded = _mm_cmpgt_epi16(value, max); - lbounded = _mm_cmplt_epi16(value, min); - retval = _mm_andnot_si128(_mm_or_si128(ubounded, lbounded), value); - ubounded = _mm_and_si128(ubounded, max); - lbounded = _mm_and_si128(lbounded, min); - retval = _mm_or_si128(retval, ubounded); - retval = _mm_or_si128(retval, lbounded); - return retval; -} - -// TODO(debargha, peter): Break up large functions into smaller ones -// in this file. -void vpx_highbd_lpf_horizontal_16_sse2(uint16_t *s, int pitch, - const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh, int bd) { - const __m128i zero = _mm_setzero_si128(); - const __m128i one = _mm_set1_epi16(1); - __m128i blimit_v, limit_v, thresh_v; - __m128i q7, p7, q6, p6, q5, p5, q4, p4, q3, p3, q2, p2, q1, p1, q0, p0; - __m128i mask, hev, flat, flat2, abs_p1p0, abs_q1q0; - __m128i ps1, qs1, ps0, qs0; - __m128i abs_p0q0, abs_p1q1, ffff, work; - __m128i filt, work_a, filter1, filter2; - __m128i flat2_q6, flat2_p6, flat2_q5, flat2_p5, flat2_q4, flat2_p4; - __m128i flat2_q3, flat2_p3, flat2_q2, flat2_p2, flat2_q1, flat2_p1; - __m128i flat2_q0, flat2_p0; - __m128i flat_q2, flat_p2, flat_q1, flat_p1, flat_q0, flat_p0; - __m128i pixelFilter_p, pixelFilter_q; - __m128i pixetFilter_p2p1p0, pixetFilter_q2q1q0; - __m128i sum_p7, sum_q7, sum_p3, sum_q3; - __m128i t4, t3, t80, t1; - __m128i eight, four; - - if (bd == 8) { - blimit_v = _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)blimit), zero); - limit_v = _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)limit), zero); - thresh_v = _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)thresh), zero); - } else if (bd == 10) { - blimit_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)blimit), zero), 2); - limit_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)limit), zero), 2); - thresh_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)thresh), zero), 2); - } else { // bd == 12 - blimit_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)blimit), zero), 4); - limit_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)limit), zero), 4); - thresh_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)thresh), zero), 4); - } - - q4 = _mm_load_si128((__m128i *)(s + 4 * pitch)); - p4 = _mm_load_si128((__m128i *)(s - 5 * pitch)); - q3 = _mm_load_si128((__m128i *)(s + 3 * pitch)); - p3 = _mm_load_si128((__m128i *)(s - 4 * pitch)); - q2 = _mm_load_si128((__m128i *)(s + 2 * pitch)); - p2 = _mm_load_si128((__m128i *)(s - 3 * pitch)); - q1 = _mm_load_si128((__m128i *)(s + 1 * pitch)); - p1 = _mm_load_si128((__m128i *)(s - 2 * pitch)); - q0 = _mm_load_si128((__m128i *)(s + 0 * pitch)); - p0 = _mm_load_si128((__m128i *)(s - 1 * pitch)); - - // highbd_filter_mask - abs_p1p0 = _mm_or_si128(_mm_subs_epu16(p1, p0), _mm_subs_epu16(p0, p1)); - abs_q1q0 = _mm_or_si128(_mm_subs_epu16(q1, q0), _mm_subs_epu16(q0, q1)); - - ffff = _mm_cmpeq_epi16(abs_p1p0, abs_p1p0); - - abs_p0q0 = _mm_or_si128(_mm_subs_epu16(p0, q0), _mm_subs_epu16(q0, p0)); - abs_p1q1 = _mm_or_si128(_mm_subs_epu16(p1, q1), _mm_subs_epu16(q1, p1)); - - // highbd_hev_mask (in C code this is actually called from highbd_filter4) - flat = _mm_max_epi16(abs_p1p0, abs_q1q0); - hev = _mm_subs_epu16(flat, thresh_v); - hev = _mm_xor_si128(_mm_cmpeq_epi16(hev, zero), ffff); - - abs_p0q0 = _mm_adds_epu16(abs_p0q0, abs_p0q0); // abs(p0 - q0) * 2 - abs_p1q1 = _mm_srli_epi16(abs_p1q1, 1); // abs(p1 - q1) / 2 - mask = _mm_subs_epu16(_mm_adds_epu16(abs_p0q0, abs_p1q1), blimit_v); - mask = _mm_xor_si128(_mm_cmpeq_epi16(mask, zero), ffff); - mask = _mm_and_si128(mask, _mm_adds_epu16(limit_v, one)); - work = _mm_max_epi16( - _mm_or_si128(_mm_subs_epu16(p1, p0), _mm_subs_epu16(p0, p1)), - _mm_or_si128(_mm_subs_epu16(q1, q0), _mm_subs_epu16(q0, q1))); - mask = _mm_max_epi16(work, mask); - work = _mm_max_epi16( - _mm_or_si128(_mm_subs_epu16(p2, p1), _mm_subs_epu16(p1, p2)), - _mm_or_si128(_mm_subs_epu16(q2, q1), _mm_subs_epu16(q1, q2))); - mask = _mm_max_epi16(work, mask); - work = _mm_max_epi16( - _mm_or_si128(_mm_subs_epu16(p3, p2), _mm_subs_epu16(p2, p3)), - _mm_or_si128(_mm_subs_epu16(q3, q2), _mm_subs_epu16(q2, q3))); - mask = _mm_max_epi16(work, mask); - - mask = _mm_subs_epu16(mask, limit_v); - mask = _mm_cmpeq_epi16(mask, zero); // return ~mask - - // lp filter - // highbd_filter4 - t4 = _mm_set1_epi16(4); - t3 = _mm_set1_epi16(3); - if (bd == 8) - t80 = _mm_set1_epi16(0x80); - else if (bd == 10) - t80 = _mm_set1_epi16(0x200); - else // bd == 12 - t80 = _mm_set1_epi16(0x800); - - t1 = _mm_set1_epi16(0x1); - - ps1 = _mm_subs_epi16(p1, t80); - qs1 = _mm_subs_epi16(q1, t80); - ps0 = _mm_subs_epi16(p0, t80); - qs0 = _mm_subs_epi16(q0, t80); - - filt = _mm_and_si128(signed_char_clamp_bd_sse2(_mm_subs_epi16(ps1, qs1), bd), - hev); - work_a = _mm_subs_epi16(qs0, ps0); - filt = _mm_adds_epi16(filt, work_a); - filt = _mm_adds_epi16(filt, work_a); - filt = signed_char_clamp_bd_sse2(_mm_adds_epi16(filt, work_a), bd); - filt = _mm_and_si128(filt, mask); - filter1 = signed_char_clamp_bd_sse2(_mm_adds_epi16(filt, t4), bd); - filter2 = signed_char_clamp_bd_sse2(_mm_adds_epi16(filt, t3), bd); - - // Filter1 >> 3 - filter1 = _mm_srai_epi16(filter1, 0x3); - filter2 = _mm_srai_epi16(filter2, 0x3); - - qs0 = _mm_adds_epi16( - signed_char_clamp_bd_sse2(_mm_subs_epi16(qs0, filter1), bd), t80); - ps0 = _mm_adds_epi16( - signed_char_clamp_bd_sse2(_mm_adds_epi16(ps0, filter2), bd), t80); - filt = _mm_adds_epi16(filter1, t1); - filt = _mm_srai_epi16(filt, 1); - filt = _mm_andnot_si128(hev, filt); - qs1 = _mm_adds_epi16(signed_char_clamp_bd_sse2(_mm_subs_epi16(qs1, filt), bd), - t80); - ps1 = _mm_adds_epi16(signed_char_clamp_bd_sse2(_mm_adds_epi16(ps1, filt), bd), - t80); - - // end highbd_filter4 - // loopfilter done - - // highbd_flat_mask4 - flat = _mm_max_epi16( - _mm_or_si128(_mm_subs_epu16(p2, p0), _mm_subs_epu16(p0, p2)), - _mm_or_si128(_mm_subs_epu16(p3, p0), _mm_subs_epu16(p0, p3))); - work = _mm_max_epi16( - _mm_or_si128(_mm_subs_epu16(q2, q0), _mm_subs_epu16(q0, q2)), - _mm_or_si128(_mm_subs_epu16(q3, q0), _mm_subs_epu16(q0, q3))); - flat = _mm_max_epi16(work, flat); - work = _mm_max_epi16(abs_p1p0, abs_q1q0); - flat = _mm_max_epi16(work, flat); - - if (bd == 8) - flat = _mm_subs_epu16(flat, one); - else if (bd == 10) - flat = _mm_subs_epu16(flat, _mm_slli_epi16(one, 2)); - else // bd == 12 - flat = _mm_subs_epu16(flat, _mm_slli_epi16(one, 4)); - - flat = _mm_cmpeq_epi16(flat, zero); - // end flat_mask4 - - // flat & mask = flat && mask (as used in filter8) - // (because, in both vars, each block of 16 either all 1s or all 0s) - flat = _mm_and_si128(flat, mask); - - p5 = _mm_load_si128((__m128i *)(s - 6 * pitch)); - q5 = _mm_load_si128((__m128i *)(s + 5 * pitch)); - p6 = _mm_load_si128((__m128i *)(s - 7 * pitch)); - q6 = _mm_load_si128((__m128i *)(s + 6 * pitch)); - p7 = _mm_load_si128((__m128i *)(s - 8 * pitch)); - q7 = _mm_load_si128((__m128i *)(s + 7 * pitch)); - - // highbd_flat_mask5 (arguments passed in are p0, q0, p4-p7, q4-q7 - // but referred to as p0-p4 & q0-q4 in fn) - flat2 = _mm_max_epi16( - _mm_or_si128(_mm_subs_epu16(p4, p0), _mm_subs_epu16(p0, p4)), - _mm_or_si128(_mm_subs_epu16(q4, q0), _mm_subs_epu16(q0, q4))); - - work = _mm_max_epi16( - _mm_or_si128(_mm_subs_epu16(p5, p0), _mm_subs_epu16(p0, p5)), - _mm_or_si128(_mm_subs_epu16(q5, q0), _mm_subs_epu16(q0, q5))); - flat2 = _mm_max_epi16(work, flat2); - - work = _mm_max_epi16( - _mm_or_si128(_mm_subs_epu16(p6, p0), _mm_subs_epu16(p0, p6)), - _mm_or_si128(_mm_subs_epu16(q6, q0), _mm_subs_epu16(q0, q6))); - flat2 = _mm_max_epi16(work, flat2); - - work = _mm_max_epi16( - _mm_or_si128(_mm_subs_epu16(p7, p0), _mm_subs_epu16(p0, p7)), - _mm_or_si128(_mm_subs_epu16(q7, q0), _mm_subs_epu16(q0, q7))); - flat2 = _mm_max_epi16(work, flat2); - - if (bd == 8) - flat2 = _mm_subs_epu16(flat2, one); - else if (bd == 10) - flat2 = _mm_subs_epu16(flat2, _mm_slli_epi16(one, 2)); - else // bd == 12 - flat2 = _mm_subs_epu16(flat2, _mm_slli_epi16(one, 4)); - - flat2 = _mm_cmpeq_epi16(flat2, zero); - flat2 = _mm_and_si128(flat2, flat); // flat2 & flat & mask - // end highbd_flat_mask5 - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // flat and wide flat calculations - eight = _mm_set1_epi16(8); - four = _mm_set1_epi16(4); - - pixelFilter_p = _mm_add_epi16(_mm_add_epi16(p6, p5), _mm_add_epi16(p4, p3)); - pixelFilter_q = _mm_add_epi16(_mm_add_epi16(q6, q5), _mm_add_epi16(q4, q3)); - - pixetFilter_p2p1p0 = _mm_add_epi16(p0, _mm_add_epi16(p2, p1)); - pixelFilter_p = _mm_add_epi16(pixelFilter_p, pixetFilter_p2p1p0); - - pixetFilter_q2q1q0 = _mm_add_epi16(q0, _mm_add_epi16(q2, q1)); - pixelFilter_q = _mm_add_epi16(pixelFilter_q, pixetFilter_q2q1q0); - pixelFilter_p = - _mm_add_epi16(eight, _mm_add_epi16(pixelFilter_p, pixelFilter_q)); - pixetFilter_p2p1p0 = _mm_add_epi16( - four, _mm_add_epi16(pixetFilter_p2p1p0, pixetFilter_q2q1q0)); - flat2_p0 = - _mm_srli_epi16(_mm_add_epi16(pixelFilter_p, _mm_add_epi16(p7, p0)), 4); - flat2_q0 = - _mm_srli_epi16(_mm_add_epi16(pixelFilter_p, _mm_add_epi16(q7, q0)), 4); - flat_p0 = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_p2p1p0, _mm_add_epi16(p3, p0)), 3); - flat_q0 = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_p2p1p0, _mm_add_epi16(q3, q0)), 3); - - sum_p7 = _mm_add_epi16(p7, p7); - sum_q7 = _mm_add_epi16(q7, q7); - sum_p3 = _mm_add_epi16(p3, p3); - sum_q3 = _mm_add_epi16(q3, q3); - - pixelFilter_q = _mm_sub_epi16(pixelFilter_p, p6); - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q6); - flat2_p1 = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p1)), 4); - flat2_q1 = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q1)), 4); - - pixetFilter_q2q1q0 = _mm_sub_epi16(pixetFilter_p2p1p0, p2); - pixetFilter_p2p1p0 = _mm_sub_epi16(pixetFilter_p2p1p0, q2); - flat_p1 = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_p2p1p0, _mm_add_epi16(sum_p3, p1)), 3); - flat_q1 = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_q2q1q0, _mm_add_epi16(sum_q3, q1)), 3); - - sum_p7 = _mm_add_epi16(sum_p7, p7); - sum_q7 = _mm_add_epi16(sum_q7, q7); - sum_p3 = _mm_add_epi16(sum_p3, p3); - sum_q3 = _mm_add_epi16(sum_q3, q3); - - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q5); - pixelFilter_q = _mm_sub_epi16(pixelFilter_q, p5); - flat2_p2 = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p2)), 4); - flat2_q2 = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q2)), 4); - - pixetFilter_p2p1p0 = _mm_sub_epi16(pixetFilter_p2p1p0, q1); - pixetFilter_q2q1q0 = _mm_sub_epi16(pixetFilter_q2q1q0, p1); - flat_p2 = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_p2p1p0, _mm_add_epi16(sum_p3, p2)), 3); - flat_q2 = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_q2q1q0, _mm_add_epi16(sum_q3, q2)), 3); - - sum_p7 = _mm_add_epi16(sum_p7, p7); - sum_q7 = _mm_add_epi16(sum_q7, q7); - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q4); - pixelFilter_q = _mm_sub_epi16(pixelFilter_q, p4); - flat2_p3 = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p3)), 4); - flat2_q3 = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q3)), 4); - - sum_p7 = _mm_add_epi16(sum_p7, p7); - sum_q7 = _mm_add_epi16(sum_q7, q7); - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q3); - pixelFilter_q = _mm_sub_epi16(pixelFilter_q, p3); - flat2_p4 = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p4)), 4); - flat2_q4 = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q4)), 4); - - sum_p7 = _mm_add_epi16(sum_p7, p7); - sum_q7 = _mm_add_epi16(sum_q7, q7); - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q2); - pixelFilter_q = _mm_sub_epi16(pixelFilter_q, p2); - flat2_p5 = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p5)), 4); - flat2_q5 = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q5)), 4); - - sum_p7 = _mm_add_epi16(sum_p7, p7); - sum_q7 = _mm_add_epi16(sum_q7, q7); - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q1); - pixelFilter_q = _mm_sub_epi16(pixelFilter_q, p1); - flat2_p6 = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p6)), 4); - flat2_q6 = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q6)), 4); - - // wide flat - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - // highbd_filter8 - p2 = _mm_andnot_si128(flat, p2); - // p2 remains unchanged if !(flat && mask) - flat_p2 = _mm_and_si128(flat, flat_p2); - // when (flat && mask) - p2 = _mm_or_si128(p2, flat_p2); // full list of p2 values - q2 = _mm_andnot_si128(flat, q2); - flat_q2 = _mm_and_si128(flat, flat_q2); - q2 = _mm_or_si128(q2, flat_q2); // full list of q2 values - - ps1 = _mm_andnot_si128(flat, ps1); - // p1 takes the value assigned to in in filter4 if !(flat && mask) - flat_p1 = _mm_and_si128(flat, flat_p1); - // when (flat && mask) - p1 = _mm_or_si128(ps1, flat_p1); // full list of p1 values - qs1 = _mm_andnot_si128(flat, qs1); - flat_q1 = _mm_and_si128(flat, flat_q1); - q1 = _mm_or_si128(qs1, flat_q1); // full list of q1 values - - ps0 = _mm_andnot_si128(flat, ps0); - // p0 takes the value assigned to in in filter4 if !(flat && mask) - flat_p0 = _mm_and_si128(flat, flat_p0); - // when (flat && mask) - p0 = _mm_or_si128(ps0, flat_p0); // full list of p0 values - qs0 = _mm_andnot_si128(flat, qs0); - flat_q0 = _mm_and_si128(flat, flat_q0); - q0 = _mm_or_si128(qs0, flat_q0); // full list of q0 values - // end highbd_filter8 - - // highbd_filter16 - p6 = _mm_andnot_si128(flat2, p6); - // p6 remains unchanged if !(flat2 && flat && mask) - flat2_p6 = _mm_and_si128(flat2, flat2_p6); - // get values for when (flat2 && flat && mask) - p6 = _mm_or_si128(p6, flat2_p6); // full list of p6 values - q6 = _mm_andnot_si128(flat2, q6); - // q6 remains unchanged if !(flat2 && flat && mask) - flat2_q6 = _mm_and_si128(flat2, flat2_q6); - // get values for when (flat2 && flat && mask) - q6 = _mm_or_si128(q6, flat2_q6); // full list of q6 values - _mm_store_si128((__m128i *)(s - 7 * pitch), p6); - _mm_store_si128((__m128i *)(s + 6 * pitch), q6); - - p5 = _mm_andnot_si128(flat2, p5); - // p5 remains unchanged if !(flat2 && flat && mask) - flat2_p5 = _mm_and_si128(flat2, flat2_p5); - // get values for when (flat2 && flat && mask) - p5 = _mm_or_si128(p5, flat2_p5); - // full list of p5 values - q5 = _mm_andnot_si128(flat2, q5); - // q5 remains unchanged if !(flat2 && flat && mask) - flat2_q5 = _mm_and_si128(flat2, flat2_q5); - // get values for when (flat2 && flat && mask) - q5 = _mm_or_si128(q5, flat2_q5); - // full list of q5 values - _mm_store_si128((__m128i *)(s - 6 * pitch), p5); - _mm_store_si128((__m128i *)(s + 5 * pitch), q5); - - p4 = _mm_andnot_si128(flat2, p4); - // p4 remains unchanged if !(flat2 && flat && mask) - flat2_p4 = _mm_and_si128(flat2, flat2_p4); - // get values for when (flat2 && flat && mask) - p4 = _mm_or_si128(p4, flat2_p4); // full list of p4 values - q4 = _mm_andnot_si128(flat2, q4); - // q4 remains unchanged if !(flat2 && flat && mask) - flat2_q4 = _mm_and_si128(flat2, flat2_q4); - // get values for when (flat2 && flat && mask) - q4 = _mm_or_si128(q4, flat2_q4); // full list of q4 values - _mm_store_si128((__m128i *)(s - 5 * pitch), p4); - _mm_store_si128((__m128i *)(s + 4 * pitch), q4); - - p3 = _mm_andnot_si128(flat2, p3); - // p3 takes value from highbd_filter8 if !(flat2 && flat && mask) - flat2_p3 = _mm_and_si128(flat2, flat2_p3); - // get values for when (flat2 && flat && mask) - p3 = _mm_or_si128(p3, flat2_p3); // full list of p3 values - q3 = _mm_andnot_si128(flat2, q3); - // q3 takes value from highbd_filter8 if !(flat2 && flat && mask) - flat2_q3 = _mm_and_si128(flat2, flat2_q3); - // get values for when (flat2 && flat && mask) - q3 = _mm_or_si128(q3, flat2_q3); // full list of q3 values - _mm_store_si128((__m128i *)(s - 4 * pitch), p3); - _mm_store_si128((__m128i *)(s + 3 * pitch), q3); - - p2 = _mm_andnot_si128(flat2, p2); - // p2 takes value from highbd_filter8 if !(flat2 && flat && mask) - flat2_p2 = _mm_and_si128(flat2, flat2_p2); - // get values for when (flat2 && flat && mask) - p2 = _mm_or_si128(p2, flat2_p2); - // full list of p2 values - q2 = _mm_andnot_si128(flat2, q2); - // q2 takes value from highbd_filter8 if !(flat2 && flat && mask) - flat2_q2 = _mm_and_si128(flat2, flat2_q2); - // get values for when (flat2 && flat && mask) - q2 = _mm_or_si128(q2, flat2_q2); // full list of q2 values - _mm_store_si128((__m128i *)(s - 3 * pitch), p2); - _mm_store_si128((__m128i *)(s + 2 * pitch), q2); - - p1 = _mm_andnot_si128(flat2, p1); - // p1 takes value from highbd_filter8 if !(flat2 && flat && mask) - flat2_p1 = _mm_and_si128(flat2, flat2_p1); - // get values for when (flat2 && flat && mask) - p1 = _mm_or_si128(p1, flat2_p1); // full list of p1 values - q1 = _mm_andnot_si128(flat2, q1); - // q1 takes value from highbd_filter8 if !(flat2 && flat && mask) - flat2_q1 = _mm_and_si128(flat2, flat2_q1); - // get values for when (flat2 && flat && mask) - q1 = _mm_or_si128(q1, flat2_q1); // full list of q1 values - _mm_store_si128((__m128i *)(s - 2 * pitch), p1); - _mm_store_si128((__m128i *)(s + 1 * pitch), q1); - - p0 = _mm_andnot_si128(flat2, p0); - // p0 takes value from highbd_filter8 if !(flat2 && flat && mask) - flat2_p0 = _mm_and_si128(flat2, flat2_p0); - // get values for when (flat2 && flat && mask) - p0 = _mm_or_si128(p0, flat2_p0); // full list of p0 values - q0 = _mm_andnot_si128(flat2, q0); - // q0 takes value from highbd_filter8 if !(flat2 && flat && mask) - flat2_q0 = _mm_and_si128(flat2, flat2_q0); - // get values for when (flat2 && flat && mask) - q0 = _mm_or_si128(q0, flat2_q0); // full list of q0 values - _mm_store_si128((__m128i *)(s - 1 * pitch), p0); - _mm_store_si128((__m128i *)(s - 0 * pitch), q0); -} - -void vpx_highbd_lpf_horizontal_16_dual_sse2(uint16_t *s, int pitch, - const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh, int bd) { - vpx_highbd_lpf_horizontal_16_sse2(s, pitch, blimit, limit, thresh, bd); - vpx_highbd_lpf_horizontal_16_sse2(s + 8, pitch, blimit, limit, thresh, bd); -} - -void vpx_highbd_lpf_horizontal_8_sse2(uint16_t *s, int pitch, - const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh, int bd) { - DECLARE_ALIGNED(16, uint16_t, flat_op2[16]); - DECLARE_ALIGNED(16, uint16_t, flat_op1[16]); - DECLARE_ALIGNED(16, uint16_t, flat_op0[16]); - DECLARE_ALIGNED(16, uint16_t, flat_oq2[16]); - DECLARE_ALIGNED(16, uint16_t, flat_oq1[16]); - DECLARE_ALIGNED(16, uint16_t, flat_oq0[16]); - const __m128i zero = _mm_setzero_si128(); - __m128i blimit_v, limit_v, thresh_v; - __m128i mask, hev, flat; - __m128i p3 = _mm_load_si128((__m128i *)(s - 4 * pitch)); - __m128i q3 = _mm_load_si128((__m128i *)(s + 3 * pitch)); - __m128i p2 = _mm_load_si128((__m128i *)(s - 3 * pitch)); - __m128i q2 = _mm_load_si128((__m128i *)(s + 2 * pitch)); - __m128i p1 = _mm_load_si128((__m128i *)(s - 2 * pitch)); - __m128i q1 = _mm_load_si128((__m128i *)(s + 1 * pitch)); - __m128i p0 = _mm_load_si128((__m128i *)(s - 1 * pitch)); - __m128i q0 = _mm_load_si128((__m128i *)(s + 0 * pitch)); - const __m128i one = _mm_set1_epi16(1); - const __m128i ffff = _mm_cmpeq_epi16(one, one); - __m128i abs_p1q1, abs_p0q0, abs_q1q0, abs_p1p0, work; - const __m128i four = _mm_set1_epi16(4); - __m128i workp_a, workp_b, workp_shft; - - const __m128i t4 = _mm_set1_epi16(4); - const __m128i t3 = _mm_set1_epi16(3); - __m128i t80; - const __m128i t1 = _mm_set1_epi16(0x1); - __m128i ps1, ps0, qs0, qs1; - __m128i filt; - __m128i work_a; - __m128i filter1, filter2; - - if (bd == 8) { - blimit_v = _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)blimit), zero); - limit_v = _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)limit), zero); - thresh_v = _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)thresh), zero); - t80 = _mm_set1_epi16(0x80); - } else if (bd == 10) { - blimit_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)blimit), zero), 2); - limit_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)limit), zero), 2); - thresh_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)thresh), zero), 2); - t80 = _mm_set1_epi16(0x200); - } else { // bd == 12 - blimit_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)blimit), zero), 4); - limit_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)limit), zero), 4); - thresh_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)thresh), zero), 4); - t80 = _mm_set1_epi16(0x800); - } - - ps1 = _mm_subs_epi16(p1, t80); - ps0 = _mm_subs_epi16(p0, t80); - qs0 = _mm_subs_epi16(q0, t80); - qs1 = _mm_subs_epi16(q1, t80); - - // filter_mask and hev_mask - abs_p1p0 = _mm_or_si128(_mm_subs_epu16(p1, p0), _mm_subs_epu16(p0, p1)); - abs_q1q0 = _mm_or_si128(_mm_subs_epu16(q1, q0), _mm_subs_epu16(q0, q1)); - - abs_p0q0 = _mm_or_si128(_mm_subs_epu16(p0, q0), _mm_subs_epu16(q0, p0)); - abs_p1q1 = _mm_or_si128(_mm_subs_epu16(p1, q1), _mm_subs_epu16(q1, p1)); - flat = _mm_max_epi16(abs_p1p0, abs_q1q0); - hev = _mm_subs_epu16(flat, thresh_v); - hev = _mm_xor_si128(_mm_cmpeq_epi16(hev, zero), ffff); - - abs_p0q0 = _mm_adds_epu16(abs_p0q0, abs_p0q0); - abs_p1q1 = _mm_srli_epi16(abs_p1q1, 1); - mask = _mm_subs_epu16(_mm_adds_epu16(abs_p0q0, abs_p1q1), blimit_v); - mask = _mm_xor_si128(_mm_cmpeq_epi16(mask, zero), ffff); - // mask |= (abs(p0 - q0) * 2 + abs(p1 - q1) / 2 > blimit) * -1; - // So taking maximums continues to work: - mask = _mm_and_si128(mask, _mm_adds_epu16(limit_v, one)); - mask = _mm_max_epi16(abs_p1p0, mask); - // mask |= (abs(p1 - p0) > limit) * -1; - mask = _mm_max_epi16(abs_q1q0, mask); - // mask |= (abs(q1 - q0) > limit) * -1; - - work = _mm_max_epi16( - _mm_or_si128(_mm_subs_epu16(p2, p1), _mm_subs_epu16(p1, p2)), - _mm_or_si128(_mm_subs_epu16(q2, q1), _mm_subs_epu16(q1, q2))); - mask = _mm_max_epi16(work, mask); - work = _mm_max_epi16( - _mm_or_si128(_mm_subs_epu16(p3, p2), _mm_subs_epu16(p2, p3)), - _mm_or_si128(_mm_subs_epu16(q3, q2), _mm_subs_epu16(q2, q3))); - mask = _mm_max_epi16(work, mask); - mask = _mm_subs_epu16(mask, limit_v); - mask = _mm_cmpeq_epi16(mask, zero); - - // flat_mask4 - flat = _mm_max_epi16( - _mm_or_si128(_mm_subs_epu16(p2, p0), _mm_subs_epu16(p0, p2)), - _mm_or_si128(_mm_subs_epu16(q2, q0), _mm_subs_epu16(q0, q2))); - work = _mm_max_epi16( - _mm_or_si128(_mm_subs_epu16(p3, p0), _mm_subs_epu16(p0, p3)), - _mm_or_si128(_mm_subs_epu16(q3, q0), _mm_subs_epu16(q0, q3))); - flat = _mm_max_epi16(work, flat); - flat = _mm_max_epi16(abs_p1p0, flat); - flat = _mm_max_epi16(abs_q1q0, flat); - - if (bd == 8) - flat = _mm_subs_epu16(flat, one); - else if (bd == 10) - flat = _mm_subs_epu16(flat, _mm_slli_epi16(one, 2)); - else // bd == 12 - flat = _mm_subs_epu16(flat, _mm_slli_epi16(one, 4)); - - flat = _mm_cmpeq_epi16(flat, zero); - flat = _mm_and_si128(flat, mask); // flat & mask - - // Added before shift for rounding part of ROUND_POWER_OF_TWO - - workp_a = _mm_add_epi16(_mm_add_epi16(p3, p3), _mm_add_epi16(p2, p1)); - workp_a = _mm_add_epi16(_mm_add_epi16(workp_a, four), p0); - workp_b = _mm_add_epi16(_mm_add_epi16(q0, p2), p3); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_store_si128((__m128i *)&flat_op2[0], workp_shft); - - workp_b = _mm_add_epi16(_mm_add_epi16(q0, q1), p1); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_store_si128((__m128i *)&flat_op1[0], workp_shft); - - workp_a = _mm_add_epi16(_mm_sub_epi16(workp_a, p3), q2); - workp_b = _mm_add_epi16(_mm_sub_epi16(workp_b, p1), p0); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_store_si128((__m128i *)&flat_op0[0], workp_shft); - - workp_a = _mm_add_epi16(_mm_sub_epi16(workp_a, p3), q3); - workp_b = _mm_add_epi16(_mm_sub_epi16(workp_b, p0), q0); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_store_si128((__m128i *)&flat_oq0[0], workp_shft); - - workp_a = _mm_add_epi16(_mm_sub_epi16(workp_a, p2), q3); - workp_b = _mm_add_epi16(_mm_sub_epi16(workp_b, q0), q1); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_store_si128((__m128i *)&flat_oq1[0], workp_shft); - - workp_a = _mm_add_epi16(_mm_sub_epi16(workp_a, p1), q3); - workp_b = _mm_add_epi16(_mm_sub_epi16(workp_b, q1), q2); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_store_si128((__m128i *)&flat_oq2[0], workp_shft); - - // lp filter - filt = signed_char_clamp_bd_sse2(_mm_subs_epi16(ps1, qs1), bd); - filt = _mm_and_si128(filt, hev); - work_a = _mm_subs_epi16(qs0, ps0); - filt = _mm_adds_epi16(filt, work_a); - filt = _mm_adds_epi16(filt, work_a); - filt = _mm_adds_epi16(filt, work_a); - // (vpx_filter + 3 * (qs0 - ps0)) & mask - filt = signed_char_clamp_bd_sse2(filt, bd); - filt = _mm_and_si128(filt, mask); - - filter1 = _mm_adds_epi16(filt, t4); - filter2 = _mm_adds_epi16(filt, t3); - - // Filter1 >> 3 - filter1 = signed_char_clamp_bd_sse2(filter1, bd); - filter1 = _mm_srai_epi16(filter1, 3); - - // Filter2 >> 3 - filter2 = signed_char_clamp_bd_sse2(filter2, bd); - filter2 = _mm_srai_epi16(filter2, 3); - - // filt >> 1 - filt = _mm_adds_epi16(filter1, t1); - filt = _mm_srai_epi16(filt, 1); - // filter = ROUND_POWER_OF_TWO(filter1, 1) & ~hev; - filt = _mm_andnot_si128(hev, filt); - - work_a = signed_char_clamp_bd_sse2(_mm_subs_epi16(qs0, filter1), bd); - work_a = _mm_adds_epi16(work_a, t80); - q0 = _mm_load_si128((__m128i *)flat_oq0); - work_a = _mm_andnot_si128(flat, work_a); - q0 = _mm_and_si128(flat, q0); - q0 = _mm_or_si128(work_a, q0); - - work_a = signed_char_clamp_bd_sse2(_mm_subs_epi16(qs1, filt), bd); - work_a = _mm_adds_epi16(work_a, t80); - q1 = _mm_load_si128((__m128i *)flat_oq1); - work_a = _mm_andnot_si128(flat, work_a); - q1 = _mm_and_si128(flat, q1); - q1 = _mm_or_si128(work_a, q1); - - work_a = _mm_loadu_si128((__m128i *)(s + 2 * pitch)); - q2 = _mm_load_si128((__m128i *)flat_oq2); - work_a = _mm_andnot_si128(flat, work_a); - q2 = _mm_and_si128(flat, q2); - q2 = _mm_or_si128(work_a, q2); - - work_a = signed_char_clamp_bd_sse2(_mm_adds_epi16(ps0, filter2), bd); - work_a = _mm_adds_epi16(work_a, t80); - p0 = _mm_load_si128((__m128i *)flat_op0); - work_a = _mm_andnot_si128(flat, work_a); - p0 = _mm_and_si128(flat, p0); - p0 = _mm_or_si128(work_a, p0); - - work_a = signed_char_clamp_bd_sse2(_mm_adds_epi16(ps1, filt), bd); - work_a = _mm_adds_epi16(work_a, t80); - p1 = _mm_load_si128((__m128i *)flat_op1); - work_a = _mm_andnot_si128(flat, work_a); - p1 = _mm_and_si128(flat, p1); - p1 = _mm_or_si128(work_a, p1); - - work_a = _mm_loadu_si128((__m128i *)(s - 3 * pitch)); - p2 = _mm_load_si128((__m128i *)flat_op2); - work_a = _mm_andnot_si128(flat, work_a); - p2 = _mm_and_si128(flat, p2); - p2 = _mm_or_si128(work_a, p2); - - _mm_store_si128((__m128i *)(s - 3 * pitch), p2); - _mm_store_si128((__m128i *)(s - 2 * pitch), p1); - _mm_store_si128((__m128i *)(s - 1 * pitch), p0); - _mm_store_si128((__m128i *)(s + 0 * pitch), q0); - _mm_store_si128((__m128i *)(s + 1 * pitch), q1); - _mm_store_si128((__m128i *)(s + 2 * pitch), q2); -} - -void vpx_highbd_lpf_horizontal_8_dual_sse2( - uint16_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, - const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1, int bd) { - vpx_highbd_lpf_horizontal_8_sse2(s, pitch, blimit0, limit0, thresh0, bd); - vpx_highbd_lpf_horizontal_8_sse2(s + 8, pitch, blimit1, limit1, thresh1, bd); -} - -void vpx_highbd_lpf_horizontal_4_sse2(uint16_t *s, int pitch, - const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh, int bd) { - const __m128i zero = _mm_setzero_si128(); - __m128i blimit_v, limit_v, thresh_v; - __m128i mask, hev, flat; - __m128i p3 = _mm_loadu_si128((__m128i *)(s - 4 * pitch)); - __m128i p2 = _mm_loadu_si128((__m128i *)(s - 3 * pitch)); - __m128i p1 = _mm_loadu_si128((__m128i *)(s - 2 * pitch)); - __m128i p0 = _mm_loadu_si128((__m128i *)(s - 1 * pitch)); - __m128i q0 = _mm_loadu_si128((__m128i *)(s - 0 * pitch)); - __m128i q1 = _mm_loadu_si128((__m128i *)(s + 1 * pitch)); - __m128i q2 = _mm_loadu_si128((__m128i *)(s + 2 * pitch)); - __m128i q3 = _mm_loadu_si128((__m128i *)(s + 3 * pitch)); - const __m128i abs_p1p0 = - _mm_or_si128(_mm_subs_epu16(p1, p0), _mm_subs_epu16(p0, p1)); - const __m128i abs_q1q0 = - _mm_or_si128(_mm_subs_epu16(q1, q0), _mm_subs_epu16(q0, q1)); - const __m128i ffff = _mm_cmpeq_epi16(abs_p1p0, abs_p1p0); - const __m128i one = _mm_set1_epi16(1); - __m128i abs_p0q0 = - _mm_or_si128(_mm_subs_epu16(p0, q0), _mm_subs_epu16(q0, p0)); - __m128i abs_p1q1 = - _mm_or_si128(_mm_subs_epu16(p1, q1), _mm_subs_epu16(q1, p1)); - __m128i work; - const __m128i t4 = _mm_set1_epi16(4); - const __m128i t3 = _mm_set1_epi16(3); - __m128i t80; - __m128i tff80; - __m128i tffe0; - __m128i t1f; - // equivalent to shifting 0x1f left by bitdepth - 8 - // and setting new bits to 1 - const __m128i t1 = _mm_set1_epi16(0x1); - __m128i t7f; - // equivalent to shifting 0x7f left by bitdepth - 8 - // and setting new bits to 1 - __m128i ps1, ps0, qs0, qs1; - __m128i filt; - __m128i work_a; - __m128i filter1, filter2; - - if (bd == 8) { - blimit_v = _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)blimit), zero); - limit_v = _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)limit), zero); - thresh_v = _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)thresh), zero); - t80 = _mm_set1_epi16(0x80); - tff80 = _mm_set1_epi16((int16_t)0xff80); - tffe0 = _mm_set1_epi16((int16_t)0xffe0); - t1f = _mm_srli_epi16(_mm_set1_epi16(0x1fff), 8); - t7f = _mm_srli_epi16(_mm_set1_epi16(0x7fff), 8); - } else if (bd == 10) { - blimit_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)blimit), zero), 2); - limit_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)limit), zero), 2); - thresh_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)thresh), zero), 2); - t80 = _mm_slli_epi16(_mm_set1_epi16(0x80), 2); - tff80 = _mm_slli_epi16(_mm_set1_epi16((int16_t)0xff80), 2); - tffe0 = _mm_slli_epi16(_mm_set1_epi16((int16_t)0xffe0), 2); - t1f = _mm_srli_epi16(_mm_set1_epi16(0x1fff), 6); - t7f = _mm_srli_epi16(_mm_set1_epi16(0x7fff), 6); - } else { // bd == 12 - blimit_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)blimit), zero), 4); - limit_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)limit), zero), 4); - thresh_v = _mm_slli_epi16( - _mm_unpacklo_epi8(_mm_load_si128((const __m128i *)thresh), zero), 4); - t80 = _mm_slli_epi16(_mm_set1_epi16(0x80), 4); - tff80 = _mm_slli_epi16(_mm_set1_epi16((int16_t)0xff80), 4); - tffe0 = _mm_slli_epi16(_mm_set1_epi16((int16_t)0xffe0), 4); - t1f = _mm_srli_epi16(_mm_set1_epi16(0x1fff), 4); - t7f = _mm_srli_epi16(_mm_set1_epi16(0x7fff), 4); - } - - ps1 = _mm_subs_epi16(_mm_loadu_si128((__m128i *)(s - 2 * pitch)), t80); - ps0 = _mm_subs_epi16(_mm_loadu_si128((__m128i *)(s - 1 * pitch)), t80); - qs0 = _mm_subs_epi16(_mm_loadu_si128((__m128i *)(s + 0 * pitch)), t80); - qs1 = _mm_subs_epi16(_mm_loadu_si128((__m128i *)(s + 1 * pitch)), t80); - - // filter_mask and hev_mask - flat = _mm_max_epi16(abs_p1p0, abs_q1q0); - hev = _mm_subs_epu16(flat, thresh_v); - hev = _mm_xor_si128(_mm_cmpeq_epi16(hev, zero), ffff); - - abs_p0q0 = _mm_adds_epu16(abs_p0q0, abs_p0q0); - abs_p1q1 = _mm_srli_epi16(abs_p1q1, 1); - mask = _mm_subs_epu16(_mm_adds_epu16(abs_p0q0, abs_p1q1), blimit_v); - mask = _mm_xor_si128(_mm_cmpeq_epi16(mask, zero), ffff); - // mask |= (abs(p0 - q0) * 2 + abs(p1 - q1) / 2 > blimit) * -1; - // So taking maximums continues to work: - mask = _mm_and_si128(mask, _mm_adds_epu16(limit_v, one)); - mask = _mm_max_epi16(flat, mask); - // mask |= (abs(p1 - p0) > limit) * -1; - // mask |= (abs(q1 - q0) > limit) * -1; - work = _mm_max_epi16( - _mm_or_si128(_mm_subs_epu16(p2, p1), _mm_subs_epu16(p1, p2)), - _mm_or_si128(_mm_subs_epu16(p3, p2), _mm_subs_epu16(p2, p3))); - mask = _mm_max_epi16(work, mask); - work = _mm_max_epi16( - _mm_or_si128(_mm_subs_epu16(q2, q1), _mm_subs_epu16(q1, q2)), - _mm_or_si128(_mm_subs_epu16(q3, q2), _mm_subs_epu16(q2, q3))); - mask = _mm_max_epi16(work, mask); - mask = _mm_subs_epu16(mask, limit_v); - mask = _mm_cmpeq_epi16(mask, zero); - - // filter4 - filt = signed_char_clamp_bd_sse2(_mm_subs_epi16(ps1, qs1), bd); - filt = _mm_and_si128(filt, hev); - work_a = _mm_subs_epi16(qs0, ps0); - filt = _mm_adds_epi16(filt, work_a); - filt = _mm_adds_epi16(filt, work_a); - filt = signed_char_clamp_bd_sse2(_mm_adds_epi16(filt, work_a), bd); - - // (vpx_filter + 3 * (qs0 - ps0)) & mask - filt = _mm_and_si128(filt, mask); - - filter1 = signed_char_clamp_bd_sse2(_mm_adds_epi16(filt, t4), bd); - filter2 = signed_char_clamp_bd_sse2(_mm_adds_epi16(filt, t3), bd); - - // Filter1 >> 3 - work_a = _mm_cmpgt_epi16(zero, filter1); // get the values that are <0 - filter1 = _mm_srli_epi16(filter1, 3); - work_a = _mm_and_si128(work_a, tffe0); // sign bits for the values < 0 - filter1 = _mm_and_si128(filter1, t1f); // clamp the range - filter1 = _mm_or_si128(filter1, work_a); // reinsert the sign bits - - // Filter2 >> 3 - work_a = _mm_cmpgt_epi16(zero, filter2); - filter2 = _mm_srli_epi16(filter2, 3); - work_a = _mm_and_si128(work_a, tffe0); - filter2 = _mm_and_si128(filter2, t1f); - filter2 = _mm_or_si128(filter2, work_a); - - // filt >> 1 - filt = _mm_adds_epi16(filter1, t1); - work_a = _mm_cmpgt_epi16(zero, filt); - filt = _mm_srli_epi16(filt, 1); - work_a = _mm_and_si128(work_a, tff80); - filt = _mm_and_si128(filt, t7f); - filt = _mm_or_si128(filt, work_a); - - filt = _mm_andnot_si128(hev, filt); - - q0 = _mm_adds_epi16( - signed_char_clamp_bd_sse2(_mm_subs_epi16(qs0, filter1), bd), t80); - q1 = _mm_adds_epi16(signed_char_clamp_bd_sse2(_mm_subs_epi16(qs1, filt), bd), - t80); - p0 = _mm_adds_epi16( - signed_char_clamp_bd_sse2(_mm_adds_epi16(ps0, filter2), bd), t80); - p1 = _mm_adds_epi16(signed_char_clamp_bd_sse2(_mm_adds_epi16(ps1, filt), bd), - t80); - - _mm_storeu_si128((__m128i *)(s - 2 * pitch), p1); - _mm_storeu_si128((__m128i *)(s - 1 * pitch), p0); - _mm_storeu_si128((__m128i *)(s + 0 * pitch), q0); - _mm_storeu_si128((__m128i *)(s + 1 * pitch), q1); -} - -void vpx_highbd_lpf_horizontal_4_dual_sse2( - uint16_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, - const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1, int bd) { - vpx_highbd_lpf_horizontal_4_sse2(s, pitch, blimit0, limit0, thresh0, bd); - vpx_highbd_lpf_horizontal_4_sse2(s + 8, pitch, blimit1, limit1, thresh1, bd); -} - -static INLINE void highbd_transpose(uint16_t *src[], int in_p, uint16_t *dst[], - int out_p, int num_8x8_to_transpose) { - int idx8x8 = 0; - __m128i p0, p1, p2, p3, p4, p5, p6, p7, x0, x1, x2, x3, x4, x5, x6, x7; - do { - uint16_t *in = src[idx8x8]; - uint16_t *out = dst[idx8x8]; - - p0 = - _mm_loadu_si128((__m128i *)(in + 0 * in_p)); // 00 01 02 03 04 05 06 07 - p1 = - _mm_loadu_si128((__m128i *)(in + 1 * in_p)); // 10 11 12 13 14 15 16 17 - p2 = - _mm_loadu_si128((__m128i *)(in + 2 * in_p)); // 20 21 22 23 24 25 26 27 - p3 = - _mm_loadu_si128((__m128i *)(in + 3 * in_p)); // 30 31 32 33 34 35 36 37 - p4 = - _mm_loadu_si128((__m128i *)(in + 4 * in_p)); // 40 41 42 43 44 45 46 47 - p5 = - _mm_loadu_si128((__m128i *)(in + 5 * in_p)); // 50 51 52 53 54 55 56 57 - p6 = - _mm_loadu_si128((__m128i *)(in + 6 * in_p)); // 60 61 62 63 64 65 66 67 - p7 = - _mm_loadu_si128((__m128i *)(in + 7 * in_p)); // 70 71 72 73 74 75 76 77 - // 00 10 01 11 02 12 03 13 - x0 = _mm_unpacklo_epi16(p0, p1); - // 20 30 21 31 22 32 23 33 - x1 = _mm_unpacklo_epi16(p2, p3); - // 40 50 41 51 42 52 43 53 - x2 = _mm_unpacklo_epi16(p4, p5); - // 60 70 61 71 62 72 63 73 - x3 = _mm_unpacklo_epi16(p6, p7); - // 00 10 20 30 01 11 21 31 - x4 = _mm_unpacklo_epi32(x0, x1); - // 40 50 60 70 41 51 61 71 - x5 = _mm_unpacklo_epi32(x2, x3); - // 00 10 20 30 40 50 60 70 - x6 = _mm_unpacklo_epi64(x4, x5); - // 01 11 21 31 41 51 61 71 - x7 = _mm_unpackhi_epi64(x4, x5); - - _mm_storeu_si128((__m128i *)(out + 0 * out_p), x6); - // 00 10 20 30 40 50 60 70 - _mm_storeu_si128((__m128i *)(out + 1 * out_p), x7); - // 01 11 21 31 41 51 61 71 - - // 02 12 22 32 03 13 23 33 - x4 = _mm_unpackhi_epi32(x0, x1); - // 42 52 62 72 43 53 63 73 - x5 = _mm_unpackhi_epi32(x2, x3); - // 02 12 22 32 42 52 62 72 - x6 = _mm_unpacklo_epi64(x4, x5); - // 03 13 23 33 43 53 63 73 - x7 = _mm_unpackhi_epi64(x4, x5); - - _mm_storeu_si128((__m128i *)(out + 2 * out_p), x6); - // 02 12 22 32 42 52 62 72 - _mm_storeu_si128((__m128i *)(out + 3 * out_p), x7); - // 03 13 23 33 43 53 63 73 - - // 04 14 05 15 06 16 07 17 - x0 = _mm_unpackhi_epi16(p0, p1); - // 24 34 25 35 26 36 27 37 - x1 = _mm_unpackhi_epi16(p2, p3); - // 44 54 45 55 46 56 47 57 - x2 = _mm_unpackhi_epi16(p4, p5); - // 64 74 65 75 66 76 67 77 - x3 = _mm_unpackhi_epi16(p6, p7); - // 04 14 24 34 05 15 25 35 - x4 = _mm_unpacklo_epi32(x0, x1); - // 44 54 64 74 45 55 65 75 - x5 = _mm_unpacklo_epi32(x2, x3); - // 04 14 24 34 44 54 64 74 - x6 = _mm_unpacklo_epi64(x4, x5); - // 05 15 25 35 45 55 65 75 - x7 = _mm_unpackhi_epi64(x4, x5); - - _mm_storeu_si128((__m128i *)(out + 4 * out_p), x6); - // 04 14 24 34 44 54 64 74 - _mm_storeu_si128((__m128i *)(out + 5 * out_p), x7); - // 05 15 25 35 45 55 65 75 - - // 06 16 26 36 07 17 27 37 - x4 = _mm_unpackhi_epi32(x0, x1); - // 46 56 66 76 47 57 67 77 - x5 = _mm_unpackhi_epi32(x2, x3); - // 06 16 26 36 46 56 66 76 - x6 = _mm_unpacklo_epi64(x4, x5); - // 07 17 27 37 47 57 67 77 - x7 = _mm_unpackhi_epi64(x4, x5); - - _mm_storeu_si128((__m128i *)(out + 6 * out_p), x6); - // 06 16 26 36 46 56 66 76 - _mm_storeu_si128((__m128i *)(out + 7 * out_p), x7); - // 07 17 27 37 47 57 67 77 - } while (++idx8x8 < num_8x8_to_transpose); -} - -static INLINE void highbd_transpose8x16(uint16_t *in0, uint16_t *in1, int in_p, - uint16_t *out, int out_p) { - uint16_t *src0[1]; - uint16_t *src1[1]; - uint16_t *dest0[1]; - uint16_t *dest1[1]; - src0[0] = in0; - src1[0] = in1; - dest0[0] = out; - dest1[0] = out + 8; - highbd_transpose(src0, in_p, dest0, out_p, 1); - highbd_transpose(src1, in_p, dest1, out_p, 1); -} - -void vpx_highbd_lpf_vertical_4_sse2(uint16_t *s, int pitch, - const uint8_t *blimit, const uint8_t *limit, - const uint8_t *thresh, int bd) { - DECLARE_ALIGNED(16, uint16_t, t_dst[8 * 8]); - uint16_t *src[1]; - uint16_t *dst[1]; - - // Transpose 8x8 - src[0] = s - 4; - dst[0] = t_dst; - - highbd_transpose(src, pitch, dst, 8, 1); - - // Loop filtering - vpx_highbd_lpf_horizontal_4_sse2(t_dst + 4 * 8, 8, blimit, limit, thresh, bd); - - src[0] = t_dst; - dst[0] = s - 4; - - // Transpose back - highbd_transpose(src, 8, dst, pitch, 1); -} - -void vpx_highbd_lpf_vertical_4_dual_sse2( - uint16_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, - const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1, int bd) { - DECLARE_ALIGNED(16, uint16_t, t_dst[16 * 8]); - uint16_t *src[2]; - uint16_t *dst[2]; - - // Transpose 8x16 - highbd_transpose8x16(s - 4, s - 4 + pitch * 8, pitch, t_dst, 16); - - // Loop filtering - vpx_highbd_lpf_horizontal_4_dual_sse2(t_dst + 4 * 16, 16, blimit0, limit0, - thresh0, blimit1, limit1, thresh1, bd); - src[0] = t_dst; - src[1] = t_dst + 8; - dst[0] = s - 4; - dst[1] = s - 4 + pitch * 8; - - // Transpose back - highbd_transpose(src, 16, dst, pitch, 2); -} - -void vpx_highbd_lpf_vertical_8_sse2(uint16_t *s, int pitch, - const uint8_t *blimit, const uint8_t *limit, - const uint8_t *thresh, int bd) { - DECLARE_ALIGNED(16, uint16_t, t_dst[8 * 8]); - uint16_t *src[1]; - uint16_t *dst[1]; - - // Transpose 8x8 - src[0] = s - 4; - dst[0] = t_dst; - - highbd_transpose(src, pitch, dst, 8, 1); - - // Loop filtering - vpx_highbd_lpf_horizontal_8_sse2(t_dst + 4 * 8, 8, blimit, limit, thresh, bd); - - src[0] = t_dst; - dst[0] = s - 4; - - // Transpose back - highbd_transpose(src, 8, dst, pitch, 1); -} - -void vpx_highbd_lpf_vertical_8_dual_sse2( - uint16_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, - const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1, int bd) { - DECLARE_ALIGNED(16, uint16_t, t_dst[16 * 8]); - uint16_t *src[2]; - uint16_t *dst[2]; - - // Transpose 8x16 - highbd_transpose8x16(s - 4, s - 4 + pitch * 8, pitch, t_dst, 16); - - // Loop filtering - vpx_highbd_lpf_horizontal_8_dual_sse2(t_dst + 4 * 16, 16, blimit0, limit0, - thresh0, blimit1, limit1, thresh1, bd); - src[0] = t_dst; - src[1] = t_dst + 8; - - dst[0] = s - 4; - dst[1] = s - 4 + pitch * 8; - - // Transpose back - highbd_transpose(src, 16, dst, pitch, 2); -} - -void vpx_highbd_lpf_vertical_16_sse2(uint16_t *s, int pitch, - const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh, int bd) { - DECLARE_ALIGNED(16, uint16_t, t_dst[8 * 16]); - uint16_t *src[2]; - uint16_t *dst[2]; - - src[0] = s - 8; - src[1] = s; - dst[0] = t_dst; - dst[1] = t_dst + 8 * 8; - - // Transpose 16x8 - highbd_transpose(src, pitch, dst, 8, 2); - - // Loop filtering - vpx_highbd_lpf_horizontal_16_sse2(t_dst + 8 * 8, 8, blimit, limit, thresh, - bd); - src[0] = t_dst; - src[1] = t_dst + 8 * 8; - dst[0] = s - 8; - dst[1] = s; - - // Transpose back - highbd_transpose(src, 8, dst, pitch, 2); -} - -void vpx_highbd_lpf_vertical_16_dual_sse2(uint16_t *s, int pitch, - const uint8_t *blimit, - const uint8_t *limit, - const uint8_t *thresh, int bd) { - DECLARE_ALIGNED(16, uint16_t, t_dst[256]); - - // Transpose 16x16 - highbd_transpose8x16(s - 8, s - 8 + 8 * pitch, pitch, t_dst, 16); - highbd_transpose8x16(s, s + 8 * pitch, pitch, t_dst + 8 * 16, 16); - - // Loop filtering - vpx_highbd_lpf_horizontal_16_dual_sse2(t_dst + 8 * 16, 16, blimit, limit, - thresh, bd); - - // Transpose back - highbd_transpose8x16(t_dst, t_dst + 8 * 16, 16, s - 8, pitch); - highbd_transpose8x16(t_dst + 8, t_dst + 8 + 8 * 16, 16, s - 8 + 8 * pitch, - pitch); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_quantize_intrin_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_quantize_intrin_avx2.c deleted file mode 100644 index 35ca5540..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_quantize_intrin_avx2.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vp9/common/vp9_scan.h" -#include "vp9/encoder/vp9_block.h" - -static VPX_FORCE_INLINE void init_one_qp(const __m128i *p, __m256i *qp) { - const __m128i sign = _mm_srai_epi16(*p, 15); - const __m128i dc = _mm_unpacklo_epi16(*p, sign); - const __m128i ac = _mm_unpackhi_epi16(*p, sign); - *qp = _mm256_insertf128_si256(_mm256_castsi128_si256(dc), ac, 1); -} - -static VPX_FORCE_INLINE void update_qp(__m256i *qp) { - int i; - for (i = 0; i < 5; ++i) { - qp[i] = _mm256_permute2x128_si256(qp[i], qp[i], 0x11); - } -} - -static VPX_FORCE_INLINE void init_qp( - const struct macroblock_plane *const mb_plane, const int16_t *dequant_ptr, - __m256i *qp, int log_scale) { - const __m128i zbin = _mm_loadu_si128((const __m128i *)mb_plane->zbin); - const __m128i round = _mm_loadu_si128((const __m128i *)mb_plane->round); - const __m128i quant = _mm_loadu_si128((const __m128i *)mb_plane->quant); - const __m128i dequant = _mm_loadu_si128((const __m128i *)dequant_ptr); - const __m128i quant_shift = - _mm_loadu_si128((const __m128i *)mb_plane->quant_shift); - init_one_qp(&zbin, &qp[0]); - init_one_qp(&round, &qp[1]); - init_one_qp(&quant, &qp[2]); - init_one_qp(&dequant, &qp[3]); - init_one_qp(&quant_shift, &qp[4]); - if (log_scale > 0) { - const __m256i rnd = _mm256_set1_epi32((int16_t)(1 << (log_scale - 1))); - qp[0] = _mm256_add_epi32(qp[0], rnd); - qp[0] = _mm256_srai_epi32(qp[0], log_scale); - - qp[1] = _mm256_add_epi32(qp[1], rnd); - qp[1] = _mm256_srai_epi32(qp[1], log_scale); - } - // Subtracting 1 here eliminates a _mm256_cmpeq_epi32() instruction when - // calculating the zbin mask. - qp[0] = _mm256_sub_epi32(qp[0], _mm256_set1_epi32(1)); -} - -// Note: -// *x is vector multiplied by *y which is 16 int32_t parallel multiplication -// and right shift 16. The output, 16 int32_t is save in *p. -static VPX_FORCE_INLINE __m256i mm256_mul_shift_epi32(const __m256i *x, - const __m256i *y) { - __m256i prod_lo = _mm256_mul_epi32(*x, *y); - __m256i prod_hi = _mm256_srli_epi64(*x, 32); - const __m256i mult_hi = _mm256_srli_epi64(*y, 32); - const __m256i mask = _mm256_set_epi32(0, -1, 0, -1, 0, -1, 0, -1); - prod_hi = _mm256_mul_epi32(prod_hi, mult_hi); - prod_lo = _mm256_srli_epi64(prod_lo, 16); - prod_lo = _mm256_and_si256(prod_lo, mask); - prod_hi = _mm256_srli_epi64(prod_hi, 16); - prod_hi = _mm256_slli_epi64(prod_hi, 32); - return _mm256_or_si256(prod_lo, prod_hi); -} - -static VPX_FORCE_INLINE __m256i get_max_lane_eob(const int16_t *iscan_ptr, - __m256i eobmax, - __m256i nz_mask) { - const __m256i packed_nz_mask = _mm256_packs_epi32(nz_mask, nz_mask); - const __m256i packed_nz_mask_perm = - _mm256_permute4x64_epi64(packed_nz_mask, 0xD8); - const __m256i iscan = - _mm256_castsi128_si256(_mm_loadu_si128((const __m128i *)iscan_ptr)); - const __m256i nz_iscan = _mm256_and_si256(iscan, packed_nz_mask_perm); - return _mm256_max_epi16(eobmax, nz_iscan); -} - -// Get the max eob from the lower 128 bits. -static VPX_FORCE_INLINE uint16_t get_max_eob(__m256i eob) { - __m256i eob_s; - eob_s = _mm256_shuffle_epi32(eob, 0xe); - eob = _mm256_max_epi16(eob, eob_s); - eob_s = _mm256_shufflelo_epi16(eob, 0xe); - eob = _mm256_max_epi16(eob, eob_s); - eob_s = _mm256_shufflelo_epi16(eob, 1); - eob = _mm256_max_epi16(eob, eob_s); -#if defined(_MSC_VER) && (_MSC_VER < 1910) - return _mm_cvtsi128_si32(_mm256_extracti128_si256(eob, 0)) & 0xffff; -#else - return (uint16_t)_mm256_extract_epi16(eob, 0); -#endif -} - -static VPX_FORCE_INLINE void quantize(const __m256i *qp, - const tran_low_t *coeff_ptr, - const int16_t *iscan_ptr, - tran_low_t *qcoeff, tran_low_t *dqcoeff, - __m256i *eob) { - const __m256i coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr); - const __m256i abs_coeff = _mm256_abs_epi32(coeff); - const __m256i zbin_mask = _mm256_cmpgt_epi32(abs_coeff, qp[0]); - - if (_mm256_movemask_epi8(zbin_mask) == 0) { - const __m256i zero = _mm256_setzero_si256(); - _mm256_storeu_si256((__m256i *)qcoeff, zero); - _mm256_storeu_si256((__m256i *)dqcoeff, zero); - return; - } - { - const __m256i tmp_rnd = - _mm256_and_si256(_mm256_add_epi32(abs_coeff, qp[1]), zbin_mask); - const __m256i tmp = mm256_mul_shift_epi32(&tmp_rnd, &qp[2]); - const __m256i tmp2 = _mm256_add_epi32(tmp, tmp_rnd); - const __m256i abs_q = mm256_mul_shift_epi32(&tmp2, &qp[4]); - const __m256i abs_dq = _mm256_mullo_epi32(abs_q, qp[3]); - const __m256i nz_mask = _mm256_cmpgt_epi32(abs_q, _mm256_setzero_si256()); - const __m256i q = _mm256_sign_epi32(abs_q, coeff); - const __m256i dq = _mm256_sign_epi32(abs_dq, coeff); - - _mm256_storeu_si256((__m256i *)qcoeff, q); - _mm256_storeu_si256((__m256i *)dqcoeff, dq); - - *eob = get_max_lane_eob(iscan_ptr, *eob, nz_mask); - } -} - -void vpx_highbd_quantize_b_avx2(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - const int step = 8; - __m256i eob = _mm256_setzero_si256(); - __m256i qp[5]; - const int16_t *iscan = scan_order->iscan; - - init_qp(mb_plane, dequant_ptr, qp, 0); - - quantize(qp, coeff_ptr, iscan, qcoeff_ptr, dqcoeff_ptr, &eob); - - coeff_ptr += step; - qcoeff_ptr += step; - dqcoeff_ptr += step; - iscan += step; - n_coeffs -= step; - - update_qp(qp); - - while (n_coeffs > 0) { - quantize(qp, coeff_ptr, iscan, qcoeff_ptr, dqcoeff_ptr, &eob); - - coeff_ptr += step; - qcoeff_ptr += step; - dqcoeff_ptr += step; - iscan += step; - n_coeffs -= step; - } - - *eob_ptr = get_max_eob(eob); -} - -static VPX_FORCE_INLINE __m256i mm256_mul_shift_epi32_logscale(const __m256i *x, - const __m256i *y, - int log_scale) { - __m256i prod_lo = _mm256_mul_epi32(*x, *y); - __m256i prod_hi = _mm256_srli_epi64(*x, 32); - const __m256i mult_hi = _mm256_srli_epi64(*y, 32); - const __m256i mask = _mm256_set_epi32(0, -1, 0, -1, 0, -1, 0, -1); - prod_hi = _mm256_mul_epi32(prod_hi, mult_hi); - prod_lo = _mm256_srli_epi64(prod_lo, 16 - log_scale); - prod_lo = _mm256_and_si256(prod_lo, mask); - prod_hi = _mm256_srli_epi64(prod_hi, 16 - log_scale); - prod_hi = _mm256_slli_epi64(prod_hi, 32); - return _mm256_or_si256(prod_lo, prod_hi); -} - -static VPX_FORCE_INLINE void quantize_b_32x32( - const __m256i *qp, const tran_low_t *coeff_ptr, const int16_t *iscan_ptr, - tran_low_t *qcoeff, tran_low_t *dqcoeff, __m256i *eob) { - const __m256i coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr); - const __m256i abs_coeff = _mm256_abs_epi32(coeff); - const __m256i zbin_mask = _mm256_cmpgt_epi32(abs_coeff, qp[0]); - - if (_mm256_movemask_epi8(zbin_mask) == 0) { - const __m256i zero = _mm256_setzero_si256(); - _mm256_storeu_si256((__m256i *)qcoeff, zero); - _mm256_storeu_si256((__m256i *)dqcoeff, zero); - return; - } - - { - const __m256i tmp_rnd = - _mm256_and_si256(_mm256_add_epi32(abs_coeff, qp[1]), zbin_mask); - // const int64_t tmp2 = ((tmpw * quant_ptr[rc != 0]) >> 16) + tmpw; - const __m256i tmp = mm256_mul_shift_epi32_logscale(&tmp_rnd, &qp[2], 0); - const __m256i tmp2 = _mm256_add_epi32(tmp, tmp_rnd); - // const int abs_qcoeff = (int)((tmp2 * quant_shift_ptr[rc != 0]) >> 15); - const __m256i abs_q = mm256_mul_shift_epi32_logscale(&tmp2, &qp[4], 1); - const __m256i abs_dq = - _mm256_srli_epi32(_mm256_mullo_epi32(abs_q, qp[3]), 1); - const __m256i nz_mask = _mm256_cmpgt_epi32(abs_q, _mm256_setzero_si256()); - const __m256i q = _mm256_sign_epi32(abs_q, coeff); - const __m256i dq = _mm256_sign_epi32(abs_dq, coeff); - - _mm256_storeu_si256((__m256i *)qcoeff, q); - _mm256_storeu_si256((__m256i *)dqcoeff, dq); - - *eob = get_max_lane_eob(iscan_ptr, *eob, nz_mask); - } -} - -void vpx_highbd_quantize_b_32x32_avx2( - const tran_low_t *coeff_ptr, const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, - uint16_t *eob_ptr, const struct ScanOrder *const scan_order) { - const unsigned int step = 8; - intptr_t n_coeffs = 32 * 32; - const int16_t *iscan = scan_order->iscan; - __m256i eob = _mm256_setzero_si256(); - __m256i qp[5]; - - init_qp(mb_plane, dequant_ptr, qp, 1); - - quantize_b_32x32(qp, coeff_ptr, iscan, qcoeff_ptr, dqcoeff_ptr, &eob); - - coeff_ptr += step; - qcoeff_ptr += step; - dqcoeff_ptr += step; - iscan += step; - n_coeffs -= step; - - update_qp(qp); - - while (n_coeffs > 0) { - quantize_b_32x32(qp, coeff_ptr, iscan, qcoeff_ptr, dqcoeff_ptr, &eob); - - coeff_ptr += step; - qcoeff_ptr += step; - dqcoeff_ptr += step; - iscan += step; - n_coeffs -= step; - } - - *eob_ptr = get_max_eob(eob); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_quantize_intrin_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_quantize_intrin_sse2.c deleted file mode 100644 index adae6075..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_quantize_intrin_sse2.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/vpx_dsp_common.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" -#include "vp9/common/vp9_scan.h" -#include "vp9/encoder/vp9_block.h" - -void vpx_highbd_quantize_b_sse2(const tran_low_t *coeff_ptr, intptr_t count, - const struct macroblock_plane *mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - int i, j, non_zero_regs = (int)count / 4, eob_i = 0; - __m128i zbins[2]; - __m128i nzbins[2]; - const int16_t *iscan = scan_order->iscan; - const int16_t *zbin_ptr = mb_plane->zbin; - const int16_t *round_ptr = mb_plane->round; - const int16_t *quant_ptr = mb_plane->quant; - const int16_t *quant_shift_ptr = mb_plane->quant_shift; - - zbins[0] = _mm_set_epi32((int)zbin_ptr[1], (int)zbin_ptr[1], (int)zbin_ptr[1], - (int)zbin_ptr[0]); - zbins[1] = _mm_set1_epi32((int)zbin_ptr[1]); - - nzbins[0] = _mm_setzero_si128(); - nzbins[1] = _mm_setzero_si128(); - nzbins[0] = _mm_sub_epi32(nzbins[0], zbins[0]); - nzbins[1] = _mm_sub_epi32(nzbins[1], zbins[1]); - - memset(qcoeff_ptr, 0, count * sizeof(*qcoeff_ptr)); - memset(dqcoeff_ptr, 0, count * sizeof(*dqcoeff_ptr)); - - // Pre-scan pass - for (i = ((int)count / 4) - 1; i >= 0; i--) { - __m128i coeffs, cmp1, cmp2; - int test; - coeffs = _mm_load_si128((const __m128i *)(coeff_ptr + i * 4)); - cmp1 = _mm_cmplt_epi32(coeffs, zbins[i != 0]); - cmp2 = _mm_cmpgt_epi32(coeffs, nzbins[i != 0]); - cmp1 = _mm_and_si128(cmp1, cmp2); - test = _mm_movemask_epi8(cmp1); - if (test == 0xffff) - non_zero_regs--; - else - break; - } - - // Quantization pass: - for (i = 0; i < non_zero_regs; i++) { - __m128i coeffs, coeffs_sign, tmp1, tmp2; - int test; - int abs_coeff[4]; - int coeff_sign[4]; - - coeffs = _mm_load_si128((const __m128i *)(coeff_ptr + i * 4)); - coeffs_sign = _mm_srai_epi32(coeffs, 31); - coeffs = _mm_sub_epi32(_mm_xor_si128(coeffs, coeffs_sign), coeffs_sign); - tmp1 = _mm_cmpgt_epi32(coeffs, zbins[i != 0]); - tmp2 = _mm_cmpeq_epi32(coeffs, zbins[i != 0]); - tmp1 = _mm_or_si128(tmp1, tmp2); - test = _mm_movemask_epi8(tmp1); - _mm_storeu_si128((__m128i *)abs_coeff, coeffs); - _mm_storeu_si128((__m128i *)coeff_sign, coeffs_sign); - - for (j = 0; j < 4; j++) { - if (test & (1 << (4 * j))) { - int k = 4 * i + j; - const int64_t tmp3 = abs_coeff[j] + round_ptr[k != 0]; - const int64_t tmp4 = ((tmp3 * quant_ptr[k != 0]) >> 16) + tmp3; - const uint32_t abs_qcoeff = - (uint32_t)((tmp4 * quant_shift_ptr[k != 0]) >> 16); - qcoeff_ptr[k] = - (int)(abs_qcoeff ^ (uint32_t)coeff_sign[j]) - coeff_sign[j]; - dqcoeff_ptr[k] = qcoeff_ptr[k] * dequant_ptr[k != 0]; - if (abs_qcoeff) eob_i = iscan[k] > eob_i ? iscan[k] : eob_i; - } - } - } - *eob_ptr = eob_i; -} - -void vpx_highbd_quantize_b_32x32_sse2( - const tran_low_t *coeff_ptr, const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, - uint16_t *eob_ptr, const struct ScanOrder *const scan_order) { - __m128i zbins[2]; - __m128i nzbins[2]; - int idx = 0; - int idx_arr[1024]; - int i, eob = 0; - const intptr_t n_coeffs = 32 * 32; - const int16_t *iscan = scan_order->iscan; - const int zbin0_tmp = ROUND_POWER_OF_TWO(mb_plane->zbin[0], 1); - const int zbin1_tmp = ROUND_POWER_OF_TWO(mb_plane->zbin[1], 1); - - zbins[0] = _mm_set_epi32(zbin1_tmp, zbin1_tmp, zbin1_tmp, zbin0_tmp); - zbins[1] = _mm_set1_epi32(zbin1_tmp); - - nzbins[0] = _mm_setzero_si128(); - nzbins[1] = _mm_setzero_si128(); - nzbins[0] = _mm_sub_epi32(nzbins[0], zbins[0]); - nzbins[1] = _mm_sub_epi32(nzbins[1], zbins[1]); - - memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); - memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); - - // Pre-scan pass - for (i = 0; i < n_coeffs / 4; i++) { - __m128i coeffs, cmp1, cmp2; - int test; - coeffs = _mm_load_si128((const __m128i *)(coeff_ptr + i * 4)); - cmp1 = _mm_cmplt_epi32(coeffs, zbins[i != 0]); - cmp2 = _mm_cmpgt_epi32(coeffs, nzbins[i != 0]); - cmp1 = _mm_and_si128(cmp1, cmp2); - test = _mm_movemask_epi8(cmp1); - if (!(test & 0xf)) idx_arr[idx++] = i * 4; - if (!(test & 0xf0)) idx_arr[idx++] = i * 4 + 1; - if (!(test & 0xf00)) idx_arr[idx++] = i * 4 + 2; - if (!(test & 0xf000)) idx_arr[idx++] = i * 4 + 3; - } - - // Quantization pass: only process the coefficients selected in - // pre-scan pass. Note: idx can be zero. - for (i = 0; i < idx; i++) { - const int rc = idx_arr[i]; - const int coeff = coeff_ptr[rc]; - const int coeff_sign = (coeff >> 31); - const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; - const int64_t tmp1 = - abs_coeff + ROUND_POWER_OF_TWO(mb_plane->round[rc != 0], 1); - const int64_t tmp2 = ((tmp1 * mb_plane->quant[rc != 0]) >> 16) + tmp1; - const uint32_t abs_qcoeff = - (uint32_t)((tmp2 * mb_plane->quant_shift[rc != 0]) >> 15); - qcoeff_ptr[rc] = (int)(abs_qcoeff ^ (uint32_t)coeff_sign) - coeff_sign; - dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2; - if (abs_qcoeff) eob = iscan[idx_arr[i]] > eob ? iscan[idx_arr[i]] : eob; - } - *eob_ptr = eob; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_sad4d_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_sad4d_avx2.c deleted file mode 100644 index e483fdce..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_sad4d_avx2.c +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include // AVX2 -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" - -static VPX_FORCE_INLINE void calc_final_4(const __m256i *const sums /*[4]*/, - uint32_t sad_array[4]) { - const __m256i t0 = _mm256_hadd_epi32(sums[0], sums[1]); - const __m256i t1 = _mm256_hadd_epi32(sums[2], sums[3]); - const __m256i t2 = _mm256_hadd_epi32(t0, t1); - const __m128i sum = _mm_add_epi32(_mm256_castsi256_si128(t2), - _mm256_extractf128_si256(t2, 1)); - _mm_storeu_si128((__m128i *)sad_array, sum); -} - -static VPX_FORCE_INLINE void highbd_sad64xHx4d(__m256i *sums_16 /*[4]*/, - const uint16_t *src, - int src_stride, - uint16_t *refs[4], - int ref_stride, int height) { - int i; - for (i = 0; i < height; ++i) { - // load src and all ref[] - const __m256i s0 = _mm256_load_si256((const __m256i *)src); - const __m256i s1 = _mm256_load_si256((const __m256i *)(src + 16)); - const __m256i s2 = _mm256_load_si256((const __m256i *)(src + 32)); - const __m256i s3 = _mm256_load_si256((const __m256i *)(src + 48)); - int x; - - for (x = 0; x < 4; ++x) { - __m256i r[4]; - r[0] = _mm256_loadu_si256((const __m256i *)refs[x]); - r[1] = _mm256_loadu_si256((const __m256i *)(refs[x] + 16)); - r[2] = _mm256_loadu_si256((const __m256i *)(refs[x] + 32)); - r[3] = _mm256_loadu_si256((const __m256i *)(refs[x] + 48)); - - // absolute differences between every ref[] to src - r[0] = _mm256_abs_epi16(_mm256_sub_epi16(r[0], s0)); - r[1] = _mm256_abs_epi16(_mm256_sub_epi16(r[1], s1)); - r[2] = _mm256_abs_epi16(_mm256_sub_epi16(r[2], s2)); - r[3] = _mm256_abs_epi16(_mm256_sub_epi16(r[3], s3)); - - // sum every abs diff - sums_16[x] = _mm256_add_epi16(sums_16[x], _mm256_add_epi16(r[0], r[1])); - sums_16[x] = _mm256_add_epi16(sums_16[x], _mm256_add_epi16(r[2], r[3])); - } - - src += src_stride; - refs[0] += ref_stride; - refs[1] += ref_stride; - refs[2] += ref_stride; - refs[3] += ref_stride; - } -} - -static VPX_FORCE_INLINE void highbd_sad64xNx4d_avx2( - const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], - int ref_stride, uint32_t sad_array[4], int n) { - const uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); - uint16_t *refs[4]; - __m256i sums_16[4]; - __m256i sums_32[4]; - int i; - - refs[0] = CONVERT_TO_SHORTPTR(ref_array[0]); - refs[1] = CONVERT_TO_SHORTPTR(ref_array[1]); - refs[2] = CONVERT_TO_SHORTPTR(ref_array[2]); - refs[3] = CONVERT_TO_SHORTPTR(ref_array[3]); - sums_32[0] = _mm256_setzero_si256(); - sums_32[1] = _mm256_setzero_si256(); - sums_32[2] = _mm256_setzero_si256(); - sums_32[3] = _mm256_setzero_si256(); - - for (i = 0; i < (n / 2); ++i) { - sums_16[0] = _mm256_setzero_si256(); - sums_16[1] = _mm256_setzero_si256(); - sums_16[2] = _mm256_setzero_si256(); - sums_16[3] = _mm256_setzero_si256(); - - highbd_sad64xHx4d(sums_16, src, src_stride, refs, ref_stride, 2); - - /* sums_16 will outrange after 2 rows, so add current sums_16 to - * sums_32*/ - sums_32[0] = _mm256_add_epi32( - sums_32[0], - _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[0])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[0], 1)))); - sums_32[1] = _mm256_add_epi32( - sums_32[1], - _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[1])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[1], 1)))); - sums_32[2] = _mm256_add_epi32( - sums_32[2], - _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[2])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[2], 1)))); - sums_32[3] = _mm256_add_epi32( - sums_32[3], - _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[3])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[3], 1)))); - - src += src_stride << 1; - } - calc_final_4(sums_32, sad_array); -} - -#define HIGHBD_SAD64XNX4D(n) \ - void vpx_highbd_sad64x##n##x4d_avx2(const uint8_t *src, int src_stride, \ - const uint8_t *const ref_array[4], \ - int ref_stride, uint32_t sad_array[4]) { \ - highbd_sad64xNx4d_avx2(src, src_stride, ref_array, ref_stride, sad_array, \ - n); \ - } - -#define HIGHBD_SADSKIP64XNx4D(n) \ - void vpx_highbd_sad_skip_64x##n##x4d_avx2( \ - const uint8_t *src, int src_stride, const uint8_t *const ref_array[4], \ - int ref_stride, uint32_t sad_array[4]) { \ - highbd_sad64xNx4d_avx2(src, 2 * src_stride, ref_array, 2 * ref_stride, \ - sad_array, n / 2); \ - sad_array[0] <<= 1; \ - sad_array[1] <<= 1; \ - sad_array[2] <<= 1; \ - sad_array[3] <<= 1; \ - } - -static VPX_FORCE_INLINE void highbd_sad32xHx4d(__m256i *sums_16 /*[4]*/, - const uint16_t *src, - int src_stride, - uint16_t *refs[4], - int ref_stride, int height) { - int i; - for (i = 0; i < height; i++) { - __m256i r[8]; - - // load src and all ref[] - const __m256i s = _mm256_load_si256((const __m256i *)src); - const __m256i s2 = _mm256_load_si256((const __m256i *)(src + 16)); - r[0] = _mm256_loadu_si256((const __m256i *)refs[0]); - r[1] = _mm256_loadu_si256((const __m256i *)(refs[0] + 16)); - r[2] = _mm256_loadu_si256((const __m256i *)refs[1]); - r[3] = _mm256_loadu_si256((const __m256i *)(refs[1] + 16)); - r[4] = _mm256_loadu_si256((const __m256i *)refs[2]); - r[5] = _mm256_loadu_si256((const __m256i *)(refs[2] + 16)); - r[6] = _mm256_loadu_si256((const __m256i *)refs[3]); - r[7] = _mm256_loadu_si256((const __m256i *)(refs[3] + 16)); - - // absolute differences between every ref[] to src - r[0] = _mm256_abs_epi16(_mm256_sub_epi16(r[0], s)); - r[1] = _mm256_abs_epi16(_mm256_sub_epi16(r[1], s2)); - r[2] = _mm256_abs_epi16(_mm256_sub_epi16(r[2], s)); - r[3] = _mm256_abs_epi16(_mm256_sub_epi16(r[3], s2)); - r[4] = _mm256_abs_epi16(_mm256_sub_epi16(r[4], s)); - r[5] = _mm256_abs_epi16(_mm256_sub_epi16(r[5], s2)); - r[6] = _mm256_abs_epi16(_mm256_sub_epi16(r[6], s)); - r[7] = _mm256_abs_epi16(_mm256_sub_epi16(r[7], s2)); - - // sum every abs diff - sums_16[0] = _mm256_add_epi16(sums_16[0], _mm256_add_epi16(r[0], r[1])); - sums_16[1] = _mm256_add_epi16(sums_16[1], _mm256_add_epi16(r[2], r[3])); - sums_16[2] = _mm256_add_epi16(sums_16[2], _mm256_add_epi16(r[4], r[5])); - sums_16[3] = _mm256_add_epi16(sums_16[3], _mm256_add_epi16(r[6], r[7])); - - src += src_stride; - refs[0] += ref_stride; - refs[1] += ref_stride; - refs[2] += ref_stride; - refs[3] += ref_stride; - } -} - -static VPX_FORCE_INLINE void highbd_sad32xNx4d_avx2( - const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], - int ref_stride, uint32_t sad_array[4], int n) { - const uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); - uint16_t *refs[4]; - __m256i sums_16[4]; - __m256i sums_32[4]; - int i; - - refs[0] = CONVERT_TO_SHORTPTR(ref_array[0]); - refs[1] = CONVERT_TO_SHORTPTR(ref_array[1]); - refs[2] = CONVERT_TO_SHORTPTR(ref_array[2]); - refs[3] = CONVERT_TO_SHORTPTR(ref_array[3]); - sums_32[0] = _mm256_setzero_si256(); - sums_32[1] = _mm256_setzero_si256(); - sums_32[2] = _mm256_setzero_si256(); - sums_32[3] = _mm256_setzero_si256(); - - for (i = 0; i < (n / 8); ++i) { - sums_16[0] = _mm256_setzero_si256(); - sums_16[1] = _mm256_setzero_si256(); - sums_16[2] = _mm256_setzero_si256(); - sums_16[3] = _mm256_setzero_si256(); - - highbd_sad32xHx4d(sums_16, src, src_stride, refs, ref_stride, 8); - - /* sums_16 will outrange after 8 rows, so add current sums_16 to - * sums_32*/ - sums_32[0] = _mm256_add_epi32( - sums_32[0], - _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[0])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[0], 1)))); - sums_32[1] = _mm256_add_epi32( - sums_32[1], - _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[1])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[1], 1)))); - sums_32[2] = _mm256_add_epi32( - sums_32[2], - _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[2])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[2], 1)))); - sums_32[3] = _mm256_add_epi32( - sums_32[3], - _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[3])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[3], 1)))); - - src += src_stride << 3; - } - calc_final_4(sums_32, sad_array); -} - -#define HIGHBD_SAD32XNX4D(n) \ - void vpx_highbd_sad32x##n##x4d_avx2(const uint8_t *src, int src_stride, \ - const uint8_t *const ref_array[4], \ - int ref_stride, uint32_t sad_array[4]) { \ - highbd_sad32xNx4d_avx2(src, src_stride, ref_array, ref_stride, sad_array, \ - n); \ - } - -#define HIGHBD_SADSKIP32XNx4D(n) \ - void vpx_highbd_sad_skip_32x##n##x4d_avx2( \ - const uint8_t *src, int src_stride, const uint8_t *const ref_array[4], \ - int ref_stride, uint32_t sad_array[4]) { \ - highbd_sad32xNx4d_avx2(src, 2 * src_stride, ref_array, 2 * ref_stride, \ - sad_array, n / 2); \ - sad_array[0] <<= 1; \ - sad_array[1] <<= 1; \ - sad_array[2] <<= 1; \ - sad_array[3] <<= 1; \ - } - -static VPX_FORCE_INLINE void highbd_sad16xHx4d(__m256i *sums_16 /*[4]*/, - const uint16_t *src, - int src_stride, - uint16_t *refs[4], - int ref_stride, int height) { - int i; - for (i = 0; i < height; i++) { - __m256i r[4]; - - // load src and all ref[] - const __m256i s = _mm256_load_si256((const __m256i *)src); - r[0] = _mm256_loadu_si256((const __m256i *)refs[0]); - r[1] = _mm256_loadu_si256((const __m256i *)refs[1]); - r[2] = _mm256_loadu_si256((const __m256i *)refs[2]); - r[3] = _mm256_loadu_si256((const __m256i *)refs[3]); - - // absolute differences between every ref[] to src - r[0] = _mm256_abs_epi16(_mm256_sub_epi16(r[0], s)); - r[1] = _mm256_abs_epi16(_mm256_sub_epi16(r[1], s)); - r[2] = _mm256_abs_epi16(_mm256_sub_epi16(r[2], s)); - r[3] = _mm256_abs_epi16(_mm256_sub_epi16(r[3], s)); - - // sum every abs diff - sums_16[0] = _mm256_add_epi16(sums_16[0], r[0]); - sums_16[1] = _mm256_add_epi16(sums_16[1], r[1]); - sums_16[2] = _mm256_add_epi16(sums_16[2], r[2]); - sums_16[3] = _mm256_add_epi16(sums_16[3], r[3]); - - src += src_stride; - refs[0] += ref_stride; - refs[1] += ref_stride; - refs[2] += ref_stride; - refs[3] += ref_stride; - } -} - -static VPX_FORCE_INLINE void highbd_sad16xNx4d_avx2( - const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], - int ref_stride, uint32_t sad_array[4], int n) { - const uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); - uint16_t *refs[4]; - __m256i sums_16[4]; - __m256i sums_32[4]; - const int height = VPXMIN(16, n); - const int num_iters = n / height; - int i; - - refs[0] = CONVERT_TO_SHORTPTR(ref_array[0]); - refs[1] = CONVERT_TO_SHORTPTR(ref_array[1]); - refs[2] = CONVERT_TO_SHORTPTR(ref_array[2]); - refs[3] = CONVERT_TO_SHORTPTR(ref_array[3]); - sums_32[0] = _mm256_setzero_si256(); - sums_32[1] = _mm256_setzero_si256(); - sums_32[2] = _mm256_setzero_si256(); - sums_32[3] = _mm256_setzero_si256(); - - for (i = 0; i < num_iters; ++i) { - sums_16[0] = _mm256_setzero_si256(); - sums_16[1] = _mm256_setzero_si256(); - sums_16[2] = _mm256_setzero_si256(); - sums_16[3] = _mm256_setzero_si256(); - - highbd_sad16xHx4d(sums_16, src, src_stride, refs, ref_stride, height); - - // sums_16 will outrange after 16 rows, so add current sums_16 to sums_32 - sums_32[0] = _mm256_add_epi32( - sums_32[0], - _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[0])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[0], 1)))); - sums_32[1] = _mm256_add_epi32( - sums_32[1], - _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[1])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[1], 1)))); - sums_32[2] = _mm256_add_epi32( - sums_32[2], - _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[2])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[2], 1)))); - sums_32[3] = _mm256_add_epi32( - sums_32[3], - _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[3])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[3], 1)))); - - src += src_stride << 4; - } - calc_final_4(sums_32, sad_array); -} - -#define HIGHBD_SAD16XNX4D(n) \ - void vpx_highbd_sad16x##n##x4d_avx2(const uint8_t *src, int src_stride, \ - const uint8_t *const ref_array[4], \ - int ref_stride, uint32_t sad_array[4]) { \ - highbd_sad16xNx4d_avx2(src, src_stride, ref_array, ref_stride, sad_array, \ - n); \ - } - -#define HIGHBD_SADSKIP16XNx4D(n) \ - void vpx_highbd_sad_skip_16x##n##x4d_avx2( \ - const uint8_t *src, int src_stride, const uint8_t *const ref_array[4], \ - int ref_stride, uint32_t sad_array[4]) { \ - highbd_sad16xNx4d_avx2(src, 2 * src_stride, ref_array, 2 * ref_stride, \ - sad_array, n / 2); \ - sad_array[0] <<= 1; \ - sad_array[1] <<= 1; \ - sad_array[2] <<= 1; \ - sad_array[3] <<= 1; \ - } - -void vpx_highbd_sad16x16x4d_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *const ref_array[4], - int ref_stride, uint32_t sad_array[4]) { - const uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); - uint16_t *refs[4]; - __m256i sums_16[4]; - - refs[0] = CONVERT_TO_SHORTPTR(ref_array[0]); - refs[1] = CONVERT_TO_SHORTPTR(ref_array[1]); - refs[2] = CONVERT_TO_SHORTPTR(ref_array[2]); - refs[3] = CONVERT_TO_SHORTPTR(ref_array[3]); - sums_16[0] = _mm256_setzero_si256(); - sums_16[1] = _mm256_setzero_si256(); - sums_16[2] = _mm256_setzero_si256(); - sums_16[3] = _mm256_setzero_si256(); - - highbd_sad16xHx4d(sums_16, src, src_stride, refs, ref_stride, 16); - - { - __m256i sums_32[4]; - sums_32[0] = _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[0])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[0], 1))); - sums_32[1] = _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[1])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[1], 1))); - sums_32[2] = _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[2])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[2], 1))); - sums_32[3] = _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[3])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[3], 1))); - calc_final_4(sums_32, sad_array); - } -} - -void vpx_highbd_sad16x8x4d_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *const ref_array[4], - int ref_stride, uint32_t sad_array[4]) { - const uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); - uint16_t *refs[4]; - __m256i sums_16[4]; - - refs[0] = CONVERT_TO_SHORTPTR(ref_array[0]); - refs[1] = CONVERT_TO_SHORTPTR(ref_array[1]); - refs[2] = CONVERT_TO_SHORTPTR(ref_array[2]); - refs[3] = CONVERT_TO_SHORTPTR(ref_array[3]); - sums_16[0] = _mm256_setzero_si256(); - sums_16[1] = _mm256_setzero_si256(); - sums_16[2] = _mm256_setzero_si256(); - sums_16[3] = _mm256_setzero_si256(); - - highbd_sad16xHx4d(sums_16, src, src_stride, refs, ref_stride, 8); - - { - __m256i sums_32[4]; - sums_32[0] = _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[0])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[0], 1))); - sums_32[1] = _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[1])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[1], 1))); - sums_32[2] = _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[2])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[2], 1))); - sums_32[3] = _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16[3])), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16[3], 1))); - calc_final_4(sums_32, sad_array); - } -} - -// clang-format off -HIGHBD_SAD64XNX4D(64) -HIGHBD_SADSKIP64XNx4D(64) - -HIGHBD_SAD64XNX4D(32) -HIGHBD_SADSKIP64XNx4D(32) - -HIGHBD_SAD32XNX4D(64) -HIGHBD_SADSKIP32XNx4D(64) - -HIGHBD_SAD32XNX4D(32) -HIGHBD_SADSKIP32XNx4D(32) - -HIGHBD_SAD32XNX4D(16) -HIGHBD_SADSKIP32XNx4D(16) - -HIGHBD_SAD16XNX4D(32) -HIGHBD_SADSKIP16XNx4D(32) - -HIGHBD_SADSKIP16XNx4D(16) - -HIGHBD_SADSKIP16XNx4D(8) - // clang-format on diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_sad4d_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_sad4d_sse2.asm deleted file mode 100644 index a07892d8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_sad4d_sse2.asm +++ /dev/null @@ -1,326 +0,0 @@ -; -; Copyright (c) 2014 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "third_party/x86inc/x86inc.asm" - -SECTION .text - -; HIGH_PROCESS_4x2x4 first, off_{first,second}_{src,ref}, advance_at_end -%macro HIGH_PROCESS_4x2x4 5-6 0 - movh m0, [srcq +%2*2] -%if %1 == 1 - movu m4, [ref1q+%3*2] - movu m5, [ref2q+%3*2] - movu m6, [ref3q+%3*2] - movu m7, [ref4q+%3*2] - movhps m0, [srcq +%4*2] - movhps m4, [ref1q+%5*2] - movhps m5, [ref2q+%5*2] - movhps m6, [ref3q+%5*2] - movhps m7, [ref4q+%5*2] - mova m3, m0 - mova m2, m0 - psubusw m3, m4 - psubusw m2, m5 - psubusw m4, m0 - psubusw m5, m0 - por m4, m3 - por m5, m2 - pmaddwd m4, m1 - pmaddwd m5, m1 - mova m3, m0 - mova m2, m0 - psubusw m3, m6 - psubusw m2, m7 - psubusw m6, m0 - psubusw m7, m0 - por m6, m3 - por m7, m2 - pmaddwd m6, m1 - pmaddwd m7, m1 -%else - movu m2, [ref1q+%3*2] - movhps m0, [srcq +%4*2] - movhps m2, [ref1q+%5*2] - mova m3, m0 - psubusw m3, m2 - psubusw m2, m0 - por m2, m3 - pmaddwd m2, m1 - paddd m4, m2 - - movu m2, [ref2q+%3*2] - mova m3, m0 - movhps m2, [ref2q+%5*2] - psubusw m3, m2 - psubusw m2, m0 - por m2, m3 - pmaddwd m2, m1 - paddd m5, m2 - - movu m2, [ref3q+%3*2] - mova m3, m0 - movhps m2, [ref3q+%5*2] - psubusw m3, m2 - psubusw m2, m0 - por m2, m3 - pmaddwd m2, m1 - paddd m6, m2 - - movu m2, [ref4q+%3*2] - mova m3, m0 - movhps m2, [ref4q+%5*2] - psubusw m3, m2 - psubusw m2, m0 - por m2, m3 - pmaddwd m2, m1 - paddd m7, m2 -%endif -%if %6 == 1 - lea srcq, [srcq +src_strideq*4] - lea ref1q, [ref1q+ref_strideq*4] - lea ref2q, [ref2q+ref_strideq*4] - lea ref3q, [ref3q+ref_strideq*4] - lea ref4q, [ref4q+ref_strideq*4] -%endif -%endmacro - -; PROCESS_8x2x4 first, off_{first,second}_{src,ref}, advance_at_end -%macro HIGH_PROCESS_8x2x4 5-6 0 - ; 1st 8 px - mova m0, [srcq +%2*2] -%if %1 == 1 - movu m4, [ref1q+%3*2] - movu m5, [ref2q+%3*2] - movu m6, [ref3q+%3*2] - movu m7, [ref4q+%3*2] - mova m3, m0 - mova m2, m0 - psubusw m3, m4 - psubusw m2, m5 - psubusw m4, m0 - psubusw m5, m0 - por m4, m3 - por m5, m2 - pmaddwd m4, m1 - pmaddwd m5, m1 - mova m3, m0 - mova m2, m0 - psubusw m3, m6 - psubusw m2, m7 - psubusw m6, m0 - psubusw m7, m0 - por m6, m3 - por m7, m2 - pmaddwd m6, m1 - pmaddwd m7, m1 -%else - mova m3, m0 - movu m2, [ref1q+%3*2] - psubusw m3, m2 - psubusw m2, m0 - por m2, m3 - mova m3, m0 - pmaddwd m2, m1 - paddd m4, m2 - movu m2, [ref2q+%3*2] - psubusw m3, m2 - psubusw m2, m0 - por m2, m3 - mova m3, m0 - pmaddwd m2, m1 - paddd m5, m2 - movu m2, [ref3q+%3*2] - psubusw m3, m2 - psubusw m2, m0 - por m2, m3 - mova m3, m0 - pmaddwd m2, m1 - paddd m6, m2 - movu m2, [ref4q+%3*2] - psubusw m3, m2 - psubusw m2, m0 - por m2, m3 - pmaddwd m2, m1 - paddd m7, m2 -%endif - - ; 2nd 8 px - mova m0, [srcq +(%4)*2] - mova m3, m0 - movu m2, [ref1q+(%5)*2] - psubusw m3, m2 - psubusw m2, m0 - por m2, m3 - mova m3, m0 - pmaddwd m2, m1 - paddd m4, m2 - movu m2, [ref2q+(%5)*2] - psubusw m3, m2 - psubusw m2, m0 - por m2, m3 - mova m3, m0 - pmaddwd m2, m1 - paddd m5, m2 - movu m2, [ref3q+(%5)*2] - psubusw m3, m2 - psubusw m2, m0 - por m2, m3 - mova m3, m0 - pmaddwd m2, m1 - paddd m6, m2 - movu m2, [ref4q+(%5)*2] - psubusw m3, m2 - psubusw m2, m0 -%if %6 == 1 - lea srcq, [srcq +src_strideq*4] - lea ref1q, [ref1q+ref_strideq*4] - lea ref2q, [ref2q+ref_strideq*4] - lea ref3q, [ref3q+ref_strideq*4] - lea ref4q, [ref4q+ref_strideq*4] -%endif - por m2, m3 - pmaddwd m2, m1 - paddd m7, m2 -%endmacro - -; HIGH_PROCESS_16x2x4 first, off_{first,second}_{src,ref}, advance_at_end -%macro HIGH_PROCESS_16x2x4 5-6 0 - HIGH_PROCESS_8x2x4 %1, %2, %3, (%2 + 8), (%3 + 8) - HIGH_PROCESS_8x2x4 0, %4, %5, (%4 + 8), (%5 + 8), %6 -%endmacro - -; HIGH_PROCESS_32x2x4 first, off_{first,second}_{src,ref}, advance_at_end -%macro HIGH_PROCESS_32x2x4 5-6 0 - HIGH_PROCESS_16x2x4 %1, %2, %3, (%2 + 16), (%3 + 16) - HIGH_PROCESS_16x2x4 0, %4, %5, (%4 + 16), (%5 + 16), %6 -%endmacro - -; HIGH_PROCESS_64x2x4 first, off_{first,second}_{src,ref}, advance_at_end -%macro HIGH_PROCESS_64x2x4 5-6 0 - HIGH_PROCESS_32x2x4 %1, %2, %3, (%2 + 32), (%3 + 32) - HIGH_PROCESS_32x2x4 0, %4, %5, (%4 + 32), (%5 + 32), %6 -%endmacro - -; void vpx_highbd_sadNxNx4d_sse2(uint8_t *src, int src_stride, -; uint8_t *ref[4], int ref_stride, -; uint32_t res[4]); -; where NxN = 64x64, 32x32, 16x16, 16x8, 8x16 or 8x8 -; Macro Arguments: -; 1: Width -; 2: Height -; 3: If 0, then normal sad, if 2, then skip every other row -%macro HIGH_SADNXN4D 2-3 0 -%if %3 == 0 ; normal sad -%if UNIX64 -cglobal highbd_sad%1x%2x4d, 5, 8, 8, src, src_stride, ref1, ref_stride, \ - res, ref2, ref3, ref4 -%else -cglobal highbd_sad%1x%2x4d, 4, 7, 8, src, src_stride, ref1, ref_stride, \ - ref2, ref3, ref4 -%endif -%else ; %3 == 2, downsample -%if UNIX64 -cglobal highbd_sad_skip_%1x%2x4d, 5, 8, 8, src, src_stride, ref1, ref_stride, \ - res, ref2, ref3, ref4 -%else -cglobal highbd_sad_skip_%1x%2x4d, 4, 7, 8, src, src_stride, ref1, ref_stride, \ - ref2, ref3, ref4 -%endif ; -%endif ; sad/avg/skip - -; set m1 - push srcq - mov srcd, 0x00010001 - movd m1, srcd - pshufd m1, m1, 0x0 - pop srcq - -%if %3 == 2 ; skip rows - lea src_strided, [2*src_strided] - lea ref_strided, [2*ref_strided] -%endif ; skip rows - movsxdifnidn src_strideq, src_strided - movsxdifnidn ref_strideq, ref_strided - mov ref2q, [ref1q+gprsize*1] - mov ref3q, [ref1q+gprsize*2] - mov ref4q, [ref1q+gprsize*3] - mov ref1q, [ref1q+gprsize*0] - -; convert byte pointers to short pointers - shl srcq, 1 - shl ref2q, 1 - shl ref3q, 1 - shl ref4q, 1 - shl ref1q, 1 - - HIGH_PROCESS_%1x2x4 1, 0, 0, src_strideq, ref_strideq, 1 -%if %3 == 2 ; Downsampling by two -%define num_rep (%2-8)/4 -%else -%define num_rep (%2-4)/2 -%endif -%rep num_rep - HIGH_PROCESS_%1x2x4 0, 0, 0, src_strideq, ref_strideq, 1 -%endrep -%undef rep - HIGH_PROCESS_%1x2x4 0, 0, 0, src_strideq, ref_strideq, 0 - ; N.B. HIGH_PROCESS outputs dwords (32 bits) - ; so in high bit depth even the smallest width (4) needs 128bits i.e. XMM - movhlps m0, m4 - movhlps m1, m5 - movhlps m2, m6 - movhlps m3, m7 - paddd m4, m0 - paddd m5, m1 - paddd m6, m2 - paddd m7, m3 - punpckldq m4, m5 - punpckldq m6, m7 - movhlps m0, m4 - movhlps m1, m6 - paddd m4, m0 - paddd m6, m1 - punpcklqdq m4, m6 -%if %3 == 2 ; skip rows - pslld m4, 1 -%endif - movifnidn r4, r4mp - movu [r4], m4 - RET -%endmacro - - -INIT_XMM sse2 -HIGH_SADNXN4D 64, 64 -HIGH_SADNXN4D 64, 32 -HIGH_SADNXN4D 32, 64 -HIGH_SADNXN4D 32, 32 -HIGH_SADNXN4D 32, 16 -HIGH_SADNXN4D 16, 32 -HIGH_SADNXN4D 16, 16 -HIGH_SADNXN4D 16, 8 -HIGH_SADNXN4D 8, 16 -HIGH_SADNXN4D 8, 8 -HIGH_SADNXN4D 8, 4 -HIGH_SADNXN4D 4, 8 -HIGH_SADNXN4D 4, 4 - -HIGH_SADNXN4D 64, 64, 2 -HIGH_SADNXN4D 64, 32, 2 -HIGH_SADNXN4D 32, 64, 2 -HIGH_SADNXN4D 32, 32, 2 -HIGH_SADNXN4D 32, 16, 2 -HIGH_SADNXN4D 16, 32, 2 -HIGH_SADNXN4D 16, 16, 2 -HIGH_SADNXN4D 16, 8, 2 -HIGH_SADNXN4D 8, 16, 2 -HIGH_SADNXN4D 8, 8, 2 -HIGH_SADNXN4D 4, 8, 2 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_sad_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_sad_avx2.c deleted file mode 100644 index 78f8eb8b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_sad_avx2.c +++ /dev/null @@ -1,522 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" - -static VPX_FORCE_INLINE unsigned int calc_final(const __m256i sums_32) { - const __m256i t0 = _mm256_add_epi32(sums_32, _mm256_srli_si256(sums_32, 8)); - const __m256i t1 = _mm256_add_epi32(t0, _mm256_srli_si256(t0, 4)); - const __m128i sum = _mm_add_epi32(_mm256_castsi256_si128(t1), - _mm256_extractf128_si256(t1, 1)); - return (unsigned int)_mm_cvtsi128_si32(sum); -} - -static VPX_FORCE_INLINE void highbd_sad64xH(__m256i *sums_16, - const uint16_t *src, int src_stride, - uint16_t *ref, int ref_stride, - int height) { - int i; - for (i = 0; i < height; ++i) { - // load src and all ref[] - const __m256i s0 = _mm256_load_si256((const __m256i *)src); - const __m256i s1 = _mm256_load_si256((const __m256i *)(src + 16)); - const __m256i s2 = _mm256_load_si256((const __m256i *)(src + 32)); - const __m256i s3 = _mm256_load_si256((const __m256i *)(src + 48)); - const __m256i r0 = _mm256_loadu_si256((const __m256i *)ref); - const __m256i r1 = _mm256_loadu_si256((const __m256i *)(ref + 16)); - const __m256i r2 = _mm256_loadu_si256((const __m256i *)(ref + 32)); - const __m256i r3 = _mm256_loadu_si256((const __m256i *)(ref + 48)); - // absolute differences between every ref[] to src - const __m256i abs_diff0 = _mm256_abs_epi16(_mm256_sub_epi16(r0, s0)); - const __m256i abs_diff1 = _mm256_abs_epi16(_mm256_sub_epi16(r1, s1)); - const __m256i abs_diff2 = _mm256_abs_epi16(_mm256_sub_epi16(r2, s2)); - const __m256i abs_diff3 = _mm256_abs_epi16(_mm256_sub_epi16(r3, s3)); - // sum every abs diff - *sums_16 = - _mm256_add_epi16(*sums_16, _mm256_add_epi16(abs_diff0, abs_diff1)); - *sums_16 = - _mm256_add_epi16(*sums_16, _mm256_add_epi16(abs_diff2, abs_diff3)); - - src += src_stride; - ref += ref_stride; - } -} - -static VPX_FORCE_INLINE unsigned int highbd_sad64xN_avx2(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, - int n) { - const uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); - __m256i sums_32 = _mm256_setzero_si256(); - int i; - - for (i = 0; i < (n / 2); ++i) { - __m256i sums_16 = _mm256_setzero_si256(); - - highbd_sad64xH(&sums_16, src, src_stride, ref, ref_stride, 2); - - /* sums_16 will outrange after 2 rows, so add current sums_16 to - * sums_32*/ - sums_32 = _mm256_add_epi32( - sums_32, - _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16)), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16, 1)))); - - src += src_stride << 1; - ref += ref_stride << 1; - } - return calc_final(sums_32); -} - -#define HIGHBD_SAD64XN(n) \ - unsigned int vpx_highbd_sad64x##n##_avx2(const uint8_t *src, int src_stride, \ - const uint8_t *ref, \ - int ref_stride) { \ - return highbd_sad64xN_avx2(src, src_stride, ref, ref_stride, n); \ - } - -#define HIGHBD_SADSKIP64xN(n) \ - unsigned int vpx_highbd_sad_skip_64x##n##_avx2( \ - const uint8_t *src, int src_stride, const uint8_t *ref, \ - int ref_stride) { \ - return 2 * highbd_sad64xN_avx2(src, 2 * src_stride, ref, 2 * ref_stride, \ - n / 2); \ - } - -static VPX_FORCE_INLINE void highbd_sad32xH(__m256i *sums_16, - const uint16_t *src, int src_stride, - uint16_t *ref, int ref_stride, - int height) { - int i; - for (i = 0; i < height; ++i) { - // load src and all ref[] - const __m256i s0 = _mm256_load_si256((const __m256i *)src); - const __m256i s1 = _mm256_load_si256((const __m256i *)(src + 16)); - const __m256i r0 = _mm256_loadu_si256((const __m256i *)ref); - const __m256i r1 = _mm256_loadu_si256((const __m256i *)(ref + 16)); - // absolute differences between every ref[] to src - const __m256i abs_diff0 = _mm256_abs_epi16(_mm256_sub_epi16(r0, s0)); - const __m256i abs_diff1 = _mm256_abs_epi16(_mm256_sub_epi16(r1, s1)); - // sum every abs diff - *sums_16 = _mm256_add_epi16(*sums_16, abs_diff0); - *sums_16 = _mm256_add_epi16(*sums_16, abs_diff1); - - src += src_stride; - ref += ref_stride; - } -} - -static VPX_FORCE_INLINE unsigned int highbd_sad32xN_avx2(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, - int n) { - const uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); - __m256i sums_32 = _mm256_setzero_si256(); - int i; - - for (i = 0; i < (n / 8); ++i) { - __m256i sums_16 = _mm256_setzero_si256(); - - highbd_sad32xH(&sums_16, src, src_stride, ref, ref_stride, 8); - - /* sums_16 will outrange after 8 rows, so add current sums_16 to - * sums_32*/ - sums_32 = _mm256_add_epi32( - sums_32, - _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16)), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16, 1)))); - - src += src_stride << 3; - ref += ref_stride << 3; - } - return calc_final(sums_32); -} - -#define HIGHBD_SAD32XN(n) \ - unsigned int vpx_highbd_sad32x##n##_avx2(const uint8_t *src, int src_stride, \ - const uint8_t *ref, \ - int ref_stride) { \ - return highbd_sad32xN_avx2(src, src_stride, ref, ref_stride, n); \ - } - -#define HIGHBD_SADSKIP32xN(n) \ - unsigned int vpx_highbd_sad_skip_32x##n##_avx2( \ - const uint8_t *src, int src_stride, const uint8_t *ref, \ - int ref_stride) { \ - return 2 * highbd_sad32xN_avx2(src, 2 * src_stride, ref, 2 * ref_stride, \ - n / 2); \ - } - -static VPX_FORCE_INLINE void highbd_sad16xH(__m256i *sums_16, - const uint16_t *src, int src_stride, - uint16_t *ref, int ref_stride, - int height) { - int i; - for (i = 0; i < height; i += 2) { - // load src and all ref[] - const __m256i s0 = _mm256_load_si256((const __m256i *)src); - const __m256i s1 = _mm256_load_si256((const __m256i *)(src + src_stride)); - const __m256i r0 = _mm256_loadu_si256((const __m256i *)ref); - const __m256i r1 = _mm256_loadu_si256((const __m256i *)(ref + ref_stride)); - // absolute differences between every ref[] to src - const __m256i abs_diff0 = _mm256_abs_epi16(_mm256_sub_epi16(r0, s0)); - const __m256i abs_diff1 = _mm256_abs_epi16(_mm256_sub_epi16(r1, s1)); - // sum every abs diff - *sums_16 = _mm256_add_epi16(*sums_16, abs_diff0); - *sums_16 = _mm256_add_epi16(*sums_16, abs_diff1); - - src += src_stride << 1; - ref += ref_stride << 1; - } -} - -static VPX_FORCE_INLINE unsigned int highbd_sad16xN_avx2(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, - int n) { - const uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); - __m256i sums_32 = _mm256_setzero_si256(); - const int height = VPXMIN(16, n); - const int num_iters = n / height; - int i; - - for (i = 0; i < num_iters; ++i) { - __m256i sums_16 = _mm256_setzero_si256(); - - highbd_sad16xH(&sums_16, src, src_stride, ref, ref_stride, height); - - // sums_16 will outrange after 16 rows, so add current sums_16 to sums_32 - sums_32 = _mm256_add_epi32( - sums_32, - _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16)), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16, 1)))); - - src += src_stride << 4; - ref += ref_stride << 4; - } - return calc_final(sums_32); -} - -#define HIGHBD_SAD16XN(n) \ - unsigned int vpx_highbd_sad16x##n##_avx2(const uint8_t *src, int src_stride, \ - const uint8_t *ref, \ - int ref_stride) { \ - return highbd_sad16xN_avx2(src, src_stride, ref, ref_stride, n); \ - } - -#define HIGHBD_SADSKIP16xN(n) \ - unsigned int vpx_highbd_sad_skip_16x##n##_avx2( \ - const uint8_t *src, int src_stride, const uint8_t *ref, \ - int ref_stride) { \ - return 2 * highbd_sad16xN_avx2(src, 2 * src_stride, ref, 2 * ref_stride, \ - n / 2); \ - } - -unsigned int vpx_highbd_sad16x16_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride) { - const uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); - __m256i sums_16 = _mm256_setzero_si256(); - - highbd_sad16xH(&sums_16, src, src_stride, ref, ref_stride, 16); - - { - const __m256i sums_32 = _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16)), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16, 1))); - return calc_final(sums_32); - } -} - -unsigned int vpx_highbd_sad16x8_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride) { - const uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); - __m256i sums_16 = _mm256_setzero_si256(); - - highbd_sad16xH(&sums_16, src, src_stride, ref, ref_stride, 8); - - { - const __m256i sums_32 = _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16)), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16, 1))); - return calc_final(sums_32); - } -} - -// clang-format off -HIGHBD_SAD64XN(64) -HIGHBD_SADSKIP64xN(64) -HIGHBD_SAD64XN(32) -HIGHBD_SADSKIP64xN(32) -HIGHBD_SAD32XN(64) -HIGHBD_SADSKIP32xN(64) -HIGHBD_SAD32XN(32) -HIGHBD_SADSKIP32xN(32) -HIGHBD_SAD32XN(16) -HIGHBD_SADSKIP32xN(16) -HIGHBD_SAD16XN(32) -HIGHBD_SADSKIP16xN(32) -HIGHBD_SADSKIP16xN(16) -HIGHBD_SADSKIP16xN(8) -//clang-format on - -// AVG ------------------------------------------------------------------------- -static VPX_FORCE_INLINE void highbd_sad64xH_avg(__m256i *sums_16, - const uint16_t *src, - int src_stride, uint16_t *ref, - int ref_stride, uint16_t *sec, - int height) { - int i; - for (i = 0; i < height; ++i) { - // load src and all ref[] - const __m256i s0 = _mm256_load_si256((const __m256i *)src); - const __m256i s1 = _mm256_load_si256((const __m256i *)(src + 16)); - const __m256i s2 = _mm256_load_si256((const __m256i *)(src + 32)); - const __m256i s3 = _mm256_load_si256((const __m256i *)(src + 48)); - const __m256i r0 = _mm256_loadu_si256((const __m256i *)ref); - const __m256i r1 = _mm256_loadu_si256((const __m256i *)(ref + 16)); - const __m256i r2 = _mm256_loadu_si256((const __m256i *)(ref + 32)); - const __m256i r3 = _mm256_loadu_si256((const __m256i *)(ref + 48)); - const __m256i x0 = _mm256_loadu_si256((const __m256i *)sec); - const __m256i x1 = _mm256_loadu_si256((const __m256i *)(sec + 16)); - const __m256i x2 = _mm256_loadu_si256((const __m256i *)(sec + 32)); - const __m256i x3 = _mm256_loadu_si256((const __m256i *)(sec + 48)); - const __m256i avg0 = _mm256_avg_epu16(r0, x0); - const __m256i avg1 = _mm256_avg_epu16(r1, x1); - const __m256i avg2 = _mm256_avg_epu16(r2, x2); - const __m256i avg3 = _mm256_avg_epu16(r3, x3); - // absolute differences between every ref/pred avg to src - const __m256i abs_diff0 = _mm256_abs_epi16(_mm256_sub_epi16(avg0, s0)); - const __m256i abs_diff1 = _mm256_abs_epi16(_mm256_sub_epi16(avg1, s1)); - const __m256i abs_diff2 = _mm256_abs_epi16(_mm256_sub_epi16(avg2, s2)); - const __m256i abs_diff3 = _mm256_abs_epi16(_mm256_sub_epi16(avg3, s3)); - // sum every abs diff - *sums_16 = - _mm256_add_epi16(*sums_16, _mm256_add_epi16(abs_diff0, abs_diff1)); - *sums_16 = - _mm256_add_epi16(*sums_16, _mm256_add_epi16(abs_diff2, abs_diff3)); - - src += src_stride; - ref += ref_stride; - sec += 64; - } -} - -#define HIGHBD_SAD64XN_AVG(n) \ - unsigned int vpx_highbd_sad64x##n##_avg_avx2( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, const uint8_t *second_pred) { \ - const uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - uint16_t *sec = CONVERT_TO_SHORTPTR(second_pred); \ - __m256i sums_32 = _mm256_setzero_si256(); \ - int i; \ - \ - for (i = 0; i < (n / 2); ++i) { \ - __m256i sums_16 = _mm256_setzero_si256(); \ - \ - highbd_sad64xH_avg(&sums_16, src, src_stride, ref, ref_stride, sec, 2); \ - \ - /* sums_16 will outrange after 2 rows, so add current sums_16 to \ - * sums_32*/ \ - sums_32 = _mm256_add_epi32( \ - sums_32, \ - _mm256_add_epi32( \ - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16)), \ - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16, 1)))); \ - \ - src += src_stride << 1; \ - ref += ref_stride << 1; \ - sec += 64 << 1; \ - } \ - return calc_final(sums_32); \ - } - -// 64x64 -HIGHBD_SAD64XN_AVG(64) - -// 64x32 -HIGHBD_SAD64XN_AVG(32) - -static VPX_FORCE_INLINE void highbd_sad32xH_avg(__m256i *sums_16, - const uint16_t *src, - int src_stride, uint16_t *ref, - int ref_stride, uint16_t *sec, - int height) { - int i; - for (i = 0; i < height; ++i) { - // load src and all ref[] - const __m256i s0 = _mm256_load_si256((const __m256i *)src); - const __m256i s1 = _mm256_load_si256((const __m256i *)(src + 16)); - const __m256i r0 = _mm256_loadu_si256((const __m256i *)ref); - const __m256i r1 = _mm256_loadu_si256((const __m256i *)(ref + 16)); - const __m256i x0 = _mm256_loadu_si256((const __m256i *)sec); - const __m256i x1 = _mm256_loadu_si256((const __m256i *)(sec + 16)); - const __m256i avg0 = _mm256_avg_epu16(r0, x0); - const __m256i avg1 = _mm256_avg_epu16(r1, x1); - // absolute differences between every ref/pred avg to src - const __m256i abs_diff0 = _mm256_abs_epi16(_mm256_sub_epi16(avg0, s0)); - const __m256i abs_diff1 = _mm256_abs_epi16(_mm256_sub_epi16(avg1, s1)); - // sum every abs diff - *sums_16 = _mm256_add_epi16(*sums_16, abs_diff0); - *sums_16 = _mm256_add_epi16(*sums_16, abs_diff1); - - src += src_stride; - ref += ref_stride; - sec += 32; - } -} - -#define HIGHBD_SAD32XN_AVG(n) \ - unsigned int vpx_highbd_sad32x##n##_avg_avx2( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, const uint8_t *second_pred) { \ - const uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); \ - uint16_t *sec = CONVERT_TO_SHORTPTR(second_pred); \ - __m256i sums_32 = _mm256_setzero_si256(); \ - int i; \ - \ - for (i = 0; i < (n / 8); ++i) { \ - __m256i sums_16 = _mm256_setzero_si256(); \ - \ - highbd_sad32xH_avg(&sums_16, src, src_stride, ref, ref_stride, sec, 8); \ - \ - /* sums_16 will outrange after 8 rows, so add current sums_16 to \ - * sums_32*/ \ - sums_32 = _mm256_add_epi32( \ - sums_32, \ - _mm256_add_epi32( \ - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16)), \ - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16, 1)))); \ - \ - src += src_stride << 3; \ - ref += ref_stride << 3; \ - sec += 32 << 3; \ - } \ - return calc_final(sums_32); \ - } - -// 32x64 -HIGHBD_SAD32XN_AVG(64) - -// 32x32 -HIGHBD_SAD32XN_AVG(32) - -// 32x16 -HIGHBD_SAD32XN_AVG(16) - -static VPX_FORCE_INLINE void highbd_sad16xH_avg(__m256i *sums_16, - const uint16_t *src, - int src_stride, uint16_t *ref, - int ref_stride, uint16_t *sec, - int height) { - int i; - for (i = 0; i < height; i += 2) { - // load src and all ref[] - const __m256i s0 = _mm256_load_si256((const __m256i *)src); - const __m256i s1 = _mm256_load_si256((const __m256i *)(src + src_stride)); - const __m256i r0 = _mm256_loadu_si256((const __m256i *)ref); - const __m256i r1 = _mm256_loadu_si256((const __m256i *)(ref + ref_stride)); - const __m256i x0 = _mm256_loadu_si256((const __m256i *)sec); - const __m256i x1 = _mm256_loadu_si256((const __m256i *)(sec + 16)); - const __m256i avg0 = _mm256_avg_epu16(r0, x0); - const __m256i avg1 = _mm256_avg_epu16(r1, x1); - // absolute differences between every ref[] to src - const __m256i abs_diff0 = _mm256_abs_epi16(_mm256_sub_epi16(avg0, s0)); - const __m256i abs_diff1 = _mm256_abs_epi16(_mm256_sub_epi16(avg1, s1)); - // sum every abs diff - *sums_16 = _mm256_add_epi16(*sums_16, abs_diff0); - *sums_16 = _mm256_add_epi16(*sums_16, abs_diff1); - - src += src_stride << 1; - ref += ref_stride << 1; - sec += 32; - } -} - -unsigned int vpx_highbd_sad16x32_avg_avx2(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, - const uint8_t *second_pred) { - const uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); - uint16_t *sec = CONVERT_TO_SHORTPTR(second_pred); - __m256i sums_32 = _mm256_setzero_si256(); - int i; - - for (i = 0; i < 2; ++i) { - __m256i sums_16 = _mm256_setzero_si256(); - - highbd_sad16xH_avg(&sums_16, src, src_stride, ref, ref_stride, sec, 16); - - // sums_16 will outrange after 16 rows, so add current sums_16 to sums_32 - sums_32 = _mm256_add_epi32( - sums_32, - _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16)), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16, 1)))); - - src += src_stride << 4; - ref += ref_stride << 4; - sec += 16 << 4; - } - return calc_final(sums_32); -} - -unsigned int vpx_highbd_sad16x16_avg_avx2(const uint8_t *src_ptr, - int src_stride, - const uint8_t *ref_ptr, - int ref_stride, - const uint8_t *second_pred) { - const uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); - uint16_t *sec = CONVERT_TO_SHORTPTR(second_pred); - __m256i sums_16 = _mm256_setzero_si256(); - - highbd_sad16xH_avg(&sums_16, src, src_stride, ref, ref_stride, sec, 16); - - { - const __m256i sums_32 = _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16)), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16, 1))); - return calc_final(sums_32); - } -} - -unsigned int vpx_highbd_sad16x8_avg_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - const uint8_t *second_pred) { - const uint16_t *src = CONVERT_TO_SHORTPTR(src_ptr); - uint16_t *ref = CONVERT_TO_SHORTPTR(ref_ptr); - uint16_t *sec = CONVERT_TO_SHORTPTR(second_pred); - __m256i sums_16 = _mm256_setzero_si256(); - - highbd_sad16xH_avg(&sums_16, src, src_stride, ref, ref_stride, sec, 8); - - { - const __m256i sums_32 = _mm256_add_epi32( - _mm256_cvtepu16_epi32(_mm256_castsi256_si128(sums_16)), - _mm256_cvtepu16_epi32(_mm256_extractf128_si256(sums_16, 1))); - return calc_final(sums_32); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_sad_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_sad_sse2.asm deleted file mode 100644 index 62ad2237..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_sad_sse2.asm +++ /dev/null @@ -1,416 +0,0 @@ -; -; Copyright (c) 2014 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "third_party/x86inc/x86inc.asm" - -SECTION .text - -; Macro Arguments -; Arg 1: Width -; Arg 2: Height -; Arg 3: Number of general purpose registers -; Arg 4: Type of function: if 0, normal sad; if 1, avg; if 2, skip rows -%macro HIGH_SAD_FN 4 -%if %4 == 0 -%if %3 == 5 -cglobal highbd_sad%1x%2, 4, %3, 7, src, src_stride, ref, ref_stride, n_rows -%else ; %3 == 7 -cglobal highbd_sad%1x%2, 4, %3, 7, src, src_stride, ref, ref_stride, \ - src_stride3, ref_stride3, n_rows -%endif ; %3 == 5/7 -%elif %4 == 1 ; avg -%if %3 == 5 -cglobal highbd_sad%1x%2_avg, 5, 1 + %3, 7, src, src_stride, ref, ref_stride, \ - second_pred, n_rows -%else ; %3 == 7 -cglobal highbd_sad%1x%2_avg, 5, VPX_ARCH_X86_64 + %3, 7, src, src_stride, \ - ref, ref_stride, \ - second_pred, \ - src_stride3, ref_stride3 -%if VPX_ARCH_X86_64 -%define n_rowsd r7d -%else ; x86-32 -%define n_rowsd dword r0m -%endif ; x86-32/64 -%endif ; %3 == 5/7 -%else ; %4 == 2, skip rows -%if %3 == 5 -cglobal highbd_sad_skip_%1x%2, 4, %3, 7, src, src_stride, ref, ref_stride, n_rows -%else ; %3 == 7 -cglobal highbd_sad_skip_%1x%2, 4, %3, 7, src, src_stride, ref, ref_stride, \ - src_stride3, ref_stride3, n_rows -%endif ; %3 == 5/7 -%endif ; sad/avg/skip -%if %4 == 2 ; double the stride if we are skipping rows - lea src_strided, [src_strided*2] - lea ref_strided, [ref_strided*2] -%endif - movsxdifnidn src_strideq, src_strided - movsxdifnidn ref_strideq, ref_strided -%if %3 == 7 - lea src_stride3q, [src_strideq*3] - lea ref_stride3q, [ref_strideq*3] -%endif ; %3 == 7 -; convert src, ref & second_pred to short ptrs (from byte ptrs) - shl srcq, 1 - shl refq, 1 -%if %4 == 1 - shl second_predq, 1 -%endif -%endmacro - -; unsigned int vpx_highbd_sad64x{16,32,64}_sse2(uint8_t *src, int src_stride, -; uint8_t *ref, int ref_stride); -%macro HIGH_SAD64XN 1-2 0 - HIGH_SAD_FN 64, %1, 5, %2 -%if %2 == 2 ; skip rows, so divide number of rows by 2 - mov n_rowsd, %1/2 -%else - mov n_rowsd, %1 -%endif - pxor m0, m0 - pxor m6, m6 - -.loop: - ; first half of each row - movu m1, [refq] - movu m2, [refq+16] - movu m3, [refq+32] - movu m4, [refq+48] -%if %2 == 1 - pavgw m1, [second_predq+mmsize*0] - pavgw m2, [second_predq+mmsize*1] - pavgw m3, [second_predq+mmsize*2] - pavgw m4, [second_predq+mmsize*3] - lea second_predq, [second_predq+mmsize*4] -%endif - mova m5, [srcq] - psubusw m5, m1 - psubusw m1, [srcq] - por m1, m5 - mova m5, [srcq+16] - psubusw m5, m2 - psubusw m2, [srcq+16] - por m2, m5 - mova m5, [srcq+32] - psubusw m5, m3 - psubusw m3, [srcq+32] - por m3, m5 - mova m5, [srcq+48] - psubusw m5, m4 - psubusw m4, [srcq+48] - por m4, m5 - paddw m1, m2 - paddw m3, m4 - movhlps m2, m1 - movhlps m4, m3 - paddw m1, m2 - paddw m3, m4 - punpcklwd m1, m6 - punpcklwd m3, m6 - paddd m0, m1 - paddd m0, m3 - ; second half of each row - movu m1, [refq+64] - movu m2, [refq+80] - movu m3, [refq+96] - movu m4, [refq+112] -%if %2 == 1 - pavgw m1, [second_predq+mmsize*0] - pavgw m2, [second_predq+mmsize*1] - pavgw m3, [second_predq+mmsize*2] - pavgw m4, [second_predq+mmsize*3] - lea second_predq, [second_predq+mmsize*4] -%endif - mova m5, [srcq+64] - psubusw m5, m1 - psubusw m1, [srcq+64] - por m1, m5 - mova m5, [srcq+80] - psubusw m5, m2 - psubusw m2, [srcq+80] - por m2, m5 - mova m5, [srcq+96] - psubusw m5, m3 - psubusw m3, [srcq+96] - por m3, m5 - mova m5, [srcq+112] - psubusw m5, m4 - psubusw m4, [srcq+112] - por m4, m5 - paddw m1, m2 - paddw m3, m4 - movhlps m2, m1 - movhlps m4, m3 - paddw m1, m2 - paddw m3, m4 - punpcklwd m1, m6 - punpcklwd m3, m6 - lea refq, [refq+ref_strideq*2] - paddd m0, m1 - lea srcq, [srcq+src_strideq*2] - paddd m0, m3 - - dec n_rowsd - jg .loop - - movhlps m1, m0 - paddd m0, m1 - punpckldq m0, m6 - movhlps m1, m0 - paddd m0, m1 -%if %2 == 2 ; we skipped rows, so we need to double the sad - pslld m0, 1 -%endif - movd eax, m0 - RET -%endmacro - -INIT_XMM sse2 -HIGH_SAD64XN 64 ; highbd_sad64x64_sse2 -HIGH_SAD64XN 32 ; highbd_sad64x32_sse2 -HIGH_SAD64XN 64, 1 ; highbd_sad64x64_avg_sse2 -HIGH_SAD64XN 32, 1 ; highbd_sad64x32_avg_sse2 -HIGH_SAD64XN 64, 2 ; highbd_sad_skip_64x64_sse2 -HIGH_SAD64XN 32, 2 ; highbd_sad_skip_64x32_sse2 - - -; unsigned int vpx_highbd_sad32x{16,32,64}_sse2(uint8_t *src, int src_stride, -; uint8_t *ref, int ref_stride); -%macro HIGH_SAD32XN 1-2 0 - HIGH_SAD_FN 32, %1, 5, %2 -%if %2 == 2 ; skip rows, so divide number of rows by 2 - mov n_rowsd, %1/2 -%else - mov n_rowsd, %1 -%endif - pxor m0, m0 - pxor m6, m6 - -.loop: - movu m1, [refq] - movu m2, [refq+16] - movu m3, [refq+32] - movu m4, [refq+48] -%if %2 == 1 - pavgw m1, [second_predq+mmsize*0] - pavgw m2, [second_predq+mmsize*1] - pavgw m3, [second_predq+mmsize*2] - pavgw m4, [second_predq+mmsize*3] - lea second_predq, [second_predq+mmsize*4] -%endif - mova m5, [srcq] - psubusw m5, m1 - psubusw m1, [srcq] - por m1, m5 - mova m5, [srcq+16] - psubusw m5, m2 - psubusw m2, [srcq+16] - por m2, m5 - mova m5, [srcq+32] - psubusw m5, m3 - psubusw m3, [srcq+32] - por m3, m5 - mova m5, [srcq+48] - psubusw m5, m4 - psubusw m4, [srcq+48] - por m4, m5 - paddw m1, m2 - paddw m3, m4 - movhlps m2, m1 - movhlps m4, m3 - paddw m1, m2 - paddw m3, m4 - punpcklwd m1, m6 - punpcklwd m3, m6 - lea refq, [refq+ref_strideq*2] - paddd m0, m1 - lea srcq, [srcq+src_strideq*2] - paddd m0, m3 - dec n_rowsd - jg .loop - - movhlps m1, m0 - paddd m0, m1 - punpckldq m0, m6 - movhlps m1, m0 - paddd m0, m1 -%if %2 == 2 ; we skipped rows, so we need to double the sad - pslld m0, 1 -%endif - movd eax, m0 - RET -%endmacro - -INIT_XMM sse2 -HIGH_SAD32XN 64 ; highbd_sad32x64_sse2 -HIGH_SAD32XN 32 ; highbd_sad32x32_sse2 -HIGH_SAD32XN 16 ; highbd_sad32x16_sse2 -HIGH_SAD32XN 64, 1 ; highbd_sad32x64_avg_sse2 -HIGH_SAD32XN 32, 1 ; highbd_sad32x32_avg_sse2 -HIGH_SAD32XN 16, 1 ; highbd_sad32x16_avg_sse2 -HIGH_SAD32XN 64, 2 ; highbd_sad_skip_32x64_sse2 -HIGH_SAD32XN 32, 2 ; highbd_sad_skip_32x32_sse2 -HIGH_SAD32XN 16, 2 ; highbd_sad_skip_32x16_sse2 - -; unsigned int vpx_highbd_sad16x{8,16,32}_sse2(uint8_t *src, int src_stride, -; uint8_t *ref, int ref_stride); -%macro HIGH_SAD16XN 1-2 0 - HIGH_SAD_FN 16, %1, 5, %2 -%if %2 == 2 ; skip rows, so divide number of rows by 2 - mov n_rowsd, %1/4 -%else - mov n_rowsd, %1/2 -%endif - pxor m0, m0 - pxor m6, m6 - -.loop: - movu m1, [refq] - movu m2, [refq+16] - movu m3, [refq+ref_strideq*2] - movu m4, [refq+ref_strideq*2+16] -%if %2 == 1 - pavgw m1, [second_predq+mmsize*0] - pavgw m2, [second_predq+16] - pavgw m3, [second_predq+mmsize*2] - pavgw m4, [second_predq+mmsize*2+16] - lea second_predq, [second_predq+mmsize*4] -%endif - mova m5, [srcq] - psubusw m5, m1 - psubusw m1, [srcq] - por m1, m5 - mova m5, [srcq+16] - psubusw m5, m2 - psubusw m2, [srcq+16] - por m2, m5 - mova m5, [srcq+src_strideq*2] - psubusw m5, m3 - psubusw m3, [srcq+src_strideq*2] - por m3, m5 - mova m5, [srcq+src_strideq*2+16] - psubusw m5, m4 - psubusw m4, [srcq+src_strideq*2+16] - por m4, m5 - paddw m1, m2 - paddw m3, m4 - movhlps m2, m1 - movhlps m4, m3 - paddw m1, m2 - paddw m3, m4 - punpcklwd m1, m6 - punpcklwd m3, m6 - lea refq, [refq+ref_strideq*4] - paddd m0, m1 - lea srcq, [srcq+src_strideq*4] - paddd m0, m3 - dec n_rowsd - jg .loop - - movhlps m1, m0 - paddd m0, m1 - punpckldq m0, m6 - movhlps m1, m0 - paddd m0, m1 -%if %2 == 2 ; we skipped rows, so we need to double the sad - pslld m0, 1 -%endif - movd eax, m0 - RET -%endmacro - -INIT_XMM sse2 -HIGH_SAD16XN 32 ; highbd_sad16x32_sse2 -HIGH_SAD16XN 16 ; highbd_sad16x16_sse2 -HIGH_SAD16XN 8 ; highbd_sad16x8_sse2 -HIGH_SAD16XN 32, 1 ; highbd_sad16x32_avg_sse2 -HIGH_SAD16XN 16, 1 ; highbd_sad16x16_avg_sse2 -HIGH_SAD16XN 8, 1 ; highbd_sad16x8_avg_sse2 -HIGH_SAD16XN 32, 2 ; highbd_sad_skip_16x32_sse2 -HIGH_SAD16XN 16, 2 ; highbd_sad_skip_16x16_sse2 -HIGH_SAD16XN 8, 2 ; highbd_sad_skip_16x8_sse2 - -; unsigned int vpx_highbd_sad8x{4,8,16}_sse2(uint8_t *src, int src_stride, -; uint8_t *ref, int ref_stride); -%macro HIGH_SAD8XN 1-2 0 - HIGH_SAD_FN 8, %1, 7, %2 -%if %2 == 2 ; skip rows, so divide number of rows by 2 - mov n_rowsd, %1/8 -%else - mov n_rowsd, %1/4 -%endif - pxor m0, m0 - pxor m6, m6 - -.loop: - movu m1, [refq] - movu m2, [refq+ref_strideq*2] - movu m3, [refq+ref_strideq*4] - movu m4, [refq+ref_stride3q*2] -%if %2 == 1 - pavgw m1, [second_predq+mmsize*0] - pavgw m2, [second_predq+mmsize*1] - pavgw m3, [second_predq+mmsize*2] - pavgw m4, [second_predq+mmsize*3] - lea second_predq, [second_predq+mmsize*4] -%endif - mova m5, [srcq] - psubusw m5, m1 - psubusw m1, [srcq] - por m1, m5 - mova m5, [srcq+src_strideq*2] - psubusw m5, m2 - psubusw m2, [srcq+src_strideq*2] - por m2, m5 - mova m5, [srcq+src_strideq*4] - psubusw m5, m3 - psubusw m3, [srcq+src_strideq*4] - por m3, m5 - mova m5, [srcq+src_stride3q*2] - psubusw m5, m4 - psubusw m4, [srcq+src_stride3q*2] - por m4, m5 - paddw m1, m2 - paddw m3, m4 - movhlps m2, m1 - movhlps m4, m3 - paddw m1, m2 - paddw m3, m4 - punpcklwd m1, m6 - punpcklwd m3, m6 - lea refq, [refq+ref_strideq*8] - paddd m0, m1 - lea srcq, [srcq+src_strideq*8] - paddd m0, m3 - dec n_rowsd - jg .loop - - movhlps m1, m0 - paddd m0, m1 - punpckldq m0, m6 - movhlps m1, m0 - paddd m0, m1 -%if %2 == 2 ; we skipped rows, so we need to double the sad - pslld m0, 1 -%endif - movd eax, m0 - RET -%endmacro - -INIT_XMM sse2 -HIGH_SAD8XN 16 ; highbd_sad8x16_sse2 -HIGH_SAD8XN 8 ; highbd_sad8x8_sse2 -HIGH_SAD8XN 4 ; highbd_sad8x4_sse2 -HIGH_SAD8XN 16, 1 ; highbd_sad8x16_avg_sse2 -HIGH_SAD8XN 8, 1 ; highbd_sad8x8_avg_sse2 -HIGH_SAD8XN 4, 1 ; highbd_sad8x4_avg_sse2 -HIGH_SAD8XN 16, 2 ; highbd_sad_skip_8x16_sse2 -HIGH_SAD8XN 8, 2 ; highbd_sad_skip_8x8_sse2 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_subpel_variance_impl_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_subpel_variance_impl_sse2.asm deleted file mode 100644 index 5a3a2818..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_subpel_variance_impl_sse2.asm +++ /dev/null @@ -1,1021 +0,0 @@ -; -; Copyright (c) 2014 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "third_party/x86inc/x86inc.asm" - -SECTION_RODATA -pw_8: times 8 dw 8 -bilin_filter_m_sse2: times 8 dw 16 - times 8 dw 0 - times 8 dw 14 - times 8 dw 2 - times 8 dw 12 - times 8 dw 4 - times 8 dw 10 - times 8 dw 6 - times 16 dw 8 - times 8 dw 6 - times 8 dw 10 - times 8 dw 4 - times 8 dw 12 - times 8 dw 2 - times 8 dw 14 - -SECTION .text - -; int vpx_sub_pixel_varianceNxh(const uint8_t *src, ptrdiff_t src_stride, -; int x_offset, int y_offset, -; const uint8_t *ref, ptrdiff_t ref_stride, -; int height, unsigned int *sse); -; -; This function returns the SE and stores SSE in the given pointer. - -%macro SUM_SSE 6 ; src1, ref1, src2, ref2, sum, sse - psubw %3, %4 - psubw %1, %2 - mova %4, %3 ; make copies to manipulate to calc sum - mova %2, %1 ; use originals for calc sse - pmaddwd %3, %3 - paddw %4, %2 - pmaddwd %1, %1 - movhlps %2, %4 - paddd %6, %3 - paddw %4, %2 - pxor %2, %2 - pcmpgtw %2, %4 ; mask for 0 > %4 (sum) - punpcklwd %4, %2 ; sign-extend word to dword - paddd %6, %1 - paddd %5, %4 - -%endmacro - -%macro STORE_AND_RET 0 -%if mmsize == 16 - ; if H=64 and W=16, we have 8 words of each 2(1bit)x64(6bit)x9bit=16bit - ; in m6, i.e. it _exactly_ fits in a signed word per word in the xmm reg. - ; We have to sign-extend it before adding the words within the register - ; and outputing to a dword. - movhlps m3, m7 - movhlps m4, m6 - paddd m7, m3 - paddd m6, m4 - pshufd m3, m7, 0x1 - pshufd m4, m6, 0x1 - paddd m7, m3 - paddd m6, m4 - mov r1, ssem ; r1 = unsigned int *sse - movd [r1], m7 ; store sse - movd eax, m6 ; store sum as return value -%endif - RET -%endmacro - -%macro INC_SRC_BY_SRC_STRIDE 0 -%if VPX_ARCH_X86=1 && CONFIG_PIC=1 - add srcq, src_stridemp - add srcq, src_stridemp -%else - lea srcq, [srcq + src_strideq*2] -%endif -%endmacro - -%macro SUBPEL_VARIANCE 1-2 0 ; W -%define bilin_filter_m bilin_filter_m_sse2 -%define filter_idx_shift 5 - - -%if VPX_ARCH_X86_64 - %if %2 == 1 ; avg - cglobal highbd_sub_pixel_avg_variance%1xh, 9, 10, 13, src, src_stride, \ - x_offset, y_offset, \ - ref, ref_stride, \ - second_pred, second_stride, height, sse - %define second_str second_strideq - %else - cglobal highbd_sub_pixel_variance%1xh, 7, 8, 13, src, src_stride, \ - x_offset, y_offset, \ - ref, ref_stride, height, sse - %endif - %define block_height heightd - %define bilin_filter sseq -%else - %if CONFIG_PIC=1 - %if %2 == 1 ; avg - cglobal highbd_sub_pixel_avg_variance%1xh, 7, 7, 13, src, src_stride, \ - x_offset, y_offset, \ - ref, ref_stride, \ - second_pred, second_stride, height, sse - %define block_height dword heightm - %define second_str second_stridemp - %else - cglobal highbd_sub_pixel_variance%1xh, 7, 7, 13, src, src_stride, \ - x_offset, y_offset, \ - ref, ref_stride, height, sse - %define block_height heightd - %endif - - ; reuse argument stack space - %define g_bilin_filterm x_offsetm - %define g_pw_8m y_offsetm - - ; Store bilin_filter and pw_8 location in stack - %if GET_GOT_DEFINED == 1 - GET_GOT eax - add esp, 4 ; restore esp - %endif - - lea ecx, [GLOBAL(bilin_filter_m)] - mov g_bilin_filterm, ecx - - lea ecx, [GLOBAL(pw_8)] - mov g_pw_8m, ecx - - LOAD_IF_USED 0, 1 ; load eax, ecx back - %else - %if %2 == 1 ; avg - cglobal highbd_sub_pixel_avg_variance%1xh, 7, 7, 13, src, src_stride, \ - x_offset, y_offset, \ - ref, ref_stride, \ - second_pred, second_stride, height, sse - %define block_height dword heightm - %define second_str second_stridemp - %else - cglobal highbd_sub_pixel_variance%1xh, 7, 7, 13, src, src_stride, \ - x_offset, y_offset, \ - ref, ref_stride, height, sse - %define block_height heightd - %endif - - %define bilin_filter bilin_filter_m - %endif -%endif - - ASSERT %1 <= 16 ; m6 overflows if w > 16 - pxor m6, m6 ; sum - pxor m7, m7 ; sse - -%if %1 < 16 - sar block_height, 1 -%endif -%if %2 == 1 ; avg - shl second_str, 1 -%endif - - ; FIXME(rbultje) replace by jumptable? - test x_offsetd, x_offsetd - jnz .x_nonzero - ; x_offset == 0 - test y_offsetd, y_offsetd - jnz .x_zero_y_nonzero - - ; x_offset == 0 && y_offset == 0 -.x_zero_y_zero_loop: -%if %1 == 16 - movu m0, [srcq] - movu m2, [srcq + 16] - mova m1, [refq] - mova m3, [refq + 16] -%if %2 == 1 ; avg - pavgw m0, [second_predq] - pavgw m2, [second_predq+16] -%endif - SUM_SSE m0, m1, m2, m3, m6, m7 - - lea srcq, [srcq + src_strideq*2] - lea refq, [refq + ref_strideq*2] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%else ; %1 < 16 - movu m0, [srcq] - movu m2, [srcq + src_strideq*2] - mova m1, [refq] - mova m3, [refq + ref_strideq*2] -%if %2 == 1 ; avg - pavgw m0, [second_predq] - add second_predq, second_str - pavgw m2, [second_predq] -%endif - SUM_SSE m0, m1, m2, m3, m6, m7 - - lea srcq, [srcq + src_strideq*4] - lea refq, [refq + ref_strideq*4] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%endif - dec block_height - jg .x_zero_y_zero_loop - STORE_AND_RET - -.x_zero_y_nonzero: - cmp y_offsetd, 8 - jne .x_zero_y_nonhalf - - ; x_offset == 0 && y_offset == 0.5 -.x_zero_y_half_loop: -%if %1 == 16 - movu m0, [srcq] - movu m1, [srcq+16] - movu m4, [srcq+src_strideq*2] - movu m5, [srcq+src_strideq*2+16] - mova m2, [refq] - mova m3, [refq+16] - pavgw m0, m4 - pavgw m1, m5 -%if %2 == 1 ; avg - pavgw m0, [second_predq] - pavgw m1, [second_predq+16] -%endif - SUM_SSE m0, m2, m1, m3, m6, m7 - - lea srcq, [srcq + src_strideq*2] - lea refq, [refq + ref_strideq*2] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%else ; %1 < 16 - movu m0, [srcq] - movu m1, [srcq+src_strideq*2] - movu m5, [srcq+src_strideq*4] - mova m2, [refq] - mova m3, [refq+ref_strideq*2] - pavgw m0, m1 - pavgw m1, m5 -%if %2 == 1 ; avg - pavgw m0, [second_predq] - add second_predq, second_str - pavgw m1, [second_predq] -%endif - SUM_SSE m0, m2, m1, m3, m6, m7 - - lea srcq, [srcq + src_strideq*4] - lea refq, [refq + ref_strideq*4] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%endif - dec block_height - jg .x_zero_y_half_loop - STORE_AND_RET - -.x_zero_y_nonhalf: - ; x_offset == 0 && y_offset == bilin interpolation -%if VPX_ARCH_X86_64 - lea bilin_filter, [GLOBAL(bilin_filter_m)] -%endif - shl y_offsetd, filter_idx_shift -%if VPX_ARCH_X86_64 && mmsize == 16 - mova m8, [bilin_filter+y_offsetq] - mova m9, [bilin_filter+y_offsetq+16] - mova m10, [GLOBAL(pw_8)] -%define filter_y_a m8 -%define filter_y_b m9 -%define filter_rnd m10 -%else ; x86-32 or mmx -%if VPX_ARCH_X86=1 && CONFIG_PIC=1 -; x_offset == 0, reuse x_offset reg -%define tempq x_offsetq - add y_offsetq, g_bilin_filterm -%define filter_y_a [y_offsetq] -%define filter_y_b [y_offsetq+16] - mov tempq, g_pw_8m -%define filter_rnd [tempq] -%else - add y_offsetq, bilin_filter -%define filter_y_a [y_offsetq] -%define filter_y_b [y_offsetq+16] -%define filter_rnd [GLOBAL(pw_8)] -%endif -%endif - -.x_zero_y_other_loop: -%if %1 == 16 - movu m0, [srcq] - movu m1, [srcq + 16] - movu m4, [srcq+src_strideq*2] - movu m5, [srcq+src_strideq*2+16] - mova m2, [refq] - mova m3, [refq+16] - ; FIXME(rbultje) instead of out=((num-x)*in1+x*in2+rnd)>>log2(num), we can - ; also do out=in1+(((num-x)*(in2-in1)+rnd)>>log2(num)). Total number of - ; instructions is the same (5), but it is 1 mul instead of 2, so might be - ; slightly faster because of pmullw latency. It would also cut our rodata - ; tables in half for this function, and save 1-2 registers on x86-64. - pmullw m1, filter_y_a - pmullw m5, filter_y_b - paddw m1, filter_rnd - pmullw m0, filter_y_a - pmullw m4, filter_y_b - paddw m0, filter_rnd - paddw m1, m5 - paddw m0, m4 - psrlw m1, 4 - psrlw m0, 4 -%if %2 == 1 ; avg - pavgw m0, [second_predq] - pavgw m1, [second_predq+16] -%endif - SUM_SSE m0, m2, m1, m3, m6, m7 - - lea srcq, [srcq + src_strideq*2] - lea refq, [refq + ref_strideq*2] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%else ; %1 < 16 - movu m0, [srcq] - movu m1, [srcq+src_strideq*2] - movu m5, [srcq+src_strideq*4] - mova m4, m1 - mova m2, [refq] - mova m3, [refq+ref_strideq*2] - pmullw m1, filter_y_a - pmullw m5, filter_y_b - paddw m1, filter_rnd - pmullw m0, filter_y_a - pmullw m4, filter_y_b - paddw m0, filter_rnd - paddw m1, m5 - paddw m0, m4 - psrlw m1, 4 - psrlw m0, 4 -%if %2 == 1 ; avg - pavgw m0, [second_predq] - add second_predq, second_str - pavgw m1, [second_predq] -%endif - SUM_SSE m0, m2, m1, m3, m6, m7 - - lea srcq, [srcq + src_strideq*4] - lea refq, [refq + ref_strideq*4] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%endif - dec block_height - jg .x_zero_y_other_loop -%undef filter_y_a -%undef filter_y_b -%undef filter_rnd - STORE_AND_RET - -.x_nonzero: - cmp x_offsetd, 8 - jne .x_nonhalf - ; x_offset == 0.5 - test y_offsetd, y_offsetd - jnz .x_half_y_nonzero - - ; x_offset == 0.5 && y_offset == 0 -.x_half_y_zero_loop: -%if %1 == 16 - movu m0, [srcq] - movu m1, [srcq + 16] - movu m4, [srcq + 2] - movu m5, [srcq + 18] - mova m2, [refq] - mova m3, [refq + 16] - pavgw m0, m4 - pavgw m1, m5 -%if %2 == 1 ; avg - pavgw m0, [second_predq] - pavgw m1, [second_predq+16] -%endif - SUM_SSE m0, m2, m1, m3, m6, m7 - - lea srcq, [srcq + src_strideq*2] - lea refq, [refq + ref_strideq*2] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%else ; %1 < 16 - movu m0, [srcq] - movu m1, [srcq + src_strideq*2] - movu m4, [srcq + 2] - movu m5, [srcq + src_strideq*2 + 2] - mova m2, [refq] - mova m3, [refq + ref_strideq*2] - pavgw m0, m4 - pavgw m1, m5 -%if %2 == 1 ; avg - pavgw m0, [second_predq] - add second_predq, second_str - pavgw m1, [second_predq] -%endif - SUM_SSE m0, m2, m1, m3, m6, m7 - - lea srcq, [srcq + src_strideq*4] - lea refq, [refq + ref_strideq*4] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%endif - dec block_height - jg .x_half_y_zero_loop - STORE_AND_RET - -.x_half_y_nonzero: - cmp y_offsetd, 8 - jne .x_half_y_nonhalf - - ; x_offset == 0.5 && y_offset == 0.5 -%if %1 == 16 - movu m0, [srcq] - movu m1, [srcq+16] - movu m2, [srcq+2] - movu m3, [srcq+18] - lea srcq, [srcq + src_strideq*2] - pavgw m0, m2 - pavgw m1, m3 -.x_half_y_half_loop: - movu m2, [srcq] - movu m3, [srcq + 16] - movu m4, [srcq + 2] - movu m5, [srcq + 18] - pavgw m2, m4 - pavgw m3, m5 - pavgw m0, m2 - pavgw m1, m3 - mova m4, [refq] - mova m5, [refq + 16] -%if %2 == 1 ; avg - pavgw m0, [second_predq] - pavgw m1, [second_predq+16] -%endif - SUM_SSE m0, m4, m1, m5, m6, m7 - mova m0, m2 - mova m1, m3 - - lea srcq, [srcq + src_strideq*2] - lea refq, [refq + ref_strideq*2] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%else ; %1 < 16 - movu m0, [srcq] - movu m2, [srcq+2] - lea srcq, [srcq + src_strideq*2] - pavgw m0, m2 -.x_half_y_half_loop: - movu m2, [srcq] - movu m3, [srcq + src_strideq*2] - movu m4, [srcq + 2] - movu m5, [srcq + src_strideq*2 + 2] - pavgw m2, m4 - pavgw m3, m5 - pavgw m0, m2 - pavgw m2, m3 - mova m4, [refq] - mova m5, [refq + ref_strideq*2] -%if %2 == 1 ; avg - pavgw m0, [second_predq] - add second_predq, second_str - pavgw m2, [second_predq] -%endif - SUM_SSE m0, m4, m2, m5, m6, m7 - mova m0, m3 - - lea srcq, [srcq + src_strideq*4] - lea refq, [refq + ref_strideq*4] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%endif - dec block_height - jg .x_half_y_half_loop - STORE_AND_RET - -.x_half_y_nonhalf: - ; x_offset == 0.5 && y_offset == bilin interpolation -%if VPX_ARCH_X86_64 - lea bilin_filter, [GLOBAL(bilin_filter_m)] -%endif - shl y_offsetd, filter_idx_shift -%if VPX_ARCH_X86_64 && mmsize == 16 - mova m8, [bilin_filter+y_offsetq] - mova m9, [bilin_filter+y_offsetq+16] - mova m10, [GLOBAL(pw_8)] -%define filter_y_a m8 -%define filter_y_b m9 -%define filter_rnd m10 -%else ; x86_32 -%if VPX_ARCH_X86=1 && CONFIG_PIC=1 -; x_offset == 0.5. We can reuse x_offset reg -%define tempq x_offsetq - add y_offsetq, g_bilin_filterm -%define filter_y_a [y_offsetq] -%define filter_y_b [y_offsetq+16] - mov tempq, g_pw_8m -%define filter_rnd [tempq] -%else - add y_offsetq, bilin_filter -%define filter_y_a [y_offsetq] -%define filter_y_b [y_offsetq+16] -%define filter_rnd [GLOBAL(pw_8)] -%endif -%endif - -%if %1 == 16 - movu m0, [srcq] - movu m1, [srcq+16] - movu m2, [srcq+2] - movu m3, [srcq+18] - lea srcq, [srcq + src_strideq*2] - pavgw m0, m2 - pavgw m1, m3 -.x_half_y_other_loop: - movu m2, [srcq] - movu m3, [srcq+16] - movu m4, [srcq+2] - movu m5, [srcq+18] - pavgw m2, m4 - pavgw m3, m5 - mova m4, m2 - mova m5, m3 - pmullw m1, filter_y_a - pmullw m3, filter_y_b - paddw m1, filter_rnd - paddw m1, m3 - pmullw m0, filter_y_a - pmullw m2, filter_y_b - paddw m0, filter_rnd - psrlw m1, 4 - paddw m0, m2 - mova m2, [refq] - psrlw m0, 4 - mova m3, [refq+16] -%if %2 == 1 ; avg - pavgw m0, [second_predq] - pavgw m1, [second_predq+16] -%endif - SUM_SSE m0, m2, m1, m3, m6, m7 - mova m0, m4 - mova m1, m5 - - lea srcq, [srcq + src_strideq*2] - lea refq, [refq + ref_strideq*2] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%else ; %1 < 16 - movu m0, [srcq] - movu m2, [srcq+2] - lea srcq, [srcq + src_strideq*2] - pavgw m0, m2 -.x_half_y_other_loop: - movu m2, [srcq] - movu m3, [srcq+src_strideq*2] - movu m4, [srcq+2] - movu m5, [srcq+src_strideq*2+2] - pavgw m2, m4 - pavgw m3, m5 - mova m4, m2 - mova m5, m3 - pmullw m4, filter_y_a - pmullw m3, filter_y_b - paddw m4, filter_rnd - paddw m4, m3 - pmullw m0, filter_y_a - pmullw m2, filter_y_b - paddw m0, filter_rnd - psrlw m4, 4 - paddw m0, m2 - mova m2, [refq] - psrlw m0, 4 - mova m3, [refq+ref_strideq*2] -%if %2 == 1 ; avg - pavgw m0, [second_predq] - add second_predq, second_str - pavgw m4, [second_predq] -%endif - SUM_SSE m0, m2, m4, m3, m6, m7 - mova m0, m5 - - lea srcq, [srcq + src_strideq*4] - lea refq, [refq + ref_strideq*4] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%endif - dec block_height - jg .x_half_y_other_loop -%undef filter_y_a -%undef filter_y_b -%undef filter_rnd - STORE_AND_RET - -.x_nonhalf: - test y_offsetd, y_offsetd - jnz .x_nonhalf_y_nonzero - - ; x_offset == bilin interpolation && y_offset == 0 -%if VPX_ARCH_X86_64 - lea bilin_filter, [GLOBAL(bilin_filter_m)] -%endif - shl x_offsetd, filter_idx_shift -%if VPX_ARCH_X86_64 && mmsize == 16 - mova m8, [bilin_filter+x_offsetq] - mova m9, [bilin_filter+x_offsetq+16] - mova m10, [GLOBAL(pw_8)] -%define filter_x_a m8 -%define filter_x_b m9 -%define filter_rnd m10 -%else ; x86-32 -%if VPX_ARCH_X86=1 && CONFIG_PIC=1 -; y_offset == 0. We can reuse y_offset reg. -%define tempq y_offsetq - add x_offsetq, g_bilin_filterm -%define filter_x_a [x_offsetq] -%define filter_x_b [x_offsetq+16] - mov tempq, g_pw_8m -%define filter_rnd [tempq] -%else - add x_offsetq, bilin_filter -%define filter_x_a [x_offsetq] -%define filter_x_b [x_offsetq+16] -%define filter_rnd [GLOBAL(pw_8)] -%endif -%endif - -.x_other_y_zero_loop: -%if %1 == 16 - movu m0, [srcq] - movu m1, [srcq+16] - movu m2, [srcq+2] - movu m3, [srcq+18] - mova m4, [refq] - mova m5, [refq+16] - pmullw m1, filter_x_a - pmullw m3, filter_x_b - paddw m1, filter_rnd - pmullw m0, filter_x_a - pmullw m2, filter_x_b - paddw m0, filter_rnd - paddw m1, m3 - paddw m0, m2 - psrlw m1, 4 - psrlw m0, 4 -%if %2 == 1 ; avg - pavgw m0, [second_predq] - pavgw m1, [second_predq+16] -%endif - SUM_SSE m0, m4, m1, m5, m6, m7 - - lea srcq, [srcq+src_strideq*2] - lea refq, [refq+ref_strideq*2] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%else ; %1 < 16 - movu m0, [srcq] - movu m1, [srcq+src_strideq*2] - movu m2, [srcq+2] - movu m3, [srcq+src_strideq*2+2] - mova m4, [refq] - mova m5, [refq+ref_strideq*2] - pmullw m1, filter_x_a - pmullw m3, filter_x_b - paddw m1, filter_rnd - pmullw m0, filter_x_a - pmullw m2, filter_x_b - paddw m0, filter_rnd - paddw m1, m3 - paddw m0, m2 - psrlw m1, 4 - psrlw m0, 4 -%if %2 == 1 ; avg - pavgw m0, [second_predq] - add second_predq, second_str - pavgw m1, [second_predq] -%endif - SUM_SSE m0, m4, m1, m5, m6, m7 - - lea srcq, [srcq+src_strideq*4] - lea refq, [refq+ref_strideq*4] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%endif - dec block_height - jg .x_other_y_zero_loop -%undef filter_x_a -%undef filter_x_b -%undef filter_rnd - STORE_AND_RET - -.x_nonhalf_y_nonzero: - cmp y_offsetd, 8 - jne .x_nonhalf_y_nonhalf - - ; x_offset == bilin interpolation && y_offset == 0.5 -%if VPX_ARCH_X86_64 - lea bilin_filter, [GLOBAL(bilin_filter_m)] -%endif - shl x_offsetd, filter_idx_shift -%if VPX_ARCH_X86_64 && mmsize == 16 - mova m8, [bilin_filter+x_offsetq] - mova m9, [bilin_filter+x_offsetq+16] - mova m10, [GLOBAL(pw_8)] -%define filter_x_a m8 -%define filter_x_b m9 -%define filter_rnd m10 -%else ; x86-32 -%if VPX_ARCH_X86=1 && CONFIG_PIC=1 -; y_offset == 0.5. We can reuse y_offset reg. -%define tempq y_offsetq - add x_offsetq, g_bilin_filterm -%define filter_x_a [x_offsetq] -%define filter_x_b [x_offsetq+16] - mov tempq, g_pw_8m -%define filter_rnd [tempq] -%else - add x_offsetq, bilin_filter -%define filter_x_a [x_offsetq] -%define filter_x_b [x_offsetq+16] -%define filter_rnd [GLOBAL(pw_8)] -%endif -%endif - -%if %1 == 16 - movu m0, [srcq] - movu m1, [srcq+16] - movu m2, [srcq+2] - movu m3, [srcq+18] - pmullw m0, filter_x_a - pmullw m2, filter_x_b - paddw m0, filter_rnd - pmullw m1, filter_x_a - pmullw m3, filter_x_b - paddw m1, filter_rnd - paddw m0, m2 - paddw m1, m3 - psrlw m0, 4 - psrlw m1, 4 - lea srcq, [srcq+src_strideq*2] -.x_other_y_half_loop: - movu m2, [srcq] - movu m3, [srcq+16] - movu m4, [srcq+2] - movu m5, [srcq+18] - pmullw m2, filter_x_a - pmullw m4, filter_x_b - paddw m2, filter_rnd - pmullw m3, filter_x_a - pmullw m5, filter_x_b - paddw m3, filter_rnd - paddw m2, m4 - paddw m3, m5 - mova m4, [refq] - mova m5, [refq+16] - psrlw m2, 4 - psrlw m3, 4 - pavgw m0, m2 - pavgw m1, m3 -%if %2 == 1 ; avg - pavgw m0, [second_predq] - pavgw m1, [second_predq+16] -%endif - SUM_SSE m0, m4, m1, m5, m6, m7 - mova m0, m2 - mova m1, m3 - - lea srcq, [srcq+src_strideq*2] - lea refq, [refq+ref_strideq*2] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%else ; %1 < 16 - movu m0, [srcq] - movu m2, [srcq+2] - pmullw m0, filter_x_a - pmullw m2, filter_x_b - paddw m0, filter_rnd - paddw m0, m2 - psrlw m0, 4 - lea srcq, [srcq+src_strideq*2] -.x_other_y_half_loop: - movu m2, [srcq] - movu m3, [srcq+src_strideq*2] - movu m4, [srcq+2] - movu m5, [srcq+src_strideq*2+2] - pmullw m2, filter_x_a - pmullw m4, filter_x_b - paddw m2, filter_rnd - pmullw m3, filter_x_a - pmullw m5, filter_x_b - paddw m3, filter_rnd - paddw m2, m4 - paddw m3, m5 - mova m4, [refq] - mova m5, [refq+ref_strideq*2] - psrlw m2, 4 - psrlw m3, 4 - pavgw m0, m2 - pavgw m2, m3 -%if %2 == 1 ; avg - pavgw m0, [second_predq] - add second_predq, second_str - pavgw m2, [second_predq] -%endif - SUM_SSE m0, m4, m2, m5, m6, m7 - mova m0, m3 - - lea srcq, [srcq+src_strideq*4] - lea refq, [refq+ref_strideq*4] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%endif - dec block_height - jg .x_other_y_half_loop -%undef filter_x_a -%undef filter_x_b -%undef filter_rnd - STORE_AND_RET - -.x_nonhalf_y_nonhalf: -; loading filter - this is same as in 8-bit depth -%if VPX_ARCH_X86_64 - lea bilin_filter, [GLOBAL(bilin_filter_m)] -%endif - shl x_offsetd, filter_idx_shift ; filter_idx_shift = 5 - shl y_offsetd, filter_idx_shift -%if VPX_ARCH_X86_64 && mmsize == 16 - mova m8, [bilin_filter+x_offsetq] - mova m9, [bilin_filter+x_offsetq+16] - mova m10, [bilin_filter+y_offsetq] - mova m11, [bilin_filter+y_offsetq+16] - mova m12, [GLOBAL(pw_8)] -%define filter_x_a m8 -%define filter_x_b m9 -%define filter_y_a m10 -%define filter_y_b m11 -%define filter_rnd m12 -%else ; x86-32 -%if VPX_ARCH_X86=1 && CONFIG_PIC=1 -; In this case, there is NO unused register. Used src_stride register. Later, -; src_stride has to be loaded from stack when it is needed. -%define tempq src_strideq - mov tempq, g_bilin_filterm - add x_offsetq, tempq - add y_offsetq, tempq -%define filter_x_a [x_offsetq] -%define filter_x_b [x_offsetq+16] -%define filter_y_a [y_offsetq] -%define filter_y_b [y_offsetq+16] - - mov tempq, g_pw_8m -%define filter_rnd [tempq] -%else - add x_offsetq, bilin_filter - add y_offsetq, bilin_filter -%define filter_x_a [x_offsetq] -%define filter_x_b [x_offsetq+16] -%define filter_y_a [y_offsetq] -%define filter_y_b [y_offsetq+16] -%define filter_rnd [GLOBAL(pw_8)] -%endif -%endif -; end of load filter - - ; x_offset == bilin interpolation && y_offset == bilin interpolation -%if %1 == 16 - movu m0, [srcq] - movu m2, [srcq+2] - movu m1, [srcq+16] - movu m3, [srcq+18] - pmullw m0, filter_x_a - pmullw m2, filter_x_b - paddw m0, filter_rnd - pmullw m1, filter_x_a - pmullw m3, filter_x_b - paddw m1, filter_rnd - paddw m0, m2 - paddw m1, m3 - psrlw m0, 4 - psrlw m1, 4 - - INC_SRC_BY_SRC_STRIDE - -.x_other_y_other_loop: - movu m2, [srcq] - movu m4, [srcq+2] - movu m3, [srcq+16] - movu m5, [srcq+18] - pmullw m2, filter_x_a - pmullw m4, filter_x_b - paddw m2, filter_rnd - pmullw m3, filter_x_a - pmullw m5, filter_x_b - paddw m3, filter_rnd - paddw m2, m4 - paddw m3, m5 - psrlw m2, 4 - psrlw m3, 4 - mova m4, m2 - mova m5, m3 - pmullw m0, filter_y_a - pmullw m2, filter_y_b - paddw m0, filter_rnd - pmullw m1, filter_y_a - pmullw m3, filter_y_b - paddw m0, m2 - paddw m1, filter_rnd - mova m2, [refq] - paddw m1, m3 - psrlw m0, 4 - psrlw m1, 4 - mova m3, [refq+16] -%if %2 == 1 ; avg - pavgw m0, [second_predq] - pavgw m1, [second_predq+16] -%endif - SUM_SSE m0, m2, m1, m3, m6, m7 - mova m0, m4 - mova m1, m5 - - INC_SRC_BY_SRC_STRIDE - lea refq, [refq + ref_strideq * 2] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%else ; %1 < 16 - movu m0, [srcq] - movu m2, [srcq+2] - pmullw m0, filter_x_a - pmullw m2, filter_x_b - paddw m0, filter_rnd - paddw m0, m2 - psrlw m0, 4 - - INC_SRC_BY_SRC_STRIDE - -.x_other_y_other_loop: - movu m2, [srcq] - movu m4, [srcq+2] - INC_SRC_BY_SRC_STRIDE - movu m3, [srcq] - movu m5, [srcq+2] - pmullw m2, filter_x_a - pmullw m4, filter_x_b - paddw m2, filter_rnd - pmullw m3, filter_x_a - pmullw m5, filter_x_b - paddw m3, filter_rnd - paddw m2, m4 - paddw m3, m5 - psrlw m2, 4 - psrlw m3, 4 - mova m4, m2 - mova m5, m3 - pmullw m0, filter_y_a - pmullw m2, filter_y_b - paddw m0, filter_rnd - pmullw m4, filter_y_a - pmullw m3, filter_y_b - paddw m0, m2 - paddw m4, filter_rnd - mova m2, [refq] - paddw m4, m3 - psrlw m0, 4 - psrlw m4, 4 - mova m3, [refq+ref_strideq*2] -%if %2 == 1 ; avg - pavgw m0, [second_predq] - add second_predq, second_str - pavgw m4, [second_predq] -%endif - SUM_SSE m0, m2, m4, m3, m6, m7 - mova m0, m5 - - INC_SRC_BY_SRC_STRIDE - lea refq, [refq + ref_strideq * 4] -%if %2 == 1 ; avg - add second_predq, second_str -%endif -%endif - dec block_height - jg .x_other_y_other_loop -%undef filter_x_a -%undef filter_x_b -%undef filter_y_a -%undef filter_y_b -%undef filter_rnd - STORE_AND_RET -%endmacro - -INIT_XMM sse2 -SUBPEL_VARIANCE 8 -SUBPEL_VARIANCE 16 - -INIT_XMM sse2 -SUBPEL_VARIANCE 8, 1 -SUBPEL_VARIANCE 16, 1 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_variance_impl_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_variance_impl_sse2.asm deleted file mode 100644 index 5bee51fa..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_variance_impl_sse2.asm +++ /dev/null @@ -1,315 +0,0 @@ -; -; Copyright (c) 2014 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -SECTION .text - -;unsigned int vpx_highbd_calc16x16var_sse2 -;( -; unsigned char * src_ptr, -; int src_stride, -; unsigned char * ref_ptr, -; int ref_stride, -; unsigned int * SSE, -; int * Sum -;) -globalsym(vpx_highbd_calc16x16var_sse2) -sym(vpx_highbd_calc16x16var_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rbx - push rsi - push rdi - ; end prolog - - mov rsi, arg(0) ;[src_ptr] - mov rdi, arg(2) ;[ref_ptr] - - movsxd rax, DWORD PTR arg(1) ;[src_stride] - movsxd rdx, DWORD PTR arg(3) ;[ref_stride] - add rax, rax ; source stride in bytes - add rdx, rdx ; recon stride in bytes - - ; Prefetch data - prefetcht0 [rsi] - prefetcht0 [rsi+16] - prefetcht0 [rsi+rax] - prefetcht0 [rsi+rax+16] - lea rbx, [rsi+rax*2] - prefetcht0 [rbx] - prefetcht0 [rbx+16] - prefetcht0 [rbx+rax] - prefetcht0 [rbx+rax+16] - - prefetcht0 [rdi] - prefetcht0 [rdi+16] - prefetcht0 [rdi+rdx] - prefetcht0 [rdi+rdx+16] - lea rbx, [rdi+rdx*2] - prefetcht0 [rbx] - prefetcht0 [rbx+16] - prefetcht0 [rbx+rdx] - prefetcht0 [rbx+rdx+16] - - pxor xmm0, xmm0 ; clear xmm0 for unpack - pxor xmm7, xmm7 ; clear xmm7 for accumulating diffs - - pxor xmm6, xmm6 ; clear xmm6 for accumulating sse - mov rcx, 16 - -.var16loop: - movdqu xmm1, XMMWORD PTR [rsi] - movdqu xmm2, XMMWORD PTR [rdi] - - lea rbx, [rsi+rax*2] - prefetcht0 [rbx] - prefetcht0 [rbx+16] - prefetcht0 [rbx+rax] - prefetcht0 [rbx+rax+16] - lea rbx, [rdi+rdx*2] - prefetcht0 [rbx] - prefetcht0 [rbx+16] - prefetcht0 [rbx+rdx] - prefetcht0 [rbx+rdx+16] - - pxor xmm5, xmm5 - - psubw xmm1, xmm2 - movdqu xmm3, XMMWORD PTR [rsi+16] - paddw xmm5, xmm1 - pmaddwd xmm1, xmm1 - movdqu xmm2, XMMWORD PTR [rdi+16] - paddd xmm6, xmm1 - - psubw xmm3, xmm2 - movdqu xmm1, XMMWORD PTR [rsi+rax] - paddw xmm5, xmm3 - pmaddwd xmm3, xmm3 - movdqu xmm2, XMMWORD PTR [rdi+rdx] - paddd xmm6, xmm3 - - psubw xmm1, xmm2 - movdqu xmm3, XMMWORD PTR [rsi+rax+16] - paddw xmm5, xmm1 - pmaddwd xmm1, xmm1 - movdqu xmm2, XMMWORD PTR [rdi+rdx+16] - paddd xmm6, xmm1 - - psubw xmm3, xmm2 - paddw xmm5, xmm3 - pmaddwd xmm3, xmm3 - paddd xmm6, xmm3 - - movdqa xmm1, xmm5 - movdqa xmm2, xmm5 - pcmpgtw xmm1, xmm0 - pcmpeqw xmm2, xmm0 - por xmm1, xmm2 - pcmpeqw xmm1, xmm0 - movdqa xmm2, xmm5 - punpcklwd xmm5, xmm1 - punpckhwd xmm2, xmm1 - paddd xmm7, xmm5 - paddd xmm7, xmm2 - - lea rsi, [rsi + 2*rax] - lea rdi, [rdi + 2*rdx] - sub rcx, 2 - jnz .var16loop - - movdqa xmm4, xmm6 - punpckldq xmm6, xmm0 - - punpckhdq xmm4, xmm0 - movdqa xmm5, xmm7 - - paddd xmm6, xmm4 - punpckldq xmm7, xmm0 - - punpckhdq xmm5, xmm0 - paddd xmm7, xmm5 - - movdqa xmm4, xmm6 - movdqa xmm5, xmm7 - - psrldq xmm4, 8 - psrldq xmm5, 8 - - paddd xmm6, xmm4 - paddd xmm7, xmm5 - - mov rdi, arg(4) ; [SSE] - mov rax, arg(5) ; [Sum] - - movd DWORD PTR [rdi], xmm6 - movd DWORD PTR [rax], xmm7 - - - ; begin epilog - pop rdi - pop rsi - pop rbx - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - - -;unsigned int vpx_highbd_calc8x8var_sse2 -;( -; unsigned char * src_ptr, -; int src_stride, -; unsigned char * ref_ptr, -; int ref_stride, -; unsigned int * SSE, -; int * Sum -;) -globalsym(vpx_highbd_calc8x8var_sse2) -sym(vpx_highbd_calc8x8var_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rbx - push rsi - push rdi - ; end prolog - - mov rsi, arg(0) ;[src_ptr] - mov rdi, arg(2) ;[ref_ptr] - - movsxd rax, DWORD PTR arg(1) ;[src_stride] - movsxd rdx, DWORD PTR arg(3) ;[ref_stride] - add rax, rax ; source stride in bytes - add rdx, rdx ; recon stride in bytes - - ; Prefetch data - prefetcht0 [rsi] - prefetcht0 [rsi+rax] - lea rbx, [rsi+rax*2] - prefetcht0 [rbx] - prefetcht0 [rbx+rax] - - prefetcht0 [rdi] - prefetcht0 [rdi+rdx] - lea rbx, [rdi+rdx*2] - prefetcht0 [rbx] - prefetcht0 [rbx+rdx] - - pxor xmm0, xmm0 ; clear xmm0 for unpack - pxor xmm7, xmm7 ; clear xmm7 for accumulating diffs - - pxor xmm6, xmm6 ; clear xmm6 for accumulating sse - mov rcx, 8 - -.var8loop: - movdqu xmm1, XMMWORD PTR [rsi] - movdqu xmm2, XMMWORD PTR [rdi] - - lea rbx, [rsi+rax*4] - prefetcht0 [rbx] - prefetcht0 [rbx+rax] - lea rbx, [rbx+rax*2] - prefetcht0 [rbx] - prefetcht0 [rbx+rax] - lea rbx, [rdi+rdx*4] - prefetcht0 [rbx] - prefetcht0 [rbx+rdx] - lea rbx, [rbx+rdx*2] - prefetcht0 [rbx] - prefetcht0 [rbx+rdx] - - pxor xmm5, xmm5 - - psubw xmm1, xmm2 - movdqu xmm3, XMMWORD PTR [rsi+rax] - paddw xmm5, xmm1 - pmaddwd xmm1, xmm1 - movdqu xmm2, XMMWORD PTR [rdi+rdx] - paddd xmm6, xmm1 - - lea rsi, [rsi + 2*rax] - lea rdi, [rdi + 2*rdx] - - psubw xmm3, xmm2 - movdqu xmm1, XMMWORD PTR [rsi] - paddw xmm5, xmm3 - pmaddwd xmm3, xmm3 - movdqu xmm2, XMMWORD PTR [rdi] - paddd xmm6, xmm3 - - psubw xmm1, xmm2 - movdqu xmm3, XMMWORD PTR [rsi+rax] - paddw xmm5, xmm1 - pmaddwd xmm1, xmm1 - movdqu xmm2, XMMWORD PTR [rdi+rdx] - paddd xmm6, xmm1 - - psubw xmm3, xmm2 - paddw xmm5, xmm3 - pmaddwd xmm3, xmm3 - paddd xmm6, xmm3 - - movdqa xmm1, xmm5 - movdqa xmm2, xmm5 - pcmpgtw xmm1, xmm0 - pcmpeqw xmm2, xmm0 - por xmm1, xmm2 - pcmpeqw xmm1, xmm0 - movdqa xmm2, xmm5 - punpcklwd xmm5, xmm1 - punpckhwd xmm2, xmm1 - paddd xmm7, xmm5 - paddd xmm7, xmm2 - - lea rsi, [rsi + 2*rax] - lea rdi, [rdi + 2*rdx] - sub rcx, 4 - jnz .var8loop - - movdqa xmm4, xmm6 - punpckldq xmm6, xmm0 - - punpckhdq xmm4, xmm0 - movdqa xmm5, xmm7 - - paddd xmm6, xmm4 - punpckldq xmm7, xmm0 - - punpckhdq xmm5, xmm0 - paddd xmm7, xmm5 - - movdqa xmm4, xmm6 - movdqa xmm5, xmm7 - - psrldq xmm4, 8 - psrldq xmm5, 8 - - paddd xmm6, xmm4 - paddd xmm7, xmm5 - - mov rdi, arg(4) ; [SSE] - mov rax, arg(5) ; [Sum] - - movd DWORD PTR [rdi], xmm6 - movd DWORD PTR [rax], xmm7 - - ; begin epilog - pop rdi - pop rsi - pop rbx - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_variance_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_variance_sse2.c deleted file mode 100644 index 381e0ad1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/highbd_variance_sse2.c +++ /dev/null @@ -1,608 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include // SSE2 - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_ports/mem.h" - -typedef uint32_t (*high_variance_fn_t)(const uint16_t *src, int src_stride, - const uint16_t *ref, int ref_stride, - uint32_t *sse, int *sum); - -uint32_t vpx_highbd_calc8x8var_sse2(const uint16_t *src, int src_stride, - const uint16_t *ref, int ref_stride, - uint32_t *sse, int *sum); - -uint32_t vpx_highbd_calc16x16var_sse2(const uint16_t *src, int src_stride, - const uint16_t *ref, int ref_stride, - uint32_t *sse, int *sum); - -static void highbd_8_variance_sse2(const uint16_t *src, int src_stride, - const uint16_t *ref, int ref_stride, int w, - int h, uint32_t *sse, int *sum, - high_variance_fn_t var_fn, int block_size) { - int i, j; - - *sse = 0; - *sum = 0; - - for (i = 0; i < h; i += block_size) { - for (j = 0; j < w; j += block_size) { - unsigned int sse0; - int sum0; - var_fn(src + src_stride * i + j, src_stride, ref + ref_stride * i + j, - ref_stride, &sse0, &sum0); - *sse += sse0; - *sum += sum0; - } - } -} - -static void highbd_10_variance_sse2(const uint16_t *src, int src_stride, - const uint16_t *ref, int ref_stride, int w, - int h, uint32_t *sse, int *sum, - high_variance_fn_t var_fn, int block_size) { - int i, j; - uint64_t sse_long = 0; - int32_t sum_long = 0; - - for (i = 0; i < h; i += block_size) { - for (j = 0; j < w; j += block_size) { - unsigned int sse0; - int sum0; - var_fn(src + src_stride * i + j, src_stride, ref + ref_stride * i + j, - ref_stride, &sse0, &sum0); - sse_long += sse0; - sum_long += sum0; - } - } - *sum = ROUND_POWER_OF_TWO(sum_long, 2); - *sse = (uint32_t)ROUND_POWER_OF_TWO(sse_long, 4); -} - -static void highbd_12_variance_sse2(const uint16_t *src, int src_stride, - const uint16_t *ref, int ref_stride, int w, - int h, uint32_t *sse, int *sum, - high_variance_fn_t var_fn, int block_size) { - int i, j; - uint64_t sse_long = 0; - int32_t sum_long = 0; - - for (i = 0; i < h; i += block_size) { - for (j = 0; j < w; j += block_size) { - unsigned int sse0; - int sum0; - var_fn(src + src_stride * i + j, src_stride, ref + ref_stride * i + j, - ref_stride, &sse0, &sum0); - sse_long += sse0; - sum_long += sum0; - } - } - *sum = ROUND_POWER_OF_TWO(sum_long, 4); - *sse = (uint32_t)ROUND_POWER_OF_TWO(sse_long, 8); -} - -#define HIGH_GET_VAR(S) \ - void vpx_highbd_8_get##S##x##S##var_sse2( \ - const uint8_t *src8, int src_stride, const uint8_t *ref8, \ - int ref_stride, uint32_t *sse, int *sum) { \ - uint16_t *src = CONVERT_TO_SHORTPTR(src8); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); \ - vpx_highbd_calc##S##x##S##var_sse2(src, src_stride, ref, ref_stride, sse, \ - sum); \ - } \ - \ - void vpx_highbd_10_get##S##x##S##var_sse2( \ - const uint8_t *src8, int src_stride, const uint8_t *ref8, \ - int ref_stride, uint32_t *sse, int *sum) { \ - uint16_t *src = CONVERT_TO_SHORTPTR(src8); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); \ - vpx_highbd_calc##S##x##S##var_sse2(src, src_stride, ref, ref_stride, sse, \ - sum); \ - *sum = ROUND_POWER_OF_TWO(*sum, 2); \ - *sse = ROUND_POWER_OF_TWO(*sse, 4); \ - } \ - \ - void vpx_highbd_12_get##S##x##S##var_sse2( \ - const uint8_t *src8, int src_stride, const uint8_t *ref8, \ - int ref_stride, uint32_t *sse, int *sum) { \ - uint16_t *src = CONVERT_TO_SHORTPTR(src8); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); \ - vpx_highbd_calc##S##x##S##var_sse2(src, src_stride, ref, ref_stride, sse, \ - sum); \ - *sum = ROUND_POWER_OF_TWO(*sum, 4); \ - *sse = ROUND_POWER_OF_TWO(*sse, 8); \ - } - -HIGH_GET_VAR(16) -HIGH_GET_VAR(8) - -#undef HIGH_GET_VAR - -#define VAR_FN(w, h, block_size, shift) \ - uint32_t vpx_highbd_8_variance##w##x##h##_sse2( \ - const uint8_t *src8, int src_stride, const uint8_t *ref8, \ - int ref_stride, uint32_t *sse) { \ - int sum; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src8); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); \ - highbd_8_variance_sse2( \ - src, src_stride, ref, ref_stride, w, h, sse, &sum, \ - vpx_highbd_calc##block_size##x##block_size##var_sse2, block_size); \ - return *sse - (uint32_t)(((int64_t)sum * sum) >> (shift)); \ - } \ - \ - uint32_t vpx_highbd_10_variance##w##x##h##_sse2( \ - const uint8_t *src8, int src_stride, const uint8_t *ref8, \ - int ref_stride, uint32_t *sse) { \ - int sum; \ - int64_t var; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src8); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); \ - highbd_10_variance_sse2( \ - src, src_stride, ref, ref_stride, w, h, sse, &sum, \ - vpx_highbd_calc##block_size##x##block_size##var_sse2, block_size); \ - var = (int64_t)(*sse) - (((int64_t)sum * sum) >> (shift)); \ - return (var >= 0) ? (uint32_t)var : 0; \ - } \ - \ - uint32_t vpx_highbd_12_variance##w##x##h##_sse2( \ - const uint8_t *src8, int src_stride, const uint8_t *ref8, \ - int ref_stride, uint32_t *sse) { \ - int sum; \ - int64_t var; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src8); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); \ - highbd_12_variance_sse2( \ - src, src_stride, ref, ref_stride, w, h, sse, &sum, \ - vpx_highbd_calc##block_size##x##block_size##var_sse2, block_size); \ - var = (int64_t)(*sse) - (((int64_t)sum * sum) >> (shift)); \ - return (var >= 0) ? (uint32_t)var : 0; \ - } - -VAR_FN(64, 64, 16, 12) -VAR_FN(64, 32, 16, 11) -VAR_FN(32, 64, 16, 11) -VAR_FN(32, 32, 16, 10) -VAR_FN(32, 16, 16, 9) -VAR_FN(16, 32, 16, 9) -VAR_FN(16, 16, 16, 8) -VAR_FN(16, 8, 8, 7) -VAR_FN(8, 16, 8, 7) -VAR_FN(8, 8, 8, 6) - -#undef VAR_FN - -unsigned int vpx_highbd_8_mse16x16_sse2(const uint8_t *src8, int src_stride, - const uint8_t *ref8, int ref_stride, - unsigned int *sse) { - int sum; - uint16_t *src = CONVERT_TO_SHORTPTR(src8); - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); - highbd_8_variance_sse2(src, src_stride, ref, ref_stride, 16, 16, sse, &sum, - vpx_highbd_calc16x16var_sse2, 16); - return *sse; -} - -unsigned int vpx_highbd_10_mse16x16_sse2(const uint8_t *src8, int src_stride, - const uint8_t *ref8, int ref_stride, - unsigned int *sse) { - int sum; - uint16_t *src = CONVERT_TO_SHORTPTR(src8); - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); - highbd_10_variance_sse2(src, src_stride, ref, ref_stride, 16, 16, sse, &sum, - vpx_highbd_calc16x16var_sse2, 16); - return *sse; -} - -unsigned int vpx_highbd_12_mse16x16_sse2(const uint8_t *src8, int src_stride, - const uint8_t *ref8, int ref_stride, - unsigned int *sse) { - int sum; - uint16_t *src = CONVERT_TO_SHORTPTR(src8); - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); - highbd_12_variance_sse2(src, src_stride, ref, ref_stride, 16, 16, sse, &sum, - vpx_highbd_calc16x16var_sse2, 16); - return *sse; -} - -unsigned int vpx_highbd_8_mse8x8_sse2(const uint8_t *src8, int src_stride, - const uint8_t *ref8, int ref_stride, - unsigned int *sse) { - int sum; - uint16_t *src = CONVERT_TO_SHORTPTR(src8); - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); - highbd_8_variance_sse2(src, src_stride, ref, ref_stride, 8, 8, sse, &sum, - vpx_highbd_calc8x8var_sse2, 8); - return *sse; -} - -unsigned int vpx_highbd_10_mse8x8_sse2(const uint8_t *src8, int src_stride, - const uint8_t *ref8, int ref_stride, - unsigned int *sse) { - int sum; - uint16_t *src = CONVERT_TO_SHORTPTR(src8); - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); - highbd_10_variance_sse2(src, src_stride, ref, ref_stride, 8, 8, sse, &sum, - vpx_highbd_calc8x8var_sse2, 8); - return *sse; -} - -unsigned int vpx_highbd_12_mse8x8_sse2(const uint8_t *src8, int src_stride, - const uint8_t *ref8, int ref_stride, - unsigned int *sse) { - int sum; - uint16_t *src = CONVERT_TO_SHORTPTR(src8); - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); - highbd_12_variance_sse2(src, src_stride, ref, ref_stride, 8, 8, sse, &sum, - vpx_highbd_calc8x8var_sse2, 8); - return *sse; -} - -// The 2 unused parameters are place holders for PIC enabled build. -// These definitions are for functions defined in -// highbd_subpel_variance_impl_sse2.asm -#define DECL(w, opt) \ - int vpx_highbd_sub_pixel_variance##w##xh_##opt( \ - const uint16_t *src, ptrdiff_t src_stride, int x_offset, int y_offset, \ - const uint16_t *ref, ptrdiff_t ref_stride, int height, \ - unsigned int *sse, void *unused0, void *unused); -#define DECLS(opt) \ - DECL(8, opt) \ - DECL(16, opt) - -DECLS(sse2) - -#undef DECLS -#undef DECL - -#define FN(w, h, wf, wlog2, hlog2, opt, cast) \ - uint32_t vpx_highbd_8_sub_pixel_variance##w##x##h##_##opt( \ - const uint8_t *src8, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref8, int ref_stride, uint32_t *sse_ptr) { \ - uint32_t sse; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src8); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); \ - int se = vpx_highbd_sub_pixel_variance##wf##xh_##opt( \ - src, src_stride, x_offset, y_offset, ref, ref_stride, h, &sse, NULL, \ - NULL); \ - if (w > wf) { \ - unsigned int sse2; \ - int se2 = vpx_highbd_sub_pixel_variance##wf##xh_##opt( \ - src + 16, src_stride, x_offset, y_offset, ref + 16, ref_stride, h, \ - &sse2, NULL, NULL); \ - se += se2; \ - sse += sse2; \ - if (w > wf * 2) { \ - se2 = vpx_highbd_sub_pixel_variance##wf##xh_##opt( \ - src + 32, src_stride, x_offset, y_offset, ref + 32, ref_stride, h, \ - &sse2, NULL, NULL); \ - se += se2; \ - sse += sse2; \ - se2 = vpx_highbd_sub_pixel_variance##wf##xh_##opt( \ - src + 48, src_stride, x_offset, y_offset, ref + 48, ref_stride, h, \ - &sse2, NULL, NULL); \ - se += se2; \ - sse += sse2; \ - } \ - } \ - *sse_ptr = sse; \ - return sse - (uint32_t)((cast se * se) >> (wlog2 + hlog2)); \ - } \ - \ - uint32_t vpx_highbd_10_sub_pixel_variance##w##x##h##_##opt( \ - const uint8_t *src8, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref8, int ref_stride, uint32_t *sse_ptr) { \ - int64_t var; \ - uint32_t sse; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src8); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); \ - int se = vpx_highbd_sub_pixel_variance##wf##xh_##opt( \ - src, src_stride, x_offset, y_offset, ref, ref_stride, h, &sse, NULL, \ - NULL); \ - if (w > wf) { \ - uint32_t sse2; \ - int se2 = vpx_highbd_sub_pixel_variance##wf##xh_##opt( \ - src + 16, src_stride, x_offset, y_offset, ref + 16, ref_stride, h, \ - &sse2, NULL, NULL); \ - se += se2; \ - sse += sse2; \ - if (w > wf * 2) { \ - se2 = vpx_highbd_sub_pixel_variance##wf##xh_##opt( \ - src + 32, src_stride, x_offset, y_offset, ref + 32, ref_stride, h, \ - &sse2, NULL, NULL); \ - se += se2; \ - sse += sse2; \ - se2 = vpx_highbd_sub_pixel_variance##wf##xh_##opt( \ - src + 48, src_stride, x_offset, y_offset, ref + 48, ref_stride, h, \ - &sse2, NULL, NULL); \ - se += se2; \ - sse += sse2; \ - } \ - } \ - se = ROUND_POWER_OF_TWO(se, 2); \ - sse = ROUND_POWER_OF_TWO(sse, 4); \ - *sse_ptr = sse; \ - var = (int64_t)(sse) - ((cast se * se) >> (wlog2 + hlog2)); \ - return (var >= 0) ? (uint32_t)var : 0; \ - } \ - \ - uint32_t vpx_highbd_12_sub_pixel_variance##w##x##h##_##opt( \ - const uint8_t *src8, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref8, int ref_stride, uint32_t *sse_ptr) { \ - int start_row; \ - uint32_t sse; \ - int se = 0; \ - int64_t var; \ - uint64_t long_sse = 0; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src8); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); \ - for (start_row = 0; start_row < h; start_row += 16) { \ - uint32_t sse2; \ - int height = h - start_row < 16 ? h - start_row : 16; \ - int se2 = vpx_highbd_sub_pixel_variance##wf##xh_##opt( \ - src + (start_row * src_stride), src_stride, x_offset, y_offset, \ - ref + (start_row * ref_stride), ref_stride, height, &sse2, NULL, \ - NULL); \ - se += se2; \ - long_sse += sse2; \ - if (w > wf) { \ - se2 = vpx_highbd_sub_pixel_variance##wf##xh_##opt( \ - src + 16 + (start_row * src_stride), src_stride, x_offset, \ - y_offset, ref + 16 + (start_row * ref_stride), ref_stride, height, \ - &sse2, NULL, NULL); \ - se += se2; \ - long_sse += sse2; \ - if (w > wf * 2) { \ - se2 = vpx_highbd_sub_pixel_variance##wf##xh_##opt( \ - src + 32 + (start_row * src_stride), src_stride, x_offset, \ - y_offset, ref + 32 + (start_row * ref_stride), ref_stride, \ - height, &sse2, NULL, NULL); \ - se += se2; \ - long_sse += sse2; \ - se2 = vpx_highbd_sub_pixel_variance##wf##xh_##opt( \ - src + 48 + (start_row * src_stride), src_stride, x_offset, \ - y_offset, ref + 48 + (start_row * ref_stride), ref_stride, \ - height, &sse2, NULL, NULL); \ - se += se2; \ - long_sse += sse2; \ - } \ - } \ - } \ - se = ROUND_POWER_OF_TWO(se, 4); \ - sse = (uint32_t)ROUND_POWER_OF_TWO(long_sse, 8); \ - *sse_ptr = sse; \ - var = (int64_t)(sse) - ((cast se * se) >> (wlog2 + hlog2)); \ - return (var >= 0) ? (uint32_t)var : 0; \ - } - -#define FNS(opt) \ - FN(64, 64, 16, 6, 6, opt, (int64_t)) \ - FN(64, 32, 16, 6, 5, opt, (int64_t)) \ - FN(32, 64, 16, 5, 6, opt, (int64_t)) \ - FN(32, 32, 16, 5, 5, opt, (int64_t)) \ - FN(32, 16, 16, 5, 4, opt, (int64_t)) \ - FN(16, 32, 16, 4, 5, opt, (int64_t)) \ - FN(16, 16, 16, 4, 4, opt, (int64_t)) \ - FN(16, 8, 16, 4, 3, opt, (int64_t)) \ - FN(8, 16, 8, 3, 4, opt, (int64_t)) \ - FN(8, 8, 8, 3, 3, opt, (int64_t)) \ - FN(8, 4, 8, 3, 2, opt, (int64_t)) - -FNS(sse2) - -#undef FNS -#undef FN - -// The 2 unused parameters are place holders for PIC enabled build. -#define DECL(w, opt) \ - int vpx_highbd_sub_pixel_avg_variance##w##xh_##opt( \ - const uint16_t *src, ptrdiff_t src_stride, int x_offset, int y_offset, \ - const uint16_t *ref, ptrdiff_t ref_stride, const uint16_t *second, \ - ptrdiff_t second_stride, int height, unsigned int *sse, void *unused0, \ - void *unused); -#define DECLS(opt1) \ - DECL(16, opt1) \ - DECL(8, opt1) - -DECLS(sse2) -#undef DECL -#undef DECLS - -#define FN(w, h, wf, wlog2, hlog2, opt, cast) \ - uint32_t vpx_highbd_8_sub_pixel_avg_variance##w##x##h##_##opt( \ - const uint8_t *src8, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref8, int ref_stride, uint32_t *sse_ptr, \ - const uint8_t *sec8) { \ - uint32_t sse; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src8); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); \ - uint16_t *sec = CONVERT_TO_SHORTPTR(sec8); \ - int se = vpx_highbd_sub_pixel_avg_variance##wf##xh_##opt( \ - src, src_stride, x_offset, y_offset, ref, ref_stride, sec, w, h, &sse, \ - NULL, NULL); \ - if (w > wf) { \ - uint32_t sse2; \ - int se2 = vpx_highbd_sub_pixel_avg_variance##wf##xh_##opt( \ - src + 16, src_stride, x_offset, y_offset, ref + 16, ref_stride, \ - sec + 16, w, h, &sse2, NULL, NULL); \ - se += se2; \ - sse += sse2; \ - if (w > wf * 2) { \ - se2 = vpx_highbd_sub_pixel_avg_variance##wf##xh_##opt( \ - src + 32, src_stride, x_offset, y_offset, ref + 32, ref_stride, \ - sec + 32, w, h, &sse2, NULL, NULL); \ - se += se2; \ - sse += sse2; \ - se2 = vpx_highbd_sub_pixel_avg_variance##wf##xh_##opt( \ - src + 48, src_stride, x_offset, y_offset, ref + 48, ref_stride, \ - sec + 48, w, h, &sse2, NULL, NULL); \ - se += se2; \ - sse += sse2; \ - } \ - } \ - *sse_ptr = sse; \ - return sse - (uint32_t)((cast se * se) >> (wlog2 + hlog2)); \ - } \ - \ - uint32_t vpx_highbd_10_sub_pixel_avg_variance##w##x##h##_##opt( \ - const uint8_t *src8, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref8, int ref_stride, uint32_t *sse_ptr, \ - const uint8_t *sec8) { \ - int64_t var; \ - uint32_t sse; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src8); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); \ - uint16_t *sec = CONVERT_TO_SHORTPTR(sec8); \ - int se = vpx_highbd_sub_pixel_avg_variance##wf##xh_##opt( \ - src, src_stride, x_offset, y_offset, ref, ref_stride, sec, w, h, &sse, \ - NULL, NULL); \ - if (w > wf) { \ - uint32_t sse2; \ - int se2 = vpx_highbd_sub_pixel_avg_variance##wf##xh_##opt( \ - src + 16, src_stride, x_offset, y_offset, ref + 16, ref_stride, \ - sec + 16, w, h, &sse2, NULL, NULL); \ - se += se2; \ - sse += sse2; \ - if (w > wf * 2) { \ - se2 = vpx_highbd_sub_pixel_avg_variance##wf##xh_##opt( \ - src + 32, src_stride, x_offset, y_offset, ref + 32, ref_stride, \ - sec + 32, w, h, &sse2, NULL, NULL); \ - se += se2; \ - sse += sse2; \ - se2 = vpx_highbd_sub_pixel_avg_variance##wf##xh_##opt( \ - src + 48, src_stride, x_offset, y_offset, ref + 48, ref_stride, \ - sec + 48, w, h, &sse2, NULL, NULL); \ - se += se2; \ - sse += sse2; \ - } \ - } \ - se = ROUND_POWER_OF_TWO(se, 2); \ - sse = ROUND_POWER_OF_TWO(sse, 4); \ - *sse_ptr = sse; \ - var = (int64_t)(sse) - ((cast se * se) >> (wlog2 + hlog2)); \ - return (var >= 0) ? (uint32_t)var : 0; \ - } \ - \ - uint32_t vpx_highbd_12_sub_pixel_avg_variance##w##x##h##_##opt( \ - const uint8_t *src8, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref8, int ref_stride, uint32_t *sse_ptr, \ - const uint8_t *sec8) { \ - int start_row; \ - int64_t var; \ - uint32_t sse; \ - int se = 0; \ - uint64_t long_sse = 0; \ - uint16_t *src = CONVERT_TO_SHORTPTR(src8); \ - uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); \ - uint16_t *sec = CONVERT_TO_SHORTPTR(sec8); \ - for (start_row = 0; start_row < h; start_row += 16) { \ - uint32_t sse2; \ - int height = h - start_row < 16 ? h - start_row : 16; \ - int se2 = vpx_highbd_sub_pixel_avg_variance##wf##xh_##opt( \ - src + (start_row * src_stride), src_stride, x_offset, y_offset, \ - ref + (start_row * ref_stride), ref_stride, sec + (start_row * w), \ - w, height, &sse2, NULL, NULL); \ - se += se2; \ - long_sse += sse2; \ - if (w > wf) { \ - se2 = vpx_highbd_sub_pixel_avg_variance##wf##xh_##opt( \ - src + 16 + (start_row * src_stride), src_stride, x_offset, \ - y_offset, ref + 16 + (start_row * ref_stride), ref_stride, \ - sec + 16 + (start_row * w), w, height, &sse2, NULL, NULL); \ - se += se2; \ - long_sse += sse2; \ - if (w > wf * 2) { \ - se2 = vpx_highbd_sub_pixel_avg_variance##wf##xh_##opt( \ - src + 32 + (start_row * src_stride), src_stride, x_offset, \ - y_offset, ref + 32 + (start_row * ref_stride), ref_stride, \ - sec + 32 + (start_row * w), w, height, &sse2, NULL, NULL); \ - se += se2; \ - long_sse += sse2; \ - se2 = vpx_highbd_sub_pixel_avg_variance##wf##xh_##opt( \ - src + 48 + (start_row * src_stride), src_stride, x_offset, \ - y_offset, ref + 48 + (start_row * ref_stride), ref_stride, \ - sec + 48 + (start_row * w), w, height, &sse2, NULL, NULL); \ - se += se2; \ - long_sse += sse2; \ - } \ - } \ - } \ - se = ROUND_POWER_OF_TWO(se, 4); \ - sse = (uint32_t)ROUND_POWER_OF_TWO(long_sse, 8); \ - *sse_ptr = sse; \ - var = (int64_t)(sse) - ((cast se * se) >> (wlog2 + hlog2)); \ - return (var >= 0) ? (uint32_t)var : 0; \ - } - -#define FNS(opt1) \ - FN(64, 64, 16, 6, 6, opt1, (int64_t)) \ - FN(64, 32, 16, 6, 5, opt1, (int64_t)) \ - FN(32, 64, 16, 5, 6, opt1, (int64_t)) \ - FN(32, 32, 16, 5, 5, opt1, (int64_t)) \ - FN(32, 16, 16, 5, 4, opt1, (int64_t)) \ - FN(16, 32, 16, 4, 5, opt1, (int64_t)) \ - FN(16, 16, 16, 4, 4, opt1, (int64_t)) \ - FN(16, 8, 16, 4, 3, opt1, (int64_t)) \ - FN(8, 16, 8, 4, 3, opt1, (int64_t)) \ - FN(8, 8, 8, 3, 3, opt1, (int64_t)) \ - FN(8, 4, 8, 3, 2, opt1, (int64_t)) - -FNS(sse2) - -#undef FNS -#undef FN - -void vpx_highbd_comp_avg_pred_sse2(uint16_t *comp_pred, const uint16_t *pred, - int width, int height, const uint16_t *ref, - int ref_stride) { - int i, j; - if (width > 8) { - for (i = 0; i < height; ++i) { - for (j = 0; j < width; j += 16) { - const __m128i p0 = _mm_loadu_si128((const __m128i *)&pred[j]); - const __m128i p1 = _mm_loadu_si128((const __m128i *)&pred[j + 8]); - const __m128i r0 = _mm_loadu_si128((const __m128i *)&ref[j]); - const __m128i r1 = _mm_loadu_si128((const __m128i *)&ref[j + 8]); - _mm_storeu_si128((__m128i *)&comp_pred[j], _mm_avg_epu16(p0, r0)); - _mm_storeu_si128((__m128i *)&comp_pred[j + 8], _mm_avg_epu16(p1, r1)); - } - comp_pred += width; - pred += width; - ref += ref_stride; - } - } else if (width == 8) { - for (i = 0; i < height; i += 2) { - const __m128i p0 = _mm_loadu_si128((const __m128i *)&pred[0]); - const __m128i p1 = _mm_loadu_si128((const __m128i *)&pred[8]); - const __m128i r0 = _mm_loadu_si128((const __m128i *)&ref[0]); - const __m128i r1 = _mm_loadu_si128((const __m128i *)&ref[ref_stride]); - _mm_storeu_si128((__m128i *)&comp_pred[0], _mm_avg_epu16(p0, r0)); - _mm_storeu_si128((__m128i *)&comp_pred[8], _mm_avg_epu16(p1, r1)); - comp_pred += 8 << 1; - pred += 8 << 1; - ref += ref_stride << 1; - } - } else { - assert(width == 4); - for (i = 0; i < height; i += 2) { - const __m128i p0 = _mm_loadl_epi64((const __m128i *)&pred[0]); - const __m128i p1 = _mm_loadl_epi64((const __m128i *)&pred[4]); - const __m128i r0 = _mm_loadl_epi64((const __m128i *)&ref[0]); - const __m128i r1 = _mm_loadl_epi64((const __m128i *)&ref[ref_stride]); - _mm_storel_epi64((__m128i *)&comp_pred[0], _mm_avg_epu16(p0, r0)); - _mm_storel_epi64((__m128i *)&comp_pred[4], _mm_avg_epu16(p1, r1)); - comp_pred += 4 << 1; - pred += 4 << 1; - ref += ref_stride << 1; - } - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/intrapred_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/intrapred_sse2.asm deleted file mode 100644 index 61af6236..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/intrapred_sse2.asm +++ /dev/null @@ -1,860 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "third_party/x86inc/x86inc.asm" - -SECTION_RODATA -pb_1: times 16 db 1 -pw_4: times 8 dw 4 -pw_8: times 8 dw 8 -pw_16: times 8 dw 16 -pw_32: times 8 dw 32 -dc_128: times 16 db 128 -pw2_4: times 8 dw 2 -pw2_8: times 8 dw 4 -pw2_16: times 8 dw 8 -pw2_32: times 8 dw 16 - -SECTION .text - -; ------------------------------------------ -; input: x, y, z, result -; -; trick from pascal -; (x+2y+z+2)>>2 can be calculated as: -; result = avg(x,z) -; result -= xor(x,z) & 1 -; result = avg(result,y) -; ------------------------------------------ -%macro X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 4 - pavgb %4, %1, %3 - pxor %3, %1 - pand %3, [GLOBAL(pb_1)] - psubb %4, %3 - pavgb %4, %2 -%endmacro - -INIT_XMM sse2 -cglobal d45_predictor_4x4, 3, 4, 4, dst, stride, above, goffset - GET_GOT goffsetq - - movq m0, [aboveq] - DEFINE_ARGS dst, stride, temp - psrldq m1, m0, 1 - psrldq m2, m0, 2 - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m0, m1, m2, m3 - - ; store 4 lines - movd [dstq ], m3 - psrlq m3, 8 - movd [dstq+strideq ], m3 - lea dstq, [dstq+strideq*2] - psrlq m3, 8 - movd [dstq ], m3 - psrlq m3, 8 - movd [dstq+strideq ], m3 - psrlq m0, 56 - movd tempd, m0 - mov [dstq+strideq+3], tempb - - RESTORE_GOT - RET - -INIT_XMM sse2 -cglobal d45_predictor_8x8, 3, 4, 4, dst, stride, above, goffset - GET_GOT goffsetq - - movu m1, [aboveq] - pslldq m0, m1, 1 - psrldq m2, m1, 1 - DEFINE_ARGS dst, stride, stride3 - lea stride3q, [strideq*3] - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m0, m1, m2, m3 - punpckhbw m0, m0 ; 7 7 - punpcklwd m0, m0 ; 7 7 7 7 - punpckldq m0, m0 ; 7 7 7 7 7 7 7 7 - punpcklqdq m3, m0 ; -1 0 1 2 3 4 5 6 7 7 7 7 7 7 7 7 - - ; store 4 lines - psrldq m3, 1 - movq [dstq ], m3 - psrldq m3, 1 - movq [dstq+strideq ], m3 - psrldq m3, 1 - movq [dstq+strideq*2], m3 - psrldq m3, 1 - movq [dstq+stride3q ], m3 - lea dstq, [dstq+strideq*4] - - ; store next 4 lines - psrldq m3, 1 - movq [dstq ], m3 - psrldq m3, 1 - movq [dstq+strideq ], m3 - psrldq m3, 1 - movq [dstq+strideq*2], m3 - psrldq m3, 1 - movq [dstq+stride3q ], m3 - - RESTORE_GOT - RET - -INIT_XMM sse2 -cglobal d207_predictor_4x4, 4, 4, 5, dst, stride, unused, left, goffset - GET_GOT goffsetq - - movd m0, [leftq] ; abcd [byte] - punpcklbw m4, m0, m0 ; aabb ccdd - punpcklwd m4, m4 ; aaaa bbbb cccc dddd - psrldq m4, 12 ; dddd - punpckldq m0, m4 ; abcd dddd - psrldq m1, m0, 1 ; bcdd - psrldq m2, m0, 2 ; cddd - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m0, m1, m2, m3 ; a2bc b2cd c3d d - pavgb m1, m0 ; ab, bc, cd, d [byte] - - punpcklbw m1, m3 ; ab, a2bc, bc, b2cd, cd, c3d, d, d - movd [dstq ], m1 - psrlq m1, 16 ; bc, b2cd, cd, c3d, d, d - movd [dstq+strideq], m1 - - lea dstq, [dstq+strideq*2] - psrlq m1, 16 ; cd, c3d, d, d - movd [dstq ], m1 - movd [dstq+strideq], m4 ; d, d, d, d - RESTORE_GOT - RET - -INIT_XMM sse2 -cglobal dc_predictor_4x4, 4, 5, 3, dst, stride, above, left, goffset - GET_GOT goffsetq - - movd m2, [leftq] - movd m0, [aboveq] - pxor m1, m1 - punpckldq m0, m2 - psadbw m0, m1 - paddw m0, [GLOBAL(pw_4)] - psraw m0, 3 - pshuflw m0, m0, 0x0 - packuswb m0, m0 - movd [dstq ], m0 - movd [dstq+strideq], m0 - lea dstq, [dstq+strideq*2] - movd [dstq ], m0 - movd [dstq+strideq], m0 - - RESTORE_GOT - RET - -INIT_XMM sse2 -cglobal dc_left_predictor_4x4, 2, 5, 2, dst, stride, above, left, goffset - movifnidn leftq, leftmp - GET_GOT goffsetq - - pxor m1, m1 - movd m0, [leftq] - psadbw m0, m1 - paddw m0, [GLOBAL(pw2_4)] - psraw m0, 2 - pshuflw m0, m0, 0x0 - packuswb m0, m0 - movd [dstq ], m0 - movd [dstq+strideq], m0 - lea dstq, [dstq+strideq*2] - movd [dstq ], m0 - movd [dstq+strideq], m0 - - RESTORE_GOT - RET - -INIT_XMM sse2 -cglobal dc_top_predictor_4x4, 3, 5, 2, dst, stride, above, left, goffset - GET_GOT goffsetq - - pxor m1, m1 - movd m0, [aboveq] - psadbw m0, m1 - paddw m0, [GLOBAL(pw2_4)] - psraw m0, 2 - pshuflw m0, m0, 0x0 - packuswb m0, m0 - movd [dstq ], m0 - movd [dstq+strideq], m0 - lea dstq, [dstq+strideq*2] - movd [dstq ], m0 - movd [dstq+strideq], m0 - - RESTORE_GOT - RET - -INIT_XMM sse2 -cglobal dc_predictor_8x8, 4, 5, 3, dst, stride, above, left, goffset - GET_GOT goffsetq - - pxor m1, m1 - movq m0, [aboveq] - movq m2, [leftq] - DEFINE_ARGS dst, stride, stride3 - lea stride3q, [strideq*3] - psadbw m0, m1 - psadbw m2, m1 - paddw m0, m2 - paddw m0, [GLOBAL(pw_8)] - psraw m0, 4 - punpcklbw m0, m0 - pshuflw m0, m0, 0x0 - movq [dstq ], m0 - movq [dstq+strideq ], m0 - movq [dstq+strideq*2], m0 - movq [dstq+stride3q ], m0 - lea dstq, [dstq+strideq*4] - movq [dstq ], m0 - movq [dstq+strideq ], m0 - movq [dstq+strideq*2], m0 - movq [dstq+stride3q ], m0 - - RESTORE_GOT - RET - -INIT_XMM sse2 -cglobal dc_top_predictor_8x8, 3, 5, 2, dst, stride, above, left, goffset - GET_GOT goffsetq - - pxor m1, m1 - movq m0, [aboveq] - DEFINE_ARGS dst, stride, stride3 - lea stride3q, [strideq*3] - psadbw m0, m1 - paddw m0, [GLOBAL(pw2_8)] - psraw m0, 3 - punpcklbw m0, m0 - pshuflw m0, m0, 0x0 - movq [dstq ], m0 - movq [dstq+strideq ], m0 - movq [dstq+strideq*2], m0 - movq [dstq+stride3q ], m0 - lea dstq, [dstq+strideq*4] - movq [dstq ], m0 - movq [dstq+strideq ], m0 - movq [dstq+strideq*2], m0 - movq [dstq+stride3q ], m0 - - RESTORE_GOT - RET - -INIT_XMM sse2 -cglobal dc_left_predictor_8x8, 2, 5, 2, dst, stride, above, left, goffset - movifnidn leftq, leftmp - GET_GOT goffsetq - - pxor m1, m1 - movq m0, [leftq] - DEFINE_ARGS dst, stride, stride3 - lea stride3q, [strideq*3] - psadbw m0, m1 - paddw m0, [GLOBAL(pw2_8)] - psraw m0, 3 - punpcklbw m0, m0 - pshuflw m0, m0, 0x0 - movq [dstq ], m0 - movq [dstq+strideq ], m0 - movq [dstq+strideq*2], m0 - movq [dstq+stride3q ], m0 - lea dstq, [dstq+strideq*4] - movq [dstq ], m0 - movq [dstq+strideq ], m0 - movq [dstq+strideq*2], m0 - movq [dstq+stride3q ], m0 - - RESTORE_GOT - RET - -INIT_XMM sse2 -cglobal dc_128_predictor_4x4, 2, 5, 1, dst, stride, above, left, goffset - GET_GOT goffsetq - - DEFINE_ARGS dst, stride, stride3 - lea stride3q, [strideq*3] - movd m0, [GLOBAL(dc_128)] - movd [dstq ], m0 - movd [dstq+strideq ], m0 - movd [dstq+strideq*2], m0 - movd [dstq+stride3q ], m0 - RESTORE_GOT - RET - -INIT_XMM sse2 -cglobal dc_128_predictor_8x8, 2, 5, 1, dst, stride, above, left, goffset - GET_GOT goffsetq - - DEFINE_ARGS dst, stride, stride3 - lea stride3q, [strideq*3] - movq m0, [GLOBAL(dc_128)] - movq [dstq ], m0 - movq [dstq+strideq ], m0 - movq [dstq+strideq*2], m0 - movq [dstq+stride3q ], m0 - lea dstq, [dstq+strideq*4] - movq [dstq ], m0 - movq [dstq+strideq ], m0 - movq [dstq+strideq*2], m0 - movq [dstq+stride3q ], m0 - RESTORE_GOT - RET - -INIT_XMM sse2 -cglobal dc_predictor_16x16, 4, 5, 3, dst, stride, above, left, goffset - GET_GOT goffsetq - - pxor m1, m1 - mova m0, [aboveq] - mova m2, [leftq] - DEFINE_ARGS dst, stride, stride3, lines4 - lea stride3q, [strideq*3] - mov lines4d, 4 - psadbw m0, m1 - psadbw m2, m1 - paddw m0, m2 - movhlps m2, m0 - paddw m0, m2 - paddw m0, [GLOBAL(pw_16)] - psraw m0, 5 - pshuflw m0, m0, 0x0 - punpcklqdq m0, m0 - packuswb m0, m0 -.loop: - mova [dstq ], m0 - mova [dstq+strideq ], m0 - mova [dstq+strideq*2], m0 - mova [dstq+stride3q ], m0 - lea dstq, [dstq+strideq*4] - dec lines4d - jnz .loop - - RESTORE_GOT - REP_RET - - -INIT_XMM sse2 -cglobal dc_top_predictor_16x16, 4, 5, 3, dst, stride, above, left, goffset - GET_GOT goffsetq - - pxor m1, m1 - mova m0, [aboveq] - DEFINE_ARGS dst, stride, stride3, lines4 - lea stride3q, [strideq*3] - mov lines4d, 4 - psadbw m0, m1 - movhlps m2, m0 - paddw m0, m2 - paddw m0, [GLOBAL(pw2_16)] - psraw m0, 4 - pshuflw m0, m0, 0x0 - punpcklqdq m0, m0 - packuswb m0, m0 -.loop: - mova [dstq ], m0 - mova [dstq+strideq ], m0 - mova [dstq+strideq*2], m0 - mova [dstq+stride3q ], m0 - lea dstq, [dstq+strideq*4] - dec lines4d - jnz .loop - - RESTORE_GOT - REP_RET - -INIT_XMM sse2 -cglobal dc_left_predictor_16x16, 4, 5, 3, dst, stride, above, left, goffset - GET_GOT goffsetq - - pxor m1, m1 - mova m0, [leftq] - DEFINE_ARGS dst, stride, stride3, lines4 - lea stride3q, [strideq*3] - mov lines4d, 4 - psadbw m0, m1 - movhlps m2, m0 - paddw m0, m2 - paddw m0, [GLOBAL(pw2_16)] - psraw m0, 4 - pshuflw m0, m0, 0x0 - punpcklqdq m0, m0 - packuswb m0, m0 -.loop: - mova [dstq ], m0 - mova [dstq+strideq ], m0 - mova [dstq+strideq*2], m0 - mova [dstq+stride3q ], m0 - lea dstq, [dstq+strideq*4] - dec lines4d - jnz .loop - - RESTORE_GOT - REP_RET - -INIT_XMM sse2 -cglobal dc_128_predictor_16x16, 4, 5, 3, dst, stride, above, left, goffset - GET_GOT goffsetq - - DEFINE_ARGS dst, stride, stride3, lines4 - lea stride3q, [strideq*3] - mov lines4d, 4 - mova m0, [GLOBAL(dc_128)] -.loop: - mova [dstq ], m0 - mova [dstq+strideq ], m0 - mova [dstq+strideq*2], m0 - mova [dstq+stride3q ], m0 - lea dstq, [dstq+strideq*4] - dec lines4d - jnz .loop - RESTORE_GOT - RET - - -INIT_XMM sse2 -cglobal dc_predictor_32x32, 4, 5, 5, dst, stride, above, left, goffset - GET_GOT goffsetq - - pxor m1, m1 - mova m0, [aboveq] - mova m2, [aboveq+16] - mova m3, [leftq] - mova m4, [leftq+16] - DEFINE_ARGS dst, stride, stride3, lines4 - lea stride3q, [strideq*3] - mov lines4d, 8 - psadbw m0, m1 - psadbw m2, m1 - psadbw m3, m1 - psadbw m4, m1 - paddw m0, m2 - paddw m0, m3 - paddw m0, m4 - movhlps m2, m0 - paddw m0, m2 - paddw m0, [GLOBAL(pw_32)] - psraw m0, 6 - pshuflw m0, m0, 0x0 - punpcklqdq m0, m0 - packuswb m0, m0 -.loop: - mova [dstq ], m0 - mova [dstq +16], m0 - mova [dstq+strideq ], m0 - mova [dstq+strideq +16], m0 - mova [dstq+strideq*2 ], m0 - mova [dstq+strideq*2+16], m0 - mova [dstq+stride3q ], m0 - mova [dstq+stride3q +16], m0 - lea dstq, [dstq+strideq*4] - dec lines4d - jnz .loop - - RESTORE_GOT - REP_RET - -INIT_XMM sse2 -cglobal dc_top_predictor_32x32, 4, 5, 5, dst, stride, above, left, goffset - GET_GOT goffsetq - - pxor m1, m1 - mova m0, [aboveq] - mova m2, [aboveq+16] - DEFINE_ARGS dst, stride, stride3, lines4 - lea stride3q, [strideq*3] - mov lines4d, 8 - psadbw m0, m1 - psadbw m2, m1 - paddw m0, m2 - movhlps m2, m0 - paddw m0, m2 - paddw m0, [GLOBAL(pw2_32)] - psraw m0, 5 - pshuflw m0, m0, 0x0 - punpcklqdq m0, m0 - packuswb m0, m0 -.loop: - mova [dstq ], m0 - mova [dstq +16], m0 - mova [dstq+strideq ], m0 - mova [dstq+strideq +16], m0 - mova [dstq+strideq*2 ], m0 - mova [dstq+strideq*2+16], m0 - mova [dstq+stride3q ], m0 - mova [dstq+stride3q +16], m0 - lea dstq, [dstq+strideq*4] - dec lines4d - jnz .loop - - RESTORE_GOT - REP_RET - -INIT_XMM sse2 -cglobal dc_left_predictor_32x32, 4, 5, 5, dst, stride, above, left, goffset - GET_GOT goffsetq - - pxor m1, m1 - mova m0, [leftq] - mova m2, [leftq+16] - DEFINE_ARGS dst, stride, stride3, lines4 - lea stride3q, [strideq*3] - mov lines4d, 8 - psadbw m0, m1 - psadbw m2, m1 - paddw m0, m2 - movhlps m2, m0 - paddw m0, m2 - paddw m0, [GLOBAL(pw2_32)] - psraw m0, 5 - pshuflw m0, m0, 0x0 - punpcklqdq m0, m0 - packuswb m0, m0 -.loop: - mova [dstq ], m0 - mova [dstq +16], m0 - mova [dstq+strideq ], m0 - mova [dstq+strideq +16], m0 - mova [dstq+strideq*2 ], m0 - mova [dstq+strideq*2+16], m0 - mova [dstq+stride3q ], m0 - mova [dstq+stride3q +16], m0 - lea dstq, [dstq+strideq*4] - dec lines4d - jnz .loop - - RESTORE_GOT - REP_RET - -INIT_XMM sse2 -cglobal dc_128_predictor_32x32, 4, 5, 3, dst, stride, above, left, goffset - GET_GOT goffsetq - - DEFINE_ARGS dst, stride, stride3, lines4 - lea stride3q, [strideq*3] - mov lines4d, 8 - mova m0, [GLOBAL(dc_128)] -.loop: - mova [dstq ], m0 - mova [dstq +16], m0 - mova [dstq+strideq ], m0 - mova [dstq+strideq +16], m0 - mova [dstq+strideq*2 ], m0 - mova [dstq+strideq*2+16], m0 - mova [dstq+stride3q ], m0 - mova [dstq+stride3q +16], m0 - lea dstq, [dstq+strideq*4] - dec lines4d - jnz .loop - RESTORE_GOT - RET - -INIT_XMM sse2 -cglobal v_predictor_4x4, 3, 3, 1, dst, stride, above - movd m0, [aboveq] - movd [dstq ], m0 - movd [dstq+strideq], m0 - lea dstq, [dstq+strideq*2] - movd [dstq ], m0 - movd [dstq+strideq], m0 - RET - -INIT_XMM sse2 -cglobal v_predictor_8x8, 3, 3, 1, dst, stride, above - movq m0, [aboveq] - DEFINE_ARGS dst, stride, stride3 - lea stride3q, [strideq*3] - movq [dstq ], m0 - movq [dstq+strideq ], m0 - movq [dstq+strideq*2], m0 - movq [dstq+stride3q ], m0 - lea dstq, [dstq+strideq*4] - movq [dstq ], m0 - movq [dstq+strideq ], m0 - movq [dstq+strideq*2], m0 - movq [dstq+stride3q ], m0 - RET - -INIT_XMM sse2 -cglobal v_predictor_16x16, 3, 4, 1, dst, stride, above - mova m0, [aboveq] - DEFINE_ARGS dst, stride, stride3, nlines4 - lea stride3q, [strideq*3] - mov nlines4d, 4 -.loop: - mova [dstq ], m0 - mova [dstq+strideq ], m0 - mova [dstq+strideq*2], m0 - mova [dstq+stride3q ], m0 - lea dstq, [dstq+strideq*4] - dec nlines4d - jnz .loop - REP_RET - -INIT_XMM sse2 -cglobal v_predictor_32x32, 3, 4, 2, dst, stride, above - mova m0, [aboveq] - mova m1, [aboveq+16] - DEFINE_ARGS dst, stride, stride3, nlines4 - lea stride3q, [strideq*3] - mov nlines4d, 8 -.loop: - mova [dstq ], m0 - mova [dstq +16], m1 - mova [dstq+strideq ], m0 - mova [dstq+strideq +16], m1 - mova [dstq+strideq*2 ], m0 - mova [dstq+strideq*2+16], m1 - mova [dstq+stride3q ], m0 - mova [dstq+stride3q +16], m1 - lea dstq, [dstq+strideq*4] - dec nlines4d - jnz .loop - REP_RET - -INIT_XMM sse2 -cglobal h_predictor_4x4, 2, 4, 4, dst, stride, line, left - movifnidn leftq, leftmp - movd m0, [leftq] - punpcklbw m0, m0 - punpcklbw m0, m0 - pshufd m1, m0, 0x1 - movd [dstq ], m0 - movd [dstq+strideq], m1 - pshufd m2, m0, 0x2 - lea dstq, [dstq+strideq*2] - pshufd m3, m0, 0x3 - movd [dstq ], m2 - movd [dstq+strideq], m3 - RET - -INIT_XMM sse2 -cglobal h_predictor_8x8, 2, 5, 3, dst, stride, line, left - movifnidn leftq, leftmp - mov lineq, -2 - DEFINE_ARGS dst, stride, line, left, stride3 - lea stride3q, [strideq*3] - movq m0, [leftq ] - punpcklbw m0, m0 ; l1 l1 l2 l2 ... l8 l8 -.loop: - pshuflw m1, m0, 0x0 ; l1 l1 l1 l1 l1 l1 l1 l1 - pshuflw m2, m0, 0x55 ; l2 l2 l2 l2 l2 l2 l2 l2 - movq [dstq ], m1 - movq [dstq+strideq], m2 - pshuflw m1, m0, 0xaa - pshuflw m2, m0, 0xff - movq [dstq+strideq*2], m1 - movq [dstq+stride3q ], m2 - pshufd m0, m0, 0xe ; [63:0] l5 l5 l6 l6 l7 l7 l8 l8 - inc lineq - lea dstq, [dstq+strideq*4] - jnz .loop - REP_RET - -INIT_XMM sse2 -cglobal h_predictor_16x16, 2, 5, 3, dst, stride, line, left - movifnidn leftq, leftmp - mov lineq, -4 - DEFINE_ARGS dst, stride, line, left, stride3 - lea stride3q, [strideq*3] -.loop: - movd m0, [leftq] - punpcklbw m0, m0 - punpcklbw m0, m0 ; l1 to l4 each repeated 4 times - pshufd m1, m0, 0x0 ; l1 repeated 16 times - pshufd m2, m0, 0x55 ; l2 repeated 16 times - mova [dstq ], m1 - mova [dstq+strideq ], m2 - pshufd m1, m0, 0xaa - pshufd m2, m0, 0xff - mova [dstq+strideq*2], m1 - mova [dstq+stride3q ], m2 - inc lineq - lea leftq, [leftq+4 ] - lea dstq, [dstq+strideq*4] - jnz .loop - REP_RET - -INIT_XMM sse2 -cglobal h_predictor_32x32, 2, 5, 3, dst, stride, line, left - movifnidn leftq, leftmp - mov lineq, -8 - DEFINE_ARGS dst, stride, line, left, stride3 - lea stride3q, [strideq*3] -.loop: - movd m0, [leftq] - punpcklbw m0, m0 - punpcklbw m0, m0 ; l1 to l4 each repeated 4 times - pshufd m1, m0, 0x0 ; l1 repeated 16 times - pshufd m2, m0, 0x55 ; l2 repeated 16 times - mova [dstq ], m1 - mova [dstq+16 ], m1 - mova [dstq+strideq ], m2 - mova [dstq+strideq+16 ], m2 - pshufd m1, m0, 0xaa - pshufd m2, m0, 0xff - mova [dstq+strideq*2 ], m1 - mova [dstq+strideq*2+16], m1 - mova [dstq+stride3q ], m2 - mova [dstq+stride3q+16 ], m2 - inc lineq - lea leftq, [leftq+4 ] - lea dstq, [dstq+strideq*4] - jnz .loop - REP_RET - -INIT_XMM sse2 -cglobal tm_predictor_4x4, 4, 4, 5, dst, stride, above, left - pxor m1, m1 - movq m0, [aboveq-1]; [63:0] tl t1 t2 t3 t4 x x x - punpcklbw m0, m1 - pshuflw m2, m0, 0x0 ; [63:0] tl tl tl tl [word] - psrldq m0, 2 - psubw m0, m2 ; [63:0] t1-tl t2-tl t3-tl t4-tl [word] - movd m2, [leftq] - punpcklbw m2, m1 - pshuflw m4, m2, 0x0 ; [63:0] l1 l1 l1 l1 [word] - pshuflw m3, m2, 0x55 ; [63:0] l2 l2 l2 l2 [word] - paddw m4, m0 - paddw m3, m0 - packuswb m4, m4 - packuswb m3, m3 - movd [dstq ], m4 - movd [dstq+strideq], m3 - lea dstq, [dstq+strideq*2] - pshuflw m4, m2, 0xaa - pshuflw m3, m2, 0xff - paddw m4, m0 - paddw m3, m0 - packuswb m4, m4 - packuswb m3, m3 - movd [dstq ], m4 - movd [dstq+strideq], m3 - RET - -INIT_XMM sse2 -cglobal tm_predictor_8x8, 4, 4, 5, dst, stride, above, left - pxor m1, m1 - movd m2, [aboveq-1] - movq m0, [aboveq] - punpcklbw m2, m1 - punpcklbw m0, m1 ; t1 t2 t3 t4 t5 t6 t7 t8 [word] - pshuflw m2, m2, 0x0 ; [63:0] tl tl tl tl [word] - DEFINE_ARGS dst, stride, line, left - mov lineq, -4 - punpcklqdq m2, m2 ; tl tl tl tl tl tl tl tl [word] - psubw m0, m2 ; t1-tl t2-tl ... t8-tl [word] - movq m2, [leftq] - punpcklbw m2, m1 ; l1 l2 l3 l4 l5 l6 l7 l8 [word] -.loop: - pshuflw m4, m2, 0x0 ; [63:0] l1 l1 l1 l1 [word] - pshuflw m3, m2, 0x55 ; [63:0] l2 l2 l2 l2 [word] - punpcklqdq m4, m4 ; l1 l1 l1 l1 l1 l1 l1 l1 [word] - punpcklqdq m3, m3 ; l2 l2 l2 l2 l2 l2 l2 l2 [word] - paddw m4, m0 - paddw m3, m0 - packuswb m4, m3 - movq [dstq ], m4 - movhps [dstq+strideq], m4 - lea dstq, [dstq+strideq*2] - psrldq m2, 4 - inc lineq - jnz .loop - REP_RET - -INIT_XMM sse2 -cglobal tm_predictor_16x16, 4, 5, 8, dst, stride, above, left - pxor m1, m1 - mova m2, [aboveq-16]; - mova m0, [aboveq] ; t1 t2 ... t16 [byte] - punpckhbw m2, m1 ; [127:112] tl [word] - punpckhbw m4, m0, m1 - punpcklbw m0, m1 ; m0:m4 t1 t2 ... t16 [word] - DEFINE_ARGS dst, stride, line, left, stride8 - mov lineq, -8 - pshufhw m2, m2, 0xff - mova m3, [leftq] ; l1 l2 ... l16 [byte] - punpckhqdq m2, m2 ; tl repeated 8 times [word] - psubw m0, m2 - psubw m4, m2 ; m0:m4 t1-tl t2-tl ... t16-tl [word] - punpckhbw m5, m3, m1 - punpcklbw m3, m1 ; m3:m5 l1 l2 ... l16 [word] - lea stride8q, [strideq*8] -.loop: - pshuflw m6, m3, 0x0 - pshuflw m7, m5, 0x0 - punpcklqdq m6, m6 ; l1 repeated 8 times [word] - punpcklqdq m7, m7 ; l8 repeated 8 times [word] - paddw m1, m6, m0 - paddw m6, m4 ; m1:m6 ti-tl+l1 [i=1,15] [word] - psrldq m5, 2 - packuswb m1, m6 - mova [dstq ], m1 - paddw m1, m7, m0 - paddw m7, m4 ; m1:m7 ti-tl+l8 [i=1,15] [word] - psrldq m3, 2 - packuswb m1, m7 - mova [dstq+stride8q], m1 - inc lineq - lea dstq, [dstq+strideq] - jnz .loop - REP_RET - -INIT_XMM sse2 -cglobal tm_predictor_32x32, 4, 4, 8, dst, stride, above, left - pxor m1, m1 - movd m2, [aboveq-1] - mova m0, [aboveq] - mova m4, [aboveq+16] - punpcklbw m2, m1 - punpckhbw m3, m0, m1 - punpckhbw m5, m4, m1 - punpcklbw m0, m1 - punpcklbw m4, m1 - pshuflw m2, m2, 0x0 - DEFINE_ARGS dst, stride, line, left - mov lineq, -16 - punpcklqdq m2, m2 - add leftq, 32 - psubw m0, m2 - psubw m3, m2 - psubw m4, m2 - psubw m5, m2 -.loop: - movd m2, [leftq+lineq*2] - pxor m1, m1 - punpcklbw m2, m1 - pshuflw m7, m2, 0x55 - pshuflw m2, m2, 0x0 - punpcklqdq m2, m2 - punpcklqdq m7, m7 - paddw m6, m2, m3 - paddw m1, m2, m0 - packuswb m1, m6 - mova [dstq ], m1 - paddw m6, m2, m5 - paddw m1, m2, m4 - packuswb m1, m6 - mova [dstq+16 ], m1 - paddw m6, m7, m3 - paddw m1, m7, m0 - packuswb m1, m6 - mova [dstq+strideq ], m1 - paddw m6, m7, m5 - paddw m1, m7, m4 - packuswb m1, m6 - mova [dstq+strideq+16], m1 - lea dstq, [dstq+strideq*2] - inc lineq - jnz .loop - REP_RET diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/intrapred_ssse3.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/intrapred_ssse3.asm deleted file mode 100644 index 5e0139fa..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/intrapred_ssse3.asm +++ /dev/null @@ -1,871 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "third_party/x86inc/x86inc.asm" - -SECTION_RODATA - -pb_1: times 16 db 1 -sh_b12345677: db 1, 2, 3, 4, 5, 6, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0 -sh_b23456777: db 2, 3, 4, 5, 6, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0 -sh_b0123456777777777: db 0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7 -sh_b1234567777777777: db 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 -sh_b2345677777777777: db 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 -sh_b123456789abcdeff: db 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15 -sh_b23456789abcdefff: db 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15 -sh_b32104567: db 3, 2, 1, 0, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0 -sh_b8091a2b345: db 8, 0, 9, 1, 10, 2, 11, 3, 4, 5, 0, 0, 0, 0, 0, 0 -sh_b76543210: db 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 -sh_b65432108: db 6, 5, 4, 3, 2, 1, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0 -sh_b54321089: db 5, 4, 3, 2, 1, 0, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0 -sh_b89abcdef: db 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0 -sh_bfedcba9876543210: db 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 - -SECTION .text - -INIT_XMM ssse3 -cglobal d45_predictor_16x16, 3, 6, 4, dst, stride, above, dst8, line, goffset - GET_GOT goffsetq - - mova m0, [aboveq] - DEFINE_ARGS dst, stride, stride3, dst8, line - lea stride3q, [strideq*3] - lea dst8q, [dstq+strideq*8] - mova m1, [GLOBAL(sh_b123456789abcdeff)] - pshufb m2, m0, [GLOBAL(sh_b23456789abcdefff)] - pavgb m3, m2, m0 - pxor m2, m0 - pshufb m0, m1 - pand m2, [GLOBAL(pb_1)] - psubb m3, m2 - pavgb m0, m3 - - ; first 4 lines and first half of 3rd 4 lines - mov lined, 2 -.loop: - mova [dstq ], m0 - movhps [dst8q ], m0 - pshufb m0, m1 - mova [dstq +strideq ], m0 - movhps [dst8q+strideq ], m0 - pshufb m0, m1 - mova [dstq +strideq*2 ], m0 - movhps [dst8q+strideq*2 ], m0 - pshufb m0, m1 - mova [dstq +stride3q ], m0 - movhps [dst8q+stride3q ], m0 - pshufb m0, m1 - lea dstq, [dstq +strideq*4] - lea dst8q, [dst8q+strideq*4] - dec lined - jnz .loop - - ; bottom-right 8x8 block - movhps [dstq +8], m0 - movhps [dstq+strideq +8], m0 - movhps [dstq+strideq*2+8], m0 - movhps [dstq+stride3q +8], m0 - lea dstq, [dstq+strideq*4] - movhps [dstq +8], m0 - movhps [dstq+strideq +8], m0 - movhps [dstq+strideq*2+8], m0 - movhps [dstq+stride3q +8], m0 - - RESTORE_GOT - RET - -INIT_XMM ssse3 -cglobal d45_predictor_32x32, 3, 6, 7, dst, stride, above, dst16, line, goffset - GET_GOT goffsetq - - mova m0, [aboveq] - mova m4, [aboveq+16] - DEFINE_ARGS dst, stride, stride3, dst16, line - lea stride3q, [strideq*3] - lea dst16q, [dstq +strideq*8] - lea dst16q, [dst16q+strideq*8] - mova m1, [GLOBAL(sh_b123456789abcdeff)] - pshufb m2, m4, [GLOBAL(sh_b23456789abcdefff)] - pavgb m3, m2, m4 - pxor m2, m4 - palignr m5, m4, m0, 1 - palignr m6, m4, m0, 2 - pshufb m4, m1 - pand m2, [GLOBAL(pb_1)] - psubb m3, m2 - pavgb m4, m3 - pavgb m3, m0, m6 - pxor m0, m6 - pand m0, [GLOBAL(pb_1)] - psubb m3, m0 - pavgb m5, m3 - - ; write 4x4 lines (and the first half of the second 4x4 lines) - mov lined, 4 -.loop: - mova [dstq ], m5 - mova [dstq +16], m4 - mova [dst16q ], m4 - palignr m3, m4, m5, 1 - pshufb m4, m1 - mova [dstq +strideq ], m3 - mova [dstq +strideq +16], m4 - mova [dst16q+strideq ], m4 - palignr m5, m4, m3, 1 - pshufb m4, m1 - mova [dstq +strideq*2 ], m5 - mova [dstq +strideq*2+16], m4 - mova [dst16q+strideq*2 ], m4 - palignr m3, m4, m5, 1 - pshufb m4, m1 - mova [dstq +stride3q ], m3 - mova [dstq +stride3q +16], m4 - mova [dst16q+stride3q ], m4 - palignr m5, m4, m3, 1 - pshufb m4, m1 - lea dstq, [dstq +strideq*4] - lea dst16q, [dst16q+strideq*4] - dec lined - jnz .loop - - ; write second half of second 4x4 lines - mova [dstq +16], m4 - mova [dstq +strideq +16], m4 - mova [dstq +strideq*2+16], m4 - mova [dstq +stride3q +16], m4 - lea dstq, [dstq +strideq*4] - mova [dstq +16], m4 - mova [dstq +strideq +16], m4 - mova [dstq +strideq*2+16], m4 - mova [dstq +stride3q +16], m4 - lea dstq, [dstq +strideq*4] - mova [dstq +16], m4 - mova [dstq +strideq +16], m4 - mova [dstq +strideq*2+16], m4 - mova [dstq +stride3q +16], m4 - lea dstq, [dstq +strideq*4] - mova [dstq +16], m4 - mova [dstq +strideq +16], m4 - mova [dstq +strideq*2+16], m4 - mova [dstq +stride3q +16], m4 - - RESTORE_GOT - RET - -; ------------------------------------------ -; input: x, y, z, result -; -; trick from pascal -; (x+2y+z+2)>>2 can be calculated as: -; result = avg(x,z) -; result -= xor(x,z) & 1 -; result = avg(result,y) -; ------------------------------------------ -%macro X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 4 - pavgb %4, %1, %3 - pxor %3, %1 - pand %3, [GLOBAL(pb_1)] - psubb %4, %3 - pavgb %4, %2 -%endmacro - -INIT_XMM ssse3 -cglobal d63_predictor_4x4, 3, 4, 5, dst, stride, above, goffset - GET_GOT goffsetq - - movq m3, [aboveq] - pshufb m1, m3, [GLOBAL(sh_b23456777)] - pshufb m2, m3, [GLOBAL(sh_b12345677)] - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m3, m2, m1, m4 - pavgb m3, m2 - - ; store 4 lines - movd [dstq ], m3 - movd [dstq+strideq], m4 - lea dstq, [dstq+strideq*2] - psrldq m3, 1 - psrldq m4, 1 - movd [dstq ], m3 - movd [dstq+strideq], m4 - RESTORE_GOT - RET - -INIT_XMM ssse3 -cglobal d63_predictor_8x8, 3, 4, 5, dst, stride, above, goffset - GET_GOT goffsetq - - movq m3, [aboveq] - DEFINE_ARGS dst, stride, stride3 - lea stride3q, [strideq*3] - pshufb m1, m3, [GLOBAL(sh_b2345677777777777)] - pshufb m0, m3, [GLOBAL(sh_b0123456777777777)] - pshufb m2, m3, [GLOBAL(sh_b1234567777777777)] - pshufb m3, [GLOBAL(sh_b0123456777777777)] - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m0, m2, m1, m4 - pavgb m3, m2 - - ; store 4 lines - movq [dstq ], m3 - movq [dstq+strideq], m4 - psrldq m3, 1 - psrldq m4, 1 - movq [dstq+strideq*2], m3 - movq [dstq+stride3q ], m4 - lea dstq, [dstq+strideq*4] - psrldq m3, 1 - psrldq m4, 1 - - ; store 4 lines - movq [dstq ], m3 - movq [dstq+strideq], m4 - psrldq m3, 1 - psrldq m4, 1 - movq [dstq+strideq*2], m3 - movq [dstq+stride3q ], m4 - RESTORE_GOT - RET - -INIT_XMM ssse3 -cglobal d63_predictor_16x16, 3, 5, 5, dst, stride, above, line, goffset - GET_GOT goffsetq - - mova m0, [aboveq] - DEFINE_ARGS dst, stride, stride3, line - lea stride3q, [strideq*3] - mova m1, [GLOBAL(sh_b123456789abcdeff)] - pshufb m2, m0, [GLOBAL(sh_b23456789abcdefff)] - pshufb m3, m0, m1 - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m0, m3, m2, m4 - pavgb m0, m3 - - mov lined, 4 -.loop: - mova [dstq ], m0 - mova [dstq+strideq ], m4 - pshufb m0, m1 - pshufb m4, m1 - mova [dstq+strideq*2], m0 - mova [dstq+stride3q ], m4 - pshufb m0, m1 - pshufb m4, m1 - lea dstq, [dstq+strideq*4] - dec lined - jnz .loop - RESTORE_GOT - REP_RET - -INIT_XMM ssse3 -cglobal d63_predictor_32x32, 3, 5, 8, dst, stride, above, line, goffset - GET_GOT goffsetq - - mova m0, [aboveq] - mova m7, [aboveq+16] - DEFINE_ARGS dst, stride, stride3, line - mova m1, [GLOBAL(sh_b123456789abcdeff)] - lea stride3q, [strideq*3] - pshufb m2, m7, [GLOBAL(sh_b23456789abcdefff)] - pshufb m3, m7, m1 - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m7, m3, m2, m4 - palignr m6, m7, m0, 1 - palignr m5, m7, m0, 2 - pavgb m7, m3 - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m0, m6, m5, m2 - pavgb m0, m6 - - mov lined, 8 -.loop: - mova [dstq ], m0 - mova [dstq +16], m7 - mova [dstq+strideq ], m2 - mova [dstq+strideq +16], m4 - palignr m3, m7, m0, 1 - palignr m5, m4, m2, 1 - pshufb m7, m1 - pshufb m4, m1 - - mova [dstq+strideq*2 ], m3 - mova [dstq+strideq*2+16], m7 - mova [dstq+stride3q ], m5 - mova [dstq+stride3q +16], m4 - palignr m0, m7, m3, 1 - palignr m2, m4, m5, 1 - pshufb m7, m1 - pshufb m4, m1 - lea dstq, [dstq+strideq*4] - dec lined - jnz .loop - RESTORE_GOT - REP_RET - -INIT_XMM ssse3 -cglobal d153_predictor_4x4, 4, 5, 4, dst, stride, above, left, goffset - GET_GOT goffsetq - movd m0, [leftq] ; l1, l2, l3, l4 - movd m1, [aboveq-1] ; tl, t1, t2, t3 - punpckldq m0, m1 ; l1, l2, l3, l4, tl, t1, t2, t3 - pshufb m0, [GLOBAL(sh_b32104567)]; l4, l3, l2, l1, tl, t1, t2, t3 - psrldq m1, m0, 1 ; l3, l2, l1, tl, t1, t2, t3 - psrldq m2, m0, 2 ; l2, l1, tl, t1, t2, t3 - ; comments below are for a predictor like this - ; A1 B1 C1 D1 - ; A2 B2 A1 B1 - ; A3 B3 A2 B2 - ; A4 B4 A3 B3 - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m0, m1, m2, m3 ; 3-tap avg B4 B3 B2 B1 C1 D1 - pavgb m1, m0 ; 2-tap avg A4 A3 A2 A1 - - punpcklqdq m3, m1 ; B4 B3 B2 B1 C1 D1 x x A4 A3 A2 A1 .. - - DEFINE_ARGS dst, stride, stride3 - lea stride3q, [strideq*3] - pshufb m3, [GLOBAL(sh_b8091a2b345)] ; A4 B4 A3 B3 A2 B2 A1 B1 C1 D1 .. - movd [dstq+stride3q ], m3 - psrldq m3, 2 ; A3 B3 A2 B2 A1 B1 C1 D1 .. - movd [dstq+strideq*2], m3 - psrldq m3, 2 ; A2 B2 A1 B1 C1 D1 .. - movd [dstq+strideq ], m3 - psrldq m3, 2 ; A1 B1 C1 D1 .. - movd [dstq ], m3 - RESTORE_GOT - RET - -INIT_XMM ssse3 -cglobal d153_predictor_8x8, 4, 5, 8, dst, stride, above, left, goffset - GET_GOT goffsetq - movq m0, [leftq] ; [0- 7] l1-8 [byte] - movhps m0, [aboveq-1] ; [8-15] tl, t1-7 [byte] - pshufb m1, m0, [GLOBAL(sh_b76543210)] ; l8-1 [word] - pshufb m2, m0, [GLOBAL(sh_b65432108)] ; l7-1,tl [word] - pshufb m3, m0, [GLOBAL(sh_b54321089)] ; l6-1,tl,t1 [word] - pshufb m0, [GLOBAL(sh_b89abcdef)] ; tl,t1-7 [word] - psrldq m4, m0, 1 ; t1-7 [word] - psrldq m5, m0, 2 ; t2-7 [word] - ; comments below are for a predictor like this - ; A1 B1 C1 D1 E1 F1 G1 H1 - ; A2 B2 A1 B1 C1 D1 E1 F1 - ; A3 B3 A2 B2 A1 B1 C1 D1 - ; A4 B4 A3 B3 A2 B2 A1 B1 - ; A5 B5 A4 B4 A3 B3 A2 B2 - ; A6 B6 A5 B5 A4 B4 A3 B3 - ; A7 B7 A6 B6 A5 B5 A4 B4 - ; A8 B8 A7 B7 A6 B6 A5 B5 - pavgb m6, m1, m2 ; 2-tap avg A8-A1 - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m0, m4, m5, m7 ; 3-tap avg C-H1 - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m1, m2, m3, m0 ; 3-tap avg B8-1 - - punpcklbw m6, m0 ; A-B8, A-B7 ... A-B2, A-B1 - - DEFINE_ARGS dst, stride, stride3 - lea stride3q, [strideq*3] - - movhps [dstq+stride3q], m6 ; A-B4, A-B3, A-B2, A-B1 - palignr m0, m7, m6, 10 ; A-B3, A-B2, A-B1, C-H1 - movq [dstq+strideq*2], m0 - psrldq m0, 2 ; A-B2, A-B1, C-H1 - movq [dstq+strideq ], m0 - psrldq m0, 2 ; A-H1 - movq [dstq ], m0 - lea dstq, [dstq+strideq*4] - movq [dstq+stride3q ], m6 ; A-B8, A-B7, A-B6, A-B5 - psrldq m6, 2 ; A-B7, A-B6, A-B5, A-B4 - movq [dstq+strideq*2], m6 - psrldq m6, 2 ; A-B6, A-B5, A-B4, A-B3 - movq [dstq+strideq ], m6 - psrldq m6, 2 ; A-B5, A-B4, A-B3, A-B2 - movq [dstq ], m6 - RESTORE_GOT - RET - -INIT_XMM ssse3 -cglobal d153_predictor_16x16, 4, 5, 8, dst, stride, above, left, goffset - GET_GOT goffsetq - mova m0, [leftq] - movu m7, [aboveq-1] - ; comments below are for a predictor like this - ; A1 B1 C1 D1 E1 F1 G1 H1 I1 J1 K1 L1 M1 N1 O1 P1 - ; A2 B2 A1 B1 C1 D1 E1 F1 G1 H1 I1 J1 K1 L1 M1 N1 - ; A3 B3 A2 B2 A1 B1 C1 D1 E1 F1 G1 H1 I1 J1 K1 L1 - ; A4 B4 A3 B3 A2 B2 A1 B1 C1 D1 E1 F1 G1 H1 I1 J1 - ; A5 B5 A4 B4 A3 B3 A2 B2 A1 B1 C1 D1 E1 F1 G1 H1 - ; A6 B6 A5 B5 A4 B4 A3 B3 A2 B2 A1 B1 C1 D1 E1 F1 - ; A7 B7 A6 B6 A5 B5 A4 B4 A3 B3 A2 B2 A1 B1 C1 D1 - ; A8 B8 A7 B7 A6 B6 A5 B5 A4 B4 A3 B3 A2 B2 A1 B1 - ; A9 B9 A8 B8 A7 B7 A6 B6 A5 B5 A4 B4 A3 B3 A2 B2 - ; Aa Ba A9 B9 A8 B8 A7 B7 A6 B6 A5 B5 A4 B4 A3 B3 - ; Ab Bb Aa Ba A9 B9 A8 B8 A7 B7 A6 B6 A5 B5 A4 B4 - ; Ac Bc Ab Bb Aa Ba A9 B9 A8 B8 A7 B7 A6 B6 A5 B5 - ; Ad Bd Ac Bc Ab Bb Aa Ba A9 B9 A8 B8 A7 B7 A6 B6 - ; Ae Be Ad Bd Ac Bc Ab Bb Aa Ba A9 B9 A8 B8 A7 B7 - ; Af Bf Ae Be Ad Bd Ac Bc Ab Bb Aa Ba A9 B9 A8 B8 - ; Ag Bg Af Bf Ae Be Ad Bd Ac Bc Ab Bb Aa Ba A9 B9 - pshufb m6, m7, [GLOBAL(sh_bfedcba9876543210)] - palignr m5, m0, m6, 15 - palignr m3, m0, m6, 14 - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m0, m5, m3, m4 ; 3-tap avg B3-Bg - pshufb m1, m0, [GLOBAL(sh_b123456789abcdeff)] - pavgb m5, m0 ; A1 - Ag - - punpcklbw m0, m4, m5 ; A-B8 ... A-B1 - punpckhbw m4, m5 ; A-B9 ... A-Bg - - pshufb m3, m7, [GLOBAL(sh_b123456789abcdeff)] - pshufb m5, m7, [GLOBAL(sh_b23456789abcdefff)] - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m7, m3, m5, m1 ; 3-tap avg C1-P1 - - pshufb m6, m0, [GLOBAL(sh_bfedcba9876543210)] - DEFINE_ARGS dst, stride, stride3 - lea stride3q, [strideq*3] - palignr m2, m1, m6, 14 - mova [dstq ], m2 - palignr m2, m1, m6, 12 - mova [dstq+strideq ], m2 - palignr m2, m1, m6, 10 - mova [dstq+strideq*2], m2 - palignr m2, m1, m6, 8 - mova [dstq+stride3q ], m2 - lea dstq, [dstq+strideq*4] - palignr m2, m1, m6, 6 - mova [dstq ], m2 - palignr m2, m1, m6, 4 - mova [dstq+strideq ], m2 - palignr m2, m1, m6, 2 - mova [dstq+strideq*2], m2 - pshufb m4, [GLOBAL(sh_bfedcba9876543210)] - mova [dstq+stride3q ], m6 - lea dstq, [dstq+strideq*4] - - palignr m2, m6, m4, 14 - mova [dstq ], m2 - palignr m2, m6, m4, 12 - mova [dstq+strideq ], m2 - palignr m2, m6, m4, 10 - mova [dstq+strideq*2], m2 - palignr m2, m6, m4, 8 - mova [dstq+stride3q ], m2 - lea dstq, [dstq+strideq*4] - palignr m2, m6, m4, 6 - mova [dstq ], m2 - palignr m2, m6, m4, 4 - mova [dstq+strideq ], m2 - palignr m2, m6, m4, 2 - mova [dstq+strideq*2], m2 - mova [dstq+stride3q ], m4 - RESTORE_GOT - RET - -INIT_XMM ssse3 -cglobal d153_predictor_32x32, 4, 5, 8, dst, stride, above, left, goffset - GET_GOT goffsetq - mova m0, [leftq] - movu m7, [aboveq-1] - movu m1, [aboveq+15] - - pshufb m4, m1, [GLOBAL(sh_b123456789abcdeff)] - pshufb m6, m1, [GLOBAL(sh_b23456789abcdefff)] - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m1, m4, m6, m2 ; 3-tap avg above [high] - - palignr m3, m1, m7, 1 - palignr m5, m1, m7, 2 - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m7, m3, m5, m1 ; 3-tap avg above [low] - - pshufb m7, [GLOBAL(sh_bfedcba9876543210)] - palignr m5, m0, m7, 15 - palignr m3, m0, m7, 14 - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m0, m5, m3, m4 ; 3-tap avg B3-Bg - pavgb m5, m0 ; A1 - Ag - punpcklbw m6, m4, m5 ; A-B8 ... A-B1 - punpckhbw m4, m5 ; A-B9 ... A-Bg - pshufb m6, [GLOBAL(sh_bfedcba9876543210)] - pshufb m4, [GLOBAL(sh_bfedcba9876543210)] - - DEFINE_ARGS dst, stride, stride3, left, line - lea stride3q, [strideq*3] - - palignr m5, m2, m1, 14 - palignr m7, m1, m6, 14 - mova [dstq ], m7 - mova [dstq+16 ], m5 - palignr m5, m2, m1, 12 - palignr m7, m1, m6, 12 - mova [dstq+strideq ], m7 - mova [dstq+strideq+16 ], m5 - palignr m5, m2, m1, 10 - palignr m7, m1, m6, 10 - mova [dstq+strideq*2 ], m7 - mova [dstq+strideq*2+16], m5 - palignr m5, m2, m1, 8 - palignr m7, m1, m6, 8 - mova [dstq+stride3q ], m7 - mova [dstq+stride3q+16 ], m5 - lea dstq, [dstq+strideq*4] - palignr m5, m2, m1, 6 - palignr m7, m1, m6, 6 - mova [dstq ], m7 - mova [dstq+16 ], m5 - palignr m5, m2, m1, 4 - palignr m7, m1, m6, 4 - mova [dstq+strideq ], m7 - mova [dstq+strideq+16 ], m5 - palignr m5, m2, m1, 2 - palignr m7, m1, m6, 2 - mova [dstq+strideq*2 ], m7 - mova [dstq+strideq*2+16], m5 - mova [dstq+stride3q ], m6 - mova [dstq+stride3q+16 ], m1 - lea dstq, [dstq+strideq*4] - - palignr m5, m1, m6, 14 - palignr m3, m6, m4, 14 - mova [dstq ], m3 - mova [dstq+16 ], m5 - palignr m5, m1, m6, 12 - palignr m3, m6, m4, 12 - mova [dstq+strideq ], m3 - mova [dstq+strideq+16 ], m5 - palignr m5, m1, m6, 10 - palignr m3, m6, m4, 10 - mova [dstq+strideq*2 ], m3 - mova [dstq+strideq*2+16], m5 - palignr m5, m1, m6, 8 - palignr m3, m6, m4, 8 - mova [dstq+stride3q ], m3 - mova [dstq+stride3q+16 ], m5 - lea dstq, [dstq+strideq*4] - palignr m5, m1, m6, 6 - palignr m3, m6, m4, 6 - mova [dstq ], m3 - mova [dstq+16 ], m5 - palignr m5, m1, m6, 4 - palignr m3, m6, m4, 4 - mova [dstq+strideq ], m3 - mova [dstq+strideq+16 ], m5 - palignr m5, m1, m6, 2 - palignr m3, m6, m4, 2 - mova [dstq+strideq*2 ], m3 - mova [dstq+strideq*2+16], m5 - mova [dstq+stride3q ], m4 - mova [dstq+stride3q+16 ], m6 - lea dstq, [dstq+strideq*4] - - mova m7, [leftq] - mova m3, [leftq+16] - palignr m5, m3, m7, 15 - palignr m0, m3, m7, 14 - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m3, m5, m0, m2 ; 3-tap avg Bh - - pavgb m5, m3 ; Ah - - punpcklbw m3, m2, m5 ; A-B8 ... A-B1 - punpckhbw m2, m5 ; A-B9 ... A-Bg - pshufb m3, [GLOBAL(sh_bfedcba9876543210)] - pshufb m2, [GLOBAL(sh_bfedcba9876543210)] - - palignr m7, m6, m4, 14 - palignr m0, m4, m3, 14 - mova [dstq ], m0 - mova [dstq+16 ], m7 - palignr m7, m6, m4, 12 - palignr m0, m4, m3, 12 - mova [dstq+strideq ], m0 - mova [dstq+strideq+16 ], m7 - palignr m7, m6, m4, 10 - palignr m0, m4, m3, 10 - mova [dstq+strideq*2 ], m0 - mova [dstq+strideq*2+16], m7 - palignr m7, m6, m4, 8 - palignr m0, m4, m3, 8 - mova [dstq+stride3q ], m0 - mova [dstq+stride3q+16 ], m7 - lea dstq, [dstq+strideq*4] - palignr m7, m6, m4, 6 - palignr m0, m4, m3, 6 - mova [dstq ], m0 - mova [dstq+16 ], m7 - palignr m7, m6, m4, 4 - palignr m0, m4, m3, 4 - mova [dstq+strideq ], m0 - mova [dstq+strideq+16 ], m7 - palignr m7, m6, m4, 2 - palignr m0, m4, m3, 2 - mova [dstq+strideq*2 ], m0 - mova [dstq+strideq*2+16], m7 - mova [dstq+stride3q ], m3 - mova [dstq+stride3q+16 ], m4 - lea dstq, [dstq+strideq*4] - - palignr m7, m4, m3, 14 - palignr m0, m3, m2, 14 - mova [dstq ], m0 - mova [dstq+16 ], m7 - palignr m7, m4, m3, 12 - palignr m0, m3, m2, 12 - mova [dstq+strideq ], m0 - mova [dstq+strideq+16 ], m7 - palignr m7, m4, m3, 10 - palignr m0, m3, m2, 10 - mova [dstq+strideq*2 ], m0 - mova [dstq+strideq*2+16], m7 - palignr m7, m4, m3, 8 - palignr m0, m3, m2, 8 - mova [dstq+stride3q ], m0 - mova [dstq+stride3q+16 ], m7 - lea dstq, [dstq+strideq*4] - palignr m7, m4, m3, 6 - palignr m0, m3, m2, 6 - mova [dstq ], m0 - mova [dstq+16 ], m7 - palignr m7, m4, m3, 4 - palignr m0, m3, m2, 4 - mova [dstq+strideq ], m0 - mova [dstq+strideq+16 ], m7 - palignr m7, m4, m3, 2 - palignr m0, m3, m2, 2 - mova [dstq+strideq*2 ], m0 - mova [dstq+strideq*2+16], m7 - mova [dstq+stride3q ], m2 - mova [dstq+stride3q+16 ], m3 - - RESTORE_GOT - RET - -INIT_XMM ssse3 -cglobal d207_predictor_8x8, 4, 5, 4, dst, stride, stride3, left, goffset - GET_GOT goffsetq - movq m3, [leftq] ; abcdefgh [byte] - lea stride3q, [strideq*3] - - pshufb m1, m3, [GLOBAL(sh_b2345677777777777)] - pshufb m0, m3, [GLOBAL(sh_b0123456777777777)] - pshufb m2, m3, [GLOBAL(sh_b1234567777777777)] - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m0, m2, m1, m3 - pavgb m0, m2 - punpcklbw m0, m3 ; interleaved output - - movq [dstq ], m0 - psrldq m0, 2 - movq [dstq+strideq ], m0 - psrldq m0, 2 - movq [dstq+strideq*2], m0 - psrldq m0, 2 - movq [dstq+stride3q ], m0 - lea dstq, [dstq+strideq*4] - pshufhw m0, m0, q0000 ; de, d2ef, ef, e2fg, fg, f2gh, gh, g3h, 8xh - psrldq m0, 2 - movq [dstq ], m0 - psrldq m0, 2 - movq [dstq+strideq ], m0 - psrldq m0, 2 - movq [dstq+strideq*2], m0 - psrldq m0, 2 - movq [dstq+stride3q ], m0 - RESTORE_GOT - RET - -INIT_XMM ssse3 -cglobal d207_predictor_16x16, 4, 5, 5, dst, stride, stride3, left, goffset - GET_GOT goffsetq - lea stride3q, [strideq*3] - mova m0, [leftq] ; abcdefghijklmnop [byte] - pshufb m1, m0, [GLOBAL(sh_b123456789abcdeff)] ; bcdefghijklmnopp - pshufb m2, m0, [GLOBAL(sh_b23456789abcdefff)] - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m0, m1, m2, m3 - pavgb m1, m0 ; ab, bc, cd .. no, op, pp [byte] - - punpckhbw m4, m1, m3 ; interleaved input - punpcklbw m1, m3 ; interleaved output - mova [dstq ], m1 - palignr m3, m4, m1, 2 - mova [dstq+strideq ], m3 - palignr m3, m4, m1, 4 - mova [dstq+strideq*2], m3 - palignr m3, m4, m1, 6 - mova [dstq+stride3q ], m3 - lea dstq, [dstq+strideq*4] - palignr m3, m4, m1, 8 - mova [dstq ], m3 - palignr m3, m4, m1, 10 - mova [dstq+strideq ], m3 - palignr m3, m4, m1, 12 - mova [dstq+strideq*2], m3 - palignr m3, m4, m1, 14 - mova [dstq+stride3q ], m3 - DEFINE_ARGS dst, stride, stride3, line - mov lined, 2 - mova m0, [GLOBAL(sh_b23456789abcdefff)] -.loop: - lea dstq, [dstq+strideq*4] - mova [dstq ], m4 - pshufb m4, m0 - mova [dstq+strideq ], m4 - pshufb m4, m0 - mova [dstq+strideq*2], m4 - pshufb m4, m0 - mova [dstq+stride3q ], m4 - pshufb m4, m0 - dec lined - jnz .loop - RESTORE_GOT - REP_RET - -INIT_XMM ssse3 -cglobal d207_predictor_32x32, 4, 5, 8, dst, stride, stride3, left, goffset - GET_GOT goffsetq - lea stride3q, [strideq*3] - mova m1, [leftq] ; 0-15 [byte] - mova m2, [leftq+16] ; 16-31 [byte] - pshufb m0, m2, [GLOBAL(sh_b23456789abcdefff)] - pshufb m4, m2, [GLOBAL(sh_b123456789abcdeff)] - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m2, m4, m0, m3 - palignr m6, m2, m1, 1 - palignr m5, m2, m1, 2 - pavgb m2, m4 ; high 16px even lines - - X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 m1, m6, m5, m0 - pavgb m1, m6 ; low 16px even lines - - punpckhbw m6, m1, m0 ; interleaved output 2 - punpcklbw m1, m0 ; interleaved output 1 - - punpckhbw m7, m2, m3 ; interleaved output 4 - punpcklbw m2, m3 ; interleaved output 3 - - ; output 1st 8 lines (and half of 2nd 8 lines) - DEFINE_ARGS dst, stride, stride3, dst8 - lea dst8q, [dstq+strideq*8] - mova [dstq ], m1 - mova [dstq +16], m6 - mova [dst8q ], m6 - palignr m0, m6, m1, 2 - palignr m4, m2, m6, 2 - mova [dstq +strideq ], m0 - mova [dstq +strideq +16], m4 - mova [dst8q+strideq ], m4 - palignr m0, m6, m1, 4 - palignr m4, m2, m6, 4 - mova [dstq +strideq*2 ], m0 - mova [dstq +strideq*2+16], m4 - mova [dst8q+strideq*2 ], m4 - palignr m0, m6, m1, 6 - palignr m4, m2, m6, 6 - mova [dstq +stride3q ], m0 - mova [dstq +stride3q +16], m4 - mova [dst8q+stride3q ], m4 - lea dstq, [dstq +strideq*4] - lea dst8q, [dst8q+strideq*4] - palignr m0, m6, m1, 8 - palignr m4, m2, m6, 8 - mova [dstq ], m0 - mova [dstq +16], m4 - mova [dst8q ], m4 - palignr m0, m6, m1, 10 - palignr m4, m2, m6, 10 - mova [dstq +strideq ], m0 - mova [dstq +strideq +16], m4 - mova [dst8q+strideq ], m4 - palignr m0, m6, m1, 12 - palignr m4, m2, m6, 12 - mova [dstq +strideq*2 ], m0 - mova [dstq +strideq*2+16], m4 - mova [dst8q+strideq*2 ], m4 - palignr m0, m6, m1, 14 - palignr m4, m2, m6, 14 - mova [dstq +stride3q ], m0 - mova [dstq +stride3q +16], m4 - mova [dst8q+stride3q ], m4 - lea dstq, [dstq+strideq*4] - lea dst8q, [dst8q+strideq*4] - - ; output 2nd half of 2nd 8 lines and half of 3rd 8 lines - mova [dstq +16], m2 - mova [dst8q ], m2 - palignr m4, m7, m2, 2 - mova [dstq +strideq +16], m4 - mova [dst8q+strideq ], m4 - palignr m4, m7, m2, 4 - mova [dstq +strideq*2+16], m4 - mova [dst8q+strideq*2 ], m4 - palignr m4, m7, m2, 6 - mova [dstq +stride3q +16], m4 - mova [dst8q+stride3q ], m4 - lea dstq, [dstq+strideq*4] - lea dst8q, [dst8q+strideq*4] - palignr m4, m7, m2, 8 - mova [dstq +16], m4 - mova [dst8q ], m4 - palignr m4, m7, m2, 10 - mova [dstq +strideq +16], m4 - mova [dst8q+strideq ], m4 - palignr m4, m7, m2, 12 - mova [dstq +strideq*2+16], m4 - mova [dst8q+strideq*2 ], m4 - palignr m4, m7, m2, 14 - mova [dstq +stride3q +16], m4 - mova [dst8q+stride3q ], m4 - lea dstq, [dstq+strideq*4] - lea dst8q, [dst8q+strideq*4] - - ; output 2nd half of 3rd 8 lines and half of 4th 8 lines - mova m0, [GLOBAL(sh_b23456789abcdefff)] - mova [dstq +16], m7 - mova [dst8q ], m7 - pshufb m7, m0 - mova [dstq +strideq +16], m7 - mova [dst8q+strideq ], m7 - pshufb m7, m0 - mova [dstq +strideq*2+16], m7 - mova [dst8q+strideq*2 ], m7 - pshufb m7, m0 - mova [dstq +stride3q +16], m7 - mova [dst8q+stride3q ], m7 - pshufb m7, m0 - lea dstq, [dstq+strideq*4] - lea dst8q, [dst8q+strideq*4] - mova [dstq +16], m7 - mova [dst8q ], m7 - pshufb m7, m0 - mova [dstq +strideq +16], m7 - mova [dst8q+strideq ], m7 - pshufb m7, m0 - mova [dstq +strideq*2+16], m7 - mova [dst8q+strideq*2 ], m7 - pshufb m7, m0 - mova [dstq +stride3q +16], m7 - mova [dst8q+stride3q ], m7 - pshufb m7, m0 - lea dstq, [dstq+strideq*4] - - ; output last half of 4th 8 lines - mova [dstq +16], m7 - mova [dstq +strideq +16], m7 - mova [dstq +strideq*2+16], m7 - mova [dstq +stride3q +16], m7 - lea dstq, [dstq+strideq*4] - mova [dstq +16], m7 - mova [dstq +strideq +16], m7 - mova [dstq +strideq*2+16], m7 - mova [dstq +stride3q +16], m7 - - ; done! - RESTORE_GOT - RET diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_txfm_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_txfm_avx2.c deleted file mode 100644 index 752435d2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_txfm_avx2.c +++ /dev/null @@ -1,626 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // AVX2 - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/txfm_common.h" - -#define PAIR256_SET_EPI16(a, b) \ - _mm256_set_epi16((int16_t)(b), (int16_t)(a), (int16_t)(b), (int16_t)(a), \ - (int16_t)(b), (int16_t)(a), (int16_t)(b), (int16_t)(a), \ - (int16_t)(b), (int16_t)(a), (int16_t)(b), (int16_t)(a), \ - (int16_t)(b), (int16_t)(a), (int16_t)(b), (int16_t)(a)) - -static INLINE void idct_load16x16(const tran_low_t *input, __m256i *in, - int stride) { - int i; - // Load 16x16 values - for (i = 0; i < 16; i++) { -#if CONFIG_VP9_HIGHBITDEPTH - const __m128i in0 = _mm_loadu_si128((const __m128i *)(input + i * stride)); - const __m128i in1 = - _mm_loadu_si128((const __m128i *)((input + i * stride) + 4)); - const __m128i in2 = - _mm_loadu_si128((const __m128i *)((input + i * stride) + 8)); - const __m128i in3 = - _mm_loadu_si128((const __m128i *)((input + i * stride) + 12)); - const __m128i ls = _mm_packs_epi32(in0, in1); - const __m128i rs = _mm_packs_epi32(in2, in3); - in[i] = _mm256_inserti128_si256(_mm256_castsi128_si256(ls), rs, 1); -#else - in[i] = _mm256_load_si256((const __m256i *)(input + i * stride)); -#endif - } -} - -static INLINE __m256i dct_round_shift_avx2(__m256i in) { - const __m256i t = _mm256_add_epi32(in, _mm256_set1_epi32(DCT_CONST_ROUNDING)); - return _mm256_srai_epi32(t, DCT_CONST_BITS); -} - -static INLINE __m256i idct_madd_round_shift_avx2(__m256i *in, __m256i *cospi) { - const __m256i t = _mm256_madd_epi16(*in, *cospi); - return dct_round_shift_avx2(t); -} - -// Calculate the dot product between in0/1 and x and wrap to short. -static INLINE __m256i idct_calc_wraplow_avx2(__m256i *in0, __m256i *in1, - __m256i *x) { - const __m256i t0 = idct_madd_round_shift_avx2(in0, x); - const __m256i t1 = idct_madd_round_shift_avx2(in1, x); - return _mm256_packs_epi32(t0, t1); -} - -// Multiply elements by constants and add them together. -static INLINE void butterfly16(__m256i in0, __m256i in1, int c0, int c1, - __m256i *out0, __m256i *out1) { - __m256i cst0 = PAIR256_SET_EPI16(c0, -c1); - __m256i cst1 = PAIR256_SET_EPI16(c1, c0); - __m256i lo = _mm256_unpacklo_epi16(in0, in1); - __m256i hi = _mm256_unpackhi_epi16(in0, in1); - *out0 = idct_calc_wraplow_avx2(&lo, &hi, &cst0); - *out1 = idct_calc_wraplow_avx2(&lo, &hi, &cst1); -} - -static INLINE void idct16_16col(__m256i *in, __m256i *out) { - __m256i step1[16], step2[16]; - - // stage 2 - butterfly16(in[1], in[15], cospi_30_64, cospi_2_64, &step2[8], &step2[15]); - butterfly16(in[9], in[7], cospi_14_64, cospi_18_64, &step2[9], &step2[14]); - butterfly16(in[5], in[11], cospi_22_64, cospi_10_64, &step2[10], &step2[13]); - butterfly16(in[13], in[3], cospi_6_64, cospi_26_64, &step2[11], &step2[12]); - - // stage 3 - butterfly16(in[2], in[14], cospi_28_64, cospi_4_64, &step1[4], &step1[7]); - butterfly16(in[10], in[6], cospi_12_64, cospi_20_64, &step1[5], &step1[6]); - step1[8] = _mm256_add_epi16(step2[8], step2[9]); - step1[9] = _mm256_sub_epi16(step2[8], step2[9]); - step1[10] = _mm256_sub_epi16(step2[11], step2[10]); - step1[11] = _mm256_add_epi16(step2[10], step2[11]); - step1[12] = _mm256_add_epi16(step2[12], step2[13]); - step1[13] = _mm256_sub_epi16(step2[12], step2[13]); - step1[14] = _mm256_sub_epi16(step2[15], step2[14]); - step1[15] = _mm256_add_epi16(step2[14], step2[15]); - - // stage 4 - butterfly16(in[0], in[8], cospi_16_64, cospi_16_64, &step2[1], &step2[0]); - butterfly16(in[4], in[12], cospi_24_64, cospi_8_64, &step2[2], &step2[3]); - butterfly16(step1[14], step1[9], cospi_24_64, cospi_8_64, &step2[9], - &step2[14]); - butterfly16(step1[10], step1[13], -cospi_8_64, -cospi_24_64, &step2[13], - &step2[10]); - step2[5] = _mm256_sub_epi16(step1[4], step1[5]); - step1[4] = _mm256_add_epi16(step1[4], step1[5]); - step2[6] = _mm256_sub_epi16(step1[7], step1[6]); - step1[7] = _mm256_add_epi16(step1[6], step1[7]); - step2[8] = step1[8]; - step2[11] = step1[11]; - step2[12] = step1[12]; - step2[15] = step1[15]; - - // stage 5 - step1[0] = _mm256_add_epi16(step2[0], step2[3]); - step1[1] = _mm256_add_epi16(step2[1], step2[2]); - step1[2] = _mm256_sub_epi16(step2[1], step2[2]); - step1[3] = _mm256_sub_epi16(step2[0], step2[3]); - butterfly16(step2[6], step2[5], cospi_16_64, cospi_16_64, &step1[5], - &step1[6]); - step1[8] = _mm256_add_epi16(step2[8], step2[11]); - step1[9] = _mm256_add_epi16(step2[9], step2[10]); - step1[10] = _mm256_sub_epi16(step2[9], step2[10]); - step1[11] = _mm256_sub_epi16(step2[8], step2[11]); - step1[12] = _mm256_sub_epi16(step2[15], step2[12]); - step1[13] = _mm256_sub_epi16(step2[14], step2[13]); - step1[14] = _mm256_add_epi16(step2[14], step2[13]); - step1[15] = _mm256_add_epi16(step2[15], step2[12]); - - // stage 6 - step2[0] = _mm256_add_epi16(step1[0], step1[7]); - step2[1] = _mm256_add_epi16(step1[1], step1[6]); - step2[2] = _mm256_add_epi16(step1[2], step1[5]); - step2[3] = _mm256_add_epi16(step1[3], step1[4]); - step2[4] = _mm256_sub_epi16(step1[3], step1[4]); - step2[5] = _mm256_sub_epi16(step1[2], step1[5]); - step2[6] = _mm256_sub_epi16(step1[1], step1[6]); - step2[7] = _mm256_sub_epi16(step1[0], step1[7]); - butterfly16(step1[13], step1[10], cospi_16_64, cospi_16_64, &step2[10], - &step2[13]); - butterfly16(step1[12], step1[11], cospi_16_64, cospi_16_64, &step2[11], - &step2[12]); - - // stage 7 - out[0] = _mm256_add_epi16(step2[0], step1[15]); - out[1] = _mm256_add_epi16(step2[1], step1[14]); - out[2] = _mm256_add_epi16(step2[2], step2[13]); - out[3] = _mm256_add_epi16(step2[3], step2[12]); - out[4] = _mm256_add_epi16(step2[4], step2[11]); - out[5] = _mm256_add_epi16(step2[5], step2[10]); - out[6] = _mm256_add_epi16(step2[6], step1[9]); - out[7] = _mm256_add_epi16(step2[7], step1[8]); - out[8] = _mm256_sub_epi16(step2[7], step1[8]); - out[9] = _mm256_sub_epi16(step2[6], step1[9]); - out[10] = _mm256_sub_epi16(step2[5], step2[10]); - out[11] = _mm256_sub_epi16(step2[4], step2[11]); - out[12] = _mm256_sub_epi16(step2[3], step2[12]); - out[13] = _mm256_sub_epi16(step2[2], step2[13]); - out[14] = _mm256_sub_epi16(step2[1], step1[14]); - out[15] = _mm256_sub_epi16(step2[0], step1[15]); -} - -static INLINE void recon_and_store16(uint8_t *dest, __m256i in_x) { - const __m256i zero = _mm256_setzero_si256(); - __m256i d0 = _mm256_castsi128_si256(_mm_loadu_si128((__m128i *)(dest))); - d0 = _mm256_permute4x64_epi64(d0, 0xd8); - d0 = _mm256_unpacklo_epi8(d0, zero); - d0 = _mm256_add_epi16(in_x, d0); - d0 = _mm256_packus_epi16( - d0, _mm256_castsi128_si256(_mm256_extractf128_si256(d0, 1))); - - _mm_storeu_si128((__m128i *)dest, _mm256_castsi256_si128(d0)); -} - -static INLINE void write_buffer_16x1(uint8_t *dest, __m256i in) { - const __m256i final_rounding = _mm256_set1_epi16(1 << 5); - __m256i out; - out = _mm256_adds_epi16(in, final_rounding); - out = _mm256_srai_epi16(out, 6); - recon_and_store16(dest, out); -} - -static INLINE void store_buffer_16x32(__m256i *in, uint8_t *dst, int stride) { - const __m256i final_rounding = _mm256_set1_epi16(1 << 5); - int j = 0; - while (j < 32) { - in[j] = _mm256_adds_epi16(in[j], final_rounding); - in[j + 1] = _mm256_adds_epi16(in[j + 1], final_rounding); - - in[j] = _mm256_srai_epi16(in[j], 6); - in[j + 1] = _mm256_srai_epi16(in[j + 1], 6); - - recon_and_store16(dst, in[j]); - dst += stride; - recon_and_store16(dst, in[j + 1]); - dst += stride; - j += 2; - } -} - -static INLINE void transpose2_8x8_avx2(__m256i *in, __m256i *out) { - int i; - __m256i t[16], u[16]; - // (1st, 2nd) ==> (lo, hi) - // (0, 1) ==> (0, 1) - // (2, 3) ==> (2, 3) - // (4, 5) ==> (4, 5) - // (6, 7) ==> (6, 7) - for (i = 0; i < 4; i++) { - t[2 * i] = _mm256_unpacklo_epi16(in[2 * i], in[2 * i + 1]); - t[2 * i + 1] = _mm256_unpackhi_epi16(in[2 * i], in[2 * i + 1]); - } - - // (1st, 2nd) ==> (lo, hi) - // (0, 2) ==> (0, 2) - // (1, 3) ==> (1, 3) - // (4, 6) ==> (4, 6) - // (5, 7) ==> (5, 7) - for (i = 0; i < 2; i++) { - u[i] = _mm256_unpacklo_epi32(t[i], t[i + 2]); - u[i + 2] = _mm256_unpackhi_epi32(t[i], t[i + 2]); - - u[i + 4] = _mm256_unpacklo_epi32(t[i + 4], t[i + 6]); - u[i + 6] = _mm256_unpackhi_epi32(t[i + 4], t[i + 6]); - } - - // (1st, 2nd) ==> (lo, hi) - // (0, 4) ==> (0, 1) - // (1, 5) ==> (4, 5) - // (2, 6) ==> (2, 3) - // (3, 7) ==> (6, 7) - for (i = 0; i < 2; i++) { - out[2 * i] = _mm256_unpacklo_epi64(u[2 * i], u[2 * i + 4]); - out[2 * i + 1] = _mm256_unpackhi_epi64(u[2 * i], u[2 * i + 4]); - - out[2 * i + 4] = _mm256_unpacklo_epi64(u[2 * i + 1], u[2 * i + 5]); - out[2 * i + 5] = _mm256_unpackhi_epi64(u[2 * i + 1], u[2 * i + 5]); - } -} - -static INLINE void transpose_16bit_16x16_avx2(__m256i *in, __m256i *out) { - __m256i t[16]; - -#define LOADL(idx) \ - t[idx] = _mm256_castsi128_si256(_mm_load_si128((__m128i const *)&in[idx])); \ - t[idx] = _mm256_inserti128_si256( \ - t[idx], _mm_load_si128((__m128i const *)&in[(idx) + 8]), 1); - -#define LOADR(idx) \ - t[8 + (idx)] = \ - _mm256_castsi128_si256(_mm_load_si128((__m128i const *)&in[idx] + 1)); \ - t[8 + (idx)] = _mm256_inserti128_si256( \ - t[8 + (idx)], _mm_load_si128((__m128i const *)&in[(idx) + 8] + 1), 1); - - // load left 8x16 - LOADL(0) - LOADL(1) - LOADL(2) - LOADL(3) - LOADL(4) - LOADL(5) - LOADL(6) - LOADL(7) - - // load right 8x16 - LOADR(0) - LOADR(1) - LOADR(2) - LOADR(3) - LOADR(4) - LOADR(5) - LOADR(6) - LOADR(7) - - // get the top 16x8 result - transpose2_8x8_avx2(t, out); - // get the bottom 16x8 result - transpose2_8x8_avx2(&t[8], &out[8]); -} - -void vpx_idct16x16_256_add_avx2(const tran_low_t *input, uint8_t *dest, - int stride) { - int i; - __m256i in[16]; - - // Load 16x16 values - idct_load16x16(input, in, 16); - - transpose_16bit_16x16_avx2(in, in); - idct16_16col(in, in); - - transpose_16bit_16x16_avx2(in, in); - idct16_16col(in, in); - - for (i = 0; i < 16; ++i) { - write_buffer_16x1(dest + i * stride, in[i]); - } -} - -// Only do addition and subtraction butterfly, size = 16, 32 -static INLINE void add_sub_butterfly_avx2(__m256i *in, __m256i *out, int size) { - int i = 0; - const int num = size >> 1; - const int bound = size - 1; - while (i < num) { - out[i] = _mm256_add_epi16(in[i], in[bound - i]); - out[bound - i] = _mm256_sub_epi16(in[i], in[bound - i]); - i++; - } -} - -// For each 16x32 block __m256i in[32], -// Input with index, 0, 4, 8, 12, 16, 20, 24, 28 -// output pixels: 0-7 in __m256i out[32] -static INLINE void idct32_1024_16x32_quarter_1(__m256i *in, __m256i *out) { - __m256i step1[8], step2[8]; - - // stage 3 - butterfly16(in[4], in[28], cospi_28_64, cospi_4_64, &step1[4], &step1[7]); - butterfly16(in[20], in[12], cospi_12_64, cospi_20_64, &step1[5], &step1[6]); - - // stage 4 - butterfly16(in[0], in[16], cospi_16_64, cospi_16_64, &step2[1], &step2[0]); - butterfly16(in[8], in[24], cospi_24_64, cospi_8_64, &step2[2], &step2[3]); - step2[4] = _mm256_add_epi16(step1[4], step1[5]); - step2[5] = _mm256_sub_epi16(step1[4], step1[5]); - step2[6] = _mm256_sub_epi16(step1[7], step1[6]); - step2[7] = _mm256_add_epi16(step1[7], step1[6]); - - // stage 5 - step1[0] = _mm256_add_epi16(step2[0], step2[3]); - step1[1] = _mm256_add_epi16(step2[1], step2[2]); - step1[2] = _mm256_sub_epi16(step2[1], step2[2]); - step1[3] = _mm256_sub_epi16(step2[0], step2[3]); - step1[4] = step2[4]; - butterfly16(step2[6], step2[5], cospi_16_64, cospi_16_64, &step1[5], - &step1[6]); - step1[7] = step2[7]; - - // stage 6 - out[0] = _mm256_add_epi16(step1[0], step1[7]); - out[1] = _mm256_add_epi16(step1[1], step1[6]); - out[2] = _mm256_add_epi16(step1[2], step1[5]); - out[3] = _mm256_add_epi16(step1[3], step1[4]); - out[4] = _mm256_sub_epi16(step1[3], step1[4]); - out[5] = _mm256_sub_epi16(step1[2], step1[5]); - out[6] = _mm256_sub_epi16(step1[1], step1[6]); - out[7] = _mm256_sub_epi16(step1[0], step1[7]); -} - -static INLINE void idct32_16x32_quarter_2_stage_4_to_6(__m256i *step1, - __m256i *out) { - __m256i step2[32]; - - // stage 4 - step2[8] = step1[8]; - step2[15] = step1[15]; - butterfly16(step1[14], step1[9], cospi_24_64, cospi_8_64, &step2[9], - &step2[14]); - butterfly16(step1[13], step1[10], -cospi_8_64, cospi_24_64, &step2[10], - &step2[13]); - step2[11] = step1[11]; - step2[12] = step1[12]; - - // stage 5 - step1[8] = _mm256_add_epi16(step2[8], step2[11]); - step1[9] = _mm256_add_epi16(step2[9], step2[10]); - step1[10] = _mm256_sub_epi16(step2[9], step2[10]); - step1[11] = _mm256_sub_epi16(step2[8], step2[11]); - step1[12] = _mm256_sub_epi16(step2[15], step2[12]); - step1[13] = _mm256_sub_epi16(step2[14], step2[13]); - step1[14] = _mm256_add_epi16(step2[14], step2[13]); - step1[15] = _mm256_add_epi16(step2[15], step2[12]); - - // stage 6 - out[8] = step1[8]; - out[9] = step1[9]; - butterfly16(step1[13], step1[10], cospi_16_64, cospi_16_64, &out[10], - &out[13]); - butterfly16(step1[12], step1[11], cospi_16_64, cospi_16_64, &out[11], - &out[12]); - out[14] = step1[14]; - out[15] = step1[15]; -} - -// For each 16x32 block __m256i in[32], -// Input with index, 2, 6, 10, 14, 18, 22, 26, 30 -// output pixels: 8-15 in __m256i out[32] -static INLINE void idct32_1024_16x32_quarter_2(__m256i *in, __m256i *out) { - __m256i step1[16], step2[16]; - - // stage 2 - butterfly16(in[2], in[30], cospi_30_64, cospi_2_64, &step2[8], &step2[15]); - butterfly16(in[18], in[14], cospi_14_64, cospi_18_64, &step2[9], &step2[14]); - butterfly16(in[10], in[22], cospi_22_64, cospi_10_64, &step2[10], &step2[13]); - butterfly16(in[26], in[6], cospi_6_64, cospi_26_64, &step2[11], &step2[12]); - - // stage 3 - step1[8] = _mm256_add_epi16(step2[8], step2[9]); - step1[9] = _mm256_sub_epi16(step2[8], step2[9]); - step1[10] = _mm256_sub_epi16(step2[11], step2[10]); - step1[11] = _mm256_add_epi16(step2[11], step2[10]); - step1[12] = _mm256_add_epi16(step2[12], step2[13]); - step1[13] = _mm256_sub_epi16(step2[12], step2[13]); - step1[14] = _mm256_sub_epi16(step2[15], step2[14]); - step1[15] = _mm256_add_epi16(step2[15], step2[14]); - - idct32_16x32_quarter_2_stage_4_to_6(step1, out); -} - -static INLINE void idct32_16x32_quarter_3_4_stage_4_to_7(__m256i *step1, - __m256i *out) { - __m256i step2[32]; - - // stage 4 - step2[16] = _mm256_add_epi16(step1[16], step1[19]); - step2[17] = _mm256_add_epi16(step1[17], step1[18]); - step2[18] = _mm256_sub_epi16(step1[17], step1[18]); - step2[19] = _mm256_sub_epi16(step1[16], step1[19]); - step2[20] = _mm256_sub_epi16(step1[23], step1[20]); - step2[21] = _mm256_sub_epi16(step1[22], step1[21]); - step2[22] = _mm256_add_epi16(step1[22], step1[21]); - step2[23] = _mm256_add_epi16(step1[23], step1[20]); - - step2[24] = _mm256_add_epi16(step1[24], step1[27]); - step2[25] = _mm256_add_epi16(step1[25], step1[26]); - step2[26] = _mm256_sub_epi16(step1[25], step1[26]); - step2[27] = _mm256_sub_epi16(step1[24], step1[27]); - step2[28] = _mm256_sub_epi16(step1[31], step1[28]); - step2[29] = _mm256_sub_epi16(step1[30], step1[29]); - step2[30] = _mm256_add_epi16(step1[29], step1[30]); - step2[31] = _mm256_add_epi16(step1[28], step1[31]); - - // stage 5 - step1[16] = step2[16]; - step1[17] = step2[17]; - butterfly16(step2[29], step2[18], cospi_24_64, cospi_8_64, &step1[18], - &step1[29]); - butterfly16(step2[28], step2[19], cospi_24_64, cospi_8_64, &step1[19], - &step1[28]); - butterfly16(step2[27], step2[20], -cospi_8_64, cospi_24_64, &step1[20], - &step1[27]); - butterfly16(step2[26], step2[21], -cospi_8_64, cospi_24_64, &step1[21], - &step1[26]); - step1[22] = step2[22]; - step1[23] = step2[23]; - step1[24] = step2[24]; - step1[25] = step2[25]; - step1[30] = step2[30]; - step1[31] = step2[31]; - - // stage 6 - out[16] = _mm256_add_epi16(step1[16], step1[23]); - out[17] = _mm256_add_epi16(step1[17], step1[22]); - out[18] = _mm256_add_epi16(step1[18], step1[21]); - out[19] = _mm256_add_epi16(step1[19], step1[20]); - step2[20] = _mm256_sub_epi16(step1[19], step1[20]); - step2[21] = _mm256_sub_epi16(step1[18], step1[21]); - step2[22] = _mm256_sub_epi16(step1[17], step1[22]); - step2[23] = _mm256_sub_epi16(step1[16], step1[23]); - - step2[24] = _mm256_sub_epi16(step1[31], step1[24]); - step2[25] = _mm256_sub_epi16(step1[30], step1[25]); - step2[26] = _mm256_sub_epi16(step1[29], step1[26]); - step2[27] = _mm256_sub_epi16(step1[28], step1[27]); - out[28] = _mm256_add_epi16(step1[27], step1[28]); - out[29] = _mm256_add_epi16(step1[26], step1[29]); - out[30] = _mm256_add_epi16(step1[25], step1[30]); - out[31] = _mm256_add_epi16(step1[24], step1[31]); - - // stage 7 - butterfly16(step2[27], step2[20], cospi_16_64, cospi_16_64, &out[20], - &out[27]); - butterfly16(step2[26], step2[21], cospi_16_64, cospi_16_64, &out[21], - &out[26]); - butterfly16(step2[25], step2[22], cospi_16_64, cospi_16_64, &out[22], - &out[25]); - butterfly16(step2[24], step2[23], cospi_16_64, cospi_16_64, &out[23], - &out[24]); -} - -static INLINE void idct32_1024_16x32_quarter_1_2(__m256i *in, __m256i *out) { - __m256i temp[16]; - - // For each 16x32 block __m256i in[32], - // Input with index, 0, 4, 8, 12, 16, 20, 24, 28 - // output pixels: 0-7 in __m256i out[32] - idct32_1024_16x32_quarter_1(in, temp); - - // Input with index, 2, 6, 10, 14, 18, 22, 26, 30 - // output pixels: 8-15 in __m256i out[32] - idct32_1024_16x32_quarter_2(in, temp); - - // stage 7 - add_sub_butterfly_avx2(temp, out, 16); -} - -// For each 16x32 block __m256i in[32], -// Input with odd index, -// 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 -// output pixels: 16-23, 24-31 in __m256i out[32] -static INLINE void idct32_1024_16x32_quarter_3_4(__m256i *in, __m256i *out) { - __m256i step1[32], step2[32]; - - // stage 1 - butterfly16(in[1], in[31], cospi_31_64, cospi_1_64, &step1[16], &step1[31]); - butterfly16(in[17], in[15], cospi_15_64, cospi_17_64, &step1[17], &step1[30]); - butterfly16(in[9], in[23], cospi_23_64, cospi_9_64, &step1[18], &step1[29]); - butterfly16(in[25], in[7], cospi_7_64, cospi_25_64, &step1[19], &step1[28]); - - butterfly16(in[5], in[27], cospi_27_64, cospi_5_64, &step1[20], &step1[27]); - butterfly16(in[21], in[11], cospi_11_64, cospi_21_64, &step1[21], &step1[26]); - - butterfly16(in[13], in[19], cospi_19_64, cospi_13_64, &step1[22], &step1[25]); - butterfly16(in[29], in[3], cospi_3_64, cospi_29_64, &step1[23], &step1[24]); - - // stage 2 - step2[16] = _mm256_add_epi16(step1[16], step1[17]); - step2[17] = _mm256_sub_epi16(step1[16], step1[17]); - step2[18] = _mm256_sub_epi16(step1[19], step1[18]); - step2[19] = _mm256_add_epi16(step1[19], step1[18]); - step2[20] = _mm256_add_epi16(step1[20], step1[21]); - step2[21] = _mm256_sub_epi16(step1[20], step1[21]); - step2[22] = _mm256_sub_epi16(step1[23], step1[22]); - step2[23] = _mm256_add_epi16(step1[23], step1[22]); - - step2[24] = _mm256_add_epi16(step1[24], step1[25]); - step2[25] = _mm256_sub_epi16(step1[24], step1[25]); - step2[26] = _mm256_sub_epi16(step1[27], step1[26]); - step2[27] = _mm256_add_epi16(step1[27], step1[26]); - step2[28] = _mm256_add_epi16(step1[28], step1[29]); - step2[29] = _mm256_sub_epi16(step1[28], step1[29]); - step2[30] = _mm256_sub_epi16(step1[31], step1[30]); - step2[31] = _mm256_add_epi16(step1[31], step1[30]); - - // stage 3 - step1[16] = step2[16]; - step1[31] = step2[31]; - butterfly16(step2[30], step2[17], cospi_28_64, cospi_4_64, &step1[17], - &step1[30]); - butterfly16(step2[29], step2[18], -cospi_4_64, cospi_28_64, &step1[18], - &step1[29]); - step1[19] = step2[19]; - step1[20] = step2[20]; - butterfly16(step2[26], step2[21], cospi_12_64, cospi_20_64, &step1[21], - &step1[26]); - butterfly16(step2[25], step2[22], -cospi_20_64, cospi_12_64, &step1[22], - &step1[25]); - step1[23] = step2[23]; - step1[24] = step2[24]; - step1[27] = step2[27]; - step1[28] = step2[28]; - - idct32_16x32_quarter_3_4_stage_4_to_7(step1, out); -} - -static INLINE void idct32_1024_16x32(__m256i *in, __m256i *out) { - __m256i temp[32]; - - // For each 16x32 block __m256i in[32], - // Input with index, 0, 4, 8, 12, 16, 20, 24, 28 - // output pixels: 0-7 in __m256i out[32] - // AND - // Input with index, 2, 6, 10, 14, 18, 22, 26, 30 - // output pixels: 8-15 in __m256i out[32] - idct32_1024_16x32_quarter_1_2(in, temp); - - // For each 16x32 block __m256i in[32], - // Input with odd index, - // 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 - // output pixels: 16-23, 24-31 in __m256i out[32] - idct32_1024_16x32_quarter_3_4(in, temp); - - // final stage - add_sub_butterfly_avx2(temp, out, 32); -} - -void vpx_idct32x32_1024_add_avx2(const tran_low_t *input, uint8_t *dest, - int stride) { - __m256i l[32], r[32], out[32], *in; - int i; - - in = l; - - for (i = 0; i < 2; i++) { - idct_load16x16(input, in, 32); - transpose_16bit_16x16_avx2(in, in); - - idct_load16x16(input + 16, in + 16, 32); - transpose_16bit_16x16_avx2(in + 16, in + 16); - idct32_1024_16x32(in, in); - - in = r; - input += 32 << 4; - } - - for (i = 0; i < 32; i += 16) { - transpose_16bit_16x16_avx2(l + i, out); - transpose_16bit_16x16_avx2(r + i, out + 16); - idct32_1024_16x32(out, out); - - store_buffer_16x32(out, dest, stride); - dest += 16; - } -} - -// Case when only upper-left 16x16 has non-zero coeff -void vpx_idct32x32_135_add_avx2(const tran_low_t *input, uint8_t *dest, - int stride) { - __m256i in[32], io[32], out[32]; - int i; - - for (i = 16; i < 32; i++) { - in[i] = _mm256_setzero_si256(); - } - - // rows - idct_load16x16(input, in, 32); - transpose_16bit_16x16_avx2(in, in); - idct32_1024_16x32(in, io); - - // columns - for (i = 0; i < 32; i += 16) { - transpose_16bit_16x16_avx2(io + i, in); - idct32_1024_16x32(in, out); - - store_buffer_16x32(out, dest, stride); - dest += 16; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_txfm_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_txfm_sse2.c deleted file mode 100644 index f42b3df8..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_txfm_sse2.c +++ /dev/null @@ -1,1235 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // SSE2 - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/x86/inv_txfm_sse2.h" -#include "vpx_dsp/x86/transpose_sse2.h" -#include "vpx_dsp/x86/txfm_common_sse2.h" - -static INLINE void transpose_16bit_4(__m128i *res) { - const __m128i tr0_0 = _mm_unpacklo_epi16(res[0], res[1]); - const __m128i tr0_1 = _mm_unpackhi_epi16(res[0], res[1]); - - res[0] = _mm_unpacklo_epi16(tr0_0, tr0_1); - res[1] = _mm_unpackhi_epi16(tr0_0, tr0_1); -} - -void vpx_idct4x4_16_add_sse2(const tran_low_t *input, uint8_t *dest, - int stride) { - const __m128i eight = _mm_set1_epi16(8); - __m128i in[2]; - - // Rows - in[0] = load_input_data8(input); - in[1] = load_input_data8(input + 8); - idct4_sse2(in); - - // Columns - idct4_sse2(in); - - // Final round and shift - in[0] = _mm_add_epi16(in[0], eight); - in[1] = _mm_add_epi16(in[1], eight); - in[0] = _mm_srai_epi16(in[0], 4); - in[1] = _mm_srai_epi16(in[1], 4); - - recon_and_store4x4_sse2(in, dest, stride); -} - -void vpx_idct4x4_1_add_sse2(const tran_low_t *input, uint8_t *dest, - int stride) { - const __m128i zero = _mm_setzero_si128(); - int a; - __m128i dc_value, d[2]; - - a = (int)dct_const_round_shift((int16_t)input[0] * cospi_16_64); - a = (int)dct_const_round_shift(a * cospi_16_64); - a = ROUND_POWER_OF_TWO(a, 4); - - dc_value = _mm_set1_epi16(a); - - // Reconstruction and Store - d[0] = _mm_cvtsi32_si128(*(const int *)(dest)); - d[1] = _mm_cvtsi32_si128(*(const int *)(dest + stride * 3)); - d[0] = _mm_unpacklo_epi32(d[0], - _mm_cvtsi32_si128(*(const int *)(dest + stride))); - d[1] = _mm_unpacklo_epi32( - _mm_cvtsi32_si128(*(const int *)(dest + stride * 2)), d[1]); - d[0] = _mm_unpacklo_epi8(d[0], zero); - d[1] = _mm_unpacklo_epi8(d[1], zero); - d[0] = _mm_add_epi16(d[0], dc_value); - d[1] = _mm_add_epi16(d[1], dc_value); - d[0] = _mm_packus_epi16(d[0], d[1]); - - *(int *)dest = _mm_cvtsi128_si32(d[0]); - d[0] = _mm_srli_si128(d[0], 4); - *(int *)(dest + stride) = _mm_cvtsi128_si32(d[0]); - d[0] = _mm_srli_si128(d[0], 4); - *(int *)(dest + stride * 2) = _mm_cvtsi128_si32(d[0]); - d[0] = _mm_srli_si128(d[0], 4); - *(int *)(dest + stride * 3) = _mm_cvtsi128_si32(d[0]); -} - -void idct4_sse2(__m128i *const in) { - const __m128i k__cospi_p16_p16 = pair_set_epi16(cospi_16_64, cospi_16_64); - const __m128i k__cospi_p16_m16 = pair_set_epi16(cospi_16_64, -cospi_16_64); - const __m128i k__cospi_p24_m08 = pair_set_epi16(cospi_24_64, -cospi_8_64); - const __m128i k__cospi_p08_p24 = pair_set_epi16(cospi_8_64, cospi_24_64); - __m128i u[2]; - - transpose_16bit_4(in); - // stage 1 - u[0] = _mm_unpacklo_epi16(in[0], in[1]); - u[1] = _mm_unpackhi_epi16(in[0], in[1]); - u[0] = idct_calc_wraplow_sse2(k__cospi_p16_p16, k__cospi_p16_m16, u[0]); - u[1] = idct_calc_wraplow_sse2(k__cospi_p08_p24, k__cospi_p24_m08, u[1]); - - // stage 2 - in[0] = _mm_add_epi16(u[0], u[1]); - in[1] = _mm_sub_epi16(u[0], u[1]); - in[1] = _mm_shuffle_epi32(in[1], 0x4E); -} - -void iadst4_sse2(__m128i *const in) { - const __m128i k__sinpi_1_3 = pair_set_epi16(sinpi_1_9, sinpi_3_9); - const __m128i k__sinpi_4_2 = pair_set_epi16(sinpi_4_9, sinpi_2_9); - const __m128i k__sinpi_2_3 = pair_set_epi16(sinpi_2_9, sinpi_3_9); - const __m128i k__sinpi_1_4 = pair_set_epi16(sinpi_1_9, sinpi_4_9); - const __m128i k__sinpi_12_n3 = - pair_set_epi16(sinpi_1_9 + sinpi_2_9, -sinpi_3_9); - __m128i u[4], v[5]; - - // 00 01 20 21 02 03 22 23 - // 10 11 30 31 12 13 32 33 - const __m128i tr0_0 = _mm_unpacklo_epi32(in[0], in[1]); - const __m128i tr0_1 = _mm_unpackhi_epi32(in[0], in[1]); - - // 00 01 10 11 20 21 30 31 - // 02 03 12 13 22 23 32 33 - in[0] = _mm_unpacklo_epi32(tr0_0, tr0_1); - in[1] = _mm_unpackhi_epi32(tr0_0, tr0_1); - - v[0] = _mm_madd_epi16(in[0], k__sinpi_1_3); // s_1 * x0 + s_3 * x1 - v[1] = _mm_madd_epi16(in[1], k__sinpi_4_2); // s_4 * x2 + s_2 * x3 - v[2] = _mm_madd_epi16(in[0], k__sinpi_2_3); // s_2 * x0 + s_3 * x1 - v[3] = _mm_madd_epi16(in[1], k__sinpi_1_4); // s_1 * x2 + s_4 * x3 - v[4] = _mm_madd_epi16(in[0], k__sinpi_12_n3); // (s_1 + s_2) * x0 - s_3 * x1 - in[0] = _mm_sub_epi16(in[0], in[1]); // x0 - x2 - in[1] = _mm_srli_epi32(in[1], 16); - in[0] = _mm_add_epi16(in[0], in[1]); - in[0] = _mm_slli_epi32(in[0], 16); // x0 - x2 + x3 - - u[0] = _mm_add_epi32(v[0], v[1]); - u[1] = _mm_sub_epi32(v[2], v[3]); - u[2] = _mm_madd_epi16(in[0], k__sinpi_1_3); - u[3] = _mm_sub_epi32(v[1], v[3]); - u[3] = _mm_add_epi32(u[3], v[4]); - - u[0] = dct_const_round_shift_sse2(u[0]); - u[1] = dct_const_round_shift_sse2(u[1]); - u[2] = dct_const_round_shift_sse2(u[2]); - u[3] = dct_const_round_shift_sse2(u[3]); - - in[0] = _mm_packs_epi32(u[0], u[1]); - in[1] = _mm_packs_epi32(u[2], u[3]); -} - -static INLINE void load_buffer_8x8(const tran_low_t *const input, - __m128i *const in) { - in[0] = load_input_data8(input + 0 * 8); - in[1] = load_input_data8(input + 1 * 8); - in[2] = load_input_data8(input + 2 * 8); - in[3] = load_input_data8(input + 3 * 8); - in[4] = load_input_data8(input + 4 * 8); - in[5] = load_input_data8(input + 5 * 8); - in[6] = load_input_data8(input + 6 * 8); - in[7] = load_input_data8(input + 7 * 8); -} - -void vpx_idct8x8_64_add_sse2(const tran_low_t *input, uint8_t *dest, - int stride) { - __m128i in[8]; - int i; - - // Load input data. - load_buffer_8x8(input, in); - - // 2-D - for (i = 0; i < 2; i++) { - vpx_idct8_sse2(in); - } - - write_buffer_8x8(in, dest, stride); -} - -void vpx_idct8x8_12_add_sse2(const tran_low_t *input, uint8_t *dest, - int stride) { - __m128i io[8]; - - io[0] = load_input_data4(input + 0 * 8); - io[1] = load_input_data4(input + 1 * 8); - io[2] = load_input_data4(input + 2 * 8); - io[3] = load_input_data4(input + 3 * 8); - - idct8x8_12_add_kernel_sse2(io); - write_buffer_8x8(io, dest, stride); -} - -static INLINE void recon_and_store_8_dual(uint8_t *const dest, - const __m128i in_x, - const int stride) { - const __m128i zero = _mm_setzero_si128(); - __m128i d0, d1; - - d0 = _mm_loadl_epi64((__m128i *)(dest + 0 * stride)); - d1 = _mm_loadl_epi64((__m128i *)(dest + 1 * stride)); - d0 = _mm_unpacklo_epi8(d0, zero); - d1 = _mm_unpacklo_epi8(d1, zero); - d0 = _mm_add_epi16(in_x, d0); - d1 = _mm_add_epi16(in_x, d1); - d0 = _mm_packus_epi16(d0, d1); - _mm_storel_epi64((__m128i *)(dest + 0 * stride), d0); - _mm_storeh_pi((__m64 *)(dest + 1 * stride), _mm_castsi128_ps(d0)); -} - -void vpx_idct8x8_1_add_sse2(const tran_low_t *input, uint8_t *dest, - int stride) { - __m128i dc_value; - tran_high_t a1; - tran_low_t out = - WRAPLOW(dct_const_round_shift((int16_t)input[0] * cospi_16_64)); - - out = WRAPLOW(dct_const_round_shift(out * cospi_16_64)); - a1 = ROUND_POWER_OF_TWO(out, 5); - dc_value = _mm_set1_epi16((int16_t)a1); - - recon_and_store_8_dual(dest, dc_value, stride); - dest += 2 * stride; - recon_and_store_8_dual(dest, dc_value, stride); - dest += 2 * stride; - recon_and_store_8_dual(dest, dc_value, stride); - dest += 2 * stride; - recon_and_store_8_dual(dest, dc_value, stride); -} - -void vpx_idct8_sse2(__m128i *const in) { - // 8x8 Transpose is copied from vpx_fdct8x8_sse2() - transpose_16bit_8x8(in, in); - - // 4-stage 1D idct8x8 - idct8(in, in); -} - -void iadst8_sse2(__m128i *const in) { - const __m128i k__cospi_p02_p30 = pair_set_epi16(cospi_2_64, cospi_30_64); - const __m128i k__cospi_p30_m02 = pair_set_epi16(cospi_30_64, -cospi_2_64); - const __m128i k__cospi_p10_p22 = pair_set_epi16(cospi_10_64, cospi_22_64); - const __m128i k__cospi_p22_m10 = pair_set_epi16(cospi_22_64, -cospi_10_64); - const __m128i k__cospi_p18_p14 = pair_set_epi16(cospi_18_64, cospi_14_64); - const __m128i k__cospi_p14_m18 = pair_set_epi16(cospi_14_64, -cospi_18_64); - const __m128i k__cospi_p26_p06 = pair_set_epi16(cospi_26_64, cospi_6_64); - const __m128i k__cospi_p06_m26 = pair_set_epi16(cospi_6_64, -cospi_26_64); - const __m128i k__cospi_p08_p24 = pair_set_epi16(cospi_8_64, cospi_24_64); - const __m128i k__cospi_p24_m08 = pair_set_epi16(cospi_24_64, -cospi_8_64); - const __m128i k__cospi_m24_p08 = pair_set_epi16(-cospi_24_64, cospi_8_64); - const __m128i k__cospi_p16_m16 = pair_set_epi16(cospi_16_64, -cospi_16_64); - const __m128i k__cospi_p16_p16 = _mm_set1_epi16(cospi_16_64); - const __m128i kZero = _mm_setzero_si128(); - __m128i s[8], u[16], v[8], w[16]; - - // transpose - transpose_16bit_8x8(in, in); - - // column transformation - // stage 1 - // interleave and multiply/add into 32-bit integer - s[0] = _mm_unpacklo_epi16(in[7], in[0]); - s[1] = _mm_unpackhi_epi16(in[7], in[0]); - s[2] = _mm_unpacklo_epi16(in[5], in[2]); - s[3] = _mm_unpackhi_epi16(in[5], in[2]); - s[4] = _mm_unpacklo_epi16(in[3], in[4]); - s[5] = _mm_unpackhi_epi16(in[3], in[4]); - s[6] = _mm_unpacklo_epi16(in[1], in[6]); - s[7] = _mm_unpackhi_epi16(in[1], in[6]); - - u[0] = _mm_madd_epi16(s[0], k__cospi_p02_p30); - u[1] = _mm_madd_epi16(s[1], k__cospi_p02_p30); - u[2] = _mm_madd_epi16(s[0], k__cospi_p30_m02); - u[3] = _mm_madd_epi16(s[1], k__cospi_p30_m02); - u[4] = _mm_madd_epi16(s[2], k__cospi_p10_p22); - u[5] = _mm_madd_epi16(s[3], k__cospi_p10_p22); - u[6] = _mm_madd_epi16(s[2], k__cospi_p22_m10); - u[7] = _mm_madd_epi16(s[3], k__cospi_p22_m10); - u[8] = _mm_madd_epi16(s[4], k__cospi_p18_p14); - u[9] = _mm_madd_epi16(s[5], k__cospi_p18_p14); - u[10] = _mm_madd_epi16(s[4], k__cospi_p14_m18); - u[11] = _mm_madd_epi16(s[5], k__cospi_p14_m18); - u[12] = _mm_madd_epi16(s[6], k__cospi_p26_p06); - u[13] = _mm_madd_epi16(s[7], k__cospi_p26_p06); - u[14] = _mm_madd_epi16(s[6], k__cospi_p06_m26); - u[15] = _mm_madd_epi16(s[7], k__cospi_p06_m26); - - // addition - w[0] = _mm_add_epi32(u[0], u[8]); - w[1] = _mm_add_epi32(u[1], u[9]); - w[2] = _mm_add_epi32(u[2], u[10]); - w[3] = _mm_add_epi32(u[3], u[11]); - w[4] = _mm_add_epi32(u[4], u[12]); - w[5] = _mm_add_epi32(u[5], u[13]); - w[6] = _mm_add_epi32(u[6], u[14]); - w[7] = _mm_add_epi32(u[7], u[15]); - w[8] = _mm_sub_epi32(u[0], u[8]); - w[9] = _mm_sub_epi32(u[1], u[9]); - w[10] = _mm_sub_epi32(u[2], u[10]); - w[11] = _mm_sub_epi32(u[3], u[11]); - w[12] = _mm_sub_epi32(u[4], u[12]); - w[13] = _mm_sub_epi32(u[5], u[13]); - w[14] = _mm_sub_epi32(u[6], u[14]); - w[15] = _mm_sub_epi32(u[7], u[15]); - - // shift and rounding - u[0] = dct_const_round_shift_sse2(w[0]); - u[1] = dct_const_round_shift_sse2(w[1]); - u[2] = dct_const_round_shift_sse2(w[2]); - u[3] = dct_const_round_shift_sse2(w[3]); - u[4] = dct_const_round_shift_sse2(w[4]); - u[5] = dct_const_round_shift_sse2(w[5]); - u[6] = dct_const_round_shift_sse2(w[6]); - u[7] = dct_const_round_shift_sse2(w[7]); - u[8] = dct_const_round_shift_sse2(w[8]); - u[9] = dct_const_round_shift_sse2(w[9]); - u[10] = dct_const_round_shift_sse2(w[10]); - u[11] = dct_const_round_shift_sse2(w[11]); - u[12] = dct_const_round_shift_sse2(w[12]); - u[13] = dct_const_round_shift_sse2(w[13]); - u[14] = dct_const_round_shift_sse2(w[14]); - u[15] = dct_const_round_shift_sse2(w[15]); - - // back to 16-bit and pack 8 integers into __m128i - in[0] = _mm_packs_epi32(u[0], u[1]); - in[1] = _mm_packs_epi32(u[2], u[3]); - in[2] = _mm_packs_epi32(u[4], u[5]); - in[3] = _mm_packs_epi32(u[6], u[7]); - in[4] = _mm_packs_epi32(u[8], u[9]); - in[5] = _mm_packs_epi32(u[10], u[11]); - in[6] = _mm_packs_epi32(u[12], u[13]); - in[7] = _mm_packs_epi32(u[14], u[15]); - - // stage 2 - s[0] = _mm_add_epi16(in[0], in[2]); - s[1] = _mm_add_epi16(in[1], in[3]); - s[2] = _mm_sub_epi16(in[0], in[2]); - s[3] = _mm_sub_epi16(in[1], in[3]); - u[0] = _mm_unpacklo_epi16(in[4], in[5]); - u[1] = _mm_unpackhi_epi16(in[4], in[5]); - u[2] = _mm_unpacklo_epi16(in[6], in[7]); - u[3] = _mm_unpackhi_epi16(in[6], in[7]); - - v[0] = _mm_madd_epi16(u[0], k__cospi_p08_p24); - v[1] = _mm_madd_epi16(u[1], k__cospi_p08_p24); - v[2] = _mm_madd_epi16(u[0], k__cospi_p24_m08); - v[3] = _mm_madd_epi16(u[1], k__cospi_p24_m08); - v[4] = _mm_madd_epi16(u[2], k__cospi_m24_p08); - v[5] = _mm_madd_epi16(u[3], k__cospi_m24_p08); - v[6] = _mm_madd_epi16(u[2], k__cospi_p08_p24); - v[7] = _mm_madd_epi16(u[3], k__cospi_p08_p24); - - w[0] = _mm_add_epi32(v[0], v[4]); - w[1] = _mm_add_epi32(v[1], v[5]); - w[2] = _mm_add_epi32(v[2], v[6]); - w[3] = _mm_add_epi32(v[3], v[7]); - w[4] = _mm_sub_epi32(v[0], v[4]); - w[5] = _mm_sub_epi32(v[1], v[5]); - w[6] = _mm_sub_epi32(v[2], v[6]); - w[7] = _mm_sub_epi32(v[3], v[7]); - - u[0] = dct_const_round_shift_sse2(w[0]); - u[1] = dct_const_round_shift_sse2(w[1]); - u[2] = dct_const_round_shift_sse2(w[2]); - u[3] = dct_const_round_shift_sse2(w[3]); - u[4] = dct_const_round_shift_sse2(w[4]); - u[5] = dct_const_round_shift_sse2(w[5]); - u[6] = dct_const_round_shift_sse2(w[6]); - u[7] = dct_const_round_shift_sse2(w[7]); - - // back to 16-bit intergers - s[4] = _mm_packs_epi32(u[0], u[1]); - s[5] = _mm_packs_epi32(u[2], u[3]); - s[6] = _mm_packs_epi32(u[4], u[5]); - s[7] = _mm_packs_epi32(u[6], u[7]); - - // stage 3 - u[0] = _mm_unpacklo_epi16(s[2], s[3]); - u[1] = _mm_unpackhi_epi16(s[2], s[3]); - u[2] = _mm_unpacklo_epi16(s[6], s[7]); - u[3] = _mm_unpackhi_epi16(s[6], s[7]); - - s[2] = idct_calc_wraplow_sse2(u[0], u[1], k__cospi_p16_p16); - s[3] = idct_calc_wraplow_sse2(u[0], u[1], k__cospi_p16_m16); - s[6] = idct_calc_wraplow_sse2(u[2], u[3], k__cospi_p16_p16); - s[7] = idct_calc_wraplow_sse2(u[2], u[3], k__cospi_p16_m16); - - in[0] = s[0]; - in[1] = _mm_sub_epi16(kZero, s[4]); - in[2] = s[6]; - in[3] = _mm_sub_epi16(kZero, s[2]); - in[4] = s[3]; - in[5] = _mm_sub_epi16(kZero, s[7]); - in[6] = s[5]; - in[7] = _mm_sub_epi16(kZero, s[1]); -} - -static INLINE void idct16_load8x8(const tran_low_t *const input, - __m128i *const in) { - in[0] = load_input_data8(input + 0 * 16); - in[1] = load_input_data8(input + 1 * 16); - in[2] = load_input_data8(input + 2 * 16); - in[3] = load_input_data8(input + 3 * 16); - in[4] = load_input_data8(input + 4 * 16); - in[5] = load_input_data8(input + 5 * 16); - in[6] = load_input_data8(input + 6 * 16); - in[7] = load_input_data8(input + 7 * 16); -} - -void vpx_idct16x16_256_add_sse2(const tran_low_t *input, uint8_t *dest, - int stride) { - __m128i l[16], r[16], out[16], *in; - int i; - - in = l; - for (i = 0; i < 2; i++) { - idct16_load8x8(input, in); - transpose_16bit_8x8(in, in); - idct16_load8x8(input + 8, in + 8); - transpose_16bit_8x8(in + 8, in + 8); - idct16_8col(in, in); - in = r; - input += 128; - } - - for (i = 0; i < 16; i += 8) { - int j; - transpose_16bit_8x8(l + i, out); - transpose_16bit_8x8(r + i, out + 8); - idct16_8col(out, out); - - for (j = 0; j < 16; ++j) { - write_buffer_8x1(dest + j * stride, out[j]); - } - - dest += 8; - } -} - -void vpx_idct16x16_38_add_sse2(const tran_low_t *input, uint8_t *dest, - int stride) { - __m128i in[16], temp[16], out[16]; - int i; - - idct16_load8x8(input, in); - transpose_16bit_8x8(in, in); - - for (i = 8; i < 16; i++) { - in[i] = _mm_setzero_si128(); - } - idct16_8col(in, temp); - - for (i = 0; i < 16; i += 8) { - int j; - transpose_16bit_8x8(temp + i, in); - idct16_8col(in, out); - - for (j = 0; j < 16; ++j) { - write_buffer_8x1(dest + j * stride, out[j]); - } - - dest += 8; - } -} - -void vpx_idct16x16_10_add_sse2(const tran_low_t *input, uint8_t *dest, - int stride) { - __m128i in[16], l[16]; - int i; - - // First 1-D inverse DCT - // Load input data. - in[0] = load_input_data4(input + 0 * 16); - in[1] = load_input_data4(input + 1 * 16); - in[2] = load_input_data4(input + 2 * 16); - in[3] = load_input_data4(input + 3 * 16); - - idct16x16_10_pass1(in, l); - - // Second 1-D inverse transform, performed per 8x16 block - for (i = 0; i < 16; i += 8) { - int j; - idct16x16_10_pass2(l + i, in); - - for (j = 0; j < 16; ++j) { - write_buffer_8x1(dest + j * stride, in[j]); - } - - dest += 8; - } -} - -static INLINE void recon_and_store_16(uint8_t *const dest, const __m128i in_x) { - const __m128i zero = _mm_setzero_si128(); - __m128i d0, d1; - - d0 = _mm_load_si128((__m128i *)(dest)); - d1 = _mm_unpackhi_epi8(d0, zero); - d0 = _mm_unpacklo_epi8(d0, zero); - d0 = _mm_add_epi16(in_x, d0); - d1 = _mm_add_epi16(in_x, d1); - d0 = _mm_packus_epi16(d0, d1); - _mm_store_si128((__m128i *)(dest), d0); -} - -void vpx_idct16x16_1_add_sse2(const tran_low_t *input, uint8_t *dest, - int stride) { - __m128i dc_value; - int i; - tran_high_t a1; - tran_low_t out = - WRAPLOW(dct_const_round_shift((int16_t)input[0] * cospi_16_64)); - - out = WRAPLOW(dct_const_round_shift(out * cospi_16_64)); - a1 = ROUND_POWER_OF_TWO(out, 6); - dc_value = _mm_set1_epi16((int16_t)a1); - - for (i = 0; i < 16; ++i) { - recon_and_store_16(dest, dc_value); - dest += stride; - } -} - -void vpx_iadst16_8col_sse2(__m128i *const in) { - // perform 16x16 1-D ADST for 8 columns - __m128i s[16], x[16], u[32], v[32]; - const __m128i k__cospi_p01_p31 = pair_set_epi16(cospi_1_64, cospi_31_64); - const __m128i k__cospi_p31_m01 = pair_set_epi16(cospi_31_64, -cospi_1_64); - const __m128i k__cospi_p05_p27 = pair_set_epi16(cospi_5_64, cospi_27_64); - const __m128i k__cospi_p27_m05 = pair_set_epi16(cospi_27_64, -cospi_5_64); - const __m128i k__cospi_p09_p23 = pair_set_epi16(cospi_9_64, cospi_23_64); - const __m128i k__cospi_p23_m09 = pair_set_epi16(cospi_23_64, -cospi_9_64); - const __m128i k__cospi_p13_p19 = pair_set_epi16(cospi_13_64, cospi_19_64); - const __m128i k__cospi_p19_m13 = pair_set_epi16(cospi_19_64, -cospi_13_64); - const __m128i k__cospi_p17_p15 = pair_set_epi16(cospi_17_64, cospi_15_64); - const __m128i k__cospi_p15_m17 = pair_set_epi16(cospi_15_64, -cospi_17_64); - const __m128i k__cospi_p21_p11 = pair_set_epi16(cospi_21_64, cospi_11_64); - const __m128i k__cospi_p11_m21 = pair_set_epi16(cospi_11_64, -cospi_21_64); - const __m128i k__cospi_p25_p07 = pair_set_epi16(cospi_25_64, cospi_7_64); - const __m128i k__cospi_p07_m25 = pair_set_epi16(cospi_7_64, -cospi_25_64); - const __m128i k__cospi_p29_p03 = pair_set_epi16(cospi_29_64, cospi_3_64); - const __m128i k__cospi_p03_m29 = pair_set_epi16(cospi_3_64, -cospi_29_64); - const __m128i k__cospi_p04_p28 = pair_set_epi16(cospi_4_64, cospi_28_64); - const __m128i k__cospi_p28_m04 = pair_set_epi16(cospi_28_64, -cospi_4_64); - const __m128i k__cospi_p20_p12 = pair_set_epi16(cospi_20_64, cospi_12_64); - const __m128i k__cospi_p12_m20 = pair_set_epi16(cospi_12_64, -cospi_20_64); - const __m128i k__cospi_m28_p04 = pair_set_epi16(-cospi_28_64, cospi_4_64); - const __m128i k__cospi_m12_p20 = pair_set_epi16(-cospi_12_64, cospi_20_64); - const __m128i k__cospi_p08_p24 = pair_set_epi16(cospi_8_64, cospi_24_64); - const __m128i k__cospi_p24_m08 = pair_set_epi16(cospi_24_64, -cospi_8_64); - const __m128i k__cospi_m24_p08 = pair_set_epi16(-cospi_24_64, cospi_8_64); - const __m128i k__cospi_m16_m16 = _mm_set1_epi16(-cospi_16_64); - const __m128i k__cospi_p16_p16 = _mm_set1_epi16(cospi_16_64); - const __m128i k__cospi_p16_m16 = pair_set_epi16(cospi_16_64, -cospi_16_64); - const __m128i k__cospi_m16_p16 = pair_set_epi16(-cospi_16_64, cospi_16_64); - const __m128i kZero = _mm_setzero_si128(); - - u[0] = _mm_unpacklo_epi16(in[15], in[0]); - u[1] = _mm_unpackhi_epi16(in[15], in[0]); - u[2] = _mm_unpacklo_epi16(in[13], in[2]); - u[3] = _mm_unpackhi_epi16(in[13], in[2]); - u[4] = _mm_unpacklo_epi16(in[11], in[4]); - u[5] = _mm_unpackhi_epi16(in[11], in[4]); - u[6] = _mm_unpacklo_epi16(in[9], in[6]); - u[7] = _mm_unpackhi_epi16(in[9], in[6]); - u[8] = _mm_unpacklo_epi16(in[7], in[8]); - u[9] = _mm_unpackhi_epi16(in[7], in[8]); - u[10] = _mm_unpacklo_epi16(in[5], in[10]); - u[11] = _mm_unpackhi_epi16(in[5], in[10]); - u[12] = _mm_unpacklo_epi16(in[3], in[12]); - u[13] = _mm_unpackhi_epi16(in[3], in[12]); - u[14] = _mm_unpacklo_epi16(in[1], in[14]); - u[15] = _mm_unpackhi_epi16(in[1], in[14]); - - v[0] = _mm_madd_epi16(u[0], k__cospi_p01_p31); - v[1] = _mm_madd_epi16(u[1], k__cospi_p01_p31); - v[2] = _mm_madd_epi16(u[0], k__cospi_p31_m01); - v[3] = _mm_madd_epi16(u[1], k__cospi_p31_m01); - v[4] = _mm_madd_epi16(u[2], k__cospi_p05_p27); - v[5] = _mm_madd_epi16(u[3], k__cospi_p05_p27); - v[6] = _mm_madd_epi16(u[2], k__cospi_p27_m05); - v[7] = _mm_madd_epi16(u[3], k__cospi_p27_m05); - v[8] = _mm_madd_epi16(u[4], k__cospi_p09_p23); - v[9] = _mm_madd_epi16(u[5], k__cospi_p09_p23); - v[10] = _mm_madd_epi16(u[4], k__cospi_p23_m09); - v[11] = _mm_madd_epi16(u[5], k__cospi_p23_m09); - v[12] = _mm_madd_epi16(u[6], k__cospi_p13_p19); - v[13] = _mm_madd_epi16(u[7], k__cospi_p13_p19); - v[14] = _mm_madd_epi16(u[6], k__cospi_p19_m13); - v[15] = _mm_madd_epi16(u[7], k__cospi_p19_m13); - v[16] = _mm_madd_epi16(u[8], k__cospi_p17_p15); - v[17] = _mm_madd_epi16(u[9], k__cospi_p17_p15); - v[18] = _mm_madd_epi16(u[8], k__cospi_p15_m17); - v[19] = _mm_madd_epi16(u[9], k__cospi_p15_m17); - v[20] = _mm_madd_epi16(u[10], k__cospi_p21_p11); - v[21] = _mm_madd_epi16(u[11], k__cospi_p21_p11); - v[22] = _mm_madd_epi16(u[10], k__cospi_p11_m21); - v[23] = _mm_madd_epi16(u[11], k__cospi_p11_m21); - v[24] = _mm_madd_epi16(u[12], k__cospi_p25_p07); - v[25] = _mm_madd_epi16(u[13], k__cospi_p25_p07); - v[26] = _mm_madd_epi16(u[12], k__cospi_p07_m25); - v[27] = _mm_madd_epi16(u[13], k__cospi_p07_m25); - v[28] = _mm_madd_epi16(u[14], k__cospi_p29_p03); - v[29] = _mm_madd_epi16(u[15], k__cospi_p29_p03); - v[30] = _mm_madd_epi16(u[14], k__cospi_p03_m29); - v[31] = _mm_madd_epi16(u[15], k__cospi_p03_m29); - - u[0] = _mm_add_epi32(v[0], v[16]); - u[1] = _mm_add_epi32(v[1], v[17]); - u[2] = _mm_add_epi32(v[2], v[18]); - u[3] = _mm_add_epi32(v[3], v[19]); - u[4] = _mm_add_epi32(v[4], v[20]); - u[5] = _mm_add_epi32(v[5], v[21]); - u[6] = _mm_add_epi32(v[6], v[22]); - u[7] = _mm_add_epi32(v[7], v[23]); - u[8] = _mm_add_epi32(v[8], v[24]); - u[9] = _mm_add_epi32(v[9], v[25]); - u[10] = _mm_add_epi32(v[10], v[26]); - u[11] = _mm_add_epi32(v[11], v[27]); - u[12] = _mm_add_epi32(v[12], v[28]); - u[13] = _mm_add_epi32(v[13], v[29]); - u[14] = _mm_add_epi32(v[14], v[30]); - u[15] = _mm_add_epi32(v[15], v[31]); - u[16] = _mm_sub_epi32(v[0], v[16]); - u[17] = _mm_sub_epi32(v[1], v[17]); - u[18] = _mm_sub_epi32(v[2], v[18]); - u[19] = _mm_sub_epi32(v[3], v[19]); - u[20] = _mm_sub_epi32(v[4], v[20]); - u[21] = _mm_sub_epi32(v[5], v[21]); - u[22] = _mm_sub_epi32(v[6], v[22]); - u[23] = _mm_sub_epi32(v[7], v[23]); - u[24] = _mm_sub_epi32(v[8], v[24]); - u[25] = _mm_sub_epi32(v[9], v[25]); - u[26] = _mm_sub_epi32(v[10], v[26]); - u[27] = _mm_sub_epi32(v[11], v[27]); - u[28] = _mm_sub_epi32(v[12], v[28]); - u[29] = _mm_sub_epi32(v[13], v[29]); - u[30] = _mm_sub_epi32(v[14], v[30]); - u[31] = _mm_sub_epi32(v[15], v[31]); - - u[0] = dct_const_round_shift_sse2(u[0]); - u[1] = dct_const_round_shift_sse2(u[1]); - u[2] = dct_const_round_shift_sse2(u[2]); - u[3] = dct_const_round_shift_sse2(u[3]); - u[4] = dct_const_round_shift_sse2(u[4]); - u[5] = dct_const_round_shift_sse2(u[5]); - u[6] = dct_const_round_shift_sse2(u[6]); - u[7] = dct_const_round_shift_sse2(u[7]); - u[8] = dct_const_round_shift_sse2(u[8]); - u[9] = dct_const_round_shift_sse2(u[9]); - u[10] = dct_const_round_shift_sse2(u[10]); - u[11] = dct_const_round_shift_sse2(u[11]); - u[12] = dct_const_round_shift_sse2(u[12]); - u[13] = dct_const_round_shift_sse2(u[13]); - u[14] = dct_const_round_shift_sse2(u[14]); - u[15] = dct_const_round_shift_sse2(u[15]); - u[16] = dct_const_round_shift_sse2(u[16]); - u[17] = dct_const_round_shift_sse2(u[17]); - u[18] = dct_const_round_shift_sse2(u[18]); - u[19] = dct_const_round_shift_sse2(u[19]); - u[20] = dct_const_round_shift_sse2(u[20]); - u[21] = dct_const_round_shift_sse2(u[21]); - u[22] = dct_const_round_shift_sse2(u[22]); - u[23] = dct_const_round_shift_sse2(u[23]); - u[24] = dct_const_round_shift_sse2(u[24]); - u[25] = dct_const_round_shift_sse2(u[25]); - u[26] = dct_const_round_shift_sse2(u[26]); - u[27] = dct_const_round_shift_sse2(u[27]); - u[28] = dct_const_round_shift_sse2(u[28]); - u[29] = dct_const_round_shift_sse2(u[29]); - u[30] = dct_const_round_shift_sse2(u[30]); - u[31] = dct_const_round_shift_sse2(u[31]); - - s[0] = _mm_packs_epi32(u[0], u[1]); - s[1] = _mm_packs_epi32(u[2], u[3]); - s[2] = _mm_packs_epi32(u[4], u[5]); - s[3] = _mm_packs_epi32(u[6], u[7]); - s[4] = _mm_packs_epi32(u[8], u[9]); - s[5] = _mm_packs_epi32(u[10], u[11]); - s[6] = _mm_packs_epi32(u[12], u[13]); - s[7] = _mm_packs_epi32(u[14], u[15]); - s[8] = _mm_packs_epi32(u[16], u[17]); - s[9] = _mm_packs_epi32(u[18], u[19]); - s[10] = _mm_packs_epi32(u[20], u[21]); - s[11] = _mm_packs_epi32(u[22], u[23]); - s[12] = _mm_packs_epi32(u[24], u[25]); - s[13] = _mm_packs_epi32(u[26], u[27]); - s[14] = _mm_packs_epi32(u[28], u[29]); - s[15] = _mm_packs_epi32(u[30], u[31]); - - // stage 2 - u[0] = _mm_unpacklo_epi16(s[8], s[9]); - u[1] = _mm_unpackhi_epi16(s[8], s[9]); - u[2] = _mm_unpacklo_epi16(s[10], s[11]); - u[3] = _mm_unpackhi_epi16(s[10], s[11]); - u[4] = _mm_unpacklo_epi16(s[12], s[13]); - u[5] = _mm_unpackhi_epi16(s[12], s[13]); - u[6] = _mm_unpacklo_epi16(s[14], s[15]); - u[7] = _mm_unpackhi_epi16(s[14], s[15]); - - v[0] = _mm_madd_epi16(u[0], k__cospi_p04_p28); - v[1] = _mm_madd_epi16(u[1], k__cospi_p04_p28); - v[2] = _mm_madd_epi16(u[0], k__cospi_p28_m04); - v[3] = _mm_madd_epi16(u[1], k__cospi_p28_m04); - v[4] = _mm_madd_epi16(u[2], k__cospi_p20_p12); - v[5] = _mm_madd_epi16(u[3], k__cospi_p20_p12); - v[6] = _mm_madd_epi16(u[2], k__cospi_p12_m20); - v[7] = _mm_madd_epi16(u[3], k__cospi_p12_m20); - v[8] = _mm_madd_epi16(u[4], k__cospi_m28_p04); - v[9] = _mm_madd_epi16(u[5], k__cospi_m28_p04); - v[10] = _mm_madd_epi16(u[4], k__cospi_p04_p28); - v[11] = _mm_madd_epi16(u[5], k__cospi_p04_p28); - v[12] = _mm_madd_epi16(u[6], k__cospi_m12_p20); - v[13] = _mm_madd_epi16(u[7], k__cospi_m12_p20); - v[14] = _mm_madd_epi16(u[6], k__cospi_p20_p12); - v[15] = _mm_madd_epi16(u[7], k__cospi_p20_p12); - - u[0] = _mm_add_epi32(v[0], v[8]); - u[1] = _mm_add_epi32(v[1], v[9]); - u[2] = _mm_add_epi32(v[2], v[10]); - u[3] = _mm_add_epi32(v[3], v[11]); - u[4] = _mm_add_epi32(v[4], v[12]); - u[5] = _mm_add_epi32(v[5], v[13]); - u[6] = _mm_add_epi32(v[6], v[14]); - u[7] = _mm_add_epi32(v[7], v[15]); - u[8] = _mm_sub_epi32(v[0], v[8]); - u[9] = _mm_sub_epi32(v[1], v[9]); - u[10] = _mm_sub_epi32(v[2], v[10]); - u[11] = _mm_sub_epi32(v[3], v[11]); - u[12] = _mm_sub_epi32(v[4], v[12]); - u[13] = _mm_sub_epi32(v[5], v[13]); - u[14] = _mm_sub_epi32(v[6], v[14]); - u[15] = _mm_sub_epi32(v[7], v[15]); - - u[0] = dct_const_round_shift_sse2(u[0]); - u[1] = dct_const_round_shift_sse2(u[1]); - u[2] = dct_const_round_shift_sse2(u[2]); - u[3] = dct_const_round_shift_sse2(u[3]); - u[4] = dct_const_round_shift_sse2(u[4]); - u[5] = dct_const_round_shift_sse2(u[5]); - u[6] = dct_const_round_shift_sse2(u[6]); - u[7] = dct_const_round_shift_sse2(u[7]); - u[8] = dct_const_round_shift_sse2(u[8]); - u[9] = dct_const_round_shift_sse2(u[9]); - u[10] = dct_const_round_shift_sse2(u[10]); - u[11] = dct_const_round_shift_sse2(u[11]); - u[12] = dct_const_round_shift_sse2(u[12]); - u[13] = dct_const_round_shift_sse2(u[13]); - u[14] = dct_const_round_shift_sse2(u[14]); - u[15] = dct_const_round_shift_sse2(u[15]); - - x[0] = _mm_add_epi16(s[0], s[4]); - x[1] = _mm_add_epi16(s[1], s[5]); - x[2] = _mm_add_epi16(s[2], s[6]); - x[3] = _mm_add_epi16(s[3], s[7]); - x[4] = _mm_sub_epi16(s[0], s[4]); - x[5] = _mm_sub_epi16(s[1], s[5]); - x[6] = _mm_sub_epi16(s[2], s[6]); - x[7] = _mm_sub_epi16(s[3], s[7]); - x[8] = _mm_packs_epi32(u[0], u[1]); - x[9] = _mm_packs_epi32(u[2], u[3]); - x[10] = _mm_packs_epi32(u[4], u[5]); - x[11] = _mm_packs_epi32(u[6], u[7]); - x[12] = _mm_packs_epi32(u[8], u[9]); - x[13] = _mm_packs_epi32(u[10], u[11]); - x[14] = _mm_packs_epi32(u[12], u[13]); - x[15] = _mm_packs_epi32(u[14], u[15]); - - // stage 3 - u[0] = _mm_unpacklo_epi16(x[4], x[5]); - u[1] = _mm_unpackhi_epi16(x[4], x[5]); - u[2] = _mm_unpacklo_epi16(x[6], x[7]); - u[3] = _mm_unpackhi_epi16(x[6], x[7]); - u[4] = _mm_unpacklo_epi16(x[12], x[13]); - u[5] = _mm_unpackhi_epi16(x[12], x[13]); - u[6] = _mm_unpacklo_epi16(x[14], x[15]); - u[7] = _mm_unpackhi_epi16(x[14], x[15]); - - v[0] = _mm_madd_epi16(u[0], k__cospi_p08_p24); - v[1] = _mm_madd_epi16(u[1], k__cospi_p08_p24); - v[2] = _mm_madd_epi16(u[0], k__cospi_p24_m08); - v[3] = _mm_madd_epi16(u[1], k__cospi_p24_m08); - v[4] = _mm_madd_epi16(u[2], k__cospi_m24_p08); - v[5] = _mm_madd_epi16(u[3], k__cospi_m24_p08); - v[6] = _mm_madd_epi16(u[2], k__cospi_p08_p24); - v[7] = _mm_madd_epi16(u[3], k__cospi_p08_p24); - v[8] = _mm_madd_epi16(u[4], k__cospi_p08_p24); - v[9] = _mm_madd_epi16(u[5], k__cospi_p08_p24); - v[10] = _mm_madd_epi16(u[4], k__cospi_p24_m08); - v[11] = _mm_madd_epi16(u[5], k__cospi_p24_m08); - v[12] = _mm_madd_epi16(u[6], k__cospi_m24_p08); - v[13] = _mm_madd_epi16(u[7], k__cospi_m24_p08); - v[14] = _mm_madd_epi16(u[6], k__cospi_p08_p24); - v[15] = _mm_madd_epi16(u[7], k__cospi_p08_p24); - - u[0] = _mm_add_epi32(v[0], v[4]); - u[1] = _mm_add_epi32(v[1], v[5]); - u[2] = _mm_add_epi32(v[2], v[6]); - u[3] = _mm_add_epi32(v[3], v[7]); - u[4] = _mm_sub_epi32(v[0], v[4]); - u[5] = _mm_sub_epi32(v[1], v[5]); - u[6] = _mm_sub_epi32(v[2], v[6]); - u[7] = _mm_sub_epi32(v[3], v[7]); - u[8] = _mm_add_epi32(v[8], v[12]); - u[9] = _mm_add_epi32(v[9], v[13]); - u[10] = _mm_add_epi32(v[10], v[14]); - u[11] = _mm_add_epi32(v[11], v[15]); - u[12] = _mm_sub_epi32(v[8], v[12]); - u[13] = _mm_sub_epi32(v[9], v[13]); - u[14] = _mm_sub_epi32(v[10], v[14]); - u[15] = _mm_sub_epi32(v[11], v[15]); - - v[0] = dct_const_round_shift_sse2(u[0]); - v[1] = dct_const_round_shift_sse2(u[1]); - v[2] = dct_const_round_shift_sse2(u[2]); - v[3] = dct_const_round_shift_sse2(u[3]); - v[4] = dct_const_round_shift_sse2(u[4]); - v[5] = dct_const_round_shift_sse2(u[5]); - v[6] = dct_const_round_shift_sse2(u[6]); - v[7] = dct_const_round_shift_sse2(u[7]); - v[8] = dct_const_round_shift_sse2(u[8]); - v[9] = dct_const_round_shift_sse2(u[9]); - v[10] = dct_const_round_shift_sse2(u[10]); - v[11] = dct_const_round_shift_sse2(u[11]); - v[12] = dct_const_round_shift_sse2(u[12]); - v[13] = dct_const_round_shift_sse2(u[13]); - v[14] = dct_const_round_shift_sse2(u[14]); - v[15] = dct_const_round_shift_sse2(u[15]); - - s[0] = _mm_add_epi16(x[0], x[2]); - s[1] = _mm_add_epi16(x[1], x[3]); - s[2] = _mm_sub_epi16(x[0], x[2]); - s[3] = _mm_sub_epi16(x[1], x[3]); - s[4] = _mm_packs_epi32(v[0], v[1]); - s[5] = _mm_packs_epi32(v[2], v[3]); - s[6] = _mm_packs_epi32(v[4], v[5]); - s[7] = _mm_packs_epi32(v[6], v[7]); - s[8] = _mm_add_epi16(x[8], x[10]); - s[9] = _mm_add_epi16(x[9], x[11]); - s[10] = _mm_sub_epi16(x[8], x[10]); - s[11] = _mm_sub_epi16(x[9], x[11]); - s[12] = _mm_packs_epi32(v[8], v[9]); - s[13] = _mm_packs_epi32(v[10], v[11]); - s[14] = _mm_packs_epi32(v[12], v[13]); - s[15] = _mm_packs_epi32(v[14], v[15]); - - // stage 4 - u[0] = _mm_unpacklo_epi16(s[2], s[3]); - u[1] = _mm_unpackhi_epi16(s[2], s[3]); - u[2] = _mm_unpacklo_epi16(s[6], s[7]); - u[3] = _mm_unpackhi_epi16(s[6], s[7]); - u[4] = _mm_unpacklo_epi16(s[10], s[11]); - u[5] = _mm_unpackhi_epi16(s[10], s[11]); - u[6] = _mm_unpacklo_epi16(s[14], s[15]); - u[7] = _mm_unpackhi_epi16(s[14], s[15]); - - in[7] = idct_calc_wraplow_sse2(u[0], u[1], k__cospi_m16_m16); - in[8] = idct_calc_wraplow_sse2(u[0], u[1], k__cospi_p16_m16); - in[4] = idct_calc_wraplow_sse2(u[2], u[3], k__cospi_p16_p16); - in[11] = idct_calc_wraplow_sse2(u[2], u[3], k__cospi_m16_p16); - in[6] = idct_calc_wraplow_sse2(u[4], u[5], k__cospi_p16_p16); - in[9] = idct_calc_wraplow_sse2(u[4], u[5], k__cospi_m16_p16); - in[5] = idct_calc_wraplow_sse2(u[6], u[7], k__cospi_m16_m16); - in[10] = idct_calc_wraplow_sse2(u[6], u[7], k__cospi_p16_m16); - - in[0] = s[0]; - in[1] = _mm_sub_epi16(kZero, s[8]); - in[2] = s[12]; - in[3] = _mm_sub_epi16(kZero, s[4]); - in[12] = s[5]; - in[13] = _mm_sub_epi16(kZero, s[13]); - in[14] = s[9]; - in[15] = _mm_sub_epi16(kZero, s[1]); -} - -void idct16_sse2(__m128i *const in0, __m128i *const in1) { - transpose_16bit_16x16(in0, in1); - idct16_8col(in0, in0); - idct16_8col(in1, in1); -} - -void iadst16_sse2(__m128i *const in0, __m128i *const in1) { - transpose_16bit_16x16(in0, in1); - vpx_iadst16_8col_sse2(in0); - vpx_iadst16_8col_sse2(in1); -} - -// Group the coefficient calculation into smaller functions to prevent stack -// spillover in 32x32 idct optimizations: -// quarter_1: 0-7 -// quarter_2: 8-15 -// quarter_3_4: 16-23, 24-31 - -// For each 8x32 block __m128i in[32], -// Input with index, 0, 4 -// output pixels: 0-7 in __m128i out[32] -static INLINE void idct32_34_8x32_quarter_1(const __m128i *const in /*in[32]*/, - __m128i *const out /*out[8]*/) { - const __m128i zero = _mm_setzero_si128(); - __m128i step1[8], step2[8]; - - // stage 3 - butterfly(in[4], zero, cospi_28_64, cospi_4_64, &step1[4], &step1[7]); - - // stage 4 - step2[0] = butterfly_cospi16(in[0]); - step2[4] = step1[4]; - step2[5] = step1[4]; - step2[6] = step1[7]; - step2[7] = step1[7]; - - // stage 5 - step1[0] = step2[0]; - step1[1] = step2[0]; - step1[2] = step2[0]; - step1[3] = step2[0]; - step1[4] = step2[4]; - butterfly(step2[6], step2[5], cospi_16_64, cospi_16_64, &step1[5], &step1[6]); - step1[7] = step2[7]; - - // stage 6 - out[0] = _mm_add_epi16(step1[0], step1[7]); - out[1] = _mm_add_epi16(step1[1], step1[6]); - out[2] = _mm_add_epi16(step1[2], step1[5]); - out[3] = _mm_add_epi16(step1[3], step1[4]); - out[4] = _mm_sub_epi16(step1[3], step1[4]); - out[5] = _mm_sub_epi16(step1[2], step1[5]); - out[6] = _mm_sub_epi16(step1[1], step1[6]); - out[7] = _mm_sub_epi16(step1[0], step1[7]); -} - -// For each 8x32 block __m128i in[32], -// Input with index, 2, 6 -// output pixels: 8-15 in __m128i out[32] -static INLINE void idct32_34_8x32_quarter_2(const __m128i *const in /*in[32]*/, - __m128i *const out /*out[16]*/) { - const __m128i zero = _mm_setzero_si128(); - __m128i step1[16], step2[16]; - - // stage 2 - butterfly(in[2], zero, cospi_30_64, cospi_2_64, &step2[8], &step2[15]); - butterfly(zero, in[6], cospi_6_64, cospi_26_64, &step2[11], &step2[12]); - - // stage 3 - step1[8] = step2[8]; - step1[9] = step2[8]; - step1[14] = step2[15]; - step1[15] = step2[15]; - step1[10] = step2[11]; - step1[11] = step2[11]; - step1[12] = step2[12]; - step1[13] = step2[12]; - - idct32_8x32_quarter_2_stage_4_to_6(step1, out); -} - -static INLINE void idct32_34_8x32_quarter_1_2( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i temp[16]; - idct32_34_8x32_quarter_1(in, temp); - idct32_34_8x32_quarter_2(in, temp); - // stage 7 - add_sub_butterfly(temp, out, 16); -} - -// For each 8x32 block __m128i in[32], -// Input with odd index, 1, 3, 5, 7 -// output pixels: 16-23, 24-31 in __m128i out[32] -static INLINE void idct32_34_8x32_quarter_3_4( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - const __m128i zero = _mm_setzero_si128(); - __m128i step1[32]; - - // stage 1 - butterfly(in[1], zero, cospi_31_64, cospi_1_64, &step1[16], &step1[31]); - butterfly(zero, in[7], cospi_7_64, cospi_25_64, &step1[19], &step1[28]); - butterfly(in[5], zero, cospi_27_64, cospi_5_64, &step1[20], &step1[27]); - butterfly(zero, in[3], cospi_3_64, cospi_29_64, &step1[23], &step1[24]); - - // stage 3 - butterfly(step1[31], step1[16], cospi_28_64, cospi_4_64, &step1[17], - &step1[30]); - butterfly(step1[28], step1[19], -cospi_4_64, cospi_28_64, &step1[18], - &step1[29]); - butterfly(step1[27], step1[20], cospi_12_64, cospi_20_64, &step1[21], - &step1[26]); - butterfly(step1[24], step1[23], -cospi_20_64, cospi_12_64, &step1[22], - &step1[25]); - - idct32_8x32_quarter_3_4_stage_4_to_7(step1, out); -} - -void idct32_34_8x32_sse2(const __m128i *const in /*in[32]*/, - __m128i *const out /*out[32]*/) { - __m128i temp[32]; - - idct32_34_8x32_quarter_1_2(in, temp); - idct32_34_8x32_quarter_3_4(in, temp); - // final stage - add_sub_butterfly(temp, out, 32); -} - -// Only upper-left 8x8 has non-zero coeff -void vpx_idct32x32_34_add_sse2(const tran_low_t *input, uint8_t *dest, - int stride) { - __m128i io[32], col[32]; - int i; - - // Load input data. Only need to load the top left 8x8 block. - load_transpose_16bit_8x8(input, 32, io); - idct32_34_8x32_sse2(io, col); - - for (i = 0; i < 32; i += 8) { - int j; - transpose_16bit_8x8(col + i, io); - idct32_34_8x32_sse2(io, io); - - for (j = 0; j < 32; ++j) { - write_buffer_8x1(dest + j * stride, io[j]); - } - - dest += 8; - } -} - -// For each 8x32 block __m128i in[32], -// Input with index, 0, 4, 8, 12, 16, 20, 24, 28 -// output pixels: 0-7 in __m128i out[32] -static INLINE void idct32_1024_8x32_quarter_1( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[8]*/) { - __m128i step1[8], step2[8]; - - // stage 3 - butterfly(in[4], in[28], cospi_28_64, cospi_4_64, &step1[4], &step1[7]); - butterfly(in[20], in[12], cospi_12_64, cospi_20_64, &step1[5], &step1[6]); - - // stage 4 - butterfly(in[0], in[16], cospi_16_64, cospi_16_64, &step2[1], &step2[0]); - butterfly(in[8], in[24], cospi_24_64, cospi_8_64, &step2[2], &step2[3]); - step2[4] = _mm_add_epi16(step1[4], step1[5]); - step2[5] = _mm_sub_epi16(step1[4], step1[5]); - step2[6] = _mm_sub_epi16(step1[7], step1[6]); - step2[7] = _mm_add_epi16(step1[7], step1[6]); - - // stage 5 - step1[0] = _mm_add_epi16(step2[0], step2[3]); - step1[1] = _mm_add_epi16(step2[1], step2[2]); - step1[2] = _mm_sub_epi16(step2[1], step2[2]); - step1[3] = _mm_sub_epi16(step2[0], step2[3]); - step1[4] = step2[4]; - butterfly(step2[6], step2[5], cospi_16_64, cospi_16_64, &step1[5], &step1[6]); - step1[7] = step2[7]; - - // stage 6 - out[0] = _mm_add_epi16(step1[0], step1[7]); - out[1] = _mm_add_epi16(step1[1], step1[6]); - out[2] = _mm_add_epi16(step1[2], step1[5]); - out[3] = _mm_add_epi16(step1[3], step1[4]); - out[4] = _mm_sub_epi16(step1[3], step1[4]); - out[5] = _mm_sub_epi16(step1[2], step1[5]); - out[6] = _mm_sub_epi16(step1[1], step1[6]); - out[7] = _mm_sub_epi16(step1[0], step1[7]); -} - -// For each 8x32 block __m128i in[32], -// Input with index, 2, 6, 10, 14, 18, 22, 26, 30 -// output pixels: 8-15 in __m128i out[32] -static INLINE void idct32_1024_8x32_quarter_2( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[16]*/) { - __m128i step1[16], step2[16]; - - // stage 2 - butterfly(in[2], in[30], cospi_30_64, cospi_2_64, &step2[8], &step2[15]); - butterfly(in[18], in[14], cospi_14_64, cospi_18_64, &step2[9], &step2[14]); - butterfly(in[10], in[22], cospi_22_64, cospi_10_64, &step2[10], &step2[13]); - butterfly(in[26], in[6], cospi_6_64, cospi_26_64, &step2[11], &step2[12]); - - // stage 3 - step1[8] = _mm_add_epi16(step2[8], step2[9]); - step1[9] = _mm_sub_epi16(step2[8], step2[9]); - step1[10] = _mm_sub_epi16(step2[11], step2[10]); - step1[11] = _mm_add_epi16(step2[11], step2[10]); - step1[12] = _mm_add_epi16(step2[12], step2[13]); - step1[13] = _mm_sub_epi16(step2[12], step2[13]); - step1[14] = _mm_sub_epi16(step2[15], step2[14]); - step1[15] = _mm_add_epi16(step2[15], step2[14]); - - idct32_8x32_quarter_2_stage_4_to_6(step1, out); -} - -static INLINE void idct32_1024_8x32_quarter_1_2( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i temp[16]; - idct32_1024_8x32_quarter_1(in, temp); - idct32_1024_8x32_quarter_2(in, temp); - // stage 7 - add_sub_butterfly(temp, out, 16); -} - -// For each 8x32 block __m128i in[32], -// Input with odd index, -// 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 -// output pixels: 16-23, 24-31 in __m128i out[32] -static INLINE void idct32_1024_8x32_quarter_3_4( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i step1[32], step2[32]; - - // stage 1 - butterfly(in[1], in[31], cospi_31_64, cospi_1_64, &step1[16], &step1[31]); - butterfly(in[17], in[15], cospi_15_64, cospi_17_64, &step1[17], &step1[30]); - butterfly(in[9], in[23], cospi_23_64, cospi_9_64, &step1[18], &step1[29]); - butterfly(in[25], in[7], cospi_7_64, cospi_25_64, &step1[19], &step1[28]); - - butterfly(in[5], in[27], cospi_27_64, cospi_5_64, &step1[20], &step1[27]); - butterfly(in[21], in[11], cospi_11_64, cospi_21_64, &step1[21], &step1[26]); - - butterfly(in[13], in[19], cospi_19_64, cospi_13_64, &step1[22], &step1[25]); - butterfly(in[29], in[3], cospi_3_64, cospi_29_64, &step1[23], &step1[24]); - - // stage 2 - step2[16] = _mm_add_epi16(step1[16], step1[17]); - step2[17] = _mm_sub_epi16(step1[16], step1[17]); - step2[18] = _mm_sub_epi16(step1[19], step1[18]); - step2[19] = _mm_add_epi16(step1[19], step1[18]); - step2[20] = _mm_add_epi16(step1[20], step1[21]); - step2[21] = _mm_sub_epi16(step1[20], step1[21]); - step2[22] = _mm_sub_epi16(step1[23], step1[22]); - step2[23] = _mm_add_epi16(step1[23], step1[22]); - - step2[24] = _mm_add_epi16(step1[24], step1[25]); - step2[25] = _mm_sub_epi16(step1[24], step1[25]); - step2[26] = _mm_sub_epi16(step1[27], step1[26]); - step2[27] = _mm_add_epi16(step1[27], step1[26]); - step2[28] = _mm_add_epi16(step1[28], step1[29]); - step2[29] = _mm_sub_epi16(step1[28], step1[29]); - step2[30] = _mm_sub_epi16(step1[31], step1[30]); - step2[31] = _mm_add_epi16(step1[31], step1[30]); - - // stage 3 - step1[16] = step2[16]; - step1[31] = step2[31]; - butterfly(step2[30], step2[17], cospi_28_64, cospi_4_64, &step1[17], - &step1[30]); - butterfly(step2[29], step2[18], -cospi_4_64, cospi_28_64, &step1[18], - &step1[29]); - step1[19] = step2[19]; - step1[20] = step2[20]; - butterfly(step2[26], step2[21], cospi_12_64, cospi_20_64, &step1[21], - &step1[26]); - butterfly(step2[25], step2[22], -cospi_20_64, cospi_12_64, &step1[22], - &step1[25]); - step1[23] = step2[23]; - step1[24] = step2[24]; - step1[27] = step2[27]; - step1[28] = step2[28]; - - idct32_8x32_quarter_3_4_stage_4_to_7(step1, out); -} - -void idct32_1024_8x32(const __m128i *const in /*in[32]*/, - __m128i *const out /*out[32]*/) { - __m128i temp[32]; - - idct32_1024_8x32_quarter_1_2(in, temp); - idct32_1024_8x32_quarter_3_4(in, temp); - // final stage - add_sub_butterfly(temp, out, 32); -} - -void vpx_idct32x32_1024_add_sse2(const tran_low_t *input, uint8_t *dest, - int stride) { - __m128i col[4][32], io[32]; - int i; - - // rows - for (i = 0; i < 4; i++) { - load_transpose_16bit_8x8(&input[0], 32, &io[0]); - load_transpose_16bit_8x8(&input[8], 32, &io[8]); - load_transpose_16bit_8x8(&input[16], 32, &io[16]); - load_transpose_16bit_8x8(&input[24], 32, &io[24]); - idct32_1024_8x32(io, col[i]); - input += 32 << 3; - } - - // columns - for (i = 0; i < 32; i += 8) { - // Transpose 32x8 block to 8x32 block - transpose_16bit_8x8(col[0] + i, io); - transpose_16bit_8x8(col[1] + i, io + 8); - transpose_16bit_8x8(col[2] + i, io + 16); - transpose_16bit_8x8(col[3] + i, io + 24); - - idct32_1024_8x32(io, io); - store_buffer_8x32(io, dest, stride); - dest += 8; - } -} - -void vpx_idct32x32_135_add_sse2(const tran_low_t *input, uint8_t *dest, - int stride) { - __m128i col[2][32], in[32], out[32]; - int i; - - for (i = 16; i < 32; i++) { - in[i] = _mm_setzero_si128(); - } - - // rows - for (i = 0; i < 2; i++) { - load_transpose_16bit_8x8(&input[0], 32, &in[0]); - load_transpose_16bit_8x8(&input[8], 32, &in[8]); - idct32_1024_8x32(in, col[i]); - input += 32 << 3; - } - - // columns - for (i = 0; i < 32; i += 8) { - transpose_16bit_8x8(col[0] + i, in); - transpose_16bit_8x8(col[1] + i, in + 8); - idct32_1024_8x32(in, out); - store_buffer_8x32(out, dest, stride); - dest += 8; - } -} - -void vpx_idct32x32_1_add_sse2(const tran_low_t *input, uint8_t *dest, - int stride) { - __m128i dc_value; - int j; - tran_high_t a1; - tran_low_t out = - WRAPLOW(dct_const_round_shift((int16_t)input[0] * cospi_16_64)); - - out = WRAPLOW(dct_const_round_shift(out * cospi_16_64)); - a1 = ROUND_POWER_OF_TWO(out, 6); - dc_value = _mm_set1_epi16((int16_t)a1); - - for (j = 0; j < 32; ++j) { - recon_and_store_16(dest + j * stride + 0, dc_value); - recon_and_store_16(dest + j * stride + 16, dc_value); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_txfm_sse2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_txfm_sse2.h deleted file mode 100644 index b4bbd186..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_txfm_sse2.h +++ /dev/null @@ -1,710 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_X86_INV_TXFM_SSE2_H_ -#define VPX_VPX_DSP_X86_INV_TXFM_SSE2_H_ - -#include // SSE2 - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/inv_txfm.h" -#include "vpx_dsp/x86/transpose_sse2.h" -#include "vpx_dsp/x86/txfm_common_sse2.h" - -static INLINE void idct8x8_12_transpose_16bit_4x8(const __m128i *const in, - __m128i *const out) { - // Unpack 16 bit elements. Goes from: - // in[0]: 30 31 32 33 00 01 02 03 - // in[1]: 20 21 22 23 10 11 12 13 - // in[2]: 40 41 42 43 70 71 72 73 - // in[3]: 50 51 52 53 60 61 62 63 - // to: - // tr0_0: 00 10 01 11 02 12 03 13 - // tr0_1: 20 30 21 31 22 32 23 33 - // tr0_2: 40 50 41 51 42 52 43 53 - // tr0_3: 60 70 61 71 62 72 63 73 - const __m128i tr0_0 = _mm_unpackhi_epi16(in[0], in[1]); - const __m128i tr0_1 = _mm_unpacklo_epi16(in[1], in[0]); - const __m128i tr0_2 = _mm_unpacklo_epi16(in[2], in[3]); - const __m128i tr0_3 = _mm_unpackhi_epi16(in[3], in[2]); - - // Unpack 32 bit elements resulting in: - // tr1_0: 00 10 20 30 01 11 21 31 - // tr1_1: 02 12 22 32 03 13 23 33 - // tr1_2: 40 50 60 70 41 51 61 71 - // tr1_3: 42 52 62 72 43 53 63 73 - const __m128i tr1_0 = _mm_unpacklo_epi32(tr0_0, tr0_1); - const __m128i tr1_1 = _mm_unpacklo_epi32(tr0_2, tr0_3); - const __m128i tr1_2 = _mm_unpackhi_epi32(tr0_0, tr0_1); - const __m128i tr1_3 = _mm_unpackhi_epi32(tr0_2, tr0_3); - - // Unpack 64 bit elements resulting in: - // out[0]: 00 10 20 30 40 50 60 70 - // out[1]: 01 11 21 31 41 51 61 71 - // out[2]: 02 12 22 32 42 52 62 72 - // out[3]: 03 13 23 33 43 53 63 73 - out[0] = _mm_unpacklo_epi64(tr1_0, tr1_1); - out[1] = _mm_unpackhi_epi64(tr1_0, tr1_1); - out[2] = _mm_unpacklo_epi64(tr1_2, tr1_3); - out[3] = _mm_unpackhi_epi64(tr1_2, tr1_3); -} - -static INLINE __m128i dct_const_round_shift_sse2(const __m128i in) { - const __m128i t = _mm_add_epi32(in, _mm_set1_epi32(DCT_CONST_ROUNDING)); - return _mm_srai_epi32(t, DCT_CONST_BITS); -} - -static INLINE __m128i idct_madd_round_shift_sse2(const __m128i in, - const __m128i cospi) { - const __m128i t = _mm_madd_epi16(in, cospi); - return dct_const_round_shift_sse2(t); -} - -// Calculate the dot product between in0/1 and x and wrap to short. -static INLINE __m128i idct_calc_wraplow_sse2(const __m128i in0, - const __m128i in1, - const __m128i x) { - const __m128i t0 = idct_madd_round_shift_sse2(in0, x); - const __m128i t1 = idct_madd_round_shift_sse2(in1, x); - return _mm_packs_epi32(t0, t1); -} - -// Multiply elements by constants and add them together. -static INLINE void butterfly(const __m128i in0, const __m128i in1, const int c0, - const int c1, __m128i *const out0, - __m128i *const out1) { - const __m128i cst0 = pair_set_epi16(c0, -c1); - const __m128i cst1 = pair_set_epi16(c1, c0); - const __m128i lo = _mm_unpacklo_epi16(in0, in1); - const __m128i hi = _mm_unpackhi_epi16(in0, in1); - *out0 = idct_calc_wraplow_sse2(lo, hi, cst0); - *out1 = idct_calc_wraplow_sse2(lo, hi, cst1); -} - -static INLINE __m128i butterfly_cospi16(const __m128i in) { - const __m128i cst = pair_set_epi16(cospi_16_64, cospi_16_64); - const __m128i lo = _mm_unpacklo_epi16(in, _mm_setzero_si128()); - const __m128i hi = _mm_unpackhi_epi16(in, _mm_setzero_si128()); - return idct_calc_wraplow_sse2(lo, hi, cst); -} - -// Functions to allow 8 bit optimisations to be used when profile 0 is used with -// highbitdepth enabled -static INLINE __m128i load_input_data4(const tran_low_t *data) { -#if CONFIG_VP9_HIGHBITDEPTH - const __m128i zero = _mm_setzero_si128(); - const __m128i in = _mm_load_si128((const __m128i *)data); - return _mm_packs_epi32(in, zero); -#else - return _mm_loadl_epi64((const __m128i *)data); -#endif -} - -static INLINE __m128i load_input_data8(const tran_low_t *data) { -#if CONFIG_VP9_HIGHBITDEPTH - const __m128i in0 = _mm_load_si128((const __m128i *)data); - const __m128i in1 = _mm_load_si128((const __m128i *)(data + 4)); - return _mm_packs_epi32(in0, in1); -#else - return _mm_load_si128((const __m128i *)data); -#endif -} - -static INLINE void load_transpose_16bit_8x8(const tran_low_t *input, - const int stride, - __m128i *const in) { - in[0] = load_input_data8(input + 0 * stride); - in[1] = load_input_data8(input + 1 * stride); - in[2] = load_input_data8(input + 2 * stride); - in[3] = load_input_data8(input + 3 * stride); - in[4] = load_input_data8(input + 4 * stride); - in[5] = load_input_data8(input + 5 * stride); - in[6] = load_input_data8(input + 6 * stride); - in[7] = load_input_data8(input + 7 * stride); - transpose_16bit_8x8(in, in); -} - -static INLINE void recon_and_store(uint8_t *const dest, const __m128i in_x) { - const __m128i zero = _mm_setzero_si128(); - __m128i d0 = _mm_loadl_epi64((__m128i *)(dest)); - d0 = _mm_unpacklo_epi8(d0, zero); - d0 = _mm_add_epi16(in_x, d0); - d0 = _mm_packus_epi16(d0, d0); - _mm_storel_epi64((__m128i *)(dest), d0); -} - -static INLINE void round_shift_8x8(const __m128i *const in, - __m128i *const out) { - const __m128i final_rounding = _mm_set1_epi16(1 << 4); - - out[0] = _mm_add_epi16(in[0], final_rounding); - out[1] = _mm_add_epi16(in[1], final_rounding); - out[2] = _mm_add_epi16(in[2], final_rounding); - out[3] = _mm_add_epi16(in[3], final_rounding); - out[4] = _mm_add_epi16(in[4], final_rounding); - out[5] = _mm_add_epi16(in[5], final_rounding); - out[6] = _mm_add_epi16(in[6], final_rounding); - out[7] = _mm_add_epi16(in[7], final_rounding); - - out[0] = _mm_srai_epi16(out[0], 5); - out[1] = _mm_srai_epi16(out[1], 5); - out[2] = _mm_srai_epi16(out[2], 5); - out[3] = _mm_srai_epi16(out[3], 5); - out[4] = _mm_srai_epi16(out[4], 5); - out[5] = _mm_srai_epi16(out[5], 5); - out[6] = _mm_srai_epi16(out[6], 5); - out[7] = _mm_srai_epi16(out[7], 5); -} - -static INLINE void write_buffer_8x8(const __m128i *const in, - uint8_t *const dest, const int stride) { - __m128i t[8]; - - round_shift_8x8(in, t); - - recon_and_store(dest + 0 * stride, t[0]); - recon_and_store(dest + 1 * stride, t[1]); - recon_and_store(dest + 2 * stride, t[2]); - recon_and_store(dest + 3 * stride, t[3]); - recon_and_store(dest + 4 * stride, t[4]); - recon_and_store(dest + 5 * stride, t[5]); - recon_and_store(dest + 6 * stride, t[6]); - recon_and_store(dest + 7 * stride, t[7]); -} - -static INLINE void recon_and_store4x4_sse2(const __m128i *const in, - uint8_t *const dest, - const int stride) { - const __m128i zero = _mm_setzero_si128(); - __m128i d[2]; - - // Reconstruction and Store - d[0] = _mm_cvtsi32_si128(*(const int *)(dest)); - d[1] = _mm_cvtsi32_si128(*(const int *)(dest + stride * 3)); - d[0] = _mm_unpacklo_epi32(d[0], - _mm_cvtsi32_si128(*(const int *)(dest + stride))); - d[1] = _mm_unpacklo_epi32( - _mm_cvtsi32_si128(*(const int *)(dest + stride * 2)), d[1]); - d[0] = _mm_unpacklo_epi8(d[0], zero); - d[1] = _mm_unpacklo_epi8(d[1], zero); - d[0] = _mm_add_epi16(d[0], in[0]); - d[1] = _mm_add_epi16(d[1], in[1]); - d[0] = _mm_packus_epi16(d[0], d[1]); - - *(int *)dest = _mm_cvtsi128_si32(d[0]); - d[0] = _mm_srli_si128(d[0], 4); - *(int *)(dest + stride) = _mm_cvtsi128_si32(d[0]); - d[0] = _mm_srli_si128(d[0], 4); - *(int *)(dest + stride * 2) = _mm_cvtsi128_si32(d[0]); - d[0] = _mm_srli_si128(d[0], 4); - *(int *)(dest + stride * 3) = _mm_cvtsi128_si32(d[0]); -} - -static INLINE void store_buffer_8x32(__m128i *in, uint8_t *dst, int stride) { - const __m128i final_rounding = _mm_set1_epi16(1 << 5); - int j = 0; - while (j < 32) { - in[j] = _mm_adds_epi16(in[j], final_rounding); - in[j + 1] = _mm_adds_epi16(in[j + 1], final_rounding); - - in[j] = _mm_srai_epi16(in[j], 6); - in[j + 1] = _mm_srai_epi16(in[j + 1], 6); - - recon_and_store(dst, in[j]); - dst += stride; - recon_and_store(dst, in[j + 1]); - dst += stride; - j += 2; - } -} - -static INLINE void write_buffer_8x1(uint8_t *const dest, const __m128i in) { - const __m128i final_rounding = _mm_set1_epi16(1 << 5); - __m128i out; - out = _mm_adds_epi16(in, final_rounding); - out = _mm_srai_epi16(out, 6); - recon_and_store(dest, out); -} - -// Only do addition and subtraction butterfly, size = 16, 32 -static INLINE void add_sub_butterfly(const __m128i *in, __m128i *out, - int size) { - int i = 0; - const int num = size >> 1; - const int bound = size - 1; - while (i < num) { - out[i] = _mm_add_epi16(in[i], in[bound - i]); - out[bound - i] = _mm_sub_epi16(in[i], in[bound - i]); - i++; - } -} - -static INLINE void idct8(const __m128i *const in /*in[8]*/, - __m128i *const out /*out[8]*/) { - __m128i step1[8], step2[8]; - - // stage 1 - butterfly(in[1], in[7], cospi_28_64, cospi_4_64, &step1[4], &step1[7]); - butterfly(in[5], in[3], cospi_12_64, cospi_20_64, &step1[5], &step1[6]); - - // stage 2 - butterfly(in[0], in[4], cospi_16_64, cospi_16_64, &step2[1], &step2[0]); - butterfly(in[2], in[6], cospi_24_64, cospi_8_64, &step2[2], &step2[3]); - - step2[4] = _mm_add_epi16(step1[4], step1[5]); - step2[5] = _mm_sub_epi16(step1[4], step1[5]); - step2[6] = _mm_sub_epi16(step1[7], step1[6]); - step2[7] = _mm_add_epi16(step1[7], step1[6]); - - // stage 3 - step1[0] = _mm_add_epi16(step2[0], step2[3]); - step1[1] = _mm_add_epi16(step2[1], step2[2]); - step1[2] = _mm_sub_epi16(step2[1], step2[2]); - step1[3] = _mm_sub_epi16(step2[0], step2[3]); - butterfly(step2[6], step2[5], cospi_16_64, cospi_16_64, &step1[5], &step1[6]); - - // stage 4 - out[0] = _mm_add_epi16(step1[0], step2[7]); - out[1] = _mm_add_epi16(step1[1], step1[6]); - out[2] = _mm_add_epi16(step1[2], step1[5]); - out[3] = _mm_add_epi16(step1[3], step2[4]); - out[4] = _mm_sub_epi16(step1[3], step2[4]); - out[5] = _mm_sub_epi16(step1[2], step1[5]); - out[6] = _mm_sub_epi16(step1[1], step1[6]); - out[7] = _mm_sub_epi16(step1[0], step2[7]); -} - -static INLINE void idct8x8_12_add_kernel_sse2(__m128i *const io /*io[8]*/) { - const __m128i zero = _mm_setzero_si128(); - const __m128i cp_16_16 = pair_set_epi16(cospi_16_64, cospi_16_64); - const __m128i cp_16_n16 = pair_set_epi16(cospi_16_64, -cospi_16_64); - __m128i step1[8], step2[8], tmp[4]; - - transpose_16bit_4x4(io, io); - // io[0]: 00 10 20 30 01 11 21 31 - // io[1]: 02 12 22 32 03 13 23 33 - - // stage 1 - { - const __m128i cp_28_n4 = pair_set_epi16(cospi_28_64, -cospi_4_64); - const __m128i cp_4_28 = pair_set_epi16(cospi_4_64, cospi_28_64); - const __m128i cp_n20_12 = pair_set_epi16(-cospi_20_64, cospi_12_64); - const __m128i cp_12_20 = pair_set_epi16(cospi_12_64, cospi_20_64); - const __m128i lo_1 = _mm_unpackhi_epi16(io[0], zero); - const __m128i lo_3 = _mm_unpackhi_epi16(io[1], zero); - step1[4] = idct_calc_wraplow_sse2(cp_28_n4, cp_4_28, lo_1); // step1 4&7 - step1[5] = idct_calc_wraplow_sse2(cp_n20_12, cp_12_20, lo_3); // step1 5&6 - } - - // stage 2 - { - const __m128i cp_24_n8 = pair_set_epi16(cospi_24_64, -cospi_8_64); - const __m128i cp_8_24 = pair_set_epi16(cospi_8_64, cospi_24_64); - const __m128i lo_0 = _mm_unpacklo_epi16(io[0], zero); - const __m128i lo_2 = _mm_unpacklo_epi16(io[1], zero); - const __m128i t = idct_madd_round_shift_sse2(cp_16_16, lo_0); - step2[0] = _mm_packs_epi32(t, t); // step2 0&1 - step2[2] = idct_calc_wraplow_sse2(cp_8_24, cp_24_n8, lo_2); // step2 3&2 - step2[4] = _mm_add_epi16(step1[4], step1[5]); // step2 4&7 - step2[5] = _mm_sub_epi16(step1[4], step1[5]); // step2 5&6 - step2[6] = _mm_unpackhi_epi64(step2[5], zero); // step2 6 - } - - // stage 3 - { - const __m128i lo_65 = _mm_unpacklo_epi16(step2[6], step2[5]); - tmp[0] = _mm_add_epi16(step2[0], step2[2]); // step1 0&1 - tmp[1] = _mm_sub_epi16(step2[0], step2[2]); // step1 3&2 - step1[2] = _mm_unpackhi_epi64(tmp[1], tmp[0]); // step1 2&1 - step1[3] = _mm_unpacklo_epi64(tmp[1], tmp[0]); // step1 3&0 - step1[5] = idct_calc_wraplow_sse2(cp_16_n16, cp_16_16, lo_65); // step1 5&6 - } - - // stage 4 - tmp[0] = _mm_add_epi16(step1[3], step2[4]); // output 3&0 - tmp[1] = _mm_add_epi16(step1[2], step1[5]); // output 2&1 - tmp[2] = _mm_sub_epi16(step1[3], step2[4]); // output 4&7 - tmp[3] = _mm_sub_epi16(step1[2], step1[5]); // output 5&6 - - idct8x8_12_transpose_16bit_4x8(tmp, io); - io[4] = io[5] = io[6] = io[7] = zero; - - idct8(io, io); -} - -static INLINE void idct16_8col(const __m128i *const in /*in[16]*/, - __m128i *const out /*out[16]*/) { - __m128i step1[16], step2[16]; - - // stage 2 - butterfly(in[1], in[15], cospi_30_64, cospi_2_64, &step2[8], &step2[15]); - butterfly(in[9], in[7], cospi_14_64, cospi_18_64, &step2[9], &step2[14]); - butterfly(in[5], in[11], cospi_22_64, cospi_10_64, &step2[10], &step2[13]); - butterfly(in[13], in[3], cospi_6_64, cospi_26_64, &step2[11], &step2[12]); - - // stage 3 - butterfly(in[2], in[14], cospi_28_64, cospi_4_64, &step1[4], &step1[7]); - butterfly(in[10], in[6], cospi_12_64, cospi_20_64, &step1[5], &step1[6]); - step1[8] = _mm_add_epi16(step2[8], step2[9]); - step1[9] = _mm_sub_epi16(step2[8], step2[9]); - step1[10] = _mm_sub_epi16(step2[11], step2[10]); - step1[11] = _mm_add_epi16(step2[10], step2[11]); - step1[12] = _mm_add_epi16(step2[12], step2[13]); - step1[13] = _mm_sub_epi16(step2[12], step2[13]); - step1[14] = _mm_sub_epi16(step2[15], step2[14]); - step1[15] = _mm_add_epi16(step2[14], step2[15]); - - // stage 4 - butterfly(in[0], in[8], cospi_16_64, cospi_16_64, &step2[1], &step2[0]); - butterfly(in[4], in[12], cospi_24_64, cospi_8_64, &step2[2], &step2[3]); - butterfly(step1[14], step1[9], cospi_24_64, cospi_8_64, &step2[9], - &step2[14]); - butterfly(step1[10], step1[13], -cospi_8_64, -cospi_24_64, &step2[13], - &step2[10]); - step2[5] = _mm_sub_epi16(step1[4], step1[5]); - step1[4] = _mm_add_epi16(step1[4], step1[5]); - step2[6] = _mm_sub_epi16(step1[7], step1[6]); - step1[7] = _mm_add_epi16(step1[6], step1[7]); - step2[8] = step1[8]; - step2[11] = step1[11]; - step2[12] = step1[12]; - step2[15] = step1[15]; - - // stage 5 - step1[0] = _mm_add_epi16(step2[0], step2[3]); - step1[1] = _mm_add_epi16(step2[1], step2[2]); - step1[2] = _mm_sub_epi16(step2[1], step2[2]); - step1[3] = _mm_sub_epi16(step2[0], step2[3]); - butterfly(step2[6], step2[5], cospi_16_64, cospi_16_64, &step1[5], &step1[6]); - step1[8] = _mm_add_epi16(step2[8], step2[11]); - step1[9] = _mm_add_epi16(step2[9], step2[10]); - step1[10] = _mm_sub_epi16(step2[9], step2[10]); - step1[11] = _mm_sub_epi16(step2[8], step2[11]); - step1[12] = _mm_sub_epi16(step2[15], step2[12]); - step1[13] = _mm_sub_epi16(step2[14], step2[13]); - step1[14] = _mm_add_epi16(step2[14], step2[13]); - step1[15] = _mm_add_epi16(step2[15], step2[12]); - - // stage 6 - step2[0] = _mm_add_epi16(step1[0], step1[7]); - step2[1] = _mm_add_epi16(step1[1], step1[6]); - step2[2] = _mm_add_epi16(step1[2], step1[5]); - step2[3] = _mm_add_epi16(step1[3], step1[4]); - step2[4] = _mm_sub_epi16(step1[3], step1[4]); - step2[5] = _mm_sub_epi16(step1[2], step1[5]); - step2[6] = _mm_sub_epi16(step1[1], step1[6]); - step2[7] = _mm_sub_epi16(step1[0], step1[7]); - butterfly(step1[13], step1[10], cospi_16_64, cospi_16_64, &step2[10], - &step2[13]); - butterfly(step1[12], step1[11], cospi_16_64, cospi_16_64, &step2[11], - &step2[12]); - - // stage 7 - out[0] = _mm_add_epi16(step2[0], step1[15]); - out[1] = _mm_add_epi16(step2[1], step1[14]); - out[2] = _mm_add_epi16(step2[2], step2[13]); - out[3] = _mm_add_epi16(step2[3], step2[12]); - out[4] = _mm_add_epi16(step2[4], step2[11]); - out[5] = _mm_add_epi16(step2[5], step2[10]); - out[6] = _mm_add_epi16(step2[6], step1[9]); - out[7] = _mm_add_epi16(step2[7], step1[8]); - out[8] = _mm_sub_epi16(step2[7], step1[8]); - out[9] = _mm_sub_epi16(step2[6], step1[9]); - out[10] = _mm_sub_epi16(step2[5], step2[10]); - out[11] = _mm_sub_epi16(step2[4], step2[11]); - out[12] = _mm_sub_epi16(step2[3], step2[12]); - out[13] = _mm_sub_epi16(step2[2], step2[13]); - out[14] = _mm_sub_epi16(step2[1], step1[14]); - out[15] = _mm_sub_epi16(step2[0], step1[15]); -} - -static INLINE void idct16x16_10_pass1(const __m128i *const input /*input[4]*/, - __m128i *const output /*output[16]*/) { - const __m128i zero = _mm_setzero_si128(); - const __m128i k__cospi_p16_p16 = pair_set_epi16(cospi_16_64, cospi_16_64); - const __m128i k__cospi_m16_p16 = pair_set_epi16(-cospi_16_64, cospi_16_64); - __m128i step1[16], step2[16]; - - transpose_16bit_4x4(input, output); - - // stage 2 - { - const __m128i k__cospi_p30_m02 = pair_set_epi16(cospi_30_64, -cospi_2_64); - const __m128i k__cospi_p02_p30 = pair_set_epi16(cospi_2_64, cospi_30_64); - const __m128i k__cospi_p06_m26 = pair_set_epi16(cospi_6_64, -cospi_26_64); - const __m128i k__cospi_p26_p06 = pair_set_epi16(cospi_26_64, cospi_6_64); - const __m128i lo_1_15 = _mm_unpackhi_epi16(output[0], zero); - const __m128i lo_13_3 = _mm_unpackhi_epi16(zero, output[1]); - step2[8] = idct_calc_wraplow_sse2(k__cospi_p30_m02, k__cospi_p02_p30, - lo_1_15); // step2 8&15 - step2[11] = idct_calc_wraplow_sse2(k__cospi_p06_m26, k__cospi_p26_p06, - lo_13_3); // step2 11&12 - } - - // stage 3 - { - const __m128i k__cospi_p28_m04 = pair_set_epi16(cospi_28_64, -cospi_4_64); - const __m128i k__cospi_p04_p28 = pair_set_epi16(cospi_4_64, cospi_28_64); - const __m128i lo_2_14 = _mm_unpacklo_epi16(output[1], zero); - step1[4] = idct_calc_wraplow_sse2(k__cospi_p28_m04, k__cospi_p04_p28, - lo_2_14); // step1 4&7 - step1[13] = _mm_unpackhi_epi64(step2[11], zero); - step1[14] = _mm_unpackhi_epi64(step2[8], zero); - } - - // stage 4 - { - const __m128i k__cospi_m08_p24 = pair_set_epi16(-cospi_8_64, cospi_24_64); - const __m128i k__cospi_p24_p08 = pair_set_epi16(cospi_24_64, cospi_8_64); - const __m128i k__cospi_m24_m08 = pair_set_epi16(-cospi_24_64, -cospi_8_64); - const __m128i lo_0_8 = _mm_unpacklo_epi16(output[0], zero); - const __m128i lo_9_14 = _mm_unpacklo_epi16(step2[8], step1[14]); - const __m128i lo_10_13 = _mm_unpacklo_epi16(step2[11], step1[13]); - const __m128i t = idct_madd_round_shift_sse2(lo_0_8, k__cospi_p16_p16); - step1[0] = _mm_packs_epi32(t, t); // step2 0&1 - step2[9] = idct_calc_wraplow_sse2(k__cospi_m08_p24, k__cospi_p24_p08, - lo_9_14); // step2 9&14 - step2[10] = idct_calc_wraplow_sse2(k__cospi_m24_m08, k__cospi_m08_p24, - lo_10_13); // step2 10&13 - step2[6] = _mm_unpackhi_epi64(step1[4], zero); - } - - // stage 5 - { - const __m128i lo_5_6 = _mm_unpacklo_epi16(step1[4], step2[6]); - step1[6] = idct_calc_wraplow_sse2(k__cospi_p16_p16, k__cospi_m16_p16, - lo_5_6); // step1 6&5 - step1[8] = _mm_add_epi16(step2[8], step2[11]); - step1[9] = _mm_add_epi16(step2[9], step2[10]); - step1[10] = _mm_sub_epi16(step2[9], step2[10]); - step1[11] = _mm_sub_epi16(step2[8], step2[11]); - step1[12] = _mm_unpackhi_epi64(step1[11], zero); - step1[13] = _mm_unpackhi_epi64(step1[10], zero); - step1[14] = _mm_unpackhi_epi64(step1[9], zero); - step1[15] = _mm_unpackhi_epi64(step1[8], zero); - } - - // stage 6 - { - const __m128i lo_10_13 = _mm_unpacklo_epi16(step1[10], step1[13]); - const __m128i lo_11_12 = _mm_unpacklo_epi16(step1[11], step1[12]); - step2[10] = idct_calc_wraplow_sse2(k__cospi_m16_p16, k__cospi_p16_p16, - lo_10_13); // step2 10&13 - step2[11] = idct_calc_wraplow_sse2(k__cospi_m16_p16, k__cospi_p16_p16, - lo_11_12); // step2 11&12 - step2[13] = _mm_unpackhi_epi64(step2[10], zero); - step2[12] = _mm_unpackhi_epi64(step2[11], zero); - step2[3] = _mm_add_epi16(step1[0], step1[4]); - step2[1] = _mm_add_epi16(step1[0], step1[6]); - step2[6] = _mm_sub_epi16(step1[0], step1[6]); - step2[4] = _mm_sub_epi16(step1[0], step1[4]); - step2[0] = _mm_unpackhi_epi64(step2[3], zero); - step2[2] = _mm_unpackhi_epi64(step2[1], zero); - step2[5] = _mm_unpackhi_epi64(step2[6], zero); - step2[7] = _mm_unpackhi_epi64(step2[4], zero); - } - - // stage 7. Left 8x16 only. - output[0] = _mm_add_epi16(step2[0], step1[15]); - output[1] = _mm_add_epi16(step2[1], step1[14]); - output[2] = _mm_add_epi16(step2[2], step2[13]); - output[3] = _mm_add_epi16(step2[3], step2[12]); - output[4] = _mm_add_epi16(step2[4], step2[11]); - output[5] = _mm_add_epi16(step2[5], step2[10]); - output[6] = _mm_add_epi16(step2[6], step1[9]); - output[7] = _mm_add_epi16(step2[7], step1[8]); - output[8] = _mm_sub_epi16(step2[7], step1[8]); - output[9] = _mm_sub_epi16(step2[6], step1[9]); - output[10] = _mm_sub_epi16(step2[5], step2[10]); - output[11] = _mm_sub_epi16(step2[4], step2[11]); - output[12] = _mm_sub_epi16(step2[3], step2[12]); - output[13] = _mm_sub_epi16(step2[2], step2[13]); - output[14] = _mm_sub_epi16(step2[1], step1[14]); - output[15] = _mm_sub_epi16(step2[0], step1[15]); -} - -static INLINE void idct16x16_10_pass2(__m128i *const l /*l[8]*/, - __m128i *const io /*io[16]*/) { - const __m128i zero = _mm_setzero_si128(); - __m128i step1[16], step2[16]; - - transpose_16bit_4x8(l, io); - - // stage 2 - butterfly(io[1], zero, cospi_30_64, cospi_2_64, &step2[8], &step2[15]); - butterfly(zero, io[3], cospi_6_64, cospi_26_64, &step2[11], &step2[12]); - - // stage 3 - butterfly(io[2], zero, cospi_28_64, cospi_4_64, &step1[4], &step1[7]); - - // stage 4 - step1[0] = butterfly_cospi16(io[0]); - butterfly(step2[15], step2[8], cospi_24_64, cospi_8_64, &step2[9], - &step2[14]); - butterfly(step2[11], step2[12], -cospi_8_64, -cospi_24_64, &step2[13], - &step2[10]); - - // stage 5 - butterfly(step1[7], step1[4], cospi_16_64, cospi_16_64, &step1[5], &step1[6]); - step1[8] = _mm_add_epi16(step2[8], step2[11]); - step1[9] = _mm_add_epi16(step2[9], step2[10]); - step1[10] = _mm_sub_epi16(step2[9], step2[10]); - step1[11] = _mm_sub_epi16(step2[8], step2[11]); - step1[12] = _mm_sub_epi16(step2[15], step2[12]); - step1[13] = _mm_sub_epi16(step2[14], step2[13]); - step1[14] = _mm_add_epi16(step2[14], step2[13]); - step1[15] = _mm_add_epi16(step2[15], step2[12]); - - // stage 6 - step2[0] = _mm_add_epi16(step1[0], step1[7]); - step2[1] = _mm_add_epi16(step1[0], step1[6]); - step2[2] = _mm_add_epi16(step1[0], step1[5]); - step2[3] = _mm_add_epi16(step1[0], step1[4]); - step2[4] = _mm_sub_epi16(step1[0], step1[4]); - step2[5] = _mm_sub_epi16(step1[0], step1[5]); - step2[6] = _mm_sub_epi16(step1[0], step1[6]); - step2[7] = _mm_sub_epi16(step1[0], step1[7]); - butterfly(step1[13], step1[10], cospi_16_64, cospi_16_64, &step2[10], - &step2[13]); - butterfly(step1[12], step1[11], cospi_16_64, cospi_16_64, &step2[11], - &step2[12]); - - // stage 7 - io[0] = _mm_add_epi16(step2[0], step1[15]); - io[1] = _mm_add_epi16(step2[1], step1[14]); - io[2] = _mm_add_epi16(step2[2], step2[13]); - io[3] = _mm_add_epi16(step2[3], step2[12]); - io[4] = _mm_add_epi16(step2[4], step2[11]); - io[5] = _mm_add_epi16(step2[5], step2[10]); - io[6] = _mm_add_epi16(step2[6], step1[9]); - io[7] = _mm_add_epi16(step2[7], step1[8]); - io[8] = _mm_sub_epi16(step2[7], step1[8]); - io[9] = _mm_sub_epi16(step2[6], step1[9]); - io[10] = _mm_sub_epi16(step2[5], step2[10]); - io[11] = _mm_sub_epi16(step2[4], step2[11]); - io[12] = _mm_sub_epi16(step2[3], step2[12]); - io[13] = _mm_sub_epi16(step2[2], step2[13]); - io[14] = _mm_sub_epi16(step2[1], step1[14]); - io[15] = _mm_sub_epi16(step2[0], step1[15]); -} - -static INLINE void idct32_8x32_quarter_2_stage_4_to_6( - __m128i *const step1 /*step1[16]*/, __m128i *const out /*out[16]*/) { - __m128i step2[32]; - - // stage 4 - step2[8] = step1[8]; - step2[15] = step1[15]; - butterfly(step1[14], step1[9], cospi_24_64, cospi_8_64, &step2[9], - &step2[14]); - butterfly(step1[13], step1[10], -cospi_8_64, cospi_24_64, &step2[10], - &step2[13]); - step2[11] = step1[11]; - step2[12] = step1[12]; - - // stage 5 - step1[8] = _mm_add_epi16(step2[8], step2[11]); - step1[9] = _mm_add_epi16(step2[9], step2[10]); - step1[10] = _mm_sub_epi16(step2[9], step2[10]); - step1[11] = _mm_sub_epi16(step2[8], step2[11]); - step1[12] = _mm_sub_epi16(step2[15], step2[12]); - step1[13] = _mm_sub_epi16(step2[14], step2[13]); - step1[14] = _mm_add_epi16(step2[14], step2[13]); - step1[15] = _mm_add_epi16(step2[15], step2[12]); - - // stage 6 - out[8] = step1[8]; - out[9] = step1[9]; - butterfly(step1[13], step1[10], cospi_16_64, cospi_16_64, &out[10], &out[13]); - butterfly(step1[12], step1[11], cospi_16_64, cospi_16_64, &out[11], &out[12]); - out[14] = step1[14]; - out[15] = step1[15]; -} - -static INLINE void idct32_8x32_quarter_3_4_stage_4_to_7( - __m128i *const step1 /*step1[32]*/, __m128i *const out /*out[32]*/) { - __m128i step2[32]; - - // stage 4 - step2[16] = _mm_add_epi16(step1[16], step1[19]); - step2[17] = _mm_add_epi16(step1[17], step1[18]); - step2[18] = _mm_sub_epi16(step1[17], step1[18]); - step2[19] = _mm_sub_epi16(step1[16], step1[19]); - step2[20] = _mm_sub_epi16(step1[23], step1[20]); - step2[21] = _mm_sub_epi16(step1[22], step1[21]); - step2[22] = _mm_add_epi16(step1[22], step1[21]); - step2[23] = _mm_add_epi16(step1[23], step1[20]); - - step2[24] = _mm_add_epi16(step1[24], step1[27]); - step2[25] = _mm_add_epi16(step1[25], step1[26]); - step2[26] = _mm_sub_epi16(step1[25], step1[26]); - step2[27] = _mm_sub_epi16(step1[24], step1[27]); - step2[28] = _mm_sub_epi16(step1[31], step1[28]); - step2[29] = _mm_sub_epi16(step1[30], step1[29]); - step2[30] = _mm_add_epi16(step1[29], step1[30]); - step2[31] = _mm_add_epi16(step1[28], step1[31]); - - // stage 5 - step1[16] = step2[16]; - step1[17] = step2[17]; - butterfly(step2[29], step2[18], cospi_24_64, cospi_8_64, &step1[18], - &step1[29]); - butterfly(step2[28], step2[19], cospi_24_64, cospi_8_64, &step1[19], - &step1[28]); - butterfly(step2[27], step2[20], -cospi_8_64, cospi_24_64, &step1[20], - &step1[27]); - butterfly(step2[26], step2[21], -cospi_8_64, cospi_24_64, &step1[21], - &step1[26]); - step1[22] = step2[22]; - step1[23] = step2[23]; - step1[24] = step2[24]; - step1[25] = step2[25]; - step1[30] = step2[30]; - step1[31] = step2[31]; - - // stage 6 - out[16] = _mm_add_epi16(step1[16], step1[23]); - out[17] = _mm_add_epi16(step1[17], step1[22]); - out[18] = _mm_add_epi16(step1[18], step1[21]); - out[19] = _mm_add_epi16(step1[19], step1[20]); - step2[20] = _mm_sub_epi16(step1[19], step1[20]); - step2[21] = _mm_sub_epi16(step1[18], step1[21]); - step2[22] = _mm_sub_epi16(step1[17], step1[22]); - step2[23] = _mm_sub_epi16(step1[16], step1[23]); - - step2[24] = _mm_sub_epi16(step1[31], step1[24]); - step2[25] = _mm_sub_epi16(step1[30], step1[25]); - step2[26] = _mm_sub_epi16(step1[29], step1[26]); - step2[27] = _mm_sub_epi16(step1[28], step1[27]); - out[28] = _mm_add_epi16(step1[27], step1[28]); - out[29] = _mm_add_epi16(step1[26], step1[29]); - out[30] = _mm_add_epi16(step1[25], step1[30]); - out[31] = _mm_add_epi16(step1[24], step1[31]); - - // stage 7 - butterfly(step2[27], step2[20], cospi_16_64, cospi_16_64, &out[20], &out[27]); - butterfly(step2[26], step2[21], cospi_16_64, cospi_16_64, &out[21], &out[26]); - butterfly(step2[25], step2[22], cospi_16_64, cospi_16_64, &out[22], &out[25]); - butterfly(step2[24], step2[23], cospi_16_64, cospi_16_64, &out[23], &out[24]); -} - -void idct4_sse2(__m128i *const in); -void vpx_idct8_sse2(__m128i *const in); -void idct16_sse2(__m128i *const in0, __m128i *const in1); -void iadst4_sse2(__m128i *const in); -void iadst8_sse2(__m128i *const in); -void vpx_iadst16_8col_sse2(__m128i *const in); -void iadst16_sse2(__m128i *const in0, __m128i *const in1); -void idct32_1024_8x32(const __m128i *const in, __m128i *const out); -void idct32_34_8x32_sse2(const __m128i *const in, __m128i *const out); -void idct32_34_8x32_ssse3(const __m128i *const in, __m128i *const out); - -#endif // VPX_VPX_DSP_X86_INV_TXFM_SSE2_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_txfm_ssse3.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_txfm_ssse3.c deleted file mode 100644 index 6e99469b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_txfm_ssse3.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/x86/inv_txfm_sse2.h" -#include "vpx_dsp/x86/inv_txfm_ssse3.h" -#include "vpx_dsp/x86/transpose_sse2.h" -#include "vpx_dsp/x86/txfm_common_sse2.h" - -static INLINE void partial_butterfly_ssse3(const __m128i in, const int c0, - const int c1, __m128i *const out0, - __m128i *const out1) { - const __m128i cst0 = _mm_set1_epi16(2 * c0); - const __m128i cst1 = _mm_set1_epi16(2 * c1); - *out0 = _mm_mulhrs_epi16(in, cst0); - *out1 = _mm_mulhrs_epi16(in, cst1); -} - -static INLINE __m128i partial_butterfly_cospi16_ssse3(const __m128i in) { - const __m128i coef_pair = _mm_set1_epi16(2 * cospi_16_64); - return _mm_mulhrs_epi16(in, coef_pair); -} - -void vpx_idct8x8_12_add_ssse3(const tran_low_t *input, uint8_t *dest, - int stride) { - __m128i io[8]; - - io[0] = load_input_data4(input + 0 * 8); - io[1] = load_input_data4(input + 1 * 8); - io[2] = load_input_data4(input + 2 * 8); - io[3] = load_input_data4(input + 3 * 8); - - idct8x8_12_add_kernel_ssse3(io); - write_buffer_8x8(io, dest, stride); -} - -// Group the coefficient calculation into smaller functions to prevent stack -// spillover in 32x32 idct optimizations: -// quarter_1: 0-7 -// quarter_2: 8-15 -// quarter_3_4: 16-23, 24-31 - -// For each 8x32 block __m128i in[32], -// Input with index, 0, 4 -// output pixels: 0-7 in __m128i out[32] -static INLINE void idct32_34_8x32_quarter_1(const __m128i *const in /*in[32]*/, - __m128i *const out /*out[8]*/) { - __m128i step1[8], step2[8]; - - // stage 3 - partial_butterfly_ssse3(in[4], cospi_28_64, cospi_4_64, &step1[4], &step1[7]); - - // stage 4 - step2[0] = partial_butterfly_cospi16_ssse3(in[0]); - step2[4] = step1[4]; - step2[5] = step1[4]; - step2[6] = step1[7]; - step2[7] = step1[7]; - - // stage 5 - step1[0] = step2[0]; - step1[1] = step2[0]; - step1[2] = step2[0]; - step1[3] = step2[0]; - step1[4] = step2[4]; - butterfly(step2[6], step2[5], cospi_16_64, cospi_16_64, &step1[5], &step1[6]); - step1[7] = step2[7]; - - // stage 6 - out[0] = _mm_add_epi16(step1[0], step1[7]); - out[1] = _mm_add_epi16(step1[1], step1[6]); - out[2] = _mm_add_epi16(step1[2], step1[5]); - out[3] = _mm_add_epi16(step1[3], step1[4]); - out[4] = _mm_sub_epi16(step1[3], step1[4]); - out[5] = _mm_sub_epi16(step1[2], step1[5]); - out[6] = _mm_sub_epi16(step1[1], step1[6]); - out[7] = _mm_sub_epi16(step1[0], step1[7]); -} - -// For each 8x32 block __m128i in[32], -// Input with index, 2, 6 -// output pixels: 8-15 in __m128i out[32] -static INLINE void idct32_34_8x32_quarter_2(const __m128i *const in /*in[32]*/, - __m128i *const out /*out[16]*/) { - __m128i step1[16], step2[16]; - - // stage 2 - partial_butterfly_ssse3(in[2], cospi_30_64, cospi_2_64, &step2[8], - &step2[15]); - partial_butterfly_ssse3(in[6], -cospi_26_64, cospi_6_64, &step2[11], - &step2[12]); - - // stage 3 - step1[8] = step2[8]; - step1[9] = step2[8]; - step1[14] = step2[15]; - step1[15] = step2[15]; - step1[10] = step2[11]; - step1[11] = step2[11]; - step1[12] = step2[12]; - step1[13] = step2[12]; - - idct32_8x32_quarter_2_stage_4_to_6(step1, out); -} - -static INLINE void idct32_34_8x32_quarter_1_2( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i temp[16]; - idct32_34_8x32_quarter_1(in, temp); - idct32_34_8x32_quarter_2(in, temp); - // stage 7 - add_sub_butterfly(temp, out, 16); -} - -// For each 8x32 block __m128i in[32], -// Input with odd index, 1, 3, 5, 7 -// output pixels: 16-23, 24-31 in __m128i out[32] -static INLINE void idct32_34_8x32_quarter_3_4( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i step1[32]; - - // stage 1 - partial_butterfly_ssse3(in[1], cospi_31_64, cospi_1_64, &step1[16], - &step1[31]); - partial_butterfly_ssse3(in[7], -cospi_25_64, cospi_7_64, &step1[19], - &step1[28]); - partial_butterfly_ssse3(in[5], cospi_27_64, cospi_5_64, &step1[20], - &step1[27]); - partial_butterfly_ssse3(in[3], -cospi_29_64, cospi_3_64, &step1[23], - &step1[24]); - - // stage 3 - butterfly(step1[31], step1[16], cospi_28_64, cospi_4_64, &step1[17], - &step1[30]); - butterfly(step1[28], step1[19], -cospi_4_64, cospi_28_64, &step1[18], - &step1[29]); - butterfly(step1[27], step1[20], cospi_12_64, cospi_20_64, &step1[21], - &step1[26]); - butterfly(step1[24], step1[23], -cospi_20_64, cospi_12_64, &step1[22], - &step1[25]); - - idct32_8x32_quarter_3_4_stage_4_to_7(step1, out); -} - -void idct32_34_8x32_ssse3(const __m128i *const in /*in[32]*/, - __m128i *const out /*out[32]*/) { - __m128i temp[32]; - - idct32_34_8x32_quarter_1_2(in, temp); - idct32_34_8x32_quarter_3_4(in, temp); - // final stage - add_sub_butterfly(temp, out, 32); -} - -// Only upper-left 8x8 has non-zero coeff -void vpx_idct32x32_34_add_ssse3(const tran_low_t *input, uint8_t *dest, - int stride) { - __m128i io[32], col[32]; - int i; - - // Load input data. Only need to load the top left 8x8 block. - load_transpose_16bit_8x8(input, 32, io); - idct32_34_8x32_ssse3(io, col); - - for (i = 0; i < 32; i += 8) { - int j; - transpose_16bit_8x8(col + i, io); - idct32_34_8x32_ssse3(io, io); - - for (j = 0; j < 32; ++j) { - write_buffer_8x1(dest + j * stride, io[j]); - } - - dest += 8; - } -} - -// For each 8x32 block __m128i in[32], -// Input with index, 0, 4, 8, 12 -// output pixels: 0-7 in __m128i out[32] -static INLINE void idct32_135_8x32_quarter_1(const __m128i *const in /*in[32]*/, - __m128i *const out /*out[8]*/) { - __m128i step1[8], step2[8]; - - // stage 3 - partial_butterfly_ssse3(in[4], cospi_28_64, cospi_4_64, &step1[4], &step1[7]); - partial_butterfly_ssse3(in[12], -cospi_20_64, cospi_12_64, &step1[5], - &step1[6]); - - // stage 4 - step2[0] = partial_butterfly_cospi16_ssse3(in[0]); - partial_butterfly_ssse3(in[8], cospi_24_64, cospi_8_64, &step2[2], &step2[3]); - step2[4] = _mm_add_epi16(step1[4], step1[5]); - step2[5] = _mm_sub_epi16(step1[4], step1[5]); - step2[6] = _mm_sub_epi16(step1[7], step1[6]); - step2[7] = _mm_add_epi16(step1[7], step1[6]); - - // stage 5 - step1[0] = _mm_add_epi16(step2[0], step2[3]); - step1[1] = _mm_add_epi16(step2[0], step2[2]); - step1[2] = _mm_sub_epi16(step2[0], step2[2]); - step1[3] = _mm_sub_epi16(step2[0], step2[3]); - step1[4] = step2[4]; - butterfly(step2[6], step2[5], cospi_16_64, cospi_16_64, &step1[5], &step1[6]); - step1[7] = step2[7]; - - // stage 6 - out[0] = _mm_add_epi16(step1[0], step1[7]); - out[1] = _mm_add_epi16(step1[1], step1[6]); - out[2] = _mm_add_epi16(step1[2], step1[5]); - out[3] = _mm_add_epi16(step1[3], step1[4]); - out[4] = _mm_sub_epi16(step1[3], step1[4]); - out[5] = _mm_sub_epi16(step1[2], step1[5]); - out[6] = _mm_sub_epi16(step1[1], step1[6]); - out[7] = _mm_sub_epi16(step1[0], step1[7]); -} - -// For each 8x32 block __m128i in[32], -// Input with index, 2, 6, 10, 14 -// output pixels: 8-15 in __m128i out[32] -static INLINE void idct32_135_8x32_quarter_2(const __m128i *const in /*in[32]*/, - __m128i *const out /*out[16]*/) { - __m128i step1[16], step2[16]; - - // stage 2 - partial_butterfly_ssse3(in[2], cospi_30_64, cospi_2_64, &step2[8], - &step2[15]); - partial_butterfly_ssse3(in[14], -cospi_18_64, cospi_14_64, &step2[9], - &step2[14]); - partial_butterfly_ssse3(in[10], cospi_22_64, cospi_10_64, &step2[10], - &step2[13]); - partial_butterfly_ssse3(in[6], -cospi_26_64, cospi_6_64, &step2[11], - &step2[12]); - - // stage 3 - step1[8] = _mm_add_epi16(step2[8], step2[9]); - step1[9] = _mm_sub_epi16(step2[8], step2[9]); - step1[10] = _mm_sub_epi16(step2[11], step2[10]); - step1[11] = _mm_add_epi16(step2[11], step2[10]); - step1[12] = _mm_add_epi16(step2[12], step2[13]); - step1[13] = _mm_sub_epi16(step2[12], step2[13]); - step1[14] = _mm_sub_epi16(step2[15], step2[14]); - step1[15] = _mm_add_epi16(step2[15], step2[14]); - - idct32_8x32_quarter_2_stage_4_to_6(step1, out); -} - -static INLINE void idct32_135_8x32_quarter_1_2( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i temp[16]; - idct32_135_8x32_quarter_1(in, temp); - idct32_135_8x32_quarter_2(in, temp); - // stage 7 - add_sub_butterfly(temp, out, 16); -} - -// For each 8x32 block __m128i in[32], -// Input with odd index, -// 1, 3, 5, 7, 9, 11, 13, 15 -// output pixels: 16-23, 24-31 in __m128i out[32] -static INLINE void idct32_135_8x32_quarter_3_4( - const __m128i *const in /*in[32]*/, __m128i *const out /*out[32]*/) { - __m128i step1[32], step2[32]; - - // stage 1 - partial_butterfly_ssse3(in[1], cospi_31_64, cospi_1_64, &step1[16], - &step1[31]); - partial_butterfly_ssse3(in[15], -cospi_17_64, cospi_15_64, &step1[17], - &step1[30]); - partial_butterfly_ssse3(in[9], cospi_23_64, cospi_9_64, &step1[18], - &step1[29]); - partial_butterfly_ssse3(in[7], -cospi_25_64, cospi_7_64, &step1[19], - &step1[28]); - - partial_butterfly_ssse3(in[5], cospi_27_64, cospi_5_64, &step1[20], - &step1[27]); - partial_butterfly_ssse3(in[11], -cospi_21_64, cospi_11_64, &step1[21], - &step1[26]); - - partial_butterfly_ssse3(in[13], cospi_19_64, cospi_13_64, &step1[22], - &step1[25]); - partial_butterfly_ssse3(in[3], -cospi_29_64, cospi_3_64, &step1[23], - &step1[24]); - - // stage 2 - step2[16] = _mm_add_epi16(step1[16], step1[17]); - step2[17] = _mm_sub_epi16(step1[16], step1[17]); - step2[18] = _mm_sub_epi16(step1[19], step1[18]); - step2[19] = _mm_add_epi16(step1[19], step1[18]); - step2[20] = _mm_add_epi16(step1[20], step1[21]); - step2[21] = _mm_sub_epi16(step1[20], step1[21]); - step2[22] = _mm_sub_epi16(step1[23], step1[22]); - step2[23] = _mm_add_epi16(step1[23], step1[22]); - - step2[24] = _mm_add_epi16(step1[24], step1[25]); - step2[25] = _mm_sub_epi16(step1[24], step1[25]); - step2[26] = _mm_sub_epi16(step1[27], step1[26]); - step2[27] = _mm_add_epi16(step1[27], step1[26]); - step2[28] = _mm_add_epi16(step1[28], step1[29]); - step2[29] = _mm_sub_epi16(step1[28], step1[29]); - step2[30] = _mm_sub_epi16(step1[31], step1[30]); - step2[31] = _mm_add_epi16(step1[31], step1[30]); - - // stage 3 - step1[16] = step2[16]; - step1[31] = step2[31]; - butterfly(step2[30], step2[17], cospi_28_64, cospi_4_64, &step1[17], - &step1[30]); - butterfly(step2[29], step2[18], -cospi_4_64, cospi_28_64, &step1[18], - &step1[29]); - step1[19] = step2[19]; - step1[20] = step2[20]; - butterfly(step2[26], step2[21], cospi_12_64, cospi_20_64, &step1[21], - &step1[26]); - butterfly(step2[25], step2[22], -cospi_20_64, cospi_12_64, &step1[22], - &step1[25]); - step1[23] = step2[23]; - step1[24] = step2[24]; - step1[27] = step2[27]; - step1[28] = step2[28]; - - idct32_8x32_quarter_3_4_stage_4_to_7(step1, out); -} - -void idct32_135_8x32_ssse3(const __m128i *const in /*in[32]*/, - __m128i *const out /*out[32]*/) { - __m128i temp[32]; - idct32_135_8x32_quarter_1_2(in, temp); - idct32_135_8x32_quarter_3_4(in, temp); - // final stage - add_sub_butterfly(temp, out, 32); -} - -void vpx_idct32x32_135_add_ssse3(const tran_low_t *input, uint8_t *dest, - int stride) { - __m128i col[2][32], io[32]; - int i; - - // rows - for (i = 0; i < 2; i++) { - load_transpose_16bit_8x8(&input[0], 32, &io[0]); - load_transpose_16bit_8x8(&input[8], 32, &io[8]); - idct32_135_8x32_ssse3(io, col[i]); - input += 32 << 3; - } - - // columns - for (i = 0; i < 32; i += 8) { - transpose_16bit_8x8(col[0] + i, io); - transpose_16bit_8x8(col[1] + i, io + 8); - idct32_135_8x32_ssse3(io, io); - store_buffer_8x32(io, dest, stride); - dest += 8; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_txfm_ssse3.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_txfm_ssse3.h deleted file mode 100644 index e9f0f690..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_txfm_ssse3.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_X86_INV_TXFM_SSSE3_H_ -#define VPX_VPX_DSP_X86_INV_TXFM_SSSE3_H_ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/x86/inv_txfm_sse2.h" -#include "vpx_dsp/x86/transpose_sse2.h" -#include "vpx_dsp/x86/txfm_common_sse2.h" - -static INLINE void idct8x8_12_add_kernel_ssse3(__m128i *const io /* io[8] */) { - const __m128i cp_28d_4d = dual_set_epi16(2 * cospi_28_64, 2 * cospi_4_64); - const __m128i cp_n20d_12d = dual_set_epi16(-2 * cospi_20_64, 2 * cospi_12_64); - const __m128i cp_8d_24d = dual_set_epi16(2 * cospi_8_64, 2 * cospi_24_64); - const __m128i cp_16_16 = _mm_set1_epi16(cospi_16_64); - const __m128i cp_16_n16 = pair_set_epi16(cospi_16_64, -cospi_16_64); - const __m128i cospi_16_64d = _mm_set1_epi16((int16_t)(2 * cospi_16_64)); - const __m128i cospi_28_64d = _mm_set1_epi16((int16_t)(2 * cospi_28_64)); - const __m128i cospi_4_64d = _mm_set1_epi16((int16_t)(2 * cospi_4_64)); - const __m128i cospi_n20_64d = _mm_set1_epi16((int16_t)(-2 * cospi_20_64)); - const __m128i cospi_12_64d = _mm_set1_epi16((int16_t)(2 * cospi_12_64)); - const __m128i cospi_24_64d = _mm_set1_epi16((int16_t)(2 * cospi_24_64)); - const __m128i cospi_8_64d = _mm_set1_epi16((int16_t)(2 * cospi_8_64)); - __m128i step1[8], step2[8], tmp[4]; - - // pass 1 - - transpose_16bit_4x4(io, io); - // io[0]: 00 10 20 30 01 11 21 31 - // io[1]: 02 12 22 32 03 13 23 33 - - // stage 1 - tmp[0] = _mm_unpacklo_epi64(io[0], io[0]); - tmp[1] = _mm_unpackhi_epi64(io[0], io[0]); - tmp[2] = _mm_unpacklo_epi64(io[1], io[1]); - tmp[3] = _mm_unpackhi_epi64(io[1], io[1]); - step1[4] = _mm_mulhrs_epi16(tmp[1], cp_28d_4d); // step1 4&7 - step1[5] = _mm_mulhrs_epi16(tmp[3], cp_n20d_12d); // step1 5&6 - - // stage 2 - step2[0] = _mm_mulhrs_epi16(tmp[0], cospi_16_64d); // step2 0&1 - step2[2] = _mm_mulhrs_epi16(tmp[2], cp_8d_24d); // step2 3&2 - step2[4] = _mm_add_epi16(step1[4], step1[5]); // step2 4&7 - step2[5] = _mm_sub_epi16(step1[4], step1[5]); // step2 5&6 - step2[6] = _mm_unpackhi_epi64(step2[5], step2[5]); // step2 6 - - // stage 3 - tmp[0] = _mm_unpacklo_epi16(step2[6], step2[5]); - step1[5] = idct_calc_wraplow_sse2(cp_16_n16, cp_16_16, tmp[0]); // step1 5&6 - tmp[0] = _mm_add_epi16(step2[0], step2[2]); // step1 0&1 - tmp[1] = _mm_sub_epi16(step2[0], step2[2]); // step1 3&2 - step1[2] = _mm_unpackhi_epi64(tmp[1], tmp[0]); // step1 2&1 - step1[3] = _mm_unpacklo_epi64(tmp[1], tmp[0]); // step1 3&0 - - // stage 4 - tmp[0] = _mm_add_epi16(step1[3], step2[4]); // output 3&0 - tmp[1] = _mm_add_epi16(step1[2], step1[5]); // output 2&1 - tmp[2] = _mm_sub_epi16(step1[3], step2[4]); // output 4&7 - tmp[3] = _mm_sub_epi16(step1[2], step1[5]); // output 5&6 - - // pass 2 - - idct8x8_12_transpose_16bit_4x8(tmp, io); - - // stage 1 - step1[4] = _mm_mulhrs_epi16(io[1], cospi_28_64d); - step1[7] = _mm_mulhrs_epi16(io[1], cospi_4_64d); - step1[5] = _mm_mulhrs_epi16(io[3], cospi_n20_64d); - step1[6] = _mm_mulhrs_epi16(io[3], cospi_12_64d); - - // stage 2 - step2[0] = _mm_mulhrs_epi16(io[0], cospi_16_64d); // step2[1] = step2[0] - step2[2] = _mm_mulhrs_epi16(io[2], cospi_24_64d); - step2[3] = _mm_mulhrs_epi16(io[2], cospi_8_64d); - step2[4] = _mm_add_epi16(step1[4], step1[5]); - step2[5] = _mm_sub_epi16(step1[4], step1[5]); - step2[6] = _mm_sub_epi16(step1[7], step1[6]); - step2[7] = _mm_add_epi16(step1[7], step1[6]); - - // stage 3 - step1[0] = _mm_add_epi16(step2[0], step2[3]); - step1[1] = _mm_add_epi16(step2[0], step2[2]); - step1[2] = _mm_sub_epi16(step2[0], step2[2]); - step1[3] = _mm_sub_epi16(step2[0], step2[3]); - butterfly(step2[6], step2[5], cospi_16_64, cospi_16_64, &step1[5], &step1[6]); - - // stage 4 - io[0] = _mm_add_epi16(step1[0], step2[7]); - io[1] = _mm_add_epi16(step1[1], step1[6]); - io[2] = _mm_add_epi16(step1[2], step1[5]); - io[3] = _mm_add_epi16(step1[3], step2[4]); - io[4] = _mm_sub_epi16(step1[3], step2[4]); - io[5] = _mm_sub_epi16(step1[2], step1[5]); - io[6] = _mm_sub_epi16(step1[1], step1[6]); - io[7] = _mm_sub_epi16(step1[0], step2[7]); -} - -void idct32_135_8x32_ssse3(const __m128i *const in, __m128i *const out); - -#endif // VPX_VPX_DSP_X86_INV_TXFM_SSSE3_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_wht_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_wht_sse2.asm deleted file mode 100644 index bcf1a6ef..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/inv_wht_sse2.asm +++ /dev/null @@ -1,103 +0,0 @@ -; -; Copyright (c) 2015 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "third_party/x86inc/x86inc.asm" -%include "vpx_dsp/x86/bitdepth_conversion_sse2.asm" - -SECTION .text - -%macro REORDER_INPUTS 0 - ; a c d b to a b c d - SWAP 1, 3, 2 -%endmacro - -%macro TRANSFORM_COLS 0 - ; input: - ; m0 a - ; m1 b - ; m2 c - ; m3 d - paddw m0, m2 - psubw m3, m1 - - ; wide subtract - punpcklwd m4, m0 - punpcklwd m5, m3 - psrad m4, 16 - psrad m5, 16 - psubd m4, m5 - psrad m4, 1 - packssdw m4, m4 ; e - - psubw m5, m4, m1 ; b - psubw m4, m2 ; c - psubw m0, m5 - paddw m3, m4 - ; m0 a - SWAP 1, 5 ; m1 b - SWAP 2, 4 ; m2 c - ; m3 d -%endmacro - -%macro TRANSPOSE_4X4 0 - punpcklwd m0, m2 - punpcklwd m1, m3 - mova m2, m0 - punpcklwd m0, m1 - punpckhwd m2, m1 - pshufd m1, m0, 0x0e - pshufd m3, m2, 0x0e -%endmacro - -; transpose a 4x4 int16 matrix in xmm0 and xmm1 to the bottom half of xmm0-xmm3 -%macro TRANSPOSE_4X4_WIDE 0 - mova m3, m0 - punpcklwd m0, m1 - punpckhwd m3, m1 - mova m2, m0 - punpcklwd m0, m3 - punpckhwd m2, m3 - pshufd m1, m0, 0x0e - pshufd m3, m2, 0x0e -%endmacro - -%macro ADD_STORE_4P_2X 5 ; src1, src2, tmp1, tmp2, zero - movd m%3, [outputq] - movd m%4, [outputq + strideq] - punpcklbw m%3, m%5 - punpcklbw m%4, m%5 - paddw m%1, m%3 - paddw m%2, m%4 - packuswb m%1, m%5 - packuswb m%2, m%5 - movd [outputq], m%1 - movd [outputq + strideq], m%2 -%endmacro - -INIT_XMM sse2 -cglobal iwht4x4_16_add, 3, 3, 7, input, output, stride - LOAD_TRAN_LOW 0, inputq, 0 - LOAD_TRAN_LOW 1, inputq, 8 - psraw m0, 2 - psraw m1, 2 - - TRANSPOSE_4X4_WIDE - REORDER_INPUTS - TRANSFORM_COLS - TRANSPOSE_4X4 - REORDER_INPUTS - TRANSFORM_COLS - - pxor m4, m4 - ADD_STORE_4P_2X 0, 1, 5, 6, 4 - lea outputq, [outputq + 2 * strideq] - ADD_STORE_4P_2X 2, 3, 5, 6, 4 - - RET diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/loopfilter_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/loopfilter_avx2.c deleted file mode 100644 index a58fb655..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/loopfilter_avx2.c +++ /dev/null @@ -1,913 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include /* AVX2 */ - -#include "./vpx_dsp_rtcd.h" -#include "vpx_ports/mem.h" - -void vpx_lpf_horizontal_16_avx2(unsigned char *s, int pitch, - const unsigned char *blimit, - const unsigned char *limit, - const unsigned char *thresh) { - __m128i mask, hev, flat, flat2; - const __m128i zero = _mm_setzero_si128(); - const __m128i one = _mm_set1_epi8(1); - __m128i q7p7, q6p6, q5p5, q4p4, q3p3, q2p2, q1p1, q0p0, p0q0, p1q1; - __m128i abs_p1p0; - - const __m128i thresh_v = - _mm_broadcastb_epi8(_mm_cvtsi32_si128((int)thresh[0])); - const __m128i limit_v = _mm_broadcastb_epi8(_mm_cvtsi32_si128((int)limit[0])); - const __m128i blimit_v = - _mm_broadcastb_epi8(_mm_cvtsi32_si128((int)blimit[0])); - - q4p4 = _mm_loadl_epi64((__m128i *)(s - 5 * pitch)); - q4p4 = _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(q4p4), (__m64 *)(s + 4 * pitch))); - q3p3 = _mm_loadl_epi64((__m128i *)(s - 4 * pitch)); - q3p3 = _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(q3p3), (__m64 *)(s + 3 * pitch))); - q2p2 = _mm_loadl_epi64((__m128i *)(s - 3 * pitch)); - q2p2 = _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(q2p2), (__m64 *)(s + 2 * pitch))); - q1p1 = _mm_loadl_epi64((__m128i *)(s - 2 * pitch)); - q1p1 = _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(q1p1), (__m64 *)(s + 1 * pitch))); - p1q1 = _mm_shuffle_epi32(q1p1, 78); - q0p0 = _mm_loadl_epi64((__m128i *)(s - 1 * pitch)); - q0p0 = _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(q0p0), (__m64 *)(s - 0 * pitch))); - p0q0 = _mm_shuffle_epi32(q0p0, 78); - - { - __m128i abs_p1q1, abs_p0q0, abs_q1q0, fe, ff, work; - abs_p1p0 = - _mm_or_si128(_mm_subs_epu8(q1p1, q0p0), _mm_subs_epu8(q0p0, q1p1)); - abs_q1q0 = _mm_srli_si128(abs_p1p0, 8); - fe = _mm_set1_epi8((int8_t)0xfe); - ff = _mm_cmpeq_epi8(abs_p1p0, abs_p1p0); - abs_p0q0 = - _mm_or_si128(_mm_subs_epu8(q0p0, p0q0), _mm_subs_epu8(p0q0, q0p0)); - abs_p1q1 = - _mm_or_si128(_mm_subs_epu8(q1p1, p1q1), _mm_subs_epu8(p1q1, q1p1)); - flat = _mm_max_epu8(abs_p1p0, abs_q1q0); - hev = _mm_subs_epu8(flat, thresh_v); - hev = _mm_xor_si128(_mm_cmpeq_epi8(hev, zero), ff); - - abs_p0q0 = _mm_adds_epu8(abs_p0q0, abs_p0q0); - abs_p1q1 = _mm_srli_epi16(_mm_and_si128(abs_p1q1, fe), 1); - mask = _mm_subs_epu8(_mm_adds_epu8(abs_p0q0, abs_p1q1), blimit_v); - mask = _mm_xor_si128(_mm_cmpeq_epi8(mask, zero), ff); - // mask |= (abs(p0 - q0) * 2 + abs(p1 - q1) / 2 > blimit) * -1; - mask = _mm_max_epu8(abs_p1p0, mask); - // mask |= (abs(p1 - p0) > limit) * -1; - // mask |= (abs(q1 - q0) > limit) * -1; - - work = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(q2p2, q1p1), _mm_subs_epu8(q1p1, q2p2)), - _mm_or_si128(_mm_subs_epu8(q3p3, q2p2), _mm_subs_epu8(q2p2, q3p3))); - mask = _mm_max_epu8(work, mask); - mask = _mm_max_epu8(mask, _mm_srli_si128(mask, 8)); - mask = _mm_subs_epu8(mask, limit_v); - mask = _mm_cmpeq_epi8(mask, zero); - } - - // lp filter - { - const __m128i t4 = _mm_set1_epi8(4); - const __m128i t3 = _mm_set1_epi8(3); - const __m128i t80 = _mm_set1_epi8((int8_t)0x80); - const __m128i t1 = _mm_set1_epi16(0x1); - __m128i qs1ps1 = _mm_xor_si128(q1p1, t80); - __m128i qs0ps0 = _mm_xor_si128(q0p0, t80); - __m128i qs0 = _mm_xor_si128(p0q0, t80); - __m128i qs1 = _mm_xor_si128(p1q1, t80); - __m128i filt; - __m128i work_a; - __m128i filter1, filter2; - __m128i flat2_q6p6, flat2_q5p5, flat2_q4p4, flat2_q3p3, flat2_q2p2; - __m128i flat2_q1p1, flat2_q0p0, flat_q2p2, flat_q1p1, flat_q0p0; - - filt = _mm_and_si128(_mm_subs_epi8(qs1ps1, qs1), hev); - work_a = _mm_subs_epi8(qs0, qs0ps0); - filt = _mm_adds_epi8(filt, work_a); - filt = _mm_adds_epi8(filt, work_a); - filt = _mm_adds_epi8(filt, work_a); - /* (vpx_filter + 3 * (qs0 - ps0)) & mask */ - filt = _mm_and_si128(filt, mask); - - filter1 = _mm_adds_epi8(filt, t4); - filter2 = _mm_adds_epi8(filt, t3); - - filter1 = _mm_unpacklo_epi8(zero, filter1); - filter1 = _mm_srai_epi16(filter1, 0xB); - filter2 = _mm_unpacklo_epi8(zero, filter2); - filter2 = _mm_srai_epi16(filter2, 0xB); - - /* Filter1 >> 3 */ - filt = _mm_packs_epi16(filter2, _mm_subs_epi16(zero, filter1)); - qs0ps0 = _mm_xor_si128(_mm_adds_epi8(qs0ps0, filt), t80); - - /* filt >> 1 */ - filt = _mm_adds_epi16(filter1, t1); - filt = _mm_srai_epi16(filt, 1); - filt = _mm_andnot_si128(_mm_srai_epi16(_mm_unpacklo_epi8(zero, hev), 0x8), - filt); - filt = _mm_packs_epi16(filt, _mm_subs_epi16(zero, filt)); - qs1ps1 = _mm_xor_si128(_mm_adds_epi8(qs1ps1, filt), t80); - // loopfilter done - - { - __m128i work; - flat = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(q2p2, q0p0), _mm_subs_epu8(q0p0, q2p2)), - _mm_or_si128(_mm_subs_epu8(q3p3, q0p0), _mm_subs_epu8(q0p0, q3p3))); - flat = _mm_max_epu8(abs_p1p0, flat); - flat = _mm_max_epu8(flat, _mm_srli_si128(flat, 8)); - flat = _mm_subs_epu8(flat, one); - flat = _mm_cmpeq_epi8(flat, zero); - flat = _mm_and_si128(flat, mask); - - q5p5 = _mm_loadl_epi64((__m128i *)(s - 6 * pitch)); - q5p5 = _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(q5p5), (__m64 *)(s + 5 * pitch))); - - q6p6 = _mm_loadl_epi64((__m128i *)(s - 7 * pitch)); - q6p6 = _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(q6p6), (__m64 *)(s + 6 * pitch))); - - flat2 = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(q4p4, q0p0), _mm_subs_epu8(q0p0, q4p4)), - _mm_or_si128(_mm_subs_epu8(q5p5, q0p0), _mm_subs_epu8(q0p0, q5p5))); - - q7p7 = _mm_loadl_epi64((__m128i *)(s - 8 * pitch)); - q7p7 = _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(q7p7), (__m64 *)(s + 7 * pitch))); - - work = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(q6p6, q0p0), _mm_subs_epu8(q0p0, q6p6)), - _mm_or_si128(_mm_subs_epu8(q7p7, q0p0), _mm_subs_epu8(q0p0, q7p7))); - - flat2 = _mm_max_epu8(work, flat2); - flat2 = _mm_max_epu8(flat2, _mm_srli_si128(flat2, 8)); - flat2 = _mm_subs_epu8(flat2, one); - flat2 = _mm_cmpeq_epi8(flat2, zero); - flat2 = _mm_and_si128(flat2, flat); // flat2 & flat & mask - } - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // flat and wide flat calculations - { - const __m128i eight = _mm_set1_epi16(8); - const __m128i four = _mm_set1_epi16(4); - __m128i p7_16, p6_16, p5_16, p4_16, p3_16, p2_16, p1_16, p0_16; - __m128i q7_16, q6_16, q5_16, q4_16, q3_16, q2_16, q1_16, q0_16; - __m128i pixelFilter_p, pixelFilter_q; - __m128i pixetFilter_p2p1p0, pixetFilter_q2q1q0; - __m128i sum_p7, sum_q7, sum_p3, sum_q3, res_p, res_q; - - p7_16 = _mm_unpacklo_epi8(q7p7, zero); - p6_16 = _mm_unpacklo_epi8(q6p6, zero); - p5_16 = _mm_unpacklo_epi8(q5p5, zero); - p4_16 = _mm_unpacklo_epi8(q4p4, zero); - p3_16 = _mm_unpacklo_epi8(q3p3, zero); - p2_16 = _mm_unpacklo_epi8(q2p2, zero); - p1_16 = _mm_unpacklo_epi8(q1p1, zero); - p0_16 = _mm_unpacklo_epi8(q0p0, zero); - q0_16 = _mm_unpackhi_epi8(q0p0, zero); - q1_16 = _mm_unpackhi_epi8(q1p1, zero); - q2_16 = _mm_unpackhi_epi8(q2p2, zero); - q3_16 = _mm_unpackhi_epi8(q3p3, zero); - q4_16 = _mm_unpackhi_epi8(q4p4, zero); - q5_16 = _mm_unpackhi_epi8(q5p5, zero); - q6_16 = _mm_unpackhi_epi8(q6p6, zero); - q7_16 = _mm_unpackhi_epi8(q7p7, zero); - - pixelFilter_p = _mm_add_epi16(_mm_add_epi16(p6_16, p5_16), - _mm_add_epi16(p4_16, p3_16)); - pixelFilter_q = _mm_add_epi16(_mm_add_epi16(q6_16, q5_16), - _mm_add_epi16(q4_16, q3_16)); - - pixetFilter_p2p1p0 = _mm_add_epi16(p0_16, _mm_add_epi16(p2_16, p1_16)); - pixelFilter_p = _mm_add_epi16(pixelFilter_p, pixetFilter_p2p1p0); - - pixetFilter_q2q1q0 = _mm_add_epi16(q0_16, _mm_add_epi16(q2_16, q1_16)); - pixelFilter_q = _mm_add_epi16(pixelFilter_q, pixetFilter_q2q1q0); - pixelFilter_p = - _mm_add_epi16(eight, _mm_add_epi16(pixelFilter_p, pixelFilter_q)); - pixetFilter_p2p1p0 = _mm_add_epi16( - four, _mm_add_epi16(pixetFilter_p2p1p0, pixetFilter_q2q1q0)); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(p7_16, p0_16)), 4); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(q7_16, q0_16)), 4); - flat2_q0p0 = _mm_packus_epi16(res_p, res_q); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_p2p1p0, _mm_add_epi16(p3_16, p0_16)), 3); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_p2p1p0, _mm_add_epi16(q3_16, q0_16)), 3); - - flat_q0p0 = _mm_packus_epi16(res_p, res_q); - - sum_p7 = _mm_add_epi16(p7_16, p7_16); - sum_q7 = _mm_add_epi16(q7_16, q7_16); - sum_p3 = _mm_add_epi16(p3_16, p3_16); - sum_q3 = _mm_add_epi16(q3_16, q3_16); - - pixelFilter_q = _mm_sub_epi16(pixelFilter_p, p6_16); - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q6_16); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p1_16)), 4); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q1_16)), 4); - flat2_q1p1 = _mm_packus_epi16(res_p, res_q); - - pixetFilter_q2q1q0 = _mm_sub_epi16(pixetFilter_p2p1p0, p2_16); - pixetFilter_p2p1p0 = _mm_sub_epi16(pixetFilter_p2p1p0, q2_16); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_p2p1p0, _mm_add_epi16(sum_p3, p1_16)), 3); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_q2q1q0, _mm_add_epi16(sum_q3, q1_16)), 3); - flat_q1p1 = _mm_packus_epi16(res_p, res_q); - - sum_p7 = _mm_add_epi16(sum_p7, p7_16); - sum_q7 = _mm_add_epi16(sum_q7, q7_16); - sum_p3 = _mm_add_epi16(sum_p3, p3_16); - sum_q3 = _mm_add_epi16(sum_q3, q3_16); - - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q5_16); - pixelFilter_q = _mm_sub_epi16(pixelFilter_q, p5_16); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p2_16)), 4); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q2_16)), 4); - flat2_q2p2 = _mm_packus_epi16(res_p, res_q); - - pixetFilter_p2p1p0 = _mm_sub_epi16(pixetFilter_p2p1p0, q1_16); - pixetFilter_q2q1q0 = _mm_sub_epi16(pixetFilter_q2q1q0, p1_16); - - res_p = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_p2p1p0, _mm_add_epi16(sum_p3, p2_16)), 3); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_q2q1q0, _mm_add_epi16(sum_q3, q2_16)), 3); - flat_q2p2 = _mm_packus_epi16(res_p, res_q); - - sum_p7 = _mm_add_epi16(sum_p7, p7_16); - sum_q7 = _mm_add_epi16(sum_q7, q7_16); - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q4_16); - pixelFilter_q = _mm_sub_epi16(pixelFilter_q, p4_16); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p3_16)), 4); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q3_16)), 4); - flat2_q3p3 = _mm_packus_epi16(res_p, res_q); - - sum_p7 = _mm_add_epi16(sum_p7, p7_16); - sum_q7 = _mm_add_epi16(sum_q7, q7_16); - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q3_16); - pixelFilter_q = _mm_sub_epi16(pixelFilter_q, p3_16); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p4_16)), 4); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q4_16)), 4); - flat2_q4p4 = _mm_packus_epi16(res_p, res_q); - - sum_p7 = _mm_add_epi16(sum_p7, p7_16); - sum_q7 = _mm_add_epi16(sum_q7, q7_16); - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q2_16); - pixelFilter_q = _mm_sub_epi16(pixelFilter_q, p2_16); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p5_16)), 4); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q5_16)), 4); - flat2_q5p5 = _mm_packus_epi16(res_p, res_q); - - sum_p7 = _mm_add_epi16(sum_p7, p7_16); - sum_q7 = _mm_add_epi16(sum_q7, q7_16); - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q1_16); - pixelFilter_q = _mm_sub_epi16(pixelFilter_q, p1_16); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p6_16)), 4); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q6_16)), 4); - flat2_q6p6 = _mm_packus_epi16(res_p, res_q); - } - // wide flat - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - flat = _mm_shuffle_epi32(flat, 68); - flat2 = _mm_shuffle_epi32(flat2, 68); - - q2p2 = _mm_andnot_si128(flat, q2p2); - flat_q2p2 = _mm_and_si128(flat, flat_q2p2); - q2p2 = _mm_or_si128(q2p2, flat_q2p2); - - qs1ps1 = _mm_andnot_si128(flat, qs1ps1); - flat_q1p1 = _mm_and_si128(flat, flat_q1p1); - q1p1 = _mm_or_si128(qs1ps1, flat_q1p1); - - qs0ps0 = _mm_andnot_si128(flat, qs0ps0); - flat_q0p0 = _mm_and_si128(flat, flat_q0p0); - q0p0 = _mm_or_si128(qs0ps0, flat_q0p0); - - q6p6 = _mm_andnot_si128(flat2, q6p6); - flat2_q6p6 = _mm_and_si128(flat2, flat2_q6p6); - q6p6 = _mm_or_si128(q6p6, flat2_q6p6); - _mm_storel_epi64((__m128i *)(s - 7 * pitch), q6p6); - _mm_storeh_pi((__m64 *)(s + 6 * pitch), _mm_castsi128_ps(q6p6)); - - q5p5 = _mm_andnot_si128(flat2, q5p5); - flat2_q5p5 = _mm_and_si128(flat2, flat2_q5p5); - q5p5 = _mm_or_si128(q5p5, flat2_q5p5); - _mm_storel_epi64((__m128i *)(s - 6 * pitch), q5p5); - _mm_storeh_pi((__m64 *)(s + 5 * pitch), _mm_castsi128_ps(q5p5)); - - q4p4 = _mm_andnot_si128(flat2, q4p4); - flat2_q4p4 = _mm_and_si128(flat2, flat2_q4p4); - q4p4 = _mm_or_si128(q4p4, flat2_q4p4); - _mm_storel_epi64((__m128i *)(s - 5 * pitch), q4p4); - _mm_storeh_pi((__m64 *)(s + 4 * pitch), _mm_castsi128_ps(q4p4)); - - q3p3 = _mm_andnot_si128(flat2, q3p3); - flat2_q3p3 = _mm_and_si128(flat2, flat2_q3p3); - q3p3 = _mm_or_si128(q3p3, flat2_q3p3); - _mm_storel_epi64((__m128i *)(s - 4 * pitch), q3p3); - _mm_storeh_pi((__m64 *)(s + 3 * pitch), _mm_castsi128_ps(q3p3)); - - q2p2 = _mm_andnot_si128(flat2, q2p2); - flat2_q2p2 = _mm_and_si128(flat2, flat2_q2p2); - q2p2 = _mm_or_si128(q2p2, flat2_q2p2); - _mm_storel_epi64((__m128i *)(s - 3 * pitch), q2p2); - _mm_storeh_pi((__m64 *)(s + 2 * pitch), _mm_castsi128_ps(q2p2)); - - q1p1 = _mm_andnot_si128(flat2, q1p1); - flat2_q1p1 = _mm_and_si128(flat2, flat2_q1p1); - q1p1 = _mm_or_si128(q1p1, flat2_q1p1); - _mm_storel_epi64((__m128i *)(s - 2 * pitch), q1p1); - _mm_storeh_pi((__m64 *)(s + 1 * pitch), _mm_castsi128_ps(q1p1)); - - q0p0 = _mm_andnot_si128(flat2, q0p0); - flat2_q0p0 = _mm_and_si128(flat2, flat2_q0p0); - q0p0 = _mm_or_si128(q0p0, flat2_q0p0); - _mm_storel_epi64((__m128i *)(s - 1 * pitch), q0p0); - _mm_storeh_pi((__m64 *)(s - 0 * pitch), _mm_castsi128_ps(q0p0)); - } -} - -DECLARE_ALIGNED(32, static const uint8_t, filt_loopfilter_avx2[32]) = { - 0, 128, 1, 128, 2, 128, 3, 128, 4, 128, 5, 128, 6, 128, 7, 128, - 8, 128, 9, 128, 10, 128, 11, 128, 12, 128, 13, 128, 14, 128, 15, 128 -}; - -void vpx_lpf_horizontal_16_dual_avx2(unsigned char *s, int pitch, - const unsigned char *blimit, - const unsigned char *limit, - const unsigned char *thresh) { - __m128i mask, hev, flat, flat2; - const __m128i zero = _mm_setzero_si128(); - const __m128i one = _mm_set1_epi8(1); - __m128i p7, p6, p5; - __m128i p4, p3, p2, p1, p0, q0, q1, q2, q3, q4; - __m128i q5, q6, q7; - __m256i p256_7, q256_7, p256_6, q256_6, p256_5, q256_5, p256_4, q256_4, - p256_3, q256_3, p256_2, q256_2, p256_1, q256_1, p256_0, q256_0; - - const __m128i thresh_v = - _mm_broadcastb_epi8(_mm_cvtsi32_si128((int)thresh[0])); - const __m128i limit_v = _mm_broadcastb_epi8(_mm_cvtsi32_si128((int)limit[0])); - const __m128i blimit_v = - _mm_broadcastb_epi8(_mm_cvtsi32_si128((int)blimit[0])); - - p256_4 = _mm256_castpd_si256( - _mm256_broadcast_pd((__m128d const *)(s - 5 * pitch))); - p256_3 = _mm256_castpd_si256( - _mm256_broadcast_pd((__m128d const *)(s - 4 * pitch))); - p256_2 = _mm256_castpd_si256( - _mm256_broadcast_pd((__m128d const *)(s - 3 * pitch))); - p256_1 = _mm256_castpd_si256( - _mm256_broadcast_pd((__m128d const *)(s - 2 * pitch))); - p256_0 = _mm256_castpd_si256( - _mm256_broadcast_pd((__m128d const *)(s - 1 * pitch))); - q256_0 = _mm256_castpd_si256( - _mm256_broadcast_pd((__m128d const *)(s - 0 * pitch))); - q256_1 = _mm256_castpd_si256( - _mm256_broadcast_pd((__m128d const *)(s + 1 * pitch))); - q256_2 = _mm256_castpd_si256( - _mm256_broadcast_pd((__m128d const *)(s + 2 * pitch))); - q256_3 = _mm256_castpd_si256( - _mm256_broadcast_pd((__m128d const *)(s + 3 * pitch))); - q256_4 = _mm256_castpd_si256( - _mm256_broadcast_pd((__m128d const *)(s + 4 * pitch))); - - p4 = _mm256_castsi256_si128(p256_4); - p3 = _mm256_castsi256_si128(p256_3); - p2 = _mm256_castsi256_si128(p256_2); - p1 = _mm256_castsi256_si128(p256_1); - p0 = _mm256_castsi256_si128(p256_0); - q0 = _mm256_castsi256_si128(q256_0); - q1 = _mm256_castsi256_si128(q256_1); - q2 = _mm256_castsi256_si128(q256_2); - q3 = _mm256_castsi256_si128(q256_3); - q4 = _mm256_castsi256_si128(q256_4); - - { - const __m128i abs_p1p0 = - _mm_or_si128(_mm_subs_epu8(p1, p0), _mm_subs_epu8(p0, p1)); - const __m128i abs_q1q0 = - _mm_or_si128(_mm_subs_epu8(q1, q0), _mm_subs_epu8(q0, q1)); - const __m128i fe = _mm_set1_epi8((int8_t)0xfe); - const __m128i ff = _mm_cmpeq_epi8(abs_p1p0, abs_p1p0); - __m128i abs_p0q0 = - _mm_or_si128(_mm_subs_epu8(p0, q0), _mm_subs_epu8(q0, p0)); - __m128i abs_p1q1 = - _mm_or_si128(_mm_subs_epu8(p1, q1), _mm_subs_epu8(q1, p1)); - __m128i work; - flat = _mm_max_epu8(abs_p1p0, abs_q1q0); - hev = _mm_subs_epu8(flat, thresh_v); - hev = _mm_xor_si128(_mm_cmpeq_epi8(hev, zero), ff); - - abs_p0q0 = _mm_adds_epu8(abs_p0q0, abs_p0q0); - abs_p1q1 = _mm_srli_epi16(_mm_and_si128(abs_p1q1, fe), 1); - mask = _mm_subs_epu8(_mm_adds_epu8(abs_p0q0, abs_p1q1), blimit_v); - mask = _mm_xor_si128(_mm_cmpeq_epi8(mask, zero), ff); - // mask |= (abs(p0 - q0) * 2 + abs(p1 - q1) / 2 > blimit) * -1; - mask = _mm_max_epu8(flat, mask); - // mask |= (abs(p1 - p0) > limit) * -1; - // mask |= (abs(q1 - q0) > limit) * -1; - work = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(p2, p1), _mm_subs_epu8(p1, p2)), - _mm_or_si128(_mm_subs_epu8(p3, p2), _mm_subs_epu8(p2, p3))); - mask = _mm_max_epu8(work, mask); - work = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(q2, q1), _mm_subs_epu8(q1, q2)), - _mm_or_si128(_mm_subs_epu8(q3, q2), _mm_subs_epu8(q2, q3))); - mask = _mm_max_epu8(work, mask); - mask = _mm_subs_epu8(mask, limit_v); - mask = _mm_cmpeq_epi8(mask, zero); - } - - // lp filter - { - const __m128i t4 = _mm_set1_epi8(4); - const __m128i t3 = _mm_set1_epi8(3); - const __m128i t80 = _mm_set1_epi8((int8_t)0x80); - const __m128i te0 = _mm_set1_epi8((int8_t)0xe0); - const __m128i t1f = _mm_set1_epi8(0x1f); - const __m128i t1 = _mm_set1_epi8(0x1); - const __m128i t7f = _mm_set1_epi8(0x7f); - - __m128i ps1 = _mm_xor_si128(p1, t80); - __m128i ps0 = _mm_xor_si128(p0, t80); - __m128i qs0 = _mm_xor_si128(q0, t80); - __m128i qs1 = _mm_xor_si128(q1, t80); - __m128i filt; - __m128i work_a; - __m128i filter1, filter2; - __m128i flat2_p6, flat2_p5, flat2_p4, flat2_p3, flat2_p2, flat2_p1, - flat2_p0, flat2_q0, flat2_q1, flat2_q2, flat2_q3, flat2_q4, flat2_q5, - flat2_q6, flat_p2, flat_p1, flat_p0, flat_q0, flat_q1, flat_q2; - - filt = _mm_and_si128(_mm_subs_epi8(ps1, qs1), hev); - work_a = _mm_subs_epi8(qs0, ps0); - filt = _mm_adds_epi8(filt, work_a); - filt = _mm_adds_epi8(filt, work_a); - filt = _mm_adds_epi8(filt, work_a); - /* (vpx_filter + 3 * (qs0 - ps0)) & mask */ - filt = _mm_and_si128(filt, mask); - - filter1 = _mm_adds_epi8(filt, t4); - filter2 = _mm_adds_epi8(filt, t3); - - /* Filter1 >> 3 */ - work_a = _mm_cmpgt_epi8(zero, filter1); - filter1 = _mm_srli_epi16(filter1, 3); - work_a = _mm_and_si128(work_a, te0); - filter1 = _mm_and_si128(filter1, t1f); - filter1 = _mm_or_si128(filter1, work_a); - qs0 = _mm_xor_si128(_mm_subs_epi8(qs0, filter1), t80); - - /* Filter2 >> 3 */ - work_a = _mm_cmpgt_epi8(zero, filter2); - filter2 = _mm_srli_epi16(filter2, 3); - work_a = _mm_and_si128(work_a, te0); - filter2 = _mm_and_si128(filter2, t1f); - filter2 = _mm_or_si128(filter2, work_a); - ps0 = _mm_xor_si128(_mm_adds_epi8(ps0, filter2), t80); - - /* filt >> 1 */ - filt = _mm_adds_epi8(filter1, t1); - work_a = _mm_cmpgt_epi8(zero, filt); - filt = _mm_srli_epi16(filt, 1); - work_a = _mm_and_si128(work_a, t80); - filt = _mm_and_si128(filt, t7f); - filt = _mm_or_si128(filt, work_a); - filt = _mm_andnot_si128(hev, filt); - ps1 = _mm_xor_si128(_mm_adds_epi8(ps1, filt), t80); - qs1 = _mm_xor_si128(_mm_subs_epi8(qs1, filt), t80); - // loopfilter done - - { - __m128i work; - work = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(p2, p0), _mm_subs_epu8(p0, p2)), - _mm_or_si128(_mm_subs_epu8(q2, q0), _mm_subs_epu8(q0, q2))); - flat = _mm_max_epu8(work, flat); - work = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(p3, p0), _mm_subs_epu8(p0, p3)), - _mm_or_si128(_mm_subs_epu8(q3, q0), _mm_subs_epu8(q0, q3))); - flat = _mm_max_epu8(work, flat); - work = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(p4, p0), _mm_subs_epu8(p0, p4)), - _mm_or_si128(_mm_subs_epu8(q4, q0), _mm_subs_epu8(q0, q4))); - flat = _mm_subs_epu8(flat, one); - flat = _mm_cmpeq_epi8(flat, zero); - flat = _mm_and_si128(flat, mask); - - p256_5 = _mm256_castpd_si256( - _mm256_broadcast_pd((__m128d const *)(s - 6 * pitch))); - q256_5 = _mm256_castpd_si256( - _mm256_broadcast_pd((__m128d const *)(s + 5 * pitch))); - p5 = _mm256_castsi256_si128(p256_5); - q5 = _mm256_castsi256_si128(q256_5); - flat2 = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(p5, p0), _mm_subs_epu8(p0, p5)), - _mm_or_si128(_mm_subs_epu8(q5, q0), _mm_subs_epu8(q0, q5))); - - flat2 = _mm_max_epu8(work, flat2); - p256_6 = _mm256_castpd_si256( - _mm256_broadcast_pd((__m128d const *)(s - 7 * pitch))); - q256_6 = _mm256_castpd_si256( - _mm256_broadcast_pd((__m128d const *)(s + 6 * pitch))); - p6 = _mm256_castsi256_si128(p256_6); - q6 = _mm256_castsi256_si128(q256_6); - work = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(p6, p0), _mm_subs_epu8(p0, p6)), - _mm_or_si128(_mm_subs_epu8(q6, q0), _mm_subs_epu8(q0, q6))); - - flat2 = _mm_max_epu8(work, flat2); - - p256_7 = _mm256_castpd_si256( - _mm256_broadcast_pd((__m128d const *)(s - 8 * pitch))); - q256_7 = _mm256_castpd_si256( - _mm256_broadcast_pd((__m128d const *)(s + 7 * pitch))); - p7 = _mm256_castsi256_si128(p256_7); - q7 = _mm256_castsi256_si128(q256_7); - work = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(p7, p0), _mm_subs_epu8(p0, p7)), - _mm_or_si128(_mm_subs_epu8(q7, q0), _mm_subs_epu8(q0, q7))); - - flat2 = _mm_max_epu8(work, flat2); - flat2 = _mm_subs_epu8(flat2, one); - flat2 = _mm_cmpeq_epi8(flat2, zero); - flat2 = _mm_and_si128(flat2, flat); // flat2 & flat & mask - } - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // flat and wide flat calculations - { - const __m256i eight = _mm256_set1_epi16(8); - const __m256i four = _mm256_set1_epi16(4); - __m256i pixelFilter_p, pixelFilter_q, pixetFilter_p2p1p0, - pixetFilter_q2q1q0, sum_p7, sum_q7, sum_p3, sum_q3, res_p, res_q; - - const __m256i filter = - _mm256_load_si256((__m256i const *)filt_loopfilter_avx2); - p256_7 = _mm256_shuffle_epi8(p256_7, filter); - p256_6 = _mm256_shuffle_epi8(p256_6, filter); - p256_5 = _mm256_shuffle_epi8(p256_5, filter); - p256_4 = _mm256_shuffle_epi8(p256_4, filter); - p256_3 = _mm256_shuffle_epi8(p256_3, filter); - p256_2 = _mm256_shuffle_epi8(p256_2, filter); - p256_1 = _mm256_shuffle_epi8(p256_1, filter); - p256_0 = _mm256_shuffle_epi8(p256_0, filter); - q256_0 = _mm256_shuffle_epi8(q256_0, filter); - q256_1 = _mm256_shuffle_epi8(q256_1, filter); - q256_2 = _mm256_shuffle_epi8(q256_2, filter); - q256_3 = _mm256_shuffle_epi8(q256_3, filter); - q256_4 = _mm256_shuffle_epi8(q256_4, filter); - q256_5 = _mm256_shuffle_epi8(q256_5, filter); - q256_6 = _mm256_shuffle_epi8(q256_6, filter); - q256_7 = _mm256_shuffle_epi8(q256_7, filter); - - pixelFilter_p = _mm256_add_epi16(_mm256_add_epi16(p256_6, p256_5), - _mm256_add_epi16(p256_4, p256_3)); - pixelFilter_q = _mm256_add_epi16(_mm256_add_epi16(q256_6, q256_5), - _mm256_add_epi16(q256_4, q256_3)); - - pixetFilter_p2p1p0 = - _mm256_add_epi16(p256_0, _mm256_add_epi16(p256_2, p256_1)); - pixelFilter_p = _mm256_add_epi16(pixelFilter_p, pixetFilter_p2p1p0); - - pixetFilter_q2q1q0 = - _mm256_add_epi16(q256_0, _mm256_add_epi16(q256_2, q256_1)); - pixelFilter_q = _mm256_add_epi16(pixelFilter_q, pixetFilter_q2q1q0); - - pixelFilter_p = _mm256_add_epi16( - eight, _mm256_add_epi16(pixelFilter_p, pixelFilter_q)); - - pixetFilter_p2p1p0 = _mm256_add_epi16( - four, _mm256_add_epi16(pixetFilter_p2p1p0, pixetFilter_q2q1q0)); - - res_p = _mm256_srli_epi16( - _mm256_add_epi16(pixelFilter_p, _mm256_add_epi16(p256_7, p256_0)), 4); - - flat2_p0 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_p, res_p), 168)); - - res_q = _mm256_srli_epi16( - _mm256_add_epi16(pixelFilter_p, _mm256_add_epi16(q256_7, q256_0)), 4); - - flat2_q0 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_q, res_q), 168)); - - res_p = - _mm256_srli_epi16(_mm256_add_epi16(pixetFilter_p2p1p0, - _mm256_add_epi16(p256_3, p256_0)), - 3); - - flat_p0 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_p, res_p), 168)); - - res_q = - _mm256_srli_epi16(_mm256_add_epi16(pixetFilter_p2p1p0, - _mm256_add_epi16(q256_3, q256_0)), - 3); - - flat_q0 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_q, res_q), 168)); - - sum_p7 = _mm256_add_epi16(p256_7, p256_7); - - sum_q7 = _mm256_add_epi16(q256_7, q256_7); - - sum_p3 = _mm256_add_epi16(p256_3, p256_3); - - sum_q3 = _mm256_add_epi16(q256_3, q256_3); - - pixelFilter_q = _mm256_sub_epi16(pixelFilter_p, p256_6); - - pixelFilter_p = _mm256_sub_epi16(pixelFilter_p, q256_6); - - res_p = _mm256_srli_epi16( - _mm256_add_epi16(pixelFilter_p, _mm256_add_epi16(sum_p7, p256_1)), 4); - - flat2_p1 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_p, res_p), 168)); - - res_q = _mm256_srli_epi16( - _mm256_add_epi16(pixelFilter_q, _mm256_add_epi16(sum_q7, q256_1)), 4); - - flat2_q1 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_q, res_q), 168)); - - pixetFilter_q2q1q0 = _mm256_sub_epi16(pixetFilter_p2p1p0, p256_2); - - pixetFilter_p2p1p0 = _mm256_sub_epi16(pixetFilter_p2p1p0, q256_2); - - res_p = - _mm256_srli_epi16(_mm256_add_epi16(pixetFilter_p2p1p0, - _mm256_add_epi16(sum_p3, p256_1)), - 3); - - flat_p1 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_p, res_p), 168)); - - res_q = - _mm256_srli_epi16(_mm256_add_epi16(pixetFilter_q2q1q0, - _mm256_add_epi16(sum_q3, q256_1)), - 3); - - flat_q1 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_q, res_q), 168)); - - sum_p7 = _mm256_add_epi16(sum_p7, p256_7); - - sum_q7 = _mm256_add_epi16(sum_q7, q256_7); - - sum_p3 = _mm256_add_epi16(sum_p3, p256_3); - - sum_q3 = _mm256_add_epi16(sum_q3, q256_3); - - pixelFilter_p = _mm256_sub_epi16(pixelFilter_p, q256_5); - - pixelFilter_q = _mm256_sub_epi16(pixelFilter_q, p256_5); - - res_p = _mm256_srli_epi16( - _mm256_add_epi16(pixelFilter_p, _mm256_add_epi16(sum_p7, p256_2)), 4); - - flat2_p2 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_p, res_p), 168)); - - res_q = _mm256_srli_epi16( - _mm256_add_epi16(pixelFilter_q, _mm256_add_epi16(sum_q7, q256_2)), 4); - - flat2_q2 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_q, res_q), 168)); - - pixetFilter_p2p1p0 = _mm256_sub_epi16(pixetFilter_p2p1p0, q256_1); - - pixetFilter_q2q1q0 = _mm256_sub_epi16(pixetFilter_q2q1q0, p256_1); - - res_p = - _mm256_srli_epi16(_mm256_add_epi16(pixetFilter_p2p1p0, - _mm256_add_epi16(sum_p3, p256_2)), - 3); - - flat_p2 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_p, res_p), 168)); - - res_q = - _mm256_srli_epi16(_mm256_add_epi16(pixetFilter_q2q1q0, - _mm256_add_epi16(sum_q3, q256_2)), - 3); - - flat_q2 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_q, res_q), 168)); - - sum_p7 = _mm256_add_epi16(sum_p7, p256_7); - - sum_q7 = _mm256_add_epi16(sum_q7, q256_7); - - pixelFilter_p = _mm256_sub_epi16(pixelFilter_p, q256_4); - - pixelFilter_q = _mm256_sub_epi16(pixelFilter_q, p256_4); - - res_p = _mm256_srli_epi16( - _mm256_add_epi16(pixelFilter_p, _mm256_add_epi16(sum_p7, p256_3)), 4); - - flat2_p3 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_p, res_p), 168)); - - res_q = _mm256_srli_epi16( - _mm256_add_epi16(pixelFilter_q, _mm256_add_epi16(sum_q7, q256_3)), 4); - - flat2_q3 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_q, res_q), 168)); - - sum_p7 = _mm256_add_epi16(sum_p7, p256_7); - - sum_q7 = _mm256_add_epi16(sum_q7, q256_7); - - pixelFilter_p = _mm256_sub_epi16(pixelFilter_p, q256_3); - - pixelFilter_q = _mm256_sub_epi16(pixelFilter_q, p256_3); - - res_p = _mm256_srli_epi16( - _mm256_add_epi16(pixelFilter_p, _mm256_add_epi16(sum_p7, p256_4)), 4); - - flat2_p4 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_p, res_p), 168)); - - res_q = _mm256_srli_epi16( - _mm256_add_epi16(pixelFilter_q, _mm256_add_epi16(sum_q7, q256_4)), 4); - - flat2_q4 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_q, res_q), 168)); - - sum_p7 = _mm256_add_epi16(sum_p7, p256_7); - - sum_q7 = _mm256_add_epi16(sum_q7, q256_7); - - pixelFilter_p = _mm256_sub_epi16(pixelFilter_p, q256_2); - - pixelFilter_q = _mm256_sub_epi16(pixelFilter_q, p256_2); - - res_p = _mm256_srli_epi16( - _mm256_add_epi16(pixelFilter_p, _mm256_add_epi16(sum_p7, p256_5)), 4); - - flat2_p5 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_p, res_p), 168)); - - res_q = _mm256_srli_epi16( - _mm256_add_epi16(pixelFilter_q, _mm256_add_epi16(sum_q7, q256_5)), 4); - - flat2_q5 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_q, res_q), 168)); - - sum_p7 = _mm256_add_epi16(sum_p7, p256_7); - - sum_q7 = _mm256_add_epi16(sum_q7, q256_7); - - pixelFilter_p = _mm256_sub_epi16(pixelFilter_p, q256_1); - - pixelFilter_q = _mm256_sub_epi16(pixelFilter_q, p256_1); - - res_p = _mm256_srli_epi16( - _mm256_add_epi16(pixelFilter_p, _mm256_add_epi16(sum_p7, p256_6)), 4); - - flat2_p6 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_p, res_p), 168)); - - res_q = _mm256_srli_epi16( - _mm256_add_epi16(pixelFilter_q, _mm256_add_epi16(sum_q7, q256_6)), 4); - - flat2_q6 = _mm256_castsi256_si128( - _mm256_permute4x64_epi64(_mm256_packus_epi16(res_q, res_q), 168)); - } - - // wide flat - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - p2 = _mm_andnot_si128(flat, p2); - flat_p2 = _mm_and_si128(flat, flat_p2); - p2 = _mm_or_si128(flat_p2, p2); - - p1 = _mm_andnot_si128(flat, ps1); - flat_p1 = _mm_and_si128(flat, flat_p1); - p1 = _mm_or_si128(flat_p1, p1); - - p0 = _mm_andnot_si128(flat, ps0); - flat_p0 = _mm_and_si128(flat, flat_p0); - p0 = _mm_or_si128(flat_p0, p0); - - q0 = _mm_andnot_si128(flat, qs0); - flat_q0 = _mm_and_si128(flat, flat_q0); - q0 = _mm_or_si128(flat_q0, q0); - - q1 = _mm_andnot_si128(flat, qs1); - flat_q1 = _mm_and_si128(flat, flat_q1); - q1 = _mm_or_si128(flat_q1, q1); - - q2 = _mm_andnot_si128(flat, q2); - flat_q2 = _mm_and_si128(flat, flat_q2); - q2 = _mm_or_si128(flat_q2, q2); - - p6 = _mm_andnot_si128(flat2, p6); - flat2_p6 = _mm_and_si128(flat2, flat2_p6); - p6 = _mm_or_si128(flat2_p6, p6); - _mm_storeu_si128((__m128i *)(s - 7 * pitch), p6); - - p5 = _mm_andnot_si128(flat2, p5); - flat2_p5 = _mm_and_si128(flat2, flat2_p5); - p5 = _mm_or_si128(flat2_p5, p5); - _mm_storeu_si128((__m128i *)(s - 6 * pitch), p5); - - p4 = _mm_andnot_si128(flat2, p4); - flat2_p4 = _mm_and_si128(flat2, flat2_p4); - p4 = _mm_or_si128(flat2_p4, p4); - _mm_storeu_si128((__m128i *)(s - 5 * pitch), p4); - - p3 = _mm_andnot_si128(flat2, p3); - flat2_p3 = _mm_and_si128(flat2, flat2_p3); - p3 = _mm_or_si128(flat2_p3, p3); - _mm_storeu_si128((__m128i *)(s - 4 * pitch), p3); - - p2 = _mm_andnot_si128(flat2, p2); - flat2_p2 = _mm_and_si128(flat2, flat2_p2); - p2 = _mm_or_si128(flat2_p2, p2); - _mm_storeu_si128((__m128i *)(s - 3 * pitch), p2); - - p1 = _mm_andnot_si128(flat2, p1); - flat2_p1 = _mm_and_si128(flat2, flat2_p1); - p1 = _mm_or_si128(flat2_p1, p1); - _mm_storeu_si128((__m128i *)(s - 2 * pitch), p1); - - p0 = _mm_andnot_si128(flat2, p0); - flat2_p0 = _mm_and_si128(flat2, flat2_p0); - p0 = _mm_or_si128(flat2_p0, p0); - _mm_storeu_si128((__m128i *)(s - 1 * pitch), p0); - - q0 = _mm_andnot_si128(flat2, q0); - flat2_q0 = _mm_and_si128(flat2, flat2_q0); - q0 = _mm_or_si128(flat2_q0, q0); - _mm_storeu_si128((__m128i *)(s - 0 * pitch), q0); - - q1 = _mm_andnot_si128(flat2, q1); - flat2_q1 = _mm_and_si128(flat2, flat2_q1); - q1 = _mm_or_si128(flat2_q1, q1); - _mm_storeu_si128((__m128i *)(s + 1 * pitch), q1); - - q2 = _mm_andnot_si128(flat2, q2); - flat2_q2 = _mm_and_si128(flat2, flat2_q2); - q2 = _mm_or_si128(flat2_q2, q2); - _mm_storeu_si128((__m128i *)(s + 2 * pitch), q2); - - q3 = _mm_andnot_si128(flat2, q3); - flat2_q3 = _mm_and_si128(flat2, flat2_q3); - q3 = _mm_or_si128(flat2_q3, q3); - _mm_storeu_si128((__m128i *)(s + 3 * pitch), q3); - - q4 = _mm_andnot_si128(flat2, q4); - flat2_q4 = _mm_and_si128(flat2, flat2_q4); - q4 = _mm_or_si128(flat2_q4, q4); - _mm_storeu_si128((__m128i *)(s + 4 * pitch), q4); - - q5 = _mm_andnot_si128(flat2, q5); - flat2_q5 = _mm_and_si128(flat2, flat2_q5); - q5 = _mm_or_si128(flat2_q5, q5); - _mm_storeu_si128((__m128i *)(s + 5 * pitch), q5); - - q6 = _mm_andnot_si128(flat2, q6); - flat2_q6 = _mm_and_si128(flat2, flat2_q6); - q6 = _mm_or_si128(flat2_q6, q6); - _mm_storeu_si128((__m128i *)(s + 6 * pitch), q6); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/loopfilter_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/loopfilter_sse2.c deleted file mode 100644 index 6ea34cdd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/loopfilter_sse2.c +++ /dev/null @@ -1,1779 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // SSE2 - -#include "./vpx_dsp_rtcd.h" -#include "vpx_ports/mem.h" -#include "vpx_ports/emmintrin_compat.h" -#include "vpx_dsp/x86/mem_sse2.h" - -static INLINE __m128i abs_diff(__m128i a, __m128i b) { - return _mm_or_si128(_mm_subs_epu8(a, b), _mm_subs_epu8(b, a)); -} - -// filter_mask and hev_mask -#define FILTER_HEV_MASK \ - do { \ - /* (abs(q1 - q0), abs(p1 - p0) */ \ - __m128i flat = abs_diff(q1p1, q0p0); \ - /* abs(p1 - q1), abs(p0 - q0) */ \ - const __m128i abs_p1q1p0q0 = abs_diff(p1p0, q1q0); \ - __m128i abs_p0q0, abs_p1q1, work; \ - \ - /* const uint8_t hev = hev_mask(thresh, *op1, *op0, *oq0, *oq1); */ \ - hev = \ - _mm_unpacklo_epi8(_mm_max_epu8(flat, _mm_srli_si128(flat, 8)), zero); \ - hev = _mm_cmpgt_epi16(hev, thresh_v); \ - hev = _mm_packs_epi16(hev, hev); \ - \ - /* const int8_t mask = filter_mask(*limit, *blimit, */ \ - /* p3, p2, p1, p0, q0, q1, q2, q3); */ \ - abs_p0q0 = \ - _mm_adds_epu8(abs_p1q1p0q0, abs_p1q1p0q0); /* abs(p0 - q0) * 2 */ \ - abs_p1q1 = \ - _mm_unpackhi_epi8(abs_p1q1p0q0, abs_p1q1p0q0); /* abs(p1 - q1) */ \ - abs_p1q1 = _mm_srli_epi16(abs_p1q1, 9); \ - abs_p1q1 = _mm_packs_epi16(abs_p1q1, abs_p1q1); /* abs(p1 - q1) / 2 */ \ - /* abs(p0 - q0) * 2 + abs(p1 - q1) / 2 */ \ - mask = _mm_adds_epu8(abs_p0q0, abs_p1q1); \ - /* abs(p3 - p2), abs(p2 - p1) */ \ - work = abs_diff(p3p2, p2p1); \ - flat = _mm_max_epu8(work, flat); \ - /* abs(q3 - q2), abs(q2 - q1) */ \ - work = abs_diff(q3q2, q2q1); \ - flat = _mm_max_epu8(work, flat); \ - flat = _mm_max_epu8(flat, _mm_srli_si128(flat, 8)); \ - mask = _mm_unpacklo_epi64(mask, flat); \ - mask = _mm_subs_epu8(mask, limit_v); \ - mask = _mm_cmpeq_epi8(mask, zero); \ - mask = _mm_and_si128(mask, _mm_srli_si128(mask, 8)); \ - } while (0) - -#define FILTER4 \ - do { \ - const __m128i t3t4 = \ - _mm_set_epi8(3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4); \ - const __m128i t80 = _mm_set1_epi8((int8_t)0x80); \ - __m128i filter, filter2filter1, work; \ - \ - ps1ps0 = _mm_xor_si128(p1p0, t80); /* ^ 0x80 */ \ - qs1qs0 = _mm_xor_si128(q1q0, t80); \ - \ - /* int8_t filter = signed_char_clamp(ps1 - qs1) & hev; */ \ - work = _mm_subs_epi8(ps1ps0, qs1qs0); \ - filter = _mm_and_si128(_mm_srli_si128(work, 8), hev); \ - /* filter = signed_char_clamp(filter + 3 * (qs0 - ps0)) & mask; */ \ - filter = _mm_subs_epi8(filter, work); \ - filter = _mm_subs_epi8(filter, work); \ - filter = _mm_subs_epi8(filter, work); /* + 3 * (qs0 - ps0) */ \ - filter = _mm_and_si128(filter, mask); /* & mask */ \ - filter = _mm_unpacklo_epi64(filter, filter); \ - \ - /* filter1 = signed_char_clamp(filter + 4) >> 3; */ \ - /* filter2 = signed_char_clamp(filter + 3) >> 3; */ \ - filter2filter1 = _mm_adds_epi8(filter, t3t4); /* signed_char_clamp */ \ - filter = _mm_unpackhi_epi8(filter2filter1, filter2filter1); \ - filter2filter1 = _mm_unpacklo_epi8(filter2filter1, filter2filter1); \ - filter2filter1 = _mm_srai_epi16(filter2filter1, 11); /* >> 3 */ \ - filter = _mm_srai_epi16(filter, 11); /* >> 3 */ \ - filter2filter1 = _mm_packs_epi16(filter2filter1, filter); \ - \ - /* filter = ROUND_POWER_OF_TWO(filter1, 1) & ~hev; */ \ - filter = _mm_subs_epi8(filter2filter1, ff); /* + 1 */ \ - filter = _mm_unpacklo_epi8(filter, filter); \ - filter = _mm_srai_epi16(filter, 9); /* round */ \ - filter = _mm_packs_epi16(filter, filter); \ - filter = _mm_andnot_si128(hev, filter); \ - \ - hev = _mm_unpackhi_epi64(filter2filter1, filter); \ - filter2filter1 = _mm_unpacklo_epi64(filter2filter1, filter); \ - \ - /* signed_char_clamp(qs1 - filter), signed_char_clamp(qs0 - filter1) */ \ - qs1qs0 = _mm_subs_epi8(qs1qs0, filter2filter1); \ - /* signed_char_clamp(ps1 + filter), signed_char_clamp(ps0 + filter2) */ \ - ps1ps0 = _mm_adds_epi8(ps1ps0, hev); \ - qs1qs0 = _mm_xor_si128(qs1qs0, t80); /* ^ 0x80 */ \ - ps1ps0 = _mm_xor_si128(ps1ps0, t80); /* ^ 0x80 */ \ - } while (0) - -void vpx_lpf_horizontal_4_sse2(uint8_t *s, int pitch, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh) { - const __m128i zero = _mm_setzero_si128(); - const __m128i limit_v = - _mm_unpacklo_epi64(_mm_loadl_epi64((const __m128i *)blimit), - _mm_loadl_epi64((const __m128i *)limit)); - const __m128i thresh_v = - _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)thresh), zero); - const __m128i ff = _mm_cmpeq_epi8(zero, zero); - __m128i q1p1, q0p0, p3p2, p2p1, p1p0, q3q2, q2q1, q1q0, ps1ps0, qs1qs0; - __m128i mask, hev; - - p3p2 = _mm_unpacklo_epi64(_mm_loadl_epi64((__m128i *)(s - 3 * pitch)), - _mm_loadl_epi64((__m128i *)(s - 4 * pitch))); - q1p1 = _mm_unpacklo_epi64(_mm_loadl_epi64((__m128i *)(s - 2 * pitch)), - _mm_loadl_epi64((__m128i *)(s + 1 * pitch))); - q0p0 = _mm_unpacklo_epi64(_mm_loadl_epi64((__m128i *)(s - 1 * pitch)), - _mm_loadl_epi64((__m128i *)(s + 0 * pitch))); - q3q2 = _mm_unpacklo_epi64(_mm_loadl_epi64((__m128i *)(s + 2 * pitch)), - _mm_loadl_epi64((__m128i *)(s + 3 * pitch))); - p1p0 = _mm_unpacklo_epi64(q0p0, q1p1); - p2p1 = _mm_unpacklo_epi64(q1p1, p3p2); - q1q0 = _mm_unpackhi_epi64(q0p0, q1p1); - q2q1 = _mm_unpacklo_epi64(_mm_srli_si128(q1p1, 8), q3q2); - - FILTER_HEV_MASK; - FILTER4; - - _mm_storeh_pi((__m64 *)(s - 2 * pitch), _mm_castsi128_ps(ps1ps0)); // *op1 - _mm_storel_epi64((__m128i *)(s - 1 * pitch), ps1ps0); // *op0 - _mm_storel_epi64((__m128i *)(s + 0 * pitch), qs1qs0); // *oq0 - _mm_storeh_pi((__m64 *)(s + 1 * pitch), _mm_castsi128_ps(qs1qs0)); // *oq1 -} - -void vpx_lpf_vertical_4_sse2(uint8_t *s, int pitch, const uint8_t *blimit, - const uint8_t *limit, const uint8_t *thresh) { - const __m128i zero = _mm_setzero_si128(); - const __m128i limit_v = - _mm_unpacklo_epi64(_mm_loadl_epi64((const __m128i *)blimit), - _mm_loadl_epi64((const __m128i *)limit)); - const __m128i thresh_v = - _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)thresh), zero); - const __m128i ff = _mm_cmpeq_epi8(zero, zero); - __m128i x0, x1, x2, x3; - __m128i q1p1, q0p0, p3p2, p2p1, p1p0, q3q2, q2q1, q1q0, ps1ps0, qs1qs0; - __m128i mask, hev; - - // 00 10 01 11 02 12 03 13 04 14 05 15 06 16 07 17 - q1q0 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(s + 0 * pitch - 4)), - _mm_loadl_epi64((__m128i *)(s + 1 * pitch - 4))); - - // 20 30 21 31 22 32 23 33 24 34 25 35 26 36 27 37 - x1 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(s + 2 * pitch - 4)), - _mm_loadl_epi64((__m128i *)(s + 3 * pitch - 4))); - - // 40 50 41 51 42 52 43 53 44 54 45 55 46 56 47 57 - x2 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(s + 4 * pitch - 4)), - _mm_loadl_epi64((__m128i *)(s + 5 * pitch - 4))); - - // 60 70 61 71 62 72 63 73 64 74 65 75 66 76 67 77 - x3 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(s + 6 * pitch - 4)), - _mm_loadl_epi64((__m128i *)(s + 7 * pitch - 4))); - - // Transpose 8x8 - // 00 10 20 30 01 11 21 31 02 12 22 32 03 13 23 33 - p1p0 = _mm_unpacklo_epi16(q1q0, x1); - // 40 50 60 70 41 51 61 71 42 52 62 72 43 53 63 73 - x0 = _mm_unpacklo_epi16(x2, x3); - // 00 10 20 30 40 50 60 70 01 11 21 31 41 51 61 71 - p3p2 = _mm_unpacklo_epi32(p1p0, x0); - // 02 12 22 32 42 52 62 72 03 13 23 33 43 53 63 73 - p1p0 = _mm_unpackhi_epi32(p1p0, x0); - p3p2 = _mm_unpackhi_epi64(p3p2, _mm_slli_si128(p3p2, 8)); // swap lo and high - p1p0 = _mm_unpackhi_epi64(p1p0, _mm_slli_si128(p1p0, 8)); // swap lo and high - - // 04 14 24 34 05 15 25 35 06 16 26 36 07 17 27 37 - q1q0 = _mm_unpackhi_epi16(q1q0, x1); - // 44 54 64 74 45 55 65 75 46 56 66 76 47 57 67 77 - x2 = _mm_unpackhi_epi16(x2, x3); - // 06 16 26 36 46 56 66 76 07 17 27 37 47 57 67 77 - q3q2 = _mm_unpackhi_epi32(q1q0, x2); - // 04 14 24 34 44 54 64 74 05 15 25 35 45 55 65 75 - q1q0 = _mm_unpacklo_epi32(q1q0, x2); - - q0p0 = _mm_unpacklo_epi64(p1p0, q1q0); - q1p1 = _mm_unpackhi_epi64(p1p0, q1q0); - p1p0 = _mm_unpacklo_epi64(q0p0, q1p1); - p2p1 = _mm_unpacklo_epi64(q1p1, p3p2); - q2q1 = _mm_unpacklo_epi64(_mm_srli_si128(q1p1, 8), q3q2); - - FILTER_HEV_MASK; - FILTER4; - - // Transpose 8x4 to 4x8 - // qs1qs0: 20 21 22 23 24 25 26 27 30 31 32 33 34 34 36 37 - // ps1ps0: 10 11 12 13 14 15 16 17 00 01 02 03 04 05 06 07 - // 00 01 02 03 04 05 06 07 10 11 12 13 14 15 16 17 - ps1ps0 = _mm_unpackhi_epi64(ps1ps0, _mm_slli_si128(ps1ps0, 8)); - // 10 30 11 31 12 32 13 33 14 34 15 35 16 36 17 37 - x0 = _mm_unpackhi_epi8(ps1ps0, qs1qs0); - // 00 20 01 21 02 22 03 23 04 24 05 25 06 26 07 27 - ps1ps0 = _mm_unpacklo_epi8(ps1ps0, qs1qs0); - // 04 14 24 34 05 15 25 35 06 16 26 36 07 17 27 37 - qs1qs0 = _mm_unpackhi_epi8(ps1ps0, x0); - // 00 10 20 30 01 11 21 31 02 12 22 32 03 13 23 33 - ps1ps0 = _mm_unpacklo_epi8(ps1ps0, x0); - - storeu_int32(s + 0 * pitch - 2, _mm_cvtsi128_si32(ps1ps0)); - ps1ps0 = _mm_srli_si128(ps1ps0, 4); - storeu_int32(s + 1 * pitch - 2, _mm_cvtsi128_si32(ps1ps0)); - ps1ps0 = _mm_srli_si128(ps1ps0, 4); - storeu_int32(s + 2 * pitch - 2, _mm_cvtsi128_si32(ps1ps0)); - ps1ps0 = _mm_srli_si128(ps1ps0, 4); - storeu_int32(s + 3 * pitch - 2, _mm_cvtsi128_si32(ps1ps0)); - - storeu_int32(s + 4 * pitch - 2, _mm_cvtsi128_si32(qs1qs0)); - qs1qs0 = _mm_srli_si128(qs1qs0, 4); - storeu_int32(s + 5 * pitch - 2, _mm_cvtsi128_si32(qs1qs0)); - qs1qs0 = _mm_srli_si128(qs1qs0, 4); - storeu_int32(s + 6 * pitch - 2, _mm_cvtsi128_si32(qs1qs0)); - qs1qs0 = _mm_srli_si128(qs1qs0, 4); - storeu_int32(s + 7 * pitch - 2, _mm_cvtsi128_si32(qs1qs0)); -} - -void vpx_lpf_horizontal_16_sse2(unsigned char *s, int pitch, - const unsigned char *blimit, - const unsigned char *limit, - const unsigned char *thresh) { - const __m128i zero = _mm_setzero_si128(); - const __m128i one = _mm_set1_epi8(1); - const __m128i blimit_v = _mm_load_si128((const __m128i *)blimit); - const __m128i limit_v = _mm_load_si128((const __m128i *)limit); - const __m128i thresh_v = _mm_load_si128((const __m128i *)thresh); - __m128i mask, hev, flat, flat2; - __m128i q7p7, q6p6, q5p5, q4p4, q3p3, q2p2, q1p1, q0p0, p0q0, p1q1; - __m128i abs_p1p0; - - q4p4 = _mm_loadl_epi64((__m128i *)(s - 5 * pitch)); - q4p4 = _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(q4p4), (__m64 *)(s + 4 * pitch))); - q3p3 = _mm_loadl_epi64((__m128i *)(s - 4 * pitch)); - q3p3 = _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(q3p3), (__m64 *)(s + 3 * pitch))); - q2p2 = _mm_loadl_epi64((__m128i *)(s - 3 * pitch)); - q2p2 = _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(q2p2), (__m64 *)(s + 2 * pitch))); - q1p1 = _mm_loadl_epi64((__m128i *)(s - 2 * pitch)); - q1p1 = _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(q1p1), (__m64 *)(s + 1 * pitch))); - p1q1 = _mm_shuffle_epi32(q1p1, 78); - q0p0 = _mm_loadl_epi64((__m128i *)(s - 1 * pitch)); - q0p0 = _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(q0p0), (__m64 *)(s - 0 * pitch))); - p0q0 = _mm_shuffle_epi32(q0p0, 78); - - { - __m128i abs_p1q1, abs_p0q0, abs_q1q0, fe, ff, work; - abs_p1p0 = abs_diff(q1p1, q0p0); - abs_q1q0 = _mm_srli_si128(abs_p1p0, 8); - fe = _mm_set1_epi8((int8_t)0xfe); - ff = _mm_cmpeq_epi8(abs_p1p0, abs_p1p0); - abs_p0q0 = abs_diff(q0p0, p0q0); - abs_p1q1 = abs_diff(q1p1, p1q1); - flat = _mm_max_epu8(abs_p1p0, abs_q1q0); - hev = _mm_subs_epu8(flat, thresh_v); - hev = _mm_xor_si128(_mm_cmpeq_epi8(hev, zero), ff); - - abs_p0q0 = _mm_adds_epu8(abs_p0q0, abs_p0q0); - abs_p1q1 = _mm_srli_epi16(_mm_and_si128(abs_p1q1, fe), 1); - mask = _mm_subs_epu8(_mm_adds_epu8(abs_p0q0, abs_p1q1), blimit_v); - mask = _mm_xor_si128(_mm_cmpeq_epi8(mask, zero), ff); - // mask |= (abs(p0 - q0) * 2 + abs(p1 - q1) / 2 > blimit) * -1; - mask = _mm_max_epu8(abs_p1p0, mask); - // mask |= (abs(p1 - p0) > limit) * -1; - // mask |= (abs(q1 - q0) > limit) * -1; - - work = _mm_max_epu8(abs_diff(q2p2, q1p1), abs_diff(q3p3, q2p2)); - mask = _mm_max_epu8(work, mask); - mask = _mm_max_epu8(mask, _mm_srli_si128(mask, 8)); - mask = _mm_subs_epu8(mask, limit_v); - mask = _mm_cmpeq_epi8(mask, zero); - } - - // lp filter - { - const __m128i t4 = _mm_set1_epi8(4); - const __m128i t3 = _mm_set1_epi8(3); - const __m128i t80 = _mm_set1_epi8((int8_t)0x80); - const __m128i t1 = _mm_set1_epi16(0x1); - __m128i qs1ps1 = _mm_xor_si128(q1p1, t80); - __m128i qs0ps0 = _mm_xor_si128(q0p0, t80); - __m128i qs0 = _mm_xor_si128(p0q0, t80); - __m128i qs1 = _mm_xor_si128(p1q1, t80); - __m128i filt; - __m128i work_a; - __m128i filter1, filter2; - __m128i flat2_q6p6, flat2_q5p5, flat2_q4p4, flat2_q3p3, flat2_q2p2; - __m128i flat2_q1p1, flat2_q0p0, flat_q2p2, flat_q1p1, flat_q0p0; - - filt = _mm_and_si128(_mm_subs_epi8(qs1ps1, qs1), hev); - work_a = _mm_subs_epi8(qs0, qs0ps0); - filt = _mm_adds_epi8(filt, work_a); - filt = _mm_adds_epi8(filt, work_a); - filt = _mm_adds_epi8(filt, work_a); - // (vpx_filter + 3 * (qs0 - ps0)) & mask - filt = _mm_and_si128(filt, mask); - - filter1 = _mm_adds_epi8(filt, t4); - filter2 = _mm_adds_epi8(filt, t3); - - filter1 = _mm_unpacklo_epi8(zero, filter1); - filter1 = _mm_srai_epi16(filter1, 0xB); - filter2 = _mm_unpacklo_epi8(zero, filter2); - filter2 = _mm_srai_epi16(filter2, 0xB); - - // Filter1 >> 3 - filt = _mm_packs_epi16(filter2, _mm_subs_epi16(zero, filter1)); - qs0ps0 = _mm_xor_si128(_mm_adds_epi8(qs0ps0, filt), t80); - - // filt >> 1 - filt = _mm_adds_epi16(filter1, t1); - filt = _mm_srai_epi16(filt, 1); - filt = _mm_andnot_si128(_mm_srai_epi16(_mm_unpacklo_epi8(zero, hev), 0x8), - filt); - filt = _mm_packs_epi16(filt, _mm_subs_epi16(zero, filt)); - qs1ps1 = _mm_xor_si128(_mm_adds_epi8(qs1ps1, filt), t80); - // loopfilter done - - { - __m128i work; - flat = _mm_max_epu8(abs_diff(q2p2, q0p0), abs_diff(q3p3, q0p0)); - flat = _mm_max_epu8(abs_p1p0, flat); - flat = _mm_max_epu8(flat, _mm_srli_si128(flat, 8)); - flat = _mm_subs_epu8(flat, one); - flat = _mm_cmpeq_epi8(flat, zero); - flat = _mm_and_si128(flat, mask); - - q5p5 = _mm_loadl_epi64((__m128i *)(s - 6 * pitch)); - q5p5 = _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(q5p5), (__m64 *)(s + 5 * pitch))); - - q6p6 = _mm_loadl_epi64((__m128i *)(s - 7 * pitch)); - q6p6 = _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(q6p6), (__m64 *)(s + 6 * pitch))); - flat2 = _mm_max_epu8(abs_diff(q4p4, q0p0), abs_diff(q5p5, q0p0)); - - q7p7 = _mm_loadl_epi64((__m128i *)(s - 8 * pitch)); - q7p7 = _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(q7p7), (__m64 *)(s + 7 * pitch))); - work = _mm_max_epu8(abs_diff(q6p6, q0p0), abs_diff(q7p7, q0p0)); - flat2 = _mm_max_epu8(work, flat2); - flat2 = _mm_max_epu8(flat2, _mm_srli_si128(flat2, 8)); - flat2 = _mm_subs_epu8(flat2, one); - flat2 = _mm_cmpeq_epi8(flat2, zero); - flat2 = _mm_and_si128(flat2, flat); // flat2 & flat & mask - } - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // flat and wide flat calculations - { - const __m128i eight = _mm_set1_epi16(8); - const __m128i four = _mm_set1_epi16(4); - __m128i p7_16, p6_16, p5_16, p4_16, p3_16, p2_16, p1_16, p0_16; - __m128i q7_16, q6_16, q5_16, q4_16, q3_16, q2_16, q1_16, q0_16; - __m128i pixelFilter_p, pixelFilter_q; - __m128i pixetFilter_p2p1p0, pixetFilter_q2q1q0; - __m128i sum_p7, sum_q7, sum_p3, sum_q3, res_p, res_q; - - p7_16 = _mm_unpacklo_epi8(q7p7, zero); - p6_16 = _mm_unpacklo_epi8(q6p6, zero); - p5_16 = _mm_unpacklo_epi8(q5p5, zero); - p4_16 = _mm_unpacklo_epi8(q4p4, zero); - p3_16 = _mm_unpacklo_epi8(q3p3, zero); - p2_16 = _mm_unpacklo_epi8(q2p2, zero); - p1_16 = _mm_unpacklo_epi8(q1p1, zero); - p0_16 = _mm_unpacklo_epi8(q0p0, zero); - q0_16 = _mm_unpackhi_epi8(q0p0, zero); - q1_16 = _mm_unpackhi_epi8(q1p1, zero); - q2_16 = _mm_unpackhi_epi8(q2p2, zero); - q3_16 = _mm_unpackhi_epi8(q3p3, zero); - q4_16 = _mm_unpackhi_epi8(q4p4, zero); - q5_16 = _mm_unpackhi_epi8(q5p5, zero); - q6_16 = _mm_unpackhi_epi8(q6p6, zero); - q7_16 = _mm_unpackhi_epi8(q7p7, zero); - - pixelFilter_p = _mm_add_epi16(_mm_add_epi16(p6_16, p5_16), - _mm_add_epi16(p4_16, p3_16)); - pixelFilter_q = _mm_add_epi16(_mm_add_epi16(q6_16, q5_16), - _mm_add_epi16(q4_16, q3_16)); - - pixetFilter_p2p1p0 = _mm_add_epi16(p0_16, _mm_add_epi16(p2_16, p1_16)); - pixelFilter_p = _mm_add_epi16(pixelFilter_p, pixetFilter_p2p1p0); - - pixetFilter_q2q1q0 = _mm_add_epi16(q0_16, _mm_add_epi16(q2_16, q1_16)); - pixelFilter_q = _mm_add_epi16(pixelFilter_q, pixetFilter_q2q1q0); - pixelFilter_p = - _mm_add_epi16(eight, _mm_add_epi16(pixelFilter_p, pixelFilter_q)); - pixetFilter_p2p1p0 = _mm_add_epi16( - four, _mm_add_epi16(pixetFilter_p2p1p0, pixetFilter_q2q1q0)); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(p7_16, p0_16)), 4); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(q7_16, q0_16)), 4); - flat2_q0p0 = _mm_packus_epi16(res_p, res_q); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_p2p1p0, _mm_add_epi16(p3_16, p0_16)), 3); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_p2p1p0, _mm_add_epi16(q3_16, q0_16)), 3); - - flat_q0p0 = _mm_packus_epi16(res_p, res_q); - - sum_p7 = _mm_add_epi16(p7_16, p7_16); - sum_q7 = _mm_add_epi16(q7_16, q7_16); - sum_p3 = _mm_add_epi16(p3_16, p3_16); - sum_q3 = _mm_add_epi16(q3_16, q3_16); - - pixelFilter_q = _mm_sub_epi16(pixelFilter_p, p6_16); - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q6_16); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p1_16)), 4); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q1_16)), 4); - flat2_q1p1 = _mm_packus_epi16(res_p, res_q); - - pixetFilter_q2q1q0 = _mm_sub_epi16(pixetFilter_p2p1p0, p2_16); - pixetFilter_p2p1p0 = _mm_sub_epi16(pixetFilter_p2p1p0, q2_16); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_p2p1p0, _mm_add_epi16(sum_p3, p1_16)), 3); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_q2q1q0, _mm_add_epi16(sum_q3, q1_16)), 3); - flat_q1p1 = _mm_packus_epi16(res_p, res_q); - - sum_p7 = _mm_add_epi16(sum_p7, p7_16); - sum_q7 = _mm_add_epi16(sum_q7, q7_16); - sum_p3 = _mm_add_epi16(sum_p3, p3_16); - sum_q3 = _mm_add_epi16(sum_q3, q3_16); - - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q5_16); - pixelFilter_q = _mm_sub_epi16(pixelFilter_q, p5_16); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p2_16)), 4); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q2_16)), 4); - flat2_q2p2 = _mm_packus_epi16(res_p, res_q); - - pixetFilter_p2p1p0 = _mm_sub_epi16(pixetFilter_p2p1p0, q1_16); - pixetFilter_q2q1q0 = _mm_sub_epi16(pixetFilter_q2q1q0, p1_16); - - res_p = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_p2p1p0, _mm_add_epi16(sum_p3, p2_16)), 3); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixetFilter_q2q1q0, _mm_add_epi16(sum_q3, q2_16)), 3); - flat_q2p2 = _mm_packus_epi16(res_p, res_q); - - sum_p7 = _mm_add_epi16(sum_p7, p7_16); - sum_q7 = _mm_add_epi16(sum_q7, q7_16); - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q4_16); - pixelFilter_q = _mm_sub_epi16(pixelFilter_q, p4_16); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p3_16)), 4); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q3_16)), 4); - flat2_q3p3 = _mm_packus_epi16(res_p, res_q); - - sum_p7 = _mm_add_epi16(sum_p7, p7_16); - sum_q7 = _mm_add_epi16(sum_q7, q7_16); - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q3_16); - pixelFilter_q = _mm_sub_epi16(pixelFilter_q, p3_16); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p4_16)), 4); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q4_16)), 4); - flat2_q4p4 = _mm_packus_epi16(res_p, res_q); - - sum_p7 = _mm_add_epi16(sum_p7, p7_16); - sum_q7 = _mm_add_epi16(sum_q7, q7_16); - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q2_16); - pixelFilter_q = _mm_sub_epi16(pixelFilter_q, p2_16); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p5_16)), 4); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q5_16)), 4); - flat2_q5p5 = _mm_packus_epi16(res_p, res_q); - - sum_p7 = _mm_add_epi16(sum_p7, p7_16); - sum_q7 = _mm_add_epi16(sum_q7, q7_16); - pixelFilter_p = _mm_sub_epi16(pixelFilter_p, q1_16); - pixelFilter_q = _mm_sub_epi16(pixelFilter_q, p1_16); - res_p = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_p, _mm_add_epi16(sum_p7, p6_16)), 4); - res_q = _mm_srli_epi16( - _mm_add_epi16(pixelFilter_q, _mm_add_epi16(sum_q7, q6_16)), 4); - flat2_q6p6 = _mm_packus_epi16(res_p, res_q); - } - // wide flat - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - flat = _mm_shuffle_epi32(flat, 68); - flat2 = _mm_shuffle_epi32(flat2, 68); - - q2p2 = _mm_andnot_si128(flat, q2p2); - flat_q2p2 = _mm_and_si128(flat, flat_q2p2); - q2p2 = _mm_or_si128(q2p2, flat_q2p2); - - qs1ps1 = _mm_andnot_si128(flat, qs1ps1); - flat_q1p1 = _mm_and_si128(flat, flat_q1p1); - q1p1 = _mm_or_si128(qs1ps1, flat_q1p1); - - qs0ps0 = _mm_andnot_si128(flat, qs0ps0); - flat_q0p0 = _mm_and_si128(flat, flat_q0p0); - q0p0 = _mm_or_si128(qs0ps0, flat_q0p0); - - q6p6 = _mm_andnot_si128(flat2, q6p6); - flat2_q6p6 = _mm_and_si128(flat2, flat2_q6p6); - q6p6 = _mm_or_si128(q6p6, flat2_q6p6); - _mm_storel_epi64((__m128i *)(s - 7 * pitch), q6p6); - _mm_storeh_pi((__m64 *)(s + 6 * pitch), _mm_castsi128_ps(q6p6)); - - q5p5 = _mm_andnot_si128(flat2, q5p5); - flat2_q5p5 = _mm_and_si128(flat2, flat2_q5p5); - q5p5 = _mm_or_si128(q5p5, flat2_q5p5); - _mm_storel_epi64((__m128i *)(s - 6 * pitch), q5p5); - _mm_storeh_pi((__m64 *)(s + 5 * pitch), _mm_castsi128_ps(q5p5)); - - q4p4 = _mm_andnot_si128(flat2, q4p4); - flat2_q4p4 = _mm_and_si128(flat2, flat2_q4p4); - q4p4 = _mm_or_si128(q4p4, flat2_q4p4); - _mm_storel_epi64((__m128i *)(s - 5 * pitch), q4p4); - _mm_storeh_pi((__m64 *)(s + 4 * pitch), _mm_castsi128_ps(q4p4)); - - q3p3 = _mm_andnot_si128(flat2, q3p3); - flat2_q3p3 = _mm_and_si128(flat2, flat2_q3p3); - q3p3 = _mm_or_si128(q3p3, flat2_q3p3); - _mm_storel_epi64((__m128i *)(s - 4 * pitch), q3p3); - _mm_storeh_pi((__m64 *)(s + 3 * pitch), _mm_castsi128_ps(q3p3)); - - q2p2 = _mm_andnot_si128(flat2, q2p2); - flat2_q2p2 = _mm_and_si128(flat2, flat2_q2p2); - q2p2 = _mm_or_si128(q2p2, flat2_q2p2); - _mm_storel_epi64((__m128i *)(s - 3 * pitch), q2p2); - _mm_storeh_pi((__m64 *)(s + 2 * pitch), _mm_castsi128_ps(q2p2)); - - q1p1 = _mm_andnot_si128(flat2, q1p1); - flat2_q1p1 = _mm_and_si128(flat2, flat2_q1p1); - q1p1 = _mm_or_si128(q1p1, flat2_q1p1); - _mm_storel_epi64((__m128i *)(s - 2 * pitch), q1p1); - _mm_storeh_pi((__m64 *)(s + 1 * pitch), _mm_castsi128_ps(q1p1)); - - q0p0 = _mm_andnot_si128(flat2, q0p0); - flat2_q0p0 = _mm_and_si128(flat2, flat2_q0p0); - q0p0 = _mm_or_si128(q0p0, flat2_q0p0); - _mm_storel_epi64((__m128i *)(s - 1 * pitch), q0p0); - _mm_storeh_pi((__m64 *)(s - 0 * pitch), _mm_castsi128_ps(q0p0)); - } -} - -static INLINE __m128i filter_add2_sub2(const __m128i *const total, - const __m128i *const a1, - const __m128i *const a2, - const __m128i *const s1, - const __m128i *const s2) { - __m128i x = _mm_add_epi16(*a1, *total); - x = _mm_add_epi16(_mm_sub_epi16(x, _mm_add_epi16(*s1, *s2)), *a2); - return x; -} - -static INLINE __m128i filter8_mask(const __m128i *const flat, - const __m128i *const other_filt, - const __m128i *const f8_lo, - const __m128i *const f8_hi) { - const __m128i f8 = - _mm_packus_epi16(_mm_srli_epi16(*f8_lo, 3), _mm_srli_epi16(*f8_hi, 3)); - const __m128i result = _mm_and_si128(*flat, f8); - return _mm_or_si128(_mm_andnot_si128(*flat, *other_filt), result); -} - -static INLINE __m128i filter16_mask(const __m128i *const flat, - const __m128i *const other_filt, - const __m128i *const f_lo, - const __m128i *const f_hi) { - const __m128i f = - _mm_packus_epi16(_mm_srli_epi16(*f_lo, 4), _mm_srli_epi16(*f_hi, 4)); - const __m128i result = _mm_and_si128(*flat, f); - return _mm_or_si128(_mm_andnot_si128(*flat, *other_filt), result); -} - -void vpx_lpf_horizontal_16_dual_sse2(unsigned char *s, int pitch, - const unsigned char *blimit, - const unsigned char *limit, - const unsigned char *thresh) { - const __m128i zero = _mm_setzero_si128(); - const __m128i one = _mm_set1_epi8(1); - const __m128i blimit_v = _mm_load_si128((const __m128i *)blimit); - const __m128i limit_v = _mm_load_si128((const __m128i *)limit); - const __m128i thresh_v = _mm_load_si128((const __m128i *)thresh); - __m128i mask, hev, flat, flat2; - __m128i p7, p6, p5; - __m128i p4, p3, p2, p1, p0, q0, q1, q2, q3, q4; - __m128i q5, q6, q7; - - __m128i op2, op1, op0, oq0, oq1, oq2; - - __m128i max_abs_p1p0q1q0; - - p7 = _mm_loadu_si128((__m128i *)(s - 8 * pitch)); - p6 = _mm_loadu_si128((__m128i *)(s - 7 * pitch)); - p5 = _mm_loadu_si128((__m128i *)(s - 6 * pitch)); - p4 = _mm_loadu_si128((__m128i *)(s - 5 * pitch)); - p3 = _mm_loadu_si128((__m128i *)(s - 4 * pitch)); - p2 = _mm_loadu_si128((__m128i *)(s - 3 * pitch)); - p1 = _mm_loadu_si128((__m128i *)(s - 2 * pitch)); - p0 = _mm_loadu_si128((__m128i *)(s - 1 * pitch)); - q0 = _mm_loadu_si128((__m128i *)(s - 0 * pitch)); - q1 = _mm_loadu_si128((__m128i *)(s + 1 * pitch)); - q2 = _mm_loadu_si128((__m128i *)(s + 2 * pitch)); - q3 = _mm_loadu_si128((__m128i *)(s + 3 * pitch)); - q4 = _mm_loadu_si128((__m128i *)(s + 4 * pitch)); - q5 = _mm_loadu_si128((__m128i *)(s + 5 * pitch)); - q6 = _mm_loadu_si128((__m128i *)(s + 6 * pitch)); - q7 = _mm_loadu_si128((__m128i *)(s + 7 * pitch)); - - { - const __m128i abs_p1p0 = abs_diff(p1, p0); - const __m128i abs_q1q0 = abs_diff(q1, q0); - const __m128i fe = _mm_set1_epi8((int8_t)0xfe); - const __m128i ff = _mm_cmpeq_epi8(zero, zero); - __m128i abs_p0q0 = abs_diff(p0, q0); - __m128i abs_p1q1 = abs_diff(p1, q1); - __m128i work; - max_abs_p1p0q1q0 = _mm_max_epu8(abs_p1p0, abs_q1q0); - - abs_p0q0 = _mm_adds_epu8(abs_p0q0, abs_p0q0); - abs_p1q1 = _mm_srli_epi16(_mm_and_si128(abs_p1q1, fe), 1); - mask = _mm_subs_epu8(_mm_adds_epu8(abs_p0q0, abs_p1q1), blimit_v); - mask = _mm_xor_si128(_mm_cmpeq_epi8(mask, zero), ff); - // mask |= (abs(p0 - q0) * 2 + abs(p1 - q1) / 2 > blimit) * -1; - mask = _mm_max_epu8(max_abs_p1p0q1q0, mask); - // mask |= (abs(p1 - p0) > limit) * -1; - // mask |= (abs(q1 - q0) > limit) * -1; - work = _mm_max_epu8(abs_diff(p2, p1), abs_diff(p3, p2)); - mask = _mm_max_epu8(work, mask); - work = _mm_max_epu8(abs_diff(q2, q1), abs_diff(q3, q2)); - mask = _mm_max_epu8(work, mask); - mask = _mm_subs_epu8(mask, limit_v); - mask = _mm_cmpeq_epi8(mask, zero); - } - - { - __m128i work; - work = _mm_max_epu8(abs_diff(p2, p0), abs_diff(q2, q0)); - flat = _mm_max_epu8(work, max_abs_p1p0q1q0); - work = _mm_max_epu8(abs_diff(p3, p0), abs_diff(q3, q0)); - flat = _mm_max_epu8(work, flat); - work = _mm_max_epu8(abs_diff(p4, p0), abs_diff(q4, q0)); - flat = _mm_subs_epu8(flat, one); - flat = _mm_cmpeq_epi8(flat, zero); - flat = _mm_and_si128(flat, mask); - flat2 = _mm_max_epu8(abs_diff(p5, p0), abs_diff(q5, q0)); - flat2 = _mm_max_epu8(work, flat2); - work = _mm_max_epu8(abs_diff(p6, p0), abs_diff(q6, q0)); - flat2 = _mm_max_epu8(work, flat2); - work = _mm_max_epu8(abs_diff(p7, p0), abs_diff(q7, q0)); - flat2 = _mm_max_epu8(work, flat2); - flat2 = _mm_subs_epu8(flat2, one); - flat2 = _mm_cmpeq_epi8(flat2, zero); - flat2 = _mm_and_si128(flat2, flat); // flat2 & flat & mask - } - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // filter4 - { - const __m128i t4 = _mm_set1_epi8(4); - const __m128i t3 = _mm_set1_epi8(3); - const __m128i t80 = _mm_set1_epi8((int8_t)0x80); - const __m128i te0 = _mm_set1_epi8((int8_t)0xe0); - const __m128i t1f = _mm_set1_epi8(0x1f); - const __m128i t1 = _mm_set1_epi8(0x1); - const __m128i t7f = _mm_set1_epi8(0x7f); - const __m128i ff = _mm_cmpeq_epi8(t4, t4); - - __m128i filt; - __m128i work_a; - __m128i filter1, filter2; - - op1 = _mm_xor_si128(p1, t80); - op0 = _mm_xor_si128(p0, t80); - oq0 = _mm_xor_si128(q0, t80); - oq1 = _mm_xor_si128(q1, t80); - - hev = _mm_subs_epu8(max_abs_p1p0q1q0, thresh_v); - hev = _mm_xor_si128(_mm_cmpeq_epi8(hev, zero), ff); - filt = _mm_and_si128(_mm_subs_epi8(op1, oq1), hev); - - work_a = _mm_subs_epi8(oq0, op0); - filt = _mm_adds_epi8(filt, work_a); - filt = _mm_adds_epi8(filt, work_a); - filt = _mm_adds_epi8(filt, work_a); - // (vpx_filter + 3 * (qs0 - ps0)) & mask - filt = _mm_and_si128(filt, mask); - filter1 = _mm_adds_epi8(filt, t4); - filter2 = _mm_adds_epi8(filt, t3); - - // Filter1 >> 3 - work_a = _mm_cmpgt_epi8(zero, filter1); - filter1 = _mm_srli_epi16(filter1, 3); - work_a = _mm_and_si128(work_a, te0); - filter1 = _mm_and_si128(filter1, t1f); - filter1 = _mm_or_si128(filter1, work_a); - oq0 = _mm_xor_si128(_mm_subs_epi8(oq0, filter1), t80); - - // Filter2 >> 3 - work_a = _mm_cmpgt_epi8(zero, filter2); - filter2 = _mm_srli_epi16(filter2, 3); - work_a = _mm_and_si128(work_a, te0); - filter2 = _mm_and_si128(filter2, t1f); - filter2 = _mm_or_si128(filter2, work_a); - op0 = _mm_xor_si128(_mm_adds_epi8(op0, filter2), t80); - - // filt >> 1 - filt = _mm_adds_epi8(filter1, t1); - work_a = _mm_cmpgt_epi8(zero, filt); - filt = _mm_srli_epi16(filt, 1); - work_a = _mm_and_si128(work_a, t80); - filt = _mm_and_si128(filt, t7f); - filt = _mm_or_si128(filt, work_a); - filt = _mm_andnot_si128(hev, filt); - op1 = _mm_xor_si128(_mm_adds_epi8(op1, filt), t80); - oq1 = _mm_xor_si128(_mm_subs_epi8(oq1, filt), t80); - // loopfilter done - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // filter8 - { - const __m128i four = _mm_set1_epi16(4); - const __m128i p3_lo = _mm_unpacklo_epi8(p3, zero); - const __m128i p2_lo = _mm_unpacklo_epi8(p2, zero); - const __m128i p1_lo = _mm_unpacklo_epi8(p1, zero); - const __m128i p0_lo = _mm_unpacklo_epi8(p0, zero); - const __m128i q0_lo = _mm_unpacklo_epi8(q0, zero); - const __m128i q1_lo = _mm_unpacklo_epi8(q1, zero); - const __m128i q2_lo = _mm_unpacklo_epi8(q2, zero); - const __m128i q3_lo = _mm_unpacklo_epi8(q3, zero); - - const __m128i p3_hi = _mm_unpackhi_epi8(p3, zero); - const __m128i p2_hi = _mm_unpackhi_epi8(p2, zero); - const __m128i p1_hi = _mm_unpackhi_epi8(p1, zero); - const __m128i p0_hi = _mm_unpackhi_epi8(p0, zero); - const __m128i q0_hi = _mm_unpackhi_epi8(q0, zero); - const __m128i q1_hi = _mm_unpackhi_epi8(q1, zero); - const __m128i q2_hi = _mm_unpackhi_epi8(q2, zero); - const __m128i q3_hi = _mm_unpackhi_epi8(q3, zero); - __m128i f8_lo, f8_hi; - - f8_lo = _mm_add_epi16(_mm_add_epi16(p3_lo, four), - _mm_add_epi16(p3_lo, p2_lo)); - f8_lo = _mm_add_epi16(_mm_add_epi16(p3_lo, f8_lo), - _mm_add_epi16(p2_lo, p1_lo)); - f8_lo = _mm_add_epi16(_mm_add_epi16(p0_lo, q0_lo), f8_lo); - - f8_hi = _mm_add_epi16(_mm_add_epi16(p3_hi, four), - _mm_add_epi16(p3_hi, p2_hi)); - f8_hi = _mm_add_epi16(_mm_add_epi16(p3_hi, f8_hi), - _mm_add_epi16(p2_hi, p1_hi)); - f8_hi = _mm_add_epi16(_mm_add_epi16(p0_hi, q0_hi), f8_hi); - - op2 = filter8_mask(&flat, &p2, &f8_lo, &f8_hi); - - f8_lo = filter_add2_sub2(&f8_lo, &q1_lo, &p1_lo, &p2_lo, &p3_lo); - f8_hi = filter_add2_sub2(&f8_hi, &q1_hi, &p1_hi, &p2_hi, &p3_hi); - op1 = filter8_mask(&flat, &op1, &f8_lo, &f8_hi); - - f8_lo = filter_add2_sub2(&f8_lo, &q2_lo, &p0_lo, &p1_lo, &p3_lo); - f8_hi = filter_add2_sub2(&f8_hi, &q2_hi, &p0_hi, &p1_hi, &p3_hi); - op0 = filter8_mask(&flat, &op0, &f8_lo, &f8_hi); - - f8_lo = filter_add2_sub2(&f8_lo, &q3_lo, &q0_lo, &p0_lo, &p3_lo); - f8_hi = filter_add2_sub2(&f8_hi, &q3_hi, &q0_hi, &p0_hi, &p3_hi); - oq0 = filter8_mask(&flat, &oq0, &f8_lo, &f8_hi); - - f8_lo = filter_add2_sub2(&f8_lo, &q3_lo, &q1_lo, &q0_lo, &p2_lo); - f8_hi = filter_add2_sub2(&f8_hi, &q3_hi, &q1_hi, &q0_hi, &p2_hi); - oq1 = filter8_mask(&flat, &oq1, &f8_lo, &f8_hi); - - f8_lo = filter_add2_sub2(&f8_lo, &q3_lo, &q2_lo, &q1_lo, &p1_lo); - f8_hi = filter_add2_sub2(&f8_hi, &q3_hi, &q2_hi, &q1_hi, &p1_hi); - oq2 = filter8_mask(&flat, &q2, &f8_lo, &f8_hi); - } - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // wide flat calculations - { - const __m128i eight = _mm_set1_epi16(8); - const __m128i p7_lo = _mm_unpacklo_epi8(p7, zero); - const __m128i p6_lo = _mm_unpacklo_epi8(p6, zero); - const __m128i p5_lo = _mm_unpacklo_epi8(p5, zero); - const __m128i p4_lo = _mm_unpacklo_epi8(p4, zero); - const __m128i p3_lo = _mm_unpacklo_epi8(p3, zero); - const __m128i p2_lo = _mm_unpacklo_epi8(p2, zero); - const __m128i p1_lo = _mm_unpacklo_epi8(p1, zero); - const __m128i p0_lo = _mm_unpacklo_epi8(p0, zero); - const __m128i q0_lo = _mm_unpacklo_epi8(q0, zero); - const __m128i q1_lo = _mm_unpacklo_epi8(q1, zero); - const __m128i q2_lo = _mm_unpacklo_epi8(q2, zero); - const __m128i q3_lo = _mm_unpacklo_epi8(q3, zero); - const __m128i q4_lo = _mm_unpacklo_epi8(q4, zero); - const __m128i q5_lo = _mm_unpacklo_epi8(q5, zero); - const __m128i q6_lo = _mm_unpacklo_epi8(q6, zero); - const __m128i q7_lo = _mm_unpacklo_epi8(q7, zero); - - const __m128i p7_hi = _mm_unpackhi_epi8(p7, zero); - const __m128i p6_hi = _mm_unpackhi_epi8(p6, zero); - const __m128i p5_hi = _mm_unpackhi_epi8(p5, zero); - const __m128i p4_hi = _mm_unpackhi_epi8(p4, zero); - const __m128i p3_hi = _mm_unpackhi_epi8(p3, zero); - const __m128i p2_hi = _mm_unpackhi_epi8(p2, zero); - const __m128i p1_hi = _mm_unpackhi_epi8(p1, zero); - const __m128i p0_hi = _mm_unpackhi_epi8(p0, zero); - const __m128i q0_hi = _mm_unpackhi_epi8(q0, zero); - const __m128i q1_hi = _mm_unpackhi_epi8(q1, zero); - const __m128i q2_hi = _mm_unpackhi_epi8(q2, zero); - const __m128i q3_hi = _mm_unpackhi_epi8(q3, zero); - const __m128i q4_hi = _mm_unpackhi_epi8(q4, zero); - const __m128i q5_hi = _mm_unpackhi_epi8(q5, zero); - const __m128i q6_hi = _mm_unpackhi_epi8(q6, zero); - const __m128i q7_hi = _mm_unpackhi_epi8(q7, zero); - - __m128i f_lo; - __m128i f_hi; - - f_lo = _mm_sub_epi16(_mm_slli_epi16(p7_lo, 3), p7_lo); // p7 * 7 - f_lo = - _mm_add_epi16(_mm_slli_epi16(p6_lo, 1), _mm_add_epi16(p4_lo, f_lo)); - f_lo = _mm_add_epi16(_mm_add_epi16(p3_lo, f_lo), - _mm_add_epi16(p2_lo, p1_lo)); - f_lo = _mm_add_epi16(_mm_add_epi16(p0_lo, q0_lo), f_lo); - f_lo = _mm_add_epi16(_mm_add_epi16(p5_lo, eight), f_lo); - - f_hi = _mm_sub_epi16(_mm_slli_epi16(p7_hi, 3), p7_hi); // p7 * 7 - f_hi = - _mm_add_epi16(_mm_slli_epi16(p6_hi, 1), _mm_add_epi16(p4_hi, f_hi)); - f_hi = _mm_add_epi16(_mm_add_epi16(p3_hi, f_hi), - _mm_add_epi16(p2_hi, p1_hi)); - f_hi = _mm_add_epi16(_mm_add_epi16(p0_hi, q0_hi), f_hi); - f_hi = _mm_add_epi16(_mm_add_epi16(p5_hi, eight), f_hi); - - p6 = filter16_mask(&flat2, &p6, &f_lo, &f_hi); - _mm_storeu_si128((__m128i *)(s - 7 * pitch), p6); - - f_lo = filter_add2_sub2(&f_lo, &q1_lo, &p5_lo, &p6_lo, &p7_lo); - f_hi = filter_add2_sub2(&f_hi, &q1_hi, &p5_hi, &p6_hi, &p7_hi); - p5 = filter16_mask(&flat2, &p5, &f_lo, &f_hi); - _mm_storeu_si128((__m128i *)(s - 6 * pitch), p5); - - f_lo = filter_add2_sub2(&f_lo, &q2_lo, &p4_lo, &p5_lo, &p7_lo); - f_hi = filter_add2_sub2(&f_hi, &q2_hi, &p4_hi, &p5_hi, &p7_hi); - p4 = filter16_mask(&flat2, &p4, &f_lo, &f_hi); - _mm_storeu_si128((__m128i *)(s - 5 * pitch), p4); - - f_lo = filter_add2_sub2(&f_lo, &q3_lo, &p3_lo, &p4_lo, &p7_lo); - f_hi = filter_add2_sub2(&f_hi, &q3_hi, &p3_hi, &p4_hi, &p7_hi); - p3 = filter16_mask(&flat2, &p3, &f_lo, &f_hi); - _mm_storeu_si128((__m128i *)(s - 4 * pitch), p3); - - f_lo = filter_add2_sub2(&f_lo, &q4_lo, &p2_lo, &p3_lo, &p7_lo); - f_hi = filter_add2_sub2(&f_hi, &q4_hi, &p2_hi, &p3_hi, &p7_hi); - op2 = filter16_mask(&flat2, &op2, &f_lo, &f_hi); - _mm_storeu_si128((__m128i *)(s - 3 * pitch), op2); - - f_lo = filter_add2_sub2(&f_lo, &q5_lo, &p1_lo, &p2_lo, &p7_lo); - f_hi = filter_add2_sub2(&f_hi, &q5_hi, &p1_hi, &p2_hi, &p7_hi); - op1 = filter16_mask(&flat2, &op1, &f_lo, &f_hi); - _mm_storeu_si128((__m128i *)(s - 2 * pitch), op1); - - f_lo = filter_add2_sub2(&f_lo, &q6_lo, &p0_lo, &p1_lo, &p7_lo); - f_hi = filter_add2_sub2(&f_hi, &q6_hi, &p0_hi, &p1_hi, &p7_hi); - op0 = filter16_mask(&flat2, &op0, &f_lo, &f_hi); - _mm_storeu_si128((__m128i *)(s - 1 * pitch), op0); - - f_lo = filter_add2_sub2(&f_lo, &q7_lo, &q0_lo, &p0_lo, &p7_lo); - f_hi = filter_add2_sub2(&f_hi, &q7_hi, &q0_hi, &p0_hi, &p7_hi); - oq0 = filter16_mask(&flat2, &oq0, &f_lo, &f_hi); - _mm_storeu_si128((__m128i *)(s - 0 * pitch), oq0); - - f_lo = filter_add2_sub2(&f_lo, &q7_lo, &q1_lo, &p6_lo, &q0_lo); - f_hi = filter_add2_sub2(&f_hi, &q7_hi, &q1_hi, &p6_hi, &q0_hi); - oq1 = filter16_mask(&flat2, &oq1, &f_lo, &f_hi); - _mm_storeu_si128((__m128i *)(s + 1 * pitch), oq1); - - f_lo = filter_add2_sub2(&f_lo, &q7_lo, &q2_lo, &p5_lo, &q1_lo); - f_hi = filter_add2_sub2(&f_hi, &q7_hi, &q2_hi, &p5_hi, &q1_hi); - oq2 = filter16_mask(&flat2, &oq2, &f_lo, &f_hi); - _mm_storeu_si128((__m128i *)(s + 2 * pitch), oq2); - - f_lo = filter_add2_sub2(&f_lo, &q7_lo, &q3_lo, &p4_lo, &q2_lo); - f_hi = filter_add2_sub2(&f_hi, &q7_hi, &q3_hi, &p4_hi, &q2_hi); - q3 = filter16_mask(&flat2, &q3, &f_lo, &f_hi); - _mm_storeu_si128((__m128i *)(s + 3 * pitch), q3); - - f_lo = filter_add2_sub2(&f_lo, &q7_lo, &q4_lo, &p3_lo, &q3_lo); - f_hi = filter_add2_sub2(&f_hi, &q7_hi, &q4_hi, &p3_hi, &q3_hi); - q4 = filter16_mask(&flat2, &q4, &f_lo, &f_hi); - _mm_storeu_si128((__m128i *)(s + 4 * pitch), q4); - - f_lo = filter_add2_sub2(&f_lo, &q7_lo, &q5_lo, &p2_lo, &q4_lo); - f_hi = filter_add2_sub2(&f_hi, &q7_hi, &q5_hi, &p2_hi, &q4_hi); - q5 = filter16_mask(&flat2, &q5, &f_lo, &f_hi); - _mm_storeu_si128((__m128i *)(s + 5 * pitch), q5); - - f_lo = filter_add2_sub2(&f_lo, &q7_lo, &q6_lo, &p1_lo, &q5_lo); - f_hi = filter_add2_sub2(&f_hi, &q7_hi, &q6_hi, &p1_hi, &q5_hi); - q6 = filter16_mask(&flat2, &q6, &f_lo, &f_hi); - _mm_storeu_si128((__m128i *)(s + 6 * pitch), q6); - } - // wide flat - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - } -} - -void vpx_lpf_horizontal_8_sse2(unsigned char *s, int pitch, - const unsigned char *blimit, - const unsigned char *limit, - const unsigned char *thresh) { - DECLARE_ALIGNED(16, unsigned char, flat_op2[16]); - DECLARE_ALIGNED(16, unsigned char, flat_op1[16]); - DECLARE_ALIGNED(16, unsigned char, flat_op0[16]); - DECLARE_ALIGNED(16, unsigned char, flat_oq2[16]); - DECLARE_ALIGNED(16, unsigned char, flat_oq1[16]); - DECLARE_ALIGNED(16, unsigned char, flat_oq0[16]); - const __m128i zero = _mm_setzero_si128(); - const __m128i blimit_v = _mm_load_si128((const __m128i *)blimit); - const __m128i limit_v = _mm_load_si128((const __m128i *)limit); - const __m128i thresh_v = _mm_load_si128((const __m128i *)thresh); - __m128i mask, hev, flat; - __m128i p3, p2, p1, p0, q0, q1, q2, q3; - __m128i q3p3, q2p2, q1p1, q0p0, p1q1, p0q0; - - q3p3 = _mm_unpacklo_epi64(_mm_loadl_epi64((__m128i *)(s - 4 * pitch)), - _mm_loadl_epi64((__m128i *)(s + 3 * pitch))); - q2p2 = _mm_unpacklo_epi64(_mm_loadl_epi64((__m128i *)(s - 3 * pitch)), - _mm_loadl_epi64((__m128i *)(s + 2 * pitch))); - q1p1 = _mm_unpacklo_epi64(_mm_loadl_epi64((__m128i *)(s - 2 * pitch)), - _mm_loadl_epi64((__m128i *)(s + 1 * pitch))); - q0p0 = _mm_unpacklo_epi64(_mm_loadl_epi64((__m128i *)(s - 1 * pitch)), - _mm_loadl_epi64((__m128i *)(s - 0 * pitch))); - p1q1 = _mm_shuffle_epi32(q1p1, 78); - p0q0 = _mm_shuffle_epi32(q0p0, 78); - - { - // filter_mask and hev_mask - const __m128i one = _mm_set1_epi8(1); - const __m128i fe = _mm_set1_epi8((int8_t)0xfe); - const __m128i ff = _mm_cmpeq_epi8(fe, fe); - __m128i abs_p1q1, abs_p0q0, abs_q1q0, abs_p1p0, work; - abs_p1p0 = abs_diff(q1p1, q0p0); - abs_q1q0 = _mm_srli_si128(abs_p1p0, 8); - - abs_p0q0 = abs_diff(q0p0, p0q0); - abs_p1q1 = abs_diff(q1p1, p1q1); - flat = _mm_max_epu8(abs_p1p0, abs_q1q0); - hev = _mm_subs_epu8(flat, thresh_v); - hev = _mm_xor_si128(_mm_cmpeq_epi8(hev, zero), ff); - - abs_p0q0 = _mm_adds_epu8(abs_p0q0, abs_p0q0); - abs_p1q1 = _mm_srli_epi16(_mm_and_si128(abs_p1q1, fe), 1); - mask = _mm_subs_epu8(_mm_adds_epu8(abs_p0q0, abs_p1q1), blimit_v); - mask = _mm_xor_si128(_mm_cmpeq_epi8(mask, zero), ff); - // mask |= (abs(p0 - q0) * 2 + abs(p1 - q1) / 2 > blimit) * -1; - mask = _mm_max_epu8(abs_p1p0, mask); - // mask |= (abs(p1 - p0) > limit) * -1; - // mask |= (abs(q1 - q0) > limit) * -1; - - work = _mm_max_epu8(abs_diff(q2p2, q1p1), abs_diff(q3p3, q2p2)); - mask = _mm_max_epu8(work, mask); - mask = _mm_max_epu8(mask, _mm_srli_si128(mask, 8)); - mask = _mm_subs_epu8(mask, limit_v); - mask = _mm_cmpeq_epi8(mask, zero); - - // flat_mask4 - - flat = _mm_max_epu8(abs_diff(q2p2, q0p0), abs_diff(q3p3, q0p0)); - flat = _mm_max_epu8(abs_p1p0, flat); - flat = _mm_max_epu8(flat, _mm_srli_si128(flat, 8)); - flat = _mm_subs_epu8(flat, one); - flat = _mm_cmpeq_epi8(flat, zero); - flat = _mm_and_si128(flat, mask); - } - - { - const __m128i four = _mm_set1_epi16(4); - unsigned char *src = s; - { - __m128i workp_a, workp_b, workp_shft; - p3 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(src - 4 * pitch)), - zero); - p2 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(src - 3 * pitch)), - zero); - p1 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(src - 2 * pitch)), - zero); - p0 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(src - 1 * pitch)), - zero); - q0 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(src - 0 * pitch)), - zero); - q1 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(src + 1 * pitch)), - zero); - q2 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(src + 2 * pitch)), - zero); - q3 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(src + 3 * pitch)), - zero); - - workp_a = _mm_add_epi16(_mm_add_epi16(p3, p3), _mm_add_epi16(p2, p1)); - workp_a = _mm_add_epi16(_mm_add_epi16(workp_a, four), p0); - workp_b = _mm_add_epi16(_mm_add_epi16(q0, p2), p3); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_storel_epi64((__m128i *)&flat_op2[0], - _mm_packus_epi16(workp_shft, workp_shft)); - - workp_b = _mm_add_epi16(_mm_add_epi16(q0, q1), p1); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_storel_epi64((__m128i *)&flat_op1[0], - _mm_packus_epi16(workp_shft, workp_shft)); - - workp_a = _mm_add_epi16(_mm_sub_epi16(workp_a, p3), q2); - workp_b = _mm_add_epi16(_mm_sub_epi16(workp_b, p1), p0); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_storel_epi64((__m128i *)&flat_op0[0], - _mm_packus_epi16(workp_shft, workp_shft)); - - workp_a = _mm_add_epi16(_mm_sub_epi16(workp_a, p3), q3); - workp_b = _mm_add_epi16(_mm_sub_epi16(workp_b, p0), q0); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_storel_epi64((__m128i *)&flat_oq0[0], - _mm_packus_epi16(workp_shft, workp_shft)); - - workp_a = _mm_add_epi16(_mm_sub_epi16(workp_a, p2), q3); - workp_b = _mm_add_epi16(_mm_sub_epi16(workp_b, q0), q1); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_storel_epi64((__m128i *)&flat_oq1[0], - _mm_packus_epi16(workp_shft, workp_shft)); - - workp_a = _mm_add_epi16(_mm_sub_epi16(workp_a, p1), q3); - workp_b = _mm_add_epi16(_mm_sub_epi16(workp_b, q1), q2); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_storel_epi64((__m128i *)&flat_oq2[0], - _mm_packus_epi16(workp_shft, workp_shft)); - } - } - // lp filter - { - const __m128i t4 = _mm_set1_epi8(4); - const __m128i t3 = _mm_set1_epi8(3); - const __m128i t80 = _mm_set1_epi8((int8_t)0x80); - const __m128i t1 = _mm_set1_epi8(0x1); - const __m128i ps1 = - _mm_xor_si128(_mm_loadl_epi64((__m128i *)(s - 2 * pitch)), t80); - const __m128i ps0 = - _mm_xor_si128(_mm_loadl_epi64((__m128i *)(s - 1 * pitch)), t80); - const __m128i qs0 = - _mm_xor_si128(_mm_loadl_epi64((__m128i *)(s + 0 * pitch)), t80); - const __m128i qs1 = - _mm_xor_si128(_mm_loadl_epi64((__m128i *)(s + 1 * pitch)), t80); - __m128i filt; - __m128i work_a; - __m128i filter1, filter2; - - filt = _mm_and_si128(_mm_subs_epi8(ps1, qs1), hev); - work_a = _mm_subs_epi8(qs0, ps0); - filt = _mm_adds_epi8(filt, work_a); - filt = _mm_adds_epi8(filt, work_a); - filt = _mm_adds_epi8(filt, work_a); - // (vpx_filter + 3 * (qs0 - ps0)) & mask - filt = _mm_and_si128(filt, mask); - - filter1 = _mm_adds_epi8(filt, t4); - filter2 = _mm_adds_epi8(filt, t3); - - // Filter1 >> 3 - filter1 = _mm_unpacklo_epi8(zero, filter1); - filter1 = _mm_srai_epi16(filter1, 11); - filter1 = _mm_packs_epi16(filter1, filter1); - - // Filter2 >> 3 - filter2 = _mm_unpacklo_epi8(zero, filter2); - filter2 = _mm_srai_epi16(filter2, 11); - filter2 = _mm_packs_epi16(filter2, zero); - - // filt >> 1 - filt = _mm_adds_epi8(filter1, t1); - filt = _mm_unpacklo_epi8(zero, filt); - filt = _mm_srai_epi16(filt, 9); - filt = _mm_packs_epi16(filt, zero); - - filt = _mm_andnot_si128(hev, filt); - - work_a = _mm_xor_si128(_mm_subs_epi8(qs0, filter1), t80); - q0 = _mm_loadl_epi64((__m128i *)flat_oq0); - work_a = _mm_andnot_si128(flat, work_a); - q0 = _mm_and_si128(flat, q0); - q0 = _mm_or_si128(work_a, q0); - - work_a = _mm_xor_si128(_mm_subs_epi8(qs1, filt), t80); - q1 = _mm_loadl_epi64((__m128i *)flat_oq1); - work_a = _mm_andnot_si128(flat, work_a); - q1 = _mm_and_si128(flat, q1); - q1 = _mm_or_si128(work_a, q1); - - work_a = _mm_loadu_si128((__m128i *)(s + 2 * pitch)); - q2 = _mm_loadl_epi64((__m128i *)flat_oq2); - work_a = _mm_andnot_si128(flat, work_a); - q2 = _mm_and_si128(flat, q2); - q2 = _mm_or_si128(work_a, q2); - - work_a = _mm_xor_si128(_mm_adds_epi8(ps0, filter2), t80); - p0 = _mm_loadl_epi64((__m128i *)flat_op0); - work_a = _mm_andnot_si128(flat, work_a); - p0 = _mm_and_si128(flat, p0); - p0 = _mm_or_si128(work_a, p0); - - work_a = _mm_xor_si128(_mm_adds_epi8(ps1, filt), t80); - p1 = _mm_loadl_epi64((__m128i *)flat_op1); - work_a = _mm_andnot_si128(flat, work_a); - p1 = _mm_and_si128(flat, p1); - p1 = _mm_or_si128(work_a, p1); - - work_a = _mm_loadu_si128((__m128i *)(s - 3 * pitch)); - p2 = _mm_loadl_epi64((__m128i *)flat_op2); - work_a = _mm_andnot_si128(flat, work_a); - p2 = _mm_and_si128(flat, p2); - p2 = _mm_or_si128(work_a, p2); - - _mm_storel_epi64((__m128i *)(s - 3 * pitch), p2); - _mm_storel_epi64((__m128i *)(s - 2 * pitch), p1); - _mm_storel_epi64((__m128i *)(s - 1 * pitch), p0); - _mm_storel_epi64((__m128i *)(s + 0 * pitch), q0); - _mm_storel_epi64((__m128i *)(s + 1 * pitch), q1); - _mm_storel_epi64((__m128i *)(s + 2 * pitch), q2); - } -} - -void vpx_lpf_horizontal_8_dual_sse2( - uint8_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, - const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1) { - DECLARE_ALIGNED(16, unsigned char, flat_op2[16]); - DECLARE_ALIGNED(16, unsigned char, flat_op1[16]); - DECLARE_ALIGNED(16, unsigned char, flat_op0[16]); - DECLARE_ALIGNED(16, unsigned char, flat_oq2[16]); - DECLARE_ALIGNED(16, unsigned char, flat_oq1[16]); - DECLARE_ALIGNED(16, unsigned char, flat_oq0[16]); - const __m128i zero = _mm_setzero_si128(); - const __m128i blimit = - _mm_unpacklo_epi64(_mm_load_si128((const __m128i *)blimit0), - _mm_load_si128((const __m128i *)blimit1)); - const __m128i limit = - _mm_unpacklo_epi64(_mm_load_si128((const __m128i *)limit0), - _mm_load_si128((const __m128i *)limit1)); - const __m128i thresh = - _mm_unpacklo_epi64(_mm_load_si128((const __m128i *)thresh0), - _mm_load_si128((const __m128i *)thresh1)); - - __m128i mask, hev, flat; - __m128i p3, p2, p1, p0, q0, q1, q2, q3; - - p3 = _mm_loadu_si128((__m128i *)(s - 4 * pitch)); - p2 = _mm_loadu_si128((__m128i *)(s - 3 * pitch)); - p1 = _mm_loadu_si128((__m128i *)(s - 2 * pitch)); - p0 = _mm_loadu_si128((__m128i *)(s - 1 * pitch)); - q0 = _mm_loadu_si128((__m128i *)(s - 0 * pitch)); - q1 = _mm_loadu_si128((__m128i *)(s + 1 * pitch)); - q2 = _mm_loadu_si128((__m128i *)(s + 2 * pitch)); - q3 = _mm_loadu_si128((__m128i *)(s + 3 * pitch)); - { - const __m128i abs_p1p0 = - _mm_or_si128(_mm_subs_epu8(p1, p0), _mm_subs_epu8(p0, p1)); - const __m128i abs_q1q0 = - _mm_or_si128(_mm_subs_epu8(q1, q0), _mm_subs_epu8(q0, q1)); - const __m128i one = _mm_set1_epi8(1); - const __m128i fe = _mm_set1_epi8((int8_t)0xfe); - const __m128i ff = _mm_cmpeq_epi8(abs_p1p0, abs_p1p0); - __m128i abs_p0q0 = - _mm_or_si128(_mm_subs_epu8(p0, q0), _mm_subs_epu8(q0, p0)); - __m128i abs_p1q1 = - _mm_or_si128(_mm_subs_epu8(p1, q1), _mm_subs_epu8(q1, p1)); - __m128i work; - - // filter_mask and hev_mask - flat = _mm_max_epu8(abs_p1p0, abs_q1q0); - hev = _mm_subs_epu8(flat, thresh); - hev = _mm_xor_si128(_mm_cmpeq_epi8(hev, zero), ff); - - abs_p0q0 = _mm_adds_epu8(abs_p0q0, abs_p0q0); - abs_p1q1 = _mm_srli_epi16(_mm_and_si128(abs_p1q1, fe), 1); - mask = _mm_subs_epu8(_mm_adds_epu8(abs_p0q0, abs_p1q1), blimit); - mask = _mm_xor_si128(_mm_cmpeq_epi8(mask, zero), ff); - // mask |= (abs(p0 - q0) * 2 + abs(p1 - q1) / 2 > blimit) * -1; - mask = _mm_max_epu8(flat, mask); - // mask |= (abs(p1 - p0) > limit) * -1; - // mask |= (abs(q1 - q0) > limit) * -1; - work = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(p2, p1), _mm_subs_epu8(p1, p2)), - _mm_or_si128(_mm_subs_epu8(p3, p2), _mm_subs_epu8(p2, p3))); - mask = _mm_max_epu8(work, mask); - work = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(q2, q1), _mm_subs_epu8(q1, q2)), - _mm_or_si128(_mm_subs_epu8(q3, q2), _mm_subs_epu8(q2, q3))); - mask = _mm_max_epu8(work, mask); - mask = _mm_subs_epu8(mask, limit); - mask = _mm_cmpeq_epi8(mask, zero); - - // flat_mask4 - work = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(p2, p0), _mm_subs_epu8(p0, p2)), - _mm_or_si128(_mm_subs_epu8(q2, q0), _mm_subs_epu8(q0, q2))); - flat = _mm_max_epu8(work, flat); - work = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(p3, p0), _mm_subs_epu8(p0, p3)), - _mm_or_si128(_mm_subs_epu8(q3, q0), _mm_subs_epu8(q0, q3))); - flat = _mm_max_epu8(work, flat); - flat = _mm_subs_epu8(flat, one); - flat = _mm_cmpeq_epi8(flat, zero); - flat = _mm_and_si128(flat, mask); - } - { - const __m128i four = _mm_set1_epi16(4); - unsigned char *src = s; - int i = 0; - - do { - __m128i workp_a, workp_b, workp_shft; - p3 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(src - 4 * pitch)), - zero); - p2 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(src - 3 * pitch)), - zero); - p1 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(src - 2 * pitch)), - zero); - p0 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(src - 1 * pitch)), - zero); - q0 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(src - 0 * pitch)), - zero); - q1 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(src + 1 * pitch)), - zero); - q2 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(src + 2 * pitch)), - zero); - q3 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i *)(src + 3 * pitch)), - zero); - - workp_a = _mm_add_epi16(_mm_add_epi16(p3, p3), _mm_add_epi16(p2, p1)); - workp_a = _mm_add_epi16(_mm_add_epi16(workp_a, four), p0); - workp_b = _mm_add_epi16(_mm_add_epi16(q0, p2), p3); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_storel_epi64((__m128i *)&flat_op2[i * 8], - _mm_packus_epi16(workp_shft, workp_shft)); - - workp_b = _mm_add_epi16(_mm_add_epi16(q0, q1), p1); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_storel_epi64((__m128i *)&flat_op1[i * 8], - _mm_packus_epi16(workp_shft, workp_shft)); - - workp_a = _mm_add_epi16(_mm_sub_epi16(workp_a, p3), q2); - workp_b = _mm_add_epi16(_mm_sub_epi16(workp_b, p1), p0); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_storel_epi64((__m128i *)&flat_op0[i * 8], - _mm_packus_epi16(workp_shft, workp_shft)); - - workp_a = _mm_add_epi16(_mm_sub_epi16(workp_a, p3), q3); - workp_b = _mm_add_epi16(_mm_sub_epi16(workp_b, p0), q0); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_storel_epi64((__m128i *)&flat_oq0[i * 8], - _mm_packus_epi16(workp_shft, workp_shft)); - - workp_a = _mm_add_epi16(_mm_sub_epi16(workp_a, p2), q3); - workp_b = _mm_add_epi16(_mm_sub_epi16(workp_b, q0), q1); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_storel_epi64((__m128i *)&flat_oq1[i * 8], - _mm_packus_epi16(workp_shft, workp_shft)); - - workp_a = _mm_add_epi16(_mm_sub_epi16(workp_a, p1), q3); - workp_b = _mm_add_epi16(_mm_sub_epi16(workp_b, q1), q2); - workp_shft = _mm_srli_epi16(_mm_add_epi16(workp_a, workp_b), 3); - _mm_storel_epi64((__m128i *)&flat_oq2[i * 8], - _mm_packus_epi16(workp_shft, workp_shft)); - - src += 8; - } while (++i < 2); - } - // lp filter - { - const __m128i t4 = _mm_set1_epi8(4); - const __m128i t3 = _mm_set1_epi8(3); - const __m128i t80 = _mm_set1_epi8((int8_t)0x80); - const __m128i te0 = _mm_set1_epi8((int8_t)0xe0); - const __m128i t1f = _mm_set1_epi8(0x1f); - const __m128i t1 = _mm_set1_epi8(0x1); - const __m128i t7f = _mm_set1_epi8(0x7f); - - const __m128i ps1 = - _mm_xor_si128(_mm_loadu_si128((__m128i *)(s - 2 * pitch)), t80); - const __m128i ps0 = - _mm_xor_si128(_mm_loadu_si128((__m128i *)(s - 1 * pitch)), t80); - const __m128i qs0 = - _mm_xor_si128(_mm_loadu_si128((__m128i *)(s + 0 * pitch)), t80); - const __m128i qs1 = - _mm_xor_si128(_mm_loadu_si128((__m128i *)(s + 1 * pitch)), t80); - __m128i filt; - __m128i work_a; - __m128i filter1, filter2; - - filt = _mm_and_si128(_mm_subs_epi8(ps1, qs1), hev); - work_a = _mm_subs_epi8(qs0, ps0); - filt = _mm_adds_epi8(filt, work_a); - filt = _mm_adds_epi8(filt, work_a); - filt = _mm_adds_epi8(filt, work_a); - // (vpx_filter + 3 * (qs0 - ps0)) & mask - filt = _mm_and_si128(filt, mask); - - filter1 = _mm_adds_epi8(filt, t4); - filter2 = _mm_adds_epi8(filt, t3); - - // Filter1 >> 3 - work_a = _mm_cmpgt_epi8(zero, filter1); - filter1 = _mm_srli_epi16(filter1, 3); - work_a = _mm_and_si128(work_a, te0); - filter1 = _mm_and_si128(filter1, t1f); - filter1 = _mm_or_si128(filter1, work_a); - - // Filter2 >> 3 - work_a = _mm_cmpgt_epi8(zero, filter2); - filter2 = _mm_srli_epi16(filter2, 3); - work_a = _mm_and_si128(work_a, te0); - filter2 = _mm_and_si128(filter2, t1f); - filter2 = _mm_or_si128(filter2, work_a); - - // filt >> 1 - filt = _mm_adds_epi8(filter1, t1); - work_a = _mm_cmpgt_epi8(zero, filt); - filt = _mm_srli_epi16(filt, 1); - work_a = _mm_and_si128(work_a, t80); - filt = _mm_and_si128(filt, t7f); - filt = _mm_or_si128(filt, work_a); - - filt = _mm_andnot_si128(hev, filt); - - work_a = _mm_xor_si128(_mm_subs_epi8(qs0, filter1), t80); - q0 = _mm_load_si128((__m128i *)flat_oq0); - work_a = _mm_andnot_si128(flat, work_a); - q0 = _mm_and_si128(flat, q0); - q0 = _mm_or_si128(work_a, q0); - - work_a = _mm_xor_si128(_mm_subs_epi8(qs1, filt), t80); - q1 = _mm_load_si128((__m128i *)flat_oq1); - work_a = _mm_andnot_si128(flat, work_a); - q1 = _mm_and_si128(flat, q1); - q1 = _mm_or_si128(work_a, q1); - - work_a = _mm_loadu_si128((__m128i *)(s + 2 * pitch)); - q2 = _mm_load_si128((__m128i *)flat_oq2); - work_a = _mm_andnot_si128(flat, work_a); - q2 = _mm_and_si128(flat, q2); - q2 = _mm_or_si128(work_a, q2); - - work_a = _mm_xor_si128(_mm_adds_epi8(ps0, filter2), t80); - p0 = _mm_load_si128((__m128i *)flat_op0); - work_a = _mm_andnot_si128(flat, work_a); - p0 = _mm_and_si128(flat, p0); - p0 = _mm_or_si128(work_a, p0); - - work_a = _mm_xor_si128(_mm_adds_epi8(ps1, filt), t80); - p1 = _mm_load_si128((__m128i *)flat_op1); - work_a = _mm_andnot_si128(flat, work_a); - p1 = _mm_and_si128(flat, p1); - p1 = _mm_or_si128(work_a, p1); - - work_a = _mm_loadu_si128((__m128i *)(s - 3 * pitch)); - p2 = _mm_load_si128((__m128i *)flat_op2); - work_a = _mm_andnot_si128(flat, work_a); - p2 = _mm_and_si128(flat, p2); - p2 = _mm_or_si128(work_a, p2); - - _mm_storeu_si128((__m128i *)(s - 3 * pitch), p2); - _mm_storeu_si128((__m128i *)(s - 2 * pitch), p1); - _mm_storeu_si128((__m128i *)(s - 1 * pitch), p0); - _mm_storeu_si128((__m128i *)(s + 0 * pitch), q0); - _mm_storeu_si128((__m128i *)(s + 1 * pitch), q1); - _mm_storeu_si128((__m128i *)(s + 2 * pitch), q2); - } -} - -void vpx_lpf_horizontal_4_dual_sse2(unsigned char *s, int pitch, - const unsigned char *blimit0, - const unsigned char *limit0, - const unsigned char *thresh0, - const unsigned char *blimit1, - const unsigned char *limit1, - const unsigned char *thresh1) { - const __m128i blimit = - _mm_unpacklo_epi64(_mm_load_si128((const __m128i *)blimit0), - _mm_load_si128((const __m128i *)blimit1)); - const __m128i limit = - _mm_unpacklo_epi64(_mm_load_si128((const __m128i *)limit0), - _mm_load_si128((const __m128i *)limit1)); - const __m128i thresh = - _mm_unpacklo_epi64(_mm_load_si128((const __m128i *)thresh0), - _mm_load_si128((const __m128i *)thresh1)); - const __m128i zero = _mm_setzero_si128(); - __m128i p3, p2, p1, p0, q0, q1, q2, q3; - __m128i mask, hev, flat; - - p3 = _mm_loadu_si128((__m128i *)(s - 4 * pitch)); - p2 = _mm_loadu_si128((__m128i *)(s - 3 * pitch)); - p1 = _mm_loadu_si128((__m128i *)(s - 2 * pitch)); - p0 = _mm_loadu_si128((__m128i *)(s - 1 * pitch)); - q0 = _mm_loadu_si128((__m128i *)(s - 0 * pitch)); - q1 = _mm_loadu_si128((__m128i *)(s + 1 * pitch)); - q2 = _mm_loadu_si128((__m128i *)(s + 2 * pitch)); - q3 = _mm_loadu_si128((__m128i *)(s + 3 * pitch)); - - // filter_mask and hev_mask - { - const __m128i abs_p1p0 = - _mm_or_si128(_mm_subs_epu8(p1, p0), _mm_subs_epu8(p0, p1)); - const __m128i abs_q1q0 = - _mm_or_si128(_mm_subs_epu8(q1, q0), _mm_subs_epu8(q0, q1)); - const __m128i fe = _mm_set1_epi8((int8_t)0xfe); - const __m128i ff = _mm_cmpeq_epi8(abs_p1p0, abs_p1p0); - __m128i abs_p0q0 = - _mm_or_si128(_mm_subs_epu8(p0, q0), _mm_subs_epu8(q0, p0)); - __m128i abs_p1q1 = - _mm_or_si128(_mm_subs_epu8(p1, q1), _mm_subs_epu8(q1, p1)); - __m128i work; - - flat = _mm_max_epu8(abs_p1p0, abs_q1q0); - hev = _mm_subs_epu8(flat, thresh); - hev = _mm_xor_si128(_mm_cmpeq_epi8(hev, zero), ff); - - abs_p0q0 = _mm_adds_epu8(abs_p0q0, abs_p0q0); - abs_p1q1 = _mm_srli_epi16(_mm_and_si128(abs_p1q1, fe), 1); - mask = _mm_subs_epu8(_mm_adds_epu8(abs_p0q0, abs_p1q1), blimit); - mask = _mm_xor_si128(_mm_cmpeq_epi8(mask, zero), ff); - // mask |= (abs(p0 - q0) * 2 + abs(p1 - q1) / 2 > blimit) * -1; - mask = _mm_max_epu8(flat, mask); - // mask |= (abs(p1 - p0) > limit) * -1; - // mask |= (abs(q1 - q0) > limit) * -1; - work = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(p2, p1), _mm_subs_epu8(p1, p2)), - _mm_or_si128(_mm_subs_epu8(p3, p2), _mm_subs_epu8(p2, p3))); - mask = _mm_max_epu8(work, mask); - work = _mm_max_epu8( - _mm_or_si128(_mm_subs_epu8(q2, q1), _mm_subs_epu8(q1, q2)), - _mm_or_si128(_mm_subs_epu8(q3, q2), _mm_subs_epu8(q2, q3))); - mask = _mm_max_epu8(work, mask); - mask = _mm_subs_epu8(mask, limit); - mask = _mm_cmpeq_epi8(mask, zero); - } - - // filter4 - { - const __m128i t4 = _mm_set1_epi8(4); - const __m128i t3 = _mm_set1_epi8(3); - const __m128i t80 = _mm_set1_epi8((int8_t)0x80); - const __m128i te0 = _mm_set1_epi8((int8_t)0xe0); - const __m128i t1f = _mm_set1_epi8(0x1f); - const __m128i t1 = _mm_set1_epi8(0x1); - const __m128i t7f = _mm_set1_epi8(0x7f); - - const __m128i ps1 = - _mm_xor_si128(_mm_loadu_si128((__m128i *)(s - 2 * pitch)), t80); - const __m128i ps0 = - _mm_xor_si128(_mm_loadu_si128((__m128i *)(s - 1 * pitch)), t80); - const __m128i qs0 = - _mm_xor_si128(_mm_loadu_si128((__m128i *)(s + 0 * pitch)), t80); - const __m128i qs1 = - _mm_xor_si128(_mm_loadu_si128((__m128i *)(s + 1 * pitch)), t80); - __m128i filt; - __m128i work_a; - __m128i filter1, filter2; - - filt = _mm_and_si128(_mm_subs_epi8(ps1, qs1), hev); - work_a = _mm_subs_epi8(qs0, ps0); - filt = _mm_adds_epi8(filt, work_a); - filt = _mm_adds_epi8(filt, work_a); - filt = _mm_adds_epi8(filt, work_a); - // (vpx_filter + 3 * (qs0 - ps0)) & mask - filt = _mm_and_si128(filt, mask); - - filter1 = _mm_adds_epi8(filt, t4); - filter2 = _mm_adds_epi8(filt, t3); - - // Filter1 >> 3 - work_a = _mm_cmpgt_epi8(zero, filter1); - filter1 = _mm_srli_epi16(filter1, 3); - work_a = _mm_and_si128(work_a, te0); - filter1 = _mm_and_si128(filter1, t1f); - filter1 = _mm_or_si128(filter1, work_a); - - // Filter2 >> 3 - work_a = _mm_cmpgt_epi8(zero, filter2); - filter2 = _mm_srli_epi16(filter2, 3); - work_a = _mm_and_si128(work_a, te0); - filter2 = _mm_and_si128(filter2, t1f); - filter2 = _mm_or_si128(filter2, work_a); - - // filt >> 1 - filt = _mm_adds_epi8(filter1, t1); - work_a = _mm_cmpgt_epi8(zero, filt); - filt = _mm_srli_epi16(filt, 1); - work_a = _mm_and_si128(work_a, t80); - filt = _mm_and_si128(filt, t7f); - filt = _mm_or_si128(filt, work_a); - - filt = _mm_andnot_si128(hev, filt); - - q0 = _mm_xor_si128(_mm_subs_epi8(qs0, filter1), t80); - q1 = _mm_xor_si128(_mm_subs_epi8(qs1, filt), t80); - p0 = _mm_xor_si128(_mm_adds_epi8(ps0, filter2), t80); - p1 = _mm_xor_si128(_mm_adds_epi8(ps1, filt), t80); - - _mm_storeu_si128((__m128i *)(s - 2 * pitch), p1); - _mm_storeu_si128((__m128i *)(s - 1 * pitch), p0); - _mm_storeu_si128((__m128i *)(s + 0 * pitch), q0); - _mm_storeu_si128((__m128i *)(s + 1 * pitch), q1); - } -} - -static INLINE void transpose8x16(unsigned char *in0, unsigned char *in1, - int in_p, unsigned char *out, int out_p) { - __m128i x0, x1, x2, x3, x4, x5, x6, x7; - __m128i x8, x9, x10, x11, x12, x13, x14, x15; - - // 2-way interleave w/hoisting of unpacks - x0 = _mm_loadl_epi64((__m128i *)in0); // 1 - x1 = _mm_loadl_epi64((__m128i *)(in0 + in_p)); // 3 - x0 = _mm_unpacklo_epi8(x0, x1); // 1 - - x2 = _mm_loadl_epi64((__m128i *)(in0 + 2 * in_p)); // 5 - x3 = _mm_loadl_epi64((__m128i *)(in0 + 3 * in_p)); // 7 - x1 = _mm_unpacklo_epi8(x2, x3); // 2 - - x4 = _mm_loadl_epi64((__m128i *)(in0 + 4 * in_p)); // 9 - x5 = _mm_loadl_epi64((__m128i *)(in0 + 5 * in_p)); // 11 - x2 = _mm_unpacklo_epi8(x4, x5); // 3 - - x6 = _mm_loadl_epi64((__m128i *)(in0 + 6 * in_p)); // 13 - x7 = _mm_loadl_epi64((__m128i *)(in0 + 7 * in_p)); // 15 - x3 = _mm_unpacklo_epi8(x6, x7); // 4 - x4 = _mm_unpacklo_epi16(x0, x1); // 9 - - x8 = _mm_loadl_epi64((__m128i *)in1); // 2 - x9 = _mm_loadl_epi64((__m128i *)(in1 + in_p)); // 4 - x8 = _mm_unpacklo_epi8(x8, x9); // 5 - x5 = _mm_unpacklo_epi16(x2, x3); // 10 - - x10 = _mm_loadl_epi64((__m128i *)(in1 + 2 * in_p)); // 6 - x11 = _mm_loadl_epi64((__m128i *)(in1 + 3 * in_p)); // 8 - x9 = _mm_unpacklo_epi8(x10, x11); // 6 - - x12 = _mm_loadl_epi64((__m128i *)(in1 + 4 * in_p)); // 10 - x13 = _mm_loadl_epi64((__m128i *)(in1 + 5 * in_p)); // 12 - x10 = _mm_unpacklo_epi8(x12, x13); // 7 - x12 = _mm_unpacklo_epi16(x8, x9); // 11 - - x14 = _mm_loadl_epi64((__m128i *)(in1 + 6 * in_p)); // 14 - x15 = _mm_loadl_epi64((__m128i *)(in1 + 7 * in_p)); // 16 - x11 = _mm_unpacklo_epi8(x14, x15); // 8 - x13 = _mm_unpacklo_epi16(x10, x11); // 12 - - x6 = _mm_unpacklo_epi32(x4, x5); // 13 - x7 = _mm_unpackhi_epi32(x4, x5); // 14 - x14 = _mm_unpacklo_epi32(x12, x13); // 15 - x15 = _mm_unpackhi_epi32(x12, x13); // 16 - - // Store first 4-line result - _mm_storeu_si128((__m128i *)out, _mm_unpacklo_epi64(x6, x14)); - _mm_storeu_si128((__m128i *)(out + out_p), _mm_unpackhi_epi64(x6, x14)); - _mm_storeu_si128((__m128i *)(out + 2 * out_p), _mm_unpacklo_epi64(x7, x15)); - _mm_storeu_si128((__m128i *)(out + 3 * out_p), _mm_unpackhi_epi64(x7, x15)); - - x4 = _mm_unpackhi_epi16(x0, x1); - x5 = _mm_unpackhi_epi16(x2, x3); - x12 = _mm_unpackhi_epi16(x8, x9); - x13 = _mm_unpackhi_epi16(x10, x11); - - x6 = _mm_unpacklo_epi32(x4, x5); - x7 = _mm_unpackhi_epi32(x4, x5); - x14 = _mm_unpacklo_epi32(x12, x13); - x15 = _mm_unpackhi_epi32(x12, x13); - - // Store second 4-line result - _mm_storeu_si128((__m128i *)(out + 4 * out_p), _mm_unpacklo_epi64(x6, x14)); - _mm_storeu_si128((__m128i *)(out + 5 * out_p), _mm_unpackhi_epi64(x6, x14)); - _mm_storeu_si128((__m128i *)(out + 6 * out_p), _mm_unpacklo_epi64(x7, x15)); - _mm_storeu_si128((__m128i *)(out + 7 * out_p), _mm_unpackhi_epi64(x7, x15)); -} - -static INLINE void transpose(unsigned char *src[], int in_p, - unsigned char *dst[], int out_p, - int num_8x8_to_transpose) { - int idx8x8 = 0; - __m128i x0, x1, x2, x3, x4, x5, x6, x7; - do { - unsigned char *in = src[idx8x8]; - unsigned char *out = dst[idx8x8]; - - x0 = - _mm_loadl_epi64((__m128i *)(in + 0 * in_p)); // 00 01 02 03 04 05 06 07 - x1 = - _mm_loadl_epi64((__m128i *)(in + 1 * in_p)); // 10 11 12 13 14 15 16 17 - // 00 10 01 11 02 12 03 13 04 14 05 15 06 16 07 17 - x0 = _mm_unpacklo_epi8(x0, x1); - - x2 = - _mm_loadl_epi64((__m128i *)(in + 2 * in_p)); // 20 21 22 23 24 25 26 27 - x3 = - _mm_loadl_epi64((__m128i *)(in + 3 * in_p)); // 30 31 32 33 34 35 36 37 - // 20 30 21 31 22 32 23 33 24 34 25 35 26 36 27 37 - x1 = _mm_unpacklo_epi8(x2, x3); - - x4 = - _mm_loadl_epi64((__m128i *)(in + 4 * in_p)); // 40 41 42 43 44 45 46 47 - x5 = - _mm_loadl_epi64((__m128i *)(in + 5 * in_p)); // 50 51 52 53 54 55 56 57 - // 40 50 41 51 42 52 43 53 44 54 45 55 46 56 47 57 - x2 = _mm_unpacklo_epi8(x4, x5); - - x6 = - _mm_loadl_epi64((__m128i *)(in + 6 * in_p)); // 60 61 62 63 64 65 66 67 - x7 = - _mm_loadl_epi64((__m128i *)(in + 7 * in_p)); // 70 71 72 73 74 75 76 77 - // 60 70 61 71 62 72 63 73 64 74 65 75 66 76 67 77 - x3 = _mm_unpacklo_epi8(x6, x7); - - // 00 10 20 30 01 11 21 31 02 12 22 32 03 13 23 33 - x4 = _mm_unpacklo_epi16(x0, x1); - // 40 50 60 70 41 51 61 71 42 52 62 72 43 53 63 73 - x5 = _mm_unpacklo_epi16(x2, x3); - // 00 10 20 30 40 50 60 70 01 11 21 31 41 51 61 71 - x6 = _mm_unpacklo_epi32(x4, x5); - mm_storelu(out + 0 * out_p, x6); // 00 10 20 30 40 50 60 70 - mm_storehu(out + 1 * out_p, x6); // 01 11 21 31 41 51 61 71 - // 02 12 22 32 42 52 62 72 03 13 23 33 43 53 63 73 - x7 = _mm_unpackhi_epi32(x4, x5); - mm_storelu(out + 2 * out_p, x7); // 02 12 22 32 42 52 62 72 - mm_storehu(out + 3 * out_p, x7); // 03 13 23 33 43 53 63 73 - - // 04 14 24 34 05 15 25 35 06 16 26 36 07 17 27 37 - x4 = _mm_unpackhi_epi16(x0, x1); - // 44 54 64 74 45 55 65 75 46 56 66 76 47 57 67 77 - x5 = _mm_unpackhi_epi16(x2, x3); - // 04 14 24 34 44 54 64 74 05 15 25 35 45 55 65 75 - x6 = _mm_unpacklo_epi32(x4, x5); - mm_storelu(out + 4 * out_p, x6); // 04 14 24 34 44 54 64 74 - mm_storehu(out + 5 * out_p, x6); // 05 15 25 35 45 55 65 75 - // 06 16 26 36 46 56 66 76 07 17 27 37 47 57 67 77 - x7 = _mm_unpackhi_epi32(x4, x5); - - mm_storelu(out + 6 * out_p, x7); // 06 16 26 36 46 56 66 76 - mm_storehu(out + 7 * out_p, x7); // 07 17 27 37 47 57 67 77 - } while (++idx8x8 < num_8x8_to_transpose); -} - -void vpx_lpf_vertical_4_dual_sse2(uint8_t *s, int pitch, const uint8_t *blimit0, - const uint8_t *limit0, const uint8_t *thresh0, - const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1) { - DECLARE_ALIGNED(16, unsigned char, t_dst[16 * 8]); - unsigned char *src[2]; - unsigned char *dst[2]; - - // Transpose 8x16 - transpose8x16(s - 4, s - 4 + pitch * 8, pitch, t_dst, 16); - - // Loop filtering - vpx_lpf_horizontal_4_dual(t_dst + 4 * 16, 16, blimit0, limit0, thresh0, - blimit1, limit1, thresh1); - src[0] = t_dst; - src[1] = t_dst + 8; - dst[0] = s - 4; - dst[1] = s - 4 + pitch * 8; - - // Transpose back - transpose(src, 16, dst, pitch, 2); -} - -void vpx_lpf_vertical_8_sse2(unsigned char *s, int pitch, - const unsigned char *blimit, - const unsigned char *limit, - const unsigned char *thresh) { - DECLARE_ALIGNED(8, unsigned char, t_dst[8 * 8]); - unsigned char *src[1]; - unsigned char *dst[1]; - - // Transpose 8x8 - src[0] = s - 4; - dst[0] = t_dst; - - transpose(src, pitch, dst, 8, 1); - - // Loop filtering - vpx_lpf_horizontal_8(t_dst + 4 * 8, 8, blimit, limit, thresh); - - src[0] = t_dst; - dst[0] = s - 4; - - // Transpose back - transpose(src, 8, dst, pitch, 1); -} - -void vpx_lpf_vertical_8_dual_sse2(uint8_t *s, int pitch, const uint8_t *blimit0, - const uint8_t *limit0, const uint8_t *thresh0, - const uint8_t *blimit1, const uint8_t *limit1, - const uint8_t *thresh1) { - DECLARE_ALIGNED(16, unsigned char, t_dst[16 * 8]); - unsigned char *src[2]; - unsigned char *dst[2]; - - // Transpose 8x16 - transpose8x16(s - 4, s - 4 + pitch * 8, pitch, t_dst, 16); - - // Loop filtering - vpx_lpf_horizontal_8_dual(t_dst + 4 * 16, 16, blimit0, limit0, thresh0, - blimit1, limit1, thresh1); - src[0] = t_dst; - src[1] = t_dst + 8; - - dst[0] = s - 4; - dst[1] = s - 4 + pitch * 8; - - // Transpose back - transpose(src, 16, dst, pitch, 2); -} - -void vpx_lpf_vertical_16_sse2(unsigned char *s, int pitch, - const unsigned char *blimit, - const unsigned char *limit, - const unsigned char *thresh) { - DECLARE_ALIGNED(8, unsigned char, t_dst[8 * 16]); - unsigned char *src[2]; - unsigned char *dst[2]; - - src[0] = s - 8; - src[1] = s; - dst[0] = t_dst; - dst[1] = t_dst + 8 * 8; - - // Transpose 16x8 - transpose(src, pitch, dst, 8, 2); - - // Loop filtering - vpx_lpf_horizontal_16(t_dst + 8 * 8, 8, blimit, limit, thresh); - - src[0] = t_dst; - src[1] = t_dst + 8 * 8; - dst[0] = s - 8; - dst[1] = s; - - // Transpose back - transpose(src, 8, dst, pitch, 2); -} - -void vpx_lpf_vertical_16_dual_sse2(unsigned char *s, int pitch, - const uint8_t *blimit, const uint8_t *limit, - const uint8_t *thresh) { - DECLARE_ALIGNED(16, unsigned char, t_dst[256]); - - // Transpose 16x16 - transpose8x16(s - 8, s - 8 + 8 * pitch, pitch, t_dst, 16); - transpose8x16(s, s + 8 * pitch, pitch, t_dst + 8 * 16, 16); - - // Loop filtering - vpx_lpf_horizontal_16_dual(t_dst + 8 * 16, 16, blimit, limit, thresh); - - // Transpose back - transpose8x16(t_dst, t_dst + 8 * 16, 16, s - 8, pitch); - transpose8x16(t_dst + 8, t_dst + 8 + 8 * 16, 16, s - 8 + 8 * pitch, pitch); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/mem_sse2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/mem_sse2.h deleted file mode 100644 index 031f361a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/mem_sse2.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_X86_MEM_SSE2_H_ -#define VPX_VPX_DSP_X86_MEM_SSE2_H_ - -#include // SSE2 -#include - -#include "./vpx_config.h" - -static INLINE void storeu_int32(void *dst, int32_t v) { - memcpy(dst, &v, sizeof(v)); -} - -static INLINE int32_t loadu_int32(const void *src) { - int32_t v; - memcpy(&v, src, sizeof(v)); - return v; -} - -static INLINE __m128i load_unaligned_u32(const void *a) { - int val; - memcpy(&val, a, sizeof(val)); - return _mm_cvtsi32_si128(val); -} - -static INLINE void store_unaligned_u32(void *const a, const __m128i v) { - const int val = _mm_cvtsi128_si32(v); - memcpy(a, &val, sizeof(val)); -} - -#define mm_storelu(dst, v) memcpy((dst), (const char *)&(v), 8) -#define mm_storehu(dst, v) memcpy((dst), (const char *)&(v) + 8, 8) - -static INLINE __m128i loadh_epi64(const __m128i s, const void *const src) { - return _mm_castps_si128( - _mm_loadh_pi(_mm_castsi128_ps(s), (const __m64 *)src)); -} - -static INLINE void load_8bit_4x4(const uint8_t *const s, const ptrdiff_t stride, - __m128i *const d) { - d[0] = _mm_cvtsi32_si128(*(const int *)(s + 0 * stride)); - d[1] = _mm_cvtsi32_si128(*(const int *)(s + 1 * stride)); - d[2] = _mm_cvtsi32_si128(*(const int *)(s + 2 * stride)); - d[3] = _mm_cvtsi32_si128(*(const int *)(s + 3 * stride)); -} - -static INLINE void load_8bit_4x8(const uint8_t *const s, const ptrdiff_t stride, - __m128i *const d) { - load_8bit_4x4(s + 0 * stride, stride, &d[0]); - load_8bit_4x4(s + 4 * stride, stride, &d[4]); -} - -static INLINE void load_8bit_8x4(const uint8_t *const s, const ptrdiff_t stride, - __m128i *const d) { - d[0] = _mm_loadl_epi64((const __m128i *)(s + 0 * stride)); - d[1] = _mm_loadl_epi64((const __m128i *)(s + 1 * stride)); - d[2] = _mm_loadl_epi64((const __m128i *)(s + 2 * stride)); - d[3] = _mm_loadl_epi64((const __m128i *)(s + 3 * stride)); -} - -static INLINE void load_8bit_8x8(const uint8_t *const s, const ptrdiff_t stride, - __m128i *const d) { - load_8bit_8x4(s + 0 * stride, stride, &d[0]); - load_8bit_8x4(s + 4 * stride, stride, &d[4]); -} - -static INLINE void load_8bit_16x8(const uint8_t *const s, - const ptrdiff_t stride, __m128i *const d) { - d[0] = _mm_load_si128((const __m128i *)(s + 0 * stride)); - d[1] = _mm_load_si128((const __m128i *)(s + 1 * stride)); - d[2] = _mm_load_si128((const __m128i *)(s + 2 * stride)); - d[3] = _mm_load_si128((const __m128i *)(s + 3 * stride)); - d[4] = _mm_load_si128((const __m128i *)(s + 4 * stride)); - d[5] = _mm_load_si128((const __m128i *)(s + 5 * stride)); - d[6] = _mm_load_si128((const __m128i *)(s + 6 * stride)); - d[7] = _mm_load_si128((const __m128i *)(s + 7 * stride)); -} - -static INLINE void loadu_8bit_16x4(const uint8_t *const s, - const ptrdiff_t stride, __m128i *const d) { - d[0] = _mm_loadu_si128((const __m128i *)(s + 0 * stride)); - d[1] = _mm_loadu_si128((const __m128i *)(s + 1 * stride)); - d[2] = _mm_loadu_si128((const __m128i *)(s + 2 * stride)); - d[3] = _mm_loadu_si128((const __m128i *)(s + 3 * stride)); -} - -static INLINE void loadu_8bit_16x8(const uint8_t *const s, - const ptrdiff_t stride, __m128i *const d) { - loadu_8bit_16x4(s + 0 * stride, stride, &d[0]); - loadu_8bit_16x4(s + 4 * stride, stride, &d[4]); -} - -static INLINE void _mm_storeh_epi64(__m128i *const d, const __m128i s) { - _mm_storeh_pi((__m64 *)d, _mm_castsi128_ps(s)); -} - -static INLINE void store_8bit_4x4(const __m128i *const s, uint8_t *const d, - const ptrdiff_t stride) { - *(int *)(d + 0 * stride) = _mm_cvtsi128_si32(s[0]); - *(int *)(d + 1 * stride) = _mm_cvtsi128_si32(s[1]); - *(int *)(d + 2 * stride) = _mm_cvtsi128_si32(s[2]); - *(int *)(d + 3 * stride) = _mm_cvtsi128_si32(s[3]); -} - -static INLINE void store_8bit_4x4_sse2(const __m128i s, uint8_t *const d, - const ptrdiff_t stride) { - __m128i ss[4]; - - ss[0] = s; - ss[1] = _mm_srli_si128(s, 4); - ss[2] = _mm_srli_si128(s, 8); - ss[3] = _mm_srli_si128(s, 12); - store_8bit_4x4(ss, d, stride); -} - -static INLINE void store_8bit_8x4_from_16x2(const __m128i *const s, - uint8_t *const d, - const ptrdiff_t stride) { - _mm_storel_epi64((__m128i *)(d + 0 * stride), s[0]); - _mm_storeh_epi64((__m128i *)(d + 1 * stride), s[0]); - _mm_storel_epi64((__m128i *)(d + 2 * stride), s[1]); - _mm_storeh_epi64((__m128i *)(d + 3 * stride), s[1]); -} - -static INLINE void store_8bit_8x8(const __m128i *const s, uint8_t *const d, - const ptrdiff_t stride) { - _mm_storel_epi64((__m128i *)(d + 0 * stride), s[0]); - _mm_storel_epi64((__m128i *)(d + 1 * stride), s[1]); - _mm_storel_epi64((__m128i *)(d + 2 * stride), s[2]); - _mm_storel_epi64((__m128i *)(d + 3 * stride), s[3]); - _mm_storel_epi64((__m128i *)(d + 4 * stride), s[4]); - _mm_storel_epi64((__m128i *)(d + 5 * stride), s[5]); - _mm_storel_epi64((__m128i *)(d + 6 * stride), s[6]); - _mm_storel_epi64((__m128i *)(d + 7 * stride), s[7]); -} - -static INLINE void storeu_8bit_16x4(const __m128i *const s, uint8_t *const d, - const ptrdiff_t stride) { - _mm_storeu_si128((__m128i *)(d + 0 * stride), s[0]); - _mm_storeu_si128((__m128i *)(d + 1 * stride), s[1]); - _mm_storeu_si128((__m128i *)(d + 2 * stride), s[2]); - _mm_storeu_si128((__m128i *)(d + 3 * stride), s[3]); -} - -#endif // VPX_VPX_DSP_X86_MEM_SSE2_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/post_proc_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/post_proc_sse2.c deleted file mode 100644 index 119fa7cd..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/post_proc_sse2.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/x86/mem_sse2.h" - -extern const int16_t vpx_rv[]; - -void vpx_mbpost_proc_down_sse2(unsigned char *dst, int pitch, int rows, - int cols, int flimit) { - int col; - const __m128i zero = _mm_setzero_si128(); - const __m128i f = _mm_set1_epi32(flimit); - DECLARE_ALIGNED(16, int16_t, above_context[8 * 8]); - - // 8 columns are processed at a time. - // If rows is less than 8 the bottom border extension fails. - assert(cols % 8 == 0); - assert(rows >= 8); - - for (col = 0; col < cols; col += 8) { - int row, i; - __m128i s = _mm_loadl_epi64((__m128i *)dst); - __m128i sum, sumsq_0, sumsq_1; - __m128i tmp_0, tmp_1; - __m128i below_context = _mm_setzero_si128(); - - s = _mm_unpacklo_epi8(s, zero); - - for (i = 0; i < 8; ++i) { - _mm_store_si128((__m128i *)above_context + i, s); - } - - // sum *= 9 - sum = _mm_slli_epi16(s, 3); - sum = _mm_add_epi16(s, sum); - - // sum^2 * 9 == (sum * 9) * sum - tmp_0 = _mm_mullo_epi16(sum, s); - tmp_1 = _mm_mulhi_epi16(sum, s); - - sumsq_0 = _mm_unpacklo_epi16(tmp_0, tmp_1); - sumsq_1 = _mm_unpackhi_epi16(tmp_0, tmp_1); - - // Prime sum/sumsq - for (i = 1; i <= 6; ++i) { - __m128i a = _mm_loadl_epi64((__m128i *)(dst + i * pitch)); - a = _mm_unpacklo_epi8(a, zero); - sum = _mm_add_epi16(sum, a); - a = _mm_mullo_epi16(a, a); - sumsq_0 = _mm_add_epi32(sumsq_0, _mm_unpacklo_epi16(a, zero)); - sumsq_1 = _mm_add_epi32(sumsq_1, _mm_unpackhi_epi16(a, zero)); - } - - for (row = 0; row < rows + 8; row++) { - const __m128i above = - _mm_load_si128((__m128i *)above_context + (row & 7)); - __m128i this_row = _mm_loadl_epi64((__m128i *)(dst + row * pitch)); - __m128i above_sq, below_sq; - __m128i mask_0, mask_1; - __m128i multmp_0, multmp_1; - __m128i rv; - __m128i out; - - this_row = _mm_unpacklo_epi8(this_row, zero); - - if (row + 7 < rows) { - // Instead of copying the end context we just stop loading when we get - // to the last one. - below_context = _mm_loadl_epi64((__m128i *)(dst + (row + 7) * pitch)); - below_context = _mm_unpacklo_epi8(below_context, zero); - } - - sum = _mm_sub_epi16(sum, above); - sum = _mm_add_epi16(sum, below_context); - - // context^2 fits in 16 bits. Don't need to mulhi and combine. Just zero - // extend. Unfortunately we can't do below_sq - above_sq in 16 bits - // because x86 does not have unpack with sign extension. - above_sq = _mm_mullo_epi16(above, above); - sumsq_0 = _mm_sub_epi32(sumsq_0, _mm_unpacklo_epi16(above_sq, zero)); - sumsq_1 = _mm_sub_epi32(sumsq_1, _mm_unpackhi_epi16(above_sq, zero)); - - below_sq = _mm_mullo_epi16(below_context, below_context); - sumsq_0 = _mm_add_epi32(sumsq_0, _mm_unpacklo_epi16(below_sq, zero)); - sumsq_1 = _mm_add_epi32(sumsq_1, _mm_unpackhi_epi16(below_sq, zero)); - - // sumsq * 16 - sumsq == sumsq * 15 - mask_0 = _mm_slli_epi32(sumsq_0, 4); - mask_0 = _mm_sub_epi32(mask_0, sumsq_0); - mask_1 = _mm_slli_epi32(sumsq_1, 4); - mask_1 = _mm_sub_epi32(mask_1, sumsq_1); - - multmp_0 = _mm_mullo_epi16(sum, sum); - multmp_1 = _mm_mulhi_epi16(sum, sum); - - mask_0 = _mm_sub_epi32(mask_0, _mm_unpacklo_epi16(multmp_0, multmp_1)); - mask_1 = _mm_sub_epi32(mask_1, _mm_unpackhi_epi16(multmp_0, multmp_1)); - - // mask - f gives a negative value when mask < f - mask_0 = _mm_sub_epi32(mask_0, f); - mask_1 = _mm_sub_epi32(mask_1, f); - - // Shift the sign bit down to create a mask - mask_0 = _mm_srai_epi32(mask_0, 31); - mask_1 = _mm_srai_epi32(mask_1, 31); - - mask_0 = _mm_packs_epi32(mask_0, mask_1); - - rv = _mm_loadu_si128((__m128i const *)(vpx_rv + (row & 127))); - - mask_1 = _mm_add_epi16(rv, sum); - mask_1 = _mm_add_epi16(mask_1, this_row); - mask_1 = _mm_srai_epi16(mask_1, 4); - - mask_1 = _mm_and_si128(mask_0, mask_1); - mask_0 = _mm_andnot_si128(mask_0, this_row); - out = _mm_or_si128(mask_1, mask_0); - - _mm_storel_epi64((__m128i *)(dst + row * pitch), - _mm_packus_epi16(out, zero)); - - _mm_store_si128((__m128i *)above_context + ((row + 8) & 7), this_row); - } - - dst += 8; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_avx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_avx.c deleted file mode 100644 index 5ff5abc1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_avx.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#if defined(_MSC_VER) -#include -#endif -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/x86/bitdepth_conversion_sse2.h" -#include "vpx_dsp/x86/quantize_sse2.h" -#include "vpx_dsp/x86/quantize_ssse3.h" -#include "vp9/common/vp9_scan.h" -#include "vp9/encoder/vp9_block.h" - -void vpx_quantize_b_avx(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - const __m128i zero = _mm_setzero_si128(); - const __m256i big_zero = _mm256_setzero_si256(); - int index; - const int16_t *iscan = scan_order->iscan; - - __m128i zbin, round, quant, dequant, shift; - __m128i coeff0, coeff1; - __m128i qcoeff0, qcoeff1; - __m128i cmp_mask0, cmp_mask1; - __m128i all_zero; - __m128i eob = zero, eob0; - - *eob_ptr = 0; - - load_b_values(mb_plane, &zbin, &round, &quant, dequant_ptr, &dequant, &shift); - - // Do DC and first 15 AC. - coeff0 = load_tran_low(coeff_ptr); - coeff1 = load_tran_low(coeff_ptr + 8); - - qcoeff0 = _mm_abs_epi16(coeff0); - qcoeff1 = _mm_abs_epi16(coeff1); - - cmp_mask0 = _mm_cmpgt_epi16(qcoeff0, zbin); - zbin = _mm_unpackhi_epi64(zbin, zbin); // Switch DC to AC - cmp_mask1 = _mm_cmpgt_epi16(qcoeff1, zbin); - - all_zero = _mm_or_si128(cmp_mask0, cmp_mask1); - if (_mm_test_all_zeros(all_zero, all_zero)) { - _mm256_store_si256((__m256i *)(qcoeff_ptr), big_zero); - _mm256_store_si256((__m256i *)(dqcoeff_ptr), big_zero); -#if CONFIG_VP9_HIGHBITDEPTH - _mm256_store_si256((__m256i *)(qcoeff_ptr + 8), big_zero); - _mm256_store_si256((__m256i *)(dqcoeff_ptr + 8), big_zero); -#endif // CONFIG_VP9_HIGHBITDEPTH - - if (n_coeffs == 16) return; - - round = _mm_unpackhi_epi64(round, round); - quant = _mm_unpackhi_epi64(quant, quant); - shift = _mm_unpackhi_epi64(shift, shift); - dequant = _mm_unpackhi_epi64(dequant, dequant); - } else { - calculate_qcoeff(&qcoeff0, round, quant, shift); - round = _mm_unpackhi_epi64(round, round); - quant = _mm_unpackhi_epi64(quant, quant); - shift = _mm_unpackhi_epi64(shift, shift); - calculate_qcoeff(&qcoeff1, round, quant, shift); - - // Reinsert signs - qcoeff0 = _mm_sign_epi16(qcoeff0, coeff0); - qcoeff1 = _mm_sign_epi16(qcoeff1, coeff1); - - // Mask out zbin threshold coeffs - qcoeff0 = _mm_and_si128(qcoeff0, cmp_mask0); - qcoeff1 = _mm_and_si128(qcoeff1, cmp_mask1); - - store_tran_low(qcoeff0, qcoeff_ptr); - store_tran_low(qcoeff1, qcoeff_ptr + 8); - - calculate_dqcoeff_and_store(qcoeff0, dequant, dqcoeff_ptr); - dequant = _mm_unpackhi_epi64(dequant, dequant); - calculate_dqcoeff_and_store(qcoeff1, dequant, dqcoeff_ptr + 8); - - eob = scan_for_eob(&qcoeff0, &qcoeff1, iscan, 0, zero); - } - - // AC only loop. - for (index = 16; index < n_coeffs; index += 16) { - coeff0 = load_tran_low(coeff_ptr + index); - coeff1 = load_tran_low(coeff_ptr + index + 8); - - qcoeff0 = _mm_abs_epi16(coeff0); - qcoeff1 = _mm_abs_epi16(coeff1); - - cmp_mask0 = _mm_cmpgt_epi16(qcoeff0, zbin); - cmp_mask1 = _mm_cmpgt_epi16(qcoeff1, zbin); - - all_zero = _mm_or_si128(cmp_mask0, cmp_mask1); - if (_mm_test_all_zeros(all_zero, all_zero)) { - _mm256_store_si256((__m256i *)(qcoeff_ptr + index), big_zero); - _mm256_store_si256((__m256i *)(dqcoeff_ptr + index), big_zero); -#if CONFIG_VP9_HIGHBITDEPTH - _mm256_store_si256((__m256i *)(qcoeff_ptr + index + 8), big_zero); - _mm256_store_si256((__m256i *)(dqcoeff_ptr + index + 8), big_zero); -#endif // CONFIG_VP9_HIGHBITDEPTH - continue; - } - - calculate_qcoeff(&qcoeff0, round, quant, shift); - calculate_qcoeff(&qcoeff1, round, quant, shift); - - qcoeff0 = _mm_sign_epi16(qcoeff0, coeff0); - qcoeff1 = _mm_sign_epi16(qcoeff1, coeff1); - - qcoeff0 = _mm_and_si128(qcoeff0, cmp_mask0); - qcoeff1 = _mm_and_si128(qcoeff1, cmp_mask1); - - store_tran_low(qcoeff0, qcoeff_ptr + index); - store_tran_low(qcoeff1, qcoeff_ptr + index + 8); - - calculate_dqcoeff_and_store(qcoeff0, dequant, dqcoeff_ptr + index); - calculate_dqcoeff_and_store(qcoeff1, dequant, dqcoeff_ptr + index + 8); - - eob0 = scan_for_eob(&qcoeff0, &qcoeff1, iscan, index, zero); - eob = _mm_max_epi16(eob, eob0); - } - - *eob_ptr = accumulate_eob(eob); -} - -void vpx_quantize_b_32x32_avx(const tran_low_t *coeff_ptr, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - const __m128i zero = _mm_setzero_si128(); - const __m256i big_zero = _mm256_setzero_si256(); - int index; - const int16_t *iscan = scan_order->iscan; - - __m128i zbin, round, quant, dequant, shift; - __m128i coeff0, coeff1; - __m128i qcoeff0, qcoeff1; - __m128i cmp_mask0, cmp_mask1; - __m128i all_zero; - __m128i eob = zero, eob0; - - load_b_values32x32(mb_plane, &zbin, &round, &quant, dequant_ptr, &dequant, - &shift); - - // Do DC and first 15 AC. - coeff0 = load_tran_low(coeff_ptr); - coeff1 = load_tran_low(coeff_ptr + 8); - - qcoeff0 = _mm_abs_epi16(coeff0); - qcoeff1 = _mm_abs_epi16(coeff1); - - cmp_mask0 = _mm_cmpgt_epi16(qcoeff0, zbin); - zbin = _mm_unpackhi_epi64(zbin, zbin); // Switch DC to AC. - cmp_mask1 = _mm_cmpgt_epi16(qcoeff1, zbin); - - all_zero = _mm_or_si128(cmp_mask0, cmp_mask1); - if (_mm_test_all_zeros(all_zero, all_zero)) { - _mm256_store_si256((__m256i *)(qcoeff_ptr), big_zero); - _mm256_store_si256((__m256i *)(dqcoeff_ptr), big_zero); -#if CONFIG_VP9_HIGHBITDEPTH - _mm256_store_si256((__m256i *)(qcoeff_ptr + 8), big_zero); - _mm256_store_si256((__m256i *)(dqcoeff_ptr + 8), big_zero); -#endif // CONFIG_VP9_HIGHBITDEPTH - - round = _mm_unpackhi_epi64(round, round); - quant = _mm_unpackhi_epi64(quant, quant); - shift = _mm_unpackhi_epi64(shift, shift); - dequant = _mm_unpackhi_epi64(dequant, dequant); - } else { - calculate_qcoeff(&qcoeff0, round, quant, shift); - round = _mm_unpackhi_epi64(round, round); - quant = _mm_unpackhi_epi64(quant, quant); - shift = _mm_unpackhi_epi64(shift, shift); - calculate_qcoeff(&qcoeff1, round, quant, shift); - - // Reinsert signs. - qcoeff0 = _mm_sign_epi16(qcoeff0, coeff0); - qcoeff1 = _mm_sign_epi16(qcoeff1, coeff1); - - // Mask out zbin threshold coeffs. - qcoeff0 = _mm_and_si128(qcoeff0, cmp_mask0); - qcoeff1 = _mm_and_si128(qcoeff1, cmp_mask1); - - store_tran_low(qcoeff0, qcoeff_ptr); - store_tran_low(qcoeff1, qcoeff_ptr + 8); - - calculate_dqcoeff_and_store_32x32(qcoeff0, dequant, zero, dqcoeff_ptr); - dequant = _mm_unpackhi_epi64(dequant, dequant); - calculate_dqcoeff_and_store_32x32(qcoeff1, dequant, zero, dqcoeff_ptr + 8); - - eob = scan_for_eob(&qcoeff0, &qcoeff1, iscan, 0, zero); - } - - // AC only loop. - for (index = 16; index < 32 * 32; index += 16) { - coeff0 = load_tran_low(coeff_ptr + index); - coeff1 = load_tran_low(coeff_ptr + index + 8); - - qcoeff0 = _mm_abs_epi16(coeff0); - qcoeff1 = _mm_abs_epi16(coeff1); - - cmp_mask0 = _mm_cmpgt_epi16(qcoeff0, zbin); - cmp_mask1 = _mm_cmpgt_epi16(qcoeff1, zbin); - - all_zero = _mm_or_si128(cmp_mask0, cmp_mask1); - if (_mm_test_all_zeros(all_zero, all_zero)) { - _mm256_store_si256((__m256i *)(qcoeff_ptr + index), big_zero); - _mm256_store_si256((__m256i *)(dqcoeff_ptr + index), big_zero); -#if CONFIG_VP9_HIGHBITDEPTH - _mm256_store_si256((__m256i *)(qcoeff_ptr + index + 8), big_zero); - _mm256_store_si256((__m256i *)(dqcoeff_ptr + index + 8), big_zero); -#endif // CONFIG_VP9_HIGHBITDEPTH - continue; - } - - calculate_qcoeff(&qcoeff0, round, quant, shift); - calculate_qcoeff(&qcoeff1, round, quant, shift); - - qcoeff0 = _mm_sign_epi16(qcoeff0, coeff0); - qcoeff1 = _mm_sign_epi16(qcoeff1, coeff1); - - qcoeff0 = _mm_and_si128(qcoeff0, cmp_mask0); - qcoeff1 = _mm_and_si128(qcoeff1, cmp_mask1); - - store_tran_low(qcoeff0, qcoeff_ptr + index); - store_tran_low(qcoeff1, qcoeff_ptr + index + 8); - - calculate_dqcoeff_and_store_32x32(qcoeff0, dequant, zero, - dqcoeff_ptr + index); - calculate_dqcoeff_and_store_32x32(qcoeff1, dequant, zero, - dqcoeff_ptr + index + 8); - - eob0 = scan_for_eob(&qcoeff0, &qcoeff1, iscan, index, zero); - eob = _mm_max_epi16(eob, eob0); - } - - *eob_ptr = accumulate_eob(eob); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_avx2.c deleted file mode 100644 index d4872f6b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_avx2.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vp9/common/vp9_scan.h" -#include "vp9/encoder/vp9_block.h" - -static VPX_FORCE_INLINE void load_b_values_avx2( - const struct macroblock_plane *mb_plane, __m256i *zbin, __m256i *round, - __m256i *quant, const int16_t *dequant_ptr, __m256i *dequant, - __m256i *shift, int log_scale) { - *zbin = - _mm256_castsi128_si256(_mm_load_si128((const __m128i *)mb_plane->zbin)); - *zbin = _mm256_permute4x64_epi64(*zbin, 0x54); - if (log_scale > 0) { - const __m256i rnd = _mm256_set1_epi16((int16_t)(1 << (log_scale - 1))); - *zbin = _mm256_add_epi16(*zbin, rnd); - *zbin = _mm256_srai_epi16(*zbin, log_scale); - } - // Subtracting 1 here eliminates a _mm256_cmpeq_epi16() instruction when - // calculating the zbin mask. (See quantize_b_logscale{0,1,2}_16) - *zbin = _mm256_sub_epi16(*zbin, _mm256_set1_epi16(1)); - - *round = - _mm256_castsi128_si256(_mm_load_si128((const __m128i *)mb_plane->round)); - *round = _mm256_permute4x64_epi64(*round, 0x54); - if (log_scale > 0) { - const __m256i rnd = _mm256_set1_epi16((int16_t)(1 << (log_scale - 1))); - *round = _mm256_add_epi16(*round, rnd); - *round = _mm256_srai_epi16(*round, log_scale); - } - - *quant = - _mm256_castsi128_si256(_mm_load_si128((const __m128i *)mb_plane->quant)); - *quant = _mm256_permute4x64_epi64(*quant, 0x54); - *dequant = - _mm256_castsi128_si256(_mm_load_si128((const __m128i *)dequant_ptr)); - *dequant = _mm256_permute4x64_epi64(*dequant, 0x54); - *shift = _mm256_castsi128_si256( - _mm_load_si128((const __m128i *)mb_plane->quant_shift)); - *shift = _mm256_permute4x64_epi64(*shift, 0x54); -} - -static VPX_FORCE_INLINE __m256i -load_coefficients_avx2(const tran_low_t *coeff_ptr) { -#if CONFIG_VP9_HIGHBITDEPTH - // typedef int32_t tran_low_t; - const __m256i coeff1 = _mm256_loadu_si256((const __m256i *)coeff_ptr); - const __m256i coeff2 = _mm256_loadu_si256((const __m256i *)(coeff_ptr + 8)); - return _mm256_packs_epi32(coeff1, coeff2); -#else - // typedef int16_t tran_low_t; - return _mm256_loadu_si256((const __m256i *)coeff_ptr); -#endif -} - -static VPX_FORCE_INLINE void store_coefficients_avx2(__m256i coeff_vals, - tran_low_t *coeff_ptr) { -#if CONFIG_VP9_HIGHBITDEPTH - // typedef int32_t tran_low_t; - __m256i coeff_sign = _mm256_srai_epi16(coeff_vals, 15); - __m256i coeff_vals_lo = _mm256_unpacklo_epi16(coeff_vals, coeff_sign); - __m256i coeff_vals_hi = _mm256_unpackhi_epi16(coeff_vals, coeff_sign); - _mm256_storeu_si256((__m256i *)coeff_ptr, coeff_vals_lo); - _mm256_storeu_si256((__m256i *)(coeff_ptr + 8), coeff_vals_hi); -#else - // typedef int16_t tran_low_t; - _mm256_storeu_si256((__m256i *)coeff_ptr, coeff_vals); -#endif -} - -static VPX_FORCE_INLINE __m256i -quantize_b_16(const tran_low_t *coeff_ptr, tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, __m256i *v_quant, __m256i *v_dequant, - __m256i *v_round, __m256i *v_zbin, __m256i *v_quant_shift) { - const __m256i v_coeff = load_coefficients_avx2(coeff_ptr); - const __m256i v_abs_coeff = _mm256_abs_epi16(v_coeff); - const __m256i v_zbin_mask = _mm256_cmpgt_epi16(v_abs_coeff, *v_zbin); - - if (_mm256_movemask_epi8(v_zbin_mask) == 0) { - _mm256_storeu_si256((__m256i *)qcoeff_ptr, _mm256_setzero_si256()); - _mm256_storeu_si256((__m256i *)dqcoeff_ptr, _mm256_setzero_si256()); -#if CONFIG_VP9_HIGHBITDEPTH - _mm256_store_si256((__m256i *)(qcoeff_ptr + 8), _mm256_setzero_si256()); - _mm256_store_si256((__m256i *)(dqcoeff_ptr + 8), _mm256_setzero_si256()); -#endif // CONFIG_VP9_HIGHBITDEPTH - return _mm256_setzero_si256(); - } - { - // tmp = v_zbin_mask ? (int64_t)abs_coeff + log_scaled_round : 0 - const __m256i v_tmp_rnd = - _mm256_and_si256(_mm256_adds_epi16(v_abs_coeff, *v_round), v_zbin_mask); - - const __m256i v_tmp32_a = _mm256_mulhi_epi16(v_tmp_rnd, *v_quant); - const __m256i v_tmp32_b = _mm256_add_epi16(v_tmp32_a, v_tmp_rnd); - const __m256i v_tmp32 = _mm256_mulhi_epi16(v_tmp32_b, *v_quant_shift); - const __m256i v_nz_mask = - _mm256_cmpgt_epi16(v_tmp32, _mm256_setzero_si256()); - const __m256i v_qcoeff = _mm256_sign_epi16(v_tmp32, v_coeff); -#if CONFIG_VP9_HIGHBITDEPTH - const __m256i low = _mm256_mullo_epi16(v_qcoeff, *v_dequant); - const __m256i high = _mm256_mulhi_epi16(v_qcoeff, *v_dequant); - - const __m256i v_dqcoeff_lo = _mm256_unpacklo_epi16(low, high); - const __m256i v_dqcoeff_hi = _mm256_unpackhi_epi16(low, high); -#else - const __m256i v_dqcoeff = _mm256_mullo_epi16(v_qcoeff, *v_dequant); -#endif - - store_coefficients_avx2(v_qcoeff, qcoeff_ptr); -#if CONFIG_VP9_HIGHBITDEPTH - _mm256_storeu_si256((__m256i *)(dqcoeff_ptr), v_dqcoeff_lo); - _mm256_storeu_si256((__m256i *)(dqcoeff_ptr + 8), v_dqcoeff_hi); -#else - store_coefficients_avx2(v_dqcoeff, dqcoeff_ptr); -#endif - return v_nz_mask; - } -} - -static VPX_FORCE_INLINE __m256i get_max_lane_eob(const int16_t *iscan, - __m256i v_eobmax, - __m256i v_mask) { -#if CONFIG_VP9_HIGHBITDEPTH - const __m256i v_iscan = _mm256_permute4x64_epi64( - _mm256_loadu_si256((const __m256i *)iscan), 0xD8); -#else - const __m256i v_iscan = _mm256_loadu_si256((const __m256i *)iscan); -#endif - const __m256i v_nz_iscan = _mm256_and_si256(v_iscan, v_mask); - return _mm256_max_epi16(v_eobmax, v_nz_iscan); -} - -static VPX_FORCE_INLINE int16_t accumulate_eob256(__m256i eob256) { - const __m128i eob_lo = _mm256_castsi256_si128(eob256); - const __m128i eob_hi = _mm256_extractf128_si256(eob256, 1); - __m128i eob = _mm_max_epi16(eob_lo, eob_hi); - __m128i eob_shuffled = _mm_shuffle_epi32(eob, 0xe); - eob = _mm_max_epi16(eob, eob_shuffled); - eob_shuffled = _mm_shufflelo_epi16(eob, 0xe); - eob = _mm_max_epi16(eob, eob_shuffled); - eob_shuffled = _mm_shufflelo_epi16(eob, 0x1); - eob = _mm_max_epi16(eob, eob_shuffled); - return _mm_extract_epi16(eob, 1); -} - -void vpx_quantize_b_avx2(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - __m256i v_zbin, v_round, v_quant, v_dequant, v_quant_shift, v_nz_mask; - __m256i v_eobmax = _mm256_setzero_si256(); - intptr_t count; - const int16_t *iscan = scan_order->iscan; - - load_b_values_avx2(mb_plane, &v_zbin, &v_round, &v_quant, dequant_ptr, - &v_dequant, &v_quant_shift, 0); - // Do DC and first 15 AC. - v_nz_mask = quantize_b_16(coeff_ptr, qcoeff_ptr, dqcoeff_ptr, &v_quant, - &v_dequant, &v_round, &v_zbin, &v_quant_shift); - - v_eobmax = get_max_lane_eob(iscan, v_eobmax, v_nz_mask); - - v_round = _mm256_unpackhi_epi64(v_round, v_round); - v_quant = _mm256_unpackhi_epi64(v_quant, v_quant); - v_dequant = _mm256_unpackhi_epi64(v_dequant, v_dequant); - v_quant_shift = _mm256_unpackhi_epi64(v_quant_shift, v_quant_shift); - v_zbin = _mm256_unpackhi_epi64(v_zbin, v_zbin); - - for (count = n_coeffs - 16; count > 0; count -= 16) { - coeff_ptr += 16; - qcoeff_ptr += 16; - dqcoeff_ptr += 16; - iscan += 16; - v_nz_mask = quantize_b_16(coeff_ptr, qcoeff_ptr, dqcoeff_ptr, &v_quant, - &v_dequant, &v_round, &v_zbin, &v_quant_shift); - - v_eobmax = get_max_lane_eob(iscan, v_eobmax, v_nz_mask); - } - - *eob_ptr = accumulate_eob256(v_eobmax); -} - -static VPX_FORCE_INLINE __m256i quantize_b_32x32_16( - const tran_low_t *coeff_ptr, tran_low_t *qcoeff_ptr, - tran_low_t *dqcoeff_ptr, const int16_t *iscan, __m256i *v_quant, - __m256i *v_dequant, __m256i *v_round, __m256i *v_zbin, - __m256i *v_quant_shift, __m256i *v_eobmax) { - const __m256i v_coeff = load_coefficients_avx2(coeff_ptr); - const __m256i v_abs_coeff = _mm256_abs_epi16(v_coeff); - const __m256i v_zbin_mask = _mm256_cmpgt_epi16(v_abs_coeff, *v_zbin); - - if (_mm256_movemask_epi8(v_zbin_mask) == 0) { - _mm256_store_si256((__m256i *)qcoeff_ptr, _mm256_setzero_si256()); - _mm256_store_si256((__m256i *)dqcoeff_ptr, _mm256_setzero_si256()); -#if CONFIG_VP9_HIGHBITDEPTH - _mm256_store_si256((__m256i *)(qcoeff_ptr + 8), _mm256_setzero_si256()); - _mm256_store_si256((__m256i *)(dqcoeff_ptr + 8), _mm256_setzero_si256()); -#endif - return *v_eobmax; - } - { - // tmp = v_zbin_mask ? (int64_t)abs_coeff + round : 0 - const __m256i v_tmp_rnd = - _mm256_and_si256(_mm256_adds_epi16(v_abs_coeff, *v_round), v_zbin_mask); - // tmp32 = (int)(((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) * - // quant_shift_ptr[rc != 0]) >> 15); - const __m256i v_tmp32_a = _mm256_mulhi_epi16(v_tmp_rnd, *v_quant); - const __m256i v_tmp32_b = _mm256_add_epi16(v_tmp32_a, v_tmp_rnd); - const __m256i v_tmp32_hi = - _mm256_slli_epi16(_mm256_mulhi_epi16(v_tmp32_b, *v_quant_shift), 1); - const __m256i v_tmp32_lo = - _mm256_srli_epi16(_mm256_mullo_epi16(v_tmp32_b, *v_quant_shift), 15); - const __m256i v_tmp32 = _mm256_or_si256(v_tmp32_hi, v_tmp32_lo); - const __m256i v_qcoeff = _mm256_sign_epi16(v_tmp32, v_coeff); - const __m256i v_sign_lo = - _mm256_unpacklo_epi16(_mm256_setzero_si256(), v_coeff); - const __m256i v_sign_hi = - _mm256_unpackhi_epi16(_mm256_setzero_si256(), v_coeff); - const __m256i low = _mm256_mullo_epi16(v_tmp32, *v_dequant); - const __m256i high = _mm256_mulhi_epi16(v_tmp32, *v_dequant); - const __m256i v_dqcoeff_lo = _mm256_sign_epi32( - _mm256_srli_epi32(_mm256_unpacklo_epi16(low, high), 1), v_sign_lo); - const __m256i v_dqcoeff_hi = _mm256_sign_epi32( - _mm256_srli_epi32(_mm256_unpackhi_epi16(low, high), 1), v_sign_hi); - const __m256i v_nz_mask = - _mm256_cmpgt_epi16(v_tmp32, _mm256_setzero_si256()); - - store_coefficients_avx2(v_qcoeff, qcoeff_ptr); - -#if CONFIG_VP9_HIGHBITDEPTH - _mm256_storeu_si256((__m256i *)(dqcoeff_ptr), v_dqcoeff_lo); - _mm256_storeu_si256((__m256i *)(dqcoeff_ptr + 8), v_dqcoeff_hi); -#else - store_coefficients_avx2(_mm256_packs_epi32(v_dqcoeff_lo, v_dqcoeff_hi), - dqcoeff_ptr); -#endif - - return get_max_lane_eob(iscan, *v_eobmax, v_nz_mask); - } -} - -void vpx_quantize_b_32x32_avx2(const tran_low_t *coeff_ptr, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - __m256i v_zbin, v_round, v_quant, v_dequant, v_quant_shift; - __m256i v_eobmax = _mm256_setzero_si256(); - intptr_t count; - const int16_t *iscan = scan_order->iscan; - - load_b_values_avx2(mb_plane, &v_zbin, &v_round, &v_quant, dequant_ptr, - &v_dequant, &v_quant_shift, 1); - - // Do DC and first 15 AC. - v_eobmax = quantize_b_32x32_16(coeff_ptr, qcoeff_ptr, dqcoeff_ptr, iscan, - &v_quant, &v_dequant, &v_round, &v_zbin, - &v_quant_shift, &v_eobmax); - - v_round = _mm256_unpackhi_epi64(v_round, v_round); - v_quant = _mm256_unpackhi_epi64(v_quant, v_quant); - v_dequant = _mm256_unpackhi_epi64(v_dequant, v_dequant); - v_quant_shift = _mm256_unpackhi_epi64(v_quant_shift, v_quant_shift); - v_zbin = _mm256_unpackhi_epi64(v_zbin, v_zbin); - - for (count = (32 * 32) - 16; count > 0; count -= 16) { - coeff_ptr += 16; - qcoeff_ptr += 16; - dqcoeff_ptr += 16; - iscan += 16; - v_eobmax = quantize_b_32x32_16(coeff_ptr, qcoeff_ptr, dqcoeff_ptr, iscan, - &v_quant, &v_dequant, &v_round, &v_zbin, - &v_quant_shift, &v_eobmax); - } - - *eob_ptr = accumulate_eob256(v_eobmax); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_sse2.c deleted file mode 100644 index 64838eaa..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_sse2.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/x86/bitdepth_conversion_sse2.h" -#include "vpx_dsp/x86/quantize_sse2.h" -#include "vp9/common/vp9_scan.h" - -void vpx_quantize_b_sse2(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - const __m128i zero = _mm_setzero_si128(); - int index = 16; - const int16_t *iscan = scan_order->iscan; - - __m128i zbin, round, quant, dequant, shift; - __m128i coeff0, coeff1, coeff0_sign, coeff1_sign; - __m128i qcoeff0, qcoeff1; - __m128i cmp_mask0, cmp_mask1; - __m128i eob, eob0; - - // Setup global values. - load_b_values(mb_plane, &zbin, &round, &quant, dequant_ptr, &dequant, &shift); - - // Do DC and first 15 AC. - coeff0 = load_tran_low(coeff_ptr); - coeff1 = load_tran_low(coeff_ptr + 8); - - // Poor man's abs(). - coeff0_sign = _mm_srai_epi16(coeff0, 15); - coeff1_sign = _mm_srai_epi16(coeff1, 15); - qcoeff0 = invert_sign_sse2(coeff0, coeff0_sign); - qcoeff1 = invert_sign_sse2(coeff1, coeff1_sign); - - cmp_mask0 = _mm_cmpgt_epi16(qcoeff0, zbin); - zbin = _mm_unpackhi_epi64(zbin, zbin); // Switch DC to AC - cmp_mask1 = _mm_cmpgt_epi16(qcoeff1, zbin); - - calculate_qcoeff(&qcoeff0, round, quant, shift); - - round = _mm_unpackhi_epi64(round, round); - quant = _mm_unpackhi_epi64(quant, quant); - shift = _mm_unpackhi_epi64(shift, shift); - - calculate_qcoeff(&qcoeff1, round, quant, shift); - - // Reinsert signs - qcoeff0 = invert_sign_sse2(qcoeff0, coeff0_sign); - qcoeff1 = invert_sign_sse2(qcoeff1, coeff1_sign); - - // Mask out zbin threshold coeffs - qcoeff0 = _mm_and_si128(qcoeff0, cmp_mask0); - qcoeff1 = _mm_and_si128(qcoeff1, cmp_mask1); - - store_tran_low(qcoeff0, qcoeff_ptr); - store_tran_low(qcoeff1, qcoeff_ptr + 8); - - calculate_dqcoeff_and_store(qcoeff0, dequant, dqcoeff_ptr); - dequant = _mm_unpackhi_epi64(dequant, dequant); - calculate_dqcoeff_and_store(qcoeff1, dequant, dqcoeff_ptr + 8); - - eob = scan_for_eob(&qcoeff0, &qcoeff1, iscan, 0, zero); - - // AC only loop. - while (index < n_coeffs) { - coeff0 = load_tran_low(coeff_ptr + index); - coeff1 = load_tran_low(coeff_ptr + index + 8); - - coeff0_sign = _mm_srai_epi16(coeff0, 15); - coeff1_sign = _mm_srai_epi16(coeff1, 15); - qcoeff0 = invert_sign_sse2(coeff0, coeff0_sign); - qcoeff1 = invert_sign_sse2(coeff1, coeff1_sign); - - cmp_mask0 = _mm_cmpgt_epi16(qcoeff0, zbin); - cmp_mask1 = _mm_cmpgt_epi16(qcoeff1, zbin); - - calculate_qcoeff(&qcoeff0, round, quant, shift); - calculate_qcoeff(&qcoeff1, round, quant, shift); - - qcoeff0 = invert_sign_sse2(qcoeff0, coeff0_sign); - qcoeff1 = invert_sign_sse2(qcoeff1, coeff1_sign); - - qcoeff0 = _mm_and_si128(qcoeff0, cmp_mask0); - qcoeff1 = _mm_and_si128(qcoeff1, cmp_mask1); - - store_tran_low(qcoeff0, qcoeff_ptr + index); - store_tran_low(qcoeff1, qcoeff_ptr + index + 8); - - calculate_dqcoeff_and_store(qcoeff0, dequant, dqcoeff_ptr + index); - calculate_dqcoeff_and_store(qcoeff1, dequant, dqcoeff_ptr + index + 8); - - eob0 = scan_for_eob(&qcoeff0, &qcoeff1, iscan, index, zero); - eob = _mm_max_epi16(eob, eob0); - - index += 16; - } - - *eob_ptr = accumulate_eob(eob); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_sse2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_sse2.h deleted file mode 100644 index 82c755a0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_sse2.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_X86_QUANTIZE_SSE2_H_ -#define VPX_VPX_DSP_X86_QUANTIZE_SSE2_H_ - -#include - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vp9/encoder/vp9_block.h" - -static INLINE void load_b_values(const struct macroblock_plane *const mb_plane, - __m128i *zbin, __m128i *round, __m128i *quant, - const int16_t *dequant_ptr, __m128i *dequant, - __m128i *shift) { - *zbin = _mm_load_si128((const __m128i *)mb_plane->zbin); - *round = _mm_load_si128((const __m128i *)mb_plane->round); - *quant = _mm_load_si128((const __m128i *)mb_plane->quant); - *zbin = _mm_sub_epi16(*zbin, _mm_set1_epi16(1)); - *dequant = _mm_load_si128((const __m128i *)dequant_ptr); - *shift = _mm_load_si128((const __m128i *)mb_plane->quant_shift); -} - -static INLINE void load_b_values32x32( - const struct macroblock_plane *const mb_plane, __m128i *zbin, - __m128i *round, __m128i *quant, const int16_t *dequant_ptr, - __m128i *dequant, __m128i *shift) { - const __m128i one = _mm_set1_epi16(1); - // The 32x32 halves zbin and round. - *zbin = _mm_load_si128((const __m128i *)mb_plane->zbin); - // Shift with rounding. - *zbin = _mm_add_epi16(*zbin, one); - *zbin = _mm_srli_epi16(*zbin, 1); - // x86 has no "greater *or equal*" comparison. Subtract 1 from zbin so - // it is a strict "greater" comparison. - *zbin = _mm_sub_epi16(*zbin, one); - - *round = _mm_load_si128((const __m128i *)mb_plane->round); - *round = _mm_add_epi16(*round, one); - *round = _mm_srli_epi16(*round, 1); - - *quant = _mm_load_si128((const __m128i *)mb_plane->quant); - *dequant = _mm_load_si128((const __m128i *)dequant_ptr); - *shift = _mm_load_si128((const __m128i *)mb_plane->quant_shift); - // I suspect this is not technically OK because quant_shift can be up - // to 1 << 16 and shifting up again will outrange that, but the test is not - // comprehensive enough to catch that and "it's been that way forever" - *shift = _mm_slli_epi16(*shift, 1); -} - -static INLINE void load_fp_values(const struct macroblock_plane *mb_plane, - __m128i *round, __m128i *quant, - const int16_t *dequant_ptr, - __m128i *dequant) { - *round = _mm_load_si128((const __m128i *)mb_plane->round_fp); - *quant = _mm_load_si128((const __m128i *)mb_plane->quant_fp); - *dequant = _mm_load_si128((const __m128i *)dequant_ptr); -} - -// With ssse3 and later abs() and sign() are preferred. -static INLINE __m128i invert_sign_sse2(__m128i a, __m128i sign) { - a = _mm_xor_si128(a, sign); - return _mm_sub_epi16(a, sign); -} - -static INLINE void calculate_qcoeff(__m128i *coeff, const __m128i round, - const __m128i quant, const __m128i shift) { - __m128i tmp, qcoeff; - qcoeff = _mm_adds_epi16(*coeff, round); - tmp = _mm_mulhi_epi16(qcoeff, quant); - qcoeff = _mm_add_epi16(tmp, qcoeff); - *coeff = _mm_mulhi_epi16(qcoeff, shift); -} - -static INLINE void calculate_dqcoeff_and_store(__m128i qcoeff, __m128i dequant, - tran_low_t *dqcoeff) { -#if CONFIG_VP9_HIGHBITDEPTH - const __m128i low = _mm_mullo_epi16(qcoeff, dequant); - const __m128i high = _mm_mulhi_epi16(qcoeff, dequant); - - const __m128i dqcoeff32_0 = _mm_unpacklo_epi16(low, high); - const __m128i dqcoeff32_1 = _mm_unpackhi_epi16(low, high); - - _mm_store_si128((__m128i *)(dqcoeff), dqcoeff32_0); - _mm_store_si128((__m128i *)(dqcoeff + 4), dqcoeff32_1); -#else - const __m128i dqcoeff16 = _mm_mullo_epi16(qcoeff, dequant); - - _mm_store_si128((__m128i *)(dqcoeff), dqcoeff16); -#endif // CONFIG_VP9_HIGHBITDEPTH -} - -// Scan 16 values for eob reference in scan. -static INLINE __m128i scan_for_eob(__m128i *coeff0, __m128i *coeff1, - const int16_t *scan, const int index, - const __m128i zero) { - const __m128i zero_coeff0 = _mm_cmpeq_epi16(*coeff0, zero); - const __m128i zero_coeff1 = _mm_cmpeq_epi16(*coeff1, zero); - __m128i scan0 = _mm_load_si128((const __m128i *)(scan + index)); - __m128i scan1 = _mm_load_si128((const __m128i *)(scan + index + 8)); - __m128i eob0, eob1; - eob0 = _mm_andnot_si128(zero_coeff0, scan0); - eob1 = _mm_andnot_si128(zero_coeff1, scan1); - return _mm_max_epi16(eob0, eob1); -} - -static INLINE int16_t accumulate_eob(__m128i eob) { - __m128i eob_shuffled; - eob_shuffled = _mm_shuffle_epi32(eob, 0xe); - eob = _mm_max_epi16(eob, eob_shuffled); - eob_shuffled = _mm_shufflelo_epi16(eob, 0xe); - eob = _mm_max_epi16(eob, eob_shuffled); - eob_shuffled = _mm_shufflelo_epi16(eob, 0x1); - eob = _mm_max_epi16(eob, eob_shuffled); - return _mm_extract_epi16(eob, 1); -} - -#endif // VPX_VPX_DSP_X86_QUANTIZE_SSE2_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_ssse3.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_ssse3.c deleted file mode 100644 index 2c6d851a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_ssse3.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/x86/bitdepth_conversion_sse2.h" -#include "vpx_dsp/x86/quantize_sse2.h" -#include "vpx_dsp/x86/quantize_ssse3.h" -#include "vp9/common/vp9_scan.h" -#include "vp9/encoder/vp9_block.h" - -void vpx_quantize_b_ssse3(const tran_low_t *coeff_ptr, intptr_t n_coeffs, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - const __m128i zero = _mm_setzero_si128(); - int index = 16; - const int16_t *iscan = scan_order->iscan; - - __m128i zbin, round, quant, dequant, shift; - __m128i coeff0, coeff1; - __m128i qcoeff0, qcoeff1; - __m128i cmp_mask0, cmp_mask1; - __m128i eob, eob0; - - load_b_values(mb_plane, &zbin, &round, &quant, dequant_ptr, &dequant, &shift); - - // Do DC and first 15 AC. - coeff0 = load_tran_low(coeff_ptr); - coeff1 = load_tran_low(coeff_ptr + 8); - - qcoeff0 = _mm_abs_epi16(coeff0); - qcoeff1 = _mm_abs_epi16(coeff1); - - cmp_mask0 = _mm_cmpgt_epi16(qcoeff0, zbin); - zbin = _mm_unpackhi_epi64(zbin, zbin); // Switch DC to AC - cmp_mask1 = _mm_cmpgt_epi16(qcoeff1, zbin); - - calculate_qcoeff(&qcoeff0, round, quant, shift); - round = _mm_unpackhi_epi64(round, round); - quant = _mm_unpackhi_epi64(quant, quant); - shift = _mm_unpackhi_epi64(shift, shift); - calculate_qcoeff(&qcoeff1, round, quant, shift); - - // Reinsert signs - qcoeff0 = _mm_sign_epi16(qcoeff0, coeff0); - qcoeff1 = _mm_sign_epi16(qcoeff1, coeff1); - - // Mask out zbin threshold coeffs - qcoeff0 = _mm_and_si128(qcoeff0, cmp_mask0); - qcoeff1 = _mm_and_si128(qcoeff1, cmp_mask1); - - store_tran_low(qcoeff0, qcoeff_ptr); - store_tran_low(qcoeff1, qcoeff_ptr + 8); - - calculate_dqcoeff_and_store(qcoeff0, dequant, dqcoeff_ptr); - dequant = _mm_unpackhi_epi64(dequant, dequant); - calculate_dqcoeff_and_store(qcoeff1, dequant, dqcoeff_ptr + 8); - - eob = scan_for_eob(&qcoeff0, &qcoeff1, iscan, 0, zero); - - // AC only loop. - while (index < n_coeffs) { - coeff0 = load_tran_low(coeff_ptr + index); - coeff1 = load_tran_low(coeff_ptr + index + 8); - - qcoeff0 = _mm_abs_epi16(coeff0); - qcoeff1 = _mm_abs_epi16(coeff1); - - cmp_mask0 = _mm_cmpgt_epi16(qcoeff0, zbin); - cmp_mask1 = _mm_cmpgt_epi16(qcoeff1, zbin); - - calculate_qcoeff(&qcoeff0, round, quant, shift); - calculate_qcoeff(&qcoeff1, round, quant, shift); - - qcoeff0 = _mm_sign_epi16(qcoeff0, coeff0); - qcoeff1 = _mm_sign_epi16(qcoeff1, coeff1); - - qcoeff0 = _mm_and_si128(qcoeff0, cmp_mask0); - qcoeff1 = _mm_and_si128(qcoeff1, cmp_mask1); - - store_tran_low(qcoeff0, qcoeff_ptr + index); - store_tran_low(qcoeff1, qcoeff_ptr + index + 8); - - calculate_dqcoeff_and_store(qcoeff0, dequant, dqcoeff_ptr + index); - calculate_dqcoeff_and_store(qcoeff1, dequant, dqcoeff_ptr + index + 8); - - eob0 = scan_for_eob(&qcoeff0, &qcoeff1, iscan, index, zero); - eob = _mm_max_epi16(eob, eob0); - - index += 16; - } - - *eob_ptr = accumulate_eob(eob); -} - -void vpx_quantize_b_32x32_ssse3(const tran_low_t *coeff_ptr, - const struct macroblock_plane *const mb_plane, - tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, - const int16_t *dequant_ptr, uint16_t *eob_ptr, - const struct ScanOrder *const scan_order) { - const __m128i zero = _mm_setzero_si128(); - int index; - const int16_t *iscan = scan_order->iscan; - - __m128i zbin, round, quant, dequant, shift; - __m128i coeff0, coeff1; - __m128i qcoeff0, qcoeff1; - __m128i cmp_mask0, cmp_mask1; - __m128i all_zero; - __m128i eob = zero, eob0; - - load_b_values32x32(mb_plane, &zbin, &round, &quant, dequant_ptr, &dequant, - &shift); - - // Do DC and first 15 AC. - coeff0 = load_tran_low(coeff_ptr); - coeff1 = load_tran_low(coeff_ptr + 8); - - qcoeff0 = _mm_abs_epi16(coeff0); - qcoeff1 = _mm_abs_epi16(coeff1); - - cmp_mask0 = _mm_cmpgt_epi16(qcoeff0, zbin); - zbin = _mm_unpackhi_epi64(zbin, zbin); // Switch DC to AC. - cmp_mask1 = _mm_cmpgt_epi16(qcoeff1, zbin); - - all_zero = _mm_or_si128(cmp_mask0, cmp_mask1); - if (_mm_movemask_epi8(all_zero) == 0) { - _mm_store_si128((__m128i *)(qcoeff_ptr), zero); - _mm_store_si128((__m128i *)(qcoeff_ptr + 8), zero); - _mm_store_si128((__m128i *)(dqcoeff_ptr), zero); - _mm_store_si128((__m128i *)(dqcoeff_ptr + 8), zero); -#if CONFIG_VP9_HIGHBITDEPTH - _mm_store_si128((__m128i *)(qcoeff_ptr + 4), zero); - _mm_store_si128((__m128i *)(qcoeff_ptr + 12), zero); - _mm_store_si128((__m128i *)(dqcoeff_ptr + 4), zero); - _mm_store_si128((__m128i *)(dqcoeff_ptr + 12), zero); -#endif // CONFIG_HIGHBITDEPTH - - round = _mm_unpackhi_epi64(round, round); - quant = _mm_unpackhi_epi64(quant, quant); - shift = _mm_unpackhi_epi64(shift, shift); - dequant = _mm_unpackhi_epi64(dequant, dequant); - } else { - calculate_qcoeff(&qcoeff0, round, quant, shift); - round = _mm_unpackhi_epi64(round, round); - quant = _mm_unpackhi_epi64(quant, quant); - shift = _mm_unpackhi_epi64(shift, shift); - calculate_qcoeff(&qcoeff1, round, quant, shift); - - // Reinsert signs. - qcoeff0 = _mm_sign_epi16(qcoeff0, coeff0); - qcoeff1 = _mm_sign_epi16(qcoeff1, coeff1); - - // Mask out zbin threshold coeffs. - qcoeff0 = _mm_and_si128(qcoeff0, cmp_mask0); - qcoeff1 = _mm_and_si128(qcoeff1, cmp_mask1); - - store_tran_low(qcoeff0, qcoeff_ptr); - store_tran_low(qcoeff1, qcoeff_ptr + 8); - - calculate_dqcoeff_and_store_32x32(qcoeff0, dequant, zero, dqcoeff_ptr); - dequant = _mm_unpackhi_epi64(dequant, dequant); - calculate_dqcoeff_and_store_32x32(qcoeff1, dequant, zero, dqcoeff_ptr + 8); - - eob = scan_for_eob(&qcoeff0, &qcoeff1, iscan, 0, zero); - } - - // AC only loop. - for (index = 16; index < 32 * 32; index += 16) { - coeff0 = load_tran_low(coeff_ptr + index); - coeff1 = load_tran_low(coeff_ptr + index + 8); - - qcoeff0 = _mm_abs_epi16(coeff0); - qcoeff1 = _mm_abs_epi16(coeff1); - - cmp_mask0 = _mm_cmpgt_epi16(qcoeff0, zbin); - cmp_mask1 = _mm_cmpgt_epi16(qcoeff1, zbin); - - all_zero = _mm_or_si128(cmp_mask0, cmp_mask1); - if (_mm_movemask_epi8(all_zero) == 0) { - _mm_store_si128((__m128i *)(qcoeff_ptr + index), zero); - _mm_store_si128((__m128i *)(qcoeff_ptr + index + 8), zero); - _mm_store_si128((__m128i *)(dqcoeff_ptr + index), zero); - _mm_store_si128((__m128i *)(dqcoeff_ptr + index + 8), zero); -#if CONFIG_VP9_HIGHBITDEPTH - _mm_store_si128((__m128i *)(qcoeff_ptr + index + 4), zero); - _mm_store_si128((__m128i *)(qcoeff_ptr + index + 12), zero); - _mm_store_si128((__m128i *)(dqcoeff_ptr + index + 4), zero); - _mm_store_si128((__m128i *)(dqcoeff_ptr + index + 12), zero); -#endif // CONFIG_VP9_HIGHBITDEPTH - continue; - } - - calculate_qcoeff(&qcoeff0, round, quant, shift); - calculate_qcoeff(&qcoeff1, round, quant, shift); - - qcoeff0 = _mm_sign_epi16(qcoeff0, coeff0); - qcoeff1 = _mm_sign_epi16(qcoeff1, coeff1); - - qcoeff0 = _mm_and_si128(qcoeff0, cmp_mask0); - qcoeff1 = _mm_and_si128(qcoeff1, cmp_mask1); - - store_tran_low(qcoeff0, qcoeff_ptr + index); - store_tran_low(qcoeff1, qcoeff_ptr + index + 8); - - calculate_dqcoeff_and_store_32x32(qcoeff0, dequant, zero, - dqcoeff_ptr + index); - calculate_dqcoeff_and_store_32x32(qcoeff1, dequant, zero, - dqcoeff_ptr + 8 + index); - - eob0 = scan_for_eob(&qcoeff0, &qcoeff1, iscan, index, zero); - eob = _mm_max_epi16(eob, eob0); - } - - *eob_ptr = accumulate_eob(eob); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_ssse3.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_ssse3.h deleted file mode 100644 index e8d2a057..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/quantize_ssse3.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_X86_QUANTIZE_SSSE3_H_ -#define VPX_VPX_DSP_X86_QUANTIZE_SSSE3_H_ - -#include - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/x86/quantize_sse2.h" - -static INLINE void calculate_dqcoeff_and_store_32x32(const __m128i qcoeff, - const __m128i dequant, - const __m128i zero, - tran_low_t *dqcoeff) { - // Un-sign to bias rounding like C. - const __m128i coeff = _mm_abs_epi16(qcoeff); - - const __m128i sign_0 = _mm_unpacklo_epi16(zero, qcoeff); - const __m128i sign_1 = _mm_unpackhi_epi16(zero, qcoeff); - - const __m128i low = _mm_mullo_epi16(coeff, dequant); - const __m128i high = _mm_mulhi_epi16(coeff, dequant); - __m128i dqcoeff32_0 = _mm_unpacklo_epi16(low, high); - __m128i dqcoeff32_1 = _mm_unpackhi_epi16(low, high); - - // "Divide" by 2. - dqcoeff32_0 = _mm_srli_epi32(dqcoeff32_0, 1); - dqcoeff32_1 = _mm_srli_epi32(dqcoeff32_1, 1); - - dqcoeff32_0 = _mm_sign_epi32(dqcoeff32_0, sign_0); - dqcoeff32_1 = _mm_sign_epi32(dqcoeff32_1, sign_1); - -#if CONFIG_VP9_HIGHBITDEPTH - _mm_store_si128((__m128i *)(dqcoeff), dqcoeff32_0); - _mm_store_si128((__m128i *)(dqcoeff + 4), dqcoeff32_1); -#else - _mm_store_si128((__m128i *)(dqcoeff), - _mm_packs_epi32(dqcoeff32_0, dqcoeff32_1)); -#endif // CONFIG_VP9_HIGHBITDEPTH -} - -#endif // VPX_VPX_DSP_X86_QUANTIZE_SSSE3_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sad4d_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sad4d_avx2.c deleted file mode 100644 index cf711198..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sad4d_avx2.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include // AVX2 -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" - -// Note with sums[4] some versions of Visual Studio may fail due to parameter -// alignment, though the functions should be equivalent: -// error C2719: 'sums': formal parameter with requested alignment of 32 won't be -// aligned -static INLINE void calc_final_4(const __m256i *const sums /*[4]*/, - uint32_t sad_array[4]) { - const __m256i t0 = _mm256_hadd_epi32(sums[0], sums[1]); - const __m256i t1 = _mm256_hadd_epi32(sums[2], sums[3]); - const __m256i t2 = _mm256_hadd_epi32(t0, t1); - const __m128i sum = _mm_add_epi32(_mm256_castsi256_si128(t2), - _mm256_extractf128_si256(t2, 1)); - _mm_storeu_si128((__m128i *)sad_array, sum); -} - -static INLINE void sad32xhx4d_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *const ref_array[4], - int ref_stride, int h, - uint32_t sad_array[4]) { - int i; - const uint8_t *refs[4]; - __m256i sums[4]; - - refs[0] = ref_array[0]; - refs[1] = ref_array[1]; - refs[2] = ref_array[2]; - refs[3] = ref_array[3]; - sums[0] = _mm256_setzero_si256(); - sums[1] = _mm256_setzero_si256(); - sums[2] = _mm256_setzero_si256(); - sums[3] = _mm256_setzero_si256(); - - for (i = 0; i < h; i++) { - __m256i r[4]; - - // load src and all ref[] - const __m256i s = _mm256_load_si256((const __m256i *)src_ptr); - r[0] = _mm256_loadu_si256((const __m256i *)refs[0]); - r[1] = _mm256_loadu_si256((const __m256i *)refs[1]); - r[2] = _mm256_loadu_si256((const __m256i *)refs[2]); - r[3] = _mm256_loadu_si256((const __m256i *)refs[3]); - - // sum of the absolute differences between every ref[] to src - r[0] = _mm256_sad_epu8(r[0], s); - r[1] = _mm256_sad_epu8(r[1], s); - r[2] = _mm256_sad_epu8(r[2], s); - r[3] = _mm256_sad_epu8(r[3], s); - - // sum every ref[] - sums[0] = _mm256_add_epi32(sums[0], r[0]); - sums[1] = _mm256_add_epi32(sums[1], r[1]); - sums[2] = _mm256_add_epi32(sums[2], r[2]); - sums[3] = _mm256_add_epi32(sums[3], r[3]); - - src_ptr += src_stride; - refs[0] += ref_stride; - refs[1] += ref_stride; - refs[2] += ref_stride; - refs[3] += ref_stride; - } - - calc_final_4(sums, sad_array); -} - -static INLINE void sad64xhx4d_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *const ref_array[4], - int ref_stride, int h, - uint32_t sad_array[4]) { - __m256i sums[4]; - int i; - const uint8_t *refs[4]; - - refs[0] = ref_array[0]; - refs[1] = ref_array[1]; - refs[2] = ref_array[2]; - refs[3] = ref_array[3]; - sums[0] = _mm256_setzero_si256(); - sums[1] = _mm256_setzero_si256(); - sums[2] = _mm256_setzero_si256(); - sums[3] = _mm256_setzero_si256(); - - for (i = 0; i < h; i++) { - __m256i r_lo[4], r_hi[4]; - // load 64 bytes from src and all ref[] - const __m256i s_lo = _mm256_load_si256((const __m256i *)src_ptr); - const __m256i s_hi = _mm256_load_si256((const __m256i *)(src_ptr + 32)); - r_lo[0] = _mm256_loadu_si256((const __m256i *)refs[0]); - r_hi[0] = _mm256_loadu_si256((const __m256i *)(refs[0] + 32)); - r_lo[1] = _mm256_loadu_si256((const __m256i *)refs[1]); - r_hi[1] = _mm256_loadu_si256((const __m256i *)(refs[1] + 32)); - r_lo[2] = _mm256_loadu_si256((const __m256i *)refs[2]); - r_hi[2] = _mm256_loadu_si256((const __m256i *)(refs[2] + 32)); - r_lo[3] = _mm256_loadu_si256((const __m256i *)refs[3]); - r_hi[3] = _mm256_loadu_si256((const __m256i *)(refs[3] + 32)); - - // sum of the absolute differences between every ref[] to src - r_lo[0] = _mm256_sad_epu8(r_lo[0], s_lo); - r_lo[1] = _mm256_sad_epu8(r_lo[1], s_lo); - r_lo[2] = _mm256_sad_epu8(r_lo[2], s_lo); - r_lo[3] = _mm256_sad_epu8(r_lo[3], s_lo); - r_hi[0] = _mm256_sad_epu8(r_hi[0], s_hi); - r_hi[1] = _mm256_sad_epu8(r_hi[1], s_hi); - r_hi[2] = _mm256_sad_epu8(r_hi[2], s_hi); - r_hi[3] = _mm256_sad_epu8(r_hi[3], s_hi); - - // sum every ref[] - sums[0] = _mm256_add_epi32(sums[0], r_lo[0]); - sums[1] = _mm256_add_epi32(sums[1], r_lo[1]); - sums[2] = _mm256_add_epi32(sums[2], r_lo[2]); - sums[3] = _mm256_add_epi32(sums[3], r_lo[3]); - sums[0] = _mm256_add_epi32(sums[0], r_hi[0]); - sums[1] = _mm256_add_epi32(sums[1], r_hi[1]); - sums[2] = _mm256_add_epi32(sums[2], r_hi[2]); - sums[3] = _mm256_add_epi32(sums[3], r_hi[3]); - - src_ptr += src_stride; - refs[0] += ref_stride; - refs[1] += ref_stride; - refs[2] += ref_stride; - refs[3] += ref_stride; - } - - calc_final_4(sums, sad_array); -} - -#define SAD64_H(h) \ - void vpx_sad64x##h##x4d_avx2(const uint8_t *src, int src_stride, \ - const uint8_t *const ref_array[4], \ - int ref_stride, uint32_t sad_array[4]) { \ - sad64xhx4d_avx2(src, src_stride, ref_array, ref_stride, h, sad_array); \ - } - -#define SAD32_H(h) \ - void vpx_sad32x##h##x4d_avx2(const uint8_t *src, int src_stride, \ - const uint8_t *const ref_array[4], \ - int ref_stride, uint32_t sad_array[4]) { \ - sad32xhx4d_avx2(src, src_stride, ref_array, ref_stride, h, sad_array); \ - } - -SAD64_H(64) -SAD32_H(32) - -#define SADS64_H(h) \ - void vpx_sad_skip_64x##h##x4d_avx2(const uint8_t *src, int src_stride, \ - const uint8_t *const ref_array[4], \ - int ref_stride, uint32_t sad_array[4]) { \ - sad64xhx4d_avx2(src, 2 * src_stride, ref_array, 2 * ref_stride, \ - ((h) >> 1), sad_array); \ - sad_array[0] <<= 1; \ - sad_array[1] <<= 1; \ - sad_array[2] <<= 1; \ - sad_array[3] <<= 1; \ - } - -#define SADS32_H(h) \ - void vpx_sad_skip_32x##h##x4d_avx2(const uint8_t *src, int src_stride, \ - const uint8_t *const ref_array[4], \ - int ref_stride, uint32_t sad_array[4]) { \ - sad32xhx4d_avx2(src, 2 * src_stride, ref_array, 2 * ref_stride, \ - ((h) >> 1), sad_array); \ - sad_array[0] <<= 1; \ - sad_array[1] <<= 1; \ - sad_array[2] <<= 1; \ - sad_array[3] <<= 1; \ - } - -SADS64_H(64) -SADS64_H(32) - -SADS32_H(64) -SADS32_H(32) -SADS32_H(16) diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sad4d_avx512.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sad4d_avx512.c deleted file mode 100644 index cfd23fed..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sad4d_avx512.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include // AVX512 -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" - -void vpx_sad64x64x4d_avx512(const uint8_t *src_ptr, int src_stride, - const uint8_t *const ref_array[4], int ref_stride, - uint32_t sad_array[4]) { - __m512i src_reg, ref0_reg, ref1_reg, ref2_reg, ref3_reg; - __m512i sum_ref0, sum_ref1, sum_ref2, sum_ref3; - __m512i sum_mlow, sum_mhigh; - int i; - const uint8_t *ref0, *ref1, *ref2, *ref3; - - ref0 = ref_array[0]; - ref1 = ref_array[1]; - ref2 = ref_array[2]; - ref3 = ref_array[3]; - sum_ref0 = _mm512_set1_epi16(0); - sum_ref1 = _mm512_set1_epi16(0); - sum_ref2 = _mm512_set1_epi16(0); - sum_ref3 = _mm512_set1_epi16(0); - for (i = 0; i < 64; i++) { - // load src and all ref[] - src_reg = _mm512_loadu_si512((const __m512i *)src_ptr); - ref0_reg = _mm512_loadu_si512((const __m512i *)ref0); - ref1_reg = _mm512_loadu_si512((const __m512i *)ref1); - ref2_reg = _mm512_loadu_si512((const __m512i *)ref2); - ref3_reg = _mm512_loadu_si512((const __m512i *)ref3); - // sum of the absolute differences between every ref[] to src - ref0_reg = _mm512_sad_epu8(ref0_reg, src_reg); - ref1_reg = _mm512_sad_epu8(ref1_reg, src_reg); - ref2_reg = _mm512_sad_epu8(ref2_reg, src_reg); - ref3_reg = _mm512_sad_epu8(ref3_reg, src_reg); - // sum every ref[] - sum_ref0 = _mm512_add_epi32(sum_ref0, ref0_reg); - sum_ref1 = _mm512_add_epi32(sum_ref1, ref1_reg); - sum_ref2 = _mm512_add_epi32(sum_ref2, ref2_reg); - sum_ref3 = _mm512_add_epi32(sum_ref3, ref3_reg); - - src_ptr += src_stride; - ref0 += ref_stride; - ref1 += ref_stride; - ref2 += ref_stride; - ref3 += ref_stride; - } - { - __m256i sum256; - __m128i sum128; - // in sum_ref[] the result is saved in the first 4 bytes - // the other 4 bytes are zeroed. - // sum_ref1 and sum_ref3 are shifted left by 4 bytes - sum_ref1 = _mm512_bslli_epi128(sum_ref1, 4); - sum_ref3 = _mm512_bslli_epi128(sum_ref3, 4); - - // merge sum_ref0 and sum_ref1 also sum_ref2 and sum_ref3 - sum_ref0 = _mm512_or_si512(sum_ref0, sum_ref1); - sum_ref2 = _mm512_or_si512(sum_ref2, sum_ref3); - - // merge every 64 bit from each sum_ref[] - sum_mlow = _mm512_unpacklo_epi64(sum_ref0, sum_ref2); - sum_mhigh = _mm512_unpackhi_epi64(sum_ref0, sum_ref2); - - // add the low 64 bit to the high 64 bit - sum_mlow = _mm512_add_epi32(sum_mlow, sum_mhigh); - - // add the low 128 bit to the high 128 bit - sum256 = _mm256_add_epi32(_mm512_castsi512_si256(sum_mlow), - _mm512_extracti32x8_epi32(sum_mlow, 1)); - sum128 = _mm_add_epi32(_mm256_castsi256_si128(sum256), - _mm256_extractf128_si256(sum256, 1)); - - _mm_storeu_si128((__m128i *)(sad_array), sum128); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sad4d_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sad4d_sse2.asm deleted file mode 100644 index ed4ea3ef..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sad4d_sse2.asm +++ /dev/null @@ -1,278 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "third_party/x86inc/x86inc.asm" - -SECTION .text - -; PROCESS_4x2x4 first, off_{first,second}_{src,ref}, advance_at_end -%macro PROCESS_4x2x4 5-6 0 - movd m0, [srcq +%2] -%if %1 == 1 - movd m6, [ref1q+%3] - movd m4, [ref2q+%3] - movd m7, [ref3q+%3] - movd m5, [ref4q+%3] - movd m1, [srcq +%4] - movd m2, [ref1q+%5] - punpckldq m0, m1 - punpckldq m6, m2 - movd m1, [ref2q+%5] - movd m2, [ref3q+%5] - movd m3, [ref4q+%5] - punpckldq m4, m1 - punpckldq m7, m2 - punpckldq m5, m3 - movlhps m0, m0 - movlhps m6, m4 - movlhps m7, m5 - psadbw m6, m0 - psadbw m7, m0 -%else - movd m1, [ref1q+%3] - movd m5, [ref1q+%5] - movd m2, [ref2q+%3] - movd m4, [ref2q+%5] - punpckldq m1, m5 - punpckldq m2, m4 - movd m3, [ref3q+%3] - movd m5, [ref3q+%5] - punpckldq m3, m5 - movd m4, [ref4q+%3] - movd m5, [ref4q+%5] - punpckldq m4, m5 - movd m5, [srcq +%4] - punpckldq m0, m5 - movlhps m0, m0 - movlhps m1, m2 - movlhps m3, m4 - psadbw m1, m0 - psadbw m3, m0 - paddd m6, m1 - paddd m7, m3 -%endif -%if %6 == 1 - lea srcq, [srcq +src_strideq*2] - lea ref1q, [ref1q+ref_strideq*2] - lea ref2q, [ref2q+ref_strideq*2] - lea ref3q, [ref3q+ref_strideq*2] - lea ref4q, [ref4q+ref_strideq*2] -%endif -%endmacro - -; PROCESS_8x2x4 first, off_{first,second}_{src,ref}, advance_at_end -%macro PROCESS_8x2x4 5-6 0 - movh m0, [srcq +%2] -%if %1 == 1 - movh m4, [ref1q+%3] - movh m5, [ref2q+%3] - movh m6, [ref3q+%3] - movh m7, [ref4q+%3] - movhps m0, [srcq +%4] - movhps m4, [ref1q+%5] - movhps m5, [ref2q+%5] - movhps m6, [ref3q+%5] - movhps m7, [ref4q+%5] - psadbw m4, m0 - psadbw m5, m0 - psadbw m6, m0 - psadbw m7, m0 -%else - movh m1, [ref1q+%3] - movh m2, [ref2q+%3] - movh m3, [ref3q+%3] - movhps m0, [srcq +%4] - movhps m1, [ref1q+%5] - movhps m2, [ref2q+%5] - movhps m3, [ref3q+%5] - psadbw m1, m0 - psadbw m2, m0 - psadbw m3, m0 - paddd m4, m1 - movh m1, [ref4q+%3] - movhps m1, [ref4q+%5] - paddd m5, m2 - paddd m6, m3 - psadbw m1, m0 - paddd m7, m1 -%endif -%if %6 == 1 - lea srcq, [srcq +src_strideq*2] - lea ref1q, [ref1q+ref_strideq*2] - lea ref2q, [ref2q+ref_strideq*2] - lea ref3q, [ref3q+ref_strideq*2] - lea ref4q, [ref4q+ref_strideq*2] -%endif -%endmacro - -; PROCESS_16x2x4 first, off_{first,second}_{src,ref}, advance_at_end -%macro PROCESS_16x2x4 5-6 0 - ; 1st 16 px - mova m0, [srcq +%2] -%if %1 == 1 - movu m4, [ref1q+%3] - movu m5, [ref2q+%3] - movu m6, [ref3q+%3] - movu m7, [ref4q+%3] - psadbw m4, m0 - psadbw m5, m0 - psadbw m6, m0 - psadbw m7, m0 -%else - movu m1, [ref1q+%3] - movu m2, [ref2q+%3] - movu m3, [ref3q+%3] - psadbw m1, m0 - psadbw m2, m0 - psadbw m3, m0 - paddd m4, m1 - movu m1, [ref4q+%3] - paddd m5, m2 - paddd m6, m3 - psadbw m1, m0 - paddd m7, m1 -%endif - - ; 2nd 16 px - mova m0, [srcq +%4] - movu m1, [ref1q+%5] - movu m2, [ref2q+%5] - movu m3, [ref3q+%5] - psadbw m1, m0 - psadbw m2, m0 - psadbw m3, m0 - paddd m4, m1 - movu m1, [ref4q+%5] - paddd m5, m2 - paddd m6, m3 -%if %6 == 1 - lea srcq, [srcq +src_strideq*2] - lea ref1q, [ref1q+ref_strideq*2] - lea ref2q, [ref2q+ref_strideq*2] - lea ref3q, [ref3q+ref_strideq*2] - lea ref4q, [ref4q+ref_strideq*2] -%endif - psadbw m1, m0 - paddd m7, m1 -%endmacro - -; PROCESS_32x2x4 first, off_{first,second}_{src,ref}, advance_at_end -%macro PROCESS_32x2x4 5-6 0 - PROCESS_16x2x4 %1, %2, %3, %2 + 16, %3 + 16 - PROCESS_16x2x4 0, %4, %5, %4 + 16, %5 + 16, %6 -%endmacro - -; PROCESS_64x2x4 first, off_{first,second}_{src,ref}, advance_at_end -%macro PROCESS_64x2x4 5-6 0 - PROCESS_32x2x4 %1, %2, %3, %2 + 32, %3 + 32 - PROCESS_32x2x4 0, %4, %5, %4 + 32, %5 + 32, %6 -%endmacro - -; void vpx_sadNxNx4d_sse2(uint8_t *src, int src_stride, -; uint8_t *ref[4], int ref_stride, -; uint32_t res[4]); -; where NxN = 64x64, 32x32, 16x16, 16x8, 8x16, 8x8, 8x4, 4x8 and 4x4 -%macro SADNXN4D 2-3 0 -%if %3 == 1 ; skip rows -%if UNIX64 -cglobal sad_skip_%1x%2x4d, 5, 8, 8, src, src_stride, ref1, ref_stride, \ - res, ref2, ref3, ref4 -%else -cglobal sad_skip_%1x%2x4d, 4, 7, 8, src, src_stride, ref1, ref_stride, \ - ref2, ref3, ref4 -%endif -%else ; normal sad -%if UNIX64 -cglobal sad%1x%2x4d, 5, 8, 8, src, src_stride, ref1, ref_stride, \ - res, ref2, ref3, ref4 -%else -cglobal sad%1x%2x4d, 4, 7, 8, src, src_stride, ref1, ref_stride, \ - ref2, ref3, ref4 -%endif -%endif -%if %3 == 1 - lea src_strided, [2*src_strided] - lea ref_strided, [2*ref_strided] -%endif - movsxdifnidn src_strideq, src_strided - movsxdifnidn ref_strideq, ref_strided - mov ref2q, [ref1q+gprsize*1] - mov ref3q, [ref1q+gprsize*2] - mov ref4q, [ref1q+gprsize*3] - mov ref1q, [ref1q+gprsize*0] - - PROCESS_%1x2x4 1, 0, 0, src_strideq, ref_strideq, 1 -%if %3 == 1 ; downsample number of rows by 2 -%define num_rep (%2-8)/4 -%else -%define num_rep (%2-4)/2 -%endif -%rep num_rep - PROCESS_%1x2x4 0, 0, 0, src_strideq, ref_strideq, 1 -%endrep -%undef num_rep - PROCESS_%1x2x4 0, 0, 0, src_strideq, ref_strideq, 0 - -%if %1 > 4 - pslldq m5, 4 - pslldq m7, 4 - por m4, m5 - por m6, m7 - mova m5, m4 - mova m7, m6 - punpcklqdq m4, m6 - punpckhqdq m5, m7 - movifnidn r4, r4mp - paddd m4, m5 -%if %3 == 1 - pslld m4, 1 -%endif - movu [r4], m4 - RET -%else - movifnidn r4, r4mp - pshufd m6, m6, 0x08 - pshufd m7, m7, 0x08 -%if %3 == 1 - pslld m6, 1 - pslld m7, 1 -%endif - movq [r4+0], m6 - movq [r4+8], m7 - RET -%endif -%endmacro - -INIT_XMM sse2 -SADNXN4D 64, 64 -SADNXN4D 64, 32 -SADNXN4D 32, 64 -SADNXN4D 32, 32 -SADNXN4D 32, 16 -SADNXN4D 16, 32 -SADNXN4D 16, 16 -SADNXN4D 16, 8 -SADNXN4D 8, 16 -SADNXN4D 8, 8 -SADNXN4D 8, 4 -SADNXN4D 4, 8 -SADNXN4D 4, 4 - -SADNXN4D 64, 64, 1 -SADNXN4D 64, 32, 1 -SADNXN4D 32, 64, 1 -SADNXN4D 32, 32, 1 -SADNXN4D 32, 16, 1 -SADNXN4D 16, 32, 1 -SADNXN4D 16, 16, 1 -SADNXN4D 16, 8, 1 -SADNXN4D 8, 16, 1 -SADNXN4D 8, 8, 1 -SADNXN4D 4, 8, 1 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sad_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sad_avx2.c deleted file mode 100644 index e00494d7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sad_avx2.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include "./vpx_dsp_rtcd.h" -#include "vpx_ports/mem.h" - -static INLINE unsigned int sad64xh_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - int h) { - int i, res; - __m256i sad1_reg, sad2_reg, ref1_reg, ref2_reg; - __m256i sum_sad = _mm256_setzero_si256(); - __m256i sum_sad_h; - __m128i sum_sad128; - for (i = 0; i < h; i++) { - ref1_reg = _mm256_loadu_si256((__m256i const *)ref_ptr); - ref2_reg = _mm256_loadu_si256((__m256i const *)(ref_ptr + 32)); - sad1_reg = - _mm256_sad_epu8(ref1_reg, _mm256_loadu_si256((__m256i const *)src_ptr)); - sad2_reg = _mm256_sad_epu8( - ref2_reg, _mm256_loadu_si256((__m256i const *)(src_ptr + 32))); - sum_sad = _mm256_add_epi32(sum_sad, _mm256_add_epi32(sad1_reg, sad2_reg)); - ref_ptr += ref_stride; - src_ptr += src_stride; - } - sum_sad_h = _mm256_srli_si256(sum_sad, 8); - sum_sad = _mm256_add_epi32(sum_sad, sum_sad_h); - sum_sad128 = _mm256_extracti128_si256(sum_sad, 1); - sum_sad128 = _mm_add_epi32(_mm256_castsi256_si128(sum_sad), sum_sad128); - res = _mm_cvtsi128_si32(sum_sad128); - return res; -} - -static INLINE unsigned int sad32xh_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - int h) { - int i, res; - __m256i sad1_reg, sad2_reg, ref1_reg, ref2_reg; - __m256i sum_sad = _mm256_setzero_si256(); - __m256i sum_sad_h; - __m128i sum_sad128; - const int ref2_stride = ref_stride << 1; - const int src2_stride = src_stride << 1; - const int max = h >> 1; - for (i = 0; i < max; i++) { - ref1_reg = _mm256_loadu_si256((__m256i const *)ref_ptr); - ref2_reg = _mm256_loadu_si256((__m256i const *)(ref_ptr + ref_stride)); - sad1_reg = - _mm256_sad_epu8(ref1_reg, _mm256_loadu_si256((__m256i const *)src_ptr)); - sad2_reg = _mm256_sad_epu8( - ref2_reg, _mm256_loadu_si256((__m256i const *)(src_ptr + src_stride))); - sum_sad = _mm256_add_epi32(sum_sad, _mm256_add_epi32(sad1_reg, sad2_reg)); - ref_ptr += ref2_stride; - src_ptr += src2_stride; - } - sum_sad_h = _mm256_srli_si256(sum_sad, 8); - sum_sad = _mm256_add_epi32(sum_sad, sum_sad_h); - sum_sad128 = _mm256_extracti128_si256(sum_sad, 1); - sum_sad128 = _mm_add_epi32(_mm256_castsi256_si128(sum_sad), sum_sad128); - res = _mm_cvtsi128_si32(sum_sad128); - return res; -} - -#define FSAD64_H(h) \ - unsigned int vpx_sad64x##h##_avx2(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *ref_ptr, int ref_stride) { \ - return sad64xh_avx2(src_ptr, src_stride, ref_ptr, ref_stride, h); \ - } - -#define FSADS64_H(h) \ - unsigned int vpx_sad_skip_64x##h##_avx2( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride) { \ - return 2 * sad64xh_avx2(src_ptr, src_stride * 2, ref_ptr, ref_stride * 2, \ - h / 2); \ - } - -#define FSAD32_H(h) \ - unsigned int vpx_sad32x##h##_avx2(const uint8_t *src_ptr, int src_stride, \ - const uint8_t *ref_ptr, int ref_stride) { \ - return sad32xh_avx2(src_ptr, src_stride, ref_ptr, ref_stride, h); \ - } - -#define FSADS32_H(h) \ - unsigned int vpx_sad_skip_32x##h##_avx2( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride) { \ - return 2 * sad32xh_avx2(src_ptr, src_stride * 2, ref_ptr, ref_stride * 2, \ - h / 2); \ - } - -#define FSAD64 \ - FSAD64_H(64) \ - FSAD64_H(32) \ - FSADS64_H(64) \ - FSADS64_H(32) - -#define FSAD32 \ - FSAD32_H(64) \ - FSAD32_H(32) \ - FSAD32_H(16) \ - FSADS32_H(64) \ - FSADS32_H(32) \ - FSADS32_H(16) - -FSAD64 -FSAD32 - -#undef FSAD64 -#undef FSAD32 -#undef FSAD64_H -#undef FSAD32_H -#undef FSADS64_H -#undef FSADS32_H - -#define FSADAVG64_H(h) \ - unsigned int vpx_sad64x##h##_avg_avx2( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, const uint8_t *second_pred) { \ - int i; \ - __m256i sad1_reg, sad2_reg, ref1_reg, ref2_reg; \ - __m256i sum_sad = _mm256_setzero_si256(); \ - __m256i sum_sad_h; \ - __m128i sum_sad128; \ - for (i = 0; i < h; i++) { \ - ref1_reg = _mm256_loadu_si256((__m256i const *)ref_ptr); \ - ref2_reg = _mm256_loadu_si256((__m256i const *)(ref_ptr + 32)); \ - ref1_reg = _mm256_avg_epu8( \ - ref1_reg, _mm256_loadu_si256((__m256i const *)second_pred)); \ - ref2_reg = _mm256_avg_epu8( \ - ref2_reg, _mm256_loadu_si256((__m256i const *)(second_pred + 32))); \ - sad1_reg = _mm256_sad_epu8( \ - ref1_reg, _mm256_loadu_si256((__m256i const *)src_ptr)); \ - sad2_reg = _mm256_sad_epu8( \ - ref2_reg, _mm256_loadu_si256((__m256i const *)(src_ptr + 32))); \ - sum_sad = \ - _mm256_add_epi32(sum_sad, _mm256_add_epi32(sad1_reg, sad2_reg)); \ - ref_ptr += ref_stride; \ - src_ptr += src_stride; \ - second_pred += 64; \ - } \ - sum_sad_h = _mm256_srli_si256(sum_sad, 8); \ - sum_sad = _mm256_add_epi32(sum_sad, sum_sad_h); \ - sum_sad128 = _mm256_extracti128_si256(sum_sad, 1); \ - sum_sad128 = _mm_add_epi32(_mm256_castsi256_si128(sum_sad), sum_sad128); \ - return (unsigned int)_mm_cvtsi128_si32(sum_sad128); \ - } - -#define FSADAVG32_H(h) \ - unsigned int vpx_sad32x##h##_avg_avx2( \ - const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \ - int ref_stride, const uint8_t *second_pred) { \ - int i; \ - __m256i sad1_reg, sad2_reg, ref1_reg, ref2_reg; \ - __m256i sum_sad = _mm256_setzero_si256(); \ - __m256i sum_sad_h; \ - __m128i sum_sad128; \ - int ref2_stride = ref_stride << 1; \ - int src2_stride = src_stride << 1; \ - int max = h >> 1; \ - for (i = 0; i < max; i++) { \ - ref1_reg = _mm256_loadu_si256((__m256i const *)ref_ptr); \ - ref2_reg = _mm256_loadu_si256((__m256i const *)(ref_ptr + ref_stride)); \ - ref1_reg = _mm256_avg_epu8( \ - ref1_reg, _mm256_loadu_si256((__m256i const *)second_pred)); \ - ref2_reg = _mm256_avg_epu8( \ - ref2_reg, _mm256_loadu_si256((__m256i const *)(second_pred + 32))); \ - sad1_reg = _mm256_sad_epu8( \ - ref1_reg, _mm256_loadu_si256((__m256i const *)src_ptr)); \ - sad2_reg = _mm256_sad_epu8( \ - ref2_reg, \ - _mm256_loadu_si256((__m256i const *)(src_ptr + src_stride))); \ - sum_sad = \ - _mm256_add_epi32(sum_sad, _mm256_add_epi32(sad1_reg, sad2_reg)); \ - ref_ptr += ref2_stride; \ - src_ptr += src2_stride; \ - second_pred += 64; \ - } \ - sum_sad_h = _mm256_srli_si256(sum_sad, 8); \ - sum_sad = _mm256_add_epi32(sum_sad, sum_sad_h); \ - sum_sad128 = _mm256_extracti128_si256(sum_sad, 1); \ - sum_sad128 = _mm_add_epi32(_mm256_castsi256_si128(sum_sad), sum_sad128); \ - return (unsigned int)_mm_cvtsi128_si32(sum_sad128); \ - } - -#define FSADAVG64 \ - FSADAVG64_H(64) \ - FSADAVG64_H(32) - -#define FSADAVG32 \ - FSADAVG32_H(64) \ - FSADAVG32_H(32) \ - FSADAVG32_H(16) - -FSADAVG64 -FSADAVG32 - -#undef FSADAVG64 -#undef FSADAVG32 -#undef FSADAVG64_H -#undef FSADAVG32_H diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sad_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sad_sse2.asm deleted file mode 100644 index 627e463b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sad_sse2.asm +++ /dev/null @@ -1,332 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "third_party/x86inc/x86inc.asm" - -SECTION .text - -; Macro Arguments -; Arg 1: Width -; Arg 2: Height -; Arg 3: Number of general purpose registers -; Arg 4: Type of function: if 0, normal sad; if 1, avg; if 2, skip rows -%macro SAD_FN 4 -%if %4 == 0 ; normal sad -%if %3 == 5 -cglobal sad%1x%2, 4, %3, 5, src, src_stride, ref, ref_stride, n_rows -%else ; %3 == 7 -cglobal sad%1x%2, 4, %3, 6, src, src_stride, ref, ref_stride, \ - src_stride3, ref_stride3, n_rows -%endif ; %3 == 5/7 - -%elif %4 == 2 ; skip -%if %3 == 5 -cglobal sad_skip_%1x%2, 4, %3, 5, src, src_stride, ref, ref_stride, n_rows -%else ; %3 == 7 -cglobal sad_skip_%1x%2, 4, %3, 6, src, src_stride, ref, ref_stride, \ - src_stride3, ref_stride3, n_rows -%endif ; %3 == 5/7 - -%else -%if %3 == 5 -cglobal sad%1x%2_avg, 5, 1 + %3, 5, src, src_stride, ref, ref_stride, \ - second_pred, n_rows -%else ; %3 == 7 -cglobal sad%1x%2_avg, 5, VPX_ARCH_X86_64 + %3, 6, src, src_stride, \ - ref, ref_stride, \ - second_pred, \ - src_stride3, ref_stride3 -%if VPX_ARCH_X86_64 -%define n_rowsd r7d -%else ; x86-32 -%define n_rowsd dword r0m -%endif ; x86-32/64 -%endif ; %3 == 5/7 -%endif ; sad/avg/skip -%if %4 == 2; skip rows so double the stride -lea src_strided, [src_strided*2] -lea ref_strided, [ref_strided*2] -%endif ; %4 skip - movsxdifnidn src_strideq, src_strided - movsxdifnidn ref_strideq, ref_strided -%if %3 == 7 - lea src_stride3q, [src_strideq*3] - lea ref_stride3q, [ref_strideq*3] -%endif ; %3 == 7 -%endmacro - -; unsigned int vpx_sad64x64_sse2(uint8_t *src, int src_stride, -; uint8_t *ref, int ref_stride); -%macro SAD64XN 1-2 0 - SAD_FN 64, %1, 5, %2 -%if %2 == 2 - mov n_rowsd, %1/2 -%else - mov n_rowsd, %1 -%endif - pxor m0, m0 -.loop: - movu m1, [refq] - movu m2, [refq+16] - movu m3, [refq+32] - movu m4, [refq+48] -%if %2 == 1 - pavgb m1, [second_predq+mmsize*0] - pavgb m2, [second_predq+mmsize*1] - pavgb m3, [second_predq+mmsize*2] - pavgb m4, [second_predq+mmsize*3] - lea second_predq, [second_predq+mmsize*4] -%endif - psadbw m1, [srcq] - psadbw m2, [srcq+16] - psadbw m3, [srcq+32] - psadbw m4, [srcq+48] - paddd m1, m2 - paddd m3, m4 - add refq, ref_strideq - paddd m0, m1 - add srcq, src_strideq - paddd m0, m3 - dec n_rowsd - jg .loop - - movhlps m1, m0 - paddd m0, m1 -%if %2 == 2 ; we skipped rows, so now we need to double the sad - pslld m0, 1 -%endif - movd eax, m0 - RET -%endmacro - -INIT_XMM sse2 -SAD64XN 64 ; sad64x64_sse2 -SAD64XN 32 ; sad64x32_sse2 -SAD64XN 64, 1 ; sad64x64_avg_sse2 -SAD64XN 32, 1 ; sad64x32_avg_sse2 -SAD64XN 64, 2 ; sad64x64_skip_sse2 -SAD64XN 32, 2 ; sad64x32_skip_sse2 - -; unsigned int vpx_sad32x32_sse2(uint8_t *src, int src_stride, -; uint8_t *ref, int ref_stride); -%macro SAD32XN 1-2 0 - SAD_FN 32, %1, 5, %2 -%if %2 == 2 - mov n_rowsd, %1/4 -%else - mov n_rowsd, %1/2 -%endif - pxor m0, m0 -.loop: - movu m1, [refq] - movu m2, [refq+16] - movu m3, [refq+ref_strideq] - movu m4, [refq+ref_strideq+16] -%if %2 == 1 - pavgb m1, [second_predq+mmsize*0] - pavgb m2, [second_predq+mmsize*1] - pavgb m3, [second_predq+mmsize*2] - pavgb m4, [second_predq+mmsize*3] - lea second_predq, [second_predq+mmsize*4] -%endif - psadbw m1, [srcq] - psadbw m2, [srcq+16] - psadbw m3, [srcq+src_strideq] - psadbw m4, [srcq+src_strideq+16] - paddd m1, m2 - paddd m3, m4 - lea refq, [refq+ref_strideq*2] - paddd m0, m1 - lea srcq, [srcq+src_strideq*2] - paddd m0, m3 - dec n_rowsd - jg .loop - - movhlps m1, m0 - paddd m0, m1 -%if %2 == 2 ; we skipped rows, so now we need to double the sad - pslld m0, 1 -%endif - movd eax, m0 - RET -%endmacro - -INIT_XMM sse2 -SAD32XN 64 ; sad32x64_sse2 -SAD32XN 32 ; sad32x32_sse2 -SAD32XN 16 ; sad32x16_sse2 -SAD32XN 64, 1 ; sad32x64_avg_sse2 -SAD32XN 32, 1 ; sad32x32_avg_sse2 -SAD32XN 16, 1 ; sad32x16_avg_sse2 -SAD32XN 64, 2 ; sad32x64_skip_sse2 -SAD32XN 32, 2 ; sad32x32_skip_sse2 -SAD32XN 16, 2 ; sad32x16_skip_sse2 - -; unsigned int vpx_sad16x{8,16}_sse2(uint8_t *src, int src_stride, -; uint8_t *ref, int ref_stride); -%macro SAD16XN 1-2 0 - SAD_FN 16, %1, 7, %2 -%if %2 == 2 - mov n_rowsd, %1/8 -%else - mov n_rowsd, %1/4 -%endif - pxor m0, m0 - -.loop: - movu m1, [refq] - movu m2, [refq+ref_strideq] - movu m3, [refq+ref_strideq*2] - movu m4, [refq+ref_stride3q] -%if %2 == 1 - pavgb m1, [second_predq+mmsize*0] - pavgb m2, [second_predq+mmsize*1] - pavgb m3, [second_predq+mmsize*2] - pavgb m4, [second_predq+mmsize*3] - lea second_predq, [second_predq+mmsize*4] -%endif - psadbw m1, [srcq] - psadbw m2, [srcq+src_strideq] - psadbw m3, [srcq+src_strideq*2] - psadbw m4, [srcq+src_stride3q] - paddd m1, m2 - paddd m3, m4 - lea refq, [refq+ref_strideq*4] - paddd m0, m1 - lea srcq, [srcq+src_strideq*4] - paddd m0, m3 - dec n_rowsd - jg .loop - - movhlps m1, m0 - paddd m0, m1 -%if %2 == 2 ; we skipped rows, so now we need to double the sad - pslld m0, 1 -%endif - movd eax, m0 - RET -%endmacro - -INIT_XMM sse2 -SAD16XN 32 ; sad16x32_sse2 -SAD16XN 16 ; sad16x16_sse2 -SAD16XN 8 ; sad16x8_sse2 -SAD16XN 32, 1 ; sad16x32_avg_sse2 -SAD16XN 16, 1 ; sad16x16_avg_sse2 -SAD16XN 8, 1 ; sad16x8_avg_sse2 -SAD16XN 32, 2 ; sad16x32_skip_sse2 -SAD16XN 16, 2 ; sad16x16_skip_sse2 -SAD16XN 8, 2 ; sad16x8_skip_sse2 - -; unsigned int vpx_sad8x{8,16}_sse2(uint8_t *src, int src_stride, -; uint8_t *ref, int ref_stride); -%macro SAD8XN 1-2 0 - SAD_FN 8, %1, 7, %2 -%if %2 == 2 - mov n_rowsd, %1/8 -%else - mov n_rowsd, %1/4 -%endif - pxor m0, m0 - -.loop: - movh m1, [refq] - movhps m1, [refq+ref_strideq] - movh m2, [refq+ref_strideq*2] - movhps m2, [refq+ref_stride3q] -%if %2 == 1 - pavgb m1, [second_predq+mmsize*0] - pavgb m2, [second_predq+mmsize*1] - lea second_predq, [second_predq+mmsize*2] -%endif - movh m3, [srcq] - movhps m3, [srcq+src_strideq] - movh m4, [srcq+src_strideq*2] - movhps m4, [srcq+src_stride3q] - psadbw m1, m3 - psadbw m2, m4 - lea refq, [refq+ref_strideq*4] - paddd m0, m1 - lea srcq, [srcq+src_strideq*4] - paddd m0, m2 - dec n_rowsd - jg .loop - - movhlps m1, m0 - paddd m0, m1 -%if %2 == 2 ; we skipped rows, so now we need to double the sad - pslld m0, 1 -%endif - movd eax, m0 - RET -%endmacro - -INIT_XMM sse2 -SAD8XN 16 ; sad8x16_sse2 -SAD8XN 8 ; sad8x8_sse2 -SAD8XN 4 ; sad8x4_sse2 -SAD8XN 16, 1 ; sad8x16_avg_sse2 -SAD8XN 8, 1 ; sad8x8_avg_sse2 -SAD8XN 4, 1 ; sad8x4_avg_sse2 -SAD8XN 16, 2 ; sad8x16_skip_sse2 -SAD8XN 8, 2 ; sad8x8_skip_sse2 - -; unsigned int vpx_sad4x{4, 8}_sse2(uint8_t *src, int src_stride, -; uint8_t *ref, int ref_stride); -%macro SAD4XN 1-2 0 - SAD_FN 4, %1, 7, %2 -%if %2 == 2 - mov n_rowsd, %1/8 -%else - mov n_rowsd, %1/4 -%endif - pxor m0, m0 - -.loop: - movd m1, [refq] - movd m2, [refq+ref_strideq] - movd m3, [refq+ref_strideq*2] - movd m4, [refq+ref_stride3q] - punpckldq m1, m2 - punpckldq m3, m4 - movlhps m1, m3 -%if %2 == 1 - pavgb m1, [second_predq+mmsize*0] - lea second_predq, [second_predq+mmsize*1] -%endif - movd m2, [srcq] - movd m5, [srcq+src_strideq] - movd m4, [srcq+src_strideq*2] - movd m3, [srcq+src_stride3q] - punpckldq m2, m5 - punpckldq m4, m3 - movlhps m2, m4 - psadbw m1, m2 - lea refq, [refq+ref_strideq*4] - paddd m0, m1 - lea srcq, [srcq+src_strideq*4] - dec n_rowsd - jg .loop - - movhlps m1, m0 - paddd m0, m1 -%if %2 == 2 ; we skipped rows, so now we need to double the sad - pslld m0, 1 -%endif - movd eax, m0 - RET -%endmacro - -INIT_XMM sse2 -SAD4XN 8 ; sad4x8_sse -SAD4XN 4 ; sad4x4_sse -SAD4XN 8, 1 ; sad4x8_avg_sse -SAD4XN 4, 1 ; sad4x4_avg_sse -SAD4XN 8, 2 ; sad4x8_skip_sse diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sse_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sse_avx2.c deleted file mode 100644 index dfe45b61..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sse_avx2.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx_ports/mem.h" -#include "vpx_dsp/x86/mem_sse2.h" - -static INLINE void sse_w32_avx2(__m256i *sum, const uint8_t *a, - const uint8_t *b) { - const __m256i v_a0 = _mm256_loadu_si256((const __m256i *)a); - const __m256i v_b0 = _mm256_loadu_si256((const __m256i *)b); - const __m256i zero = _mm256_setzero_si256(); - const __m256i v_a00_w = _mm256_unpacklo_epi8(v_a0, zero); - const __m256i v_a01_w = _mm256_unpackhi_epi8(v_a0, zero); - const __m256i v_b00_w = _mm256_unpacklo_epi8(v_b0, zero); - const __m256i v_b01_w = _mm256_unpackhi_epi8(v_b0, zero); - const __m256i v_d00_w = _mm256_sub_epi16(v_a00_w, v_b00_w); - const __m256i v_d01_w = _mm256_sub_epi16(v_a01_w, v_b01_w); - *sum = _mm256_add_epi32(*sum, _mm256_madd_epi16(v_d00_w, v_d00_w)); - *sum = _mm256_add_epi32(*sum, _mm256_madd_epi16(v_d01_w, v_d01_w)); -} - -static INLINE int64_t summary_all_avx2(const __m256i *sum_all) { - int64_t sum; - __m256i zero = _mm256_setzero_si256(); - const __m256i sum0_4x64 = _mm256_unpacklo_epi32(*sum_all, zero); - const __m256i sum1_4x64 = _mm256_unpackhi_epi32(*sum_all, zero); - const __m256i sum_4x64 = _mm256_add_epi64(sum0_4x64, sum1_4x64); - const __m128i sum_2x64 = _mm_add_epi64(_mm256_castsi256_si128(sum_4x64), - _mm256_extracti128_si256(sum_4x64, 1)); - const __m128i sum_1x64 = _mm_add_epi64(sum_2x64, _mm_srli_si128(sum_2x64, 8)); - _mm_storel_epi64((__m128i *)&sum, sum_1x64); - return sum; -} - -#if CONFIG_VP9_HIGHBITDEPTH -static INLINE void summary_32_avx2(const __m256i *sum32, __m256i *sum) { - const __m256i sum0_4x64 = - _mm256_cvtepu32_epi64(_mm256_castsi256_si128(*sum32)); - const __m256i sum1_4x64 = - _mm256_cvtepu32_epi64(_mm256_extracti128_si256(*sum32, 1)); - const __m256i sum_4x64 = _mm256_add_epi64(sum0_4x64, sum1_4x64); - *sum = _mm256_add_epi64(*sum, sum_4x64); -} - -static INLINE int64_t summary_4x64_avx2(const __m256i sum_4x64) { - int64_t sum; - const __m128i sum_2x64 = _mm_add_epi64(_mm256_castsi256_si128(sum_4x64), - _mm256_extracti128_si256(sum_4x64, 1)); - const __m128i sum_1x64 = _mm_add_epi64(sum_2x64, _mm_srli_si128(sum_2x64, 8)); - - _mm_storel_epi64((__m128i *)&sum, sum_1x64); - return sum; -} -#endif - -static INLINE void sse_w4x4_avx2(const uint8_t *a, int a_stride, - const uint8_t *b, int b_stride, __m256i *sum) { - const __m128i v_a0 = load_unaligned_u32(a); - const __m128i v_a1 = load_unaligned_u32(a + a_stride); - const __m128i v_a2 = load_unaligned_u32(a + a_stride * 2); - const __m128i v_a3 = load_unaligned_u32(a + a_stride * 3); - const __m128i v_b0 = load_unaligned_u32(b); - const __m128i v_b1 = load_unaligned_u32(b + b_stride); - const __m128i v_b2 = load_unaligned_u32(b + b_stride * 2); - const __m128i v_b3 = load_unaligned_u32(b + b_stride * 3); - const __m128i v_a0123 = _mm_unpacklo_epi64(_mm_unpacklo_epi32(v_a0, v_a1), - _mm_unpacklo_epi32(v_a2, v_a3)); - const __m128i v_b0123 = _mm_unpacklo_epi64(_mm_unpacklo_epi32(v_b0, v_b1), - _mm_unpacklo_epi32(v_b2, v_b3)); - const __m256i v_a_w = _mm256_cvtepu8_epi16(v_a0123); - const __m256i v_b_w = _mm256_cvtepu8_epi16(v_b0123); - const __m256i v_d_w = _mm256_sub_epi16(v_a_w, v_b_w); - *sum = _mm256_add_epi32(*sum, _mm256_madd_epi16(v_d_w, v_d_w)); -} - -static INLINE void sse_w8x2_avx2(const uint8_t *a, int a_stride, - const uint8_t *b, int b_stride, __m256i *sum) { - const __m128i v_a0 = _mm_loadl_epi64((const __m128i *)a); - const __m128i v_a1 = _mm_loadl_epi64((const __m128i *)(a + a_stride)); - const __m128i v_b0 = _mm_loadl_epi64((const __m128i *)b); - const __m128i v_b1 = _mm_loadl_epi64((const __m128i *)(b + b_stride)); - const __m256i v_a_w = _mm256_cvtepu8_epi16(_mm_unpacklo_epi64(v_a0, v_a1)); - const __m256i v_b_w = _mm256_cvtepu8_epi16(_mm_unpacklo_epi64(v_b0, v_b1)); - const __m256i v_d_w = _mm256_sub_epi16(v_a_w, v_b_w); - *sum = _mm256_add_epi32(*sum, _mm256_madd_epi16(v_d_w, v_d_w)); -} - -int64_t vpx_sse_avx2(const uint8_t *a, int a_stride, const uint8_t *b, - int b_stride, int width, int height) { - int32_t y = 0; - int64_t sse = 0; - __m256i sum = _mm256_setzero_si256(); - __m256i zero = _mm256_setzero_si256(); - switch (width) { - case 4: - do { - sse_w4x4_avx2(a, a_stride, b, b_stride, &sum); - a += a_stride << 2; - b += b_stride << 2; - y += 4; - } while (y < height); - sse = summary_all_avx2(&sum); - break; - case 8: - do { - sse_w8x2_avx2(a, a_stride, b, b_stride, &sum); - a += a_stride << 1; - b += b_stride << 1; - y += 2; - } while (y < height); - sse = summary_all_avx2(&sum); - break; - case 16: - do { - const __m128i v_a0 = _mm_loadu_si128((const __m128i *)a); - const __m128i v_a1 = _mm_loadu_si128((const __m128i *)(a + a_stride)); - const __m128i v_b0 = _mm_loadu_si128((const __m128i *)b); - const __m128i v_b1 = _mm_loadu_si128((const __m128i *)(b + b_stride)); - const __m256i v_a = - _mm256_insertf128_si256(_mm256_castsi128_si256(v_a0), v_a1, 0x01); - const __m256i v_b = - _mm256_insertf128_si256(_mm256_castsi128_si256(v_b0), v_b1, 0x01); - const __m256i v_al = _mm256_unpacklo_epi8(v_a, zero); - const __m256i v_au = _mm256_unpackhi_epi8(v_a, zero); - const __m256i v_bl = _mm256_unpacklo_epi8(v_b, zero); - const __m256i v_bu = _mm256_unpackhi_epi8(v_b, zero); - const __m256i v_asub = _mm256_sub_epi16(v_al, v_bl); - const __m256i v_bsub = _mm256_sub_epi16(v_au, v_bu); - const __m256i temp = - _mm256_add_epi32(_mm256_madd_epi16(v_asub, v_asub), - _mm256_madd_epi16(v_bsub, v_bsub)); - sum = _mm256_add_epi32(sum, temp); - a += a_stride << 1; - b += b_stride << 1; - y += 2; - } while (y < height); - sse = summary_all_avx2(&sum); - break; - case 32: - do { - sse_w32_avx2(&sum, a, b); - a += a_stride; - b += b_stride; - y += 1; - } while (y < height); - sse = summary_all_avx2(&sum); - break; - case 64: - do { - sse_w32_avx2(&sum, a, b); - sse_w32_avx2(&sum, a + 32, b + 32); - a += a_stride; - b += b_stride; - y += 1; - } while (y < height); - sse = summary_all_avx2(&sum); - break; - default: - if ((width & 0x07) == 0) { - do { - int i = 0; - do { - sse_w8x2_avx2(a + i, a_stride, b + i, b_stride, &sum); - i += 8; - } while (i < width); - a += a_stride << 1; - b += b_stride << 1; - y += 2; - } while (y < height); - } else { - do { - int i = 0; - do { - const uint8_t *a2; - const uint8_t *b2; - sse_w8x2_avx2(a + i, a_stride, b + i, b_stride, &sum); - a2 = a + i + (a_stride << 1); - b2 = b + i + (b_stride << 1); - sse_w8x2_avx2(a2, a_stride, b2, b_stride, &sum); - i += 8; - } while (i + 4 < width); - sse_w4x4_avx2(a + i, a_stride, b + i, b_stride, &sum); - a += a_stride << 2; - b += b_stride << 2; - y += 4; - } while (y < height); - } - sse = summary_all_avx2(&sum); - break; - } - - return sse; -} - -#if CONFIG_VP9_HIGHBITDEPTH -static INLINE void highbd_sse_w16_avx2(__m256i *sum, const uint16_t *a, - const uint16_t *b) { - const __m256i v_a_w = _mm256_loadu_si256((const __m256i *)a); - const __m256i v_b_w = _mm256_loadu_si256((const __m256i *)b); - const __m256i v_d_w = _mm256_sub_epi16(v_a_w, v_b_w); - *sum = _mm256_add_epi32(*sum, _mm256_madd_epi16(v_d_w, v_d_w)); -} - -static INLINE void highbd_sse_w4x4_avx2(__m256i *sum, const uint16_t *a, - int a_stride, const uint16_t *b, - int b_stride) { - const __m128i v_a0 = _mm_loadl_epi64((const __m128i *)a); - const __m128i v_a1 = _mm_loadl_epi64((const __m128i *)(a + a_stride)); - const __m128i v_a2 = _mm_loadl_epi64((const __m128i *)(a + a_stride * 2)); - const __m128i v_a3 = _mm_loadl_epi64((const __m128i *)(a + a_stride * 3)); - const __m128i v_b0 = _mm_loadl_epi64((const __m128i *)b); - const __m128i v_b1 = _mm_loadl_epi64((const __m128i *)(b + b_stride)); - const __m128i v_b2 = _mm_loadl_epi64((const __m128i *)(b + b_stride * 2)); - const __m128i v_b3 = _mm_loadl_epi64((const __m128i *)(b + b_stride * 3)); - const __m128i v_a_hi = _mm_unpacklo_epi64(v_a0, v_a1); - const __m128i v_a_lo = _mm_unpacklo_epi64(v_a2, v_a3); - const __m256i v_a_w = - _mm256_insertf128_si256(_mm256_castsi128_si256(v_a_lo), v_a_hi, 1); - const __m128i v_b_hi = _mm_unpacklo_epi64(v_b0, v_b1); - const __m128i v_b_lo = _mm_unpacklo_epi64(v_b2, v_b3); - const __m256i v_b_w = - _mm256_insertf128_si256(_mm256_castsi128_si256(v_b_lo), v_b_hi, 1); - const __m256i v_d_w = _mm256_sub_epi16(v_a_w, v_b_w); - *sum = _mm256_add_epi32(*sum, _mm256_madd_epi16(v_d_w, v_d_w)); -} - -static INLINE void highbd_sse_w8x2_avx2(__m256i *sum, const uint16_t *a, - int a_stride, const uint16_t *b, - int b_stride) { - const __m128i v_a_hi = _mm_loadu_si128((const __m128i *)(a + a_stride)); - const __m128i v_a_lo = _mm_loadu_si128((const __m128i *)a); - const __m256i v_a_w = - _mm256_insertf128_si256(_mm256_castsi128_si256(v_a_lo), v_a_hi, 1); - const __m128i v_b_hi = _mm_loadu_si128((const __m128i *)(b + b_stride)); - const __m128i v_b_lo = _mm_loadu_si128((const __m128i *)b); - const __m256i v_b_w = - _mm256_insertf128_si256(_mm256_castsi128_si256(v_b_lo), v_b_hi, 1); - const __m256i v_d_w = _mm256_sub_epi16(v_a_w, v_b_w); - *sum = _mm256_add_epi32(*sum, _mm256_madd_epi16(v_d_w, v_d_w)); -} - -int64_t vpx_highbd_sse_avx2(const uint8_t *a8, int a_stride, const uint8_t *b8, - int b_stride, int width, int height) { - int32_t y = 0; - int64_t sse = 0; - uint16_t *a = CONVERT_TO_SHORTPTR(a8); - uint16_t *b = CONVERT_TO_SHORTPTR(b8); - __m256i sum = _mm256_setzero_si256(); - switch (width) { - case 4: - do { - highbd_sse_w4x4_avx2(&sum, a, a_stride, b, b_stride); - a += a_stride << 2; - b += b_stride << 2; - y += 4; - } while (y < height); - sse = summary_all_avx2(&sum); - break; - case 8: - do { - highbd_sse_w8x2_avx2(&sum, a, a_stride, b, b_stride); - a += a_stride << 1; - b += b_stride << 1; - y += 2; - } while (y < height); - sse = summary_all_avx2(&sum); - break; - case 16: - do { - highbd_sse_w16_avx2(&sum, a, b); - a += a_stride; - b += b_stride; - y += 1; - } while (y < height); - sse = summary_all_avx2(&sum); - break; - case 32: - do { - int l = 0; - __m256i sum32 = _mm256_setzero_si256(); - do { - highbd_sse_w16_avx2(&sum32, a, b); - highbd_sse_w16_avx2(&sum32, a + 16, b + 16); - a += a_stride; - b += b_stride; - l += 1; - } while (l < 64 && l < (height - y)); - summary_32_avx2(&sum32, &sum); - y += 64; - } while (y < height); - sse = summary_4x64_avx2(sum); - break; - case 64: - do { - int l = 0; - __m256i sum32 = _mm256_setzero_si256(); - do { - highbd_sse_w16_avx2(&sum32, a, b); - highbd_sse_w16_avx2(&sum32, a + 16 * 1, b + 16 * 1); - highbd_sse_w16_avx2(&sum32, a + 16 * 2, b + 16 * 2); - highbd_sse_w16_avx2(&sum32, a + 16 * 3, b + 16 * 3); - a += a_stride; - b += b_stride; - l += 1; - } while (l < 32 && l < (height - y)); - summary_32_avx2(&sum32, &sum); - y += 32; - } while (y < height); - sse = summary_4x64_avx2(sum); - break; - default: - if (width & 0x7) { - do { - int i = 0; - __m256i sum32 = _mm256_setzero_si256(); - do { - const uint16_t *a2; - const uint16_t *b2; - highbd_sse_w8x2_avx2(&sum32, a + i, a_stride, b + i, b_stride); - a2 = a + i + (a_stride << 1); - b2 = b + i + (b_stride << 1); - highbd_sse_w8x2_avx2(&sum32, a2, a_stride, b2, b_stride); - i += 8; - } while (i + 4 < width); - highbd_sse_w4x4_avx2(&sum32, a + i, a_stride, b + i, b_stride); - summary_32_avx2(&sum32, &sum); - a += a_stride << 2; - b += b_stride << 2; - y += 4; - } while (y < height); - } else { - do { - int l = 0; - __m256i sum32 = _mm256_setzero_si256(); - do { - int i = 0; - do { - highbd_sse_w8x2_avx2(&sum32, a + i, a_stride, b + i, b_stride); - i += 8; - } while (i < width); - a += a_stride << 1; - b += b_stride << 1; - l += 2; - } while (l < 8 && l < (height - y)); - summary_32_avx2(&sum32, &sum); - y += 8; - } while (y < height); - } - sse = summary_4x64_avx2(sum); - break; - } - return sse; -} -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sse_sse4.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sse_sse4.c deleted file mode 100644 index 4a7585c5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sse_sse4.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" - -#include "vpx_ports/mem.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/x86/mem_sse2.h" - -static INLINE int64_t summary_all_sse4(const __m128i *sum_all) { - int64_t sum; - const __m128i sum0 = _mm_cvtepu32_epi64(*sum_all); - const __m128i sum1 = _mm_cvtepu32_epi64(_mm_srli_si128(*sum_all, 8)); - const __m128i sum_2x64 = _mm_add_epi64(sum0, sum1); - const __m128i sum_1x64 = _mm_add_epi64(sum_2x64, _mm_srli_si128(sum_2x64, 8)); - _mm_storel_epi64((__m128i *)&sum, sum_1x64); - return sum; -} - -#if CONFIG_VP9_HIGHBITDEPTH -static INLINE void summary_32_sse4(const __m128i *sum32, __m128i *sum64) { - const __m128i sum0 = _mm_cvtepu32_epi64(*sum32); - const __m128i sum1 = _mm_cvtepu32_epi64(_mm_srli_si128(*sum32, 8)); - *sum64 = _mm_add_epi64(sum0, *sum64); - *sum64 = _mm_add_epi64(sum1, *sum64); -} -#endif - -static INLINE void sse_w16_sse4_1(__m128i *sum, const uint8_t *a, - const uint8_t *b) { - const __m128i v_a0 = _mm_loadu_si128((const __m128i *)a); - const __m128i v_b0 = _mm_loadu_si128((const __m128i *)b); - const __m128i v_a00_w = _mm_cvtepu8_epi16(v_a0); - const __m128i v_a01_w = _mm_cvtepu8_epi16(_mm_srli_si128(v_a0, 8)); - const __m128i v_b00_w = _mm_cvtepu8_epi16(v_b0); - const __m128i v_b01_w = _mm_cvtepu8_epi16(_mm_srli_si128(v_b0, 8)); - const __m128i v_d00_w = _mm_sub_epi16(v_a00_w, v_b00_w); - const __m128i v_d01_w = _mm_sub_epi16(v_a01_w, v_b01_w); - *sum = _mm_add_epi32(*sum, _mm_madd_epi16(v_d00_w, v_d00_w)); - *sum = _mm_add_epi32(*sum, _mm_madd_epi16(v_d01_w, v_d01_w)); -} - -static INLINE void sse4x2_sse4_1(const uint8_t *a, int a_stride, - const uint8_t *b, int b_stride, __m128i *sum) { - const __m128i v_a0 = load_unaligned_u32(a); - const __m128i v_a1 = load_unaligned_u32(a + a_stride); - const __m128i v_b0 = load_unaligned_u32(b); - const __m128i v_b1 = load_unaligned_u32(b + b_stride); - const __m128i v_a_w = _mm_cvtepu8_epi16(_mm_unpacklo_epi32(v_a0, v_a1)); - const __m128i v_b_w = _mm_cvtepu8_epi16(_mm_unpacklo_epi32(v_b0, v_b1)); - const __m128i v_d_w = _mm_sub_epi16(v_a_w, v_b_w); - *sum = _mm_add_epi32(*sum, _mm_madd_epi16(v_d_w, v_d_w)); -} - -static INLINE void sse8_sse4_1(const uint8_t *a, const uint8_t *b, - __m128i *sum) { - const __m128i v_a0 = _mm_loadl_epi64((const __m128i *)a); - const __m128i v_b0 = _mm_loadl_epi64((const __m128i *)b); - const __m128i v_a_w = _mm_cvtepu8_epi16(v_a0); - const __m128i v_b_w = _mm_cvtepu8_epi16(v_b0); - const __m128i v_d_w = _mm_sub_epi16(v_a_w, v_b_w); - *sum = _mm_add_epi32(*sum, _mm_madd_epi16(v_d_w, v_d_w)); -} - -int64_t vpx_sse_sse4_1(const uint8_t *a, int a_stride, const uint8_t *b, - int b_stride, int width, int height) { - int y = 0; - int64_t sse = 0; - __m128i sum = _mm_setzero_si128(); - switch (width) { - case 4: - do { - sse4x2_sse4_1(a, a_stride, b, b_stride, &sum); - a += a_stride << 1; - b += b_stride << 1; - y += 2; - } while (y < height); - sse = summary_all_sse4(&sum); - break; - case 8: - do { - sse8_sse4_1(a, b, &sum); - a += a_stride; - b += b_stride; - y += 1; - } while (y < height); - sse = summary_all_sse4(&sum); - break; - case 16: - do { - sse_w16_sse4_1(&sum, a, b); - a += a_stride; - b += b_stride; - y += 1; - } while (y < height); - sse = summary_all_sse4(&sum); - break; - case 32: - do { - sse_w16_sse4_1(&sum, a, b); - sse_w16_sse4_1(&sum, a + 16, b + 16); - a += a_stride; - b += b_stride; - y += 1; - } while (y < height); - sse = summary_all_sse4(&sum); - break; - case 64: - do { - sse_w16_sse4_1(&sum, a, b); - sse_w16_sse4_1(&sum, a + 16 * 1, b + 16 * 1); - sse_w16_sse4_1(&sum, a + 16 * 2, b + 16 * 2); - sse_w16_sse4_1(&sum, a + 16 * 3, b + 16 * 3); - a += a_stride; - b += b_stride; - y += 1; - } while (y < height); - sse = summary_all_sse4(&sum); - break; - default: - if (width & 0x07) { - do { - int i = 0; - do { - sse8_sse4_1(a + i, b + i, &sum); - sse8_sse4_1(a + i + a_stride, b + i + b_stride, &sum); - i += 8; - } while (i + 4 < width); - sse4x2_sse4_1(a + i, a_stride, b + i, b_stride, &sum); - a += (a_stride << 1); - b += (b_stride << 1); - y += 2; - } while (y < height); - } else { - do { - int i = 0; - do { - sse8_sse4_1(a + i, b + i, &sum); - i += 8; - } while (i < width); - a += a_stride; - b += b_stride; - y += 1; - } while (y < height); - } - sse = summary_all_sse4(&sum); - break; - } - - return sse; -} - -#if CONFIG_VP9_HIGHBITDEPTH -static INLINE void highbd_sse_w4x2_sse4_1(__m128i *sum, const uint16_t *a, - int a_stride, const uint16_t *b, - int b_stride) { - const __m128i v_a0 = _mm_loadl_epi64((const __m128i *)a); - const __m128i v_a1 = _mm_loadl_epi64((const __m128i *)(a + a_stride)); - const __m128i v_b0 = _mm_loadl_epi64((const __m128i *)b); - const __m128i v_b1 = _mm_loadl_epi64((const __m128i *)(b + b_stride)); - const __m128i v_a_w = _mm_unpacklo_epi64(v_a0, v_a1); - const __m128i v_b_w = _mm_unpacklo_epi64(v_b0, v_b1); - const __m128i v_d_w = _mm_sub_epi16(v_a_w, v_b_w); - *sum = _mm_add_epi32(*sum, _mm_madd_epi16(v_d_w, v_d_w)); -} - -static INLINE void highbd_sse_w8_sse4_1(__m128i *sum, const uint16_t *a, - const uint16_t *b) { - const __m128i v_a_w = _mm_loadu_si128((const __m128i *)a); - const __m128i v_b_w = _mm_loadu_si128((const __m128i *)b); - const __m128i v_d_w = _mm_sub_epi16(v_a_w, v_b_w); - *sum = _mm_add_epi32(*sum, _mm_madd_epi16(v_d_w, v_d_w)); -} - -int64_t vpx_highbd_sse_sse4_1(const uint8_t *a8, int a_stride, - const uint8_t *b8, int b_stride, int width, - int height) { - int32_t y = 0; - int64_t sse = 0; - uint16_t *a = CONVERT_TO_SHORTPTR(a8); - uint16_t *b = CONVERT_TO_SHORTPTR(b8); - __m128i sum = _mm_setzero_si128(); - switch (width) { - case 4: - do { - highbd_sse_w4x2_sse4_1(&sum, a, a_stride, b, b_stride); - a += a_stride << 1; - b += b_stride << 1; - y += 2; - } while (y < height); - sse = summary_all_sse4(&sum); - break; - case 8: - do { - highbd_sse_w8_sse4_1(&sum, a, b); - a += a_stride; - b += b_stride; - y += 1; - } while (y < height); - sse = summary_all_sse4(&sum); - break; - case 16: - do { - int l = 0; - __m128i sum32 = _mm_setzero_si128(); - do { - highbd_sse_w8_sse4_1(&sum32, a, b); - highbd_sse_w8_sse4_1(&sum32, a + 8, b + 8); - a += a_stride; - b += b_stride; - l += 1; - } while (l < 64 && l < (height - y)); - summary_32_sse4(&sum32, &sum); - y += 64; - } while (y < height); - _mm_storel_epi64((__m128i *)&sse, - _mm_add_epi64(sum, _mm_srli_si128(sum, 8))); - break; - case 32: - do { - int l = 0; - __m128i sum32 = _mm_setzero_si128(); - do { - highbd_sse_w8_sse4_1(&sum32, a, b); - highbd_sse_w8_sse4_1(&sum32, a + 8 * 1, b + 8 * 1); - highbd_sse_w8_sse4_1(&sum32, a + 8 * 2, b + 8 * 2); - highbd_sse_w8_sse4_1(&sum32, a + 8 * 3, b + 8 * 3); - a += a_stride; - b += b_stride; - l += 1; - } while (l < 32 && l < (height - y)); - summary_32_sse4(&sum32, &sum); - y += 32; - } while (y < height); - _mm_storel_epi64((__m128i *)&sse, - _mm_add_epi64(sum, _mm_srli_si128(sum, 8))); - break; - case 64: - do { - int l = 0; - __m128i sum32 = _mm_setzero_si128(); - do { - highbd_sse_w8_sse4_1(&sum32, a, b); - highbd_sse_w8_sse4_1(&sum32, a + 8 * 1, b + 8 * 1); - highbd_sse_w8_sse4_1(&sum32, a + 8 * 2, b + 8 * 2); - highbd_sse_w8_sse4_1(&sum32, a + 8 * 3, b + 8 * 3); - highbd_sse_w8_sse4_1(&sum32, a + 8 * 4, b + 8 * 4); - highbd_sse_w8_sse4_1(&sum32, a + 8 * 5, b + 8 * 5); - highbd_sse_w8_sse4_1(&sum32, a + 8 * 6, b + 8 * 6); - highbd_sse_w8_sse4_1(&sum32, a + 8 * 7, b + 8 * 7); - a += a_stride; - b += b_stride; - l += 1; - } while (l < 16 && l < (height - y)); - summary_32_sse4(&sum32, &sum); - y += 16; - } while (y < height); - _mm_storel_epi64((__m128i *)&sse, - _mm_add_epi64(sum, _mm_srli_si128(sum, 8))); - break; - default: - if (width & 0x7) { - do { - __m128i sum32 = _mm_setzero_si128(); - int i = 0; - do { - highbd_sse_w8_sse4_1(&sum32, a + i, b + i); - highbd_sse_w8_sse4_1(&sum32, a + i + a_stride, b + i + b_stride); - i += 8; - } while (i + 4 < width); - highbd_sse_w4x2_sse4_1(&sum32, a + i, a_stride, b + i, b_stride); - a += (a_stride << 1); - b += (b_stride << 1); - y += 2; - summary_32_sse4(&sum32, &sum); - } while (y < height); - } else { - do { - int l = 0; - __m128i sum32 = _mm_setzero_si128(); - do { - int i = 0; - do { - highbd_sse_w8_sse4_1(&sum32, a + i, b + i); - i += 8; - } while (i < width); - a += a_stride; - b += b_stride; - l += 1; - } while (l < 8 && l < (height - y)); - summary_32_sse4(&sum32, &sum); - y += 8; - } while (y < height); - } - _mm_storel_epi64((__m128i *)&sse, - _mm_add_epi64(sum, _mm_srli_si128(sum, 8))); - break; - } - return sse; -} -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/ssim_opt_x86_64.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/ssim_opt_x86_64.asm deleted file mode 100644 index 1ad3b88c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/ssim_opt_x86_64.asm +++ /dev/null @@ -1,129 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "vpx_ports/x86_abi_support.asm" - -; tabulate_ssim - sums sum_s,sum_r,sum_sq_s,sum_sq_r, sum_sxr -%macro TABULATE_SSIM 0 - paddusw xmm15, xmm3 ; sum_s - paddusw xmm14, xmm4 ; sum_r - movdqa xmm1, xmm3 - pmaddwd xmm1, xmm1 - paddd xmm13, xmm1 ; sum_sq_s - movdqa xmm2, xmm4 - pmaddwd xmm2, xmm2 - paddd xmm12, xmm2 ; sum_sq_r - pmaddwd xmm3, xmm4 - paddd xmm11, xmm3 ; sum_sxr -%endmacro - -; Sum across the register %1 starting with q words -%macro SUM_ACROSS_Q 1 - movdqa xmm2,%1 - punpckldq %1,xmm0 - punpckhdq xmm2,xmm0 - paddq %1,xmm2 - movdqa xmm2,%1 - punpcklqdq %1,xmm0 - punpckhqdq xmm2,xmm0 - paddq %1,xmm2 -%endmacro - -; Sum across the register %1 starting with q words -%macro SUM_ACROSS_W 1 - movdqa xmm1, %1 - punpcklwd %1,xmm0 - punpckhwd xmm1,xmm0 - paddd %1, xmm1 - SUM_ACROSS_Q %1 -%endmacro - -SECTION .text - -;void vpx_ssim_parms_8x8_sse2( -; unsigned char *s, -; int sp, -; unsigned char *r, -; int rp -; uint32_t *sum_s, -; uint32_t *sum_r, -; uint32_t *sum_sq_s, -; uint32_t *sum_sq_r, -; uint32_t *sum_sxr); -; -; TODO: Use parm passing through structure, probably don't need the pxors -; ( calling app will initialize to 0 ) could easily fit everything in sse2 -; without too much hastle, and can probably do better estimates with psadw -; or pavgb At this point this is just meant to be first pass for calculating -; all the parms needed for 16x16 ssim so we can play with dssim as distortion -; in mode selection code. -globalsym(vpx_ssim_parms_8x8_sse2) -sym(vpx_ssim_parms_8x8_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 9 - SAVE_XMM 15 - push rsi - push rdi - ; end prolog - - mov rsi, arg(0) ;s - mov rcx, arg(1) ;sp - mov rdi, arg(2) ;r - mov rax, arg(3) ;rp - - pxor xmm0, xmm0 - pxor xmm15,xmm15 ;sum_s - pxor xmm14,xmm14 ;sum_r - pxor xmm13,xmm13 ;sum_sq_s - pxor xmm12,xmm12 ;sum_sq_r - pxor xmm11,xmm11 ;sum_sxr - - mov rdx, 8 ;row counter -.NextRow: - - ;grab source and reference pixels - movq xmm3, [rsi] - movq xmm4, [rdi] - punpcklbw xmm3, xmm0 ; low_s - punpcklbw xmm4, xmm0 ; low_r - - TABULATE_SSIM - - add rsi, rcx ; next s row - add rdi, rax ; next r row - - dec rdx ; counter - jnz .NextRow - - SUM_ACROSS_W xmm15 - SUM_ACROSS_W xmm14 - SUM_ACROSS_Q xmm13 - SUM_ACROSS_Q xmm12 - SUM_ACROSS_Q xmm11 - - mov rdi,arg(4) - movd [rdi], xmm15; - mov rdi,arg(5) - movd [rdi], xmm14; - mov rdi,arg(6) - movd [rdi], xmm13; - mov rdi,arg(7) - movd [rdi], xmm12; - mov rdi,arg(8) - movd [rdi], xmm11; - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/subpel_variance_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/subpel_variance_sse2.asm deleted file mode 100644 index d1d8d346..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/subpel_variance_sse2.asm +++ /dev/null @@ -1,1467 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "third_party/x86inc/x86inc.asm" - -SECTION_RODATA -pw_8: times 8 dw 8 -bilin_filter_m_sse2: times 8 dw 16 - times 8 dw 0 - times 8 dw 14 - times 8 dw 2 - times 8 dw 12 - times 8 dw 4 - times 8 dw 10 - times 8 dw 6 - times 16 dw 8 - times 8 dw 6 - times 8 dw 10 - times 8 dw 4 - times 8 dw 12 - times 8 dw 2 - times 8 dw 14 - -bilin_filter_m_ssse3: times 8 db 16, 0 - times 8 db 14, 2 - times 8 db 12, 4 - times 8 db 10, 6 - times 16 db 8 - times 8 db 6, 10 - times 8 db 4, 12 - times 8 db 2, 14 - -SECTION .text - -; int vpx_sub_pixel_varianceNxh(const uint8_t *src, ptrdiff_t src_stride, -; int x_offset, int y_offset, -; const uint8_t *ref, ptrdiff_t ref_stride, -; int height, unsigned int *sse); -; -; This function returns the SE and stores SSE in the given pointer. - -%macro SUM_SSE 6 ; src1, ref1, src2, ref2, sum, sse - psubw %3, %4 - psubw %1, %2 - paddw %5, %3 - pmaddwd %3, %3 - paddw %5, %1 - pmaddwd %1, %1 - paddd %6, %3 - paddd %6, %1 -%endmacro - -%macro STORE_AND_RET 1 -%if %1 > 4 - ; if H=64 and W=16, we have 8 words of each 2(1bit)x64(6bit)x9bit=16bit - ; in m6, i.e. it _exactly_ fits in a signed word per word in the xmm reg. - ; We have to sign-extend it before adding the words within the register - ; and outputing to a dword. - pcmpgtw m5, m6 ; mask for 0 > x - movhlps m3, m7 - punpcklwd m4, m6, m5 - punpckhwd m6, m5 ; sign-extend m6 word->dword - paddd m7, m3 - paddd m6, m4 - pshufd m3, m7, 0x1 - movhlps m4, m6 - paddd m7, m3 - paddd m6, m4 - mov r1, ssem ; r1 = unsigned int *sse - pshufd m4, m6, 0x1 - movd [r1], m7 ; store sse - paddd m6, m4 - movd raxd, m6 ; store sum as return value -%else ; 4xh - pshuflw m4, m6, 0xe - pshuflw m3, m7, 0xe - paddw m6, m4 - paddd m7, m3 - pcmpgtw m5, m6 ; mask for 0 > x - mov r1, ssem ; r1 = unsigned int *sse - punpcklwd m6, m5 ; sign-extend m6 word->dword - movd [r1], m7 ; store sse - pshuflw m4, m6, 0xe - paddd m6, m4 - movd raxd, m6 ; store sum as return value -%endif - RET -%endmacro - -%macro INC_SRC_BY_SRC_STRIDE 0 -%if VPX_ARCH_X86=1 && CONFIG_PIC=1 - add srcq, src_stridemp -%else - add srcq, src_strideq -%endif -%endmacro - -%macro SUBPEL_VARIANCE 1-2 0 ; W -%if cpuflag(ssse3) -%define bilin_filter_m bilin_filter_m_ssse3 -%define filter_idx_shift 4 -%else -%define bilin_filter_m bilin_filter_m_sse2 -%define filter_idx_shift 5 -%endif -; FIXME(rbultje) only bilinear filters use >8 registers, and ssse3 only uses -; 11, not 13, if the registers are ordered correctly. May make a minor speed -; difference on Win64 - -%if VPX_ARCH_X86_64 - %if %2 == 1 ; avg - cglobal sub_pixel_avg_variance%1xh, 9, 10, 13, src, src_stride, \ - x_offset, y_offset, ref, ref_stride, \ - second_pred, second_stride, height, sse - %define second_str second_strideq - %else - cglobal sub_pixel_variance%1xh, 7, 8, 13, src, src_stride, \ - x_offset, y_offset, ref, ref_stride, \ - height, sse - %endif - %define block_height heightd - %define bilin_filter sseq -%else - %if CONFIG_PIC=1 - %if %2 == 1 ; avg - cglobal sub_pixel_avg_variance%1xh, 7, 7, 13, src, src_stride, \ - x_offset, y_offset, ref, ref_stride, \ - second_pred, second_stride, height, sse - %define block_height dword heightm - %define second_str second_stridemp - %else - cglobal sub_pixel_variance%1xh, 7, 7, 13, src, src_stride, \ - x_offset, y_offset, ref, ref_stride, \ - height, sse - %define block_height heightd - %endif - - ; reuse argument stack space - %define g_bilin_filterm x_offsetm - %define g_pw_8m y_offsetm - - ;Store bilin_filter and pw_8 location in stack - %if GET_GOT_DEFINED == 1 - GET_GOT eax - add esp, 4 ; restore esp - %endif - - lea ecx, [GLOBAL(bilin_filter_m)] - mov g_bilin_filterm, ecx - - lea ecx, [GLOBAL(pw_8)] - mov g_pw_8m, ecx - - LOAD_IF_USED 0, 1 ; load eax, ecx back - %else - %if %2 == 1 ; avg - cglobal sub_pixel_avg_variance%1xh, 7, 7, 13, src, src_stride, \ - x_offset, y_offset, \ - ref, ref_stride, second_pred, second_stride, \ - height, sse - %define block_height dword heightm - %define second_str second_stridemp - %else - cglobal sub_pixel_variance%1xh, 7, 7, 13, src, src_stride, \ - x_offset, y_offset, ref, ref_stride, \ - height, sse - %define block_height heightd - %endif - %define bilin_filter bilin_filter_m - %endif -%endif - -%if %1 == 4 - %define movx movd -%else - %define movx movh -%endif - - ASSERT %1 <= 16 ; m6 overflows if w > 16 - pxor m6, m6 ; sum - pxor m7, m7 ; sse - ; FIXME(rbultje) if both filters are bilinear, we don't actually use m5; we - ; could perhaps use it for something more productive then - pxor m5, m5 ; dedicated zero register -%if %1 < 16 - sar block_height, 1 -%if %2 == 1 ; avg - shl second_str, 1 -%endif -%endif - - ; FIXME(rbultje) replace by jumptable? - test x_offsetd, x_offsetd - jnz .x_nonzero - ; x_offset == 0 - test y_offsetd, y_offsetd - jnz .x_zero_y_nonzero - - ; x_offset == 0 && y_offset == 0 -.x_zero_y_zero_loop: -%if %1 == 16 - movu m0, [srcq] - mova m1, [refq] -%if %2 == 1 ; avg - pavgb m0, [second_predq] - punpckhbw m3, m1, m5 - punpcklbw m1, m5 -%endif - punpckhbw m2, m0, m5 - punpcklbw m0, m5 - -%if %2 == 0 ; !avg - punpckhbw m3, m1, m5 - punpcklbw m1, m5 -%endif - SUM_SSE m0, m1, m2, m3, m6, m7 - - add srcq, src_strideq - add refq, ref_strideq -%else ; %1 < 16 - movx m0, [srcq] -%if %2 == 1 ; avg -%if %1 > 4 - movhps m0, [srcq+src_strideq] -%else ; 4xh - movx m1, [srcq+src_strideq] - punpckldq m0, m1 -%endif -%else ; !avg - movx m2, [srcq+src_strideq] -%endif - - movx m1, [refq] - movx m3, [refq+ref_strideq] - -%if %2 == 1 ; avg -%if %1 > 4 - pavgb m0, [second_predq] -%else - movh m2, [second_predq] - pavgb m0, m2 -%endif - punpcklbw m3, m5 - punpcklbw m1, m5 -%if %1 > 4 - punpckhbw m2, m0, m5 - punpcklbw m0, m5 -%else ; 4xh - punpcklbw m0, m5 - movhlps m2, m0 -%endif -%else ; !avg - punpcklbw m0, m5 - punpcklbw m2, m5 - punpcklbw m3, m5 - punpcklbw m1, m5 -%endif - SUM_SSE m0, m1, m2, m3, m6, m7 - - lea srcq, [srcq+src_strideq*2] - lea refq, [refq+ref_strideq*2] -%endif -%if %2 == 1 ; avg - add second_predq, second_str -%endif - dec block_height - jg .x_zero_y_zero_loop - STORE_AND_RET %1 - -.x_zero_y_nonzero: - cmp y_offsetd, 4 - jne .x_zero_y_nonhalf - - ; x_offset == 0 && y_offset == 0.5 -.x_zero_y_half_loop: -%if %1 == 16 - movu m0, [srcq] - movu m4, [srcq+src_strideq] - mova m1, [refq] - pavgb m0, m4 - punpckhbw m3, m1, m5 -%if %2 == 1 ; avg - pavgb m0, [second_predq] -%endif - punpcklbw m1, m5 - punpckhbw m2, m0, m5 - punpcklbw m0, m5 - SUM_SSE m0, m1, m2, m3, m6, m7 - - add srcq, src_strideq - add refq, ref_strideq -%else ; %1 < 16 - movx m0, [srcq] - movx m2, [srcq+src_strideq] -%if %2 == 1 ; avg -%if %1 > 4 - movhps m2, [srcq+src_strideq*2] -%else ; 4xh - movx m1, [srcq+src_strideq*2] - punpckldq m2, m1 -%endif - movx m1, [refq] -%if %1 > 4 - movlhps m0, m2 -%else ; 4xh - punpckldq m0, m2 -%endif - movx m3, [refq+ref_strideq] - pavgb m0, m2 - punpcklbw m1, m5 -%if %1 > 4 - pavgb m0, [second_predq] - punpcklbw m3, m5 - punpckhbw m2, m0, m5 - punpcklbw m0, m5 -%else ; 4xh - movh m4, [second_predq] - pavgb m0, m4 - punpcklbw m3, m5 - punpcklbw m0, m5 - movhlps m2, m0 -%endif -%else ; !avg - movx m4, [srcq+src_strideq*2] - movx m1, [refq] - pavgb m0, m2 - movx m3, [refq+ref_strideq] - pavgb m2, m4 - punpcklbw m0, m5 - punpcklbw m2, m5 - punpcklbw m3, m5 - punpcklbw m1, m5 -%endif - SUM_SSE m0, m1, m2, m3, m6, m7 - - lea srcq, [srcq+src_strideq*2] - lea refq, [refq+ref_strideq*2] -%endif -%if %2 == 1 ; avg - add second_predq, second_str -%endif - dec block_height - jg .x_zero_y_half_loop - STORE_AND_RET %1 - -.x_zero_y_nonhalf: - ; x_offset == 0 && y_offset == bilin interpolation -%if VPX_ARCH_X86_64 - lea bilin_filter, [GLOBAL(bilin_filter_m)] -%endif - shl y_offsetd, filter_idx_shift -%if VPX_ARCH_X86_64 && %1 > 4 - mova m8, [bilin_filter+y_offsetq] -%if notcpuflag(ssse3) ; FIXME(rbultje) don't scatter registers on x86-64 - mova m9, [bilin_filter+y_offsetq+16] -%endif - mova m10, [GLOBAL(pw_8)] -%define filter_y_a m8 -%define filter_y_b m9 -%define filter_rnd m10 -%else ; x86-32 or mmx -%if VPX_ARCH_X86=1 && CONFIG_PIC=1 -; x_offset == 0, reuse x_offset reg -%define tempq x_offsetq - add y_offsetq, g_bilin_filterm -%define filter_y_a [y_offsetq] -%define filter_y_b [y_offsetq+16] - mov tempq, g_pw_8m -%define filter_rnd [tempq] -%else - add y_offsetq, bilin_filter -%define filter_y_a [y_offsetq] -%define filter_y_b [y_offsetq+16] -%define filter_rnd [GLOBAL(pw_8)] -%endif -%endif - -.x_zero_y_other_loop: -%if %1 == 16 - movu m0, [srcq] - movu m4, [srcq+src_strideq] - mova m1, [refq] -%if cpuflag(ssse3) - punpckhbw m2, m0, m4 - punpcklbw m0, m4 - pmaddubsw m2, filter_y_a - pmaddubsw m0, filter_y_a - paddw m2, filter_rnd - paddw m0, filter_rnd -%else - punpckhbw m2, m0, m5 - punpckhbw m3, m4, m5 - punpcklbw m0, m5 - punpcklbw m4, m5 - ; FIXME(rbultje) instead of out=((num-x)*in1+x*in2+rnd)>>log2(num), we can - ; also do out=in1+(((num-x)*(in2-in1)+rnd)>>log2(num)). Total number of - ; instructions is the same (5), but it is 1 mul instead of 2, so might be - ; slightly faster because of pmullw latency. It would also cut our rodata - ; tables in half for this function, and save 1-2 registers on x86-64. - pmullw m2, filter_y_a - pmullw m3, filter_y_b - paddw m2, filter_rnd - pmullw m0, filter_y_a - pmullw m4, filter_y_b - paddw m0, filter_rnd - paddw m2, m3 - paddw m0, m4 -%endif - psraw m2, 4 - psraw m0, 4 -%if %2 == 1 ; avg - ; FIXME(rbultje) pipeline - packuswb m0, m2 - pavgb m0, [second_predq] - punpckhbw m2, m0, m5 - punpcklbw m0, m5 -%endif - punpckhbw m3, m1, m5 - punpcklbw m1, m5 - SUM_SSE m0, m1, m2, m3, m6, m7 - - add srcq, src_strideq - add refq, ref_strideq -%else ; %1 < 16 - movx m0, [srcq] - movx m2, [srcq+src_strideq] - movx m4, [srcq+src_strideq*2] - movx m3, [refq+ref_strideq] -%if cpuflag(ssse3) - movx m1, [refq] - punpcklbw m0, m2 - punpcklbw m2, m4 - pmaddubsw m0, filter_y_a - pmaddubsw m2, filter_y_a - punpcklbw m3, m5 - paddw m2, filter_rnd - paddw m0, filter_rnd -%else - punpcklbw m0, m5 - punpcklbw m2, m5 - punpcklbw m4, m5 - pmullw m0, filter_y_a - pmullw m1, m2, filter_y_b - punpcklbw m3, m5 - paddw m0, filter_rnd - pmullw m2, filter_y_a - pmullw m4, filter_y_b - paddw m0, m1 - paddw m2, filter_rnd - movx m1, [refq] - paddw m2, m4 -%endif - psraw m0, 4 - psraw m2, 4 -%if %2 == 1 ; avg - ; FIXME(rbultje) pipeline -%if %1 == 4 - movlhps m0, m2 -%endif - packuswb m0, m2 -%if %1 > 4 - pavgb m0, [second_predq] - punpckhbw m2, m0, m5 - punpcklbw m0, m5 -%else ; 4xh - movh m2, [second_predq] - pavgb m0, m2 - punpcklbw m0, m5 - movhlps m2, m0 -%endif -%endif - punpcklbw m1, m5 - SUM_SSE m0, m1, m2, m3, m6, m7 - - lea srcq, [srcq+src_strideq*2] - lea refq, [refq+ref_strideq*2] -%endif -%if %2 == 1 ; avg - add second_predq, second_str -%endif - dec block_height - jg .x_zero_y_other_loop -%undef filter_y_a -%undef filter_y_b -%undef filter_rnd - STORE_AND_RET %1 - -.x_nonzero: - cmp x_offsetd, 4 - jne .x_nonhalf - ; x_offset == 0.5 - test y_offsetd, y_offsetd - jnz .x_half_y_nonzero - - ; x_offset == 0.5 && y_offset == 0 -.x_half_y_zero_loop: -%if %1 == 16 - movu m0, [srcq] - movu m4, [srcq+1] - mova m1, [refq] - pavgb m0, m4 - punpckhbw m3, m1, m5 -%if %2 == 1 ; avg - pavgb m0, [second_predq] -%endif - punpcklbw m1, m5 - punpckhbw m2, m0, m5 - punpcklbw m0, m5 - SUM_SSE m0, m1, m2, m3, m6, m7 - - add srcq, src_strideq - add refq, ref_strideq -%else ; %1 < 16 - movx m0, [srcq] - movx m4, [srcq+1] -%if %2 == 1 ; avg -%if %1 > 4 - movhps m0, [srcq+src_strideq] - movhps m4, [srcq+src_strideq+1] -%else ; 4xh - movx m1, [srcq+src_strideq] - punpckldq m0, m1 - movx m2, [srcq+src_strideq+1] - punpckldq m4, m2 -%endif - movx m1, [refq] - movx m3, [refq+ref_strideq] - pavgb m0, m4 - punpcklbw m3, m5 -%if %1 > 4 - pavgb m0, [second_predq] - punpcklbw m1, m5 - punpckhbw m2, m0, m5 - punpcklbw m0, m5 -%else ; 4xh - movh m2, [second_predq] - pavgb m0, m2 - punpcklbw m1, m5 - punpcklbw m0, m5 - movhlps m2, m0 -%endif -%else ; !avg - movx m2, [srcq+src_strideq] - movx m1, [refq] - pavgb m0, m4 - movx m4, [srcq+src_strideq+1] - movx m3, [refq+ref_strideq] - pavgb m2, m4 - punpcklbw m0, m5 - punpcklbw m2, m5 - punpcklbw m3, m5 - punpcklbw m1, m5 -%endif - SUM_SSE m0, m1, m2, m3, m6, m7 - - lea srcq, [srcq+src_strideq*2] - lea refq, [refq+ref_strideq*2] -%endif -%if %2 == 1 ; avg - add second_predq, second_str -%endif - dec block_height - jg .x_half_y_zero_loop - STORE_AND_RET %1 - -.x_half_y_nonzero: - cmp y_offsetd, 4 - jne .x_half_y_nonhalf - - ; x_offset == 0.5 && y_offset == 0.5 -%if %1 == 16 - movu m0, [srcq] - movu m3, [srcq+1] - add srcq, src_strideq - pavgb m0, m3 -.x_half_y_half_loop: - movu m4, [srcq] - movu m3, [srcq+1] - mova m1, [refq] - pavgb m4, m3 - punpckhbw m3, m1, m5 - pavgb m0, m4 -%if %2 == 1 ; avg - punpcklbw m1, m5 - pavgb m0, [second_predq] - punpckhbw m2, m0, m5 - punpcklbw m0, m5 -%else - punpckhbw m2, m0, m5 - punpcklbw m0, m5 - punpcklbw m1, m5 -%endif - SUM_SSE m0, m1, m2, m3, m6, m7 - mova m0, m4 - - add srcq, src_strideq - add refq, ref_strideq -%else ; %1 < 16 - movx m0, [srcq] - movx m3, [srcq+1] - add srcq, src_strideq - pavgb m0, m3 -.x_half_y_half_loop: - movx m2, [srcq] - movx m3, [srcq+1] -%if %2 == 1 ; avg -%if %1 > 4 - movhps m2, [srcq+src_strideq] - movhps m3, [srcq+src_strideq+1] -%else - movx m1, [srcq+src_strideq] - punpckldq m2, m1 - movx m1, [srcq+src_strideq+1] - punpckldq m3, m1 -%endif - pavgb m2, m3 -%if %1 > 4 - movlhps m0, m2 - movhlps m4, m2 -%else ; 4xh - punpckldq m0, m2 - pshuflw m4, m2, 0xe -%endif - movx m1, [refq] - pavgb m0, m2 - movx m3, [refq+ref_strideq] -%if %1 > 4 - pavgb m0, [second_predq] -%else - movh m2, [second_predq] - pavgb m0, m2 -%endif - punpcklbw m3, m5 - punpcklbw m1, m5 -%if %1 > 4 - punpckhbw m2, m0, m5 - punpcklbw m0, m5 -%else - punpcklbw m0, m5 - movhlps m2, m0 -%endif -%else ; !avg - movx m4, [srcq+src_strideq] - movx m1, [srcq+src_strideq+1] - pavgb m2, m3 - pavgb m4, m1 - pavgb m0, m2 - pavgb m2, m4 - movx m1, [refq] - movx m3, [refq+ref_strideq] - punpcklbw m0, m5 - punpcklbw m2, m5 - punpcklbw m3, m5 - punpcklbw m1, m5 -%endif - SUM_SSE m0, m1, m2, m3, m6, m7 - mova m0, m4 - - lea srcq, [srcq+src_strideq*2] - lea refq, [refq+ref_strideq*2] -%endif -%if %2 == 1 ; avg - add second_predq, second_str -%endif - dec block_height - jg .x_half_y_half_loop - STORE_AND_RET %1 - -.x_half_y_nonhalf: - ; x_offset == 0.5 && y_offset == bilin interpolation -%if VPX_ARCH_X86_64 - lea bilin_filter, [GLOBAL(bilin_filter_m)] -%endif - shl y_offsetd, filter_idx_shift -%if VPX_ARCH_X86_64 && %1 > 4 - mova m8, [bilin_filter+y_offsetq] -%if notcpuflag(ssse3) ; FIXME(rbultje) don't scatter registers on x86-64 - mova m9, [bilin_filter+y_offsetq+16] -%endif - mova m10, [GLOBAL(pw_8)] -%define filter_y_a m8 -%define filter_y_b m9 -%define filter_rnd m10 -%else ;x86_32 -%if VPX_ARCH_X86=1 && CONFIG_PIC=1 -; x_offset == 0.5. We can reuse x_offset reg -%define tempq x_offsetq - add y_offsetq, g_bilin_filterm -%define filter_y_a [y_offsetq] -%define filter_y_b [y_offsetq+16] - mov tempq, g_pw_8m -%define filter_rnd [tempq] -%else - add y_offsetq, bilin_filter -%define filter_y_a [y_offsetq] -%define filter_y_b [y_offsetq+16] -%define filter_rnd [GLOBAL(pw_8)] -%endif -%endif - -%if %1 == 16 - movu m0, [srcq] - movu m3, [srcq+1] - add srcq, src_strideq - pavgb m0, m3 -.x_half_y_other_loop: - movu m4, [srcq] - movu m2, [srcq+1] - mova m1, [refq] - pavgb m4, m2 -%if cpuflag(ssse3) - punpckhbw m2, m0, m4 - punpcklbw m0, m4 - pmaddubsw m2, filter_y_a - pmaddubsw m0, filter_y_a - paddw m2, filter_rnd - paddw m0, filter_rnd - psraw m2, 4 -%else - punpckhbw m2, m0, m5 - punpckhbw m3, m4, m5 - pmullw m2, filter_y_a - pmullw m3, filter_y_b - paddw m2, filter_rnd - punpcklbw m0, m5 - paddw m2, m3 - punpcklbw m3, m4, m5 - pmullw m0, filter_y_a - pmullw m3, filter_y_b - paddw m0, filter_rnd - psraw m2, 4 - paddw m0, m3 -%endif - punpckhbw m3, m1, m5 - psraw m0, 4 -%if %2 == 1 ; avg - ; FIXME(rbultje) pipeline - packuswb m0, m2 - pavgb m0, [second_predq] - punpckhbw m2, m0, m5 - punpcklbw m0, m5 -%endif - punpcklbw m1, m5 - SUM_SSE m0, m1, m2, m3, m6, m7 - mova m0, m4 - - add srcq, src_strideq - add refq, ref_strideq -%else ; %1 < 16 - movx m0, [srcq] - movx m3, [srcq+1] - add srcq, src_strideq - pavgb m0, m3 -%if notcpuflag(ssse3) - punpcklbw m0, m5 -%endif -.x_half_y_other_loop: - movx m2, [srcq] - movx m1, [srcq+1] - movx m4, [srcq+src_strideq] - movx m3, [srcq+src_strideq+1] - pavgb m2, m1 - pavgb m4, m3 - movx m3, [refq+ref_strideq] -%if cpuflag(ssse3) - movx m1, [refq] - punpcklbw m0, m2 - punpcklbw m2, m4 - pmaddubsw m0, filter_y_a - pmaddubsw m2, filter_y_a - punpcklbw m3, m5 - paddw m0, filter_rnd - paddw m2, filter_rnd -%else - punpcklbw m2, m5 - punpcklbw m4, m5 - pmullw m0, filter_y_a - pmullw m1, m2, filter_y_b - punpcklbw m3, m5 - paddw m0, filter_rnd - pmullw m2, filter_y_a - paddw m0, m1 - pmullw m1, m4, filter_y_b - paddw m2, filter_rnd - paddw m2, m1 - movx m1, [refq] -%endif - psraw m0, 4 - psraw m2, 4 -%if %2 == 1 ; avg - ; FIXME(rbultje) pipeline -%if %1 == 4 - movlhps m0, m2 -%endif - packuswb m0, m2 -%if %1 > 4 - pavgb m0, [second_predq] - punpckhbw m2, m0, m5 - punpcklbw m0, m5 -%else - movh m2, [second_predq] - pavgb m0, m2 - punpcklbw m0, m5 - movhlps m2, m0 -%endif -%endif - punpcklbw m1, m5 - SUM_SSE m0, m1, m2, m3, m6, m7 - mova m0, m4 - - lea srcq, [srcq+src_strideq*2] - lea refq, [refq+ref_strideq*2] -%endif -%if %2 == 1 ; avg - add second_predq, second_str -%endif - dec block_height - jg .x_half_y_other_loop -%undef filter_y_a -%undef filter_y_b -%undef filter_rnd - STORE_AND_RET %1 - -.x_nonhalf: - test y_offsetd, y_offsetd - jnz .x_nonhalf_y_nonzero - - ; x_offset == bilin interpolation && y_offset == 0 -%if VPX_ARCH_X86_64 - lea bilin_filter, [GLOBAL(bilin_filter_m)] -%endif - shl x_offsetd, filter_idx_shift -%if VPX_ARCH_X86_64 && %1 > 4 - mova m8, [bilin_filter+x_offsetq] -%if notcpuflag(ssse3) ; FIXME(rbultje) don't scatter registers on x86-64 - mova m9, [bilin_filter+x_offsetq+16] -%endif - mova m10, [GLOBAL(pw_8)] -%define filter_x_a m8 -%define filter_x_b m9 -%define filter_rnd m10 -%else ; x86-32 -%if VPX_ARCH_X86=1 && CONFIG_PIC=1 -;y_offset == 0. We can reuse y_offset reg. -%define tempq y_offsetq - add x_offsetq, g_bilin_filterm -%define filter_x_a [x_offsetq] -%define filter_x_b [x_offsetq+16] - mov tempq, g_pw_8m -%define filter_rnd [tempq] -%else - add x_offsetq, bilin_filter -%define filter_x_a [x_offsetq] -%define filter_x_b [x_offsetq+16] -%define filter_rnd [GLOBAL(pw_8)] -%endif -%endif - -.x_other_y_zero_loop: -%if %1 == 16 - movu m0, [srcq] - movu m4, [srcq+1] - mova m1, [refq] -%if cpuflag(ssse3) - punpckhbw m2, m0, m4 - punpcklbw m0, m4 - pmaddubsw m2, filter_x_a - pmaddubsw m0, filter_x_a - paddw m2, filter_rnd - paddw m0, filter_rnd -%else - punpckhbw m2, m0, m5 - punpckhbw m3, m4, m5 - punpcklbw m0, m5 - punpcklbw m4, m5 - pmullw m2, filter_x_a - pmullw m3, filter_x_b - paddw m2, filter_rnd - pmullw m0, filter_x_a - pmullw m4, filter_x_b - paddw m0, filter_rnd - paddw m2, m3 - paddw m0, m4 -%endif - psraw m2, 4 - psraw m0, 4 -%if %2 == 1 ; avg - ; FIXME(rbultje) pipeline - packuswb m0, m2 - pavgb m0, [second_predq] - punpckhbw m2, m0, m5 - punpcklbw m0, m5 -%endif - punpckhbw m3, m1, m5 - punpcklbw m1, m5 - SUM_SSE m0, m1, m2, m3, m6, m7 - - add srcq, src_strideq - add refq, ref_strideq -%else ; %1 < 16 - movx m0, [srcq] - movx m1, [srcq+1] - movx m2, [srcq+src_strideq] - movx m4, [srcq+src_strideq+1] - movx m3, [refq+ref_strideq] -%if cpuflag(ssse3) - punpcklbw m0, m1 - movx m1, [refq] - punpcklbw m2, m4 - pmaddubsw m0, filter_x_a - pmaddubsw m2, filter_x_a - punpcklbw m3, m5 - paddw m0, filter_rnd - paddw m2, filter_rnd -%else - punpcklbw m0, m5 - punpcklbw m1, m5 - punpcklbw m2, m5 - punpcklbw m4, m5 - pmullw m0, filter_x_a - pmullw m1, filter_x_b - punpcklbw m3, m5 - paddw m0, filter_rnd - pmullw m2, filter_x_a - pmullw m4, filter_x_b - paddw m0, m1 - paddw m2, filter_rnd - movx m1, [refq] - paddw m2, m4 -%endif - psraw m0, 4 - psraw m2, 4 -%if %2 == 1 ; avg - ; FIXME(rbultje) pipeline -%if %1 == 4 - movlhps m0, m2 -%endif - packuswb m0, m2 -%if %1 > 4 - pavgb m0, [second_predq] - punpckhbw m2, m0, m5 - punpcklbw m0, m5 -%else - movh m2, [second_predq] - pavgb m0, m2 - punpcklbw m0, m5 - movhlps m2, m0 -%endif -%endif - punpcklbw m1, m5 - SUM_SSE m0, m1, m2, m3, m6, m7 - - lea srcq, [srcq+src_strideq*2] - lea refq, [refq+ref_strideq*2] -%endif -%if %2 == 1 ; avg - add second_predq, second_str -%endif - dec block_height - jg .x_other_y_zero_loop -%undef filter_x_a -%undef filter_x_b -%undef filter_rnd - STORE_AND_RET %1 - -.x_nonhalf_y_nonzero: - cmp y_offsetd, 4 - jne .x_nonhalf_y_nonhalf - - ; x_offset == bilin interpolation && y_offset == 0.5 -%if VPX_ARCH_X86_64 - lea bilin_filter, [GLOBAL(bilin_filter_m)] -%endif - shl x_offsetd, filter_idx_shift -%if VPX_ARCH_X86_64 && %1 > 4 - mova m8, [bilin_filter+x_offsetq] -%if notcpuflag(ssse3) ; FIXME(rbultje) don't scatter registers on x86-64 - mova m9, [bilin_filter+x_offsetq+16] -%endif - mova m10, [GLOBAL(pw_8)] -%define filter_x_a m8 -%define filter_x_b m9 -%define filter_rnd m10 -%else ; x86-32 -%if VPX_ARCH_X86=1 && CONFIG_PIC=1 -; y_offset == 0.5. We can reuse y_offset reg. -%define tempq y_offsetq - add x_offsetq, g_bilin_filterm -%define filter_x_a [x_offsetq] -%define filter_x_b [x_offsetq+16] - mov tempq, g_pw_8m -%define filter_rnd [tempq] -%else - add x_offsetq, bilin_filter -%define filter_x_a [x_offsetq] -%define filter_x_b [x_offsetq+16] -%define filter_rnd [GLOBAL(pw_8)] -%endif -%endif - -%if %1 == 16 - movu m0, [srcq] - movu m1, [srcq+1] -%if cpuflag(ssse3) - punpckhbw m2, m0, m1 - punpcklbw m0, m1 - pmaddubsw m2, filter_x_a - pmaddubsw m0, filter_x_a - paddw m2, filter_rnd - paddw m0, filter_rnd -%else - punpckhbw m2, m0, m5 - punpckhbw m3, m1, m5 - punpcklbw m0, m5 - punpcklbw m1, m5 - pmullw m0, filter_x_a - pmullw m1, filter_x_b - paddw m0, filter_rnd - pmullw m2, filter_x_a - pmullw m3, filter_x_b - paddw m2, filter_rnd - paddw m0, m1 - paddw m2, m3 -%endif - psraw m0, 4 - psraw m2, 4 - add srcq, src_strideq - packuswb m0, m2 -.x_other_y_half_loop: - movu m4, [srcq] - movu m3, [srcq+1] -%if cpuflag(ssse3) - mova m1, [refq] - punpckhbw m2, m4, m3 - punpcklbw m4, m3 - pmaddubsw m2, filter_x_a - pmaddubsw m4, filter_x_a - paddw m2, filter_rnd - paddw m4, filter_rnd - psraw m2, 4 - psraw m4, 4 - packuswb m4, m2 - pavgb m0, m4 - punpckhbw m3, m1, m5 - punpcklbw m1, m5 -%else - punpckhbw m2, m4, m5 - punpckhbw m1, m3, m5 - punpcklbw m4, m5 - punpcklbw m3, m5 - pmullw m4, filter_x_a - pmullw m3, filter_x_b - paddw m4, filter_rnd - pmullw m2, filter_x_a - pmullw m1, filter_x_b - paddw m2, filter_rnd - paddw m4, m3 - paddw m2, m1 - mova m1, [refq] - psraw m4, 4 - psraw m2, 4 - punpckhbw m3, m1, m5 - ; FIXME(rbultje) the repeated pack/unpack here around m0/m2 is because we - ; have a 1-register shortage to be able to store the backup of the bilin - ; filtered second line as words as cache for the next line. Packing into - ; a byte costs 1 pack and 2 unpacks, but saves a register. - packuswb m4, m2 - punpcklbw m1, m5 - pavgb m0, m4 -%endif -%if %2 == 1 ; avg - ; FIXME(rbultje) pipeline - pavgb m0, [second_predq] -%endif - punpckhbw m2, m0, m5 - punpcklbw m0, m5 - SUM_SSE m0, m1, m2, m3, m6, m7 - mova m0, m4 - - add srcq, src_strideq - add refq, ref_strideq -%else ; %1 < 16 - movx m0, [srcq] - movx m1, [srcq+1] -%if cpuflag(ssse3) - punpcklbw m0, m1 - pmaddubsw m0, filter_x_a - paddw m0, filter_rnd -%else - punpcklbw m0, m5 - punpcklbw m1, m5 - pmullw m0, filter_x_a - pmullw m1, filter_x_b - paddw m0, filter_rnd - paddw m0, m1 -%endif - add srcq, src_strideq - psraw m0, 4 -.x_other_y_half_loop: - movx m2, [srcq] - movx m1, [srcq+1] - movx m4, [srcq+src_strideq] - movx m3, [srcq+src_strideq+1] -%if cpuflag(ssse3) - punpcklbw m2, m1 - punpcklbw m4, m3 - pmaddubsw m2, filter_x_a - pmaddubsw m4, filter_x_a - movx m1, [refq] - movx m3, [refq+ref_strideq] - paddw m2, filter_rnd - paddw m4, filter_rnd -%else - punpcklbw m2, m5 - punpcklbw m1, m5 - punpcklbw m4, m5 - punpcklbw m3, m5 - pmullw m2, filter_x_a - pmullw m1, filter_x_b - paddw m2, filter_rnd - pmullw m4, filter_x_a - pmullw m3, filter_x_b - paddw m4, filter_rnd - paddw m2, m1 - movx m1, [refq] - paddw m4, m3 - movx m3, [refq+ref_strideq] -%endif - psraw m2, 4 - psraw m4, 4 - pavgw m0, m2 - pavgw m2, m4 -%if %2 == 1 ; avg - ; FIXME(rbultje) pipeline - also consider going to bytes here -%if %1 == 4 - movlhps m0, m2 -%endif - packuswb m0, m2 -%if %1 > 4 - pavgb m0, [second_predq] - punpckhbw m2, m0, m5 - punpcklbw m0, m5 -%else - movh m2, [second_predq] - pavgb m0, m2 - punpcklbw m0, m5 - movhlps m2, m0 -%endif -%endif - punpcklbw m3, m5 - punpcklbw m1, m5 - SUM_SSE m0, m1, m2, m3, m6, m7 - mova m0, m4 - - lea srcq, [srcq+src_strideq*2] - lea refq, [refq+ref_strideq*2] -%endif -%if %2 == 1 ; avg - add second_predq, second_str -%endif - dec block_height - jg .x_other_y_half_loop -%undef filter_x_a -%undef filter_x_b -%undef filter_rnd - STORE_AND_RET %1 - -.x_nonhalf_y_nonhalf: -%if VPX_ARCH_X86_64 - lea bilin_filter, [GLOBAL(bilin_filter_m)] -%endif - shl x_offsetd, filter_idx_shift - shl y_offsetd, filter_idx_shift -%if VPX_ARCH_X86_64 && %1 > 4 - mova m8, [bilin_filter+x_offsetq] -%if notcpuflag(ssse3) ; FIXME(rbultje) don't scatter registers on x86-64 - mova m9, [bilin_filter+x_offsetq+16] -%endif - mova m10, [bilin_filter+y_offsetq] -%if notcpuflag(ssse3) ; FIXME(rbultje) don't scatter registers on x86-64 - mova m11, [bilin_filter+y_offsetq+16] -%endif - mova m12, [GLOBAL(pw_8)] -%define filter_x_a m8 -%define filter_x_b m9 -%define filter_y_a m10 -%define filter_y_b m11 -%define filter_rnd m12 -%else ; x86-32 -%if VPX_ARCH_X86=1 && CONFIG_PIC=1 -; In this case, there is NO unused register. Used src_stride register. Later, -; src_stride has to be loaded from stack when it is needed. -%define tempq src_strideq - mov tempq, g_bilin_filterm - add x_offsetq, tempq - add y_offsetq, tempq -%define filter_x_a [x_offsetq] -%define filter_x_b [x_offsetq+16] -%define filter_y_a [y_offsetq] -%define filter_y_b [y_offsetq+16] - - mov tempq, g_pw_8m -%define filter_rnd [tempq] -%else - add x_offsetq, bilin_filter - add y_offsetq, bilin_filter -%define filter_x_a [x_offsetq] -%define filter_x_b [x_offsetq+16] -%define filter_y_a [y_offsetq] -%define filter_y_b [y_offsetq+16] -%define filter_rnd [GLOBAL(pw_8)] -%endif -%endif - - ; x_offset == bilin interpolation && y_offset == bilin interpolation -%if %1 == 16 - movu m0, [srcq] - movu m1, [srcq+1] -%if cpuflag(ssse3) - punpckhbw m2, m0, m1 - punpcklbw m0, m1 - pmaddubsw m2, filter_x_a - pmaddubsw m0, filter_x_a - paddw m2, filter_rnd - paddw m0, filter_rnd -%else - punpckhbw m2, m0, m5 - punpckhbw m3, m1, m5 - punpcklbw m0, m5 - punpcklbw m1, m5 - pmullw m0, filter_x_a - pmullw m1, filter_x_b - paddw m0, filter_rnd - pmullw m2, filter_x_a - pmullw m3, filter_x_b - paddw m2, filter_rnd - paddw m0, m1 - paddw m2, m3 -%endif - psraw m0, 4 - psraw m2, 4 - - INC_SRC_BY_SRC_STRIDE - - packuswb m0, m2 -.x_other_y_other_loop: -%if cpuflag(ssse3) - movu m4, [srcq] - movu m3, [srcq+1] - mova m1, [refq] - punpckhbw m2, m4, m3 - punpcklbw m4, m3 - pmaddubsw m2, filter_x_a - pmaddubsw m4, filter_x_a - punpckhbw m3, m1, m5 - paddw m2, filter_rnd - paddw m4, filter_rnd - psraw m2, 4 - psraw m4, 4 - packuswb m4, m2 - punpckhbw m2, m0, m4 - punpcklbw m0, m4 - pmaddubsw m2, filter_y_a - pmaddubsw m0, filter_y_a - punpcklbw m1, m5 - paddw m2, filter_rnd - paddw m0, filter_rnd - psraw m2, 4 - psraw m0, 4 -%else - movu m3, [srcq] - movu m4, [srcq+1] - punpckhbw m1, m3, m5 - punpckhbw m2, m4, m5 - punpcklbw m3, m5 - punpcklbw m4, m5 - pmullw m3, filter_x_a - pmullw m4, filter_x_b - paddw m3, filter_rnd - pmullw m1, filter_x_a - pmullw m2, filter_x_b - paddw m1, filter_rnd - paddw m3, m4 - paddw m1, m2 - psraw m3, 4 - psraw m1, 4 - packuswb m4, m3, m1 - punpckhbw m2, m0, m5 - punpcklbw m0, m5 - pmullw m2, filter_y_a - pmullw m1, filter_y_b - paddw m2, filter_rnd - pmullw m0, filter_y_a - pmullw m3, filter_y_b - paddw m2, m1 - mova m1, [refq] - paddw m0, filter_rnd - psraw m2, 4 - paddw m0, m3 - punpckhbw m3, m1, m5 - psraw m0, 4 - punpcklbw m1, m5 -%endif -%if %2 == 1 ; avg - ; FIXME(rbultje) pipeline - packuswb m0, m2 - pavgb m0, [second_predq] - punpckhbw m2, m0, m5 - punpcklbw m0, m5 -%endif - SUM_SSE m0, m1, m2, m3, m6, m7 - mova m0, m4 - - INC_SRC_BY_SRC_STRIDE - add refq, ref_strideq -%else ; %1 < 16 - movx m0, [srcq] - movx m1, [srcq+1] -%if cpuflag(ssse3) - punpcklbw m0, m1 - pmaddubsw m0, filter_x_a - paddw m0, filter_rnd -%else - punpcklbw m0, m5 - punpcklbw m1, m5 - pmullw m0, filter_x_a - pmullw m1, filter_x_b - paddw m0, filter_rnd - paddw m0, m1 -%endif - psraw m0, 4 -%if cpuflag(ssse3) - packuswb m0, m0 -%endif - - INC_SRC_BY_SRC_STRIDE - -.x_other_y_other_loop: - movx m2, [srcq] - movx m1, [srcq+1] - - INC_SRC_BY_SRC_STRIDE - movx m4, [srcq] - movx m3, [srcq+1] - -%if cpuflag(ssse3) - punpcklbw m2, m1 - punpcklbw m4, m3 - pmaddubsw m2, filter_x_a - pmaddubsw m4, filter_x_a - movx m3, [refq+ref_strideq] - movx m1, [refq] - paddw m2, filter_rnd - paddw m4, filter_rnd - psraw m2, 4 - psraw m4, 4 - packuswb m2, m2 - packuswb m4, m4 - punpcklbw m0, m2 - punpcklbw m2, m4 - pmaddubsw m0, filter_y_a - pmaddubsw m2, filter_y_a - punpcklbw m3, m5 - paddw m0, filter_rnd - paddw m2, filter_rnd - psraw m0, 4 - psraw m2, 4 - punpcklbw m1, m5 -%else - punpcklbw m2, m5 - punpcklbw m1, m5 - punpcklbw m4, m5 - punpcklbw m3, m5 - pmullw m2, filter_x_a - pmullw m1, filter_x_b - paddw m2, filter_rnd - pmullw m4, filter_x_a - pmullw m3, filter_x_b - paddw m4, filter_rnd - paddw m2, m1 - paddw m4, m3 - psraw m2, 4 - psraw m4, 4 - pmullw m0, filter_y_a - pmullw m3, m2, filter_y_b - paddw m0, filter_rnd - pmullw m2, filter_y_a - pmullw m1, m4, filter_y_b - paddw m2, filter_rnd - paddw m0, m3 - movx m3, [refq+ref_strideq] - paddw m2, m1 - movx m1, [refq] - psraw m0, 4 - psraw m2, 4 - punpcklbw m3, m5 - punpcklbw m1, m5 -%endif -%if %2 == 1 ; avg - ; FIXME(rbultje) pipeline -%if %1 == 4 - movlhps m0, m2 -%endif - packuswb m0, m2 -%if %1 > 4 - pavgb m0, [second_predq] - punpckhbw m2, m0, m5 - punpcklbw m0, m5 -%else - movh m2, [second_predq] - pavgb m0, m2 - punpcklbw m0, m5 - movhlps m2, m0 -%endif -%endif - SUM_SSE m0, m1, m2, m3, m6, m7 - mova m0, m4 - - INC_SRC_BY_SRC_STRIDE - lea refq, [refq+ref_strideq*2] -%endif -%if %2 == 1 ; avg - add second_predq, second_str -%endif - dec block_height - jg .x_other_y_other_loop -%undef filter_x_a -%undef filter_x_b -%undef filter_y_a -%undef filter_y_b -%undef filter_rnd -%undef movx - STORE_AND_RET %1 -%endmacro - -; FIXME(rbultje) the non-bilinear versions (i.e. x=0,8&&y=0,8) are identical -; between the ssse3 and non-ssse3 version. It may make sense to merge their -; code in the sense that the ssse3 version would jump to the appropriate -; location in the sse/2 version, rather than duplicating that code in the -; binary. - -INIT_XMM sse2 -SUBPEL_VARIANCE 4 -SUBPEL_VARIANCE 8 -SUBPEL_VARIANCE 16 - -INIT_XMM ssse3 -SUBPEL_VARIANCE 4 -SUBPEL_VARIANCE 8 -SUBPEL_VARIANCE 16 - -INIT_XMM sse2 -SUBPEL_VARIANCE 4, 1 -SUBPEL_VARIANCE 8, 1 -SUBPEL_VARIANCE 16, 1 - -INIT_XMM ssse3 -SUBPEL_VARIANCE 4, 1 -SUBPEL_VARIANCE 8, 1 -SUBPEL_VARIANCE 16, 1 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/subtract_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/subtract_avx2.c deleted file mode 100644 index 4849581e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/subtract_avx2.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" - -static VPX_FORCE_INLINE void subtract32_avx2(int16_t *diff_ptr, - const uint8_t *src_ptr, - const uint8_t *pred_ptr) { - const __m256i s = _mm256_lddqu_si256((const __m256i *)src_ptr); - const __m256i p = _mm256_lddqu_si256((const __m256i *)pred_ptr); - const __m256i s_0 = _mm256_cvtepu8_epi16(_mm256_castsi256_si128(s)); - const __m256i s_1 = _mm256_cvtepu8_epi16(_mm256_extracti128_si256(s, 1)); - const __m256i p_0 = _mm256_cvtepu8_epi16(_mm256_castsi256_si128(p)); - const __m256i p_1 = _mm256_cvtepu8_epi16(_mm256_extracti128_si256(p, 1)); - const __m256i d_0 = _mm256_sub_epi16(s_0, p_0); - const __m256i d_1 = _mm256_sub_epi16(s_1, p_1); - _mm256_storeu_si256((__m256i *)diff_ptr, d_0); - _mm256_storeu_si256((__m256i *)(diff_ptr + 16), d_1); -} - -static VPX_FORCE_INLINE void subtract_block_16xn_avx2( - int rows, int16_t *diff_ptr, ptrdiff_t diff_stride, const uint8_t *src_ptr, - ptrdiff_t src_stride, const uint8_t *pred_ptr, ptrdiff_t pred_stride) { - int j; - for (j = 0; j < rows; ++j) { - const __m128i s = _mm_lddqu_si128((const __m128i *)src_ptr); - const __m128i p = _mm_lddqu_si128((const __m128i *)pred_ptr); - const __m256i s_0 = _mm256_cvtepu8_epi16(s); - const __m256i p_0 = _mm256_cvtepu8_epi16(p); - const __m256i d_0 = _mm256_sub_epi16(s_0, p_0); - _mm256_storeu_si256((__m256i *)diff_ptr, d_0); - src_ptr += src_stride; - pred_ptr += pred_stride; - diff_ptr += diff_stride; - } -} - -static VPX_FORCE_INLINE void subtract_block_32xn_avx2( - int rows, int16_t *diff_ptr, ptrdiff_t diff_stride, const uint8_t *src_ptr, - ptrdiff_t src_stride, const uint8_t *pred_ptr, ptrdiff_t pred_stride) { - int j; - for (j = 0; j < rows; ++j) { - subtract32_avx2(diff_ptr, src_ptr, pred_ptr); - src_ptr += src_stride; - pred_ptr += pred_stride; - diff_ptr += diff_stride; - } -} - -static VPX_FORCE_INLINE void subtract_block_64xn_avx2( - int rows, int16_t *diff_ptr, ptrdiff_t diff_stride, const uint8_t *src_ptr, - ptrdiff_t src_stride, const uint8_t *pred_ptr, ptrdiff_t pred_stride) { - int j; - for (j = 0; j < rows; ++j) { - subtract32_avx2(diff_ptr, src_ptr, pred_ptr); - subtract32_avx2(diff_ptr + 32, src_ptr + 32, pred_ptr + 32); - src_ptr += src_stride; - pred_ptr += pred_stride; - diff_ptr += diff_stride; - } -} - -void vpx_subtract_block_avx2(int rows, int cols, int16_t *diff_ptr, - ptrdiff_t diff_stride, const uint8_t *src_ptr, - ptrdiff_t src_stride, const uint8_t *pred_ptr, - ptrdiff_t pred_stride) { - switch (cols) { - case 16: - subtract_block_16xn_avx2(rows, diff_ptr, diff_stride, src_ptr, src_stride, - pred_ptr, pred_stride); - break; - case 32: - subtract_block_32xn_avx2(rows, diff_ptr, diff_stride, src_ptr, src_stride, - pred_ptr, pred_stride); - break; - case 64: - subtract_block_64xn_avx2(rows, diff_ptr, diff_stride, src_ptr, src_stride, - pred_ptr, pred_stride); - break; - default: - vpx_subtract_block_sse2(rows, cols, diff_ptr, diff_stride, src_ptr, - src_stride, pred_ptr, pred_stride); - break; - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -void vpx_highbd_subtract_block_avx2(int rows, int cols, int16_t *diff_ptr, - ptrdiff_t diff_stride, - const uint8_t *src8_ptr, - ptrdiff_t src_stride, - const uint8_t *pred8_ptr, - ptrdiff_t pred_stride, int bd) { - uint16_t *src_ptr = CONVERT_TO_SHORTPTR(src8_ptr); - uint16_t *pred_ptr = CONVERT_TO_SHORTPTR(pred8_ptr); - (void)bd; - if (cols == 64) { - int j = rows; - do { - const __m256i s0 = _mm256_lddqu_si256((const __m256i *)src_ptr); - const __m256i s1 = _mm256_lddqu_si256((const __m256i *)(src_ptr + 16)); - const __m256i s2 = _mm256_lddqu_si256((const __m256i *)(src_ptr + 32)); - const __m256i s3 = _mm256_lddqu_si256((const __m256i *)(src_ptr + 48)); - const __m256i p0 = _mm256_lddqu_si256((const __m256i *)pred_ptr); - const __m256i p1 = _mm256_lddqu_si256((const __m256i *)(pred_ptr + 16)); - const __m256i p2 = _mm256_lddqu_si256((const __m256i *)(pred_ptr + 32)); - const __m256i p3 = _mm256_lddqu_si256((const __m256i *)(pred_ptr + 48)); - const __m256i d0 = _mm256_sub_epi16(s0, p0); - const __m256i d1 = _mm256_sub_epi16(s1, p1); - const __m256i d2 = _mm256_sub_epi16(s2, p2); - const __m256i d3 = _mm256_sub_epi16(s3, p3); - _mm256_storeu_si256((__m256i *)diff_ptr, d0); - _mm256_storeu_si256((__m256i *)(diff_ptr + 16), d1); - _mm256_storeu_si256((__m256i *)(diff_ptr + 32), d2); - _mm256_storeu_si256((__m256i *)(diff_ptr + 48), d3); - src_ptr += src_stride; - pred_ptr += pred_stride; - diff_ptr += diff_stride; - } while (--j != 0); - } else if (cols == 32) { - int j = rows; - do { - const __m256i s0 = _mm256_lddqu_si256((const __m256i *)src_ptr); - const __m256i s1 = _mm256_lddqu_si256((const __m256i *)(src_ptr + 16)); - const __m256i p0 = _mm256_lddqu_si256((const __m256i *)pred_ptr); - const __m256i p1 = _mm256_lddqu_si256((const __m256i *)(pred_ptr + 16)); - const __m256i d0 = _mm256_sub_epi16(s0, p0); - const __m256i d1 = _mm256_sub_epi16(s1, p1); - _mm256_storeu_si256((__m256i *)diff_ptr, d0); - _mm256_storeu_si256((__m256i *)(diff_ptr + 16), d1); - src_ptr += src_stride; - pred_ptr += pred_stride; - diff_ptr += diff_stride; - } while (--j != 0); - } else if (cols == 16) { - int j = rows; - do { - const __m256i s0 = _mm256_lddqu_si256((const __m256i *)src_ptr); - const __m256i s1 = - _mm256_lddqu_si256((const __m256i *)(src_ptr + src_stride)); - const __m256i p0 = _mm256_lddqu_si256((const __m256i *)pred_ptr); - const __m256i p1 = - _mm256_lddqu_si256((const __m256i *)(pred_ptr + pred_stride)); - const __m256i d0 = _mm256_sub_epi16(s0, p0); - const __m256i d1 = _mm256_sub_epi16(s1, p1); - _mm256_storeu_si256((__m256i *)diff_ptr, d0); - _mm256_storeu_si256((__m256i *)(diff_ptr + diff_stride), d1); - src_ptr += src_stride << 1; - pred_ptr += pred_stride << 1; - diff_ptr += diff_stride << 1; - j -= 2; - } while (j != 0); - } else if (cols == 8) { - int j = rows; - do { - const __m128i s0 = _mm_lddqu_si128((const __m128i *)src_ptr); - const __m128i s1 = - _mm_lddqu_si128((const __m128i *)(src_ptr + src_stride)); - const __m128i p0 = _mm_lddqu_si128((const __m128i *)pred_ptr); - const __m128i p1 = - _mm_lddqu_si128((const __m128i *)(pred_ptr + pred_stride)); - const __m128i d0 = _mm_sub_epi16(s0, p0); - const __m128i d1 = _mm_sub_epi16(s1, p1); - _mm_storeu_si128((__m128i *)diff_ptr, d0); - _mm_storeu_si128((__m128i *)(diff_ptr + diff_stride), d1); - src_ptr += src_stride << 1; - pred_ptr += pred_stride << 1; - diff_ptr += diff_stride << 1; - j -= 2; - } while (j != 0); - } else { - int j = rows; - assert(cols == 4); - do { - const __m128i s0 = _mm_loadl_epi64((const __m128i *)src_ptr); - const __m128i s1 = - _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride)); - const __m128i p0 = _mm_loadl_epi64((const __m128i *)pred_ptr); - const __m128i p1 = - _mm_loadl_epi64((const __m128i *)(pred_ptr + pred_stride)); - const __m128i d0 = _mm_sub_epi16(s0, p0); - const __m128i d1 = _mm_sub_epi16(s1, p1); - _mm_storel_epi64((__m128i *)diff_ptr, d0); - _mm_storel_epi64((__m128i *)(diff_ptr + diff_stride), d1); - src_ptr += src_stride << 1; - pred_ptr += pred_stride << 1; - diff_ptr += diff_stride << 1; - j -= 2; - } while (j != 0); - } -} -#endif // CONFIG_VP9_HIGHBITDEPTH diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/subtract_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/subtract_sse2.asm deleted file mode 100644 index e3055ab2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/subtract_sse2.asm +++ /dev/null @@ -1,128 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "third_party/x86inc/x86inc.asm" - -SECTION .text - -; void vpx_subtract_block(int rows, int cols, -; int16_t *diff, ptrdiff_t diff_stride, -; const uint8_t *src, ptrdiff_t src_stride, -; const uint8_t *pred, ptrdiff_t pred_stride) - -INIT_XMM sse2 -cglobal subtract_block, 7, 7, 8, \ - rows, cols, diff, diff_stride, src, src_stride, \ - pred, pred_stride -%define pred_str colsq - pxor m7, m7 ; dedicated zero register - cmp colsd, 4 - je .case_4 - cmp colsd, 8 - je .case_8 - cmp colsd, 16 - je .case_16 - cmp colsd, 32 - je .case_32 - -%macro loop16 6 - mova m0, [srcq+%1] - mova m4, [srcq+%2] - mova m1, [predq+%3] - mova m5, [predq+%4] - punpckhbw m2, m0, m7 - punpckhbw m3, m1, m7 - punpcklbw m0, m7 - punpcklbw m1, m7 - psubw m2, m3 - psubw m0, m1 - punpckhbw m1, m4, m7 - punpckhbw m3, m5, m7 - punpcklbw m4, m7 - punpcklbw m5, m7 - psubw m1, m3 - psubw m4, m5 - mova [diffq+mmsize*0+%5], m0 - mova [diffq+mmsize*1+%5], m2 - mova [diffq+mmsize*0+%6], m4 - mova [diffq+mmsize*1+%6], m1 -%endmacro - - mov pred_str, pred_stridemp -.loop_64: - loop16 0*mmsize, 1*mmsize, 0*mmsize, 1*mmsize, 0*mmsize, 2*mmsize - loop16 2*mmsize, 3*mmsize, 2*mmsize, 3*mmsize, 4*mmsize, 6*mmsize - lea diffq, [diffq+diff_strideq*2] - add predq, pred_str - add srcq, src_strideq - dec rowsd - jg .loop_64 - RET - -.case_32: - mov pred_str, pred_stridemp -.loop_32: - loop16 0, mmsize, 0, mmsize, 0, 2*mmsize - lea diffq, [diffq+diff_strideq*2] - add predq, pred_str - add srcq, src_strideq - dec rowsd - jg .loop_32 - RET - -.case_16: - mov pred_str, pred_stridemp -.loop_16: - loop16 0, src_strideq, 0, pred_str, 0, diff_strideq*2 - lea diffq, [diffq+diff_strideq*4] - lea predq, [predq+pred_str*2] - lea srcq, [srcq+src_strideq*2] - sub rowsd, 2 - jg .loop_16 - RET - -%macro loop_h 0 - movh m0, [srcq] - movh m2, [srcq+src_strideq] - movh m1, [predq] - movh m3, [predq+pred_str] - punpcklbw m0, m7 - punpcklbw m1, m7 - punpcklbw m2, m7 - punpcklbw m3, m7 - psubw m0, m1 - psubw m2, m3 - mova [diffq], m0 - mova [diffq+diff_strideq*2], m2 -%endmacro - -.case_8: - mov pred_str, pred_stridemp -.loop_8: - loop_h - lea diffq, [diffq+diff_strideq*4] - lea srcq, [srcq+src_strideq*2] - lea predq, [predq+pred_str*2] - sub rowsd, 2 - jg .loop_8 - RET - -INIT_MMX -.case_4: - mov pred_str, pred_stridemp -.loop_4: - loop_h - lea diffq, [diffq+diff_strideq*4] - lea srcq, [srcq+src_strideq*2] - lea predq, [predq+pred_str*2] - sub rowsd, 2 - jg .loop_4 - emms - RET diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sum_squares_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sum_squares_sse2.c deleted file mode 100644 index df6514b2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/sum_squares_sse2.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2016 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/x86/mem_sse2.h" - -uint64_t vpx_sum_squares_2d_i16_sse2(const int16_t *src, int stride, int size) { - // Over 75% of all calls are with size == 4. - if (size == 4) { - __m128i s[2], sq[2], ss; - - s[0] = _mm_loadl_epi64((const __m128i *)(src + 0 * stride)); - s[0] = loadh_epi64(s[0], src + 1 * stride); - s[1] = _mm_loadl_epi64((const __m128i *)(src + 2 * stride)); - s[1] = loadh_epi64(s[1], src + 3 * stride); - sq[0] = _mm_madd_epi16(s[0], s[0]); - sq[1] = _mm_madd_epi16(s[1], s[1]); - sq[0] = _mm_add_epi32(sq[0], sq[1]); - ss = _mm_add_epi32(sq[0], _mm_srli_si128(sq[0], 8)); - ss = _mm_add_epi32(ss, _mm_srli_epi64(ss, 32)); - - return (uint64_t)_mm_cvtsi128_si32(ss); - } else { - // Generic case - int r = size; - const __m128i v_zext_mask_q = _mm_set_epi32(0, -1, 0, -1); - __m128i v_acc_q = _mm_setzero_si128(); - - assert(size % 8 == 0); - - do { - int c = 0; - __m128i v_acc_d = _mm_setzero_si128(); - - do { - const int16_t *const b = src + c; - const __m128i v_val_0_w = - _mm_load_si128((const __m128i *)(b + 0 * stride)); - const __m128i v_val_1_w = - _mm_load_si128((const __m128i *)(b + 1 * stride)); - const __m128i v_val_2_w = - _mm_load_si128((const __m128i *)(b + 2 * stride)); - const __m128i v_val_3_w = - _mm_load_si128((const __m128i *)(b + 3 * stride)); - const __m128i v_val_4_w = - _mm_load_si128((const __m128i *)(b + 4 * stride)); - const __m128i v_val_5_w = - _mm_load_si128((const __m128i *)(b + 5 * stride)); - const __m128i v_val_6_w = - _mm_load_si128((const __m128i *)(b + 6 * stride)); - const __m128i v_val_7_w = - _mm_load_si128((const __m128i *)(b + 7 * stride)); - - const __m128i v_sq_0_d = _mm_madd_epi16(v_val_0_w, v_val_0_w); - const __m128i v_sq_1_d = _mm_madd_epi16(v_val_1_w, v_val_1_w); - const __m128i v_sq_2_d = _mm_madd_epi16(v_val_2_w, v_val_2_w); - const __m128i v_sq_3_d = _mm_madd_epi16(v_val_3_w, v_val_3_w); - const __m128i v_sq_4_d = _mm_madd_epi16(v_val_4_w, v_val_4_w); - const __m128i v_sq_5_d = _mm_madd_epi16(v_val_5_w, v_val_5_w); - const __m128i v_sq_6_d = _mm_madd_epi16(v_val_6_w, v_val_6_w); - const __m128i v_sq_7_d = _mm_madd_epi16(v_val_7_w, v_val_7_w); - - const __m128i v_sum_01_d = _mm_add_epi32(v_sq_0_d, v_sq_1_d); - const __m128i v_sum_23_d = _mm_add_epi32(v_sq_2_d, v_sq_3_d); - const __m128i v_sum_45_d = _mm_add_epi32(v_sq_4_d, v_sq_5_d); - const __m128i v_sum_67_d = _mm_add_epi32(v_sq_6_d, v_sq_7_d); - - const __m128i v_sum_0123_d = _mm_add_epi32(v_sum_01_d, v_sum_23_d); - const __m128i v_sum_4567_d = _mm_add_epi32(v_sum_45_d, v_sum_67_d); - - v_acc_d = _mm_add_epi32(v_acc_d, v_sum_0123_d); - v_acc_d = _mm_add_epi32(v_acc_d, v_sum_4567_d); - c += 8; - } while (c < size); - - v_acc_q = _mm_add_epi64(v_acc_q, _mm_and_si128(v_acc_d, v_zext_mask_q)); - v_acc_q = _mm_add_epi64(v_acc_q, _mm_srli_epi64(v_acc_d, 32)); - - src += 8 * stride; - r -= 8; - } while (r); - - v_acc_q = _mm_add_epi64(v_acc_q, _mm_srli_si128(v_acc_q, 8)); - -#if VPX_ARCH_X86_64 - return (uint64_t)_mm_cvtsi128_si64(v_acc_q); -#else - { - uint64_t tmp; - _mm_storel_epi64((__m128i *)&tmp, v_acc_q); - return tmp; - } -#endif - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/transpose_sse2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/transpose_sse2.h deleted file mode 100644 index b4f1190d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/transpose_sse2.h +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_X86_TRANSPOSE_SSE2_H_ -#define VPX_VPX_DSP_X86_TRANSPOSE_SSE2_H_ - -#include // SSE2 - -#include "./vpx_config.h" - -static INLINE __m128i transpose_8bit_4x4(const __m128i *const in) { - // Unpack 8 bit elements. Goes from: - // in[0]: 00 01 02 03 - // in[1]: 10 11 12 13 - // in[2]: 20 21 22 23 - // in[3]: 30 31 32 33 - // to: - // a0: 00 10 01 11 02 12 03 13 - // a1: 20 30 21 31 22 32 23 33 - const __m128i a0 = _mm_unpacklo_epi8(in[0], in[1]); - const __m128i a1 = _mm_unpacklo_epi8(in[2], in[3]); - - // Unpack 16 bit elements resulting in: - // 00 10 20 30 01 11 21 31 02 12 22 32 03 13 23 33 - return _mm_unpacklo_epi16(a0, a1); -} - -static INLINE void transpose_8bit_8x8(const __m128i *const in, - __m128i *const out) { - // Unpack 8 bit elements. Goes from: - // in[0]: 00 01 02 03 04 05 06 07 - // in[1]: 10 11 12 13 14 15 16 17 - // in[2]: 20 21 22 23 24 25 26 27 - // in[3]: 30 31 32 33 34 35 36 37 - // in[4]: 40 41 42 43 44 45 46 47 - // in[5]: 50 51 52 53 54 55 56 57 - // in[6]: 60 61 62 63 64 65 66 67 - // in[7]: 70 71 72 73 74 75 76 77 - // to: - // a0: 00 10 01 11 02 12 03 13 04 14 05 15 06 16 07 17 - // a1: 20 30 21 31 22 32 23 33 24 34 25 35 26 36 27 37 - // a2: 40 50 41 51 42 52 43 53 44 54 45 55 46 56 47 57 - // a3: 60 70 61 71 62 72 63 73 64 74 65 75 66 76 67 77 - const __m128i a0 = _mm_unpacklo_epi8(in[0], in[1]); - const __m128i a1 = _mm_unpacklo_epi8(in[2], in[3]); - const __m128i a2 = _mm_unpacklo_epi8(in[4], in[5]); - const __m128i a3 = _mm_unpacklo_epi8(in[6], in[7]); - - // Unpack 16 bit elements resulting in: - // b0: 00 10 20 30 01 11 21 31 02 12 22 32 03 13 23 33 - // b1: 40 50 60 70 41 51 61 71 42 52 62 72 43 53 63 73 - // b2: 04 14 24 34 05 15 25 35 06 16 26 36 07 17 27 37 - // b3: 44 54 64 74 45 55 65 75 46 56 66 76 47 57 67 77 - const __m128i b0 = _mm_unpacklo_epi16(a0, a1); - const __m128i b1 = _mm_unpackhi_epi16(a0, a1); - const __m128i b2 = _mm_unpacklo_epi16(a2, a3); - const __m128i b3 = _mm_unpackhi_epi16(a2, a3); - - // Unpack 32 bit elements resulting in: - // c0: 00 10 20 30 40 50 60 70 01 11 21 31 41 51 61 71 - // c1: 02 12 22 32 42 52 62 72 03 13 23 33 43 53 63 73 - // c2: 04 14 24 34 44 54 64 74 05 15 25 35 45 55 65 75 - // c3: 06 16 26 36 46 56 66 76 07 17 27 37 47 57 67 77 - const __m128i c0 = _mm_unpacklo_epi32(b0, b2); - const __m128i c1 = _mm_unpackhi_epi32(b0, b2); - const __m128i c2 = _mm_unpacklo_epi32(b1, b3); - const __m128i c3 = _mm_unpackhi_epi32(b1, b3); - - // Unpack 64 bit elements resulting in: - // out[0]: 00 10 20 30 40 50 60 70 - // out[1]: 01 11 21 31 41 51 61 71 - // out[2]: 02 12 22 32 42 52 62 72 - // out[3]: 03 13 23 33 43 53 63 73 - // out[4]: 04 14 24 34 44 54 64 74 - // out[5]: 05 15 25 35 45 55 65 75 - // out[6]: 06 16 26 36 46 56 66 76 - // out[7]: 07 17 27 37 47 57 67 77 - out[0] = _mm_unpacklo_epi64(c0, c0); - out[1] = _mm_unpackhi_epi64(c0, c0); - out[2] = _mm_unpacklo_epi64(c1, c1); - out[3] = _mm_unpackhi_epi64(c1, c1); - out[4] = _mm_unpacklo_epi64(c2, c2); - out[5] = _mm_unpackhi_epi64(c2, c2); - out[6] = _mm_unpacklo_epi64(c3, c3); - out[7] = _mm_unpackhi_epi64(c3, c3); -} - -static INLINE void transpose_16bit_4x4(const __m128i *const in, - __m128i *const out) { - // Unpack 16 bit elements. Goes from: - // in[0]: 00 01 02 03 XX XX XX XX - // in[1]: 10 11 12 13 XX XX XX XX - // in[2]: 20 21 22 23 XX XX XX XX - // in[3]: 30 31 32 33 XX XX XX XX - // to: - // a0: 00 10 01 11 02 12 03 13 - // a1: 20 30 21 31 22 32 23 33 - const __m128i a0 = _mm_unpacklo_epi16(in[0], in[1]); - const __m128i a1 = _mm_unpacklo_epi16(in[2], in[3]); - - // Unpack 32 bit elements resulting in: - // out[0]: 00 10 20 30 01 11 21 31 - // out[1]: 02 12 22 32 03 13 23 33 - out[0] = _mm_unpacklo_epi32(a0, a1); - out[1] = _mm_unpackhi_epi32(a0, a1); -} - -static INLINE void transpose_16bit_4x8(const __m128i *const in, - __m128i *const out) { - // Unpack 16 bit elements. Goes from: - // in[0]: 00 01 02 03 XX XX XX XX - // in[1]: 10 11 12 13 XX XX XX XX - // in[2]: 20 21 22 23 XX XX XX XX - // in[3]: 30 31 32 33 XX XX XX XX - // in[4]: 40 41 42 43 XX XX XX XX - // in[5]: 50 51 52 53 XX XX XX XX - // in[6]: 60 61 62 63 XX XX XX XX - // in[7]: 70 71 72 73 XX XX XX XX - // to: - // a0: 00 10 01 11 02 12 03 13 - // a1: 20 30 21 31 22 32 23 33 - // a2: 40 50 41 51 42 52 43 53 - // a3: 60 70 61 71 62 72 63 73 - const __m128i a0 = _mm_unpacklo_epi16(in[0], in[1]); - const __m128i a1 = _mm_unpacklo_epi16(in[2], in[3]); - const __m128i a2 = _mm_unpacklo_epi16(in[4], in[5]); - const __m128i a3 = _mm_unpacklo_epi16(in[6], in[7]); - - // Unpack 32 bit elements resulting in: - // b0: 00 10 20 30 01 11 21 31 - // b1: 40 50 60 70 41 51 61 71 - // b2: 02 12 22 32 03 13 23 33 - // b3: 42 52 62 72 43 53 63 73 - const __m128i b0 = _mm_unpacklo_epi32(a0, a1); - const __m128i b1 = _mm_unpacklo_epi32(a2, a3); - const __m128i b2 = _mm_unpackhi_epi32(a0, a1); - const __m128i b3 = _mm_unpackhi_epi32(a2, a3); - - // Unpack 64 bit elements resulting in: - // out[0]: 00 10 20 30 40 50 60 70 - // out[1]: 01 11 21 31 41 51 61 71 - // out[2]: 02 12 22 32 42 52 62 72 - // out[3]: 03 13 23 33 43 53 63 73 - out[0] = _mm_unpacklo_epi64(b0, b1); - out[1] = _mm_unpackhi_epi64(b0, b1); - out[2] = _mm_unpacklo_epi64(b2, b3); - out[3] = _mm_unpackhi_epi64(b2, b3); -} - -static INLINE void transpose_16bit_8x8(const __m128i *const in, - __m128i *const out) { - // Unpack 16 bit elements. Goes from: - // in[0]: 00 01 02 03 04 05 06 07 - // in[1]: 10 11 12 13 14 15 16 17 - // in[2]: 20 21 22 23 24 25 26 27 - // in[3]: 30 31 32 33 34 35 36 37 - // in[4]: 40 41 42 43 44 45 46 47 - // in[5]: 50 51 52 53 54 55 56 57 - // in[6]: 60 61 62 63 64 65 66 67 - // in[7]: 70 71 72 73 74 75 76 77 - // to: - // a0: 00 10 01 11 02 12 03 13 - // a1: 20 30 21 31 22 32 23 33 - // a2: 40 50 41 51 42 52 43 53 - // a3: 60 70 61 71 62 72 63 73 - // a4: 04 14 05 15 06 16 07 17 - // a5: 24 34 25 35 26 36 27 37 - // a6: 44 54 45 55 46 56 47 57 - // a7: 64 74 65 75 66 76 67 77 - const __m128i a0 = _mm_unpacklo_epi16(in[0], in[1]); - const __m128i a1 = _mm_unpacklo_epi16(in[2], in[3]); - const __m128i a2 = _mm_unpacklo_epi16(in[4], in[5]); - const __m128i a3 = _mm_unpacklo_epi16(in[6], in[7]); - const __m128i a4 = _mm_unpackhi_epi16(in[0], in[1]); - const __m128i a5 = _mm_unpackhi_epi16(in[2], in[3]); - const __m128i a6 = _mm_unpackhi_epi16(in[4], in[5]); - const __m128i a7 = _mm_unpackhi_epi16(in[6], in[7]); - - // Unpack 32 bit elements resulting in: - // b0: 00 10 20 30 01 11 21 31 - // b1: 40 50 60 70 41 51 61 71 - // b2: 04 14 24 34 05 15 25 35 - // b3: 44 54 64 74 45 55 65 75 - // b4: 02 12 22 32 03 13 23 33 - // b5: 42 52 62 72 43 53 63 73 - // b6: 06 16 26 36 07 17 27 37 - // b7: 46 56 66 76 47 57 67 77 - const __m128i b0 = _mm_unpacklo_epi32(a0, a1); - const __m128i b1 = _mm_unpacklo_epi32(a2, a3); - const __m128i b2 = _mm_unpacklo_epi32(a4, a5); - const __m128i b3 = _mm_unpacklo_epi32(a6, a7); - const __m128i b4 = _mm_unpackhi_epi32(a0, a1); - const __m128i b5 = _mm_unpackhi_epi32(a2, a3); - const __m128i b6 = _mm_unpackhi_epi32(a4, a5); - const __m128i b7 = _mm_unpackhi_epi32(a6, a7); - - // Unpack 64 bit elements resulting in: - // out[0]: 00 10 20 30 40 50 60 70 - // out[1]: 01 11 21 31 41 51 61 71 - // out[2]: 02 12 22 32 42 52 62 72 - // out[3]: 03 13 23 33 43 53 63 73 - // out[4]: 04 14 24 34 44 54 64 74 - // out[5]: 05 15 25 35 45 55 65 75 - // out[6]: 06 16 26 36 46 56 66 76 - // out[7]: 07 17 27 37 47 57 67 77 - out[0] = _mm_unpacklo_epi64(b0, b1); - out[1] = _mm_unpackhi_epi64(b0, b1); - out[2] = _mm_unpacklo_epi64(b4, b5); - out[3] = _mm_unpackhi_epi64(b4, b5); - out[4] = _mm_unpacklo_epi64(b2, b3); - out[5] = _mm_unpackhi_epi64(b2, b3); - out[6] = _mm_unpacklo_epi64(b6, b7); - out[7] = _mm_unpackhi_epi64(b6, b7); -} - -// Transpose in-place -static INLINE void transpose_16bit_16x16(__m128i *const left, - __m128i *const right) { - __m128i tbuf[8]; - transpose_16bit_8x8(left, left); - transpose_16bit_8x8(right, tbuf); - transpose_16bit_8x8(left + 8, right); - transpose_16bit_8x8(right + 8, right + 8); - - left[8] = tbuf[0]; - left[9] = tbuf[1]; - left[10] = tbuf[2]; - left[11] = tbuf[3]; - left[12] = tbuf[4]; - left[13] = tbuf[5]; - left[14] = tbuf[6]; - left[15] = tbuf[7]; -} - -static INLINE void transpose_32bit_4x4(const __m128i *const in, - __m128i *const out) { - // Unpack 32 bit elements. Goes from: - // in[0]: 00 01 02 03 - // in[1]: 10 11 12 13 - // in[2]: 20 21 22 23 - // in[3]: 30 31 32 33 - // to: - // a0: 00 10 01 11 - // a1: 20 30 21 31 - // a2: 02 12 03 13 - // a3: 22 32 23 33 - - const __m128i a0 = _mm_unpacklo_epi32(in[0], in[1]); - const __m128i a1 = _mm_unpacklo_epi32(in[2], in[3]); - const __m128i a2 = _mm_unpackhi_epi32(in[0], in[1]); - const __m128i a3 = _mm_unpackhi_epi32(in[2], in[3]); - - // Unpack 64 bit elements resulting in: - // out[0]: 00 10 20 30 - // out[1]: 01 11 21 31 - // out[2]: 02 12 22 32 - // out[3]: 03 13 23 33 - out[0] = _mm_unpacklo_epi64(a0, a1); - out[1] = _mm_unpackhi_epi64(a0, a1); - out[2] = _mm_unpacklo_epi64(a2, a3); - out[3] = _mm_unpackhi_epi64(a2, a3); -} - -static INLINE void transpose_32bit_4x4x2(const __m128i *const in, - __m128i *const out) { - // Unpack 32 bit elements. Goes from: - // in[0]: 00 01 02 03 - // in[1]: 10 11 12 13 - // in[2]: 20 21 22 23 - // in[3]: 30 31 32 33 - // in[4]: 04 05 06 07 - // in[5]: 14 15 16 17 - // in[6]: 24 25 26 27 - // in[7]: 34 35 36 37 - // to: - // a0: 00 10 01 11 - // a1: 20 30 21 31 - // a2: 02 12 03 13 - // a3: 22 32 23 33 - // a4: 04 14 05 15 - // a5: 24 34 25 35 - // a6: 06 16 07 17 - // a7: 26 36 27 37 - const __m128i a0 = _mm_unpacklo_epi32(in[0], in[1]); - const __m128i a1 = _mm_unpacklo_epi32(in[2], in[3]); - const __m128i a2 = _mm_unpackhi_epi32(in[0], in[1]); - const __m128i a3 = _mm_unpackhi_epi32(in[2], in[3]); - const __m128i a4 = _mm_unpacklo_epi32(in[4], in[5]); - const __m128i a5 = _mm_unpacklo_epi32(in[6], in[7]); - const __m128i a6 = _mm_unpackhi_epi32(in[4], in[5]); - const __m128i a7 = _mm_unpackhi_epi32(in[6], in[7]); - - // Unpack 64 bit elements resulting in: - // out[0]: 00 10 20 30 - // out[1]: 01 11 21 31 - // out[2]: 02 12 22 32 - // out[3]: 03 13 23 33 - // out[4]: 04 14 24 34 - // out[5]: 05 15 25 35 - // out[6]: 06 16 26 36 - // out[7]: 07 17 27 37 - out[0] = _mm_unpacklo_epi64(a0, a1); - out[1] = _mm_unpackhi_epi64(a0, a1); - out[2] = _mm_unpacklo_epi64(a2, a3); - out[3] = _mm_unpackhi_epi64(a2, a3); - out[4] = _mm_unpacklo_epi64(a4, a5); - out[5] = _mm_unpackhi_epi64(a4, a5); - out[6] = _mm_unpacklo_epi64(a6, a7); - out[7] = _mm_unpackhi_epi64(a6, a7); -} - -static INLINE void transpose_32bit_8x4(const __m128i *const in, - __m128i *const out) { - // Unpack 32 bit elements. Goes from: - // in[0]: 00 01 02 03 - // in[1]: 04 05 06 07 - // in[2]: 10 11 12 13 - // in[3]: 14 15 16 17 - // in[4]: 20 21 22 23 - // in[5]: 24 25 26 27 - // in[6]: 30 31 32 33 - // in[7]: 34 35 36 37 - // to: - // a0: 00 10 01 11 - // a1: 20 30 21 31 - // a2: 02 12 03 13 - // a3: 22 32 23 33 - // a4: 04 14 05 15 - // a5: 24 34 25 35 - // a6: 06 16 07 17 - // a7: 26 36 27 37 - const __m128i a0 = _mm_unpacklo_epi32(in[0], in[2]); - const __m128i a1 = _mm_unpacklo_epi32(in[4], in[6]); - const __m128i a2 = _mm_unpackhi_epi32(in[0], in[2]); - const __m128i a3 = _mm_unpackhi_epi32(in[4], in[6]); - const __m128i a4 = _mm_unpacklo_epi32(in[1], in[3]); - const __m128i a5 = _mm_unpacklo_epi32(in[5], in[7]); - const __m128i a6 = _mm_unpackhi_epi32(in[1], in[3]); - const __m128i a7 = _mm_unpackhi_epi32(in[5], in[7]); - - // Unpack 64 bit elements resulting in: - // out[0]: 00 10 20 30 - // out[1]: 01 11 21 31 - // out[2]: 02 12 22 32 - // out[3]: 03 13 23 33 - // out[4]: 04 14 24 34 - // out[5]: 05 15 25 35 - // out[6]: 06 16 26 36 - // out[7]: 07 17 27 37 - out[0] = _mm_unpacklo_epi64(a0, a1); - out[1] = _mm_unpackhi_epi64(a0, a1); - out[2] = _mm_unpacklo_epi64(a2, a3); - out[3] = _mm_unpackhi_epi64(a2, a3); - out[4] = _mm_unpacklo_epi64(a4, a5); - out[5] = _mm_unpackhi_epi64(a4, a5); - out[6] = _mm_unpacklo_epi64(a6, a7); - out[7] = _mm_unpackhi_epi64(a6, a7); -} - -#endif // VPX_VPX_DSP_X86_TRANSPOSE_SSE2_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/txfm_common_sse2.h b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/txfm_common_sse2.h deleted file mode 100644 index de5ce43b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/txfm_common_sse2.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_DSP_X86_TXFM_COMMON_SSE2_H_ -#define VPX_VPX_DSP_X86_TXFM_COMMON_SSE2_H_ - -#include -#include "vpx/vpx_integer.h" - -#define pair_set_epi16(a, b) \ - _mm_set_epi16((int16_t)(b), (int16_t)(a), (int16_t)(b), (int16_t)(a), \ - (int16_t)(b), (int16_t)(a), (int16_t)(b), (int16_t)(a)) - -#define pair_set_epi32(a, b) \ - _mm_set_epi32((int)(b), (int)(a), (int)(b), (int)(a)) - -#define dual_set_epi16(a, b) \ - _mm_set_epi16((int16_t)(b), (int16_t)(b), (int16_t)(b), (int16_t)(b), \ - (int16_t)(a), (int16_t)(a), (int16_t)(a), (int16_t)(a)) - -#define octa_set_epi16(a, b, c, d, e, f, g, h) \ - _mm_setr_epi16((int16_t)(a), (int16_t)(b), (int16_t)(c), (int16_t)(d), \ - (int16_t)(e), (int16_t)(f), (int16_t)(g), (int16_t)(h)) - -#endif // VPX_VPX_DSP_X86_TXFM_COMMON_SSE2_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/variance_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/variance_avx2.c deleted file mode 100644 index 8305b9f2..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/variance_avx2.c +++ /dev/null @@ -1,872 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // AVX2 - -#include "./vpx_dsp_rtcd.h" - -/* clang-format off */ -DECLARE_ALIGNED(32, static const uint8_t, bilinear_filters_avx2[512]) = { - 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, - 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, - 14, 2, 14, 2, 14, 2, 14, 2, 14, 2, 14, 2, 14, 2, 14, 2, - 14, 2, 14, 2, 14, 2, 14, 2, 14, 2, 14, 2, 14, 2, 14, 2, - 12, 4, 12, 4, 12, 4, 12, 4, 12, 4, 12, 4, 12, 4, 12, 4, - 12, 4, 12, 4, 12, 4, 12, 4, 12, 4, 12, 4, 12, 4, 12, 4, - 10, 6, 10, 6, 10, 6, 10, 6, 10, 6, 10, 6, 10, 6, 10, 6, - 10, 6, 10, 6, 10, 6, 10, 6, 10, 6, 10, 6, 10, 6, 10, 6, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 6, 10, 6, 10, 6, 10, 6, 10, 6, 10, 6, 10, 6, 10, 6, 10, - 6, 10, 6, 10, 6, 10, 6, 10, 6, 10, 6, 10, 6, 10, 6, 10, - 4, 12, 4, 12, 4, 12, 4, 12, 4, 12, 4, 12, 4, 12, 4, 12, - 4, 12, 4, 12, 4, 12, 4, 12, 4, 12, 4, 12, 4, 12, 4, 12, - 2, 14, 2, 14, 2, 14, 2, 14, 2, 14, 2, 14, 2, 14, 2, 14, - 2, 14, 2, 14, 2, 14, 2, 14, 2, 14, 2, 14, 2, 14, 2, 14, -}; - -DECLARE_ALIGNED(32, static const int8_t, adjacent_sub_avx2[32]) = { - 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, - 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1 -}; -/* clang-format on */ - -static INLINE void variance_kernel_avx2(const __m256i src, const __m256i ref, - __m256i *const sse, - __m256i *const sum) { - const __m256i adj_sub = _mm256_load_si256((__m256i const *)adjacent_sub_avx2); - - // unpack into pairs of source and reference values - const __m256i src_ref0 = _mm256_unpacklo_epi8(src, ref); - const __m256i src_ref1 = _mm256_unpackhi_epi8(src, ref); - - // subtract adjacent elements using src*1 + ref*-1 - const __m256i diff0 = _mm256_maddubs_epi16(src_ref0, adj_sub); - const __m256i diff1 = _mm256_maddubs_epi16(src_ref1, adj_sub); - const __m256i madd0 = _mm256_madd_epi16(diff0, diff0); - const __m256i madd1 = _mm256_madd_epi16(diff1, diff1); - - // add to the running totals - *sum = _mm256_add_epi16(*sum, _mm256_add_epi16(diff0, diff1)); - *sse = _mm256_add_epi32(*sse, _mm256_add_epi32(madd0, madd1)); -} - -static INLINE void variance_final_from_32bit_sum_avx2(__m256i vsse, - __m128i vsum, - unsigned int *const sse, - int *const sum) { - // extract the low lane and add it to the high lane - const __m128i sse_reg_128 = _mm_add_epi32(_mm256_castsi256_si128(vsse), - _mm256_extractf128_si256(vsse, 1)); - - // unpack sse and sum registers and add - const __m128i sse_sum_lo = _mm_unpacklo_epi32(sse_reg_128, vsum); - const __m128i sse_sum_hi = _mm_unpackhi_epi32(sse_reg_128, vsum); - const __m128i sse_sum = _mm_add_epi32(sse_sum_lo, sse_sum_hi); - - // perform the final summation and extract the results - const __m128i res = _mm_add_epi32(sse_sum, _mm_srli_si128(sse_sum, 8)); - *((int *)sse) = _mm_cvtsi128_si32(res); - *((int *)sum) = _mm_extract_epi32(res, 1); -} - -static INLINE void variance_final_from_16bit_sum_avx2(__m256i vsse, - __m256i vsum, - unsigned int *const sse, - int *const sum) { - // extract the low lane and add it to the high lane - const __m128i sum_reg_128 = _mm_add_epi16(_mm256_castsi256_si128(vsum), - _mm256_extractf128_si256(vsum, 1)); - const __m128i sum_reg_64 = - _mm_add_epi16(sum_reg_128, _mm_srli_si128(sum_reg_128, 8)); - const __m128i sum_int32 = _mm_cvtepi16_epi32(sum_reg_64); - - variance_final_from_32bit_sum_avx2(vsse, sum_int32, sse, sum); -} - -static INLINE __m256i sum_to_32bit_avx2(const __m256i sum) { - const __m256i sum_lo = _mm256_cvtepi16_epi32(_mm256_castsi256_si128(sum)); - const __m256i sum_hi = - _mm256_cvtepi16_epi32(_mm256_extractf128_si256(sum, 1)); - return _mm256_add_epi32(sum_lo, sum_hi); -} - -static INLINE void variance8_kernel_avx2( - const uint8_t *const src, const int src_stride, const uint8_t *const ref, - const int ref_stride, __m256i *const sse, __m256i *const sum) { - __m128i src0, src1, ref0, ref1; - __m256i ss, rr, diff; - - // 0 0 0.... 0 s07 s06 s05 s04 s03 s02 s01 s00 - src0 = _mm_loadl_epi64((const __m128i *)(src + 0 * src_stride)); - - // 0 0 0.... 0 s17 s16 s15 s14 s13 s12 s11 s10 - src1 = _mm_loadl_epi64((const __m128i *)(src + 1 * src_stride)); - - // s17 s16...s11 s10 s07 s06...s01 s00 (8bit) - src0 = _mm_unpacklo_epi64(src0, src1); - - // s17 s16...s11 s10 s07 s06...s01 s00 (16 bit) - ss = _mm256_cvtepu8_epi16(src0); - - // 0 0 0.... 0 r07 r06 r05 r04 r03 r02 r01 r00 - ref0 = _mm_loadl_epi64((const __m128i *)(ref + 0 * ref_stride)); - - // 0 0 0.... 0 r17 r16 0 r15 0 r14 0 r13 0 r12 0 r11 0 r10 - ref1 = _mm_loadl_epi64((const __m128i *)(ref + 1 * ref_stride)); - - // r17 r16...r11 r10 r07 r06...r01 r00 (8 bit) - ref0 = _mm_unpacklo_epi64(ref0, ref1); - - // r17 r16...r11 r10 r07 r06...r01 r00 (16 bit) - rr = _mm256_cvtepu8_epi16(ref0); - - diff = _mm256_sub_epi16(ss, rr); - *sse = _mm256_add_epi32(*sse, _mm256_madd_epi16(diff, diff)); - *sum = _mm256_add_epi16(*sum, diff); -} - -static INLINE void variance16_kernel_avx2( - const uint8_t *const src, const int src_stride, const uint8_t *const ref, - const int ref_stride, __m256i *const sse, __m256i *const sum) { - const __m128i s0 = _mm_loadu_si128((__m128i const *)(src + 0 * src_stride)); - const __m128i s1 = _mm_loadu_si128((__m128i const *)(src + 1 * src_stride)); - const __m128i r0 = _mm_loadu_si128((__m128i const *)(ref + 0 * ref_stride)); - const __m128i r1 = _mm_loadu_si128((__m128i const *)(ref + 1 * ref_stride)); - const __m256i s = _mm256_inserti128_si256(_mm256_castsi128_si256(s0), s1, 1); - const __m256i r = _mm256_inserti128_si256(_mm256_castsi128_si256(r0), r1, 1); - variance_kernel_avx2(s, r, sse, sum); -} - -static INLINE void variance32_kernel_avx2(const uint8_t *const src, - const uint8_t *const ref, - __m256i *const sse, - __m256i *const sum) { - const __m256i s = _mm256_loadu_si256((__m256i const *)(src)); - const __m256i r = _mm256_loadu_si256((__m256i const *)(ref)); - variance_kernel_avx2(s, r, sse, sum); -} - -static INLINE void variance8_avx2(const uint8_t *src, const int src_stride, - const uint8_t *ref, const int ref_stride, - const int h, __m256i *const vsse, - __m256i *const vsum) { - int i; - *vsum = _mm256_setzero_si256(); - *vsse = _mm256_setzero_si256(); - - for (i = 0; i < h; i += 2) { - variance8_kernel_avx2(src, src_stride, ref, ref_stride, vsse, vsum); - src += 2 * src_stride; - ref += 2 * ref_stride; - } -} - -static INLINE void variance16_avx2(const uint8_t *src, const int src_stride, - const uint8_t *ref, const int ref_stride, - const int h, __m256i *const vsse, - __m256i *const vsum) { - int i; - *vsum = _mm256_setzero_si256(); - *vsse = _mm256_setzero_si256(); - - for (i = 0; i < h; i += 2) { - variance16_kernel_avx2(src, src_stride, ref, ref_stride, vsse, vsum); - src += 2 * src_stride; - ref += 2 * ref_stride; - } -} - -static INLINE void variance32_avx2(const uint8_t *src, const int src_stride, - const uint8_t *ref, const int ref_stride, - const int h, __m256i *const vsse, - __m256i *const vsum) { - int i; - *vsum = _mm256_setzero_si256(); - *vsse = _mm256_setzero_si256(); - - for (i = 0; i < h; i++) { - variance32_kernel_avx2(src, ref, vsse, vsum); - src += src_stride; - ref += ref_stride; - } -} - -static INLINE void variance64_avx2(const uint8_t *src, const int src_stride, - const uint8_t *ref, const int ref_stride, - const int h, __m256i *const vsse, - __m256i *const vsum) { - int i; - *vsum = _mm256_setzero_si256(); - - for (i = 0; i < h; i++) { - variance32_kernel_avx2(src + 0, ref + 0, vsse, vsum); - variance32_kernel_avx2(src + 32, ref + 32, vsse, vsum); - src += src_stride; - ref += ref_stride; - } -} - -void vpx_get16x16var_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse, int *sum) { - __m256i vsse, vsum; - variance16_avx2(src_ptr, src_stride, ref_ptr, ref_stride, 16, &vsse, &vsum); - variance_final_from_16bit_sum_avx2(vsse, vsum, sse, sum); -} - -#define FILTER_SRC(filter) \ - /* filter the source */ \ - exp_src_lo = _mm256_maddubs_epi16(exp_src_lo, filter); \ - exp_src_hi = _mm256_maddubs_epi16(exp_src_hi, filter); \ - \ - /* add 8 to source */ \ - exp_src_lo = _mm256_add_epi16(exp_src_lo, pw8); \ - exp_src_hi = _mm256_add_epi16(exp_src_hi, pw8); \ - \ - /* divide source by 16 */ \ - exp_src_lo = _mm256_srai_epi16(exp_src_lo, 4); \ - exp_src_hi = _mm256_srai_epi16(exp_src_hi, 4); - -#define CALC_SUM_SSE_INSIDE_LOOP \ - /* expand each byte to 2 bytes */ \ - exp_dst_lo = _mm256_unpacklo_epi8(dst_reg, zero_reg); \ - exp_dst_hi = _mm256_unpackhi_epi8(dst_reg, zero_reg); \ - /* source - dest */ \ - exp_src_lo = _mm256_sub_epi16(exp_src_lo, exp_dst_lo); \ - exp_src_hi = _mm256_sub_epi16(exp_src_hi, exp_dst_hi); \ - /* caculate sum */ \ - *sum_reg = _mm256_add_epi16(*sum_reg, exp_src_lo); \ - exp_src_lo = _mm256_madd_epi16(exp_src_lo, exp_src_lo); \ - *sum_reg = _mm256_add_epi16(*sum_reg, exp_src_hi); \ - exp_src_hi = _mm256_madd_epi16(exp_src_hi, exp_src_hi); \ - /* calculate sse */ \ - *sse_reg = _mm256_add_epi32(*sse_reg, exp_src_lo); \ - *sse_reg = _mm256_add_epi32(*sse_reg, exp_src_hi); - -// final calculation to sum and sse -#define CALC_SUM_AND_SSE \ - res_cmp = _mm256_cmpgt_epi16(zero_reg, sum_reg); \ - sse_reg_hi = _mm256_srli_si256(sse_reg, 8); \ - sum_reg_lo = _mm256_unpacklo_epi16(sum_reg, res_cmp); \ - sum_reg_hi = _mm256_unpackhi_epi16(sum_reg, res_cmp); \ - sse_reg = _mm256_add_epi32(sse_reg, sse_reg_hi); \ - sum_reg = _mm256_add_epi32(sum_reg_lo, sum_reg_hi); \ - \ - sse_reg_hi = _mm256_srli_si256(sse_reg, 4); \ - sum_reg_hi = _mm256_srli_si256(sum_reg, 8); \ - \ - sse_reg = _mm256_add_epi32(sse_reg, sse_reg_hi); \ - sum_reg = _mm256_add_epi32(sum_reg, sum_reg_hi); \ - *((int *)sse) = _mm_cvtsi128_si32(_mm256_castsi256_si128(sse_reg)) + \ - _mm_cvtsi128_si32(_mm256_extractf128_si256(sse_reg, 1)); \ - sum_reg_hi = _mm256_srli_si256(sum_reg, 4); \ - sum_reg = _mm256_add_epi32(sum_reg, sum_reg_hi); \ - sum = _mm_cvtsi128_si32(_mm256_castsi256_si128(sum_reg)) + \ - _mm_cvtsi128_si32(_mm256_extractf128_si256(sum_reg, 1)); - -static INLINE void spv32_x0_y0(const uint8_t *src, int src_stride, - const uint8_t *dst, int dst_stride, - const uint8_t *second_pred, int second_stride, - int do_sec, int height, __m256i *sum_reg, - __m256i *sse_reg) { - const __m256i zero_reg = _mm256_setzero_si256(); - __m256i exp_src_lo, exp_src_hi, exp_dst_lo, exp_dst_hi; - int i; - for (i = 0; i < height; i++) { - const __m256i dst_reg = _mm256_loadu_si256((__m256i const *)dst); - const __m256i src_reg = _mm256_loadu_si256((__m256i const *)src); - if (do_sec) { - const __m256i sec_reg = _mm256_loadu_si256((__m256i const *)second_pred); - const __m256i avg_reg = _mm256_avg_epu8(src_reg, sec_reg); - exp_src_lo = _mm256_unpacklo_epi8(avg_reg, zero_reg); - exp_src_hi = _mm256_unpackhi_epi8(avg_reg, zero_reg); - second_pred += second_stride; - } else { - exp_src_lo = _mm256_unpacklo_epi8(src_reg, zero_reg); - exp_src_hi = _mm256_unpackhi_epi8(src_reg, zero_reg); - } - CALC_SUM_SSE_INSIDE_LOOP - src += src_stride; - dst += dst_stride; - } -} - -// (x == 0, y == 4) or (x == 4, y == 0). sstep determines the direction. -static INLINE void spv32_half_zero(const uint8_t *src, int src_stride, - const uint8_t *dst, int dst_stride, - const uint8_t *second_pred, - int second_stride, int do_sec, int height, - __m256i *sum_reg, __m256i *sse_reg, - int sstep) { - const __m256i zero_reg = _mm256_setzero_si256(); - __m256i exp_src_lo, exp_src_hi, exp_dst_lo, exp_dst_hi; - int i; - for (i = 0; i < height; i++) { - const __m256i dst_reg = _mm256_loadu_si256((__m256i const *)dst); - const __m256i src_0 = _mm256_loadu_si256((__m256i const *)src); - const __m256i src_1 = _mm256_loadu_si256((__m256i const *)(src + sstep)); - const __m256i src_avg = _mm256_avg_epu8(src_0, src_1); - if (do_sec) { - const __m256i sec_reg = _mm256_loadu_si256((__m256i const *)second_pred); - const __m256i avg_reg = _mm256_avg_epu8(src_avg, sec_reg); - exp_src_lo = _mm256_unpacklo_epi8(avg_reg, zero_reg); - exp_src_hi = _mm256_unpackhi_epi8(avg_reg, zero_reg); - second_pred += second_stride; - } else { - exp_src_lo = _mm256_unpacklo_epi8(src_avg, zero_reg); - exp_src_hi = _mm256_unpackhi_epi8(src_avg, zero_reg); - } - CALC_SUM_SSE_INSIDE_LOOP - src += src_stride; - dst += dst_stride; - } -} - -static INLINE void spv32_x0_y4(const uint8_t *src, int src_stride, - const uint8_t *dst, int dst_stride, - const uint8_t *second_pred, int second_stride, - int do_sec, int height, __m256i *sum_reg, - __m256i *sse_reg) { - spv32_half_zero(src, src_stride, dst, dst_stride, second_pred, second_stride, - do_sec, height, sum_reg, sse_reg, src_stride); -} - -static INLINE void spv32_x4_y0(const uint8_t *src, int src_stride, - const uint8_t *dst, int dst_stride, - const uint8_t *second_pred, int second_stride, - int do_sec, int height, __m256i *sum_reg, - __m256i *sse_reg) { - spv32_half_zero(src, src_stride, dst, dst_stride, second_pred, second_stride, - do_sec, height, sum_reg, sse_reg, 1); -} - -static INLINE void spv32_x4_y4(const uint8_t *src, int src_stride, - const uint8_t *dst, int dst_stride, - const uint8_t *second_pred, int second_stride, - int do_sec, int height, __m256i *sum_reg, - __m256i *sse_reg) { - const __m256i zero_reg = _mm256_setzero_si256(); - const __m256i src_a = _mm256_loadu_si256((__m256i const *)src); - const __m256i src_b = _mm256_loadu_si256((__m256i const *)(src + 1)); - __m256i prev_src_avg = _mm256_avg_epu8(src_a, src_b); - __m256i exp_src_lo, exp_src_hi, exp_dst_lo, exp_dst_hi; - int i; - src += src_stride; - for (i = 0; i < height; i++) { - const __m256i dst_reg = _mm256_loadu_si256((__m256i const *)dst); - const __m256i src_0 = _mm256_loadu_si256((__m256i const *)(src)); - const __m256i src_1 = _mm256_loadu_si256((__m256i const *)(src + 1)); - const __m256i src_avg = _mm256_avg_epu8(src_0, src_1); - const __m256i current_avg = _mm256_avg_epu8(prev_src_avg, src_avg); - prev_src_avg = src_avg; - - if (do_sec) { - const __m256i sec_reg = _mm256_loadu_si256((__m256i const *)second_pred); - const __m256i avg_reg = _mm256_avg_epu8(current_avg, sec_reg); - exp_src_lo = _mm256_unpacklo_epi8(avg_reg, zero_reg); - exp_src_hi = _mm256_unpackhi_epi8(avg_reg, zero_reg); - second_pred += second_stride; - } else { - exp_src_lo = _mm256_unpacklo_epi8(current_avg, zero_reg); - exp_src_hi = _mm256_unpackhi_epi8(current_avg, zero_reg); - } - // save current source average - CALC_SUM_SSE_INSIDE_LOOP - dst += dst_stride; - src += src_stride; - } -} - -// (x == 0, y == bil) or (x == 4, y == bil). sstep determines the direction. -static INLINE void spv32_bilin_zero(const uint8_t *src, int src_stride, - const uint8_t *dst, int dst_stride, - const uint8_t *second_pred, - int second_stride, int do_sec, int height, - __m256i *sum_reg, __m256i *sse_reg, - int offset, int sstep) { - const __m256i zero_reg = _mm256_setzero_si256(); - const __m256i pw8 = _mm256_set1_epi16(8); - const __m256i filter = _mm256_load_si256( - (__m256i const *)(bilinear_filters_avx2 + (offset << 5))); - __m256i exp_src_lo, exp_src_hi, exp_dst_lo, exp_dst_hi; - int i; - for (i = 0; i < height; i++) { - const __m256i dst_reg = _mm256_loadu_si256((__m256i const *)dst); - const __m256i src_0 = _mm256_loadu_si256((__m256i const *)src); - const __m256i src_1 = _mm256_loadu_si256((__m256i const *)(src + sstep)); - exp_src_lo = _mm256_unpacklo_epi8(src_0, src_1); - exp_src_hi = _mm256_unpackhi_epi8(src_0, src_1); - - FILTER_SRC(filter) - if (do_sec) { - const __m256i sec_reg = _mm256_loadu_si256((__m256i const *)second_pred); - const __m256i exp_src = _mm256_packus_epi16(exp_src_lo, exp_src_hi); - const __m256i avg_reg = _mm256_avg_epu8(exp_src, sec_reg); - second_pred += second_stride; - exp_src_lo = _mm256_unpacklo_epi8(avg_reg, zero_reg); - exp_src_hi = _mm256_unpackhi_epi8(avg_reg, zero_reg); - } - CALC_SUM_SSE_INSIDE_LOOP - src += src_stride; - dst += dst_stride; - } -} - -static INLINE void spv32_x0_yb(const uint8_t *src, int src_stride, - const uint8_t *dst, int dst_stride, - const uint8_t *second_pred, int second_stride, - int do_sec, int height, __m256i *sum_reg, - __m256i *sse_reg, int y_offset) { - spv32_bilin_zero(src, src_stride, dst, dst_stride, second_pred, second_stride, - do_sec, height, sum_reg, sse_reg, y_offset, src_stride); -} - -static INLINE void spv32_xb_y0(const uint8_t *src, int src_stride, - const uint8_t *dst, int dst_stride, - const uint8_t *second_pred, int second_stride, - int do_sec, int height, __m256i *sum_reg, - __m256i *sse_reg, int x_offset) { - spv32_bilin_zero(src, src_stride, dst, dst_stride, second_pred, second_stride, - do_sec, height, sum_reg, sse_reg, x_offset, 1); -} - -static INLINE void spv32_x4_yb(const uint8_t *src, int src_stride, - const uint8_t *dst, int dst_stride, - const uint8_t *second_pred, int second_stride, - int do_sec, int height, __m256i *sum_reg, - __m256i *sse_reg, int y_offset) { - const __m256i zero_reg = _mm256_setzero_si256(); - const __m256i pw8 = _mm256_set1_epi16(8); - const __m256i filter = _mm256_load_si256( - (__m256i const *)(bilinear_filters_avx2 + (y_offset << 5))); - const __m256i src_a = _mm256_loadu_si256((__m256i const *)src); - const __m256i src_b = _mm256_loadu_si256((__m256i const *)(src + 1)); - __m256i prev_src_avg = _mm256_avg_epu8(src_a, src_b); - __m256i exp_src_lo, exp_src_hi, exp_dst_lo, exp_dst_hi; - int i; - src += src_stride; - for (i = 0; i < height; i++) { - const __m256i dst_reg = _mm256_loadu_si256((__m256i const *)dst); - const __m256i src_0 = _mm256_loadu_si256((__m256i const *)src); - const __m256i src_1 = _mm256_loadu_si256((__m256i const *)(src + 1)); - const __m256i src_avg = _mm256_avg_epu8(src_0, src_1); - exp_src_lo = _mm256_unpacklo_epi8(prev_src_avg, src_avg); - exp_src_hi = _mm256_unpackhi_epi8(prev_src_avg, src_avg); - prev_src_avg = src_avg; - - FILTER_SRC(filter) - if (do_sec) { - const __m256i sec_reg = _mm256_loadu_si256((__m256i const *)second_pred); - const __m256i exp_src_avg = _mm256_packus_epi16(exp_src_lo, exp_src_hi); - const __m256i avg_reg = _mm256_avg_epu8(exp_src_avg, sec_reg); - exp_src_lo = _mm256_unpacklo_epi8(avg_reg, zero_reg); - exp_src_hi = _mm256_unpackhi_epi8(avg_reg, zero_reg); - second_pred += second_stride; - } - CALC_SUM_SSE_INSIDE_LOOP - dst += dst_stride; - src += src_stride; - } -} - -static INLINE void spv32_xb_y4(const uint8_t *src, int src_stride, - const uint8_t *dst, int dst_stride, - const uint8_t *second_pred, int second_stride, - int do_sec, int height, __m256i *sum_reg, - __m256i *sse_reg, int x_offset) { - const __m256i zero_reg = _mm256_setzero_si256(); - const __m256i pw8 = _mm256_set1_epi16(8); - const __m256i filter = _mm256_load_si256( - (__m256i const *)(bilinear_filters_avx2 + (x_offset << 5))); - const __m256i src_a = _mm256_loadu_si256((__m256i const *)src); - const __m256i src_b = _mm256_loadu_si256((__m256i const *)(src + 1)); - __m256i exp_src_lo, exp_src_hi, exp_dst_lo, exp_dst_hi; - __m256i src_reg, src_pack; - int i; - exp_src_lo = _mm256_unpacklo_epi8(src_a, src_b); - exp_src_hi = _mm256_unpackhi_epi8(src_a, src_b); - FILTER_SRC(filter) - // convert each 16 bit to 8 bit to each low and high lane source - src_pack = _mm256_packus_epi16(exp_src_lo, exp_src_hi); - - src += src_stride; - for (i = 0; i < height; i++) { - const __m256i dst_reg = _mm256_loadu_si256((__m256i const *)dst); - const __m256i src_0 = _mm256_loadu_si256((__m256i const *)src); - const __m256i src_1 = _mm256_loadu_si256((__m256i const *)(src + 1)); - exp_src_lo = _mm256_unpacklo_epi8(src_0, src_1); - exp_src_hi = _mm256_unpackhi_epi8(src_0, src_1); - - FILTER_SRC(filter) - - src_reg = _mm256_packus_epi16(exp_src_lo, exp_src_hi); - // average between previous pack to the current - src_pack = _mm256_avg_epu8(src_pack, src_reg); - - if (do_sec) { - const __m256i sec_reg = _mm256_loadu_si256((__m256i const *)second_pred); - const __m256i avg_pack = _mm256_avg_epu8(src_pack, sec_reg); - exp_src_lo = _mm256_unpacklo_epi8(avg_pack, zero_reg); - exp_src_hi = _mm256_unpackhi_epi8(avg_pack, zero_reg); - second_pred += second_stride; - } else { - exp_src_lo = _mm256_unpacklo_epi8(src_pack, zero_reg); - exp_src_hi = _mm256_unpackhi_epi8(src_pack, zero_reg); - } - CALC_SUM_SSE_INSIDE_LOOP - src_pack = src_reg; - dst += dst_stride; - src += src_stride; - } -} - -static INLINE void spv32_xb_yb(const uint8_t *src, int src_stride, - const uint8_t *dst, int dst_stride, - const uint8_t *second_pred, int second_stride, - int do_sec, int height, __m256i *sum_reg, - __m256i *sse_reg, int x_offset, int y_offset) { - const __m256i zero_reg = _mm256_setzero_si256(); - const __m256i pw8 = _mm256_set1_epi16(8); - const __m256i xfilter = _mm256_load_si256( - (__m256i const *)(bilinear_filters_avx2 + (x_offset << 5))); - const __m256i yfilter = _mm256_load_si256( - (__m256i const *)(bilinear_filters_avx2 + (y_offset << 5))); - const __m256i src_a = _mm256_loadu_si256((__m256i const *)src); - const __m256i src_b = _mm256_loadu_si256((__m256i const *)(src + 1)); - __m256i exp_src_lo, exp_src_hi, exp_dst_lo, exp_dst_hi; - __m256i prev_src_pack, src_pack; - int i; - exp_src_lo = _mm256_unpacklo_epi8(src_a, src_b); - exp_src_hi = _mm256_unpackhi_epi8(src_a, src_b); - FILTER_SRC(xfilter) - // convert each 16 bit to 8 bit to each low and high lane source - prev_src_pack = _mm256_packus_epi16(exp_src_lo, exp_src_hi); - src += src_stride; - - for (i = 0; i < height; i++) { - const __m256i dst_reg = _mm256_loadu_si256((__m256i const *)dst); - const __m256i src_0 = _mm256_loadu_si256((__m256i const *)src); - const __m256i src_1 = _mm256_loadu_si256((__m256i const *)(src + 1)); - exp_src_lo = _mm256_unpacklo_epi8(src_0, src_1); - exp_src_hi = _mm256_unpackhi_epi8(src_0, src_1); - - FILTER_SRC(xfilter) - src_pack = _mm256_packus_epi16(exp_src_lo, exp_src_hi); - - // merge previous pack to current pack source - exp_src_lo = _mm256_unpacklo_epi8(prev_src_pack, src_pack); - exp_src_hi = _mm256_unpackhi_epi8(prev_src_pack, src_pack); - - FILTER_SRC(yfilter) - if (do_sec) { - const __m256i sec_reg = _mm256_loadu_si256((__m256i const *)second_pred); - const __m256i exp_src = _mm256_packus_epi16(exp_src_lo, exp_src_hi); - const __m256i avg_reg = _mm256_avg_epu8(exp_src, sec_reg); - exp_src_lo = _mm256_unpacklo_epi8(avg_reg, zero_reg); - exp_src_hi = _mm256_unpackhi_epi8(avg_reg, zero_reg); - second_pred += second_stride; - } - - prev_src_pack = src_pack; - - CALC_SUM_SSE_INSIDE_LOOP - dst += dst_stride; - src += src_stride; - } -} - -static INLINE int sub_pix_var32xh(const uint8_t *src, int src_stride, - int x_offset, int y_offset, - const uint8_t *dst, int dst_stride, - const uint8_t *second_pred, int second_stride, - int do_sec, int height, unsigned int *sse) { - const __m256i zero_reg = _mm256_setzero_si256(); - __m256i sum_reg = _mm256_setzero_si256(); - __m256i sse_reg = _mm256_setzero_si256(); - __m256i sse_reg_hi, res_cmp, sum_reg_lo, sum_reg_hi; - int sum; - // x_offset = 0 and y_offset = 0 - if (x_offset == 0) { - if (y_offset == 0) { - spv32_x0_y0(src, src_stride, dst, dst_stride, second_pred, second_stride, - do_sec, height, &sum_reg, &sse_reg); - // x_offset = 0 and y_offset = 4 - } else if (y_offset == 4) { - spv32_x0_y4(src, src_stride, dst, dst_stride, second_pred, second_stride, - do_sec, height, &sum_reg, &sse_reg); - // x_offset = 0 and y_offset = bilin interpolation - } else { - spv32_x0_yb(src, src_stride, dst, dst_stride, second_pred, second_stride, - do_sec, height, &sum_reg, &sse_reg, y_offset); - } - // x_offset = 4 and y_offset = 0 - } else if (x_offset == 4) { - if (y_offset == 0) { - spv32_x4_y0(src, src_stride, dst, dst_stride, second_pred, second_stride, - do_sec, height, &sum_reg, &sse_reg); - // x_offset = 4 and y_offset = 4 - } else if (y_offset == 4) { - spv32_x4_y4(src, src_stride, dst, dst_stride, second_pred, second_stride, - do_sec, height, &sum_reg, &sse_reg); - // x_offset = 4 and y_offset = bilin interpolation - } else { - spv32_x4_yb(src, src_stride, dst, dst_stride, second_pred, second_stride, - do_sec, height, &sum_reg, &sse_reg, y_offset); - } - // x_offset = bilin interpolation and y_offset = 0 - } else { - if (y_offset == 0) { - spv32_xb_y0(src, src_stride, dst, dst_stride, second_pred, second_stride, - do_sec, height, &sum_reg, &sse_reg, x_offset); - // x_offset = bilin interpolation and y_offset = 4 - } else if (y_offset == 4) { - spv32_xb_y4(src, src_stride, dst, dst_stride, second_pred, second_stride, - do_sec, height, &sum_reg, &sse_reg, x_offset); - // x_offset = bilin interpolation and y_offset = bilin interpolation - } else { - spv32_xb_yb(src, src_stride, dst, dst_stride, second_pred, second_stride, - do_sec, height, &sum_reg, &sse_reg, x_offset, y_offset); - } - } - CALC_SUM_AND_SSE - return sum; -} - -static int sub_pixel_variance32xh_avx2(const uint8_t *src, int src_stride, - int x_offset, int y_offset, - const uint8_t *dst, int dst_stride, - int height, unsigned int *sse) { - return sub_pix_var32xh(src, src_stride, x_offset, y_offset, dst, dst_stride, - NULL, 0, 0, height, sse); -} - -static int sub_pixel_avg_variance32xh_avx2(const uint8_t *src, int src_stride, - int x_offset, int y_offset, - const uint8_t *dst, int dst_stride, - const uint8_t *second_pred, - int second_stride, int height, - unsigned int *sse) { - return sub_pix_var32xh(src, src_stride, x_offset, y_offset, dst, dst_stride, - second_pred, second_stride, 1, height, sse); -} - -typedef void (*get_var_avx2)(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse, int *sum); - -unsigned int vpx_variance8x4_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m256i vsse, vsum; - int sum; - variance8_avx2(src_ptr, src_stride, ref_ptr, ref_stride, 4, &vsse, &vsum); - variance_final_from_16bit_sum_avx2(vsse, vsum, sse, &sum); - return *sse - ((sum * sum) >> 5); -} - -unsigned int vpx_variance8x8_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m256i vsse, vsum; - int sum; - variance8_avx2(src_ptr, src_stride, ref_ptr, ref_stride, 8, &vsse, &vsum); - variance_final_from_16bit_sum_avx2(vsse, vsum, sse, &sum); - return *sse - ((sum * sum) >> 6); -} - -unsigned int vpx_variance8x16_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m256i vsse, vsum; - int sum; - variance8_avx2(src_ptr, src_stride, ref_ptr, ref_stride, 16, &vsse, &vsum); - variance_final_from_16bit_sum_avx2(vsse, vsum, sse, &sum); - return *sse - ((sum * sum) >> 7); -} - -unsigned int vpx_variance16x8_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - int sum; - __m256i vsse, vsum; - variance16_avx2(src_ptr, src_stride, ref_ptr, ref_stride, 8, &vsse, &vsum); - variance_final_from_16bit_sum_avx2(vsse, vsum, sse, &sum); - return *sse - (uint32_t)(((int64_t)sum * sum) >> 7); -} - -unsigned int vpx_variance16x16_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - int sum; - __m256i vsse, vsum; - variance16_avx2(src_ptr, src_stride, ref_ptr, ref_stride, 16, &vsse, &vsum); - variance_final_from_16bit_sum_avx2(vsse, vsum, sse, &sum); - return *sse - (uint32_t)(((int64_t)sum * sum) >> 8); -} - -unsigned int vpx_variance16x32_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - int sum; - __m256i vsse, vsum; - variance16_avx2(src_ptr, src_stride, ref_ptr, ref_stride, 32, &vsse, &vsum); - variance_final_from_16bit_sum_avx2(vsse, vsum, sse, &sum); - return *sse - (uint32_t)(((int64_t)sum * sum) >> 9); -} - -unsigned int vpx_variance32x16_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - int sum; - __m256i vsse, vsum; - variance32_avx2(src_ptr, src_stride, ref_ptr, ref_stride, 16, &vsse, &vsum); - variance_final_from_16bit_sum_avx2(vsse, vsum, sse, &sum); - return *sse - (uint32_t)(((int64_t)sum * sum) >> 9); -} - -unsigned int vpx_variance32x32_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - int sum; - __m256i vsse, vsum; - __m128i vsum_128; - variance32_avx2(src_ptr, src_stride, ref_ptr, ref_stride, 32, &vsse, &vsum); - vsum_128 = _mm_add_epi16(_mm256_castsi256_si128(vsum), - _mm256_extractf128_si256(vsum, 1)); - vsum_128 = _mm_add_epi32(_mm_cvtepi16_epi32(vsum_128), - _mm_cvtepi16_epi32(_mm_srli_si128(vsum_128, 8))); - variance_final_from_32bit_sum_avx2(vsse, vsum_128, sse, &sum); - return *sse - (uint32_t)(((int64_t)sum * sum) >> 10); -} - -unsigned int vpx_variance32x64_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - int sum; - __m256i vsse, vsum; - __m128i vsum_128; - variance32_avx2(src_ptr, src_stride, ref_ptr, ref_stride, 64, &vsse, &vsum); - vsum = sum_to_32bit_avx2(vsum); - vsum_128 = _mm_add_epi32(_mm256_castsi256_si128(vsum), - _mm256_extractf128_si256(vsum, 1)); - variance_final_from_32bit_sum_avx2(vsse, vsum_128, sse, &sum); - return *sse - (uint32_t)(((int64_t)sum * sum) >> 11); -} - -unsigned int vpx_variance64x32_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m256i vsse = _mm256_setzero_si256(); - __m256i vsum = _mm256_setzero_si256(); - __m128i vsum_128; - int sum; - variance64_avx2(src_ptr, src_stride, ref_ptr, ref_stride, 32, &vsse, &vsum); - vsum = sum_to_32bit_avx2(vsum); - vsum_128 = _mm_add_epi32(_mm256_castsi256_si128(vsum), - _mm256_extractf128_si256(vsum, 1)); - variance_final_from_32bit_sum_avx2(vsse, vsum_128, sse, &sum); - return *sse - (uint32_t)(((int64_t)sum * sum) >> 11); -} - -unsigned int vpx_variance64x64_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m256i vsse = _mm256_setzero_si256(); - __m256i vsum = _mm256_setzero_si256(); - __m128i vsum_128; - int sum; - int i = 0; - - for (i = 0; i < 2; i++) { - __m256i vsum16; - variance64_avx2(src_ptr + 32 * i * src_stride, src_stride, - ref_ptr + 32 * i * ref_stride, ref_stride, 32, &vsse, - &vsum16); - vsum = _mm256_add_epi32(vsum, sum_to_32bit_avx2(vsum16)); - } - vsum_128 = _mm_add_epi32(_mm256_castsi256_si128(vsum), - _mm256_extractf128_si256(vsum, 1)); - variance_final_from_32bit_sum_avx2(vsse, vsum_128, sse, &sum); - return *sse - (unsigned int)(((int64_t)sum * sum) >> 12); -} - -unsigned int vpx_mse16x8_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - int sum; - __m256i vsse, vsum; - variance16_avx2(src_ptr, src_stride, ref_ptr, ref_stride, 8, &vsse, &vsum); - variance_final_from_16bit_sum_avx2(vsse, vsum, sse, &sum); - return *sse; -} - -unsigned int vpx_mse16x16_avx2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - int sum; - __m256i vsse, vsum; - variance16_avx2(src_ptr, src_stride, ref_ptr, ref_stride, 16, &vsse, &vsum); - variance_final_from_16bit_sum_avx2(vsse, vsum, sse, &sum); - return *sse; -} - -unsigned int vpx_sub_pixel_variance64x64_avx2( - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, - const uint8_t *ref_ptr, int ref_stride, unsigned int *sse) { - unsigned int sse1; - const int se1 = sub_pixel_variance32xh_avx2( - src_ptr, src_stride, x_offset, y_offset, ref_ptr, ref_stride, 64, &sse1); - unsigned int sse2; - const int se2 = - sub_pixel_variance32xh_avx2(src_ptr + 32, src_stride, x_offset, y_offset, - ref_ptr + 32, ref_stride, 64, &sse2); - const int se = se1 + se2; - *sse = sse1 + sse2; - return *sse - (uint32_t)(((int64_t)se * se) >> 12); -} - -unsigned int vpx_sub_pixel_variance32x32_avx2( - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, - const uint8_t *ref_ptr, int ref_stride, unsigned int *sse) { - const int se = sub_pixel_variance32xh_avx2( - src_ptr, src_stride, x_offset, y_offset, ref_ptr, ref_stride, 32, sse); - return *sse - (uint32_t)(((int64_t)se * se) >> 10); -} - -unsigned int vpx_sub_pixel_avg_variance64x64_avx2( - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, - const uint8_t *ref_ptr, int ref_stride, unsigned int *sse, - const uint8_t *second_pred) { - unsigned int sse1; - const int se1 = sub_pixel_avg_variance32xh_avx2(src_ptr, src_stride, x_offset, - y_offset, ref_ptr, ref_stride, - second_pred, 64, 64, &sse1); - unsigned int sse2; - const int se2 = sub_pixel_avg_variance32xh_avx2( - src_ptr + 32, src_stride, x_offset, y_offset, ref_ptr + 32, ref_stride, - second_pred + 32, 64, 64, &sse2); - const int se = se1 + se2; - - *sse = sse1 + sse2; - - return *sse - (uint32_t)(((int64_t)se * se) >> 12); -} - -unsigned int vpx_sub_pixel_avg_variance32x32_avx2( - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, - const uint8_t *ref_ptr, int ref_stride, unsigned int *sse, - const uint8_t *second_pred) { - // Process 32 elements in parallel. - const int se = sub_pixel_avg_variance32xh_avx2(src_ptr, src_stride, x_offset, - y_offset, ref_ptr, ref_stride, - second_pred, 32, 32, sse); - return *sse - (uint32_t)(((int64_t)se * se) >> 10); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/variance_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/variance_sse2.c deleted file mode 100644 index d6eb12da..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/variance_sse2.c +++ /dev/null @@ -1,565 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include // SSE2 - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_ports/mem.h" -#include "vpx_dsp/x86/mem_sse2.h" - -static INLINE unsigned int add32x4_sse2(__m128i val) { - val = _mm_add_epi32(val, _mm_srli_si128(val, 8)); - val = _mm_add_epi32(val, _mm_srli_si128(val, 4)); - return (unsigned int)_mm_cvtsi128_si32(val); -} - -unsigned int vpx_get_mb_ss_sse2(const int16_t *src_ptr) { - __m128i vsum = _mm_setzero_si128(); - int i; - - for (i = 0; i < 32; ++i) { - const __m128i v = _mm_loadu_si128((const __m128i *)src_ptr); - vsum = _mm_add_epi32(vsum, _mm_madd_epi16(v, v)); - src_ptr += 8; - } - - return add32x4_sse2(vsum); -} - -static INLINE __m128i load4x2_sse2(const uint8_t *const p, const int stride) { - const __m128i p0 = _mm_cvtsi32_si128(loadu_int32(p + 0 * stride)); - const __m128i p1 = _mm_cvtsi32_si128(loadu_int32(p + 1 * stride)); - const __m128i p01 = _mm_unpacklo_epi32(p0, p1); - return _mm_unpacklo_epi8(p01, _mm_setzero_si128()); -} - -static INLINE void variance_kernel_sse2(const __m128i src_ptr, - const __m128i ref_ptr, - __m128i *const sse, - __m128i *const sum) { - const __m128i diff = _mm_sub_epi16(src_ptr, ref_ptr); - *sse = _mm_add_epi32(*sse, _mm_madd_epi16(diff, diff)); - *sum = _mm_add_epi16(*sum, diff); -} - -// Can handle 128 pixels' diff sum (such as 8x16 or 16x8) -// Slightly faster than variance_final_256_pel_sse2() -static INLINE void variance_final_128_pel_sse2(__m128i vsse, __m128i vsum, - unsigned int *const sse, - int *const sum) { - *sse = add32x4_sse2(vsse); - - vsum = _mm_add_epi16(vsum, _mm_srli_si128(vsum, 8)); - vsum = _mm_add_epi16(vsum, _mm_srli_si128(vsum, 4)); - vsum = _mm_add_epi16(vsum, _mm_srli_si128(vsum, 2)); - *sum = (int16_t)_mm_extract_epi16(vsum, 0); -} - -// Can handle 256 pixels' diff sum (such as 16x16) -static INLINE void variance_final_256_pel_sse2(__m128i vsse, __m128i vsum, - unsigned int *const sse, - int *const sum) { - *sse = add32x4_sse2(vsse); - - vsum = _mm_add_epi16(vsum, _mm_srli_si128(vsum, 8)); - vsum = _mm_add_epi16(vsum, _mm_srli_si128(vsum, 4)); - *sum = (int16_t)_mm_extract_epi16(vsum, 0); - *sum += (int16_t)_mm_extract_epi16(vsum, 1); -} - -// Can handle 512 pixels' diff sum (such as 16x32 or 32x16) -static INLINE void variance_final_512_pel_sse2(__m128i vsse, __m128i vsum, - unsigned int *const sse, - int *const sum) { - *sse = add32x4_sse2(vsse); - - vsum = _mm_add_epi16(vsum, _mm_srli_si128(vsum, 8)); - vsum = _mm_unpacklo_epi16(vsum, vsum); - vsum = _mm_srai_epi32(vsum, 16); - *sum = (int)add32x4_sse2(vsum); -} - -static INLINE __m128i sum_to_32bit_sse2(const __m128i sum) { - const __m128i sum_lo = _mm_srai_epi32(_mm_unpacklo_epi16(sum, sum), 16); - const __m128i sum_hi = _mm_srai_epi32(_mm_unpackhi_epi16(sum, sum), 16); - return _mm_add_epi32(sum_lo, sum_hi); -} - -// Can handle 1024 pixels' diff sum (such as 32x32) -static INLINE int sum_final_sse2(const __m128i sum) { - const __m128i t = sum_to_32bit_sse2(sum); - return (int)add32x4_sse2(t); -} - -static INLINE void variance4_sse2(const uint8_t *src_ptr, const int src_stride, - const uint8_t *ref_ptr, const int ref_stride, - const int h, __m128i *const sse, - __m128i *const sum) { - int i; - - assert(h <= 256); // May overflow for larger height. - *sse = _mm_setzero_si128(); - *sum = _mm_setzero_si128(); - - for (i = 0; i < h; i += 2) { - const __m128i s = load4x2_sse2(src_ptr, src_stride); - const __m128i r = load4x2_sse2(ref_ptr, ref_stride); - - variance_kernel_sse2(s, r, sse, sum); - src_ptr += 2 * src_stride; - ref_ptr += 2 * ref_stride; - } -} - -static INLINE void variance8_sse2(const uint8_t *src_ptr, const int src_stride, - const uint8_t *ref_ptr, const int ref_stride, - const int h, __m128i *const sse, - __m128i *const sum) { - const __m128i zero = _mm_setzero_si128(); - int i; - - assert(h <= 128); // May overflow for larger height. - *sse = _mm_setzero_si128(); - *sum = _mm_setzero_si128(); - - for (i = 0; i < h; i++) { - const __m128i s = - _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)src_ptr), zero); - const __m128i r = - _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)ref_ptr), zero); - - variance_kernel_sse2(s, r, sse, sum); - src_ptr += src_stride; - ref_ptr += ref_stride; - } -} - -static INLINE void variance16_kernel_sse2(const uint8_t *const src_ptr, - const uint8_t *const ref_ptr, - __m128i *const sse, - __m128i *const sum) { - const __m128i zero = _mm_setzero_si128(); - const __m128i s = _mm_loadu_si128((const __m128i *)src_ptr); - const __m128i r = _mm_loadu_si128((const __m128i *)ref_ptr); - const __m128i src0 = _mm_unpacklo_epi8(s, zero); - const __m128i ref0 = _mm_unpacklo_epi8(r, zero); - const __m128i src1 = _mm_unpackhi_epi8(s, zero); - const __m128i ref1 = _mm_unpackhi_epi8(r, zero); - - variance_kernel_sse2(src0, ref0, sse, sum); - variance_kernel_sse2(src1, ref1, sse, sum); -} - -static INLINE void variance16_sse2(const uint8_t *src_ptr, const int src_stride, - const uint8_t *ref_ptr, const int ref_stride, - const int h, __m128i *const sse, - __m128i *const sum) { - int i; - - assert(h <= 64); // May overflow for larger height. - *sse = _mm_setzero_si128(); - *sum = _mm_setzero_si128(); - - for (i = 0; i < h; ++i) { - variance16_kernel_sse2(src_ptr, ref_ptr, sse, sum); - src_ptr += src_stride; - ref_ptr += ref_stride; - } -} - -static INLINE void variance32_sse2(const uint8_t *src_ptr, const int src_stride, - const uint8_t *ref_ptr, const int ref_stride, - const int h, __m128i *const sse, - __m128i *const sum) { - int i; - - assert(h <= 32); // May overflow for larger height. - // Don't initialize sse here since it's an accumulation. - *sum = _mm_setzero_si128(); - - for (i = 0; i < h; ++i) { - variance16_kernel_sse2(src_ptr + 0, ref_ptr + 0, sse, sum); - variance16_kernel_sse2(src_ptr + 16, ref_ptr + 16, sse, sum); - src_ptr += src_stride; - ref_ptr += ref_stride; - } -} - -static INLINE void variance64_sse2(const uint8_t *src_ptr, const int src_stride, - const uint8_t *ref_ptr, const int ref_stride, - const int h, __m128i *const sse, - __m128i *const sum) { - int i; - - assert(h <= 16); // May overflow for larger height. - // Don't initialize sse here since it's an accumulation. - *sum = _mm_setzero_si128(); - - for (i = 0; i < h; ++i) { - variance16_kernel_sse2(src_ptr + 0, ref_ptr + 0, sse, sum); - variance16_kernel_sse2(src_ptr + 16, ref_ptr + 16, sse, sum); - variance16_kernel_sse2(src_ptr + 32, ref_ptr + 32, sse, sum); - variance16_kernel_sse2(src_ptr + 48, ref_ptr + 48, sse, sum); - src_ptr += src_stride; - ref_ptr += ref_stride; - } -} - -void vpx_get8x8var_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse, int *sum) { - __m128i vsse, vsum; - variance8_sse2(src_ptr, src_stride, ref_ptr, ref_stride, 8, &vsse, &vsum); - variance_final_128_pel_sse2(vsse, vsum, sse, sum); -} - -void vpx_get16x16var_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse, int *sum) { - __m128i vsse, vsum; - variance16_sse2(src_ptr, src_stride, ref_ptr, ref_stride, 16, &vsse, &vsum); - variance_final_256_pel_sse2(vsse, vsum, sse, sum); -} - -unsigned int vpx_variance4x4_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m128i vsse, vsum; - int sum; - variance4_sse2(src_ptr, src_stride, ref_ptr, ref_stride, 4, &vsse, &vsum); - variance_final_128_pel_sse2(vsse, vsum, sse, &sum); - return *sse - ((sum * sum) >> 4); -} - -unsigned int vpx_variance4x8_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m128i vsse, vsum; - int sum; - variance4_sse2(src_ptr, src_stride, ref_ptr, ref_stride, 8, &vsse, &vsum); - variance_final_128_pel_sse2(vsse, vsum, sse, &sum); - return *sse - ((sum * sum) >> 5); -} - -unsigned int vpx_variance8x4_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m128i vsse, vsum; - int sum; - variance8_sse2(src_ptr, src_stride, ref_ptr, ref_stride, 4, &vsse, &vsum); - variance_final_128_pel_sse2(vsse, vsum, sse, &sum); - return *sse - ((sum * sum) >> 5); -} - -unsigned int vpx_variance8x8_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m128i vsse, vsum; - int sum; - variance8_sse2(src_ptr, src_stride, ref_ptr, ref_stride, 8, &vsse, &vsum); - variance_final_128_pel_sse2(vsse, vsum, sse, &sum); - return *sse - ((sum * sum) >> 6); -} - -unsigned int vpx_variance8x16_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m128i vsse, vsum; - int sum; - variance8_sse2(src_ptr, src_stride, ref_ptr, ref_stride, 16, &vsse, &vsum); - variance_final_128_pel_sse2(vsse, vsum, sse, &sum); - return *sse - ((sum * sum) >> 7); -} - -unsigned int vpx_variance16x8_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m128i vsse, vsum; - int sum; - variance16_sse2(src_ptr, src_stride, ref_ptr, ref_stride, 8, &vsse, &vsum); - variance_final_128_pel_sse2(vsse, vsum, sse, &sum); - return *sse - ((sum * sum) >> 7); -} - -unsigned int vpx_variance16x16_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m128i vsse, vsum; - int sum; - variance16_sse2(src_ptr, src_stride, ref_ptr, ref_stride, 16, &vsse, &vsum); - variance_final_256_pel_sse2(vsse, vsum, sse, &sum); - return *sse - (uint32_t)(((int64_t)sum * sum) >> 8); -} - -unsigned int vpx_variance16x32_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m128i vsse, vsum; - int sum; - variance16_sse2(src_ptr, src_stride, ref_ptr, ref_stride, 32, &vsse, &vsum); - variance_final_512_pel_sse2(vsse, vsum, sse, &sum); - return *sse - (unsigned int)(((int64_t)sum * sum) >> 9); -} - -unsigned int vpx_variance32x16_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m128i vsse = _mm_setzero_si128(); - __m128i vsum; - int sum; - variance32_sse2(src_ptr, src_stride, ref_ptr, ref_stride, 16, &vsse, &vsum); - variance_final_512_pel_sse2(vsse, vsum, sse, &sum); - return *sse - (unsigned int)(((int64_t)sum * sum) >> 9); -} - -unsigned int vpx_variance32x32_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m128i vsse = _mm_setzero_si128(); - __m128i vsum; - int sum; - variance32_sse2(src_ptr, src_stride, ref_ptr, ref_stride, 32, &vsse, &vsum); - *sse = add32x4_sse2(vsse); - sum = sum_final_sse2(vsum); - return *sse - (unsigned int)(((int64_t)sum * sum) >> 10); -} - -unsigned int vpx_variance32x64_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m128i vsse = _mm_setzero_si128(); - __m128i vsum = _mm_setzero_si128(); - int sum; - int i = 0; - - for (i = 0; i < 2; i++) { - __m128i vsum16; - variance32_sse2(src_ptr + 32 * i * src_stride, src_stride, - ref_ptr + 32 * i * ref_stride, ref_stride, 32, &vsse, - &vsum16); - vsum = _mm_add_epi32(vsum, sum_to_32bit_sse2(vsum16)); - } - *sse = add32x4_sse2(vsse); - sum = (int)add32x4_sse2(vsum); - return *sse - (unsigned int)(((int64_t)sum * sum) >> 11); -} - -unsigned int vpx_variance64x32_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m128i vsse = _mm_setzero_si128(); - __m128i vsum = _mm_setzero_si128(); - int sum; - int i = 0; - - for (i = 0; i < 2; i++) { - __m128i vsum16; - variance64_sse2(src_ptr + 16 * i * src_stride, src_stride, - ref_ptr + 16 * i * ref_stride, ref_stride, 16, &vsse, - &vsum16); - vsum = _mm_add_epi32(vsum, sum_to_32bit_sse2(vsum16)); - } - *sse = add32x4_sse2(vsse); - sum = (int)add32x4_sse2(vsum); - return *sse - (unsigned int)(((int64_t)sum * sum) >> 11); -} - -unsigned int vpx_variance64x64_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - __m128i vsse = _mm_setzero_si128(); - __m128i vsum = _mm_setzero_si128(); - int sum; - int i = 0; - - for (i = 0; i < 4; i++) { - __m128i vsum16; - variance64_sse2(src_ptr + 16 * i * src_stride, src_stride, - ref_ptr + 16 * i * ref_stride, ref_stride, 16, &vsse, - &vsum16); - vsum = _mm_add_epi32(vsum, sum_to_32bit_sse2(vsum16)); - } - *sse = add32x4_sse2(vsse); - sum = (int)add32x4_sse2(vsum); - return *sse - (unsigned int)(((int64_t)sum * sum) >> 12); -} - -unsigned int vpx_mse8x8_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - vpx_variance8x8_sse2(src_ptr, src_stride, ref_ptr, ref_stride, sse); - return *sse; -} - -unsigned int vpx_mse8x16_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - vpx_variance8x16_sse2(src_ptr, src_stride, ref_ptr, ref_stride, sse); - return *sse; -} - -unsigned int vpx_mse16x8_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - vpx_variance16x8_sse2(src_ptr, src_stride, ref_ptr, ref_stride, sse); - return *sse; -} - -unsigned int vpx_mse16x16_sse2(const uint8_t *src_ptr, int src_stride, - const uint8_t *ref_ptr, int ref_stride, - unsigned int *sse) { - vpx_variance16x16_sse2(src_ptr, src_stride, ref_ptr, ref_stride, sse); - return *sse; -} - -// The 2 unused parameters are place holders for PIC enabled build. -// These definitions are for functions defined in subpel_variance.asm -#define DECL(w, opt) \ - int vpx_sub_pixel_variance##w##xh_##opt( \ - const uint8_t *src_ptr, ptrdiff_t src_stride, int x_offset, \ - int y_offset, const uint8_t *ref_ptr, ptrdiff_t ref_stride, int height, \ - unsigned int *sse, void *unused0, void *unused) -#define DECLS(opt1, opt2) \ - DECL(4, opt1); \ - DECL(8, opt1); \ - DECL(16, opt1) - -DECLS(sse2, sse2); -DECLS(ssse3, ssse3); -#undef DECLS -#undef DECL - -#define FN(w, h, wf, wlog2, hlog2, opt, cast_prod, cast) \ - unsigned int vpx_sub_pixel_variance##w##x##h##_##opt( \ - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref_ptr, int ref_stride, unsigned int *sse) { \ - unsigned int sse_tmp; \ - int se = vpx_sub_pixel_variance##wf##xh_##opt( \ - src_ptr, src_stride, x_offset, y_offset, ref_ptr, ref_stride, h, \ - &sse_tmp, NULL, NULL); \ - if (w > wf) { \ - unsigned int sse2; \ - int se2 = vpx_sub_pixel_variance##wf##xh_##opt( \ - src_ptr + 16, src_stride, x_offset, y_offset, ref_ptr + 16, \ - ref_stride, h, &sse2, NULL, NULL); \ - se += se2; \ - sse_tmp += sse2; \ - if (w > wf * 2) { \ - se2 = vpx_sub_pixel_variance##wf##xh_##opt( \ - src_ptr + 32, src_stride, x_offset, y_offset, ref_ptr + 32, \ - ref_stride, h, &sse2, NULL, NULL); \ - se += se2; \ - sse_tmp += sse2; \ - se2 = vpx_sub_pixel_variance##wf##xh_##opt( \ - src_ptr + 48, src_stride, x_offset, y_offset, ref_ptr + 48, \ - ref_stride, h, &sse2, NULL, NULL); \ - se += se2; \ - sse_tmp += sse2; \ - } \ - } \ - *sse = sse_tmp; \ - return sse_tmp - \ - (unsigned int)(cast_prod(cast se * se) >> (wlog2 + hlog2)); \ - } - -#define FNS(opt1, opt2) \ - FN(64, 64, 16, 6, 6, opt1, (int64_t), (int64_t)) \ - FN(64, 32, 16, 6, 5, opt1, (int64_t), (int64_t)) \ - FN(32, 64, 16, 5, 6, opt1, (int64_t), (int64_t)) \ - FN(32, 32, 16, 5, 5, opt1, (int64_t), (int64_t)) \ - FN(32, 16, 16, 5, 4, opt1, (int64_t), (int64_t)) \ - FN(16, 32, 16, 4, 5, opt1, (int64_t), (int64_t)) \ - FN(16, 16, 16, 4, 4, opt1, (uint32_t), (int64_t)) \ - FN(16, 8, 16, 4, 3, opt1, (int32_t), (int32_t)) \ - FN(8, 16, 8, 3, 4, opt1, (int32_t), (int32_t)) \ - FN(8, 8, 8, 3, 3, opt1, (int32_t), (int32_t)) \ - FN(8, 4, 8, 3, 2, opt1, (int32_t), (int32_t)) \ - FN(4, 8, 4, 2, 3, opt1, (int32_t), (int32_t)) \ - FN(4, 4, 4, 2, 2, opt1, (int32_t), (int32_t)) - -FNS(sse2, sse2) -FNS(ssse3, ssse3) - -#undef FNS -#undef FN - -// The 2 unused parameters are place holders for PIC enabled build. -#define DECL(w, opt) \ - int vpx_sub_pixel_avg_variance##w##xh_##opt( \ - const uint8_t *src_ptr, ptrdiff_t src_stride, int x_offset, \ - int y_offset, const uint8_t *ref_ptr, ptrdiff_t ref_stride, \ - const uint8_t *second_pred, ptrdiff_t second_stride, int height, \ - unsigned int *sse, void *unused0, void *unused) -#define DECLS(opt1, opt2) \ - DECL(4, opt1); \ - DECL(8, opt1); \ - DECL(16, opt1) - -DECLS(sse2, sse2); -DECLS(ssse3, ssse3); -#undef DECL -#undef DECLS - -#define FN(w, h, wf, wlog2, hlog2, opt, cast_prod, cast) \ - unsigned int vpx_sub_pixel_avg_variance##w##x##h##_##opt( \ - const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, \ - const uint8_t *ref_ptr, int ref_stride, unsigned int *sse, \ - const uint8_t *second_pred) { \ - unsigned int sse_tmp; \ - int se = vpx_sub_pixel_avg_variance##wf##xh_##opt( \ - src_ptr, src_stride, x_offset, y_offset, ref_ptr, ref_stride, \ - second_pred, w, h, &sse_tmp, NULL, NULL); \ - if (w > wf) { \ - unsigned int sse2; \ - int se2 = vpx_sub_pixel_avg_variance##wf##xh_##opt( \ - src_ptr + 16, src_stride, x_offset, y_offset, ref_ptr + 16, \ - ref_stride, second_pred + 16, w, h, &sse2, NULL, NULL); \ - se += se2; \ - sse_tmp += sse2; \ - if (w > wf * 2) { \ - se2 = vpx_sub_pixel_avg_variance##wf##xh_##opt( \ - src_ptr + 32, src_stride, x_offset, y_offset, ref_ptr + 32, \ - ref_stride, second_pred + 32, w, h, &sse2, NULL, NULL); \ - se += se2; \ - sse_tmp += sse2; \ - se2 = vpx_sub_pixel_avg_variance##wf##xh_##opt( \ - src_ptr + 48, src_stride, x_offset, y_offset, ref_ptr + 48, \ - ref_stride, second_pred + 48, w, h, &sse2, NULL, NULL); \ - se += se2; \ - sse_tmp += sse2; \ - } \ - } \ - *sse = sse_tmp; \ - return sse_tmp - \ - (unsigned int)(cast_prod(cast se * se) >> (wlog2 + hlog2)); \ - } - -#define FNS(opt1, opt2) \ - FN(64, 64, 16, 6, 6, opt1, (int64_t), (int64_t)) \ - FN(64, 32, 16, 6, 5, opt1, (int64_t), (int64_t)) \ - FN(32, 64, 16, 5, 6, opt1, (int64_t), (int64_t)) \ - FN(32, 32, 16, 5, 5, opt1, (int64_t), (int64_t)) \ - FN(32, 16, 16, 5, 4, opt1, (int64_t), (int64_t)) \ - FN(16, 32, 16, 4, 5, opt1, (int64_t), (int64_t)) \ - FN(16, 16, 16, 4, 4, opt1, (uint32_t), (int64_t)) \ - FN(16, 8, 16, 4, 3, opt1, (uint32_t), (int32_t)) \ - FN(8, 16, 8, 3, 4, opt1, (uint32_t), (int32_t)) \ - FN(8, 8, 8, 3, 3, opt1, (uint32_t), (int32_t)) \ - FN(8, 4, 8, 3, 2, opt1, (uint32_t), (int32_t)) \ - FN(4, 8, 4, 2, 3, opt1, (uint32_t), (int32_t)) \ - FN(4, 4, 4, 2, 2, opt1, (uint32_t), (int32_t)) - -FNS(sse2, sse) -FNS(ssse3, ssse3) - -#undef FNS -#undef FN diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_convolve_copy_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_convolve_copy_sse2.asm deleted file mode 100644 index 3f444e2e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_convolve_copy_sse2.asm +++ /dev/null @@ -1,226 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "third_party/x86inc/x86inc.asm" - -SECTION .text - -%macro convolve_fn 1-2 -%ifidn %1, avg -%define AUX_XMM_REGS 4 -%else -%define AUX_XMM_REGS 0 -%endif -%ifidn %2, highbd -%define pavg pavgw -cglobal %2_convolve_%1, 4, 8, 4+AUX_XMM_REGS, src, src_stride, \ - dst, dst_stride, \ - f, fxo, fxs, fyo, fys, w, h, bd -%else -%define pavg pavgb -cglobal convolve_%1, 4, 8, 4+AUX_XMM_REGS, src, src_stride, \ - dst, dst_stride, \ - f, fxo, fxs, fyo, fys, w, h -%endif - mov r4d, dword wm -%ifidn %2, highbd - shl r4d, 1 - shl src_strideq, 1 - shl dst_strideq, 1 -%else - cmp r4d, 4 - je .w4 -%endif - cmp r4d, 8 - je .w8 - cmp r4d, 16 - je .w16 - cmp r4d, 32 - je .w32 -%ifidn %2, highbd - cmp r4d, 64 - je .w64 - - mov r4d, dword hm -.loop128: - movu m0, [srcq] - movu m1, [srcq+16] - movu m2, [srcq+32] - movu m3, [srcq+48] -%ifidn %1, avg - pavg m0, [dstq] - pavg m1, [dstq+16] - pavg m2, [dstq+32] - pavg m3, [dstq+48] -%endif - mova [dstq ], m0 - mova [dstq+16], m1 - mova [dstq+32], m2 - mova [dstq+48], m3 - movu m0, [srcq+64] - movu m1, [srcq+80] - movu m2, [srcq+96] - movu m3, [srcq+112] - add srcq, src_strideq -%ifidn %1, avg - pavg m0, [dstq+64] - pavg m1, [dstq+80] - pavg m2, [dstq+96] - pavg m3, [dstq+112] -%endif - mova [dstq+64], m0 - mova [dstq+80], m1 - mova [dstq+96], m2 - mova [dstq+112], m3 - add dstq, dst_strideq - dec r4d - jnz .loop128 - RET -%endif - -.w64: - mov r4d, dword hm -.loop64: - movu m0, [srcq] - movu m1, [srcq+16] - movu m2, [srcq+32] - movu m3, [srcq+48] - add srcq, src_strideq -%ifidn %1, avg - pavg m0, [dstq] - pavg m1, [dstq+16] - pavg m2, [dstq+32] - pavg m3, [dstq+48] -%endif - mova [dstq ], m0 - mova [dstq+16], m1 - mova [dstq+32], m2 - mova [dstq+48], m3 - add dstq, dst_strideq - dec r4d - jnz .loop64 - RET - -.w32: - mov r4d, dword hm -.loop32: - movu m0, [srcq] - movu m1, [srcq+16] - movu m2, [srcq+src_strideq] - movu m3, [srcq+src_strideq+16] - lea srcq, [srcq+src_strideq*2] -%ifidn %1, avg - pavg m0, [dstq] - pavg m1, [dstq +16] - pavg m2, [dstq+dst_strideq] - pavg m3, [dstq+dst_strideq+16] -%endif - mova [dstq ], m0 - mova [dstq +16], m1 - mova [dstq+dst_strideq ], m2 - mova [dstq+dst_strideq+16], m3 - lea dstq, [dstq+dst_strideq*2] - sub r4d, 2 - jnz .loop32 - RET - -.w16: - mov r4d, dword hm - lea r5q, [src_strideq*3] - lea r6q, [dst_strideq*3] -.loop16: - movu m0, [srcq] - movu m1, [srcq+src_strideq] - movu m2, [srcq+src_strideq*2] - movu m3, [srcq+r5q] - lea srcq, [srcq+src_strideq*4] -%ifidn %1, avg - pavg m0, [dstq] - pavg m1, [dstq+dst_strideq] - pavg m2, [dstq+dst_strideq*2] - pavg m3, [dstq+r6q] -%endif - mova [dstq ], m0 - mova [dstq+dst_strideq ], m1 - mova [dstq+dst_strideq*2], m2 - mova [dstq+r6q ], m3 - lea dstq, [dstq+dst_strideq*4] - sub r4d, 4 - jnz .loop16 - RET - -.w8: - mov r4d, dword hm - lea r5q, [src_strideq*3] - lea r6q, [dst_strideq*3] -.loop8: - movh m0, [srcq] - movh m1, [srcq+src_strideq] - movh m2, [srcq+src_strideq*2] - movh m3, [srcq+r5q] - lea srcq, [srcq+src_strideq*4] -%ifidn %1, avg - movh m4, [dstq] - movh m5, [dstq+dst_strideq] - movh m6, [dstq+dst_strideq*2] - movh m7, [dstq+r6q] - pavg m0, m4 - pavg m1, m5 - pavg m2, m6 - pavg m3, m7 -%endif - movh [dstq ], m0 - movh [dstq+dst_strideq ], m1 - movh [dstq+dst_strideq*2], m2 - movh [dstq+r6q ], m3 - lea dstq, [dstq+dst_strideq*4] - sub r4d, 4 - jnz .loop8 - RET - -%ifnidn %2, highbd -.w4: - mov r4d, dword hm - lea r5q, [src_strideq*3] - lea r6q, [dst_strideq*3] -.loop4: - movd m0, [srcq] - movd m1, [srcq+src_strideq] - movd m2, [srcq+src_strideq*2] - movd m3, [srcq+r5q] - lea srcq, [srcq+src_strideq*4] -%ifidn %1, avg - movd m4, [dstq] - movd m5, [dstq+dst_strideq] - movd m6, [dstq+dst_strideq*2] - movd m7, [dstq+r6q] - pavg m0, m4 - pavg m1, m5 - pavg m2, m6 - pavg m3, m7 -%endif - movd [dstq ], m0 - movd [dstq+dst_strideq ], m1 - movd [dstq+dst_strideq*2], m2 - movd [dstq+r6q ], m3 - lea dstq, [dstq+dst_strideq*4] - sub r4d, 4 - jnz .loop4 - RET -%endif -%endmacro - -INIT_XMM sse2 -convolve_fn copy -convolve_fn avg -%if CONFIG_VP9_HIGHBITDEPTH -convolve_fn copy, highbd -convolve_fn avg, highbd -%endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_high_subpixel_8t_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_high_subpixel_8t_sse2.asm deleted file mode 100644 index fc301fb3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_high_subpixel_8t_sse2.asm +++ /dev/null @@ -1,964 +0,0 @@ -; -; Copyright (c) 2014 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -;Note: tap3 and tap4 have to be applied and added after other taps to avoid -;overflow. - -%macro HIGH_GET_FILTERS_4 0 - mov rdx, arg(5) ;filter ptr - mov rcx, 0x00000040 - - movdqa xmm7, [rdx] ;load filters - pshuflw xmm0, xmm7, 0b ;k0 - pshuflw xmm1, xmm7, 01010101b ;k1 - pshuflw xmm2, xmm7, 10101010b ;k2 - pshuflw xmm3, xmm7, 11111111b ;k3 - psrldq xmm7, 8 - pshuflw xmm4, xmm7, 0b ;k4 - pshuflw xmm5, xmm7, 01010101b ;k5 - pshuflw xmm6, xmm7, 10101010b ;k6 - pshuflw xmm7, xmm7, 11111111b ;k7 - - punpcklwd xmm0, xmm6 - punpcklwd xmm2, xmm5 - punpcklwd xmm3, xmm4 - punpcklwd xmm1, xmm7 - - movdqa k0k6, xmm0 - movdqa k2k5, xmm2 - movdqa k3k4, xmm3 - movdqa k1k7, xmm1 - - movq xmm6, rcx - pshufd xmm6, xmm6, 0 - movdqa krd, xmm6 - - ;Compute max and min values of a pixel - mov rdx, 0x00010001 - movsxd rcx, DWORD PTR arg(6) ;bd - movq xmm0, rdx - movq xmm1, rcx - pshufd xmm0, xmm0, 0b - movdqa xmm2, xmm0 - psllw xmm0, xmm1 - psubw xmm0, xmm2 - pxor xmm1, xmm1 - movdqa max, xmm0 ;max value (for clamping) - movdqa min, xmm1 ;min value (for clamping) - -%endm - -%macro HIGH_APPLY_FILTER_4 1 - punpcklwd xmm0, xmm6 ;two row in one register - punpcklwd xmm1, xmm7 - punpcklwd xmm2, xmm5 - punpcklwd xmm3, xmm4 - - pmaddwd xmm0, k0k6 ;multiply the filter factors - pmaddwd xmm1, k1k7 - pmaddwd xmm2, k2k5 - pmaddwd xmm3, k3k4 - - paddd xmm0, xmm1 ;sum - paddd xmm0, xmm2 - paddd xmm0, xmm3 - - paddd xmm0, krd ;rounding - psrad xmm0, 7 ;shift - packssdw xmm0, xmm0 ;pack to word - - ;clamp the values - pminsw xmm0, max - pmaxsw xmm0, min - -%if %1 - movq xmm1, [rdi] - pavgw xmm0, xmm1 -%endif - movq [rdi], xmm0 -%endm - -%macro HIGH_GET_FILTERS 0 - mov rdx, arg(5) ;filter ptr - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - mov rcx, 0x00000040 - - movdqa xmm7, [rdx] ;load filters - pshuflw xmm0, xmm7, 0b ;k0 - pshuflw xmm1, xmm7, 01010101b ;k1 - pshuflw xmm2, xmm7, 10101010b ;k2 - pshuflw xmm3, xmm7, 11111111b ;k3 - pshufhw xmm4, xmm7, 0b ;k4 - pshufhw xmm5, xmm7, 01010101b ;k5 - pshufhw xmm6, xmm7, 10101010b ;k6 - pshufhw xmm7, xmm7, 11111111b ;k7 - punpcklqdq xmm2, xmm2 - punpcklqdq xmm3, xmm3 - punpcklwd xmm0, xmm1 - punpckhwd xmm6, xmm7 - punpckhwd xmm2, xmm5 - punpckhwd xmm3, xmm4 - - movdqa k0k1, xmm0 ;store filter factors on stack - movdqa k6k7, xmm6 - movdqa k2k5, xmm2 - movdqa k3k4, xmm3 - - movq xmm6, rcx - pshufd xmm6, xmm6, 0 - movdqa krd, xmm6 ;rounding - - ;Compute max and min values of a pixel - mov rdx, 0x00010001 - movsxd rcx, DWORD PTR arg(6) ;bd - movq xmm0, rdx - movq xmm1, rcx - pshufd xmm0, xmm0, 0b - movdqa xmm2, xmm0 - psllw xmm0, xmm1 - psubw xmm0, xmm2 - pxor xmm1, xmm1 - movdqa max, xmm0 ;max value (for clamping) - movdqa min, xmm1 ;min value (for clamping) -%endm - -%macro LOAD_VERT_8 1 - movdqu xmm0, [rsi + %1] ;0 - movdqu xmm1, [rsi + rax + %1] ;1 - movdqu xmm6, [rsi + rdx * 2 + %1] ;6 - lea rsi, [rsi + rax] - movdqu xmm7, [rsi + rdx * 2 + %1] ;7 - movdqu xmm2, [rsi + rax + %1] ;2 - movdqu xmm3, [rsi + rax * 2 + %1] ;3 - movdqu xmm4, [rsi + rdx + %1] ;4 - movdqu xmm5, [rsi + rax * 4 + %1] ;5 -%endm - -%macro HIGH_APPLY_FILTER_8 2 - movdqu temp, xmm4 - movdqa xmm4, xmm0 - punpcklwd xmm0, xmm1 - punpckhwd xmm4, xmm1 - movdqa xmm1, xmm6 - punpcklwd xmm6, xmm7 - punpckhwd xmm1, xmm7 - movdqa xmm7, xmm2 - punpcklwd xmm2, xmm5 - punpckhwd xmm7, xmm5 - - movdqu xmm5, temp - movdqu temp, xmm4 - movdqa xmm4, xmm3 - punpcklwd xmm3, xmm5 - punpckhwd xmm4, xmm5 - movdqu xmm5, temp - - pmaddwd xmm0, k0k1 - pmaddwd xmm5, k0k1 - pmaddwd xmm6, k6k7 - pmaddwd xmm1, k6k7 - pmaddwd xmm2, k2k5 - pmaddwd xmm7, k2k5 - pmaddwd xmm3, k3k4 - pmaddwd xmm4, k3k4 - - paddd xmm0, xmm6 - paddd xmm0, xmm2 - paddd xmm0, xmm3 - paddd xmm5, xmm1 - paddd xmm5, xmm7 - paddd xmm5, xmm4 - - paddd xmm0, krd ;rounding - paddd xmm5, krd - psrad xmm0, 7 ;shift - psrad xmm5, 7 - packssdw xmm0, xmm5 ;pack back to word - - ;clamp the values - pminsw xmm0, max - pmaxsw xmm0, min - -%if %1 - movdqu xmm1, [rdi + %2] - pavgw xmm0, xmm1 -%endif - movdqu [rdi + %2], xmm0 -%endm - -SECTION .text - -;void vpx_highbd_filter_block1d4_v8_sse2 -;( -; unsigned char *src_ptr, -; unsigned int src_pitch, -; unsigned char *output_ptr, -; unsigned int out_pitch, -; unsigned int output_height, -; short *filter -;) -globalsym(vpx_highbd_filter_block1d4_v8_sse2) -sym(vpx_highbd_filter_block1d4_v8_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 7 - push rsi - push rdi - push rbx - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 7 - %define k0k6 [rsp + 16 * 0] - %define k2k5 [rsp + 16 * 1] - %define k3k4 [rsp + 16 * 2] - %define k1k7 [rsp + 16 * 3] - %define krd [rsp + 16 * 4] - %define max [rsp + 16 * 5] - %define min [rsp + 16 * 6] - - HIGH_GET_FILTERS_4 - - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rbx, DWORD PTR arg(3) ;out_pitch - lea rax, [rax + rax] ;bytes per line - lea rbx, [rbx + rbx] - lea rdx, [rax + rax * 2] - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - movq xmm0, [rsi] ;load src: row 0 - movq xmm1, [rsi + rax] ;1 - movq xmm6, [rsi + rdx * 2] ;6 - lea rsi, [rsi + rax] - movq xmm7, [rsi + rdx * 2] ;7 - movq xmm2, [rsi + rax] ;2 - movq xmm3, [rsi + rax * 2] ;3 - movq xmm4, [rsi + rdx] ;4 - movq xmm5, [rsi + rax * 4] ;5 - - HIGH_APPLY_FILTER_4 0 - - lea rdi, [rdi + rbx] - dec rcx - jnz .loop - - add rsp, 16 * 7 - pop rsp - pop rbx - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -;void vpx_highbd_filter_block1d8_v8_sse2 -;( -; unsigned char *src_ptr, -; unsigned int src_pitch, -; unsigned char *output_ptr, -; unsigned int out_pitch, -; unsigned int output_height, -; short *filter -;) -globalsym(vpx_highbd_filter_block1d8_v8_sse2) -sym(vpx_highbd_filter_block1d8_v8_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 7 - push rsi - push rdi - push rbx - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 8 - %define k0k1 [rsp + 16 * 0] - %define k6k7 [rsp + 16 * 1] - %define k2k5 [rsp + 16 * 2] - %define k3k4 [rsp + 16 * 3] - %define krd [rsp + 16 * 4] - %define temp [rsp + 16 * 5] - %define max [rsp + 16 * 6] - %define min [rsp + 16 * 7] - - HIGH_GET_FILTERS - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rbx, DWORD PTR arg(3) ;out_pitch - lea rax, [rax + rax] ;bytes per line - lea rbx, [rbx + rbx] - lea rdx, [rax + rax * 2] - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - LOAD_VERT_8 0 - HIGH_APPLY_FILTER_8 0, 0 - - lea rdi, [rdi + rbx] - dec rcx - jnz .loop - - add rsp, 16 * 8 - pop rsp - pop rbx - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -;void vpx_highbd_filter_block1d16_v8_sse2 -;( -; unsigned char *src_ptr, -; unsigned int src_pitch, -; unsigned char *output_ptr, -; unsigned int out_pitch, -; unsigned int output_height, -; short *filter -;) -globalsym(vpx_highbd_filter_block1d16_v8_sse2) -sym(vpx_highbd_filter_block1d16_v8_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 7 - push rsi - push rdi - push rbx - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 8 - %define k0k1 [rsp + 16 * 0] - %define k6k7 [rsp + 16 * 1] - %define k2k5 [rsp + 16 * 2] - %define k3k4 [rsp + 16 * 3] - %define krd [rsp + 16 * 4] - %define temp [rsp + 16 * 5] - %define max [rsp + 16 * 6] - %define min [rsp + 16 * 7] - - HIGH_GET_FILTERS - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rbx, DWORD PTR arg(3) ;out_pitch - lea rax, [rax + rax] ;bytes per line - lea rbx, [rbx + rbx] - lea rdx, [rax + rax * 2] - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - LOAD_VERT_8 0 - HIGH_APPLY_FILTER_8 0, 0 - sub rsi, rax - - LOAD_VERT_8 16 - HIGH_APPLY_FILTER_8 0, 16 - add rdi, rbx - - dec rcx - jnz .loop - - add rsp, 16 * 8 - pop rsp - pop rbx - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_highbd_filter_block1d4_v8_avg_sse2) -sym(vpx_highbd_filter_block1d4_v8_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 7 - push rsi - push rdi - push rbx - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 7 - %define k0k6 [rsp + 16 * 0] - %define k2k5 [rsp + 16 * 1] - %define k3k4 [rsp + 16 * 2] - %define k1k7 [rsp + 16 * 3] - %define krd [rsp + 16 * 4] - %define max [rsp + 16 * 5] - %define min [rsp + 16 * 6] - - HIGH_GET_FILTERS_4 - - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rbx, DWORD PTR arg(3) ;out_pitch - lea rax, [rax + rax] ;bytes per line - lea rbx, [rbx + rbx] - lea rdx, [rax + rax * 2] - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - movq xmm0, [rsi] ;load src: row 0 - movq xmm1, [rsi + rax] ;1 - movq xmm6, [rsi + rdx * 2] ;6 - lea rsi, [rsi + rax] - movq xmm7, [rsi + rdx * 2] ;7 - movq xmm2, [rsi + rax] ;2 - movq xmm3, [rsi + rax * 2] ;3 - movq xmm4, [rsi + rdx] ;4 - movq xmm5, [rsi + rax * 4] ;5 - - HIGH_APPLY_FILTER_4 1 - - lea rdi, [rdi + rbx] - dec rcx - jnz .loop - - add rsp, 16 * 7 - pop rsp - pop rbx - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_highbd_filter_block1d8_v8_avg_sse2) -sym(vpx_highbd_filter_block1d8_v8_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 7 - push rsi - push rdi - push rbx - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 8 - %define k0k1 [rsp + 16 * 0] - %define k6k7 [rsp + 16 * 1] - %define k2k5 [rsp + 16 * 2] - %define k3k4 [rsp + 16 * 3] - %define krd [rsp + 16 * 4] - %define temp [rsp + 16 * 5] - %define max [rsp + 16 * 6] - %define min [rsp + 16 * 7] - - HIGH_GET_FILTERS - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rbx, DWORD PTR arg(3) ;out_pitch - lea rax, [rax + rax] ;bytes per line - lea rbx, [rbx + rbx] - lea rdx, [rax + rax * 2] - movsxd rcx, DWORD PTR arg(4) ;output_height -.loop: - LOAD_VERT_8 0 - HIGH_APPLY_FILTER_8 1, 0 - - lea rdi, [rdi + rbx] - dec rcx - jnz .loop - - add rsp, 16 * 8 - pop rsp - pop rbx - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_highbd_filter_block1d16_v8_avg_sse2) -sym(vpx_highbd_filter_block1d16_v8_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 7 - push rsi - push rdi - push rbx - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 8 - %define k0k1 [rsp + 16 * 0] - %define k6k7 [rsp + 16 * 1] - %define k2k5 [rsp + 16 * 2] - %define k3k4 [rsp + 16 * 3] - %define krd [rsp + 16 * 4] - %define temp [rsp + 16 * 5] - %define max [rsp + 16 * 6] - %define min [rsp + 16 * 7] - - HIGH_GET_FILTERS - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rbx, DWORD PTR arg(3) ;out_pitch - lea rax, [rax + rax] ;bytes per line - lea rbx, [rbx + rbx] - lea rdx, [rax + rax * 2] - movsxd rcx, DWORD PTR arg(4) ;output_height -.loop: - LOAD_VERT_8 0 - HIGH_APPLY_FILTER_8 1, 0 - sub rsi, rax - - LOAD_VERT_8 16 - HIGH_APPLY_FILTER_8 1, 16 - add rdi, rbx - - dec rcx - jnz .loop - - add rsp, 16 * 8 - pop rsp - pop rbx - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -;void vpx_highbd_filter_block1d4_h8_sse2 -;( -; unsigned char *src_ptr, -; unsigned int src_pixels_per_line, -; unsigned char *output_ptr, -; unsigned int output_pitch, -; unsigned int output_height, -; short *filter -;) -globalsym(vpx_highbd_filter_block1d4_h8_sse2) -sym(vpx_highbd_filter_block1d4_h8_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 7 - %define k0k6 [rsp + 16 * 0] - %define k2k5 [rsp + 16 * 1] - %define k3k4 [rsp + 16 * 2] - %define k1k7 [rsp + 16 * 3] - %define krd [rsp + 16 * 4] - %define max [rsp + 16 * 5] - %define min [rsp + 16 * 6] - - HIGH_GET_FILTERS_4 - - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - lea rax, [rax + rax] ;bytes per line - lea rdx, [rdx + rdx] - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - movdqu xmm0, [rsi - 6] ;load src - movdqu xmm4, [rsi + 2] - movdqa xmm1, xmm0 - movdqa xmm6, xmm4 - movdqa xmm7, xmm4 - movdqa xmm2, xmm0 - movdqa xmm3, xmm0 - movdqa xmm5, xmm4 - - psrldq xmm1, 2 - psrldq xmm6, 4 - psrldq xmm7, 6 - psrldq xmm2, 4 - psrldq xmm3, 6 - psrldq xmm5, 2 - - HIGH_APPLY_FILTER_4 0 - - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx - jnz .loop - - add rsp, 16 * 7 - pop rsp - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -;void vpx_highbd_filter_block1d8_h8_sse2 -;( -; unsigned char *src_ptr, -; unsigned int src_pixels_per_line, -; unsigned char *output_ptr, -; unsigned int output_pitch, -; unsigned int output_height, -; short *filter -;) -globalsym(vpx_highbd_filter_block1d8_h8_sse2) -sym(vpx_highbd_filter_block1d8_h8_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 8 - %define k0k1 [rsp + 16 * 0] - %define k6k7 [rsp + 16 * 1] - %define k2k5 [rsp + 16 * 2] - %define k3k4 [rsp + 16 * 3] - %define krd [rsp + 16 * 4] - %define temp [rsp + 16 * 5] - %define max [rsp + 16 * 6] - %define min [rsp + 16 * 7] - - HIGH_GET_FILTERS - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - lea rax, [rax + rax] ;bytes per line - lea rdx, [rdx + rdx] - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - movdqu xmm0, [rsi - 6] ;load src - movdqu xmm1, [rsi - 4] - movdqu xmm2, [rsi - 2] - movdqu xmm3, [rsi] - movdqu xmm4, [rsi + 2] - movdqu xmm5, [rsi + 4] - movdqu xmm6, [rsi + 6] - movdqu xmm7, [rsi + 8] - - HIGH_APPLY_FILTER_8 0, 0 - - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx - jnz .loop - - add rsp, 16 * 8 - pop rsp - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -;void vpx_highbd_filter_block1d16_h8_sse2 -;( -; unsigned char *src_ptr, -; unsigned int src_pixels_per_line, -; unsigned char *output_ptr, -; unsigned int output_pitch, -; unsigned int output_height, -; short *filter -;) -globalsym(vpx_highbd_filter_block1d16_h8_sse2) -sym(vpx_highbd_filter_block1d16_h8_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 8 - %define k0k1 [rsp + 16 * 0] - %define k6k7 [rsp + 16 * 1] - %define k2k5 [rsp + 16 * 2] - %define k3k4 [rsp + 16 * 3] - %define krd [rsp + 16 * 4] - %define temp [rsp + 16 * 5] - %define max [rsp + 16 * 6] - %define min [rsp + 16 * 7] - - HIGH_GET_FILTERS - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - lea rax, [rax + rax] ;bytes per line - lea rdx, [rdx + rdx] - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - movdqu xmm0, [rsi - 6] ;load src - movdqu xmm1, [rsi - 4] - movdqu xmm2, [rsi - 2] - movdqu xmm3, [rsi] - movdqu xmm4, [rsi + 2] - movdqu xmm5, [rsi + 4] - movdqu xmm6, [rsi + 6] - movdqu xmm7, [rsi + 8] - - HIGH_APPLY_FILTER_8 0, 0 - - movdqu xmm0, [rsi + 10] ;load src - movdqu xmm1, [rsi + 12] - movdqu xmm2, [rsi + 14] - movdqu xmm3, [rsi + 16] - movdqu xmm4, [rsi + 18] - movdqu xmm5, [rsi + 20] - movdqu xmm6, [rsi + 22] - movdqu xmm7, [rsi + 24] - - HIGH_APPLY_FILTER_8 0, 16 - - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx - jnz .loop - - add rsp, 16 * 8 - pop rsp - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_highbd_filter_block1d4_h8_avg_sse2) -sym(vpx_highbd_filter_block1d4_h8_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 7 - %define k0k6 [rsp + 16 * 0] - %define k2k5 [rsp + 16 * 1] - %define k3k4 [rsp + 16 * 2] - %define k1k7 [rsp + 16 * 3] - %define krd [rsp + 16 * 4] - %define max [rsp + 16 * 5] - %define min [rsp + 16 * 6] - - HIGH_GET_FILTERS_4 - - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - lea rax, [rax + rax] ;bytes per line - lea rdx, [rdx + rdx] - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - movdqu xmm0, [rsi - 6] ;load src - movdqu xmm4, [rsi + 2] - movdqa xmm1, xmm0 - movdqa xmm6, xmm4 - movdqa xmm7, xmm4 - movdqa xmm2, xmm0 - movdqa xmm3, xmm0 - movdqa xmm5, xmm4 - - psrldq xmm1, 2 - psrldq xmm6, 4 - psrldq xmm7, 6 - psrldq xmm2, 4 - psrldq xmm3, 6 - psrldq xmm5, 2 - - HIGH_APPLY_FILTER_4 1 - - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx - jnz .loop - - add rsp, 16 * 7 - pop rsp - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_highbd_filter_block1d8_h8_avg_sse2) -sym(vpx_highbd_filter_block1d8_h8_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 8 - %define k0k1 [rsp + 16 * 0] - %define k6k7 [rsp + 16 * 1] - %define k2k5 [rsp + 16 * 2] - %define k3k4 [rsp + 16 * 3] - %define krd [rsp + 16 * 4] - %define temp [rsp + 16 * 5] - %define max [rsp + 16 * 6] - %define min [rsp + 16 * 7] - - HIGH_GET_FILTERS - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - lea rax, [rax + rax] ;bytes per line - lea rdx, [rdx + rdx] - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - movdqu xmm0, [rsi - 6] ;load src - movdqu xmm1, [rsi - 4] - movdqu xmm2, [rsi - 2] - movdqu xmm3, [rsi] - movdqu xmm4, [rsi + 2] - movdqu xmm5, [rsi + 4] - movdqu xmm6, [rsi + 6] - movdqu xmm7, [rsi + 8] - - HIGH_APPLY_FILTER_8 1, 0 - - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx - jnz .loop - - add rsp, 16 * 8 - pop rsp - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_highbd_filter_block1d16_h8_avg_sse2) -sym(vpx_highbd_filter_block1d16_h8_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 8 - %define k0k1 [rsp + 16 * 0] - %define k6k7 [rsp + 16 * 1] - %define k2k5 [rsp + 16 * 2] - %define k3k4 [rsp + 16 * 3] - %define krd [rsp + 16 * 4] - %define temp [rsp + 16 * 5] - %define max [rsp + 16 * 6] - %define min [rsp + 16 * 7] - - HIGH_GET_FILTERS - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - lea rax, [rax + rax] ;bytes per line - lea rdx, [rdx + rdx] - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - movdqu xmm0, [rsi - 6] ;load src - movdqu xmm1, [rsi - 4] - movdqu xmm2, [rsi - 2] - movdqu xmm3, [rsi] - movdqu xmm4, [rsi + 2] - movdqu xmm5, [rsi + 4] - movdqu xmm6, [rsi + 6] - movdqu xmm7, [rsi + 8] - - HIGH_APPLY_FILTER_8 1, 0 - - movdqu xmm0, [rsi + 10] ;load src - movdqu xmm1, [rsi + 12] - movdqu xmm2, [rsi + 14] - movdqu xmm3, [rsi + 16] - movdqu xmm4, [rsi + 18] - movdqu xmm5, [rsi + 20] - movdqu xmm6, [rsi + 22] - movdqu xmm7, [rsi + 24] - - HIGH_APPLY_FILTER_8 1, 16 - - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx - jnz .loop - - add rsp, 16 * 8 - pop rsp - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_high_subpixel_bilinear_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_high_subpixel_bilinear_sse2.asm deleted file mode 100644 index bd51c75b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_high_subpixel_bilinear_sse2.asm +++ /dev/null @@ -1,496 +0,0 @@ -; -; Copyright (c) 2014 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "vpx_ports/x86_abi_support.asm" - -%macro HIGH_GET_PARAM_4 0 - mov rdx, arg(5) ;filter ptr - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - mov rcx, 0x00000040 - - movdqa xmm3, [rdx] ;load filters - pshuflw xmm4, xmm3, 11111111b ;k3 - psrldq xmm3, 8 - pshuflw xmm3, xmm3, 0b ;k4 - punpcklwd xmm4, xmm3 ;k3k4 - - movq xmm3, rcx ;rounding - pshufd xmm3, xmm3, 0 - - mov rdx, 0x00010001 - movsxd rcx, DWORD PTR arg(6) ;bd - movq xmm5, rdx - movq xmm2, rcx - pshufd xmm5, xmm5, 0b - movdqa xmm1, xmm5 - psllw xmm5, xmm2 - psubw xmm5, xmm1 ;max value (for clamping) - pxor xmm2, xmm2 ;min value (for clamping) - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - movsxd rcx, DWORD PTR arg(4) ;output_height -%endm - -%macro HIGH_APPLY_FILTER_4 1 - - punpcklwd xmm0, xmm1 ;two row in one register - pmaddwd xmm0, xmm4 ;multiply the filter factors - - paddd xmm0, xmm3 ;rounding - psrad xmm0, 7 ;shift - packssdw xmm0, xmm0 ;pack to word - - ;clamp the values - pminsw xmm0, xmm5 - pmaxsw xmm0, xmm2 - -%if %1 - movq xmm1, [rdi] - pavgw xmm0, xmm1 -%endif - - movq [rdi], xmm0 - lea rsi, [rsi + 2*rax] - lea rdi, [rdi + 2*rdx] - dec rcx -%endm - -%if VPX_ARCH_X86_64 -%macro HIGH_GET_PARAM 0 - mov rdx, arg(5) ;filter ptr - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - mov rcx, 0x00000040 - - movdqa xmm6, [rdx] ;load filters - - pshuflw xmm7, xmm6, 11111111b ;k3 - pshufhw xmm6, xmm6, 0b ;k4 - psrldq xmm6, 8 - punpcklwd xmm7, xmm6 ;k3k4k3k4k3k4k3k4 - - movq xmm4, rcx ;rounding - pshufd xmm4, xmm4, 0 - - mov rdx, 0x00010001 - movsxd rcx, DWORD PTR arg(6) ;bd - movq xmm8, rdx - movq xmm5, rcx - pshufd xmm8, xmm8, 0b - movdqa xmm1, xmm8 - psllw xmm8, xmm5 - psubw xmm8, xmm1 ;max value (for clamping) - pxor xmm5, xmm5 ;min value (for clamping) - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - movsxd rcx, DWORD PTR arg(4) ;output_height -%endm - -%macro HIGH_APPLY_FILTER_8 1 - movdqa xmm6, xmm0 - punpckhwd xmm6, xmm1 - punpcklwd xmm0, xmm1 - pmaddwd xmm6, xmm7 - pmaddwd xmm0, xmm7 - - paddd xmm6, xmm4 ;rounding - paddd xmm0, xmm4 ;rounding - psrad xmm6, 7 ;shift - psrad xmm0, 7 ;shift - packssdw xmm0, xmm6 ;pack back to word - - ;clamp the values - pminsw xmm0, xmm8 - pmaxsw xmm0, xmm5 - -%if %1 - movdqu xmm1, [rdi] - pavgw xmm0, xmm1 -%endif - movdqu [rdi], xmm0 ;store the result - - lea rsi, [rsi + 2*rax] - lea rdi, [rdi + 2*rdx] - dec rcx -%endm - -%macro HIGH_APPLY_FILTER_16 1 - movdqa xmm9, xmm0 - movdqa xmm6, xmm2 - punpckhwd xmm9, xmm1 - punpckhwd xmm6, xmm3 - punpcklwd xmm0, xmm1 - punpcklwd xmm2, xmm3 - - pmaddwd xmm9, xmm7 - pmaddwd xmm6, xmm7 - pmaddwd xmm0, xmm7 - pmaddwd xmm2, xmm7 - - paddd xmm9, xmm4 ;rounding - paddd xmm6, xmm4 - paddd xmm0, xmm4 - paddd xmm2, xmm4 - - psrad xmm9, 7 ;shift - psrad xmm6, 7 - psrad xmm0, 7 - psrad xmm2, 7 - - packssdw xmm0, xmm9 ;pack back to word - packssdw xmm2, xmm6 ;pack back to word - - ;clamp the values - pminsw xmm0, xmm8 - pmaxsw xmm0, xmm5 - pminsw xmm2, xmm8 - pmaxsw xmm2, xmm5 - -%if %1 - movdqu xmm1, [rdi] - movdqu xmm3, [rdi + 16] - pavgw xmm0, xmm1 - pavgw xmm2, xmm3 -%endif - movdqu [rdi], xmm0 ;store the result - movdqu [rdi + 16], xmm2 ;store the result - - lea rsi, [rsi + 2*rax] - lea rdi, [rdi + 2*rdx] - dec rcx -%endm -%endif - -SECTION .text - -globalsym(vpx_highbd_filter_block1d4_v2_sse2) -sym(vpx_highbd_filter_block1d4_v2_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - push rsi - push rdi - ; end prolog - - HIGH_GET_PARAM_4 -.loop: - movq xmm0, [rsi] ;load src - movq xmm1, [rsi + 2*rax] - - HIGH_APPLY_FILTER_4 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - UNSHADOW_ARGS - pop rbp - ret - -%if VPX_ARCH_X86_64 -globalsym(vpx_highbd_filter_block1d8_v2_sse2) -sym(vpx_highbd_filter_block1d8_v2_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 8 - push rsi - push rdi - ; end prolog - - HIGH_GET_PARAM -.loop: - movdqu xmm0, [rsi] ;0 - movdqu xmm1, [rsi + 2*rax] ;1 - - HIGH_APPLY_FILTER_8 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_highbd_filter_block1d16_v2_sse2) -sym(vpx_highbd_filter_block1d16_v2_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 9 - push rsi - push rdi - ; end prolog - - HIGH_GET_PARAM -.loop: - movdqu xmm0, [rsi] ;0 - movdqu xmm2, [rsi + 16] - movdqu xmm1, [rsi + 2*rax] ;1 - movdqu xmm3, [rsi + 2*rax + 16] - - HIGH_APPLY_FILTER_16 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret -%endif - -globalsym(vpx_highbd_filter_block1d4_v2_avg_sse2) -sym(vpx_highbd_filter_block1d4_v2_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - push rsi - push rdi - ; end prolog - - HIGH_GET_PARAM_4 -.loop: - movq xmm0, [rsi] ;load src - movq xmm1, [rsi + 2*rax] - - HIGH_APPLY_FILTER_4 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - UNSHADOW_ARGS - pop rbp - ret - -%if VPX_ARCH_X86_64 -globalsym(vpx_highbd_filter_block1d8_v2_avg_sse2) -sym(vpx_highbd_filter_block1d8_v2_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 8 - push rsi - push rdi - ; end prolog - - HIGH_GET_PARAM -.loop: - movdqu xmm0, [rsi] ;0 - movdqu xmm1, [rsi + 2*rax] ;1 - - HIGH_APPLY_FILTER_8 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_highbd_filter_block1d16_v2_avg_sse2) -sym(vpx_highbd_filter_block1d16_v2_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 9 - push rsi - push rdi - ; end prolog - - HIGH_GET_PARAM -.loop: - movdqu xmm0, [rsi] ;0 - movdqu xmm1, [rsi + 2*rax] ;1 - movdqu xmm2, [rsi + 16] - movdqu xmm3, [rsi + 2*rax + 16] - - HIGH_APPLY_FILTER_16 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret -%endif - -globalsym(vpx_highbd_filter_block1d4_h2_sse2) -sym(vpx_highbd_filter_block1d4_h2_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - push rsi - push rdi - ; end prolog - - HIGH_GET_PARAM_4 -.loop: - movdqu xmm0, [rsi] ;load src - movdqa xmm1, xmm0 - psrldq xmm1, 2 - - HIGH_APPLY_FILTER_4 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - UNSHADOW_ARGS - pop rbp - ret - -%if VPX_ARCH_X86_64 -globalsym(vpx_highbd_filter_block1d8_h2_sse2) -sym(vpx_highbd_filter_block1d8_h2_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 8 - push rsi - push rdi - ; end prolog - - HIGH_GET_PARAM -.loop: - movdqu xmm0, [rsi] ;load src - movdqu xmm1, [rsi + 2] - - HIGH_APPLY_FILTER_8 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_highbd_filter_block1d16_h2_sse2) -sym(vpx_highbd_filter_block1d16_h2_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 9 - push rsi - push rdi - ; end prolog - - HIGH_GET_PARAM -.loop: - movdqu xmm0, [rsi] ;load src - movdqu xmm1, [rsi + 2] - movdqu xmm2, [rsi + 16] - movdqu xmm3, [rsi + 18] - - HIGH_APPLY_FILTER_16 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret -%endif - -globalsym(vpx_highbd_filter_block1d4_h2_avg_sse2) -sym(vpx_highbd_filter_block1d4_h2_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - push rsi - push rdi - ; end prolog - - HIGH_GET_PARAM_4 -.loop: - movdqu xmm0, [rsi] ;load src - movdqa xmm1, xmm0 - psrldq xmm1, 2 - - HIGH_APPLY_FILTER_4 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - UNSHADOW_ARGS - pop rbp - ret - -%if VPX_ARCH_X86_64 -globalsym(vpx_highbd_filter_block1d8_h2_avg_sse2) -sym(vpx_highbd_filter_block1d8_h2_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 8 - push rsi - push rdi - ; end prolog - - HIGH_GET_PARAM -.loop: - movdqu xmm0, [rsi] ;load src - movdqu xmm1, [rsi + 2] - - HIGH_APPLY_FILTER_8 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_highbd_filter_block1d16_h2_avg_sse2) -sym(vpx_highbd_filter_block1d16_h2_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 7 - SAVE_XMM 9 - push rsi - push rdi - ; end prolog - - HIGH_GET_PARAM -.loop: - movdqu xmm0, [rsi] ;load src - movdqu xmm1, [rsi + 2] - movdqu xmm2, [rsi + 16] - movdqu xmm3, [rsi + 18] - - HIGH_APPLY_FILTER_16 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret -%endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_4t_intrin_sse2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_4t_intrin_sse2.c deleted file mode 100644 index 21a35ae3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_4t_intrin_sse2.c +++ /dev/null @@ -1,1161 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_dsp/x86/convolve.h" -#include "vpx_dsp/x86/convolve_sse2.h" -#include "vpx_ports/mem.h" - -#define CONV8_ROUNDING_BITS (7) -#define CONV8_ROUNDING_NUM (1 << (CONV8_ROUNDING_BITS - 1)) - -static void vpx_filter_block1d16_h4_sse2(const uint8_t *src_ptr, - ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - __m128i kernel_reg; // Kernel - __m128i kernel_reg_23, kernel_reg_45; // Segments of the kernel used - const __m128i reg_32 = _mm_set1_epi16(32); // Used for rounding - int h; - - __m128i src_reg, src_reg_shift_1, src_reg_shift_2, src_reg_shift_3; - __m128i dst_first, dst_second; - __m128i even, odd; - - // Start one pixel before as we need tap/2 - 1 = 1 sample from the past - src_ptr -= 1; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm_srai_epi16(kernel_reg, 1); - kernel_reg_23 = extract_quarter_2_epi16_sse2(&kernel_reg); - kernel_reg_45 = extract_quarter_3_epi16_sse2(&kernel_reg); - - for (h = height; h > 0; --h) { - // We will load multiple shifted versions of the row and shuffle them into - // 16-bit words of the form - // ... s[2] s[1] s[0] s[-1] - // ... s[4] s[3] s[2] s[1] - // Then we call multiply and add to get partial results - // s[2]k[3]+s[1]k[2] s[0]k[3]s[-1]k[2] - // s[4]k[5]+s[3]k[4] s[2]k[5]s[1]k[4] - // The two results are then added together for the first half of even - // output. - // Repeat multiple times to get the whole outoput - src_reg = _mm_loadu_si128((const __m128i *)src_ptr); - src_reg_shift_1 = _mm_srli_si128(src_reg, 1); - src_reg_shift_2 = _mm_srli_si128(src_reg, 2); - src_reg_shift_3 = _mm_srli_si128(src_reg, 3); - - // Output 6 4 2 0 - even = mm_madd_add_epi8_sse2(&src_reg, &src_reg_shift_2, &kernel_reg_23, - &kernel_reg_45); - - // Output 7 5 3 1 - odd = mm_madd_add_epi8_sse2(&src_reg_shift_1, &src_reg_shift_3, - &kernel_reg_23, &kernel_reg_45); - - // Combine to get the first half of the dst - dst_first = mm_zip_epi32_sse2(&even, &odd); - - // Do again to get the second half of dst - src_reg = _mm_loadu_si128((const __m128i *)(src_ptr + 8)); - src_reg_shift_1 = _mm_srli_si128(src_reg, 1); - src_reg_shift_2 = _mm_srli_si128(src_reg, 2); - src_reg_shift_3 = _mm_srli_si128(src_reg, 3); - - // Output 14 12 10 8 - even = mm_madd_add_epi8_sse2(&src_reg, &src_reg_shift_2, &kernel_reg_23, - &kernel_reg_45); - - // Output 15 13 11 9 - odd = mm_madd_add_epi8_sse2(&src_reg_shift_1, &src_reg_shift_3, - &kernel_reg_23, &kernel_reg_45); - - // Combine to get the second half of the dst - dst_second = mm_zip_epi32_sse2(&even, &odd); - - // Round each result - dst_first = mm_round_epi16_sse2(&dst_first, ®_32, 6); - dst_second = mm_round_epi16_sse2(&dst_second, ®_32, 6); - - // Finally combine to get the final dst - dst_first = _mm_packus_epi16(dst_first, dst_second); - _mm_store_si128((__m128i *)dst_ptr, dst_first); - - src_ptr += src_stride; - dst_ptr += dst_stride; - } -} - -/* The macro used to generate functions shifts the src_ptr up by 3 rows already - * */ - -static void vpx_filter_block1d16_v4_sse2(const uint8_t *src_ptr, - ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - // Register for source s[-1:3, :] - __m128i src_reg_m1, src_reg_0, src_reg_1, src_reg_2, src_reg_3; - // Interleaved rows of the source. lo is first half, hi second - __m128i src_reg_m10_lo, src_reg_m10_hi, src_reg_01_lo, src_reg_01_hi; - __m128i src_reg_12_lo, src_reg_12_hi, src_reg_23_lo, src_reg_23_hi; - // Half of half of the interleaved rows - __m128i src_reg_m10_lo_1, src_reg_m10_lo_2, src_reg_m10_hi_1, - src_reg_m10_hi_2; - __m128i src_reg_01_lo_1, src_reg_01_lo_2, src_reg_01_hi_1, src_reg_01_hi_2; - __m128i src_reg_12_lo_1, src_reg_12_lo_2, src_reg_12_hi_1, src_reg_12_hi_2; - __m128i src_reg_23_lo_1, src_reg_23_lo_2, src_reg_23_hi_1, src_reg_23_hi_2; - - __m128i kernel_reg; // Kernel - __m128i kernel_reg_23, kernel_reg_45; // Segments of the kernel used - - // Result after multiply and add - __m128i res_reg_m10_lo, res_reg_01_lo, res_reg_12_lo, res_reg_23_lo; - __m128i res_reg_m10_hi, res_reg_01_hi, res_reg_12_hi, res_reg_23_hi; - __m128i res_reg_m1012, res_reg_0123; - __m128i res_reg_m1012_lo, res_reg_0123_lo, res_reg_m1012_hi, res_reg_0123_hi; - - const __m128i reg_32 = _mm_set1_epi16(32); // Used for rounding - - // We will compute the result two rows at a time - const ptrdiff_t src_stride_unrolled = src_stride << 1; - const ptrdiff_t dst_stride_unrolled = dst_stride << 1; - int h; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm_srai_epi16(kernel_reg, 1); - kernel_reg_23 = extract_quarter_2_epi16_sse2(&kernel_reg); - kernel_reg_45 = extract_quarter_3_epi16_sse2(&kernel_reg); - - // We will load two rows of pixels as 8-bit words, rearrange them as 16-bit - // words, - // shuffle the data into the form - // ... s[0,1] s[-1,1] s[0,0] s[-1,0] - // ... s[0,7] s[-1,7] s[0,6] s[-1,6] - // ... s[0,9] s[-1,9] s[0,8] s[-1,8] - // ... s[0,13] s[-1,13] s[0,12] s[-1,12] - // so that we can call multiply and add with the kernel to get 32-bit words of - // the form - // ... s[0,1]k[3]+s[-1,1]k[2] s[0,0]k[3]+s[-1,0]k[2] - // Finally, we can add multiple rows together to get the desired output. - - // First shuffle the data - src_reg_m1 = _mm_loadu_si128((const __m128i *)src_ptr); - src_reg_0 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride)); - src_reg_m10_lo = _mm_unpacklo_epi8(src_reg_m1, src_reg_0); - src_reg_m10_hi = _mm_unpackhi_epi8(src_reg_m1, src_reg_0); - src_reg_m10_lo_1 = _mm_unpacklo_epi8(src_reg_m10_lo, _mm_setzero_si128()); - src_reg_m10_lo_2 = _mm_unpackhi_epi8(src_reg_m10_lo, _mm_setzero_si128()); - src_reg_m10_hi_1 = _mm_unpacklo_epi8(src_reg_m10_hi, _mm_setzero_si128()); - src_reg_m10_hi_2 = _mm_unpackhi_epi8(src_reg_m10_hi, _mm_setzero_si128()); - - // More shuffling - src_reg_1 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 2)); - src_reg_01_lo = _mm_unpacklo_epi8(src_reg_0, src_reg_1); - src_reg_01_hi = _mm_unpackhi_epi8(src_reg_0, src_reg_1); - src_reg_01_lo_1 = _mm_unpacklo_epi8(src_reg_01_lo, _mm_setzero_si128()); - src_reg_01_lo_2 = _mm_unpackhi_epi8(src_reg_01_lo, _mm_setzero_si128()); - src_reg_01_hi_1 = _mm_unpacklo_epi8(src_reg_01_hi, _mm_setzero_si128()); - src_reg_01_hi_2 = _mm_unpackhi_epi8(src_reg_01_hi, _mm_setzero_si128()); - - for (h = height; h > 1; h -= 2) { - src_reg_2 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 3)); - - src_reg_12_lo = _mm_unpacklo_epi8(src_reg_1, src_reg_2); - src_reg_12_hi = _mm_unpackhi_epi8(src_reg_1, src_reg_2); - - src_reg_3 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 4)); - - src_reg_23_lo = _mm_unpacklo_epi8(src_reg_2, src_reg_3); - src_reg_23_hi = _mm_unpackhi_epi8(src_reg_2, src_reg_3); - - // Partial output from first half - res_reg_m10_lo = mm_madd_packs_epi16_sse2( - &src_reg_m10_lo_1, &src_reg_m10_lo_2, &kernel_reg_23); - - res_reg_01_lo = mm_madd_packs_epi16_sse2(&src_reg_01_lo_1, &src_reg_01_lo_2, - &kernel_reg_23); - - src_reg_12_lo_1 = _mm_unpacklo_epi8(src_reg_12_lo, _mm_setzero_si128()); - src_reg_12_lo_2 = _mm_unpackhi_epi8(src_reg_12_lo, _mm_setzero_si128()); - res_reg_12_lo = mm_madd_packs_epi16_sse2(&src_reg_12_lo_1, &src_reg_12_lo_2, - &kernel_reg_45); - - src_reg_23_lo_1 = _mm_unpacklo_epi8(src_reg_23_lo, _mm_setzero_si128()); - src_reg_23_lo_2 = _mm_unpackhi_epi8(src_reg_23_lo, _mm_setzero_si128()); - res_reg_23_lo = mm_madd_packs_epi16_sse2(&src_reg_23_lo_1, &src_reg_23_lo_2, - &kernel_reg_45); - - // Add to get first half of the results - res_reg_m1012_lo = _mm_adds_epi16(res_reg_m10_lo, res_reg_12_lo); - res_reg_0123_lo = _mm_adds_epi16(res_reg_01_lo, res_reg_23_lo); - - // Now repeat everything again for the second half - // Partial output for second half - res_reg_m10_hi = mm_madd_packs_epi16_sse2( - &src_reg_m10_hi_1, &src_reg_m10_hi_2, &kernel_reg_23); - - res_reg_01_hi = mm_madd_packs_epi16_sse2(&src_reg_01_hi_1, &src_reg_01_hi_2, - &kernel_reg_23); - - src_reg_12_hi_1 = _mm_unpacklo_epi8(src_reg_12_hi, _mm_setzero_si128()); - src_reg_12_hi_2 = _mm_unpackhi_epi8(src_reg_12_hi, _mm_setzero_si128()); - res_reg_12_hi = mm_madd_packs_epi16_sse2(&src_reg_12_hi_1, &src_reg_12_hi_2, - &kernel_reg_45); - - src_reg_23_hi_1 = _mm_unpacklo_epi8(src_reg_23_hi, _mm_setzero_si128()); - src_reg_23_hi_2 = _mm_unpackhi_epi8(src_reg_23_hi, _mm_setzero_si128()); - res_reg_23_hi = mm_madd_packs_epi16_sse2(&src_reg_23_hi_1, &src_reg_23_hi_2, - &kernel_reg_45); - - // Second half of the results - res_reg_m1012_hi = _mm_adds_epi16(res_reg_m10_hi, res_reg_12_hi); - res_reg_0123_hi = _mm_adds_epi16(res_reg_01_hi, res_reg_23_hi); - - // Round the words - res_reg_m1012_lo = mm_round_epi16_sse2(&res_reg_m1012_lo, ®_32, 6); - res_reg_0123_lo = mm_round_epi16_sse2(&res_reg_0123_lo, ®_32, 6); - res_reg_m1012_hi = mm_round_epi16_sse2(&res_reg_m1012_hi, ®_32, 6); - res_reg_0123_hi = mm_round_epi16_sse2(&res_reg_0123_hi, ®_32, 6); - - // Combine to get the result - res_reg_m1012 = _mm_packus_epi16(res_reg_m1012_lo, res_reg_m1012_hi); - res_reg_0123 = _mm_packus_epi16(res_reg_0123_lo, res_reg_0123_hi); - - _mm_store_si128((__m128i *)dst_ptr, res_reg_m1012); - _mm_store_si128((__m128i *)(dst_ptr + dst_stride), res_reg_0123); - - // Update the source by two rows - src_ptr += src_stride_unrolled; - dst_ptr += dst_stride_unrolled; - - src_reg_m10_lo_1 = src_reg_12_lo_1; - src_reg_m10_lo_2 = src_reg_12_lo_2; - src_reg_m10_hi_1 = src_reg_12_hi_1; - src_reg_m10_hi_2 = src_reg_12_hi_2; - src_reg_01_lo_1 = src_reg_23_lo_1; - src_reg_01_lo_2 = src_reg_23_lo_2; - src_reg_01_hi_1 = src_reg_23_hi_1; - src_reg_01_hi_2 = src_reg_23_hi_2; - src_reg_1 = src_reg_3; - } -} - -static void vpx_filter_block1d8_h4_sse2(const uint8_t *src_ptr, - ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - __m128i kernel_reg; // Kernel - __m128i kernel_reg_23, kernel_reg_45; // Segments of the kernel used - const __m128i reg_32 = _mm_set1_epi16(32); // Used for rounding - int h; - - __m128i src_reg, src_reg_shift_1, src_reg_shift_2, src_reg_shift_3; - __m128i dst_first; - __m128i even, odd; - - // Start one pixel before as we need tap/2 - 1 = 1 sample from the past - src_ptr -= 1; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm_srai_epi16(kernel_reg, 1); - kernel_reg_23 = extract_quarter_2_epi16_sse2(&kernel_reg); - kernel_reg_45 = extract_quarter_3_epi16_sse2(&kernel_reg); - - for (h = height; h > 0; --h) { - // We will load multiple shifted versions of the row and shuffle them into - // 16-bit words of the form - // ... s[2] s[1] s[0] s[-1] - // ... s[4] s[3] s[2] s[1] - // Then we call multiply and add to get partial results - // s[2]k[3]+s[1]k[2] s[0]k[3]s[-1]k[2] - // s[4]k[5]+s[3]k[4] s[2]k[5]s[1]k[4] - // The two results are then added together to get the even output - src_reg = _mm_loadu_si128((const __m128i *)src_ptr); - src_reg_shift_1 = _mm_srli_si128(src_reg, 1); - src_reg_shift_2 = _mm_srli_si128(src_reg, 2); - src_reg_shift_3 = _mm_srli_si128(src_reg, 3); - - // Output 6 4 2 0 - even = mm_madd_add_epi8_sse2(&src_reg, &src_reg_shift_2, &kernel_reg_23, - &kernel_reg_45); - - // Output 7 5 3 1 - odd = mm_madd_add_epi8_sse2(&src_reg_shift_1, &src_reg_shift_3, - &kernel_reg_23, &kernel_reg_45); - - // Combine to get the first half of the dst - dst_first = mm_zip_epi32_sse2(&even, &odd); - dst_first = mm_round_epi16_sse2(&dst_first, ®_32, 6); - - // Saturate and convert to 8-bit words - dst_first = _mm_packus_epi16(dst_first, _mm_setzero_si128()); - - _mm_storel_epi64((__m128i *)dst_ptr, dst_first); - - src_ptr += src_stride; - dst_ptr += dst_stride; - } -} - -static void vpx_filter_block1d8_v4_sse2(const uint8_t *src_ptr, - ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - // Register for source s[-1:3, :] - __m128i src_reg_m1, src_reg_0, src_reg_1, src_reg_2, src_reg_3; - // Interleaved rows of the source. lo is first half, hi second - __m128i src_reg_m10_lo, src_reg_01_lo; - __m128i src_reg_12_lo, src_reg_23_lo; - // Half of half of the interleaved rows - __m128i src_reg_m10_lo_1, src_reg_m10_lo_2; - __m128i src_reg_01_lo_1, src_reg_01_lo_2; - __m128i src_reg_12_lo_1, src_reg_12_lo_2; - __m128i src_reg_23_lo_1, src_reg_23_lo_2; - - __m128i kernel_reg; // Kernel - __m128i kernel_reg_23, kernel_reg_45; // Segments of the kernel used - - // Result after multiply and add - __m128i res_reg_m10_lo, res_reg_01_lo, res_reg_12_lo, res_reg_23_lo; - __m128i res_reg_m1012, res_reg_0123; - __m128i res_reg_m1012_lo, res_reg_0123_lo; - - const __m128i reg_32 = _mm_set1_epi16(32); // Used for rounding - - // We will compute the result two rows at a time - const ptrdiff_t src_stride_unrolled = src_stride << 1; - const ptrdiff_t dst_stride_unrolled = dst_stride << 1; - int h; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm_srai_epi16(kernel_reg, 1); - kernel_reg_23 = extract_quarter_2_epi16_sse2(&kernel_reg); - kernel_reg_45 = extract_quarter_3_epi16_sse2(&kernel_reg); - - // We will load two rows of pixels as 8-bit words, rearrange them as 16-bit - // words, - // shuffle the data into the form - // ... s[0,1] s[-1,1] s[0,0] s[-1,0] - // ... s[0,7] s[-1,7] s[0,6] s[-1,6] - // ... s[0,9] s[-1,9] s[0,8] s[-1,8] - // ... s[0,13] s[-1,13] s[0,12] s[-1,12] - // so that we can call multiply and add with the kernel to get 32-bit words of - // the form - // ... s[0,1]k[3]+s[-1,1]k[2] s[0,0]k[3]+s[-1,0]k[2] - // Finally, we can add multiple rows together to get the desired output. - - // First shuffle the data - src_reg_m1 = _mm_loadu_si128((const __m128i *)src_ptr); - src_reg_0 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride)); - src_reg_m10_lo = _mm_unpacklo_epi8(src_reg_m1, src_reg_0); - src_reg_m10_lo_1 = _mm_unpacklo_epi8(src_reg_m10_lo, _mm_setzero_si128()); - src_reg_m10_lo_2 = _mm_unpackhi_epi8(src_reg_m10_lo, _mm_setzero_si128()); - - // More shuffling - src_reg_1 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 2)); - src_reg_01_lo = _mm_unpacklo_epi8(src_reg_0, src_reg_1); - src_reg_01_lo_1 = _mm_unpacklo_epi8(src_reg_01_lo, _mm_setzero_si128()); - src_reg_01_lo_2 = _mm_unpackhi_epi8(src_reg_01_lo, _mm_setzero_si128()); - - for (h = height; h > 1; h -= 2) { - src_reg_2 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 3)); - - src_reg_12_lo = _mm_unpacklo_epi8(src_reg_1, src_reg_2); - - src_reg_3 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 4)); - - src_reg_23_lo = _mm_unpacklo_epi8(src_reg_2, src_reg_3); - - // Partial output - res_reg_m10_lo = mm_madd_packs_epi16_sse2( - &src_reg_m10_lo_1, &src_reg_m10_lo_2, &kernel_reg_23); - - res_reg_01_lo = mm_madd_packs_epi16_sse2(&src_reg_01_lo_1, &src_reg_01_lo_2, - &kernel_reg_23); - - src_reg_12_lo_1 = _mm_unpacklo_epi8(src_reg_12_lo, _mm_setzero_si128()); - src_reg_12_lo_2 = _mm_unpackhi_epi8(src_reg_12_lo, _mm_setzero_si128()); - res_reg_12_lo = mm_madd_packs_epi16_sse2(&src_reg_12_lo_1, &src_reg_12_lo_2, - &kernel_reg_45); - - src_reg_23_lo_1 = _mm_unpacklo_epi8(src_reg_23_lo, _mm_setzero_si128()); - src_reg_23_lo_2 = _mm_unpackhi_epi8(src_reg_23_lo, _mm_setzero_si128()); - res_reg_23_lo = mm_madd_packs_epi16_sse2(&src_reg_23_lo_1, &src_reg_23_lo_2, - &kernel_reg_45); - - // Add to get results - res_reg_m1012_lo = _mm_adds_epi16(res_reg_m10_lo, res_reg_12_lo); - res_reg_0123_lo = _mm_adds_epi16(res_reg_01_lo, res_reg_23_lo); - - // Round the words - res_reg_m1012_lo = mm_round_epi16_sse2(&res_reg_m1012_lo, ®_32, 6); - res_reg_0123_lo = mm_round_epi16_sse2(&res_reg_0123_lo, ®_32, 6); - - // Convert to 8-bit words - res_reg_m1012 = _mm_packus_epi16(res_reg_m1012_lo, _mm_setzero_si128()); - res_reg_0123 = _mm_packus_epi16(res_reg_0123_lo, _mm_setzero_si128()); - - // Save only half of the register (8 words) - _mm_storel_epi64((__m128i *)dst_ptr, res_reg_m1012); - _mm_storel_epi64((__m128i *)(dst_ptr + dst_stride), res_reg_0123); - - // Update the source by two rows - src_ptr += src_stride_unrolled; - dst_ptr += dst_stride_unrolled; - - src_reg_m10_lo_1 = src_reg_12_lo_1; - src_reg_m10_lo_2 = src_reg_12_lo_2; - src_reg_01_lo_1 = src_reg_23_lo_1; - src_reg_01_lo_2 = src_reg_23_lo_2; - src_reg_1 = src_reg_3; - } -} - -static void vpx_filter_block1d4_h4_sse2(const uint8_t *src_ptr, - ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - __m128i kernel_reg; // Kernel - __m128i kernel_reg_23, kernel_reg_45; // Segments of the kernel used - const __m128i reg_32 = _mm_set1_epi16(32); // Used for rounding - int h; - - __m128i src_reg, src_reg_shift_1, src_reg_shift_2, src_reg_shift_3; - __m128i dst_first; - __m128i tmp_0, tmp_1; - - // Start one pixel before as we need tap/2 - 1 = 1 sample from the past - src_ptr -= 1; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm_srai_epi16(kernel_reg, 1); - kernel_reg_23 = extract_quarter_2_epi16_sse2(&kernel_reg); - kernel_reg_45 = extract_quarter_3_epi16_sse2(&kernel_reg); - - for (h = height; h > 0; --h) { - // We will load multiple shifted versions of the row and shuffle them into - // 16-bit words of the form - // ... s[1] s[0] s[0] s[-1] - // ... s[3] s[2] s[2] s[1] - // Then we call multiply and add to get partial results - // s[1]k[3]+s[0]k[2] s[0]k[3]s[-1]k[2] - // s[3]k[5]+s[2]k[4] s[2]k[5]s[1]k[4] - // The two results are then added together to get the output - src_reg = _mm_loadu_si128((const __m128i *)src_ptr); - src_reg_shift_1 = _mm_srli_si128(src_reg, 1); - src_reg_shift_2 = _mm_srli_si128(src_reg, 2); - src_reg_shift_3 = _mm_srli_si128(src_reg, 3); - - // Convert to 16-bit words - src_reg = _mm_unpacklo_epi8(src_reg, _mm_setzero_si128()); - src_reg_shift_1 = _mm_unpacklo_epi8(src_reg_shift_1, _mm_setzero_si128()); - src_reg_shift_2 = _mm_unpacklo_epi8(src_reg_shift_2, _mm_setzero_si128()); - src_reg_shift_3 = _mm_unpacklo_epi8(src_reg_shift_3, _mm_setzero_si128()); - - // Shuffle into the right format - tmp_0 = _mm_unpacklo_epi32(src_reg, src_reg_shift_1); - tmp_1 = _mm_unpacklo_epi32(src_reg_shift_2, src_reg_shift_3); - - // Partial output - tmp_0 = _mm_madd_epi16(tmp_0, kernel_reg_23); - tmp_1 = _mm_madd_epi16(tmp_1, kernel_reg_45); - - // Output - dst_first = _mm_add_epi32(tmp_0, tmp_1); - dst_first = _mm_packs_epi32(dst_first, _mm_setzero_si128()); - - dst_first = mm_round_epi16_sse2(&dst_first, ®_32, 6); - - // Saturate and convert to 8-bit words - dst_first = _mm_packus_epi16(dst_first, _mm_setzero_si128()); - - *((int *)(dst_ptr)) = _mm_cvtsi128_si32(dst_first); - - src_ptr += src_stride; - dst_ptr += dst_stride; - } -} - -static void vpx_filter_block1d4_v4_sse2(const uint8_t *src_ptr, - ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - // Register for source s[-1:3, :] - __m128i src_reg_m1, src_reg_0, src_reg_1, src_reg_2, src_reg_3; - // Interleaved rows of the source. lo is first half, hi second - __m128i src_reg_m10_lo, src_reg_01_lo; - __m128i src_reg_12_lo, src_reg_23_lo; - // Half of half of the interleaved rows - __m128i src_reg_m10_lo_1; - __m128i src_reg_01_lo_1; - __m128i src_reg_12_lo_1; - __m128i src_reg_23_lo_1; - - __m128i kernel_reg; // Kernel - __m128i kernel_reg_23, kernel_reg_45; // Segments of the kernel used - - // Result after multiply and add - __m128i res_reg_m10_lo, res_reg_01_lo, res_reg_12_lo, res_reg_23_lo; - __m128i res_reg_m1012, res_reg_0123; - __m128i res_reg_m1012_lo, res_reg_0123_lo; - - const __m128i reg_32 = _mm_set1_epi16(32); // Used for rounding - const __m128i reg_zero = _mm_setzero_si128(); - - // We will compute the result two rows at a time - const ptrdiff_t src_stride_unrolled = src_stride << 1; - const ptrdiff_t dst_stride_unrolled = dst_stride << 1; - int h; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm_srai_epi16(kernel_reg, 1); - kernel_reg_23 = extract_quarter_2_epi16_sse2(&kernel_reg); - kernel_reg_45 = extract_quarter_3_epi16_sse2(&kernel_reg); - - // We will load two rows of pixels as 8-bit words, rearrange them as 16-bit - // words, - // shuffle the data into the form - // ... s[0,1] s[-1,1] s[0,0] s[-1,0] - // ... s[0,7] s[-1,7] s[0,6] s[-1,6] - // ... s[0,9] s[-1,9] s[0,8] s[-1,8] - // ... s[0,13] s[-1,13] s[0,12] s[-1,12] - // so that we can call multiply and add with the kernel to get 32-bit words of - // the form - // ... s[0,1]k[3]+s[-1,1]k[2] s[0,0]k[3]+s[-1,0]k[2] - // Finally, we can add multiple rows together to get the desired output. - - // First shuffle the data - src_reg_m1 = _mm_loadu_si128((const __m128i *)src_ptr); - src_reg_0 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride)); - src_reg_m10_lo = _mm_unpacklo_epi8(src_reg_m1, src_reg_0); - src_reg_m10_lo_1 = _mm_unpacklo_epi8(src_reg_m10_lo, _mm_setzero_si128()); - - // More shuffling - src_reg_1 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 2)); - src_reg_01_lo = _mm_unpacklo_epi8(src_reg_0, src_reg_1); - src_reg_01_lo_1 = _mm_unpacklo_epi8(src_reg_01_lo, _mm_setzero_si128()); - - for (h = height; h > 1; h -= 2) { - src_reg_2 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 3)); - - src_reg_12_lo = _mm_unpacklo_epi8(src_reg_1, src_reg_2); - - src_reg_3 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 4)); - - src_reg_23_lo = _mm_unpacklo_epi8(src_reg_2, src_reg_3); - - // Partial output - res_reg_m10_lo = - mm_madd_packs_epi16_sse2(&src_reg_m10_lo_1, ®_zero, &kernel_reg_23); - - res_reg_01_lo = - mm_madd_packs_epi16_sse2(&src_reg_01_lo_1, ®_zero, &kernel_reg_23); - - src_reg_12_lo_1 = _mm_unpacklo_epi8(src_reg_12_lo, _mm_setzero_si128()); - res_reg_12_lo = - mm_madd_packs_epi16_sse2(&src_reg_12_lo_1, ®_zero, &kernel_reg_45); - - src_reg_23_lo_1 = _mm_unpacklo_epi8(src_reg_23_lo, _mm_setzero_si128()); - res_reg_23_lo = - mm_madd_packs_epi16_sse2(&src_reg_23_lo_1, ®_zero, &kernel_reg_45); - - // Add to get results - res_reg_m1012_lo = _mm_adds_epi16(res_reg_m10_lo, res_reg_12_lo); - res_reg_0123_lo = _mm_adds_epi16(res_reg_01_lo, res_reg_23_lo); - - // Round the words - res_reg_m1012_lo = mm_round_epi16_sse2(&res_reg_m1012_lo, ®_32, 6); - res_reg_0123_lo = mm_round_epi16_sse2(&res_reg_0123_lo, ®_32, 6); - - // Convert to 8-bit words - res_reg_m1012 = _mm_packus_epi16(res_reg_m1012_lo, reg_zero); - res_reg_0123 = _mm_packus_epi16(res_reg_0123_lo, reg_zero); - - // Save only half of the register (8 words) - *((int *)(dst_ptr)) = _mm_cvtsi128_si32(res_reg_m1012); - *((int *)(dst_ptr + dst_stride)) = _mm_cvtsi128_si32(res_reg_0123); - - // Update the source by two rows - src_ptr += src_stride_unrolled; - dst_ptr += dst_stride_unrolled; - - src_reg_m10_lo_1 = src_reg_12_lo_1; - src_reg_01_lo_1 = src_reg_23_lo_1; - src_reg_1 = src_reg_3; - } -} - -#if CONFIG_VP9_HIGHBITDEPTH && VPX_ARCH_X86_64 -static void vpx_highbd_filter_block1d4_h4_sse2( - const uint16_t *src_ptr, ptrdiff_t src_stride, uint16_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, const int16_t *kernel, int bd) { - // We will load multiple shifted versions of the row and shuffle them into - // 16-bit words of the form - // ... s[2] s[1] s[0] s[-1] - // ... s[4] s[3] s[2] s[1] - // Then we call multiply and add to get partial results - // s[2]k[3]+s[1]k[2] s[0]k[3]s[-1]k[2] - // s[4]k[5]+s[3]k[4] s[2]k[5]s[1]k[4] - // The two results are then added together to get the even output - - __m128i src_reg, src_reg_shift_1, src_reg_shift_2, src_reg_shift_3; - __m128i res_reg; - __m128i even, odd; - - __m128i kernel_reg; // Kernel - __m128i kernel_reg_23, kernel_reg_45; // Segments of the kernel used - const __m128i reg_round = - _mm_set1_epi32(CONV8_ROUNDING_NUM); // Used for rounding - const __m128i reg_max = _mm_set1_epi16((1 << bd) - 1); - const __m128i reg_zero = _mm_setzero_si128(); - int h; - - // Start one pixel before as we need tap/2 - 1 = 1 sample from the past - src_ptr -= 1; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg_23 = extract_quarter_2_epi16_sse2(&kernel_reg); - kernel_reg_45 = extract_quarter_3_epi16_sse2(&kernel_reg); - - for (h = height; h > 0; --h) { - src_reg = _mm_loadu_si128((const __m128i *)src_ptr); - src_reg_shift_1 = _mm_srli_si128(src_reg, 2); - src_reg_shift_2 = _mm_srli_si128(src_reg, 4); - src_reg_shift_3 = _mm_srli_si128(src_reg, 6); - - // Output 2 0 - even = mm_madd_add_epi16_sse2(&src_reg, &src_reg_shift_2, &kernel_reg_23, - &kernel_reg_45); - - // Output 3 1 - odd = mm_madd_add_epi16_sse2(&src_reg_shift_1, &src_reg_shift_3, - &kernel_reg_23, &kernel_reg_45); - - // Combine to get the first half of the dst - res_reg = _mm_unpacklo_epi32(even, odd); - res_reg = mm_round_epi32_sse2(&res_reg, ®_round, CONV8_ROUNDING_BITS); - res_reg = _mm_packs_epi32(res_reg, reg_zero); - - // Saturate the result and save - res_reg = _mm_min_epi16(res_reg, reg_max); - res_reg = _mm_max_epi16(res_reg, reg_zero); - _mm_storel_epi64((__m128i *)dst_ptr, res_reg); - - src_ptr += src_stride; - dst_ptr += dst_stride; - } -} - -static void vpx_highbd_filter_block1d4_v4_sse2( - const uint16_t *src_ptr, ptrdiff_t src_stride, uint16_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, const int16_t *kernel, int bd) { - // We will load two rows of pixels as 16-bit words, and shuffle them into the - // form - // ... s[0,1] s[-1,1] s[0,0] s[-1,0] - // ... s[0,7] s[-1,7] s[0,6] s[-1,6] - // ... s[0,9] s[-1,9] s[0,8] s[-1,8] - // ... s[0,13] s[-1,13] s[0,12] s[-1,12] - // so that we can call multiply and add with the kernel to get 32-bit words of - // the form - // ... s[0,1]k[3]+s[-1,1]k[2] s[0,0]k[3]+s[-1,0]k[2] - // Finally, we can add multiple rows together to get the desired output. - - // Register for source s[-1:3, :] - __m128i src_reg_m1, src_reg_0, src_reg_1, src_reg_2, src_reg_3; - // Interleaved rows of the source. lo is first half, hi second - __m128i src_reg_m10, src_reg_01; - __m128i src_reg_12, src_reg_23; - - __m128i kernel_reg; // Kernel - __m128i kernel_reg_23, kernel_reg_45; // Segments of the kernel used - - // Result after multiply and add - __m128i res_reg_m10, res_reg_01, res_reg_12, res_reg_23; - __m128i res_reg_m1012, res_reg_0123; - - const __m128i reg_round = - _mm_set1_epi32(CONV8_ROUNDING_NUM); // Used for rounding - const __m128i reg_max = _mm_set1_epi16((1 << bd) - 1); - const __m128i reg_zero = _mm_setzero_si128(); - - // We will compute the result two rows at a time - const ptrdiff_t src_stride_unrolled = src_stride << 1; - const ptrdiff_t dst_stride_unrolled = dst_stride << 1; - int h; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg_23 = extract_quarter_2_epi16_sse2(&kernel_reg); - kernel_reg_45 = extract_quarter_3_epi16_sse2(&kernel_reg); - - // First shuffle the data - src_reg_m1 = _mm_loadl_epi64((const __m128i *)src_ptr); - src_reg_0 = _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride)); - src_reg_m10 = _mm_unpacklo_epi16(src_reg_m1, src_reg_0); - - // More shuffling - src_reg_1 = _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride * 2)); - src_reg_01 = _mm_unpacklo_epi16(src_reg_0, src_reg_1); - - for (h = height; h > 1; h -= 2) { - src_reg_2 = _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride * 3)); - - src_reg_12 = _mm_unpacklo_epi16(src_reg_1, src_reg_2); - - src_reg_3 = _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride * 4)); - - src_reg_23 = _mm_unpacklo_epi16(src_reg_2, src_reg_3); - - // Partial output - res_reg_m10 = _mm_madd_epi16(src_reg_m10, kernel_reg_23); - res_reg_01 = _mm_madd_epi16(src_reg_01, kernel_reg_23); - res_reg_12 = _mm_madd_epi16(src_reg_12, kernel_reg_45); - res_reg_23 = _mm_madd_epi16(src_reg_23, kernel_reg_45); - - // Add to get results - res_reg_m1012 = _mm_add_epi32(res_reg_m10, res_reg_12); - res_reg_0123 = _mm_add_epi32(res_reg_01, res_reg_23); - - // Round the words - res_reg_m1012 = - mm_round_epi32_sse2(&res_reg_m1012, ®_round, CONV8_ROUNDING_BITS); - res_reg_0123 = - mm_round_epi32_sse2(&res_reg_0123, ®_round, CONV8_ROUNDING_BITS); - - res_reg_m1012 = _mm_packs_epi32(res_reg_m1012, reg_zero); - res_reg_0123 = _mm_packs_epi32(res_reg_0123, reg_zero); - - // Saturate according to bit depth - res_reg_m1012 = _mm_min_epi16(res_reg_m1012, reg_max); - res_reg_0123 = _mm_min_epi16(res_reg_0123, reg_max); - res_reg_m1012 = _mm_max_epi16(res_reg_m1012, reg_zero); - res_reg_0123 = _mm_max_epi16(res_reg_0123, reg_zero); - - // Save only half of the register (8 words) - _mm_storel_epi64((__m128i *)dst_ptr, res_reg_m1012); - _mm_storel_epi64((__m128i *)(dst_ptr + dst_stride), res_reg_0123); - - // Update the source by two rows - src_ptr += src_stride_unrolled; - dst_ptr += dst_stride_unrolled; - - src_reg_m10 = src_reg_12; - src_reg_01 = src_reg_23; - src_reg_1 = src_reg_3; - } -} - -static void vpx_highbd_filter_block1d8_h4_sse2( - const uint16_t *src_ptr, ptrdiff_t src_stride, uint16_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, const int16_t *kernel, int bd) { - // We will load multiple shifted versions of the row and shuffle them into - // 16-bit words of the form - // ... s[2] s[1] s[0] s[-1] - // ... s[4] s[3] s[2] s[1] - // Then we call multiply and add to get partial results - // s[2]k[3]+s[1]k[2] s[0]k[3]s[-1]k[2] - // s[4]k[5]+s[3]k[4] s[2]k[5]s[1]k[4] - // The two results are then added together for the first half of even - // output. - // Repeat multiple times to get the whole outoput - - __m128i src_reg, src_reg_next, src_reg_shift_1, src_reg_shift_2, - src_reg_shift_3; - __m128i res_reg; - __m128i even, odd; - __m128i tmp_0, tmp_1; - - __m128i kernel_reg; // Kernel - __m128i kernel_reg_23, kernel_reg_45; // Segments of the kernel used - const __m128i reg_round = - _mm_set1_epi32(CONV8_ROUNDING_NUM); // Used for rounding - const __m128i reg_max = _mm_set1_epi16((1 << bd) - 1); - const __m128i reg_zero = _mm_setzero_si128(); - int h; - - // Start one pixel before as we need tap/2 - 1 = 1 sample from the past - src_ptr -= 1; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg_23 = extract_quarter_2_epi16_sse2(&kernel_reg); - kernel_reg_45 = extract_quarter_3_epi16_sse2(&kernel_reg); - - for (h = height; h > 0; --h) { - // We will put first half in the first half of the reg, and second half in - // second half - src_reg = _mm_loadu_si128((const __m128i *)src_ptr); - src_reg_next = _mm_loadu_si128((const __m128i *)(src_ptr + 5)); - - // Output 6 4 2 0 - tmp_0 = _mm_srli_si128(src_reg, 4); - tmp_1 = _mm_srli_si128(src_reg_next, 2); - src_reg_shift_2 = _mm_unpacklo_epi64(tmp_0, tmp_1); - even = mm_madd_add_epi16_sse2(&src_reg, &src_reg_shift_2, &kernel_reg_23, - &kernel_reg_45); - - // Output 7 5 3 1 - tmp_0 = _mm_srli_si128(src_reg, 2); - tmp_1 = src_reg_next; - src_reg_shift_1 = _mm_unpacklo_epi64(tmp_0, tmp_1); - - tmp_0 = _mm_srli_si128(src_reg, 6); - tmp_1 = _mm_srli_si128(src_reg_next, 4); - src_reg_shift_3 = _mm_unpacklo_epi64(tmp_0, tmp_1); - - odd = mm_madd_add_epi16_sse2(&src_reg_shift_1, &src_reg_shift_3, - &kernel_reg_23, &kernel_reg_45); - - // Combine to get the first half of the dst - even = mm_round_epi32_sse2(&even, ®_round, CONV8_ROUNDING_BITS); - odd = mm_round_epi32_sse2(&odd, ®_round, CONV8_ROUNDING_BITS); - res_reg = mm_zip_epi32_sse2(&even, &odd); - - // Saturate the result and save - res_reg = _mm_min_epi16(res_reg, reg_max); - res_reg = _mm_max_epi16(res_reg, reg_zero); - - _mm_store_si128((__m128i *)dst_ptr, res_reg); - - src_ptr += src_stride; - dst_ptr += dst_stride; - } -} - -static void vpx_highbd_filter_block1d8_v4_sse2( - const uint16_t *src_ptr, ptrdiff_t src_stride, uint16_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, const int16_t *kernel, int bd) { - // We will load two rows of pixels as 16-bit words, and shuffle them into the - // form - // ... s[0,1] s[-1,1] s[0,0] s[-1,0] - // ... s[0,7] s[-1,7] s[0,6] s[-1,6] - // ... s[0,9] s[-1,9] s[0,8] s[-1,8] - // ... s[0,13] s[-1,13] s[0,12] s[-1,12] - // so that we can call multiply and add with the kernel to get 32-bit words of - // the form - // ... s[0,1]k[3]+s[-1,1]k[2] s[0,0]k[3]+s[-1,0]k[2] - // Finally, we can add multiple rows together to get the desired output. - - // Register for source s[-1:3, :] - __m128i src_reg_m1, src_reg_0, src_reg_1, src_reg_2, src_reg_3; - // Interleaved rows of the source. lo is first half, hi second - __m128i src_reg_m10_lo, src_reg_01_lo, src_reg_m10_hi, src_reg_01_hi; - __m128i src_reg_12_lo, src_reg_23_lo, src_reg_12_hi, src_reg_23_hi; - - // Result after multiply and add - __m128i res_reg_m10_lo, res_reg_01_lo, res_reg_12_lo, res_reg_23_lo; - __m128i res_reg_m10_hi, res_reg_01_hi, res_reg_12_hi, res_reg_23_hi; - __m128i res_reg_m1012, res_reg_0123; - __m128i res_reg_m1012_lo, res_reg_0123_lo; - __m128i res_reg_m1012_hi, res_reg_0123_hi; - - __m128i kernel_reg; // Kernel - __m128i kernel_reg_23, kernel_reg_45; // Segments of the kernel used - - const __m128i reg_round = - _mm_set1_epi32(CONV8_ROUNDING_NUM); // Used for rounding - const __m128i reg_max = _mm_set1_epi16((1 << bd) - 1); - const __m128i reg_zero = _mm_setzero_si128(); - - // We will compute the result two rows at a time - const ptrdiff_t src_stride_unrolled = src_stride << 1; - const ptrdiff_t dst_stride_unrolled = dst_stride << 1; - int h; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg_23 = extract_quarter_2_epi16_sse2(&kernel_reg); - kernel_reg_45 = extract_quarter_3_epi16_sse2(&kernel_reg); - - // First shuffle the data - src_reg_m1 = _mm_loadu_si128((const __m128i *)src_ptr); - src_reg_0 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride)); - src_reg_m10_lo = _mm_unpacklo_epi16(src_reg_m1, src_reg_0); - src_reg_m10_hi = _mm_unpackhi_epi16(src_reg_m1, src_reg_0); - - // More shuffling - src_reg_1 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 2)); - src_reg_01_lo = _mm_unpacklo_epi16(src_reg_0, src_reg_1); - src_reg_01_hi = _mm_unpackhi_epi16(src_reg_0, src_reg_1); - - for (h = height; h > 1; h -= 2) { - src_reg_2 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 3)); - - src_reg_12_lo = _mm_unpacklo_epi16(src_reg_1, src_reg_2); - src_reg_12_hi = _mm_unpackhi_epi16(src_reg_1, src_reg_2); - - src_reg_3 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 4)); - - src_reg_23_lo = _mm_unpacklo_epi16(src_reg_2, src_reg_3); - src_reg_23_hi = _mm_unpackhi_epi16(src_reg_2, src_reg_3); - - // Partial output for first half - res_reg_m10_lo = _mm_madd_epi16(src_reg_m10_lo, kernel_reg_23); - res_reg_01_lo = _mm_madd_epi16(src_reg_01_lo, kernel_reg_23); - res_reg_12_lo = _mm_madd_epi16(src_reg_12_lo, kernel_reg_45); - res_reg_23_lo = _mm_madd_epi16(src_reg_23_lo, kernel_reg_45); - - // Add to get results - res_reg_m1012_lo = _mm_add_epi32(res_reg_m10_lo, res_reg_12_lo); - res_reg_0123_lo = _mm_add_epi32(res_reg_01_lo, res_reg_23_lo); - - // Round the words - res_reg_m1012_lo = - mm_round_epi32_sse2(&res_reg_m1012_lo, ®_round, CONV8_ROUNDING_BITS); - res_reg_0123_lo = - mm_round_epi32_sse2(&res_reg_0123_lo, ®_round, CONV8_ROUNDING_BITS); - - // Partial output for first half - res_reg_m10_hi = _mm_madd_epi16(src_reg_m10_hi, kernel_reg_23); - res_reg_01_hi = _mm_madd_epi16(src_reg_01_hi, kernel_reg_23); - res_reg_12_hi = _mm_madd_epi16(src_reg_12_hi, kernel_reg_45); - res_reg_23_hi = _mm_madd_epi16(src_reg_23_hi, kernel_reg_45); - - // Add to get results - res_reg_m1012_hi = _mm_add_epi32(res_reg_m10_hi, res_reg_12_hi); - res_reg_0123_hi = _mm_add_epi32(res_reg_01_hi, res_reg_23_hi); - - // Round the words - res_reg_m1012_hi = - mm_round_epi32_sse2(&res_reg_m1012_hi, ®_round, CONV8_ROUNDING_BITS); - res_reg_0123_hi = - mm_round_epi32_sse2(&res_reg_0123_hi, ®_round, CONV8_ROUNDING_BITS); - - // Combine the two halfs - res_reg_m1012 = _mm_packs_epi32(res_reg_m1012_lo, res_reg_m1012_hi); - res_reg_0123 = _mm_packs_epi32(res_reg_0123_lo, res_reg_0123_hi); - - // Saturate according to bit depth - res_reg_m1012 = _mm_min_epi16(res_reg_m1012, reg_max); - res_reg_0123 = _mm_min_epi16(res_reg_0123, reg_max); - res_reg_m1012 = _mm_max_epi16(res_reg_m1012, reg_zero); - res_reg_0123 = _mm_max_epi16(res_reg_0123, reg_zero); - - // Save only half of the register (8 words) - _mm_store_si128((__m128i *)dst_ptr, res_reg_m1012); - _mm_store_si128((__m128i *)(dst_ptr + dst_stride), res_reg_0123); - - // Update the source by two rows - src_ptr += src_stride_unrolled; - dst_ptr += dst_stride_unrolled; - - src_reg_m10_lo = src_reg_12_lo; - src_reg_m10_hi = src_reg_12_hi; - src_reg_01_lo = src_reg_23_lo; - src_reg_01_hi = src_reg_23_hi; - src_reg_1 = src_reg_3; - } -} - -static void vpx_highbd_filter_block1d16_h4_sse2( - const uint16_t *src_ptr, ptrdiff_t src_stride, uint16_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, const int16_t *kernel, int bd) { - vpx_highbd_filter_block1d8_h4_sse2(src_ptr, src_stride, dst_ptr, dst_stride, - height, kernel, bd); - vpx_highbd_filter_block1d8_h4_sse2(src_ptr + 8, src_stride, dst_ptr + 8, - dst_stride, height, kernel, bd); -} - -static void vpx_highbd_filter_block1d16_v4_sse2( - const uint16_t *src_ptr, ptrdiff_t src_stride, uint16_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, const int16_t *kernel, int bd) { - vpx_highbd_filter_block1d8_v4_sse2(src_ptr, src_stride, dst_ptr, dst_stride, - height, kernel, bd); - vpx_highbd_filter_block1d8_v4_sse2(src_ptr + 8, src_stride, dst_ptr + 8, - dst_stride, height, kernel, bd); -} -#endif // CONFIG_VP9_HIGHBITDEPTH && VPX_ARCH_X86_64 - -// From vpx_subpixel_8t_sse2.asm. -filter8_1dfunction vpx_filter_block1d16_v8_sse2; -filter8_1dfunction vpx_filter_block1d16_h8_sse2; -filter8_1dfunction vpx_filter_block1d8_v8_sse2; -filter8_1dfunction vpx_filter_block1d8_h8_sse2; -filter8_1dfunction vpx_filter_block1d4_v8_sse2; -filter8_1dfunction vpx_filter_block1d4_h8_sse2; -filter8_1dfunction vpx_filter_block1d16_v8_avg_sse2; -filter8_1dfunction vpx_filter_block1d16_h8_avg_sse2; -filter8_1dfunction vpx_filter_block1d8_v8_avg_sse2; -filter8_1dfunction vpx_filter_block1d8_h8_avg_sse2; -filter8_1dfunction vpx_filter_block1d4_v8_avg_sse2; -filter8_1dfunction vpx_filter_block1d4_h8_avg_sse2; - -// Use the [vh]8 version because there is no [vh]4 implementation. -#define vpx_filter_block1d16_v4_avg_sse2 vpx_filter_block1d16_v8_avg_sse2 -#define vpx_filter_block1d16_h4_avg_sse2 vpx_filter_block1d16_h8_avg_sse2 -#define vpx_filter_block1d8_v4_avg_sse2 vpx_filter_block1d8_v8_avg_sse2 -#define vpx_filter_block1d8_h4_avg_sse2 vpx_filter_block1d8_h8_avg_sse2 -#define vpx_filter_block1d4_v4_avg_sse2 vpx_filter_block1d4_v8_avg_sse2 -#define vpx_filter_block1d4_h4_avg_sse2 vpx_filter_block1d4_h8_avg_sse2 - -// From vpx_dsp/x86/vpx_subpixel_bilinear_sse2.asm. -filter8_1dfunction vpx_filter_block1d16_v2_sse2; -filter8_1dfunction vpx_filter_block1d16_h2_sse2; -filter8_1dfunction vpx_filter_block1d8_v2_sse2; -filter8_1dfunction vpx_filter_block1d8_h2_sse2; -filter8_1dfunction vpx_filter_block1d4_v2_sse2; -filter8_1dfunction vpx_filter_block1d4_h2_sse2; -filter8_1dfunction vpx_filter_block1d16_v2_avg_sse2; -filter8_1dfunction vpx_filter_block1d16_h2_avg_sse2; -filter8_1dfunction vpx_filter_block1d8_v2_avg_sse2; -filter8_1dfunction vpx_filter_block1d8_h2_avg_sse2; -filter8_1dfunction vpx_filter_block1d4_v2_avg_sse2; -filter8_1dfunction vpx_filter_block1d4_h2_avg_sse2; - -// void vpx_convolve8_horiz_sse2(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, int y_step_q4, -// int w, int h); -// void vpx_convolve8_vert_sse2(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, int y_step_q4, -// int w, int h); -// void vpx_convolve8_avg_horiz_sse2(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, -// int y_step_q4, int w, int h); -// void vpx_convolve8_avg_vert_sse2(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, int y_step_q4, -// int w, int h); -FUN_CONV_1D(horiz, x0_q4, x_step_q4, h, src, , sse2, 0) -FUN_CONV_1D(vert, y0_q4, y_step_q4, v, src - (num_taps / 2 - 1) * src_stride, , - sse2, 0) -FUN_CONV_1D(avg_horiz, x0_q4, x_step_q4, h, src, avg_, sse2, 1) -FUN_CONV_1D(avg_vert, y0_q4, y_step_q4, v, - src - (num_taps / 2 - 1) * src_stride, avg_, sse2, 1) - -// void vpx_convolve8_sse2(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, int y_step_q4, -// int w, int h); -// void vpx_convolve8_avg_sse2(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, int y_step_q4, -// int w, int h); -FUN_CONV_2D(, sse2, 0) -FUN_CONV_2D(avg_, sse2, 1) - -#if CONFIG_VP9_HIGHBITDEPTH && VPX_ARCH_X86_64 -// From vpx_dsp/x86/vpx_high_subpixel_8t_sse2.asm. -highbd_filter8_1dfunction vpx_highbd_filter_block1d16_v8_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d16_h8_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d8_v8_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d8_h8_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d4_v8_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d4_h8_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d16_v8_avg_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d16_h8_avg_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d8_v8_avg_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d8_h8_avg_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d4_v8_avg_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d4_h8_avg_sse2; - -// Use the [vh]8 version because there is no [vh]4 implementation. -#define vpx_highbd_filter_block1d16_v4_avg_sse2 \ - vpx_highbd_filter_block1d16_v8_avg_sse2 -#define vpx_highbd_filter_block1d16_h4_avg_sse2 \ - vpx_highbd_filter_block1d16_h8_avg_sse2 -#define vpx_highbd_filter_block1d8_v4_avg_sse2 \ - vpx_highbd_filter_block1d8_v8_avg_sse2 -#define vpx_highbd_filter_block1d8_h4_avg_sse2 \ - vpx_highbd_filter_block1d8_h8_avg_sse2 -#define vpx_highbd_filter_block1d4_v4_avg_sse2 \ - vpx_highbd_filter_block1d4_v8_avg_sse2 -#define vpx_highbd_filter_block1d4_h4_avg_sse2 \ - vpx_highbd_filter_block1d4_h8_avg_sse2 - -// From vpx_dsp/x86/vpx_high_subpixel_bilinear_sse2.asm. -highbd_filter8_1dfunction vpx_highbd_filter_block1d16_v2_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d16_h2_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d8_v2_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d8_h2_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d4_v2_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d4_h2_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d16_v2_avg_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d16_h2_avg_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d8_v2_avg_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d8_h2_avg_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d4_v2_avg_sse2; -highbd_filter8_1dfunction vpx_highbd_filter_block1d4_h2_avg_sse2; - -// void vpx_highbd_convolve8_horiz_sse2(const uint8_t *src, -// ptrdiff_t src_stride, -// uint8_t *dst, -// ptrdiff_t dst_stride, -// const int16_t *filter_x, -// int x_step_q4, -// const int16_t *filter_y, -// int y_step_q4, -// int w, int h, int bd); -// void vpx_highbd_convolve8_vert_sse2(const uint8_t *src, -// ptrdiff_t src_stride, -// uint8_t *dst, -// ptrdiff_t dst_stride, -// const int16_t *filter_x, -// int x_step_q4, -// const int16_t *filter_y, -// int y_step_q4, -// int w, int h, int bd); -// void vpx_highbd_convolve8_avg_horiz_sse2(const uint8_t *src, -// ptrdiff_t src_stride, -// uint8_t *dst, -// ptrdiff_t dst_stride, -// const int16_t *filter_x, -// int x_step_q4, -// const int16_t *filter_y, -// int y_step_q4, -// int w, int h, int bd); -// void vpx_highbd_convolve8_avg_vert_sse2(const uint8_t *src, -// ptrdiff_t src_stride, -// uint8_t *dst, -// ptrdiff_t dst_stride, -// const int16_t *filter_x, -// int x_step_q4, -// const int16_t *filter_y, -// int y_step_q4, -// int w, int h, int bd); -HIGH_FUN_CONV_1D(horiz, x0_q4, x_step_q4, h, src, , sse2, 0) -HIGH_FUN_CONV_1D(vert, y0_q4, y_step_q4, v, - src - src_stride * (num_taps / 2 - 1), , sse2, 0) -HIGH_FUN_CONV_1D(avg_horiz, x0_q4, x_step_q4, h, src, avg_, sse2, 1) -HIGH_FUN_CONV_1D(avg_vert, y0_q4, y_step_q4, v, - src - src_stride * (num_taps / 2 - 1), avg_, sse2, 1) - -// void vpx_highbd_convolve8_sse2(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, int y_step_q4, -// int w, int h, int bd); -// void vpx_highbd_convolve8_avg_sse2(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, -// int y_step_q4, int w, int h, int bd); -HIGH_FUN_CONV_2D(, sse2, 0) -HIGH_FUN_CONV_2D(avg_, sse2, 1) -#endif // CONFIG_VP9_HIGHBITDEPTH && VPX_ARCH_X86_64 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_8t_intrin_avx2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_8t_intrin_avx2.c deleted file mode 100644 index 526c2838..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_8t_intrin_avx2.c +++ /dev/null @@ -1,1374 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/x86/convolve.h" -#include "vpx_dsp/x86/convolve_avx2.h" -#include "vpx_dsp/x86/convolve_sse2.h" -#include "vpx_dsp/x86/convolve_ssse3.h" -#include "vpx_ports/mem.h" - -// filters for 16_h8 -DECLARE_ALIGNED(32, static const uint8_t, - filt1_global_avx2[32]) = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, - 6, 6, 7, 7, 8, 0, 1, 1, 2, 2, 3, - 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 }; - -DECLARE_ALIGNED(32, static const uint8_t, - filt2_global_avx2[32]) = { 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, - 8, 8, 9, 9, 10, 2, 3, 3, 4, 4, 5, - 5, 6, 6, 7, 7, 8, 8, 9, 9, 10 }; - -DECLARE_ALIGNED(32, static const uint8_t, filt3_global_avx2[32]) = { - 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, - 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12 -}; - -DECLARE_ALIGNED(32, static const uint8_t, filt4_global_avx2[32]) = { - 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, - 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14 -}; - -DECLARE_ALIGNED(32, static const uint8_t, filt_d4_global_avx2[64]) = { - 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6, 0, 1, 2, 3, 1, 2, - 3, 4, 2, 3, 4, 5, 3, 4, 5, 6, 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, - 7, 8, 9, 10, 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10, -}; - -#define CALC_CONVOLVE8_HORZ_ROW \ - srcReg = mm256_loadu2_si128(src_ptr - 3, src_ptr - 3 + src_pitch); \ - s1[0] = _mm256_shuffle_epi8(srcReg, filt[0]); \ - s1[1] = _mm256_shuffle_epi8(srcReg, filt[1]); \ - s1[2] = _mm256_shuffle_epi8(srcReg, filt[2]); \ - s1[3] = _mm256_shuffle_epi8(srcReg, filt[3]); \ - s1[0] = convolve8_16_avx2(s1, f1); \ - s1[0] = _mm256_packus_epi16(s1[0], s1[0]); \ - src_ptr += src_stride; \ - _mm_storel_epi64((__m128i *)&output_ptr[0], _mm256_castsi256_si128(s1[0])); \ - output_ptr += output_pitch; \ - _mm_storel_epi64((__m128i *)&output_ptr[0], \ - _mm256_extractf128_si256(s1[0], 1)); \ - output_ptr += output_pitch; - -static INLINE void vpx_filter_block1d16_h8_x_avx2( - const uint8_t *src_ptr, ptrdiff_t src_pixels_per_line, uint8_t *output_ptr, - ptrdiff_t output_pitch, uint32_t output_height, const int16_t *filter, - const int avg) { - __m128i outReg1, outReg2; - __m256i outReg32b1, outReg32b2; - unsigned int i; - ptrdiff_t src_stride, dst_stride; - __m256i f[4], filt[4], s[4]; - - shuffle_filter_avx2(filter, f); - filt[0] = _mm256_load_si256((__m256i const *)filt1_global_avx2); - filt[1] = _mm256_load_si256((__m256i const *)filt2_global_avx2); - filt[2] = _mm256_load_si256((__m256i const *)filt3_global_avx2); - filt[3] = _mm256_load_si256((__m256i const *)filt4_global_avx2); - - // multiple the size of the source and destination stride by two - src_stride = src_pixels_per_line << 1; - dst_stride = output_pitch << 1; - for (i = output_height; i > 1; i -= 2) { - __m256i srcReg; - - // load the 2 strides of source - srcReg = mm256_loadu2_si128(src_ptr - 3, src_ptr + src_pixels_per_line - 3); - - // filter the source buffer - s[0] = _mm256_shuffle_epi8(srcReg, filt[0]); - s[1] = _mm256_shuffle_epi8(srcReg, filt[1]); - s[2] = _mm256_shuffle_epi8(srcReg, filt[2]); - s[3] = _mm256_shuffle_epi8(srcReg, filt[3]); - outReg32b1 = convolve8_16_avx2(s, f); - - // reading 2 strides of the next 16 bytes - // (part of it was being read by earlier read) - srcReg = mm256_loadu2_si128(src_ptr + 5, src_ptr + src_pixels_per_line + 5); - - // filter the source buffer - s[0] = _mm256_shuffle_epi8(srcReg, filt[0]); - s[1] = _mm256_shuffle_epi8(srcReg, filt[1]); - s[2] = _mm256_shuffle_epi8(srcReg, filt[2]); - s[3] = _mm256_shuffle_epi8(srcReg, filt[3]); - outReg32b2 = convolve8_16_avx2(s, f); - - // shrink to 8 bit each 16 bits, the low and high 64-bits of each lane - // contain the first and second convolve result respectively - outReg32b1 = _mm256_packus_epi16(outReg32b1, outReg32b2); - - src_ptr += src_stride; - - if (avg) { - const __m256i outReg = mm256_loadu2_si128( - (__m128i *)output_ptr, (__m128i *)(output_ptr + output_pitch)); - outReg32b1 = _mm256_avg_epu8(outReg32b1, outReg); - } - mm256_store2_si128((__m128i *)output_ptr, - (__m128i *)(output_ptr + output_pitch), &outReg32b1); - output_ptr += dst_stride; - } - - // if the number of strides is odd. - // process only 16 bytes - if (i > 0) { - const __m128i srcReg1 = _mm_loadu_si128((const __m128i *)(src_ptr - 3)); - const __m128i srcReg2 = _mm_loadu_si128((const __m128i *)(src_ptr + 5)); - const __m256i srcReg = - _mm256_inserti128_si256(_mm256_castsi128_si256(srcReg1), srcReg2, 1); - - // filter the source buffer - s[0] = _mm256_shuffle_epi8(srcReg, filt[0]); - s[1] = _mm256_shuffle_epi8(srcReg, filt[1]); - s[2] = _mm256_shuffle_epi8(srcReg, filt[2]); - s[3] = _mm256_shuffle_epi8(srcReg, filt[3]); - - // The low and high 128-bits of each lane contain the first and second - // convolve result respectively - outReg32b1 = convolve8_16_avx2(s, f); - outReg1 = _mm256_castsi256_si128(outReg32b1); - outReg2 = _mm256_extractf128_si256(outReg32b1, 1); - - // shrink to 8 bit each 16 bits - outReg1 = _mm_packus_epi16(outReg1, outReg2); - - // average if necessary - if (avg) { - outReg1 = _mm_avg_epu8(outReg1, _mm_load_si128((__m128i *)output_ptr)); - } - - // save 16 bytes - _mm_store_si128((__m128i *)output_ptr, outReg1); - } -} - -static void vpx_filter_block1d16_h8_avx2( - const uint8_t *src_ptr, ptrdiff_t src_stride, uint8_t *output_ptr, - ptrdiff_t dst_stride, uint32_t output_height, const int16_t *filter) { - vpx_filter_block1d16_h8_x_avx2(src_ptr, src_stride, output_ptr, dst_stride, - output_height, filter, 0); -} - -static void vpx_filter_block1d16_h8_avg_avx2( - const uint8_t *src_ptr, ptrdiff_t src_stride, uint8_t *output_ptr, - ptrdiff_t dst_stride, uint32_t output_height, const int16_t *filter) { - vpx_filter_block1d16_h8_x_avx2(src_ptr, src_stride, output_ptr, dst_stride, - output_height, filter, 1); -} - -static void vpx_filter_block1d8_h8_avx2( - const uint8_t *src_ptr, ptrdiff_t src_pitch, uint8_t *output_ptr, - ptrdiff_t output_pitch, uint32_t output_height, const int16_t *filter) { - __m256i filt[4], f1[4], s1[4], srcReg; - __m128i f[4], s[4]; - int y = output_height; - - // Multiply the size of the source stride by two - const ptrdiff_t src_stride = src_pitch << 1; - - shuffle_filter_avx2(filter, f1); - filt[0] = _mm256_load_si256((__m256i const *)filt1_global_avx2); - filt[1] = _mm256_load_si256((__m256i const *)filt2_global_avx2); - filt[2] = _mm256_load_si256((__m256i const *)filt3_global_avx2); - filt[3] = _mm256_load_si256((__m256i const *)filt4_global_avx2); - - // Process next 4 rows - while (y > 3) { - CALC_CONVOLVE8_HORZ_ROW - CALC_CONVOLVE8_HORZ_ROW - y -= 4; - } - - // If remaining, then process 2 rows at a time - while (y > 1) { - CALC_CONVOLVE8_HORZ_ROW - y -= 2; - } - - // For the remaining height. - if (y > 0) { - const __m128i src_reg_128 = _mm_loadu_si128((const __m128i *)(src_ptr - 3)); - - f[0] = _mm256_castsi256_si128(f1[0]); - f[1] = _mm256_castsi256_si128(f1[1]); - f[2] = _mm256_castsi256_si128(f1[2]); - f[3] = _mm256_castsi256_si128(f1[3]); - - // filter the source buffer - s[0] = _mm_shuffle_epi8(src_reg_128, _mm256_castsi256_si128(filt[0])); - s[1] = _mm_shuffle_epi8(src_reg_128, _mm256_castsi256_si128(filt[1])); - s[2] = _mm_shuffle_epi8(src_reg_128, _mm256_castsi256_si128(filt[2])); - s[3] = _mm_shuffle_epi8(src_reg_128, _mm256_castsi256_si128(filt[3])); - s[0] = convolve8_8_ssse3(s, f); - - // Saturate 16bit value to 8bit. - s[0] = _mm_packus_epi16(s[0], s[0]); - - // Save only 8 bytes - _mm_storel_epi64((__m128i *)&output_ptr[0], s[0]); - } -} - -static INLINE void vpx_filter_block1d16_v8_x_avx2( - const uint8_t *src_ptr, ptrdiff_t src_pitch, uint8_t *output_ptr, - ptrdiff_t out_pitch, uint32_t output_height, const int16_t *filter, - const int avg) { - __m256i srcRegHead1; - unsigned int i; - ptrdiff_t src_stride, dst_stride; - __m256i f[4], s1[4], s2[4]; - - shuffle_filter_avx2(filter, f); - - // multiple the size of the source and destination stride by two - src_stride = src_pitch << 1; - dst_stride = out_pitch << 1; - - { - __m128i s[6]; - __m256i s32b[6]; - - // load 16 bytes 7 times in stride of src_pitch - s[0] = _mm_loadu_si128((const __m128i *)(src_ptr + 0 * src_pitch)); - s[1] = _mm_loadu_si128((const __m128i *)(src_ptr + 1 * src_pitch)); - s[2] = _mm_loadu_si128((const __m128i *)(src_ptr + 2 * src_pitch)); - s[3] = _mm_loadu_si128((const __m128i *)(src_ptr + 3 * src_pitch)); - s[4] = _mm_loadu_si128((const __m128i *)(src_ptr + 4 * src_pitch)); - s[5] = _mm_loadu_si128((const __m128i *)(src_ptr + 5 * src_pitch)); - srcRegHead1 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src_ptr + 6 * src_pitch))); - - // have each consecutive loads on the same 256 register - s32b[0] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[0]), s[1], 1); - s32b[1] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[1]), s[2], 1); - s32b[2] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[2]), s[3], 1); - s32b[3] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[3]), s[4], 1); - s32b[4] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[4]), s[5], 1); - s32b[5] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[5]), - _mm256_castsi256_si128(srcRegHead1), 1); - - // merge every two consecutive registers except the last one - // the first lanes contain values for filtering odd rows (1,3,5...) and - // the second lanes contain values for filtering even rows (2,4,6...) - s1[0] = _mm256_unpacklo_epi8(s32b[0], s32b[1]); - s2[0] = _mm256_unpackhi_epi8(s32b[0], s32b[1]); - s1[1] = _mm256_unpacklo_epi8(s32b[2], s32b[3]); - s2[1] = _mm256_unpackhi_epi8(s32b[2], s32b[3]); - s1[2] = _mm256_unpacklo_epi8(s32b[4], s32b[5]); - s2[2] = _mm256_unpackhi_epi8(s32b[4], s32b[5]); - } - - // The output_height is always a multiple of two. - assert(!(output_height & 1)); - - for (i = output_height; i > 1; i -= 2) { - __m256i srcRegHead2, srcRegHead3; - - // load the next 2 loads of 16 bytes and have every two - // consecutive loads in the same 256 bit register - srcRegHead2 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src_ptr + 7 * src_pitch))); - srcRegHead1 = _mm256_inserti128_si256( - srcRegHead1, _mm256_castsi256_si128(srcRegHead2), 1); - srcRegHead3 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src_ptr + 8 * src_pitch))); - srcRegHead2 = _mm256_inserti128_si256( - srcRegHead2, _mm256_castsi256_si128(srcRegHead3), 1); - - // merge the two new consecutive registers - // the first lane contain values for filtering odd rows (1,3,5...) and - // the second lane contain values for filtering even rows (2,4,6...) - s1[3] = _mm256_unpacklo_epi8(srcRegHead1, srcRegHead2); - s2[3] = _mm256_unpackhi_epi8(srcRegHead1, srcRegHead2); - - s1[0] = convolve8_16_avx2(s1, f); - s2[0] = convolve8_16_avx2(s2, f); - - // shrink to 8 bit each 16 bits, the low and high 64-bits of each lane - // contain the first and second convolve result respectively - s1[0] = _mm256_packus_epi16(s1[0], s2[0]); - - src_ptr += src_stride; - - // average if necessary - if (avg) { - const __m256i outReg = mm256_loadu2_si128( - (__m128i *)output_ptr, (__m128i *)(output_ptr + out_pitch)); - s1[0] = _mm256_avg_epu8(s1[0], outReg); - } - - mm256_store2_si128((__m128i *)output_ptr, - (__m128i *)(output_ptr + out_pitch), s1); - - output_ptr += dst_stride; - - // shift down by two rows - s1[0] = s1[1]; - s2[0] = s2[1]; - s1[1] = s1[2]; - s2[1] = s2[2]; - s1[2] = s1[3]; - s2[2] = s2[3]; - srcRegHead1 = srcRegHead3; - } -} - -static void vpx_filter_block1d16_v8_avx2(const uint8_t *src_ptr, - ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *filter) { - vpx_filter_block1d16_v8_x_avx2(src_ptr, src_stride, dst_ptr, dst_stride, - height, filter, 0); -} - -static void vpx_filter_block1d16_v8_avg_avx2( - const uint8_t *src_ptr, ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, const int16_t *filter) { - vpx_filter_block1d16_v8_x_avx2(src_ptr, src_stride, dst_ptr, dst_stride, - height, filter, 1); -} - -static void vpx_filter_block1d16_h4_avx2(const uint8_t *src_ptr, - ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - // We will cast the kernel from 16-bit words to 8-bit words, and then extract - // the middle four elements of the kernel into two registers in the form - // ... k[3] k[2] k[3] k[2] - // ... k[5] k[4] k[5] k[4] - // Then we shuffle the source into - // ... s[1] s[0] s[0] s[-1] - // ... s[3] s[2] s[2] s[1] - // Calling multiply and add gives us half of the sum. Calling add gives us - // first half of the output. Repeat again to get the second half of the - // output. Finally we shuffle again to combine the two outputs. - // Since avx2 allows us to use 256-bit buffer, we can do this two rows at a - // time. - - __m128i kernel_reg; // Kernel - __m256i kernel_reg_256, kernel_reg_23, - kernel_reg_45; // Segments of the kernel used - const __m256i reg_32 = _mm256_set1_epi16(32); // Used for rounding - const ptrdiff_t unrolled_src_stride = src_stride << 1; - const ptrdiff_t unrolled_dst_stride = dst_stride << 1; - int h; - - __m256i src_reg, src_reg_shift_0, src_reg_shift_2; - __m256i dst_first, dst_second; - __m256i tmp_0, tmp_1; - __m256i idx_shift_0 = - _mm256_setr_epi8(0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 0, 1, 1, - 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8); - __m256i idx_shift_2 = - _mm256_setr_epi8(2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 2, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10); - - // Start one pixel before as we need tap/2 - 1 = 1 sample from the past - src_ptr -= 1; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm_srai_epi16(kernel_reg, 1); - kernel_reg = _mm_packs_epi16(kernel_reg, kernel_reg); - kernel_reg_256 = _mm256_broadcastsi128_si256(kernel_reg); - kernel_reg_23 = - _mm256_shuffle_epi8(kernel_reg_256, _mm256_set1_epi16(0x0302u)); - kernel_reg_45 = - _mm256_shuffle_epi8(kernel_reg_256, _mm256_set1_epi16(0x0504u)); - - for (h = height; h >= 2; h -= 2) { - // Load the source - src_reg = mm256_loadu2_si128(src_ptr, src_ptr + src_stride); - src_reg_shift_0 = _mm256_shuffle_epi8(src_reg, idx_shift_0); - src_reg_shift_2 = _mm256_shuffle_epi8(src_reg, idx_shift_2); - - // Partial result for first half - tmp_0 = _mm256_maddubs_epi16(src_reg_shift_0, kernel_reg_23); - tmp_1 = _mm256_maddubs_epi16(src_reg_shift_2, kernel_reg_45); - dst_first = _mm256_adds_epi16(tmp_0, tmp_1); - - // Do again to get the second half of dst - // Load the source - src_reg = mm256_loadu2_si128(src_ptr + 8, src_ptr + src_stride + 8); - src_reg_shift_0 = _mm256_shuffle_epi8(src_reg, idx_shift_0); - src_reg_shift_2 = _mm256_shuffle_epi8(src_reg, idx_shift_2); - - // Partial result for second half - tmp_0 = _mm256_maddubs_epi16(src_reg_shift_0, kernel_reg_23); - tmp_1 = _mm256_maddubs_epi16(src_reg_shift_2, kernel_reg_45); - dst_second = _mm256_adds_epi16(tmp_0, tmp_1); - - // Round each result - dst_first = mm256_round_epi16(&dst_first, ®_32, 6); - dst_second = mm256_round_epi16(&dst_second, ®_32, 6); - - // Finally combine to get the final dst - dst_first = _mm256_packus_epi16(dst_first, dst_second); - mm256_store2_si128((__m128i *)dst_ptr, (__m128i *)(dst_ptr + dst_stride), - &dst_first); - - src_ptr += unrolled_src_stride; - dst_ptr += unrolled_dst_stride; - } - - // Repeat for the last row if needed - if (h > 0) { - src_reg = _mm256_loadu_si256((const __m256i *)src_ptr); - // Reorder into 2 1 1 2 - src_reg = _mm256_permute4x64_epi64(src_reg, 0x94); - - src_reg_shift_0 = _mm256_shuffle_epi8(src_reg, idx_shift_0); - src_reg_shift_2 = _mm256_shuffle_epi8(src_reg, idx_shift_2); - - tmp_0 = _mm256_maddubs_epi16(src_reg_shift_0, kernel_reg_23); - tmp_1 = _mm256_maddubs_epi16(src_reg_shift_2, kernel_reg_45); - dst_first = _mm256_adds_epi16(tmp_0, tmp_1); - - dst_first = mm256_round_epi16(&dst_first, ®_32, 6); - - dst_first = _mm256_packus_epi16(dst_first, dst_first); - dst_first = _mm256_permute4x64_epi64(dst_first, 0x8); - - _mm_store_si128((__m128i *)dst_ptr, _mm256_castsi256_si128(dst_first)); - } -} - -static void vpx_filter_block1d16_v4_avx2(const uint8_t *src_ptr, - ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - // We will load two rows of pixels as 8-bit words, rearrange them into the - // form - // ... s[1,0] s[0,0] s[0,0] s[-1,0] - // so that we can call multiply and add with the kernel partial output. Then - // we can call add with another row to get the output. - - // Register for source s[-1:3, :] - __m256i src_reg_1, src_reg_2, src_reg_3; - // Interleaved rows of the source. lo is first half, hi second - __m256i src_reg_m10, src_reg_01, src_reg_12, src_reg_23; - __m256i src_reg_m1001_lo, src_reg_m1001_hi, src_reg_1223_lo, src_reg_1223_hi; - - __m128i kernel_reg; // Kernel - __m256i kernel_reg_256, kernel_reg_23, - kernel_reg_45; // Segments of the kernel used - - // Result after multiply and add - __m256i res_reg_m1001_lo, res_reg_1223_lo, res_reg_m1001_hi, res_reg_1223_hi; - __m256i res_reg, res_reg_lo, res_reg_hi; - - const __m256i reg_32 = _mm256_set1_epi16(32); // Used for rounding - - // We will compute the result two rows at a time - const ptrdiff_t src_stride_unrolled = src_stride << 1; - const ptrdiff_t dst_stride_unrolled = dst_stride << 1; - int h; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm_srai_epi16(kernel_reg, 1); - kernel_reg = _mm_packs_epi16(kernel_reg, kernel_reg); - kernel_reg_256 = _mm256_broadcastsi128_si256(kernel_reg); - kernel_reg_23 = - _mm256_shuffle_epi8(kernel_reg_256, _mm256_set1_epi16(0x0302u)); - kernel_reg_45 = - _mm256_shuffle_epi8(kernel_reg_256, _mm256_set1_epi16(0x0504u)); - - // Row -1 to row 0 - src_reg_m10 = mm256_loadu2_si128((const __m128i *)src_ptr, - (const __m128i *)(src_ptr + src_stride)); - - // Row 0 to row 1 - src_reg_1 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 2))); - src_reg_01 = _mm256_permute2x128_si256(src_reg_m10, src_reg_1, 0x21); - - // First three rows - src_reg_m1001_lo = _mm256_unpacklo_epi8(src_reg_m10, src_reg_01); - src_reg_m1001_hi = _mm256_unpackhi_epi8(src_reg_m10, src_reg_01); - - for (h = height; h > 1; h -= 2) { - src_reg_2 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 3))); - - src_reg_12 = _mm256_inserti128_si256(src_reg_1, - _mm256_castsi256_si128(src_reg_2), 1); - - src_reg_3 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 4))); - - src_reg_23 = _mm256_inserti128_si256(src_reg_2, - _mm256_castsi256_si128(src_reg_3), 1); - - // Last three rows - src_reg_1223_lo = _mm256_unpacklo_epi8(src_reg_12, src_reg_23); - src_reg_1223_hi = _mm256_unpackhi_epi8(src_reg_12, src_reg_23); - - // Output from first half - res_reg_m1001_lo = _mm256_maddubs_epi16(src_reg_m1001_lo, kernel_reg_23); - res_reg_1223_lo = _mm256_maddubs_epi16(src_reg_1223_lo, kernel_reg_45); - res_reg_lo = _mm256_adds_epi16(res_reg_m1001_lo, res_reg_1223_lo); - - // Output from second half - res_reg_m1001_hi = _mm256_maddubs_epi16(src_reg_m1001_hi, kernel_reg_23); - res_reg_1223_hi = _mm256_maddubs_epi16(src_reg_1223_hi, kernel_reg_45); - res_reg_hi = _mm256_adds_epi16(res_reg_m1001_hi, res_reg_1223_hi); - - // Round the words - res_reg_lo = mm256_round_epi16(&res_reg_lo, ®_32, 6); - res_reg_hi = mm256_round_epi16(&res_reg_hi, ®_32, 6); - - // Combine to get the result - res_reg = _mm256_packus_epi16(res_reg_lo, res_reg_hi); - - // Save the result - mm256_store2_si128((__m128i *)dst_ptr, (__m128i *)(dst_ptr + dst_stride), - &res_reg); - - // Update the source by two rows - src_ptr += src_stride_unrolled; - dst_ptr += dst_stride_unrolled; - - src_reg_m1001_lo = src_reg_1223_lo; - src_reg_m1001_hi = src_reg_1223_hi; - src_reg_1 = src_reg_3; - } -} - -static void vpx_filter_block1d8_h4_avx2(const uint8_t *src_ptr, - ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - // We will cast the kernel from 16-bit words to 8-bit words, and then extract - // the middle four elements of the kernel into two registers in the form - // ... k[3] k[2] k[3] k[2] - // ... k[5] k[4] k[5] k[4] - // Then we shuffle the source into - // ... s[1] s[0] s[0] s[-1] - // ... s[3] s[2] s[2] s[1] - // Calling multiply and add gives us half of the sum. Calling add gives us - // first half of the output. Repeat again to get the second half of the - // output. Finally we shuffle again to combine the two outputs. - // Since avx2 allows us to use 256-bit buffer, we can do this two rows at a - // time. - - __m128i kernel_reg_128; // Kernel - __m256i kernel_reg, kernel_reg_23, - kernel_reg_45; // Segments of the kernel used - const __m256i reg_32 = _mm256_set1_epi16(32); // Used for rounding - const ptrdiff_t unrolled_src_stride = src_stride << 1; - const ptrdiff_t unrolled_dst_stride = dst_stride << 1; - int h; - - __m256i idx_shift_0 = - _mm256_setr_epi8(0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 0, 1, 1, - 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8); - __m256i idx_shift_2 = - _mm256_setr_epi8(2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 2, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10); - - // Start one pixel before as we need tap/2 - 1 = 1 sample from the past - src_ptr -= 1; - - // Load Kernel - kernel_reg_128 = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg_128 = _mm_srai_epi16(kernel_reg_128, 1); - kernel_reg_128 = _mm_packs_epi16(kernel_reg_128, kernel_reg_128); - kernel_reg = _mm256_broadcastsi128_si256(kernel_reg_128); - kernel_reg_23 = _mm256_shuffle_epi8(kernel_reg, _mm256_set1_epi16(0x0302u)); - kernel_reg_45 = _mm256_shuffle_epi8(kernel_reg, _mm256_set1_epi16(0x0504u)); - - for (h = height; h >= 2; h -= 2) { - // Load the source - const __m256i src_reg = mm256_loadu2_si128(src_ptr, src_ptr + src_stride); - __m256i dst_reg; - __m256i tmp_0, tmp_1; - const __m256i src_reg_shift_0 = _mm256_shuffle_epi8(src_reg, idx_shift_0); - const __m256i src_reg_shift_2 = _mm256_shuffle_epi8(src_reg, idx_shift_2); - - // Get the output - tmp_0 = _mm256_maddubs_epi16(src_reg_shift_0, kernel_reg_23); - tmp_1 = _mm256_maddubs_epi16(src_reg_shift_2, kernel_reg_45); - dst_reg = _mm256_adds_epi16(tmp_0, tmp_1); - - // Round the result - dst_reg = mm256_round_epi16(&dst_reg, ®_32, 6); - - // Finally combine to get the final dst - dst_reg = _mm256_packus_epi16(dst_reg, dst_reg); - mm256_storeu2_epi64((__m128i *)dst_ptr, (__m128i *)(dst_ptr + dst_stride), - &dst_reg); - - src_ptr += unrolled_src_stride; - dst_ptr += unrolled_dst_stride; - } - - // Repeat for the last row if needed - if (h > 0) { - const __m128i src_reg = _mm_loadu_si128((const __m128i *)src_ptr); - __m128i dst_reg; - const __m128i reg_32_128 = _mm_set1_epi16(32); // Used for rounding - __m128i tmp_0, tmp_1; - - __m128i src_reg_shift_0 = - _mm_shuffle_epi8(src_reg, _mm256_castsi256_si128(idx_shift_0)); - __m128i src_reg_shift_2 = - _mm_shuffle_epi8(src_reg, _mm256_castsi256_si128(idx_shift_2)); - - tmp_0 = _mm_maddubs_epi16(src_reg_shift_0, - _mm256_castsi256_si128(kernel_reg_23)); - tmp_1 = _mm_maddubs_epi16(src_reg_shift_2, - _mm256_castsi256_si128(kernel_reg_45)); - dst_reg = _mm_adds_epi16(tmp_0, tmp_1); - - dst_reg = mm_round_epi16_sse2(&dst_reg, ®_32_128, 6); - - dst_reg = _mm_packus_epi16(dst_reg, _mm_setzero_si128()); - - _mm_storel_epi64((__m128i *)dst_ptr, dst_reg); - } -} - -static void vpx_filter_block1d8_v4_avx2(const uint8_t *src_ptr, - ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - // We will load two rows of pixels as 8-bit words, rearrange them into the - // form - // ... s[1,0] s[0,0] s[0,0] s[-1,0] - // so that we can call multiply and add with the kernel partial output. Then - // we can call add with another row to get the output. - - // Register for source s[-1:3, :] - __m256i src_reg_1, src_reg_2, src_reg_3; - // Interleaved rows of the source. lo is first half, hi second - __m256i src_reg_m10, src_reg_01, src_reg_12, src_reg_23; - __m256i src_reg_m1001, src_reg_1223; - - __m128i kernel_reg_128; // Kernel - __m256i kernel_reg, kernel_reg_23, - kernel_reg_45; // Segments of the kernel used - - // Result after multiply and add - __m256i res_reg_m1001, res_reg_1223; - __m256i res_reg; - - const __m256i reg_32 = _mm256_set1_epi16(32); // Used for rounding - - // We will compute the result two rows at a time - const ptrdiff_t src_stride_unrolled = src_stride << 1; - const ptrdiff_t dst_stride_unrolled = dst_stride << 1; - int h; - - // Load Kernel - kernel_reg_128 = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg_128 = _mm_srai_epi16(kernel_reg_128, 1); - kernel_reg_128 = _mm_packs_epi16(kernel_reg_128, kernel_reg_128); - kernel_reg = _mm256_broadcastsi128_si256(kernel_reg_128); - kernel_reg_23 = _mm256_shuffle_epi8(kernel_reg, _mm256_set1_epi16(0x0302u)); - kernel_reg_45 = _mm256_shuffle_epi8(kernel_reg, _mm256_set1_epi16(0x0504u)); - - // Row -1 to row 0 - src_reg_m10 = mm256_loadu2_epi64((const __m128i *)src_ptr, - (const __m128i *)(src_ptr + src_stride)); - - // Row 0 to row 1 - src_reg_1 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 2))); - src_reg_01 = _mm256_permute2x128_si256(src_reg_m10, src_reg_1, 0x21); - - // First three rows - src_reg_m1001 = _mm256_unpacklo_epi8(src_reg_m10, src_reg_01); - - for (h = height; h > 1; h -= 2) { - src_reg_2 = _mm256_castsi128_si256( - _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride * 3))); - - src_reg_12 = _mm256_inserti128_si256(src_reg_1, - _mm256_castsi256_si128(src_reg_2), 1); - - src_reg_3 = _mm256_castsi128_si256( - _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride * 4))); - - src_reg_23 = _mm256_inserti128_si256(src_reg_2, - _mm256_castsi256_si128(src_reg_3), 1); - - // Last three rows - src_reg_1223 = _mm256_unpacklo_epi8(src_reg_12, src_reg_23); - - // Output - res_reg_m1001 = _mm256_maddubs_epi16(src_reg_m1001, kernel_reg_23); - res_reg_1223 = _mm256_maddubs_epi16(src_reg_1223, kernel_reg_45); - res_reg = _mm256_adds_epi16(res_reg_m1001, res_reg_1223); - - // Round the words - res_reg = mm256_round_epi16(&res_reg, ®_32, 6); - - // Combine to get the result - res_reg = _mm256_packus_epi16(res_reg, res_reg); - - // Save the result - mm256_storeu2_epi64((__m128i *)dst_ptr, (__m128i *)(dst_ptr + dst_stride), - &res_reg); - - // Update the source by two rows - src_ptr += src_stride_unrolled; - dst_ptr += dst_stride_unrolled; - - src_reg_m1001 = src_reg_1223; - src_reg_1 = src_reg_3; - } -} - -static void vpx_filter_block1d4_h4_avx2(const uint8_t *src_ptr, - ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - // We will cast the kernel from 16-bit words to 8-bit words, and then extract - // the middle four elements of the kernel into a single register in the form - // k[5:2] k[5:2] k[5:2] k[5:2] - // Then we shuffle the source into - // s[5:2] s[4:1] s[3:0] s[2:-1] - // Calling multiply and add gives us half of the sum next to each other. - // Calling horizontal add then gives us the output. - // Since avx2 has 256-bit register, we can do 2 rows at a time. - - __m128i kernel_reg_128; // Kernel - __m256i kernel_reg; - const __m256i reg_32 = _mm256_set1_epi16(32); // Used for rounding - int h; - const ptrdiff_t unrolled_src_stride = src_stride << 1; - const ptrdiff_t unrolled_dst_stride = dst_stride << 1; - - __m256i shuf_idx = - _mm256_setr_epi8(0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6, 0, 1, 2, - 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6); - - // Start one pixel before as we need tap/2 - 1 = 1 sample from the past - src_ptr -= 1; - - // Load Kernel - kernel_reg_128 = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg_128 = _mm_srai_epi16(kernel_reg_128, 1); - kernel_reg_128 = _mm_packs_epi16(kernel_reg_128, kernel_reg_128); - kernel_reg = _mm256_broadcastsi128_si256(kernel_reg_128); - kernel_reg = _mm256_shuffle_epi8(kernel_reg, _mm256_set1_epi32(0x05040302u)); - - for (h = height; h > 1; h -= 2) { - // Load the source - const __m256i src_reg = mm256_loadu2_epi64( - (const __m128i *)src_ptr, (const __m128i *)(src_ptr + src_stride)); - const __m256i src_reg_shuf = _mm256_shuffle_epi8(src_reg, shuf_idx); - - // Get the result - __m256i dst = _mm256_maddubs_epi16(src_reg_shuf, kernel_reg); - dst = _mm256_hadds_epi16(dst, _mm256_setzero_si256()); - - // Round result - dst = mm256_round_epi16(&dst, ®_32, 6); - - // Pack to 8-bits - dst = _mm256_packus_epi16(dst, _mm256_setzero_si256()); - - // Save - mm256_storeu2_epi32((__m128i *const)dst_ptr, - (__m128i *const)(dst_ptr + dst_stride), &dst); - - src_ptr += unrolled_src_stride; - dst_ptr += unrolled_dst_stride; - } - - if (h > 0) { - // Load the source - const __m128i reg_32_128 = _mm_set1_epi16(32); // Used for rounding - __m128i src_reg = _mm_loadl_epi64((const __m128i *)src_ptr); - __m128i src_reg_shuf = - _mm_shuffle_epi8(src_reg, _mm256_castsi256_si128(shuf_idx)); - - // Get the result - __m128i dst = - _mm_maddubs_epi16(src_reg_shuf, _mm256_castsi256_si128(kernel_reg)); - dst = _mm_hadds_epi16(dst, _mm_setzero_si128()); - - // Round result - dst = mm_round_epi16_sse2(&dst, ®_32_128, 6); - - // Pack to 8-bits - dst = _mm_packus_epi16(dst, _mm_setzero_si128()); - *((int *)(dst_ptr)) = _mm_cvtsi128_si32(dst); - } -} - -static void vpx_filter_block1d4_v4_avx2(const uint8_t *src_ptr, - ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - // We will load two rows of pixels as 8-bit words, rearrange them into the - // form - // ... s[3,0] s[2,0] s[1,0] s[0,0] s[2,0] s[1,0] s[0,0] s[-1,0] - // so that we can call multiply and add with the kernel to get partial output. - // Calling horizontal add then gives us the completely output - - // Register for source s[-1:3, :] - __m256i src_reg_1, src_reg_2, src_reg_3; - // Interleaved rows of the source. lo is first half, hi second - __m256i src_reg_m10, src_reg_01, src_reg_12, src_reg_23; - __m256i src_reg_m1001, src_reg_1223, src_reg_m1012_1023; - - __m128i kernel_reg_128; // Kernel - __m256i kernel_reg; - - // Result after multiply and add - __m256i res_reg; - - const __m256i reg_32 = _mm256_set1_epi16(32); // Used for rounding - - // We will compute the result two rows at a time - const ptrdiff_t src_stride_unrolled = src_stride << 1; - const ptrdiff_t dst_stride_unrolled = dst_stride << 1; - int h; - - // Load Kernel - kernel_reg_128 = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg_128 = _mm_srai_epi16(kernel_reg_128, 1); - kernel_reg_128 = _mm_packs_epi16(kernel_reg_128, kernel_reg_128); - kernel_reg = _mm256_broadcastsi128_si256(kernel_reg_128); - kernel_reg = _mm256_shuffle_epi8(kernel_reg, _mm256_set1_epi32(0x05040302u)); - - // Row -1 to row 0 - src_reg_m10 = mm256_loadu2_si128((const __m128i *)src_ptr, - (const __m128i *)(src_ptr + src_stride)); - - // Row 0 to row 1 - src_reg_1 = _mm256_castsi128_si256( - _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 2))); - src_reg_01 = _mm256_permute2x128_si256(src_reg_m10, src_reg_1, 0x21); - - // First three rows - src_reg_m1001 = _mm256_unpacklo_epi8(src_reg_m10, src_reg_01); - - for (h = height; h > 1; h -= 2) { - src_reg_2 = _mm256_castsi128_si256( - _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride * 3))); - - src_reg_12 = _mm256_inserti128_si256(src_reg_1, - _mm256_castsi256_si128(src_reg_2), 1); - - src_reg_3 = _mm256_castsi128_si256( - _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride * 4))); - - src_reg_23 = _mm256_inserti128_si256(src_reg_2, - _mm256_castsi256_si128(src_reg_3), 1); - - // Last three rows - src_reg_1223 = _mm256_unpacklo_epi8(src_reg_12, src_reg_23); - - // Combine all the rows - src_reg_m1012_1023 = _mm256_unpacklo_epi16(src_reg_m1001, src_reg_1223); - - // Output - res_reg = _mm256_maddubs_epi16(src_reg_m1012_1023, kernel_reg); - res_reg = _mm256_hadds_epi16(res_reg, _mm256_setzero_si256()); - - // Round the words - res_reg = mm256_round_epi16(&res_reg, ®_32, 6); - - // Combine to get the result - res_reg = _mm256_packus_epi16(res_reg, res_reg); - - // Save the result - mm256_storeu2_epi32((__m128i *)dst_ptr, (__m128i *)(dst_ptr + dst_stride), - &res_reg); - - // Update the source by two rows - src_ptr += src_stride_unrolled; - dst_ptr += dst_stride_unrolled; - - src_reg_m1001 = src_reg_1223; - src_reg_1 = src_reg_3; - } -} - -static void vpx_filter_block1d8_v8_avx2( - const uint8_t *src_ptr, ptrdiff_t src_pitch, uint8_t *output_ptr, - ptrdiff_t out_pitch, uint32_t output_height, const int16_t *filter) { - __m256i f[4], ss[4]; - __m256i r[8]; - __m128i s[9]; - - unsigned int y = output_height; - // Multiply the size of the source stride by two - const ptrdiff_t src_stride = src_pitch << 1; - - // The output_height is always a multiple of two. - assert(!(output_height & 1)); - - shuffle_filter_avx2(filter, f); - s[0] = _mm_loadl_epi64((const __m128i *)(src_ptr + 0 * src_pitch)); - s[1] = _mm_loadl_epi64((const __m128i *)(src_ptr + 1 * src_pitch)); - s[2] = _mm_loadl_epi64((const __m128i *)(src_ptr + 2 * src_pitch)); - s[3] = _mm_loadl_epi64((const __m128i *)(src_ptr + 3 * src_pitch)); - s[4] = _mm_loadl_epi64((const __m128i *)(src_ptr + 4 * src_pitch)); - s[5] = _mm_loadl_epi64((const __m128i *)(src_ptr + 5 * src_pitch)); - s[6] = _mm_loadl_epi64((const __m128i *)(src_ptr + 6 * src_pitch)); - - // merge the result together - // r[0]: 0 0 0 0 0 0 0 0 r17 r16 r15 r14 r13 r12 r11 r10 | 0 0 0 0 0 0 0 0 - // r07 r06 r05 r04 r03 r02 r01 r00 - r[0] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[0]), s[1], 1); - - // r[1]: 0 0 0 0 0 0 0 0 r27 r26 r25 r24 r23 r22 r21 r20 | 0 0 0 0 0 0 0 0 - // r17 r16 r15 r14 r13 r12 r11 r10 - r[1] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[1]), s[2], 1); - - // r[2]: 0 0 0 0 0 0 0 0 r37 r36 r35 r34 r33 r32 r31 r30 | 0 0 0 0 0 0 0 0 - // r27 r26 r25 r24 r23 r22 r21 r20 - r[2] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[2]), s[3], 1); - - // r[3]: 0 0 0 0 0 0 0 0 r47 r46 r45 r44 r43 r42 r41 r40 | 0 0 0 0 0 0 0 0 - // r37 r36 r35 r34 r33 r32 r31 r30 - r[3] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[3]), s[4], 1); - - // r[4]: 0 0 0 0 0 0 0 0 r57 r56 r55 r54 r53 r52 r51 r50 | 0 0 0 0 0 0 0 0 - // r47 r46 r45 r44 r43 r42 r41 r40 - r[4] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[4]), s[5], 1); - - // r[5]: 0 0 0 0 0 0 0 0 r67 r66 r65 r64 r63 r62 r61 r60 | 0 0 0 0 0 0 0 0 - // r57 r56 r55 r54 r53 r52 r51 r50 - r[5] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[5]), s[6], 1); - - // Merge together - // ss[0]: |r27 r17|.......|r21 r11|r20 r10 || r17 r07|.....|r12 r02|r11 - // r01|r10 r00| - ss[0] = _mm256_unpacklo_epi8(r[0], r[1]); - - // ss[0]: |r47 r37|.......|r41 r31|r40 r30 || r37 r27|.....|r32 r22|r31 - // r21|r30 r20| - ss[1] = _mm256_unpacklo_epi8(r[2], r[3]); - - // ss[2]: |r67 r57|.......|r61 r51|r60 r50 || r57 r47|.....|r52 r42|r51 - // r41|r50 r40| - ss[2] = _mm256_unpacklo_epi8(r[4], r[5]); - - // Process 2 rows at a time - do { - s[7] = _mm_loadl_epi64((const __m128i *)(src_ptr + 7 * src_pitch)); - s[8] = _mm_loadl_epi64((const __m128i *)(src_ptr + 8 * src_pitch)); - - // r[6]: 0 0 0 0 0 0 0 0 r77 r76 r75 r74 r73 r72 r71 r70 | 0 0 0 0 0 0 0 - // 0 r67 r66 r65 r64 r63 r62 r61 r60 - r[6] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[6]), s[7], 1); - // r[7]: 0 0 0 0 0 0 0 0 r87 r86 r85 r84 r83 r82 r81 r80 | 0 0 0 0 0 0 0 - // 0 r77 r76 r75 r74 r73 r72 r71 r70 - r[7] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[7]), s[8], 1); - - // ss[3] : | r87 r77 | .......| r81 r71 | r80 r70 || r77 r67 | .....| r72 - // r62 | r71 r61|r70 r60| - ss[3] = _mm256_unpacklo_epi8(r[6], r[7]); - ss[0] = convolve8_16_avx2(ss, f); - ss[0] = _mm256_packus_epi16(ss[0], ss[0]); - src_ptr += src_stride; - - /* shift down two rows */ - s[6] = s[8]; - _mm_storel_epi64((__m128i *)&output_ptr[0], _mm256_castsi256_si128(ss[0])); - output_ptr += out_pitch; - _mm_storel_epi64((__m128i *)&output_ptr[0], - _mm256_extractf128_si256(ss[0], 1)); - output_ptr += out_pitch; - ss[0] = ss[1]; - ss[1] = ss[2]; - ss[2] = ss[3]; - y -= 2; - } while (y > 1); -} - -static void vpx_filter_block1d4_h8_avx2( - const uint8_t *src_ptr, ptrdiff_t src_pitch, uint8_t *output_ptr, - ptrdiff_t output_pitch, uint32_t output_height, const int16_t *filter) { - __m128i filtersReg; - __m256i addFilterReg64_256bit; - unsigned int y = output_height; - - assert(output_height > 1); - - addFilterReg64_256bit = _mm256_set1_epi16(32); - - // f7 f6 f5 f4 f3 f2 f1 f0 (16 bit) - filtersReg = _mm_loadu_si128((const __m128i *)filter); - - // converting the 16 bit (short) to 8 bit (byte) and have the same data - // in both lanes of 128 bit register. - // f7 f6 f5 f4 f3 f2 f1 f0 || f7 f6 f5 f4 f3 f2 f1 f0 (8 bit each) - filtersReg = _mm_packs_epi16(filtersReg, filtersReg); - - { - ptrdiff_t src_stride; - __m256i filt1Reg, filt2Reg, firstFilters, secondFilters; - // have the same data in both lanes of a 256 bit register - // f7 f6 f5 f4 f3 f2 f1 f0 f7 f6 f5 f4 f3 f2 f1 f0 | f7 f6 f5 f4 f3 f2 f1 f0 - // f7 f6 f5 f4 f3 f2 f1 f0 (8bit each) - const __m256i filtersReg32 = _mm256_broadcastsi128_si256(filtersReg); - - // duplicate only the first 32 bits - // f3 f2 f1 f0|f3 f2 f1 f0|f3 f2 f1 f0|f3 f2 f1 f0 | f3 f2 f1 f0|f3 f2 f1 - // f0|f3 f2 f1 f0|f3 f2 f1 f0 - firstFilters = _mm256_shuffle_epi32(filtersReg32, 0); - // duplicate only the second 32 bits - // f7 f6 f5 f4|f7 f6 f5 f4|f7 f6 f5 f4|f7 f6 f5 f4 | f7 f6 f5 f4|f7 f6 f5 - // f4|f7 f6 f5 f4|f7 f6 f5 f4 - secondFilters = _mm256_shuffle_epi32(filtersReg32, 0x55); - - // s6 s5 s4 s3 s5 s4 s3 s2 s4 s3 s2 s1 s3 s2 s1 s0 | s6 s5 s4 s3 s5 s4 s3 - // s2 s4 s3 s2 s1 s3 s2 s1 s0 - filt1Reg = _mm256_load_si256((__m256i const *)filt_d4_global_avx2); - - // s10 s9 s8 s7 s9 s8 s7 s6 s8 s7 s6 s5 s7 s6 s5 s4 | s10 s9 s8 s7 s9 s8 s7 - // s6 s8 s7 s6 s5 s7 s6 s5 s4 - filt2Reg = _mm256_load_si256((__m256i const *)(filt_d4_global_avx2 + 32)); - - // multiple the size of the source and destination stride by two - src_stride = src_pitch << 1; - - do { - __m256i srcRegFilt32b1_1, srcRegFilt32b2, srcReg32b1; - // load the 2 strides of source - // r115 r114 ...... r15 r14 r13 r12 r11 r10 | r015 r014 r013 ...... r07 - // r06 r05 r04 r03 r02 r01 r00 - srcReg32b1 = mm256_loadu2_si128(src_ptr - 3, src_ptr - 3 + src_pitch); - - // filter the source buffer - // r16 r15 r14 r13 r15 r14 r13 r12 r14 r13 r12 r11 r13 r12 r11 r10 | r06 - // r05 r04 r03 r05 r04 r03 r02 r04 r03 r02 r01 r03 r02 r01 r00 - srcRegFilt32b1_1 = _mm256_shuffle_epi8(srcReg32b1, filt1Reg); - - // multiply 4 adjacent elements with the filter and add the result - // ...|f3*r14+f2*r13|f1*r13+f0*r12|f3*r13+f2*r12|f1*r11+f0*r10||... - // |f1*r03+f0*r02|f3*r04+f2*r03|f1*r02+f0*r01|f3*r03+f2*r02|f1*r01+f0*r00 - srcRegFilt32b1_1 = _mm256_maddubs_epi16(srcRegFilt32b1_1, firstFilters); - - // filter the source buffer - // r110 r19 r18 r17|r19 r18 r17 r16|r18 r17 r16 r15|r17 r16 r15 r14||r010 - // r09 r08 r07|r09 r08 r07 r06|r08 r07 r06 r05|r07 r06 r05 r04 - srcRegFilt32b2 = _mm256_shuffle_epi8(srcReg32b1, filt2Reg); - - // multiply 4 adjacent elements with the filter and add the result - // r010 r09 r08 r07|r9 r08 r07 r06|r08 r07 r06 r05|r07 r06 r05 r04||r010 - // r09 r08 r07|r9 r08 r07 r06|r08 r07 r06 r05|r07 r06 r05 r04 - srcRegFilt32b2 = _mm256_maddubs_epi16(srcRegFilt32b2, secondFilters); - - srcRegFilt32b1_1 = - _mm256_add_epi16(srcRegFilt32b1_1, addFilterReg64_256bit); - srcRegFilt32b1_1 = _mm256_adds_epi16(srcRegFilt32b1_1, srcRegFilt32b2); - - srcRegFilt32b1_1 = - _mm256_hadds_epi16(srcRegFilt32b1_1, _mm256_setzero_si256()); - - // 0 0 0 0 R13 R12 R11 R10 || 0 0 0 0 R03 R02 R01 R00 (16bit) - srcRegFilt32b1_1 = _mm256_srai_epi16(srcRegFilt32b1_1, 7); - - // 8zeros 0 0 0 0 R13 R12 R11 R10 || 8zeros 0 0 0 0 R03 R02 R01 R00 (8bit) - srcRegFilt32b1_1 = - _mm256_packus_epi16(srcRegFilt32b1_1, _mm256_setzero_si256()); - - src_ptr += src_stride; - // save first row 4 values - *((int *)&output_ptr[0]) = - _mm_cvtsi128_si32(_mm256_castsi256_si128(srcRegFilt32b1_1)); - output_ptr += output_pitch; - - // save second row 4 values - *((int *)&output_ptr[0]) = - _mm_cvtsi128_si32(_mm256_extractf128_si256(srcRegFilt32b1_1, 1)); - output_ptr += output_pitch; - - y = y - 2; - } while (y > 1); - - // For remaining height - if (y > 0) { - __m128i srcReg1, srcRegFilt1_1, addFilterReg64; - __m128i srcRegFilt2; - - addFilterReg64 = _mm_set1_epi32((int)0x0400040u); - - srcReg1 = _mm_loadu_si128((const __m128i *)(src_ptr - 3)); - - // filter the source buffer - srcRegFilt1_1 = - _mm_shuffle_epi8(srcReg1, _mm256_castsi256_si128(filt1Reg)); - - // multiply 4 adjacent elements with the filter and add the result - srcRegFilt1_1 = _mm_maddubs_epi16(srcRegFilt1_1, - _mm256_castsi256_si128(firstFilters)); - - // filter the source buffer - srcRegFilt2 = _mm_shuffle_epi8(srcReg1, _mm256_castsi256_si128(filt2Reg)); - - // multiply 4 adjacent elements with the filter and add the result - srcRegFilt2 = - _mm_maddubs_epi16(srcRegFilt2, _mm256_castsi256_si128(secondFilters)); - - srcRegFilt1_1 = _mm_adds_epi16(srcRegFilt1_1, srcRegFilt2); - srcRegFilt1_1 = _mm_hadds_epi16(srcRegFilt1_1, _mm_setzero_si128()); - // shift by 6 bit each 16 bit - srcRegFilt1_1 = _mm_adds_epi16(srcRegFilt1_1, addFilterReg64); - srcRegFilt1_1 = _mm_srai_epi16(srcRegFilt1_1, 7); - - // shrink to 8 bit each 16 bits, the first lane contain the first - // convolve result and the second lane contain the second convolve result - srcRegFilt1_1 = _mm_packus_epi16(srcRegFilt1_1, _mm_setzero_si128()); - - // save 4 bytes - *((int *)(output_ptr)) = _mm_cvtsi128_si32(srcRegFilt1_1); - } - } -} - -static void vpx_filter_block1d4_v8_avx2( - const uint8_t *src_ptr, ptrdiff_t src_pitch, uint8_t *output_ptr, - ptrdiff_t out_pitch, uint32_t output_height, const int16_t *filter) { - __m256i f[4], ss[4]; - __m256i r[9], rr[2]; - __m128i s[11]; - - unsigned int y = output_height; - // Multiply the size of the source stride by four - const ptrdiff_t src_stride = src_pitch << 2; - const ptrdiff_t out_stride = out_pitch << 2; - - // The output_height is always a multiple of two. - assert(!(output_height & 0x01)); - - shuffle_filter_avx2(filter, f); - - s[0] = _mm_loadl_epi64((const __m128i *)(src_ptr + 0 * src_pitch)); - s[1] = _mm_loadl_epi64((const __m128i *)(src_ptr + 1 * src_pitch)); - s[2] = _mm_loadl_epi64((const __m128i *)(src_ptr + 2 * src_pitch)); - s[3] = _mm_loadl_epi64((const __m128i *)(src_ptr + 3 * src_pitch)); - s[4] = _mm_loadl_epi64((const __m128i *)(src_ptr + 4 * src_pitch)); - s[5] = _mm_loadl_epi64((const __m128i *)(src_ptr + 5 * src_pitch)); - s[6] = _mm_loadl_epi64((const __m128i *)(src_ptr + 6 * src_pitch)); - - r[0] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[0]), s[2], 1); - r[1] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[1]), s[3], 1); - r[2] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[2]), s[4], 1); - r[3] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[3]), s[5], 1); - r[4] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[4]), s[6], 1); - - // r37.....r24..r33..r31 r30 r23 r22 r21 r20|r17....r14 r07..r05 r04 r13 r12 - // r11 r10 r03 r02 r01 r00 - rr[0] = _mm256_unpacklo_epi32(r[0], r[1]); - - // r47.....r34..r43..r41 r40 r33 r32 r31 r30|r27....r24 r17..r15 r14 r23 r22 - // r21 r20 r13 r12 r11 r10 - rr[1] = _mm256_unpacklo_epi32(r[1], r[2]); - - // r43 r33....r40 r30|r33 r23....r30 r20||r23 r13....r20 r10|r13 r03....r10 - // r00| - ss[0] = _mm256_unpacklo_epi8(rr[0], rr[1]); - - // r37.....r24..r33..r31 r30 r23 r22 r21 r20||r17....r14 r07..r05 r04 r13 r12 - // r11 r10 r03 r02 r01 r00 - rr[0] = _mm256_unpacklo_epi32(r[2], r[3]); - - // r47.....r34..r43..r41 r40 r33 r32 r31 r30|r27....r24 r17..r15 r14 r23 r22 - // r21 r20 r13 r12 r11 r10 - rr[1] = _mm256_unpacklo_epi32(r[3], r[4]); - - // r63 r53....r60 r50|r53 r43....r50 r40||r43 r33....r40 r30|r33 r23....r30 - // r20| - ss[1] = _mm256_unpacklo_epi8(rr[0], rr[1]); - // Process 4 rows at a time - while (y >= 4) { - s[7] = _mm_loadl_epi64((const __m128i *)(src_ptr + 7 * src_pitch)); - s[8] = _mm_loadl_epi64((const __m128i *)(src_ptr + 8 * src_pitch)); - s[9] = _mm_loadl_epi64((const __m128i *)(src_ptr + 9 * src_pitch)); - s[10] = _mm_loadl_epi64((const __m128i *)(src_ptr + 10 * src_pitch)); - - r[5] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[5]), s[7], 1); - r[6] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[6]), s[8], 1); - rr[0] = _mm256_unpacklo_epi32(r[4], r[5]); - rr[1] = _mm256_unpacklo_epi32(r[5], r[6]); - ss[2] = _mm256_unpacklo_epi8(rr[0], rr[1]); - - r[7] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[7]), s[9], 1); - r[8] = _mm256_inserti128_si256(_mm256_castsi128_si256(s[8]), s[10], 1); - rr[0] = _mm256_unpacklo_epi32(r[6], r[7]); - rr[1] = _mm256_unpacklo_epi32(r[7], r[8]); - ss[3] = _mm256_unpacklo_epi8(rr[0], rr[1]); - - ss[0] = convolve8_16_avx2(ss, f); - - // r3 r2 r3 r2 r1 r0 r1 r0 - ss[0] = _mm256_packus_epi16(ss[0], ss[0]); - src_ptr += src_stride; - - mm256_storeu2_epi32((__m128i *const)output_ptr, - (__m128i *const)(output_ptr + (2 * out_pitch)), ss); - - ss[0] = _mm256_srli_si256(ss[0], 4); - - mm256_storeu2_epi32((__m128i *const)(output_ptr + (1 * out_pitch)), - (__m128i *const)(output_ptr + (3 * out_pitch)), ss); - - output_ptr += out_stride; - - ss[0] = ss[2]; - ss[1] = ss[3]; - - s[6] = s[10]; - s[5] = s[9]; - - r[4] = r[8]; - y -= 4; - } - - // Process 2 rows - if (y == 2) { - __m128i ss1[4], f1[4], r1[4]; - - s[4] = _mm_loadl_epi64((const __m128i *)(src_ptr + 4 * src_pitch)); - s[7] = _mm_loadl_epi64((const __m128i *)(src_ptr + 7 * src_pitch)); - s[8] = _mm_loadl_epi64((const __m128i *)(src_ptr + 8 * src_pitch)); - - f1[0] = _mm256_castsi256_si128(f[0]); - f1[1] = _mm256_castsi256_si128(f[1]); - f1[2] = _mm256_castsi256_si128(f[2]); - f1[3] = _mm256_castsi256_si128(f[3]); - - r1[0] = _mm_unpacklo_epi32(s[4], s[5]); - r1[1] = _mm_unpacklo_epi32(s[5], s[6]); - - // R7-6 xxxx .. . . x| r73 r72 r71 r70 r63 r62 r61 r60 - r1[2] = _mm_unpacklo_epi32(s[6], s[7]); - - // R8-7 xxxx .. . . x| r83 r82 r81 r80 r73 r72 r71 r70 - r1[3] = _mm_unpacklo_epi32(s[7], s[8]); - - // r23 r13....r20 r10|r13 r03....r10 r00 - ss1[0] = _mm256_castsi256_si128(ss[0]); - - // r43 r33....r40 r30|r33 r23....r30 r20 - ss1[1] = _mm256_castsi256_si128(ss[1]); - - // r63 r53....r60 r50|r53 r43....r50 r40 - ss1[2] = _mm_unpacklo_epi8(r1[0], r1[1]); - - // r83 r73....r80 r70|r73 r63....r70 r60 - ss1[3] = _mm_unpacklo_epi8(r1[2], r1[3]); - - ss1[0] = convolve8_8_ssse3(ss1, f1); - - // r1 r0 r1 r0 - ss1[0] = _mm_packus_epi16(ss1[0], ss1[0]); - - // Save first row 4 values - *((int *)&output_ptr[0]) = _mm_cvtsi128_si32(ss1[0]); - output_ptr += out_pitch; - - ss1[0] = _mm_srli_si128(ss1[0], 4); - // Save second row 4 values - *((int *)&output_ptr[0]) = _mm_cvtsi128_si32(ss1[0]); - } -} - -#if HAVE_AVX2 && HAVE_SSSE3 -#if VPX_ARCH_X86_64 -filter8_1dfunction vpx_filter_block1d8_v8_intrin_ssse3; -filter8_1dfunction vpx_filter_block1d8_h8_intrin_ssse3; -filter8_1dfunction vpx_filter_block1d4_h8_intrin_ssse3; -#else // VPX_ARCH_X86 -filter8_1dfunction vpx_filter_block1d8_v8_ssse3; -filter8_1dfunction vpx_filter_block1d8_h8_ssse3; -filter8_1dfunction vpx_filter_block1d4_h8_ssse3; -#endif // VPX_ARCH_X86_64 -filter8_1dfunction vpx_filter_block1d8_v8_avg_ssse3; -filter8_1dfunction vpx_filter_block1d8_h8_avg_ssse3; -filter8_1dfunction vpx_filter_block1d4_v8_avg_ssse3; -filter8_1dfunction vpx_filter_block1d4_h8_avg_ssse3; -#define vpx_filter_block1d8_v8_avg_avx2 vpx_filter_block1d8_v8_avg_ssse3 -#define vpx_filter_block1d8_h8_avg_avx2 vpx_filter_block1d8_h8_avg_ssse3 -#define vpx_filter_block1d4_v8_avg_avx2 vpx_filter_block1d4_v8_avg_ssse3 -#define vpx_filter_block1d4_h8_avg_avx2 vpx_filter_block1d4_h8_avg_ssse3 -filter8_1dfunction vpx_filter_block1d16_v2_ssse3; -filter8_1dfunction vpx_filter_block1d16_h2_ssse3; -filter8_1dfunction vpx_filter_block1d8_v2_ssse3; -filter8_1dfunction vpx_filter_block1d8_h2_ssse3; -filter8_1dfunction vpx_filter_block1d4_v2_ssse3; -filter8_1dfunction vpx_filter_block1d4_h2_ssse3; -#define vpx_filter_block1d16_v2_avx2 vpx_filter_block1d16_v2_ssse3 -#define vpx_filter_block1d16_h2_avx2 vpx_filter_block1d16_h2_ssse3 -#define vpx_filter_block1d8_v2_avx2 vpx_filter_block1d8_v2_ssse3 -#define vpx_filter_block1d8_h2_avx2 vpx_filter_block1d8_h2_ssse3 -#define vpx_filter_block1d4_v2_avx2 vpx_filter_block1d4_v2_ssse3 -#define vpx_filter_block1d4_h2_avx2 vpx_filter_block1d4_h2_ssse3 -filter8_1dfunction vpx_filter_block1d16_v2_avg_ssse3; -filter8_1dfunction vpx_filter_block1d16_h2_avg_ssse3; -filter8_1dfunction vpx_filter_block1d8_v2_avg_ssse3; -filter8_1dfunction vpx_filter_block1d8_h2_avg_ssse3; -filter8_1dfunction vpx_filter_block1d4_v2_avg_ssse3; -filter8_1dfunction vpx_filter_block1d4_h2_avg_ssse3; -#define vpx_filter_block1d16_v2_avg_avx2 vpx_filter_block1d16_v2_avg_ssse3 -#define vpx_filter_block1d16_h2_avg_avx2 vpx_filter_block1d16_h2_avg_ssse3 -#define vpx_filter_block1d8_v2_avg_avx2 vpx_filter_block1d8_v2_avg_ssse3 -#define vpx_filter_block1d8_h2_avg_avx2 vpx_filter_block1d8_h2_avg_ssse3 -#define vpx_filter_block1d4_v2_avg_avx2 vpx_filter_block1d4_v2_avg_ssse3 -#define vpx_filter_block1d4_h2_avg_avx2 vpx_filter_block1d4_h2_avg_ssse3 - -#define vpx_filter_block1d16_v4_avg_avx2 vpx_filter_block1d16_v8_avg_avx2 -#define vpx_filter_block1d16_h4_avg_avx2 vpx_filter_block1d16_h8_avg_avx2 -#define vpx_filter_block1d8_v4_avg_avx2 vpx_filter_block1d8_v8_avg_avx2 -#define vpx_filter_block1d8_h4_avg_avx2 vpx_filter_block1d8_h8_avg_avx2 -#define vpx_filter_block1d4_v4_avg_avx2 vpx_filter_block1d4_v8_avg_avx2 -#define vpx_filter_block1d4_h4_avg_avx2 vpx_filter_block1d4_h8_avg_avx2 -// void vpx_convolve8_horiz_avx2(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, int y_step_q4, -// int w, int h); -// void vpx_convolve8_vert_avx2(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, int y_step_q4, -// int w, int h); -// void vpx_convolve8_avg_horiz_avx2(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, -// int y_step_q4, int w, int h); -// void vpx_convolve8_avg_vert_avx2(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, -// int y_step_q4, int w, int h); -FUN_CONV_1D(horiz, x0_q4, x_step_q4, h, src, , avx2, 0) -FUN_CONV_1D(vert, y0_q4, y_step_q4, v, src - src_stride * (num_taps / 2 - 1), , - avx2, 0) -FUN_CONV_1D(avg_horiz, x0_q4, x_step_q4, h, src, avg_, avx2, 1) -FUN_CONV_1D(avg_vert, y0_q4, y_step_q4, v, - src - src_stride * (num_taps / 2 - 1), avg_, avx2, 1) - -// void vpx_convolve8_avx2(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, int y_step_q4, -// int w, int h); -// void vpx_convolve8_avg_avx2(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, int y_step_q4, -// int w, int h); -FUN_CONV_2D(, avx2, 0) -FUN_CONV_2D(avg_, avx2, 1) -#endif // HAVE_AX2 && HAVE_SSSE3 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_8t_intrin_ssse3.c b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_8t_intrin_ssse3.c deleted file mode 100644 index 4ea2752d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_8t_intrin_ssse3.c +++ /dev/null @@ -1,1087 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include // SSSE3 - -#include - -#include "./vpx_config.h" -#include "./vpx_dsp_rtcd.h" -#include "vpx_dsp/vpx_filter.h" -#include "vpx_dsp/x86/convolve.h" -#include "vpx_dsp/x86/convolve_sse2.h" -#include "vpx_dsp/x86/convolve_ssse3.h" -#include "vpx_dsp/x86/mem_sse2.h" -#include "vpx_dsp/x86/transpose_sse2.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" - -static INLINE __m128i shuffle_filter_convolve8_8_ssse3( - const __m128i *const s, const int16_t *const filter) { - __m128i f[4]; - shuffle_filter_ssse3(filter, f); - return convolve8_8_ssse3(s, f); -} - -// Used by the avx2 implementation. -#if VPX_ARCH_X86_64 -// Use the intrinsics below -filter8_1dfunction vpx_filter_block1d4_h8_intrin_ssse3; -filter8_1dfunction vpx_filter_block1d8_h8_intrin_ssse3; -filter8_1dfunction vpx_filter_block1d8_v8_intrin_ssse3; -#define vpx_filter_block1d4_h8_ssse3 vpx_filter_block1d4_h8_intrin_ssse3 -#define vpx_filter_block1d8_h8_ssse3 vpx_filter_block1d8_h8_intrin_ssse3 -#define vpx_filter_block1d8_v8_ssse3 vpx_filter_block1d8_v8_intrin_ssse3 -#else // VPX_ARCH_X86 -// Use the assembly in vpx_dsp/x86/vpx_subpixel_8t_ssse3.asm. -filter8_1dfunction vpx_filter_block1d4_h8_ssse3; -filter8_1dfunction vpx_filter_block1d8_h8_ssse3; -filter8_1dfunction vpx_filter_block1d8_v8_ssse3; -#endif - -#if VPX_ARCH_X86_64 -void vpx_filter_block1d4_h8_intrin_ssse3( - const uint8_t *src_ptr, ptrdiff_t src_pitch, uint8_t *output_ptr, - ptrdiff_t output_pitch, uint32_t output_height, const int16_t *filter) { - __m128i firstFilters, secondFilters, shuffle1, shuffle2; - __m128i srcRegFilt1, srcRegFilt2; - __m128i addFilterReg64, filtersReg, srcReg; - unsigned int i; - - // create a register with 0,64,0,64,0,64,0,64,0,64,0,64,0,64,0,64 - addFilterReg64 = _mm_set1_epi32((int)0x0400040u); - filtersReg = _mm_loadu_si128((const __m128i *)filter); - // converting the 16 bit (short) to 8 bit (byte) and have the same data - // in both lanes of 128 bit register. - filtersReg = _mm_packs_epi16(filtersReg, filtersReg); - - // duplicate only the first 16 bits in the filter into the first lane - firstFilters = _mm_shufflelo_epi16(filtersReg, 0); - // duplicate only the third 16 bit in the filter into the first lane - secondFilters = _mm_shufflelo_epi16(filtersReg, 0xAAu); - // duplicate only the seconds 16 bits in the filter into the second lane - // firstFilters: k0 k1 k0 k1 k0 k1 k0 k1 k2 k3 k2 k3 k2 k3 k2 k3 - firstFilters = _mm_shufflehi_epi16(firstFilters, 0x55u); - // duplicate only the forth 16 bits in the filter into the second lane - // secondFilters: k4 k5 k4 k5 k4 k5 k4 k5 k6 k7 k6 k7 k6 k7 k6 k7 - secondFilters = _mm_shufflehi_epi16(secondFilters, 0xFFu); - - // loading the local filters - shuffle1 = _mm_setr_epi8(0, 1, 1, 2, 2, 3, 3, 4, 2, 3, 3, 4, 4, 5, 5, 6); - shuffle2 = _mm_setr_epi8(4, 5, 5, 6, 6, 7, 7, 8, 6, 7, 7, 8, 8, 9, 9, 10); - - for (i = 0; i < output_height; i++) { - srcReg = _mm_loadu_si128((const __m128i *)(src_ptr - 3)); - - // filter the source buffer - srcRegFilt1 = _mm_shuffle_epi8(srcReg, shuffle1); - srcRegFilt2 = _mm_shuffle_epi8(srcReg, shuffle2); - - // multiply 2 adjacent elements with the filter and add the result - srcRegFilt1 = _mm_maddubs_epi16(srcRegFilt1, firstFilters); - srcRegFilt2 = _mm_maddubs_epi16(srcRegFilt2, secondFilters); - - // sum the results together, saturating only on the final step - // the specific order of the additions prevents outranges - srcRegFilt1 = _mm_add_epi16(srcRegFilt1, srcRegFilt2); - - // extract the higher half of the register - srcRegFilt2 = _mm_srli_si128(srcRegFilt1, 8); - - // add the rounding offset early to avoid another saturated add - srcRegFilt1 = _mm_add_epi16(srcRegFilt1, addFilterReg64); - srcRegFilt1 = _mm_adds_epi16(srcRegFilt1, srcRegFilt2); - - // shift by 7 bit each 16 bits - srcRegFilt1 = _mm_srai_epi16(srcRegFilt1, 7); - - // shrink to 8 bit each 16 bits - srcRegFilt1 = _mm_packus_epi16(srcRegFilt1, srcRegFilt1); - src_ptr += src_pitch; - - // save only 4 bytes - *((int *)&output_ptr[0]) = _mm_cvtsi128_si32(srcRegFilt1); - - output_ptr += output_pitch; - } -} - -void vpx_filter_block1d8_h8_intrin_ssse3( - const uint8_t *src_ptr, ptrdiff_t src_pitch, uint8_t *output_ptr, - ptrdiff_t output_pitch, uint32_t output_height, const int16_t *filter) { - unsigned int i; - __m128i f[4], filt[4], s[4]; - - shuffle_filter_ssse3(filter, f); - filt[0] = _mm_setr_epi8(0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8); - filt[1] = _mm_setr_epi8(2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10); - filt[2] = _mm_setr_epi8(4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12); - filt[3] = - _mm_setr_epi8(6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14); - - for (i = 0; i < output_height; i++) { - const __m128i srcReg = _mm_loadu_si128((const __m128i *)(src_ptr - 3)); - - // filter the source buffer - s[0] = _mm_shuffle_epi8(srcReg, filt[0]); - s[1] = _mm_shuffle_epi8(srcReg, filt[1]); - s[2] = _mm_shuffle_epi8(srcReg, filt[2]); - s[3] = _mm_shuffle_epi8(srcReg, filt[3]); - s[0] = convolve8_8_ssse3(s, f); - - // shrink to 8 bit each 16 bits - s[0] = _mm_packus_epi16(s[0], s[0]); - - src_ptr += src_pitch; - - // save only 8 bytes - _mm_storel_epi64((__m128i *)&output_ptr[0], s[0]); - - output_ptr += output_pitch; - } -} - -void vpx_filter_block1d8_v8_intrin_ssse3( - const uint8_t *src_ptr, ptrdiff_t src_pitch, uint8_t *output_ptr, - ptrdiff_t out_pitch, uint32_t output_height, const int16_t *filter) { - unsigned int i; - __m128i f[4], s[8], ss[4]; - - shuffle_filter_ssse3(filter, f); - - // load the first 7 rows of 8 bytes - s[0] = _mm_loadl_epi64((const __m128i *)(src_ptr + 0 * src_pitch)); - s[1] = _mm_loadl_epi64((const __m128i *)(src_ptr + 1 * src_pitch)); - s[2] = _mm_loadl_epi64((const __m128i *)(src_ptr + 2 * src_pitch)); - s[3] = _mm_loadl_epi64((const __m128i *)(src_ptr + 3 * src_pitch)); - s[4] = _mm_loadl_epi64((const __m128i *)(src_ptr + 4 * src_pitch)); - s[5] = _mm_loadl_epi64((const __m128i *)(src_ptr + 5 * src_pitch)); - s[6] = _mm_loadl_epi64((const __m128i *)(src_ptr + 6 * src_pitch)); - - for (i = 0; i < output_height; i++) { - // load the last 8 bytes - s[7] = _mm_loadl_epi64((const __m128i *)(src_ptr + 7 * src_pitch)); - - // merge the result together - ss[0] = _mm_unpacklo_epi8(s[0], s[1]); - ss[1] = _mm_unpacklo_epi8(s[2], s[3]); - - // merge the result together - ss[2] = _mm_unpacklo_epi8(s[4], s[5]); - ss[3] = _mm_unpacklo_epi8(s[6], s[7]); - - ss[0] = convolve8_8_ssse3(ss, f); - // shrink to 8 bit each 16 bits - ss[0] = _mm_packus_epi16(ss[0], ss[0]); - - src_ptr += src_pitch; - - // shift down a row - s[0] = s[1]; - s[1] = s[2]; - s[2] = s[3]; - s[3] = s[4]; - s[4] = s[5]; - s[5] = s[6]; - s[6] = s[7]; - - // save only 8 bytes convolve result - _mm_storel_epi64((__m128i *)&output_ptr[0], ss[0]); - - output_ptr += out_pitch; - } -} -#endif // VPX_ARCH_X86_64 - -static void vpx_filter_block1d16_h4_ssse3(const uint8_t *src_ptr, - ptrdiff_t src_stride, - uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - // We will cast the kernel from 16-bit words to 8-bit words, and then extract - // the middle four elements of the kernel into two registers in the form - // ... k[3] k[2] k[3] k[2] - // ... k[5] k[4] k[5] k[4] - // Then we shuffle the source into - // ... s[1] s[0] s[0] s[-1] - // ... s[3] s[2] s[2] s[1] - // Calling multiply and add gives us half of the sum. Calling add gives us - // first half of the output. Repeat again to get the second half of the - // output. Finally we shuffle again to combine the two outputs. - - __m128i kernel_reg; // Kernel - __m128i kernel_reg_23, kernel_reg_45; // Segments of the kernel used - const __m128i reg_32 = _mm_set1_epi16(32); // Used for rounding - int h; - - __m128i src_reg, src_reg_shift_0, src_reg_shift_2; - __m128i dst_first, dst_second; - __m128i tmp_0, tmp_1; - __m128i idx_shift_0 = - _mm_setr_epi8(0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8); - __m128i idx_shift_2 = - _mm_setr_epi8(2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10); - - // Start one pixel before as we need tap/2 - 1 = 1 sample from the past - src_ptr -= 1; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm_srai_epi16(kernel_reg, 1); - kernel_reg = _mm_packs_epi16(kernel_reg, kernel_reg); - kernel_reg_23 = _mm_shuffle_epi8(kernel_reg, _mm_set1_epi16(0x0302u)); - kernel_reg_45 = _mm_shuffle_epi8(kernel_reg, _mm_set1_epi16(0x0504u)); - - for (h = height; h > 0; --h) { - // Load the source - src_reg = _mm_loadu_si128((const __m128i *)src_ptr); - src_reg_shift_0 = _mm_shuffle_epi8(src_reg, idx_shift_0); - src_reg_shift_2 = _mm_shuffle_epi8(src_reg, idx_shift_2); - - // Partial result for first half - tmp_0 = _mm_maddubs_epi16(src_reg_shift_0, kernel_reg_23); - tmp_1 = _mm_maddubs_epi16(src_reg_shift_2, kernel_reg_45); - dst_first = _mm_adds_epi16(tmp_0, tmp_1); - - // Do again to get the second half of dst - // Load the source - src_reg = _mm_loadu_si128((const __m128i *)(src_ptr + 8)); - src_reg_shift_0 = _mm_shuffle_epi8(src_reg, idx_shift_0); - src_reg_shift_2 = _mm_shuffle_epi8(src_reg, idx_shift_2); - - // Partial result for first half - tmp_0 = _mm_maddubs_epi16(src_reg_shift_0, kernel_reg_23); - tmp_1 = _mm_maddubs_epi16(src_reg_shift_2, kernel_reg_45); - dst_second = _mm_adds_epi16(tmp_0, tmp_1); - - // Round each result - dst_first = mm_round_epi16_sse2(&dst_first, ®_32, 6); - dst_second = mm_round_epi16_sse2(&dst_second, ®_32, 6); - - // Finally combine to get the final dst - dst_first = _mm_packus_epi16(dst_first, dst_second); - _mm_store_si128((__m128i *)dst_ptr, dst_first); - - src_ptr += src_stride; - dst_ptr += dst_stride; - } -} - -static void vpx_filter_block1d16_v4_ssse3(const uint8_t *src_ptr, - ptrdiff_t src_stride, - uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - // We will load two rows of pixels as 8-bit words, rearrange them into the - // form - // ... s[0,1] s[-1,1] s[0,0] s[-1,0] - // ... s[0,9] s[-1,9] s[0,8] s[-1,8] - // so that we can call multiply and add with the kernel to get 16-bit words of - // the form - // ... s[0,1]k[3]+s[-1,1]k[2] s[0,0]k[3]+s[-1,0]k[2] - // Finally, we can add multiple rows together to get the desired output. - - // Register for source s[-1:3, :] - __m128i src_reg_m1, src_reg_0, src_reg_1, src_reg_2, src_reg_3; - // Interleaved rows of the source. lo is first half, hi second - __m128i src_reg_m10_lo, src_reg_m10_hi, src_reg_01_lo, src_reg_01_hi; - __m128i src_reg_12_lo, src_reg_12_hi, src_reg_23_lo, src_reg_23_hi; - - __m128i kernel_reg; // Kernel - __m128i kernel_reg_23, kernel_reg_45; // Segments of the kernel used - - // Result after multiply and add - __m128i res_reg_m10_lo, res_reg_01_lo, res_reg_12_lo, res_reg_23_lo; - __m128i res_reg_m10_hi, res_reg_01_hi, res_reg_12_hi, res_reg_23_hi; - __m128i res_reg_m1012, res_reg_0123; - __m128i res_reg_m1012_lo, res_reg_0123_lo, res_reg_m1012_hi, res_reg_0123_hi; - - const __m128i reg_32 = _mm_set1_epi16(32); // Used for rounding - - // We will compute the result two rows at a time - const ptrdiff_t src_stride_unrolled = src_stride << 1; - const ptrdiff_t dst_stride_unrolled = dst_stride << 1; - int h; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm_srai_epi16(kernel_reg, 1); - kernel_reg = _mm_packs_epi16(kernel_reg, kernel_reg); - kernel_reg_23 = _mm_shuffle_epi8(kernel_reg, _mm_set1_epi16(0x0302u)); - kernel_reg_45 = _mm_shuffle_epi8(kernel_reg, _mm_set1_epi16(0x0504u)); - - // First shuffle the data - src_reg_m1 = _mm_loadu_si128((const __m128i *)src_ptr); - src_reg_0 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride)); - src_reg_m10_lo = _mm_unpacklo_epi8(src_reg_m1, src_reg_0); - src_reg_m10_hi = _mm_unpackhi_epi8(src_reg_m1, src_reg_0); - - // More shuffling - src_reg_1 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 2)); - src_reg_01_lo = _mm_unpacklo_epi8(src_reg_0, src_reg_1); - src_reg_01_hi = _mm_unpackhi_epi8(src_reg_0, src_reg_1); - - for (h = height; h > 1; h -= 2) { - src_reg_2 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 3)); - - src_reg_12_lo = _mm_unpacklo_epi8(src_reg_1, src_reg_2); - src_reg_12_hi = _mm_unpackhi_epi8(src_reg_1, src_reg_2); - - src_reg_3 = _mm_loadu_si128((const __m128i *)(src_ptr + src_stride * 4)); - - src_reg_23_lo = _mm_unpacklo_epi8(src_reg_2, src_reg_3); - src_reg_23_hi = _mm_unpackhi_epi8(src_reg_2, src_reg_3); - - // Partial output from first half - res_reg_m10_lo = _mm_maddubs_epi16(src_reg_m10_lo, kernel_reg_23); - res_reg_01_lo = _mm_maddubs_epi16(src_reg_01_lo, kernel_reg_23); - - res_reg_12_lo = _mm_maddubs_epi16(src_reg_12_lo, kernel_reg_45); - res_reg_23_lo = _mm_maddubs_epi16(src_reg_23_lo, kernel_reg_45); - - // Add to get first half of the results - res_reg_m1012_lo = _mm_adds_epi16(res_reg_m10_lo, res_reg_12_lo); - res_reg_0123_lo = _mm_adds_epi16(res_reg_01_lo, res_reg_23_lo); - - // Partial output for second half - res_reg_m10_hi = _mm_maddubs_epi16(src_reg_m10_hi, kernel_reg_23); - res_reg_01_hi = _mm_maddubs_epi16(src_reg_01_hi, kernel_reg_23); - - res_reg_12_hi = _mm_maddubs_epi16(src_reg_12_hi, kernel_reg_45); - res_reg_23_hi = _mm_maddubs_epi16(src_reg_23_hi, kernel_reg_45); - - // Second half of the results - res_reg_m1012_hi = _mm_adds_epi16(res_reg_m10_hi, res_reg_12_hi); - res_reg_0123_hi = _mm_adds_epi16(res_reg_01_hi, res_reg_23_hi); - - // Round the words - res_reg_m1012_lo = mm_round_epi16_sse2(&res_reg_m1012_lo, ®_32, 6); - res_reg_0123_lo = mm_round_epi16_sse2(&res_reg_0123_lo, ®_32, 6); - res_reg_m1012_hi = mm_round_epi16_sse2(&res_reg_m1012_hi, ®_32, 6); - res_reg_0123_hi = mm_round_epi16_sse2(&res_reg_0123_hi, ®_32, 6); - - // Combine to get the result - res_reg_m1012 = _mm_packus_epi16(res_reg_m1012_lo, res_reg_m1012_hi); - res_reg_0123 = _mm_packus_epi16(res_reg_0123_lo, res_reg_0123_hi); - - _mm_store_si128((__m128i *)dst_ptr, res_reg_m1012); - _mm_store_si128((__m128i *)(dst_ptr + dst_stride), res_reg_0123); - - // Update the source by two rows - src_ptr += src_stride_unrolled; - dst_ptr += dst_stride_unrolled; - - src_reg_m10_lo = src_reg_12_lo; - src_reg_m10_hi = src_reg_12_hi; - src_reg_01_lo = src_reg_23_lo; - src_reg_01_hi = src_reg_23_hi; - src_reg_1 = src_reg_3; - } -} - -static void vpx_filter_block1d8_h4_ssse3(const uint8_t *src_ptr, - ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - // We will cast the kernel from 16-bit words to 8-bit words, and then extract - // the middle four elements of the kernel into two registers in the form - // ... k[3] k[2] k[3] k[2] - // ... k[5] k[4] k[5] k[4] - // Then we shuffle the source into - // ... s[1] s[0] s[0] s[-1] - // ... s[3] s[2] s[2] s[1] - // Calling multiply and add gives us half of the sum. Calling add gives us - // first half of the output. Repeat again to get the second half of the - // output. Finally we shuffle again to combine the two outputs. - - __m128i kernel_reg; // Kernel - __m128i kernel_reg_23, kernel_reg_45; // Segments of the kernel used - const __m128i reg_32 = _mm_set1_epi16(32); // Used for rounding - int h; - - __m128i src_reg, src_reg_shift_0, src_reg_shift_2; - __m128i dst_first; - __m128i tmp_0, tmp_1; - __m128i idx_shift_0 = - _mm_setr_epi8(0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8); - __m128i idx_shift_2 = - _mm_setr_epi8(2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10); - - // Start one pixel before as we need tap/2 - 1 = 1 sample from the past - src_ptr -= 1; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm_srai_epi16(kernel_reg, 1); - kernel_reg = _mm_packs_epi16(kernel_reg, kernel_reg); - kernel_reg_23 = _mm_shuffle_epi8(kernel_reg, _mm_set1_epi16(0x0302u)); - kernel_reg_45 = _mm_shuffle_epi8(kernel_reg, _mm_set1_epi16(0x0504u)); - - for (h = height; h > 0; --h) { - // Load the source - src_reg = _mm_loadu_si128((const __m128i *)src_ptr); - src_reg_shift_0 = _mm_shuffle_epi8(src_reg, idx_shift_0); - src_reg_shift_2 = _mm_shuffle_epi8(src_reg, idx_shift_2); - - // Get the result - tmp_0 = _mm_maddubs_epi16(src_reg_shift_0, kernel_reg_23); - tmp_1 = _mm_maddubs_epi16(src_reg_shift_2, kernel_reg_45); - dst_first = _mm_adds_epi16(tmp_0, tmp_1); - - // Round round result - dst_first = mm_round_epi16_sse2(&dst_first, ®_32, 6); - - // Pack to 8-bits - dst_first = _mm_packus_epi16(dst_first, _mm_setzero_si128()); - _mm_storel_epi64((__m128i *)dst_ptr, dst_first); - - src_ptr += src_stride; - dst_ptr += dst_stride; - } -} - -static void vpx_filter_block1d8_v4_ssse3(const uint8_t *src_ptr, - ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - // We will load two rows of pixels as 8-bit words, rearrange them into the - // form - // ... s[0,1] s[-1,1] s[0,0] s[-1,0] - // so that we can call multiply and add with the kernel to get 16-bit words of - // the form - // ... s[0,1]k[3]+s[-1,1]k[2] s[0,0]k[3]+s[-1,0]k[2] - // Finally, we can add multiple rows together to get the desired output. - - // Register for source s[-1:3, :] - __m128i src_reg_m1, src_reg_0, src_reg_1, src_reg_2, src_reg_3; - // Interleaved rows of the source. lo is first half, hi second - __m128i src_reg_m10, src_reg_01; - __m128i src_reg_12, src_reg_23; - - __m128i kernel_reg; // Kernel - __m128i kernel_reg_23, kernel_reg_45; // Segments of the kernel used - - // Result after multiply and add - __m128i res_reg_m10, res_reg_01, res_reg_12, res_reg_23; - __m128i res_reg_m1012, res_reg_0123; - - const __m128i reg_32 = _mm_set1_epi16(32); // Used for rounding - - // We will compute the result two rows at a time - const ptrdiff_t src_stride_unrolled = src_stride << 1; - const ptrdiff_t dst_stride_unrolled = dst_stride << 1; - int h; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm_srai_epi16(kernel_reg, 1); - kernel_reg = _mm_packs_epi16(kernel_reg, kernel_reg); - kernel_reg_23 = _mm_shuffle_epi8(kernel_reg, _mm_set1_epi16(0x0302u)); - kernel_reg_45 = _mm_shuffle_epi8(kernel_reg, _mm_set1_epi16(0x0504u)); - - // First shuffle the data - src_reg_m1 = _mm_loadl_epi64((const __m128i *)src_ptr); - src_reg_0 = _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride)); - src_reg_m10 = _mm_unpacklo_epi8(src_reg_m1, src_reg_0); - - // More shuffling - src_reg_1 = _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride * 2)); - src_reg_01 = _mm_unpacklo_epi8(src_reg_0, src_reg_1); - - for (h = height; h > 1; h -= 2) { - src_reg_2 = _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride * 3)); - - src_reg_12 = _mm_unpacklo_epi8(src_reg_1, src_reg_2); - - src_reg_3 = _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride * 4)); - - src_reg_23 = _mm_unpacklo_epi8(src_reg_2, src_reg_3); - - // Partial output - res_reg_m10 = _mm_maddubs_epi16(src_reg_m10, kernel_reg_23); - res_reg_01 = _mm_maddubs_epi16(src_reg_01, kernel_reg_23); - - res_reg_12 = _mm_maddubs_epi16(src_reg_12, kernel_reg_45); - res_reg_23 = _mm_maddubs_epi16(src_reg_23, kernel_reg_45); - - // Add to get entire output - res_reg_m1012 = _mm_adds_epi16(res_reg_m10, res_reg_12); - res_reg_0123 = _mm_adds_epi16(res_reg_01, res_reg_23); - - // Round the words - res_reg_m1012 = mm_round_epi16_sse2(&res_reg_m1012, ®_32, 6); - res_reg_0123 = mm_round_epi16_sse2(&res_reg_0123, ®_32, 6); - - // Pack from 16-bit to 8-bit - res_reg_m1012 = _mm_packus_epi16(res_reg_m1012, _mm_setzero_si128()); - res_reg_0123 = _mm_packus_epi16(res_reg_0123, _mm_setzero_si128()); - - _mm_storel_epi64((__m128i *)dst_ptr, res_reg_m1012); - _mm_storel_epi64((__m128i *)(dst_ptr + dst_stride), res_reg_0123); - - // Update the source by two rows - src_ptr += src_stride_unrolled; - dst_ptr += dst_stride_unrolled; - - src_reg_m10 = src_reg_12; - src_reg_01 = src_reg_23; - src_reg_1 = src_reg_3; - } -} - -static void vpx_filter_block1d4_h4_ssse3(const uint8_t *src_ptr, - ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - // We will cast the kernel from 16-bit words to 8-bit words, and then extract - // the middle four elements of the kernel into a single register in the form - // k[5:2] k[5:2] k[5:2] k[5:2] - // Then we shuffle the source into - // s[5:2] s[4:1] s[3:0] s[2:-1] - // Calling multiply and add gives us half of the sum next to each other. - // Calling horizontal add then gives us the output. - - __m128i kernel_reg; // Kernel - const __m128i reg_32 = _mm_set1_epi16(32); // Used for rounding - int h; - - __m128i src_reg, src_reg_shuf; - __m128i dst_first; - __m128i shuf_idx = - _mm_setr_epi8(0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6); - - // Start one pixel before as we need tap/2 - 1 = 1 sample from the past - src_ptr -= 1; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm_srai_epi16(kernel_reg, 1); - kernel_reg = _mm_packs_epi16(kernel_reg, kernel_reg); - kernel_reg = _mm_shuffle_epi8(kernel_reg, _mm_set1_epi32(0x05040302u)); - - for (h = height; h > 0; --h) { - // Load the source - src_reg = _mm_loadu_si128((const __m128i *)src_ptr); - src_reg_shuf = _mm_shuffle_epi8(src_reg, shuf_idx); - - // Get the result - dst_first = _mm_maddubs_epi16(src_reg_shuf, kernel_reg); - dst_first = _mm_hadds_epi16(dst_first, _mm_setzero_si128()); - - // Round result - dst_first = mm_round_epi16_sse2(&dst_first, ®_32, 6); - - // Pack to 8-bits - dst_first = _mm_packus_epi16(dst_first, _mm_setzero_si128()); - *((int *)(dst_ptr)) = _mm_cvtsi128_si32(dst_first); - - src_ptr += src_stride; - dst_ptr += dst_stride; - } -} - -static void vpx_filter_block1d4_v4_ssse3(const uint8_t *src_ptr, - ptrdiff_t src_stride, uint8_t *dst_ptr, - ptrdiff_t dst_stride, uint32_t height, - const int16_t *kernel) { - // We will load two rows of pixels as 8-bit words, rearrange them into the - // form - // ... s[2,0] s[1,0] s[0,0] s[-1,0] - // so that we can call multiply and add with the kernel partial output. Then - // we can call horizontal add to get the output. - // Finally, we can add multiple rows together to get the desired output. - // This is done two rows at a time - - // Register for source s[-1:3, :] - __m128i src_reg_m1, src_reg_0, src_reg_1, src_reg_2, src_reg_3; - // Interleaved rows of the source. - __m128i src_reg_m10, src_reg_01; - __m128i src_reg_12, src_reg_23; - __m128i src_reg_m1001, src_reg_1223; - __m128i src_reg_m1012_1023_lo, src_reg_m1012_1023_hi; - - __m128i kernel_reg; // Kernel - - // Result after multiply and add - __m128i reg_0, reg_1; - - const __m128i reg_32 = _mm_set1_epi16(32); // Used for rounding - - // We will compute the result two rows at a time - const ptrdiff_t src_stride_unrolled = src_stride << 1; - const ptrdiff_t dst_stride_unrolled = dst_stride << 1; - int h; - - // Load Kernel - kernel_reg = _mm_loadu_si128((const __m128i *)kernel); - kernel_reg = _mm_srai_epi16(kernel_reg, 1); - kernel_reg = _mm_packs_epi16(kernel_reg, kernel_reg); - kernel_reg = _mm_shuffle_epi8(kernel_reg, _mm_set1_epi32(0x05040302u)); - - // First shuffle the data - src_reg_m1 = _mm_loadl_epi64((const __m128i *)src_ptr); - src_reg_0 = _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride)); - src_reg_m10 = _mm_unpacklo_epi32(src_reg_m1, src_reg_0); - - // More shuffling - src_reg_1 = _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride * 2)); - src_reg_01 = _mm_unpacklo_epi32(src_reg_0, src_reg_1); - - // Put three rows next to each other - src_reg_m1001 = _mm_unpacklo_epi8(src_reg_m10, src_reg_01); - - for (h = height; h > 1; h -= 2) { - src_reg_2 = _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride * 3)); - src_reg_12 = _mm_unpacklo_epi32(src_reg_1, src_reg_2); - - src_reg_3 = _mm_loadl_epi64((const __m128i *)(src_ptr + src_stride * 4)); - src_reg_23 = _mm_unpacklo_epi32(src_reg_2, src_reg_3); - - // Put three rows next to each other - src_reg_1223 = _mm_unpacklo_epi8(src_reg_12, src_reg_23); - - // Put all four rows next to each other - src_reg_m1012_1023_lo = _mm_unpacklo_epi16(src_reg_m1001, src_reg_1223); - src_reg_m1012_1023_hi = _mm_unpackhi_epi16(src_reg_m1001, src_reg_1223); - - // Get the results - reg_0 = _mm_maddubs_epi16(src_reg_m1012_1023_lo, kernel_reg); - reg_1 = _mm_maddubs_epi16(src_reg_m1012_1023_hi, kernel_reg); - reg_0 = _mm_hadds_epi16(reg_0, _mm_setzero_si128()); - reg_1 = _mm_hadds_epi16(reg_1, _mm_setzero_si128()); - - // Round the words - reg_0 = mm_round_epi16_sse2(®_0, ®_32, 6); - reg_1 = mm_round_epi16_sse2(®_1, ®_32, 6); - - // Pack from 16-bit to 8-bit and put them in the right order - reg_0 = _mm_packus_epi16(reg_0, reg_0); - reg_1 = _mm_packus_epi16(reg_1, reg_1); - - // Save the result - *((int *)(dst_ptr)) = _mm_cvtsi128_si32(reg_0); - *((int *)(dst_ptr + dst_stride)) = _mm_cvtsi128_si32(reg_1); - - // Update the source by two rows - src_ptr += src_stride_unrolled; - dst_ptr += dst_stride_unrolled; - - src_reg_m1001 = src_reg_1223; - src_reg_1 = src_reg_3; - } -} - -// From vpx_dsp/x86/vpx_subpixel_8t_ssse3.asm -filter8_1dfunction vpx_filter_block1d16_v8_ssse3; -filter8_1dfunction vpx_filter_block1d16_h8_ssse3; -filter8_1dfunction vpx_filter_block1d4_v8_ssse3; -filter8_1dfunction vpx_filter_block1d16_v8_avg_ssse3; -filter8_1dfunction vpx_filter_block1d16_h8_avg_ssse3; -filter8_1dfunction vpx_filter_block1d8_v8_avg_ssse3; -filter8_1dfunction vpx_filter_block1d8_h8_avg_ssse3; -filter8_1dfunction vpx_filter_block1d4_v8_avg_ssse3; -filter8_1dfunction vpx_filter_block1d4_h8_avg_ssse3; - -// Use the [vh]8 version because there is no [vh]4 implementation. -#define vpx_filter_block1d16_v4_avg_ssse3 vpx_filter_block1d16_v8_avg_ssse3 -#define vpx_filter_block1d16_h4_avg_ssse3 vpx_filter_block1d16_h8_avg_ssse3 -#define vpx_filter_block1d8_v4_avg_ssse3 vpx_filter_block1d8_v8_avg_ssse3 -#define vpx_filter_block1d8_h4_avg_ssse3 vpx_filter_block1d8_h8_avg_ssse3 -#define vpx_filter_block1d4_v4_avg_ssse3 vpx_filter_block1d4_v8_avg_ssse3 -#define vpx_filter_block1d4_h4_avg_ssse3 vpx_filter_block1d4_h8_avg_ssse3 - -// From vpx_dsp/x86/vpx_subpixel_bilinear_ssse3.asm -filter8_1dfunction vpx_filter_block1d16_v2_ssse3; -filter8_1dfunction vpx_filter_block1d16_h2_ssse3; -filter8_1dfunction vpx_filter_block1d8_v2_ssse3; -filter8_1dfunction vpx_filter_block1d8_h2_ssse3; -filter8_1dfunction vpx_filter_block1d4_v2_ssse3; -filter8_1dfunction vpx_filter_block1d4_h2_ssse3; -filter8_1dfunction vpx_filter_block1d16_v2_avg_ssse3; -filter8_1dfunction vpx_filter_block1d16_h2_avg_ssse3; -filter8_1dfunction vpx_filter_block1d8_v2_avg_ssse3; -filter8_1dfunction vpx_filter_block1d8_h2_avg_ssse3; -filter8_1dfunction vpx_filter_block1d4_v2_avg_ssse3; -filter8_1dfunction vpx_filter_block1d4_h2_avg_ssse3; - -// void vpx_convolve8_horiz_ssse3(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, int y_step_q4, -// int w, int h); -// void vpx_convolve8_vert_ssse3(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, int y_step_q4, -// int w, int h); -// void vpx_convolve8_avg_horiz_ssse3(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, -// int y_step_q4, int w, int h); -// void vpx_convolve8_avg_vert_ssse3(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, -// int y_step_q4, int w, int h); -FUN_CONV_1D(horiz, x0_q4, x_step_q4, h, src, , ssse3, 0) -FUN_CONV_1D(vert, y0_q4, y_step_q4, v, src - src_stride * (num_taps / 2 - 1), , - ssse3, 0) -FUN_CONV_1D(avg_horiz, x0_q4, x_step_q4, h, src, avg_, ssse3, 1) -FUN_CONV_1D(avg_vert, y0_q4, y_step_q4, v, - src - src_stride * (num_taps / 2 - 1), avg_, ssse3, 1) - -static void filter_horiz_w8_ssse3(const uint8_t *const src, - const ptrdiff_t src_stride, - uint8_t *const dst, - const int16_t *const x_filter) { - __m128i s[8], ss[4], temp; - - load_8bit_8x8(src, src_stride, s); - // 00 01 10 11 20 21 30 31 40 41 50 51 60 61 70 71 - // 02 03 12 13 22 23 32 33 42 43 52 53 62 63 72 73 - // 04 05 14 15 24 25 34 35 44 45 54 55 64 65 74 75 - // 06 07 16 17 26 27 36 37 46 47 56 57 66 67 76 77 - transpose_16bit_4x8(s, ss); - temp = shuffle_filter_convolve8_8_ssse3(ss, x_filter); - // shrink to 8 bit each 16 bits - temp = _mm_packus_epi16(temp, temp); - // save only 8 bytes convolve result - _mm_storel_epi64((__m128i *)dst, temp); -} - -static void transpose8x8_to_dst(const uint8_t *const src, - const ptrdiff_t src_stride, uint8_t *const dst, - const ptrdiff_t dst_stride) { - __m128i s[8]; - - load_8bit_8x8(src, src_stride, s); - transpose_8bit_8x8(s, s); - store_8bit_8x8(s, dst, dst_stride); -} - -static void scaledconvolve_horiz_w8(const uint8_t *src, - const ptrdiff_t src_stride, uint8_t *dst, - const ptrdiff_t dst_stride, - const InterpKernel *const x_filters, - const int x0_q4, const int x_step_q4, - const int w, const int h) { - DECLARE_ALIGNED(16, uint8_t, temp[8 * 8]); - int x, y, z; - src -= SUBPEL_TAPS / 2 - 1; - - // This function processes 8x8 areas. The intermediate height is not always - // a multiple of 8, so force it to be a multiple of 8 here. - y = h + (8 - (h & 0x7)); - - do { - int x_q4 = x0_q4; - for (x = 0; x < w; x += 8) { - // process 8 src_x steps - for (z = 0; z < 8; ++z) { - const uint8_t *const src_x = &src[x_q4 >> SUBPEL_BITS]; - const int16_t *const x_filter = x_filters[x_q4 & SUBPEL_MASK]; - if (x_q4 & SUBPEL_MASK) { - filter_horiz_w8_ssse3(src_x, src_stride, temp + (z * 8), x_filter); - } else { - int i; - for (i = 0; i < 8; ++i) { - temp[z * 8 + i] = src_x[i * src_stride + 3]; - } - } - x_q4 += x_step_q4; - } - - // transpose the 8x8 filters values back to dst - transpose8x8_to_dst(temp, 8, dst + x, dst_stride); - } - - src += src_stride * 8; - dst += dst_stride * 8; - } while (y -= 8); -} - -static void filter_horiz_w4_ssse3(const uint8_t *const src, - const ptrdiff_t src_stride, - uint8_t *const dst, - const int16_t *const filter) { - __m128i s[4], ss[2]; - __m128i temp; - - load_8bit_8x4(src, src_stride, s); - transpose_16bit_4x4(s, ss); - // 00 01 10 11 20 21 30 31 - s[0] = ss[0]; - // 02 03 12 13 22 23 32 33 - s[1] = _mm_srli_si128(ss[0], 8); - // 04 05 14 15 24 25 34 35 - s[2] = ss[1]; - // 06 07 16 17 26 27 36 37 - s[3] = _mm_srli_si128(ss[1], 8); - - temp = shuffle_filter_convolve8_8_ssse3(s, filter); - // shrink to 8 bit each 16 bits - temp = _mm_packus_epi16(temp, temp); - // save only 4 bytes - *(int *)dst = _mm_cvtsi128_si32(temp); -} - -static void transpose4x4_to_dst(const uint8_t *const src, - const ptrdiff_t src_stride, uint8_t *const dst, - const ptrdiff_t dst_stride) { - __m128i s[4]; - - load_8bit_4x4(src, src_stride, s); - s[0] = transpose_8bit_4x4(s); - s[1] = _mm_srli_si128(s[0], 4); - s[2] = _mm_srli_si128(s[0], 8); - s[3] = _mm_srli_si128(s[0], 12); - store_8bit_4x4(s, dst, dst_stride); -} - -static void scaledconvolve_horiz_w4(const uint8_t *src, - const ptrdiff_t src_stride, uint8_t *dst, - const ptrdiff_t dst_stride, - const InterpKernel *const x_filters, - const int x0_q4, const int x_step_q4, - const int w, const int h) { - DECLARE_ALIGNED(16, uint8_t, temp[4 * 4]); - int x, y, z; - src -= SUBPEL_TAPS / 2 - 1; - - for (y = 0; y < h; y += 4) { - int x_q4 = x0_q4; - for (x = 0; x < w; x += 4) { - // process 4 src_x steps - for (z = 0; z < 4; ++z) { - const uint8_t *const src_x = &src[x_q4 >> SUBPEL_BITS]; - const int16_t *const x_filter = x_filters[x_q4 & SUBPEL_MASK]; - if (x_q4 & SUBPEL_MASK) { - filter_horiz_w4_ssse3(src_x, src_stride, temp + (z * 4), x_filter); - } else { - int i; - for (i = 0; i < 4; ++i) { - temp[z * 4 + i] = src_x[i * src_stride + 3]; - } - } - x_q4 += x_step_q4; - } - - // transpose the 4x4 filters values back to dst - transpose4x4_to_dst(temp, 4, dst + x, dst_stride); - } - - src += src_stride * 4; - dst += dst_stride * 4; - } -} - -static __m128i filter_vert_kernel(const __m128i *const s, - const int16_t *const filter) { - __m128i ss[4]; - __m128i temp; - - // 00 10 01 11 02 12 03 13 - ss[0] = _mm_unpacklo_epi8(s[0], s[1]); - // 20 30 21 31 22 32 23 33 - ss[1] = _mm_unpacklo_epi8(s[2], s[3]); - // 40 50 41 51 42 52 43 53 - ss[2] = _mm_unpacklo_epi8(s[4], s[5]); - // 60 70 61 71 62 72 63 73 - ss[3] = _mm_unpacklo_epi8(s[6], s[7]); - - temp = shuffle_filter_convolve8_8_ssse3(ss, filter); - // shrink to 8 bit each 16 bits - return _mm_packus_epi16(temp, temp); -} - -static void filter_vert_w4_ssse3(const uint8_t *const src, - const ptrdiff_t src_stride, uint8_t *const dst, - const int16_t *const filter) { - __m128i s[8]; - __m128i temp; - - load_8bit_4x8(src, src_stride, s); - temp = filter_vert_kernel(s, filter); - // save only 4 bytes - *(int *)dst = _mm_cvtsi128_si32(temp); -} - -static void scaledconvolve_vert_w4( - const uint8_t *src, const ptrdiff_t src_stride, uint8_t *const dst, - const ptrdiff_t dst_stride, const InterpKernel *const y_filters, - const int y0_q4, const int y_step_q4, const int w, const int h) { - int y; - int y_q4 = y0_q4; - - src -= src_stride * (SUBPEL_TAPS / 2 - 1); - for (y = 0; y < h; ++y) { - const unsigned char *src_y = &src[(y_q4 >> SUBPEL_BITS) * src_stride]; - const int16_t *const y_filter = y_filters[y_q4 & SUBPEL_MASK]; - - if (y_q4 & SUBPEL_MASK) { - filter_vert_w4_ssse3(src_y, src_stride, &dst[y * dst_stride], y_filter); - } else { - memcpy(&dst[y * dst_stride], &src_y[3 * src_stride], w); - } - - y_q4 += y_step_q4; - } -} - -static void filter_vert_w8_ssse3(const uint8_t *const src, - const ptrdiff_t src_stride, uint8_t *const dst, - const int16_t *const filter) { - __m128i s[8], temp; - - load_8bit_8x8(src, src_stride, s); - temp = filter_vert_kernel(s, filter); - // save only 8 bytes convolve result - _mm_storel_epi64((__m128i *)dst, temp); -} - -static void scaledconvolve_vert_w8( - const uint8_t *src, const ptrdiff_t src_stride, uint8_t *const dst, - const ptrdiff_t dst_stride, const InterpKernel *const y_filters, - const int y0_q4, const int y_step_q4, const int w, const int h) { - int y; - int y_q4 = y0_q4; - - src -= src_stride * (SUBPEL_TAPS / 2 - 1); - for (y = 0; y < h; ++y) { - const unsigned char *src_y = &src[(y_q4 >> SUBPEL_BITS) * src_stride]; - const int16_t *const y_filter = y_filters[y_q4 & SUBPEL_MASK]; - if (y_q4 & SUBPEL_MASK) { - filter_vert_w8_ssse3(src_y, src_stride, &dst[y * dst_stride], y_filter); - } else { - memcpy(&dst[y * dst_stride], &src_y[3 * src_stride], w); - } - y_q4 += y_step_q4; - } -} - -static void filter_vert_w16_ssse3(const uint8_t *src, - const ptrdiff_t src_stride, - uint8_t *const dst, - const int16_t *const filter, const int w) { - int i; - __m128i f[4]; - shuffle_filter_ssse3(filter, f); - - for (i = 0; i < w; i += 16) { - __m128i s[8], s_lo[4], s_hi[4], temp_lo, temp_hi; - - loadu_8bit_16x8(src, src_stride, s); - - // merge the result together - s_lo[0] = _mm_unpacklo_epi8(s[0], s[1]); - s_hi[0] = _mm_unpackhi_epi8(s[0], s[1]); - s_lo[1] = _mm_unpacklo_epi8(s[2], s[3]); - s_hi[1] = _mm_unpackhi_epi8(s[2], s[3]); - s_lo[2] = _mm_unpacklo_epi8(s[4], s[5]); - s_hi[2] = _mm_unpackhi_epi8(s[4], s[5]); - s_lo[3] = _mm_unpacklo_epi8(s[6], s[7]); - s_hi[3] = _mm_unpackhi_epi8(s[6], s[7]); - temp_lo = convolve8_8_ssse3(s_lo, f); - temp_hi = convolve8_8_ssse3(s_hi, f); - - // shrink to 8 bit each 16 bits, the first lane contain the first convolve - // result and the second lane contain the second convolve result - temp_hi = _mm_packus_epi16(temp_lo, temp_hi); - src += 16; - // save 16 bytes convolve result - _mm_store_si128((__m128i *)&dst[i], temp_hi); - } -} - -static void scaledconvolve_vert_w16( - const uint8_t *src, const ptrdiff_t src_stride, uint8_t *const dst, - const ptrdiff_t dst_stride, const InterpKernel *const y_filters, - const int y0_q4, const int y_step_q4, const int w, const int h) { - int y; - int y_q4 = y0_q4; - - src -= src_stride * (SUBPEL_TAPS / 2 - 1); - for (y = 0; y < h; ++y) { - const unsigned char *src_y = &src[(y_q4 >> SUBPEL_BITS) * src_stride]; - const int16_t *const y_filter = y_filters[y_q4 & SUBPEL_MASK]; - if (y_q4 & SUBPEL_MASK) { - filter_vert_w16_ssse3(src_y, src_stride, &dst[y * dst_stride], y_filter, - w); - } else { - memcpy(&dst[y * dst_stride], &src_y[3 * src_stride], w); - } - y_q4 += y_step_q4; - } -} - -void vpx_scaled_2d_ssse3(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, - ptrdiff_t dst_stride, const InterpKernel *filter, - int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, - int w, int h) { - // Note: Fixed size intermediate buffer, temp, places limits on parameters. - // 2d filtering proceeds in 2 steps: - // (1) Interpolate horizontally into an intermediate buffer, temp. - // (2) Interpolate temp vertically to derive the sub-pixel result. - // Deriving the maximum number of rows in the temp buffer (135): - // --Smallest scaling factor is x1/2 ==> y_step_q4 = 32 (Normative). - // --Largest block size is 64x64 pixels. - // --64 rows in the downscaled frame span a distance of (64 - 1) * 32 in the - // original frame (in 1/16th pixel units). - // --Must round-up because block may be located at sub-pixel position. - // --Require an additional SUBPEL_TAPS rows for the 8-tap filter tails. - // --((64 - 1) * 32 + 15) >> 4 + 8 = 135. - // --Require an additional 8 rows for the horiz_w8 transpose tail. - // When calling in frame scaling function, the smallest scaling factor is x1/4 - // ==> y_step_q4 = 64. Since w and h are at most 16, the temp buffer is still - // big enough. - DECLARE_ALIGNED(16, uint8_t, temp[(135 + 8) * 64]); - const int intermediate_height = - (((h - 1) * y_step_q4 + y0_q4) >> SUBPEL_BITS) + SUBPEL_TAPS; - - assert(w <= 64); - assert(h <= 64); - assert(y_step_q4 <= 32 || (y_step_q4 <= 64 && h <= 32)); - assert(x_step_q4 <= 64); - - if (w >= 8) { - scaledconvolve_horiz_w8(src - src_stride * (SUBPEL_TAPS / 2 - 1), - src_stride, temp, 64, filter, x0_q4, x_step_q4, w, - intermediate_height); - } else { - scaledconvolve_horiz_w4(src - src_stride * (SUBPEL_TAPS / 2 - 1), - src_stride, temp, 64, filter, x0_q4, x_step_q4, w, - intermediate_height); - } - - if (w >= 16) { - scaledconvolve_vert_w16(temp + 64 * (SUBPEL_TAPS / 2 - 1), 64, dst, - dst_stride, filter, y0_q4, y_step_q4, w, h); - } else if (w == 8) { - scaledconvolve_vert_w8(temp + 64 * (SUBPEL_TAPS / 2 - 1), 64, dst, - dst_stride, filter, y0_q4, y_step_q4, w, h); - } else { - scaledconvolve_vert_w4(temp + 64 * (SUBPEL_TAPS / 2 - 1), 64, dst, - dst_stride, filter, y0_q4, y_step_q4, w, h); - } -} - -// void vpx_convolve8_ssse3(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, int y_step_q4, -// int w, int h); -// void vpx_convolve8_avg_ssse3(const uint8_t *src, ptrdiff_t src_stride, -// uint8_t *dst, ptrdiff_t dst_stride, -// const InterpKernel *filter, int x0_q4, -// int32_t x_step_q4, int y0_q4, int y_step_q4, -// int w, int h); -FUN_CONV_2D(, ssse3, 0) -FUN_CONV_2D(avg_, ssse3, 1) diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_8t_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_8t_sse2.asm deleted file mode 100644 index c8455e13..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_8t_sse2.asm +++ /dev/null @@ -1,989 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -;Note: tap3 and tap4 have to be applied and added after other taps to avoid -;overflow. - -%macro GET_FILTERS_4 0 - mov rdx, arg(5) ;filter ptr - mov rcx, 0x0400040 - - movdqa xmm7, [rdx] ;load filters - pshuflw xmm0, xmm7, 0b ;k0 - pshuflw xmm1, xmm7, 01010101b ;k1 - pshuflw xmm2, xmm7, 10101010b ;k2 - pshuflw xmm3, xmm7, 11111111b ;k3 - psrldq xmm7, 8 - pshuflw xmm4, xmm7, 0b ;k4 - pshuflw xmm5, xmm7, 01010101b ;k5 - pshuflw xmm6, xmm7, 10101010b ;k6 - pshuflw xmm7, xmm7, 11111111b ;k7 - - punpcklqdq xmm0, xmm1 - punpcklqdq xmm2, xmm3 - punpcklqdq xmm5, xmm4 - punpcklqdq xmm6, xmm7 - - movdqa k0k1, xmm0 - movdqa k2k3, xmm2 - movdqa k5k4, xmm5 - movdqa k6k7, xmm6 - - movq xmm6, rcx - pshufd xmm6, xmm6, 0 - movdqa krd, xmm6 - - pxor xmm7, xmm7 - movdqa zero, xmm7 -%endm - -%macro APPLY_FILTER_4 1 - punpckldq xmm0, xmm1 ;two row in one register - punpckldq xmm6, xmm7 - punpckldq xmm2, xmm3 - punpckldq xmm5, xmm4 - - punpcklbw xmm0, zero ;unpack to word - punpcklbw xmm6, zero - punpcklbw xmm2, zero - punpcklbw xmm5, zero - - pmullw xmm0, k0k1 ;multiply the filter factors - pmullw xmm6, k6k7 - pmullw xmm2, k2k3 - pmullw xmm5, k5k4 - - paddsw xmm0, xmm6 ;sum - movdqa xmm1, xmm0 - psrldq xmm1, 8 - paddsw xmm0, xmm1 - paddsw xmm0, xmm2 - psrldq xmm2, 8 - paddsw xmm0, xmm5 - psrldq xmm5, 8 - paddsw xmm0, xmm2 - paddsw xmm0, xmm5 - - paddsw xmm0, krd ;rounding - psraw xmm0, 7 ;shift - packuswb xmm0, xmm0 ;pack to byte - -%if %1 - movd xmm1, [rdi] - pavgb xmm0, xmm1 -%endif - movd [rdi], xmm0 -%endm - -%macro GET_FILTERS 0 - mov rdx, arg(5) ;filter ptr - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - mov rcx, 0x0400040 - - movdqa xmm7, [rdx] ;load filters - pshuflw xmm0, xmm7, 0b ;k0 - pshuflw xmm1, xmm7, 01010101b ;k1 - pshuflw xmm2, xmm7, 10101010b ;k2 - pshuflw xmm3, xmm7, 11111111b ;k3 - pshufhw xmm4, xmm7, 0b ;k4 - pshufhw xmm5, xmm7, 01010101b ;k5 - pshufhw xmm6, xmm7, 10101010b ;k6 - pshufhw xmm7, xmm7, 11111111b ;k7 - - punpcklwd xmm0, xmm0 - punpcklwd xmm1, xmm1 - punpcklwd xmm2, xmm2 - punpcklwd xmm3, xmm3 - punpckhwd xmm4, xmm4 - punpckhwd xmm5, xmm5 - punpckhwd xmm6, xmm6 - punpckhwd xmm7, xmm7 - - movdqa k0, xmm0 ;store filter factors on stack - movdqa k1, xmm1 - movdqa k2, xmm2 - movdqa k3, xmm3 - movdqa k4, xmm4 - movdqa k5, xmm5 - movdqa k6, xmm6 - movdqa k7, xmm7 - - movq xmm6, rcx - pshufd xmm6, xmm6, 0 - movdqa krd, xmm6 ;rounding - - pxor xmm7, xmm7 - movdqa zero, xmm7 -%endm - -%macro LOAD_VERT_8 1 - movq xmm0, [rsi + %1] ;0 - movq xmm1, [rsi + rax + %1] ;1 - movq xmm6, [rsi + rdx * 2 + %1] ;6 - lea rsi, [rsi + rax] - movq xmm7, [rsi + rdx * 2 + %1] ;7 - movq xmm2, [rsi + rax + %1] ;2 - movq xmm3, [rsi + rax * 2 + %1] ;3 - movq xmm4, [rsi + rdx + %1] ;4 - movq xmm5, [rsi + rax * 4 + %1] ;5 -%endm - -%macro APPLY_FILTER_8 2 - punpcklbw xmm0, zero - punpcklbw xmm1, zero - punpcklbw xmm6, zero - punpcklbw xmm7, zero - punpcklbw xmm2, zero - punpcklbw xmm5, zero - punpcklbw xmm3, zero - punpcklbw xmm4, zero - - pmullw xmm0, k0 - pmullw xmm1, k1 - pmullw xmm6, k6 - pmullw xmm7, k7 - pmullw xmm2, k2 - pmullw xmm5, k5 - pmullw xmm3, k3 - pmullw xmm4, k4 - - paddsw xmm0, xmm1 - paddsw xmm0, xmm6 - paddsw xmm0, xmm7 - paddsw xmm0, xmm2 - paddsw xmm0, xmm5 - paddsw xmm0, xmm3 - paddsw xmm0, xmm4 - - paddsw xmm0, krd ;rounding - psraw xmm0, 7 ;shift - packuswb xmm0, xmm0 ;pack back to byte -%if %1 - movq xmm1, [rdi + %2] - pavgb xmm0, xmm1 -%endif - movq [rdi + %2], xmm0 -%endm - -SECTION .text - -;void vpx_filter_block1d4_v8_sse2 -;( -; unsigned char *src_ptr, -; unsigned int src_pitch, -; unsigned char *output_ptr, -; unsigned int out_pitch, -; unsigned int output_height, -; short *filter -;) -globalsym(vpx_filter_block1d4_v8_sse2) -sym(vpx_filter_block1d4_v8_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - push rbx - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 6 - %define k0k1 [rsp + 16 * 0] - %define k2k3 [rsp + 16 * 1] - %define k5k4 [rsp + 16 * 2] - %define k6k7 [rsp + 16 * 3] - %define krd [rsp + 16 * 4] - %define zero [rsp + 16 * 5] - - GET_FILTERS_4 - - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rbx, DWORD PTR arg(3) ;out_pitch - lea rdx, [rax + rax * 2] - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - movd xmm0, [rsi] ;load src: row 0 - movd xmm1, [rsi + rax] ;1 - movd xmm6, [rsi + rdx * 2] ;6 - lea rsi, [rsi + rax] - movd xmm7, [rsi + rdx * 2] ;7 - movd xmm2, [rsi + rax] ;2 - movd xmm3, [rsi + rax * 2] ;3 - movd xmm4, [rsi + rdx] ;4 - movd xmm5, [rsi + rax * 4] ;5 - - APPLY_FILTER_4 0 - - lea rdi, [rdi + rbx] - dec rcx - jnz .loop - - add rsp, 16 * 6 - pop rsp - pop rbx - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -;void vpx_filter_block1d8_v8_sse2 -;( -; unsigned char *src_ptr, -; unsigned int src_pitch, -; unsigned char *output_ptr, -; unsigned int out_pitch, -; unsigned int output_height, -; short *filter -;) -globalsym(vpx_filter_block1d8_v8_sse2) -sym(vpx_filter_block1d8_v8_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - push rbx - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 10 - %define k0 [rsp + 16 * 0] - %define k1 [rsp + 16 * 1] - %define k2 [rsp + 16 * 2] - %define k3 [rsp + 16 * 3] - %define k4 [rsp + 16 * 4] - %define k5 [rsp + 16 * 5] - %define k6 [rsp + 16 * 6] - %define k7 [rsp + 16 * 7] - %define krd [rsp + 16 * 8] - %define zero [rsp + 16 * 9] - - GET_FILTERS - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rbx, DWORD PTR arg(3) ;out_pitch - lea rdx, [rax + rax * 2] - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - LOAD_VERT_8 0 - APPLY_FILTER_8 0, 0 - - lea rdi, [rdi + rbx] - dec rcx - jnz .loop - - add rsp, 16 * 10 - pop rsp - pop rbx - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -;void vpx_filter_block1d16_v8_sse2 -;( -; unsigned char *src_ptr, -; unsigned int src_pitch, -; unsigned char *output_ptr, -; unsigned int out_pitch, -; unsigned int output_height, -; short *filter -;) -globalsym(vpx_filter_block1d16_v8_sse2) -sym(vpx_filter_block1d16_v8_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - push rbx - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 10 - %define k0 [rsp + 16 * 0] - %define k1 [rsp + 16 * 1] - %define k2 [rsp + 16 * 2] - %define k3 [rsp + 16 * 3] - %define k4 [rsp + 16 * 4] - %define k5 [rsp + 16 * 5] - %define k6 [rsp + 16 * 6] - %define k7 [rsp + 16 * 7] - %define krd [rsp + 16 * 8] - %define zero [rsp + 16 * 9] - - GET_FILTERS - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rbx, DWORD PTR arg(3) ;out_pitch - lea rdx, [rax + rax * 2] - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - LOAD_VERT_8 0 - APPLY_FILTER_8 0, 0 - sub rsi, rax - - LOAD_VERT_8 8 - APPLY_FILTER_8 0, 8 - add rdi, rbx - - dec rcx - jnz .loop - - add rsp, 16 * 10 - pop rsp - pop rbx - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d4_v8_avg_sse2) -sym(vpx_filter_block1d4_v8_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - push rbx - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 6 - %define k0k1 [rsp + 16 * 0] - %define k2k3 [rsp + 16 * 1] - %define k5k4 [rsp + 16 * 2] - %define k6k7 [rsp + 16 * 3] - %define krd [rsp + 16 * 4] - %define zero [rsp + 16 * 5] - - GET_FILTERS_4 - - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rbx, DWORD PTR arg(3) ;out_pitch - lea rdx, [rax + rax * 2] - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - movd xmm0, [rsi] ;load src: row 0 - movd xmm1, [rsi + rax] ;1 - movd xmm6, [rsi + rdx * 2] ;6 - lea rsi, [rsi + rax] - movd xmm7, [rsi + rdx * 2] ;7 - movd xmm2, [rsi + rax] ;2 - movd xmm3, [rsi + rax * 2] ;3 - movd xmm4, [rsi + rdx] ;4 - movd xmm5, [rsi + rax * 4] ;5 - - APPLY_FILTER_4 1 - - lea rdi, [rdi + rbx] - dec rcx - jnz .loop - - add rsp, 16 * 6 - pop rsp - pop rbx - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d8_v8_avg_sse2) -sym(vpx_filter_block1d8_v8_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - push rbx - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 10 - %define k0 [rsp + 16 * 0] - %define k1 [rsp + 16 * 1] - %define k2 [rsp + 16 * 2] - %define k3 [rsp + 16 * 3] - %define k4 [rsp + 16 * 4] - %define k5 [rsp + 16 * 5] - %define k6 [rsp + 16 * 6] - %define k7 [rsp + 16 * 7] - %define krd [rsp + 16 * 8] - %define zero [rsp + 16 * 9] - - GET_FILTERS - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rbx, DWORD PTR arg(3) ;out_pitch - lea rdx, [rax + rax * 2] - movsxd rcx, DWORD PTR arg(4) ;output_height -.loop: - LOAD_VERT_8 0 - APPLY_FILTER_8 1, 0 - - lea rdi, [rdi + rbx] - dec rcx - jnz .loop - - add rsp, 16 * 10 - pop rsp - pop rbx - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d16_v8_avg_sse2) -sym(vpx_filter_block1d16_v8_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - push rbx - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 10 - %define k0 [rsp + 16 * 0] - %define k1 [rsp + 16 * 1] - %define k2 [rsp + 16 * 2] - %define k3 [rsp + 16 * 3] - %define k4 [rsp + 16 * 4] - %define k5 [rsp + 16 * 5] - %define k6 [rsp + 16 * 6] - %define k7 [rsp + 16 * 7] - %define krd [rsp + 16 * 8] - %define zero [rsp + 16 * 9] - - GET_FILTERS - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rbx, DWORD PTR arg(3) ;out_pitch - lea rdx, [rax + rax * 2] - movsxd rcx, DWORD PTR arg(4) ;output_height -.loop: - LOAD_VERT_8 0 - APPLY_FILTER_8 1, 0 - sub rsi, rax - - LOAD_VERT_8 8 - APPLY_FILTER_8 1, 8 - add rdi, rbx - - dec rcx - jnz .loop - - add rsp, 16 * 10 - pop rsp - pop rbx - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -;void vpx_filter_block1d4_h8_sse2 -;( -; unsigned char *src_ptr, -; unsigned int src_pixels_per_line, -; unsigned char *output_ptr, -; unsigned int output_pitch, -; unsigned int output_height, -; short *filter -;) -globalsym(vpx_filter_block1d4_h8_sse2) -sym(vpx_filter_block1d4_h8_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 6 - %define k0k1 [rsp + 16 * 0] - %define k2k3 [rsp + 16 * 1] - %define k5k4 [rsp + 16 * 2] - %define k6k7 [rsp + 16 * 3] - %define krd [rsp + 16 * 4] - %define zero [rsp + 16 * 5] - - GET_FILTERS_4 - - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - movdqu xmm0, [rsi - 3] ;load src - - movdqa xmm1, xmm0 - movdqa xmm6, xmm0 - movdqa xmm7, xmm0 - movdqa xmm2, xmm0 - movdqa xmm3, xmm0 - movdqa xmm5, xmm0 - movdqa xmm4, xmm0 - - psrldq xmm1, 1 - psrldq xmm6, 6 - psrldq xmm7, 7 - psrldq xmm2, 2 - psrldq xmm3, 3 - psrldq xmm5, 5 - psrldq xmm4, 4 - - APPLY_FILTER_4 0 - - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx - jnz .loop - - add rsp, 16 * 6 - pop rsp - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -;void vpx_filter_block1d8_h8_sse2 -;( -; unsigned char *src_ptr, -; unsigned int src_pixels_per_line, -; unsigned char *output_ptr, -; unsigned int output_pitch, -; unsigned int output_height, -; short *filter -;) -globalsym(vpx_filter_block1d8_h8_sse2) -sym(vpx_filter_block1d8_h8_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 10 - %define k0 [rsp + 16 * 0] - %define k1 [rsp + 16 * 1] - %define k2 [rsp + 16 * 2] - %define k3 [rsp + 16 * 3] - %define k4 [rsp + 16 * 4] - %define k5 [rsp + 16 * 5] - %define k6 [rsp + 16 * 6] - %define k7 [rsp + 16 * 7] - %define krd [rsp + 16 * 8] - %define zero [rsp + 16 * 9] - - GET_FILTERS - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - movdqu xmm0, [rsi - 3] ;load src - - movdqa xmm1, xmm0 - movdqa xmm6, xmm0 - movdqa xmm7, xmm0 - movdqa xmm2, xmm0 - movdqa xmm5, xmm0 - movdqa xmm3, xmm0 - movdqa xmm4, xmm0 - - psrldq xmm1, 1 - psrldq xmm6, 6 - psrldq xmm7, 7 - psrldq xmm2, 2 - psrldq xmm5, 5 - psrldq xmm3, 3 - psrldq xmm4, 4 - - APPLY_FILTER_8 0, 0 - - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx - jnz .loop - - add rsp, 16 * 10 - pop rsp - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -;void vpx_filter_block1d16_h8_sse2 -;( -; unsigned char *src_ptr, -; unsigned int src_pixels_per_line, -; unsigned char *output_ptr, -; unsigned int output_pitch, -; unsigned int output_height, -; short *filter -;) -globalsym(vpx_filter_block1d16_h8_sse2) -sym(vpx_filter_block1d16_h8_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 10 - %define k0 [rsp + 16 * 0] - %define k1 [rsp + 16 * 1] - %define k2 [rsp + 16 * 2] - %define k3 [rsp + 16 * 3] - %define k4 [rsp + 16 * 4] - %define k5 [rsp + 16 * 5] - %define k6 [rsp + 16 * 6] - %define k7 [rsp + 16 * 7] - %define krd [rsp + 16 * 8] - %define zero [rsp + 16 * 9] - - GET_FILTERS - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - movdqu xmm0, [rsi - 3] ;load src - - movdqa xmm1, xmm0 - movdqa xmm6, xmm0 - movdqa xmm7, xmm0 - movdqa xmm2, xmm0 - movdqa xmm5, xmm0 - movdqa xmm3, xmm0 - movdqa xmm4, xmm0 - - psrldq xmm1, 1 - psrldq xmm6, 6 - psrldq xmm7, 7 - psrldq xmm2, 2 - psrldq xmm5, 5 - psrldq xmm3, 3 - psrldq xmm4, 4 - - APPLY_FILTER_8 0, 0 - - movdqu xmm0, [rsi + 5] ;load src - - movdqa xmm1, xmm0 - movdqa xmm6, xmm0 - movdqa xmm7, xmm0 - movdqa xmm2, xmm0 - movdqa xmm5, xmm0 - movdqa xmm3, xmm0 - movdqa xmm4, xmm0 - - psrldq xmm1, 1 - psrldq xmm6, 6 - psrldq xmm7, 7 - psrldq xmm2, 2 - psrldq xmm5, 5 - psrldq xmm3, 3 - psrldq xmm4, 4 - - APPLY_FILTER_8 0, 8 - - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx - jnz .loop - - add rsp, 16 * 10 - pop rsp - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d4_h8_avg_sse2) -sym(vpx_filter_block1d4_h8_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 6 - %define k0k1 [rsp + 16 * 0] - %define k2k3 [rsp + 16 * 1] - %define k5k4 [rsp + 16 * 2] - %define k6k7 [rsp + 16 * 3] - %define krd [rsp + 16 * 4] - %define zero [rsp + 16 * 5] - - GET_FILTERS_4 - - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - movdqu xmm0, [rsi - 3] ;load src - - movdqa xmm1, xmm0 - movdqa xmm6, xmm0 - movdqa xmm7, xmm0 - movdqa xmm2, xmm0 - movdqa xmm3, xmm0 - movdqa xmm5, xmm0 - movdqa xmm4, xmm0 - - psrldq xmm1, 1 - psrldq xmm6, 6 - psrldq xmm7, 7 - psrldq xmm2, 2 - psrldq xmm3, 3 - psrldq xmm5, 5 - psrldq xmm4, 4 - - APPLY_FILTER_4 1 - - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx - jnz .loop - - add rsp, 16 * 6 - pop rsp - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d8_h8_avg_sse2) -sym(vpx_filter_block1d8_h8_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 10 - %define k0 [rsp + 16 * 0] - %define k1 [rsp + 16 * 1] - %define k2 [rsp + 16 * 2] - %define k3 [rsp + 16 * 3] - %define k4 [rsp + 16 * 4] - %define k5 [rsp + 16 * 5] - %define k6 [rsp + 16 * 6] - %define k7 [rsp + 16 * 7] - %define krd [rsp + 16 * 8] - %define zero [rsp + 16 * 9] - - GET_FILTERS - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - movdqu xmm0, [rsi - 3] ;load src - - movdqa xmm1, xmm0 - movdqa xmm6, xmm0 - movdqa xmm7, xmm0 - movdqa xmm2, xmm0 - movdqa xmm5, xmm0 - movdqa xmm3, xmm0 - movdqa xmm4, xmm0 - - psrldq xmm1, 1 - psrldq xmm6, 6 - psrldq xmm7, 7 - psrldq xmm2, 2 - psrldq xmm5, 5 - psrldq xmm3, 3 - psrldq xmm4, 4 - - APPLY_FILTER_8 1, 0 - - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx - jnz .loop - - add rsp, 16 * 10 - pop rsp - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d16_h8_avg_sse2) -sym(vpx_filter_block1d16_h8_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - ALIGN_STACK 16, rax - sub rsp, 16 * 10 - %define k0 [rsp + 16 * 0] - %define k1 [rsp + 16 * 1] - %define k2 [rsp + 16 * 2] - %define k3 [rsp + 16 * 3] - %define k4 [rsp + 16 * 4] - %define k5 [rsp + 16 * 5] - %define k6 [rsp + 16 * 6] - %define k7 [rsp + 16 * 7] - %define krd [rsp + 16 * 8] - %define zero [rsp + 16 * 9] - - GET_FILTERS - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - movsxd rcx, DWORD PTR arg(4) ;output_height - -.loop: - movdqu xmm0, [rsi - 3] ;load src - - movdqa xmm1, xmm0 - movdqa xmm6, xmm0 - movdqa xmm7, xmm0 - movdqa xmm2, xmm0 - movdqa xmm5, xmm0 - movdqa xmm3, xmm0 - movdqa xmm4, xmm0 - - psrldq xmm1, 1 - psrldq xmm6, 6 - psrldq xmm7, 7 - psrldq xmm2, 2 - psrldq xmm5, 5 - psrldq xmm3, 3 - psrldq xmm4, 4 - - APPLY_FILTER_8 1, 0 - - movdqu xmm0, [rsi + 5] ;load src - - movdqa xmm1, xmm0 - movdqa xmm6, xmm0 - movdqa xmm7, xmm0 - movdqa xmm2, xmm0 - movdqa xmm5, xmm0 - movdqa xmm3, xmm0 - movdqa xmm4, xmm0 - - psrldq xmm1, 1 - psrldq xmm6, 6 - psrldq xmm7, 7 - psrldq xmm2, 2 - psrldq xmm5, 5 - psrldq xmm3, 3 - psrldq xmm4, 4 - - APPLY_FILTER_8 1, 8 - - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx - jnz .loop - - add rsp, 16 * 10 - pop rsp - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_8t_ssse3.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_8t_ssse3.asm deleted file mode 100644 index fe617f12..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_8t_ssse3.asm +++ /dev/null @@ -1,803 +0,0 @@ -; -; Copyright (c) 2015 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "third_party/x86inc/x86inc.asm" - -SECTION_RODATA -pw_64: times 8 dw 64 - -; %define USE_PMULHRSW -; NOTE: pmulhrsw has a latency of 5 cycles. Tests showed a performance loss -; when using this instruction. -; -; The add order below (based on ffvp9) must be followed to prevent outranges. -; x = k0k1 + k4k5 -; y = k2k3 + k6k7 -; z = signed SAT(x + y) - -SECTION .text -%define LOCAL_VARS_SIZE 16*6 - -%macro SETUP_LOCAL_VARS 0 - ; TODO(slavarnway): using xmm registers for these on VPX_ARCH_X86_64 + - ; pmaddubsw has a higher latency on some platforms, this might be eased by - ; interleaving the instructions. - %define k0k1 [rsp + 16*0] - %define k2k3 [rsp + 16*1] - %define k4k5 [rsp + 16*2] - %define k6k7 [rsp + 16*3] - packsswb m4, m4 - ; TODO(slavarnway): multiple pshufb instructions had a higher latency on - ; some platforms. - pshuflw m0, m4, 0b ;k0_k1 - pshuflw m1, m4, 01010101b ;k2_k3 - pshuflw m2, m4, 10101010b ;k4_k5 - pshuflw m3, m4, 11111111b ;k6_k7 - punpcklqdq m0, m0 - punpcklqdq m1, m1 - punpcklqdq m2, m2 - punpcklqdq m3, m3 - mova k0k1, m0 - mova k2k3, m1 - mova k4k5, m2 - mova k6k7, m3 -%if VPX_ARCH_X86_64 - %define krd m12 - %define tmp0 [rsp + 16*4] - %define tmp1 [rsp + 16*5] - mova krd, [GLOBAL(pw_64)] -%else - %define krd [rsp + 16*4] -%if CONFIG_PIC=0 - mova m6, [GLOBAL(pw_64)] -%else - ; build constants without accessing global memory - pcmpeqb m6, m6 ;all ones - psrlw m6, 15 - psllw m6, 6 ;aka pw_64 -%endif - mova krd, m6 -%endif -%endm - -;------------------------------------------------------------------------------- -%if VPX_ARCH_X86_64 - %define LOCAL_VARS_SIZE_H4 0 -%else - %define LOCAL_VARS_SIZE_H4 16*4 -%endif - -%macro SUBPIX_HFILTER4 1 -cglobal filter_block1d4_%1, 6, 6, 11, LOCAL_VARS_SIZE_H4, \ - src, sstride, dst, dstride, height, filter - mova m4, [filterq] - packsswb m4, m4 -%if VPX_ARCH_X86_64 - %define k0k1k4k5 m8 - %define k2k3k6k7 m9 - %define krd m10 - mova krd, [GLOBAL(pw_64)] - pshuflw k0k1k4k5, m4, 0b ;k0_k1 - pshufhw k0k1k4k5, k0k1k4k5, 10101010b ;k0_k1_k4_k5 - pshuflw k2k3k6k7, m4, 01010101b ;k2_k3 - pshufhw k2k3k6k7, k2k3k6k7, 11111111b ;k2_k3_k6_k7 -%else - %define k0k1k4k5 [rsp + 16*0] - %define k2k3k6k7 [rsp + 16*1] - %define krd [rsp + 16*2] - pshuflw m6, m4, 0b ;k0_k1 - pshufhw m6, m6, 10101010b ;k0_k1_k4_k5 - pshuflw m7, m4, 01010101b ;k2_k3 - pshufhw m7, m7, 11111111b ;k2_k3_k6_k7 -%if CONFIG_PIC=0 - mova m1, [GLOBAL(pw_64)] -%else - ; build constants without accessing global memory - pcmpeqb m1, m1 ;all ones - psrlw m1, 15 - psllw m1, 6 ;aka pw_64 -%endif - mova k0k1k4k5, m6 - mova k2k3k6k7, m7 - mova krd, m1 -%endif - dec heightd - -.loop: - ;Do two rows at once - movu m4, [srcq - 3] - movu m5, [srcq + sstrideq - 3] - punpckhbw m1, m4, m4 - punpcklbw m4, m4 - punpckhbw m3, m5, m5 - punpcklbw m5, m5 - palignr m0, m1, m4, 1 - pmaddubsw m0, k0k1k4k5 - palignr m1, m4, 5 - pmaddubsw m1, k2k3k6k7 - palignr m2, m3, m5, 1 - pmaddubsw m2, k0k1k4k5 - palignr m3, m5, 5 - pmaddubsw m3, k2k3k6k7 - punpckhqdq m4, m0, m2 - punpcklqdq m0, m2 - punpckhqdq m5, m1, m3 - punpcklqdq m1, m3 - paddsw m0, m4 - paddsw m1, m5 -%ifidn %1, h8_avg - movd m4, [dstq] - movd m5, [dstq + dstrideq] -%endif - paddsw m0, m1 - paddsw m0, krd - psraw m0, 7 - packuswb m0, m0 - psrldq m1, m0, 4 - -%ifidn %1, h8_avg - pavgb m0, m4 - pavgb m1, m5 -%endif - movd [dstq], m0 - movd [dstq + dstrideq], m1 - - lea srcq, [srcq + sstrideq ] - prefetcht0 [srcq + 4 * sstrideq - 3] - lea srcq, [srcq + sstrideq ] - lea dstq, [dstq + 2 * dstrideq ] - prefetcht0 [srcq + 2 * sstrideq - 3] - - sub heightd, 2 - jg .loop - - ; Do last row if output_height is odd - jne .done - - movu m4, [srcq - 3] - punpckhbw m1, m4, m4 - punpcklbw m4, m4 - palignr m0, m1, m4, 1 - palignr m1, m4, 5 - pmaddubsw m0, k0k1k4k5 - pmaddubsw m1, k2k3k6k7 - psrldq m2, m0, 8 - psrldq m3, m1, 8 - paddsw m0, m2 - paddsw m1, m3 - paddsw m0, m1 - paddsw m0, krd - psraw m0, 7 - packuswb m0, m0 -%ifidn %1, h8_avg - movd m4, [dstq] - pavgb m0, m4 -%endif - movd [dstq], m0 -.done: - REP_RET -%endm - -;------------------------------------------------------------------------------- -%macro SUBPIX_HFILTER8 1 -cglobal filter_block1d8_%1, 6, 6, 14, LOCAL_VARS_SIZE, \ - src, sstride, dst, dstride, height, filter - mova m4, [filterq] - SETUP_LOCAL_VARS - dec heightd - -.loop: - ;Do two rows at once - movu m0, [srcq - 3] - movu m4, [srcq + sstrideq - 3] - punpckhbw m1, m0, m0 - punpcklbw m0, m0 - palignr m5, m1, m0, 13 - pmaddubsw m5, k6k7 - palignr m2, m1, m0, 5 - palignr m3, m1, m0, 9 - palignr m1, m0, 1 - pmaddubsw m1, k0k1 - punpckhbw m6, m4, m4 - punpcklbw m4, m4 - pmaddubsw m2, k2k3 - pmaddubsw m3, k4k5 - - palignr m7, m6, m4, 13 - palignr m0, m6, m4, 5 - pmaddubsw m7, k6k7 - paddsw m1, m3 - paddsw m2, m5 - paddsw m1, m2 -%ifidn %1, h8_avg - movh m2, [dstq] - movhps m2, [dstq + dstrideq] -%endif - palignr m5, m6, m4, 9 - palignr m6, m4, 1 - pmaddubsw m0, k2k3 - pmaddubsw m6, k0k1 - paddsw m1, krd - pmaddubsw m5, k4k5 - psraw m1, 7 - paddsw m0, m7 - paddsw m6, m5 - paddsw m6, m0 - paddsw m6, krd - psraw m6, 7 - packuswb m1, m6 -%ifidn %1, h8_avg - pavgb m1, m2 -%endif - movh [dstq], m1 - movhps [dstq + dstrideq], m1 - - lea srcq, [srcq + sstrideq ] - prefetcht0 [srcq + 4 * sstrideq - 3] - lea srcq, [srcq + sstrideq ] - lea dstq, [dstq + 2 * dstrideq ] - prefetcht0 [srcq + 2 * sstrideq - 3] - sub heightd, 2 - jg .loop - - ; Do last row if output_height is odd - jne .done - - movu m0, [srcq - 3] - punpckhbw m3, m0, m0 - punpcklbw m0, m0 - palignr m1, m3, m0, 1 - palignr m2, m3, m0, 5 - palignr m4, m3, m0, 13 - palignr m3, m0, 9 - pmaddubsw m1, k0k1 - pmaddubsw m2, k2k3 - pmaddubsw m3, k4k5 - pmaddubsw m4, k6k7 - paddsw m1, m3 - paddsw m4, m2 - paddsw m1, m4 - paddsw m1, krd - psraw m1, 7 - packuswb m1, m1 -%ifidn %1, h8_avg - movh m0, [dstq] - pavgb m1, m0 -%endif - movh [dstq], m1 -.done: - REP_RET -%endm - -;------------------------------------------------------------------------------- -%macro SUBPIX_HFILTER16 1 -cglobal filter_block1d16_%1, 6, 6, 14, LOCAL_VARS_SIZE, \ - src, sstride, dst, dstride, height, filter - mova m4, [filterq] - SETUP_LOCAL_VARS - -.loop: - prefetcht0 [srcq + 2 * sstrideq -3] - - movu m0, [srcq - 3] - movu m4, [srcq - 2] - pmaddubsw m0, k0k1 - pmaddubsw m4, k0k1 - movu m1, [srcq - 1] - movu m5, [srcq + 0] - pmaddubsw m1, k2k3 - pmaddubsw m5, k2k3 - movu m2, [srcq + 1] - movu m6, [srcq + 2] - pmaddubsw m2, k4k5 - pmaddubsw m6, k4k5 - movu m3, [srcq + 3] - movu m7, [srcq + 4] - pmaddubsw m3, k6k7 - pmaddubsw m7, k6k7 - paddsw m0, m2 - paddsw m1, m3 - paddsw m0, m1 - paddsw m4, m6 - paddsw m5, m7 - paddsw m4, m5 - paddsw m0, krd - paddsw m4, krd - psraw m0, 7 - psraw m4, 7 - packuswb m0, m0 - packuswb m4, m4 - punpcklbw m0, m4 -%ifidn %1, h8_avg - pavgb m0, [dstq] -%endif - lea srcq, [srcq + sstrideq] - mova [dstq], m0 - lea dstq, [dstq + dstrideq] - dec heightd - jnz .loop - REP_RET -%endm - -INIT_XMM ssse3 -SUBPIX_HFILTER16 h8 ; vpx_filter_block1d16_h8_ssse3 -SUBPIX_HFILTER16 h8_avg ; vpx_filter_block1d16_h8_avg_ssse3 -SUBPIX_HFILTER8 h8 ; vpx_filter_block1d8_h8_ssse3 -SUBPIX_HFILTER8 h8_avg ; vpx_filter_block1d8_h8_avg_ssse3 -SUBPIX_HFILTER4 h8 ; vpx_filter_block1d4_h8_ssse3 -SUBPIX_HFILTER4 h8_avg ; vpx_filter_block1d4_h8_avg_ssse3 - -;------------------------------------------------------------------------------- - -; TODO(Linfeng): Detect cpu type and choose the code with better performance. -%define X86_SUBPIX_VFILTER_PREFER_SLOW_CELERON 1 - -%if VPX_ARCH_X86_64 && X86_SUBPIX_VFILTER_PREFER_SLOW_CELERON - %define NUM_GENERAL_REG_USED 9 -%else - %define NUM_GENERAL_REG_USED 6 -%endif - -%macro SUBPIX_VFILTER 2 -cglobal filter_block1d%2_%1, 6, NUM_GENERAL_REG_USED, 15, LOCAL_VARS_SIZE, \ - src, sstride, dst, dstride, height, filter - mova m4, [filterq] - SETUP_LOCAL_VARS - -%ifidn %2, 8 - %define movx movh -%else - %define movx movd -%endif - - dec heightd - -%if VPX_ARCH_X86 || X86_SUBPIX_VFILTER_PREFER_SLOW_CELERON - -%if VPX_ARCH_X86_64 - %define src1q r7 - %define sstride6q r8 - %define dst_stride dstrideq -%else - %define src1q filterq - %define sstride6q dstrideq - %define dst_stride dstridemp -%endif - mov src1q, srcq - add src1q, sstrideq - lea sstride6q, [sstrideq + sstrideq * 4] - add sstride6q, sstrideq ;pitch * 6 - -.loop: - ;Do two rows at once - movx m0, [srcq ] ;A - movx m1, [src1q ] ;B - punpcklbw m0, m1 ;A B - movx m2, [srcq + sstrideq * 2 ] ;C - pmaddubsw m0, k0k1 - mova m6, m2 - movx m3, [src1q + sstrideq * 2] ;D - punpcklbw m2, m3 ;C D - pmaddubsw m2, k2k3 - movx m4, [srcq + sstrideq * 4 ] ;E - mova m7, m4 - movx m5, [src1q + sstrideq * 4] ;F - punpcklbw m4, m5 ;E F - pmaddubsw m4, k4k5 - punpcklbw m1, m6 ;A B next iter - movx m6, [srcq + sstride6q ] ;G - punpcklbw m5, m6 ;E F next iter - punpcklbw m3, m7 ;C D next iter - pmaddubsw m5, k4k5 - movx m7, [src1q + sstride6q ] ;H - punpcklbw m6, m7 ;G H - pmaddubsw m6, k6k7 - pmaddubsw m3, k2k3 - pmaddubsw m1, k0k1 - paddsw m0, m4 - paddsw m2, m6 - movx m6, [srcq + sstrideq * 8 ] ;H next iter - punpcklbw m7, m6 - pmaddubsw m7, k6k7 - paddsw m0, m2 - paddsw m0, krd - psraw m0, 7 - paddsw m1, m5 - packuswb m0, m0 - - paddsw m3, m7 - paddsw m1, m3 - paddsw m1, krd - psraw m1, 7 - lea srcq, [srcq + sstrideq * 2 ] - lea src1q, [src1q + sstrideq * 2] - packuswb m1, m1 - -%ifidn %1, v8_avg - movx m2, [dstq] - pavgb m0, m2 -%endif - movx [dstq], m0 - add dstq, dst_stride -%ifidn %1, v8_avg - movx m3, [dstq] - pavgb m1, m3 -%endif - movx [dstq], m1 - add dstq, dst_stride - sub heightd, 2 - jg .loop - - ; Do last row if output_height is odd - jne .done - - movx m0, [srcq ] ;A - movx m1, [srcq + sstrideq ] ;B - movx m6, [srcq + sstride6q ] ;G - punpcklbw m0, m1 ;A B - movx m7, [src1q + sstride6q ] ;H - pmaddubsw m0, k0k1 - movx m2, [srcq + sstrideq * 2 ] ;C - punpcklbw m6, m7 ;G H - movx m3, [src1q + sstrideq * 2] ;D - pmaddubsw m6, k6k7 - movx m4, [srcq + sstrideq * 4 ] ;E - punpcklbw m2, m3 ;C D - movx m5, [src1q + sstrideq * 4] ;F - punpcklbw m4, m5 ;E F - pmaddubsw m2, k2k3 - pmaddubsw m4, k4k5 - paddsw m2, m6 - paddsw m0, m4 - paddsw m0, m2 - paddsw m0, krd - psraw m0, 7 - packuswb m0, m0 -%ifidn %1, v8_avg - movx m1, [dstq] - pavgb m0, m1 -%endif - movx [dstq], m0 - -%else - ; VPX_ARCH_X86_64 - - movx m0, [srcq ] ;A - movx m1, [srcq + sstrideq ] ;B - lea srcq, [srcq + sstrideq * 2 ] - movx m2, [srcq] ;C - movx m3, [srcq + sstrideq] ;D - lea srcq, [srcq + sstrideq * 2 ] - movx m4, [srcq] ;E - movx m5, [srcq + sstrideq] ;F - lea srcq, [srcq + sstrideq * 2 ] - movx m6, [srcq] ;G - punpcklbw m0, m1 ;A B - punpcklbw m1, m2 ;A B next iter - punpcklbw m2, m3 ;C D - punpcklbw m3, m4 ;C D next iter - punpcklbw m4, m5 ;E F - punpcklbw m5, m6 ;E F next iter - -.loop: - ;Do two rows at once - movx m7, [srcq + sstrideq] ;H - lea srcq, [srcq + sstrideq * 2 ] - movx m14, [srcq] ;H next iter - punpcklbw m6, m7 ;G H - punpcklbw m7, m14 ;G H next iter - pmaddubsw m8, m0, k0k1 - pmaddubsw m9, m1, k0k1 - mova m0, m2 - mova m1, m3 - pmaddubsw m10, m2, k2k3 - pmaddubsw m11, m3, k2k3 - mova m2, m4 - mova m3, m5 - pmaddubsw m4, k4k5 - pmaddubsw m5, k4k5 - paddsw m8, m4 - paddsw m9, m5 - mova m4, m6 - mova m5, m7 - pmaddubsw m6, k6k7 - pmaddubsw m7, k6k7 - paddsw m10, m6 - paddsw m11, m7 - paddsw m8, m10 - paddsw m9, m11 - mova m6, m14 - paddsw m8, krd - paddsw m9, krd - psraw m8, 7 - psraw m9, 7 -%ifidn %2, 4 - packuswb m8, m8 - packuswb m9, m9 -%else - packuswb m8, m9 -%endif - -%ifidn %1, v8_avg - movx m7, [dstq] -%ifidn %2, 4 - movx m10, [dstq + dstrideq] - pavgb m9, m10 -%else - movhpd m7, [dstq + dstrideq] -%endif - pavgb m8, m7 -%endif - movx [dstq], m8 -%ifidn %2, 4 - movx [dstq + dstrideq], m9 -%else - movhpd [dstq + dstrideq], m8 -%endif - - lea dstq, [dstq + dstrideq * 2 ] - sub heightd, 2 - jg .loop - - ; Do last row if output_height is odd - jne .done - - movx m7, [srcq + sstrideq] ;H - punpcklbw m6, m7 ;G H - pmaddubsw m0, k0k1 - pmaddubsw m2, k2k3 - pmaddubsw m4, k4k5 - pmaddubsw m6, k6k7 - paddsw m0, m4 - paddsw m2, m6 - paddsw m0, m2 - paddsw m0, krd - psraw m0, 7 - packuswb m0, m0 -%ifidn %1, v8_avg - movx m1, [dstq] - pavgb m0, m1 -%endif - movx [dstq], m0 - -%endif ; VPX_ARCH_X86_64 - -.done: - REP_RET - -%endm - -;------------------------------------------------------------------------------- -%macro SUBPIX_VFILTER16 1 -cglobal filter_block1d16_%1, 6, NUM_GENERAL_REG_USED, 16, LOCAL_VARS_SIZE, \ - src, sstride, dst, dstride, height, filter - mova m4, [filterq] - SETUP_LOCAL_VARS - -%if VPX_ARCH_X86 || X86_SUBPIX_VFILTER_PREFER_SLOW_CELERON - -%if VPX_ARCH_X86_64 - %define src1q r7 - %define sstride6q r8 - %define dst_stride dstrideq -%else - %define src1q filterq - %define sstride6q dstrideq - %define dst_stride dstridemp -%endif - lea src1q, [srcq + sstrideq] - lea sstride6q, [sstrideq + sstrideq * 4] - add sstride6q, sstrideq ;pitch * 6 - -.loop: - movh m0, [srcq ] ;A - movh m1, [src1q ] ;B - movh m2, [srcq + sstrideq * 2 ] ;C - movh m3, [src1q + sstrideq * 2] ;D - movh m4, [srcq + sstrideq * 4 ] ;E - movh m5, [src1q + sstrideq * 4] ;F - - punpcklbw m0, m1 ;A B - movh m6, [srcq + sstride6q] ;G - punpcklbw m2, m3 ;C D - movh m7, [src1q + sstride6q] ;H - punpcklbw m4, m5 ;E F - pmaddubsw m0, k0k1 - movh m3, [srcq + 8] ;A - pmaddubsw m2, k2k3 - punpcklbw m6, m7 ;G H - movh m5, [srcq + sstrideq + 8] ;B - pmaddubsw m4, k4k5 - punpcklbw m3, m5 ;A B - movh m7, [srcq + sstrideq * 2 + 8] ;C - pmaddubsw m6, k6k7 - movh m5, [src1q + sstrideq * 2 + 8] ;D - punpcklbw m7, m5 ;C D - paddsw m2, m6 - pmaddubsw m3, k0k1 - movh m1, [srcq + sstrideq * 4 + 8] ;E - paddsw m0, m4 - pmaddubsw m7, k2k3 - movh m6, [src1q + sstrideq * 4 + 8] ;F - punpcklbw m1, m6 ;E F - paddsw m0, m2 - paddsw m0, krd - movh m2, [srcq + sstride6q + 8] ;G - pmaddubsw m1, k4k5 - movh m5, [src1q + sstride6q + 8] ;H - psraw m0, 7 - punpcklbw m2, m5 ;G H - pmaddubsw m2, k6k7 - paddsw m7, m2 - paddsw m3, m1 - paddsw m3, m7 - paddsw m3, krd - psraw m3, 7 - packuswb m0, m3 - - add srcq, sstrideq - add src1q, sstrideq -%ifidn %1, v8_avg - pavgb m0, [dstq] -%endif - mova [dstq], m0 - add dstq, dst_stride - dec heightd - jnz .loop - REP_RET - -%else - ; VPX_ARCH_X86_64 - dec heightd - - movu m1, [srcq ] ;A - movu m3, [srcq + sstrideq ] ;B - lea srcq, [srcq + sstrideq * 2] - punpcklbw m0, m1, m3 ;A B - punpckhbw m1, m3 ;A B - movu m5, [srcq] ;C - punpcklbw m2, m3, m5 ;A B next iter - punpckhbw m3, m5 ;A B next iter - mova tmp0, m2 ;store to stack - mova tmp1, m3 ;store to stack - movu m7, [srcq + sstrideq] ;D - lea srcq, [srcq + sstrideq * 2] - punpcklbw m4, m5, m7 ;C D - punpckhbw m5, m7 ;C D - movu m9, [srcq] ;E - punpcklbw m6, m7, m9 ;C D next iter - punpckhbw m7, m9 ;C D next iter - movu m11, [srcq + sstrideq] ;F - lea srcq, [srcq + sstrideq * 2] - punpcklbw m8, m9, m11 ;E F - punpckhbw m9, m11 ;E F - movu m2, [srcq] ;G - punpcklbw m10, m11, m2 ;E F next iter - punpckhbw m11, m2 ;E F next iter - -.loop: - ;Do two rows at once - pmaddubsw m13, m0, k0k1 - mova m0, m4 - pmaddubsw m14, m8, k4k5 - pmaddubsw m15, m4, k2k3 - mova m4, m8 - paddsw m13, m14 - movu m3, [srcq + sstrideq] ;H - lea srcq, [srcq + sstrideq * 2] - punpcklbw m14, m2, m3 ;G H - mova m8, m14 - pmaddubsw m14, k6k7 - paddsw m15, m14 - paddsw m13, m15 - paddsw m13, krd - psraw m13, 7 - - pmaddubsw m14, m1, k0k1 - pmaddubsw m1, m9, k4k5 - pmaddubsw m15, m5, k2k3 - paddsw m14, m1 - mova m1, m5 - mova m5, m9 - punpckhbw m2, m3 ;G H - mova m9, m2 - pmaddubsw m2, k6k7 - paddsw m15, m2 - paddsw m14, m15 - paddsw m14, krd - psraw m14, 7 - packuswb m13, m14 -%ifidn %1, v8_avg - pavgb m13, [dstq] -%endif - mova [dstq], m13 - - ; next iter - pmaddubsw m15, tmp0, k0k1 - pmaddubsw m14, m10, k4k5 - pmaddubsw m13, m6, k2k3 - paddsw m15, m14 - mova tmp0, m6 - mova m6, m10 - movu m2, [srcq] ;G next iter - punpcklbw m14, m3, m2 ;G H next iter - mova m10, m14 - pmaddubsw m14, k6k7 - paddsw m13, m14 - paddsw m15, m13 - paddsw m15, krd - psraw m15, 7 - - pmaddubsw m14, tmp1, k0k1 - mova tmp1, m7 - pmaddubsw m13, m7, k2k3 - mova m7, m11 - pmaddubsw m11, k4k5 - paddsw m14, m11 - punpckhbw m3, m2 ;G H next iter - mova m11, m3 - pmaddubsw m3, k6k7 - paddsw m13, m3 - paddsw m14, m13 - paddsw m14, krd - psraw m14, 7 - packuswb m15, m14 -%ifidn %1, v8_avg - pavgb m15, [dstq + dstrideq] -%endif - mova [dstq + dstrideq], m15 - lea dstq, [dstq + dstrideq * 2] - sub heightd, 2 - jg .loop - - ; Do last row if output_height is odd - jne .done - - movu m3, [srcq + sstrideq] ;H - punpcklbw m6, m2, m3 ;G H - punpckhbw m2, m3 ;G H - pmaddubsw m0, k0k1 - pmaddubsw m1, k0k1 - pmaddubsw m4, k2k3 - pmaddubsw m5, k2k3 - pmaddubsw m8, k4k5 - pmaddubsw m9, k4k5 - pmaddubsw m6, k6k7 - pmaddubsw m2, k6k7 - paddsw m0, m8 - paddsw m1, m9 - paddsw m4, m6 - paddsw m5, m2 - paddsw m0, m4 - paddsw m1, m5 - paddsw m0, krd - paddsw m1, krd - psraw m0, 7 - psraw m1, 7 - packuswb m0, m1 -%ifidn %1, v8_avg - pavgb m0, [dstq] -%endif - mova [dstq], m0 - -.done: - REP_RET - -%endif ; VPX_ARCH_X86_64 - -%endm - -INIT_XMM ssse3 -SUBPIX_VFILTER16 v8 ; vpx_filter_block1d16_v8_ssse3 -SUBPIX_VFILTER16 v8_avg ; vpx_filter_block1d16_v8_avg_ssse3 -SUBPIX_VFILTER v8, 8 ; vpx_filter_block1d8_v8_ssse3 -SUBPIX_VFILTER v8_avg, 8 ; vpx_filter_block1d8_v8_avg_ssse3 -SUBPIX_VFILTER v8, 4 ; vpx_filter_block1d4_v8_ssse3 -SUBPIX_VFILTER v8_avg, 4 ; vpx_filter_block1d4_v8_avg_ssse3 diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_sse2.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_sse2.asm deleted file mode 100644 index 65790b1c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_sse2.asm +++ /dev/null @@ -1,450 +0,0 @@ -; -; Copyright (c) 2014 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "vpx_ports/x86_abi_support.asm" - -%macro GET_PARAM_4 0 - mov rdx, arg(5) ;filter ptr - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - mov rcx, 0x0400040 - - movdqa xmm3, [rdx] ;load filters - pshuflw xmm4, xmm3, 11111111b ;k3 - psrldq xmm3, 8 - pshuflw xmm3, xmm3, 0b ;k4 - punpcklqdq xmm4, xmm3 ;k3k4 - - movq xmm3, rcx ;rounding - pshufd xmm3, xmm3, 0 - - pxor xmm2, xmm2 - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - movsxd rcx, DWORD PTR arg(4) ;output_height -%endm - -%macro APPLY_FILTER_4 1 - - punpckldq xmm0, xmm1 ;two row in one register - punpcklbw xmm0, xmm2 ;unpack to word - pmullw xmm0, xmm4 ;multiply the filter factors - - movdqa xmm1, xmm0 - psrldq xmm1, 8 - paddsw xmm0, xmm1 - - paddsw xmm0, xmm3 ;rounding - psraw xmm0, 7 ;shift - packuswb xmm0, xmm0 ;pack to byte - -%if %1 - movd xmm1, [rdi] - pavgb xmm0, xmm1 -%endif - - movd [rdi], xmm0 - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx -%endm - -%macro GET_PARAM 0 - mov rdx, arg(5) ;filter ptr - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - mov rcx, 0x0400040 - - movdqa xmm7, [rdx] ;load filters - - pshuflw xmm6, xmm7, 11111111b ;k3 - pshufhw xmm7, xmm7, 0b ;k4 - punpcklwd xmm6, xmm6 - punpckhwd xmm7, xmm7 - - movq xmm4, rcx ;rounding - pshufd xmm4, xmm4, 0 - - pxor xmm5, xmm5 - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - movsxd rcx, DWORD PTR arg(4) ;output_height -%endm - -%macro APPLY_FILTER_8 1 - punpcklbw xmm0, xmm5 - punpcklbw xmm1, xmm5 - - pmullw xmm0, xmm6 - pmullw xmm1, xmm7 - paddsw xmm0, xmm1 - paddsw xmm0, xmm4 ;rounding - psraw xmm0, 7 ;shift - packuswb xmm0, xmm0 ;pack back to byte -%if %1 - movq xmm1, [rdi] - pavgb xmm0, xmm1 -%endif - movq [rdi], xmm0 ;store the result - - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx -%endm - -%macro APPLY_FILTER_16 1 - punpcklbw xmm0, xmm5 - punpcklbw xmm1, xmm5 - punpckhbw xmm2, xmm5 - punpckhbw xmm3, xmm5 - - pmullw xmm0, xmm6 - pmullw xmm1, xmm7 - pmullw xmm2, xmm6 - pmullw xmm3, xmm7 - - paddsw xmm0, xmm1 - paddsw xmm2, xmm3 - - paddsw xmm0, xmm4 ;rounding - paddsw xmm2, xmm4 - psraw xmm0, 7 ;shift - psraw xmm2, 7 - packuswb xmm0, xmm2 ;pack back to byte -%if %1 - movdqu xmm1, [rdi] - pavgb xmm0, xmm1 -%endif - movdqu [rdi], xmm0 ;store the result - - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx -%endm - -SECTION .text - -globalsym(vpx_filter_block1d4_v2_sse2) -sym(vpx_filter_block1d4_v2_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - push rsi - push rdi - ; end prolog - - GET_PARAM_4 -.loop: - movd xmm0, [rsi] ;load src - movd xmm1, [rsi + rax] - - APPLY_FILTER_4 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d8_v2_sse2) -sym(vpx_filter_block1d8_v2_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - GET_PARAM -.loop: - movq xmm0, [rsi] ;0 - movq xmm1, [rsi + rax] ;1 - - APPLY_FILTER_8 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d16_v2_sse2) -sym(vpx_filter_block1d16_v2_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - GET_PARAM -.loop: - movdqu xmm0, [rsi] ;0 - movdqu xmm1, [rsi + rax] ;1 - movdqa xmm2, xmm0 - movdqa xmm3, xmm1 - - APPLY_FILTER_16 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d4_v2_avg_sse2) -sym(vpx_filter_block1d4_v2_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - push rsi - push rdi - ; end prolog - - GET_PARAM_4 -.loop: - movd xmm0, [rsi] ;load src - movd xmm1, [rsi + rax] - - APPLY_FILTER_4 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d8_v2_avg_sse2) -sym(vpx_filter_block1d8_v2_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - GET_PARAM -.loop: - movq xmm0, [rsi] ;0 - movq xmm1, [rsi + rax] ;1 - - APPLY_FILTER_8 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d16_v2_avg_sse2) -sym(vpx_filter_block1d16_v2_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - GET_PARAM -.loop: - movdqu xmm0, [rsi] ;0 - movdqu xmm1, [rsi + rax] ;1 - movdqa xmm2, xmm0 - movdqa xmm3, xmm1 - - APPLY_FILTER_16 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d4_h2_sse2) -sym(vpx_filter_block1d4_h2_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - push rsi - push rdi - ; end prolog - - GET_PARAM_4 -.loop: - movdqu xmm0, [rsi] ;load src - movdqa xmm1, xmm0 - psrldq xmm1, 1 - - APPLY_FILTER_4 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d8_h2_sse2) -sym(vpx_filter_block1d8_h2_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - GET_PARAM -.loop: - movdqu xmm0, [rsi] ;load src - movdqa xmm1, xmm0 - psrldq xmm1, 1 - - APPLY_FILTER_8 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d16_h2_sse2) -sym(vpx_filter_block1d16_h2_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - GET_PARAM -.loop: - movdqu xmm0, [rsi] ;load src - movdqu xmm1, [rsi + 1] - movdqa xmm2, xmm0 - movdqa xmm3, xmm1 - - APPLY_FILTER_16 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d4_h2_avg_sse2) -sym(vpx_filter_block1d4_h2_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - push rsi - push rdi - ; end prolog - - GET_PARAM_4 -.loop: - movdqu xmm0, [rsi] ;load src - movdqa xmm1, xmm0 - psrldq xmm1, 1 - - APPLY_FILTER_4 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d8_h2_avg_sse2) -sym(vpx_filter_block1d8_h2_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - GET_PARAM -.loop: - movdqu xmm0, [rsi] ;load src - movdqa xmm1, xmm0 - psrldq xmm1, 1 - - APPLY_FILTER_8 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d16_h2_avg_sse2) -sym(vpx_filter_block1d16_h2_avg_sse2): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - GET_PARAM -.loop: - movdqu xmm0, [rsi] ;load src - movdqu xmm1, [rsi + 1] - movdqa xmm2, xmm0 - movdqa xmm3, xmm1 - - APPLY_FILTER_16 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_ssse3.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_ssse3.asm deleted file mode 100644 index 32e3cd3d..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_dsp/x86/vpx_subpixel_bilinear_ssse3.asm +++ /dev/null @@ -1,420 +0,0 @@ -; -; Copyright (c) 2014 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - -%include "vpx_ports/x86_abi_support.asm" - -%macro GET_PARAM_4 0 - mov rdx, arg(5) ;filter ptr - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - mov ecx, 0x01000100 - - movdqa xmm3, [rdx] ;load filters - psrldq xmm3, 6 - packsswb xmm3, xmm3 - pshuflw xmm3, xmm3, 0b ;k3_k4 - - movd xmm2, ecx ;rounding_shift - pshufd xmm2, xmm2, 0 - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - movsxd rcx, DWORD PTR arg(4) ;output_height -%endm - -%macro APPLY_FILTER_4 1 - punpcklbw xmm0, xmm1 - pmaddubsw xmm0, xmm3 - - pmulhrsw xmm0, xmm2 ;rounding(+64)+shift(>>7) - packuswb xmm0, xmm0 ;pack to byte - -%if %1 - movd xmm1, [rdi] - pavgb xmm0, xmm1 -%endif - movd [rdi], xmm0 - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx -%endm - -%macro GET_PARAM 0 - mov rdx, arg(5) ;filter ptr - mov rsi, arg(0) ;src_ptr - mov rdi, arg(2) ;output_ptr - mov ecx, 0x01000100 - - movdqa xmm7, [rdx] ;load filters - psrldq xmm7, 6 - packsswb xmm7, xmm7 - pshuflw xmm7, xmm7, 0b ;k3_k4 - punpcklwd xmm7, xmm7 - - movd xmm6, ecx ;rounding_shift - pshufd xmm6, xmm6, 0 - - movsxd rax, DWORD PTR arg(1) ;pixels_per_line - movsxd rdx, DWORD PTR arg(3) ;out_pitch - movsxd rcx, DWORD PTR arg(4) ;output_height -%endm - -%macro APPLY_FILTER_8 1 - punpcklbw xmm0, xmm1 - pmaddubsw xmm0, xmm7 - - pmulhrsw xmm0, xmm6 ;rounding(+64)+shift(>>7) - packuswb xmm0, xmm0 ;pack back to byte - -%if %1 - movq xmm1, [rdi] - pavgb xmm0, xmm1 -%endif - movq [rdi], xmm0 ;store the result - - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx -%endm - -%macro APPLY_FILTER_16 1 - punpcklbw xmm0, xmm1 - punpckhbw xmm2, xmm1 - pmaddubsw xmm0, xmm7 - pmaddubsw xmm2, xmm7 - - pmulhrsw xmm0, xmm6 ;rounding(+64)+shift(>>7) - pmulhrsw xmm2, xmm6 - packuswb xmm0, xmm2 ;pack back to byte - -%if %1 - movdqu xmm1, [rdi] - pavgb xmm0, xmm1 -%endif - movdqu [rdi], xmm0 ;store the result - - lea rsi, [rsi + rax] - lea rdi, [rdi + rdx] - dec rcx -%endm - -SECTION .text - -globalsym(vpx_filter_block1d4_v2_ssse3) -sym(vpx_filter_block1d4_v2_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - push rsi - push rdi - ; end prolog - - GET_PARAM_4 -.loop: - movd xmm0, [rsi] ;load src - movd xmm1, [rsi + rax] - - APPLY_FILTER_4 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d8_v2_ssse3) -sym(vpx_filter_block1d8_v2_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - GET_PARAM -.loop: - movq xmm0, [rsi] ;0 - movq xmm1, [rsi + rax] ;1 - - APPLY_FILTER_8 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d16_v2_ssse3) -sym(vpx_filter_block1d16_v2_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - GET_PARAM -.loop: - movdqu xmm0, [rsi] ;0 - movdqu xmm1, [rsi + rax] ;1 - movdqa xmm2, xmm0 - - APPLY_FILTER_16 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d4_v2_avg_ssse3) -sym(vpx_filter_block1d4_v2_avg_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - push rsi - push rdi - ; end prolog - - GET_PARAM_4 -.loop: - movd xmm0, [rsi] ;load src - movd xmm1, [rsi + rax] - - APPLY_FILTER_4 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d8_v2_avg_ssse3) -sym(vpx_filter_block1d8_v2_avg_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - GET_PARAM -.loop: - movq xmm0, [rsi] ;0 - movq xmm1, [rsi + rax] ;1 - - APPLY_FILTER_8 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d16_v2_avg_ssse3) -sym(vpx_filter_block1d16_v2_avg_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - GET_PARAM -.loop: - movdqu xmm0, [rsi] ;0 - movdqu xmm1, [rsi + rax] ;1 - movdqa xmm2, xmm0 - - APPLY_FILTER_16 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d4_h2_ssse3) -sym(vpx_filter_block1d4_h2_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - push rsi - push rdi - ; end prolog - - GET_PARAM_4 -.loop: - movdqu xmm0, [rsi] ;load src - movdqa xmm1, xmm0 - psrldq xmm1, 1 - - APPLY_FILTER_4 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d8_h2_ssse3) -sym(vpx_filter_block1d8_h2_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - GET_PARAM -.loop: - movdqu xmm0, [rsi] ;load src - movdqa xmm1, xmm0 - psrldq xmm1, 1 - - APPLY_FILTER_8 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d16_h2_ssse3) -sym(vpx_filter_block1d16_h2_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - GET_PARAM -.loop: - movdqu xmm0, [rsi] ;load src - movdqu xmm1, [rsi + 1] - movdqa xmm2, xmm0 - - APPLY_FILTER_16 0 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d4_h2_avg_ssse3) -sym(vpx_filter_block1d4_h2_avg_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - push rsi - push rdi - ; end prolog - - GET_PARAM_4 -.loop: - movdqu xmm0, [rsi] ;load src - movdqa xmm1, xmm0 - psrldq xmm1, 1 - - APPLY_FILTER_4 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d8_h2_avg_ssse3) -sym(vpx_filter_block1d8_h2_avg_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - GET_PARAM -.loop: - movdqu xmm0, [rsi] ;load src - movdqa xmm1, xmm0 - psrldq xmm1, 1 - - APPLY_FILTER_8 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret - -globalsym(vpx_filter_block1d16_h2_avg_ssse3) -sym(vpx_filter_block1d16_h2_avg_ssse3): - push rbp - mov rbp, rsp - SHADOW_ARGS_TO_STACK 6 - SAVE_XMM 7 - push rsi - push rdi - ; end prolog - - GET_PARAM -.loop: - movdqu xmm0, [rsi] ;load src - movdqu xmm1, [rsi + 1] - movdqa xmm2, xmm0 - - APPLY_FILTER_16 1 - jnz .loop - - ; begin epilog - pop rdi - pop rsi - RESTORE_XMM - UNSHADOW_ARGS - pop rbp - ret diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_mem/include/vpx_mem_intrnl.h b/presentation/src/main/cpp/third_party/libvpx/vpx_mem/include/vpx_mem_intrnl.h deleted file mode 100644 index 56311302..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_mem/include/vpx_mem_intrnl.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_MEM_INCLUDE_VPX_MEM_INTRNL_H_ -#define VPX_VPX_MEM_INCLUDE_VPX_MEM_INTRNL_H_ -#include "./vpx_config.h" - -#define ADDRESS_STORAGE_SIZE sizeof(size_t) - -#ifndef DEFAULT_ALIGNMENT -#if defined(VXWORKS) -/*default addr alignment to use in calls to vpx_* functions other than - * vpx_memalign*/ -#define DEFAULT_ALIGNMENT 32 -#else -#define DEFAULT_ALIGNMENT (2 * sizeof(void *)) /* NOLINT */ -#endif -#endif - -/*returns an addr aligned to the byte boundary specified by align*/ -#define align_addr(addr, align) \ - (void *)(((size_t)(addr) + ((align)-1)) & ~(size_t)((align)-1)) - -#endif // VPX_VPX_MEM_INCLUDE_VPX_MEM_INTRNL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_mem/vpx_mem.c b/presentation/src/main/cpp/third_party/libvpx/vpx_mem/vpx_mem.c deleted file mode 100644 index 18abf115..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_mem/vpx_mem.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_mem.h" -#include -#include -#include -#include -#include "include/vpx_mem_intrnl.h" -#include "vpx/vpx_integer.h" - -#if !defined(VPX_MAX_ALLOCABLE_MEMORY) -#if SIZE_MAX > (1ULL << 40) -#define VPX_MAX_ALLOCABLE_MEMORY (1ULL << 40) -#else -// For 32-bit targets keep this below INT_MAX to avoid valgrind warnings. -#define VPX_MAX_ALLOCABLE_MEMORY ((1ULL << 31) - (1 << 16)) -#endif -#endif - -// Returns 0 in case of overflow of nmemb * size. -static int check_size_argument_overflow(uint64_t nmemb, uint64_t size) { - const uint64_t total_size = nmemb * size; - if (nmemb == 0) return 1; - if (size > VPX_MAX_ALLOCABLE_MEMORY / nmemb) return 0; - if (total_size != (size_t)total_size) return 0; - - return 1; -} - -static size_t *get_malloc_address_location(void *const mem) { - return ((size_t *)mem) - 1; -} - -static uint64_t get_aligned_malloc_size(size_t size, size_t align) { - return (uint64_t)size + align - 1 + ADDRESS_STORAGE_SIZE; -} - -static void set_actual_malloc_address(void *const mem, - const void *const malloc_addr) { - size_t *const malloc_addr_location = get_malloc_address_location(mem); - *malloc_addr_location = (size_t)malloc_addr; -} - -static void *get_actual_malloc_address(void *const mem) { - size_t *const malloc_addr_location = get_malloc_address_location(mem); - return (void *)(*malloc_addr_location); -} - -void *vpx_memalign(size_t align, size_t size) { - void *x = NULL, *addr; - const uint64_t aligned_size = get_aligned_malloc_size(size, align); - if (!check_size_argument_overflow(1, aligned_size)) return NULL; - - addr = malloc((size_t)aligned_size); - if (addr) { - x = align_addr((unsigned char *)addr + ADDRESS_STORAGE_SIZE, align); - set_actual_malloc_address(x, addr); - } - return x; -} - -void *vpx_malloc(size_t size) { return vpx_memalign(DEFAULT_ALIGNMENT, size); } - -void *vpx_calloc(size_t num, size_t size) { - void *x; - if (!check_size_argument_overflow(num, size)) return NULL; - - x = vpx_malloc(num * size); - if (x) memset(x, 0, num * size); - return x; -} - -void vpx_free(void *memblk) { - if (memblk) { - void *addr = get_actual_malloc_address(memblk); - free(addr); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_mem/vpx_mem.h b/presentation/src/main/cpp/third_party/libvpx/vpx_mem/vpx_mem.h deleted file mode 100644 index 7689a05e..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_mem/vpx_mem.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_MEM_VPX_MEM_H_ -#define VPX_VPX_MEM_VPX_MEM_H_ - -#include "vpx_config.h" -#if defined(__uClinux__) -#include -#endif - -#include -#include - -#include "vpx/vpx_integer.h" - -#if defined(__cplusplus) -extern "C" { -#endif - -void *vpx_memalign(size_t align, size_t size); -void *vpx_malloc(size_t size); -void *vpx_calloc(size_t num, size_t size); -void vpx_free(void *memblk); - -#if CONFIG_VP9_HIGHBITDEPTH -static INLINE void *vpx_memset16(void *dest, int val, size_t length) { - size_t i; - uint16_t *dest16 = (uint16_t *)dest; - for (i = 0; i < length; i++) *dest16++ = val; - return dest; -} -#endif - -#include - -#ifdef VPX_MEM_PLTFRM -#include VPX_MEM_PLTFRM -#endif - -#if defined(__cplusplus) -} -#endif - -#endif // VPX_VPX_MEM_VPX_MEM_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_mem/vpx_mem.mk b/presentation/src/main/cpp/third_party/libvpx/vpx_mem/vpx_mem.mk deleted file mode 100644 index 7f275eab..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_mem/vpx_mem.mk +++ /dev/null @@ -1,4 +0,0 @@ -MEM_SRCS-yes += vpx_mem.mk -MEM_SRCS-yes += vpx_mem.c -MEM_SRCS-yes += vpx_mem.h -MEM_SRCS-yes += include/vpx_mem_intrnl.h diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/aarch32_cpudetect.c b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/aarch32_cpudetect.c deleted file mode 100644 index 20f688e1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/aarch32_cpudetect.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -// Feature detection code for Armv7-A / AArch32. - -#include "./vpx_config.h" -#include "arm_cpudetect.h" - -#if !CONFIG_RUNTIME_CPU_DETECT - -static int arm_get_cpu_caps(void) { - // This function should actually be a no-op. There is no way to adjust any of - // these because the RTCD tables do not exist: the functions are called - // statically. - int flags = 0; -#if HAVE_NEON - flags |= HAS_NEON; -#endif // HAVE_NEON - return flags; -} - -#elif defined(_MSC_VER) // end !CONFIG_RUNTIME_CPU_DETECT - -static int arm_get_cpu_caps(void) { - int flags = 0; -#if HAVE_NEON || HAVE_NEON_ASM - // MSVC has no inline __asm support for Arm, but it does let you __emit - // instructions via their assembled hex code. - // All of these instructions should be essentially nops. - __try { - // VORR q0,q0,q0 - __emit(0xF2200150); - flags |= HAS_NEON; - } __except (GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) { - // Ignore exception. - } -#endif // HAVE_NEON || HAVE_NEON_ASM - return flags; -} - -#elif defined(VPX_USE_ANDROID_CPU_FEATURES) - -static int arm_get_cpu_caps(void) { - int flags = 0; -#if HAVE_NEON || HAVE_NEON_ASM - uint64_t features = android_getCpuFeatures(); - if (features & ANDROID_CPU_ARM_FEATURE_NEON) { - flags |= HAS_NEON; - } -#endif // HAVE_NEON || HAVE_NEON_ASM - return flags; -} - -#elif defined(__linux__) // end defined(VPX_USE_ANDROID_CPU_FEATURES) - -#include - -// Define hwcap values ourselves: building with an old auxv header where these -// hwcap values are not defined should not prevent features from being enabled. -#define VPX_AARCH32_HWCAP_NEON (1 << 12) - -static int arm_get_cpu_caps(void) { - int flags = 0; - unsigned long hwcap = getauxval(AT_HWCAP); -#if HAVE_NEON || HAVE_NEON_ASM - if (hwcap & VPX_AARCH32_HWCAP_NEON) { - flags |= HAS_NEON; - } -#endif // HAVE_NEON || HAVE_NEON_ASM - return flags; -} -#else // end __linux__ -#error \ - "Runtime CPU detection selected, but no CPU detection method available" \ -"for your platform. Rerun configure with --disable-runtime-cpu-detect." -#endif - -int arm_cpu_caps(void) { - int flags = 0; - if (arm_cpu_env_flags(&flags)) { - return flags; - } - return arm_get_cpu_caps() & arm_cpu_env_mask(); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/aarch64_cpudetect.c b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/aarch64_cpudetect.c deleted file mode 100644 index df8e1e24..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/aarch64_cpudetect.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "vpx_ports/arm.h" -#include "vpx_ports/arm_cpudetect.h" - -#if defined(__APPLE__) -#include -#endif - -#if !CONFIG_RUNTIME_CPU_DETECT - -static int arm_get_cpu_caps(void) { - // This function should actually be a no-op. There is no way to adjust any of - // these because the RTCD tables do not exist: the functions are called - // statically. - int flags = 0; -#if HAVE_NEON - flags |= HAS_NEON; -#endif // HAVE_NEON - return flags; -} - -#elif defined(__APPLE__) // end !CONFIG_RUNTIME_CPU_DETECT - -// sysctlbyname() parameter documentation for instruction set characteristics: -// https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics -static INLINE int64_t have_feature(const char *feature) { - int64_t feature_present = 0; - size_t size = sizeof(feature_present); - if (sysctlbyname(feature, &feature_present, &size, NULL, 0) != 0) { - return 0; - } - return feature_present; -} - -static int arm_get_cpu_caps(void) { - int flags = 0; -#if HAVE_NEON - flags |= HAS_NEON; -#endif // HAVE_NEON -#if HAVE_NEON_DOTPROD - if (have_feature("hw.optional.arm.FEAT_DotProd")) { - flags |= HAS_NEON_DOTPROD; - } -#endif // HAVE_NEON_DOTPROD -#if HAVE_NEON_I8MM - if (have_feature("hw.optional.arm.FEAT_I8MM")) { - flags |= HAS_NEON_I8MM; - } -#endif // HAVE_NEON_I8MM - return flags; -} - -#elif defined(_WIN32) // end __APPLE__ - -static int arm_get_cpu_caps(void) { - int flags = 0; -// IsProcessorFeaturePresent() parameter documentation: -// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent#parameters -#if HAVE_NEON - flags |= HAS_NEON; // Neon is mandatory in Armv8.0-A. -#endif // HAVE_NEON -#if HAVE_NEON_DOTPROD -// Support for PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE was added in Windows SDK -// 20348, supported by Windows 11 and Windows Server 2022. -#if defined(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE) - if (IsProcessorFeaturePresent(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE)) { - flags |= HAS_NEON_DOTPROD; - } -#endif // defined(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE) -#endif // HAVE_NEON_DOTPROD -#if HAVE_NEON_I8MM -// Support for PF_ARM_SVE_I8MM_INSTRUCTIONS_AVAILABLE was added in Windows SDK -// 26100. -#if defined(PF_ARM_SVE_I8MM_INSTRUCTIONS_AVAILABLE) - // There's no PF_* flag that indicates whether plain I8MM is available - // or not. But if SVE_I8MM is available, that also implies that - // regular I8MM is available. - if (IsProcessorFeaturePresent(PF_ARM_SVE_I8MM_INSTRUCTIONS_AVAILABLE)) { - flags |= HAS_NEON_I8MM; - } -#endif // defined(PF_ARM_SVE_I8MM_INSTRUCTIONS_AVAILABLE) -#endif // HAVE_NEON_I8MM -#if HAVE_SVE -// Support for PF_ARM_SVE_INSTRUCTIONS_AVAILABLE was added in Windows SDK 26100. -#if defined(PF_ARM_SVE_INSTRUCTIONS_AVAILABLE) - if (IsProcessorFeaturePresent(PF_ARM_SVE_INSTRUCTIONS_AVAILABLE)) { - flags |= HAS_SVE; - } -#endif // defined(PF_ARM_SVE_INSTRUCTIONS_AVAILABLE) -#endif // HAVE_SVE -#if HAVE_SVE2 -// Support for PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE was added in Windows SDK -// 26100. -#if defined(PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE) - if (IsProcessorFeaturePresent(PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE)) { - flags |= HAS_SVE2; - } -#endif // defined(PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE) -#endif // HAVE_SVE2 - return flags; -} - -#elif defined(VPX_USE_ANDROID_CPU_FEATURES) - -static int arm_get_cpu_caps(void) { - int flags = 0; -#if HAVE_NEON - flags |= HAS_NEON; // Neon is mandatory in Armv8.0-A. -#endif // HAVE_NEON - return flags; -} - -#elif defined(__linux__) // end defined(VPX_USE_ANDROID_CPU_FEATURES) - -#include - -// Define hwcap values ourselves: building with an old auxv header where these -// hwcap values are not defined should not prevent features from being enabled. -#define VPX_AARCH64_HWCAP_ASIMDDP (1 << 20) -#define VPX_AARCH64_HWCAP_SVE (1 << 22) -#define VPX_AARCH64_HWCAP2_SVE2 (1 << 1) -#define VPX_AARCH64_HWCAP2_I8MM (1 << 13) - -static int arm_get_cpu_caps(void) { - int flags = 0; -#if HAVE_NEON_DOTPROD || HAVE_SVE - unsigned long hwcap = getauxval(AT_HWCAP); -#endif // HAVE_NEON_DOTPROD || HAVE_SVE -#if HAVE_NEON_I8MM || HAVE_SVE2 - unsigned long hwcap2 = getauxval(AT_HWCAP2); -#endif // HAVE_NEON_I8MM || HAVE_SVE2 -#if HAVE_NEON - flags |= HAS_NEON; // Neon is mandatory in Armv8.0-A. -#endif // HAVE_NEON -#if HAVE_NEON_DOTPROD - if (hwcap & VPX_AARCH64_HWCAP_ASIMDDP) { - flags |= HAS_NEON_DOTPROD; - } -#endif // HAVE_NEON_DOTPROD -#if HAVE_NEON_I8MM - if (hwcap2 & VPX_AARCH64_HWCAP2_I8MM) { - flags |= HAS_NEON_I8MM; - } -#endif // HAVE_NEON_I8MM -#if HAVE_SVE - if (hwcap & VPX_AARCH64_HWCAP_SVE) { - flags |= HAS_SVE; - } -#endif // HAVE_SVE -#if HAVE_SVE2 - if (hwcap2 & VPX_AARCH64_HWCAP2_SVE2) { - flags |= HAS_SVE2; - } -#endif // HAVE_SVE2 - return flags; -} - -#elif defined(__Fuchsia__) // end __linux__ - -#include -#include - -// Added in https://fuchsia-review.googlesource.com/c/fuchsia/+/894282. -#ifndef ZX_ARM64_FEATURE_ISA_I8MM -#define ZX_ARM64_FEATURE_ISA_I8MM ((uint32_t)(1u << 19)) -#endif -// Added in https://fuchsia-review.googlesource.com/c/fuchsia/+/895083. -#ifndef ZX_ARM64_FEATURE_ISA_SVE -#define ZX_ARM64_FEATURE_ISA_SVE ((uint32_t)(1u << 20)) -#endif - -static int arm_get_cpu_caps(void) { - int flags = 0; -#if HAVE_NEON - flags |= HAS_NEON; // Neon is mandatory in Armv8.0-A. -#endif // HAVE_NEON - uint32_t features; - zx_status_t status = zx_system_get_features(ZX_FEATURE_KIND_CPU, &features); - if (status != ZX_OK) { - return flags; - } -#if HAVE_NEON_DOTPROD - if (features & ZX_ARM64_FEATURE_ISA_DP) { - flags |= HAS_NEON_DOTPROD; - } -#endif // HAVE_NEON_DOTPROD -#if HAVE_NEON_I8MM - if (features & ZX_ARM64_FEATURE_ISA_I8MM) { - flags |= HAS_NEON_I8MM; - } -#endif // HAVE_NEON_I8MM -#if HAVE_SVE - if (features & ZX_ARM64_FEATURE_ISA_SVE) { - flags |= HAS_SVE; - } -#endif // HAVE_SVE - return flags; -} - -#else // end __Fuchsia__ -#error \ - "Runtime CPU detection selected, but no CPU detection method available" \ -"for your platform. Rerun configure with --disable-runtime-cpu-detect." -#endif - -int arm_cpu_caps(void) { - int flags = 0; - if (!arm_cpu_env_flags(&flags)) { - flags = arm_get_cpu_caps() & arm_cpu_env_mask(); - } - - // Restrict flags: FEAT_I8MM assumes that FEAT_DotProd is available. - if (!(flags & HAS_NEON_DOTPROD)) { - flags &= ~HAS_NEON_I8MM; - } - - // Restrict flags: FEAT_SVE assumes that FEAT_{DotProd,I8MM} are available. - if (!(flags & HAS_NEON_DOTPROD)) { - flags &= ~HAS_SVE; - } - if (!(flags & HAS_NEON_I8MM)) { - flags &= ~HAS_SVE; - } - - // Restrict flags: FEAT_SVE2 assumes that FEAT_SVE is available. - if (!(flags & HAS_SVE)) { - flags &= ~HAS_SVE2; - } - - return flags; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/arm.h b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/arm.h deleted file mode 100644 index 814c3cc4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/arm.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_PORTS_ARM_H_ -#define VPX_VPX_PORTS_ARM_H_ -#include -#include "vpx_config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// Armv7-A optional Neon instructions, mandatory from Armv8.0-A. -#define HAS_NEON (1 << 0) -// Armv8.2-A optional Neon dot-product instructions, mandatory from Armv8.4-A. -#define HAS_NEON_DOTPROD (1 << 1) -// Armv8.2-A optional Neon i8mm instructions, mandatory from Armv8.6-A. -#define HAS_NEON_I8MM (1 << 2) -// Armv8.2-A optional SVE instructions, mandatory from Armv9.0-A. -#define HAS_SVE (1 << 3) -// Armv9.0-A SVE2 instructions. -#define HAS_SVE2 (1 << 4) - -int arm_cpu_caps(void); - -// Earlier gcc compilers have issues with some neon intrinsics -#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ == 4 && \ - __GNUC_MINOR__ <= 6 -#define VPX_INCOMPATIBLE_GCC -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_PORTS_ARM_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/arm_cpudetect.h b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/arm_cpudetect.h deleted file mode 100644 index 9b64a1fa..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/arm_cpudetect.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2023 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "vpx_config.h" -#include "vpx_ports/arm.h" - -#if defined(_WIN32) -#undef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#undef WIN32_EXTRA_LEAN -#define WIN32_EXTRA_LEAN -#include -#endif - -#ifdef WINAPI_FAMILY -#include -#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) -#define getenv(x) NULL -#endif -#endif - -#if defined(__ANDROID__) && (__ANDROID_API__ < 18) -#define VPX_USE_ANDROID_CPU_FEATURES 1 -// Use getauxval() when targeting (64-bit) Android with API level >= 18. -// getauxval() is supported since Android API level 18 (Android 4.3.) -// First Android version with 64-bit support was Android 5.x (API level 21). -#include -#endif - -static INLINE int arm_cpu_env_flags(int *flags) { - const char *env = getenv("VPX_SIMD_CAPS"); - if (env && *env) { - *flags = (int)strtol(env, NULL, 0); - return 1; - } - return 0; -} - -static INLINE int arm_cpu_env_mask(void) { - const char *env = getenv("VPX_SIMD_CAPS_MASK"); - return env && *env ? (int)strtol(env, NULL, 0) : ~0; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/asmdefs_mmi.h b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/asmdefs_mmi.h deleted file mode 100644 index 400a51cc..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/asmdefs_mmi.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_PORTS_ASMDEFS_MMI_H_ -#define VPX_VPX_PORTS_ASMDEFS_MMI_H_ - -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" - -#if HAVE_MMI - -#if HAVE_MIPS64 -#define mips_reg int64_t -#define MMI_ADDU(reg1, reg2, reg3) \ - "daddu " #reg1 ", " #reg2 ", " #reg3 " \n\t" - -#define MMI_ADDIU(reg1, reg2, immediate) \ - "daddiu " #reg1 ", " #reg2 ", " #immediate " \n\t" - -#define MMI_ADDI(reg1, reg2, immediate) \ - "daddi " #reg1 ", " #reg2 ", " #immediate " \n\t" - -#define MMI_SUBU(reg1, reg2, reg3) \ - "dsubu " #reg1 ", " #reg2 ", " #reg3 " \n\t" - -#define MMI_L(reg, addr, bias) \ - "ld " #reg ", " #bias "(" #addr ") \n\t" - -#define MMI_SRL(reg1, reg2, shift) \ - "ssrld " #reg1 ", " #reg2 ", " #shift " \n\t" - -#define MMI_SLL(reg1, reg2, shift) \ - "dsll " #reg1 ", " #reg2 ", " #shift " \n\t" - -#define MMI_MTC1(reg, fp) \ - "dmtc1 " #reg ", " #fp " \n\t" - -#define MMI_LI(reg, immediate) \ - "dli " #reg ", " #immediate " \n\t" - -#else -#define mips_reg int32_t -#define MMI_ADDU(reg1, reg2, reg3) \ - "addu " #reg1 ", " #reg2 ", " #reg3 " \n\t" - -#define MMI_ADDIU(reg1, reg2, immediate) \ - "addiu " #reg1 ", " #reg2 ", " #immediate " \n\t" - -#define MMI_ADDI(reg1, reg2, immediate) \ - "addi " #reg1 ", " #reg2 ", " #immediate " \n\t" - -#define MMI_SUBU(reg1, reg2, reg3) \ - "subu " #reg1 ", " #reg2 ", " #reg3 " \n\t" - -#define MMI_L(reg, addr, bias) \ - "lw " #reg ", " #bias "(" #addr ") \n\t" - -#define MMI_SRL(reg1, reg2, shift) \ - "ssrlw " #reg1 ", " #reg2 ", " #shift " \n\t" - -#define MMI_SLL(reg1, reg2, shift) \ - "sll " #reg1 ", " #reg2 ", " #shift " \n\t" - -#define MMI_MTC1(reg, fp) \ - "mtc1 " #reg ", " #fp " \n\t" - -#define MMI_LI(reg, immediate) \ - "li " #reg ", " #immediate " \n\t" - -#endif /* HAVE_MIPS64 */ - -#endif /* HAVE_MMI */ - -#endif // VPX_VPX_PORTS_ASMDEFS_MMI_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/bitops.h b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/bitops.h deleted file mode 100644 index e92c972f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/bitops.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_PORTS_BITOPS_H_ -#define VPX_VPX_PORTS_BITOPS_H_ - -#include - -#ifdef _MSC_VER -#if defined(_M_X64) || defined(_M_IX86) -#include -#define USE_MSC_INTRINSICS -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -// These versions of get_lsb() and get_msb() are only valid when n != 0 -// because all of the optimized versions are undefined when n == 0: -// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html - -// use GNU builtins where available. -#if defined(__GNUC__) && \ - ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4) -static INLINE int get_lsb(unsigned int n) { - assert(n != 0); - return __builtin_ctz(n); -} - -static INLINE int get_msb(unsigned int n) { - assert(n != 0); - return 31 ^ __builtin_clz(n); -} -#elif defined(USE_MSC_INTRINSICS) -#pragma intrinsic(_BitScanForward) -#pragma intrinsic(_BitScanReverse) - -static INLINE int get_lsb(unsigned int n) { - unsigned long first_set_bit; // NOLINT(runtime/int) - _BitScanForward(&first_set_bit, n); - return first_set_bit; -} - -static INLINE int get_msb(unsigned int n) { - unsigned long first_set_bit; - assert(n != 0); - _BitScanReverse(&first_set_bit, n); - return first_set_bit; -} -#undef USE_MSC_INTRINSICS -#else -static INLINE int get_lsb(unsigned int n) { - int i; - assert(n != 0); - for (i = 0; i < 32 && !(n & 1); ++i) n >>= 1; - return i; -} - -// Returns (int)floor(log2(n)). n must be > 0. -static INLINE int get_msb(unsigned int n) { - int log = 0; - unsigned int value = n; - int i; - - assert(n != 0); - - for (i = 4; i >= 0; --i) { - const int shift = (1 << i); - const unsigned int x = value >> shift; - if (x != 0) { - value = x; - log += shift; - } - } - return log; -} -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_PORTS_BITOPS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/compiler_attributes.h b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/compiler_attributes.h deleted file mode 100644 index 4b468749..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/compiler_attributes.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2020 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_PORTS_COMPILER_ATTRIBUTES_H_ -#define VPX_VPX_PORTS_COMPILER_ATTRIBUTES_H_ - -#if !defined(__has_feature) -#define __has_feature(x) 0 -#endif // !defined(__has_feature) - -#if !defined(__has_attribute) -#define __has_attribute(x) 0 -#endif // !defined(__has_attribute) - -//------------------------------------------------------------------------------ -// Sanitizer attributes. - -#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) -#define VPX_WITH_ASAN 1 -#else -#define VPX_WITH_ASAN 0 -#endif // __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) - -#if defined(__clang__) && __has_attribute(no_sanitize) -// Both of these have defined behavior and are used in certain operations or -// optimizations thereof. There are cases where an overflow may be unintended, -// however, so use of these attributes should be done with care. -#define VPX_NO_UNSIGNED_OVERFLOW_CHECK \ - __attribute__((no_sanitize("unsigned-integer-overflow"))) -#if __clang_major__ >= 12 -#define VPX_NO_UNSIGNED_SHIFT_CHECK \ - __attribute__((no_sanitize("unsigned-shift-base"))) -#endif // __clang__ >= 12 -#endif // __clang__ - -#ifndef VPX_NO_UNSIGNED_OVERFLOW_CHECK -#define VPX_NO_UNSIGNED_OVERFLOW_CHECK -#endif -#ifndef VPX_NO_UNSIGNED_SHIFT_CHECK -#define VPX_NO_UNSIGNED_SHIFT_CHECK -#endif - -//------------------------------------------------------------------------------ -// Variable attributes. - -#if __has_attribute(uninitialized) -// Attribute "uninitialized" disables -ftrivial-auto-var-init=pattern for -// the specified variable. -// -// -ftrivial-auto-var-init is security risk mitigation feature, so attribute -// should not be used "just in case", but only to fix real performance -// bottlenecks when other approaches do not work. In general the compiler is -// quite effective at eliminating unneeded initializations introduced by the -// flag, e.g. when they are followed by actual initialization by a program. -// However if compiler optimization fails and code refactoring is hard, the -// attribute can be used as a workaround. -#define VPX_UNINITIALIZED __attribute__((uninitialized)) -#else -#define VPX_UNINITIALIZED -#endif // __has_attribute(uninitialized) - -#endif // VPX_VPX_PORTS_COMPILER_ATTRIBUTES_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/emmintrin_compat.h b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/emmintrin_compat.h deleted file mode 100644 index d6cc68ee..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/emmintrin_compat.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2012 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_PORTS_EMMINTRIN_COMPAT_H_ -#define VPX_VPX_PORTS_EMMINTRIN_COMPAT_H_ - -#if defined(__GNUC__) && __GNUC__ < 4 -/* From emmintrin.h (gcc 4.5.3) */ -/* Casts between various SP, DP, INT vector types. Note that these do no - conversion of values, they just change the type. */ -extern __inline __m128 - __attribute__((__gnu_inline__, __always_inline__, __artificial__)) - _mm_castpd_ps(__m128d __A) { - return (__m128)__A; -} - -extern __inline __m128i - __attribute__((__gnu_inline__, __always_inline__, __artificial__)) - _mm_castpd_si128(__m128d __A) { - return (__m128i)__A; -} - -extern __inline __m128d - __attribute__((__gnu_inline__, __always_inline__, __artificial__)) - _mm_castps_pd(__m128 __A) { - return (__m128d)__A; -} - -extern __inline __m128i - __attribute__((__gnu_inline__, __always_inline__, __artificial__)) - _mm_castps_si128(__m128 __A) { - return (__m128i)__A; -} - -extern __inline __m128 - __attribute__((__gnu_inline__, __always_inline__, __artificial__)) - _mm_castsi128_ps(__m128i __A) { - return (__m128)__A; -} - -extern __inline __m128d - __attribute__((__gnu_inline__, __always_inline__, __artificial__)) - _mm_castsi128_pd(__m128i __A) { - return (__m128d)__A; -} -#endif - -#endif // VPX_VPX_PORTS_EMMINTRIN_COMPAT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/emms_mmx.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/emms_mmx.asm deleted file mode 100644 index b31b25eb..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/emms_mmx.asm +++ /dev/null @@ -1,18 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -section .text -globalsym(vpx_clear_system_state) -sym(vpx_clear_system_state): - emms - ret diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/emms_mmx.c b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/emms_mmx.c deleted file mode 100644 index 79b98a75..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/emms_mmx.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2018 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "vpx_ports/system_state.h" - -void vpx_clear_system_state(void) { _mm_empty(); } diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/float_control_word.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/float_control_word.asm deleted file mode 100644 index bb75b7a3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/float_control_word.asm +++ /dev/null @@ -1,33 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_ports/x86_abi_support.asm" - -section .text - -%if LIBVPX_YASM_WIN64 -globalsym(vpx_winx64_fldcw) -sym(vpx_winx64_fldcw): - sub rsp, 8 - mov [rsp], rcx ; win x64 specific - fldcw [rsp] - add rsp, 8 - ret - - -globalsym(vpx_winx64_fstcw) -sym(vpx_winx64_fstcw): - sub rsp, 8 - fstcw [rsp] - mov rax, [rsp] - add rsp, 8 - ret -%endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/loongarch.h b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/loongarch.h deleted file mode 100644 index d93ff9f5..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/loongarch.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2021 Loongson Technology Corporation Limited - * Contributed by Jin Bo - * Contributed by Lu Wang - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_PORTS_LOONGARCH_H_ -#define VPX_VPX_PORTS_LOONGARCH_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define HAS_LSX 0x01 -#define HAS_LASX 0x02 - -int loongarch_cpu_caps(void); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_PORTS_LOONGARCH_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/loongarch_cpudetect.c b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/loongarch_cpudetect.c deleted file mode 100644 index 7b4322d3..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/loongarch_cpudetect.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2021 Loongson Technology Corporation Limited - * Contributed by Jin Bo - * Contributed by Lu Wang - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_config.h" -#include "vpx_ports/loongarch.h" - -#define LOONGARCH_CFG2 0x02 -#define LOONGARCH_CFG2_LSX (1 << 6) -#define LOONGARCH_CFG2_LASX (1 << 7) - -#if CONFIG_RUNTIME_CPU_DETECT -#if defined(__loongarch__) && defined(__linux__) -int loongarch_cpu_caps(void) { - int reg = 0; - int flag = 0; - - __asm__ volatile("cpucfg %0, %1 \n\t" : "+&r"(reg) : "r"(LOONGARCH_CFG2)); - if (reg & LOONGARCH_CFG2_LSX) flag |= HAS_LSX; - - if (reg & LOONGARCH_CFG2_LASX) flag |= HAS_LASX; - - return flag; -} -#else /* end __loongarch__ && __linux__ */ -#error \ - "--enable-runtime-cpu-detect selected, but no CPU detection method " \ -"available for your platform. Reconfigure with --disable-runtime-cpu-detect." -#endif -#else /* end CONFIG_RUNTIME_CPU_DETECT */ -int loongarch_cpu_caps(void) { return 0; } -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/mem.h b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/mem.h deleted file mode 100644 index 72d73876..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/mem.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_PORTS_MEM_H_ -#define VPX_VPX_PORTS_MEM_H_ - -#include "vpx_config.h" -#include "vpx/vpx_integer.h" - -#if defined(__GNUC__) || defined(__SUNPRO_C) -#define DECLARE_ALIGNED(n, typ, val) typ val __attribute__((aligned(n))) -#elif defined(_MSC_VER) -#define DECLARE_ALIGNED(n, typ, val) __declspec(align(n)) typ val -#else -#warning No alignment directives known for this compiler. -#define DECLARE_ALIGNED(n, typ, val) typ val -#endif - -#if defined(__has_builtin) -#define VPX_HAS_BUILTIN(x) __has_builtin(x) -#else -#define VPX_HAS_BUILTIN(x) 0 -#endif - -#if !VPX_HAS_BUILTIN(__builtin_prefetch) && !defined(__GNUC__) -#define __builtin_prefetch(x) -#endif - -/* Shift down with rounding */ -#define ROUND_POWER_OF_TWO(value, n) (((value) + (1 << ((n)-1))) >> (n)) -#define ROUND64_POWER_OF_TWO(value, n) (((value) + (1ULL << ((n)-1))) >> (n)) - -#define ALIGN_POWER_OF_TWO(value, n) \ - (((value) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1)) - -#define CONVERT_TO_SHORTPTR(x) ((uint16_t *)(((uintptr_t)(x)) << 1)) -#define CAST_TO_SHORTPTR(x) ((uint16_t *)((uintptr_t)(x))) -#if CONFIG_VP9_HIGHBITDEPTH -#define CONVERT_TO_BYTEPTR(x) ((uint8_t *)(((uintptr_t)(x)) >> 1)) -#define CAST_TO_BYTEPTR(x) ((uint8_t *)((uintptr_t)(x))) -#endif // CONFIG_VP9_HIGHBITDEPTH - -#endif // VPX_VPX_PORTS_MEM_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/mem_ops.h b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/mem_ops.h deleted file mode 100644 index b17015e7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/mem_ops.h +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_PORTS_MEM_OPS_H_ -#define VPX_VPX_PORTS_MEM_OPS_H_ - -/* \file - * \brief Provides portable memory access primitives - * - * This function provides portable primitives for getting and setting of - * signed and unsigned integers in 16, 24, and 32 bit sizes. The operations - * can be performed on unaligned data regardless of hardware support for - * unaligned accesses. - * - * The type used to pass the integral values may be changed by defining - * MEM_VALUE_T with the appropriate type. The type given must be an integral - * numeric type. - * - * The actual functions instantiated have the MEM_VALUE_T type name pasted - * on to the symbol name. This allows the developer to instantiate these - * operations for multiple types within the same translation unit. This is - * of somewhat questionable utility, but the capability exists nonetheless. - * Users not making use of this functionality should call the functions - * without the type name appended, and the preprocessor will take care of - * it. - * - * NOTE: This code is not supported on platforms where char > 1 octet ATM. - */ - -#ifndef MAU_T -/* Minimum Access Unit for this target */ -#define MAU_T unsigned char -#endif - -#ifndef MEM_VALUE_T -#define MEM_VALUE_T int -#endif - -#undef MEM_VALUE_T_SZ_BITS -#define MEM_VALUE_T_SZ_BITS (sizeof(MEM_VALUE_T) << 3) - -#undef mem_ops_wrap_symbol -#define mem_ops_wrap_symbol(fn) mem_ops_wrap_symbol2(fn, MEM_VALUE_T) -#undef mem_ops_wrap_symbol2 -#define mem_ops_wrap_symbol2(fn, typ) mem_ops_wrap_symbol3(fn, typ) -#undef mem_ops_wrap_symbol3 -#define mem_ops_wrap_symbol3(fn, typ) fn##_as_##typ - -/* - * Include aligned access routines - */ -#define INCLUDED_BY_MEM_OPS_H -#include "mem_ops_aligned.h" -#undef INCLUDED_BY_MEM_OPS_H - -#undef mem_get_be16 -#define mem_get_be16 mem_ops_wrap_symbol(mem_get_be16) -static unsigned MEM_VALUE_T mem_get_be16(const void *vmem) { - unsigned MEM_VALUE_T val; - const MAU_T *mem = (const MAU_T *)vmem; - - val = mem[0] << 8; - val |= mem[1]; - return val; -} - -#undef mem_get_be24 -#define mem_get_be24 mem_ops_wrap_symbol(mem_get_be24) -static unsigned MEM_VALUE_T mem_get_be24(const void *vmem) { - unsigned MEM_VALUE_T val; - const MAU_T *mem = (const MAU_T *)vmem; - - val = mem[0] << 16; - val |= mem[1] << 8; - val |= mem[2]; - return val; -} - -#undef mem_get_be32 -#define mem_get_be32 mem_ops_wrap_symbol(mem_get_be32) -static unsigned MEM_VALUE_T mem_get_be32(const void *vmem) { - unsigned MEM_VALUE_T val; - const MAU_T *mem = (const MAU_T *)vmem; - - val = ((unsigned MEM_VALUE_T)mem[0]) << 24; - val |= mem[1] << 16; - val |= mem[2] << 8; - val |= mem[3]; - return val; -} - -#undef mem_get_le16 -#define mem_get_le16 mem_ops_wrap_symbol(mem_get_le16) -static unsigned MEM_VALUE_T mem_get_le16(const void *vmem) { - unsigned MEM_VALUE_T val; - const MAU_T *mem = (const MAU_T *)vmem; - - val = mem[1] << 8; - val |= mem[0]; - return val; -} - -#undef mem_get_le24 -#define mem_get_le24 mem_ops_wrap_symbol(mem_get_le24) -static unsigned MEM_VALUE_T mem_get_le24(const void *vmem) { - unsigned MEM_VALUE_T val; - const MAU_T *mem = (const MAU_T *)vmem; - - val = mem[2] << 16; - val |= mem[1] << 8; - val |= mem[0]; - return val; -} - -#undef mem_get_le32 -#define mem_get_le32 mem_ops_wrap_symbol(mem_get_le32) -static unsigned MEM_VALUE_T mem_get_le32(const void *vmem) { - unsigned MEM_VALUE_T val; - const MAU_T *mem = (const MAU_T *)vmem; - - val = ((unsigned MEM_VALUE_T)mem[3]) << 24; - val |= mem[2] << 16; - val |= mem[1] << 8; - val |= mem[0]; - return val; -} - -#define mem_get_s_generic(end, sz) \ - static VPX_INLINE signed MEM_VALUE_T mem_get_s##end##sz(const void *vmem) { \ - const MAU_T *mem = (const MAU_T *)vmem; \ - signed MEM_VALUE_T val = mem_get_##end##sz(mem); \ - return (val << (MEM_VALUE_T_SZ_BITS - sz)) >> (MEM_VALUE_T_SZ_BITS - sz); \ - } - -/* clang-format off */ -#undef mem_get_sbe16 -#define mem_get_sbe16 mem_ops_wrap_symbol(mem_get_sbe16) -mem_get_s_generic(be, 16) - -#undef mem_get_sbe24 -#define mem_get_sbe24 mem_ops_wrap_symbol(mem_get_sbe24) -mem_get_s_generic(be, 24) - -#undef mem_get_sbe32 -#define mem_get_sbe32 mem_ops_wrap_symbol(mem_get_sbe32) -mem_get_s_generic(be, 32) - -#undef mem_get_sle16 -#define mem_get_sle16 mem_ops_wrap_symbol(mem_get_sle16) -mem_get_s_generic(le, 16) - -#undef mem_get_sle24 -#define mem_get_sle24 mem_ops_wrap_symbol(mem_get_sle24) -mem_get_s_generic(le, 24) - -#undef mem_get_sle32 -#define mem_get_sle32 mem_ops_wrap_symbol(mem_get_sle32) -mem_get_s_generic(le, 32) - -#undef mem_put_be16 -#define mem_put_be16 mem_ops_wrap_symbol(mem_put_be16) -static VPX_INLINE void mem_put_be16(void *vmem, MEM_VALUE_T val) { - MAU_T *mem = (MAU_T *)vmem; - - mem[0] = (MAU_T)((val >> 8) & 0xff); - mem[1] = (MAU_T)((val >> 0) & 0xff); -} - -#undef mem_put_be24 -#define mem_put_be24 mem_ops_wrap_symbol(mem_put_be24) -static VPX_INLINE void mem_put_be24(void *vmem, MEM_VALUE_T val) { - MAU_T *mem = (MAU_T *)vmem; - - mem[0] = (MAU_T)((val >> 16) & 0xff); - mem[1] = (MAU_T)((val >> 8) & 0xff); - mem[2] = (MAU_T)((val >> 0) & 0xff); -} - -#undef mem_put_be32 -#define mem_put_be32 mem_ops_wrap_symbol(mem_put_be32) -static VPX_INLINE void mem_put_be32(void *vmem, MEM_VALUE_T val) { - MAU_T *mem = (MAU_T *)vmem; - - mem[0] = (MAU_T)((val >> 24) & 0xff); - mem[1] = (MAU_T)((val >> 16) & 0xff); - mem[2] = (MAU_T)((val >> 8) & 0xff); - mem[3] = (MAU_T)((val >> 0) & 0xff); -} - -#undef mem_put_le16 -#define mem_put_le16 mem_ops_wrap_symbol(mem_put_le16) -static VPX_INLINE void mem_put_le16(void *vmem, MEM_VALUE_T val) { - MAU_T *mem = (MAU_T *)vmem; - - mem[0] = (MAU_T)((val >> 0) & 0xff); - mem[1] = (MAU_T)((val >> 8) & 0xff); -} - -#undef mem_put_le24 -#define mem_put_le24 mem_ops_wrap_symbol(mem_put_le24) -static VPX_INLINE void mem_put_le24(void *vmem, MEM_VALUE_T val) { - MAU_T *mem = (MAU_T *)vmem; - - mem[0] = (MAU_T)((val >> 0) & 0xff); - mem[1] = (MAU_T)((val >> 8) & 0xff); - mem[2] = (MAU_T)((val >> 16) & 0xff); -} - -#undef mem_put_le32 -#define mem_put_le32 mem_ops_wrap_symbol(mem_put_le32) -static VPX_INLINE void mem_put_le32(void *vmem, MEM_VALUE_T val) { - MAU_T *mem = (MAU_T *)vmem; - - mem[0] = (MAU_T)((val >> 0) & 0xff); - mem[1] = (MAU_T)((val >> 8) & 0xff); - mem[2] = (MAU_T)((val >> 16) & 0xff); - mem[3] = (MAU_T)((val >> 24) & 0xff); -} -/* clang-format on */ -#endif // VPX_VPX_PORTS_MEM_OPS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/mem_ops_aligned.h b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/mem_ops_aligned.h deleted file mode 100644 index 8649b876..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/mem_ops_aligned.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_PORTS_MEM_OPS_ALIGNED_H_ -#define VPX_VPX_PORTS_MEM_OPS_ALIGNED_H_ - -#include "vpx/vpx_integer.h" - -/* \file - * \brief Provides portable memory access primitives for operating on aligned - * data - * - * This file is split from mem_ops.h for easier maintenance. See mem_ops.h - * for a more detailed description of these primitives. - */ -#ifndef INCLUDED_BY_MEM_OPS_H -#error Include mem_ops.h, not mem_ops_aligned.h directly. -#endif - -/* Architectures that provide instructions for doing this byte swapping - * could redefine these macros. - */ -#define swap_endian_16(val, raw) \ - do { \ - val = (uint16_t)(((raw >> 8) & 0x00ff) | ((raw << 8) & 0xff00)); \ - } while (0) -#define swap_endian_32(val, raw) \ - do { \ - val = ((raw >> 24) & 0x000000ff) | ((raw >> 8) & 0x0000ff00) | \ - ((raw << 8) & 0x00ff0000) | ((raw << 24) & 0xff000000); \ - } while (0) -#define swap_endian_16_se(val, raw) \ - do { \ - swap_endian_16(val, raw); \ - val = ((val << 16) >> 16); \ - } while (0) -#define swap_endian_32_se(val, raw) swap_endian_32(val, raw) - -#define mem_get_ne_aligned_generic(end, sz) \ - static VPX_INLINE unsigned MEM_VALUE_T mem_get_##end##sz##_aligned( \ - const void *vmem) { \ - const uint##sz##_t *mem = (const uint##sz##_t *)vmem; \ - return *mem; \ - } - -#define mem_get_sne_aligned_generic(end, sz) \ - static VPX_INLINE signed MEM_VALUE_T mem_get_s##end##sz##_aligned( \ - const void *vmem) { \ - const int##sz##_t *mem = (const int##sz##_t *)vmem; \ - return *mem; \ - } - -#define mem_get_se_aligned_generic(end, sz) \ - static VPX_INLINE unsigned MEM_VALUE_T mem_get_##end##sz##_aligned( \ - const void *vmem) { \ - const uint##sz##_t *mem = (const uint##sz##_t *)vmem; \ - unsigned MEM_VALUE_T val, raw = *mem; \ - swap_endian_##sz(val, raw); \ - return val; \ - } - -#define mem_get_sse_aligned_generic(end, sz) \ - static VPX_INLINE signed MEM_VALUE_T mem_get_s##end##sz##_aligned( \ - const void *vmem) { \ - const int##sz##_t *mem = (const int##sz##_t *)vmem; \ - unsigned MEM_VALUE_T val, raw = *mem; \ - swap_endian_##sz##_se(val, raw); \ - return val; \ - } - -#define mem_put_ne_aligned_generic(end, sz) \ - static VPX_INLINE void mem_put_##end##sz##_aligned(void *vmem, \ - MEM_VALUE_T val) { \ - uint##sz##_t *mem = (uint##sz##_t *)vmem; \ - *mem = (uint##sz##_t)val; \ - } - -#define mem_put_se_aligned_generic(end, sz) \ - static VPX_INLINE void mem_put_##end##sz##_aligned(void *vmem, \ - MEM_VALUE_T val) { \ - uint##sz##_t *mem = (uint##sz##_t *)vmem, raw; \ - swap_endian_##sz(raw, val); \ - *mem = (uint##sz##_t)raw; \ - } - -#include "vpx_config.h" -#if CONFIG_BIG_ENDIAN -#define mem_get_be_aligned_generic(sz) mem_get_ne_aligned_generic(be, sz) -#define mem_get_sbe_aligned_generic(sz) mem_get_sne_aligned_generic(be, sz) -#define mem_get_le_aligned_generic(sz) mem_get_se_aligned_generic(le, sz) -#define mem_get_sle_aligned_generic(sz) mem_get_sse_aligned_generic(le, sz) -#define mem_put_be_aligned_generic(sz) mem_put_ne_aligned_generic(be, sz) -#define mem_put_le_aligned_generic(sz) mem_put_se_aligned_generic(le, sz) -#else -#define mem_get_be_aligned_generic(sz) mem_get_se_aligned_generic(be, sz) -#define mem_get_sbe_aligned_generic(sz) mem_get_sse_aligned_generic(be, sz) -#define mem_get_le_aligned_generic(sz) mem_get_ne_aligned_generic(le, sz) -#define mem_get_sle_aligned_generic(sz) mem_get_sne_aligned_generic(le, sz) -#define mem_put_be_aligned_generic(sz) mem_put_se_aligned_generic(be, sz) -#define mem_put_le_aligned_generic(sz) mem_put_ne_aligned_generic(le, sz) -#endif - -/* clang-format off */ -#undef mem_get_be16_aligned -#define mem_get_be16_aligned mem_ops_wrap_symbol(mem_get_be16_aligned) -mem_get_be_aligned_generic(16) - -#undef mem_get_be32_aligned -#define mem_get_be32_aligned mem_ops_wrap_symbol(mem_get_be32_aligned) -mem_get_be_aligned_generic(32) - -#undef mem_get_le16_aligned -#define mem_get_le16_aligned mem_ops_wrap_symbol(mem_get_le16_aligned) -mem_get_le_aligned_generic(16) - -#undef mem_get_le32_aligned -#define mem_get_le32_aligned mem_ops_wrap_symbol(mem_get_le32_aligned) -mem_get_le_aligned_generic(32) - -#undef mem_get_sbe16_aligned -#define mem_get_sbe16_aligned mem_ops_wrap_symbol(mem_get_sbe16_aligned) -mem_get_sbe_aligned_generic(16) - -#undef mem_get_sbe32_aligned -#define mem_get_sbe32_aligned mem_ops_wrap_symbol(mem_get_sbe32_aligned) -mem_get_sbe_aligned_generic(32) - -#undef mem_get_sle16_aligned -#define mem_get_sle16_aligned mem_ops_wrap_symbol(mem_get_sle16_aligned) -mem_get_sle_aligned_generic(16) - -#undef mem_get_sle32_aligned -#define mem_get_sle32_aligned mem_ops_wrap_symbol(mem_get_sle32_aligned) -mem_get_sle_aligned_generic(32) - -#undef mem_put_be16_aligned -#define mem_put_be16_aligned mem_ops_wrap_symbol(mem_put_be16_aligned) -mem_put_be_aligned_generic(16) - -#undef mem_put_be32_aligned -#define mem_put_be32_aligned mem_ops_wrap_symbol(mem_put_be32_aligned) -mem_put_be_aligned_generic(32) - -#undef mem_put_le16_aligned -#define mem_put_le16_aligned mem_ops_wrap_symbol(mem_put_le16_aligned) -mem_put_le_aligned_generic(16) - -#undef mem_put_le32_aligned -#define mem_put_le32_aligned mem_ops_wrap_symbol(mem_put_le32_aligned) -mem_put_le_aligned_generic(32) - -#undef mem_get_ne_aligned_generic -#undef mem_get_se_aligned_generic -#undef mem_get_sne_aligned_generic -#undef mem_get_sse_aligned_generic -#undef mem_put_ne_aligned_generic -#undef mem_put_se_aligned_generic -#undef swap_endian_16 -#undef swap_endian_32 -#undef swap_endian_16_se -#undef swap_endian_32_se -/* clang-format on */ - -#endif // VPX_VPX_PORTS_MEM_OPS_ALIGNED_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/mips.h b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/mips.h deleted file mode 100644 index 439de754..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/mips.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2020 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_PORTS_MIPS_H_ -#define VPX_VPX_PORTS_MIPS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define HAS_MMI 0x01 -#define HAS_MSA 0x02 - -int mips_cpu_caps(void); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_PORTS_MIPS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/mips_cpudetect.c b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/mips_cpudetect.c deleted file mode 100644 index e0eca2d4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/mips_cpudetect.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2020 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include -#include -#include "./vpx_config.h" -#include "vpx_ports/mips.h" - -#if CONFIG_RUNTIME_CPU_DETECT -#if defined(__mips__) && defined(__linux__) -int mips_cpu_caps(void) { - char cpuinfo_line[512]; - int flag = 0x0; - FILE *f = fopen("/proc/cpuinfo", "r"); - if (!f) { - // Assume nothing if /proc/cpuinfo is unavailable. - // This will occur for Chrome sandbox for Pepper or Render process. - return 0; - } - while (fgets(cpuinfo_line, sizeof(cpuinfo_line) - 1, f)) { - if (memcmp(cpuinfo_line, "cpu model", 9) == 0) { - // Workaround early kernel without mmi in ASEs line. - if (strstr(cpuinfo_line, "Loongson-3")) { - flag |= HAS_MMI; - } else if (strstr(cpuinfo_line, "Loongson-2K")) { - flag |= HAS_MMI | HAS_MSA; - } - } - if (memcmp(cpuinfo_line, "ASEs implemented", 16) == 0) { - if (strstr(cpuinfo_line, "loongson-mmi") && - strstr(cpuinfo_line, "loongson-ext")) { - flag |= HAS_MMI; - } - if (strstr(cpuinfo_line, "msa")) { - flag |= HAS_MSA; - } - // ASEs is the last line, so we can break here. - break; - } - } - fclose(f); - return flag; -} -#else /* end __mips__ && __linux__ */ -#error \ - "--enable-runtime-cpu-detect selected, but no CPU detection method " \ -"available for your platform. Reconfigure with --disable-runtime-cpu-detect." -#endif -#else /* end CONFIG_RUNTIME_CPU_DETECT */ -int mips_cpu_caps(void) { return 0; } -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/ppc.h b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/ppc.h deleted file mode 100644 index a11f4e87..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/ppc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_PORTS_PPC_H_ -#define VPX_VPX_PORTS_PPC_H_ -#include - -#include "./vpx_config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define HAS_VSX 0x01 - -int ppc_simd_caps(void); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_PORTS_PPC_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/ppc_cpudetect.c b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/ppc_cpudetect.c deleted file mode 100644 index 374a0271..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/ppc_cpudetect.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include - -#include "./vpx_config.h" -#include "vpx_ports/ppc.h" - -#if CONFIG_RUNTIME_CPU_DETECT -static int cpu_env_flags(int *flags) { - char *env; - env = getenv("VPX_SIMD_CAPS"); - if (env && *env) { - *flags = (int)strtol(env, NULL, 0); - return 0; - } - *flags = 0; - return -1; -} - -static int cpu_env_mask(void) { - char *env; - env = getenv("VPX_SIMD_CAPS_MASK"); - return env && *env ? (int)strtol(env, NULL, 0) : ~0; -} - -int ppc_simd_caps(void) { - int flags; - int mask; - int fd; - ssize_t count; - unsigned int i; - uint64_t buf[64]; - - // If VPX_SIMD_CAPS is set then allow only those capabilities. - if (!cpu_env_flags(&flags)) { - return flags; - } - - mask = cpu_env_mask(); - - fd = open("/proc/self/auxv", O_RDONLY); - if (fd < 0) { - return 0; - } - - while ((count = read(fd, buf, sizeof(buf))) > 0) { - for (i = 0; i < (count / sizeof(*buf)); i += 2) { - if (buf[i] == AT_HWCAP) { -#if HAVE_VSX - if (buf[i + 1] & PPC_FEATURE_HAS_VSX) { - flags |= HAS_VSX; - } -#endif // HAVE_VSX - goto out_close; - } else if (buf[i] == AT_NULL) { - goto out_close; - } - } - } -out_close: - close(fd); - return flags & mask; -} -#else -// If there is no RTCD the function pointers are not used and can not be -// changed. -int ppc_simd_caps(void) { return 0; } -#endif // CONFIG_RUNTIME_CPU_DETECT diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/static_assert.h b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/static_assert.h deleted file mode 100644 index f632d9f1..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/static_assert.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2020 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_PORTS_STATIC_ASSERT_H_ -#define VPX_VPX_PORTS_STATIC_ASSERT_H_ - -#if defined(_MSC_VER) -#define VPX_STATIC_ASSERT(boolexp) \ - do { \ - char vpx_static_assert[(boolexp) ? 1 : -1]; \ - (void)vpx_static_assert; \ - } while (0) -#else // !_MSC_VER -#define VPX_STATIC_ASSERT(boolexp) \ - do { \ - struct { \ - unsigned int vpx_static_assert : (boolexp) ? 1 : -1; \ - } vpx_static_assert; \ - (void)vpx_static_assert; \ - } while (0) -#endif // _MSC_VER - -#endif // VPX_VPX_PORTS_STATIC_ASSERT_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/system_state.h b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/system_state.h deleted file mode 100644 index 32ebd0ed..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/system_state.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_PORTS_SYSTEM_STATE_H_ -#define VPX_VPX_PORTS_SYSTEM_STATE_H_ - -#include "./vpx_config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if (VPX_ARCH_X86 || VPX_ARCH_X86_64) && HAVE_MMX -extern void vpx_clear_system_state(void); -#else -#define vpx_clear_system_state() -#endif // (VPX_ARCH_X86 || VPX_ARCH_X86_64) && HAVE_MMX - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_PORTS_SYSTEM_STATE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/vpx_once.h b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/vpx_once.h deleted file mode 100644 index d33eff43..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/vpx_once.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_PORTS_VPX_ONCE_H_ -#define VPX_VPX_PORTS_VPX_ONCE_H_ - -#include "vpx_config.h" - -/* Implement a function wrapper to guarantee initialization - * thread-safety for library singletons. - * - * NOTE: These functions use static locks, and can only be - * used with one common argument per compilation unit. So - * - * file1.c: - * vpx_once(foo); - * ... - * vpx_once(foo); - * - * file2.c: - * vpx_once(bar); - * - * will ensure foo() and bar() are each called only once, but in - * - * file1.c: - * vpx_once(foo); - * vpx_once(bar): - * - * bar() will never be called because the lock is used up - * by the call to foo(). - */ - -#if CONFIG_MULTITHREAD && defined(_WIN32) -#include -#include -/* Declare a per-compilation-unit state variable to track the progress - * of calling func() only once. This must be at global scope because - * local initializers are not thread-safe in MSVC prior to Visual - * Studio 2015. - * - * As a static, once_state will be zero-initialized as program start. - */ -static LONG once_state; -static void once(void (*func)(void)) { - /* Try to advance once_state from its initial value of 0 to 1. - * Only one thread can succeed in doing so. - */ - if (InterlockedCompareExchange(&once_state, 1, 0) == 0) { - /* We're the winning thread, having set once_state to 1. - * Call our function. */ - func(); - /* Now advance once_state to 2, unblocking any other threads. */ - InterlockedIncrement(&once_state); - return; - } - - /* We weren't the winning thread, but we want to block on - * the state variable so we don't return before func() - * has finished executing elsewhere. - * - * Try to advance once_state from 2 to 2, which is only possible - * after the winning thead advances it from 1 to 2. - */ - while (InterlockedCompareExchange(&once_state, 2, 2) != 2) { - /* State isn't yet 2. Try again. - * - * We are used for singleton initialization functions, - * which should complete quickly. Contention will likewise - * be rare, so it's worthwhile to use a simple but cpu- - * intensive busy-wait instead of successive backoff, - * waiting on a kernel object, or another heavier-weight scheme. - * - * We can at least yield our timeslice. - */ - Sleep(0); - } - - /* We've seen once_state advance to 2, so we know func() - * has been called. And we've left once_state as we found it, - * so other threads will have the same experience. - * - * It's safe to return now. - */ - return; -} - -#elif CONFIG_MULTITHREAD && HAVE_PTHREAD_H -#include -static void once(void (*func)(void)) { - static pthread_once_t lock = PTHREAD_ONCE_INIT; - pthread_once(&lock, func); -} - -#else -/* No-op version that performs no synchronization. *_rtcd() is idempotent, - * so as long as your platform provides atomic loads/stores of pointers - * no synchronization is strictly necessary. - */ - -static void once(void (*func)(void)) { - static volatile int done; - - if (!done) { - func(); - done = 1; - } -} -#endif - -#endif // VPX_VPX_PORTS_VPX_ONCE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/vpx_ports.mk b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/vpx_ports.mk deleted file mode 100644 index b0ad210f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/vpx_ports.mk +++ /dev/null @@ -1,57 +0,0 @@ -## -## Copyright (c) 2012 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - - -PORTS_SRCS-yes += vpx_ports.mk - -PORTS_SRCS-yes += bitops.h -PORTS_SRCS-yes += compiler_attributes.h -PORTS_SRCS-yes += mem.h -PORTS_SRCS-yes += static_assert.h -PORTS_SRCS-yes += system_state.h -PORTS_SRCS-yes += vpx_timer.h - -ifeq ($(VPX_ARCH_X86),yes) -PORTS_SRCS-$(HAVE_MMX) += emms_mmx.c -endif -ifeq ($(VPX_ARCH_X86_64),yes) -# Visual Studio x64 does not support the _mm_empty() intrinsic. -PORTS_SRCS-$(HAVE_MMX) += emms_mmx.asm -endif - -ifeq ($(VPX_ARCH_X86_64),yes) -PORTS_SRCS-$(CONFIG_MSVS) += float_control_word.asm -endif - -ifeq ($(VPX_ARCH_X86)$(VPX_ARCH_X86_64),yes) -PORTS_SRCS-yes += x86.h -PORTS_SRCS-yes += x86_abi_support.asm -endif - -ifeq ($(VPX_ARCH_AARCH64),yes) -PORTS_SRCS-yes += aarch64_cpudetect.c -else -PORTS_SRCS-$(VPX_ARCH_ARM) += aarch32_cpudetect.c -endif -PORTS_SRCS-$(VPX_ARCH_ARM) += arm_cpudetect.h -PORTS_SRCS-$(VPX_ARCH_ARM) += arm.h - -PORTS_SRCS-$(VPX_ARCH_PPC) += ppc_cpudetect.c -PORTS_SRCS-$(VPX_ARCH_PPC) += ppc.h - -PORTS_SRCS-$(VPX_ARCH_MIPS) += mips_cpudetect.c -PORTS_SRCS-$(VPX_ARCH_MIPS) += mips.h - -PORTS_SRCS-$(VPX_ARCH_LOONGARCH) += loongarch_cpudetect.c -PORTS_SRCS-$(VPX_ARCH_LOONGARCH) += loongarch.h - -ifeq ($(VPX_ARCH_MIPS), yes) -PORTS_SRCS-yes += asmdefs_mmi.h -endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/vpx_timer.h b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/vpx_timer.h deleted file mode 100644 index 4934d529..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/vpx_timer.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_PORTS_VPX_TIMER_H_ -#define VPX_VPX_PORTS_VPX_TIMER_H_ - -#include "./vpx_config.h" - -#include "vpx/vpx_integer.h" - -#if CONFIG_OS_SUPPORT - -#if defined(_WIN32) -/* - * Win32 specific includes - */ -#undef NOMINMAX -#define NOMINMAX -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#else -/* - * POSIX specific includes - */ -#include - -/* timersub is not provided by msys at this time. */ -#ifndef timersub -#define timersub(a, b, result) \ - do { \ - (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((result)->tv_usec < 0) { \ - --(result)->tv_sec; \ - (result)->tv_usec += 1000000; \ - } \ - } while (0) -#endif -#endif - -struct vpx_usec_timer { -#if defined(_WIN32) - LARGE_INTEGER begin, end; -#else - struct timeval begin, end; -#endif -}; - -static INLINE void vpx_usec_timer_start(struct vpx_usec_timer *t) { -#if defined(_WIN32) - QueryPerformanceCounter(&t->begin); -#else - gettimeofday(&t->begin, NULL); -#endif -} - -static INLINE void vpx_usec_timer_mark(struct vpx_usec_timer *t) { -#if defined(_WIN32) - QueryPerformanceCounter(&t->end); -#else - gettimeofday(&t->end, NULL); -#endif -} - -static INLINE int64_t vpx_usec_timer_elapsed(struct vpx_usec_timer *t) { -#if defined(_WIN32) - LARGE_INTEGER freq, diff; - - diff.QuadPart = t->end.QuadPart - t->begin.QuadPart; - - QueryPerformanceFrequency(&freq); - return diff.QuadPart * 1000000 / freq.QuadPart; -#else - struct timeval diff; - - timersub(&t->end, &t->begin, &diff); - return (int64_t)diff.tv_sec * 1000000 + diff.tv_usec; -#endif -} - -#else /* CONFIG_OS_SUPPORT = 0*/ - -/* Empty timer functions if CONFIG_OS_SUPPORT = 0 */ -#ifndef timersub -#define timersub(a, b, result) -#endif - -struct vpx_usec_timer { - void *dummy; -}; - -static INLINE void vpx_usec_timer_start(struct vpx_usec_timer *t) {} - -static INLINE void vpx_usec_timer_mark(struct vpx_usec_timer *t) {} - -static INLINE int vpx_usec_timer_elapsed(struct vpx_usec_timer *t) { return 0; } - -#endif /* CONFIG_OS_SUPPORT */ - -#endif // VPX_VPX_PORTS_VPX_TIMER_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/x86.h b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/x86.h deleted file mode 100644 index 3fa50b2f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/x86.h +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_PORTS_X86_H_ -#define VPX_VPX_PORTS_X86_H_ -#include - -#if defined(_MSC_VER) -#include /* For __cpuidex, __rdtsc */ -#endif - -#include "vpx_config.h" -#include "vpx/vpx_integer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - VPX_CPU_UNKNOWN = -1, - VPX_CPU_AMD, - VPX_CPU_AMD_OLD, - VPX_CPU_CENTAUR, - VPX_CPU_CYRIX, - VPX_CPU_INTEL, - VPX_CPU_NEXGEN, - VPX_CPU_NSC, - VPX_CPU_RISE, - VPX_CPU_SIS, - VPX_CPU_TRANSMETA, - VPX_CPU_TRANSMETA_OLD, - VPX_CPU_UMC, - VPX_CPU_VIA, - - VPX_CPU_LAST -} vpx_cpu_t; - -#if defined(__GNUC__) || defined(__ANDROID__) -#if VPX_ARCH_X86_64 -#define cpuid(func, func2, ax, bx, cx, dx) \ - __asm__ __volatile__("cpuid \n\t" \ - : "=a"(ax), "=b"(bx), "=c"(cx), "=d"(dx) \ - : "a"(func), "c"(func2)) -#else -#define cpuid(func, func2, ax, bx, cx, dx) \ - __asm__ __volatile__( \ - "mov %%ebx, %%edi \n\t" \ - "cpuid \n\t" \ - "xchg %%edi, %%ebx \n\t" \ - : "=a"(ax), "=D"(bx), "=c"(cx), "=d"(dx) \ - : "a"(func), "c"(func2)) -#endif -#elif defined(__SUNPRO_C) || \ - defined(__SUNPRO_CC) /* end __GNUC__ or __ANDROID__*/ -#if VPX_ARCH_X86_64 -#define cpuid(func, func2, ax, bx, cx, dx) \ - asm volatile( \ - "xchg %rsi, %rbx \n\t" \ - "cpuid \n\t" \ - "movl %ebx, %edi \n\t" \ - "xchg %rsi, %rbx \n\t" \ - : "=a"(ax), "=D"(bx), "=c"(cx), "=d"(dx) \ - : "a"(func), "c"(func2)) -#else -#define cpuid(func, func2, ax, bx, cx, dx) \ - asm volatile( \ - "pushl %ebx \n\t" \ - "cpuid \n\t" \ - "movl %ebx, %edi \n\t" \ - "popl %ebx \n\t" \ - : "=a"(ax), "=D"(bx), "=c"(cx), "=d"(dx) \ - : "a"(func), "c"(func2)) -#endif -#else /* end __SUNPRO__ */ -#if VPX_ARCH_X86_64 -#if defined(_MSC_VER) && _MSC_VER > 1500 -#define cpuid(func, func2, a, b, c, d) \ - do { \ - int regs[4]; \ - __cpuidex(regs, func, func2); \ - a = regs[0]; \ - b = regs[1]; \ - c = regs[2]; \ - d = regs[3]; \ - } while (0) -#else -#define cpuid(func, func2, a, b, c, d) \ - do { \ - int regs[4]; \ - __cpuid(regs, func); \ - a = regs[0]; \ - b = regs[1]; \ - c = regs[2]; \ - d = regs[3]; \ - } while (0) -#endif -#else -#define cpuid(func, func2, a, b, c, d) \ - __asm mov eax, func __asm mov ecx, func2 __asm cpuid __asm mov a, \ - eax __asm mov b, ebx __asm mov c, ecx __asm mov d, edx -#endif -#endif /* end others */ - -// NaCl has no support for xgetbv or the raw opcode. -#if !defined(__native_client__) && (defined(__i386__) || defined(__x86_64__)) -static INLINE uint64_t xgetbv(void) { - const uint32_t ecx = 0; - uint32_t eax, edx; - // Use the raw opcode for xgetbv for compatibility with older toolchains. - __asm__ volatile(".byte 0x0f, 0x01, 0xd0\n" - : "=a"(eax), "=d"(edx) - : "c"(ecx)); - return ((uint64_t)edx << 32) | eax; -} -#elif (defined(_M_X64) || defined(_M_IX86)) && defined(_MSC_FULL_VER) && \ - _MSC_FULL_VER >= 160040219 // >= VS2010 SP1 -#include -#define xgetbv() _xgetbv(0) -#elif defined(_MSC_VER) && defined(_M_IX86) -static INLINE uint64_t xgetbv(void) { - uint32_t eax_, edx_; - __asm { - xor ecx, ecx // ecx = 0 - // Use the raw opcode for xgetbv for compatibility with older toolchains. - __asm _emit 0x0f __asm _emit 0x01 __asm _emit 0xd0 - mov eax_, eax - mov edx_, edx - } - return ((uint64_t)edx_ << 32) | eax_; -} -#else -#define xgetbv() 0U // no AVX for older x64 or unrecognized toolchains. -#endif - -#if defined(_MSC_VER) && _MSC_VER >= 1700 -#undef NOMINMAX -#define NOMINMAX -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#if WINAPI_FAMILY_PARTITION(WINAPI_FAMILY_APP) -#define getenv(x) NULL -#endif -#endif - -#define HAS_MMX 0x001 -#define HAS_SSE 0x002 -#define HAS_SSE2 0x004 -#define HAS_SSE3 0x008 -#define HAS_SSSE3 0x010 -#define HAS_SSE4_1 0x020 -#define HAS_AVX 0x040 -#define HAS_AVX2 0x080 -#define HAS_AVX512 0x100 -#ifndef BIT -#define BIT(n) (1u << (n)) -#endif - -static INLINE int x86_simd_caps(void) { - unsigned int flags = 0; - unsigned int mask = ~0u; - unsigned int max_cpuid_val, reg_eax, reg_ebx, reg_ecx, reg_edx; - char *env; - (void)reg_ebx; - - /* See if the CPU capabilities are being overridden by the environment */ - env = getenv("VPX_SIMD_CAPS"); - - if (env && *env) return (int)strtol(env, NULL, 0); - - env = getenv("VPX_SIMD_CAPS_MASK"); - - if (env && *env) mask = (unsigned int)strtoul(env, NULL, 0); - - /* Ensure that the CPUID instruction supports extended features */ - cpuid(0, 0, max_cpuid_val, reg_ebx, reg_ecx, reg_edx); - - if (max_cpuid_val < 1) return 0; - - /* Get the standard feature flags */ - cpuid(1, 0, reg_eax, reg_ebx, reg_ecx, reg_edx); - - if (reg_edx & BIT(23)) flags |= HAS_MMX; - - if (reg_edx & BIT(25)) flags |= HAS_SSE; /* aka xmm */ - - if (reg_edx & BIT(26)) flags |= HAS_SSE2; /* aka wmt */ - - if (reg_ecx & BIT(0)) flags |= HAS_SSE3; - - if (reg_ecx & BIT(9)) flags |= HAS_SSSE3; - - if (reg_ecx & BIT(19)) flags |= HAS_SSE4_1; - - // bits 27 (OSXSAVE) & 28 (256-bit AVX) - if ((reg_ecx & (BIT(27) | BIT(28))) == (BIT(27) | BIT(28))) { - // Check for OS-support of YMM state. Necessary for AVX and AVX2. - if ((xgetbv() & 0x6) == 0x6) { - flags |= HAS_AVX; - - if (max_cpuid_val >= 7) { - /* Get the leaf 7 feature flags. Needed to check for AVX2 support */ - cpuid(7, 0, reg_eax, reg_ebx, reg_ecx, reg_edx); - - if (reg_ebx & BIT(5)) flags |= HAS_AVX2; - - // bits 16 (AVX-512F) & 17 (AVX-512DQ) & 28 (AVX-512CD) & - // 30 (AVX-512BW) & 32 (AVX-512VL) - if ((reg_ebx & (BIT(16) | BIT(17) | BIT(28) | BIT(30) | BIT(31))) == - (BIT(16) | BIT(17) | BIT(28) | BIT(30) | BIT(31))) { - // Check for OS-support of ZMM and YMM state. Necessary for AVX-512. - if ((xgetbv() & 0xe6) == 0xe6) flags |= HAS_AVX512; - } - } - } - } - - (void)reg_eax; // Avoid compiler warning on unused-but-set variable. - - return flags & mask; -} - -// Fine-Grain Measurement Functions -// -// If you are timing a small region of code, access the timestamp counter -// (TSC) via: -// -// unsigned int start = x86_tsc_start(); -// ... -// unsigned int end = x86_tsc_end(); -// unsigned int diff = end - start; -// -// The start/end functions introduce a few more instructions than using -// x86_readtsc directly, but prevent the CPU's out-of-order execution from -// affecting the measurement (by having earlier/later instructions be evaluated -// in the time interval). See the white paper, "How to Benchmark Code -// Execution Times on Intel(R) IA-32 and IA-64 Instruction Set Architectures" by -// Gabriele Paoloni for more information. -// -// If you are timing a large function (CPU time > a couple of seconds), use -// x86_readtsc64 to read the timestamp counter in a 64-bit integer. The -// out-of-order leakage that can occur is minimal compared to total runtime. -static INLINE unsigned int x86_readtsc(void) { -#if defined(__GNUC__) - unsigned int tsc; - __asm__ __volatile__("rdtsc\n\t" : "=a"(tsc) :); - return tsc; -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) - unsigned int tsc; - asm volatile("rdtsc\n\t" : "=a"(tsc) :); - return tsc; -#else -#if VPX_ARCH_X86_64 - return (unsigned int)__rdtsc(); -#else - __asm rdtsc; -#endif -#endif -} -// 64-bit CPU cycle counter -static INLINE uint64_t x86_readtsc64(void) { -#if defined(__GNUC__) - uint32_t hi, lo; - __asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi)); - return ((uint64_t)hi << 32) | lo; -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) - uint_t hi, lo; - asm volatile("rdtsc\n\t" : "=a"(lo), "=d"(hi)); - return ((uint64_t)hi << 32) | lo; -#else -#if VPX_ARCH_X86_64 - return (uint64_t)__rdtsc(); -#else - __asm rdtsc; -#endif -#endif -} - -// 32-bit CPU cycle counter with a partial fence against out-of-order execution. -static INLINE unsigned int x86_readtscp(void) { -#if defined(__GNUC__) - unsigned int tscp; - __asm__ __volatile__("rdtscp\n\t" : "=a"(tscp) :); - return tscp; -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) - unsigned int tscp; - asm volatile("rdtscp\n\t" : "=a"(tscp) :); - return tscp; -#elif defined(_MSC_VER) - unsigned int ui; - return (unsigned int)__rdtscp(&ui); -#else -#if VPX_ARCH_X86_64 - return (unsigned int)__rdtscp(); -#else - __asm rdtscp; -#endif -#endif -} - -static INLINE unsigned int x86_tsc_start(void) { - unsigned int reg_eax, reg_ebx, reg_ecx, reg_edx; - // This call should not be removed. See function notes above. - cpuid(0, 0, reg_eax, reg_ebx, reg_ecx, reg_edx); - // Avoid compiler warnings on unused-but-set variables. - (void)reg_eax; - (void)reg_ebx; - (void)reg_ecx; - (void)reg_edx; - return x86_readtsc(); -} - -static INLINE unsigned int x86_tsc_end(void) { - uint32_t v = x86_readtscp(); - unsigned int reg_eax, reg_ebx, reg_ecx, reg_edx; - // This call should not be removed. See function notes above. - cpuid(0, 0, reg_eax, reg_ebx, reg_ecx, reg_edx); - // Avoid compiler warnings on unused-but-set variables. - (void)reg_eax; - (void)reg_ebx; - (void)reg_ecx; - (void)reg_edx; - return v; -} - -#if defined(__GNUC__) -#define x86_pause_hint() __asm__ __volatile__("pause \n\t") -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) -#define x86_pause_hint() asm volatile("pause \n\t") -#else -#if VPX_ARCH_X86_64 -#define x86_pause_hint() _mm_pause(); -#else -#define x86_pause_hint() __asm pause -#endif -#endif - -#if defined(__GNUC__) -static void x87_set_control_word(unsigned short mode) { - __asm__ __volatile__("fldcw %0" : : "m"(*&mode)); -} -static unsigned short x87_get_control_word(void) { - unsigned short mode; - __asm__ __volatile__("fstcw %0\n\t" : "=m"(*&mode) :); - return mode; -} -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) -static void x87_set_control_word(unsigned short mode) { - asm volatile("fldcw %0" : : "m"(*&mode)); -} -static unsigned short x87_get_control_word(void) { - unsigned short mode; - asm volatile("fstcw %0\n\t" : "=m"(*&mode) :); - return mode; -} -#elif VPX_ARCH_X86_64 -/* No fldcw intrinsics on Windows x64, punt to external asm */ -extern void vpx_winx64_fldcw(unsigned short mode); -extern unsigned short vpx_winx64_fstcw(void); -#define x87_set_control_word vpx_winx64_fldcw -#define x87_get_control_word vpx_winx64_fstcw -#else -static void x87_set_control_word(unsigned short mode) { - __asm { fldcw mode } -} -static unsigned short x87_get_control_word(void) { - unsigned short mode; - __asm { fstcw mode } - return mode; -} -#endif - -static INLINE unsigned int x87_set_double_precision(void) { - unsigned int mode = x87_get_control_word(); - // Intel 64 and IA-32 Architectures Developer's Manual: Vol. 1 - // https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-1-manual.pdf - // 8.1.5.2 Precision Control Field - // Bits 8 and 9 (0x300) of the x87 FPU Control Word ("Precision Control") - // determine the number of bits used in floating point calculations. To match - // later SSE instructions restrict x87 operations to Double Precision (0x200). - // Precision PC Field - // Single Precision (24-Bits) 00B - // Reserved 01B - // Double Precision (53-Bits) 10B - // Extended Precision (64-Bits) 11B - x87_set_control_word((mode & ~0x300u) | 0x200u); - return mode; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_PORTS_X86_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/x86_abi_support.asm b/presentation/src/main/cpp/third_party/libvpx/vpx_ports/x86_abi_support.asm deleted file mode 100644 index 6b2d6b96..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_ports/x86_abi_support.asm +++ /dev/null @@ -1,425 +0,0 @@ -; -; Copyright (c) 2010 The WebM project authors. All Rights Reserved. -; -; Use of this source code is governed by a BSD-style license -; that can be found in the LICENSE file in the root of the source -; tree. An additional intellectual property rights grant can be found -; in the file PATENTS. All contributing project authors may -; be found in the AUTHORS file in the root of the source tree. -; - - -%include "vpx_config.asm" - -; 32/64 bit compatibility macros -; -; In general, we make the source use 64 bit syntax, then twiddle with it using -; the preprocessor to get the 32 bit syntax on 32 bit platforms. -; -%ifidn __OUTPUT_FORMAT__,elf32 -%define ABI_IS_32BIT 1 -%elifidn __OUTPUT_FORMAT__,macho32 -%define ABI_IS_32BIT 1 -%elifidn __OUTPUT_FORMAT__,win32 -%define ABI_IS_32BIT 1 -%elifidn __OUTPUT_FORMAT__,aout -%define ABI_IS_32BIT 1 -%else -%define ABI_IS_32BIT 0 -%endif - -%if ABI_IS_32BIT -%define rax eax -%define rbx ebx -%define rcx ecx -%define rdx edx -%define rsi esi -%define rdi edi -%define rsp esp -%define rbp ebp -%define movsxd mov -%macro movq 2 - %ifidn %1,eax - movd %1,%2 - %elifidn %2,eax - movd %1,%2 - %elifidn %1,ebx - movd %1,%2 - %elifidn %2,ebx - movd %1,%2 - %elifidn %1,ecx - movd %1,%2 - %elifidn %2,ecx - movd %1,%2 - %elifidn %1,edx - movd %1,%2 - %elifidn %2,edx - movd %1,%2 - %elifidn %1,esi - movd %1,%2 - %elifidn %2,esi - movd %1,%2 - %elifidn %1,edi - movd %1,%2 - %elifidn %2,edi - movd %1,%2 - %elifidn %1,esp - movd %1,%2 - %elifidn %2,esp - movd %1,%2 - %elifidn %1,ebp - movd %1,%2 - %elifidn %2,ebp - movd %1,%2 - %else - movq %1,%2 - %endif -%endmacro -%endif - - -; LIBVPX_YASM_WIN64 -; Set LIBVPX_YASM_WIN64 if output is Windows 64bit so the code will work if x64 -; or win64 is defined on the Yasm command line. -%ifidn __OUTPUT_FORMAT__,win64 -%define LIBVPX_YASM_WIN64 1 -%elifidn __OUTPUT_FORMAT__,x64 -%define LIBVPX_YASM_WIN64 1 -%else -%define LIBVPX_YASM_WIN64 0 -%endif - -; Declare groups of platforms -%ifidn __OUTPUT_FORMAT__,elf32 - %define LIBVPX_ELF 1 -%elifidn __OUTPUT_FORMAT__,elfx32 - %define LIBVPX_ELF 1 -%elifidn __OUTPUT_FORMAT__,elf64 - %define LIBVPX_ELF 1 -%else - %define LIBVPX_ELF 0 -%endif - -%ifidn __OUTPUT_FORMAT__,macho32 - %define LIBVPX_MACHO 1 -%elifidn __OUTPUT_FORMAT__,macho64 - %define LIBVPX_MACHO 1 -%else - %define LIBVPX_MACHO 0 -%endif - -; sym() -; Return the proper symbol name for the target ABI. -; -; Certain ABIs, notably MS COFF and Darwin MACH-O, require that symbols -; with C linkage be prefixed with an underscore. -; -%if LIBVPX_ELF || LIBVPX_YASM_WIN64 - %define sym(x) x -%else - ; Mach-O / COFF - %define sym(x) _ %+ x -%endif - -; globalsym() -; Return a global declaration with the proper decoration for the target ABI. -; -; When CHROMIUM is defined, include attributes to hide the symbol from the -; global namespace. -; -; Chromium doesn't like exported global symbols due to symbol clashing with -; plugins among other things. -; -; Requires Chromium's patched copy of yasm: -; http://src.chromium.org/viewvc/chrome?view=rev&revision=73761 -; http://www.tortall.net/projects/yasm/ticket/236 -; or nasm > 2.14. -; -%ifdef CHROMIUM - %ifdef __NASM_VER__ - %if __NASM_VERSION_ID__ < 0x020e0000 ; 2.14 - ; nasm < 2.14 does not support :private_extern directive - %fatal Must use nasm 2.14 or newer - %endif - %endif - - %if LIBVPX_ELF - %define globalsym(x) global sym(x) %+ :function hidden - %elif LIBVPX_MACHO - %define globalsym(x) global sym(x) %+ :private_extern - %else - ; COFF / PE32+ - %define globalsym(x) global sym(x) - %endif -%else - %define globalsym(x) global sym(x) -%endif - -; arg() -; Return the address specification of the given argument -; -%if ABI_IS_32BIT - %define arg(x) [ebp+8+4*x] -%else - ; 64 bit ABI passes arguments in registers. This is a workaround to get up - ; and running quickly. Relies on SHADOW_ARGS_TO_STACK - %if LIBVPX_YASM_WIN64 - %define arg(x) [rbp+16+8*x] - %else - %define arg(x) [rbp-8-8*x] - %endif -%endif - -; REG_SZ_BYTES, REG_SZ_BITS -; Size of a register -%if ABI_IS_32BIT -%define REG_SZ_BYTES 4 -%define REG_SZ_BITS 32 -%else -%define REG_SZ_BYTES 8 -%define REG_SZ_BITS 64 -%endif - - -; ALIGN_STACK -; This macro aligns the stack to the given alignment (in bytes). The stack -; is left such that the previous value of the stack pointer is the first -; argument on the stack (ie, the inverse of this macro is 'pop rsp.') -; This macro uses one temporary register, which is not preserved, and thus -; must be specified as an argument. -%macro ALIGN_STACK 2 - mov %2, rsp - and rsp, -%1 - lea rsp, [rsp - (%1 - REG_SZ_BYTES)] - push %2 -%endmacro - - -; -; The Microsoft assembler tries to impose a certain amount of type safety in -; its register usage. YASM doesn't recognize these directives, so we just -; %define them away to maintain as much compatibility as possible with the -; original inline assembler we're porting from. -; -%idefine PTR -%idefine XMMWORD -%idefine MMWORD - -; PIC macros -; -%if ABI_IS_32BIT - %if CONFIG_PIC=1 - %ifidn __OUTPUT_FORMAT__,elf32 - %define WRT_PLT wrt ..plt - %macro GET_GOT 1 - extern _GLOBAL_OFFSET_TABLE_ - push %1 - call %%get_got - %%sub_offset: - jmp %%exitGG - %%get_got: - mov %1, [esp] - add %1, _GLOBAL_OFFSET_TABLE_ + $$ - %%sub_offset wrt ..gotpc - ret - %%exitGG: - %undef GLOBAL - %define GLOBAL(x) x + %1 wrt ..gotoff - %undef RESTORE_GOT - %define RESTORE_GOT pop %1 - %endmacro - %elifidn __OUTPUT_FORMAT__,macho32 - %macro GET_GOT 1 - push %1 - call %%get_got - %%get_got: - pop %1 - %undef GLOBAL - %define GLOBAL(x) x + %1 - %%get_got - %undef RESTORE_GOT - %define RESTORE_GOT pop %1 - %endmacro - %endif - %endif - - %ifdef CHROMIUM - %ifidn __OUTPUT_FORMAT__,macho32 - %define HIDDEN_DATA(x) x:private_extern - %else - %define HIDDEN_DATA(x) x - %endif - %else - %define HIDDEN_DATA(x) x - %endif -%else - %macro GET_GOT 1 - %endmacro - %define GLOBAL(x) rel x - %ifidn __OUTPUT_FORMAT__,elf64 - %define WRT_PLT wrt ..plt - %define HIDDEN_DATA(x) x:data hidden - %elifidn __OUTPUT_FORMAT__,elfx32 - %define WRT_PLT wrt ..plt - %define HIDDEN_DATA(x) x:data hidden - %elifidn __OUTPUT_FORMAT__,macho64 - %ifdef CHROMIUM - %define HIDDEN_DATA(x) x:private_extern - %else - %define HIDDEN_DATA(x) x - %endif - %else - %define HIDDEN_DATA(x) x - %endif -%endif -%ifnmacro GET_GOT - %macro GET_GOT 1 - %endmacro - %define GLOBAL(x) x -%endif -%ifndef RESTORE_GOT -%define RESTORE_GOT -%endif -%ifndef WRT_PLT -%define WRT_PLT -%endif - -%if ABI_IS_32BIT - %macro SHADOW_ARGS_TO_STACK 1 - %endm - %define UNSHADOW_ARGS -%else -%if LIBVPX_YASM_WIN64 - %macro SHADOW_ARGS_TO_STACK 1 ; argc - %if %1 > 0 - mov arg(0),rcx - %endif - %if %1 > 1 - mov arg(1),rdx - %endif - %if %1 > 2 - mov arg(2),r8 - %endif - %if %1 > 3 - mov arg(3),r9 - %endif - %endm -%else - %macro SHADOW_ARGS_TO_STACK 1 ; argc - %if %1 > 0 - push rdi - %endif - %if %1 > 1 - push rsi - %endif - %if %1 > 2 - push rdx - %endif - %if %1 > 3 - push rcx - %endif - %if %1 > 4 - push r8 - %endif - %if %1 > 5 - push r9 - %endif - %if %1 > 6 - %assign i %1-6 - %assign off 16 - %rep i - mov rax,[rbp+off] - push rax - %assign off off+8 - %endrep - %endif - %endm -%endif - %define UNSHADOW_ARGS mov rsp, rbp -%endif - -; Win64 ABI requires that XMM6:XMM15 are callee saved -; SAVE_XMM n, [u] -; store registers 6-n on the stack -; if u is specified, use unaligned movs. -; Win64 ABI requires 16 byte stack alignment, but then pushes an 8 byte return -; value. Typically we follow this up with 'push rbp' - re-aligning the stack - -; but in some cases this is not done and unaligned movs must be used. -%if LIBVPX_YASM_WIN64 -%macro SAVE_XMM 1-2 a - %if %1 < 6 - %error Only xmm registers 6-15 must be preserved - %else - %assign last_xmm %1 - %define movxmm movdq %+ %2 - %assign xmm_stack_space ((last_xmm - 5) * 16) - sub rsp, xmm_stack_space - %assign i 6 - %rep (last_xmm - 5) - movxmm [rsp + ((i - 6) * 16)], xmm %+ i - %assign i i+1 - %endrep - %endif -%endmacro -%macro RESTORE_XMM 0 - %ifndef last_xmm - %error RESTORE_XMM must be paired with SAVE_XMM n - %else - %assign i last_xmm - %rep (last_xmm - 5) - movxmm xmm %+ i, [rsp +((i - 6) * 16)] - %assign i i-1 - %endrep - add rsp, xmm_stack_space - ; there are a couple functions which return from multiple places. - ; otherwise, we could uncomment these: - ; %undef last_xmm - ; %undef xmm_stack_space - ; %undef movxmm - %endif -%endmacro -%else -%macro SAVE_XMM 1-2 -%endmacro -%macro RESTORE_XMM 0 -%endmacro -%endif - -; Name of the rodata section -; -; .rodata seems to be an elf-ism, as it doesn't work on OSX. -; -%ifidn __OUTPUT_FORMAT__,macho64 -%define SECTION_RODATA section .text -%elifidn __OUTPUT_FORMAT__,macho32 -%macro SECTION_RODATA 0 -section .text -%endmacro -%elifidn __OUTPUT_FORMAT__,aout -%define SECTION_RODATA section .data -%else -%define SECTION_RODATA section .rodata -%endif - - -; Tell GNU ld that we don't require an executable stack. -%ifidn __OUTPUT_FORMAT__,elf32 -section .note.GNU-stack noalloc noexec nowrite progbits -section .text -%elifidn __OUTPUT_FORMAT__,elf64 -section .note.GNU-stack noalloc noexec nowrite progbits -section .text -%elifidn __OUTPUT_FORMAT__,elfx32 -section .note.GNU-stack noalloc noexec nowrite progbits -section .text -%endif - -; On Android platforms use lrand48 when building postproc routines. Prior to L -; rand() was not available. -%if CONFIG_POSTPROC=1 || CONFIG_VP9_POSTPROC=1 -%ifdef __ANDROID__ -extern sym(lrand48) -%define LIBVPX_RAND lrand48 -%else -extern sym(rand) -%define LIBVPX_RAND rand -%endif -%endif ; CONFIG_POSTPROC || CONFIG_VP9_POSTPROC diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/generic/gen_scalers.c b/presentation/src/main/cpp/third_party/libvpx/vpx_scale/generic/gen_scalers.c deleted file mode 100644 index d8db4b35..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/generic/gen_scalers.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpx_scale_rtcd.h" -#include "vpx_scale/vpx_scale.h" -#include "vpx_mem/vpx_mem.h" -/**************************************************************************** - * Imports - ****************************************************************************/ - -/**************************************************************************** - * - * - * INPUTS : const unsigned char *source : Pointer to source data. - * unsigned int source_width : Stride of source. - * unsigned char *dest : Pointer to destination data. - * unsigned int dest_width : Stride of dest (UNUSED). - * - * OUTPUTS : None. - * - * RETURNS : void - * - * FUNCTION : Copies horizontal line of pixels from source to - * destination scaling up by 4 to 5. - * - * SPECIAL NOTES : None. - * - ****************************************************************************/ -void vp8_horizontal_line_5_4_scale_c(const unsigned char *source, - unsigned int source_width, - unsigned char *dest, - unsigned int dest_width) { - unsigned i; - unsigned int a, b, c, d, e; - unsigned char *des = dest; - const unsigned char *src = source; - - (void)dest_width; - - for (i = 0; i < source_width; i += 5) { - a = src[0]; - b = src[1]; - c = src[2]; - d = src[3]; - e = src[4]; - - des[0] = (unsigned char)a; - des[1] = (unsigned char)((b * 192 + c * 64 + 128) >> 8); - des[2] = (unsigned char)((c * 128 + d * 128 + 128) >> 8); - des[3] = (unsigned char)((d * 64 + e * 192 + 128) >> 8); - - src += 5; - des += 4; - } -} - -void vp8_vertical_band_5_4_scale_c(unsigned char *source, - unsigned int src_pitch, unsigned char *dest, - unsigned int dest_pitch, - unsigned int dest_width) { - unsigned int i; - unsigned int a, b, c, d, e; - unsigned char *des = dest; - unsigned char *src = source; - - for (i = 0; i < dest_width; i++) { - a = src[0 * src_pitch]; - b = src[1 * src_pitch]; - c = src[2 * src_pitch]; - d = src[3 * src_pitch]; - e = src[4 * src_pitch]; - - des[0 * dest_pitch] = (unsigned char)a; - des[1 * dest_pitch] = (unsigned char)((b * 192 + c * 64 + 128) >> 8); - des[2 * dest_pitch] = (unsigned char)((c * 128 + d * 128 + 128) >> 8); - des[3 * dest_pitch] = (unsigned char)((d * 64 + e * 192 + 128) >> 8); - - src++; - des++; - } -} - -/*7*************************************************************************** - * - * ROUTINE : vp8_horizontal_line_3_5_scale_c - * - * INPUTS : const unsigned char *source : Pointer to source data. - * unsigned int source_width : Stride of source. - * unsigned char *dest : Pointer to destination data. - * unsigned int dest_width : Stride of dest (UNUSED). - * - * OUTPUTS : None. - * - * RETURNS : void - * - * FUNCTION : Copies horizontal line of pixels from source to - * destination scaling up by 3 to 5. - * - * SPECIAL NOTES : None. - * - * - ****************************************************************************/ -void vp8_horizontal_line_5_3_scale_c(const unsigned char *source, - unsigned int source_width, - unsigned char *dest, - unsigned int dest_width) { - unsigned int i; - unsigned int a, b, c, d, e; - unsigned char *des = dest; - const unsigned char *src = source; - - (void)dest_width; - - for (i = 0; i < source_width; i += 5) { - a = src[0]; - b = src[1]; - c = src[2]; - d = src[3]; - e = src[4]; - - des[0] = (unsigned char)a; - des[1] = (unsigned char)((b * 85 + c * 171 + 128) >> 8); - des[2] = (unsigned char)((d * 171 + e * 85 + 128) >> 8); - - src += 5; - des += 3; - } -} - -void vp8_vertical_band_5_3_scale_c(unsigned char *source, - unsigned int src_pitch, unsigned char *dest, - unsigned int dest_pitch, - unsigned int dest_width) { - unsigned int i; - unsigned int a, b, c, d, e; - unsigned char *des = dest; - unsigned char *src = source; - - for (i = 0; i < dest_width; i++) { - a = src[0 * src_pitch]; - b = src[1 * src_pitch]; - c = src[2 * src_pitch]; - d = src[3 * src_pitch]; - e = src[4 * src_pitch]; - - des[0 * dest_pitch] = (unsigned char)a; - des[1 * dest_pitch] = (unsigned char)((b * 85 + c * 171 + 128) >> 8); - des[2 * dest_pitch] = (unsigned char)((d * 171 + e * 85 + 128) >> 8); - - src++; - des++; - } -} - -/**************************************************************************** - * - * ROUTINE : vp8_horizontal_line_1_2_scale_c - * - * INPUTS : const unsigned char *source : Pointer to source data. - * unsigned int source_width : Stride of source. - * unsigned char *dest : Pointer to destination data. - * unsigned int dest_width : Stride of dest (UNUSED). - * - * OUTPUTS : None. - * - * RETURNS : void - * - * FUNCTION : Copies horizontal line of pixels from source to - * destination scaling up by 1 to 2. - * - * SPECIAL NOTES : None. - * - ****************************************************************************/ -void vp8_horizontal_line_2_1_scale_c(const unsigned char *source, - unsigned int source_width, - unsigned char *dest, - unsigned int dest_width) { - unsigned int i; - unsigned int a; - unsigned char *des = dest; - const unsigned char *src = source; - - (void)dest_width; - - for (i = 0; i < source_width; i += 2) { - a = src[0]; - des[0] = (unsigned char)(a); - src += 2; - des += 1; - } -} - -void vp8_vertical_band_2_1_scale_c(unsigned char *source, - unsigned int src_pitch, unsigned char *dest, - unsigned int dest_pitch, - unsigned int dest_width) { - (void)dest_pitch; - (void)src_pitch; - memcpy(dest, source, dest_width); -} - -void vp8_vertical_band_2_1_scale_i_c(unsigned char *source, - unsigned int src_pitch, - unsigned char *dest, - unsigned int dest_pitch, - unsigned int dest_width) { - int i; - int temp; - int width = dest_width; - - (void)dest_pitch; - - for (i = 0; i < width; i++) { - temp = 8; - temp += source[i - (int)src_pitch] * 3; - temp += source[i] * 10; - temp += source[i + src_pitch] * 3; - temp >>= 4; - dest[i] = (unsigned char)(temp); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/generic/vpx_scale.c b/presentation/src/main/cpp/third_party/libvpx/vpx_scale/generic/vpx_scale.c deleted file mode 100644 index 36d6d362..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/generic/vpx_scale.c +++ /dev/null @@ -1,532 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/**************************************************************************** - * - * Module Title : scale.c - * - * Description : Image scaling functions. - * - ***************************************************************************/ - -/**************************************************************************** - * Header Files - ****************************************************************************/ -#include - -#include "./vpx_scale_rtcd.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_scale/vpx_scale.h" -#include "vpx_scale/yv12config.h" - -typedef struct { - int expanded_frame_width; - int expanded_frame_height; - - int HScale; - int HRatio; - int VScale; - int VRatio; - - YV12_BUFFER_CONFIG *src_yuv_config; - YV12_BUFFER_CONFIG *dst_yuv_config; - -} SCALE_VARS; - -/**************************************************************************** - * - * ROUTINE : scale1d_2t1_i - * - * INPUTS : const unsigned char *source : Pointer to data to be scaled. - * int source_step : Number of pixels to step on in - * source. - * unsigned int source_scale : Scale for source (UNUSED). - * unsigned int source_length : Length of source (UNUSED). - * unsigned char *dest : Pointer to output data array. - * int dest_step : Number of pixels to step on in - * destination. - * unsigned int dest_scale : Scale for destination - * (UNUSED). - * unsigned int dest_length : Length of destination. - * - * OUTPUTS : None. - * - * RETURNS : void - * - * FUNCTION : Performs 2-to-1 interpolated scaling. - * - * SPECIAL NOTES : None. - * - ****************************************************************************/ -static void scale1d_2t1_i(const unsigned char *source, int source_step, - unsigned int source_scale, unsigned int source_length, - unsigned char *dest, int dest_step, - unsigned int dest_scale, unsigned int dest_length) { - unsigned int i, j; - unsigned int temp; - int source_pitch = source_step; - (void)source_length; - (void)source_scale; - (void)dest_scale; - - source_step *= 2; - dest[0] = source[0]; - - for (i = dest_step, j = source_step; i < dest_length * dest_step; - i += dest_step, j += source_step) { - temp = 8; - temp += 3 * source[j - source_pitch]; - temp += 10 * source[j]; - temp += 3 * source[j + source_pitch]; - temp >>= 4; - dest[i] = (char)(temp); - } -} - -/**************************************************************************** - * - * ROUTINE : scale1d_2t1_ps - * - * INPUTS : const unsigned char *source : Pointer to data to be scaled. - * int source_step : Number of pixels to step on in - * source. - * unsigned int source_scale : Scale for source (UNUSED). - * unsigned int source_length : Length of source (UNUSED). - * unsigned char *dest : Pointer to output data array. - * int dest_step : Number of pixels to step on in - * destination. - * unsigned int dest_scale : Scale for destination - * (UNUSED). - * unsigned int dest_length : Length of destination. - * - * OUTPUTS : None. - * - * RETURNS : void - * - * FUNCTION : Performs 2-to-1 point subsampled scaling. - * - * SPECIAL NOTES : None. - * - ****************************************************************************/ -static void scale1d_2t1_ps(const unsigned char *source, int source_step, - unsigned int source_scale, - unsigned int source_length, unsigned char *dest, - int dest_step, unsigned int dest_scale, - unsigned int dest_length) { - unsigned int i, j; - - (void)source_length; - (void)source_scale; - (void)dest_scale; - - source_step *= 2; - j = 0; - - for (i = 0; i < dest_length * dest_step; i += dest_step, j += source_step) - dest[i] = source[j]; -} -/**************************************************************************** - * - * ROUTINE : scale1d_c - * - * INPUTS : const unsigned char *source : Pointer to data to be scaled. - * int source_step : Number of pixels to step on in - * source. - * unsigned int source_scale : Scale for source. - * unsigned int source_length : Length of source (UNUSED). - * unsigned char *dest : Pointer to output data array. - * int dest_step : Number of pixels to step on in - * destination. - * unsigned int dest_scale : Scale for destination. - * unsigned int dest_length : Length of destination. - * - * OUTPUTS : None. - * - * RETURNS : void - * - * FUNCTION : Performs linear interpolation in one dimension. - * - * SPECIAL NOTES : None. - * - ****************************************************************************/ -static void scale1d_c(const unsigned char *source, int source_step, - unsigned int source_scale, unsigned int source_length, - unsigned char *dest, int dest_step, - unsigned int dest_scale, unsigned int dest_length) { - unsigned int i; - unsigned int round_value = dest_scale / 2; - unsigned int left_modifier = dest_scale; - unsigned int right_modifier = 0; - unsigned char left_pixel = *source; - unsigned char right_pixel = *(source + source_step); - - (void)source_length; - - /* These asserts are needed if there are boundary issues... */ - /*assert ( dest_scale > source_scale );*/ - /*assert ( (source_length-1) * dest_scale >= (dest_length-1) * source_scale - * );*/ - - assert(dest_scale != 0); - for (i = 0; i < dest_length * dest_step; i += dest_step) { - dest[i] = (char)((left_modifier * left_pixel + - right_modifier * right_pixel + round_value) / - dest_scale); - - right_modifier += source_scale; - - while (right_modifier > dest_scale) { - right_modifier -= dest_scale; - source += source_step; - left_pixel = *source; - right_pixel = *(source + source_step); - } - - left_modifier = dest_scale - right_modifier; - } -} - -/**************************************************************************** - * - * ROUTINE : Scale2D - * - * INPUTS : const unsigned char *source : Pointer to data to be - * scaled. - * int source_pitch : Stride of source image. - * unsigned int source_width : Width of input image. - * unsigned int source_height : Height of input image. - * unsigned char *dest : Pointer to output data - * array. - * int dest_pitch : Stride of destination - * image. - * unsigned int dest_width : Width of destination image. - * unsigned int dest_height : Height of destination - * image. - * unsigned char *temp_area : Pointer to temp work area. - * unsigned char temp_area_height : Height of temp work area. - * unsigned int hscale : Horizontal scale factor - * numerator. - * unsigned int hratio : Horizontal scale factor - * denominator. - * unsigned int vscale : Vertical scale factor - * numerator. - * unsigned int vratio : Vertical scale factor - * denominator. - * unsigned int interlaced : Interlace flag. - * - * OUTPUTS : None. - * - * RETURNS : void - * - * FUNCTION : Performs 2-tap linear interpolation in two dimensions. - * - * SPECIAL NOTES : Expansion is performed one band at a time to help with - * caching. - * - ****************************************************************************/ -static void Scale2D( - /*const*/ - unsigned char *source, int source_pitch, unsigned int source_width, - unsigned int source_height, unsigned char *dest, int dest_pitch, - unsigned int dest_width, unsigned int dest_height, unsigned char *temp_area, - unsigned char temp_area_height, unsigned int hscale, unsigned int hratio, - unsigned int vscale, unsigned int vratio, unsigned int interlaced) { - /*unsigned*/ - int i, j, k; - int bands; - int dest_band_height; - int source_band_height; - - typedef void (*Scale1D)(const unsigned char *source, int source_step, - unsigned int source_scale, unsigned int source_length, - unsigned char *dest, int dest_step, - unsigned int dest_scale, unsigned int dest_length); - - Scale1D Scale1Dv = scale1d_c; - Scale1D Scale1Dh = scale1d_c; - - void (*horiz_line_scale)(const unsigned char *, unsigned int, unsigned char *, - unsigned int) = NULL; - void (*vert_band_scale)(unsigned char *, unsigned int, unsigned char *, - unsigned int, unsigned int) = NULL; - - int ratio_scalable = 1; - int interpolation = 0; - - unsigned char *source_base; - unsigned char *line_src; - - source_base = (unsigned char *)source; - - if (source_pitch < 0) { - int offset; - - offset = (source_height - 1); - offset *= source_pitch; - - source_base += offset; - } - - /* find out the ratio for each direction */ - switch (hratio * 10 / hscale) { - case 8: - /* 4-5 Scale in Width direction */ - horiz_line_scale = vp8_horizontal_line_5_4_scale; - break; - case 6: - /* 3-5 Scale in Width direction */ - horiz_line_scale = vp8_horizontal_line_5_3_scale; - break; - case 5: - /* 1-2 Scale in Width direction */ - horiz_line_scale = vp8_horizontal_line_2_1_scale; - break; - default: - /* The ratio is not acceptable now */ - /* throw("The ratio is not acceptable for now!"); */ - ratio_scalable = 0; - break; - } - - switch (vratio * 10 / vscale) { - case 8: - /* 4-5 Scale in vertical direction */ - vert_band_scale = vp8_vertical_band_5_4_scale; - source_band_height = 5; - dest_band_height = 4; - break; - case 6: - /* 3-5 Scale in vertical direction */ - vert_band_scale = vp8_vertical_band_5_3_scale; - source_band_height = 5; - dest_band_height = 3; - break; - case 5: - /* 1-2 Scale in vertical direction */ - - if (interlaced) { - /* if the content is interlaced, point sampling is used */ - vert_band_scale = vp8_vertical_band_2_1_scale; - } else { - interpolation = 1; - /* if the content is progressive, interplo */ - vert_band_scale = vp8_vertical_band_2_1_scale_i; - } - - source_band_height = 2; - dest_band_height = 1; - break; - default: - /* The ratio is not acceptable now */ - /* throw("The ratio is not acceptable for now!"); */ - ratio_scalable = 0; - break; - } - - if (ratio_scalable) { - if (source_height == dest_height) { - /* for each band of the image */ - for (k = 0; k < (int)dest_height; k++) { - horiz_line_scale(source, source_width, dest, dest_width); - source += source_pitch; - dest += dest_pitch; - } - - return; - } - - if (interpolation) { - if (source < source_base) source = source_base; - - horiz_line_scale(source, source_width, temp_area, dest_width); - } - - for (k = 0; - k < (int)(dest_height + dest_band_height - 1) / dest_band_height; - k++) { - /* scale one band horizontally */ - for (i = 0; i < source_band_height; i++) { - /* Trap case where we could read off the base of the source buffer */ - - line_src = (unsigned char *)source + i * source_pitch; - - if (line_src < source_base) line_src = source_base; - - horiz_line_scale(line_src, source_width, - temp_area + (i + 1) * dest_pitch, dest_width); - } - - /* Vertical scaling is in place */ - vert_band_scale(temp_area + dest_pitch, dest_pitch, dest, dest_pitch, - dest_width); - - if (interpolation) - memcpy(temp_area, temp_area + source_band_height * dest_pitch, - dest_width); - - /* Next band... */ - source += (unsigned long)source_band_height * source_pitch; - dest += (unsigned long)dest_band_height * dest_pitch; - } - - return; - } - - if (hscale == 2 && hratio == 1) Scale1Dh = scale1d_2t1_ps; - - if (vscale == 2 && vratio == 1) { - if (interlaced) - Scale1Dv = scale1d_2t1_ps; - else - Scale1Dv = scale1d_2t1_i; - } - - if (source_height == dest_height) { - /* for each band of the image */ - for (k = 0; k < (int)dest_height; k++) { - Scale1Dh(source, 1, hscale, source_width + 1, dest, 1, hratio, - dest_width); - source += source_pitch; - dest += dest_pitch; - } - - return; - } - - if (dest_height > source_height) { - dest_band_height = temp_area_height - 1; - source_band_height = dest_band_height * source_height / dest_height; - } else { - source_band_height = temp_area_height - 1; - dest_band_height = source_band_height * vratio / vscale; - } - - /* first row needs to be done so that we can stay one row ahead for vertical - * zoom */ - Scale1Dh(source, 1, hscale, source_width + 1, temp_area, 1, hratio, - dest_width); - - /* for each band of the image */ - bands = (dest_height + dest_band_height - 1) / dest_band_height; - - for (k = 0; k < bands; k++) { - /* scale one band horizontally */ - for (i = 1; i < source_band_height + 1; i++) { - if (k * source_band_height + i < (int)source_height) { - Scale1Dh(source + i * source_pitch, 1, hscale, source_width + 1, - temp_area + i * dest_pitch, 1, hratio, dest_width); - } else { /* Duplicate the last row */ - /* copy temp_area row 0 over from last row in the past */ - memcpy(temp_area + i * dest_pitch, temp_area + (i - 1) * dest_pitch, - dest_pitch); - } - } - - /* scale one band vertically */ - for (j = 0; j < (int)dest_width; j++) { - Scale1Dv(&temp_area[j], dest_pitch, vscale, source_band_height + 1, - &dest[j], dest_pitch, vratio, dest_band_height); - } - - /* copy temp_area row 0 over from last row in the past */ - memcpy(temp_area, temp_area + source_band_height * dest_pitch, dest_pitch); - - /* move to the next band */ - source += source_band_height * source_pitch; - dest += dest_band_height * dest_pitch; - } -} - -/**************************************************************************** - * - * ROUTINE : vpx_scale_frame - * - * INPUTS : YV12_BUFFER_CONFIG *src : Pointer to frame to be - * scaled. - * YV12_BUFFER_CONFIG *dst : Pointer to buffer to hold - * scaled frame. - * unsigned char *temp_area : Pointer to temp work area. - * unsigned char temp_area_height : Height of temp work area. - * unsigned int hscale : Horizontal scale factor - * numerator. - * unsigned int hratio : Horizontal scale factor - * denominator. - * unsigned int vscale : Vertical scale factor - * numerator. - * unsigned int vratio : Vertical scale factor - * denominator. - * unsigned int interlaced : Interlace flag. - * - * OUTPUTS : None. - * - * RETURNS : void - * - * FUNCTION : Performs 2-tap linear interpolation in two dimensions. - * - * SPECIAL NOTES : Expansion is performed one band at a time to help with - * caching. - * - ****************************************************************************/ -void vpx_scale_frame(YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst, - unsigned char *temp_area, unsigned char temp_height, - unsigned int hscale, unsigned int hratio, - unsigned int vscale, unsigned int vratio, - unsigned int interlaced) { - int i; - int dw = (hscale - 1 + src->y_width * hratio) / hscale; - int dh = (vscale - 1 + src->y_height * vratio) / vscale; - - /* call our internal scaling routines!! */ - Scale2D((unsigned char *)src->y_buffer, src->y_stride, src->y_width, - src->y_height, (unsigned char *)dst->y_buffer, dst->y_stride, dw, dh, - temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced); - - if (dw < (int)dst->y_width) - for (i = 0; i < dh; i++) - memset(dst->y_buffer + i * dst->y_stride + dw - 1, - dst->y_buffer[i * dst->y_stride + dw - 2], dst->y_width - dw + 1); - - if (dh < (int)dst->y_height) - for (i = dh - 1; i < (int)dst->y_height; i++) - memcpy(dst->y_buffer + i * dst->y_stride, - dst->y_buffer + (dh - 2) * dst->y_stride, dst->y_width + 1); - - Scale2D((unsigned char *)src->u_buffer, src->uv_stride, src->uv_width, - src->uv_height, (unsigned char *)dst->u_buffer, dst->uv_stride, - dw / 2, dh / 2, temp_area, temp_height, hscale, hratio, vscale, - vratio, interlaced); - - if (dw / 2 < (int)dst->uv_width) - for (i = 0; i < dst->uv_height; i++) - memset(dst->u_buffer + i * dst->uv_stride + dw / 2 - 1, - dst->u_buffer[i * dst->uv_stride + dw / 2 - 2], - dst->uv_width - dw / 2 + 1); - - if (dh / 2 < (int)dst->uv_height) - for (i = dh / 2 - 1; i < (int)dst->y_height / 2; i++) - memcpy(dst->u_buffer + i * dst->uv_stride, - dst->u_buffer + (dh / 2 - 2) * dst->uv_stride, dst->uv_width); - - Scale2D((unsigned char *)src->v_buffer, src->uv_stride, src->uv_width, - src->uv_height, (unsigned char *)dst->v_buffer, dst->uv_stride, - dw / 2, dh / 2, temp_area, temp_height, hscale, hratio, vscale, - vratio, interlaced); - - if (dw / 2 < (int)dst->uv_width) - for (i = 0; i < dst->uv_height; i++) - memset(dst->v_buffer + i * dst->uv_stride + dw / 2 - 1, - dst->v_buffer[i * dst->uv_stride + dw / 2 - 2], - dst->uv_width - dw / 2 + 1); - - if (dh / 2 < (int)dst->uv_height) - for (i = dh / 2 - 1; i < (int)dst->y_height / 2; i++) - memcpy(dst->v_buffer + i * dst->uv_stride, - dst->v_buffer + (dh / 2 - 2) * dst->uv_stride, dst->uv_width); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/generic/yv12config.c b/presentation/src/main/cpp/third_party/libvpx/vpx_scale/generic/yv12config.c deleted file mode 100644 index c52dab05..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/generic/yv12config.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "vpx_scale/yv12config.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" - -#if defined(VPX_MAX_ALLOCABLE_MEMORY) -#include "vp9/common/vp9_onyxc_int.h" -#endif // VPX_MAX_ALLOCABLE_MEMORY -/**************************************************************************** - * Exports - ****************************************************************************/ - -/**************************************************************************** - * - ****************************************************************************/ -#define yv12_align_addr(addr, align) \ - (void *)(((size_t)(addr) + ((align)-1)) & (size_t) - (align)) - -int vp8_yv12_de_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf) { - if (ybf) { - // If libvpx is using frame buffer callbacks then buffer_alloc_sz must - // not be set. - if (ybf->buffer_alloc_sz > 0) { - vpx_free(ybf->buffer_alloc); - } - - /* buffer_alloc isn't accessed by most functions. Rather y_buffer, - u_buffer and v_buffer point to buffer_alloc and are used. Clear out - all of this so that a freed pointer isn't inadvertently used */ - memset(ybf, 0, sizeof(YV12_BUFFER_CONFIG)); - } else { - return -1; - } - - return 0; -} - -int vp8_yv12_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, - int height, int border) { - if (ybf) { - int aligned_width = (width + 15) & ~15; - int aligned_height = (height + 15) & ~15; - int y_stride = ((aligned_width + 2 * border) + 31) & ~31; - int yplane_size = (aligned_height + 2 * border) * y_stride; - int uv_width = aligned_width >> 1; - int uv_height = aligned_height >> 1; - /** There is currently a bunch of code which assumes - * uv_stride == y_stride/2, so enforce this here. */ - int uv_stride = y_stride >> 1; - int uvplane_size = (uv_height + border) * uv_stride; - const size_t frame_size = yplane_size + 2 * uvplane_size; - - if (!ybf->buffer_alloc) { - ybf->buffer_alloc = (uint8_t *)vpx_memalign(32, frame_size); - if (!ybf->buffer_alloc) { - ybf->buffer_alloc_sz = 0; - return -1; - } -#if defined(__has_feature) -#if __has_feature(memory_sanitizer) - // This memset is needed for fixing the issue of using uninitialized - // value in msan test. It will cause a perf loss, so only do this for - // msan test. - memset(ybf->buffer_alloc, 0, frame_size); -#endif -#endif - ybf->buffer_alloc_sz = frame_size; - } - - if (ybf->buffer_alloc_sz < frame_size) return -1; - - /* Only support allocating buffers that have a border that's a multiple - * of 32. The border restriction is required to get 16-byte alignment of - * the start of the chroma rows without introducing an arbitrary gap - * between planes, which would break the semantics of things like - * vpx_img_set_rect(). */ - if (border & 0x1f) return -3; - - ybf->y_crop_width = width; - ybf->y_crop_height = height; - ybf->y_width = aligned_width; - ybf->y_height = aligned_height; - ybf->y_stride = y_stride; - - ybf->uv_crop_width = (width + 1) / 2; - ybf->uv_crop_height = (height + 1) / 2; - ybf->uv_width = uv_width; - ybf->uv_height = uv_height; - ybf->uv_stride = uv_stride; - - ybf->alpha_width = 0; - ybf->alpha_height = 0; - ybf->alpha_stride = 0; - - ybf->border = border; - ybf->frame_size = frame_size; - - ybf->y_buffer = ybf->buffer_alloc + (border * y_stride) + border; - ybf->u_buffer = - ybf->buffer_alloc + yplane_size + (border / 2 * uv_stride) + border / 2; - ybf->v_buffer = ybf->buffer_alloc + yplane_size + uvplane_size + - (border / 2 * uv_stride) + border / 2; - ybf->alpha_buffer = NULL; - - ybf->corrupted = 0; /* assume not currupted by errors */ - return 0; - } - return -2; -} - -int vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height, - int border) { - if (ybf) { - vp8_yv12_de_alloc_frame_buffer(ybf); - return vp8_yv12_realloc_frame_buffer(ybf, width, height, border); - } - return -2; -} - -#if CONFIG_VP9 -// TODO(jkoleszar): Maybe replace this with struct vpx_image - -int vpx_free_frame_buffer(YV12_BUFFER_CONFIG *ybf) { - if (ybf) { - if (ybf->buffer_alloc_sz > 0) { - vpx_free(ybf->buffer_alloc); - } - - /* buffer_alloc isn't accessed by most functions. Rather y_buffer, - u_buffer and v_buffer point to buffer_alloc and are used. Clear out - all of this so that a freed pointer isn't inadvertently used */ - memset(ybf, 0, sizeof(YV12_BUFFER_CONFIG)); - } else { - return -1; - } - - return 0; -} - -int vpx_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height, - int ss_x, int ss_y, -#if CONFIG_VP9_HIGHBITDEPTH - int use_highbitdepth, -#endif - int border, int byte_alignment, - vpx_codec_frame_buffer_t *fb, - vpx_get_frame_buffer_cb_fn_t cb, void *cb_priv) { -#if CONFIG_SIZE_LIMIT - if (width > DECODE_WIDTH_LIMIT || height > DECODE_HEIGHT_LIMIT) return -1; -#endif - - /* Only support allocating buffers that have a border that's a multiple - * of 32. The border restriction is required to get 16-byte alignment of - * the start of the chroma rows without introducing an arbitrary gap - * between planes, which would break the semantics of things like - * vpx_img_set_rect(). */ - if (border & 0x1f) return -3; - - if (ybf) { - const int vp9_byte_align = (byte_alignment == 0) ? 1 : byte_alignment; - const int aligned_width = (width + 7) & ~7; - const int aligned_height = (height + 7) & ~7; - const int y_stride = ((aligned_width + 2 * border) + 31) & ~31; - const uint64_t yplane_size = - (aligned_height + 2 * border) * (uint64_t)y_stride + byte_alignment; - const int uv_width = aligned_width >> ss_x; - const int uv_height = aligned_height >> ss_y; - const int uv_stride = y_stride >> ss_x; - const int uv_border_w = border >> ss_x; - const int uv_border_h = border >> ss_y; - const uint64_t uvplane_size = - (uv_height + 2 * uv_border_h) * (uint64_t)uv_stride + byte_alignment; - -#if CONFIG_VP9_HIGHBITDEPTH - const uint64_t frame_size = - (1 + use_highbitdepth) * (yplane_size + 2 * uvplane_size); -#else - const uint64_t frame_size = yplane_size + 2 * uvplane_size; -#endif // CONFIG_VP9_HIGHBITDEPTH - - uint8_t *buf = NULL; - -#if defined(VPX_MAX_ALLOCABLE_MEMORY) - // The decoder may allocate REF_FRAMES frame buffers in the frame buffer - // pool. Bound the total amount of allocated memory as if these REF_FRAMES - // frame buffers were allocated in a single allocation. - if (frame_size > VPX_MAX_ALLOCABLE_MEMORY / REF_FRAMES) return -1; -#endif // VPX_MAX_ALLOCABLE_MEMORY - - // frame_size is stored in buffer_alloc_sz, which is a size_t. If it won't - // fit, fail early. - if (frame_size > SIZE_MAX) { - return -1; - } - - if (cb != NULL) { - const int align_addr_extra_size = 31; - const uint64_t external_frame_size = frame_size + align_addr_extra_size; - - assert(fb != NULL); - - if (external_frame_size != (size_t)external_frame_size) return -1; - - // Allocation to hold larger frame, or first allocation. - if (cb(cb_priv, (size_t)external_frame_size, fb) < 0) return -1; - - if (fb->data == NULL || fb->size < external_frame_size) return -1; - - ybf->buffer_alloc = (uint8_t *)yv12_align_addr(fb->data, 32); - -#if defined(__has_feature) -#if __has_feature(memory_sanitizer) - // This memset is needed for fixing the issue of using uninitialized - // value in msan test. It will cause a perf loss, so only do this for - // msan test. - memset(ybf->buffer_alloc, 0, (size_t)frame_size); -#endif -#endif - } else if (frame_size > ybf->buffer_alloc_sz) { - // Allocation to hold larger frame, or first allocation. - vpx_free(ybf->buffer_alloc); - ybf->buffer_alloc = NULL; - ybf->buffer_alloc_sz = 0; - - ybf->buffer_alloc = (uint8_t *)vpx_memalign(32, (size_t)frame_size); - if (!ybf->buffer_alloc) return -1; - - ybf->buffer_alloc_sz = (size_t)frame_size; - - // This memset is needed for fixing valgrind error from C loop filter - // due to access uninitialized memory in frame border. It could be - // removed if border is totally removed. - memset(ybf->buffer_alloc, 0, ybf->buffer_alloc_sz); - } - - ybf->y_crop_width = width; - ybf->y_crop_height = height; - ybf->y_width = aligned_width; - ybf->y_height = aligned_height; - ybf->y_stride = y_stride; - - ybf->uv_crop_width = (width + ss_x) >> ss_x; - ybf->uv_crop_height = (height + ss_y) >> ss_y; - ybf->uv_width = uv_width; - ybf->uv_height = uv_height; - ybf->uv_stride = uv_stride; - - ybf->border = border; - ybf->frame_size = (size_t)frame_size; - ybf->subsampling_x = ss_x; - ybf->subsampling_y = ss_y; - - buf = ybf->buffer_alloc; -#if CONFIG_VP9_HIGHBITDEPTH - if (use_highbitdepth) { - // Store uint16 addresses when using 16bit framebuffers - buf = CONVERT_TO_BYTEPTR(ybf->buffer_alloc); - ybf->flags = YV12_FLAG_HIGHBITDEPTH; - } else { - ybf->flags = 0; - } -#endif // CONFIG_VP9_HIGHBITDEPTH - - ybf->y_buffer = (uint8_t *)yv12_align_addr( - buf + (border * y_stride) + border, vp9_byte_align); - ybf->u_buffer = (uint8_t *)yv12_align_addr( - buf + yplane_size + (uv_border_h * uv_stride) + uv_border_w, - vp9_byte_align); - ybf->v_buffer = - (uint8_t *)yv12_align_addr(buf + yplane_size + uvplane_size + - (uv_border_h * uv_stride) + uv_border_w, - vp9_byte_align); - - ybf->corrupted = 0; /* assume not corrupted by errors */ - return 0; - } - return -2; -} - -int vpx_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height, - int ss_x, int ss_y, -#if CONFIG_VP9_HIGHBITDEPTH - int use_highbitdepth, -#endif - int border, int byte_alignment) { - if (ybf) { - vpx_free_frame_buffer(ybf); - return vpx_realloc_frame_buffer(ybf, width, height, ss_x, ss_y, -#if CONFIG_VP9_HIGHBITDEPTH - use_highbitdepth, -#endif - border, byte_alignment, NULL, NULL, NULL); - } - return -2; -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/generic/yv12extend.c b/presentation/src/main/cpp/third_party/libvpx/vpx_scale/generic/yv12extend.c deleted file mode 100644 index e2318065..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/generic/yv12extend.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include "./vpx_config.h" -#include "./vpx_scale_rtcd.h" -#include "vpx/vpx_integer.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_ports/mem.h" -#include "vpx_scale/yv12config.h" -#if CONFIG_VP9_HIGHBITDEPTH -#include "vp9/common/vp9_common.h" -#endif - -static void extend_plane(uint8_t *const src, int src_stride, int width, - int height, int extend_top, int extend_left, - int extend_bottom, int extend_right) { - int i; - const int linesize = extend_left + extend_right + width; - - /* copy the left and right most columns out */ - uint8_t *src_ptr1 = src; - uint8_t *src_ptr2 = src + width - 1; - uint8_t *dst_ptr1 = src - extend_left; - uint8_t *dst_ptr2 = src + width; - - for (i = 0; i < height; ++i) { - memset(dst_ptr1, src_ptr1[0], extend_left); - memset(dst_ptr2, src_ptr2[0], extend_right); - src_ptr1 += src_stride; - src_ptr2 += src_stride; - dst_ptr1 += src_stride; - dst_ptr2 += src_stride; - } - - /* Now copy the top and bottom lines into each line of the respective - * borders - */ - src_ptr1 = src - extend_left; - src_ptr2 = src + src_stride * (height - 1) - extend_left; - dst_ptr1 = src + src_stride * -extend_top - extend_left; - dst_ptr2 = src + src_stride * height - extend_left; - - for (i = 0; i < extend_top; ++i) { - memcpy(dst_ptr1, src_ptr1, linesize); - dst_ptr1 += src_stride; - } - - for (i = 0; i < extend_bottom; ++i) { - memcpy(dst_ptr2, src_ptr2, linesize); - dst_ptr2 += src_stride; - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -static void extend_plane_high(uint8_t *const src8, int src_stride, int width, - int height, int extend_top, int extend_left, - int extend_bottom, int extend_right) { - int i; - const int linesize = extend_left + extend_right + width; - uint16_t *src = CONVERT_TO_SHORTPTR(src8); - - /* copy the left and right most columns out */ - uint16_t *src_ptr1 = src; - uint16_t *src_ptr2 = src + width - 1; - uint16_t *dst_ptr1 = src - extend_left; - uint16_t *dst_ptr2 = src + width; - - for (i = 0; i < height; ++i) { - vpx_memset16(dst_ptr1, src_ptr1[0], extend_left); - vpx_memset16(dst_ptr2, src_ptr2[0], extend_right); - src_ptr1 += src_stride; - src_ptr2 += src_stride; - dst_ptr1 += src_stride; - dst_ptr2 += src_stride; - } - - /* Now copy the top and bottom lines into each line of the respective - * borders - */ - src_ptr1 = src - extend_left; - src_ptr2 = src + src_stride * (height - 1) - extend_left; - dst_ptr1 = src + src_stride * -extend_top - extend_left; - dst_ptr2 = src + src_stride * height - extend_left; - - for (i = 0; i < extend_top; ++i) { - memcpy(dst_ptr1, src_ptr1, linesize * sizeof(uint16_t)); - dst_ptr1 += src_stride; - } - - for (i = 0; i < extend_bottom; ++i) { - memcpy(dst_ptr2, src_ptr2, linesize * sizeof(uint16_t)); - dst_ptr2 += src_stride; - } -} -#endif - -void vp8_yv12_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf) { - const int uv_border = ybf->border / 2; - - assert(ybf->border % 2 == 0); - assert(ybf->y_height - ybf->y_crop_height < 16); - assert(ybf->y_width - ybf->y_crop_width < 16); - assert(ybf->y_height - ybf->y_crop_height >= 0); - assert(ybf->y_width - ybf->y_crop_width >= 0); - - extend_plane(ybf->y_buffer, ybf->y_stride, ybf->y_crop_width, - ybf->y_crop_height, ybf->border, ybf->border, - ybf->border + ybf->y_height - ybf->y_crop_height, - ybf->border + ybf->y_width - ybf->y_crop_width); - - extend_plane(ybf->u_buffer, ybf->uv_stride, ybf->uv_crop_width, - ybf->uv_crop_height, uv_border, uv_border, - uv_border + ybf->uv_height - ybf->uv_crop_height, - uv_border + ybf->uv_width - ybf->uv_crop_width); - - extend_plane(ybf->v_buffer, ybf->uv_stride, ybf->uv_crop_width, - ybf->uv_crop_height, uv_border, uv_border, - uv_border + ybf->uv_height - ybf->uv_crop_height, - uv_border + ybf->uv_width - ybf->uv_crop_width); -} - -#if CONFIG_VP9 -static void extend_frame(YV12_BUFFER_CONFIG *const ybf, int ext_size) { - const int c_w = ybf->uv_crop_width; - const int c_h = ybf->uv_crop_height; - const int ss_x = ybf->uv_width < ybf->y_width; - const int ss_y = ybf->uv_height < ybf->y_height; - const int c_et = ext_size >> ss_y; - const int c_el = ext_size >> ss_x; - const int c_eb = c_et + ybf->uv_height - ybf->uv_crop_height; - const int c_er = c_el + ybf->uv_width - ybf->uv_crop_width; - - assert(ybf->y_height - ybf->y_crop_height < 16); - assert(ybf->y_width - ybf->y_crop_width < 16); - assert(ybf->y_height - ybf->y_crop_height >= 0); - assert(ybf->y_width - ybf->y_crop_width >= 0); - -#if CONFIG_VP9_HIGHBITDEPTH - if (ybf->flags & YV12_FLAG_HIGHBITDEPTH) { - extend_plane_high(ybf->y_buffer, ybf->y_stride, ybf->y_crop_width, - ybf->y_crop_height, ext_size, ext_size, - ext_size + ybf->y_height - ybf->y_crop_height, - ext_size + ybf->y_width - ybf->y_crop_width); - extend_plane_high(ybf->u_buffer, ybf->uv_stride, c_w, c_h, c_et, c_el, c_eb, - c_er); - extend_plane_high(ybf->v_buffer, ybf->uv_stride, c_w, c_h, c_et, c_el, c_eb, - c_er); - return; - } -#endif - extend_plane(ybf->y_buffer, ybf->y_stride, ybf->y_crop_width, - ybf->y_crop_height, ext_size, ext_size, - ext_size + ybf->y_height - ybf->y_crop_height, - ext_size + ybf->y_width - ybf->y_crop_width); - - extend_plane(ybf->u_buffer, ybf->uv_stride, c_w, c_h, c_et, c_el, c_eb, c_er); - - extend_plane(ybf->v_buffer, ybf->uv_stride, c_w, c_h, c_et, c_el, c_eb, c_er); -} - -void vpx_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf) { - extend_frame(ybf, ybf->border); -} - -void vpx_extend_frame_inner_borders_c(YV12_BUFFER_CONFIG *ybf) { - const int inner_bw = (ybf->border > VP9INNERBORDERINPIXELS) - ? VP9INNERBORDERINPIXELS - : ybf->border; - extend_frame(ybf, inner_bw); -} - -#if CONFIG_VP9_HIGHBITDEPTH -static void memcpy_short_addr(uint8_t *dst8, const uint8_t *src8, int num) { - uint16_t *dst = CONVERT_TO_SHORTPTR(dst8); - uint16_t *src = CONVERT_TO_SHORTPTR(src8); - memcpy(dst, src, num * sizeof(uint16_t)); -} -#endif // CONFIG_VP9_HIGHBITDEPTH -#endif // CONFIG_VP9 - -// Copies the source image into the destination image and updates the -// destination's UMV borders. -// Note: The frames are assumed to be identical in size. - -void vp8_yv12_copy_frame_c(const YV12_BUFFER_CONFIG *src_ybc, - YV12_BUFFER_CONFIG *dst_ybc) { - int row; - const uint8_t *src = src_ybc->y_buffer; - uint8_t *dst = dst_ybc->y_buffer; - -#if 0 - /* These assertions are valid in the codec, but the libvpx-tester uses - * this code slightly differently. - */ - assert(src_ybc->y_width == dst_ybc->y_width); - assert(src_ybc->y_height == dst_ybc->y_height); -#endif - - for (row = 0; row < src_ybc->y_height; ++row) { - memcpy(dst, src, src_ybc->y_width); - src += src_ybc->y_stride; - dst += dst_ybc->y_stride; - } - - src = src_ybc->u_buffer; - dst = dst_ybc->u_buffer; - - for (row = 0; row < src_ybc->uv_height; ++row) { - memcpy(dst, src, src_ybc->uv_width); - src += src_ybc->uv_stride; - dst += dst_ybc->uv_stride; - } - - src = src_ybc->v_buffer; - dst = dst_ybc->v_buffer; - - for (row = 0; row < src_ybc->uv_height; ++row) { - memcpy(dst, src, src_ybc->uv_width); - src += src_ybc->uv_stride; - dst += dst_ybc->uv_stride; - } - - vp8_yv12_extend_frame_borders_c(dst_ybc); -} - -#if CONFIG_VP9 -void vpx_yv12_copy_frame_c(const YV12_BUFFER_CONFIG *src_ybc, - YV12_BUFFER_CONFIG *dst_ybc) { - int row; - const uint8_t *src = src_ybc->y_buffer; - uint8_t *dst = dst_ybc->y_buffer; - -#if 0 - /* These assertions are valid in the codec, but the libvpx-tester uses - * this code slightly differently. - */ - assert(src_ybc->y_width == dst_ybc->y_width); - assert(src_ybc->y_height == dst_ybc->y_height); -#endif - -#if CONFIG_VP9_HIGHBITDEPTH - if (src_ybc->flags & YV12_FLAG_HIGHBITDEPTH) { - assert(dst_ybc->flags & YV12_FLAG_HIGHBITDEPTH); - for (row = 0; row < src_ybc->y_height; ++row) { - memcpy_short_addr(dst, src, src_ybc->y_width); - src += src_ybc->y_stride; - dst += dst_ybc->y_stride; - } - - src = src_ybc->u_buffer; - dst = dst_ybc->u_buffer; - - for (row = 0; row < src_ybc->uv_height; ++row) { - memcpy_short_addr(dst, src, src_ybc->uv_width); - src += src_ybc->uv_stride; - dst += dst_ybc->uv_stride; - } - - src = src_ybc->v_buffer; - dst = dst_ybc->v_buffer; - - for (row = 0; row < src_ybc->uv_height; ++row) { - memcpy_short_addr(dst, src, src_ybc->uv_width); - src += src_ybc->uv_stride; - dst += dst_ybc->uv_stride; - } - - vpx_extend_frame_borders_c(dst_ybc); - return; - } else { - assert(!(dst_ybc->flags & YV12_FLAG_HIGHBITDEPTH)); - } -#endif - - for (row = 0; row < src_ybc->y_height; ++row) { - memcpy(dst, src, src_ybc->y_width); - src += src_ybc->y_stride; - dst += dst_ybc->y_stride; - } - - src = src_ybc->u_buffer; - dst = dst_ybc->u_buffer; - - for (row = 0; row < src_ybc->uv_height; ++row) { - memcpy(dst, src, src_ybc->uv_width); - src += src_ybc->uv_stride; - dst += dst_ybc->uv_stride; - } - - src = src_ybc->v_buffer; - dst = dst_ybc->v_buffer; - - for (row = 0; row < src_ybc->uv_height; ++row) { - memcpy(dst, src, src_ybc->uv_width); - src += src_ybc->uv_stride; - dst += dst_ybc->uv_stride; - } - - vpx_extend_frame_borders_c(dst_ybc); -} -#endif // CONFIG_VP9 - -void vpx_yv12_copy_y_c(const YV12_BUFFER_CONFIG *src_ybc, - YV12_BUFFER_CONFIG *dst_ybc) { - int row; - const uint8_t *src = src_ybc->y_buffer; - uint8_t *dst = dst_ybc->y_buffer; - -#if CONFIG_VP9_HIGHBITDEPTH - if (src_ybc->flags & YV12_FLAG_HIGHBITDEPTH) { - const uint16_t *src16 = CONVERT_TO_SHORTPTR(src); - uint16_t *dst16 = CONVERT_TO_SHORTPTR(dst); - for (row = 0; row < src_ybc->y_height; ++row) { - memcpy(dst16, src16, src_ybc->y_width * sizeof(uint16_t)); - src16 += src_ybc->y_stride; - dst16 += dst_ybc->y_stride; - } - return; - } -#endif - - for (row = 0; row < src_ybc->y_height; ++row) { - memcpy(dst, src, src_ybc->y_width); - src += src_ybc->y_stride; - dst += dst_ybc->y_stride; - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/mips/dspr2/yv12extend_dspr2.c b/presentation/src/main/cpp/third_party/libvpx/vpx_scale/mips/dspr2/yv12extend_dspr2.c deleted file mode 100644 index d3d1b07f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/mips/dspr2/yv12extend_dspr2.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "./vpx_config.h" -#include "vpx_scale/yv12config.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_scale/vpx_scale.h" - -#if HAVE_DSPR2 -static void extend_plane(uint8_t *const src, int src_stride, int width, - int height, int extend_top, int extend_left, - int extend_bottom, int extend_right) { - int i, j; - uint8_t *left_src, *right_src; - uint8_t *left_dst_start, *right_dst_start; - uint8_t *left_dst, *right_dst; - uint8_t *top_src, *bot_src; - uint8_t *top_dst, *bot_dst; - uint32_t left_pix; - uint32_t right_pix; - uint32_t linesize; - - /* copy the left and right most columns out */ - left_src = src; - right_src = src + width - 1; - left_dst_start = src - extend_left; - right_dst_start = src + width; - - for (i = height; i--;) { - left_dst = left_dst_start; - right_dst = right_dst_start; - - __asm__ __volatile__( - "lb %[left_pix], 0(%[left_src]) \n\t" - "lb %[right_pix], 0(%[right_src]) \n\t" - "replv.qb %[left_pix], %[left_pix] \n\t" - "replv.qb %[right_pix], %[right_pix] \n\t" - - : [left_pix] "=&r"(left_pix), [right_pix] "=&r"(right_pix) - : [left_src] "r"(left_src), [right_src] "r"(right_src)); - - for (j = extend_left / 4; j--;) { - __asm__ __volatile__( - "sw %[left_pix], 0(%[left_dst]) \n\t" - "sw %[right_pix], 0(%[right_dst]) \n\t" - - : - : [left_dst] "r"(left_dst), [left_pix] "r"(left_pix), - [right_dst] "r"(right_dst), [right_pix] "r"(right_pix)); - - left_dst += 4; - right_dst += 4; - } - - for (j = extend_left % 4; j--;) { - __asm__ __volatile__( - "sb %[left_pix], 0(%[left_dst]) \n\t" - "sb %[right_pix], 0(%[right_dst]) \n\t" - - : - : [left_dst] "r"(left_dst), [left_pix] "r"(left_pix), - [right_dst] "r"(right_dst), [right_pix] "r"(right_pix)); - - left_dst += 1; - right_dst += 1; - } - - left_src += src_stride; - right_src += src_stride; - left_dst_start += src_stride; - right_dst_start += src_stride; - } - - /* Now copy the top and bottom lines into each line of the respective - * borders - */ - top_src = src - extend_left; - bot_src = src + src_stride * (height - 1) - extend_left; - top_dst = src + src_stride * (-extend_top) - extend_left; - bot_dst = src + src_stride * (height)-extend_left; - linesize = extend_left + extend_right + width; - - for (i = 0; i < extend_top; i++) { - memcpy(top_dst, top_src, linesize); - top_dst += src_stride; - } - - for (i = 0; i < extend_bottom; i++) { - memcpy(bot_dst, bot_src, linesize); - bot_dst += src_stride; - } -} - -static void extend_frame(YV12_BUFFER_CONFIG *const ybf, int ext_size) { - const int c_w = ybf->uv_crop_width; - const int c_h = ybf->uv_crop_height; - const int ss_x = ybf->uv_width < ybf->y_width; - const int ss_y = ybf->uv_height < ybf->y_height; - const int c_et = ext_size >> ss_y; - const int c_el = ext_size >> ss_x; - const int c_eb = c_et + ybf->uv_height - ybf->uv_crop_height; - const int c_er = c_el + ybf->uv_width - ybf->uv_crop_width; - - assert(ybf->y_height - ybf->y_crop_height < 16); - assert(ybf->y_width - ybf->y_crop_width < 16); - assert(ybf->y_height - ybf->y_crop_height >= 0); - assert(ybf->y_width - ybf->y_crop_width >= 0); - - extend_plane(ybf->y_buffer, ybf->y_stride, ybf->y_crop_width, - ybf->y_crop_height, ext_size, ext_size, - ext_size + ybf->y_height - ybf->y_crop_height, - ext_size + ybf->y_width - ybf->y_crop_width); - - extend_plane(ybf->u_buffer, ybf->uv_stride, c_w, c_h, c_et, c_el, c_eb, c_er); - - extend_plane(ybf->v_buffer, ybf->uv_stride, c_w, c_h, c_et, c_el, c_eb, c_er); -} - -void vpx_extend_frame_borders_dspr2(YV12_BUFFER_CONFIG *ybf) { - extend_frame(ybf, ybf->border); -} - -void vpx_extend_frame_inner_borders_dspr2(YV12_BUFFER_CONFIG *ybf) { - const int inner_bw = (ybf->border > VP9INNERBORDERINPIXELS) - ? VP9INNERBORDERINPIXELS - : ybf->border; - extend_frame(ybf, inner_bw); -} -#endif diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/vpx_scale.h b/presentation/src/main/cpp/third_party/libvpx/vpx_scale/vpx_scale.h deleted file mode 100644 index fd5ba7cc..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/vpx_scale.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_SCALE_VPX_SCALE_H_ -#define VPX_VPX_SCALE_VPX_SCALE_H_ - -#include "vpx_scale/yv12config.h" - -extern void vpx_scale_frame(YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst, - unsigned char *temp_area, unsigned char temp_height, - unsigned int hscale, unsigned int hratio, - unsigned int vscale, unsigned int vratio, - unsigned int interlaced); - -#endif // VPX_VPX_SCALE_VPX_SCALE_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/vpx_scale.mk b/presentation/src/main/cpp/third_party/libvpx/vpx_scale/vpx_scale.mk deleted file mode 100644 index a49abf3b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/vpx_scale.mk +++ /dev/null @@ -1,16 +0,0 @@ -SCALE_SRCS-yes += vpx_scale.mk -SCALE_SRCS-yes += yv12config.h -SCALE_SRCS-$(CONFIG_SPATIAL_RESAMPLING) += vpx_scale.h -SCALE_SRCS-$(CONFIG_SPATIAL_RESAMPLING) += generic/vpx_scale.c -SCALE_SRCS-yes += generic/yv12config.c -SCALE_SRCS-yes += generic/yv12extend.c -SCALE_SRCS-$(CONFIG_SPATIAL_RESAMPLING) += generic/gen_scalers.c -SCALE_SRCS-yes += vpx_scale_rtcd.c -SCALE_SRCS-yes += vpx_scale_rtcd.pl - -#mips(dspr2) -SCALE_SRCS-$(HAVE_DSPR2) += mips/dspr2/yv12extend_dspr2.c - -SCALE_SRCS-no += $(SCALE_SRCS_REMOVE-yes) - -$(eval $(call rtcd_h_template,vpx_scale_rtcd,vpx_scale/vpx_scale_rtcd.pl)) diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/vpx_scale_rtcd.c b/presentation/src/main/cpp/third_party/libvpx/vpx_scale/vpx_scale_rtcd.c deleted file mode 100644 index 706b0770..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/vpx_scale_rtcd.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2011 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "./vpx_config.h" -#define RTCD_C -#include "./vpx_scale_rtcd.h" -#include "vpx_ports/vpx_once.h" - -void vpx_scale_rtcd(void) { once(setup_rtcd_internal); } diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/vpx_scale_rtcd.pl b/presentation/src/main/cpp/third_party/libvpx/vpx_scale/vpx_scale_rtcd.pl deleted file mode 100644 index 1281071a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_scale/vpx_scale_rtcd.pl +++ /dev/null @@ -1,44 +0,0 @@ -## -## Copyright (c) 2017 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -sub vpx_scale_forward_decls() { -print < -#include "./vpx_config.h" -#include "vpx/vpx_integer.h" - -#if defined(__GNUC__) -#define LOCAL_GCC_VERSION ((__GNUC__ << 8) | __GNUC_MINOR__) -#define LOCAL_GCC_PREREQ(maj, min) (LOCAL_GCC_VERSION >= (((maj) << 8) | (min))) -#else -#define LOCAL_GCC_VERSION 0 -#define LOCAL_GCC_PREREQ(maj, min) 0 -#endif - -// handle clang compatibility -#ifndef __has_builtin -#define __has_builtin(x) 0 -#endif - -// some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__) -#if !defined(WORDS_BIGENDIAN) && \ - (defined(__BIG_ENDIAN__) || defined(_M_PPC) || \ - (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))) -#define WORDS_BIGENDIAN -#endif - -#if defined(WORDS_BIGENDIAN) -#define HToLE32 BSwap32 -#define HToLE16 BSwap16 -#define HToBE64(x) (x) -#define HToBE32(x) (x) -#else -#define HToLE32(x) (x) -#define HToLE16(x) (x) -#define HToBE64(X) BSwap64(X) -#define HToBE32(X) BSwap32(X) -#endif - -#if LOCAL_GCC_PREREQ(4, 8) || __has_builtin(__builtin_bswap16) -#define HAVE_BUILTIN_BSWAP16 -#endif - -#if LOCAL_GCC_PREREQ(4, 3) || __has_builtin(__builtin_bswap32) -#define HAVE_BUILTIN_BSWAP32 -#endif - -#if LOCAL_GCC_PREREQ(4, 3) || __has_builtin(__builtin_bswap64) -#define HAVE_BUILTIN_BSWAP64 -#endif - -#if HAVE_MIPS32 && defined(__mips__) && !defined(__mips64) && \ - defined(__mips_isa_rev) && (__mips_isa_rev >= 2) && (__mips_isa_rev < 6) -#define VPX_USE_MIPS32_R2 -#endif - -static INLINE uint16_t BSwap16(uint16_t x) { -#if defined(HAVE_BUILTIN_BSWAP16) - return __builtin_bswap16(x); -#elif defined(_MSC_VER) - return _byteswap_ushort(x); -#else - // gcc will recognize a 'rorw $8, ...' here: - return (x >> 8) | ((x & 0xff) << 8); -#endif // HAVE_BUILTIN_BSWAP16 -} - -static INLINE uint32_t BSwap32(uint32_t x) { -#if defined(VPX_USE_MIPS32_R2) - uint32_t ret; - __asm__ volatile( - "wsbh %[ret], %[x] \n\t" - "rotr %[ret], %[ret], 16 \n\t" - : [ret] "=r"(ret) - : [x] "r"(x)); - return ret; -#elif defined(HAVE_BUILTIN_BSWAP32) - return __builtin_bswap32(x); -#elif defined(__i386__) || defined(__x86_64__) - uint32_t swapped_bytes; - __asm__ volatile("bswap %0" : "=r"(swapped_bytes) : "0"(x)); - return swapped_bytes; -#elif defined(_MSC_VER) - return (uint32_t)_byteswap_ulong(x); -#else - return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24); -#endif // HAVE_BUILTIN_BSWAP32 -} - -static INLINE uint64_t BSwap64(uint64_t x) { -#if defined(HAVE_BUILTIN_BSWAP64) - return __builtin_bswap64(x); -#elif defined(__x86_64__) - uint64_t swapped_bytes; - __asm__ volatile("bswapq %0" : "=r"(swapped_bytes) : "0"(x)); - return swapped_bytes; -#elif defined(_MSC_VER) - return (uint64_t)_byteswap_uint64(x); -#else // generic code for swapping 64-bit values (suggested by bdb@) - x = ((x & 0xffffffff00000000ull) >> 32) | ((x & 0x00000000ffffffffull) << 32); - x = ((x & 0xffff0000ffff0000ull) >> 16) | ((x & 0x0000ffff0000ffffull) << 16); - x = ((x & 0xff00ff00ff00ff00ull) >> 8) | ((x & 0x00ff00ff00ff00ffull) << 8); - return x; -#endif // HAVE_BUILTIN_BSWAP64 -} - -#endif // VPX_VPX_UTIL_ENDIAN_INL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_util/loongson_intrinsics.h b/presentation/src/main/cpp/third_party/libvpx/vpx_util/loongson_intrinsics.h deleted file mode 100644 index b8b9e6db..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_util/loongson_intrinsics.h +++ /dev/null @@ -1,2090 +0,0 @@ -/* - * Copyright (c) 2022 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - * - */ - -#ifndef VPX_VPX_UTIL_LOONGSON_INTRINSICS_H_ -#define VPX_VPX_UTIL_LOONGSON_INTRINSICS_H_ - -/* - * Copyright (c) 2021 Loongson Technology Corporation Limited - * All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - * - * Contributed by Shiyou Yin - * Xiwei Gu - * Lu Wang - * - * This file is a header file for loongarch builtin extension. - * - */ - -#ifndef LOONGSON_INTRINSICS_H -#define LOONGSON_INTRINSICS_H - -/** - * MAJOR version: Macro usage changes. - * MINOR version: Add new functions, or bug fixes. - * MICRO version: Comment changes or implementation changes. - */ -#define LSOM_VERSION_MAJOR 1 -#define LSOM_VERSION_MINOR 2 -#define LSOM_VERSION_MICRO 1 - -#define DUP2_ARG1(_INS, _IN0, _IN1, _OUT0, _OUT1) \ - { \ - _OUT0 = _INS(_IN0); \ - _OUT1 = _INS(_IN1); \ - } - -#define DUP2_ARG2(_INS, _IN0, _IN1, _IN2, _IN3, _OUT0, _OUT1) \ - { \ - _OUT0 = _INS(_IN0, _IN1); \ - _OUT1 = _INS(_IN2, _IN3); \ - } - -#define DUP2_ARG3(_INS, _IN0, _IN1, _IN2, _IN3, _IN4, _IN5, _OUT0, _OUT1) \ - { \ - _OUT0 = _INS(_IN0, _IN1, _IN2); \ - _OUT1 = _INS(_IN3, _IN4, _IN5); \ - } - -#define DUP4_ARG1(_INS, _IN0, _IN1, _IN2, _IN3, _OUT0, _OUT1, _OUT2, _OUT3) \ - { \ - DUP2_ARG1(_INS, _IN0, _IN1, _OUT0, _OUT1); \ - DUP2_ARG1(_INS, _IN2, _IN3, _OUT2, _OUT3); \ - } - -#define DUP4_ARG2(_INS, _IN0, _IN1, _IN2, _IN3, _IN4, _IN5, _IN6, _IN7, _OUT0, \ - _OUT1, _OUT2, _OUT3) \ - { \ - DUP2_ARG2(_INS, _IN0, _IN1, _IN2, _IN3, _OUT0, _OUT1); \ - DUP2_ARG2(_INS, _IN4, _IN5, _IN6, _IN7, _OUT2, _OUT3); \ - } - -#define DUP4_ARG3(_INS, _IN0, _IN1, _IN2, _IN3, _IN4, _IN5, _IN6, _IN7, _IN8, \ - _IN9, _IN10, _IN11, _OUT0, _OUT1, _OUT2, _OUT3) \ - { \ - DUP2_ARG3(_INS, _IN0, _IN1, _IN2, _IN3, _IN4, _IN5, _OUT0, _OUT1); \ - DUP2_ARG3(_INS, _IN6, _IN7, _IN8, _IN9, _IN10, _IN11, _OUT2, _OUT3); \ - } - -#ifdef __loongarch_sx -#include -/* - * ============================================================================= - * Description : Dot product & addition of byte vector elements - * Arguments : Inputs - in_c, in_h, in_l - * Outputs - out - * Return Type - halfword - * Details : Signed byte elements from in_h are multiplied by - * signed byte elements from in_l, and then added adjacent to - * each other to get a result twice the size of input. Then - * the results are added to signed half-word elements from in_c. - * Example : out = __lsx_vdp2add_h_b(in_c, in_h, in_l) - * in_c : 1,2,3,4, 1,2,3,4 - * in_h : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 - * in_l : 8,7,6,5, 4,3,2,1, 8,7,6,5, 4,3,2,1 - * out : 23,40,41,26, 23,40,41,26 - * ============================================================================= - */ -static inline __m128i __lsx_vdp2add_h_b(__m128i in_c, __m128i in_h, - __m128i in_l) { - __m128i out; - - out = __lsx_vmaddwev_h_b(in_c, in_h, in_l); - out = __lsx_vmaddwod_h_b(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product & addition of byte vector elements - * Arguments : Inputs - in_c, in_h, in_l - * Outputs - out - * Return Type - halfword - * Details : Unsigned byte elements from in_h are multiplied by - * unsigned byte elements from in_l, and then added adjacent to - * each other to get a result twice the size of input. - * The results are added to signed half-word elements from in_c. - * Example : out = __lsx_vdp2add_h_bu(in_c, in_h, in_l) - * in_c : 1,2,3,4, 1,2,3,4 - * in_h : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 - * in_l : 8,7,6,5, 4,3,2,1, 8,7,6,5, 4,3,2,1 - * out : 23,40,41,26, 23,40,41,26 - * ============================================================================= - */ -static inline __m128i __lsx_vdp2add_h_bu(__m128i in_c, __m128i in_h, - __m128i in_l) { - __m128i out; - - out = __lsx_vmaddwev_h_bu(in_c, in_h, in_l); - out = __lsx_vmaddwod_h_bu(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product & addition of byte vector elements - * Arguments : Inputs - in_c, in_h, in_l - * Outputs - out - * Return Type - halfword - * Details : Unsigned byte elements from in_h are multiplied by - * signed byte elements from in_l, and then added adjacent to - * each other to get a result twice the size of input. - * The results are added to signed half-word elements from in_c. - * Example : out = __lsx_vdp2add_h_bu_b(in_c, in_h, in_l) - * in_c : 1,1,1,1, 1,1,1,1 - * in_h : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 - * in_l : -1,-2,-3,-4, -5,-6,-7,-8, 1,2,3,4, 5,6,7,8 - * out : -4,-24,-60,-112, 6,26,62,114 - * ============================================================================= - */ -static inline __m128i __lsx_vdp2add_h_bu_b(__m128i in_c, __m128i in_h, - __m128i in_l) { - __m128i out; - - out = __lsx_vmaddwev_h_bu_b(in_c, in_h, in_l); - out = __lsx_vmaddwod_h_bu_b(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product & addition of half-word vector elements - * Arguments : Inputs - in_c, in_h, in_l - * Outputs - out - * Return Type - __m128i - * Details : Signed half-word elements from in_h are multiplied by - * signed half-word elements from in_l, and then added adjacent to - * each other to get a result twice the size of input. - * Then the results are added to signed word elements from in_c. - * Example : out = __lsx_vdp2add_h_b(in_c, in_h, in_l) - * in_c : 1,2,3,4 - * in_h : 1,2,3,4, 5,6,7,8 - * in_l : 8,7,6,5, 4,3,2,1 - * out : 23,40,41,26 - * ============================================================================= - */ -static inline __m128i __lsx_vdp2add_w_h(__m128i in_c, __m128i in_h, - __m128i in_l) { - __m128i out; - - out = __lsx_vmaddwev_w_h(in_c, in_h, in_l); - out = __lsx_vmaddwod_w_h(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product of byte vector elements - * Arguments : Inputs - in_h, in_l - * Outputs - out - * Return Type - halfword - * Details : Signed byte elements from in_h are multiplied by - * signed byte elements from in_l, and then added adjacent to - * each other to get a result twice the size of input. - * Example : out = __lsx_vdp2_h_b(in_h, in_l) - * in_h : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 - * in_l : 8,7,6,5, 4,3,2,1, 8,7,6,5, 4,3,2,1 - * out : 22,38,38,22, 22,38,38,22 - * ============================================================================= - */ -static inline __m128i __lsx_vdp2_h_b(__m128i in_h, __m128i in_l) { - __m128i out; - - out = __lsx_vmulwev_h_b(in_h, in_l); - out = __lsx_vmaddwod_h_b(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product of byte vector elements - * Arguments : Inputs - in_h, in_l - * Outputs - out - * Return Type - halfword - * Details : Unsigned byte elements from in_h are multiplied by - * unsigned byte elements from in_l, and then added adjacent to - * each other to get a result twice the size of input. - * Example : out = __lsx_vdp2_h_bu(in_h, in_l) - * in_h : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 - * in_l : 8,7,6,5, 4,3,2,1, 8,7,6,5, 4,3,2,1 - * out : 22,38,38,22, 22,38,38,22 - * ============================================================================= - */ -static inline __m128i __lsx_vdp2_h_bu(__m128i in_h, __m128i in_l) { - __m128i out; - - out = __lsx_vmulwev_h_bu(in_h, in_l); - out = __lsx_vmaddwod_h_bu(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product of byte vector elements - * Arguments : Inputs - in_h, in_l - * Outputs - out - * Return Type - halfword - * Details : Unsigned byte elements from in_h are multiplied by - * signed byte elements from in_l, and then added adjacent to - * each other to get a result twice the size of input. - * Example : out = __lsx_vdp2_h_bu_b(in_h, in_l) - * in_h : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 - * in_l : 8,7,6,5, 4,3,2,1, 8,7,6,5, 4,3,2,-1 - * out : 22,38,38,22, 22,38,38,6 - * ============================================================================= - */ -static inline __m128i __lsx_vdp2_h_bu_b(__m128i in_h, __m128i in_l) { - __m128i out; - - out = __lsx_vmulwev_h_bu_b(in_h, in_l); - out = __lsx_vmaddwod_h_bu_b(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product of byte vector elements - * Arguments : Inputs - in_h, in_l - * Outputs - out - * Return Type - halfword - * Details : Signed byte elements from in_h are multiplied by - * signed byte elements from in_l, and then added adjacent to - * each other to get a result twice the size of input. - * Example : out = __lsx_vdp2_w_h(in_h, in_l) - * in_h : 1,2,3,4, 5,6,7,8 - * in_l : 8,7,6,5, 4,3,2,1 - * out : 22,38,38,22 - * ============================================================================= - */ -static inline __m128i __lsx_vdp2_w_h(__m128i in_h, __m128i in_l) { - __m128i out; - - out = __lsx_vmulwev_w_h(in_h, in_l); - out = __lsx_vmaddwod_w_h(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product of byte vector elements - * Arguments : Inputs - in_h, in_l - * Outputs - out - * Return Type - double - * Details : Signed byte elements from in_h are multiplied by - * signed byte elements from in_l, and then added adjacent to - * each other to get a result twice the size of input. - * Example : out = __lsx_vdp2_d_w(in_h, in_l) - * in_h : 1,2,3,4 - * in_l : 8,7,6,5 - * out : 22,38 - * ============================================================================= - */ -static inline __m128i __lsx_vdp2_d_w(__m128i in_h, __m128i in_l) { - __m128i out; - - out = __lsx_vmulwev_d_w(in_h, in_l); - out = __lsx_vmaddwod_d_w(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Clip all halfword elements of input vector between min & max - * out = ((_in) < (min)) ? (min) : (((_in) > (max)) ? (max) : - * (_in)) - * Arguments : Inputs - _in (input vector) - * - min (min threshold) - * - max (max threshold) - * Outputs - out (output vector with clipped elements) - * Return Type - signed halfword - * Example : out = __lsx_vclip_h(_in) - * _in : -8,2,280,249, -8,255,280,249 - * min : 1,1,1,1, 1,1,1,1 - * max : 9,9,9,9, 9,9,9,9 - * out : 1,2,9,9, 1,9,9,9 - * ============================================================================= - */ -static inline __m128i __lsx_vclip_h(__m128i _in, __m128i min, __m128i max) { - __m128i out; - - out = __lsx_vmax_h(min, _in); - out = __lsx_vmin_h(max, out); - return out; -} - -/* - * ============================================================================= - * Description : Set each element of vector between 0 and 255 - * Arguments : Inputs - _in - * Outputs - out - * Return Type - halfword - * Details : Signed byte elements from _in are clamped between 0 and 255. - * Example : out = __lsx_vclip255_h(_in) - * _in : -8,255,280,249, -8,255,280,249 - * out : 0,255,255,249, 0,255,255,249 - * ============================================================================= - */ -static inline __m128i __lsx_vclip255_h(__m128i _in) { - __m128i out; - - out = __lsx_vmaxi_h(_in, 0); - out = __lsx_vsat_hu(out, 7); - return out; -} - -/* - * ============================================================================= - * Description : Set each element of vector between 0 and 255 - * Arguments : Inputs - _in - * Outputs - out - * Return Type - word - * Details : Signed byte elements from _in are clamped between 0 and 255. - * Example : out = __lsx_vclip255_w(_in) - * _in : -8,255,280,249 - * out : 0,255,255,249 - * ============================================================================= - */ -static inline __m128i __lsx_vclip255_w(__m128i _in) { - __m128i out; - - out = __lsx_vmaxi_w(_in, 0); - out = __lsx_vsat_wu(out, 7); - return out; -} - -/* - * ============================================================================= - * Description : Swap two variables - * Arguments : Inputs - _in0, _in1 - * Outputs - _in0, _in1 (in-place) - * Details : Swapping of two input variables using xor - * Example : LSX_SWAP(_in0, _in1) - * _in0 : 1,2,3,4 - * _in1 : 5,6,7,8 - * _in0(out) : 5,6,7,8 - * _in1(out) : 1,2,3,4 - * ============================================================================= - */ -#define LSX_SWAP(_in0, _in1) \ - { \ - _in0 = __lsx_vxor_v(_in0, _in1); \ - _in1 = __lsx_vxor_v(_in0, _in1); \ - _in0 = __lsx_vxor_v(_in0, _in1); \ - } - -/* - * ============================================================================= - * Description : Transpose 4x4 block with word elements in vectors - * Arguments : Inputs - in0, in1, in2, in3 - * Outputs - out0, out1, out2, out3 - * Details : - * Example : - * 1, 2, 3, 4 1, 5, 9,13 - * 5, 6, 7, 8 to 2, 6,10,14 - * 9,10,11,12 =====> 3, 7,11,15 - * 13,14,15,16 4, 8,12,16 - * ============================================================================= - */ -#define LSX_TRANSPOSE4x4_W(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ - { \ - __m128i _t0, _t1, _t2, _t3; \ - \ - _t0 = __lsx_vilvl_w(_in1, _in0); \ - _t1 = __lsx_vilvh_w(_in1, _in0); \ - _t2 = __lsx_vilvl_w(_in3, _in2); \ - _t3 = __lsx_vilvh_w(_in3, _in2); \ - _out0 = __lsx_vilvl_d(_t2, _t0); \ - _out1 = __lsx_vilvh_d(_t2, _t0); \ - _out2 = __lsx_vilvl_d(_t3, _t1); \ - _out3 = __lsx_vilvh_d(_t3, _t1); \ - } - -/* - * ============================================================================= - * Description : Transpose 8x8 block with byte elements in vectors - * Arguments : Inputs - _in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7 - * Outputs - _out0, _out1, _out2, _out3, _out4, _out5, _out6, - * _out7 - * Details : The rows of the matrix become columns, and the columns - * become rows. - * Example : LSX_TRANSPOSE8x8_B - * _in0 : 00,01,02,03,04,05,06,07, 00,00,00,00,00,00,00,00 - * _in1 : 10,11,12,13,14,15,16,17, 00,00,00,00,00,00,00,00 - * _in2 : 20,21,22,23,24,25,26,27, 00,00,00,00,00,00,00,00 - * _in3 : 30,31,32,33,34,35,36,37, 00,00,00,00,00,00,00,00 - * _in4 : 40,41,42,43,44,45,46,47, 00,00,00,00,00,00,00,00 - * _in5 : 50,51,52,53,54,55,56,57, 00,00,00,00,00,00,00,00 - * _in6 : 60,61,62,63,64,65,66,67, 00,00,00,00,00,00,00,00 - * _in7 : 70,71,72,73,74,75,76,77, 00,00,00,00,00,00,00,00 - * - * _ out0 : 00,10,20,30,40,50,60,70, 00,00,00,00,00,00,00,00 - * _ out1 : 01,11,21,31,41,51,61,71, 00,00,00,00,00,00,00,00 - * _ out2 : 02,12,22,32,42,52,62,72, 00,00,00,00,00,00,00,00 - * _ out3 : 03,13,23,33,43,53,63,73, 00,00,00,00,00,00,00,00 - * _ out4 : 04,14,24,34,44,54,64,74, 00,00,00,00,00,00,00,00 - * _ out5 : 05,15,25,35,45,55,65,75, 00,00,00,00,00,00,00,00 - * _ out6 : 06,16,26,36,46,56,66,76, 00,00,00,00,00,00,00,00 - * _ out7 : 07,17,27,37,47,57,67,77, 00,00,00,00,00,00,00,00 - * ============================================================================= - */ -#define LSX_TRANSPOSE8x8_B(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ - _out7) \ - { \ - __m128i zero = { 0 }; \ - __m128i shuf8 = { 0x0F0E0D0C0B0A0908, 0x1716151413121110 }; \ - __m128i _t0, _t1, _t2, _t3, _t4, _t5, _t6, _t7; \ - \ - _t0 = __lsx_vilvl_b(_in2, _in0); \ - _t1 = __lsx_vilvl_b(_in3, _in1); \ - _t2 = __lsx_vilvl_b(_in6, _in4); \ - _t3 = __lsx_vilvl_b(_in7, _in5); \ - _t4 = __lsx_vilvl_b(_t1, _t0); \ - _t5 = __lsx_vilvh_b(_t1, _t0); \ - _t6 = __lsx_vilvl_b(_t3, _t2); \ - _t7 = __lsx_vilvh_b(_t3, _t2); \ - _out0 = __lsx_vilvl_w(_t6, _t4); \ - _out2 = __lsx_vilvh_w(_t6, _t4); \ - _out4 = __lsx_vilvl_w(_t7, _t5); \ - _out6 = __lsx_vilvh_w(_t7, _t5); \ - _out1 = __lsx_vshuf_b(zero, _out0, shuf8); \ - _out3 = __lsx_vshuf_b(zero, _out2, shuf8); \ - _out5 = __lsx_vshuf_b(zero, _out4, shuf8); \ - _out7 = __lsx_vshuf_b(zero, _out6, shuf8); \ - } - -/* - * ============================================================================= - * Description : Transpose 8x8 block with half-word elements in vectors - * Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7 - * Outputs - out0, out1, out2, out3, out4, out5, out6, out7 - * Details : - * Example : - * 00,01,02,03,04,05,06,07 00,10,20,30,40,50,60,70 - * 10,11,12,13,14,15,16,17 01,11,21,31,41,51,61,71 - * 20,21,22,23,24,25,26,27 02,12,22,32,42,52,62,72 - * 30,31,32,33,34,35,36,37 to 03,13,23,33,43,53,63,73 - * 40,41,42,43,44,45,46,47 ======> 04,14,24,34,44,54,64,74 - * 50,51,52,53,54,55,56,57 05,15,25,35,45,55,65,75 - * 60,61,62,63,64,65,66,67 06,16,26,36,46,56,66,76 - * 70,71,72,73,74,75,76,77 07,17,27,37,47,57,67,77 - * ============================================================================= - */ -#define LSX_TRANSPOSE8x8_H(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ - _out7) \ - { \ - __m128i _s0, _s1, _t0, _t1, _t2, _t3, _t4, _t5, _t6, _t7; \ - \ - _s0 = __lsx_vilvl_h(_in6, _in4); \ - _s1 = __lsx_vilvl_h(_in7, _in5); \ - _t0 = __lsx_vilvl_h(_s1, _s0); \ - _t1 = __lsx_vilvh_h(_s1, _s0); \ - _s0 = __lsx_vilvh_h(_in6, _in4); \ - _s1 = __lsx_vilvh_h(_in7, _in5); \ - _t2 = __lsx_vilvl_h(_s1, _s0); \ - _t3 = __lsx_vilvh_h(_s1, _s0); \ - _s0 = __lsx_vilvl_h(_in2, _in0); \ - _s1 = __lsx_vilvl_h(_in3, _in1); \ - _t4 = __lsx_vilvl_h(_s1, _s0); \ - _t5 = __lsx_vilvh_h(_s1, _s0); \ - _s0 = __lsx_vilvh_h(_in2, _in0); \ - _s1 = __lsx_vilvh_h(_in3, _in1); \ - _t6 = __lsx_vilvl_h(_s1, _s0); \ - _t7 = __lsx_vilvh_h(_s1, _s0); \ - \ - _out0 = __lsx_vpickev_d(_t0, _t4); \ - _out2 = __lsx_vpickev_d(_t1, _t5); \ - _out4 = __lsx_vpickev_d(_t2, _t6); \ - _out6 = __lsx_vpickev_d(_t3, _t7); \ - _out1 = __lsx_vpickod_d(_t0, _t4); \ - _out3 = __lsx_vpickod_d(_t1, _t5); \ - _out5 = __lsx_vpickod_d(_t2, _t6); \ - _out7 = __lsx_vpickod_d(_t3, _t7); \ - } - -/* - * ============================================================================= - * Description : Transpose input 8x4 byte block into 4x8 - * Arguments : Inputs - _in0, _in1, _in2, _in3 (input 8x4 byte block) - * Outputs - _out0, _out1, _out2, _out3 (output 4x8 byte block) - * Return Type - as per RTYPE - * Details : The rows of the matrix become columns, and the columns become - * rows. - * Example : LSX_TRANSPOSE8x4_B - * _in0 : 00,01,02,03,00,00,00,00, 00,00,00,00,00,00,00,00 - * _in1 : 10,11,12,13,00,00,00,00, 00,00,00,00,00,00,00,00 - * _in2 : 20,21,22,23,00,00,00,00, 00,00,00,00,00,00,00,00 - * _in3 : 30,31,32,33,00,00,00,00, 00,00,00,00,00,00,00,00 - * _in4 : 40,41,42,43,00,00,00,00, 00,00,00,00,00,00,00,00 - * _in5 : 50,51,52,53,00,00,00,00, 00,00,00,00,00,00,00,00 - * _in6 : 60,61,62,63,00,00,00,00, 00,00,00,00,00,00,00,00 - * _in7 : 70,71,72,73,00,00,00,00, 00,00,00,00,00,00,00,00 - * - * _out0 : 00,10,20,30,40,50,60,70, 00,00,00,00,00,00,00,00 - * _out1 : 01,11,21,31,41,51,61,71, 00,00,00,00,00,00,00,00 - * _out2 : 02,12,22,32,42,52,62,72, 00,00,00,00,00,00,00,00 - * _out3 : 03,13,23,33,43,53,63,73, 00,00,00,00,00,00,00,00 - * ============================================================================= - */ -#define LSX_TRANSPOSE8x4_B(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _out0, _out1, _out2, _out3) \ - { \ - __m128i _tmp0_m, _tmp1_m, _tmp2_m, _tmp3_m; \ - \ - _tmp0_m = __lsx_vpackev_w(_in4, _in0); \ - _tmp1_m = __lsx_vpackev_w(_in5, _in1); \ - _tmp2_m = __lsx_vilvl_b(_tmp1_m, _tmp0_m); \ - _tmp0_m = __lsx_vpackev_w(_in6, _in2); \ - _tmp1_m = __lsx_vpackev_w(_in7, _in3); \ - \ - _tmp3_m = __lsx_vilvl_b(_tmp1_m, _tmp0_m); \ - _tmp0_m = __lsx_vilvl_h(_tmp3_m, _tmp2_m); \ - _tmp1_m = __lsx_vilvh_h(_tmp3_m, _tmp2_m); \ - \ - _out0 = __lsx_vilvl_w(_tmp1_m, _tmp0_m); \ - _out2 = __lsx_vilvh_w(_tmp1_m, _tmp0_m); \ - _out1 = __lsx_vilvh_d(_out2, _out0); \ - _out3 = __lsx_vilvh_d(_out0, _out2); \ - } - -/* - * ============================================================================= - * Description : Transpose 16x8 block with byte elements in vectors - * Arguments : Inputs - in0, in1, in2, in3, in4, in5, in6, in7, in8 - * in9, in10, in11, in12, in13, in14, in15 - * Outputs - out0, out1, out2, out3, out4, out5, out6, out7 - * Details : - * Example : - * 000,001,002,003,004,005,006,007 - * 008,009,010,011,012,013,014,015 - * 016,017,018,019,020,021,022,023 - * 024,025,026,027,028,029,030,031 - * 032,033,034,035,036,037,038,039 - * 040,041,042,043,044,045,046,047 000,008,...,112,120 - * 048,049,050,051,052,053,054,055 001,009,...,113,121 - * 056,057,058,059,060,061,062,063 to 002,010,...,114,122 - * 064,068,066,067,068,069,070,071 =====> 003,011,...,115,123 - * 072,073,074,075,076,077,078,079 004,012,...,116,124 - * 080,081,082,083,084,085,086,087 005,013,...,117,125 - * 088,089,090,091,092,093,094,095 006,014,...,118,126 - * 096,097,098,099,100,101,102,103 007,015,...,119,127 - * 104,105,106,107,108,109,110,111 - * 112,113,114,115,116,117,118,119 - * 120,121,122,123,124,125,126,127 - * ============================================================================= - */ -#define LSX_TRANSPOSE16x8_B(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _in8, _in9, _in10, _in11, _in12, _in13, _in14, \ - _in15, _out0, _out1, _out2, _out3, _out4, _out5, \ - _out6, _out7) \ - { \ - __m128i _tmp0, _tmp1, _tmp2, _tmp3, _tmp4, _tmp5, _tmp6, _tmp7; \ - __m128i _t0, _t1, _t2, _t3, _t4, _t5, _t6, _t7; \ - DUP4_ARG2(__lsx_vilvl_b, _in2, _in0, _in3, _in1, _in6, _in4, _in7, _in5, \ - _tmp0, _tmp1, _tmp2, _tmp3); \ - DUP4_ARG2(__lsx_vilvl_b, _in10, _in8, _in11, _in9, _in14, _in12, _in15, \ - _in13, _tmp4, _tmp5, _tmp6, _tmp7); \ - DUP2_ARG2(__lsx_vilvl_b, _tmp1, _tmp0, _tmp3, _tmp2, _t0, _t2); \ - DUP2_ARG2(__lsx_vilvh_b, _tmp1, _tmp0, _tmp3, _tmp2, _t1, _t3); \ - DUP2_ARG2(__lsx_vilvl_b, _tmp5, _tmp4, _tmp7, _tmp6, _t4, _t6); \ - DUP2_ARG2(__lsx_vilvh_b, _tmp5, _tmp4, _tmp7, _tmp6, _t5, _t7); \ - DUP2_ARG2(__lsx_vilvl_w, _t2, _t0, _t3, _t1, _tmp0, _tmp4); \ - DUP2_ARG2(__lsx_vilvh_w, _t2, _t0, _t3, _t1, _tmp2, _tmp6); \ - DUP2_ARG2(__lsx_vilvl_w, _t6, _t4, _t7, _t5, _tmp1, _tmp5); \ - DUP2_ARG2(__lsx_vilvh_w, _t6, _t4, _t7, _t5, _tmp3, _tmp7); \ - DUP2_ARG2(__lsx_vilvl_d, _tmp1, _tmp0, _tmp3, _tmp2, _out0, _out2); \ - DUP2_ARG2(__lsx_vilvh_d, _tmp1, _tmp0, _tmp3, _tmp2, _out1, _out3); \ - DUP2_ARG2(__lsx_vilvl_d, _tmp5, _tmp4, _tmp7, _tmp6, _out4, _out6); \ - DUP2_ARG2(__lsx_vilvh_d, _tmp5, _tmp4, _tmp7, _tmp6, _out5, _out7); \ - } - -/* - * ============================================================================= - * Description : Butterfly of 4 input vectors - * Arguments : Inputs - in0, in1, in2, in3 - * Outputs - out0, out1, out2, out3 - * Details : Butterfly operation - * Example : - * out0 = in0 + in3; - * out1 = in1 + in2; - * out2 = in1 - in2; - * out3 = in0 - in3; - * ============================================================================= - */ -#define LSX_BUTTERFLY_4_B(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ - { \ - _out0 = __lsx_vadd_b(_in0, _in3); \ - _out1 = __lsx_vadd_b(_in1, _in2); \ - _out2 = __lsx_vsub_b(_in1, _in2); \ - _out3 = __lsx_vsub_b(_in0, _in3); \ - } -#define LSX_BUTTERFLY_4_H(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ - { \ - _out0 = __lsx_vadd_h(_in0, _in3); \ - _out1 = __lsx_vadd_h(_in1, _in2); \ - _out2 = __lsx_vsub_h(_in1, _in2); \ - _out3 = __lsx_vsub_h(_in0, _in3); \ - } -#define LSX_BUTTERFLY_4_W(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ - { \ - _out0 = __lsx_vadd_w(_in0, _in3); \ - _out1 = __lsx_vadd_w(_in1, _in2); \ - _out2 = __lsx_vsub_w(_in1, _in2); \ - _out3 = __lsx_vsub_w(_in0, _in3); \ - } -#define LSX_BUTTERFLY_4_D(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ - { \ - _out0 = __lsx_vadd_d(_in0, _in3); \ - _out1 = __lsx_vadd_d(_in1, _in2); \ - _out2 = __lsx_vsub_d(_in1, _in2); \ - _out3 = __lsx_vsub_d(_in0, _in3); \ - } - -/* - * ============================================================================= - * Description : Butterfly of 8 input vectors - * Arguments : Inputs - _in0, _in1, _in2, _in3, ~ - * Outputs - _out0, _out1, _out2, _out3, ~ - * Details : Butterfly operation - * Example : - * _out0 = _in0 + _in7; - * _out1 = _in1 + _in6; - * _out2 = _in2 + _in5; - * _out3 = _in3 + _in4; - * _out4 = _in3 - _in4; - * _out5 = _in2 - _in5; - * _out6 = _in1 - _in6; - * _out7 = _in0 - _in7; - * ============================================================================= - */ -#define LSX_BUTTERFLY_8_B(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ - _out7) \ - { \ - _out0 = __lsx_vadd_b(_in0, _in7); \ - _out1 = __lsx_vadd_b(_in1, _in6); \ - _out2 = __lsx_vadd_b(_in2, _in5); \ - _out3 = __lsx_vadd_b(_in3, _in4); \ - _out4 = __lsx_vsub_b(_in3, _in4); \ - _out5 = __lsx_vsub_b(_in2, _in5); \ - _out6 = __lsx_vsub_b(_in1, _in6); \ - _out7 = __lsx_vsub_b(_in0, _in7); \ - } - -#define LSX_BUTTERFLY_8_H(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ - _out7) \ - { \ - _out0 = __lsx_vadd_h(_in0, _in7); \ - _out1 = __lsx_vadd_h(_in1, _in6); \ - _out2 = __lsx_vadd_h(_in2, _in5); \ - _out3 = __lsx_vadd_h(_in3, _in4); \ - _out4 = __lsx_vsub_h(_in3, _in4); \ - _out5 = __lsx_vsub_h(_in2, _in5); \ - _out6 = __lsx_vsub_h(_in1, _in6); \ - _out7 = __lsx_vsub_h(_in0, _in7); \ - } - -#define LSX_BUTTERFLY_8_W(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ - _out7) \ - { \ - _out0 = __lsx_vadd_w(_in0, _in7); \ - _out1 = __lsx_vadd_w(_in1, _in6); \ - _out2 = __lsx_vadd_w(_in2, _in5); \ - _out3 = __lsx_vadd_w(_in3, _in4); \ - _out4 = __lsx_vsub_w(_in3, _in4); \ - _out5 = __lsx_vsub_w(_in2, _in5); \ - _out6 = __lsx_vsub_w(_in1, _in6); \ - _out7 = __lsx_vsub_w(_in0, _in7); \ - } - -#define LSX_BUTTERFLY_8_D(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ - _out7) \ - { \ - _out0 = __lsx_vadd_d(_in0, _in7); \ - _out1 = __lsx_vadd_d(_in1, _in6); \ - _out2 = __lsx_vadd_d(_in2, _in5); \ - _out3 = __lsx_vadd_d(_in3, _in4); \ - _out4 = __lsx_vsub_d(_in3, _in4); \ - _out5 = __lsx_vsub_d(_in2, _in5); \ - _out6 = __lsx_vsub_d(_in1, _in6); \ - _out7 = __lsx_vsub_d(_in0, _in7); \ - } - -/* - * ============================================================================= - * Description : Butterfly of 16 input vectors - * Arguments : Inputs - _in0, _in1, _in2, _in3, ~ - * Outputs - _out0, _out1, _out2, _out3, ~ - * Details : Butterfly operation - * Example : - * _out0 = _in0 + _in15; - * _out1 = _in1 + _in14; - * _out2 = _in2 + _in13; - * _out3 = _in3 + _in12; - * _out4 = _in4 + _in11; - * _out5 = _in5 + _in10; - * _out6 = _in6 + _in9; - * _out7 = _in7 + _in8; - * _out8 = _in7 - _in8; - * _out9 = _in6 - _in9; - * _out10 = _in5 - _in10; - * _out11 = _in4 - _in11; - * _out12 = _in3 - _in12; - * _out13 = _in2 - _in13; - * _out14 = _in1 - _in14; - * _out15 = _in0 - _in15; - * ============================================================================= - */ - -#define LSX_BUTTERFLY_16_B(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _in8, _in9, _in10, _in11, _in12, _in13, _in14, \ - _in15, _out0, _out1, _out2, _out3, _out4, _out5, \ - _out6, _out7, _out8, _out9, _out10, _out11, _out12, \ - _out13, _out14, _out15) \ - { \ - _out0 = __lsx_vadd_b(_in0, _in15); \ - _out1 = __lsx_vadd_b(_in1, _in14); \ - _out2 = __lsx_vadd_b(_in2, _in13); \ - _out3 = __lsx_vadd_b(_in3, _in12); \ - _out4 = __lsx_vadd_b(_in4, _in11); \ - _out5 = __lsx_vadd_b(_in5, _in10); \ - _out6 = __lsx_vadd_b(_in6, _in9); \ - _out7 = __lsx_vadd_b(_in7, _in8); \ - \ - _out8 = __lsx_vsub_b(_in7, _in8); \ - _out9 = __lsx_vsub_b(_in6, _in9); \ - _out10 = __lsx_vsub_b(_in5, _in10); \ - _out11 = __lsx_vsub_b(_in4, _in11); \ - _out12 = __lsx_vsub_b(_in3, _in12); \ - _out13 = __lsx_vsub_b(_in2, _in13); \ - _out14 = __lsx_vsub_b(_in1, _in14); \ - _out15 = __lsx_vsub_b(_in0, _in15); \ - } - -#define LSX_BUTTERFLY_16_H(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _in8, _in9, _in10, _in11, _in12, _in13, _in14, \ - _in15, _out0, _out1, _out2, _out3, _out4, _out5, \ - _out6, _out7, _out8, _out9, _out10, _out11, _out12, \ - _out13, _out14, _out15) \ - { \ - _out0 = __lsx_vadd_h(_in0, _in15); \ - _out1 = __lsx_vadd_h(_in1, _in14); \ - _out2 = __lsx_vadd_h(_in2, _in13); \ - _out3 = __lsx_vadd_h(_in3, _in12); \ - _out4 = __lsx_vadd_h(_in4, _in11); \ - _out5 = __lsx_vadd_h(_in5, _in10); \ - _out6 = __lsx_vadd_h(_in6, _in9); \ - _out7 = __lsx_vadd_h(_in7, _in8); \ - \ - _out8 = __lsx_vsub_h(_in7, _in8); \ - _out9 = __lsx_vsub_h(_in6, _in9); \ - _out10 = __lsx_vsub_h(_in5, _in10); \ - _out11 = __lsx_vsub_h(_in4, _in11); \ - _out12 = __lsx_vsub_h(_in3, _in12); \ - _out13 = __lsx_vsub_h(_in2, _in13); \ - _out14 = __lsx_vsub_h(_in1, _in14); \ - _out15 = __lsx_vsub_h(_in0, _in15); \ - } - -#define LSX_BUTTERFLY_16_W(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _in8, _in9, _in10, _in11, _in12, _in13, _in14, \ - _in15, _out0, _out1, _out2, _out3, _out4, _out5, \ - _out6, _out7, _out8, _out9, _out10, _out11, _out12, \ - _out13, _out14, _out15) \ - { \ - _out0 = __lsx_vadd_w(_in0, _in15); \ - _out1 = __lsx_vadd_w(_in1, _in14); \ - _out2 = __lsx_vadd_w(_in2, _in13); \ - _out3 = __lsx_vadd_w(_in3, _in12); \ - _out4 = __lsx_vadd_w(_in4, _in11); \ - _out5 = __lsx_vadd_w(_in5, _in10); \ - _out6 = __lsx_vadd_w(_in6, _in9); \ - _out7 = __lsx_vadd_w(_in7, _in8); \ - \ - _out8 = __lsx_vsub_w(_in7, _in8); \ - _out9 = __lsx_vsub_w(_in6, _in9); \ - _out10 = __lsx_vsub_w(_in5, _in10); \ - _out11 = __lsx_vsub_w(_in4, _in11); \ - _out12 = __lsx_vsub_w(_in3, _in12); \ - _out13 = __lsx_vsub_w(_in2, _in13); \ - _out14 = __lsx_vsub_w(_in1, _in14); \ - _out15 = __lsx_vsub_w(_in0, _in15); \ - } - -#define LSX_BUTTERFLY_16_D(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _in8, _in9, _in10, _in11, _in12, _in13, _in14, \ - _in15, _out0, _out1, _out2, _out3, _out4, _out5, \ - _out6, _out7, _out8, _out9, _out10, _out11, _out12, \ - _out13, _out14, _out15) \ - { \ - _out0 = __lsx_vadd_d(_in0, _in15); \ - _out1 = __lsx_vadd_d(_in1, _in14); \ - _out2 = __lsx_vadd_d(_in2, _in13); \ - _out3 = __lsx_vadd_d(_in3, _in12); \ - _out4 = __lsx_vadd_d(_in4, _in11); \ - _out5 = __lsx_vadd_d(_in5, _in10); \ - _out6 = __lsx_vadd_d(_in6, _in9); \ - _out7 = __lsx_vadd_d(_in7, _in8); \ - \ - _out8 = __lsx_vsub_d(_in7, _in8); \ - _out9 = __lsx_vsub_d(_in6, _in9); \ - _out10 = __lsx_vsub_d(_in5, _in10); \ - _out11 = __lsx_vsub_d(_in4, _in11); \ - _out12 = __lsx_vsub_d(_in3, _in12); \ - _out13 = __lsx_vsub_d(_in2, _in13); \ - _out14 = __lsx_vsub_d(_in1, _in14); \ - _out15 = __lsx_vsub_d(_in0, _in15); \ - } - -#endif // LSX - -#ifdef __loongarch_asx -#include -/* - * ============================================================================= - * Description : Dot product of byte vector elements - * Arguments : Inputs - in_h, in_l - * Output - out - * Return Type - signed halfword - * Details : Unsigned byte elements from in_h are multiplied with - * unsigned byte elements from in_l producing a result - * twice the size of input i.e. signed halfword. - * Then these multiplied results of adjacent odd-even elements - * are added to the out vector - * Example : See out = __lasx_xvdp2_w_h(in_h, in_l) - * ============================================================================= - */ -static inline __m256i __lasx_xvdp2_h_bu(__m256i in_h, __m256i in_l) { - __m256i out; - - out = __lasx_xvmulwev_h_bu(in_h, in_l); - out = __lasx_xvmaddwod_h_bu(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product of byte vector elements - * Arguments : Inputs - in_h, in_l - * Output - out - * Return Type - signed halfword - * Details : Signed byte elements from in_h are multiplied with - * signed byte elements from in_l producing a result - * twice the size of input i.e. signed halfword. - * Then these multiplication results of adjacent odd-even elements - * are added to the out vector - * Example : See out = __lasx_xvdp2_w_h(in_h, in_l) - * ============================================================================= - */ -static inline __m256i __lasx_xvdp2_h_b(__m256i in_h, __m256i in_l) { - __m256i out; - - out = __lasx_xvmulwev_h_b(in_h, in_l); - out = __lasx_xvmaddwod_h_b(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product of halfword vector elements - * Arguments : Inputs - in_h, in_l - * Output - out - * Return Type - signed word - * Details : Signed halfword elements from in_h are multiplied with - * signed halfword elements from in_l producing a result - * twice the size of input i.e. signed word. - * Then these multiplied results of adjacent odd-even elements - * are added to the out vector. - * Example : out = __lasx_xvdp2_w_h(in_h, in_l) - * in_h : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 - * in_l : 8,7,6,5, 4,3,2,1, 8,7,6,5, 4,3,2,1 - * out : 22,38,38,22, 22,38,38,22 - * ============================================================================= - */ -static inline __m256i __lasx_xvdp2_w_h(__m256i in_h, __m256i in_l) { - __m256i out; - - out = __lasx_xvmulwev_w_h(in_h, in_l); - out = __lasx_xvmaddwod_w_h(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product of word vector elements - * Arguments : Inputs - in_h, in_l - * Output - out - * Return Type - signed double - * Details : Signed word elements from in_h are multiplied with - * signed word elements from in_l producing a result - * twice the size of input i.e. signed double-word. - * Then these multiplied results of adjacent odd-even elements - * are added to the out vector. - * Example : See out = __lasx_xvdp2_w_h(in_h, in_l) - * ============================================================================= - */ -static inline __m256i __lasx_xvdp2_d_w(__m256i in_h, __m256i in_l) { - __m256i out; - - out = __lasx_xvmulwev_d_w(in_h, in_l); - out = __lasx_xvmaddwod_d_w(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product of halfword vector elements - * Arguments : Inputs - in_h, in_l - * Output - out - * Return Type - signed word - * Details : Unsigned halfword elements from in_h are multiplied with - * signed halfword elements from in_l producing a result - * twice the size of input i.e. unsigned word. - * Multiplication result of adjacent odd-even elements - * are added to the out vector - * Example : See out = __lasx_xvdp2_w_h(in_h, in_l) - * ============================================================================= - */ -static inline __m256i __lasx_xvdp2_w_hu_h(__m256i in_h, __m256i in_l) { - __m256i out; - - out = __lasx_xvmulwev_w_hu_h(in_h, in_l); - out = __lasx_xvmaddwod_w_hu_h(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product & addition of byte vector elements - * Arguments : Inputs - in_h, in_l - * Output - out - * Return Type - halfword - * Details : Signed byte elements from in_h are multiplied with - * signed byte elements from in_l producing a result - * twice the size of input i.e. signed halfword. - * Then these multiplied results of adjacent odd-even elements - * are added to the in_c vector. - * Example : See out = __lasx_xvdp2add_w_h(in_c, in_h, in_l) - * ============================================================================= - */ -static inline __m256i __lasx_xvdp2add_h_b(__m256i in_c, __m256i in_h, - __m256i in_l) { - __m256i out; - - out = __lasx_xvmaddwev_h_b(in_c, in_h, in_l); - out = __lasx_xvmaddwod_h_b(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product & addition of byte vector elements - * Arguments : Inputs - in_h, in_l - * Output - out - * Return Type - halfword - * Details : Unsigned byte elements from in_h are multiplied with - * unsigned byte elements from in_l producing a result - * twice the size of input i.e. signed halfword. - * Then these multiplied results of adjacent odd-even elements - * are added to the in_c vector. - * Example : See out = __lasx_xvdp2add_w_h(in_c, in_h, in_l) - * ============================================================================= - */ -static inline __m256i __lasx_xvdp2add_h_bu(__m256i in_c, __m256i in_h, - __m256i in_l) { - __m256i out; - - out = __lasx_xvmaddwev_h_bu(in_c, in_h, in_l); - out = __lasx_xvmaddwod_h_bu(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product & addition of byte vector elements - * Arguments : Inputs - in_h, in_l - * Output - out - * Return Type - halfword - * Details : Unsigned byte elements from in_h are multiplied with - * signed byte elements from in_l producing a result - * twice the size of input i.e. signed halfword. - * Then these multiplied results of adjacent odd-even elements - * are added to the in_c vector. - * Example : See out = __lasx_xvdp2add_w_h(in_c, in_h, in_l) - * ============================================================================= - */ -static inline __m256i __lasx_xvdp2add_h_bu_b(__m256i in_c, __m256i in_h, - __m256i in_l) { - __m256i out; - - out = __lasx_xvmaddwev_h_bu_b(in_c, in_h, in_l); - out = __lasx_xvmaddwod_h_bu_b(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product of halfword vector elements - * Arguments : Inputs - in_c, in_h, in_l - * Output - out - * Return Type - per RTYPE - * Details : Signed halfword elements from in_h are multiplied with - * signed halfword elements from in_l producing a result - * twice the size of input i.e. signed word. - * Multiplication result of adjacent odd-even elements - * are added to the in_c vector. - * Example : out = __lasx_xvdp2add_w_h(in_c, in_h, in_l) - * in_c : 1,2,3,4, 1,2,3,4 - * in_h : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8, - * in_l : 8,7,6,5, 4,3,2,1, 8,7,6,5, 4,3,2,1, - * out : 23,40,41,26, 23,40,41,26 - * ============================================================================= - */ -static inline __m256i __lasx_xvdp2add_w_h(__m256i in_c, __m256i in_h, - __m256i in_l) { - __m256i out; - - out = __lasx_xvmaddwev_w_h(in_c, in_h, in_l); - out = __lasx_xvmaddwod_w_h(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product of halfword vector elements - * Arguments : Inputs - in_c, in_h, in_l - * Output - out - * Return Type - signed word - * Details : Unsigned halfword elements from in_h are multiplied with - * unsigned halfword elements from in_l producing a result - * twice the size of input i.e. signed word. - * Multiplication result of adjacent odd-even elements - * are added to the in_c vector. - * Example : See out = __lasx_xvdp2add_w_h(in_c, in_h, in_l) - * ============================================================================= - */ -static inline __m256i __lasx_xvdp2add_w_hu(__m256i in_c, __m256i in_h, - __m256i in_l) { - __m256i out; - - out = __lasx_xvmaddwev_w_hu(in_c, in_h, in_l); - out = __lasx_xvmaddwod_w_hu(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Dot product of halfword vector elements - * Arguments : Inputs - in_c, in_h, in_l - * Output - out - * Return Type - signed word - * Details : Unsigned halfword elements from in_h are multiplied with - * signed halfword elements from in_l producing a result - * twice the size of input i.e. signed word. - * Multiplication result of adjacent odd-even elements - * are added to the in_c vector - * Example : See out = __lasx_xvdp2add_w_h(in_c, in_h, in_l) - * ============================================================================= - */ -static inline __m256i __lasx_xvdp2add_w_hu_h(__m256i in_c, __m256i in_h, - __m256i in_l) { - __m256i out; - - out = __lasx_xvmaddwev_w_hu_h(in_c, in_h, in_l); - out = __lasx_xvmaddwod_w_hu_h(out, in_h, in_l); - return out; -} - -/* - * ============================================================================= - * Description : Vector Unsigned Dot Product and Subtract - * Arguments : Inputs - in_c, in_h, in_l - * Output - out - * Return Type - signed halfword - * Details : Unsigned byte elements from in_h are multiplied with - * unsigned byte elements from in_l producing a result - * twice the size of input i.e. signed halfword. - * Multiplication result of adjacent odd-even elements - * are added together and subtracted from double width elements - * in_c vector. - * Example : See out = __lasx_xvdp2sub_w_h(in_c, in_h, in_l) - * ============================================================================= - */ -static inline __m256i __lasx_xvdp2sub_h_bu(__m256i in_c, __m256i in_h, - __m256i in_l) { - __m256i out; - - out = __lasx_xvmulwev_h_bu(in_h, in_l); - out = __lasx_xvmaddwod_h_bu(out, in_h, in_l); - out = __lasx_xvsub_h(in_c, out); - return out; -} - -/* - * ============================================================================= - * Description : Vector Signed Dot Product and Subtract - * Arguments : Inputs - in_c, in_h, in_l - * Output - out - * Return Type - signed word - * Details : Signed halfword elements from in_h are multiplied with - * Signed halfword elements from in_l producing a result - * twice the size of input i.e. signed word. - * Multiplication result of adjacent odd-even elements - * are added together and subtracted from double width elements - * in_c vector. - * Example : out = __lasx_xvdp2sub_w_h(in_c, in_h, in_l) - * in_c : 0,0,0,0, 0,0,0,0 - * in_h : 3,1,3,0, 0,0,0,1, 0,0,1,1, 0,0,0,1 - * in_l : 2,1,1,0, 1,0,0,0, 0,0,1,0, 1,0,0,1 - * out : -7,-3,0,0, 0,-1,0,-1 - * ============================================================================= - */ -static inline __m256i __lasx_xvdp2sub_w_h(__m256i in_c, __m256i in_h, - __m256i in_l) { - __m256i out; - - out = __lasx_xvmulwev_w_h(in_h, in_l); - out = __lasx_xvmaddwod_w_h(out, in_h, in_l); - out = __lasx_xvsub_w(in_c, out); - return out; -} - -/* - * ============================================================================= - * Description : Dot product of halfword vector elements - * Arguments : Inputs - in_h, in_l - * Output - out - * Return Type - signed word - * Details : Signed halfword elements from in_h are multiplied with - * signed halfword elements from in_l producing a result - * four times the size of input i.e. signed doubleword. - * Then these multiplication results of four adjacent elements - * are added together and stored to the out vector. - * Example : out = __lasx_xvdp4_d_h(in_h, in_l) - * in_h : 3,1,3,0, 0,0,0,1, 0,0,1,-1, 0,0,0,1 - * in_l : -2,1,1,0, 1,0,0,0, 0,0,1, 0, 1,0,0,1 - * out : -2,0,1,1 - * ============================================================================= - */ -static inline __m256i __lasx_xvdp4_d_h(__m256i in_h, __m256i in_l) { - __m256i out; - - out = __lasx_xvmulwev_w_h(in_h, in_l); - out = __lasx_xvmaddwod_w_h(out, in_h, in_l); - out = __lasx_xvhaddw_d_w(out, out); - return out; -} - -/* - * ============================================================================= - * Description : The high half of the vector elements are expanded and - * added after being doubled. - * Arguments : Inputs - in_h, in_l - * Output - out - * Details : The in_h vector and the in_l vector are added after the - * higher half of the two-fold sign extension (signed byte - * to signed halfword) and stored to the out vector. - * Example : See out = __lasx_xvaddwh_w_h(in_h, in_l) - * ============================================================================= - */ -static inline __m256i __lasx_xvaddwh_h_b(__m256i in_h, __m256i in_l) { - __m256i out; - - out = __lasx_xvilvh_b(in_h, in_l); - out = __lasx_xvhaddw_h_b(out, out); - return out; -} - -/* - * ============================================================================= - * Description : The high half of the vector elements are expanded and - * added after being doubled. - * Arguments : Inputs - in_h, in_l - * Output - out - * Details : The in_h vector and the in_l vector are added after the - * higher half of the two-fold sign extension (signed halfword - * to signed word) and stored to the out vector. - * Example : out = __lasx_xvaddwh_w_h(in_h, in_l) - * in_h : 3, 0,3,0, 0,0,0,-1, 0,0,1,-1, 0,0,0,1 - * in_l : 2,-1,1,2, 1,0,0, 0, 1,0,1, 0, 1,0,0,1 - * out : 1,0,0,-1, 1,0,0, 2 - * ============================================================================= - */ -static inline __m256i __lasx_xvaddwh_w_h(__m256i in_h, __m256i in_l) { - __m256i out; - - out = __lasx_xvilvh_h(in_h, in_l); - out = __lasx_xvhaddw_w_h(out, out); - return out; -} - -/* - * ============================================================================= - * Description : The low half of the vector elements are expanded and - * added after being doubled. - * Arguments : Inputs - in_h, in_l - * Output - out - * Details : The in_h vector and the in_l vector are added after the - * lower half of the two-fold sign extension (signed byte - * to signed halfword) and stored to the out vector. - * Example : See out = __lasx_xvaddwl_w_h(in_h, in_l) - * ============================================================================= - */ -static inline __m256i __lasx_xvaddwl_h_b(__m256i in_h, __m256i in_l) { - __m256i out; - - out = __lasx_xvilvl_b(in_h, in_l); - out = __lasx_xvhaddw_h_b(out, out); - return out; -} - -/* - * ============================================================================= - * Description : The low half of the vector elements are expanded and - * added after being doubled. - * Arguments : Inputs - in_h, in_l - * Output - out - * Details : The in_h vector and the in_l vector are added after the - * lower half of the two-fold sign extension (signed halfword - * to signed word) and stored to the out vector. - * Example : out = __lasx_xvaddwl_w_h(in_h, in_l) - * in_h : 3, 0,3,0, 0,0,0,-1, 0,0,1,-1, 0,0,0,1 - * in_l : 2,-1,1,2, 1,0,0, 0, 1,0,1, 0, 1,0,0,1 - * out : 5,-1,4,2, 1,0,2,-1 - * ============================================================================= - */ -static inline __m256i __lasx_xvaddwl_w_h(__m256i in_h, __m256i in_l) { - __m256i out; - - out = __lasx_xvilvl_h(in_h, in_l); - out = __lasx_xvhaddw_w_h(out, out); - return out; -} - -/* - * ============================================================================= - * Description : The low half of the vector elements are expanded and - * added after being doubled. - * Arguments : Inputs - in_h, in_l - * Output - out - * Details : The out vector and the out vector are added after the - * lower half of the two-fold zero extension (unsigned byte - * to unsigned halfword) and stored to the out vector. - * Example : See out = __lasx_xvaddwl_w_h(in_h, in_l) - * ============================================================================= - */ -static inline __m256i __lasx_xvaddwl_h_bu(__m256i in_h, __m256i in_l) { - __m256i out; - - out = __lasx_xvilvl_b(in_h, in_l); - out = __lasx_xvhaddw_hu_bu(out, out); - return out; -} - -/* - * ============================================================================= - * Description : The low half of the vector elements are expanded and - * added after being doubled. - * Arguments : Inputs - in_h, in_l - * Output - out - * Details : The in_l vector after double zero extension (unsigned byte to - * signed halfword),added to the in_h vector. - * Example : See out = __lasx_xvaddw_w_w_h(in_h, in_l) - * ============================================================================= - */ -static inline __m256i __lasx_xvaddw_h_h_bu(__m256i in_h, __m256i in_l) { - __m256i out; - - out = __lasx_xvsllwil_hu_bu(in_l, 0); - out = __lasx_xvadd_h(in_h, out); - return out; -} - -/* - * ============================================================================= - * Description : The low half of the vector elements are expanded and - * added after being doubled. - * Arguments : Inputs - in_h, in_l - * Output - out - * Details : The in_l vector after double sign extension (signed halfword to - * signed word), added to the in_h vector. - * Example : out = __lasx_xvaddw_w_w_h(in_h, in_l) - * in_h : 0, 1,0,0, -1,0,0,1, - * in_l : 2,-1,1,2, 1,0,0,0, 0,0,1,0, 1,0,0,1, - * out : 2, 0,1,2, -1,0,1,1, - * ============================================================================= - */ -static inline __m256i __lasx_xvaddw_w_w_h(__m256i in_h, __m256i in_l) { - __m256i out; - - out = __lasx_xvsllwil_w_h(in_l, 0); - out = __lasx_xvadd_w(in_h, out); - return out; -} - -/* - * ============================================================================= - * Description : Multiplication and addition calculation after expansion - * of the lower half of the vector. - * Arguments : Inputs - in_c, in_h, in_l - * Output - out - * Details : The in_h vector and the in_l vector are multiplied after - * the lower half of the two-fold sign extension (signed halfword - * to signed word), and the result is added to the vector in_c, - * then stored to the out vector. - * Example : out = __lasx_xvmaddwl_w_h(in_c, in_h, in_l) - * in_c : 1,2,3,4, 5,6,7,8 - * in_h : 1,2,3,4, 1,2,3,4, 5,6,7,8, 5,6,7,8 - * in_l : 200, 300, 400, 500, 2000, 3000, 4000, 5000, - * -200,-300,-400,-500, -2000,-3000,-4000,-5000 - * out : 201, 602,1203,2004, -995, -1794,-2793,-3992 - * ============================================================================= - */ -static inline __m256i __lasx_xvmaddwl_w_h(__m256i in_c, __m256i in_h, - __m256i in_l) { - __m256i tmp0, tmp1, out; - - tmp0 = __lasx_xvsllwil_w_h(in_h, 0); - tmp1 = __lasx_xvsllwil_w_h(in_l, 0); - tmp0 = __lasx_xvmul_w(tmp0, tmp1); - out = __lasx_xvadd_w(tmp0, in_c); - return out; -} - -/* - * ============================================================================= - * Description : Multiplication and addition calculation after expansion - * of the higher half of the vector. - * Arguments : Inputs - in_c, in_h, in_l - * Output - out - * Details : The in_h vector and the in_l vector are multiplied after - * the higher half of the two-fold sign extension (signed - * halfword to signed word), and the result is added to - * the vector in_c, then stored to the out vector. - * Example : See out = __lasx_xvmaddwl_w_h(in_c, in_h, in_l) - * ============================================================================= - */ -static inline __m256i __lasx_xvmaddwh_w_h(__m256i in_c, __m256i in_h, - __m256i in_l) { - __m256i tmp0, tmp1, out; - - tmp0 = __lasx_xvilvh_h(in_h, in_h); - tmp1 = __lasx_xvilvh_h(in_l, in_l); - tmp0 = __lasx_xvmulwev_w_h(tmp0, tmp1); - out = __lasx_xvadd_w(tmp0, in_c); - return out; -} - -/* - * ============================================================================= - * Description : Multiplication calculation after expansion of the lower - * half of the vector. - * Arguments : Inputs - in_h, in_l - * Output - out - * Details : The in_h vector and the in_l vector are multiplied after - * the lower half of the two-fold sign extension (signed - * halfword to signed word), then stored to the out vector. - * Example : out = __lasx_xvmulwl_w_h(in_h, in_l) - * in_h : 3,-1,3,0, 0,0,0,-1, 0,0,1,-1, 0,0,0,1 - * in_l : 2,-1,1,2, 1,0,0, 0, 0,0,1, 0, 1,0,0,1 - * out : 6,1,3,0, 0,0,1,0 - * ============================================================================= - */ -static inline __m256i __lasx_xvmulwl_w_h(__m256i in_h, __m256i in_l) { - __m256i tmp0, tmp1, out; - - tmp0 = __lasx_xvsllwil_w_h(in_h, 0); - tmp1 = __lasx_xvsllwil_w_h(in_l, 0); - out = __lasx_xvmul_w(tmp0, tmp1); - return out; -} - -/* - * ============================================================================= - * Description : Multiplication calculation after expansion of the lower - * half of the vector. - * Arguments : Inputs - in_h, in_l - * Output - out - * Details : The in_h vector and the in_l vector are multiplied after - * the lower half of the two-fold sign extension (signed - * halfword to signed word), then stored to the out vector. - * Example : out = __lasx_xvmulwh_w_h(in_h, in_l) - * in_h : 3,-1,3,0, 0,0,0,-1, 0,0,1,-1, 0,0,0,1 - * in_l : 2,-1,1,2, 1,0,0, 0, 0,0,1, 0, 1,0,0,1 - * out : 0,0,0,0, 0,0,0,1 - * ============================================================================= - */ -static inline __m256i __lasx_xvmulwh_w_h(__m256i in_h, __m256i in_l) { - __m256i tmp0, tmp1, out; - - tmp0 = __lasx_xvilvh_h(in_h, in_h); - tmp1 = __lasx_xvilvh_h(in_l, in_l); - out = __lasx_xvmulwev_w_h(tmp0, tmp1); - return out; -} - -/* - * ============================================================================= - * Description : The low half of the vector elements are added to the high half - * after being doubled, then saturated. - * Arguments : Inputs - in_h, in_l - * Output - out - * Details : The in_h vector adds the in_l vector after the lower half of - * the two-fold zero extension (unsigned byte to unsigned - * halfword) and then saturated. The results are stored to the out - * vector. - * Example : out = __lasx_xvsaddw_hu_hu_bu(in_h, in_l) - * in_h : 2,65532,1,2, 1,0,0,0, 0,0,1,0, 1,0,0,1 - * in_l : 3,6,3,0, 0,0,0,1, 0,0,1,1, 0,0,0,1, 3,18,3,0, 0,0,0,1, 0,0,1,1, - * 0,0,0,1 - * out : 5,65535,4,2, 1,0,0,1, 3,18,4,0, 1,0,0,2, - * ============================================================================= - */ -static inline __m256i __lasx_xvsaddw_hu_hu_bu(__m256i in_h, __m256i in_l) { - __m256i tmp1, out; - __m256i zero = { 0 }; - - tmp1 = __lasx_xvilvl_b(zero, in_l); - out = __lasx_xvsadd_hu(in_h, tmp1); - return out; -} - -/* - * ============================================================================= - * Description : Clip all halfword elements of input vector between min & max - * out = ((in) < (min)) ? (min) : (((in) > (max)) ? (max) : (in)) - * Arguments : Inputs - in (input vector) - * - min (min threshold) - * - max (max threshold) - * Outputs - in (output vector with clipped elements) - * Return Type - signed halfword - * Example : out = __lasx_xvclip_h(in, min, max) - * in : -8,2,280,249, -8,255,280,249, 4,4,4,4, 5,5,5,5 - * min : 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1 - * max : 9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9 - * out : 1,2,9,9, 1,9,9,9, 4,4,4,4, 5,5,5,5 - * ============================================================================= - */ -static inline __m256i __lasx_xvclip_h(__m256i in, __m256i min, __m256i max) { - __m256i out; - - out = __lasx_xvmax_h(min, in); - out = __lasx_xvmin_h(max, out); - return out; -} - -/* - * ============================================================================= - * Description : Clip all signed halfword elements of input vector - * between 0 & 255 - * Arguments : Inputs - in (input vector) - * Outputs - out (output vector with clipped elements) - * Return Type - signed halfword - * Example : See out = __lasx_xvclip255_w(in) - * ============================================================================= - */ -static inline __m256i __lasx_xvclip255_h(__m256i in) { - __m256i out; - - out = __lasx_xvmaxi_h(in, 0); - out = __lasx_xvsat_hu(out, 7); - return out; -} - -/* - * ============================================================================= - * Description : Clip all signed word elements of input vector - * between 0 & 255 - * Arguments : Inputs - in (input vector) - * Output - out (output vector with clipped elements) - * Return Type - signed word - * Example : out = __lasx_xvclip255_w(in) - * in : -8,255,280,249, -8,255,280,249 - * out : 0,255,255,249, 0,255,255,249 - * ============================================================================= - */ -static inline __m256i __lasx_xvclip255_w(__m256i in) { - __m256i out; - - out = __lasx_xvmaxi_w(in, 0); - out = __lasx_xvsat_wu(out, 7); - return out; -} - -/* - * ============================================================================= - * Description : Indexed halfword element values are replicated to all - * elements in output vector. If 'idx < 8' use xvsplati_l_*, - * if 'idx >= 8' use xvsplati_h_*. - * Arguments : Inputs - in, idx - * Output - out - * Details : Idx element value from in vector is replicated to all - * elements in out vector. - * Valid index range for halfword operation is 0-7 - * Example : out = __lasx_xvsplati_l_h(in, idx) - * in : 20,10,11,12, 13,14,15,16, 0,0,2,0, 0,0,0,0 - * idx : 0x02 - * out : 11,11,11,11, 11,11,11,11, 11,11,11,11, 11,11,11,11 - * ============================================================================= - */ -static inline __m256i __lasx_xvsplati_l_h(__m256i in, int idx) { - __m256i out; - - out = __lasx_xvpermi_q(in, in, 0x02); - out = __lasx_xvreplve_h(out, idx); - return out; -} - -/* - * ============================================================================= - * Description : Indexed halfword element values are replicated to all - * elements in output vector. If 'idx < 8' use xvsplati_l_*, - * if 'idx >= 8' use xvsplati_h_*. - * Arguments : Inputs - in, idx - * Output - out - * Details : Idx element value from in vector is replicated to all - * elements in out vector. - * Valid index range for halfword operation is 0-7 - * Example : out = __lasx_xvsplati_h_h(in, idx) - * in : 20,10,11,12, 13,14,15,16, 0,2,0,0, 0,0,0,0 - * idx : 0x09 - * out : 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2 - * ============================================================================= - */ -static inline __m256i __lasx_xvsplati_h_h(__m256i in, int idx) { - __m256i out; - - out = __lasx_xvpermi_q(in, in, 0x13); - out = __lasx_xvreplve_h(out, idx); - return out; -} - -/* - * ============================================================================= - * Description : Transpose 4x4 block with double-word elements in vectors - * Arguments : Inputs - _in0, _in1, _in2, _in3 - * Outputs - _out0, _out1, _out2, _out3 - * Example : LASX_TRANSPOSE4x4_D - * _in0 : 1,2,3,4 - * _in1 : 1,2,3,4 - * _in2 : 1,2,3,4 - * _in3 : 1,2,3,4 - * - * _out0 : 1,1,1,1 - * _out1 : 2,2,2,2 - * _out2 : 3,3,3,3 - * _out3 : 4,4,4,4 - * ============================================================================= - */ -#define LASX_TRANSPOSE4x4_D(_in0, _in1, _in2, _in3, _out0, _out1, _out2, \ - _out3) \ - { \ - __m256i _tmp0, _tmp1, _tmp2, _tmp3; \ - _tmp0 = __lasx_xvilvl_d(_in1, _in0); \ - _tmp1 = __lasx_xvilvh_d(_in1, _in0); \ - _tmp2 = __lasx_xvilvl_d(_in3, _in2); \ - _tmp3 = __lasx_xvilvh_d(_in3, _in2); \ - _out0 = __lasx_xvpermi_q(_tmp2, _tmp0, 0x20); \ - _out2 = __lasx_xvpermi_q(_tmp2, _tmp0, 0x31); \ - _out1 = __lasx_xvpermi_q(_tmp3, _tmp1, 0x20); \ - _out3 = __lasx_xvpermi_q(_tmp3, _tmp1, 0x31); \ - } - -/* - * ============================================================================= - * Description : Transpose 8x8 block with word elements in vectors - * Arguments : Inputs - _in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7 - * Outputs - _out0, _out1, _out2, _out3, _out4, _out5, _out6, - * _out7 - * Example : LASX_TRANSPOSE8x8_W - * _in0 : 1,2,3,4,5,6,7,8 - * _in1 : 2,2,3,4,5,6,7,8 - * _in2 : 3,2,3,4,5,6,7,8 - * _in3 : 4,2,3,4,5,6,7,8 - * _in4 : 5,2,3,4,5,6,7,8 - * _in5 : 6,2,3,4,5,6,7,8 - * _in6 : 7,2,3,4,5,6,7,8 - * _in7 : 8,2,3,4,5,6,7,8 - * - * _out0 : 1,2,3,4,5,6,7,8 - * _out1 : 2,2,2,2,2,2,2,2 - * _out2 : 3,3,3,3,3,3,3,3 - * _out3 : 4,4,4,4,4,4,4,4 - * _out4 : 5,5,5,5,5,5,5,5 - * _out5 : 6,6,6,6,6,6,6,6 - * _out6 : 7,7,7,7,7,7,7,7 - * _out7 : 8,8,8,8,8,8,8,8 - * ============================================================================= - */ -#define LASX_TRANSPOSE8x8_W(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ - _out7) \ - { \ - __m256i _s0_m, _s1_m; \ - __m256i _tmp0_m, _tmp1_m, _tmp2_m, _tmp3_m; \ - __m256i _tmp4_m, _tmp5_m, _tmp6_m, _tmp7_m; \ - \ - _s0_m = __lasx_xvilvl_w(_in2, _in0); \ - _s1_m = __lasx_xvilvl_w(_in3, _in1); \ - _tmp0_m = __lasx_xvilvl_w(_s1_m, _s0_m); \ - _tmp1_m = __lasx_xvilvh_w(_s1_m, _s0_m); \ - _s0_m = __lasx_xvilvh_w(_in2, _in0); \ - _s1_m = __lasx_xvilvh_w(_in3, _in1); \ - _tmp2_m = __lasx_xvilvl_w(_s1_m, _s0_m); \ - _tmp3_m = __lasx_xvilvh_w(_s1_m, _s0_m); \ - _s0_m = __lasx_xvilvl_w(_in6, _in4); \ - _s1_m = __lasx_xvilvl_w(_in7, _in5); \ - _tmp4_m = __lasx_xvilvl_w(_s1_m, _s0_m); \ - _tmp5_m = __lasx_xvilvh_w(_s1_m, _s0_m); \ - _s0_m = __lasx_xvilvh_w(_in6, _in4); \ - _s1_m = __lasx_xvilvh_w(_in7, _in5); \ - _tmp6_m = __lasx_xvilvl_w(_s1_m, _s0_m); \ - _tmp7_m = __lasx_xvilvh_w(_s1_m, _s0_m); \ - _out0 = __lasx_xvpermi_q(_tmp4_m, _tmp0_m, 0x20); \ - _out1 = __lasx_xvpermi_q(_tmp5_m, _tmp1_m, 0x20); \ - _out2 = __lasx_xvpermi_q(_tmp6_m, _tmp2_m, 0x20); \ - _out3 = __lasx_xvpermi_q(_tmp7_m, _tmp3_m, 0x20); \ - _out4 = __lasx_xvpermi_q(_tmp4_m, _tmp0_m, 0x31); \ - _out5 = __lasx_xvpermi_q(_tmp5_m, _tmp1_m, 0x31); \ - _out6 = __lasx_xvpermi_q(_tmp6_m, _tmp2_m, 0x31); \ - _out7 = __lasx_xvpermi_q(_tmp7_m, _tmp3_m, 0x31); \ - } - -/* - * ============================================================================= - * Description : Transpose input 16x8 byte block - * Arguments : Inputs - _in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, - * _in8, _in9, _in10, _in11, _in12, _in13, _in14, _in15 - * (input 16x8 byte block) - * Outputs - _out0, _out1, _out2, _out3, _out4, _out5, _out6, - * _out7 (output 8x16 byte block) - * Details : The rows of the matrix become columns, and the columns become - * rows. - * Example : See LASX_TRANSPOSE16x8_H - * ============================================================================= - */ -#define LASX_TRANSPOSE16x8_B(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _in8, _in9, _in10, _in11, _in12, _in13, _in14, \ - _in15, _out0, _out1, _out2, _out3, _out4, _out5, \ - _out6, _out7) \ - { \ - __m256i _tmp0_m, _tmp1_m, _tmp2_m, _tmp3_m; \ - __m256i _tmp4_m, _tmp5_m, _tmp6_m, _tmp7_m; \ - \ - _tmp0_m = __lasx_xvilvl_b(_in2, _in0); \ - _tmp1_m = __lasx_xvilvl_b(_in3, _in1); \ - _tmp2_m = __lasx_xvilvl_b(_in6, _in4); \ - _tmp3_m = __lasx_xvilvl_b(_in7, _in5); \ - _tmp4_m = __lasx_xvilvl_b(_in10, _in8); \ - _tmp5_m = __lasx_xvilvl_b(_in11, _in9); \ - _tmp6_m = __lasx_xvilvl_b(_in14, _in12); \ - _tmp7_m = __lasx_xvilvl_b(_in15, _in13); \ - _out0 = __lasx_xvilvl_b(_tmp1_m, _tmp0_m); \ - _out1 = __lasx_xvilvh_b(_tmp1_m, _tmp0_m); \ - _out2 = __lasx_xvilvl_b(_tmp3_m, _tmp2_m); \ - _out3 = __lasx_xvilvh_b(_tmp3_m, _tmp2_m); \ - _out4 = __lasx_xvilvl_b(_tmp5_m, _tmp4_m); \ - _out5 = __lasx_xvilvh_b(_tmp5_m, _tmp4_m); \ - _out6 = __lasx_xvilvl_b(_tmp7_m, _tmp6_m); \ - _out7 = __lasx_xvilvh_b(_tmp7_m, _tmp6_m); \ - _tmp0_m = __lasx_xvilvl_w(_out2, _out0); \ - _tmp2_m = __lasx_xvilvh_w(_out2, _out0); \ - _tmp4_m = __lasx_xvilvl_w(_out3, _out1); \ - _tmp6_m = __lasx_xvilvh_w(_out3, _out1); \ - _tmp1_m = __lasx_xvilvl_w(_out6, _out4); \ - _tmp3_m = __lasx_xvilvh_w(_out6, _out4); \ - _tmp5_m = __lasx_xvilvl_w(_out7, _out5); \ - _tmp7_m = __lasx_xvilvh_w(_out7, _out5); \ - _out0 = __lasx_xvilvl_d(_tmp1_m, _tmp0_m); \ - _out1 = __lasx_xvilvh_d(_tmp1_m, _tmp0_m); \ - _out2 = __lasx_xvilvl_d(_tmp3_m, _tmp2_m); \ - _out3 = __lasx_xvilvh_d(_tmp3_m, _tmp2_m); \ - _out4 = __lasx_xvilvl_d(_tmp5_m, _tmp4_m); \ - _out5 = __lasx_xvilvh_d(_tmp5_m, _tmp4_m); \ - _out6 = __lasx_xvilvl_d(_tmp7_m, _tmp6_m); \ - _out7 = __lasx_xvilvh_d(_tmp7_m, _tmp6_m); \ - } - -/* - * ============================================================================= - * Description : Transpose input 16x8 byte block - * Arguments : Inputs - _in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, - * _in8, _in9, _in10, _in11, _in12, _in13, _in14, _in15 - * (input 16x8 byte block) - * Outputs - _out0, _out1, _out2, _out3, _out4, _out5, _out6, - * _out7 (output 8x16 byte block) - * Details : The rows of the matrix become columns, and the columns become - * rows. - * Example : LASX_TRANSPOSE16x8_H - * _in0 : 1,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 - * _in1 : 2,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 - * _in2 : 3,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 - * _in3 : 4,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 - * _in4 : 5,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 - * _in5 : 6,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 - * _in6 : 7,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 - * _in7 : 8,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 - * _in8 : 9,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 - * _in9 : 1,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 - * _in10 : 0,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 - * _in11 : 2,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 - * _in12 : 3,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 - * _in13 : 7,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 - * _in14 : 5,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 - * _in15 : 6,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0 - * - * _out0 : 1,2,3,4,5,6,7,8,9,1,0,2,3,7,5,6 - * _out1 : 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 - * _out2 : 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 - * _out3 : 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 - * _out4 : 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 - * _out5 : 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6 - * _out6 : 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 - * _out7 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 - * ============================================================================= - */ -#define LASX_TRANSPOSE16x8_H(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _in8, _in9, _in10, _in11, _in12, _in13, _in14, \ - _in15, _out0, _out1, _out2, _out3, _out4, _out5, \ - _out6, _out7) \ - { \ - __m256i _tmp0_m, _tmp1_m, _tmp2_m, _tmp3_m; \ - __m256i _tmp4_m, _tmp5_m, _tmp6_m, _tmp7_m; \ - __m256i _t0, _t1, _t2, _t3, _t4, _t5, _t6, _t7; \ - \ - _tmp0_m = __lasx_xvilvl_h(_in2, _in0); \ - _tmp1_m = __lasx_xvilvl_h(_in3, _in1); \ - _tmp2_m = __lasx_xvilvl_h(_in6, _in4); \ - _tmp3_m = __lasx_xvilvl_h(_in7, _in5); \ - _tmp4_m = __lasx_xvilvl_h(_in10, _in8); \ - _tmp5_m = __lasx_xvilvl_h(_in11, _in9); \ - _tmp6_m = __lasx_xvilvl_h(_in14, _in12); \ - _tmp7_m = __lasx_xvilvl_h(_in15, _in13); \ - _t0 = __lasx_xvilvl_h(_tmp1_m, _tmp0_m); \ - _t1 = __lasx_xvilvh_h(_tmp1_m, _tmp0_m); \ - _t2 = __lasx_xvilvl_h(_tmp3_m, _tmp2_m); \ - _t3 = __lasx_xvilvh_h(_tmp3_m, _tmp2_m); \ - _t4 = __lasx_xvilvl_h(_tmp5_m, _tmp4_m); \ - _t5 = __lasx_xvilvh_h(_tmp5_m, _tmp4_m); \ - _t6 = __lasx_xvilvl_h(_tmp7_m, _tmp6_m); \ - _t7 = __lasx_xvilvh_h(_tmp7_m, _tmp6_m); \ - _tmp0_m = __lasx_xvilvl_d(_t2, _t0); \ - _tmp2_m = __lasx_xvilvh_d(_t2, _t0); \ - _tmp4_m = __lasx_xvilvl_d(_t3, _t1); \ - _tmp6_m = __lasx_xvilvh_d(_t3, _t1); \ - _tmp1_m = __lasx_xvilvl_d(_t6, _t4); \ - _tmp3_m = __lasx_xvilvh_d(_t6, _t4); \ - _tmp5_m = __lasx_xvilvl_d(_t7, _t5); \ - _tmp7_m = __lasx_xvilvh_d(_t7, _t5); \ - _out0 = __lasx_xvpermi_q(_tmp1_m, _tmp0_m, 0x20); \ - _out1 = __lasx_xvpermi_q(_tmp3_m, _tmp2_m, 0x20); \ - _out2 = __lasx_xvpermi_q(_tmp5_m, _tmp4_m, 0x20); \ - _out3 = __lasx_xvpermi_q(_tmp7_m, _tmp6_m, 0x20); \ - \ - _tmp0_m = __lasx_xvilvh_h(_in2, _in0); \ - _tmp1_m = __lasx_xvilvh_h(_in3, _in1); \ - _tmp2_m = __lasx_xvilvh_h(_in6, _in4); \ - _tmp3_m = __lasx_xvilvh_h(_in7, _in5); \ - _tmp4_m = __lasx_xvilvh_h(_in10, _in8); \ - _tmp5_m = __lasx_xvilvh_h(_in11, _in9); \ - _tmp6_m = __lasx_xvilvh_h(_in14, _in12); \ - _tmp7_m = __lasx_xvilvh_h(_in15, _in13); \ - _t0 = __lasx_xvilvl_h(_tmp1_m, _tmp0_m); \ - _t1 = __lasx_xvilvh_h(_tmp1_m, _tmp0_m); \ - _t2 = __lasx_xvilvl_h(_tmp3_m, _tmp2_m); \ - _t3 = __lasx_xvilvh_h(_tmp3_m, _tmp2_m); \ - _t4 = __lasx_xvilvl_h(_tmp5_m, _tmp4_m); \ - _t5 = __lasx_xvilvh_h(_tmp5_m, _tmp4_m); \ - _t6 = __lasx_xvilvl_h(_tmp7_m, _tmp6_m); \ - _t7 = __lasx_xvilvh_h(_tmp7_m, _tmp6_m); \ - _tmp0_m = __lasx_xvilvl_d(_t2, _t0); \ - _tmp2_m = __lasx_xvilvh_d(_t2, _t0); \ - _tmp4_m = __lasx_xvilvl_d(_t3, _t1); \ - _tmp6_m = __lasx_xvilvh_d(_t3, _t1); \ - _tmp1_m = __lasx_xvilvl_d(_t6, _t4); \ - _tmp3_m = __lasx_xvilvh_d(_t6, _t4); \ - _tmp5_m = __lasx_xvilvl_d(_t7, _t5); \ - _tmp7_m = __lasx_xvilvh_d(_t7, _t5); \ - _out4 = __lasx_xvpermi_q(_tmp1_m, _tmp0_m, 0x20); \ - _out5 = __lasx_xvpermi_q(_tmp3_m, _tmp2_m, 0x20); \ - _out6 = __lasx_xvpermi_q(_tmp5_m, _tmp4_m, 0x20); \ - _out7 = __lasx_xvpermi_q(_tmp7_m, _tmp6_m, 0x20); \ - } - -/* - * ============================================================================= - * Description : Transpose 4x4 block with halfword elements in vectors - * Arguments : Inputs - _in0, _in1, _in2, _in3 - * Outputs - _out0, _out1, _out2, _out3 - * Return Type - signed halfword - * Details : The rows of the matrix become columns, and the columns become - * rows. - * Example : See LASX_TRANSPOSE8x8_H - * ============================================================================= - */ -#define LASX_TRANSPOSE4x4_H(_in0, _in1, _in2, _in3, _out0, _out1, _out2, \ - _out3) \ - { \ - __m256i _s0_m, _s1_m; \ - \ - _s0_m = __lasx_xvilvl_h(_in1, _in0); \ - _s1_m = __lasx_xvilvl_h(_in3, _in2); \ - _out0 = __lasx_xvilvl_w(_s1_m, _s0_m); \ - _out2 = __lasx_xvilvh_w(_s1_m, _s0_m); \ - _out1 = __lasx_xvilvh_d(_out0, _out0); \ - _out3 = __lasx_xvilvh_d(_out2, _out2); \ - } - -/* - * ============================================================================= - * Description : Transpose input 8x8 byte block - * Arguments : Inputs - _in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7 - * (input 8x8 byte block) - * Outputs - _out0, _out1, _out2, _out3, _out4, _out5, _out6, - * _out7 (output 8x8 byte block) - * Example : See LASX_TRANSPOSE8x8_H - * ============================================================================= - */ -#define LASX_TRANSPOSE8x8_B(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ - _out7) \ - { \ - __m256i _tmp0_m, _tmp1_m, _tmp2_m, _tmp3_m; \ - __m256i _tmp4_m, _tmp5_m, _tmp6_m, _tmp7_m; \ - _tmp0_m = __lasx_xvilvl_b(_in2, _in0); \ - _tmp1_m = __lasx_xvilvl_b(_in3, _in1); \ - _tmp2_m = __lasx_xvilvl_b(_in6, _in4); \ - _tmp3_m = __lasx_xvilvl_b(_in7, _in5); \ - _tmp4_m = __lasx_xvilvl_b(_tmp1_m, _tmp0_m); \ - _tmp5_m = __lasx_xvilvh_b(_tmp1_m, _tmp0_m); \ - _tmp6_m = __lasx_xvilvl_b(_tmp3_m, _tmp2_m); \ - _tmp7_m = __lasx_xvilvh_b(_tmp3_m, _tmp2_m); \ - _out0 = __lasx_xvilvl_w(_tmp6_m, _tmp4_m); \ - _out2 = __lasx_xvilvh_w(_tmp6_m, _tmp4_m); \ - _out4 = __lasx_xvilvl_w(_tmp7_m, _tmp5_m); \ - _out6 = __lasx_xvilvh_w(_tmp7_m, _tmp5_m); \ - _out1 = __lasx_xvbsrl_v(_out0, 8); \ - _out3 = __lasx_xvbsrl_v(_out2, 8); \ - _out5 = __lasx_xvbsrl_v(_out4, 8); \ - _out7 = __lasx_xvbsrl_v(_out6, 8); \ - } - -/* - * ============================================================================= - * Description : Transpose 8x8 block with halfword elements in vectors. - * Arguments : Inputs - _in0, _in1, ~ - * Outputs - _out0, _out1, ~ - * Details : The rows of the matrix become columns, and the columns become - * rows. - * Example : LASX_TRANSPOSE8x8_H - * _in0 : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 - * _in1 : 8,2,3,4, 5,6,7,8, 8,2,3,4, 5,6,7,8 - * _in2 : 8,2,3,4, 5,6,7,8, 8,2,3,4, 5,6,7,8 - * _in3 : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 - * _in4 : 9,2,3,4, 5,6,7,8, 9,2,3,4, 5,6,7,8 - * _in5 : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 - * _in6 : 1,2,3,4, 5,6,7,8, 1,2,3,4, 5,6,7,8 - * _in7 : 9,2,3,4, 5,6,7,8, 9,2,3,4, 5,6,7,8 - * - * _out0 : 1,8,8,1, 9,1,1,9, 1,8,8,1, 9,1,1,9 - * _out1 : 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2 - * _out2 : 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3 - * _out3 : 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4 - * _out4 : 5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5 - * _out5 : 6,6,6,6, 6,6,6,6, 6,6,6,6, 6,6,6,6 - * _out6 : 7,7,7,7, 7,7,7,7, 7,7,7,7, 7,7,7,7 - * _out7 : 8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8 - * ============================================================================= - */ -#define LASX_TRANSPOSE8x8_H(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ - _out7) \ - { \ - __m256i _s0_m, _s1_m; \ - __m256i _tmp0_m, _tmp1_m, _tmp2_m, _tmp3_m; \ - __m256i _tmp4_m, _tmp5_m, _tmp6_m, _tmp7_m; \ - \ - _s0_m = __lasx_xvilvl_h(_in6, _in4); \ - _s1_m = __lasx_xvilvl_h(_in7, _in5); \ - _tmp0_m = __lasx_xvilvl_h(_s1_m, _s0_m); \ - _tmp1_m = __lasx_xvilvh_h(_s1_m, _s0_m); \ - _s0_m = __lasx_xvilvh_h(_in6, _in4); \ - _s1_m = __lasx_xvilvh_h(_in7, _in5); \ - _tmp2_m = __lasx_xvilvl_h(_s1_m, _s0_m); \ - _tmp3_m = __lasx_xvilvh_h(_s1_m, _s0_m); \ - \ - _s0_m = __lasx_xvilvl_h(_in2, _in0); \ - _s1_m = __lasx_xvilvl_h(_in3, _in1); \ - _tmp4_m = __lasx_xvilvl_h(_s1_m, _s0_m); \ - _tmp5_m = __lasx_xvilvh_h(_s1_m, _s0_m); \ - _s0_m = __lasx_xvilvh_h(_in2, _in0); \ - _s1_m = __lasx_xvilvh_h(_in3, _in1); \ - _tmp6_m = __lasx_xvilvl_h(_s1_m, _s0_m); \ - _tmp7_m = __lasx_xvilvh_h(_s1_m, _s0_m); \ - \ - _out0 = __lasx_xvpickev_d(_tmp0_m, _tmp4_m); \ - _out2 = __lasx_xvpickev_d(_tmp1_m, _tmp5_m); \ - _out4 = __lasx_xvpickev_d(_tmp2_m, _tmp6_m); \ - _out6 = __lasx_xvpickev_d(_tmp3_m, _tmp7_m); \ - _out1 = __lasx_xvpickod_d(_tmp0_m, _tmp4_m); \ - _out3 = __lasx_xvpickod_d(_tmp1_m, _tmp5_m); \ - _out5 = __lasx_xvpickod_d(_tmp2_m, _tmp6_m); \ - _out7 = __lasx_xvpickod_d(_tmp3_m, _tmp7_m); \ - } - -/* - * ============================================================================= - * Description : Butterfly of 4 input vectors - * Arguments : Inputs - _in0, _in1, _in2, _in3 - * Outputs - _out0, _out1, _out2, _out3 - * Details : Butterfly operation - * Example : LASX_BUTTERFLY_4 - * _out0 = _in0 + _in3; - * _out1 = _in1 + _in2; - * _out2 = _in1 - _in2; - * _out3 = _in0 - _in3; - * ============================================================================= - */ -#define LASX_BUTTERFLY_4_B(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ - { \ - _out0 = __lasx_xvadd_b(_in0, _in3); \ - _out1 = __lasx_xvadd_b(_in1, _in2); \ - _out2 = __lasx_xvsub_b(_in1, _in2); \ - _out3 = __lasx_xvsub_b(_in0, _in3); \ - } -#define LASX_BUTTERFLY_4_H(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ - { \ - _out0 = __lasx_xvadd_h(_in0, _in3); \ - _out1 = __lasx_xvadd_h(_in1, _in2); \ - _out2 = __lasx_xvsub_h(_in1, _in2); \ - _out3 = __lasx_xvsub_h(_in0, _in3); \ - } -#define LASX_BUTTERFLY_4_W(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ - { \ - _out0 = __lasx_xvadd_w(_in0, _in3); \ - _out1 = __lasx_xvadd_w(_in1, _in2); \ - _out2 = __lasx_xvsub_w(_in1, _in2); \ - _out3 = __lasx_xvsub_w(_in0, _in3); \ - } -#define LASX_BUTTERFLY_4_D(_in0, _in1, _in2, _in3, _out0, _out1, _out2, _out3) \ - { \ - _out0 = __lasx_xvadd_d(_in0, _in3); \ - _out1 = __lasx_xvadd_d(_in1, _in2); \ - _out2 = __lasx_xvsub_d(_in1, _in2); \ - _out3 = __lasx_xvsub_d(_in0, _in3); \ - } - -/* - * ============================================================================= - * Description : Butterfly of 8 input vectors - * Arguments : Inputs - _in0, _in1, _in2, _in3, ~ - * Outputs - _out0, _out1, _out2, _out3, ~ - * Details : Butterfly operation - * Example : LASX_BUTTERFLY_8 - * _out0 = _in0 + _in7; - * _out1 = _in1 + _in6; - * _out2 = _in2 + _in5; - * _out3 = _in3 + _in4; - * _out4 = _in3 - _in4; - * _out5 = _in2 - _in5; - * _out6 = _in1 - _in6; - * _out7 = _in0 - _in7; - * ============================================================================= - */ -#define LASX_BUTTERFLY_8_B(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ - _out7) \ - { \ - _out0 = __lasx_xvadd_b(_in0, _in7); \ - _out1 = __lasx_xvadd_b(_in1, _in6); \ - _out2 = __lasx_xvadd_b(_in2, _in5); \ - _out3 = __lasx_xvadd_b(_in3, _in4); \ - _out4 = __lasx_xvsub_b(_in3, _in4); \ - _out5 = __lasx_xvsub_b(_in2, _in5); \ - _out6 = __lasx_xvsub_b(_in1, _in6); \ - _out7 = __lasx_xvsub_b(_in0, _in7); \ - } - -#define LASX_BUTTERFLY_8_H(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ - _out7) \ - { \ - _out0 = __lasx_xvadd_h(_in0, _in7); \ - _out1 = __lasx_xvadd_h(_in1, _in6); \ - _out2 = __lasx_xvadd_h(_in2, _in5); \ - _out3 = __lasx_xvadd_h(_in3, _in4); \ - _out4 = __lasx_xvsub_h(_in3, _in4); \ - _out5 = __lasx_xvsub_h(_in2, _in5); \ - _out6 = __lasx_xvsub_h(_in1, _in6); \ - _out7 = __lasx_xvsub_h(_in0, _in7); \ - } - -#define LASX_BUTTERFLY_8_W(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ - _out7) \ - { \ - _out0 = __lasx_xvadd_w(_in0, _in7); \ - _out1 = __lasx_xvadd_w(_in1, _in6); \ - _out2 = __lasx_xvadd_w(_in2, _in5); \ - _out3 = __lasx_xvadd_w(_in3, _in4); \ - _out4 = __lasx_xvsub_w(_in3, _in4); \ - _out5 = __lasx_xvsub_w(_in2, _in5); \ - _out6 = __lasx_xvsub_w(_in1, _in6); \ - _out7 = __lasx_xvsub_w(_in0, _in7); \ - } - -#define LASX_BUTTERFLY_8_D(_in0, _in1, _in2, _in3, _in4, _in5, _in6, _in7, \ - _out0, _out1, _out2, _out3, _out4, _out5, _out6, \ - _out7) \ - { \ - _out0 = __lasx_xvadd_d(_in0, _in7); \ - _out1 = __lasx_xvadd_d(_in1, _in6); \ - _out2 = __lasx_xvadd_d(_in2, _in5); \ - _out3 = __lasx_xvadd_d(_in3, _in4); \ - _out4 = __lasx_xvsub_d(_in3, _in4); \ - _out5 = __lasx_xvsub_d(_in2, _in5); \ - _out6 = __lasx_xvsub_d(_in1, _in6); \ - _out7 = __lasx_xvsub_d(_in0, _in7); \ - } - -#endif // LASX - -/* - * ============================================================================= - * Description : Print out elements in vector. - * Arguments : Inputs - RTYPE, _element_num, _in0, _enter - * Outputs - - * Details : Print out '_element_num' elements in 'RTYPE' vector '_in0', if - * '_enter' is TRUE, prefix "\nVP:" will be added first. - * Example : VECT_PRINT(v4i32,4,in0,1); // in0: 1,2,3,4 - * VP:1,2,3,4, - * ============================================================================= - */ -#define VECT_PRINT(RTYPE, element_num, in0, enter) \ - { \ - RTYPE _tmp0 = (RTYPE)in0; \ - int _i = 0; \ - if (enter) printf("\nVP:"); \ - for (_i = 0; _i < element_num; _i++) printf("%d,", _tmp0[_i]); \ - } - -#endif /* LOONGSON_INTRINSICS_H */ -#endif /* VPX_VPX_UTIL_LOONGSON_INTRINSICS_H_ */ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_atomics.h b/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_atomics.h deleted file mode 100644 index 23ad5668..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_atomics.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2017 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_UTIL_VPX_ATOMICS_H_ -#define VPX_VPX_UTIL_VPX_ATOMICS_H_ - -#include "./vpx_config.h" - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#if CONFIG_OS_SUPPORT && CONFIG_MULTITHREAD - -// Look for built-in atomic support. We cannot use or -// since neither is guaranteed to exist on both C and C++ platforms, and we need -// to back the atomic type with the same type (g++ needs to be able to use -// gcc-built code). g++ 6 doesn't support _Atomic as a keyword and can't use the -// stdatomic.h header. Even if both and existed it's not -// guaranteed that atomic_int is the same type as std::atomic_int. -// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60932#c13. -#if !defined(__has_builtin) -#define __has_builtin(x) 0 // Compatibility with non-clang compilers. -#endif // !defined(__has_builtin) - -#if (__has_builtin(__atomic_load_n)) || \ - (defined(__GNUC__) && \ - (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))) -// For GCC >= 4.7 and Clang versions that support __atomic builtins, use those. -#define VPX_USE_ATOMIC_BUILTINS -#else -// Use platform-specific asm barriers. -#if defined(_MSC_VER) -// TODO(pbos): This assumes that newer versions of MSVC are building with the -// default /volatile:ms (or older, where this is always true. Consider adding -// support for using instead of stdatomic.h when building C++11 under -// MSVC. It's unclear what to do for plain C under /volatile:iso (inline asm?), -// there're no explicit Interlocked* functions for only storing or loading -// (presumably because volatile has historically implied that on MSVC). -// -// For earlier versions of MSVC or the default /volatile:ms volatile int are -// acquire/release and require no barrier. -#define vpx_atomic_memory_barrier() \ - do { \ - } while (0) -#else -#if VPX_ARCH_X86 || VPX_ARCH_X86_64 -// Use a compiler barrier on x86, no runtime penalty. -#define vpx_atomic_memory_barrier() __asm__ __volatile__("" ::: "memory") -#elif VPX_ARCH_ARM -#define vpx_atomic_memory_barrier() __asm__ __volatile__("dmb ish" ::: "memory") -#elif VPX_ARCH_MIPS -#define vpx_atomic_memory_barrier() __asm__ __volatile__("sync" ::: "memory") -#else -#error Unsupported architecture! -#endif // VPX_ARCH_X86 || VPX_ARCH_X86_64 -#endif // defined(_MSC_VER) -#endif // atomic builtin availability check - -// These are wrapped in a struct so that they are not easily accessed directly -// on any platform (to discourage programmer errors by setting values directly). -// This primitive MUST be initialized using vpx_atomic_init or VPX_ATOMIC_INIT -// (NOT memset) and accessed through vpx_atomic_ functions. -typedef struct vpx_atomic_int { - volatile int value; -} vpx_atomic_int; - -#define VPX_ATOMIC_INIT(num) \ - { num } - -// Initialization of an atomic int, not thread safe. -static INLINE void vpx_atomic_init(vpx_atomic_int *atomic, int value) { - atomic->value = value; -} - -static INLINE void vpx_atomic_store_release(vpx_atomic_int *atomic, int value) { -#if defined(VPX_USE_ATOMIC_BUILTINS) - __atomic_store_n(&atomic->value, value, __ATOMIC_RELEASE); -#else - vpx_atomic_memory_barrier(); - atomic->value = value; -#endif // defined(VPX_USE_ATOMIC_BUILTINS) -} - -static INLINE int vpx_atomic_load_acquire(const vpx_atomic_int *atomic) { -#if defined(VPX_USE_ATOMIC_BUILTINS) - return __atomic_load_n(&atomic->value, __ATOMIC_ACQUIRE); -#else - int v = atomic->value; - vpx_atomic_memory_barrier(); - return v; -#endif // defined(VPX_USE_ATOMIC_BUILTINS) -} - -#undef VPX_USE_ATOMIC_BUILTINS -#undef vpx_atomic_memory_barrier - -#endif /* CONFIG_OS_SUPPORT && CONFIG_MULTITHREAD */ - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus - -#endif // VPX_VPX_UTIL_VPX_ATOMICS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_debug_util.c b/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_debug_util.c deleted file mode 100644 index 3ce4065b..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_debug_util.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright (c) 2019 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include "vpx_util/vpx_debug_util.h" - -#if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG -static int frame_idx_w = 0; -static int frame_idx_r = 0; - -void bitstream_queue_set_frame_write(int frame_idx) { frame_idx_w = frame_idx; } - -int bitstream_queue_get_frame_write(void) { return frame_idx_w; } - -void bitstream_queue_set_frame_read(int frame_idx) { frame_idx_r = frame_idx; } - -int bitstream_queue_get_frame_read(void) { return frame_idx_r; } -#endif - -#if CONFIG_BITSTREAM_DEBUG -#define QUEUE_MAX_SIZE 2000000 -static int result_queue[QUEUE_MAX_SIZE]; -static int prob_queue[QUEUE_MAX_SIZE]; - -static int queue_r = 0; -static int queue_w = 0; -static int queue_prev_w = -1; -static int skip_r = 0; -static int skip_w = 0; -void bitstream_queue_set_skip_write(int skip) { skip_w = skip; } - -void bitstream_queue_set_skip_read(int skip) { skip_r = skip; } - -void bitstream_queue_record_write(void) { queue_prev_w = queue_w; } - -void bitstream_queue_reset_write(void) { queue_w = queue_prev_w; } - -int bitstream_queue_get_write(void) { return queue_w; } - -int bitstream_queue_get_read(void) { return queue_r; } - -void bitstream_queue_pop(int *result, int *prob) { - if (!skip_r) { - if (queue_w == queue_r) { - printf("buffer underflow queue_w %d queue_r %d\n", queue_w, queue_r); - assert(0); - } - *result = result_queue[queue_r]; - *prob = prob_queue[queue_r]; - queue_r = (queue_r + 1) % QUEUE_MAX_SIZE; - } -} - -void bitstream_queue_push(int result, const int prob) { - if (!skip_w) { - result_queue[queue_w] = result; - prob_queue[queue_w] = prob; - queue_w = (queue_w + 1) % QUEUE_MAX_SIZE; - if (queue_w == queue_r) { - printf("buffer overflow queue_w %d queue_r %d\n", queue_w, queue_r); - assert(0); - } - } -} -#endif // CONFIG_BITSTREAM_DEBUG - -#if CONFIG_MISMATCH_DEBUG -static int frame_buf_idx_r = 0; -static int frame_buf_idx_w = 0; -#define MAX_FRAME_BUF_NUM 20 -#define MAX_FRAME_STRIDE 1920 -#define MAX_FRAME_HEIGHT 1080 -static uint16_t - frame_pre[MAX_FRAME_BUF_NUM][3] - [MAX_FRAME_STRIDE * MAX_FRAME_HEIGHT]; // prediction only -static uint16_t - frame_tx[MAX_FRAME_BUF_NUM][3] - [MAX_FRAME_STRIDE * MAX_FRAME_HEIGHT]; // prediction + txfm -static int frame_stride = MAX_FRAME_STRIDE; -static int frame_height = MAX_FRAME_HEIGHT; -static int frame_size = MAX_FRAME_STRIDE * MAX_FRAME_HEIGHT; -void mismatch_move_frame_idx_w(void) { - frame_buf_idx_w = (frame_buf_idx_w + 1) % MAX_FRAME_BUF_NUM; - if (frame_buf_idx_w == frame_buf_idx_r) { - printf("frame_buf overflow\n"); - assert(0); - } -} - -void mismatch_reset_frame(int num_planes) { - int plane; - for (plane = 0; plane < num_planes; ++plane) { - memset(frame_pre[frame_buf_idx_w][plane], 0, - sizeof(frame_pre[frame_buf_idx_w][plane][0]) * frame_size); - memset(frame_tx[frame_buf_idx_w][plane], 0, - sizeof(frame_tx[frame_buf_idx_w][plane][0]) * frame_size); - } -} - -void mismatch_move_frame_idx_r(void) { - if (frame_buf_idx_w == frame_buf_idx_r) { - printf("frame_buf underflow\n"); - assert(0); - } - frame_buf_idx_r = (frame_buf_idx_r + 1) % MAX_FRAME_BUF_NUM; -} - -void mismatch_record_block_pre(const uint8_t *src, int src_stride, int plane, - int pixel_c, int pixel_r, int blk_w, int blk_h, - int highbd) { - const uint16_t *src16 = highbd ? CONVERT_TO_SHORTPTR(src) : NULL; - int r, c; - - if (pixel_c + blk_w >= frame_stride || pixel_r + blk_h >= frame_height) { - printf("frame_buf undersized\n"); - assert(0); - } - - for (r = 0; r < blk_h; ++r) { - for (c = 0; c < blk_w; ++c) { - frame_pre[frame_buf_idx_w][plane] - [(r + pixel_r) * frame_stride + c + pixel_c] = - src16 ? src16[r * src_stride + c] : src[r * src_stride + c]; - } - } -#if 0 - { - int ref_frame_idx = 3; - int ref_plane = 1; - int ref_pixel_c = 162; - int ref_pixel_r = 16; - if (frame_idx_w == ref_frame_idx && plane == ref_plane && - ref_pixel_c >= pixel_c && ref_pixel_c < pixel_c + blk_w && - ref_pixel_r >= pixel_r && ref_pixel_r < pixel_r + blk_h) { - printf( - "\nrecord_block_pre frame_idx %d plane %d pixel_c %d pixel_r %d blk_w" - " %d blk_h %d\n", - frame_idx_w, plane, pixel_c, pixel_r, blk_w, blk_h); - } - } -#endif -} -void mismatch_record_block_tx(const uint8_t *src, int src_stride, int plane, - int pixel_c, int pixel_r, int blk_w, int blk_h, - int highbd) { - const uint16_t *src16 = highbd ? CONVERT_TO_SHORTPTR(src) : NULL; - int r, c; - if (pixel_c + blk_w >= frame_stride || pixel_r + blk_h >= frame_height) { - printf("frame_buf undersized\n"); - assert(0); - } - - for (r = 0; r < blk_h; ++r) { - for (c = 0; c < blk_w; ++c) { - frame_tx[frame_buf_idx_w][plane] - [(r + pixel_r) * frame_stride + c + pixel_c] = - src16 ? src16[r * src_stride + c] : src[r * src_stride + c]; - } - } -#if 0 - { - int ref_frame_idx = 3; - int ref_plane = 1; - int ref_pixel_c = 162; - int ref_pixel_r = 16; - if (frame_idx_w == ref_frame_idx && plane == ref_plane && - ref_pixel_c >= pixel_c && ref_pixel_c < pixel_c + blk_w && - ref_pixel_r >= pixel_r && ref_pixel_r < pixel_r + blk_h) { - printf( - "\nrecord_block_tx frame_idx %d plane %d pixel_c %d pixel_r %d blk_w " - "%d blk_h %d\n", - frame_idx_w, plane, pixel_c, pixel_r, blk_w, blk_h); - } - } -#endif -} -void mismatch_check_block_pre(const uint8_t *src, int src_stride, int plane, - int pixel_c, int pixel_r, int blk_w, int blk_h, - int highbd) { - const uint16_t *src16 = highbd ? CONVERT_TO_SHORTPTR(src) : NULL; - int mismatch = 0; - int r, c; - if (pixel_c + blk_w >= frame_stride || pixel_r + blk_h >= frame_height) { - printf("frame_buf undersized\n"); - assert(0); - } - - for (r = 0; r < blk_h; ++r) { - for (c = 0; c < blk_w; ++c) { - if (frame_pre[frame_buf_idx_r][plane] - [(r + pixel_r) * frame_stride + c + pixel_c] != - (uint16_t)(src16 ? src16[r * src_stride + c] - : src[r * src_stride + c])) { - mismatch = 1; - } - } - } - if (mismatch) { - int rr, cc; - printf( - "\ncheck_block_pre failed frame_idx %d plane %d " - "pixel_c %d pixel_r " - "%d blk_w %d blk_h %d\n", - frame_idx_r, plane, pixel_c, pixel_r, blk_w, blk_h); - printf("enc\n"); - for (rr = 0; rr < blk_h; ++rr) { - for (cc = 0; cc < blk_w; ++cc) { - printf("%d ", frame_pre[frame_buf_idx_r][plane] - [(rr + pixel_r) * frame_stride + cc + pixel_c]); - } - printf("\n"); - } - - printf("dec\n"); - for (rr = 0; rr < blk_h; ++rr) { - for (cc = 0; cc < blk_w; ++cc) { - printf("%d ", - src16 ? src16[rr * src_stride + cc] : src[rr * src_stride + cc]); - } - printf("\n"); - } - assert(0); - } -} -void mismatch_check_block_tx(const uint8_t *src, int src_stride, int plane, - int pixel_c, int pixel_r, int blk_w, int blk_h, - int highbd) { - const uint16_t *src16 = highbd ? CONVERT_TO_SHORTPTR(src) : NULL; - int mismatch = 0; - int r, c; - if (pixel_c + blk_w >= frame_stride || pixel_r + blk_h >= frame_height) { - printf("frame_buf undersized\n"); - assert(0); - } - - for (r = 0; r < blk_h; ++r) { - for (c = 0; c < blk_w; ++c) { - if (frame_tx[frame_buf_idx_r][plane] - [(r + pixel_r) * frame_stride + c + pixel_c] != - (uint16_t)(src16 ? src16[r * src_stride + c] - : src[r * src_stride + c])) { - mismatch = 1; - } - } - } - if (mismatch) { - int rr, cc; - printf( - "\ncheck_block_tx failed frame_idx %d plane %d pixel_c " - "%d pixel_r " - "%d blk_w %d blk_h %d\n", - frame_idx_r, plane, pixel_c, pixel_r, blk_w, blk_h); - printf("enc\n"); - for (rr = 0; rr < blk_h; ++rr) { - for (cc = 0; cc < blk_w; ++cc) { - printf("%d ", frame_tx[frame_buf_idx_r][plane] - [(rr + pixel_r) * frame_stride + cc + pixel_c]); - } - printf("\n"); - } - - printf("dec\n"); - for (rr = 0; rr < blk_h; ++rr) { - for (cc = 0; cc < blk_w; ++cc) { - printf("%d ", - src16 ? src16[rr * src_stride + cc] : src[rr * src_stride + cc]); - } - printf("\n"); - } - assert(0); - } -} -#endif // CONFIG_MISMATCH_DEBUG diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_debug_util.h b/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_debug_util.h deleted file mode 100644 index df1a1aab..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_debug_util.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2019 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_UTIL_VPX_DEBUG_UTIL_H_ -#define VPX_VPX_UTIL_VPX_DEBUG_UTIL_H_ - -#include "./vpx_config.h" - -#include "vpx_dsp/prob.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG -void bitstream_queue_set_frame_write(int frame_idx); -int bitstream_queue_get_frame_write(void); -void bitstream_queue_set_frame_read(int frame_idx); -int bitstream_queue_get_frame_read(void); -#endif - -#if CONFIG_BITSTREAM_DEBUG -/* This is a debug tool used to detect bitstream error. On encoder side, it - * pushes each bit and probability into a queue before the bit is written into - * the Arithmetic coder. On decoder side, whenever a bit is read out from the - * Arithmetic coder, it pops out the reference bit and probability from the - * queue as well. If the two results do not match, this debug tool will report - * an error. This tool can be used to pin down the bitstream error precisely. - * By combining gdb's backtrace method, we can detect which module causes the - * bitstream error. */ -int bitstream_queue_get_write(void); -int bitstream_queue_get_read(void); -void bitstream_queue_record_write(void); -void bitstream_queue_reset_write(void); -void bitstream_queue_pop(int *result, int *prob); -void bitstream_queue_push(int result, const int prob); -void bitstream_queue_set_skip_write(int skip); -void bitstream_queue_set_skip_read(int skip); -#endif // CONFIG_BITSTREAM_DEBUG - -#if CONFIG_MISMATCH_DEBUG -void mismatch_move_frame_idx_w(void); -void mismatch_move_frame_idx_r(void); -void mismatch_reset_frame(int num_planes); -void mismatch_record_block_pre(const uint8_t *src, int src_stride, int plane, - int pixel_c, int pixel_r, int blk_w, int blk_h, - int highbd); -void mismatch_record_block_tx(const uint8_t *src, int src_stride, int plane, - int pixel_c, int pixel_r, int blk_w, int blk_h, - int highbd); -void mismatch_check_block_pre(const uint8_t *src, int src_stride, int plane, - int pixel_c, int pixel_r, int blk_w, int blk_h, - int highbd); -void mismatch_check_block_tx(const uint8_t *src, int src_stride, int plane, - int pixel_c, int pixel_r, int blk_w, int blk_h, - int highbd); -#endif // CONFIG_MISMATCH_DEBUG - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_UTIL_VPX_DEBUG_UTIL_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_pthread.h b/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_pthread.h deleted file mode 100644 index cdd18d0f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_pthread.h +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2024 Google Inc. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -// ----------------------------------------------------------------------------- -// -// pthread.h wrapper - -#ifndef VPX_VPX_UTIL_VPX_PTHREAD_H_ -#define VPX_VPX_UTIL_VPX_PTHREAD_H_ - -#include "./vpx_config.h" - -#if CONFIG_MULTITHREAD - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(_WIN32) && !HAVE_PTHREAD_H -// Prevent leaking max/min macros. -#undef NOMINMAX -#define NOMINMAX -#undef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#include // NOLINT -#include // NOLINT -#include // NOLINT -#include // NOLINT -typedef HANDLE pthread_t; -typedef CRITICAL_SECTION pthread_mutex_t; - -#if _WIN32_WINNT < 0x0600 -#error _WIN32_WINNT must target Windows Vista / Server 2008 or newer. -#endif -typedef CONDITION_VARIABLE pthread_cond_t; - -#ifndef WINAPI_FAMILY_PARTITION -#define WINAPI_PARTITION_DESKTOP 1 -#define WINAPI_FAMILY_PARTITION(x) x -#endif - -#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) -#define USE_CREATE_THREAD -#endif - -//------------------------------------------------------------------------------ -// simplistic pthread emulation layer - -// _beginthreadex requires __stdcall -#if defined(__GNUC__) && \ - (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) -#define THREADFN __attribute__((force_align_arg_pointer)) unsigned int __stdcall -#else -#define THREADFN unsigned int __stdcall -#endif -#define THREAD_EXIT_SUCCESS 0 - -static INLINE int pthread_create(pthread_t *const thread, const void *attr, - unsigned int(__stdcall *start)(void *), - void *arg) { - (void)attr; -#ifdef USE_CREATE_THREAD - *thread = CreateThread(NULL, /* lpThreadAttributes */ - 0, /* dwStackSize */ - start, arg, 0, /* dwStackSize */ - NULL); /* lpThreadId */ -#else - *thread = (pthread_t)_beginthreadex(NULL, /* void *security */ - 0, /* unsigned stack_size */ - start, arg, 0, /* unsigned initflag */ - NULL); /* unsigned *thrdaddr */ -#endif - if (*thread == NULL) return 1; - SetThreadPriority(*thread, THREAD_PRIORITY_ABOVE_NORMAL); - return 0; -} - -static INLINE int pthread_join(pthread_t thread, void **value_ptr) { - (void)value_ptr; - return (WaitForSingleObjectEx(thread, INFINITE, FALSE /*bAlertable*/) != - WAIT_OBJECT_0 || - CloseHandle(thread) == 0); -} - -// Mutex -static INLINE int pthread_mutex_init(pthread_mutex_t *const mutex, - void *mutexattr) { - (void)mutexattr; - InitializeCriticalSectionEx(mutex, 0 /*dwSpinCount*/, 0 /*Flags*/); - return 0; -} - -static INLINE int pthread_mutex_trylock(pthread_mutex_t *const mutex) { - return TryEnterCriticalSection(mutex) ? 0 : EBUSY; -} - -static INLINE int pthread_mutex_lock(pthread_mutex_t *const mutex) { - EnterCriticalSection(mutex); - return 0; -} - -static INLINE int pthread_mutex_unlock(pthread_mutex_t *const mutex) { - LeaveCriticalSection(mutex); - return 0; -} - -static INLINE int pthread_mutex_destroy(pthread_mutex_t *const mutex) { - DeleteCriticalSection(mutex); - return 0; -} - -// Condition -static INLINE int pthread_cond_destroy(pthread_cond_t *const condition) { - (void)condition; - return 0; -} - -static INLINE int pthread_cond_init(pthread_cond_t *const condition, - void *cond_attr) { - (void)cond_attr; - InitializeConditionVariable(condition); - return 0; -} - -static INLINE int pthread_cond_signal(pthread_cond_t *const condition) { - WakeConditionVariable(condition); - return 0; -} - -static INLINE int pthread_cond_broadcast(pthread_cond_t *const condition) { - WakeAllConditionVariable(condition); - return 0; -} - -static INLINE int pthread_cond_wait(pthread_cond_t *const condition, - pthread_mutex_t *const mutex) { - int ok; - ok = SleepConditionVariableCS(condition, mutex, INFINITE); - return !ok; -} -#else // _WIN32 -#include // NOLINT -#define THREADFN void * -#define THREAD_EXIT_SUCCESS NULL -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // CONFIG_MULTITHREAD - -#endif // VPX_VPX_UTIL_VPX_PTHREAD_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_thread.c b/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_thread.c deleted file mode 100644 index 0d0e2f57..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_thread.c +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -// ----------------------------------------------------------------------------- -// -// Multi-threaded worker -// -// Original source: -// https://chromium.googlesource.com/webm/libwebp - -// Enable GNU extensions in glibc so that we can call pthread_setname_np(). -// This must be before any #include statements. -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include -#include // for memset() -#include "./vpx_config.h" -#include "./vpx_thread.h" -#include "vpx_mem/vpx_mem.h" -#include "vpx_util/vpx_pthread.h" - -#if CONFIG_MULTITHREAD - -struct VPxWorkerImpl { - pthread_mutex_t mutex_; - pthread_cond_t condition_; - pthread_t thread_; -}; - -//------------------------------------------------------------------------------ - -static void execute(VPxWorker *const worker); // Forward declaration. - -static THREADFN thread_loop(void *ptr) { - VPxWorker *const worker = (VPxWorker *)ptr; -#ifdef __APPLE__ - if (worker->thread_name != NULL) { - // Apple's version of pthread_setname_np takes one argument and operates on - // the current thread only. The maximum size of the thread_name buffer was - // noted in the Chromium source code and was confirmed by experiments. If - // thread_name is too long, pthread_setname_np returns -1 with errno - // ENAMETOOLONG (63). - char thread_name[64]; - strncpy(thread_name, worker->thread_name, sizeof(thread_name) - 1); - thread_name[sizeof(thread_name) - 1] = '\0'; - pthread_setname_np(thread_name); - } -#elif (defined(__GLIBC__) && !defined(__GNU__)) || defined(__BIONIC__) - if (worker->thread_name != NULL) { - // Linux and Android require names (with nul) fit in 16 chars, otherwise - // pthread_setname_np() returns ERANGE (34). - char thread_name[16]; - strncpy(thread_name, worker->thread_name, sizeof(thread_name) - 1); - thread_name[sizeof(thread_name) - 1] = '\0'; - pthread_setname_np(pthread_self(), thread_name); - } -#endif - pthread_mutex_lock(&worker->impl_->mutex_); - for (;;) { - while (worker->status_ == VPX_WORKER_STATUS_OK) { // wait in idling mode - pthread_cond_wait(&worker->impl_->condition_, &worker->impl_->mutex_); - } - if (worker->status_ == VPX_WORKER_STATUS_WORKING) { - // When worker->status_ is VPX_WORKER_STATUS_WORKING, the main thread - // doesn't change worker->status_ and will wait until the worker changes - // worker->status_ to VPX_WORKER_STATUS_OK. See change_state(). So the - // worker can safely call execute() without holding worker->impl_->mutex_. - // When the worker reacquires worker->impl_->mutex_, worker->status_ must - // still be VPX_WORKER_STATUS_WORKING. - pthread_mutex_unlock(&worker->impl_->mutex_); - execute(worker); - pthread_mutex_lock(&worker->impl_->mutex_); - assert(worker->status_ == VPX_WORKER_STATUS_WORKING); - worker->status_ = VPX_WORKER_STATUS_OK; - // signal to the main thread that we're done (for sync()) - pthread_cond_signal(&worker->impl_->condition_); - } else { - assert(worker->status_ == VPX_WORKER_STATUS_NOT_OK); // finish the worker - break; - } - } - pthread_mutex_unlock(&worker->impl_->mutex_); - return THREAD_EXIT_SUCCESS; // Thread is finished -} - -// main thread state control -static void change_state(VPxWorker *const worker, VPxWorkerStatus new_status) { - // No-op when attempting to change state on a thread that didn't come up. - // Checking status_ without acquiring the lock first would result in a data - // race. - if (worker->impl_ == NULL) return; - - pthread_mutex_lock(&worker->impl_->mutex_); - if (worker->status_ >= VPX_WORKER_STATUS_OK) { - // wait for the worker to finish - while (worker->status_ != VPX_WORKER_STATUS_OK) { - pthread_cond_wait(&worker->impl_->condition_, &worker->impl_->mutex_); - } - // assign new status and release the working thread if needed - if (new_status != VPX_WORKER_STATUS_OK) { - worker->status_ = new_status; - pthread_cond_signal(&worker->impl_->condition_); - } - } - pthread_mutex_unlock(&worker->impl_->mutex_); -} - -#endif // CONFIG_MULTITHREAD - -//------------------------------------------------------------------------------ - -static void init(VPxWorker *const worker) { - memset(worker, 0, sizeof(*worker)); - worker->status_ = VPX_WORKER_STATUS_NOT_OK; -} - -static int sync(VPxWorker *const worker) { -#if CONFIG_MULTITHREAD - change_state(worker, VPX_WORKER_STATUS_OK); -#endif - assert(worker->status_ <= VPX_WORKER_STATUS_OK); - return !worker->had_error; -} - -static int reset(VPxWorker *const worker) { - int ok = 1; - worker->had_error = 0; - if (worker->status_ < VPX_WORKER_STATUS_OK) { -#if CONFIG_MULTITHREAD - worker->impl_ = (VPxWorkerImpl *)vpx_calloc(1, sizeof(*worker->impl_)); - if (worker->impl_ == NULL) { - return 0; - } - if (pthread_mutex_init(&worker->impl_->mutex_, NULL)) { - goto Error; - } - if (pthread_cond_init(&worker->impl_->condition_, NULL)) { - pthread_mutex_destroy(&worker->impl_->mutex_); - goto Error; - } - pthread_mutex_lock(&worker->impl_->mutex_); - ok = !pthread_create(&worker->impl_->thread_, NULL, thread_loop, worker); - if (ok) worker->status_ = VPX_WORKER_STATUS_OK; - pthread_mutex_unlock(&worker->impl_->mutex_); - if (!ok) { - pthread_mutex_destroy(&worker->impl_->mutex_); - pthread_cond_destroy(&worker->impl_->condition_); - Error: - vpx_free(worker->impl_); - worker->impl_ = NULL; - return 0; - } -#else - worker->status_ = VPX_WORKER_STATUS_OK; -#endif - } else if (worker->status_ > VPX_WORKER_STATUS_OK) { - ok = sync(worker); - } - assert(!ok || (worker->status_ == VPX_WORKER_STATUS_OK)); - return ok; -} - -static void execute(VPxWorker *const worker) { - if (worker->hook != NULL) { - worker->had_error |= !worker->hook(worker->data1, worker->data2); - } -} - -static void launch(VPxWorker *const worker) { -#if CONFIG_MULTITHREAD - change_state(worker, VPX_WORKER_STATUS_WORKING); -#else - execute(worker); -#endif -} - -static void end(VPxWorker *const worker) { -#if CONFIG_MULTITHREAD - if (worker->impl_ != NULL) { - change_state(worker, VPX_WORKER_STATUS_NOT_OK); - pthread_join(worker->impl_->thread_, NULL); - pthread_mutex_destroy(&worker->impl_->mutex_); - pthread_cond_destroy(&worker->impl_->condition_); - vpx_free(worker->impl_); - worker->impl_ = NULL; - } -#else - worker->status_ = VPX_WORKER_STATUS_NOT_OK; - assert(worker->impl_ == NULL); -#endif - assert(worker->status_ == VPX_WORKER_STATUS_NOT_OK); -} - -//------------------------------------------------------------------------------ - -static VPxWorkerInterface g_worker_interface = { init, reset, sync, - launch, execute, end }; - -int vpx_set_worker_interface(const VPxWorkerInterface *const winterface) { - if (winterface == NULL || winterface->init == NULL || - winterface->reset == NULL || winterface->sync == NULL || - winterface->launch == NULL || winterface->execute == NULL || - winterface->end == NULL) { - return 0; - } - g_worker_interface = *winterface; - return 1; -} - -const VPxWorkerInterface *vpx_get_worker_interface(void) { - return &g_worker_interface; -} - -//------------------------------------------------------------------------------ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_thread.h b/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_thread.h deleted file mode 100644 index 22051eae..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_thread.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the COPYING file in the root of the source -// tree. An additional intellectual property rights grant can be found -// in the file PATENTS. All contributing project authors may -// be found in the AUTHORS file in the root of the source tree. -// ----------------------------------------------------------------------------- -// -// Multi-threaded worker -// -// Original source: -// https://chromium.googlesource.com/webm/libwebp - -#ifndef VPX_VPX_UTIL_VPX_THREAD_H_ -#define VPX_VPX_UTIL_VPX_THREAD_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -// State of the worker thread object -typedef enum { - VPX_WORKER_STATUS_NOT_OK = 0, // object is unusable - VPX_WORKER_STATUS_OK, // ready to work - VPX_WORKER_STATUS_WORKING // busy finishing the current task -} VPxWorkerStatus; - -// Function to be called by the worker thread. Takes two opaque pointers as -// arguments (data1 and data2). Should return true on success and return false -// in case of error. -typedef int (*VPxWorkerHook)(void *, void *); - -// Platform-dependent implementation details for the worker. -typedef struct VPxWorkerImpl VPxWorkerImpl; - -// Synchronization object used to launch job in the worker thread -typedef struct { - VPxWorkerImpl *impl_; - VPxWorkerStatus status_; - // Thread name for the debugger. If not NULL, must point to a string that - // outlives the worker thread. For portability, use a name <= 15 characters - // long (not including the terminating NUL character). - const char *thread_name; - VPxWorkerHook hook; // hook to call - void *data1; // first argument passed to 'hook' - void *data2; // second argument passed to 'hook' - int had_error; // true if a call to 'hook' returned false -} VPxWorker; - -// The interface for all thread-worker related functions. All these functions -// must be implemented. -typedef struct { - // Must be called first, before any other method. - void (*init)(VPxWorker *const worker); - // Must be called to initialize the object and spawn the thread. Re-entrant. - // Will potentially launch the thread. Returns false in case of error. - int (*reset)(VPxWorker *const worker); - // Makes sure the previous work is finished. Returns true if worker->had_error - // was not set and no error condition was triggered by the working thread. - int (*sync)(VPxWorker *const worker); - // Triggers the thread to call hook() with data1 and data2 arguments. These - // hook/data1/data2 values can be changed at any time before calling this - // function, but not be changed afterward until the next call to Sync(). - void (*launch)(VPxWorker *const worker); - // This function is similar to launch() except that it calls the - // hook directly instead of using a thread. Convenient to bypass the thread - // mechanism while still using the VPxWorker structs. sync() must - // still be called afterward (for error reporting). - void (*execute)(VPxWorker *const worker); - // Kill the thread and terminate the object. To use the object again, one - // must call reset() again. - void (*end)(VPxWorker *const worker); -} VPxWorkerInterface; - -// Install a new set of threading functions, overriding the defaults. This -// should be done before any workers are started, i.e., before any encoding or -// decoding takes place. The contents of the interface struct are copied, it -// is safe to free the corresponding memory after this call. This function is -// not thread-safe. Return false in case of invalid pointer or methods. -int vpx_set_worker_interface(const VPxWorkerInterface *const winterface); - -// Retrieve the currently set thread worker interface. -const VPxWorkerInterface *vpx_get_worker_interface(void); - -//------------------------------------------------------------------------------ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_UTIL_VPX_THREAD_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_timestamp.h b/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_timestamp.h deleted file mode 100644 index 5296458f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_timestamp.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2019 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_UTIL_VPX_TIMESTAMP_H_ -#define VPX_VPX_UTIL_VPX_TIMESTAMP_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -// Rational Number with an int64 numerator -typedef struct vpx_rational64 { - int64_t num; // fraction numerator - int den; // fraction denominator -} vpx_rational64_t; // alias for struct vpx_rational64_t - -static INLINE int gcd(int64_t a, int b) { - int r; // remainder - assert(a >= 0); - assert(b > 0); - while (b != 0) { - r = (int)(a % b); - a = b; - b = r; - } - - return (int)a; -} - -static INLINE void reduce_ratio(vpx_rational64_t *ratio) { - const int denom = gcd(ratio->num, ratio->den); - ratio->num /= denom; - ratio->den /= denom; -} - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus - -#endif // VPX_VPX_UTIL_VPX_TIMESTAMP_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_util.mk b/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_util.mk deleted file mode 100644 index 948e6d6f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_util.mk +++ /dev/null @@ -1,21 +0,0 @@ -## -## Copyright (c) 2015 The WebM project authors. All Rights Reserved. -## -## Use of this source code is governed by a BSD-style license -## that can be found in the LICENSE file in the root of the source -## tree. An additional intellectual property rights grant can be found -## in the file PATENTS. All contributing project authors may -## be found in the AUTHORS file in the root of the source tree. -## - -UTIL_SRCS-yes += vpx_atomics.h -UTIL_SRCS-yes += vpx_util.mk -UTIL_SRCS-yes += vpx_pthread.h -UTIL_SRCS-yes += vpx_thread.c -UTIL_SRCS-yes += vpx_thread.h -UTIL_SRCS-yes += endian_inl.h -UTIL_SRCS-yes += vpx_write_yuv_frame.h -UTIL_SRCS-yes += vpx_write_yuv_frame.c -UTIL_SRCS-yes += vpx_timestamp.h -UTIL_SRCS-$(or $(CONFIG_BITSTREAM_DEBUG),$(CONFIG_MISMATCH_DEBUG)) += vpx_debug_util.h -UTIL_SRCS-$(or $(CONFIG_BITSTREAM_DEBUG),$(CONFIG_MISMATCH_DEBUG)) += vpx_debug_util.c diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_write_yuv_frame.c b/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_write_yuv_frame.c deleted file mode 100644 index 4ef57a2f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_write_yuv_frame.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "vpx_dsp/skin_detection.h" -#include "vpx_util/vpx_write_yuv_frame.h" - -void vpx_write_yuv_frame(FILE *yuv_file, YV12_BUFFER_CONFIG *s) { -#if defined(OUTPUT_YUV_SRC) || defined(OUTPUT_YUV_DENOISED) || \ - defined(OUTPUT_YUV_SKINMAP) || defined(OUTPUT_YUV_SVC_SRC) - - unsigned char *src = s->y_buffer; - int h = s->y_crop_height; - - do { - fwrite(src, s->y_width, 1, yuv_file); - src += s->y_stride; - } while (--h); - - src = s->u_buffer; - h = s->uv_crop_height; - - do { - fwrite(src, s->uv_width, 1, yuv_file); - src += s->uv_stride; - } while (--h); - - src = s->v_buffer; - h = s->uv_crop_height; - - do { - fwrite(src, s->uv_width, 1, yuv_file); - src += s->uv_stride; - } while (--h); - -#else - (void)yuv_file; - (void)s; -#endif -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_write_yuv_frame.h b/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_write_yuv_frame.h deleted file mode 100644 index ce110245..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpx_util/vpx_write_yuv_frame.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2015 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPX_UTIL_VPX_WRITE_YUV_FRAME_H_ -#define VPX_VPX_UTIL_VPX_WRITE_YUV_FRAME_H_ - -#include -#include "vpx_scale/yv12config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void vpx_write_yuv_frame(FILE *yuv_file, YV12_BUFFER_CONFIG *s); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPX_UTIL_VPX_WRITE_YUV_FRAME_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpxdec.c b/presentation/src/main/cpp/third_party/libvpx/vpxdec.c deleted file mode 100644 index bfe6c1d6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpxdec.c +++ /dev/null @@ -1,1146 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include -#include -#include -#include - -#include "./vpx_config.h" - -#if CONFIG_LIBYUV -#include "third_party/libyuv/include/libyuv/scale.h" -#endif - -#include "./args.h" -#include "./ivfdec.h" - -#include "vpx/vpx_decoder.h" -#include "vpx_ports/mem_ops.h" -#include "vpx_ports/vpx_timer.h" - -#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER -#include "vpx/vp8dx.h" -#endif - -#include "./md5_utils.h" - -#include "./tools_common.h" -#if CONFIG_WEBM_IO -#include "./webmdec.h" -#endif -#include "./y4menc.h" - -static const char *exec_name; - -struct VpxDecInputContext { - struct VpxInputContext *vpx_input_ctx; - struct WebmInputContext *webm_ctx; -}; - -static const arg_def_t help = - ARG_DEF(NULL, "help", 0, "Show usage options and exit"); -static const arg_def_t looparg = - ARG_DEF(NULL, "loops", 1, "Number of times to decode the file"); -static const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1, "Codec to use"); -static const arg_def_t use_yv12 = - ARG_DEF(NULL, "yv12", 0, "Output raw YV12 frames"); -static const arg_def_t use_i420 = - ARG_DEF(NULL, "i420", 0, "Output raw I420 frames"); -static const arg_def_t flipuvarg = - ARG_DEF(NULL, "flipuv", 0, "Flip the chroma planes in the output"); -static const arg_def_t rawvideo = - ARG_DEF(NULL, "rawvideo", 0, "Output raw YUV frames"); -static const arg_def_t noblitarg = - ARG_DEF(NULL, "noblit", 0, "Don't process the decoded frames"); -static const arg_def_t progressarg = - ARG_DEF(NULL, "progress", 0, "Show progress after each frame decodes"); -static const arg_def_t limitarg = - ARG_DEF(NULL, "limit", 1, "Stop decoding after n frames"); -static const arg_def_t skiparg = - ARG_DEF(NULL, "skip", 1, "Skip the first n input frames"); -static const arg_def_t postprocarg = - ARG_DEF(NULL, "postproc", 0, "Postprocess decoded frames"); -static const arg_def_t summaryarg = - ARG_DEF(NULL, "summary", 0, "Show timing summary"); -static const arg_def_t outputfile = - ARG_DEF("o", "output", 1, "Output file name pattern (see below)"); -static const arg_def_t threadsarg = - ARG_DEF("t", "threads", 1, "Max threads to use"); -static const arg_def_t frameparallelarg = - ARG_DEF(NULL, "frame-parallel", 0, "Frame parallel decode (ignored)"); -static const arg_def_t verbosearg = - ARG_DEF("v", "verbose", 0, "Show version string"); -static const arg_def_t error_concealment = - ARG_DEF(NULL, "error-concealment", 0, "Enable decoder error-concealment"); -static const arg_def_t scalearg = - ARG_DEF("S", "scale", 0, "Scale output frames uniformly"); -static const arg_def_t continuearg = - ARG_DEF("k", "keep-going", 0, "(debug) Continue decoding after error"); -static const arg_def_t fb_arg = - ARG_DEF(NULL, "frame-buffers", 1, "Number of frame buffers to use"); -static const arg_def_t md5arg = - ARG_DEF(NULL, "md5", 0, "Compute the MD5 sum of the decoded frame"); -#if CONFIG_VP9_HIGHBITDEPTH -static const arg_def_t outbitdeptharg = - ARG_DEF(NULL, "output-bit-depth", 1, "Output bit-depth for decoded frames"); -#endif -static const arg_def_t svcdecodingarg = ARG_DEF( - NULL, "svc-decode-layer", 1, "Decode SVC stream up to given spatial layer"); -static const arg_def_t framestatsarg = - ARG_DEF(NULL, "framestats", 1, "Output per-frame stats (.csv format)"); -static const arg_def_t rowmtarg = - ARG_DEF(NULL, "row-mt", 1, "Enable multi-threading to run row-wise in VP9"); -static const arg_def_t lpfoptarg = - ARG_DEF(NULL, "lpf-opt", 1, - "Do loopfilter without waiting for all threads to sync."); - -static const arg_def_t *all_args[] = { &help, - &codecarg, - &use_yv12, - &use_i420, - &flipuvarg, - &rawvideo, - &noblitarg, - &progressarg, - &limitarg, - &skiparg, - &postprocarg, - &summaryarg, - &outputfile, - &threadsarg, - &frameparallelarg, - &verbosearg, - &scalearg, - &fb_arg, - &md5arg, - &error_concealment, - &continuearg, -#if CONFIG_VP9_HIGHBITDEPTH - &outbitdeptharg, -#endif - &svcdecodingarg, - &framestatsarg, - &rowmtarg, - &lpfoptarg, - NULL }; - -#if CONFIG_VP8_DECODER -static const arg_def_t addnoise_level = - ARG_DEF(NULL, "noise-level", 1, "Enable VP8 postproc add noise"); -static const arg_def_t deblock = - ARG_DEF(NULL, "deblock", 0, "Enable VP8 deblocking"); -static const arg_def_t demacroblock_level = ARG_DEF( - NULL, "demacroblock-level", 1, "Enable VP8 demacroblocking, w/ level"); -static const arg_def_t mfqe = - ARG_DEF(NULL, "mfqe", 0, "Enable multiframe quality enhancement"); - -static const arg_def_t *vp8_pp_args[] = { &addnoise_level, &deblock, - &demacroblock_level, &mfqe, NULL }; -#endif - -#if CONFIG_LIBYUV -static INLINE int libyuv_scale(vpx_image_t *src, vpx_image_t *dst, - FilterModeEnum mode) { -#if CONFIG_VP9_HIGHBITDEPTH - if (src->fmt == VPX_IMG_FMT_I42016) { - assert(dst->fmt == VPX_IMG_FMT_I42016); - return I420Scale_16( - (uint16_t *)src->planes[VPX_PLANE_Y], src->stride[VPX_PLANE_Y] / 2, - (uint16_t *)src->planes[VPX_PLANE_U], src->stride[VPX_PLANE_U] / 2, - (uint16_t *)src->planes[VPX_PLANE_V], src->stride[VPX_PLANE_V] / 2, - src->d_w, src->d_h, (uint16_t *)dst->planes[VPX_PLANE_Y], - dst->stride[VPX_PLANE_Y] / 2, (uint16_t *)dst->planes[VPX_PLANE_U], - dst->stride[VPX_PLANE_U] / 2, (uint16_t *)dst->planes[VPX_PLANE_V], - dst->stride[VPX_PLANE_V] / 2, dst->d_w, dst->d_h, mode); - } -#endif - assert(src->fmt == VPX_IMG_FMT_I420); - assert(dst->fmt == VPX_IMG_FMT_I420); - return I420Scale(src->planes[VPX_PLANE_Y], src->stride[VPX_PLANE_Y], - src->planes[VPX_PLANE_U], src->stride[VPX_PLANE_U], - src->planes[VPX_PLANE_V], src->stride[VPX_PLANE_V], src->d_w, - src->d_h, dst->planes[VPX_PLANE_Y], dst->stride[VPX_PLANE_Y], - dst->planes[VPX_PLANE_U], dst->stride[VPX_PLANE_U], - dst->planes[VPX_PLANE_V], dst->stride[VPX_PLANE_V], dst->d_w, - dst->d_h, mode); -} -#endif -static void show_help(FILE *fout, int shorthelp) { - int i; - - fprintf(fout, "Usage: %s filename\n\n", exec_name); - - if (shorthelp) { - fprintf(fout, "Use --help to see the full list of options.\n"); - return; - } - - fprintf(fout, "Options:\n"); - arg_show_usage(fout, all_args); -#if CONFIG_VP8_DECODER - fprintf(fout, "\nVP8 Postprocessing Options:\n"); - arg_show_usage(fout, vp8_pp_args); -#endif - fprintf(fout, - "\nOutput File Patterns:\n\n" - " The -o argument specifies the name of the file(s) to " - "write to. If the\n argument does not include any escape " - "characters, the output will be\n written to a single file. " - "Otherwise, the filename will be calculated by\n expanding " - "the following escape characters:\n"); - fprintf(fout, - "\n\t%%w - Frame width" - "\n\t%%h - Frame height" - "\n\t%% - Frame number, zero padded to places (1..9)" - "\n\n Pattern arguments are only supported in conjunction " - "with the --yv12 and\n --i420 options. If the -o option is " - "not specified, the output will be\n directed to stdout.\n"); - fprintf(fout, "\nIncluded decoders:\n\n"); - - for (i = 0; i < get_vpx_decoder_count(); ++i) { - const VpxInterface *const decoder = get_vpx_decoder_by_index(i); - fprintf(fout, " %-6s - %s\n", decoder->name, - vpx_codec_iface_name(decoder->codec_interface())); - } -} - -void usage_exit(void) { - show_help(stderr, 1); - exit(EXIT_FAILURE); -} - -static int raw_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read, - size_t *buffer_size) { - char raw_hdr[RAW_FRAME_HDR_SZ]; - size_t frame_size = 0; - - if (fread(raw_hdr, RAW_FRAME_HDR_SZ, 1, infile) != 1) { - if (!feof(infile)) warn("Failed to read RAW frame size\n"); - } else { - const size_t kCorruptFrameThreshold = 256 * 1024 * 1024; - const size_t kFrameTooSmallThreshold = 256 * 1024; - frame_size = mem_get_le32(raw_hdr); - - if (frame_size > kCorruptFrameThreshold) { - warn("Read invalid frame size (%u)\n", (unsigned int)frame_size); - frame_size = 0; - } - - if (frame_size < kFrameTooSmallThreshold) { - warn("Warning: Read invalid frame size (%u) - not a raw file?\n", - (unsigned int)frame_size); - } - - if (frame_size > *buffer_size) { - uint8_t *new_buf = realloc(*buffer, 2 * frame_size); - if (new_buf) { - *buffer = new_buf; - *buffer_size = 2 * frame_size; - } else { - warn("Failed to allocate compressed data buffer\n"); - frame_size = 0; - } - } - } - - if (!feof(infile)) { - if (fread(*buffer, 1, frame_size, infile) != frame_size) { - warn("Failed to read full frame\n"); - return 1; - } - *bytes_read = frame_size; - return 0; - } - - return 1; -} - -static int dec_read_frame(struct VpxDecInputContext *input, uint8_t **buf, - size_t *bytes_in_buffer, size_t *buffer_size) { - switch (input->vpx_input_ctx->file_type) { -#if CONFIG_WEBM_IO - case FILE_TYPE_WEBM: - return webm_read_frame(input->webm_ctx, buf, bytes_in_buffer); -#endif - case FILE_TYPE_RAW: - return raw_read_frame(input->vpx_input_ctx->file, buf, bytes_in_buffer, - buffer_size); - case FILE_TYPE_IVF: - return ivf_read_frame(input->vpx_input_ctx->file, buf, bytes_in_buffer, - buffer_size); - default: return 1; - } -} - -static void update_image_md5(const vpx_image_t *img, const int planes[3], - MD5Context *md5) { - int i, y; - - for (i = 0; i < 3; ++i) { - const int plane = planes[i]; - const unsigned char *buf = img->planes[plane]; - const int stride = img->stride[plane]; - const int w = vpx_img_plane_width(img, plane) * - ((img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1); - const int h = vpx_img_plane_height(img, plane); - - for (y = 0; y < h; ++y) { - MD5Update(md5, buf, w); - buf += stride; - } - } -} - -static void write_image_file(const vpx_image_t *img, const int planes[3], - FILE *file) { - int i, y; -#if CONFIG_VP9_HIGHBITDEPTH - const int bytes_per_sample = ((img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1); -#else - const int bytes_per_sample = 1; -#endif - - for (i = 0; i < 3; ++i) { - const int plane = planes[i]; - const unsigned char *buf = img->planes[plane]; - const int stride = img->stride[plane]; - const int w = vpx_img_plane_width(img, plane); - const int h = vpx_img_plane_height(img, plane); - - for (y = 0; y < h; ++y) { - fwrite(buf, bytes_per_sample, w, file); - buf += stride; - } - } -} - -static int file_is_raw(struct VpxInputContext *input) { - uint8_t buf[32]; - int is_raw = 0; - vpx_codec_stream_info_t si; - - si.sz = sizeof(si); - - if (fread(buf, 1, 32, input->file) == 32) { - int i; - - if (mem_get_le32(buf) < 256 * 1024 * 1024) { - for (i = 0; i < get_vpx_decoder_count(); ++i) { - const VpxInterface *const decoder = get_vpx_decoder_by_index(i); - if (!vpx_codec_peek_stream_info(decoder->codec_interface(), buf + 4, - 32 - 4, &si)) { - is_raw = 1; - input->fourcc = decoder->fourcc; - input->width = si.w; - input->height = si.h; - input->framerate.numerator = 30; - input->framerate.denominator = 1; - break; - } - } - } - } - - rewind(input->file); - return is_raw; -} - -static void show_progress(int frame_in, int frame_out, uint64_t dx_time) { - fprintf(stderr, - "%d decoded frames/%d showed frames in %" PRId64 " us (%.2f fps)\r", - frame_in, frame_out, dx_time, - (double)frame_out * 1000000.0 / (double)dx_time); -} - -struct ExternalFrameBuffer { - uint8_t *data; - size_t size; - int in_use; -}; - -struct ExternalFrameBufferList { - int num_external_frame_buffers; - struct ExternalFrameBuffer *ext_fb; -}; - -// Callback used by libvpx to request an external frame buffer. |cb_priv| -// Application private data passed into the set function. |min_size| is the -// minimum size in bytes needed to decode the next frame. |fb| pointer to the -// frame buffer. -static int get_vp9_frame_buffer(void *cb_priv, size_t min_size, - vpx_codec_frame_buffer_t *fb) { - int i; - struct ExternalFrameBufferList *const ext_fb_list = - (struct ExternalFrameBufferList *)cb_priv; - if (ext_fb_list == NULL) return -1; - - // Find a free frame buffer. - for (i = 0; i < ext_fb_list->num_external_frame_buffers; ++i) { - if (!ext_fb_list->ext_fb[i].in_use) break; - } - - if (i == ext_fb_list->num_external_frame_buffers) return -1; - - if (ext_fb_list->ext_fb[i].size < min_size) { - free(ext_fb_list->ext_fb[i].data); - ext_fb_list->ext_fb[i].data = (uint8_t *)calloc(min_size, sizeof(uint8_t)); - if (!ext_fb_list->ext_fb[i].data) return -1; - - ext_fb_list->ext_fb[i].size = min_size; - } - - fb->data = ext_fb_list->ext_fb[i].data; - fb->size = ext_fb_list->ext_fb[i].size; - ext_fb_list->ext_fb[i].in_use = 1; - - // Set the frame buffer's private data to point at the external frame buffer. - fb->priv = &ext_fb_list->ext_fb[i]; - return 0; -} - -// Callback used by libvpx when there are no references to the frame buffer. -// |cb_priv| user private data passed into the set function. |fb| pointer -// to the frame buffer. -static int release_vp9_frame_buffer(void *cb_priv, - vpx_codec_frame_buffer_t *fb) { - struct ExternalFrameBuffer *const ext_fb = - (struct ExternalFrameBuffer *)fb->priv; - (void)cb_priv; - ext_fb->in_use = 0; - return 0; -} - -static void generate_filename(const char *pattern, char *out, size_t q_len, - unsigned int d_w, unsigned int d_h, - unsigned int frame_in) { - const char *p = pattern; - char *q = out; - - do { - char *next_pat = strchr(p, '%'); - - if (p == next_pat) { - size_t pat_len; - - /* parse the pattern */ - q[q_len - 1] = '\0'; - switch (p[1]) { - case 'w': snprintf(q, q_len - 1, "%d", d_w); break; - case 'h': snprintf(q, q_len - 1, "%d", d_h); break; - case '1': snprintf(q, q_len - 1, "%d", frame_in); break; - case '2': snprintf(q, q_len - 1, "%02d", frame_in); break; - case '3': snprintf(q, q_len - 1, "%03d", frame_in); break; - case '4': snprintf(q, q_len - 1, "%04d", frame_in); break; - case '5': snprintf(q, q_len - 1, "%05d", frame_in); break; - case '6': snprintf(q, q_len - 1, "%06d", frame_in); break; - case '7': snprintf(q, q_len - 1, "%07d", frame_in); break; - case '8': snprintf(q, q_len - 1, "%08d", frame_in); break; - case '9': snprintf(q, q_len - 1, "%09d", frame_in); break; - default: die("Unrecognized pattern %%%c\n", p[1]); - } - - pat_len = strlen(q); - if (pat_len >= q_len - 1) die("Output filename too long.\n"); - q += pat_len; - p += 2; - q_len -= pat_len; - } else { - size_t copy_len; - - /* copy the next segment */ - if (!next_pat) - copy_len = strlen(p); - else - copy_len = next_pat - p; - - if (copy_len >= q_len - 1) die("Output filename too long.\n"); - - memcpy(q, p, copy_len); - q[copy_len] = '\0'; - q += copy_len; - p += copy_len; - q_len -= copy_len; - } - } while (*p); -} - -static int is_single_file(const char *outfile_pattern) { - const char *p = outfile_pattern; - - do { - p = strchr(p, '%'); - if (p && p[1] >= '1' && p[1] <= '9') - return 0; // pattern contains sequence number, so it's not unique - if (p) p++; - } while (p); - - return 1; -} - -static void print_md5(unsigned char digest[16], const char *filename) { - int i; - - for (i = 0; i < 16; ++i) printf("%02x", digest[i]); - printf(" %s\n", filename); -} - -static FILE *open_outfile(const char *name) { - if (strcmp("-", name) == 0) { - set_binary_mode(stdout); - return stdout; - } else { - FILE *file = fopen(name, "wb"); - if (!file) fatal("Failed to open output file '%s'", name); - return file; - } -} - -#if CONFIG_VP9_HIGHBITDEPTH -static int img_shifted_realloc_required(const vpx_image_t *img, - const vpx_image_t *shifted, - vpx_img_fmt_t required_fmt) { - return img->d_w != shifted->d_w || img->d_h != shifted->d_h || - required_fmt != shifted->fmt; -} -#endif - -static int main_loop(int argc, const char **argv_) { - vpx_codec_ctx_t decoder; - char *fn = NULL; - int i; - int ret = EXIT_FAILURE; - uint8_t *buf = NULL; - size_t bytes_in_buffer = 0, buffer_size = 0; - FILE *infile; - int frame_in = 0, frame_out = 0, flipuv = 0, noblit = 0; - int do_md5 = 0, progress = 0; - int stop_after = 0, postproc = 0, summary = 0, quiet = 1; - int arg_skip = 0; - int ec_enabled = 0; - int keep_going = 0; - int enable_row_mt = 0; - int enable_lpf_opt = 0; - const VpxInterface *interface = NULL; - const VpxInterface *fourcc_interface = NULL; - uint64_t dx_time = 0; - struct arg arg; - char **argv, **argi, **argj; - - int single_file; - int use_y4m = 1; - int opt_yv12 = 0; - int opt_i420 = 0; - vpx_codec_dec_cfg_t cfg = { 0, 0, 0 }; -#if CONFIG_VP9_HIGHBITDEPTH - unsigned int output_bit_depth = 0; -#endif - int svc_decoding = 0; - int svc_spatial_layer = 0; -#if CONFIG_VP8_DECODER - vp8_postproc_cfg_t vp8_pp_cfg = { 0, 0, 0 }; -#endif - int frames_corrupted = 0; - int dec_flags = 0; - int do_scale = 0; - vpx_image_t *scaled_img = NULL; -#if CONFIG_VP9_HIGHBITDEPTH - vpx_image_t *img_shifted = NULL; -#endif - int frame_avail, got_data, flush_decoder = 0; - int num_external_frame_buffers = 0; - struct ExternalFrameBufferList ext_fb_list = { 0, NULL }; - - const char *outfile_pattern = NULL; - char outfile_name[PATH_MAX] = { 0 }; - FILE *outfile = NULL; - - FILE *framestats_file = NULL; - - MD5Context md5_ctx; - unsigned char md5_digest[16]; - - struct VpxDecInputContext input = { NULL, NULL }; - struct VpxInputContext vpx_input_ctx; -#if CONFIG_WEBM_IO - struct WebmInputContext webm_ctx; - memset(&(webm_ctx), 0, sizeof(webm_ctx)); - input.webm_ctx = &webm_ctx; -#endif - input.vpx_input_ctx = &vpx_input_ctx; - - /* Parse command line */ - exec_name = argv_[0]; - argv = argv_dup(argc - 1, argv_ + 1); - if (!argv) { - fprintf(stderr, "Error allocating argument list\n"); - return EXIT_FAILURE; - } - for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { - memset(&arg, 0, sizeof(arg)); - arg.argv_step = 1; - - if (arg_match(&arg, &help, argi)) { - show_help(stdout, 0); - exit(EXIT_SUCCESS); - } else if (arg_match(&arg, &codecarg, argi)) { - interface = get_vpx_decoder_by_name(arg.val); - if (!interface) - die("Error: Unrecognized argument (%s) to --codec\n", arg.val); - } else if (arg_match(&arg, &looparg, argi)) { - // no-op - } else if (arg_match(&arg, &outputfile, argi)) - outfile_pattern = arg.val; - else if (arg_match(&arg, &use_yv12, argi)) { - use_y4m = 0; - flipuv = 1; - opt_yv12 = 1; - } else if (arg_match(&arg, &use_i420, argi)) { - use_y4m = 0; - flipuv = 0; - opt_i420 = 1; - } else if (arg_match(&arg, &rawvideo, argi)) { - use_y4m = 0; - } else if (arg_match(&arg, &flipuvarg, argi)) - flipuv = 1; - else if (arg_match(&arg, &noblitarg, argi)) - noblit = 1; - else if (arg_match(&arg, &progressarg, argi)) - progress = 1; - else if (arg_match(&arg, &limitarg, argi)) - stop_after = arg_parse_uint(&arg); - else if (arg_match(&arg, &skiparg, argi)) - arg_skip = arg_parse_uint(&arg); - else if (arg_match(&arg, &postprocarg, argi)) - postproc = 1; - else if (arg_match(&arg, &md5arg, argi)) - do_md5 = 1; - else if (arg_match(&arg, &summaryarg, argi)) - summary = 1; - else if (arg_match(&arg, &threadsarg, argi)) - cfg.threads = arg_parse_uint(&arg); -#if CONFIG_VP9_DECODER - else if (arg_match(&arg, &frameparallelarg, argi)) { - /* ignored for compatibility */ - } -#endif - else if (arg_match(&arg, &verbosearg, argi)) - quiet = 0; - else if (arg_match(&arg, &scalearg, argi)) - do_scale = 1; - else if (arg_match(&arg, &fb_arg, argi)) - num_external_frame_buffers = arg_parse_uint(&arg); - else if (arg_match(&arg, &continuearg, argi)) - keep_going = 1; -#if CONFIG_VP9_HIGHBITDEPTH - else if (arg_match(&arg, &outbitdeptharg, argi)) { - output_bit_depth = arg_parse_uint(&arg); - } -#endif - else if (arg_match(&arg, &svcdecodingarg, argi)) { - svc_decoding = 1; - svc_spatial_layer = arg_parse_uint(&arg); - } else if (arg_match(&arg, &framestatsarg, argi)) { - framestats_file = fopen(arg.val, "w"); - if (!framestats_file) { - die("Error: Could not open --framestats file (%s) for writing.\n", - arg.val); - } - } else if (arg_match(&arg, &rowmtarg, argi)) { - enable_row_mt = arg_parse_uint(&arg); - } else if (arg_match(&arg, &lpfoptarg, argi)) { - enable_lpf_opt = arg_parse_uint(&arg); - } -#if CONFIG_VP8_DECODER - else if (arg_match(&arg, &addnoise_level, argi)) { - postproc = 1; - vp8_pp_cfg.post_proc_flag |= VP8_ADDNOISE; - vp8_pp_cfg.noise_level = arg_parse_uint(&arg); - } else if (arg_match(&arg, &demacroblock_level, argi)) { - postproc = 1; - vp8_pp_cfg.post_proc_flag |= VP8_DEMACROBLOCK; - vp8_pp_cfg.deblocking_level = arg_parse_uint(&arg); - } else if (arg_match(&arg, &deblock, argi)) { - postproc = 1; - vp8_pp_cfg.post_proc_flag |= VP8_DEBLOCK; - } else if (arg_match(&arg, &mfqe, argi)) { - postproc = 1; - vp8_pp_cfg.post_proc_flag |= VP8_MFQE; - } else if (arg_match(&arg, &error_concealment, argi)) { - ec_enabled = 1; - } -#endif // CONFIG_VP8_DECODER - else - argj++; - } - - /* Check for unrecognized options */ - for (argi = argv; *argi; argi++) - if (argi[0][0] == '-' && strlen(argi[0]) > 1) - die("Error: Unrecognized option %s\n", *argi); - - /* Handle non-option arguments */ - fn = argv[0]; - - if (!fn) { - free(argv); - fprintf(stderr, "No input file specified!\n"); - usage_exit(); - } - /* Open file */ - infile = strcmp(fn, "-") ? fopen(fn, "rb") : set_binary_mode(stdin); - - if (!infile) { - fatal("Failed to open input file '%s'", strcmp(fn, "-") ? fn : "stdin"); - } -#if CONFIG_OS_SUPPORT - /* Make sure we don't dump to the terminal, unless forced to with -o - */ - if (!outfile_pattern && isatty(fileno(stdout)) && !do_md5 && !noblit) { - fprintf(stderr, - "Not dumping raw video to your terminal. Use '-o -' to " - "override.\n"); - return EXIT_FAILURE; - } -#endif - input.vpx_input_ctx->file = infile; - if (file_is_ivf(input.vpx_input_ctx)) - input.vpx_input_ctx->file_type = FILE_TYPE_IVF; -#if CONFIG_WEBM_IO - else if (file_is_webm(input.webm_ctx, input.vpx_input_ctx)) - input.vpx_input_ctx->file_type = FILE_TYPE_WEBM; -#endif - else if (file_is_raw(input.vpx_input_ctx)) - input.vpx_input_ctx->file_type = FILE_TYPE_RAW; - else { - fprintf(stderr, "Unrecognized input file type.\n"); -#if !CONFIG_WEBM_IO - fprintf(stderr, "vpxdec was built without WebM container support.\n"); -#endif - free(argv); - return EXIT_FAILURE; - } - - outfile_pattern = outfile_pattern ? outfile_pattern : "-"; - single_file = is_single_file(outfile_pattern); - - if (!noblit && single_file) { - generate_filename(outfile_pattern, outfile_name, PATH_MAX, - vpx_input_ctx.width, vpx_input_ctx.height, 0); - if (do_md5) - MD5Init(&md5_ctx); - else - outfile = open_outfile(outfile_name); - } - - if (use_y4m && !noblit) { - if (!single_file) { - fprintf(stderr, - "YUV4MPEG2 not supported with output patterns," - " try --i420 or --yv12 or --rawvideo.\n"); - return EXIT_FAILURE; - } - -#if CONFIG_WEBM_IO - if (vpx_input_ctx.file_type == FILE_TYPE_WEBM) { - if (webm_guess_framerate(input.webm_ctx, input.vpx_input_ctx)) { - fprintf(stderr, - "Failed to guess framerate -- error parsing " - "webm file?\n"); - return EXIT_FAILURE; - } - } -#endif - } - - fourcc_interface = get_vpx_decoder_by_fourcc(vpx_input_ctx.fourcc); - if (interface && fourcc_interface && interface != fourcc_interface) - warn("Header indicates codec: %s\n", fourcc_interface->name); - else - interface = fourcc_interface; - - if (!interface) interface = get_vpx_decoder_by_index(0); - - dec_flags = (postproc ? VPX_CODEC_USE_POSTPROC : 0) | - (ec_enabled ? VPX_CODEC_USE_ERROR_CONCEALMENT : 0); - if (vpx_codec_dec_init(&decoder, interface->codec_interface(), &cfg, - dec_flags)) { - fprintf(stderr, "Failed to initialize decoder: %s\n", - vpx_codec_error(&decoder)); - goto fail2; - } - if (svc_decoding) { - if (vpx_codec_control(&decoder, VP9_DECODE_SVC_SPATIAL_LAYER, - svc_spatial_layer)) { - fprintf(stderr, "Failed to set spatial layer for svc decode: %s\n", - vpx_codec_error(&decoder)); - goto fail; - } - } - if (interface->fourcc == VP9_FOURCC && - vpx_codec_control(&decoder, VP9D_SET_ROW_MT, enable_row_mt)) { - fprintf(stderr, "Failed to set decoder in row multi-thread mode: %s\n", - vpx_codec_error(&decoder)); - goto fail; - } - if (interface->fourcc == VP9_FOURCC && - vpx_codec_control(&decoder, VP9D_SET_LOOP_FILTER_OPT, enable_lpf_opt)) { - fprintf(stderr, "Failed to set decoder in optimized loopfilter mode: %s\n", - vpx_codec_error(&decoder)); - goto fail; - } - if (!quiet) fprintf(stderr, "%s\n", decoder.name); - -#if CONFIG_VP8_DECODER - if (vp8_pp_cfg.post_proc_flag && - vpx_codec_control(&decoder, VP8_SET_POSTPROC, &vp8_pp_cfg)) { - fprintf(stderr, "Failed to configure postproc: %s\n", - vpx_codec_error(&decoder)); - goto fail; - } -#endif - - if (arg_skip) fprintf(stderr, "Skipping first %d frames.\n", arg_skip); - while (arg_skip) { - if (dec_read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) break; - arg_skip--; - } - - if (num_external_frame_buffers > 0) { - ext_fb_list.num_external_frame_buffers = num_external_frame_buffers; - ext_fb_list.ext_fb = (struct ExternalFrameBuffer *)calloc( - num_external_frame_buffers, sizeof(*ext_fb_list.ext_fb)); - if (!ext_fb_list.ext_fb) { - fprintf(stderr, "Failed to allocate ExternalFrameBuffer\n"); - goto fail; - } - if (vpx_codec_set_frame_buffer_functions(&decoder, get_vp9_frame_buffer, - release_vp9_frame_buffer, - &ext_fb_list)) { - fprintf(stderr, "Failed to configure external frame buffers: %s\n", - vpx_codec_error(&decoder)); - goto fail; - } - } - - frame_avail = 1; - got_data = 0; - - if (framestats_file) fprintf(framestats_file, "bytes,qp\n"); - - /* Decode file */ - while (frame_avail || got_data) { - vpx_codec_iter_t iter = NULL; - vpx_image_t *img; - struct vpx_usec_timer timer; - int corrupted = 0; - - frame_avail = 0; - if (!stop_after || frame_in < stop_after) { - if (!dec_read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) { - frame_avail = 1; - frame_in++; - - vpx_usec_timer_start(&timer); - - if (vpx_codec_decode(&decoder, buf, (unsigned int)bytes_in_buffer, NULL, - 0)) { - const char *detail = vpx_codec_error_detail(&decoder); - warn("Failed to decode frame %d: %s", frame_in, - vpx_codec_error(&decoder)); - if (detail) warn("Additional information: %s", detail); - corrupted = 1; - if (!keep_going) goto fail; - } - - if (framestats_file) { - int qp; - if (vpx_codec_control(&decoder, VPXD_GET_LAST_QUANTIZER, &qp)) { - warn("Failed VPXD_GET_LAST_QUANTIZER: %s", - vpx_codec_error(&decoder)); - if (!keep_going) goto fail; - } - fprintf(framestats_file, "%d,%d\n", (int)bytes_in_buffer, qp); - } - - vpx_usec_timer_mark(&timer); - dx_time += vpx_usec_timer_elapsed(&timer); - } else { - flush_decoder = 1; - } - } else { - flush_decoder = 1; - } - - vpx_usec_timer_start(&timer); - - if (flush_decoder) { - // Flush the decoder in frame parallel decode. - if (vpx_codec_decode(&decoder, NULL, 0, NULL, 0)) { - warn("Failed to flush decoder: %s", vpx_codec_error(&decoder)); - corrupted = 1; - if (!keep_going) goto fail; - } - } - - got_data = 0; - if ((img = vpx_codec_get_frame(&decoder, &iter))) { - ++frame_out; - got_data = 1; - } - - vpx_usec_timer_mark(&timer); - dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer); - - if (!corrupted && - vpx_codec_control(&decoder, VP8D_GET_FRAME_CORRUPTED, &corrupted)) { - warn("Failed VP8_GET_FRAME_CORRUPTED: %s", vpx_codec_error(&decoder)); - if (!keep_going) goto fail; - } - frames_corrupted += corrupted; - - if (progress) show_progress(frame_in, frame_out, dx_time); - - if (!noblit && img) { - const int PLANES_YUV[] = { VPX_PLANE_Y, VPX_PLANE_U, VPX_PLANE_V }; - const int PLANES_YVU[] = { VPX_PLANE_Y, VPX_PLANE_V, VPX_PLANE_U }; - const int *planes = flipuv ? PLANES_YVU : PLANES_YUV; - - if (do_scale) { - if (frame_out == 1) { - // If the output frames are to be scaled to a fixed display size then - // use the width and height specified in the container. If either of - // these is set to 0, use the display size set in the first frame - // header. If that is unavailable, use the raw decoded size of the - // first decoded frame. - int render_width = vpx_input_ctx.width; - int render_height = vpx_input_ctx.height; - if (!render_width || !render_height) { - int render_size[2]; - if (vpx_codec_control(&decoder, VP9D_GET_DISPLAY_SIZE, - render_size)) { - // As last resort use size of first frame as display size. - render_width = img->d_w; - render_height = img->d_h; - } else { - render_width = render_size[0]; - render_height = render_size[1]; - } - } - scaled_img = - vpx_img_alloc(NULL, img->fmt, render_width, render_height, 16); - if (!scaled_img) { - fprintf(stderr, "Failed to allocate scaled image (%d x %d)\n", - render_width, render_height); - goto fail; - } - scaled_img->bit_depth = img->bit_depth; - } - - if (img->d_w != scaled_img->d_w || img->d_h != scaled_img->d_h) { -#if CONFIG_LIBYUV - libyuv_scale(img, scaled_img, kFilterBox); - img = scaled_img; -#else - fprintf(stderr, - "Failed to scale output frame: %s.\n" - "Scaling is disabled in this configuration. " - "To enable scaling, configure with --enable-libyuv\n", - vpx_codec_error(&decoder)); - goto fail; -#endif - } - } -#if CONFIG_VP9_HIGHBITDEPTH - // Default to codec bit depth if output bit depth not set - if (!output_bit_depth && single_file && !do_md5) { - output_bit_depth = img->bit_depth; - } - // Shift up or down if necessary - if (output_bit_depth != 0 && output_bit_depth != img->bit_depth) { - const vpx_img_fmt_t shifted_fmt = - output_bit_depth == 8 - ? img->fmt ^ (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) - : img->fmt | VPX_IMG_FMT_HIGHBITDEPTH; - if (img_shifted && - img_shifted_realloc_required(img, img_shifted, shifted_fmt)) { - vpx_img_free(img_shifted); - img_shifted = NULL; - } - if (!img_shifted) { - img_shifted = - vpx_img_alloc(NULL, shifted_fmt, img->d_w, img->d_h, 16); - if (!img_shifted) { - fprintf(stderr, "Failed to allocate image\n"); - goto fail; - } - img_shifted->bit_depth = output_bit_depth; - } - if (output_bit_depth > img->bit_depth) { - vpx_img_upshift(img_shifted, img, output_bit_depth - img->bit_depth); - } else { - vpx_img_downshift(img_shifted, img, - img->bit_depth - output_bit_depth); - } - img = img_shifted; - } -#endif - - if (single_file) { - if (use_y4m) { - char y4m_buf[Y4M_BUFFER_SIZE] = { 0 }; - size_t len = 0; - if (img->fmt == VPX_IMG_FMT_I440 || img->fmt == VPX_IMG_FMT_I44016) { - fprintf(stderr, "Cannot produce y4m output for 440 sampling.\n"); - goto fail; - } - if (frame_out == 1) { - // Y4M file header - len = y4m_write_file_header( - y4m_buf, sizeof(y4m_buf), vpx_input_ctx.width, - vpx_input_ctx.height, &vpx_input_ctx.framerate, img->fmt, - img->bit_depth); - if (do_md5) { - MD5Update(&md5_ctx, (md5byte *)y4m_buf, (unsigned int)len); - } else { - fputs(y4m_buf, outfile); - } - } - - // Y4M frame header - len = y4m_write_frame_header(y4m_buf, sizeof(y4m_buf)); - if (do_md5) { - MD5Update(&md5_ctx, (md5byte *)y4m_buf, (unsigned int)len); - } else { - fputs(y4m_buf, outfile); - } - } else { - if (frame_out == 1) { - // Check if --yv12 or --i420 options are consistent with the - // bit-stream decoded - if (opt_i420) { - if (img->fmt != VPX_IMG_FMT_I420 && - img->fmt != VPX_IMG_FMT_I42016) { - fprintf(stderr, "Cannot produce i420 output for bit-stream.\n"); - goto fail; - } - } - if (opt_yv12) { - if ((img->fmt != VPX_IMG_FMT_I420 && - img->fmt != VPX_IMG_FMT_YV12) || - img->bit_depth != 8) { - fprintf(stderr, "Cannot produce yv12 output for bit-stream.\n"); - goto fail; - } - } - } - } - - if (do_md5) { - update_image_md5(img, planes, &md5_ctx); - } else { - if (!corrupted) write_image_file(img, planes, outfile); - } - } else { - generate_filename(outfile_pattern, outfile_name, PATH_MAX, img->d_w, - img->d_h, frame_in); - if (do_md5) { - MD5Init(&md5_ctx); - update_image_md5(img, planes, &md5_ctx); - MD5Final(md5_digest, &md5_ctx); - print_md5(md5_digest, outfile_name); - } else { - outfile = open_outfile(outfile_name); - write_image_file(img, planes, outfile); - fclose(outfile); - } - } - } - } - - if (summary || progress) { - show_progress(frame_in, frame_out, dx_time); - fprintf(stderr, "\n"); - } - - if (frames_corrupted) { - fprintf(stderr, "WARNING: %d frames corrupted.\n", frames_corrupted); - } else { - ret = EXIT_SUCCESS; - } - -fail: - - if (vpx_codec_destroy(&decoder)) { - fprintf(stderr, "Failed to destroy decoder: %s\n", - vpx_codec_error(&decoder)); - } - -fail2: - - if (!noblit && single_file) { - if (do_md5) { - MD5Final(md5_digest, &md5_ctx); - print_md5(md5_digest, outfile_name); - } else { - fclose(outfile); - } - } - -#if CONFIG_WEBM_IO - if (input.vpx_input_ctx->file_type == FILE_TYPE_WEBM) - webm_free(input.webm_ctx); -#endif - - if (input.vpx_input_ctx->file_type != FILE_TYPE_WEBM) free(buf); - - if (scaled_img) vpx_img_free(scaled_img); -#if CONFIG_VP9_HIGHBITDEPTH - if (img_shifted) vpx_img_free(img_shifted); -#endif - - for (i = 0; i < ext_fb_list.num_external_frame_buffers; ++i) { - free(ext_fb_list.ext_fb[i].data); - } - free(ext_fb_list.ext_fb); - - fclose(infile); - if (framestats_file) fclose(framestats_file); - - free(argv); - - return ret; -} - -int main(int argc, const char **argv_) { - unsigned int loops = 1, i; - char **argv, **argi, **argj; - struct arg arg; - int error = 0; - - argv = argv_dup(argc - 1, argv_ + 1); - if (!argv) { - fprintf(stderr, "Error allocating argument list\n"); - return EXIT_FAILURE; - } - for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { - memset(&arg, 0, sizeof(arg)); - arg.argv_step = 1; - - if (arg_match(&arg, &looparg, argi)) { - loops = arg_parse_uint(&arg); - break; - } - } - free(argv); - for (i = 0; !error && i < loops; i++) error = main_loop(argc, argv_); - return error; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpxenc.c b/presentation/src/main/cpp/third_party/libvpx/vpxenc.c deleted file mode 100644 index 5e9fddec..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpxenc.c +++ /dev/null @@ -1,2075 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpxenc.h" -#include "./vpx_config.h" - -#include -#include -#include -#include -#include -#include -#include - -#if CONFIG_LIBYUV -#include "third_party/libyuv/include/libyuv/scale.h" -#endif - -#include "vpx/vpx_encoder.h" -#if CONFIG_DECODERS -#include "vpx/vpx_decoder.h" -#endif - -#include "./args.h" -#include "./ivfenc.h" -#include "./tools_common.h" - -#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER -#include "vpx/vp8cx.h" -#endif -#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER -#include "vpx/vp8dx.h" -#endif - -#include "vpx/vpx_integer.h" -#include "vpx_ports/mem_ops.h" -#include "vpx_ports/vpx_timer.h" -#include "./rate_hist.h" -#include "./vpxstats.h" -#include "./warnings.h" -#if CONFIG_WEBM_IO -#include "./webmenc.h" -#endif -#include "./y4minput.h" - -static size_t wrap_fwrite(const void *ptr, size_t size, size_t nmemb, - FILE *stream) { - return fwrite(ptr, size, nmemb, stream); -} -#define fwrite wrap_fwrite - -static const char *exec_name; - -static VPX_TOOLS_FORMAT_PRINTF(3, 0) void warn_or_exit_on_errorv( - vpx_codec_ctx_t *ctx, int fatal, const char *s, va_list ap) { - if (ctx->err) { - const char *detail = vpx_codec_error_detail(ctx); - - vfprintf(stderr, s, ap); - fprintf(stderr, ": %s\n", vpx_codec_error(ctx)); - - if (detail) fprintf(stderr, " %s\n", detail); - - if (fatal) exit(EXIT_FAILURE); - } -} - -static VPX_TOOLS_FORMAT_PRINTF(2, - 3) void ctx_exit_on_error(vpx_codec_ctx_t *ctx, - const char *s, ...) { - va_list ap; - - va_start(ap, s); - warn_or_exit_on_errorv(ctx, 1, s, ap); - va_end(ap); -} - -static VPX_TOOLS_FORMAT_PRINTF(3, 4) void warn_or_exit_on_error( - vpx_codec_ctx_t *ctx, int fatal, const char *s, ...) { - va_list ap; - - va_start(ap, s); - warn_or_exit_on_errorv(ctx, fatal, s, ap); - va_end(ap); -} - -static const arg_def_t help = - ARG_DEF(NULL, "help", 0, "Show usage options and exit"); -static const arg_def_t debugmode = - ARG_DEF("D", "debug", 0, "Debug mode (makes output deterministic)"); -static const arg_def_t outputfile = - ARG_DEF("o", "output", 1, "Output filename"); -static const arg_def_t use_nv12 = - ARG_DEF(NULL, "nv12", 0, "Input file is NV12 "); -static const arg_def_t use_yv12 = - ARG_DEF(NULL, "yv12", 0, "Input file is YV12 "); -static const arg_def_t use_i420 = - ARG_DEF(NULL, "i420", 0, "Input file is I420 (default)"); -static const arg_def_t use_i422 = - ARG_DEF(NULL, "i422", 0, "Input file is I422"); -static const arg_def_t use_i444 = - ARG_DEF(NULL, "i444", 0, "Input file is I444"); -static const arg_def_t use_i440 = - ARG_DEF(NULL, "i440", 0, "Input file is I440"); -static const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1, "Codec to use"); -static const arg_def_t passes = - ARG_DEF("p", "passes", 1, "Number of passes (1/2)"); -static const arg_def_t pass_arg = - ARG_DEF(NULL, "pass", 1, "Pass to execute (1/2)"); -static const arg_def_t fpf_name = - ARG_DEF(NULL, "fpf", 1, "First pass statistics file name"); -static const arg_def_t limit = - ARG_DEF(NULL, "limit", 1, "Stop encoding after n input frames"); -static const arg_def_t skip = - ARG_DEF(NULL, "skip", 1, "Skip the first n input frames"); -static const arg_def_t deadline = - ARG_DEF("d", "deadline", 1, "Deadline per frame (usec)"); -static const arg_def_t best_dl = - ARG_DEF(NULL, "best", 0, "Use Best Quality Deadline"); -static const arg_def_t good_dl = - ARG_DEF(NULL, "good", 0, "Use Good Quality Deadline"); -static const arg_def_t rt_dl = - ARG_DEF(NULL, "rt", 0, "Use Realtime Quality Deadline"); -static const arg_def_t quietarg = - ARG_DEF("q", "quiet", 0, "Do not print encode progress"); -static const arg_def_t verbosearg = - ARG_DEF("v", "verbose", 0, "Show encoder parameters"); -static const arg_def_t psnrarg = - ARG_DEF(NULL, "psnr", 0, "Show PSNR in status line"); - -static const struct arg_enum_list test_decode_enum[] = { - { "off", TEST_DECODE_OFF }, - { "fatal", TEST_DECODE_FATAL }, - { "warn", TEST_DECODE_WARN }, - { NULL, 0 } -}; -static const arg_def_t recontest = ARG_DEF_ENUM( - NULL, "test-decode", 1, "Test encode/decode mismatch", test_decode_enum); -static const arg_def_t framerate = - ARG_DEF(NULL, "fps", 1, "Stream frame rate (rate/scale)"); -static const arg_def_t use_webm = - ARG_DEF(NULL, "webm", 0, "Output WebM (default when WebM IO is enabled)"); -static const arg_def_t use_ivf = ARG_DEF(NULL, "ivf", 0, "Output IVF"); -static const arg_def_t out_part = - ARG_DEF("P", "output-partitions", 0, - "Makes encoder output partitions. Requires IVF output!"); -static const arg_def_t q_hist_n = - ARG_DEF(NULL, "q-hist", 1, "Show quantizer histogram (n-buckets)"); -static const arg_def_t rate_hist_n = - ARG_DEF(NULL, "rate-hist", 1, "Show rate histogram (n-buckets)"); -static const arg_def_t disable_warnings = - ARG_DEF(NULL, "disable-warnings", 0, - "Disable warnings about potentially incorrect encode settings."); -static const arg_def_t disable_warning_prompt = - ARG_DEF("y", "disable-warning-prompt", 0, - "Display warnings, but do not prompt user to continue."); - -#if CONFIG_VP9_HIGHBITDEPTH -static const arg_def_t test16bitinternalarg = ARG_DEF( - NULL, "test-16bit-internal", 0, "Force use of 16 bit internal buffer"); -#endif - -static const arg_def_t *main_args[] = { &help, - &debugmode, - &outputfile, - &codecarg, - &passes, - &pass_arg, - &fpf_name, - &limit, - &skip, - &deadline, - &best_dl, - &good_dl, - &rt_dl, - &quietarg, - &verbosearg, - &psnrarg, - &use_webm, - &use_ivf, - &out_part, - &q_hist_n, - &rate_hist_n, - &disable_warnings, - &disable_warning_prompt, - &recontest, - NULL }; - -static const arg_def_t usage = - ARG_DEF("u", "usage", 1, "Usage profile number to use"); -static const arg_def_t threads = - ARG_DEF("t", "threads", 1, "Max number of threads to use"); -static const arg_def_t profile = - ARG_DEF(NULL, "profile", 1, "Bitstream profile number to use"); -static const arg_def_t width = ARG_DEF("w", "width", 1, "Frame width"); -static const arg_def_t height = ARG_DEF("h", "height", 1, "Frame height"); -#if CONFIG_WEBM_IO -static const struct arg_enum_list stereo_mode_enum[] = { - { "mono", STEREO_FORMAT_MONO }, - { "left-right", STEREO_FORMAT_LEFT_RIGHT }, - { "bottom-top", STEREO_FORMAT_BOTTOM_TOP }, - { "top-bottom", STEREO_FORMAT_TOP_BOTTOM }, - { "right-left", STEREO_FORMAT_RIGHT_LEFT }, - { NULL, 0 } -}; -static const arg_def_t stereo_mode = ARG_DEF_ENUM( - NULL, "stereo-mode", 1, "Stereo 3D video format", stereo_mode_enum); -#endif -static const arg_def_t timebase = ARG_DEF( - NULL, "timebase", 1, "Output timestamp precision (fractional seconds)"); -static const arg_def_t error_resilient = - ARG_DEF(NULL, "error-resilient", 1, "Enable error resiliency features"); -static const arg_def_t lag_in_frames = - ARG_DEF(NULL, "lag-in-frames", 1, "Max number of frames to lag"); - -static const arg_def_t *global_args[] = { &use_nv12, - &use_yv12, - &use_i420, - &use_i422, - &use_i444, - &use_i440, - &usage, - &threads, - &profile, - &width, - &height, -#if CONFIG_WEBM_IO - &stereo_mode, -#endif - &timebase, - &framerate, - &error_resilient, -#if CONFIG_VP9_HIGHBITDEPTH - &test16bitinternalarg, -#endif - &lag_in_frames, - NULL }; - -static const arg_def_t dropframe_thresh = - ARG_DEF(NULL, "drop-frame", 1, "Temporal resampling threshold (buf %)"); -static const arg_def_t resize_allowed = - ARG_DEF(NULL, "resize-allowed", 1, "Spatial resampling enabled (bool)"); -static const arg_def_t resize_width = - ARG_DEF(NULL, "resize-width", 1, "Width of encoded frame"); -static const arg_def_t resize_height = - ARG_DEF(NULL, "resize-height", 1, "Height of encoded frame"); -static const arg_def_t resize_up_thresh = - ARG_DEF(NULL, "resize-up", 1, "Upscale threshold (buf %)"); -static const arg_def_t resize_down_thresh = - ARG_DEF(NULL, "resize-down", 1, "Downscale threshold (buf %)"); -static const struct arg_enum_list end_usage_enum[] = { { "vbr", VPX_VBR }, - { "cbr", VPX_CBR }, - { "cq", VPX_CQ }, - { "q", VPX_Q }, - { NULL, 0 } }; -static const arg_def_t end_usage = - ARG_DEF_ENUM(NULL, "end-usage", 1, "Rate control mode", end_usage_enum); -static const arg_def_t target_bitrate = - ARG_DEF(NULL, "target-bitrate", 1, "Bitrate (kbps)"); -static const arg_def_t min_quantizer = - ARG_DEF(NULL, "min-q", 1, "Minimum (best) quantizer"); -static const arg_def_t max_quantizer = - ARG_DEF(NULL, "max-q", 1, "Maximum (worst) quantizer"); -static const arg_def_t undershoot_pct = - ARG_DEF(NULL, "undershoot-pct", 1, "Datarate undershoot (min) target (%)"); -static const arg_def_t overshoot_pct = - ARG_DEF(NULL, "overshoot-pct", 1, "Datarate overshoot (max) target (%)"); -static const arg_def_t buf_sz = - ARG_DEF(NULL, "buf-sz", 1, "Client buffer size (ms)"); -static const arg_def_t buf_initial_sz = - ARG_DEF(NULL, "buf-initial-sz", 1, "Client initial buffer size (ms)"); -static const arg_def_t buf_optimal_sz = - ARG_DEF(NULL, "buf-optimal-sz", 1, "Client optimal buffer size (ms)"); -static const arg_def_t *rc_args[] = { - &dropframe_thresh, &resize_allowed, &resize_width, &resize_height, - &resize_up_thresh, &resize_down_thresh, &end_usage, &target_bitrate, - &min_quantizer, &max_quantizer, &undershoot_pct, &overshoot_pct, - &buf_sz, &buf_initial_sz, &buf_optimal_sz, NULL -}; - -#if CONFIG_VP9_ENCODER -static const arg_def_t use_vizier_rc_params = - ARG_DEF(NULL, "use-vizier-rc-params", 1, "Use vizier rc params"); -static const arg_def_t active_wq_factor = - ARG_DEF(NULL, "active-wq-factor", 1, "Active worst quality factor"); -static const arg_def_t err_per_mb_factor = - ARG_DEF(NULL, "err-per-mb-factor", 1, "Error per macroblock factor"); -static const arg_def_t sr_default_decay_limit = ARG_DEF( - NULL, "sr-default-decay-limit", 1, "Second reference default decay limit"); -static const arg_def_t sr_diff_factor = - ARG_DEF(NULL, "sr-diff-factor", 1, "Second reference diff factor"); -static const arg_def_t kf_err_per_mb_factor = ARG_DEF( - NULL, "kf-err-per-mb-factor", 1, "Keyframe error per macroblock factor"); -static const arg_def_t kf_frame_min_boost_factor = - ARG_DEF(NULL, "kf-frame-min-boost-factor", 1, "Keyframe min boost"); -static const arg_def_t kf_frame_max_boost_first_factor = - ARG_DEF(NULL, "kf-frame-max-boost-first-factor", 1, - "Max keyframe boost adjustment factor for first frame"); -static const arg_def_t kf_frame_max_boost_subs_factor = - ARG_DEF(NULL, "kf-frame-max-boost-subs-factor", 1, - "Max boost adjustment factor for subsequent KFs"); -static const arg_def_t kf_max_total_boost_factor = ARG_DEF( - NULL, "kf-max-total-boost-factor", 1, "Keyframe max total boost factor"); -static const arg_def_t gf_max_total_boost_factor = - ARG_DEF(NULL, "gf-max-total-boost-factor", 1, - "Golden frame max total boost factor"); -static const arg_def_t gf_frame_max_boost_factor = - ARG_DEF(NULL, "gf-frame-max-boost-factor", 1, - "Golden frame max per frame boost factor"); -static const arg_def_t zm_factor = - ARG_DEF(NULL, "zm-factor", 1, "Zero motion power factor"); -static const arg_def_t rd_mult_inter_qp_fac = - ARG_DEF(NULL, "rd-mult-inter-qp-fac", 1, - "RD multiplier adjustment for inter frames"); -static const arg_def_t rd_mult_arf_qp_fac = - ARG_DEF(NULL, "rd-mult-arf-qp-fac", 1, - "RD multiplier adjustment for alt-ref frames"); -static const arg_def_t rd_mult_key_qp_fac = ARG_DEF( - NULL, "rd-mult-key-qp-fac", 1, "RD multiplier adjustment for key frames"); -static const arg_def_t *vizier_rc_args[] = { &use_vizier_rc_params, - &active_wq_factor, - &err_per_mb_factor, - &sr_default_decay_limit, - &sr_diff_factor, - &kf_err_per_mb_factor, - &kf_frame_min_boost_factor, - &kf_frame_max_boost_first_factor, - &kf_frame_max_boost_subs_factor, - &kf_max_total_boost_factor, - &gf_max_total_boost_factor, - &gf_frame_max_boost_factor, - &zm_factor, - &rd_mult_inter_qp_fac, - &rd_mult_arf_qp_fac, - &rd_mult_key_qp_fac, - NULL }; -#endif - -static const arg_def_t bias_pct = - ARG_DEF(NULL, "bias-pct", 1, "CBR/VBR bias (0=CBR, 100=VBR)"); -static const arg_def_t minsection_pct = - ARG_DEF(NULL, "minsection-pct", 1, "GOP min bitrate (% of target)"); -static const arg_def_t maxsection_pct = - ARG_DEF(NULL, "maxsection-pct", 1, "GOP max bitrate (% of target)"); -static const arg_def_t corpus_complexity = - ARG_DEF(NULL, "corpus-complexity", 1, "corpus vbr complexity midpoint"); -static const arg_def_t *rc_twopass_args[] = { &bias_pct, &minsection_pct, - &maxsection_pct, - &corpus_complexity, NULL }; - -static const arg_def_t kf_min_dist = - ARG_DEF(NULL, "kf-min-dist", 1, "Minimum keyframe interval (frames)"); -static const arg_def_t kf_max_dist = - ARG_DEF(NULL, "kf-max-dist", 1, "Maximum keyframe interval (frames)"); -static const arg_def_t kf_disabled = - ARG_DEF(NULL, "disable-kf", 0, "Disable keyframe placement"); -static const arg_def_t *kf_args[] = { &kf_min_dist, &kf_max_dist, &kf_disabled, - NULL }; - -static const arg_def_t noise_sens = - ARG_DEF(NULL, "noise-sensitivity", 1, "Noise sensitivity (frames to blur)"); -static const arg_def_t sharpness = - ARG_DEF(NULL, "sharpness", 1, - "Increase sharpness at the expense of lower PSNR. (0..7)"); -static const arg_def_t static_thresh = - ARG_DEF(NULL, "static-thresh", 1, "Motion detection threshold"); -static const arg_def_t arnr_maxframes = - ARG_DEF(NULL, "arnr-maxframes", 1, "AltRef max frames (0..15)"); -static const arg_def_t arnr_strength = - ARG_DEF(NULL, "arnr-strength", 1, "AltRef filter strength (0..6)"); -static const arg_def_t arnr_type = - ARG_DEF(NULL, "arnr-type", 1, "AltRef filter type (1..3)"); -static const struct arg_enum_list tuning_enum[] = { { "psnr", VP8_TUNE_PSNR }, - { "ssim", VP8_TUNE_SSIM }, - { NULL, 0 } }; -static const arg_def_t tune_ssim = - ARG_DEF_ENUM(NULL, "tune", 1, "Material to favor", tuning_enum); -static const arg_def_t cq_level = - ARG_DEF(NULL, "cq-level", 1, "Constant/Constrained Quality level"); -static const arg_def_t max_intra_rate_pct = - ARG_DEF(NULL, "max-intra-rate", 1, "Max I-frame bitrate (pct)"); -static const arg_def_t gf_cbr_boost_pct = ARG_DEF( - NULL, "gf-cbr-boost", 1, "Boost for Golden Frame in CBR mode (pct)"); - -#if CONFIG_VP8_ENCODER -static const arg_def_t cpu_used_vp8 = - ARG_DEF(NULL, "cpu-used", 1, "CPU Used (-16..16)"); -static const arg_def_t auto_altref_vp8 = ARG_DEF( - NULL, "auto-alt-ref", 1, "Enable automatic alt reference frames. (0..1)"); -static const arg_def_t token_parts = - ARG_DEF(NULL, "token-parts", 1, "Number of token partitions to use, log2"); -static const arg_def_t screen_content_mode = - ARG_DEF(NULL, "screen-content-mode", 1, "Screen content mode"); -static const arg_def_t *vp8_args[] = { &cpu_used_vp8, - &auto_altref_vp8, - &noise_sens, - &sharpness, - &static_thresh, - &token_parts, - &arnr_maxframes, - &arnr_strength, - &arnr_type, - &tune_ssim, - &cq_level, - &max_intra_rate_pct, - &gf_cbr_boost_pct, - &screen_content_mode, - NULL }; -static const int vp8_arg_ctrl_map[] = { VP8E_SET_CPUUSED, - VP8E_SET_ENABLEAUTOALTREF, - VP8E_SET_NOISE_SENSITIVITY, - VP8E_SET_SHARPNESS, - VP8E_SET_STATIC_THRESHOLD, - VP8E_SET_TOKEN_PARTITIONS, - VP8E_SET_ARNR_MAXFRAMES, - VP8E_SET_ARNR_STRENGTH, - VP8E_SET_ARNR_TYPE, - VP8E_SET_TUNING, - VP8E_SET_CQ_LEVEL, - VP8E_SET_MAX_INTRA_BITRATE_PCT, - VP8E_SET_GF_CBR_BOOST_PCT, - VP8E_SET_SCREEN_CONTENT_MODE, - 0 }; -#endif - -#if CONFIG_VP9_ENCODER -static const arg_def_t cpu_used_vp9 = - ARG_DEF(NULL, "cpu-used", 1, "CPU Used (-9..9)"); -static const arg_def_t auto_altref_vp9 = ARG_DEF( - NULL, "auto-alt-ref", 1, - "Enable automatic alt reference frames, 2+ enables multi-layer. (0..6)"); -static const arg_def_t tile_cols = - ARG_DEF(NULL, "tile-columns", 1, "Number of tile columns to use, log2"); -static const arg_def_t tile_rows = - ARG_DEF(NULL, "tile-rows", 1, - "Number of tile rows to use, log2 (set to 0 while threads > 1)"); - -static const arg_def_t enable_tpl_model = - ARG_DEF(NULL, "enable-tpl", 1, "Enable temporal dependency model"); -static const arg_def_t enable_keyframe_filtering = - ARG_DEF(NULL, "enable-keyframe-filtering", 1, - "Enable key frame temporal filtering (0: off (default), 1: on)"); - -static const arg_def_t lossless = - ARG_DEF(NULL, "lossless", 1, "Lossless mode (0: false (default), 1: true)"); -static const arg_def_t frame_parallel_decoding = ARG_DEF( - NULL, "frame-parallel", 1, "Enable frame parallel decodability features"); -static const arg_def_t aq_mode = ARG_DEF( - NULL, "aq-mode", 1, - "Adaptive quantization mode (0: off (default), 1: variance 2: complexity, " - "3: cyclic refresh, 4: equator360)"); -static const arg_def_t alt_ref_aq = ARG_DEF(NULL, "alt-ref-aq", 1, - "Special adaptive quantization for " - "the alternate reference frames."); -static const arg_def_t frame_periodic_boost = - ARG_DEF(NULL, "frame-boost", 1, - "Enable frame periodic boost (0: off (default), 1: on)"); -static const arg_def_t max_inter_rate_pct = - ARG_DEF(NULL, "max-inter-rate", 1, "Max P-frame bitrate (pct)"); -static const arg_def_t min_gf_interval = ARG_DEF( - NULL, "min-gf-interval", 1, - "min gf/arf frame interval (default 0, indicating in-built behavior)"); -static const arg_def_t max_gf_interval = ARG_DEF( - NULL, "max-gf-interval", 1, - "max gf/arf frame interval (default 0, indicating in-built behavior)"); - -static const struct arg_enum_list color_space_enum[] = { - { "unknown", VPX_CS_UNKNOWN }, - { "bt601", VPX_CS_BT_601 }, - { "bt709", VPX_CS_BT_709 }, - { "smpte170", VPX_CS_SMPTE_170 }, - { "smpte240", VPX_CS_SMPTE_240 }, - { "bt2020", VPX_CS_BT_2020 }, - { "reserved", VPX_CS_RESERVED }, - { "sRGB", VPX_CS_SRGB }, - { NULL, 0 } -}; - -static const arg_def_t input_color_space = - ARG_DEF_ENUM(NULL, "color-space", 1, - "The color space of input content:", color_space_enum); - -#if CONFIG_VP9_HIGHBITDEPTH -static const struct arg_enum_list bitdepth_enum[] = { - { "8", VPX_BITS_8 }, { "10", VPX_BITS_10 }, { "12", VPX_BITS_12 }, { NULL, 0 } -}; - -static const arg_def_t bitdeptharg = ARG_DEF_ENUM( - "b", "bit-depth", 1, - "Bit depth for codec (8 for version <=1, 10 or 12 for version 2)", - bitdepth_enum); -static const arg_def_t inbitdeptharg = - ARG_DEF(NULL, "input-bit-depth", 1, "Bit depth of input"); -#endif - -static const struct arg_enum_list tune_content_enum[] = { - { "default", VP9E_CONTENT_DEFAULT }, - { "screen", VP9E_CONTENT_SCREEN }, - { "film", VP9E_CONTENT_FILM }, - { NULL, 0 } -}; - -static const arg_def_t tune_content = ARG_DEF_ENUM( - NULL, "tune-content", 1, "Tune content type", tune_content_enum); - -static const arg_def_t target_level = ARG_DEF( - NULL, "target-level", 1, - "Target level\n" - " 255: off (default)\n" - " 0: only keep level stats\n" - " 1: adaptively set alt-ref " - "distance and column tile limit based on picture size, and keep" - " level stats\n" - " 10: level 1.0 11: level 1.1 " - "... 62: level 6.2"); - -static const arg_def_t row_mt = - ARG_DEF(NULL, "row-mt", 1, - "Enable row based non-deterministic multi-threading in VP9"); - -static const arg_def_t disable_loopfilter = - ARG_DEF(NULL, "disable-loopfilter", 1, - "Control Loopfilter in VP9:\n" - " " - "0: Loopfilter on for all frames (default)\n" - " " - "1: Loopfilter off for non reference frames\n" - " " - "2: Loopfilter off for all frames"); -#endif - -#if CONFIG_VP9_ENCODER -static const arg_def_t *vp9_args[] = { &cpu_used_vp9, - &auto_altref_vp9, - &sharpness, - &static_thresh, - &tile_cols, - &tile_rows, - &enable_tpl_model, - &enable_keyframe_filtering, - &arnr_maxframes, - &arnr_strength, - &arnr_type, - &tune_ssim, - &cq_level, - &max_intra_rate_pct, - &max_inter_rate_pct, - &gf_cbr_boost_pct, - &lossless, - &frame_parallel_decoding, - &aq_mode, - &alt_ref_aq, - &frame_periodic_boost, - &noise_sens, - &tune_content, - &input_color_space, - &min_gf_interval, - &max_gf_interval, - &target_level, - &row_mt, - &disable_loopfilter, -// NOTE: The entries above have a corresponding entry in vp9_arg_ctrl_map. The -// entries below do not have a corresponding entry in vp9_arg_ctrl_map. They -// must be listed at the end of vp9_args. -#if CONFIG_VP9_HIGHBITDEPTH - &bitdeptharg, - &inbitdeptharg, -#endif // CONFIG_VP9_HIGHBITDEPTH - NULL }; -static const int vp9_arg_ctrl_map[] = { VP8E_SET_CPUUSED, - VP8E_SET_ENABLEAUTOALTREF, - VP8E_SET_SHARPNESS, - VP8E_SET_STATIC_THRESHOLD, - VP9E_SET_TILE_COLUMNS, - VP9E_SET_TILE_ROWS, - VP9E_SET_TPL, - VP9E_SET_KEY_FRAME_FILTERING, - VP8E_SET_ARNR_MAXFRAMES, - VP8E_SET_ARNR_STRENGTH, - VP8E_SET_ARNR_TYPE, - VP8E_SET_TUNING, - VP8E_SET_CQ_LEVEL, - VP8E_SET_MAX_INTRA_BITRATE_PCT, - VP9E_SET_MAX_INTER_BITRATE_PCT, - VP9E_SET_GF_CBR_BOOST_PCT, - VP9E_SET_LOSSLESS, - VP9E_SET_FRAME_PARALLEL_DECODING, - VP9E_SET_AQ_MODE, - VP9E_SET_ALT_REF_AQ, - VP9E_SET_FRAME_PERIODIC_BOOST, - VP9E_SET_NOISE_SENSITIVITY, - VP9E_SET_TUNE_CONTENT, - VP9E_SET_COLOR_SPACE, - VP9E_SET_MIN_GF_INTERVAL, - VP9E_SET_MAX_GF_INTERVAL, - VP9E_SET_TARGET_LEVEL, - VP9E_SET_ROW_MT, - VP9E_SET_DISABLE_LOOPFILTER, - 0 }; -#endif - -static const arg_def_t *no_args[] = { NULL }; - -static void show_help(FILE *fout, int shorthelp) { - int i; - const int num_encoder = get_vpx_encoder_count(); - - fprintf(fout, "Usage: %s -o dst_filename src_filename \n", - exec_name); - - if (shorthelp) { - fprintf(fout, "Use --help to see the full list of options.\n"); - return; - } - - fprintf(fout, "\nOptions:\n"); - arg_show_usage(fout, main_args); - fprintf(fout, "\nEncoder Global Options:\n"); - arg_show_usage(fout, global_args); - fprintf(fout, "\nRate Control Options:\n"); - arg_show_usage(fout, rc_args); - fprintf(fout, "\nTwopass Rate Control Options:\n"); - arg_show_usage(fout, rc_twopass_args); - fprintf(fout, "\nKeyframe Placement Options:\n"); - arg_show_usage(fout, kf_args); -#if CONFIG_VP8_ENCODER - fprintf(fout, "\nVP8 Specific Options:\n"); - arg_show_usage(fout, vp8_args); -#endif -#if CONFIG_VP9_ENCODER - fprintf(fout, "\nVP9 Specific Options:\n"); - arg_show_usage(fout, vp9_args); - fprintf(fout, "\nVizier Rate Control Options:\n"); - arg_show_usage(fout, vizier_rc_args); -#endif - fprintf(fout, - "\nStream timebase (--timebase):\n" - " The desired precision of timestamps in the output, expressed\n" - " in fractional seconds. Default is 1/1000.\n"); - fprintf(fout, "\nIncluded encoders:\n\n"); - - for (i = 0; i < num_encoder; ++i) { - const VpxInterface *const encoder = get_vpx_encoder_by_index(i); - const char *defstr = (i == (num_encoder - 1)) ? "(default)" : ""; - fprintf(fout, " %-6s - %s %s\n", encoder->name, - vpx_codec_iface_name(encoder->codec_interface()), defstr); - } - fprintf(fout, "\n "); - fprintf(fout, "Use --codec to switch to a non-default encoder.\n\n"); -} - -void usage_exit(void) { - show_help(stderr, 1); - exit(EXIT_FAILURE); -} - -#define NELEMENTS(x) (sizeof(x) / sizeof(x[0])) -#if CONFIG_VP9_ENCODER -#define ARG_CTRL_CNT_MAX NELEMENTS(vp9_arg_ctrl_map) -#else -#define ARG_CTRL_CNT_MAX NELEMENTS(vp8_arg_ctrl_map) -#endif - -#if !CONFIG_WEBM_IO -typedef int stereo_format_t; -struct WebmOutputContext { - int debug; -}; -#endif - -/* Per-stream configuration */ -struct stream_config { - struct vpx_codec_enc_cfg cfg; - const char *out_fn; - const char *stats_fn; - stereo_format_t stereo_fmt; - int arg_ctrls[ARG_CTRL_CNT_MAX][2]; - int arg_ctrl_cnt; - int write_webm; -#if CONFIG_VP9_HIGHBITDEPTH - // whether to use 16bit internal buffers - int use_16bit_internal; -#endif -}; - -struct stream_state { - int index; - struct stream_state *next; - struct stream_config config; - FILE *file; - struct rate_hist *rate_hist; - struct WebmOutputContext webm_ctx; - uint64_t psnr_sse_total; - uint64_t psnr_samples_total; - double psnr_totals[4]; - int psnr_count; - int counts[64]; - vpx_codec_ctx_t encoder; - unsigned int frames_out; - uint64_t cx_time; - size_t nbytes; - stats_io_t stats; - struct vpx_image *img; - vpx_codec_ctx_t decoder; - int mismatch_seen; -}; - -static void validate_positive_rational(const char *msg, - struct vpx_rational *rat) { - if (rat->den < 0) { - rat->num *= -1; - rat->den *= -1; - } - - if (rat->num < 0) die("Error: %s must be positive\n", msg); - - if (!rat->den) die("Error: %s has zero denominator\n", msg); -} - -static void parse_global_config(struct VpxEncoderConfig *global, char **argv) { - char **argi, **argj; - struct arg arg; - const int num_encoder = get_vpx_encoder_count(); - - if (num_encoder < 1) die("Error: no valid encoder available\n"); - - /* Initialize default parameters */ - memset(global, 0, sizeof(*global)); - global->codec = get_vpx_encoder_by_index(num_encoder - 1); - global->passes = 0; - global->color_type = I420; - /* Assign default deadline to good quality */ - global->deadline = VPX_DL_GOOD_QUALITY; - - for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { - arg.argv_step = 1; - - if (arg_match(&arg, &help, argi)) { - show_help(stdout, 0); - exit(EXIT_SUCCESS); - } else if (arg_match(&arg, &codecarg, argi)) { - global->codec = get_vpx_encoder_by_name(arg.val); - if (!global->codec) - die("Error: Unrecognized argument (%s) to --codec\n", arg.val); - } else if (arg_match(&arg, &passes, argi)) { - global->passes = arg_parse_uint(&arg); - - if (global->passes < 1 || global->passes > 2) - die("Error: Invalid number of passes (%d)\n", global->passes); - } else if (arg_match(&arg, &pass_arg, argi)) { - global->pass = arg_parse_uint(&arg); - - if (global->pass < 1 || global->pass > 2) - die("Error: Invalid pass selected (%d)\n", global->pass); - } else if (arg_match(&arg, &usage, argi)) - global->usage = arg_parse_uint(&arg); - else if (arg_match(&arg, &deadline, argi)) - global->deadline = arg_parse_uint(&arg); - else if (arg_match(&arg, &best_dl, argi)) - global->deadline = VPX_DL_BEST_QUALITY; - else if (arg_match(&arg, &good_dl, argi)) - global->deadline = VPX_DL_GOOD_QUALITY; - else if (arg_match(&arg, &rt_dl, argi)) - global->deadline = VPX_DL_REALTIME; - else if (arg_match(&arg, &use_yv12, argi)) - global->color_type = YV12; - else if (arg_match(&arg, &use_nv12, argi)) - global->color_type = NV12; - else if (arg_match(&arg, &use_i420, argi)) - global->color_type = I420; - else if (arg_match(&arg, &use_i422, argi)) - global->color_type = I422; - else if (arg_match(&arg, &use_i444, argi)) - global->color_type = I444; - else if (arg_match(&arg, &use_i440, argi)) - global->color_type = I440; - else if (arg_match(&arg, &quietarg, argi)) - global->quiet = 1; - else if (arg_match(&arg, &verbosearg, argi)) - global->verbose = 1; - else if (arg_match(&arg, &limit, argi)) - global->limit = arg_parse_uint(&arg); - else if (arg_match(&arg, &skip, argi)) - global->skip_frames = arg_parse_uint(&arg); - else if (arg_match(&arg, &psnrarg, argi)) - global->show_psnr = 1; - else if (arg_match(&arg, &recontest, argi)) - global->test_decode = arg_parse_enum_or_int(&arg); - else if (arg_match(&arg, &framerate, argi)) { - global->framerate = arg_parse_rational(&arg); - validate_positive_rational(arg.name, &global->framerate); - global->have_framerate = 1; - } else if (arg_match(&arg, &out_part, argi)) - global->out_part = 1; - else if (arg_match(&arg, &debugmode, argi)) - global->debug = 1; - else if (arg_match(&arg, &q_hist_n, argi)) - global->show_q_hist_buckets = arg_parse_uint(&arg); - else if (arg_match(&arg, &rate_hist_n, argi)) - global->show_rate_hist_buckets = arg_parse_uint(&arg); - else if (arg_match(&arg, &disable_warnings, argi)) - global->disable_warnings = 1; - else if (arg_match(&arg, &disable_warning_prompt, argi)) - global->disable_warning_prompt = 1; - else - argj++; - } - - if (global->pass) { - /* DWIM: Assume the user meant passes=2 if pass=2 is specified */ - if (global->pass > global->passes) { - warn("Assuming --pass=%d implies --passes=%d\n", global->pass, - global->pass); - global->passes = global->pass; - } - } - /* Validate global config */ - if (global->passes == 0) { -#if CONFIG_VP9_ENCODER - // Make default VP9 passes = 2 until there is a better quality 1-pass - // encoder - if (global->codec != NULL && global->codec->name != NULL) - global->passes = (strcmp(global->codec->name, "vp9") == 0 && - global->deadline != VPX_DL_REALTIME) - ? 2 - : 1; -#else - global->passes = 1; -#endif - } - - if (global->deadline == VPX_DL_REALTIME && global->passes > 1) { - warn("Enforcing one-pass encoding in realtime mode\n"); - global->passes = 1; - } -} - -static struct stream_state *new_stream(struct VpxEncoderConfig *global, - struct stream_state *prev) { - struct stream_state *stream; - - stream = calloc(1, sizeof(*stream)); - if (stream == NULL) { - fatal("Failed to allocate new stream."); - } - - if (prev) { - memcpy(stream, prev, sizeof(*stream)); - stream->index++; - prev->next = stream; - } else { - vpx_codec_err_t res; - - /* Populate encoder configuration */ - res = vpx_codec_enc_config_default(global->codec->codec_interface(), - &stream->config.cfg, global->usage); - if (res) fatal("Failed to get config: %s\n", vpx_codec_err_to_string(res)); - - /* Change the default timebase to a high enough value so that the - * encoder will always create strictly increasing timestamps. - */ - stream->config.cfg.g_timebase.den = 1000; - - /* Never use the library's default resolution, require it be parsed - * from the file or set on the command line. - */ - stream->config.cfg.g_w = 0; - stream->config.cfg.g_h = 0; - - /* Initialize remaining stream parameters */ - stream->config.write_webm = 1; -#if CONFIG_WEBM_IO - stream->config.stereo_fmt = STEREO_FORMAT_MONO; - stream->webm_ctx.last_pts_ns = -1; - stream->webm_ctx.writer = NULL; - stream->webm_ctx.segment = NULL; -#endif - - /* Allows removal of the application version from the EBML tags */ - stream->webm_ctx.debug = global->debug; - - /* Default lag_in_frames is 0 in realtime mode CBR mode*/ - if (global->deadline == VPX_DL_REALTIME && - stream->config.cfg.rc_end_usage == VPX_CBR) - stream->config.cfg.g_lag_in_frames = 0; - } - - /* Output files must be specified for each stream */ - stream->config.out_fn = NULL; - - stream->next = NULL; - return stream; -} - -static int parse_stream_params(struct VpxEncoderConfig *global, - struct stream_state *stream, char **argv) { - char **argi, **argj; - struct arg arg; - const arg_def_t **ctrl_args = no_args; - const int *ctrl_args_map = NULL; - struct stream_config *config = &stream->config; - int eos_mark_found = 0; -#if CONFIG_VP9_HIGHBITDEPTH - int test_16bit_internal = 0; -#endif - - // Handle codec specific options - if (0) { -#if CONFIG_VP8_ENCODER - } else if (strcmp(global->codec->name, "vp8") == 0) { - ctrl_args = vp8_args; - ctrl_args_map = vp8_arg_ctrl_map; -#endif -#if CONFIG_VP9_ENCODER - } else if (strcmp(global->codec->name, "vp9") == 0) { - ctrl_args = vp9_args; - ctrl_args_map = vp9_arg_ctrl_map; -#endif - } - - for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { - arg.argv_step = 1; - - /* Once we've found an end-of-stream marker (--) we want to continue - * shifting arguments but not consuming them. - */ - if (eos_mark_found) { - argj++; - continue; - } else if (!strcmp(*argj, "--")) { - eos_mark_found = 1; - continue; - } - - if (arg_match(&arg, &outputfile, argi)) { - config->out_fn = arg.val; - } else if (arg_match(&arg, &fpf_name, argi)) { - config->stats_fn = arg.val; - } else if (arg_match(&arg, &use_webm, argi)) { -#if CONFIG_WEBM_IO - config->write_webm = 1; -#else - die("Error: --webm specified but webm is disabled."); -#endif - } else if (arg_match(&arg, &use_ivf, argi)) { - config->write_webm = 0; - } else if (arg_match(&arg, &threads, argi)) { - config->cfg.g_threads = arg_parse_uint(&arg); - } else if (arg_match(&arg, &profile, argi)) { - config->cfg.g_profile = arg_parse_uint(&arg); - } else if (arg_match(&arg, &width, argi)) { - config->cfg.g_w = arg_parse_uint(&arg); - } else if (arg_match(&arg, &height, argi)) { - config->cfg.g_h = arg_parse_uint(&arg); -#if CONFIG_VP9_HIGHBITDEPTH - } else if (arg_match(&arg, &bitdeptharg, argi)) { - config->cfg.g_bit_depth = arg_parse_enum_or_int(&arg); - } else if (arg_match(&arg, &inbitdeptharg, argi)) { - config->cfg.g_input_bit_depth = arg_parse_uint(&arg); -#endif -#if CONFIG_WEBM_IO - } else if (arg_match(&arg, &stereo_mode, argi)) { - config->stereo_fmt = arg_parse_enum_or_int(&arg); -#endif - } else if (arg_match(&arg, &timebase, argi)) { - config->cfg.g_timebase = arg_parse_rational(&arg); - validate_positive_rational(arg.name, &config->cfg.g_timebase); - } else if (arg_match(&arg, &error_resilient, argi)) { - config->cfg.g_error_resilient = arg_parse_uint(&arg); - } else if (arg_match(&arg, &end_usage, argi)) { - config->cfg.rc_end_usage = arg_parse_enum_or_int(&arg); - } else if (arg_match(&arg, &lag_in_frames, argi)) { - config->cfg.g_lag_in_frames = arg_parse_uint(&arg); - if (global->deadline == VPX_DL_REALTIME && - config->cfg.rc_end_usage == VPX_CBR && - config->cfg.g_lag_in_frames != 0) { - warn("non-zero %s option ignored in realtime CBR mode.\n", arg.name); - config->cfg.g_lag_in_frames = 0; - } - } else if (arg_match(&arg, &dropframe_thresh, argi)) { - config->cfg.rc_dropframe_thresh = arg_parse_uint(&arg); - } else if (arg_match(&arg, &resize_allowed, argi)) { - config->cfg.rc_resize_allowed = arg_parse_uint(&arg); - } else if (arg_match(&arg, &resize_width, argi)) { - config->cfg.rc_scaled_width = arg_parse_uint(&arg); - } else if (arg_match(&arg, &resize_height, argi)) { - config->cfg.rc_scaled_height = arg_parse_uint(&arg); - } else if (arg_match(&arg, &resize_up_thresh, argi)) { - config->cfg.rc_resize_up_thresh = arg_parse_uint(&arg); - } else if (arg_match(&arg, &resize_down_thresh, argi)) { - config->cfg.rc_resize_down_thresh = arg_parse_uint(&arg); - } else if (arg_match(&arg, &end_usage, argi)) { - config->cfg.rc_end_usage = arg_parse_enum_or_int(&arg); - } else if (arg_match(&arg, &target_bitrate, argi)) { - config->cfg.rc_target_bitrate = arg_parse_uint(&arg); - } else if (arg_match(&arg, &min_quantizer, argi)) { - config->cfg.rc_min_quantizer = arg_parse_uint(&arg); - } else if (arg_match(&arg, &max_quantizer, argi)) { - config->cfg.rc_max_quantizer = arg_parse_uint(&arg); - } else if (arg_match(&arg, &undershoot_pct, argi)) { - config->cfg.rc_undershoot_pct = arg_parse_uint(&arg); - } else if (arg_match(&arg, &overshoot_pct, argi)) { - config->cfg.rc_overshoot_pct = arg_parse_uint(&arg); - } else if (arg_match(&arg, &buf_sz, argi)) { - config->cfg.rc_buf_sz = arg_parse_uint(&arg); - } else if (arg_match(&arg, &buf_initial_sz, argi)) { - config->cfg.rc_buf_initial_sz = arg_parse_uint(&arg); - } else if (arg_match(&arg, &buf_optimal_sz, argi)) { - config->cfg.rc_buf_optimal_sz = arg_parse_uint(&arg); - } else if (arg_match(&arg, &bias_pct, argi)) { - config->cfg.rc_2pass_vbr_bias_pct = arg_parse_uint(&arg); - if (global->passes < 2) - warn("option %s ignored in one-pass mode.\n", arg.name); - } else if (arg_match(&arg, &minsection_pct, argi)) { - config->cfg.rc_2pass_vbr_minsection_pct = arg_parse_uint(&arg); - - if (global->passes < 2) - warn("option %s ignored in one-pass mode.\n", arg.name); - } else if (arg_match(&arg, &maxsection_pct, argi)) { - config->cfg.rc_2pass_vbr_maxsection_pct = arg_parse_uint(&arg); - - if (global->passes < 2) - warn("option %s ignored in one-pass mode.\n", arg.name); - } else if (arg_match(&arg, &corpus_complexity, argi)) { - config->cfg.rc_2pass_vbr_corpus_complexity = arg_parse_uint(&arg); - - if (global->passes < 2) - warn("option %s ignored in one-pass mode.\n", arg.name); - } else if (arg_match(&arg, &kf_min_dist, argi)) { - config->cfg.kf_min_dist = arg_parse_uint(&arg); - } else if (arg_match(&arg, &kf_max_dist, argi)) { - config->cfg.kf_max_dist = arg_parse_uint(&arg); - } else if (arg_match(&arg, &kf_disabled, argi)) { - config->cfg.kf_mode = VPX_KF_DISABLED; -#if CONFIG_VP9_ENCODER - } else if (arg_match(&arg, &use_vizier_rc_params, argi)) { - config->cfg.use_vizier_rc_params = arg_parse_int(&arg); - } else if (arg_match(&arg, &active_wq_factor, argi)) { - config->cfg.active_wq_factor = arg_parse_rational(&arg); - } else if (arg_match(&arg, &err_per_mb_factor, argi)) { - config->cfg.err_per_mb_factor = arg_parse_rational(&arg); - } else if (arg_match(&arg, &sr_default_decay_limit, argi)) { - config->cfg.sr_default_decay_limit = arg_parse_rational(&arg); - } else if (arg_match(&arg, &sr_diff_factor, argi)) { - config->cfg.sr_diff_factor = arg_parse_rational(&arg); - } else if (arg_match(&arg, &kf_err_per_mb_factor, argi)) { - config->cfg.kf_err_per_mb_factor = arg_parse_rational(&arg); - } else if (arg_match(&arg, &kf_frame_min_boost_factor, argi)) { - config->cfg.kf_frame_min_boost_factor = arg_parse_rational(&arg); - } else if (arg_match(&arg, &kf_frame_max_boost_first_factor, argi)) { - config->cfg.kf_frame_max_boost_first_factor = arg_parse_rational(&arg); - } else if (arg_match(&arg, &kf_frame_max_boost_subs_factor, argi)) { - config->cfg.kf_frame_max_boost_subs_factor = arg_parse_rational(&arg); - } else if (arg_match(&arg, &kf_max_total_boost_factor, argi)) { - config->cfg.kf_max_total_boost_factor = arg_parse_rational(&arg); - } else if (arg_match(&arg, &gf_max_total_boost_factor, argi)) { - config->cfg.gf_max_total_boost_factor = arg_parse_rational(&arg); - } else if (arg_match(&arg, &gf_frame_max_boost_factor, argi)) { - config->cfg.gf_frame_max_boost_factor = arg_parse_rational(&arg); - } else if (arg_match(&arg, &zm_factor, argi)) { - config->cfg.zm_factor = arg_parse_rational(&arg); - } else if (arg_match(&arg, &rd_mult_inter_qp_fac, argi)) { - config->cfg.rd_mult_inter_qp_fac = arg_parse_rational(&arg); - } else if (arg_match(&arg, &rd_mult_arf_qp_fac, argi)) { - config->cfg.rd_mult_arf_qp_fac = arg_parse_rational(&arg); - } else if (arg_match(&arg, &rd_mult_key_qp_fac, argi)) { - config->cfg.rd_mult_key_qp_fac = arg_parse_rational(&arg); -#endif -#if CONFIG_VP9_HIGHBITDEPTH - } else if (arg_match(&arg, &test16bitinternalarg, argi)) { - if (strcmp(global->codec->name, "vp9") == 0) { - test_16bit_internal = 1; - } -#endif - } else { - int i, match = 0; - for (i = 0; ctrl_args[i]; i++) { - if (arg_match(&arg, ctrl_args[i], argi)) { - int j; - match = 1; - - /* Point either to the next free element or the first - * instance of this control. - */ - for (j = 0; j < config->arg_ctrl_cnt; j++) - if (ctrl_args_map != NULL && - config->arg_ctrls[j][0] == ctrl_args_map[i]) - break; - - /* Update/insert */ - assert(j < (int)ARG_CTRL_CNT_MAX); - if (ctrl_args_map != NULL && j < (int)ARG_CTRL_CNT_MAX) { - config->arg_ctrls[j][0] = ctrl_args_map[i]; - config->arg_ctrls[j][1] = arg_parse_enum_or_int(&arg); - if (j == config->arg_ctrl_cnt) config->arg_ctrl_cnt++; - } - } - } - if (!match) argj++; - } - } -#if CONFIG_VP9_HIGHBITDEPTH - if (strcmp(global->codec->name, "vp9") == 0) { - config->use_16bit_internal = - test_16bit_internal | (config->cfg.g_profile > 1); - } -#endif - return eos_mark_found; -} - -#define FOREACH_STREAM(func) \ - do { \ - struct stream_state *stream; \ - for (stream = streams; stream; stream = stream->next) { \ - func; \ - } \ - } while (0) - -static void validate_stream_config(const struct stream_state *stream, - const struct VpxEncoderConfig *global) { - const struct stream_state *streami; - (void)global; - - if (!stream->config.cfg.g_w || !stream->config.cfg.g_h) - fatal( - "Stream %d: Specify stream dimensions with --width (-w) " - " and --height (-h)", - stream->index); - - // Check that the codec bit depth is greater than the input bit depth. - if (stream->config.cfg.g_input_bit_depth > - (unsigned int)stream->config.cfg.g_bit_depth) { - fatal("Stream %d: codec bit depth (%d) less than input bit depth (%d)", - stream->index, (int)stream->config.cfg.g_bit_depth, - stream->config.cfg.g_input_bit_depth); - } - - for (streami = stream; streami; streami = streami->next) { - /* All streams require output files */ - if (!streami->config.out_fn) - fatal("Stream %d: Output file is required (specify with -o)", - streami->index); - - /* Check for two streams outputting to the same file */ - if (streami != stream) { - const char *a = stream->config.out_fn; - const char *b = streami->config.out_fn; - if (!strcmp(a, b) && strcmp(a, "/dev/null") && strcmp(a, ":nul")) - fatal("Stream %d: duplicate output file (from stream %d)", - streami->index, stream->index); - } - - /* Check for two streams sharing a stats file. */ - if (streami != stream) { - const char *a = stream->config.stats_fn; - const char *b = streami->config.stats_fn; - if (a && b && !strcmp(a, b)) - fatal("Stream %d: duplicate stats file (from stream %d)", - streami->index, stream->index); - } - } -} - -static void set_stream_dimensions(struct stream_state *stream, unsigned int w, - unsigned int h) { - if (!stream->config.cfg.g_w) { - if (!stream->config.cfg.g_h) - stream->config.cfg.g_w = w; - else - stream->config.cfg.g_w = w * stream->config.cfg.g_h / h; - } - if (!stream->config.cfg.g_h) { - stream->config.cfg.g_h = h * stream->config.cfg.g_w / w; - } -} - -static const char *file_type_to_string(enum VideoFileType t) { - switch (t) { - case FILE_TYPE_RAW: return "RAW"; - case FILE_TYPE_Y4M: return "Y4M"; - default: return "Other"; - } -} - -static const char *image_format_to_string(vpx_img_fmt_t f) { - switch (f) { - case VPX_IMG_FMT_I420: return "I420"; - case VPX_IMG_FMT_I422: return "I422"; - case VPX_IMG_FMT_I444: return "I444"; - case VPX_IMG_FMT_I440: return "I440"; - case VPX_IMG_FMT_YV12: return "YV12"; - case VPX_IMG_FMT_I42016: return "I42016"; - case VPX_IMG_FMT_I42216: return "I42216"; - case VPX_IMG_FMT_I44416: return "I44416"; - case VPX_IMG_FMT_I44016: return "I44016"; - default: return "Other"; - } -} - -static void show_stream_config(struct stream_state *stream, - struct VpxEncoderConfig *global, - struct VpxInputContext *input) { -#define SHOW(field) \ - fprintf(stderr, " %-28s = %d\n", #field, stream->config.cfg.field) - - if (stream->index == 0) { - fprintf(stderr, "Codec: %s\n", - vpx_codec_iface_name(global->codec->codec_interface())); - fprintf(stderr, "Source file: %s File Type: %s Format: %s\n", - input->filename, file_type_to_string(input->file_type), - image_format_to_string(input->fmt)); - } - if (stream->next || stream->index) - fprintf(stderr, "\nStream Index: %d\n", stream->index); - fprintf(stderr, "Destination file: %s\n", stream->config.out_fn); - fprintf(stderr, "Encoder parameters:\n"); - - SHOW(g_usage); - SHOW(g_threads); - SHOW(g_profile); - SHOW(g_w); - SHOW(g_h); - SHOW(g_bit_depth); - SHOW(g_input_bit_depth); - SHOW(g_timebase.num); - SHOW(g_timebase.den); - SHOW(g_error_resilient); - SHOW(g_pass); - SHOW(g_lag_in_frames); - SHOW(rc_dropframe_thresh); - SHOW(rc_resize_allowed); - SHOW(rc_scaled_width); - SHOW(rc_scaled_height); - SHOW(rc_resize_up_thresh); - SHOW(rc_resize_down_thresh); - SHOW(rc_end_usage); - SHOW(rc_target_bitrate); - SHOW(rc_min_quantizer); - SHOW(rc_max_quantizer); - SHOW(rc_undershoot_pct); - SHOW(rc_overshoot_pct); - SHOW(rc_buf_sz); - SHOW(rc_buf_initial_sz); - SHOW(rc_buf_optimal_sz); - SHOW(rc_2pass_vbr_bias_pct); - SHOW(rc_2pass_vbr_minsection_pct); - SHOW(rc_2pass_vbr_maxsection_pct); - SHOW(rc_2pass_vbr_corpus_complexity); - SHOW(kf_mode); - SHOW(kf_min_dist); - SHOW(kf_max_dist); - // Temporary use for debug - SHOW(use_vizier_rc_params); - SHOW(active_wq_factor.num); - SHOW(active_wq_factor.den); -} - -static void open_output_file(struct stream_state *stream, - struct VpxEncoderConfig *global, - const struct VpxRational *pixel_aspect_ratio) { - const char *fn = stream->config.out_fn; - const struct vpx_codec_enc_cfg *const cfg = &stream->config.cfg; - - if (cfg->g_pass == VPX_RC_FIRST_PASS) return; - - stream->file = strcmp(fn, "-") ? fopen(fn, "wb") : set_binary_mode(stdout); - - if (!stream->file) fatal("Failed to open output file"); - - if (stream->config.write_webm && fseek(stream->file, 0, SEEK_CUR)) - fatal("WebM output to pipes not supported."); - -#if CONFIG_WEBM_IO - if (stream->config.write_webm) { - stream->webm_ctx.stream = stream->file; - write_webm_file_header(&stream->webm_ctx, cfg, stream->config.stereo_fmt, - global->codec->fourcc, pixel_aspect_ratio); - } -#else - (void)pixel_aspect_ratio; -#endif - - if (!stream->config.write_webm) { - ivf_write_file_header(stream->file, cfg, global->codec->fourcc, 0); - } -} - -static void close_output_file(struct stream_state *stream, - unsigned int fourcc) { - const struct vpx_codec_enc_cfg *const cfg = &stream->config.cfg; - - if (cfg->g_pass == VPX_RC_FIRST_PASS) return; - -#if CONFIG_WEBM_IO - if (stream->config.write_webm) { - write_webm_file_footer(&stream->webm_ctx); - } -#endif - - if (!stream->config.write_webm) { - if (!fseek(stream->file, 0, SEEK_SET)) - ivf_write_file_header(stream->file, &stream->config.cfg, fourcc, - stream->frames_out); - } - - fclose(stream->file); -} - -static void setup_pass(struct stream_state *stream, - struct VpxEncoderConfig *global, int pass) { - if (stream->config.stats_fn) { - if (!stats_open_file(&stream->stats, stream->config.stats_fn, pass)) - fatal("Failed to open statistics store"); - } else { - if (!stats_open_mem(&stream->stats, pass)) - fatal("Failed to open statistics store"); - } - - stream->config.cfg.g_pass = global->passes == 2 - ? pass ? VPX_RC_LAST_PASS : VPX_RC_FIRST_PASS - : VPX_RC_ONE_PASS; - if (pass) { - stream->config.cfg.rc_twopass_stats_in = stats_get(&stream->stats); - } - - stream->cx_time = 0; - stream->nbytes = 0; - stream->frames_out = 0; -} - -static void initialize_encoder(struct stream_state *stream, - struct VpxEncoderConfig *global) { - int i; - int flags = 0; - - flags |= global->show_psnr ? VPX_CODEC_USE_PSNR : 0; - flags |= global->out_part ? VPX_CODEC_USE_OUTPUT_PARTITION : 0; -#if CONFIG_VP9_HIGHBITDEPTH - flags |= stream->config.use_16bit_internal ? VPX_CODEC_USE_HIGHBITDEPTH : 0; -#endif - - /* Construct Encoder Context */ - vpx_codec_enc_init(&stream->encoder, global->codec->codec_interface(), - &stream->config.cfg, flags); - ctx_exit_on_error(&stream->encoder, "Failed to initialize encoder"); - - /* Note that we bypass the vpx_codec_control wrapper macro because - * we're being clever to store the control IDs in an array. Real - * applications will want to make use of the enumerations directly - */ - for (i = 0; i < stream->config.arg_ctrl_cnt; i++) { - int ctrl = stream->config.arg_ctrls[i][0]; - int value = stream->config.arg_ctrls[i][1]; - if (vpx_codec_control_(&stream->encoder, ctrl, value)) - fprintf(stderr, "Error: Tried to set control %d = %d\n", ctrl, value); - - ctx_exit_on_error(&stream->encoder, "Failed to control codec"); - } - -#if CONFIG_DECODERS - if (global->test_decode != TEST_DECODE_OFF) { - const VpxInterface *decoder = get_vpx_decoder_by_name(global->codec->name); - vpx_codec_dec_init(&stream->decoder, decoder->codec_interface(), NULL, 0); - } -#endif -} - -static void encode_frame(struct stream_state *stream, - struct VpxEncoderConfig *global, struct vpx_image *img, - unsigned int frames_in) { - vpx_codec_pts_t frame_start, next_frame_start; - struct vpx_codec_enc_cfg *cfg = &stream->config.cfg; - struct vpx_usec_timer timer; - - frame_start = - (cfg->g_timebase.den * (int64_t)(frames_in - 1) * global->framerate.den) / - cfg->g_timebase.num / global->framerate.num; - next_frame_start = - (cfg->g_timebase.den * (int64_t)(frames_in)*global->framerate.den) / - cfg->g_timebase.num / global->framerate.num; - -/* Scale if necessary */ -#if CONFIG_VP9_HIGHBITDEPTH - if (img) { - if ((img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) && - (img->d_w != cfg->g_w || img->d_h != cfg->g_h)) { - if (img->fmt != VPX_IMG_FMT_I42016) { - fprintf(stderr, "%s can only scale 4:2:0 inputs\n", exec_name); - exit(EXIT_FAILURE); - } -#if CONFIG_LIBYUV - if (!stream->img) { - stream->img = - vpx_img_alloc(NULL, VPX_IMG_FMT_I42016, cfg->g_w, cfg->g_h, 16); - } - I420Scale_16( - (uint16_t *)img->planes[VPX_PLANE_Y], img->stride[VPX_PLANE_Y] / 2, - (uint16_t *)img->planes[VPX_PLANE_U], img->stride[VPX_PLANE_U] / 2, - (uint16_t *)img->planes[VPX_PLANE_V], img->stride[VPX_PLANE_V] / 2, - img->d_w, img->d_h, (uint16_t *)stream->img->planes[VPX_PLANE_Y], - stream->img->stride[VPX_PLANE_Y] / 2, - (uint16_t *)stream->img->planes[VPX_PLANE_U], - stream->img->stride[VPX_PLANE_U] / 2, - (uint16_t *)stream->img->planes[VPX_PLANE_V], - stream->img->stride[VPX_PLANE_V] / 2, stream->img->d_w, - stream->img->d_h, kFilterBox); - img = stream->img; -#else - stream->encoder.err = 1; - ctx_exit_on_error(&stream->encoder, - "Stream %d: Failed to encode frame.\n" - "Scaling disabled in this configuration. \n" - "To enable, configure with --enable-libyuv\n", - stream->index); -#endif - } - } -#endif - if (img && (img->d_w != cfg->g_w || img->d_h != cfg->g_h)) { - if (img->fmt != VPX_IMG_FMT_I420 && img->fmt != VPX_IMG_FMT_YV12) { - fprintf(stderr, "%s can only scale 4:2:0 8bpp inputs\n", exec_name); - exit(EXIT_FAILURE); - } -#if CONFIG_LIBYUV - if (!stream->img) - stream->img = - vpx_img_alloc(NULL, VPX_IMG_FMT_I420, cfg->g_w, cfg->g_h, 16); - I420Scale( - img->planes[VPX_PLANE_Y], img->stride[VPX_PLANE_Y], - img->planes[VPX_PLANE_U], img->stride[VPX_PLANE_U], - img->planes[VPX_PLANE_V], img->stride[VPX_PLANE_V], img->d_w, img->d_h, - stream->img->planes[VPX_PLANE_Y], stream->img->stride[VPX_PLANE_Y], - stream->img->planes[VPX_PLANE_U], stream->img->stride[VPX_PLANE_U], - stream->img->planes[VPX_PLANE_V], stream->img->stride[VPX_PLANE_V], - stream->img->d_w, stream->img->d_h, kFilterBox); - img = stream->img; -#else - stream->encoder.err = 1; - ctx_exit_on_error(&stream->encoder, - "Stream %d: Failed to encode frame.\n" - "Scaling disabled in this configuration. \n" - "To enable, configure with --enable-libyuv\n", - stream->index); -#endif - } - - vpx_usec_timer_start(&timer); - vpx_codec_encode(&stream->encoder, img, frame_start, - (unsigned long)(next_frame_start - frame_start), 0, - global->deadline); - vpx_usec_timer_mark(&timer); - stream->cx_time += vpx_usec_timer_elapsed(&timer); - ctx_exit_on_error(&stream->encoder, "Stream %d: Failed to encode frame", - stream->index); -} - -static void update_quantizer_histogram(struct stream_state *stream) { - if (stream->config.cfg.g_pass != VPX_RC_FIRST_PASS) { - int q; - - vpx_codec_control(&stream->encoder, VP8E_GET_LAST_QUANTIZER_64, &q); - ctx_exit_on_error(&stream->encoder, "Failed to read quantizer"); - stream->counts[q]++; - } -} - -static void get_cx_data(struct stream_state *stream, - struct VpxEncoderConfig *global, int *got_data) { - const vpx_codec_cx_pkt_t *pkt; - const struct vpx_codec_enc_cfg *cfg = &stream->config.cfg; - vpx_codec_iter_t iter = NULL; - - *got_data = 0; - while ((pkt = vpx_codec_get_cx_data(&stream->encoder, &iter))) { - static size_t fsize = 0; - static FileOffset ivf_header_pos = 0; - - switch (pkt->kind) { - case VPX_CODEC_CX_FRAME_PKT: - if (!(pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT)) { - stream->frames_out++; - } - if (!global->quiet) - fprintf(stderr, " %6luF", (unsigned long)pkt->data.frame.sz); - - update_rate_histogram(stream->rate_hist, cfg, pkt); -#if CONFIG_WEBM_IO - if (stream->config.write_webm) { - write_webm_block(&stream->webm_ctx, cfg, pkt); - } -#endif - if (!stream->config.write_webm) { - if (pkt->data.frame.partition_id <= 0) { - ivf_header_pos = ftello(stream->file); - fsize = pkt->data.frame.sz; - - ivf_write_frame_header(stream->file, pkt->data.frame.pts, fsize); - } else { - fsize += pkt->data.frame.sz; - - if (!(pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT)) { - const FileOffset currpos = ftello(stream->file); - fseeko(stream->file, ivf_header_pos, SEEK_SET); - ivf_write_frame_size(stream->file, fsize); - fseeko(stream->file, currpos, SEEK_SET); - } - } - - (void)fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz, - stream->file); - } - stream->nbytes += pkt->data.raw.sz; - - *got_data = 1; -#if CONFIG_DECODERS - if (global->test_decode != TEST_DECODE_OFF && !stream->mismatch_seen) { - vpx_codec_decode(&stream->decoder, pkt->data.frame.buf, - (unsigned int)pkt->data.frame.sz, NULL, 0); - if (stream->decoder.err) { - warn_or_exit_on_error(&stream->decoder, - global->test_decode == TEST_DECODE_FATAL, - "Failed to decode frame %d in stream %d", - stream->frames_out + 1, stream->index); - stream->mismatch_seen = stream->frames_out + 1; - } - } -#endif - break; - case VPX_CODEC_STATS_PKT: - stream->frames_out++; - stats_write(&stream->stats, pkt->data.twopass_stats.buf, - pkt->data.twopass_stats.sz); - stream->nbytes += pkt->data.raw.sz; - break; - case VPX_CODEC_PSNR_PKT: - - if (global->show_psnr) { - int i; - - stream->psnr_sse_total += pkt->data.psnr.sse[0]; - stream->psnr_samples_total += pkt->data.psnr.samples[0]; - for (i = 0; i < 4; i++) { - if (!global->quiet) - fprintf(stderr, "%.3f ", pkt->data.psnr.psnr[i]); - stream->psnr_totals[i] += pkt->data.psnr.psnr[i]; - } - stream->psnr_count++; - } - - break; - default: break; - } - } -} - -static void show_psnr(struct stream_state *stream, double peak) { - int i; - double ovpsnr; - - if (!stream->psnr_count) return; - - fprintf(stderr, "Stream %d PSNR (Overall/Avg/Y/U/V)", stream->index); - ovpsnr = sse_to_psnr((double)stream->psnr_samples_total, peak, - (double)stream->psnr_sse_total); - fprintf(stderr, " %.3f", ovpsnr); - - for (i = 0; i < 4; i++) { - fprintf(stderr, " %.3f", stream->psnr_totals[i] / stream->psnr_count); - } - fprintf(stderr, "\n"); -} - -static float usec_to_fps(uint64_t usec, unsigned int frames) { - return (float)(usec > 0 ? frames * 1000000.0 / (float)usec : 0); -} - -static void test_decode(struct stream_state *stream, - enum TestDecodeFatality fatal, - const VpxInterface *codec) { - vpx_image_t enc_img, dec_img; - - if (stream->mismatch_seen) return; - - /* Get the internal reference frame */ - if (strcmp(codec->name, "vp8") == 0) { - struct vpx_ref_frame ref_enc, ref_dec; - unsigned int aligned_width = (stream->config.cfg.g_w + 15u) & ~15u; - unsigned int aligned_height = (stream->config.cfg.g_h + 15u) & ~15u; - - vpx_img_alloc(&ref_enc.img, VPX_IMG_FMT_I420, aligned_width, aligned_height, - 1); - enc_img = ref_enc.img; - vpx_img_alloc(&ref_dec.img, VPX_IMG_FMT_I420, aligned_width, aligned_height, - 1); - dec_img = ref_dec.img; - - ref_enc.frame_type = VP8_LAST_FRAME; - ref_dec.frame_type = VP8_LAST_FRAME; - vpx_codec_control(&stream->encoder, VP8_COPY_REFERENCE, &ref_enc); - vpx_codec_control(&stream->decoder, VP8_COPY_REFERENCE, &ref_dec); - } else { - struct vp9_ref_frame ref_enc, ref_dec; - - ref_enc.idx = 0; - ref_dec.idx = 0; - vpx_codec_control(&stream->encoder, VP9_GET_REFERENCE, &ref_enc); - enc_img = ref_enc.img; - vpx_codec_control(&stream->decoder, VP9_GET_REFERENCE, &ref_dec); - dec_img = ref_dec.img; -#if CONFIG_VP9_HIGHBITDEPTH - if ((enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) != - (dec_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH)) { - if (enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) { - vpx_img_alloc(&enc_img, enc_img.fmt - VPX_IMG_FMT_HIGHBITDEPTH, - enc_img.d_w, enc_img.d_h, 16); - vpx_img_truncate_16_to_8(&enc_img, &ref_enc.img); - } - if (dec_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) { - vpx_img_alloc(&dec_img, dec_img.fmt - VPX_IMG_FMT_HIGHBITDEPTH, - dec_img.d_w, dec_img.d_h, 16); - vpx_img_truncate_16_to_8(&dec_img, &ref_dec.img); - } - } -#endif - } - ctx_exit_on_error(&stream->encoder, "Failed to get encoder reference frame"); - ctx_exit_on_error(&stream->decoder, "Failed to get decoder reference frame"); - - if (!compare_img(&enc_img, &dec_img)) { - int y[4], u[4], v[4]; -#if CONFIG_VP9_HIGHBITDEPTH - if (enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) { - find_mismatch_high(&enc_img, &dec_img, y, u, v); - } else { - find_mismatch(&enc_img, &dec_img, y, u, v); - } -#else - find_mismatch(&enc_img, &dec_img, y, u, v); -#endif - stream->decoder.err = 1; - warn_or_exit_on_error(&stream->decoder, fatal == TEST_DECODE_FATAL, - "Stream %d: Encode/decode mismatch on frame %d at" - " Y[%d, %d] {%d/%d}," - " U[%d, %d] {%d/%d}," - " V[%d, %d] {%d/%d}", - stream->index, stream->frames_out, y[0], y[1], y[2], - y[3], u[0], u[1], u[2], u[3], v[0], v[1], v[2], v[3]); - stream->mismatch_seen = stream->frames_out; - } - - vpx_img_free(&enc_img); - vpx_img_free(&dec_img); -} - -static void print_time(const char *label, int64_t etl) { - int64_t hours; - int64_t mins; - int64_t secs; - - if (etl >= 0) { - hours = etl / 3600; - etl -= hours * 3600; - mins = etl / 60; - etl -= mins * 60; - secs = etl; - - fprintf(stderr, "[%3s %2" PRId64 ":%02" PRId64 ":%02" PRId64 "] ", label, - hours, mins, secs); - } else { - fprintf(stderr, "[%3s unknown] ", label); - } -} - -int main(int argc, const char **argv_) { - int pass; - vpx_image_t raw; -#if CONFIG_VP9_HIGHBITDEPTH - vpx_image_t raw_shift; - int allocated_raw_shift = 0; - int use_16bit_internal = 0; - int input_shift = 0; -#endif - int frame_avail, got_data; - - struct VpxInputContext input; - struct VpxEncoderConfig global; - struct stream_state *streams = NULL; - char **argv, **argi; - uint64_t cx_time = 0; - int stream_cnt = 0; - int res = 0; - - memset(&input, 0, sizeof(input)); - memset(&raw, 0, sizeof(raw)); - exec_name = argv_[0]; - - /* Setup default input stream settings */ - input.framerate.numerator = 30; - input.framerate.denominator = 1; - input.only_i420 = 1; - input.bit_depth = 0; - - /* First parse the global configuration values, because we want to apply - * other parameters on top of the default configuration provided by the - * codec. - */ - argv = argv_dup(argc - 1, argv_ + 1); - if (!argv) { - fprintf(stderr, "Error allocating argument list\n"); - return EXIT_FAILURE; - } - parse_global_config(&global, argv); - - if (argc < 3) usage_exit(); - - switch (global.color_type) { - case I420: input.fmt = VPX_IMG_FMT_I420; break; - case I422: input.fmt = VPX_IMG_FMT_I422; break; - case I444: input.fmt = VPX_IMG_FMT_I444; break; - case I440: input.fmt = VPX_IMG_FMT_I440; break; - case YV12: input.fmt = VPX_IMG_FMT_YV12; break; - case NV12: input.fmt = VPX_IMG_FMT_NV12; break; - } - - { - /* Now parse each stream's parameters. Using a local scope here - * due to the use of 'stream' as loop variable in FOREACH_STREAM - * loops - */ - struct stream_state *stream = NULL; - - do { - stream = new_stream(&global, stream); - stream_cnt++; - if (!streams) streams = stream; - } while (parse_stream_params(&global, stream, argv)); - } - - /* Check for unrecognized options */ - for (argi = argv; *argi; argi++) - if (argi[0][0] == '-' && argi[0][1]) - die("Error: Unrecognized option %s\n", *argi); - - FOREACH_STREAM(check_encoder_config(global.disable_warning_prompt, &global, - &stream->config.cfg);); - - /* Handle non-option arguments */ - input.filename = argv[0]; - - if (!input.filename) { - fprintf(stderr, "No input file specified!\n"); - usage_exit(); - } - - /* Decide if other chroma subsamplings than 4:2:0 are supported */ - if (global.codec->fourcc == VP9_FOURCC) input.only_i420 = 0; - - for (pass = global.pass ? global.pass - 1 : 0; pass < global.passes; pass++) { - int frames_in = 0, seen_frames = 0; - int64_t estimated_time_left = -1; - int64_t average_rate = -1; - int64_t lagged_count = 0; - - open_input_file(&input); - - /* If the input file doesn't specify its w/h (raw files), try to get - * the data from the first stream's configuration. - */ - if (!input.width || !input.height) { - FOREACH_STREAM({ - if (stream->config.cfg.g_w && stream->config.cfg.g_h) { - input.width = stream->config.cfg.g_w; - input.height = stream->config.cfg.g_h; - break; - } - }); - } - - /* Update stream configurations from the input file's parameters */ - if (!input.width || !input.height) - fatal( - "Specify stream dimensions with --width (-w) " - " and --height (-h)"); - - /* If input file does not specify bit-depth but input-bit-depth parameter - * exists, assume that to be the input bit-depth. However, if the - * input-bit-depth paramter does not exist, assume the input bit-depth - * to be the same as the codec bit-depth. - */ - if (!input.bit_depth) { - FOREACH_STREAM({ - if (stream->config.cfg.g_input_bit_depth) - input.bit_depth = stream->config.cfg.g_input_bit_depth; - else - input.bit_depth = stream->config.cfg.g_input_bit_depth = - (int)stream->config.cfg.g_bit_depth; - }); - if (input.bit_depth > 8) input.fmt |= VPX_IMG_FMT_HIGHBITDEPTH; - } else { - FOREACH_STREAM( - { stream->config.cfg.g_input_bit_depth = input.bit_depth; }); - } - - FOREACH_STREAM(set_stream_dimensions(stream, input.width, input.height)); - FOREACH_STREAM(validate_stream_config(stream, &global)); - - /* Ensure that --passes and --pass are consistent. If --pass is set and - * --passes=2, ensure --fpf was set. - */ - if (global.pass && global.passes == 2) - FOREACH_STREAM({ - if (!stream->config.stats_fn) - die("Stream %d: Must specify --fpf when --pass=%d" - " and --passes=2\n", - stream->index, global.pass); - }); - -#if !CONFIG_WEBM_IO - FOREACH_STREAM({ - if (stream->config.write_webm) { - stream->config.write_webm = 0; - warn( - "vpxenc was compiled without WebM container support." - "Producing IVF output"); - } - }); -#endif - - /* Use the frame rate from the file only if none was specified - * on the command-line. - */ - if (!global.have_framerate) { - global.framerate.num = input.framerate.numerator; - global.framerate.den = input.framerate.denominator; - FOREACH_STREAM(stream->config.cfg.g_timebase.den = global.framerate.num; - stream->config.cfg.g_timebase.num = global.framerate.den); - } - - /* Show configuration */ - if (global.verbose && pass == 0) - FOREACH_STREAM(show_stream_config(stream, &global, &input)); - - if (pass == (global.pass ? global.pass - 1 : 0)) { - // The Y4M reader does its own allocation. - if (input.file_type != FILE_TYPE_Y4M) { - vpx_img_alloc(&raw, input.fmt, input.width, input.height, 32); - } - FOREACH_STREAM(stream->rate_hist = init_rate_histogram( - &stream->config.cfg, &global.framerate)); - } - - FOREACH_STREAM(setup_pass(stream, &global, pass)); - FOREACH_STREAM( - open_output_file(stream, &global, &input.pixel_aspect_ratio)); - FOREACH_STREAM(initialize_encoder(stream, &global)); - -#if CONFIG_VP9_HIGHBITDEPTH - if (strcmp(global.codec->name, "vp9") == 0) { - // Check to see if at least one stream uses 16 bit internal. - // Currently assume that the bit_depths for all streams using - // highbitdepth are the same. - FOREACH_STREAM({ - if (stream->config.use_16bit_internal) { - use_16bit_internal = 1; - } - if (stream->config.cfg.g_profile == 0) { - input_shift = 0; - } else { - input_shift = (int)stream->config.cfg.g_bit_depth - - stream->config.cfg.g_input_bit_depth; - } - }); - } -#endif - - frame_avail = 1; - got_data = 0; - - while (frame_avail || got_data) { - struct vpx_usec_timer timer; - - if (!global.limit || frames_in < global.limit) { - frame_avail = read_frame(&input, &raw); - - if (frame_avail) frames_in++; - seen_frames = - frames_in > global.skip_frames ? frames_in - global.skip_frames : 0; - - if (!global.quiet) { - float fps = usec_to_fps(cx_time, seen_frames); - fprintf(stderr, "\rPass %d/%d ", pass + 1, global.passes); - - if (stream_cnt == 1) - fprintf(stderr, "frame %4d/%-4d %7" PRId64 "B ", frames_in, - streams->frames_out, (int64_t)streams->nbytes); - else - fprintf(stderr, "frame %4d ", frames_in); - - fprintf(stderr, "%7" PRId64 " %s %.2f %s ", - cx_time > 9999999 ? cx_time / 1000 : cx_time, - cx_time > 9999999 ? "ms" : "us", fps >= 1.0 ? fps : fps * 60, - fps >= 1.0 ? "fps" : "fpm"); - print_time("ETA", estimated_time_left); - } - - } else - frame_avail = 0; - - if (frames_in > global.skip_frames) { -#if CONFIG_VP9_HIGHBITDEPTH - vpx_image_t *frame_to_encode; - if (input_shift || (use_16bit_internal && input.bit_depth == 8)) { - assert(use_16bit_internal); - // Input bit depth and stream bit depth do not match, so up - // shift frame to stream bit depth - if (!allocated_raw_shift) { - vpx_img_alloc(&raw_shift, raw.fmt | VPX_IMG_FMT_HIGHBITDEPTH, - input.width, input.height, 32); - allocated_raw_shift = 1; - } - vpx_img_upshift(&raw_shift, &raw, input_shift); - frame_to_encode = &raw_shift; - } else { - frame_to_encode = &raw; - } - vpx_usec_timer_start(&timer); - if (use_16bit_internal) { - assert(frame_to_encode->fmt & VPX_IMG_FMT_HIGHBITDEPTH); - FOREACH_STREAM({ - if (stream->config.use_16bit_internal) - encode_frame(stream, &global, - frame_avail ? frame_to_encode : NULL, frames_in); - else - assert(0); - }); - } else { - assert((frame_to_encode->fmt & VPX_IMG_FMT_HIGHBITDEPTH) == 0); - FOREACH_STREAM(encode_frame(stream, &global, - frame_avail ? frame_to_encode : NULL, - frames_in)); - } -#else - vpx_usec_timer_start(&timer); - FOREACH_STREAM(encode_frame(stream, &global, frame_avail ? &raw : NULL, - frames_in)); -#endif - vpx_usec_timer_mark(&timer); - cx_time += vpx_usec_timer_elapsed(&timer); - - FOREACH_STREAM(update_quantizer_histogram(stream)); - - got_data = 0; - FOREACH_STREAM(get_cx_data(stream, &global, &got_data)); - - if (!got_data && input.length && streams != NULL && - !streams->frames_out) { - lagged_count = global.limit ? seen_frames : ftello(input.file); - } else if (input.length) { - int64_t remaining; - int64_t rate; - - if (global.limit) { - const int64_t frame_in_lagged = (seen_frames - lagged_count) * 1000; - - rate = cx_time ? frame_in_lagged * (int64_t)1000000 / cx_time : 0; - remaining = 1000 * (global.limit - global.skip_frames - - seen_frames + lagged_count); - } else { - const int64_t input_pos = ftello(input.file); - const int64_t input_pos_lagged = input_pos - lagged_count; - - rate = cx_time ? input_pos_lagged * (int64_t)1000000 / cx_time : 0; - remaining = input.length - input_pos + lagged_count; - } - - average_rate = - (average_rate <= 0) ? rate : (average_rate * 7 + rate) / 8; - estimated_time_left = average_rate ? remaining / average_rate : -1; - } - - if (got_data && global.test_decode != TEST_DECODE_OFF) - FOREACH_STREAM(test_decode(stream, global.test_decode, global.codec)); - } - - fflush(stdout); - if (!global.quiet) fprintf(stderr, "\033[K"); - } - - if (stream_cnt > 1) fprintf(stderr, "\n"); - - if (!global.quiet) { - FOREACH_STREAM(fprintf( - stderr, - "\rPass %d/%d frame %4d/%-4d %7" PRId64 "B %7" PRId64 "b/f %7" PRId64 - "b/s %7" PRId64 " %s (%.2f fps)\033[K\n", - pass + 1, global.passes, frames_in, stream->frames_out, - (int64_t)stream->nbytes, - seen_frames ? (int64_t)(stream->nbytes * 8 / seen_frames) : 0, - seen_frames - ? (int64_t)stream->nbytes * 8 * (int64_t)global.framerate.num / - global.framerate.den / seen_frames - : 0, - stream->cx_time > 9999999 ? stream->cx_time / 1000 : stream->cx_time, - stream->cx_time > 9999999 ? "ms" : "us", - usec_to_fps(stream->cx_time, seen_frames))); - } - - if (global.show_psnr) { - if (global.codec->fourcc == VP9_FOURCC) { - FOREACH_STREAM( - show_psnr(stream, (1 << stream->config.cfg.g_input_bit_depth) - 1)); - } else { - FOREACH_STREAM(show_psnr(stream, 255.0)); - } - } - - FOREACH_STREAM(vpx_codec_destroy(&stream->encoder)); - - if (global.test_decode != TEST_DECODE_OFF) { - FOREACH_STREAM(vpx_codec_destroy(&stream->decoder)); - } - - close_input_file(&input); - - if (global.test_decode == TEST_DECODE_FATAL) { - FOREACH_STREAM(res |= stream->mismatch_seen); - } - FOREACH_STREAM(close_output_file(stream, global.codec->fourcc)); - - FOREACH_STREAM(stats_close(&stream->stats, global.passes - 1)); - - if (global.pass) break; - } - - if (global.show_q_hist_buckets) - FOREACH_STREAM( - show_q_histogram(stream->counts, global.show_q_hist_buckets)); - - if (global.show_rate_hist_buckets) - FOREACH_STREAM(show_rate_histogram(stream->rate_hist, &stream->config.cfg, - global.show_rate_hist_buckets)); - FOREACH_STREAM(destroy_rate_histogram(stream->rate_hist)); - -#if CONFIG_INTERNAL_STATS - /* TODO(jkoleszar): This doesn't belong in this executable. Do it for now, - * to match some existing utilities. - */ - if (!(global.pass == 1 && global.passes == 2)) - FOREACH_STREAM({ - FILE *f = fopen("opsnr.stt", "a"); - if (stream->mismatch_seen) { - fprintf(f, "First mismatch occurred in frame %d\n", - stream->mismatch_seen); - } else { - fprintf(f, "No mismatch detected in recon buffers\n"); - } - fclose(f); - }); -#endif - -#if CONFIG_VP9_HIGHBITDEPTH - if (allocated_raw_shift) vpx_img_free(&raw_shift); -#endif - vpx_img_free(&raw); - free(argv); - free(streams); - return res ? EXIT_FAILURE : EXIT_SUCCESS; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/vpxenc.h b/presentation/src/main/cpp/third_party/libvpx/vpxenc.h deleted file mode 100644 index be54840f..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpxenc.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_VPXENC_H_ -#define VPX_VPXENC_H_ - -#include "vpx/vpx_encoder.h" - -#ifdef __cplusplus -extern "C" { -#endif - -enum TestDecodeFatality { - TEST_DECODE_OFF, - TEST_DECODE_FATAL, - TEST_DECODE_WARN, -}; - -typedef enum { - I420, // 4:2:0 8+ bit-depth - I422, // 4:2:2 8+ bit-depth - I444, // 4:4:4 8+ bit-depth - I440, // 4:4:0 8+ bit-depth - YV12, // 4:2:0 with uv flipped, only 8-bit depth - NV12, // 4:2:0 with uv interleaved -} ColorInputType; - -struct VpxInterface; - -/* Configuration elements common to all streams. */ -struct VpxEncoderConfig { - const struct VpxInterface *codec; - int passes; - int pass; - int usage; - int deadline; - ColorInputType color_type; - int quiet; - int verbose; - int limit; - int skip_frames; - int show_psnr; - enum TestDecodeFatality test_decode; - int have_framerate; - struct vpx_rational framerate; - int out_part; - int debug; - int show_q_hist_buckets; - int show_rate_hist_buckets; - int disable_warnings; - int disable_warning_prompt; - int experimental_bitstream; -}; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPXENC_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/vpxstats.c b/presentation/src/main/cpp/third_party/libvpx/vpxstats.c deleted file mode 100644 index c0dd14e4..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpxstats.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./vpxstats.h" - -#include -#include -#include - -#include "./tools_common.h" - -int stats_open_file(stats_io_t *stats, const char *fpf, int pass) { - int res; - stats->pass = pass; - - if (pass == 0) { - stats->file = fopen(fpf, "wb"); - stats->buf.sz = 0; - stats->buf.buf = NULL; - res = (stats->file != NULL); - } else { - size_t nbytes; - - stats->file = fopen(fpf, "rb"); - - if (stats->file == NULL) fatal("First-pass stats file does not exist!"); - - if (fseek(stats->file, 0, SEEK_END)) - fatal("First-pass stats file must be seekable!"); - - stats->buf.sz = stats->buf_alloc_sz = ftell(stats->file); - rewind(stats->file); - - stats->buf.buf = malloc(stats->buf_alloc_sz); - - if (!stats->buf.buf) - fatal("Failed to allocate first-pass stats buffer (%u bytes)", - (unsigned int)stats->buf_alloc_sz); - - nbytes = fread(stats->buf.buf, 1, stats->buf.sz, stats->file); - res = (nbytes == stats->buf.sz); - } - - return res; -} - -int stats_open_mem(stats_io_t *stats, int pass) { - int res; - stats->pass = pass; - - if (!pass) { - stats->buf.sz = 0; - stats->buf_alloc_sz = 64 * 1024; - stats->buf.buf = malloc(stats->buf_alloc_sz); - } - - stats->buf_ptr = stats->buf.buf; - res = (stats->buf.buf != NULL); - return res; -} - -void stats_close(stats_io_t *stats, int last_pass) { - if (stats->file) { - if (stats->pass == last_pass) { - free(stats->buf.buf); - } - - fclose(stats->file); - stats->file = NULL; - } else { - if (stats->pass == last_pass) free(stats->buf.buf); - } -} - -void stats_write(stats_io_t *stats, const void *pkt, size_t len) { - if (stats->file) { - (void)fwrite(pkt, 1, len, stats->file); - } else { - if (stats->buf.sz + len > stats->buf_alloc_sz) { - size_t new_sz = stats->buf_alloc_sz + 64 * 1024; - char *new_ptr = realloc(stats->buf.buf, new_sz); - - if (new_ptr) { - stats->buf_ptr = new_ptr + (stats->buf_ptr - (char *)stats->buf.buf); - stats->buf.buf = new_ptr; - stats->buf_alloc_sz = new_sz; - } else { - fatal("Failed to realloc firstpass stats buffer."); - } - } - - memcpy(stats->buf_ptr, pkt, len); - stats->buf.sz += len; - stats->buf_ptr += len; - } -} - -vpx_fixed_buf_t stats_get(stats_io_t *stats) { return stats->buf; } diff --git a/presentation/src/main/cpp/third_party/libvpx/vpxstats.h b/presentation/src/main/cpp/third_party/libvpx/vpxstats.h deleted file mode 100644 index 3625ee32..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/vpxstats.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_VPXSTATS_H_ -#define VPX_VPXSTATS_H_ - -#include - -#include "vpx/vpx_encoder.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* This structure is used to abstract the different ways of handling - * first pass statistics - */ -typedef struct { - vpx_fixed_buf_t buf; - int pass; - FILE *file; - char *buf_ptr; - size_t buf_alloc_sz; -} stats_io_t; - -int stats_open_file(stats_io_t *stats, const char *fpf, int pass); -int stats_open_mem(stats_io_t *stats, int pass); -void stats_close(stats_io_t *stats, int last_pass); -void stats_write(stats_io_t *stats, const void *pkt, size_t len); -vpx_fixed_buf_t stats_get(stats_io_t *stats); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_VPXSTATS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/warnings.c b/presentation/src/main/cpp/third_party/libvpx/warnings.c deleted file mode 100644 index 3e6e7025..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/warnings.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./warnings.h" - -#include -#include -#include -#include - -#include "vpx/vpx_encoder.h" - -#include "./tools_common.h" -#include "./vpxenc.h" - -static const char quantizer_warning_string[] = - "Bad quantizer values. Quantizer values should not be equal, and should " - "differ by at least 8."; -static const char lag_in_frames_with_realtime[] = - "Lag in frames is ignored when deadline is set to realtime for cbr mode."; - -struct WarningListNode { - const char *warning_string; - struct WarningListNode *next_warning; -}; - -struct WarningList { - struct WarningListNode *warning_node; -}; - -static void add_warning(const char *warning_string, - struct WarningList *warning_list) { - struct WarningListNode **node = &warning_list->warning_node; - - struct WarningListNode *new_node = malloc(sizeof(*new_node)); - if (new_node == NULL) { - fatal("Unable to allocate warning node."); - } - - new_node->warning_string = warning_string; - new_node->next_warning = NULL; - - while (*node != NULL) node = &(*node)->next_warning; - - *node = new_node; -} - -static void free_warning_list(struct WarningList *warning_list) { - while (warning_list->warning_node != NULL) { - struct WarningListNode *const node = warning_list->warning_node; - warning_list->warning_node = node->next_warning; - free(node); - } -} - -static int continue_prompt(int num_warnings) { - int c; - fprintf(stderr, - "%d encoder configuration warning(s). Continue? (y to continue) ", - num_warnings); - c = getchar(); - return c == 'y'; -} - -static void check_quantizer(int min_q, int max_q, - struct WarningList *warning_list) { - const int lossless = min_q == 0 && max_q == 0; - if (!lossless && (min_q == max_q || abs(max_q - min_q) < 8)) - add_warning(quantizer_warning_string, warning_list); -} - -static void check_lag_in_frames_realtime_deadline( - int lag_in_frames, int deadline, int rc_end_usage, - struct WarningList *warning_list) { - if (deadline == VPX_DL_REALTIME && lag_in_frames != 0 && rc_end_usage == 1) - add_warning(lag_in_frames_with_realtime, warning_list); -} - -void check_encoder_config(int disable_prompt, - const struct VpxEncoderConfig *global_config, - const struct vpx_codec_enc_cfg *stream_config) { - int num_warnings = 0; - struct WarningListNode *warning = NULL; - struct WarningList warning_list = { 0 }; - - check_quantizer(stream_config->rc_min_quantizer, - stream_config->rc_max_quantizer, &warning_list); - check_lag_in_frames_realtime_deadline( - stream_config->g_lag_in_frames, global_config->deadline, - stream_config->rc_end_usage, &warning_list); - /* Count and print warnings. */ - for (warning = warning_list.warning_node; warning != NULL; - warning = warning->next_warning, ++num_warnings) { - warn("%s", warning->warning_string); - } - - free_warning_list(&warning_list); - - if (num_warnings) { - if (!disable_prompt && !continue_prompt(num_warnings)) exit(EXIT_FAILURE); - } -} diff --git a/presentation/src/main/cpp/third_party/libvpx/warnings.h b/presentation/src/main/cpp/third_party/libvpx/warnings.h deleted file mode 100644 index 15558c64..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/warnings.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_WARNINGS_H_ -#define VPX_WARNINGS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -struct vpx_codec_enc_cfg; -struct VpxEncoderConfig; - -/* - * Checks config for improperly used settings. Warns user upon encountering - * settings that will lead to poor output quality. Prompts user to continue - * when warnings are issued. - */ -void check_encoder_config(int disable_prompt, - const struct VpxEncoderConfig *global_config, - const struct vpx_codec_enc_cfg *stream_config); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_WARNINGS_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/webmdec.cc b/presentation/src/main/cpp/third_party/libvpx/webmdec.cc deleted file mode 100644 index f7671bb6..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/webmdec.cc +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "./webmdec.h" - -#include -#include - -#include "third_party/libwebm/mkvparser/mkvparser.h" -#include "third_party/libwebm/mkvparser/mkvreader.h" - -namespace { - -void reset(struct WebmInputContext *const webm_ctx) { - if (webm_ctx->reader != nullptr) { - mkvparser::MkvReader *const reader = - reinterpret_cast(webm_ctx->reader); - delete reader; - } - if (webm_ctx->segment != nullptr) { - mkvparser::Segment *const segment = - reinterpret_cast(webm_ctx->segment); - delete segment; - } - if (webm_ctx->buffer != nullptr) { - delete[] webm_ctx->buffer; - } - webm_ctx->reader = nullptr; - webm_ctx->segment = nullptr; - webm_ctx->buffer = nullptr; - webm_ctx->cluster = nullptr; - webm_ctx->block_entry = nullptr; - webm_ctx->block = nullptr; - webm_ctx->block_frame_index = 0; - webm_ctx->video_track_index = 0; - webm_ctx->timestamp_ns = 0; - webm_ctx->is_key_frame = false; -} - -void get_first_cluster(struct WebmInputContext *const webm_ctx) { - mkvparser::Segment *const segment = - reinterpret_cast(webm_ctx->segment); - const mkvparser::Cluster *const cluster = segment->GetFirst(); - webm_ctx->cluster = cluster; -} - -void rewind_and_reset(struct WebmInputContext *const webm_ctx, - struct VpxInputContext *const vpx_ctx) { - rewind(vpx_ctx->file); - reset(webm_ctx); -} - -} // namespace - -int file_is_webm(struct WebmInputContext *webm_ctx, - struct VpxInputContext *vpx_ctx) { - mkvparser::MkvReader *const reader = new mkvparser::MkvReader(vpx_ctx->file); - webm_ctx->reader = reader; - webm_ctx->reached_eos = 0; - - mkvparser::EBMLHeader header; - long long pos = 0; - if (header.Parse(reader, pos) < 0) { - rewind_and_reset(webm_ctx, vpx_ctx); - return 0; - } - - mkvparser::Segment *segment; - if (mkvparser::Segment::CreateInstance(reader, pos, segment)) { - rewind_and_reset(webm_ctx, vpx_ctx); - return 0; - } - webm_ctx->segment = segment; - if (segment->Load() < 0) { - rewind_and_reset(webm_ctx, vpx_ctx); - return 0; - } - - const mkvparser::Tracks *const tracks = segment->GetTracks(); - const mkvparser::VideoTrack *video_track = nullptr; - for (unsigned long i = 0; i < tracks->GetTracksCount(); ++i) { - const mkvparser::Track *const track = tracks->GetTrackByIndex(i); - if (track->GetType() == mkvparser::Track::kVideo) { - video_track = static_cast(track); - webm_ctx->video_track_index = static_cast(track->GetNumber()); - break; - } - } - - if (video_track == nullptr || video_track->GetCodecId() == nullptr) { - rewind_and_reset(webm_ctx, vpx_ctx); - return 0; - } - - if (!strncmp(video_track->GetCodecId(), "V_VP8", 5)) { - vpx_ctx->fourcc = VP8_FOURCC; - } else if (!strncmp(video_track->GetCodecId(), "V_VP9", 5)) { - vpx_ctx->fourcc = VP9_FOURCC; - } else { - rewind_and_reset(webm_ctx, vpx_ctx); - return 0; - } - - vpx_ctx->framerate.denominator = 0; - vpx_ctx->framerate.numerator = 0; - vpx_ctx->width = static_cast(video_track->GetWidth()); - vpx_ctx->height = static_cast(video_track->GetHeight()); - - get_first_cluster(webm_ctx); - - return 1; -} - -int webm_read_frame(struct WebmInputContext *webm_ctx, uint8_t **buffer, - size_t *buffer_size) { - // This check is needed for frame parallel decoding, in which case this - // function could be called even after it has reached end of input stream. - if (webm_ctx->reached_eos) { - return 1; - } - mkvparser::Segment *const segment = - reinterpret_cast(webm_ctx->segment); - const mkvparser::Cluster *cluster = - reinterpret_cast(webm_ctx->cluster); - const mkvparser::Block *block = - reinterpret_cast(webm_ctx->block); - const mkvparser::BlockEntry *block_entry = - reinterpret_cast(webm_ctx->block_entry); - bool block_entry_eos = false; - do { - long status = 0; - bool get_new_block = false; - if (block_entry == nullptr && !block_entry_eos) { - status = cluster->GetFirst(block_entry); - get_new_block = true; - } else if (block_entry_eos || block_entry->EOS()) { - cluster = segment->GetNext(cluster); - if (cluster == nullptr || cluster->EOS()) { - *buffer_size = 0; - webm_ctx->reached_eos = 1; - return 1; - } - status = cluster->GetFirst(block_entry); - block_entry_eos = false; - get_new_block = true; - } else if (block == nullptr || - webm_ctx->block_frame_index == block->GetFrameCount() || - block->GetTrackNumber() != webm_ctx->video_track_index) { - status = cluster->GetNext(block_entry, block_entry); - if (block_entry == nullptr || block_entry->EOS()) { - block_entry_eos = true; - continue; - } - get_new_block = true; - } - if (status || block_entry == nullptr) { - return -1; - } - if (get_new_block) { - block = block_entry->GetBlock(); - if (block == nullptr) return -1; - webm_ctx->block_frame_index = 0; - } - } while (block_entry_eos || - block->GetTrackNumber() != webm_ctx->video_track_index); - - webm_ctx->cluster = cluster; - webm_ctx->block_entry = block_entry; - webm_ctx->block = block; - - const mkvparser::Block::Frame &frame = - block->GetFrame(webm_ctx->block_frame_index); - ++webm_ctx->block_frame_index; - if (frame.len > static_cast(*buffer_size)) { - delete[] * buffer; - *buffer = new uint8_t[frame.len]; - if (*buffer == nullptr) { - return -1; - } - webm_ctx->buffer = *buffer; - } - *buffer_size = frame.len; - webm_ctx->timestamp_ns = block->GetTime(cluster); - webm_ctx->is_key_frame = block->IsKey(); - - mkvparser::MkvReader *const reader = - reinterpret_cast(webm_ctx->reader); - return frame.Read(reader, *buffer) ? -1 : 0; -} - -int webm_guess_framerate(struct WebmInputContext *webm_ctx, - struct VpxInputContext *vpx_ctx) { - uint32_t i = 0; - uint8_t *buffer = nullptr; - size_t buffer_size = 0; - while (webm_ctx->timestamp_ns < 1000000000 && i < 50) { - if (webm_read_frame(webm_ctx, &buffer, &buffer_size)) { - break; - } - ++i; - } - vpx_ctx->framerate.numerator = (i - 1) * 1000000; - vpx_ctx->framerate.denominator = - static_cast(webm_ctx->timestamp_ns / 1000); - delete[] buffer; - // webm_ctx->buffer is assigned to the buffer pointer in webm_read_frame(). - webm_ctx->buffer = nullptr; - - get_first_cluster(webm_ctx); - webm_ctx->block = nullptr; - webm_ctx->block_entry = nullptr; - webm_ctx->block_frame_index = 0; - webm_ctx->timestamp_ns = 0; - webm_ctx->reached_eos = 0; - - return 0; -} - -void webm_free(struct WebmInputContext *webm_ctx) { reset(webm_ctx); } diff --git a/presentation/src/main/cpp/third_party/libvpx/webmdec.h b/presentation/src/main/cpp/third_party/libvpx/webmdec.h deleted file mode 100644 index 6ae7ee16..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/webmdec.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_WEBMDEC_H_ -#define VPX_WEBMDEC_H_ - -#include "./tools_common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct VpxInputContext; - -struct WebmInputContext { - void *reader; - void *segment; - uint8_t *buffer; - const void *cluster; - const void *block_entry; - const void *block; - int block_frame_index; - int video_track_index; - int64_t timestamp_ns; - int is_key_frame; - int reached_eos; -}; - -// Checks if the input is a WebM file. If so, initializes WebMInputContext so -// that webm_read_frame can be called to retrieve a video frame. -// Returns 1 on success and 0 on failure or input is not WebM file. -// TODO(vigneshv): Refactor this function into two smaller functions specific -// to their task. -int file_is_webm(struct WebmInputContext *webm_ctx, - struct VpxInputContext *vpx_ctx); - -// Reads a WebM Video Frame. Memory for the buffer is created, owned and managed -// by this function. For the first call, |buffer| should be NULL and -// |*buffer_size| should be 0. Once all the frames are read and used, -// webm_free() should be called, otherwise there will be a leak. -// Parameters: -// webm_ctx - WebmInputContext object -// buffer - pointer where the frame data will be filled. -// buffer_size - pointer to buffer size. -// Return values: -// 0 - Success -// 1 - End of Stream -// -1 - Error -int webm_read_frame(struct WebmInputContext *webm_ctx, uint8_t **buffer, - size_t *buffer_size); - -// Guesses the frame rate of the input file based on the container timestamps. -int webm_guess_framerate(struct WebmInputContext *webm_ctx, - struct VpxInputContext *vpx_ctx); - -// Resets the WebMInputContext. -void webm_free(struct WebmInputContext *webm_ctx); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_WEBMDEC_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/webmenc.cc b/presentation/src/main/cpp/third_party/libvpx/webmenc.cc deleted file mode 100644 index c718ab5a..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/webmenc.cc +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "./webmenc.h" - -#include - -#include "third_party/libwebm/mkvmuxer/mkvmuxer.h" -#include "third_party/libwebm/mkvmuxer/mkvmuxerutil.h" -#include "third_party/libwebm/mkvmuxer/mkvwriter.h" - -namespace { -const uint64_t kDebugTrackUid = 0xDEADBEEF; -const int kVideoTrackNumber = 1; -} // namespace - -void write_webm_file_header(struct WebmOutputContext *webm_ctx, - const vpx_codec_enc_cfg_t *cfg, - stereo_format_t stereo_fmt, unsigned int fourcc, - const struct VpxRational *par) { - mkvmuxer::MkvWriter *const writer = new mkvmuxer::MkvWriter(webm_ctx->stream); - mkvmuxer::Segment *const segment = new mkvmuxer::Segment(); - segment->Init(writer); - segment->set_mode(mkvmuxer::Segment::kFile); - segment->OutputCues(true); - - mkvmuxer::SegmentInfo *const info = segment->GetSegmentInfo(); - const uint64_t kTimecodeScale = 1000000; - info->set_timecode_scale(kTimecodeScale); - std::string version = "vpxenc"; - if (!webm_ctx->debug) { - version.append(std::string(" ") + vpx_codec_version_str()); - } - info->set_writing_app(version.c_str()); - - const uint64_t video_track_id = - segment->AddVideoTrack(static_cast(cfg->g_w), - static_cast(cfg->g_h), kVideoTrackNumber); - mkvmuxer::VideoTrack *const video_track = static_cast( - segment->GetTrackByNumber(video_track_id)); - video_track->SetStereoMode(stereo_fmt); - const char *codec_id; - switch (fourcc) { - case VP8_FOURCC: codec_id = "V_VP8"; break; - case VP9_FOURCC: - default: codec_id = "V_VP9"; break; - } - video_track->set_codec_id(codec_id); - if (par->numerator > 1 || par->denominator > 1) { - // TODO(fgalligan): Add support of DisplayUnit, Display Aspect Ratio type - // to WebM format. - const uint64_t display_width = static_cast( - ((cfg->g_w * par->numerator * 1.0) / par->denominator) + .5); - video_track->set_display_width(display_width); - video_track->set_display_height(cfg->g_h); - } - if (webm_ctx->debug) { - video_track->set_uid(kDebugTrackUid); - } - webm_ctx->writer = writer; - webm_ctx->segment = segment; -} - -void write_webm_block(struct WebmOutputContext *webm_ctx, - const vpx_codec_enc_cfg_t *cfg, - const vpx_codec_cx_pkt_t *pkt) { - mkvmuxer::Segment *const segment = - reinterpret_cast(webm_ctx->segment); - int64_t pts_ns = pkt->data.frame.pts * 1000000000ll * cfg->g_timebase.num / - cfg->g_timebase.den; - if (pts_ns <= webm_ctx->last_pts_ns) pts_ns = webm_ctx->last_pts_ns + 1000000; - webm_ctx->last_pts_ns = pts_ns; - - segment->AddFrame(static_cast(pkt->data.frame.buf), - pkt->data.frame.sz, kVideoTrackNumber, pts_ns, - pkt->data.frame.flags & VPX_FRAME_IS_KEY); -} - -void write_webm_file_footer(struct WebmOutputContext *webm_ctx) { - mkvmuxer::MkvWriter *const writer = - reinterpret_cast(webm_ctx->writer); - mkvmuxer::Segment *const segment = - reinterpret_cast(webm_ctx->segment); - segment->Finalize(); - delete segment; - delete writer; - webm_ctx->writer = nullptr; - webm_ctx->segment = nullptr; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/webmenc.h b/presentation/src/main/cpp/third_party/libvpx/webmenc.h deleted file mode 100644 index 4176e820..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/webmenc.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2013 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef VPX_WEBMENC_H_ -#define VPX_WEBMENC_H_ - -#include -#include - -#include "tools_common.h" -#include "vpx/vpx_encoder.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct WebmOutputContext { - int debug; - FILE *stream; - int64_t last_pts_ns; - void *writer; - void *segment; -}; - -/* Stereo 3D packed frame format */ -typedef enum stereo_format { - STEREO_FORMAT_MONO = 0, - STEREO_FORMAT_LEFT_RIGHT = 1, - STEREO_FORMAT_BOTTOM_TOP = 2, - STEREO_FORMAT_TOP_BOTTOM = 3, - STEREO_FORMAT_RIGHT_LEFT = 11 -} stereo_format_t; - -void write_webm_file_header(struct WebmOutputContext *webm_ctx, - const vpx_codec_enc_cfg_t *cfg, - stereo_format_t stereo_fmt, unsigned int fourcc, - const struct VpxRational *par); - -void write_webm_block(struct WebmOutputContext *webm_ctx, - const vpx_codec_enc_cfg_t *cfg, - const vpx_codec_cx_pkt_t *pkt); - -void write_webm_file_footer(struct WebmOutputContext *webm_ctx); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_WEBMENC_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/y4menc.c b/presentation/src/main/cpp/third_party/libvpx/y4menc.c deleted file mode 100644 index 3940249c..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/y4menc.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include "./y4menc.h" - -int y4m_write_file_header(char *buf, size_t len, int width, int height, - const struct VpxRational *framerate, - vpx_img_fmt_t fmt, unsigned int bit_depth) { - const char *color; - switch (bit_depth) { - case 8: - color = fmt == VPX_IMG_FMT_I444 ? "C444\n" - : fmt == VPX_IMG_FMT_I422 ? "C422\n" - : "C420jpeg\n"; - break; - case 9: - color = fmt == VPX_IMG_FMT_I44416 ? "C444p9 XYSCSS=444P9\n" - : fmt == VPX_IMG_FMT_I42216 ? "C422p9 XYSCSS=422P9\n" - : "C420p9 XYSCSS=420P9\n"; - break; - case 10: - color = fmt == VPX_IMG_FMT_I44416 ? "C444p10 XYSCSS=444P10\n" - : fmt == VPX_IMG_FMT_I42216 ? "C422p10 XYSCSS=422P10\n" - : "C420p10 XYSCSS=420P10\n"; - break; - case 12: - color = fmt == VPX_IMG_FMT_I44416 ? "C444p12 XYSCSS=444P12\n" - : fmt == VPX_IMG_FMT_I42216 ? "C422p12 XYSCSS=422P12\n" - : "C420p12 XYSCSS=420P12\n"; - break; - case 14: - color = fmt == VPX_IMG_FMT_I44416 ? "C444p14 XYSCSS=444P14\n" - : fmt == VPX_IMG_FMT_I42216 ? "C422p14 XYSCSS=422P14\n" - : "C420p14 XYSCSS=420P14\n"; - break; - case 16: - color = fmt == VPX_IMG_FMT_I44416 ? "C444p16 XYSCSS=444P16\n" - : fmt == VPX_IMG_FMT_I42216 ? "C422p16 XYSCSS=422P16\n" - : "C420p16 XYSCSS=420P16\n"; - break; - default: color = NULL; assert(0); - } - return snprintf(buf, len, "YUV4MPEG2 W%u H%u F%u:%u I%c %s", width, height, - framerate->numerator, framerate->denominator, 'p', color); -} - -int y4m_write_frame_header(char *buf, size_t len) { - return snprintf(buf, len, "FRAME\n"); -} diff --git a/presentation/src/main/cpp/third_party/libvpx/y4menc.h b/presentation/src/main/cpp/third_party/libvpx/y4menc.h deleted file mode 100644 index 9a367e34..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/y4menc.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2014 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef VPX_Y4MENC_H_ -#define VPX_Y4MENC_H_ - -#include "./tools_common.h" - -#include "vpx/vpx_decoder.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define Y4M_BUFFER_SIZE 128 - -int y4m_write_file_header(char *buf, size_t len, int width, int height, - const struct VpxRational *framerate, - vpx_img_fmt_t fmt, unsigned int bit_depth); -int y4m_write_frame_header(char *buf, size_t len); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_Y4MENC_H_ diff --git a/presentation/src/main/cpp/third_party/libvpx/y4minput.c b/presentation/src/main/cpp/third_party/libvpx/y4minput.c deleted file mode 100644 index 40f152d0..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/y4minput.c +++ /dev/null @@ -1,1171 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - * - * Based on code from the OggTheora software codec source code, - * Copyright (C) 2002-2010 The Xiph.Org Foundation and contributors. - */ -#include -#include -#include -#include -#include - -#include "vpx/vpx_integer.h" -#include "y4minput.h" - -// Reads 'size' bytes from 'file' into 'buf' with some fault tolerance. -// Returns true on success. -static int file_read(void *buf, size_t size, FILE *file) { - const int kMaxTries = 5; - int try_count = 0; - int file_error = 0; - size_t len = 0; - while (!feof(file) && len < size && try_count < kMaxTries) { - const size_t n = fread((uint8_t *)buf + len, 1, size - len, file); - ++try_count; - len += n; - file_error = ferror(file); - if (file_error) { - if (errno == EINTR || errno == EAGAIN) { - clearerr(file); - continue; - } else { - fprintf(stderr, "Error reading file: %u of %u bytes read, %d: %s\n", - (uint32_t)len, (uint32_t)size, errno, strerror(errno)); - return 0; - } - } - } - - if (!feof(file) && len != size) { - fprintf(stderr, - "Error reading file: %u of %u bytes read," - " error: %d, tries: %d, %d: %s\n", - (uint32_t)len, (uint32_t)size, file_error, try_count, errno, - strerror(errno)); - } - return len == size; -} - -static int y4m_parse_tags(y4m_input *_y4m, char *_tags) { - char *p; - char *q; - for (p = _tags;; p = q) { - /*Skip any leading spaces.*/ - while (*p == ' ') p++; - /*If that's all we have, stop.*/ - if (p[0] == '\0') break; - /*Find the end of this tag.*/ - for (q = p + 1; *q != '\0' && *q != ' '; q++) { - } - /*Process the tag.*/ - switch (p[0]) { - case 'W': { - if (sscanf(p + 1, "%d", &_y4m->pic_w) != 1) return -1; - break; - } - case 'H': { - if (sscanf(p + 1, "%d", &_y4m->pic_h) != 1) return -1; - break; - } - case 'F': { - if (sscanf(p + 1, "%d:%d", &_y4m->fps_n, &_y4m->fps_d) != 2) { - return -1; - } - break; - } - case 'I': { - _y4m->interlace = p[1]; - break; - } - case 'A': { - if (sscanf(p + 1, "%d:%d", &_y4m->par_n, &_y4m->par_d) != 2) { - return -1; - } - break; - } - case 'C': { - if (q - p > 16) return -1; - memcpy(_y4m->chroma_type, p + 1, q - p - 1); - _y4m->chroma_type[q - p - 1] = '\0'; - break; - } - /*Ignore unknown tags.*/ - } - } - return 0; -} - -// Copy a single tag into the buffer, along with a null character. -// Returns 0 if any file IO errors occur. -static int copy_tag(char *buf, size_t buf_len, char *end_tag, FILE *file) { - size_t i; - assert(buf_len >= 1); - // Skip leading space characters. - do { - if (!file_read(buf, 1, file)) { - return 0; - } - } while (buf[0] == ' '); - - // If we hit the newline, treat this as the "empty" tag. - if (buf[0] == '\n') { - buf[0] = '\0'; - *end_tag = '\n'; - return 1; - } - - // Copy over characters until a space is hit, or the buffer is exhausted. - for (i = 1; i < buf_len; ++i) { - if (!file_read(buf + i, 1, file)) { - return 0; - } - if (buf[i] == ' ' || buf[i] == '\n') { - break; - } - } - if (i == buf_len) { - fprintf(stderr, "Error: Y4M header tags must be less than %lu characters\n", - (unsigned long)i); - return 0; - } - *end_tag = buf[i]; - buf[i] = '\0'; - return 1; -} - -/* Returns 1 if tags were parsed successfully, 0 otherwise. */ -static int parse_tags(y4m_input *y4m_ctx, FILE *file) { - char tag[256]; - char end; /* Character denoting the end of the tag, ' ' or '\n'. */ - /* Set Y4M tags to defaults, updating them as processing occurs. Mandatory - fields are marked with -1 and will be checked after the tags are parsed. */ - y4m_ctx->pic_w = -1; - y4m_ctx->pic_h = -1; - y4m_ctx->fps_n = -1; /* Also serves as marker for fps_d */ - y4m_ctx->par_n = 0; - y4m_ctx->par_d = 0; - y4m_ctx->interlace = '?'; - snprintf(y4m_ctx->chroma_type, sizeof(y4m_ctx->chroma_type), "420"); - - /* Find one tag at a time. */ - do { - if (!copy_tag(tag, sizeof(tag), &end, file)) { - return 0; - } - /* y4m_parse_tags returns 0 on success. */ - if (y4m_parse_tags(y4m_ctx, tag)) { - return 0; - } - } while (end != '\n'); - - /* Check the mandatory fields. */ - if (y4m_ctx->pic_w == -1) { - fprintf(stderr, "Width field missing\n"); - return 0; - } - if (y4m_ctx->pic_h == -1) { - fprintf(stderr, "Height field missing\n"); - return 0; - } - if (y4m_ctx->fps_n == -1) { - fprintf(stderr, "FPS field missing\n"); - return 0; - } - return 1; -} - -/*All anti-aliasing filters in the following conversion functions are based on - one of two window functions: - The 6-tap Lanczos window (for down-sampling and shifts): - sinc(\pi*t)*sinc(\pi*t/3), |t|<3 (sinc(t)==sin(t)/t) - 0, |t|>=3 - The 4-tap Mitchell window (for up-sampling): - 7|t|^3-12|t|^2+16/3, |t|<1 - -(7/3)|x|^3+12|x|^2-20|x|+32/3, |t|<2 - 0, |t|>=2 - The number of taps is intentionally kept small to reduce computational - overhead and limit ringing. - - The taps from these filters are scaled so that their sum is 1, and the - result is scaled by 128 and rounded to integers to create a filter whose - intermediate values fit inside 16 bits. - Coefficients are rounded in such a way as to ensure their sum is still 128, - which is usually equivalent to normal rounding. - - Conversions which require both horizontal and vertical filtering could - have these steps pipelined, for less memory consumption and better cache - performance, but we do them separately for simplicity.*/ -#define OC_MINI(_a, _b) ((_a) > (_b) ? (_b) : (_a)) -#define OC_MAXI(_a, _b) ((_a) < (_b) ? (_b) : (_a)) -#define OC_CLAMPI(_a, _b, _c) (OC_MAXI(_a, OC_MINI(_b, _c))) - -/*420jpeg chroma samples are sited like: - Y-------Y-------Y-------Y------- - | | | | - | BR | | BR | - | | | | - Y-------Y-------Y-------Y------- - | | | | - | | | | - | | | | - Y-------Y-------Y-------Y------- - | | | | - | BR | | BR | - | | | | - Y-------Y-------Y-------Y------- - | | | | - | | | | - | | | | - - 420mpeg2 chroma samples are sited like: - Y-------Y-------Y-------Y------- - | | | | - BR | BR | - | | | | - Y-------Y-------Y-------Y------- - | | | | - | | | | - | | | | - Y-------Y-------Y-------Y------- - | | | | - BR | BR | - | | | | - Y-------Y-------Y-------Y------- - | | | | - | | | | - | | | | - - We use a resampling filter to shift the site locations one quarter pixel (at - the chroma plane's resolution) to the right. - The 4:2:2 modes look exactly the same, except there are twice as many chroma - lines, and they are vertically co-sited with the luma samples in both the - mpeg2 and jpeg cases (thus requiring no vertical resampling).*/ -static void y4m_42xmpeg2_42xjpeg_helper(unsigned char *_dst, - const unsigned char *_src, int _c_w, - int _c_h) { - int y; - int x; - for (y = 0; y < _c_h; y++) { - /*Filter: [4 -17 114 35 -9 1]/128, derived from a 6-tap Lanczos - window.*/ - for (x = 0; x < OC_MINI(_c_w, 2); x++) { - _dst[x] = (unsigned char)OC_CLAMPI( - 0, - (4 * _src[0] - 17 * _src[OC_MAXI(x - 1, 0)] + 114 * _src[x] + - 35 * _src[OC_MINI(x + 1, _c_w - 1)] - - 9 * _src[OC_MINI(x + 2, _c_w - 1)] + _src[OC_MINI(x + 3, _c_w - 1)] + - 64) >> - 7, - 255); - } - for (; x < _c_w - 3; x++) { - _dst[x] = (unsigned char)OC_CLAMPI( - 0, - (4 * _src[x - 2] - 17 * _src[x - 1] + 114 * _src[x] + - 35 * _src[x + 1] - 9 * _src[x + 2] + _src[x + 3] + 64) >> - 7, - 255); - } - for (; x < _c_w; x++) { - _dst[x] = (unsigned char)OC_CLAMPI( - 0, - (4 * _src[x - 2] - 17 * _src[x - 1] + 114 * _src[x] + - 35 * _src[OC_MINI(x + 1, _c_w - 1)] - - 9 * _src[OC_MINI(x + 2, _c_w - 1)] + _src[_c_w - 1] + 64) >> - 7, - 255); - } - _dst += _c_w; - _src += _c_w; - } -} - -/*This format is only used for interlaced content, but is included for - completeness. - - 420jpeg chroma samples are sited like: - Y-------Y-------Y-------Y------- - | | | | - | BR | | BR | - | | | | - Y-------Y-------Y-------Y------- - | | | | - | | | | - | | | | - Y-------Y-------Y-------Y------- - | | | | - | BR | | BR | - | | | | - Y-------Y-------Y-------Y------- - | | | | - | | | | - | | | | - - 420paldv chroma samples are sited like: - YR------Y-------YR------Y------- - | | | | - | | | | - | | | | - YB------Y-------YB------Y------- - | | | | - | | | | - | | | | - YR------Y-------YR------Y------- - | | | | - | | | | - | | | | - YB------Y-------YB------Y------- - | | | | - | | | | - | | | | - - We use a resampling filter to shift the site locations one quarter pixel (at - the chroma plane's resolution) to the right. - Then we use another filter to move the C_r location down one quarter pixel, - and the C_b location up one quarter pixel.*/ -static void y4m_convert_42xpaldv_42xjpeg(y4m_input *_y4m, unsigned char *_dst, - unsigned char *_aux) { - unsigned char *tmp; - int c_w; - int c_h; - int c_sz; - int pli; - int y; - int x; - /*Skip past the luma data.*/ - _dst += _y4m->pic_w * _y4m->pic_h; - /*Compute the size of each chroma plane.*/ - c_w = (_y4m->pic_w + 1) / 2; - c_h = (_y4m->pic_h + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h; - c_sz = c_w * c_h; - tmp = _aux + 2 * c_sz; - for (pli = 1; pli < 3; pli++) { - /*First do the horizontal re-sampling. - This is the same as the mpeg2 case, except that after the horizontal - case, we need to apply a second vertical filter.*/ - y4m_42xmpeg2_42xjpeg_helper(tmp, _aux, c_w, c_h); - _aux += c_sz; - switch (pli) { - case 1: { - /*Slide C_b up a quarter-pel. - This is the same filter used above, but in the other order.*/ - for (x = 0; x < c_w; x++) { - for (y = 0; y < OC_MINI(c_h, 3); y++) { - _dst[y * c_w] = (unsigned char)OC_CLAMPI( - 0, - (tmp[0] - 9 * tmp[OC_MAXI(y - 2, 0) * c_w] + - 35 * tmp[OC_MAXI(y - 1, 0) * c_w] + 114 * tmp[y * c_w] - - 17 * tmp[OC_MINI(y + 1, c_h - 1) * c_w] + - 4 * tmp[OC_MINI(y + 2, c_h - 1) * c_w] + 64) >> - 7, - 255); - } - for (; y < c_h - 2; y++) { - _dst[y * c_w] = (unsigned char)OC_CLAMPI( - 0, - (tmp[(y - 3) * c_w] - 9 * tmp[(y - 2) * c_w] + - 35 * tmp[(y - 1) * c_w] + 114 * tmp[y * c_w] - - 17 * tmp[(y + 1) * c_w] + 4 * tmp[(y + 2) * c_w] + 64) >> - 7, - 255); - } - for (; y < c_h; y++) { - _dst[y * c_w] = (unsigned char)OC_CLAMPI( - 0, - (tmp[(y - 3) * c_w] - 9 * tmp[(y - 2) * c_w] + - 35 * tmp[(y - 1) * c_w] + 114 * tmp[y * c_w] - - 17 * tmp[OC_MINI(y + 1, c_h - 1) * c_w] + - 4 * tmp[(c_h - 1) * c_w] + 64) >> - 7, - 255); - } - _dst++; - tmp++; - } - _dst += c_sz - c_w; - tmp -= c_w; - break; - } - case 2: { - /*Slide C_r down a quarter-pel. - This is the same as the horizontal filter.*/ - for (x = 0; x < c_w; x++) { - for (y = 0; y < OC_MINI(c_h, 2); y++) { - _dst[y * c_w] = (unsigned char)OC_CLAMPI( - 0, - (4 * tmp[0] - 17 * tmp[OC_MAXI(y - 1, 0) * c_w] + - 114 * tmp[y * c_w] + 35 * tmp[OC_MINI(y + 1, c_h - 1) * c_w] - - 9 * tmp[OC_MINI(y + 2, c_h - 1) * c_w] + - tmp[OC_MINI(y + 3, c_h - 1) * c_w] + 64) >> - 7, - 255); - } - for (; y < c_h - 3; y++) { - _dst[y * c_w] = (unsigned char)OC_CLAMPI( - 0, - (4 * tmp[(y - 2) * c_w] - 17 * tmp[(y - 1) * c_w] + - 114 * tmp[y * c_w] + 35 * tmp[(y + 1) * c_w] - - 9 * tmp[(y + 2) * c_w] + tmp[(y + 3) * c_w] + 64) >> - 7, - 255); - } - for (; y < c_h; y++) { - _dst[y * c_w] = (unsigned char)OC_CLAMPI( - 0, - (4 * tmp[(y - 2) * c_w] - 17 * tmp[(y - 1) * c_w] + - 114 * tmp[y * c_w] + 35 * tmp[OC_MINI(y + 1, c_h - 1) * c_w] - - 9 * tmp[OC_MINI(y + 2, c_h - 1) * c_w] + tmp[(c_h - 1) * c_w] + - 64) >> - 7, - 255); - } - _dst++; - tmp++; - } - break; - } - } - /*For actual interlaced material, this would have to be done separately on - each field, and the shift amounts would be different. - C_r moves down 1/8, C_b up 3/8 in the top field, and C_r moves down 3/8, - C_b up 1/8 in the bottom field. - The corresponding filters would be: - Down 1/8 (reverse order for up): [3 -11 125 15 -4 0]/128 - Down 3/8 (reverse order for up): [4 -19 98 56 -13 2]/128*/ - } -} - -/*Perform vertical filtering to reduce a single plane from 4:2:2 to 4:2:0. - This is used as a helper by several converation routines.*/ -static void y4m_422jpeg_420jpeg_helper(unsigned char *_dst, - const unsigned char *_src, int _c_w, - int _c_h) { - int y; - int x; - /*Filter: [3 -17 78 78 -17 3]/128, derived from a 6-tap Lanczos window.*/ - for (x = 0; x < _c_w; x++) { - for (y = 0; y < OC_MINI(_c_h, 2); y += 2) { - _dst[(y >> 1) * _c_w] = - OC_CLAMPI(0, - (64 * _src[0] + 78 * _src[OC_MINI(1, _c_h - 1) * _c_w] - - 17 * _src[OC_MINI(2, _c_h - 1) * _c_w] + - 3 * _src[OC_MINI(3, _c_h - 1) * _c_w] + 64) >> - 7, - 255); - } - for (; y < _c_h - 3; y += 2) { - _dst[(y >> 1) * _c_w] = - OC_CLAMPI(0, - (3 * (_src[(y - 2) * _c_w] + _src[(y + 3) * _c_w]) - - 17 * (_src[(y - 1) * _c_w] + _src[(y + 2) * _c_w]) + - 78 * (_src[y * _c_w] + _src[(y + 1) * _c_w]) + 64) >> - 7, - 255); - } - for (; y < _c_h; y += 2) { - _dst[(y >> 1) * _c_w] = OC_CLAMPI( - 0, - (3 * (_src[(y - 2) * _c_w] + _src[(_c_h - 1) * _c_w]) - - 17 * (_src[(y - 1) * _c_w] + _src[OC_MINI(y + 2, _c_h - 1) * _c_w]) + - 78 * (_src[y * _c_w] + _src[OC_MINI(y + 1, _c_h - 1) * _c_w]) + - 64) >> - 7, - 255); - } - _src++; - _dst++; - } -} - -/*420jpeg chroma samples are sited like: - Y-------Y-------Y-------Y------- - | | | | - | BR | | BR | - | | | | - Y-------Y-------Y-------Y------- - | | | | - | | | | - | | | | - Y-------Y-------Y-------Y------- - | | | | - | BR | | BR | - | | | | - Y-------Y-------Y-------Y------- - | | | | - | | | | - | | | | - - 422jpeg chroma samples are sited like: - Y---BR--Y-------Y---BR--Y------- - | | | | - | | | | - | | | | - Y---BR--Y-------Y---BR--Y------- - | | | | - | | | | - | | | | - Y---BR--Y-------Y---BR--Y------- - | | | | - | | | | - | | | | - Y---BR--Y-------Y---BR--Y------- - | | | | - | | | | - | | | | - - We use a resampling filter to decimate the chroma planes by two in the - vertical direction.*/ -static void y4m_convert_422jpeg_420jpeg(y4m_input *_y4m, unsigned char *_dst, - unsigned char *_aux) { - int c_w; - int c_h; - int c_sz; - int dst_c_w; - int dst_c_h; - int dst_c_sz; - int pli; - /*Skip past the luma data.*/ - _dst += _y4m->pic_w * _y4m->pic_h; - /*Compute the size of each chroma plane.*/ - c_w = (_y4m->pic_w + _y4m->src_c_dec_h - 1) / _y4m->src_c_dec_h; - c_h = _y4m->pic_h; - dst_c_w = (_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h; - dst_c_h = (_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v; - c_sz = c_w * c_h; - dst_c_sz = dst_c_w * dst_c_h; - for (pli = 1; pli < 3; pli++) { - y4m_422jpeg_420jpeg_helper(_dst, _aux, c_w, c_h); - _aux += c_sz; - _dst += dst_c_sz; - } -} - -/*420jpeg chroma samples are sited like: - Y-------Y-------Y-------Y------- - | | | | - | BR | | BR | - | | | | - Y-------Y-------Y-------Y------- - | | | | - | | | | - | | | | - Y-------Y-------Y-------Y------- - | | | | - | BR | | BR | - | | | | - Y-------Y-------Y-------Y------- - | | | | - | | | | - | | | | - - 422 chroma samples are sited like: - YBR-----Y-------YBR-----Y------- - | | | | - | | | | - | | | | - YBR-----Y-------YBR-----Y------- - | | | | - | | | | - | | | | - YBR-----Y-------YBR-----Y------- - | | | | - | | | | - | | | | - YBR-----Y-------YBR-----Y------- - | | | | - | | | | - | | | | - - We use a resampling filter to shift the original site locations one quarter - pixel (at the original chroma resolution) to the right. - Then we use a second resampling filter to decimate the chroma planes by two - in the vertical direction.*/ -static void y4m_convert_422_420jpeg(y4m_input *_y4m, unsigned char *_dst, - unsigned char *_aux) { - unsigned char *tmp; - int c_w; - int c_h; - int c_sz; - int dst_c_h; - int dst_c_sz; - int pli; - /*Skip past the luma data.*/ - _dst += _y4m->pic_w * _y4m->pic_h; - /*Compute the size of each chroma plane.*/ - c_w = (_y4m->pic_w + _y4m->src_c_dec_h - 1) / _y4m->src_c_dec_h; - c_h = _y4m->pic_h; - dst_c_h = (_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v; - c_sz = c_w * c_h; - dst_c_sz = c_w * dst_c_h; - tmp = _aux + 2 * c_sz; - for (pli = 1; pli < 3; pli++) { - /*In reality, the horizontal and vertical steps could be pipelined, for - less memory consumption and better cache performance, but we do them - separately for simplicity.*/ - /*First do horizontal filtering (convert to 422jpeg)*/ - y4m_42xmpeg2_42xjpeg_helper(tmp, _aux, c_w, c_h); - /*Now do the vertical filtering.*/ - y4m_422jpeg_420jpeg_helper(_dst, tmp, c_w, c_h); - _aux += c_sz; - _dst += dst_c_sz; - } -} - -/*420jpeg chroma samples are sited like: - Y-------Y-------Y-------Y------- - | | | | - | BR | | BR | - | | | | - Y-------Y-------Y-------Y------- - | | | | - | | | | - | | | | - Y-------Y-------Y-------Y------- - | | | | - | BR | | BR | - | | | | - Y-------Y-------Y-------Y------- - | | | | - | | | | - | | | | - - 411 chroma samples are sited like: - YBR-----Y-------Y-------Y------- - | | | | - | | | | - | | | | - YBR-----Y-------Y-------Y------- - | | | | - | | | | - | | | | - YBR-----Y-------Y-------Y------- - | | | | - | | | | - | | | | - YBR-----Y-------Y-------Y------- - | | | | - | | | | - | | | | - - We use a filter to resample at site locations one eighth pixel (at the source - chroma plane's horizontal resolution) and five eighths of a pixel to the - right. - Then we use another filter to decimate the planes by 2 in the vertical - direction.*/ -static void y4m_convert_411_420jpeg(y4m_input *_y4m, unsigned char *_dst, - unsigned char *_aux) { - unsigned char *tmp; - int c_w; - int c_h; - int c_sz; - int dst_c_w; - int dst_c_h; - int dst_c_sz; - int tmp_sz; - int pli; - int y; - int x; - /*Skip past the luma data.*/ - _dst += _y4m->pic_w * _y4m->pic_h; - /*Compute the size of each chroma plane.*/ - c_w = (_y4m->pic_w + _y4m->src_c_dec_h - 1) / _y4m->src_c_dec_h; - c_h = _y4m->pic_h; - dst_c_w = (_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h; - dst_c_h = (_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v; - c_sz = c_w * c_h; - dst_c_sz = dst_c_w * dst_c_h; - tmp_sz = dst_c_w * c_h; - tmp = _aux + 2 * c_sz; - for (pli = 1; pli < 3; pli++) { - /*In reality, the horizontal and vertical steps could be pipelined, for - less memory consumption and better cache performance, but we do them - separately for simplicity.*/ - /*First do horizontal filtering (convert to 422jpeg)*/ - for (y = 0; y < c_h; y++) { - /*Filters: [1 110 18 -1]/128 and [-3 50 86 -5]/128, both derived from a - 4-tap Mitchell window.*/ - for (x = 0; x < OC_MINI(c_w, 1); x++) { - tmp[x << 1] = (unsigned char)OC_CLAMPI( - 0, - (111 * _aux[0] + 18 * _aux[OC_MINI(1, c_w - 1)] - - _aux[OC_MINI(2, c_w - 1)] + 64) >> - 7, - 255); - tmp[x << 1 | 1] = (unsigned char)OC_CLAMPI( - 0, - (47 * _aux[0] + 86 * _aux[OC_MINI(1, c_w - 1)] - - 5 * _aux[OC_MINI(2, c_w - 1)] + 64) >> - 7, - 255); - } - for (; x < c_w - 2; x++) { - tmp[x << 1] = - (unsigned char)OC_CLAMPI(0, - (_aux[x - 1] + 110 * _aux[x] + - 18 * _aux[x + 1] - _aux[x + 2] + 64) >> - 7, - 255); - tmp[x << 1 | 1] = (unsigned char)OC_CLAMPI( - 0, - (-3 * _aux[x - 1] + 50 * _aux[x] + 86 * _aux[x + 1] - - 5 * _aux[x + 2] + 64) >> - 7, - 255); - } - for (; x < c_w; x++) { - tmp[x << 1] = (unsigned char)OC_CLAMPI( - 0, - (_aux[x - 1] + 110 * _aux[x] + 18 * _aux[OC_MINI(x + 1, c_w - 1)] - - _aux[c_w - 1] + 64) >> - 7, - 255); - if ((x << 1 | 1) < dst_c_w) { - tmp[x << 1 | 1] = (unsigned char)OC_CLAMPI( - 0, - (-3 * _aux[x - 1] + 50 * _aux[x] + - 86 * _aux[OC_MINI(x + 1, c_w - 1)] - 5 * _aux[c_w - 1] + 64) >> - 7, - 255); - } - } - tmp += dst_c_w; - _aux += c_w; - } - tmp -= tmp_sz; - /*Now do the vertical filtering.*/ - y4m_422jpeg_420jpeg_helper(_dst, tmp, dst_c_w, c_h); - _dst += dst_c_sz; - } -} - -/*Convert 444 to 420jpeg.*/ -static void y4m_convert_444_420jpeg(y4m_input *_y4m, unsigned char *_dst, - unsigned char *_aux) { - unsigned char *tmp; - int c_w; - int c_h; - int c_sz; - int dst_c_w; - int dst_c_h; - int dst_c_sz; - int tmp_sz; - int pli; - int y; - int x; - /*Skip past the luma data.*/ - _dst += _y4m->pic_w * _y4m->pic_h; - /*Compute the size of each chroma plane.*/ - c_w = (_y4m->pic_w + _y4m->src_c_dec_h - 1) / _y4m->src_c_dec_h; - c_h = _y4m->pic_h; - dst_c_w = (_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h; - dst_c_h = (_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v; - c_sz = c_w * c_h; - dst_c_sz = dst_c_w * dst_c_h; - tmp_sz = dst_c_w * c_h; - tmp = _aux + 2 * c_sz; - for (pli = 1; pli < 3; pli++) { - /*Filter: [3 -17 78 78 -17 3]/128, derived from a 6-tap Lanczos window.*/ - for (y = 0; y < c_h; y++) { - for (x = 0; x < OC_MINI(c_w, 2); x += 2) { - tmp[x >> 1] = OC_CLAMPI(0, - (64 * _aux[0] + 78 * _aux[OC_MINI(1, c_w - 1)] - - 17 * _aux[OC_MINI(2, c_w - 1)] + - 3 * _aux[OC_MINI(3, c_w - 1)] + 64) >> - 7, - 255); - } - for (; x < c_w - 3; x += 2) { - tmp[x >> 1] = OC_CLAMPI(0, - (3 * (_aux[x - 2] + _aux[x + 3]) - - 17 * (_aux[x - 1] + _aux[x + 2]) + - 78 * (_aux[x] + _aux[x + 1]) + 64) >> - 7, - 255); - } - for (; x < c_w; x += 2) { - tmp[x >> 1] = - OC_CLAMPI(0, - (3 * (_aux[x - 2] + _aux[c_w - 1]) - - 17 * (_aux[x - 1] + _aux[OC_MINI(x + 2, c_w - 1)]) + - 78 * (_aux[x] + _aux[OC_MINI(x + 1, c_w - 1)]) + 64) >> - 7, - 255); - } - tmp += dst_c_w; - _aux += c_w; - } - tmp -= tmp_sz; - /*Now do the vertical filtering.*/ - y4m_422jpeg_420jpeg_helper(_dst, tmp, dst_c_w, c_h); - _dst += dst_c_sz; - } -} - -/*The image is padded with empty chroma components at 4:2:0.*/ -static void y4m_convert_mono_420jpeg(y4m_input *_y4m, unsigned char *_dst, - unsigned char *_aux) { - int c_sz; - (void)_aux; - _dst += _y4m->pic_w * _y4m->pic_h; - c_sz = ((_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h) * - ((_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v); - memset(_dst, 128, c_sz * 2); -} - -/*No conversion function needed.*/ -static void y4m_convert_null(y4m_input *_y4m, unsigned char *_dst, - unsigned char *_aux) { - (void)_y4m; - (void)_dst; - (void)_aux; -} - -static const char TAG[] = "YUV4MPEG2"; - -int y4m_input_open(y4m_input *y4m_ctx, FILE *file, char *skip_buffer, - int num_skip, int only_420) { - // File must start with |TAG|. - char tag_buffer[9]; // 9 == strlen(TAG) - // Read as much as possible from |skip_buffer|, which were characters - // that were previously read from the file to do input-type detection. - assert(num_skip >= 0 && num_skip <= 8); - if (num_skip > 0) { - memcpy(tag_buffer, skip_buffer, num_skip); - } - // Start reading from the file now that the |skip_buffer| is depleted. - if (!file_read(tag_buffer + num_skip, 9 - num_skip, file)) { - return -1; - } - if (memcmp(TAG, tag_buffer, 9) != 0) { - fprintf(stderr, "Error parsing header: must start with %s\n", TAG); - return -1; - } - // Next character must be a space. - if (!file_read(tag_buffer, 1, file) || tag_buffer[0] != ' ') { - fprintf(stderr, "Error parsing header: space must follow %s\n", TAG); - return -1; - } - if (!parse_tags(y4m_ctx, file)) { - fprintf(stderr, "Error parsing %s header.\n", TAG); - } - if (y4m_ctx->interlace == '?') { - fprintf(stderr, - "Warning: Input video interlacing format unknown; " - "assuming progressive scan.\n"); - } else if (y4m_ctx->interlace != 'p') { - fprintf(stderr, - "Input video is interlaced; " - "Only progressive scan handled.\n"); - return -1; - } - y4m_ctx->vpx_fmt = VPX_IMG_FMT_I420; - y4m_ctx->bps = 12; - y4m_ctx->bit_depth = 8; - y4m_ctx->aux_buf = NULL; - y4m_ctx->dst_buf = NULL; - if (strcmp(y4m_ctx->chroma_type, "420") == 0 || - strcmp(y4m_ctx->chroma_type, "420jpeg") == 0 || - strcmp(y4m_ctx->chroma_type, "420mpeg2") == 0) { - y4m_ctx->src_c_dec_h = y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_v = - y4m_ctx->dst_c_dec_v = 2; - y4m_ctx->dst_buf_read_sz = - y4m_ctx->pic_w * y4m_ctx->pic_h + - 2 * ((y4m_ctx->pic_w + 1) / 2) * ((y4m_ctx->pic_h + 1) / 2); - /* Natively supported: no conversion required. */ - y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; - y4m_ctx->convert = y4m_convert_null; - } else if (strcmp(y4m_ctx->chroma_type, "420p10") == 0) { - y4m_ctx->src_c_dec_h = 2; - y4m_ctx->dst_c_dec_h = 2; - y4m_ctx->src_c_dec_v = 2; - y4m_ctx->dst_c_dec_v = 2; - y4m_ctx->dst_buf_read_sz = - 2 * (y4m_ctx->pic_w * y4m_ctx->pic_h + - 2 * ((y4m_ctx->pic_w + 1) / 2) * ((y4m_ctx->pic_h + 1) / 2)); - /* Natively supported: no conversion required. */ - y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; - y4m_ctx->convert = y4m_convert_null; - y4m_ctx->bit_depth = 10; - y4m_ctx->bps = 15; - y4m_ctx->vpx_fmt = VPX_IMG_FMT_I42016; - if (only_420) { - fprintf(stderr, "Unsupported conversion from 420p10 to 420jpeg\n"); - return -1; - } - } else if (strcmp(y4m_ctx->chroma_type, "420p12") == 0) { - y4m_ctx->src_c_dec_h = 2; - y4m_ctx->dst_c_dec_h = 2; - y4m_ctx->src_c_dec_v = 2; - y4m_ctx->dst_c_dec_v = 2; - y4m_ctx->dst_buf_read_sz = - 2 * (y4m_ctx->pic_w * y4m_ctx->pic_h + - 2 * ((y4m_ctx->pic_w + 1) / 2) * ((y4m_ctx->pic_h + 1) / 2)); - /* Natively supported: no conversion required. */ - y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; - y4m_ctx->convert = y4m_convert_null; - y4m_ctx->bit_depth = 12; - y4m_ctx->bps = 18; - y4m_ctx->vpx_fmt = VPX_IMG_FMT_I42016; - if (only_420) { - fprintf(stderr, "Unsupported conversion from 420p12 to 420jpeg\n"); - return -1; - } - } else if (strcmp(y4m_ctx->chroma_type, "420paldv") == 0) { - y4m_ctx->src_c_dec_h = y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_v = - y4m_ctx->dst_c_dec_v = 2; - y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h; - /*Chroma filter required: read into the aux buf first. - We need to make two filter passes, so we need some extra space in the - aux buffer.*/ - y4m_ctx->aux_buf_sz = - 3 * ((y4m_ctx->pic_w + 1) / 2) * ((y4m_ctx->pic_h + 1) / 2); - y4m_ctx->aux_buf_read_sz = - 2 * ((y4m_ctx->pic_w + 1) / 2) * ((y4m_ctx->pic_h + 1) / 2); - y4m_ctx->convert = y4m_convert_42xpaldv_42xjpeg; - } else if (strcmp(y4m_ctx->chroma_type, "422jpeg") == 0) { - y4m_ctx->src_c_dec_h = y4m_ctx->dst_c_dec_h = 2; - y4m_ctx->src_c_dec_v = 1; - y4m_ctx->dst_c_dec_v = 2; - y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h; - /*Chroma filter required: read into the aux buf first.*/ - y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = - 2 * ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h; - y4m_ctx->convert = y4m_convert_422jpeg_420jpeg; - } else if (strcmp(y4m_ctx->chroma_type, "422") == 0) { - y4m_ctx->src_c_dec_h = 2; - y4m_ctx->src_c_dec_v = 1; - if (only_420) { - y4m_ctx->dst_c_dec_h = 2; - y4m_ctx->dst_c_dec_v = 2; - y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h; - /*Chroma filter required: read into the aux buf first. - We need to make two filter passes, so we need some extra space in the - aux buffer.*/ - y4m_ctx->aux_buf_read_sz = - 2 * ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h; - y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz + - ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h; - y4m_ctx->convert = y4m_convert_422_420jpeg; - } else { - y4m_ctx->vpx_fmt = VPX_IMG_FMT_I422; - y4m_ctx->bps = 16; - y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h; - y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v; - y4m_ctx->dst_buf_read_sz = - y4m_ctx->pic_w * y4m_ctx->pic_h + - 2 * ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h; - /*Natively supported: no conversion required.*/ - y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; - y4m_ctx->convert = y4m_convert_null; - } - } else if (strcmp(y4m_ctx->chroma_type, "422p10") == 0) { - y4m_ctx->src_c_dec_h = 2; - y4m_ctx->src_c_dec_v = 1; - y4m_ctx->vpx_fmt = VPX_IMG_FMT_I42216; - y4m_ctx->bps = 20; - y4m_ctx->bit_depth = 10; - y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h; - y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v; - y4m_ctx->dst_buf_read_sz = - 2 * (y4m_ctx->pic_w * y4m_ctx->pic_h + - 2 * ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h); - y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; - y4m_ctx->convert = y4m_convert_null; - if (only_420) { - fprintf(stderr, "Unsupported conversion from 422p10 to 420jpeg\n"); - return -1; - } - } else if (strcmp(y4m_ctx->chroma_type, "422p12") == 0) { - y4m_ctx->src_c_dec_h = 2; - y4m_ctx->src_c_dec_v = 1; - y4m_ctx->vpx_fmt = VPX_IMG_FMT_I42216; - y4m_ctx->bps = 24; - y4m_ctx->bit_depth = 12; - y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h; - y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v; - y4m_ctx->dst_buf_read_sz = - 2 * (y4m_ctx->pic_w * y4m_ctx->pic_h + - 2 * ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h); - y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; - y4m_ctx->convert = y4m_convert_null; - if (only_420) { - fprintf(stderr, "Unsupported conversion from 422p12 to 420jpeg\n"); - return -1; - } - } else if (strcmp(y4m_ctx->chroma_type, "411") == 0) { - y4m_ctx->src_c_dec_h = 4; - y4m_ctx->dst_c_dec_h = 2; - y4m_ctx->src_c_dec_v = 1; - y4m_ctx->dst_c_dec_v = 2; - y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h; - /*Chroma filter required: read into the aux buf first. - We need to make two filter passes, so we need some extra space in the - aux buffer.*/ - y4m_ctx->aux_buf_read_sz = 2 * ((y4m_ctx->pic_w + 3) / 4) * y4m_ctx->pic_h; - y4m_ctx->aux_buf_sz = - y4m_ctx->aux_buf_read_sz + ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h; - y4m_ctx->convert = y4m_convert_411_420jpeg; - fprintf(stderr, "Unsupported conversion from yuv 411\n"); - return -1; - } else if (strcmp(y4m_ctx->chroma_type, "444") == 0) { - y4m_ctx->src_c_dec_h = 1; - y4m_ctx->src_c_dec_v = 1; - if (only_420) { - y4m_ctx->dst_c_dec_h = 2; - y4m_ctx->dst_c_dec_v = 2; - y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h; - /*Chroma filter required: read into the aux buf first. - We need to make two filter passes, so we need some extra space in the - aux buffer.*/ - y4m_ctx->aux_buf_read_sz = 2 * y4m_ctx->pic_w * y4m_ctx->pic_h; - y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz + - ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h; - y4m_ctx->convert = y4m_convert_444_420jpeg; - } else { - y4m_ctx->vpx_fmt = VPX_IMG_FMT_I444; - y4m_ctx->bps = 24; - y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h; - y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v; - y4m_ctx->dst_buf_read_sz = 3 * y4m_ctx->pic_w * y4m_ctx->pic_h; - /*Natively supported: no conversion required.*/ - y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; - y4m_ctx->convert = y4m_convert_null; - } - } else if (strcmp(y4m_ctx->chroma_type, "444p10") == 0) { - y4m_ctx->src_c_dec_h = 1; - y4m_ctx->src_c_dec_v = 1; - y4m_ctx->vpx_fmt = VPX_IMG_FMT_I44416; - y4m_ctx->bps = 30; - y4m_ctx->bit_depth = 10; - y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h; - y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v; - y4m_ctx->dst_buf_read_sz = 2 * 3 * y4m_ctx->pic_w * y4m_ctx->pic_h; - y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; - y4m_ctx->convert = y4m_convert_null; - if (only_420) { - fprintf(stderr, "Unsupported conversion from 444p10 to 420jpeg\n"); - return -1; - } - } else if (strcmp(y4m_ctx->chroma_type, "444p12") == 0) { - y4m_ctx->src_c_dec_h = 1; - y4m_ctx->src_c_dec_v = 1; - y4m_ctx->vpx_fmt = VPX_IMG_FMT_I44416; - y4m_ctx->bps = 36; - y4m_ctx->bit_depth = 12; - y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h; - y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v; - y4m_ctx->dst_buf_read_sz = 2 * 3 * y4m_ctx->pic_w * y4m_ctx->pic_h; - y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; - y4m_ctx->convert = y4m_convert_null; - if (only_420) { - fprintf(stderr, "Unsupported conversion from 444p12 to 420jpeg\n"); - return -1; - } - } else if (strcmp(y4m_ctx->chroma_type, "mono") == 0) { - y4m_ctx->src_c_dec_h = y4m_ctx->src_c_dec_v = 0; - y4m_ctx->dst_c_dec_h = y4m_ctx->dst_c_dec_v = 2; - y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h; - /*No extra space required, but we need to clear the chroma planes.*/ - y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; - y4m_ctx->convert = y4m_convert_mono_420jpeg; - } else { - fprintf(stderr, "Unknown chroma sampling type: %s\n", y4m_ctx->chroma_type); - return -1; - } - /*The size of the final frame buffers is always computed from the - destination chroma decimation type.*/ - y4m_ctx->dst_buf_sz = - y4m_ctx->pic_w * y4m_ctx->pic_h + - 2 * ((y4m_ctx->pic_w + y4m_ctx->dst_c_dec_h - 1) / y4m_ctx->dst_c_dec_h) * - ((y4m_ctx->pic_h + y4m_ctx->dst_c_dec_v - 1) / y4m_ctx->dst_c_dec_v); - if (y4m_ctx->bit_depth == 8) - y4m_ctx->dst_buf = (unsigned char *)malloc(y4m_ctx->dst_buf_sz); - else - y4m_ctx->dst_buf = (unsigned char *)malloc(2 * y4m_ctx->dst_buf_sz); - if (!y4m_ctx->dst_buf) return -1; - - if (y4m_ctx->aux_buf_sz > 0) { - y4m_ctx->aux_buf = (unsigned char *)malloc(y4m_ctx->aux_buf_sz); - if (!y4m_ctx->aux_buf) { - free(y4m_ctx->dst_buf); - return -1; - } - } - return 0; -} - -void y4m_input_close(y4m_input *_y4m) { - free(_y4m->dst_buf); - free(_y4m->aux_buf); -} - -int y4m_input_fetch_frame(y4m_input *_y4m, FILE *_fin, vpx_image_t *_img) { - char frame[6]; - int pic_sz; - int c_w; - int c_h; - int c_sz; - int bytes_per_sample = _y4m->bit_depth > 8 ? 2 : 1; - /*Read and skip the frame header.*/ - if (!file_read(frame, 6, _fin)) return 0; - if (memcmp(frame, "FRAME", 5)) { - fprintf(stderr, "Loss of framing in Y4M input data\n"); - return -1; - } - if (frame[5] != '\n') { - char c; - int j; - for (j = 0; j < 79 && file_read(&c, 1, _fin) && c != '\n'; j++) { - } - if (j == 79) { - fprintf(stderr, "Error parsing Y4M frame header\n"); - return -1; - } - } - /*Read the frame data that needs no conversion.*/ - if (!file_read(_y4m->dst_buf, _y4m->dst_buf_read_sz, _fin)) { - fprintf(stderr, "Error reading Y4M frame data.\n"); - return -1; - } - /*Read the frame data that does need conversion.*/ - if (!file_read(_y4m->aux_buf, _y4m->aux_buf_read_sz, _fin)) { - fprintf(stderr, "Error reading Y4M frame data.\n"); - return -1; - } - /*Now convert the just read frame.*/ - (*_y4m->convert)(_y4m, _y4m->dst_buf, _y4m->aux_buf); - /*Fill in the frame buffer pointers. - We don't use vpx_img_wrap() because it forces padding for odd picture - sizes, which would require a separate fread call for every row.*/ - memset(_img, 0, sizeof(*_img)); - /*Y4M has the planes in Y'CbCr order, which libvpx calls Y, U, and V.*/ - _img->fmt = _y4m->vpx_fmt; - _img->w = _img->d_w = _y4m->pic_w; - _img->h = _img->d_h = _y4m->pic_h; - _img->bit_depth = _y4m->bit_depth; - _img->x_chroma_shift = _y4m->dst_c_dec_h >> 1; - _img->y_chroma_shift = _y4m->dst_c_dec_v >> 1; - _img->bps = _y4m->bps; - - /*Set up the buffer pointers.*/ - pic_sz = _y4m->pic_w * _y4m->pic_h * bytes_per_sample; - c_w = (_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h; - c_w *= bytes_per_sample; - c_h = (_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v; - c_sz = c_w * c_h; - _img->stride[VPX_PLANE_Y] = _img->stride[VPX_PLANE_ALPHA] = - _y4m->pic_w * bytes_per_sample; - _img->stride[VPX_PLANE_U] = _img->stride[VPX_PLANE_V] = c_w; - _img->planes[VPX_PLANE_Y] = _y4m->dst_buf; - _img->planes[VPX_PLANE_U] = _y4m->dst_buf + pic_sz; - _img->planes[VPX_PLANE_V] = _y4m->dst_buf + pic_sz + c_sz; - _img->planes[VPX_PLANE_ALPHA] = _y4m->dst_buf + pic_sz + 2 * c_sz; - return 1; -} diff --git a/presentation/src/main/cpp/third_party/libvpx/y4minput.h b/presentation/src/main/cpp/third_party/libvpx/y4minput.h deleted file mode 100644 index 573750d7..00000000 --- a/presentation/src/main/cpp/third_party/libvpx/y4minput.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2010 The WebM project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - * - * Based on code from the OggTheora software codec source code, - * Copyright (C) 2002-2010 The Xiph.Org Foundation and contributors. - */ - -#ifndef VPX_Y4MINPUT_H_ -#define VPX_Y4MINPUT_H_ - -#include -#include "vpx/vpx_image.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct y4m_input y4m_input; - -/*The function used to perform chroma conversion.*/ -typedef void (*y4m_convert_func)(y4m_input *_y4m, unsigned char *_dst, - unsigned char *_src); - -struct y4m_input { - int pic_w; - int pic_h; - int fps_n; - int fps_d; - int par_n; - int par_d; - char interlace; - int src_c_dec_h; - int src_c_dec_v; - int dst_c_dec_h; - int dst_c_dec_v; - char chroma_type[16]; - /*The size of each converted frame buffer.*/ - size_t dst_buf_sz; - /*The amount to read directly into the converted frame buffer.*/ - size_t dst_buf_read_sz; - /*The size of the auxilliary buffer.*/ - size_t aux_buf_sz; - /*The amount to read into the auxilliary buffer.*/ - size_t aux_buf_read_sz; - y4m_convert_func convert; - unsigned char *dst_buf; - unsigned char *aux_buf; - enum vpx_img_fmt vpx_fmt; - int bps; - unsigned int bit_depth; -}; - -/** - * Open the input file, treating it as Y4M. |y4m_ctx| is filled in after - * reading it. The |skip_buffer| indicates bytes that were previously read - * from |file|, to do input-type detection; this buffer will be read before - * the |file| is read. It is of size |num_skip|, which *must* be 8 or less. - * - * Returns 0 on success, -1 on failure. - */ -int y4m_input_open(y4m_input *y4m_ctx, FILE *file, char *skip_buffer, - int num_skip, int only_420); -void y4m_input_close(y4m_input *_y4m); -int y4m_input_fetch_frame(y4m_input *_y4m, FILE *_fin, vpx_image_t *img); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // VPX_Y4MINPUT_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/.Gifs/1.gif b/presentation/src/main/cpp/third_party/rlottie/.Gifs/1.gif deleted file mode 100644 index a5892269..00000000 Binary files a/presentation/src/main/cpp/third_party/rlottie/.Gifs/1.gif and /dev/null differ diff --git a/presentation/src/main/cpp/third_party/rlottie/.Gifs/2.gif b/presentation/src/main/cpp/third_party/rlottie/.Gifs/2.gif deleted file mode 100644 index 3b9b4655..00000000 Binary files a/presentation/src/main/cpp/third_party/rlottie/.Gifs/2.gif and /dev/null differ diff --git a/presentation/src/main/cpp/third_party/rlottie/.Gifs/logo.png b/presentation/src/main/cpp/third_party/rlottie/.Gifs/logo.png deleted file mode 100644 index 4af86966..00000000 Binary files a/presentation/src/main/cpp/third_party/rlottie/.Gifs/logo.png and /dev/null differ diff --git a/presentation/src/main/cpp/third_party/rlottie/.Gifs/rlottie.xcf b/presentation/src/main/cpp/third_party/rlottie/.Gifs/rlottie.xcf deleted file mode 100644 index 6d53592f..00000000 Binary files a/presentation/src/main/cpp/third_party/rlottie/.Gifs/rlottie.xcf and /dev/null differ diff --git a/presentation/src/main/cpp/third_party/rlottie/.Gifs/rlottie_player.png b/presentation/src/main/cpp/third_party/rlottie/.Gifs/rlottie_player.png deleted file mode 100644 index f47fffa6..00000000 Binary files a/presentation/src/main/cpp/third_party/rlottie/.Gifs/rlottie_player.png and /dev/null differ diff --git a/presentation/src/main/cpp/third_party/rlottie/.appveyor.yml b/presentation/src/main/cpp/third_party/rlottie/.appveyor.yml deleted file mode 100644 index 254e5c77..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/.appveyor.yml +++ /dev/null @@ -1,23 +0,0 @@ -os: Visual Studio 2017 -platform: - - x86 -environment: - matrix: - - ARCH: x86 - PYTHON: "C:\\Python35" - - ARCH: x64 - PYTHON: "C:\\Python35-x64" -skip_branch_with_pr: true -install: - - git submodule update --init --recursive - - set PATH=%cd%;%PYTHON%;%PYTHON%\Scripts;%PATH% - - pip install meson==0.50.0 ninja - - call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" -build_script: - - meson -Dwerror=false --backend=ninja --prefix=%cd% build - - where link - - ninja -C build -test_script: - - ninja -C build test -after_build: - - ninja -C build install diff --git a/presentation/src/main/cpp/third_party/rlottie/.clang-format b/presentation/src/main/cpp/third_party/rlottie/.clang-format deleted file mode 100644 index 10f4c7a5..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/.clang-format +++ /dev/null @@ -1,90 +0,0 @@ ---- -Language: Cpp -BasedOnStyle: Google -AccessModifierOffset: -4 -AlignAfterOpenBracket: Align -AlignConsecutiveAssignments: false -AlignConsecutiveDeclarations: true -AlignEscapedNewlinesLeft: true -AlignOperands: true -AlignTrailingComments: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: false -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: Inline -AllowShortIfStatementsOnASingleLine: true -AllowShortLoopsOnASingleLine: true -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: true -AlwaysBreakTemplateDeclarations: true -BinPackArguments: true -BinPackParameters: true -BraceWrapping: - AfterClass: false - AfterControlStatement: false - AfterEnum: false - AfterFunction: false - AfterNamespace: false - AfterObjCDeclaration: false - AfterStruct: false - AfterUnion: false - BeforeCatch: false - BeforeElse: false - IndentBraces: false -BreakBeforeBinaryOperators: None -BreakBeforeBraces: WebKit -BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false -ColumnLimit: 80 -CommentPragmas: '^ IWYU pragma:' -ConstructorInitializerAllOnOneLineOrOnePerLine: true -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: true -DerivePointerAlignment: true -DisableFormat: false -ExperimentalAutoDetectBinPacking: false -ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] -IncludeCategories: - - Regex: '^<.*\.h>' - Priority: 1 - - Regex: '^<.*' - Priority: 2 - - Regex: '.*' - Priority: 3 -IndentCaseLabels: false -IndentWidth: 4 -IndentWrappedFunctionNames: false -KeepEmptyLinesAtTheStartOfBlocks: false -MacroBlockBegin: '' -MacroBlockEnd: '' -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None -ObjCBlockIndentWidth: 2 -ObjCSpaceAfterProperty: false -ObjCSpaceBeforeProtocolList: false -PenaltyBreakBeforeFirstCallParameter: 1 -PenaltyBreakComment: 300 -PenaltyBreakFirstLessLess: 120 -PenaltyBreakString: 1000 -PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 200 -PointerAlignment: Right -ReflowComments: true -SortIncludes: true -SpaceAfterCStyleCast: false -SpaceBeforeAssignmentOperators: true -SpaceBeforeParens: ControlStatements -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 2 -SpacesInAngles: false -SpacesInContainerLiterals: true -SpacesInCStyleCastParentheses: false -SpacesInParentheses: false -SpacesInSquareBrackets: false -Standard: Auto -TabWidth: 4 -UseTab: Never -... - diff --git a/presentation/src/main/cpp/third_party/rlottie/.gitignore b/presentation/src/main/cpp/third_party/rlottie/.gitignore deleted file mode 100644 index 260edc85..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -build -*.creator* -*.config -*.files -*.includes -html -latex -*.swp -tmp -.cproject -.project -.vs -**/*.DS_Store -builddir_wasm \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/.travis.yml b/presentation/src/main/cpp/third_party/rlottie/.travis.yml deleted file mode 100644 index b3807427..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/.travis.yml +++ /dev/null @@ -1,22 +0,0 @@ -sudo: false - -os: - - linux - -language: - - cpp - -services: - - docker - -before_install: - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker pull smohantty/rlottie-ci-setup; fi - -script: - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo FROM smohantty/rlottie-ci-setup > Dockerfile; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo ADD . /root >> Dockerfile; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker build -t withgit .; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker run withgit /bin/sh -c "cd /root && TRAVIS=true meson -Dtest=true builddir && ninja -C builddir test && ninja -C builddir install"; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker run withgit /bin/sh -c "cd /root && TRAVIS=true meson -Dcache=false -Dmodule=false -Ddumptree=true builddir && ninja -C builddir install"; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker run withgit /bin/sh -c "cd /root && TRAVIS=true meson -Dthread=false builddir && ninja -C builddir install"; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker run withgit /bin/sh -c "cd /root && TRAVIS=true cmake -DLOTTIE_TEST=ON -Bbuilddir -H. && make -C builddir -j$(nproc) all test && make -C builddir install"; fi diff --git a/presentation/src/main/cpp/third_party/rlottie/AUTHORS b/presentation/src/main/cpp/third_party/rlottie/AUTHORS deleted file mode 100644 index 5f2ff9b9..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/AUTHORS +++ /dev/null @@ -1,18 +0,0 @@ -Subhransu Mohanty -Hermet Park -Youngbok Shin -Jaeun Choi -Bryce Harrington -Junsu Choi -Yuangu -Mihai Serban -Shinwoo Kim -Vincent Torri -Nicholas Guriev -John Preston -Anatoly Korniltsev -Александр Першин -Anton Sergeev -HyunGu Lee -ChaeLin Shin -Seungjae Yoon diff --git a/presentation/src/main/cpp/third_party/rlottie/CMakeLists.txt b/presentation/src/main/cpp/third_party/rlottie/CMakeLists.txt deleted file mode 100644 index b6fdfaeb..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/CMakeLists.txt +++ /dev/null @@ -1,210 +0,0 @@ -cmake_minimum_required( VERSION 3.3 ) - -#declare project -project( rlottie VERSION 0.2 LANGUAGES C CXX ASM) - -if (NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE MinSizeRel) -endif() - -if (NOT DEFINED BUILD_SHARED_LIBS) - # Keep the previous behavior of the build system, consistent with Meson. - set(BUILD_SHARED_LIBS ON) -endif() - -#declare target -add_library( rlottie ) -set_target_properties( rlottie PROPERTIES DEFINE_SYMBOL RLOTTIE_BUILD ) - -#declare version of the target -set(player_version_major 0) -set(player_version_minor 2) -set(player_version ${player_version_major}.${player_version_minor}) -set_target_properties(rlottie PROPERTIES - VERSION ${player_version} - SOVERSION ${player_version_major} - ) - -#declare alias so that library can be used inside the build tree, e.g. when testing -add_library(rlottie::rlottie ALIAS rlottie) - -option(LOTTIE_MODULE "Enable LOTTIE MODULE SUPPORT" ON) -option(LOTTIE_THREAD "Enable LOTTIE THREAD SUPPORT" ON) -option(LOTTIE_CACHE "Enable LOTTIE CACHE SUPPORT" ON) -option(LOTTIE_TEST "Build LOTTIE AUTOTESTS" OFF) -option(LOTTIE_CCACHE "Enable LOTTIE ccache SUPPORT" OFF) -option(LOTTIE_ASAN "Compile with asan" OFF) - -set(LOTTIE_MODULE_PATH "${CMAKE_SHARED_LIBRARY_PREFIX}rlottie-image-loader${CMAKE_SHARED_LIBRARY_SUFFIX}" - CACHE STRING "Absolute or relative path to dynamic loader plugin.") - -configure_file(${CMAKE_CURRENT_LIST_DIR}/cmake/config.h.in config.h) - -target_include_directories(rlottie - PUBLIC $ - PRIVATE - "${CMAKE_CURRENT_BINARY_DIR}" - ) - -#declare common target compilation options -if(MSVC) - target_compile_options(rlottie - PUBLIC - PRIVATE - /std:c++14 - /EHs-c- # disable exceptions - /GR- # disable RTTI - /W3 - ) -else() - target_compile_options(rlottie - PUBLIC - PRIVATE - -std=c++14 - -fno-exceptions - -fno-unwind-tables - -fno-asynchronous-unwind-tables - -fno-rtti - -Wall - -fvisibility=hidden - -Wnon-virtual-dtor - -Woverloaded-virtual - -Wno-unused-parameter - ) -endif() - -if (WIN32 AND NOT BUILD_SHARED_LIBS) - target_compile_definitions(rlottie PUBLIC -DRLOTTIE_BUILD=0) - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") -endif() - -#declare dependancy -set( CMAKE_THREAD_PREFER_PTHREAD TRUE ) -find_package( Threads ) - -if(WIN32) - set( OSSPEC_LIBS Shlwapi.lib ) -endif() - -target_link_libraries(rlottie - PUBLIC - "${CMAKE_THREAD_LIBS_INIT}" - ${OSSPEC_LIBS} - ) - -if (NOT APPLE AND NOT WIN32 AND NOT ANDROID) - target_link_libraries(rlottie - PRIVATE - "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/rlottie.expmap" - ) -endif() - -if (LOTTIE_MODULE) - # for dlopen, dlsym and dlclose dependancy - target_link_libraries(rlottie PRIVATE ${CMAKE_DL_LIBS}) -endif() - -if (NOT LOTTIE_ASAN) - if(APPLE) - target_link_libraries(rlottie - PUBLIC - "-Wl, -undefined error" - ) - elseif(NOT MSVC) - target_link_libraries(rlottie - PUBLIC - "-Wl,--no-undefined" - ) - endif() -endif() - -if (LOTTIE_CCACHE) - find_program(CCACHE_FOUND ccache) - if (CCACHE_FOUND) - message(STATUS "Found ccache") - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) - set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) - else() - message(STATUS "Could NOT find ccache (this is NOT an error)") - endif() -endif() - -if (LOTTIE_ASAN) - target_compile_options(rlottie PUBLIC -fsanitize=address) - target_link_options(rlottie PUBLIC -fsanitize=address) -endif() - -if (NOT LIB_INSTALL_DIR) - set (LIB_INSTALL_DIR "/usr/lib") -endif (NOT LIB_INSTALL_DIR) - -#declare source and include files -add_subdirectory(inc) -add_subdirectory(src) -if (NOT ANDROID) - add_subdirectory(example) -endif() - -if (LOTTIE_TEST) - enable_testing() - add_subdirectory(test) -endif() - -SET(PREFIX ${CMAKE_INSTALL_PREFIX}) -SET(EXEC_DIR ${PREFIX}) -SET(LIBDIR ${LIB_INSTALL_DIR}) -SET(INCDIR ${PREFIX}/include) - -CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc) -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) - - -#install header -install(FILES - inc/rlottie.h - inc/rlottie_capi.h - inc/rlottiecommon.h - DESTINATION include) - -#install lib -install( TARGETS rlottie EXPORT rlottie-targets - LIBRARY DESTINATION ${LIB_INSTALL_DIR} - ARCHIVE DESTINATION ${LIB_INSTALL_DIR} - INCLUDES DESTINATION include - ) - -#install config file. - -install( EXPORT rlottie-targets - FILE rlottieTargets.cmake - NAMESPACE rlottie:: - DESTINATION ${LIB_INSTALL_DIR}/cmake/rlottie - ) - - -#Create a ConfigVersion.cmake file -include(CMakePackageConfigHelpers) -write_basic_package_version_file( - ${CMAKE_CURRENT_BINARY_DIR}/rlottieConfigVersion.cmake - VERSION ${PROJECT_VERSION} - COMPATIBILITY AnyNewerVersion -) - -configure_package_config_file(${CMAKE_CURRENT_LIST_DIR}/cmake/rlottieConfig.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/rlottieConfig.cmake - INSTALL_DESTINATION ${LIB_INSTALL_DIR}/cmake/rlottie -) - -#Install the config, configversion and custom find modules -install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/rlottieConfig.cmake - ${CMAKE_CURRENT_BINARY_DIR}/rlottieConfigVersion.cmake - DESTINATION ${LIB_INSTALL_DIR}/cmake/rlottie -) - - -export(EXPORT rlottie-targets FILE ${CMAKE_CURRENT_BINARY_DIR}/rlottieTargets.cmake NAMESPACE rlottie::) - -#Register package in user's package registry -export(PACKAGE rlottie) diff --git a/presentation/src/main/cpp/third_party/rlottie/COPYING b/presentation/src/main/cpp/third_party/rlottie/COPYING deleted file mode 100644 index e0825e7f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/COPYING +++ /dev/null @@ -1,17 +0,0 @@ -Licensing - -rlottie basically comes with MIT license(licenses/COPYING.MIT) -but some parts of shared code are covered by different licenses. Listed -below are the folder names and the license file covering it. Note that this -license would cover all of the source invovled in each folders, unless -specifically noted otherwise. So please refer to these imported project sources -for details. - -Dependencies and licenses: - -src/vector/ licenses/COPYING.MIT, COPYING.SKIA -src/vector/freetype licenses/COPYING.FTL -src/vector/pixman licenses/COPYING.PIX -src/vector/stb licenses/COPYING.STB -src/lottie/rapidjson licenses/COPYING.RPD - diff --git a/presentation/src/main/cpp/third_party/rlottie/README.md b/presentation/src/main/cpp/third_party/rlottie/README.md deleted file mode 100644 index 3f1c5a61..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/README.md +++ /dev/null @@ -1,319 +0,0 @@ - -# rlottie - -[![Build Status](https://travis-ci.org/Samsung/rlottie.svg?branch=master)](https://travis-ci.org/Samsung/rlottie) -[![Build status](https://ci.appveyor.com/api/projects/status/n3xonxk1ooo6s7nr?svg=true&passingText=windows%20-%20passing)](https://ci.appveyor.com/project/smohantty/rlottie-mliua) -[![Gitter](https://badges.gitter.im/rLottie-dev/community.svg)](https://gitter.im/rLottie-dev/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) - -

- -

- -rlottie is a platform independent standalone c++ library for rendering vector based animations and art in realtime. - -Lottie loads and renders animations and vectors exported in the bodymovin JSON format. Bodymovin JSON can be created and exported from After Effects with [bodymovin](https://github.com/bodymovin/bodymovin), Sketch with [Lottie Sketch Export](https://github.com/buba447/Lottie-Sketch-Export), and from [Haiku](https://www.haiku.ai). - -For the first time, designers can create and ship beautiful animations without an engineer painstakingly recreating it by hand. Since the animation is backed by JSON they are extremely small in size but can be large in complexity! - -Here are small samples of the power of Lottie. - -

- - - -

- -## Contents -- [Building Lottie](#building-lottie) - - [Meson Build](#meson-build) - - [Cmake Build](#cmake-build) - - [Test](#test) -- [Demo](#demo) -- [Previewing Lottie JSON Files](#previewing-lottie-json-files) -- [Quick Start](#quick-start) -- [Dynamic Property](#dynamic-property) -- [Supported After Effects Features](#supported-after-effects-features) -- [Issues or Feature Requests?](#issues-or-feature-requests) - -## Building Lottie -rlottie supports [meson](https://mesonbuild.com/) and [cmake](https://cmake.org/) build system. rlottie is written in `C++14`. and has a public header dependency of `C++11` - -### Meson Build -install [meson](http://mesonbuild.com/Getting-meson.html) and [ninja](https://ninja-build.org/) if not already installed. - -Run meson to configure rlottie -``` -meson build -``` -Run ninja to build rlottie -``` -ninja -C build -``` - -### Cmake Build - -Install [cmake](https://cmake.org/download/) if not already installed - -Create a build directory for out of source `build` -``` -mkdir build -``` -Run cmake command inside `build` directory to configure rlottie. -``` -cd build -cmake .. - -# install in a different path. eg ~/test/usr/lib -cmake -DCMAKE_INSTALL_PREFIX=~/test .. - -# static build -cmake -DBUILD_SHARED_LIBS=OFF .. -``` -Run make to build rlottie - -``` -make -j 2 -``` -To install rlottie library - -``` -make install -``` - -### Test - -Configure to build test -``` -meson configure -Dtest=true -``` -Build test suit - -``` -ninja -``` -Run test suit -``` -ninja test -``` -[Back to contents](#contents) - -# -## Demo -If you want to see rlottie library in action without building it please visit [rlottie online viewer](http://rlottie.com) - -While building rlottie library it generates a simple lottie to GIF converter which can be used to convert lottie json file to GIF file. - -Run Demo -``` -lottie2gif [lottie file name] -``` - -# -## Previewing Lottie JSON Files -Please visit [rlottie online viewer](http://rlottie.com) - -[rlottie online viewer](http://rlottie.com) uses rlottie wasm library to render the resource locally in your browser. To test your JSON resource drag and drop it to the browser window. - -# -## Quick Start - -Lottie loads and renders animations and vectors exported in the bodymovin JSON format. Bodymovin JSON can be created and exported from After Effects with [bodymovin](https://github.com/bodymovin/bodymovin), Sketch with [Lottie Sketch Export](https://github.com/buba447/Lottie-Sketch-Export), and from [Haiku](https://www.haiku.ai). - -You can quickly load a Lottie animation with: -```cpp -auto animation = rlottie::Animation::loadFromFile("absolute_path/test.json"); -``` -You can load a lottie animation from raw data with: -```cpp -auto animation = rlottie::Animation::loadFromData(std::string(rawData), std::string(cacheKey)); -``` - -Properties like `frameRate` , `totalFrame` , `duration` can be queried with: -```cpp -# get the frame rate of the resource. -double frameRate = animation->frameRate(); - -#get total frame that exists in the resource -size_t totalFrame = animation->totalFrame(); - -#get total animation duration in sec for the resource -double duration = animation->duration(); -``` -Render a particular frame in a surface buffer `immediately` with: -```cpp -rlottie::Surface surface(buffer, width , height , stride); -animation->renderSync(frameNo, surface); -``` -Render a particular frame in a surface buffer `asyncronousely` with: -```cpp -rlottie::Surface surface(buffer, width , height , stride); -# give a render request -std::future handle = animation->render(frameNo, surface); -... -#when the render data is needed -rlottie::Surface surface = handle.get(); -``` - -[Back to contents](#contents) - - -## Dynamic Property - -You can update properties dynamically at runtime. This can be used for a variety of purposes such as: -- Theming (day and night or arbitrary themes). -- Responding to events such as an error or a success. -- Animating a single part of an animation in response to an event. -- Responding to view sizes or other values not known at design time. - -### Understanding After Effects - -To understand how to change animation properties in Lottie, you should first understand how animation properties are stored in Lottie. Animation properties are stored in a data tree that mimics the information hierarchy of After Effects. In After Effects a Composition is a collection of Layers that each have their own timelines. Layer objects have string names, and their contents can be an image, shape layers, fills, strokes, or just about anything that is drawable. Each object in After Effects has a name. Lottie can find these objects and properties by their name using a KeyPath. - -### Usage - -To update a property at runtime, you need 3 things: -1. KeyPath -2. rLottie::Property -3. setValue() - -### KeyPath - -A KeyPath is used to target a specific content or a set of contents that will be updated. A KeyPath is specified by a list of strings that correspond to the hierarchy of After Effects contents in the original animation. -KeyPaths can include the specific name of the contents or wildcards: -- Wildcard * - - Wildcards match any single content name in its position in the keypath. -- Globstar ** - - Globstars match zero or more layers. - -### Properties - -`rLottie::Property` is an enumeration of properties that can be set. They correspond to the animatable value in After Effects and the available properties are listed below. -```cpp -enum class Property { - FillColor, /*!< Color property of Fill object , value type is rlottie::Color */ - FillOpacity, /*!< Opacity property of Fill object , value type is float [ 0 .. 100] */ - StrokeColor, /*!< Color property of Stroke object , value type is rlottie::Color */ - StrokeOpacity, /*!< Opacity property of Stroke object , value type is float [ 0 .. 100] */ - StrokeWidth, /*!< stroke with property of Stroke object , value type is float */ - ... -}; -``` - -### setValue() - -`setValue()` requires a keypath of string and value. The value can be `Color`, `Size` and `Point` structure or a function that returns them. `Color`, `Size`, and `Point` vary depending on the type of `rLottie::Property`. This value or function(callback) is called and applied to every frame. This value can be set differently for each frame by using the `FrameInfo` argument passed to the function. - - -### Usage -```cpp -animation->setValue("**",rlottie::Color(0, 1, 0)); -``` - -```cpp -animation->setValue("Layer1.Box 1.Fill1", - [](const rlottie::FrameInfo& info) { - if (info.curFrame() < 15 ) - return rlottie::Color(0, 1, 0); - else { - return rlottie::Color(1, 0, 0); - } - }); -``` - -[Back to contents](#contents) - -# -# -## Supported After Effects Features - -| **Shapes** | **Supported** | -|:--|:-:| -| Shape | 👍 | -| Ellipse | 👍 | -| Rectangle | 👍 | -| Rounded Rectangle | 👍 | -| Polystar | 👍 | -| Group | 👍 | -| Trim Path (individually) | 👍 | -| Trim Path (simultaneously) | 👍 | -| **Renderable** | **Supported** | -| Fill | 👍 | -| Stroke | 👍 | -| Radial Gradient | 👍 | -| Linear Gradient | 👍 | -| Gradient Stroke | 👍 | -| **Transforms** | **Supported** | -| Position | 👍 | -| Position (separated X/Y) | 👍 | -| Scale | 👍 | -| Skew | ⛔️ | -| Rotation | 👍 | -| Anchor Point | 👍 | -| Opacity | 👍 | -| Parenting | 👍 | -| Auto Orient | 👍 | -| **Interpolation** | **Supported** | -| Linear Interpolation | 👍 | -| Bezier Interpolation | 👍 | -| Hold Interpolation | 👍 | -| Spatial Bezier Interpolation | 👍 | -| Rove Across Time | 👍 | -| **Masks** | **Supported** | -| Mask Path | 👍 | -| Mask Opacity | 👍 | -| Add | 👍 | -| Subtract | 👍 | -| Intersect | 👍 | -| Lighten | ⛔️ | -| Darken | ⛔️ | -| Difference | ⛔️ | -| Expansion | ⛔️ | -| Feather | ⛔️ | -| **Mattes** | **Supported** | -| Alpha Matte | 👍 | -| Alpha Inverted Matte | 👍 | -| Luma Matte | 👍 | -| Luma Inverted Matte | 👍 | -| **Merge Paths** | **Supported** | -| Merge | ⛔️ | -| Add | ⛔️ | -| Subtract | ⛔️ | -| Intersect | ⛔️ | -| Exclude Intersection | ⛔️ | -| **Layer Effects** | **Supported** | -| Fill | ⛔️ | -| Stroke | ⛔️ | -| Tint | ⛔️ | -| Tritone | ⛔️ | -| Levels Individual Controls | ⛔️ | -| **Text** | **Supported** | -| Glyphs | ⛔️ | -| Fonts | ⛔️ | -| Transform | ⛔️ | -| Fill | ⛔️ | -| Stroke | ⛔️ | -| Tracking | ⛔️ | -| Anchor point grouping | ⛔️ | -| Text Path | ⛔️ | -| Per-character 3D | ⛔️ | -| Range selector (Units) | ⛔️ | -| Range selector (Based on) | ⛔️ | -| Range selector (Amount) | ⛔️ | -| Range selector (Shape) | ⛔️ | -| Range selector (Ease High) | ⛔️ | -| Range selector (Ease Low) | ⛔️ | -| Range selector (Randomize order) | ⛔️ | -| expression selector | ⛔️ | -| **Other** | **Supported** | -| Expressions | ⛔️ | -| Images | 👍 | -| Precomps | 👍 | -| Time Stretch | 👍 | -| Time remap | 👍 | -| Markers | 👍 | - -# -[Back to contents](#contents) - -## Issues or Feature Requests? -File github issues for anything that is broken. Be sure to check the [list of supported features](#supported-after-effects-features) before submitting. If an animation is not working, please attach the After Effects file to your issue. Debugging without the original can be very difficult. For immidiate assistant or support please reach us in [Gitter](https://gitter.im/rLottie-dev/community#) diff --git a/presentation/src/main/cpp/third_party/rlottie/arm_build.sh b/presentation/src/main/cpp/third_party/rlottie/arm_build.sh deleted file mode 100644 index cd9bcf60..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/arm_build.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -if [ -z "$1" ]; then - echo "Sysroot PATH is not provided" - echo "Usage: arm_build SYSROOT_PATH" - exit 1; -fi - -if [ ! -d "./builddir_wasm" ]; then - sed "s|SYSROOT:|$1|g" arm_cross.txt > /tmp/.arm_cross.txt - meson builddir_arm --cross-file /tmp/.arm_cross.txt -fi - -sudo ninja -C builddir_arm/ diff --git a/presentation/src/main/cpp/third_party/rlottie/arm_cross.txt b/presentation/src/main/cpp/third_party/rlottie/arm_cross.txt deleted file mode 100644 index 927be56f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/arm_cross.txt +++ /dev/null @@ -1,16 +0,0 @@ -[binaries] -cpp = 'SYSROOT:/bin/arm-none-linux-gnueabihf-g++' -ar = 'SYSROOT:/bin/arm-none-linux-gnueabihf-ar' - -[properties] -root = 'SYSROOT:' -shared_lib_suffix = 'so' -static_lib_suffix = 'so' -shared_module_suffix = 'so' -exe_suffix = 'exe' - -[host_machine] -system = 'arm' -cpu_family = 'arm' -cpu = 'armv7l' -endian = 'little' \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/cmake/config.h.in b/presentation/src/main/cpp/third_party/rlottie/cmake/config.h.in deleted file mode 100644 index ca42a9e1..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/cmake/config.h.in +++ /dev/null @@ -1,19 +0,0 @@ -#cmakedefine LOTTIE_MODULE - -#ifdef LOTTIE_MODULE -#define LOTTIE_IMAGE_MODULE_SUPPORT -#endif - -#define LOTTIE_IMAGE_MODULE_PLUGIN "@LOTTIE_MODULE_PATH@" - -#cmakedefine LOTTIE_THREAD - -#ifdef LOTTIE_THREAD -#define LOTTIE_THREAD_SUPPORT -#endif - -#cmakedefine LOTTIE_CACHE - -#ifdef LOTTIE_CACHE -#define LOTTIE_CACHE_SUPPORT -#endif diff --git a/presentation/src/main/cpp/third_party/rlottie/cmake/rlottieConfig.cmake.in b/presentation/src/main/cpp/third_party/rlottie/cmake/rlottieConfig.cmake.in deleted file mode 100644 index 730672a1..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/cmake/rlottieConfig.cmake.in +++ /dev/null @@ -1,16 +0,0 @@ -get_filename_component(rlottie_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) -include(CMakeFindDependencyMacro) - -list(APPEND CMAKE_MODULE_PATH ${rlottie_CMAKE_DIR}) - -# NOTE Had to use find_package because find_dependency does not support COMPONENTS or MODULE until 3.8.0 - -#find_dependency(RapidJSON 1.0 REQUIRED MODULE) -#find_package(Boost 1.55 REQUIRED COMPONENTS regex) -list(REMOVE_AT CMAKE_MODULE_PATH -1) - -if(NOT TARGET rlottie::rlottie) - include("${rlottie_CMAKE_DIR}/rlottieTargets.cmake") -endif() - -set(rlottie_LIBRARIES rlottie::rlottie) diff --git a/presentation/src/main/cpp/third_party/rlottie/example/CMakeLists.txt b/presentation/src/main/cpp/third_party/rlottie/example/CMakeLists.txt deleted file mode 100644 index aacdc7c0..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -add_executable(lottie2gif "lottie2gif.cpp") - -if(MSVC) - target_compile_options(lottie2gif - PRIVATE - /std:c++14) -else() - target_compile_options(lottie2gif - PRIVATE - -std=c++14) -endif() - -target_link_libraries(lottie2gif rlottie) - -target_include_directories(lottie2gif - PRIVATE - "${CMAKE_CURRENT_LIST_DIR}/../inc/") diff --git a/presentation/src/main/cpp/third_party/rlottie/example/demo.cpp b/presentation/src/main/cpp/third_party/rlottie/example/demo.cpp deleted file mode 100644 index 4898081e..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/demo.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "evasapp.h" -#include "lottieview.h" -#include -#include -#include -#include -using namespace std; - -class Demo -{ -public: - Demo(EvasApp *app, std::string &filePath) { - Demo1(app, filePath); - Demo2(app, filePath); - Demo3(app, filePath); - Demo4(app, filePath); - Demo5(app, filePath); - Demo6(app, filePath); - Demo7(app, filePath); - Demo8(app, filePath); - } - void Demo1(EvasApp *app, std::string &filePath) { - /* Fill Color */ - view1.reset(new LottieView(app->evas())); - view1->setFilePath(filePath.c_str()); - if (view1->player()) { - view1->player()->setValue("Shape Layer 1.Ellipse 1.Fill 1", - [](const rlottie::FrameInfo& info) { - if (info.curFrame() < 60 ) - return rlottie::Color(0, 0, 1); - else { - return rlottie::Color(1, 0, 0); - } - }); - } - view1->setPos(0, 0); - view1->setSize(300, 300); - view1->show(); - view1->play(); - view1->loop(true); - view1->setRepeatMode(LottieView::RepeatMode::Reverse); - } - - void Demo2(EvasApp *app, std::string &filePath) { - /* Stroke Opacity */ - view2.reset(new LottieView(app->evas())); - view2->setFilePath(filePath.c_str()); - if (view2->player()) { - view2->player()->setValue("Shape Layer 2.Shape 1.Stroke 1", - [](const rlottie::FrameInfo& info) { - if (info.curFrame() < 60 ) - return 20; - else { - return 100; - } - }); - } - view2->setPos(300, 0); - view2->setSize(300, 300); - view2->show(); - view2->play(); - view2->loop(true); - view2->setRepeatMode(LottieView::RepeatMode::Reverse); - } - - void Demo3(EvasApp *app, std::string &filePath) { - /* Stroke Opacity */ - view3.reset(new LottieView(app->evas())); - view3->setFilePath(filePath.c_str()); - if (view3->player()) { - view3->player()->setValue("**", - [](const rlottie::FrameInfo& info) { - if (info.curFrame() < 60 ) - return 1.0; - else { - return 5.0; - } - }); - } - view3->setPos(600, 0); - view3->setSize(300, 300); - view3->show(); - view3->play(); - view3->loop(true); - view3->setRepeatMode(LottieView::RepeatMode::Reverse); - } - - void Demo4(EvasApp *app, std::string &filePath) { - /* Transform position */ - view4.reset(new LottieView(app->evas())); - view4->setFilePath(filePath.c_str()); - if (view4->player()) { - view4->player()->setValue("Shape Layer 1.Ellipse 1", - [](const rlottie::FrameInfo& info) { - return rlottie::Point(-20 + (double)info.curFrame()/2.0, - -20 + (double)info.curFrame()/2.0); - }); - } - view4->setPos(900, 0); - view4->setSize(300, 300); - view4->show(); - view4->play(); - view4->loop(true); - view4->setRepeatMode(LottieView::RepeatMode::Reverse); - } - - void Demo5(EvasApp *app, std::string &filePath) { - /* Transform position */ - view5.reset(new LottieView(app->evas())); - view5->setFilePath(filePath.c_str()); - if (view5->player()) { - view5->player()->setValue("Shape Layer 2.Shape 1", - [](const rlottie::FrameInfo& info) { - return rlottie::Point(-20 + (double)info.curFrame()/2.0, - -20 + (double)info.curFrame()/2.0); - }); - } - view5->setPos(1200, 0); - view5->setSize(300, 300); - view5->show(); - view5->play(); - view5->loop(true); - view5->setRepeatMode(LottieView::RepeatMode::Reverse); - } - - void Demo6(EvasApp *app, std::string &filePath) { - /* Transform scale */ - view6.reset(new LottieView(app->evas())); - view6->setFilePath(filePath.c_str()); - if (view6->player()) { - view6->player()->setValue("Shape Layer 1.Ellipse 1", - [](const rlottie::FrameInfo& info) { - return rlottie::Size(100 - info.curFrame(), - 50); - }); - } - view6->setPos(1500, 0); - view6->setSize(300, 300); - view6->show(); - view6->play(); - view6->loop(true); - view6->setRepeatMode(LottieView::RepeatMode::Reverse); - } - - void Demo7(EvasApp *app, std::string &filePath) { - /* Transform rotation */ - view7.reset(new LottieView(app->evas())); - view7->setFilePath(filePath.c_str()); - if (view7->player()) { - view7->player()->setValue("Shape Layer 2.Shape 1", - [](const rlottie::FrameInfo& info) { - return info.curFrame() * 20; - }); - } - view7->setPos(1800, 0); - view7->setSize(300, 300); - view7->show(); - view7->play(); - view7->loop(true); - view7->setRepeatMode(LottieView::RepeatMode::Reverse); - } - void Demo8(EvasApp *app, std::string &filePath) { - /* Transform + color */ - view8.reset(new LottieView(app->evas())); - view8->setFilePath(filePath.c_str()); - if (view8->player()) { - view8->player()->setValue("Shape Layer 1.Ellipse 1", - [](const rlottie::FrameInfo& info) { - return info.curFrame() * 20; - }); - view8->player()->setValue("Shape Layer 1.Ellipse 1", - [](const rlottie::FrameInfo& info) { - return rlottie::Size(50, 100 - info.curFrame()); - }); - view8->player()->setValue("Shape Layer 1.Ellipse 1", - [](const rlottie::FrameInfo& info) { - return rlottie::Point(-20 + (double)info.curFrame()/2.0, - -20 + (double)info.curFrame()/2.0); - }); - view8->player()->setValue("Shape Layer 1.Ellipse 1.Fill 1", - [](const rlottie::FrameInfo& info) { - if (info.curFrame() < 60 ) - return rlottie::Color(0, 0, 1); - else { - return rlottie::Color(1, 0, 0); - } - }); - view8->player()->setValue("Shape Layer 2.Trim Paths 1", - [](const rlottie::FrameInfo& info) { - return rlottie::Point(0, 30); - }); - } - view8->setPos(2100, 0); - view8->setSize(300, 300); - view8->show(); - view8->play(); - view8->loop(true); - view8->setRepeatMode(LottieView::RepeatMode::Reverse); - } -private: - std::unique_ptr view1; - std::unique_ptr view2; - std::unique_ptr view3; - std::unique_ptr view4; - std::unique_ptr view5; - std::unique_ptr view6; - std::unique_ptr view7; - std::unique_ptr view8; -}; - -static void -onExitCb(void *data, void */*extra*/) -{ - Demo *demo = (Demo *)data; - delete demo; -} - -int -main(void) -{ - EvasApp *app = new EvasApp(2400, 300); - app->setup(); - - std::string filePath = DEMO_DIR; - filePath +="done.json"; - - auto demo = new Demo(app, filePath); - - app->addExitCb(onExitCb, demo); - app->run(); - - delete app; - return 0; -} - - - - - diff --git a/presentation/src/main/cpp/third_party/rlottie/example/demo_marker.cpp b/presentation/src/main/cpp/third_party/rlottie/example/demo_marker.cpp deleted file mode 100644 index 0a0f54ee..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/demo_marker.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "evasapp.h" -#include "lottieview.h" -#include -#include -#include -#include -using namespace std; - -class DemoMarker -{ -public: - DemoMarker(EvasApp *app, std::string filePath) { - view1.reset(new LottieView(app->evas())); - view1->setFilePath(filePath.c_str()); - view1->setPos(0, 0); - view1->setSize(400, 400); - view1->show(); - view1->play(); - view1->loop(true); - - /* Play with marker */ - view2.reset(new LottieView(app->evas())); - view2->setFilePath(filePath.c_str()); - view2->setPos(400, 0); - view2->setSize(400, 400); - view2->show(); - view2->play("second"); - view2->loop(true); - - /* Play marker to marker */ - view3.reset(new LottieView(app->evas())); - view3->setFilePath(filePath.c_str()); - view3->setPos(800, 0); - view3->setSize(400, 400); - view3->show(); - view3->play("second", "third"); - view3->loop(true); - } - -private: - std::unique_ptr view1; - std::unique_ptr view2; - std::unique_ptr view3; -}; - -static void -onExitCb(void *data, void */*extra*/) -{ - DemoMarker *demo = (DemoMarker *)data; - delete demo; -} - -int -main(void) -{ - EvasApp *app = new EvasApp(1200, 400); - app->setup(); - - std::string filePath = DEMO_DIR; - filePath +="marker.json"; - - auto demo = new DemoMarker(app, filePath); - - app->addExitCb(onExitCb, demo); - app->run(); - - delete app; - return 0; -} - - - - - diff --git a/presentation/src/main/cpp/third_party/rlottie/example/evasapp.cpp b/presentation/src/main/cpp/third_party/rlottie/example/evasapp.cpp deleted file mode 100644 index 5f42884d..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/evasapp.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "evasapp.h" -#include -#include - -static void -_on_resize(Ecore_Evas *ee) -{ - EvasApp *app = (EvasApp *)ecore_evas_data_get(ee, "app"); - int w, h; - ecore_evas_geometry_get(ee, NULL, NULL, &w, &h); - app->resize(w, h); - if (app->mResizeCb) - app->mResizeCb(app->mResizeData, nullptr); -} - -static void -_on_delete(Ecore_Evas *ee) -{ - EvasApp *app = (EvasApp *)ecore_evas_data_get(ee, "app"); - if (app->mExitCb) - app->mExitCb(app->mExitData, nullptr); - - ecore_main_loop_quit(); - ecore_evas_free(ee); -} - -static Eina_Bool -on_key_down(void *data, int /*type*/, void *event) -{ - Ecore_Event_Key *keyData = (Ecore_Event_Key *)event; - - EvasApp *app = (EvasApp *) data; - if (app && app->mKeyCb) - app->mKeyCb(app->mKeyData, (void *)keyData->key); - - return false; -} - -static void -on_pre_render(Ecore_Evas *ee) -{ - EvasApp *app = (EvasApp *)ecore_evas_data_get(ee, "app"); - if (app->mRenderPreCb) - app->mRenderPreCb(app->mRenderPreData, nullptr); -} - -static void -on_post_render(Ecore_Evas *ee) -{ - EvasApp *app = (EvasApp *)ecore_evas_data_get(ee, "app"); - if (app && app->mRenderPostCb) - app->mRenderPostCb(app->mRenderPostData, nullptr); -} - -void EvasApp::exit() -{ - _on_delete(mEcoreEvas); -} -EvasApp::EvasApp(int w, int h) -{ - if (!ecore_evas_init()) - return; - mw = w; - mh = h; - //setenv("ECORE_EVAS_ENGINE", "opengl_x11", 1); - mEcoreEvas = ecore_evas_new(NULL, 0, 0, mw, mh, NULL); - if (!mEcoreEvas) return; -} - -void -EvasApp::setup() -{ - ecore_evas_data_set(mEcoreEvas, "app", this); - ecore_evas_callback_resize_set(mEcoreEvas, _on_resize); - ecore_evas_callback_delete_request_set(mEcoreEvas, _on_delete); - ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, on_key_down, this); - ecore_evas_callback_pre_render_set(mEcoreEvas, on_pre_render); - ecore_evas_callback_post_render_set(mEcoreEvas, on_post_render); - - ecore_evas_show(mEcoreEvas); - mEvas = ecore_evas_get(mEcoreEvas); - mBackground = evas_object_rectangle_add(mEvas); - evas_object_color_set(mBackground, 70, 70, 70, 255); - evas_object_show(mBackground); -} - -void -EvasApp::resize(int w, int h) -{ - evas_object_resize(mBackground, w, h); - mw = w; - mh = h; -} - -void EvasApp::run() -{ - resize(mw, mh); - ecore_main_loop_begin(); - ecore_evas_shutdown(); -} - -static bool isLottiefile(const char *filename) { - const char *dot = strrchr(filename, '.'); - if(!dot || dot == filename) return false; - return !strcmp(dot + 1, "json") || !strcmp(dot + 1, "lottie"); -} - -std::vector -EvasApp::jsonFiles(const std::string &dirName, bool /*recurse*/) -{ - DIR *d; - struct dirent *dir; - std::vector result; - d = opendir(dirName.c_str()); - if (d) { - while ((dir = readdir(d)) != NULL) { - if (isLottiefile(dir->d_name)) - result.push_back(dirName + dir->d_name); - } - closedir(d); - } - - std::sort(result.begin(), result.end(), [](auto & a, auto &b){return a < b;}); - - return result; -} - diff --git a/presentation/src/main/cpp/third_party/rlottie/example/evasapp.h b/presentation/src/main/cpp/third_party/rlottie/example/evasapp.h deleted file mode 100644 index e1fdb18d..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/evasapp.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef EVASAPP_H -#define EVASAPP_H - -#ifndef EFL_BETA_API_SUPPORT -#define EFL_BETA_API_SUPPORT -#endif - -#ifndef EFL_EO_API_SUPPORT -#define EFL_EO_API_SUPPORT -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - - -typedef void (*appCb)(void *userData, void *extra); -class EvasApp -{ -public: - EvasApp(int w, int h); - void setup(); - void resize(int w, int h); - int width() const{ return mw;} - int height() const{ return mh;} - void run(); - Ecore_Evas * ee() const{return mEcoreEvas;} - Evas * evas() const {return mEvas;} - void addExitCb(appCb exitcb, void *data) {mExitCb = exitcb; mExitData = data;} - void addResizeCb(appCb resizecb, void *data) {mResizeCb = resizecb; mResizeData = data;} - void addKeyCb(appCb keycb, void *data) {mKeyCb = keycb; mKeyData = data;} - void addRenderPreCb(appCb renderPrecb, void *data) {mRenderPreCb = renderPrecb; mRenderPreData = data;} - void addRenderPostCb(appCb renderPostcb, void *data) {mRenderPostCb = renderPostcb; mRenderPostData = data;} - void exit(); - static std::vector jsonFiles(const std::string &dir, bool recurse=false); -public: - int mw{0}; - int mh{0}; - Ecore_Evas *mEcoreEvas{nullptr}; - Evas *mEvas{nullptr}; - Evas_Object *mBackground{nullptr}; - appCb mResizeCb{nullptr}; - void *mResizeData{nullptr}; - appCb mExitCb{nullptr}; - void *mExitData{nullptr}; - appCb mKeyCb{nullptr}; - void *mKeyData{nullptr}; - appCb mRenderPreCb{nullptr}; - void *mRenderPreData{nullptr}; - appCb mRenderPostCb{nullptr}; - void *mRenderPostData{nullptr}; -}; -#endif //EVASAPP_H diff --git a/presentation/src/main/cpp/third_party/rlottie/example/gif.h b/presentation/src/main/cpp/third_party/rlottie/example/gif.h deleted file mode 100644 index 72cc148c..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/gif.h +++ /dev/null @@ -1,835 +0,0 @@ -// -// gif.h -// by Charlie Tangora -// Public domain. -// Email me : ctangora -at- gmail -dot- com -// -// This file offers a simple, very limited way to create animated GIFs directly in code. -// -// Those looking for particular cleverness are likely to be disappointed; it's pretty -// much a straight-ahead implementation of the GIF format with optional Floyd-Steinberg -// dithering. (It does at least use delta encoding - only the changed portions of each -// frame are saved.) -// -// So resulting files are often quite large. The hope is that it will be handy nonetheless -// as a quick and easily-integrated way for programs to spit out animations. -// -// Only RGBA8 is currently supported as an input format. (The alpha is ignored.) -// -// If capturing a buffer with a bottom-left origin (such as OpenGL), define GIF_FLIP_VERT -// to automatically flip the buffer data when writing the image (the buffer itself is -// unchanged. -// -// USAGE: -// Create a GifWriter struct. Pass it to GifBegin() to initialize and write the header. -// Pass subsequent frames to GifWriteFrame(). -// Finally, call GifEnd() to close the file handle and free memory. -// - -#ifndef gif_h -#define gif_h - -#include // for FILE* -#include // for memcpy and bzero -#include // for integer typedefs - -// Define these macros to hook into a custom memory allocator. -// TEMP_MALLOC and TEMP_FREE will only be called in stack fashion - frees in the reverse order of mallocs -// and any temp memory allocated by a function will be freed before it exits. -// MALLOC and FREE are used only by GifBegin and GifEnd respectively (to allocate a buffer the size of the image, which -// is used to find changed pixels for delta-encoding.) - -#ifndef GIF_TEMP_MALLOC -#include -#define GIF_TEMP_MALLOC malloc -#endif - -#ifndef GIF_TEMP_FREE -#include -#define GIF_TEMP_FREE free -#endif - -#ifndef GIF_MALLOC -#include -#define GIF_MALLOC malloc -#endif - -#ifndef GIF_FREE -#include -#define GIF_FREE free -#endif - -const int kGifTransIndex = 0; - -struct GifPalette -{ - int bitDepth; - - uint8_t r[256]; - uint8_t g[256]; - uint8_t b[256]; - - // k-d tree over RGB space, organized in heap fashion - // i.e. left child of node i is node i*2, right child is node i*2+1 - // nodes 256-511 are implicitly the leaves, containing a color - uint8_t treeSplitElt[255]; - uint8_t treeSplit[255]; -}; - -// max, min, and abs functions -int GifIMax(int l, int r) { return l>r?l:r; } -int GifIMin(int l, int r) { return l (1<bitDepth)-1) - { - int ind = treeRoot-(1<bitDepth); - if(ind == kGifTransIndex) return; - - // check whether this color is better than the current winner - int r_err = r - ((int32_t)pPal->r[ind]); - int g_err = g - ((int32_t)pPal->g[ind]); - int b_err = b - ((int32_t)pPal->b[ind]); - int diff = GifIAbs(r_err)+GifIAbs(g_err)+GifIAbs(b_err); - - if(diff < bestDiff) - { - bestInd = ind; - bestDiff = diff; - } - - return; - } - - // take the appropriate color (r, g, or b) for this node of the k-d tree - int comps[3]; comps[0] = r; comps[1] = g; comps[2] = b; - int splitComp = comps[pPal->treeSplitElt[treeRoot]]; - - int splitPos = pPal->treeSplit[treeRoot]; - if(splitPos > splitComp) - { - // check the left subtree - GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2); - if( bestDiff > splitPos - splitComp ) - { - // cannot prove there's not a better value in the right subtree, check that too - GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2+1); - } - } - else - { - GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2+1); - if( bestDiff > splitComp - splitPos ) - { - GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2); - } - } -} - -void GifSwapPixels(uint8_t* image, int pixA, int pixB) -{ - uint8_t rA = image[pixA*4]; - uint8_t gA = image[pixA*4+1]; - uint8_t bA = image[pixA*4+2]; - uint8_t aA = image[pixA*4+3]; - - uint8_t rB = image[pixB*4]; - uint8_t gB = image[pixB*4+1]; - uint8_t bB = image[pixB*4+2]; - uint8_t aB = image[pixA*4+3]; - - image[pixA*4] = rB; - image[pixA*4+1] = gB; - image[pixA*4+2] = bB; - image[pixA*4+3] = aB; - - image[pixB*4] = rA; - image[pixB*4+1] = gA; - image[pixB*4+2] = bA; - image[pixB*4+3] = aA; -} - -// just the partition operation from quicksort -int GifPartition(uint8_t* image, const int left, const int right, const int elt, int pivotIndex) -{ - const int pivotValue = image[(pivotIndex)*4+elt]; - GifSwapPixels(image, pivotIndex, right-1); - int storeIndex = left; - bool split = 0; - for(int ii=left; ii neededCenter) - GifPartitionByMedian(image, left, pivotIndex, com, neededCenter); - - if(pivotIndex < neededCenter) - GifPartitionByMedian(image, pivotIndex+1, right, com, neededCenter); - } -} - -// Builds a palette by creating a balanced k-d tree of all pixels in the image -void GifSplitPalette(uint8_t* image, int numPixels, int firstElt, int lastElt, int splitElt, int splitDist, int treeNode, bool buildForDither, GifPalette* pal) -{ - if(lastElt <= firstElt || numPixels == 0) - return; - - // base case, bottom of the tree - if(lastElt == firstElt+1) - { - if(buildForDither) - { - // Dithering needs at least one color as dark as anything - // in the image and at least one brightest color - - // otherwise it builds up error and produces strange artifacts - if( firstElt == 1 ) - { - // special case: the darkest color in the image - uint32_t r=255, g=255, b=255; - for(int ii=0; iir[firstElt] = (uint8_t)r; - pal->g[firstElt] = (uint8_t)g; - pal->b[firstElt] = (uint8_t)b; - - return; - } - - if( firstElt == (1 << pal->bitDepth)-1 ) - { - // special case: the lightest color in the image - uint32_t r=0, g=0, b=0; - for(int ii=0; iir[firstElt] = (uint8_t)r; - pal->g[firstElt] = (uint8_t)g; - pal->b[firstElt] = (uint8_t)b; - - return; - } - } - - // otherwise, take the average of all colors in this subcube - uint64_t r=0, g=0, b=0; - for(int ii=0; iir[firstElt] = (uint8_t)r; - pal->g[firstElt] = (uint8_t)g; - pal->b[firstElt] = (uint8_t)b; - - return; - } - - // Find the axis with the largest range - int minR = 255, maxR = 0; - int minG = 255, maxG = 0; - int minB = 255, maxB = 0; - for(int ii=0; ii maxR) maxR = r; - if(r < minR) minR = r; - - if(g > maxG) maxG = g; - if(g < minG) minG = g; - - if(b > maxB) maxB = b; - if(b < minB) minB = b; - } - - int rRange = maxR - minR; - int gRange = maxG - minG; - int bRange = maxB - minB; - - // and split along that axis. (incidentally, this means this isn't a "proper" k-d tree but I don't know what else to call it) - int splitCom = 1; - if(bRange > gRange) splitCom = 2; - if(rRange > bRange && rRange > gRange) splitCom = 0; - - int subPixelsA = numPixels * (splitElt - firstElt) / (lastElt - firstElt); - int subPixelsB = numPixels-subPixelsA; - - GifPartitionByMedian(image, 0, numPixels, splitCom, subPixelsA); - - pal->treeSplitElt[treeNode] = (uint8_t)splitCom; - pal->treeSplit[treeNode] = image[subPixelsA*4+splitCom]; - - GifSplitPalette(image, subPixelsA, firstElt, splitElt, splitElt-splitDist, splitDist/2, treeNode*2, buildForDither, pal); - GifSplitPalette(image+subPixelsA*4, subPixelsB, splitElt, lastElt, splitElt+splitDist, splitDist/2, treeNode*2+1, buildForDither, pal); -} - -// Finds all pixels that have changed from the previous image and -// moves them to the fromt of th buffer. -// This allows us to build a palette optimized for the colors of the -// changed pixels only. -int GifPickChangedPixels( const uint8_t* lastFrame, uint8_t* frame, int numPixels ) -{ - int numChanged = 0; - uint8_t* writeIter = frame; - - for (int ii=0; iibitDepth = bitDepth; - - // SplitPalette is destructive (it sorts the pixels by color) so - // we must create a copy of the image for it to destroy - size_t imageSize = (size_t)(width * height * 4 * sizeof(uint8_t)); - uint8_t* destroyableImage = (uint8_t*)GIF_TEMP_MALLOC(imageSize); - memcpy(destroyableImage, nextFrame, imageSize); - - int numPixels = (int)(width * height); - if(lastFrame) - numPixels = GifPickChangedPixels(lastFrame, destroyableImage, numPixels); - - const int lastElt = 1 << bitDepth; - const int splitElt = lastElt/2; - const int splitDist = splitElt/2; - - GifSplitPalette(destroyableImage, numPixels, 1, lastElt, splitElt, splitDist, 1, buildForDither, pPal); - - GIF_TEMP_FREE(destroyableImage); - - // add the bottom node for the transparency index - pPal->treeSplit[1 << (bitDepth-1)] = 0; - pPal->treeSplitElt[1 << (bitDepth-1)] = 0; - - pPal->r[0] = pPal->g[0] = pPal->b[0] = 0; -} - -// Implements Floyd-Steinberg dithering, writes palette value to alpha -void GifDitherImage( const uint8_t* lastFrame, const uint8_t* nextFrame, uint8_t* outFrame, uint32_t width, uint32_t height, GifPalette* pPal ) -{ - int numPixels = (int)(width * height); - - // quantPixels initially holds color*256 for all pixels - // The extra 8 bits of precision allow for sub-single-color error values - // to be propagated - int32_t *quantPixels = (int32_t *)GIF_TEMP_MALLOC(sizeof(int32_t) * (size_t)numPixels * 4); - - for( int ii=0; iir[bestInd]) * 256; - int32_t g_err = nextPix[1] - int32_t(pPal->g[bestInd]) * 256; - int32_t b_err = nextPix[2] - int32_t(pPal->b[bestInd]) * 256; - - nextPix[0] = pPal->r[bestInd]; - nextPix[1] = pPal->g[bestInd]; - nextPix[2] = pPal->b[bestInd]; - nextPix[3] = bestInd; - - // Propagate the error to the four adjacent locations - // that we haven't touched yet - int quantloc_7 = (int)(yy * width + xx + 1); - int quantloc_3 = (int)(yy * width + width + xx - 1); - int quantloc_5 = (int)(yy * width + width + xx); - int quantloc_1 = (int)(yy * width + width + xx + 1); - - if(quantloc_7 < numPixels) - { - int32_t* pix7 = quantPixels+4*quantloc_7; - pix7[0] += GifIMax( -pix7[0], r_err * 7 / 16 ); - pix7[1] += GifIMax( -pix7[1], g_err * 7 / 16 ); - pix7[2] += GifIMax( -pix7[2], b_err * 7 / 16 ); - } - - if(quantloc_3 < numPixels) - { - int32_t* pix3 = quantPixels+4*quantloc_3; - pix3[0] += GifIMax( -pix3[0], r_err * 3 / 16 ); - pix3[1] += GifIMax( -pix3[1], g_err * 3 / 16 ); - pix3[2] += GifIMax( -pix3[2], b_err * 3 / 16 ); - } - - if(quantloc_5 < numPixels) - { - int32_t* pix5 = quantPixels+4*quantloc_5; - pix5[0] += GifIMax( -pix5[0], r_err * 5 / 16 ); - pix5[1] += GifIMax( -pix5[1], g_err * 5 / 16 ); - pix5[2] += GifIMax( -pix5[2], b_err * 5 / 16 ); - } - - if(quantloc_1 < numPixels) - { - int32_t* pix1 = quantPixels+4*quantloc_1; - pix1[0] += GifIMax( -pix1[0], r_err / 16 ); - pix1[1] += GifIMax( -pix1[1], g_err / 16 ); - pix1[2] += GifIMax( -pix1[2], b_err / 16 ); - } - } - } - - // Copy the palettized result to the output buffer - for( int ii=0; iir[bestInd]; - outFrame[1] = pPal->g[bestInd]; - outFrame[2] = pPal->b[bestInd]; - outFrame[3] = (uint8_t)bestInd; - } - - if(lastFrame) lastFrame += 4; - outFrame += 4; - nextFrame += 4; - } -} - -// Simple structure to write out the LZW-compressed portion of the image -// one bit at a time -struct GifBitStatus -{ - uint8_t bitIndex; // how many bits in the partial byte written so far - uint8_t byte; // current partial byte - - uint32_t chunkIndex; - uint8_t chunk[256]; // bytes are written in here until we have 256 of them, then written to the file -}; - -// insert a single bit -void GifWriteBit( GifBitStatus& stat, uint32_t bit ) -{ - bit = bit & 1; - bit = bit << stat.bitIndex; - stat.byte |= bit; - - ++stat.bitIndex; - if( stat.bitIndex > 7 ) - { - // move the newly-finished byte to the chunk buffer - stat.chunk[stat.chunkIndex++] = stat.byte; - // and start a new byte - stat.bitIndex = 0; - stat.byte = 0; - } -} - -// write all bytes so far to the file -void GifWriteChunk( FILE* f, GifBitStatus& stat ) -{ - fputc((int)stat.chunkIndex, f); - fwrite(stat.chunk, 1, stat.chunkIndex, f); - - stat.bitIndex = 0; - stat.byte = 0; - stat.chunkIndex = 0; -} - -void GifWriteCode( FILE* f, GifBitStatus& stat, uint32_t code, uint32_t length ) -{ - for( uint32_t ii=0; ii> 1; - - if( stat.chunkIndex == 255 ) - { - GifWriteChunk(f, stat); - } - } -} - -// The LZW dictionary is a 256-ary tree constructed as the file is encoded, -// this is one node -struct GifLzwNode -{ - uint16_t m_next[256]; -}; - -// write a 256-color (8-bit) image palette to the file -void GifWritePalette( const GifPalette* pPal, FILE* f ) -{ - fputc(0, f); // first color: transparency - fputc(0, f); - fputc(0, f); - - for(int ii=1; ii<(1 << pPal->bitDepth); ++ii) - { - uint32_t r = pPal->r[ii]; - uint32_t g = pPal->g[ii]; - uint32_t b = pPal->b[ii]; - - fputc((int)r, f); - fputc((int)g, f); - fputc((int)b, f); - } -} - -// write the image header, LZW-compress and write out the image -void GifWriteLzwImage(FILE* f, uint8_t* image, uint32_t left, uint32_t top, uint32_t width, uint32_t height, uint32_t delay, GifPalette* pPal) -{ - // graphics control extension - fputc(0x21, f); - fputc(0xf9, f); - fputc(0x04, f); - fputc(0x05, f); // leave prev frame in place, this frame has transparency - fputc(delay & 0xff, f); - fputc((delay >> 8) & 0xff, f); - fputc(kGifTransIndex, f); // transparent color index - fputc(0, f); - - fputc(0x2c, f); // image descriptor block - - fputc(left & 0xff, f); // corner of image in canvas space - fputc((left >> 8) & 0xff, f); - fputc(top & 0xff, f); - fputc((top >> 8) & 0xff, f); - - fputc(width & 0xff, f); // width and height of image - fputc((width >> 8) & 0xff, f); - fputc(height & 0xff, f); - fputc((height >> 8) & 0xff, f); - - //fputc(0, f); // no local color table, no transparency - //fputc(0x80, f); // no local color table, but transparency - - fputc(0x80 + pPal->bitDepth-1, f); // local color table present, 2 ^ bitDepth entries - GifWritePalette(pPal, f); - - const int minCodeSize = pPal->bitDepth; - const uint32_t clearCode = 1 << pPal->bitDepth; - - fputc(minCodeSize, f); // min code size 8 bits - - GifLzwNode* codetree = (GifLzwNode*)GIF_TEMP_MALLOC(sizeof(GifLzwNode)*4096); - - memset(codetree, 0, sizeof(GifLzwNode)*4096); - int32_t curCode = -1; - uint32_t codeSize = (uint32_t)minCodeSize + 1; - uint32_t maxCode = clearCode+1; - - GifBitStatus stat; - stat.byte = 0; - stat.bitIndex = 0; - stat.chunkIndex = 0; - - GifWriteCode(f, stat, clearCode, codeSize); // start with a fresh LZW dictionary - - for(uint32_t yy=0; yy= (1ul << codeSize) ) - { - // dictionary entry count has broken a size barrier, - // we need more bits for codes - codeSize++; - } - if( maxCode == 4095 ) - { - // the dictionary is full, clear it out and begin anew - GifWriteCode(f, stat, clearCode, codeSize); // clear tree - - memset(codetree, 0, sizeof(GifLzwNode)*4096); - codeSize = (uint32_t)(minCodeSize + 1); - maxCode = clearCode+1; - } - - curCode = nextValue; - } - } - } - - // compression footer - GifWriteCode(f, stat, (uint32_t)curCode, codeSize); - GifWriteCode(f, stat, clearCode, codeSize); - GifWriteCode(f, stat, clearCode + 1, (uint32_t)minCodeSize + 1); - - // write out the last partial chunk - while( stat.bitIndex ) GifWriteBit(stat, 0); - if( stat.chunkIndex ) GifWriteChunk(f, stat); - - fputc(0, f); // image block terminator - - GIF_TEMP_FREE(codetree); -} - -struct GifWriter -{ - FILE* f; - uint8_t* oldImage; - bool firstFrame; -}; - -// Creates a gif file. -// The input GIFWriter is assumed to be uninitialized. -// The delay value is the time between frames in hundredths of a second - note that not all viewers pay much attention to this value. -bool GifBegin( GifWriter* writer, const char* filename, uint32_t width, uint32_t height, uint32_t delay, int32_t bitDepth = 8, bool dither = false ) -{ - (void)bitDepth; (void)dither; // Mute "Unused argument" warnings -#if defined(_MSC_VER) && (_MSC_VER >= 1400) - writer->f = 0; - fopen_s(&writer->f, filename, "wb"); -#else - writer->f = fopen(filename, "wb"); -#endif - if(!writer->f) return false; - - writer->firstFrame = true; - - // allocate - writer->oldImage = (uint8_t*)GIF_MALLOC(width*height*4); - - fputs("GIF89a", writer->f); - - // screen descriptor - fputc(width & 0xff, writer->f); - fputc((width >> 8) & 0xff, writer->f); - fputc(height & 0xff, writer->f); - fputc((height >> 8) & 0xff, writer->f); - - fputc(0xf0, writer->f); // there is an unsorted global color table of 2 entries - fputc(0, writer->f); // background color - fputc(0, writer->f); // pixels are square (we need to specify this because it's 1989) - - // now the "global" palette (really just a dummy palette) - // color 0: black - fputc(0, writer->f); - fputc(0, writer->f); - fputc(0, writer->f); - // color 1: also black - fputc(0, writer->f); - fputc(0, writer->f); - fputc(0, writer->f); - - if( delay != 0 ) - { - // animation header - fputc(0x21, writer->f); // extension - fputc(0xff, writer->f); // application specific - fputc(11, writer->f); // length 11 - fputs("NETSCAPE2.0", writer->f); // yes, really - fputc(3, writer->f); // 3 bytes of NETSCAPE2.0 data - - fputc(1, writer->f); // JUST BECAUSE - fputc(0, writer->f); // loop infinitely (byte 0) - fputc(0, writer->f); // loop infinitely (byte 1) - - fputc(0, writer->f); // block terminator - } - - return true; -} - -// Writes out a new frame to a GIF in progress. -// The GIFWriter should have been created by GIFBegin. -// AFAIK, it is legal to use different bit depths for different frames of an image - -// this may be handy to save bits in animations that don't change much. -bool GifWriteFrame( GifWriter* writer, const uint8_t* image, uint32_t width, uint32_t height, uint32_t delay, int bitDepth = 8, bool dither = false ) -{ - if(!writer->f) return false; - - const uint8_t* oldImage = writer->firstFrame? NULL : writer->oldImage; - writer->firstFrame = false; - - GifPalette pal; - GifMakePalette((dither? NULL : oldImage), image, width, height, bitDepth, dither, &pal); - - if(dither) - GifDitherImage(oldImage, image, writer->oldImage, width, height, &pal); - else - GifThresholdImage(oldImage, image, writer->oldImage, width, height, &pal); - - GifWriteLzwImage(writer->f, writer->oldImage, 0, 0, width, height, delay, &pal); - - return true; -} - -// Writes the EOF code, closes the file handle, and frees temp memory used by a GIF. -// Many if not most viewers will still display a GIF properly if the EOF code is missing, -// but it's still a good idea to write it out. -bool GifEnd( GifWriter* writer ) -{ - if(!writer->f) return false; - - fputc(0x3b, writer->f); // end of file - fclose(writer->f); - GIF_FREE(writer->oldImage); - - writer->f = NULL; - writer->oldImage = NULL; - - return true; -} - -#endif diff --git a/presentation/src/main/cpp/third_party/rlottie/example/lottie2gif.cpp b/presentation/src/main/cpp/third_party/rlottie/example/lottie2gif.cpp deleted file mode 100644 index cb43c219..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/lottie2gif.cpp +++ /dev/null @@ -1,178 +0,0 @@ -#include "gif.h" -#include - -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#else -#include -#include -#endif - -class GifBuilder { -public: - explicit GifBuilder(const std::string &fileName , const uint32_t width, - const uint32_t height, const int bgColor=0xffffffff, const uint32_t delay = 2) - { - GifBegin(&handle, fileName.c_str(), width, height, delay); - bgColorR = (uint8_t) ((bgColor & 0xff0000) >> 16); - bgColorG = (uint8_t) ((bgColor & 0x00ff00) >> 8); - bgColorB = (uint8_t) ((bgColor & 0x0000ff)); - } - ~GifBuilder() - { - GifEnd(&handle); - } - void addFrame(rlottie::Surface &s, uint32_t delay = 2) - { - argbTorgba(s); - GifWriteFrame(&handle, - reinterpret_cast(s.buffer()), - s.width(), - s.height(), - delay); - } - void argbTorgba(rlottie::Surface &s) - { - uint8_t *buffer = reinterpret_cast(s.buffer()); - uint32_t totalBytes = s.height() * s.bytesPerLine(); - - for (uint32_t i = 0; i < totalBytes; i += 4) { - unsigned char a = buffer[i+3]; - // compute only if alpha is non zero - if (a) { - unsigned char r = buffer[i+2]; - unsigned char g = buffer[i+1]; - unsigned char b = buffer[i]; - - if (a != 255) { //un premultiply - unsigned char r2 = (unsigned char) ((float) bgColorR * ((float) (255 - a) / 255)); - unsigned char g2 = (unsigned char) ((float) bgColorG * ((float) (255 - a) / 255)); - unsigned char b2 = (unsigned char) ((float) bgColorB * ((float) (255 - a) / 255)); - buffer[i] = r + r2; - buffer[i+1] = g + g2; - buffer[i+2] = b + b2; - - } else { - // only swizzle r and b - buffer[i] = r; - buffer[i+2] = b; - } - } else { - buffer[i+2] = bgColorB; - buffer[i+1] = bgColorG; - buffer[i] = bgColorR; - } - } - } - -private: - GifWriter handle; - uint8_t bgColorR, bgColorG, bgColorB; -}; - -class App { -public: - int render(uint32_t w, uint32_t h) - { - auto player = rlottie::Animation::loadFromFile(fileName); - if (!player) return help(); - - auto buffer = std::unique_ptr(new uint32_t[w * h]); - size_t frameCount = player->totalFrame(); - - GifBuilder builder(gifName.data(), w, h, bgColor); - for (size_t i = 0; i < frameCount ; i++) { - rlottie::Surface surface(buffer.get(), w, h, w * 4); - player->renderSync(i, surface); - builder.addFrame(surface); - } - return result(); - } - - int setup(int argc, char **argv, size_t *width, size_t *height) - { - char *path{nullptr}; - - *width = *height = 200; //default gif size - - if (argc > 1) path = argv[1]; - if (argc > 2) { - char tmp[20]; - char *x = strstr(argv[2], "x"); - if (x) { - snprintf(tmp, x - argv[2] + 1, "%s", argv[2]); - *width = atoi(tmp); - snprintf(tmp, sizeof(tmp), "%s", x + 1); - *height = atoi(tmp); - } - } - if (argc > 3) bgColor = strtol(argv[3], NULL, 16); - - if (!path) return help(); - - std::array memory; - -#ifdef _WIN32 - path = _fullpath(memory.data(), path, memory.size()); -#else - path = realpath(path, memory.data()); -#endif - if (!path) return help(); - - fileName = std::string(path); - - if (!jsonFile()) return help(); - - gifName = basename(fileName); - gifName.append(".gif"); - return 0; - } - -private: - std::string basename(const std::string &str) - { - return str.substr(str.find_last_of("/\\") + 1); - } - - bool jsonFile() { - std::string extn = ".json"; - if ( fileName.size() <= extn.size() || - fileName.substr(fileName.size()- extn.size()) != extn ) - return false; - - return true; - } - - int result() { - std::cout<<"Generated GIF file : "< -#include -#include -#include -#include -#include -#include - -#include - -static bool isJsonFile(const char *filename) { - const char *dot = strrchr(filename, '.'); - if(!dot || dot == filename) return false; - return !strcmp(dot + 1, "json"); -} - -static std::vector -jsonFiles(const std::string &dirName) -{ - DIR *d; - struct dirent *dir; - std::vector result; - d = opendir(dirName.c_str()); - if (d) { - while ((dir = readdir(d)) != NULL) { - if (isJsonFile(dir->d_name)) - result.push_back(dirName + dir->d_name); - } - closedir(d); - } - - std::sort(result.begin(), result.end(), [](auto & a, auto &b){return a < b;}); - - return result; -} - -class Renderer -{ -public: - explicit Renderer(const std::string& filename) - { - _animation = rlottie::Animation::loadFromFile(filename); - _frames = _animation->totalFrame(); - _buffer = std::make_unique(100 * 100); - _surface = rlottie::Surface(_buffer.get(), 100, 100, 100 * 4); - } - void render() - { - if (_cur >= _frames) _cur = 0; - _animation->renderSync(_cur++, _surface); - } - void renderAsync() - { - if (_cur >= _frames) _cur = 0; - _future = _animation->render(_cur++, _surface); - } - void get() - { - if (_future.valid()) _future.get(); - } -private: - std::unique_ptr _buffer; - std::unique_ptr _animation; - size_t _frames{0}; - size_t _cur{0}; - rlottie::Surface _surface; - std::future _future; -}; - -class PerfTest -{ -public: - explicit PerfTest(size_t resourceCount, size_t iterations): - _resourceCount(resourceCount), _iterations(iterations) - { - _resourceList = jsonFiles(std::string(DEMO_DIR)); - } - void test(bool async) - { - setup(); - std::cout<<" Test Started : .... \n"; - auto start = std::chrono::high_resolution_clock::now(); - benchmark(async); - std::chrono::duration secs = std::chrono::high_resolution_clock::now() - start; - std::chrono::duration millisecs = secs; - std::cout<< " Test Finished.\n"; - std::cout<< " \nPerformance Report: \n\n"; - std::cout<< " \t Resource Rendered per Frame : "<< _resourceCount <<"\n"; - std::cout<< " \t Render Buffer Size : (100 X 100) \n"; - std::cout<< " \t Render Mode : "<< (async ? "Async" : "Sync")<<"\n"; - std::cout<< " \t Total Frames Rendered : "<< _iterations<<"\n"; - std::cout<< " \t Total Render Time : "<< secs.count()<<"sec\n"; - std::cout<< " \t Avrage Time per Resource : "<< millisecs.count() / (_iterations * _resourceCount)<<"ms\n"; - std::cout<< " \t Avrage Time Per Frame : "<< millisecs.count() / _iterations <<"ms\n"; - std::cout<< " \t FPS : "<< _iterations / secs.count() <<"fps\n\n"; - } -private: - void setup() - { - for (auto i = 0u; i < _resourceCount; i++) { - auto index = i % _resourceList.size(); - _renderers.push_back(std::make_unique(_resourceList[index])); - } - } - - void benchmark(bool async) - { - for (auto i = 0u; i < _iterations; i++) { - if (async) { - for (const auto &e : _renderers) e->renderAsync(); - for (const auto &e : _renderers) e->get(); - } else { - for (const auto &e : _renderers) e->render(); - } - } - } - -private: - size_t _resourceCount; - size_t _iterations; - - std::vector _resourceList; - std::vector> _renderers; -}; - -static int help() -{ - std::cout<<"\nUsage : ./perf [--sync] [-c] [resource count] [-i] [iteration count] \n"; - std::cout<<"\nExample : ./perf -c 50 -i 100 \n"; - std::cout<<"\n\t runs perf test for 100 iterations. renders 50 resource per iteration\n\n"; - return 0; -} -int -main(int argc, char ** argv) -{ - bool async = true; - size_t resourceCount = 250; - size_t iterations = 500; - auto index = 0; - - while (index < argc) { - const char* option = argv[index]; - index++; - if (!strcmp(option,"--help") || !strcmp(option,"-h")) { - return help(); - } else if (!strcmp(option,"--sync")) { - async = false; - } else if (!strcmp(option,"-c")) { - resourceCount = (index < argc) ? atoi(argv[index]) : resourceCount; - index++; - } else if (!strcmp(option,"-i")) { - iterations = (index < argc) ? atoi(argv[index]) : iterations; - index++; - } - } - - PerfTest obj(resourceCount, iterations); - obj.test(async); - return 0; -} diff --git a/presentation/src/main/cpp/third_party/rlottie/example/lottieview.cpp b/presentation/src/main/cpp/third_party/rlottie/example/lottieview.cpp deleted file mode 100644 index 7fdf903b..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/lottieview.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include"lottieview.h" - -using namespace rlottie; - -static void -_image_update_cb(void *data, Evas_Object *obj EINA_UNUSED) -{ - RenderStrategy *info = (RenderStrategy *)data; - info->dataCb(); -} - -void RenderStrategy::addCallback(){ - if (_useImage) - evas_object_image_pixels_get_callback_set(_renderObject, _image_update_cb, this); -} - -static Eina_Bool -animator(void *data , double pos) -{ - LottieView *view = static_cast(data); - - view->seek(pos); - if (pos == 1.0) { - view->mAnimator = NULL; - view->finished(); - return EINA_FALSE; - } - return EINA_TRUE; -} - -LottieView::LottieView(Evas *evas, Strategy s) { - mPalying = false; - mReverse = false; - mRepeatCount = 0; - mRepeatMode = LottieView::RepeatMode::Restart; - mLoop = false; - mSpeed = 1; - - switch (s) { - case Strategy::renderCpp: { - mRenderDelegate = std::make_unique(evas); - break; - } - case Strategy::renderCppAsync: { - mRenderDelegate = std::make_unique(evas); - break; - } - case Strategy::renderC: { - mRenderDelegate = std::make_unique(evas); - break; - } - case Strategy::renderCAsync: { - mRenderDelegate = std::make_unique(evas); - break; - } - case Strategy::eflVg: { - mRenderDelegate = std::make_unique(evas); - break; - } - default: - mRenderDelegate = std::make_unique(evas); - break; - } -} - -LottieView::~LottieView() -{ - if (mAnimator) ecore_animator_del(mAnimator); -} - -Evas_Object *LottieView::getImage() { - return mRenderDelegate->renderObject(); -} - -void LottieView::show() -{ - mRenderDelegate->show(); - seek(0); -} - -void LottieView::hide() -{ - mRenderDelegate->hide(); -} - -void LottieView::seek(float pos) -{ - if (!mRenderDelegate) return; - - mPos = mapProgress(pos); - - // check if the pos maps to the current frame - if (mCurFrame == mRenderDelegate->frameAtPos(mPos)) return; - - mCurFrame = mRenderDelegate->frameAtPos(mPos); - - mRenderDelegate->render(mCurFrame); -} - -float LottieView::getPos() -{ - return mPos; -} - -void LottieView::setFilePath(const char *filePath) -{ - mRenderDelegate->loadFromFile(filePath); -} - -void LottieView::loadFromData(const std::string &jsonData, const std::string &key, const std::string &resourcePath) -{ - mRenderDelegate->loadFromData(jsonData, key, resourcePath); -} - -void LottieView::setSize(int w, int h) -{ - mRenderDelegate->resize(w, h); -} - -void LottieView::setPos(int x, int y) -{ - mRenderDelegate->setPos(x, y); -} - -void LottieView::finished() -{ - restart(); -} - -void LottieView::loop(bool loop) -{ - mLoop = loop; -} - -void LottieView::setRepeatCount(int count) -{ - mRepeatCount = count; -} - -void LottieView::setRepeatMode(LottieView::RepeatMode mode) -{ - mRepeatMode = mode; -} - -void LottieView::play() -{ - if (mAnimator) ecore_animator_del(mAnimator); - mAnimator = ecore_animator_timeline_add(duration()/mSpeed, animator, this); - mReverse = false; - mCurCount = mRepeatCount; - mPalying = true; -} - -void LottieView::play(const std::string &marker) -{ - size_t totalframe = getTotalFrame(); - auto frame = mRenderDelegate->findFrameAtMarker(marker); - - setMinProgress((float)std::get<0>(frame) / (float)totalframe); - if (std::get<1>(frame) != 0) - setMaxProgress((float)std::get<1>(frame) / (float)totalframe); - - this->play(); -} - -void LottieView::play(const std::string &startmarker, const std::string endmarker) -{ - size_t totalframe = getTotalFrame(); - auto stframe = mRenderDelegate->findFrameAtMarker(startmarker); - auto edframe = mRenderDelegate->findFrameAtMarker(endmarker); - - setMinProgress((float)std::get<0>(stframe) / (float)totalframe); - if (std::get<0>(edframe) != 0) - setMaxProgress((float)std::get<0>(edframe) / (float)totalframe); - - this->play(); -} - -void LottieView::pause() -{ - -} - -void LottieView::stop() -{ - mPalying = false; - if (mAnimator) { - ecore_animator_del(mAnimator); - mAnimator = NULL; - } -} - -void LottieView::restart() -{ - mCurCount--; - if (mLoop || mRepeatCount) { - if (mRepeatMode == LottieView::RepeatMode::Reverse) - mReverse = !mReverse; - else - mReverse = false; - - if (mAnimator) ecore_animator_del(mAnimator); - mAnimator = ecore_animator_timeline_add(duration()/mSpeed, animator, this); - } -} diff --git a/presentation/src/main/cpp/third_party/rlottie/example/lottieview.h b/presentation/src/main/cpp/third_party/rlottie/example/lottieview.h deleted file mode 100644 index ca8de7e1..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/lottieview.h +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef LOTTIEVIEW_H -#define LOTTIEVIEW_H - -#ifndef EFL_BETA_API_SUPPORT -#define EFL_BETA_API_SUPPORT -#endif - -#ifndef EFL_EO_API_SUPPORT -#define EFL_EO_API_SUPPORT -#endif - -#include -#include -#include -#include -#include -#include "rlottie.h" -#include "rlottie_capi.h" -#include -#include -#include - -class RenderStrategy { -public: - virtual ~RenderStrategy() { - evas_object_del(renderObject()); - } - RenderStrategy(Evas_Object *obj, bool useImage = true):_renderObject(obj), _useImage(useImage){ - addCallback(); - } - virtual rlottie::Animation *player() {return nullptr;} - virtual void loadFromFile(const char *filePath) = 0; - virtual void loadFromData(const std::string &jsonData, const std::string &key, const std::string &resourcePath) = 0; - virtual size_t totalFrame() = 0; - virtual double frameRate() = 0; - virtual size_t frameAtPos(double pos) = 0; - virtual double duration() = 0; - void render(int frame) { - _renderCount++; - _redraw = renderRequest(frame); - if (_redraw && _useImage) - evas_object_image_pixels_dirty_set(renderObject(), EINA_TRUE); - } - void dataCb() { - if (_redraw && _useImage) { - evas_object_image_data_set(renderObject(), buffer()); - } - _redraw = false; - } - virtual void resize(int width, int height) = 0; - virtual void setPos(int x, int y) {evas_object_move(renderObject(), x, y);} - typedef std::tuple MarkerFrame; - virtual MarkerFrame findFrameAtMarker(const std::string &markerName) = 0; - void show() {evas_object_show(_renderObject);} - void hide() {evas_object_hide(_renderObject);} - void addCallback(); - Evas_Object* renderObject() const {return _renderObject;} - size_t renderCount() const {return _renderCount;} -protected: - virtual bool renderRequest(int) = 0; - virtual uint32_t* buffer() = 0; -private: - size_t _renderCount{0}; - bool _redraw{false}; - Evas_Object *_renderObject; - bool _useImage{true}; -}; - -class CppApiBase : public RenderStrategy { -public: - CppApiBase(Evas_Object *renderObject): RenderStrategy(renderObject) {} - rlottie::Animation *player() {return mPlayer.get();} - void loadFromFile(const char *filePath) - { - mPlayer = rlottie::Animation::loadFromFile(filePath); - - if (!mPlayer) { - printf("load failed file %s\n", filePath); - } - } - - void loadFromData(const std::string &jsonData, const std::string &key, const std::string &resourcePath) - { - mPlayer = rlottie::Animation::loadFromData(jsonData, key, resourcePath); - - if (!mPlayer) { - printf("load failed from data\n"); - } - } - - size_t totalFrame() { - return mPlayer->totalFrame(); - - } - double duration() { - return mPlayer->duration(); - } - - double frameRate() { - return mPlayer->frameRate(); - } - - size_t frameAtPos(double pos) { - return mPlayer->frameAtPos(pos); - } - - MarkerFrame findFrameAtMarker(const std::string &markerName) - { - auto markerList = mPlayer->markers(); - auto marker = std::find_if(markerList.begin(), markerList.end() - , [&markerName](const auto& e) { - return std::get<0>(e) == markerName; - }); - if (marker == markerList.end()) - return std::make_tuple(0, 0); - return std::make_tuple(std::get<1>(*marker), std::get<2>(*marker)); - } - -protected: - std::unique_ptr mPlayer; -}; - -class RlottieRenderStrategyCBase : public RenderStrategy { -public: - RlottieRenderStrategyCBase(Evas *evas):RenderStrategy(evas_object_image_filled_add(evas)) { - evas_object_image_colorspace_set(renderObject(), EVAS_COLORSPACE_ARGB8888); - evas_object_image_alpha_set(renderObject(), EINA_TRUE); - } - void resize(int width, int height) { - evas_object_resize(renderObject(), width, height); - evas_object_image_size_set(renderObject(), width, height); - } -}; - -class RlottieRenderStrategy : public CppApiBase { -public: - RlottieRenderStrategy(Evas *evas):CppApiBase(evas_object_image_filled_add(evas)) { - evas_object_image_colorspace_set(renderObject(), EVAS_COLORSPACE_ARGB8888); - evas_object_image_alpha_set(renderObject(), EINA_TRUE); - } - void resize(int width, int height) { - evas_object_resize(renderObject(), width, height); - evas_object_image_size_set(renderObject(), width, height); - } -}; - -class RlottieRenderStrategy_CPP : public RlottieRenderStrategy { -public: - RlottieRenderStrategy_CPP(Evas *evas):RlottieRenderStrategy(evas) {} - - bool renderRequest(int frame) { - int width , height; - Evas_Object *image = renderObject(); - evas_object_image_size_get(image, &width, &height); - mBuffer = (uint32_t *)evas_object_image_data_get(image, EINA_TRUE); - size_t bytesperline = evas_object_image_stride_get(image); - rlottie::Surface surface(mBuffer, width, height, bytesperline); - mPlayer->renderSync(frame, surface); - return true; - } - uint32_t* buffer() { - return mBuffer; - } - -private: - uint32_t * mBuffer; -}; - -class RlottieRenderStrategy_CPP_ASYNC : public RlottieRenderStrategy { -public: - RlottieRenderStrategy_CPP_ASYNC(Evas *evas):RlottieRenderStrategy(evas) {} - ~RlottieRenderStrategy_CPP_ASYNC() { - if (mRenderTask.valid()) - mRenderTask.get(); - } - bool renderRequest(int frame) { - //addCallback(); - if (mRenderTask.valid()) return true; - int width , height; - Evas_Object *image = renderObject(); - evas_object_image_size_get(image, &width, &height); - auto buffer = (uint32_t *)evas_object_image_data_get(image, EINA_TRUE); - size_t bytesperline = evas_object_image_stride_get(image); - rlottie::Surface surface(buffer, width, height, bytesperline); - mRenderTask = mPlayer->render(frame, surface); - return true; - } - - uint32_t* buffer() { - auto surface = mRenderTask.get(); - return surface.buffer(); - } -private: - std::future mRenderTask; -}; - - -class RlottieRenderStrategy_C : public RlottieRenderStrategyCBase { -public: - RlottieRenderStrategy_C(Evas *evas):RlottieRenderStrategyCBase(evas) {} - ~RlottieRenderStrategy_C() { - if (mPlayer) lottie_animation_destroy(mPlayer); - } - void loadFromFile(const char *filePath) - { - mPlayer = lottie_animation_from_file(filePath); - - if (!mPlayer) { - printf("load failed file %s\n", filePath); - } - } - - void loadFromData(const std::string &jsonData, const std::string &key, const std::string &resourcePath) - { - mPlayer = lottie_animation_from_data(jsonData.c_str(), key.c_str(), resourcePath.c_str()); - if (!mPlayer) { - printf("load failed from data\n"); - } - } - - size_t totalFrame() { - return lottie_animation_get_totalframe(mPlayer); - - } - - double frameRate() { - return lottie_animation_get_framerate(mPlayer); - } - - size_t frameAtPos(double pos) { - return lottie_animation_get_frame_at_pos(mPlayer, pos); - } - - double duration() { - return lottie_animation_get_duration(mPlayer); - } - MarkerFrame findFrameAtMarker(const std::string &markerName) - { - printf("Can't not [%s] marker, CAPI isn't implements yet\n", markerName.c_str()); - return std::make_tuple(0, 0); - } - - bool renderRequest(int frame) { - int width , height; - Evas_Object *image = renderObject(); - evas_object_image_size_get(image, &width, &height); - mBuffer = (uint32_t *)evas_object_image_data_get(image, EINA_TRUE); - size_t bytesperline = evas_object_image_stride_get(image); - lottie_animation_render(mPlayer, frame, mBuffer, width, height, bytesperline); - return true; - } - - uint32_t* buffer() { - return mBuffer; - } - -private: - uint32_t * mBuffer; -protected: - Lottie_Animation *mPlayer; -}; - -class RlottieRenderStrategy_C_ASYNC : public RlottieRenderStrategy_C { -public: - RlottieRenderStrategy_C_ASYNC(Evas *evas):RlottieRenderStrategy_C(evas) {} - ~RlottieRenderStrategy_C_ASYNC() { - if (mDirty) lottie_animation_render_flush(mPlayer); - } - bool renderRequest(int frame) { - if (mDirty) return true; - mDirty = true; - Evas_Object *image = renderObject(); - evas_object_image_size_get(image, &mWidth, &mHeight); - mBuffer = (uint32_t *)evas_object_image_data_get(image, EINA_TRUE); - size_t bytesperline = evas_object_image_stride_get(image); - lottie_animation_render_async(mPlayer, frame, mBuffer, mWidth, mHeight, bytesperline); - return true; - } - - uint32_t* buffer() { - lottie_animation_render_flush(mPlayer); - mDirty =false; - return mBuffer; - } - -private: - uint32_t * mBuffer; - int mWidth; - int mHeight; - bool mDirty{false}; -}; - -enum class Strategy { - renderCpp = 0, - renderCppAsync, - renderC, - renderCAsync, - eflVg -}; - -class LottieView -{ -public: - enum class RepeatMode { - Restart, - Reverse - }; - LottieView(Evas *evas, Strategy s = Strategy::renderCppAsync); - ~LottieView(); - rlottie::Animation *player(){return mRenderDelegate->player();} - Evas_Object *getImage(); - void setSize(int w, int h); - void setPos(int x, int y); - void setFilePath(const char *filePath); - void loadFromData(const std::string &jsonData, const std::string &key, const std::string &resourcePath=""); - void show(); - void hide(); - void loop(bool loop); - void setSpeed(float speed) { mSpeed = speed;} - void setRepeatCount(int count); - void setRepeatMode(LottieView::RepeatMode mode); - float getFrameRate() const { return mRenderDelegate->frameRate(); } - long getTotalFrame() const { return mRenderDelegate->totalFrame(); } -public: - void seek(float pos); - float getPos(); - void finished(); - void play(); - void play(const std::string &marker); - void play(const std::string &startmarker, const std::string endmarker); - void pause(); - void stop(); - void initializeBufferObject(Evas *evas); - void setMinProgress(float progress) - { - //clamp it to [0,1] - mMinProgress = progress; - } - void setMaxProgress(float progress) - { - //clamp it to [0,1] - mMaxprogress = progress; - } - - size_t renderCount() const { - return mRenderDelegate ? mRenderDelegate->renderCount() : 0; - } -private: - float mapProgress(float progress) { - //clamp it to the segment - progress = (mMinProgress + (mMaxprogress - mMinProgress) * progress); - - // currently playing and in reverse mode - if (mPalying && mReverse) - progress = mMaxprogress > mMinProgress ? - mMaxprogress - progress : mMinProgress - progress; - - - return progress; - } - float duration() const { - // usually we run the animation for mPlayer->duration() - // but now run animation for segmented duration. - return mRenderDelegate->duration() * fabs(mMaxprogress - mMinProgress); - } - void createVgNode(LOTNode *node, Efl_VG *root); - void update(const std::vector &); - void updateTree(const LOTLayerNode *); - void update(const LOTLayerNode *, Efl_VG *parent); - void restart(); -public: - int mRepeatCount; - LottieView::RepeatMode mRepeatMode; - size_t mCurFrame{UINT_MAX}; - Ecore_Animator *mAnimator{nullptr}; - bool mLoop; - int mCurCount; - bool mReverse; - bool mPalying; - float mSpeed; - float mPos; - //keep a segment of the animation default is [0, 1] - float mMinProgress{0}; - float mMaxprogress{1}; - std::unique_ptr mRenderDelegate; -}; - -#include -class EflVgRenderStrategy : public RenderStrategy { -public: - EflVgRenderStrategy(Evas *evas):RenderStrategy(evas_object_vg_add(evas), false) {} - - void loadFromFile(const char *filePath) { - evas_object_vg_file_set(renderObject(), filePath, NULL); - } - - void loadFromData(const std::string&, const std::string&, const std::string&) { - assert(false); - } - - size_t totalFrame() { - return evas_object_vg_animated_frame_count_get(renderObject()) - 1; - } - - double frameRate() { - return (double)totalFrame() / evas_object_vg_animated_frame_duration_get(renderObject(), 0, 0); - } - - size_t frameAtPos(double pos) { - return totalFrame() * pos; - } - - double duration() { - return evas_object_vg_animated_frame_duration_get(renderObject(), 0, 0); - } - - void resize(int width, int height) { - evas_object_resize(renderObject(), width, height); - } - - uint32_t *buffer() { - assert(false); - return nullptr; - } - - bool renderRequest(int frame) { - evas_object_vg_animated_frame_set(renderObject(), frame); - return false; - } - - MarkerFrame findFrameAtMarker(const std::string&) { - return std::make_tuple(0, 0); - } -}; - -#endif //LOTTIEVIEW_H diff --git a/presentation/src/main/cpp/third_party/rlottie/example/lottieviewer.cpp b/presentation/src/main/cpp/third_party/rlottie/example/lottieviewer.cpp deleted file mode 100644 index d3d86f35..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/lottieviewer.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include "lottieview.h" -#include "evasapp.h" -#include -#include -#include -#include -#include -#include -#include - -using namespace std; - -typedef struct _AppInfo AppInfo; -struct _AppInfo { - LottieView *view; - Evas_Object *layout; - Evas_Object *slider; - Evas_Object *button; - Ecore_Animator *animator; - Eina_Bool autoPlaying; -}; - -typedef struct _ItemData ItemData; -struct _ItemData { - int index; -}; - - -std::vector jsonFiles; -bool renderMode = true; - -static void -_layout_del_cb(void *data, Evas *, Evas_Object *, void *) -{ - AppInfo *info = (AppInfo *)data; - if (info->view) delete info->view; - ecore_animator_del(info->animator); - free(info); -} - -static void -_update_frame_info(AppInfo *info) -{ - long currFrameNo = info->view->mCurFrame; - long totalFrameNo = info->view->getTotalFrame(); - - char buf[64]; - sprintf(buf, "%ld (total: %ld)", currFrameNo, totalFrameNo); - elm_object_part_text_set(info->layout, "text", buf); -} - -static void -_toggle_start_button(AppInfo *info) -{ - if (!info->autoPlaying) - { - info->autoPlaying = EINA_TRUE; - info->view->play(); - elm_object_text_set(info->button, "Stop"); - } - else - { - info->autoPlaying = EINA_FALSE; - info->view->stop(); - elm_object_text_set(info->button, "Start"); - } -} - -static Eina_Bool -_animator_cb(void *data) -{ - AppInfo *info = (AppInfo *)data; - - if (info && info->autoPlaying && info->view) - { - float pos = info->view->getPos(); - _update_frame_info(info); - elm_slider_value_set(info->slider, (double)pos); - evas_object_image_pixels_dirty_set(info->view->getImage(), EINA_TRUE); - if (pos >= 1.0) - _toggle_start_button(info); - } - return ECORE_CALLBACK_RENEW; -} - -static void -_slider_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) -{ - double val = elm_slider_value_get(obj); - AppInfo *info = (AppInfo *)data; - - if (!info->autoPlaying) - { - info->view->seek(val); - evas_object_image_pixels_dirty_set(info->view->getImage(), EINA_TRUE); - } - - _update_frame_info(info); -} - -static void -_button_clicked_cb(void *data, Evas_Object */*obj*/, void */*event_info*/) -{ - AppInfo *info = (AppInfo *)data; - if (info->view->getPos() >= 1.0f) info->view->mPos = 0.0f; - _toggle_start_button(info); -} - -Evas_Object * -create_layout(Evas_Object *parent, const char *file) -{ - Evas_Object *layout, *slider, *image, *button; - Ecore_Animator *animator; - AppInfo *info = (AppInfo *)calloc(sizeof(AppInfo), 1); - - //LAYOUT - layout = elm_layout_add(parent); - evas_object_show(layout); - evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - - std::string edjPath = DEMO_DIR; - edjPath +="layout.edj"; - - elm_layout_file_set(layout, edjPath.c_str(), "layout"); - - //LOTTIEVIEW - LottieView *view = new LottieView(evas_object_evas_get(layout), Strategy::renderCppAsync); - view->setFilePath(file); - view->setSize(500, 500); - - //IMAGE from LOTTIEVIEW - image = view->getImage(); - evas_object_show(image); - elm_object_part_content_set(layout, "lottie", image); - - //SLIDER - slider = elm_slider_add(layout); - elm_object_part_content_set(layout, "slider", slider); - elm_slider_step_set(slider, 0.01); - evas_object_smart_callback_add(slider, "changed", _slider_cb, (void *)info); - - button = elm_button_add(layout); - elm_object_text_set(button, "Start"); - elm_object_part_content_set(layout, "button", button); - evas_object_smart_callback_add(button, "clicked", _button_clicked_cb, (void *)info); - - animator = ecore_animator_add(_animator_cb, info); - - info->view = view; - info->layout = layout; - info->slider = slider; - info->button = button; - info->animator = animator; - evas_object_event_callback_add(layout, EVAS_CALLBACK_DEL, _layout_del_cb, (void *)info); - - view->seek(0.0); - _update_frame_info(info); - - return layout; -} - -static void -_gl_selected_cb(void *data, Evas_Object */*obj*/, void *event_info) -{ - Evas_Object *nf = (Evas_Object *)data; - Elm_Object_Item *it = (Elm_Object_Item *)event_info; - elm_genlist_item_selected_set(it, EINA_FALSE); - - Evas_Object *layout = create_layout(nf, jsonFiles[elm_genlist_item_index_get(it) - 1].c_str()); - elm_naviframe_item_push(nf, NULL, NULL, NULL, layout, NULL); -} - -static char * -_gl_text_get(void *data, Evas_Object */*obj*/, const char */*part*/) -{ - ItemData *id = (ItemData *) data; - const char *ptr = strrchr(jsonFiles[id->index].c_str(), '/'); - int len = int(ptr + 1 - jsonFiles[id->index].c_str()); // +1 to include '/' - return strdup(jsonFiles[id->index].substr(len).c_str()); -} - -static void -_gl_del(void */*data*/, Evas_Object */*obj*/) -{ -} - -EAPI_MAIN int -elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) -{ - Evas_Object *win, *nf, *genlist; - Elm_Genlist_Item_Class *itc = elm_genlist_item_class_new(); - ItemData *itemData; - - - if (argc > 1) { - if (!strcmp(argv[1], "--disable-render")) - renderMode = false; - } - - //WIN - elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED); - win = elm_win_util_standard_add("lottie", "LottieViewer"); - elm_win_autodel_set(win, EINA_TRUE); - evas_object_resize(win, 500, 700); - evas_object_show(win); - - //NAVIFRAME - nf = elm_naviframe_add(win); - evas_object_size_hint_weight_set(nf, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - elm_win_resize_object_add(win, nf); - evas_object_show(nf); - - //GENLIST - genlist = elm_genlist_add(nf); - elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS); - evas_object_smart_callback_add(genlist, "selected", _gl_selected_cb, nf); - - itc->item_style = "default"; - itc->func.text_get = _gl_text_get; - itc->func.del = _gl_del; - - jsonFiles = EvasApp::jsonFiles(DEMO_DIR); - - for (uint32_t i = 0; i < jsonFiles.size(); i++) { - itemData = (ItemData *)calloc(sizeof(ItemData), 1); - itemData->index = i; - elm_genlist_item_append(genlist, itc, (void *)itemData, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL); - } - - elm_naviframe_item_push(nf, "Lottie Viewer", NULL, NULL, genlist, NULL); - - elm_run(); - - return 0; -} -ELM_MAIN() diff --git a/presentation/src/main/cpp/third_party/rlottie/example/lottieviewtest.cpp b/presentation/src/main/cpp/third_party/rlottie/example/lottieviewtest.cpp deleted file mode 100644 index 402fcd27..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/lottieviewtest.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "evasapp.h" -#include "lottieview.h" -#include -#include -#include -#include -using namespace std; - -static Eina_Bool onTestDone(void *data); -/* - * To check the frame rate with rendermode off run - * ECORE_EVAS_FPS_DEBUG=1 ./lottieviewTest --disable-render - * - * To check the frame rate with render backend - * ECORE_EVAS_FPS_DEBUG=1 ./lottieviewTest - * - */ - -class LottieViewTest -{ -public: - LottieViewTest(EvasApp *app, Strategy st, double timeout) { - mStartTime = std::chrono::high_resolution_clock::now(); - mStrategy = st; - mApp = app; - - if (timeout > 0) { - ecore_timer_add(timeout, onTestDone, mApp); - } - // work around for 60fps - ecore_animator_frametime_set(1.0f/120.0f); - } - - void show(int numberOfImage) { - auto resource = EvasApp::jsonFiles(std::string(DEMO_DIR)); - - if (resource.empty()) return; - - int count = numberOfImage; - int colums = (int) ceil(sqrt(count)); - int offset = 3; - int vw = (mApp->width() - (offset * colums))/colums; - int vh = vw; - int posx = offset; - int posy = offset; - int resourceSize = resource.size(); - for (int i = 0 ; i < numberOfImage; i++) { - int index = i % resourceSize; - std::unique_ptr view(new LottieView(mApp->evas(), mStrategy)); - view->setFilePath(resource[index].c_str()); - view->setPos(posx, posy); - view->setSize(vw, vh); - view->show(); - view->play(); - view->loop(true); - //view->setRepeatMode(LottieView::RepeatMode::Reverse); - posx += vw+offset; - if ((mApp->width() - posx) < vw) { - posx = offset; - posy = posy + vh + offset; - } - mViews.push_back(std::move(view)); - } - } - - ~LottieViewTest() { - const auto frames = mViews.empty() ? 0 : mViews[0]->renderCount(); - const double secs = std::chrono::duration(std::chrono::high_resolution_clock::now() - mStartTime).count(); - std::cout<<"\tTestTime : "<< secs<<" sec \n\tTotalFrames : "<> mViews; - std::chrono::high_resolution_clock::time_point mStartTime; -}; - -static void -onExitCb(void *data, void */*extra*/) -{ - LottieViewTest *view = (LottieViewTest *)data; - delete view; -} - - -static Eina_Bool -onTestDone(void *data) -{ - EvasApp *app = (EvasApp *)data; - app->exit(); - return ECORE_CALLBACK_CANCEL; -} - -int -main(int argc, char **argv) -{ - Strategy st = Strategy::renderCppAsync; - auto index = 0; - double timeOut = 0; - size_t itemCount = 250; - while (index < argc) { - const char* option = argv[index]; - index++; - if (!strcmp(option,"--help") || !strcmp(option,"-h")) { - return LottieViewTest::help(); - } else if (!strcmp(option,"-s")) { - st = (index < argc) ? static_cast(atoi(argv[index])) : Strategy::renderCppAsync; - index++; - } else if (!strcmp(option,"-t")) { - timeOut = (index < argc) ? atoi(argv[index]) : 10; - index++; - } else if (!strcmp(option,"-c")) { - itemCount = (index < argc) ? atoi(argv[index]) : 10; - index++; - } - } - - EvasApp *app = new EvasApp(800, 800); - app->setup(); - - LottieViewTest *view = new LottieViewTest(app, st, timeOut); - view->show(itemCount); - - app->addExitCb(onExitCb, view); - - app->run(); - delete app; - return 0; -} - - - - - diff --git a/presentation/src/main/cpp/third_party/rlottie/example/meson.build b/presentation/src/main/cpp/third_party/rlottie/example/meson.build deleted file mode 100644 index f5b864b4..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/meson.build +++ /dev/null @@ -1,74 +0,0 @@ - -override_default = ['warning_level=2', 'werror=false'] - -common_source = files('evasapp.cpp') -common_source += files('lottieview.cpp') - -demo_sources = files('demo.cpp') -demo_sources += common_source - -executable('lottie2gif', - 'lottie2gif.cpp', - include_directories : inc, - override_options : override_default, - link_with : rlottie_lib) - -if host_machine.system() != 'windows' - executable('perf', - 'lottieperf.cpp', - include_directories : inc, - override_options : override_default, - link_with : rlottie_lib) -endif - -demo_dep = dependency('elementary', required : false, disabler : true) - -executable('demo', - demo_sources, - include_directories : inc, - override_options : override_default, - link_with : rlottie_lib, - dependencies : demo_dep) - - -demo_marker_sources = files('demo_marker.cpp') -demo_marker_sources += common_source - -executable('demo_marker', - demo_marker_sources, - include_directories : inc, - override_options : override_default, - link_with : rlottie_lib, - dependencies : demo_dep) - -lottieview_test_src = files('lottieviewtest.cpp') -lottieview_test_src += common_source - -executable('lottieviewTest', - lottieview_test_src, - include_directories : inc, - override_options : override_default, - link_with : rlottie_lib, - dependencies : demo_dep) - -uxsample_test_src = files('uxsampletest.cpp') -uxsample_test_src += common_source - -executable('uxsampleTest', - uxsample_test_src, - include_directories : inc, - override_options : override_default, - link_with : rlottie_lib, - dependencies : demo_dep) - -lottieviewer_sources = files('lottieviewer.cpp') -lottieviewer_sources += common_source - -executable('lottieviewer', - lottieviewer_sources, - include_directories : inc, - override_options : override_default, - link_with : rlottie_lib, - dependencies : demo_dep) - - diff --git a/presentation/src/main/cpp/third_party/rlottie/example/pathtest.cpp b/presentation/src/main/cpp/third_party/rlottie/example/pathtest.cpp deleted file mode 100644 index be16f33b..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/pathtest.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "evasapp.h" -#include"vpath.h" -#include -using namespace std; - -EvasApp *APP; - -static void -_on_resize(Ecore_Evas *ee) -{ - int w, h; - ecore_evas_geometry_get(ee, NULL, NULL, &w, &h); - APP->resize(w, h); -} - -class PathTest -{ -public: - PathTest(EvasApp *app) { - mApp = app; - mShape = evas_vg_shape_add(mApp->root()); - } - void setColor(int r, int g, int b, int a) { - evas_vg_node_color_set(mShape, r, g, b, a); - } - - void setStrokeColor(int r, int g, int b, int a) { - evas_vg_shape_stroke_color_set(mShape, r, g, b, a); - } - - void setStrokeWidth(int w) { - evas_vg_shape_stroke_width_set(mShape, w); - } - - void setPath(const VPath &path) { - Efl_VG *shape = mShape; - evas_vg_shape_reset(shape); - const std::vector &elm = path.elements(); - const std::vector &pts = path.points(); - int i=0; - for (auto e : elm) { - switch(e) { - case VPath::Element::MoveTo: - { - VPointF p = pts[i++]; - evas_vg_shape_append_move_to(shape, p.x(), p.y()); - break; - } - case VPath::Element::LineTo: - { - VPointF p = pts[i++]; - evas_vg_shape_append_line_to(shape, p.x(), p.y()); - break; - } - case VPath::Element::CubicTo: - { - VPointF p = pts[i++]; - VPointF p1 = pts[i++]; - VPointF p2 = pts[i++]; - evas_vg_shape_append_cubic_to(shape, p.x(), p.y(), p1.x(), p1.y(), p2.x(), p2.y()); - break; - } - case VPath::Element::Close: - { - evas_vg_shape_append_close(shape); - break; - } - } - } - } - -public: - EvasApp *mApp; - Efl_VG *mShape; -}; - -int -main(void) -{ - APP = new EvasApp(800, 800); - ecore_evas_callback_resize_set(APP->mEcoreEvas, _on_resize); - APP->setup(); - - VPath path; - path.addRoundRect(VRectF(100, 100, 200, 200), 20, 20, VPath::Direction::CCW); - path.addCircle(50, 50, 20, VPath::Direction::CCW); - - path.addOval(VRectF(300, 100, 100, 50), VPath::Direction::CCW); - - path.addPolystar(15.0, 106.0, 34.0, 0.0, 150, - 150, 231.0, 88.0, VPath::Direction::CW); - - PathTest test(APP); - test.setPath(path); - test.setColor(255, 0, 0, 255); - test.setStrokeColor(200, 200, 0, 200); - test.setStrokeWidth(5); - - - APP->run(); - delete APP; - return 0; -} - - - - - diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/1643-exploding-star.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/1643-exploding-star.json deleted file mode 100644 index badb8fd3..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/1643-exploding-star.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.12.0","fr":29.9700012207031,"ip":0,"op":60.0000024438501,"w":400,"h":400,"nm":"explodingStar","ddd":0,"assets":[{"id":"comp_29","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-19,"ix":10},"p":{"a":0,"k":[200.25,201.125,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[51.125,51.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200,202.875,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[37.875,37.875,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[190,205.25,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[30.875,30.875,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[208.25,210.75,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[30.875,30.875,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[204.125,189.875,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[30.875,30.875,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[196.875,194.625,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[30.875,30.875,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[177.625,190.875,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[14.125,14.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200.875,213.5,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[14.125,14.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[194.5,211.375,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[12.5,12.5,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200.5,190.25,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[15,15,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[210.625,183.375,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[13.875,13.875,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[192.875,174.125,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[13.875,13.875,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[181,196,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[13.875,13.875,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[187.25,215.625,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[13.875,13.875,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[204.625,199.375,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[13.875,13.875,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[188.125,226.375,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[11.125,11.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[178.5,217.75,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[11.125,11.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[174.5,199.875,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[11.125,11.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[180.25,184.5,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[11.125,11.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[193.25,190.625,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[11.125,11.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":21,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[207.875,189.875,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[11.125,11.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":22,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[216,211.25,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[11.125,11.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":23,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[208.375,217,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[11.125,11.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":24,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[235.375,189.75,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[11.125,11.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":25,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[229.5,186,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[11.125,11.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":26,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[204,167.375,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[11.125,11.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":27,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[196.375,167.75,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[11.125,11.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":28,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":36,"ix":10},"p":{"a":0,"k":[200.125,156.75,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[7.5,7.75,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":29,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[225.375,235,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[7.5,7.75,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":30,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[175,234.375,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[7.5,7.75,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":31,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":17,"ix":10},"p":{"a":0,"k":[159.375,186.875,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[7.5,7.75,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":32,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":21,"ix":10},"p":{"a":0,"k":[240.875,186.75,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[7.5,7.75,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":33,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[231.75,195.125,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[10.125,10.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":34,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[222,212.5,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[10.125,10.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":35,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[205.75,223.75,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[10.125,10.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":36,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[181.875,216.25,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[10.125,10.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":37,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[185.125,190.25,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[10.125,10.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":38,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200.25,159.75,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[10.125,10.125,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":39,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[182,207,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[15.375,15.375,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":40,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[208.5,209.75,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[15.375,15.375,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":41,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[218.125,186.625,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[15.375,15.375,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":42,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[191.75,180.875,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[15.375,15.375,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":43,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[195.125,220.5,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[15.375,15.375,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":44,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[179.875,227.375,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[15.375,15.375,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":45,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[220.125,198.25,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[21,21,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":46,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[218.375,224.875,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[19,19,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":47,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[204.5,177.875,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[19,19,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":48,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[192.75,202.5,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[19.875,19.875,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":49,"ty":0,"nm":"ronddiminue","refId":"comp_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[171.375,190.625,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[19,19,100],"ix":6}},"ao":0,"w":200,"h":200,"ip":0,"op":150.000006109625,"st":0,"bm":0}]},{"id":"comp_30","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Calque de forme 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.571,"y":0.93},"o":{"x":0.167,"y":0.167},"n":"0p571_0p93_0p167_0p167","t":0,"s":[100,100,0],"e":[100,69.985,0],"to":[0,-0.17251245677471,0],"ti":[0,9.91851329803467,0]},{"i":{"x":0.731,"y":1},"o":{"x":0.343,"y":0.505},"n":"0p731_1_0p343_0p505","t":3,"s":[100,69.985,0],"e":[100,40,0],"to":[0,-9.9765567779541,0],"ti":[0,0.03740864992142,0]},{"t":30.0000012219251}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.57,0.57,0.57],"y":[0.896,0.896,6.336]},"o":{"x":[0.194,0.194,0.194],"y":[0.038,0.038,-1.924]},"n":["0p57_0p896_0p194_0p038","0p57_0p896_0p194_0p038","0p57_6p336_0p194_-1p924"],"t":0,"s":[100,100,100],"e":[48.393,48.393,100]},{"i":{"x":[0.704,0.704,0.704],"y":[1,1,1]},"o":{"x":[0.328,0.328,0.328],"y":[0.781,0.781,-36.631]},"n":["0p704_1_0p328_0p781","0p704_1_0p328_0p781","0p704_1_0p328_-36p631"],"t":3,"s":[48.393,48.393,100],"e":[1,1,100]},{"t":30.0000012219251}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[21.4,0],[0,-21.4],[-21.4,0],[0,21.4]],"o":[[-21.4,0],[0,21.4],[21.4,0],[0,-21.4]],"v":[[0,-38.748],[-38.748,0],[0,38.748],[38.748,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.435294121504,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[130,130],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":31.0000012626559,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Calque de forme 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.57,"y":0.93},"o":{"x":0.167,"y":0.167},"n":"0p57_0p93_0p167_0p167","t":0,"s":[100,100,0],"e":[130.638,100,0],"to":[3.4184627532959,0,0],"ti":[-8.54281234741211,0,0]},{"i":{"x":0.704,"y":1},"o":{"x":0.328,"y":0.504},"n":"0p704_1_0p328_0p504","t":3,"s":[130.638,100,0],"e":[160,100,0],"to":[8.11733150482178,0,0],"ti":[-3.24820375442505,0,0]},{"t":30.0000012219251}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.57,0.57,0.57],"y":[0.896,0.896,6.336]},"o":{"x":[0.194,0.194,0.194],"y":[0.038,0.038,-1.924]},"n":["0p57_0p896_0p194_0p038","0p57_0p896_0p194_0p038","0p57_6p336_0p194_-1p924"],"t":0,"s":[100,100,100],"e":[48.393,48.393,100]},{"i":{"x":[0.704,0.704,0.704],"y":[1,1,1]},"o":{"x":[0.328,0.328,0.328],"y":[0.781,0.781,-36.631]},"n":["0p704_1_0p328_0p781","0p704_1_0p328_0p781","0p704_1_0p328_-36p631"],"t":3,"s":[48.393,48.393,100],"e":[1,1,100]},{"t":30.0000012219251}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[21.4,0],[0,-21.4],[-21.4,0],[0,21.4]],"o":[[-21.4,0],[0,21.4],[21.4,0],[0,-21.4]],"v":[[0,-38.748],[-38.748,0],[0,38.748],[38.748,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.435294121504,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[130,130],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":31.0000012626559,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Calque de forme 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.57,"y":0.93},"o":{"x":0.167,"y":0.167},"n":"0p57_0p93_0p167_0p167","t":0,"s":[100,100,0],"e":[100,130.638,0],"to":[0,3.4184627532959,0],"ti":[0,-8.54281234741211,0]},{"i":{"x":0.704,"y":1},"o":{"x":0.328,"y":0.504},"n":"0p704_1_0p328_0p504","t":3,"s":[100,130.638,0],"e":[100,160,0],"to":[0,8.11733150482178,0],"ti":[0,-3.24820375442505,0]},{"t":30.0000012219251}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.57,0.57,0.57],"y":[0.896,0.896,6.336]},"o":{"x":[0.194,0.194,0.194],"y":[0.038,0.038,-1.924]},"n":["0p57_0p896_0p194_0p038","0p57_0p896_0p194_0p038","0p57_6p336_0p194_-1p924"],"t":0,"s":[100,100,100],"e":[48.393,48.393,100]},{"i":{"x":[0.704,0.704,0.704],"y":[1,1,1]},"o":{"x":[0.328,0.328,0.328],"y":[0.781,0.781,-36.631]},"n":["0p704_1_0p328_0p781","0p704_1_0p328_0p781","0p704_1_0p328_-36p631"],"t":3,"s":[48.393,48.393,100],"e":[1,1,100]},{"t":30.0000012219251}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[21.4,0],[0,-21.4],[-21.4,0],[0,21.4]],"o":[[-21.4,0],[0,21.4],[21.4,0],[0,-21.4]],"v":[[0,-38.748],[-38.748,0],[0,38.748],[38.748,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.435294121504,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[130,130],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":31.0000012626559,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Calque de forme 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.57,"y":0.93},"o":{"x":0.167,"y":0.167},"n":"0p57_0p93_0p167_0p167","t":0,"s":[100,100,0],"e":[69.355,100,0],"to":[-3.41931676864624,0,0],"ti":[8.54487895965576,0,0]},{"i":{"x":0.704,"y":1},"o":{"x":0.328,"y":0.504},"n":"0p704_1_0p328_0p504","t":3,"s":[69.355,100,0],"e":[40,100,0],"to":[-8.11513328552246,0,0],"ti":[3.24734997749329,0,0]},{"t":30.0000012219251}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.57,0.57,0.57],"y":[0.896,0.896,6.336]},"o":{"x":[0.194,0.194,0.194],"y":[0.038,0.038,-1.924]},"n":["0p57_0p896_0p194_0p038","0p57_0p896_0p194_0p038","0p57_6p336_0p194_-1p924"],"t":0,"s":[100,100,100],"e":[48.393,48.393,100]},{"i":{"x":[0.704,0.704,0.704],"y":[1,1,1]},"o":{"x":[0.328,0.328,0.328],"y":[0.781,0.781,-36.631]},"n":["0p704_1_0p328_0p781","0p704_1_0p328_0p781","0p704_1_0p328_-36p631"],"t":3,"s":[48.393,48.393,100],"e":[1,1,100]},{"t":30.0000012219251}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[21.4,0],[0,-21.4],[-21.4,0],[0,21.4]],"o":[[-21.4,0],[0,21.4],[21.4,0],[0,-21.4]],"v":[[0,-38.748],[-38.748,0],[0,38.748],[38.748,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.435294121504,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[130,130],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":31.0000012626559,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Précomp. 2","td":1,"refId":"comp_29","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200,200,0],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,50]},"n":["0p667_1_0p167_0p167","0p667_1_0p167_0p167","0p667_1_0p167_50"],"t":30,"s":[100,100,100],"e":[400,400,100]},{"t":60.0000024438501}],"ix":6}},"ao":0,"w":400,"h":400,"ip":30.0000012219251,"op":180.00000733155,"st":30.0000012219251,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Calque de forme 1","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200,200,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[207.859,-205.404],[-207.859,-205.404],[-207.859,205.404],[207.859,205.404]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.709803938866,0.219607844949,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-1.141,0.404],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30.0000012219251,"op":180.00000733155,"st":30.0000012219251,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"Précomp. 2","refId":"comp_29","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200,200,0],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,49.858]},"n":["0p667_1_0p167_0p167","0p667_1_0p167_0p167","0p667_1_0p167_49p858"],"t":30,"s":[118,118,100],"e":[400,400,100]},{"t":60.0000024438501}],"ix":6}},"ao":0,"w":400,"h":400,"ip":30.0000012219251,"op":180.00000733155,"st":30.0000012219251,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"etoile Silhouettes","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200,196,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[0.001,-77.997],[27.025,-28.974],[81.99,-18.413],[43.729,22.447],[50.673,77.997],[0.001,54.223],[-50.673,77.997],[-43.728,22.447],[-81.99,-18.413],[-27.025,-28.974]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.709999952129,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.499,399.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.154,0],[1.391,1.009],[-0.362,2.892],[0,0],[0,0],[-0.9,2.772],[-2.862,0.55],[0,0],[0,0],[-2.915,0],[-1.406,-2.553],[0,0],[0,0],[-0.9,-2.771],[1.993,-2.128],[0,0],[0,0],[2.36,-1.713],[1.66,0],[1.082,0.508],[0,0],[0,0]],"o":[[-1.661,0],[-2.358,-1.713],[0,0],[0,0],[-1.991,-2.127],[0.901,-2.771],[0,0],[0,0],[1.407,-2.553],[2.914,0],[0,0],[0,0],[2.862,0.55],[0.902,2.772],[0,0],[0,0],[0.363,2.89],[-1.39,1.009],[-1.156,0],[0,0],[0,0],[-1.082,0.508]],"v":[[-50.674,85.996],[-55.377,84.47],[-58.613,77.005],[-52.133,25.178],[-87.83,-12.944],[-89.599,-20.884],[-83.5,-26.268],[-32.221,-36.121],[-7.007,-81.858],[-0.001,-85.996],[7.005,-81.858],[32.218,-36.121],[83.499,-26.268],[89.597,-20.884],[87.829,-12.943],[52.13,25.178],[58.611,77.005],[55.374,84.47],[50.673,85.996],[47.275,85.238],[-0.001,63.06],[-47.278,85.238]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.435000002384,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.501,399.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Groupe 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":32.0000013033867,"st":0,"bm":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/1667-firework.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/1667-firework.json deleted file mode 100644 index 76eb2ead..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/1667-firework.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.12.0","fr":29.9700012207031,"ip":0,"op":78.0000031770051,"w":800,"h":800,"nm":"feudartifis","ddd":0,"assets":[{"id":"comp_36","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"dota2x6","refId":"comp_37","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":45,"ix":10},"p":{"a":0,"k":[520,520,0],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":400,"h":400,"ip":34.0000013848484,"op":80.0000032584668,"st":34.0000013848484,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"dota2x6","refId":"comp_37","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":45,"ix":10},"p":{"a":0,"k":[300,520,0],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":400,"h":400,"ip":34.0000013848484,"op":80.0000032584668,"st":34.0000013848484,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"dota2x6","refId":"comp_37","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":45,"ix":10},"p":{"a":0,"k":[280,300,0],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":400,"h":400,"ip":33.0000013441176,"op":80.0000032584668,"st":33.0000013441176,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"dota2x6","refId":"comp_37","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":45,"ix":10},"p":{"a":0,"k":[480,280,0],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":400,"h":400,"ip":32.0000013033867,"op":80.0000032584668,"st":32.0000013033867,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"dota2x6","refId":"comp_37","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":45,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":400,"h":400,"ip":31.0000012626559,"op":80.0000032584668,"st":31.0000012626559,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"dota2x6","refId":"comp_37","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":45,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":0,"k":[134,134,100],"ix":6}},"ao":0,"w":400,"h":400,"ip":0,"op":80.0000032584668,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"dota1x6","refId":"comp_39","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":30,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":1.00000004073083,"op":80.0000032584668,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"dota1x6","refId":"comp_39","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":0,"op":80.0000032584668,"st":0,"bm":0}]},{"id":"comp_37","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"dota2","refId":"comp_38","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":300,"ix":10},"p":{"a":0,"k":[200,200,0],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":400,"h":400,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"dota2","refId":"comp_38","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":240,"ix":10},"p":{"a":0,"k":[200,200,0],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":400,"h":400,"ip":1.00000004073083,"op":151.000006150356,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"dota2","refId":"comp_38","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[200,200,0],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":400,"h":400,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"dota2","refId":"comp_38","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":120,"ix":10},"p":{"a":0,"k":[200,200,0],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":400,"h":400,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"dota2","refId":"comp_38","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":60,"ix":10},"p":{"a":0,"k":[200,200,0],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":400,"h":400,"ip":1.00000004073083,"op":151.000006150356,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"dota2","refId":"comp_38","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200,200,0],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":400,"h":400,"ip":0,"op":150.000006109625,"st":0,"bm":0}]},{"id":"comp_38","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Calque de forme 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":0,"s":[200,200,0],"e":[200,100,0],"to":[0,-16.6666660308838,0],"ti":[0,16.6666660308838,0]},{"t":30.0000012219251}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[98,98,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[27.556,0],[0,-27.556],[-27.556,0],[0,27.556]],"o":[[-27.556,0],[0,27.556],[27.556,0],[0,-27.556]],"v":[[0,-49.895],[-49.895,0],[0,49.895],[49.895,0]],"c":true}],"e":[{"i":[[27.556,0],[0,-27.556],[-27.556,0],[0,27.556]],"o":[[-27.556,0],[0,27.556],[27.556,0],[0,-27.556]],"v":[[0,-304.996],[-49.895,-255.102],[0,49.895],[49.895,-255.102]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":10,"s":[{"i":[[27.556,0],[0,-27.556],[-27.556,0],[0,27.556]],"o":[[-27.556,0],[0,27.556],[27.556,0],[0,-27.556]],"v":[[0,-304.996],[-49.895,-255.102],[0,49.895],[49.895,-255.102]],"c":true}],"e":[{"i":[[27.556,0],[0,-27.556],[-27.556,0],[0,27.556]],"o":[[-27.556,0],[0,27.556],[27.556,0],[0,-27.556]],"v":[[0,-49.895],[-49.895,0],[0,49.895],[49.895,0]],"c":true}]},{"t":30.0000012219251}],"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.435294121504,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[10,10],"e":[0,0]},{"t":30.0000012219251}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30.0000012219251,"st":0,"bm":0}]},{"id":"comp_39","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"dota1","refId":"comp_40","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":300,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":1.00000004073083,"op":151.000006150356,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"dota1","refId":"comp_40","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":240,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"dota1","refId":"comp_40","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":1.00000004073083,"op":151.000006150356,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"dota1","refId":"comp_40","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":120,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"dota1","refId":"comp_40","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":60,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":1.00000004073083,"op":151.000006150356,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"dota1","refId":"comp_40","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":0,"op":150.000006109625,"st":0,"bm":0}]},{"id":"comp_40","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"dota2x6","refId":"comp_37","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":30,"s":[0],"e":[20]},{"t":60.0000024438501}],"ix":10},"p":{"a":0,"k":[400,110,0],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":400,"h":400,"ip":30.0000012219251,"op":180.00000733155,"st":30.0000012219251,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Calque de forme 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":0,"s":[400,400,0],"e":[400,110,0],"to":[0,-48.3333320617676,0],"ti":[0,48.3333320617676,0]},{"t":30.0000012219251}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[98,98,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[27.556,0],[0,-27.556],[-27.556,0],[0,27.556]],"o":[[-27.556,0],[0,27.556],[27.556,0],[0,-27.556]],"v":[[0,-49.895],[-49.895,0],[0,49.895],[49.895,0]],"c":true}],"e":[{"i":[[27.556,0],[0,-27.556],[-27.556,0],[0,27.556]],"o":[[-27.556,0],[0,27.556],[27.556,0],[0,-27.556]],"v":[[0,-407.037],[-49.895,-357.143],[0,49.895],[49.895,-357.143]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":6,"s":[{"i":[[27.556,0],[0,-27.556],[-27.556,0],[0,27.556]],"o":[[-27.556,0],[0,27.556],[27.556,0],[0,-27.556]],"v":[[0,-407.037],[-49.895,-357.143],[0,49.895],[49.895,-357.143]],"c":true}],"e":[{"i":[[27.556,0],[0,-27.556],[-27.556,0],[0,27.556]],"o":[[-27.556,0],[0,27.556],[27.556,0],[0,-27.556]],"v":[[0,-49.895],[-49.895,0],[0,49.895],[49.895,0]],"c":true}]},{"t":30.0000012219251}],"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.709803938866,0.219607844949,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[10,10],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30.0000012219251,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"feudar Précomp. 5","refId":"comp_36","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,-0.498]},"n":["0p667_1_0p167_0p167","0p667_1_0p167_0p167","0p667_1_0p167_-0p498"],"t":0,"s":[52,52,100],"e":[100,100,100]},{"t":31.0000012626559}],"ix":6}},"ao":0,"w":800,"h":800,"ip":0,"op":120.0000048877,"st":0,"bm":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/1st_animation.lottie b/presentation/src/main/cpp/third_party/rlottie/example/resource/1st_animation.lottie deleted file mode 100644 index 9a491649..00000000 Binary files a/presentation/src/main/cpp/third_party/rlottie/example/resource/1st_animation.lottie and /dev/null differ diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/27746-joypixels-partying-face-emoji-animation.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/27746-joypixels-partying-face-emoji-animation.json deleted file mode 100644 index d204e53b..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/27746-joypixels-partying-face-emoji-animation.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.5.7","fr":24,"ip":0,"op":48,"w":1024,"h":1024,"nm":"party_face","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Face_CTRL","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"t":0,"s":[0,-286,0],"to":[0.092,3.435,0],"ti":[0.627,6.25,0]},{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"t":4,"s":[0.552,-265.39,0],"to":[-0.627,-6.25,0],"ti":[0.092,3.435,0]},{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":18,"s":[-3.763,-323.5,0],"to":[-0.092,-3.435,0],"ti":[-0.627,-6.25,0]},{"t":26,"s":[0,-286,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Controller","np":13,"mn":"Pseudo/DUIK controller","ix":1,"en":1,"ef":[{"ty":6,"nm":"Icon","mn":"Pseudo/DUIK controller-0001","ix":1,"v":0},{"ty":2,"nm":"Color","mn":"Pseudo/DUIK controller-0002","ix":2,"v":{"a":0,"k":[0.92549020052,0.0941176489,0.0941176489,1],"ix":2}},{"ty":3,"nm":"Position","mn":"Pseudo/DUIK controller-0003","ix":3,"v":{"a":0,"k":[0,0],"ix":3}},{"ty":0,"nm":"Size","mn":"Pseudo/DUIK controller-0004","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Orientation","mn":"Pseudo/DUIK controller-0005","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Opacity","mn":"Pseudo/DUIK controller-0006","ix":6,"v":{"a":0,"k":100,"ix":6}},{"ty":6,"nm":"","mn":"Pseudo/DUIK controller-0007","ix":7,"v":0},{"ty":6,"nm":"Anchor","mn":"Pseudo/DUIK controller-0008","ix":8,"v":0},{"ty":2,"nm":"Color","mn":"Pseudo/DUIK controller-0009","ix":9,"v":{"a":0,"k":[0,0,0,1],"ix":9}},{"ty":0,"nm":"Size","mn":"Pseudo/DUIK controller-0010","ix":10,"v":{"a":0,"k":100,"ix":10}},{"ty":6,"nm":"","mn":"Pseudo/DUIK controller-0011","ix":11,"v":0}]}],"ip":0,"op":48,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":3,"nm":"Head_CTRL","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":18,"s":[4]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":26,"s":[-1]},{"t":48,"s":[0]}],"ix":10},"p":{"a":0,"k":[517.24,850.396,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[100,100,100]},{"i":{"x":[0,0,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0]},"t":4,"s":[103,97,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":18,"s":[97,103,100]},{"i":{"x":[0,0.051,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":26,"s":[103,97,100]},{"t":48,"s":[100,100,100]}],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Controller","np":13,"mn":"Pseudo/DUIK controller","ix":1,"en":1,"ef":[{"ty":6,"nm":"Icon","mn":"Pseudo/DUIK controller-0001","ix":1,"v":0},{"ty":2,"nm":"Color","mn":"Pseudo/DUIK controller-0002","ix":2,"v":{"a":0,"k":[0.92549020052,0.0941176489,0.0941176489,1],"ix":2}},{"ty":3,"nm":"Position","mn":"Pseudo/DUIK controller-0003","ix":3,"v":{"a":0,"k":[0,0],"ix":3}},{"ty":0,"nm":"Size","mn":"Pseudo/DUIK controller-0004","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Orientation","mn":"Pseudo/DUIK controller-0005","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Opacity","mn":"Pseudo/DUIK controller-0006","ix":6,"v":{"a":0,"k":100,"ix":6}},{"ty":6,"nm":"","mn":"Pseudo/DUIK controller-0007","ix":7,"v":0},{"ty":6,"nm":"Anchor","mn":"Pseudo/DUIK controller-0008","ix":8,"v":0},{"ty":2,"nm":"Color","mn":"Pseudo/DUIK controller-0009","ix":9,"v":{"a":0,"k":[0,0,0,1],"ix":9}},{"ty":0,"nm":"Size","mn":"Pseudo/DUIK controller-0010","ix":10,"v":{"a":0,"k":100,"ix":10}},{"ty":6,"nm":"","mn":"Pseudo/DUIK controller-0011","ix":11,"v":0}]}],"ip":0,"op":49,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"HatStripe","parent":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[4.631,7.095]],"o":[[3.818,5.331],[0,0],[0,0],[0,0]],"v":[[9.463,-26.924],[16.938,-19.632],[17.467,-14.328],[6.154,-25.348]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":9,"k":{"a":0,"k":[0.176,0.91,0.302,0.533,0.267,0.9,0.292,0.524,0.359,0.89,0.282,0.514,0.474,0.863,0.251,0.484,0.588,0.835,0.22,0.455,0.715,0.792,0.171,0.406,0.842,0.749,0.122,0.357,0.921,0.714,0.082,0.32,1,0.678,0.043,0.282],"ix":9}},"s":{"a":0,"k":[10.307,-30.112],"ix":5},"e":{"a":0,"k":[20.858,-18.045],"ix":6},"t":1,"nm":"Stripegradienta","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"HatStripe","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":49,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"HatStripe1","parent":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[3.103,1.552],[5.313,8.386]],"o":[[6.646,8.84],[0,0],[-0.334,0.638],[0,0],[0,0]],"v":[[2.846,-23.771],[17.989,-9.078],[18.085,-8.12],[12.218,-9.919],[-0.462,-22.195]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":9,"k":{"a":0,"k":[0.176,0.91,0.302,0.533,0.267,0.9,0.292,0.524,0.359,0.89,0.282,0.514,0.474,0.863,0.251,0.484,0.588,0.835,0.22,0.455,0.715,0.792,0.171,0.406,0.842,0.749,0.122,0.357,0.921,0.714,0.082,0.32,1,0.678,0.043,0.282],"ix":9}},"s":{"a":0,"k":[10.307,-30.112],"ix":5},"e":{"a":0,"k":[23.622,-15.706],"ix":6},"t":1,"nm":"Stripegradientb","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"HatStripe1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":49,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"HatStripe2","parent":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[1.385,2.573]],"o":[[0,0],[0,0],[0,0]],"v":[[15.906,-29.994],[16.41,-24.931],[12.732,-28.48]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":9,"k":{"a":0,"k":[0.176,0.91,0.302,0.533,0.267,0.9,0.292,0.524,0.359,0.89,0.282,0.514,0.474,0.863,0.251,0.484,0.588,0.835,0.22,0.455,0.715,0.792,0.171,0.406,0.842,0.749,0.122,0.357,0.921,0.714,0.082,0.32,1,0.678,0.043,0.282],"ix":9}},"s":{"a":0,"k":[10.307,-30.112],"ix":5},"e":{"a":0,"k":[18.414,-21.744],"ix":6},"t":1,"nm":"Stripegradientc","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"HatStripe2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":49,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Hat","parent":21,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":2,"ix":10},"p":{"a":0,"k":[-230.213,207.025,0],"ix":2},"a":{"a":0,"k":[9.386,-12.953,0],"ix":1},"s":{"a":0,"k":[115.214,105.229,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-1.048,1.975]],"o":[[0,0],[-1.045,1.979],[0,0]],"v":[[15.906,-29.995],[18.084,-8.12],[-3.275,-20.853]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":11,"k":{"a":0,"k":[0.115,0.459,0.839,1,0.198,0.451,0.831,0.992,0.282,0.443,0.824,0.984,0.372,0.418,0.798,0.959,0.461,0.392,0.773,0.933,0.555,0.349,0.731,0.894,0.648,0.306,0.69,0.855,0.743,0.247,0.633,0.798,0.838,0.188,0.576,0.741,0.919,0.125,0.516,0.68,1,0.063,0.455,0.62],"ix":9}},"s":{"a":0,"k":[-3.016,-26.005],"ix":5},"e":{"a":0,"k":[13.937,-7.054],"ix":6},"t":1,"nm":"Hatgradient","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Hat","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":49,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Confetti11","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-74,"ix":10},"p":{"a":0,"k":[135.111,329.463,0],"ix":2},"a":{"a":0,"k":[16.786,25.814,0],"ix":1},"s":{"a":0,"k":[1381.996,1381.996,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.175,-0.325],[-0.525,0.4],[-0.469,-0.175],[-0.66,1.01],[-1.025,-0.249],[-0.1,-0.725]],"o":[[0,0],[1.298,0.359],[0.525,-0.4],[1.275,0.475],[0.85,-1.3],[1.75,0.425],[0.269,1.224]],"v":[[8.8,29.45],[12.675,25.025],[14.575,27.625],[16.675,23.625],[19.2,26.775],[22.125,23.425],[24.325,26.75]],"c":false},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":19,"s":[100]},{"t":40,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[100]},{"t":36,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Raccorder les tracés 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.650980392157,0.901960844152,0.223529426724,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"green","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Forme 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":15,"op":42,"st":15,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Confetti10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[873,522.696,0],"ix":2},"a":{"a":0,"k":[25.11,6.511,0],"ix":1},"s":{"a":0,"k":[1381.996,1381.996,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.116,1.363],[0.225,0.8],[-0.35,1.125],[-0.05,0.35],[0.3,0.675],[-0.425,0.475],[1.275,0]],"o":[[1.6,-0.7],[-0.225,-0.8],[0.35,-1.125],[0.05,-0.35],[-0.3,-0.675],[0.425,-0.475],[-1.275,0]],"v":[[24.6,13.6],[28.575,11.15],[24.25,8.375],[26.2,5.125],[21.65,4.95],[24.55,0.35],[22.6,-0.675]],"c":false},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":4,"s":[100]},{"t":25,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[100]},{"t":21,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Raccorder les tracés 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.909803981407,0.109803929048,0.152941176471,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Contour 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Forme 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Layer 10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":1,"s":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":18,"s":[100]},{"t":20,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":1,"s":[0]},{"t":19,"s":[149]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":1,"s":[194.929,367.888,0],"to":[0,46.667,0],"ti":[0,-46.667,0]},{"t":20,"s":[194.929,647.888,0]}],"ix":2},"a":{"a":0,"k":[-270.075,219.877,0],"ix":1},"s":{"a":0,"k":[1262,1262,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-3.567],[0,3.569]],"o":[[0,3.569],[0,-3.567]],"v":[[-267.399,219.876],[-272.751,219.876]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.058823529631,0.705882370472,0.831372559071,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":1,"op":20,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Layer 9","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":21,"s":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":23,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":38,"s":[100]},{"t":40,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":21,"s":[0]},{"t":39,"s":[-238]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":21,"s":[870.597,174.763,0],"to":[0,46.667,0],"ti":[0,-46.667,0]},{"t":40,"s":[870.597,454.763,0]}],"ix":2},"a":{"a":0,"k":[-216.535,204.574,0],"ix":1},"s":{"a":0,"k":[1262,1262,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-3.568],[0,3.569]],"o":[[0,3.569],[0,-3.568]],"v":[[-213.859,204.573],[-219.211,204.573]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.65098041296,0.901960790157,0.223529413342,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":21,"op":40,"st":20,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Layer 8","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":12,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":27,"s":[100]},{"t":29,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[0]},{"t":28,"s":[-49]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":10,"s":[790.435,694.021,0],"to":[0,46.667,0],"ti":[0,-46.667,0]},{"t":29,"s":[790.435,974.021,0]}],"ix":2},"a":{"a":0,"k":[-222.887,245.719,0],"ix":1},"s":{"a":0,"k":[1262,1262,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-219.674,244.714],[-221.718,249.449],[-226.101,246.73],[-224.056,241.989]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901960790157,0.207843139768,0.870588243008,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":10,"op":29,"st":9,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Layer 7","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":17,"s":[100]},{"t":19,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":18,"s":[35]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[423.853,174.764,0],"to":[0,46.667,0],"ti":[0,-46.667,0]},{"t":19,"s":[423.853,454.764,0]}],"ix":2},"a":{"a":0,"k":[-251.935,204.574,0],"ix":1},"s":{"a":0,"k":[1262,1262,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-249.335,205.209],[-252.875,208.444],[-254.535,203.943],[-250.991,200.703]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.058823529631,0.705882370472,0.831372559071,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":19,"st":-1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Layer 6","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":29,"s":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":31,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":46,"s":[100]},{"t":48,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":29,"s":[0]},{"t":47,"s":[-115]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":29,"s":[194.479,190.293,0],"to":[0,46.667,0],"ti":[0,-46.667,0]},{"t":48,"s":[194.479,470.293,0]}],"ix":2},"a":{"a":0,"k":[-270.111,205.804,0],"ix":1},"s":{"a":0,"k":[1262,1262,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-266.857,204.993],[-269.272,209.164],[-273.364,206.613],[-270.943,202.444]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.909803926945,0.109803922474,0.152941182256,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":29,"op":48,"st":28,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Layer 5","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":16,"s":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":18,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":33,"s":[100]},{"t":35,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":16,"s":[0]},{"t":34,"s":[29]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":16,"s":[781.475,542.889,0],"to":[0,46.667,0],"ti":[0,-46.667,0]},{"t":35,"s":[781.475,822.889,0]}],"ix":2},"a":{"a":0,"k":[-223.597,233.744,0],"ix":1},"s":{"a":0,"k":[1262,1262,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-221.09,235.787],[-226.105,236.067],[-223.558,231.42]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.65098041296,0.901960790157,0.223529413342,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":16,"op":35,"st":15,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Layer 4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":7,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":22,"s":[100]},{"t":24,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0]},{"t":23,"s":[-78]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":5,"s":[289.011,51.812,0],"to":[0,46.667,0],"ti":[0,-46.667,0]},{"t":24,"s":[289.011,331.812,0]}],"ix":2},"a":{"a":0,"k":[-262.62,194.831,0],"ix":1},"s":{"a":0,"k":[1262,1262,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-259.364,196.93],[-265.876,198.066],[-263.263,191.596]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.901960790157,0.207843139768,0.870588243008,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":5,"op":24,"st":4,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Mouth","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1.1,101.975,0],"ix":2},"a":{"a":0,"k":[-244.448,237.823,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[1262,1262,100]},{"i":{"x":[0,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":4,"s":[1299.86,1262,100]},{"i":{"x":[0,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":18,"s":[1173.66,1262,100]},{"i":{"x":[0,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":30,"s":[1375.58,1262,100]},{"t":41,"s":[1262,1262,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.296,0.419],[1.111,0.249],[-1.006,1.535],[-1.835,3.294],[0.211,-1.095],[-0.41,-1.177],[-1.08,-0.51],[-1.838,-3.404],[1.972,0.537]],"o":[[0.925,-1.314],[-0.841,-0.189],[1.132,-1.727],[0.507,3.837],[-0.222,1.148],[0.296,0.85],[1.012,0.479],[-3.419,-1.598],[-2.499,-0.679]],"v":[[-250.347,241.811],[-251.329,238.417],[-251.856,235.16],[-245.719,230.892],[-249.789,236.446],[-248.06,239.115],[-247.821,242.498],[-241.295,244.546],[-248.775,244.67]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.086274512112,0.149019613862,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":49,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Wistle 2","parent":18,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":0.97},"o":{"x":0.167,"y":0.167},"t":19,"s":[-269.13,249.354,0],"to":[-2.391,0.777,0],"ti":[0,0,0]},{"i":{"x":0,"y":0.97},"o":{"x":0.333,"y":0},"t":30,"s":[-283.475,254.013,0],"to":[0,0,0],"ti":[-2.391,0.777,0]},{"t":41,"s":[-269.13,249.354,0]}],"ix":2},"a":{"a":0,"k":[-269.13,249.354,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.085,0.085,0.582],"y":[0.783,0.783,0.263]},"o":{"x":[0.24,0.24,0.18],"y":[0.147,0.147,0.294]},"t":19,"s":[100,100,100]},{"i":{"x":[0.727,0.727,0.667],"y":[1.024,1.024,1.031]},"o":{"x":[0.261,0.261,0.347],"y":[0.023,0.023,0.153]},"t":23,"s":[40.348,40.348,100]},{"i":{"x":[0.727,0.727,0.667],"y":[1,1,1]},"o":{"x":[0.223,0.223,0.333],"y":[5.639,5.639,-0.218]},"t":24,"s":[0,0,100]},{"i":{"x":[0,0,0.667],"y":[1,1,1]},"o":{"x":[0.223,0.223,0.333],"y":[0,0,0]},"t":31,"s":[0,0,100]},{"i":{"x":[0.017,0.017,0.667],"y":[0.994,0.994,1]},"o":{"x":[0.401,0.401,0.333],"y":[0,0,0]},"t":32,"s":[36,36,100]},{"t":41,"s":[100,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.349,0.972],[-1.201,-1.202]],"o":[[-1.227,-0.883],[0.93,0.929]],"v":[[-270.784,247.568],[-268.41,245.193]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.160784319043,0.443137258291,0.141176477075,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.157,1.555],[-1.921,-1.922]],"o":[[-1.961,-1.409],[1.489,1.489]],"v":[[-271.896,248.061],[-268.099,244.26]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.321568638086,0.57647061348,0.1254902035,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.901,2.09],[-2.585,-2.583]],"o":[[-2.641,-1.899],[2.003,2.003]],"v":[[-273.022,248.652],[-267.914,243.537]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.478431373835,0.709803938866,0.113725490868,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.166,2.21],[2.033,2.806],[-1.296,-3.921],[-4.548,2.075],[-0.061,0.344]],"o":[[0,0],[-1.537,-2.119],[0.744,2.244],[-0.055,-0.962],[0.194,-1.095]],"v":[[-267.526,244.127],[-271.283,238.679],[-276.315,243.625],[-268.976,249.505],[-269.135,245.865]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.65098041296,0.901960790157,0.223529413342,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":49,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Wistle","parent":16,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":5,"s":[2]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":18,"s":[4]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":30,"s":[-16]},{"t":41,"s":[0]}],"ix":10},"p":{"a":0,"k":[-249.704,239.133,0],"ix":2},"a":{"a":0,"k":[-249.704,239.133,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"t":19,"s":[{"i":[[-0.27,0.114],[0.522,-0.162],[0,0],[0,0]],"o":[[0.486,-0.201],[-0.349,0.109],[0,0],[-0.001,0.002]],"v":[[-265.416,247.908],[-266.411,243.219],[-269.252,244.125],[-269.065,249.449]],"c":true}]},{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":30,"s":[{"i":[[-0.27,0.114],[0.522,-0.162],[0,0],[0,0]],"o":[[0.486,-0.201],[-0.349,0.109],[0,0],[-0.001,0.002]],"v":[[-265.416,247.908],[-266.411,243.219],[-284.873,249.317],[-284.686,254.641]],"c":true}]},{"t":41,"s":[{"i":[[-0.27,0.114],[0.522,-0.162],[0,0],[0,0]],"o":[[0.486,-0.201],[-0.349,0.109],[0,0],[-0.001,0.002]],"v":[[-265.416,247.908],[-266.411,243.219],[-269.252,244.125],[-269.065,249.449]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.478431373835,0.709803938866,0.113725490868,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.441,0.168],[0,0],[0.451,-0.16]],"o":[[0.445,-0.171],[0,0],[-0.462,0.162],[0,0]],"v":[[-261.763,246.347],[-259.498,245.484],[-263.556,242.416],[-265.742,243.183]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.058823529631,0.705882370472,0.831372559071,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":50,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.717,0.273],[0,0],[0.794,-0.273]],"o":[[0.799,-0.307],[0,0],[-0.764,0.265],[0,0]],"v":[[-256.817,244.455],[-254.535,243.584],[-258.435,240.64],[-260.781,241.459]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.058823529631,0.705882370472,0.831372559071,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":50,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.271,-0.967],[-0.407,0.148],[1.258,0.945],[0.803,-0.283]],"o":[[0.988,-0.374],[-1.257,-0.951],[-0.66,0.232],[1.279,0.953]],"v":[[-251.812,242.543],[-249.663,241.733],[-253.431,238.887],[-255.637,239.659]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.058823529631,0.705882370472,0.831372559071,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":50,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.988,0.359],[0.92,-0.309],[6.715,-2.361]],"o":[[6.81,-2.612],[0.59,-0.214],[-1.177,0.393],[0,0]],"v":[[-266.05,248.005],[-249.399,241.634],[-250.421,237.841],[-267.078,243.648]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.839215695858,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":49,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"Blush","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":21,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":27,"s":[97]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":34,"s":[100]},{"t":46,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-1.651,60.272,0],"ix":2},"a":{"a":0,"k":[-244.666,234.519,0],"ix":1},"s":{"a":0,"k":[1262,1262,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.559,0],[0,-5.557],[5.557,0],[0,5.561]],"o":[[5.557,0],[0,5.561],[-5.559,0],[0,-5.557]],"v":[[-229.286,224.454],[-219.221,234.519],[-229.286,244.583],[-239.35,234.519]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0.1,1,0.388,0.6,0.73,1,0.649,0.351,1,1,0.91,0.102,0.1,1,0.73,0.5,1,0],"ix":9}},"s":{"a":0,"k":[-230,234],"ix":5},"e":{"a":0,"k":[-219.936,234],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"B1G","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":60,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.559,0],[0,-5.557],[5.557,0],[0,5.561]],"o":[[5.557,0],[0,5.561],[-5.559,0],[0,-5.557]],"v":[[-260.046,224.454],[-249.983,234.519],[-260.046,244.583],[-270.111,234.519]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0.1,1,0.388,0.6,0.73,1,0.649,0.351,1,1,0.91,0.102,0.1,1,0.73,0.5,1,0],"ix":9}},"s":{"a":0,"k":[-261,234],"ix":5},"e":{"a":0,"k":[-250.936,234],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"B2G","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":60,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":49,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Eyes","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,-52.396,0],"ix":2},"a":{"a":0,"k":[-244.535,225.591,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[1262,1262,100]},{"i":{"x":[0,0,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":5,"s":[1262,1009.6,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":18,"s":[1262,1388.2,100]},{"i":{"x":[0,0,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":26,"s":[1262,1009.6,100]},{"t":44,"s":[1262,1262,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.605,0.779],[3.988,-5.154],[-0.258,0.756],[-3.385,-9.963]],"o":[[-3.989,-5.154],[-0.605,0.779],[3.385,-9.963],[0.258,0.756]],"v":[[-248.954,223.965],[-259.716,223.965],[-261.3,223.408],[-247.37,223.408]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.086274512112,0.149019613862,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.605,0.779],[3.989,-5.154],[-0.258,0.756],[-3.387,-9.963]],"o":[[-3.989,-5.154],[-0.605,0.779],[3.385,-9.963],[0.256,0.756]],"v":[[-229.355,223.965],[-240.117,223.965],[-241.7,223.408],[-227.769,223.408]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.086274512112,0.149019613862,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":49,"st":0,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"Face","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,-338.396,0],"ix":2},"a":{"a":0,"k":[-244.535,225.591,0],"ix":1},"s":{"a":0,"k":[1262,1262,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[15.464,0],[0,-15.467],[-15.464,0],[-0.001,15.459]],"o":[[-15.464,0],[0,15.459],[15.464,0],[0.001,-15.467]],"v":[[-244.535,197.592],[-272.535,225.592],[-244.535,253.59],[-216.535,225.592]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,1,0.584,0,0.4,1,0.747,0.051,1,1,0.91,0.102],"ix":9}},"s":{"a":0,"k":[-231.07,253],"ix":5},"e":{"a":0,"k":[-231.07,198.011],"ix":6},"t":1,"nm":"party_face_grad","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":49,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"party_face","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[512,512,0],"ix":2},"a":{"a":0,"k":[512,512,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1024,"h":1024,"ip":0,"op":48,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/29056-nepenthe-illustration.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/29056-nepenthe-illustration.json deleted file mode 100644 index aa567847..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/29056-nepenthe-illustration.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.6.2","fr":25,"ip":0,"op":100,"w":1432,"h":1016,"nm":"render me","ddd":0,"assets":[{"id":"image_0","w":844,"h":223,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA0wAAADfBAMAAAA3qU70AAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAYUExURUdwTA8RJg8RJg8RJg4RJg8RJg4RJg8RJuvyX9EAAAAHdFJOUwDoyaNRdybLpWG9AAAH4ElEQVR42u2dSXPbRhBGCWLxVYtlXGV5wZWyneBKKY5wpeXEvJKKFV4FLZ6/HwLcQBcxAGlQ6K68V+VSqWjw0J9m+uueBZ0OPCvBLTFQQDfsEQT5OOYVQdAg0wNBUDDpmXREFBTIZEhO8nGNeUkUFMgU3hMFDTKZAWGQL9NrLLkGmU7wehpkOojMW+IgXqYfY5PiycXL9OiF5r5PJISXt4+dG0PHSLxMT53OOTWuBpm8yKRMe7JlyuY7N6R4UiBT54LsJJr5epMX/lqN6zFnPodMnfjXOnvdY0L5HDIltZed/t5cfjGcnkOmSW2ZzjZOeliQZ5HJqS3T4cYkhqN/FpnGdWUKDjfqEZnjuXzBiKjucdKrORq8zf8xMSb97Sr4/uHQmKPfieu+LERdQ+5vtoSOKUDHvXmZnvKfw7o7IkpkcosymXsmvv3IFD/VfMDdLJO3JpM5ILJ7kSmsa6i7JXVwaMLicCKyDcv0mNuz2jv+nRKZYvNuplOa/8Ce70Mmv3ZLb1IiU2Ieg69nZx+vsj6uMaeEtlmZfuRT2UndB4YlMjkmLRRRs2+FpujOAjqu/ddf1qPtmtUHU3f+RGiblSk3ZV9q55KopF3hF+ydz+aKhnFnwf1e+4GwRKagKE2ITHuRqTZe6UGbsJCcYmRqFn9LmdxSExcXBEyQqUn+HXlbytQtlSkpJKe5zYdGuAzTT+F2FY5TKpNTSE4Ohrw5xnnPYDuZXpTKNJ0O05/8IzTiHnK2kykpfWBq9ZaVk0sXoimCaBeZhuUPhKvk5HLuuilu5s3s7QIal8s0/ehx6R/7BLjRwbSlTFG5TJPV+oXPAcSG6O62IB6W65p941wdn/WmhhjOZXoaNSWTv0p0Hp3XZvDC3ZbDbbPk6tt8jks1O+dtmes9m0zRssD18OPNkCxS03aP+YXiaNN3Lr4OB9EMC593t31JXCqTwx6IhvEXc95ge5n6tg+Z7faRmu53eK5UpmD70QlWJjtue3RWtdHmmRQnvoeqKe00KlOywzdCtYPYOpO8mD5kFxEP0bhM26+E22VyDVeSNkpsdttBPLFOawGb/PdQ3Z7u9FxqH6RsgmiQbHrape82tMuUcBajWc4P3+04Wd7bjSBWr1FGnT3I5G/f14D9OESrPQxpFwmR6anic6xe+4QVMk2wekJkssrQ5ciMBEzFOUAPqydEpruq5EWU2qZ6RSmh+do+XmXTrosjbx+/UqYgrBhusH9q7HaIkUmDTBwUbJ9u1bqf9/ErPXIRMg1sKuWrwsSpZao2O5wbrpUSItPInrpYZ28f+46V+Q4LPIQAmVJ78YtMArBvLFpcy8udEC1j35IS73bKA5omti0nLW/lPSVQ7WJdY+/ueBgHmia0JZ7lAcQRgWpdprvK1MQqe9tYa9fF2XheEdQyns0fLM+J9ghUu1g3tbqkJiG4tpaeQ2oSQtfWhJiQmoTg2JoQCVWTAIJRPmAeqvw4c16L3L4+PPqWDZgfVTK9J1itcZ3XRO9iW9k0u8OAF3a2qNLq/Vm9Cpm4vqM1bgqvOetXOD1q29aK2sLb6FKrW8dAtGjxosJgerC3KFLceFuMi2/gtG1z+GLMW8LVEl5Y90WpwcdPhKstvvA+W3WDiW0OQrlYfzs0FkEm64OJ7eEy6a6rZNtADu2RrKvEZQIq5jw6diLxf5rzWJlVkZoweiIZr6vEqVoVDoI5TybDdZ+HHdcgE4NJw6R3z2ASyqQoU494CMUpqHRCOBSUtw9MeXJZNovu+wRDfn2LSqKZbys6ZsaTjXcepkffiIP8AUUIABhi/3suB8RAARcviYECHBY1NNClEasBnysoVTi9kH0RGojYZaSBIUvuGhhzzFaH1eN0hgqrx5E0DVaPW+GVWD0suQJikpMGJiQnJVaPd2GosHokJwVwEleJ1aOtp4CEq3E04FDgasDlkkMNBHgILR6iTxQ0eIgeUdDgIbB68vE5266CEEeugRhHriM50XxVUeBSOGkocEMuFVWg0jmFkwKyu6/vCIP0sim72oN1dvl2nNGkYDAZZFKSmdgDJp6IW/7VzHmUt8Lpcsu/BhIchBo7ThNCOrNrK4mDbAJexkBxCw3hUtzq8ePEQYNMVE0qZDogDhpyE2GQjmc4NqOjvE0HREE8F4bbXhUQ/EUMhHPdJwYaXB5ZSQExHVcVgwknrmEwsYdSAT5NIg0MuQNHx2Di9RjyuWBzngK8kB0QOgYTb8fQMJjSCJkUDKZHRpOGzNQLsRDCGWc2j+PrwgnCbGWdNzcJx8l3E0XsopRNlG90HdIhF013dlSGm4pkE89kcrk7VDLZDsqHaW6aGgmSk1yGWWYKH1gXlF3a5gfXh2n2SiD2+Mvh++fPV1drpa15NfUPg+k/LqUUQ34eMH3zbfF7dti2P3V7p8gkibGZ8Wa0NBBP2Y+DTsKkJ8sxzM5BDxa/9jKZXk3HFRZCVMthrlN/1s7LqlrHHLicuRWEWXEy60Ac5OL1YpNS3gohmF+jMrtAqp/NedmGItekt2EmGwghKQynLB/l55mG5uSCwSSJfwoyPfm5G+/4YTqIZpYChEx7UUGny9ntAuPpkPqTsSR21ovzHclBdDwiLsK4NUWypUD3iJEke9bLbYNHVhLITdFEEA6xw+nDSqYe4RCLd73sFxEMyVwymFTwxznXjavg8/XZ6/eEQT6UtFr5D6mcUCRF5QD7AAAAAElFTkSuQmCC","e":1},{"id":"image_1","w":36,"h":13,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAANCAMAAAD2fTxUAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAA5UExURUdwTA4RJhIRJA8RJg8RJQ8RJg8RJQ4QJg8RJg8RJg4RJQ4RJgwSKQ8QJg8QJg8RJQ4PJg4QJQ8RJpKCIt8AAAASdFJOUwDBFG6w44P58dZcPQmXzE0wJAZ+YQ8AAAC4SURBVBjTfZFZkkQhCARRQBB37n/Y0X7Ra3RP/qkZpYUAL0wkIpuzYClzRfgkjkYq7nLDLzSn+jRS170n2olaQkMzXJiPq+kKrOksNTer7+nViN15nIf0rTAV+MYk9Rxh5a2kCL9IIgjJhX4rAEUlQXOxfxzLzgWGutL4bkQM+zSdS/VUIyzxtVytywKfSnglBr1NTjn3cCBmljNZF27r8bjW+T7lB7LjR/34FmwUej70bGWs+Oz8B+VrCdHHB0D2AAAAAElFTkSuQmCC","e":1},{"id":"image_2","w":38,"h":15,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAPCAMAAAC/QE1iAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAADYUExURUdwTOvVyTcwRmY/Xu3UxuvTx0MvSsWtrenWz+3MwdJgdxASJ1Q4WlQ5W+3ZyBgaLe7MwlQ4W+zUyLRYc+3Qxfdtg0k2UlM4WvOXnkMtTO/FvexpfxUWKu7Vx1M6WppOa1I6W8FZcVU6Wu7LwO/KwPGtrbBXcrVYc/SUnfSDkFQ5WvKdo/GYofZsg+7Wx/San7GdnfOMlzImQIVmes5heS0rPPZthPV6jPKTnCIiNPC2s+7Vx/Ztgw8RJlQ5W+3Vx/V6jPSHlEctQZJNYBoYLt9keuJ1iPCurdtUA0wAAAA8dFJOUwAOB0BXGREBBin4+MahH+Gg/TlshZ+A3/4b8v7xbXKFK/Vg1LSTxZ/i7lWub7+/bw3dkxlU9t/tUK3j6zDmLiEAAADySURBVCjPfZFpc4IwEIYJEDZJORW5var2vu8jjQLa/v9/1OgoU4bC8/V9Zmd3X0WpExuGCiooXQBBgZM5TpYdbcmcd9IQcE9fXN6/pmVZrL8OPD8YfyREdfdsxStSxjZ8My2LYm1q6sGyh7Oc/0s6ZsKayFUBAPvLmyveRj80Y1AIEJ33rlstPjgWI1VOsynvQmqWXA+oPuiwXrTQ07YH4OFth9YPRbC7lVD3vM05ZUJYxv611I9W9fxJuxifTJlnBpO4ejDBupv8RFGeV/a38ExrpBlQ70pW5c8/l5Ik+ZjN3+jjHexo9k4QwtS2EVEa4S9p/0iWl45G+wAAAABJRU5ErkJggg==","e":1},{"id":"image_3","w":32,"h":14,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAOCAMAAAB5Au6AAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAA8UExURUdwTA4QJg4RJRATJhUYJA4QJg0QJw4QJg4QJg8RJg4RJQ8QJg4QJg4QJQ4RJg8QJg8PJQ4QJQ8QJw4QJYXtO7MAAAAUdFJOUwDq1iYExQ7++/WisG5af98XRzGWxB0/VwAAALpJREFUGNN1UQkOhDAIpAcUeqL+/69L1V3NRidNSBiOYQpwIcZIFCM8IdTinXCa4OF8aXovXIpLLDvPM/KMIzc6aMoy89bW2xqUSMPSPVuLz2FOR5FR6kqnjEMO1YyOk1+BMPkWbzqv3dpHylDFB3hDF4SNt1eeUDaobHueoSheIaK4/ETP23G/ooiVBAXV7+S1bWabuHKqq2hGyMCJYX7uEIf1Gmcdp887xA3My/9vtNrt5dL7Eoh++Q+sPAedm4QFhAAAAABJRU5ErkJggg==","e":1},{"id":"image_4","w":31,"h":13,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB8AAAANCAMAAABmbkWbAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAABUUExURUdwTPdtgvRsg5BKZfdtg/dtg2U+YIhQcd5kffVtg/Ztg/dtg/Zsg/lug+9rgvpuhvZsg/dug/Ztg1M4XPdtg1M5Wp1QbalSb81gebFXcYJIZfZtg1kboDwAAAAbdFJOUwBOehL83SAGI/KPsdEtQwtrpF5Vve6PPupvcpay1VYAAACJSURBVBjTfZBJEsMgDAQFCElgDMZLNv3/n3HFFZcTL62buuYwA7CBSyncmt608A+zo2zr6AOiKoZUe1mdEyGbUJf7gsl8NN3HoEdg6GbtxOsZXoDpXKsacPVC+wz0Os83c0+anlcaeJgexzouAzANt30/bEzZrGdTwLW1b2x2u4UldzFGa+Tn+wa3eBn5y3jsiQAAAABJRU5ErkJggg==","e":1},{"id":"image_5","w":61,"h":126,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD0AAAB+BAMAAABlgAQYAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAtUExURUdwTA8RJg8RJg8RJg8RJg8RJg8RJg8RJg8RJQ8RJg8RJhAQJQ8QJg8RJg8RJmhr0ooAAAAOdFJOUwD469vJYh2nM3qSDLlJeVnYAAAAA8VJREFUSMeFl8trE1EUhydNZ9K8xBaVijjUhbooDK0bQWSIrixKaDeCRUJbN2IxdCkuQtKNK0sUcRkCIlXQUK0KdiGl1o1KsKsKQjGTPkxtz9/gZDpzH2eON1ndmW/uzHn+7ommsV9RU/8+dODxDlzv8AHjaocXjHTgYxNqXsqo+eK+mqcaC+oAwIyS95h/1B+wd9S81qDuJn8Gq1mgIpC8zxwAKgLGeZYhc4DiJnurTUXIgNFgWdkkeTVYvuWPCmHhYYvBUJinudU95lGK801ZwgAdDvMSafwg9v9l6yiRwjRss3UCzhD286gY1i4Rvy1+UW+G82O2+MVaIxwhS+BRIoXiN+PQH+ZCWRlWuMbsPeGi7qj5WjiFUtC7wwZKPA4nMJdikhS9pWJWcCaUvBQyoCDxbsBFXHDkcsEprDli3yftTSV3u7SI21bis7jGKg3JoxQMKrlutpRcwwbmkEE11ASYTyEDMccGYp5GBuYABcRuqnlFNjCHZW0KliWOewoZuIFLGkVwLiSrcgTzoIUqpiglFJ8LJS55XsW59iflGhySrvDJmICTEseiJXdxN9GSYkhiUMZcinBcstYX6hmxI0I8JTqgh0VTFx0geFJ0gDo3xZ6muOhAguBTgs2xsP1SBoj4SToahfChIQp9F3XsCqJH8hqXsQhQwwpPGsmjvAc+UWNBjPdAnuJpk2VozlEPIxtNivMM5fYozlWhRo41k8xBm9zfxRwEcn8MgmEFdjWlg9AipymWQXOb5CyDwvwgOehnsAcGSB7xj3KdGmo8B6t+qQUH1sMFuccyqLzHUY8N+s8F5f1K1iE/AFFW3quyzti7fnkF5f1Z5oU934/gxiWZ+7oacf7D3xzo2iTjw0VUwp5hJdYp9ijKsOf4GCsPq4wC4AW2wsrDknUgeZC4SosNWigRWS/xFTae4fE35wWots8G2d8yn/PeXOhngyDiec+y7DE2SG4hkfI8swaZ5qCDu8uRrE6Ag/+QeONlhsULNbreHjzSrHxSgIWk1818vFFmOoiEbsl0E5JgZ10UZCFdstvP32pyHTXF0euODWel9Lj7hQQ8sOBIu4EKxwXOE3DTgr62YUb2NAvHTj3oROOZCb3fvFWdCXVkKOfz9ysAvVf8JDuBf5FM/oCvD0MjwNpjaPplF1mOtLnxxAKAeyyINjhfpqfd1aGZqGufvmICNF/wVltyH+8b+eXqcPXdhfnL7l7YuS7Gad3dAI2LLx+VF9sQ+l6jeeHjKe/2uao2vnrt69OwVCzcvjH//fld4u/nP8Ofk6OBRJ9aAAAAAElFTkSuQmCC","e":1},{"id":"image_6","w":57,"h":128,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAACABAMAAABD89wLAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAkUExURUdwTFQ5W1Q5W1Q5W1Q5W1M5W1Q5W1M5W1M5W1Q5W1Q4W1Q5W/5++OAAAAALdFJOUwDz4cqsE1Mlco03ILuDPQAAAkdJREFUSMd9lytPA0EUhZfCUqCG4EgNISSQYGoIoqaQYMA0QWKWQAIJZh2iBoMBAwKFWSxrOn3wun8OWrbzPHNWtftlds59zJmZJEnS29tuEn3eROQ+Snf/qBxH4PwEioqM7k2pDDC9+adSQNquaAfSZkU/Ia0gnjidUeE0A7Su6SqlffrlEdMsilLpkmyI3MUKOH02AD2hoh81HZIK4lzWhOVyyVBQ4hWhooWKNvSHJkuRtsO5fKUTl4Z+hPRM2MQNYbm0aUZpi9JQ9JywbNl0RKmw8ovk2DhiDeCM7VM6pnTUZfPKkUcXHDqKtyyIKXVpJ9qUwD68sWNKv2OugzzPGyvRZTZ9nhy67NENkklfdE2Y6IYw0T51M136dA8b1sy3cmh2aL2E9AM7A7DEkCpKhdOC0halqywiezUB+gW9DpTpRlhIDUAzSu+QTwJaAvpEVY3jveGscUQVy4YVMKQZybNVQ0j7pL4W3UX0O9zpUEiQCqcZm1f7A6Z9FpFeaZgOKRVOM0pbTHO1lhYxrDbMWoR+RZvdVKkXoYNoO5uAddM10XrQbdVGIemXfud+Osl4RbL0dI9Ilv4TiO/YtETtof/0QLbqcarsEpWgAcw+dw68xXz5ElCz618F8xbWLli0Q83mhFR4qVQvtuPkruitB6dfc+egte71a7cW2pmh9iY+yH23skJXs7V9apVzVmplLPbZ5Bxd0S50o1TR7bsHrGalcnLSWtv0r5VLE+Hbfz8O1U4S3nTSAxlOZKbv8DZbv75Cr38Byi0OavxExwwAAAAASUVORK5CYII=","e":1},{"id":"image_7","w":70,"h":134,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEYAAACGBAMAAACS6OEDAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAwUExURUdwTA8RJg4RJg8RJg0RJg8RJg8RJg4RJg8QJg4RJQ8QJg8RJg8RJg8RJg4PJQ8RJiCZW5cAAAAPdFJOUwDw+eMOt8gyith1oUdfH8UAvmwAAAQ3SURBVFjDjVhNaBNBFE6btI1Jmoq29iC6WpUqWjcWj0JiLV5bPSgepAVvKqQVBRGkBcGDHqIHQS+mJ+vJ9KKIHlKKoB4k1ZsgpPUoCN2NTfPT+NzdZHdn3rzpuJcmm2935nvve99700AAXysB5RW7qMasPlJjslNKSJehfk3bphpT3KfGaLNKSDeow9P2H1ueWVdj0g3/czxFY/Re/3PHIp0smPS/FBZITBDmvM+j6UkSkzd86iGgwwllJnOwnYKEoMKGM0FGWd/rf4kCuZ8O9vY2WKBpMRltAzK9RYMRYTssU5gJhlagB6g4hzSGVmDMpJQdgX5WAiYlpU5g66ZgUHk/zTEpknLLmOwucyVSYFXuiSoBiWt1TgNVktYxabB8Wlyi0+skLS6JWQqTM7kEJesULZ5sskZli395tkGV+hD/ngolwl4lJoj0S2FuMPXnYA5vXX8OpkFkC8WeWCsMFRUm1M4JlX7PCCCD10XMT1RycagrhEpjski+BAYJ1caURepD2IuqCqHanlYShTqObVh4Tw5l1Oouwn4mjBUlJinewWvFxMin8Z6jMCisXlJSD2UwZlU02mJJoC6YaMEQqKfEGlBSt5ZPqagHziB/DovUrX4xt4XruvfGt7KnVv3zzxVNsX9EUR/ME54eQf00W6b8aI0XPOEjXfrfLZyZfDBKtmDN4C1snMAkTZbItCB4R4jANsKcQbXFPPfkBNmqilzwydYQmGGNNq7VKMwIy7Yb25zL9qAqPFbiN+VK8aJfYdVDhcdyKYbKkkkPlxpT8ZmSZFhkVDUhGS6LjNVSXag5Ac35exukMQzfMJykMVG/MoL0AGcHqNdfdkEy/+uehAvmsmRSTm7ILdUlk92gwol6kddDdOl8Pu3aSwxqMozHOCoLoa2gcdeLEjJMxP2pjVaYEyDteGvmpBXWLJiaW0byE1e+7PqT/EjyrST3J0/prdlXq8kxnc3BIKT/kWPCTQV18bZHko/QRw2OPLbqSEokj48RnRxmyWymgm8vX1fE5tOO2lR+Rcx8D2p3ySkx82MmqoVFfnqxfWrMQJLhi0Szp8SZMqpNfixz7LRYQx2SV1zGXiazgToiX/wFW10ZPqVLsIEM2FJppowGhgZaO2FL9RQXQrOM1LFmS77Ess0afGvtsk06psNuzkuRizgngbMaXGemuaMoQHknD5/BmPVfvUefRN3Hycl5qC57qXiuJaigRpJwaNHVwkK6Hx3Xm6PALR36FlvFkspxyfn9Rm8F9bsOu5Zbg9EIMwDfubQDvC52D+DAZSddqaAbxPinKzrAkVeeliwQ9M1bO0xFHUGF7r5+bCHWP7ILv9AAzKsdpUDs2ZeXDy+csACw/ymylF/D1l2jbHXgARPs68C1efGfEuesH+rWOcz6M7DzybsPpGffHx6w3P/2+7cPftyUlnd8lDoj/wPckt+R6cu6CwAAAABJRU5ErkJggg==","e":1},{"id":"image_8","w":65,"h":135,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAACHBAMAAAC7aCnfAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAeUExURUdwTFQ5W1Q5W1Q5W1Q5W1Q5W1Q5W1Q6WlQ5W1Q5Wy9xE3kAAAAJdFJOUwDt1LJOjDEWbrBIp70AAAJSSURBVFjDpdi/b9pAFAdwDmOMNxSWeOsYb0idsqFmaL1lqSo2d2RDilSJrVOkbIZA0vffNohg7v2495WSG9FH5t6Pez4YDPT6sx7466G6+tp64I7e1tYho+oo6JAW3+i07pOPeAf0LyXCWdAiIZa9SO2kB7S1szK5CGrBNojmpmgiMTVFHYkObJTo1c3Xcb1YYghFCcUyFntLVOgZRQzMfORMzEHO6dmq3CYW9zAUWBWCVdmi9qGdJTIWCmow+zRsYFWWsLIs2A4Fa4oCihyKIRQlFCwdZj4aQllnCTMrx4BVfR6s1UGlELqRV0K0YKNEf/0TaR2oQgB9KCdSdH7dLFFCsYLiFgr6vMigaKCokRgTEhkUAYoGihqKComRBuIVZYQihlCAYmMIPgyfDHHw20cJI1gxHgzAx8OY0DNyS+xRwnjWAxQlFBsoGjOWhTN+Tuva7zBxe6xMEc+phOj8svA+TIiDXzg22vOEIL8sTJQfFwu3LCxldUp8Aem4DP8iKTqUjl4EKJLB9qVLixeUjv5QJdPRlz8Jzkd3BEWWFjsUyrnJHEHOoWXiyRFrkI7zXdkB74XxxA4K8g7cpZdzV3TWvUPVPxDaqrh31HqrYsqt9J1L3BeDPnZc7DMdDO/jLtftzttjOtaNGMRZrlSb5WJjtW6RmotbHW7ORWPULmMiWHMoi3c6NGfZ70hMzFa9fPlUXcpb8eKfyt6/lq8YWahZK99k8/iEzb6v9XVq0bfUbG3+InzuY7+x/xvZHkMr3h529cv+3+LH42ko/XyMP/0Pz+kZh99xrMcAAAAASUVORK5CYII=","e":1},{"id":"image_9","w":442,"h":636,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAboAAAJ8BAMAAAB6gHmCAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAqUExURUdwTA8RJg4QJg8RJg8RJg8QJg8RJg8RJg8RJg8RJg8RJg8RJg4RJg8RJoLgUvsAAAANdFJOUwD37N3LFLYqcYqhQVkYVYunAAAgAElEQVR42txd/28UxxU/3+3eru8uEj4IpHVWso1DUtqVOBvckLBSKCShhJPOpkAUQMIN0JLqJPMlhZRasoFQAj3JJJSmCZZwgCCknmQnrWjSWrJJSqCRJXbvANsw/0tnd/bb3c7uTszu3Nn7C/h8t743897n83lvZt5GIqFdqaudm8/lIgvz+uoXAAChqf3AzYVnW+qKAOSuq63QQrn9wHcLy7jbGQCUTbnIrovwP9DArk8Xjm1JOHGg/S/ohzffRhO4UOx7cz205pd95s/c2Q5t/t5fCMZ9LQKw+K8VL3H/Ux00vWn+I+i3EE5Wjla/yp1W/dPw1nl7nYLGbXINRmV+Tx80Trnu8rv3YDyCFRPz2i1L7t7HXVCn7+/z1bh/QOMGPAUMRBd5bd+8NO73IigNEVDhkoF5aFyj6OWWpoyBhFFCockev3Pm4zPfH902H6SlBJRrJGQP5bW8JRI5trejSVZpvqmt87VLde6tbC+Qf0f2Tggu8hunRGC/2jb/qZ6tOwnAOmI5kwEytDC9vHNDZ2dbqwCQ1P5v/SKKAH7yA7z410DZfO5dNJU7/vPB3g7VQnlFnfonL4KlP+Srcasr8Yf9l5YLKnUp1bheH6IjyZsuwkhMD9Vl0Mn7AsgLP4NkUX9K7S2BHFG8bySCH9ddLi6BpQFpf6gIXq8z6z588qAzryOgNFpXxm0Xggg64xoBP6szv3whSLUqKPUELCdAOVASHgQ/rx/jEoISLEfxQqluyhNsPiAysK7z4JV6se5IYGRgeQOYrRtIUYJPtLNynSTvJ+Q3gr/pVvDTOkkNVoaR5Yvl+pi6cETveXC5Hqau7Voo942DZ+vAum9eDCldlOqA8hIh4KWhV/bUng1C46U4eKbW1g2CfWHdmpWUvhr7pfAgvJtP1to1R+QQYTtRY9eMh1oBYWuMmvkwp051zVoSeiLk4lW8plpzJOSx5cQHtTOOF8L+48PyRM2suxV6/hyrXYbOiaFDGi/UjBOYJ4951m94sqXa0cET6+fkqC8nDNUKU55cP6f8QCMOWmpj3RcBRHzSb/aTQo1KY1ll9Mmtu+7v/jXSKQHAWfJlv3eM1YYTbgWRnvDN/sA8XRPHDILsGh/74o5Qzs1Tx4wk/DGjJjXpQ4Hkzcxi37cM1iLwsoHUPA41EUhN+mVNXvhRIOmp6BtUjYB+FrQ1GH8ZFn0zHApa3XEVA6By9Tai/yDlAW1YCUogZTOL/L2Xet2PAWsCuY+UuUcAK89Rti6gxIQVN/orkUbwmLJ12WBWDjnhnRLBmyiDJi8Ew0EpcAkQZMkl2mEXjH5oBO8L/nA/RrkwNigHwgcw856Q/AM4RrkinQ0oEhh5NN9CMMOraBqXAs1z+VjS4WBRJVfwp4SI0Ew37ObEr3HHp7pLkd0EcC/N0LRufG5hF3M42Hg50kAAiMPleRB20ecdMnMWAgvBaCoUdTQnzK0G3e3QJdmZCEegeqI0KWGOYRcZd4SPCIOOABAZmgXp7jmyXaHaoVlhGYSMpwkogWLxoTjHIM+XHcwCyW7KHxBTQgs968Q5ikypjJuTfhto5txSCXqEl5qjdGCFkkOIXVYhw/Tzt35be8JjgD+C9WFHpeQQkEPqy0ZhoXF1rwt65OnlQA2K/zThKiEJubp42QDgtLEGZHAd1+MuFeACvRxoiqCkghP1MWV51Sv9GpNnH+pgtS7CZvpccqA+akqFIMR/g+NkZTHWut0oqL5cAi0o4EM6ShAMwVysQAAqm3Fknq72r34ZKREt3W9VYy4+4xLqtDK8FIlw6MQFz/qyw7r9N76DgadGaV471sS2YUkhQY3OEySirxUTJ/mRausK6inlJRNSi7pcgj5xCzt0PLXV8yiJYBcwoCkNP3BAoXpKWR6G6jrzKnrp7BBety+jZN1BAh3GCc444ZqqrcvlH7F/vJgBspzrWao7xus5vFihtQBbmCWJTWec8HKx+pPiPU7tSCKCfRmUdXBdbjhNa+dDlmAYcXWehJKvBkShhVX/OSYpK9ALJ/aQCvCwLomA7uKY0j9Tqh4XzphhXkZWxV1nqKDQMY4TCeCLwRTNeh5IlQWiVAbo+jnejqJt/YBrsFMSK7xAQD0xzDaMyVnxYYWnikDWIeQjtOk/6p5Z9VBaw2skKTv0YI4GDk+L9iz8iGD2KuG6tIlh017OQEesxEmkyhhmrTu/TFhk/fQNsBqxJNB/Jlu8/iodscKQFFUKwJmyiGtsguNDaJy5RexbzUF5L1ikJVaiJPFdlB0YlxSumTTB9kLjrGNtV7Q7FrxmJ0lJrBwkweZsGuQco3/TiNik2sDQFkcnVF/nl3gmJiKd2sMkSZosLQejDpm/S49YXgKg4nR6j+p1ee/DUlk6dF4gkpmrHQgeVXiUgm6Hwrmy30UCTluq7OfrVKwrEhRweLDfgeBPzSZUb911Uk16KieWzQxEGtITPjhFhc7zBAGQAJ84ELz/EQMikfNq77CV1TF5spldXfRemzhIp9hOIqJj8l2HjC7ej8mR2wD1SKtWCJnbqxq890tF6RCeRLCa2KPscvCTuCrW9rZb+74L6T7e++szdAhPJCCeyXLS8WWEgQa1zvAidob41+CNnbjC3jlnCcCHNFIEgWBbU3GWrbaOlyNPAbnVjSxvqqVbh5SEpL8iZ+TDNLJzokWE7OOIXVPC67ZUikS7Ph30wH0OzDgyjXSr0QGIpbLhiGgpTXyu0rqTnQLaIFuc8QT9KliEI8L1GqJGolFsTxAkQEmYAkqWZ3KnIZgs1sAk+6xn9vFMFWvesx3HKco5CikCAe/wMILMTTbcWbVLdPuAMaleDl25e71H0zaDevm0QKPYTrJAr9Zzh1F4JlGL9lKfPqmrvEeuYvL6FRQKaJy6adA5SYGDgcSs5TPHUHv9FSdKBiR5B222woJ+hJJ6pwUqdD5FENwMhLepV7izG7R2mO2XIozSl7ywegi67B6foLZLhSICpn40nnEam8X0HQF3r250P30Vgw421qU/NeCS9q1VYAFrfGsyWWBr7S7s0XlhCAUzhfwVFYVPqV8W384MTlnmBTh3qmnL9Sc+8AC1bf3Ez7qiYC1SpPQY4PVJE8Knc1bdPxNJoC9bmW+y23I771zVmrPCuTvcufGA+TySFEi/fPzO59I7vnPXbGmc2EyfzvLIQ8Xwi+1JTYgVIX/tF4H9rMzxD0ZAk945eDmEVbbyU1ovtR13/ZBBfPpLsyjVcE8fHOE+Sr3Cz84TqpskBbBkQu0MbUZC6kqr0RQZokgOR+92J3O94Mwljf5W46v0wZMeITwLfyucVjVlUOfVOLBGkzuvmdbUfqDPRbwgD/VOYzjV+u16m6SRAUu1Ii4Knc41/TClA4r9SOp4885/3/k+5y7NUIKxzMczVHj8GqHxBsO789N27AyV7lT3kPTYiNpKQ56btw0WZ332YDGoTnhUe+9LZq1jWpehe8K2TqU7TtCVvi2J4z01rslzPjuixmzpH2v28SpO6zcJnc5VWcQDY7Ujb+bLTNnb4/Q0xmdTbsXi7ESVdeGXozl1sx1jDuJu88uOzXh7nO7Cw946Dr/wqXtm+GvnvLqmGjMDIG7CyvC0d41MJ7FJXX9wLnfH+p6RFGbDzs61yG4wwYs1VwtQlZPNucVTzoBc9NGRLY6ySsT1zIike2Qx7OxcQ+V+CyqLExXyk/u4yjwWfW2zOm+cH5KAveEmdxWtB+HP37CiPqOFsLNzba/duLUCwhizqHvNexsrHrS14yJad8zPmuCJNu1/YZX+dp45LepPHZDKXnQS/uqyhgpTlnWcaZ3+xf6QSb92488339224+i24xdbUWnWojlWl8LsiJocfX7jb3s7oDjVnzrQiD96bS72hn7YSXPAKeB0oKzBVNrjYoxrMXJc3io4GK1ukr3Wu9bqv3M5n29CUtj5KwLlccxyTN4KmWPrDT390mikWmWYJ0pZ7ZFcTU3pLvOhf3n8MWizBsqHfP41peU/3Zi5G7aJQParvR1t6fYD/zReOGTpXwY8b+WD7I6jNpxwa7VjLjpxIeevaJtkA0bOTnl5jQ3KU+4l5a34Y9BJa8akcAkPyXRcj69uj6pHxZq3e6cnl14ctp0qIZ9/RSkWrpES49GZu9EeLz1uXboSLu0c+q2ILoS7nQrtRUuC+xgLSh454WV7dLmsQo64nM+3NY4NuWCrlzYwscMJ7oXwfIU9efAqdoIFl44mNpcPuWCrp2dZzP6DvOtfTgkzlT6MfZCC28Msorb5ioW6/prUT9f2Y2h30vWg7+FKuzkJYPpQbQcufZmnyvbQDLMlgpEdM+ARRi89wHsWW9127DBwPpTD/bkf4LqdHMIsaRqagxUUTF7rUrJiqrs7cVlnw9TP3J5vxFT8JSFMSjCrRMMY7h4EW/CY4uhsG3c8Z+0kAC5d0wqLKuIejIaY/xiwxmDwPyEIuOH/FYbGRqr2rEDjXB6NkWyqeL0QJiVYJ0JFDK704nYlwIByvjMlAXmtOQvJK8D1OUmJdVWKKMQswToU0A3+T921/0Zx3PHFvvHe3S5SzkZui1gp2IgmSCthG9GQdiWMLYpIT7pYPBMh8QqvchKQUl5CIkBSCFgiCWlRykmEECAoJ2FKcFRsya6aFAcsdc8uKlTzv3Qft4+zd2Zn72bXM99fbPkenu/Od76v+X4/3xcBFivgyX4K2wO+6B1zTtr6a2YY+OS2OUgbFbiJhRmeYHxFK75cq6TAQsDJm4VJ91AJxpN+ZA1k1HMd1sXKFOm8uwyMr0pT9vmL4wGGFahwYS17f1QhYnbCiV4veiUfjRqkrOnGP04k+TxI+cM2X14FnMeMMhQ/6rMmTeY690VwjbX46hj9TpGh5wKe+AfmBdfdYWsD3/14DcRPVds8cuHC5eFobnx8dwm15Q4B/oo9Yxi2dvav7e8xEwtttBX4PPhKrAkxl0aDg62f1rhZI33lGO0lpOLzNGsD/wwMxmcA39/qXpzL5TrX/jUGPx7G5osptc+tiL7p3fz46bHZL8o3Gl+DCmNiTp6RcEtFdRxkCtFZOa6M7SwMsVLEM5ChAEWxLa4AdlaiD/RG+4I0hXRkc6CqpkCzlSSIqBJ+TuN4xKRWGka7BzRuhlVYiIW7xiuZaEBuxqRWpMYNKbm3fChpbyVRKH+xgNbcsVyVNM39QDOLbxhLEDSaGMRJWBAUxzrKFSaYM55yHLkVRmZcGickBnsuJQ78i/J4YAyPOUusiUHM7KkxpGybmRl7PBjDSlhRmebBoz9RoJTkaJdC0gdPS0xlbtwYthTqozxEJSGVCUgOCW2Ll40v1VZHkoD2JWUzG16mvb0KnckTHg3FeS8YWcPRftSseJlVQaI88k97yRB3kkJ3DoucGNIcEeXpph+yyaLcJ+yuJDuh4FLYGzIKVd9iktK0B7JjsIhANK9Q/Ifoysg79Lk7HH7GH9CcUIzBTHp4hfrWESTfqIpmGj3LQl5Le/eIQAGKFEUTN0LmYSddjz1D5EU2UxRNHKgQ6G2nalqLRG6WRDGJVcJN8ssi6kbrFROywvUSPdHEh65UB8grhB5yC7XWCzmkzUGjZw3nkcZugFqyIOyCRKamn0WFWOAe0BLN0PGg4dHybVfzpG9grQFxgiOtUKr3K4VK3oMQXeDDeiphEuWbIHkd2Ge0UmPhIg6+hNiBycDdk/OY9FNaI6+/PAchnVbKNEG8IWv673Cvb81Z4H1ib2UP8riIOyAxlMM/FTh9jVL4szr8TVvVmaXcM5a+a+V1Qbq5BC3j4CbUr5AzN0VJqYwT9Zs+UlAtBQ5/wwI4ij1INa2+ODqvwMrXtOL8KdKT8FoD/8X4+Bukb1WgvpcSc5JCVoxsSFYD7BnbsYzs0AFjkyu/p+f5EdaZmGC7r9XP3FIyYyDdpMlcBNRRWauXPYO5djJvTjYeYYViSBlhBr2JJlxPwHCOmLl3zO6Fz+kxR3rsXPYih5XmQSJjzjzacMGHVAOu5VEsv4rCGUNbCmPJS4mY22rWlC8do8icoEXzxWUFwt9G+sBOCJcRKZSfzHryVVQTAZELItPGGtZFeHsv1FeRMGc2Q9FUlhY1+eHiCdM+EB6c/efgC+OTGtSJnsVWs7WmfYwuc8beodoaMcGuIWs1nxEndvd05DpW9Pf3rz1w/TvvhR9Vwu04rwYCTTdM72OaeRC0wRDOnI+3j7qgn1pX7LeVCLiqwAUk6l3aaX5utRADbVLg69E/4j2SH2t5sxncV7BOkgvjgaWT5jfo24VY6BzEBzdBZ091BnNYysDqm2nt7F7S39djt9wZe2Yoy7aDJEbunAUyeiMe5sxJFJFdcvCZiTN8R0h3VYXxm6cbhYxpCcGpi7ssvNeO1jdJDrS8xvyC6UNCXGT4j5XIseJx86xUrMe+8q6tSDKO1yNZ0DHLSL7G7rJ8S4iRsiq+ky54+yZ2mzxUvO7BzHSt27GKTAQiK+2o9Adl5sQGUq+z8q3vNPrSJlJODQ9X01b/6OsFIWY6R+ro+q2csbZufyYw7etGkStbusIsmCWVtN2TQNpB6up69KkhezXohXLOE7GMboZq+nthunLBWALMCcDYiKWRFFeLaSdrcBok30RD8wWDPXRNlGXB9XUFIRES8zDS2TPe317w4Rha3Hmat6liB9q/wEU77WNCUmQeo9YzxFXPf7PUbIs/dS6qHnfbpqtqYy/yyE3dKQjJkWicveekT1PSrDAv478EB6onmaUXVbUaFGCZDihc+J2QKJnoe1M/kG7dQjuY9bkBQPO4c2a2T1aCA1r4m4KQNJmjiojkRdTsrDlQ/Z79Gvfcig603+jsvTthHrm/CHNAm8zzQJC2aXbURf5V31+/8oW41W08PetqzIj54nQr8T6nCZ64KlR3zncuPEr+SperHveOQM6cVCKZM4PeEOaKzBSW4V+FiKe7+iP+1U+4v42/cCS09rLypEo3GRudzPEB+oJLIcmV6vZm/c7KiPtbsZq9T9ciDhjuDVx4SJhTOqlZcc0PWO6qWkPs8P31sWcbrjg5mOW1Xne0dGE8h2+njf6Jfsppt4/srO9NrgWTl7jaZ7vPiBga677AAFnDLWAF6QYCt8ijJShl0OLs0JB782lhvbYzwZwgbLGhe1oPIvbPncYnBoUBLQ4XZadGy4p24o/kiB2X86qdDVp/KWhNA26CbiTg1e9dl2W6GhCYmuotgSGSdzlAMbnOuzO3MOsiQ0oBzI+5UYNlGbaY57jtjMAWHfeAcKC+5MD1YS+bDohQ1VtMkF5geiek98qJ0omdPnhoRe/s2/8va5Wb7w+RwLAeMeTX2rjKXoFJ2nJr8Yw8c+fK3d0dK4skmfEyvHbLTOyuKgiskvixDQ1WQ/piAsgCoOrmB9s+FJgmMPJFX3duBoPhZVFZC+58XUFgn8CpiS92uyzqXQSXNkOwsuLuIYEfApuPjQwfPSoUZCW83TKvfy5wSi2hd9JZ+FzglrSwavAPPEh6/mg0pAxYVqm3VidIGYg36P9wsT7BRr44syxYHit5adWRXHFiH1/clVdboSmuxOyTKmw0+PsaOM0XdxY8F9CCEect2qRY97nVgogCT8wBCJdeOlrYgNmUIvy1sHlilxkedO5X7/O1d2bU19HWiyyJex/qrR2L7eqOQ0Ddzpetm6pWqejBmddHVb/bBuUF6qt8cfdCunjvtgL1A31BbRjSnjPH/9zf063/yRZk5RW+JNMyZcWXlwuBUDDVW8CBahgBlP9xyN1giKYfdzxR5b98cWctdyCkaak0XfMwuLEINnepkNa2ohMjqFwFC9WhUpmQEM8dsqly5axIdh+ahNcW3iRJbYov7hZ5Dhlmh52rS63CE3dyFVwA3yAlO/lqwBd3zqh1PMaaN9BO03nizgFxH8WahIzbC52Pe2AmVcpW1/02FpHCQ9wpxTsdjTI57TVN2MSRd608yBKgVyg5rbL4JiKPu9PMIDySkANQjEcZaHGz1dviHuVKlZyORLyz4sG2zI9/MjtFctqc04gBGDP3bh5DMIHh5OhAOWCIY9DeNbGFVxZC5WpYKmHhj729SzEEYBlOjgcmEnKXxe4xc2mVakQDsNx5w6HSrKBREwWv7lBhLOhGxuVOhi/54U5278zhv7FetKNLRMhRgJdx0dWw3MnuZHCgEGOPzD15gFFY7kRv7rnGkaPZ7IqcguNO8E1158hZGXBdD5e7jcceP3tywaBnw0cdIQReVUSRGRh4ckfM4O4/p558sae/p3txTqlW7Oi5jp5+q3NZ9lgqceSslF0QK6WSg8HU2rn+ouddTsKfccNd3k0CfeXjJ2eRv9rKu7w8DPnJtXsQXeKO1s6e/j0Hvrl2+dnjYwadGnly8d7uvmrn8q88PcSNORcVb6licDkDOHXxVnfOO2wpfq7OSb3Gdy/4XE5uzHkLNmZFPJAkUY0pGfMIwsyNOR+oI4+gcZN7mKwjw1XkxpyX6zhDg9yY83wdNzpHeDHnoJ6b1BQv5lxW6rjjz/BizjOwjsGuosqJOU/VNcMxz8lFSVNdkehoogMm6qehutyOeZxE56W6MkDNSc4kTdjc1amL5oDqKxwSFS5qxSTlZYIPJXlztyhBgebD3Bl+NBfxa1Odqv0wF/HrUJ1muZkLg1fS63Op6M3iiJOKdbrDfNy/4jS79BRn8DiI8HCLfKjomKZ5jQODl0EL2MPW/i4MFniRgzLGFFI5SF3bha1a5Qzqk5McFIuhzd0Gsyx/k4LcvAEOUproKPQTC8G9jOw4THGQ0kSbu/xq26zd4DgGyqPMnajesH/8EhlcsB8DIc2dgy9ZRqZl2e+5kJBZV4e7cWTPT5l5k5BB1r2Jin3gBpBGe5z5kpxm5M0kUJeHcNfMfNJvHlqt5+2Yfeg5Okpg3SRgkq7j9qYVkVpFpjX0LT6DgD47dq+hrKLHC2msmwQF3a8kqeZ00bOYBEOZ8cRRGldGeha++eyq8hyt9sfJh/vNkQ+NEa60CnNYeO9mxhNHp7Fl3o9UFHaATVnGlWYJ31hw4t51nDsiMa40tcbSdmwrTQAbi69LTHuaMmxM6x1m2hfLwMYsVorpjG2mQfyzNGT54KUbrRhSWQ5gU9ErM2upyPI11/xGzfEQy1m/yUZ1XjPLakVrtGAow3CpX+OtWIBhtZJuvFCPYbWSatxcjbOrVt6GDfv4DKuVwcZrvdLs1tjmG3eC2VUrQKWQFymzekeZptF5PMRq2UqKhoefqrPMLHYagBTABmWFUVy4QfgeDW+OUYyjPBWFMMhm9gGoFRpPvYlNe56hY4izbGYfUuFlbKBAIgJM2vMjSIBhh652rPiWV3teCrvj+BISDf1h056HdfL8n7lr/43iusLr3Z2d3Z1Fih+pSNBIsQ2oSTMS2CYtpCMBdkyIstL6AYmqRDIEkdTJStgUpYQiGSjluRIOhFezEikWDW5Xwm6apiSWMAmEAP5hdjdUBu7/0pmd2ZfnPmZm587c+YGHwet75p7H95177jlDoHjqu3SeyN4jLMZzQSzgrUouprQ5QcSZCAmRwVLGGMHXRXVeGiEvPckgPw8RcFgQ6L+3E5eeYZCfz2Aa6mvPu4ajXxghvyf2JnrkCC5zwVDcplVkHWePn0uEOqiMEetDxGQ8x94t0QQo4peUMfKwof81rAbePxESPJwzeFuQfG1+kLnqACJ1bSp7FfIxUZy5fHuW4DJVkF3iR5xMxlkqMGANhykEW+F1Yxq2EqrTjF3P5kXiqkvFfbxsxduzBqTjoJXM/y6k3spaWjdribEQeMmCvnVK1k6JWAPS8xayIYIIQP6GRStmCkinlRcsJBXOf2ARhDAGpKXChLuKzlKrnCgJh9n+PJYy0mELTsXWI7uSG3XpGQcfuQ19rrCEwybc/cBBljLScsFl6MRSRloQF102E5Yy0nH3HThDGWkKXQzG2WGwFK4bR9hhsGn30zwCM0CaozEDLe2wGwYFHEaBjs2zwmCp3BQPs3JBm8o1AmZKO7JUuCYrDJZO7xBGGGyCziV/Ro6C4nTwPCOlmkFKvpuNo6CMQgfwssFg0/nyaOEabbUncGQLlMEyAKQ56bFZupw9R7MAi20xFhgstC2hzaxPGvbfmWCwGg5LmRC+rWAVA1ATY4HBwnBYXJHsAOsxRVzFKIPNQYphZ4tZO/hFLiYXoQzW/6MgGA7LLQ/ZCBMx8CQDOz7h/WewMBzGSxuj4jrLH9EENoagdur/nSdYZ8i4ciaQtP7eZQUxf9P/M9gg5K2PqxhqlnSQXgMoFwOc/IhJBpuBnODnHtvB1gOaa4QOI/afwabNIZeTn9V+saqaSa3WYwiqhEmfj4J4yIT2WClO3bYYixOls7oYNJ3t9+UEWPe9cEkuq6qpd2jnoVlDvy8bwob/zOnNjZKLFg13Qvf+KfYY7BykHi/9yMBX1kiqbrjz0Poi2V8GC7F7TnxiZCQmLJndE0MJNkIZ7BkfheMgYKnSnkh6wRLF2GgY8LPMMVhYsWFTec8WrBhNyAh0nPgU6rT8PAoKQq4pZ/OVheswcZs20+/S9LXdu3f19fV21z09mwqf79N1vGim+D4z2HchOKwcAbkDYP20MVIT4J7WD0s7DW1q5CuDzZlrvYUSIOZP7upqx0gklqZQdnR29/ePnk7pDuQGlMH6CKTlPMRNqNt5s0usTtPs6Oju7uvfPTo9ff3SpYvHjx+/9/DhwwcPvv32431EXBL3kcHyEJg7AFKBT9pBc0tnT782TvPBf/ZZBNPPQJGefww2BunskC0G+PO7r5/+t23UA63l95HBhiDvW3Y4CSAOv3s55t9R0JzZ5gV8Kz/0g2hXHPGPwebM4DDsmLTALUzwj8FK5hg1ABzz4Dziyz4xWB7StyLnGFwswLsE+NaFC9b7TXLc7CEI1+mwX2ewkN5vjp0KsjAk4dfAkgHzeiLW9WibSRNWICikPwx2wcwtB6222NgvgwO0khMAABRdSURBVMLRJXwAvknzPjHYtFmUrEX/vb2EQ+vxf7KA0Fh/UkeQCCVbi70JCWy4nFQKdW8HUdWT8GcshGA++o3Wgpe73f1HEd86X7yjquIP9eALNWgs6QuDhRQMh2sWqPV1AL+EB0rD5A7X6SaqRDer+GF4kEKV+ap/mwerj5+XAPSgq+nVsoIu1vnbVYif40fqCFIwnH5cJUfva5uUgxaRri1/8XBtCzLUoLGoL6kjcyDipYpTya4wXALEzUQrOxYR19Ry4cd28LXnxDxe0VWuHCzmIdg4uKIa45bXOtyiZSriATE3KdJQRVdD6r+VMg5x0ewSMtX7zbna7cohUIkfg3whBySZiu9e9lpA9yilw7ylQbEKl2dqtyuD2KOwD5P/IAgpWdmJ3EQI6Pxo/jmzSlelG6rdLlQJMufD9POkCYfxVRci31imRjtt5cNtZh9oIO0D6rbUctMQyvUnPR8VBKkmqTqVgHhjzpAuYSpFiRlCaNWzkdpXhJysedDziAfJYVVHb/Al6Uruku88Y5LuGcMVKoFIrWYiJ2uG3WiAaBOprEEjFQHcGgB6EOb6rpik+1nXXgD2hAp16oDAyxzwGmpmzE4l/aiacZmIAR0eclNL+WzCyMvmALgxUBczkXUSnhuebMqHcVIVMami37+g//H8iOn/LRrUPh+YqwNZadR8Ba8NL2G+NB2tcQpSNf6apFO9rb7Ba0cC6XUWGJ73ES8Moz9VOZI/V3bqnEmDD1WUWqhX7xlUkoETvZ3zBKlQG6/hA5mKxvFXb5lfQ/lA5GC9oaHnhqa9PaWEdHjJ1Hj3YKWcI9FrAo9CuZGoAF5dIjbKvJo8Ta7wkO48yUe1Xr8s/Cfrzd99WDcjLrukaSH6enDc07ocyL1UTnpa+xcDPHNnIXcNohJ4MxXgJ8FvLfNU0ctzPEhFdrROeQ4Zw9L2d8EM5ggA/ddkUNyz1HkgdyjrJQuCdDSL1P38mFjqryx0PQ9V7B1aSsnctgQ9FTXoYfqBk/IBNMosPZOFOynunR0tcFIjTLU3v2Jmc+jbzzFA6M/pKi83q9BYvWUkksXrlzeBF5EvCLZYzDVMybtaTVjhZGaJVsU2AaBssOcLZtBnBgvenXTBbo/llkJg4QR+3h3UukbQL9Qzgg67xZQkRCT+xPQpMr5bgwa2lO75meMVrO+QhAe63Beqon5GpMToJoZJsM4rs/sVBL3g25Bs7+ju7Xie+NqeYmzSI7hyCGIeAmHmyrzmX35DijSYY+QI8Kj1A+yme4xAMEOvqW+gtHfCHoxBo10HL3lDYaF99sIEqCS8pL7+kvLyGOvDndXlvFFNaI9E4gDvv50JDOjK+xNGAkwJQMhqG8DGHmh3kCDp8H745UBS9+kRtP0sYKhAQvQESSdh5t1EYs98V6+hdlG0ax/DfUrai1vM8K48A+iknKFs8WbDq/IvYsAKRr+DogeqCU9QHURWqgyVt+NTQ0x+Jca2RgI4r0lfNWegnnkOOWh3tvyHTYZlCi0pdFDDrf+wB6qZhgK+OWRObsaQJdFu2FsM7RhjWOni9FUT0c55ASnduLFlwy3GUd5QEQPFcBGby1FXTUQjswVkHA7pxIxPbjBqi9KLGK+PxSNfUQ/ocLPDSCe0loQ62/qjVEpf/gHTF5zHSydQT40h0sJzaHWbbLt46pup5jcDk/l/BAI3JdzoFcLFrwxlrInqoj6Dru5LyM0t7WB9SvUKSneXuCQBXff8jsA0tlNWTVT/wDFM7WK4pbtnp6aeR7RE33o0lLwrEtAqJ9GlQQizCwxipJsc4VJhbdncX3p7ME2j/yyCDkImZo4uQ0edxmCkE7pUVxAh+nLuKgBF0qUhus2WkcMLmtBeJf4L7RfSOxd2ApA/Q3wFaZqFxGFUxjuIli6iRfEYIR359iZVuA/JCxiD5HSomx1OuvBy8t7dlQBoO2YlMUCz/gE5f3EQI522d3tHcFp5VQTK6ymLhn/F05RK6VmmXEDaXZv6jZsxtPTmWlUrrbYLHwDL6Zkd6qOXAWUrguHxa1+/txPdyT2hbhxo/bvlFwyo3XtCN1wNqXG6DbF9R5RmtDe8q24cWH3LjnHQIgpJNFT4XtLOfO5AN2+q/6+I7/rjTm3khUWT05+9tNAYbvw8v1/16SC/9Y4dM9aUEqw8atP2KZ2XhLAXpPlz2lrzr5yyuBPCOe1Kur2N054cpaO8DEHl92/WYLLS+fsH5BW/M6XJpqw+ansVYUpHeTKJPHL3u4AuYP/nOMjI/fe9UiuB1n86WAVP55Q5ZgHCcvc3G30CWnpGT0Ml5L65pvcSaP3AmW+fpxLyhqyNCvjTVKURQktn3+jFBx9XbhJyB+5dfq9d/1ensmmHmDRyYzmrGqHtTnO1Z0VzS0d3j9Z9pKujWdG/pKz8MuV8ITTOYe2NwT5wclethLWP0vnGsQaVyH2WZ78U7cCJa71d7XXtVRTVHI+lGlxJQnTfr4w7KyN867t7l6a1vjh9u0evX/wx5cZSJt33K2l2pvREXPcrPEsTE2W3/UqEpbHx427jlRmWJpW67leSTE2NnwTPeZN0sO1Et6XcsBNXs9IuzbrkT/Z2tHf0jJ5qXJXcTP1lXCH8ic1ldLbyy8bSI0OuVtvKrhyd8ed7e/q6dfjS+VEjyxPcrBGIuQnteBVla/KtvNDAh9x2cUVDLg9K437SeGB+q/Pti7oYFLKu9xdSea62fRMNLMmtoMBLFHKk/DnJTp4WEhRcisCULuK8vdnayQ8qKLzsFq6jc+bJnxWB4lS8YbeS7vQOBX9QxXvf4auRwa/dgWH02M/XzsWbdWdIcJjmJaOvJZD/zNlLdyei0x22p+6ewzHUh1yJ6DLdMpGvRNDmCOfF3Ijo1IdWHwEOB1F/4UKkGqRZaFB6PgVLr4lajcONd6zKUc+G8TuA4uhnpBvO/fEeTGuLyqDgxPTCDXN0T7Jh20X0RUuqcMybbNj3AGxxBscao9VJTy72cTuAkznpKhxryOUlPBoZFZUcEba9oNAIlg551Sz9X0AZcbR5jWDprGdtf3c4QsWzjWweJ3nWslkFVg4ciyA1sHle9se47WgbZk0dI+x87zrPpBNkXMU7ZvMcLzHt1UVv5w5w1nFeOuHpCEHe0eYlHG9eyNvhGcNON8+Z5WW9bQPPOapFUTdvi6Of9v/qru2njSuNW4XxBfthbSOqZjUPOGykIvmBGKEmkqVNiFCSriUvkUMb8rANNCpokUBpC02yUi4IlSRI0O1GXKUlF7Y4RAokW9KGB0i6TWjdhzGoqrQ7/8ueczyeOTOe8Zzz2WPDeUMYPN+c73z38/tFKwzhfwnUMwZuXl2leczQyQMoix8WsKxVvFu+Jh8A/NVT0OYlKukPlDME+UqQsQ1UgVL2OiiluQTI7WscrxeZHXWIbxYASXpVGOITkEQIJ+mcya8nWjmgK22dgdW5BixA7y2XuyoY6QGYj3WLWT5ztFUdhjYgrt0iZ+UiXh2Sr1qYavpErsK0r0qEq9Au/Q2uQKCzgomrbk3AQncUCHD83UDFA5XSVBPFY+zNKr9cLQIzD5As1JOQmO3RW9XiwIKz9J5lrxk+rh4RMJgee5E1jRWqOOYN5jjyRRmrfzUVh7anDRq0ZXiTkctxoppUsmvQU+FJsEUgopSsnnRusKs9y7R51b1/4ImCv32BBdR9yAbJxeEFZ7B0szx4vOJcJ/qDB+72C3H7aolX3q2mcDbAaUXXlL1deavMg9C8yy+CA6WaIqhXaqDyz6pKRxGy8S6vbaDjEavE1anVBeCRUvy/trtb7ftotfC6wILdsy9UtMLenRmfTafTM9N3/p3U9Ascww/ZIXNXjm6he1x3uVkKnVaY3+N/hEs3snTx4lyRmkNlSn3+W+2NhTe2c2wfE7+D/tfVnSj+N0etsoVERSzm1QeN1I17SswGrDid4Be8JUuRCNKHd61caQVSu8D9aB7yYvn2Z6mUKzU8vDHeSy54SW2bLh84il/IPkp1dX9tVQCcqgBDzRjZq2Br32vDL0Z6sHw7k674X6CuMrfrz8yrtwGRlQ0avnEXCJJFnymUDgapkuufTED7T4m38ymwmRiXHOe9+jZaFKWDyH5gqAGaPSnerNbUejhtU4S/I92TTj0p9gn0gQvAgQSV+9EUKNbtcHqAAQnl+n/Y1UdkCTiv7lbvjkdNIvFFZ22KF/OxHLHdFgwlCjMrneqemzCS1zkbp5yLyzIGsLVV3ykZmOJNqKqX+J/J1r3jsD2pv8ZkHOJAHUr8ZnANOq11sjfyA7InhxhVYwuWQPtF9aUUQlMPODn2NoqEO8oagngZC6+G9alm8Qukc8PudLA5ImznTxbPGG71qlhrgghyu1OaIymQbgA2LcfqCaQ/Ff3IsxxAnPJ+o6A4mqqEJgz/oK48ly3N1octtheUv1cQnpTbeHFIfYAiRHZFDap93b6eBFwYmnbnYVEfMIr2DaVCYj53ARWOVrWbM5R9UWIXh8ZvMDStjSfAwWX2X0JSGDmmXLuYAPR+BWrDjSRFaw61Wwm4ZnMxcyWM4cA6Z0b8x3Ln4xdAROimJKrVBztC3BH2CGE0amcsv8OgD9msAtrhi5ID8jdADk1nPav6ar0zlL8EVjNsiTbStTG+RIAb66+p2d5TEsj/mb+mepaelhjQvx0nqDHIiTNnMRQ2xmd781B4WRqzGEVhk5gUl1eTPHTyZmhP+8WSLntZH6ewGRr0cw2JshAElcDq1XLDYL2ih1DO6I1KbdmDsMAx2XzjNBRRXFyJtBmLj17xN+y6OLNoX5S+G2wYJtoq992Dz0VzfJ88AqwcDMU6lu+smxyv+K840OQ7KMJHdHpjBCtKlPfugecrvHHvF/7iAwW99/T8esrS9u3iivgfOPWSvls6pW+9+8WyjvQRH1e/aVEyktqKM4pi6VxxrpNyTnd9r07UTxLXlbMhSdCjJTMuxm/RL3am1+1SUCzdY57X7Y3TA4zoJ/0kXU0Z/QFRvrBZZegsEq7J3tLHsWA8PTzPRzTSBwrZDXPEneUr9I2R4CRpsXNH7J20QLKfTnaHJ9yTpY/VH3DIbjjwQ+VCWSTFVnPE/TWZDa8iIP6eBI2s79tzj/q/HlyrN9LGD8mbZREOF8otKJa9IiMYh48MnQRExokjnBirHR9SUqQUR3g+k55+XZ69wzBTllQV2EdMsuWgJM5IsOWvOGhoVsTx4FNBB0cfkrghGC3HPCbxA1YIb8iiNLPph5K8XGfywJeRsjQrH/QeN7BJIOOprJJDFf8D0iGwsBpCgnnoXGFYZZnJIb4n32cNFBS6X8pyKHai/XBjqZMAOcYDS+w6YVHeZT3ZnblTIiR2mU75Sc0tyOE5fcqaI0wRLpfmzUdyjAeWjO3otbLj36wqvuBTmxIdaWVqhftXyFYOGszTO6VFYgJGLI9FSMzfZNkhCCD9Z6/gbeX7o4vFLvcQ2STtlPkKIWi0ECUBmC/qvtWrpWkHrRnS/EhnOOrAv+Sb5r6oFRiX/6d20cAgMSD/anyAVdXNcV/hELZ7tEkFqXWlyMtB3pb50BHNHFSdCBUXCCnlK66M9+bYMfoGaUNb2PHTZlE5s1dh7LAqWqiwu29ITuQwT3o1pBZ8kEZLrct3XrzY+PLu4cZQJBaLHY40BhUGFN2+Dphcn9SmWAMiR4KnZqCYo+P2oG0aG+YKFTo13+ttIZIExQKWhbmkwYCYFE4WtEA8wd51+YJEAOit/jxsf1h93ECENCdxoEc72H1L7ZFIJHai3yShnzK7cz6hjW90skKrnSc8Rdmjr9mCs2PcIJL6XPPq3XakkCf65weLBt5mF18pJRCiTHZNGMt5Nlbephv8OHZ+/qvgL00vftEz4DWy3DBor5SkcsDMU4SjS25P85i3AxyImuqdrqg5YCveSI48a46nIrD7hFu6M7zXx19aXPSMU6YGJ2ANRfxS4AGpvq6wu/1AAoST6BWlh3xbZ5HpXqedOC57WNX8u7cxoZscOsWxFbgnCQKPXMSDcOzrK6v0w63bU1xhlU4XPL/wfCk3KBr+hEfNcIEDBvyJvMgOO079M9mqSOGJ61Qn0EL2hzL2qeez7bkgWWp6xBOKnsee6tAgSDqM9yo3fcNGsYNexQHrA6mbvxGI3UCxwPSdTGY83RvLExaFTzH5t643MzMzs239ve34jB4FCudy3SSPgUOv1j6TYMi/ne6//RkR/ot4EYRDr3EKlQxI4kVFP6G2eabn/K6HnnTOniwhY/yxhRoGNxx2z2ijQvEVa0W5QjETNCU3JA3ZfIs+puuYf8Kui9pqKo1wy/+AGncPTxqLitQqZrhQ1mesiXt+IoP0UjB0sOObnxkPG2khkzcaiSyfSF+cT7pKXCgznp2dzRk0ataEFPVCsfxAvM2Izw2zQFDo2shk1jke0HOBBDHT66kUysMEVxlX1/ZxauQP14aIz+1GdiG91G+jIf6EnH1Y6hPgkk1pbBxFd/Gm6rhwnt/MY6ywd7lW4tej9Hvnr0mXU0uIK0UnLNy7fN8DB0tXDTjr4CV0vcwhSXqpwjPzeoXe/KMSvhuDrW86KRwGtq1fnsGBLiBAwOOFh+agX/15yXtvv54q5h8S/eApeRRqwaz4uaicnXRYONz1l5kmxk0X8VZIPlDICyWo4LLKX6PIZAX61x+QSEPijjBwVe59195fIz14/5iZ4tWqkPyea1+s89goSUc4Tp//XmEfdw/Ld58rK8P9yANJ1/5ZP5r6FD8mp41EDupKz6QNA2MVqdrC1RB94KFviIRalzPDVzJv7uYGKzdd+2vhKDxLNVG3jxdcvg0qqZd1P3Jvi6c2wEdILUwOtXakZ2Zm9TeoHUsKHF3++zifWRlOXblFuoDZthX1tF0d78V3goPBgx1zrn26RsmcR04Bs6f/Y0ya32ReMLR/9u66nC+ucDQN9pN24jEGKVQi2freXV1vvswM7uPn/z+IwNG/6uh2lgAAAABJRU5ErkJggg==","e":1},{"id":"image_10","w":438,"h":633,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbYAAAJ5CAMAAAD1geW+AAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAABIUExURUdwTOjMwMmvre67rlc6XHhXcPG2pPORl/dtg1U5W1k7XO++r/KYmlQ5W6KHkVU5W9pkfPdug/KtmvZtg1Q5W+3Vx/OZmfWBjmb3llkAAAASdFJOUwDr/HQw/eAyzq9gn1Xc/vP8pl0/0WkAABlTSURBVHja7J1td6M6EoQtgUKEefEYsP//Px2MncRgY0C0hFpUf9hzdmf23pgnVV1qCflwYFip1nmudRofUHyYlXVZP6oEPC7MXgvw+DH7ZZeDnX8Vf2R2B1fXLTo8Kp+EVs+tEuTYCA3k/INWGxTIMYQGclyhgRxXaCDHFdqDHNZz7KB1Bcm5oZbXxAXJcZPaUHJpqrvK87xsK7/tJtwqxXDMP2iPfNINNltYL39UYrDplz8uI3v7D6DzR2qLKkcr5CM1pE/OUkP65Cq1H68EN2ZS+7FKgGMmNQiOLzVwY2eQ4MZVauDGlhq4sTNIcOMqtfs6AKS4Sa0ryI2d1GCTXKmBG09q4MatrSGWsJUaYglbarBJltR2b5NMqe3cJtlS27VN8qW2Z5vkTG2/Nsmb2l7lxpzaTuXGnto+U4mu2dcObTKuA6gYFgm5gRrkBmqQWzhxZIdyi4Ohtie5BWOR+5KbDojafuQW10FVDIuE3GCRkBsscucT5dAscic26ZVFpjT/mBIW6bYrUeGHRTqsIsnhkvxSpDxS/TwxLNJdNQ1Rcwtcbto3bJFEKOEmNtW0hVDCTWzFDZuCSzKbj3TY4JLchpGSEFu4LundMFI0cEmGk/+OWlPAJVmJTZFiC9UlvRNbcccmsOJmtc32wEbV3HKIzV2QJHTJGGJzl0jQ3HiJTf1ga9DcGImt+MWG5sZHbE/YJJobG7E9YcMuAB+xPUZbYy55amvpnCS45la6ZjJj1/qP2qtLqlPV1mnnzS11Ta08LAiSry7ZQauqxT82PHJtFl+Gre+Sp/SObbHcYnjkynCwJJH0XVI9tGbALYVHrozis0dbQ7k9QWtLLRQ5PHJNzVhx9LHJX6mlPWyL5FaGlUmcn0TOZ2ATzfGPWha/1dpStQW1Vep8rd0uoKZ9uSe24+Fuk0Nqe84k7ltbuhTbbbe05TaEppb/i9HazMdW8fS/Uw2xNdWL1va9CeC8tcmDCbbLSoMMbU7ietWm5PSvSlm8YPtarbWgMonzRKLEFDYlX6A1IlqttaAyCV0imbmfWTSHw1JozTX5XhVGgsskdImkS3szWluTxAuhtYGEQGpBZRIybGrmaZ1mHNsIs2EewcEEwiBZzDuK2tLN0mXQ+mI7rfkhg2ludLl+3mmdlm6ULoPWV9uqE0GhNDe6ICnmnWks3h7q+Qitac4/zOLTuh9SA9ubcdQMbCJ+2a6eYNYlybUZMrDmlhImkjnY1MspgxnQ/rrbae2PGUhz04SJZM6RxsFfm8fsR2/Xc7b2sGsKbMbYjkuZPfRGcNg1kOaWUyaSGc/0vn+mVK2KRdBucfJKcLY8kOZG2tpmLNyWsnoznVRobjGpR8449539PP0kssqtFbMsVKjNzTE2tV5s89qbup9FlyrM5kaW/+WMB1qQQJvT3pRImvfcwji+RRUk1RQ2VYiGrKZsUn1476MEttnYKJnN4Pas6he9hZBJqE4kyHQMmyoezGJn3NTHThhCJiEbSGbvXo8v/rpZ0hCXVHMXGSq4lVtMm0iesP2KzFoVc499DeWGIDk8aaUfxGRjv0ShZp6NVaFhI0sk0c9NSx+IHYUro/ysS/6ZJB/MFYQYmS2M8rpJSzRbVfFp6T/2t9KAWtvz/EJOL2c7XLLZuFI5R2zD5qYDam1yZryWzfa0mom7Lyaw5eG0NjW9LFK3rZYtHfFtd5Ny+v0BGdiCOx/dT3nhJhtfq5jcGxJhLbjj8V/QYX9Tjb8li6nfsLA2AdJPWirYYBtimfpz7psA+hMU+TFT++yTk/tzZSCt7R0UwQhbswwb70wSf4aieCQSE2xpsK1t8GH9ptb/WeUkNh1EaxvR0kpsB6tz5A8/azG5RGCdScr5apN+QZtw9OnJZRyCR9aT8Ux4Zoriow+KyRNDaQgeWU/+Ajfe16fmFtSR8nzCA9kstl+8oZg8Vsm3ucUTrUuSrtqsu6wc/y1TIR0pTyewFd6u2kSzyBxkUO9L6Qk1kbY2YR/b6M+rgnpfKneJjRLoyP9DjB1vDep9qXhqvk/Z2gQhNjEjSxZTYmPb3NKJLSrhaWsTYsaKW02JjW1z0xPbaZLQI4ULam+jbzF6DE3zb23vBFXQYXND7d2KW9Wj7ziU/FvbO7kpusW2q8mYGrwxUoR3ZUI6dW5Gsdlr+zAxDu7KBP3pTb6B42waNEw33aZfW+C9aTPCzbs58jTYhV/1nAbgkUNuktX4f3TSH5hL6vEbYV76hHLpfYk7bAxd8v3dP7l4h02671hZcsOXJJlNbPxcMp68YUAR7GwLv02Sn0uOvERa/hmiYtjalt7GVYbR2p4dcR42cUx8UdryhRs/lywn31bnGCQX31mog/DIZ0iszpGYYitD8cjfl4HZnP5fk0mYuWQ+fVEnv4mkCTZWLjl1h4zozYmagLGx2uOevEOmeH4/M2hsOpDWNn3tgMclFmPjFEpKYGMYSpbds8Uo/5vcNa8D9Uh/839y/zhJ9nuXV7EcG59Qsswj/c3/z58pi4RJImEkt4V3EXqLTQw+V2T4fRxxiB7pVSLp7d8lL8tRswuEdYge6RM28fyND8fVPsJqDbD0s3mE7XhIfuQmMoLfSE5rAM0XW2uLmeg2+RISI+Hkkgs/mvItg4whO5hf/ByH55E+rbajVRsbrOW21CO9Wm1HqzY2OMut5IytEePgshW3rOvQPNK72ZYQxyhJ7g0ui6LoeLwt5tqlgYhW3IcfB+aRHs+2emfDpBBrvq1HB+aRfI4krPum2Tgsj/Tusi2yM5Kc5KbDxVbX4cqtDBZbsRJbHofkkWx6m1qJzWebNFjZ7CKQeG6TZbDY1HpsOiCPrHcjNn/lZjL9EXsRm7+pxGSOIPcQI722SaPtKBbHJGuiikPxSBbvSSkqbF7apOGsVe4ij3hrk8bf1Sx3YpF+2qT5LqLch0X6aZMr9qOUDD5F+mqT677P3ltwqiauOBSP9HglIGvy8ssm4/UfSIRukB5y0wQfqAg4QvrZ3mKaTxR2W3u8yqHDEptnRiltiS0OIv37aZTCkta86mwp4QfzYikgVfhSo/NIT5xyH9CoAokvitsHNGqxbQzOktS8g0Yvtg3B7QaaFbFtNO+yA630EZolsXWfVwYATXv6yr2u7ZVkDs1PodkVW2eUgjE07e/dFnFe2+UmmULzV2i2LdINODvMPL9EpnZQNsHZgKb9v/hHl5zBWWlpPO60S+375O3bcWyAs7O2PjAp27FkhuLOU9X/65Fsir2MHj9w0/WG4Hp4kiGvJHkhJwpbP6Fm9uX2jsDVqhAjzJLzjOqUZmvEn3P8zmY3TtntgP+hOy8vCWabCO4uOjNmXRVgthk4c2rU4ErWzNw6ZXH+is6RB+D4M3MnOLUghVgEl4fBzBW44kxSq8CVOo0PQZVlcOpMViYrAZ3eZBYHxuwBruRAzYRbeojTEJHZnVSWpNSWc8sDRmZRcsTUli2+8zR4aHdyKS06aq21BWZvwbXkcm+1NhtbqXfE7E9zROQkObV5i4AdQnuQI7FLerGp6bwfxzuFRmaXzj1S75lYH13pk0mioc1HZ2yY5JFEsj5+5R5d7odLFhDaMnBmeiuceCSERr0zZx8bhPa5jBpcYdcjSwhtzri53FZuYGaMLtVa529WBWVZ2pbbs9hyMDPVXnpb17UM2+r2jt/ut1oQW3g71Ztv/uQW5VZAZq4G0emBsrl9QWaW2bXmeVtSHY5UyI4Znqu7+qISGh6l26LRW4IH6bgiUNupUYLaBpWA2h65gZpLVlTcXqkl2T9ES1vYvpLn/0JFrUX2XVUVNGgv+R8J8mSfTofsVpdzhCdspbL2of+Lsqx98El0NJTb8RglncaiX2IPbHBJW0Hk0j1hmjFJ1a/L+YwnbAnb9fGMr5e1K4BsiO0KtVlbZj895iOx2q7obdYyydNjpjbJ6owdAVuZxCo2LABsNTdg447tQo4Nvc0BtutKapcXbEc8YPu9rQI2YLv987Bu44jtgimJpYoqukzyBhuipJ36V9FlEmBjie1avUy3MCZxgK0ix4aFm51l27dNbFgBOFht28CGKGk/SK7FVgGbo/oGNv4eaQEbVgD2PXLlehvYAsF2wcLN+kRy9Xob2DbCVhFjw5jEwYxkHbbkDTbsb3uPLXuLDWMS+8s2C9iwUWp/2Ube27ACcJJIyLFhx81Fa1u3AqgQJbdpbUNul/PlVtdb3f7wVt3/cpmJDZnERWtbXtcnghUyyRajLRuFTOLCI8kL4y3yckCt7ZVobrbjP1ySQR0dYYNLktbVCbYLXJJfIoFLskwkHTZs3jDEhktlvJuRzJQbHja3/I8VN3H9c4UNlwExDJJwSZ4eCWw8xYZXuBnmyK654XkTVeQQGy5xIqsvYONYV5fYLhhvscuRt+b2BbmR1NEpNrwKQFQXx9i+wI0i/l/dYsMd5Rw98nZoFg+dWfzHiZJNW9tJ1epkjA0nSrZpbar72mBDcNji3miy9Z112GKF5sYH26lOfr6qO61PRi6JFffa+mfokD+F5sZkINnHdkJz2yKRVCuxKSO5YVDiHFuPWq1PJtggt3WVrcWW1SYuiVDiPP/3TdIwlGBQ4jhIDrAlyJIbtLbvtdg0BiUsEkm73F6bJLHidp9IenLLU4yTebS2Vm7lL7XY8GQsXNK1Rz7rLTU+zwyXdBv//wSXalVV5tgwKHGZI3/3SVcwq3Dd3SZioziagAW3aYw8b4ntHwCYWeT5Um1ZIGBUX+frptjgkkZ1Pm9KrfoGAqPOtjG2ClnSoI4bt7aqQihh6JEIJVyxIZQsX2pv7pFwSYP6t73Y4JLLq/Kh4JJL478X2LB0W+qRXmDD0m1hfVeQG8MxclVBbmhtWAPsqbVhDcAw/mMNwNUjEUp4eiRCCUuPhNxYeiTkxtMjsQZg6ZFYA/D0SKwBeM0jEUpczyNPStW1Mr4sDaFki0By+n0vkQgc5OYgkJzyv7dJyxPkxiOQ/L1Lav7qNuTm3CMH15JAbjw8coANcuOxaBvcAQS58ciRQ2w0csOEy/Jgyw42TLgsD7YGvS2loYYJl+Xhv5VIglBie/h/siI2hBLbw/+e3EoMlJkM/5+HW/mpgtw4DP/73P63dyZLrqNaFJWCCtALNLm4DP//p89NVl6n05YBHZqN9plU1OA60lpem0MjSZAadSvYkHxtAfzvn3+N2AYAdSvekDz2JbLQqFvJhoRnuFAzkqcTQDOSujEjqRt2RlI3zIzk/g1kRnL/ptDCFk8oYy5ssSlhQ8KmZIiGhLphNiTUDTQjqRtkRlI3zIykbnCTNuoGOWmjbqgNCXXDbEioG2RDQt1QM5K6QWYkdcPMSG6XQmYkt0sxM5LbpZAZyaYkZWFrtQXfe7mshk1JiYUtPbtybwcLbk768MPrFt2Q2Au1Yq8Hu362pW7yDYm7Vxlq/v7hgbpJNyT2fmV9mYhM/1EYZmS8bGV0+/5wT91EMzLojCubGJHUTTwj3fp9ZUOxiHRsJmUz0j1WKBWRiS4bZmQKNlcsItlMimZk+InNF5ONo5vkwpZz5XTz+Z991P0bkyeEqG57PpuypQghqpve8dkrZUsQQlQ3teOzj9mU/MmVLV+3cAqX8sHfy/nryj+bkvLd/63UKyK3+saRX5xyy6yQ/Cy7OnsZkPaA2S5OuUtl5N9azaUmWW7UrUxGFi5ul+7PSF8fW6BusqvIdcpTN8CMTEvJhRnZR0YmzgoNM7IP2dKwLczIPmRLXDszzMguZEvEtjAj+8CWuORpmJE9ZGQqtoUZ2YVsqRtDhhm5vYfZp26HOZ0Qua9tpXFoq5Q9n89WFNtRTifE7WsHaWhXYF81i6bkyqGt1Mg2q/NjqZlNSZmh7d311+pOIA3bOp+fSjAlj9GU7Oj+5zU66X7+u1/UNrkF6iaYkc9JF49NnZOweeqWl5EvZVM/nZnNHN1CpmFLTcmFGbkh2/OFn2N9sy8ycpPbibqJZaT+feXn/IzcnL0F6pYz1/YfJl4xl34PNk/dcubasRc/MiVfUTsbwcFteN3yZXuFzcal5Foc2+C67ZDtlTOzzg9J5QQHt8F1+yOLLXJwOyf/U0/dhFZIXLIy2/9UO9GUHFm3XavIwticLLaRdVv2YHs5uMVhM8nxGqhbYkPiq9gmezJhaN32yebysbl0TU/ULUm2FGw29uDCnByuJ+qWJJuPvvbn8xq/6ZYUkXnYFkPZInZuYhdJnrlFKZrzPIbluLKd4s8WzAkbpTdwypyVijzHl/UYDXNY2XzsmZBZza5knahb/LrWpxNb/+3e2LUstMynn4ynW+wNpObTCQOlLlFnS1PLe3LlcLrlPYawYXnqNu14MlqzysI22CQg/8loWNgGi8mlErZwfR6ab4htqJiMfpnNx44k7lKHZoPbUDEZK1uQEqQdtoFiMl42oSsdGqbkODG5nGoNbT1gW44m2/5sC4LziNPBdVvqYbtzk5m0Z7/hY4yuJOENkkKOtFwnGSYml6rYLlM31xrbCDGZ8rpW11XlYxsgJpcDYsOPyaR3Iw+DDT4ml2NiA4/JJNkGwgYek8tRsUHHZJpsQ2FDjsmlCrbbuogP0kcaTkfllijbKf8Cq0XWViXw+trlILKd9mohdxRlOQmUOYZsmdi8/MEvmRdFg8bkUgdbEMcm9Xrv5RCy7cYmMrhJvrTWHEG23WNb6IoZZkymy7bbNt8XNEhuS21sKvQGDXB4y5BtX0guc3fMAIe3rJlPZsrdDiP3yAwuJk3u16x+90ZJZnAxuWOZwQ/EDCwmzb5vGvwozLBiUmBNzw/BDIqbkfm+D9IZUWThVLWW48j217pH7fa/1b42MqDhzYh/7/ADnltNAj/TFhlOTC6lvn7KraJmLbKqPy43U/wqPMm3nYq+LTEUbmY5sfDaElJDbEsMCSHGJGVD5EbZILlRNsS2hLJBtiWUDTEmKRskN8qGyI2yQXKjbIjcKBvkNICyIU4DKBtiTHLDBpIbqSFyY0RCcqNsiNwoGyQ3yoY4faNskNM3yoYYk5QNkhtlQ+RG2RC5cVkLkhupIXJjREJyo2yI3CgbJDfKhsiNsiFyY/MPyY3UELkxIiG5UTZEbpQNkhtlQ+RG2RC5sfmH5EZqiNwYkZDcKBsiN8oGyY2yIXKjbIjc2PxDciM1RG6MSEhulA2RG2VD5MZ+BJIbqSGCY0QicmNEQnIjNURujEhIcJQNkRtlQ+TGfqQ6N0YkZBlG5EFjkrIhxiRlQ4xJ9iOQupEaom6MyFb1h7IhlqNsB8M2ZD/y+VXQvgts1mp9+WO0tken9vTq9XVdjTFTl+TC41+j1VGpPRJ7Teq52r5y/emP0eaA7YhP4tWFdL/+FHOwdsS7PeV7waaPFJH7mP0XluvSHptTR6EmwOzObVqbdiQJui2E9nDBTHvZorAZMmvaVuZhA49IaWjVufksbNDUCjC7VmvZnBuZWiFoANiAqRWDVhebz8CGS60gNOOay+aGpFaQWfWexLrUlgSUWmloNVe5wrvZ42jUhKBpa9VqJrMqa3UzbMGtqdgQqYmJ9nM7UulGPcn7tZpxqAmuYK3PV0M1wfb2G6lhqIlBO8/rq+vRANu7iHwvGxi1/cy+uJzPdn1zSapjCy5ZNiBqwe+chX3XPF+7kLe/5MozgOCSRzZzuGh0s10/7PXbqq3ke2pvZQOJyP3MzpdUvNasIo5nVMUWXLpsy8jMtNbzvexsL6ViD9SoioPb1rczsBHp89tElX0fxFoNW3AZ1HqXzaeveKhV6fl8+c+64+aVaj2Jz6JmBvPsq6Nf995Ma+osbwWXRW36MxQ0O0nVWmXmtvkVtw4ku4EGtFnw+UeqArZtaJvHI90ozGSpTbb4JsAOaJNxgzC7tI2iz4izhZcl90C7ZkEYgdmFmppESxfdc/ObrfC2aKtSVvdxK97uhZDzOpXE5upBe/PzM1pr3exAWZnFq/Ms/qxhXWqLO0800/YcYIl1/XlW4tSmMpfJbyEzcbPILm6e3LsVc6G2TlMFbL5snqjYuX/zGyc/3wIfU6rM2w+Ez7l++HF+uNVXNz8tLQTre1mk1KtGXvw+cldvQ/j400sbaGvqJourMLRX2GaVPKBEfmeToX4F3UKRM6halXz5mc67VOFS/lYJJyWmPGweDlm5Me0Dtq/Tr96HcAoyAWKmTGzFmkn/++QNBrS32ArcG7LjjwlAmpUd094ccW1K7f1vyJfRzJUZ1KYKpfuhtvUb8hjMqqj2borbiNr2b8h3Ho1vTuwDczMyke37RiZ66qADbkYssnPBeV9lKFDTNA43I/qn+ParHz24dt/k6oRa3E/Ih5iVtnq4bseLrTJT9VK6D2rx6l8XAhrb9W2ZMg2QlQSnTenIvi7khBawqqw9Rh0HejoP0GjmaRxQqamXut2Qvwugvpfqs0XK/1r29siCu11G6Xm2ZuqwXj9S4dW3sUpd70UwAC1SJrEX8+gumT38eTbnNA/EUmkkswmzTPWZSjfCwTJ7uxWmi6aE6gGcVhN0mQbfqDk4dGi/udX5Rm3B4UObHo557+ntgcBpM7F2rQIwH0FNr4yO0BDRERogOg5qgEMd8xGQHKEhzgsIrSNw+vr60497UdiLj+OA019P9P7Z1HztJv5lePsfyzakh0FO25VXB0s5qgOi3MNiKZFVr/8DY4M+r+XQHNYAAAAASUVORK5CYII=","e":1},{"id":"image_11","w":212,"h":183,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANQAAAC3BAMAAACYkG3fAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAtUExURUdwTA8RJg4QJg8RJg8RJg8RJQ8RJg8RJg4RJg4QJQ4RJg8RJg8RJg4RJg8RJj488RwAAAAOdFJOUwD3693MErqmOSWPeWNOqMvMdQAACfdJREFUeNrdXP9vU9cVv4n94i+xKxwKJFCektCwNtuejNM2bceeAriI0unJZIXBpk2mKimTOitBWliZagWQOljXKEDXEbZWyappWqtZCYyuGlKUlJZVqIsITGLTRrT3bDk0hPM37Nz73ssX54vfs7n3h54f7BfHfp+ce8+3z7nHIQQlcJoIku/Hap66IQQppALAwz0ioLqgJibDNwQg+SB7mfxCMQQs4bB+CB9vQZQ7kqRO0Se/MsUdqhqetJQb5Q3lhQH2XGVBcpSzRh97DijTvKEmc9ZFJpvgDDWSty481kryk/F8gX3wkwl7AYnKe7POZsnsZnGG8uh2oG3XOYfcKhgq8DCO0aLNugpCki+UX3ncvpJ5R9yUHWelWVBeMmbY1qDWco+39hZpj3CGCss2QnqGd8BNZfssKN5akXPwnBUuHuNenMk5U62RJu45fxCaWaoar+MOFZThWyzy8q9kyKcArehcVXoff6xLAKuH0OzbBJS478twV4S1U7ktZ2ma7BOBtQezVUBOioCqhvvoxEJWkKQNQipzCRFQPsz81VbOv/0E3wJeW0WImR2DAOu4Qp3J2bXuODJWriUNrZ08OiWPSu4vwDUeSnIdCVPyGIQmovEtdWl5q2EmroRRMmFwhaqETqRbWNhkacXBlYb7YQYXr5NotYQ98/XiPqLVSWobJZFRziuYJDdzRKFrp/EtCgNwD1PyUCON75l7nNkqVrpaXQuFmshzJltIS04aO2ll7eFN7ORpUi03U618vIndBAamNGPHIeDcnamGeuJl+gSUIc4loZrHtM9cSuNLVwNbtmN4H2GlZ4ZvnXESDitNWHrStZvkGi4kbYqcyOE2UUpSsYqrUchRKaAOkHHqU577fLkqGvi5R0zO6uNKFjw61mb+WILIGACrjQRXKPp4c3fPCGL6ZZ6O5aVaYZxo9tIWjcbT2oNmlh/RX1NmLGos/SbWOp8zSA9oVQPygBmd1g3jRp3Bokn6SAbIzZUEH8U2vfBg2Ipicrku/a9YWnizCXIJkQDshtCFbfSntQ9EsXSttZDPqRtJKDIalPUX+m+B1YJ/QwGIILbxWvlIv9Ws1Ks9PpandpGBrXTvgAWOFxFk97/3HwHQy47EYQy2ZvXXe9+Lqf+TVsiaqWva7AOs/Yz+eBV3r9w19GYvYLqiUnEvhBZSvcX6+zX0t4AKVieFkvRvlgk1toEoeQtKUpIYEnVgNPIhNJJB0Gdd+ta869IkFSWTjImQh2YI1p03Iakyp/ZB06cAz8+98/fl8i+8u8807B/NoFYBzMge1iyUICszA5ndVRUOlVWyy1ima6yfMLm6Qx5iZz8qqzzRm76+4L1vQ7acgipEmeKL8DS1g2bFSAzTTitlJrhp8LUCm0vDhrKqJdzrgKb/gYTk5LXv+JUNTFXUMgO5Qh18cjmtcpPe49Ls3EL1sXq6N0dxA5dgQBfBKL1QDLGiTOrCjaH6pM3zLH+CpGD9Ev6ulrFdksKqidA22kXD/bHddN/Sf/8+uQyLT5mMIKhfxscTdqCTUsvEhosA3y65YDdPYsymlh15caeMpTOUPwV6qSzWC2afWKmnAC27zFeH4Znl7EiB7I1SHctsVmh19PjiqrmCAXn54853Sm4QhVVzqTJ3EW59SGaFYPtKJ+6fAPN499K13fSfyTrMw23ouHTrNGMFk0bPKClNBh/9oczOD3qbMB71kCrYSP16xQAU0BYHEgeCFXSGrVlvlKTphYa7dGL20G6ZRVeg2T3U4JPku2zq4r2kxNTbh5EqVYwSYzDc5d6D2zBEUB3GO31mmjrSFpKLdtCuguF6u7SodRqoDVSYuvgve61iY6V4dtD9YI1WT2njAAlGbqTtUDHmgOdXq4uyWdEFRM8NKVPvdq2VlDU2fM7BB99ZWA046fpMMadsgEOzJ8RheaOTT14C/bArqLOMyG3Xd5NKsAJsVRFTn/Nk46duoKz7xtEE7WU74XBgJqxB1k1l6JdZddTVxxq4ZrHitKeFppFzk//TrDU8OOqX6+287Lgv/T0F1rogXu3MGtIDPrufHwTnB52YUNY7N3kfja8k3VlpQ3nc9IoxoTg/JxpkWTCVHLcp6ZirnmAKYKtDvcKrz1F1UgOabvlVKufGggNIKrc62y/PhjA96FETcjOYc2iyu0N9P2I1O8I6HiWpPAnXhCCpsQTscztdR7FMZlnM1pPkHBw6mfPBqIfl3nbXJ0uSinz5Zw4iO+WJhjJdaSSQknbSVrj7FkUay/DWoh9Tk6xifeYMZpCggnlBK6XVjjYP2dcTxVNj+GBr3ySNT788lvA7C+uF8gbtqhivrgiWptzU10kytbZHR0uBItWsZ7P69XmvFKaYEapNMErUaAmxYoFcQ0sEffPHzFLeuv7jg4UzI8epwwZriX3kPVbGoMKbWyjYpp3xWIMcMWp6FnUDMQ1UGfvtyTB3saJQLmwHW/SnFxPUJGUjOfvoTynvWEn6uw22eAhBUmrpBoGesPhqucNa0n+64/FY5NklYjYtySpmJsyGDBpgGylffvf5kht+HKPDni/3WCTbA0OEm3jRunvX9ILO5pomeB5g0d1J10/mgZGETI5wFG0KnWrk7jDQeMH3aJ0S4BuZNf4jNUOYUzfyhPIC5ElmFebuHuTgUZ5QUgrvn663bD3JE4rs/xzjUb2l4QDhLRYU9ylcGjNWWf6c4A5FGySUEGe5I5Fe8zQuk+cP5TG7fykBw4Jh89sp2j3+UCTN2kbqRgFQVZD7TMAUs8Ve9Gevc5/NtttGKG0ioMg/ZdB5D7fPlnEd3ZznmBbYxpAoKK9VNwkQj4hxX1MqDVFIpF0gVParqJXnKwnl1YVBVekJUVDVAmozu10kLjBxH6SbT4yFJRHWcRIkWlQYlMUSREj6f8KgMl8Kg5qYFgZ1VlzCEhhvfXxn5+dLSFzNKSniHCt1XxjU8bwwKE8JZwclc+IBYWrJjwmDGp8SBlXBe05/XnkBTcLUSgukCIJYPl1BWcy39Fh6tL9JLKCalsV8fZPKRbfjIWUkLcX9NE+pcsvVaMNKUtTAAinzC9JlE5trkeeLlhiyvqt8pLA6NxS/0hIah8tF+sE2egJSvMY4Avqrha8d6D91h8qp/l87cPLbqNM6J8HAfxD0zX8+bb/1wK/++HJLYyQSkUHHx8bGlpb4zo6jxz648sWd03sXf3z/9ZfwnZsdLvRLAHoNvWU83hJrkGE5QeCW+Csf/qsv0J8g0vk717vjO2IN9Jj9J45j4fvzbh+p2RTviDPZ0RJrbIgsgo406vim2NwvHv6Ti319s3tHrBFvW7PpiVc+Lti1t7648sHRox0dVOXGxcA1j/7ctWdKB86fWmoz5sve8//9W/fLbJVRs6eOfXjlH5z/Axjq2r+XSP0LX/0//0sQTNgDQHUAAAAASUVORK5CYII=","e":1},{"id":"image_12","w":205,"h":179,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAM0AAACzCAMAAAAdSmjqAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAABLUExURUdwTPDCsfG5p+7Ov+7UxvDBsO/Lu/KzofG2pOu7rFo+X+7Vx/G7qu+6qVY6XFY7XFQ4W3xhd1tBYK6VmlQ5W/Ktmu3Vx1Q5W9e+t5KfY8YAAAAVdFJOUwCR1Enich377DrnuV20w0Qg64XnqMma+qUAAAWASURBVHja7ZzpcqwgEIVFQETRWRKYef8nveIy4jITxw266/aPVGpMUn7p7sMBhSiycb2Xj/J+iVDEJXvUUV7hs1zLRxcZeJxr9njgwSkfDzw4l8cwStA09xHNA7Sy/Y5pQNdaOaYBXWvZhAZyrU1hICdnJjeAk1PO0Pzi0TQbeMYb0KV2maO5YxI1ZI0DV6OvMxqd4XHRoEVtdsjBMvts4ooKB/QkZ4IDezFqjHOPMOHAXh0YrKrBLzU77vwiSk4NVOJJTs2ToVnEHfgcDLXm+BwUtfbSahzJuaBKzqvWhkKQGIpHCBJmTJ4gEQILU+HgEIIGxsAstokQ5A0MzOS8aq1NDjVdUNC1dhmkxhgCegxtVPoFYxjsMdTi9IVmTBJBb53coVHA/drFTQ1QVXNq7enSGOB+Td4GNDQCXmuD5BCoyXlmM7UGtXGUeba15uIAHXGs07y1tXaDPuLUtvmZyYbmCVwGmiGzbR231jhAmG7I7JTgBloGiBnhPCGPn+x188/bCAegVXMHzOZ9jwxwqTGHhjUe5wduqRE3OW3vwNXowTSg6p2Lk5y+1FQsRMyBNU4VP3biNio1GgttI5Vzf0CS6nIgrMmIxpqc7MdVNZnqLsQEh7eglpV490IJMzPJ6RxBXWo9zASHu9feJs8jTKMEnSPgSVQM7tfFkSMWe5mHBdP46d7fiNH9pn1ihJ4Jj+khMzCmcHVgesd8vsg+9Na5/nkUmWNvWH1/Q6SPLD6rbZbm1rsb1nAIrZy7LSLygcVjtb3aZtA/P2Un0Xpl+Km23qEN5eD5rmmCxpmTtP4zvSF8NM9c38jPNIvzdX7zzKrAPjAe0kPeszBDtsHY9JzLQ0cILh1nW2FOL7eRDDiVJ/QOMCeXG3tXaELHkxtbJ9jnpScxb3AY1zvBnDj2KPMGZ65pQh977ISAzdfZvnFKteXvfADZmeaM9NB3rmbv1JySHjLxz+yg1JyRnvbe+dFdc056pq65/k7Qg2iOTU9HIV849MDMHJ0e8hoqO2OTb5zV+EwPHXU/U/ZreizOccZ6dnpD9NFxULnRE2zAieWWe4E5qtymK7f6rDiCxx/NATzUI8zuPNNCywVcnny8ZmuoPBlnPx46XAxs3uLiZ+PsxTNdTWM0UqfT7MSTjy20yGXCtI/Y4Qkw641zS6MSJrSn2Ao0HWy4P5gaqFA7+hoRe4VpPFy8MkfEj0c7qOhoqDRVhlYAhUvTdBHhSiZrGyfVQYZI0ziu9EEVn8cl6a6kMVbo0KNYlhyWM8ZJ8DT6r2cEHQ1nafgwWi7SARJRKgDQqEWlRqvJDgCYPxqnm6/ZF4Eg0MRLRlD7jmABgUYvmX/aISoGQSP/XBuoYaIUBM1f87qk3TYkQNAs3U0HgyZeSAOj0vRCGhgqoBd6ahgKrRfOtalGIWqwGqdYSCMFJlEDghOhwln+0FSmaEQt+muDACxv0/o2EscFAlFzMoRB1Pr+QSFqr0Dg1IDQSFQ0FBWNQkXz/SPfkC0OQUXz/fAZsr+JUdGkX9MEveTxNU3QSx5fm4GgH7NJTCb6ezMQ9IO2r81AEjINRyXRBJVEF6gk+v/KACZrE7SLjlCJWoRK1L5ftSGoaEJ+7UaiapwVNBwVTcAavYYmXFVbcx5iuI/cV72fn6KiCfah7rq9E6HirNwJEijO2n0tYeKs3qUTJM76PUch4mzYQRUgzpaDq8PD2XQMd3A42w4VDw1n4xHpgb0btfkUbi4w0YSUnnSPc6gDeXVtty38AfDselwE97z3ePejSSQp4jhN7TGEoorU7saMCxukCs65UpRKmVQRRUkipaRKqepze7n+udj+fvrVOYZ2zyfxe8z5klU7WYHWkA1ixVhDNv+m5v9E1ATjH6aTkLYQfrGnAAAAAElFTkSuQmCC","e":1},{"id":"image_13","w":109,"h":142,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAG0AAACOBAMAAADJBptJAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAtUExURUdwTA8RJg8RJg8RJg8RJg4RJg8RJg8RJg4RJQ4SJg4QJg8RJg8RJg8RJg8RJstyczcAAAAOdFJOUwD15b3SPY8ZKQxlealSXZwvWAAABI9JREFUWMOdWM1rE2kYn7ZJkzSm2C12a8Wh9XNdYVBPu4cNxcPqggyxN0FKi/dQxY9bibp4EA0RQVBY2e5pRShVvOyl+LEXDw1VD96K7yStouX5G5ypWpN5n6/Je5rO9Jf3eZ/P3+91HPW6+fCtk3zde+6CObGcFHbHg2gFC8lgfSHM7BoIgacS4Z6B+f2t89eZ0NaZBLAegN82Hi48g08JcHU4+PUpexim1LBeCErfngvemhr3CvZ+/2MC/lbCcr5piVvWG1ab2WbaSe0Jr8B465952Kb0pmlPL7+pgmXdRvuLs1DS4LbE7eqBQxrcufi/ZdztGlzZxM3yVzU4vxF/s7Kuit7O+Kv+QIFLtUcvWt2gwFVhwTZBUYTloBZ/lQZFn3GRulFkaB+WjYrAI24JceMi7iwgrQ9GFdnidITzsKKBrRKsAKsd4VKoSTKuinYvGVdEU1j0S8H9iOLGOzpeWsyXRbQF5eGp0Mq8Bt6pFqRWhjquW2qEc/gPdwl1m/PwRtJvJDN3ou/vNyUzcX/X+dGZ8Zr4+d1VgQ38jEcHDggl+x/xe2zYCx7Rzrv48J2HY/iHeb7NFw3RXb1P/DwZIr7wVUsFT3BL2mvW8C+zLLU738qR2s/d4FK6aAg6lYWPbEoPkVk0zjJHalStcMXe65KH8LmoT5MdqwBMEeXdJuXrbi7qj6jUjDrjVCfbOW7ApdgxOj5r3HYV6tssM1KY0zk+zcrzbkCeLg1NZjuaXnbT3DrvGvJ0YZKRtVeEnxh28QPxm9k5oGMXVxItMB/Mr/R2twxeQxdDeTjCsgQsCrknoRJtljgShHXi3OFIwHJiqwtxWSayEcwCLx+tz6fdSC7vq7DjF6wmcDvaa9+MRGbiyRKqVhMsSZxr3jrFn2AGH4iy0+pVOQ8GZWbfY5mZgqAiC4JJq7MUVYLOIjO90FDJx2HLgP0K3GzczFCeVzoxM6+6qkhbZp5TeaXLys2y6kplMbCCrjEzB+8tobZVFYUpK3001xRVYws1za2B/8GujpriPsv2ed2oksXOA01yFi2fZ1gas2nmqJ0/HzRmztgtX3EpUl9XKq44JXuH5KusxVPIcO6XNNlGYSOaRU6zHCY6J+VrO9QFi/KdSBEq2IyR0jqPUtg6SE3pMtpHZJyPNvOyhNsCO3A+WZHEIxrgeQGXJfTHpODPFKFxqwKubqaI0mJxeZcQj/d53En4g6BcLC7jByVqai+zM32EzD6uHspkdaa5+uujZVKG6xMT9ATPMOK//YI97rFhxis7mKOvMryR6VkrazUyV7jRUSX5OyOvuFuKgheU2Hp+SQVhhL3VIQZS2uPJNjU4J7ggfNFKpU62CytpO7rdkNAfCxj9lLeL2LVdSq+l020c8Ec7dkYcU2H6Wpr8H+LqrD2CXrwGQ2ksb+c4j+OemYaDCvLl9LjtG4byZVkBczJFaJXsKRAuADfX1VZ5WnBBRfCjEE4D/DLzLeIAxx3l6hsDs/vf6OmNII1j68ZYKBz3HD0Syc51J8G69j98WWaw5iRa11+MDbgDe5ac5OvupZxys8/PMuf7sOzAxgAAAABJRU5ErkJggg==","e":1},{"id":"image_14","w":105,"h":138,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGkAAACKBAMAAABbfHklAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAYUExURUdwTPK1o/Kyn/Kum/Kum/Kum/KvnfKtmiQgcRMAAAAHdFJOUwBXkd65Hj6xrfX2AAACYElEQVRYw52ZzUsDMRDF09qP64KHXgWRXsWivRZE9lqo0muxh73uR3X+fSti2W6SmTdvzvtjXl6SySQbAhj3IvIUnLGU3zgdXNBC/qLbOqCR/EdDpDrHG5HqrPFApDo7QqQS2YDU/IpqXXN1iTtCoMgXIRC1YyBQBKKGkBQANI6oDTEskUeA2kdUDVBlRDWMGYj1sRnSMWYgE7ZPUFvCDJEDYQZAjSlqTlEpM2w3SopKQUKZIZQZnXv3Q1RS4IkaVusp8Jf4ZgRae3lMUQuKSkNGoc8INOphRqBxFGUgoQS2lMDac0Riw5pTw1oyw8oKrBkv1GFlUwmVqqVS1Yzt6rBytqv1KS+wYbzQOpR8KqFStVSqDWGgJrASwsGZMAKVVB1jhVIIF0qq7Cl+q6TKVepZKW6BHzqU3CSjVzEi0ZHP1haUamlKE4pna2pDifW+s6F4EU7XABU1DEcAimraOwINFzykL5rkCQQNJ7nCKErgiRLYUAK/vCswsbtmGDQwHhzWwHhwWIPdBQ6rwzqz61i2cNXs7ZKqIcy429fgaX+1Bm82aIXub+PJAT3i+jM8CX7Kc5wqR2TpXrgotWWoxBm+dhcnkAoM1TguI/oRSQkMlMDgLdSYG+mO0KJq/AHDfMArCS9MqnC3q0p3vCS8sKjC30Uq3fGeSRVuCC/yN3D9hjZiBIYpc1PQlm/BXAbVh5aKSZU99vQ3nVwbZbyMV8zzUUai9QiflGi/cO+IVMn+C3lML6lfCzsmVewHkiq6BqC/xo7YrVPTWAQ0eoY8O37dXTS+uH4ufq5+mdUD8u0Pn8J8VklX1HsAAAAASUVORK5CYII=","e":1},{"id":"image_15","w":228,"h":183,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOQAAAC3BAMAAADwY+/nAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAwUExURUdwTA4QJg8RJg8RJg8RJg8RJg8QJQ4RJg8QJg8RJQ8RJg8QJQ8QJg8RJQ8RJg8RJlax668AAAAPdFJOUwD68eTWxw20hx2fb1kxRNgG8IoAAAuiSURBVHja7Vx7cFTVGb9C9pV9wOYBCLTXXRLCQ3sJCYL4WIKodACXBEEswgbKozBUCYGCWthIoK0WyIJ0YGjFJPgYGZgQHqIzVZIIQunYhjAtaO2YQLUdOp3MvZsMiLRfz2OfYXez99zc85fnj917k3vv737n+77f97jnriDwGgfe3zB37qZybnjGf60bL4LszAnwArwwRwTIKn6xTKrlg/i3SiRg3sYPywWH9xsegPZtLlAmbKcz2tnFAfFKGcgTdlCr+WdgF+ivxZMS5B0OmaltkdAfqnRGtJWBMr89vLetVTDBPfoiXpYgZ2dkb8WCgGCF/+qKeEaEgvaoxI+9JwgW+FZPxOMgT4ohm4MP4U/phr6Ii2J381vxl1dHL/lKVF6I2T3rpHsNim6IeyX57bgbGEPnuFPWi2XNHvnduBsIHqVbA6BdH0RHKcTqcZVHXhjavAuO6gNZDWPjRIYHw9t60c9lsTvGO6wlMCaiQAPoEr5sHrkpDjGGEMwwWw/Ieng4Br8UcmNuwKYL5F4xhmGspZATazB2cYoO1uqVj8bOahwighzXJyhftMbsXIWRke2f9EQULFKfQJ51PxujLCnKop97eiIKRmlknzCNM6s2RsjI9jkJcns6vtHTF5DHsj86VRCZOM/N8NZWFC6b7jjaM1o7oqVkk2A8FpYmA0IotkqAyQn4tC8gM7vRdJnWhPb8oai/vwTk6YmqAW8fQLY8gj5Mj4dkk6vCaszenPDwvoAsxeay7H66s5iwgBGpMf8VQS9IRx6m7KUhb/NibrEfBHlysrDo1W6xGSRM7aaQ1iyEb1sLyoKkRZ3vfs2QzYSmL1LmbBtGGCeJGimkdo4tJe7RQOPD6VrBUgF5r6Q43ve45tiYQzVEnaSzSbCs+1HK7MY/SyukgfihTaQEsBghG1OfoB2ymZQ1hiA2l9Wv1vd+vTrNkD5C4v1uoAp5W6Fz4s5eT6B1gpYS2UkSqTduYkNVZqRxxtaxWlVJg+Mbw21eyHkvrXzz+xohl9wmX18OqoPB6aXh9Voha2hR/GUBdDWld4Z3uEZID/XHxaL8QppnSMM0Wg+0hnLw8IUsn/RCHaBRysxQtdhPoYq0ny8Th6Y+A+7TBtm/m3430Fu/XDRizoTUpZUBNNL6RWqwDtqa2+LMLwpYUivrea1lUM2g0PxiQngNJgm+NUKjnMpbOhX2ktbxy7lfCz4amV+7RfLwUYLQMVIwQSrP87F3RPaVANxolWhy1XE3ZoUstLMLbXmV5O0AB/yAFfE3IjhBXijRfKMDp1AV2ehjV7CgvX+KptkeZlVmivL8z7ZKwTkhK0KyGUvw7HZkO8cKnqS9HaOfue3jxfNjqYT8kFtiK/JjFdYsrHa3L4E1Sc5bBY+ogfnp+UOHtlOyWQKk8LB6ZHptw//Qjoi3S6tsrnF26WaSWsKrNKUPaDw1XsT98RnluGCjRat9LXQRZTqQGbYp+HbGtwrVt4WLSejgY1ARLI3VCI+MMa2IQW6HEAFoVpqFijicBNknoLr9BiqVv5ewKpQUFU2fE0jAxw4dmoqAc5s6qRDHAUYASXoETy0lskzkmrYgEjmYKAaUqhFyhQgTSYhYXSlCro8wq1WSZwh+KuafR/uJMy5F17Qj9rEUJuh7HIeu9JnH6oVIZ/UkEnQg3rgET+LAQKy+XxYVoAUbsvIM+ued8eSr9GMqukg9FEQJ5awI5HoNowiBkT6OrVAhPORDO3YFldQ2V08x90qIgtOnGikuyzgBMpLP8nQrrZpvkYSYhA+bCwHbvp0aiFQMkbFfgtzW9IUs7DEj9YBkcoTuwkMcxk9UuieIwAzfdBy1H+9hP/skCKpwyWvimJ7NJMgNRFuPo8P1lM07BPPEwIyNpT3aZvtEkFWQqy3Svo1SrBQlLruEBfKPxH5KLnv6ifEA98YdfwVAfkYF0b0MsxLQSDBs79WAg0ONcuS5g9Q+PIggJsWGL+N1JOMmVUFj8J0VscUXFvMvoIjDcVCS3SKxD7MypzhcX74eWFm+/MBWgOAHatjcT82/xzBBVyDUI1zoR0aDmEV2k8bD7iFRnUvB9XnrXXEPaNIYpmiPOj6hoAZyDUYJP8axyv7HX1eQe4s2zNBUIB26xKyXylVFxoZg4jtcCjdINEKmbxWJU1pc+EiDsyoceiSYXAjgnNCkChBp8oEkzurBTSWz+CSee+yOglXGwvhoIS88h8IMuql//+ojteF/S9LUqQU7gmFygERs7ByZMrYmJwkt59e5ALpaBYZhlZImiGYRyfZbckNmkkZa4W2UJ2SJxdOK3MhklOlMiEKLnDym+qMMQ/Iri5j7fqnylkQCedYTOxjTY0+KRHcpJXSSgpOYvVZ0yjMteRuKRri3f8aayO1J9YTBIcnRJixm9ZUH3dPLhVKky2PlrIhGX1cgxb8bIWzNdpEIbPwPlhXBNTPXHctSZ52Z0B0hBiUi11QE13yUFdLfS9bplasi1B9hxamIYJurGBFNYi8J2dVwRXwJYFz4jyW1GqSsU3q5WbPYHTIkEO+OTM1sdl2axCG9dtPofDZD0BcpCRpR2dUYYDPXCrlXjbSRatEmwuzmSK6zBN3oWlZzHdXrMWYR085ulGRm0CeWyG4NSru5mAnR4lPSMDsysz5k2OZIo8MhFZctYiuT06of2uBhweGehxsF1H6W44TQyWSwdm9aaacZxcS9vyA+SvhnCf7sZFsGcg3S69R6lXbK4DVBQnxO5B4DmB6+oNw1PddqDhP/YpwTnFYakUoH3MMCmSh3TdIfGx5O2qtQanZkGfKafiyQJuhO05kdIQJCHD/F6LsVyED5wV3jGBzEI/8sbeoPLSFwwMA6mGfsh1j3eQbIq2mwQPTYKaE+qwIorb+IYnXNbNWIKJFqUqGDYZQeQRmKyOdlBOdVH7oqYKEKB6YP2LcAbVTUTRGsTtVxJAMGq0ld/DgD+hjkStITbbw3cTekN9tRNTFtSJn7RZhkIh56SS4Sb6mFbIOxKh1qmHDGPTlgJYlBJsph1T4ttKmxHTIrSJmWP5WjE4npVroK1MbnBvih2qSMeqZNpL7x94Bq2+lW78WzaVBha+4i21F9ooHmebvlJibIY6D+8ZCNmKjRE2SqCkyiwlCheYNE1iEsiEYvzGM4rQavRKlhW5PVAkNZTtuN0BAvs1SwK9S6ZMR+sqd5YhelpW8GpSr6pfE5F5BWhHpF1ifp8KTBPwBqmuaRcUJNv7RnmneY5dSTYpC5Dq1hcS3LVlF5lxVR6GBYgLq6EpTNzIgooVyj6vh/bD77ViFkH2FHRF6iLqdb5RIB8j/RgIi8ZJDKE9x5C8q1IKL8Wdf17wldWurmDYkckztkA2N41jBOq/SSPhht8ABvyAzgbrJm4G6ydk+Qu8lWKAHekC1yO2/IS3q9P5F8LNX99a0EFV8tb8hMfd6fSO2YU3hDWlXmBd9BfgcZZ7Hj+Psldycx8M9E+vMnvGb+wcvH1oHRUiFIt/hbz328Ieu4W49V6uKtymPsi15ZqUdkasFomVaPiscqfTKuS8BXSEs1AMziiWguxMvReCJ+jlfaTOLoIK8fxMvBnuUHuPICFnEMxwhyoAJ3YWfyAzRekUSArh0cEc/ixdYFf+CIeAZP6vy/ckRsQYDBwzxL9WY8qR9y9EbLcYQ442uOIh44idyf56Qaz51DatzJc1K3dHuh6wOOk2qvoK898Bv4daAgR8IRjNcRYi5PSxUueCDmhzJ4DMyqD/JEJC/IcEW8jlfcP8QR0VaJJlWeyc//jadwFpfD0TmulOGcajo//1/9pqSLiJZk//jdmy4EqMzva7uxbL88MdGiffv5Sgwo5/c9i1tdbvwzbp/GGuTKL159qpC8vpb3cz0Mdf94fG3niOK5Gw6h8c76px51h96Wy96ol9mUhd/Hixty8Us62ukV/CuAcXBZxRs/1ZtEz78z99EiNx5F055+8ffcctTleOiO8n+z4rmlve2p1wAAAABJRU5ErkJggg==","e":1},{"id":"image_16","w":227,"h":179,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOMAAACzCAMAAABM3luJAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAABRUExURUdwTO7Vx1M5WlQ4W+/DsvKwnfC/ruy/sfG1pPKxn+y8rVQ5W+/Mve7Ds1Q5W1Q5W+3TxOrIulg9Xlk+XnledZV7iZl/jPKtmlQ5W+3Vx+m2p5//mwwAAAAXdFJOUwDg4CBp/pI85PkQRiDDn8Gl/fdo9viItUfLvQAABhJJREFUeNrtndGaqjoMhQVaaKEFFN0F3/9Bj8wotgiKQNs0c3Kpc/N/K1lJQ3EOB3SRNGVZxW1clWVyQIlXtVqU+PjidhQnRHx58cr3Ew0WwqY8tTNRYQfsowgesHgPGL7r5EXVfowTbglDd50lEoadrMsJQ3XWbwjbNkZPeIvgZtbkW8LwOmQSf40YmrEWKxBPJepKDK55JOsIQ2JcU4mBMa5HDGYI2IAYCmOxATEMxtVuA2yYE2nURanYO08hMYqo6yMS+yNCOSXfEbtO7o/YtrAQuy7bHxEGoxwQu3T0VbUdsc0BIGZPxC4aNY0dEEEcIOUs4x6ZCoJRl3GUq3tkKohDsi5jR3bPVAiMhoyd0SBLLIyGjGY5xvswNrBkrA3HaZEw1t1cOSYlEsbcQOyGz5typ0QFwEimUnXp45pAlh3yNVWLqt03KkiO020/EAM8QJqO05E8iXdH9JyrI8e5xWl/RM+eQ8aIUWaBMYGUqjdEC6kaw0rVfybitW7KWzXFIZfjOFXP5q7pcm+YG32oAJWqejGerz8f5ZshPXfHyESUA0rTXo0BdgukDxnzVHIuf/Zv42ocsrQeH7bWQ3qQMWNU9cHJy5DTDRzlE/E2FmyCjN03DsLVI1hG5nR8ftGPs7VYD+keMWNKCzruHJfBbzQdhycERRiIXBlxnWaMs3Y8Goh1SzrviJSoo4nyQIxMGYeNZAwG8eabjHFOKeeMyTSfU/E1XX911BA7aZydvyxJa4jk7ptPDEYmEX//jOot8ng2i3FAfDzO+grSFqJpKoOD9pRUTQZ9mVcv2upjvJL8ArJK3JjKIBlLazUXhrn8a0/HCR2Hfd1SyLiw3/zUVGIugOzOx246Hvs6vyIy9TZmObmxmdNETSce9jQ+Rcy4Uishdeky7bwcvQq55BJLlTjPU02wuc+jidwcI6YL3wOorInI1KaYKEJiIh6LZsli2Rrhgjz9FGNCQ8Tj5bxoXXcqiwMExM9tMqpJvWYfWdk8DIsvVRSTA49Ri3U6eR7xRXgQx+8Qp5WkZknqSp7Fx2ZR2l1obK/FqaFOY2QzwjVFckhuTlQ2tk9QeyGOvPW5CZi0m1PpcBO1CpF+HneebbGLGp+Ae6poQEZGCzEs51w63iXuiji2HXM9cDqfL5eLzJxv2ZjaNa7TjORRnKmHy31ki2gLR7reY+upO1gBZCpdLmQ9d7c1tGJ8I2RUT90zCwKRfhwExmdKDCrO244Xxj0Q6cQH9A1iFKKKdLG1vt4XDDNR6ZuK/F1hIajF+WHnZ6SrsSBOu05EHHdHu4gzyRpNvMETzBy+2HUEGhXNZI0yH72RWEfUkjUSz+utnp7n24pHskqh3cTCk6daska/Pup4xnGESKn2tieZfS8y1FJ8FmR9t9Ha5RznphTvuUqGpcbca5EB5+ndcp57m7qbfU85YER1vGqMIsKIeBt9qLac6iFdIBKXiH3oLirqWmBym2FjjmNx8z7+ACLDj8idLouJD0TlcufvwW1cZ6qXPHWbqX7yVDGBPU9dInoSUXGBXEQq0YvocNdPPFWiciVinvoidNX6M3lV/sJyrgohMlIzn4TW55tUfbi7j+DUyBWEsDrEZSAQ7RYkgcHIbJcjgKA278NJhT9ZmcKfrFzhT1al0CergILIGfb2aHXUIWAYVY68PVo9XzGF3nRyOIhKorcce1MA+QOMgCzHWvOQgBgpflu19gRZ4dcRUuuwVY+gGNn/jCgY5R9gTPEz2lp25PjLEVJ/tHelg4NhtPcEkqHPVDiMNi8fMfyIQM5Wdq+QSfyIIPYAzPJFQP+M3Pq1Fd+MlNm/zZn6BXTyayoeGZmrn4sh3iR0d3Gc4JbQ17MAlxL6YWTuf7RJ4JbQ9SGZstTTP9VkeHPU7VDuKUcdDgE+JXTD6FdCB0MABUBotUFy70lqeYvM0uwAJhjSIrRsOsAILZgOOMLdTQcg4b6mQ0ES7mg6FEqrsGU6kAF3MR3ggNtNh4MH3PaclYKaZiwcIWkQAm4oSB4SYL+3Yt9kK73hkaD4Hr6TSinZb/A+KO1/oJj2/ziOc8Z/vpBMyvDw/gPUxIjoNXkP8gAAAABJRU5ErkJggg==","e":1},{"id":"image_17","w":132,"h":133,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIQAAACFBAMAAABoNk0xAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAtUExURUdwTA8RJg4RJg8RJQ4RJg8QJg4RJQ8RJg4RJQ4QJg8RJQ8RJg4QJQ8QJg8RJkDSbW4AAAAOdFJOUwD16RIp2z/Mv2tVqpeC7EG9fwAABL5JREFUaN6lWt9rHFUUnnTGSXbThdSiba1eGqxCqwzrjzXVqmwralRaLNUHKw5hpVAohAZF8MGhYhFBXGr98SQhFgKiuBh88KGwKPSlL6Ep5DV4h0w36Y/vb3CyKXWTPefec6f3aWdmOXPPvd/9vu+cXc9bH8+8+dOlK3XvHoafIB87J4pHCObRHSvVwiGuAfr+xyJgd9EY49jxY57Mc1PArmIRwjjrLoL/bAycLRTiJI7f+VSKkRVJJYjTu58PAo8WCDGEkf8vLqJTIMS87oGUH+MP98WMVnsvB3GrQB5vb7hu6vOuIX7GxqNRw17XEM3O5sRcFzSIljfdWcLfbiEqONO3OLtcV7PeB7XMjTi26D5Ef+t4UA7pvlcO47ZTiMn+Wfhx6kRfrZSCyhmXENNEiK24ea8hHEHeSgmOOewE8lZKgKCkXEB+NJ2hOMQF5ANk2oN4yAWd1PsClcppeJBG8/QmIjKNrdhDnz45/4VqhLwfYUYcI1kmbz+F7eIQS6vk7bKDoBzNGHmRQ2MANEcNy6GxhZOvRMwaw6C3xBvDO9JdxQ3OdnSkCGWl5yI+EoZog3lZSa1IGQNXmScL+EK6JSOc0inpamDVY6fxsSxErKvsNDIZNiZ5AbyAE0LWWeYelSOZHJQNfH0Sso1NwC58kOBxmd3iifIg9FWRTVnmH/6DjsCxhFHGPywp7BNMYw4TJpevBfz1NIvxNcfSlKRSUTeNTyWpxDA9nZWk0jDqn98WpFLhT+s6fvGeHaDayAxjglRqFpO3gI7t2AcWuxpG9l1Z0pZDoPSf1nNiMd6LsDGYryyeJPgcD9Rt9Gd5yQsKnRkLNPZadw3pTDFh7ClUoL80feFluyf5LQKy701E/qC9GPxBATv5IJDY1XAuz+YDtq7AWYmEns6zSc9zLlZYkx05Bn2OYTgltUaLYJSyJi+oTila9AMNcUE1DlptpznrRuLsFn1cIa61cwYhz7YyCUpfKuSJOORg3sM2SZalyKGuG6c3MMF1+TRi0m4OQbu0gbaTfRmHvtbztIuac6hQc6GkWOw+lcrbMIdpKY4c2jCMFM86VKh+nNHA1fIKtUUrx5JD86JGZz3kAPIKfaZcWp6cIWjI+1o+Y98rSr6gnDtqyxe0xVDloLyV/SoDxCAWI/RFuoOytqBSNShxbY7c/QvJK1Q3WI/4iBAY0W22nSDs8gUJm3IT+4UhVni/ImuABEmHZwJZZRjEmQEzoj50qDJDeFEfxti7aoimUTJV07lyC6ZhbhM3IOg8HDBySz4N+6bUzBrcsFnurpv416Lc++yUM2LhE2vXYN5S0/kJHrbJmc0jHoBFD0LARpFti7UfRmZFjjLbjUmBhl+AkQKVwNDkG2to0pUgaZePwfCiAYhoeh44xz/TElIpK6QMwHwIHdHr4LoGuevfI9OKBWB3nT4gmJCFyHcFT1TJPMRGJAcYnqwStbGD5z+FfB4TfQ7Hju6e8Us+jx3fbUyv6fij/FujeZH8fn2D/3b9Ffr01Nr/Gr758M7la4t8ycyOX+e6f4749BXPf+OvY3li0iZ5z8y9WdUNsm10m1779IlXYJSncHekl71i46V3R9cDfFb1Co/g90tffX2lFyP/AQ0AJOmayh70AAAAAElFTkSuQmCC","e":1},{"id":"image_18","w":128,"h":130,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACCBAMAAAB82N3zAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAbUExURUdwTPKvnfG6qfKxnvG5qPKum/KvnPOvnfKtmpAHqr8AAAAIdFJOUwD5Pedsu40ZNqw1mwAAArhJREFUaN61mr1vE0EQxRef7WvjGFtbOqJxCThOtnSEkFyGCIkrLSKBS4cCaC+Ow/zZ5CD447xzM7NPTBEpUu6n997O7t3uxrmqWkui3uSjS64PROR7dJ76fIee620iYPkPUM7SALSt9Sjl+WwHoFPIQWUiQUJO+/Uac0D0YAf8PADYPeT+AGCP8dBBgoSiBjDHWH/eGmP7CGD00DkCGGPcZljuJgQ0CFXNUMApmIHNQ5dAD1GAxcNdDGBphWUMYGnnIgp4QAEGD3ELhhjnccAaGwVLK2QEeugyAH2MHpVQEBjjmMAYuRTVHlqExhhQCWNUAhuCVgIbglpCQCWMUQkdQiV4VMKcl/BSBXjBA3Rfv60GgM5EINDEmEATGYEmmkLQmSgINHHXCFDsQzqNAM0+JBAYw7gZIMfQFQDyWHoCTUgeRBMZgSbaEkA0EUTCORgC0fQz0Iyyi9zLgF8pH3z7NZlMv2IenkZzOkI8VIT+DUe4Il31LrheCkoCDVZxwrf3WsIwuZ+FqZWrAeV16oTYJvnJ+p6uV38hn2YIQ5Hejc8Vi6E9RyVkBkD0hdXyBsJJTMKZAbABmrHkX7rKXvLsDlnpYV39eEQm1B8JI9TD5X/xoG2F6s9KB0gI7N5QGWOfm1DaGDeePStReii46aCNsQLcO0BC4MZRK6HkAbrFteRmtGVh4gDqhYkDqBcmFqCVMHSghHsHSjhxoISGc0OdhKaDR5WEawdKaAKoJCwcKKF5EyFLKIUdsbi2SSd2bQ8CRBNDcVsvSLh0mIRyIZ8shKTVQJuj6gi+wUS5Up0R8SYelTdRvv5ZYb1EeLXfOSHl7Pqq/n1nOWfjY7BcEUe3Y6ZL6vz26PkL463iO+s0EgiDhOvp72HXBptVAuApCP/lb5qDpBv2ajxn+e2bXh/4R4Wqfhz89htIIdE27w88zwAAAABJRU5ErkJggg==","e":1},{"id":"image_19","w":195,"h":244,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMMAAAD0BAMAAADULo+MAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAtUExURUdwTA8RJg8QJg8RJg4RJg4QJQ8QJg8RJg8RJg4RJg8RJg8RJg4RJg8RJQ8RJrjguTIAAAAOdFJOUwD37ODPDnq9H2CTqUYy5vGncQAACTRJREFUeNq1XO9vFNUankt39kd3N6GFC2LLiRUU9d5OqIZI/DFBjEZQJxVosJGYYvlwc6829d6IwR8bWjVoooaiRo2xQcH4yQY0Ek20KaDBaCSFGz94ic2d3b2tlHvfv+Ge2c7utjPnnCFznplP7W6y75znfd/nfd73nBnDWHS9/v77P/caiV19l3oYEbWt//pgQha+66L6tf4viVh4jBZd5QMJoJXmGLU/9+GrfY/+eryHyN2OB6tElemmvXuI7pgGW0iRO7Do3+wgo1vAWDm0bekH/7JpJXQdGeoIYp97mtYgTUy6R0OfZU/SMM5CTnjDplPBueO8KwzRXXQDyoJpLRd+nrXKqOxoIckvHaHLIBNDVckXeUaHMSas32UI9tBaUDxtlH01ShWQKwZkXxUsTG484srjZhzj8BkFGGmCxO3EnCJlJmgLolTMKr48RKsAJmwVoxYYAim700gaKVuZXiOImFKb4DGlT+lOp5qG6YR+RClN8Oy7Rr+qzkaIkzn91Lui/DpLpB22e1caEUht1DVxuj1K7WqH7c42NRBFy9XWaW0DEYWXjmqaaO2KoIhD9EdNE4WuzqjKqx22W69E6KxJV1eI7Ivi6xlttt3FIty5m2Z1/W1vivAWK2vLwfnINk2XbUcrEc4YoeWaJvJRN5mnK7qZYXVHtQeuLtuWonJrSNsZF92BKN3brRu2tDlquKDrDNOJQspxdbvwM1FIjWl3Aa2sO2qC0amtdCKAyDFtQn+ZVvdFOGNK00TRdu9O2BnGWVJDldJvXvcwekAtn3Uzw2uAq8pl2Pq9jOmolzEEUOi7qKrqJHYC5jp8GVuUPDavbYLf55yyZgCGFUWbrlP1ITSgb+MMVVVFRb8J8IhIdaMZyMjzI/qvSk1VASbyyvmTPhPWUliVX+OQ4dRuVfC3ANpjHvwlRYVFMGFNWv5Zbt8GzCo8mlBMsSe0m75aI+8ofDqKSD7DeEnh8Lx2K+NnuLyxwySfB/hmhRQ6jDCRUVD6GGTeaWRtedwANKF/q53y5JuDmFClhq3dLfmMKufCCYAMWcgw6YR5B90EMZFm5ekkZciCEJDFZtHC7JlwtTOfqAypkUhZVkJPY5hQhVQGtQ+XkiKVAzGhNx2aSlSG1FJsi7QHGE4aqRbQbqICKZAMUSFlwraP5UhhZIgSqYuo5JNnXwYjQ2qRM5+sDKkhNS1LvsNJIwVLPo7UtUn2AD6jT0sqHyr5pEjx5OsFmZDWPlTlUyB1GiM7F+52OFHZWUNKnMc5kOxcQEpMqjbsrI40pmBkK0dqBEa20pjKAM+YSWIKMHqORArVZiiQAvrbKImRGsX5mzf6s0n7Oy3OPqS/ZUgB85sjtSppf6eZcHMU6W8JUkh/8/tdk7S/OVK9CftbgtQErH7XZPKapP2dFk5dMrj6bUhOBeRwek2KlA3Ta1KkoP4Wz6cu4PSaDKkUqjn2pbgAKay/xUjZFaSJM6IkmESde/aRqor8PYxF6mjC/uYdRbcgXeaRJvICuW9aUH+btmCLadJF+tsYo01J+zsjSLQUaPLsX1krPBIE+9sYErCeVYWaEI3AJlHDzoWrIJjXnQbtNDRL0HB4ZTdATbSExW0aNl+r679Q0TBtrL85eZ9I2N9cnK0N5zfW34INtxRSEtaKRogKc7CHihqwbAz5ew5rIh9O8Anto37Bew71+ReBLZ9PhcMhjgf7Ozywy2EfGxROy9H+5tk8EPL3QQOc4EHoR6AtgCHaxIXnd7gVzqlOO8XUOkHeY1fAJjIh4Vkqg00UrGCQzkBbAGERaoG2fN71UvAXW2FbMs26FGCMLJs10GEb5BCngjYxHkzncXDJ8NI50AXsQJcMzrbzwVqIphAj+ER2gaFDyngzCIwzb8CdEeiNhuAhVQwS3w50VfKIbzrg7xN4Z5wI5Pd1aBOZICuV0FWJV6EAoc9U4SaGAv5N4f29LEDoWTiFGAX6X6BOLYcjFST0R+Alg4ft0nqdcw182C51hulswodtAJmZCjymJgKiMK1+ciNe2C7lELNURS8jF2zBL9Fd8LANEHrRqYCbAGMkIDvMPHXAwzZYI/YqjsDHDNu1IUENrkxmWBNkyIW6o+gEdpJM7wmwCrIPyFoCAn+L5qaAQDFLcD7rHOv4DOjuW0UDtf4e9yGYCepmot3Js4xu7EWtYvlJwTKy1rcO3QIzkWLhCcuFysGcRddi1sH+nT0Z2r7Ielazn9Pt7yFMWP/hjeQq8UAkY7XfD+B2+3J4rlP0u5t/brdowzv6jcys93jtUhYZ800ObU73UHm/bgtYmq+x68NLqqsfxs4WI7uP0YpTv+hVb0/XFmx3uFn4mN/K5No8bvmgh6j9/u91dG1NrR0i90X/dz+nOpnvWpAj/U4bUfmF+CbOLwxwniDygsd8m5FbFyElP9AeX/PpVuY+HNvEH3wB+DG5K5/a8zRR5at608T81bx52TD3MTe2pG68m2uQ338XudsbGX1ytf/nuKfn3max5U++IWvT99627rkmXR1iz9T1ei2kBymuGM01B8/ZH8xFn9sd9fU4tV2BYil2zyweS5gfl482cn1BQaStuLLBEh5m2ce2NUcA/k0MxT32Iny5zm7WfINg45xIS9xuc0Yw2fyOrZ5qcuJco8GJGVPLwpPslLuhWUF2NuLBZDF1SWs4GEcXvdrRdJpAspgSrhjemWy1bm78fcRtxpEVVyXa4RMug/V3L5rHFo97rLgcIngFUPEYlb/pNfrO8Yr0paG/imUCtW9eIl4lPBI/YABMiJ8OfP2498rQB58yECYkT/WZb/z26isBIojN52dkTzaE1FXs3iZ9leWmoNE+7aWO3qtyWvxZEm/vtl1V66nRPGVYXYAoa7DW3H6Q3Oh1jGmNDrkKpz9F8WhJb+Bd5DZW7lc6vZVpHg4y/9bFs1klkY/EV1KN6yeuXleckhnJWYi95P4vOPmt2z8lxOss3Qfpwj0ZTitEbUvRRg3Dih9s9Sg8nCUv0924Zn/P8R5yD4RmJZVpA3j18wi+YyqQm+iB3jmL2rf/sngoUp0CmzB+9N6NvcGveea7lvuVAb/6j/NUdO988pW+Pb/+gwGHLouv147x6u1ef30XuxqOjGvk76z2xvIVnxjJXYW/Pvvs86eanv4/OobD+GFfsjcAAAAASUVORK5CYII=","e":1},{"id":"image_20","w":193,"h":240,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMEAAADwCAMAAACOuvCmAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAA8UExURUdwTO7UxoRhdNu3ruvQwWdIY+7Uxu3Txe3Vx+7Vx31Xa55xeqZ0fO7TxLOMj41jcr+Kiax6gO3Vx1Q5W0o1D90AAAASdFJOUwBY/f0g/KdAwOLkgD+A+azVv7uyF24AAAT6SURBVHja7Z1hc7MgEIQRhQMTTaL//7++aZu+E6vGAzplt9P7mnbGJ7t7h0bRmK0aQoxTjDF4P4ihqyFOy4qhYT78B4QnOX4/7RcDQzO9rgEdIEyHha1DnBQVB3KAewViC32W0DWhVSFOh26ayBGmxIIzUpNKENklgOtIQzoBWBSmnOrIJcCaznHKq4G2Ef0vwvUEaEOK2QQoac4HQBGhgABEhIlehFiC0HD3IpSOOhQRIKxSuyICiFOFMgIEH/kyguFPhOpZRhgKTaEIHXs3QuiohQQAkzlO7GH2pQShq5wFKSWYYmC3UfXVhS8nCNz9FECEoZwgVg5zoPfRd0Sh9qlCE9lFeOmkSCFCeUeqL4JnT0L5bK4vgrCLIJ59bdEN9DPhN7Sj4uUFwDU8/msvpRdfEC6klvVUiDvZyvJsIBBKhjPGLRcNeZYLmyrG/VMS6UUQehFKooByw0VDL0LBWIC5P9tzT7WiwdbQI+DczSnsWc6fzTgiZPtI6BGA7msWehFyowAkQq6PhN5HSHf4B3oRMn2E9PxdJgIQQWYUoB4UCexZzvSR0PsI65GpQC9Clo+wRBB6EbJ8hCVClo+E3kdgj/YH8qVFno/AHscW9ixn+Uj+RPgToTzMaHulCHtDzfER2v4W6T6C2+tF2LOc4SM4EdJ9JPQ+wtt8KrA31HQf4W0YJOxZTveR0PsIcCM5Yc9yso8AN/9K9BHiRnjCnuVUHyFuCpnoI0PvI8idagN7lhN9JPQ+wtzgNbBnOc1HmLtOC72Nknxk6H0Eunm5kI8E8wu2OU7xEeqe38Ke5RQfNfQi/II9y1HfaaEPM+z+/UKfZb2PYF8qovYR7msghN5Gah/hvptG66Ng6H0k9D7y/CIYehGA3zOlDDNwlrU+EnofeX4RDL0IyO+M04UZOctKHwm9jzy/CIZeBOj3P6rCDJ1lnY+E3keeXwRDL0JDL4LnFwGbQNNRwV8JLOwjQeUjoRfB84tg6EVo6EXw/CIYehEaehE8vwiGXoSGXoTAL4LQiwCf5eNVtqH3EXyWD30UO3oRAr0I+O3oUAR8HwV6hOOOCo9wPJnhEQI9guJsDR0h0CNorgRH/t9EpiDkIoAzaO8jxGVIuLlcyEVAZZgvl7mlZpjvZbXH376VABLMow7Avv+x6094BLNt1QDvf3474xC4j2NyxwjtvCgBI1Ag2AWAbVuPcTWjn5UIXyS4flwWA4C4PH2tLwHckuB/+KtDPBHMTg+wwPVVM3F6Pqw9J7V2nl8QvA0K39Q6jTgvjsuNihC/1xdWsW+Dok6TXX25i2NrRzvb0+r4V367PT6oMe3cvM9g1x9uKvCsUn+u1k6fvdSO8xjHvePfWIU8//epPsFRrdvuuPi87+o1I1W5w6hfu6pRPqyNZvWV8Ypso62xN658Jrg2spqBffcRpo3c9sDbAPhhEZQ22jsL2gKY7YBoo52F3+bUcB7TRpsm2vwCYLuRU636fj7KZ5fQi9rF0ds9C44VTxLUDPalWtCLI+ecvTavsX9YgyQf6epq2BF6Q49g2BF+XoM7Qv+dBHWuDp8cs4m+WYbe1KpTz2yiTwbHLMED4mbLABzADyTnEjs5lF94cv3kgH6iMt3plowBBfBw1CWFAhDgk4IbQD0roAE02UYHOJwVPQHAY1ZsXuS6khz/Tn+yNzF8db7cOdz9xL+/rFdy/wDxEWTVBoKr+QAAAABJRU5ErkJggg==","e":1},{"id":"image_21","w":101,"h":347,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGUAAAFbBAMAAAA+VV2VAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAtUExURUdwTA8RJg4RJg8RJg8RJg8RJg8RJg4QJQ8RJg8RJg8RJg8RJg4RJg4RJQ8RJvCXA+EAAAAOdFJOUwD16MjZD7Qlnl+Jc0k4GV7VgwAACh9JREFUeNqdXN9vI1cVnvjX2LEd7WazWxU2o2zV1RYtGqUsbRGUUbZFSCxg2e4KtRKsQqgWKqQoRkBZgVYp8IAAWVkh9QGkyIuK6ENkpYiHSkVWFoGAB6z4hQeEos7Ym938un8Dd8Zx4rlzftzbeUrG+cZ3zvnOd7577IllxY+fvH/7OxtVy+B4bcnxhRDTn9NGlH4qRseFFT3IZEWcHrtaoKIr/3Rm483/vf+6I386p3FTJU8I/0vDn++EqI/xmPsS8u2T396Wb/pVDvK1GMSyXnWFv0ZDsnJln4+d+ZHDre6mEFeVUw+E3yIxnhiowbVd8SQFyQmxmDhZT15n/GiLXeBsRcwTuXHAV1Pi4zgmIwZQ1svuACdDU1wEz7/lr2KQsiPgqL4iPoFh0qIPv1BwDjBMR8wirywH2A1VBLbshthECkcM8FXPYZHewzC2OMJuB0935THCT38LxXQCJDu7OENuiRX4di7imBSMaVDsTQtw3etYDiLNE38wy7U8/gMvwiVCIG92ATqN8zDCQEQoiyeMMUX43U9iDd1PHlAcDpMWLWNMRqwZY1I+JXwTCIYS2BqIqZOYHhjVWkBhdj4CpguvjcQ8+AiYHphxOm4NUPoyJKYOsoTDQEWc9inD8Q7IrJzYJpvmGqgSWxQG1MsCJTtWB8TYziqFAVeedak6XYfv1lswxzQvm2Pas8aYbLdP1sI2XPKbFGYLlsp5CgOqUl5cpmobxJQoa9dDFu48pmoOxngDc0ybqKAGouY9QrExTEqsGmpI2E0WCL2GMXlx3hhTIBJUR7pglkgQhrEqfXPMckD0xkVMkLbN+mmU1JYxpo5bBBRDJDWDvUQkFcUUcbOMYmw8qagpt9y+OcYLcAwmME3U8+TQ8ODWN4e6yAZaqXkUg2ZbYo6MozMpDtGrzaIYLN0FgXnsIvoKToSC2LdMiVASKK1QIpRxKjax6rbxTVgHI0LW6eOtCSFCFqc8TgTXfL9rVdAywYmAY3BF8NAmiKfBw7cgaHiWcV1Gl93ErecytoQ23qA72Esd3EE9wIiwjveMOkaELm4EMhgRGnifQXWshrs7VCtqeG8qOfsY41EMWifojRJEyBDGBiNCmhgVYBzJiVnCFGOm69AyJUJeHFimRCji4osSoYCLL0qEssBHOZgi2LiQokTIOoRjx4jgEnt4TGAqAbWrhAu/Qu4MFk1FES2UZWJvjbmhJrEDySNjxTaxRcS6eofYtWCds0vNzZBEkGNNpLpr1EwPSWqKwsDjH1KssAtSYoUlNU0ID2YJc4TwSMl+DPNjzzKt1ElBzWlhE0cJT2jitkCnuEvOS1qGwhOyZNFUeLCMU8KDGTJKeDBnTokI5nEJZxWuYmAqIljVtemhHnjFDjkUh112lxm+L5iKCLJJJEVE0v5J8N0JQUD6IykiiGNOkx90yKqrmrmXKH1bhoKADEZoQYC3QZR7wWSRFgTYeNGCADtZWhCQBJGCgMhihcaAkytSEMLtSctUEODRGS0I8OSKFgTJk1mjbdMw5wC3dkhBkPnbNRUEeF5cJwUhTNCKoSDAs/SMOENioFktIwigLJIOIbrmeYNZEv56kRYEywaKv0Q6BHkAhWw7uzTG9U1mPLgFd2lBkEndNC1u6xZASI/8CA8mF1PcMqmPTOYo6HSoQxe3lQXUmSlumdRA0wPQQaoxxQ31uhRT3Nbd5EKYzh1+9LaQjD+DAao/xxS3rLpHyfZ3RGPKyarjilsmaKBpVMmqK3PFLRlZNS1uSEpdprhlghb1DDFddVxxywyeSRYqXdwysofJndGKxVTdYy1fxyR1ne72UdVpWQ1FMrYTXZgpbimLLR17oiR1XsdzMqWc5gQBqLocV9yy1x0kCvWyxSVoN/HOT3CYBCULtP0H6VViBUHK4qZaqJwgJKuO+sT4JEFqOlwWk/xstMKJiNQm9ZY9TkSAbyQ0Bywm8YF3O2Axia/edYIqh+mq05QuJyJhA1Wqrse4CqjG6qzwyATNqVne5DAJHqdZ4ZH8OlALdZUNtvqdxTwrPDJBA9U58ZiO0ggKrFiFVbembFwXLD5Bq0qhzrGYtLqWCitWUpyU63rnLb7qlMH0MitwsuoUA9Oc5TGqAHSOeIxazN09HtNVCqahgVG/qJXSwGQUgqU1MHlFSvMHPKbgxJNY2ucxWVdZzC6PsTzlwgMNTFORUl8Dc09RW0cDU1eS6q3oJCie1PYWj8kpSe2uaiRISerdOY0EOfFqvvWhRhDceKVOPdJJapxhExoktd6L99RMXwMzEWdYTocIqXOKemlgcjPVeOyrGgmKY8oaHcjKBtvxgjqjsbjpOMM8naRej5O0qaGK1lvxtruuU6nri4pF0MDcfU5pSWs85tYVpQ3Pa5An3j5s96EGeS6SRIcV4VD1cDwmfaSqCi89aivQ8SI3lfVnKzzjMmo1d/aNY2DtBOaYHm8wE+0ww+7qrMyB6ShF8uAgIcdss0sdJqqddeYJjDVgdSRpI/rslvNUoe1/ffCXcFUXXE60J45jcOdnl5zh85gXmlwQJiKRt5eE8J96+dpLT529sX8vYIIw1Y+IKYLP/iP6/Tdnj9htw1Q4euiIcxs/OA71O3OsJtyV+4qc+MqYIlQtl7GlXeehtfxJxcoyQWhX9osz6mCE6VzNpaD3XILatDAu/1o8k7SCdBC81b8l6FViBgluyz7udPZvP31p+sab4W8urQnuKH//vB49YTu9ES64T5uX49v9vSTPy7/64OdO6M7aZAllh4qRvS+CN6K/+7E7hz9nMJrYRD34z+KZ0ZV3ziR9txqi8G9fOfvi6XTsw6TvVhUjxLz+4thE7WF49gq51Qpj+8Uxk9B7FEaGKtV8tN0cNz218M89apqSCzHZGbXY16kEpSMKT4+ZnomQA7UBizm7prwP+UhbJuoc3lg6pvY4mzDEdMaa985RFE5CSzPRwqfGirkZbonK1M57iMmMPVx9aS6iLmHOh0bXFiflbfeje6OkJzNcVeXkgexXn47e0ttjMbXgeHHZ+5+JctUkiJAeYorBMSl/OPP3Ycfvsxjr2SF9XvOOvzfxgCBC7hhz0w+fZf/60ogRDcIl5EfXWwq+++877156YdT+iBHZ5Oh69l+nn7720gsnLZOYzRdOpfm/v/zFH0/jSWBKY69VYzysMhoCxJPAlJ1NBEPoG/JcXXpA7eznCb5jvQS2knVKRJCNSINqqYj9XKc6UANeeJv6xwMZWJW8K+TopWUQzlFSIYUpOS2ycUMrn6SnuPf6hjRQtO00mvQuCHziusnMKyr7QGBa3Iwncb/f53apOaH6KpszfdKMqpr5PX4m3fPjtTrpXNCYwsXSWqr4/JbOuu+/MRazb4ova+y5i87o35DId3lWXNWYb8jYCv9c9K9bstLFXbX0jj85wp9+/va3PuWcGiz2ePu6E9lE/4Y2xLK+8bt3b1/7wvMbp2f+Dyp6XsCMme1sAAAAAElFTkSuQmCC","e":1},{"id":"image_22","w":97,"h":344,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGEAAAFYCAMAAAB02mJAAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAABXUExURUdwTO3Vxu3Rw+3Vx+3Vx+7VyO7Vx+zOwO3SxO7Vx+3TxWdHY+3UxrCChoRecO3RwoZeb3RRaJdtee3Vx6Jze9OspaZ3gMaWk8WPjPG0ou3Vx1Q5W1M5W0ExlaQAAAAadFJOUwDNQr2cbPgeW98z/ary/Ync8qLrdPlC67v2gNcAsgAABrFJREFUeNrdnOty4joQhOX7/Q4BLN7/OQ+EJGAC8UyPu7bqqHZ/pDbrjvSpeySh2Ll3Le/iKJimIIq7JMzc1i2s03nR0iKKww2fH80vWjpHIfP5txZtMFzZH8+/tMLcjbCYV5qtGysd+OqGQSIr5pkqIRTAYYgFYBjRrGg1Mos0AnPKHaNry7ljhEyocNa2iDtG1xZSx0g9nUJAQDedkC6ophPUBRVrrAsK1mAX5rmTKtSogniYUlQhFfo6n+FWkwfp0omSO0iXlpEHSagQGwRkwVEYFCZRblsGKaJjCCQKHV3BAnouyH4TKkR0hYDOoaArTHQ/zHQFUx9qOoeYPpc6uh9ytqdF4W3KJREGU7aKQsMlFg4hdUkpJm2qogl9uZTT1xoyhYBN2mQImYJlMskWxhYQQoWOrmBwhPRsI6UrFHQFfL7S99NiBRyEWCFgc8CrkFihpCvAIDI6iFKsENMVcmp9sISf4kAUjCbFWWJMVwA9l8gVSroC6DmNAua5zrFRaxQw1LFjo1Z9QAChVn2OAqEOHBt14dioJ0dH7eioMzrqjI66pKMO6ahzOurEsVHrFGJyfGOoY5VCyI5vaFmmClfo6LXQKUTkcMUmk6NPJt2Nh5KugOSG8o5OQFeI2cGEoFYqlOzoQ1Br7zHpUSvv5wColdEHoFYGE4BafdsrZccGgLqko9ZeHtQfoWjvxGXs2ACOULSxoQehvv6YsGND7zltbOg9N6kV1J5zdNTqu7Q5Ozb0ntPfOS7IsaEHoY4NtefUsaH2HHBrOiXHhtpz+tjQotbHhtpzeoWMHRtqz5V0ECEdRE4HoY8NLYjOsUEgv2yRs2NDCaJwbBCTo4NAFBK2qZVVCPr9o5RsamUVSuioEVPrPIeYWuc5xNQ6z0GmVoGATK0D4eggSjqIkA4ip4NI6CAgU6tA1I4NInBsEJipNSBSRweR0UGUdBA5HURCBwFaTgECtJxiXQZaTrEuAy2nWJehllOsyzI6atByCs+BllN4DrWc3HOo5eQgUMvJPRc5tudgy4k9Nzm65xwdNWo5uefgl5NkbFPLPZfQQcCmFoOATS0GETg2CNzUUhCpo4PI6CBKOoicDgK3nLQK4ZaTViHcctIqZLCcsAoZLCdEbbCc1HOWN0vRLSf0XE4HkdBBGCwnBGGxnAxE5NggLKaWgZgcHYSjg8joIEo6iJAOIqeDSBwbROfYIEyxIQJhig0RiMCxQUyODSJ1dBAZHURJBxHSQeR0ELbYkIDoHBtE7dggjLEhAGGMDQGIydFBWBUSdmwItoyltRMpOTYEW8acjtoaG+ues8bGuuessbHuObOpV0EUjg0iNSusOsL+bu6aberVaDJbbjWaEjqI2K4QcOvouiMmR0ed0VGHdNQJHXVMRx3QUW+QfSE9mbL/Q24UdNQRHXX3z4tQQk+mmj6ZUnoybVCrY/owJfRlWULfRayu8SO6grmUrr+GoyZbzs5acAzEP2iyDhP91FLyJuqcGn0bbOgE56IJXSHnxve1lPYfxLXAZ25UPXNDetmoHL23KLS/H7lv2qHy3n/9U9B4PxoU/NPjT6f99emXdj439el0ye/W+8GQGu3h/rP75tB9jF8Cn60dj/7oz97v8PpQfQ/Tvr381P7z70O7fXk+46w7X90E2u9nPyvcJHDWxy+FYvR/txFX6D8Fyublc+8dgofp4HeX7DtlTbXSB3iYGn9q/HU+rrYRVniaPG8aPJuyyosE8NlUvnhWNdaNb25/6rE1DlP4W6DdL1Pkwzab8sVAtGPj98852Npm024xOqdX4W0cpgcnV/vX5eHHithselBo3hSgw49ChSj0dwhvunDJ9J9v+TAp+LdV9G5JBMRwV9i/VTDZ+p5352Z9lJBa+jhZ10hfWmbpw9u59Fg4diYO7xQqW4I/FIZW0IfepOAPr/cnjxwGpACtduLoTagX9f9l8EW9N6Fe/Pfx1f4nb23FelgUt9+2LsrDooL0Fj9cSZx+Cyy/w6rgd8v9yrBbLqOQZBqeFgFNd9doD9+r1rvCYCN9G6mmOeynKQgO/sVCvLLUuKfV9laLpvGvxfAmq9edVza1wodSQM8hUyoMzmoIgsKgUwAKRE9XGHUKQBlVTiZk465CXSGfxapAtNYdxGo7QpsUzXzFzuN25EHSdOJ8BBXEnWjhDwoGKudP18k80RouJojGqTHdfBCM02C7WrE+ToPp2Hhdoj3aL4f8JVEdNrgacpF4y6LaoANfM6qvKAQWp03Hpl12pep3buOW5d2x79uhqoa+H38//j/b+QOe9QfMkAAAAABJRU5ErkJggg==","e":1},{"id":"image_23","w":587,"h":678,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAksAAAKmBAMAAACvScdtAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAkUExURUdwTA8RJg8RJg8RJg8RJg8RJg8RJg4RJg8RJg8RJg8RJQ8RJgEEaqYAAAALdFJOUwDw3MatEZNbd0Anrz/kswAAH6JJREFUeNrsnT1TI0kWRRuVvi0coqMpB2eMGTk4a5WDvXJg9w/gy6GNteSwdjm0LQeti6WlA5rWn1tjNjZmePfdfKWqilhuqkyGJkJnsjLfuycz9enT/56HT8cn/czujwwCz/Au509/Hf3F4jZnTP+I/uLfLnPG9Ncwpl+OmCKYvuSM6S9hTC85L/PhV2nwnDGm6W9hTP/OGNM4jKnYPeaLqfg1XF7uM64vB+H1a7zPuL7cnodnsT2qLzN5Eb+GMc32F+CHmYyw+iz6m/MS/Orfr/LAtApj+rR4sz/7ZyaN3jLeqS1+gH9+kQemKv45q5dW//xDPwvnc46u7cgB3Up1lgem0sE0e7CzPehWqvMsKM1LZw6e3psfrQGmRR6YJh6msS2INqCpW+QRQk32TuEztD/f7h9yxTT1GrXCYjrZ2xdx8ZoFJrefLezLOAC/mwmmIRghvzOxK2ABXtDqRxaYCi9E+tcvAOllrpgGYFr+fb4+B5guQpW54HPiJbffvoDp/tRi+p4Fpu3uGv+Hr19A8WA7k2UemL55uuTrZ9u/7N9CfZ7gs/YwrT+Dxsau/qs8rFTtjYa1RTIqf+SKaeVhqkHduLATUb3LApM7BQcxrb0lQOtx654a1I3VM8D0mAOmhVdFr1DwbSeijVeeaj3laztM2yyM+bx8a4BpZSeimywwzfZeSLsEmGo7Ed14CYPUg/oPHxOYiAZZ7L+Yon0BLiYwEQ28kFjqGcJdJh6mGzt0csdUQUyGSeH+AaXHHwzVa+i3C/et1cJ02wjTpR2OOWDy13OkTMDQGYNEU+/Zur0GwjREmHLYa+F3rhjTqa0octhEULs5CMI0tkwm+7cMMPnhI8I03X+x3U4O2nfpY/qMWptXiykHn1m5YgRFB4DJvMwB0+J7E0zz0mSdozID7et/yBHCNCot1TIDnzl3w0uICTFZZOAzZ+5yPi/RNjjAJAdMfnE4L9F/WdiFscrAZ/od2QxiqvLE5Pf3OCRf7iI/knv8UG0GW9ql7W2WGWhfP5XDLmFlO+VVBtr3xk3lMKba5i51Btp366ZyEzi5r61aWWfgMzfuZ5xCTBuLdZ2Bz6x3Dy6mCzj6bgPk5J6Vu0yNISZgoLYZaF8/bgpjusnAZ1YNMQEDdZKBz/T71qGD6SJATu0hmRq25gXCdKGOiSS0hYPpNENME1+LYExDW5sX+tp36ku2Ai5gQNQN9bUvMdsDB9ObxSSvfckLgzFN7Vs61te+ZHMS3tEzsaJuqo+J1DwnENNs/xIYYGoPaTQwJlBoTfTtuB83OfvDgM8EA0ztIZGaQ7A03c1M346TgPYbJmhF3UjfjpO4fxPFBAaY2lP5js05AAb+RSnvM4mxXWNMwMot5DGRbRLO3lXwmi7UtS+bfWsHk52yKnVMc7KWO1t8a4tJ3o6z7aWOcwG6abl/1MbE2rEVfpWebA+zUrfjYxIVOftxQBdYq9txFjw6Bu/GZgrydpydhXNKKiAI1urad9AJpo269r0hJtKpPEEsvFXHxHZJuJjOmsCWeNieG+eUBvAoJ+o+ky3lTh8DPIq89iWFodfugYp0oK59STfmbcIAgqBQ176kt/e6YiAICnXtSwI1rysGL+NQ3WeSFNvbqzKy/2Ys7jNZKudu6bEjcCruM5mIdHcGWEwTcZ/JtLZ70M5O++qY2KQy9jG9LyLme22fyTZwuVHU0pSkc3GfyerCoVdaA7Ui7jNZKuf+tzo7TKxndf8byCrFfSYLilxMG4up0hZ1LHZ0txsCtpX2MdYNCS9PGmBaaou6moSX7q5M8DautEUd07VuTA5CuFpb1C3JnOK+kKDYEhd1bIVybQIo3dfaBoptc3P3+AJn8KRtoBgmd48v6Je30phGrGVdeZuWQPqiLermbEO3uxV6ZmMTbVFHT1G4bgrAHUgbKJphu25qZPMAbVFHjYg/vS8App/CmOjpU4JpZ/+QsoGi74q/CtqidCxtoOgWCR+TzQOm0mqFreOkWLB5wERarbDwcu4PEJsHzKQxsfCSmE6bB2gbKBZeEkx24+5IWq2wNI0c0wDvqjQmls2SqypAoyttoFjST06zgDpioWyg2Dk4cpoFVKWV8lEx9qqQO2ZAB7dUVissvCSlJ+iYV8pqpTwME8hfamG1QjNecksj2BynrFZoi0EwgX+nfFSMbpkkjQwYhcpqhWa8rJGxc9qNsDOgGS/DZAsJZQM1ZAk2O+Zs40tltUIzXnbSrjJNjjImmvGyPT22ZVZWK9TVsgs9bACjrFbovMvaYhtfKqsVeuCbXTZki0lltUJLZ5Ye2GJSWa3QrYAsPbBv62yv6wxoW8/Tg/dLpLJaYVE4TQ9slaSsVlhpRHeIDe2X+wpjYkcoaMgCqiRhZ8C2O9OQBUQLwpjYmk8vtwYMhdUKW/PpVengjRRWK2zapd9PAJZ/XbVCax1+n4cFrKtW6GLGb4exs5quWplwTKcU07XpDy9lMb006Uf4uqarVqhY4ccr7Lqmq1aoWOGqxMaXumqFLmb8jkYbweg6A7qY8Rs/baCnjOmsCQg+YRey96bRxYwfcrYzka5aoYsZv9vaEtZVK3Rx4jel25lIV63QxYzfU2Elr65aoafil+5XkeOZSFet0MWM36FjZ6K5LCa6mPEbmexMpKtWaETET1eADEYWEw0c+bdfgZlI1hnQxYwPDvCKyWJiB3tGCdltMVWqF4KxxSy1J8COHVm1wl6T1OFdi1hWrSwOlb7whZVVKwdLXzh2ZNVKSaXvj4Y111rUGYy49H1NVPBXTTrED/y0kL5Iy6mqFdrTDxPb4W0Io6pWEtKXGwALRdUZtJC+CIoqpmm3mFRPrdCQPzXTWN+kqlbomp9atyyUoahaoWt+aoOJLT/HomqFetqnROthl8mpqFqhWwg2jTGpGii6gqcuALciRdVADfhJ3/uGDeFc1BkkTvreNYwXVA0ULY2SmGymJ3ohGD/pmxIANuUVVSu0gkweQbEcRU+tbPmB6MTQsCmvqIGiG96TE41NeUUN1MHnxv9bWF0lx5fEQ1VIcnW3kEUN1PrQc+POzCZqoNj//VHyvLxdJ0UP9zBM6WsFbNUleriHTbnp+79tRyhqoFg/ksZkY5iTRHz+QR9W56S/9tmGeqJqhbVt6e9at2H4gB57/bBP1QqT9TKih3tYqzpO2iRr+UQNFNtTmP7INvoWNVALeqd66gWy0beogWKYCnvzULIAFTVQ/Or51Kplo29RA1XumtTY6eZY9HBPs8vj0u+sqFo5Yoo89FMFdgjaskvSQM1bYrK9jqSBopFSIBRBauVRDxPdGhGI2FYm1ZM0UBRTYC98JgaKJm+B7wPJxEBNWmKyhkDSQFFM6/QnzsRA0W3hgYGRiYFKYEpOM5kYKJrjBmZj289IGqgxx3SXxnRmxtdpZpgCJZCNpCQNFI27l+mCGom688wwBfoO++8lDRS1AoEu1ooUSQNF/9/z25ucuU3yejkqTwLRka27JA0UlSeBIDKTwz1tMdmEQfJwD61yAum/9U3zIyaAKY/DPcwxRT4w+J1yd8QUGHGKaoU1qqHvB7PT/CJdbWlh2ocwXTdvcT4gposGi32oUldUK+0xmbGzFFQrLGsM1dN27CiqFY7pJYLp3mC6ksO0JZhCd6TbvFxRrTAPMo1EIvYVU7xejn2mUHJk7aWiWtlQTK+HYFJUKwxTKK61f0BRrbDdFCFMW4BJT62sKaaAI7EzkaJaYZjShwwgJkW1wjEF3p6TLL65pzUm9AVHL4KYbgmBswims0NawQ/21BRToACyQ05RrXSA6f21qYr3pnWA6f3yP8oMU+hSa7D8C6qVDjCZ5V9QrbDtlaFWf4wwPR4xvXtAdieoVhim0NZlgElQrTBMoRgSFJOCp1bYR9rEMD03WRY+LKY7gukq/QdAzS14amXZFhMw6IJqhWEKjQpQc2/1nAHHdHsQppu8MNUHYhroqZXWmD4hTOc5YYrVP3YfmKAzYKd3opiu06HBcTQhTHLOgLWpsd7M5gGCzqA9JntMSvBCMI7p4aC/IOgM+sA0zwtTLF6zr6agM+CYHg9bK/WcAcUUyrRB2aDnDKrdQ4OlPohJ76Yr9olig8JedCXoDNpjAg2ynjNg80/szkGwW17PGSxaYwIZp54zYKOpPBSTnjNgoylWJQJBoOcMesGkF4YTTMGeA7hhvXMG7TGBnQYDQUzXLTGBN0zPGRBMoYPjEJOeM+gFk54zYJhi6RrYeqh3zoBgCma1YL6eyjkDiun7gZj0zhl0genswHGogWlyMCa9cwa9YBrlhSk0EaPjZHLfjkE+0DSK6WejhjpbTLbklgvD+8EkF4YTTMFaGnUmcmF4P5jkwvAuMNlfkwvDKaZQn49oyoXhBNPwcExyG+i7wGQXRDlnULbGhOoGOWdAR9NbDNP3SJ8niymYaKMOWS4Mp5i+HIpJLgwvd416WvCgDE4uDO8Hk1wYTjGFpCQSMHJhOMEUXK6QzpMLw9tjQomuXBjeD6bREVMIidoGeoop1nEgTGob6LvABP6EWhhOMEX7V1TIq4XhnWCyL5haGE4xXRyMSS0M7wmTWhhOMEUjSLQDXy0M7wITOB2kFoZ3gunh4H+bOSa1MJxgir44qEZSC8MppsuDMamF4SQLf2qBSS0MJ5iiizqquNXC8J4wqYXhJcN0FcRkGxO1MHzRHhPq39TCcIJp3QKTWhjeCSbwe0dMod8TC8MJpmhmBDGJheEdYIKFg1gY3hcmsTC8A0ywqRELwwmm6CeFLbJYGN4BJphLiYXhfWESC8P7wrRVw3TtY4otVlBUiYXhBNMyjOk0+MOsMcEtGWJheCeYAJHg/lYJTA9tML1lgqlqg0nsavVOMIGN0WJheAeYitwxPQYxgdlazBkwTLsoJjBbi12t3hcmsZ3hBFM0p8UiXAzTvidMWmE4ufQljulH3phifwJvq9C6gb7qC5OWM+hkNKFKUssZkNEUFbe44NZyBp1gQgW3ljNgmIKVD+5LtJwBWZDaYdJyBv5oCrcb+BpRLWfgj6YGmFCXe3LEFAkDtJxBF5jKnDGFt09inlrOwE9yg5fPe5i0zhkQTPtWmLTOGfjfTxePaSEmLWfgj6b4DnjY1Wg5gy4wwShB65wBw/Q9jOm6xQrwIZ5lX5i01Epvo0lLrfijKT4H4/ZZ6qL+TjDtH8NjLGtMD43aIDFML63+xlLp1Ir/YaYNMN2Bn66UDFSfmO6VMN21xoSBrJUMVJ+Yro6Y/owJjRspA+VjigdGWPBuj5jeY0Kvl5SBWnWACc9CUgaqi9GEr7+Q+g7kVSeYLiGmsyOmPz74oqdC6auifUxxg4TXtKGSqOsCE17TpERdf5ikRJ3foLbFJCXqusCEK6SJEqaaYIpOwbhCmin5zFVvmKTOQHUzmlAhOSqzwFS0xCQl6rrA5NTbR0zvfxPeOaDkMxmmn2FMbxjTtRCm29aYnMm+EsK07gQTLESXQtqXYTpvi+nhiCnd5Cpp3x4x1ULatxtML83+tBKmeJY9PWKKYYJZwEbIjvufJY7J2TCmpH17xHRzxPSnxwnglLRvN5ie8R/IA9Np8G/Mj5hCmMrndn/g//956gCTc+6iENpE0CsmnU0EfnHTGtNQ6CLVLjA5qfdYaK9FN5h2GNPrEdMfHywHpv9h73x+2kiyON7YbjA+pR1FGdIXbGcu6wvBKBdf2GBZSL6YaKzReC/RDjKMfAHNLBi4sFIGE3HBWkXG5GLPiGVtTm0YSFL/3Fb1L1e3u93V7jaBqn6n/DA2/fF733r16lUVRb0W9jOKKa+YZgJMZkxFS0y3TGCa94aJpl4LXzBZb8+MifRgsofhGRNNvRb+YAIBJiJMp5bpVIDJYDYLl+l+gMmIaSvAFGAaVWL0jikrBZhws+lzpahzxx7TmmdMhQATGaY2PZieeMdk03JXpafBKcD0zTGd0NMH5gsmm5MZDujpAwsHmO4Nk83S8Sd6+sDsl2Zd9N3YYLoKMJkwWb60Q0+7nC+YrHfYw3egCNML75g61GOK+IHJ5qVT9HQV+oRp3jonCzARYZqnB9MXd4LDJib77hoX3jTFMKaOZ0zhABMZpif0YLrzjsmmzBBgIsIUoaeVNxpgukdMz6w99UWAiSlM9g2S3jFF6el49gVTOMBEhumF9XtT0xg+G2Aiw3TrB6av7r4CVjF9oRxTzA9MNtWYmEgPJtvmbT8w3QaYnDHx9GDi/cF0F2DygIme3Ri2Pe4uMNlVYwJMRJjS9GBK+4LpM7OY1nzARM+mFdutAJ0AEwkmF94UpR9T1gdvYhmTK2+yziOzFGGSJoiJni1QBR8wzQSYAm9SMRUn5k0FejBV7bYpBZgCTK7txG6bkitMNwGmABOH9t9secZkd2hMNcDEGKZPASYyTIcBJmfrTBDTCQOYpgJMBqd5F2BytqlJYpIowrQ8MUwHNJ0lE2AiwrQQYPrWmIq0YLLdpuTi/Ca7lrsAE5E3faIHU2SC3hRgYg3TtN2mt1CA6Z4wdejBFLXb9BZgMmJ64RnTDP2YZsBcgInkEb8EmEh05S7mHZNFf1Mqv08PJv4S3Px9bgLeFAVAEsGH9iPnU+rWjnKZpCACaEX/vekKyCakNvcfo/eUWzKehAAwW/Yf03Y8ob65FF+qf3wsfGLdWmVlMSkY8KjfuOWuQReYrHov03f8WUH/CITq/EHzKct8EhZ4gCQklzbFW+u1/rAnTFGUZ6xJtZWEiKHa3Cs+PPFpHq/b88nkN/fO0S+dvuXeWq38usI0tBlD7gNegyMdf7m+KGAfnMpt7rW/se70Wq3d2nElZxNdCE9qqVJX+GjRccPNiHN+Y8oi8mtqQlCurSRF05dUPy/eZ0Q1a0frucxiEoqyIIgisDbcfcwPdIMW1A79xRSVbx1dw/Km8o4BFZJE+StrXUwOF99rKsO5ABxM42P/XoVrVHTqW2B6Mj6mjjwFmjKll+UaHoAaLYgrk6sc755flPxynV0YUZlFZzySoIbXheO7IkxcejgncIFp+KysrLxIGrLIwvnuERRMS6+H4RBPJjOZpVyuUjk+3t1rnfcuSiUyeKVSr4neWRBHYBGUj0hlMrk8/GL2XAS+3DYSGs6jvWCaVrwzZDdZ4cvy6CsCx2AQ1SeDzwYfDhGED6hbHv51JaNIzgg20GNkKq1eaewIlzHxomQe7CIeMDXA85GYNFhoLEbS4czLrclw1Vj2JZSVfojGUD3FFSbjD/NppTEhRDb15UtdJCYQmDwOeYAjQTZLecVvfB4Ofs3LKiz2i2ZMz8gxfTX9qLKnJ+S+QsCXYFYDJfi4UpHjKbO4iCJO0MwkNKrU5JDbTHLMhL+Y8uZV8yKvK0zGCuiJ6l0hPwspPBTzcq8HU0PF4B97pdIkyXCWc5ObsTGZTqydFdVmIL7L0WaanoyH6Zlx0nzNUWsN8J0pksbFVADf04tpRpROfcEUBdIWvZigiP/NF0wNiu7ztXxYQ07g4jhGQ8IORW6BZkxwIrbgA6Yw6LepxvSHIVqibjDN47H7XHcsSkUcb6WPWp+r54RpRhwkFnRigtnzcxzTl3EwdWhOmnQRb2OY5sbBlKY5abIQ8Rlyb8LWqiJ0J02KvcUmdq4wLQzi9pZ6SmjSeugJE3yDZfox6SUQTm5VcY/pLegXGcCEZeJjYcqS6z4lIu4Ck76LKgLouQdypHV0CR4H079ZEHAlidYGdBcHD2sX0UEBX2AD06Cc4grTO03A24xgCmuTjTEwZfHJDt0W0+v95AcPd5QfmWZFwJFtq2O6K0yHioDfMENJT51cYFJOxmBIwBWFUcYtN5i2ZAGX2gxhaqidlOSYlFN7GBJwZFHVK8jPZz5AR2VBAX/HEiauoGgMOaYTxHWbJQFXssRb95iggH/PFiZ1/dcNpiJrAq5EHXKMLDGmKsRUYEvAkYVkmSE/n7kqsSfgSqK45QZToQ8F/Jpjzqoo6txggjPBefYwyWWCggtMIWDs+mGmTHDoAlP2umDqIWPEDsCcG0x9BgVcKRNcuzi1MgtYFHBOaVglx5QGrGXgmm2DOTeYWBRwZNOgT35qJaDnkky3lgbEFzZMAyYaByytAUCfOED7rFJCLkJ4HCOU+ztmMcFRnhBTGJB3adJnHUC4f6kAyHt+6bMoAG3C15HvR6Ay6hbItF4i38dJoV0RZUOxNEiyWETRbY2ouh0GUoNpTFOAJOoK4PMUU4viFpic132hgL9bYxpTCIjOM9oGuIYitsw0poKj6MTQ3otPbNbkdEz/cVzvDqMSygFD3V9WCPZFpw0ocg28CraYxrR14lCVjMo18AI4ZRtTxKHG3ZD/v0A2q6HUIuCQT4+UHV7ZPJel50zZ8TDp/aojBJzj0hLDlLhpiGl6ZNQpXSi82Gcb0zvt9LNRAs7F2MYURRD+GNG21FDSqllG1zJxTDOi7T5CKODzyutu2Ma0LOvPsr2At5XgvGUZ04wMKGxbnNOOr4iwvLCiYYqJNsW5qLYHKEy+d5pGmxXlcNu2qSY1NEkKsbywgvxoWYmpWxsBX9AwPQswobnIlqWAa0PgGtOlcI5Xx7iOZZmgqk9jGkzXeDlO9aaoeGMl4LqPHTBd49UxcQWLqMMOkDthung5wBQejjoeOzm7ynRVjuPSKonY8CafMDaPY7sqN8DEbQ9FXRVzsCzT5SaOe6PBmTZHXRRfwUv32cbUG8TVrVnAsfJK+poLTJWiZZOADwY3XvwcAFLsB+N8xHBo9qz4JQAU21lto7HuL6OAL+CFhL8YZ8TX3ggAXEMlr94ZBPy6iP2N6V45jmv+rF6d9oLj/oFnTmuGo6CZxvTTe+0WlPhrOPZf4YN+1tDPE2G2QBDbWVQZCS8/yPF1hS3sho2LLRFGZ77/04JNSm209TgbONAJjMIiPuwdshhsr7Rgy2OXXk5hvTlZGGWLrwf/WS6yNrLtvFEZSWqwaRbCXAZNdUUgPV39yHiwPV09HUrDDw1zOJXlL6w50k/rg5HN4oZZ3JvQuU5/JrQX/4slQdJGNky1DTaFSXj6Th4MVQ2TUqttJhgdaYygatvJzRRWesuqc7jLnwXASPA13w8YLX2wf1g8b0p/Hc6vRv7wI3ejnZWEfrHby42Rj1nFakqGafClpvtUkkKIBvcSpzad5CWN1ZTSX01ZBOaQdWp0ir88whAhRs63JsbwNoH0V/ucFM5uNh5/OtU13hgrxZc2iL7+CF5gylqV4QbBB8Hn9x5t+KE7dQ1Xn8ZTq/ukT7OGz9sKNkVdSEp///jS5qNzqnJzPWMgJEFErr7wE7zz+0SpPVldyXO5briJ/dHEH7psOCkYr7Be2nR73Tdv6CK40kY9y3fpvsdvYo+7/7B7R9Q0hZkUz+T3xrnl1ni52FundblYzTBGxFP5DxcPNM7OjLd7o9+1Pm4IzFbB7zg0kjtCukeLCZMP75ceFKLujjHOBEjofPypDFo1MIj2bLxN6M1HRm9GrPYuHogT4b8Z0gYPg/Ol6pJPtwz//ObUxVsYkjTEKp7KfTtYPEyJjMOZ4CHMVEaiMh82T0L+PPSYi6BLr1NLlfp5axda6/xi4irPl1u1Cgwy4+XmENGep2mDzsiqnhTN10/dRy/6GgX7O+Yzuc26z9dhQza7taP1lcXE8N3vsgB4+7QfVUZSfNUaRz0RH6/IVG4eQccSRtw7j3ih+8N74xPju83jSi6zCH1HtPwQPyRS86OhcjjuGT+I4OnG2M9RbsIAsPqKDWGJLl3PLOXyleP67l7rvHdRcv7AWG30t5DM5OvewkyZFWtZtNOCwG/wZalfvH1arLt7XFnJJBOCAJxNv68eWiqVMVkK/XPClrsQR3x8SXT5s0HpyKocbrT/JtAc94NPGtJrQTGvHVVgrBBSIzPJ5xxktqaX6ISXROW12X+Kcunc/0GK77Wgm+WgnyWh/4hj0IFel8rkN+vnvia0l4NKr92SgaVDvZI9b3Wfm5whR2vuHh9XKuu5HIouOegSiYSAWUILRKRkm1D//U8w+Oag/CGQVOjwn/0toRb26F7YxKvh8Zcb7mM49j6h1SzbdCJC9QOsijZuuV+vhNO4YtA9whZV4q+9PeCP6ggpxfP0LAEbVwyklB8KzJ+p1N2MAA/XTHNQP6uwMa2Z5XHLlHmWPoHlD70PURhnNHgAA5qp5iMlX9cnM4TribzgYtnmoYz5flahnCefb4RBSfBRoCrXVpKiryUWsonPIBuTS/APOQBRQVw0FnvvUVljZ9iCnfB04+MD9KquUa0np0SjXfnsFaaGr/cuHgopVLVbN9Z7oRfVv9186//dmrFugzAQhrP4AZKO3eANCE8QrMwsN9RroqpvgJM5QukTULKjymy8Yc/XkBiMqkbECcDAhBh+353v7vu/04vjdY5nlZfwXKnEV2pvA4cAp5mSK2M39pja2KlQdgisrd2QKicTV/+TDit//dkokuA8xES26ti5hz3gpbMx2zQWEPdxok0ct34LIMx4pm34/QnOfWfJg8kRF77DpoqhPKVeHMs0asxmQ7d91M2ujK5h5caDwUDpHXHrLnsZ3fgk5Mbo6IgJ9T9kTLcYQGVyGwUWcViE+9kon9YIVWmxPm5rrTCvCoA6u5LjMTXWjEat9kdum7VMGFqtM/M9FTYTEQq1SHanUuUYNMErCsAJJHhdwAqvCfoaZhN4lGXCuDBfIpeapYScE1fha47vLf8L65KJQ6fxBBnGW0LNcQ9qSRx9GWLePsLd8tzKro0FmED/5ZdVVc1/odkepq1Md2km5vvOeVTDS89rhtrZTeBjn7ibevDcGmu1YQyYwBKe5cVga/MPIXZ9Z2IxoukAAAAASUVORK5CYII=","e":1},{"id":"image_24","w":568,"h":155,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjgAAACbBAMAAACdTPysAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAVUExURUdwTMKEqdCQpM6OpcqLptOSpLN4rfQ1/FYAAAAGdFJOUwDnQ3q0IJ9STX8AAARISURBVHja7Z1Lc5swFIWxHbq2Wg9rBmLWNjhZ17Wma+qUfTEJ//8nVOTRJK51zUPYoHvOKpPJyOk35xxdEQqOU1sTxx7NTS9oE5w/phf8YhGcg+kFo9QaNtNH3+h6buitbGETrsvym7nlZqJU6/mjx+IGG1n9U5TMdfLkZcF8EY81W/tQYfHKdz0ZW/r+fVEhRwUoCxO5/UTlVYWxjzhafASA3EAD5Z9MlcTsxNpDBXSeyqtMbeeRZn0hk+VQmOxVfqQQZX35vaTqmNAuSK/DIwgTRWQr6hilL+vMzn9QrhDFy0tkZlP5o5FD+rVOVPvjhGKUGPeRG7xExivNat57qjRGElJhSoIg61oiouxNxWVSddZQFaxKO0VMKQyUskxZzM2yvfo6fv52snv5KfMm6S1XUWmrulfytLRXna0zsRhO50q+txhOgVT1l6vIajiHSw85Y1LuX3fIsdg6keVwurTO1HY2XXbzifVwCgw5feTK/lR1qOSIAZy21uFgnNaVPGEBp0Adm84Vj1S1rOSICZxW1vG4wJnjzGm0ktmkqkWupnzYNK9kRsYpc9QxoRXq2FiuIlZwmlXylBebZqMOM+M0G3U8ZnCa5GrGjU2TXEXs4BSoYxO5ihjCOaCOux8hZiVH1TlCTHimql6u1izruGauPKbGqZUrz/eYwqmRq3LHlE2dXJV8tcJwTOXqBjOOPle/aDg3JedcrXFnBSHcWUEoRR+3vHDBPFX0bs48VeV3pEqvOS4B6lXAOMQc6KOO9YU8Rx3rh8ACqdJqqp10IsC50e1XMA6xX6GOiRME6vhZB6SKGHVQx80OnzAOkSvUMZEr1LE+V0gVkSvUsX7UgXE+ao46rn2EQB3rc4VUEblCHetzBeMQuUIdE6MO6lh/hECqiCME6lifKxiHqGTUMTHqoI71ow5SRexXqGP9fgXjEKWDOiZKB3Ws0SNSRTYy6lgPB8bRC8ah4PwEAz0cDwwAp1UhAw4BBwwAp92EDAbE2QoMtHpCIes1Bxy9VoCjV4rjA7GT41IXsVnhVE70Ma4ga+UDjlZfuT/XQy9xhz93nt6mFvHb7SfYy4/I3H24HfA3gHxI04+j+/pvweTNNCf+A+MtjhCnTPP2mK4tTEM8N+fBY03m7swT8Lhm6zyZSu4aZKgHC21BhsTDJVxi1+ZtaLeCA5m07YtN3Y2wOkxxt/e3WxuvdmFiEC8hY8ec7ImXkMnSMa7xxytf7GKnNz2Ml48yjO/0rekI86UaJnUupXALMNS7MjyAGW/9iF67tw4fOcD6EULuruSX/8afcDCA8oVMgmFQ+dTPm2tH7CL7dAcLJdeykDo8ps7wdfmMqZHXd8ajiwGqtqPUGZ/6BTSg7ai19qqETNZ0XkHp4zx9PQ8FGyk6MFJExEIxCVLHXrlBspEKk6hBqsIhkyReZg5PZfsgTJJESrndCk/xyqvUSEVkuL/zX51lLjGIZMDnAAAAAElFTkSuQmCC","e":1},{"id":"image_25","w":1100,"h":16,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABEwAAAAQCAMAAAA73BoXAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAzUExURUdwTA8RJg8RJg8RJg8QJg8RJg8RJg4QJg8RJg4RJg4RJg8RJQ8RJg4RJw8RJg8RJg8RJrvXL1sAAAAQdFJOUwCdwSLe0bD68+pdSIgQczMT+aKaAAABxUlEQVR42u2a67KCIBSF8RI7hcD3f9pTHcGtgFAdupzW98scGmcMv1l7mRBCnKxxjAvKY2c6x2lBAADAjGppKoC2B5TkGDCs6VccOK1HttLTyMahGz1jdChBNW4d2EUciB8dgBou6afaUPFHyn0/toAof022+MJU5MChigMjCmQOtHAg+FiaCezIJ7ViJbhbHEjlV2SrHoiBZQ5kCszkwNGEs7BFDgRCdD1E8q8cGOQ+SsZAyhxmfEdU04F92oHtIZYDmQL3HaiKHAg13I6FTMAbKrBoFKZ7U2ZqfV0HRnNgfBQuqgPfLgeeJPY2AM+sA4lyJeHuLEwvc2B6FB67q03GI7YEAF+UA3MnKD4k70bCQV8zkRlwvwEAj6F/axMtXaRZh51NFAqzUjpX4d4C8FUMqkYL41n6IdcYKes6JN8rmXFumrRx5dN5CnOcZzNPK9n4xqe6Hg4E4NUYvM4qceCiQCZBh/4bBw45BxIcCCAT8AQHMgV2GwUyB4YKTDqQK7AtzYGIgV/LUeFpBG8WA1WYAyOjcMqBawmW5kA48HEa/M8PgOp1YFSB6Rz4iQ4kabE/AEAdGK8Do69EuAN9HSj1Zcb5ATo8WiVMHoMzAAAAAElFTkSuQmCC","e":1},{"id":"image_26","w":48,"h":94,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAABeBAMAAACX0oqeAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAwUExURUdwTA8RJg4RJg4QJg8RJg4RJg8RJg8QJg8RJQ8RJRERJg4RJg8RJg8RJQ8QJg8RJpPY0ycAAAAPdFJOUwDw+dnOuuJkJU8PozqOerrmGqYAAAHWSURBVEjHlVW7TgJRFLwGkRXQ0JEY4zbGBCygtEMaW/iDJbGzgfADrn6BiaWFa/QDjIWNBWhhZSLxB+APdBdYY3gcLyuYsMwU0HFmc++ZOXPmKgV/6w6uq1IF1xPyg4FV+WbAEAMROcTA4xOub+6TZi8PcN0odjAQ3SUnfaSJTmYZA7fuBQYafVyPmdvkJCFXNNwm6anPhM1goE0UN0wPs4hKD5/0wqZdkjymnZMWsYeLPVgXQq9A6MVEKkQPcve1eDZhgXkbORmTtZAtCKwIGeupSI3c7cJ6PEcE2RAyjAhr6lyIEdpMqQJRSjfl410V0m1USIJopVIQeF+625IIXhmTaJsUMnBNY7QcDS16lvGrsGlQi7QYcewdixsaE1dV6SoiVZ/ZcDBfsf81nLfh3Z4928thaO0qM+NmQ0p8zbYpFUqP8Uz1kIZXx/YUCHvkofwXLwvivu5M53QfXuKgYQ2EXw2jOvl0DajeSAfAYnw+95wAWBhHwmtN7vCcxTg/mQBgTtYoiEkQkb6jAR+ZsKMl8VFW5LW6PnoCMtrsyAvWQE8QAfWeSuYQcOM6cRMBUa+pql0YYTVldeEbV1Of0KFHtjqD0fOm73HxFqhksUke/uTcv19puudJ/g4pnAAAAABJRU5ErkJggg==","e":1},{"id":"image_27","w":27,"h":75,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAABLCAMAAAC2hAyQAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAA2UExURUdwTA4RJQ8RJg8QJg8RJg4RJg8QJg4QJg8RJg8RJg4RJRARJg4RJg4RJg8RJg8RJQ8QJg8RJhEbR1QAAAARdFJOUwCI1EmXJV/55PGmELfIejhsz7gv3QAAAZdJREFUSMd9ldm6gyAMhEWQEFk07/+yJ8H1qFO/9qYpZObP4jB8P9M0oMenEQZnkYhio8gCQnmWER0rIWakhFeock7o1DClAo85aSiUKyP9Q2SofyhSsBKczhFPGCVMtzBOp9VxKJaEPMJMAmHqlfVHwWekknCjBBHoXK9MiCVjKauIBFgekRVCgVQsHQMqUbBMBQaLp+5g8RhbMJjIgkkRD0ELAdJVY4ypQHuM7XWZFRcIWTeZyLoVD/W00URY0g8s6Y3FBzed9ig/+6AnyfRCZj+N9u+J3sgabb21yAfOQtUSennjzIn9WdkHzkjbPnngjGvujdensVlsvq2L2FGN2/a742x9RtOursfa1R+GweZjOUoUb6tkx+iOmL9WCe+lGZ8dWCm1fUBs/sMNdaCbZ7fF+Ni8h9G9Ld2Jc0mSllurxyuW6+Uzpw6yHajLHavrB+OOeqbzxmNIRr+hduos/l/tipkM9crC7fG6UP36DV5ZPVtbG0P0ExTxe30GstjM/DUQri+J9t3XvjDe/noUv0qHx474A9GgGY8CJIFRAAAAAElFTkSuQmCC","e":1},{"id":"image_28","w":26,"h":30,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAeBAMAAADA9RPrAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAwUExURQ8RJkdwTA8RJg8RJg8RJw8QJQ8QJQ4RJg8RJQ4RJgoRJQ8RJg4QJRAQJw4QJg4RJDd5J08AAAAQdFJOU/8A8uQauXarzkkLh5ssV2Hpoh0+AAAA8ElEQVQY003QO04DMRCA4V9eNiu0EWjAJFmJlYxES8SjoyLkApsbkLQ0lEg0rOAC0FBHdHQpoA5ngAtwA47AjCMRuxl/9sz4gcTh5zGw0lebaryRapCn2nOp+kzTPc7TOrYT7ZInusSNorzVPxPb4AcnGq5gYnq7ONBwA7bI6NfCPRya5o2e5ANsxcxwJNIDytiFjl0FuqaaTORVVUj/kwqe7AC9zPLR1FpLiv3Q0UzKKljdjC71Me4F2wvk1A2cmjItRRr+h2q5VoHsrFUivSzEqXNs6ts/Yq67u6W1n/DX+ryhVGc/q3+p3h8WIt/yBx/1KZf7o2fOAAAAAElFTkSuQmCC","e":1},{"id":"image_29","w":107,"h":87,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGsAAABXBAMAAADxKabpAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAwUExURUdwTA8RJg4RJg8RJg8RJg8RJg8QJg4RJQ4RJg8RJQ8QJg8QJg8RJhESKQ4RJg8RJk7AHnQAAAAPdFJOUwD2687evKdmUZIrPX0JGZHC8voAAAQTSURBVFjDlVhNaBNBFJ7an8SkiWJtrWLdFg8q2m561EuC4E1ItCgUkcSfIuIhrXrwIBiweLU9eE6qoghCK3rxZKQgemqxgj+nKF487ib90Yrjzuxmu++92U26p+7LfjNvvve9nyljjH15N3b2/SLb5BPm4tkxOrcpVKzI7cc4WtoE7Ct3H/Na87BH3PMcqjQLa+Un9A3cznKTsBc8E5nfABrnmoPleY6x6GXNBZ5sCqYLGGOfT7u47iYYDXEbxtg919OuxiFsd2EseqqOqxYawbZwnnFfbtRPWGuE++6FsV96k/vd5zzhFehwHRd8vgUIY/GLDm65Ehw2noKWmw6uJwiWJTB218EdCYAlOe/HtpcO7pg/LK2A1bPCyAXBtlOrs59Z8JekCsYmbdxKAKxPZb9u4w76w/4pf5gOPJ4FW1eXpqytloofbFW9YDQtcbv8mPzt4/9WOx9yPrBlP7oe224uqlVS9Q2qTcthtSZNX5h9PGOc/mKVcsNfeh1yu93KNOUBlWrCh5VZyzruD4tLN7uJvcWP4o3KxkG5cSsXyVPK5jLtHCAFnhGHwzLoCSwFDrT8qovgHsqYK1qwR5SdGukANitou5gGPc/zHqz5NtXprBSoeV6XFBUrqSAzCWUStXY/L/+6DWjD9UEMCgX4XpPHG0Hbwfb8BsVbLN0rtt0PbXyNyCSFvBSa76ih05kVzFMfaiZ8r2X3fia3S+HcWMUGo8xmjDlYBGAMokQDSbnQAkiMH4QUDSeqDO94FhAlTsz34MWBECOiE/cmoZ7ucCgLaUigwchyQIdEdeAsb8FUOrmCApVEFkHuX9LQiZw+itAtgjkIel0vWJBfSUoG5gAuXrJtmFS8a3BYwGkhY4DWakVezXLSUWM61by0leHSuOvMKDJTRKofcmLSeZG40I7Y1RWVuUgTWpQdowQ5SamqcYGGMwOGQ9qJRaoMUn7X4co1piAFFVURcY8pohG2HVLKZBz0Op7liskrjzPM1mUCOuSmfPjD2MiZq7cqbdT1TqgvSVs9BEsD9rXlinB9ivBUhRFxaYs9vWQP2hr10iqq3sq0AGl77l5BqrQbZlAd9DgUc68gkMu4ZdnnedVwxMPOhoMkEVeQbgyQX7F5TdFoWmB1lFwOwU+epMlasmfnkARN1EdDadp9LRf+4LwcUowRayShvBoIiZOYJZphSCjbkAZkbeylNyCUdK0wBPKwokGRj+DhopjdomKOECm1TiYLA3NLRtUiWUlMkuBu91a6OYW9NGllAN+EdTr4x3XMSYwc96fCzQkybhZJJZim1ygrninCLqq7kSS9Dk3gYFoTH76DSRWaoEKHdHwb+0SvbqFhst0kuV6kyejMIg+ODxyAuhjF31yYUg3V3xr9i+Z16T+d6eIOq03mFgAAAABJRU5ErkJggg==","e":1},{"id":"image_30","w":106,"h":87,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGoAAABXBAMAAAAe683XAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAbUExURUdwTPZtg/dtg/dtg/dug/Ztg/dtg/Ztg/Ztg2S3F38AAAAIdFJOUwDhwh8+qI5d2+VbKAAAAapJREFUWMPFlz1vgzAYhN1C2o4l7cCYkA6MQeqQkTFjFZWEH9DQjNnKWEiivD+7oKgKGH+8vg69FT2+s32yjRBesQqq8fpzLlyU0EXVxoXK6VenPZ8K6Sq2nUddnVIedd+jqOalHJGkdw71IFP0wqBKQrAdIZiKsmNKyorlhGAayoLFGopmEFWlzPJK5UoRiuo5QtGzliKTZhClXREjpZ1aaMaeIEqT0UJpMsYWSp3RSlVzh86bzeyUymxnpVTFYlCKYnGoYcaSQQ0XZEmI2YIQsxtCzG4JMbvjUbXx1tMqNdyw7IghIeuRQ2YlIWYLJkUT921udDQ+HVgRuRsmrcfga8zpR842SxUPRLeIXsilaqBTUsQSishuRy8iux29iCM+1emiz6fOLrfRtYuuJ+lFe+fTrdX3P00sgXbMh3bMIeIRititog9NzCHiBIp4/PsxkEATa++xg/thuoQi+lBEvtkbZPYoELODQMzOAjEDXyx7gVzRfTNuGaV3zoKFDd6YCWDVZIwBq2bPiiJbRdOg+RhEUbYuPrZT3s+VrNevYpu1IwXjdpzG6gftaC/iUZIH6QAAAABJRU5ErkJggg==","e":1},{"id":"image_31","w":191,"h":246,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAL8AAAD2BAMAAAB1k0uRAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAnUExURUdwTA8RJg4RJg4RJg8RJg8RJg8QJA8QJg8QJg8RJg8QJg4RJg8RJujnRRsAAAAMdFJOUwDzzeKbtg+CS2YiNhVJDboAAAqQSURBVHja7Vy9jxtFFLfX9q4/UoSEHAnawpEQkLDFESAJYQufUvAhF+FDCNAWdwkfjYsLCAkJFz4iUUQufERpiAsfCIXCxREFaK6xfUfucvNH4Z1d2zez82beW/u6bJEPe+3fzrz3+73fvJ11JvPseHY8O54d5OPfu8f7/WWPnfpg9RgBHMbY4P1/jg+g7bpjiOGxQdj+MLMyRmBnfjyeecqz/UzmpxCBXTmWQWyxG+M/vwyniY0eHMMg6oNe+FfJ54P4fOGDKLu70T8qH3KENx98vViAAjucRJuHmo0WnE59Vpv++zuOwF75eZEAwejIf+5FCHu/Li7W9nSG+BGlK2Ov9hYXgmXh/49ihCvbCwLIsvWMEuHNBSE0mfzKBGGvtRCAsRBBCKNFIJRDIZKPOzHCcAGz5LCTilfjbGVn5gewWFX18u0Y4YW5AXZYR/n6SoxwbW4pZWrO2kGMUFt8Ek2dwCJSqcKeQG8V/ZgOc5bLQzjB3Ajh3DwAOUmJhOOrOAw35ioGuk/HhBu05kmiju7tlbnD4A96BlPJj3fSV5uhQUnc+djgGEd/M5a91bRJdGA6ZXOuXD3BXjTOojfPJHV1NBDDkG6SPLVYi8fv0RDOpkkiFzXyeupJKjGGIWkxnqQ05WywijsvJd3W2AjrbbgmdeieCKkylag27NKTaBc9mfyokpNoHy+7vH6uEpWILWHPjTPpLDGJEESeHLdSxHmNNKkBPc5dEjsdeoEOcESeHBtkPrtIIk9bDhzhMsF0YYkskGGEXr3lyfoV0FLVInPfoaVqluGJLBToF/BZukQEqHA+D2poeVkmAsR8Rs6sT1ZHLsBoto21NEWZtfBmdVyQGblETVK1iqMBS7EOzqMFIzdOh3S9B+QQslSlENiGGMJOKqczZVsVM9TdVABR9Rxi0uEgFUBcGKoInh2mXFzjhjA+67+UC6O/MEMYlxtlJwfVZMIMISTyckqAzBZCkfJEJ/hncgh7RtWiWJCPFEOoGZSC5IquKKLwxKAUFDG987IqkToGALztss/XVFzY1/ZZGEM7nEw+4YY4nQcavW+P38f7uo1ExhT5HC1pPQVYDu4nkL1zqi/QCn5TA/Do0wRploG6UNWJKQhfeqsnL/ZrwKpqLxVA5t4X0smqrlpBTzZPB+Cc2hZzcgR6pHOacqCRw5XXxGvdhcSAgT05XytWBaGzvwEwiq9IluF6owEoe1eFuViGVXsIA+hq/p3R9lFOqbOxqAuzAcBxrx5Nl3WNCVOveGyT2gazIWyBHpNnqnolWTYB3Jy1h+ow5z2QzSHAgb6DMx2CCyd0DlyPVEwAY4d4bWoPdvUWaRtIgH2DK4hrgKW7lCZEBTOA7bGXJ7XvKcxISPFKRoBx2Y2asW2tQ/OB2hwCHBoXAtVYlqsGG3lSvYwwed8gGrun9TcOMEfh60/Ni+IbEedbpoVtJxVAlJ8VgzvIqucojwAIq956eCkjk4tWzBEKYC0sWAWTUQ+UBgkF4IS3uHKmtVxWyTUUQBjAy1mTppSUPjgEMK+gxkk+7BuvJMyjQboRhGd5xqXWmqqu4QAiITAttTjXXkwH0Ea1h3xFoiIBIve2bu5KJIoCEsDmBcW0ULEUhTPPcAv9JkN0ffhlHKYDsBim61NPGjAHCVDEjCAi83YCANWWDRBBjvps1QS/Ud2cNYbp3yaDgAZwUM2nZuKsksnZCSzqYIIgWsgiukPcxfR9nAThK+jNBhbqTFe+DBt9Oybse+hW9DMmPEkHwBO1ikm2kTwmZF82i0m4QkKzXHRn2cGoRTlBNR/fuvYxvStPrsEevtvSxZC5K+d9gO/u5zCJmpMnso5vqXFf0sPoXUtSj3VkEDxEotpylNuEtmYbUzw8ict9QmPWwrCyLXE5S2gtVzCVPytdRZbSHMcEgUd5VUwrlTldhYzPPobL66J4KD5TvPTu3dV0QfDFSXfUJc3+/vXnLn0ib1CvMAQtm+KclCB6Pvx4rFKnX/qhRw1CQ7zkMqiRlW+5X3zu0nurQg4+JYqFRq8fx/soT39GkSNHKvzhl4Dqcz7e5niqM5tQ0xYGW0ojTxe3yvUYYXABXxN8MVB1vdrF++wZO9ObpIiJl3XxnK5B7Sa74NmwFRPfZNT6IrX6JjH6251s8O5EQjBCpNEeRYy+8WcIfI3RMjuLkYhnSO3i+RlCgLu5eKTyFRACZl+fblLfQVDNFfLGQdnfXyZb+TFUEwWliDOPf8Shfh6xlpJymeGs15eTZDK7hIZYu32k9crPEJbNeborzlgrQ0LYN+fpUJwxnHH5akpqs0MbiD4DaVx+myAYplQsfBRfsYl7WMAXEiGH64fMvLL5gkS6F9Ar2cx0r+MBZUVaIm3LszBRbgiTYjPS/pzbzFw2c+IgXdIt5eiJihplTe0RlggTNixT1otN4taKrpHLZXHW+8TdJwWzYot1L0shQlyxBuaKUBNC8oQAIBEVci5VYq8pQwlaW5h1IhGijsdTI9OWxCG3CABWoow/VCzU9kVtukEAKCXc18c97SW0qbukXMkw568oVoJDcUCkjWTykOsXZT0Rx2hRd2rviEPOuzXFGmGgm1OEvT0Sw9vJHcyu4B5tl7QHKJrimVg47q6Six2I2YgOpDADm4qneALxG5vUvXBHL9BxFTkueaEGI24XPPr5TVU7tS1eco4qd41ZGhWVewkaUp5R08iaFd1bSo8hma0yI6bREQH2lOGTzZZPTCN72h/Iqz9pSWW1Tk2jqSXfUHsY2c1tUdVomka+WmXykvpY1GcWJ1niAN1guUvkUItaLh7yGlBKKnIZdokb1J34CgNgd5ctJ75HNF/xF5TBHVxyG6pN9EY8sXs8WZZQADlqlOs8/7fAai6vXfPUKEdNmgBUAE96h9ecGjGNToYTMYTLdkt+geqADzS3WhP3JfrEwh/6hj0LVpjEfQmLGoQwTfqwC+7KbxWpz3SGUazDF9VOfJ1HDEI4B5qNkjuJBG4Tg9DQ90X6CQCLkRab0d49eNDJWzcV4oN4Bf2je42kuHm0ohPtAQXXFSeSAH2itYie6MrgAQqMtiD3tE2LbBLAdmmJWtc+MaYA4JlNkOwdbfdOBZCj/R5CVtuZUgGUGMkdWdrTVQA8bHgyO1riZFVvrjHKs2kVbdYpARzaHGlvJTSUw/NJeeRp7l9xgKT6bzGK/6rrPL+6FuVVO+W0ROgQ3/QoepTVZVFbHaAtimbndCnRVSdkiRGWg3kdk5tA+QoYvndU0vlZyA9YhDDbuiZ2AABwzcb+kICvURbw4ZU2gc2ehpbgwysO4Rn5pian4SczAvzPOezANVkTHws/hCwMUNFkmIceggWLkaPhSA49BM2jzQVNqkQ/VYAZQhEmpfZZxlvoIbignGqfZYyGcBlHhA6s1jBdb2F/bKEJAjT1su8hf/+lDwJ4en9iIX+TKgcG2TXc5glwP4bkQDfUjA8l53G/F1F2B/Dn9SvKTdxPXvgjeI71Do7/So55/2owBGlgItJNFBeae2DJN+7mXsG4vA1Y841aU/ERK6rfD6B6Zp5evglhz1CdnYtQlmJ2iz/SPM45OdQXcA+5mnz8xoVMmmOslm8jz8ykO+6/FI38f3F81AyRkO+JAAAAAElFTkSuQmCC","e":1},{"id":"image_32","w":182,"h":234,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALYAAADqBAMAAAD9kqK7AAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAYUExURUdwTPZtg/dtg/Ztg/Ztg/Ztg/dtg/Ztg1P6lZ0AAAAHdFJOUwDdtyCTPlwlXJ6YAAAEHUlEQVR42r2cTW/aQBRFB0NgG+pE3hraxltQFLFFKSrbbCq2SK3iLTMB3t9vXEHrgMef73RWUSJOru67bzweezAmNxL73UBjKCLuJ8NOJBt3BP1GTuNuq84O5O/4qs3e/GPLA2L3abgtYjcgPbhga0rfyNV4QOw+S39B7NaEB1IM3zJ2q/VR4mPL585sL1psV8+HfnbnggZSBp91Yo/K2HLfiZ2WsruFJSlndwpLBbpLWIZV7A71DCrZ7es5qma3tjytwW5reVKD3dZyqTXumZi0tzyoybYzJiZtXUnrslu4ktRmN3dF6o97KCZtXAmasBu6MmrClhCKSfN5JWnEbjavSMMRQjFpWM6BcMJ7wglfNGbX7860Obt2dyYt2HVdkTYjZCLYQPhAOOE94YQvhBOeCid8LZzwSDDhfRFM+LA9u1L4QDjhPeGEL4QTngonfC2c8EQ44ZFwwjuyy4T3RTDhndklwofCCe/O9gsfCCdcge0VHggnXIPtE67B9gnvCSdche0RPlJhO5AtL+qXtApTlNiF1dwIJ1yLXSQ8VWJLDLIP2kuIclPU2AXV1GM7kH3dm4rsUHfJVm6KIvvKFE12CLKd7lKz1BRVdgiyHci+MEUVfTHR6rIPIPvjRCugKRFoijLbgewPKYxAwxPhDNdmO5CdN1ydHSPX4ivD1dkOZOcM12fHIPugv0YuMFyfLer3JLmxBdmx8j1gYTFHwhUTYIvuPkRxMQPhikmwD3r7bN5iEmxR29f0F/NGuGL2CfaOWWz+GUdoYZUPSgIGZQ0GJSXYS+ziIHKLXRxE3rhJ9hxCYiI8hxCZrAScrE4hRCarcwgFDGEEhnANhhBp+j3Y9JZbWYnMuKY/BXwAhpBpzB3YmDuwMQ9gYx7BxtyDjWnBK6aAV8zTlsEAbEymef7DlScBGzMFG3MBNmYPbEwkhA5cWlnwfsqS9zwzMIQzcBmxBdf3WzAoSzAoMRiUmNs5PU+ySFB24I7YznC7P2+GK+YB3AY/gtuyR8MVc2+4Yu65Z1859gZk6xvuDGe4Ax82OsMZ7gxnuDWc4RZ8cmwNZ7g1oOEGNNyAhufZc85vbVOs4UyxyDunReyAmk+y50gRx9Y1xRnOlAu2qin7i7cJ5yD7BmRrts8VOzMlgtjZo9JfymtNIOJH4MzN1doeeMHtjXsB/++9FBHxW/DkQFx08ivi2FqTytJwwou/5UlHuOesnYZw5zmgNUda/iQ8QVrn1EARE0ElV/zfftG5nK7kOOkcKqXGuzo7hePSdvn49PT44/V1tZpUXBkaxzD/pvpgUisntWMYegJQfvB43lT2h4+UH5iuFcPQ85GqE+rzprJzH6k6Wd9fZeN5Op1OJuPxOMpERe8/jCfvv5o+Z3/8dvWR50lkP31ZZf/zN2hWl+pHzkvwAAAAAElFTkSuQmCC","e":1},{"id":"image_33","w":89,"h":91,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFkAAABbBAMAAADq7TSXAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAwUExURUdwTA4RJg4QJg8RJg8RJg8RJg8RJg8RJg4RJg8QJQ8RJg4QJg4RJQ8PJg4RJg8RJmN7w94AAAAPdFJOUwDq+/Tdln27qkljITQPzPlUNIQAAAQ5SURBVFjDjVdNaBNBFJ5i+pMmKa0i1FaI1VqrVqKilOJPigc9iCSUoscEETym1oMgQouihyK0tkeRVnv00FQRpSLEiuChYFq9CVI96EUJ2U3aUKTjzu7Mzpuf3XRO2dkvM9/7+d57i1C19W1p6W0ebWUFr/zYcXyvtTpuV8WGB+MxTJfxpwr403YGJf8pZf2wkUF6rnHiwROE5g0/dOgmPbc4ZptYi0d9KP+k4LMz1N5Ye1WwcZ75LhIte9IYdsDmQ76XKHmh71HKabA3gmf04KcOuCS8TuFVLbheB0ZzuEcb7ahDQ7p4EmvNHFA5k/UCFzXg7443kvL+F2xMePH4q7zYhg01mldtcJt6Zw3G/fJeg51K60iLPiPvFWzSaQ06gPGGtPXV5nER6dHdUjJFvXgg1ITxprjzwc67tBdadHgwTtC7kFc+mMLGrJ0eHtWgwbo1rxy9ijzROAeepwi4gnzQIPRh++ikF7rWegnScp6A15AfmnsrkvD2HmOShLHCuAv5oY0kUKnv0bb+kpAW3u9TvJog+hlB03R/55FVLjoUB+l0C6IW8hydhjayMN7l1oSut+RcNbjocet3B4Nk3MQK3th3x9WlG51GIrBTbgqwRK47h08igKaRXybuc+O6TD35KgpEt8KzqiDkUwDbtfpNHIr/s3We0x7qxFRtwgfIpgUuTYA6iA3OycyDIJs5FBkW9ZxytUOifkhIt1H0iBTDHKzf1GlB4pEh/sIi1kx44D4QpQTTPAkN1HOjdROptCYsk3HmhwwW61DQMo/YvRu2zxiTSlQSb9jpq8WseB/+x5LVhG9CDrpdls4eli9il4irhYXY1sxoN6vodqnYU7YJQc1kxWTWCC1SUBAr9VA9moTSTqp6pYwsS2GkBExm5FGlQfRJsozTUE5z+XL5G1JvbWQErHQxcnLNL2uqyREayQ6ZorGqdEunAZLAVWQiSpOeptWE6KZHJnJQRjO69bJLCroqHqf3BSSW5K5OGUxc0s34p8UOzSsLLJmHnblDdGBKR2SFuoQoH/bBCKkLSoFNMQIZ0V8NOo+QmJjsb/Csl0T+H3+0XHguGbnOqiscA6xH8xrJb/NXVhBOD/N7RaRt0hG2dQJGsp+hy2LY3dUKAkaTckTQQo0LPfb7/mWmpZhrm4iepNjOsbyo9w3XrDUheyQLnZCweS0loO1RqTOtaJK1nAxE22rvlQRM8qzEvVMWIrkzr8ykPLyLEB3QyMa2ZYgrrgKP2VAm2xhoMwEY+UW5IlL/rQHtb0JfJXXZugosLoE3Cm0yL/DqbrWIIkCXdSLrghovgnxVaM+J/S4DlDaO0xrZlASR8zY8XtINdqeFZ45OdWlGevEjKsE/NjKXZHRGns2m+GD3XvF2QiruViq5Nofzatil+T9SaPOZAg35utetnuhZzafPY0/0QG8WbX0tiDr6DxmMoWqtapeXAAAAAElFTkSuQmCC","e":1},{"id":"image_34","w":85,"h":89,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFUAAABZBAMAAAC9GXUSAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAhUExURUdwTPZtg/Ztg/dthPZtg/dtgvZtg/dtg/Zsg/VshPZtg6zo4F4AAAAKdFJOUwDgwiCnQIxcDEzztAWqAAABvklEQVRIx52XsU/CQBSHq0gkTjRsnbAjkzA4E0McmNA4MZmYdGDCxYGJzYTJzZUKiL6/0ivt1Vauve98G+TLL7/37t27V8+ri8Z7dHMpfnj75NVH6+VSdMRXtejrWArRrUMfpBS7GvS+jMoHR0UmHJUhR+XLjA4MqHwb0WZgYo3JNXpiDFNyd2bUlNygAjUk1wiq2P0R269C5ZPVwFiIqhoc2hI7ULGEiR0XuFZW5lxWHrlsibXIlg7ZIltkbbLFq2yTLbBWWWlz2V/WLitrzZ4KZ6ecBRZyv/bMcpbI6vqCzHJ2Stght5CxyELWv1POMgvpfWMW5I1bSO98j7HJLGkyNKa9oFloYcstHObvCWSTub6C7EaxC8gmrT6GrGqzFkSTIz6nrDq2M+HlXTmUjJYheWJnvAyYnTuUd8nZrUNH7hzYrpFde5UXM0BsujwwNl09Hex6DnPEQ7Ms23UCXF1Y364DO+GsXs1I73QcWL1tzbgFwmoL5G7mC9+KWwCzZMN3ouIn1gIMHB0XdM3JXsKevcfYA9v+X259XDIlvH+msjYbnT+fCtdRNBqNwjD0fT9WUrHvqx/qryiKCrI/PdaGVqEjP2MAAAAASUVORK5CYII=","e":1},{"id":"image_35","w":119,"h":114,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHcAAAByBAMAAACb2lMKAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAwUExURUdwTA4RJg4QJg4RJg8RJg0RJQ8RJg4QJQ4RJg4QJg8QJg4RJQ8RJg8QJg8RJg8RJmr5n+UAAAAPdFJOUwD47cbiEqIm1Ga0U409egyMdCwAAAV4SURBVFjDnVnPi1tFHJ+mm2w2yT6K6/qrP7J2kdKDvnioehCSi4hdIWnrH9Ai9CKyWShePLgIIh4024r2ImzqxYOHBMFj3QiCCqJRBLWldKsIHgrLewnbNNvN+GbevPfmO/Odl7zMaTPvfd585/P9fH/MLCFTja/JlCP9192L79angs7+8yT1xvvTYG9wKKUPkkPzn9NgJLb7hh1iaSchUd9RaRxKhJ1/NkIu36H7ibbbCKEPv0lSdJgAO1cNoM5HNeKBEzBmhdjH/mW/UwkYi7Cv1ogALya12f1CzHjg0YRcBdjBRjA1Q2lvMh8FPC90w7msZ8VE2rgmsE/UosmDHuu1CcDfCuwj8mTOm9gYj72CYUnBmzk/FnsOxRLLm1ofh80U9f1yB3hzS+OIFk5aUMmZnyCuBNGDrpaMvNl7E5HV13lNe9u5H4s9KMIIC4HimDQ2J5LOKYKDd+PALR+7gj6048X9FepgCdwf6+GBIWFU48BpP5TcbcPzRlxYXYkhS4Ado9E+9hiZAiyM7plDtmwG+0w72yQWjH/a8pl+mcSCaS1GHrEKKpsKZdb3Unsa8KwfxO/FBk3DAP4NGv1HEvAcZ8sJY/iFtkGeGPiOwnRrxQSuGbQlhdvmoIZHFSKSVQ6WcvJZNEGj4BzHHgGOOxr64Xs5kzio/6jTBvsYhh3N8zLYxXPe04B96opNf3y6LqfePrpwHzA0WxQl7a3jHVAxBujC6yo3Tb89eAbWqh628EATE6tK6QvuBnToLkZ1SYsxRvef9KRi4gjxsZaOd1hhsWx5YdaT0D2tYlN/g/LYYgZeAwuTA1qhu8ywelu45s2dU5LwO2qJnS2iC5MztOfV6WOKNUpxT6E7ZvO9v9VSuap6tEHxRiNF+0XVLw2loeGxiNWfGcR/ttJK7bB3njLkQ0U4aQrTNqfLqRsahBNKqqIwqLhxj2MZ54xeO3KKMS3TkSVd1fP/DJS2ZfATIZcQHzCB7QPbKK1462ALu2oK3IQCawi6/lMtf817cBgrZhVoNevKfl+o63LoILlT0kgqkHWhuKL5SaOCuZl2gR2+uhogbrmIK1r9pnLinWcKeVTE5Un1tW685rJRlchSV3r5V3FUfvvuTz9fBZ4aAer7ofJeijbHmCnlX+cnbmd5Q4rmRVDzDod/Q4vcH4rBca7fiZJsBTiqFEVXR6bLkQ7N/bbuqZQcYamAOj944OBnjTw49u/IOs9Ejl3TwPRD4XsXCGZJDux2RIUy2HHjgLyWBaOxHERRLjqrP/fj9Vu3bl6/+dnFuu+be3J0uiCt7kWJyWPj9FVd7hU5CY9ApPeiPE6XP0FONpGhDZjBC4J6npge+lLLDgXZN3yFbfjljgiWYRfL41KgZZRUyBirCCc3kbx0W66QKbVQb3KZnDXUAC7OJYLK3P/aA/+do1g2LcriLKvVJMeitWBKxRlQLdiX2srh2OXSHGBWA77U0sHl6nSrhsrF9bUvp7hdLbN+SqH/YL+7bm4vGIUX0A5DnNmj6rql50dvW7bpUgDGY0tn1W8EHbTFXwO3h7be8FsxRyMgEax/9eOpgl57AokUsDWqaK4PduSAX/vYwQe3+jZ4ksJorZqs5k+WAHsl5C4Ct1pR/BaiJMtotRKnq8jRbMZodRm2ymXkmLKlxhkQQBMQO0Bajp7Rahe2F0Ok5Vg0nl3vwxdHiIrOG+8wmhC8R7TOEr9AuaxK2dZvxQqG61TeJ5wYs7+M4XIwCw7lgoNDGhgP5VXtHwEtXdoZ3FH5onbZuamLyQr7Cs3JQy1fqXExb5cMVy9OU6NWqwvf1AxWH9E+6E52O5/FLm3m3pjsivwX6pwiU468TT+YFuuVzlemxpLMizqL/wMR04Ao3xV41AAAAABJRU5ErkJggg==","e":1},{"id":"image_36","w":117,"h":110,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHUAAABuBAMAAADrO0HXAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAeUExURUdwTPdtg/ZugvZtg/Ztg/ZtgvZtg/dtg/dvg/Ztg6hj0LwAAAAJdFJOUwDgH8CmP4taTYK8sgAAAAI1SURBVFjD7Zm/T8JQEMdroSIbrS7dQBMTN0hZupnYmHST6MKmSJq4ObjwJ7hRQcj9t4KY8t7r+3F3Xb2VfPq997177x2t51GjMx/F4XjmMeIDfqPs00Vz+Itbpug+ljQyyI8obGloKqCwIi1VQgEe8OgTKIE361FF8WZd1VC0WUFcZzcch0lGa1GABiimSL4BhXc3OzGg8MypDpb1Yz47MKLOprTIOtkW8Nkplw2yS0vKMLQ3xQUw2QnYY8hpCidrq84heuyMLawzYzPrztjMHtp4a2WX+LMNyRqPCgQ7ADaLMcrkFU5WyyJltSxSVscGMZvF1Ue/j7AZa1isUToWL1tjCbK1c5Igq7IUWZWlyKp3WcpnA+CzAz5LckqZN2iy0pxDlIU+8p7WRIm9px0zITXlDd8paQZOiewXt6fk44qasriNqCkLbUVOWWgNcsplg5TXDVLecntZun2nwC8RebnHEtGXC/wKCTanfJsZKVc2t4Fvc5fOVofkgoyu/q2SIuZbtbLIfjusesGMR3qrNjFmA+qtekVtwAXVKWED5uQKVVZ5MZmtrPIbdEanwSY6bbDcNn+59CtBeCXa4qfsnfBTJu9e8S1ul5+yd8NPmXp9Si+eP2lsJI6gC76s98aXJV4K0qB/BnyWeBf17H8w1jnWqtq4XvYtE3xk/w8YWUYX9YuEorL/2SgcqX+1r4vsLglDCMNknBUzy8yE+hDiF8V898BktHsk7B56niRZdl8oH2B+AHCfJJtRpnsaAAAAAElFTkSuQmCC","e":1},{"id":"image_37","w":216,"h":280,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANgAAAEYBAMAAADMkSXeAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAnUExURUdwTA8RJg8RJg8RJg8RJg8QJg8RJg8RJg8RJg8RJg4RJg4QJQ8RJoZ4WTUAAAAMdFJOUwD26tpKtchnhBaeLfM6b38AAAzGSURBVHja1V3PjxtJFR673W7/4BBEYDehD4PCahdtHwYUxGH74IkEQsiHCAmJlfpgsVxW6sPMHjggH2Z2JSQkH8bJsgeYw7AIJIQP4yBAQj5gOzOZhPqjcFfZ46ru+vG9tj0SviSZ2H7dVd/73vdevdezt/d//fr8T5d3ZuvfIfv4jkw1f8WmH12d3Ymt2qds+tda9Lc7WcKIzS729o7f3MGu/TBi86PFn41w57fW/CxksxP+19HNjnet9lPGph+KvzfYb3dqq/Fdxtjj1b92e2u/jxa23r79Z50d7c7WP8KFrWsJg+FbO7P1u8zW9ET6SX/a2aUt9oH8I4/t78ZWi9t6qGKTXe3EVpBhg81yy5ayXaxjO85sTZ/mfjxh39mBsT9mtti38z+u72IdP+G2il/cZuxk27a+YLoNE5v2zW2TFAcie6r5rwmb7wIc7F3d/9X111D+dcptXWtJt8bYzfY3bGoAQsy2SVmB2LAPDP/dZ+xge8YSVqQp6VVlW3S1F0bUr8I12xplWVC/imlsa9Sfclu2GDli7M12bD3htuY2qTFcvOFyi4t4YXuPz7aEx0TP9Sq/hLIGKv96LqjDva2zLQhSYBEXrzHwHvdr5ETiios3jzO+G4krLnYutTODiF3uvObijUlEuBgSP/obg1+QPRQ+vMUbX20BHZBQC9iG4PchF1u+Mv26ichKtZrU8BqwjZhfcAfKQlW2iRJpcmE/RVO91kabNuY39j78/nCDTROkSFCfyQabdsxvrId/YFh+0xqGLMLuKCU3bQBFllwyw8pVDlowKapuWYoeRyTYi1d38ZGXpW/sPu1DHg29qsihJgsZF5cQdIKByWE+ovmKfGOzyzIIflDuxuj1hgorocLFjZ2VWv1ZKSiWKKSUcetRyRsTEuvgbm5MSKz/0lmx1I3xaE3Kdxvlb4wvypS6FCVvjIwQEaDf3yv3IiLkkLNi2ZSVxiHtkG2S/FRIQfBZGbpX07Q5adFZ+UJ9FmWmZ4QrY5scQVDEY8LYZuU8gg5pkSWVzkvvEZhqo/paBc4JhUP3NjHmwQndkJXURyqzYuzIc6T9jYxxduyguHcx1R+AC75Ace8Spj/bTuIkApnDI4N3AQ0OYJ/zvUuJfdHbCvabEO6/PAGwfwV5iBP3tUdnAAnNMHi4pEf9oZMYEN5vQIFs4NYLIRA2DpECSztyl3tid8lQVFhcX+UDuejIHWQgeOwdA8QJOFoC0WIMxNWKM7MOIHi0EKHsLpiNITlwiBSL686IBsFjL0U0XsPl1T4EjwYUWNuu8Mm1h1M2P8N0V2gPn0Jzd9yEBsl4R7G4igSXrO4OaaHUvv3cyQ4ATENS2U4h3MkUADX1X4LJJjuFcAWnOH39QruxmHw9t4ItLmjuxntaZ8Xqe1a+ammc7KMj3epgktLKV4eaEP3kse7+sYyjboN2pEnJ/PllEUVgpt2ykKOvc7Ja9HFxccAswHbe1NU6WXJdZDQwSaxZyDHSCvxCNIngJK9pNubrI1k9t7INhrfOZEx7RljFLC88yW0ZXLCIjKweGURlquq6ASFLjEzKsWXSA4fqEUJEKCLEphgzNmUTnpKqBXgRQASRC9NVaKV5oNQBPQI+eIx5alL4N6aV7ykwukSNDQyLVTGHzYGcZ6WUKoLpMD4xp+xVCVOZSLkhGdvXM4uJoQOpoOpT8MHXfN+QTuybETyXVhvGx95E/6UDm4TrrxE8IBU8J/p1CG263FvXbyPSGcu51phvFcLBrVoIaEXIr2iNje1VlniFxzoJH3yH72m/bQagakgrDGqNBcyeJN4qlxGtPycz9h+txO/Z8w3OmzR8cGOvdcC31kcS4V4B8XRRayx0fclQgL9OPDfVGfOdBYKlAiTiQ2ts7D4vCDlNj4jnChXNSqTuPFqEwYh4AqdBY425+w64x9SotX6Nn3lALTPbtJs69dRUY6wPFAaz6uq8Qq2/a4g4QlYn29cB9XimaIxLHSe7ZvQYEo7EDPGswpCTLs5o1COTYqQeQYVj0T9BPFErapAQqr+3hbF7JGMFdeUz7AgvZPRTroJuHIKnQWmJQ9CCIk7AbRctUSRb/DO9nLdCtNBl9J7dJKcyfXQnhozeuZXmWGCMtkhV6WAsJIMJujgeY+Shl1yay7cMivQ+o3c+5xJ4H75ea3tw+8dnQGliCPcbBObY8K+/fO9rHZOYyG0ZFnzrBjA2f/2LkL1zZKK4ae5GMXGmj5zt33xr8fN3Osba1SxX/MD4rqvb3J/wquHXDa7TUMmpijciphowfsb58hsdrN7YJ7WP55nxSxFPj5z5yNrFMQrSTDOIKcXphZUHbtSIeLCH+rQaYj8V4fSxneFeqi6NhahqnhnFRKT1JFaV+hW853GSg+0/hS3rTL+q5AZ4vjVQCVyM5rJ5B9c7EZ5vxQqtLSci50fOCzxQ8AFKmFBZ8FPrlKI2UBOihprgig4w9iEldhLw4csorkXAbFg+dvZxiasgXyziG2Tp1+EsxlXFubS7vmMiUhthmgR8yMiPwSEZ5Zy6RVAV6XpFXmAbJlbgWt4HtF6zRr7obENChSdv7ATPx9vrtx7D/YHKKWSC95y2bjlfjF++hYLqtewGYD7u3eJ2gDfwyyfHNYY3clZWLCeaLLEQKJ+J+4QW1e5qm0aEJkv5tL9CyMdXRc0GpXtUZqsuIR+Pl1wwoCTxTGKrhJAChWIRghAILLJEmso02cM/l7nnIaWRuSVtU42Qj7eEe/L+L3jSSCYQn5CPL93MI3Voy/2NVQIYl26WkooTcoPGhIAr4WY+rZ4kl3dGhEq2cLM+rUM7kQBImUvgbtYOaVV9uTcpJFwmdzOPWLsK19kYZUSszW8poZUbZZ+mjDZljPgyIA7JyD5dJVSi+KnZkDhyIfv0OWHEOruw/ZQ4ky2LAsKgAC+W/Jw6mSDHacr8bHZhp9QCoBynI20Z6XPj52LqAUIsrYS+o/jJhcmnyRM5UnOjoXGo8f1Lw+eoZXbZgKkL/PSXep8mV75lNzPNdjQeHWkTQfJ0Y1VyM+MQ1el7+rImdT63ItW5J6aad+urFzouIE+1y35s9un0oe4iyeM/qbTJiTGaPS+434QguRUEn2hcLofZ6EqzItRhYGUMwTIlcJp/yGRSYuxNRn6TGVvmFuC7LhIP9aEHMvJtnYfNOHdrYYmxt3MJ7Q1biD9Ub61ZZuxNfpKGb8NyS2WmoMx0mDzM4VlXJlVurUUeIFY5n++fOcaPlVBXp58uicFLmRRe29TUlQosokerEw8V+9UqbckV+lGWOqE1sRs7lAvNkxKPFlGot2tXFL7cETgo8XQFmYZdTwFqyk8ay9iqDBiP5Kvt2XXYlXSV1EcQqAQ1cmy63D8Z0X3aV3ggcTBQIO1pSJ+bVccFUxfC4lsL7RI0rA5XpK5MvHv7hqAEW6k6wPkArPrt21u65joKGLkxq++su2rr9CndQI2WkdNRk5WGKEGNuVmwyKwK1swvnKMENeZmV93G/FUB+Zwep3OiNHJSUMZY1ytcdmjGcjOXQIddsjTSJ/NwMzd3BhgbLoExIjfT5NMxwNjq+JbOw9Vc2Qkw1lyWamMyD3dzJbgIiFHLTaPzcD5piZ3QF57W48ZuNiErzFidK7A2+WF7hQcWxACeRcmbTvpeviyZIp4aZzhskCVqIYNOEGOZUDnyycYKSS3UEJzxaY8eYQp55gARntlNPfCo1Zbi+G8foXKuPqpU0q8WytZdKEjFy3bek034QwQpd/jNRkUm1AiTFtYdaz/O3jUiRphmca65AgE6QyK1t9wvJsUeZKwmilbkRvZXxWsGSCii1/40D9xsYfQ6ondFa6bDwcmMCbkeF2iWvYkVzj2wy8RC+UsCm2HUQ4udXd2pXIyBjNe9XxFd+qlu6zvYZynNw21tC0Ef41feFv26dEohSdAeiBBC7Bxq/beKfUmDaCzR3oMP6piIFqhDLW2j83gDUipoGHq/zYiAuIurgqoBu+DYmk/KO03rAAbFgCRBTJPhXUxbBBQJYqwmV7CdDyh9Ep6JbsDKb0DRO10TmgKMYQMg3VGY9NLkf0BUrBEkiOWR8FiuTDFmedg9VnJoE/TO2OyTFciDFkwD653E3A5XR+elYL0TmuUK+LSDCNY7DVuAiCDsp7AE8Wxkk0DYH8ESZGKTsxMIaH24Xyq1nZt7UC/lEFUFNWswwji2iqqCF/aFihBHq4OqIPvVE/ftTuiO+C3QWN3BEWPEqwNQgriwXUdUWjOCjLVcwqgdIpufQBLk2CnWEsTYj5BaQS2aRo5fe/lsa79o6O/s7T9fuhb6wZaMpfOOe/Pvb8dW+xHwmxpHr7Z0Z8i+Pt/q7w9zeewP7tDY3tkd2PgfTbu5VIv3YsUAAAAASUVORK5CYII=","e":1},{"id":"image_38","w":211,"h":276,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANMAAAEUBAMAAABDsx5SAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAYUExURUdwTPdtg/dtg/Ztg/dtg/Ztg/dtg/Ztg1eFWmwAAAAHdFJOUwC63Ukhk/JJHBAqAAAE3ElEQVR42sWdPVPbQBCGUWxMq1BELWQ8Uaswk1ELmsnQQpG4dSjiFiGs+/uBxLJs6+s+dp9clWEIz+y77+5JJ93p7Ex4fNvenjHjqzFLBDT7ZIx5IcKaJeZ9LDESEFZD0g+rJZlS2Xob045M23rtWCLiKSt4StJTsEvSUrCHpFRa8x6SMbEG6qaPZCqdVt43FBS8MwNDXMFZOoSqAPPpKDgfJkmXVjFCkm1Ow4mSbk6j8skqeDNOEjTGnZkaUqU1TydRFSSfnILT8kkpaCGflII3NiSRKraST6SK7eQTqeLCkhSu4Mw2qGAFp3qfoN0Le1Kg3eepA6rEggpL1ix1Qi0ZTwQq6CZfiILz1BUVY0F52909KO9kuQflmyyPoHyT5ROUX7K8gjK/sKBMjQXl5YsbP5KHL+48Se6+8JXPo4gL4z0yKijnZEX+JNdk5QGoEtPPsYgDTOHoi6Cg3HwRFpSLLwKDcmnugUE5+CI0KAdfhAZl74vwoMwaC8rWggJB2bamKJxka8FcAGVnQQn9jHmATPE2rrCgzCsWlI3bhYKycXskQ7Jxey6Emna7lH4Wbi+kSJNulwvKPEOmsCisXA5VYfqZLWUKY16woCZqWNAUb+MWMsVEuxDVb7xdFKKk0UvBRBY1cik4kyWNtQth/UbahbApxlCRMGmkM+XSqBLTzzxRphhpgok4ykBFNdJvCwVUhuk30G819KsfMP0GokowlIZ+A6iCQyUYSke/3hlfR7/eqBIsKiX9+lARh8oxlPz8O3iLqqVfT1Ra+vVElWAoLav3oNRS1b0/yDGUmtW7KD39Ousxevp1okowlJ7VOyjFVJ3WVc6hEgylmaoTVKFIqq8w/Y7nK1X9jlERh8o5VIKhdFNVx1iqjq7Zcw6VYCjdVB2hIg6Vc6gEQ2mn6mA1RjtVB8tZOYfSTlW7HqidqoNVTvVUtWu3C23UC+eKknPFlnPFFnNF+/hlwaHUXdE+KlN3xf7+VN8V+7sDfVfsLwP1XbGfGfVdsZ9DUg6lT2qmK8CANWfAkjPgljNghbWlPWqjj3rmDHiFGbDpS4ABm2aRcyjAgIYzYIkZsGkWhAErzoCvnAF3FbziKjjFymoOkHbTPeH13X3cueNscOFfVh8AlF9ZeaF2ZXUPoK64Cn7gKjjjKvgWm612ZUU0iy03MVZezcJrrLk5OOZQmVcLDLmNu9BHNbdx95gBiRb4yqGaNR+g2zYLMT+51ZEV5nUAVXKoikOtuaXUmENlGKrmnlC0D0NSzID6qDWHijlU+zhzg7lCHXWwl4dzxRnnCnUBD7aHKDvwcCtPihlQG1VxqJh7zyfDUDX3olnJoY62GK4wVyijMgx1vJlxhaVKFxVzqAx7Lfpkh+Y95grVxYSTPcILzBWqqzEZ9mL+6W7kcyxVmkuPMYfqbNvFUqU4N3Z33q+oVCk2we4O6wWWKrUarv7rRtA5liqtq/be4xhWVKq03N57zMkCS5WO20vs2IKho0cSKlUqvhj65MEC00/DFzF3HMjgkUgbxuoqFlxiR9+MfHIjwoIS98XYOVmUKcSjGjkULtpgKPFt6jF2TtbY52WEw1pSZ+pNfDNHNKyJz1J8/7Efj4+PH3fj8vLy89/x9Ptt1MbU9fs/vvz74fX1dfOLb/+n/QNDQf0BKbgAsidZ48sAAAAASUVORK5CYII=","e":1},{"id":"image_39","w":156,"h":137,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJwAAACJBAMAAAArjUxWAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAqUExURUdwTA4RJg8RJg4RJg4RJg8QJg4RJg4QJg4RJg8QJg8QJg8QJg4RJQ8RJopBEywAAAANdFJOUwD42+zIg7OaET5qVSlQ6G/4AAAGZklEQVRo3q1a22scZRT/ks3szl4ebEzbpMnAVi0VZSCRGrywsKlBCjKwrYJPC0ErKrKwVRAfXOia+iIKhvogSiGxCD4YaGpfBAMb4+2lD3tLaPT7X9z5ZmYzO+cyM5uZh7K70/z2fOfy+51zZoUQQtf/EQleJUOeungvKbRJaV/tCzeTgduTTyzZgN2L3yYB1+gI8eU1YwD4+KV3fjsxnNmz/y18aKhDP/fBydB048B58fd5hSenPz0JXEEeuq/ybzt4cvnr8eGyQzhR+MjF674/NlxO9o/feHhyuTUmXF4e+d5d8/A6lfHgtBE4cd9w8dqvjQWXlv+OvP/Gw5PPj1djc6MffF7y8M6M4cBmEE7kVzy8mfjE8BDACX0Y4OnYeNtyAX74g+fAXtyMrsn/kE//8hw4E5O3THhYlT+mi3c2JhfLR3h6e3gvx4IzCDhR8AJ8JQ4/SQpuiNeuxClZEk4ULLd+WzFKloYTWdd/p2OULAMncm6+PB1DFhk4kTHiuS/Fw4k/3OpICE7cjZV9E2FwuhPedj0ioQTokwpHtOPeCYUTU85xX4wCtxsOJ7aiR7caAU53svkgSsMTAc7LvmIU9hwVRvz6xWkOWgnBCStiNKxocBknGpsJwYkdhdePANePAldwkjmsNsyIcG4yHyQFZwdtcJWTgtOilO4A7jAil21FyOUYcHlVG50wuIOIcGI/3Lw4cHop1Lw4cOKzUPPM6LLi/G/ePCvMuUguF5OCc5ilx+Z6V8Q1by0pOMe8Q47c2yK2eRVGetqx2l8V3Hm6cZcyRALym2B10G7Rsi2R4SHre32rHGimB9cLBNxXuCc2PvFNpaMUvM6l8gQed+2p4XySXRoVnKzB0GiKuHX3wrA/DcrrDpMrtmcXsb5p6T331e0OSsubZB49ht14fcY1qtFDVWOB1ONZvC95xk20QzSVu8Rmgep5at26Q+lHeCqX8b0HJWW35BnHfDgCrtPBMCg6Huj+FRUrGCknVzbxiZHKyR01Pa1jbFklg2GSDJVRHdgGluVpsjJqNKVYsrs5MKRO8UoZZyhJLBDW7eGugfooRbVnd+g2K2cM2vVaG9suqGBgdyaYtmjgiHMWzm0qGIu42YuCPG3b7FKDKyppU1SVuSVDpZGJa4YmmcnCouGaeOplOaHbp0Wastxg+gBN0jJcwwXc5JTWJInSkbR59FvIxdUeSZRCN1DTt7lxQWNUaxsttCbbYpl0h5NGCy1FqcXwtEfkNgyhjzSXeEpLugTjbGC9Y56fjUy6pjMoxxtsi2ebcI75KsAQJttEpZlMbmKnbfBLlxIdWw077UPwFfr3P358fXV19d2fXWabYygieNoUoCjtSXfRe+rST6qYQCYXfBxfhN4Zzcbsm5ePN/mKxwPElrvcOqaVPqQo8PXfveVu7trP1oD1ufNn/ae9CZyNaOOf3mZ2JZiY2ZX2ml/RypBTkIZWf8M1MCBa+o1jdLsGgkW4S5HAF694u3z//fv+VbIF0zJFk9oDLyRH/oWUr71NQU5OM3LhPQzp+u2ZD0jGHAgtWbWai1fxCWmdF7sSrQjDbdsiMbE2od5WWUL+3b/fyQTPpup2FjDDAk0CN3xj2BZQFhPw5RQ/Qjur/LK3rOhA+h+Vwqzkx1DlvjkvCRYQTi5G1ashJXe8jK8jhNgHkjnLjbRep24ibLEL8mxShqyiLOdAGkalU6AwtBDnqdP2nZJaQ7uLWcBRnPNcAaqi5dMAiVENcZ6yoE4sD1MgVVJhe03bgtk8Xj15kCo5bv0w/L40MYNYoC8xQ9akqjT3ie6sCVjFzrxHYesYk2iO0mCAnAzbG+5KZtlWCg4neclx3nD5RGyfqkCALGb6UbRi0BsAdbYu4Bk2VWrMDh+eLU2MgKPJusgEqgjcWQxLlTpT00cgVVhWKTF7QDtQ0zB09xi4beawKlAtsLPmYjvJPU6pAeqqhjw/YNW9CaaTKXZJ6qZmhSHEPvT1HAO3x3hDh3PsDjPhhM5HcB+TCVmo2xb0OOdVoHN6PCWTApWGhDnJL9RVnVUY0wOOVanH/CYjwzmjAdum/ZAndSVG71IwTuphE1O43MNhDZmjd3jzJrmHdBaECzFvMFDRN/cRy2/z5l1lGDtnwJJSvyo4zTSOTF5ayC85cgOefon+k6sM3ANMCXPXX2UkQ1sWiV6/cjf/B8FwcW3CUm/1AAAAAElFTkSuQmCC","e":1},{"id":"image_40","w":155,"h":136,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJsAAACIBAMAAAACDYSKAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAYUExURUdwTPdtg/dtg/dtgvZtg/Ztg/dtg/Ztg6hNFG4AAAAHdFJOUwDgwB+aPl/o2jT2AAACfklEQVRo3t2YQW+bQBCFiW3KGbupr67jiqutRMq1SilcLVUJ11SVzLWmpu/vl7RS1bALzM68U+dmS3y8t29mYYmi6O4h3RX7iFUZujqzgDH+1Ln4wsAt8LeWxZGJ62r3zYi7wut6+0zFAYUFd+/gcDEIrOCpgovDRZtx7cWhURouMVCf9TPmrQ8aHMDkxaDy3oDKW4DKm8DhJgw3m8Cdj8YdoN/PQbwEk7y9bUPp17V5B1DHUQtw5z0VF2C3lODkdmU4cffJcOJuEeKw4uKE6WZCnDBdMU6WrhwnsivHidIIwEnkrUGVF4ITzEYITjAbCKoVFzeZBrjywJW35spbc+WF4ibkBePG5WWgygvHjcoLx43KU+AawqPn3zpycSsubiQMDW5Engo3LE+FG5ZXq3ANFzfYKxWobu91uKEwrkCVNwNVnhaHjerEOFit4ngc7DbW4vxhzNW4hvMoG5+MjOu2BDWMWo3ztl6lx7WqjwFBbmd6nC+MhQHXEKfM33oxuG7BdZtx3ZZct7UF57ZeYsG5g7Yw4Vpq43ncguu25LqtuW4TrltbtI5bW7Tu3NpwztzaonXmtua6TbhujdH23cbgus24bitQB2MG6mAY58LZBsB1W3LdVtxWsWbRa5WYvHgZd/EO3MWLuYtndrvhtkrLbZXenP3nrXIhtwp5h3/mut1w3bZct/3H44E7tvO1Dfcxos7t94g6tz8jqttLRA3Deas1yuOeHt3DbcKcWut76DV58TbUbN3DqEme5zPIgSnOJO+H7/PgXZ7n2+37NPVd8e5r4NfBV0pvbx8fn06nU/6wTZFud/l+nue/b/dyv3PHSNPlsvv18uen7opfI/SWaA+ckLgAAAAASUVORK5CYII=","e":1},{"id":"image_41","w":844,"h":654,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA0wAAAKOAQMAAACvBAv/AAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAGUExURUdwTO3Vx8dfoesAAAABdFJOUwBA5thmAAABMElEQVR42u3Y0QmAMAxAwTiZqztSBxDqr1CKEBRLe2+AXPKbiEx7bTvik1AoFAqFQqFQKBQKhUKhUCgUCnWfUVAoFAqFQqFQKBQKhUKhUCgUCoVCoVAoFAqFQqFQKBQKhUJNQSU2QqFQKBQKhUKhUCgUCoVCoVAoFAqFQqFQKBQKhUKhUCgUCoVCoVAoFAqFQqFQKBQKhUKhUCgUCrUStdV+BYVCoVAoFAqFQqFQKBRq2BdJ794ThUKhUCgUCoVCoVAoFAqFQqFQKBQKhUKhUCgU6h8qFwqFQqFQKBQKhUKhUHNRz4NQKBQKhUKhUCgUCoVCoVAoFAqFQqFQKBQKhUKhUKgXQ6FQKBQKhUKhUCgUCoVCoVAoFAqFQqFQKBQKhUKhUCgUCoVCoVAoFGp16gI+hOHAfebiJwAAAABJRU5ErkJggg==","e":1},{"id":"image_42","w":1402,"h":985,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABXoAAAPZBAMAAABdQI9IAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAkelRYdENyZWF0b3IAAAiZc0zJT0pVcEwrSS1ScE1LS00uKQYAQXoGzmp6FcUAAAAJcEhZcwAAAAEAAAABAE8lxNYAAAAPUExURUdwTPKtmvKtmvKtmvKtmuqpWp0AAAAEdFJOUwBFyYlLnn4yAAAWmUlEQVR42uzdW3bbxhYEUNLKAEBRAxApDoCvAUQk5j+mq+Qux3GWbIGvRldj74/8i6i06xwA5GzGbLb42+4X/134gKg1uYf9et3/zmn9dvhI8Hwux9Rj/pHcTT/U6bRef+R41/ngGO+wXR4Oh7ePJK776/x1FIsw5fvt4erM/ifBzmBK1oTlYb3p72h9kF8KJbe/v9ObMY6HbxUeEd3vAd5JMA+z3PeP9RFgFYKHVIZ1X8BJBebu2T1s+kJUYO587hbLrvxy575bNLt/e9v52LnHnmHdj2Etv9xcGvb9WOSXuNLw7wJsgUbiwWuBRvLBK7+EZ/f//cHF4LJNw76vx5vjl0sK76avivwSVxp+OKsPZGwaHL9c23g3fZ1MbwS2hh/Hr6d3+J3nvmZuvhFXebVfWgjvx/Ervnwa3mMfwPDGJ542fQbxJWnZ8B8rV4ufw9sHMbuRsykTX9oJr/jyw77vxZfMTVlgePv+LL6krHmdvjQUXvElOLziK7zB4RVf4Y325hJOWHh4+/7sGtrzBsdXeRBe3Zcsz30vvmRa9o0wugmv+BIj5k0K8aW1Ra+3LawbxBel16uaFOwNm+bSe9q6rBNx7HvxJdO3vkW+ZUdvcPqiN4wSX6ObfYPNA3qDR3a4t33fiy+ZnvrGeVy94d5wbD29Nmfteu578a3PYrFc7g6Hw+6wXCz8tswkR7bI+M4Xh/36p8uyXh92XfeR4sVcYqd29Abdt/hI7vqX58lms/4rx07iaR29KfH9iO6Qv+UjwgtVvv1tWVR8F/sLjpLT227yAX7qJ2RXeXYv/XvWU8/vcUrprfmhh8VV/wieJv1Lt5M6eiuO7+LqAjfl/B77iakyvvPbflrsbefoNbqNFt6bJ+dpFuDJHb01nr53+U3HCeb3qZ+iVWMHb8BI6ui94xOTrR28/+S3c/ROIL7VXOU7v9Qypfy+TDW9tTzw+4BfxZvM/mEyTzjUunpYbtr+h+WhnvtefJs6eKc0vm36SRv5Gj/w62ZPEzh+v/UTN+rmbPnQs2Pd/N3j49TTO+Lm7OE/Yt56e3jqGetf2MWm3b/Nuqzxzdly0/L/mtZl5VYPXXutoaqtoHVZUwVxWe7YaDe+Zrbvl7jo6mFe9vsOG53dzGyjFMR56Xdg2/zlGTPbGLPbCD+I1+LP1pnZxii/z03/r6k4tFx+5yN9c0Z730BoZit+RJW4QzGN+26KwyfX+LHD23LEj7yx+H4T1k+sd22Gt7XNmeJQeHc2+r2hhuI7l9Oy+a3gmw53ioPlWdKy4ee/a6s4OH4jblG0HF/FoeTxu9zU8md1ioPjN681NHXXTXEolt+nTZv/U7pVUXl9ONzhUtf2EHUDT5x5xmFo/e3aaQ3NxFdxGJzfm/6prWZca2ntqziUyW+V4Y3fmykOJfI7r/WHxMLj63XMi0f1y7+Y5mlT7/+Ondorv79tDTX/MclrX7X3uvxeMO7M15X/LWrv5Ax9+nde/0/nrtRe+f3MRb80bHJTe0te9i9uwC1CfrI8dXJTe2/eoB1+NcIt9zF/xZvaO90Af3YPOSi7sdXX05GPqRDLddgfsFV7Jz3D/WgQ80NeHzsnplftvXMH7maLQ+SHGtgdvBTEd1tDG7n/csStzf5w0YjtDoY2cruDoY1/7R06QxuxdoY2DG5FvLhgxA5uhjZyD19DGz97N7Rha+YBM0bYmrnThsPX0IbD19BGe4evoY3cw9edNnIPX1/lwGdO7hPj8LVyQPP9dGizciD28DW08Qvv0kuuzsqBWCsrByzNrBwo79VTDliaWZhhaeYZHZpZmlmY8bu5re6lmdeCyF2aSS+/nduqPnxfXCBi57aj60Ps0kx6yZ3bNq4Pv/UqvagOblZQXr3Vwc0KcquD9JJbHdysILc6eLOCL/3pVhuxTtKL6uBWG+WtpBdbB7faKG8rvagO3slEdZBewrcOHtIhtzpIL7nVQXoZpMo3LKSX3J2ZByTJLb7OXnKLr7OX3OIrveQWX+lloHfpRfGVXsrrpBfF1yvFFLdy9qL4Onsprr6Nr7OX3OLr7CW3+EovucVXehlefKWXXJ30YmyTXiY/tkkvuWOb9CK9TGLp0EkvxjbpRXohdekgvVzgXXqxdJBeyi8dpBcrM+mlPOnFykx6Ke9VerEyk16kFwY7Sy+5KzPpxcpMepn4ykx6kV4moqqFr+8xI3dl5uwlN73OXi5yll5inaSXXNJLrppuV/idYi6zlV5ivUov0iu9FFfVwnfjenCJs/QivdJLcVXdrji6HlyU3k56iVVTel9cDqSXidhKL9J7B88uBxep6WablyvITa9HJJFepmIlvUivh8worqaHzOYb14PU9HpMh+D0Hl0PYtP74nogvUivm21Ir/QygfS6XUFuet2uIDe9Fr5IL9LrdgXSa+HLJNJrZUZueq3MkF6k18IX6bUyQ3qh6vQeXRGGW9WV3hdXhNj0WvhygVfpRXqtzJBeGGw7szJDeq3MmHp6rcwYrqssvb4/ndz0esqM4WbSS6pTben1LajkptfKjOD0Wjow1Lm69Fo6kJtez+mQm15POjDU+8zYhvRKL6W9ziwdkN67+cNVYZjtzNIB6ZVeSuvqS6/ndBimvhvFFr5IL+07Sy+x3qWXWBWue91sQ3pp3lZ6idXVmN6j64L00rQa170eMmOYs/QS6116kV7ppbgq172mNgapct1r30vuwszzvQxamFWZXl+mQ+7CTHEgduWgODDIysYBKwfPpmPl4FYFg1cONR69ZjZiVw7WZcSuHBy9DPSq9WLlYOFA8aGtvpXD0VUhdeXgNhuxQ5uRjcFWtmUY2hy9FNcZ2TC0Gdkorbb7xHoDsUObkY0L1HWf2F02coc2IxuxQ5vfaCN2aLPqJXdo27seXKKmO21WvcQObXoDuUObVS+xQ5veQOzQpjeQO7QdXQwurL3VDG1LF4PU2qs3kFt79QZia6/eQGzt1RvIrb16A7G1130KrlBJcdAbuKL2er6BWHV8B9STo5fYfZmRjdjiYNVL7L7MqperVPFNDl5lI3ZfZtVLbnHQG7hKDTfarHqJ3ZfpDeTuy/QGYmuv3kDsvkxvIHZfNj+6CKTWXr2Ba43+fJlHy8jdl+kNXF0cOr0B+zKPllHa2LeJPVpG7L7Mqpfc4mBkI7Y4GNmILQ5GNnKLg6OX2OJgZOMGI9+q0Bu4wbveQKytkQ0z2zVeXABu8Gpkw8zmhQomNbMZ2Yid2Yxs5M5sjl5uMuZ9Nu+ykTuzGdnIPXp9/MTObHoDsTObkY3Yo9e2jBtnNiMbsUZ8xMEvWxG7LtMbuNG7kY1YnVUv1mVGNqazLjOyEbsuM7Jxq52RDesyRy+lrRy9OHodvUzn6H3x4ZN69LpRwa3Gez7n6MPnxqPXPWK0XkcvWi84emneebSj95sPn9ijd+PDJ/XodY+YW432XK97xNx89Ho8B0evo5fS3h29pBrxOxwcvcRuy+x6cfRiZHP0Ylvm6KVUbxjv6PVwGbEjm4fLyB3ZHL3EjmyOXnJHNkcvsb3B0UvuyObo5cbeMOLR++LjJ3Vk82gksb3Bo5Hk9gZHL7G9wdFLbm9w9HJbbxgxvNZl3OQ0Zm9wp4LY3uDoJbc3mNm4qTd0MzMboXYzxQGl18xG4dI7am+YzV0BQkuv9+C5xXbc8HoPntjSa2bjhtI7cnjNbMSWXkcvuaXXG0HEll7rMnJLr0cciC29HnHg6vBuHb0ovdZlFPY2fnity7hyYuvGT691GaETm5mN3IlNcSA4vGY2rlJFeBUHrrGrIbweS+caqyrCqziQG14P6HC5tzrCqzhwRXi7meKAk1dxYJrhVRzIDa/iQG54FQdCBzbFgeTwKg6k1gbFgeDwKg7E1gbFgeDwKg7EhldxIDe8igODrSrLrrcqGGxXW3i9jslAdbyAqThwTXi7+sKrODDIucLwKg7khneuODBkUzar0d6FITW8vrOX2PAqveSG176B1PBaljHAamZiw8lrYkN4PyxdGVLDa2IjNrwmNnLDe3RpCA2viY3c8JrY+NK50vC6QcyXanwY3cSG8NK4baW9wQ1ivrSybiB2YuusG1B63SCmcHgrLb3usfG1ndKLic1tCgp7rzS8Nr18XXpnegOpOr0BpffO7Bv4sjd0egOptkY2Up31Bhy9nm+gNKtebMuMbGi9Vr3Et14jG1866Q2Y2YxsKA56A4MZ2bBx8DYQxf1pZEPtNbJRXOfo5X/t3eFt40YURWF6twE6UgEyrQJoSQVYUvqvKTKSRYAsHJPSmJxLfueHCyAPHu67M5RTuRi9sLSVxK+WYRA7oxfslXphaTN6kby0Gb3IXdqMXgyjwgtmP7wVDKPCc+KTt4LUysHlMgylN3rB3mJ1mXeCobTqMrDXSQVWb6/Ri1x77WyItVddhtzOQXBA7Oy1syHXXsEBufZuvRCk2is4INdedyOR2zmcvA+kzl7BAbmzV3BArr2CA2LtdbMXI6noyyCnxMi1V3DASN4FB8Ry1jiAvYIDJqeaX4JyVIFce12OxGiq+Q3JrXeB0dRir+CA8bSCA9irL8Pk9PoyxLITe8FesReTcxZ7wV6xF5NzEXvBXrEX09OKvYilF3uhMhN7scbSQezFnVzFXrDX3V5MX5m1Yi+UDr6Fx/rstbQhtzLzE1DIrcwsbcgtHU7eAVLt9TskeKAyUzkgl1blAPaqHDA5vcoBsexUDojl3S0HxHJWmCGWq8IMsVwUZsi1d9bKzIcVeAj2Ipde3YtYdupesFfdi8k5q3sRy1Xdi9zKTN2LXNgLlZnbvVhV6bD19BFr78nTR2zpwF7klg57Tx8PMt89Hc8esaWDwwo8zLu6F9Y2t3uxnrWNvcgNvluPHg+zYy8EX4cVWE3wZS9ig68vK5AbfNmL3ODrqA25wddRG3KDL3uRG3zZi9zg66AYucGXvcgNvuxFbvDdeuyIDb7sRaHg27IXgq9LOpicF/ZC8GUv1hB89546YoMve1GKyRtf13uRG3xd70W54MteCL7sxfKDr+u9yA2+7EVu8HVBErnBl73IDb7sRUEm/o/F/lkbcte2rSeOgrTshbWNvVh48D154IgNvuxFSS7sheDLXkzPjr2wtrEXy17b2Iuya1vLXljb2ItFr23sRe7atve4Ebu2mb3IXdvMXhSmNXthbTN7MTkvZi+sbezF9Gsbe5ELe5FLz14oHdiLyTmzF0oH9mLBpQN7Udzelr1QOvgtHbAXGMxkNx38AiqKM1ll5tenUZwre5FbOvifQci1t2UvYpnKXv8rE+Xp2Qv2+rANy7X35FmjNDv2IpbJDtu2njVK47AN7GUvpufqsA3sVfhicqb7NsizRq69ew8bsfaePGyUhr3IpXVcAfYqfLFcexW+KE7PXrD3y+OKvYeNVHsVviiOn/AFe1VmWLK9KjPk2qt0QK697kiiNBP+v0ylA3LtVTog115rG2JzL3tRmvfG2gaz19qGBc9eaxuCZ+/W40bs7LW2IXf2OitG7ux1QR25s9fahrK8NNY2sNfahkXba21Dbu61tiHXXmsbgu39wwNHrL2CL0rST2qvS5LItVfwRbC9W08csfY6r0BB2kbwBXt9HYSl2yv4ohwTyyv4IthewRe59gq+KMZlcnsFX+TaK/gi117BF7n2Cr4ItlfwRa697vgi114ftyHXXnd8EWyvj9tQhmsj+MLs1ZlhDbNX8EWwvQ6LkZscHBYjd/aKDsidvTozBNsrOiDXXtEBwfaKDsi1V3RAbOcgOiB49jqwQPDsFR2Qa6/ogGB7RQfk2uv7IOTa69NiBNvrCwvk2is6INdep8UItld0wIOc57NX5Ytge1W+yLXX3obH2M1or70Nwfba25Brr70NwfYavsi11y+a4RH6ee21tyHXXqUZcu21tyHYXnsbcu01fBFsr+GLXHsNX9xN2xi+MHsNX6xv9hq+CJ69hi9yZ6/hi2B7DV8E22v4Itdewxf3cKnDXr/mi3vsberg4FUg1t6fe+8CY7lWYq+PLBBsr48skGuv1gyjOVdjr9YMY3mpx17ZASPZ1WOvxQ0j6SuyV3bAONqa7JUdkGuv7IAxXJq6kB2Qa6/sgOFcK7O32XgnGMq5NntdNsNgdtXZ+yT6ItZedyUxlL4+e0VfDKSt0F6tLyILM60v4u3V+mIA14a+SOVcqb3Nhr4ILMwUD4i315kbvqJv6ItU2oa+UJjRF+ylLwZyrdzeJ/riU84NfaEwoy8UZvTFguylLz6pHNomAfoisDBzWx25hRl9EVyYuTCJ4MKMvkiuHH7xbHdDYOXwqzkzfpG4tBm/CF7a+Ivgpc3JG/5D2yRi/uLPnJO239sz/uLaxLLpvD6xN9hf9dm66ZtoDvwVe3NRP6yYcxOP9U3sTeZZftD2JueHzUEBoS9LnsBHAq+L92ZRiBD6svAIQWB9WfAAloH1ZeEZmMH6suQMwWB9WX6KkIP1ZcmLnCG8RF6atfD0vDl2FBYcohWWIwQHyxwEhzmjsCEsOKR3whQWHIJjxN8cjWLBIb2V+ODwz1/ZWHAIxhcbgkMw/j99xez4+ZW+snCtXASHL/lJ30o5k3PAKkffOum5Sd/Y4MBM+goOi9f3RBbBIVdfxa+yl75Q9tIXyl6nxoLDWvAvkgUH+qJA2Ss4jEZxJjgEr260UfbKDhAcZmDPnBrwSdBd/GCO4ODCDuxs07PljtGrdsD9o9fOpvO1s62Pn+xRlynNYPQ6sTB6YW8zeu1tMHrtbfiEHQHtbbGjl372NqNXdIDRa2/DUNxweBz3JGfC5bISla+9zejNZUukOXhlnr0tFgcV9rZYnBGrfHPbMqPX3uagAqKDgwp7G7RlMyA6OKiwt8HKNsPexihtmb0NQ3KD0Wtvi80NVjZ7m9wAe5u+wXkb9A32NucUsLcJvYYvhN4MfN8m9CrNIPQqzYReKM2E3nWwJZjQmzt8Gfad8gq9SjOhF04spsaPjxi+uRub0Gv42tjgxMLG5rgYA3ljluGrboDjYnWD42KQ1/DVlcHwJS8MX/IavnBKYfiSF4YveQ1fyLyGL3lh+NZ8SEFew5e8MHwdDxu+IG/9uOf7EK5EzsuJgvfjMvrM+MLt/jMK8hq+DthgcXNGoTWDssHwJS8sbuSFxU3NKzuAvBY3ZxSQHZxRQHYYIe8zW6pjw8thZYMzCtFX5IXoK/JC9B0mb88SR26p8oq8oq99Dd/CgaPkzY2+NrdPywby0lfZgG/c3BQPUgN9DV7Q1+AFfe8fvOSlb+rgdaMsjQ19JV76huMDIPqm0gm8sdl39ccWvnkP5mnddx4k3nB913zjTMerOYsdvNY16SFW3t6rlx6kBqjOrGu4d/x26yp5pYZlcZAaID1IDdA9GLwYN36X7++rwbvc8btZ9vbWvRm8y56/nbmLXJ4PC527Xu1K/F1c/6BoWFX/sCx/FQ1rW+D2QgMUEHOHBt9PKICFBsQtcMfsAawlW3mAuAnccRfBI3hzU3jPXeQO4RtPT5uMUXzx6074zOPjjcOh2nF8OXIXX0eKD49fu66qXKHfxV3ZuNvvZ9a4M3Zx9yx++jjnmGvHu6nbegkosuN9hOPJNO5e35iL8pHi0H2/uYYuvm8UH79pCHev0gKmGMK3HNGVLXXfrGiYcq27UeTE4yLnYrYo8ZDC3ZG6mH0SH0dvdBfmoqqN7paHL19Iu/840Hs9Hp8lXdSYh3/727b//v04BsH/8xchcY8IypDHpAAAAABJRU5ErkJggg==","e":1},{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Pre-comp 2","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[716,508,0],"ix":2},"a":{"a":0,"k":[716,508,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1432,"h":1016,"ip":57,"op":95,"st":57,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"Pre-comp 2","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[716,508,0],"ix":2},"a":{"a":0,"k":[716,508,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1432,"h":1016,"ip":5,"op":43,"st":5,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"gai","parent":4,"refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"xich du","refId":"comp_13","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.662],"y":[1.451]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[1.628]},{"i":{"x":[0.655],"y":[1.345]},"o":{"x":[0.167],"y":[0.167]},"t":50,"s":[-2.095]},{"t":100,"s":[1.628]}],"ix":10},"p":{"a":0,"k":[724,-112,0],"ix":2},"a":{"a":0,"k":[922,-96,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":2,"nm":"Layer 8","refId":"image_25","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[750,878,0],"ix":2},"a":{"a":0,"k":[550,8,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":2,"nm":"cay co Copy","refId":"image_26","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.586],"y":[1.796]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.473],"y":[1.527]},"o":{"x":[0.167],"y":[0.095]},"t":50,"s":[7.171]},{"t":100,"s":[0]}],"ix":10},"p":{"a":0,"k":[543,877.5,0],"ix":2},"a":{"a":0,"k":[20,92.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":2,"nm":"cay co Copy 2","refId":"image_27","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.586],"y":[1.796]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.473],"y":[1.527]},"o":{"x":[0.167],"y":[0.095]},"t":50,"s":[7.171]},{"t":100,"s":[0]}],"ix":10},"p":{"a":0,"k":[695.5,878.5,0],"ix":2},"a":{"a":0,"k":[12.5,73.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":2,"nm":"cay co","refId":"image_28","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.586],"y":[1.796]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.473],"y":[1.527]},"o":{"x":[0.167],"y":[0.095]},"t":50,"s":[7.171]},{"t":100,"s":[0]}],"ix":10},"p":{"a":0,"k":[839,878,0],"ix":2},"a":{"a":0,"k":[13,29,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"la","refId":"comp_15","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[716,508,0],"ix":2},"a":{"a":0,"k":[716,508,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1338,552],[204,552],[204,880],[1338,880]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"w":1432,"h":1016,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":2,"nm":"Layer 4","refId":"image_41","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[739,453,0],"ix":2},"a":{"a":0,"k":[422,327,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":2,"nm":"Layer 7","refId":"image_42","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[720,503.5,0],"ix":2},"a":{"a":0,"k":[701,492.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"nhac 5","refId":"image_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":7,"s":[100]},{"t":28,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[460,349.5,0],"ix":2},"a":{"a":0,"k":[148,192.5,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.495,0.495,0.833],"y":[1,1,-15.667]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,16.667]},"t":5,"s":[0,0,100]},{"t":30,"s":[100,100,100]}],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[78,211],[-20,211],[-46,109],[52,109]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"ip":5,"op":33,"st":5,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"nhac 4","refId":"image_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[100]},{"t":23,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[460,349.5,0],"ix":2},"a":{"a":0,"k":[148,192.5,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.495,0.495,0.833],"y":[1,1,-15.667]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,16.667]},"t":0,"s":[0,0,100]},{"t":25,"s":[100,100,100]}],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[108,111],[10,111],[-16,9],[82,9]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"ip":0,"op":28,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"nhac 3","refId":"image_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":12,"s":[100]},{"t":33,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1047,316.5,0],"ix":2},"a":{"a":0,"k":[735,159.5,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.495,0.495,0.833],"y":[1,1,-15.667]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,16.667]},"t":10,"s":[0,0,100]},{"t":35,"s":[100,100,100]}],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[870,155],[772,155],[772,263],[870,263]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"ip":10,"op":38,"st":10,"bm":0},{"ddd":0,"ind":4,"ty":2,"nm":"nhac 2","refId":"image_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":7,"s":[100]},{"t":28,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1047,316.5,0],"ix":2},"a":{"a":0,"k":[735,159.5,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.502,0.502,0.833],"y":[1,1,-15.667]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,16.667]},"t":5,"s":[0,0,100]},{"t":30,"s":[100,100,100]}],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[872,17],[774,17],[774,125],[872,125]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"ip":5,"op":33,"st":5,"bm":0},{"ddd":0,"ind":5,"ty":2,"nm":"nhac","refId":"image_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[100]},{"t":23,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1047,316.5,0],"ix":2},"a":{"a":0,"k":[735,159.5,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.495,0.495,0.833],"y":[1,1,-15.667]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,16.667]},"t":0,"s":[0,0,100]},{"t":25,"s":[100,100,100]}],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[794,-33],[674,-33],[674,81],[794,81]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"ip":0,"op":28,"st":0,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Folder 1","parent":7,"refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"toc phai","parent":7,"refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.618],"y":[1.112]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[5.526]},{"i":{"x":[0.833],"y":[0.85]},"o":{"x":[0.835],"y":[-0.355]},"t":20,"s":[13.451]},{"i":{"x":[0.32],"y":[0.673]},"o":{"x":[0.333],"y":[0.321]},"t":50,"s":[-4.561]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":74,"s":[3.584]},{"i":{"x":[0.833],"y":[1.082]},"o":{"x":[0.485],"y":[0]},"t":86,"s":[1.076]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[-0.375]},"t":94,"s":[6.58]},{"t":100,"s":[5.526]}],"ix":10},"p":{"a":0,"k":[1009,200,0],"ix":2},"a":{"a":0,"k":[1009,200,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"toc trai","parent":7,"refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.547],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[-1.94]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.856],"y":[-0.264]},"t":20,"s":[6.345]},{"i":{"x":[0.405],"y":[1.08]},"o":{"x":[0.167],"y":[0.167]},"t":50,"s":[-7.992]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":74,"s":[-0.474]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.386],"y":[0]},"t":86,"s":[-3.915]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.717],"y":[0]},"t":94,"s":[-1.689]},{"t":100,"s":[-1.94]}],"ix":10},"p":{"a":0,"k":[853,197,0],"ix":2},"a":{"a":0,"k":[853,197,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"than","refId":"comp_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[934,532,0],"ix":2},"a":{"a":0,"k":[934,532,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1172,286],[1103,300],[1075,305.25],[1045.25,313.75],[964.5,332.5],[949.433,337.568],[947.951,334.416],[940.919,332.015],[931.064,330.338],[924.247,330.982],[916.249,333.553],[906.5,339],[890.25,328.25],[877.9,327.55],[858.225,327.825],[834.125,330.375],[770,303.75],[716,286],[716,734],[1172,734]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"tay trai","parent":4,"refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.544],"y":[1.262]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":18,"s":[10.265]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.488],"y":[-1.491]},"t":32,"s":[10.265]},{"t":87,"s":[0]}],"ix":10},"p":{"a":0,"k":[876,349,0],"ix":2},"a":{"a":0,"k":[876,349,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"tay phai","parent":4,"refId":"comp_9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.447],"y":[-1.407]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[1.12]},"o":{"x":[0.453],"y":[0.198]},"t":32,"s":[-2.832]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.582],"y":[0.283]},"t":50,"s":[-18.819]},{"i":{"x":[0.526],"y":[1]},"o":{"x":[0.201],"y":[0.141]},"t":64,"s":[-13.171]},{"t":87,"s":[0]}],"ix":10},"p":{"a":0,"k":[981,352,0],"ix":2},"a":{"a":0,"k":[981,352,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"dau","parent":4,"refId":"comp_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.604],"y":[1.231]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.396],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":18,"s":[-5.635]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":25,"s":[-5.164]},{"i":{"x":[0.53],"y":[1]},"o":{"x":[0.167],"y":[-0.046]},"t":32,"s":[-5.164]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.592],"y":[0.278]},"t":50,"s":[4.266]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":57,"s":[3.21]},{"i":{"x":[0.252],"y":[0.722]},"o":{"x":[0.167],"y":[0.167]},"t":64,"s":[3.21]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":82,"s":[-0.222]},{"t":89,"s":[0]}],"ix":10},"p":{"a":0,"k":[926,331.5,0],"ix":2},"a":{"a":0,"k":[926,331.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":true,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1172,286],[1103,300],[1075,305.25],[1045.25,313.75],[1002,325.25],[971.683,327.068],[958.726,336.118],[947.984,340.978],[937.064,337.838],[925.497,334.732],[914.499,336.553],[904.439,341.586],[888.959,331.104],[877.9,327.55],[858.225,327.825],[834.125,330.375],[770,303.75],[716,286],[716,734],[1172,734]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"chan trai","parent":4,"refId":"comp_11","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.588],"y":[1.293]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[3.871]},{"i":{"x":[0.739],"y":[1.318]},"o":{"x":[0.167],"y":[0.043]},"t":50,"s":[-9.145]},{"t":100,"s":[3.871]}],"ix":10},"p":{"a":0,"k":[929,614,0],"ix":2},"a":{"a":0,"k":[929,614,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"chan phai","parent":4,"refId":"comp_12","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.588],"y":[1.523]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.631],"y":[1.369]},"o":{"x":[0.167],"y":[0.219]},"t":50,"s":[-2.662]},{"t":100,"s":[0]}],"ix":10},"p":{"a":0,"k":[918,619,0],"ix":2},"a":{"a":0,"k":[918,619,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_3","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"line gai Copy 6","refId":"image_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[997,253.5,0],"ix":2},"a":{"a":0,"k":[18,6.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"Layer 3 Copy 5","refId":"image_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[997,253.5,0],"ix":2},"a":{"a":0,"k":[19,7.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"line gai Copy 7","refId":"image_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[860,258,0],"ix":2},"a":{"a":0,"k":[16,7,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":2,"nm":"Layer 3 Copy 6","refId":"image_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[860.5,258.5,0],"ix":2},"a":{"a":0,"k":[15.5,6.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_4","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"line gai Copy 5","refId":"image_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1023.5,252,0],"ix":2},"a":{"a":0,"k":[30.5,63,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"Layer 16","refId":"image_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1025.5,251,0],"ix":2},"a":{"a":0,"k":[28.5,64,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_5","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"line gai Copy 8","refId":"image_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[842,261,0],"ix":2},"a":{"a":0,"k":[35,67,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"Layer 17","refId":"image_8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[841.5,258.5,0],"ix":2},"a":{"a":0,"k":[32.5,67.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_6","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"line gai","refId":"image_9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[943,406,0],"ix":2},"a":{"a":0,"k":[221,318,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"Layer 3","refId":"image_10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[943,405.5,0],"ix":2},"a":{"a":0,"k":[219,316.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_7","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Folder 2","refId":"comp_8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.449],"y":[1.126]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":18,"s":[-5.48]},{"i":{"x":[0.722],"y":[0.943]},"o":{"x":[0.388],"y":[-0.057]},"t":32,"s":[-5.48]},{"i":{"x":[0.788],"y":[1.034]},"o":{"x":[0.455],"y":[-0.105]},"t":62,"s":[15.503]},{"t":87,"s":[0]}],"ix":10},"p":{"a":0,"k":[814,439,0],"ix":2},"a":{"a":0,"k":[814,439,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"line gai Copy 2","refId":"image_13","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[841.5,399,0],"ix":2},"a":{"a":0,"k":[54.5,71,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"Layer 3 Copy 2","refId":"image_14","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[841.5,399,0],"ix":2},"a":{"a":0,"k":[52.5,69,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_8","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[961.375,539.875,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.25,-0.75],[0,-1.5],[0,-3],[-0.75,-3.25],[-0.5,-2.5],[0,0],[-0.75,-2.25],[0,0],[-0.25,3],[0,3.25],[0,3.75],[0.5,4],[1.022,2.993],[0,0]],"o":[[0,0],[0,0],[-0.25,0.75],[0,1.5],[0,3],[0.75,3.25],[0.5,2.5],[0,0],[0.75,2.25],[0,0],[0.25,-3],[0,-3.25],[0,-3.75],[-0.5,-4],[-3.5,-10.25],[0,0]],"v":[[-142.75,-140],[-147,-139],[-148.25,-134],[-149.25,-125],[-148.5,-115.75],[-147.75,-103.25],[-144.5,-91.5],[-142.5,-84.25],[-141,-76.375],[-136,-76.25],[-135,-81],[-135,-97.25],[-134.25,-107.5],[-134.25,-116.5],[-135.5,-124.5],[-140,-137.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949005126953,0.678436279297,0.603912353516,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"line gai Copy 10","refId":"image_11","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[723,382.5,0],"ix":2},"a":{"a":0,"k":[106,91.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"Layer 3 Copy 8","refId":"image_12","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[721.5,382.5,0],"ix":2},"a":{"a":0,"k":[102.5,89.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_9","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"khuy tay phai","refId":"comp_10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.417],"y":[1.585]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.735],"y":[1.177]},"o":{"x":[0.518],"y":[1.013]},"t":32,"s":[4.747]},{"i":{"x":[0.833],"y":[1.074]},"o":{"x":[0.893],"y":[1.325]},"t":65,"s":[-10.131]},{"t":87,"s":[0]}],"ix":10},"p":{"a":0,"k":[1064,438,0],"ix":2},"a":{"a":0,"k":[1064,438,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"line gai Copy","refId":"image_17","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1031,397.5,0],"ix":2},"a":{"a":0,"k":[66,66.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"Layer 3 Copy","refId":"image_18","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1031,398,0],"ix":2},"a":{"a":0,"k":[64,65,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_10","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1061.647,428.514,0],"ix":2},"a":{"a":0,"k":[101.647,-111.486,0],"ix":1},"s":{"a":0,"k":[94,94,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,-0.75],[0,-3],[-0.75,-3.5],[0,0],[0,0],[-1.25,0],[-1,0.75],[-0.75,4.25],[1.5,4.75],[0.75,1],[1,2.75],[0,0]],"o":[[0,0],[0,0],[0,0.75],[0,3],[0.75,3.5],[0,0],[0,0],[1.25,0],[1,-0.75],[0.75,-4.25],[-1.5,-4.75],[-0.75,-1],[-1,-2.75],[0,0]],"v":[[93.25,-143.5],[90.25,-132.5],[90.75,-117],[91,-106],[92.5,-93.25],[94.75,-83.75],[96.75,-80.5],[101,-80],[106,-79.75],[111.25,-87.5],[112.5,-111.75],[107.25,-126.5],[103,-132.75],[98.5,-142.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.949005126953,0.678436279297,0.603912353516,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"line gai Copy 9","refId":"image_15","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1168,374.5,0],"ix":2},"a":{"a":0,"k":[114,91.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"Layer 3 Copy 7","refId":"image_16","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1167.5,373.5,0],"ix":2},"a":{"a":0,"k":[113.5,89.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_11","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"line gai Copy 3","refId":"image_19","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1027.5,750,0],"ix":2},"a":{"a":0,"k":[97.5,122,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"Layer 3 Copy 3","refId":"image_20","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1027.5,751,0],"ix":2},"a":{"a":0,"k":[96.5,120,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_12","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"line gai Copy 4","refId":"image_21","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[944.5,821.5,0],"ix":2},"a":{"a":0,"k":[50.5,173.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"Layer 3 Copy 4","refId":"image_22","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[944.5,822,0],"ix":2},"a":{"a":0,"k":[48.5,172,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_13","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"line xich du","refId":"comp_14","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"Layer 6","refId":"image_24","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[937,677.5,0],"ix":2},"a":{"a":0,"k":[284,77.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_14","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"line xich du","refId":"image_23","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[931.5,418,0],"ix":2},"a":{"a":0,"k":[293.5,339,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_15","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"la 6","refId":"comp_16","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.459],"y":[1.709]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.444],"y":[1.556]},"o":{"x":[0.167],"y":[0.167]},"t":50,"s":[5.965]},{"t":100,"s":[0]}],"ix":10},"p":{"a":0,"k":[298,874,0],"ix":2},"a":{"a":0,"k":[496,890,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"la 4","refId":"comp_17","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.459],"y":[1.709]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.444],"y":[1.556]},"o":{"x":[0.167],"y":[0.167]},"t":50,"s":[5.965]},{"t":100,"s":[0]}],"ix":10},"p":{"a":0,"k":[390,874,0],"ix":2},"a":{"a":0,"k":[588,890,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"la 5","refId":"comp_18","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.459],"y":[1.709]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.444],"y":[1.556]},"o":{"x":[0.167],"y":[0.167]},"t":50,"s":[5.965]},{"t":100,"s":[0]}],"ix":10},"p":{"a":0,"k":[438,872,0],"ix":2},"a":{"a":0,"k":[636,888,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"la 2","refId":"comp_19","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.459],"y":[1.709]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.444],"y":[1.556]},"o":{"x":[0.167],"y":[0.167]},"t":50,"s":[5.965]},{"t":100,"s":[0]}],"ix":10},"p":{"a":0,"k":[1226,878,0],"ix":2},"a":{"a":0,"k":[1424,894,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"la 1","refId":"comp_20","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.459],"y":[1.709]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.444],"y":[1.556]},"o":{"x":[0.167],"y":[0.167]},"t":50,"s":[5.965]},{"t":100,"s":[0]}],"ix":10},"p":{"a":0,"k":[1128,882,0],"ix":2},"a":{"a":0,"k":[1326,898,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"la 3","refId":"comp_21","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.459],"y":[1.709]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.444],"y":[1.556]},"o":{"x":[0.167],"y":[0.167]},"t":50,"s":[5.965]},{"t":100,"s":[0]}],"ix":10},"p":{"a":0,"k":[1058,878,0],"ix":2},"a":{"a":0,"k":[1256,894,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_16","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"la 6","refId":"image_29","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[481.5,849.5,0],"ix":2},"a":{"a":0,"k":[53.5,43.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"Layer 14","refId":"image_30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[483,851.5,0],"ix":2},"a":{"a":0,"k":[53,43.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_17","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"la 4","refId":"image_31","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[555.5,771,0],"ix":2},"a":{"a":0,"k":[95.5,123,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"Layer 12","refId":"image_32","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[558,778,0],"ix":2},"a":{"a":0,"k":[91,117,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_18","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"la 5","refId":"image_33","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[658.5,849.5,0],"ix":2},"a":{"a":0,"k":[44.5,45.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"Layer 13","refId":"image_34","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[658.5,850.5,0],"ix":2},"a":{"a":0,"k":[42.5,44.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_19","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"la 2","refId":"image_35","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1443.5,844,0],"ix":2},"a":{"a":0,"k":[59.5,57,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"Layer 10","refId":"image_36","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1441.5,845,0],"ix":2},"a":{"a":0,"k":[58.5,55,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_20","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"la 1","refId":"image_37","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1348,761,0],"ix":2},"a":{"a":0,"k":[108,140,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"Layer 9","refId":"image_38","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1347.5,761,0],"ix":2},"a":{"a":0,"k":[105.5,138,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_21","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"la 3","refId":"image_39","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1238,829.5,0],"ix":2},"a":{"a":0,"k":[78,68.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"Layer 11","refId":"image_40","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1239.5,831,0],"ix":2},"a":{"a":0,"k":[77.5,68,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Illustration","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[716,508,0],"ix":2},"a":{"a":0,"k":[716,508,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1432,"h":1016,"ip":0,"op":250,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git "a/presentation/src/main/cpp/third_party/rlottie/example/resource/360\302\272_degree.json" "b/presentation/src/main/cpp/third_party/rlottie/example/resource/360\302\272_degree.json" deleted file mode 100644 index 810b9a59..00000000 --- "a/presentation/src/main/cpp/third_party/rlottie/example/resource/360\302\272_degree.json" +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.13","fr":30,"ip":0,"op":76,"w":1024,"h":1024,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"360º Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[390.977,552.004,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.703,3.281],[8.276,0],[4.43,-1.239],[4.229,-2.916],[0,0],[-5.105,0],[-1.623,-1.02],[0,-2.114],[10.973,0],[0,0],[0,0],[0,0],[-2.516,-0.602],[-1.13,-1.184],[0,-2.188],[2.169,-1.33],[4.739,0],[3.627,0.857],[3.5,1.787],[0,0],[-3.664,-0.62],[-4.302,0],[-5.888,4.266],[0,7.438],[13.344,1.677],[0,0],[-3.027,3.555],[0,4.959]],"o":[[-4.703,-3.281],[-5.724,0],[-4.43,1.24],[0,0],[5.469,-3.427],[2.734,0],[1.622,1.021],[0,5.615],[0,0],[0,0],[0,0],[4.047,0],[2.516,0.602],[1.13,1.185],[0,2.844],[-2.17,1.331],[-3.062,0],[-3.628,-0.856],[0,0],[4.266,1.641],[3.664,0.62],[10.463,0],[5.887,-4.266],[0,-10.938],[0,0],[5.723,-1.604],[3.026,-3.555],[0,-5.76]],"v":[[51.625,-76.18],[32.156,-81.102],[16.926,-79.242],[3.938,-73.008],[12.906,-58.57],[28.766,-63.711],[35.301,-62.18],[37.734,-57.477],[21.273,-49.055],[16.242,-49.055],[16.242,-32.812],[21.164,-32.812],[31.008,-31.91],[36.477,-29.23],[38.172,-24.172],[34.918,-17.91],[24.555,-15.914],[14.52,-17.199],[3.828,-21.164],[3.828,-3.227],[15.723,0.164],[27.672,1.094],[52.199,-5.305],[61.031,-22.859],[41.016,-41.781],[41.016,-42.109],[54.141,-49.848],[58.68,-62.617]],"c":true},"ix":2},"nm":"3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.439220024558,0.439220024558,0.439220024558,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"3","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.323,-6.125],[-9.443,0],[-4.959,5.086],[0,8.787],[3.919,4.576],[7.109,0],[3.281,-6.198],[0,0],[-3.537,3.172],[-7.219,0],[-3.646,-0.692],[0,0],[3.245,0],[6.216,-3.281],[3.19,-6.909],[0,-11.156]],"o":[[5.323,6.125],[8.895,0],[4.958,-5.086],[0,-8.166],[-3.92,-4.575],[-7.255,0],[0,0],[0.328,-7.182],[3.536,-3.172],[4.266,0],[0,0],[-4.339,-0.62],[-9.115,0],[-6.216,3.281],[-3.191,6.909],[0,11.011]],"v":[[77.438,-8.094],[99.586,1.094],[120.367,-6.535],[127.805,-27.344],[121.926,-46.457],[105.383,-53.32],[89.578,-44.023],[88.922,-44.023],[94.719,-59.555],[110.852,-64.312],[122.719,-63.273],[122.719,-80.172],[111.344,-81.102],[88.348,-76.18],[74.238,-60.895],[69.453,-33.797]],"c":true},"ix":2},"nm":"6","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.495,2.242],[0,3.5],[-1.55,1.677],[-2.48,0],[0,-6.489],[1.44,-1.731],[2.297,0]],"o":[[-1.495,-2.242],[0,-2.406],[1.549,-1.677],[5.031,0],[0,3.792],[-1.441,1.732],[-2.443,0]],"v":[[93.188,-19.387],[90.945,-28],[93.27,-34.125],[99.312,-36.641],[106.859,-26.906],[104.699,-18.621],[99.094,-16.023]],"c":true},"ix":2},"nm":"6","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.439220024558,0.439220024558,0.439220024558,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"6","np":5,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.867,6.909],[9.516,0],[4.739,-6.635],[0,-14.219],[-4.849,-6.872],[-9.552,0],[-4.74,6.581],[0,14.146]],"o":[[-4.867,-6.909],[-9.771,0],[-4.74,6.636],[0,13.562],[4.848,6.873],[9.77,0],[4.739,-6.58],[0,-13.672]],"v":[[185.637,-70.738],[164.062,-81.102],[142.297,-71.148],[135.188,-39.867],[142.461,-9.215],[164.062,1.094],[185.828,-8.777],[192.938,-39.867]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.13,3.427],[-2.662,0],[-1.13,-3.555],[0,-8.859],[1.112,-3.5],[2.698,0],[1.13,3.391],[0,9.042]],"o":[[1.13,-3.427],[2.661,0],[1.13,3.555],[0,8.823],[-1.113,3.5],[-2.662,0],[-1.13,-3.391],[0,-9.114]],"v":[[158.375,-58.68],[164.062,-63.82],[169.75,-58.488],[171.445,-39.867],[169.777,-21.383],[164.062,-16.133],[158.375,-21.219],[156.68,-39.867]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.439220024558,0.439220024558,0.439220024558,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"0","np":5,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.573,3.755],[5.723,0],[3.445,-3.609],[0,-6.453],[-3.482,-3.737],[-5.797,0],[-3.482,3.664],[0,6.344]],"o":[[-3.573,-3.755],[-6.016,0],[-3.445,3.609],[0,6.198],[3.481,3.738],[6.052,0],[3.481,-3.664],[0,-6.161]],"v":[[232.859,-75.25],[218.914,-80.883],[204.723,-75.469],[199.555,-60.375],[204.777,-45.473],[218.695,-39.867],[232.996,-45.363],[238.219,-60.375]],"c":true},"ix":2},"nm":"º","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-3.646,0],[0,-6.344],[3.609,0],[0.875,1.55],[0,3.172]],"o":[[3.609,0],[0,6.271],[-1.896,0],[-0.875,-1.549],[0,-6.344]],"v":[[218.805,-69.891],[224.219,-60.375],[218.805,-50.969],[214.648,-53.293],[213.336,-60.375]],"c":true},"ix":2},"nm":"º","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.439220024558,0.439220024558,0.439220024558,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"º","np":5,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":350,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Verti","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[0],"e":[360]},{"t":60}],"ix":10},"p":{"a":0,"k":[512,512,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p833_0p833_0p333_0","0p833_1_0p333_0"],"t":0,"s":[310,512],"e":[1,512]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":15,"s":[1,512],"e":[310,512]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":30,"s":[310,512],"e":[512,512]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0]},"n":["0p667_1_0p167_0p167","0p667_1_0p167_0"],"t":45,"s":[512,512],"e":[310,512]},{"t":60}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.439215686275,0.439215686275,0.439215686275,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":350,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Hori","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[0],"e":[360]},{"t":60}],"ix":10},"p":{"a":0,"k":[512,512,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[1,0.833]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p833_1_0p333_0","0p833_0p833_0p333_0"],"t":0,"s":[512,310],"e":[512,512]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":15,"s":[512,512],"e":[512,310]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":30,"s":[512,310],"e":[512,1]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0,0.167]},"n":["0p667_1_0p167_0","0p667_1_0p167_0p167"],"t":45,"s":[512,1],"e":[512,310]},{"t":60}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.439215686275,0.439215686275,0.439215686275,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":350,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Main","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[512,512,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"d":1,"ty":"el","s":{"a":0,"k":[512,512],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.439215686275,0.439215686275,0.439215686275,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":350,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/3d.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/3d.json deleted file mode 100644 index a5babf8b..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/3d.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.2.1","fr":60,"ip":0,"op":60,"w":500,"h":500,"nm":"Comp 1","ddd":1,"assets":[],"layers":[{"ddd":1,"ind":1,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"rx":{"a":0,"k":0,"ix":8},"ry":{"a":0,"k":0,"ix":9},"rz":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[360]},{"t":55}],"ix":10},"or":{"a":0,"k":[0,0,0],"ix":7},"p":{"a":0,"k":[75,384,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.075893886387,0.175385013223,0.921568632126,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":60,"st":0,"bm":0},{"ddd":1,"ind":2,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"rx":{"a":0,"k":0,"ix":8},"ry":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[360]},{"t":55}],"ix":9},"rz":{"a":0,"k":0,"ix":10},"or":{"a":0,"k":[0,0,0],"ix":7},"p":{"a":0,"k":[76,234,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.025943866,0.945098042488,0.134079754353,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":60,"st":0,"bm":0},{"ddd":1,"ind":3,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"rx":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[360]},{"t":55}],"ix":8},"ry":{"a":0,"k":0,"ix":9},"rz":{"a":0,"k":0,"ix":10},"or":{"a":0,"k":[0,0,0],"ix":7},"p":{"a":0,"k":[76,72,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":60,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/4479-fireworks.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/4479-fireworks.json deleted file mode 100644 index f76b61de..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/4479-fireworks.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.3.4","fr":29,"ip":0,"op":117,"w":800,"h":800,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p5_1_0p167_0p167"],"t":0,"s":[0],"e":[100]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p5_1_0p5_0"],"t":49,"s":[100],"e":[2]},{"t":69}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[535,755,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.5,1,0.833],"y":[1,1,1]},"o":{"x":[0.5,0,0.167],"y":[0,0,0]},"n":["0p5_1_0p5_0","1_1_0_0","0p833_1_0p167_0"],"t":49,"s":[96.254,-1.205,100],"e":[96.254,-159.205,100]},{"i":{"x":[0.5,1,0.833],"y":[1,1,1]},"o":{"x":[0.5,0,0.167],"y":[0,0,0]},"n":["0p5_1_0p5_0","1_1_0_0","0p833_1_0p167_0"],"t":67,"s":[96.254,-159.205,100],"e":[96.254,-152.205,100]},{"t":72}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[18.695,41.477],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.60784295774,0.321568986481,0.921568986481,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.345098039216,0.851361083984,0.909803921569,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-4.652,214.738],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":580,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Shape Layer 9","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p5_1_0p5_0"],"t":21,"s":[0],"e":[100]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p5_1_0p5_0"],"t":63,"s":[100],"e":[2]},{"t":83}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[261,733,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.5,1,0.833],"y":[1,1,1]},"o":{"x":[0.5,0,0.167],"y":[0,0,0]},"n":["0p5_1_0p5_0","1_1_0_0","0p833_1_0p167_0"],"t":63,"s":[96.254,-1.205,100],"e":[96.254,-159.205,100]},{"i":{"x":[0.5,1,0.833],"y":[1,1,1]},"o":{"x":[0.5,0,0.167],"y":[0,0,0]},"n":["0p5_1_0p5_0","1_1_0_0","0p833_1_0p167_0"],"t":81,"s":[96.254,-159.205,100],"e":[96.254,-152.205,100]},{"t":86}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[18.695,41.477],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.60784295774,0.321568986481,0.921568986481,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.345098039216,0.851361083984,0.909803921569,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-4.652,214.738],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":580,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Shape Layer 8","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p5_1_0p5_0"],"t":0,"s":[0],"e":[100]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p5_1_0p5_0"],"t":26,"s":[100],"e":[2]},{"t":46}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[415,717,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.5,1,0.833],"y":[1,1,1]},"o":{"x":[0.5,0,0.167],"y":[0,0,0]},"n":["0p5_1_0p5_0","1_1_0_0","0p833_1_0p167_0"],"t":26,"s":[96.254,-1.205,100],"e":[96.254,-159.205,100]},{"i":{"x":[0.5,1,0.833],"y":[1,1,1]},"o":{"x":[0.5,0,0.167],"y":[0,0,0]},"n":["0p5_1_0p5_0","1_1_0_0","0p833_1_0p167_0"],"t":44,"s":[96.254,-159.205,100],"e":[96.254,-152.205,100]},{"t":49}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[18.695,41.477],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.60784295774,0.321568986481,0.921568986481,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.345098039216,0.851361083984,0.909803921569,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-4.652,214.738],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":580,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Shape Layer 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[264,408,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.3,0.3],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"n":["0p3_1_0p7_0","0p3_1_0p7_0"],"t":78,"s":[20,0],"e":[0,60]},{"t":97}],"ix":2},"p":{"a":0,"k":[0,-51],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.124487452209,0.808345139027,0.834175884724,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.187980338931,0.750694930553,0.863511025906,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.456,"y":1},"o":{"x":0.178,"y":0.339},"n":"0p456_1_0p178_0p339","t":77,"s":[2.992,13.768],"e":[0,-154],"to":[0.40790435671806,-12.2535486221313],"ti":[-0.18578809499741,5.58112049102783]},{"t":119}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"rp","c":{"a":0,"k":13,"ix":1},"o":{"a":0,"k":0,"ix":2},"m":1,"ix":2,"tr":{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":27.692,"ix":4},"so":{"a":1,"k":[{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.6],"y":[0]},"n":["0p4_1_0p6_0"],"t":72,"s":[10],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":97,"s":[100],"e":[0]},{"t":104}],"ix":5},"eo":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.6],"y":[0]},"n":["0p833_1_0p6_0"],"t":72,"s":[13],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":97,"s":[100],"e":[0]},{"t":104}],"ix":6},"nm":"Transform"},"nm":"Repeater 1","mn":"ADBE Vector Filter - Repeater","hd":false}],"ip":68,"op":554,"st":-26,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Shape Layer 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[264,408,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.3,0.3],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"n":["0p3_1_0p7_0","0p3_1_0p7_0"],"t":85,"s":[20,0],"e":[0,60]},{"t":104}],"ix":2},"p":{"a":0,"k":[0,-51],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.607843137255,0.321568627451,0.921568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.603921568627,0.345098039216,0.909803921569,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.456,"y":1},"o":{"x":0.178,"y":0.121},"n":"0p456_1_0p178_0p121","t":87,"s":[2.992,13.768],"e":[0,-154],"to":[0.40790435671806,-12.2535486221313],"ti":[-0.18578809499741,5.58112049102783]},{"t":102}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"rp","c":{"a":0,"k":13,"ix":1},"o":{"a":0,"k":0,"ix":2},"m":1,"ix":2,"tr":{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":27.692,"ix":4},"so":{"a":1,"k":[{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.6],"y":[0]},"n":["0p4_1_0p6_0"],"t":87,"s":[10],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":97,"s":[100],"e":[0]},{"t":105}],"ix":5},"eo":{"a":1,"k":[{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.6],"y":[0]},"n":["0p4_1_0p6_0"],"t":87,"s":[13],"e":[99]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":97,"s":[99],"e":[1]},{"t":105}],"ix":6},"nm":"Transform"},"nm":"Repeater 1","mn":"ADBE Vector Filter - Repeater","hd":false}],"ip":68,"op":554,"st":-26,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[528,424,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.3,0.3],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"n":["0p3_1_0p7_0","0p3_1_0p7_0"],"t":64,"s":[20,0],"e":[0,60]},{"t":83}],"ix":2},"p":{"a":0,"k":[0,-51],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.124487452209,0.808345139027,0.834175884724,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.187980338931,0.750694930553,0.863511025906,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.456,"y":1},"o":{"x":0.178,"y":0.339},"n":"0p456_1_0p178_0p339","t":63,"s":[2.992,13.768],"e":[0,-154],"to":[0.40790435671806,-12.2535486221313],"ti":[-0.18578809499741,5.58112049102783]},{"t":105}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"rp","c":{"a":0,"k":13,"ix":1},"o":{"a":0,"k":0,"ix":2},"m":1,"ix":2,"tr":{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":27.692,"ix":4},"so":{"a":1,"k":[{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.6],"y":[0]},"n":["0p4_1_0p6_0"],"t":58,"s":[10],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":83,"s":[100],"e":[0]},{"t":90}],"ix":5},"eo":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.6],"y":[0]},"n":["0p833_1_0p6_0"],"t":58,"s":[13],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":83,"s":[100],"e":[0]},{"t":90}],"ix":6},"nm":"Transform"},"nm":"Repeater 1","mn":"ADBE Vector Filter - Repeater","hd":false}],"ip":54,"op":540,"st":-40,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[528,424,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.3,0.3],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"n":["0p3_1_0p7_0","0p3_1_0p7_0"],"t":71,"s":[20,0],"e":[0,60]},{"t":90}],"ix":2},"p":{"a":0,"k":[0,-51],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.607843137255,0.321568627451,0.921568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.603921568627,0.345098039216,0.909803921569,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.456,"y":1},"o":{"x":0.178,"y":0.121},"n":"0p456_1_0p178_0p121","t":73,"s":[2.992,13.768],"e":[0,-154],"to":[0.40790435671806,-12.2535486221313],"ti":[-0.18578809499741,5.58112049102783]},{"t":88}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"rp","c":{"a":0,"k":13,"ix":1},"o":{"a":0,"k":0,"ix":2},"m":1,"ix":2,"tr":{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":27.692,"ix":4},"so":{"a":1,"k":[{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.6],"y":[0]},"n":["0p4_1_0p6_0"],"t":73,"s":[10],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":83,"s":[100],"e":[0]},{"t":91}],"ix":5},"eo":{"a":1,"k":[{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.6],"y":[0]},"n":["0p4_1_0p6_0"],"t":73,"s":[13],"e":[99]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":83,"s":[99],"e":[1]},{"t":91}],"ix":6},"nm":"Transform"},"nm":"Repeater 1","mn":"ADBE Vector Filter - Repeater","hd":false}],"ip":54,"op":540,"st":-40,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[404,302,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.3,0.3],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"n":["0p3_1_0p7_0","0p3_1_0p7_0"],"t":48,"s":[20,0],"e":[0,60]},{"t":67}],"ix":2},"p":{"a":0,"k":[0,-51],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.124487452209,0.808345139027,0.834175884724,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.187980338931,0.750694930553,0.863511025906,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.456,"y":1},"o":{"x":0.178,"y":0.339},"n":"0p456_1_0p178_0p339","t":47,"s":[2.992,13.768],"e":[0,-154],"to":[0.40790435671806,-12.2535486221313],"ti":[-0.18578809499741,5.58112049102783]},{"t":89}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"rp","c":{"a":0,"k":13,"ix":1},"o":{"a":0,"k":0,"ix":2},"m":1,"ix":2,"tr":{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":27.692,"ix":4},"so":{"a":1,"k":[{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.6],"y":[0]},"n":["0p4_1_0p6_0"],"t":42,"s":[10],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":67,"s":[100],"e":[0]},{"t":74}],"ix":5},"eo":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.6],"y":[0]},"n":["0p833_1_0p6_0"],"t":42,"s":[13],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":67,"s":[100],"e":[0]},{"t":74}],"ix":6},"nm":"Transform"},"nm":"Repeater 1","mn":"ADBE Vector Filter - Repeater","hd":false}],"ip":38,"op":524,"st":-56,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[404,302,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.3,0.3],"y":[1,1]},"o":{"x":[0.7,0.7],"y":[0,0]},"n":["0p3_1_0p7_0","0p3_1_0p7_0"],"t":55,"s":[20,0],"e":[0,60]},{"t":74}],"ix":2},"p":{"a":0,"k":[0,-51],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.607843137255,0.321568627451,0.921568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.603921568627,0.345098039216,0.909803921569,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.456,"y":1},"o":{"x":0.178,"y":0.121},"n":"0p456_1_0p178_0p121","t":57,"s":[2.992,13.768],"e":[0,-154],"to":[0.40790435671806,-12.2535486221313],"ti":[-0.18578809499741,5.58112049102783]},{"t":72}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"rp","c":{"a":0,"k":13,"ix":1},"o":{"a":0,"k":0,"ix":2},"m":1,"ix":2,"tr":{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":27.692,"ix":4},"so":{"a":1,"k":[{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.6],"y":[0]},"n":["0p4_1_0p6_0"],"t":57,"s":[10],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":67,"s":[100],"e":[0]},{"t":75}],"ix":5},"eo":{"a":1,"k":[{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.6],"y":[0]},"n":["0p4_1_0p6_0"],"t":57,"s":[13],"e":[99]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":67,"s":[99],"e":[1]},{"t":75}],"ix":6},"nm":"Transform"},"nm":"Repeater 1","mn":"ADBE Vector Filter - Repeater","hd":false}],"ip":38,"op":524,"st":-56,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/5317-fireworkds.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/5317-fireworkds.json deleted file mode 100644 index 6b02a1f7..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/5317-fireworkds.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.13.0","fr":30,"ip":0,"op":150,"w":720,"h":1280,"nm":"portWin","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":15,"ix":10},"p":{"a":0,"k":[568,319.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.057,0.057,0.667],"y":[1,1,1]},"o":{"x":[0,0,0.333],"y":[0,0,0]},"n":["0p057_1_0_0","0p057_1_0_0","0p667_1_0p333_0"],"t":9,"s":[0,0,100],"e":[100,100,100]},{"t":33}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":2,"d":1,"pt":{"a":0,"k":3,"ix":3},"p":{"a":1,"k":[{"i":{"x":0.194,"y":1},"o":{"x":0.054,"y":0},"n":"0p194_1_0p054_0","t":9,"s":[0,0],"e":[0,300],"to":[0,50],"ti":[0,-50]},{"t":33}],"ix":4},"r":{"a":0,"k":0,"ix":5},"or":{"a":0,"k":100,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.194,0.431],"y":[1,1]},"o":{"x":[0.054,0.057],"y":[0,0]},"n":["0p194_1_0p054_0","0p431_1_0p057_0"],"t":9,"s":[50,0],"e":[0,100]},{"t":33}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"rp","c":{"a":0,"k":12,"ix":1},"o":{"a":0,"k":0,"ix":2},"m":1,"ix":2,"tr":{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":30,"ix":4},"so":{"a":0,"k":100,"ix":5},"eo":{"a":0,"k":100,"ix":6},"nm":"Transform"},"nm":"Repeater 1","mn":"ADBE Vector Filter - Repeater","hd":false}],"ip":9,"op":34.5,"st":9,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":7.5,"ix":10},"p":{"a":0,"k":[568,319.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.057,0.057,0.667],"y":[1,1,1]},"o":{"x":[0,0,0.333],"y":[0,0,0]},"n":["0p057_1_0_0","0p057_1_0_0","0p667_1_0p333_0"],"t":9,"s":[0,0,100],"e":[100,100,100]},{"t":30}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":2,"d":1,"pt":{"a":0,"k":3,"ix":3},"p":{"a":1,"k":[{"i":{"x":0.194,"y":1},"o":{"x":0.054,"y":0},"n":"0p194_1_0p054_0","t":9,"s":[0,0],"e":[0,300],"to":[0,50],"ti":[0,-50]},{"t":30}],"ix":4},"r":{"a":0,"k":0,"ix":5},"or":{"a":0,"k":100,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"fl","c":{"a":0,"k":[0.981387867647,0.886240581438,0.30961525113,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.194,0.431],"y":[1,1]},"o":{"x":[0.054,0.057],"y":[0,0]},"n":["0p194_1_0p054_0","0p431_1_0p057_0"],"t":9,"s":[50,0],"e":[0,100]},{"t":30}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"rp","c":{"a":0,"k":24,"ix":1},"o":{"a":0,"k":0,"ix":2},"m":1,"ix":2,"tr":{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":15,"ix":4},"so":{"a":0,"k":100,"ix":5},"eo":{"a":0,"k":100,"ix":6},"nm":"Transform"},"nm":"Repeater 1","mn":"ADBE Vector Filter - Repeater","hd":false}],"ip":7.5,"op":31.5,"st":7.5,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[568,319.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.057,0.057,0.667],"y":[1,1,1]},"o":{"x":[0,0,0.333],"y":[0,0,0]},"n":["0p057_1_0_0","0p057_1_0_0","0p667_1_0p333_0"],"t":6,"s":[0,0,100],"e":[100,100,100]},{"t":27}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":2,"d":1,"pt":{"a":0,"k":3,"ix":3},"p":{"a":1,"k":[{"i":{"x":0.194,"y":1},"o":{"x":0.054,"y":0},"n":"0p194_1_0p054_0","t":6,"s":[0,0],"e":[0,300],"to":[0,50],"ti":[0,-50]},{"t":27}],"ix":4},"r":{"a":0,"k":0,"ix":5},"or":{"a":0,"k":100,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.497633421655,0.16718751496,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.194,0.431],"y":[1,1]},"o":{"x":[0.054,0.057],"y":[0,0]},"n":["0p194_1_0p054_0","0p431_1_0p057_0"],"t":6,"s":[50,0],"e":[0,100]},{"t":27}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"rp","c":{"a":0,"k":12,"ix":1},"o":{"a":0,"k":0,"ix":2},"m":1,"ix":2,"tr":{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":30,"ix":4},"so":{"a":0,"k":100,"ix":5},"eo":{"a":0,"k":100,"ix":6},"nm":"Transform"},"nm":"Repeater 1","mn":"ADBE Vector Filter - Repeater","hd":false}],"ip":6,"op":28.5,"st":6,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[568,319.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[1,0.95],"y":[1,1]},"o":{"x":[0.71,0.333],"y":[0,0]},"n":["1_1_0p71_0","0p95_1_0p333_0"],"t":0,"s":[4,0],"e":[435,4]},{"i":{"x":[0,0],"y":[1,1]},"o":{"x":[0.02,0.087],"y":[0,0]},"n":["0_1_0p02_0","0_1_0p087_0"],"t":7.5,"s":[435,4],"e":[0,3]},{"t":12}],"ix":2},"p":{"a":1,"k":[{"i":{"x":1,"y":1},"o":{"x":0.71,"y":0},"n":"1_1_0p71_0","t":0,"s":[-568,0],"e":[-283,0],"to":[47.5,0],"ti":[-94.6666641235352,0]},{"i":{"x":0,"y":1},"o":{"x":0.02,"y":0},"n":"0_1_0p02_0","t":7.5,"s":[-283,0],"e":[0,0],"to":[94.6666641235352,0],"ti":[-47.1666679382324,0]},{"t":12}],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.615883501838,0.36321997549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":54,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Fireworks","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-62.525,"ix":10},"p":{"a":0,"k":[153.272,612.543,0],"ix":2},"a":{"a":0,"k":[568,319.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1136,"h":639,"ip":26,"op":80,"st":26,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"Fireworks","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-82.434,"ix":10},"p":{"a":0,"k":[315.416,300.741,0],"ix":2},"a":{"a":0,"k":[568,319.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1136,"h":639,"ip":17,"op":71,"st":17,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"Fireworks","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-108.396,"ix":10},"p":{"a":0,"k":[564.728,513.82,0],"ix":2},"a":{"a":0,"k":[568,319.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1136,"h":639,"ip":8,"op":62,"st":8,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"Fireworks","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-119.562,"ix":10},"p":{"a":0,"k":[360,640,0],"ix":2},"a":{"a":0,"k":[568,319.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1136,"h":639,"ip":0,"op":54,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"Fireworks","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-105.393,"ix":10},"p":{"a":0,"k":[253.284,768.545,0],"ix":2},"a":{"a":0,"k":[568,319.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1136,"h":639,"ip":98,"op":152,"st":98,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"Fireworks","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-125.303,"ix":10},"p":{"a":0,"k":[415.429,456.742,0],"ix":2},"a":{"a":0,"k":[568,319.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1136,"h":639,"ip":89,"op":143,"st":89,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"Fireworks","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-151.264,"ix":10},"p":{"a":0,"k":[664.741,669.822,0],"ix":2},"a":{"a":0,"k":[568,319.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1136,"h":639,"ip":80,"op":134,"st":80,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"Fireworks","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-162.431,"ix":10},"p":{"a":0,"k":[460.013,796.002,0],"ix":2},"a":{"a":0,"k":[568,319.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1136,"h":639,"ip":72,"op":126,"st":72,"bm":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/5344-honey-sack-hud.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/5344-honey-sack-hud.json deleted file mode 100644 index 8eedfc96..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/5344-honey-sack-hud.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.2.1","fr":29.9700012207031,"ip":4.00000016292334,"op":35.0000014255792,"w":420,"h":420,"nm":"Cred points_Bg Pattern_Anim","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 70","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.251,8.5]],"o":[[-0.246,-8.5],[0,0]],"v":[[97,165.5],[96,131.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 69","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0]],"o":[[0,0]],"v":[[209,99.25]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[6.167,2.833]],"o":[[-6.25,2.667],[0,0],[0,0]],"v":[[206.25,82.25],[187.5,90.25],[169,81.75]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":4,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 68","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.562,2.128]],"o":[[-4.565,-2.117],[0,0]],"v":[[187,173],[168.75,164.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 67","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[6.167,3]],"o":[[-5.333,-2.833],[0,0],[0,0],[0,0]],"v":[[149.5,172.5],[133.5,164],[133,132.5],[114.5,123.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 66","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.499,-2.252]],"o":[[-4.502,2.243],[0,0]],"v":[[187,-204],[169,-195]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 65","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0.25,10.917],[0,0],[0,0]],"v":[[151.25,-236],[152,-203.25],[131,-194.25]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 64","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.127,-8]],"o":[[0.12,8],[0,0]],"v":[[41,-235],[41.5,-203]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Shape Layer 63","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-4.999,-3.252]],"o":[[5.002,3.245],[0,0]],"v":[[-215,-208],[-195,-195]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Shape Layer 62","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[5.667,-2.667]],"o":[[-5.333,-2.333],[0,0],[0,0]],"v":[[221,-155],[205,-162],[188,-154]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Shape Layer 61","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,11]],"o":[[-6.167,-2.833],[0,0],[0,0]],"v":[[205.5,50],[187,41.5],[187,8.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Shape Layer 60","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-5.333,3]],"o":[[5.333,-3],[0,0],[0,0],[0,0]],"v":[[-193,132],[-177,123],[-157,133],[-141,124]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Shape Layer 59","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,11.167]],"o":[[0,-10.833],[0,0],[0,0],[0,0]],"v":[[-105,206],[-105,173.5],[-86.5,165],[-86.5,131.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Shape Layer 58","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,11.167]],"o":[[0,-10.833],[0,0],[0,0],[0,0]],"v":[[77,205.5],[77,173],[60,164.5],[60,131]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Shape Layer 57","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.126,8]],"o":[[-0.121,-8],[0,0]],"v":[[-30,206],[-30.5,174]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Shape Layer 56","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.691,2.222]],"o":[[-4.926,-2.333],[0,0]],"v":[[-140.5,-71.5],[-159.5,-80.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Shape Layer 55","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-4.999,2.248]],"o":[[5.002,-2.255],[0,0]],"v":[[-198,-29],[-178,-38]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Shape Layer 54","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.333,10.833]],"o":[[6,3.5],[0,0],[0,0],[0,0]],"v":[[-213.5,39],[-195.5,49.5],[-177.5,41.5],[-176.5,9]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Shape Layer 53","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0]],"o":[[0,0]],"v":[[-177.5,-40]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.247,7.531]],"o":[[-0.259,-7.907],[0,0]],"v":[[-123,0],[-124,-30.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[2],"e":[0.5]},{"t":48.0000019550801}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.775,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[100],"e":[0]},{"t":33.225001353282}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":4,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"Shape Layer 50","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[5.667,2.667]],"o":[[0,-10.5],[0,0],[0,0],[0,0],[0,0]],"v":[[150.5,122.5],[150.5,91],[132.5,83],[114.5,91],[97.5,83]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Shape Layer 49","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.333,9.5]],"o":[[4.167,-1.667],[0,0],[0,0]],"v":[[48,87.5],[60.5,82.5],[59.5,54]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"Shape Layer 48","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,11]],"o":[[0,-10.167],[0,0],[0,0],[0,0]],"v":[[77,122],[77,91.5],[96.5,82.5],[96.5,49.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":"Shape Layer 47","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[5.333,-3]],"o":[[-6.667,2.667],[0,0],[0,0],[0,0]],"v":[[187,-122],[167,-114],[151,-124],[135,-115]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":23,"ty":4,"nm":"Shape Layer 45","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,-10.333]],"o":[[0,10.667],[0,0],[0,0],[0,0]],"v":[[96,-194],[96,-162],[78,-153],[78,-122]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":24,"ty":4,"nm":"Shape Layer 43","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,11]],"o":[[-5.667,-2.833],[0,0],[0,0],[0,0],[0,0]],"v":[[204.5,-32.5],[187.5,-41],[168.5,-31.5],[150.5,-40],[150.5,-73]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":25,"ty":4,"nm":"Shape Layer 41","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-4.691,2.346]],"o":[[4.926,-2.463],[0,0]],"v":[[22,50],[41,40.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":26,"ty":4,"nm":"Shape Layer 40","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[6.167,3.333]],"o":[[-0.167,-10.667],[0,0],[0,0]],"v":[[41.5,124],[41,92],[22.5,82]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":27,"ty":4,"nm":"Shape Layer 36","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.167,10.333]],"o":[[-5.667,-3.167],[0,0],[0,0]],"v":[[150.5,9.5],[133.5,0],[133,-31]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":28,"ty":4,"nm":"Shape Layer 34","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[5.333,2.167]],"o":[[-6.333,-2.667],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[187.5,-72.5],[168.5,-80.5],[151,-72],[132.5,-81.5],[131.5,-113],[115.5,-119.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":34,"s":[2],"e":[0.5]},{"t":43.0000017514259}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":17.775,"s":[100],"e":[0]},{"t":41.0000016699642}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":5,"s":[100],"e":[0]},{"t":28.2250011496278}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":-1.00000004073083,"op":299.00001217852,"st":-1.00000004073083,"bm":0},{"ddd":0,"ind":29,"ty":4,"nm":"Shape Layer 33","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,-10.667]],"o":[[-0.167,10],[0,0],[0,0],[0,0]],"v":[[78.5,-233.5],[78,-203.5],[60.5,-195.5],[60.5,-163.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":34,"s":[2],"e":[0.5]},{"t":43.0000017514259}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":30,"ty":4,"nm":"Shape Layer 32","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,10.167]],"o":[[-5.167,3.5],[0,0],[0,0],[0,0]],"v":[[149.5,-41.5],[134,-31],[115,-40.5],[115,-71]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":34,"s":[2],"e":[0.5]},{"t":43.0000017514259}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":31,"ty":4,"nm":"Shape Layer 24","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,-10.167]],"o":[[-5.667,3],[0,0],[0,0]],"v":[[168.5,1],[151.5,10],[151.5,40.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":32,"ty":4,"nm":"Shape Layer 22","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[6,3.333]],"o":[[-6.167,3.167],[0,0],[0,0]],"v":[[169.5,-163],[151,-153.5],[133,-163.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":33,"ty":4,"nm":"Shape Layer 21","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[6.667,-2.667]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[132.5,-194],[133,-162.5],[114,-153],[115,-120.5],[95,-112.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":34,"ty":4,"nm":"Shape Layer 20","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,10.5]],"o":[[-6.333,-2.833],[0,0],[0,0]],"v":[[60,49],[41,40.5],[41,9]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":35,"ty":4,"nm":"Shape Layer 17","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.44,2.18]],"o":[[-4.437,-2.19],[0,0]],"v":[[40.5,-72.5],[22.75,-81.25]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":36,"ty":4,"nm":"Shape Layer 16","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[6.333,-2.5]],"o":[[-6.333,-3],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[170,50],[151,41],[132.5,51],[114.5,42],[114.5,9.5],[96,1.5],[77,9]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":37,"ty":4,"nm":"Shape Layer 12","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.63,2.127]],"o":[[-4.61,-2.118],[0,0]],"v":[[59,-32],[40.5,-40.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":38,"ty":4,"nm":"Shape Layer 11","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[6,2.667]],"o":[[-0.167,-10.833],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[23.5,165],[23,132.5],[4.5,123],[6,90],[23,82],[23,50.5],[5.5,42],[4.5,9],[-13.5,1]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":39,"ty":4,"nm":"Shape Layer 9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.167,-10.667]],"o":[[-5.833,3.167],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[132,-81.5],[114.5,-72],[96,-80.5],[95,-113],[77.5,-121],[59,-113],[59.5,-81]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":40,"ty":4,"nm":"Shape Layer 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0]],"o":[[0,0]],"v":[[78,-72]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[6,-2.833]],"o":[[0.167,11.667],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[22.5,-197],[23,-162],[4,-154],[5,-122],[-14,-113.5],[-13.5,-82],[-31.5,-73.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":41,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[5.833,2.5]],"o":[[-6.667,2.667],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[115,-40.5],[95,-32.5],[78.5,-40],[78.5,-71.5],[59,-81],[40.5,-72],[40.5,-40.5],[22,-32.5],[4.5,-40]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":42,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,-10.667]],"o":[[-6,-2.833],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[78.5,-154.5],[60.5,-163],[41.5,-154],[41,-122.5],[23,-114],[23,-81.5],[4.5,-73],[4.5,-41]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":43,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[255,210,0],"ix":2},"a":{"a":0,"k":[5,-40,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[6,2.833]],"o":[[-6,-2.917],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[78,90],[60,81.25],[60,49.5],[78.25,40.25],[77.5,9.25],[59.5,0],[41,8.75],[22.5,0.5],[22.5,-32.25],[4.5,-40.75]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":44,"ty":4,"nm":"Shape Layer 52","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-6,3]],"o":[[6.5,3.167],[0,0],[0,0]],"v":[[-178,-204],[-158.5,-194.5],[-140.5,-203.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":45,"ty":4,"nm":"Shape Layer 51","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,-11]],"o":[[0,10.833],[0,0],[0,0],[0,0]],"v":[[-67.5,-235.5],[-67.5,-203],[-49.5,-195],[-49.5,-162]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":46,"ty":4,"nm":"Shape Layer 46","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[5.667,-3],[0,0],[0,0],[0,0]],"v":[[-176,9],[-159,0],[-141,8],[-141,41]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":47,"ty":4,"nm":"Shape Layer 44","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-5,1.667]],"o":[[6,-2.333],[0,0],[0,0],[0,0]],"v":[[-141,90],[-123,83],[-123,49],[-108,44]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":48,"ty":4,"nm":"Shape Layer 42","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-4.506,-2.562]],"o":[[4.482,2.565],[0,0]],"v":[[-122,-163],[-104,-152.75]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":49,"ty":4,"nm":"Shape Layer 39","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-7.654]],"o":[[0,8.037],[0,0]],"v":[[-68.5,-153.5],[-68.5,-122.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":50,"ty":4,"nm":"Shape Layer 38","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.252,8.75]],"o":[[-0.245,-8.75],[0,0]],"v":[[-32,125],[-33,90]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":51,"ty":4,"nm":"Shape Layer 37","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[-5.5,-2.5]],"o":[[5.5,2.833],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-12.5,-244],[4,-235.5],[5.5,-204.5],[-13.5,-196],[-12.5,-162],[4,-154.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":52,"ty":4,"nm":"Shape Layer 35","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,-11.167]],"o":[[6.667,3],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-196.5,-163],[-176.5,-154],[-160,-162.5],[-142,-155.5],[-141,-121.5],[-123,-114.5],[-121.5,-80.5],[-141.5,-72.5],[-141.5,-39]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":17.775,"s":[100],"e":[0]},{"t":41.0000016699642}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":5,"s":[100],"e":[0]},{"t":28.2250011496278}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":53,"ty":4,"nm":"Shape Layer 31","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-4.568,-1.852]],"o":[[4.796,1.944],[0,0]],"v":[[-31.5,-121.5],[-13,-114]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":34,"s":[2],"e":[0.5]},{"t":43.0000017514259}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":54,"ty":4,"nm":"Shape Layer 30","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,8.272]],"o":[[0,-8.685],[0,0]],"v":[[95.5,1],[95.5,-32.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":34,"s":[2],"e":[0.5]},{"t":43.0000017514259}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":55,"ty":4,"nm":"Shape Layer 29","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,7.901]],"o":[[0,-8.296],[0,0]],"v":[[-50,0.5],[-50,-31.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":34,"s":[2],"e":[0.5]},{"t":43.0000017514259}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":56,"ty":4,"nm":"Shape Layer 28","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[6,3]],"o":[[0,-10.333],[0,0],[0,0]],"v":[[-50,81.5],[-50,50.5],[-68,41.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":34,"s":[2],"e":[0.5]},{"t":43.0000017514259}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":57,"ty":4,"nm":"Shape Layer 27","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.624,2.128]],"o":[[-4.627,-2.117],[0,0]],"v":[[-67.5,90.75],[-86,82.25]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":58,"ty":4,"nm":"Shape Layer 26","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-6.167,2.667]],"o":[[5.667,-2.5],[0,0],[0,0],[0,0]],"v":[[-122,131],[-105,123.5],[-86,132],[-67.5,124]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":59,"ty":4,"nm":"Shape Layer 25","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-6,3.167]],"o":[[0,-10.667],[0,0],[0,0]],"v":[[-13.5,165],[-13.5,133],[4.5,123.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":60,"ty":4,"nm":"Shape Layer 19","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-6,-2.667]],"o":[[0.167,10.833],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-141.5,-236],[-141,-203.5],[-123,-193.5],[-104,-203],[-86.5,-195],[-86.5,-162],[-104.5,-152.5],[-104.5,-121],[-86.5,-113]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":61,"ty":4,"nm":"Shape Layer 18","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-4.752,2.493]],"o":[[4.749,-2.502],[0,0]],"v":[[-87,-31],[-68,-41]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":62,"ty":4,"nm":"Shape Layer 15","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-5.833,2.833]],"o":[[6,-2.75],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-195.75,-113.75],[-177.75,-122],[-158.75,-112.75],[-159.25,-80.75],[-178.25,-72.5],[-176.5,-39],[-158.5,-31.5],[-140.5,-39.5],[-123,-31.5],[-105.5,-40]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":63,"ty":4,"nm":"Shape Layer 14","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[-6,-3]],"o":[[6,2.667],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-159.5,1],[-141.5,9],[-122.5,-0.5],[-105,9],[-105,41],[-87,50]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":64,"ty":4,"nm":"Shape Layer 13","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.167,10.667]],"o":[[0,-11],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-49.5,165.5],[-49.5,132.5],[-67.5,124],[-67.5,91],[-50,82],[-31.5,91.5],[-13,82],[-14,50.5],[-32.5,41.5],[-32,9.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":65,"ty":4,"nm":"Shape Layer 10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,251,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-6,2.833]],"o":[[6,2.667],[0,0],[0,0],[0,0],[0,0]],"v":[[-86.25,-80.75],[-68.25,-72.75],[-68,-40.5],[-50,-32],[-32,-40.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":66,"ty":4,"nm":"Shape Layer 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0.333,10],[0,0],[0,0],[0,0],[0,0]],"v":[[-50.5,-192],[-49.5,-162],[-31.5,-154],[-32,-122],[-48.5,-114]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":67,"ty":4,"nm":"Shape Layer 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,10.5]],"o":[[6.083,-3],[0,0],[0,0],[0,0],[0,0]],"v":[[-105,8.75],[-86.75,-0.25],[-86.75,-31.75],[-105.5,-41],[-105.5,-72.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":68,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249,250.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-5.833,-2.833]],"o":[[5.833,2.833],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-122.5,-81],[-105,-72.5],[-86,-81],[-86.5,-113],[-68.5,-123],[-50,-113.5],[-50,-81],[-32,-74],[-32,-41],[-14.5,-32.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":69,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[254.5,210,0],"ix":2},"a":{"a":0,"k":[5.5,-40.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-18,8.5]],"o":[[0,-6.333],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-105.5,110],[-105.5,91],[-86.5,81.5],[-87,49.5],[-68,41.5],[-67,8.5],[-49.5,0],[-32,9],[-13.5,0],[-13.5,-32.5],[4.5,-41]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.172549019608,0.862745157878,0.737254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[2],"e":[0.5]},{"t":44.0000017921567}],"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":18.775,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":29.2250011903587}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"pattern 12","refId":"comp_0","sr":0.8,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[207,250.75,0],"ix":2},"a":{"a":0,"k":[250,250,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[112.666,0],[0,-112.666],[-112.666,0],[0,112.666]],"o":[[-112.666,0],[0,112.666],[112.666,0],[0,-112.666]],"v":[[253.926,5.082],[49.926,209.082],[253.926,413.082],[457.926,209.082]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"w":500,"h":500,"ip":0,"op":240.0000097754,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/Indicators1.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/Indicators1.json deleted file mode 100644 index 742c48bc..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/Indicators1.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.6.9","fr":29.9700012207031,"ip":0,"op":427.000017392067,"w":800,"h":600,"nm":"Indicators 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":1,"y":0},"n":"0p833_0p833_1_0","t":0,"s":[325.441,300.5,0],"e":[350.147,300.5,0],"to":[4.11765050888062,0,0],"ti":[-8.34681701660156,0,0]},{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":20,"s":[350.147,300.5,0],"e":[375.522,300.5,0],"to":[8.34681701660156,0,0],"ti":[-4.22916650772095,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":45,"s":[375.522,300.5,0],"e":[375.522,300.5,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":1,"y":0},"n":"0p833_0p833_1_0","t":65,"s":[375.522,300.5,0],"e":[400.772,300.5,0],"to":[4.20833349227905,0,0],"ti":[-8.33333301544189,0,0]},{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":85,"s":[400.772,300.5,0],"e":[425.522,300.5,0],"to":[8.33333301544189,0,0],"ti":[-4.125,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":110,"s":[425.522,300.5,0],"e":[425.522,300.5,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":1,"y":0},"n":"0p833_0p833_1_0","t":130,"s":[425.522,300.5,0],"e":[450.853,300.5,0],"to":[4.22176122665405,0,0],"ti":[-8.33941173553467,0,0]},{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":150,"s":[450.853,300.5,0],"e":[475.559,300.5,0],"to":[8.33941173553467,0,0],"ti":[-4.11765050888062,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":175,"s":[475.559,300.5,0],"e":[475.559,300.5,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":1,"y":0},"n":"0p833_0p833_1_0","t":195,"s":[475.559,300.5,0],"e":[450.853,300.5,0],"to":[-4.11765050888062,0,0],"ti":[8.32598400115967,0,0]},{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":215,"s":[450.853,300.5,0],"e":[425.603,300.5,0],"to":[-8.32598400115967,0,0],"ti":[4.20833349227905,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":240,"s":[425.603,300.5,0],"e":[425.603,300.5,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":1,"y":0},"n":"0p833_0p833_1_0","t":260,"s":[425.603,300.5,0],"e":[400.228,300.5,0],"to":[-4.22916650772095,0,0],"ti":[8.34375,0,0]},{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":280,"s":[400.228,300.5,0],"e":[375.54,300.5,0],"to":[-8.34375,0,0],"ti":[4.11458349227905,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":305,"s":[375.54,300.5,0],"e":[375.54,300.5,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":1,"y":0},"n":"0p833_0p833_1_0","t":325,"s":[375.54,300.5,0],"e":[350.147,300.5,0],"to":[-4.232177734375,0,0],"ti":[8.34982776641846,0,0]},{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":345,"s":[350.147,300.5,0],"e":[325.441,300.5,0],"to":[-8.34982776641846,0,0],"ti":[4.11765050888062,0,0]},{"t":370.000015070409}]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":1,"y":0},"n":"0p833_0p833_1_0","t":0,"s":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}],"e":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[24.706,12.5],[-24.706,12.5],[-37.206,0],[-37.206,0],[-24.706,-12.5],[24.706,-12.5],[37.206,0],[37.206,0]],"c":true}]},{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":20,"s":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[24.706,12.5],[-24.706,12.5],[-37.206,0],[-37.206,0],[-24.706,-12.5],[24.706,-12.5],[37.206,0],[37.206,0]],"c":true}],"e":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":45,"s":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}],"e":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":1,"y":0},"n":"0p833_0p833_1_0","t":65,"s":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}],"e":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[24.706,12.5],[-24.706,12.5],[-37.206,0],[-37.206,0],[-24.706,-12.5],[24.706,-12.5],[37.206,0],[37.206,0]],"c":true}]},{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":85,"s":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[24.706,12.5],[-24.706,12.5],[-37.206,0],[-37.206,0],[-24.706,-12.5],[24.706,-12.5],[37.206,0],[37.206,0]],"c":true}],"e":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":110,"s":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}],"e":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":1,"y":0},"n":"0p833_0p833_1_0","t":130,"s":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}],"e":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[24.706,12.5],[-24.706,12.5],[-37.206,0],[-37.206,0],[-24.706,-12.5],[24.706,-12.5],[37.206,0],[37.206,0]],"c":true}]},{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":150,"s":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[24.706,12.5],[-24.706,12.5],[-37.206,0],[-37.206,0],[-24.706,-12.5],[24.706,-12.5],[37.206,0],[37.206,0]],"c":true}],"e":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":175,"s":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}],"e":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":1,"y":0},"n":"0p833_0p833_1_0","t":195,"s":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}],"e":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[24.706,12.5],[-24.706,12.5],[-37.206,0],[-37.206,0],[-24.706,-12.5],[24.706,-12.5],[37.206,0],[37.206,0]],"c":true}]},{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":215,"s":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[24.706,12.5],[-24.706,12.5],[-37.206,0],[-37.206,0],[-24.706,-12.5],[24.706,-12.5],[37.206,0],[37.206,0]],"c":true}],"e":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":240,"s":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}],"e":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":1,"y":0},"n":"0p833_0p833_1_0","t":260,"s":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}],"e":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[24.706,12.5],[-24.706,12.5],[-37.206,0],[-37.206,0],[-24.706,-12.5],[24.706,-12.5],[37.206,0],[37.206,0]],"c":true}]},{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":280,"s":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[24.706,12.5],[-24.706,12.5],[-37.206,0],[-37.206,0],[-24.706,-12.5],[24.706,-12.5],[37.206,0],[37.206,0]],"c":true}],"e":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":305,"s":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}],"e":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":1,"y":0},"n":"0p833_0p833_1_0","t":325,"s":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}],"e":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[24.706,12.5],[-24.706,12.5],[-37.206,0],[-37.206,0],[-24.706,-12.5],[24.706,-12.5],[37.206,0],[37.206,0]],"c":true}]},{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":345,"s":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[24.706,12.5],[-24.706,12.5],[-37.206,0],[-37.206,0],[-24.706,-12.5],[24.706,-12.5],[37.206,0],[37.206,0]],"c":true}],"e":[{"i":[[6.875,0],[0,0],[0,6.875],[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0]],"o":[[0,0],[-6.875,0],[0,0],[0,-6.875],[0,0],[6.875,0],[0,0],[0,6.875]],"v":[[0,12.5],[0,12.5],[-12.5,0],[-12.5,0],[0,-12.5],[0,-12.5],[12.5,0],[12.5,0]],"c":true}]},{"t":370.000015070409}]},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.105882,0.105882,0.105882,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":450.000018328876,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 2","ks":{"o":{"a":0,"k":25},"r":{"a":0,"k":0},"p":{"a":0,"k":[375.559,300.5,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.904,0],[0,-6.903],[-6.903,0],[0,6.903]],"o":[[-6.903,0],[0,6.903],[6.904,0],[0,-6.903]],"v":[[100,-12.5],[87.5,0],[100,12.5],[112.5,0]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.105882,0.105882,0.105882,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 4","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.903,0],[0,-6.903],[-6.903,0],[0,6.903]],"o":[[-6.903,0],[0,6.903],[6.903,0],[0,-6.903]],"v":[[50,-12.5],[37.5,0],[50,12.5],[62.5,0]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.105882,0.105882,0.105882,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 3","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.904,0],[0,-6.903],[-6.903,0],[0,6.903]],"o":[[-6.903,0],[0,6.903],[6.904,0],[0,-6.903]],"v":[[0,-12.5],[-12.5,0],[0,12.5],[12.5,0]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.105882,0.105882,0.105882,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-6.903],[6.904,0],[0,6.903],[-6.903,0]],"o":[[0,6.903],[-6.903,0],[0,-6.903],[6.904,0]],"v":[[-61.617,0],[-74.117,12.5],[-86.617,0],[-74.117,-12.5]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.105882,0.105882,0.105882,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[24,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":4,"mn":"ADBE Vector Group"}],"ip":0,"op":450.000018328876,"st":0,"bm":0,"sr":1}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/ModernPictogramsForLottie_LoudMute.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/ModernPictogramsForLottie_LoudMute.json deleted file mode 100644 index ac8e09ce..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/ModernPictogramsForLottie_LoudMute.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.10.1","fr":60,"ip":0,"op":88,"w":800,"h":800,"nm":"LoudMute_Preview","ddd":0,"assets":[{"id":"comp_43","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Waves 4","parent":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.25,"y":0},"n":"0p833_0p833_0p25_0","t":1,"s":[76.303,74.511,0],"e":[56.303,74.511,0],"to":[-3.33333325386047,0,0],"ti":[3.33333325386047,0,0]},{"t":14}],"ix":2},"a":{"a":0,"k":[76.303,74.511,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,1]},"o":{"x":[0.25,0.25,0.25],"y":[0,0,0]},"n":["0p833_0p833_0p25_0","0p833_0p833_0p25_0","0p833_1_0p25_0"],"t":1,"s":[100,100,100],"e":[10,10,100]},{"t":14}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,11.05],[8.061,8.06],[0,0],[0,-13.78],[10.531,-10.531]],"o":[[8.061,-7.931],[0,-10.92],[0,0],[10.14,10.14],[0,12.87],[0,0]],"v":[[23.401,29.836],[35.492,-0.065],[23.401,-30.096],[30.292,-36.986],[46.022,0.585],[30.681,36.986]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[76.303,74.511],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":12,"st":-126,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Waves 3","parent":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.25,"y":0},"n":"0p833_0p833_0p25_0","t":1,"s":[76.303,74.511,0],"e":[56.303,74.511,0],"to":[-3.33333325386047,0,0],"ti":[3.33333325386047,0,0]},{"t":14}],"ix":2},"a":{"a":0,"k":[76.303,74.511,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,1]},"o":{"x":[0.25,0.25,0.25],"y":[0,0,0]},"n":["0p833_0p833_0p25_0","0p833_0p833_0p25_0","0p833_1_0p25_0"],"t":1,"s":[100,100,100],"e":[10,10,100]},{"t":14}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,6.239],[4.42,4.551],[0,0],[0,-8.71],[7.151,-7.021]],"o":[[4.681,-4.68],[0,-6.11],[0,0],[6.37,6.501],[0,7.93],[0,0]],"v":[[8.84,16.835],[15.991,-0.585],[9.361,-17.096],[15.731,-23.466],[25.872,0.195],[15.601,23.466]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[76.303,74.511],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":12,"st":-126,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"StrikeOut","parent":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[34.642,37.517,0],"ix":2},"a":{"a":0,"k":[-26.733,-37.483,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":5,"s":[0,0,100],"e":[100,100,100]},{"t":7}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-26.75,-37.5],[40.5,29.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.19],"y":[1]},"o":{"x":[0.328],"y":[0]},"n":["0p19_1_0p328_0"],"t":7,"s":[0],"e":[0]},{"t":30}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.19],"y":[1]},"o":{"x":[0.328],"y":[-0.008]},"n":["0p19_1_0p328_-0p008"],"t":7,"s":[0.05],"e":[100]},{"t":30}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":5,"op":32,"st":-13,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"StrikeOutMatte","parent":5,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[66.533,75,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"n":"0_1_0p333_0","t":7,"s":[{"i":[[0,0],[0,0],[-15.409,-15.602],[2.12,-1.823],[2.829,2.891],[0,0],[0,0],[0,0],[-1,0.25],[0,0]],"o":[[0,0],[0,0],[3.254,3.295],[-2.194,1.886],[-7.913,-8.089],[0,0],[0,0],[0,0],[1,-0.25],[0,0]],"v":[[12.25,-60.25],[-102.807,-117.884],[-28.583,-43.548],[-28.734,-33.862],[-37.96,-34.576],[-112.917,-109.231],[-52.75,-30.75],[-52.25,54.75],[43.5,62.75],[45.75,-58.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[-15.409,-15.602],[2.12,-1.823],[2.829,2.891],[0,0],[0,0],[0,0],[-1,0.25],[0,0]],"o":[[0,0],[0,0],[3.254,3.295],[-2.194,1.886],[-7.913,-8.089],[0,0],[0,0],[0,0],[1,-0.25],[0,0]],"v":[[12.25,-60.25],[-34.407,-49.484],[39.817,24.852],[39.666,34.538],[30.44,33.824],[-44.517,-40.831],[-52.75,-30.75],[-52.25,54.75],[43.5,62.75],[45.75,-58.75]],"c":true}]},{"t":30}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-4,"op":52,"st":-4,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Sound","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.19,"y":1},"o":{"x":0.25,"y":0},"n":"0p19_1_0p25_0","t":7,"s":[76.303,74.511,0],"e":[89.928,74.511,0],"to":[2.27083325386047,0,0],"ti":[-2.27083325386047,0,0]},{"t":30}],"ix":2},"a":{"a":0,"k":[76.303,74.511,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1.82,39.196],[-22.491,14.885],[-46.022,14.885],[-46.022,-14.885],[-22.491,-14.885],[1.82,-39.196]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[76.303,74.511],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":32,"st":-13,"bm":0}]},{"id":"comp_44","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Waves 2","parent":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.19,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p19_1_0p167_0p167","t":15,"s":[56.303,74.511,0],"e":[76.303,74.511,0],"to":[3.33333325386047,0,0],"ti":[-3.33333325386047,0,0]},{"t":47}],"ix":2},"a":{"a":0,"k":[76.303,74.511,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.19,0.19,0.19],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,15]},"n":["0p19_1_0p167_0p167","0p19_1_0p167_0p167","0p19_1_0p167_15"],"t":15,"s":[10,10,100],"e":[100,100,100]},{"t":47}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,11.05],[8.061,8.06],[0,0],[0,-13.78],[10.531,-10.531]],"o":[[8.061,-7.931],[0,-10.92],[0,0],[10.14,10.14],[0,12.87],[0,0]],"v":[[23.401,29.836],[35.492,-0.065],[23.401,-30.096],[30.292,-36.986],[46.022,0.585],[30.681,36.986]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[76.303,74.511],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":15,"op":56,"st":-98,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Waves","parent":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.19,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p19_1_0p167_0p167","t":17,"s":[56.303,74.511,0],"e":[76.303,74.511,0],"to":[3.33333325386047,0,0],"ti":[-3.33333325386047,0,0]},{"t":54}],"ix":2},"a":{"a":0,"k":[76.303,74.511,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.19,0.19,0.19],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,15]},"n":["0p19_1_0p167_0p167","0p19_1_0p167_0p167","0p19_1_0p167_15"],"t":17,"s":[10,10,100],"e":[100,100,100]},{"t":54}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,6.239],[4.42,4.551],[0,0],[0,-8.71],[7.151,-7.021]],"o":[[4.681,-4.68],[0,-6.11],[0,0],[6.37,6.501],[0,7.93],[0,0]],"v":[[8.84,16.835],[15.991,-0.585],[9.361,-17.096],[15.731,-23.466],[25.872,0.195],[15.601,23.466]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[76.303,74.511],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":17,"op":56,"st":-96,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"StrikeOut","parent":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[34.642,37.517,0],"ix":2},"a":{"a":0,"k":[-26.733,-37.483,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":22,"s":[100,100,100],"e":[0,0,100]},{"t":29}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-26.75,-37.5],[40.5,29.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.108],"y":[1]},"o":{"x":[0.256],"y":[0]},"n":["0p108_1_0p256_0"],"t":1,"s":[0],"e":[0]},{"t":22}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.108],"y":[0.981]},"o":{"x":[0.256],"y":[0]},"n":["0p108_0p981_0p256_0"],"t":1,"s":[100],"e":[0.05]},{"t":22}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":38,"st":-98,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"StrikeOutMatte","parent":5,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[66.418,75,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"n":"0_1_0p333_0","t":1,"s":[{"i":[[0,0],[0,0],[-15.409,-15.602],[2.12,-1.823],[2.829,2.891],[0,0],[0,0],[0,0],[-1,0.25],[0,0]],"o":[[0,0],[0,0],[3.254,3.295],[-2.194,1.886],[-7.913,-8.089],[0,0],[0,0],[0,0],[1,-0.25],[0,0]],"v":[[12.25,-60.25],[-34.407,-49.484],[39.817,24.852],[39.666,34.538],[30.44,33.824],[-44.517,-40.831],[-52.75,-30.75],[-52.25,54.75],[43.5,62.75],[45.75,-58.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[-15.409,-15.602],[2.12,-1.823],[2.829,2.891],[0,0],[0,0],[0,0],[-1,0.25],[0,0]],"o":[[0,0],[0,0],[3.254,3.295],[-2.194,1.886],[-7.913,-8.089],[0,0],[0,0],[0,0],[1,-0.25],[0,0]],"v":[[12.25,-60.25],[-102.807,-117.884],[-28.583,-43.548],[-28.734,-33.862],[-37.96,-34.576],[-112.917,-109.231],[-52.75,-30.75],[-52.25,54.75],[43.5,62.75],[45.75,-58.75]],"c":true}]},{"t":24}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":56,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Sound","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.1,"y":1},"o":{"x":0.25,"y":0},"n":"0p1_1_0p25_0","t":1,"s":[89.928,74.511,0],"e":[76.303,74.511,0],"to":[-2.27083325386047,0,0],"ti":[2.27083325386047,0,0]},{"t":30}],"ix":2},"a":{"a":0,"k":[76.303,74.511,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1.82,39.196],[-22.491,14.885],[-46.022,14.885],[-46.022,-14.885],[-22.491,-14.885],[1.82,-39.196]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[76.303,74.511],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":56,"st":-98,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"LoudMute_Mute","refId":"comp_43","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[75,75,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":150,"h":150,"ip":56,"op":88,"st":56,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"LoudMute_Loud","refId":"comp_44","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[75,75,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":150,"h":150,"ip":0,"op":56,"st":0,"bm":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/StickAndBall.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/StickAndBall.json deleted file mode 100644 index 423b284d..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/StickAndBall.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.7.0","fr":24,"ip":0,"op":23,"w":1080,"h":1080,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"#ball","ln":"ball","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"s":true,"x":{"a":0,"k":539},"y":{"a":1,"k":[{"i":{"x":[0.339],"y":[1]},"o":{"x":[0.893],"y":[0]},"n":["0p339_1_0p893_0"],"t":0,"s":[219],"e":[554]},{"i":{"x":[0.075],"y":[1]},"o":{"x":[0.622],"y":[0]},"n":["0p075_1_0p622_0"],"t":11,"s":[554],"e":[219]},{"t":22}]}},"a":{"a":0,"k":[-130,-257,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":2,"s":[94,94],"e":[85,122]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":5,"s":[85,122],"e":[94,94]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":7,"s":[94,94],"e":[94,92]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":11,"s":[94,92],"e":[94,94]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":15,"s":[94,94],"e":[84,118]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":17,"s":[84,118],"e":[94,94]},{"t":19}]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[1,1,1,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"a":0,"k":[0.9019608,0.4032295,0.6379266,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-129,-257],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":23,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"#stick","ln":"stick","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":5,"s":[90],"e":[75.623]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":6,"s":[75.623],"e":[65.727]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":7,"s":[65.727],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":11,"s":[0],"e":[-37.333]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":13,"s":[-37.333],"e":[-41]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":14,"s":[-41],"e":[-66]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[-66],"e":[-82]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":16,"s":[-82],"e":[-90]},{"t":17}]},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[541.19,619.31,0],"e":[541.44,617.06,0],"to":[0.04166666790843,-0.375,0],"ti":[-0.04166666790843,0.375,0]},{"t":22}]},"a":{"a":0,"k":[251.515,7.576,0]},"s":{"a":0,"k":[33,33,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":13,"s":[{"i":[[-248.361,0],[-247.665,0]],"o":[[308.273,0],[237.183,0]],"v":[[-487.636,3.94],[983.453,7.879]],"c":false}],"e":[{"i":[[-243.183,50.45],[-568.665,-169.629]],"o":[[453.246,-94.029],[331.868,98.994]],"v":[[-487.636,3.94],[983.453,7.879]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":15,"s":[{"i":[[-243.183,50.45],[-568.665,-169.629]],"o":[[453.246,-94.029],[331.868,98.994]],"v":[[-487.636,3.94],[983.453,7.879]],"c":false}],"e":[{"i":[[-247.951,-14.258],[-458.271,96.09]],"o":[[469.414,26.993],[232.133,-48.674]],"v":[[-487.636,3.94],[983.453,-89.091]],"c":false}]},{"i":{"x":0.333,"y":1},"o":{"x":0.333,"y":0},"n":"0p333_1_0p333_0","t":18,"s":[{"i":[[-247.951,-14.258],[-458.271,96.09]],"o":[[469.414,26.993],[232.133,-48.674]],"v":[[-487.636,3.94],[983.453,-89.091]],"c":false}],"e":[{"i":[[-248.361,0],[-247.665,0]],"o":[[308.273,0],[237.183,0]],"v":[[-487.636,3.94],[983.453,7.879]],"c":false}]},{"t":22}]},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[1,1,1,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":97},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":23,"st":0,"bm":0,"sr":1}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/A Shapes_All_01_1920x1080.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/A Shapes_All_01_1920x1080.json deleted file mode 100644 index 5691c1ff..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/A Shapes_All_01_1920x1080.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.18","fr":30,"ip":0,"op":36,"w":1920,"h":1080,"nm":"A Shapes_All_01","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[1924.5,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[483.75,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[964,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[1444.25,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[3.5,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"ellipse Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,77.324],[77.324,0],[0,-77.324],[-77.324,0]],"o":[[0,-77.324],[-77.324,0],[0,77.324],[77.324,0]],"v":[[140.007,0],[0,-140.007],[-140.007,0],[0,140.007]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_3","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_4","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rounded Rectangle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.6,0],[0,0],[0,-6.6],[0,0],[-6.6,0],[0,0],[0,6.6],[0,0]],"o":[[0,0],[-6.6,0],[0,0],[0,6.6],[0,0],[6.6,0],[0,0],[0,-6.6]],"v":[[128.333,-140.333],[-128.333,-140.333],[-140.333,-128.333],[-140.333,128.333],[-128.333,140.333],[128.333,140.333],[140.333,128.333],[140.333,-128.333]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_5","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Polystar Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-75.095,130],[-150.191,0],[-75.095,-130],[75.095,-130],[150.192,0],[75.095,130]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_6","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"merge Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[338.188,258.876,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[143.993,-143.993],[-143.993,-143.993],[-143.993,143.993],[143.993,143.993]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[942.053,592.591],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,103.879],[103.879,0],[0,-103.879],[-103.88,0]],"o":[[0,-103.879],[-103.88,0],[0,103.879],[103.879,0]],"v":[[188.091,0],[0,-188.09],[-188.09,0],[0,188.09]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1081.098,472],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_7","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"merge Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[338.188,258.876,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[143.993,-143.993],[-143.993,-143.993],[-143.993,143.993],[143.993,143.993]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[942.053,592.591],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,103.879],[103.879,0],[0,-103.879],[-103.88,0]],"o":[[0,-103.879],[-103.88,0],[0,103.879],[103.879,0]],"v":[[188.091,0],[0,-188.09],[-188.09,0],[0,188.09]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[1081.098,472],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":0,"s":[100],"e":[0]},{"t":30}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":40,"s":[100],"e":[0]},{"t":70}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":2,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_8","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"merge Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[338.188,258.876,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[143.993,-143.993],[-143.993,-143.993],[-143.993,143.993],[143.993,143.993]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[942.053,592.591],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,103.879],[103.879,0],[0,-103.879],[-103.88,0]],"o":[[0,-103.879],[-103.88,0],[0,103.879],[103.879,0]],"v":[[188.091,0],[0,-188.09],[-188.09,0],[0,188.09]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[1081.098,472],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":0,"s":[100],"e":[0]},{"t":30}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":40,"s":[100],"e":[0]},{"t":70}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]}],"fonts":{"list":[{"fName":"SamsungOne-500","fFamily":"SamsungOne","fStyle":"500","ascent":70.9991455078125}]},"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"div","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":10,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":5,"nm":"A Shapes_01 Shape","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[39.375,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"A Shapes_01 Shape","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":5,"nm":"A Shapes_02 Ellipse","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[519.5,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"A Shapes_02 Ellipse","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":5,"nm":"A Shapes_03 Rectangle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1000.375,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"A Shapes_03 Rectangle","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":5,"nm":"A Shapes_04 Rounded Rectangle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1480.5,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"A Shapes_04 Rounded Rectangle","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":5,"nm":"A Shapes_05 Polystar","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[39.375,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"A Shapes_05 Polystar","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":5,"nm":"A Shapes_06 Group","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[519.5,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"A Shapes_06 Group","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":5,"nm":"A Shapes_07 Trim Path (individually)","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1000.375,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"A Shapes_07 Trim Path (individually)","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":5,"nm":"A Shapes_08 Trim Path (simultaneously)","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1480.5,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"A Shapes_08 Trim Path \r(simultaneously)","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"A Shapes_01 Shape","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[248,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":0,"nm":"A Shapes_02 Ellipse","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[726,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":0,"nm":"A Shapes_03 Rectangle","refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1204,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":0,"nm":"A Shapes_04 Rounded Rectangle","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1678,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":0,"nm":"A Shapes_05 Polystar","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[248,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":0,"nm":"A Shapes_06 Group","refId":"comp_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[732,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":0,"nm":"A Shapes_07 Trim Path (individually)","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1198,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":0,"nm":"A Shapes_08 Trim Path (simultaneously)","refId":"comp_8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1678,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":37,"st":0,"bm":0}],"markers":[],"chars":[{"ch":"A","size":150,"style":"500","w":61.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[42.7,-21.35],[49.951,0],[59.317,0],[36.154,-67.877],[25.58,-67.877],[2.518,0],[11.581,0],[18.631,-21.35]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-1.007,4.028],[0,0],[-1.511,-4.431],[0,0]],"o":[[0,0],[1.309,-4.129],[0,0],[1.007,3.928],[0,0],[0,0]],"v":[[20.444,-28.198],[27.09,-47.836],[30.515,-60.123],[30.716,-60.123],[34.241,-47.736],[40.887,-28.198]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"A","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":" ","size":150,"style":"500","w":21.2,"data":{},"fFamily":"SamsungOne"},{"ch":"S","size":150,"style":"500","w":49.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.546,0],[0,10.474],[11.481,4.431],[0,6.345],[-9.265,0],[-2.216,-1.208],[0,0],[6.949,0],[0,-10.574],[-11.078,-3.928],[0,-6.345],[8.963,0],[3.928,2.417]],"o":[[3.625,2.417],[16.013,0],[0,-9.97],[-9.366,-3.625],[0,-4.633],[6.143,0],[0,0],[-3.021,-1.712],[-13.193,0],[0,9.567],[9.164,3.525],[0,6.848],[-6.042,0],[0,0]],"v":[[4.23,-3.323],[21.552,1.007],[45.319,-18.53],[27.997,-38.47],[14.502,-51.562],[27.292,-61.734],[40.182,-58.511],[42.599,-65.662],[27.594,-68.985],[5.64,-50.555],[23.566,-31.32],[36.356,-17.825],[22.156,-6.244],[6.445,-10.675]],"c":true},"ix":2},"nm":"S","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"S","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"h","size":150,"style":"500","w":55.5,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.504,1.208],[-5.74,0],[0,-7.855],[0,0],[0,0],[0,0],[6.546,0],[2.618,-1.511],[1.41,-2.518],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,-1.712],[1.611,-4.834],[8.359,0],[0,0],[0,0],[0,0],[0,-16.818],[-3.323,0],[-2.719,1.511],[0,0],[0,0],[0,0],[0,0]],"v":[[7.352,0],[16.214,0],[16.214,-29.407],[16.818,-33.636],[28.702,-42.499],[39.981,-27.997],[39.981,0],[48.843,0],[48.843,-29.004],[31.824,-49.85],[22.76,-47.333],[16.415,-41.089],[16.214,-41.089],[16.214,-71.503],[7.352,-71.503]],"c":true},"ix":2},"nm":"h","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"h","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"a","size":150,"style":"500","w":48.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,4.23],[0,0],[14.905,0],[4.028,-2.618],[0,0],[-4.532,0],[0,-4.028],[0,0],[0,-11.783],[-9.869,0],[-2.719,3.827],[0,0],[0,0]],"o":[[-0.604,-3.323],[0,0],[0,-9.769],[-6.143,0],[0,0],[3.424,-2.216],[9.97,0],[0,0],[-18.832,-0.101],[0,7.05],[6.949,0],[0,0],[0,0],[0,0]],"v":[[42.398,0],[41.592,-11.682],[41.592,-29.91],[23.062,-49.85],[7.05,-45.52],[9.064,-39.679],[21.753,-43.304],[32.831,-32.025],[32.831,-31.018],[3.525,-12.891],[18.43,1.108],[33.334,-6.143],[33.636,-6.143],[34.341,0]],"c":true},"ix":2},"nm":"a","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.302,-0.906],[6.345,0],[0,5.74],[-9.668,-0.201]],"o":[[0,0.906],[-1.41,4.129],[-4.532,0],[0,-9.467],[0,0]],"v":[[33.032,-16.415],[32.529,-13.596],[20.746,-5.438],[12.387,-13.898],[33.032,-24.875]],"c":true},"ix":2},"nm":"a","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"a","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"p","size":150,"style":"500","w":56.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-6.445,0],[0,17.523],[11.783,0],[3.625,-5.942],[0,0],[0,0],[0,0],[0,-6.244]],"o":[[0,0],[0,0],[0,0],[2.921,4.834],[11.481,0],[0,-14.804],[-7.956,0],[0,0],[0,0],[0,0],[0.201,4.633],[0,0]],"v":[[7.352,19.94],[16.113,19.94],[16.113,-6.546],[16.315,-6.546],[31.32,1.108],[53.476,-25.076],[32.831,-49.85],[15.509,-40.384],[15.308,-40.384],[14.905,-48.743],[6.949,-48.743],[7.352,-32.831]],"c":true},"ix":2},"nm":"p","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-0.302,1.108],[-6.042,0],[0,-9.769],[9.366,0],[1.611,6.143],[0,1.309]],"o":[[0,-1.208],[1.712,-6.647],[9.366,0],[0,11.179],[-6.345,0],[-0.201,-1.108],[0,0]],"v":[[16.113,-28.198],[16.718,-31.824],[30.112,-42.801],[44.614,-24.673],[29.81,-5.841],[16.516,-16.214],[16.113,-19.839]],"c":true},"ix":2},"nm":"p","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"p","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"e","size":150,"style":"500","w":50.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,1.813],[15.912,0],[0,-14.703],[-15.005,0],[-3.122,1.41],[0,0],[6.345,0],[0.201,11.984]],"o":[[0.101,-0.906],[0,-8.963],[-14.2,0],[0,14.703],[7.755,0],[0,0],[-3.323,1.41],[-8.862,0],[0,0]],"v":[[46.527,-22.76],[46.829,-26.889],[26.688,-49.85],[3.827,-23.566],[27.795,1.007],[44.009,-2.014],[42.499,-8.359],[29.004,-5.841],[12.286,-22.76]],"c":true},"ix":2},"nm":"e","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-8.963,0],[0.101,-5.64]],"o":[[0.705,-6.143],[9.97,0],[0,0]],"v":[[12.387,-29.105],[25.983,-43.506],[38.269,-29.105]],"c":true},"ix":2},"nm":"e","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"e","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"s","size":150,"style":"500","w":39.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-5.338,0],[0,8.56],[8.459,3.223],[0,4.028],[-5.237,0],[-1.913,-1.208],[0,0],[4.935,0],[0,-7.855],[-8.762,-3.122],[0,-4.23],[6.445,0],[2.618,1.712]],"o":[[3.424,2.014],[11.581,0],[0,-7.251],[-6.345,-2.417],[0,-3.625],[4.532,0],[0,0],[-2.719,-1.611],[-10.474,0],[0,5.841],[6.546,2.417],[0,4.028],[-4.431,0],[0,0]],"v":[[3.928,-2.316],[17.624,1.007],[35.852,-13.596],[23.062,-28.299],[13.797,-36.557],[21.954,-43.204],[31.924,-40.384],[34.14,-46.829],[22.156,-49.85],[5.338,-35.55],[18.228,-21.753],[27.292,-12.79],[17.825,-5.539],[6.143,-9.064]],"c":true},"ix":2},"nm":"s","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"s","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"_","size":150,"style":"500","w":50,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,7.553],[0,12.589],[50.354,12.589],[50.354,7.553]],"c":true},"ix":2},"nm":"_","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"_","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"0","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.797,0],[0,-21.954],[-12.79,0],[0,22.256]],"o":[[-13.293,0],[0.201,21.652],[14.502,0],[0,-20.847]],"v":[[26.385,-66.568],[3.625,-32.529],[25.278,1.108],[48.038,-33.435]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-7.755,0],[0,-16.113],[9.064,0],[0,17.02]],"o":[[9.164,0],[0,16.718],[-8.057,0],[0,-17.825]],"v":[[25.882,-59.72],[39.175,-33.032],[25.781,-5.74],[12.488,-32.428]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"0","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"8","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-13.696,0],[0,11.38],[8.157,3.223],[0,0],[0,5.539],[12.689,0],[0,-10.373],[-7.251,-3.424],[0,0],[0,-8.258]],"o":[[12.488,0],[0,-7.956],[0,0],[8.057,-3.827],[0,-8.157],[-11.481,0],[0,5.64],[0,0],[-8.057,3.424],[0,9.567]],"v":[[25.681,1.108],[47.937,-17.926],[34.744,-34.845],[34.744,-35.147],[45.52,-50.455],[26.486,-66.568],[6.244,-49.146],[16.617,-34.442],[16.718,-34.14],[3.726,-16.617]],"c":true},"ix":2},"nm":"8","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[7.956,0],[-0.302,6.647],[-7.654,2.216],[0,-7.956]],"o":[[-8.359,0],[0,-6.244],[8.862,2.518],[0,6.747]],"v":[[25.882,-5.338],[12.79,-17.825],[24.573,-31.32],[38.974,-17.02]],"c":true},"ix":2},"nm":"8","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-7.352,0],[0,-5.237],[5.64,-1.913],[0,6.546]],"o":[[7.956,0],[0,5.942],[-7.553,-2.014],[0,-5.64]],"v":[[25.983,-60.223],[37.061,-49.548],[27.09,-37.665],[14.603,-49.75]],"c":true},"ix":2},"nm":"8","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"8","np":6,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"T","size":150,"style":"500","w":53.5,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[20.544,0],[29.407,0],[29.407,-60.425],[50.153,-60.425],[50.153,-67.877],[-0.101,-67.877],[-0.101,-60.425],[20.544,-60.425]],"c":true},"ix":2},"nm":"T","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"T","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"r","size":150,"style":"500","w":33.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.201,1.208],[-6.244,0],[-0.906,-0.201],[0,0],[1.007,0],[2.216,-6.546],[0,0],[0,0],[0,0],[0,-5.74]],"o":[[0,0],[0,0],[0,-1.511],[1.208,-6.647],[1.208,0],[0,0],[-0.806,-0.201],[-5.942,0],[0,0],[0,0],[0,0],[0.302,4.532],[0,0]],"v":[[7.352,0],[16.113,0],[16.113,-25.983],[16.516,-30.112],[28.4,-41.492],[31.421,-41.19],[31.421,-49.548],[28.903,-49.85],[15.408,-39.175],[15.005,-39.175],[14.703,-48.743],[6.949,-48.743],[7.352,-33.536]],"c":true},"ix":2},"nm":"r","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"r","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"i","size":150,"style":"500","w":23.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16.214,0],[16.214,-48.743],[7.352,-48.743],[7.352,0]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[3.323,0],[0,-3.122],[-3.122,0],[0.101,3.021]],"o":[[-3.223,0],[0,3.021],[3.525,0],[0,-3.122]],"v":[[11.783,-67.978],[6.244,-62.439],[11.581,-57.001],[17.221,-62.439]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"i","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"m","size":150,"style":"500","w":83.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.504,1.309],[-5.539,0],[0,-7.755],[0,0],[0,0],[0,0],[-0.403,1.208],[-5.035,0],[0,-9.366],[0,0],[0,0],[0,0],[6.445,0],[2.921,-2.216],[1.511,-2.719],[0,0],[6.647,0],[2.719,-4.633],[0,0],[0,0],[0,0],[0,-5.035]],"o":[[0,0],[0,0],[0,-1.511],[1.41,-4.431],[6.747,0],[0,0],[0,0],[0,0],[0,-1.611],[1.511,-4.33],[7.15,0],[0,0],[0,0],[0,0],[0,-16.919],[-4.633,0],[-2.014,1.511],[0,0],[-2.115,-5.74],[-8.057,0],[0,0],[0,0],[0,0],[0.302,4.028],[0,0]],"v":[[7.352,0],[16.013,0],[16.013,-29.407],[16.718,-33.737],[27.695,-42.599],[37.866,-29.205],[37.866,0],[46.527,0],[46.527,-30.112],[47.232,-34.543],[57.706,-42.599],[68.28,-27.594],[68.28,0],[76.941,0],[76.941,-28.702],[60.928,-49.85],[50.153,-46.426],[44.714,-40.082],[44.513,-40.082],[30.716,-49.85],[15.408,-40.887],[15.106,-40.887],[14.703,-48.743],[6.949,-48.743],[7.352,-35.55]],"c":true},"ix":2},"nm":"m","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"m","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"P","size":150,"style":"500","w":53.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-2.618,0],[-4.633,4.935],[0,6.143],[3.726,3.223],[8.661,0],[4.23,-0.705]],"o":[[0,0],[0,0],[2.014,0.504],[8.56,0],[3.424,-3.525],[0,-6.042],[-4.028,-3.625],[-7.05,0],[0,0]],"v":[[7.654,0],[16.415,0],[16.415,-27.191],[23.465,-26.587],[44.211,-34.039],[49.448,-48.541],[43.506,-62.741],[24.472,-68.381],[7.654,-67.072]],"c":true},"ix":2},"nm":"P","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-3.827,0],[0,-8.963],[10.574,0],[1.913,0.504]],"o":[[1.511,-0.403],[9.668,0],[0,9.366],[-2.921,0],[0,0]],"v":[[16.415,-60.727],[24.673,-61.432],[40.686,-48.138],[23.666,-33.636],[16.415,-34.341]],"c":true},"ix":2},"nm":"P","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"P","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"t","size":150,"style":"500","w":33.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-2.518,-2.618],[-4.129,0],[-1.712,0.705],[0,0],[2.316,0],[0,6.042],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,5.74],[2.115,2.417],[3.424,0],[0,0],[-1.108,0.302],[-4.935,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[9.366,-60.425],[9.366,-48.743],[1.813,-48.743],[1.813,-41.995],[9.366,-41.995],[9.366,-15.408],[12.79,-2.719],[22.357,1.007],[30.212,-0.201],[29.81,-6.848],[24.673,-6.244],[18.027,-15.71],[18.027,-41.995],[30.716,-41.995],[30.716,-48.743],[18.027,-48.743],[18.027,-62.741]],"c":true},"ix":2},"nm":"t","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"t","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"\r","size":150,"style":"500","w":0,"fFamily":"SamsungOne"},{"ch":"(","size":150,"style":"500","w":28.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.101,-19.839],[-6.345,-8.359],[0,0],[0,17.926],[-7.352,9.869]],"o":[[-6.345,8.459],[0,19.638],[0,0],[-7.15,-10.071],[0,-18.228],[0,0]],"v":[[19.638,-69.891],[6.445,-28.702],[19.638,12.186],[26.587,12.186],[13.898,-28.702],[26.587,-69.891]],"c":true},"ix":2},"nm":"(","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"(","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"u","size":150,"style":"500","w":55.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0.504,-1.309],[5.942,0],[0,9.265],[0,0],[0,0],[0,0],[-7.654,0],[-2.316,3.928],[0,0],[0,0],[0,0],[0,5.035]],"o":[[0,0],[0,0],[0,1.611],[-1.611,3.928],[-8.057,0],[0,0],[0,0],[0,0],[0,17.12],[8.661,0],[0,0],[0,0],[0,0],[-0.302,-3.827],[0,0]],"v":[[48.138,-48.743],[39.276,-48.743],[39.276,-18.832],[38.47,-14.301],[26.788,-6.244],[15.912,-21.753],[15.912,-48.743],[7.05,-48.743],[7.05,-20.242],[23.868,1.108],[39.981,-7.956],[40.182,-7.956],[40.686,0],[48.541,0],[48.138,-13.293]],"c":true},"ix":2},"nm":"u","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"u","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"l","size":150,"style":"500","w":23.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[7.352,0],[16.214,0],[16.214,-71.503],[7.352,-71.503]],"c":true},"ix":2},"nm":"l","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"l","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"n","size":150,"style":"500","w":55.5,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.403,1.108],[-5.841,0],[0,-7.855],[0,0],[0,0],[0,0],[6.747,0],[2.417,-4.633],[0,0],[0,0],[0,0],[0,-5.035]],"o":[[0,0],[0,0],[0,-1.511],[1.511,-4.935],[8.359,0],[0,0],[0,0],[0,0],[0,-16.718],[-8.057,0],[0,0],[0,0],[0,0],[0.302,4.028],[0,0]],"v":[[7.352,0],[16.214,0],[16.214,-29.306],[16.818,-33.435],[28.702,-42.499],[39.981,-28.098],[39.981,0],[48.843,0],[48.843,-29.105],[31.622,-49.85],[15.509,-40.686],[15.308,-40.686],[14.804,-48.743],[6.949,-48.743],[7.352,-35.55]],"c":true},"ix":2},"nm":"n","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"n","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"o","size":150,"style":"500","w":54.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.998,0],[0,-16.315],[-13.193,0],[0,18.027]],"o":[[-13.495,0],[0,15.408],[11.783,0],[0,-14.905]],"v":[[27.997,-49.85],[3.827,-23.969],[27.191,1.108],[51.462,-24.774]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-10.474,0],[0,-8.258],[8.459,0],[0,10.675]],"o":[[10.474,0],[0,10.977],[-8.661,0],[0,-9.265]],"v":[[27.795,-43.204],[42.398,-24.472],[27.594,-5.539],[12.79,-24.271]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"o","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"y","size":150,"style":"500","w":48.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,-0.504],[0.403,-0.906],[2.417,-1.913],[2.216,-0.705],[0,0],[-4.33,3.827],[-6.345,16.718],[0,0],[0,0],[0,0],[0.906,-2.921],[0,0],[1.108,3.223],[0,0]],"o":[[0,0],[0.403,1.108],[0,0.504],[-2.014,4.532],[-2.618,2.216],[0,0],[2.216,-0.403],[6.042,-5.237],[0,0],[0,0],[0,0],[-1.208,3.525],[0,0],[-0.806,-2.921],[0,0],[0,0]],"v":[[0.906,-48.743],[18.933,-3.827],[19.537,-1.511],[18.832,0.604],[11.38,10.474],[3.625,14.804],[5.841,22.256],[16.718,16.516],[33.435,-13.998],[46.729,-48.743],[37.363,-48.743],[27.695,-20.142],[24.573,-9.97],[24.371,-9.97],[21.249,-19.94],[10.574,-48.743]],"c":true},"ix":2},"nm":"y","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"y","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":")","size":150,"style":"500","w":28.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,19.739],[6.445,8.258],[0,0],[0,-18.027],[7.15,-9.97]],"o":[[6.445,-8.56],[0,-19.839],[0,0],[7.251,9.97],[0,18.127],[0,0]],"v":[[8.862,12.186],[22.055,-28.903],[8.862,-69.891],[2.014,-69.891],[14.703,-29.004],[2.014,12.186]],"c":true},"ix":2},"nm":")","mn":"ADBE Vector Shape - Group","hd":false}],"nm":")","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"7","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[5.74,-65.46],[5.74,-58.109],[37.766,-58.109],[37.766,-57.907],[9.366,0],[18.53,0],[47.031,-59.619],[47.031,-65.46]],"c":true},"ix":2},"nm":"7","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"7","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"d","size":150,"style":"500","w":56.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[7.452,0],[-0.101,-16.214],[-11.783,0],[-2.719,5.438],[0,0],[0,0],[0,0],[0,4.33],[0,0]],"o":[[0,0],[0,0],[-2.216,-3.928],[-11.884,0],[0,14.804],[7.956,0],[0,0],[0,0],[0,0],[-0.302,-3.323],[0,0],[0,0]],"v":[[40.585,-71.503],[40.585,-42.398],[40.384,-42.398],[25.681,-49.85],[3.827,-23.666],[24.673,1.108],[41.29,-8.459],[41.492,-8.459],[41.895,0],[49.85,0],[49.448,-12.589],[49.448,-71.503]],"c":true},"ix":2},"nm":"d","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.302,-1.208],[5.942,0],[0,9.869],[-9.164,0],[-1.309,-5.64],[0,-1.108]],"o":[[0,1.41],[-1.611,6.647],[-9.567,0],[0,-10.776],[6.647,0],[0.302,1.108],[0,0]],"v":[[40.585,-20.444],[40.182,-16.617],[27.191,-6.042],[12.79,-24.069],[27.393,-42.902],[40.182,-32.629],[40.585,-28.903]],"c":true},"ix":2},"nm":"d","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"d","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"v","size":150,"style":"500","w":49.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.108,-4.028],[0,0],[1.611,4.431],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[-1.611,4.431],[0,0],[-1.007,-4.028],[0,0],[0,0]],"v":[[1.309,-48.743],[19.839,0],[28.299,0],[47.433,-48.743],[38.168,-48.743],[28.702,-21.35],[24.573,-8.862],[24.271,-8.862],[20.343,-21.35],[10.776,-48.743]],"c":true},"ix":2},"nm":"v","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"v","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"6","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[2.618,-0.403],[5.438,-5.338],[0,-12.891],[-13.998,0],[0,11.984],[11.581,0],[3.122,-4.129],[0,0],[-13.898,2.316],[-1.813,-0.101]],"o":[[-1.611,0],[-8.258,1.007],[-6.445,6.445],[0,17.02],[13.596,0],[0,-12.79],[-7.251,0],[0,0],[1.511,-10.776],[2.518,-0.403],[0,0]],"v":[[41.895,-66.467],[35.449,-65.964],[14.502,-56.296],[3.424,-26.788],[26.587,1.108],[48.34,-21.954],[28.601,-43.103],[12.79,-35.55],[12.488,-35.55],[35.248,-58.813],[41.895,-59.216]],"c":true},"ix":2},"nm":"6","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[7.654,0],[0.201,10.776],[-0.604,1.007],[-5.338,0],[0,-9.366]],"o":[[-9.265,0],[0,-1.611],[2.417,-4.733],[8.157,0],[0,9.366]],"v":[[26.587,-5.74],[12.186,-24.472],[13.193,-28.4],[25.882,-36.456],[39.377,-21.451]],"c":true},"ix":2},"nm":"6","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"6","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"G","size":150,"style":"500","w":64.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[5.74,0],[0,17.221],[-16.516,0],[-3.625,-1.611],[0,0],[7.855,0],[0.101,-20.242],[-5.841,-5.64],[-10.272,0],[-3.928,1.41]],"o":[[0,0],[0,0],[0,0],[0,0],[-2.014,1.007],[-15.811,0],[0,-17.02],[6.848,0],[0,0],[-2.921,-1.41],[-22.76,0],[0,10.574],[6.647,6.345],[9.164,0],[0,0]],"v":[[59.317,-35.651],[36.96,-35.651],[36.96,-28.601],[50.757,-28.601],[50.757,-8.359],[39.075,-6.546],[12.891,-33.939],[40.182,-61.23],[55.188,-58.31],[57.303,-65.46],[40.384,-68.582],[3.625,-33.536],[13.092,-8.258],[38.47,0.705],[59.317,-3.021]],"c":true},"ix":2},"nm":"G","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"G","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"5","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-3.726,0],[-0.101,-8.459],[8.359,0],[2.719,1.611],[0,0],[-7.15,0],[0,12.79],[5.136,2.921],[5.035,0],[1.511,-0.201],[0,0],[0,0]],"o":[[0,0],[0,0],[2.417,-0.302],[13.092,0],[0,8.762],[-5.942,0],[0,0],[3.122,2.014],[14.2,0],[0,-8.258],[-4.028,-2.417],[-2.417,0],[0,0],[0,0],[0,0]],"v":[[43.607,-65.46],[12.286,-65.46],[8.057,-34.039],[17.12,-34.744],[35.953,-20.242],[20.444,-6.042],[6.445,-9.668],[4.23,-2.921],[20.544,1.108],[44.916,-21.249],[35.55,-38.068],[21.451,-41.592],[16.113,-41.19],[18.631,-58.008],[43.607,-58.008]],"c":true},"ix":2},"nm":"5","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"5","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"4","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[40.283,0],[40.283,-17.825],[49.448,-17.825],[49.448,-24.774],[40.283,-24.774],[40.283,-65.46],[30.716,-65.46],[1.511,-23.666],[1.511,-17.825],[31.924,-17.825],[31.924,0]],"c":true},"ix":2},"nm":"4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-2.014,3.827],[0,0],[0,-3.424],[0,0]],"o":[[0,0],[0,0],[1.813,-3.021],[0,0],[-0.201,3.424],[0,0],[0,0]],"v":[[10.474,-24.774],[10.474,-24.976],[26.486,-47.232],[31.924,-56.9],[32.227,-56.9],[31.924,-46.628],[31.924,-24.774]],"c":true},"ix":2},"nm":"4","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"4","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"R","size":150,"style":"500","w":53.8,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-2.014,-9.366],[-1.108,-1.913],[0,0],[2.216,9.467],[5.237,1.813],[0,0],[0,8.963],[3.424,3.021],[9.366,0],[4.431,-0.906]],"o":[[0,0],[0,0],[0,0],[7.956,0.302],[1.913,8.459],[0,0],[-1.41,-2.618],[-1.611,-7.05],[0,0],[7.15,-2.417],[0,-5.237],[-4.23,-3.827],[-6.042,0],[0,0]],"v":[[7.654,0],[16.415,0],[16.415,-29.407],[24.673,-29.407],[38.269,-16.214],[42.801,0],[51.865,0],[46.628,-18.631],[36.658,-32.327],[36.658,-32.629],[49.448,-49.951],[44.11,-62.842],[24.472,-68.381],[7.654,-66.971]],"c":true},"ix":2},"nm":"R","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-4.23,0],[0,-8.762],[9.366,0],[0,0]],"o":[[1.41,-0.403],[9.265,0.101],[0,7.755],[0,0],[0,0]],"v":[[16.415,-60.828],[25.076,-61.633],[40.686,-48.944],[25.378,-36.053],[16.415,-36.053]],"c":true},"ix":2},"nm":"R","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"R","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"c","size":150,"style":"500","w":44.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[5.035,0],[0,11.279],[-11.179,0],[-2.115,-1.208],[0,0],[5.237,0],[0,-15.005],[-14.703,0],[-2.316,1.208]],"o":[[-2.518,1.108],[-9.668,0],[0,-10.172],[4.834,0],[0,0],[-2.417,-1.208],[-15.912,0],[0,14.905],[6.546,0],[0,0]],"v":[[40.585,-8.459],[29.709,-6.042],[12.79,-24.271],[30.011,-42.7],[40.283,-40.384],[42.297,-47.232],[30.011,-49.75],[3.827,-23.868],[28.098,1.007],[42.096,-1.813]],"c":true},"ix":2},"nm":"c","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"c","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"g","size":150,"style":"500","w":55.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[8.459,0],[0,-16.516],[-12.085,0],[-2.719,4.532],[0,0],[0,0],[9.064,0],[3.223,2.014],[0,0],[-5.841,0],[-4.733,4.431],[0,11.179],[0,0],[-0.201,3.525]],"o":[[0,0],[0,0],[-2.115,-4.028],[-11.179,0],[0,13.495],[7.553,0],[0,0],[0,0],[0,12.286],[-6.042,0],[0,0],[3.928,2.618],[6.143,0],[4.733,-4.23],[0,0],[0,-5.942],[0,0]],"v":[[41.592,-48.743],[41.19,-41.391],[40.988,-41.391],[25.781,-49.85],[3.827,-23.969],[24.573,-0.201],[40.082,-8.359],[40.283,-8.359],[40.283,-2.921],[24.573,14.099],[10.272,10.272],[8.057,17.02],[24.271,21.048],[41.995,15.207],[48.944,-7.05],[48.944,-35.349],[49.347,-48.743]],"c":true},"ix":2},"nm":"g","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.504,-1.511],[5.438,0],[0,9.567],[-8.459,0],[-1.611,-5.136],[0,-1.511]],"o":[[0,1.511],[-1.913,5.64],[-9.567,0],[0,-11.279],[6.445,0],[0.403,1.208],[0,0]],"v":[[40.182,-20.746],[39.478,-16.013],[27.191,-6.949],[12.79,-24.472],[27.292,-42.902],[39.679,-33.536],[40.182,-29.507]],"c":true},"ix":2},"nm":"g","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"g","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"3","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-7.352,0],[0,10.474],[8.057,1.611],[0,0],[0,6.747],[12.891,0],[3.424,-2.518],[0,0],[-5.237,0],[0,-5.237],[6.445,0],[0,0],[0,0],[0,0],[-0.101,-9.164],[11.38,0],[2.518,1.611]],"o":[[3.223,2.115],[15.71,0],[0,-9.164],[0,0],[8.057,-2.921],[0,-7.956],[-7.05,0],[0,0],[2.82,-2.014],[8.157,0],[0,7.755],[0,0],[0,0],[0,0],[8.56,0],[0.101,5.438],[-6.143,0],[0,0]],"v":[[4.23,-3.323],[21.249,1.108],[45.117,-18.53],[30.515,-35.349],[30.515,-35.55],[42.599,-50.958],[23.868,-66.568],[6.747,-61.533],[9.064,-55.087],[22.156,-59.418],[33.636,-49.548],[19.034,-38.47],[14.099,-38.47],[14.099,-31.824],[19.034,-31.824],[35.953,-18.732],[21.149,-6.042],[6.647,-10.172]],"c":true},"ix":2},"nm":"3","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"3","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"2","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,12.085],[14.099,0],[4.532,-3.827],[0,0],[-5.942,0],[0,-6.647],[16.718,-15.912],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[13.797,-13.293],[0,-9.366],[-7.553,0],[0,0],[3.021,-2.518],[9.769,0],[-0.101,9.869],[0,0],[0,0],[0,0]],"v":[[46.326,0],[46.326,-7.352],[16.919,-7.352],[16.919,-7.553],[22.156,-12.387],[44.714,-47.534],[24.673,-66.568],[6.143,-59.921],[8.963,-53.677],[22.861,-59.216],[35.852,-46.426],[11.481,-12.186],[4.532,-5.438],[4.532,0]],"c":true},"ix":2},"nm":"2","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"E","size":150,"style":"500","w":49.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[42.801,-39.075],[16.415,-39.075],[16.415,-60.526],[44.312,-60.526],[44.312,-67.877],[7.654,-67.877],[7.654,0],[45.822,0],[45.822,-7.352],[16.415,-7.352],[16.415,-31.824],[42.801,-31.824]],"c":true},"ix":2},"nm":"E","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"E","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"1","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[23.767,0],[32.327,0],[32.327,-65.46],[24.774,-65.46],[10.474,-57.806],[12.186,-51.059],[23.566,-57.202],[23.767,-57.202]],"c":true},"ix":2},"nm":"1","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/B Fills_All_01_1920x1080.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/B Fills_All_01_1920x1080.json deleted file mode 100644 index 1e6d4b1b..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/B Fills_All_01_1920x1080.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.18","fr":30,"ip":0,"op":114,"w":1920,"h":1080,"nm":"B Fills_All_01","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[1924.5,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[643.833,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[1284.167,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[3.5,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0.901960790157,0.712618291378,0.054901961237,1],"e":[0.054901961237,0.631372570992,0.901960790157,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.054901961237,0.631372570992,0.901960790157,1],"e":[0.901960790157,0.713725507259,0.054901961237,1]},{"t":30}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0],"e":[100]},{"t":30}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_3","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Fill rlue Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[391.686,274.164,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[11.387,51.452],[-75.913,0],[20.243,-42.174],[-1.265,20.244],[-66.213,-5.061],[-0.421,-16.448],[57.356,-14.761],[-5.905,26.992],[-28.256,-32.474],[27.835,-38.378],[38.378,33.317],[-33.739,0],[49.344,-58.201],[0.844,65.37],[-10.122,3.374],[-3.795,-24.461],[29.522,0.843],[5.483,60.309],[-19.821,0],[-25.726,-13.496],[7.169,-10.965]],"o":[[0,0],[-11.387,-51.452],[75.913,0],[-20.244,42.174],[1.265,-20.243],[66.213,5.061],[0.422,16.448],[-57.357,14.761],[5.904,-26.991],[28.257,32.474],[-27.835,38.379],[-38.379,-33.318],[33.739,0],[-49.343,58.2],[-0.843,-65.369],[10.122,-3.374],[3.796,24.461],[-29.522,-0.843],[-5.483,-60.309],[19.822,0],[25.726,13.495],[-7.17,10.965]],"v":[[-27.834,-41.963],[-73.383,-69.798],[5.904,-198.429],[77.601,-61.363],[21.088,-63.472],[115.979,-114.502],[190.204,-37.324],[121.883,44.915],[50.188,17.502],[117.244,19.189],[135.8,135.589],[10.123,139.807],[0.844,48.289],[-0.422,140.229],[-140.018,98.476],[-80.13,-6.537],[-46.391,13.285],[-83.083,50.398],[-185.143,-36.902],[-121.039,-115.768],[-40.909,-101.428],[-16.026,-54.615]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":2,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[924.302,493.932],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_4","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,313.5,0],"ix":2},"a":{"a":0,"k":[962,643,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":88,"s":[100],"e":[0]},{"t":108}],"ix":10},"r":1,"g":{"p":3,"k":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[0,0.055,0.631,0.902,0.592,0.478,0.673,0.478,1,0.902,0.714,0.055],"e":[0,0.902,0.055,0.173,0.592,0.902,0.384,0.114,1,0.902,0.714,0.055]},{"t":67}],"ix":9}},"s":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[0,0],"e":[0,426],"to":[0,71],"ti":[0,-71]},{"t":20}],"ix":5},"e":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[1,0],"e":[2,-140],"to":[0.16666667163372,-23.3333339691162],"ti":[-0.16666667163372,23.3333339691162]},{"t":40}],"ix":6},"t":2,"h":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":68,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":78,"s":[0],"e":[100]},{"t":88}],"ix":7},"a":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":42,"s":[0],"e":[360]},{"t":67}],"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_5","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":40,"s":[100],"e":[0]},{"t":60}],"ix":10},"r":1,"g":{"p":3,"k":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[0,0.055,0.631,0.902,0.592,0.478,0.673,0.478,1,0.902,0.714,0.055,0,0.6,0.5,0.8,1,1],"e":[0,0.902,0.055,0.173,0.592,0.902,0.384,0.114,1,0.902,0.714,0.055,0,0.6,0.5,0.8,1,1]},{"t":40}],"ix":9}},"s":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[-235,0],"e":[0,0],"to":[39.1666679382324,0],"ti":[-39.1666679382324,0]},{"t":20}],"ix":5},"e":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[0,140],"e":[0,13],"to":[0,-21.1666660308838],"ti":[0,21.1666660308838]},{"t":40}],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]}],"fonts":{"list":[{"fName":"SamsungOne-500","fFamily":"SamsungOne","fStyle":"500","ascent":70.9991455078125}]},"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"div","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":10,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":5,"nm":"B Fills_01 Color","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[39.375,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"B Fills_01 Color","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":115,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":5,"nm":"B Fills_02 Opacity","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[679.25,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"B Fills_02 Opacity","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":115,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":5,"nm":"B Fills_03 Fill Rule","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1320,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"B Fills_03 Fill Rule","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":115,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":5,"nm":"B Fills_04 Radial Gradient","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[39.375,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"B Fills_04 Radial Gradient","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":115,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":5,"nm":"B Fills_05 Linear Gradient","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[679.25,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"B Fills_05 Linear Gradient","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":115,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"B Fills_01 Color","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[328,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"B Fills_02 Opacity","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[965.75,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"B Fills_03 Fill Rule","refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1597.5,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"B Fills_04 Radial Gradient","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[328,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":0,"nm":"B Fills_05 Linear Gradient","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[965.75,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0}],"markers":[],"chars":[{"ch":"B","size":150,"style":"500","w":54.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.042,0],[-4.733,4.33],[0,5.841],[6.445,1.611],[0,0],[0,6.546],[3.525,2.618],[8.762,0],[3.827,-0.806]],"o":[[2.921,0.403],[11.078,0],[3.424,-3.323],[0,-10.071],[0,0],[7.15,-2.618],[0,-5.338],[-4.23,-3.424],[-6.143,0],[0,0]],"v":[[7.654,-0.201],[21.249,0.604],[44.714,-5.74],[50.455,-19.336],[36.456,-36.356],[36.456,-36.557],[47.937,-51.462],[42.297,-63.446],[23.666,-68.381],[7.654,-66.971]],"c":true},"ix":2},"nm":"B","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-4.028,0],[0,-7.956],[9.265,0],[0,0]],"o":[[1.41,-0.302],[8.862,0],[0,6.546],[0,0],[0,0]],"v":[[16.415,-61.029],[24.17,-61.633],[39.075,-50.555],[24.371,-39.175],[16.415,-39.175]],"c":true},"ix":2},"nm":"B","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,-9.265],[9.064,0],[1.712,0.302]],"o":[[0,0],[9.567,0],[0,9.869],[-3.122,0],[0,0]],"v":[[16.415,-32.529],[23.666,-32.529],[41.19,-19.437],[23.767,-6.244],[16.415,-6.647]],"c":true},"ix":2},"nm":"B","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"B","np":6,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":" ","size":150,"style":"500","w":21.2,"data":{},"fFamily":"SamsungOne"},{"ch":"F","size":150,"style":"500","w":48.7,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[7.654,0],[16.415,0],[16.415,-30.716],[42.096,-30.716],[42.096,-37.967],[16.415,-37.967],[16.415,-60.526],[44.211,-60.526],[44.211,-67.877],[7.654,-67.877]],"c":true},"ix":2},"nm":"F","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"F","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"i","size":150,"style":"500","w":23.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16.214,0],[16.214,-48.743],[7.352,-48.743],[7.352,0]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[3.323,0],[0,-3.122],[-3.122,0],[0.101,3.021]],"o":[[-3.223,0],[0,3.021],[3.525,0],[0,-3.122]],"v":[[11.783,-67.978],[6.244,-62.439],[11.581,-57.001],[17.221,-62.439]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"i","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"l","size":150,"style":"500","w":23.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[7.352,0],[16.214,0],[16.214,-71.503],[7.352,-71.503]],"c":true},"ix":2},"nm":"l","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"l","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"s","size":150,"style":"500","w":39.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-5.338,0],[0,8.56],[8.459,3.223],[0,4.028],[-5.237,0],[-1.913,-1.208],[0,0],[4.935,0],[0,-7.855],[-8.762,-3.122],[0,-4.23],[6.445,0],[2.618,1.712]],"o":[[3.424,2.014],[11.581,0],[0,-7.251],[-6.345,-2.417],[0,-3.625],[4.532,0],[0,0],[-2.719,-1.611],[-10.474,0],[0,5.841],[6.546,2.417],[0,4.028],[-4.431,0],[0,0]],"v":[[3.928,-2.316],[17.624,1.007],[35.852,-13.596],[23.062,-28.299],[13.797,-36.557],[21.954,-43.204],[31.924,-40.384],[34.14,-46.829],[22.156,-49.85],[5.338,-35.55],[18.228,-21.753],[27.292,-12.79],[17.825,-5.539],[6.143,-9.064]],"c":true},"ix":2},"nm":"s","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"s","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"_","size":150,"style":"500","w":50,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,7.553],[0,12.589],[50.354,12.589],[50.354,7.553]],"c":true},"ix":2},"nm":"_","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"_","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"0","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.797,0],[0,-21.954],[-12.79,0],[0,22.256]],"o":[[-13.293,0],[0.201,21.652],[14.502,0],[0,-20.847]],"v":[[26.385,-66.568],[3.625,-32.529],[25.278,1.108],[48.038,-33.435]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-7.755,0],[0,-16.113],[9.064,0],[0,17.02]],"o":[[9.164,0],[0,16.718],[-8.057,0],[0,-17.825]],"v":[[25.882,-59.72],[39.175,-33.032],[25.781,-5.74],[12.488,-32.428]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"0","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"5","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-3.726,0],[-0.101,-8.459],[8.359,0],[2.719,1.611],[0,0],[-7.15,0],[0,12.79],[5.136,2.921],[5.035,0],[1.511,-0.201],[0,0],[0,0]],"o":[[0,0],[0,0],[2.417,-0.302],[13.092,0],[0,8.762],[-5.942,0],[0,0],[3.122,2.014],[14.2,0],[0,-8.258],[-4.028,-2.417],[-2.417,0],[0,0],[0,0],[0,0]],"v":[[43.607,-65.46],[12.286,-65.46],[8.057,-34.039],[17.12,-34.744],[35.953,-20.242],[20.444,-6.042],[6.445,-9.668],[4.23,-2.921],[20.544,1.108],[44.916,-21.249],[35.55,-38.068],[21.451,-41.592],[16.113,-41.19],[18.631,-58.008],[43.607,-58.008]],"c":true},"ix":2},"nm":"5","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"5","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"L","size":150,"style":"500","w":47.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[7.654,0],[45.419,0],[45.419,-7.352],[16.415,-7.352],[16.415,-67.877],[7.654,-67.877]],"c":true},"ix":2},"nm":"L","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"L","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"n","size":150,"style":"500","w":55.5,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.403,1.108],[-5.841,0],[0,-7.855],[0,0],[0,0],[0,0],[6.747,0],[2.417,-4.633],[0,0],[0,0],[0,0],[0,-5.035]],"o":[[0,0],[0,0],[0,-1.511],[1.511,-4.935],[8.359,0],[0,0],[0,0],[0,0],[0,-16.718],[-8.057,0],[0,0],[0,0],[0,0],[0.302,4.028],[0,0]],"v":[[7.352,0],[16.214,0],[16.214,-29.306],[16.818,-33.435],[28.702,-42.499],[39.981,-28.098],[39.981,0],[48.843,0],[48.843,-29.105],[31.622,-49.85],[15.509,-40.686],[15.308,-40.686],[14.804,-48.743],[6.949,-48.743],[7.352,-35.55]],"c":true},"ix":2},"nm":"n","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"n","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"e","size":150,"style":"500","w":50.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,1.813],[15.912,0],[0,-14.703],[-15.005,0],[-3.122,1.41],[0,0],[6.345,0],[0.201,11.984]],"o":[[0.101,-0.906],[0,-8.963],[-14.2,0],[0,14.703],[7.755,0],[0,0],[-3.323,1.41],[-8.862,0],[0,0]],"v":[[46.527,-22.76],[46.829,-26.889],[26.688,-49.85],[3.827,-23.566],[27.795,1.007],[44.009,-2.014],[42.499,-8.359],[29.004,-5.841],[12.286,-22.76]],"c":true},"ix":2},"nm":"e","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-8.963,0],[0.101,-5.64]],"o":[[0.705,-6.143],[9.97,0],[0,0]],"v":[[12.387,-29.105],[25.983,-43.506],[38.269,-29.105]],"c":true},"ix":2},"nm":"e","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"e","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"a","size":150,"style":"500","w":48.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,4.23],[0,0],[14.905,0],[4.028,-2.618],[0,0],[-4.532,0],[0,-4.028],[0,0],[0,-11.783],[-9.869,0],[-2.719,3.827],[0,0],[0,0]],"o":[[-0.604,-3.323],[0,0],[0,-9.769],[-6.143,0],[0,0],[3.424,-2.216],[9.97,0],[0,0],[-18.832,-0.101],[0,7.05],[6.949,0],[0,0],[0,0],[0,0]],"v":[[42.398,0],[41.592,-11.682],[41.592,-29.91],[23.062,-49.85],[7.05,-45.52],[9.064,-39.679],[21.753,-43.304],[32.831,-32.025],[32.831,-31.018],[3.525,-12.891],[18.43,1.108],[33.334,-6.143],[33.636,-6.143],[34.341,0]],"c":true},"ix":2},"nm":"a","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.302,-0.906],[6.345,0],[0,5.74],[-9.668,-0.201]],"o":[[0,0.906],[-1.41,4.129],[-4.532,0],[0,-9.467],[0,0]],"v":[[33.032,-16.415],[32.529,-13.596],[20.746,-5.438],[12.387,-13.898],[33.032,-24.875]],"c":true},"ix":2},"nm":"a","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"a","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"r","size":150,"style":"500","w":33.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.201,1.208],[-6.244,0],[-0.906,-0.201],[0,0],[1.007,0],[2.216,-6.546],[0,0],[0,0],[0,0],[0,-5.74]],"o":[[0,0],[0,0],[0,-1.511],[1.208,-6.647],[1.208,0],[0,0],[-0.806,-0.201],[-5.942,0],[0,0],[0,0],[0,0],[0.302,4.532],[0,0]],"v":[[7.352,0],[16.113,0],[16.113,-25.983],[16.516,-30.112],[28.4,-41.492],[31.421,-41.19],[31.421,-49.548],[28.903,-49.85],[15.408,-39.175],[15.005,-39.175],[14.703,-48.743],[6.949,-48.743],[7.352,-33.536]],"c":true},"ix":2},"nm":"r","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"r","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"G","size":150,"style":"500","w":64.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[5.74,0],[0,17.221],[-16.516,0],[-3.625,-1.611],[0,0],[7.855,0],[0.101,-20.242],[-5.841,-5.64],[-10.272,0],[-3.928,1.41]],"o":[[0,0],[0,0],[0,0],[0,0],[-2.014,1.007],[-15.811,0],[0,-17.02],[6.848,0],[0,0],[-2.921,-1.41],[-22.76,0],[0,10.574],[6.647,6.345],[9.164,0],[0,0]],"v":[[59.317,-35.651],[36.96,-35.651],[36.96,-28.601],[50.757,-28.601],[50.757,-8.359],[39.075,-6.546],[12.891,-33.939],[40.182,-61.23],[55.188,-58.31],[57.303,-65.46],[40.384,-68.582],[3.625,-33.536],[13.092,-8.258],[38.47,0.705],[59.317,-3.021]],"c":true},"ix":2},"nm":"G","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"G","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"d","size":150,"style":"500","w":56.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[7.452,0],[-0.101,-16.214],[-11.783,0],[-2.719,5.438],[0,0],[0,0],[0,0],[0,4.33],[0,0]],"o":[[0,0],[0,0],[-2.216,-3.928],[-11.884,0],[0,14.804],[7.956,0],[0,0],[0,0],[0,0],[-0.302,-3.323],[0,0],[0,0]],"v":[[40.585,-71.503],[40.585,-42.398],[40.384,-42.398],[25.681,-49.85],[3.827,-23.666],[24.673,1.108],[41.29,-8.459],[41.492,-8.459],[41.895,0],[49.85,0],[49.448,-12.589],[49.448,-71.503]],"c":true},"ix":2},"nm":"d","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.302,-1.208],[5.942,0],[0,9.869],[-9.164,0],[-1.309,-5.64],[0,-1.108]],"o":[[0,1.41],[-1.611,6.647],[-9.567,0],[0,-10.776],[6.647,0],[0.302,1.108],[0,0]],"v":[[40.585,-20.444],[40.182,-16.617],[27.191,-6.042],[12.79,-24.069],[27.393,-42.902],[40.182,-32.629],[40.585,-28.903]],"c":true},"ix":2},"nm":"d","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"d","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"t","size":150,"style":"500","w":33.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-2.518,-2.618],[-4.129,0],[-1.712,0.705],[0,0],[2.316,0],[0,6.042],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,5.74],[2.115,2.417],[3.424,0],[0,0],[-1.108,0.302],[-4.935,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[9.366,-60.425],[9.366,-48.743],[1.813,-48.743],[1.813,-41.995],[9.366,-41.995],[9.366,-15.408],[12.79,-2.719],[22.357,1.007],[30.212,-0.201],[29.81,-6.848],[24.673,-6.244],[18.027,-15.71],[18.027,-41.995],[30.716,-41.995],[30.716,-48.743],[18.027,-48.743],[18.027,-62.741]],"c":true},"ix":2},"nm":"t","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"t","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"4","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[40.283,0],[40.283,-17.825],[49.448,-17.825],[49.448,-24.774],[40.283,-24.774],[40.283,-65.46],[30.716,-65.46],[1.511,-23.666],[1.511,-17.825],[31.924,-17.825],[31.924,0]],"c":true},"ix":2},"nm":"4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-2.014,3.827],[0,0],[0,-3.424],[0,0]],"o":[[0,0],[0,0],[1.813,-3.021],[0,0],[-0.201,3.424],[0,0],[0,0]],"v":[[10.474,-24.774],[10.474,-24.976],[26.486,-47.232],[31.924,-56.9],[32.227,-56.9],[31.924,-46.628],[31.924,-24.774]],"c":true},"ix":2},"nm":"4","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"4","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"R","size":150,"style":"500","w":53.8,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-2.014,-9.366],[-1.108,-1.913],[0,0],[2.216,9.467],[5.237,1.813],[0,0],[0,8.963],[3.424,3.021],[9.366,0],[4.431,-0.906]],"o":[[0,0],[0,0],[0,0],[7.956,0.302],[1.913,8.459],[0,0],[-1.41,-2.618],[-1.611,-7.05],[0,0],[7.15,-2.417],[0,-5.237],[-4.23,-3.827],[-6.042,0],[0,0]],"v":[[7.654,0],[16.415,0],[16.415,-29.407],[24.673,-29.407],[38.269,-16.214],[42.801,0],[51.865,0],[46.628,-18.631],[36.658,-32.327],[36.658,-32.629],[49.448,-49.951],[44.11,-62.842],[24.472,-68.381],[7.654,-66.971]],"c":true},"ix":2},"nm":"R","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-4.23,0],[0,-8.762],[9.366,0],[0,0]],"o":[[1.41,-0.403],[9.265,0.101],[0,7.755],[0,0],[0,0]],"v":[[16.415,-60.828],[25.076,-61.633],[40.686,-48.944],[25.378,-36.053],[16.415,-36.053]],"c":true},"ix":2},"nm":"R","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"R","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"3","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-7.352,0],[0,10.474],[8.057,1.611],[0,0],[0,6.747],[12.891,0],[3.424,-2.518],[0,0],[-5.237,0],[0,-5.237],[6.445,0],[0,0],[0,0],[0,0],[-0.101,-9.164],[11.38,0],[2.518,1.611]],"o":[[3.223,2.115],[15.71,0],[0,-9.164],[0,0],[8.057,-2.921],[0,-7.956],[-7.05,0],[0,0],[2.82,-2.014],[8.157,0],[0,7.755],[0,0],[0,0],[0,0],[8.56,0],[0.101,5.438],[-6.143,0],[0,0]],"v":[[4.23,-3.323],[21.249,1.108],[45.117,-18.53],[30.515,-35.349],[30.515,-35.55],[42.599,-50.958],[23.868,-66.568],[6.747,-61.533],[9.064,-55.087],[22.156,-59.418],[33.636,-49.548],[19.034,-38.47],[14.099,-38.47],[14.099,-31.824],[19.034,-31.824],[35.953,-18.732],[21.149,-6.042],[6.647,-10.172]],"c":true},"ix":2},"nm":"3","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"3","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"u","size":150,"style":"500","w":55.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0.504,-1.309],[5.942,0],[0,9.265],[0,0],[0,0],[0,0],[-7.654,0],[-2.316,3.928],[0,0],[0,0],[0,0],[0,5.035]],"o":[[0,0],[0,0],[0,1.611],[-1.611,3.928],[-8.057,0],[0,0],[0,0],[0,0],[0,17.12],[8.661,0],[0,0],[0,0],[0,0],[-0.302,-3.827],[0,0]],"v":[[48.138,-48.743],[39.276,-48.743],[39.276,-18.832],[38.47,-14.301],[26.788,-6.244],[15.912,-21.753],[15.912,-48.743],[7.05,-48.743],[7.05,-20.242],[23.868,1.108],[39.981,-7.956],[40.182,-7.956],[40.686,0],[48.541,0],[48.138,-13.293]],"c":true},"ix":2},"nm":"u","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"u","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"2","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,12.085],[14.099,0],[4.532,-3.827],[0,0],[-5.942,0],[0,-6.647],[16.718,-15.912],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[13.797,-13.293],[0,-9.366],[-7.553,0],[0,0],[3.021,-2.518],[9.769,0],[-0.101,9.869],[0,0],[0,0],[0,0]],"v":[[46.326,0],[46.326,-7.352],[16.919,-7.352],[16.919,-7.553],[22.156,-12.387],[44.714,-47.534],[24.673,-66.568],[6.143,-59.921],[8.963,-53.677],[22.861,-59.216],[35.852,-46.426],[11.481,-12.186],[4.532,-5.438],[4.532,0]],"c":true},"ix":2},"nm":"2","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"O","size":150,"style":"500","w":68.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[18.53,0],[0,-21.552],[-17.926,0],[0,23.364]],"o":[[-18.127,0],[0,20.544],[17.322,0],[0,-20.142]],"v":[[35.147,-68.985],[3.625,-33.334],[34.14,1.108],[65.662,-34.644]],"c":true},"ix":2},"nm":"O","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-14.502,0],[0,-13.495],[13.898,0],[0,14.502]],"o":[[14.603,0],[0,15.408],[-13.797,0],[0,-14.905]],"v":[[34.744,-61.835],[56.396,-34.241],[34.644,-6.042],[12.991,-33.536]],"c":true},"ix":2},"nm":"O","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"O","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"p","size":150,"style":"500","w":56.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-6.445,0],[0,17.523],[11.783,0],[3.625,-5.942],[0,0],[0,0],[0,0],[0,-6.244]],"o":[[0,0],[0,0],[0,0],[2.921,4.834],[11.481,0],[0,-14.804],[-7.956,0],[0,0],[0,0],[0,0],[0.201,4.633],[0,0]],"v":[[7.352,19.94],[16.113,19.94],[16.113,-6.546],[16.315,-6.546],[31.32,1.108],[53.476,-25.076],[32.831,-49.85],[15.509,-40.384],[15.308,-40.384],[14.905,-48.743],[6.949,-48.743],[7.352,-32.831]],"c":true},"ix":2},"nm":"p","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-0.302,1.108],[-6.042,0],[0,-9.769],[9.366,0],[1.611,6.143],[0,1.309]],"o":[[0,-1.208],[1.712,-6.647],[9.366,0],[0,11.179],[-6.345,0],[-0.201,-1.108],[0,0]],"v":[[16.113,-28.198],[16.718,-31.824],[30.112,-42.801],[44.614,-24.673],[29.81,-5.841],[16.516,-16.214],[16.113,-19.839]],"c":true},"ix":2},"nm":"p","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"p","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"c","size":150,"style":"500","w":44.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[5.035,0],[0,11.279],[-11.179,0],[-2.115,-1.208],[0,0],[5.237,0],[0,-15.005],[-14.703,0],[-2.316,1.208]],"o":[[-2.518,1.108],[-9.668,0],[0,-10.172],[4.834,0],[0,0],[-2.417,-1.208],[-15.912,0],[0,14.905],[6.546,0],[0,0]],"v":[[40.585,-8.459],[29.709,-6.042],[12.79,-24.271],[30.011,-42.7],[40.283,-40.384],[42.297,-47.232],[30.011,-49.75],[3.827,-23.868],[28.098,1.007],[42.096,-1.813]],"c":true},"ix":2},"nm":"c","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"c","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"y","size":150,"style":"500","w":48.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,-0.504],[0.403,-0.906],[2.417,-1.913],[2.216,-0.705],[0,0],[-4.33,3.827],[-6.345,16.718],[0,0],[0,0],[0,0],[0.906,-2.921],[0,0],[1.108,3.223],[0,0]],"o":[[0,0],[0.403,1.108],[0,0.504],[-2.014,4.532],[-2.618,2.216],[0,0],[2.216,-0.403],[6.042,-5.237],[0,0],[0,0],[0,0],[-1.208,3.525],[0,0],[-0.806,-2.921],[0,0],[0,0]],"v":[[0.906,-48.743],[18.933,-3.827],[19.537,-1.511],[18.832,0.604],[11.38,10.474],[3.625,14.804],[5.841,22.256],[16.718,16.516],[33.435,-13.998],[46.729,-48.743],[37.363,-48.743],[27.695,-20.142],[24.573,-9.97],[24.371,-9.97],[21.249,-19.94],[10.574,-48.743]],"c":true},"ix":2},"nm":"y","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"y","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"1","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[23.767,0],[32.327,0],[32.327,-65.46],[24.774,-65.46],[10.474,-57.806],[12.186,-51.059],[23.566,-57.202],[23.767,-57.202]],"c":true},"ix":2},"nm":"1","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"C","size":150,"style":"500","w":55.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[5.338,0],[0,16.617],[-15.912,0],[-3.323,-1.611],[0,0],[8.459,0],[0,-21.249],[-19.135,0],[-3.223,1.611]],"o":[[-3.525,1.712],[-16.516,0],[0,-17.825],[5.64,0],[0,0],[-2.316,-1.208],[-21.048,0],[0,22.256],[8.258,0],[0,0]],"v":[[53.275,-9.164],[38.974,-6.345],[12.891,-33.636],[39.377,-61.633],[53.073,-58.813],[55.188,-65.964],[39.075,-68.985],[3.625,-33.334],[37.161,1.007],[55.087,-2.216]],"c":true},"ix":2},"nm":"C","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"C","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"o","size":150,"style":"500","w":54.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.998,0],[0,-16.315],[-13.193,0],[0,18.027]],"o":[[-13.495,0],[0,15.408],[11.783,0],[0,-14.905]],"v":[[27.997,-49.85],[3.827,-23.969],[27.191,1.108],[51.462,-24.774]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-10.474,0],[0,-8.258],[8.459,0],[0,10.675]],"o":[[10.474,0],[0,10.977],[-8.661,0],[0,-9.265]],"v":[[27.795,-43.204],[42.398,-24.472],[27.594,-5.539],[12.79,-24.271]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"o","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/C Strokes_All_01_1920x1080.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/C Strokes_All_01_1920x1080.json deleted file mode 100644 index a8984437..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/C Strokes_All_01_1920x1080.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.18","fr":30,"ip":0,"op":36,"w":1920,"h":1080,"nm":"C Strokes_All_01","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[1924.5,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[483.75,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[964,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[1444.25,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[3.5,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0.901960790157,0.713725507259,0.054901961237,1],"e":[0.054901961237,0.631372570992,0.901960790157,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.054901961237,0.631372570992,0.901960790157,1],"e":[0.901960790157,0.713725507259,0.054901961237,1]},{"t":30}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":15,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.054901961237,0.631372570992,0.901960790157,1],"ix":3},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0],"e":[100]},{"t":30}],"ix":4},"w":{"a":0,"k":15,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_3","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[15],"e":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[40],"e":[15]},{"t":30}],"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_4","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"line Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375.125,243.75,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-194.25,95.5],[-194.25,-96],[19.75,-96],[19.75,96],[194.25,96]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":15,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[959.75,540.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_5","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":1,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_6","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":1,"lj":1,"ml":1,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_7","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":15,"ix":5},"lc":1,"lj":1,"ml":4,"d":[{"n":"d","nm":"dash","v":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[10],"e":[73]},{"t":30}],"ix":1}},{"n":"o","nm":"offset","v":{"a":0,"k":0,"ix":7}}],"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_8","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":15,"ix":10},"g":{"p":3,"k":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":40,"s":[0,0.055,0.631,0.902,0.5,0.478,0.673,0.478,1,0.902,0.714,0.055],"e":[0,0.902,0.055,0.174,0.5,0.902,0.384,0.115,1,0.902,0.714,0.055]},{"t":50}],"ix":8}},"s":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[0,143],"e":[130,601],"to":[21.6666660308838,76.3333358764648],"ti":[-21.6666660308838,-76.3333358764648]},{"t":40}],"ix":4},"e":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[-76,0],"e":[184,0],"to":[43.3333320617676,0],"ti":[-43.3333320617676,0]},{"t":20}],"ix":5},"t":1,"lc":1,"lj":1,"ml":4,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]}],"fonts":{"list":[{"fName":"SamsungOne-500","fFamily":"SamsungOne","fStyle":"500","ascent":70.9991455078125}]},"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"div","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":10,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":5,"nm":"C Strokes_01 Color","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[39.375,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"C Strokes_01 Color","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":5,"nm":"C Strokes_02 Opacity","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[519.5,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"C Strokes_02 Opacity","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":5,"nm":"C Strokes_03 Width","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1000.375,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"C Strokes_03 Width","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":5,"nm":"C Strokes_04 Line Cap","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1480.5,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"C Strokes_04 Line Cap","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":5,"nm":"C Strokes_05 Line Join","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[39.375,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"C Strokes_05 Line Join","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":5,"nm":"C Strokes_06 Miter Limit","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[519.5,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"C Strokes_06 Miter Limit","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":5,"nm":"C Strokes_07 Dashes","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1000.375,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"C Strokes_07 Dashes","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":5,"nm":"C Strokes_08 Gradient","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1480.5,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"C Strokes_08 Gradient","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"C Strokes_01 Color","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[248,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":0,"nm":"C Strokes_02 Opacity","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[726,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":0,"nm":"C Strokes_03 Width","refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1204,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":0,"nm":"C Strokes_04 Line Cap","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1678,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":0,"nm":"C Strokes_05 Line Join","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[248,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":0,"nm":"C Strokes_06 Miter Limit","refId":"comp_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[732,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":0,"nm":"C Strokes_07 Dashes","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1198,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":0,"nm":"C Strokes_08 Gradient","refId":"comp_8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1678,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0}],"markers":[],"chars":[{"ch":"C","size":150,"style":"500","w":55.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[5.338,0],[0,16.617],[-15.912,0],[-3.323,-1.611],[0,0],[8.459,0],[0,-21.249],[-19.135,0],[-3.223,1.611]],"o":[[-3.525,1.712],[-16.516,0],[0,-17.825],[5.64,0],[0,0],[-2.316,-1.208],[-21.048,0],[0,22.256],[8.258,0],[0,0]],"v":[[53.275,-9.164],[38.974,-6.345],[12.891,-33.636],[39.377,-61.633],[53.073,-58.813],[55.188,-65.964],[39.075,-68.985],[3.625,-33.334],[37.161,1.007],[55.087,-2.216]],"c":true},"ix":2},"nm":"C","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"C","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":" ","size":150,"style":"500","w":21.2,"data":{},"fFamily":"SamsungOne"},{"ch":"S","size":150,"style":"500","w":49.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.546,0],[0,10.474],[11.481,4.431],[0,6.345],[-9.265,0],[-2.216,-1.208],[0,0],[6.949,0],[0,-10.574],[-11.078,-3.928],[0,-6.345],[8.963,0],[3.928,2.417]],"o":[[3.625,2.417],[16.013,0],[0,-9.97],[-9.366,-3.625],[0,-4.633],[6.143,0],[0,0],[-3.021,-1.712],[-13.193,0],[0,9.567],[9.164,3.525],[0,6.848],[-6.042,0],[0,0]],"v":[[4.23,-3.323],[21.552,1.007],[45.319,-18.53],[27.997,-38.47],[14.502,-51.562],[27.292,-61.734],[40.182,-58.511],[42.599,-65.662],[27.594,-68.985],[5.64,-50.555],[23.566,-31.32],[36.356,-17.825],[22.156,-6.244],[6.445,-10.675]],"c":true},"ix":2},"nm":"S","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"S","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"t","size":150,"style":"500","w":33.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-2.518,-2.618],[-4.129,0],[-1.712,0.705],[0,0],[2.316,0],[0,6.042],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,5.74],[2.115,2.417],[3.424,0],[0,0],[-1.108,0.302],[-4.935,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[9.366,-60.425],[9.366,-48.743],[1.813,-48.743],[1.813,-41.995],[9.366,-41.995],[9.366,-15.408],[12.79,-2.719],[22.357,1.007],[30.212,-0.201],[29.81,-6.848],[24.673,-6.244],[18.027,-15.71],[18.027,-41.995],[30.716,-41.995],[30.716,-48.743],[18.027,-48.743],[18.027,-62.741]],"c":true},"ix":2},"nm":"t","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"t","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"r","size":150,"style":"500","w":33.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.201,1.208],[-6.244,0],[-0.906,-0.201],[0,0],[1.007,0],[2.216,-6.546],[0,0],[0,0],[0,0],[0,-5.74]],"o":[[0,0],[0,0],[0,-1.511],[1.208,-6.647],[1.208,0],[0,0],[-0.806,-0.201],[-5.942,0],[0,0],[0,0],[0,0],[0.302,4.532],[0,0]],"v":[[7.352,0],[16.113,0],[16.113,-25.983],[16.516,-30.112],[28.4,-41.492],[31.421,-41.19],[31.421,-49.548],[28.903,-49.85],[15.408,-39.175],[15.005,-39.175],[14.703,-48.743],[6.949,-48.743],[7.352,-33.536]],"c":true},"ix":2},"nm":"r","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"r","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"o","size":150,"style":"500","w":54.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.998,0],[0,-16.315],[-13.193,0],[0,18.027]],"o":[[-13.495,0],[0,15.408],[11.783,0],[0,-14.905]],"v":[[27.997,-49.85],[3.827,-23.969],[27.191,1.108],[51.462,-24.774]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-10.474,0],[0,-8.258],[8.459,0],[0,10.675]],"o":[[10.474,0],[0,10.977],[-8.661,0],[0,-9.265]],"v":[[27.795,-43.204],[42.398,-24.472],[27.594,-5.539],[12.79,-24.271]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"o","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"k","size":150,"style":"500","w":48.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.208,-1.712],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.41,1.712],[0,0],[0,0]],"v":[[16.113,-71.503],[7.352,-71.503],[7.352,0],[16.113,0],[16.113,-18.329],[20.645,-23.364],[37.463,0],[48.239,0],[26.788,-28.702],[45.621,-48.743],[34.946,-48.743],[20.645,-31.924],[16.315,-26.385],[16.113,-26.385]],"c":true},"ix":2},"nm":"k","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"k","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"e","size":150,"style":"500","w":50.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,1.813],[15.912,0],[0,-14.703],[-15.005,0],[-3.122,1.41],[0,0],[6.345,0],[0.201,11.984]],"o":[[0.101,-0.906],[0,-8.963],[-14.2,0],[0,14.703],[7.755,0],[0,0],[-3.323,1.41],[-8.862,0],[0,0]],"v":[[46.527,-22.76],[46.829,-26.889],[26.688,-49.85],[3.827,-23.566],[27.795,1.007],[44.009,-2.014],[42.499,-8.359],[29.004,-5.841],[12.286,-22.76]],"c":true},"ix":2},"nm":"e","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-8.963,0],[0.101,-5.64]],"o":[[0.705,-6.143],[9.97,0],[0,0]],"v":[[12.387,-29.105],[25.983,-43.506],[38.269,-29.105]],"c":true},"ix":2},"nm":"e","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"e","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"s","size":150,"style":"500","w":39.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-5.338,0],[0,8.56],[8.459,3.223],[0,4.028],[-5.237,0],[-1.913,-1.208],[0,0],[4.935,0],[0,-7.855],[-8.762,-3.122],[0,-4.23],[6.445,0],[2.618,1.712]],"o":[[3.424,2.014],[11.581,0],[0,-7.251],[-6.345,-2.417],[0,-3.625],[4.532,0],[0,0],[-2.719,-1.611],[-10.474,0],[0,5.841],[6.546,2.417],[0,4.028],[-4.431,0],[0,0]],"v":[[3.928,-2.316],[17.624,1.007],[35.852,-13.596],[23.062,-28.299],[13.797,-36.557],[21.954,-43.204],[31.924,-40.384],[34.14,-46.829],[22.156,-49.85],[5.338,-35.55],[18.228,-21.753],[27.292,-12.79],[17.825,-5.539],[6.143,-9.064]],"c":true},"ix":2},"nm":"s","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"s","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"_","size":150,"style":"500","w":50,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,7.553],[0,12.589],[50.354,12.589],[50.354,7.553]],"c":true},"ix":2},"nm":"_","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"_","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"0","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.797,0],[0,-21.954],[-12.79,0],[0,22.256]],"o":[[-13.293,0],[0.201,21.652],[14.502,0],[0,-20.847]],"v":[[26.385,-66.568],[3.625,-32.529],[25.278,1.108],[48.038,-33.435]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-7.755,0],[0,-16.113],[9.064,0],[0,17.02]],"o":[[9.164,0],[0,16.718],[-8.057,0],[0,-17.825]],"v":[[25.882,-59.72],[39.175,-33.032],[25.781,-5.74],[12.488,-32.428]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"0","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"8","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-13.696,0],[0,11.38],[8.157,3.223],[0,0],[0,5.539],[12.689,0],[0,-10.373],[-7.251,-3.424],[0,0],[0,-8.258]],"o":[[12.488,0],[0,-7.956],[0,0],[8.057,-3.827],[0,-8.157],[-11.481,0],[0,5.64],[0,0],[-8.057,3.424],[0,9.567]],"v":[[25.681,1.108],[47.937,-17.926],[34.744,-34.845],[34.744,-35.147],[45.52,-50.455],[26.486,-66.568],[6.244,-49.146],[16.617,-34.442],[16.718,-34.14],[3.726,-16.617]],"c":true},"ix":2},"nm":"8","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[7.956,0],[-0.302,6.647],[-7.654,2.216],[0,-7.956]],"o":[[-8.359,0],[0,-6.244],[8.862,2.518],[0,6.747]],"v":[[25.882,-5.338],[12.79,-17.825],[24.573,-31.32],[38.974,-17.02]],"c":true},"ix":2},"nm":"8","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-7.352,0],[0,-5.237],[5.64,-1.913],[0,6.546]],"o":[[7.956,0],[0,5.942],[-7.553,-2.014],[0,-5.64]],"v":[[25.983,-60.223],[37.061,-49.548],[27.09,-37.665],[14.603,-49.75]],"c":true},"ix":2},"nm":"8","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"8","np":6,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"G","size":150,"style":"500","w":64.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[5.74,0],[0,17.221],[-16.516,0],[-3.625,-1.611],[0,0],[7.855,0],[0.101,-20.242],[-5.841,-5.64],[-10.272,0],[-3.928,1.41]],"o":[[0,0],[0,0],[0,0],[0,0],[-2.014,1.007],[-15.811,0],[0,-17.02],[6.848,0],[0,0],[-2.921,-1.41],[-22.76,0],[0,10.574],[6.647,6.345],[9.164,0],[0,0]],"v":[[59.317,-35.651],[36.96,-35.651],[36.96,-28.601],[50.757,-28.601],[50.757,-8.359],[39.075,-6.546],[12.891,-33.939],[40.182,-61.23],[55.188,-58.31],[57.303,-65.46],[40.384,-68.582],[3.625,-33.536],[13.092,-8.258],[38.47,0.705],[59.317,-3.021]],"c":true},"ix":2},"nm":"G","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"G","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"a","size":150,"style":"500","w":48.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,4.23],[0,0],[14.905,0],[4.028,-2.618],[0,0],[-4.532,0],[0,-4.028],[0,0],[0,-11.783],[-9.869,0],[-2.719,3.827],[0,0],[0,0]],"o":[[-0.604,-3.323],[0,0],[0,-9.769],[-6.143,0],[0,0],[3.424,-2.216],[9.97,0],[0,0],[-18.832,-0.101],[0,7.05],[6.949,0],[0,0],[0,0],[0,0]],"v":[[42.398,0],[41.592,-11.682],[41.592,-29.91],[23.062,-49.85],[7.05,-45.52],[9.064,-39.679],[21.753,-43.304],[32.831,-32.025],[32.831,-31.018],[3.525,-12.891],[18.43,1.108],[33.334,-6.143],[33.636,-6.143],[34.341,0]],"c":true},"ix":2},"nm":"a","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.302,-0.906],[6.345,0],[0,5.74],[-9.668,-0.201]],"o":[[0,0.906],[-1.41,4.129],[-4.532,0],[0,-9.467],[0,0]],"v":[[33.032,-16.415],[32.529,-13.596],[20.746,-5.438],[12.387,-13.898],[33.032,-24.875]],"c":true},"ix":2},"nm":"a","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"a","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"d","size":150,"style":"500","w":56.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[7.452,0],[-0.101,-16.214],[-11.783,0],[-2.719,5.438],[0,0],[0,0],[0,0],[0,4.33],[0,0]],"o":[[0,0],[0,0],[-2.216,-3.928],[-11.884,0],[0,14.804],[7.956,0],[0,0],[0,0],[0,0],[-0.302,-3.323],[0,0],[0,0]],"v":[[40.585,-71.503],[40.585,-42.398],[40.384,-42.398],[25.681,-49.85],[3.827,-23.666],[24.673,1.108],[41.29,-8.459],[41.492,-8.459],[41.895,0],[49.85,0],[49.448,-12.589],[49.448,-71.503]],"c":true},"ix":2},"nm":"d","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.302,-1.208],[5.942,0],[0,9.869],[-9.164,0],[-1.309,-5.64],[0,-1.108]],"o":[[0,1.41],[-1.611,6.647],[-9.567,0],[0,-10.776],[6.647,0],[0.302,1.108],[0,0]],"v":[[40.585,-20.444],[40.182,-16.617],[27.191,-6.042],[12.79,-24.069],[27.393,-42.902],[40.182,-32.629],[40.585,-28.903]],"c":true},"ix":2},"nm":"d","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"d","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"i","size":150,"style":"500","w":23.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16.214,0],[16.214,-48.743],[7.352,-48.743],[7.352,0]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[3.323,0],[0,-3.122],[-3.122,0],[0.101,3.021]],"o":[[-3.223,0],[0,3.021],[3.525,0],[0,-3.122]],"v":[[11.783,-67.978],[6.244,-62.439],[11.581,-57.001],[17.221,-62.439]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"i","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"n","size":150,"style":"500","w":55.5,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.403,1.108],[-5.841,0],[0,-7.855],[0,0],[0,0],[0,0],[6.747,0],[2.417,-4.633],[0,0],[0,0],[0,0],[0,-5.035]],"o":[[0,0],[0,0],[0,-1.511],[1.511,-4.935],[8.359,0],[0,0],[0,0],[0,0],[0,-16.718],[-8.057,0],[0,0],[0,0],[0,0],[0.302,4.028],[0,0]],"v":[[7.352,0],[16.214,0],[16.214,-29.306],[16.818,-33.435],[28.702,-42.499],[39.981,-28.098],[39.981,0],[48.843,0],[48.843,-29.105],[31.622,-49.85],[15.509,-40.686],[15.308,-40.686],[14.804,-48.743],[6.949,-48.743],[7.352,-35.55]],"c":true},"ix":2},"nm":"n","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"n","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"7","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[5.74,-65.46],[5.74,-58.109],[37.766,-58.109],[37.766,-57.907],[9.366,0],[18.53,0],[47.031,-59.619],[47.031,-65.46]],"c":true},"ix":2},"nm":"7","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"7","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"D","size":150,"style":"500","w":66.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.244,0],[-6.345,6.345],[0,11.078],[6.042,5.539],[12.589,0],[5.338,-0.806]],"o":[[4.431,0.504],[13.193,0],[6.345,-6.244],[0,-10.977],[-5.942,-5.539],[-6.949,0],[0,0]],"v":[[7.654,-0.201],[23.566,0.604],[53.577,-9.164],[63.345,-35.55],[53.778,-59.921],[26.285,-68.381],[7.654,-66.971]],"c":true},"ix":2},"nm":"D","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-4.532,0],[0.101,-16.013],[18.732,0],[2.216,0.403]],"o":[[2.316,-0.504],[18.53,0],[0,18.329],[-3.424,0],[0,0]],"v":[[16.415,-60.526],[26.688,-61.432],[54.181,-35.248],[25.278,-6.445],[16.415,-6.949]],"c":true},"ix":2},"nm":"D","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"D","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"h","size":150,"style":"500","w":55.5,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.504,1.208],[-5.74,0],[0,-7.855],[0,0],[0,0],[0,0],[6.546,0],[2.618,-1.511],[1.41,-2.518],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,-1.712],[1.611,-4.834],[8.359,0],[0,0],[0,0],[0,0],[0,-16.818],[-3.323,0],[-2.719,1.511],[0,0],[0,0],[0,0],[0,0]],"v":[[7.352,0],[16.214,0],[16.214,-29.407],[16.818,-33.636],[28.702,-42.499],[39.981,-27.997],[39.981,0],[48.843,0],[48.843,-29.004],[31.824,-49.85],[22.76,-47.333],[16.415,-41.089],[16.214,-41.089],[16.214,-71.503],[7.352,-71.503]],"c":true},"ix":2},"nm":"h","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"h","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"6","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[2.618,-0.403],[5.438,-5.338],[0,-12.891],[-13.998,0],[0,11.984],[11.581,0],[3.122,-4.129],[0,0],[-13.898,2.316],[-1.813,-0.101]],"o":[[-1.611,0],[-8.258,1.007],[-6.445,6.445],[0,17.02],[13.596,0],[0,-12.79],[-7.251,0],[0,0],[1.511,-10.776],[2.518,-0.403],[0,0]],"v":[[41.895,-66.467],[35.449,-65.964],[14.502,-56.296],[3.424,-26.788],[26.587,1.108],[48.34,-21.954],[28.601,-43.103],[12.79,-35.55],[12.488,-35.55],[35.248,-58.813],[41.895,-59.216]],"c":true},"ix":2},"nm":"6","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[7.654,0],[0.201,10.776],[-0.604,1.007],[-5.338,0],[0,-9.366]],"o":[[-9.265,0],[0,-1.611],[2.417,-4.733],[8.157,0],[0,9.366]],"v":[[26.587,-5.74],[12.186,-24.472],[13.193,-28.4],[25.882,-36.456],[39.377,-21.451]],"c":true},"ix":2},"nm":"6","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"6","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"M","size":150,"style":"500","w":80.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[1.712,-6.848],[0,0],[2.82,8.359],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.201,8.459],[0,0],[-3.223,-9.567],[0,0],[0,0],[0,0],[-2.316,7.956],[0,0],[-0.504,-9.467]],"o":[[0,0],[0,0],[0,0],[0,0],[-3.021,8.56],[0,0],[-1.712,-7.05],[0,0],[0,0],[0,0],[0,0],[0,0],[0.604,-10.172],[0,0],[1.913,8.057],[0,0],[0,0],[0,0],[3.424,-9.366],[0,0],[-0.101,8.459],[0,0]],"v":[[66.568,0],[75.128,0],[70.898,-67.877],[59.72,-67.877],[47.635,-35.046],[40.485,-12.186],[40.182,-12.186],[33.334,-35.046],[21.753,-67.877],[10.574,-67.877],[5.841,0],[14.2,0],[16.013,-29.105],[17.322,-59.116],[17.523,-59.116],[25.378,-32.73],[36.356,-0.403],[43.002,-0.403],[54.987,-33.334],[63.547,-59.116],[63.849,-59.116],[64.856,-29.81]],"c":true},"ix":2},"nm":"M","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"M","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"L","size":150,"style":"500","w":47.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[7.654,0],[45.419,0],[45.419,-7.352],[16.415,-7.352],[16.415,-67.877],[7.654,-67.877]],"c":true},"ix":2},"nm":"L","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"L","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"m","size":150,"style":"500","w":83.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.504,1.309],[-5.539,0],[0,-7.755],[0,0],[0,0],[0,0],[-0.403,1.208],[-5.035,0],[0,-9.366],[0,0],[0,0],[0,0],[6.445,0],[2.921,-2.216],[1.511,-2.719],[0,0],[6.647,0],[2.719,-4.633],[0,0],[0,0],[0,0],[0,-5.035]],"o":[[0,0],[0,0],[0,-1.511],[1.41,-4.431],[6.747,0],[0,0],[0,0],[0,0],[0,-1.611],[1.511,-4.33],[7.15,0],[0,0],[0,0],[0,0],[0,-16.919],[-4.633,0],[-2.014,1.511],[0,0],[-2.115,-5.74],[-8.057,0],[0,0],[0,0],[0,0],[0.302,4.028],[0,0]],"v":[[7.352,0],[16.013,0],[16.013,-29.407],[16.718,-33.737],[27.695,-42.599],[37.866,-29.205],[37.866,0],[46.527,0],[46.527,-30.112],[47.232,-34.543],[57.706,-42.599],[68.28,-27.594],[68.28,0],[76.941,0],[76.941,-28.702],[60.928,-49.85],[50.153,-46.426],[44.714,-40.082],[44.513,-40.082],[30.716,-49.85],[15.408,-40.887],[15.106,-40.887],[14.703,-48.743],[6.949,-48.743],[7.352,-35.55]],"c":true},"ix":2},"nm":"m","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"m","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"5","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-3.726,0],[-0.101,-8.459],[8.359,0],[2.719,1.611],[0,0],[-7.15,0],[0,12.79],[5.136,2.921],[5.035,0],[1.511,-0.201],[0,0],[0,0]],"o":[[0,0],[0,0],[2.417,-0.302],[13.092,0],[0,8.762],[-5.942,0],[0,0],[3.122,2.014],[14.2,0],[0,-8.258],[-4.028,-2.417],[-2.417,0],[0,0],[0,0],[0,0]],"v":[[43.607,-65.46],[12.286,-65.46],[8.057,-34.039],[17.12,-34.744],[35.953,-20.242],[20.444,-6.042],[6.445,-9.668],[4.23,-2.921],[20.544,1.108],[44.916,-21.249],[35.55,-38.068],[21.451,-41.592],[16.113,-41.19],[18.631,-58.008],[43.607,-58.008]],"c":true},"ix":2},"nm":"5","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"5","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"J","size":150,"style":"500","w":37,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[7.855,0],[1.813,0.705],[0,0],[-3.223,0],[0,18.027],[0,0],[0,0]],"o":[[0,13.293],[-2.921,0],[0,0],[2.216,0.906],[11.682,0],[0,0],[0,0],[0,0]],"v":[[21.552,-23.163],[9.064,-6.345],[1.712,-7.654],[0.403,-0.504],[9.769,1.108],[30.313,-22.458],[30.313,-67.877],[21.552,-67.877]],"c":true},"ix":2},"nm":"J","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"J","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"4","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[40.283,0],[40.283,-17.825],[49.448,-17.825],[49.448,-24.774],[40.283,-24.774],[40.283,-65.46],[30.716,-65.46],[1.511,-23.666],[1.511,-17.825],[31.924,-17.825],[31.924,0]],"c":true},"ix":2},"nm":"4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-2.014,3.827],[0,0],[0,-3.424],[0,0]],"o":[[0,0],[0,0],[1.813,-3.021],[0,0],[-0.201,3.424],[0,0],[0,0]],"v":[[10.474,-24.774],[10.474,-24.976],[26.486,-47.232],[31.924,-56.9],[32.227,-56.9],[31.924,-46.628],[31.924,-24.774]],"c":true},"ix":2},"nm":"4","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"4","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"p","size":150,"style":"500","w":56.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-6.445,0],[0,17.523],[11.783,0],[3.625,-5.942],[0,0],[0,0],[0,0],[0,-6.244]],"o":[[0,0],[0,0],[0,0],[2.921,4.834],[11.481,0],[0,-14.804],[-7.956,0],[0,0],[0,0],[0,0],[0.201,4.633],[0,0]],"v":[[7.352,19.94],[16.113,19.94],[16.113,-6.546],[16.315,-6.546],[31.32,1.108],[53.476,-25.076],[32.831,-49.85],[15.509,-40.384],[15.308,-40.384],[14.905,-48.743],[6.949,-48.743],[7.352,-32.831]],"c":true},"ix":2},"nm":"p","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-0.302,1.108],[-6.042,0],[0,-9.769],[9.366,0],[1.611,6.143],[0,1.309]],"o":[[0,-1.208],[1.712,-6.647],[9.366,0],[0,11.179],[-6.345,0],[-0.201,-1.108],[0,0]],"v":[[16.113,-28.198],[16.718,-31.824],[30.112,-42.801],[44.614,-24.673],[29.81,-5.841],[16.516,-16.214],[16.113,-19.839]],"c":true},"ix":2},"nm":"p","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"p","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"3","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-7.352,0],[0,10.474],[8.057,1.611],[0,0],[0,6.747],[12.891,0],[3.424,-2.518],[0,0],[-5.237,0],[0,-5.237],[6.445,0],[0,0],[0,0],[0,0],[-0.101,-9.164],[11.38,0],[2.518,1.611]],"o":[[3.223,2.115],[15.71,0],[0,-9.164],[0,0],[8.057,-2.921],[0,-7.956],[-7.05,0],[0,0],[2.82,-2.014],[8.157,0],[0,7.755],[0,0],[0,0],[0,0],[8.56,0],[0.101,5.438],[-6.143,0],[0,0]],"v":[[4.23,-3.323],[21.249,1.108],[45.117,-18.53],[30.515,-35.349],[30.515,-35.55],[42.599,-50.958],[23.868,-66.568],[6.747,-61.533],[9.064,-55.087],[22.156,-59.418],[33.636,-49.548],[19.034,-38.47],[14.099,-38.47],[14.099,-31.824],[19.034,-31.824],[35.953,-18.732],[21.149,-6.042],[6.647,-10.172]],"c":true},"ix":2},"nm":"3","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"3","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"W","size":150,"style":"500","w":86.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-1.208,6.747],[0,0],[-2.115,-8.661],[0,0],[0,0],[0,0],[0,0],[0,0],[1.41,-7.452],[0,0],[1.913,8.057],[0,0],[0,0],[0,0],[1.108,-6.747],[0,0],[2.014,8.459],[0,0],[0,0],[0,0]],"o":[[0,0],[2.518,-8.762],[0,0],[0.906,6.848],[0,0],[0,0],[0,0],[0,0],[0,0],[-2.115,8.459],[0,0],[-1.007,-7.15],[0,0],[0,0],[0,0],[-2.316,8.762],[0,0],[-1.208,-6.546],[0,0],[0,0],[0,0],[0,0]],"v":[[27.896,0],[37.564,-35.349],[42.801,-57.504],[43.002,-57.504],[47.433,-35.349],[55.994,0],[65.158,0],[84.393,-67.877],[75.43,-67.877],[66.467,-33.636],[61.029,-10.172],[60.828,-10.172],[56.094,-33.435],[47.836,-67.877],[38.672,-67.877],[29.608,-33.636],[24.069,-10.071],[23.868,-10.071],[18.832,-33.536],[10.776,-67.877],[1.511,-67.877],[18.732,0]],"c":true},"ix":2},"nm":"W","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"W","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"2","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,12.085],[14.099,0],[4.532,-3.827],[0,0],[-5.942,0],[0,-6.647],[16.718,-15.912],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[13.797,-13.293],[0,-9.366],[-7.553,0],[0,0],[3.021,-2.518],[9.769,0],[-0.101,9.869],[0,0],[0,0],[0,0]],"v":[[46.326,0],[46.326,-7.352],[16.919,-7.352],[16.919,-7.553],[22.156,-12.387],[44.714,-47.534],[24.673,-66.568],[6.143,-59.921],[8.963,-53.677],[22.861,-59.216],[35.852,-46.426],[11.481,-12.186],[4.532,-5.438],[4.532,0]],"c":true},"ix":2},"nm":"2","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"O","size":150,"style":"500","w":68.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[18.53,0],[0,-21.552],[-17.926,0],[0,23.364]],"o":[[-18.127,0],[0,20.544],[17.322,0],[0,-20.142]],"v":[[35.147,-68.985],[3.625,-33.334],[34.14,1.108],[65.662,-34.644]],"c":true},"ix":2},"nm":"O","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-14.502,0],[0,-13.495],[13.898,0],[0,14.502]],"o":[[14.603,0],[0,15.408],[-13.797,0],[0,-14.905]],"v":[[34.744,-61.835],[56.396,-34.241],[34.644,-6.042],[12.991,-33.536]],"c":true},"ix":2},"nm":"O","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"O","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"c","size":150,"style":"500","w":44.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[5.035,0],[0,11.279],[-11.179,0],[-2.115,-1.208],[0,0],[5.237,0],[0,-15.005],[-14.703,0],[-2.316,1.208]],"o":[[-2.518,1.108],[-9.668,0],[0,-10.172],[4.834,0],[0,0],[-2.417,-1.208],[-15.912,0],[0,14.905],[6.546,0],[0,0]],"v":[[40.585,-8.459],[29.709,-6.042],[12.79,-24.271],[30.011,-42.7],[40.283,-40.384],[42.297,-47.232],[30.011,-49.75],[3.827,-23.868],[28.098,1.007],[42.096,-1.813]],"c":true},"ix":2},"nm":"c","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"c","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"y","size":150,"style":"500","w":48.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,-0.504],[0.403,-0.906],[2.417,-1.913],[2.216,-0.705],[0,0],[-4.33,3.827],[-6.345,16.718],[0,0],[0,0],[0,0],[0.906,-2.921],[0,0],[1.108,3.223],[0,0]],"o":[[0,0],[0.403,1.108],[0,0.504],[-2.014,4.532],[-2.618,2.216],[0,0],[2.216,-0.403],[6.042,-5.237],[0,0],[0,0],[0,0],[-1.208,3.525],[0,0],[-0.806,-2.921],[0,0],[0,0]],"v":[[0.906,-48.743],[18.933,-3.827],[19.537,-1.511],[18.832,0.604],[11.38,10.474],[3.625,14.804],[5.841,22.256],[16.718,16.516],[33.435,-13.998],[46.729,-48.743],[37.363,-48.743],[27.695,-20.142],[24.573,-9.97],[24.371,-9.97],[21.249,-19.94],[10.574,-48.743]],"c":true},"ix":2},"nm":"y","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"y","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"1","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[23.767,0],[32.327,0],[32.327,-65.46],[24.774,-65.46],[10.474,-57.806],[12.186,-51.059],[23.566,-57.202],[23.767,-57.202]],"c":true},"ix":2},"nm":"1","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"l","size":150,"style":"500","w":23.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[7.352,0],[16.214,0],[16.214,-71.503],[7.352,-71.503]],"c":true},"ix":2},"nm":"l","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"l","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/D Transforms_All_01_1920x1080.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/D Transforms_All_01_1920x1080.json deleted file mode 100644 index b1078dbe..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/D Transforms_All_01_1920x1080.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.18","fr":30,"ip":0,"op":66,"w":1920,"h":1080,"nm":"D Transforms_All_01","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[1924.5,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[483.75,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[964,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[1444.25,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[3.5,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":0,"s":[174.5,244,0],"e":[296.34,182,0],"to":[23.0368061065674,0,0],"ti":[-55.0616836547852,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":20,"s":[296.34,182,0],"e":[430.132,294.129,0],"to":[41.3462142944336,0,0],"ti":[-41.2537689208984,-13.1089372634888,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":40,"s":[430.132,294.129,0],"e":[575,244,0],"to":[54.448616027832,17.301778793335,0],"ti":[-22.8313579559326,0,0]},{"t":60}],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":0,"s":[174.5],"e":[368.34]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p667_1_0p167_0"],"t":20,"s":[368.34],"e":[368.34]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":40,"s":[368.34],"e":[575]},{"t":60}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":20,"s":[185],"e":[265.5]},{"t":40}],"ix":4}},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_3","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.246,0.246,0.667],"y":[1,1,1]},"o":{"x":[0.421,0.421,0.167],"y":[0.125,0.125,0]},"n":["0p246_1_0p421_0p125","0p246_1_0p421_0p125","0p667_1_0p167_0"],"t":0,"s":[50,50,100],"e":[75,75,100]},{"i":{"x":[0.441,0.441,0.667],"y":[1,1,1]},"o":{"x":[0.651,0.651,0.167],"y":[0,0,0]},"n":["0p441_1_0p651_0","0p441_1_0p651_0","0p667_1_0p167_0"],"t":20,"s":[75,75,100],"e":[35,35,100]},{"i":{"x":[0,0,0.667],"y":[1,1,1]},"o":{"x":[0.487,0.487,0.167],"y":[0,0,0]},"n":["0_1_0p487_0","0_1_0p487_0","0p667_1_0p167_0"],"t":40,"s":[35,35,100],"e":[50,50,100]},{"t":60}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_4","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.363],"y":[1]},"o":{"x":[0.717],"y":[0.463]},"n":["0p363_1_0p717_0p463"],"t":0,"s":[0],"e":[720]},{"t":60}],"ix":10},"p":{"a":0,"k":[375,241,0],"ix":2},"a":{"a":0,"k":[962,728,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_5","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[962,504,0],"e":[724,701,0],"to":[-39.6666679382324,32.8333320617676,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":15,"s":[724,701,0],"e":[962,504,0],"to":[0,0,0],"ti":[-78,50.8333320617676,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":30,"s":[962,504,0],"e":[1192,396,0],"to":[78,-50.8333320617676,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":45,"s":[1192,396,0],"e":[962,504,0],"to":[0,0,0],"ti":[38.3333320617676,-18,0]},{"t":60}],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_6","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0],"e":[100]},{"t":30}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_7","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.363],"y":[1]},"o":{"x":[0.717],"y":[0.463]},"n":["0p363_1_0p717_0p463"],"t":0,"s":[0],"e":[720]},{"t":60}],"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Rectantgle Outlines 2","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[730,278,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_8","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[139.2,378.1,0],"e":[585.6,82,0],"to":[-0.95211333036423,-289.677154541016,0],"ti":[2.61271214485168,258.688842773438,0]},{"t":60}],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[45,45,100],"ix":6}},"ao":1,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]}],"fonts":{"list":[{"fName":"SamsungOne-500","fFamily":"SamsungOne","fStyle":"500","ascent":70.9991455078125}]},"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"div","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":10,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":5,"nm":"D Transforms_01 Position","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[39.375,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"D Transforms_01 Position","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":67,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":5,"nm":"D Transforms_02 Position","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[519.5,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"D Transforms_02 Position","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":67,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":5,"nm":"D Transforms_03 Scale","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1000.375,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"D Transforms_03 Scale","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":67,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":5,"nm":"D Transforms_04 Rotation","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1480.5,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"D Transforms_04 Rotation","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":67,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":5,"nm":"D Transforms_05 Anchor Point","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[39.375,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"D Transforms_05 Anchor Point","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":67,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":5,"nm":"D Transforms_06 Opacity","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[519.5,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"D Transforms_06 Opacity","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":67,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":5,"nm":"D Transforms_07 Parenting","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1000.375,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"D Transforms_07 Parenting","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":67,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":5,"nm":"D Transforms_08 Auto Orient","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1480.5,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"D Transforms_08 Auto Orient","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":67,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"D Transforms_01 Position","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[248,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[70,70,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":0,"nm":"D Transforms_02 Position (separated X,Y)","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[726,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[70,70,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":0,"nm":"D Transforms_03 Scale","refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1204,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[70,70,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":0,"nm":"D Transforms_04 Rotation","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1678,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[70,70,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":0,"nm":"D Transforms_05 Anchor Point","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[248,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[70,70,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":0,"nm":"D Transforms_06 Opacity","refId":"comp_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[732,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[70,70,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":0,"nm":"D Transforms_07 Parenting","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1198,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[70,70,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":0,"nm":"D Transforms_08 Auto Orient","refId":"comp_8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1678,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[70,70,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0}],"markers":[],"chars":[{"ch":"D","size":150,"style":"500","w":66.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.244,0],[-6.345,6.345],[0,11.078],[6.042,5.539],[12.589,0],[5.338,-0.806]],"o":[[4.431,0.504],[13.193,0],[6.345,-6.244],[0,-10.977],[-5.942,-5.539],[-6.949,0],[0,0]],"v":[[7.654,-0.201],[23.566,0.604],[53.577,-9.164],[63.345,-35.55],[53.778,-59.921],[26.285,-68.381],[7.654,-66.971]],"c":true},"ix":2},"nm":"D","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-4.532,0],[0.101,-16.013],[18.732,0],[2.216,0.403]],"o":[[2.316,-0.504],[18.53,0],[0,18.329],[-3.424,0],[0,0]],"v":[[16.415,-60.526],[26.688,-61.432],[54.181,-35.248],[25.278,-6.445],[16.415,-6.949]],"c":true},"ix":2},"nm":"D","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"D","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":" ","size":150,"style":"500","w":21.2,"data":{},"fFamily":"SamsungOne"},{"ch":"T","size":150,"style":"500","w":53.5,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[20.544,0],[29.407,0],[29.407,-60.425],[50.153,-60.425],[50.153,-67.877],[-0.101,-67.877],[-0.101,-60.425],[20.544,-60.425]],"c":true},"ix":2},"nm":"T","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"T","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"r","size":150,"style":"500","w":33.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.201,1.208],[-6.244,0],[-0.906,-0.201],[0,0],[1.007,0],[2.216,-6.546],[0,0],[0,0],[0,0],[0,-5.74]],"o":[[0,0],[0,0],[0,-1.511],[1.208,-6.647],[1.208,0],[0,0],[-0.806,-0.201],[-5.942,0],[0,0],[0,0],[0,0],[0.302,4.532],[0,0]],"v":[[7.352,0],[16.113,0],[16.113,-25.983],[16.516,-30.112],[28.4,-41.492],[31.421,-41.19],[31.421,-49.548],[28.903,-49.85],[15.408,-39.175],[15.005,-39.175],[14.703,-48.743],[6.949,-48.743],[7.352,-33.536]],"c":true},"ix":2},"nm":"r","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"r","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"a","size":150,"style":"500","w":48.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,4.23],[0,0],[14.905,0],[4.028,-2.618],[0,0],[-4.532,0],[0,-4.028],[0,0],[0,-11.783],[-9.869,0],[-2.719,3.827],[0,0],[0,0]],"o":[[-0.604,-3.323],[0,0],[0,-9.769],[-6.143,0],[0,0],[3.424,-2.216],[9.97,0],[0,0],[-18.832,-0.101],[0,7.05],[6.949,0],[0,0],[0,0],[0,0]],"v":[[42.398,0],[41.592,-11.682],[41.592,-29.91],[23.062,-49.85],[7.05,-45.52],[9.064,-39.679],[21.753,-43.304],[32.831,-32.025],[32.831,-31.018],[3.525,-12.891],[18.43,1.108],[33.334,-6.143],[33.636,-6.143],[34.341,0]],"c":true},"ix":2},"nm":"a","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.302,-0.906],[6.345,0],[0,5.74],[-9.668,-0.201]],"o":[[0,0.906],[-1.41,4.129],[-4.532,0],[0,-9.467],[0,0]],"v":[[33.032,-16.415],[32.529,-13.596],[20.746,-5.438],[12.387,-13.898],[33.032,-24.875]],"c":true},"ix":2},"nm":"a","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"a","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"n","size":150,"style":"500","w":55.5,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.403,1.108],[-5.841,0],[0,-7.855],[0,0],[0,0],[0,0],[6.747,0],[2.417,-4.633],[0,0],[0,0],[0,0],[0,-5.035]],"o":[[0,0],[0,0],[0,-1.511],[1.511,-4.935],[8.359,0],[0,0],[0,0],[0,0],[0,-16.718],[-8.057,0],[0,0],[0,0],[0,0],[0.302,4.028],[0,0]],"v":[[7.352,0],[16.214,0],[16.214,-29.306],[16.818,-33.435],[28.702,-42.499],[39.981,-28.098],[39.981,0],[48.843,0],[48.843,-29.105],[31.622,-49.85],[15.509,-40.686],[15.308,-40.686],[14.804,-48.743],[6.949,-48.743],[7.352,-35.55]],"c":true},"ix":2},"nm":"n","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"n","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"s","size":150,"style":"500","w":39.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-5.338,0],[0,8.56],[8.459,3.223],[0,4.028],[-5.237,0],[-1.913,-1.208],[0,0],[4.935,0],[0,-7.855],[-8.762,-3.122],[0,-4.23],[6.445,0],[2.618,1.712]],"o":[[3.424,2.014],[11.581,0],[0,-7.251],[-6.345,-2.417],[0,-3.625],[4.532,0],[0,0],[-2.719,-1.611],[-10.474,0],[0,5.841],[6.546,2.417],[0,4.028],[-4.431,0],[0,0]],"v":[[3.928,-2.316],[17.624,1.007],[35.852,-13.596],[23.062,-28.299],[13.797,-36.557],[21.954,-43.204],[31.924,-40.384],[34.14,-46.829],[22.156,-49.85],[5.338,-35.55],[18.228,-21.753],[27.292,-12.79],[17.825,-5.539],[6.143,-9.064]],"c":true},"ix":2},"nm":"s","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"s","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"f","size":150,"style":"500","w":29.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-7.553,0],[-1.309,-0.604],[0,0],[3.122,0],[3.323,-3.223],[0,-6.848],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,-7.452],[2.518,0],[0,0],[-1.712,-0.705],[-4.129,0],[-4.129,3.928],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[17.02,0],[17.02,-41.995],[28.802,-41.995],[28.802,-48.743],[17.02,-48.743],[17.02,-51.361],[26.486,-65.46],[32.126,-64.352],[33.334,-71.201],[25.781,-72.61],[13.898,-68.079],[8.258,-51.059],[8.258,-48.743],[1.41,-48.743],[1.41,-41.995],[8.258,-41.995],[8.258,0]],"c":true},"ix":2},"nm":"f","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"f","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"o","size":150,"style":"500","w":54.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.998,0],[0,-16.315],[-13.193,0],[0,18.027]],"o":[[-13.495,0],[0,15.408],[11.783,0],[0,-14.905]],"v":[[27.997,-49.85],[3.827,-23.969],[27.191,1.108],[51.462,-24.774]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-10.474,0],[0,-8.258],[8.459,0],[0,10.675]],"o":[[10.474,0],[0,10.977],[-8.661,0],[0,-9.265]],"v":[[27.795,-43.204],[42.398,-24.472],[27.594,-5.539],[12.79,-24.271]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"o","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"m","size":150,"style":"500","w":83.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.504,1.309],[-5.539,0],[0,-7.755],[0,0],[0,0],[0,0],[-0.403,1.208],[-5.035,0],[0,-9.366],[0,0],[0,0],[0,0],[6.445,0],[2.921,-2.216],[1.511,-2.719],[0,0],[6.647,0],[2.719,-4.633],[0,0],[0,0],[0,0],[0,-5.035]],"o":[[0,0],[0,0],[0,-1.511],[1.41,-4.431],[6.747,0],[0,0],[0,0],[0,0],[0,-1.611],[1.511,-4.33],[7.15,0],[0,0],[0,0],[0,0],[0,-16.919],[-4.633,0],[-2.014,1.511],[0,0],[-2.115,-5.74],[-8.057,0],[0,0],[0,0],[0,0],[0.302,4.028],[0,0]],"v":[[7.352,0],[16.013,0],[16.013,-29.407],[16.718,-33.737],[27.695,-42.599],[37.866,-29.205],[37.866,0],[46.527,0],[46.527,-30.112],[47.232,-34.543],[57.706,-42.599],[68.28,-27.594],[68.28,0],[76.941,0],[76.941,-28.702],[60.928,-49.85],[50.153,-46.426],[44.714,-40.082],[44.513,-40.082],[30.716,-49.85],[15.408,-40.887],[15.106,-40.887],[14.703,-48.743],[6.949,-48.743],[7.352,-35.55]],"c":true},"ix":2},"nm":"m","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"m","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"_","size":150,"style":"500","w":50,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,7.553],[0,12.589],[50.354,12.589],[50.354,7.553]],"c":true},"ix":2},"nm":"_","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"_","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"0","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.797,0],[0,-21.954],[-12.79,0],[0,22.256]],"o":[[-13.293,0],[0.201,21.652],[14.502,0],[0,-20.847]],"v":[[26.385,-66.568],[3.625,-32.529],[25.278,1.108],[48.038,-33.435]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-7.755,0],[0,-16.113],[9.064,0],[0,17.02]],"o":[[9.164,0],[0,16.718],[-8.057,0],[0,-17.825]],"v":[[25.882,-59.72],[39.175,-33.032],[25.781,-5.74],[12.488,-32.428]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"0","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"8","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-13.696,0],[0,11.38],[8.157,3.223],[0,0],[0,5.539],[12.689,0],[0,-10.373],[-7.251,-3.424],[0,0],[0,-8.258]],"o":[[12.488,0],[0,-7.956],[0,0],[8.057,-3.827],[0,-8.157],[-11.481,0],[0,5.64],[0,0],[-8.057,3.424],[0,9.567]],"v":[[25.681,1.108],[47.937,-17.926],[34.744,-34.845],[34.744,-35.147],[45.52,-50.455],[26.486,-66.568],[6.244,-49.146],[16.617,-34.442],[16.718,-34.14],[3.726,-16.617]],"c":true},"ix":2},"nm":"8","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[7.956,0],[-0.302,6.647],[-7.654,2.216],[0,-7.956]],"o":[[-8.359,0],[0,-6.244],[8.862,2.518],[0,6.747]],"v":[[25.882,-5.338],[12.79,-17.825],[24.573,-31.32],[38.974,-17.02]],"c":true},"ix":2},"nm":"8","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-7.352,0],[0,-5.237],[5.64,-1.913],[0,6.546]],"o":[[7.956,0],[0,5.942],[-7.553,-2.014],[0,-5.64]],"v":[[25.983,-60.223],[37.061,-49.548],[27.09,-37.665],[14.603,-49.75]],"c":true},"ix":2},"nm":"8","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"8","np":6,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"A","size":150,"style":"500","w":61.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[42.7,-21.35],[49.951,0],[59.317,0],[36.154,-67.877],[25.58,-67.877],[2.518,0],[11.581,0],[18.631,-21.35]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-1.007,4.028],[0,0],[-1.511,-4.431],[0,0]],"o":[[0,0],[1.309,-4.129],[0,0],[1.007,3.928],[0,0],[0,0]],"v":[[20.444,-28.198],[27.09,-47.836],[30.515,-60.123],[30.716,-60.123],[34.241,-47.736],[40.887,-28.198]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"A","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"u","size":150,"style":"500","w":55.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0.504,-1.309],[5.942,0],[0,9.265],[0,0],[0,0],[0,0],[-7.654,0],[-2.316,3.928],[0,0],[0,0],[0,0],[0,5.035]],"o":[[0,0],[0,0],[0,1.611],[-1.611,3.928],[-8.057,0],[0,0],[0,0],[0,0],[0,17.12],[8.661,0],[0,0],[0,0],[0,0],[-0.302,-3.827],[0,0]],"v":[[48.138,-48.743],[39.276,-48.743],[39.276,-18.832],[38.47,-14.301],[26.788,-6.244],[15.912,-21.753],[15.912,-48.743],[7.05,-48.743],[7.05,-20.242],[23.868,1.108],[39.981,-7.956],[40.182,-7.956],[40.686,0],[48.541,0],[48.138,-13.293]],"c":true},"ix":2},"nm":"u","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"u","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"t","size":150,"style":"500","w":33.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-2.518,-2.618],[-4.129,0],[-1.712,0.705],[0,0],[2.316,0],[0,6.042],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,5.74],[2.115,2.417],[3.424,0],[0,0],[-1.108,0.302],[-4.935,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[9.366,-60.425],[9.366,-48.743],[1.813,-48.743],[1.813,-41.995],[9.366,-41.995],[9.366,-15.408],[12.79,-2.719],[22.357,1.007],[30.212,-0.201],[29.81,-6.848],[24.673,-6.244],[18.027,-15.71],[18.027,-41.995],[30.716,-41.995],[30.716,-48.743],[18.027,-48.743],[18.027,-62.741]],"c":true},"ix":2},"nm":"t","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"t","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"O","size":150,"style":"500","w":68.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[18.53,0],[0,-21.552],[-17.926,0],[0,23.364]],"o":[[-18.127,0],[0,20.544],[17.322,0],[0,-20.142]],"v":[[35.147,-68.985],[3.625,-33.334],[34.14,1.108],[65.662,-34.644]],"c":true},"ix":2},"nm":"O","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-14.502,0],[0,-13.495],[13.898,0],[0,14.502]],"o":[[14.603,0],[0,15.408],[-13.797,0],[0,-14.905]],"v":[[34.744,-61.835],[56.396,-34.241],[34.644,-6.042],[12.991,-33.536]],"c":true},"ix":2},"nm":"O","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"O","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"i","size":150,"style":"500","w":23.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16.214,0],[16.214,-48.743],[7.352,-48.743],[7.352,0]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[3.323,0],[0,-3.122],[-3.122,0],[0.101,3.021]],"o":[[-3.223,0],[0,3.021],[3.525,0],[0,-3.122]],"v":[[11.783,-67.978],[6.244,-62.439],[11.581,-57.001],[17.221,-62.439]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"i","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"e","size":150,"style":"500","w":50.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,1.813],[15.912,0],[0,-14.703],[-15.005,0],[-3.122,1.41],[0,0],[6.345,0],[0.201,11.984]],"o":[[0.101,-0.906],[0,-8.963],[-14.2,0],[0,14.703],[7.755,0],[0,0],[-3.323,1.41],[-8.862,0],[0,0]],"v":[[46.527,-22.76],[46.829,-26.889],[26.688,-49.85],[3.827,-23.566],[27.795,1.007],[44.009,-2.014],[42.499,-8.359],[29.004,-5.841],[12.286,-22.76]],"c":true},"ix":2},"nm":"e","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-8.963,0],[0.101,-5.64]],"o":[[0.705,-6.143],[9.97,0],[0,0]],"v":[[12.387,-29.105],[25.983,-43.506],[38.269,-29.105]],"c":true},"ix":2},"nm":"e","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"e","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"7","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[5.74,-65.46],[5.74,-58.109],[37.766,-58.109],[37.766,-57.907],[9.366,0],[18.53,0],[47.031,-59.619],[47.031,-65.46]],"c":true},"ix":2},"nm":"7","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"7","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"P","size":150,"style":"500","w":53.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-2.618,0],[-4.633,4.935],[0,6.143],[3.726,3.223],[8.661,0],[4.23,-0.705]],"o":[[0,0],[0,0],[2.014,0.504],[8.56,0],[3.424,-3.525],[0,-6.042],[-4.028,-3.625],[-7.05,0],[0,0]],"v":[[7.654,0],[16.415,0],[16.415,-27.191],[23.465,-26.587],[44.211,-34.039],[49.448,-48.541],[43.506,-62.741],[24.472,-68.381],[7.654,-67.072]],"c":true},"ix":2},"nm":"P","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-3.827,0],[0,-8.963],[10.574,0],[1.913,0.504]],"o":[[1.511,-0.403],[9.668,0],[0,9.366],[-2.921,0],[0,0]],"v":[[16.415,-60.727],[24.673,-61.432],[40.686,-48.138],[23.666,-33.636],[16.415,-34.341]],"c":true},"ix":2},"nm":"P","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"P","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"g","size":150,"style":"500","w":55.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[8.459,0],[0,-16.516],[-12.085,0],[-2.719,4.532],[0,0],[0,0],[9.064,0],[3.223,2.014],[0,0],[-5.841,0],[-4.733,4.431],[0,11.179],[0,0],[-0.201,3.525]],"o":[[0,0],[0,0],[-2.115,-4.028],[-11.179,0],[0,13.495],[7.553,0],[0,0],[0,0],[0,12.286],[-6.042,0],[0,0],[3.928,2.618],[6.143,0],[4.733,-4.23],[0,0],[0,-5.942],[0,0]],"v":[[41.592,-48.743],[41.19,-41.391],[40.988,-41.391],[25.781,-49.85],[3.827,-23.969],[24.573,-0.201],[40.082,-8.359],[40.283,-8.359],[40.283,-2.921],[24.573,14.099],[10.272,10.272],[8.057,17.02],[24.271,21.048],[41.995,15.207],[48.944,-7.05],[48.944,-35.349],[49.347,-48.743]],"c":true},"ix":2},"nm":"g","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.504,-1.511],[5.438,0],[0,9.567],[-8.459,0],[-1.611,-5.136],[0,-1.511]],"o":[[0,1.511],[-1.913,5.64],[-9.567,0],[0,-11.279],[6.445,0],[0.403,1.208],[0,0]],"v":[[40.182,-20.746],[39.478,-16.013],[27.191,-6.949],[12.79,-24.472],[27.292,-42.902],[39.679,-33.536],[40.182,-29.507]],"c":true},"ix":2},"nm":"g","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"g","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"6","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[2.618,-0.403],[5.438,-5.338],[0,-12.891],[-13.998,0],[0,11.984],[11.581,0],[3.122,-4.129],[0,0],[-13.898,2.316],[-1.813,-0.101]],"o":[[-1.611,0],[-8.258,1.007],[-6.445,6.445],[0,17.02],[13.596,0],[0,-12.79],[-7.251,0],[0,0],[1.511,-10.776],[2.518,-0.403],[0,0]],"v":[[41.895,-66.467],[35.449,-65.964],[14.502,-56.296],[3.424,-26.788],[26.587,1.108],[48.34,-21.954],[28.601,-43.103],[12.79,-35.55],[12.488,-35.55],[35.248,-58.813],[41.895,-59.216]],"c":true},"ix":2},"nm":"6","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[7.654,0],[0.201,10.776],[-0.604,1.007],[-5.338,0],[0,-9.366]],"o":[[-9.265,0],[0,-1.611],[2.417,-4.733],[8.157,0],[0,9.366]],"v":[[26.587,-5.74],[12.186,-24.472],[13.193,-28.4],[25.882,-36.456],[39.377,-21.451]],"c":true},"ix":2},"nm":"6","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"6","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"p","size":150,"style":"500","w":56.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-6.445,0],[0,17.523],[11.783,0],[3.625,-5.942],[0,0],[0,0],[0,0],[0,-6.244]],"o":[[0,0],[0,0],[0,0],[2.921,4.834],[11.481,0],[0,-14.804],[-7.956,0],[0,0],[0,0],[0,0],[0.201,4.633],[0,0]],"v":[[7.352,19.94],[16.113,19.94],[16.113,-6.546],[16.315,-6.546],[31.32,1.108],[53.476,-25.076],[32.831,-49.85],[15.509,-40.384],[15.308,-40.384],[14.905,-48.743],[6.949,-48.743],[7.352,-32.831]],"c":true},"ix":2},"nm":"p","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-0.302,1.108],[-6.042,0],[0,-9.769],[9.366,0],[1.611,6.143],[0,1.309]],"o":[[0,-1.208],[1.712,-6.647],[9.366,0],[0,11.179],[-6.345,0],[-0.201,-1.108],[0,0]],"v":[[16.113,-28.198],[16.718,-31.824],[30.112,-42.801],[44.614,-24.673],[29.81,-5.841],[16.516,-16.214],[16.113,-19.839]],"c":true},"ix":2},"nm":"p","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"p","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"c","size":150,"style":"500","w":44.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[5.035,0],[0,11.279],[-11.179,0],[-2.115,-1.208],[0,0],[5.237,0],[0,-15.005],[-14.703,0],[-2.316,1.208]],"o":[[-2.518,1.108],[-9.668,0],[0,-10.172],[4.834,0],[0,0],[-2.417,-1.208],[-15.912,0],[0,14.905],[6.546,0],[0,0]],"v":[[40.585,-8.459],[29.709,-6.042],[12.79,-24.271],[30.011,-42.7],[40.283,-40.384],[42.297,-47.232],[30.011,-49.75],[3.827,-23.868],[28.098,1.007],[42.096,-1.813]],"c":true},"ix":2},"nm":"c","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"c","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"y","size":150,"style":"500","w":48.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,-0.504],[0.403,-0.906],[2.417,-1.913],[2.216,-0.705],[0,0],[-4.33,3.827],[-6.345,16.718],[0,0],[0,0],[0,0],[0.906,-2.921],[0,0],[1.108,3.223],[0,0]],"o":[[0,0],[0.403,1.108],[0,0.504],[-2.014,4.532],[-2.618,2.216],[0,0],[2.216,-0.403],[6.042,-5.237],[0,0],[0,0],[0,0],[-1.208,3.525],[0,0],[-0.806,-2.921],[0,0],[0,0]],"v":[[0.906,-48.743],[18.933,-3.827],[19.537,-1.511],[18.832,0.604],[11.38,10.474],[3.625,14.804],[5.841,22.256],[16.718,16.516],[33.435,-13.998],[46.729,-48.743],[37.363,-48.743],[27.695,-20.142],[24.573,-9.97],[24.371,-9.97],[21.249,-19.94],[10.574,-48.743]],"c":true},"ix":2},"nm":"y","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"y","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"5","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-3.726,0],[-0.101,-8.459],[8.359,0],[2.719,1.611],[0,0],[-7.15,0],[0,12.79],[5.136,2.921],[5.035,0],[1.511,-0.201],[0,0],[0,0]],"o":[[0,0],[0,0],[2.417,-0.302],[13.092,0],[0,8.762],[-5.942,0],[0,0],[3.122,2.014],[14.2,0],[0,-8.258],[-4.028,-2.417],[-2.417,0],[0,0],[0,0],[0,0]],"v":[[43.607,-65.46],[12.286,-65.46],[8.057,-34.039],[17.12,-34.744],[35.953,-20.242],[20.444,-6.042],[6.445,-9.668],[4.23,-2.921],[20.544,1.108],[44.916,-21.249],[35.55,-38.068],[21.451,-41.592],[16.113,-41.19],[18.631,-58.008],[43.607,-58.008]],"c":true},"ix":2},"nm":"5","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"5","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"h","size":150,"style":"500","w":55.5,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.504,1.208],[-5.74,0],[0,-7.855],[0,0],[0,0],[0,0],[6.546,0],[2.618,-1.511],[1.41,-2.518],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,-1.712],[1.611,-4.834],[8.359,0],[0,0],[0,0],[0,0],[0,-16.818],[-3.323,0],[-2.719,1.511],[0,0],[0,0],[0,0],[0,0]],"v":[[7.352,0],[16.214,0],[16.214,-29.407],[16.818,-33.636],[28.702,-42.499],[39.981,-27.997],[39.981,0],[48.843,0],[48.843,-29.004],[31.824,-49.85],[22.76,-47.333],[16.415,-41.089],[16.214,-41.089],[16.214,-71.503],[7.352,-71.503]],"c":true},"ix":2},"nm":"h","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"h","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"4","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[40.283,0],[40.283,-17.825],[49.448,-17.825],[49.448,-24.774],[40.283,-24.774],[40.283,-65.46],[30.716,-65.46],[1.511,-23.666],[1.511,-17.825],[31.924,-17.825],[31.924,0]],"c":true},"ix":2},"nm":"4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-2.014,3.827],[0,0],[0,-3.424],[0,0]],"o":[[0,0],[0,0],[1.813,-3.021],[0,0],[-0.201,3.424],[0,0],[0,0]],"v":[[10.474,-24.774],[10.474,-24.976],[26.486,-47.232],[31.924,-56.9],[32.227,-56.9],[31.924,-46.628],[31.924,-24.774]],"c":true},"ix":2},"nm":"4","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"4","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"R","size":150,"style":"500","w":53.8,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-2.014,-9.366],[-1.108,-1.913],[0,0],[2.216,9.467],[5.237,1.813],[0,0],[0,8.963],[3.424,3.021],[9.366,0],[4.431,-0.906]],"o":[[0,0],[0,0],[0,0],[7.956,0.302],[1.913,8.459],[0,0],[-1.41,-2.618],[-1.611,-7.05],[0,0],[7.15,-2.417],[0,-5.237],[-4.23,-3.827],[-6.042,0],[0,0]],"v":[[7.654,0],[16.415,0],[16.415,-29.407],[24.673,-29.407],[38.269,-16.214],[42.801,0],[51.865,0],[46.628,-18.631],[36.658,-32.327],[36.658,-32.629],[49.448,-49.951],[44.11,-62.842],[24.472,-68.381],[7.654,-66.971]],"c":true},"ix":2},"nm":"R","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-4.23,0],[0,-8.762],[9.366,0],[0,0]],"o":[[1.41,-0.403],[9.265,0.101],[0,7.755],[0,0],[0,0]],"v":[[16.415,-60.828],[25.076,-61.633],[40.686,-48.944],[25.378,-36.053],[16.415,-36.053]],"c":true},"ix":2},"nm":"R","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"R","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"3","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-7.352,0],[0,10.474],[8.057,1.611],[0,0],[0,6.747],[12.891,0],[3.424,-2.518],[0,0],[-5.237,0],[0,-5.237],[6.445,0],[0,0],[0,0],[0,0],[-0.101,-9.164],[11.38,0],[2.518,1.611]],"o":[[3.223,2.115],[15.71,0],[0,-9.164],[0,0],[8.057,-2.921],[0,-7.956],[-7.05,0],[0,0],[2.82,-2.014],[8.157,0],[0,7.755],[0,0],[0,0],[0,0],[8.56,0],[0.101,5.438],[-6.143,0],[0,0]],"v":[[4.23,-3.323],[21.249,1.108],[45.117,-18.53],[30.515,-35.349],[30.515,-35.55],[42.599,-50.958],[23.868,-66.568],[6.747,-61.533],[9.064,-55.087],[22.156,-59.418],[33.636,-49.548],[19.034,-38.47],[14.099,-38.47],[14.099,-31.824],[19.034,-31.824],[35.953,-18.732],[21.149,-6.042],[6.647,-10.172]],"c":true},"ix":2},"nm":"3","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"3","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"S","size":150,"style":"500","w":49.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.546,0],[0,10.474],[11.481,4.431],[0,6.345],[-9.265,0],[-2.216,-1.208],[0,0],[6.949,0],[0,-10.574],[-11.078,-3.928],[0,-6.345],[8.963,0],[3.928,2.417]],"o":[[3.625,2.417],[16.013,0],[0,-9.97],[-9.366,-3.625],[0,-4.633],[6.143,0],[0,0],[-3.021,-1.712],[-13.193,0],[0,9.567],[9.164,3.525],[0,6.848],[-6.042,0],[0,0]],"v":[[4.23,-3.323],[21.552,1.007],[45.319,-18.53],[27.997,-38.47],[14.502,-51.562],[27.292,-61.734],[40.182,-58.511],[42.599,-65.662],[27.594,-68.985],[5.64,-50.555],[23.566,-31.32],[36.356,-17.825],[22.156,-6.244],[6.445,-10.675]],"c":true},"ix":2},"nm":"S","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"S","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"l","size":150,"style":"500","w":23.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[7.352,0],[16.214,0],[16.214,-71.503],[7.352,-71.503]],"c":true},"ix":2},"nm":"l","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"l","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"2","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,12.085],[14.099,0],[4.532,-3.827],[0,0],[-5.942,0],[0,-6.647],[16.718,-15.912],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[13.797,-13.293],[0,-9.366],[-7.553,0],[0,0],[3.021,-2.518],[9.769,0],[-0.101,9.869],[0,0],[0,0],[0,0]],"v":[[46.326,0],[46.326,-7.352],[16.919,-7.352],[16.919,-7.553],[22.156,-12.387],[44.714,-47.534],[24.673,-66.568],[6.143,-59.921],[8.963,-53.677],[22.861,-59.216],[35.852,-46.426],[11.481,-12.186],[4.532,-5.438],[4.532,0]],"c":true},"ix":2},"nm":"2","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"1","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[23.767,0],[32.327,0],[32.327,-65.46],[24.774,-65.46],[10.474,-57.806],[12.186,-51.059],[23.566,-57.202],[23.767,-57.202]],"c":true},"ix":2},"nm":"1","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/E Interpolation_All_01_1920x1080.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/E Interpolation_All_01_1920x1080.json deleted file mode 100644 index 46cabbe1..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/E Interpolation_All_01_1920x1080.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.18","fr":30,"ip":0,"op":41,"w":1920,"h":1080,"nm":"E Interpolation_All_01","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[1924.5,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[643.833,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[1284.167,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[3.5,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"01 Linear Interpolation","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[111,244,0],"e":[639,244,0],"to":[88,0,0],"ti":[-88,0,0]},{"t":35}],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"02 Bezier Interpolation","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.119,"y":1},"o":{"x":0.341,"y":0.896},"n":"0p119_1_0p341_0p896","t":0,"s":[111,244,0],"e":[639,244,0],"to":[0,0,0],"ti":[0,0,0]},{"t":35}],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_3","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"03 Hold Interpolation","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"t":0,"s":[111,244,0],"h":1},{"t":35,"s":[639,244,0],"h":1}],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_4","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"04 Spatial Bezier Interpolation","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.119,"y":1},"o":{"x":0.341,"y":0.888},"n":"0p119_1_0p341_0p888","t":0,"s":[111,244,0],"e":[639,244,0],"to":[87.1999969482422,-42.4000015258789,0],"ti":[-118.400001525879,55.2000007629395,0]},{"t":35}],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_5","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"05 Rove Across Time","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.395,"y":0.334},"o":{"x":0.501,"y":0.701},"n":"0p395_0p334_0p501_0p701","t":0,"s":[111,244,0],"e":[572.148,244,0],"to":[72.73828125,0,0],"ti":[-135.300979614258,0,0]},{"i":{"x":0.532,"y":1},"o":{"x":0.115,"y":1},"n":"0p532_1_0p115_1","t":16.283,"s":[572.148,244,0],"e":[639,244,0],"to":[28.3884334564209,0,0],"ti":[-15.2617216110229,0,0]},{"t":35}],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0]],"o":[[0,0]],"v":[[2448.799,1789]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.054901998183,0.631372967888,0.901961023667,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"div","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":10,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"E Interpolation_01 Linear Interpolation","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[324.499,163.512,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[72.458,72.458,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.849,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.536,0.498],[1.035,0],[0.624,-0.243],[0.625,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.85,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.741,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.705],[5.914,-3.031],[5.914,8.036],[3.543,8.036],[3.543,-2.826],[2.739,-5.006],[0.381,-5.753],[-1.668,-5.388],[-3.542,-4.26],[-3.542,8.036],[-5.913,8.036],[-5.913,-7.656],[-3.717,-7.656],[-3.717,-5.929],[1.084,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1124.737,391.907],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.693,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.693,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.693,-1.035],[-1.366,0],[-0.693,1.034],[0,2.011],[0.692,1.024],[1.347,0]],"v":[[3.06,4.552],[4.099,0],[3.06,-4.537],[0.03,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[0,6.09]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.109,0],[-1.133,-1.396],[0,-2.693],[1.131,-1.405],[2.108,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.142,-1.396],[2.088,0],[1.131,1.395],[0,2.675],[-1.133,1.405],[-2.108,0]],"v":[[-4.86,6.134],[-6.557,0],[-4.845,-6.133],[0.03,-8.227],[4.86,-6.133],[6.557,0],[4.86,6.119],[0,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1106.702,392.097],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.172,-4.831],[1.2,-4.831],[1.2,10.861],[-1.172,10.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.284,0.293],[0,0.527],[-0.283,0.293],[-0.526,0],[-0.283,-0.293],[0,-0.507],[0.282,-0.293],[0.528,0]],"o":[[-0.283,-0.293],[0,-0.527],[0.284,-0.293],[0.528,0],[0.282,0.293],[0,0.547],[-0.283,0.293],[-0.526,0]],"v":[[-1.216,-7.963],[-1.639,-9.193],[-1.216,-10.422],[-0.001,-10.861],[1.215,-10.422],[1.639,-9.222],[1.215,-7.963],[-0.001,-7.524]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1093.321,389.081],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":4,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.468,-0.547],[-0.977,0],[-0.547,0.176],[0,0],[0.878,0]],"o":[[-0.82,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.469,0.546],[0.526,0],[0,0],[-0.721,0.235],[-1.601,0]],"v":[[-1.067,8.958],[-2.297,5.079],[-2.297,-3.616],[-4.962,-3.616],[-4.962,-5.637],[-2.297,-5.637],[-2.297,-10.262],[0.075,-10.262],[0.075,-5.637],[4.758,-5.637],[4.758,-3.616],[0.075,-3.616],[0.075,4.728],[0.777,7.304],[2.944,8.124],[4.554,7.861],[4.963,9.91],[2.563,10.262]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1082.384,389.887],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.653,0.303],[-0.566,0.625],[0,0],[1.142,-0.547],[0,-1.171],[-0.517,-0.458],[-1.014,0]],"o":[[0.654,-0.302],[0,0],[-2.439,0.02],[-1.142,0.547],[0,0.898],[0.517,0.459],[0.8,0]],"v":[[1.727,5.606],[3.557,4.215],[3.557,-0.087],[-1.816,0.762],[-3.528,3.337],[-2.752,5.373],[-0.454,6.061]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-0.849],[0,-1.64],[0,0],[0,0],[0,0],[2.128,0],[0.859,0.82],[0,1.483],[-1.522,0.878],[-3.26,0.02],[0,0],[0.614,0.507],[1.191,0],[1.151,-0.546],[0,0],[-1.639,0]],"o":[[1.034,0.849],[0,0],[0,0],[0,0],[-1.015,1.542],[-1.562,0],[-0.859,-0.819],[0,-1.874],[1.523,-0.879],[0,0],[0,-0.975],[-0.615,-0.508],[-1.307,0],[0,0],[1.424,-0.721],[1.717,0]],"v":[[4.348,-6.923],[5.9,-3.191],[5.9,7.876],[3.733,7.876],[3.733,5.884],[-0.981,8.197],[-4.611,6.967],[-5.9,3.514],[-3.616,-0.614],[3.557,-1.962],[3.557,-2.986],[2.635,-5.21],[-0.073,-5.973],[-3.762,-5.152],[-4.377,-7.114],[0.219,-8.197]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1067.159,392.067],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":4,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,2.323],[0,0],[0,0],[0,0],[-0.254,-0.243],[-0.547,0],[-0.409,0.079],[0,0],[0.644,0]],"o":[[0,0],[0,0],[0,0],[0,0.547],[0.253,0.245],[0.352,0],[0,0],[-0.625,0.156],[-2.283,0]],"v":[[-2.664,7.875],[-2.664,-11.359],[-0.293,-11.359],[-0.293,7.671],[0.088,8.856],[1.288,9.223],[2.43,9.104],[2.664,11.125],[0.761,11.359]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1054.993,388.759],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.09]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1040.265,392.097],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":4,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.653,0.995],[0,1.971],[0.684,1.025],[1.347,0],[0.594,-0.293],[0.546,-0.625],[0,0],[-0.674,-0.302],[-0.741,0]],"o":[[0.654,-0.996],[0,-1.991],[-0.683,-1.024],[-0.723,0],[-0.596,0.293],[0,0],[0.488,0.546],[0.673,0.303],[1.289,0]],"v":[[2.854,1.727],[3.835,-2.723],[2.81,-7.247],[-0.234,-8.783],[-2.21,-8.344],[-3.923,-6.967],[-3.923,1.493],[-2.181,2.766],[-0.059,3.22]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-1.464],[0,-2.616],[1.083,-1.435],[1.952,0],[0.693,0.312],[0.488,0.566],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.761,0.409],[-0.956,0]],"o":[[1.034,1.464],[0,2.557],[-1.083,1.434],[-0.82,0],[-0.693,-0.312],[0,0],[0,0],[0,0],[0,0],[0,0],[0.527,-0.8],[0.761,-0.41],[1.854,0]],"v":[[4.743,-8.871],[6.294,-2.751],[4.669,3.236],[0.117,5.387],[-2.152,4.918],[-3.923,3.601],[-3.923,11.066],[-6.294,11.066],[-6.294,-10.686],[-4.099,-10.686],[-4.099,-8.637],[-2.167,-10.452],[0.41,-11.066]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1022.932,394.936],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":4,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.585,-0.253],[0,0],[0.605,0],[0.555,-0.312],[0.448,-0.663],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.717,0]],"o":[[0,0],[-0.743,-0.214],[-0.742,0],[-0.557,0.313],[0,0],[0,0],[0,0],[0,0],[0,0],[1.113,-1.678],[0.703,0]],"v":[[4.187,-7.627],[3.661,-5.314],[1.639,-5.636],[-0.307,-5.168],[-1.815,-3.704],[-1.815,8.007],[-4.187,8.007],[-4.187,-7.686],[-1.99,-7.686],[-1.99,-5.49],[2.255,-8.007]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1007.823,391.936],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":2,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.273,-3.221],[0,0],[0.703,0.849],[1.229,0]],"o":[[0,0],[-0.019,-1.522],[-0.702,-0.849],[-2.401,0]],"v":[[-3.967,-1.245],[4.024,-1.245],[2.942,-4.801],[0.044,-6.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.078,-0.331],[0,0],[-0.811,-0.888],[-1.484,0],[-1.211,0.781],[0,0],[0.887,-0.264],[0.975,0],[1.24,1.444],[0,2.576],[-1.142,1.444],[-2.069,0],[-1.113,-1.327],[0,-2.38]],"o":[[0,0],[0.078,1.757],[0.809,0.889],[1.464,0],[0,0],[-0.625,0.488],[-0.889,0.264],[-2.226,0],[-1.239,-1.444],[0,-2.596],[1.143,-1.445],[1.992,0],[1.112,1.328],[0,0.567]],"v":[[6.308,0.687],[-3.997,0.687],[-2.664,4.655],[0.776,5.986],[4.786,4.816],[5.693,6.689],[3.425,7.816],[0.63,8.212],[-4.568,6.046],[-6.427,0.014],[-4.714,-6.046],[0.102,-8.212],[4.758,-6.222],[6.427,-0.66]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[991.823,392.082],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10","np":4,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.468,-0.547],[-0.977,0],[-0.547,0.176],[0,0],[0.878,0]],"o":[[-0.82,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.469,0.546],[0.526,0],[0,0],[-0.721,0.235],[-1.601,0]],"v":[[-1.068,8.958],[-2.298,5.079],[-2.298,-3.616],[-4.963,-3.616],[-4.963,-5.637],[-2.298,-5.637],[-2.298,-10.262],[0.074,-10.262],[0.074,-5.637],[4.757,-5.637],[4.757,-3.616],[0.074,-3.616],[0.074,4.728],[0.776,7.304],[2.943,8.124],[4.553,7.861],[4.962,9.91],[2.562,10.262]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[976.83,389.887],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11","np":2,"cix":2,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.85,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.537,0.498],[1.034,0],[0.625,-0.243],[0.624,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.849,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.742,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.705],[5.914,-3.031],[5.914,8.036],[3.543,8.036],[3.543,-2.826],[2.738,-5.006],[0.381,-5.753],[-1.669,-5.388],[-3.542,-4.26],[-3.542,8.036],[-5.914,8.036],[-5.914,-7.656],[-3.717,-7.656],[-3.717,-5.929],[1.083,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[961.532,391.907],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12","np":2,"cix":2,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.216,-10.598],[1.216,-10.598],[1.216,10.598],[-1.216,10.598]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[947.581,389.344],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":2,"cix":2,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.586,-0.253],[0,0],[0.605,0],[0.556,-0.312],[0.449,-0.663],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.717,0]],"o":[[0,0],[-0.742,-0.214],[-0.742,0],[-0.556,0.313],[0,0],[0,0],[0,0],[0,0],[0,0],[1.114,-1.678],[0.704,0]],"v":[[4.187,-7.627],[3.659,-5.314],[1.639,-5.636],[-0.307,-5.168],[-1.815,-3.704],[-1.815,8.007],[-4.187,8.007],[-4.187,-7.686],[-1.992,-7.686],[-1.992,-5.49],[2.253,-8.007]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[929.411,391.936],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 14","np":2,"cix":2,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.654,0.303],[-0.566,0.625],[0,0],[1.143,-0.547],[0,-1.171],[-0.518,-0.458],[-1.015,0]],"o":[[0.653,-0.302],[0,0],[-2.44,0.02],[-1.142,0.547],[0,0.898],[0.516,0.459],[0.8,0]],"v":[[1.727,5.606],[3.557,4.215],[3.557,-0.087],[-1.816,0.762],[-3.528,3.337],[-2.752,5.373],[-0.454,6.061]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.034,-0.849],[0,-1.64],[0,0],[0,0],[0,0],[2.127,0],[0.86,0.82],[0,1.483],[-1.522,0.878],[-3.26,0.02],[0,0],[0.615,0.507],[1.191,0],[1.151,-0.546],[0,0],[-1.639,0]],"o":[[1.034,0.849],[0,0],[0,0],[0,0],[-1.016,1.542],[-1.562,0],[-0.858,-0.819],[0,-1.874],[1.523,-0.879],[0,0],[0,-0.975],[-0.614,-0.508],[-1.307,0],[0,0],[1.424,-0.721],[1.718,0]],"v":[[4.347,-6.923],[5.899,-3.191],[5.899,7.876],[3.733,7.876],[3.733,5.884],[-0.981,8.197],[-4.612,6.967],[-5.9,3.514],[-3.616,-0.614],[3.557,-1.962],[3.557,-2.986],[2.634,-5.21],[-0.074,-5.973],[-3.762,-5.152],[-4.377,-7.114],[0.219,-8.197]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[912.883,392.067],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 15","np":4,"cix":2,"ix":15,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.273,-3.221],[0,0],[0.702,0.849],[1.229,0]],"o":[[0,0],[-0.019,-1.522],[-0.703,-0.849],[-2.402,0]],"v":[[-3.967,-1.245],[4.026,-1.245],[2.943,-4.801],[0.044,-6.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.078,-0.331],[0,0],[-0.81,-0.888],[-1.483,0],[-1.21,0.781],[0,0],[0.887,-0.264],[0.975,0],[1.24,1.444],[0,2.576],[-1.142,1.444],[-2.069,0],[-1.113,-1.327],[0,-2.38]],"o":[[0,0],[0.078,1.757],[0.81,0.889],[1.464,0],[0,0],[-0.625,0.488],[-0.889,0.264],[-2.225,0],[-1.24,-1.444],[0,-2.596],[1.142,-1.445],[1.991,0],[1.112,1.328],[0,0.567]],"v":[[6.308,0.687],[-3.997,0.687],[-2.664,4.655],[0.776,5.986],[4.786,4.816],[5.695,6.689],[3.425,7.816],[0.63,8.212],[-4.568,6.046],[-6.427,0.014],[-4.714,-6.046],[0.102,-8.212],[4.758,-6.222],[6.427,-0.66]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[896.603,392.082],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 16","np":4,"cix":2,"ix":16,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.849,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.536,0.498],[1.035,0],[0.624,-0.243],[0.625,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.85,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.741,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.705],[5.914,-3.031],[5.914,8.036],[3.543,8.036],[3.543,-2.826],[2.739,-5.006],[0.381,-5.753],[-1.668,-5.388],[-3.542,-4.26],[-3.542,8.036],[-5.913,8.036],[-5.913,-7.656],[-3.717,-7.656],[-3.717,-5.929],[1.084,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[878.903,391.907],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 17","np":2,"cix":2,"ix":17,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.171,-4.831],[1.2,-4.831],[1.2,10.861],[-1.171,10.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.282,0.293],[0,0.527],[-0.283,0.293],[-0.527,0],[-0.283,-0.293],[0,-0.507],[0.283,-0.293],[0.527,0]],"o":[[-0.283,-0.293],[0,-0.527],[0.282,-0.293],[0.527,0],[0.283,0.293],[0,0.547],[-0.283,0.293],[-0.527,0]],"v":[[-1.215,-7.963],[-1.64,-9.193],[-1.215,-10.422],[0,-10.861],[1.215,-10.422],[1.64,-9.222],[1.215,-7.963],[0,-7.524]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[865.084,389.081],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 18","np":4,"cix":2,"ix":18,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[5.899,8.373],[5.899,10.598],[-5.899,10.598],[-5.899,-10.598],[-3.469,-10.598],[-3.469,8.373]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[853.093,389.345],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 19","np":2,"cix":2,"ix":19,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[4.01,-10.598],[4.01,10.598],[1.61,10.598],[1.61,-7.963],[-3.309,-6.265],[-4.011,-8.314],[1.96,-10.598]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[826.99,389.345],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 20","np":2,"cix":2,"ix":20,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.742,1.425],[0,3.025],[0.741,1.425],[1.581,0],[0.741,-1.425],[0,-3.025],[-0.743,-1.425],[-1.581,0]],"o":[[0.741,-1.425],[0,-3.025],[-0.742,-1.425],[-1.562,0],[-0.743,1.425],[0,3.025],[0.741,1.425],[1.561,0]],"v":[[3.47,6.675],[4.582,0],[3.47,-6.674],[-0.014,-8.812],[-3.469,-6.674],[-4.581,0],[-3.469,6.675],[0.015,8.813]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.171,1.786],[0,3.747],[-1.161,1.786],[-2.381,0],[-1.172,-1.786],[0,-3.748],[1.161,-1.786],[2.381,0]],"o":[[-1.171,-1.786],[0,-3.748],[1.161,-1.786],[2.38,0],[1.171,1.786],[0,3.747],[-1.162,1.786],[-2.381,0]],"v":[[-5.313,8.3],[-7.07,0],[-5.328,-8.299],[-0.014,-10.979],[5.315,-8.299],[7.07,0],[5.328,8.3],[0.015,10.979]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[811.516,389.344],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 21","np":4,"cix":2,"ix":21,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-5.958,-1.112],[5.958,-1.112],[5.958,1.112],[-5.958,1.112]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[792.338,403.193],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 22","np":2,"cix":2,"ix":22,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.849,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.536,0.498],[1.035,0],[0.624,-0.243],[0.625,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.85,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.741,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.705],[5.913,-3.031],[5.913,8.036],[3.542,8.036],[3.542,-2.826],[2.738,-5.006],[0.38,-5.753],[-1.669,-5.388],[-3.543,-4.26],[-3.543,8.036],[-5.914,8.036],[-5.914,-7.656],[-3.718,-7.656],[-3.718,-5.929],[1.083,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[773.848,391.907],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 23","np":2,"cix":2,"ix":23,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.09]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[755.812,392.097],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 24","np":4,"cix":2,"ix":24,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.171,-4.831],[1.201,-4.831],[1.201,10.861],[-1.171,10.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.283,0.293],[0,0.527],[-0.283,0.293],[-0.527,0],[-0.283,-0.293],[0,-0.507],[0.283,-0.293],[0.527,0]],"o":[[-0.283,-0.293],[0,-0.527],[0.283,-0.293],[0.527,0],[0.283,0.293],[0,0.547],[-0.283,0.293],[-0.527,0]],"v":[[-1.215,-7.963],[-1.639,-9.193],[-1.215,-10.422],[0,-10.861],[1.215,-10.422],[1.639,-9.222],[1.215,-7.963],[0,-7.524]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[742.431,389.081],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 25","np":4,"cix":2,"ix":25,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.469,-0.547],[-0.976,0],[-0.547,0.176],[0,0],[0.879,0]],"o":[[-0.819,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.468,0.546],[0.527,0],[0,0],[-0.722,0.235],[-1.601,0]],"v":[[-1.068,8.958],[-2.297,5.079],[-2.297,-3.616],[-4.963,-3.616],[-4.963,-5.637],[-2.297,-5.637],[-2.297,-10.262],[0.073,-10.262],[0.073,-5.637],[4.758,-5.637],[4.758,-3.616],[0.073,-3.616],[0.073,4.728],[0.776,7.304],[2.943,8.124],[4.552,7.861],[4.962,9.91],[2.561,10.262]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[731.494,389.887],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 26","np":2,"cix":2,"ix":26,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.653,0.303],[-0.566,0.625],[0,0],[1.142,-0.547],[0,-1.171],[-0.517,-0.458],[-1.014,0]],"o":[[0.654,-0.302],[0,0],[-2.439,0.02],[-1.142,0.547],[0,0.898],[0.517,0.459],[0.8,0]],"v":[[1.727,5.606],[3.557,4.215],[3.557,-0.087],[-1.815,0.762],[-3.528,3.337],[-2.752,5.373],[-0.454,6.061]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-0.849],[0,-1.64],[0,0],[0,0],[0,0],[2.128,0],[0.859,0.82],[0,1.483],[-1.522,0.878],[-3.26,0.02],[0,0],[0.614,0.507],[1.191,0],[1.151,-0.546],[0,0],[-1.639,0]],"o":[[1.034,0.849],[0,0],[0,0],[0,0],[-1.015,1.542],[-1.562,0],[-0.859,-0.819],[0,-1.874],[1.523,-0.879],[0,0],[0,-0.975],[-0.615,-0.508],[-1.307,0],[0,0],[1.424,-0.721],[1.717,0]],"v":[[4.348,-6.923],[5.9,-3.191],[5.9,7.876],[3.733,7.876],[3.733,5.884],[-0.981,8.197],[-4.611,6.967],[-5.899,3.514],[-3.616,-0.614],[3.557,-1.962],[3.557,-2.986],[2.635,-5.21],[-0.073,-5.973],[-3.762,-5.152],[-4.377,-7.114],[0.22,-8.197]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[716.27,392.067],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 27","np":4,"cix":2,"ix":27,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,2.323],[0,0],[0,0],[0,0],[-0.254,-0.243],[-0.547,0],[-0.41,0.079],[0,0],[0.644,0]],"o":[[0,0],[0,0],[0,0],[0,0.547],[0.254,0.245],[0.351,0],[0,0],[-0.625,0.156],[-2.283,0]],"v":[[-2.664,7.875],[-2.664,-11.359],[-0.293,-11.359],[-0.293,7.671],[0.087,8.856],[1.288,9.223],[2.43,9.104],[2.664,11.125],[0.761,11.359]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[704.103,388.759],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 28","np":2,"cix":2,"ix":28,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.09]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[689.376,392.097],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 29","np":4,"cix":2,"ix":29,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.654,0.995],[0,1.971],[0.683,1.025],[1.347,0],[0.595,-0.293],[0.546,-0.625],[0,0],[-0.673,-0.302],[-0.742,0]],"o":[[0.653,-0.996],[0,-1.991],[-0.684,-1.024],[-0.723,0],[-0.595,0.293],[0,0],[0.487,0.546],[0.674,0.303],[1.288,0]],"v":[[2.855,1.727],[3.835,-2.723],[2.811,-7.247],[-0.234,-8.783],[-2.21,-8.344],[-3.922,-6.967],[-3.922,1.493],[-2.181,2.766],[-0.058,3.22]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-1.464],[0,-2.616],[1.083,-1.435],[1.951,0],[0.694,0.312],[0.487,0.566],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.761,0.409],[-0.957,0]],"o":[[1.034,1.464],[0,2.557],[-1.084,1.434],[-0.821,0],[-0.692,-0.312],[0,0],[0,0],[0,0],[0,0],[0,0],[0.526,-0.8],[0.761,-0.41],[1.853,0]],"v":[[4.744,-8.871],[6.294,-2.751],[4.67,3.236],[0.118,5.387],[-2.152,4.918],[-3.922,3.601],[-3.922,11.066],[-6.294,11.066],[-6.294,-10.686],[-4.098,-10.686],[-4.098,-8.637],[-2.166,-10.452],[0.411,-11.066]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[672.041,394.936],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 30","np":4,"cix":2,"ix":30,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.586,-0.253],[0,0],[0.605,0],[0.556,-0.312],[0.449,-0.663],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.717,0]],"o":[[0,0],[-0.742,-0.214],[-0.742,0],[-0.556,0.313],[0,0],[0,0],[0,0],[0,0],[0,0],[1.114,-1.678],[0.704,0]],"v":[[4.187,-7.627],[3.659,-5.314],[1.639,-5.636],[-0.307,-5.168],[-1.815,-3.704],[-1.815,8.007],[-4.187,8.007],[-4.187,-7.686],[-1.992,-7.686],[-1.992,-5.49],[2.253,-8.007]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[656.934,391.936],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 31","np":2,"cix":2,"ix":31,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.273,-3.221],[0,0],[0.702,0.849],[1.229,0]],"o":[[0,0],[-0.019,-1.522],[-0.703,-0.849],[-2.402,0]],"v":[[-3.967,-1.245],[4.026,-1.245],[2.943,-4.801],[0.044,-6.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.078,-0.331],[0,0],[-0.81,-0.888],[-1.483,0],[-1.21,0.781],[0,0],[0.887,-0.264],[0.975,0],[1.24,1.444],[0,2.576],[-1.142,1.444],[-2.069,0],[-1.113,-1.327],[0,-2.38]],"o":[[0,0],[0.078,1.757],[0.81,0.889],[1.464,0],[0,0],[-0.625,0.488],[-0.889,0.264],[-2.225,0],[-1.24,-1.444],[0,-2.596],[1.142,-1.445],[1.991,0],[1.112,1.328],[0,0.567]],"v":[[6.308,0.687],[-3.997,0.687],[-2.664,4.655],[0.776,5.986],[4.786,4.816],[5.695,6.689],[3.425,7.816],[0.63,8.212],[-4.568,6.046],[-6.427,0.014],[-4.714,-6.046],[0.102,-8.212],[4.758,-6.222],[6.427,-0.66]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[640.932,392.082],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 32","np":4,"cix":2,"ix":32,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.468,-0.547],[-0.977,0],[-0.547,0.176],[0,0],[0.878,0]],"o":[[-0.82,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.469,0.546],[0.526,0],[0,0],[-0.721,0.235],[-1.601,0]],"v":[[-1.067,8.958],[-2.297,5.079],[-2.297,-3.616],[-4.962,-3.616],[-4.962,-5.637],[-2.297,-5.637],[-2.297,-10.262],[0.075,-10.262],[0.075,-5.637],[4.758,-5.637],[4.758,-3.616],[0.075,-3.616],[0.075,4.728],[0.777,7.304],[2.944,8.124],[4.554,7.861],[4.963,9.91],[2.563,10.262]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[625.94,389.887],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 33","np":2,"cix":2,"ix":33,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.85,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.537,0.498],[1.034,0],[0.625,-0.243],[0.624,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.849,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.742,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.705],[5.914,-3.031],[5.914,8.036],[3.543,8.036],[3.543,-2.826],[2.738,-5.006],[0.381,-5.753],[-1.669,-5.388],[-3.542,-4.26],[-3.542,8.036],[-5.914,8.036],[-5.914,-7.656],[-3.717,-7.656],[-3.717,-5.929],[1.083,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[610.642,391.907],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 34","np":2,"cix":2,"ix":34,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.216,-10.598],[1.216,-10.598],[1.216,10.598],[-1.216,10.598]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[596.692,389.344],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 35","np":2,"cix":2,"ix":35,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[6.383,8.402],[6.383,10.598],[-6.383,10.598],[-6.383,-10.598],[6.03,-10.598],[6.03,-8.403],[-3.952,-8.403],[-3.952,-1.347],[3.513,-1.347],[3.513,0.878],[-3.952,0.878],[-3.952,8.402]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[575.681,389.345],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 36","np":2,"cix":2,"ix":36,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":42,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"E Interpolation_02 Bezier Interpolation","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[964.374,113.924,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[72.458,72.458,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.849,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.536,0.498],[1.035,0],[0.624,-0.243],[0.625,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.85,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.741,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.705],[5.914,-3.031],[5.914,8.036],[3.543,8.036],[3.543,-2.826],[2.739,-5.006],[0.381,-5.753],[-1.668,-5.388],[-3.542,-4.26],[-3.542,8.036],[-5.913,8.036],[-5.913,-7.656],[-3.717,-7.656],[-3.717,-5.929],[1.084,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1127.343,460.157],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.693,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.693,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.693,-1.035],[-1.366,0],[-0.693,1.034],[0,2.011],[0.692,1.024],[1.347,0]],"v":[[3.06,4.552],[4.099,0],[3.06,-4.537],[0.03,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[0,6.09]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.109,0],[-1.133,-1.396],[0,-2.693],[1.131,-1.405],[2.108,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.142,-1.396],[2.088,0],[1.131,1.395],[0,2.675],[-1.133,1.405],[-2.108,0]],"v":[[-4.86,6.134],[-6.557,0],[-4.845,-6.133],[0.03,-8.227],[4.86,-6.133],[6.557,0],[4.86,6.119],[0,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1109.308,460.347],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.171,-4.831],[1.201,-4.831],[1.201,10.861],[-1.171,10.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.283,0.293],[0,0.527],[-0.283,0.293],[-0.527,0],[-0.284,-0.293],[0,-0.507],[0.282,-0.293],[0.527,0]],"o":[[-0.283,-0.293],[0,-0.527],[0.283,-0.293],[0.527,0],[0.282,0.293],[0,0.547],[-0.284,0.293],[-0.527,0]],"v":[[-1.215,-7.963],[-1.639,-9.193],[-1.215,-10.422],[0,-10.861],[1.216,-10.422],[1.639,-9.222],[1.216,-7.963],[0,-7.524]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1095.926,457.331],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":4,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.468,-0.547],[-0.977,0],[-0.547,0.176],[0,0],[0.878,0]],"o":[[-0.82,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.469,0.546],[0.526,0],[0,0],[-0.721,0.235],[-1.601,0]],"v":[[-1.067,8.958],[-2.297,5.079],[-2.297,-3.616],[-4.962,-3.616],[-4.962,-5.637],[-2.297,-5.637],[-2.297,-10.262],[0.075,-10.262],[0.075,-5.637],[4.758,-5.637],[4.758,-3.616],[0.075,-3.616],[0.075,4.728],[0.777,7.304],[2.944,8.124],[4.554,7.861],[4.963,9.91],[2.563,10.262]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1084.989,458.137],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.654,0.303],[-0.566,0.625],[0,0],[1.143,-0.547],[0,-1.171],[-0.518,-0.458],[-1.015,0]],"o":[[0.653,-0.302],[0,0],[-2.44,0.02],[-1.142,0.547],[0,0.898],[0.516,0.459],[0.8,0]],"v":[[1.728,5.606],[3.557,4.215],[3.557,-0.087],[-1.816,0.762],[-3.527,3.337],[-2.751,5.373],[-0.453,6.061]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.034,-0.849],[0,-1.64],[0,0],[0,0],[0,0],[2.127,0],[0.86,0.82],[0,1.483],[-1.522,0.878],[-3.26,0.02],[0,0],[0.615,0.507],[1.191,0],[1.151,-0.546],[0,0],[-1.639,0]],"o":[[1.034,0.849],[0,0],[0,0],[0,0],[-1.016,1.542],[-1.562,0],[-0.858,-0.819],[0,-1.874],[1.523,-0.879],[0,0],[0,-0.975],[-0.614,-0.508],[-1.307,0],[0,0],[1.424,-0.721],[1.718,0]],"v":[[4.348,-6.923],[5.9,-3.191],[5.9,7.876],[3.734,7.876],[3.734,5.884],[-0.98,8.197],[-4.612,6.967],[-5.9,3.514],[-3.615,-0.614],[3.557,-1.962],[3.557,-2.986],[2.635,-5.21],[-0.073,-5.973],[-3.761,-5.152],[-4.376,-7.114],[0.219,-8.197]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1069.765,460.317],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":4,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,2.323],[0,0],[0,0],[0,0],[-0.254,-0.243],[-0.547,0],[-0.409,0.079],[0,0],[0.644,0]],"o":[[0,0],[0,0],[0,0],[0,0.547],[0.253,0.245],[0.352,0],[0,0],[-0.625,0.156],[-2.283,0]],"v":[[-2.664,7.875],[-2.664,-11.359],[-0.293,-11.359],[-0.293,7.671],[0.088,8.856],[1.288,9.223],[2.43,9.104],[2.664,11.125],[0.761,11.359]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1057.599,457.009],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.09]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1042.871,460.347],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":4,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.653,0.995],[0,1.971],[0.684,1.025],[1.347,0],[0.594,-0.293],[0.546,-0.625],[0,0],[-0.674,-0.302],[-0.741,0]],"o":[[0.654,-0.996],[0,-1.991],[-0.683,-1.024],[-0.723,0],[-0.596,0.293],[0,0],[0.488,0.546],[0.673,0.303],[1.289,0]],"v":[[2.854,1.727],[3.835,-2.723],[2.81,-7.247],[-0.234,-8.783],[-2.21,-8.344],[-3.923,-6.967],[-3.923,1.493],[-2.181,2.766],[-0.059,3.22]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-1.464],[0,-2.616],[1.083,-1.435],[1.952,0],[0.693,0.312],[0.488,0.566],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.761,0.409],[-0.956,0]],"o":[[1.034,1.464],[0,2.557],[-1.083,1.434],[-0.82,0],[-0.693,-0.312],[0,0],[0,0],[0,0],[0,0],[0,0],[0.527,-0.8],[0.761,-0.41],[1.854,0]],"v":[[4.743,-8.871],[6.294,-2.751],[4.669,3.236],[0.117,5.387],[-2.152,4.918],[-3.923,3.601],[-3.923,11.066],[-6.294,11.066],[-6.294,-10.686],[-4.099,-10.686],[-4.099,-8.637],[-2.167,-10.452],[0.41,-11.066]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1025.538,463.186],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":4,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.585,-0.253],[0,0],[0.605,0],[0.555,-0.312],[0.448,-0.663],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.717,0]],"o":[[0,0],[-0.743,-0.214],[-0.742,0],[-0.557,0.313],[0,0],[0,0],[0,0],[0,0],[0,0],[1.113,-1.678],[0.703,0]],"v":[[4.187,-7.627],[3.661,-5.314],[1.639,-5.636],[-0.307,-5.168],[-1.815,-3.704],[-1.815,8.007],[-4.187,8.007],[-4.187,-7.686],[-1.99,-7.686],[-1.99,-5.49],[2.255,-8.007]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1010.429,460.186],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":2,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.273,-3.221],[0,0],[0.703,0.849],[1.229,0]],"o":[[0,0],[-0.019,-1.522],[-0.702,-0.849],[-2.401,0]],"v":[[-3.967,-1.245],[4.024,-1.245],[2.942,-4.801],[0.044,-6.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.078,-0.331],[0,0],[-0.811,-0.888],[-1.484,0],[-1.211,0.781],[0,0],[0.887,-0.264],[0.975,0],[1.24,1.444],[0,2.576],[-1.142,1.444],[-2.069,0],[-1.113,-1.327],[0,-2.38]],"o":[[0,0],[0.078,1.757],[0.809,0.889],[1.464,0],[0,0],[-0.625,0.488],[-0.889,0.264],[-2.226,0],[-1.239,-1.444],[0,-2.596],[1.143,-1.445],[1.992,0],[1.112,1.328],[0,0.567]],"v":[[6.308,0.687],[-3.997,0.687],[-2.664,4.655],[0.776,5.986],[4.786,4.816],[5.693,6.689],[3.425,7.816],[0.63,8.212],[-4.568,6.046],[-6.427,0.014],[-4.714,-6.046],[0.102,-8.212],[4.758,-6.222],[6.427,-0.66]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[994.428,460.332],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10","np":4,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.468,-0.547],[-0.977,0],[-0.547,0.176],[0,0],[0.878,0]],"o":[[-0.82,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.469,0.546],[0.526,0],[0,0],[-0.721,0.235],[-1.601,0]],"v":[[-1.067,8.958],[-2.297,5.079],[-2.297,-3.616],[-4.962,-3.616],[-4.962,-5.637],[-2.297,-5.637],[-2.297,-10.262],[0.075,-10.262],[0.075,-5.637],[4.758,-5.637],[4.758,-3.616],[0.075,-3.616],[0.075,4.728],[0.777,7.304],[2.944,8.124],[4.554,7.861],[4.963,9.91],[2.563,10.262]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[979.436,458.137],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11","np":2,"cix":2,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.85,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.537,0.498],[1.034,0],[0.625,-0.243],[0.624,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.849,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.742,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.705],[5.914,-3.031],[5.914,8.036],[3.543,8.036],[3.543,-2.826],[2.738,-5.006],[0.381,-5.753],[-1.669,-5.388],[-3.542,-4.26],[-3.542,8.036],[-5.914,8.036],[-5.914,-7.656],[-3.717,-7.656],[-3.717,-5.929],[1.083,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[964.137,460.157],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12","np":2,"cix":2,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.216,-10.598],[1.216,-10.598],[1.216,10.598],[-1.216,10.598]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[950.187,457.594],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":2,"cix":2,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.586,-0.253],[0,0],[0.605,0],[0.556,-0.312],[0.449,-0.663],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.717,0]],"o":[[0,0],[-0.742,-0.214],[-0.742,0],[-0.556,0.313],[0,0],[0,0],[0,0],[0,0],[0,0],[1.114,-1.678],[0.704,0]],"v":[[4.187,-7.627],[3.659,-5.314],[1.639,-5.636],[-0.307,-5.168],[-1.815,-3.704],[-1.815,8.007],[-4.187,8.007],[-4.187,-7.686],[-1.992,-7.686],[-1.992,-5.49],[2.253,-8.007]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[932.017,460.186],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 14","np":2,"cix":2,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.273,-3.221],[0,0],[0.702,0.849],[1.229,0]],"o":[[0,0],[-0.019,-1.522],[-0.703,-0.849],[-2.402,0]],"v":[[-3.967,-1.245],[4.026,-1.245],[2.943,-4.801],[0.044,-6.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.078,-0.331],[0,0],[-0.81,-0.888],[-1.483,0],[-1.21,0.781],[0,0],[0.887,-0.264],[0.975,0],[1.24,1.444],[0,2.576],[-1.142,1.444],[-2.069,0],[-1.113,-1.327],[0,-2.38]],"o":[[0,0],[0.078,1.757],[0.81,0.889],[1.464,0],[0,0],[-0.625,0.488],[-0.889,0.264],[-2.225,0],[-1.24,-1.444],[0,-2.596],[1.142,-1.445],[1.991,0],[1.112,1.328],[0,0.567]],"v":[[6.308,0.687],[-3.997,0.687],[-2.664,4.655],[0.776,5.986],[4.786,4.816],[5.695,6.689],[3.425,7.816],[0.63,8.212],[-4.568,6.046],[-6.427,0.014],[-4.714,-6.046],[0.102,-8.212],[4.758,-6.222],[6.427,-0.66]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[916.015,460.332],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 15","np":4,"cix":2,"ix":15,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.172,-4.831],[1.2,-4.831],[1.2,10.861],[-1.172,10.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.284,0.293],[0,0.527],[-0.283,0.293],[-0.526,0],[-0.283,-0.293],[0,-0.507],[0.282,-0.293],[0.528,0]],"o":[[-0.283,-0.293],[0,-0.527],[0.284,-0.293],[0.528,0],[0.282,0.293],[0,0.547],[-0.283,0.293],[-0.526,0]],"v":[[-1.216,-7.963],[-1.639,-9.193],[-1.216,-10.422],[-0.001,-10.861],[1.215,-10.422],[1.639,-9.222],[1.215,-7.963],[-0.001,-7.524]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[902.825,457.331],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 16","np":4,"cix":2,"ix":16,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[5.549,5.826],[5.549,7.846],[-5.549,7.846],[-5.549,5.826],[2.737,-5.826],[-5.314,-5.826],[-5.314,-7.846],[5.432,-7.846],[5.432,-5.826],[-2.826,5.826]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[890.805,460.347],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 17","np":2,"cix":2,"ix":17,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.273,-3.221],[0,0],[0.702,0.849],[1.229,0]],"o":[[0,0],[-0.019,-1.522],[-0.703,-0.849],[-2.402,0]],"v":[[-3.967,-1.245],[4.026,-1.245],[2.943,-4.801],[0.044,-6.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.078,-0.331],[0,0],[-0.81,-0.888],[-1.483,0],[-1.21,0.781],[0,0],[0.887,-0.264],[0.975,0],[1.24,1.444],[0,2.576],[-1.142,1.444],[-2.069,0],[-1.113,-1.327],[0,-2.38]],"o":[[0,0],[0.078,1.757],[0.81,0.889],[1.464,0],[0,0],[-0.625,0.488],[-0.889,0.264],[-2.225,0],[-1.24,-1.444],[0,-2.596],[1.142,-1.445],[1.991,0],[1.112,1.328],[0,0.567]],"v":[[6.308,0.687],[-3.997,0.687],[-2.664,4.655],[0.776,5.986],[4.786,4.816],[5.695,6.689],[3.425,7.816],[0.63,8.212],[-4.568,6.046],[-6.427,0.014],[-4.714,-6.046],[0.102,-8.212],[4.758,-6.222],[6.427,-0.66]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[874.877,460.332],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 18","np":4,"cix":2,"ix":18,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.644,0.645],[0,1.269],[0.664,0.634],[1.288,0],[0,0],[0,0],[0,0]],"o":[[0.645,-0.644],[0,-1.249],[-0.663,-0.634],[0,0],[0,0],[0,0],[1.249,0]],"v":[[3.776,7.436],[4.743,4.567],[3.747,1.742],[0.82,0.79],[-4.86,0.79],[-4.86,8.402],[0.936,8.402]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.643,0.576],[0,1.132],[0.663,0.615],[1.288,0]],"o":[[0,0],[0,0],[1.249,0],[0.645,-0.576],[0,-1.19],[-0.663,-0.615],[0,0]],"v":[[-4.86,-8.402],[-4.86,-1.347],[-0.235,-1.347],[2.605,-2.21],[3.572,-4.772],[2.576,-7.48],[-0.352,-8.402]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,-2.752],[1.141,-1.063],[2.029,0],[0,0],[0,0],[0,0],[-1.113,-1.014],[0,-1.835],[0.459,-0.712],[0.897,-0.273]],"o":[[0,1.893],[-1.142,1.064],[0,0],[0,0],[0,0],[1.991,0],[1.112,1.015],[0,1.112],[-0.459,0.713],[2.615,0.683]],"v":[[7.29,4.567],[5.577,9.002],[0.82,10.598],[-7.29,10.598],[-7.29,-10.598],[-0.235,-10.598],[4.421,-9.076],[6.089,-4.801],[5.401,-2.064],[3.367,-0.585]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[856.797,457.595],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 19","np":5,"cix":2,"ix":19,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[-0.361,0.712],[0,0.703],[0.674,0.605],[1.191,0],[0.859,-0.283],[0.722,-0.508],[0,0],[-1.152,0.361],[-1.094,0],[-1.113,-0.986],[0,-1.62],[0.459,-0.985],[1.093,-1.327],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0.898,-1.113],[0.36,-0.713],[0,-1.034],[-0.673,-0.605],[-0.839,0],[-0.859,0.283],[0,0],[0.742,-0.586],[1.151,-0.361],[1.834,0],[1.112,0.985],[0,0.957],[-0.459,0.986],[0,0],[0,0]],"v":[[6.266,8.68],[6.266,10.789],[-6.208,10.789],[-6.208,8.651],[1.17,-0.307],[3.059,-3.044],[3.6,-5.167],[2.59,-7.626],[-0.206,-8.534],[-2.753,-8.109],[-5.124,-6.923],[-6.266,-8.826],[-3.426,-10.246],[-0.059,-10.789],[4.362,-9.31],[6.031,-5.401],[5.342,-2.488],[3.016,0.981],[-3.397,8.68]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[829.362,457.404],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 20","np":2,"cix":2,"ix":20,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.742,1.425],[0,3.025],[0.741,1.425],[1.581,0],[0.741,-1.425],[0,-3.025],[-0.743,-1.425],[-1.581,0]],"o":[[0.741,-1.425],[0,-3.025],[-0.742,-1.425],[-1.562,0],[-0.743,1.425],[0,3.025],[0.741,1.425],[1.561,0]],"v":[[3.47,6.675],[4.582,0],[3.47,-6.674],[-0.014,-8.812],[-3.469,-6.674],[-4.581,0],[-3.469,6.675],[0.015,8.813]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.171,1.786],[0,3.747],[-1.161,1.786],[-2.381,0],[-1.172,-1.786],[0,-3.748],[1.161,-1.786],[2.381,0]],"o":[[-1.171,-1.786],[0,-3.748],[1.161,-1.786],[2.38,0],[1.171,1.786],[0,3.747],[-1.162,1.786],[-2.381,0]],"v":[[-5.313,8.3],[-7.07,0],[-5.328,-8.299],[-0.014,-10.979],[5.315,-8.299],[7.07,0],[5.328,8.3],[0.015,10.979]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[811.516,457.594],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 21","np":4,"cix":2,"ix":21,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-5.958,-1.112],[5.958,-1.112],[5.958,1.112],[-5.958,1.112]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[792.338,471.443],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 22","np":2,"cix":2,"ix":22,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.849,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.536,0.498],[1.035,0],[0.624,-0.243],[0.625,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.85,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.741,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.705],[5.913,-3.031],[5.913,8.036],[3.542,8.036],[3.542,-2.826],[2.738,-5.006],[0.38,-5.753],[-1.669,-5.388],[-3.543,-4.26],[-3.543,8.036],[-5.914,8.036],[-5.914,-7.656],[-3.718,-7.656],[-3.718,-5.929],[1.083,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[773.848,460.157],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 23","np":2,"cix":2,"ix":23,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.09]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[755.812,460.347],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 24","np":4,"cix":2,"ix":24,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.171,-4.831],[1.201,-4.831],[1.201,10.861],[-1.171,10.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.283,0.293],[0,0.527],[-0.283,0.293],[-0.527,0],[-0.283,-0.293],[0,-0.507],[0.283,-0.293],[0.527,0]],"o":[[-0.283,-0.293],[0,-0.527],[0.283,-0.293],[0.527,0],[0.283,0.293],[0,0.547],[-0.283,0.293],[-0.527,0]],"v":[[-1.215,-7.963],[-1.639,-9.193],[-1.215,-10.422],[0,-10.861],[1.215,-10.422],[1.639,-9.222],[1.215,-7.963],[0,-7.524]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[742.431,457.331],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 25","np":4,"cix":2,"ix":25,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.469,-0.547],[-0.976,0],[-0.547,0.176],[0,0],[0.879,0]],"o":[[-0.819,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.468,0.546],[0.527,0],[0,0],[-0.722,0.235],[-1.601,0]],"v":[[-1.068,8.958],[-2.297,5.079],[-2.297,-3.616],[-4.963,-3.616],[-4.963,-5.637],[-2.297,-5.637],[-2.297,-10.262],[0.073,-10.262],[0.073,-5.637],[4.758,-5.637],[4.758,-3.616],[0.073,-3.616],[0.073,4.728],[0.776,7.304],[2.943,8.124],[4.552,7.861],[4.962,9.91],[2.561,10.262]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[731.494,458.137],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 26","np":2,"cix":2,"ix":26,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.653,0.303],[-0.566,0.625],[0,0],[1.142,-0.547],[0,-1.171],[-0.517,-0.458],[-1.014,0]],"o":[[0.654,-0.302],[0,0],[-2.439,0.02],[-1.142,0.547],[0,0.898],[0.517,0.459],[0.8,0]],"v":[[1.727,5.606],[3.557,4.215],[3.557,-0.087],[-1.815,0.762],[-3.528,3.337],[-2.752,5.373],[-0.454,6.061]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-0.849],[0,-1.64],[0,0],[0,0],[0,0],[2.128,0],[0.859,0.82],[0,1.483],[-1.522,0.878],[-3.26,0.02],[0,0],[0.614,0.507],[1.191,0],[1.151,-0.546],[0,0],[-1.639,0]],"o":[[1.034,0.849],[0,0],[0,0],[0,0],[-1.015,1.542],[-1.562,0],[-0.859,-0.819],[0,-1.874],[1.523,-0.879],[0,0],[0,-0.975],[-0.615,-0.508],[-1.307,0],[0,0],[1.424,-0.721],[1.717,0]],"v":[[4.348,-6.923],[5.9,-3.191],[5.9,7.876],[3.733,7.876],[3.733,5.884],[-0.981,8.197],[-4.611,6.967],[-5.899,3.514],[-3.616,-0.614],[3.557,-1.962],[3.557,-2.986],[2.635,-5.21],[-0.073,-5.973],[-3.762,-5.152],[-4.377,-7.114],[0.22,-8.197]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[716.27,460.317],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 27","np":4,"cix":2,"ix":27,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,2.323],[0,0],[0,0],[0,0],[-0.254,-0.243],[-0.547,0],[-0.41,0.079],[0,0],[0.644,0]],"o":[[0,0],[0,0],[0,0],[0,0.547],[0.254,0.245],[0.351,0],[0,0],[-0.625,0.156],[-2.283,0]],"v":[[-2.664,7.875],[-2.664,-11.359],[-0.293,-11.359],[-0.293,7.671],[0.087,8.856],[1.288,9.223],[2.43,9.104],[2.664,11.125],[0.761,11.359]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[704.103,457.009],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 28","np":2,"cix":2,"ix":28,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.09]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[689.376,460.347],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 29","np":4,"cix":2,"ix":29,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.654,0.995],[0,1.971],[0.683,1.025],[1.347,0],[0.595,-0.293],[0.546,-0.625],[0,0],[-0.673,-0.302],[-0.742,0]],"o":[[0.653,-0.996],[0,-1.991],[-0.684,-1.024],[-0.723,0],[-0.595,0.293],[0,0],[0.487,0.546],[0.674,0.303],[1.288,0]],"v":[[2.855,1.727],[3.835,-2.723],[2.811,-7.247],[-0.234,-8.783],[-2.21,-8.344],[-3.922,-6.967],[-3.922,1.493],[-2.181,2.766],[-0.058,3.22]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-1.464],[0,-2.616],[1.083,-1.435],[1.951,0],[0.694,0.312],[0.487,0.566],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.761,0.409],[-0.957,0]],"o":[[1.034,1.464],[0,2.557],[-1.084,1.434],[-0.821,0],[-0.692,-0.312],[0,0],[0,0],[0,0],[0,0],[0,0],[0.526,-0.8],[0.761,-0.41],[1.853,0]],"v":[[4.744,-8.871],[6.294,-2.751],[4.67,3.236],[0.118,5.387],[-2.152,4.918],[-3.922,3.601],[-3.922,11.066],[-6.294,11.066],[-6.294,-10.686],[-4.098,-10.686],[-4.098,-8.637],[-2.166,-10.452],[0.411,-11.066]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[672.041,463.186],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 30","np":4,"cix":2,"ix":30,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.586,-0.253],[0,0],[0.605,0],[0.556,-0.312],[0.449,-0.663],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.717,0]],"o":[[0,0],[-0.742,-0.214],[-0.742,0],[-0.556,0.313],[0,0],[0,0],[0,0],[0,0],[0,0],[1.114,-1.678],[0.704,0]],"v":[[4.187,-7.627],[3.659,-5.314],[1.639,-5.636],[-0.307,-5.168],[-1.815,-3.704],[-1.815,8.007],[-4.187,8.007],[-4.187,-7.686],[-1.992,-7.686],[-1.992,-5.49],[2.253,-8.007]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[656.934,460.186],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 31","np":2,"cix":2,"ix":31,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.273,-3.221],[0,0],[0.702,0.849],[1.229,0]],"o":[[0,0],[-0.019,-1.522],[-0.703,-0.849],[-2.402,0]],"v":[[-3.967,-1.245],[4.026,-1.245],[2.943,-4.801],[0.044,-6.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.078,-0.331],[0,0],[-0.81,-0.888],[-1.483,0],[-1.21,0.781],[0,0],[0.887,-0.264],[0.975,0],[1.24,1.444],[0,2.576],[-1.142,1.444],[-2.069,0],[-1.113,-1.327],[0,-2.38]],"o":[[0,0],[0.078,1.757],[0.81,0.889],[1.464,0],[0,0],[-0.625,0.488],[-0.889,0.264],[-2.225,0],[-1.24,-1.444],[0,-2.596],[1.142,-1.445],[1.991,0],[1.112,1.328],[0,0.567]],"v":[[6.308,0.687],[-3.997,0.687],[-2.664,4.655],[0.776,5.986],[4.786,4.816],[5.695,6.689],[3.425,7.816],[0.63,8.212],[-4.568,6.046],[-6.427,0.014],[-4.714,-6.046],[0.102,-8.212],[4.758,-6.222],[6.427,-0.66]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[640.932,460.332],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 32","np":4,"cix":2,"ix":32,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.468,-0.547],[-0.977,0],[-0.547,0.176],[0,0],[0.878,0]],"o":[[-0.82,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.469,0.546],[0.526,0],[0,0],[-0.721,0.235],[-1.601,0]],"v":[[-1.067,8.958],[-2.297,5.079],[-2.297,-3.616],[-4.962,-3.616],[-4.962,-5.637],[-2.297,-5.637],[-2.297,-10.262],[0.075,-10.262],[0.075,-5.637],[4.758,-5.637],[4.758,-3.616],[0.075,-3.616],[0.075,4.728],[0.777,7.304],[2.944,8.124],[4.554,7.861],[4.963,9.91],[2.563,10.262]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[625.94,458.137],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 33","np":2,"cix":2,"ix":33,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.85,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.537,0.498],[1.034,0],[0.625,-0.243],[0.624,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.849,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.742,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.705],[5.914,-3.031],[5.914,8.036],[3.543,8.036],[3.543,-2.826],[2.738,-5.006],[0.381,-5.753],[-1.669,-5.388],[-3.542,-4.26],[-3.542,8.036],[-5.914,8.036],[-5.914,-7.656],[-3.717,-7.656],[-3.717,-5.929],[1.083,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[610.642,460.157],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 34","np":2,"cix":2,"ix":34,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.216,-10.598],[1.216,-10.598],[1.216,10.598],[-1.216,10.598]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[596.692,457.594],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 35","np":2,"cix":2,"ix":35,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[6.383,8.402],[6.383,10.598],[-6.383,10.598],[-6.383,-10.598],[6.03,-10.598],[6.03,-8.403],[-3.952,-8.403],[-3.952,-1.347],[3.513,-1.347],[3.513,0.878],[-3.952,0.878],[-3.952,8.402]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[575.681,457.595],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 36","np":2,"cix":2,"ix":36,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":42,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"E Interpolation_03 Hold Interpolation","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1605.124,64.606,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[72.458,72.458,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.849,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.536,0.498],[1.035,0],[0.624,-0.243],[0.625,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.85,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.741,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.705],[5.914,-3.031],[5.914,8.036],[3.543,8.036],[3.543,-2.826],[2.739,-5.006],[0.381,-5.753],[-1.668,-5.388],[-3.542,-4.26],[-3.542,8.036],[-5.913,8.036],[-5.913,-7.656],[-3.717,-7.656],[-3.717,-5.929],[1.084,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1104.68,528.407],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.09]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1086.644,528.597],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.171,-4.831],[1.201,-4.831],[1.201,10.861],[-1.171,10.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.283,0.293],[0,0.527],[-0.283,0.293],[-0.527,0],[-0.284,-0.293],[0,-0.507],[0.282,-0.293],[0.527,0]],"o":[[-0.283,-0.293],[0,-0.527],[0.283,-0.293],[0.527,0],[0.282,0.293],[0,0.547],[-0.284,0.293],[-0.527,0]],"v":[[-1.215,-7.963],[-1.639,-9.193],[-1.215,-10.422],[0,-10.861],[1.216,-10.422],[1.639,-9.222],[1.216,-7.963],[0,-7.524]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1073.263,525.581],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":4,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.468,-0.547],[-0.977,0],[-0.547,0.176],[0,0],[0.878,0]],"o":[[-0.82,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.469,0.546],[0.526,0],[0,0],[-0.721,0.235],[-1.601,0]],"v":[[-1.067,8.958],[-2.297,5.08],[-2.297,-3.616],[-4.962,-3.616],[-4.962,-5.636],[-2.297,-5.636],[-2.297,-10.261],[0.075,-10.261],[0.075,-5.636],[4.758,-5.636],[4.758,-3.616],[0.075,-3.616],[0.075,4.729],[0.777,7.305],[2.944,8.125],[4.554,7.861],[4.963,9.91],[2.563,10.262]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1062.326,526.387],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.653,0.303],[-0.566,0.625],[0,0],[1.142,-0.547],[0,-1.171],[-0.517,-0.458],[-1.014,0]],"o":[[0.654,-0.302],[0,0],[-2.439,0.02],[-1.142,0.547],[0,0.898],[0.517,0.459],[0.8,0]],"v":[[1.727,5.606],[3.557,4.215],[3.557,-0.088],[-1.816,0.761],[-3.528,3.337],[-2.752,5.372],[-0.454,6.06]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-0.849],[0,-1.64],[0,0],[0,0],[0,0],[2.128,0],[0.859,0.82],[0,1.483],[-1.522,0.878],[-3.26,0.02],[0,0],[0.614,0.507],[1.191,0],[1.151,-0.546],[0,0],[-1.639,0]],"o":[[1.034,0.849],[0,0],[0,0],[0,0],[-1.015,1.542],[-1.562,0],[-0.859,-0.819],[0,-1.874],[1.523,-0.879],[0,0],[0,-0.975],[-0.615,-0.508],[-1.307,0],[0,0],[1.424,-0.721],[1.717,0]],"v":[[4.348,-6.924],[5.9,-3.191],[5.9,7.875],[3.733,7.875],[3.733,5.884],[-0.981,8.197],[-4.611,6.967],[-5.9,3.513],[-3.616,-0.615],[3.557,-1.962],[3.557,-2.987],[2.635,-5.211],[-0.073,-5.973],[-3.762,-5.153],[-4.377,-7.115],[0.219,-8.198]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1047.102,528.567],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":4,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,2.323],[0,0],[0,0],[0,0],[-0.254,-0.243],[-0.547,0],[-0.41,0.079],[0,0],[0.644,0]],"o":[[0,0],[0,0],[0,0],[0,0.547],[0.254,0.245],[0.351,0],[0,0],[-0.625,0.156],[-2.283,0]],"v":[[-2.665,7.875],[-2.665,-11.359],[-0.293,-11.359],[-0.293,7.671],[0.087,8.856],[1.288,9.223],[2.43,9.104],[2.664,11.125],[0.761,11.359]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1034.935,525.259],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.09]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1020.208,528.597],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":4,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.654,0.995],[0,1.971],[0.683,1.025],[1.347,0],[0.595,-0.293],[0.546,-0.625],[0,0],[-0.673,-0.302],[-0.742,0]],"o":[[0.653,-0.996],[0,-1.991],[-0.684,-1.024],[-0.723,0],[-0.595,0.293],[0,0],[0.487,0.546],[0.674,0.303],[1.288,0]],"v":[[2.855,1.727],[3.835,-2.722],[2.811,-7.247],[-0.234,-8.782],[-2.21,-8.344],[-3.922,-6.967],[-3.922,1.494],[-2.181,2.766],[-0.058,3.221]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-1.464],[0,-2.616],[1.083,-1.435],[1.951,0],[0.694,0.312],[0.487,0.566],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.761,0.409],[-0.957,0]],"o":[[1.034,1.464],[0,2.557],[-1.084,1.434],[-0.821,0],[-0.692,-0.312],[0,0],[0,0],[0,0],[0,0],[0,0],[0.526,-0.8],[0.761,-0.41],[1.853,0]],"v":[[4.744,-8.87],[6.294,-2.751],[4.67,3.236],[0.118,5.387],[-2.152,4.919],[-3.922,3.602],[-3.922,11.067],[-6.294,11.067],[-6.294,-10.686],[-4.098,-10.686],[-4.098,-8.636],[-2.166,-10.451],[0.411,-11.066]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1002.873,531.436],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":4,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.585,-0.253],[0,0],[0.605,0],[0.555,-0.312],[0.448,-0.663],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.717,0]],"o":[[0,0],[-0.743,-0.214],[-0.742,0],[-0.557,0.313],[0,0],[0,0],[0,0],[0,0],[0,0],[1.113,-1.678],[0.703,0]],"v":[[4.187,-7.627],[3.661,-5.314],[1.639,-5.636],[-0.307,-5.168],[-1.815,-3.704],[-1.815,8.007],[-4.187,8.007],[-4.187,-7.686],[-1.99,-7.686],[-1.99,-5.49],[2.255,-8.007]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[987.766,528.436],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":2,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.273,-3.221],[0,0],[0.702,0.849],[1.229,0]],"o":[[0,0],[-0.019,-1.522],[-0.703,-0.849],[-2.402,0]],"v":[[-3.967,-1.245],[4.026,-1.245],[2.943,-4.802],[0.044,-6.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.078,-0.331],[0,0],[-0.81,-0.888],[-1.483,0],[-1.21,0.781],[0,0],[0.887,-0.264],[0.975,0],[1.24,1.444],[0,2.576],[-1.142,1.444],[-2.069,0],[-1.113,-1.327],[0,-2.38]],"o":[[0,0],[0.078,1.757],[0.81,0.889],[1.464,0],[0,0],[-0.625,0.488],[-0.889,0.264],[-2.225,0],[-1.24,-1.444],[0,-2.596],[1.142,-1.445],[1.991,0],[1.112,1.328],[0,0.567]],"v":[[6.308,0.687],[-3.997,0.687],[-2.664,4.654],[0.776,5.986],[4.786,4.815],[5.695,6.689],[3.425,7.816],[0.63,8.212],[-4.568,6.045],[-6.427,0.014],[-4.714,-6.046],[0.102,-8.213],[4.758,-6.222],[6.427,-0.66]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[971.764,528.582],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10","np":4,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.468,-0.547],[-0.977,0],[-0.547,0.176],[0,0],[0.878,0]],"o":[[-0.82,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.469,0.546],[0.526,0],[0,0],[-0.721,0.235],[-1.601,0]],"v":[[-1.068,8.958],[-2.298,5.08],[-2.298,-3.616],[-4.963,-3.616],[-4.963,-5.636],[-2.298,-5.636],[-2.298,-10.261],[0.074,-10.261],[0.074,-5.636],[4.757,-5.636],[4.757,-3.616],[0.074,-3.616],[0.074,4.729],[0.776,7.305],[2.943,8.125],[4.553,7.861],[4.962,9.91],[2.562,10.262]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[956.773,526.387],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11","np":2,"cix":2,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.85,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.537,0.498],[1.034,0],[0.625,-0.243],[0.624,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.849,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.742,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.705],[5.914,-3.031],[5.914,8.036],[3.543,8.036],[3.543,-2.826],[2.738,-5.006],[0.381,-5.753],[-1.669,-5.388],[-3.542,-4.26],[-3.542,8.036],[-5.914,8.036],[-5.914,-7.656],[-3.717,-7.656],[-3.717,-5.929],[1.083,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[941.474,528.407],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12","np":2,"cix":2,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.216,-10.598],[1.216,-10.598],[1.216,10.598],[-1.216,10.598]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[927.523,525.844],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":2,"cix":2,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.596,0.293],[-0.547,0.625],[0,0],[0.674,0.302],[0.741,0],[0.653,-0.995],[0,-1.971],[-0.683,-1.025],[-1.346,0]],"o":[[0.596,-0.292],[0,0],[-0.488,-0.546],[-0.673,-0.303],[-1.288,0],[-0.655,0.995],[0,1.991],[0.683,1.025],[0.723,0]],"v":[[2.211,8.739],[3.923,7.363],[3.923,-1.098],[2.181,-2.371],[0.06,-2.825],[-2.854,-1.332],[-3.836,3.118],[-2.811,7.641],[0.233,9.178]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0.762,-0.41],[0.956,0],[1.034,1.464],[0,2.616],[-1.083,1.435],[-1.952,0],[-0.693,-0.312],[-0.488,-0.566],[0,0]],"o":[[0,0],[0,0],[0,0],[-0.528,0.8],[-0.761,0.41],[-1.855,0],[-1.035,-1.464],[0,-2.556],[1.083,-1.434],[0.819,0],[0.693,0.312],[0,0],[0,0]],"v":[[6.294,-11.462],[6.294,11.081],[4.099,11.081],[4.099,9.032],[2.167,10.847],[-0.41,11.462],[-4.742,9.266],[-6.294,3.147],[-4.669,-2.84],[-0.117,-4.991],[2.151,-4.523],[3.923,-3.206],[3.923,-11.462]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[905.225,525.362],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 14","np":4,"cix":2,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,2.323],[0,0],[0,0],[0,0],[-0.254,-0.243],[-0.547,0],[-0.409,0.079],[0,0],[0.644,0]],"o":[[0,0],[0,0],[0,0],[0,0.547],[0.253,0.245],[0.352,0],[0,0],[-0.625,0.156],[-2.283,0]],"v":[[-2.664,7.875],[-2.664,-11.359],[-0.293,-11.359],[-0.293,7.671],[0.088,8.856],[1.288,9.223],[2.43,9.104],[2.664,11.125],[0.761,11.359]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[892.312,525.259],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 15","np":2,"cix":2,"ix":15,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.693,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.693,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.693,-1.035],[-1.366,0],[-0.693,1.034],[0,2.011],[0.692,1.024],[1.347,0]],"v":[[3.06,4.552],[4.098,0],[3.06,-4.537],[0.029,-6.089],[-3.06,-4.537],[-4.099,0],[-3.06,4.552],[-0.001,6.09]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.109,0],[-1.133,-1.396],[0,-2.693],[1.131,-1.405],[2.108,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.142,-1.396],[2.088,0],[1.131,1.395],[0,2.675],[-1.133,1.405],[-2.108,0]],"v":[[-4.861,6.134],[-6.557,0],[-4.846,-6.133],[0.029,-8.227],[4.86,-6.133],[6.557,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[877.585,528.597],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 16","np":4,"cix":2,"ix":16,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[7.466,-10.598],[7.466,10.598],[5.035,10.598],[5.035,0.937],[-5.035,0.937],[-5.035,10.598],[-7.466,10.598],[-7.466,-10.598],[-5.035,-10.598],[-5.035,-1.259],[5.035,-1.259],[5.035,-10.598]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[857.85,525.845],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 17","np":2,"cix":2,"ix":17,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.112,-1.151],[0,-1.874],[0.585,-1.044],[1.054,-0.566],[1.405,0],[1.102,0.302],[0.801,0.508],[0,0],[-0.878,-0.263],[-0.801,0],[-0.791,0.81],[0,1.444],[0.761,0.761],[1.367,0],[0.586,-0.176],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[1.113,1.152],[0,1.346],[-0.586,1.044],[-1.055,0.565],[-1.015,0],[-1.103,-0.303],[0,0],[0.819,0.468],[0.878,0.263],[1.424,0],[0.79,-0.81],[0,-1.347],[-0.762,-0.761],[-0.742,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.854,0.039]],"v":[[4.86,-0.6],[6.529,3.938],[5.651,7.524],[3.192,9.94],[-0.497,10.788],[-3.674,10.335],[-6.529,9.12],[-5.562,7.041],[-3.015,8.139],[-0.497,8.534],[2.826,7.319],[4.011,3.938],[2.87,0.776],[-0.322,-0.366],[-2.313,-0.102],[-3.22,-1.273],[3.22,-8.681],[-6.177,-8.681],[-6.177,-10.788],[5.915,-10.788],[5.915,-8.681],[0.41,-2.386]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[829.624,526.035],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 18","np":2,"cix":2,"ix":18,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.742,1.425],[0,3.025],[0.741,1.425],[1.581,0],[0.741,-1.425],[0,-3.025],[-0.743,-1.425],[-1.581,0]],"o":[[0.741,-1.425],[0,-3.025],[-0.742,-1.425],[-1.562,0],[-0.743,1.425],[0,3.025],[0.741,1.425],[1.561,0]],"v":[[3.47,6.675],[4.582,0],[3.47,-6.674],[-0.014,-8.812],[-3.469,-6.674],[-4.581,0],[-3.469,6.675],[0.015,8.813]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.171,1.786],[0,3.747],[-1.161,1.786],[-2.381,0],[-1.172,-1.786],[0,-3.748],[1.161,-1.786],[2.381,0]],"o":[[-1.171,-1.786],[0,-3.748],[1.161,-1.786],[2.38,0],[1.171,1.786],[0,3.747],[-1.162,1.786],[-2.381,0]],"v":[[-5.313,8.3],[-7.07,0],[-5.328,-8.299],[-0.014,-10.979],[5.315,-8.299],[7.07,0],[5.328,8.3],[0.015,10.979]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[811.516,525.844],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 19","np":4,"cix":2,"ix":19,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-5.958,-1.112],[5.958,-1.112],[5.958,1.112],[-5.958,1.112]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[792.338,539.693],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 20","np":2,"cix":2,"ix":20,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.849,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.536,0.498],[1.035,0],[0.624,-0.243],[0.625,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.85,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.741,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.705],[5.913,-3.031],[5.913,8.036],[3.542,8.036],[3.542,-2.826],[2.738,-5.006],[0.38,-5.753],[-1.669,-5.388],[-3.543,-4.26],[-3.543,8.036],[-5.914,8.036],[-5.914,-7.656],[-3.718,-7.656],[-3.718,-5.929],[1.083,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[773.848,528.407],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 21","np":2,"cix":2,"ix":21,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.09]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[755.812,528.597],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 22","np":4,"cix":2,"ix":22,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.171,-4.831],[1.201,-4.831],[1.201,10.861],[-1.171,10.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.283,0.293],[0,0.527],[-0.283,0.293],[-0.527,0],[-0.283,-0.293],[0,-0.507],[0.283,-0.293],[0.527,0]],"o":[[-0.283,-0.293],[0,-0.527],[0.283,-0.293],[0.527,0],[0.283,0.293],[0,0.547],[-0.283,0.293],[-0.527,0]],"v":[[-1.215,-7.963],[-1.639,-9.193],[-1.215,-10.422],[0,-10.861],[1.215,-10.422],[1.639,-9.222],[1.215,-7.963],[0,-7.524]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[742.431,525.581],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 23","np":4,"cix":2,"ix":23,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.469,-0.547],[-0.976,0],[-0.547,0.176],[0,0],[0.879,0]],"o":[[-0.819,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.468,0.546],[0.527,0],[0,0],[-0.722,0.235],[-1.601,0]],"v":[[-1.068,8.958],[-2.297,5.08],[-2.297,-3.616],[-4.963,-3.616],[-4.963,-5.636],[-2.297,-5.636],[-2.297,-10.261],[0.073,-10.261],[0.073,-5.636],[4.758,-5.636],[4.758,-3.616],[0.073,-3.616],[0.073,4.729],[0.776,7.305],[2.943,8.125],[4.552,7.861],[4.962,9.91],[2.561,10.262]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[731.494,526.387],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 24","np":2,"cix":2,"ix":24,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.653,0.303],[-0.566,0.625],[0,0],[1.142,-0.547],[0,-1.171],[-0.517,-0.458],[-1.014,0]],"o":[[0.654,-0.302],[0,0],[-2.439,0.02],[-1.142,0.547],[0,0.898],[0.517,0.459],[0.8,0]],"v":[[1.727,5.606],[3.557,4.215],[3.557,-0.088],[-1.815,0.761],[-3.528,3.337],[-2.752,5.372],[-0.454,6.06]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-0.849],[0,-1.64],[0,0],[0,0],[0,0],[2.128,0],[0.859,0.82],[0,1.483],[-1.522,0.878],[-3.26,0.02],[0,0],[0.614,0.507],[1.191,0],[1.151,-0.546],[0,0],[-1.639,0]],"o":[[1.034,0.849],[0,0],[0,0],[0,0],[-1.015,1.542],[-1.562,0],[-0.859,-0.819],[0,-1.874],[1.523,-0.879],[0,0],[0,-0.975],[-0.615,-0.508],[-1.307,0],[0,0],[1.424,-0.721],[1.717,0]],"v":[[4.348,-6.924],[5.9,-3.191],[5.9,7.875],[3.733,7.875],[3.733,5.884],[-0.981,8.197],[-4.611,6.967],[-5.899,3.513],[-3.616,-0.615],[3.557,-1.962],[3.557,-2.987],[2.635,-5.211],[-0.073,-5.973],[-3.762,-5.153],[-4.377,-7.115],[0.22,-8.198]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[716.27,528.567],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 25","np":4,"cix":2,"ix":25,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,2.323],[0,0],[0,0],[0,0],[-0.254,-0.243],[-0.547,0],[-0.41,0.079],[0,0],[0.644,0]],"o":[[0,0],[0,0],[0,0],[0,0.547],[0.254,0.245],[0.351,0],[0,0],[-0.625,0.156],[-2.283,0]],"v":[[-2.664,7.875],[-2.664,-11.359],[-0.293,-11.359],[-0.293,7.671],[0.087,8.856],[1.288,9.223],[2.43,9.104],[2.664,11.125],[0.761,11.359]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[704.103,525.259],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 26","np":2,"cix":2,"ix":26,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.09]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[689.376,528.597],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 27","np":4,"cix":2,"ix":27,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.654,0.995],[0,1.971],[0.683,1.025],[1.347,0],[0.595,-0.293],[0.546,-0.625],[0,0],[-0.673,-0.302],[-0.742,0]],"o":[[0.653,-0.996],[0,-1.991],[-0.684,-1.024],[-0.723,0],[-0.595,0.293],[0,0],[0.487,0.546],[0.674,0.303],[1.288,0]],"v":[[2.855,1.727],[3.835,-2.722],[2.811,-7.247],[-0.234,-8.782],[-2.21,-8.344],[-3.922,-6.967],[-3.922,1.494],[-2.181,2.766],[-0.058,3.221]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-1.464],[0,-2.616],[1.083,-1.435],[1.951,0],[0.694,0.312],[0.487,0.566],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.761,0.409],[-0.957,0]],"o":[[1.034,1.464],[0,2.557],[-1.084,1.434],[-0.821,0],[-0.692,-0.312],[0,0],[0,0],[0,0],[0,0],[0,0],[0.526,-0.8],[0.761,-0.41],[1.853,0]],"v":[[4.744,-8.87],[6.294,-2.751],[4.67,3.236],[0.118,5.387],[-2.152,4.919],[-3.922,3.602],[-3.922,11.067],[-6.294,11.067],[-6.294,-10.686],[-4.098,-10.686],[-4.098,-8.636],[-2.166,-10.451],[0.411,-11.066]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[672.041,531.436],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 28","np":4,"cix":2,"ix":28,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.586,-0.253],[0,0],[0.605,0],[0.556,-0.312],[0.449,-0.663],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.717,0]],"o":[[0,0],[-0.742,-0.214],[-0.742,0],[-0.556,0.313],[0,0],[0,0],[0,0],[0,0],[0,0],[1.114,-1.678],[0.704,0]],"v":[[4.187,-7.627],[3.659,-5.314],[1.639,-5.636],[-0.307,-5.168],[-1.815,-3.704],[-1.815,8.007],[-4.187,8.007],[-4.187,-7.686],[-1.992,-7.686],[-1.992,-5.49],[2.253,-8.007]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[656.934,528.436],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 29","np":2,"cix":2,"ix":29,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.273,-3.221],[0,0],[0.702,0.849],[1.229,0]],"o":[[0,0],[-0.019,-1.522],[-0.703,-0.849],[-2.402,0]],"v":[[-3.967,-1.245],[4.026,-1.245],[2.943,-4.802],[0.044,-6.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.078,-0.331],[0,0],[-0.81,-0.888],[-1.483,0],[-1.21,0.781],[0,0],[0.887,-0.264],[0.975,0],[1.24,1.444],[0,2.576],[-1.142,1.444],[-2.069,0],[-1.113,-1.327],[0,-2.38]],"o":[[0,0],[0.078,1.757],[0.81,0.889],[1.464,0],[0,0],[-0.625,0.488],[-0.889,0.264],[-2.225,0],[-1.24,-1.444],[0,-2.596],[1.142,-1.445],[1.991,0],[1.112,1.328],[0,0.567]],"v":[[6.308,0.687],[-3.997,0.687],[-2.664,4.654],[0.776,5.986],[4.786,4.815],[5.695,6.689],[3.425,7.816],[0.63,8.212],[-4.568,6.045],[-6.427,0.014],[-4.714,-6.046],[0.102,-8.213],[4.758,-6.222],[6.427,-0.66]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[640.932,528.582],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 30","np":4,"cix":2,"ix":30,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.468,-0.547],[-0.977,0],[-0.547,0.176],[0,0],[0.878,0]],"o":[[-0.82,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.469,0.546],[0.526,0],[0,0],[-0.721,0.235],[-1.601,0]],"v":[[-1.067,8.958],[-2.297,5.08],[-2.297,-3.616],[-4.962,-3.616],[-4.962,-5.636],[-2.297,-5.636],[-2.297,-10.261],[0.075,-10.261],[0.075,-5.636],[4.758,-5.636],[4.758,-3.616],[0.075,-3.616],[0.075,4.729],[0.777,7.305],[2.944,8.125],[4.554,7.861],[4.963,9.91],[2.563,10.262]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[625.94,526.387],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 31","np":2,"cix":2,"ix":31,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.85,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.537,0.498],[1.034,0],[0.625,-0.243],[0.624,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.849,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.742,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.705],[5.914,-3.031],[5.914,8.036],[3.543,8.036],[3.543,-2.826],[2.738,-5.006],[0.381,-5.753],[-1.669,-5.388],[-3.542,-4.26],[-3.542,8.036],[-5.914,8.036],[-5.914,-7.656],[-3.717,-7.656],[-3.717,-5.929],[1.083,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[610.642,528.407],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 32","np":2,"cix":2,"ix":32,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.216,-10.598],[1.216,-10.598],[1.216,10.598],[-1.216,10.598]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[596.692,525.844],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 33","np":2,"cix":2,"ix":33,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[6.383,8.402],[6.383,10.598],[-6.383,10.598],[-6.383,-10.598],[6.03,-10.598],[6.03,-8.403],[-3.952,-8.403],[-3.952,-1.347],[3.513,-1.347],[3.513,0.878],[-3.952,0.878],[-3.952,8.402]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[575.681,525.845],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 34","np":2,"cix":2,"ix":34,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":42,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"E Interpolation_04 Spatial Bezier Interpolation","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[324.499,555.091,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[72.458,72.458,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.85,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.537,0.498],[1.034,0],[0.625,-0.243],[0.624,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.849,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.742,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.704],[5.914,-3.031],[5.914,8.036],[3.543,8.036],[3.543,-2.825],[2.738,-5.006],[0.381,-5.752],[-1.669,-5.387],[-3.542,-4.26],[-3.542,8.036],[-5.914,8.036],[-5.914,-7.656],[-3.717,-7.656],[-3.717,-5.928],[1.083,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1238.255,596.656],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.089]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1220.22,596.847],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.172,-4.831],[1.2,-4.831],[1.2,10.861],[-1.172,10.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.283,0.292],[0,0.527],[-0.283,0.293],[-0.526,0],[-0.284,-0.293],[0,-0.507],[0.282,-0.293],[0.527,0]],"o":[[-0.283,-0.293],[0,-0.527],[0.283,-0.293],[0.527,0],[0.282,0.293],[0,0.547],[-0.284,0.292],[-0.526,0]],"v":[[-1.215,-7.963],[-1.64,-9.193],[-1.215,-10.422],[0,-10.861],[1.216,-10.422],[1.64,-9.222],[1.216,-7.963],[0,-7.524]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1206.839,593.831],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":4,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.469,-0.547],[-0.976,0],[-0.547,0.176],[0,0],[0.879,0]],"o":[[-0.819,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.468,0.546],[0.527,0],[0,0],[-0.722,0.235],[-1.601,0]],"v":[[-1.068,8.958],[-2.297,5.079],[-2.297,-3.616],[-4.962,-3.616],[-4.962,-5.636],[-2.297,-5.636],[-2.297,-10.261],[0.074,-10.261],[0.074,-5.636],[4.758,-5.636],[4.758,-3.616],[0.074,-3.616],[0.074,4.729],[0.777,7.305],[2.943,8.125],[4.553,7.86],[4.963,9.91],[2.562,10.261]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1195.902,594.637],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.653,0.303],[-0.566,0.625],[0,0],[1.142,-0.547],[0,-1.171],[-0.517,-0.458],[-1.014,0]],"o":[[0.654,-0.302],[0,0],[-2.439,0.02],[-1.142,0.547],[0,0.898],[0.517,0.459],[0.8,0]],"v":[[1.727,5.606],[3.557,4.215],[3.557,-0.088],[-1.816,0.761],[-3.528,3.337],[-2.752,5.372],[-0.454,6.06]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-0.849],[0,-1.64],[0,0],[0,0],[0,0],[2.128,0],[0.859,0.82],[0,1.483],[-1.522,0.878],[-3.26,0.02],[0,0],[0.614,0.507],[1.191,0],[1.151,-0.546],[0,0],[-1.639,0]],"o":[[1.034,0.849],[0,0],[0,0],[0,0],[-1.015,1.542],[-1.562,0],[-0.859,-0.819],[0,-1.874],[1.523,-0.879],[0,0],[0,-0.975],[-0.615,-0.508],[-1.307,0],[0,0],[1.424,-0.721],[1.717,0]],"v":[[4.348,-6.924],[5.9,-3.191],[5.9,7.875],[3.733,7.875],[3.733,5.884],[-0.981,8.197],[-4.611,6.967],[-5.9,3.513],[-3.616,-0.615],[3.557,-1.962],[3.557,-2.987],[2.635,-5.211],[-0.073,-5.973],[-3.762,-5.153],[-4.377,-7.115],[0.219,-8.198]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1180.678,596.817],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":4,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,2.323],[0,0],[0,0],[0,0],[-0.254,-0.243],[-0.547,0],[-0.41,0.079],[0,0],[0.644,0]],"o":[[0,0],[0,0],[0,0],[0,0.547],[0.254,0.245],[0.351,0],[0,0],[-0.625,0.156],[-2.283,0]],"v":[[-2.665,7.875],[-2.665,-11.359],[-0.293,-11.359],[-0.293,7.67],[0.087,8.855],[1.288,9.222],[2.43,9.104],[2.664,11.125],[0.761,11.359]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1168.511,593.509],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.089]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1153.784,596.847],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":4,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.654,0.995],[0,1.971],[0.683,1.025],[1.347,0],[0.595,-0.293],[0.546,-0.625],[0,0],[-0.673,-0.302],[-0.742,0]],"o":[[0.653,-0.996],[0,-1.991],[-0.684,-1.024],[-0.723,0],[-0.595,0.293],[0,0],[0.487,0.546],[0.674,0.303],[1.288,0]],"v":[[2.855,1.728],[3.835,-2.722],[2.811,-7.246],[-0.234,-8.782],[-2.21,-8.344],[-3.922,-6.967],[-3.922,1.494],[-2.181,2.766],[-0.058,3.221]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-1.464],[0,-2.616],[1.083,-1.435],[1.951,0],[0.694,0.312],[0.487,0.566],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.761,0.409],[-0.957,0]],"o":[[1.034,1.464],[0,2.557],[-1.084,1.434],[-0.821,0],[-0.692,-0.312],[0,0],[0,0],[0,0],[0,0],[0,0],[0.526,-0.8],[0.761,-0.41],[1.853,0]],"v":[[4.744,-8.87],[6.294,-2.751],[4.67,3.236],[0.118,5.387],[-2.152,4.919],[-3.922,3.602],[-3.922,11.067],[-6.294,11.067],[-6.294,-10.686],[-4.098,-10.686],[-4.098,-8.636],[-2.166,-10.451],[0.411,-11.066]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1136.45,599.686],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":4,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.586,-0.253],[0,0],[0.605,0],[0.556,-0.312],[0.449,-0.663],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.717,0]],"o":[[0,0],[-0.742,-0.214],[-0.742,0],[-0.556,0.313],[0,0],[0,0],[0,0],[0,0],[0,0],[1.114,-1.678],[0.704,0]],"v":[[4.187,-7.627],[3.659,-5.314],[1.639,-5.636],[-0.307,-5.168],[-1.816,-3.704],[-1.816,8.007],[-4.187,8.007],[-4.187,-7.686],[-1.992,-7.686],[-1.992,-5.49],[2.253,-8.007]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1121.342,596.686],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":2,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.273,-3.221],[0,0],[0.702,0.849],[1.229,0]],"o":[[0,0],[-0.019,-1.522],[-0.703,-0.849],[-2.402,0]],"v":[[-3.967,-1.245],[4.026,-1.245],[2.943,-4.801],[0.045,-6.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.078,-0.331],[0,0],[-0.81,-0.888],[-1.483,0],[-1.21,0.781],[0,0],[0.887,-0.264],[0.975,0],[1.24,1.444],[0,2.576],[-1.142,1.444],[-2.069,0],[-1.113,-1.327],[0,-2.38]],"o":[[0,0],[0.078,1.757],[0.81,0.889],[1.464,0],[0,0],[-0.625,0.488],[-0.889,0.264],[-2.225,0],[-1.24,-1.444],[0,-2.596],[1.142,-1.445],[1.991,0],[1.112,1.328],[0,0.567]],"v":[[6.308,0.688],[-3.996,0.688],[-2.664,4.654],[0.776,5.987],[4.786,4.815],[5.695,6.69],[3.426,7.816],[0.63,8.212],[-4.568,6.045],[-6.427,0.014],[-4.714,-6.045],[0.103,-8.212],[4.758,-6.221],[6.427,-0.659]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1105.34,596.832],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10","np":4,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.468,-0.547],[-0.977,0],[-0.547,0.176],[0,0],[0.878,0]],"o":[[-0.82,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.469,0.546],[0.526,0],[0,0],[-0.721,0.235],[-1.601,0]],"v":[[-1.067,8.958],[-2.297,5.079],[-2.297,-3.616],[-4.962,-3.616],[-4.962,-5.636],[-2.297,-5.636],[-2.297,-10.261],[0.075,-10.261],[0.075,-5.636],[4.758,-5.636],[4.758,-3.616],[0.075,-3.616],[0.075,4.729],[0.777,7.305],[2.944,8.125],[4.554,7.86],[4.963,9.91],[2.563,10.261]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1090.349,594.637],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11","np":2,"cix":2,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.849,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.536,0.498],[1.035,0],[0.624,-0.243],[0.625,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.85,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.741,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.704],[5.914,-3.031],[5.914,8.036],[3.543,8.036],[3.543,-2.825],[2.739,-5.006],[0.381,-5.752],[-1.668,-5.387],[-3.542,-4.26],[-3.542,8.036],[-5.913,8.036],[-5.913,-7.656],[-3.717,-7.656],[-3.717,-5.928],[1.084,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1075.05,596.656],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12","np":2,"cix":2,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.215,-10.598],[1.215,-10.598],[1.215,10.598],[-1.215,10.598]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1061.099,594.094],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":2,"cix":2,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.585,-0.253],[0,0],[0.605,0],[0.555,-0.312],[0.448,-0.663],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.717,0]],"o":[[0,0],[-0.743,-0.214],[-0.742,0],[-0.557,0.313],[0,0],[0,0],[0,0],[0,0],[0,0],[1.113,-1.678],[0.703,0]],"v":[[4.187,-7.627],[3.661,-5.314],[1.639,-5.636],[-0.307,-5.168],[-1.815,-3.704],[-1.815,8.007],[-4.187,8.007],[-4.187,-7.686],[-1.99,-7.686],[-1.99,-5.49],[2.255,-8.007]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1042.929,596.686],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 14","np":2,"cix":2,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.273,-3.221],[0,0],[0.703,0.849],[1.229,0]],"o":[[0,0],[-0.019,-1.522],[-0.702,-0.849],[-2.401,0]],"v":[[-3.967,-1.245],[4.024,-1.245],[2.942,-4.801],[0.043,-6.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.078,-0.331],[0,0],[-0.811,-0.888],[-1.484,0],[-1.211,0.781],[0,0],[0.887,-0.264],[0.975,0],[1.24,1.444],[0,2.576],[-1.142,1.444],[-2.069,0],[-1.113,-1.327],[0,-2.38]],"o":[[0,0],[0.078,1.757],[0.809,0.889],[1.464,0],[0,0],[-0.625,0.488],[-0.889,0.264],[-2.226,0],[-1.239,-1.444],[0,-2.596],[1.143,-1.445],[1.992,0],[1.112,1.328],[0,0.567]],"v":[[6.308,0.688],[-3.997,0.688],[-2.665,4.654],[0.776,5.987],[4.786,4.815],[5.693,6.69],[3.425,7.816],[0.63,8.212],[-4.568,6.045],[-6.427,0.014],[-4.714,-6.045],[0.101,-8.212],[4.757,-6.221],[6.427,-0.659]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1026.928,596.832],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 15","np":4,"cix":2,"ix":15,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.172,-4.831],[1.199,-4.831],[1.199,10.861],[-1.172,10.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.283,0.292],[0,0.527],[-0.283,0.293],[-0.527,0],[-0.283,-0.293],[0,-0.507],[0.283,-0.293],[0.528,0]],"o":[[-0.283,-0.293],[0,-0.527],[0.283,-0.293],[0.528,0],[0.283,0.293],[0,0.547],[-0.283,0.292],[-0.527,0]],"v":[[-1.216,-7.963],[-1.64,-9.193],[-1.216,-10.422],[-0.001,-10.861],[1.214,-10.422],[1.639,-9.222],[1.214,-7.963],[-0.001,-7.524]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1013.738,593.831],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 16","np":4,"cix":2,"ix":16,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[5.548,5.826],[5.548,7.846],[-5.548,7.846],[-5.548,5.826],[2.737,-5.826],[-5.313,-5.826],[-5.313,-7.846],[5.431,-7.846],[5.431,-5.826],[-2.825,5.826]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1001.718,596.847],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 17","np":2,"cix":2,"ix":17,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.273,-3.221],[0,0],[0.702,0.849],[1.229,0]],"o":[[0,0],[-0.019,-1.522],[-0.703,-0.849],[-2.402,0]],"v":[[-3.967,-1.245],[4.026,-1.245],[2.943,-4.801],[0.044,-6.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.078,-0.331],[0,0],[-0.81,-0.888],[-1.483,0],[-1.21,0.781],[0,0],[0.887,-0.264],[0.975,0],[1.24,1.444],[0,2.576],[-1.142,1.444],[-2.069,0],[-1.113,-1.327],[0,-2.38]],"o":[[0,0],[0.078,1.757],[0.81,0.889],[1.464,0],[0,0],[-0.625,0.488],[-0.889,0.264],[-2.225,0],[-1.24,-1.444],[0,-2.596],[1.142,-1.445],[1.991,0],[1.112,1.328],[0,0.567]],"v":[[6.308,0.688],[-3.997,0.688],[-2.664,4.654],[0.776,5.987],[4.786,4.815],[5.695,6.69],[3.425,7.816],[0.63,8.212],[-4.568,6.045],[-6.427,0.014],[-4.714,-6.045],[0.102,-8.212],[4.758,-6.221],[6.427,-0.659]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[985.79,596.832],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 18","np":4,"cix":2,"ix":18,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.645,0.645],[0,1.269],[0.663,0.634],[1.288,0],[0,0],[0,0],[0,0]],"o":[[0.644,-0.644],[0,-1.249],[-0.664,-0.634],[0,0],[0,0],[0,0],[1.249,0]],"v":[[3.777,7.436],[4.742,4.567],[3.747,1.742],[0.82,0.79],[-4.86,0.79],[-4.86,8.402],[0.937,8.402]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.644,0.576],[0,1.132],[0.663,0.615],[1.288,0]],"o":[[0,0],[0,0],[1.249,0],[0.644,-0.576],[0,-1.19],[-0.664,-0.615],[0,0]],"v":[[-4.86,-8.402],[-4.86,-1.347],[-0.234,-1.347],[2.606,-2.21],[3.572,-4.772],[2.577,-7.48],[-0.352,-8.402]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,-2.752],[1.141,-1.063],[2.029,0],[0,0],[0,0],[0,0],[-1.113,-1.014],[0,-1.835],[0.458,-0.712],[0.897,-0.273]],"o":[[0,1.893],[-1.143,1.064],[0,0],[0,0],[0,0],[1.99,0],[1.113,1.015],[0,1.112],[-0.459,0.713],[2.615,0.683]],"v":[[7.289,4.567],[5.578,9.002],[0.82,10.598],[-7.289,10.598],[-7.289,-10.598],[-0.234,-10.598],[4.421,-9.076],[6.09,-4.801],[5.402,-2.064],[3.367,-0.585]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[967.71,594.095],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 19","np":5,"cix":2,"ix":19,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,2.323],[0,0],[0,0],[0,0],[-0.254,-0.243],[-0.547,0],[-0.41,0.079],[0,0],[0.644,0]],"o":[[0,0],[0,0],[0,0],[0,0.547],[0.254,0.245],[0.351,0],[0,0],[-0.625,0.156],[-2.283,0]],"v":[[-2.664,7.875],[-2.664,-11.359],[-0.293,-11.359],[-0.293,7.67],[0.087,8.855],[1.288,9.222],[2.43,9.104],[2.664,11.125],[0.761,11.359]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[944.636,593.509],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 20","np":2,"cix":2,"ix":20,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.653,0.303],[-0.566,0.625],[0,0],[1.142,-0.547],[0,-1.171],[-0.517,-0.458],[-1.014,0]],"o":[[0.654,-0.302],[0,0],[-2.439,0.02],[-1.142,0.547],[0,0.898],[0.517,0.459],[0.8,0]],"v":[[1.727,5.606],[3.557,4.215],[3.557,-0.088],[-1.815,0.761],[-3.528,3.337],[-2.752,5.372],[-0.454,6.06]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-0.849],[0,-1.64],[0,0],[0,0],[0,0],[2.128,0],[0.859,0.82],[0,1.483],[-1.522,0.878],[-3.26,0.02],[0,0],[0.614,0.507],[1.191,0],[1.151,-0.546],[0,0],[-1.639,0]],"o":[[1.034,0.849],[0,0],[0,0],[0,0],[-1.015,1.542],[-1.562,0],[-0.859,-0.819],[0,-1.874],[1.523,-0.879],[0,0],[0,-0.975],[-0.615,-0.508],[-1.307,0],[0,0],[1.424,-0.721],[1.717,0]],"v":[[4.348,-6.924],[5.9,-3.191],[5.9,7.875],[3.733,7.875],[3.733,5.884],[-0.981,8.197],[-4.611,6.967],[-5.899,3.513],[-3.616,-0.615],[3.557,-1.962],[3.557,-2.987],[2.635,-5.211],[-0.073,-5.973],[-3.762,-5.153],[-4.377,-7.115],[0.22,-8.198]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[929.689,596.817],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 21","np":4,"cix":2,"ix":21,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.172,-4.831],[1.2,-4.831],[1.2,10.861],[-1.172,10.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.283,0.292],[0,0.527],[-0.284,0.293],[-0.526,0],[-0.283,-0.293],[0,-0.507],[0.282,-0.293],[0.528,0]],"o":[[-0.284,-0.293],[0,-0.527],[0.283,-0.293],[0.528,0],[0.282,0.293],[0,0.547],[-0.283,0.292],[-0.526,0]],"v":[[-1.215,-7.963],[-1.639,-9.193],[-1.215,-10.422],[-0.001,-10.861],[1.215,-10.422],[1.639,-9.222],[1.215,-7.963],[-0.001,-7.524]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[917.318,593.831],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 22","np":4,"cix":2,"ix":22,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.468,-0.547],[-0.977,0],[-0.547,0.176],[0,0],[0.878,0]],"o":[[-0.82,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.469,0.546],[0.526,0],[0,0],[-0.721,0.235],[-1.601,0]],"v":[[-1.068,8.958],[-2.298,5.079],[-2.298,-3.616],[-4.963,-3.616],[-4.963,-5.636],[-2.298,-5.636],[-2.298,-10.261],[0.074,-10.261],[0.074,-5.636],[4.757,-5.636],[4.757,-3.616],[0.074,-3.616],[0.074,4.729],[0.776,7.305],[2.943,8.125],[4.553,7.86],[4.962,9.91],[2.562,10.261]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[906.381,594.637],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 23","np":2,"cix":2,"ix":23,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.654,0.303],[-0.566,0.625],[0,0],[1.143,-0.547],[0,-1.171],[-0.518,-0.458],[-1.015,0]],"o":[[0.653,-0.302],[0,0],[-2.44,0.02],[-1.142,0.547],[0,0.898],[0.516,0.459],[0.8,0]],"v":[[1.728,5.606],[3.557,4.215],[3.557,-0.088],[-1.815,0.761],[-3.527,3.337],[-2.751,5.372],[-0.453,6.06]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.034,-0.849],[0,-1.64],[0,0],[0,0],[0,0],[2.127,0],[0.86,0.82],[0,1.483],[-1.522,0.878],[-3.26,0.02],[0,0],[0.615,0.507],[1.191,0],[1.151,-0.546],[0,0],[-1.639,0]],"o":[[1.034,0.849],[0,0],[0,0],[0,0],[-1.016,1.542],[-1.562,0],[-0.858,-0.819],[0,-1.874],[1.523,-0.879],[0,0],[0,-0.975],[-0.614,-0.508],[-1.307,0],[0,0],[1.424,-0.721],[1.718,0]],"v":[[4.348,-6.924],[5.9,-3.191],[5.9,7.875],[3.734,7.875],[3.734,5.884],[-0.98,8.197],[-4.612,6.967],[-5.899,3.513],[-3.615,-0.615],[3.557,-1.962],[3.557,-2.987],[2.635,-5.211],[-0.073,-5.973],[-3.761,-5.153],[-4.376,-7.115],[0.219,-8.198]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[891.156,596.817],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 24","np":4,"cix":2,"ix":24,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.654,0.995],[0,1.971],[0.683,1.025],[1.347,0],[0.595,-0.293],[0.546,-0.625],[0,0],[-0.673,-0.302],[-0.742,0]],"o":[[0.653,-0.996],[0,-1.991],[-0.684,-1.024],[-0.723,0],[-0.595,0.293],[0,0],[0.487,0.546],[0.674,0.303],[1.288,0]],"v":[[2.855,1.728],[3.835,-2.722],[2.811,-7.246],[-0.234,-8.782],[-2.21,-8.344],[-3.922,-6.967],[-3.922,1.494],[-2.181,2.766],[-0.058,3.221]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-1.464],[0,-2.616],[1.083,-1.435],[1.951,0],[0.694,0.312],[0.487,0.566],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.761,0.409],[-0.957,0]],"o":[[1.034,1.464],[0,2.557],[-1.084,1.434],[-0.821,0],[-0.692,-0.312],[0,0],[0,0],[0,0],[0,0],[0,0],[0.526,-0.8],[0.761,-0.41],[1.853,0]],"v":[[4.744,-8.87],[6.294,-2.751],[4.67,3.236],[0.118,5.387],[-2.152,4.919],[-3.922,3.602],[-3.922,11.067],[-6.294,11.067],[-6.294,-10.686],[-4.098,-10.686],[-4.098,-8.636],[-2.166,-10.451],[0.411,-11.066]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[874.832,599.686],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 25","np":4,"cix":2,"ix":25,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.151,0.293],[0.879,0.547],[0,0],[-1.952,0],[-0.81,0.634],[0,1.131],[0.546,0.596],[1.132,0.293],[0,0],[0.839,0.946],[0,1.523],[-1.2,1.064],[-2.068,0],[-1.073,-0.224],[-0.897,-0.429],[0,0],[1.561,0],[0.731,-0.595],[0,-1.054],[-0.537,-0.595],[-1.132,-0.292],[0,0],[-0.85,-0.936],[0,-1.522],[1.269,-1.102],[2.186,0]],"o":[[-1.151,-0.292],[0,0],[1.834,1.053],[1.464,0],[0.809,-0.634],[0,-0.956],[-0.547,-0.595],[0,0],[-1.796,-0.488],[-0.839,-0.947],[0,-1.815],[1.2,-1.064],[1.035,0],[1.074,0.225],[0,0],[-1.991,-0.801],[-1.327,0],[-0.733,0.596],[0,0.957],[0.536,0.596],[0,0],[1.796,0.507],[0.849,0.937],[0,1.894],[-1.269,1.103],[-1.171,0]],"v":[[-3.762,10.51],[-6.807,9.251],[-5.957,7.173],[-0.278,8.754],[3.133,7.802],[4.347,5.153],[3.528,2.825],[1.01,1.493],[-1.391,0.82],[-5.343,-1.332],[-6.602,-5.036],[-4.801,-9.354],[0.102,-10.949],[3.264,-10.613],[6.221,-9.632],[5.373,-7.553],[0.044,-8.754],[-3.044,-7.861],[-4.143,-5.387],[-3.337,-3.06],[-0.834,-1.728],[1.566,-1.054],[5.534,1.112],[6.807,4.801],[4.904,9.295],[-0.278,10.949]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[856.226,594.095],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 26","np":2,"cix":2,"ix":26,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[2.137,3.865],[2.137,-8.343],[-4.655,3.865]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[7.231,3.865],[7.231,6.002],[4.479,6.002],[4.479,10.598],[2.137,10.598],[2.137,6.002],[-7.231,6.002],[-7.231,3.865],[1.083,-10.598],[4.479,-10.598],[4.479,3.865]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[830.094,594.094],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 27","np":4,"cix":2,"ix":27,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.742,1.425],[0,3.025],[0.741,1.425],[1.581,0],[0.741,-1.425],[0,-3.025],[-0.743,-1.425],[-1.581,0]],"o":[[0.741,-1.425],[0,-3.025],[-0.742,-1.425],[-1.562,0],[-0.743,1.425],[0,3.025],[0.741,1.425],[1.561,0]],"v":[[3.47,6.676],[4.582,0.001],[3.47,-6.674],[-0.014,-8.811],[-3.469,-6.674],[-4.581,0.001],[-3.469,6.676],[0.015,8.813]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.171,1.786],[0,3.747],[-1.161,1.786],[-2.381,0],[-1.172,-1.786],[0,-3.748],[1.161,-1.786],[2.381,0]],"o":[[-1.171,-1.786],[0,-3.748],[1.161,-1.786],[2.38,0],[1.171,1.786],[0,3.747],[-1.162,1.786],[-2.381,0]],"v":[[-5.313,8.301],[-7.07,0.001],[-5.328,-8.299],[-0.014,-10.978],[5.315,-8.299],[7.07,0.001],[5.328,8.301],[0.015,10.979]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[811.516,594.094],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 28","np":4,"cix":2,"ix":28,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-5.958,-1.113],[5.958,-1.113],[5.958,1.112],[-5.958,1.112]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[792.338,607.943],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 29","np":2,"cix":2,"ix":29,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.849,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.536,0.498],[1.035,0],[0.624,-0.243],[0.625,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.85,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.741,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.704],[5.913,-3.031],[5.913,8.036],[3.542,8.036],[3.542,-2.825],[2.738,-5.006],[0.38,-5.752],[-1.669,-5.387],[-3.543,-4.26],[-3.543,8.036],[-5.914,8.036],[-5.914,-7.656],[-3.718,-7.656],[-3.718,-5.928],[1.083,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[773.848,596.656],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 30","np":2,"cix":2,"ix":30,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.089]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[755.812,596.847],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 31","np":4,"cix":2,"ix":31,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.171,-4.831],[1.201,-4.831],[1.201,10.861],[-1.171,10.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.283,0.292],[0,0.527],[-0.283,0.293],[-0.527,0],[-0.283,-0.293],[0,-0.507],[0.283,-0.293],[0.527,0]],"o":[[-0.283,-0.293],[0,-0.527],[0.283,-0.293],[0.527,0],[0.283,0.293],[0,0.547],[-0.283,0.292],[-0.527,0]],"v":[[-1.215,-7.963],[-1.639,-9.193],[-1.215,-10.422],[0,-10.861],[1.215,-10.422],[1.639,-9.222],[1.215,-7.963],[0,-7.524]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[742.431,593.831],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 32","np":4,"cix":2,"ix":32,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.469,-0.547],[-0.976,0],[-0.547,0.176],[0,0],[0.879,0]],"o":[[-0.819,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.468,0.546],[0.527,0],[0,0],[-0.722,0.235],[-1.601,0]],"v":[[-1.068,8.958],[-2.297,5.079],[-2.297,-3.616],[-4.963,-3.616],[-4.963,-5.636],[-2.297,-5.636],[-2.297,-10.261],[0.073,-10.261],[0.073,-5.636],[4.758,-5.636],[4.758,-3.616],[0.073,-3.616],[0.073,4.729],[0.776,7.305],[2.943,8.125],[4.552,7.86],[4.962,9.91],[2.561,10.261]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[731.494,594.637],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 33","np":2,"cix":2,"ix":33,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.653,0.303],[-0.566,0.625],[0,0],[1.142,-0.547],[0,-1.171],[-0.517,-0.458],[-1.014,0]],"o":[[0.654,-0.302],[0,0],[-2.439,0.02],[-1.142,0.547],[0,0.898],[0.517,0.459],[0.8,0]],"v":[[1.727,5.606],[3.557,4.215],[3.557,-0.088],[-1.815,0.761],[-3.528,3.337],[-2.752,5.372],[-0.454,6.06]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-0.849],[0,-1.64],[0,0],[0,0],[0,0],[2.128,0],[0.859,0.82],[0,1.483],[-1.522,0.878],[-3.26,0.02],[0,0],[0.614,0.507],[1.191,0],[1.151,-0.546],[0,0],[-1.639,0]],"o":[[1.034,0.849],[0,0],[0,0],[0,0],[-1.015,1.542],[-1.562,0],[-0.859,-0.819],[0,-1.874],[1.523,-0.879],[0,0],[0,-0.975],[-0.615,-0.508],[-1.307,0],[0,0],[1.424,-0.721],[1.717,0]],"v":[[4.348,-6.924],[5.9,-3.191],[5.9,7.875],[3.733,7.875],[3.733,5.884],[-0.981,8.197],[-4.611,6.967],[-5.899,3.513],[-3.616,-0.615],[3.557,-1.962],[3.557,-2.987],[2.635,-5.211],[-0.073,-5.973],[-3.762,-5.153],[-4.377,-7.115],[0.22,-8.198]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[716.27,596.817],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 34","np":4,"cix":2,"ix":34,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,2.323],[0,0],[0,0],[0,0],[-0.254,-0.243],[-0.547,0],[-0.41,0.079],[0,0],[0.644,0]],"o":[[0,0],[0,0],[0,0],[0,0.547],[0.254,0.245],[0.351,0],[0,0],[-0.625,0.156],[-2.283,0]],"v":[[-2.664,7.875],[-2.664,-11.359],[-0.293,-11.359],[-0.293,7.67],[0.087,8.855],[1.288,9.222],[2.43,9.104],[2.664,11.125],[0.761,11.359]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[704.103,593.509],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 35","np":2,"cix":2,"ix":35,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.089]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[689.376,596.847],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 36","np":4,"cix":2,"ix":36,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.654,0.995],[0,1.971],[0.683,1.025],[1.347,0],[0.595,-0.293],[0.546,-0.625],[0,0],[-0.673,-0.302],[-0.742,0]],"o":[[0.653,-0.996],[0,-1.991],[-0.684,-1.024],[-0.723,0],[-0.595,0.293],[0,0],[0.487,0.546],[0.674,0.303],[1.288,0]],"v":[[2.855,1.728],[3.835,-2.722],[2.811,-7.246],[-0.234,-8.782],[-2.21,-8.344],[-3.922,-6.967],[-3.922,1.494],[-2.181,2.766],[-0.058,3.221]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-1.464],[0,-2.616],[1.083,-1.435],[1.951,0],[0.694,0.312],[0.487,0.566],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.761,0.409],[-0.957,0]],"o":[[1.034,1.464],[0,2.557],[-1.084,1.434],[-0.821,0],[-0.692,-0.312],[0,0],[0,0],[0,0],[0,0],[0,0],[0.526,-0.8],[0.761,-0.41],[1.853,0]],"v":[[4.744,-8.87],[6.294,-2.751],[4.67,3.236],[0.118,5.387],[-2.152,4.919],[-3.922,3.602],[-3.922,11.067],[-6.294,11.067],[-6.294,-10.686],[-4.098,-10.686],[-4.098,-8.636],[-2.166,-10.451],[0.411,-11.066]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[672.041,599.686],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 37","np":4,"cix":2,"ix":37,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.586,-0.253],[0,0],[0.605,0],[0.556,-0.312],[0.449,-0.663],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.717,0]],"o":[[0,0],[-0.742,-0.214],[-0.742,0],[-0.556,0.313],[0,0],[0,0],[0,0],[0,0],[0,0],[1.114,-1.678],[0.704,0]],"v":[[4.187,-7.627],[3.659,-5.314],[1.639,-5.636],[-0.307,-5.168],[-1.815,-3.704],[-1.815,8.007],[-4.187,8.007],[-4.187,-7.686],[-1.992,-7.686],[-1.992,-5.49],[2.253,-8.007]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[656.934,596.686],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 38","np":2,"cix":2,"ix":38,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.273,-3.221],[0,0],[0.702,0.849],[1.229,0]],"o":[[0,0],[-0.019,-1.522],[-0.703,-0.849],[-2.402,0]],"v":[[-3.967,-1.245],[4.026,-1.245],[2.943,-4.801],[0.044,-6.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.078,-0.331],[0,0],[-0.81,-0.888],[-1.483,0],[-1.21,0.781],[0,0],[0.887,-0.264],[0.975,0],[1.24,1.444],[0,2.576],[-1.142,1.444],[-2.069,0],[-1.113,-1.327],[0,-2.38]],"o":[[0,0],[0.078,1.757],[0.81,0.889],[1.464,0],[0,0],[-0.625,0.488],[-0.889,0.264],[-2.225,0],[-1.24,-1.444],[0,-2.596],[1.142,-1.445],[1.991,0],[1.112,1.328],[0,0.567]],"v":[[6.308,0.688],[-3.997,0.688],[-2.664,4.654],[0.776,5.987],[4.786,4.815],[5.695,6.69],[3.425,7.816],[0.63,8.212],[-4.568,6.045],[-6.427,0.014],[-4.714,-6.045],[0.102,-8.212],[4.758,-6.221],[6.427,-0.659]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[640.932,596.832],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 39","np":4,"cix":2,"ix":39,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.468,-0.547],[-0.977,0],[-0.547,0.176],[0,0],[0.878,0]],"o":[[-0.82,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.469,0.546],[0.526,0],[0,0],[-0.721,0.235],[-1.601,0]],"v":[[-1.067,8.958],[-2.297,5.079],[-2.297,-3.616],[-4.962,-3.616],[-4.962,-5.636],[-2.297,-5.636],[-2.297,-10.261],[0.075,-10.261],[0.075,-5.636],[4.758,-5.636],[4.758,-3.616],[0.075,-3.616],[0.075,4.729],[0.777,7.305],[2.944,8.125],[4.554,7.86],[4.963,9.91],[2.563,10.261]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[625.94,594.637],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 40","np":2,"cix":2,"ix":40,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.85,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.537,0.498],[1.034,0],[0.625,-0.243],[0.624,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.849,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.742,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.704],[5.914,-3.031],[5.914,8.036],[3.543,8.036],[3.543,-2.825],[2.738,-5.006],[0.381,-5.752],[-1.669,-5.387],[-3.542,-4.26],[-3.542,8.036],[-5.914,8.036],[-5.914,-7.656],[-3.717,-7.656],[-3.717,-5.928],[1.083,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[610.642,596.656],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 41","np":2,"cix":2,"ix":41,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.216,-10.598],[1.216,-10.598],[1.216,10.598],[-1.216,10.598]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[596.692,594.094],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 42","np":2,"cix":2,"ix":42,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[6.383,8.402],[6.383,10.598],[-6.383,10.598],[-6.383,-10.598],[6.03,-10.598],[6.03,-8.403],[-3.952,-8.403],[-3.952,-1.347],[3.513,-1.347],[3.513,0.878],[-3.952,0.878],[-3.952,8.402]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[575.681,594.095],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 43","np":2,"cix":2,"ix":43,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":42,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"E Interpolation_05 Rove Across Time","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[964.374,505.638,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[72.458,72.458,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.273,-3.221],[0,0],[0.703,0.849],[1.229,0]],"o":[[0,0],[-0.019,-1.522],[-0.702,-0.849],[-2.401,0]],"v":[[-3.967,-1.245],[4.025,-1.245],[2.942,-4.801],[0.044,-6.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.078,-0.331],[0,0],[-0.811,-0.888],[-1.484,0],[-1.211,0.781],[0,0],[0.887,-0.264],[0.975,0],[1.24,1.444],[0,2.576],[-1.142,1.444],[-2.069,0],[-1.113,-1.327],[0,-2.38]],"o":[[0,0],[0.078,1.757],[0.809,0.889],[1.464,0],[0,0],[-0.625,0.488],[-0.889,0.264],[-2.226,0],[-1.239,-1.444],[0,-2.596],[1.143,-1.445],[1.992,0],[1.112,1.328],[0,0.567]],"v":[[6.308,0.688],[-3.996,0.688],[-2.664,4.654],[0.776,5.987],[4.786,4.815],[5.693,6.69],[3.426,7.816],[0.63,8.212],[-4.568,6.045],[-6.427,0.014],[-4.714,-6.045],[0.102,-8.212],[4.758,-6.221],[6.427,-0.659]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1091.986,665.082],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.82,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.507,0.498],[0.977,0],[0.624,-0.253],[0.625,-0.546],[0,-0.41],[0,0],[0,0],[0,0],[0.518,0.498],[0.976,0],[0.606,-0.243],[0.624,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.834,0],[-0.722,-0.419],[-0.352,-0.781],[-1.932,0]],"o":[[0.819,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.508,-0.498],[-0.702,0],[-0.625,0.254],[0.058,0.352],[0,0],[0,0],[0,0],[0,-0.956],[-0.516,-0.498],[-0.703,0],[-0.604,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[0.996,0],[0.722,0.42],[1.384,-1.62],[1.464,0]],"v":[[9.121,-6.704],[10.349,-3.031],[10.349,8.036],[7.978,8.036],[7.978,-2.825],[7.218,-5.006],[4.992,-5.752],[3.002,-5.372],[1.128,-4.172],[1.216,-3.031],[1.216,8.036],[-1.155,8.036],[-1.155,-2.825],[-1.932,-5.006],[-4.172,-5.752],[-6.133,-5.387],[-7.977,-4.26],[-7.977,8.036],[-10.349,8.036],[-10.349,-7.656],[-8.152,-7.656],[-8.152,-5.928],[-3.469,-8.036],[-0.892,-7.407],[0.719,-5.606],[5.695,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1069.85,664.906],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.171,-4.831],[1.201,-4.831],[1.201,10.861],[-1.171,10.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.283,0.292],[0,0.527],[-0.283,0.293],[-0.527,0],[-0.284,-0.293],[0,-0.507],[0.282,-0.293],[0.527,0]],"o":[[-0.283,-0.293],[0,-0.527],[0.283,-0.293],[0.527,0],[0.282,0.293],[0,0.547],[-0.284,0.292],[-0.527,0]],"v":[[-1.215,-7.963],[-1.639,-9.193],[-1.215,-10.422],[0,-10.861],[1.216,-10.422],[1.639,-9.222],[1.216,-7.963],[0,-7.524]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1051.595,662.081],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":4,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[6.836,-8.373],[1.215,-8.373],[1.215,10.598],[-1.215,10.598],[-1.215,-8.373],[-6.836,-8.373],[-6.836,-10.598],[6.836,-10.598]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1038.668,662.344],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.927,0.244],[0.703,0.45],[0,0],[-1.621,0],[-0.576,0.41],[0,0.8],[0.361,0.371],[0.781,0.195],[0,0],[0.683,0.712],[0,1.152],[-0.966,0.82],[-1.738,0],[-0.86,-0.214],[-0.683,-0.351],[0,0],[1.308,0],[0.527,-0.39],[0,-0.742],[-0.371,-0.361],[-0.782,-0.195],[0,0],[-0.673,-0.732],[0,-1.19],[1.014,-0.839],[1.795,0]],"o":[[-0.928,-0.244],[0,0],[1.367,0.86],[1.112,0],[0.575,-0.41],[0,-0.625],[-0.361,-0.371],[0,0],[-1.425,-0.332],[-0.683,-0.712],[0,-1.444],[0.967,-0.82],[0.859,0],[0.858,0.215],[0,0],[-1.367,-0.703],[-1.015,0],[-0.528,0.39],[0,0.586],[0.371,0.361],[0,0],[1.424,0.332],[0.674,0.732],[0,1.483],[-1.016,0.839],[-0.996,0]],"v":[[-3.089,7.831],[-5.534,6.792],[-4.685,4.771],[-0.205,6.06],[2.327,5.445],[3.19,3.63],[2.649,2.138],[0.936,1.289],[-1.143,0.79],[-4.304,-0.776],[-5.329,-3.571],[-3.88,-6.967],[0.175,-8.198],[2.752,-7.875],[5.064,-7.026],[4.128,-5.007],[0.116,-6.06],[-2.196,-5.475],[-2.986,-3.776],[-2.431,-2.357],[-0.703,-1.523],[1.376,-1.024],[4.522,0.57],[5.533,3.455],[4.011,6.939],[-0.205,8.198]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1014.76,665.097],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.927,0.244],[0.703,0.45],[0,0],[-1.621,0],[-0.576,0.41],[0,0.8],[0.361,0.371],[0.781,0.195],[0,0],[0.683,0.712],[0,1.152],[-0.966,0.82],[-1.738,0],[-0.86,-0.214],[-0.683,-0.351],[0,0],[1.308,0],[0.527,-0.39],[0,-0.742],[-0.371,-0.361],[-0.782,-0.195],[0,0],[-0.673,-0.732],[0,-1.19],[1.014,-0.839],[1.795,0]],"o":[[-0.928,-0.244],[0,0],[1.367,0.86],[1.112,0],[0.575,-0.41],[0,-0.625],[-0.361,-0.371],[0,0],[-1.425,-0.332],[-0.683,-0.712],[0,-1.444],[0.967,-0.82],[0.859,0],[0.858,0.215],[0,0],[-1.367,-0.703],[-1.015,0],[-0.528,0.39],[0,0.586],[0.371,0.361],[0,0],[1.424,0.332],[0.674,0.732],[0,1.483],[-1.016,0.839],[-0.996,0]],"v":[[-3.088,7.831],[-5.533,6.792],[-4.684,4.771],[-0.204,6.06],[2.328,5.445],[3.191,3.63],[2.65,2.138],[0.937,1.289],[-1.142,0.79],[-4.303,-0.776],[-5.328,-3.571],[-3.879,-6.967],[0.176,-8.198],[2.753,-7.875],[5.065,-7.026],[4.129,-5.007],[0.117,-6.06],[-2.195,-5.475],[-2.985,-3.776],[-2.43,-2.357],[-0.702,-1.523],[1.377,-1.024],[4.523,0.57],[5.534,3.455],[4.012,6.939],[-0.204,8.198]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[999.857,665.097],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.089]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[983.724,665.097],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":4,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.586,-0.253],[0,0],[0.605,0],[0.556,-0.312],[0.449,-0.663],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.717,0]],"o":[[0,0],[-0.742,-0.214],[-0.742,0],[-0.556,0.313],[0,0],[0,0],[0,0],[0,0],[0,0],[1.114,-1.678],[0.704,0]],"v":[[4.187,-7.627],[3.659,-5.314],[1.639,-5.636],[-0.307,-5.168],[-1.815,-3.704],[-1.815,8.007],[-4.187,8.007],[-4.187,-7.686],[-1.992,-7.686],[-1.992,-5.49],[2.253,-8.007]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[969.436,664.936],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.249,1.444],[0,2.576],[-0.576,1.24],[-1.044,0.683],[-1.366,0],[-0.78,-0.225],[-0.645,-0.409],[0,0],[1.151,0],[0.771,-1.025],[0,-1.834],[-0.81,-1.044],[-1.562,0],[-1.132,0.644],[0,0],[0.78,-0.225],[0.878,0]],"o":[[-1.249,-1.444],[0,-1.64],[0.575,-1.239],[1.044,-0.683],[0.78,0],[0.78,0.224],[0,0],[-1.268,-0.682],[-1.386,0],[-0.771,1.025],[0,2.03],[0.809,1.044],[1.171,0],[0,0],[-0.566,0.429],[-0.781,0.224],[-2.206,0]],"v":[[-3.909,6.046],[-5.782,0.015],[-4.919,-4.304],[-2.489,-7.187],[1.127,-8.212],[3.469,-7.875],[5.607,-6.924],[4.698,-4.992],[1.069,-6.016],[-2.167,-4.479],[-3.323,-0.19],[-2.108,4.421],[1.449,5.987],[4.904,5.021],[5.782,6.895],[3.762,7.876],[1.274,8.213]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[954.459,665.082],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":2,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[3.616,2.81],[-0.044,-8.022],[-3.674,2.81]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[4.346,4.978],[-4.406,4.978],[-6.281,10.599],[-8.885,10.599],[-1.362,-10.599],[1.361,-10.599],[8.885,10.599],[6.25,10.599]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[936.131,662.345],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10","np":4,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.273,-3.221],[0,0],[0.702,0.849],[1.229,0]],"o":[[0,0],[-0.019,-1.522],[-0.703,-0.849],[-2.402,0]],"v":[[-3.967,-1.245],[4.026,-1.245],[2.943,-4.801],[0.044,-6.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.078,-0.331],[0,0],[-0.81,-0.888],[-1.483,0],[-1.21,0.781],[0,0],[0.887,-0.264],[0.975,0],[1.24,1.444],[0,2.576],[-1.142,1.444],[-2.069,0],[-1.113,-1.327],[0,-2.38]],"o":[[0,0],[0.078,1.757],[0.81,0.889],[1.464,0],[0,0],[-0.625,0.488],[-0.889,0.264],[-2.225,0],[-1.24,-1.444],[0,-2.596],[1.142,-1.445],[1.991,0],[1.112,1.328],[0,0.567]],"v":[[6.308,0.688],[-3.997,0.688],[-2.664,4.654],[0.776,5.987],[4.786,4.815],[5.695,6.69],[3.425,7.816],[0.63,8.212],[-4.568,6.045],[-6.427,0.014],[-4.714,-6.045],[0.102,-8.212],[4.758,-6.221],[6.427,-0.659]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[909.251,665.082],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11","np":4,"cix":2,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[6.763,-7.846],[1.318,7.846],[-1.289,7.846],[-6.763,-7.846],[-4.187,-7.846],[0.058,5.3],[4.245,-7.846]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[892.371,665.096],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12","np":2,"cix":2,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.089]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[875.301,665.097],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":4,"cix":2,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.684,0.732],[0,1.444],[0.702,0.742],[1.366,0],[0,0]],"o":[[0,0],[1.327,0],[0.682,-0.732],[0,-1.425],[-0.703,-0.742],[0,0],[0,0]],"v":[[-4.904,0.322],[-0.278,0.322],[2.738,-0.776],[3.762,-4.04],[2.708,-7.29],[-0.395,-8.403],[-4.904,-8.403]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.161,-1.151],[0,-2.049],[0.78,-1.084],[1.464,-0.352],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[2.068,0],[1.161,1.152],[0,1.679],[-0.781,1.083],[0,0],[0,0],[0,0]],"v":[[-0.835,2.489],[-4.904,2.489],[-4.904,10.598],[-7.334,10.598],[-7.334,-10.598],[-0.278,-10.598],[4.567,-8.871],[6.309,-4.07],[5.138,0.073],[1.771,2.225],[7.333,10.598],[4.347,10.598]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[857.455,662.345],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 14","np":4,"cix":2,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.956,-0.556],[-0.518,-1.014],[0,-1.327],[0.585,-1.064],[1.073,-0.585],[1.406,0],[1.025,0.282],[0.722,0.468],[0,0],[-0.83,-0.244],[-0.742,0],[-0.821,0.84],[0,1.484],[0.77,0.8],[1.347,0],[0.625,-0.185],[0.468,-0.351],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.586,0.127],[-0.566,0]],"o":[[0.956,0.556],[0.517,1.016],[0,1.386],[-0.586,1.064],[-1.074,0.586],[-0.995,0],[-1.024,-0.283],[0,0],[0.721,0.429],[0.829,0.244],[1.425,0],[0.819,-0.839],[0,-1.424],[-0.772,-0.8],[-0.664,0],[-0.624,0.186],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.469,-0.214],[0.585,-0.127],[1.248,0]],"v":[[3.382,-2.107],[5.593,0.248],[6.367,3.763],[5.49,7.436],[3.002,9.91],[-0.718,10.789],[-3.747,10.365],[-6.367,9.237],[-5.401,7.159],[-3.073,8.169],[-0.718,8.534],[2.651,7.276],[3.88,3.792],[2.724,0.455],[-0.453,-0.747],[-2.386,-0.469],[-4.024,0.336],[-5.518,-0.482],[-4.875,-10.789],[5.461,-10.789],[5.461,-8.68],[-2.795,-8.68],[-3.234,-2.24],[-1.654,-2.752],[0.073,-2.941]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[829.698,662.535],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 15","np":2,"cix":2,"ix":15,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.742,1.425],[0,3.025],[0.741,1.425],[1.581,0],[0.741,-1.425],[0,-3.025],[-0.743,-1.425],[-1.581,0]],"o":[[0.741,-1.425],[0,-3.025],[-0.742,-1.425],[-1.562,0],[-0.743,1.425],[0,3.025],[0.741,1.425],[1.561,0]],"v":[[3.47,6.676],[4.582,0.001],[3.47,-6.674],[-0.014,-8.811],[-3.469,-6.674],[-4.581,0.001],[-3.469,6.676],[0.015,8.813]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.171,1.786],[0,3.747],[-1.161,1.786],[-2.381,0],[-1.172,-1.786],[0,-3.748],[1.161,-1.786],[2.381,0]],"o":[[-1.171,-1.786],[0,-3.748],[1.161,-1.786],[2.38,0],[1.171,1.786],[0,3.747],[-1.162,1.786],[-2.381,0]],"v":[[-5.313,8.301],[-7.07,0.001],[-5.328,-8.299],[-0.014,-10.978],[5.315,-8.299],[7.07,0.001],[5.328,8.301],[0.015,10.979]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[811.516,662.344],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 16","np":4,"cix":2,"ix":16,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-5.958,-1.113],[5.958,-1.113],[5.958,1.112],[-5.958,1.112]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[792.338,676.193],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 17","np":2,"cix":2,"ix":17,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.849,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.536,0.498],[1.035,0],[0.624,-0.243],[0.625,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.85,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.741,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.704],[5.913,-3.031],[5.913,8.036],[3.542,8.036],[3.542,-2.825],[2.738,-5.006],[0.38,-5.752],[-1.669,-5.387],[-3.543,-4.26],[-3.543,8.036],[-5.914,8.036],[-5.914,-7.656],[-3.718,-7.656],[-3.718,-5.928],[1.083,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[773.848,664.906],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 18","np":2,"cix":2,"ix":18,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.089]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[755.812,665.097],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 19","np":4,"cix":2,"ix":19,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.171,-4.831],[1.201,-4.831],[1.201,10.861],[-1.171,10.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.283,0.292],[0,0.527],[-0.283,0.293],[-0.527,0],[-0.283,-0.293],[0,-0.507],[0.283,-0.293],[0.527,0]],"o":[[-0.283,-0.293],[0,-0.527],[0.283,-0.293],[0.527,0],[0.283,0.293],[0,0.547],[-0.283,0.292],[-0.527,0]],"v":[[-1.215,-7.963],[-1.639,-9.193],[-1.215,-10.422],[0,-10.861],[1.215,-10.422],[1.639,-9.222],[1.215,-7.963],[0,-7.524]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[742.431,662.081],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 20","np":4,"cix":2,"ix":20,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.469,-0.547],[-0.976,0],[-0.547,0.176],[0,0],[0.879,0]],"o":[[-0.819,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.468,0.546],[0.527,0],[0,0],[-0.722,0.235],[-1.601,0]],"v":[[-1.068,8.958],[-2.297,5.079],[-2.297,-3.616],[-4.963,-3.616],[-4.963,-5.636],[-2.297,-5.636],[-2.297,-10.261],[0.073,-10.261],[0.073,-5.636],[4.758,-5.636],[4.758,-3.616],[0.073,-3.616],[0.073,4.729],[0.776,7.305],[2.943,8.125],[4.552,7.86],[4.962,9.91],[2.561,10.261]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[731.494,662.887],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 21","np":2,"cix":2,"ix":21,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.653,0.303],[-0.566,0.625],[0,0],[1.142,-0.547],[0,-1.171],[-0.517,-0.458],[-1.014,0]],"o":[[0.654,-0.302],[0,0],[-2.439,0.02],[-1.142,0.547],[0,0.898],[0.517,0.459],[0.8,0]],"v":[[1.727,5.606],[3.557,4.215],[3.557,-0.088],[-1.815,0.761],[-3.528,3.337],[-2.752,5.372],[-0.454,6.06]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-0.849],[0,-1.64],[0,0],[0,0],[0,0],[2.128,0],[0.859,0.82],[0,1.483],[-1.522,0.878],[-3.26,0.02],[0,0],[0.614,0.507],[1.191,0],[1.151,-0.546],[0,0],[-1.639,0]],"o":[[1.034,0.849],[0,0],[0,0],[0,0],[-1.015,1.542],[-1.562,0],[-0.859,-0.819],[0,-1.874],[1.523,-0.879],[0,0],[0,-0.975],[-0.615,-0.508],[-1.307,0],[0,0],[1.424,-0.721],[1.717,0]],"v":[[4.348,-6.924],[5.9,-3.191],[5.9,7.875],[3.733,7.875],[3.733,5.884],[-0.981,8.197],[-4.611,6.967],[-5.899,3.513],[-3.616,-0.615],[3.557,-1.962],[3.557,-2.987],[2.635,-5.211],[-0.073,-5.973],[-3.762,-5.153],[-4.377,-7.115],[0.22,-8.198]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[716.27,665.067],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 22","np":4,"cix":2,"ix":22,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,2.323],[0,0],[0,0],[0,0],[-0.254,-0.243],[-0.547,0],[-0.41,0.079],[0,0],[0.644,0]],"o":[[0,0],[0,0],[0,0],[0,0.547],[0.254,0.245],[0.351,0],[0,0],[-0.625,0.156],[-2.283,0]],"v":[[-2.664,7.875],[-2.664,-11.359],[-0.293,-11.359],[-0.293,7.67],[0.087,8.855],[1.288,9.222],[2.43,9.104],[2.664,11.125],[0.761,11.359]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[704.103,661.759],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 23","np":2,"cix":2,"ix":23,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.692,1.024],[0,2.011],[0.692,1.034],[1.327,0],[0.692,-1.035],[0,-1.99],[-0.694,-1.025],[-1.346,0]],"o":[[0.692,-1.025],[0,-1.99],[-0.692,-1.035],[-1.366,0],[-0.694,1.034],[0,2.011],[0.692,1.024],[1.348,0]],"v":[[3.059,4.552],[4.099,0],[3.059,-4.537],[0.029,-6.089],[-3.059,-4.537],[-4.099,0],[-3.059,4.552],[-0.001,6.089]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.132,1.396],[0,2.694],[-1.142,1.395],[-2.108,0],[-1.132,-1.396],[0,-2.693],[1.132,-1.405],[2.109,0]],"o":[[-1.132,-1.395],[0,-2.693],[1.141,-1.396],[2.089,0],[1.132,1.395],[0,2.675],[-1.132,1.405],[-2.107,0]],"v":[[-4.86,6.134],[-6.558,0],[-4.845,-6.133],[0.029,-8.227],[4.86,-6.133],[6.558,0],[4.86,6.119],[-0.001,8.227]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[689.376,665.097],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 24","np":4,"cix":2,"ix":24,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.654,0.995],[0,1.971],[0.683,1.025],[1.347,0],[0.595,-0.293],[0.546,-0.625],[0,0],[-0.673,-0.302],[-0.742,0]],"o":[[0.653,-0.996],[0,-1.991],[-0.684,-1.024],[-0.723,0],[-0.595,0.293],[0,0],[0.487,0.546],[0.674,0.303],[1.288,0]],"v":[[2.855,1.728],[3.835,-2.722],[2.811,-7.246],[-0.234,-8.782],[-2.21,-8.344],[-3.922,-6.967],[-3.922,1.494],[-2.181,2.766],[-0.058,3.221]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.035,-1.464],[0,-2.616],[1.083,-1.435],[1.951,0],[0.694,0.312],[0.487,0.566],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.761,0.409],[-0.957,0]],"o":[[1.034,1.464],[0,2.557],[-1.084,1.434],[-0.821,0],[-0.692,-0.312],[0,0],[0,0],[0,0],[0,0],[0,0],[0.526,-0.8],[0.761,-0.41],[1.853,0]],"v":[[4.744,-8.87],[6.294,-2.751],[4.67,3.236],[0.118,5.387],[-2.152,4.919],[-3.922,3.602],[-3.922,11.067],[-6.294,11.067],[-6.294,-10.686],[-4.098,-10.686],[-4.098,-8.636],[-2.166,-10.451],[0.411,-11.066]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[672.041,667.936],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 25","np":4,"cix":2,"ix":25,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.586,-0.253],[0,0],[0.605,0],[0.556,-0.312],[0.449,-0.663],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.717,0]],"o":[[0,0],[-0.742,-0.214],[-0.742,0],[-0.556,0.313],[0,0],[0,0],[0,0],[0,0],[0,0],[1.114,-1.678],[0.704,0]],"v":[[4.187,-7.627],[3.659,-5.314],[1.639,-5.636],[-0.307,-5.168],[-1.815,-3.704],[-1.815,8.007],[-4.187,8.007],[-4.187,-7.686],[-1.992,-7.686],[-1.992,-5.49],[2.253,-8.007]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[656.934,664.936],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 26","np":2,"cix":2,"ix":26,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.273,-3.221],[0,0],[0.702,0.849],[1.229,0]],"o":[[0,0],[-0.019,-1.522],[-0.703,-0.849],[-2.402,0]],"v":[[-3.967,-1.245],[4.026,-1.245],[2.943,-4.801],[0.044,-6.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.078,-0.331],[0,0],[-0.81,-0.888],[-1.483,0],[-1.21,0.781],[0,0],[0.887,-0.264],[0.975,0],[1.24,1.444],[0,2.576],[-1.142,1.444],[-2.069,0],[-1.113,-1.327],[0,-2.38]],"o":[[0,0],[0.078,1.757],[0.81,0.889],[1.464,0],[0,0],[-0.625,0.488],[-0.889,0.264],[-2.225,0],[-1.24,-1.444],[0,-2.596],[1.142,-1.445],[1.991,0],[1.112,1.328],[0,0.567]],"v":[[6.308,0.688],[-3.997,0.688],[-2.664,4.654],[0.776,5.987],[4.786,4.815],[5.695,6.69],[3.425,7.816],[0.63,8.212],[-4.568,6.045],[-6.427,0.014],[-4.714,-6.045],[0.102,-8.212],[4.758,-6.221],[6.427,-0.659]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[640.932,665.082],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 27","np":4,"cix":2,"ix":27,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.819,0.869],[0,1.717],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.468,-0.547],[-0.977,0],[-0.547,0.176],[0,0],[0.878,0]],"o":[[-0.82,-0.869],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,1.17],[0.469,0.546],[0.526,0],[0,0],[-0.721,0.235],[-1.601,0]],"v":[[-1.067,8.958],[-2.297,5.079],[-2.297,-3.616],[-4.962,-3.616],[-4.962,-5.636],[-2.297,-5.636],[-2.297,-10.261],[0.075,-10.261],[0.075,-5.636],[4.758,-5.636],[4.758,-3.616],[0.075,-3.616],[0.075,4.729],[0.777,7.305],[2.944,8.125],[4.554,7.86],[4.963,9.91],[2.563,10.261]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[625.94,662.887],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 28","np":2,"cix":2,"ix":28,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.85,-0.888],[0,-1.561],[0,0],[0,0],[0,0],[0.537,0.498],[1.034,0],[0.625,-0.243],[0.624,-0.507],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.913,0]],"o":[[0.849,0.888],[0,0],[0,0],[0,0],[0,-0.956],[-0.537,-0.498],[-0.742,0],[-0.625,0.245],[0,0],[0,0],[0,0],[0,0],[0,0],[1.288,-1.405],[1.523,0]],"v":[[4.641,-6.704],[5.914,-3.031],[5.914,8.036],[3.543,8.036],[3.543,-2.825],[2.738,-5.006],[0.381,-5.752],[-1.669,-5.387],[-3.542,-4.26],[-3.542,8.036],[-5.914,8.036],[-5.914,-7.656],[-3.717,-7.656],[-3.717,-5.928],[1.083,-8.036]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[610.642,664.906],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 29","np":2,"cix":2,"ix":29,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.216,-10.598],[1.216,-10.598],[1.216,10.598],[-1.216,10.598]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[596.692,662.344],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 30","np":2,"cix":2,"ix":30,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[6.383,8.402],[6.383,10.598],[-6.383,10.598],[-6.383,-10.598],[6.03,-10.598],[6.03,-8.403],[-3.952,-8.403],[-3.952,-1.347],[3.513,-1.347],[3.513,0.878],[-3.952,0.878],[-3.952,8.402]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054999998504,0.630999995213,0.902000038297,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[575.681,662.345],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 31","np":2,"cix":2,"ix":31,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":42,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"E Interpolation_01 Linear Interpolation","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[328,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[70,70,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"E Interpolation_02 Bezier Interpolation","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[965.75,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[70,70,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"E Interpolation_03 Hold Interpolation","refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1597.5,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[70,70,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"E Interpolation_04 Spatial Bezier Interpolation","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[328,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[70,70,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":0,"nm":"E Interpolation_05 Rove Across Time","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[965.75,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[70,70,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":120,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/F Masks_All_01_1920x1080.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/F Masks_All_01_1920x1080.json deleted file mode 100644 index 40895fb5..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/F Masks_All_01_1920x1080.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.18","fr":30,"ip":0,"op":41,"w":1920,"h":1080,"nm":"F Masks_All_01","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[1924.5,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[643.833,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[1284.167,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[3.5,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[823,461],[823,547],[1101,547],[1101,461]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[823,365],[823,643],[1101,643],[1101,365]],"c":true},"ix":1},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0],"e":[100]},{"t":30}],"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_3","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[823,365],[823,643],[1101,643],[1101,365]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1060,471],[1060,537],[1126,537],[1126,471]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1060,471],[1060,537],[1126,537],[1126,471]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[823,365],[823,643],[1101,643],[1101,365]],"c":true}]},{"t":40}],"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_4","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"s","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[823,365],[823,643],[1101,643],[1101,365]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1060,471],[1060,537],[1126,537],[1126,471]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1060,471],[1060,537],[1126,537],[1126,471]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[823,365],[823,643],[1101,643],[1101,365]],"c":true}]},{"t":40}],"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_5","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"i","pt":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[823,365],[823,643],[1101,643],[1101,365]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1087,365],[1087,643],[1101,643],[1101,365]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":20,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1087,365],[1087,643],[1101,643],[1101,365]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[823,365],[823,643],[1101,643],[1101,365]],"c":true}]},{"t":40}],"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"},{"inv":false,"mode":"i","pt":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[823,365],[823,643],[1101,643],[1101,365]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[823,365],[823,643],[836.5,643],[836.5,365]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":20,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[823,365],[823,643],[836.5,643],[836.5,365]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[823,365],[823,643],[1101,643],[1101,365]],"c":true}]},{"t":40}],"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 2"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_6","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[823,403],[823,519.5],[994,519.5],[994,403]],"c":true},"ix":1},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[90]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[90],"e":[100]},{"t":40}],"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"},{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1009.5,484],[1009.5,643],[1101,643],[1101,484]],"c":true},"ix":1},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[80]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[80],"e":[100]},{"t":40}],"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 2"},{"inv":false,"mode":"l","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[862,365],[862,626],[1073.5,626],[1073.5,365]],"c":true},"ix":1},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[80],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[100],"e":[80]},{"t":40}],"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 3"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]}],"fonts":{"list":[{"fName":"SamsungOne-500","fFamily":"SamsungOne","fStyle":"500","ascent":70.9991455078125}]},"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"div","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":10,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":5,"nm":"F Masks_01 Mask Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[39.375,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"F Masks_01 Mask Path","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":42,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":5,"nm":"F Masks_02 Mask Opacity","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[679.25,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"F Masks_02 Mask Opacity","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":42,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":5,"nm":"F Masks_03 Add","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1320,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"F Masks_03 Add","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":42,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":5,"nm":"F Masks_04 Subtract","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[39.375,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"F Masks_04 Subtract","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":42,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":5,"nm":"F Masks_05 Intersect","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[679.25,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"F Masks_05 Intersect","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":42,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":5,"nm":"F Masks_06 Lighten","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1320,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"F Masks_06 Lighten","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":42,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"F Masks_01 Mask Path","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[328,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[90,90,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"F Masks_02 Mask Opacity","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[965.75,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[90,90,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"F Masks_03 Add","refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1597.5,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[90,90,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":0,"nm":"F Masks_04 Subtract","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[328,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[90,90,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":0,"nm":"F Masks_05 Intersect","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[965.75,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[90,90,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":0,"nm":"F Masks_06 Lighten","refId":"comp_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1597.5,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[90,90,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0}],"markers":[],"chars":[{"ch":"F","size":150,"style":"500","w":48.7,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[7.654,0],[16.415,0],[16.415,-30.716],[42.096,-30.716],[42.096,-37.967],[16.415,-37.967],[16.415,-60.526],[44.211,-60.526],[44.211,-67.877],[7.654,-67.877]],"c":true},"ix":2},"nm":"F","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"F","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":" ","size":150,"style":"500","w":21.2,"data":{},"fFamily":"SamsungOne"},{"ch":"M","size":150,"style":"500","w":80.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[1.712,-6.848],[0,0],[2.82,8.359],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.201,8.459],[0,0],[-3.223,-9.567],[0,0],[0,0],[0,0],[-2.316,7.956],[0,0],[-0.504,-9.467]],"o":[[0,0],[0,0],[0,0],[0,0],[-3.021,8.56],[0,0],[-1.712,-7.05],[0,0],[0,0],[0,0],[0,0],[0,0],[0.604,-10.172],[0,0],[1.913,8.057],[0,0],[0,0],[0,0],[3.424,-9.366],[0,0],[-0.101,8.459],[0,0]],"v":[[66.568,0],[75.128,0],[70.898,-67.877],[59.72,-67.877],[47.635,-35.046],[40.485,-12.186],[40.182,-12.186],[33.334,-35.046],[21.753,-67.877],[10.574,-67.877],[5.841,0],[14.2,0],[16.013,-29.105],[17.322,-59.116],[17.523,-59.116],[25.378,-32.73],[36.356,-0.403],[43.002,-0.403],[54.987,-33.334],[63.547,-59.116],[63.849,-59.116],[64.856,-29.81]],"c":true},"ix":2},"nm":"M","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"M","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"a","size":150,"style":"500","w":48.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,4.23],[0,0],[14.905,0],[4.028,-2.618],[0,0],[-4.532,0],[0,-4.028],[0,0],[0,-11.783],[-9.869,0],[-2.719,3.827],[0,0],[0,0]],"o":[[-0.604,-3.323],[0,0],[0,-9.769],[-6.143,0],[0,0],[3.424,-2.216],[9.97,0],[0,0],[-18.832,-0.101],[0,7.05],[6.949,0],[0,0],[0,0],[0,0]],"v":[[42.398,0],[41.592,-11.682],[41.592,-29.91],[23.062,-49.85],[7.05,-45.52],[9.064,-39.679],[21.753,-43.304],[32.831,-32.025],[32.831,-31.018],[3.525,-12.891],[18.43,1.108],[33.334,-6.143],[33.636,-6.143],[34.341,0]],"c":true},"ix":2},"nm":"a","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.302,-0.906],[6.345,0],[0,5.74],[-9.668,-0.201]],"o":[[0,0.906],[-1.41,4.129],[-4.532,0],[0,-9.467],[0,0]],"v":[[33.032,-16.415],[32.529,-13.596],[20.746,-5.438],[12.387,-13.898],[33.032,-24.875]],"c":true},"ix":2},"nm":"a","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"a","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"s","size":150,"style":"500","w":39.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-5.338,0],[0,8.56],[8.459,3.223],[0,4.028],[-5.237,0],[-1.913,-1.208],[0,0],[4.935,0],[0,-7.855],[-8.762,-3.122],[0,-4.23],[6.445,0],[2.618,1.712]],"o":[[3.424,2.014],[11.581,0],[0,-7.251],[-6.345,-2.417],[0,-3.625],[4.532,0],[0,0],[-2.719,-1.611],[-10.474,0],[0,5.841],[6.546,2.417],[0,4.028],[-4.431,0],[0,0]],"v":[[3.928,-2.316],[17.624,1.007],[35.852,-13.596],[23.062,-28.299],[13.797,-36.557],[21.954,-43.204],[31.924,-40.384],[34.14,-46.829],[22.156,-49.85],[5.338,-35.55],[18.228,-21.753],[27.292,-12.79],[17.825,-5.539],[6.143,-9.064]],"c":true},"ix":2},"nm":"s","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"s","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"k","size":150,"style":"500","w":48.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.208,-1.712],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.41,1.712],[0,0],[0,0]],"v":[[16.113,-71.503],[7.352,-71.503],[7.352,0],[16.113,0],[16.113,-18.329],[20.645,-23.364],[37.463,0],[48.239,0],[26.788,-28.702],[45.621,-48.743],[34.946,-48.743],[20.645,-31.924],[16.315,-26.385],[16.113,-26.385]],"c":true},"ix":2},"nm":"k","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"k","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"_","size":150,"style":"500","w":50,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,7.553],[0,12.589],[50.354,12.589],[50.354,7.553]],"c":true},"ix":2},"nm":"_","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"_","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"0","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.797,0],[0,-21.954],[-12.79,0],[0,22.256]],"o":[[-13.293,0],[0.201,21.652],[14.502,0],[0,-20.847]],"v":[[26.385,-66.568],[3.625,-32.529],[25.278,1.108],[48.038,-33.435]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-7.755,0],[0,-16.113],[9.064,0],[0,17.02]],"o":[[9.164,0],[0,16.718],[-8.057,0],[0,-17.825]],"v":[[25.882,-59.72],[39.175,-33.032],[25.781,-5.74],[12.488,-32.428]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"0","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"6","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[2.618,-0.403],[5.438,-5.338],[0,-12.891],[-13.998,0],[0,11.984],[11.581,0],[3.122,-4.129],[0,0],[-13.898,2.316],[-1.813,-0.101]],"o":[[-1.611,0],[-8.258,1.007],[-6.445,6.445],[0,17.02],[13.596,0],[0,-12.79],[-7.251,0],[0,0],[1.511,-10.776],[2.518,-0.403],[0,0]],"v":[[41.895,-66.467],[35.449,-65.964],[14.502,-56.296],[3.424,-26.788],[26.587,1.108],[48.34,-21.954],[28.601,-43.103],[12.79,-35.55],[12.488,-35.55],[35.248,-58.813],[41.895,-59.216]],"c":true},"ix":2},"nm":"6","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[7.654,0],[0.201,10.776],[-0.604,1.007],[-5.338,0],[0,-9.366]],"o":[[-9.265,0],[0,-1.611],[2.417,-4.733],[8.157,0],[0,9.366]],"v":[[26.587,-5.74],[12.186,-24.472],[13.193,-28.4],[25.882,-36.456],[39.377,-21.451]],"c":true},"ix":2},"nm":"6","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"6","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"L","size":150,"style":"500","w":47.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[7.654,0],[45.419,0],[45.419,-7.352],[16.415,-7.352],[16.415,-67.877],[7.654,-67.877]],"c":true},"ix":2},"nm":"L","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"L","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"i","size":150,"style":"500","w":23.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16.214,0],[16.214,-48.743],[7.352,-48.743],[7.352,0]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[3.323,0],[0,-3.122],[-3.122,0],[0.101,3.021]],"o":[[-3.223,0],[0,3.021],[3.525,0],[0,-3.122]],"v":[[11.783,-67.978],[6.244,-62.439],[11.581,-57.001],[17.221,-62.439]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"i","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"g","size":150,"style":"500","w":55.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[8.459,0],[0,-16.516],[-12.085,0],[-2.719,4.532],[0,0],[0,0],[9.064,0],[3.223,2.014],[0,0],[-5.841,0],[-4.733,4.431],[0,11.179],[0,0],[-0.201,3.525]],"o":[[0,0],[0,0],[-2.115,-4.028],[-11.179,0],[0,13.495],[7.553,0],[0,0],[0,0],[0,12.286],[-6.042,0],[0,0],[3.928,2.618],[6.143,0],[4.733,-4.23],[0,0],[0,-5.942],[0,0]],"v":[[41.592,-48.743],[41.19,-41.391],[40.988,-41.391],[25.781,-49.85],[3.827,-23.969],[24.573,-0.201],[40.082,-8.359],[40.283,-8.359],[40.283,-2.921],[24.573,14.099],[10.272,10.272],[8.057,17.02],[24.271,21.048],[41.995,15.207],[48.944,-7.05],[48.944,-35.349],[49.347,-48.743]],"c":true},"ix":2},"nm":"g","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.504,-1.511],[5.438,0],[0,9.567],[-8.459,0],[-1.611,-5.136],[0,-1.511]],"o":[[0,1.511],[-1.913,5.64],[-9.567,0],[0,-11.279],[6.445,0],[0.403,1.208],[0,0]],"v":[[40.182,-20.746],[39.478,-16.013],[27.191,-6.949],[12.79,-24.472],[27.292,-42.902],[39.679,-33.536],[40.182,-29.507]],"c":true},"ix":2},"nm":"g","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"g","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"h","size":150,"style":"500","w":55.5,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.504,1.208],[-5.74,0],[0,-7.855],[0,0],[0,0],[0,0],[6.546,0],[2.618,-1.511],[1.41,-2.518],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,-1.712],[1.611,-4.834],[8.359,0],[0,0],[0,0],[0,0],[0,-16.818],[-3.323,0],[-2.719,1.511],[0,0],[0,0],[0,0],[0,0]],"v":[[7.352,0],[16.214,0],[16.214,-29.407],[16.818,-33.636],[28.702,-42.499],[39.981,-27.997],[39.981,0],[48.843,0],[48.843,-29.004],[31.824,-49.85],[22.76,-47.333],[16.415,-41.089],[16.214,-41.089],[16.214,-71.503],[7.352,-71.503]],"c":true},"ix":2},"nm":"h","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"h","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"t","size":150,"style":"500","w":33.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-2.518,-2.618],[-4.129,0],[-1.712,0.705],[0,0],[2.316,0],[0,6.042],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,5.74],[2.115,2.417],[3.424,0],[0,0],[-1.108,0.302],[-4.935,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[9.366,-60.425],[9.366,-48.743],[1.813,-48.743],[1.813,-41.995],[9.366,-41.995],[9.366,-15.408],[12.79,-2.719],[22.357,1.007],[30.212,-0.201],[29.81,-6.848],[24.673,-6.244],[18.027,-15.71],[18.027,-41.995],[30.716,-41.995],[30.716,-48.743],[18.027,-48.743],[18.027,-62.741]],"c":true},"ix":2},"nm":"t","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"t","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"e","size":150,"style":"500","w":50.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,1.813],[15.912,0],[0,-14.703],[-15.005,0],[-3.122,1.41],[0,0],[6.345,0],[0.201,11.984]],"o":[[0.101,-0.906],[0,-8.963],[-14.2,0],[0,14.703],[7.755,0],[0,0],[-3.323,1.41],[-8.862,0],[0,0]],"v":[[46.527,-22.76],[46.829,-26.889],[26.688,-49.85],[3.827,-23.566],[27.795,1.007],[44.009,-2.014],[42.499,-8.359],[29.004,-5.841],[12.286,-22.76]],"c":true},"ix":2},"nm":"e","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-8.963,0],[0.101,-5.64]],"o":[[0.705,-6.143],[9.97,0],[0,0]],"v":[[12.387,-29.105],[25.983,-43.506],[38.269,-29.105]],"c":true},"ix":2},"nm":"e","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"e","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"n","size":150,"style":"500","w":55.5,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.403,1.108],[-5.841,0],[0,-7.855],[0,0],[0,0],[0,0],[6.747,0],[2.417,-4.633],[0,0],[0,0],[0,0],[0,-5.035]],"o":[[0,0],[0,0],[0,-1.511],[1.511,-4.935],[8.359,0],[0,0],[0,0],[0,0],[0,-16.718],[-8.057,0],[0,0],[0,0],[0,0],[0.302,4.028],[0,0]],"v":[[7.352,0],[16.214,0],[16.214,-29.306],[16.818,-33.435],[28.702,-42.499],[39.981,-28.098],[39.981,0],[48.843,0],[48.843,-29.105],[31.622,-49.85],[15.509,-40.686],[15.308,-40.686],[14.804,-48.743],[6.949,-48.743],[7.352,-35.55]],"c":true},"ix":2},"nm":"n","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"n","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"5","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-3.726,0],[-0.101,-8.459],[8.359,0],[2.719,1.611],[0,0],[-7.15,0],[0,12.79],[5.136,2.921],[5.035,0],[1.511,-0.201],[0,0],[0,0]],"o":[[0,0],[0,0],[2.417,-0.302],[13.092,0],[0,8.762],[-5.942,0],[0,0],[3.122,2.014],[14.2,0],[0,-8.258],[-4.028,-2.417],[-2.417,0],[0,0],[0,0],[0,0]],"v":[[43.607,-65.46],[12.286,-65.46],[8.057,-34.039],[17.12,-34.744],[35.953,-20.242],[20.444,-6.042],[6.445,-9.668],[4.23,-2.921],[20.544,1.108],[44.916,-21.249],[35.55,-38.068],[21.451,-41.592],[16.113,-41.19],[18.631,-58.008],[43.607,-58.008]],"c":true},"ix":2},"nm":"5","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"5","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"I","size":150,"style":"500","w":23.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[7.654,-67.877],[7.654,0],[16.415,0],[16.415,-67.877]],"c":true},"ix":2},"nm":"I","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"I","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"r","size":150,"style":"500","w":33.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.201,1.208],[-6.244,0],[-0.906,-0.201],[0,0],[1.007,0],[2.216,-6.546],[0,0],[0,0],[0,0],[0,-5.74]],"o":[[0,0],[0,0],[0,-1.511],[1.208,-6.647],[1.208,0],[0,0],[-0.806,-0.201],[-5.942,0],[0,0],[0,0],[0,0],[0.302,4.532],[0,0]],"v":[[7.352,0],[16.113,0],[16.113,-25.983],[16.516,-30.112],[28.4,-41.492],[31.421,-41.19],[31.421,-49.548],[28.903,-49.85],[15.408,-39.175],[15.005,-39.175],[14.703,-48.743],[6.949,-48.743],[7.352,-33.536]],"c":true},"ix":2},"nm":"r","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"r","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"c","size":150,"style":"500","w":44.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[5.035,0],[0,11.279],[-11.179,0],[-2.115,-1.208],[0,0],[5.237,0],[0,-15.005],[-14.703,0],[-2.316,1.208]],"o":[[-2.518,1.108],[-9.668,0],[0,-10.172],[4.834,0],[0,0],[-2.417,-1.208],[-15.912,0],[0,14.905],[6.546,0],[0,0]],"v":[[40.585,-8.459],[29.709,-6.042],[12.79,-24.271],[30.011,-42.7],[40.283,-40.384],[42.297,-47.232],[30.011,-49.75],[3.827,-23.868],[28.098,1.007],[42.096,-1.813]],"c":true},"ix":2},"nm":"c","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"c","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"4","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[40.283,0],[40.283,-17.825],[49.448,-17.825],[49.448,-24.774],[40.283,-24.774],[40.283,-65.46],[30.716,-65.46],[1.511,-23.666],[1.511,-17.825],[31.924,-17.825],[31.924,0]],"c":true},"ix":2},"nm":"4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-2.014,3.827],[0,0],[0,-3.424],[0,0]],"o":[[0,0],[0,0],[1.813,-3.021],[0,0],[-0.201,3.424],[0,0],[0,0]],"v":[[10.474,-24.774],[10.474,-24.976],[26.486,-47.232],[31.924,-56.9],[32.227,-56.9],[31.924,-46.628],[31.924,-24.774]],"c":true},"ix":2},"nm":"4","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"4","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"S","size":150,"style":"500","w":49.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.546,0],[0,10.474],[11.481,4.431],[0,6.345],[-9.265,0],[-2.216,-1.208],[0,0],[6.949,0],[0,-10.574],[-11.078,-3.928],[0,-6.345],[8.963,0],[3.928,2.417]],"o":[[3.625,2.417],[16.013,0],[0,-9.97],[-9.366,-3.625],[0,-4.633],[6.143,0],[0,0],[-3.021,-1.712],[-13.193,0],[0,9.567],[9.164,3.525],[0,6.848],[-6.042,0],[0,0]],"v":[[4.23,-3.323],[21.552,1.007],[45.319,-18.53],[27.997,-38.47],[14.502,-51.562],[27.292,-61.734],[40.182,-58.511],[42.599,-65.662],[27.594,-68.985],[5.64,-50.555],[23.566,-31.32],[36.356,-17.825],[22.156,-6.244],[6.445,-10.675]],"c":true},"ix":2},"nm":"S","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"S","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"u","size":150,"style":"500","w":55.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0.504,-1.309],[5.942,0],[0,9.265],[0,0],[0,0],[0,0],[-7.654,0],[-2.316,3.928],[0,0],[0,0],[0,0],[0,5.035]],"o":[[0,0],[0,0],[0,1.611],[-1.611,3.928],[-8.057,0],[0,0],[0,0],[0,0],[0,17.12],[8.661,0],[0,0],[0,0],[0,0],[-0.302,-3.827],[0,0]],"v":[[48.138,-48.743],[39.276,-48.743],[39.276,-18.832],[38.47,-14.301],[26.788,-6.244],[15.912,-21.753],[15.912,-48.743],[7.05,-48.743],[7.05,-20.242],[23.868,1.108],[39.981,-7.956],[40.182,-7.956],[40.686,0],[48.541,0],[48.138,-13.293]],"c":true},"ix":2},"nm":"u","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"u","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"b","size":150,"style":"500","w":56.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-7.05,0],[0,17.422],[12.085,0],[3.122,-5.438],[0,0],[0,0],[0,0],[0,0],[0.201,-3.323]],"o":[[0,0],[0,0],[3.625,6.445],[10.876,0],[0.101,-14.804],[-7.855,0],[0,0],[0,0],[0,0],[0,0],[0,4.33],[0,0]],"v":[[14.603,0],[15.005,-8.057],[15.308,-8.057],[31.622,1.108],[53.476,-24.976],[32.932,-49.85],[16.315,-40.887],[16.113,-40.887],[16.113,-71.503],[7.352,-71.503],[7.352,-12.589],[6.949,0]],"c":true},"ix":2},"nm":"b","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-0.201,1.007],[-6.042,0],[0,-9.769],[9.265,0],[1.712,6.143],[0,1.108]],"o":[[0,-1.41],[1.813,-6.747],[9.467,0],[0,11.179],[-6.445,0],[-0.201,-1.007],[0,0]],"v":[[16.113,-28.299],[16.617,-31.924],[30.112,-42.801],[44.614,-24.673],[29.81,-5.942],[16.516,-16.315],[16.113,-19.537]],"c":true},"ix":2},"nm":"b","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"b","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"3","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-7.352,0],[0,10.474],[8.057,1.611],[0,0],[0,6.747],[12.891,0],[3.424,-2.518],[0,0],[-5.237,0],[0,-5.237],[6.445,0],[0,0],[0,0],[0,0],[-0.101,-9.164],[11.38,0],[2.518,1.611]],"o":[[3.223,2.115],[15.71,0],[0,-9.164],[0,0],[8.057,-2.921],[0,-7.956],[-7.05,0],[0,0],[2.82,-2.014],[8.157,0],[0,7.755],[0,0],[0,0],[0,0],[8.56,0],[0.101,5.438],[-6.143,0],[0,0]],"v":[[4.23,-3.323],[21.249,1.108],[45.117,-18.53],[30.515,-35.349],[30.515,-35.55],[42.599,-50.958],[23.868,-66.568],[6.747,-61.533],[9.064,-55.087],[22.156,-59.418],[33.636,-49.548],[19.034,-38.47],[14.099,-38.47],[14.099,-31.824],[19.034,-31.824],[35.953,-18.732],[21.149,-6.042],[6.647,-10.172]],"c":true},"ix":2},"nm":"3","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"3","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"A","size":150,"style":"500","w":61.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[42.7,-21.35],[49.951,0],[59.317,0],[36.154,-67.877],[25.58,-67.877],[2.518,0],[11.581,0],[18.631,-21.35]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-1.007,4.028],[0,0],[-1.511,-4.431],[0,0]],"o":[[0,0],[1.309,-4.129],[0,0],[1.007,3.928],[0,0],[0,0]],"v":[[20.444,-28.198],[27.09,-47.836],[30.515,-60.123],[30.716,-60.123],[34.241,-47.736],[40.887,-28.198]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"A","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"d","size":150,"style":"500","w":56.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[7.452,0],[-0.101,-16.214],[-11.783,0],[-2.719,5.438],[0,0],[0,0],[0,0],[0,4.33],[0,0]],"o":[[0,0],[0,0],[-2.216,-3.928],[-11.884,0],[0,14.804],[7.956,0],[0,0],[0,0],[0,0],[-0.302,-3.323],[0,0],[0,0]],"v":[[40.585,-71.503],[40.585,-42.398],[40.384,-42.398],[25.681,-49.85],[3.827,-23.666],[24.673,1.108],[41.29,-8.459],[41.492,-8.459],[41.895,0],[49.85,0],[49.448,-12.589],[49.448,-71.503]],"c":true},"ix":2},"nm":"d","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.302,-1.208],[5.942,0],[0,9.869],[-9.164,0],[-1.309,-5.64],[0,-1.108]],"o":[[0,1.41],[-1.611,6.647],[-9.567,0],[0,-10.776],[6.647,0],[0.302,1.108],[0,0]],"v":[[40.585,-20.444],[40.182,-16.617],[27.191,-6.042],[12.79,-24.069],[27.393,-42.902],[40.182,-32.629],[40.585,-28.903]],"c":true},"ix":2},"nm":"d","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"d","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"2","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,12.085],[14.099,0],[4.532,-3.827],[0,0],[-5.942,0],[0,-6.647],[16.718,-15.912],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[13.797,-13.293],[0,-9.366],[-7.553,0],[0,0],[3.021,-2.518],[9.769,0],[-0.101,9.869],[0,0],[0,0],[0,0]],"v":[[46.326,0],[46.326,-7.352],[16.919,-7.352],[16.919,-7.553],[22.156,-12.387],[44.714,-47.534],[24.673,-66.568],[6.143,-59.921],[8.963,-53.677],[22.861,-59.216],[35.852,-46.426],[11.481,-12.186],[4.532,-5.438],[4.532,0]],"c":true},"ix":2},"nm":"2","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"O","size":150,"style":"500","w":68.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[18.53,0],[0,-21.552],[-17.926,0],[0,23.364]],"o":[[-18.127,0],[0,20.544],[17.322,0],[0,-20.142]],"v":[[35.147,-68.985],[3.625,-33.334],[34.14,1.108],[65.662,-34.644]],"c":true},"ix":2},"nm":"O","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-14.502,0],[0,-13.495],[13.898,0],[0,14.502]],"o":[[14.603,0],[0,15.408],[-13.797,0],[0,-14.905]],"v":[[34.744,-61.835],[56.396,-34.241],[34.644,-6.042],[12.991,-33.536]],"c":true},"ix":2},"nm":"O","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"O","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"p","size":150,"style":"500","w":56.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-6.445,0],[0,17.523],[11.783,0],[3.625,-5.942],[0,0],[0,0],[0,0],[0,-6.244]],"o":[[0,0],[0,0],[0,0],[2.921,4.834],[11.481,0],[0,-14.804],[-7.956,0],[0,0],[0,0],[0,0],[0.201,4.633],[0,0]],"v":[[7.352,19.94],[16.113,19.94],[16.113,-6.546],[16.315,-6.546],[31.32,1.108],[53.476,-25.076],[32.831,-49.85],[15.509,-40.384],[15.308,-40.384],[14.905,-48.743],[6.949,-48.743],[7.352,-32.831]],"c":true},"ix":2},"nm":"p","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-0.302,1.108],[-6.042,0],[0,-9.769],[9.366,0],[1.611,6.143],[0,1.309]],"o":[[0,-1.208],[1.712,-6.647],[9.366,0],[0,11.179],[-6.345,0],[-0.201,-1.108],[0,0]],"v":[[16.113,-28.198],[16.718,-31.824],[30.112,-42.801],[44.614,-24.673],[29.81,-5.841],[16.516,-16.214],[16.113,-19.839]],"c":true},"ix":2},"nm":"p","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"p","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"y","size":150,"style":"500","w":48.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,-0.504],[0.403,-0.906],[2.417,-1.913],[2.216,-0.705],[0,0],[-4.33,3.827],[-6.345,16.718],[0,0],[0,0],[0,0],[0.906,-2.921],[0,0],[1.108,3.223],[0,0]],"o":[[0,0],[0.403,1.108],[0,0.504],[-2.014,4.532],[-2.618,2.216],[0,0],[2.216,-0.403],[6.042,-5.237],[0,0],[0,0],[0,0],[-1.208,3.525],[0,0],[-0.806,-2.921],[0,0],[0,0]],"v":[[0.906,-48.743],[18.933,-3.827],[19.537,-1.511],[18.832,0.604],[11.38,10.474],[3.625,14.804],[5.841,22.256],[16.718,16.516],[33.435,-13.998],[46.729,-48.743],[37.363,-48.743],[27.695,-20.142],[24.573,-9.97],[24.371,-9.97],[21.249,-19.94],[10.574,-48.743]],"c":true},"ix":2},"nm":"y","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"y","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"1","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[23.767,0],[32.327,0],[32.327,-65.46],[24.774,-65.46],[10.474,-57.806],[12.186,-51.059],[23.566,-57.202],[23.767,-57.202]],"c":true},"ix":2},"nm":"1","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"P","size":150,"style":"500","w":53.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-2.618,0],[-4.633,4.935],[0,6.143],[3.726,3.223],[8.661,0],[4.23,-0.705]],"o":[[0,0],[0,0],[2.014,0.504],[8.56,0],[3.424,-3.525],[0,-6.042],[-4.028,-3.625],[-7.05,0],[0,0]],"v":[[7.654,0],[16.415,0],[16.415,-27.191],[23.465,-26.587],[44.211,-34.039],[49.448,-48.541],[43.506,-62.741],[24.472,-68.381],[7.654,-67.072]],"c":true},"ix":2},"nm":"P","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-3.827,0],[0,-8.963],[10.574,0],[1.913,0.504]],"o":[[1.511,-0.403],[9.668,0],[0,9.366],[-2.921,0],[0,0]],"v":[[16.415,-60.727],[24.673,-61.432],[40.686,-48.138],[23.666,-33.636],[16.415,-34.341]],"c":true},"ix":2},"nm":"P","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"P","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/F Masks_All_02_1920x1080.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/F Masks_All_02_1920x1080.json deleted file mode 100644 index e4e2462d..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/UXSample_1920x1080/F Masks_All_02_1920x1080.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.18","fr":30,"ip":0,"op":41,"w":1920,"h":1080,"nm":"F Masks_All_02","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[1924.5,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[643.833,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[1284.167,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[3.5,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-994,4],[1024,4]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[823,403],[823,519.5],[994,519.5],[994,403]],"c":true},"ix":1},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[20],"e":[100]},{"t":40}],"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"},{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1009.5,484],[1009.5,643],[1101,643],[1101,484]],"c":true},"ix":1},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[50]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[50],"e":[100]},{"t":40}],"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 2"},{"inv":false,"mode":"d","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[862,365],[862,626],[1073.5,626],[1073.5,365]],"c":true},"ix":1},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[80],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[100],"e":[80]},{"t":40}],"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 3"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[823,403],[823,519.5],[994,519.5],[994,403]],"c":true},"ix":1},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[100],"e":[100]},{"t":40}],"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"},{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1009.5,484],[1009.5,643],[1101,643],[1101,484]],"c":true},"ix":1},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[80]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[80],"e":[100]},{"t":40}],"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 2"},{"inv":false,"mode":"f","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[862,365],[862,626],[1073.5,626],[1073.5,365]],"c":true},"ix":1},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[80],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[100],"e":[80]},{"t":40}],"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 3"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_3","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[904,446],[904,562],[1020,562],[1020,446]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":0,"s":[0],"e":[200]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":20,"s":[200],"e":[0]},{"t":40}],"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]},{"id":"comp_4","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Rectantgle Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,244,0],"ix":2},"a":{"a":0,"k":[962,504,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[904,446],[904,562],[1020,562],[1020,446]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[139,139],[-139,139],[-139,-139],[139,-139]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.054901960784,0.63137254902,0.901960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[962,504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6300,"st":0,"bm":0}]}],"fonts":{"list":[{"fName":"SamsungOne-500","fFamily":"SamsungOne","fStyle":"500","ascent":70.9991455078125}]},"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"div","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":10,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":5,"nm":"F Masks_07 Darken","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[39.375,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"F Masks_07 Darken","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":42,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":5,"nm":"F Masks_08 Difference","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[679.25,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"F Masks_08 Difference","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":42,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":5,"nm":"F Masks_09 Expansion","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1320,62,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"F Masks_09 Expansion","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":42,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":5,"nm":"F Masks_10 Feather","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[39.375,601.938,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[14.576,14.576,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":150,"f":"SamsungOne-500","t":"F Masks_10 Feather","j":0,"tr":44,"lh":180,"ls":0,"fc":[0.05,0.63,0.9]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":42,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"F Masks_07 Darken_750x488","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[328,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[90,90,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"F Masks_08 Difference_750x488","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[965.75,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[90,90,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"F Masks_09 Expansion_750x488","refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1597.5,267,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[90,90,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"F Masks_10 Feather_750x488","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[328,809.5,0],"ix":2},"a":{"a":0,"k":[375,244,0],"ix":1},"s":{"a":0,"k":[90,90,100],"ix":6}},"ao":0,"w":750,"h":488,"ip":0,"op":6300,"st":0,"bm":0}],"markers":[],"chars":[{"ch":"F","size":150,"style":"500","w":48.7,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[7.654,0],[16.415,0],[16.415,-30.716],[42.096,-30.716],[42.096,-37.967],[16.415,-37.967],[16.415,-60.526],[44.211,-60.526],[44.211,-67.877],[7.654,-67.877]],"c":true},"ix":2},"nm":"F","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"F","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":" ","size":150,"style":"500","w":21.2,"data":{},"fFamily":"SamsungOne"},{"ch":"M","size":150,"style":"500","w":80.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[1.712,-6.848],[0,0],[2.82,8.359],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.201,8.459],[0,0],[-3.223,-9.567],[0,0],[0,0],[0,0],[-2.316,7.956],[0,0],[-0.504,-9.467]],"o":[[0,0],[0,0],[0,0],[0,0],[-3.021,8.56],[0,0],[-1.712,-7.05],[0,0],[0,0],[0,0],[0,0],[0,0],[0.604,-10.172],[0,0],[1.913,8.057],[0,0],[0,0],[0,0],[3.424,-9.366],[0,0],[-0.101,8.459],[0,0]],"v":[[66.568,0],[75.128,0],[70.898,-67.877],[59.72,-67.877],[47.635,-35.046],[40.485,-12.186],[40.182,-12.186],[33.334,-35.046],[21.753,-67.877],[10.574,-67.877],[5.841,0],[14.2,0],[16.013,-29.105],[17.322,-59.116],[17.523,-59.116],[25.378,-32.73],[36.356,-0.403],[43.002,-0.403],[54.987,-33.334],[63.547,-59.116],[63.849,-59.116],[64.856,-29.81]],"c":true},"ix":2},"nm":"M","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"M","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"a","size":150,"style":"500","w":48.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,4.23],[0,0],[14.905,0],[4.028,-2.618],[0,0],[-4.532,0],[0,-4.028],[0,0],[0,-11.783],[-9.869,0],[-2.719,3.827],[0,0],[0,0]],"o":[[-0.604,-3.323],[0,0],[0,-9.769],[-6.143,0],[0,0],[3.424,-2.216],[9.97,0],[0,0],[-18.832,-0.101],[0,7.05],[6.949,0],[0,0],[0,0],[0,0]],"v":[[42.398,0],[41.592,-11.682],[41.592,-29.91],[23.062,-49.85],[7.05,-45.52],[9.064,-39.679],[21.753,-43.304],[32.831,-32.025],[32.831,-31.018],[3.525,-12.891],[18.43,1.108],[33.334,-6.143],[33.636,-6.143],[34.341,0]],"c":true},"ix":2},"nm":"a","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.302,-0.906],[6.345,0],[0,5.74],[-9.668,-0.201]],"o":[[0,0.906],[-1.41,4.129],[-4.532,0],[0,-9.467],[0,0]],"v":[[33.032,-16.415],[32.529,-13.596],[20.746,-5.438],[12.387,-13.898],[33.032,-24.875]],"c":true},"ix":2},"nm":"a","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"a","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"s","size":150,"style":"500","w":39.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-5.338,0],[0,8.56],[8.459,3.223],[0,4.028],[-5.237,0],[-1.913,-1.208],[0,0],[4.935,0],[0,-7.855],[-8.762,-3.122],[0,-4.23],[6.445,0],[2.618,1.712]],"o":[[3.424,2.014],[11.581,0],[0,-7.251],[-6.345,-2.417],[0,-3.625],[4.532,0],[0,0],[-2.719,-1.611],[-10.474,0],[0,5.841],[6.546,2.417],[0,4.028],[-4.431,0],[0,0]],"v":[[3.928,-2.316],[17.624,1.007],[35.852,-13.596],[23.062,-28.299],[13.797,-36.557],[21.954,-43.204],[31.924,-40.384],[34.14,-46.829],[22.156,-49.85],[5.338,-35.55],[18.228,-21.753],[27.292,-12.79],[17.825,-5.539],[6.143,-9.064]],"c":true},"ix":2},"nm":"s","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"s","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"k","size":150,"style":"500","w":48.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.208,-1.712],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.41,1.712],[0,0],[0,0]],"v":[[16.113,-71.503],[7.352,-71.503],[7.352,0],[16.113,0],[16.113,-18.329],[20.645,-23.364],[37.463,0],[48.239,0],[26.788,-28.702],[45.621,-48.743],[34.946,-48.743],[20.645,-31.924],[16.315,-26.385],[16.113,-26.385]],"c":true},"ix":2},"nm":"k","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"k","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"_","size":150,"style":"500","w":50,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,7.553],[0,12.589],[50.354,12.589],[50.354,7.553]],"c":true},"ix":2},"nm":"_","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"_","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"1","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[23.767,0],[32.327,0],[32.327,-65.46],[24.774,-65.46],[10.474,-57.806],[12.186,-51.059],[23.566,-57.202],[23.767,-57.202]],"c":true},"ix":2},"nm":"1","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"0","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.797,0],[0,-21.954],[-12.79,0],[0,22.256]],"o":[[-13.293,0],[0.201,21.652],[14.502,0],[0,-20.847]],"v":[[26.385,-66.568],[3.625,-32.529],[25.278,1.108],[48.038,-33.435]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-7.755,0],[0,-16.113],[9.064,0],[0,17.02]],"o":[[9.164,0],[0,16.718],[-8.057,0],[0,-17.825]],"v":[[25.882,-59.72],[39.175,-33.032],[25.781,-5.74],[12.488,-32.428]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"0","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"e","size":150,"style":"500","w":50.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,1.813],[15.912,0],[0,-14.703],[-15.005,0],[-3.122,1.41],[0,0],[6.345,0],[0.201,11.984]],"o":[[0.101,-0.906],[0,-8.963],[-14.2,0],[0,14.703],[7.755,0],[0,0],[-3.323,1.41],[-8.862,0],[0,0]],"v":[[46.527,-22.76],[46.829,-26.889],[26.688,-49.85],[3.827,-23.566],[27.795,1.007],[44.009,-2.014],[42.499,-8.359],[29.004,-5.841],[12.286,-22.76]],"c":true},"ix":2},"nm":"e","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-8.963,0],[0.101,-5.64]],"o":[[0.705,-6.143],[9.97,0],[0,0]],"v":[[12.387,-29.105],[25.983,-43.506],[38.269,-29.105]],"c":true},"ix":2},"nm":"e","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"e","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"t","size":150,"style":"500","w":33.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-2.518,-2.618],[-4.129,0],[-1.712,0.705],[0,0],[2.316,0],[0,6.042],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,5.74],[2.115,2.417],[3.424,0],[0,0],[-1.108,0.302],[-4.935,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[9.366,-60.425],[9.366,-48.743],[1.813,-48.743],[1.813,-41.995],[9.366,-41.995],[9.366,-15.408],[12.79,-2.719],[22.357,1.007],[30.212,-0.201],[29.81,-6.848],[24.673,-6.244],[18.027,-15.71],[18.027,-41.995],[30.716,-41.995],[30.716,-48.743],[18.027,-48.743],[18.027,-62.741]],"c":true},"ix":2},"nm":"t","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"t","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"h","size":150,"style":"500","w":55.5,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.504,1.208],[-5.74,0],[0,-7.855],[0,0],[0,0],[0,0],[6.546,0],[2.618,-1.511],[1.41,-2.518],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,-1.712],[1.611,-4.834],[8.359,0],[0,0],[0,0],[0,0],[0,-16.818],[-3.323,0],[-2.719,1.511],[0,0],[0,0],[0,0],[0,0]],"v":[[7.352,0],[16.214,0],[16.214,-29.407],[16.818,-33.636],[28.702,-42.499],[39.981,-27.997],[39.981,0],[48.843,0],[48.843,-29.004],[31.824,-49.85],[22.76,-47.333],[16.415,-41.089],[16.214,-41.089],[16.214,-71.503],[7.352,-71.503]],"c":true},"ix":2},"nm":"h","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"h","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"r","size":150,"style":"500","w":33.1,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.201,1.208],[-6.244,0],[-0.906,-0.201],[0,0],[1.007,0],[2.216,-6.546],[0,0],[0,0],[0,0],[0,-5.74]],"o":[[0,0],[0,0],[0,-1.511],[1.208,-6.647],[1.208,0],[0,0],[-0.806,-0.201],[-5.942,0],[0,0],[0,0],[0,0],[0.302,4.532],[0,0]],"v":[[7.352,0],[16.113,0],[16.113,-25.983],[16.516,-30.112],[28.4,-41.492],[31.421,-41.19],[31.421,-49.548],[28.903,-49.85],[15.408,-39.175],[15.005,-39.175],[14.703,-48.743],[6.949,-48.743],[7.352,-33.536]],"c":true},"ix":2},"nm":"r","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"r","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"9","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-3.223,0.504],[-5.035,4.935],[0,14.401],[13.394,0],[0,-12.387],[-11.783,0],[-3.625,4.431],[0,0],[4.33,-3.928],[5.136,-0.705],[1.913,0.201]],"o":[[2.115,0.101],[7.05,-0.806],[6.445,-6.244],[0,-16.718],[-13.394,0],[0,11.179],[6.546,0],[0,0],[-1.208,7.755],[-3.726,3.525],[-3.021,0.302],[0,0]],"v":[[9.668,1.007],[17.825,0.504],[36.859,-8.258],[48.138,-38.974],[26.486,-66.568],[4.129,-43.304],[23.465,-23.264],[38.873,-30.313],[39.175,-30.313],[30.515,-12.891],[16.818,-6.546],[9.668,-6.244]],"c":true},"ix":2},"nm":"9","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-7.553,0],[0,-11.179],[0.504,-0.806],[5.942,0],[0,8.157]],"o":[[9.265,0],[0,1.41],[-2.316,3.928],[-7.654,0],[0,-9.265]],"v":[[25.781,-59.821],[39.175,-40.082],[38.37,-36.859],[25.479,-30.011],[12.891,-43.909]],"c":true},"ix":2},"nm":"9","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"9","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"E","size":150,"style":"500","w":49.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[42.801,-39.075],[16.415,-39.075],[16.415,-60.526],[44.312,-60.526],[44.312,-67.877],[7.654,-67.877],[7.654,0],[45.822,0],[45.822,-7.352],[16.415,-7.352],[16.415,-31.824],[42.801,-31.824]],"c":true},"ix":2},"nm":"E","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"E","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"x","size":150,"style":"500","w":46.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[-1.611,2.921],[0,0],[-1.913,-2.82],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.611,-2.921],[0,0],[1.813,2.719],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[1.813,-2.921],[0,0],[1.712,2.921],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.611,2.618],[0,0],[-1.611,-2.719],[0,0],[0,0]],"v":[[1.611,-48.743],[18.127,-24.875],[0.806,0],[10.574,0],[17.624,-10.977],[22.76,-19.437],[22.961,-19.437],[28.198,-10.977],[35.349,0],[45.419,0],[28.299,-25.177],[44.916,-48.743],[35.349,-48.743],[28.5,-38.37],[23.666,-30.313],[23.364,-30.313],[18.43,-38.269],[11.481,-48.743]],"c":true},"ix":2},"nm":"x","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"x","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"p","size":150,"style":"500","w":56.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-6.445,0],[0,17.523],[11.783,0],[3.625,-5.942],[0,0],[0,0],[0,0],[0,-6.244]],"o":[[0,0],[0,0],[0,0],[2.921,4.834],[11.481,0],[0,-14.804],[-7.956,0],[0,0],[0,0],[0,0],[0.201,4.633],[0,0]],"v":[[7.352,19.94],[16.113,19.94],[16.113,-6.546],[16.315,-6.546],[31.32,1.108],[53.476,-25.076],[32.831,-49.85],[15.509,-40.384],[15.308,-40.384],[14.905,-48.743],[6.949,-48.743],[7.352,-32.831]],"c":true},"ix":2},"nm":"p","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-0.302,1.108],[-6.042,0],[0,-9.769],[9.366,0],[1.611,6.143],[0,1.309]],"o":[[0,-1.208],[1.712,-6.647],[9.366,0],[0,11.179],[-6.345,0],[-0.201,-1.108],[0,0]],"v":[[16.113,-28.198],[16.718,-31.824],[30.112,-42.801],[44.614,-24.673],[29.81,-5.841],[16.516,-16.214],[16.113,-19.839]],"c":true},"ix":2},"nm":"p","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"p","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"n","size":150,"style":"500","w":55.5,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.403,1.108],[-5.841,0],[0,-7.855],[0,0],[0,0],[0,0],[6.747,0],[2.417,-4.633],[0,0],[0,0],[0,0],[0,-5.035]],"o":[[0,0],[0,0],[0,-1.511],[1.511,-4.935],[8.359,0],[0,0],[0,0],[0,0],[0,-16.718],[-8.057,0],[0,0],[0,0],[0,0],[0.302,4.028],[0,0]],"v":[[7.352,0],[16.214,0],[16.214,-29.306],[16.818,-33.435],[28.702,-42.499],[39.981,-28.098],[39.981,0],[48.843,0],[48.843,-29.105],[31.622,-49.85],[15.509,-40.686],[15.308,-40.686],[14.804,-48.743],[6.949,-48.743],[7.352,-35.55]],"c":true},"ix":2},"nm":"n","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"n","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"i","size":150,"style":"500","w":23.4,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16.214,0],[16.214,-48.743],[7.352,-48.743],[7.352,0]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[3.323,0],[0,-3.122],[-3.122,0],[0.101,3.021]],"o":[[-3.223,0],[0,3.021],[3.525,0],[0,-3.122]],"v":[[11.783,-67.978],[6.244,-62.439],[11.581,-57.001],[17.221,-62.439]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"i","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"o","size":150,"style":"500","w":54.9,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.998,0],[0,-16.315],[-13.193,0],[0,18.027]],"o":[[-13.495,0],[0,15.408],[11.783,0],[0,-14.905]],"v":[[27.997,-49.85],[3.827,-23.969],[27.191,1.108],[51.462,-24.774]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-10.474,0],[0,-8.258],[8.459,0],[0,10.675]],"o":[[10.474,0],[0,10.977],[-8.661,0],[0,-9.265]],"v":[[27.795,-43.204],[42.398,-24.472],[27.594,-5.539],[12.79,-24.271]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"o","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"8","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-13.696,0],[0,11.38],[8.157,3.223],[0,0],[0,5.539],[12.689,0],[0,-10.373],[-7.251,-3.424],[0,0],[0,-8.258]],"o":[[12.488,0],[0,-7.956],[0,0],[8.057,-3.827],[0,-8.157],[-11.481,0],[0,5.64],[0,0],[-8.057,3.424],[0,9.567]],"v":[[25.681,1.108],[47.937,-17.926],[34.744,-34.845],[34.744,-35.147],[45.52,-50.455],[26.486,-66.568],[6.244,-49.146],[16.617,-34.442],[16.718,-34.14],[3.726,-16.617]],"c":true},"ix":2},"nm":"8","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[7.956,0],[-0.302,6.647],[-7.654,2.216],[0,-7.956]],"o":[[-8.359,0],[0,-6.244],[8.862,2.518],[0,6.747]],"v":[[25.882,-5.338],[12.79,-17.825],[24.573,-31.32],[38.974,-17.02]],"c":true},"ix":2},"nm":"8","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-7.352,0],[0,-5.237],[5.64,-1.913],[0,6.546]],"o":[[7.956,0],[0,5.942],[-7.553,-2.014],[0,-5.64]],"v":[[25.983,-60.223],[37.061,-49.548],[27.09,-37.665],[14.603,-49.75]],"c":true},"ix":2},"nm":"8","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"8","np":6,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"D","size":150,"style":"500","w":66.6,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.244,0],[-6.345,6.345],[0,11.078],[6.042,5.539],[12.589,0],[5.338,-0.806]],"o":[[4.431,0.504],[13.193,0],[6.345,-6.244],[0,-10.977],[-5.942,-5.539],[-6.949,0],[0,0]],"v":[[7.654,-0.201],[23.566,0.604],[53.577,-9.164],[63.345,-35.55],[53.778,-59.921],[26.285,-68.381],[7.654,-66.971]],"c":true},"ix":2},"nm":"D","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-4.532,0],[0.101,-16.013],[18.732,0],[2.216,0.403]],"o":[[2.316,-0.504],[18.53,0],[0,18.329],[-3.424,0],[0,0]],"v":[[16.415,-60.526],[26.688,-61.432],[54.181,-35.248],[25.278,-6.445],[16.415,-6.949]],"c":true},"ix":2},"nm":"D","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"D","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"f","size":150,"style":"500","w":29.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-7.553,0],[-1.309,-0.604],[0,0],[3.122,0],[3.323,-3.223],[0,-6.848],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,-7.452],[2.518,0],[0,0],[-1.712,-0.705],[-4.129,0],[-4.129,3.928],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[17.02,0],[17.02,-41.995],[28.802,-41.995],[28.802,-48.743],[17.02,-48.743],[17.02,-51.361],[26.486,-65.46],[32.126,-64.352],[33.334,-71.201],[25.781,-72.61],[13.898,-68.079],[8.258,-51.059],[8.258,-48.743],[1.41,-48.743],[1.41,-41.995],[8.258,-41.995],[8.258,0]],"c":true},"ix":2},"nm":"f","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"f","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"c","size":150,"style":"500","w":44.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[5.035,0],[0,11.279],[-11.179,0],[-2.115,-1.208],[0,0],[5.237,0],[0,-15.005],[-14.703,0],[-2.316,1.208]],"o":[[-2.518,1.108],[-9.668,0],[0,-10.172],[4.834,0],[0,0],[-2.417,-1.208],[-15.912,0],[0,14.905],[6.546,0],[0,0]],"v":[[40.585,-8.459],[29.709,-6.042],[12.79,-24.271],[30.011,-42.7],[40.283,-40.384],[42.297,-47.232],[30.011,-49.75],[3.827,-23.868],[28.098,1.007],[42.096,-1.813]],"c":true},"ix":2},"nm":"c","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"c","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"},{"ch":"7","size":150,"style":"500","w":51.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[5.74,-65.46],[5.74,-58.109],[37.766,-58.109],[37.766,-57.907],[9.366,0],[18.53,0],[47.031,-59.619],[47.031,-65.46]],"c":true},"ix":2},"nm":"7","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"7","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"SamsungOne"}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/_alarm.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/_alarm.json deleted file mode 100644 index 68344840..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/_alarm.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.13","fr":30,"ip":0,"op":60,"w":300,"h":300,"nm":"alram","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"02","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-36,"ix":10},"p":{"a":0,"k":[114.4,38.435,0],"ix":2},"a":{"a":0,"k":[56,-77,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":11,"s":[100,100,100],"e":[120,120,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":16,"s":[120,120,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":21,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":41,"s":[100,100,100],"e":[120,120,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":46,"s":[120,120,100],"e":[100,100,100]},{"t":51}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[40,40],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"타원 패스 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"선 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.803921568627,0.122952704336,0.235112313663,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"칠 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[55,-78],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"변형"}],"nm":"타원 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"01","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.883],"y":[1.286]},"o":{"x":[0.377],"y":[-0.667]},"n":["0p883_1p286_0p377_-0p667"],"t":0,"s":[0],"e":[-24.645]},{"i":{"x":[0.79],"y":[1.277]},"o":{"x":[0.479],"y":[1.173]},"n":["0p79_1p277_0p479_1p173"],"t":15,"s":[-24.645],"e":[0]},{"i":{"x":[0.558],"y":[0.987]},"o":{"x":[0.382],"y":[-0.496]},"n":["0p558_0p987_0p382_-0p496"],"t":30,"s":[0],"e":[25.003]},{"i":{"x":[0.606],"y":[1.408]},"o":{"x":[0.368],"y":[-0.01]},"n":["0p606_1p408_0p368_-0p01"],"t":45,"s":[25.003],"e":[0]},{"t":60}],"ix":10},"p":{"a":0,"k":[150,68,0],"ix":2},"a":{"a":0,"k":[79.5,1.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[16.704,0],[2.581,16.778],[-2.692,0.414],[-0.413,-2.691],[-11.823,0],[-1.848,11.914],[-2.689,-0.401],[0.417,-2.69]],"o":[[-16.725,0],[-0.414,-2.692],[2.687,-0.43],[1.836,11.934],[11.809,0],[0.419,-2.692],[2.691,0.419],[-2.6,16.754]],"v":[[0.001,17.505],[-33.318,-11.453],[-29.195,-17.075],[-23.573,-12.952],[0.001,7.645],[23.57,-12.918],[29.199,-17.035],[33.315,-11.407]],"c":true},"ix":2},"nm":"패스 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"칠 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[79.299,148.318],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"변형"}],"nm":"그룹 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[14.119,0],[0.276,-14.184],[0,-23.047],[0,0],[6.395,-4.16],[0,-4.302],[-8.032,-0.949],[-18.918,0],[-13.078,1.594],[0,16.065],[6.281,5.042],[0.249,9.057],[0.054,0.809],[18.499,9.322]],"o":[[-14.096,0],[-19.936,9.885],[0,0],[0.038,8.569],[-8.422,5.477],[0,16.08],[13.468,1.59],[18.738,0],[7.804,-0.951],[0,-3.69],[-7.863,-6.311],[-0.022,-0.803],[-1.404,-21.085],[-0.24,-14.216]],"v":[[0,-68.536],[-25.872,-42.896],[-58.71,10.594],[-58.709,10.879],[-68.861,31.212],[-79.051,47.267],[-49.681,66.815],[0.801,68.536],[50.519,66.81],[79.051,47.267],[71.452,33.077],[58.687,8.896],[58.573,6.478],[25.873,-42.831]],"c":true},"ix":2},"nm":"패스 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-8.845,0],[0,-9.001],[0.648,-1.77],[-1.361,-20.457],[-0.019,-0.676],[-9.666,-7.758],[0,-2.278],[38.213,0],[0,10.802],[-3.67,2.386],[0.051,11.472],[0,0.078],[-19.637,6.445],[0,1.993]],"o":[[8.846,0],[0,2],[18.524,6.142],[0.046,0.682],[0.344,12.522],[2.533,2.033],[0,10.802],[-38.213,0],[0,-2.768],[9.499,-6.179],[-0.001,-0.077],[0,-22.126],[-0.643,-1.765],[0,-9.001]],"v":[[0,-58.674],[16.017,-42.376],[14.998,-36.699],[48.734,7.133],[48.831,9.169],[65.28,40.768],[69.191,47.267],[0.801,58.676],[-69.19,47.267],[-63.485,39.478],[-48.849,10.827],[-48.85,10.594],[-15.004,-36.719],[-16.016,-42.376]],"c":true},"ix":2},"nm":"패스 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"패스 병합 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"칠 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[79.301,68.785],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"변형"}],"nm":"그룹 2","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/a_cup_of_coffee.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/a_cup_of_coffee.json deleted file mode 100644 index 9d6b2e52..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/a_cup_of_coffee.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.9","fr":60,"ip":0,"op":72,"w":600,"h":600,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"1-Hello Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[300,300,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-20.4,189.08],[0,0],[0,-44.148],[44.147,0],[2.388,0.215]],"o":[[20.4,189.08],[0,0],[0,0],[0,0],[44.147,0],[0,44.147],[-2.443,0],[0,0]],"v":[[135.532,-154.949],[68.843,154.949],[-128.378,154.949],[-195.068,-154.949],[135.532,-154.949],[215.468,-75.013],[135.532,4.922],[128.284,4.598]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[0],"e":[0]},{"t":35}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[0],"e":[100]},{"t":35}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.19199999641,0.722000002394,0.741000007181,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":9,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[291.348,370.49],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[5.78,8.259],[-5.781,8.258],[5.78,8.259],[0,0]],"o":[[0,0],[5.78,-8.259],[-5.781,-8.258],[5.78,-8.259],[0,0],[0,0]],"v":[[-7.704,55.018],[1.924,41.264],[1.924,13.754],[1.924,-13.754],[1.924,-41.264],[-7.704,-55.018]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[-13.53]},"o":{"x":[0.333],"y":[0]},"n":["0p667_-13p53_0p333_0"],"t":23,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0.156]},"n":["0p667_1_0p333_0p156"],"t":36,"s":[0],"e":[100]},{"t":50}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":23,"s":[0],"e":[100]},{"t":50}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.19199999641,0.722000002394,0.741000007181,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":9,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[330.898,129.578],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[5.781,8.259],[-5.781,8.258],[5.781,8.259],[0,0]],"o":[[0,0],[5.781,-8.259],[-5.781,-8.258],[5.781,-8.259],[0,0],[0,0]],"v":[[-7.704,55.018],[1.923,41.264],[1.923,13.754],[1.923,-13.754],[1.923,-41.264],[-7.704,-55.018]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[0.763]},"o":{"x":[0.333],"y":[0]},"n":["0p667_0p763_0p333_0"],"t":10,"s":[0],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[25.626]},"n":["0p667_1_0p333_25p626"],"t":22,"s":[100],"e":[100]},{"t":35}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":10,"s":[0],"e":[100]},{"t":35}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.19199999641,0.722000002394,0.741000007181,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":9,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[262.303,129.578],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[5.781,8.259],[-5.781,8.258],[5.781,8.259],[0,0]],"o":[[0,0],[5.781,-8.259],[-5.781,-8.258],[5.781,-8.259],[0,0],[0,0]],"v":[[-7.704,55.018],[1.923,41.264],[1.923,13.754],[1.923,-13.754],[1.923,-41.264],[-7.704,-55.018]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":16,"s":[0],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":27,"s":[100],"e":[100]},{"t":39}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":16,"s":[0],"e":[100]},{"t":39}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.19199999641,0.722000002394,0.741000007181,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":9,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[193.707,129.578],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":3,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[5.78,8.259],[-5.781,8.258],[5.78,8.259],[0,0]],"o":[[0,0],[5.78,-8.259],[-5.781,-8.258],[5.78,-8.259],[0,0],[0,0]],"v":[[-7.704,55.018],[1.924,41.264],[1.924,13.754],[1.924,-13.754],[1.924,-41.264],[-7.704,-55.018]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":45,"s":[0],"e":[0]},{"t":72}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":45,"s":[0],"e":[100]},{"t":72}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.19199999641,0.722000002394,0.741000007181,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":9,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[330.898,129.578],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":3,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[5.781,8.259],[-5.781,8.258],[5.781,8.259],[0,0]],"o":[[0,0],[5.781,-8.259],[-5.781,-8.258],[5.781,-8.259],[0,0],[0,0]],"v":[[-7.704,55.018],[1.923,41.264],[1.923,13.754],[1.923,-13.754],[1.923,-41.264],[-7.704,-55.018]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":32,"s":[0],"e":[0]},{"t":57}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":32,"s":[0],"e":[100]},{"t":57}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.19199999641,0.722000002394,0.741000007181,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":9,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[262.303,129.578],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":3,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[5.781,8.259],[-5.781,8.258],[5.781,8.259],[0,0]],"o":[[0,0],[5.781,-8.259],[-5.781,-8.258],[5.781,-8.259],[0,0],[0,0]],"v":[[-7.704,55.018],[1.923,41.264],[1.923,13.754],[1.923,-13.754],[1.923,-41.264],[-7.704,-55.018]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":38,"s":[0],"e":[0]},{"t":61}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":38,"s":[0],"e":[100]},{"t":61}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.19199999641,0.722000002394,0.741000007181,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":9,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[193.707,129.578],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":3,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":72,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/a_mountain.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/a_mountain.json deleted file mode 100644 index 65fed4be..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/a_mountain.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.15","fr":25,"ip":0,"op":89,"w":300,"h":300,"nm":"MountainCircle","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"CloudA contornos","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":25,"s":[65,155,0],"e":[136,155,0],"to":[11.8333330154419,0,0],"ti":[-11.8333330154419,0,0]},{"t":88}],"ix":2},"a":{"a":0,"k":[21.25,16.25,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.25,0.25,0.667],"y":[1,1,1]},"o":{"x":[0.75,0.75,0.333],"y":[0,0,0]},"n":["0p25_1_0p75_0","0p25_1_0p75_0","0p667_1_0p333_0"],"t":10,"s":[100,0,100],"e":[100,110,100]},{"i":{"x":[0.25,0.25,0.667],"y":[1,1,1]},"o":{"x":[0.75,0.75,0.333],"y":[0,0,0]},"n":["0p25_1_0p75_0","0p25_1_0p75_0","0p667_1_0p333_0"],"t":17,"s":[100,110,100],"e":[100,90,100]},{"i":{"x":[0.25,0.25,0.667],"y":[1,1,1]},"o":{"x":[0.75,0.75,0.333],"y":[0,0,0]},"n":["0p25_1_0p75_0","0p25_1_0p75_0","0p667_1_0p333_0"],"t":22,"s":[100,90,100],"e":[100,100,100]},{"t":24}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-4.418],[4.418,0],[0,4.418],[-4.418,0]],"o":[[0,4.418],[-4.418,0],[0,-4.418],[4.418,0]],"v":[[8,0],[0,8],[-8,0],[0,-8]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-78,149],[222,149],[222,-151],[-78,-151]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-78,-151],[222,-151],[222,149],[-78,149]],"c":true},"ix":2},"nm":"Trazado 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Combinar trazados 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929000016755,0.929000016755,0.929000016755,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.25,12.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-6.627],[6.627,0],[0,6.627],[-6.627,0]],"o":[[0,6.627],[-6.627,0],[0,-6.627],[6.627,0]],"v":[[12,0],[0,12],[-12,0],[0,-12]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-72,141],[228,141],[228,-159],[-72,-159]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-72,-159],[228,-159],[228,141],[-72,141]],"c":true},"ix":2},"nm":"Trazado 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Combinar trazados 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929000016755,0.929000016755,0.929000016755,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[28.25,20.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 2","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-6.075],[6.075,0],[0,6.075],[-6.075,0]],"o":[[0,6.075],[-6.075,0],[0,-6.075],[6.075,0]],"v":[[11,0],[0,11],[-11,0],[0,-11]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-65,150],[235,150],[235,-150],[-65,-150]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-65,-150],[235,-150],[235,150],[-65,150]],"c":true},"ix":2},"nm":"Trazado 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Combinar trazados 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929000016755,0.929000016755,0.929000016755,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[21.25,11.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 3","np":4,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-7.18],[7.18,0],[0,7.18],[-7.18,0]],"o":[[0,7.18],[-7.18,0],[0,-7.18],[7.18,0]],"v":[[13,0],[0,13],[-13,0],[0,-13]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-57,145],[243,145],[243,-155],[-57,-155]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-57,-155],[243,-155],[243,145],[-57,145]],"c":true},"ix":2},"nm":"Trazado 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Combinar trazados 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929000016755,0.929000016755,0.929000016755,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[13.25,16.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 4","np":4,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":89,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Circle 4","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,150,0],"ix":2},"a":{"a":0,"k":[137.25,137.25,0],"ix":1},"s":{"a":0,"k":[97.333,97.333,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-75.663],[75.663,0],[0,75.663],[-75.663,0]],"o":[[0,75.663],[-75.663,0],[0,-75.663],[75.663,0]],"v":[[137,0],[0,137],[-137,0],[0,-137]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-150,150],[150,150],[150,-150],[-150,-150]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-150,-150],[150,-150],[150,150],[-150,150]],"c":true},"ix":2},"nm":"Trazado 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Combinar trazados 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.081999999402,0.626999978458,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[137.25,137.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":89,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Sun contornos","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.25,"y":1},"o":{"x":0.75,"y":0},"n":"0p25_1_0p75_0","t":11,"s":[182,-13,0],"e":[182,83,0],"to":[0,16,0],"ti":[0,-13.6666669845581,0]},{"i":{"x":0.25,"y":1},"o":{"x":0.75,"y":0},"n":"0p25_1_0p75_0","t":29,"s":[182,83,0],"e":[182,69,0],"to":[0,13.6666669845581,0],"ti":[0,2.33333325386047,0]},{"t":33}],"ix":2},"a":{"a":0,"k":[20.25,20.25,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-11.05],[11.05,0],[0,0]],"o":[[0,11.05],[0,0],[11.05,0]],"v":[[10,0],[-10,20],[-10,-20]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-192,207],[108,207],[108,-93],[-192,-93]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-192,-93],[108,-93],[108,207],[-192,207]],"c":true},"ix":2},"nm":"Trazado 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Combinar trazados 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952999997606,0.611999990426,0.071000005685,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[30.25,20.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-11.046],[11.046,0],[0,11.046],[-11.046,0]],"o":[[0,11.046],[-11.046,0],[0,-11.046],[11.046,0]],"v":[[20,0],[0,20],[-20,0],[0,-20]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-182,207],[118,207],[118,-93],[-182,-93]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-182,-93],[118,-93],[118,207],[-182,207]],"c":true},"ix":2},"nm":"Trazado 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Combinar trazados 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.944999964097,0.769000004787,0.059000000299,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[20.25,20.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 2","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":89,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Circle 2","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,150,0],"ix":2},"a":{"a":0,"k":[137.25,137.25,0],"ix":1},"s":{"a":0,"k":[97.333,97.333,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-75.663],[75.663,0],[0,75.663],[-75.663,0]],"o":[[0,75.663],[-75.663,0],[0,-75.663],[75.663,0]],"v":[[137,0],[0,137],[-137,0],[0,-137]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-150,150],[150,150],[150,-150],[-150,-150]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-150,-150],[150,-150],[150,150],[-150,150]],"c":true},"ix":2},"nm":"Trazado 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Combinar trazados 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.081999999402,0.626999978458,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[137.25,137.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":89,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"MountainF contornos","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,280.135,0],"ix":2},"a":{"a":0,"k":[113.88,151.115,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.25,0.25,0.667],"y":[1,1,1]},"o":{"x":[0.75,0.75,0.333],"y":[0,0,0]},"n":["0p25_1_0p75_0","0p25_1_0p75_0","0p667_1_0p333_0"],"t":0,"s":[100,0,100],"e":[100,110,100]},{"i":{"x":[0.25,0.25,0.667],"y":[1,1,1]},"o":{"x":[0.75,0.75,0.333],"y":[0,0,0]},"n":["0p25_1_0p75_0","0p25_1_0p75_0","0p667_1_0p333_0"],"t":7,"s":[100,110,100],"e":[100,90,100]},{"i":{"x":[0.25,0.25,0.667],"y":[1,1,1]},"o":{"x":[0.75,0.75,0.333],"y":[0,0,0]},"n":["0p25_1_0p75_0","0p25_1_0p75_0","0p667_1_0p333_0"],"t":12,"s":[100,90,100],"e":[100,100,100]},{"t":14}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[30.77,0],[14.62,5.52],[0,0],[-0.921,-0.9]],"o":[[-22.529,17.55],[-16.54,0],[0,0],[1.17,-0.03],[0,0]],"v":[[64.32,48.55],[-17.32,76.55],[-64.32,68.01],[-64.32,-76.52],[-61.039,-75.22]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-167.32,93.55],[132.68,93.55],[132.68,-206.45],[-167.32,-206.45]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-167.32,-206.45],[132.68,-206.45],[132.68,93.55],[-167.32,93.55]],"c":true},"ix":2},"nm":"Trazado 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Combinar trazados 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.172999991623,0.243000000598,0.313999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[131.2,77.429],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[30.77,0],[23.34,38.3],[0,0],[-1.987,-1.96]],"o":[[-22.529,17.55],[-48.13,0],[0,0],[1.634,-2.264],[0,0]],"v":[[97.635,48.864],[15.995,76.865],[-97.635,12.995],[-34.613,-74.329],[-27.725,-74.905]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-134.005,93.865],[165.995,93.865],[165.995,-206.135],[-134.005,-206.135]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-134.005,-206.135],[165.995,-206.135],[165.995,93.865],[-134.005,93.865]],"c":true},"ix":2},"nm":"Trazado 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Combinar trazados 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.204000001795,0.286000001197,0.368999974868,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[97.885,77.115],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 2","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":89,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"CloudB contornos","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":32,"s":[181.824,192.221,0],"e":[216.824,192.221,0],"to":[5.83333349227905,0,0],"ti":[-5.83333349227905,0,0]},{"t":88}],"ix":2},"a":{"a":0,"k":[14.733,8.87,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.25,0.25,0.667],"y":[1,1,1]},"o":{"x":[0.75,0.75,0.333],"y":[0,0,0]},"n":["0p25_1_0p75_0","0p25_1_0p75_0","0p667_1_0p333_0"],"t":17,"s":[100,0,100],"e":[100,110,100]},{"i":{"x":[0.25,0.25,0.667],"y":[1,1,1]},"o":{"x":[0.75,0.75,0.333],"y":[0,0,0]},"n":["0p25_1_0p75_0","0p25_1_0p75_0","0p667_1_0p333_0"],"t":24,"s":[100,110,100],"e":[100,90,100]},{"i":{"x":[0.25,0.25,0.667],"y":[1,1,1]},"o":{"x":[0.75,0.75,0.333],"y":[0,0,0]},"n":["0p25_1_0p75_0","0p25_1_0p75_0","0p667_1_0p333_0"],"t":29,"s":[100,90,100],"e":[100,100,100]},{"t":31}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.392,-3.246],[3.246,0.392],[-0.391,3.246],[-3.246,-0.392]],"o":[[-0.391,3.246],[-3.246,-0.391],[0.391,-3.246],[3.246,0.391]],"v":[[5.877,0.708],[-0.709,5.878],[-5.878,-0.709],[0.708,-5.878]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-190.038,106.159],[109.962,106.159],[109.962,-193.841],[-190.038,-193.841]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-190.038,-193.841],[109.962,-193.841],[109.962,106.159],[-190.038,106.159]],"c":true},"ix":2},"nm":"Trazado 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Combinar trazados 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.808000033509,0.808000033509,0.808000033509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[22.948,10.49],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.245,-2.028],[2.029,0.245],[-0.244,2.029],[-2.029,-0.244]],"o":[[-0.244,2.029],[-2.029,-0.245],[0.244,-2.029],[2.029,0.245]],"v":[[3.673,0.442],[-0.443,3.673],[-3.674,-0.443],[0.443,-3.674]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-191.304,110.478],[108.696,110.478],[108.696,-189.522],[-191.304,-189.522]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-191.304,-189.522],[108.696,-189.522],[108.696,110.478],[-191.304,110.478]],"c":true},"ix":2},"nm":"Trazado 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Combinar trazados 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.808000033509,0.808000033509,0.808000033509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[24.213,6.171],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 2","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.391,-3.246],[3.246,0.391],[-0.39,3.246],[-3.246,-0.391]],"o":[[-0.392,3.246],[-3.246,-0.392],[0.392,-3.246],[3.246,0.392]],"v":[[5.878,0.708],[-0.709,5.878],[-5.879,-0.708],[0.708,-5.878]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-173.609,105.902],[126.391,105.902],[126.391,-194.098],[-173.609,-194.098]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-173.609,-194.098],[126.391,-194.098],[126.391,105.902],[-173.609,105.902]],"c":true},"ix":2},"nm":"Trazado 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Combinar trazados 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.808000033509,0.808000033509,0.808000033509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[6.518,10.746],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 3","np":4,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.538,-4.464],[4.464,0.539],[-0.538,4.464],[-4.464,-0.538]],"o":[[-0.537,4.463],[-4.463,-0.538],[0.538,-4.463],[4.463,0.538]],"v":[[8.082,0.974],[-0.975,8.081],[-8.082,-0.974],[0.975,-8.082]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-182.779,107.779],[117.221,107.779],[117.221,-192.221],[-182.779,-192.221]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-182.779,-192.221],[117.221,-192.221],[117.221,107.779],[-182.779,107.779]],"c":true},"ix":2},"nm":"Trazado 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Combinar trazados 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.808000033509,0.808000033509,0.808000033509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[15.689,8.87],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 4","np":4,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":89,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Circle 3","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,150,0],"ix":2},"a":{"a":0,"k":[137.25,137.25,0],"ix":1},"s":{"a":0,"k":[96.667,96.667,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-75.663],[75.663,0],[0,75.663],[-75.663,0]],"o":[[0,75.663],[-75.663,0],[0,-75.663],[75.663,0]],"v":[[137,0],[0,137],[-137,0],[0,-137]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-150,150],[150,150],[150,-150],[-150,-150]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-150,-150],[150,-150],[150,150],[-150,150]],"c":true},"ix":2},"nm":"Trazado 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Combinar trazados 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.081999999402,0.626999978458,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[137.25,137.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":89,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"MountainB contornos","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[174.57,280.73,0],"ix":2},"a":{"a":0,"k":[0.249,105.98,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.25,0.25,0.667],"y":[1,1,1]},"o":{"x":[0.75,0.75,0.333],"y":[0,0,0]},"n":["0p25_1_0p75_0","0p25_1_0p75_0","0p667_1_0p333_0"],"t":0,"s":[100,0,100],"e":[100,110,100]},{"i":{"x":[0.25,0.25,0.667],"y":[1,1,1]},"o":{"x":[0.75,0.75,0.333],"y":[0,0,0]},"n":["0p25_1_0p75_0","0p25_1_0p75_0","0p667_1_0p333_0"],"t":7,"s":[100,110,100],"e":[100,90,100]},{"i":{"x":[0.25,0.25,0.667],"y":[1,1,1]},"o":{"x":[0.75,0.75,0.333],"y":[0,0,0]},"n":["0p25_1_0p75_0","0p25_1_0p75_0","0p667_1_0p333_0"],"t":12,"s":[100,90,100],"e":[100,100,100]},{"t":14}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[36.889,-6.891],[0,0]],"o":[[-19.399,30.58],[0,0],[0,0]],"v":[[43.91,-6.726],[-43.91,52.866],[8.52,-52.866]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-218.48,72.135],[81.52,72.135],[81.52,-227.865],[-218.48,-227.865]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-218.48,-227.865],[81.52,-227.865],[81.52,72.135],[-218.48,72.135]],"c":true},"ix":2},"nm":"Trazado 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Combinar trazados 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.109999997008,0.165000002992,0.20800000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[44.159,53.116],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":89,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Circle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,150,0],"ix":2},"a":{"a":0,"k":[137.25,137.25,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-75.663],[75.663,0],[0,75.663],[-75.663,0]],"o":[[0,75.663],[-75.663,0],[0,-75.663],[75.663,0]],"v":[[137,0],[0,137],[-137,0],[0,-137]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-150,150],[150,150],[150,-150],[-150,-150]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-150,-150],[150,-150],[150,150],[-150,150]],"c":true},"ix":2},"nm":"Trazado 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Combinar trazados 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.081999999402,0.626999978458,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[137.25,137.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":89,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/abstract_circle.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/abstract_circle.json deleted file mode 100644 index 8b10f9ae..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/abstract_circle.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.16","fr":15,"ip":0,"op":51,"w":500,"h":500,"nm":"El 28","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Circle Abstract","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":49,"s":[100],"e":[0]},{"t":51}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250.316,250.684,0],"ix":2},"a":{"a":0,"k":[280,0,0],"ix":1},"s":{"a":0,"k":[225,225,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[145,145],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.190695878571,0.889764404297,0.972549019608,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.583]},"o":{"x":[0.01],"y":[0.006]},"n":["0p833_0p583_0p01_0p006"],"t":22.2,"s":[3],"e":[0]},{"t":49.2001953125}],"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[236,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.99,0.99],"y":[0.997,0.997]},"o":{"x":[1,1],"y":[1,1]},"n":["0p99_0p997_1_1","0p99_0p997_1_1"],"t":0,"s":[0,0],"e":[50,50]},{"i":{"x":[0.833,0.833],"y":[0.676,0.676]},"o":{"x":[0.01,0.01],"y":[0.043,0.043]},"n":["0p833_0p676_0p01_0p043","0p833_0p676_0p01_0p043"],"t":6,"s":[50,50],"e":[75,75]},{"t":49.2001953125}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"rp","c":{"a":1,"k":[{"i":{"x":[0.99],"y":[0.985]},"o":{"x":[1],"y":[2.692]},"n":["0p99_0p985_1_2p692"],"t":0,"s":[0],"e":[18]},{"i":{"x":[0.833],"y":[0.288]},"o":{"x":[0.01],"y":[-0.02]},"n":["0p833_0p288_0p01_-0p02"],"t":21,"s":[18],"e":[0]},{"t":49.2001953125}],"ix":1},"o":{"a":0,"k":5,"ix":2},"m":1,"ix":2,"tr":{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[280,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":20,"ix":4},"so":{"a":0,"k":100,"ix":5},"eo":{"a":0,"k":100,"ix":6},"nm":"Transform"},"nm":"Repeater 1","mn":"ADBE Vector Filter - Repeater","hd":false}],"ip":0,"op":51,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/acrobatics.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/acrobatics.json deleted file mode 100644 index 7dce062f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/acrobatics.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.0.5","fr":29.9700012207031,"ip":0,"op":46.0000018736184,"w":288,"h":360,"nm":"jump","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"a7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[29],"e":[-23]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[-23],"e":[-52]},{"t":30.0000012219251}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.585,"y":0.651},"o":{"x":0.232,"y":0.316},"n":"0p585_0p651_0p232_0p316","t":0,"s":[223.86,137.848,0],"e":[173.574,30.76,0],"to":[-1.73460388183594,-57.7228088378906,0],"ti":[29.553560256958,21.1779880523682,0]},{"i":{"x":0.649,"y":0.681},"o":{"x":0.307,"y":0.343},"n":"0p649_0p681_0p307_0p343","t":5,"s":[173.574,30.76,0],"e":[85.663,23.367,0],"to":[-27.3250160217285,-19.5810222625732,0],"ti":[26.9960441589355,-14.1411228179932,0]},{"i":{"x":0.671,"y":0.846},"o":{"x":0.331,"y":0.195},"n":"0p671_0p846_0p331_0p195","t":10,"s":[85.663,23.367,0],"e":[36.511,149.665,0],"to":[-19.3489608764648,10.1354112625122,0],"ti":[-6.15889406204224,-86.5106048583984,0]},{"i":{"x":0.696,"y":0.889},"o":{"x":0.354,"y":0.179},"n":"0p696_0p889_0p354_0p179","t":15,"s":[36.511,149.665,0],"e":[74.554,29.842,0],"to":[1.17162692546844,16.4571990966797,0],"ti":[-42.0285682678223,27.0350360870361,0]},{"i":{"x":0.652,"y":0.943},"o":{"x":0.268,"y":0.138},"n":"0p652_0p943_0p268_0p138","t":20,"s":[74.554,29.842,0],"e":[163.85,25.327,0],"to":[50.7120628356934,-30.1498985290527,0],"ti":[-6.47687864303589,-3.83117437362671,0]},{"i":{"x":0.855,"y":0.672},"o":{"x":0.451,"y":0.05},"n":"0p855_0p672_0p451_0p05","t":25,"s":[163.85,25.327,0],"e":[223.441,143.403,0],"to":[73.0731658935547,50.364128112793,0],"ti":[-1.62066376209259,-0.90557879209518,0]},{"i":{"x":0.585,"y":0.656},"o":{"x":0.262,"y":0.658},"n":"0p585_0p656_0p262_0p658","t":30,"s":[223.441,143.403,0],"e":[173.574,30.76,0],"to":[1.62066376209259,0.90557879209518,0],"ti":[29.553560256958,21.1779880523682,0]},{"i":{"x":0.649,"y":0.681},"o":{"x":0.307,"y":0.343},"n":"0p649_0p681_0p307_0p343","t":35,"s":[173.574,30.76,0],"e":[85.663,23.367,0],"to":[-27.3250160217285,-19.5810222625732,0],"ti":[26.9960441589355,-14.1411228179932,0]},{"i":{"x":0.671,"y":0.75},"o":{"x":0.331,"y":0.315},"n":"0p671_0p75_0p331_0p315","t":40,"s":[85.663,23.367,0],"e":[63.011,118.165,0],"to":[-19.3489608764648,10.1354112625122,0],"ti":[-21.1588935852051,-45.0106010437012,0]},{"t":46.0000018736184}],"ix":2},"a":{"a":0,"k":[49.985,49.973,0],"ix":1},"s":{"a":0,"k":[-50.014,50.014,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.5,-8.4],[8.4,1.6],[0.199,0.1],[2.599,-0.9],[0.201,0],[1.6,8.5],[-8.5,1.6],[-2.8,-1.2],[0,0],[0,0],[2.9,2.9],[0,0],[-4.2,-4.1],[-0.2,-2.1],[0,0],[-0.5,-0.3],[0.299,-0.5],[0,0],[-0.7,0.3],[-3.2,-0.6]],"o":[[-1.6,8.5],[-0.3,0],[-2.5,-0.9],[-0.201,0.1],[-8.5,1.6],[-1.6,-8.5],[3.2,-0.6],[1,0.5],[0,0],[-2,0],[-4.199,-4.2],[0,0],[2.3,2.3],[0,0],[0.3,-0.5],[0.5,0.3],[0,0],[0.801,-0.1],[2.8,-1.3],[8.5,1.5]],"v":[[25.65,1.6],[4.65,29.5],[3.951,29.3],[-3.749,29.3],[-4.45,29.5],[-25.55,1.6],[-13.05,-16.6],[-3.85,-15.5],[-0.749,-14.7],[0.45,-16.9],[-8.05,-20.3],[-11.35,-30.3],[-1.35,-27],[1.951,-19.7],[7.451,-29.9],[8.85,-30.3],[9.251,-28.9],[1.65,-14.7],[3.85,-15.4],[13.05,-16.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.988235294819,0.380392163992,0.411764711142,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[50.366,50.503],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":167.000006802049,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"a6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":29,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.67},"o":{"x":0.185,"y":0.366},"n":"0p833_0p67_0p185_0p366","t":0,"s":[186.985,40.473,0],"e":[216.985,116.473,0],"to":[1.01539611816406,-0.97280883789062,0],"ti":[6.98460388183594,-38.0271911621094,0]},{"i":{"x":0.833,"y":0.74},"o":{"x":0.185,"y":0.289},"n":"0p833_0p74_0p185_0p289","t":5,"s":[216.985,116.473,0],"e":[169.985,27.473,0],"to":[5.01539611816406,-38.4728088378906,0],"ti":[28.5490169525146,10.817400932312,0]},{"i":{"x":0.833,"y":0.716},"o":{"x":0.185,"y":0.315},"n":"0p833_0p716_0p185_0p315","t":10,"s":[169.985,27.473,0],"e":[76.485,28.973,0],"to":[-64,-24.25,0],"ti":[8.20706558227539,-7.81933689117432,0]},{"i":{"x":0.833,"y":0.732},"o":{"x":0.185,"y":0.298},"n":"0p833_0p732_0p185_0p298","t":15,"s":[76.485,28.973,0],"e":[42.485,121.973,0],"to":[-36.8030128479004,35.0643157958984,0],"ti":[-8.51539611816406,-3.02719116210938,0]},{"i":{"x":0.833,"y":0.756},"o":{"x":0.185,"y":0.271},"n":"0p833_0p756_0p185_0p271","t":20,"s":[42.485,121.973,0],"e":[85.485,24.473,0],"to":[-12.9846038818359,-63.4728088378906,0],"ti":[-12.5153961181641,8.47280883789062,0]},{"i":{"x":0.833,"y":0.717},"o":{"x":0.185,"y":0.314},"n":"0p833_0p717_0p185_0p314","t":25,"s":[85.485,24.473,0],"e":[178.485,31.973,0],"to":[40.0153961181641,-28.4728088378906,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.775},"o":{"x":0.167,"y":0.225},"n":"0p833_0p775_0p167_0p225","t":30,"s":[178.485,31.973,0],"e":[216.485,144.473,0],"to":[0,0,0],"ti":[16.4846038818359,-63.0271911621094,0]},{"i":{"x":0.833,"y":0.792},"o":{"x":0.185,"y":0.23},"n":"0p833_0p792_0p185_0p23","t":35,"s":[216.485,144.473,0],"e":[169.985,27.473,0],"to":[12.0153961181641,-51.9728088378906,0],"ti":[28.5490169525146,10.817400932312,0]},{"i":{"x":0.833,"y":0.669},"o":{"x":0.185,"y":0.368},"n":"0p833_0p669_0p185_0p368","t":40,"s":[169.985,27.473,0],"e":[73.485,29.473,0],"to":[-64,-24.25,0],"ti":[25.5490169525146,-10.682599067688,0]},{"t":46.0000018736184}],"ix":2},"a":{"a":0,"k":[49.985,49.973,0],"ix":1},"s":{"a":0,"k":[-50.014,50.014,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.5,-8.4],[8.4,1.6],[0.199,0.1],[2.599,-0.9],[0.201,0],[1.6,8.5],[-8.5,1.6],[-2.8,-1.2],[0,0],[0,0],[2.9,2.9],[0,0],[-4.2,-4.1],[-0.2,-2.1],[0,0],[-0.5,-0.3],[0.299,-0.5],[0,0],[-0.7,0.3],[-3.2,-0.6]],"o":[[-1.6,8.5],[-0.3,0],[-2.5,-0.9],[-0.201,0.1],[-8.5,1.6],[-1.6,-8.5],[3.2,-0.6],[1,0.5],[0,0],[-2,0],[-4.199,-4.2],[0,0],[2.3,2.3],[0,0],[0.3,-0.5],[0.5,0.3],[0,0],[0.801,-0.1],[2.8,-1.3],[8.5,1.5]],"v":[[25.65,1.6],[4.65,29.5],[3.951,29.3],[-3.749,29.3],[-4.45,29.5],[-25.55,1.6],[-13.05,-16.6],[-3.85,-15.5],[-0.749,-14.7],[0.45,-16.9],[-8.05,-20.3],[-11.35,-30.3],[-1.35,-27],[1.951,-19.7],[7.451,-29.9],[8.85,-30.3],[9.251,-28.9],[1.65,-14.7],[3.85,-15.4],[13.05,-16.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.988235294819,0.380392163992,0.411764711142,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[50.366,50.503],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":167.000006802049,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"a5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":29,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.585,"y":0.55},"o":{"x":0.185,"y":0.325},"n":"0p585_0p55_0p185_0p325","t":0,"s":[82.985,26.973,0],"e":[173.574,30.76,0],"to":[0.01539611816406,-3.97280883789062,0],"ti":[-43.4464416503906,-27.3220119476318,0]},{"i":{"x":0.585,"y":0.412},"o":{"x":0.303,"y":0.429},"n":"0p585_0p412_0p303_0p429","t":5,"s":[173.574,30.76,0],"e":[205.574,91.76,0],"to":[23.8329467773438,26.0342674255371,0],"ti":[6.07351684570312,9.26034545898438,0]},{"i":{"x":0.585,"y":0.449},"o":{"x":0.303,"y":0.402},"n":"0p585_0p449_0p303_0p402","t":10,"s":[205.574,91.76,0],"e":[167.074,25.76,0],"to":[-9.07351684570312,-39.7603454589844,0],"ti":[15.0735168457031,13.2603454589844,0]},{"i":{"x":0.585,"y":0.526},"o":{"x":0.303,"y":0.345},"n":"0p585_0p526_0p303_0p345","t":15,"s":[167.074,25.76,0],"e":[80.574,28.26,0],"to":[-48.5735168457031,-23.5103454589844,0],"ti":[8.82351684570312,-4.48965454101562,0]},{"i":{"x":0.585,"y":0.478},"o":{"x":0.303,"y":0.381},"n":"0p585_0p478_0p303_0p381","t":20,"s":[80.574,28.26,0],"e":[55.074,104.26,0],"to":[-26.8235168457031,30.9896545410156,0],"ti":[-2.42648315429688,-0.48965454101562,0]},{"i":{"x":0.585,"y":0.489},"o":{"x":0.303,"y":0.372},"n":"0p585_0p489_0p303_0p372","t":25,"s":[55.074,104.26,0],"e":[83.574,27.76,0],"to":[1.17648315429688,-59.2603454589844,0],"ti":[0,0,0]},{"i":{"x":0.585,"y":0.542},"o":{"x":0.167,"y":0.184},"n":"0p585_0p542_0p167_0p184","t":30,"s":[83.574,27.76,0],"e":[173.574,30.76,0],"to":[0,0,0],"ti":[-43.4464416503906,-27.3220119476318,0]},{"i":{"x":0.585,"y":0.624},"o":{"x":0.303,"y":0.274},"n":"0p585_0p624_0p303_0p274","t":35,"s":[173.574,30.76,0],"e":[217.074,133.26,0],"to":[23.8329467773438,26.0342674255371,0],"ti":[6.07351684570312,9.26034545898438,0]},{"i":{"x":0.585,"y":0.567},"o":{"x":0.303,"y":0.316},"n":"0p585_0p567_0p303_0p316","t":40,"s":[217.074,133.26,0],"e":[168.574,25.76,0],"to":[-17.0735168457031,-77.0103454589844,0],"ti":[6.07351684570312,9.26034545898438,0]},{"t":46.0000018736184}],"ix":2},"a":{"a":0,"k":[49.985,49.973,0],"ix":1},"s":{"a":0,"k":[-50.014,50.014,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.5,-8.4],[8.4,1.6],[0.199,0.1],[2.599,-0.9],[0.201,0],[1.6,8.5],[-8.5,1.6],[-2.8,-1.2],[0,0],[0,0],[2.9,2.9],[0,0],[-4.2,-4.1],[-0.2,-2.1],[0,0],[-0.5,-0.3],[0.299,-0.5],[0,0],[-0.7,0.3],[-3.2,-0.6]],"o":[[-1.6,8.5],[-0.3,0],[-2.5,-0.9],[-0.201,0.1],[-8.5,1.6],[-1.6,-8.5],[3.2,-0.6],[1,0.5],[0,0],[-2,0],[-4.199,-4.2],[0,0],[2.3,2.3],[0,0],[0.3,-0.5],[0.5,0.3],[0,0],[0.801,-0.1],[2.8,-1.3],[8.5,1.5]],"v":[[25.65,1.6],[4.65,29.5],[3.951,29.3],[-3.749,29.3],[-4.45,29.5],[-25.55,1.6],[-13.05,-16.6],[-3.85,-15.5],[-0.749,-14.7],[0.45,-16.9],[-8.05,-20.3],[-11.35,-30.3],[-1.35,-27],[1.951,-19.7],[7.451,-29.9],[8.85,-30.3],[9.251,-28.9],[1.65,-14.7],[3.85,-15.4],[13.05,-16.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.986887276173,0.380120933056,0.411817699671,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[50.125,50.785],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":167.000006802049,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"a1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":29,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.732},"o":{"x":0.185,"y":0.298},"n":"0p833_0p732_0p185_0p298","t":0,"s":[59.985,118.973,0],"e":[82.985,26.973,0],"to":[-19.4846038818359,-32.9728088378906,0],"ti":[-31.0153961181641,26.4728088378906,0]},{"i":{"x":0.833,"y":0.675},"o":{"x":0.185,"y":0.361},"n":"0p833_0p675_0p185_0p361","t":5,"s":[82.985,26.973,0],"e":[162.985,24.473,0],"to":[31.0153961181641,-26.4728088378906,0],"ti":[-21.0153961181641,-9.52719116210938,0]},{"i":{"x":0.833,"y":0.572},"o":{"x":0.185,"y":0.475},"n":"0p833_0p572_0p185_0p475","t":10,"s":[162.985,24.473,0],"e":[203.985,72.973,0],"to":[21.0153961181641,9.52719116210938,0],"ti":[-4.51539611816406,-16.5271911621094,0]},{"i":{"x":0.833,"y":0.556},"o":{"x":0.185,"y":0.493},"n":"0p833_0p556_0p185_0p493","t":15,"s":[203.985,72.973,0],"e":[165.485,24.973,0],"to":[-10.9846038818359,-31.4728088378906,0],"ti":[7.73460388183594,4.09780883789062,0]},{"i":{"x":0.833,"y":0.67},"o":{"x":0.185,"y":0.366},"n":"0p833_0p67_0p185_0p366","t":20,"s":[165.485,24.973,0],"e":[85.985,24.223,0],"to":[-51.1335983276367,-27.8870468139648,0],"ti":[2.48460388183594,-2.02719116210938,0]},{"i":{"x":0.833,"y":0.702},"o":{"x":0.185,"y":0.331},"n":"0p833_0p702_0p185_0p331","t":25,"s":[85.985,24.223,0],"e":[53.485,105.723,0],"to":[-50.724681854248,41.3863258361816,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.677},"o":{"x":0.167,"y":0.323},"n":"0p833_0p677_0p167_0p323","t":30,"s":[53.485,105.723,0],"e":[82.985,26.973,0],"to":[0,0,0],"ti":[-31.0153961181641,26.4728088378906,0]},{"i":{"x":0.833,"y":0.675},"o":{"x":0.185,"y":0.361},"n":"0p833_0p675_0p185_0p361","t":35,"s":[82.985,26.973,0],"e":[162.985,24.473,0],"to":[31.0153961181641,-26.4728088378906,0],"ti":[-21.0153961181641,-9.52719116210938,0]},{"i":{"x":0.833,"y":0.753},"o":{"x":0.185,"y":0.274},"n":"0p833_0p753_0p185_0p274","t":40,"s":[162.985,24.473,0],"e":[219.985,140.473,0],"to":[21.0153961181641,9.52719116210938,0],"ti":[-15.0153961181641,-99.0271911621094,0]},{"t":46.0000018736184}],"ix":2},"a":{"a":0,"k":[49.985,49.973,0],"ix":1},"s":{"a":0,"k":[-50.014,50.014,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.5,-8.4],[8.4,1.6],[0.199,0.1],[2.599,-0.9],[0.201,0],[1.6,8.5],[-8.5,1.6],[-2.8,-1.2],[0,0],[0,0],[2.9,2.9],[0,0],[-4.2,-4.1],[-0.2,-2.1],[0,0],[-0.5,-0.3],[0.299,-0.5],[0,0],[-0.7,0.3],[-3.2,-0.6]],"o":[[-1.6,8.5],[-0.3,0],[-2.5,-0.9],[-0.201,0.1],[-8.5,1.6],[-1.6,-8.5],[3.2,-0.6],[1,0.5],[0,0],[-2,0],[-4.199,-4.2],[0,0],[2.3,2.3],[0,0],[0.3,-0.5],[0.5,0.3],[0,0],[0.801,-0.1],[2.8,-1.3],[8.5,1.5]],"v":[[25.65,1.6],[4.65,29.5],[3.951,29.3],[-3.749,29.3],[-4.45,29.5],[-25.55,1.6],[-13.05,-16.6],[-3.85,-15.5],[-0.749,-14.7],[0.45,-16.9],[-8.05,-20.3],[-11.35,-30.3],[-1.35,-27],[1.951,-19.7],[7.451,-29.9],[8.85,-30.3],[9.251,-28.9],[1.65,-14.7],[3.85,-15.4],[13.05,-16.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.988235294819,0.380392163992,0.411764711142,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[50.366,50.503],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":167.000006802049,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"teeth Outlines","parent":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[20.312,41.66,0],"ix":2},"a":{"a":0,"k":[3.718,3.618,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.646,-2.841],[2.087,-2.018],[-0.571,2.841],[-2.087,2.392]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[5.1,4.146],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.338,-2.982],[1.673,-2.18],[-0.039,2.982],[-1.673,2.673]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.923,3.232],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"right eye Outlines","parent":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[42.538,16.724,0],"e":[47.764,16.011,0],"to":[0.87093943357468,-0.11872462183237,0],"ti":[-0.05034303665161,-1.83084356784821,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[47.764,16.011,0],"e":[41.775,15.029,0],"to":[0.01295710168779,0.4712156355381,0],"ti":[3.24095487594604,-0.21771761775017,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":18,"s":[41.775,15.029,0],"e":[35.94,19.224,0],"to":[-2.2777636051178,0.15301331877708,0],"ti":[0.64945775270462,-2.75669002532959,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":19,"s":[35.94,19.224,0],"e":[37.155,29.03,0],"to":[-1.57354974746704,6.67909383773804,0],"ti":[0.77238988876343,-1.01815032958984,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[37.155,29.03,0],"e":[38.689,17.956,0],"to":[-0.66211730241776,0.87279099225998,0],"ti":[-4.08277225494385,3.6608738899231,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":30.5,"s":[38.689,17.956,0],"e":[46.673,19.389,0],"to":[4.08277225494385,-3.6608738899231,0],"ti":[0,0,0]},{"t":42.0000017106951}],"ix":2},"a":{"a":0,"k":[2.909,2.909,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[110,110,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":17,"s":[100,100,100],"e":[110,110,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":22,"s":[110,110,100],"e":[100,100,100]},{"t":42.0000017106951}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.86,-0.994],[0.994,-0.859],[0.86,0.994],[-0.994,0.86]],"o":[[0.86,0.994],[-0.993,0.86],[-0.86,-0.993],[0.993,-0.859]],"v":[[1.799,-1.557],[1.556,1.798],[-1.799,1.556],[-1.556,-1.799]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.349000010771,0.349000010771,0.349000010771,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[2.909,2.909],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"left eye Outlines","parent":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[20.352,12.353,0],"e":[23.754,15.218,0],"to":[0.75799149274826,-0.13729524612427,0],"ti":[1.20316421985626,-1.69811820983887,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[23.754,15.218,0],"e":[14.162,14.634,0],"to":[-0.43755486607552,0.61755484342575,0],"ti":[5.72465705871582,-5.02380609512329,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":18.75,"s":[14.162,14.634,0],"e":[14.48,23.107,0],"to":[-5.72465705871582,5.02380609512329,0],"ti":[1.21317493915558,0.42704656720161,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[14.48,23.107,0],"e":[14.053,13.997,0],"to":[-1.21317493915558,-0.42704656720161,0],"ti":[-4.91244649887085,5.34288120269775,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":29.75,"s":[14.053,13.997,0],"e":[23.538,15.395,0],"to":[4.91244649887085,-5.34288120269775,0],"ti":[-1.43252968788147,0.25947457551956,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[23.538,15.395,0],"e":[20.161,13.089,0],"to":[1.894491314888,-0.34314984083176,0],"ti":[-1.51578795909882,0.27455517649651,0]},{"t":47.0000019143492}],"ix":2},"a":{"a":0,"k":[2.909,2.909,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[110,110,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":17,"s":[100,100,100],"e":[110,110,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":22,"s":[110,110,100],"e":[100,100,100]},{"t":42.0000017106951}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.86,-0.994],[0.994,-0.859],[0.86,0.993],[-0.994,0.86]],"o":[[0.86,0.994],[-0.993,0.86],[-0.86,-0.993],[0.993,-0.859]],"v":[[1.799,-1.557],[1.556,1.798],[-1.799,1.556],[-1.556,-1.799]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.349000010771,0.349000010771,0.349000010771,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[2.909,2.909],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"right blush Outlines","parent":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[9.908,34.526,0],"ix":2},"a":{"a":0,"k":[4.844,4.952,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.811,2.618],[-2.549,-0.789],[0.811,-2.618],[2.549,0.79]],"o":[[0.811,-2.618],[2.548,0.79],[-0.811,2.619],[-2.548,-0.789]],"v":[[-4.615,-1.43],[1.469,-4.742],[4.615,1.428],[-1.469,4.739]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.976000019148,0.430999995213,0.430999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[4.844,4.952],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"left blush Outlines","parent":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[37.356,40.818,0],"ix":2},"a":{"a":0,"k":[5.879,5.991,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.756,-1.649],[1.716,2.869],[-2.756,1.649],[-1.716,-2.868]],"o":[[-2.756,1.649],[-1.716,-2.868],[2.756,-1.649],[1.716,2.868]],"v":[[3.107,5.193],[-4.99,2.986],[-3.107,-5.192],[4.99,-2.985]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.976000019148,0.430999995213,0.430999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[5.879,5.991],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"glass leg Outlines","parent":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[-42]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":17,"s":[-42],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":22,"s":[0],"e":[-42]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":42,"s":[-42],"e":[0]},{"t":47.0000019143492}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[58.822,31.197,0],"e":[64.21,21.554,0],"to":[0.89794141054153,-1.60704386234283,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[64.21,21.554,0],"e":[58.822,31.197,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[58.822,31.197,0],"e":[64.21,21.554,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[64.21,21.554,0],"e":[58.822,31.197,0],"to":[0,0,0],"ti":[0.89794141054153,-1.60704386234283,0]},{"t":47.0000019143492}],"ix":2},"a":{"a":0,"k":[10.014,11.241,0],"ix":1},"s":{"a":0,"k":[104.675,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[-1.819,-2.087],[-4.279,-4.91],[1.819,2.088],[4.279,4.91]],"o":[[4.278,4.91],[1.828,2.099],[-4.28,-4.91],[-1.829,-2.099]],"v":[[-7.945,-5.839],[4.892,8.892],[7.945,5.839],[-4.892,-8.892]],"c":true}],"e":[{"i":[[-1.819,-2.087],[-4.279,-4.91],[1.819,2.088],[4.279,4.91]],"o":[[4.278,4.91],[1.828,2.099],[-4.28,-4.91],[-1.829,-2.099]],"v":[[-7.945,-5.839],[1.191,4.186],[4.147,0.904],[-4.892,-8.892]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[{"i":[[-1.819,-2.087],[-4.279,-4.91],[1.819,2.088],[4.279,4.91]],"o":[[4.278,4.91],[1.828,2.099],[-4.28,-4.91],[-1.829,-2.099]],"v":[[-7.945,-5.839],[1.191,4.186],[4.147,0.904],[-4.892,-8.892]],"c":true}],"e":[{"i":[[-1.819,-2.087],[-4.279,-4.91],[1.819,2.088],[4.279,4.91]],"o":[[4.278,4.91],[1.828,2.099],[-4.28,-4.91],[-1.829,-2.099]],"v":[[-7.945,-5.839],[4.892,8.892],[7.945,5.839],[-4.892,-8.892]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[{"i":[[-1.819,-2.087],[-4.279,-4.91],[1.819,2.088],[4.279,4.91]],"o":[[4.278,4.91],[1.828,2.099],[-4.28,-4.91],[-1.829,-2.099]],"v":[[-7.945,-5.839],[4.892,8.892],[7.945,5.839],[-4.892,-8.892]],"c":true}],"e":[{"i":[[-1.819,-2.087],[-4.279,-4.91],[1.819,2.088],[4.279,4.91]],"o":[[4.278,4.91],[1.828,2.099],[-4.28,-4.91],[-1.829,-2.099]],"v":[[-7.945,-5.839],[1.191,4.186],[4.147,0.904],[-4.892,-8.892]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[{"i":[[-1.819,-2.087],[-4.279,-4.91],[1.819,2.088],[4.279,4.91]],"o":[[4.278,4.91],[1.828,2.099],[-4.28,-4.91],[-1.829,-2.099]],"v":[[-7.945,-5.839],[1.191,4.186],[4.147,0.904],[-4.892,-8.892]],"c":true}],"e":[{"i":[[-1.819,-2.087],[-4.279,-4.91],[1.819,2.088],[4.279,4.91]],"o":[[4.278,4.91],[1.828,2.099],[-4.28,-4.91],[-1.829,-2.099]],"v":[[-7.945,-5.839],[4.892,8.892],[7.945,5.839],[-4.892,-8.892]],"c":true}]},{"t":47.0000019143492}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.313999998803,0.365000017952,0.976000019148,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[10.014,11.241],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"glass mid","parent":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[31.189,19.107,0],"ix":2},"a":{"a":0,"k":[12.089,10.362,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-3.454,-3.454]],"o":[[0,0],[0,0]],"v":[[-3.454,0],[3.454,1.727]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.313999998803,0.365000017952,0.976000019148,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.454,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[12.089,10.362],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"right glass Outlines","parent":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[9]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":17,"s":[9],"e":[0]},{"t":22.0000008960784}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[42.247,23.795,0],"e":[42.247,19.795,0],"to":[0,-0.66666668653488,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[42.247,19.795,0],"e":[42.247,23.795,0],"to":[0,0,0],"ti":[0,-0.66666668653488,0]},{"t":22.0000008960784}],"ix":2},"a":{"a":0,"k":[18.398,18.804,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.726,-1.893],[3.751,3.273],[-3.663,4.242],[-3.679,-3.355],[-0.074,-2.34]],"o":[[-3.452,3.786],[-3.725,-3.252],[3.349,-3.877],[1.839,1.677],[0.074,2.339]],"v":[[7.221,6.114],[-5.691,6.896],[-6.101,-6.033],[6.811,-6.814],[9.689,-0.512]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.313999998803,0.365000017952,0.976000019148,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.454,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[18.398,18.804],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"right ear Outlines","parent":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":17,"s":[-14],"e":[-14]},{"t":42.0000017106951}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[68.438,22.11,0],"e":[59.029,9.437,0],"to":[-1.56817352771759,-2.11210107803345,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[59.029,9.437,0],"e":[68.438,22.11,0],"to":[0,0,0],"ti":[-0.69228959083557,-0.1520429700613,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[68.438,22.11,0],"e":[63.183,10.349,0],"to":[0.69228959083557,0.1520429700613,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[63.183,10.349,0],"e":[68.438,22.11,0],"to":[0,0,0],"ti":[-0.87588393688202,-1.96005809307098,0]},{"t":47.0000019143492}],"ix":2},"a":{"a":0,"k":[7.277,8.167,0],"ix":1},"s":{"a":0,"k":[87.794,95.636,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.205,"y":1},"o":{"x":1,"y":0},"n":"0p205_1_1_0","t":0,"s":[{"i":[[0.373,-0.494],[-4.647,-2.786],[-0.182,3.144],[3.477,0]],"o":[[-2.483,3.287],[1.628,0.976],[0.235,-4.094],[-1.392,0]],"v":[[-4.544,-7.153],[2.088,4.966],[8.16,-3.175],[-1.665,-7.917]],"c":true}],"e":[{"i":[[0.373,-0.494],[-4.647,-2.786],[-0.182,3.144],[3.477,0]],"o":[[-2.483,3.287],[1.628,0.976],[0.235,-4.094],[-1.392,0]],"v":[[-4.544,-7.153],[2.088,4.966],[8.16,-3.175],[-1.665,-7.917]],"c":true}]},{"i":{"x":1,"y":0.998},"o":{"x":1,"y":0},"n":"1_0p998_1_0","t":18,"s":[{"i":[[0.373,-0.494],[-4.647,-2.786],[-0.182,3.144],[3.477,0]],"o":[[-2.483,3.287],[1.628,0.976],[0.235,-4.094],[-1.392,0]],"v":[[-4.544,-7.153],[2.088,4.966],[8.16,-3.175],[-1.665,-7.917]],"c":true}],"e":[{"i":[[0.373,-0.494],[-4.647,-2.786],[-0.182,3.144],[3.477,0]],"o":[[-2.483,3.287],[1.628,0.976],[0.235,-4.094],[-1.392,0]],"v":[[-4.544,-7.153],[2.088,4.966],[8.16,-3.175],[-1.665,-7.917]],"c":true}]},{"i":{"x":0,"y":1},"o":{"x":0.052,"y":1},"n":"0_1_0p052_1","t":23,"s":[{"i":[[0.373,-0.494],[-4.647,-2.786],[-0.182,3.144],[3.477,0]],"o":[[-2.483,3.287],[1.628,0.976],[0.235,-4.094],[-1.392,0]],"v":[[-4.544,-7.153],[2.088,4.966],[8.16,-3.175],[-1.665,-7.917]],"c":true}],"e":[{"i":[[0.373,-0.494],[-4.647,-2.786],[-0.182,3.144],[3.477,0]],"o":[[-2.483,3.287],[1.628,0.976],[0.235,-4.094],[-1.392,0]],"v":[[-4.544,-7.153],[2.088,4.966],[8.16,-3.175],[-1.665,-7.917]],"c":true}]},{"t":34.0000013848484}],"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0.115,0.286],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[99.454,101.055],"ix":3},"r":{"a":0,"k":-1.33,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.984313726425,0.525490224361,0.537254929543,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[7.541,7.827],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[104.62,100.21],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"left glass Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[-24]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":17,"s":[-24],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":22,"s":[0],"e":[-3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":42,"s":[-3],"e":[0]},{"t":47.0000019143492}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[113.337,79.663,0],"e":[86.337,67.663,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[86.337,67.663,0],"e":[113.337,79.663,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[113.337,79.663,0],"e":[105.337,60.663,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[105.337,60.663,0],"e":[113.337,79.663,0],"to":[0,0,0],"ti":[0,0,0]},{"t":47.0000019143492}],"ix":2},"a":{"a":0,"k":[18.693,18.548,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[4.149,-2.624],[2.546,4.026],[-4.149,2.623],[-2.546,-4.025]],"o":[[-4.149,2.624],[-2.546,-4.025],[4.149,-2.624],[2.546,4.026]],"v":[[4.611,7.289],[-7.512,4.751],[-4.609,-7.29],[7.512,-4.752]],"c":true}],"e":[{"i":[[4.149,-2.624],[2.546,4.026],[-4.149,2.623],[-2.546,-4.025]],"o":[[-4.149,2.624],[-2.546,-4.025],[4.149,-2.624],[2.546,4.026]],"v":[[4.611,7.289],[-7.512,4.751],[-4.609,-7.29],[7.512,-4.752]],"c":true}]},{"t":47.0000019143492}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.313999998803,0.365000017952,0.976000019148,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.454,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[18.693,18.548],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"right leg Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[-21]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":17,"s":[-21],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":42,"s":[2],"e":[0]},{"t":47.0000019143492}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[137.234,263.001,0],"e":[149.234,229.001,0],"to":[2,-5.66666650772095,0],"ti":[-1.5,-0.5,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[149.234,229.001,0],"e":[146.234,266.001,0],"to":[1.5,0.5,0],"ti":[3.5,-0.16666667163372,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[146.234,266.001,0],"e":[128.234,230.001,0],"to":[-3.5,0.16666667163372,0],"ti":[1.5,0.5,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[128.234,230.001,0],"e":[137.234,263.001,0],"to":[-1.5,-0.5,0],"ti":[-1.5,-5.5,0]},{"t":47.0000019143492}],"ix":2},"a":{"a":0,"k":[6.404,11.75,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[1.203,-6.24],[-7.402,0.838],[1.536,2.127],[0,0]],"o":[[-1.039,5.389],[4.747,-0.538],[0,0],[0,0]],"v":[[-10.659,2.429],[-9.691,18.566],[16.208,-23.499],[-4.812,-19.381]],"c":true}],"e":[{"i":[[3.453,-0.562],[-9.391,2.685],[1.536,2.127],[0,0]],"o":[[-5.722,0.931],[9.444,-2.7],[0,0],[0,0]],"v":[[-8.909,-9.07],[-7.939,-2.692],[7.715,-15.478],[-4.811,-19.381]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[{"i":[[3.453,-0.562],[-9.391,2.685],[1.536,2.127],[0,0]],"o":[[-5.722,0.931],[9.444,-2.7],[0,0],[0,0]],"v":[[-8.909,-9.07],[-7.939,-2.692],[7.715,-15.478],[-4.811,-19.381]],"c":true}],"e":[{"i":[[3.453,-0.562],[-9.391,2.685],[1.536,2.127],[0,0]],"o":[[-5.722,0.931],[9.444,-2.7],[0,0],[0,0]],"v":[[-8.909,-9.07],[-7.939,-2.692],[7.715,-15.478],[-4.811,-19.381]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[{"i":[[3.453,-0.562],[-9.391,2.685],[1.536,2.127],[0,0]],"o":[[-5.722,0.931],[9.444,-2.7],[0,0],[0,0]],"v":[[-8.909,-9.07],[-7.939,-2.692],[7.715,-15.478],[-4.811,-19.381]],"c":true}],"e":[{"i":[[3.453,-0.562],[-9.391,2.685],[1.536,2.127],[0,0]],"o":[[-5.722,0.931],[9.444,-2.7],[0,0],[0,0]],"v":[[-8.909,-9.07],[-7.939,-2.692],[7.715,-15.478],[-4.811,-19.381]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[{"i":[[3.453,-0.562],[-9.391,2.685],[1.536,2.127],[0,0]],"o":[[-5.722,0.931],[9.444,-2.7],[0,0],[0,0]],"v":[[-8.909,-9.07],[-7.939,-2.692],[7.715,-15.478],[-4.811,-19.381]],"c":true}],"e":[{"i":[[1.203,-6.24],[-7.402,0.838],[1.536,2.127],[0,0]],"o":[[-1.039,5.389],[4.747,-0.538],[0,0],[0,0]],"v":[[-10.659,2.43],[-11.187,28.112],[16.208,-23.499],[-4.811,-19.381]],"c":true}]},{"t":47.0000019143492}],"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,99.949],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.976470589638,0.57647061348,0.57647061348,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[9.625,19.807],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100.231,99.569],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"left leg Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[-7]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":17,"s":[-7],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":22,"s":[0],"e":[5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":42,"s":[5],"e":[0]},{"t":47.0000019143492}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[114.346,258.893,0],"e":[119.596,226.893,0],"to":[0.875,-5.33333349227905,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[119.596,226.893,0],"e":[119.846,266.393,0],"to":[0,0,0],"ti":[0.46127620339394,-2.81158828735352,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[119.846,266.393,0],"e":[97.596,219.893,0],"to":[-0.875,5.33333349227905,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[97.596,219.893,0],"e":[114.346,258.893,0],"to":[0,0,0],"ti":[-2.79166674613953,-6.5,0]},{"t":47.0000019143492}],"ix":2},"a":{"a":0,"k":[16.021,16.585,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[-12.369,-1.388],[2.77,3.145],[0,1.393],[0,0],[0,0]],"o":[[10.544,1.183],[-1.665,-1.89],[0,-7.65],[0,0],[0,0]],"v":[[4.143,8.543],[10.207,3.82],[6.493,-1.492],[0.929,-14.48],[-15.771,-16.335]],"c":true}],"e":[{"i":[[-11.149,1.063],[4.196,6.676],[0,0],[0,0],[0,0]],"o":[[4.05,-0.386],[-2.99,-4.757],[0,0],[0,0],[0,0]],"v":[[9.806,8.474],[5.06,-1.478],[2.993,-11.242],[0.928,-14.48],[-16.343,-15.672]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[{"i":[[-11.149,1.063],[4.196,6.676],[0,0],[0,0],[0,0]],"o":[[4.05,-0.386],[-2.99,-4.757],[0,0],[0,0],[0,0]],"v":[[9.806,8.474],[5.06,-1.478],[2.993,-11.242],[0.928,-14.48],[-16.343,-15.672]],"c":true}],"e":[{"i":[[-9.87,-7.218],[0.816,5.06],[0,1.393],[0,0],[0,0]],"o":[[5.454,3.988],[-0.463,-2.868],[0,-7.65],[0,0],[0,0]],"v":[[8.992,22.67],[9.912,7.963],[6.01,-5.865],[0.929,-14.48],[-19.64,-21.193]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[{"i":[[-9.87,-7.218],[0.816,5.06],[0,1.393],[0,0],[0,0]],"o":[[5.454,3.988],[-0.463,-2.868],[0,-7.65],[0,0],[0,0]],"v":[[8.992,22.67],[9.912,7.963],[6.01,-5.865],[0.929,-14.48],[-19.64,-21.193]],"c":true}],"e":[{"i":[[-11.149,1.063],[4.196,6.676],[0,0],[0,0],[0,0]],"o":[[4.05,-0.386],[-2.99,-4.757],[0,0],[0,0],[0,0]],"v":[[9.806,8.474],[5.06,-1.478],[2.993,-11.242],[0.928,-14.48],[-16.343,-15.672]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[{"i":[[-11.149,1.063],[4.196,6.676],[0,0],[0,0],[0,0]],"o":[[4.05,-0.386],[-2.99,-4.757],[0,0],[0,0],[0,0]],"v":[[9.806,8.474],[5.06,-1.478],[2.993,-11.242],[0.928,-14.48],[-16.343,-15.672]],"c":true}],"e":[{"i":[[-12.369,-1.388],[2.77,3.145],[0,1.393],[0,0],[0,0]],"o":[[10.544,1.183],[-1.665,-1.89],[0,-7.65],[0,0],[0,0]],"v":[[4.143,8.543],[10.207,3.82],[6.493,-1.492],[0.929,-14.48],[-15.771,-16.335]],"c":true}]},{"t":47.0000019143492}],"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.976470589638,0.57647061348,0.57647061348,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.083,16.789],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[103.391,102.914],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"body","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":22,"s":[0],"e":[14]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":42,"s":[14],"e":[0]},{"t":47.0000019143492}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[131.075,163.508,0],"e":[125.075,144.508,0],"to":[-1,-3.16666674613953,0],"ti":[0.16666667163372,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[125.075,144.508,0],"e":[130.075,163.508,0],"to":[-0.16666667163372,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[130.075,163.508,0],"e":[125.075,144.508,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[125.075,144.508,0],"e":[130.075,163.508,0],"to":[0,0,0],"ti":[-0.83333331346512,-3.16666674613953,0]},{"t":47.0000019143492}],"ix":2},"a":{"a":0,"k":[57.909,101.248,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[3.119,14.05],[1.443,14.3],[-2.17,13.017],[24.121,3.711],[1.855,-5.566],[0,0],[3.711,-9.276],[-0.497,-4.769],[0.927,-0.928],[1.074,-2.294],[1.392,-5.65],[-12.598,-18.435],[-23.003,15.653]],"o":[[-3.406,-15.344],[-0.176,-1.741],[1.856,-11.133],[-24.12,-3.711],[0,0],[0,0],[-0.436,1.09],[0.861,8.25],[-0.637,0.638],[-2.503,5.341],[-5.042,20.471],[16.307,23.863],[20.023,-13.625]],"v":[[114.214,133.19],[100.314,82.432],[100.948,46.636],[74.972,3.961],[34.153,24.371],[32.297,29.937],[21.165,41.069],[19.24,50.728],[25.804,69.828],[11.164,95.141],[5.292,111.681],[15.526,172.377],[93.31,188.365]],"c":true}],"e":[{"i":[[2.064,8.136],[5.519,9.808],[2.437,12.97],[31.861,-4.221],[0.18,-13.631],[0,0],[1.918,-5.829],[-4.252,-6.457],[0.927,-0.928],[6.669,-10.901],[0.041,-8.441],[-15.193,-18.637],[-23.788,14.432]],"o":[[-3.865,-15.235],[-0.858,-1.525],[-4.115,-21.896],[-12.162,1.611],[0,0],[0,0],[-0.367,1.115],[6.593,10.012],[-0.637,0.638],[-4.793,7.835],[-0.091,18.721],[14.406,17.672],[31.523,-19.125]],"v":[[116.714,116.69],[100.314,82.932],[88.948,43.136],[42.472,-1.539],[16.153,25.371],[16.797,38.187],[11.665,44.569],[11.74,60.728],[23.804,72.328],[12.164,86.641],[4.292,113.681],[19.026,162.377],[92.31,178.365]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[{"i":[[2.064,8.136],[5.519,9.808],[2.437,12.97],[31.861,-4.221],[0.18,-13.631],[0,0],[1.918,-5.829],[-4.252,-6.457],[0.927,-0.928],[6.669,-10.901],[0.041,-8.441],[-15.193,-18.637],[-23.788,14.432]],"o":[[-3.865,-15.235],[-0.858,-1.525],[-4.115,-21.896],[-12.162,1.611],[0,0],[0,0],[-0.367,1.115],[6.593,10.012],[-0.637,0.638],[-4.793,7.835],[-0.091,18.721],[14.406,17.672],[31.523,-19.125]],"v":[[116.714,116.69],[100.314,82.932],[88.948,43.136],[42.472,-1.539],[16.153,25.371],[16.797,38.187],[11.665,44.569],[11.74,60.728],[23.804,72.328],[12.164,86.641],[4.292,113.681],[19.026,162.377],[92.31,178.365]],"c":true}],"e":[{"i":[[3.119,14.05],[1.443,14.3],[-2.17,13.017],[24.121,3.711],[1.855,-5.566],[0,0],[3.711,-9.276],[-0.497,-4.769],[0.927,-0.928],[1.074,-2.294],[1.392,-5.65],[-12.598,-18.435],[-23.003,15.653]],"o":[[-3.406,-15.344],[-0.176,-1.741],[1.856,-11.133],[-24.12,-3.711],[0,0],[0,0],[-0.436,1.09],[0.861,8.25],[-0.637,0.638],[-2.503,5.341],[-5.042,20.471],[16.307,23.863],[20.023,-13.625]],"v":[[114.214,133.19],[100.314,82.432],[100.948,46.636],[74.972,3.961],[34.153,24.371],[32.297,29.937],[21.165,41.069],[19.24,50.728],[25.804,69.828],[11.164,95.141],[5.292,111.681],[15.526,172.377],[93.31,188.365]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[{"i":[[3.119,14.05],[1.443,14.3],[-2.17,13.017],[24.121,3.711],[1.855,-5.566],[0,0],[3.711,-9.276],[-0.497,-4.769],[0.927,-0.928],[1.074,-2.294],[1.392,-5.65],[-12.598,-18.435],[-23.003,15.653]],"o":[[-3.406,-15.344],[-0.176,-1.741],[1.856,-11.133],[-24.12,-3.711],[0,0],[0,0],[-0.436,1.09],[0.861,8.25],[-0.637,0.638],[-2.503,5.341],[-5.042,20.471],[16.307,23.863],[20.023,-13.625]],"v":[[114.214,133.19],[100.314,82.432],[100.948,46.636],[74.972,3.961],[34.153,24.371],[32.297,29.937],[21.165,41.069],[19.24,50.728],[25.804,69.828],[11.164,95.141],[5.292,111.681],[15.526,172.377],[93.31,188.365]],"c":true}],"e":[{"i":[[2.064,8.136],[5.519,9.808],[2.437,12.97],[31.861,-4.221],[0.18,-13.631],[0,0],[1.918,-5.829],[-4.252,-6.457],[0.927,-0.928],[6.669,-10.901],[0.041,-8.441],[-15.193,-18.637],[-23.788,14.432]],"o":[[-3.865,-15.235],[-0.858,-1.525],[-4.115,-21.896],[-12.162,1.611],[0,0],[0,0],[-0.367,1.115],[6.593,10.012],[-0.637,0.638],[-4.793,7.835],[-0.091,18.721],[14.406,17.672],[31.523,-19.125]],"v":[[116.714,116.69],[100.314,82.932],[88.948,43.136],[42.472,-1.539],[16.153,25.371],[16.797,38.187],[11.665,44.569],[11.74,60.728],[23.804,72.328],[12.164,86.641],[4.292,113.681],[19.026,162.377],[92.31,178.365]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[{"i":[[2.064,8.136],[5.519,9.808],[2.437,12.97],[31.861,-4.221],[0.18,-13.631],[0,0],[1.918,-5.829],[-4.252,-6.457],[0.927,-0.928],[6.669,-10.901],[0.041,-8.441],[-15.193,-18.637],[-23.788,14.432]],"o":[[-3.865,-15.235],[-0.858,-1.525],[-4.115,-21.896],[-12.162,1.611],[0,0],[0,0],[-0.367,1.115],[6.593,10.012],[-0.637,0.638],[-4.793,7.835],[-0.091,18.721],[14.406,17.672],[31.523,-19.125]],"v":[[116.714,116.69],[100.314,82.932],[88.948,43.136],[42.472,-1.539],[16.153,25.371],[16.797,38.187],[11.665,44.569],[11.74,60.728],[23.804,72.328],[12.164,86.641],[4.292,113.681],[19.026,162.377],[92.31,178.365]],"c":true}],"e":[{"i":[[3.119,14.05],[1.443,14.3],[-2.17,13.017],[24.121,3.711],[1.855,-5.566],[0,0],[3.711,-9.276],[-0.497,-4.769],[0.927,-0.928],[1.074,-2.294],[1.392,-5.65],[-12.598,-18.435],[-23.003,15.653]],"o":[[-3.406,-15.344],[-0.176,-1.741],[1.856,-11.133],[-24.12,-3.711],[0,0],[0,0],[-0.436,1.09],[0.861,8.25],[-0.637,0.638],[-2.503,5.341],[-5.042,20.471],[16.307,23.863],[20.023,-13.625]],"v":[[114.214,133.19],[100.314,82.432],[100.948,46.636],[74.972,3.961],[34.153,24.371],[32.297,29.937],[21.165,41.069],[19.24,50.728],[25.804,69.828],[11.164,95.141],[5.292,111.681],[15.526,172.377],[93.31,188.365]],"c":true}]},{"t":47.0000019143492}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.976000019148,0.57599995931,0.57599995931,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"left ear","parent":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[47.905,119.544,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[76.687,99.836,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[13,-4.5],[0,0],[0,0]],"o":[[-10.459,3.62],[0,0],[0,0]],"v":[[-8,-120.5],[-19.5,-109.5],[1.932,-112.016]],"c":true}],"e":[{"i":[[10.44,-3.65],[0,0],[0,0]],"o":[[-10.448,3.653],[0,0],[0,0]],"v":[[-26.889,-117.04],[-18.018,-107.449],[-7.084,-114.234]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[{"i":[[10.44,-3.65],[0,0],[0,0]],"o":[[-10.448,3.653],[0,0],[0,0]],"v":[[-26.889,-117.04],[-18.018,-107.449],[-7.084,-114.234]],"c":true}],"e":[{"i":[[14.183,-1.941],[0,0],[0,0]],"o":[[-18.722,2.562],[0,0],[0,0]],"v":[[-3.16,-120.237],[-19.5,-109.5],[1.932,-112.016]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[{"i":[[14.183,-1.941],[0,0],[0,0]],"o":[[-18.722,2.562],[0,0],[0,0]],"v":[[-3.16,-120.237],[-19.5,-109.5],[1.932,-112.016]],"c":true}],"e":[{"i":[[10.932,1.606],[0,0],[0,0]],"o":[[-21.367,-3.138],[0,0],[0,0]],"v":[[3.658,-121.26],[-24.796,-110.572],[-6.371,-112.546]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[{"i":[[10.932,1.606],[0,0],[0,0]],"o":[[-21.367,-3.138],[0,0],[0,0]],"v":[[3.658,-121.26],[-24.796,-110.572],[-6.371,-112.546]],"c":true}],"e":[{"i":[[13,-4.5],[0,0],[0,0]],"o":[[-10.459,3.62],[0,0],[0,0]],"v":[[-8,-120.5],[-19.5,-109.5],[1.932,-112.016]],"c":true}]},{"t":47.0000019143492}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952941179276,0.509803950787,0.501960813999,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[101.015,100.81],"ix":3},"r":{"a":0,"k":0.022,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"right arm Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[171.186,127.399,0],"ix":2},"a":{"a":0,"k":[52.548,63.288,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[-11.104,-11.125],[-10.566,6.314],[-2.469,1.867],[-0.826,0.524],[0.43,1.436],[0.92,0.748],[2.738,-0.091],[2.379,-0.189],[7.807,0.614],[4.254,0.971]],"o":[[10.295,-6.33],[3.554,-2.124],[0.935,-0.707],[4.367,-2.771],[-0.501,-1.673],[-1.395,-1.134],[-1.711,0.057],[-4.64,0.37],[-18.768,-1.478],[8.543,11.558]],"v":[[-19.199,20.792],[15.781,0.985],[24.956,-5.034],[33.911,-2.903],[32.779,-11.406],[28.355,-15.942],[22.268,-17.235],[16.161,-16.8],[-2.301,-16.674],[-32.458,-20.792]],"c":true}],"e":[{"i":[[-11.104,-11.125],[-15.5,5.99],[-2.532,1.977],[-0.818,0.548],[1.315,0.658],[2.733,-1.47],[2.307,-0.855],[2.425,-0.21],[7.873,0.585],[4.207,1.23]],"o":[[10.722,-6.116],[4.08,-1.577],[0.941,-0.73],[4.189,-2.716],[-6.288,-3.145],[-1.576,0.848],[-1.622,0.601],[-4.686,0.403],[-18.771,-1.407],[7.528,11.882]],"v":[[-20.519,21.393],[8.649,4.112],[26.044,-4.509],[33.858,-10.09],[38.489,-23.076],[26.709,-19.924],[22.363,-17.256],[13.134,-18.87],[-8.198,-20.59],[-32.653,-20.553]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":1,"s":[{"i":[[-11.104,-11.125],[-15.5,5.99],[-2.532,1.977],[-0.818,0.548],[1.315,0.658],[2.733,-1.47],[2.307,-0.855],[2.425,-0.21],[7.873,0.585],[4.207,1.23]],"o":[[10.722,-6.116],[4.08,-1.577],[0.941,-0.73],[4.189,-2.716],[-6.288,-3.145],[-1.576,0.848],[-1.622,0.601],[-4.686,0.403],[-18.771,-1.407],[7.528,11.882]],"v":[[-20.519,21.393],[8.649,4.112],[26.044,-4.509],[33.858,-10.09],[38.489,-23.076],[26.709,-19.924],[22.363,-17.256],[13.134,-18.87],[-8.198,-20.59],[-32.653,-20.553]],"c":true}],"e":[{"i":[[-11.104,-11.125],[-14.505,10.067],[-3.542,3.728],[-1.091,0.379],[0.288,0.961],[0.755,0.802],[2.104,0.089],[3.158,-0.545],[8.937,0.129],[3.463,5.376]],"o":[[17.56,-2.697],[6.68,-4.636],[1.042,-1.097],[2.469,-0.858],[-0.436,-1.457],[-1.146,-1.217],[-2.026,-0.086],[-5.416,0.935],[-18.824,-0.272],[-8.717,17.058]],"v":[[-41.654,31.01],[10.463,7.876],[26.189,-5.06],[28.786,-8.112],[33.299,-14.684],[31.518,-23.387],[24.713,-25.943],[16.161,-16.8],[-8.385,-13.15],[-35.767,-16.742]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[{"i":[[-11.104,-11.125],[-14.505,10.067],[-3.542,3.728],[-1.091,0.379],[0.288,0.961],[0.755,0.802],[2.104,0.089],[3.158,-0.545],[8.937,0.129],[3.463,5.376]],"o":[[17.56,-2.697],[6.68,-4.636],[1.042,-1.097],[2.469,-0.858],[-0.436,-1.457],[-1.146,-1.217],[-2.026,-0.086],[-5.416,0.935],[-18.824,-0.272],[-8.717,17.058]],"v":[[-41.654,31.01],[10.463,7.876],[26.189,-5.06],[28.786,-8.112],[33.299,-14.684],[31.518,-23.387],[24.713,-25.943],[16.161,-16.8],[-8.385,-13.15],[-35.767,-16.742]],"c":true}],"e":[{"i":[[-11.104,-11.125],[-9.387,5.292],[-3.92,2.822],[-0.773,0.752],[-0.73,0.992],[5.019,-0.422],[2.101,0.07],[3.195,-0.254],[7.601,1.883],[4.254,0.971]],"o":[[9.446,-0.926],[6.596,-3.719],[1.154,-0.831],[1.526,-1.486],[1.973,-2.682],[-1.59,0.134],[-2.024,-0.067],[-4.64,0.37],[-17.269,-4.278],[8.543,11.558]],"v":[[-19.199,20.792],[9.216,3.798],[25.656,-6.016],[28.563,-8.391],[35.362,-14.602],[32.833,-21.042],[23.922,-17.241],[16.161,-16.8],[-4.885,-17.657],[-32.458,-20.792]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[{"i":[[-11.104,-11.125],[-9.387,5.292],[-3.92,2.822],[-0.773,0.752],[-0.73,0.992],[5.019,-0.422],[2.101,0.07],[3.195,-0.254],[7.601,1.883],[4.254,0.971]],"o":[[9.446,-0.926],[6.596,-3.719],[1.154,-0.831],[1.526,-1.486],[1.973,-2.682],[-1.59,0.134],[-2.024,-0.067],[-4.64,0.37],[-17.269,-4.278],[8.543,11.558]],"v":[[-19.199,20.792],[9.216,3.798],[25.656,-6.016],[28.563,-8.391],[35.362,-14.602],[32.833,-21.042],[23.922,-17.241],[16.161,-16.8],[-4.885,-17.657],[-32.458,-20.792]],"c":true}],"e":[{"i":[[-11.104,-11.125],[-10.566,6.314],[-2.638,2.383],[-0.503,0.637],[-0.393,0.923],[2.901,0.041],[2.651,-0.472],[3.195,-0.254],[7.807,0.614],[4.254,0.971]],"o":[[10.295,-6.33],[4.866,-2.908],[0.776,-0.701],[0.993,-1.259],[1.852,-4.349],[-1.596,-0.023],[-1.993,0.355],[-4.64,0.37],[-18.768,-1.478],[8.543,11.558]],"v":[[-19.199,20.792],[15.781,0.985],[27.397,-7.033],[29.325,-9.043],[32.427,-12.909],[31.801,-24.024],[23.922,-17.241],[16.161,-16.8],[-2.301,-16.674],[-32.458,-20.792]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[{"i":[[-11.104,-11.125],[-10.566,6.314],[-2.638,2.383],[-0.503,0.637],[-0.393,0.923],[2.901,0.041],[2.651,-0.472],[3.195,-0.254],[7.807,0.614],[4.254,0.971]],"o":[[10.295,-6.33],[4.866,-2.908],[0.776,-0.701],[0.993,-1.259],[1.852,-4.349],[-1.596,-0.023],[-1.993,0.355],[-4.64,0.37],[-18.768,-1.478],[8.543,11.558]],"v":[[-19.199,20.792],[15.781,0.985],[27.397,-7.033],[29.325,-9.043],[32.427,-12.909],[31.801,-24.024],[23.922,-17.241],[16.161,-16.8],[-2.301,-16.674],[-32.458,-20.792]],"c":true}],"e":[{"i":[[-11.104,-11.125],[-10.566,6.314],[-2.638,2.383],[-0.503,0.637],[0.288,0.961],[0.747,0.74],[2.101,0.07],[3.195,-0.254],[7.807,0.614],[4.254,0.971]],"o":[[10.295,-6.33],[4.866,-2.908],[0.776,-0.701],[0.993,-1.259],[-0.436,-1.457],[-1.134,-1.123],[-2.024,-0.067],[-4.64,0.37],[-18.768,-1.478],[8.543,11.558]],"v":[[-19.199,20.792],[15.781,0.985],[27.397,-7.033],[29.325,-9.043],[30.454,-12.39],[28.7,-15.633],[23.922,-17.241],[16.161,-16.8],[-2.301,-16.674],[-32.458,-20.792]],"c":true}]},{"t":47.0000019143492}],"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[0,0],"e":[-7.516,-68.234],"to":[-1.25260412693024,-11.3723955154419],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[-7.516,-68.234],"e":[0,0],"to":[0,0],"ti":[0.44322040677071,-8.47819042205811]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[0,0],"e":[-10.175,-17.365],"to":[-0.44322040677071,8.47819042205811],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[-10.175,-17.365],"e":[0,0],"to":[0,0],"ti":[-1.69582462310791,-2.89420580863953]},{"t":47.0000019143492}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[101.323,101.673],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[-34]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":17,"s":[-34],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":22,"s":[0],"e":[25.257]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":42,"s":[25.257],"e":[0]},{"t":47.0000019143492}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.976470589638,0.57647061348,0.57647061348,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[74.24,107.805],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[98.342,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"Tail Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[-33]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":17,"s":[-33],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":22,"s":[0],"e":[-17]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":42,"s":[-17],"e":[0]},{"t":47.0000019143492}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[212.335,167.723,0],"e":[190.335,118.723,0],"to":[-3.66666674613953,-8.16666698455811,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[190.335,118.723,0],"e":[212.335,167.723,0],"to":[0,0,0],"ti":[-0.83333331346512,-1.83333337306976,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[212.335,167.723,0],"e":[195.335,129.723,0],"to":[0.83333331346512,1.83333337306976,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[195.335,129.723,0],"e":[212.335,167.723,0],"to":[0,0,0],"ti":[-2.83333325386047,-6.33333349227905,0]},{"t":47.0000019143492}],"ix":2},"a":{"a":0,"k":[54.728,57.385,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[15.626,-43.075],[8.28,-11.357],[-20.938,9.59],[-4.438,25.785],[17.722,4.423],[2.676,0]],"o":[[-6.694,18.454],[12.237,-1.587],[23.8,-10.901],[3.197,-18.576],[-2.934,-0.733],[-23.09,0.001]],"v":[[-30.358,12.605],[-54.478,57.135],[-2.526,42.293],[51.281,-13.37],[30.872,-56.045],[22.465,-57.136]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952941179276,0.509803950787,0.501960813999,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[54.728,57.386],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":23,"ty":4,"nm":"left hand","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[-62]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":17,"s":[-62],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":22,"s":[0],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":42,"s":[2],"e":[0]},{"t":47.0000019143492}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[73.59,148.469,0],"e":[66.59,159.469,0],"to":[-1.16666662693024,1.83333337306976,0],"ti":[0.5,0.83333331346512,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[66.59,159.469,0],"e":[70.59,143.469,0],"to":[-0.5,-0.83333331346512,0],"ti":[-2.5,7.16666650772095,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[70.59,143.469,0],"e":[81.59,116.469,0],"to":[2.5,-7.16666650772095,0],"ti":[-0.5,-0.83333331346512,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[81.59,116.469,0],"e":[73.59,148.469,0],"to":[0.5,0.83333331346512,0],"ti":[1.33333337306976,-5.33333349227905,0]},{"t":47.0000019143492}],"ix":2},"a":{"a":0,"k":[26.314,29.276,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[2.354,-5.536],[-1.08,-3.642],[-22.462,-9.92],[-0.008,2.143],[8.241,2.434],[0.346,0.758],[2.55,0.62]],"o":[[-1.514,3.559],[2.627,8.841],[-1.75,-5.549],[-4.541,0.998],[-7.681,-2.268],[-0.844,-1.846],[-4.134,0.346]],"v":[[-24.551,-20.684],[-24.479,-9.865],[9.958,29.026],[26.064,-6.89],[3.748,-10.381],[-10.835,-16.004],[-14.424,-29.026]],"c":true}],"e":[{"i":[[-2.873,-10.082],[-1.08,-3.642],[-27.836,-10.69],[-0.008,2.143],[7.525,2.066],[0.88,0.302],[2.55,0.62]],"o":[[1.06,3.72],[2.627,8.841],[-1.75,-5.549],[-4.045,0.889],[-8.797,-2.415],[-5.212,-1.789],[1.105,-8.394]],"v":[[-30.277,-15.063],[-24.157,-9.482],[9.958,29.026],[38.112,-0.636],[3.547,-8.438],[-10.835,-16.004],[-22.437,-22.629]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[{"i":[[-2.873,-10.082],[-1.08,-3.642],[-27.836,-10.69],[-0.008,2.143],[7.525,2.066],[0.88,0.302],[2.55,0.62]],"o":[[1.06,3.72],[2.627,8.841],[-1.75,-5.549],[-4.045,0.889],[-8.797,-2.415],[-5.212,-1.789],[1.105,-8.394]],"v":[[-30.277,-15.063],[-24.157,-9.482],[9.958,29.026],[38.112,-0.636],[3.547,-8.438],[-10.835,-16.004],[-22.437,-22.629]],"c":true}],"e":[{"i":[[2.354,-5.536],[-1.08,-3.642],[-10.4,-18.741],[-0.008,2.143],[7.525,2.066],[0.386,0.847],[2.55,0.62]],"o":[[-1.514,3.559],[2.627,8.841],[-1.75,-5.549],[-4.045,0.889],[-8.797,-2.415],[-0.844,-1.846],[-4.134,0.346]],"v":[[-24.551,-20.684],[-24.479,-9.865],[9.958,29.026],[33.529,-4.995],[8.487,-12.851],[-10.835,-16.004],[-14.424,-29.026]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[{"i":[[2.354,-5.536],[-1.08,-3.642],[-10.4,-18.741],[-0.008,2.143],[7.525,2.066],[0.386,0.847],[2.55,0.62]],"o":[[-1.514,3.559],[2.627,8.841],[-1.75,-5.549],[-4.045,0.889],[-8.797,-2.415],[-0.844,-1.846],[-4.134,0.346]],"v":[[-24.551,-20.684],[-24.479,-9.865],[9.958,29.026],[33.529,-4.995],[8.487,-12.851],[-10.835,-16.004],[-14.424,-29.026]],"c":true}],"e":[{"i":[[-2.873,-10.082],[-1.08,-3.642],[-27.836,-10.69],[-0.008,2.143],[7.525,2.066],[0.88,0.302],[2.55,0.62]],"o":[[1.06,3.72],[2.627,8.841],[-1.75,-5.549],[-4.045,0.889],[-8.797,-2.415],[-5.212,-1.789],[1.105,-8.394]],"v":[[-30.277,-15.063],[-24.157,-9.482],[9.958,29.026],[38.112,-0.636],[3.547,-8.438],[-10.835,-16.004],[-22.437,-22.629]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[{"i":[[-2.873,-10.082],[-1.08,-3.642],[-27.836,-10.69],[-0.008,2.143],[7.525,2.066],[0.88,0.302],[2.55,0.62]],"o":[[1.06,3.72],[2.627,8.841],[-1.75,-5.549],[-4.045,0.889],[-8.797,-2.415],[-5.212,-1.789],[1.105,-8.394]],"v":[[-30.277,-15.063],[-24.157,-9.482],[9.958,29.026],[38.112,-0.636],[3.547,-8.438],[-10.835,-16.004],[-22.437,-22.629]],"c":true}],"e":[{"i":[[2.354,-5.536],[-1.08,-3.642],[-22.462,-9.92],[-0.008,2.143],[8.241,2.434],[0.346,0.758],[2.55,0.62]],"o":[[-1.514,3.559],[2.627,8.841],[-1.75,-5.549],[-4.541,0.998],[-7.681,-2.268],[-0.844,-1.846],[-4.134,0.346]],"v":[[-24.551,-20.684],[-24.479,-9.865],[9.958,29.026],[26.064,-6.89],[3.748,-10.381],[-10.835,-16.004],[-14.424,-29.026]],"c":true}]},{"t":47.0000019143492}],"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0.152,0.512],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.951700389385,0.511714220047,0.503170788288,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[26.602,29.879],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":24,"ty":4,"nm":"shadow","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[145,183,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[109.014,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[64.705,22.852],"e":[30,10.595]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":17,"s":[30,10.595],"e":[64.705,22.852]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":22,"s":[64.705,22.852],"e":[30,10.595]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":42,"s":[30,10.595],"e":[64.705,22.852]},{"t":46.0000018736184}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0.532000601292,0.344732820988,0.344732820988,1],"e":[0.361688107252,0.33187431097,0.33187431097,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":17,"s":[0.361688107252,0.33187431097,0.33187431097,1],"e":[0.532000601292,0.344732820988,0.344732820988,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":22,"s":[0.532000601292,0.344732820988,0.344732820988,1],"e":[0.361688107252,0.33187431097,0.33187431097,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":42,"s":[0.361688107252,0.33187431097,0.33187431097,1],"e":[0.532000601292,0.344732820988,0.344732820988,1]},{"t":46.0000018736184}],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[40],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":17,"s":[20],"e":[40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":22,"s":[40],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":42,"s":[20],"e":[40]},{"t":46.0000018736184}],"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-13.212,107.812],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[92.827,156.063],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":167.000006802049,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/anubis.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/anubis.json deleted file mode 100644 index 232779db..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/anubis.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.8","fr":60,"ip":3,"op":140,"w":500,"h":500,"nm":"ANUB","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"a","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-3.113,"ix":10},"p":{"a":0,"k":[327.214,315.758,0],"ix":2},"a":{"a":0,"k":[-17,77,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-20.2,"s":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}],"e":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-13.001,"s":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}],"e":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-3.399,"s":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}],"e":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":2.999,"s":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}],"e":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":13.4,"s":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}],"e":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20.599,"s":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}],"e":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":32.599,"s":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}],"e":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42.2,"s":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}],"e":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":49.999,"s":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}],"e":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":58.999,"s":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}],"e":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":66.2,"s":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}],"e":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":78.2,"s":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}],"e":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":87.8,"s":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}],"e":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":94.999,"s":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}],"e":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":104.599,"s":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}],"e":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":111.8,"s":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}],"e":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":123.8,"s":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}],"e":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":133.999,"s":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}],"e":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}]},{"t":138.99921875}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.149019607843,0.133333333333,0.109803921569,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":15,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-22,82],"ix":2},"a":{"a":0,"k":[-22,82],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-3,"op":289,"st":-20.2,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"b","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-6,"ix":10},"p":{"a":0,"k":[221.537,318.968,0],"ix":2},"a":{"a":0,"k":[-17,77,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-2.4,"s":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}],"e":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":3,"s":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}],"e":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":14.401,"s":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}],"e":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":21.6,"s":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}],"e":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":31.2,"s":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}],"e":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":43.2,"s":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}],"e":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":50.401,"s":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}],"e":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":60,"s":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}],"e":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":67.2,"s":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}],"e":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":76.799,"s":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}],"e":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":88.799,"s":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}],"e":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":96,"s":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}],"e":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":105.6,"s":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}],"e":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":112.799,"s":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}],"e":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":122.401,"s":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}],"e":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":132,"s":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}],"e":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}]},{"t":139.000390625}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.149019607843,0.133333333333,0.109803921569,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":15,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-22,82],"ix":2},"a":{"a":0,"k":[-22,82],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":288,"st":-2.4,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"c","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-3.113,"ix":10},"p":{"a":0,"k":[361.652,319.398,0],"ix":2},"a":{"a":0,"k":[-17,77,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-14.4,"s":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}],"e":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-7.201,"s":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}],"e":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-0.002,"s":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}],"e":[{"i":[[-3.791,-1.166],[-4.083,-10.915]],"o":[[3.791,1.166],[3.33,8.322]],"v":[[-17,75],[5.704,158.168]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":3,"s":[{"i":[[-3.791,-1.166],[-4.083,-10.915]],"o":[[3.791,1.166],[3.33,8.322]],"v":[[-17,75],[5.704,158.168]],"c":false}],"e":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":11.998,"s":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}],"e":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":21.6,"s":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}],"e":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":28.799,"s":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}],"e":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":38.399,"s":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}],"e":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":45.6,"s":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}],"e":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":57.6,"s":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}],"e":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":67.2,"s":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}],"e":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":74.399,"s":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}],"e":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":83.998,"s":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}],"e":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":91.2,"s":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}],"e":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":103.2,"s":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}],"e":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":112.799,"s":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}],"e":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":119.998,"s":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}],"e":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":130,"s":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}],"e":[{"i":[[-3.791,-1.166],[-4.083,-10.915]],"o":[[3.791,1.166],[3.33,8.322]],"v":[[-17,75],[5.704,158.168]],"c":false}]},{"t":139.000390625}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.149019607843,0.133333333333,0.109803921569,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":15,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-22,82],"ix":2},"a":{"a":0,"k":[-22,82],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-20,"op":279,"st":-14.4,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"d","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-6,"ix":10},"p":{"a":0,"k":[254.302,326.574,0],"ix":2},"a":{"a":0,"k":[-17,77,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-28.8,"s":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}],"e":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-21.601,"s":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}],"e":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-11.999,"s":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}],"e":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-4.8,"s":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}],"e":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":2.8,"s":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}],"e":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":16.8,"s":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}],"e":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":24.001,"s":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}],"e":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":33.6,"s":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}],"e":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":40.8,"s":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}],"e":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":50.399,"s":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}],"e":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":62.399,"s":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}],"e":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":69.6,"s":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}],"e":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":79.2,"s":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}],"e":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":86.399,"s":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}],"e":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":96.001,"s":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}],"e":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":106.001,"s":[{"i":[[-6.5,-2],[-4.5,-15.5]],"o":[[6.5,2],[3.209,11.054]],"v":[[-17,75],[18,154]],"c":false}],"e":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":113.2,"s":[{"i":[[-4.161,-1.28],[50.642,-32.142]],"o":[[4.161,1.28],[-33.86,21.491]],"v":[[-17,75],[1.858,129.142]],"c":false}],"e":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":121.001,"s":[{"i":[[0,0],[29.75,-14.5]],"o":[[0,0],[-29.75,14.5]],"v":[[-17,75],[-56.25,145.5]],"c":false}],"e":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":130.001,"s":[{"i":[[0,0],[-7.5,-34]],"o":[[0,0],[7.5,34]],"v":[[-17,75],[-61,161]],"c":false}],"e":[{"i":[[0,0],[-3.5,-4.5]],"o":[[0,0],[3.5,4.5]],"v":[[-17,75],[-11.5,164]],"c":false}]},{"t":139.00078125}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.149019607843,0.133333333333,0.109803921569,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":15,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-22,82],"ix":2},"a":{"a":0,"k":[-22,82],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":266,"st":-28.8,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"b2","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.25],"y":[1]},"o":{"x":[0.75],"y":[0]},"n":["0p25_1_0p75_0"],"t":0,"s":[-81],"e":[-97]},{"i":{"x":[0.25],"y":[1]},"o":{"x":[0.75],"y":[0]},"n":["0p25_1_0p75_0"],"t":67.199,"s":[-97],"e":[-81]},{"t":136.80078125}],"ix":10},"p":{"a":0,"k":[-13.573,-61.514,0],"ix":2},"a":{"a":0,"k":[-6,48,0],"ix":1},"s":{"a":0,"k":[73.171,73.171,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[82,82],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.149019607843,0.132484795065,0.111034221275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-6,48],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":141.6,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"b1","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-87,"ix":10},"p":{"a":0,"k":[-27.177,43.546,0],"ix":2},"a":{"a":0,"k":[-6,48,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"fl","c":{"a":0,"k":[0.149019607843,0.132484795065,0.111034221275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[82,82],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.149019607843,0.132484795065,0.111034221275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-6,48],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":141.6,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"b","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":83,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":5,"s":[355.857,302.207,0],"e":[355.857,308.207,0],"to":[0,1,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":16.801,"s":[355.857,308.207,0],"e":[355.857,302.207,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":33.6,"s":[355.857,302.207,0],"e":[355.857,308.207,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":50.4,"s":[355.857,308.207,0],"e":[355.857,302.207,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":67.199,"s":[355.857,302.207,0],"e":[355.857,308.207,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":84,"s":[355.857,308.207,0],"e":[355.857,302.207,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":100.801,"s":[355.857,302.207,0],"e":[355.857,308.207,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":120,"s":[355.857,308.207,0],"e":[355.857,302.207,0],"to":[0,0,0],"ti":[0,1,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":139,"s":[355.857,302.207,0],"e":[355.857,302.207,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":180,"s":[355.857,302.207,0],"e":[355.857,308.207,0],"to":[0,1,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":196.801,"s":[355.857,308.207,0],"e":[355.857,302.207,0],"to":[0,0,0],"ti":[0,1,0]},{"t":216}],"ix":2},"a":{"a":0,"k":[-5.706,-66.449,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.021,11.991],[1.75,-16.75],[3.593,-23.13],[3.492,-8.369],[0,23.5]],"o":[[-6.242,-14.906],[-1.081,10.349],[-2.222,14.305],[-14.312,34.299],[0,-55.082]],"v":[[14.5,-63],[-40.44,-62.693],[-44.148,-3.184],[-56.34,28.612],[12.218,41.438]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.149019607843,0.132484795065,0.111034221275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":141.6,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"ne","parent":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[0],"e":[20]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":67.199,"s":[20],"e":[0]},{"t":134.400390625}],"ix":10},"p":{"a":0,"k":[-12,50,0],"ix":2},"a":{"a":0,"k":[-12,50,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.59,12.987],[1.75,-16.75],[-1.434,-15.164],[4.955,22.972]],"o":[[-1,-22],[-1.75,16.75],[3.5,37],[-11,-51]],"v":[[3.5,-51.5],[-31.25,-48.25],[-45,45],[12,36.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.149019607843,0.132484795065,0.111034221275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":141.6,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"ta","parent":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[7],"e":[75]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":22.801,"s":[75],"e":[7]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":45.6,"s":[7],"e":[75]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":68.4,"s":[75],"e":[7]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":91.199,"s":[7],"e":[75]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":114,"s":[75],"e":[7]},{"t":136.80078125}],"ix":10},"p":{"a":0,"k":[15.301,27.13,0],"ix":2},"a":{"a":0,"k":[21.895,-104.814,0],"ix":1},"s":{"a":0,"k":[136.667,136.667,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.827,-5.636],[1.374,-48.171],[-2.647,2.438]],"o":[[33.061,38.596],[-0.068,2.375],[34.628,-76.569]],"v":[[-18.205,-190.23],[15.659,-106.249],[25.25,-102.254]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.149019607843,0.132484795065,0.111034221275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":141.6,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"el","parent":11,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[-17],"e":[41]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":62.4,"s":[41],"e":[-17]},{"t":129.599609375}],"ix":10},"p":{"a":0,"k":[-90.831,16.442,0],"ix":2},"a":{"a":0,"k":[16.5,-109.52,0],"ix":1},"s":{"a":0,"k":[140.26,140.26,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.618,-7.395],[-2.323,-2.379],[-2.647,2.438]],"o":[[6.75,80.75],[1.66,1.7],[38.998,-68.667]],"v":[[-1.601,-210.907],[11.871,-104.272],[20.531,-99.66]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.149019607843,0.132484795065,0.111034221275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":141.6,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"hea","parent":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[-15],"e":[8]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":67.199,"s":[8],"e":[-15]},{"t":134.400390625}],"ix":10},"p":{"a":0,"k":[-7.5,-46.5,0],"ix":2},"a":{"a":0,"k":[-110.468,94.987,0],"ix":1},"s":{"a":0,"k":[71.296,71.296,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"fl","c":{"a":0,"k":[0.149019607843,0.132484795065,0.111034221275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[14.727,19.286],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.149019607843,0.132484795065,0.111034221275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-175.409,43.844],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[59.914,100],"ix":3},"r":{"a":0,"k":-168.452,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 5","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[14.727,19.286],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.149019607843,0.132484795065,0.111034221275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-122.039,45.221],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 3","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-10.966,2.431],[-1.181,-4.133],[1.601,-0.057],[-0.599,3.554]],"o":[[1.746,-0.387],[1.277,4.469],[-14.816,0.529],[0.406,-2.406]],"v":[[-8.421,-5.275],[2.908,3.703],[-0.161,10.282],[-18.683,3.926]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333333333,0.874509803922,0.650980392157,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"eye1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-181.299,40.461],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":38.4,"s":[100,92.381],"e":[100,-0.256]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":55.199,"s":[100,-0.256],"e":[100,-0.256]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":62.4,"s":[100,-0.256],"e":[100,92.381]},{"t":79.19921875}],"ix":3},"r":{"a":0,"k":-128.667,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 6","np":3,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[40.675,16.831],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333333333,0.874509803922,0.650980392157,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"eye2","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-123.091,45.195],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":38.4,"s":[100,92.381],"e":[100,-0.256]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":55.199,"s":[100,-0.256],"e":[100,-0.256]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":62.4,"s":[100,-0.256],"e":[100,92.381]},{"t":79.19921875}],"ix":3},"r":{"a":0,"k":-19.654,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 2","np":3,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[10.344,0.175],[-115.817,6.255]],"o":[[0,0],[-7.047,-0.119],[34.894,-1.884]],"v":[[-167.279,58.669],[-254.234,57.818],[-149.783,98.993]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.149019607843,0.132484795065,0.111034221275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-162,72.234],"ix":2},"a":{"a":0,"k":[-164.104,75.74],"ix":1},"s":{"a":0,"k":[100.434,93.355],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[108,108],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.149019607843,0.132484795065,0.111034221275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-128,48],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":141.6,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"er","parent":11,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":7.199,"s":[-17],"e":[41]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":67.199,"s":[41],"e":[-17]},{"t":134.400390625}],"ix":10},"p":{"a":0,"k":[-151.699,7.848,0],"ix":2},"a":{"a":0,"k":[16.5,-109.52,0],"ix":1},"s":{"a":0,"k":[131.332,131.332,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.618,-7.395],[-2.323,-2.379],[-2.647,2.438]],"o":[[6.75,80.75],[1.66,1.7],[26.148,-64.813]],"v":[[-1.601,-210.907],[9.521,-107.006],[20.155,-104.319]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.149019607843,0.132484795065,0.111034221275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":141.6,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/ao.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/ao.json deleted file mode 100644 index 9f78a33c..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/ao.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.2.1","fr":60,"ip":0,"op":60,"w":500,"h":500,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-89.47,0],[0,-89.47],[89.47,0],[0,89.47]],"o":[[89.47,0],[0,89.47],[-89.47,0],[0,-89.47]],"v":[[0,-162],[162,0],[0,162],[-162,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":60,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.562,"y":0.562},"o":{"x":0.167,"y":0.167},"n":"0p562_0p562_0p167_0p167","t":8,"s":[250,88,0],"e":[412,250,0],"to":[89.4701232910156,0,0],"ti":[0,-89.4701232910156,0]},{"i":{"x":0.656,"y":0.656},"o":{"x":0.311,"y":0.311},"n":"0p656_0p656_0p311_0p311","t":38,"s":[412,250,0],"e":[250,412,0],"to":[0,89.4701232910156,0],"ti":[89.4701232910156,0,0]},{"i":{"x":0.689,"y":0.689},"o":{"x":0.343,"y":0.343},"n":"0p689_0p689_0p343_0p343","t":68,"s":[250,412,0],"e":[88,250,0],"to":[-89.4701232910156,0,0],"ti":[0,89.4701232910156,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.437,"y":0.437},"n":"0p833_0p833_0p437_0p437","t":98,"s":[88,250,0],"e":[250,88,0],"to":[0,-89.4701232910156,0],"ti":[-89.4701232910156,0,0]},{"t":128}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":1,"shapes":[{"ty":"rc","d":1,"s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":60,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/balloons_with_string.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/balloons_with_string.json deleted file mode 100644 index 49e71218..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/balloons_with_string.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.1","fr":60,"ip":0,"op":600,"w":1440,"h":2560,"nm":"Balloon Animation","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"pinkBalloon ","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.566,"y":0.555},"o":{"x":0.18,"y":0.163},"n":"0p566_0p555_0p18_0p163","t":52,"s":[856,3484.5,0],"e":[863.025,2076.672,0],"to":[1.26471793651581,-253.457336425781,0],"ti":[-3.05289053916931,611.818237304688,0]},{"i":{"x":0.841,"y":0.859},"o":{"x":0.385,"y":0.391},"n":"0p841_0p859_0p385_0p391","t":157.5,"s":[863.025,2076.672,0],"e":[875.959,-515.333,0],"to":[4.97676658630371,-997.374938964844,0],"ti":[-2.06172013282776,413.181518554688,0]},{"t":350}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[404.62,501.104],[403.62,497.604],[403.62,620.104],[405.62,622.104]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"String","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0.465349324544,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"greenBalloon 4","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.829},"o":{"x":0.167,"y":0.173},"n":"0p833_0p829_0p167_0p173","t":52,"s":[56,3300.5,0],"e":[315.448,-162.334,0],"to":[43.2412719726562,-577.138977050781,0],"ti":[-43.2412719726562,577.138977050781,0]},{"t":350}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,1,0.528860234279,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[404.62,501.104],[403.62,497.604],[403.62,620.104],[405.62,622.104]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"String","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"greenBalloon 3","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.851},"o":{"x":0.167,"y":0.16},"n":"0p833_0p851_0p167_0p16","t":148,"s":[1240,2924.5,0],"e":[1275.959,-478.276,0],"to":[5.99310493469238,-567.12939453125,0],"ti":[-5.99310493469238,567.12939453125,0]},{"t":402}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,1,0.528860234279,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[404.62,501.104],[403.62,497.604],[403.62,620.104],[405.62,622.104]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"String","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"greenBalloon 2","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.167},"n":"0p833_0p834_0p167_0p167","t":0,"s":[198,2837.667,0],"e":[762,-368.5,0],"to":[94,-534.361145019531,0],"ti":[-94,534.361145019531,0]},{"t":271}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,1,0.528860234279,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[404.62,501.104],[403.62,497.604],[403.62,620.104],[405.62,622.104]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"String","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"blueBalloon","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.83},"o":{"x":0.167,"y":0.198},"n":"0p833_0p83_0p167_0p198","t":23,"s":[1235.406,3127.833,0],"e":[761.634,-588.86,0],"to":[-78.9620056152344,-619.448791503906,0],"ti":[78.9620056152344,619.448791503906,0]},{"t":344}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.46011020436,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[404.62,501.104],[403.62,497.604],[403.62,620.104],[405.62,622.104]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"String","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"yellowBalloon","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.856},"o":{"x":0.167,"y":0.167},"n":"0p833_0p856_0p167_0p167","t":0,"s":[1235.406,3127.833,0],"e":[1211.959,-627.333,0],"to":[-3.90793800354004,-625.861022949219,0],"ti":[3.90793800354004,625.861022949219,0]},{"t":271}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.987591911765,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[404.62,501.104],[403.62,497.604],[403.62,620.104],[405.62,622.104]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"String","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"purpleBalloon","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.845},"o":{"x":0.167,"y":0.167},"n":"0p833_0p845_0p167_0p167","t":0,"s":[776,3020.5,0],"e":[539.959,-454.276,0],"to":[-39.3402290344238,-579.12939453125,0],"ti":[39.3402290344238,579.12939453125,0]},{"t":271}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.462959289551,0,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[404.62,501.104],[403.62,497.604],[403.62,620.104],[405.62,622.104]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"String","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"blueBallloon","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.863},"o":{"x":0.167,"y":0.134},"n":"0p833_0p863_0p167_0p134","t":106,"s":[512,2724.5,0],"e":[1162,-464.5,0],"to":[108.333335876465,-531.5,0],"ti":[-108.333335876465,531.5,0]},{"t":330}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.721047674441,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[404.62,501.104],[403.62,497.604],[403.62,620.104],[405.62,622.104]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"String","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"blueBalloon","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.869},"o":{"x":0.167,"y":0.128},"n":"0p833_0p869_0p167_0p128","t":191,"s":[1232,2996.5,0],"e":[831.959,-273.776,0],"to":[-60.6597709655762,-578.37939453125,0],"ti":[66.6735610961914,545.046020507812,0]},{"t":408}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.497150914809,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[404.62,501.104],[403.62,497.604],[403.62,620.104],[405.62,622.104]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"String","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"redBallloon","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.885},"o":{"x":0.167,"y":0.112},"n":"0p833_0p885_0p167_0p112","t":191,"s":[848,3476.5,0],"e":[604.041,-273.776,0],"to":[-60.6597709655762,-578.37939453125,0],"ti":[40.6597709655762,625.046020507812,0]},{"t":408}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0.392279561361,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[404.62,501.104],[403.62,497.604],[403.62,620.104],[405.62,622.104]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"String","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"yellowBallloon 3","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.877},"o":{"x":0.167,"y":0.121},"n":"0p833_0p877_0p167_0p121","t":191,"s":[272,3204.5,0],"e":[312.041,-293.667,0],"to":[6.67356204986572,-583.02783203125,0],"ti":[-6.67356204986572,583.02783203125,0]},{"t":408}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.949172794118,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[404.62,501.104],[403.62,497.604],[403.62,620.104],[405.62,622.104]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"String","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"yellowBallloon 2","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.841},"o":{"x":0.167,"y":0.156},"n":"0p833_0p841_0p167_0p156","t":121,"s":[512,2924.5,0],"e":[539.959,-454.276,0],"to":[4.65977144241333,-563.12939453125,0],"ti":[-4.65977144241333,563.12939453125,0]},{"t":391}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.949172794118,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[404.62,501.104],[403.62,497.604],[403.62,620.104],[405.62,622.104]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"String","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"yellowBallloon","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.863},"o":{"x":0.167,"y":0.134},"n":"0p833_0p863_0p167_0p134","t":106,"s":[1376,2804.5,0],"e":[312.041,-293.667,0],"to":[-177.326431274414,-516.361145019531,0],"ti":[177.326431274414,516.361145019531,0]},{"t":331}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.949172794118,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[404.62,501.104],[403.62,497.604],[403.62,620.104],[405.62,622.104]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"String","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"redBalloonNew","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.847},"o":{"x":0.167,"y":0.167},"n":"0p833_0p847_0p167_0p167","t":0,"s":[1016,2740.5,0],"e":[1098,-774.166,0],"to":[13.6666669845581,-585.777709960938,0],"ti":[-13.6666669845581,585.777709960938,0]},{"t":271}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0.404779561361,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[404.62,501.104],[403.62,497.604],[403.62,620.104],[405.62,622.104]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"String","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"greenBalloonNew","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[198,2984.5,0],"e":[718,-260,0],"to":[86.6666641235352,-540.75,0],"ti":[-86.6666641235352,540.75,0]},{"t":360}],"ix":2},"a":{"a":0,"k":[-100.906,408.167,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[404.62,501.104],[403.62,497.604],[403.62,620.104],[405.62,622.104],[402.076,560.068]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-503,38],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100.015,103.448],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"String","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,1,0.903125,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-100.906,394.391],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/bell.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/bell.json deleted file mode 100644 index c70f06bb..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/bell.json +++ /dev/null @@ -1 +0,0 @@ -{"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":0,"ty":1,"nm":"White Solid 1","td":1,"ks":{"o":{"k":100},"r":{"k":22},"p":{"k":[288.003,547.449,0]},"a":{"k":[25,25,0]},"s":{"k":[412,168,100]}},"ao":0,"sw":50,"sh":50,"sc":"#ffffff","ip":0,"op":50,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","tt":2,"ks":{"o":{"k":100},"r":{"k":22},"p":{"k":[273.145,580.253,0]},"a":{"k":[-0.776,155.616,0]},"s":{"k":[110.945,113.273,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[59.648,59.648]},"p":{"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"fl","fillEnabled":true,"c":{"k":[0,0,0,1]},"o":{"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[-1,155.5],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":50,"st":0,"bm":0,"sr":1}]}],"layers":[{"ddd":0,"ind":0,"ty":3,"nm":"Null 1","ks":{"o":{"k":0},"r":{"k":[{"i":{"x":[0.833],"y":[1.093]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1p093_0p167_0p167"],"t":0,"s":[0],"e":[-22]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.037]},"n":["0p833_1_0p167_0p037"],"t":6.931,"s":[-22],"e":[22]},{"i":{"x":[0.833],"y":[0.966]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p966_0p167_0"],"t":12.435,"s":[22],"e":[-22]},{"i":{"x":[0.833],"y":[0.857]},"o":{"x":[0.167],"y":[-0.098]},"n":["0p833_0p857_0p167_-0p098"],"t":18,"s":[-22],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.295]},"n":["0p833_1_0p167_0p295"],"t":26,"s":[0],"e":[4]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p667_1_0p167_0"],"t":29,"s":[4],"e":[0]},{"t":33}]},"p":{"k":[221.5,77,0]},"a":{"k":[0,0,0]},"s":{"k":[344,344,100]}},"ao":0,"ip":0,"op":50,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":1,"nm":"Black Solid 1","parent":0,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[0,30.959,0]},"a":{"k":[221.5,183.5,0]},"s":{"k":[29.07,29.07,100]}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"k":{"i":[[3.376,4.804],[0,15.358],[0,0],[40.857,4.809],[0,6.956],[9.556,0],[0,-9.556],[-4.437,-3.072],[-0.007,-0.031],[0,-42.092],[0,0],[8.971,-12.559],[-5.461,0],[0,0]],"o":[[-8.874,-12.628],[0,0],[0,-41.969],[4.427,-3.689],[0,-9.556],[-9.556,0],[0,5.802],[0,0],[-40.638,4.737],[0,0],[0,15.358],[-3.413,4.778],[0,0],[5.461,0]],"v":[[318.087,264.087],[303.411,220.401],[303.411,172.619],[231.019,91.367],[238.565,77.056],[221.5,59.991],[204.435,77.056],[211.944,91.049],[211.971,91.152],[139.589,172.619],[139.589,220.401],[124.913,264.087],[130.374,275.009],[312.626,275.009]],"c":true}},"o":{"k":100},"x":{"k":0},"nm":"Mask 1"}],"ef":[{"ty":21,"nm":"Fill","mn":"ADBE Fill","ix":1,"ef":[{"ty":3,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"k":0}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"k":0}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"k":[1,1,1,1]}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"k":0}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"k":0}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"k":0}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"k":1}}]}],"sw":443,"sh":367,"sc":"#000000","ip":0,"op":50,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":0,"nm":"Pre-comp 1","parent":0,"refId":"comp_0","ks":{"o":{"k":100},"r":{"k":-22},"p":{"k":[{"i":{"x":0.833,"y":0.814},"o":{"x":0.167,"y":0.167},"n":"0p833_0p814_0p167_0p167","t":2,"s":[4.737,11.725,0],"e":[19.737,11.725,0],"to":[2.5,0,0],"ti":[2.83333325386047,0,0]},{"i":{"x":0.833,"y":0.844},"o":{"x":0.167,"y":0.157},"n":"0p833_0p844_0p167_0p157","t":4.572,"s":[19.737,11.725,0],"e":[-12.263,11.725,0],"to":[-2.83333325386047,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.88},"o":{"x":0.167,"y":0.177},"n":"0p833_0p88_0p167_0p177","t":9,"s":[-12.263,11.725,0],"e":[19.737,11.725,0],"to":[0,0,0],"ti":[-2.66666674613953,0,0]},{"i":{"x":0.833,"y":0.886},"o":{"x":0.167,"y":0.22},"n":"0p833_0p886_0p167_0p22","t":14.008,"s":[19.737,11.725,0],"e":[-8.129,11.725,0],"to":[0.7367005944252,0,0],"ti":[4.95352220535278,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.284},"n":"0p833_0p833_0p167_0p284","t":22,"s":[-8.129,11.725,0],"e":[3.737,11.725,0],"to":[-2.79587697982788,0,0],"ti":[0.0821717903018,0,0]},{"t":31}]},"a":{"k":[350,437.5,0]},"s":{"k":[29.07,29.07,100]}},"ao":0,"ef":[{"ty":21,"nm":"Fill","mn":"ADBE Fill","ix":1,"ef":[{"ty":3,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"k":0}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"k":0}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"k":[1,1,1,1]}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"k":0}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"k":0}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"k":0}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"k":1}}]}],"w":700,"h":875,"ip":0,"op":50,"st":0,"bm":0,"sr":1}],"v":"4.5.0","ddd":0,"ip":0,"op":42,"fr":25,"w":443,"h":367} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/birth_stone_logo.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/birth_stone_logo.json deleted file mode 100644 index f52bcc2a..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/birth_stone_logo.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.2.1","fr":29.9700012207031,"ip":0,"op":120.0000048877,"w":150,"h":120,"nm":"logo 2","ddd":1,"assets":[],"layers":[{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[98,45.5,0],"ix":2},"a":{"a":0,"k":[-23,-14.5,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[19.25,-19.25],[0,0],[0,0]],"o":[[0,0],[0,0],[-20.25,20.25],[0,0],[0,0]],"v":[[19.5,-14],[-12.5,-45.25],[-51.25,-42.25],[-55.75,-5.25],[-23,28.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":8,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.584,0.894,0.929,0.5,0.692,0.733,0.965,1,0.8,0.573,1],"ix":8}},"s":{"a":0,"k":[-64.303,-9.492],"ix":4},"e":{"a":0,"k":[23.721,-13.33],"ix":5},"t":1,"lc":2,"lj":2,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":100,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":30,"s":[100],"e":[0]},{"t":60.0000024438501}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":120.0000048877,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,60,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[22.75,-19.25],[0,0],[0,0]],"o":[[0,0],[0,0],[-19.75,19.75],[0,0],[0,0]],"v":[[19.5,-14],[-12.5,-45.25],[-51.25,-42.25],[-55.75,-5.25],[-23,28.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":8,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,1,0.788,0.6,0.5,0.902,0.682,0.798,1,0.804,0.576,0.996],"ix":8}},"s":{"a":0,"k":[-64.303,-9.492],"ix":4},"e":{"a":0,"k":[23.721,-13.33],"ix":5},"t":1,"lc":2,"lj":2,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":100,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[100],"e":[0]},{"t":30.0000012219251}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":120.0000048877,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75.5,103,0],"ix":2},"a":{"a":0,"k":[0,42.5,0],"ix":1},"s":{"a":0,"k":[91.956,91.956,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[18.648,18.648],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.8,0.572549019608,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":8,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,42.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":100,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":60,"s":[100],"e":[0]},{"t":89.0000036250443}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":120.0000048877,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/bounching_ball.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/bounching_ball.json deleted file mode 100644 index 37792951..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/bounching_ball.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.5.7","fr":30,"ip":0,"op":30,"w":800,"h":600,"ddd":0,"assets":[{"id":"comp_1","layers":[{"ddd":0,"ind":0,"ty":4,"nm":"Shape Layer 4","td":1,"ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"s":true,"x":{"a":0,"k":960},"y":{"a":1,"k":[{"i":{"x":[0.96],"y":[0.317]},"o":{"x":[0.453],"y":[0]},"n":["0p96_0p317_0p453_0"],"t":0,"s":[372.934],"e":[910.934]},{"i":{"x":[0.491],"y":[0.491]},"o":{"x":[0.405],"y":[0.405]},"n":["0p491_0p491_0p405_0p405"],"t":14,"s":[910.934],"e":[910.934]},{"i":{"x":[0.328],"y":[1]},"o":{"x":[0.02],"y":[0.674]},"n":["0p328_1_0p02_0p674"],"t":16,"s":[910.934],"e":[372.934]},{"t":30}]}},"a":{"a":0,"k":[-55.922,214.156,0]},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[43,43,100],"e":[36.8,54.9,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":14,"s":[36.8,54.9,100],"e":[56.6,27.5,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":15,"s":[56.6,27.5,100],"e":[56.6,27.5,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":16,"s":[56.6,27.5,100],"e":[34.58,45.3,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":18,"s":[34.58,45.3,100],"e":[47.692,41.258,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":25,"s":[47.692,41.258,100],"e":[43,43,100]},{"t":30}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[460.156,460.156]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[0.2,0.77,0.61,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"a":0,"k":[0.95,0.31,0.56,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-55.922,-15.922],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":150,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 3","parent":2,"tt":1,"ks":{"o":{"a":0,"k":12},"r":{"a":0,"k":0},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[23.697,-140.59,0],"e":[59.033,-256.954,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":15,"s":[59.033,-256.954,0],"e":[23.697,-140.59,0],"to":[0,0,0],"ti":[0,0,0]},{"t":30}]},"a":{"a":0,"k":[7.73,-318.27,0]},"s":{"a":0,"k":[168.239,178.473,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[36.539,36.539]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[0.2,0.77,0.61,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"a":0,"k":[1,1,1,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[7.73,-318.27],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":150,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"s":true,"x":{"a":0,"k":960},"y":{"a":1,"k":[{"i":{"x":[0.96],"y":[0.317]},"o":{"x":[0.453],"y":[0]},"n":["0p96_0p317_0p453_0"],"t":0,"s":[372.934],"e":[910.934]},{"i":{"x":[0.491],"y":[0.491]},"o":{"x":[0.405],"y":[0.405]},"n":["0p491_0p491_0p405_0p405"],"t":14,"s":[910.934],"e":[910.934]},{"i":{"x":[0.328],"y":[1]},"o":{"x":[0.02],"y":[0.674]},"n":["0p328_1_0p02_0p674"],"t":16,"s":[910.934],"e":[372.934]},{"t":30}]}},"a":{"a":0,"k":[-55.922,214.156,0]},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[43,43,100],"e":[36.8,54.9,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":14,"s":[36.8,54.9,100],"e":[56.6,27.5,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":15,"s":[56.6,27.5,100],"e":[56.6,27.5,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":16,"s":[56.6,27.5,100],"e":[34.58,45.3,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":18,"s":[34.58,45.3,100],"e":[47.692,41.258,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":25,"s":[47.692,41.258,100],"e":[43,43,100]},{"t":30}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[460.156,460.156]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[0.2,0.77,0.61,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"a":0,"k":[0.95,0.31,0.56,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-55.922,-15.922],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":150,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 2","ks":{"o":{"a":0,"k":45},"r":{"a":0,"k":0},"p":{"a":0,"k":[958,908,0]},"a":{"a":0,"k":[-2,400,0]},"s":{"a":1,"k":[{"i":{"x":[0.893,0.893,1],"y":[0.5,-0.195,1]},"o":{"x":[0.44,0.44,0],"y":[0,0,0]},"n":["0p893_0p5_0p44_0","0p893_-0p195_0p44_0","1_1_0_0"],"t":0,"s":[117.1,83.8,100],"e":[39.9,51.5,100]},{"i":{"x":[0.539,0.539,1],"y":[1,1,1]},"o":{"x":[0.175,0.175,0],"y":[0.542,1.294,0]},"n":["0p539_1_0p175_0p542","0p539_1_0p175_1p294","1_1_0_0"],"t":16,"s":[39.9,51.5,100],"e":[117.1,83.8,100]},{"t":30}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[467.797,27.125]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[0.2,0.77,0.61,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"a":0,"k":[0.18,0.62,0.5,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-2,400],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[69.545,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":150,"st":0,"bm":0,"sr":1}]}],"layers":[{"ddd":0,"ind":0,"ty":0,"nm":"bouncing ball.1920x1080","cl":"1920x1080","refId":"comp_1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[400,300,0]},"a":{"a":0,"k":[960,540,0]},"s":{"a":0,"k":[55.556,55.556,100]}},"ao":0,"w":1920,"h":1080,"ip":0,"op":150,"st":0,"bm":0,"sr":1}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/browser.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/browser.json deleted file mode 100644 index d7e10a9d..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/browser.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.1","fr":25,"ip":0,"op":149,"w":256,"h":256,"nm":"Composição 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Camada de forma 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[68.5,23.75,0],"ix":2},"a":{"a":0,"k":[-92,-93.5,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.32,0.32,0.32],"y":[1.27,1.27,1]},"o":{"x":[0.17,0.17,0.17],"y":[0.89,0.89,0]},"n":["0p32_1p27_0p17_0p89","0p32_1p27_0p17_0p89","0p32_1_0p17_0"],"t":41,"s":[0,0,100],"e":[85,85,100]},{"t":47}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[14.5,14.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Caminho da elipse 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.701960784314,0.701960784314,0.701960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Preenchimento 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-92,-93.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Elipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":149,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Camada de forma 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[48.5,23.75,0],"ix":2},"a":{"a":0,"k":[-92,-93.5,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.32,0.32,0.32],"y":[1.27,1.27,1]},"o":{"x":[0.17,0.17,0.17],"y":[0.89,0.89,0]},"n":["0p32_1p27_0p17_0p89","0p32_1p27_0p17_0p89","0p32_1_0p17_0"],"t":35,"s":[0,0,100],"e":[85,85,100]},{"t":41}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[14.5,14.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Caminho da elipse 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.701960784314,0.701960784314,0.701960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Preenchimento 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-92,-93.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Elipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":149,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Camada de forma 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[28.5,23.75,0],"ix":2},"a":{"a":0,"k":[-92,-93.5,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.32,0.32,0.32],"y":[1.27,1.27,1]},"o":{"x":[0.17,0.17,0.17],"y":[0.89,0.89,0]},"n":["0p32_1p27_0p17_0p89","0p32_1p27_0p17_0p89","0p32_1_0p17_0"],"t":29,"s":[0,0,100],"e":[85,85,100]},{"t":35}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[14.5,14.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Caminho da elipse 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.701960784314,0.701960784314,0.701960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Preenchimento 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-92,-93.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Elipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":149,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"line 9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.34,"y":1},"o":{"x":0.66,"y":0},"n":"0p34_1_0p66_0","t":64,"s":[53.085,245,0],"e":[53.085,200,0],"to":[0,-7.5,0],"ti":[0,7.5,0]},{"t":80}],"ix":2},"a":{"a":0,"k":[-73.675,-37.75,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.34,0.34,0.34],"y":[1,1,1]},"o":{"x":[0.66,0.66,0.66],"y":[0,0,0]},"n":["0p34_1_0p66_0","0p34_1_0p66_0","0p34_1_0p66_0"],"t":111,"s":[0,100,100],"e":[127.498,100,100]},{"t":126}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[116.75,12],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Caminho do retângulo 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.149019607843,0.650980392157,0.819607902976,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Preenchimento 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-14.375,-37.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Retângulo 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":149,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"line 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.34,"y":1},"o":{"x":0.66,"y":0},"n":"0p34_1_0p66_0","t":64,"s":[109.085,217.25,0],"e":[109.085,172.25,0],"to":[0,-7.5,0],"ti":[0,7.5,0]},{"t":80}],"ix":2},"a":{"a":0,"k":[-117.575,-37.75,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.34,0.34,0.34],"y":[1,1,1]},"o":{"x":[0.66,0.66,0.66],"y":[0,0,0]},"n":["0p34_1_0p66_0","0p34_1_0p66_0","0p34_1_0p66_0"],"t":99,"s":[0,88.542,100],"e":[50.947,88.542,100]},{"t":111}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[116.75,12],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":110,"ix":4},"nm":"Caminho do retângulo 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.286274509804,0.721568627451,0.643137254902,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Preenchimento 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-58.722,-37.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Retângulo 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":149,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"line 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.34,"y":1},"o":{"x":0.66,"y":0},"n":"0p34_1_0p66_0","t":64,"s":[53.085,217.25,0],"e":[53.085,172.25,0],"to":[0,-7.5,0],"ti":[0,7.5,0]},{"t":80}],"ix":2},"a":{"a":0,"k":[-117.575,-37.75,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.1,0.1,0.1],"y":[1,1,1]},"o":{"x":[0.9,0.9,0.9],"y":[0,0,0]},"n":["0p1_1_0p9_0","0p1_1_0p9_0","0p1_1_0p9_0"],"t":88,"s":[0,79.167,100],"e":[37.298,88.542,100]},{"t":103}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[116.75,12],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Caminho do retângulo 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.89019613827,0.36862745098,0.325490196078,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Preenchimento 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-58.722,-37.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Retângulo 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":149,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"line 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.34,"y":1},"o":{"x":0.66,"y":0},"n":"0p34_1_0p66_0","t":64,"s":[52.835,190.25,0],"e":[52.835,145.25,0],"to":[0,-7.5,0],"ti":[0,7.5,0]},{"t":80}],"ix":2},"a":{"a":0,"k":[-117.575,-37.75,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.34,0.34,0.34],"y":[1,1,1]},"o":{"x":[0.66,0.66,0.66],"y":[0,0,0]},"n":["0p34_1_0p66_0","0p34_1_0p66_0","0p34_1_0p66_0"],"t":79,"s":[0,100,100],"e":[88.298,100,100]},{"t":94}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[116.75,12],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Caminho do retângulo 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.286274509804,0.721568627451,0.643137254902,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Preenchimento 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-58.722,-37.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Retângulo 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":149,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"line 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.34,"y":1},"o":{"x":0.66,"y":0},"n":"0p34_1_0p66_0","t":64,"s":[123.585,162.75,0],"e":[123.585,117.75,0],"to":[0,-7.5,0],"ti":[0,7.5,0]},{"t":80}],"ix":2},"a":{"a":0,"k":[-117.575,-37.75,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.34,0.34,0.34],"y":[1,1,1]},"o":{"x":[0.66,0.66,0.66],"y":[0,0,0]},"n":["0p34_1_0p66_0","0p34_1_0p66_0","0p34_1_0p66_0"],"t":62,"s":[0,100,100],"e":[67.298,100,100]},{"t":72}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[116.75,12],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Caminho do retângulo 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.149019607843,0.650980392157,0.819607902976,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Preenchimento 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-58.722,-37.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Retângulo 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":149,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"line 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.34,"y":1},"o":{"x":0.66,"y":0},"n":"0p34_1_0p66_0","t":64,"s":[56.335,162.75,0],"e":[56.335,117.75,0],"to":[0,-7.5,0],"ti":[0,7.5,0]},{"t":80}],"ix":2},"a":{"a":0,"k":[-115.975,-37.75,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.34,0.34,0.34],"y":[1,1,1]},"o":{"x":[0.66,0.66,0.66],"y":[0,0,0]},"n":["0p34_1_0p66_0","0p34_1_0p66_0","0p34_1_0p66_0"],"t":52,"s":[0,100,100],"e":[48.498,100,100]},{"t":65}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[116.75,12],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Caminho do retângulo 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.89019613827,0.36862745098,0.325490196078,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Preenchimento 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-58.722,-37.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Retângulo 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":149,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"line 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.34,"y":1},"o":{"x":0.66,"y":0},"n":"0p34_1_0p66_0","t":64,"s":[53.085,126.75,0],"e":[53.085,90.75,0],"to":[0,-6,0],"ti":[0,6,0]},{"t":80}],"ix":2},"a":{"a":0,"k":[-72.975,-37.75,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.34,0.34,0.34],"y":[1,1,1]},"o":{"x":[0.66,0.66,0.66],"y":[0,0,0]},"n":["0p34_1_0p66_0","0p34_1_0p66_0","0p34_1_0p66_0"],"t":40,"s":[0,100,100],"e":[105.498,100,100]},{"t":53}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[116.75,12],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Caminho do retângulo 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.937254961799,0.937254961799,0.937254961799,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Preenchimento 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-14.375,-37.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Retângulo 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":149,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"blue","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.34,"y":1},"o":{"x":0.088,"y":1},"n":"0p34_1_0p088_1","t":16,"s":[127.77,391.572,0],"e":[127.77,145.572,0],"to":[0,-41,0],"ti":[0,41,0]},{"t":35}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[80.876,70.93,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[250.5,245.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":13,"ix":4},"nm":"Caminho do retângulo 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.16862745098,0.254901960784,0.301960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Preenchimento 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.25,-3.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[107.86,108.079],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Retângulo 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":149,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"index","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.34,"y":1},"o":{"x":0.088,"y":1},"n":"0p34_1_0p088_1","t":7,"s":[127.77,402.072,0],"e":[127.77,131.072,0],"to":[0,-45.1666679382324,0],"ti":[0,45.1666679382324,0]},{"t":26}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[92,94.51,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[250.5,245.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":13,"ix":4},"nm":"Caminho do retângulo 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.937254961799,0.937254961799,0.937254961799,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Preenchimento 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.25,-3.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[107.86,108.079],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Retângulo 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":149,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/confetti.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/confetti.json deleted file mode 100644 index 495035cb..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/confetti.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.12.0","fr":29.9700012207031,"ip":0,"op":59.0000024031193,"w":800,"h":800,"nm":"confettis2","ddd":0,"assets":[{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"p20","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":4,"s":[100],"e":[0]},{"t":43.0000017514259}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":4,"s":[400,400,0],"e":[71,152,0],"to":[1.83333337306976,-220.66667175293,0],"ti":[85.1666641235352,-23.3333339691162,0]},{"t":43.0000017514259}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.901960790157,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":4.00000016292334,"op":364.000014826024,"st":4.00000016292334,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"p19","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":3,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":3,"s":[400,400,0],"e":[579,746,0],"to":[101.833335876465,91.3333358764648,0],"ti":[27.1666660308838,-153.33332824707,0]},{"t":42.0000017106951}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":3.00000012219251,"op":363.000014785293,"st":3.00000012219251,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"p18","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":2,"s":[100],"e":[0]},{"t":41.0000016699642}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":2,"s":[400,400,0],"e":[503,238,0],"to":[-84.1666641235352,-74.6666641235352,0],"ti":[-88.8333358764648,-45.3333320617676,0]},{"t":41.0000016699642}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.074509806931,0.737254917622,0.172549024224,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2.00000008146167,"op":362.000014744562,"st":2.00000008146167,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"p17","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":1,"s":[100],"e":[0]},{"t":40.0000016292334}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":1,"s":[400,400,0],"e":[91,556,0],"to":[-82.1666641235352,-112.666664123535,0],"ti":[73.1666641235352,-199.33332824707,0]},{"t":40.0000016292334}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":1.00000004073083,"op":361.000014703831,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"p16","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":0,"s":[100],"e":[0]},{"t":39.0000015885026}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":0,"s":[400,400,0],"e":[511,308,0],"to":[77.8333358764648,91.3333358764648,0],"ti":[51.1666679382324,60.6666679382324,0]},{"t":39.0000015885026}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.270588248968,0.529411792755,0.952941179276,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360.000014663101,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"p15","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":1,"s":[100],"e":[0]},{"t":40.0000016292334}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":1,"s":[400,400,0],"e":[155,280,0],"to":[-30.1666660308838,-122.666664123535,0],"ti":[95.1666641235352,-53.3333320617676,0]},{"t":40.0000016292334}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.901960790157,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":1.00000004073083,"op":361.000014703831,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"p14","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":2,"s":[100],"e":[0]},{"t":41.0000016699642}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":2,"s":[400,400,0],"e":[681,388.872,0],"to":[143.83332824707,49.3333320617676,0],"ti":[-58.8333320617676,48.6666679382324,0]},{"t":41.0000016699642}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2.00000008146167,"op":362.000014744562,"st":2.00000008146167,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"p13","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":3,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":3,"s":[400,400,0],"e":[257,284,0],"to":[-24.1666660308838,-72.6666641235352,0],"ti":[75.1666641235352,-5.33333349227905,0]},{"t":42.0000017106951}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.074509806931,0.737254917622,0.172549024224,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":3.00000012219251,"op":363.000014785293,"st":3.00000012219251,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"p12","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":4,"s":[100],"e":[0]},{"t":43.0000017514259}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":4,"s":[400,400,0],"e":[301,474,0],"to":[-14.1666669845581,31.3333339691162,0],"ti":[65.1666641235352,-13.3333330154419,0]},{"t":43.0000017514259}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":4.00000016292334,"op":364.000014826024,"st":4.00000016292334,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"p11","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":0,"s":[100],"e":[0]},{"t":39.0000015885026}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":0,"s":[400,400,0],"e":[499,570,0],"to":[-8.16666698455811,63.3333320617676,0],"ti":[-62.8333320617676,-29.3333339691162,0]},{"t":39.0000015885026}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.270588248968,0.529411792755,0.952941179276,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360.000014663101,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"p10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":1,"s":[100],"e":[0]},{"t":40.0000016292334}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":1,"s":[400,400,0],"e":[557,68,0],"to":[81.8333358764648,-104.666664123535,0],"ti":[-58.8333320617676,104.666664123535,0]},{"t":40.0000016292334}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.901960790157,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":1.00000004073083,"op":361.000014703831,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"p9","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":2,"s":[100],"e":[0]},{"t":41.0000016699642}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":2,"s":[400,400,0],"e":[715,138,0],"to":[151.83332824707,-46.6666679382324,0],"ti":[-26.8333339691162,72.6666641235352,0]},{"t":41.0000016699642}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2.00000008146167,"op":362.000014744562,"st":2.00000008146167,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"p8","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":3,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":3,"s":[400,400,0],"e":[679,664,0],"to":[107.833335876465,89.3333358764648,0],"ti":[-92.8333358764648,-103.333335876465,0]},{"t":42.0000017106951}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.074509806931,0.737254917622,0.172549024224,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":3.00000012219251,"op":363.000014785293,"st":3.00000012219251,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"p7","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":4,"s":[100],"e":[0]},{"t":43.0000017514259}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":4,"s":[400,400,0],"e":[97,686,0],"to":[-36.1666679382324,53.3333320617676,0],"ti":[75.1666641235352,-39.3333320617676,0]},{"t":43.0000017514259}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":4.00000016292334,"op":364.000014826024,"st":4.00000016292334,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"p6","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":5,"s":[100],"e":[0]},{"t":44.0000017921567}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":5,"s":[400,400,0],"e":[65,340,0],"to":[-148.16667175293,-132.66667175293,0],"ti":[61.1666679382324,-65.3333358764648,0]},{"t":44.0000017921567}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.270588248968,0.529411792755,0.952941179276,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":5.00000020365417,"op":365.000014866755,"st":5.00000020365417,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"p5","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":6,"s":[100],"e":[0]},{"t":45.0000018328876}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.004,"y":0.691},"o":{"x":0.014,"y":0},"n":"0p004_0p691_0p014_0","t":6,"s":[400,400,0],"e":[400,23.613,0],"to":[-55.3803939819336,-168.204071044922,0],"ti":[27.0301876068115,124.269813537598,0]},{"t":45.0000018328876}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.901960790157,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":6.00000024438501,"op":366.000014907486,"st":6.00000024438501,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"p4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":7,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":7,"s":[400,400,0],"e":[303,660,0],"to":[109.833335876465,69.3333358764648,0],"ti":[97.1666641235352,0.66666668653488,0]},{"t":46.0000018736184}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":7.00000028511585,"op":367.000014948216,"st":7.00000028511585,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"p3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":8,"s":[100],"e":[0]},{"t":47.0000019143492}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":8,"s":[400,400,0],"e":[663,498,0],"to":[41.8333320617676,109.333335876465,0],"ti":[-71.8333358764648,39.6666679382324,0]},{"t":47.0000019143492}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.076272718608,0.735462605953,0.171031266451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":8.00000032584668,"op":368.000014988947,"st":8.00000032584668,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"p2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":9,"s":[100],"e":[0]},{"t":48.0000019550801}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":9,"s":[400,400,0],"e":[187,88,0],"to":[-0.16666667163372,-158.66667175293,0],"ti":[89.1666641235352,6.66666650772095,0]},{"t":48.0000019550801}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.271778345108,0.528400123119,0.952267169952,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":9.00000036657752,"op":369.000015029678,"st":9.00000036657752,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"p1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":0,"s":[100],"e":[0]},{"t":39.0000015885026}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":0,"s":[400,400,0],"e":[621,234,0],"to":[-0.16666667163372,-158.66667175293,0],"ti":[-92.8333358764648,-103.333335876465,0]},{"t":39.0000015885026}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.903676450253,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360.000014663101,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":42,"ix":10},"p":{"a":0,"k":[396,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[91.5,91.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":9.00000036657752,"op":369.000015029678,"st":9.00000036657752,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":267,"ix":10},"p":{"a":0,"k":[416,420,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":7.00000028511585,"op":367.000014948216,"st":7.00000028511585,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":358,"ix":10},"p":{"a":0,"k":[436,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":5.00000020365417,"op":365.000014866755,"st":5.00000020365417,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":177,"ix":10},"p":{"a":0,"k":[416,380,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":3.00000012219251,"op":363.000014785293,"st":3.00000012219251,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":132,"ix":10},"p":{"a":0,"k":[416,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[91.5,91.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":1.00000004073083,"op":361.000014703831,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[396,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[91.5,91.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":8.00000032584668,"op":368.000014988947,"st":8.00000032584668,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":135,"ix":10},"p":{"a":0,"k":[416,420,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":6.00000024438501,"op":366.000014907486,"st":6.00000024438501,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":226,"ix":10},"p":{"a":0,"k":[436,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":4.00000016292334,"op":364.000014826024,"st":4.00000016292334,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":45,"ix":10},"p":{"a":0,"k":[416,380,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":2.00000008146167,"op":362.000014744562,"st":2.00000008146167,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[416,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[91.5,91.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":0,"op":360.000014663101,"st":0,"bm":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/cooking.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/cooking.json deleted file mode 100644 index d14ac8f7..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/cooking.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.20","fr":30,"ip":0,"op":90,"w":300,"h":300,"nm":"Layers-Panelinha","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"fum3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[118,140,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[14.645,21.967],[0,0]],"o":[[0,0],[-10,-15],[0,0]],"v":[[103.5,-40.5],[102.5,-73],[105,-104]],"c":false},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.23137254902,0.647058823529,0.345098039216,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Traçado 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Forma 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":52,"s":[0],"e":[100]},{"t":61}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":38,"s":[1],"e":[100]},{"t":48}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Aparar caminhos 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"fum2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[146.5,146.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[14.645,21.967],[0,0]],"o":[[0,0],[-10,-15],[0,0]],"v":[[103.5,-40.5],[102.5,-73],[105,-104]],"c":false},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.23137254902,0.647058823529,0.345098039216,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Traçado 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Forma 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":48,"s":[0],"e":[100]},{"t":57}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":34,"s":[0],"e":[100]},{"t":44}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Aparar caminhos 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"fum1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[172.5,156,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[14.645,21.967],[0,0]],"o":[[0,0],[-10,-15],[0,0]],"v":[[103.5,-40.5],[102.5,-73],[105,-104]],"c":false},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.23137254902,0.647058823529,0.345098039216,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Traçado 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Forma 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":44,"s":[0],"e":[100]},{"t":53}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":30,"s":[0],"e":[100]},{"t":40}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Aparar caminhos 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"tampa","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":21,"s":[3],"e":[-1]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p667_1_0p167_0"],"t":30,"s":[-1],"e":[-1]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":60,"s":[-1],"e":[3]},{"t":69}],"ix":10},"p":{"a":0,"k":[45.545,146.5,0],"ix":2},"a":{"a":0,"k":[6.582,51.75,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-10.057,-13.526],[-8.536,81.451],[234.078,78.965],[232.557,-16.012]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Máscara 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.181,-0.003]],"o":[[0,0]],"v":[[-0.22,-21.078]],"c":true},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[2.101,1.25],[4.773,0.893],[13.723,0.898],[6.051,0],[9.651,0],[0.205,3.94],[-2.76,0.691],[-1.947,1.145],[1.654,1.108],[3.862,0.587],[0,0],[3.533,-3.061],[0.933,-1.926],[-2.019,-0.218],[-0.671,0],[-2.685,0.154],[0,0],[4.667,-0.497],[21.998,-8.59],[4.733,-3.077],[1.514,-2.149],[0,0],[-62.874,3.606],[-0.255,0.592]],"o":[[-4.282,-2.547],[-13.548,-2.532],[-5.987,-0.393],[-9.334,0],[-0.192,-3.681],[3.294,-0.218],[2.102,-0.527],[-1.199,-1.786],[-2.849,-1.909],[0,0],[-5.411,0.808],[-1.487,1.289],[1.947,0.89],[0.659,0.072],[2.366,0],[0,0],[-4.912,0.467],[-23.337,2.485],[-5.247,2.049],[-2.046,1.33],[0,0],[62.874,-3.606],[0.254,-0.591],[-1.644,-2.017]],"v":[[105.32,8.989],[91.723,2.741],[50.79,-3.165],[32.749,-3.677],[4.32,-3.394],[3.742,-14.488],[12.777,-15.21],[18.647,-18.522],[14.986,-23.785],[4.674,-27.5],[-6.408,-27.5],[-20.437,-21.662],[-23.316,-15.976],[-17.462,-13.435],[-15.468,-13.334],[-7.956,-13.851],[-7.956,-2.777],[-22.213,-1.412],[-90.667,13.278],[-105.657,21.258],[-110.332,27.5],[-79.052,27.5],[109.569,16.681],[110.332,14.907]],"c":true},"ix":2},"nm":"Caminho 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Mesclar caminhos 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-255.545,289.5],[256.455,289.5],[256.455,-222.5],[-255.545,-222.5]],"c":true},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-255.545,-222.5],[256.455,-222.5],[256.455,289.5],[-255.545,289.5]],"c":true},"ix":2},"nm":"Caminho 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Mesclar caminhos 2","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"tr","p":{"a":0,"k":[110.582,27.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":6,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":4,"s":[100],"e":[0]},{"t":14}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":-3,"ix":3},"m":1,"ix":2,"nm":"Aparar caminhos 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.23137254902,0.647058823529,0.345098039216,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Traçado 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"panela 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[0],"e":[100]},{"t":9}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[149.925,197.5,0],"ix":2},"a":{"a":0,"k":[143.235,47.75,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.854,0.559],[0,0],[0.197,-2.328],[-5.896,-0.369],[-6.169,-0.264],[-0.728,-2.833],[-3.983,-13.859],[-3.697,-8.321],[-7.952,-1.308],[-6.447,-0.036],[-14.887,0],[-15.552,0.02],[-8.777,0.258],[-4.491,11.132],[-0.586,2.192],[-4.853,18.555],[-3.728,0.187],[-6.651,0.375],[-0.172,3.214]],"o":[[0,0],[-1.855,0.449],[-0.294,3.472],[6.161,0.386],[4.003,0.171],[3.58,13.924],[2.471,8.597],[2.569,5.782],[6.307,1.038],[14.886,0.083],[15.552,0],[8.786,-0.012],[15.381,-0.451],[0.862,-2.136],[4.955,-18.539],[0.713,-2.723],[6.654,-0.332],[4.02,-0.227],[0.131,-2.44]],"v":[[139.143,-47.5],[-139.292,-47.5],[-142.691,-43.703],[-134.774,-38.372],[-116.302,-37.118],[-109.899,-32.57],[-98.867,9.16],[-89.946,34.679],[-73.248,45.708],[-53.949,47.392],[-9.29,47.5],[37.366,47.453],[63.72,47.118],[93.278,29.351],[95.421,22.838],[110.176,-32.797],[116.329,-37.095],[136.264,-38.412],[142.854,-43.204]],"c":true},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-255.925,208.5],[256.075,208.5],[256.075,-303.5],[-255.925,-303.5]],"c":true},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-255.925,-303.5],[256.075,-303.5],[256.075,208.5],[-255.925,208.5]],"c":true},"ix":2},"nm":"Caminho 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Mesclar caminhos 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"tr","p":{"a":0,"k":[143.235,47.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.23137255013,0.647058844566,0.345098048449,1],"ix":4},"o":{"a":0,"k":32,"ix":5},"r":1,"nm":"Preenchimento 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"panela","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[149.925,197.5,0],"ix":2},"a":{"a":0,"k":[143.235,47.75,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.854,0.559],[0,0],[0.197,-2.328],[-5.896,-0.369],[-6.169,-0.264],[-0.728,-2.833],[-3.983,-13.859],[-3.697,-8.321],[-7.952,-1.308],[-6.447,-0.036],[-14.887,0],[-15.552,0.02],[-8.777,0.258],[-4.491,11.132],[-0.586,2.192],[-4.853,18.555],[-3.728,0.187],[-6.651,0.375],[-0.172,3.214]],"o":[[0,0],[-1.855,0.449],[-0.294,3.472],[6.161,0.386],[4.003,0.171],[3.58,13.924],[2.471,8.597],[2.569,5.782],[6.307,1.038],[14.886,0.083],[15.552,0],[8.786,-0.012],[15.381,-0.451],[0.862,-2.136],[4.955,-18.539],[0.713,-2.723],[6.654,-0.332],[4.02,-0.227],[0.131,-2.44]],"v":[[139.143,-47.5],[-139.292,-47.5],[-142.691,-43.703],[-134.774,-38.372],[-116.302,-37.118],[-109.899,-32.57],[-98.867,9.16],[-89.946,34.679],[-73.248,45.708],[-53.949,47.392],[-9.29,47.5],[37.366,47.453],[63.72,47.118],[93.278,29.351],[95.421,22.838],[110.176,-32.797],[116.329,-37.095],[136.264,-38.412],[142.854,-43.204]],"c":true},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-255.925,208.5],[256.075,208.5],[256.075,-303.5],[-255.925,-303.5]],"c":true},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-255.925,-303.5],[256.075,-303.5],[256.075,208.5],[-255.925,208.5]],"c":true},"ix":2},"nm":"Caminho 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":4,"nm":"Mesclar caminhos 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"tr","p":{"a":0,"k":[143.235,47.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[100],"e":[0]},{"t":9}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":95,"ix":3},"m":1,"ix":2,"nm":"Aparar caminhos 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.23137254902,0.647058823529,0.345098039216,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Traçado 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":90,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/dna.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/dna.json deleted file mode 100644 index 545d474b..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/dna.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.13.0","fr":60,"ip":0,"op":241,"w":800,"h":600,"nm":"DNA","ddd":0,"assets":[{"id":"comp_6","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[22,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-156,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[56.455,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-153,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[90.909,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-150,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[125.364,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-147,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[159.818,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-144,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[194.273,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-141,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[228.727,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-138,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[263.182,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-135,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[297.636,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-132,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[332.091,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-129,"bm":0},{"ddd":0,"ind":11,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[366.545,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-126,"bm":0},{"ddd":0,"ind":12,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[401,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-123,"bm":0},{"ddd":0,"ind":13,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[435.455,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-120,"bm":0},{"ddd":0,"ind":14,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[469.909,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-117,"bm":0},{"ddd":0,"ind":15,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[504.364,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-114,"bm":0},{"ddd":0,"ind":16,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[538.818,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-111,"bm":0},{"ddd":0,"ind":17,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[573.273,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-108,"bm":0},{"ddd":0,"ind":18,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[607.727,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-105,"bm":0},{"ddd":0,"ind":19,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[642.182,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-102,"bm":0},{"ddd":0,"ind":20,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[676.636,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-99,"bm":0},{"ddd":0,"ind":21,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[711.091,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-96,"bm":0},{"ddd":0,"ind":22,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[745.545,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-93,"bm":0},{"ddd":0,"ind":23,"ty":0,"nm":"meet bar","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[780,290,0],"ix":2},"a":{"a":0,"k":[32,205,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":64,"h":410,"ip":0,"op":361,"st":-90,"bm":0}]},{"id":"comp_7","layers":[{"ddd":0,"ind":1,"ty":3,"nm":"traceNull","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[958,53,0],"ix":2,"x":"var $bm_rt;\nvar pathLayer = thisComp.layer('bar');\nvar progress = div(thisLayer.effect('Pseudo/ADBE Trace Path')('Pseudo/ADBE Trace Path-0001'), 100);\nvar pathToTrace = pathLayer('ADBE Root Vectors Group')(1)('ADBE Vector Shape');\n$bm_rt = pathLayer.toComp(pathToTrace.pointOnPath(progress));"},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Trace Path","np":4,"mn":"Pseudo/ADBE Trace Path","ix":1,"en":1,"ef":[{"ty":0,"nm":"Progress","mn":"Pseudo/ADBE Trace Path-0001","ix":1,"v":{"a":1,"k":[{"i":{"x":[0.6],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p6_1_0p4_0"],"t":0,"s":[0],"e":[100]},{"i":{"x":[0.6],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p6_1_0p4_0"],"t":60,"s":[100],"e":[0]},{"t":120}],"ix":1,"x":"var $bm_rt;\nif (thisProperty.numKeys > 1) {\n $bm_rt = thisProperty.loopOut('cycle');\n} else {\n $bm_rt = value;\n}"}},{"ty":7,"nm":"Loop","mn":"Pseudo/ADBE Trace Path-0002","ix":2,"v":{"a":0,"k":0,"ix":2}}]}],"ip":0,"op":720,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"botDot","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[660,124,0],"ix":2,"x":"var $bm_rt;\nvar barLayer, barPath;\nbarLayer = thisComp.layer('bar');\nbarPath = barLayer.content('Path 1').path.points();\n$bm_rt = sub(barLayer.toComp(barPath[1]), sub(thisComp.layer('traceNull').transform.position, barLayer.toComp(barPath[0])));"},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[12,12],"e":[16,16]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":30,"s":[16,16],"e":[12,12]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":60,"s":[12,12],"e":[4,4]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":90,"s":[4,4],"e":[12,12]},{"t":120}],"ix":2,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.666666666667,0.850980392157,0.96862745098,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":720,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"topDot","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[388,200,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('traceNull').transform.position;"},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[12,12],"e":[4,4]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":30,"s":[4,4],"e":[12,12]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":60,"s":[12,12],"e":[16,16]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":90,"s":[16,16],"e":[12,12]},{"t":120}],"ix":2,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.666666666667,0.850980392157,0.96862745098,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":720,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"bar","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[306,436,0],"ix":2},"a":{"a":0,"k":[102,468,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-171,76],[-171,396]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('traceNull').effect('Trace Path')('Progress');"},"e":{"a":0,"k":100,"ix":2,"x":"var $bm_rt;\n$bm_rt = sub(100, content('Trim Paths 1').start);"},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":2,"ix":10},"g":{"p":5,"k":{"a":0,"k":[0,0.639,0.816,0.929,0.254,0.357,0.496,0.594,0.507,0.075,0.176,0.259,0.754,0.357,0.496,0.594,1,0.639,0.816,0.929,0,1,0.253,0.5,0.505,0,0.752,0.5,1,1],"ix":8}},"s":{"a":0,"k":[258,509],"ix":4},"e":{"a":1,"k":[{"i":{"x":0.6,"y":1},"o":{"x":0.4,"y":0},"n":"0p6_1_0p4_0","t":0,"s":[396,-25],"e":[-7,-25],"to":[0,0],"ti":[0,0]},{"i":{"x":0.6,"y":1},"o":{"x":0.4,"y":0},"n":"0p6_1_0p4_0","t":60,"s":[-7,-25],"e":[396,-25],"to":[0,0],"ti":[0,0]},{"t":120}],"ix":5,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"t":1,"lc":1,"lj":1,"ml":4,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false}],"ip":0,"op":720,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"NULL CONTROL","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":20,"ix":10},"p":{"a":0,"k":[410.059,291.323,0],"ix":2},"a":{"a":0,"k":[60,60,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":241,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"meet graph","parent":1,"refId":"comp_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60,60,0],"ix":2},"a":{"a":0,"k":[400,300,0],"ix":1},"s":{"a":0,"k":[78.88,-78.88,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Starglow","np":68,"mn":"tc Starglow","ix":1,"en":0,"ef":[{"ty":7,"nm":"Preset","mn":"tc Starglow-0059","ix":1,"v":{"a":0,"k":39,"ix":1}},{"ty":7,"nm":"Input Channel","mn":"tc Starglow-0001","ix":2,"v":{"a":0,"k":4,"ix":2}},{"ty":6,"nm":"Pre-Process","mn":"tc Starglow-0002","ix":3,"v":0},{"ty":0,"nm":"Threshold","mn":"tc Starglow-0003","ix":4,"v":{"a":0,"k":160,"ix":4}},{"ty":0,"nm":"Threshold Soft","mn":"tc Starglow-0004","ix":5,"v":{"a":0,"k":10,"ix":5}},{"ty":7,"nm":"Use Mask","mn":"tc Starglow-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Mask Radius","mn":"tc Starglow-0006","ix":7,"v":{"a":0,"k":100,"ix":7}},{"ty":0,"nm":"Mask Feather","mn":"tc Starglow-0007","ix":8,"v":{"a":0,"k":50,"ix":8}},{"ty":3,"nm":"Mask Position","mn":"tc Starglow-0008","ix":9,"v":{"a":0,"k":[400,300],"ix":9}},{"ty":6,"nm":"","mn":"tc Starglow-0009","ix":10,"v":0},{"ty":0,"nm":"Streak Length","mn":"tc Starglow-0010","ix":11,"v":{"a":0,"k":20,"ix":11}},{"ty":0,"nm":"Boost Light","mn":"tc Starglow-0021","ix":12,"v":{"a":0,"k":0,"ix":12}},{"ty":6,"nm":"Individual Lengths","mn":"tc Starglow-0011","ix":13,"v":0},{"ty":0,"nm":"Up","mn":"tc Starglow-0012","ix":14,"v":{"a":0,"k":1,"ix":14}},{"ty":0,"nm":"Down","mn":"tc Starglow-0013","ix":15,"v":{"a":0,"k":1,"ix":15}},{"ty":0,"nm":"Left","mn":"tc Starglow-0014","ix":16,"v":{"a":0,"k":0,"ix":16}},{"ty":0,"nm":"Right","mn":"tc Starglow-0015","ix":17,"v":{"a":0,"k":0,"ix":17}},{"ty":0,"nm":"Up Left","mn":"tc Starglow-0016","ix":18,"v":{"a":0,"k":0,"ix":18}},{"ty":0,"nm":"Up Right","mn":"tc Starglow-0017","ix":19,"v":{"a":0,"k":0,"ix":19}},{"ty":0,"nm":"Down Left","mn":"tc Starglow-0018","ix":20,"v":{"a":0,"k":0,"ix":20}},{"ty":0,"nm":"Down Right","mn":"tc Starglow-0019","ix":21,"v":{"a":0,"k":0,"ix":21}},{"ty":6,"nm":"","mn":"tc Starglow-0020","ix":22,"v":0},{"ty":6,"nm":"Individual Colors","mn":"tc Starglow-0046","ix":23,"v":0},{"ty":7,"nm":"Up","mn":"tc Starglow-0047","ix":24,"v":{"a":0,"k":1,"ix":24}},{"ty":7,"nm":"Down","mn":"tc Starglow-0048","ix":25,"v":{"a":0,"k":2,"ix":25}},{"ty":7,"nm":"Left","mn":"tc Starglow-0049","ix":26,"v":{"a":0,"k":1,"ix":26}},{"ty":7,"nm":"Right","mn":"tc Starglow-0050","ix":27,"v":{"a":0,"k":1,"ix":27}},{"ty":7,"nm":"Up Left","mn":"tc Starglow-0051","ix":28,"v":{"a":0,"k":1,"ix":28}},{"ty":7,"nm":"Up Right","mn":"tc Starglow-0052","ix":29,"v":{"a":0,"k":1,"ix":29}},{"ty":7,"nm":"Down Left","mn":"tc Starglow-0053","ix":30,"v":{"a":0,"k":2,"ix":30}},{"ty":7,"nm":"Down Right","mn":"tc Starglow-0054","ix":31,"v":{"a":0,"k":3,"ix":31}},{"ty":6,"nm":"","mn":"tc Starglow-0055","ix":32,"v":0},{"ty":6,"nm":"Colormap A","mn":"tc Starglow-0022","ix":33,"v":0},{"ty":7,"nm":"Preset","mn":"tc Starglow-0023","ix":34,"v":{"a":0,"k":5,"ix":34}},{"ty":2,"nm":"Highlights","mn":"tc Starglow-0024","ix":35,"v":{"a":0,"k":[1,1,1,0],"ix":35}},{"ty":2,"nm":"Mid High","mn":"tc Starglow-0025","ix":36,"v":{"a":0,"k":[1,0.650980392157,1,0],"ix":36}},{"ty":2,"nm":"Midtones","mn":"tc Starglow-0026","ix":37,"v":{"a":0,"k":[1,0.650980392157,0,0.035294117647],"ix":37}},{"ty":2,"nm":"Mid Low","mn":"tc Starglow-0027","ix":38,"v":{"a":0,"k":[1,0.650980392157,1,0],"ix":38}},{"ty":2,"nm":"Shadows","mn":"tc Starglow-0028","ix":39,"v":{"a":0,"k":[1,0,0,0],"ix":39}},{"ty":6,"nm":"","mn":"tc Starglow-0029","ix":40,"v":0},{"ty":6,"nm":"Colormap B","mn":"tc Starglow-0030","ix":41,"v":0},{"ty":7,"nm":"Preset","mn":"tc Starglow-0031","ix":42,"v":{"a":0,"k":9,"ix":42}},{"ty":2,"nm":"Highlights","mn":"tc Starglow-0032","ix":43,"v":{"a":0,"k":[1,1,1,0],"ix":43}},{"ty":2,"nm":"Mid High","mn":"tc Starglow-0033","ix":44,"v":{"a":0,"k":[0.988235294118,0.788235294118,0.635294117647,0],"ix":44}},{"ty":2,"nm":"Midtones","mn":"tc Starglow-0034","ix":45,"v":{"a":0,"k":[0.501960784314,1,1,0.035294117647],"ix":45}},{"ty":2,"nm":"Mid Low","mn":"tc Starglow-0035","ix":46,"v":{"a":0,"k":[0.572549019608,0.478431372549,0.945098039216,0],"ix":46}},{"ty":2,"nm":"Shadows","mn":"tc Starglow-0036","ix":47,"v":{"a":0,"k":[0,0,1,0],"ix":47}},{"ty":6,"nm":"","mn":"tc Starglow-0037","ix":48,"v":0},{"ty":6,"nm":"Colormap C","mn":"tc Starglow-0038","ix":49,"v":0},{"ty":7,"nm":"Preset","mn":"tc Starglow-0039","ix":50,"v":{"a":0,"k":7,"ix":50}},{"ty":2,"nm":"Highlights","mn":"tc Starglow-0040","ix":51,"v":{"a":0,"k":[1,1,1,0],"ix":51}},{"ty":2,"nm":"Mid High","mn":"tc Starglow-0041","ix":52,"v":{"a":0,"k":[0.78431372549,1,0.501960784314,1],"ix":52}},{"ty":2,"nm":"Midtones","mn":"tc Starglow-0042","ix":53,"v":{"a":0,"k":[0.650980392157,1,0,0.035294117647],"ix":53}},{"ty":2,"nm":"Mid Low","mn":"tc Starglow-0043","ix":54,"v":{"a":0,"k":[0.313725490196,1,0,1],"ix":54}},{"ty":2,"nm":"Shadows","mn":"tc Starglow-0044","ix":55,"v":{"a":0,"k":[0,1,0,0],"ix":55}},{"ty":6,"nm":"","mn":"tc Starglow-0045","ix":56,"v":0},{"ty":6,"nm":"Shimmer","mn":"tc Starglow-0060","ix":57,"v":0},{"ty":0,"nm":"Amount","mn":"tc Starglow-0061","ix":58,"v":{"a":0,"k":0,"ix":58}},{"ty":0,"nm":"Detail","mn":"tc Starglow-0062","ix":59,"v":{"a":0,"k":10,"ix":59}},{"ty":0,"nm":"Phase","mn":"tc Starglow-0063","ix":60,"v":{"a":0,"k":0,"ix":60}},{"ty":7,"nm":"Use Loop","mn":"tc Starglow-0064","ix":61,"v":{"a":0,"k":0,"ix":61}},{"ty":0,"nm":"Revolutions in Loop","mn":"tc Starglow-0065","ix":62,"v":{"a":0,"k":1,"ix":62}},{"ty":6,"nm":"","mn":"tc Starglow-0066","ix":63,"v":0},{"ty":0,"nm":"Source Opacity","mn":"tc Starglow-0056","ix":64,"v":{"a":0,"k":100,"ix":64}},{"ty":0,"nm":"Starglow Opacity","mn":"tc Starglow-0057","ix":65,"v":{"a":0,"k":43,"ix":65}},{"ty":7,"nm":"Transfer Mode","mn":"tc Starglow-0058","ix":66,"v":{"a":0,"k":7,"ix":66}}]}],"w":800,"h":600,"ip":0,"op":241,"st":-16,"bm":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/done.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/done.json deleted file mode 100644 index a4b11963..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/done.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.11.1","fr":29.9700012207031,"ip":0,"op":76.0000030955435,"w":70,"h":70,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[35,35,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":33,"s":[0,0,100],"e":[120,120,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":46,"s":[120,120,100],"e":[100,100,100]},{"t":52.0000021180034}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-7,1.438],[-2.656,5.781],[7.422,-4.297]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":33,"s":[0],"e":[100]},{"t":52.0000021180034}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":450.000018328876,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[35,35,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":18,"s":[0,0,100],"e":[120,120,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":33,"s":[120,120,100],"e":[80,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":41,"s":[80,80,100],"e":[110,110,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":49,"s":[110,110,100],"e":[100,100,100]},{"t":52.0000021180034}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.015,0],[0,-13.015],[-13.015,0],[0,13.015]],"o":[[-13.015,0],[0,13.015],[13.015,0],[0,-13.015]],"v":[[0,-23.566],[-23.566,0],[0,23.566],[23.566,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.898039215686,0.898039215686,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.760784313725,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[105.535,105.535],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":450.000018328876,"st":0,"bm":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/dynamic_path_test.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/dynamic_path_test.json deleted file mode 100644 index a01e506d..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/dynamic_path_test.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.17","fr":29.9700012207031,"ip":0,"op":150.000006109625,"w":300,"h":300,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":20,"s":[135,135],"e":[116,116]},{"t":137.000005580124}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[24,25],"e":[57,52],"to":[5.5,4.5],"ti":[-5.5,-4.5]},{"t":129.000005254278}],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[54]},{"t":149.000006068894}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[100,100],"e":[50,50]},{"t":40.0000016292334}],"ix":2},"p":{"a":0,"k":[-26,-37],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.145327582955,0.057777773589,0.866666674614,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 2","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":5,"ix":3},"p":{"a":0,"k":[26,-54],"ix":4},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":110,"s":[0],"e":[184]},{"t":149.000006068894}],"ix":5},"ir":{"a":0,"k":30,"ix":6},"is":{"a":0,"k":27,"ix":8},"or":{"a":0,"k":59,"ix":7},"os":{"a":0,"k":73,"ix":9},"ix":5,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"fl","c":{"a":0,"k":[0.07993286103,0.716212213039,0.766274511814,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 3","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":150.000006109625,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/dynamic_property.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/dynamic_property.json deleted file mode 100644 index ef04bd08..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/dynamic_property.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.4.3","fr":60,"ip":0,"op":30,"w":800,"h":800,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"ABCDEFG Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[395,397,0],"ix":2},"a":{"a":0,"k":[86,-17,0],"ix":1},"s":{"a":0,"k":[343,343,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-0.516],[0.334,-0.269],[0.949,-0.047],[0,0],[0,0],[0,0],[0.545,0.475],[0.668,1.594],[0,0],[0,0],[0,0],[0.598,-0.563],[0.996,-0.176],[0,0],[0,0],[0,0],[0.346,0.275],[0,0.363],[-0.399,0.926],[0,0],[0,0]],"o":[[0.469,1.113],[0,0.387],[-0.334,0.27],[0,0],[0,0],[0,0],[-0.973,-0.059],[-0.545,-0.475],[0,0],[0,0],[0,0],[-0.727,1.723],[-0.293,0.281],[0,0],[0,0],[0,0],[-1.149,-0.082],[-0.346,-0.275],[0,-0.457],[0,0],[0,0],[0,0]],"v":[[17.912,-4.553],[18.615,-2.109],[18.114,-1.125],[16.189,-0.65],[16.189,0],[25.594,0],[25.594,-0.65],[23.317,-1.45],[21.498,-4.553],[13.201,-24.381],[12.586,-24.381],[4.201,-4.764],[2.215,-1.336],[0.281,-0.65],[0.281,0],[7.787,0],[7.787,-0.65],[5.546,-1.187],[5.027,-2.145],[5.625,-4.219],[7.242,-7.98],[16.471,-7.98]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[7.787,-9.281],[11.936,-18.914],[15.979,-9.281]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.727,0.943],[0,1.195],[0.926,1.072],[1.758,0.422],[1.922,0],[0,0],[0,0],[0,0],[-0.457,-0.516],[0,-1.477],[0,0],[0.269,-0.41],[0.996,0],[0,0],[0,0],[0,0],[-1.307,0.498],[-0.75,1.084],[0,1.184],[1.137,1.078],[1.652,0.352]],"o":[[0.726,-0.943],[0,-1.394],[-0.926,-1.072],[-1.16,-0.281],[0,0],[0,0],[0,0],[0.902,0],[0.34,0.387],[0,0],[0,1.336],[-0.434,0.633],[0,0],[0,0],[0,0],[2.683,0],[1.307,-0.498],[0.75,-1.084],[0,-1.558],[-0.82,-0.773],[1.418,-0.457]],"v":[[45.844,-14.265],[46.934,-17.473],[45.545,-21.173],[41.52,-23.414],[36.896,-23.836],[26.596,-23.836],[26.596,-23.186],[27.492,-23.186],[29.531,-22.412],[30.041,-19.617],[30.041,-4.219],[29.637,-1.6],[27.492,-0.65],[26.596,-0.65],[26.596,0],[37.846,0],[43.831,-0.747],[46.916,-3.12],[48.041,-6.521],[46.336,-10.477],[42.627,-12.164]],"c":true},"ix":2},"nm":"B","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-1.172,0],[-1.137,-0.984],[0,-1.394],[0.457,-0.762],[0.861,-0.369],[1.711,0],[0.556,0.041],[0.433,0.082]],"o":[[0.937,-0.258],[2.18,0],[1.137,0.984],[0,0.903],[-0.457,0.762],[-0.861,0.369],[-0.668,0],[-0.557,-0.041],[0,0]],"v":[[33.416,-22.271],[36.58,-22.658],[41.555,-21.182],[43.26,-17.613],[42.574,-15.117],[40.597,-13.421],[36.738,-12.867],[34.901,-12.929],[33.416,-13.113]],"c":true},"ix":2},"nm":"B","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[-0.516,0.024],[-0.727,0],[-1.137,-0.492],[-0.504,-0.855],[0,-0.926],[1.113,-0.955],[2.121,0],[1.359,0.316]],"o":[[0.316,-0.059],[0.516,-0.023],[1.676,0],[1.137,0.492],[0.504,0.856],[0,1.406],[-1.113,0.955],[-1.324,0],[0,0]],"v":[[33.416,-11.496],[34.664,-11.619],[36.527,-11.654],[40.746,-10.916],[43.207,-8.895],[43.963,-6.223],[42.293,-2.681],[37.441,-1.248],[33.416,-1.723]],"c":true},"ix":2},"nm":"B","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":6,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.305,-0.316],[0.316,0],[0.492,0.258],[1.723,0],[1.869,-1.096],[1.066,-1.992],[0,-2.379],[-1.617,-2.18],[-3.949,0],[-1.594,0.984],[-1.195,2.121],[0,0],[1.184,-0.662],[1.547,0],[1.389,0.844],[0.691,1.582],[0,2.156],[-0.733,1.758],[-1.277,0.803],[-1.582,0],[-1.348,-1.066],[-0.727,-2.426],[0,0],[0,0]],"o":[[-0.129,0.563],[-0.235,0.223],[-0.211,0],[-1.676,-0.844],[-2.215,0],[-1.869,1.096],[-1.066,1.992],[0,2.953],[2.168,2.93],[2.191,0],[1.594,-0.984],[0,0],[-1.418,1.969],[-1.184,0.662],[-1.781,0],[-1.389,-0.844],[-0.692,-1.582],[0,-2.613],[0.732,-1.758],[1.277,-0.803],[1.887,0],[1.347,1.066],[0,0],[0,0],[0,0]],"v":[[71.068,-24.381],[70.418,-23.063],[69.592,-22.729],[68.537,-23.115],[63.439,-24.381],[57.313,-22.737],[52.91,-18.105],[51.311,-11.549],[53.736,-3.85],[62.912,0.545],[68.59,-0.932],[72.773,-5.59],[72.229,-5.941],[68.326,-1.995],[64.23,-1.002],[59.476,-2.268],[56.355,-5.906],[55.318,-11.514],[56.417,-18.07],[59.432,-21.911],[63.721,-23.115],[68.572,-21.516],[71.684,-16.277],[72.229,-16.277],[71.684,-24.381]],"c":true},"ix":2},"nm":"C","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"C","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-2.262,2.485],[0,3.316],[1.131,1.887],[1.857,0.809],[3.562,0],[0,0],[0,0],[0,0],[-0.457,-0.516],[0,-1.488],[0,0],[0.258,-0.387],[1.008,0],[0,0],[0,0]],"o":[[4.629,0],[2.015,-2.226],[0,-2.472],[-1.131,-1.887],[-1.858,-0.809],[0,0],[0,0],[0,0],[0.902,0],[0.328,0.375],[0,0],[0,1.348],[-0.422,0.645],[0,0],[0,0],[0,0]],"v":[[85.289,0],[95.625,-3.727],[98.648,-12.041],[96.952,-18.58],[92.47,-22.623],[84.34,-23.836],[74.637,-23.836],[74.637,-23.186],[75.533,-23.186],[77.572,-22.412],[78.064,-19.617],[78.064,-4.219],[77.678,-1.617],[75.533,-0.65],[74.637,-0.65],[74.637,0]],"c":true},"ix":2},"nm":"D","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-1.055,0],[-1.793,-1.898],[0,-3.293],[1.793,-1.91],[2.719,0],[1.488,0.328]],"o":[[1.347,-0.34],[2.813,0],[1.793,1.898],[0,3.27],[-1.793,1.91],[-1.008,0],[0,0]],"v":[[81.439,-21.99],[85.043,-22.5],[91.951,-19.652],[94.641,-11.865],[91.951,-4.096],[85.184,-1.23],[81.439,-1.723]],"c":true},"ix":2},"nm":"D","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"D","np":5,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.469,-0.176],[-0.299,-0.469],[-0.246,-1.254],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.422,-0.469],[0,-1.512],[0,0],[0.135,-0.375],[0.375,-0.187],[0.563,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.726,-0.726],[0.609,-0.187],[1.347,0],[0,0],[0.234,0.135],[0.094,0.229],[0,1.055],[0,0],[0,0],[-0.481,-0.234],[-0.211,-0.41],[-0.164,-1.16],[0,0],[0,0],[0,0],[0.609,-0.539],[1.359,0],[0,0],[0,0]],"o":[[1.184,0],[0.586,0.246],[0.299,0.469],[0,0],[0,0],[0,0],[0,0],[0,0],[0.984,0],[0.305,0.352],[0,0],[0,1.16],[-0.135,0.375],[-0.504,0.27],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.762,1.465],[-0.563,0.551],[-0.609,0.188],[0,0],[-0.656,0],[-0.235,-0.135],[-0.094,-0.229],[0,0],[0,0],[0.996,0],[0.48,0.235],[0.164,0.328],[0,0],[0,0],[0,0],[-0.07,1.36],[-0.457,0.41],[0,0],[0,0],[0,0]],"v":[[114.082,-22.535],[116.561,-22.271],[117.888,-21.199],[118.705,-18.615],[119.391,-18.615],[119.127,-23.836],[100.758,-23.836],[100.758,-23.186],[101.602,-23.186],[103.711,-22.482],[104.168,-19.688],[104.168,-4.201],[103.966,-1.898],[103.201,-1.055],[101.602,-0.65],[100.758,-0.65],[100.758,0],[119.127,0],[121.184,-5.977],[120.48,-5.977],[118.248,-2.689],[116.49,-1.582],[113.555,-1.301],[109.512,-1.301],[108.176,-1.503],[107.684,-2.048],[107.543,-3.973],[107.543,-11.83],[112.781,-11.83],[114.996,-11.479],[116.033,-10.512],[116.525,-8.279],[117.176,-8.279],[117.176,-16.576],[116.525,-16.576],[115.506,-13.729],[112.781,-13.113],[107.543,-13.113],[107.543,-22.535]],"c":true},"ix":2},"nm":"E","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"E","np":3,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.592,-0.234],[-0.404,-0.521],[-0.305,-1.113],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.504,-0.281],[-0.117,-0.293],[0,-1.207],[0,0],[0.281,-0.375],[0.984,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.516,0.281],[0.117,0.293],[0,1.207],[0,0],[0,0],[-0.404,-0.217],[-0.229,-0.433],[-0.012,-0.926],[0,0],[0,0],[0,0],[0.463,-0.439],[0.996,0],[0,0],[0,0]],"o":[[1.242,0],[0.592,0.235],[0.404,0.522],[0,0],[0,0],[0,0],[0,0],[0,0],[0.574,0],[0.363,0.211],[0.152,0.387],[0,0],[0,1.43],[-0.445,0.574],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.563,0],[-0.375,-0.211],[-0.152,-0.387],[0,0],[0,0],[0.797,0],[0.404,0.217],[0.229,0.434],[0,0],[0,0],[0,0],[-0.152,1.301],[-0.463,0.439],[0,0],[0,0],[0,0]],"v":[[134.631,-22.535],[137.382,-22.184],[138.876,-21.05],[139.939,-18.598],[140.555,-18.598],[140.326,-23.836],[122.59,-23.836],[122.59,-23.186],[123.434,-23.186],[125.051,-22.764],[125.771,-22.008],[126,-19.617],[126,-4.219],[125.578,-1.512],[123.434,-0.65],[122.59,-0.65],[122.59,0],[132.82,0],[132.82,-0.65],[131.959,-0.65],[130.342,-1.072],[129.604,-1.828],[129.375,-4.219],[129.375,-11.707],[133.717,-11.707],[135.519,-11.382],[136.468,-10.406],[136.828,-8.367],[137.479,-8.367],[137.479,-16.436],[136.828,-16.436],[135.905,-13.825],[133.717,-13.166],[129.375,-13.166],[129.375,-22.535]],"c":true},"ix":2},"nm":"F","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"F","np":3,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.158,-0.205],[0.222,0],[0.656,0.246],[0.709,0.141],[0.867,0],[1.746,-1.02],[1.195,-2.285],[0,-2.098],[-1.793,-2.215],[-4.605,0],[-1.313,0.34],[-1.348,0.727],[0,0],[-0.235,0.434],[-0.914,0],[0,0],[0,0],[0,0],[0,0],[-0.381,-0.193],[-0.182,-0.369],[0,-1.195],[0,0],[0.82,-0.222],[0.879,0],[1.424,0.873],[0.879,1.875],[0,2.274],[-1.324,2.028],[-3.035,0],[-1.418,-1.371],[-0.621,-1.875],[0,0],[0,0]],"o":[[-0.035,0.598],[-0.158,0.205],[-0.223,0],[-1.301,-0.48],[-0.709,-0.141],[-2.379,0],[-2.086,1.23],[-1.008,1.922],[0,2.895],[2.391,2.953],[1.605,0],[1.312,-0.34],[0,0],[0,-1.277],[0.34,-0.609],[0,0],[0,0],[0,0],[0,0],[0.961,0],[0.381,0.193],[0.182,0.369],[0,0],[-0.762,0.434],[-0.82,0.223],[-1.5,0],[-1.424,-0.873],[-0.879,-1.875],[0,-2.801],[1.582,-2.402],[2.226,0],[0.984,0.949],[0,0],[0,0],[0,0]],"v":[[163.477,-24.381],[163.187,-23.177],[162.615,-22.869],[161.297,-23.238],[158.282,-24.17],[155.918,-24.381],[149.73,-22.852],[144.809,-17.578],[143.297,-11.549],[145.986,-3.885],[156.48,0.545],[160.857,0.035],[164.848,-1.564],[164.848,-8.859],[165.199,-11.426],[167.08,-12.34],[167.52,-12.34],[167.52,-13.008],[158.291,-13.008],[158.291,-12.34],[160.304,-12.05],[161.147,-11.206],[161.42,-8.859],[161.42,-1.969],[159.047,-0.984],[156.498,-0.65],[152.112,-1.96],[148.658,-6.082],[147.34,-12.305],[149.326,-19.547],[156.252,-23.15],[161.719,-21.094],[164.127,-16.857],[164.742,-16.857],[164.127,-24.381]],"c":true},"ix":2},"nm":"G","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"G","np":3,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/eid_mubarak.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/eid_mubarak.json deleted file mode 100644 index 7c198b1d..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/eid_mubarak.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.6","fr":29.9700012207031,"ip":0,"op":144.00000586524,"w":800,"h":800,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Dot1/Eid-letters Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[387,452,0],"ix":2},"a":{"a":0,"k":[16,16,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":90,"s":[0,0,100],"e":[100,100,100]},{"t":100.000004073084}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[8.897,-0.05],[0.113,9.015],[-8.894,0.102],[-0.039,-8.805]],"o":[[-8.985,0.051],[-0.111,-8.845],[8.768,-0.1],[0.039,8.935]],"v":[[0.144,15.694],[-15.609,0.174],[-0.079,-15.645],[15.68,-0.066]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.046535948211,0.414443550858,0.698039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[15.969,15.995],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Dot2/Eid-letters Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":100,"ix":10},"p":{"a":0,"k":[378,485,0],"ix":2},"a":{"a":0,"k":[13,13,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":85,"s":[0,0,100],"e":[100,100,100]},{"t":96.0000039101602}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.005,-7.006],[7.005,0.057],[-0.098,6.816],[-6.785,-0.025]],"o":[[-0.006,7.073],[-6.911,-0.055],[0.098,-6.888],[6.855,0.025]],"v":[[12.548,0.084],[0.055,12.587],[-12.455,-0.029],[0.172,-12.619]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.046535948211,0.414443550858,0.698039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[12.803,12.894],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Dot3/Eid-letters Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[485,606,0],"ix":2},"a":{"a":0,"k":[16.5,16,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":40,"s":[0,0,100],"e":[100,100,100]},{"t":55.0000022401959}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[8.746,-0.066],[0.071,8.674],[-8.785,0.027],[-0.09,-8.869]],"o":[[-8.745,0.067],[-0.073,-8.788],[8.991,-0.027],[0.088,8.767]],"v":[[0.186,15.657],[-15.759,0.091],[-0.154,-15.698],[15.745,-0.218]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.046535948211,0.414443550858,0.698039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.083,15.975],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"E/Eid-letters Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[477,380,0],"ix":2},"a":{"a":0,"k":[122.5,80,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[14.912,0],[0,-15.74],[-14.912,0],[0,15.74]],"o":[[-14.912,0],[0,15.74],[14.912,0],[0,-15.74]],"v":[[224.5,-49],[197.5,-20.5],[223,11],[251.5,-20.5]],"c":true}],"e":[{"i":[[14.912,0],[9.238,-12.744],[-14.884,0.906],[0,15.74]],"o":[[-14.912,0],[-83,114.5],[57.5,-3.5],[0,-15.74]],"v":[[201,22],[156.5,14],[170.5,103],[251.5,-20.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":8,"s":[{"i":[[14.912,0],[9.238,-12.744],[-14.884,0.906],[0,15.74]],"o":[[-14.912,0],[-83,114.5],[57.5,-3.5],[0,-15.74]],"v":[[201,22],[156.5,14],[170.5,103],[251.5,-20.5]],"c":true}],"e":[{"i":[[14.912,0],[9.238,-12.744],[-14.884,0.906],[0,15.74]],"o":[[-14.912,0],[-83,114.5],[57.5,-3.5],[0,-15.74]],"v":[[201,22],[156.5,14],[160.5,130.5],[251.5,-20.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":13,"s":[{"i":[[14.912,0],[9.238,-12.744],[-14.884,0.906],[0,15.74]],"o":[[-14.912,0],[-83,114.5],[57.5,-3.5],[0,-15.74]],"v":[[201,22],[156.5,14],[160.5,130.5],[251.5,-20.5]],"c":true}],"e":[{"i":[[14.912,0],[9.238,-12.744],[-14.884,0.911],[29,236.5]],"o":[[-14.912,0],[-83,114.5],[49,-3],[-1.916,-15.623]],"v":[[201,22],[156.5,14],[160.5,130.5],[251.5,-20.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[{"i":[[14.912,0],[9.238,-12.744],[-14.884,0.911],[29,236.5]],"o":[[-14.912,0],[-83,114.5],[49,-3],[-1.916,-15.623]],"v":[[201,22],[156.5,14],[160.5,130.5],[251.5,-20.5]],"c":true}],"e":[{"i":[[14.912,0],[9.238,-12.744],[10.544,-10.544],[29,236.5]],"o":[[-14.912,0],[-83,114.5],[-100,100],[-1.916,-15.623]],"v":[[201,22],[156.5,14],[99,117],[251.5,-20.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":27,"s":[{"i":[[14.912,0],[9.238,-12.744],[10.544,-10.544],[29,236.5]],"o":[[-14.912,0],[-83,114.5],[-100,100],[-1.916,-15.623]],"v":[[201,22],[156.5,14],[99,117],[251.5,-20.5]],"c":true}],"e":[{"i":[[14.912,0],[7.935,-13.594],[9.191,-3.786],[183.637,333.26]],"o":[[-14.912,0],[-79.939,136.951],[-157.852,65.032],[-7.596,-13.786]],"v":[[201,22],[156.5,14],[50.5,109.5],[221.5,-13]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":32,"s":[{"i":[[14.912,0],[7.935,-13.594],[9.191,-3.786],[183.637,333.26]],"o":[[-14.912,0],[-79.939,136.951],[-157.852,65.032],[-7.596,-13.786]],"v":[[201,22],[156.5,14],[50.5,109.5],[221.5,-13]],"c":true}],"e":[{"i":[[14.912,0],[7.935,-13.594],[9.191,-3.786],[183.637,333.26]],"o":[[-14.912,0],[-79.939,136.951],[-157.852,65.032],[-7.596,-13.786]],"v":[[201,22],[156.5,20.5],[41,88.5],[212,-34]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":39,"s":[{"i":[[14.912,0],[7.935,-13.594],[9.191,-3.786],[183.637,333.26]],"o":[[-14.912,0],[-79.939,136.951],[-157.852,65.032],[-7.596,-13.786]],"v":[[201,22],[156.5,20.5],[41,88.5],[212,-34]],"c":true}],"e":[{"i":[[14.912,0],[7.935,-13.594],[9.191,-3.786],[183.637,333.26]],"o":[[-14.912,0],[-79.939,136.951],[-157.852,65.032],[-7.596,-13.786]],"v":[[201,22],[116.5,-39],[41,88.5],[212,-34]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":44,"s":[{"i":[[14.912,0],[7.935,-13.594],[9.191,-3.786],[183.637,333.26]],"o":[[-14.912,0],[-79.939,136.951],[-157.852,65.032],[-7.596,-13.786]],"v":[[201,22],[116.5,-39],[41,88.5],[212,-34]],"c":true}],"e":[{"i":[[14.912,0],[7.935,-13.594],[8.523,-5.115],[178.348,365.656]],"o":[[-14.912,0],[-79.939,136.951],[-163.23,97.968],[-6.9,-14.147]],"v":[[201,22],[116.5,-39],[-19.5,41],[212,-34]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":49,"s":[{"i":[[14.912,0],[7.935,-13.594],[8.523,-5.115],[178.348,365.656]],"o":[[-14.912,0],[-79.939,136.951],[-163.23,97.968],[-6.9,-14.147]],"v":[[201,22],[116.5,-39],[-19.5,41],[212,-34]],"c":true}],"e":[{"i":[[14.912,0],[7.935,-13.594],[8.523,-5.115],[178.348,365.656]],"o":[[-14.912,0],[-79.939,136.951],[-163.23,97.968],[-6.9,-14.147]],"v":[[201,22],[13,-89],[-19.5,41],[212,-34]],"c":true}]},{"t":57.0000023216576}],"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-15.21,7.235],[2.246,0.395],[-9.788,20.106],[-0.732,1.373],[-6.202,-0.151],[-9.412,15.289],[-2.308,4.75],[-0.675,-1.605],[9.191,-12.372],[8.825,-1.392],[9.092,5.583],[1.895,0.378],[-1.216,-2.194],[-10.857,-0.872],[-7.769,1.993],[-1.772,1.626],[-9.414,12.271],[-1.1,0.691],[0.055,-1.272],[1.095,-1.404],[25.893,-19.379],[17.172,1.05],[1.317,0]],"o":[[16.191,1.61],[-3.303,-0.366],[-21.938,-3.854],[0.681,-1.399],[2.609,-4.89],[17.204,0.421],[2.286,-3.713],[1.391,1.912],[5.596,13.314],[-5.472,7.363],[-10.169,1.604],[-0.985,-0.606],[0.665,2.499],[5.397,9.744],[8.169,0.655],[2.305,-0.591],[11.422,-10.484],[0.742,-0.967],[0.709,1.305],[-0.076,1.764],[-19.821,25.379],[-13.357,9.996],[-1.066,-0.065],[0,0]],"v":[[5.595,57.525],[51.68,47.482],[43.838,46.594],[21.039,1.595],[23.213,-2.535],[35.427,-9.515],[76.559,-30.424],[82.754,-43.023],[86.198,-38.197],[83.743,0.608],[61.716,12.801],[32.576,8.47],[28.808,6.72],[30.885,14.173],[55.884,29.188],[79.64,25.97],[86.045,22.353],[116.637,-12.372],[119.891,-14.481],[121.869,-10.572],[119.958,-5.393],[52.727,63.141],[7.298,78.269],[3.843,78.259]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[3.45,12.351],[0.178,0.306],[0.104,0.059],[13.744,6.907],[-5.73,23.029],[2.691,0.072],[3.141,8.396],[1.117,6.957],[-3.065,-2.548],[-7.604,-0.065],[-13.199,-0.032],[-6.655,-3.927],[10.925,2.071],[7.75,0.539],[9.341,1.332],[4.542,8.538],[-1.104,7.651],[-1.024,5.088],[-0.066,-2.312],[-4.346,-4.918],[-6.589,-0.067],[-8.027,0.351],[-10.117,-5.579],[2.419,-13.264],[1.46,-6.035],[0.262,-2.612],[15.96,0.712],[0.411,-2.425],[-13.665,5.614],[-5.539,3.419],[-2.945,-4.356],[-14.555,-1.639]],"o":[[-20.808,-1.891],[-0.094,-0.335],[-0.052,-0.089],[-11.724,14.264],[-13.077,-6.57],[-2.794,0],[-9.113,-0.242],[-2.489,-6.653],[2.654,3.042],[6.164,5.124],[13.198,0.112],[8.876,0.021],[2.271,-10.209],[-7.578,-1.436],[-9.437,-0.656],[-9.236,-1.317],[-3.756,-7.062],[0.676,-4.686],[3.014,1.48],[0.179,6.347],[4.472,5.061],[8.034,0.081],[11.326,-0.495],[11.722,6.464],[-1.11,6.089],[-0.57,2.353],[-15.945,-4.52],[-2.722,-0.122],[-2.953,17.398],[6.164,-2.532],[1.988,3.936],[2.88,4.259],[0,0]],"v":[[3.843,78.259],[-35.76,44.485],[-36.23,43.534],[-36.535,43.353],[-76.51,54.9],[-87.302,11.892],[-95.482,11.882],[-114.334,-1.163],[-119.259,-21.863],[-111.225,-12.822],[-89.766,-7.158],[-50.168,-7.116],[-30.405,-2.048],[-45.051,-24.108],[-68.273,-25.845],[-96.558,-28.004],[-118.168,-42.428],[-120.398,-64.926],[-117.549,-79.319],[-114.147,-73.424],[-108.44,-56.064],[-91.426,-48.772],[-67.32,-49.199],[-34.953,-42.89],[-19.47,-10.811],[-24.189,7.207],[-24.992,14.67],[-73.022,11.895],[-76.78,15.316],[-48.044,36.241],[-30.94,25.9],[-24.049,39.217],[5.595,57.525]],"c":false},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.046535948211,0.414443550858,0.698039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[122.174,79.568],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"K/Eid-letters Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[306,444,0],"ix":2},"a":{"a":0,"k":[122,132.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":63,"s":[{"i":[[33.413,0],[0,-12.703],[-33.413,0],[0,12.703]],"o":[[-33.413,0],[0,12.703],[33.413,0],[0,-12.703]],"v":[[112.5,-61.5],[52,-38.5],[112.5,-15.5],[173,-38.5]],"c":true}],"e":[{"i":[[33.413,0],[0,-12.703],[-22.871,-24.359],[0,12.703]],"o":[[-33.413,0],[0,12.703],[84.5,90],[0,-12.703]],"v":[[112.5,-61.5],[67,112.5],[127.5,135.5],[173,-38.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":70,"s":[{"i":[[33.413,0],[0,-12.703],[-22.871,-24.359],[0,12.703]],"o":[[-33.413,0],[0,12.703],[84.5,90],[0,-12.703]],"v":[[112.5,-61.5],[67,112.5],[127.5,135.5],[173,-38.5]],"c":true}],"e":[{"i":[[33.413,0],[0,-12.702],[-32.773,-6.508],[0,12.703]],"o":[[-33.413,0],[0,12.703],[211.5,42],[0,-12.703]],"v":[[112.5,-61.5],[20,146.5],[80.5,169.5],[173,-38.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":76,"s":[{"i":[[33.413,0],[0,-12.702],[-32.773,-6.508],[0,12.703]],"o":[[-33.413,0],[0,12.703],[211.5,42],[0,-12.703]],"v":[[112.5,-61.5],[20,146.5],[80.5,169.5],[173,-38.5]],"c":true}],"e":[{"i":[[33.413,0],[-5.1,-11.634],[-32.666,-7.025],[0,12.703]],"o":[[-33.413,0],[32,73],[232.5,50],[0,-12.703]],"v":[[112.5,-61.5],[19,185.5],[79.5,208.5],[173,-38.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":82,"s":[{"i":[[33.413,0],[-5.1,-11.634],[-32.666,-7.025],[0,12.703]],"o":[[-33.413,0],[32,73],[232.5,50],[0,-12.703]],"v":[[112.5,-61.5],[19,185.5],[79.5,208.5],[173,-38.5]],"c":true}],"e":[{"i":[[33.413,0],[-8.343,-9.579],[-32.979,-5.365],[0,12.703]],"o":[[-33.413,0],[54,62],[565.5,92],[0,-12.703]],"v":[[112.5,-61.5],[45,189.5],[105.5,212.5],[298.5,151]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":88,"s":[{"i":[[33.413,0],[-8.343,-9.579],[-32.979,-5.365],[0,12.703]],"o":[[-33.413,0],[54,62],[565.5,92],[0,-12.703]],"v":[[112.5,-61.5],[45,189.5],[105.5,212.5],[298.5,151]],"c":true}],"e":[{"i":[[33.413,0],[-8.343,-9.579],[-30.818,-12.911],[0,12.703]],"o":[[-33.413,0],[54,62],[496.5,208],[0,-12.703]],"v":[[112.5,-61.5],[45,189.5],[105.5,212.5],[298.5,151]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":94,"s":[{"i":[[33.413,0],[-8.343,-9.579],[-30.818,-12.911],[0,12.703]],"o":[[-33.413,0],[54,62],[496.5,208],[0,-12.703]],"v":[[112.5,-61.5],[45,189.5],[105.5,212.5],[298.5,151]],"c":true}],"e":[{"i":[[33.413,0],[-8.343,-9.579],[-5.675,-32.928],[19.5,99.5]],"o":[[-33.413,0],[54,62],[45.5,264],[-2.443,-12.465]],"v":[[112.5,-61.5],[45,189.5],[77.5,216.5],[298.5,151]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":99,"s":[{"i":[[33.413,0],[-8.343,-9.579],[-5.675,-32.928],[19.5,99.5]],"o":[[-33.413,0],[54,62],[45.5,264],[-2.443,-12.465]],"v":[[112.5,-61.5],[45,189.5],[77.5,216.5],[298.5,151]],"c":true}],"e":[{"i":[[33.413,0],[-8.343,-9.579],[-5.675,-32.928],[19.5,99.5]],"o":[[-33.413,0],[54,62],[45.5,264],[-2.443,-12.465]],"v":[[112.5,-61.5],[-23,118.5],[-26.5,210.5],[307.5,161]],"c":true}]},{"t":105.000004276738}],"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.509,10.645],[-2.145,-4.72],[-10.953,-2.651],[-6.522,-0.021],[-50.512,-0.052],[-5.189,-0.785],[-3.43,-8.152],[-0.708,-1.77],[-0.345,0.023],[0.814,3.237],[7.604,3.556],[14.25,0.816],[19.383,1.268],[10.003,4.401],[1.46,15.257],[-0.281,6.69],[-0.172,0.743],[-6.53,-1.78],[-10.108,24.027],[2.916,17.739],[16.924,19.848],[0.274,1.38],[-1.052,-0.768],[-6.537,-8.808],[1.776,-31.941],[12.48,-13.591],[17.96,0.885],[11.095,6.467],[-5.821,-3.975],[-10.296,-0.914],[-17.824,-1.194],[-13.423,-4.065],[-7.468,-10.232],[0.022,-7.864],[0.144,-7.911],[0.578,-1.143],[0.949,0.681],[2.374,0.372],[7.146,0.021],[52.661,0.008],[8.957,5.213],[3.351,11.818]],"o":[[1.571,5.283],[4.779,10.51],[6.347,1.536],[50.511,0.162],[5.247,0.005],[8.724,1.319],[0.739,1.756],[0.345,-0.024],[-0.326,-3.36],[-2.167,-8.615],[-13.165,-6.156],[-19.394,-1.112],[-10.773,-0.705],[-14.255,-6.274],[-0.632,-6.61],[0.048,-1.137],[6.676,2.397],[25.2,6.869],[7.064,-16.792],[-4.251,-25.863],[-0.796,-0.934],[1.51,0.142],[8.858,6.47],[18.928,25.5],[-1,17.995],[-12.177,13.261],[-12.868,-0.634],[0.43,4.427],[8.764,5.985],[17.789,1.579],[13.859,0.929],[11.807,3.577],[4.541,6.221],[-0.023,7.914],[-0.021,1.153],[-0.905,-0.743],[-2.169,-1.558],[-7.065,-1.108],[-52.661,-0.155],[-10.197,-0.001],[-10.676,-6.212],[-2.896,-10.212]],"v":[[-121.032,58.143],[-116.368,73.411],[-91.857,92.734],[-72.331,95.223],[79.204,95.275],[94.935,96.493],[113.163,110.969],[115.291,116.275],[116.327,116.206],[115.27,106.146],[99.143,88.948],[57.531,80.536],[-0.669,77.521],[-32.03,70.315],[-55.567,37.694],[-55.02,17.634],[-54.355,14.633],[-34.878,21.539],[24.458,-7.651],[29.595,-59.495],[-2.872,-127.703],[-3.759,-131.786],[0.708,-131.275],[23.711,-108.223],[50.801,-22.35],[31.987,25.883],[-13.426,44.078],[-49.089,32.782],[-39.414,45.692],[-10.354,55.206],[43.109,58.858],[84.298,64.503],[114.204,83.836],[121.469,104.875],[121.396,128.614],[119.738,132.044],[117.016,129.825],[110.417,125.423],[89.012,123.521],[-68.972,123.416],[-98.089,116.877],[-118.551,89.365]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.046535948211,0.414443550858,0.698039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[121.791,132.294],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"M/Eid-letters Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[447,358,0],"ix":2},"a":{"a":0,"k":[177,234.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":16,"s":[{"i":[[19.33,0],[0,-17.949],[-19.33,0],[0,17.949]],"o":[[-19.33,0],[0,17.949],[19.33,0],[0,-17.949]],"v":[[395,333.5],[360,366],[395,398.5],[430,366]],"c":true}],"e":[{"i":[[18.955,3.791],[0,-17.949],[-19.33,0],[0,17.949]],"o":[[-155,-31],[0,17.949],[19.33,0],[0,-17.949]],"v":[[395,333.5],[284,470],[319,502.5],[430,366]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":26,"s":[{"i":[[18.955,3.791],[0,-17.949],[-19.33,0],[0,17.949]],"o":[[-155,-31],[0,17.949],[19.33,0],[0,-17.949]],"v":[[395,333.5],[284,470],[319,502.5],[430,366]],"c":true}],"e":[{"i":[[18.955,3.791],[0,-17.949],[-16.515,-10.046],[0,17.949]],"o":[[-155,-31],[0,17.949],[217,132],[0,-17.949]],"v":[[395,333.5],[168,464],[203,496.5],[430,366]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":38,"s":[{"i":[[18.955,3.791],[0,-17.949],[-16.515,-10.046],[0,17.949]],"o":[[-155,-31],[0,17.949],[217,132],[0,-17.949]],"v":[[395,333.5],[168,464],[203,496.5],[430,366]],"c":true}],"e":[{"i":[[8.815,17.203],[-0.868,-17.928],[-10,7],[0,17.949]],"o":[[-207,-404],[13,268.5],[208.081,-145.654],[0,-17.949]],"v":[[395,333.5],[141,83],[236,551.5],[421,568]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":44,"s":[{"i":[[8.815,17.203],[-0.868,-17.928],[-10,7],[0,17.949]],"o":[[-207,-404],[13,268.5],[208.081,-145.654],[0,-17.949]],"v":[[395,333.5],[141,83],[236,551.5],[421,568]],"c":true}],"e":[{"i":[[8.904,17.157],[-121,-97.5],[-270,43],[0,17.949]],"o":[[-301,-580],[209.317,168.664],[250.833,-39.947],[0,-17.949]],"v":[[395,333.5],[32,84],[236,551.5],[421,568]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":50,"s":[{"i":[[8.904,17.157],[-121,-97.5],[-270,43],[0,17.949]],"o":[[-301,-580],[209.317,168.664],[250.833,-39.947],[0,-17.949]],"v":[[395,333.5],[32,84],[236,551.5],[421,568]],"c":true}],"e":[{"i":[[8.904,17.157],[-85,-143.5],[-270,43],[0,17.949]],"o":[[-301,-580],[136.998,231.285],[250.833,-39.947],[0,-17.949]],"v":[[395,333.5],[-2,146],[202,613.5],[421,568]],"c":true}]},{"t":63.0000025660426}],"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.386,-4.245],[1.598,4.619],[2.608,6.321],[-4.087,-6.576]],"o":[[4.093,-3.155],[-2.202,-6.363],[-5.213,5.574],[2.42,3.895]],"v":[[152.378,205.634],[154.674,193.072],[147.012,174.25],[145.464,193.406]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.352,-6.311],[0.336,-13.427],[-4.214,-7.723],[-12.867,10.262],[-3.052,3.153],[-1.56,-3.275],[-11.438,9.821],[-4.476,10.63],[-2.437,6.673],[-3.574,-4.79],[-3.354,-3.906],[7.139,-11.656],[6.768,-9.317],[8.117,7.042],[3.823,-4.055],[10.174,3.021],[2.314,10.754],[5.104,-3.02],[9.34,12.862],[0.345,11.327],[0,19.187],[0.144,9.352]],"o":[[-0.658,6.387],[-0.748,13.411],[-0.215,8.566],[7.863,14.41],[3.317,-2.646],[1.247,3.129],[6.474,13.6],[8.997,-7.726],[2.82,-6.692],[3.149,4.939],[3.066,4.109],[8.895,10.356],[-5.583,9.113],[-3.762,-12.216],[-3.529,4.639],[-7.178,7.612],[-7.226,-2.146],[-1.584,6.311],[-12.703,7.512],[-6.864,-9.451],[-0.584,-19.17],[-0.001,-9.355],[0,0]],"v":[[37.694,76.381],[34.037,116.093],[32.308,156.352],[37.512,181.037],[74.36,188.637],[83.412,179.401],[87.383,189.266],[119.917,196.104],[138.491,167.421],[145.978,147.115],[155.653,162.098],[165.941,173.614],[169.35,207.13],[150.125,233.884],[129.519,207.823],[119.128,221.313],[92.875,228.352],[78.16,208.651],[68.231,222.354],[29.762,213.099],[19.553,181.378],[19.407,123.82],[19.314,69.156]],"c":false},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[-0.017,1.005],[-0.401,40.061],[6.175,21.01],[24.443,14.22],[25.532,-19.954],[1.967,-25.641],[-8.44,-14.225],[2.485,-1.879],[1.397,1.826],[3.187,6.491],[-1.463,18.779],[-23.602,18.074],[-34.665,-11.265],[-13.398,-23.511],[-2.664,-25.241],[1.111,-31.166],[1.377,-25.872],[0,-2.799]],"o":[[0.06,-1.004],[0.687,-40.057],[0.218,-21.769],[-7.84,-26.675],[-27.965,-16.27],[-20.344,15.898],[-1.272,16.576],[1.289,2.171],[-1.041,0.786],[-4.417,-5.768],[-8.349,-17.005],[2.32,-29.771],[29.138,-22.313],[25.611,8.323],[12.733,22.34],[3.283,31.122],[-0.924,25.889],[-0.121,2.264],[0,0]],"v":[[19.314,69.156],[19.49,66.144],[21.456,-54.031],[13.18,-118.352],[-33.712,-180.742],[-124.757,-174.553],[-157.743,-112.094],[-146.794,-66.039],[-145.659,-59.128],[-152.535,-62.07],[-164.515,-80.31],[-175.026,-134.412],[-135.401,-206.527],[-38.859,-222.619],[19.035,-173.766],[40.378,-102.055],[41.805,-8.574],[37.712,69.044],[37.694,76.381]],"c":false},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.046535948211,0.414443550858,0.698039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[176.74,234.135],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Moon/Eid-letters Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[378,242,0],"ix":2},"a":{"a":0,"k":[37.5,40,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":61,"s":[{"i":[[10.217,0],[0,-8.56],[-10.217,0],[0,8.56]],"o":[[-10.217,0],[0,8.56],[10.217,0],[0,-8.56]],"v":[[56,-26],[37.5,-10.5],[56,5],[74.5,-10.5]],"c":true}],"e":[{"i":[[10.217,0],[0,-8.56],[-10.217,0],[0,8.56]],"o":[[-10.217,0],[0,8.56],[10.217,0],[0,-8.56]],"v":[[56,-26],[-47.5,49.5],[36,11],[74.5,-10.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":69,"s":[{"i":[[10.217,0],[0,-8.56],[-10.217,0],[0,8.56]],"o":[[-10.217,0],[0,8.56],[10.217,0],[0,-8.56]],"v":[[56,-26],[-47.5,49.5],[36,11],[74.5,-10.5]],"c":true}],"e":[{"i":[[10.217,0],[-3.655,-7.741],[-10.217,0],[0,8.56]],"o":[[-10.217,0],[89,188.5],[10.217,0],[0,-8.56]],"v":[[56,-26],[-47.5,49.5],[36,11],[74.5,-10.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":80,"s":[{"i":[[10.217,0],[-3.655,-7.741],[-10.217,0],[0,8.56]],"o":[[-10.217,0],[89,188.5],[10.217,0],[0,-8.56]],"v":[[56,-26],[-47.5,49.5],[36,11],[74.5,-10.5]],"c":true}],"e":[{"i":[[10.217,0],[-7.781,-3.568],[-10.217,0],[0,8.56]],"o":[[-10.217,0],[326,149.5],[10.217,0],[0,-8.56]],"v":[[56,-26],[-47.5,49.5],[36,11],[74.5,-10.5]],"c":true}]},{"t":89.0000036250443}],"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-15.658,0.156],[-10.218,-16.033],[-18.193,16.255],[16.324,3.105],[-1.53,18.101]],"o":[[-19.83,10.392],[9.625,15.104],[-4.724,13.95],[-21.217,-4.037],[1.779,-21.071]],"v":[[-0.114,-39.281],[-14.396,9.088],[36.881,14.827],[-3.499,36.176],[-35.351,-4.618]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.046535948211,0.414443550858,0.698039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[37.13,39.531],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"R/Eid-letters Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[340,558,0],"ix":2},"a":{"a":0,"k":[123.5,94.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":45,"s":[{"i":[[20.435,0],[0,-17.397],[-20.435,0],[0,17.397]],"o":[[-20.435,0],[0,17.397],[20.435,0],[0,-17.397]],"v":[[272.5,-66.5],[235.5,-35],[272.5,-3.5],[309.5,-35]],"c":true}],"e":[{"i":[[30.652,0],[0,-46.944],[-30.652,0],[0,46.944]],"o":[[-30.652,0],[0,46.944],[30.652,0],[0,-46.944]],"v":[[253,-62.5],[197.5,22.5],[253,107.5],[308.5,22.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":55,"s":[{"i":[[30.652,0],[0,-46.944],[-30.652,0],[0,46.944]],"o":[[-30.652,0],[0,46.944],[30.652,0],[0,-46.944]],"v":[[253,-62.5],[197.5,22.5],[253,107.5],[308.5,22.5]],"c":true}],"e":[{"i":[[70.416,0],[0,-82.29],[-70.416,0],[0,82.29]],"o":[[-70.416,0],[0,82.29],[70.416,0],[0,-82.29]],"v":[[181,-62.5],[53.5,86.5],[181,235.5],[308.5,86.5]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":62,"s":[{"i":[[70.416,0],[0,-82.29],[-70.416,0],[0,82.29]],"o":[[-70.416,0],[0,82.29],[70.416,0],[0,-82.29]],"v":[[181,-62.5],[53.5,86.5],[181,235.5],[308.5,86.5]],"c":true}],"e":[{"i":[[99.964,0],[0,-80.081],[-99.964,0],[0,80.081]],"o":[[-99.964,0],[0,80.081],[99.964,0],[0,-80.081]],"v":[[127.5,-62.5],[-53.5,82.5],[127.5,227.5],[308.5,82.5]],"c":true}]},{"t":69.0000028104276}],"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.146,0.124],[-8.243,-4.776],[-38.109,6.854],[-16.072,7.476],[-9.628,14.094],[3.637,11.238],[4.163,6.798],[2.957,5.406],[-9.868,11.409],[-5.761,2.072],[-1.619,0.391],[-3.699,-10.748],[-3.418,-10.051],[14.678,-20.125],[17.747,-11.114],[24.294,4.112],[29.162,20.773],[6.105,4.777]],"o":[[7.927,5.319],[33.258,19.272],[17.404,-3.131],[15.188,-7.065],[6.436,-9.42],[-2.415,-7.462],[-3.234,-5.281],[-6.578,-12.025],[3.994,-4.618],[0.959,-0.343],[-8.897,10.434],[3.455,10.041],[8.077,23.754],[-12.208,16.739],[-21.088,13.205],[-35.496,-6.006],[-6.308,-4.493],[0.146,-0.125]],"v":[[-122.403,33.635],[-98.574,49.513],[8.324,68.802],[58.81,54.018],[97.266,23.724],[104.221,-7.421],[92.927,-28.471],[82.197,-43.676],[88.143,-82.786],[102.714,-92.925],[106.32,-93.811],[103.241,-61.692],[114.766,-31.969],[104.208,34.024],[60.388,77.071],[-7.983,89.699],[-104.496,48.299],[-122.842,34.008]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.046535948211,0.414443550858,0.698039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[123.092,94.061],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/emoji_shock.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/emoji_shock.json deleted file mode 100644 index 65b69bcb..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/emoji_shock.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.5.7","fr":30,"ip":0,"op":90,"w":100,"h":100,"ddd":0,"assets":[{"id":"comp_43","layers":[{"ddd":0,"ind":0,"ty":4,"nm":"eyes","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[-286,45.5,0]},"a":{"a":0,"k":[-252,-416.5,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[-1.381,0],[0,-1.381],[1.381,0],[0,1.381]],"o":[[1.381,0],[0,1.381],[-1.381,0],[0,-1.381]],"v":[[70.5,-419],[73,-416.5],[70.5,-414],[68,-416.5]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ind":1,"ty":"sh","ks":{"a":0,"k":{"i":[[-1.381,0],[0,-1.381],[1.381,0],[0,1.381]],"o":[[1.381,0],[0,1.381],[-1.381,0],[0,-1.381]],"v":[[97.5,-419],[100,-416.5],[97.5,-414],[95,-416.5]],"c":true}},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.33,0.33,0.28,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":4,"mn":"ADBE Vector Group"}],"ip":0,"op":92,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"eyes_white","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[-286,45.5,0]},"a":{"a":0,"k":[-252,-416.5,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[-3.59,0],[0,-3.59],[3.59,0],[0,3.59]],"o":[[3.59,0],[0,3.59],[-3.59,0],[0,-3.59]],"v":[[97.5,-423],[104,-416.5],[97.5,-410],[91,-416.5]],"c":true}},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.98,0.95,0.94,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[97.38,-416.49],"ix":2},"a":{"a":0,"k":[97.38,-416.49],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":16,"s":[80,80],"e":[150,150]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":21,"s":[150,150],"e":[140,140]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":31,"s":[140,140],"e":[150,150]},{"i":{"x":[0.313,0.313],"y":[1,1]},"o":{"x":[0.069,0.069],"y":[0,0]},"n":["0p313_1_0p069_0","0p313_1_0p069_0"],"t":40,"s":[150,150],"e":[75,75]},{"i":{"x":[0.313,0.313],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0,0]},"n":["0p313_1_0p167_0","0p313_1_0p167_0"],"t":60,"s":[75,75],"e":[80,80]},{"t":90}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[-3.59,0],[0,-3.59],[3.59,0],[0,3.59]],"o":[[3.59,0],[0,3.59],[-3.59,0],[0,-3.59]],"v":[[70.5,-423],[77,-416.5],[70.5,-410],[64,-416.5]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.98,0.95,0.94,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[70.32,-416.373],"ix":2},"a":{"a":0,"k":[70.32,-416.373],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":16,"s":[80,80],"e":[150,150]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":21,"s":[150,150],"e":[140,140]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":31,"s":[140,140],"e":[150,150]},{"i":{"x":[0.313,0.313],"y":[1,1]},"o":{"x":[0.069,0.069],"y":[0,0]},"n":["0p313_1_0p069_0","0p313_1_0p069_0"],"t":40,"s":[150,150],"e":[75,75]},{"i":{"x":[0.313,0.313],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0,0]},"n":["0p313_1_0p167_0","0p313_1_0p167_0"],"t":60,"s":[75,75],"e":[80,80]},{"t":90}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":92,"st":0,"bm":0,"sr":1}]},{"id":"comp_44","layers":[{"ddd":0,"ind":0,"ty":4,"nm":"mouth 3","td":1,"ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[50,65,0]},"a":{"a":0,"k":[84,-397,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":1,"k":[{"i":{"x":0.851,"y":1},"o":{"x":0.837,"y":0},"n":"0p851_1_0p837_0","t":7,"s":[{"i":[[-4.971,0],[0,-2.5],[4.971,0],[0,2.219]],"o":[[4.971,0],[0,2.594],[-4.971,0],[0,-2.344]],"v":[[84,-398.906],[91.5,-397],[84,-395],[76.75,-397]],"c":true}],"e":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-406.812],[93,-397],[84,-386.75],[75,-397]],"c":true}]},{"i":{"x":0.577,"y":1},"o":{"x":0.563,"y":0},"n":"0p577_1_0p563_0","t":14,"s":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-406.812],[93,-397],[84,-386.75],[75,-397]],"c":true}],"e":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-405.5],[93,-397],[84,-389],[75,-397]],"c":true}]},{"i":{"x":0.615,"y":1},"o":{"x":0.586,"y":0},"n":"0p615_1_0p586_0","t":21,"s":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-405.5],[93,-397],[84,-389],[75,-397]],"c":true}],"e":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-406],[93,-397],[84,-388],[75,-397]],"c":true}]},{"i":{"x":0.531,"y":0.201},"o":{"x":0.778,"y":0},"n":"0p531_0p201_0p778_0","t":30,"s":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-406],[93,-397],[84,-388],[75,-397]],"c":true}],"e":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-403.375],[93,-397],[84,-389.625],[75,-397]],"c":true}]},{"i":{"x":0.683,"y":1},"o":{"x":0.587,"y":1},"n":"0p683_1_0p587_1","t":46,"s":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-403.375],[93,-397],[84,-389.625],[75,-397]],"c":true}],"e":[{"i":[[-4.971,0],[0,-2.5],[4.971,0],[0,2.219]],"o":[[4.971,0],[0,2.594],[-4.971,0],[0,-2.344]],"v":[[84,-398.906],[91.5,-397],[84,-395],[76.75,-397]],"c":true}]},{"t":65}]},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":7,"s":[0.33,0.33,0.28,1],"e":[0.96,0.62,0.52,1]},{"t":9}]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":92,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"mouth_teeth","tt":1,"ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[-118,60,0]},"a":{"a":0,"k":[-83.5,-402,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[68,-409.75],[101,-409.75],[101,-400],[68,-400]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.98,0.95,0.94,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":92,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"mouth 2","td":1,"ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[50,65,0]},"a":{"a":0,"k":[84,-397,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":1,"k":[{"i":{"x":0.851,"y":1},"o":{"x":0.837,"y":0},"n":"0p851_1_0p837_0","t":7,"s":[{"i":[[-4.971,0],[0,-2.5],[4.971,0],[0,2.219]],"o":[[4.971,0],[0,2.594],[-4.971,0],[0,-2.344]],"v":[[84,-398.906],[91.5,-397],[84,-395],[76.75,-397]],"c":true}],"e":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-406.812],[93,-397],[84,-386.75],[75,-397]],"c":true}]},{"i":{"x":0.577,"y":1},"o":{"x":0.563,"y":0},"n":"0p577_1_0p563_0","t":14,"s":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-406.812],[93,-397],[84,-386.75],[75,-397]],"c":true}],"e":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-405.5],[93,-397],[84,-389],[75,-397]],"c":true}]},{"i":{"x":0.615,"y":1},"o":{"x":0.586,"y":0},"n":"0p615_1_0p586_0","t":21,"s":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-405.5],[93,-397],[84,-389],[75,-397]],"c":true}],"e":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-406],[93,-397],[84,-388],[75,-397]],"c":true}]},{"i":{"x":0.531,"y":0.201},"o":{"x":0.778,"y":0},"n":"0p531_0p201_0p778_0","t":30,"s":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-406],[93,-397],[84,-388],[75,-397]],"c":true}],"e":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-403.375],[93,-397],[84,-389.625],[75,-397]],"c":true}]},{"i":{"x":0.683,"y":1},"o":{"x":0.587,"y":1},"n":"0p683_1_0p587_1","t":46,"s":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-403.375],[93,-397],[84,-389.625],[75,-397]],"c":true}],"e":[{"i":[[-4.971,0],[0,-2.5],[4.971,0],[0,2.219]],"o":[[4.971,0],[0,2.594],[-4.971,0],[0,-2.344]],"v":[[84,-398.906],[91.5,-397],[84,-395],[76.75,-397]],"c":true}]},{"t":65}]},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":7,"s":[0.33,0.33,0.28,1],"e":[0.96,0.62,0.52,1]},{"t":9}]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":92,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"mouth_teeth","tt":1,"ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[51.5,73.438,0]},"a":{"a":0,"k":[85.5,-388.562,0]},"s":{"a":1,"k":[{"i":{"x":[0.388,0.388,0.667],"y":[1,1,0.667]},"o":{"x":[0.559,0.559,0.333],"y":[0,0,0.333]},"n":["0p388_1_0p559_0","0p388_1_0p559_0","0p667_0p667_0p333_0p333"],"t":5,"s":[150,150,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p833_1_0p167_0","0p833_1_0p167_0","0p833_0p833_0p167_0p167"],"t":28,"s":[100,100,100],"e":[150,150,100]},{"t":54}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[-8.284,0],[0,-4.418],[8.284,0],[0,4.418]],"o":[[8.284,0],[0,4.418],[-8.284,0],[0,-4.418]],"v":[[88,-393],[103,-385],[88,-377],[73,-385]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.85,0.53,0.43,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":92,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":4,"ty":4,"nm":"mouth","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[50,65,0]},"a":{"a":0,"k":[84,-397,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":1,"k":[{"i":{"x":0.851,"y":1},"o":{"x":0.837,"y":0},"n":"0p851_1_0p837_0","t":7,"s":[{"i":[[-4.971,0],[0,-2.5],[4.971,0],[0,2.219]],"o":[[4.971,0],[0,2.594],[-4.971,0],[0,-2.344]],"v":[[84,-398.906],[91.5,-397],[84,-395],[76.75,-397]],"c":true}],"e":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-406.812],[93,-397],[84,-386.75],[75,-397]],"c":true}]},{"i":{"x":0.577,"y":1},"o":{"x":0.563,"y":0},"n":"0p577_1_0p563_0","t":14,"s":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-406.812],[93,-397],[84,-386.75],[75,-397]],"c":true}],"e":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-405.5],[93,-397],[84,-389],[75,-397]],"c":true}]},{"i":{"x":0.615,"y":1},"o":{"x":0.586,"y":0},"n":"0p615_1_0p586_0","t":21,"s":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-405.5],[93,-397],[84,-389],[75,-397]],"c":true}],"e":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-406],[93,-397],[84,-388],[75,-397]],"c":true}]},{"i":{"x":0.531,"y":0.201},"o":{"x":0.778,"y":0},"n":"0p531_0p201_0p778_0","t":30,"s":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-406],[93,-397],[84,-388],[75,-397]],"c":true}],"e":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-403.375],[93,-397],[84,-389.625],[75,-397]],"c":true}]},{"i":{"x":0.683,"y":1},"o":{"x":0.587,"y":1},"n":"0p683_1_0p587_1","t":46,"s":[{"i":[[-4.971,0],[0,-4.971],[4.971,0],[0,4.971]],"o":[[4.971,0],[0,4.971],[-4.971,0],[0,-4.971]],"v":[[84,-403.375],[93,-397],[84,-389.625],[75,-397]],"c":true}],"e":[{"i":[[-4.971,0],[0,-2.5],[4.971,0],[0,2.219]],"o":[[4.971,0],[0,2.594],[-4.971,0],[0,-2.344]],"v":[[84,-398.906],[91.5,-397],[84,-395],[76.75,-397]],"c":true}]},{"t":65}]},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.96,0.62,0.52,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":92,"st":0,"bm":0,"sr":1}]},{"id":"comp_45","layers":[{"ddd":0,"ind":0,"ty":4,"nm":"round_normal","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[50,50,0]},"a":{"a":0,"k":[-252,-412,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[-17.673,0],[0,-17.673],[17.673,0],[0,17.673]],"o":[[17.673,0],[0,17.673],[-17.673,0],[0,-17.673]],"v":[[-252,-444],[-220,-412],[-252,-380],[-284,-412]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[1,0.88,0.59,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":300,"st":0,"bm":0,"sr":1}]}],"layers":[{"ddd":0,"ind":0,"ty":0,"nm":"eyes_O","parent":2,"refId":"comp_43","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.304],"y":[1]},"o":{"x":[0.446],"y":[0]},"n":["0p304_1_0p446_0"],"t":0,"s":[-11],"e":[0]},{"i":{"x":[0.304],"y":[0.304]},"o":{"x":[0.167],"y":[0.167]},"n":["0p304_0p304_0p167_0p167"],"t":15,"s":[0],"e":[0]},{"i":{"x":[0.049],"y":[1]},"o":{"x":[0.438],"y":[0]},"n":["0p049_1_0p438_0"],"t":46,"s":[0],"e":[-11]},{"t":90}]},"p":{"a":1,"k":[{"i":{"x":0.304,"y":1},"o":{"x":0.446,"y":0},"n":"0p304_1_0p446_0","t":0,"s":[45,50,0],"e":[50,50,0],"to":[1.33333337306976,1.125,0],"ti":[-1.33333337306976,1.1875,0]},{"i":{"x":0.304,"y":1},"o":{"x":0.167,"y":0},"n":"0p304_1_0p167_0","t":15,"s":[50,50,0],"e":[50,50,0],"to":[1.33333337306976,-1.1875,0],"ti":[-1.33333337306976,1.1875,0]},{"i":{"x":0.049,"y":1},"o":{"x":0.438,"y":0},"n":"0p049_1_0p438_0","t":46,"s":[50,50,0],"e":[45,50,0],"to":[1.33333337306976,-1.1875,0],"ti":[-1.33333337306976,-1.125,0]},{"t":90}]},"a":{"a":0,"k":[50,50,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"w":100,"h":100,"ip":0,"op":91,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":0,"nm":"mouth_O","parent":0,"refId":"comp_44","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.366],"y":[1]},"o":{"x":[0.446],"y":[0]},"n":["0p366_1_0p446_0"],"t":0,"s":[9],"e":[0]},{"i":{"x":[0.667],"y":[0.667]},"o":{"x":[0.333],"y":[0.333]},"n":["0p667_0p667_0p333_0p333"],"t":15,"s":[0],"e":[0]},{"i":{"x":[0.049],"y":[1]},"o":{"x":[0.501],"y":[0]},"n":["0p049_1_0p501_0"],"t":46,"s":[0],"e":[9]},{"t":90}]},"p":{"a":0,"k":[50,50,0]},"a":{"a":0,"k":[50,50,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"w":100,"h":100,"ip":0,"op":91,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":0,"nm":"base_normal","refId":"comp_45","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.425],"y":[0.675]},"o":{"x":[0.515],"y":[0]},"n":["0p425_0p675_0p515_0"],"t":0,"s":[-7],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.477],"y":[0.942]},"n":["0p667_1_0p477_0p942"],"t":15,"s":[0],"e":[2]},{"i":{"x":[0.531],"y":[0.354]},"o":{"x":[0.333],"y":[0]},"n":["0p531_0p354_0p333_0"],"t":30,"s":[2],"e":[0]},{"i":{"x":[0.361],"y":[1]},"o":{"x":[0.33],"y":[0.357]},"n":["0p361_1_0p33_0p357"],"t":46,"s":[0],"e":[-7]},{"t":90}]},"p":{"a":0,"k":[50,84.5,0]},"a":{"a":0,"k":[50,84.5,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"w":100,"h":100,"ip":0,"op":91,"st":0,"bm":0,"sr":1}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/emoji_wink.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/emoji_wink.json deleted file mode 100644 index 29b39a53..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/emoji_wink.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.5.7","fr":30,"ip":0,"op":60,"w":100,"h":100,"ddd":0,"assets":[{"id":"comp_38","layers":[{"ddd":0,"ind":0,"ty":4,"nm":"round_normal","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[50,50,0]},"a":{"a":0,"k":[-252,-412,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[-17.673,0],[0,-17.673],[17.673,0],[0,17.673]],"o":[[17.673,0],[0,17.673],[-17.673,0],[0,-17.673]],"v":[[-252,-444],[-220,-412],[-252,-380],[-284,-412]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[1,0.88,0.59,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":300,"st":0,"bm":0,"sr":1}]}],"layers":[{"ddd":0,"ind":0,"ty":4,"nm":"eyes_normal","parent":2,"ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[50,45.5,0]},"a":{"a":0,"k":[-252,-416.5,0]},"s":{"a":1,"k":[{"i":{"x":[0.516,0.831,0.667],"y":[0.516,1,0.667]},"o":{"x":[0.75,0.705,0.333],"y":[0.75,0,0.333]},"n":["0p516_0p516_0p75_0p75","0p831_1_0p705_0","0p667_0p667_0p333_0p333"],"t":40,"s":[100,100,100],"e":[100,0,100]},{"i":{"x":[0.667,0.667,0.667],"y":[0.667,1,0.667]},"o":{"x":[0.333,0.333,0.333],"y":[0.333,0,0.333]},"n":["0p667_0p667_0p333_0p333","0p667_1_0p333_0","0p667_0p667_0p333_0p333"],"t":45,"s":[100,0,100],"e":[100,110,100]},{"i":{"x":[0.298,0.276,0.667],"y":[0.298,1,0.667]},"o":{"x":[0.038,0.105,0.333],"y":[0.038,0,0.333]},"n":["0p298_0p298_0p038_0p038","0p276_1_0p105_0","0p667_0p667_0p333_0p333"],"t":50,"s":[100,110,100],"e":[100,98,100]},{"i":{"x":[0.667,0.667,0.667],"y":[0.667,1,0.667]},"o":{"x":[0.333,0.333,0.333],"y":[0.333,0,0.333]},"n":["0p667_0p667_0p333_0p333","0p667_1_0p333_0","0p667_0p667_0p333_0p333"],"t":55,"s":[100,98,100],"e":[100,100,100]},{"t":60}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":1,"k":[{"i":{"x":0.313,"y":1},"o":{"x":0.467,"y":0},"n":"0p313_1_0p467_0","t":6,"s":[{"i":[[-1.933,0],[0,-1.933],[1.933,0],[0,1.933]],"o":[[1.933,0],[0,1.933],[-1.933,0],[0,-1.933]],"v":[[-237.5,-420],[-234,-416.5],[-237.5,-413],[-241,-416.5]],"c":true}],"e":[{"i":[[-1.933,0],[-0.312,-1.313],[1.933,0],[0,1.062]],"o":[[1.933,0],[0.174,0.732],[-1.933,0],[0,-1.25]],"v":[[-237.437,-418],[-231.25,-415.875],[-237.5,-416.938],[-243.188,-415.937]],"c":true}]},{"i":{"x":0.395,"y":1},"o":{"x":0.716,"y":0},"n":"0p395_1_0p716_0","t":16,"s":[{"i":[[-1.933,0],[-0.312,-1.313],[1.933,0],[0,1.062]],"o":[[1.933,0],[0.174,0.732],[-1.933,0],[0,-1.25]],"v":[[-237.437,-418],[-231.25,-415.875],[-237.5,-416.938],[-243.188,-415.937]],"c":true}],"e":[{"i":[[-1.933,0],[0,-1.933],[1.933,0],[0,1.933]],"o":[[1.933,0],[0,1.933],[-1.933,0],[0,-1.933]],"v":[[-237.5,-420],[-234,-416.5],[-237.5,-413],[-241,-416.5]],"c":true}]},{"t":29}]},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ind":1,"ty":"sh","ks":{"a":0,"k":{"i":[[-1.933,0],[0,-1.933],[1.933,0],[0,1.933]],"o":[[1.933,0],[0,1.933],[-1.933,0],[0,-1.933]],"v":[[-266.5,-420],[-263,-416.5],[-266.5,-413],[-270,-416.5]],"c":true}},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.33,0.33,0.28,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":4,"mn":"ADBE Vector Group"}],"ip":0,"op":61,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"mouth_smile","parent":2,"ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.25],"y":[1]},"o":{"x":[0.75],"y":[0]},"n":["0p25_1_0p75_0"],"t":4,"s":[0],"e":[-15]},{"i":{"x":[0.25],"y":[1]},"o":{"x":[0.75],"y":[0]},"n":["0p25_1_0p75_0"],"t":15,"s":[-15],"e":[0]},{"t":30}]},"p":{"a":0,"k":[50.862,57.489,0]},"a":{"a":0,"k":[-251.138,-404.511,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":1,"k":[{"i":{"x":0.292,"y":1},"o":{"x":0.506,"y":0},"n":"0p292_1_0p506_0","t":0,"s":[{"i":[[6.254,0],[2.91,1.715],[-0.616,0.558],[-0.707,-0.436],[-2.276,0],[-3.615,1.995],[-0.52,-0.71],[0.737,-0.384]],"o":[[-6.249,0],[-0.716,-0.422],[0.615,-0.558],[3.273,2.017],[2.662,0],[0.728,-0.402],[0.324,0.602],[-3.252,1.696]],"v":[[-252.006,-391.01],[-263.629,-394.434],[-263.522,-396.373],[-261.398,-396.454],[-252.006,-394.02],[-242.635,-396.433],[-240.261,-396.227],[-240.405,-394.414]],"c":true}],"e":[{"i":[[6.233,0],[4.195,4.639],[-0.616,0.558],[-0.558,-0.615],[-5.401,0],[-3.206,6.717],[-0.615,-0.557],[0.338,-0.759]],"o":[[-6.249,0],[-0.557,-0.616],[0.615,-0.558],[3.626,4.01],[4.636,0],[0.358,-0.75],[0.616,0.557],[-2.811,6.323]],"v":[[-252.044,-390.197],[-266.129,-396.746],[-266.022,-398.873],[-263.898,-398.767],[-252.076,-392.959],[-239.687,-401.031],[-237.564,-401.138],[-237.457,-399.012]],"c":true}]},{"i":{"x":0.564,"y":1},"o":{"x":0.571,"y":0},"n":"0p564_1_0p571_0","t":15,"s":[{"i":[[6.233,0],[4.195,4.639],[-0.616,0.558],[-0.558,-0.615],[-5.401,0],[-3.206,6.717],[-0.615,-0.557],[0.338,-0.759]],"o":[[-6.249,0],[-0.557,-0.616],[0.615,-0.558],[3.626,4.01],[4.636,0],[0.358,-0.75],[0.616,0.557],[-2.811,6.323]],"v":[[-252.044,-390.197],[-266.129,-396.746],[-266.022,-398.873],[-263.898,-398.767],[-252.076,-392.959],[-239.687,-401.031],[-237.564,-401.138],[-237.457,-399.012]],"c":true}],"e":[{"i":[[6.254,0],[2.91,1.715],[-0.616,0.558],[-0.707,-0.436],[-2.276,0],[-3.615,1.995],[-0.52,-0.71],[0.737,-0.384]],"o":[[-6.249,0],[-0.716,-0.422],[0.615,-0.558],[3.273,2.017],[2.662,0],[0.728,-0.402],[0.324,0.602],[-3.252,1.696]],"v":[[-252.006,-391.01],[-263.629,-394.434],[-263.522,-396.373],[-261.398,-396.454],[-252.006,-394.02],[-242.635,-396.433],[-240.261,-396.227],[-240.405,-394.414]],"c":true}]},{"i":{"x":0.681,"y":0.833},"o":{"x":0.546,"y":0},"n":"0p681_0p833_0p546_0","t":30,"s":[{"i":[[6.254,0],[2.91,1.715],[-0.616,0.558],[-0.707,-0.436],[-2.276,0],[-3.615,1.995],[-0.52,-0.71],[0.737,-0.384]],"o":[[-6.249,0],[-0.716,-0.422],[0.615,-0.558],[3.273,2.017],[2.662,0],[0.728,-0.402],[0.324,0.602],[-3.252,1.696]],"v":[[-252.006,-391.01],[-263.629,-394.434],[-263.522,-396.373],[-261.398,-396.454],[-252.006,-394.02],[-242.635,-396.433],[-240.261,-396.227],[-240.405,-394.414]],"c":true}],"e":[{"i":[[6.254,0],[2.91,1.715],[-0.616,0.558],[-0.734,-0.389],[-2.276,0],[-3.487,2.248],[-0.52,-0.71],[0.673,-0.488]],"o":[[-6.249,0],[-0.716,-0.422],[0.615,-0.558],[3.089,1.638],[2.662,0],[0.699,-0.451],[0.324,0.602],[-2.905,2.105]],"v":[[-252.006,-391.01],[-264.507,-394.555],[-264.401,-396.494],[-262.276,-396.576],[-252.006,-394.02],[-242.076,-396.998],[-239.702,-396.793],[-239.845,-394.98]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.497,"y":0.261},"n":"0p667_1_0p497_0p261","t":40,"s":[{"i":[[6.254,0],[2.91,1.715],[-0.616,0.558],[-0.734,-0.389],[-2.276,0],[-3.487,2.248],[-0.52,-0.71],[0.673,-0.488]],"o":[[-6.249,0],[-0.716,-0.422],[0.615,-0.558],[3.089,1.638],[2.662,0],[0.699,-0.451],[0.324,0.602],[-2.905,2.105]],"v":[[-252.006,-391.01],[-264.507,-394.555],[-264.401,-396.494],[-262.276,-396.576],[-252.006,-394.02],[-242.076,-396.998],[-239.702,-396.793],[-239.845,-394.98]],"c":true}],"e":[{"i":[[6.254,0],[2.91,1.715],[-0.616,0.558],[-0.707,-0.436],[-2.276,0],[-3.615,1.995],[-0.52,-0.71],[0.737,-0.384]],"o":[[-6.249,0],[-0.716,-0.422],[0.615,-0.558],[3.273,2.017],[2.662,0],[0.728,-0.402],[0.324,0.602],[-3.252,1.696]],"v":[[-252.006,-391.01],[-263.629,-394.434],[-263.522,-396.373],[-261.398,-396.454],[-252.006,-394.02],[-242.635,-396.433],[-240.261,-396.227],[-240.405,-394.414]],"c":true}]},{"t":60}]},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.33,0.33,0.28,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":61,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":0,"nm":"base_normal","refId":"comp_38","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.273],"y":[1]},"o":{"x":[0.464],"y":[0]},"n":["0p273_1_0p464_0"],"t":4,"s":[0],"e":[13]},{"i":{"x":[0.532],"y":[1]},"o":{"x":[0.578],"y":[0]},"n":["0p532_1_0p578_0"],"t":19,"s":[13],"e":[0]},{"t":40}]},"p":{"a":0,"k":[50,50,0]},"a":{"a":0,"k":[50,50,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"w":100,"h":100,"ip":0,"op":61,"st":0,"bm":0,"sr":1}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/file_transfer.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/file_transfer.json deleted file mode 100644 index ef823ffb..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/file_transfer.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.0.6","fr":25,"ip":0,"op":50,"w":503,"h":495,"nm":"file transfer","ddd":0,"assets":[{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Layer 4 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[90.033,347.439,0],"ix":2},"a":{"a":0,"k":[64.5,97.25,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-17.824,0],[0,0]],"o":[[0,0],[0,17.824],[0,0],[0,0]],"v":[[-47,-79.75],[-47,47.477],[-14.727,79.75],[47,79.75]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.122000002394,0.187999994615,0.277999997606,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[64.5,97.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[100]},{"t":10}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":10,"s":[0],"e":[100]},{"t":20}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":36,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Layer 7 Outlines","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[100],"e":[0]},{"t":23}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":5,"s":[90],"e":[72]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":6,"s":[72],"e":[38]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":7,"s":[38],"e":[0]},{"t":8}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[42.545,272.726,0],"e":[42.545,283.601,0],"to":[0,1.8125,0],"ti":[0,-5.89583349227905,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":1,"s":[42.545,283.601,0],"e":[42.545,308.101,0],"to":[0,5.89583349227905,0],"ti":[0,-7.75,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":2,"s":[42.545,308.101,0],"e":[42.545,330.101,0],"to":[0,7.75,0],"ti":[0,-7.47916650772095,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":3,"s":[42.545,330.101,0],"e":[42.545,352.976,0],"to":[0,7.47916650772095,0],"ti":[0,-8.41666698455811,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":4,"s":[42.545,352.976,0],"e":[42.545,380.601,0],"to":[0,8.41666698455811,0],"ti":[-0.33333334326744,-8.5625,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":5,"s":[42.545,380.601,0],"e":[44.545,404.351,0],"to":[0.33333334326744,8.5625,0],"ti":[-2.875,-6.91666650772095,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":6,"s":[44.545,404.351,0],"e":[59.795,422.101,0],"to":[2.875,6.91666650772095,0],"ti":[-6.0625,-3.8125,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":7,"s":[59.795,422.101,0],"e":[80.92,427.226,0],"to":[6.0625,3.8125,0],"ti":[-7.52083349227905,-0.85416668653488,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":8,"s":[80.92,427.226,0],"e":[104.92,427.226,0],"to":[7.52083349227905,0.85416668653488,0],"ti":[-8.25,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":9,"s":[104.92,427.226,0],"e":[130.42,427.226,0],"to":[8.25,0,0],"ti":[-4.25,0,0]},{"t":10}],"ix":2},"a":{"a":0,"k":[28.637,39.774,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-11.137,-22.274],[11.137,0],[-11.137,22.274]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.122000002394,0.187999994615,0.277999997606,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[28.637,39.774],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":1,"op":36,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Pre-comp 1","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[251.5,247.5,0],"ix":2},"a":{"a":0,"k":[251.5,247.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":503,"h":495,"ip":0,"op":100,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"Pre-comp 1","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[251.5,247.5,0],"ix":2},"a":{"a":0,"k":[251.5,247.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":503,"h":495,"ip":0,"op":100,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Layer 3 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":20,"s":[152.057,121.25,0],"e":[350.557,373.25,0],"to":[2.08333325386047,63,0],"ti":[-199.744842529297,-2.53560209274292,0]},{"t":35}],"ix":2},"a":{"a":0,"k":[152.25,121.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-3.7],[0,0],[-3.7,0],[0,0],[0,3.7],[0,0],[3.7,0],[0,0],[0,0]],"o":[[-3.7,0],[0,0],[0,3.7],[0,0],[3.7,0],[0,0],[0,-3.7],[0,0],[0,0],[0,0]],"v":[[-138.3,-114.25],[-145,-107.55],[-145,107.65],[-138.3,114.35],[138.3,114.35],[145,107.65],[145,-66.65],[138.3,-73.35],[-12.2,-73.35],[-45.5,-114.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[7.5,0],[0,0],[0,7.6],[0,0],[-7.6,0],[0,0],[0,0],[0,0],[0,-7.6],[0,0]],"o":[[0,0],[-7.5,0],[0,0],[0,-7.6],[0,0],[0,0],[0,0],[7.5,0],[0,0],[0,7.5]],"v":[[138.3,121.25],[-138.3,121.25],[-152,107.55],[-152,-107.55],[-138.3,-121.25],[-42.1,-121.25],[-8.8,-80.25],[138.3,-80.25],[152,-66.55],[152,107.65]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.122000002394,0.187999994615,0.277999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[152.25,121.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.412,0],[0,0],[0,7.412],[0,0],[-7.412,0],[0,0],[0,0],[0,0],[0,-7.412],[0,0]],"o":[[0,0],[-7.315,0],[0,0],[0,-7.315],[0,0],[0,0],[0,0],[7.314,0],[0,0],[0,7.315]],"v":[[134.878,118.25],[-134.878,118.25],[-148.239,104.889],[-148.239,-104.889],[-134.878,-118.25],[-41.059,-118.25],[-8.582,-78.265],[134.878,-78.265],[148.239,-64.903],[148.239,104.986]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[152.193,121.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":100,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Layer 2 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":20,"s":[350.557,373.25,0],"e":[152.057,121.25,0],"to":[9.91666698455811,-261,0],"ti":[0,0,0]},{"t":35}],"ix":2},"a":{"a":0,"k":[152.25,121.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-3.7],[0,0],[-3.7,0],[0,0],[0,3.7],[0,0],[3.7,0],[0,0],[0,0],[0,0]],"o":[[-3.7,0],[0,0],[0,3.7],[0,0],[3.7,0],[0,0],[0,-3.7],[0,0],[0,0],[0,0],[0,0]],"v":[[-138.3,-114.25],[-145,-107.55],[-145,107.65],[-138.3,114.35],[138.3,114.35],[145,107.65],[145,-66.65],[138.3,-73.35],[-12.1,-73.35],[-45.401,-114.35],[-138.3,-114.35]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[7.6,0],[0,0],[0,7.6],[0,0],[-7.6,0],[0,0],[0,0],[0,0],[0,-7.6],[0,0]],"o":[[0,0],[-7.5,0],[0,0],[0,-7.5],[0,0],[0,0],[0,0],[7.5,0],[0,0],[0,7.5]],"v":[[138.3,121.25],[-138.3,121.25],[-152,107.55],[-152,-107.55],[-138.3,-121.25],[-42.1,-121.25],[-8.8,-80.25],[138.3,-80.25],[152,-66.55],[152,107.65]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.122000002394,0.187999994615,0.277999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[152.25,121.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.35,0],[0,0],[0,7.35],[0,0],[-7.349,0],[0,0],[0,0],[0,0],[0,-7.35],[0,0]],"o":[[0,0],[-7.253,0],[0,0],[0,-7.253],[0,0],[0,0],[0,0],[7.253,0],[0,0],[0,7.253]],"v":[[133.738,117.25],[-133.738,117.25],[-146.985,104.002],[-146.985,-104.002],[-133.738,-117.25],[-40.71,-117.25],[-8.51,-77.603],[133.738,-77.603],[146.986,-64.354],[146.986,104.099]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[152.25,121.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":100,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/fingerprint_success.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/fingerprint_success.json deleted file mode 100644 index e0365506..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/fingerprint_success.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.16","fr":60,"ip":0,"op":154,"w":800,"h":600,"nm":"Fingerprint Added","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"check-mark","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":114.999,"s":[0],"e":[100]},{"t":125.999075247122}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[478,200,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":112.999,"s":[40.225,40.225,100],"e":[90.225,90.225,100]},{"t":128.999075247122}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.58,0.581],[0,0],[-0.586,0.586],[0,0],[-0.586,-0.586],[0,0],[0,0],[-0.578,-0.593],[0,0],[0.593,-0.578],[0,0]],"o":[[0,0],[-0.586,-0.586],[0,0],[0.586,-0.586],[0,0],[0,0],[0.593,-0.578],[0,0],[0.578,0.593],[0,0],[-0.588,0.573]],"v":[[-6.426,14.748],[-20.11,1.063],[-20.11,-1.059],[-16.575,-4.594],[-14.454,-4.594],[-5.306,4.553],[14.506,-14.756],[16.627,-14.729],[20.117,-11.148],[20.09,-9.027],[-4.318,14.761]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":77,"op":757.023023023023,"st":-143.877877877878,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"circle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[478,200,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":91,"s":[118,118,100],"e":[83.4,83.4,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":104,"s":[83.4,83.4,100],"e":[100,100,100]},{"t":114}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":506.533,"s":[{"i":[[27.5,0],[0,0],[0,27.5],[0,0],[-27.5,0],[0,0],[0,-27.5],[0,0]],"o":[[0,0],[-27.5,0],[0,0],[0,-27.5],[0,0],[27.5,0],[0,0],[0,27.5]],"v":[[0,50],[0,50],[-50,0],[-50,0],[0,-50],[0,-50],[50,0],[50,0]],"c":true}],"e":[{"i":[[27.5,0],[0,0],[0,27.5],[0,0],[-27.5,0],[0,0],[0,-27.5],[0,0]],"o":[[0,0],[-27.5,0],[0,0],[0,-27.5],[0,0],[27.5,0],[0,0],[0,27.5]],"v":[[77.5,50],[-77.5,50],[-127.5,0],[-127.5,0],[-77.5,-50],[77.5,-50],[127.5,0],[127.5,0]],"c":true}]},{"t":526.552734375}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.227450980392,0.717647058824,0.23137254902,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":74,"op":574.600600600601,"st":-26,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"bg","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":460.461,"s":[35],"e":[0]},{"t":490.490234375}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400.5,299.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-11.083,111.167],[-18.417,129.833]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 19","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-31.333],[0,0]],"o":[[0,0],[0,26.833],[0,0]],"v":[[-2.917,0.375],[1.25,47.375],[-4.75,89.625]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.5,-1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 18","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[16.5,-45.333]],"o":[[0,0],[0,0]],"v":[[21.083,65.167],[4.75,129.833]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 17","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,34.5],[0.343,7.079],[-15.143,3.994],[-2.486,-6.934],[0,0]],"o":[[0,0],[0,-34.5],[-0.312,-6.447],[15.167,-4],[4.909,13.694],[0,0]],"v":[[-40.371,123.25],[-20.538,49.917],[-24.38,1.838],[-7.871,-22.25],[18.462,-7.583],[22.962,42.625]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 16","np":3,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-11.333,0],[-9.167,-11.792],[0,-58.958],[0,0]],"o":[[0,0],[10.833,0],[7.836,10.081],[0,35.958],[0,0]],"v":[[-18.417,-41.083],[-2.583,-43.75],[30.25,-27.917],[44.417,52.625],[30.25,123.75]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-0.5,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 15","np":3,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-2.218,33.169],[0,12.439],[0,0]],"o":[[0,0],[1.75,-26.167],[0,-22.363],[0,0]],"v":[[-59.375,115.875],[-41.875,56.792],[-45.744,2.238],[-35.625,-28.375]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 14","np":3,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-51.333],[0,0]],"o":[[0,0],[0,41.022],[0,0]],"v":[[57.417,-21.5],[65.083,46.5],[55.917,114.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 13","np":3,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.5,13],[0,15.5],[-25.188,12.89],[0,0]],"o":[[0,0],[-0.5,-13],[0,-15.5],[49.667,-25.417],[0,0]],"v":[[-64.25,56.042],[-63.5,32.625],[-67.333,-1.875],[-34.167,-57.125],[48.333,-40.708]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 12","np":3,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-2.5,11.25]],"o":[[0,0],[0,0]],"v":[[-23,35.875],[-12,9.125]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-56,68.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 11","np":3,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[25.588,51.877],[0.253,0.286]],"o":[[-0.862,-0.039],[-12.167,-24.667],[0,0]],"v":[[83.122,95.5],[73.789,-41.833],[39.122,-75.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 10","np":3,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[37.69,-39.496],[0.227,-12.901],[0,-12.5],[0,0]],"o":[[0,0],[-22.167,23.229],[-0.229,12.998],[0,29.875],[0,0]],"v":[[18.047,-83.903],[-66.12,-59.632],[-88.229,0.347],[-84.703,39.347],[-95.703,89.597]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 9","np":3,"cix":2,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[1.346,-17.25]],"o":[[0,0],[0,0]],"v":[[108.577,39.125],[107.577,65.875]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 8","np":3,"cix":2,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 7","np":2,"cix":2,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-52.475,-34.419],[0,0],[0,0]],"o":[[0,0],[46.5,30.5],[0,0],[0,0]],"v":[[-44.5,-100.374],[58.25,-89.29],[106.75,6.46],[107.5,16.21]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 6","np":3,"cix":2,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[2,18],[0,15.375],[-45.25,31.75]],"o":[[0,0],[-2,-18],[0,-15.375],[0,0]],"v":[[-111.125,71.625],[-106.125,41.625],[-110.125,3],[-64.875,-88.125]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 5","np":3,"cix":2,"ix":15,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[35.5,34.75],[0,0]],"o":[[0,0],[-34.746,-34.012],[0,0]],"v":[[126.531,-3.938],[89.281,-91.854],[17.531,-127.937]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 4","np":3,"cix":2,"ix":16,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 3","np":2,"cix":2,"ix":17,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[31.5,-19.5],[0,0]],"o":[[0,0],[-31.5,19.5],[0,0]],"v":[[-4.75,-129.937],[-71,-110.687],[-118.75,-56.937]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":18,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-22.25],[0,0]],"o":[[0,0],[0,22.25],[0,0]],"v":[[-128.25,-36.875],[-133.5,-0.125],[-126.5,40.375]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.509803921569,0.427450980392,0.827450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":19,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[100]},{"t":34}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":20,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Scan","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":338.338,"s":[100],"e":[0]},{"t":368.369140625}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400.5,299.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-11.083,111.167],[-18.417,129.833]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 19","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-31.333],[0,0]],"o":[[0,0],[0,26.833],[0,0]],"v":[[-2.917,0.375],[1.25,47.375],[-4.75,89.625]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.5,-1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 18","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[16.5,-45.333]],"o":[[0,0],[0,0]],"v":[[21.083,65.167],[4.75,129.833]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 17","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,34.5],[0.343,7.079],[-15.143,3.994],[-2.486,-6.934],[0,0]],"o":[[0,0],[0,-34.5],[-0.312,-6.447],[15.167,-4],[4.909,13.694],[0,0]],"v":[[-40.371,123.25],[-20.538,49.917],[-24.38,1.838],[-7.871,-22.25],[18.462,-7.583],[22.962,42.625]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 16","np":3,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-11.333,0],[-9.167,-11.792],[0,-58.958],[0,0]],"o":[[0,0],[10.833,0],[7.836,10.081],[0,35.958],[0,0]],"v":[[-18.417,-41.083],[-2.583,-43.75],[30.25,-27.917],[44.417,52.625],[30.25,123.75]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-0.5,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 15","np":3,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-2.218,33.169],[0,12.439],[0,0]],"o":[[0,0],[1.75,-26.167],[0,-22.363],[0,0]],"v":[[-59.375,115.875],[-41.875,56.792],[-45.744,2.238],[-35.625,-28.375]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 14","np":3,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-51.333],[0,0]],"o":[[0,0],[0,41.022],[0,0]],"v":[[57.417,-21.5],[65.083,46.5],[55.917,114.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 13","np":3,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.5,13],[0,15.5],[-25.188,12.89],[0,0]],"o":[[0,0],[-0.5,-13],[0,-15.5],[49.667,-25.417],[0,0]],"v":[[-64.25,56.042],[-63.5,32.625],[-67.333,-1.875],[-34.167,-57.125],[48.333,-40.708]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 12","np":3,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-2.5,11.25]],"o":[[0,0],[0,0]],"v":[[-23,35.875],[-12,9.125]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-56,68.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 11","np":3,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[25.588,51.877],[0.253,0.286]],"o":[[-0.862,-0.039],[-12.167,-24.667],[0,0]],"v":[[83.122,95.5],[73.789,-41.833],[39.122,-75.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 10","np":3,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[37.69,-39.496],[0.227,-12.901],[0,-12.5],[0,0]],"o":[[0,0],[-22.167,23.229],[-0.229,12.998],[0,29.875],[0,0]],"v":[[18.047,-83.903],[-66.12,-59.632],[-88.229,0.347],[-84.703,39.347],[-95.703,89.597]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 9","np":3,"cix":2,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[1.346,-17.25]],"o":[[0,0],[0,0]],"v":[[108.577,39.125],[107.577,65.875]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 8","np":3,"cix":2,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 7","np":2,"cix":2,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-52.475,-34.419],[0,0],[0,0]],"o":[[0,0],[46.5,30.5],[0,0],[0,0]],"v":[[-44.5,-100.374],[58.25,-89.29],[106.75,6.46],[107.5,16.21]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 6","np":3,"cix":2,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[2,18],[0,15.375],[-45.25,31.75]],"o":[[0,0],[-2,-18],[0,-15.375],[0,0]],"v":[[-111.125,71.625],[-106.125,41.625],[-110.125,3],[-64.875,-88.125]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 5","np":3,"cix":2,"ix":15,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[35.5,34.75],[0,0]],"o":[[0,0],[-34.746,-34.012],[0,0]],"v":[[126.531,-3.938],[89.281,-91.854],[17.531,-127.937]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 4","np":3,"cix":2,"ix":16,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 3","np":2,"cix":2,"ix":17,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[31.5,-19.5],[0,0]],"o":[[0,0],[-31.5,19.5],[0,0]],"v":[[-4.75,-129.937],[-71,-110.687],[-118.75,-56.937]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":18,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-22.25],[0,0]],"o":[[0,0],[0,22.25],[0,0]],"v":[[-128.25,-36.875],[-133.5,-0.125],[-126.5,40.375]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117647059,0.23137254902,0.658823529412,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":19,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":38,"s":[0],"e":[100]},{"t":96}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":20,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/funky_chicken.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/funky_chicken.json deleted file mode 100644 index 9870f716..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/funky_chicken.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.14","fr":30,"ip":0,"op":32,"w":512,"h":512,"nm":"cipa 3","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"cipa","refId":"comp_1","sr":0.8,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[442,468,0],"ix":2},"a":{"a":0,"k":[450,450,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":900,"h":900,"ip":0,"op":32,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Слой-фигура 1","sr":1,"ks":{"o":{"a":0,"k":36,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[442,440,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":0,"s":[103.311,100,100],"e":[85,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":8,"s":[85,100,100],"e":[103.311,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":16,"s":[103.311,100,100],"e":[85,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":24,"s":[85,100,100],"e":[103.311,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":32,"s":[103.311,100,100],"e":[85,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":40,"s":[85,100,100],"e":[103.311,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":49,"s":[103.311,100,100],"e":[85,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":57,"s":[85,100,100],"e":[103.311,100,100]},{"t":65}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[327.625,10.68],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Контур прямоугольника 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.582368259804,0.582368259804,0.582368259804,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[42.812,290.66],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,132.703],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Прямоугольник 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":32,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Кривые ochki","parent":4,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[297.64,420.945,0],"ix":2},"a":{"a":0,"k":[297.64,420.945,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[0,0],[62.833,-11.624],[0,0],[17.986,-6.775],[0.333,-10.334],[3,-6],[2.333,7.333],[-2.726,8.808],[-4.655,2.007],[0,0],[-25.667,5.333],[0,0]],"o":[[0,0],[-70.215,12.99],[0.12,-1.267],[-12.802,4.822],[-0.333,10.333],[-3,6],[-2.333,-7.333],[2.167,-7],[30.525,-13.156],[0,0],[25.666,-5.333],[0,0]],"v":[[98.247,-45.334],[59.58,56.999],[-31.331,-27.111],[-83.333,-10.978],[-101.333,5.021],[-101.666,62.354],[-124.333,70.354],[-115.333,-4.812],[-102.501,-17.593],[-31.331,-50.778],[46.914,-70.334],[90.247,-78.376]],"c":false}],"e":[{"i":[[0,0],[59.667,-10],[0,0],[17.986,-6.775],[0.333,-10.334],[3,-6],[2.333,7.333],[-2.726,8.808],[-4.655,2.007],[0,0],[-25.667,5.333],[0,0]],"o":[[0,0],[-70.424,11.803],[0.12,-1.267],[-12.802,4.822],[-0.333,10.333],[-3,6],[-2.333,-7.333],[2.167,-7],[30.525,-13.156],[0,0],[25.666,-5.333],[0,0]],"v":[[134.139,-50.603],[88.999,52.688],[5.999,-32.978],[-100.333,-6.978],[-118.333,9.021],[-118.666,66.354],[-141.333,74.354],[-132.333,-0.812],[-119.501,-13.594],[5.999,-56.646],[76.334,-74.646],[124.143,-83.369]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[59.667,-10],[0,0],[17.986,-6.775],[0.333,-10.334],[3,-6],[2.333,7.333],[-2.726,8.808],[-4.655,2.007],[0,0],[-25.667,5.333],[0,0]],"o":[[0,0],[-70.424,11.803],[0.12,-1.267],[-12.802,4.822],[-0.333,10.333],[-3,6],[-2.333,-7.333],[2.167,-7],[30.525,-13.156],[0,0],[25.666,-5.333],[0,0]],"v":[[134.139,-50.603],[88.999,52.688],[5.999,-32.978],[-100.333,-6.978],[-118.333,9.021],[-118.666,66.354],[-141.333,74.354],[-132.333,-0.812],[-119.501,-13.594],[5.999,-56.646],[76.334,-74.646],[124.143,-83.369]],"c":false}],"e":[{"i":[[0,0],[62.833,-11.624],[0,0],[17.986,-6.775],[0.333,-10.334],[3,-6],[2.333,7.333],[-2.726,8.808],[-4.655,2.007],[0,0],[-25.667,5.333],[0,0]],"o":[[0,0],[-70.215,12.99],[0.12,-1.267],[-12.802,4.822],[-0.333,10.333],[-3,6],[-2.333,-7.333],[2.167,-7],[30.525,-13.156],[0,0],[25.666,-5.333],[0,0]],"v":[[98.247,-45.334],[59.58,56.999],[-31.331,-27.111],[-83.333,-10.978],[-101.333,5.021],[-101.666,62.354],[-124.333,70.354],[-115.333,-4.812],[-102.501,-17.594],[-31.331,-50.778],[46.914,-70.334],[90.247,-78.376]],"c":false}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[260.333,426.312],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[3.34,20.121],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-40.586,-15.689],[-6.773,-7.368],[-35.44,22.897]],"c":true}],"e":[{"i":[[4.375,20.5],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-4.638,-21.232],[27.639,-11.958],[-1.901,17.366]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[4.375,20.5],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-4.638,-21.232],[27.639,-11.958],[-1.901,17.366]],"c":true}],"e":[{"i":[[3.34,20.121],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-40.586,-15.689],[-6.773,-7.368],[-35.44,22.897]],"c":true}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[399.167,397],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-37.857,7.499],[-8.502,7.569],[-38.857,-1.626]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.965,2.23],[25.91,2.98],[-2.965,-6.895]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.965,2.23],[25.91,2.98],[-2.965,-6.895]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-37.857,7.499],[-8.502,7.569],[-38.857,-1.626]],"c":true}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.783999992819,0.039000002543,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[398.812,383.062],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 3","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[4.125,20.75],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-40.586,-15.689],[-6.773,-7.368],[-36.586,22.311]],"c":true}],"e":[{"i":[[4.125,20.75],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-4.694,-20.958],[27.639,-11.958],[-0.694,17.042]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[4.125,20.75],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-4.694,-20.958],[27.639,-11.958],[-0.694,17.042]],"c":true}],"e":[{"i":[[4.125,20.75],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-40.586,-15.689],[-6.773,-7.368],[-36.586,22.311]],"c":true}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.579999976065,0.039000002543,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[399.167,397],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 4","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[0,0],[-78.198,17.874],[7.634,11.583],[26,-3.667],[0,0]],"o":[[0,0],[54.631,-12.487],[-9.667,-14.667],[-25.958,3.661],[0,0]],"v":[[-84.836,-16.046],[-6.919,60.121],[27.414,-54.546],[-38.744,-60.302],[-96.586,-50.296]],"c":false}],"e":[{"i":[[0,0],[-69.656,15.715],[7.634,11.583],[26,-3.667],[0,0]],"o":[[0,0],[54.666,-12.334],[-9.667,-14.667],[-25.958,3.661],[0,0]],"v":[[-48.944,-21.315],[22.501,55.81],[56.834,-58.858],[-5.833,-64.858],[-62.69,-55.289]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[-69.656,15.715],[7.634,11.583],[26,-3.667],[0,0]],"o":[[0,0],[54.666,-12.334],[-9.667,-14.667],[-25.958,3.661],[0,0]],"v":[[-48.944,-21.315],[22.501,55.81],[56.834,-58.858],[-5.833,-64.858],[-62.69,-55.289]],"c":false}],"e":[{"i":[[0,0],[-78.198,17.874],[7.634,11.583],[26,-3.667],[0,0]],"o":[[0,0],[54.631,-12.487],[-9.667,-14.667],[-25.958,3.661],[0,0]],"v":[[-84.836,-16.046],[-6.919,60.121],[27.414,-54.546],[-38.744,-60.302],[-96.586,-50.296]],"c":false}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[444.166,398.858],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 5","np":2,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[0,0],[0,0],[-47.667,7.666],[0,0],[0,0],[60.667,-11],[0,0],[0,0]],"o":[[0,0],[0,0],[47.667,-7.667],[0,0],[0,0],[-60.666,11],[0,0],[0,0]],"v":[[-159.381,42.754],[-82.245,6.333],[43.747,-23.188],[151.414,-38.522],[140.08,-40.522],[41.08,-27.522],[-85.934,3.188],[-155.787,36.774]],"c":true}],"e":[{"i":[[0,0],[0,0],[-47.667,7.666],[0,0],[0,0],[60.667,-11],[0,0],[0,0]],"o":[[0,0],[0,0],[47.667,-7.667],[0,0],[0,0],[-60.666,11],[0,0],[0,0]],"v":[[-175.833,43.833],[-44.833,-0.167],[77.643,-28.181],[180.833,-42.833],[169.5,-44.833],[74.976,-32.515],[-48.833,-4.167],[-172.501,39.501]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[0,0],[-47.667,7.666],[0,0],[0,0],[60.667,-11],[0,0],[0,0]],"o":[[0,0],[0,0],[47.667,-7.667],[0,0],[0,0],[-60.666,11],[0,0],[0,0]],"v":[[-175.833,43.833],[-44.833,-0.167],[77.643,-28.181],[180.833,-42.833],[169.5,-44.833],[74.976,-32.515],[-48.833,-4.167],[-172.501,39.501]],"c":true}],"e":[{"i":[[0,0],[0,0],[-47.667,7.666],[0,0],[0,0],[60.667,-11],[0,0],[0,0]],"o":[[0,0],[0,0],[47.667,-7.667],[0,0],[0,0],[-60.666,11],[0,0],[0,0]],"v":[[-159.381,42.754],[-82.245,6.333],[43.747,-23.188],[151.414,-38.522],[140.08,-40.522],[41.08,-27.522],[-85.934,3.188],[-155.787,36.774]],"c":true}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039000002543,0.732999973671,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[307.833,374.833],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 6","np":2,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[0,0],[0,0],[0,0],[2,-5],[-2.084,-0.811],[-1.333,2.333],[0,0],[-3,1.666]],"o":[[0,0],[0,0],[0,0],[-2,5],[6,2.333],[1.333,-2.333],[0,0],[3,-1.667]],"v":[[39.712,-40.466],[37.379,-61.133],[-33.958,-29.666],[-45.625,-16.666],[-52.958,59.667],[-31.958,49.667],[-31.291,-14.666],[-24.625,-20.666]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[2,-5],[-2.084,-0.811],[-1.333,2.333],[0,0],[-3,1.666]],"o":[[0,0],[0,0],[0,0],[-2,5],[6,2.333],[1.333,-2.333],[0,0],[3,-1.667]],"v":[[77.042,-46.333],[74.709,-67],[-50.958,-25.666],[-62.625,-12.666],[-69.958,63.667],[-48.958,53.667],[-48.291,-10.666],[-41.625,-16.666]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[0,0],[0,0],[2,-5],[-2.084,-0.811],[-1.333,2.333],[0,0],[-3,1.666]],"o":[[0,0],[0,0],[0,0],[-2,5],[6,2.333],[1.333,-2.333],[0,0],[3,-1.667]],"v":[[77.042,-46.333],[74.709,-67],[-50.958,-25.666],[-62.625,-12.666],[-69.958,63.667],[-48.958,53.667],[-48.291,-10.666],[-41.625,-16.666]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[2,-5],[-2.084,-0.811],[-1.333,2.333],[0,0],[-3,1.666]],"o":[[0,0],[0,0],[0,0],[-2,5],[6,2.333],[1.333,-2.333],[0,0],[3,-1.667]],"v":[[39.712,-40.466],[37.379,-61.133],[-33.958,-29.666],[-45.625,-16.666],[-52.958,59.667],[-31.958,49.667],[-31.291,-14.666],[-24.625,-20.666]],"c":true}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.109999997008,0.313999998803,0.596000043084,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[190.292,438.667],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 7","np":2,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[-17.553,4.111],[-4.534,0],[-3,-8.333],[48.215,-10.557],[1,8.333],[-6.167,2.5]],"o":[[18.5,-4.333],[4.666,0],[3,8.333],[-51,11.167],[-1,-8.334],[6.969,-2.826]],"v":[[-49.105,-45.549],[-1.36,-53.772],[11.473,-44.105],[-14.527,49.228],[-89.438,-19.882],[-80.438,-36.382]],"c":true}],"e":[{"i":[[-17.553,4.111],[-4.534,0],[-3,-8.333],[48.215,-10.557],[1,8.333],[-6.167,2.5]],"o":[[18.5,-4.333],[4.666,0],[3,8.333],[-51,11.167],[-1,-8.334],[6.969,-2.826]],"v":[[-11.774,-51.417],[32.536,-58.765],[45.369,-49.098],[14.893,44.917],[-52.107,-25.749],[-43.107,-42.249]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[-17.553,4.111],[-4.534,0],[-3,-8.333],[48.215,-10.557],[1,8.333],[-6.167,2.5]],"o":[[18.5,-4.333],[4.666,0],[3,8.333],[-51,11.167],[-1,-8.334],[6.969,-2.826]],"v":[[-11.774,-51.417],[32.536,-58.765],[45.369,-49.098],[14.893,44.917],[-52.107,-25.749],[-43.107,-42.249]],"c":true}],"e":[{"i":[[-17.553,4.111],[-4.534,0],[-3,-8.333],[48.215,-10.557],[1,8.333],[-6.167,2.5]],"o":[[18.5,-4.333],[4.666,0],[3,8.333],[-51,11.167],[-1,-8.334],[6.969,-2.826]],"v":[[-49.104,-45.549],[-1.36,-53.772],[11.473,-44.105],[-14.527,49.228],[-89.438,-19.882],[-80.438,-36.382]],"c":true}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.411999990426,0.063000002094,0.325,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[333.107,419.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 8","np":2,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[0,0],[-6.5,-8.5],[-7.25,2.25],[-1.75,-1],[2.5,-10.25],[0,0],[-8,0.75],[0,0],[1.25,14.75],[10.5,-1],[0.5,2],[-2.093,12.324],[0,0]],"o":[[0,0],[5.075,6.637],[7.25,-2.25],[1.75,1],[-2.5,10.25],[0,0],[8,-0.75],[0,0],[-0.587,-6.926],[-4.41,0.42],[-0.5,-2],[2.25,-13.25],[0,0]],"v":[[-51.58,-38.633],[-56.08,10.617],[-39.58,15.617],[-29.83,12.617],[-31.08,38.367],[-35.827,50.306],[-14.419,53.061],[-2.169,50.811],[4.581,3.561],[-9.919,-8.689],[-24.919,-6.939],[-22.669,-31.939],[-20.419,-47.189]],"c":true}],"e":[{"i":[[0,0],[-6.5,-8.5],[-7.25,2.25],[-1.75,-1],[2.5,-10.25],[0,0],[-8,0.75],[0,0],[1.25,14.75],[10.5,-1],[0.5,2],[-2.093,12.324],[0,0]],"o":[[0,0],[5.075,6.637],[7.25,-2.25],[1.75,1],[-2.5,10.25],[0,0],[8,-0.75],[0,0],[-0.587,-6.926],[-4.41,0.42],[-0.5,-2],[2.25,-13.25],[0,0]],"v":[[-14.25,-44.5],[-18.75,4.75],[-2.25,9.75],[7.5,6.75],[6.25,32.5],[0.75,48],[15,48.75],[27.25,46.5],[34,-0.75],[19.5,-13],[4.5,-11.25],[6.75,-36.25],[9,-51.5]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[-6.5,-8.5],[-7.25,2.25],[-1.75,-1],[2.5,-10.25],[0,0],[-8,0.75],[0,0],[1.25,14.75],[10.5,-1],[0.5,2],[-2.093,12.324],[0,0]],"o":[[0,0],[5.075,6.637],[7.25,-2.25],[1.75,1],[-2.5,10.25],[0,0],[8,-0.75],[0,0],[-0.587,-6.926],[-4.41,0.42],[-0.5,-2],[2.25,-13.25],[0,0]],"v":[[-14.25,-44.5],[-18.75,4.75],[-2.25,9.75],[7.5,6.75],[6.25,32.5],[0.75,48],[15,48.75],[27.25,46.5],[34,-0.75],[19.5,-13],[4.5,-11.25],[6.75,-36.25],[9,-51.5]],"c":true}],"e":[{"i":[[0,0],[-6.5,-8.5],[-7.25,2.25],[-1.75,-1],[2.5,-10.25],[0,0],[-8,0.75],[0,0],[1.25,14.75],[10.5,-1],[0.5,2],[-2.093,12.324],[0,0]],"o":[[0,0],[5.075,6.637],[7.25,-2.25],[1.75,1],[-2.5,10.25],[0,0],[8,-0.75],[0,0],[-0.587,-6.926],[-4.41,0.42],[-0.5,-2],[2.25,-13.25],[0,0]],"v":[[-51.58,-38.633],[-56.08,10.617],[-39.58,15.617],[-29.83,12.617],[-31.08,38.367],[-35.827,50.306],[-14.419,53.061],[-2.169,50.811],[4.581,3.561],[-9.919,-8.689],[-24.919,-6.939],[-22.669,-31.939],[-20.419,-47.189]],"c":true}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.948999980852,0.477999997606,0.830999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[325.5,416.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 9","np":2,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[-17.553,4.111],[-4.534,0],[-3,-8.333],[48.215,-10.557],[1,8.333],[-6.167,2.5]],"o":[[18.5,-4.333],[4.666,0],[3,8.333],[-51,11.167],[-1,-8.334],[6.969,-2.826]],"v":[[-49.105,-45.549],[-1.36,-53.772],[11.473,-44.105],[-14.527,49.228],[-89.438,-19.882],[-80.438,-36.382]],"c":true}],"e":[{"i":[[-17.553,4.111],[-4.534,0],[-3,-8.333],[48.215,-10.557],[1,8.333],[-6.167,2.5]],"o":[[18.5,-4.333],[4.666,0],[3,8.333],[-51,11.167],[-1,-8.334],[6.969,-2.826]],"v":[[-11.774,-51.417],[32.536,-58.765],[45.369,-49.098],[14.893,44.917],[-52.107,-25.749],[-43.107,-42.249]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[-17.553,4.111],[-4.534,0],[-3,-8.333],[48.215,-10.557],[1,8.333],[-6.167,2.5]],"o":[[18.5,-4.333],[4.666,0],[3,8.333],[-51,11.167],[-1,-8.334],[6.969,-2.826]],"v":[[-11.774,-51.417],[32.536,-58.765],[45.369,-49.098],[14.893,44.917],[-52.107,-25.749],[-43.107,-42.249]],"c":true}],"e":[{"i":[[-17.553,4.111],[-4.534,0],[-3,-8.333],[48.215,-10.557],[1,8.333],[-6.167,2.5]],"o":[[18.5,-4.333],[4.666,0],[3,8.333],[-51,11.167],[-1,-8.334],[6.969,-2.826]],"v":[[-49.104,-45.549],[-1.36,-53.772],[11.473,-44.105],[-14.527,49.228],[-89.438,-19.882],[-80.438,-36.382]],"c":true}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.885999971278,0.337000020345,0.74900004069,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[333.107,419.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 10","np":2,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[0,0],[59.667,-10],[0,0],[17.986,-6.775],[0.333,-10.334],[3,-6],[2.333,7.333],[-2.726,8.808],[-4.655,2.007],[0,0],[-25.667,5.333],[0,0]],"o":[[0,0],[-70.424,11.803],[0.12,-1.267],[-12.802,4.822],[-0.333,10.333],[-3,6],[-2.333,-7.333],[2.167,-7],[30.525,-13.156],[0,0],[25.666,-5.333],[0,0]],"v":[[98.247,-45.522],[59.58,56.811],[-31.331,-27.299],[-83.333,-11.166],[-101.333,4.834],[-101.666,62.167],[-124.333,70.167],[-115.333,-5],[-102.501,-17.781],[-31.331,-50.966],[46.914,-70.522],[90.914,-78.189]],"c":false}],"e":[{"i":[[0,0],[59.667,-10],[0,0],[17.986,-6.775],[0.333,-10.334],[3,-6],[2.333,7.333],[-2.726,8.808],[-4.655,2.007],[0,0],[-25.667,5.333],[0,0]],"o":[[0,0],[-70.424,11.803],[0.12,-1.267],[-12.802,4.822],[-0.333,10.333],[-3,6],[-2.333,-7.333],[2.167,-7],[30.525,-13.156],[0,0],[25.666,-5.333],[0,0]],"v":[[134.139,-50.791],[88.999,52.5],[5.999,-33.166],[-100.333,-7.166],[-118.333,8.834],[-118.666,66.167],[-141.333,74.167],[-132.333,-1],[-119.501,-13.781],[5.999,-56.833],[76.334,-74.833],[124.81,-83.182]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[59.667,-10],[0,0],[17.986,-6.775],[0.333,-10.334],[3,-6],[2.333,7.333],[-2.726,8.808],[-4.655,2.007],[0,0],[-25.667,5.333],[0,0]],"o":[[0,0],[-70.424,11.803],[0.12,-1.267],[-12.802,4.822],[-0.333,10.333],[-3,6],[-2.333,-7.333],[2.167,-7],[30.525,-13.156],[0,0],[25.666,-5.333],[0,0]],"v":[[134.139,-50.791],[88.999,52.5],[5.999,-33.166],[-100.333,-7.166],[-118.333,8.834],[-118.666,66.167],[-141.333,74.167],[-132.333,-1],[-119.501,-13.781],[5.999,-56.833],[76.334,-74.833],[124.81,-83.182]],"c":false}],"e":[{"i":[[0,0],[59.667,-10],[0,0],[17.986,-6.775],[0.333,-10.334],[3,-6],[2.333,7.333],[-2.726,8.808],[-4.655,2.007],[0,0],[-25.667,5.333],[0,0]],"o":[[0,0],[-70.424,11.803],[0.12,-1.267],[-12.802,4.822],[-0.333,10.333],[-3,6],[-2.333,-7.333],[2.167,-7],[30.525,-13.156],[0,0],[25.666,-5.333],[0,0]],"v":[[98.247,-45.522],[59.58,56.811],[-31.331,-27.299],[-83.333,-11.166],[-101.333,4.834],[-101.666,62.167],[-124.333,70.167],[-115.333,-5],[-102.501,-17.781],[-31.331,-50.966],[46.914,-70.522],[90.914,-78.189]],"c":false}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.430999995213,0.694000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[260.333,426.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 11","np":2,"cix":2,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[-17.776,3.003],[-4.526,-0.284],[-2.472,-8.504],[48.781,-7.515],[0.475,8.379],[-6.31,2.109]],"o":[[18.735,-3.166],[4.657,0.292],[2.472,8.505],[-51.599,7.949],[-0.477,-8.38],[7.133,-2.383]],"v":[[-41.42,-47.106],[2.244,-51.507],[14.446,-41.056],[-17.352,50.465],[-83.282,-24.017],[-73.267,-39.921]],"c":true}],"e":[{"i":[[-17.776,3.003],[-4.526,-0.284],[-2.472,-8.504],[48.781,-7.515],[0.475,8.379],[-6.31,2.109]],"o":[[18.735,-3.166],[4.657,0.292],[2.472,8.505],[-51.599,7.949],[-0.477,-8.38],[7.133,-2.383]],"v":[[-8.509,-51.662],[31.663,-55.819],[43.866,-45.368],[12.068,46.153],[-45.895,-29.254],[-35.88,-45.158]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[-17.776,3.003],[-4.526,-0.284],[-2.472,-8.504],[48.781,-7.515],[0.475,8.379],[-6.31,2.109]],"o":[[18.735,-3.166],[4.657,0.292],[2.472,8.505],[-51.599,7.949],[-0.477,-8.38],[7.133,-2.383]],"v":[[-8.509,-51.662],[31.663,-55.819],[43.866,-45.368],[12.068,46.153],[-45.895,-29.254],[-35.88,-45.158]],"c":true}],"e":[{"i":[[-17.776,3.003],[-4.526,-0.284],[-2.472,-8.504],[48.781,-7.515],[0.475,8.379],[-6.31,2.109]],"o":[[18.735,-3.166],[4.657,0.292],[2.472,8.505],[-51.599,7.949],[-0.477,-8.38],[7.133,-2.383]],"v":[[-41.42,-47.106],[2.244,-51.507],[14.446,-41.056],[-17.352,50.465],[-83.282,-24.017],[-73.267,-39.921]],"c":true}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.411999990426,0.063000002094,0.325,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[448.707,398.839],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 12","np":2,"cix":2,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[0,0],[-5.954,-8.891],[-7.377,1.792],[-1.684,-1.108],[3.137,-10.073],[0,0],[-8.032,0.247],[0,0],[0.323,14.799],[10.542,-0.34],[0.374,2.028],[-2.861,12.169],[0,0]],"o":[[0,0],[4.649,6.942],[7.377,-1.791],[1.684,1.108],[-3.138,10.074],[0,0],[8.031,-0.248],[0,0],[-0.152,-6.95],[-4.428,0.143],[-0.374,-2.027],[3.076,-13.083],[0,0]],"v":[[-47.969,-40.476],[-53.586,7.757],[-40.39,14.489],[-28.476,11.967],[-31.406,36.59],[-34.839,52.005],[-17.172,53.403],[-4.805,51.924],[4.892,5.191],[-8.812,-7.945],[-23.892,-7.139],[-20.08,-31.949],[-16.878,-47.027]],"c":true}],"e":[{"i":[[0,0],[-5.954,-8.891],[-7.377,1.792],[-1.684,-1.108],[3.137,-10.073],[0,0],[-8.032,0.247],[0,0],[0.323,14.799],[10.542,-0.34],[0.374,2.028],[-2.861,12.169],[0,0]],"o":[[0,0],[4.649,6.942],[7.377,-1.791],[1.684,1.108],[-3.138,10.074],[0,0],[8.031,-0.248],[0,0],[-0.152,-6.95],[-4.428,0.143],[-0.374,-2.027],[3.076,-13.083],[0,0]],"v":[[-11.103,-45.809],[-14.204,2.38],[1.95,8.404],[7.393,6.703],[4.532,32.324],[2.548,46.767],[12.247,49.091],[24.614,47.612],[34.311,0.879],[20.607,-12.256],[5.527,-11.45],[9.339,-36.26],[12.541,-51.338]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[-5.954,-8.891],[-7.377,1.792],[-1.684,-1.108],[3.137,-10.073],[0,0],[-8.032,0.247],[0,0],[0.323,14.799],[10.542,-0.34],[0.374,2.028],[-2.861,12.169],[0,0]],"o":[[0,0],[4.649,6.942],[7.377,-1.791],[1.684,1.108],[-3.138,10.074],[0,0],[8.031,-0.248],[0,0],[-0.152,-6.95],[-4.428,0.143],[-0.374,-2.027],[3.076,-13.083],[0,0]],"v":[[-11.103,-45.809],[-14.204,2.38],[1.95,8.404],[7.393,6.703],[4.532,32.324],[2.548,46.767],[12.247,49.091],[24.614,47.612],[34.311,0.879],[20.607,-12.256],[5.527,-11.45],[9.339,-36.26],[12.541,-51.338]],"c":true}],"e":[{"i":[[0,0],[-5.954,-8.891],[-7.377,1.792],[-1.684,-1.108],[3.137,-10.073],[0,0],[-8.032,0.247],[0,0],[0.323,14.799],[10.542,-0.34],[0.374,2.028],[-2.861,12.169],[0,0]],"o":[[0,0],[4.649,6.942],[7.377,-1.791],[1.684,1.108],[-3.138,10.074],[0,0],[8.031,-0.248],[0,0],[-0.152,-6.95],[-4.428,0.143],[-0.374,-2.027],[3.076,-13.083],[0,0]],"v":[[-47.969,-40.476],[-53.586,7.757],[-40.39,14.489],[-28.476,11.967],[-31.406,36.59],[-34.839,52.005],[-17.172,53.402],[-4.805,51.923],[4.892,5.19],[-8.812,-7.944],[-23.892,-7.138],[-20.08,-31.948],[-16.878,-47.026]],"c":true}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.948999980852,0.477999997606,0.830999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[440.991,396.264],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 13","np":2,"cix":2,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[-17.776,3.003],[-4.526,-0.284],[-2.472,-8.504],[48.781,-7.515],[0.475,8.379],[-6.31,2.109]],"o":[[18.735,-3.166],[4.657,0.292],[2.472,8.505],[-51.599,7.949],[-0.477,-8.38],[7.133,-2.383]],"v":[[-41.42,-47.106],[2.244,-51.507],[14.446,-41.056],[-17.352,50.465],[-83.282,-24.017],[-73.267,-39.921]],"c":true}],"e":[{"i":[[-17.776,3.003],[-4.526,-0.284],[-2.472,-8.504],[48.781,-7.515],[0.475,8.379],[-6.31,2.109]],"o":[[18.735,-3.166],[4.657,0.292],[2.472,8.505],[-51.599,7.949],[-0.477,-8.38],[7.133,-2.383]],"v":[[-8.509,-51.662],[31.663,-55.819],[43.866,-45.368],[12.068,46.153],[-45.895,-29.254],[-35.88,-45.158]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[-17.776,3.003],[-4.526,-0.284],[-2.472,-8.504],[48.781,-7.515],[0.475,8.379],[-6.31,2.109]],"o":[[18.735,-3.166],[4.657,0.292],[2.472,8.505],[-51.599,7.949],[-0.477,-8.38],[7.133,-2.383]],"v":[[-8.509,-51.662],[31.663,-55.819],[43.866,-45.368],[12.068,46.153],[-45.895,-29.254],[-35.88,-45.158]],"c":true}],"e":[{"i":[[-17.776,3.003],[-4.526,-0.284],[-2.472,-8.504],[48.781,-7.515],[0.475,8.379],[-6.31,2.109]],"o":[[18.735,-3.166],[4.657,0.292],[2.472,8.505],[-51.599,7.949],[-0.477,-8.38],[7.133,-2.383]],"v":[[-41.42,-47.106],[2.244,-51.507],[14.446,-41.056],[-17.352,50.465],[-83.282,-24.017],[-73.267,-39.921]],"c":true}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.885999971278,0.337000020345,0.74900004069,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[448.707,398.839],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 14","np":2,"cix":2,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[0,0],[-76.291,14.727],[13,1.667],[28.667,-1.333],[0,0]],"o":[[0,0],[71.119,-13.729],[-5.96,-0.764],[-28.667,1.333],[0,0]],"v":[[-98.253,-47.606],[-19.919,59.394],[14.747,-63.273],[-25.586,-65.606],[-99.919,-54.273]],"c":true}],"e":[{"i":[[0,0],[-63.044,12.094],[13,1.667],[28.667,-1.333],[0,0]],"o":[[0,0],[71.135,-13.646],[-5.96,-0.764],[-28.667,1.333],[0,0]],"v":[[-64.358,-52.599],[9.5,55.083],[44.166,-67.584],[3.833,-69.917],[-66.024,-59.266]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[-63.044,12.094],[13,1.667],[28.667,-1.333],[0,0]],"o":[[0,0],[71.135,-13.646],[-5.96,-0.764],[-28.667,1.333],[0,0]],"v":[[-64.358,-52.599],[9.5,55.083],[44.166,-67.584],[3.833,-69.917],[-66.024,-59.266]],"c":true}],"e":[{"i":[[0,0],[-76.291,14.727],[13,1.667],[28.667,-1.333],[0,0]],"o":[[0,0],[71.119,-13.729],[-5.96,-0.764],[-28.667,1.333],[0,0]],"v":[[-98.253,-47.606],[-19.919,59.394],[14.747,-63.273],[-25.586,-65.606],[-99.919,-54.273]],"c":true}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.430999995213,0.694000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[450.167,401.584],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 15","np":2,"cix":2,"ix":15,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":40,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Кривые volosy","parent":4,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[297.64,420.945,0],"ix":2},"a":{"a":0,"k":[297.64,420.945,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[0,0],[-4.493,1.259],[-1.676,-26.43],[0,0],[-16,-0.667],[0,0],[1.333,32.667],[0,0],[-14,4],[0,0],[-11.334,4],[0,0],[-21.269,2.127],[0,0]],"o":[[-0.5,-15.667],[11.036,-3.092],[1.084,17.083],[0,0],[16,0.666],[0,0],[-1.333,-32.667],[0,0],[14,-4],[0,0],[11.333,-4],[0,0],[33.333,-3.334],[0,0]],"v":[[-108.667,29],[-106.417,9.25],[-90.834,50.75],[-90.834,85.417],[-63.5,89.417],[-27.5,88.75],[-76.167,8.75],[-59.834,-36.667],[-33.834,-36],[-8.5,-55.333],[13.501,-56],[29.5,-71.333],[60.833,-63.333],[109.166,-91.333]],"c":false}],"e":[{"i":[[0,0],[-4.493,1.259],[-3.812,-26.207],[0,0],[-16,-0.667],[0,0],[1.333,32.667],[0,0],[-14,4],[0,0],[-11.334,4],[0,0],[-21.269,2.127],[0,0]],"o":[[-0.5,-15.667],[11.036,-3.092],[2.667,18.333],[0,0],[16,0.666],[0,0],[-1.333,-32.667],[0,0],[14,-4],[0,0],[11.333,-4],[0,0],[33.333,-3.334],[0,0]],"v":[[-108.667,29],[-99.667,8.5],[-67.834,52],[-67.834,86.667],[-40.5,90.667],[8.187,87.118],[-48.69,9.318],[-39.834,-36.667],[-13.834,-36],[11.5,-55.333],[33.5,-56],[49.5,-71.333],[80.833,-63.333],[118.166,-91.333]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[-4.493,1.259],[-3.812,-26.207],[0,0],[-16,-0.667],[0,0],[1.333,32.667],[0,0],[-14,4],[0,0],[-11.334,4],[0,0],[-21.269,2.127],[0,0]],"o":[[-0.5,-15.667],[11.036,-3.092],[2.667,18.333],[0,0],[16,0.666],[0,0],[-1.333,-32.667],[0,0],[14,-4],[0,0],[11.333,-4],[0,0],[33.333,-3.334],[0,0]],"v":[[-108.667,29],[-99.667,8.5],[-67.834,52],[-67.834,86.667],[-40.5,90.667],[8.187,87.118],[-48.69,9.318],[-39.834,-36.667],[-13.834,-36],[11.5,-55.333],[33.5,-56],[49.5,-71.333],[80.833,-63.333],[118.166,-91.333]],"c":false}],"e":[{"i":[[0,0],[-4.493,1.259],[-1.676,-26.43],[0,0],[-16,-0.667],[0,0],[1.333,32.667],[0,0],[-14,4],[0,0],[-11.334,4],[0,0],[-21.269,2.127],[0,0]],"o":[[-0.5,-15.667],[11.036,-3.092],[1.084,17.083],[0,0],[16,0.666],[0,0],[-1.333,-32.667],[0,0],[14,-4],[0,0],[11.333,-4],[0,0],[33.333,-3.334],[0,0]],"v":[[-108.667,29],[-106.417,9.25],[-90.834,50.75],[-90.834,85.417],[-63.5,89.417],[-27.5,88.75],[-76.167,8.75],[-59.834,-36.667],[-33.834,-36],[-8.5,-55.333],[13.5,-56],[29.5,-71.333],[60.833,-63.333],[109.166,-91.333]],"c":false}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[278.5,378.667],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[0,0],[-4.493,1.259],[-3.812,-26.207],[0,0],[-16,-0.667],[0,0],[1.333,32.667],[0,0],[-14,4],[0,0],[-11.334,4],[0,0],[-21.269,2.127],[0,0],[53.5,4.5],[48,-26.5],[-2,-29]],"o":[[-0.5,-15.667],[11.036,-3.092],[2.667,18.333],[0,0],[16,0.666],[0,0],[-1.333,-32.667],[0,0],[14,-4],[0,0],[11.333,-4],[0,0],[33.333,-3.334],[0,0],[-47.501,-3.995],[-48,26.5],[2,29]],"v":[[-96.417,54.914],[-94.167,35.164],[-78.584,76.664],[-78.584,111.332],[-51.25,115.332],[-15.25,114.664],[-63.917,34.664],[-47.584,-10.753],[-21.584,-10.086],[3.75,-29.418],[25.75,-30.086],[41.75,-45.418],[73.083,-37.418],[121.416,-65.418],[76.25,-113.253],[-65.25,-87.253],[-127.75,15.747]],"c":true}],"e":[{"i":[[0,0],[-4.493,1.259],[-3.812,-26.207],[0,0],[-16,-0.667],[0,0],[1.333,32.667],[0,0],[-14,4],[0,0],[-11.334,4],[0,0],[-21.269,2.127],[0,0],[53.5,4.5],[48,-26.5],[-2,-29]],"o":[[-0.5,-15.667],[11.036,-3.092],[2.667,18.333],[0,0],[16,0.666],[0,0],[-1.333,-32.667],[0,0],[14,-4],[0,0],[11.333,-4],[0,0],[33.333,-3.334],[0,0],[-47.501,-3.995],[-48,26.5],[2,29]],"v":[[-96.417,54.914],[-87.417,34.414],[-55.584,77.914],[-55.584,112.582],[-28.25,116.582],[20.436,113.033],[-36.441,35.233],[-27.584,-10.753],[-1.584,-10.086],[23.75,-29.418],[45.75,-30.086],[61.75,-45.418],[93.083,-37.418],[130.416,-65.418],[76.25,-113.253],[-65.25,-87.253],[-127.75,15.747]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[-4.493,1.259],[-3.812,-26.207],[0,0],[-16,-0.667],[0,0],[1.333,32.667],[0,0],[-14,4],[0,0],[-11.334,4],[0,0],[-21.269,2.127],[0,0],[53.5,4.5],[48,-26.5],[-2,-29]],"o":[[-0.5,-15.667],[11.036,-3.092],[2.667,18.333],[0,0],[16,0.666],[0,0],[-1.333,-32.667],[0,0],[14,-4],[0,0],[11.333,-4],[0,0],[33.333,-3.334],[0,0],[-47.501,-3.995],[-48,26.5],[2,29]],"v":[[-96.417,54.914],[-87.417,34.414],[-55.584,77.914],[-55.584,112.582],[-28.25,116.582],[20.436,113.033],[-36.441,35.233],[-27.584,-10.753],[-1.584,-10.086],[23.75,-29.418],[45.75,-30.086],[61.75,-45.418],[93.083,-37.418],[130.416,-65.418],[76.25,-113.253],[-65.25,-87.253],[-127.75,15.747]],"c":true}],"e":[{"i":[[0,0],[-4.493,1.259],[-3.812,-26.207],[0,0],[-16,-0.667],[0,0],[1.333,32.667],[0,0],[-14,4],[0,0],[-11.334,4],[0,0],[-21.269,2.127],[0,0],[53.5,4.5],[48,-26.5],[-2,-29]],"o":[[-0.5,-15.667],[11.036,-3.092],[2.667,18.333],[0,0],[16,0.666],[0,0],[-1.333,-32.667],[0,0],[14,-4],[0,0],[11.333,-4],[0,0],[33.333,-3.334],[0,0],[-47.501,-3.995],[-48,26.5],[2,29]],"v":[[-96.417,54.914],[-94.167,35.164],[-78.584,76.664],[-78.584,111.332],[-51.25,115.332],[-15.25,114.664],[-63.917,34.664],[-47.584,-10.753],[-21.584,-10.086],[3.75,-29.418],[25.75,-30.086],[41.75,-45.418],[73.083,-37.418],[121.416,-65.418],[76.25,-113.253],[-65.25,-87.253],[-127.75,15.747]],"c":true}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.180000005984,0.035000000748,0.144999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[266.25,352.752],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":40,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Кривые R_ruka","parent":4,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[196.296,490.712,0],"ix":2},"a":{"a":0,"k":[196.293,491.186,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[13.227,-15.815],[-7,-6],[-13.802,5.751],[0,0]],"o":[[0,0],[-11.499,13.749],[7,6],[13.663,-5.693],[0,0]],"v":[[17.67,-35.5],[-6.308,-13.159],[-19.412,28.154],[10.657,13.007],[31.33,7.739]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.830999995213,0.26699999641,0.019999999626,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[168.83,506.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[17.969,15.418],[13.227,-15.815],[-7,-6],[-13.802,5.751],[0,0]],"o":[[0,0],[-11.499,13.749],[7,6],[13.663,-5.693],[0,0]],"v":[[15.516,-35.5],[-8.462,-13.159],[-21.566,28.154],[8.503,13.007],[29.175,7.739]],"c":true},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.875,0.039000002543,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[171.56,505.925],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":40,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Кривые telo","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[2],"e":[15]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":20,"s":[15],"e":[2]},{"t":40}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[449.64,462.945,0],"e":[449.64,439.945,0],"to":[0,-3.83333325386047,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":10,"s":[449.64,439.945,0],"e":[449.64,462.945,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[449.64,462.945,0],"e":[449.64,439.945,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":30,"s":[449.64,439.945,0],"e":[449.64,462.945,0],"to":[0,0,0],"ti":[0,-3.83333325386047,0]},{"t":40}],"ix":2},"a":{"a":0,"k":[297.64,420.945,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[100,100,100],"e":[100,97,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":5,"s":[100,97,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":10,"s":[100,100,100],"e":[100,103,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":15,"s":[100,103,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":20,"s":[100,100,100],"e":[100,97,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":25,"s":[100,97,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":30,"s":[100,100,100],"e":[100,103,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":35,"s":[100,103,100],"e":[100,100,100]},{"t":40}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[0,0],[-69.333,11.333],[0,0]],"o":[[0,0],[69.333,-11.334],[0,0]],"v":[[-94.243,-3.694],[-16.919,36.694],[-99.586,-41.973]],"c":false}],"e":[{"i":[[0,0],[-69.333,11.333],[0,0]],"o":[[0,0],[69.333,-11.334],[0,0]],"v":[[-59.666,-8],[13.667,32.667],[-69,-46]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[-69.333,11.333],[0,0]],"o":[[0,0],[69.333,-11.334],[0,0]],"v":[[-59.666,-8],[13.667,32.667],[-69,-46]],"c":false}],"e":[{"i":[[0,0],[-69.333,11.333],[0,0]],"o":[[0,0],[69.333,-11.334],[0,0]],"v":[[-94.243,-3.694],[-16.919,36.694],[-99.586,-41.973]],"c":false}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.705999995213,0.011999999776,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[448.333,423.667],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[0,0],[0,0],[-71.333,14],[0,0],[0,0]],"o":[[0,0],[0,0],[78.024,-15.313],[0,0],[0,0]],"v":[[-105.345,-5.167],[-75.449,-13.199],[17.988,59.833],[23.988,-65.833],[-112.012,-25.833]],"c":false}],"e":[{"i":[[0,0],[0,0],[-71.333,14],[0,0],[0,0]],"o":[[0,0],[0,0],[78.024,-15.313],[0,0],[0,0]],"v":[[-105.345,-5.167],[-41.012,-19.499],[40.988,54.833],[46.988,-70.833],[-112.012,-25.833]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[0,0],[-71.333,14],[0,0],[0,0]],"o":[[0,0],[0,0],[78.024,-15.313],[0,0],[0,0]],"v":[[-105.345,-5.167],[-41.012,-19.499],[40.988,54.833],[46.988,-70.833],[-112.012,-25.833]],"c":false}],"e":[{"i":[[0,0],[0,0],[-71.333,14],[0,0],[0,0]],"o":[[0,0],[0,0],[78.024,-15.313],[0,0],[0,0]],"v":[[-105.345,-5.167],[-75.449,-13.199],[17.988,59.833],[23.988,-65.833],[-112.012,-25.833]],"c":false}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.705999995213,0.011999999776,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[300.345,427.167],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.333,19.334],[-73.334,27.334],[-30,-32],[19.411,-53.972],[60.441,-6.199],[4.666,100.667]],"o":[[-3.588,-52.03],[104.531,-38.961],[30,32],[-27.333,76],[-78,8],[-2.105,-45.407]],"v":[[-166.578,-27.52],[-85.911,-160.186],[120.422,-90.186],[150.755,89.147],[8.755,191.147],[-163.911,59.147]],"c":true},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.830999995213,0.26699999641,0.019999999626,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[339.578,452.853],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 3","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[0,0],[-63.626,-57.679],[0,0],[64.667,41.999],[3.334,67.333],[0,0]],"o":[[0,0],[71.333,64.667],[0,0],[-60.325,-39.181],[-3.333,-67.333],[0,0]],"v":[[-88.333,-130.667],[-39.667,42],[120.333,94],[-47.001,88.667],[-117.001,-46.667],[-117.001,-125.999]],"c":false}],"e":[{"i":[[0,0],[-63.626,-57.679],[0,0],[64.667,41.999],[3.334,67.333],[0,0]],"o":[[0,0],[71.333,64.667],[0,0],[-60.325,-39.181],[-3.333,-67.333],[0,0]],"v":[[-76.333,-130.667],[-21.667,36],[120.333,94],[-47.001,88.667],[-117.001,-46.667],[-117.001,-125.999]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[-63.626,-57.679],[0,0],[64.667,41.999],[3.334,67.333],[0,0]],"o":[[0,0],[71.333,64.667],[0,0],[-60.325,-39.181],[-3.333,-67.333],[0,0]],"v":[[-76.333,-130.667],[-21.667,36],[120.333,94],[-47.001,88.667],[-117.001,-46.667],[-117.001,-125.999]],"c":false}],"e":[{"i":[[0,0],[-63.626,-57.679],[0,0],[64.667,41.999],[3.334,67.333],[0,0]],"o":[[0,0],[71.333,64.667],[0,0],[-60.325,-39.181],[-3.333,-67.333],[0,0]],"v":[[-88.333,-130.667],[-39.667,42],[120.333,94],[-47.001,88.667],[-117.001,-46.667],[-117.001,-125.999]],"c":false}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.705999995213,0.011999999776,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[290.667,535.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 4","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.333,19.334],[-73.334,27.334],[-30,-32],[19.411,-53.972],[60.441,-6.199],[4.666,100.667]],"o":[[-3.588,-52.03],[104.531,-38.961],[30,32],[-27.333,76],[-78,8],[-2.105,-45.407]],"v":[[-166.578,-27.52],[-85.911,-160.186],[120.422,-90.186],[150.755,89.147],[8.755,191.147],[-163.911,59.147]],"c":true},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.830999995213,0.26699999641,0.019999999626,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.875,0.039000002543,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[339.578,452.853],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 5","np":3,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":40,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Кривые L_noga 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":20,"s":[0],"e":[34]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":30,"s":[34],"e":[67]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":40,"s":[67],"e":[34]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":50,"s":[34],"e":[0]},{"t":60}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":20,"s":[577.14,653.445,0],"e":[485.14,672.445,0],"to":[-14.5833330154419,8.58333301544189,0],"ti":[40.7188301086426,-1.91244661808014,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":30,"s":[485.14,672.445,0],"e":[397.14,653.945,0],"to":[-47.4723854064941,2.2296416759491,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":40,"s":[397.14,653.945,0],"e":[485.14,646.445,0],"to":[0,0,0],"ti":[-17.2466659545898,0.14780442416668,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":50,"s":[485.14,646.445,0],"e":[577.14,653.445,0],"to":[60.0219345092773,-0.51438969373703,0],"ti":[13.1223392486572,-7.72343397140503,0]},{"t":60}],"ix":2},"a":{"a":0,"k":[425.14,624.445,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":20,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[12.323,-8.378],[-6.738,22.378],[18.988,-0.711]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[8.169,-8.122],[-11.207,15.154],[14.192,-2.049]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":28,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[8.169,-8.122],[-11.207,15.154],[14.192,-2.049]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[12.328,-3.35],[-12.728,12.696],[12.56,-2.505]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":30,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[12.328,-3.35],[-12.728,12.696],[12.56,-2.505]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[8.777,-4.082],[-13.794,13.763],[9.374,-2.623]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":32,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[8.777,-4.082],[-13.794,13.763],[9.374,-2.623]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[9.271,-0.383],[-14.861,14.83],[10.232,1.691]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":34,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[9.271,-0.383],[-14.861,14.83],[10.232,1.691]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[9.417,4.837],[-16.861,16.831],[13,13.368]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":40,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[9.417,4.837],[-16.861,16.831],[13,13.368]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-8.55,25.291],[-26.4,-1.895],[-14.663,36.832]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":47,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-8.55,25.291],[-26.4,-1.895],[-14.663,36.832]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[12.323,-8.378],[-6.738,22.378],[18.988,-0.711]],"c":false}]},{"t":60}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.830999995213,0.26699999641,0.019999999626,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[455.594,644.211],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":20,"s":[{"i":[[0,0],[0,0],[5.023,8.361],[0,0]],"o":[[0,0],[0,0],[-6.791,-11.305],[0,0]],"v":[[29.083,14.289],[1.022,26.044],[-15.293,6.51],[-25.084,-16.544]],"c":false}],"e":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[19.49,0.585],[-4.978,16.544],[-16.289,-2.108],[-29.554,-28.296]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":30,"s":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[19.49,0.585],[-4.978,16.544],[-16.289,-2.108],[-29.554,-28.296]],"c":false}],"e":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[17.209,2.001],[-6.041,17.565],[-11.82,-3.225],[-29.554,-28.296]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":32,"s":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[17.209,2.001],[-6.041,17.565],[-11.82,-3.225],[-29.554,-28.296]],"c":false}],"e":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[18.972,7.85],[-7.105,18.585],[-7.352,-4.342],[-29.554,-28.296]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":34,"s":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[18.972,7.85],[-7.105,18.585],[-7.352,-4.342],[-29.554,-28.296]],"c":false}],"e":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[21.289,28.144],[-9.1,20.498],[1.029,-6.436],[-29.554,-28.296]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":40,"s":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[21.289,28.144],[-9.1,20.498],[1.029,-6.436],[-29.554,-28.296]],"c":false}],"e":[{"i":[[0,0],[0,0],[4.706,8.543],[0,0]],"o":[[0,0],[0,0],[-5.449,-9.892],[0,0]],"v":[[-17,40.956],[-18.639,1.771],[-4.062,-18.442],[-29.554,-28.296]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":47,"s":[{"i":[[0,0],[0,0],[4.706,8.543],[0,0]],"o":[[0,0],[0,0],[-5.449,-9.892],[0,0]],"v":[[-17,40.956],[-18.639,1.771],[-4.062,-18.442],[-29.554,-28.296]],"c":false}],"e":[{"i":[[0,0],[0,0],[5.023,8.361],[0,0]],"o":[[0,0],[0,0],[-6.791,-11.305],[0,0]],"v":[[29.083,14.289],[1.022,26.044],[-15.293,6.51],[-25.084,-16.544]],"c":false}]},{"t":60}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.830999995213,0.26699999641,0.019999999626,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[447.833,640.544],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":20,"op":60,"st":20,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Кривые L_noga 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":-20,"s":[0],"e":[34]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":-10,"s":[34],"e":[67]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":0,"s":[67],"e":[34]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":10,"s":[34],"e":[0]},{"t":20}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":-20,"s":[577.14,653.445,0],"e":[485.14,672.445,0],"to":[-14.5833330154419,8.58333301544189,0],"ti":[40.7188301086426,-1.91244661808014,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":-10,"s":[485.14,672.445,0],"e":[397.14,653.945,0],"to":[-47.4723854064941,2.2296416759491,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":0,"s":[397.14,653.945,0],"e":[485.14,646.445,0],"to":[0,0,0],"ti":[-17.2466659545898,0.14780442416668,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":10,"s":[485.14,646.445,0],"e":[577.14,653.445,0],"to":[60.0219345092773,-0.51438969373703,0],"ti":[13.1223392486572,-7.72343397140503,0]},{"t":20}],"ix":2},"a":{"a":0,"k":[425.14,624.445,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":-20,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[12.323,-8.378],[-6.738,22.378],[18.988,-0.711]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[8.169,-8.122],[-11.207,15.154],[14.192,-2.049]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-12,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[8.169,-8.122],[-11.207,15.154],[14.192,-2.049]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[12.328,-3.35],[-12.728,12.696],[12.56,-2.505]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-10,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[12.328,-3.35],[-12.728,12.696],[12.56,-2.505]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[8.777,-4.082],[-13.794,13.763],[9.374,-2.623]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-8,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[8.777,-4.082],[-13.794,13.763],[9.374,-2.623]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[9.271,-0.383],[-14.861,14.83],[10.232,1.691]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":-6,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[9.271,-0.383],[-14.861,14.83],[10.232,1.691]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[9.417,4.837],[-16.861,16.831],[13,13.368]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":0,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[9.417,4.837],[-16.861,16.831],[13,13.368]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-8.55,25.291],[-26.4,-1.895],[-14.663,36.832]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":7,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-8.55,25.291],[-26.4,-1.895],[-14.663,36.832]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[12.323,-8.378],[-6.738,22.378],[18.988,-0.711]],"c":false}]},{"t":20}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.830999995213,0.26699999641,0.019999999626,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[455.594,644.211],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":-20,"s":[{"i":[[0,0],[0,0],[5.023,8.361],[0,0]],"o":[[0,0],[0,0],[-6.791,-11.305],[0,0]],"v":[[29.083,14.289],[1.022,26.044],[-15.293,6.51],[-25.084,-16.544]],"c":false}],"e":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[19.49,0.585],[-4.978,16.544],[-16.289,-2.108],[-29.554,-28.296]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-10,"s":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[19.49,0.585],[-4.978,16.544],[-16.289,-2.108],[-29.554,-28.296]],"c":false}],"e":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[17.209,2.001],[-6.041,17.565],[-11.82,-3.225],[-29.554,-28.296]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-8,"s":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[17.209,2.001],[-6.041,17.565],[-11.82,-3.225],[-29.554,-28.296]],"c":false}],"e":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[18.972,7.85],[-7.105,18.585],[-7.352,-4.342],[-29.554,-28.296]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":-6,"s":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[18.972,7.85],[-7.105,18.585],[-7.352,-4.342],[-29.554,-28.296]],"c":false}],"e":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[21.289,28.144],[-9.1,20.498],[1.029,-6.436],[-29.554,-28.296]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":0,"s":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[21.289,28.144],[-9.1,20.498],[1.029,-6.436],[-29.554,-28.296]],"c":false}],"e":[{"i":[[0,0],[0,0],[4.706,8.543],[0,0]],"o":[[0,0],[0,0],[-5.449,-9.892],[0,0]],"v":[[-17,40.956],[-18.639,1.771],[-4.062,-18.442],[-29.554,-28.296]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":7,"s":[{"i":[[0,0],[0,0],[4.706,8.543],[0,0]],"o":[[0,0],[0,0],[-5.449,-9.892],[0,0]],"v":[[-17,40.956],[-18.639,1.771],[-4.062,-18.442],[-29.554,-28.296]],"c":false}],"e":[{"i":[[0,0],[0,0],[5.023,8.361],[0,0]],"o":[[0,0],[0,0],[-6.791,-11.305],[0,0]],"v":[[29.083,14.289],[1.022,26.044],[-15.293,6.51],[-25.084,-16.544]],"c":false}]},{"t":20}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.830999995213,0.26699999641,0.019999999626,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[447.833,640.544],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-20,"op":20,"st":-20,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Кривые L_noga","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":0,"s":[0],"e":[34]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":10,"s":[34],"e":[67]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":20,"s":[67],"e":[34]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":30,"s":[34],"e":[0]},{"t":40}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":0,"s":[577.14,653.445,0],"e":[485.14,672.445,0],"to":[-14.5833330154419,8.58333301544189,0],"ti":[40.7188301086426,-1.91244661808014,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":10,"s":[485.14,672.445,0],"e":[397.14,653.945,0],"to":[-47.4723854064941,2.2296416759491,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":20,"s":[397.14,653.945,0],"e":[485.14,646.445,0],"to":[0,0,0],"ti":[-17.2466659545898,0.14780442416668,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":30,"s":[485.14,646.445,0],"e":[577.14,653.445,0],"to":[60.0219345092773,-0.51438969373703,0],"ti":[13.1223392486572,-7.72343397140503,0]},{"t":40}],"ix":2},"a":{"a":0,"k":[425.14,624.445,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":0,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[12.323,-8.378],[-6.738,22.378],[18.988,-0.711]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[8.169,-8.122],[-11.207,15.154],[14.192,-2.049]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":8,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[8.169,-8.122],[-11.207,15.154],[14.192,-2.049]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[12.328,-3.35],[-12.728,12.696],[12.56,-2.505]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":10,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[12.328,-3.35],[-12.728,12.696],[12.56,-2.505]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[8.777,-4.082],[-13.794,13.763],[9.374,-2.623]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":12,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[8.777,-4.082],[-13.794,13.763],[9.374,-2.623]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[9.271,-0.383],[-14.861,14.83],[10.232,1.691]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":14,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[9.271,-0.383],[-14.861,14.83],[10.232,1.691]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[9.417,4.837],[-16.861,16.831],[13,13.368]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":20,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[9.417,4.837],[-16.861,16.831],[13,13.368]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-8.55,25.291],[-26.4,-1.895],[-14.663,36.832]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":27,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-8.55,25.291],[-26.4,-1.895],[-14.663,36.832]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[12.323,-8.378],[-6.738,22.378],[18.988,-0.711]],"c":false}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.830999995213,0.26699999641,0.019999999626,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[455.594,644.211],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":0,"s":[{"i":[[0,0],[0,0],[5.023,8.361],[0,0]],"o":[[0,0],[0,0],[-6.791,-11.305],[0,0]],"v":[[29.083,14.289],[1.022,26.044],[-15.293,6.51],[-25.084,-16.544]],"c":false}],"e":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[19.49,0.585],[-4.978,16.544],[-16.289,-2.108],[-29.554,-28.296]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":10,"s":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[19.49,0.585],[-4.978,16.544],[-16.289,-2.108],[-29.554,-28.296]],"c":false}],"e":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[17.209,2.001],[-6.041,17.565],[-11.82,-3.225],[-29.554,-28.296]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":12,"s":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[17.209,2.001],[-6.041,17.565],[-11.82,-3.225],[-29.554,-28.296]],"c":false}],"e":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[18.972,7.85],[-7.105,18.585],[-7.352,-4.342],[-29.554,-28.296]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":14,"s":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[18.972,7.85],[-7.105,18.585],[-7.352,-4.342],[-29.554,-28.296]],"c":false}],"e":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[21.289,28.144],[-9.1,20.498],[1.029,-6.436],[-29.554,-28.296]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":20,"s":[{"i":[[0,0],[0,0],[4.542,8.632],[0,0]],"o":[[0,0],[0,0],[-8.023,-15.246],[0,0]],"v":[[21.289,28.144],[-9.1,20.498],[1.029,-6.436],[-29.554,-28.296]],"c":false}],"e":[{"i":[[0,0],[0,0],[4.706,8.543],[0,0]],"o":[[0,0],[0,0],[-5.449,-9.892],[0,0]],"v":[[-17,40.956],[-18.639,1.771],[-4.062,-18.442],[-29.554,-28.296]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":27,"s":[{"i":[[0,0],[0,0],[4.706,8.543],[0,0]],"o":[[0,0],[0,0],[-5.449,-9.892],[0,0]],"v":[[-17,40.956],[-18.639,1.771],[-4.062,-18.442],[-29.554,-28.296]],"c":false}],"e":[{"i":[[0,0],[0,0],[5.023,8.361],[0,0]],"o":[[0,0],[0,0],[-6.791,-11.305],[0,0]],"v":[[29.083,14.289],[1.022,26.044],[-15.293,6.51],[-25.084,-16.544]],"c":false}]},{"t":40}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.830999995213,0.26699999641,0.019999999626,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[447.833,640.544],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":40,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Кривые volosy_back","parent":4,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[278.64,439.945,0],"ix":2},"a":{"a":0,"k":[278.64,439.945,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0.167,0]},"n":["0p667_1_0p167_0","0p667_1_0p167_0p167","0p667_1_0p167_0"],"t":0,"s":[100,100,100],"e":[100,96,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,0.833,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_1_0p333_0","0p833_0p833_0p333_0","0p833_1_0p333_0"],"t":5,"s":[100,96,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0.167,0]},"n":["0p667_1_0p167_0","0p667_1_0p167_0p167","0p667_1_0p167_0"],"t":10,"s":[100,100,100],"e":[100,104,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,0.833,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_1_0p333_0","0p833_0p833_0p333_0","0p833_1_0p333_0"],"t":15,"s":[100,104,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0.167,0]},"n":["0p667_1_0p167_0","0p667_1_0p167_0p167","0p667_1_0p167_0"],"t":20,"s":[100,100,100],"e":[100,96,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,0.833,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_1_0p333_0","0p833_0p833_0p333_0","0p833_1_0p333_0"],"t":25,"s":[100,96,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0.167,0]},"n":["0p667_1_0p167_0","0p667_1_0p167_0p167","0p667_1_0p167_0"],"t":30,"s":[100,100,100],"e":[100,104,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,0.833,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_1_0p333_0","0p833_0p833_0p333_0","0p833_1_0p333_0"],"t":35,"s":[100,104,100],"e":[100,100,100]},{"t":40}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[18.333,4.667],[0,0],[20.667,14.666],[0,0],[6.667,28],[0,0],[-4.333,20.667],[0,0],[-4.333,9.334],[0,0],[-21,18],[0,0],[-22.661,8.664],[0,0],[-15,2],[0,0],[-25.333,-2.333],[0,0],[-18,-10.334],[0,0],[-13.334,-9],[0,0],[-5,-21.667],[0,0],[4.334,-16.667],[0,0],[3.666,-9],[0,0]],"o":[[0,0],[-18.334,-4.667],[0,0],[-20.667,-14.667],[0,0],[-5.9,-24.781],[0,0],[4.333,-20.667],[0,0],[4.333,-9.333],[0,0],[21,-18],[0,0],[22.666,-8.667],[0,0],[15,-2],[0,0],[25.334,2.334],[0,0],[18,10.333],[0,0],[13.333,9],[0,0],[5,21.666],[0,0],[-4.333,16.667],[0,0],[-3.667,9],[0,0]],"v":[[-65.883,165.167],[-99.217,171.167],[-121.883,149.167],[-159.883,142.834],[-178.551,110.167],[-215.883,75.166],[-205.216,31.834],[-213.883,-10.833],[-194.883,-36.5],[-192.883,-55.5],[-176.551,-67.166],[-161.551,-113.167],[-115.883,-123.167],[-88.217,-157.167],[-49.217,-151.5],[-23.217,-171.833],[5.449,-163.5],[44.449,-173.5],[78.449,-156.833],[119.449,-154.167],[144.449,-121.5],[175.783,-116.833],[191.783,-88.5],[213.45,-62.166],[208.45,-28.166],[217.45,5.167],[199.783,30.167],[199.783,49.5],[179.117,62.167]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[253.883,287.833],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[13.333,9],[0,0],[18,10.333],[0,0],[25.334,2.333],[0,0],[15,-2],[0,0],[22.667,-8.667],[0,0],[21,-18],[0,0],[4.333,-9.334],[0,0],[4.333,-20.666],[0,0],[-10.61,20.795],[0,0],[-5.334,7],[0,0],[-20.667,14.667],[0,0],[-24.166,9.916],[0,0],[-17.177,2.417],[0,0],[-23.667,-3.667],[0,0],[-17.666,-8],[0,0],[-13,-11],[0,0],[-7.25,-4.75]],"o":[[-5,-21.667],[0,0],[-13.334,-9],[0,0],[-18,-10.333],[0,0],[-25.333,-2.334],[0,0],[-15,2],[0,0],[-22.66,8.665],[0,0],[-21,18],[0,0],[-4.334,9.333],[0,0],[-4.334,20.667],[0,0],[8.333,-16.333],[0,0],[5.333,-7],[0,0],[20.667,-14.667],[0,0],[21.189,-8.695],[0,0],[22.5,-3.167],[0,0],[23.667,3.666],[0,0],[17.667,8],[0,0],[13,11],[0,0],[7.25,4.75]],"v":[[215.833,9.834],[194.167,-16.499],[178.167,-44.833],[146.833,-49.499],[121.833,-82.167],[80.833,-84.833],[46.833,-101.499],[7.834,-91.499],[-20.834,-99.833],[-46.833,-79.499],[-85.833,-85.167],[-113.5,-51.167],[-159.167,-41.167],[-174.167,4.833],[-190.5,16.501],[-192.5,35.501],[-211.5,61.167],[-202.833,103.833],[-202.5,62.167],[-178.167,43.167],[-177.5,21.833],[-160.167,13.167],[-147.167,-28.167],[-104.5,-38.083],[-79.833,-70.499],[-41.833,-63.833],[-18.499,-84.167],[10.833,-72.833],[46.833,-86.499],[82.167,-64.499],[115.833,-69.499],[141,-39.833],[174.5,-34.333],[189.833,-9.499],[202.5,-3.583]],"c":true},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.430999995213,0.216000007181,0.654999976065,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[251.5,215.833],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[18.333,4.667],[0,0],[20.667,14.666],[0,0],[6.667,28],[0,0],[-4.333,20.667],[0,0],[-4.333,9.334],[0,0],[-21,18],[0,0],[-22.661,8.664],[0,0],[-15,2],[0,0],[-25.333,-2.333],[0,0],[-18,-10.334],[0,0],[-13.334,-9],[0,0],[-5,-21.667],[0,0],[4.334,-16.667],[0,0],[3.666,-9],[0,0]],"o":[[0,0],[-18.334,-4.667],[0,0],[-20.667,-14.667],[0,0],[-5.9,-24.781],[0,0],[4.333,-20.667],[0,0],[4.333,-9.333],[0,0],[21,-18],[0,0],[22.666,-8.667],[0,0],[15,-2],[0,0],[25.334,2.334],[0,0],[18,10.333],[0,0],[13.333,9],[0,0],[5,21.666],[0,0],[-4.333,16.667],[0,0],[-3.667,9],[0,0]],"v":[[-65.883,165.167],[-99.217,171.167],[-121.883,149.167],[-159.883,142.834],[-178.551,110.167],[-215.883,75.166],[-205.216,31.834],[-213.883,-10.833],[-194.883,-36.5],[-192.883,-55.5],[-176.551,-67.166],[-161.551,-113.167],[-115.883,-123.167],[-88.217,-157.167],[-49.217,-151.5],[-23.217,-171.833],[5.449,-163.5],[44.449,-173.5],[78.449,-156.833],[119.449,-154.167],[144.449,-121.5],[175.783,-116.833],[191.783,-88.5],[213.45,-62.166],[208.45,-28.166],[217.45,5.167],[199.783,30.167],[199.783,49.5],[179.117,62.167]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.180000005984,0.035000000748,0.144999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[253.883,287.833],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 3","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":40,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Кривые L_ruka","parent":4,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[461.575,424.56,0],"ix":2},"a":{"a":0,"k":[454.176,425.589,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-16.006,-12.996],[5.725,-7.226],[14.647,3.007],[0,0]],"o":[[0,0],[13.914,11.297],[-5.723,7.228],[-14.5,-2.976],[0,0]],"v":[[-27.114,-31.501],[5.777,-13.773],[26.534,24.273],[-5.875,15.152],[-32.259,13.552]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.830999995213,0.26699999641,0.019999999626,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[487.767,436.625],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-14.69,18.569],[-16.006,-12.996],[5.724,-7.228],[14.647,3.007],[0,0]],"o":[[0,0],[13.915,11.297],[-5.724,7.227],[-14.499,-2.977],[0,0]],"v":[[-22.341,-31.501],[10.55,-13.773],[31.307,24.274],[-1.102,15.153],[-27.485,13.552]],"c":true},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.875,0.039000002543,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[482.32,436.17],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":40,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"cipa 2","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,266,0],"ix":2},"a":{"a":0,"k":[450,450,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":900,"h":900,"ip":0,"op":32,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/gears.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/gears.json deleted file mode 100644 index 13b2a0ee..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/gears.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.5.7","fr":30,"ip":0,"op":52,"w":128,"h":128,"ddd":0,"assets":[],"layers":[{"ddd":0,"ind":0,"ty":3,"nm":"Null 5","ks":{"o":{"a":0,"k":0},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[0],"e":[90]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":25,"s":[90],"e":[0]},{"t":52}]},"p":{"a":0,"k":[64,64,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"ip":0,"op":53,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"gear3","parent":0,"ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[360],"e":[0]},{"t":52}]},"p":{"s":true,"x":{"a":0,"k":19.125},"y":{"a":0,"k":22.125}},"a":{"a":0,"k":[28,30,0]},"s":{"a":0,"k":[75,75,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[1.627,0.306],[0,0],[0,0],[0,0],[1.704,-0.597],[0,0],[0,0],[0,0],[1.186,-1.384],[0,0],[0,0],[0,0],[0.33,-1.753],[0,0],[0,0],[0,0],[-0.6,-1.701],[0,0],[0,0],[0,0],[-1.387,-1.186],[0,0],[0,0],[0,0],[-0.127,-0.045],[-1.627,-0.306],[0,0],[0,0],[0,0],[-1.703,0.598],[0,0],[0,0],[0,0],[-1.185,1.383],[0,0],[0,0],[0,0],[-0.329,1.754],[0,0],[0,0],[0,0],[0.6,1.703],[0,0],[0,0],[0,0],[1.386,1.188],[0,0],[0,0],[0,0],[0.126,0.045]],"o":[[-1.591,-0.564],[0,0],[0,0],[0,0],[-1.779,0.307],[0,0],[0,0],[0,0],[-1.371,1.14],[0,0],[0,0],[0,0],[-0.63,1.709],[0,0],[0,0],[0,0],[0.31,1.777],[0,0],[0,0],[0,0],[1.145,1.369],[0,0],[0,0],[0,0],[0.127,0.047],[1.59,0.564],[0,0],[0,0],[0,0],[1.779,-0.308],[0,0],[0,0],[0,0],[1.371,-1.142],[0,0],[0,0],[0,0],[0.631,-1.708],[0,0],[0,0],[0,0],[-0.311,-1.78],[0,0],[0,0],[0,0],[-1.145,-1.371],[0,0],[0,0],[0,0],[-0.125,-0.047],[-0.126,-0.044]],"v":[[105.253,4.747],[100.419,3.445],[97.651,8.16],[91.588,8.111],[88.885,3.362],[83.651,4.72],[83.618,10.179],[78.347,13.166],[73.623,10.395],[69.778,14.184],[72.485,18.94],[69.421,24.162],[63.947,24.118],[62.513,29.322],[67.238,32.093],[67.2,38.151],[62.449,40.843],[63.816,46.073],[69.283,46.117],[72.28,51.386],[69.513,56.102],[73.312,59.946],[78.07,57.251],[83.302,60.32],[83.266,65.787],[83.646,65.925],[88.479,67.227],[91.245,62.513],[97.309,62.56],[100.012,67.31],[105.245,65.951],[105.279,60.493],[110.55,57.506],[115.275,60.278],[119.119,56.488],[116.412,51.731],[119.477,46.511],[124.95,46.553],[126.383,41.349],[121.659,38.579],[121.697,32.52],[126.449,29.83],[125.08,24.598],[119.616,24.555],[116.618,19.286],[119.384,14.571],[115.584,10.724],[110.827,13.421],[105.596,10.352],[105.63,4.884],[105.253,4.747]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ind":1,"ty":"sh","ks":{"a":0,"k":{"i":[[-9.941,0],[0,-9.941],[9.941,0],[0,9.941]],"o":[[9.941,0],[0,9.941],[-9.941,0],[0,-9.941]],"v":[[94.463,17.334],[112.463,35.334],[94.463,53.334],[76.463,35.334]],"c":true}},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.25,0.37,0.44,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-66.463,-5.334],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":4,"mn":"ADBE Vector Group"}],"ip":0,"op":53,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"gear2","parent":0,"ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[-360],"e":[0]},{"t":52}]},"p":{"s":true,"x":{"a":0,"k":-22.5},"y":{"a":0,"k":-2.25}},"a":{"a":0,"k":[-36,-4,0]},"s":{"a":0,"k":[75,75,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[1.982,-0.286],[0,0],[0,0],[0,0],[1.588,-1.254],[0,0],[0,0],[0,0],[0.734,-1.84],[0,0],[0,0],[0,0],[-0.285,-1.981],[0,0],[0,0],[0,0],[-1.254,-1.589],[0,0],[0,0],[0,0],[-1.839,-0.735],[0,0],[0,0],[0,0],[-1.982,0.287],[0,0],[0,0],[0,0],[-1.587,1.254],[0,0],[0,0],[0,0],[-0.734,1.838],[0,0],[0,0],[0,0],[0.287,1.982],[0,0],[0,0],[0,0],[1.255,1.588],[0,0],[0,0],[0,0],[1.838,0.734]],"o":[[0,0],[0,0],[0,0],[-2.001,-0.045],[0,0],[0,0],[0,0],[-1.737,0.951],[0,0],[0,0],[0,0],[-1.052,1.727],[0,0],[0,0],[0,0],[-0.046,2.003],[0,0],[0,0],[0,0],[0.951,1.736],[0,0],[0,0],[0,0],[1.727,1.054],[0,0],[0,0],[0,0],[2.003,0.044],[0,0],[0,0],[0,0],[1.736,-0.95],[0,0],[0,0],[0,0],[1.053,-1.726],[0,0],[0,0],[0,0],[0.044,-2.001],[0,0],[0,0],[0,0],[-0.952,-1.738],[0,0],[0,0],[0,0],[-1.727,-1.053],[-1.838,-0.734]],"v":[[43.8,-32.098],[39.776,-27.554],[33.19,-28.898],[31.27,-34.644],[25.285,-34.281],[24.075,-28.343],[17.7,-26.211],[13.157,-30.235],[8.16,-26.928],[10.083,-21.173],[5.628,-16.139],[-0.317,-17.35],[-2.993,-11.989],[1.549,-7.964],[0.207,-1.377],[-5.538,0.543],[-5.176,6.53],[0.762,7.74],[2.891,14.117],[-1.132,18.662],[2.175,23.66],[7.929,21.736],[12.96,26.192],[11.749,32.139],[17.11,34.817],[21.132,30.273],[27.718,31.613],[29.637,37.362],[35.623,36.999],[36.833,31.06],[43.207,28.929],[47.752,32.952],[52.748,29.646],[50.825,23.89],[55.281,18.856],[61.225,20.068],[63.902,14.708],[59.359,10.683],[60.701,4.096],[66.448,2.174],[66.084,-3.812],[60.147,-5.023],[58.017,-11.399],[62.04,-15.943],[58.733,-20.942],[52.979,-19.019],[47.948,-23.475],[49.159,-29.421],[43.8,-32.098]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ind":1,"ty":"sh","ks":{"a":0,"k":{"i":[[-11.046,0],[0,-11.046],[11.046,0],[0,11.046]],"o":[[11.046,0],[0,11.046],[-11.046,0],[0,-11.046]],"v":[[30.463,-18.666],[50.463,1.334],[30.463,21.334],[10.463,1.334]],"c":true}},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.89,0.34,0.3,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-66.463,-5.334],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":4,"mn":"ADBE Vector Group"}],"ip":0,"op":53,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"gear1","parent":0,"ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[360],"e":[0]},{"t":52}]},"p":{"s":true,"x":{"a":0,"k":17.063},"y":{"a":0,"k":-23.437}},"a":{"a":0,"k":[24,-34,0]},"s":{"a":0,"k":[75,75,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[1.357,0.446],[0,0],[0,0],[0,0],[1.525,-0.316],[0,0],[0,0],[0,0],[1.17,-1.05],[0,0],[0,0],[0,0],[0.479,-1.462],[0,0],[0,0],[0,0],[-0.322,-1.524],[0,0],[0,0],[0,0],[-1.053,-1.172],[0,0],[0,0],[0,0],[-0.103,-0.053],[-1.358,-0.446],[0,0],[0,0],[0,0],[-1.524,0.318],[0,0],[0,0],[0,0],[-1.169,1.05],[0,0],[0,0],[0,0],[-0.478,1.463],[0,0],[0,0],[0,0],[0.322,1.525],[0,0],[0,0],[0,0],[1.053,1.174],[0,0],[0,0],[0,0],[0.102,0.053]],"o":[[-1.298,-0.664],[0,0],[0,0],[0,0],[-1.557,0.062],[0,0],[0,0],[0,0],[-1.301,0.82],[0,0],[0,0],[0,0],[-0.731,1.392],[0,0],[0,0],[0,0],[0.065,1.557],[0,0],[0,0],[0,0],[0.826,1.303],[0,0],[0,0],[0,0],[0.103,0.055],[1.297,0.663],[0,0],[0,0],[0,0],[1.556,-0.062],[0,0],[0,0],[0,0],[1.301,-0.821],[0,0],[0,0],[0,0],[0.732,-1.391],[0,0],[0,0],[0,0],[-0.066,-1.557],[0,0],[0,0],[0,0],[-0.826,-1.304],[0,0],[0,0],[0,0],[-0.102,-0.054],[-0.103,-0.052]],"v":[[103.129,-53.638],[99.14,-55.302],[96.242,-51.581],[91.061,-52.312],[89.282,-56.683],[84.652,-56.115],[84.01,-51.446],[79.164,-49.487],[75.435,-52.395],[71.719,-49.589],[73.501,-45.211],[70.293,-41.09],[65.615,-41.749],[63.803,-37.459],[67.534,-34.55],[66.821,-29.369],[62.454,-27.604],[63.036,-22.972],[67.707,-22.315],[69.68,-17.464],[66.782,-13.743],[69.6,-10.021],[73.973,-11.788],[78.105,-8.567],[77.46,-3.891],[77.769,-3.73],[81.757,-2.067],[84.653,-5.788],[89.836,-5.059],[91.615,-0.687],[96.244,-1.256],[96.887,-5.923],[101.731,-7.882],[105.462,-4.973],[109.177,-7.78],[107.396,-12.158],[110.604,-16.279],[115.282,-15.621],[117.092,-19.912],[113.363,-22.82],[114.076,-28.001],[118.443,-29.765],[117.86,-34.397],[113.19,-35.054],[111.218,-39.904],[114.114,-43.626],[111.296,-47.35],[106.923,-45.582],[102.792,-48.802],[103.436,-53.479],[103.129,-53.638]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ind":1,"ty":"sh","ks":{"a":0,"k":{"i":[[-8.837,0],[0,-8.837],[8.836,0],[0,8.837]],"o":[[8.836,0],[0,8.837],[-8.837,0],[0,-8.837]],"v":[[90.463,-44.666],[106.463,-28.666],[90.463,-12.666],[74.463,-28.666]],"c":true}},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.39,0.5,0.56,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-66.463,-5.334],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":4,"mn":"ADBE Vector Group"}],"ip":0,"op":53,"st":0,"bm":0,"sr":1}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/gears_or_settings.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/gears_or_settings.json deleted file mode 100644 index 668465fa..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/gears_or_settings.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.1","fr":25,"ip":0,"op":29,"w":261,"h":299,"nm":"Comp 1","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"gear Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[91],"e":[0]},{"t":29}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[65.543,243.492,0],"e":[66.114,246.141,0],"to":[0.63389188051224,0.43371549248695,0],"ti":[-0.59447288513184,-1.12922275066376,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":1,"s":[66.114,246.141,0],"e":[66.79,248.814,0],"to":[0.41561776399612,0.78948098421097,0],"ti":[-0.45528426766396,-1.02199518680573,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":2,"s":[66.79,248.814,0],"e":[67.639,251.325,0],"to":[0.3837648332119,0.86145251989365,0],"ti":[-0.43365067243576,-0.97296315431595,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":3,"s":[67.639,251.325,0],"e":[68.655,253.812,0],"to":[0.39388379454613,0.88373994827271,0],"ti":[-0.45162639021873,-0.9361160993576,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":4,"s":[68.655,253.812,0],"e":[69.789,256.264,0],"to":[0.42802980542183,0.8872058391571,0],"ti":[-0.49433445930481,-0.91032445430756,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":5,"s":[69.789,256.264,0],"e":[71.114,258.581,0],"to":[0.48347863554955,0.89033323526382,0],"ti":[-0.56523299217224,-0.93818730115891,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":6,"s":[71.114,258.581,0],"e":[72.489,260.831,0],"to":[2.14385366439819,3.55841970443726,0],"ti":[-0.56523299217224,-0.93818730115891,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":7,"s":[72.489,260.831,0],"e":[74.039,263.038,0],"to":[0.66254264116287,1.09970414638519,0],"ti":[-0.56497228145599,-0.77992361783981,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":8,"s":[74.039,263.038,0],"e":[75.676,265.237,0],"to":[0.67640376091003,0.93375080823898,0],"ti":[-0.79516309499741,-0.82775580883026,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":9,"s":[75.676,265.237,0],"e":[77.505,267.325,0],"to":[0.68977969884872,0.71805286407471,0],"ti":[-0.97716957330704,-0.82866209745407,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":10,"s":[77.505,267.325,0],"e":[79.389,269.272,0],"to":[0.76325196027756,0.64725506305695,0],"ti":[-0.82630759477615,-0.56484717130661,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":11,"s":[79.389,269.272,0],"e":[81.407,271.087,0],"to":[0.83111488819122,0.56813335418701,0],"ti":[-0.88650888204575,-0.55724161863327,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":12,"s":[81.407,271.087,0],"e":[83.475,272.848,0],"to":[0.85700911283493,0.53869867324829,0],"ti":[-0.89429974555969,-0.50983655452728,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":13,"s":[83.475,272.848,0],"e":[85.579,274.422,0],"to":[0.88868284225464,0.50663435459137,0],"ti":[-0.92676615715027,-0.45997801423073,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":14,"s":[85.579,274.422,0],"e":[87.872,275.881,0],"to":[0.92115861177444,0.45719486474991,0],"ti":[-0.93775117397308,-0.39359641075134,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":15,"s":[87.872,275.881,0],"e":[90.159,277.311,0],"to":[0.95279586315155,0.39991104602814,0],"ti":[-1.10174834728241,-0.50261902809143,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":16,"s":[90.159,277.311,0],"e":[92.506,278.622,0],"to":[1.1385383605957,0.51940268278122,0],"ti":[-0.95087832212448,-0.2986201941967,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[92.506,278.622,0],"e":[95.023,279.586,0],"to":[0.99073857069016,0.31113818287849,0],"ti":[-0.93247872591019,-0.34245449304581,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":18,"s":[95.023,279.586,0],"e":[97.558,280.658,0],"to":[0.93090575933456,0.34187683463097,0],"ti":[-0.92517024278641,-0.03547479957342,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":19,"s":[97.558,280.658,0],"e":[100.144,281.54,0],"to":[0.95009499788284,0.03643051534891,0],"ti":[-0.93971288204193,-0.2205313295126,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[100.144,281.54,0],"e":[102.775,282.08,0],"to":[1.01888990402222,0.23911255598068,0],"ti":[-1.10344433784485,-0.17690135538578,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":21,"s":[102.775,282.08,0],"e":[105.473,282.795,0],"to":[1.20659899711609,0.19343885779381,0],"ti":[-0.9462838768959,0.08564107865095,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[105.473,282.795,0],"e":[108.081,283.204,0],"to":[1.06814050674438,-0.09666941314936,0],"ti":[-0.91514319181442,-0.08660132437944,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":23,"s":[108.081,283.204,0],"e":[110.765,283.459,0],"to":[1.16727662086487,0.11046107113361,0],"ti":[-0.86166793107986,0.15333108603954,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":24,"s":[110.765,283.459,0],"e":[113.543,283.492,0],"to":[1.8156601190567,-0.32309100031853,0],"ti":[-0.0203275885433,-0.0203275885433,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":25,"s":[113.543,283.492,0],"e":[116.293,283.367,0],"to":[0.02718277275562,0.02718277275562,0],"ti":[-0.04166666790843,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":26,"s":[116.293,283.367,0],"e":[118.918,283.117,0],"to":[0.04166666790843,0,0],"ti":[0.04166666790843,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":27,"s":[118.918,283.117,0],"e":[121.668,282.867,0],"to":[-0.04166666790843,0,0],"ti":[0.04166666790843,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":28,"s":[121.668,282.867,0],"e":[124.168,282.242,0],"to":[-0.04166666790843,0,0],"ti":[0.04166666790843,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":29,"s":[124.168,282.242,0],"e":[124.168,282.367,0],"to":[-0.04166666790843,0,0],"ti":[0.04166666790843,0,0]},{"t":30}],"ix":2},"a":{"a":0,"k":[144,280,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[16.838,0],[0,16.837],[-16.837,0],[0,-16.839]],"o":[[-16.837,0],[0,-16.839],[16.838,0],[0,16.837]],"v":[[0,30.48],[-30.48,-0.001],[0,-30.48],[30.48,-0.001]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.356,1.169],[0,0],[0,0],[0,0],[0.889,0.829],[0,0],[0,0],[0,0],[1.195,0.278],[0,0],[0,0],[0,0],[1.169,-0.347],[0,0],[0,0],[0,0],[0.823,-0.892],[0,0],[0,0],[0,0],[0.286,-1.197],[0,0],[0,0],[0,0],[-0.357,-1.165],[0,0],[0,0],[0,0],[-0.881,-0.832],[0,0],[0,0],[0,0],[-1.197,-0.277],[0,0],[0,0],[0,0],[-1.169,0.356],[0,0],[0,0],[0,0],[-0.829,0.883],[0,0],[0,0],[0,0],[-0.277,1.197],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[-0.811,-0.911],[0,0],[0,0],[0,0],[-1.157,-0.377],[0,0],[0,0],[0,0],[-1.197,0.25],[0,0],[0,0],[0,0],[-0.9,0.812],[0,0],[0,0],[0,0],[-0.376,1.159],[0,0],[0,0],[0,0],[0.247,1.198],[0,0],[0,0],[0,0],[0.813,0.901],[0,0],[0,0],[0,0],[1.157,0.376],[0,0],[0,0],[0,0],[1.205,-0.257],[0,0],[0,0],[0,0],[0.911,-0.812],[0,0],[0,0],[0,0],[0.377,-1.165],[0,0],[0,0],[0,0],[-0.25,-1.208]],"v":[[40.709,-12.329],[44.006,-19.519],[39.294,-27.681],[31.648,-28.402],[29.097,-31.015],[28.354,-38.909],[20.181,-43.617],[13.217,-40.431],[9.676,-41.423],[5.097,-47.871],[-4.333,-47.871],[-8.774,-41.622],[-12.337,-40.718],[-19.529,-44.005],[-27.688,-39.295],[-28.411,-31.648],[-31.014,-29.094],[-38.91,-28.353],[-43.626,-20.182],[-40.442,-13.217],[-41.431,-9.676],[-47.871,-5.094],[-47.871,4.334],[-41.628,8.773],[-40.719,12.334],[-44.013,19.529],[-39.293,27.689],[-31.647,28.412],[-29.104,31.015],[-28.354,38.908],[-20.192,43.626],[-13.225,40.442],[-9.686,41.432],[-5.104,47.871],[4.334,47.871],[8.766,41.629],[12.327,40.719],[19.519,44.014],[27.681,39.293],[28.402,31.648],[31.013,29.102],[38.909,28.351],[43.618,20.181],[40.432,13.224],[41.422,9.686],[47.872,5.105],[47.872,-4.334],[41.62,-8.764]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[133.701,231.739],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":29,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"01","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[415.5,245,0],"ix":2},"a":{"a":0,"k":[360,300,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":720,"h":600,"ip":0,"op":29,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"01","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[345.5,185,0],"ix":2},"a":{"a":0,"k":[360,300,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":720,"h":600,"ip":0,"op":29,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/glow_loading.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/glow_loading.json deleted file mode 100644 index 3cbcc056..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/glow_loading.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.6.8","fr":29.9700012207031,"ip":0,"op":69.0000028104276,"w":256,"h":256,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Glow ball","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[360]},{"t":69.0000028104276}]},"p":{"a":0,"k":[127.984,127.969,0]},"a":{"a":0,"k":[-0.182,32.385,0]},"s":{"a":0,"k":[132,132,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[14.125,14.125]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"fl","c":{"a":0,"k":[0.1635217,0.8509804,0.8105415,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-0.063,1.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":300.00001221925,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 8","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":315},"p":{"a":0,"k":[127.984,127.969,0]},"a":{"a":0,"k":[-0.182,32.385,0]},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":56,"s":[132,132,100],"e":[145,145,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":59,"s":[145,145,100],"e":[132,132,100]},{"t":63.0000025660426}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[14.125,14.125]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0.1647059,0.6313726,0.8509804,1],"e":[0.1647059,0.6313726,0.8509804,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0.1647059,0.6313726,0.8509804,1],"e":[0.1647059,0.8509804,0.8117647,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":62,"s":[0.1647059,0.8509804,0.8117647,1],"e":[0.1647059,0.6313726,0.8509804,1]},{"t":69.0000028104276}]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-0.063,1.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":300.00001221925,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 7","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":270},"p":{"a":0,"k":[127.984,127.969,0]},"a":{"a":0,"k":[-0.182,32.385,0]},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":48,"s":[132,132,100],"e":[145,145,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":51,"s":[145,145,100],"e":[132,132,100]},{"t":55.0000022401959}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[14.125,14.125]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0.1647059,0.6313726,0.8509804,1],"e":[0.1647059,0.6745098,0.8431373,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":47,"s":[0.1647059,0.6745098,0.8431373,1],"e":[0.1647059,0.8509804,0.8117647,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":58,"s":[0.1647059,0.8509804,0.8117647,1],"e":[0.1647059,0.6313726,0.8509804,1]},{"t":69.0000028104276}]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-0.063,1.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":300.00001221925,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 6","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":225},"p":{"a":0,"k":[127.984,127.969,0]},"a":{"a":0,"k":[-0.182,32.385,0]},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":39,"s":[132,132,100],"e":[145,145,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":42,"s":[145,145,100],"e":[132,132,100]},{"t":46.0000018736184}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[14.125,14.125]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0.1647059,0.6313726,0.8509804,1],"e":[0.1647059,0.6313726,0.8509804,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":37,"s":[0.1647059,0.6313726,0.8509804,1],"e":[0.1647059,0.8509804,0.8117647,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":43,"s":[0.1647059,0.8509804,0.8117647,1],"e":[0.1647059,0.6313726,0.8509804,1]},{"t":48.0000019550801}]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-0.063,1.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":300.00001221925,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 5","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":180},"p":{"a":0,"k":[127.984,127.969,0]},"a":{"a":0,"k":[-0.182,32.385,0]},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":31,"s":[132,132,100],"e":[145,145,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":34,"s":[145,145,100],"e":[132,132,100]},{"t":38.0000015477717}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[14.125,14.125]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0.1647059,0.6313726,0.8509804,1],"e":[0.1647059,0.6313726,0.8509804,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":26,"s":[0.1647059,0.6313726,0.8509804,1],"e":[0.1647059,0.8509804,0.8117647,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":38,"s":[0.1647059,0.8509804,0.8117647,1],"e":[0.1647059,0.6313726,0.8509804,1]},{"t":42.0000017106951}]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-0.063,1.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":300.00001221925,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 4","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":135},"p":{"a":0,"k":[127.984,127.969,0]},"a":{"a":0,"k":[-0.182,32.385,0]},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":23,"s":[132,132,100],"e":[145,145,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":26,"s":[145,145,100],"e":[132,132,100]},{"t":30.0000012219251}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[14.125,14.125]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0.1647059,0.6313726,0.8509804,1],"e":[0.1647059,0.8509804,0.8117647,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":30,"s":[0.1647059,0.8509804,0.8117647,1],"e":[0.1647059,0.6313726,0.8509804,1]},{"t":38.0000015477717}]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-0.063,1.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":300.00001221925,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 3","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":90},"p":{"a":0,"k":[127.984,127.969,0]},"a":{"a":0,"k":[-0.182,32.385,0]},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":14,"s":[132,132,100],"e":[145,145,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":17,"s":[145,145,100],"e":[132,132,100]},{"t":21.0000008553475}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[14.125,14.125]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0.1647059,0.6313726,0.8509804,1],"e":[0.1647059,0.8509804,0.8117647,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":22,"s":[0.1647059,0.8509804,0.8117647,1],"e":[0.1647059,0.6313726,0.8509804,1]},{"t":28.0000011404634}]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-0.063,1.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":300.00001221925,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":8,"ty":4,"nm":"Shape Layer 2","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":45},"p":{"a":0,"k":[127.984,127.969,0]},"a":{"a":0,"k":[-0.182,32.385,0]},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":7,"s":[132,132,100],"e":[145,145,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":10,"s":[145,145,100],"e":[132,132,100]},{"t":14.0000005702317}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[14.125,14.125]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0.1647059,0.6313726,0.8509804,1],"e":[0.1647059,0.8509804,0.8117647,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":16,"s":[0.1647059,0.8509804,0.8117647,1],"e":[0.1647059,0.6313726,0.8509804,1]},{"t":22.0000008960784}]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-0.063,1.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":300.00001221925,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":9,"ty":4,"nm":"Shape Layer 1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[127.984,127.969,0]},"a":{"a":0,"k":[-0.182,32.385,0]},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[132,132,100],"e":[145,145,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":3,"s":[145,145,100],"e":[132,132,100]},{"t":7.00000028511585}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[14.125,14.125]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0.1647059,0.6313726,0.8509804,1],"e":[0.1647059,0.8509804,0.8117647,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":5,"s":[0.1647059,0.8509804,0.8117647,1],"e":[0.1647059,0.6313726,0.8509804,1]},{"t":16.0000006516934}]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-0.063,1.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":300.00001221925,"st":0,"bm":0,"sr":1}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/gradient_animated_background.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/gradient_animated_background.json deleted file mode 100644 index f9ce52d4..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/gradient_animated_background.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.6.10","fr":15,"ip":0,"op":155,"w":1080,"h":1920,"nm":"background","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[540,960,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[1160,880]},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect"},{"ty":"st","c":{"a":0,"k":[0.9960784,0.7843137,0.145098,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":6},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"gf","o":{"a":0,"k":100},"r":1,"g":{"p":3,"k":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[0,0.511,0.89,0.283,0.5,0.334,0.873,0.583,1,0.156,0.857,0.882],"e":[0,0.726,0.283,0.89,0.5,0.441,0.356,0.886,1,0.156,0.429,0.882]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":31,"s":[0,0.726,0.283,0.89,0.5,0.441,0.356,0.886,1,0.156,0.429,0.882],"e":[0,0.89,0.283,0.283,0.5,0.886,0.553,0.219,1,0.882,0.823,0.156]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":61,"s":[0,0.89,0.283,0.283,0.5,0.886,0.553,0.219,1,0.882,0.823,0.156],"e":[0,0,0.312,0.737,0.5,0.078,0.597,0.754,1,0.156,0.882,0.771]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":91,"s":[0,0,0.312,0.737,0.5,0.078,0.597,0.754,1,0.156,0.882,0.771],"e":[0,0.51,0.89,0.282,0.5,0.333,0.873,0.582,1,0.157,0.855,0.882]},{"t":120}]}},"s":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[-430.769,-404.573],"e":[23.726,-364.48],"to":[75.7491683959961,6.68213844299316],"ti":[-123.915840148926,-8.51547145843506]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":31,"s":[23.726,-364.48],"e":[312.726,-353.48],"to":[123.915840148926,8.51547145843506],"ti":[-1.00208830833435,-1.83333337306976]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":61,"s":[312.726,-353.48],"e":[29.739,-353.48],"to":[1.00208830833435,1.83333337306976],"ti":[120.055290222168,0.60746711492538]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":91,"s":[29.739,-353.48],"e":[-407.606,-357.125],"to":[-120.055290222168,-0.60746711492538],"ti":[72.8907089233398,0.60746711492538]},{"t":120}]},"e":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[374.412,342.611],"e":[22.822,357.191],"to":[-58.5984153747559,2.42986845970154],"ti":[132.520950317383,-7.89707231521606]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":31,"s":[22.822,357.191],"e":[-420.714,389.994],"to":[-132.520950317383,7.89707231521606],"ti":[-4.68509674072266,-7.89707231521606]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":61,"s":[-420.714,389.994],"e":[50.932,404.573],"to":[4.68509674072266,7.89707231521606],"ti":[-132.918350219727,4.25226974487305]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":91,"s":[50.932,404.573],"e":[376.797,364.48],"to":[132.918350219727,-4.25226974487305],"ti":[-54.3107261657715,6.68213844299316]},{"t":120}]},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[93.29,219.491],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":155,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":1,"nm":"Deep Red Solid 1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[540,960,0]},"a":{"a":0,"k":[540,960,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"sw":1080,"sh":1920,"sc":"#be2a2a","ip":0,"op":155,"st":0,"bm":0,"sr":1}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/gradient_sleepy_loader.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/gradient_sleepy_loader.json deleted file mode 100644 index 2881125f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/gradient_sleepy_loader.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.8","fr":23.9759979248047,"ip":0,"op":240.999979140721,"w":300,"h":300,"nm":"SynthesisProto_Loader","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Layer 2 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[-180],"e":[180]},{"t":239.999979227274}],"ix":10},"p":{"a":0,"k":[150.125,150,0],"ix":2},"a":{"a":0,"k":[533,533,0],"ix":1},"s":{"a":0,"k":[16,16,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[65.74,-27.805],[48.897,-48.895],[26.837,-63.449],[0,-71.877],[-27.805,-65.739],[-48.894,-48.896],[-63.449,-26.837],[-71.878,0],[-65.739,27.805],[-48.895,48.895],[-26.837,63.449],[0,71.878],[27.805,65.739],[48.896,48.896],[63.449,26.837],[71.877,0]],"o":[[-63.449,26.837],[-48.894,48.896],[-27.805,65.739],[0,71.878],[26.837,63.449],[48.897,48.895],[65.74,27.805],[71.877,0],[63.449,-26.837],[48.896,-48.896],[27.805,-65.739],[0,-71.877],[-26.837,-63.449],[-48.895,-48.895],[-65.739,-27.805],[-71.878,0]],"v":[[-207.395,-490.833],[-376.703,-376.703],[-490.833,-207.394],[-532.735,0],[-490.833,207.393],[-376.703,376.702],[-207.395,490.833],[0,532.735],[207.394,490.833],[376.702,376.702],[490.833,207.393],[532.738,0],[490.833,-207.394],[376.702,-376.703],[207.394,-490.833],[0,-532.738]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[65.201,65.2],[0,92.206],[-65.199,65.2],[-92.207,0],[-65.2,-65.2],[0,-92.206],[65.2,-65.201],[92.206,0]],"o":[[-65.199,-65.201],[0,-92.206],[65.201,-65.2],[92.206,0],[65.2,65.2],[0,92.206],[-65.2,65.2],[-92.207,0]],"v":[[-244.095,244.094],[-345.202,0],[-244.095,-244.094],[0,-345.202],[244.095,-244.094],[345.202,0],[244.095,244.094],[0,345.202]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"g":{"p":3,"k":{"a":0,"k":[0,0.133,0.063,0.282,0.5,0.386,0.257,0.459,1,0.639,0.451,0.635],"ix":9}},"s":{"a":0,"k":[661,0],"ix":5},"e":{"a":0,"k":[-690,0],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[533,533],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":720.999937595269,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Layer 1 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[180],"e":[-180]},{"t":239.999979227274}],"ix":10},"p":{"a":0,"k":[150.125,150,0],"ix":2},"a":{"a":0,"k":[726,726,0],"ix":1},"s":{"a":0,"k":[16,16,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-400.378],[-400.379,0],[0,400.378],[400.378,0]],"o":[[0,400.378],[400.378,0],[0,-400.378],[-400.379,0]],"v":[[-724.948,0],[0,724.949],[724.948,0],[0,-724.949]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"g":{"p":3,"k":{"a":0,"k":[0,0.133,0.063,0.282,0.5,0.386,0.257,0.459,1,0.639,0.451,0.635],"ix":9}},"s":{"a":0,"k":[200,0],"ix":5},"e":{"a":0,"k":[-608,0],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[726,726],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":180,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":720.999937595269,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/happy.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/happy.json deleted file mode 100644 index 2558e31b..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/happy.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.17","fr":25,"ip":0,"op":79,"w":1100,"h":1072,"nm":"feliz","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"emoticon feliz","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[561,549,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[300,300,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Degradado de 4 colores","np":16,"mn":"ADBE 4ColorGradient","ix":1,"en":1,"ef":[{"ty":6,"nm":"Posiciones y colores","mn":"ADBE 4ColorGradient-0011","ix":1,"v":0},{"ty":3,"nm":"Punto 1","mn":"ADBE 4ColorGradient-0001","ix":2,"v":{"a":0,"k":[70.469,58.563],"ix":2}},{"ty":2,"nm":"Color 1","mn":"ADBE 4ColorGradient-0002","ix":3,"v":{"a":0,"k":[0.937254905701,0.937254905701,0.623529434204,1],"ix":3}},{"ty":3,"nm":"Punto 2","mn":"ADBE 4ColorGradient-0003","ix":4,"v":{"a":0,"k":[970.521,70.474],"ix":4}},{"ty":2,"nm":"Color 2","mn":"ADBE 4ColorGradient-0004","ix":5,"v":{"a":0,"k":[0.937254905701,0.937254905701,0.623529434204,1],"ix":5}},{"ty":3,"nm":"Punto 3","mn":"ADBE 4ColorGradient-0005","ix":6,"v":{"a":0,"k":[110,964.8],"ix":6}},{"ty":2,"nm":"Color 3","mn":"ADBE 4ColorGradient-0006","ix":7,"v":{"a":0,"k":[0.937254905701,0.937254905701,0.623529434204,1],"ix":7}},{"ty":3,"nm":"Punto 4","mn":"ADBE 4ColorGradient-0007","ix":8,"v":{"a":0,"k":[990,964.8],"ix":8}},{"ty":2,"nm":"Color 4","mn":"ADBE 4ColorGradient-0008","ix":9,"v":{"a":0,"k":[1,0.78823530674,0.278431385756,1],"ix":9}},{"ty":6,"nm":"Color 4","mn":"ADBE 4ColorGradient-0012","ix":10,"v":0},{"ty":0,"nm":"Fusionar","mn":"ADBE 4ColorGradient-0009","ix":11,"v":{"a":0,"k":100,"ix":11}},{"ty":0,"nm":"Variación","mn":"ADBE 4ColorGradient-0010","ix":12,"v":{"a":0,"k":0,"ix":12}},{"ty":0,"nm":"Opacidad","mn":"ADBE 4ColorGradient-0013","ix":13,"v":{"a":0,"k":100,"ix":13}},{"ty":7,"nm":"Modo de fusión","mn":"ADBE 4ColorGradient-0014","ix":14,"v":{"a":0,"k":5,"ix":14}}]}],"shapes":[{"ty":"gr","it":[{"ty":"fl","c":{"a":0,"k":[0,0.894117474556,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"d":1,"ty":"el","s":{"a":0,"k":[115,115],"ix":2},"p":{"a":0,"k":[39,-37],"ix":3},"nm":"Trazado elíptico 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tm","s":{"a":0,"k":32,"ix":1},"e":{"a":0,"k":0,"ix":2},"o":{"a":0,"k":-187,"ix":3},"m":1,"ix":3,"nm":"Recortar trazados 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.011764706112,0.010841984302,0.010841984302,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":8,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Trazo 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[6,99],"e":[63,88],"to":[9.5,-1.83333337306976],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":31.699,"s":[63,88],"e":[6,99],"to":[0,0],"ti":[9.5,3]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":45.88,"s":[6,99],"e":[6,70],"to":[-9.5,-3],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":50.884,"s":[6,70],"e":[6,99],"to":[0,0],"ti":[7.83333349227905,-2.83333325386047]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":55.055,"s":[6,99],"e":[-41,87],"to":[-7.83333349227905,2.83333325386047],"ti":[7.83333349227905,2]},{"t":65.8990478108317}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[100,100],"e":[100,100]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":45.88,"s":[100,100],"e":[146,146]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":50.884,"s":[146,146],"e":[100,100]},{"t":55.0552978108317}],"ix":3},"r":{"a":0,"k":-51.614,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"boca 2","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":45.88,"s":[54.7,80.409],"e":[54.7,0]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":50.884,"s":[54.7,0],"e":[54.7,76]},{"t":55.0552978108317}],"ix":2},"p":{"a":0,"k":[-51,0],"ix":3},"nm":"Trazado elíptico 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":45.88,"s":[54.7,80.409],"e":[54.7,0]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":50.884,"s":[54.7,0],"e":[54.7,76]},{"t":55.0552978108317}],"ix":2},"p":{"a":0,"k":[51,0],"ix":3},"nm":"Trazado elíptico 2","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.027450980619,0.026697425172,0.026697425172,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 2","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"fl","c":{"a":0,"k":[0.007843137255,0.00719723234,0.00719723234,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.171},"n":"0p667_1_0p167_0p171","t":5.005,"s":[0,-26],"e":[71,-26],"to":[11.8333330154419,0],"ti":[0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":28.362,"s":[71,-26],"e":[0,-26],"to":[0,0],"ti":[22.1666660308838,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":50.884,"s":[0,-26],"e":[-62,-26],"to":[-22.1666660308838,0],"ti":[10.3333330154419,0]},{"t":74.2408446858317}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0]},"n":["0p667_1_0p167_0p167","0p667_1_0p167_0"],"t":5.005,"s":[100,100],"e":[74,100]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":28.362,"s":[74,100],"e":[100,100]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":50.884,"s":[100,100],"e":[87,100]},{"t":74.2408446858317}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"ojos","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Trazado elíptico 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":15,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Recortar trazados 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.011764706112,0.010841984302,0.010841984302,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":8,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Trazo 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[52,-36],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":-8,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"ceja2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Trazado elíptico 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":15,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Recortar trazados 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.011764706112,0.010841984302,0.010841984302,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":8,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Trazo 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-52,-36],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":-45,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"ceja1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.171},"n":"0p667_1_0p167_0p171","t":5.005,"s":[0,0],"e":[73,0],"to":[12.1666669845581,0],"ti":[0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":28.362,"s":[73,0],"e":[0,0],"to":[0,0],"ti":[23.3333339691162,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":50.884,"s":[0,0],"e":[-67,0],"to":[-23.3333339691162,0],"ti":[11.1666669845581,0]},{"t":74.2408446858317}],"ix":2},"a":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":45.88,"s":[0,0],"e":[0,-15],"to":[0,-2.5],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":50.884,"s":[0,-15],"e":[0,0],"to":[0,0],"ti":[0,-2.5]},{"t":55.0552978108317}],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0]},"n":["0p667_1_0p167_0p167","0p667_1_0p167_0"],"t":5.005,"s":[100,100],"e":[70,100]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":28.362,"s":[70,100],"e":[100,100]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":50.884,"s":[100,100],"e":[77,100]},{"t":74.2408446858317}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"cejas","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[300,300],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Trazado elíptico 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.960784313725,0.847058823529,0.505882352941,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"cara","np":2,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":-1.66833500166833,"op":248.581915248582,"st":-1.66833500166833,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/heart.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/heart.json deleted file mode 100644 index 08b20396..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/heart.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.7","fr":29.9700012207031,"ip":0,"op":24.00000097754,"w":100,"h":100,"nm":"heart","ddd":0,"assets":[{"id":"comp_4","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Shape Layer 2 Comp 2","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2},"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":100,"h":100,"ip":0,"op":900.000036657751,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"Shape Layer 2 Comp 2","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":130,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2},"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":100,"h":100,"ip":0,"op":900.000036657751,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"Shape Layer 2 Comp 2","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2},"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":100,"h":100,"ip":0,"op":900.000036657751,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"Shape Layer 2 Comp 2","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":45,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2},"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":100,"h":100,"ip":0,"op":900.000036657751,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"Shape Layer 2 Comp 2","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-135,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2},"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":100,"h":100,"ip":0,"op":900.000036657751,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"Shape Layer 2 Comp 2","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2},"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":100,"h":100,"ip":0,"op":900.000036657751,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"Shape Layer 2 Comp 2","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-45,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2},"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":100,"h":100,"ip":0,"op":900.000036657751,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"Shape Layer 2 Comp 2","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2},"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":100,"h":100,"ip":0,"op":900.000036657751,"st":0,"bm":0}]},{"id":"comp_5","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0.281]},"n":["0p667_1_0p333_0p281"],"t":3,"s":[0],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":9,"s":[100],"e":[0]},{"t":17.0000006924242}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":0.567},"o":{"x":0.333,"y":0.406},"n":"0p667_0p567_0p333_0p406","t":3,"s":[39.878,39.582,0],"e":[39.878,22.253,0],"to":[0,-0.83333331346512,0],"ti":[0,2.48720121383667,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0.5},"n":"0p667_1_0p333_0p5","t":9,"s":[39.878,22.253,0],"e":[39.878,2.25,0],"to":[0,-8.33440494537354,0],"ti":[0,3.3337619304657,0]},{"t":17.0000006924242}],"ix":2},"a":{"a":0,"k":[-0.122,-27.75,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[15.897,15.897,-17.409]},"o":{"x":[0.333,0.333,0.333],"y":[-44.172,-44.172,107.618]},"n":["0p667_15p897_0p333_-44p172","0p667_15p897_0p333_-44p172","0p667_-17p409_0p333_107p618"],"t":3,"s":[78.68,78.68,100],"e":[78,78,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[-0.562,-0.562,24.545]},"n":["0p667_1_0p333_-0p562","0p667_1_0p333_-0p562","0p667_1_0p333_24p545"],"t":9,"s":[78,78,100],"e":[54,54,100]},{"t":17.0000006924242}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[6.66,6.66],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.909803921569,0.18431372549,0.56862745098,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-0.17,-26.594],"ix":2},"a":{"a":0,"k":[0,1.076],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900.000036657751,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0.281]},"n":["0p667_1_0p333_0p281"],"t":0,"s":[0],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":6,"s":[100],"e":[0]},{"t":17.0000006924242}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":0.567},"o":{"x":0.333,"y":0.406},"n":"0p667_0p567_0p333_0p406","t":0,"s":[49.878,39.582,0],"e":[49.878,22.253,0],"to":[0,-2.35414934158325,0],"ti":[0,2.48720121383667,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0.687},"n":"0p667_1_0p333_0p687","t":6,"s":[49.878,22.253,0],"e":[49.878,2.25,0],"to":[0,-8.33440494537354,0],"ti":[0,3.3337619304657,0]},{"t":17.0000006924242}],"ix":2},"a":{"a":0,"k":[-0.122,-27.75,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[15.897,15.897,-17.409]},"o":{"x":[0.333,0.333,0.333],"y":[-44.172,-44.172,107.618]},"n":["0p667_15p897_0p333_-44p172","0p667_15p897_0p333_-44p172","0p667_-17p409_0p333_107p618"],"t":0,"s":[78.68,78.68,100],"e":[78,78,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[-0.773,-0.773,33.75]},"n":["0p667_1_0p333_-0p773","0p667_1_0p333_-0p773","0p667_1_0p333_33p75"],"t":6,"s":[78,78,100],"e":[54,54,100]},{"t":17.0000006924242}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[6.66,6.66],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.964705882353,0.309803921569,0.4,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-0.17,-26.594],"ix":2},"a":{"a":0,"k":[0,1.076],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900.000036657751,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0.281]},"n":["0p667_1_0p333_0p281"],"t":5,"s":[0],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":11,"s":[100],"e":[0]},{"t":19.0000007738859}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":0.567},"o":{"x":0.333,"y":0.406},"n":"0p667_0p567_0p333_0p406","t":5,"s":[59.878,39.582,0],"e":[59.878,22.253,0],"to":[0,-2.35414934158325,0],"ti":[0,2.48720121383667,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0.5},"n":"0p667_1_0p333_0p5","t":11,"s":[59.878,22.253,0],"e":[59.878,2.25,0],"to":[0,-8.33440494537354,0],"ti":[0,3.3337619304657,0]},{"t":19.0000007738859}],"ix":2},"a":{"a":0,"k":[-0.122,-27.75,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[15.897,15.897,-17.409]},"o":{"x":[0.333,0.333,0.333],"y":[-44.172,-44.172,107.618]},"n":["0p667_15p897_0p333_-44p172","0p667_15p897_0p333_-44p172","0p667_-17p409_0p333_107p618"],"t":5,"s":[78.68,78.68,100],"e":[78,78,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[-0.562,-0.562,24.545]},"n":["0p667_1_0p333_-0p562","0p667_1_0p333_-0p562","0p667_1_0p333_24p545"],"t":11,"s":[78,78,100],"e":[54,54,100]},{"t":19.0000007738859}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[6.66,6.66],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.868822583965,0.051056981554,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-0.17,-26.594],"ix":2},"a":{"a":0,"k":[0,1.076],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":5.00000020365417,"op":905.000036861406,"st":5.00000020365417,"bm":0}]}],"layers":[{"ddd":0,"ind":3,"ty":4,"nm":"Layer 2 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50.085,49.972,0],"ix":2},"a":{"a":0,"k":[20.392,17.022,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.486,0.486,0.333],"y":[0,0,0]},"n":["0p667_1_0p486_0","0p667_1_0p486_0","0p667_1_0p333_0"],"t":0,"s":[0,0,100],"e":[119,119,100]},{"i":{"x":[0.576,0.576,0.667],"y":[1,1,1]},"o":{"x":[0.439,0.439,0.333],"y":[0,0,0]},"n":["0p576_1_0p439_0","0p576_1_0p439_0","0p667_1_0p333_0"],"t":5,"s":[119,119,100],"e":[82,82,100]},{"i":{"x":[0.288,0.288,0.667],"y":[1,1,1]},"o":{"x":[0.152,0.152,0.333],"y":[0,0,0]},"n":["0p288_1_0p152_0","0p288_1_0p152_0","0p667_1_0p333_0"],"t":10,"s":[82,82,100],"e":[100,100,100]},{"t":15.0000006109625}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.008,2.091],[-2.887,0.06],[0,0],[-2.098,-2.123],[0,0],[0,0],[-3.003,0.063],[0,0],[-2.092,-2.008],[-0.059,-2.889],[2.542,-1.428],[0.178,8.815]],"o":[[2.007,-2.09],[0,0],[3.002,-0.062],[0,0],[0,0],[2.009,-2.205],[0,0],[2.89,-0.058],[2.09,2.008],[0.229,11.336],[-7.185,-3.885],[-0.059,-2.89]],"v":[[-17.06,-13.009],[-9.471,-16.342],[-9.465,-16.342],[-1.555,-13.145],[-0.209,-11.783],[1.081,-13.198],[8.851,-16.714],[8.855,-16.714],[16.579,-13.69],[19.913,-6.096],[0.38,16.772],[-20.083,-5.285]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.964999988032,0.310000011968,0.4,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[20.392,17.022],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900.000036657751,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"Shape Layer 2 Comp 1","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2},"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[86,86,100],"ix":6}},"ao":0,"w":100,"h":100,"ip":3.00000012219251,"op":903.000036779944,"st":3.00000012219251,"bm":0},{"ddd":0,"ind":6,"ty":1,"nm":"White Solid 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2},"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"sw":100,"sh":100,"sc":"#ffffff","ip":0,"op":900.000036657751,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/hourglass.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/hourglass.json deleted file mode 100644 index 8f54d57f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/hourglass.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.0.3","fr":24,"ip":0,"op":46,"w":1280,"h":720,"nm":"Comp 1","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Layer 4 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[719.269,437.649,0],"ix":2},"a":{"a":0,"k":[81.853,109.045,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-15.782,6.528],[0,-19.879]],"o":[[0,0],[0,0],[0,-19.879],[15.81,6.551],[0,0]],"v":[[49.861,99.744],[-49.855,99.744],[-49.855,49.873],[-0.011,4.538],[49.861,49.873]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,19.879],[0,0],[0,0],[0,0],[15.787,-6.528]],"o":[[0,0],[0,0],[0,0],[0,19.901],[-15.782,-6.528]],"v":[[-49.855,-49.873],[-49.855,-99.717],[49.861,-99.717],[49.861,-49.873],[-0.011,-4.54]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[16.932,7.99],[0,23.823],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-16.938,-7.99],[0,-23.795],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,-23.795],[16.932,-7.99],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,23.823],[-16.938,7.99],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[81.6,99.744],[58.939,99.744],[58.939,49.873],[9.067,-0.001],[58.939,-49.873],[58.939,-99.717],[81.6,-99.717],[81.6,-108.795],[-81.6,-108.795],[-81.6,-99.717],[-58.933,-99.717],[-58.933,-49.873],[-9.061,-0.001],[-58.933,49.873],[-58.933,99.744],[-81.6,99.744],[-81.6,108.795],[81.6,108.795]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.999999820485,0.999999760646,0.999999820485,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[81.85,109.045],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Layer 3 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[717.751,446.954,0],"e":[717.751,529.954,0],"to":[0,13.8333330154419,0],"ti":[0,-13.8333330154419,0]},{"t":4}],"ix":2},"a":{"a":0,"k":[3.594,3.594,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.839,0],[0,-1.839],[-1.857,0],[0,1.84]],"o":[[-1.857,0],[0,1.84],[1.839,0],[0,-1.839]],"v":[[0,-3.345],[-3.345,0],[0,3.345],[3.345,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[3.594,3.594],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":32,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Layer 10 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":25,"s":[719.431,537.721,0],"e":[719.431,537,0],"to":[0,-0.90864837169647,0],"ti":[0,1.77124309539795,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":32,"s":[719.431,537,0],"e":[719.431,537,0],"to":[0,-0.35245817899704,0],"ti":[0,0.40625029802322,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":36,"s":[719.431,537,0],"e":[719.431,537.722,0],"to":[0,-0.05667289346457,0],"ti":[0,0.15397024154663,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":37,"s":[719.431,537.722,0],"e":[719.431,513.721,0],"to":[0,-2.94422245025635,0],"ti":[0,0.72574734687805,0]},{"t":41}],"ix":2},"a":{"a":0,"k":[61.419,0.91,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[100,0.39,100],"e":[100,7.248,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":4,"s":[100,7.248,100],"e":[100,65.273,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":9,"s":[100,65.273,100],"e":[102,103.253,100]},{"t":24}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-6.218,1.013],[0,0],[0,0],[0,0],[0,0],[0,0],[14.228,-18.623],[8.547,0.072],[0,0],[0.008,0.001],[0.037,0.001],[0,0],[0.001,0],[0,0],[0.203,0.01],[0,0],[0.028,0.007],[12.494,16.755]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[6.458,1.052],[-12.475,16.329],[0,0],[-0.007,0],[-0.037,-0.001],[0,0],[-0.001,-0.001],[0,0],[-0.196,0.005],[0,0],[-0.028,-0.002],[-9.007,-0.572],[-13.433,-18.017]],"v":[[-54.95,-35.66],[-2.777,-35.66],[-2.777,-35.659],[2.537,-35.659],[2.537,-35.66],[54.71,-35.66],[41.714,8.278],[0.017,35.588],[0.017,35.595],[-0.005,35.589],[-0.12,35.593],[-0.119,35.556],[-0.121,35.555],[-0.12,35.593],[-0.722,35.574],[-0.722,35.595],[-0.806,35.571],[-42.953,5.945]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[61.418,35.91],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Layer 9 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":12,"s":[717.751,446.954,0],"e":[717.751,529.954,0],"to":[0,13.8333330154419,0],"ti":[0,-13.8333330154419,0]},{"t":16}],"ix":2},"a":{"a":0,"k":[3.594,3.594,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.839,0],[0,-1.839],[-1.857,0],[0,1.84]],"o":[[-1.857,0],[0,1.84],[1.839,0],[0,-1.839]],"v":[[0,-3.345],[-3.345,0],[0,3.345],[3.345,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[3.594,3.594],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":12,"op":24,"st":12,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Layer 8 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":11,"s":[717.751,446.954,0],"e":[717.751,529.954,0],"to":[0,13.8333330154419,0],"ti":[0,-13.8333330154419,0]},{"t":15}],"ix":2},"a":{"a":0,"k":[3.594,3.594,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.839,0],[0,-1.839],[-1.857,0],[0,1.84]],"o":[[-1.857,0],[0,1.84],[1.839,0],[0,-1.839]],"v":[[0,-3.345],[-3.345,0],[0,3.345],[3.345,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[3.594,3.594],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":11,"op":23,"st":11,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Layer 7 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":10,"s":[717.751,446.954,0],"e":[717.751,529.954,0],"to":[0,13.8333330154419,0],"ti":[0,-13.8333330154419,0]},{"t":14}],"ix":2},"a":{"a":0,"k":[3.594,3.594,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.839,0],[0,-1.839],[-1.857,0],[0,1.84]],"o":[[-1.857,0],[0,1.84],[1.839,0],[0,-1.839]],"v":[[0,-3.345],[-3.345,0],[0,3.345],[3.345,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[3.594,3.594],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":10,"op":22,"st":10,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Layer 6 Outlines 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":7,"s":[717.751,446.954,0],"e":[717.751,529.954,0],"to":[0,13.8333330154419,0],"ti":[0,-13.8333330154419,0]},{"t":11}],"ix":2},"a":{"a":0,"k":[3.594,3.594,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.839,0],[0,-1.839],[-1.857,0],[0,1.84]],"o":[[-1.857,0],[0,1.84],[1.839,0],[0,-1.839]],"v":[[0,-3.345],[-3.345,0],[0,3.345],[3.345,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[3.594,3.594],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":7,"op":19,"st":7,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Layer 6 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":5,"s":[717.751,446.954,0],"e":[717.751,529.954,0],"to":[0,13.8333330154419,0],"ti":[0,-13.8333330154419,0]},{"t":9}],"ix":2},"a":{"a":0,"k":[3.594,3.594,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.839,0],[0,-1.839],[-1.857,0],[0,1.84]],"o":[[-1.857,0],[0,1.84],[1.839,0],[0,-1.839]],"v":[[0,-3.345],[-3.345,0],[0,3.345],[3.345,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[3.594,3.594],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":5,"op":17,"st":5,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Layer 5 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":2,"s":[717.751,446.954,0],"e":[717.751,529.954,0],"to":[0,13.8333330154419,0],"ti":[0,-13.8333330154419,0]},{"t":6}],"ix":2},"a":{"a":0,"k":[3.594,3.594,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.839,0],[0,-1.839],[-1.857,0],[0,1.84]],"o":[[-1.857,0],[0,1.84],[1.839,0],[0,-1.839]],"v":[[0,-3.345],[-3.345,0],[0,3.345],[3.345,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[3.594,3.594],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2,"op":14,"st":2,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Layer 2 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[718.431,432.721,0],"ix":2},"a":{"a":0,"k":[61.419,69.91,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[100,100,100],"e":[88.882,63.763,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":10,"s":[88.882,63.763,100],"e":[84.435,49.34,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":14,"s":[84.435,49.34,100],"e":[65.373,33.486,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":18,"s":[65.373,33.486,100],"e":[39.758,11.315,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":24,"s":[39.758,11.315,100],"e":[30.803,-0.129,100]},{"t":27}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-6.218,1.013],[0,0],[0,0],[0,0],[0,0],[0,0],[14.228,-18.623],[8.547,0.072],[0,0],[0.008,0.001],[0.037,0.001],[0,0],[0.001,0],[0,0],[0.203,0.01],[0,0],[0.028,0.007],[12.494,16.755]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[6.458,1.052],[-12.475,16.329],[0,0],[-0.007,0],[-0.037,-0.001],[0,0],[-0.001,-0.001],[0,0],[-0.196,0.005],[0,0],[-0.028,-0.002],[-9.007,-0.572],[-13.433,-18.017]],"v":[[-54.95,-35.66],[-2.777,-35.66],[-2.777,-35.659],[2.537,-35.659],[2.537,-35.66],[54.71,-35.66],[41.714,8.278],[0.017,35.588],[0.017,35.595],[-0.005,35.589],[-0.12,35.593],[-0.119,35.556],[-0.121,35.555],[-0.12,35.593],[-0.722,35.574],[-0.722,35.595],[-0.806,35.571],[-42.953,5.945]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[61.418,35.91],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":2,"ty":0,"nm":"egg timer","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":34,"s":[0],"e":[180]},{"t":40}],"ix":10},"p":{"a":0,"k":[628,388,0],"ix":2},"a":{"a":0,"k":[719,437,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1400,"h":980,"ip":0,"op":47,"st":0,"bm":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/image_embedded.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/image_embedded.json deleted file mode 100644 index c3d48387..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/image_embedded.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.4.3","fr":60,"ip":0,"op":60,"w":800,"h":800,"nm":"Comp 1","ddd":0,"assets":[{"id":"image_0","w":200,"h":300,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAAEsCAYAAACG+vy+AAAgAElEQVR4Xly9C7Tla1Xd+e29zzlVdYsLl6cKAZLWaKsdjenWoR0HaKImrQ61Y8zQ1iHa7StttH00GMVHHAYBjSIxoh0RENELKEoUFUFIIgiIBLHTLYo61PYBmiCPW7fqPPajx5y/Ob//xpJrVZ06Z+/9/75vrTXXXHOtb/XtX/nDh/1YjcPqZBzGGPrz/jDGYTXGdr8f+7HWv+qr42ysx3rsx9DfV2v/vh+HcTiMsfLPHcb2cPDP7w76Pn1N3zHGejXGyt+n/9ZjvR5jtVqNlb4+eK3NajXWeu9xGGv9gL9X770a6xWvr9eaX/fX9Mn0uYf/zOfOc/gn9fOHvAM/zVf0B/3sauyGPvd6HFbr+fr9Hr2evlu/Dz29fnA1xsHPqc+9H0M/51XkdVk/3lM/5tXTIunPWVt94/J11nN5jX5O/7DX6ERrs1n7BbQWrOV+rA5aG+3DGIfd3p/Lb+L3Wv6sn9+M/bh7M4Z2euXXGWPjp9K6ag2G92+399tmrVhzfZ+eS8+xyz6cjjFO1vr53RiH/bi+HuNstRqX+8O48PfyGhs/xGHs9yt/NJ2qK+2VP6deb4wrr+d+bFbrcbbSeWGh+j1nq8O4uVmNzUrnbcXnHOtxsT+M8z1nxTukdfL38Ln9Lz6LrK9+Xmuh5/fZO4zBsh7GxV5ngf3WWbrU1n77Vz7bW7tfzaM/DquVF0kv621YHcZmfxin3ii9sB5qPa68AD2EMgotwmHMz3vYc1j0YTgRNjedHC2ED6//ygPaiOYRlvHwsBsfteHXZdF5dP1sDZpDyU/vvID9/Ly6DpM+hxdvHmUdeP5+pU9zWPtZ5RS0UDxej30+mV5XHzSHUO8/D3uece/Pweph8DUTm1qMTLuC89C3c5bnlvr7/PY2ED1rNna9Yd12OpReyrGxt9HaaNMOY6d/sxHMc+PvPVvrkA3vow6t/jvxuu/83tuD9v3gfdUa6qBrHbteXseVrIcDqs9xOg7j2maM1X43zrSvQ4d9NS7sXPlZvQfrr9fVymBk+kz6Hr1W18jP5KXejzXeiWcc+3HXZjXOvDK4PTm2q/1qXMrRZT9kAHbW2QuME8PW516vtLs4Be8PR9ifSwZxycfivB1WY/UdX/lsHnXNm9ob6sBoseKFOFircbbGgvWkfTG9hR5IP4XnwRPo+7VDByzEH3i1xxPrARwt9J82ao1H5GjmE/vfWKw+BM9YLx4Ps8piafGzlVr0nRYw3y8v22VlvTDyPHEWWxvFV/S7DrnXIwumz6wPo6i69hr1MOMB7Xny9ePI4M3OIcejs67YHhGgxuAIOCMy3+MoZCexctSVY9HL6CDqEMl56Hu29pI1yP3Y77UCGBi/MIgbqzGurffj1HvgmOjV4vCySoqml/v9uLMjItaLd5/1UzIefb8c5rW1Xjv7pEMrY5P9JlpuVvtxQhxmrRLZHJEcWVgBRQY5QX1moht7xFnZj2urw7i+XnOmvDXslZ5URiZXaIPw4Va0SPTPe2N8McW8hj6kfkKvcb4f44JlnM+9espX/cjBoT2GoYOhY8ohAYYY8thT8QFkjRhILRyIxEIGguz1YLz5fm8glsMGaOvB18IJThHyepAbVXgNfR0flA9ub9/4CYDaFt7EQ+trRMYl1OejAVPyTDMcG551sXkfr4XDfLyKnIixViFR4oRDtH5WXpPvsUPoR8zhAV4AMexY/IEWTyrvTVxdoCXGoVfl+71u+9XYnCTuao13OpA7Ik0i7Mq4gK3W7zosm8N+XFsPHzQ9/0kW0Z9ntffBw1BW4/ywHuc+uIkfdqM66Iquy0HX++i1DeEEbwOz/az16lrrHMzL3R7HVcM1HGJndge9Ms/l/YmR6PeTIQinNeDrdliJVor+WlFFM59EH/r9OAtKKSQMsObwGyEpqvE6ipQXA1hFWhBw/7SveQ7nWtBInt6HkQMXHzRzBVmynsbhyHgVHye8PbfCC8nf1vmzHtuL742uN8um1Vjy0Hj25Cr2JtmgGI8DUuJM8wJgIIePEE4UJBc6EB39zfLYGLN+GYsH5tl+9Wx/Ja/hKAHfiI5sTQAQxrNuHsRxAvYFBs7Dnn9zNI0f0WsJsqzWY7fjoOi1tHs6Jt6JmctoPXFYJ+s13jELZXi07W4Rxe199YL6eXnOA55Yh+h0rcgDXG6eghPEoQm2XIwxzresaSEyvzevWuDuqfMQEiydG+WAjTqsxgJptB9yBM5Qkwt4PeLJ+RzLCjvKHfSZV4aGXg9FLq25YKD/Yz2vreVGFD05Y/p+Dn8/dyNVYrbXh+ijs3yltGFPDqvj4n/+rq95riMWnzHJjQ/JGLs1gdPvk//HIRQE0/fKkPQqx5CDMO+F0WHPa+/2u+DAhDlvGJusdzixF8JD1oNOuHWUDwSx+Qebc/jwJx/RBhWoTQPJ9/J8SXSSpPrQTZOT59ASYwjHUUvfVfICbxdDSaj3QXK0AhtPA4oH7rFqNFLU1rqVuDAuz8bUQBpl+STTp41NINvJRgYG5AAFcEDsX73ePqnJN/gE2tHT1d6HB+cDtPUBDdGgI60k+2J38OGTsZuOgM4x3NP3QkushgykxrjdK3EG7Ho/5WZ7QJMLYHQYFdAquVggLYdmFejFe8sgHPXWymkwcMFtHWilA/oefY4iHL0/qSI5X41U77WcMZ5NP6/nNFmw53e5G//c07/muQcdNJuBk2os2KxCchJDn2J94z0eUP++rYfNAcIjL+zRxgcSTOqQtodJYNHIbQihwrKYfOGJ85gwEP7jzI3j1QMgehzrvY3x/QObsc33FBbgdoFEQdjxiol8E3YsyZo3MXSEcXMiwGJAeaUYC5g2GxP2bUHo/HRDe1+K9eyTBGIEO5NU9kBrzeo6lAPwZx2EzSaw7bBzvqdkXQdCuSNOi2URZFMk2azljWXs2hf9I95en+VCMGu/tzfVgSHp52B2h5qH9fPJu9sDxyML0onZGocdzkCLt9bZIkKe6kwFa3nPgxb0Z3vxuYaLcSsKbtb7cd3nkbyR2BnioURNokg/7Vw/J+lr55I9T44eYT6dP5ls4syvvvtrnwdJm3DU0Fi8DMBZjf1avklLK4hF4PQLrTZArXj+YsvSuooS+qWwSnImdqLeEGxalkIL5g2yTWE4oDoSerap8WWe0sAA7QFW7+iSHMTGvNKChAr1pgQC+TV79ANJ8rKLUSS69uvFzv47a+CH7/PXJzuXi+8PrOKpl4R0JuTxrDPxDxzK0gVylSpPLgc/buzv5FOwS7mc8IX+06HfGeyN60eRGc/N6mi97YmH8gJ4WUV9RUE5ljtb9qwwC+DKOvn7y/Tk9bV7yiO8B+B2H+SNjvBEEzhYkwbrgKkYRldHBmnDXLY4qy2j2gduwVXh6VkpOWadN+hoHLgjmxN9DJzoD2PF3oXlCmtbY4F2HmP1PV/3/IXIi7dzUhzKkMMWOnW98WErxBLVq4fQG67ELjhRxyvMGkeTb+csCx71RhoWgCllAKYeRdUE0WnDyzrxKMlHZuLIQgNAepCxqtY0xJUbV+uzGtZgHFrYom4vb8+5ocZffa+43hANvFO8X6KGXyIb37xFB5iDhDcy5Fv4NCJRPrjyuLJYZmO6eUeY3Ct8BBH9BOsNa7fe2ED2onh3Sh5YX72O6FF2aj0u83x6LdUWTNvPhLqHngN2Z7eHLg+rZHhiYE5C32jqmpjXNlArUN0MZRLsE+VaCycxHRkeEDpf+6D1oh6TPMZ5GgulMyXYVja1iXrZylgJVHeo3p2S04PIBU6x3kURTAbiMoWfhwjlmlryVv2bd+4ZX/+j05/7Y8SLsxmwJ3oDQ5XVxvWS3dhA5cW0mh6G4ImfYbHx0dqEJZkHdwubKmlOvlJWKUVBaiBQnMXpwKWkQzPsT7/LWQsbx7PoPe0/vBjb/Ur/HBYmHj41n+mtp5fMBiUy9FmW5wl+npGFz+uNnIxaDEnGYQMQOxgjCaXKHpHHgfF5B8w3fw7sDU0wsxr9nBJ2RQ/gaE7zYQstbMZL9KgOCMdD0EmHQPBHh1Z0r1k9f3YSXDNtqzEurijg9UkbQexyYgT28jFy8kntaaCiWTkZIbQJz5U1So63SxCXY9RPXYqRM+wLQZC8SRHA7Oe69bhASzIor5Yct7hw5XJEh4VSlmGRNwlOCQoCB222PmNyYiKTlhqK480zv/65pHFhgeQNhPN4/eBl07RY2FZGog/jwmLgViJIPbmr02FQHP677ZPGXUKf+R/HZPBtizgkqHgPcG84cxladqT4tZWEeldStuybFx5iQZ9bLJ0Wr5gTFq4LVWoyny9wRK/VekbXpOAsdjrjGKAKEyFqUPdArdDPweY5gQzrBfYHArzvr4UNtKNJcJfj4J0oFHK+Q4knxzNTJTbnIJeGoxJ1u99Rl4BCV/WbRF5bJihqLy5Pa0aHg33qSL9E/DouCq0Ng0QQEwV+IEryZtRMZzfHqRJjIUzkEAt9FPVxwKyydlNFSEU7Gb4p6+YEodz1vZeqrO8wmFnmCE4oIbBzXrVEKah8yCn2bsEkdtA/8HXPEa4Brznhazkbj9acQr8LorgA50OFjwOqFAPWY+MpS99pc4ptTSPnRVuQxiPJ8+BpTOe5CJV6QZJ3YE1hSg7dEU/PwaKqrG+caXjwuqv/TuwWLh8mLEXF8Ok9pj5+Ohg6eGaOoAFs9I60RED7+9Cp1GwwT6NURSx7bYyzhltjKJb3egaOtWCn15RnO8pmlsJf1tCIy9GWgq2MRYW3sd+Z7dE7nqrKvZGHPYxzyVFUowqLCNTCkHS0XA9QdTpemM8nmlV1BkEsHc6wSKHvQZ6sRXfl6ElJvuMw7TicALNX2ZrULpT7iFVSIVKlBJxAGU7Vb3SWVCy11/driO0a42pQt3Ftzj8G0wZhxOcyi9nkX+dAz2hj4ut52UnemGX94Sc+JyTeajjc2VAq1cAXlpHRG4OjcyhcfSfwcjBTzIumSR/AYdcoLdRpP78TywAWPxTGYY/n0J/EKp7NBy84Hv0VnkKHHt9Y7j3PYIi1SDVytL2QovWKMb0qoXW1WH029FVL8W2JVjLeVloKh+r38XZxM9SH8lllJLOutMS3fO5EmUlLNupg5MTsmB0JEpiZR8VF2KkMM1mONDsZCJ5REeJ0DXNztROM6o4dLN2QBAWMDvy4bbmJKFQiHPQMjktGUodX9cNBRUoZwRpDWOJgDKPOJcYGgFwAV+GknkHnS9HjYq8Dz0HXMbmmSOccNWvtpee8KdpJjyVd1nFu6OTdCZb2NQXqGe1gyhzdwyD6FE9HyPusfuRJzyNIxqt6K9Z41Foigr44fie4ScadDOtFN+Mg7Lc2X+GF1oNc7XgAxHThlctYYE/vwzZUGyQD0YaZjhS3nfBnSJcahMmBJGPAleM6aQ0VNgxvUqAs6hfuWxsFC0L6T3Tk2cWItbBp6JHX8eEM3YmgDlaocQN5xFIYI5jpc8ephP+3bCQJszc5+jFX8yPBaJUCYWH8oA2kfA+fO/HK8CPb5z/Xc9fZ7LY79s7ULYf3bIxxY0OOoleT49BBu9wjN9GqeV/MEOHBqdID/fxTqPlikKJ0l/VuHUz/rvoNtaKAw8h99EVBpu6gXk3GcdvECgXl65K0hC3zA+d1vG5DNRvVMigz1uEB3BdBrRyDopEMHe0ZZgM6JYFfJDOh1X/4Sc8/oJTF7nlBhT48kf+uxCVRxZ4rH8RlNZsZR2K/PuHgWbNFMW166hpY5QOBQ7bgWTdJ+M6hI5KksBX8yoJEEjIFlXjXMkZIVvCweg5Xb7PQHKYcQnn15FvW87giz+f20QhUQzqSr03NUTOuJWLUJ5rGjjDuWAXbBF4eWarXJvX6rCSm4G5j6EprSnW1JDSjBuZb5tBPHHQM/AOn++v7/VjtUrEKQycs3vxAh99JbLyrcDyVZfISOyhHmRTfHIHCaJXMdgGuhAowjjwpybUS9TBDZTlxLEtxE9ISgxdUurVDRCoDuWtDBJmRNNH+cg8sM3w+oobtZPp+UXgrRYC8CJGQtVjQAcVIv0dzph/4hucfZJk+VOWPq6iMRMOFm3lIIocPXenDUBylyiasNydW0md7RnIJ5wWRC+DZWRCUxPGXNg4MgygipiaQK65DkcMJb6JSUt54gnrUnJbUQBoRFdmKcOqt+2wUncbYmnX6KxL1/NgUmoCuZqLcIl9l5JZRJ0FdaGOex6roOBeKYayp2wVChgAZi5GBCstzRh/WdC6wy0c8LQQW+OG9UPcacom54kGu9DVrMjgUS+bE56ioUO+JTIV3bztCk/HEkNQbgF+mqI3/cSKm75vaJql3wa/vm7W0m3VUER29Gu/dIUbUz0pDZjLBFXUM6M4UObIPpZ1l3NZUpYbmyBj5S6O7HUcEnn76aMqoybEeWofV9z3pxw6qdso74LmOYIM/DBBF1NmlvasYrNQ6/MLFhST5+7UoVcIesKWhWrIKfB4/1kQLcQTFKB5Ui2RYkAUzJQnyi+aHEMmWLTUQQmU1QknUqs8KwgoK8QJQBGt9gnCuPIxCGTmZ09yjugjgoHAtNjLzMozGh0Ekgz+CkshKPsjo9O8mIvzC/WCFm7xGBXYumgU+ppJwxOItXh9qlWMueNgaaJWzWhh5ThmIDvDWvSPKHXgG8mGiZGD7FBs6r7Jz26sEEoyRepEfoTUQcjOzTH6diEJTDG7EcFRRDSZ4X06pfSmYNI71lpPvjQ0bKT0FYz2n6GrlStVqwXZyhiUbueNuAByJIkwCZsgbcIRySauHp16s1fhJ4I7Vdz/xJw5iMaynmakTzImtyeEXKCIpsAhD5yRRjgpLOyzZcwXXC9YYkvGgV3JWYU3ArPLSJXbLNrUIhgfRJsoowL1AOW9SlL9+xEnDzqMRP59kO8pU4e7mU8bOLmzxJYdnQcgWD0M0FNuapVt+fKpI+0aGcjqcIRBI9EJHJlQ56sQQkLhTDZbhN9GF/VrkFjruhQnSNzmyVCPmmspEgAFafKJjpStF3AWHUpSleHiQXsqROHGpSmMX5oDcwuwuQpahS87B4lF9WKwr6CD5mU2terc6u6KEIzq/EUjM2FngFnUrKYpxUGbnyn6uRD9vxpXz0UXAg8MhIiphF/SCrlauSjTpx23u1C8010TrNdz71Ax09fQnvfCgBbOFhjrjtUqpCRJw8EWRKiIY2lS/Fb0+HzCHTrDG379xwqcPWHyMeCxQxsUZaIkZ0szIaGM2Pkj2eFVmJieAYcIL6ISJH69i1fSfE1TVbFgkFLgpbrmzbCkQUb1GDbBUu6vwZMl9vlsbWqixKYRrmlCj0V7KO6I89ZNhKhX+BWLVa+JgUkOwPoq1p0OTiq+bmAopZ7J7RAk2kZ9FP3lfiIxCPK2XtHGWXOx3fk8zgUrGi9mDtVDE8gxOzPsAkb27uBiH2ocDmiyFQhuxHRv1E16nGjUiBYLKMa6rkYuMioJfjnsPB/wUTtfy9uSJpqmVp6ppKxV4OXKgKmumugeOzKXQnDVtCH9efuXMO7/i0K6e+qQXu/QmA2kIZjH2xrB9KIe+JLX2bJKdhBLWQkvvIxFZPbVe/s5+M27bga1nI4sxftiJJv7Yaw52NsMkQQxHeB090VIEKiyDAYGFqRchIQfC4YUXarRwaZGaxAlW4mzPtLa4Ei+l+kUTvvL3yURmk9YCvEzxynkoMc6BKNzRE3qz7ABW40SRJF5VK6BinPMuYxw4fMngFTlET5eW5HWBOn0Xok/zL6ICh4nDT6WYoixwDG2S/s0GEgey6MdyBpLwE3nTuxEGbFbHo5BFGUE22VoO9agm60fYPlDWRijNlttpldzjjBsJG2GqKxDVUFisz6x9N02dnBGZSljM1DoaeWnyQmmc4F4qZ8JWrU27Lb2XT33SixwbnQDFyquLASuyGUo4WaC8+VpQS/0L9LTJgru5zoMPY5xbEcr3ywD1kBeH9bht9eQC6Eim4qmNdYNWDan0usOq0C4CVfpEh3Dl8lBO7J1vBZIFc7RjjTMA++IDER3Qsl7tmaZQJk+lRW3CDgUeY2j60GS9+jMtfyjZKpb99yPOHcQFhK0WytViPUOMXcdgMjFRmDYXsYFYebvkgqE4moWkzx5Vdg8DPSp7RxUIJnIHixpTVCvd6RrC7NEARje34kfjfQ9yIaW6eSYictutOQxFJZwNPpOjtn42EnavRahWWh8C2UsEhcBwJhvvSUcjDqzzEGySLSHEZ5O4q9CdLtdyLDYif4owVzgCoSqfwmd84wsPwmtdAMr5y0NVui5D0QGEVnQmaM+qnMRaID1k84S8hqIFBoJWSAwSHPd63G+MGBFf6eUa32Q1yIX0ebQIZWD88aKWte4m0Yf+ajyWWaQI4PTeSCg4K/Lc+l4yTrCzVbHZNEcQJXp7aOqG80kK2LAamBP8y9Lky6UYiSjsBhLuBFl/HW9ex6TPRKGUNe7ACw8oOBpgUJYFrw98rFECcoAx9aaGsHEObooLrAGD8x9KVyJXStSzsQk1NVBXzwOhEicjw1KynAhDP0bl/nTs+T0DkRyJJkEdQiVwXS7Xa+CcePKFUM2GueRi3rpkgxW5MngDB9c4WgdTAsjoZafaR1OnoAWjHIy4UJezcxirH3zyCw/uypKQr6X8UHNEEH7Q3WiGPcipvYGWL+A/1AJKLrGm0jyLMUgt9IWziOoEb8Rx633bwadD7qEJDs/QwoURaHHWDBuwE0f46MMQXRWhOqErhS17gDBGigQyVn2PqsHOW7KZbUU93cA4KUKpknx/aMZWW+E7Wp3PyU/z0qxDlCovp9/IaKzfRqMmjHDycjyI8YAMbhEo1Sr2MC2hxv2HHeswaV9J3DkV1XzZ869aqI33nvUP1AGWwzd5CgQVq1XdlFZfkbcFYj1GHc4Rq5z6Wdgr09qBhjFEWpZBHgx8CIRxzksfhqKcUAPGIbhPa20OgH9eBkP+y1lUzkkZs8XgMpIBZfYdqAdc+PW3EtVQKKdUsEf35dOU+pnTi6ownvPN9/oU3acPmgPEJmHp9YB45E6c4CDSvw71a3bJRYYjMk+NMvWaWgAtio0EnCgPTQU5koEjKQns0d4yeq2UmDbBtHqW5uvkNDmF8Wz1BE2C9b4y0lvC86lNyEu7q86Jq6q0aL+azGnj1JctBTC9ATgQGq0EC2CqQAxtEptoJkm/MWhEikd5jA2wn1lFw3RTqtIruUbwNEn6alwqH7Kjh5BAcbBLca/gJZXkqGTNFLa9wMyPXqsNceE3THWyl26aMjUdnVVcMe2xeOZ6VSt+J7Tk0DfCdNAC0Zg2bhfiJuVLXqt8AzoXIgK2THkk/95fOCQKz86U/H3NIZCPzFWPIpc90WtL1h4FR6aZyCnQPQic23loxBLJFF94VpU29mP1vG954UEhTd78PktDFvZqmSpxLJ1gNA4fi4O9O2zivrFyia+qUjVzEkunYkvbpH7gjgVx5CLbMF9OZO0dyHGSYvgDX2siG0M9Zp6qpzF68MEHerjF1PByP27LW8RgrS8Km2QSwDJqNtIQwQaCRB7VcnBqtgNIkRhXxXLFqZHi0Kx1LNshtCs6OR+IlTvRTA6oLxZL6xBaUKd+9aOiIEayJPhaI9ee0jZqyiMHH92U8DcSbwSyQKXK0vXvMpD1Toa6zUCD7HEYNEeQFNEY09NzCWVskalgtml4PLXZSucq5DhtqZ7V6uB/1Zt00N356OjA2pIxLdIUvydluYlTXQ5IAbQkCOwlbbQykBIQBWdozHIuQyVzjtlngD3TVlbPfvJPHK6fAJ/EON02ZsRL9o11mJpAUcVugt1QhZwO2Ti5yVjFvFLZlUU7fAbGmelIzUFLCOPC8DY2GsVw5dRAvHjPKY3QT24I4S3wpTBUT69P0egjb6WoRdgHibqqrQiyFlMWBO/IJgMJ9veZwrLoXiNhLeA1wxISozUD14HSrgolzqZbKBniAniwFNbkPbXwUqXys+11iKfv4e57JcILugmGtVrcBAkJO4boYXrTKIkadnKFKvLe9vT7sd9t51A8eiREjVNoBKgARfl5TEXgx8Ptui4JkBasRtIqR8Q5ar0nBpCD31FEjRB9Zc89CKeCDi0ERvRfNzTQIeJVOR+tn86PCCEGzPE5OUvZtpYGYoSul2SuGwwcHN3qh7/53sPdG4Zy6YC+Z7sadw6MaoMDp7DEBL0mZ60vpJyfsqJBWYqKLAtFJ8Ekh+nIC8D/eA0YLD2M+qDrIjrGZzFEDpjgWZtwyCdIcBe2ozOSdBCth6paNZH4/l1pQA4IxILaTzEQQS05AYqcaQoL21K4UDkCarWckTUYut5Rz0p/Nqewm66NEElR2MInT2KaAqAia+lpS0dMBy+HGTlLIEI2vnw/Bz/+vbg7UTPVmAWU5MBQN8I5mPHL0DcoWt4Y9gk62KTPTPDxy4JM7ftRD3qBD8+fOVcukEZmM7tLO16pgkh4sPbSmPHOuvC2vCAenpzlLpcoiPC3pVh2XkHdjghScqQ0dbEPaYOMuLqzatsmennut9x7eOBGIynBmu/absZtixU5gC2wyUBavp3FvpkoNRwSAfzi+Z14SEFw56hCnUAWT3GS/EDU74VOj2ovanJqlKrRxHZgbRh5aTmH5jzhwuY0ChgrvB7ar0X307Cb2mU2loUXU3Y9iaS8suogUgGgXi7zgREoEiph7kbq3z15w/sb6Jnmoxqyfo6JlAxnE7QoGyTxotbkjiKXGL4UwFsfoV6SiNDzGe5l6qZyGN174YOE0raMmn1+4AzddbxewaOJF8nhZ061dy8MquUlYvBzS3st7dU5uOkibI2llGs1akjmRTQAf+WgLAXJ3AED4wwHNAxKO4L21Ml8yBiLLYMkUCuTlEti0pZdpQ0XiQaL3iwbGaPX3qiwqDbcnFRUFelZWT3vW37scHM9xoNPPVFovHd/4uS0C4lMIln9pPBWLugYK8cDlkrjBzOORnRpOr8KAxQAACAASURBVPjoZacTUX/2Qq009QIYpQVQR9jlitKk+6tTOaZIVQk1fpuDCIy/kW4zHV1P1MjhYoQq7axltDqWVIuoZyPk8xSif33wA6+1IZeRUXtyYiYaivU6VcWbIwjJEIFnlbR6iSap+owmBRLuS79Wau8uzqyjakczN4uU5my1c2usn3wK7IAMdj5HlDDSFYxDh1vfD8TAOOS4ahQM9AM+4nakaYxEJLmEiZq2RcfovNcttQcmVuyKjJ68w54+IRYnRaSh+YqcT19zTuMhb205YI+rg5MRoSYIpT1rNkQODYbQ87qNNnuBNIcozu4SJSutYXRS1Ao1kKgZnIuEnFj9+Lfde7i53o+7aAgYd+LhtHmCNHpMY8uwG3pjM087VXeXBaDoRCbJ2FEHXryBmnWiy3Il1ErT9ZxjBA5HHHglfsZhdSnaOVcIL+7gWGFeqE4dnruc4LWJKrULsUU+AGGgWtNtf0eS+BYqqUFAVZpmFcuyEz3MBpmpEeXoNlXzeJFqTFDjepCNMdBAkYAqf+Xhydsy7tLTFF2txsguh0R4MIp4VcYknRoGRvPuaTLISPrLdYwj42gvSCGRJz96cmTYtFS4p8gxVCdpSg857zf/HkaKNCzdpvl+08ypQ1QqbiMKHGNGlvbxSMJkwND2bMAmEzLbqhyA10EOMePWuarRkn5cr6PiblXbznGTaANnww7OvA/Dt0ohtbQOiJvqdSXp9377iw43VL0VERX6TIukw0GRTG9FpdyJTjwyMvZF+g4zEr6s2V+SbvuT1cbG5152txgCtQyBMt9dh0vraQVwuHOvr2so8vCYPdRyIE866TSUeeYEs+IKIu8gAi0ojUvB+CYcGH7naGLIlg2MZEItquqP6BCBqVtDvT8l1ZzVSCS8GWV6yCGocWQ4QPRKc5lS9a0MR+yZhXqRXbTFlZ/ntRj+UKYOuNfo4YT6CI7pc3poRX6mxTu0YkQMvVL7MTwFvT+foW4YBM9ko0pCT7SlIOh+mmmzKTrGEOmBIWcQLLbqQrWNTFSvYtwgqm0QmROsd+2A6hJYrqe4Ap8iYmpFWoO6q+aMxMmeVfKPTtVkbd4316QOxqusXvgdLz7c2HTatyhRMniJDGlA4SMBJ/LnXDMgtkCRgFE/9TRNgDJ8S4fR/RUn48qHMVEFzQbePW2UHhbRtktHaI68Gay0cwpb+dB7EXlvPYpYKFeg41KZfJhiYoyksBHaFkMjEWcB7ak7fTBlqNuaJVtGSWF3r/xD8vsQEjLWDB3TZxdm7tCCJqocJiKJinGFhmIJPQbUjoZoZDYvzqe/k7dBVfP0CEBlUKbObRzZHeVFHjWKHKWHBFgXoWioTSTienKGOhTi4BQRTXYugQFPGCkq/FErpDJup5rCYqO8p7RoEaKOFXwVnQ5EhbwxjBVL1mHl9jMM/Ksw0UM2klb5M7WMnPUmJQNy+uqEdjyGRu5POMJO0STPYCeXJN3dpJYYYfB2HD/5nS85WMYxdtY7aaGUyEpvr40p3UguQjTRSpH4ofR1ggy3Ow3FEMXfBISgC3Djeof0W/JR+jO/GHrgLQq0oobARtO036Of/pTOvkpfCYW/cNi8VCAH0YY5S/THtxClr3eKfZM4JoSTsOll6ig8HjOq0M2e/hR3TKYGYRcSjh4GMI+W9ljyBV5UG6iipBgzJawEZzZLh96G4bC/TC8HJtAR18Q7wXWO2sGAKs4Mm+Xn7vUGUe+mXtKI57pKIrlyFBUU1Z7rZwjRYIPIVMzCK9U/tP/sTa6+8Jnp+WidDAesXEokiJ2QWVEmkVhRkRxBBq9zARsJodE50At7x96URpq5mNeTdfUexumk+BMXT7pAapSal7WB0MFtmvO/i8r+6ae+5KCk6YbujkjiqST9fsNwfHC9g35oNtRkwxsymdqRqwnigfhZYEHiSwZLA7X83xwhFElKqqmxOzrVfLbyCul+dEJuPdjGXormqkXQCHuSduFAKnwkBUJkJhmjeqSjwszxHjqgykEacVpLuJ4ypjdPY2SsNUNNoI/aRi+u0uiBrsWkW1L9D24agiFKuk0PQ3RqwEHCvfj95Luzvx60jralvR4kxmGmLOtYLtUxTOwIp7xjp354AHXgq+HYTgwWtSJPs9lj2OixiFKmn48ErtVowSJGHZFhHfqbnIHOmJ9ba7XeoBKYTW1M+NCZ0Bns/tC23c7HUs9xrEd+E0zBJMkz73N1g9GizdoP0pLZOWlaG6ekUofKDXpZO82ffdpPHa5t1v7gNzbS6Yxx3/Zk3Mr4lFbBob0Fu7TgKtSg1aFhqoEAYaIWU3Nf249teVh0P4RSDrcSUi+5FkpWHN/u5vyMmtFDkPTWI8r75sIYdZZpIL974DM8zXkG4YeGIaIX2BSuXt6bCjMiRtpZe5lO+tijgaLnWZCTZ9b3io1ClKcoyR0fMo4Ew9n3fATIYV1TMLScI7IRkmteV5DEQ/kiHiIXjvDQHnUzJSGki2WY+Cw4/KVOQbUcta0+y1WkPyAB9o7dSGRNvUro4dLKyt3si9juroggkdnQwiuyggq56e56ZeWvW0HrsEHZQ637DdctUBErE3BinXzX87BWm3GhmcrHDN1RbtP8gkF5MGWt1bT/RPWsMyEicGny5rjYkAbuJkzuYXib/Ew1Ks8OS26z+vnvfulBH7hqWSVu79mtx63dBu1UcKQ2ytSc56Eexu0dfb+FBiRNWLrDZWoPfJ5aK/AFXQ0GokF09FzgOfR7r+DyAcniTq8cT6ID6iFg8qwbeW8MBMhEHUefpbclcTjVtVY9U5Er5xqpAXCM8B5YGBimQ0Oi7mO4VIzFUqXJiegDdKh3p3YR/5A7U9yPnqTdAxGcT0FPWw5jFQOv5XbdZFbUOzJ1JUMSYK4QHlbF20gTGoPeEkcaXsvNZYiC/Hd5c8/Tyld19YHu8bAI0i8cObzFjMmDEp00tRGJTgecyzCg28XEeUi0uxhJ0gXj9TNmijS/YOZbmW0lowkawQCWCSkz/z9a3wkwEh0sRlX5QIbYdc36A5sKf3MbV1CRk3Xn3atxnv33fv7S97zULbcdzaOFvBybcXu3gZJL364SdhnHXZmR1NE5HvCVrrWkEfRb1KEG/lQrpddH5Ad0KMTSkQF7Up6k0EEOwrQMEjsq8IFIOlap+q50VUNznchUYLw6KA6sDD5dhhBQ/GxNh750MyapL8gzupfAUIDDi3i21DHdg1SSiZqGWTn4XEmXwWQdQmHjAK60Ic3R2TIJ8r/52VNgUo7YaG4mMUXcGoObgZLzzcpOVao1jjmiCPYKdQJ5JLPQUFOoHVr7TXNVxIiHra9UULTw2KOMZpKn9tTF6tDM7DHqVc8D3JKx5fIeNze1qYpr/JDerMbF6gQB65TJZjhcvD6o3vV+nFDqSq5RAXFMWujzyBHKSPSrzCXOnK/1z81F9DU5KDvtOqEaiGTeOtFMa2cKoFgEywI8mUQT+RDuKcnSwkqeovBNaFqPW1twq46+PQquzdCjxTN5fEOmFGSKzDokYSuma2q0iArUphJ5cgXZUvRzp8nYB0YwF6piR5gROBr0YXiXSMXDoOkzCCZwLwSwUYkjauIk/elDcC3HHh4Ma2jlalNagwXdspmFPM0jWmS0vk2HKlq3pVgFeFBVVxRvtdTyao7OrsHAVi394IxosuQ/Sb4+c5W5Hd1KJMBQYdBoKdV6gNUxepMOzuuqVyPqOGrIQMJmOg85bJGnW6enQRSR0NsIWT/tpQ+b4Ol+P840umfl+J46E/Ux3w+534ztOgJWT8YJdVdyo4fauWVmisVZ6TXmrC7ngwzNUxF6FlcrF4qS3Il9GbFK8+WgbaD8svN6xff97EFG4AS81xqEHi0rxHVcEeoF991lRoJ6p/qJL7YM+9Iis3gp3euQ5f7DFmyOb5uiUQfIZRVvpsfrokwNy+agEo7MpBlXUhQ0YxPdfkcE1ZMZnYYKVsjvz3cAhN5Hnlr/ci1j9PX5tW70CyyZuyuyOR6dXRU7AJxNtq1U6+KhOmTPRUgzOUpWBUsCe0K/Mn1efH8HXEN4QNN2dhTDqKt1pl/jaNBzoCwRJnK7HAyqyES3/jstvzsTBUIEHX/UNTbjZmPAKZrqzWfRzjSPUhQPhZBVKg2f3vF4bmoh4Hv8Z9sdmCKoHFTOadZr5lOksS25ms92p+VHRYBWLNKiNp45D44hpLjcmcONRZhCpNLvc01FptO8+pkvgyPKG3YRbUEeg6NpJiry8UDaH23kXUq43IN+GGcbBGLmN4Q5vWDxUrNoRkOUk7PMfdWDOmRPcUSqsYUvgWBU3wMqnKBnHFGuPtMaeM5Skm9mMLVqg8JYD+kBEClC6TCcu45CVVybZg2UcwaiUAUBPqjTyDAeXxopx+LDqP79aSuRaAN829RDX/3OBiLZfsZBTNGdSYpMLzH0zNUSHcujDwo8YCiCHAuSCPIXTtwyfKENQnRRNrWlLkS7byecsE+VejPxJVdbp9LNCNM4vFxX4ZbUo3sNYc4CG6fqYR6/5D/ARHKyRvd+NhmH0IriaznLFGIlsYgejDoZRG33gSDzV7szlzsy5WkEy1xgThsF5YdGVIZrBKzgsJPwrF79r19ms+v1Xz2IDAtrsUZTszMORjmKnSZskBIuBF94jesaPxrMqUiiCm8HGPgxnH4QxpQIakPkTU0bRiLew6dvZS6wjEKBWTABQ3TkMBzIeEqxac1Xkqv4aKRbzUmiinKZdaXDeOE5vT1AjDWaqqRovwws4rlc8fcgiIUVgy3FGEmq28OQwou9E0ZxfaPfhePr1cDHhhlR/hqSaB3ca8artobShJ2xNQjsJPnxoQsz5vpTNhdGCzioxq0OwXKO5EYxRlfQXYiwbU4/jNlpT9pAB1hNyTjjhPwZ0vBEZNIRpPnJV1dHpeBYFyGjWcY8mx8lTXHQ2RzijmpFX9ch6pQIOymz3Y5JlyAcEqnb/air/wqVaa8IjeKPwNltizlBCCcOAzrG6jXPetmBMTy8cVkDKW31Ukqg4NGAGdLYM3DhyGKVo6QnwZXd/KzEck4u3VCTUSrh6GdRJlGkYdxfT9GRnm3e39INRS9X5ZdeEyr9/Y+1RgtWz4QxCy5ek7Ga7wVNm87spsxrrxNyZ4IPWJlSGke3juJfWDzXIXKYPWerNyplTpQMo/BKn96VYhfJWGMXM92ph2xwiQ7RKh0VYfUIMtw7sUYZv7VylYPYMXaQNEeiCmN5XqQ9GAjQBHaL6ILXt+jQTOTRnOT0pbcJTHQ0nYoVeHZeV6KTKeDC4Q6BiONwUKBWZUc3J3eS/8pREBcYou2TmVGqHaZnAiB5SJ3IbM9gwt28UqLqi+DuWchtExfANbcEJydzvvarP/AyCXNNubUwoxNA408tnVXTYZLalD70ROLkAo4IhB86BgNRlIvY5yuRlRmqqhtuX6/afgEPWz66dKueTzrX+vhqgeDc27WoR6ZZy5jZpECa+/05+AeP2bF3odZjOYMPGr0nHlVpyEWNACZISWtEgzlwjUoiNpwwA33TokwnIh13JI4UJRU5qJ63xdWDzbKm+tz6DIrCen/m5GJ8TIWXypbPxVidXFm8I0GnO3JvycnCCsdoMkgDLxsYkQTdkgwjhVTgE1FLLLuZTP/tt2ioUiBsjuDCmmncFISzFopUHVfqSOVbeTEMV5w6D3neE8nam7A2xYuhtemNWhZrDakBFX9ujRy1LPJTDNMG33xkDv4GfUBSLO3jutZaRlpI2xNvRkzv95ofeNmBPg3qF4oSFGH4kFoY9yKsNJKeTcS6uWMjbC6VyGh9bD4Zj9MD4uaWNOXQK6BK7fYoAY+qNX0KPnWuHguGVfqO96Nu0MIPdKvPfJ9ucvpED6Y+hn5NNV0/IOOQoehfFLWcwGX6un7SM4WT7/hYerBFBsJFJN88iiQ2/SNJjJ33SCdmSrSZULVdUKpI4qkbKJqo4AnTha+/2O2TuLd/HJghWle9DrGk0KxU1T1nNoyTWCOtHv0NwFRLLPbcdDujTzRzgplmiXyIBH+T6Opat4P2iz5vfY/bkX2QzTn5s8Ca1znkHkQ7KqSV7RuBmGm/+KLa6D4W6uJE0/6ageq+eVf7kwhWg0aD1YjIa7oL0l+MU8+tXBo2x3BvILHhXVINQzW1eOtc/cqzfj4Bmt4N0ZjtDdBPIyyTB8R8NTBYdzeYEs2JZPp7rN/JBImUPlyb8VH+pgaRwlF7lcWRI5VglSt+BCZUssg0xxpkvTzJGcI8KsdskKAYi5I5W23l9SHBq+9zbYMci6Nn8oBlhE7zGgCIl/+oX5pkc4EsnfXbaY4et+/kPHfk2VORXOog0Y+vnG6RvMjzehSsh8XRIqw98XTKHHp5fdG6VVtn2ULfcvSY6yQHV8kFaoHCNzNh2g9HLOhjH1jllqmyT2fULsPD1oOw6XZM33nkk0TSyAJt5NRHmLfFPrSGFZI8bdpLPqbXoO89BcLAJ8Sg0fTNHnnafpeKe6rqc3gdkb3pgSl/GYw7P4kOSgUK7UStVxwKXFZgWMlAfsE5qMWD1uMj1XMvQiIHFKowNMrbzj5VFbubjLSDAhDwgKMsyYnBU6qZ+jO8eqBBHkg1Fdt5+4YzWdChslAmbqpGkqA78wNuperNQ2WE2XQ9jSQMtw9ot1RIml2LoZRL74ZHSJ85Ca1+uRknm0jlHfBXD0bNhs0ss2IqNdNSSm0CnQoVkFvLyei1UBTjCWVMd9SemwMZ35O6R3on/G9RCMeZdPJJh4CzI/HYqaovOSRRzoYfD4xRQS2rorDAKEWinZuqNKHQLF1qTREEBUIpalJUdKGUQU0IFFN/8FqmOQ5dFLukzyIyRb9cP4kTYe0o+nI+iSrcwpVpkW0OK48cxhKan9usaM9eCrmEPlIHqHycVpUMq1f94C+2LswEDjIGtmheTB9vdDQGCM1KL6DBP5TSrIfxXFonaZUMcHg610gsgr2VHjB3ThARkDeU2gyXw6PEWPyK5vaRdSCfgNpDmUty77pIvIc2Re3E+g5jax/DGIqjjpLmKMuCkyPnAdK1MNir6GbjViKANwrD9P0YqZwL4wsOcMFoR+GUjeFauzJlHuCcPIhpgEl8k3ugH0K8OKv6SUYpJkbGkgmNztZyjYVJmB6m4tEUblUw9Kdzrgg00mgjD5HecWjMoqVLcb9XkZgZWGxJVx36V/UOat7KbflMVUqbgKgOLyUIDiq5nM6Eh9ulpFD2TZ+CPiAQjF7f6XumlDBIAseOo1qNrTtWlWdot0E3ikgYC+0N+qSS1+Dsl9u6/C+v/MFfOvgeCdRvKS8dAZmwGR60cPQwvoGo1fewH/aqwZWLESdSBKPm3E7MHGEJCD5VYoY3I08w/666ypFCuA07zjzsHFkQNdAs00ZytXCSMuQkSKhlAxgIj91GKi2kW4LjIDwkOYbPhgBRjOnjaXLmpvzf8M2OgQTYWVRk7Gxa0wQgCpCSJLXsmFWz2cgOXkbirkNKg9e8ZDOSCwwzzGKYJ66MCOFA0gYj2PfM55GERyQCFDEFTM/dyn76vkKrgKOLmonw0sXY6Ys9eKWyQyQnOSZX7FhSQ9xMwqkSWu+p3E8MWUWqluWkt4VgTg7E2qPJq0jTgz0cavcuNPtV3BlL5Yk2cfRyyolbuHTnab4HvRtOdvXKH/oljX0bYx2FVER+nvyd4qBDvzFgS1IwWfJupeM8KsUeeGmJxUg6LTBe3g+WRppclnMMmSgCE0VMMfrPsF9O7ueUL6DUrMom9/Dd6mlhrSRlwcdg4T4PEm9g6oSGXn/C/+VhY+mFNUXxSKbEYwDorcpkEWUd4aq9Sk+8qcjAEWp9QIhSx6D/DMoITNRrLfIRpo3A7LG+pqddy2neRRRmRBO1F19fF7tQfjVzmIBOiwkjKVLCTv/+Ims3f6i8SWzRXjCO/hd/XhfOeqvUsoJ2OMk3yElaewgDZXgWeOrwHJGqz58Kr7tJHWudtD9SAJ+udh4oYR/vdKLQc+fonLuAgOmFUrr9N/BKCJbh1WFaUwuyBrFkR9ZKy0CEPozVq37oFQdPRSxVmiS2QxPM6fegQ5qnTwTc1kYkjkkbTvgZsDMbiMQ8fLY9AAfVA8UC3ewFEo3oI3GZCIp0v52q1EYVUuck0IY/lLEM67w4LAZyFmQbsFrNqTYIIfNZyJuAAqZSdRnQOHVvwh3nHx3XgydsjmZ6mZPPfeTzAhwOR9k9KGRYFoAh0bFKZaT48fA+sCkSuuEJlYLu1dPB5pIioBaRqqJOoI3WwPcKBobMWWD+XiATw9UyctYfDHjS26+glRn27D6SHCTaCVQEhnRBB8XzkKMRZ2cnXw/eUQMeCTTM2tXqZE6ulJH6PhmTKPTO3LRiuAO2A5+c82K8HTpR5QMSiNTCMqTCgGwOfuiMBSBiFQjoLdgvFZF3Iqx+5d/+shP8dv1Rl+OyBYY4H3ndbB6Hv0O52usbwixGI0Uo68m/ayEtWQjbgakRsucdFJY8ABXKVzuSHKQXkvaHa8N8IFw8wouFXV+oPD8PkhS9X7IKjCUJqFt0e9V0CpL1Lo4AFSauT8edceJh2/q8x+NXa5ytxpaN04Fqi6i+pzL1BcBm3I4r8rn2QII/H7bQjcH13O/BeqgnRVHFI4nmVcr8m7122lbLuNWIS9nDGhJD/bVo1YgahV6oG7w7obRXBv6K3jRKOZPUfuzJJIiGLbShtDWTmdisvwC1coVDHaEdEONdESsA8WDnKCQoN7ppyAnsNqpOIxppKlpeP79pUPaJ91uyV7dzx0l6dFRyVfIVzqVzsLCLCEZXY/X6Z/8ygTtshFgs8cFlPdo1kAABfEkPOsvDG5e+ZEpGsHbYLD7M0sXH5Do+DMwMm0H325FkJEusL/oatlSLJbtmAiA5iiFZCGB4gSbay8C6KcXvnd+bXI8csR5ev5ANFs8ztMZm3FmdjnOZ90EKUQzOz9287ehOCX0WFwqDj4lcnUAfhWgOgKlL42B5SElyUNye6wYl14CAQIIQ+ptrFGVzotD1iKU9aloOKwmsaW71n2TsKrsUoWK8N5T18jzcEtvIiPqglXZBKhmIVygQ2LvvaemowLt3yhfK7k1EYE8OVV86VV5aUBZjwMp0TbUio/58ctiO61Y+N49ln2f6n3OIWcwOCahbE06dKbyMfbJTS2WeZ4eY6PlplyH1sP1Y/dpzXllC1x7ZFu1FVgJV/8CP2+NXedKbmZwwchCbUBoyRLXfD28q0SNWUoDLCElviDd9qbACu8pG4Yc6isfpll3Hbhzi2dy3ECMzEAprNSvumQXMZMdMY1QESRFP4Rt2hvZauPF12m3V2LVxr4Lwspu90hYQn+uDQdKPysg1i04AKcOSgQDAEKKqDF7tu4KfHAJKr7f2m3G+Q39mAZ+fE2FiC5J8KRvbvCWcRXMmfRjNDPPupD8bahpjoeZAYVCzuMz2YEbM8YpXdDxJ9NbNVGaPwjKKYuaOQuUPrAg3kvX6s+SEgfF0D1YHl/wk++8253QYevbwAXkOkhgiU4d8AAiJEXupDAr/Z0wjfjo65s4RctZS6mB/yJ82phFZUFBjdKs3PvdVWTLC6rxizd4LbzSXtJSejSSRI9V3X/KZeodaZn1bEFkGcoYmi9YeNR7xhw5R0PuT9AOhgGXIHBw9g/MJUWz60u0WaUUMBVkFGBdDWY3VCcRui5I6lDfW4uuZ2MEOJ8zmbhB9qd2FY3Pim7WQQ6R/JIm5mst04KknYGj535xAwq1VhQ9EMOVXeg7VDVbby3HYnIz7D+qqo9tOejFm7iaHcvgiAvs22Rh0hYF6T7Fv+hnBQYZiA19I8rEIMWH2oJ124tVC3azvcvSIXCOhZ6qJZRxyhpZ42NNeRdXcCfDJQed1agy1ZsRSJ0vmfphsq+nrrI3zJ1PkW0YxxUCYwyx2CvgMrmsVqmeqOmlYzSKXpFgZ1ABC0tXWhsWARiB41pZywgEDMYPSanLskvCe22pdnAF++NAnjCCNp3bgRv+EtGWih4o+wvosun5W3+fEcFaFk1zGDD06phITe1l5MvWXJBm0dQPFKHZVVg8V7AsqMyTCHH1GMDpI6yG1aHpdX/k1xk2NNLfXSt0iwj1mUgFJmDZIUrnbWM1Fq/Bk+TByGZpH8ESo2Jut2ozlzstIXWRMciTw8vvx9nf88Xjmz7xgfOrHPH583Ef9j1y7IH5+B1So1+/v1H2gN523pU2XlmHepdMa7YQCJ/Rnif8EH0NhTE8M5b6U/Hq3pA/KkeHrTKr9wfWEQFy9rqRDoM7FA/vQeQ4aTqoDyyn4QdM6ckxiAwphKU5HE5i2Aj+15mnFkUIQ8KvPw61naa3Wcx9BQ/IhzgGtCrmzMQiH0bacdjdMvel5rwqU5sv+4HoYT5dIZ9k0lEAte0+iA5d1Vqbs1SAp7YU8vr8QOOOwmwiSszHZl2R/81ZSP/DsRycHQbGaEF8wDqhMlMoEFf990Wg1ObMWaX2SmUy9yagKVBamo3OotRzNR7K3ktCStdFwAfdUB3pqd9R+es1et/Js1kH3VDRl0GFAm4VBehySPuDlrfGd9/7o+LJP/9xx9z0PQ0qiWlMMlbyHKuRx8t3rHACFsFJ6OV8S1OmCR303NFhRqCO3610dFE4n7ekohF91ATb74bFEu1wN4YgT0sR7BdO49FkgHg0mmNDShpL8E0IB+IgCgbYK7TXPUA1b2UGcsv+/wlfyCaBB5qSl78d3vuhJU7fpBTlQxMxeboG5TCD5bN5BZ+1Nz1OSzqUkFMzo7GLjWHb9Oi4AOhgFbnlvCwVm4/7CIjj5PuzHjd5xl2ro0tLK4pPhZPpf8V/wcCGaBW+pBLdO4uOQr4E+Ir8OxjeNqwiw29qTbTabcXqycZejx50GKlptGo/WngJYlYRebeRW9QgihI/DijGplay4YzBzrkx/566TvkaTW8EpD53wRwfnPPDsdPzzzui0UwAAIABJREFUH/3h8S+/4EvGX1zQgCa1gpwPWC3MEIsPHLbhRR8WrZjeqwPwtDbeN8OtRqFcCMTDpi8ERa+kRIY5nQYfWMbP8l5IzdO3H2N0mVN09QGhEtQySmOSZyh4OS2REGb4rFwG1Duhz81e4cBSz6noMsRPZwWE7WP8kBwSYqDOHbZM3/MHlMfIYKPkCOTX9zZiobnifVpIndFa5/CNz1MOQnmdYhVQqbKLdBBjJNn0NqooXHrmq+EVxRV4DhiYtpLISlPTdD7h6mcYrl5n0EkgyFQiJTf3HUo7dREZiSUOMgCH1+USSePxHRFN/9NGncmz7S7Gakv4F6tzdnY6NOShk096LQOppbwQVWSWPZSsPSqyfVijLjqfQPOxuGdEdDRr4MancP8QD3pNEs9Zm4qjuX52Or7hec8Z3/GFXzT+8py1dK9ItUcpEOojeZ6tL6QMe9PBBE7i015QpxOev7B3duHJMSSsiWAQFNauuWGpI3XtYRlp6sgT9TE6quqhkJkbzmmog9dO9RoQiZyM4CzjhTjos6U59al2JnoeQfLTGhpkD06h8J6bvtgbnjg5cQrEViR4nSl6gvsQprCfmTfgAX4UsrmgFgdbB2Tj+7Uf/Y+HFtDI+BGgFTphW0cYOP0JHM1lRI4XMF2FTFHMQIPSuHMz8chMry/WhDFxqK04LUkT0/3CFyX8Wbflxc21xpVkJ5HXv0jCr1/asNP91VhfXbDZ8nTXr4+T040LWuXDCwRm/0gLb/FWFD3JR/R0FQRqUIVyJrRWjNbE8BDp+d9S4ZZxyIBkSAtXDwN4dnI6/vnzf2R82+d90bjlkUotBpLUtjEMRqpGSwSSI1LUl7ec83uTB7HGSFcMcS3LoF/GV+elpYE7DyOLSX8FBxKHQJOUJiGG3SydXzo7UJdJLdSzdMAqu+9dl5ykzu5K/SJ3B3ILLWWEUCyh8DnYqIsxsvYGwTgy0YbgSg4jZlKCVJ+FGFAdHtdlAwWbywU/zEDg99eWvuHHXmNHUiEbwADrd3jWQTOOhK5TKHQ24PYIvIo28CLIDZiUUG1ja+JHcgx6BDKQjHUEJ5d3up5i1LC0tTYJ6yQKY2LTjS3yxJvH6DieiOSmZGV3PtZXV0CN69fGycmJF9ALWclEFt7exqcDGhVGjCIeNQ6FbjbNHXXK85MvqQAp09QBpOiE3+TgaNDFVTZXMBbBoeDGjdPT8U0/9tzxbZ/3+R65JJk7hVryijYUTXHnkTdUb70OZK8VKH2mddN7WnzoA4Ev5kYq9g1R08LeNe8DMYB1T5Mf+LLXAmK3ePQizKh65ywC+j/0OUoONI+Rk3INK+epjolZw0QLSKCygMk/EwVSQaO6X4WyCZhGCV5REn5p4jgl5GNWkdtCUxbInsbkSGMK60NBrl73gtcdfIvqvKx8kT9gZwwZ1nA2Y9N50WYGPaiwOKXgfFCHUSdMmXIYqpcbmCiaGSoEBqhfWy2+4NBmI8CopmQdIuYttjwj9N9sM62yd8YCClBO0HZjs7sa693lODk9HavNydicbDzP6vpmN66HRtQHNrybIJEoCfWM72uVV9FHSSyzXCnK9SByd0bEF6lX6LVljDc32zns2lEiB04G8i0//iPjyf/4c10ak2GJKbo6aJiByG7ODIPblt+1RLoRTFGbaZEpmqohamwzH2o3TteCSnV9Y9zZcUWZx2y2El81dFW7Pi1cuqpzIPX2khMB2Svbp9gHizir6ymERhvunEC6ujJX1cz5dVJNt7gzziVYIzcSLzU5392RgilaLs4MreN1jwAwPRvqh/bKo5bmJ45qHimKEjkyeUV/fu1PvP7gPvNcLOkPlVlIvk/ci8Qbt+m9BUMS7bBdMSZKOhGTRUxoOjDddaWLQ8jbRHzLbD6wu0LeB5Yl1MWyWTxGo5xFgsIDcTDcVXlUqfbi7HZjtfPNIxiH8o8Tbz2TTtISW0ZG/ePX12oMgnI2qDJ8XC6GbI/3bOZxbqD8oxAITh1mBnbsuhvPKCZqRTr1UZDncns1vuJZTx9f+Q8+fXzsh33UON/SSajD71GcURJjIDwtkFg9I4zL8dblBq6zsR0319tx46BnwaEod6vs5r0ykP163PElglqH3PSbq6B91XeQg2fl6j8VL0OthwTLNQHsB5oynrV1GqI8mYKm4LQegzCy2AD/w30nHHAgFPMNtG/UnojsOFHEseRyIZLmuFmOP0LUwLzMDHCdalbxONlVc1Rk2WKxP81r7339Qd6KkLs07liz5BpDMpAwS3w4xksuBZtw3DGSyoaNW82M0QvsJLqMTHBoP5QLZpZaRJ/VHCRDD9wleHRHhdMzjUON0tccPqCZuMRvjkriwTeHq9yyuhrrkxOzWb03kEWknqKDJHmDE80wN/VWEBIarBzDqQLAa6PcgkTd65NCmmOJ3j9QElJimz6EeLmxGn95333jCd//XeN/e9zfH//kEz5p3L7a+eBrFKn75sN4ANU4PMA46lCCuKUqBadubjQHl7KvPpdv6DaJcfA1ZSpESl/mEbxeNyTv1w5bJmp6fhUEjKKcG4pE3TcviZHK5Ji6CYRsjmE1ca8a8BlS0pzXdS87hIj2y2ZitBE3l70jftFf4jkImZmGZJ0IDYNIncUUtLov7X+OBJyJ5+Q1vKbVF7nUCNSV+QElkdIXtHrTi95wkHGIUvSY+dCCEHV4V4pvFGyO9VeGEZ5NRbW6lGkjDkxW7uJLlbQCtmqVwMkIBxGLsTp+b+cGy9VZ1nBNhiU0ZfsXjH/FLnE9Q+OrBXZbbXHmJKnP+uyaayH2qqkm03uA5AN/DUyiNgTzoV9UkFEZlO/wdQYCRsageM8OE2hl3S7EB5bbZG9s3BHPUU+j0//0tKeMb/7Mzxwf92EfOe7fagSp7txDl8WVcRnocHT7FsYI9BWEs4F7/NLeQw30Ux4kPgugY9zWYGlJWnZU61lzEvy71js8vbVfzKoyrOxFN4atGIJWwKYf0aedQ5vFMqeMqytwEC6iVvE9RbAYB7mFqu2MIDqWHwHB0uSULkG3fRvVBOHMyTwYu80m8AqXVTZUEKvZS7pVEwRo2w6wq/jyTS9+w4Ekm6KUtVi+ABPXgq4K3GjDc2ydOCjCQAyhTALLG4PptV8uzgRfJglmNE5udprFmaXRiLm1nVCRtt0OSms9JJIIV16dS2RhItI7SEy3vXKRzz0vp9ech3iiYCZtVPfF81ayXqhQtJpRPE6qQwcmqmIg+f60gjbqzH77CDG1BqqD3L1RmQroqf9u3zkf//Mzvmd82eMfPz7r4z9x3H9FLcR3Z2TW8LzYM01edkA5OIJWusLixnrr8Z76NxmAhmzo/5y0Bu6JVFDudJ9gCyfMe83QZ83QhdpVuy/XmgGHrN1KgmsYkkk4al1QJDd7ZehE3qIIrffl0k4kPVq723tJRkrb5nrplHqaN6Cyxdk0t1DSLXkIRVNBz14L0VID021QEQTuBXq7oJjcn3euTCaSqJyFxUljVqtff9Eb7BwLs5qPVK6ODJoCHY4m1dVAoWOY5eue593mGTvp5iN9Hj68k95w4SFJEqmWwc9lGSRRsScn3HgfYdvC/SZpXVii3C4kPJwIsdpvx/6KGsjh5HRsNqeenaXDIOixFIryPoIBSaypKXB4yCXAu146f3uY9ei4vJkWPYKjdVho69zSEZe3uGt95UOMP9X6rsedy4vx2d/73eOf/b1PHJ/yMY8bt7c79yOQ5yUJnTLu9lwkUuUuSUGYu6Xp0msf1uNdu83Y7skvPO6UKcV2djr46s+nTwSnoih4bZ3qda4hI1q+b16oXMYjUodgqsiSjDQKngfyMPVe66y8SySBvle53K29lNE0NlExZ14ZkG7JQWwI7mZs7zuHH14Kho8nAuK3hlG5SyE056lVmLZt81PxDtPpoz9DieFc+E0v/rVDK8Gl/zz7SkAj+UYxmuOH6X5ewIcg0cIK2kzIK9RyQp67PApRlOijx+Kj4UGDDadOPxy6cSEDpXnv0q2RkjQBdv6wSOqVyzAQjCr60N0Wm5Ox2uhKB5I3eXz1GiAvoZIMxOLfGM8J/GsVorUQezR/pqOoEt2cvLM+JfQt0ObmWhBPiSafUTBOC0lewdP/5h/84fjGFzx7fORjHjue+oX/K6RAqPMLZjLk7zSp0e3XUa2IJz2tw5geD6kIoj+5Su4IgexCz9uW3c7KajH3dKVcrYJNHU4BztRIPF4WBqnX83HnPcwVV1VjTfpdOYinb8o49LU1Q/IEj6aMXkfXgz20h6pzUKdpHueo6TPQ44zIklrOcnp61IGtrI05uyMpij+V6z7cezIj+HTAKKq7tiY8fuPFrweYuBcbbOpe8/Dk7stmvU3R+Y3bH5578kiOlw6uysUdvTs/N9um16dItdz7wCddbhBqwg1nzb1yLZz2vc0WhZJDz9/pJ2Gz8nobSUx2u7E+PXE+o9yDwdoUKTtDSp6OQc5UusPFzQPVyY5e4zw3c6HIdzg0EhcGgiV3swfVoVPsDDQlse0aH8bl+cV4/W//v+N7f+6F49H33DP+1RO+dDzkgQ82VPEM4X0ZqjI46MgIpuGlQgrZn4aW9Rzl6KhURNwkF7CbKYuRyjJniqiqf0czR/7Tfm98Qmj83NeK3+8ABMY3dRqjCQmxYxuMlloHBdyOcK3Q0hX3NYl9YZVQjcSavcOQgnbyMJMh1OPq4B2LvS6J9vNSn3zuOihPo0+iXnFm8lafo2Ny7T//1OsOPqzz9lgVr3JHXA4ydzhwiPWbw1ASd3a9dgvtNptVop5lnm7gQDxhuW4bHjoXhG7Fhxn4VsrPG9NkKl2ITAZM4cdsFtDLoTb3bmM4muyxQRnc+0FUYbexw1iJudJ/llhnaIEkJzAsJBshyGa/AHkGSaXgkAfryYf4INEmerLS62lDYlgZUm0PuBJ7dWv87GtfNf6fP/7D8ZY/+v1x9/Xr41P+1keMz/64x43rZzfHgx70kNDNWEQPJOM6ieDOMWQIuZwEmtLHMOwM+RlXFbT1GYN1yhDP6sQ29096momSdHn7HLi2RFMv4jnhndA92al4phe+XX8RTasxPu412nNZEoM16G9vh6OhrtbKBIHYNSLNnf3puHMAklH0JXeM7wx5seSJ2vfCre6d3l11K89pS44ZUEb5IfO7mPgYLW/nPP/WT/4qE6ridZgXC4+TU8uAgMlu1RgWxSrOSFaLIRAwMSh5uJ0v7WwvRG6y1ffJM4LfJvOADh/mCs1NrL9tuHmv8vlTfavN9a1IMRBFrjUQo0OnUYfCzAGxCKnyrqoXXFu5A8YJpyreNGkJGqWSXZKBci+nK8Umiwt3SZonONqZOt046cUrayoJUI3w/4L/+Krx8je/Ybz7zsW42FPtuHl6Oj76sY8Zf/cjPnp8/N/678d+CwGqX713zxBJ7xdhHve7Y5jNk+akj2iOzlbkQoVaHIbkOM33MqxDh/NS8MpFdsa1UmOBWKk317953FAmOBqWhsfRORCDZp2TDny6JCloUlvCtwaiHcFDXya0O3ENiPZieu8NhR35k5f5nnnWhhwGCr5XXJveTq4KmCXiOZtMDmREUW1ZeqCMQ+SAf+snXzfdo0WHlnET2uvPPbuWXla/GfNi8RyEsyNpQOe/RtNlvj5TQhw1+iApIs4e6RgW/pCZSEaYgRIcRL7W3GXmMJUOaJPdSMUEDhW6nElkBhIJeW/DlVEAq5SL0HOChzpzq6dSUF9anXbivHHYvBaXTDuY6VmP2zqwuuxHjI2GGnS6eSQ0QCI676j/HMa3v/DF42fe8qZxujmdPaNX26tx/WQznvq5Txgf/WEfMXY7jfzsc+OArPGKwhckSwEM5mfpPe/n7A1V+mwegGBIsdzg5G7KMGKuVGslAiULDYv4+3eGT6Bpai7CpwtJPkd7MnVTtLH248wJu+YNR9CYw9rcRa8gRvVix8QT5lWhsaocXyODnOOm/FDkERzL2QkJY3bSeQ7ndea8R0MGl4jLEySDkYH8qlfJP+ykLwaSg6zF4OqxpfEe9W6HN6fmEOxHWE8USW3EeYc0XfFOkz8Ip73kGfkcoXxpsSxciOLbwr/jGa/NykLLRfW7zNEigtBe2ansFEHldTXx/dr6alyPsYjjNxTRATc9qTMX2sG9DrSb9uCx6PKG63EnHXmnA5aqY3hgwNJnk1E2jihX5+Mp9947/t1v/9642l25qOnJLKvVuHl2Ov7PT/qH41Mf//fH5ZXSZLA/jFqGtQUSAPTw3OQQyzXMSzNVb91Yim9irBRN9PMumRzdBtVMN3bJQD53ia7TaFRiBW1EJfGlXAj8kX8EBTjXlQPxvTKZy3uE+Z3TRXZC2wJSxyq/OdgRICoSz3Xo3ehQ2YST6vNAIoKWxWUWUVpxkdFRVoMsY6mmF9a/v/WnXp9AS4jicWEISNqBBLbkfN3FwiTW7XWeHzYFtl5C0+sKXPWNrN5RxUWlBrvEggwR8N/CoEHdBWbl4c2kTRQKPKM7bKI1f3pDjlCYELSFV6VfEfFdX23H9cPW9Qm3+uaGLAvrXGBUNV6fmuGUhVYoijmw293GWiV5xzPVng0r4FY4sMLVBYYyuv14133vGV/wrH873vGed/s1VOSk0KZJjJfjcz/mY8fXftbnMCQ6++EDYgfURmWKp8Lu9P3Dvun7L3eosiElFqM27eu6xG6cbRjrkwoXCTqN69GkpXVg3kEPiC7qTwoIu2lUzl4IhlXHRgYQgsFbThQt08QZSr1jTtnvEA1gclBREAVrUKjKWQjnFyWDWypcWGb/Zr8P3njCEEtY8gbc2Azc4oyNsXrrS14/uQkn6i6oAKW88fO+PsGvXmxf7pmD2g41L1zerOQoDUWLiNGPEYzqZp9kOvq985q6IJWdBNXwvXm+XiJjGzgyqLmYWVMoSER0UJncX+eEXdEiPP0NGYgglSNIZBMO0Xgley/lCEctpimGUMmOJi2VC8Os1m/keT2nNvmV24r36/G6t/7O+OaXvHTcd3GR0xXCIhMlP+rRjx1P/px/Mu65+0HAn/RsmBzIRS8+jKZ4t05ySeSRkAgNCA67dyWHRd7U5IEvE0qbcnD9yUl6PLaJMqjI2wEQmFdEjqFs9ZYqRlq3BYNmBJG73nEh9BnhRNl/DnzxM7lmhY+t+2CinLHK2zliSKJK7Vbr16TAjj0FTu2bnncqI9IXxY4mqieSmIqekD429Fs//QZ/VR6SyQVJIAMdZBSM3cSi6AFRIo/CtDdSucU2bzBnr051ZVIjJ+0tpMF29Q4I8CXvjT/jtTkMQCQtXG/InVZh4yi3g7GYwgxzpi+4quvmf7h6z9hKko7cXarX3bhrLzoW1qncfidquLDlgmkPIbBJjUuFI8jxK4nAa3PTUWQw4a91qK62q/HTb/zN8YyXvwLIFs/mZ8/kyYc94AHjqZ//hPGohz18igwrVLRTiFfWIjEPl8/OlHkl2FE4pB/FNK5ZLBEHKOa0ay6IZg4CJYEQAh60AG2uAW0QMeGPtDeKUJ0hIEWEPbUIBeUXIWDq/XOnC69SIGaAGvlQ9j1Kia6H2Tp7hzjHRI426rWj0pquNEe5nVaTTkz1Eynl9GjU4jyBgtjlxUn3/DfX3Y/Vb/8MEaQVY6i75ZBWPrw0sfDilshHnoY+izdmJhHOU4JGqFC2tbfOOjolP8HDVGHJn9+HKo6GaybnE4Yt+UqjVvH25CmWvUR64D4OSR84JErOZRg3JNLbXzqCXJskdwYVBHb5KXyQlZTrEDLnl6Q8vJGeaUeSTu9BhdhEKuZHCMKsxuV2M37uP/3m+KYXvXBsd9txuRVTZDCGyni9Hh/w4IeM7//iLx2PfcQjApFoQivg6kFrNdw9H+ERWUmbKFg7VzeLlLCoEA4Up6PiaaLFRJCZM2UKu3KUtQ7+gneqGujkGx+3XH5jxquzumYrdnyJPTY7Wnhjjx7DDKu+/Ju/Hmo3VD/PTFSuMfVqNlPoPutHg7Qz9sioqPeahN6uBApYnymScbyr333p671KRIgkTzPOhAIMrqnX0lu72Bf4ZdFY79gOuzCjwLTQtuNyjRqSgqPL56cdL7lEeIcjcTJeBEIhbFch3eyyY2OWJcVKGDoAPlcEsfxB8OogA9laxSqJ+Nnh0kYjr+4B2maEEsy9I1TEPXXkQB6ASJBuOFOMOYTw7qrPaOofamV55K17MTbjlb/51vGt9/6E6d2r3XZs1ic2ltONeubX46F33RzP/rKvGI98yINDZXYSZSMlKSuUZNL4GILnCzhvYjCbopIjh+EevSE+HyIuGPmVnADIJCNurYGb3jjQbbdua6/zh3hlH9QoA0hRK5Np7w/vsRQp39dIiBIhZfKappMzlNtGkpqMWbwKYE3tozAwe+kcHbjoqZ2BmOTSMfLMYLAD8HC+iD7jsBk8Msbq91/6Ot9RCDyqunEJOsCV+iosvoUeY1Av23pcashZ+hJmmSidhSxWpp1YQbsZ516pmKVp4LzHbLllg7DpJn9BpP1M/mgoQNuh2LqJLMH+1Adn8bp6G7fhSpjnPhAaptxcZMO5Gmu16FqAmLklR3mHq+i6uNJVZg6AEnMVIH0Q45WUvfnnI59uhVsSFiX0ojB//ff/aDzxBT82zq8ux9X20hL87dVunJ5tXNh86F13jR/9p/9s3HPzepqhlsSWKJ9DYHhGCR9O/6h+ZLgVufzRNXCO2r0tKxXvjXrHV4dxuT0Zd7YnEz5rbRlcftzEBi5QNEJEuRCt/tNkKOekwamjWvLEmKAPcrVUIJGZZ/ibUTzoM1iXZdhBb06N14ffaUJYVBnNvCwJ6KsIYzV25ih4BQPB9bOq00hmpU2lKeswVr//795AYIlnZhgZWS9cMl1qhLLlDr98E5+9F3z6nmsQt0Pg++QU9Fib6s0sLfPbmcbuw2UPwp1x9hTBVU3aOszBYrK6vxgRFfWE/5IAnVSfQ+uQm4srBUeAV4y3tNH4dyXqGpZ9yUU2h8sMZy7bg9flxizYPF9Ukw9gciKScCXN9uLxgiTuGpuDclre/d7XvH484xdfBiCy11eNYDM+5OEPG1/7GZ85/vYHftDY7q5czJxXzeW+j8Q39iY3yF5faQfScWcvjB8y3s5hsDxmTpnByPXakoRoCW9tT8flHgOxc8nwcYZ8k4eIqmUEU6bQl8N3uSw1mZlrJGH6qwzKJJMqE1qIDIyfwiuX6yBVWeBRL+cJ85reFjvn3O1IPpozERQgI1GBtUMO6dWB4VR3JXdHYqyWMP3uz77xYF1Tqpi1Ko59UphUjAE3LIABWZHH0VR3LgPl/r9KTIo1O6LUBpLxQs13lk7EYtzQ1iHGQgAVxE6oFVtOX3UzlVDWU1RTS8s93qZ7lW8cxl2HK65m1n/7Mll80o0GoR3cIeMKvavUiRpdHRlK4LwPjenwnTRfMjTmRLVS7CqwxvBvgZjr1Wa87U//Ynzu939fGC4S/munZ+P97757vODrviF3zjOYuVXqVo6pW4UZCp0p3ZdrJfW89mDtT2EoeQMiDoiJNjRJRdUtAkYRP6N5fF1Zkm9T15mc6RpR9t51GDsgEAdxK9C2Kgif3d7tQfQoGK5qHGiuxLyOlvOgq98YW0sdplKlNJcyB8FG0sEfnQuQMxxZkuCU5ECloH1XY/gwruOmCN762+ptP/tG5/LypnzgYHuHn6UsX8MhJWp4P74VFgZKC8tF73nQWKONxAVD+k0srxdtrOHFyYBmM1ZYKH0eDIhQ6GAbpoL5WGFDTIOzEEjrj3rnfQi4+MYV1SheFS1kGKJ3zw5XbnY61e+RmPD6yh9K7cpYwLpAKaoOLr+li81y7nSiMTZTWL8KWkm6wd+UGbiN90/+/L+Oz37mD46tItbp6VAVXbfCftDDHjqe9eVf7cOIn9aYIksFrDlTQ1RH1WALMHTKkVRW1Oc0MSANlPo/Qrta65QOUhmzjI5KOGTK4tiAMC2uom5YUITurSyl2/0TKeEzk/ywV3vPyTHOPQX3IG/687B9qcJ5bVtU5UR6mEcihA4wTCdMFbGQ+cUwYtJwJS8KxOI+Rc4Rc72a4PPJFQlt6HZu5CS9E3L1ez/3JgqFxnhV6pKwx4YzKGDhiOGsQ90m2yec8bX2MLibMCyWeXj3dGsq4aLl10CCdoUxEKLv2kR0Cc9d0KCqmCoYFQZ1oakrvmyy3mio363DUg5yuBp3OffYjtM90MrDz7LRKH11IE32zzGbeDDSVCtzRfcGaoZrAcrpvz1Sdw4OsADaGviinONTnvavxn9577vGtdNr487lHVelv/DjHze+6lM/bYr8nEXHY7t7UZfjNGd0cQ56yQaYhi5T54km7bNQ7qVVujhwly5FtOaCCGDsyPI8fsJJ4uSyGc/ObRWiRCmoYibh6TKc4tM6B61GoB91sNDMuSKb2IOnA/DFQHSjrelboi8dm8zY8thbpykQFh0K1wKimUO341K87PsifsRp6n/cNEwrQ53O6vdf9utW8zZBR+HCwnpx3EAk3pw+gjDXeOkyBklsHDVSwGpRyGY29VnpG+6FoVa0airKJlPxViNzAY4S7BhKg3H2obTg5OxzXMtidLK7sWw6F+0twyqpam4FrwqE6lc/ihaOGoEm1p/KA2WivHn1SAc5SLrkMjlXMK+Ww1BDh3afi9xCVRKBiMI6HjevXRsf843fMk43h3G+3Y3zy/Nx7eR0fMknfML4kk/+JLNa8rhcWQ2ZUu0TY0MxDDNJnCxPf7QDi+LAe5b6gqCSPtH2cOorsD3Y2iQJF7iC/Sns0qXJRTat0AMX/V1hucp1Rf5jLVjqZksOnjwIL40GK0OsO4xC5yxtC72+ji7WFAJMjnDmPGqpHbA7Em8jh0xnJD/EWXgMLNK+2d9ElAd2a58cDdNO3cF5LXas/vDn6AfZa8xHZArAAha/ExFbZDLsCPBByJcEMBoaVMDLodaRxBsakLGLAAAgAElEQVRRJ9cBsTbL9ZKMwReH5Gp775AIjDvqLvO2OETrxUjky6EbecSYqwamYt+KAX7MB8tXwiFIZJZu8g7fg6gkWpEEeKVFcH6W/MNyfI/X3LK+ufvucodbMVNiok1CHwauqfoOUEz+EiNCPTrG2enJ+MQn/4vxwLtOx32X23Hn4nzcPDsbn/ZRHzme+JmfMS6228A69EJ6Do1mFoXcS2X0/GbWdrBNGZNhw1KbgqvcocEhXBhop1u4BPNckPUwbo4+s3URp/ooN2FlHEKo79QyInkPAE4OwplgVlX7jATzQA69K5Jrzpb6twffmQYH7OGrO+Ct9TGisJN1XSi0IyLKiGEsBeE05CHTK6PAXjp82Cf2q5cOURA1E2bjgq3zOf+zl/0qAzx96Ur0PWVdLC9uzyDXBLfHeMGbKfu3OmnN/8J/l42glAZdWwzaQQ+6nOZCG5Rhn6b80ouCTyTXmWNfsk0UiNgabW2NmVAfdkOHwZ1XmfoReYXzjz21DzFXbihyvsF9F0wICS7WQY8ylAgE5OLZOFidSFuWxWAl0WNqt2ZOxSfWp5JBfeZ3Pm28+84trv66uhgf+n7vPx734f/d+JpP+5RxdaWuif5Kb6MvIqUsXHcELUl8p82Xu15EJ3d9JtHhL2T0agyd9lVugqVuUHl72p5LtXrBGU4xXeHxrIIki6hwPWjJPAWX5rCi+qUZCKJVC+WAs7CmON20U/SKvvxd0SIfLsxW1datWQW/eVQTnaFEeoz/SIY181rnHEE5jip+vih/3/7zr7Vpzstm0jsO7cvkDzwSB4YL4jlIMp5iTJfEUqHk6oBW1zngTL9goy2D8HMizkPvJSPBo5QqMENRyjhRyREo9HE33v1W/rz0q/mYOBoxH9dHLAtQI3Kx0AJF6h8eOmDKj8PfA2BpiSFnMo6ofM0U5VD2+WT4SDHIV4jEWl7oB8AJBAalgtW4fXk1PvFbv3U87AE3x3vOL8bF9nI84Oz6+Ji/8ZjxQ1/2BNdIluY0wQtBI6r1PqqhkXEoND/Ybx/U866hDUyBcjRIjsY2SJmXqJ6Ku6bbcD86bVj4n2ZxqRn4eRAXao06xT90yeSlmCfWYh69H1yPAerQPjOQYmGrcDgtFHJxafNARfJWziFQKLpiLzHa5GGsvcFmGMRezVEnTa7NWaR+gsojzSO9LFZP82e/8NrYNVbGQWJeUaewwWBRtlfGD4V53C7PQlL+ZyPw7khMqHLKKDZcDWbPQbKG5gHL1oZWWq+Qbw1Q2C8nVkdNXc09JpOVCd09iPKQnsk1K/sAYqjIPIcLhVTRZSBlrUw9ZhNIdKF6HeMMw3wNjhu+EHdijG7siVaJduEMJet6xNUIpOmXoNw73vXu8ZU/9IPjL+67zxf8bLeXbpj6b9///cZP/B9fOs6vLjLTSlQnMhWt36xJ2NlDllLwBSJYTT0vQKIGYpdltfDiTT1LIA7F4sbEGzRkGIMznwj6PPppdhiC1Htlsl3pnBkWBxnhJAc/58HeHVhH4Q6So8M8yjiSgwCz6jYhS45rc/y7oDEQuAad7wuZMPVX6Xkx49UOwhZL5rO6Rm9p4uodv/Da8kwZwJDF7ECv1BLKiMjDurlIylFbaK5H88BiktVQAISpoAPu9+ZqN7f0Gn8y/iV0PDStrxWQ5+8MwUYYluh4ygfBunQvHt55UaZA0h2dw+BvZcaXv8+/p3vQz9TDn4arMEIwOB3tz8UQhWHcdZc6RDfdPYv1akszWYv/k38/qFYyxu+9/R3jf3/Ws8atyzv2hncuLsfD7n7A+OBHPHy86Ou+zJBLMpX2ccpAlORKDWyRaUWepjqhben+ixRoXtpTBmFpQrPXVGTJXeo7weNEZ8bmEBcmqZCkV3usglpYgVCxjA8VMnAtIo7PnjyKihIHsEgYl0b3VM7PjcnA2/7qn2orOOoesRRhrY9r5Me5lWQqqTQHQRy9oPPMo70iqjfys16rt7/89W5L6aw6wj9RoMk4u5MrEqL1sSd1AsdVACShhHlBrIKpJB4RIVL/8AF27SAovx1j1VD17uzUVKzdyvVdaVVYAn9mwtoj2ysrgQ4NaEUvnsxwLAxMDUkTFyteZMIJEhMKbWH3XQtI85T/Xf9lvqzjOzFr7245pP1EkfTMTPYt+UKwrV5fgsT/+w/+eHz+M585HvGAm+PW1dW4vLocf+3BD/EYoDc+5cnj1vm5bn6jWSmkjt714kqmqk+tYQcEfB0wU8u6/KijcnIguP4g4quwS/T6aKpIdsuKHUb2IKCuZCSMpT8ANKx6TUrIO9L7wp9o8kIzd5JNdVJ0qvJm0LMLF2Z5ugw+lkABMO+fWzSPOyWRFmFmDLIDFmNbkCyQKyyAd8qtAZHh+FAcNcLl/IbuS445ZCBvOFTCIEjQxvUGbrQ9lXTXO2GhCoHrFY1GaIE4MKUUFyqWzbG/tTiMQ8RjaZPoYmzK6TTJRkHCb+iVP8+CYfBjU0j3uqXfw/mCcw8gHesMNicaUOYj5+i4Hyo4DeeODsG23K6rZF6NUBlCF+rU3jV4GzgcCXXmxi75Rj8DcE1rJBXta976e+NHfvEV40/e/e5x//bSFeP3e8DN8Ze3zsevP+3J4/ziylhb3wsxQD3q8nI17hzOxqFUbQ6I0uytWo0DlzvMutHW0hgAIpS8aXkOYin6ktCtKxhiZaZVDzf3EwLBiAWsM3kouQSXulIUFCh1gTi1iFKxgEOgFM3CIWSCrlrLIK8KsQXbk/8lutqwRKDopYgoam8AKrecCE1eKQEQcpmu2PzHDJgd6mqs/vTlb4yB4Fa8vWGxnE6b06eWS60EfhmEygc4U/VZSWPeDGFbvE0q3kE4SztuNC8k6m1LakQhwbMwO3dpq1OjDAghGDdH7oKH6+c3m2+5fRJDM1iALat5RfPuQzDk2eg4Y/FsGDaQ/owijT4B0cM3XcWjI5brALa2VqX1y5iRCFagJ/aPvhIu83n5b/zWePpP/vR4x/33W3pyfnkxHnH3A8Y9dz1gvPSJX2EBY0jJRaK+24/Ly/24kIEwWsL748tItV7J9/RFD1BIHSh4Ir/1p+K8oltbEEe1dIm+gZzOMaako2etVf2k9EmcUcTiCD0+NRCaUamBfJlkg4oXaCZlLc41t+fOQiWkjpwn1Xpeg6CBilH3JHp9s7+wjoVtyS1nTIlhhoygXnJkNDo3f/aK/5SoxBtx0UlnG+VOiSY+xKmZYwBZzEmlkBgu+ojdsgVHi+MHSZWShpfAsdxMlWoG1OnU0mpRVEgkksB6ZKhAsCqegADG509FN0fLEaS1EstNaKDxczY8B1pW2oKGSpVwPR+5h1ppmeWnIWgtYKnwtRiJ/VkWHK9d2qCwFQPRa5+drsdLfvU3xpN+/IXjIXc9YNy+uhrvOb8zHnvPPWaTXvLELx8PvHkTg00PxX7H9ddquJIKwWRE2kOtjTIU1S25WgNYm6Ir3xScYRmVmNQg3PUZ0GJv7mdY2EhHi0zVVP1BtQrHDjN5mjii22erIubgUZHGOLxaGVNEgZlDW5QBtQrFW2KGx0ZbNVWHyZv0uav8aPFSWjoTKunL96cPLayvQToLCsYJJuqBFEp0RNZkmc4Yqz995ZuzFEFqvTgzPQ5QqJWdRAsVPO/qen39WpM3qsqM4KRVUH9/M4HaV5JbJ/bpWUjrKmUisV6ZxZEZV9RNNh5LJEoSeAZ0arIeEjVBPxlrD6xHgeJRoAOYlXRMf8KHR2Nm7yaG63KcHC6j02K0p20wRskon6XQVjqbjSsCDnntdeU1rp2sx7Nf8brxlt952/jdv3jnePt9d1xn+ujHPGq85c/eMe796i8aj3zoQ8d2q/6USHmkM7KnQ4zPwQM8qiCo32dFvJtuuj6y8wgGta+dhAJwQ2egg4tQEFUyKUFK0WG1fPOvDQb17ZT5xxg7RwD4yWt1bBFBuhIYiTt7owCuiYkqZOGpQgXqioCI44tamA5CKvBIYjJh0/sL6uEi1l4CK6YLrVUr7QFrY+vv6/zoJPlCn3/+6jcfmrwujUFJfsJuwBCnYBhun3fH55+sr8aJZj8FB5uwcyW60abGUVm94yTeQ4OMZ20gC2PhGX4e0bmu/SplwNyuCx+QVN5zDB1KUwgMiFyiSS6P6W25ftYksDAXRFAKXF1eEvTru8txbXXuCGIubnYK4nU8DUQjaiJhgPJejDZYYBbWWvU/O12N73npL4+3/8mfjl9+2x+MO9ut+0Ie+aAHjUc/6EHjiZ/9yePDHvPocXF5ZZLGjmQNS+aDK5o01Hop8KXzaenjnkxbBox3KEEXIO4ML5r+GQ5RInNk2zYGVa7TyTdhkVsViJylyPtnK7vTo0FMygSSrreNLbAdi8v852iy2nRlZQcGws25MpeMiHWTWqj4wGJD5SSArkOZwUz5IXQ0W9TWgFypbWeHOXst3vnqN5HydGpFVJH1fHgWMIottUK+OEZ5QtO+663pSPDy1Rg6RItAiL9PCljdTHg7PGPuGqnVCbcatggqMO5NSXpDvmooygguVwwWg1JkNi3kMLUOPna4/xYTTQE2/2iSCSNDFTcXb4bb02GW2vfm4XycrnTPYcQRoV5BjaFdS/kGkvauddY3tGFAl57uxunJeMqLf368/M1vGe+8/5YVqXfOb48PfPjDxgc99J7xBZ/08eNjP+SDxtWForMS35OhO8CVRApaEWnRTqGnQ16DRKTD9yBHqgie1eQoWlv3qF4Cv0c27Fzz6LA4cvlWLXbZuWAq1UiAgHMuLueeQ20zREvo+NYxUiOqsZU9OvgOSDlYHZH2wAOxaB1K/uEIeNSCHCgvaY8lPiFf6DYgFDYvxsMcXdWdmWCqvDNzuKOFZCCvUpKuzzNr0ECHXH1YQWJnroIVS5+B6wyEdN+FjUyRIwYyJRkwEPMD7jdU0dus6IOVFs1KnVUn2UkI6NnoZA1H2iqZge7LUyQ5t9iRpE1P4at/nVsA+Wo0TZfLl/LvEA39r7Ibxh5hONJsnR0uxqlQv2leOYNO9KvUpgMAOJyE9tCjGSABROhQ2/24cbYe3/T8nx5vftvbxnvuXIx3n1+Mq93l+GsPetC4eXoyvvwffML45I/8sHF1Jepa6xXNF9vvdWHq7+I8MA4DrvBDzckSsQOxDDXM8NHFzk9USAkM8o7NPCBJdPKTymfwwB1iTkIPsgjcTvrQ5ivnMTaeECEWKAa6O38o68TrHANz3/0STNRry/lrbuNN1cuNTjES4VGGaSx0Lxw2n4M+EozC5IEd825c7tVYdRird736jZMj6EWIs/E/SRSFHS6gMdBpFT3hTPBqI/mJosuaCw48P9xQJIl7RTC1rTAdHKbgNSe4oQicwGs2LN1tzD1M3hGRIN5e+QjFRz4/m1PgpoIgtG4476NmIkSJKQyVR3fi2YJk8obkWTIODYXTbVXuN/dkPti05i7ObI4SXD1mC2N0pVQzpAiyGV/1fz1/vN/pyfipt/wmd3HstuOB187G3Wen40s/+fHjH33c/zAurpB+AFBIbOm9ORlXni6TiVjVExmJRCTos1+6YJ6vqB34+lQYZ494fQwErE6V27nJlOyHUp30bJ7To6N4H4STPZwtARB1nDynuMfAkKVmMQuF0+sv9LyjiKck5sx4kn+lPaAHCptEuBp4wHDuvedny7LJQC53TIOxcZmpUzTZj9V7Xv1rHPNgvU6baPIyNySmi4ae+gFXRyIpdvLrtrCrJLEWDiQPoSW0dy4AfShOGpfOdADf5+iilk8l6fuTcbE/HRfKAPR366tSH/GYVNgwqucyEuoheg8PU3CfOZMSYZdwcU2k2wNisJIbovqNS/IZHVIUBOo0lJbrIFiZwuDSoR01wWwEi4+bYscUYA+7cdfZ6fjiZ/zQuHuzH7/8W7/nTTq/vBwf+PCHjw966EPGx33EB48vfPzfHeeeHJ7CWZw0A8cRBF6tT9y0pfZlOxs7gUWaY7VCqSw/fqaaTLV0GZxGgKzSHM4WhUMMv0pZ9FgL1epzFJaxRxjyJDRrFbem0WUkTC+YNz4lbyvzFnLJ+0UBMQMw7Jz4OTup1ODMVGUeGUa+KM1xMCEUEvHMiCpi6BaysfdkmStNl0mheKc/3/fq1x1ojY2QywuIhS2MGg8u5O7D1ao1pTh0WZLGK1F3sr4dh1UjSIpv6UdIdsnC9sLHKifDxjC+9MRGouEIlzuBm2tO2DWPy5JC95GEKq6oMck+zBpYWJ/N1QJvBj3hYMpAKI/1yQQT07oUBH1jnp0fULAeEYUBchNWjEswJ0Vt4yXScUhghpoXUQOBSbvr7GR8ztOfOf74z/98nK5Pxn+9//a4dX7/+OsPe+j42L/+mPGIhz10fPWn/8NxrtGjYX8MZ7x2qHER30c16wFtgVbwtCksJlJ0b/3XGgE6Cjxua1zAozI9NLEtzUZExc59K7Wb2Dh7f8okpMKtusSkVxmhxFr2QgRgkt2JhYgxVh9H+uJL07iO5f4k7QOv5ajU8ah5jqoZGCpB1J1Rw0LLMbbbikmhfy+2IiLYI9vArX//2inAgO0owGKh7SFjLHpDMUjLrEHdTou6V4H+bHU5Tk4UNbShOZBcrZhQm1C6jEnN11MhtjfSaVeOIq94YlHj1VbA5nTAI51RVZfy17ScjmsLl+HyU9AszHIlXBuUG1yZ1NKcIY1hTd4jK9GdIrrGU+2pTvA6jtKnqJsLa5Yyj1klS01WLWr28lIiZY3KBnzYjhsnq/F5T/834+Mf+8jxk2/+z+Mvb59b+ft3Hv2ocd+di/F3/uYHjq//R5/h+ogjg4uXBWkL3JxK7OQReO3g/OQRHJbUyG1ETYCjx673njJznVDmC5dupe6BQtraZBuO323+bphiFNC8ThS1EAT3tLR21jlsVTJUeEREiHG4iZJz2LyKupvywjnzc8qdDB1Un6nDlUm5d4Q2W4Y+aMSPRJ8yECaybNWzYyZyR33HeVEi/Z1//9qDpedk6uFY+OfQW/aC9kVeGNUhEBSqYqtDKEXsXavLcX19Pk43V2OsYRIowGzH2Fz6a1BvglSW2aaCpd/LfrVKJJbr1BFktz8b57uzcTGuj6vD2bijw7c6RSYf9SnFw7SzNpHvBTruy1CTFJNB2lE4i4uTnoQGpAp/hZbHWaKeI+xQcwBDxLYA5Hg46JZFqtqrE5OW3hLuVoGnFz/3+d/1b8Yjr5+On3vr74yT9em4uLr0Ov3tRz1qfPSHfPD4un/8WeP25X5cts+a8hXNWobFglaecZSJ+4l2kccUBXWKZZWMqCE43MbzLgLG2NsEFSjkiJF+cprWCiNbUMyA6ZAHEFqVosg4GLbn0a3urSl6UF6r6ECXplfNEJkLbiqWtHHEqCk5FNYHvvkFOVsmH9QwFcSipVZtxUrrNFjJCBQtrI520TM97P49uZCnyxzG6s5/+BWY71Q38TTg29KqFUpInozArBopKEV9pxKlG+Ni3Dw5H5s1m0zipXChYa+atnGk2Qot6O9xYh/pgzdFG74eq93p2O1Px9X+bFzsr43zQwxlJe0th4QchNDpTUxrJhCRPkYxW2bbpKfyldCpktIxkEPCJugzctc5Y0ahMqtVChPUuosT+yxk++JnNMudFqlPEzWy+KVHt9vxJd/3rHH/rfvHH77zneNitx/3nd8Zj7rnweMjHv3I8dB7Hjr+5RM+b9y+2EYIWFankbL7dAyPl8Iuhoj0nToJdSM7rybPTWgzsb7OG5Ip8EhnwsLR+NX8GdeQ6JH5A4C34v8snamhK99XbwNx1OWdQsmQw4YI4lJVVByFVYDVROJeKzIHygFJ9ts941DTq2PjUPIt56KkfKvEm45FGQbRhd9tUE5Me/1enNrVr/wHermWfIuE0Dhz0fnwNK1wuzw4Z2fRe8EwBF08c2Ota+dlEBFu6LDJCET/tog4hXeLp5lYJbWR1f7EcEts1jSS5CJmcNLPDphr/0NqTVKAehCDvJOmn4NhzWplW7nGbUF/+F62Hbk0TVT2hzaaRCpHnQZ/Ntuv6RblBMaJ8isLX3RuUfyMy/PL8b88/XvHPWdn47137oz/793vHbfOb4+/+X4fMD7lwz90vO2d7xn/+p9+sQuFhgCtAoejE9RBhtNJ7y30KUq7T27ZV6cEZX7ivHxI5XnLIlIcDAObn42BmcgJ41Xn6bZazkqLpJWJNKqbT7PTuwTmHnVnFq/o3xlsoXMimh7OUi0VSzaXulbwFzUQsid0WQdLcHTQL69kBIociiT7sdMtx8rddodxsd3N8UC05na+FvAMKX0KmtrT3WtezfYeUXwcCDBvqV+cKM39Vt+mUOVtd0Fn7YdzYW1cjWurS1O/cH6ycBkIJaOYH5HFMoYj7heQ7UIi/Yw6jCfjansyLnbXxsVKUUQIVH3sGxcLjS8jh+/UPGj8tAnLO0nars+Xe9EXI1nUnDJQg8mKLv3uHd3TQlMPBYeSyz77PvJ66JLN5niNWkALHIjmSA95361b418858fH3/vw/2Y8+1WvHe+6c+5w/7gP/eDxR//lneOxH/Do8a1f9AXJhmW0UCSO8JK0ez8oj1KBIrcg0UXubY1UMLlzqWrjks8AhTgUhkJRWds6bF+hBENR67UhIbjvjan2+q4yiZA5+H5MgEYmkuoaSTV/TcoNq/yfRr9qUn3Y0rR8q3qegkmKfkR8bgHjMxo9CDJdjXF+eRgXu60jCOJT01WM9VEyrjZg0fn6WhDUArv5zCaptr/yyv+fqzeBt7OszsXXPns6U04SEggzQSIEJ1SUqojzWK1WKtfbwdbev7b2/rxqba3/jgK1trbqbWsntXbCoU51qFTrrCgIAoKCILNJgAwkOckZ93x/z7De74vYNMnJOXt/+/veNT3rWc+aBAQboF5s7ozKEaUWZfqMhVc17irpA0WU7E+kkAA9qjvs0JliUsaeiDRv5aVHRLrwdPAwSyno7q0gdHlqjmQ51ULjEHDvGtt2KN4hcqaiHXRqKnaUZqPeK3eog8wGeR9sshVdQZ4iB3+S/OaKi/c9OT45PqvoqilCDH8JVc3XskyQk9OsBrRzPnEtz7dPJvHQ4pH4rb99b1y0Y3t85NrrY6k/oIrJiZs2xZknnhzR7MSlr351tFrtwpSSfJAgJAkjYObezOckHMIIigiFiuTqc2pSTqlEdpl9yIwGaWLQaZsjJ83CYEV23eW85DiEcuV1ZA2bSKHeh7AsG3hKY8vKOFKqZGJIg8EOJ3sa4E+t31TSMqeofNexiKeAngdDRAn0NPDncfQG+LsUaRChKNfkzGUN/+Y120S23KjOGRgdf2xJvvqrEx5Eh1ANz9gPmWMEqBU3QJ7Rs9Vmizpz9HIdaTepGyq9WiBcWbVgpoLH1x33bCZStSjlREvr1J1W1nNCtkaU2EE/BIiW+iMIxtTZcld5MOW+CPfa5cGV91b9Ia2qNm4sLncqJyi1AUtwofOjrFWS3GgiJ5Am1mplXkWZsjq66c8LN7b0tHMOAYcEqN/9+w/EOz/yEebGN953b6z1+/y1bfPm+JknPDkOrK7H617xP2Nmds6AsbBYdakViwnzcgKzGkBj5AQwQY+tmXbCtuw56V5oVCHTyzQQRZHJSIoi2SwUbcWUHY5jy8Xhxw1lKAWkwYppzayELliTj0UMyLwo1COIEkIEdSEahcYvGAdwS7M0cGYsO6VoLTE/9mPg6REluNJNEQLkzv5Qf+4PEHGValJJBuik1yPIMDRcplFw70VxGkcRycm1X9PlIUUyypoTZnJ8AtjorXLTUR7iIqqgEgtvxkF6/wwBSU3P0+Rw2+AdQEHEDWAK1ui7NknUyDPX6Z0MP2IWFI3DwchU+AkoJogi3Odk0A/0EwgQe1CKyoE6UCzMjSBxP4hRFcxkQCg6AYlMUkpzn2dSKUIqxLPrgAEiw+J8f3tv3GcNYuFmJglEUSdfhzSY8Sj27NsXr/6Ld8dx87MxGPRj/9GjcXh1KbZs2BQXPvK8ONobxm+98pdjYeG4whLQiGxWSp6czPSGg1JGznBMR1gSpNwfn59IFUsipWsyWNcpRqyygQcjUSfaXWo7DdX7WS67OUsSpQel6GiVYikhBMqW8LeZDrz/A6VbmcQZSeUKPKrNQBK2Fx3ULq5FRETVv4sTouhAp801DZIBwi84HU4t4s+GfrPepIg1vu7pRroy3ArvsuR5Z6RDVfCdr0xyDXN+eBlLDYbFx+C9dAj1uKMIdHhIop9TmMGoRnotDih5cSTCJccorXeB1l+r2Y9GYxCT6LmRZxxlggJdDTgxf/E85amhHsIOO2+jeiXeekFDAYERMEHfdVI2DImYkPLuVQA8NBCY1qARuD6EEd3a53y2y24iKgXIMO3GPC4Wep6lV6QVNQITbYKVKyNTc0ue8fb7dsVHv/yVePSpJ8e/fePbcWhthYfygnPOjQcOL8bO7TviZ5/3oti6bZvcS/Hcvh8eLdasjAtoGqb6EMzpS9RMiDUjhxp3BW1kWuYegD2zRo0thIBDmTWFq0itIBDRlCgX007UR95E74Ys8UkACvS84repM54NMfV38r1gFN3JesxO1mM6elLPSWG/cZ8RBKRGRDsxjM0HQ13BHseExM/shwC5Sv4XfbvZyMmmUE9I902jySZWItMZXfffPu7J2tUmFTVnFD1KgQ7vDcEAhtlcX6Xow7A1gd5Ru2zBxQwCji5XfnlISUcup9Fzh7hpKWzMkTbmsCucn4rvhio1q6EGHBqF/VEn1idtIlpQC6TEJB9ckzJCjGqsBAFvCvqFkWT45ifFByQGjtHWKe4bzzydRH+8ds5/WG8rAYCk2EvBBf/pd2Xf0Ps1GIrX5kAPuFx64Lfcc1/805WfizOO2xqfu/n7sdLrMT1otabi9BNPi7PPOCte9Oznxyknn+YmpLIi2YB7D56clOiePmfOgitHH0dnCHgbvSnN3LMmguBnqZUAACAASURBVHGQOat6hUWsUS04MTJyAcvyerV+zqlAaQzyoJU9MTDgVgybuF/tmuiGZzjoLDzEVakumF5fiSywBhlDEnY95iZrMdNAMp0rKYYRjGyqZbO+wOVTHYWFtxqBMBRqqbl7X4CI0nRMmr2djbjxfm6u2ZjefxdFemKTzhnLUzAAlYP85EghYoATZVECejGok8CTKEFhX4I6SC5gcSjdi+B6BVPmSbNrCLEQHV65sLSoAM2JqyODwANQm0jKTbJ4ComNobLRceHeiRGaifZu2DyrKQ4dXjzStsUNqNFrXD5PXq5cRlqAAaQc37XjUa5LnpVEAESENCM1aR6sVXyQfTBQd4juIsV4pHk33HFXvP8zn4sNs9Nx0493x6HlpVhZX42Tj9sWTzjviXF0aSl+8WWXxPbTt1fNyhoFI0sleu7SkzCNJvu+Rp+mIIqNAz9CP2LomXQp1zGq0RiEfGnwSEajtFQpTY4QsNBlo5hVl5FN96RgJI1WjJptjkuzHuHNkNpk8peS7qP3FNQDAAWKl5CCRfSYn6xGt9mL6QmiRl8qlaiRkFoxglgohA1AqS3iPODPmValgfBcZWpqpnKaQxIl1ZAURamggeMbv+7EARefcKtTmzwVIvX7oHr+AOmLSYL6XTWKjEQhP/cW0ts6yy9jT1ygiVRDaMUUuu8uhjXemTh+LsN0HguOlkdJ2eG2yDF1qYBusZmoGRJED6R+KOJ7KOLNFMiaRKkXhKyBniQTFOdiJHiQ6RbCLoTaREAi9o7CnpFFUZe8IuPxMhWJHCRXW7WH7goOZ5I9r731h/GeT3yC0XdpvReHlo/E0dUVbpr66ac9N+YXjosnPvbxcc7DzzGAIC1ZdHjR28HrslFXxgBY9SnN5XPwhmL3b3jgYSisv1KYDa8DA4EBSaOYLAGvbUinxbSDUUZzPjkKi3uAe8wnSePQn4GscYENBrwkEsasQ+m8Zou4shqOY9QjoNAdD6I76cdMY8BNX1jPDfoS5nEA/9It2kCow+vUif0hp1ZqBEqfK4U3iDp6KJJnlGhcVXXysxUmuFJsOWaYxM3fMDNM3Bt1hxQ4xZs3BZ2pTjPGIyhTABJ2zkGfnEIBSokyF9XopBGKLHZdaDHn9Gan7hSKdm09JC7iHka9815aWaxLNHqrvNwbhTy0hDltALkYtCoQsA14HUonlskTaNDgYWGD04hJzofwpju/RSifajWi3ZiyYB5m0hXNrH/Ba4IXpGel8VRMUkq2pgESX5dhfvt7N8U3b7ghzj7l1Pjkt74ZDx09xEbWacefEgubNsWOM3fEU550UZx+2uk87Pg5pGxMWZ26sS5y5E4RC2pTETiweqEF5HitWaDDAViYguvm4L2HvWiheM6p0cLC9XQh9XKtjsh6RXk+FRIbTnNpHBDbqAa3KPwBgqGH2qRvbKeJ+z9aj86ox7qDK/CMfJKUyAyDWKVHLTTViFOH32EYyhix9QsUEgnsZf2hbCa5ejpFFUNEaR+7OExPhfZplEEaxY3x9z4/QSccvRAYQK6A1jij804qkbXUl6CaoEiCuYJYCJb6IuBnAdXBTUsKCy5KBDMh5QVAcb8EXmN6CmhFz5QUUFVqNPike9B2cS2JouB69Uv7ru29mVa1VJuw2qiaV9pL4pUFzNFx8HVtUFisH47sE1DCBjMZU6DUCO4m+pXQ91TOgUMMWp1ZRC2ABJzkKNpdJuJ5Audr114TRxcPxvzsQvzLlZ+Oo0cXef9n5zbEScefFNtOODkuOP8Jcd5jzncdJQgdi3+4azAF0pxOqaPNmOYkQePD6A1RC7K2E5zyoRbbJlJF+HcU7SF6EENGk1SCmTCamkVgeBmHjqPJOHyAV53SEtnT0IYgf/ehpqdCOsgEDQaEZpF2suWI7cIwjrHSKSp3cmeJKEwwDmkJJPER6ZUYzjkxiEIdkZPpFakjpsF4JiTp7vQRGR7owE2ZT46Xlrjo/DFqIsVKsqCqPEcN7wXO5JyFrGX0Abk680EvQJMhKM4VPZiDGnpUfyDxD1uoMXgZoeBGwJHovmOFWGuK0sYmCqb6XRLpcPEappKsqCfq+Gf3Mgy7ajSXTLEiQkCZf3wd++g8soqrA5ExFd+h1SvqdbJiVRtRZhS5L1TRuRZW14T/6BSm2ppsTMat081SIPogp8jCV779zbj2hu/Ew04/Kz795StjfX2V2rytZjueeeGzo9XsxlOffGHsPGdnWSHBazWiljwmKbRoXFhtWWVk+EwCWXx4sGIMf4fquyVhE8kpU3dQv2e9JO6U0t6fpL6LKaCKykaSax3MscqcH76105hwzcQMDIHwrtI5Qb099aUmSLMU/1seiALoxWQZEcX8OHX7rSHg6cZcrgMOFhFO4y4CEfIv2fPR33NLVym/XaCnpG0p2Ec3f5vpskp4yzc635a5iFLA/2CVSOSdNgH27Y3Ak2rHOmsALYxPNhIKXQVDqPcpOvGCG02xN0tRbk6+u63ovmOZZpfDtIB/17krEBjZhExb6eLGBKNQM9En05djUdas1XVz4YqNlXPb/CSSyYEBg7q/ml7egztIhfAwsVxHcy6eq7BXkdcaUfgZnyOHdpT7mznkFdeqlTwu4CExiLolD/jL3/pafODf/zVGg2EcXV2KdqvJwhMYfXd6Js46bUe85Pkviic96UIPQClF0LoydRkgFEdNLzb/VHNkGw9bs0TzAa4/FesmURP9o0yoNmKxIM0ZGX9OFeneruWZlkpZXY+YjUKLLgg71TXhJQjGcIApuEkY97M77kV7uB5To77u7ajHPwOZYn1k0IapVXMS01yO6oZrocGbjWEgjilVOqRELA1DJ82lfm2puCJGcVLyibgYnpcYRK4ZbIy/f7XZaTn44wLGh1dxzEU6mym42VbTAA9o0qCRrGLvHqsjIA3qKyT2TYwcd9SHCtGXvehUPDxGtiULXqQQo8DOPZXd8PcwlPUI/NK4n9CtcSf6k+noNTCd0tE+DGv7csoQEcXawAWWpFSnGowsLH2T0/OKMIdOtLlW9iEZfoco5EGCaTW5+kwsA3DXZCSEmc1FxXuycuIiItPLYxL/+fWvxbv/+b2B7bKQC8X9wGwCNgLPdGfi6PJSvOk1r4tnPu25xdFkN7fi76aipKII34s9EMR0C1EEVBhlFPz8SDGJ/KEms/qAAYyqw+42u+kZqksrEesibWRTlcma5MnxgmFMo+ge92N6hIZfLzpIo4Zrlm8dBFI3QMkaZFNKwx0uNPwx9ybyyBjtQHptHocieiEaiofGYOEOv9ptWU8r1VMPRJ8hibTGGvnZijyr4SyWCL3v3TihB+Kie+3AS26SAXeTB+0h2Jr3gTIHDO+Hw7Y6noo1Mm+rzjlD9FBeH1GEmsc5+UZ2Y2ra6hCJqoGUS0ka16PRs6hBZD0TskPp4YDIgD4w0t5yIFkUMkBNNNWJyVRbpDZiDWzfMQXMzVYc2ne0SZ0pNvJQDJsbpEinDjYPplEpbX+axKSJ1MrIH2FCUTBYrCfjy/MN3pbIr376i1+Iu+65M+7cdW/ces+dMTc9S+8PcOD8nY+O47eeEOee88h4+lOf4f6GgnmurBOFx41Jpzb6GmgmyfkKzu+sYdiNUUO5ea7QY4rkxplbATpM7iEkU5acK5MaM0PQscOtcc6O9AypKkCP8SBmxusxPVyLmdGa0qfxuqgvVLyB60dvJtHLkndodoSplXSHaST2+ALEqmU3VG4sG6W8INQwLtFFRx4xf/WzdYJmSf6d+cg9ZySmgXxvkjvMcRFNFEitwlcoqIUjtTeMqi+RaAEcgcSIpdgOY1nhllQTIAmzCQ7lDnIXMKKJJ9FNnVZarUXNWGFwZBb6vyhMYSjiMQG/1+ozfGjktj0iMSyQkfphhsSEPvZgOD8u2JZMWNLlp0lXwfKeoWdMRDCwsbrj3gZvyDIySYXmd9GF9aM/iliJDot/SIUirdB8ttIQboIi+qT5ePyHyPXvV/5XrC8fjdt33xcPHNwfK2vYD6L5yJ2nb49HnHlOdBY2xvOf8wKmc8UPulDG66QKu6D0jMoSeWDNlH0pKhwaAvYsOo2XlO9cmSB2sjuOFdeJ/QFB2ix2a41kDV4lf0DHqzsexdykF/PDtdgwWorp8Uq0x+tWPVRfhQ6TCieImGIDw9DUd7HDdteL6JJ7FGmoUoRP4zaSmcl9bU8IV8wR81TxLWNWya5i3fMsRmPr3DI68tXv3jCZaqq3werBS+VhvbowMVf1ooJ22X9A1BjJg1QCzpKyZ/hmRPHqglqdlOJ0AtdEqmN3d6jxR9NiCkWanXhsTEK61QTTU5qCSbKG8Bx7HeB0OqziARBZIbKBfo1uMCOCd/oJSICuFqgpwu+J9ODGA8Mn41cgoKJaaNEOm5raDEUynj0tqA0rw0ZMmlpt1vLEn4xNjGL8gtA3+i7woB/47H/G4Yceiq2bNsdXb7w+Dhw+GH3sRG93YucZ22PLpuPj7LMeHhdd+CymrFkqUi+qKOhn/SiYGf0R4ine4sS2hWuPIgRnaFOeOCNDAv/+HQeIoIwYsPg+3g2ubat1K3VolCJ5kAlObW7cj42jldg0Wozp0QrutDZ4sS5y03SChqXQTj4hY0TOlVz7JlycOa78UlGR8cCXWN/JLcsRhmRQp/STQV4TE1UP67OoS1Ux03OitnHg6pu475Sib+6G00imsL8CCw61C1iNFMO7DlV6ZflUDqow9VJHld5qhP0PyH2VckhHoDZ/4UeuWQQ9/rz1jCV0ZkppUBNgtBfdVnRVc3Uabi3fm/UEt3yU9+froTGXqwzSE9VyUFFkmrFuGR2gPGqyGTJO5Q9jYaTMC7Go1l27xuoNJDzGZ0Wky01GPgeFeKI6TN3G8f6PfijW1vqxPhrEnffdHUeXj8TS+mpMt6bjtBO2xQsufGYcXD4aL3veTyuNM0NWe7x1oIjAe/0ATGiWNxC9Ca040yCZ7qOxFR8Io3KlchFsrWdhvpbrKtbfOVOSjoMwriJKQgb82A1Nb85OhjE3Xo+FwdGYHS/RQNrgUbE7L8pNNiFFhvAmLBUSvsbqRLD9QC6XF6aah5Zpn2ZfVMtIKtXnyaBD7ttkn9KETzUtdeIk9aQhQTY3qJ4zFY1919wsMoS/t1CPmRpoyTo0eFutcTSbKjeZ9IyheijqBqIAHg4jB/fBqYjnxlBul1LKqfW8+tBalOgIldx7d6rTV8i7KI1g0eYNs+ypTAYxM1lnBxaoD9ItGKQMU7I3PVwPUwMp8Gnu2UaYxTfZxyOmZZxTZicWQzRTMW6iZmq5KYgUT/KXOeWGiyP3JyOqB3JIjrMx4LG3UITb6DSeLF7WRz/3GfK+4Pdv/tGtse+hvezgr/Z68Se/9r/j3v2HottpxTMedz57Pb0p6QHksBKfmQ0adQveA7UTUjoYOe4J269lTXWyLW0IdBxGFpOIUwQP7KpI/1d2UZ9Zn3Kk1NyQD50zEDgkIFdzk34sjFZidrwcnckqp3c6IxhHz7QRHWYaJLl9jlI5UpHMYSN0HoJ1XafNyEL17O89/SmttTw9MlppumUMrtU75q7hOnL7biKvTMz2XXfLBCQzbvZyrmkGDZszsERNew2i3cQMxTCQkiHEDyGiwCk/XCiyvFyiY0yeRqLLEnHMFACjIakWLsGACgXJv2vqQh8QXlsD/Sjcqgk+wMG48UjduPsOnhNiD0SEFL3KwnlDoCofhNIApULqJI6PUCTUVIQP8RntuXTTlaFSaMDum81RpgdaIsOVxGUm2iWf05LsT6AOwf38109+NH7qrDPivr0Pxdd+cBOh3taUJrKfcf7j49TjT4rFpaV40VOfHo0WqyCtB/CBF9xhh5Oxt0xFai9fcVSpNeDopyYu46D0ylxsc0AgoW3XNOmwBC27NGdKJeoIzoP6Z3od3Btc7eykHxvHazE7Xo3pcU/6xi7UUYsyqpmRy9LHwgtuuak5ScaGwYDy6snxUwaD48cKzZpoqmHVVE1QSEmUMxibu0afTNdh0LFgnjMCuo8937l10gADsxbWIPUDRAuejrPZnogDuoDDBESpPaVBHMiDYk/FWgOG0o6xZyuKFA4/pJiWityCQxOJ0DgkiwcTFf1BXGAKCtaTYkFq3kzVS0fKIgFOGqHRI0QxGaQiFxAc+iuPXEpfFg9yEl0rLzI8e56Ah8vD/IqbvnmIPCNNviFScGwz+x6gWDha4ZK1S0NlP6kLfo12o0Ep0yv+46PxrB2nxZdvvzN+vH8/jWF9MCD9/pQTTowLd54bD62sxC+88KUxaYKE6ULT+sHs6JcHr7qwTn3hQJUjudZuZwrl1EUhSNwq3GKemFp9YQa0iNT+3rQWR32CA3AALY8gGw3C15GBoDm4abgWC7ES05M19rbg1Nj/8P55iiqYK8WuvaOYRUq8FUrokpI6KNnrnND9plggz0bOw8iUk8TpCqViE5gRwe4DnYTOZH5W1SSNaNx97Q8nItKZluxYgL+KoIf/01qvLFrJCiVtoBetEQwllM5wmAkNqVYMmu2YohK52yzcY2HZfL6uPDL+Ocl+smhfKG2iktnX7dGgEQpWoVeSidEGKBiuC0ouqkexbfWVCVuNjAg8RObykALCAlzcING8RaMWXUGEPoEOMi7ckzHqGqRiGMoxMq/ohQS8xc+NXoyKW0VP5ciwmkG02i12kf/min/klt1fuOjJ8fZPfo6KJuAULa4ux1/82mvju7fdEYeXjsZrL74kxs1ponKqPXBARKoTNC7PzrkMgjQqTlLthQJ7nqmhR7UKjA6Hagnez9S+VVJaGoiIEmJPOz7YVlzu8JDgvraQL1rLKqsIzgNNxrF1dDQ2j4/GHGmjqCEBz2MHPGgq2vEuhZE8Mkq9UteKnCtSmXC5ZnmYL4W9KGr0iVtFEUP2VEzHJyrmBjHrMlGT8B+f/xR+WXCDTkSFJCP+7d+9k+sPyA7NAXh7db4BRxT1cQveQDqFim0yYQHd5l6JlLYCmmUFRDI7iQE0Y9yUGANDHqODH3Ku9OI1ZKomzj4OpqgGFiGwmAS8B8Z6swDlWK1p2Vlmi+kq3EtTJ+An6UTJc4i2DmPVA/H8OKLjcBx9pmp+3G5sylOrONb8RTatRJ5DMakETgIPEoHADwyjMRhEo9mI9ngQl7/vPfGkM0+N7/14TxxeXor1/iAGI9RDg+h2puNVT39afH/37njTz10c0Zxls49NSD88DaMldUK0c0Q1PSw5CXyvakVzkAyNKs3M1EWVnq7Z/w8ypnaaSg1TGwxpVcYpJS10rj4P+GzZCq1kbNUfOW60HJvHSzE7WaP2GHdbejgLPWZEeew+pLibBRXEacqVC05jPe+Tg2I4zFpPDoRwIgCnqeygxY0DloViaor7VKiSijhmmin6qH4V92wSjTuuvytLZb5QPlp1qTWiCTSJhyl1iJwq4fbA07IrCcarBcJYQ3DOQmgO0h2QF5mRy/WZQq4brA6mTDBxcFxH8eKGGYWtJjDo7jQjVHVA+cgdhZSZSfaHB8YDVL1amoAowcLdKuA5DYiP1UOj1/mqIrlSEXlgR7faBCUPnWHRgYIjewYMWPgzZjHAXm01oznsxV/9y/viEaecEC9+0hPivV/4atzy413RGwxibTCMN19ycbSb3bhjz+549fOeFlNNzOIDeFCUTmAg7x3BU4oQVIUovCRAk6wDywSdiwlOg7r7bkIHfzp1fem+as+GP8a6owBNTsgkwSOYjDdBzxd8NUcUHjk2XzHrMYz58Vp0h6vKCCZo9GpEljWjN9+ynmOeZZJiLthhKo3DLiaxVkAopUI2MdOA/NSIvzooFXgdCJfKPHj/jKxmnaO1EYqi+prQ2caPvnvnBD/I/JzhOXu9VqrjIdMhqlAg3Qh1YAX0adZZ7mcy1IBNa4hcE8UYPrxYvhQhHaWCoYdyOLfsc91sGWd3Ec2XrNIuGYgONH6p7qg6uQn1Ib0Aiws/S9YrG1J4kLoBlN3m4ZWBg6XLx25pflKpTa9gRCDFRveEqAj0603VEK1fKZVqORxgedk8hPwyHA39wyQG62vxrn98b7zl5y+O+++/Lz533ffi1j0PxPELC7H74EPx5otfFt3p2bjp7vviVc9+Smydn+PhgZJ9Nrp0a0QjgYwNEUPTMTJ6SFBPqRejntMxsX7xAu4olXujQ0msrvCfcNF65hohS+1cbz72vyiddscaXiE3QaGfZIgd9W0W06hnp8drrEca3KLVL3MbSKXUbNdsDmo59T+SHDnhHHyWsCzsE54GORL1z1QjOiRr4DrbMWk2Y4i0m6LnoB+JMq9UU0ADUuOEuxkJ77r2tkkqYggtqFADlgq0cG1Z5YCLawqxHsXutdCFQ7QOJQG47Dewi64uN2UeqfdqBMLTa/Cs+vCS0BQu5vBnPX3JT8qlUQ6GxiERAnzVnF0T/qoF9YoKvl7zKRKUkJSREJ1K9lLGQITGiBdhVEcThHGY2fq4EatDaYTh4FM4wF60tKismq/oKRvEEVteWY7f+8t3xRPO3hH37t0Xu/fdTyj3xM2b4759D8TWhY3x2O1nxm17Hoi3/MLLY+fJp6r34uvRclUd+hUAJeA/j5BO2QN7YI3Fb0bYjBbmI5U00YgUH0kux6xFomMRKn0P72g6Xf687nDW+PwzmM9Zg3r+hlOaMJjCSVN2Ati7OerTqSIVzf0qMI4xxN5GA44jc0VbLXqzUUBj17lQCYODDo0BtSqEcMFQWtFowlAgXythD45LZIPIzl6KnHYId1x7OzttKmqde9FGcrbakadEEEvRO2TKH+fQmEJeAabspXzrXK/DCkQV4cyz3tmQY0pAOpXyOucMz2yKOZ8HR4e1l3NIIG2SyjRxkA1FeUzl7EbqKCvj9/WBZW/BzNOEuPlPjKipVijQAr0geG3kymsAJegglDKqaJU6uCJOg72UPDUiROJgN+LHDzwYb/m7v4pTT9wWjz7jjPjubbfGgcWl6LSacXjlaGyYno3H7zgnHjh0MF75vOfGBefuLGkgjh15St4KuwwDAaMAA1KE3wFvKyMgWmdUqEDtPmQyBhXjdAX+DMmtyvMum3eulQfbEbcMMySVv17gK+uRW8k6jFlMbolyM5VO2f10qy8CKWSaDsdKpzqMUX8QI6B8KO7hUB25nFMIXoKnAvEOfRpONAqKTsIjJhwp9WQeoMTGDXwYgcuBAbqBH1z7I/07wr9JeVJNcg5mqrNU7NQk4wQG9nwbg1Vuqw8IVETqi7m8BDdHH4FjmhyYQURRkg4EgbpGZSVWVXTjdZGOADFinZOqKEQ07BX0yi72K7qD7p0iHg6q9nInCqTCTx126bbCmFjQsVk5jummkKce3tvozgDcMopGgAErtrJEJpQPMPVAk7IPThVuUJcdcPwMPidgQ6Jhk0bceMd98a4P/XNcsPORhHfvfnAPJUaH41Esra3GY7Y/LB4Flff+KB7xsDPieRc8JSZjCMv5uTQmNIKc4Fy3UiBhbjZnVSehaHc56evM/eU+uCVSZGGhnpSiZfY97KFLq0MRRGYj95fi0v6x9L/lVZRNOOSU+XD9HCKKlBPFaNZZ0X1tUHxBu0Qk1DCI0XAY416fRpNXwTeaQiSHJK6dGoyEzV68tuVZcfZI0KocQmmUpzXX7knj1qt+wLlBihS4m4o/UDFC59JXrEYMta1yb7qbd3g9zlrYoycpsPwgU1OzhF0U84bwZ3xIzcdi84nRCRCubr4gXSFewKNYe5SR0co48onihjBdomfPmYf0IQkRy6ARTbIHk5LcQD+k70WeAF9Wc85K1tSE8sIgRC4JvPKzUIJmMFTPodWVNCgVTZBCouMvI/vSTbfEF6+9Ji6+8Mmxd3Exrr3j7rj7gQfihE0b4569++L/vPh5cc4Z2+P+g0di10OL8XPPfS6JjLgPvL4Ipnj4HxdMeH85jpUKUF0vaiEJM7sRl5BwLrpJL+80ttr2VdWWYtJmpNF5IJzjCJzVyTEml9SWYiI+SKX2SdQ4MTLVhylBdYyhOW2VSIPvM4wEcHuzCfdTGxMzTSYbIqZP5evp96qnU9gcNnYBEAWZiMYP/vtayQnwwFYLEpVnZlxQAYhDB38IwmDmgfC8qZCngtTphvN6SVbK8pJvL/lH274lJxFRMqWRsoaIBczrffGkvvDFxlTyJtAKVIhLcICpu8loMEVOKTk8EuhGvYBCtoRV0+opDEe+lMZPGUVdqCjlxs5EHbpUMUk4mjQ3F7HMqD0DLXqJIqdqL9BhJC30sa9fE3seejB+/hkXxm333h8f/Oa1sX9xMU7ZujUeOHwojluYi1c974XR7nTiqpt/GL/4kpdGD0IHrZwfhLPItcVOBcmH82oxozriwIl6kWIL6i4brfK9Uu2kw5XO3mVbDft1TMnGoesLfTWzdiuX8IumnxvF4aBZ4T5VJqAawIfSbFv03HLvZELJ2WAWHD9kAY/n20Jt4aghYqp7b1knE0TJYjk1smQk1SLQFOSrLJivdf2V35rAU8tbKy0CPDcha7UZLWL68NjuV3D3oBtS7KegF4H0RJAgBpV0fbogfFClR86FWTRluWsTtLAwYwe9hDwlJWnw/UILbPuaUtNwjt/HzT7ouZJKnfVDzgV7aAqNw2Dzskkp4nxFCuB5aYpqGKVmSgkVyURlSa+qrbY0Rxho0yU5DMFwNr6TiJXdDI3G/Qtsk/rLT30p7t21Kx556qlx/a7d8cCRpdh/6AibbWvDfjzqjNOj056Oubl5yv+86Zd+NdbWe2oCNlsohphj8wErpPF5KZUkfOLNuD4svGXmPSHgIfUoHQB/j1FIoFdCXvx5PUMh40nSo9JZfs20CT7jun2U4tmGYgG9lGySWYhgmHsw5aTTeOr0lUIaVvqFSI1aFlmNYVy+t6OrH65gDTuByoHqwuk0nB4yQ/PW3Kq4iGhc/fEvTlC0gJ6Nwg+vRYNhce4pHAAAIABJREFUi1aTbhLWxqxDFXzwYoWe4hsn1MDFgVmm1V1UvilqnoNxskx8GP043CEnPKWGpJUOM/WCgYgzbFYr3pIFPYq6QTQHmGf3Ep/SEHMx5tSA4byJkJ6SRfI86teK1iLZTXvNxOgMYyrtSwsQwpVar/ZhRlFqntno3HSnE6//u4/FA/sfisedeWqMW9Px2etujMOrKzHXnYnV/no86dxHxPaTT4s79uyJ5bW1eOtrfiNW0GmnHpSTGpMn2Z9hSiHIljl1FuY2Ah1k/WxeH/tCKFKhhGiYV41N1xYuWtO/6ycFLetJGr3iN/gU+jcmxAVEMdJk2FhRNQscweFSWJFh2+5qkUtXUOguzGhVxGeVxOK8vG61yFNfy6igb8j/ObxnZmhSamY6Tsau/+BnKNHBS2AdIkNpw9mqmNClOW0jtYMrkHMbqIQCSDMfIf2CITgVyqaL+xzs2Hs8TBHFZDQfHHkOz1wb1RBfUx9QNYhTKhizURj6ATanhH4BAcEgkwZyRsLSuZ7BHfxSYyqlFKCgcpOSmHzYFnzO3g4hQbk2sJf5H+4bD4EgNXGHco9Gamrpe3WG9Lqz3U68/E/+MVZXjsZZJ54Yq8NxXHPHXbHa78cJm7bE7v1745zTTouTtm6Lc87cER/90n/HB//4bbHaF1TOaOTPJq0pZUdMXfl2NiKnS0if6l1txjtttygQKeY8xvg8YC8bToc6iWzE0cSeXeRbIZ4J71bNwwrOLg6PD6+i57utxUOvO1IKI9E7bCh5mPU47AQKN09p09ADZqhFZES62xU9X++bohQ0jlw9bRaA0k2LgjAYp4kixfrwZ/hX4s3O09DzQE5NqjaiC45/6Z4qBeGuDUuITreQE4LqDrhRpBVwW/AnGA8OVhNLJ21w7LJySAufW6IByZAtDFMfUB7aWjeWTbop7fiTx8/IoJtMiX7rOknFvBINE/6cHlh8puJ1Ss2k5qPcX/Y+7OGMs+ONGCmTtuK+gOacdaO4xw9Alr7RV6o/T3e68bQ3vyte9LidsfP0U+LE4zbFP3z+qrjuR/fEI888Lb57113x6DMfFq98/gtjbTCI795+d/zsM58Wc/MbjGK5t0GVFXOeDf9MOMQmdCUL89SA46XZGQDhy50wld+2E7DYdPHkVHDxxiynyjzIhlGVjaWijL2Bf2Mdls3DrEUSJzM5UO5DrrBK69KtyOA50ZrAQkZ6EDH7Ax5+8NuoNMPEsTQW5MDS/kylKnpgfBp6Jpl+yVa91An/euuHPkq+MDWTPHwkb6ObjA/YnZpEFzMhFFtwkWNvQj4U/w1oiREe10Q8aBy9VfgUdwnQmwfkeV8Ev+Gw1qcaJeBljIad69r2JI/kSpssE1ZL9DjU8xZlbeZcWPYhj57UBGcR9rzZ7NItVvek1oJiOuuhfz8IUjuse6U0T7dc/Qc/gNKRTmcxFU9607vjj3/xp+PsU06I23btjQ987fq4+8G90W43Y3F5NX7txS+Ox517bqyu9+KaH94R5597dmw/5bTSEc80ib0N6wrjcAHm1ECVokM2ZOlRFeLMPFC0USpW3HYhLSaalGmSPtUUe2WkY7B1IOSlnq6Wvodrkcyk5IqMhjl00ZBLwa8bx4hkNUuZTRoY45Ug69qHgyo+XwaOvA0AQ99X58MUtC3VJJ3So4bzD5v/l2dJBski/a4Pf2iSqt7I7blrW+U9WazUnzU7EqLKLShJOudPaDcvRsNAiDYugoxsMEKRHVuNeLKIzZSKNU+iCDmgn7VVBR7k5eN9RHM2dGvqsr6OS/dksYtzJ0ylSIbnxAFOWJqhmSiUehsq4KoGKKBipl74OujyhXbvCGMSZaadTB3MF8rowejJVKcZh5bW4wWX/kP8+jMeH7fc/1Dctf9w7F9aiyMrR2N+bj56/WGc//AdceDI0Thp63GxvLwaL7jwqfGERzySZEZRgnSQyMFSuUaggaxXFq2plSwKDNMMhRDVrOV3o1uuuXiN+oZj4NCse5RK+jlyLELdL95DUN6NPk1xuajq2JQAFYQ/pswRoyyoSKhz2eFuqiZkWqeIpVZA1aVXAFJ+rN5TRJ/r6RQtp1r1xmCmVX4CuGcpmJUZiesGFvz0ZnYajHq6Z43dH/lXz7YKCWGfgykMWFPoyArUHAwhetCgAXSaQq0otelCmTRkOwl8H/5Fh7DaM47ahTWGH1R6cTYEUV8kH8tlGtNWPqzUtKrPhOkhk1tldTylaUXUzwdBX0gjYd1DdrEcAa6RNZbBiGoSTdEkIwKv24M4ebjwXqIOqj6iVKpTunIAS/1mf9icih/uOhCX/NkH4kk7Tout89OxPprEdffcH4urvXjWYx4R37jldj6Ln7ngiXHX/fvi4Npy/PSTL4wXXXQR4WKKthExk8yQYp3ntEnnEWWxdIxdwFeG4QPAW5iHoVYkO0WVZlwalBAf7uRwocs4a0wYbiMNwVW+Id0pMguyoSYuXA0AQS0Lqg6uEQYC0QvK62sEN42u0mN2PcooJigeFJSCEqNZCGNzZCJwz2SoQqzoBDmLIvV31Sgg1/pJgvfFa55E48Er/k7AJklt+kzt5pQ0iTw7QNyZnCkpfCdXBZ5VhygTEeV/DWwDKgfDG0+L+VgVvuYFkmMkz1X3ckJK2F/xbpBM1fTOYh9LaEKRJ3fZVXibi0YnTS7FLSJnOkgW2l7LVr8GEd3ktVT/KEXjV2zBXOxiFpD2XhhCTBSHv+tgI0++6tZ74zV/++G46OwzYr4zA4GYuPru3RSuxqHsjUdxzqmnxJnbTlFzsDkVWxY2xq9e/PLoDeExpf0r3VndI33epPlUewmVIpEjI2fiOiAznqwP5IiE7yhFceJu5nYWzGkk1Vq3ZD7kRJwxIqd0YjLgpa257IEPvUeilDmX4r5VNiEpK1ut1lbkyGtLMMCgBZwFnh/AGECwBRTIn0/3rc4zo46QovK89McEOOxSd73v/04kw6jOM6ySOzJYqAvyxetQyNdNHFG68YHVB8AjIizsgpnMzWQF6yS5YMwPZXoCD7fyA/JmiMKIns1JvaJ3ZK3Vgi7oobMTnoda51akQT/9giplDZIYh9MNKs6a++8jr1SBjiSbponWSGsW96jVzv5AFuUaC+CwTpmF1j0VM9b9kMYkuq1m/Ps3vhfv/8JV8ZsvfQabj0/YeVb81j9+Mu58YH884/GPis98+7p4/ct/LrZsPV7121Qrvn/nnfErL31p9IbqMHEeuzTH3GPKw10vUtnBlxflPWPBzTEp7Seq9zbsdFQ7Onp4HFdZd+rtVk01MaRlmPx/zgL4CIzoZcpGb23EgHpYyEowoz6E0qLY2XSWSW/3odf8hqICezd8G2QCBmlojIoQY4wsZ8TMFIDP35Eru/Hs7TG+KPKRj2jJo5INTaJxz9+9Y0LhEj5FwLBqcCnFFysHEQ8DKEqdEgcXjQOjuSolJLNDUWtliDYYh3EX6OydmJNDM+GTS3RF30utveROuX5UV9pwZUrMZCPLL6l6uWo00ZDpSdxNNm2FFP00mmQdFKRDTABGTxu3M+yiYOZzoiZgYUBnyucarUbNcDbP+9Rpt+KvPv2VuOFH98ZvXvKi2DC/EB/80lVx9wMPxoOLi/H08x4V377l9th+0snx/KdeFPPzC1yL8IM77otLXvj8orhCz59kQ9dy2vjFY1JWDfDpWJqI1H5H/CyuWWyXfkVV1FedaXmbhHHpUKr+XalTJAWU7YAacuWzke9R2MI+hHKVWBenFFU76nW2uB8GBxo1C/tanvK0llGmT6xtM41L2J7ZoM6i4O+8N4qTOno6pwIpEvBR3cPPg2u8/z1vJYqVqAX+mX6RhaChtaQya+luSauocE4jYewosCnz/MInV/SgZzEuRJ6S4TTVQpmX6sU1pKMTqo2r8uKyK9UwSln1N3KRHbEyH2ffn5FCRs40pNREacKaTdAJEQnRx0HFPj2Um2IcidB4Kg2G4VxCUI4xzpt9o52iKgLLCvFazVYnLvu3T8TB5ZV4ydOeGtf/8I7YNL8h/vs718XiKli8M1w8edppJ8cjznpELC0fjTNOOz2+d+ut8apXvCI6na7z7drJNu6vno7RK5InM9K6oWkULz8lpYkISsk7p1vT3ddBYSSlUehQFUTIp8pHrIYmiq1cMmrfwRTJyEhTRSNfIx+3AAL0mQjVc7mP2d4eP9CV2ZvlMTFIgVqE/SEedqX9iBC5pgFnbcQoYQDDQ1GZLSRhUufezvaH7/gj12J6kF1HC+0erGaRK4/uPNZIV1qa1gEklVnRwzOEDtcyJhzGRD7UeTYnyHCtIoDoLRKm83LIwr60eAMjXirQy55SGAFNo3xGqq2kJ5yQbAoT07vQq3pKDneCrE+P+lJuVHqxiLIsipOwCNOEwLJqS9dK6szj0KFPxP4hm6hYW6ohHXzvW/72fdFsteLMk0/nR7j9x7vi0OLhOLy8HKu9tZjtzMb200+PDbNzMbdhPnq9XiytrsSrLnlFbNm0uWSDWlGq6JuUP8EF6SGVdhCRsxOkETFNca6dwAZZBaKtZLsta6zSJU5YlAcLDsVjk3oXHV2jffY0pU4saS8zAltxqeWyHazoXYp8V0U5SZopmgiGcsplboMRYyTKEOdNFPeVhupqMloUQMNOUzsq00FW4ZGB4uuX/fGE65CNBrHewP9EqbIXrhXWTr3Si5cUA29m5Q6YX/HFDkVEfNAvoYSoTDSpAwoYoqIzC82owTRCh07FmR6d5jLsS/zQ8H0gIZbOMtOkNCCLG/v61CNJrSqjXvaOeQ0yG/VB0PBMZRbSyJ22AMhAf0j4vLomvH/Qr6K30itQjcSfYbk3iMv+/h+47vmcM88UCbQ5Fd++8QZKDk13ZmNtbS3O2bEjTtxyQqwP+rGyuhqD4SB+6Wd/Nk49+ZQifJYpDWNaqUGF7hggddT0ugB3vhuAQ1Prqmh42TiSel6efdXZzoikx6Xi236tHEIZSvaAFBGUwTiqOHNgoeyJ0Dy+NGSyOTzCm5mGaTNp7OyE08i0Ajo3GFOekCwKZRnqk+nVlTJXfa5MuSQWZydanqPLApy3z1/+zqqEdVRlFstPhsLZepIOqfTp5lwJQUqHhmJS3l05b2UASFUo/gYuV7lP6jRnRFGAr6y9oEYeJ5b1C22DtdNA+Ok1mywVCi8AMjM5+yRTnPir7lYWlpxDcIqYKSVgX/gejmoC7jZcqHF4pZEsOv05YABrSJEnkkpq5mqFwjMwvmXH89CRo/GH731vPHbHw+P4zVvi3B0Pi72Hj8b7P/7RGAxHsXnjxjh0dDHm5+fjN/7Hz8dtd98TDx1dovjckx/3+HjEjh0yQtZdSoULjG18nwJs1jnOAoLr2jLZziEieZnC7dLBl6E02ZtQGMz6o3g9vqjSWjlRd6/tUTN99lFwFKv3GGQ4vB7P8AtQSmtS/q9aQWlSiQIlDdb54nlkf6Map+Ced2skQIEHaBlJVBYwV4/IKie5oTcRslpEph/97GXvnqQCdgmL1t/N4tnFiC3RauL2UuBm4TLRZKSOFqME7rSCfsKHDIeGSGmxELym9wJihuiiMMuD6AIOhwLRgvVbGigfINR15DVpOEjF2KMxR8j5vjyrOvfcDEUKhU43k48yi5x/FiqGV+WoZhbaTjtgZDozKkhxXdy1MbSx+7AwreI6ZKn/KRdWlLnvwf1x6fv+KS55zjPjvLN3xP7FpbjxR1B43xUPHjoUWzbMx8EjS/HKl7yU6iZ4kP/1raviSY96dJxx8knx2HPPNYInXy2QqeKUKZ+u6sTERCo3ZtTDERnrG1Q81vIQ7DBBg7jVjFabkn3HRnxTRJLtUNIX/kEHWs8+MwnVgeqZWRfN6Y3BsmOmHus9JJqika9s3srQy5h8gWmzp8OmplM9ooreLpAUFNohjIQiff74Nre0AYn/jaPxsT965yRRG0GueaOqQjZvnkKfaO85zJTVP4+6KRdoCMJwOLuts1SabMyXDR3yVhY1u4ROdVPx9fTwJbJkvmwYUsWvwqlqFw/d831N4nMqpWxLsyH6nCryU0xAD1swrmDt6roztROHTK9T1UY4CNmI1GEtOT4dW65BUw3yg7t/HG/714/H377pNXHXAwdi9/6D8alvfCu2n3hc/Hj/QS0Iik7s3P6wWFiYj32HD8Xc3ExsXTgutm7aGM968pO8TtkGgs9eImZxcUppRFWQEeX32GkJJlc0Zt2BGsTfy8BO5XyFU2y8gtRolu61bKlSuuHrpSqj2Q9Z6Lvq1XsmObRuLL7ORJW8JLT6NNVCThmduujJEFDfST2MqtDIXpR7O04lRb6taDc6v2pKkkZf6iMZeuODf/AXqeuuY1ZyWUUGRQh5XaZPRm00f6gagQfUBXjVIFRXXv0RN/Ls3eRl8HCUeuGQwvvTOzt1oKKFxc5yZj2rfT1YZ7Z+0DoIilhCdrMe8ACXchIZkSMTghDf11gYr5O9H9VEmYqxy54z8Nk78EGjMftwZGSBADLuB723d4QAqYRW7tdvui3+9j++EK949lPiSzfcFPuOLAdSwCSLCnEbx1x3Oo6sLEcfW2mbzeh2uvHMJ5wfv/KylxJIIDxrx8D3yvnr6hjX6NtG0QhqpACgjl9GGHzWJgQNHH1o6KnMAl2yqalot7GnMkmeBd/Ts8QBTMQum8AFeMkSSahhkqFVq7heIsLm0WyjTwoCFRdLVH0bVllAWo1oM0m3wF+1xsHPMpEvQr5JlHNq7nqG0kOYVBxguY/g4cYVf/BOx0EdOMWPLLHzERhuyI6zm3Ty2jpQsivrajlvV6DVq9LZ+5coOn4SbkJiHgWkR4h/KbVSRGJk4osYXvUNxbtRlcKokt7Im0kd3tFsZN2AvR2cPNNMC5eyZLFvnd/83Pg+FN/KPIygEQXCsL+MWMwDh3miQiBkKmyLbIcFp7oeXBf/nVKmjfjwV66NK758dQyGWNowianudMzPzEZvbU0Das1WrA96MdvpxsHlwxx95mBUcyoeedaOeNNrXqMhtCzMMyI6UuYMjw5r1g9urqlxY3DHFHZ7FBXIiWQ5qjj1SkoGvgcTjiXCugGakQfeCZ+RKGEW2GwS53mqTlamO0rvde7qKZnql6T21/7NTcHy/Rae06iwv498NYMFhod5jTawcsQLlSmRv8p4eadwD//19/+iuvpCOfbJ5rmsjSJmzMvwnIVijvg7+vislghZOrO2YqfNeu2MLqTXVyLEXvKsi2T6I/i0opYYMjZy1AQyU49w7pmoUDGw4OjQhrIhDU78Lzo6Gxs1iaciui3xqvCqFKimbKnEx/jgSgfZC2WIAiqhxU+lJm6H+jw6rCgV3/nxL8SXbrot1tdWafQra6uxddOWuP+h/TE/PR3NqXYsrizFSVuOj/1HDsaG7kx0OtMclkLz8E/e8pZodSxMkI05RoWEvaWQSAdUCH8JUKhmMVGgkNZoNy6EuROEEDaciXL0kvtzWGscrTb4Tl5XkEaXEkwKm0qr+Ua6X86KnfJVDRWlNFVmpL84IzGvrdQtZVBKjlMRxtywWlpWXhPkTfK0ki7k9CIrCafa+RmT6V075pWBKK+u9oCoW1z1JFjRU6jLzSOZq+JGjut6Hj3fQFatD1AfgtG/++qqnE4H3GmYqO5Oo4yx68EawsNMCikt1sXiLhOS4p0yKXKh2OaRZXGOPSgyNBxcSOxgWSSRrLwOswe0K9srD2SZ1gRW/YE5D8jrrA0TWs5uPQr0Ka6jQ0pFHeHmVPT747j29rvjv66+Nu55cC87v+C2Lfd6MTczSyUTjOJigQ6uCwxXKHjMtjucMwdLodvuxEtf+MJ41kVPidnZOQIVIuaJbInfxXZwA7QEDP07/0oULoVtdJiZa2d9QG/v50pWhT+fi2tqmyEFgQB3p2vnIs/EmfM8uOWU6SKU8mT7Ub0wERLTQJKD57PCFNVoluuCNJSk71DIz0Ni2eSV0bhOgUbYcBjDwTg63bacYDmciZIJrmaJwDZBZkPKWhr/9vvvLMPF9C4u7IxVGb2wl+V5rT5kQqO6Ba5J7NXSiyR0l+39dBeJ1KetCLI1VaEc1nrXVAVeyp8yhTB3R0ufqI/Kq0gP6UjPh9CGVisZyPpPvRTVPogoOD+QqUSDDxGE34O0zFQa8IHw2dst7fvIddIcWzXRVf0QCLjBQFAnaLp935HV+PGBxfjv73wnbrj1dkqP9of9mGm1Y3q6Eatr8nLnnLo1jq414sjq4VhdHXLlQULmuG8wEPz9Rc9/YZyx/fR4/HmP8gHN2iK79lX3Xvc1Mys/I58S3V0LNSeJUIWBfJ+78TDCsuKATnscvX6f4t3tdpvK7kT/iuevHbSCWkl7rMyBl2a46fWJvqXIN8Ec1SS0oTSS4perNI51h0xTp9CNC3cRYmVlLaZnpqVA77SdvCujozzWduYMBEwL7divuPTdJnzb0qkllfKjNWv6iQpFOrVZqPnUCVTif0o7Xaj6z+mZcqa5MBLyGXLlWZqw0QZXN4rROatQwZL6cPnERWOuzoQNLKNSZo7ZdbfHRV0BDhr5ZqxPko8l4qbArwajDmn+zHBkMIJx9TMYU8ZHkUB2zko04tPfviH+4RNX8rWMiMjzuZOfKeh0pxn9voigvIcYQCv9G99taAEMh/HoRz4q/vj33yKPWHMu6cAcjtNf8veKSuMvk4Pn3N3Pt3hgH8rsTtMr415Y/4t9Jw4gSY2G8juIaNSmUvMq++OZQvFSy1moUrd8T12VJJ90vdYEcBHNdXCUe0oEy+gWjKrVMk1egYDoKOftEb2hpTWKznSXAI0MLsUmEpVI48ro4+zl3y5NNm916HRIdePoGPL8J5RWjxguyBUhHJodafJKqkSpel46FBogEkVOhiHqfDq9DIkmc2XoN4vV97N62pUPUZMzrZWphTrrSSlQ2eGIhWk0nHovIBdgKaAdihkSYha0Pd2MmOZUMWRp5LlbLRiP3g9AgIQgZEyIRtfccnu8+a//2RJGNAs3yGxa2SSzq891bZp4s2d0sxMpIgr3hz98R7zr8j/SLL37VnpkPzGBV2B7I0bFmTjqV2m558z9tPw4mcZwJ2L2L9ykzGIZurkD/JKwm4r9RjQ7rZhqtaLZBrihYShFdntDWYCfmD8n9dYkYM5sh2iTHZ4L73K6QUS0Gg7QJ1GC9NqgvY+Ix7e8GDai1xsoA8DUoSFtziH5ckqNVNmLzscVb32XbLowOl2L1JKxhG7Lsc3PWDOObATpEYk9mf+pRimMxRpKVh5/UiQrhMWHOq1FQ/Xqc9SNUfsyZGxZDGpLkj6UzoyKWObp+ZCyZ2JtHmx24sCOPxMNypuTUlqHUCj7OzIYHNYmELIWoofqEkUJNQgz6hxdWYk3/Nl7Ys+DD7mppYMB7wuIVzKlSrPSALg73QUuPLIaqWIDH1ldicee95h462+/wemEfW+S75yHJ4qYNpEeOh1L5YjySdVyghpSWeX3YtMKWPGhplcf0kBG/X6MISxBpUzUWBNGFkYTpIuEBhGBYTz4TJpAFKCZ3D0bkcKKU6ZKmVOVpaMMTjgHyERqxHJmNKpRiUKkeoDxY8/XoyndHwxpIK1OmxkOd73Y2SeClj2ycm8+hE56rXJxDCiFd82/2z4qMpmPn/fv6dzLQ+QL4tDiRtbU7rJGKZYqj5X772QyTu0y9SrqCvkPmfqV7ywFffkoRkMyQ1MEMfSJISh7ehqONaZSM1bLgvxgaSjWkIUndE8km5K4XjJ2rTdbj7ysh5zOXX/LbfHO914RDx05pGZkNKLX78Vx8xtjqbfKQSgcuuZUKwZQDJyaik2z81ymgyjbbrViOOzHwtyGeNQjdsavvOJl8bAzTi/0ETWP7emVafJGks2c3q+yg2MK8XoK5CDmjng+4cwoVDiwlkgOlzxiiYjj4TAGvX6MelhlN2BtQvnP7E8QBWvxa0QDEYFgUOy1wMnoHus5Ak1D6qaYXiJ+oqi5WQrzRHBW2F2JHe1TGJ5qRa/ZjVGrLWkjrLPo9WgYqEfqtbR4WaazFDKtUfqPXv5uFulJKkuqbwaQRKiMaZXaQtdf1SEMw65maPtENJS2JTplC6oQE8OvdY+me+154DrCZcPTl/y6aYtOLWohq3SbGdrLLyhfCH+E94Ln18yH0iIWmqSTCPVJ8mWqsbCzjwfGqCOjIemPxme34HupnoxOKt5j/4GD8b/f/FaOw/aGPe4BmenOxPz0TDx4+CEiWcurK9Fpd6LTarMInp+Z4cFaH2jcea7b5Yq2173qF+MVL3uRpwsdF7zvnLU1Rw08SkrLKbG8pJ1VPZJdbz1h9baU+im1kI/NpiEdgu+NOthaGGSMjJEcqpfQGeb8Pnamz88VqoqbblUwgyDfEL8gaeRDiq1ew777WrqxiXYRmLFemjhgaUo6j2BXY2Sc7HNEkDYMBCleK6a63RiOhowgbRaSFd7L1RWAhImcQYBkHMN+Pxofu+zPTc/LBpK8W7mrtUOalA9jIXaWSXFOV2IExB1PfTilN7w55fUqo0z8IfNBGmctqulnBAiovKkEy9SEzNtk7J+u24ceqUq7SUyfRSQRGRgK6hHVPIRAeeYlTZRQtuoQP3pfd9IyJDGj7C7HcmksJbOsEDmwdb/6ze/E33zgQ9Hrr8aWzZtj8ciRWO/3Y8vC5ji0tBTbT90Wi4tLsbiyykZht9WK+en5GEDnF1gYxqDbLUKST33i4+N3Xv/qgvq5lcDrhm0QvbOwQtYkFXp7TIy1k8vzyiflZ2/405wkl67Fi2t1W0XvEU3ez5mCDIJ8+70+IwbnWPL2lJZCdUBdlwvlsmB1RsQRahM0fHM/G+dEPDPuZmze+PyrMhkIlAvEGLCnI44ZrgkFO2Rc8Xd8L3eLWFykpJTkYr31Hb5jeqB5gPNI5uEs6VN2HzP9KTE5UyPXCCWcOw0qvSo9BF1ElSLRZyWDM+uEPHx+R/aOAAAgAElEQVQGDajC7jtQUrmkrRvHrwJMNeSjCKLQDQIe/24qvKKA+wieL9FrJK9LEYL5sufTGUFqD4bXkpSJIu3vwwYSZbMRf/+PH4qvffu70WXRqtkDRAkceqxbO2nLQqwsr8Xew0sxMzcdS0tHow1leBblqk9gaJ1Oh5yst7z+NeRqpaGWlMG3NUvAhNkFXeofeRTqhUkthWVdXEfYMMXHmqKynWTXKoXEDDjIo+1od7CXUuTQkrahF9GHyLRmxdW3ySPnM5dnKGsnr8Lj+j8sMvLaA0rRMh0bckkT1z83mwQCYIT5HFL5GfcZ4EkXgnitpiIKVkQM0BsZik9IpMt5Dp9pLghyPfofl/6ZEiM+Y3F6SiGUsxb1g1zMyRIsRf5dhz4vsjQdzfzES5QpsowiLpqLd+JDqGoWUSVMgchrpLOvxnozBVQhXXl7kuvo1ZwKeROrDpSCpryg6yauM86fUd5Mg0qj4b0TbZ4yNSlTxKkooVK5PKcWRHgv19bX48//8v1x5327ecApVRNjzqfjAKNoRYoFjSfUbPNzsyxikapgkApSP1D64Cox9G06zXj9//dLnA1RtiltLB1+MQ+UKtXgess58V94ublNtmL/aiao4uOliiPuMXo3QM/w2eBtOZMx1aRREJzIlQKGyfNRJiKa3W2maEC4MlLxLHiitdDaXQm7ZiyzQ64T2PNCSgnD6a3HeLUX4z7u3TianU40Aef6LATSU8z04DrxvjCWZouN1/X1fnRmppl+8T0skMflq6mL9Z+X/alSTbuIaiddNauVlOr8vuJ8nMNVQdtxpzbFlalaOTSFzlJrahmZks+tirGC7+Oh5qB8XmuGdxwEeHYYGxt+1WQcRNT4Yy7I6wAC8Xp4n1TAOOZUZ21l0mHmwFVpa+SsYgwnQqamSEYkpat79x+IP/3r91OLF54OTUJ48w2zs5wU7HQ7sWnjZtYxGLGdm9tAgwBxbvnoUiyvr9NIEH2mp6eJ3Lz2lf8jfupxjymUdyaZ4J7lw3AtkGvj0qMX2kYmrXkf2bm2XI5TWhmCoNZEexKcSAfYancckRFFlMbS6ThdzQlBvS9SGQEQJVMpIf+YvLo0rJm4swdpuSg4Mp1Y3gdGV6ERvE4Mlrkxo/6VILIi6qCIpzPS7w2jN+hTbI89HfDeWs3oTncET+N7v/K2t000863misTgsifphp+Zo3kd2R7M8igpAaXoccjWmXNOW+vA55ch0aIiuUrdGREKdwY3Jwv9rJHcv7BBVKp+VVMtu/KlncPQ6flrQ4psAHKyzuroyqCVGJZepQxOjyOLXVdgRj5UC7tp4DTPWHLad9xyx93xd1d8PI4sLfGAr/XWePi77W4srS3HOWftiLm5WR1ur4bAM0CR+ODe/XFk+SiZths3zDN/xp6R5z/tKfHq/3lxWTbJq8iOftLcTXlidDEfilHBu8g5rEQj0GcoHKZa45X8JK9S078LyBDqM9FBclqH1IaplFPZXLcmfoturIinuocikhp+9zx9Jhe5dAmvB0eWJ0lcBde1+KI3aeH18Xr9PtCzIX8G0Q2RQ5kEboHqEqJn2GDcG8Tayip/xz1otpsxPTsd3bkZ8c1wRr562aWTSq2uqiM016wokhraMqTEIWqFMe9bxZ3i9ySaU5U1UuAro7Z1plW9drdZ+VBn6qfNVTmRaHlKd5kJ4ZrbQ2iQDsoylJ5jyBxdzwp5p/SCVZxXnwXXLmE7z1E4vaR/5QvLUBLxqe6YvJyQPKWJCiZT8akvfSPuu//BuObmm+OE47bE/sVDMTczw1QHHKznXPhkC/GBRIknPVQzq9GOO+7bHbfeew8/00lbtsX6YD2mmu3YMDsT7/id/2PQQjMW2mOf4hY+UhR4xnz/KCYQNSiGYJ5d3TnZETBoDMbUvZWtmPNmxgAcYn8gT93tAlgdxbAnkXBqBQMRZK0FiSSlpawL0JDlHvmmhqDyEnNEwQwGpHMkqOJ39oPsxKhG46lOWxKuD0YBZ9Ib4DOCt4ZejOVuGxHTc92YnU/umoXGKffjUsxcQURMsqcN6/PMfPHSy/zE6wSTqngmxJeaqA7LQk1q32PHm5GvoGBV8LAXVo1RvLGLpBJp0onzhcyC5R9NQTEKppnrrB+c5tT7EIxArPCryFEoGy7KfZBKhHOvwBkS319zIpVYXOkE4wy7VpMh8af0UizAfQds0H9zxWfigYMHYtOG+di3/4Cm9BqNOHh4kSonH37H73FHOlQ82jHkDnV4OHSE/+ULV8fHv/pNGsj87Gwcv2VzrK33o7fWj99/3f+KrZs3F9QtcZHq4HmvCQ4L5rTd04GHXV/tRX/NxWpzKqbnp1lbEWxATYGOsz3toDcoECz+3F9di2F/RM/c6bboqfmMcPYwUzHQDpn2dCva3Y4KaDsqIm29gVAjN2VhvCnmJmq/oHhKPU3QJ/Enw3N1hKo+q52Wz0n19YoGhVHm5IDhdbmG2xsNdDBVO8vmRKHRvvuIxhfeepkzpIrpyKPvmkRvo3/Lc0toswb/Zn8j+5JEoyiTo7yyqj/gDZJnI9eV6R2/i7lmHmCFHv10lfowTBYmjLnbCTlqgLxsakWDjZ+FL+EDzJ918VqQqKrBWX1Wjfvm3D2Mg6t3uKsEVAhMCPrK1Aow7IooMIruZEDIdbk3jD/8p/+Iw0sr8bTzHx0333FX7F88QpJfYziJE7dtict//RejD+9XNHXktYGyfOnam+JT37gmDi0v84NsnJ+NjbOzsXhkKS5+3rPiORc+UdKbngzUB06Bcc3DIBL01rgUmyheZ6bL3+FkkGIM+8NYW14jZUQ4cURndjqmQKvHgXGej74GDv+I3XKdCM6+M1vQTcjJTS1dMsCS1+YowsNI+NhbxdzkJFMBowgz3ei60NYAV87YZ49HjxP9EyBkgMJ1SizEkQ47G9eGlfmEMn0vzrgGLhXABh/NvL4vXHY5a5CkamQTzjiCxRBKDKyf1TRr5ZHJBzIGposp7Sa2/zEFiOsC4wDz605FrSxvdQl3f9NDK1qAhend3PTYBhAM1Za6lBGpMgAp7NV+EdlxMyzp/DYqOY+EuiuNLN5HX5NkhfSFwlfjRKIWmuqVpYICZ9FuTcV1P7gr3vnJz7MgP+fUk+Ome3eRgo3apdNsxuMffU78xsUviD5WyrlOU/SUE7rxtnvjA5/6fDx0dDGmp7tx3MaN0euvx1xnJjYuLMTlb/hfsd4bSsnENZDo6ylxmLMVQQNAvo2eEOdnrMBCiaX+OI4cXIxhb0B6OI2Cq+qyThBdBB4eBsnpPzwLrpZzuuQ8QWipEDpOGjrKpqOUo3W/LUlQHlShkXDeRFOTWmcnBwQoudmZUlTqKMIN8Nm5MBmNPtQSljRyQzPJVnzuVMHXfVYfzBvQPPdOaVgbZNaxjS9efrlIxT5l9Asle6q8t/xFGkrCiE4jKxjLB8dLcDwElQUW+3HWt8UhUn/OFHPj82DBciGPVw0o/9V14LoEIkgIgXpXJUJkTXNss46XVma2Uz7IV3RMcEpDkicSdFILEY5wqn9rTUAqmWi0OBudZJJGRLfTif/7kf+MOx/YS8dw+oknxE0/uifm52bi4JHFmG6245IXPDNeeNEFnsUxIGAjR0p07wP74h3v+0gcWFyMk7ZujlNPOpGF/J337YpmtOId//9vxKaF+YpLl1OEJQPI4ams86rGbnaOsYf8yOGl6K0AKlWxLlUUGIBEqUvq4SU+/FoaZKbS+aB93xQQa7l+1j8u8KpUO38wp7lMnK2BNcosxH/jjA2vEVk0DN0jyxai1uMrSIt+hlC0IxzTKHP3RthzKIdYkFz3V9CjanzpbYggbpQ4ec1aIk9IplfZ48jUiEfSqVZ6h3rpLY+m5h6Gj6AsgrkMwW+qbmggjaBgHbwwPjgm+ChaR8pyonipxqjBJInaOfUrsHKqfDi4lUI7xe70IJTOoeh3we4HV5AORx1CEr7ZKZlZ4NwiRCHGLk2PXXivwW4EG1KXve/Dcd7Os+OL3/lubNqwEPsPH4yFubno9YYxHA7iN3/5kjjvnDNLekWH6qiG5uTK+npc9tdXxF0P7OE9O+mEbTE33YnhsBeHjqzEa17x0njyeTvZEc56SrPxum/HQPJOMbJJmukQUK7e2kB9BUvKsF5BcU31dK0sQO3C6II/D3TwpWGmu2o8Vq4u0wNDrImAFaqJbrbV5csJ06RmSRP1utorU4dDaiczEVbbWPaf5VOr1DydHlNLGku1FjqjA3tfmPWxKgoFur/yJ5erB2wZfBmHTqXy91Sq0OywbaiQGfXGtVzcTwbWDaar1rEhnZA4QnJINEsmGUgdMC3rYV5LAW1J6eAa1AJzdcBmluT/Vb+4acgfxebCOkxteR8X5EqAtC4ho6Y6x3p9EurwWRyWsh5SqiZjypQtaxs9A8+i26ASUrjlnl3x6W9eF2dvPyV27TsQ9+zeG8dt3hjdbjuOLB6NlfVe/OFrfoE7QJSU+eX5UVSkTnfbcfnffyRuvvNOkvamW604/aST4+Stx8Ud9++JR591Vrzyxc827JqeF961pTtcG3dVoM/0UJFFFCCTDykZa1EDi+ypYE2YODlyep8BUzaIHMBw0PWuvLAMM0UY8ExgTRKkkHiGTSUpMbWZcl1lGo0/E2+4qLPVjmR7Ad9/8sVda2aJUOZpnMqxEerUilQjjhare07KkEeq+crIrb7+dkWQAvPTm1ZldRpEBkH7Zpfsdu/O7VVzKBRi4xSiwnRTi3M0qVfnUOkV2QDm9yuiIOowqjStiGJ0CQ9bcv96T6m6V4c7Ra8J28OAODBW9XfydtvXKaMsKu/ytPrZSkHcyVRRSxFokP5GaZgyDfduEgK3BtdnvnVdLK31Y9/hw7Ft0+b4zm0/snJHIzZtmOOuj9/55Z+LLQsLKv0MRlQRW2nav33uq/H1G74f6/1ejIb9uOBRj4iDi0uUUt04Ox2vveRnYma6W9Lkgopkns+XruDSxCtK7VbLHMoI6wicJWyRxTAUYFvMxagw1gCSIogWA4U4Y4wsoodoo1V1WnLkJw+/xhQ8YfiTwtI25MpZq0au4PW8ckf4iuSlp5NIqVPljEhFj7YgVp4TStnVRLfMJqBNfuPtlztAGm1KCJcRxR8wkbScsbUoXDUnIuURbp9F5LDcDyFS21C3OY6ZlhaAYseGXrparqMMwWvXCIgkkJyr2JL1KPEERVB9TcIKEKJLFRIpHcL4KOBGITf9uUT+Wt6Mt9aeDS3UYerGuJoaV6k06SLfjVT2C1wbZTjn4W4EMfn3/9dVsXXTfFxz+91x+vHHx533747Z7oz6ATEVx22cjV9/yfNjfrYr48hUMS8SQ1ftVnz75tvjM1ddHweOHootCxtiOJxEp9OMTRs2xOLikXjjL10c2zZv4j3h0FLN0IrWrldSCIhQOpYUrCoLkGNkhcn0tnQAXI5V26II02I+HemXES1CpzCs9R5TMfVcvNlJjW51tGkbrgGyHjFlqfRpipU7T05Jp/QjhU6TqWXNqVcZpjMeAzP+FPpcWUfq1pNZQQNRDcrTByf81bddaiaJYd4k3SnGWGekNsaaxZJvJV/HMjo41J0GCGIjSndKEUVqi5wHn4poQ7FwSqGa6ZNle9AdJqfHQyyZP+M18bOAh4EK8QZmiuu5hyYmZXxQRc7TIhXsyBqNtEpO+8NVBCOHwp8ocJDRE4xOopxSggdwiCgE4QUYVgELbMis4YmYePsq3x8tM1X+exeX4x2f+HIsrqzF7EzH5cGEjTIYDzzuI884KX71+c/grAd+TE7CsLrBAKQA9z90ON7571dS/X3HSSfEti1bSJG4fdce7k5/zUteEBc86myiNNmjquDMGrvU7OWSEieiJ9d8bGptQ8k0M3EOnW4jS5m6csGmuGgUXxsGUy4YD9Iujckqk6AKSaZixVD0WLJIJoyuDyJjpYNz76vWgatwlCqyMyFLtjCfCaI7EDcdUtziqqmsM060zUCQRhnAj9MgXONrb7u0apPWJCOz4MuDx5vqiMKUnPL/6mqqXyDNqIwe4OV3W2MKIXDPufWzZtj5h5HkplhdtHLDLMZ0M0pBJzC8vBfeP7lBspaIqZl8wFwrIYMZYX47YjDCITeVxr8neIAXRmEIQxJyJh0tPB8Y1iB3izCfk0gcizfZgbtETtdIm1YkvPbO++Pme/fG7oOLcXhtPWY6zdh3eJkeCuzdg0tH46JzHx6/+tynFNFuRZ+qbipvEo148/s/FnsPH4jZ6W6cuuX4mO5248jyEaZvF+w8J1578QtNMa8OlSJS1pJOo4+h8aQebpUqJ7u5qgOy2FVcyglOIZrON5OFY6+GIhcIGYxEwgh+tQoErdJBz/9wURBXhFTjEjkfkjEiKw4FnTyQyiZ0TqvKJdNjHVqdJUH8jhClheYC2hJJQrrUkOS9+ObbL60BglUUcVKcAbcKvb6YYjC2GqPaMhavkEbDDMV5WcbIOW3JksIWKBBtIg++1m6p20s2Kl4HhX0bFLoxf2903XTwnj5+E4WLDcsiMiVyASMZcS9BLsGqaokU1mPYl/EkjQavBSeC6JF7SarapFIwwfvAGABL0zHWohH6a+/5/PVx/pknxp9f+S1qW+HQPHzbQqyMJrHn0Fr0Bqvx4ic8Ol76U49hV5lsBR4k/57oDGHxqXjnJ78SN919T6z21+KCh++MpbX1mJ3txoZuM27fsz/+7Nd+nvvXq8Q06T6ZNpUg5s670+eacqEerQ9chceU8iFTsayVMhKlAWTUz5V9LB8RWSoGpXXOEv0yEpbRJZUTiyWk2JsOtdaUmydqTp1jj3Gl6rOWDK18zFwKWjxbgY1ZwqRmgfCq6n2ufvsfOWU1quQ4VKgkxVATZtXV62alhpGvwjAiczivVSuuolhvhcdLLbHa/ZdggZgFZjtZFLuL3SXtYcy0xzEzgw80okG1Oq5dvCaLAYVNCHtMdHORCo0aMYXFfszrlA8rFYtAI3owxMJSvC8lwNU4JYggp6E0Kwt5rFqQcLUybfVXlAboLd7+8W/GY848Ib55673x9HMfFp+47vuxaXYu1ga9GE3aMZn04pef/aS4YMfpTosUE7NpCyhbqJv++/S1P4jPXHMjSY6P3n56dFqdOGHzbFx/124Wza94+k/FRY85OwYonnP+n89IqJHAicR9LdGah8eGwRSnBJOahRg+UKap1yGiWRfF8A8KJVZ+X5YW1RZoMnPyaHDpRbCcyZrXurl8K58vRyBdfjaMq4iRDShdvgrmOjeNrLiM9qlEWbu3MjpHrvzY+ft3//QP4DOP8TzCsxN/dnpTYOUSpKoMwAqJTHWcOyss6W5rQMcPOz28H474TZXj5/llB1cxTD7Dr1NeU89GUQhomYt/6lBpqk6ERXljpHOIVLNt9GIsuV8W9E1FDx3ZkdUQUbPw4Kdv8qJMHxyDL15HbFdXimvUWM244e7d8enrbo0ztmyMg0dW49xTt8X3d90f+48sUSUR1wWG7u+94oVxypYFT3AmfScflLdF2encdM8D8Q9fuDpW15Zj68b52Dg7FzPdNpGw5bV+bN24EL/5smdFP4lLeYBzB2OCL/l8sjimf9Hu9LQNffJa0etQoXLNtJLiZY16FsNKkzbhU764vBzRXhqMRaxZ4HuHJTlKNhQjRKgf2NF3nlWWh2Z2V/KvSume38yD6OZAUlsKQps5YbYKKgeSP1WwyiPv/+3JaNiI4bDBQ8KVz6NG9K0yh/uMRh7RKKMSSJvkX10QUWi64uvlazBtALJERrA8bSUu5nBe9Ror72mDIozqrLF6ZCr81TNwHZTewAGioG/FtHyraMCKWjAUQM+JRMH759LQakVcRsZsNDpy5kNnwaoIxjOAvkW7Fe/61FVxy64HYrYLaHSKM+UbUDOsr8b09Exsmu7Eg4cX4z2vvaQYh4pEH6aad8uv7jlwNP7qc1fF/iOLsdBtcm0b0JhDS2ucgViYnY/fvvg5cfzGDbpn5bQfuzhV72FsPb2kz0upFZwBGCs0S7nK+RMBUhWdaXlGqARflO7KFhJXq7r4yhbs+OiNauhbIlT27NoGkFKjaYA+EdZFYNyqAR3171L4cNHvSKLBsLwep2b+IeMDuu7BJ944mZpBk8T5Q78R47UpMK4jYDj4+yRcH+jWcnFnbR+eYGh45imuTcseBEWJ3cdAqqIwWpVcglP1+ljzzFTGkCwh2/LBhECxyeTqWAsYxdPS58rXzVtjXSyiGDI0mWiVtjju1s+lXyu/RwWe+h+lEtXxMgycKAsToqlGPHR0Ld7+sa/E9hMW4o4HD8Rzz9sZ19+9Ow4tr8ZMuxWHV9eZS5+8eXNc+vPPo/EoJXVenn4vPT04RjGJw8vr8S9fvT5+tHtXbN92fJx98gkx0+7E4ZXV+M4d98aWhbl4wfnnxbMes8P32OBH2nhaTJJB/fq27FK6ZZC2UqiTgDxAStGqfYMp7JD3vmYAzASqZ0JmcOmvGf51156DXjSA0g6uPVHd+/zWTIWqFC9Di9HErKkK7FZLnUoUVWqdAuT5aNOxZkZHEzz0njdP2i2IAjSi1cUYI/JtcFvkXXMDLgrPqbZ62kylYFBTDY4u8pBjiQ3Pr5d2mmJCWSQiVArQbFgYg+eUGLu5ek1a7ngq+gP8opKum3f4PZt+Qpd4K41QcMtpRhR7Rb6kIqdvtqDeXCHh1ZCli148Th4ce7E0wwLn1u4e4cfxhJAuIF/c9Zt/vDeuvOH22H7C5rjt/n0eCoLET5/3ZmFuNlZWV2JhZjpO3rJFyo2OsCjWUUNoDwm0btWAA8Wj027HYBJx794HSXZsdTrRwcx6TGK914vpTjvO2HZ8PGXnw2io2HX/+LNO51gvodpaI1I5rflKvm+lPjnGqybyYw9eBUvfVB90sxqMywqVtEFWKztyL4hJjn7gmn83r8JHRMyOyu0lQuUcxkdQr5dRoCR2qRSfFBXD8An8FHEIfCSXZ6k+X/WP9Go8PqOPvJECtczt8GLDqRgPVPFnvsdvR3aEXL7ZiBGiCgzJCzaB5uEbuL+PXkMPV5FFJ1TIVe4BQT8AfQ18TzaO5ClIkRlpfQBJr2z4ySCU2GmVm3aJGAj299SXhMKIoJGL70eM6bQmhJwF92n3CNLIPtJKqDDiX7yqQFFQh0r9EzQiq+aSeh16hsPxOP75K9fGld+7g/QOjMqC5r+0uhbdWdQbGA6CcEMr1ntHeT82zGyI047bEicszEcf8jIRsbq2Gtu3boxDq9CSGseexR4NAD0gfJaV9aPRaU/ijt174pQtG+PA8iCWV5eDI6+4J6y/hqy90CPZefJJ8buveFHMdIlilC21GtqowaQ+lExyymZcHw/3vMrhc+Mh96DUo2oGKr6ci2kmFZxa9NFO0Wz/e9JgWKdmZpGYQjGWytNlj4fzG8wM/F6umSsgokoKjoF+6fSkIVDPOnS9NupMs7KRMP7wGyY48MMBGJLqGUDUmR9pFNFGAWLeDOqUKTTlJjjgyi9bnXH0VyF2FjHdwSgjoFmgTGD05n4ORByoY/giRiIh4qKkNSBUiCRFp8fZ/WbaVbbdJn1E3iNbwfmgND6rQrzp1c9aCed9Hq5BuCqOEQhr1oygkFotsJp7RRzsEKQgIQo0SPMGCs1KF2Fgk/jyTXfFDbv2xpXfv48K8xRmGAxi44ZNbDiurCyzGdhfXw7INWye3xxnnHBytFsdK6KLvoEFnoDBV3ojAgvTED2jrtZU7D+8L2Zaw7hr34GYbmEWpcWVCBgpHfT7MdvtMrKAVzSeDOORp54Ub3n582O603GBWzUM82BlL0k6wekz0+n4yCdHKgnfJUN2/yDTlkzh8oAlxy3RIUcV6Se6OedCXY3HqjhP0EiprIw7U/MCKTtVFnJVXKU+h8eWE7TzJ6Jj4FPkAtKSM9Qg/lKalzS1Mbry9ZMGEJyVqRivwiMivVLqg6IVw2+caTbSRM4TvO4YxiOJ0f5Agy5U6KAXViTBwVIY1IHSy3gQaUpok4giuYJAdBXLd8VwPBU9dMFdv7COcTnnnrhTrbxBMgQ5H9O1VT375mS+moha1e3J44HlOSJz6gDgVXIffMYxXq8f+NpgHFdef0fsObIan/reXexmd7tdbrFFPwBpE1TZJyNow2LOAZOBG1m8UwKIQMaQ6BNUFZESoS5B6sV/hfjyYBi9cT/Weut8PaRc050uRdmG0IyCWmB7mjsNoZCyZXYmFmba8bs/9ywajvy3D5rHCJKgqX+r1Sv2zIqQWb3Xv6eG8/B2VnWHMiOnv6759DrV8xE6qjd07V0g1uLVS8ZgEKh24PMIZ0ugsH+LkTkjqV1bVVskP8w8vrQgXrfRuGPGytEi+NQbJ7GutGiC37kdqRH9oRhOLTTokIK08RQ8A9D3GyFS4MPgexAd4IET1cCDR9IMjzxUAZtJUskbXRPgnZjScIpON51LJKemYqUv48OEJwp5La6h/gYjm1YyOxXL/ow9CoOTh2CUnqUAQx6ZymtmAVnN4td2cDvyyLi1pJR7RaYijqz247c//J3YdXiNhp1pimRx1G8pBSXAAjubAXV5dbjkWARRw3C0T8UDVD6jAkXgdJpcF01qPWR4OMsA4+rEEPq0rGk0xPSBVz2HHC18cnHNwHYWiML02MtGDbG4HnOiUlOmUQqS0H/eu+xDGM4t6Y5yd9zPBNLq3LA82OnVC2JklArfK2XNakhOB7zAcoVMm3VT0oXS2JlCK5S4lNHZUtCwbnQW8zYOlyT6/goFjsboo28gx1uezJdRYGtfFIfT9PBIW8Yh1fJwGQWp9Sb4wd3i69RQkv4qjcvFOaTuGs0MqZ58w65xe2w+CHwPXhKplTTT5AWBqg0gpKa6QA5Ai2xITBx7hsSvlYU9y+Da7vC6cJleQ+iJFBt1Dzhay1RMtHM1L0VDwQNMHtdybxS/++Gr4uo7d3szwFAAACAASURBVPNn+6NhtKfaTHfA6ymFJLdZNSnfA9lLQLNa8YYaSTAyzL3UCLzfinS4PhXtYhrgEaAWxPPSoqHq/KAGwlPeccKmeO8vPyM2g9vjLVnsQTCFTAYAVOjV7yKK5saoWNCZCin6kG3gLn+pM5yF5RrubDQStHHKlp5ZOyz1vJRe657z/pSmQa5Cs8iDHVyJGh5VUBGvVFd3SPdGNpQZhH+qHPbaZGMtE3FO5mjmwSknnISzR1e/bgLvz0GRtUY0hg0eRI+O685nx46U2EbEwEUf99Elu9AQB5N0HGbTRVDDAP1aNU3EkaLeHCJz140dVdUWM2M30FuIW5OY0HBwPYpkE7ARe7rmMVCv3lQMhk0TBnNU1ColXkFNFCMXUTqs8iMwOsl7Srldn4fpQT5YOxH1d9Rdx+H4+y/eEp+98Z4YjGEUzegBZZrCHm55fKREPOA1J0Po0g9aaYjnMPj+rRiOQdPB72OJtkGZvNXmUk/o98LAQHyE0HW33Y61/iDmuhikGpEiv/PErfGmF/9UzHekm5u5tw6po5UNIyO3qDMNTnQCuBCkof/UL8p0ySmXvXAxBo/HVsV0fp/qzfrP82fqTeMKRdf7+o0pVueJP23GquDiElmKUThJy9ytRCOPmLteUjRMyKeeXsrTFPgXp2382TeIGEUL9Bxz6vyYzwTECoeK/Y2ytlmpgwazjF97DTReR8xO1QL0FHpEJdJkTaPCSc1IeHA8INUcehh4fSBghIvRf2mPozk7isbMJGJOW4LIuepD/4VyI6bRS0GQJ51Dy84B3AA1gUrwrDu1icJnFOHJ8o+Vng7TQkVOdu3HjXjXF26Lz9z8AOVmMrzbYSra8KaP2PXOVEkZgDrY7Czb+5Eoyb8L4kbqhRQKQAPuKdcjjMcUtoZaB/aR8HfUORRlk/riWdu2xBt/5sKYbmNzbdV/yshgxnuZ0spuugbKdGjIeLaR6Hodyu3xk05UkKLKiVe9GIcb/KZVZ0Zw2ZtKekn2nZz+1CgmpQxiKprPI/smmc4lcnDs+crrUne+MvaCvrEOUjHE60uAQQmZ2hHjj71BX87DgDCOH8i+RnKQPBxDD+xJvxQco/elNzVFIzuavgG82daM0kcxa1fNC94x0tpNYkSenKiGiILZ3lPKB7UP3O2ZDcPobIQqOPBqXXMApoahoj7ilKJqD4jNg+UrgKHilckYhJtQVAIPp11J/SjimNJEV2rqje/BWm8Yv/OxH8Z1ux6K1cEgevDozQ6hVqxYwwrDzXPzcXhpkaFwNB5w7zj+ncbih4HUCOoj023UEkqE261m9PqjmJtGygaHI1+N790AXld/PdYgwmCjkWsQ/Akl+N9/+bPjlK0LxzTsEhlCaiWHlWmF01jDrRk5lAyXtkRVCThX1+Pzd3tjLe+XKgBTR9JZ6umrSFdiVQzP3C1CuHlucu7GRYFHRhxh6gyB6pA7Ey6RT4ZhWN6RWoe9WIONQ9+lKOd7gSsZfewNyUHjASFt3rx5QmhIuYjHmgSI0AsCYDZkDOVWlGI1EEtXlOdJLimzKOb7eK8yBKOL43osMzqlQlHrtJMjpdoD763+hNY1swA1+1ZHSKopGs5KRqihZNQrfnA8nPRqKuLy6efyTqZ+Lvbwj4mc0ZeQ39WIa+46EJd+9uZY6a3G3MyGWB+sxoaZeXrzNYykDgexeX4h7tq7J045bisXQs90Z+O+Aw/FtuO2xur6IEYxjrO2LMTCTCceOIQVCOjIr8aOEzfH8vow7j98OLrd6ZhtNWNtgPcdRLsFpGxIqBdz65xKHGFZZSeGg34cXe/HeWecEr9z8dOin8NLrhOruOAax/csD62Dm9MiR2lD/XQl6dazMFdeoAMGI6n1rYpBKKcqgGwxqqxVbFDJf6yMSyQUPZwassa+1bERqEC+SfFPdC6tXTBIflqf0UyrKlCkMmCc+Q++wee3+Ha/rPkrVVS1WWXFnBCfUizlIjWZmPyqnFT1PekN0hvjg7rRqL5I9dCEbHlzq90H+VL5kpCLRB7FZprSueIYfqIplYUmc+kajKvxYtMZfJnlftYeSjY8lToLRUPB/Lorro3dhw7HcfNzcWh1hdI0IFDCy6ytD2JudiZ27dsbmxc2xXpvNR67/Yy49f69sXnjlth/8EBsO+6kOLxyOLZu3BSnbmzEyuqIdcx9WAs9Mx9dbNMdTih3gxkLRBL4kT2HD0anPU1AAHCv6NoARbLQF9b/6899Ypz3sFPK1F8qXu470ovNEItjbZaAR+UQSt/BLpnoIRkLlWqmgo2sJP2vIN30wD+Rlrkh55NeahAHrfLs+Hp1FC29euatxxTvBRstdUUW8XkuS02UWEZ5wBU8QOOtrFOfh7JFV75ecc56Qsq73EVPd8zPKQSnGIOwPHoZXqI7fwbUyoRWhjyF6SScoQmpIaWja62Yb4+j3RwRDZORyKpVnxg6ThTEX6dN8YOq+M1LzZtT1QB6LRbFbu7h51QjOdXz1ys0x4iLm4e6n1VxiPdGQ/BTN94Xn/7e3SQoYkoQRTRqDqxxXlxbi4WZGdYOi6tLFAPAWVyYnaHHH2BOH1NrjF5o7o1jfroTy6uj6HRaMcT7odjHXpBWI46u96I71YwlvO7cXBxdW2Pqhs9wZHU5prstzonrGcmx4Jo3zrTjjS95OqknKHb3Lw3irv2rcfu+tXjsaRvicSdLE5gGUbrY1f1k/LcN8R6bUgNnmJIMSv2SWJrPLr27MogKpM0zlFHh2BRIz7yq2LMQr8PCGYn0VGrRpYY+laBYN4pEuUoRn4RzXV0dM5AGGlKsa15HRjELXQL5OnhMkdRN0gFLsTQf9OQ58Yz5lUFFSU/Lj03uhguk1SD6hfx+0o/orWhv4NJaMw6vtuNwvxmnLCBvH8WWDQNSXngNpYFToUqu9YlmCZHILqyLLl8cjcBQMbhiBQbWOLVGZg0gyNCyS64mYzbT8jZUEkQR+5f68RdX3hRLEFIAsDcYxXS3E+v99ei23MQbDePw8hEW57j7J8x1Y3p6PpbWBlJWBCjBdWtNaufCqLETZABImExYbEqC4UzH2mBI6Pip554Wuw9ImfHq2+6OLQvzTOn80Cwggc8CJE1crRedvzN+6qztjHjX71mJG/YsUh1l20I3nvfwjUJtXFP9P6be/FmS9LoOO1mVlZVZ+/b23rune4AZADODjYBIA6K4yqYpBWkrTClMhWxaDoap8J/gn/xXOBzhXxzhoGRaEbJoLbRMAhAJEoMZzILZenp/S733aq/KrZZ0nHOzXs8gBjPT3a8ql++7373nnnOuvXsLN9sClv++df809PFl512lyFXOnne8t6fyFyNy3qzdbqSrZCun5dtJ/vLs1jfktCUDSrcQim3G7W9ftQC2jN8vfMo2jdNbzkc7aE3l1kJWG7/MDa7AGQAXsxjDRQIn+6s/Utfvyskk3yAWknMI1+bqvsT68oxTh+nLlaTNYAtaCqPt4aGNEC2KSGJOiOWiACoBeylW2/zVsxriFdMDB/PUwetHEa4fJKBUW1+RN9tYZNO/9uoI1R3lViT5g/6ChsceIhuMOSqnzZAX2UawtFOBv7addW7ggNUmW1jSIqwhMFsron/x7jH++J3HmIeRFnGl7GtzWO2U4bC3g3iZ4oOnn6HbaOHezi6idQFVN8OAnrgbIlP2uTFJZxx6qRklVmdx6AtTrS0dZZ6k6rKXvSpeOWjhqNPEdx/cwP/0x/8edT/A4+PnmkxVKhXhlQLMooUeXq3s42u3b+Gf/PK3EPg+3j0J8fbziSDivaqHX3mlYWhafo+G5OS9iSvkZwuabHOkfJF+ERLdut3n3fSXEXxLNf9C6qXNsqW3vxRK5ZjUy/NmG5y3O/CLiXqOPlkm9PLE/0IWZg83T9VsY3wh9/vCcbHdIlaHFlS//fCzU8SrNZz1//nfm/fyFqi+2pL51WwHhnwRysgv3Db8VtCyzWOvkjBruonkmB+KW92ISGy5XW4GTEMXDycBPpmWVXxHKwf3mgm+/2CKsvW5XgqUtk9A1/Py5NC1bP/Ob0eJ1XZlW6fLELptekb0jAU/FYVsPmqD56mgwpYNFDIkbPtdDi5mKf7Hf/4+Pjq71LSjZL1G1XPhlwoYhNafuLV7gNPLPgK/gqrvY5dz+gCMwhCDeYR5HCKMI2nLKaI67DTx1o1d1DRgEprxNwljXM4WemFhvMI85kSqIkokRaKIV28e4i8+/BC9RhsXkxHm8cLmXNB13fW0QWsB+V0F/N4v/SLu3byGh5cxHl7MtfmCUhHX6kW0AxcxvYE57IebNe+EW9efn2UeW2Q3cNHc7VbQreYcry/2Fr7wbrapUZ68bNeqUtvLWaSuPxvPTCE7VR9hnOodE4gweUGemunzt6dL/s/8H1s/ZLvO3N8rR8dsL+T+W1dsYxu1xnul9IDfbSelrUdeW0JX+/UGbz87R8SUdf2//oGGSukDFTKtB2H9DmPC8sJXy21xbpCsIrCNk7OJDV/UR3xxcEnemd4+dEZzEiLPYxft8hLlAhBvCvi3/TpCImYsNHNA+qudFN/qzreH0TbbMzxJhdz22LXIYJ3Zl3mppVFWvJs5mj2MLYw4SzL8tL/G3aaDw7oNj/l8bL2KpuegUeZ9FvBilglZ4mgCjmH+33/8Gf7v9x5jGi/RrgSYpylutWqqO54MRri5z6KYxbaDRcRJtg3MwxmafhHzZIkXkyn2d6+j29qDX+T8vgpeO6zj771xkOtjXrp6LDcbfcY0jvHkfIg/e+8jfHp2icPOjhAsngp0hufG+uDxQ51kbBSKVewUlZbVa234BQe3772OjSgQRuXZ0lwIL3PjWb/KRj0z5WPqt0wT1AIP1bKrNXExW+A7t3bwtaN2bt9p9HU5TuY0oCuYdutllnPeeUKGyw3+9MPHVz7CGgi62aA/mmjDfv/BDey3G0Iht6ktT9iSxmrbQuUCpw5mEkWqEx4cdjGYJ9qEVa+UJzVEOB0MFonqvG7dx3C+xPl0gVFiY7u7ARuxdDBh+uvjxWCKUbRGreKJsMp5Lk7/f/7DjH9IfUIdAlvAzhY/m3RcVVcO9Hmxav6zlpoog8nVY2aok+eSVxuf/rX25/jFvHD+k4q+NHOw2BTw2czFjGxhdgRJdKTHUrbGr+6EOZ0gNxa+ws8tFbmqE7Z5sm5iS2neUkxycM8pyCT60Xgpc+UJN8jFGl9uFfBrt0qy+PnfPoq0gbOCi793x8WzxQafjDMcBkXEKOL5aI4Pfv5TTMKZFiCNEviZzVIRF/MpXM9HrVpHmCRYLpcouC5GkwnuH/bw6ckpfvkrX8LKv4YJBfAMLoxSBQfdWoCvXO/iO9cCUeCN2uNoMRipcStNLuK9Zyf4X/7Nn5Epp647n3ZQKolBfDq6UL5NMiMp9uy0E1ZmtO62d9Dbu/WyIZb3W1LRYrihtoiUNS/5fDkWrlQEunXOQ7QN0qkGeHO/iWsdnooZonSNk+kC57MIozCV9oWnFilAHD/3xu0D3O3Vjdq/cfDvP3yq97ulqEQcBZ3nrst1ils7Pdzt9dAskSVgjWNudG6Uiufhs9MhjqcLTMNIiN6d3SZORhEWyQq3ezUUSyUMpxyGukLRLes0rvtFkUbT1dp8AVBQvVchuJE5aAee1v8iZf23wYuLU5SyJZx/8d/9lxltafiHSbGmcVqvVsflIkKv0UK97CsaEUblDfH3/SLtQgtKE0h7WCTRFY2CzbKgVEY9qFhqlAGnixWSlYPZcoPPpxl+/aaHZJ0pz+Ymoy5Dhm0ZMFoXpAnnWz8bzfH9G74+gy9vlq71M9RIcFFMkrVcPRghdDymG6RZhsWaJ59jNAuHi6eIh6NE90DKxycjwqUpgrIvGshh1cV3jio4na/w9llshbtTwC9dr+Bng7UidMMrIM6K+NnPf4anpy+0aOjjToatXyggDhmZ5jjaOxKyRsO3yWyq62GEbLfa+Kff/45qkz955zmGUaqTTfMHOWzSK6Jbr6IXmDFz3SvgGzd7eNgfmz6/aMYSoq8UXZ1Q//Jv3sZZ/xheHv0J+X5++kwUd98LjC6jQUElvHr3NZwcP8aNm6/ALQUyfWAqyFqIAAMH4fCPTyPevw3dsX4sLZp4mnJ+SAGTaJFDyg7u9ppolEs4G4cYRakYzO1aRX9+FjKFTFEJyihx2lOxhEkY6juJ2JVJm8lPKoZajrem6zxHIjgooezV0CjF6NYrGMxj2bSyKUoNf7oCaPooqs1qiScvHptjPdfTeoVKUMFkEaJUKNjsxzVHJKRiTYfhQO6UtWoHHpnPnR1iktAkXRQkTOPp4qwW8Dg++ruvv5LxJXku5bIbWfkftBs4GUfC9L9ycIDf+eZ38d75AoNojXqljAM/wjuff4x3n71A4AcqVOWqJ/ODTJ3fr1y7joNmEzvNLs5iV5ujwkWTAt/c8/Hj45H0DtRBvLZbwWQNLQZqt7NiEbM4xiJaYrdqjZR2pYz+YoVqEdhvVnAyGuFkusa9XqDj/3iyxPmQC3KDkufr4XHCaaNSQqNUwufjSDfPF04R0WweolJngcqhNWvUXRfDeKUFTbg0ns/RqXN6EjeG1SCb9RIff/4JQqINADyOUJuPUdMpuEJWola8Abfg4vnFKZI1WU0F3Dy6g9fuvoYaC6osw3iRqFvO9IkLkQGIMKyveRxmel2vVrQJHp329Vx3u000K4FOrEWYIEx5MngYTIb463d/hMNuT6kTO/STxUyDKdlMXK8ShFGMVqMJ3/Ox2+5hb/caLmdztOsNnU48pbjd6xUfi0VogYMBaL7Im7FFGWbTpI76mm1iy8lOaZxiyXqC2Q9nkJc8JFFoC9Ll/TLwrTXFt385QsWv6B0wyLUbFZyOh6jXd2WwxxSWJwI3L9G5JSHyYR+L+TzfzBl8r4g4inVSV+stpZTcIDFH021W6DQqV9oRv9LCernEcHSmacJRONb4O8OWjGHuuWXcvHZbJ9R0mig4MHhqAi69eb/+2v2ME4sYpeW+7jrKyYpZAWFKt0NaZHZQcHoyUl4lFwiTOcZxhFRpgjVCvKKDql/GeEHNdQEeXekKDva69/RSGGHrtRrOB2Os1wkWSYr7ex08OutreGStUpPzXLJaIyRiQ4npKhVqwy3ChcBiiZGC3WmmFA5omryUa3qhwGmrRsyjazpHf9WqLRmr7e/uYMV53cUCxtMh1uslyh7TsyL8ckWFLG9CjuZqxqwNFMi5UBxEz+h5dvIULy7PVPxSFcg/MKcYisNAC0Xs9/iiZ3h+eaLUgo/mK/dexVcffAVhHNvYtYIr9SCjGnsnSWq6GdYAGiizyaTt4OYaLuYCARZJokZjr9HAahmjWU4wXwbYrbm40x3io9M1/vg/vI2j3o6eRX8yxCKK5WhIz14uyCRJEPhVtCtVvHLny4r4rFGZIm81OGVOisp9dZl28XqSVYp5PMP13QMslxvJp/0y10gBYZii7pcw5/AdonIUiq2BZqUsReV4xvcc4dZBFxyxMEtSFBwX1RLw4vwphrNzZQa7nV3MFwtUgxYCv42sQP6YGRGWsUaa8hqWSgPnaaxUo9FsKYAz6MyjBcIoQbJcoRkQ+TPWBDdrOB9hOrlAobBCqbhBSnOSrKgApQZrBvWdePIU3aayjKOdI1AyO5pO4Lxx/3YWpSxgrWBgCaC5CHT9KBYQJRtUgypqwQ5G00tskOiIpBadp4Xiu4ypjQfEKM3cz+CrDfY61xGtiigXPG0+ztdjejQL54iTSIMsOSuw3WoijWOs1zE2zgaBV4Ffbmr+3WwRKjqwk0yshQvKjldrpPEayJotlaw4Jba7nboUxgl838Ns2sdySQcQzrKz+oCDMXutHo4ObuZdaEOweIoyV+VMbdY4YbJGrezgyYtHatSxd7HT6mG6mCkijudTQa1s4B0PL7GIQm3ie0c38Ob911TMMqUslaviV0nzwTHEyxRPz/nyzMVdKBt1M5TYJgtUSoag8d5Y3LPAVkpGJeKa3RI6R9qkJt9z8Pjpx9hptJQ2nQ4u9IxctwA377DXKg3sd/YQJzHanR1UKz6icKKCOYoiSUGLbqAgczY4xSScIE1jPWe+16LjquO/2+0iSua4GJyhUqogXabodjrq7LP+CTzPNCfrjYb7VHwO3iE4w5rWhVMq4kX/CQaTCy1MvmNulGa1gaJbgVfuwuPiL1mQvbw8Q6Hkoew14BRoXWrex0zNeLIV2aDdbHA6CVF2zfCbtfN09gKbVQRXgMRaUgSmtaxpVpxyS/Io7Z90cjkoeQECL8BBu4fLWQKfqeurd25kfJBpanPcuEAYEflgDRmioW8JfqmG4Yz5sBl7bdm6pRIHtReliONLV3FNa3xCn2UfB51D3TQ/kxfI3LRaZid4jCQd69TR563590YO5jqCi0Xc3D+AU+5iuaTVfojJfIRqpYZmtaWijgs94IZzNrrZNaPeeiHNupzItRULikDnwwFmcWhU7xyeJoJCOHSntYfrB7cw4ukH9mrMzXAWs1exQT3w8OL82AwUCBMmIcolH+VygMlsgkW8wINrN9AfDTW24HI8UJ3w1oMvo1oO0Gu1Ea8yTGJG37Kg3zRNMB4z0i8MYeM2z4tkbiiiSBV21MWyZA1SVAS3oZZsKFqddjVrj/j9pI8X/RPcPryBz54/UVHLHJwLhpGfyNW9m/dwftlHLSB1PoLDQpTaewY7pyh6C98BfbsYXpnuEQhg4StjPDKsBfuulXKtVkxtaKFEZoCrBibfqTIRRmyyrDMHIeuT+i6Kbh31WgWPnn+MRTy3dSO00cRe7Ckd7d5WMd6sBjg/7wsQYR24095TSliv1qV85aKnKXq7XkGcrvF8tDANfzrFPJ1hvYxRlnEe3xkpOCLRCVThxmPQYrZDPQ6bziSR1vwqdho9Yz4Qcf7u6/cyapw5v5F9gItZIhIcd6bGcHEYo+uj4ARKH5g3cKELnpMCjqATdzNTFA67N0o2o05QovSzjsBvKGXhCeAThiyVMY0GOBuf52YD+RwLdo7lFs6H5SDwPXgqDuuYLyLh0Cyg6AHFBbjt3xQ9XxEuXS2QpCO9NGsAbrBZpRp6GaZrsYK5wLeqPVNkWHPzcHcPvfoOwqWDVsNTUb5MJpiEiZxWTqaxEKdktZQ/LhEjph90OtzrdHS/Z8NL1Q3Mv/cP9lGrVPUzrUoXaxQxj0eosvis1rCMpii7HILpmxZGRz0BiQxRkmA0iUDVIevCbdChicMhjebYJ1mlWsCs4xi10zjC6eQcnz57jm6jg3qtjuOLC30e0Rumd6wveILRKIPXMI+mSjdFduG7c/n++NzWuJyy0Wgb0WOuzvfNIpjTnNTH4hi2tXoGpNvzWbOOJc2G0ZhbnroYLkoNpuFmdsuoBF3x54bTMxXNytCJxBEMYHDV5zB95ntu6KRP0kQpqQJCoYBKEKBWbSqIsgfSqtVUi/AEoHHFycUJnp69EEpa84zlQKTWLGYtUAj4cUs61TTSjyx2Nmo3NPgo6d3VqjU4X33lptJt7n7eKP9iTspjnQ0wHklEJdYbF9PQIqjisoSD1lmV4S9THxWaTFD4kinw8eTd1Gn2cHp+rs9uNzksZoUoDbXReNIQiVDhx2OuYHAlTzO+TKIf3dYBr4LlMtbrSEe6nEJ4HJOmQWf4UoAlp8NuEsyjuY5fV+O/+BKBaMXfeznymfnqlovF+6WBA6fQtgVncg1t1N/wiwFm4QYRrzU1Ir6Jn4B5FKpuO9rdxfHluaJSFEd6cQ/u3BbUO1us0PBdbbRFspSJ9W7Ng8/FxHR05SCk0XOWodfooFpmBF8qOgeBrzycBEUuEIYkjn/ebJYYzgbi7xOJYc04nIU4nyUoYYPhaITbB6Sk9CW4ajfqWmiM5KylaCrOOR4MZvbsuYhdFEq+9UjWS6VhzNGVEspozxYn/8f6YJEyCFkjlQuOwZkb5Gq+CN9y7vJIhjF/j2nyQXcXk/kMc6Wq5N+ZApVBldJq/vyKUm0GDG4UBeR8JrtUlUTViqj5Lmp+WYBCUK6h4NKPlutzjSia4WI8gLNhWCIKyeCYk2uN739lF8t0S7pRa+6rHSH3/5zF4Ny/fSNLUjsRpF4T153Nk6IGPqoA1VhgsklLCBOTkhrDhFBgbvgl90WzymGXkkc62YdEalh3cBgLf6npV1AosfvMPJ8R2IwNpMvmS8qn/zBdItGP7imHnY5efLxcaLHEaWb8JykaTYMtodDVAJwMqzRBUSIleziEkXliEBIVaSCjn5SNMjaZKq8jw839jswSGCy4wEnbIJs2zQoYjsbo1BuYROxEu/BdTzAmdx472RSFpUmCawd0X/cw51izzRqNoCzajEZqbDIErmlSJvFSJyuvnUvsqHcD+we3sFgsMBido1Wr6rSlA/h4ONXJGJRdFNZrDGZ9bNbRlfKRwUmbflPA0/Mh6n4dtaCuOoIRmDJfbshECNySk3CUgvLZ69np2fhwCqwhbVYh0zvNfcn9bG3tMGBmGi2h2etbthEbbtssMU9tt/0w0mdMc7/WGuGGVkqdSxtIUTIhmDVXhTJlmRSVNCOMFahtaBIDEj+Dm5tZDn+OhTqb16w3Y9KG1mskCXU3DLjGgDY6kQnT7HvprcwLZiZi9Tc3P8EEXgMzFB4Szs2jQw3xZDrFtIQXT2oBGds8PtVZpc7ALSAIStDJm+9GnghycidJkReQi5l8lxRtG44ozYYQqQ0qxQL2ah7C1RLni7UYrVLn5cQ8XWQ+bJ4XF7jcUGz/c56fEf74MqPct0vKQ50kNidQtYWaBvz+VFNPuem5QTVGTMm8zafQtOPcoV1UBQINTgG7raqK/DhORVxlikPwm2Z6bsGTrQ6N2vg9+92eiISfHT8VvMqCk4uh22oqLWFw4GlT9szlUS3UFXRiUNfBnN8QMFfw8O39I1wuFmL/NqoBNkTj2PPQg2bRuxL0/WD/YPtcBgAAIABJREFUGp6ePUcYjpGsKbzi+l4rZx5HNJojGTTBrcMb6tOMF1NtXkZwLvZsleg0Z2gharjtgHOxl3SK8N1TpZIrnnMhj20Gq5c0PFPG30ZR4Xvkd3BRM/Xazkzk/W8RQqlKcyaDNHs5TVjP/6WLk+pfbiBlMhSXETBZ2+AlzZgp0MjcBbXiTIvY7yLSVxbRs4CYtZrkzox79rO8agsE1kPj+yc4lWpjm2TO1N0WMAnVa5Lvwf5hZu4YtvP4QhhNLU83TyZevdIdl0o4m1Vt7EiePECjWtKDX8SMKxl8OW/YA6CPLNMX+kcxyvFZs6G35oDKhAtldeXuQXiON8wL5G10ayXM40QLk9GFf7PgZLbAG7TcnEexIW56EDkbNVkuxbFiscUTkvY4kr/mToZs5LGgZE+BvRh+b9krouqpZLOXcrUAuABJFKTMdSV4kQvgoLsjnP354NQMFTgTpVxEr1nXyAaj7ue6OXbFObpMVJt8OmvBRafaxE69qcKVGpBNYYVGlWZvXCCWruqepLYsoD8M8drBDczCBV5cHmMwm6lTXAlKqJSoWDQF5mQ6lw+wcnd+ik7ptTa4GKxKmawuNHUjMwC+K4O6ubmtXsvHBuSEQdtMObUnVzIaPWlrHfpyvLcxd3Nk0CWMbUHKUvKc82YcJJ3avEfqTswQY62TtuKVtJbYrTdtkKX3PN1Y0POT+M74eQIRCkVlOaqrWKPxmeQnELMHpk8MfDEZ5Rz0Q6WmYm9BjUHeHAOl7d0Mzm5vL2M0sFaYNWq2Rxx3HReroE+zS9cRzAYR6Rxlt4AOL66w1iZhNOEJHvHBAmrjc++y1jDaCvV0OaIAel5liERkzR8cCzx1fmnRWbSGHT1Itb/NPIKb1GxUeHzyRLEXw4egppsM7Zhb85vYqeaYMOb4pl4gl0p5L/ll+YBKppKqvdh55YYWqmPcLZ00gvOI1vmikE/jEIHno1VrYh7NMA15rNJeNEKbm8MtYDpfaDOyiOfdsXilnNZWawFBraaFfNTuqqHan02xLi5NACbhmUVogxK3av4izkYT3OjQsrSI5/1jROlcfR/fb2EwGUi2y1XE2o0/x1PH6kZ7TtsAwVyfJ5d4dVpA+UKWQUKu0WZtkQcULlgNyLQbMEpQvimuPHe3hNYvnAbcbHFKQME4cDp5cltagUp6urZebLa7I6YQ3SW7FWYLuRnehp/DE4hBzlFDlwibvTegxtkoOSs5ZAqe93fqPlMrKyE4Y4YgC3+PfTbWb2G8QRgZCbPhl7Fb9bBYrhEl7Ek5cI72DtVJ1+ZgsyonqZlnrrkK6mQhFMyRWkSC2HF3HAQeKQ9LlEsFNOlkXsiQJBvl5rwBmzO4UTQyixaKhtixZzRntGDjh6gVo4FNqxIaUmSTr6QFT/gxJdOUKj4hasZLYr3C5iQh3TBaqrnE/CV/tVdzPzS7MF/lfEise/izRGysJ2GRXYMp2aQru1eGbsxjeZLwwXNjuEVPEZnRZbfV08+fDS4Rr/L54psN6rVAvz4PFzkpkmY+xojliUAUr+LXsNvdEeb+YniBwWyAZtOQGAtIViPxGVtWQPGUQhpO+5e4fXiEdtDAdDHHZ88/Uc/l5sEtPD5+pgYjTwKuOPWCtMGYnlkqZc4qdgQoGpulhI2PY2Bj3p37K6uUJdzJ3gxrzXyIJ6+PgYZ/6V3mbgqWbJjSw/J4szni+5PvOFtU2qx8j1uxmIMC/byY2pfZ/ecpSLTSNiPTMgayVWobdFs/pEqdzERcwJzSMUPYEtYcMj/M0KlZess6midLzDnveqRM/Y2PRcfQJAV26gGCAsELUpdIhynCOdzbzxhlt+IkPSA9kPwo4cWK60Pui6eFLKeNDSkRllLVyqROG/I1joxewV0tY2bl+fSCYvpUFCtTD6lAIt5KdY96GIThYPY4/O+gXAbTJDbCxLjk0SZki1GYNGlHBDRCeey82/AaR+zgoMSaxBSLnP0xTxghDFzgwuFcDUZJGiKY9sbGIPPzPa+kk4t/id7NBp1M7IgWeTbmTMN8PFQ86sJjRMtYcPZgQu24Z0Q9+mMVi+g0Gnh23tfL69ZbEjdRH8JR0M9HFxgsxmjWAzXTTLVpo4wZ4RQKuIFXrMEMoTk9m+L6Xg97lZ4gyY+Pn6jG+PKNu7iYTnA+GQkCNmZzhlUeZQ1UMbRJU2tzc2ydNBmLe9ZlpIGzqVdAIuRoAz9gg5cLz+x3eB18t6T3c90QiCDYYS0G8xqosmgWeGKbS7wurh+PJ3uGwSTSJuLnEoWkSR5PXdUe+h5LQQ10ealV0npi/yKy2pLFNT+DS4PPhjUz77NUNnq++lnOEmFCpI4bkhmF3Yfky0S5HHolBzrdAyFqdi9aj/z3nd5uti1eLNoYrZe/KXQhzxkF4foc8UX+CkOBo9SCRSohS7p1cJPZlCYHq2SpzWE5b05j8Tjb1VKel9oDLl7zhNExKIoKX2JRzUudYoSA8klQXKyaEstGFMmVonq7oqfvVig7NWaozNFy42RSSi6TNcKt5y4pHRIBmFLNUkije/B0VHp1JdJxkBC5I3PXr4rLw5potSFDNNBGH86meOvuK3jU70urMZ7PkKwTHDTb4kidjYd6VuxiN/gzyzVOojFm0RyddlVTbgslNgKXKhI5CZd/kyK/ylj4M50paObfk+MLHO224SwD1EoeBvMhFnGIVw45qcrByaAvCDVasvdD4qEZL1kxbZuPi9YrB/iFr3xdjow/+eCvrZMuEMRqR/LbbNSjmU8b29sctiqe9Su4iJidblMdg+pNSszTkJ9Tk7fXGoFNdVWfjaxbPmd+Wo00DzU8WdeRImSb1/x4iVQyQBs5U6eTggjX10YBmoGU11IqU+5sAdanVVRuPkjSIuF1Bm8hZQRdcjnFNqgSVOrlJEsz/2BQ5udv4PQ6u+qDGMxqx6sabLnIe6sD4+aqVn1FAC5YFkAyNGOqxM3EeiVfyIzEvCBGJcv9zY7fBCqmlmLHmZtQZstrYB4yKmQqNkkJMtiVi5XevxZFiGbxQdWqbFzaNfP7SWDc8wkEE+vf0vPZjbZ8lWnhRWQTaLcMAMsyCkKrdNTyOFUKkqNcXxxtrNOGDUJfKehue1eNs9E8Qrvm4FF/rLSl02jLh2qeREiSFHutLiIyAzhYx/dQkaFDCdM0UtTnaRUErugTW0koUZu9+iEKmwLm6RDTdCKuGtcHofPRZI5GrYbipoT+8FL0FnLJeOIQSB1Px+JwGQrFpiU9ga0YZ2p51Othr7uP29duI1lbj4Mo29nZMwwnQzzsP5PdbNMv6PvOp7ZBDU6351Og0yAjuIREXLSWdZAPpfENRJkkBwWqSqWouOT4hjXma2ARMvOwDU90lGuJpxeDENG/Wx02P4GzxRLjKINXobcxv0/W/8ZbW0J9KdV3DLwFrqEEzUoRnkP2+EbiL9bLhpZZYBBYwX6H6ldXEDjXZbsaoMzNnNNReDpyAzr7vX2du1yMfk5sY0Qw76gtLGfpEpEf20gWwRWNtotqi6dzQeZFNzcFi2U7fo0tLHybEJ02h120Hf1WoFV9a1gyveKvckOy9mGqpetSz8PyW6V+joO272DHt6OaNU284glikKBeE3UMCxl76uhmZ1XHuApIpnFmlKBGWG5ZtJ2MpCCqI9nqLj7qW/uHqJSreHY+xN094N3HI+XZe91dsW3nZMo2u3l3f2mFPjluqkV8zeMWB00QMGUGBoUSESPnyMK1YUDbhTleLPQS2f+ZzuZG0ItjUUMaQUUbcTC9xDzhr3N0Qln1FBuOROv6gwvstNoSc4UxO+rUehgsS3Yyr4f1y4vxmWgj3aaLcLHGIiFqZM/sJbpPMZXh6kSE+Pl8hynZ0HlzkFQRIWLUqhQJ2FDWsMHlIhXSxPRLJ0/egeeznUUpbrbLOGgauHIeZhiluQQ6N0HnPdEwwyxhecKwS26nPr+r6uWcqww6qbiGGbi5vonQMuU0BoghpWpSUlDFUzxvjnOT8/3z5HOuHVzP5DbCoyvfYfxhRsztXAcuEh5zjEAUw2iD5PagQhG0EcwaU/MghIisFEVUcCracLSb7WQ2u1S6XumSc4jxyqrEECt+lmkGNlgmBusZ/cWgRiEyToZXOlWL/NlKfzZcMv80Lg3/PGW8Z5M8Vck3iRWkBTUwhbAVObaATSMLALxPnoxWT2zguDkpUjj/RozP+mKGa7faeHhuaB8ZxErrVpk4Y8PFVBvQr7h49Y0m+p9nKG1cbYrttfNE5UlLCU/4xpdR+uG7qGiuyNavyzbocDxTY4yjFdjltq64KQZ5PXwfz8/7iNZLNdMKtCiljqPVVSCbzmei9y8WE3l2cbZIzWcTlJsgUq3BxaZhpVmKXt0FnetR4OIyeHUerrCgkQEbcEUDW2zkhKXVAltkxWQkQzVA8znprSrrqgLCjS8GdNkvqx5gisyAWvEqWFPeS3FWhfSVFUYxG7xW/zBgcGNUvTICj7QiC5aMJQwC3HTVMvufFLxZYb8FO7h29d/q+G9rM8t6OHiI9KVauZzD+ywBuIm4dwpwup39jHDX1laFL0Ntf4eRjcUsv8z6BCxI+RAsJ+TRZemT5oQU7TOIHHilAoIStRhEiizr4SmwXPuYhexuk0lr3XppSBiddPG5ZU2Ob4rWkbN2uat1guTQItMMFa6rBN1qWbkladQkoI3jJVoVT4t6vSRrdoWpnOtzPoFTQL1SVy11//arKBY9dZp5TvN+1DlORgjcc1D9fT5eYxCu0J8zXcqk1djrXMNoeKl0gy/kvltA6/7X1KBMshSPnzwm5CBWsMaLSP66NLiXQ2142s1nqFZrUvyxXkiCAqL+UEUnC3wK0g529hUozi+H6HbaWjhMLd588GWbGzK8wPuPPsbrd15BNJ/jcjHFfrODDvq41aKuwZVS8ucDF5+OCPxHQo24QPm0KVRSYHQSmWgQ5uYJTmRnFnEib47iEV2DB9driXC6BRNiEkA3dHfMXS2uTBKMU8cTUG9VsokdBZ4omqDul60p7ZWxWGbqQTCr4Joi2GBLwCZtCeF3rN9Bej1BsUW6FsxPPVKpGGC0mKDgxHCyVDWHbVxTxyZRqnRWCKRQ6nw+SD7yW9ZKJRdefq3EaOREw9VwtHs9E5EwzylT8mA0Ns2KGnYsaxU/j6oU30SKIDz+qdVYLZl+MXKSjx/joNvFejVQLsejnp9N4RJRKKrI1IRau2rSDOahnAa50MtuIFt/FWMiyRXRbHQ0DzxJ+EJsI/JU2m134PmUUqZyHCxm/MwMbtlXbRCmiTDu/uhcN50uI1T8BtKEijYSMz0c3XwVpy/el5thGBGZqeqzhLaRv7O4RKtEMt8aw6iEJAtQCnro1drYCy7hVA5wPGMUnYvH4gdlHHZ3dU18oZ89e6rNzVqMG4/3rpOU+TkSJo9YuR10uvuia3NrzudTTMYXZFfY+J9cblNwNrgYDVVDNeoNTdLdabb0jChWmi0WmEQp6uUSLidDo4wsnqBajoUaLuIUjcZ19BcZBsO+TpRSEBh7ehWjVQ+w3lDavES9Qu8tQrOQ6yM7zduilmTKst/APDVhNtdHveQiXcbo+WwFlDCOHQQutecEMWjrxJ8nydGgfrM63eB2tY7LdKJn4xYCSYSjeIZwGSFMDfE093vzP2BGR/Gck62QbnzMkiUqJU45Zj/MZqrwf1OmnswK2BMrERIim5vDiaxPp4yHtbPY52Q6MNWympnppkoGZjvkb/F9vfH6L2bZ0vJXRmj1HGyKgnYxO9ckIIomkLMUrx/eV2eZPQX+3nwWY6/ro7jp68h+fH6K6YJUDSsOGUEp/OfiJc26Wqriy/d2MI9WePtZFW6pi2X0Al5pg2bjOlzEuBxf4t7Nm9ivp3jnZ89wzsJ3mchzig+DiIceolu2hpVmYpiNClMIfme7VpXtTRxTJsrRBJamea6PZmsPZ/1H1usVOkJ6gakiCQcynbQZH+wqLxHITrSAasnFQXWBSqWNpLiXj//NcDke4vj8RD2ga/tHhghtpaaLuVIjFkE8HRo+HUcyvPfRT+FWajg8uocwWsAtbBAkI1zf2cMMAcZxqPSKlHpyhI729jHLCojZwBydWS1RcHD94Boen57ilWs38fjkBOPpSKgR0S3eOK+DBSm1MGIqlIqYUqVXJGuWPQ0W8olOQ2YAs5geXFajsN8g5nQuKOs1d7HJSlI/UmoceKzNUom4mO7yNEg3ZUwTBsxEyJ8twQDpqohkmWE46eOGV0Y/nWGjdK0Ch7KFdYgk5T1TQx+otmEaxBPTLbKwD5V9sH5hP4wboUIzjSJ7WSvVZ9FyqdYBuXLGrLYmadlzrenMWoVdfRt3ptSULQGuD1JVNDIvM/6WSJi/8Uv/INskESbRGV4MSBW3OXeMo8zbxB5lc62Q4XuvfRefPHmEx6N+Dv8xqido10toVbnTl7icxggJweUUaK5U7mZ1LtmD8F1U3SL2OjXpBp6Pq0Ia0nQBt7SGX+1is7Q8n8V8kljDjVWuRFNqdHHDrlH2fSQL08PzpOJ3mKOGaUMoM+VCIPuXhVqlWcKEmoGir/vkBuev15seVpFFKoMOAz3UBVOJnLlcDgIR4Bgtt55OtaAqOatgWCcTRZp6fPZqKkFVi5HAB9E30jlKjocaDQEmYziuzUvn30y5IqrtLBdTb6fIZ14OJJ3tX5xgt9VGt9XVvVCrQenYw2fPlMIy/aRYjMFtubIgwkjMyCoRGUVMlA04fKaetOMUrFEyzJgXlEnMHJkmwwUmixTMJNhw4++rpqFEtkbB1TWsUtpXpNhvUDVpQI5bWOvUuAy5ACsYTUNlBI1qWV1xqUyLdaw3NXx+cowHByUsnQ0mUjEwe8iwTBYollYIvAZOLkMpKEfhQtdVo2lGPBUb2mBrtgcyBJ5lKKIcBTaXZUZkgYIo9tA4RZgNRsGADg4bXUHH56OBJB6sl7jZCfiIZCQTdp6GBRRYd967+eWMIvZbhw3E0QxnIwpguLusqVL1rTNKhgcKAVhpDKa8K2C/TeE/2Y9WR5BWPEuIKpCDTy5U7tCXe2AZ1EttgckyaVTAX+uPlphE9nJqtRLWyxom0yke3LqJRqVpMlTfz+W9RgAsFDco11jcFDGf28AeRpw0oRmCIV5e2cVovpB5AoEBQqrLlM3AOqIowSKeocJxZY2KpvvSGICLj3QNppU0CeCpQkSNRTcNqlljUNutWR1LYyNzFEE18OF7VZT9QI1AFo7Me3m8M1hw8x1WPTy8GBIRsEasY/2CSRwJmdM4FDqzu4SQeW01IWHHZy9w9+iaNB5cLPw9vvBPnz6E5xXMvI4pJkmhJEyKR2cdbs8rqxDWME9Jql2Jkfh7bBKKPeAD/eFTFb6EhzU1OKMpx7aXxd6Xg9sHN9Gt7emUqRQjOKs+RtEcCY3FqemmEYVDyLWEKRvGDudWMl3iqe3BL1VQKe9jOHuBVpUWPDTSoIEEdR8pQlojNR3s793BX7/7EHutBsaLue6tqsVPeYHxrxjF240yhuPQnh1P7JLxuSw9ouqQKTu76vnM9izDL371G7rHjz7/UEGVwjVC0M0Km8AZrh918PRsjEYt3yC7nd2sUythv25cxstFgusdH5+dU2dcwH6N8lube8GHS3j30QVfPgsbYLqIco6ONZhcRi8ed6QYiIdvrXtNS8ogeooYmZ5BpiWH2LOL0SIVe5MrhHBkmkxRqzUQeB0dy/VK84qGwOLeKRCxSpSuRfEKtXpH7NcopkJPZZSQsoEWfCqRk8Gp3KRlLYZFNEcQVLRJ6IPLITRhNMdiPoHvVxTVeFpR905VIBt7rDE6jaZOV5IgGWkIs3Jh7JG8yKASVJTeUH9NnJ3p2o5bwsPzPlCm24ilPeq9IMNb9+/rvn/22UNpyd11gnDNyM7c3MUnTz/G9976ju6DJ+hwPNRGvZiOZBvJmot8J1JhyDWiapH3KgSP8w+XNLMjV4mIoMlnmXM3/Io15QprXE6eS8YqeorcaAqCXbdN1AqbsbUWUnpKlVzs1irwi1OMw6kM1ryCixmFaUumadZl50JkxG8EZCRvdIKiQFtWPhsz42CULxQCJKkDFfxEP0sBklXxC0TFKB85t9JQWVNcGigQlE2vxLVVDny4ToTpghp10wzx5FNTkul4sYh/9g/+IZ73h/jBT36AdM2+zRJln30QPzcHpJkG0zhgPl/B+cadmxnhUeas5J7Y1BmOVeOHujJuIN2C8kb6HLVrgS0kwoPcoUQEViZMMnp7rudm51tuGXYCEUJVx1P8J/N/5TNiQVmttjEYDvVQWSjVq8x/E7jSqzMt20FCinvONuXVE4KVlpv4fbpEr7OPdEmB0gxdunV4nhanFa0U7JDnQz4VYVZfGPdgNJSpAc0G5vOFJkQxonPRUPhEZR9/Lo4T7PX2sFjMdB82547oCk8Aaj3Y3CzLMCEMzQpJUlI5ZGxQQxFhNENYNMWgIGGhQkDVD/B0tIAfVNEoLrFJE6TxDCl5W4I0Pbz90dv4lW/9knJmsnhDpkduEf351KZQrekZtZTDCOsSyYH9skiM/D1GyS3lxyg0PIU9nVgG1y8RpmNMZqGxpIkusntOoid5TAxoHD7q+yiVAvjFhoioq9UYq00E2qKalzAwT2mxY9QgpsjEKCxYWU+f74XPU9xXmcYBZb+EarkLJ6R4LMWqkOHWtfvyQiB88bz/JLcEAop+SeOxyfKm1FsyhWIJ4/kcLfqRLU7x4uyx6lSTC7P+MnvONx88wNdefxOTRYy33/8pLi+PtY74MbWKq3fGe+duUx+OseLvf+/XMsog+2cfypRBF63T31i1PJ3IbOTQShYy0vFK/MKXRRMEk8GqGbOmYIjzLmyX8y+JdJapibB4ktiUTuPiFIroNBvoVKooF+uYJRuMFudavKR0cBMx1WlUd1CrdpGQo0wfrVwnMYsjoUNGgy+rFmC+TZ4UFxcbaaRrMN1gWiQRTLGktIOLdzQd6QEyAo/GY9EWyEUqlvizc6NS+wHWywit1o4WW61qJmwz0UmAa729fNIs83ySGTkTxOQC7CuUGAjSCBdLk75SYqvhP4GH0WSG6/uH+JfvPUOvHuCVdgkeVpjPplgVXbDGIW3j3U/ex9/5xnd0QtMthU1CLvr+8EKbZmtaQD7RYpWgUvIFf7KOI5Oam0YSaXLe1maPw00tdWBmp/w0mWI6m1nPp8DUyJOjI08UwrFsLDI1q/oVtOp7CJyZNiV7KKuMXsAjo+ls2FQk5YM1S12a/2k4R0aBUd4PY4Dk6Vxiqsf00wFuH9zDMp4BxbrS5Fq9hRtHr2jdhOHEJiTnhEkGBSoaqdk/7p+h3mrgk0cPBRasVpSFGwuDRXmlXMNmRdfFDd66eQ/zhKmTi+F0jJPBMdqtEgKfKCxTUkeHgbhjebvDeePezaxZ30M4uxDuzt9glG9Wq/KCjeO5TaCVKs+koWT9chFQ6y2hPgl+MucizmxsTEJqZK9yQxgCYozSLZuUm4XEPsZR0uaZTmwyH2fDvqBLK47JS/JE8CMlgdfW6dxByaX3EXUlMepBFaPZBLPpBB55Tqul7IWYQpGTxAtnL0CqwdzryHixjkwD/HKgFIqnS6/dVjd8OySGCFyURji/ODU7IKxQrTfx9OS5mLjddgd7za5JZNMIvXYHk/nc6DhsTsUJlq6LeRyDd+r79O+1E2owNkO4vXYXf/zTz3CzU8crvQoq2RJnkzFcL5AEmBvt8bPP8Y3X3rDnx/oqTS1VosWo6yld4X8T7n304gmazZaQOC5I6a7Zoc+fP/9d6BzpHSLkbZBs+O5mGE5GZrixssJWkgB59ZK5QFQwgOvSvaUHZzOA767AIaZhys3EAprGcrQpIurk4lp3F91KCaOYPTDWhittCM9j7yJT0LsYnxojQPasU0HtpOj06rdkz8OmIN9N7qIrQwl+9vngEkf7ZuLQq1ZxOqApxxiPz2goPldgvHN0E36piuFkgN1aHffvv4V3Pn+Me9duYzab452Pf4R6lSDLS0+3OEpNXJcDE84rRzvUEWqhM6WwWiGTkwd9crnIjJZkv67GjYbd0w7G+FfkKPGkOL28FJyoSbBScBEVMFmmuDYA6qQ/LI3oxjSBm5H5pHoxa5oiECBg4VhWCkb6iHL2gv35erWNcvlQOf86TdGoVfRS6W8r+onrYkbkak1tmXXj7QFQWWi4ONNBbr7pbIJWo5VP7yUETTOAiuk/aOSc0OWEQ20WIPmHBSJTONJYaChAOPH67q5My5iHcGHJX0wuMUu46xgfnl+gETTQWadY1lqoVxuoNpoYXpzK1YTy3SlfYFCAU9vHUdXHebLSxmXhL6nxYo7d/Ws240SBiGhaimazY3McKY9ephjNpnj47BFazTZKRRblxjZQLyanzGhSsTl05/WIpzEXYTLFJ08/UQ3H1ESE0ALrjobeZRhOcbh7iDvXHmC1TDCdPMFkMUS9to9iqa5AejE8Q6FYRr3WUj20097FKmUz1CZvbeiGyJOcykxng/GYHLYIRS/A+59/KJCEmQC5YTd3XlUatb9zoO+/HNJSlSpAWvv4mM15PUfyJiZ6OZxFqHhFPD19F2OaUzBALVdoVdq4d3Qb3/rqt/GDd97Hzk4Xu70efvLuD+C6tCedCRBiI1PmDrlEgMAQ60vnG6/czAbTuR4gCya6IrZ6+5gNTkT44t+8Qe44UrSZTondKDl8EdPZWOYC1XIFM1IrmE4Rc1+uzf2D+a/1L/XCFMilDDMnCdGXVYTXlOoQghTZMRfoS10ougejfBE1r4wHd38Bg+kCVc/Dwc6OIjFRN9LeDzsHOLs8hkNvWtJncj4YNSYS1Mj9rygjteFshKPeAYZU33klOYRsSMTL6QhcdDwRuTFGw4FSuW63a3MEJeelkyLRrlTQIX+ONQyDx146we6tB3j++DlKzz9A7do9fDiJ4O/fQzKbQ+vqAAAgAElEQVSd4O71Lhbnpzj96EPc/5W/i/T0U4TzAfpoIMyKIiGyj3CvXMQvrgb4t+37KOTuMTxBWCPVmk3h9qKUrzP0B2fy3/3xz942Ah8btDrFuUFso1wpCkWloqwgwCaMRH+Jihs8fPIRwjDW+9jt7ePe0StKR6bhAN1GDxWCJUUXxyfvoNHYRaFIW6E6xvMRkjgW2lj1qwoUzDZ4sizmU0TJQicH0xeeonudFk4uLuCSau6V8fTsM0wmU/RaOwiTGY5278ErV7UWuIGZpvO06A/JmOZU3xDdVg/tWtsM4pIUB/sH+Pjhj3F2cYJmrY07hzfxrde/iW53H3/247fx6aMP8Lv/6d/Hch3j3/35v0ayukS1UoHn1nB68RxLeY0xkOcadTIq7h3sZNQbCCvemAqwVa3BD2hHY8S5wKuh3OiCtODnJ09R8QO0mh04pRI+e/Qx+udnEgKxD0JpLVMOERCzgnLwZqmAMSsTKeWsMcf6Rjg8O91bEQtPJ5oysECXHsAagDbchp17arc7OOpdR6qBOCboWfH4JgnS89FutnWNrdYuZrNhzgZgIW3+WKJKkwy5SrB0MvlqCX1T08sX1k83FzMPMDHXcHQhI7vDnX11zPld0zhClhAc6OJyMrHBmo26JLwSYSVzlDZztsdwfHKGB6+9Be/pXyNzejgZX6J6/xuYz89lLZRmVSR0XS+QMGcGcqTSTGZjdKt1LBZzHB4cXHWCuXFZi7DeUX+I6CC1J6dPMbt2Bz/6+dumzcj1H62KuUcSlSK1hP0fpjxspolik0sa+CzTdYxwsbBuuxeIkiNJOhNMwr864GnptMLKqQgpMzn0Ss3OStnSXzWbN+zIp6hUqlhvSPeo4Dtf/2WZYSTRDOPJWL0GzlQcz/vqT+00a3j/4XsII2YLNX0GJyD/ZjnFv4qKMhVnjytL6YnmoUmCaLWNTcHBwe4hRmefwXMiVGodvPnat0X3+eizT/HkxVO0O118881vKW3sXw7x7nt/CddbYmenh/7gGPP5UKlVFGmss6yFnFt7vUw9A48plckXCT4+uHlHpsHcKCdnE7Q6u8jWIwT1PUTTc0XJ88E5ms0dVIMGhoMTRMsI3e41nJ0/Mx3wGmg4Rdwol/HhcqEUiUWhWQnRIqgiCS/N0wrZChWeSGtGi0iNm6vjTvmgSXwblSp2m130dm7h9OJC3By/UsOLszMVwHxR7EFsbfUrlYpSQEKffHPcVCzOyYNqN5u4tnOAeRypqTiaTgUEcBG1ahVpW4ihPzt9ji/dvY/dVseMF1j8qpAjgGFTZrmgmUtLCyMrI5II7eQ8PT+TrDZyMjQQ4XJJVIU0bZIWDTHi/5F5oBHQiuwejs9P8eDmLfHi+MLo5EhPMLIB4jgWJ4o5OdNXOjzy2xq1Op68eKJ6kvfbZPpLEmbBzWswPt9EJ+gkS7HrVbFJeMpvsCEETXZvHIkBwcKVKRbNL7Y+aEw7JQSrczIV67hILGC6ufBaZB+U13rMONZModUTMQ3JtYObunYW6Ed711D0u/q1h09+hiePP5Cx9DwaYZmygcqAQWmFg3WS4JXb1zFLEjw77qNSbeBo//oVV48pIAPCfDHGftN4hHxH8q1LZigUa8pe0kINq/ASjldHGk+xKawRr4fmecZajan7yjrvvt+Ac723k4lQJmUXXb59tFsdXDt4Fb32Lpxshl6ZZsgO/uTPfyLY8TKkDSYLpzU2BTbwNkjDkY7BgkdKRoQVfZUyOyUCv4ZFOMotd6xjTYFMlrkICsCC0YVmy+xYrRz0Oh1JVvnnQv4zl4yypCHER69gAgijyUh5KdMBpn1yU7QQZ8YE6st46nXQSsc0UqYcZBThfdcqbL5x4hO1KEwNMoznY9VSGj5TtBqr02jlm0yZYs4iDdUvqQR0iV+b5twx+xkujpS2p0GAR8/HuNHxME5TDdNhGlmr8ZlEQs5Y55XLZYSLSLAyr40o0OlooDmEXKTs4NOHi/dIAIJo3IvzM9UM7IGwZiNgwROI9UvNTdEuN/D4+QmKUYRJ1bXFQuoIhWHU+yexsgEeC4LdSasRR2mFN197Hf/xnZ/KHZMMHmrs+b2s02h+wHSNaOaWiMgFpkM3b0YSobRTh+Zx7J8RLEiUvvCe33zjDTw9pwG3L0vW2WSAZ0/ezk9zs74VMioUjeYaC3QadSSrSMX+6eUAFc+3dJeoXJFMAdZiIZr1OiZUd5YoduNpYL4H1ORcTsZSgnKjNap1bAqREDYSNG3Uok0eU6HOU/ja/t2MuS3d6ejt1Grt4a27PfyjX+ngz989xg/ePkXTr+KTgfkMsbFis71toXCnGnxrD0T/vp0xwubiJhOBrEg25XSCDW+atPlkiWazizKZV04B1XUCp0yL/Klkqux0i+dPzpWc98yenguJ9QQXOtMM2vyzUGP0JqwoGjup6/KNZJpAyj2bVizaTQJMwiX7PdzQraoVoTY+IVUaxkhHoZelH8BOu6vvYDOMqVTgGVWbkblcYg2Qi8NymSqpfIzqRvMv4nw01Mtgo49/mWUOe02maTDdhNV2ZqpgVG3aC7GXQxEWT13Cu5xtof4K4XRRvg2JUom3XmIUzdCud9AqOug/O0ZhlWDleti994rsQ9VU06SvNQZEpjjDI6fjMI3lwuApy44837c8qOgDkAecikcD7pwyzv6X2T3kdanlVpL05nMA+Yzpz8U6UkpUgh5pjLPhUAhnq9HV/JTVOkav1VVQZO3abdTtOecGf2EaKaN40v8Iyw37XbEGE+3VezifX1L2hW61peD46u3rSKM5zi7O8Hn/ROxeIplM7QQbx7G5+GR8t2UUPKbElBsHshLiM49jNiVLcL7+5e9m4WKG6FoNs58/RbfewVfvdfCPvneAf/PTE5yMqFwbYbywriQfCRcbYV0dm9L+Ul6Z09gZWXJdsVwhWPyTdUsxFo/noApaK8wmU0UG1hr0qq2wiUiNgFCgkpqWRKSs0LQC04pR7nSrDRjtSDzjIlM3PaCTuTldyPWJC1E6lLWijxp6xRLiKMTxoI/dbg83dvdtaKWTaeQZm0iESymR7TU7oiEw6osCL9cXfiadw40WbmbWRtswa1SCFxR5WQebKUiz7JtGgVGM4IHMwY1doM/KAQRJMXIXFbtu6jZsHAEbk3zWJGly0ajbncuPWYjzMwjDP3z+OV65cVvXZDPi7dRkE1Nsf96DEMkNzkob+FRyhnSrpMVq7g6TW/5wvoYNY7XAp96AelysJ82GSOighHM5EJtPk+IPcbMvlgm8QtmivGQU9ucSuVzmI6W5eRj46DQpBI/ZhRkrKGDkSgVe47Ozx0qj2d+hNiRbbhSA3TKhY1c+yWy1tatcC8CSTHDP1IsEDYhs0XaKYMw6W6FWKyCK1tjrXccyZZ06lCUrKdViRX/vzb/NhAP9RYJnTx+iUanj4GAfv/93jvCj9/q4jA+xqn8brfAv0aySIlIWIW4eUvO8BH1xL0ZjpRnsSgviJWuV6FQSImDKwE53u52Lrcy1w5Qf9vKs0NtoMZHOUa001IUlJ0oEYmkCyNWidQ67y4QCvZwObk2dcrmG1TqyozkvPremEczVzbKTghoWqBlOLy8U4fe6XQxnM8wTEu/Mg0pGCXGMZq2uRqIcOuSbVTJxD6W3DAKixpskQC9d9qYEKUh5t278xXAg2HU6GWnyFGsF9o24qLcKPZEtVdSaUYKZQ1MRlwpWZod4a6ogTXUOnSt1UEWcYZeIFjKcDy/RbTZllsdrNScenjm53UA+fIi/M5qNUamxCM+HlubTbZmLcuMT2ZP7jFgPuYJ0S5PJ5/bxO1gT8USy+slerLmj0EuspJM+TBZC5gzQJIROwITMCQbUXETJQUQa0xDoBNrqQARV5yk0ezXjEevdpfpLYTzTMye4IoHWJkPZr6PONGs2Qq/T1hgDneo8TVfWFFZLwy2iVW9jtojwT37rP8fDkwke9i9x7859XJw+xvHZEzhfu/M1hQjm4JeTGZqt29jUfhflgNqNJYrzd+DhPRx097UwzbQ5twvNpaHEviWUophcxgg0jeZsOAthUgIqSjMiGTrENMgENWaWQFsdDTRhfhjFivjteksFNaPyTrslyoI4+tKiWx3BE2U4mchZb8kjNPdcMsq6cXSofzfvJRNDEWmT64bj4GI6FkzIjjy7aYxi/Fxu1latbqeGJmqZhtmUjHx3JDFSwGX/rcaSWMf2T6ZYvAZpEDSgiEUyOUl27UpMNMbORGfb0cuMzrJJFWHQ6gQGBT3DfANtvXDVz5ARM3/PHAQ1HDM3D5cwirUQPzD31tW646iBSoCT4RD77a4WGGtPnQ85o5jjzZpEn1hnaqNZqrU1krPrJ5OYjvq59U9OATIXSzO7I1+N76RZ4zBR80njE+IGZBOQzu304K3nIAN7GITvzcPLSIi8H64BXh+n906GT7UuzETTtEnSfVCc5JDEeKC0PEkXuLF/gFXGtNmukbT44/6pGokEFBpMy+iftkpQ4qi6QgXhcoX2KkOj5cP51W/9SsaH0mm2jbNC1znqJ7jA1LdwcXw5kPs5d6iJXjLZxAsdcZgbx0pthLBItmkvLUcHr4hp0ntLsGJHtYrpgk2CIvxLjtfT0xMMF5F6GAIg8yjP7+dPm82lxJYG8+bRj/WDeXnZTA1NKhL/y0YJmDuh5Z2MHkyJuOhJqRAnrOhiHsZyxyDd4PnluQwOpMUXbd3F2TCPVlUSDq33YOMJ7Lq04SnYimP0hwMthkcvnuHbD76i/oiNoTd/qdx10+yWLPfJn5PVQzJaYOM0icRJsmQnn10uioh9jmqD3K1cqU+BKR4Hf8aoCUDwEC4SuB7pFCZR5X6ezUd4dnYsBjDruHajJwDGzGYdNem4qS16m1bfjC7sxDLJlAUa2Yyy5ySUcGuuQCmxMYO5JniK73W6ljaw4TqL0KzT9d9OHaZH7d4Rnr14glbALMPcDcUlo9mbvNvoGDlGPDvD07MTpWjqW+eNYJo0EKTodA5R5viKiP2UfcQp2c4mCSdG+/jshTYbAQobRGteCURY2V9Rj29DM7oAzm9977dl+8OjjgUw57vxQamYY8Rer3F8zg3SMQo80Z9co24NvZKYq4TGGhx1nBsbbB1StqkUuX029tcSK/470wx+DxcZv4s5/Tsf/xyPT16oodWus7BN8NrdBzjc2bUCUG4oW0q3qd1kbc+CUZYzhuszgsecSiSKPb/H0iHm9ex8s4aQ5aXsTnMjswIHBpG4t8T5eIjrOzt6ASbDLeHJ+ble+N09GjLYNCwbJMTobdAvf//TF090bzyJPnj0Mb772pvYbbSFBskNPc8xVR/QooiGvdo1ZmsjtoJkoQQUQo0qUEcoL1B4PUKyRMQjLs+gQe8xV0GG+nMiOZJBb6f+5gGLhwkDyWRyjpPzE6ypW6/U8Rvf/S4GyxJOScfnKIXBmUa0MXfPhYBWZ+TNXQtuublbLr1WkOBIg/x0liU3i+ECMNyeVvmQIJIuiW5qVILsUTPcvvtVPHz6CSqlBM6GCkDKJljr0nfY6rr+eR+ldYin/TNtdNWoJSNGEqYlk9wr10Wd53Ple9H4PJmKmJxAVsD5lF9t+c1GaT2fPfXyFrttForzP/zOf53ZMbU130rFauRLIqWC6dRwGqHbqGCVrlCpNITq5Dp9pQHnQzqbZzqSuWD5PynydLLbhtC/5XmkTBdkb5k7nuTCIYp0JosJPvz8I02funV0A5PJBDudLm7sX7/C8a0xZSkIN/dWRyEHkC+YHfCrjR9mG8bcQq6GQtucQIINuQk3r5VUZ54449lCaZelJIbhc6OR20PnEeazQpFka1lUakbIlS+aKSK7xSxMOS11p9mWTSkjJzcnT4Qtv5Vfzu4yuVxS5ct31sy0GUvMboicrHzUspqtBhZwJITu5sr8wkAMymwZ7Iw/Jt5C7v9lyJqY0FjiOWHiZawRFb/9y7+BfpghXJYQOGv8+J0fqtvNC+G7tKTSzDQsMzBzCjb6zArIpmbxBKW2g2nTRXyO0XSBi9UIblTQRmcPhuxxNodJXS+vyyhuVui1WrgYniNzfdy/eRPNSkUDRenawpF/xfUSq6KP4WiAlu9gEjFFYjORcwjXAjPomcCNx/k21I4w9dN8kVx3bwCP6eMV/vMJzrx+r1RRgIqSmVGjqK9iR/Af/8ZvZvOlkRRZvJKASKowFz27oLJqzDxMZ+d6+K/ffR2v3nhgyIsaiw6G0ykGkwmOdvcwnk11yuzv7tsRrTyxqLTj9LKPW4fX9F0XgwGajZZpm4mXc0TWai1+1GB8KXlotVwWA7ZWbaAS1LTolHqIDmCpCanlzDXJvSK6xtkgXGyEAmW+LRWi6SK2Ba0VrWYgJvw7p8Iw3ePUJXv/ttHJBjA/WVtoPEmMrWqiJDMvsCJXC1tdebZaLQ2SWbJ1X/K8aptSMTzQpYUn38saxH7GKmpLvfKxdYyALGNyV3qT0Rp6ZSiS0b61cVQg89kTAbJeD7ISWnWSGD1USh5OL85kMmeTpQpoEVqnEYLfELhCIL3baCtt5t2zoGUDkfder1bVy/j0yWPcunYdBZr9cSwCpa/LJQajS6Xsn1x+hn7/HC7lrlQa+kal32/tSTUacUDRxaV8scijYgSPlgU0GnVc391Dtcr5LwE+PzsRg+LVr/wqfvzTf4duZY5m0cXFYobT8aWQRjKfg1JDDpeck1n1C2IgkDzK5uYsnNq024ybx+TBPL3KPsm21Cix7qGBn00442aXXer3vvntjF3xywHH48aYxYnklqSx89hiClQNOmq6tOttHPT29E9547KBkyzU1CtsHHRabZwPKGUsiGTGxqMJ7h2ZDgzGQ9zYP0KtUsGjF0/xja+8oSONP5+mIcbRJRbpEhd9FuakpdPKpYpGvY60MFYkYToTJqTZG9RM6JTFqa5F/Q2uRAMEzArTCnSmYHTLabUDLCmb1amZx8KrGfFGbtSvbg2j7QixDaLobQ9WdqVMD1Zmyq3+kCBVK2i5UYQg5Xm7sXvyXzPvvPzabBNpT+TIzfa6ZMiXQ+n8yXBOzT5P5tyvTNHc0hjjt4mRaMU/awFAU7O4EHld7DtsN839vTfw6PjY5rCXXRTLM2wcDunJR+hxGlihhS9f+6pOP8p5Z4u5CJHsohM8oK0Rf0+pM5G8vN6zRicXPDSvMYwXCCo+TqeXGEQjOGRUrAv48o0HqLolRLMpJrMhRtOhRhJUio4m9RZKDr70yutYZiU8OjnGdDXRcJ1e18Uv33jDnHtZM69T9GcDfPb0DOWACGcJd/YPsdfumdzYpyArxWA0NjEVJeZsbUSxTCvm8Vw1DwGizImUphNAqFUCOGXfz3jE84YI07JQ90tktdbRqjaFnzPKHu0c2DG6YUpijSDSU4ylux16YjRhXrWlNHYUW7FnZEFaaY5mI9UAw/kAWZYgXS8QryJRLYobjiJmjeGqYUglHzugzy4/tZMjH8dgWAHzV2tSUnfw6OypThEbSGMReEttT5NMC6zVo7t7fmbkptYsbOkRxcjIgpWmcDwRWs2Guuk1RkyPptMVkfFcx4NftulXPEl+8vPP8fYnj+REyFOW96pQn4+A2LJwrwYO5SxlnS7s4nPK0ya1xcmi0eH0JtJWzN0v5em3djC4SLC3b0NjtptN05JylnWr0kFQrtoryO+chSdJnoLLczdKOvTc6dzDjz94D77PunGDRTISVE89O098siTM7rOMg95N0Xv4DPhMNaSU6NSVUaadgDpzVezmwSDve0isJU8zDgyiLdMMx9NzjKMpCfC4s3Md7ppcNAeXgyGWHNUcLBGFG6yqK0TjFbygAD+jg6QnH+P7zV3B7fL3zY2w/9/33pdGn9yv2Woq/hfFeG2u4yCQGyMzHvZlahwBXsgwGhMCLmA6neFsMpV1EM33yLyQK2iv2ct2u3vqaHI4IslmPDlkiUL3B7qS0DrUJS/fjnVrEOaNDAVsQ61eZhHmz+o6rrxr6fmUbhY4G79AupqLLkCLD2uSGS9JUbFoc77Nrl/WxzYrRPPz8u+kqJ6iLRHnGM35p0qounXcvX6ESTzAjx9+oPXJVHEZWUOOI+GIAu7uBGi3qqiUAlzbO9KJdrCzK9ycPR4Kq2jIfDGc4msPbl8Zjdkr32ZJthCkbSk4+NHPPsJ//NnHYhyrb8CFziYY0yLpw63ZZuHCtqzKIWk0cjNwpWu5LSu78Osl6mUP7WpFm+3Tp4/w7PgYrXYFh3sdTKKJRF104ri7fwNBqSPqCQo0szAtjbQ4DGAy/rbr2C7imGO8pROxUQtKDWWKZ0OJhFGxoM6KqBZrYuze3b+l4CEXdZpFM7fXBF3rH1naSvjdeFwWzAxqN49lzghhOk1kKka8jDGMxng+PBMcnJVX8NIqZuMZ1p0Y2czF7m4TTuIi4Fhvr4IgaGGnW8XF8BhFrHC9vY+6R0ZuER8+PzYbIK+GZuBq2OqQvajZEHPNr0y1tiulKu4ePsD13p70/LVaFZvlGp+f9HFrr60sZDKbKSA7v/d3fz8jlcE6qeY+x9tibm/Fq3Wztzm0ZeIG8Rkub7Bfrq+x04QztJNIU05Pho8wic+RFcy0S9E131tKsfXBVsQr91OqYcNobDCL9Za4kEQ+4zRefbf9uplMc9gM/VuLaFW7+Pq9B/jTn/wFfuHV1/D/vfOButh0GyHU+ODGHfzim1/Hf/ILb+H5+QC3jvZysoShbLz5MIxwPp7izvXDq8LTHEdeXrilQZab/ekP/wZ/8dP3cxg0v7u8sWawaF7o5zNYtoYN23pDXMWcqEgdh3HjgJSWoMjwjRs38d6jn+Odj9/BfnsPv/7t76MeMNJv8OTiFO9//inG0QUqtZymrQDGjUFqjN2XNh/T3S/cg7VvrB9kG9s679tehwU+oozsXGdolXdwvXkPB52eYPGt46M1V80hkvfKz1EvLAdsdCKJ4pKpHuEJuKXIcCQcWeAjsqOdFYaThVTfNw734XKql1gVwA8/+CsMJpeoVXvy3719cAMpgYbLpxqDcau3j265rWu/mKXYqdZQrVhHfqsLmqULHE/6mC+Rm0HE2G12cLRzDbVSE0/OzvGlm4f6GbrhsBRwfu/X/qtM7hcaKGKbwqr87cC53I1QaZRpz7ftUnW46fbuuZgyoqVjpQfTaIR5NMY6i3P/XebpRirbdmVtY23dug1gsk1ouLS5cLPznUen3A3PouA2xzZkTNyg3NaU1z2ZLuFsXPzmN76Df/VXP9JL/ttv/QLajZZFumKGX//+38LZcII7h0Y1mcySKxeW3V4dF+Mx9rodKf+ofJSQyiry7VFgirv1Gv/Hn/4HPD45E5vVTJJN16xHmGvhrKdq/rHbGe2EezlwhzpvplfjcGFdCC4oat/Jpi1k+MbhPv74z/8fnI8upNL8Z//FP8az81P86Oc/RphMUA5sQ1z1KayIsuvMR0YbRSZ3zs/9h22D2DPc9jUM9TKSKR8WafFKnkjbEMXEw/XWHVxr3ZZUmmuAfTCCO0ovBWMb3C2ky0Z+XXXYjT1g38keDH9ec+TpLkIdfZZhr9NGpkYyXSRjIXl/8/FP8eL8GRyHtB0qHymHruLG3qE4U/EmtnSrmCEOCzgk4bbVVoaxnWwl3HSzloZ+GoWYpnNMOQApmcue1kMDd69dEz+P19yq1OD8wW//QWbUcHuY1mjLO9A5lJqJuGZwovGd6D3r48XwBfrzF4hSIgSJhunYmND8IeR5qSVM9rZER7iqI8xulIuexSL3nlnk5CmXkCCb1cC/tr5R+ZzRfPPk7nikh4QbBBUXl5ep7H3IsyLrt1Tw8M3XvgbXKyvv/M3v/y05mXz+7BT3bx+J6fnho+cYz0J0GlWR3fqDgVKu3V7rCka1F2t6fYEAeTPvhz99H8NpiA8fP7pKKSx/t6aZcn/VAKbKZM9JTuXye6qiWPSF8YdEj8jTYrOPdQXnIFZLuNGo409+8K9xOrgQsvff/Gf/EJ8+f4J3H/9AwYy9B8lJBKXbPD4BC1f0eTtFZPrNfD2fvcGr0nbQZIL8aNGLInKXT/66shK1e9C7oJtIsYUv7b8uyTHrV/Lu6BE2DUND8SRys2CqukTZhmUe1hy19UArVxIJLR0zT12yfqv1KhrNplIvbp5FOBe6+aR/jDAeYTyfmh0VjedKnpqO1CT1mm2sNiVEqyHcAk+SDq41dtEK6jmjw1Jcq5V4LzRKTzBNUnxyNoJTXOFy1ke57EgX5fzh7/yhxWTqBTRUM8fKpXfINGxGnBnPFWLllRx8fPwBhmFfp4XJatl7ZBfWnPnssMkL4dwlxQIJP58Dc2w+CDvALITYJ8oFeeZml3+GmQpYw2xbdHMEl5qRJpvQYtiqDi/7EfZ39tC/HIv/Q+3xL731t6RupFHa56fP8Pu//Vu4frAvQODscoCjXTJIc1KcmjtbffIaT549w5fuv2LmyVvrWdVg23HS9ovvffIQP3jv5xhOZkJAuBgIdbNe48O3JuAGG85C5KBL11MTdKdO/lBJ0YuUa0pHGeHoQTWMlsSNkcUxbu7u4Z//+f8laJzs4X/6O/8tPn38OT44/kvVcpaYcs9up0fZBtGpkKsQtWf0Z/JNLlq6pT6W9OYBMv8XbS52slcZjnauoz8+E1KndEx1hjxK8NrB17DX3BXsy4XOk388m1nfhBtHLIb8RMkN/pTO5QzkPJxaMMmbLGqe5qKuRqOGgLR09SbW+PnjJ2hWS7iYnOFs0Bd8y1/XgCWyL2gs4dVx2N5Dt9MQMkq1I6ksR61dHDS6FJjn7GT7Ga5Vvq/3n53h9k5Ns1UG0Qx9soT/6Hf/iAQBM4KWWN3GE7DFDyeFX87w4fPPhaqEyzGSJWfvbYt1y523Q0e2GYj6D3ldwYdsczxsQRMR40fbKARSWQwBs8jEF0hPVXO8NlrJ/0/VewdZfl7ZYeflHPjI9sAAACAASURBVDrn7skBQwzCIA1AEBkEGMAAcMmlsORyA73cYEll2bJdLpXlKv2hktYuWbKktWTLtVruagPTklwGBBIZ4ACYGcxgcuocX7+ck+uc+/16oEFNYWa6+733+8IN5557rsXBjo1hPQca6GIoVbPRQyQeQrvRR6lYF2eMyBYHpxCSPn7rHdgsFJErFdAP9PH7z/2aUVRCAaxu5TE5xLDLKCLafNLo6w2xApi0UgpIya5N9TF+mSqylpPwGX757gd44cRJXWw2dfFQkLZC2NAq+zYgiNwotqWyR2UoOygFFRI5eTDqfUrPcEa7qZnXqgURK2Pw4fCuvfj2T/9SxEUWAL/21JexvLGOcyu/Qr3N4iTZxW6SrsuVvEqxByTsxK+qpLOGZSEQDRzbqE1t3j6qyA6Cew325h/E5HbcO8sXLXzy94MYSc9i99A+pGNJcaa4SRLMowyoKx6KnSxZW0+j10AA9e+4cqZHn7EuEwVoNmWMvTbRsOj622QJsE+ec+zrVZQqeaxtr6BQ3ka5Vtb3U7dAeU6/jpHsiGo8UXpmjZ+mwHUPA9EMBuIZpGIp6bHxc5xb3MDRuTGHxNol9v3+F76p48wCWBdtFGuUH23gyuolVTo585xYcVvarbao9uFdIcwhM7TyHi/J8mtvAawG4cW4NvDRagqmqWUS+rLiokxob3bqAtab7iAgJeV2WaS/1eyhXuljemIMW7miqqjZVAb3HTlOcoiUFbfLRWw3KvjyY0+KYjA2kNFms85TrlQxkE3KtXtj5xgWsJYzOTpih8b7rWe3zy5pVvLU9PceLtxYUEimEQH1Jq4sb2B8OI21fBn5EiU+w8LVqZnF1yRFJSDELIYEZU7ZdqyuPRomq6SQWsFLNRgMYHJgCH/1wt+Iyk1o+bc+8zwuL1zBYuECqq2C0TmkoWvrKN4SESkHuxno4Ybf/Fc5kYW+XH9pX3Ewkp3NmyGxG23nXRS2oVKR0ma6WnzPUXZxoojDRzCcHhIcrigA7LPoSApqMbeOXaNTyiuo92vozE1IeIcSo8jC8lDvrPHzmEontYIp1JFAOJpAtU4tgI7EO0g+5Ox41lNKtaZmnnT7JlZOLh0T7lAwgnRqCIdm9wsjZcMdaVUUivD1OljNF3BkcmSH+qKg9Q+f+0Z/q7yFzdoqitV1dPoG/WkksLRiaD04ipd6p1b44yH3xht7saVnXDxUydAph2p44ZU3FcrGPZgYmOMxGSgknMu8g6y2O4z8IhNLGRuPvNJDtUy1jR4Ozcxho7iNYrWippen739K4nArmytYLm9j18QMvvTwo6JA8LU3cwW8e/G6Fp2yQg8dO6RwQ9QVmU87JYak3Zy9Z9bVh7DH6HU9HaEQdWetksx23++8cgLz23kMpRNY2tzC3MgoVgsllCj/E6TgQxcj2SQGEoNIp4YVZ9+yZxRH9k24ufEkHJJnFMSHH17B0sIa/vrlv0KhVNYl+sPnfhtXFq7j2uZZoVdaExY3dNjtwCv699gUSvzdcWOF3oavuG+wMXv2vJZ/qv/G6daKkLgT+jCHYS3EBOm0wzs5OHst+pgaOITZoWlk4ymJK/CzFWo1fP+1l/Ho7fco5+K7KT/xQi2Fg14NxRBK++WMsXd+HKFQ5MV+FwMDWaUG4uIxXJc6Zh1b+S1s5NfR6pQlJaROUhoNQcCm35xNDOOWuYOYHhlXPxKtyQsn3sFtB/aptbrTqKLXacB37Nhsn6IH3nQlr4prWL3ZfVEJ3YeUyLCbPmuap3SzHmLiCoY7wKkhItJhcgLP2ht6FDXteIiGi5md1L2GMboQ6uZMbaM0dxtAOELZ0wA2t0wbdzQzjKMH7lSVnbAgSXbLG2uYmxzG7qlZibQNpTLKMo09Spkbcp8g2oXGNXc7YuDOjI3drEy7UErdcaKLm9y+R+RU/cAhQ7xStKSpWAh/985JvHN1HrfPTeHM/JI+T6Vax1Yhj2gsKTo7QY7Dc9N45sHjdqg5vNR5V6cKJg/74ZkLWFlexfde/hvxjbg23/jM15AvFnB17QPkG6s7/eLmflWntQR4x4M4r+vGQSs89EZ7O7jaSqo2G4YWV52hiiKthqOj6nhpLu109u/mjHSxmzt9DMTHsGdoDzKxIc1/L1Vr+E9/9zd46q6HVN1Wq677DPQAptNl0K98ssI3R89xyZ9XTrCw1sI0ySz5TLhbNawIJWW7yJWKWNvewMTQIPKlHLbyGyjVCqg0qvJgUrznc0rhMoyhzAimh6alaj+UjEgtU6qW7G+6797dfRa4zPJbCMFCnUnA28gDegzDtS0dNEFg73bbpuxcMOUkXqJuFmZ25nbML54UpCckiq+hSbKu0u3uF9/eS9b7hHc/gn7pIlKnq8Q+iyDuuuUY3j7zK4UWFJb75PGnEIskUaoUsLS+hO1aDc8+/JDGpVndQWbECw4V33ozw7k17FTg7AkJYzvWsZErPXiUjF4qnVveZExWnyT3OUWJf6O6OWdqEKr8dy++jV+7/0587633UGaLZ6+PieFxrOTzTBjkiYYyMXz58ceMkbBTQrQ14Xr+4Ge/QLNURyQaxvd/8V09Ay/J85/8kpgGp+ffRbG5bI/FhjKtr112K/7thNNOkd4OIHM81avcFCbzEsa32qlreXWevk2jVfOZa6m2mR0WCwtB0zgzJ+6kUdF87SCmB/dgKjOLwVQaf/LDv8RvPP5pzXzZLpHm0RRPLBqzsNIawczgesbYakMOdXLuyvpJrH7j1VnIRKBSCz3LyMggy9pY3tpSkx5DPXa0MldhD8lWaU1Cg2zM4gVhcxuNNUmou6f2Y8/0OHydHgbSabu4x47N9L2Cn/qRHfxlIZIddvvPPJ6hDzbK2dbY4cPajJvwnRfJxqMZ7N/1CZw6/7dWPXau3pJcl4R7HtWFB+qecxAzcxVuumLePiHchg7jZx/4JN4+976pmaOPY4fvQjyWwo3VBQxl09iqVPD3n/mcjRVmSETGKX87EoaGOJLqQUXzdhuZZFQEPTJhCejxh3iXOX/DgyRt2ItLWDkv3kmzOluhp2ByTmLlv/rJq7hlbhbX19fx3sXLxu7l1NdMFtF4Qt2SnA789554RIILtGpWJLU14fOeOn8ehc2iaPsvnnhR+lTMWT51/AkxHS6tXsBy6YrN/JAXMktjnp8Q6s1Cqtf7zn0kP8mzSZ5h9KBz+7t9DmNsu3F3ahy7KULOzQ8giANzR3F14SyaXUrFGhRsoJ8NX51IzWHf2AG8f/k8Hrn9brVZs8i4kt/G1aVVHJiYUKit9mmXJ/G0UaGdXp6iF6Txu49lF93rodl5VjtAXJN6s6b8lxI/jCZoKNTHJG2tBsrlEvLlTcnsUkes1mopT6I+2MQwxfkqVlsKRbF7Yg98h4+M9ukNvDmCBg+6CND9QRfE3WTx61WRdaQJBwea97FL4+HdXOCZiQMYzx7BB9deQq1R3CEImkewS3KzKu5o8a6yzFfstBjbAul0FL5uFEvrW7Lyt+09gsN7b5WKN3MAji1YzG/pUH7h3mNY2Mpj/9iQ07Yy+DosipQN1+Hl4GFntZrCx3PjIwYxO6/F52NDjkbHuPKzqaK4vg1RNDhcxwAD84bGjOVhf+X8PBYKFdyzbxb/9qevKhnUEEle2GBQaoscGf3M/XdhMBNVa4EBRl7FyA762XPXsLS2jNdOvqJCISkfX3niWWzkVrC0uYTVyiVX2nMlYy9M8VI6x5bWxXNhjWeBdfEdDUSG0HHHVK9xdRtdFK/OJ4PBaVHWkKYalmbYG7Jnhs0QSTkYQvqtrgiTEX8G+6f2qrhHb/TSyRO4sryA5x9/GjfWiUKVcPvej6nYSmj8jXNn0UYEqUAd9x+9z9BLKnC6fMqDEaycYA/iFUo1npqegQYvFBKJNpFMKBz3ui8liNGuChlkcxnzrqurayjWcogEfSiUNk2sYmYu3ZeF1igqowhYtOVRsA1X5SHR4BqXSAuSc/Gpfe9NcqDK+y6R5fenY+Mi+a3nrjntJ0u1vbZU8552uGwj7WEJeZa227ogf+/xT+Nn776B9dw2YlTpGBrGx489JJLi0sY6sqkA3l1ew9cfvA9HJiYc/aSHty4v4+wqBY37UhX/1iOHkYwGRCw0gW6+F02eparihxHR8ateb5aYWleyjq74ttND7RkTayVWSOC+ZyVfwf/3xmk8c8fH8O23PsBQKoF8tYYUuxzRw8jAFGot8tS6+PjhaRyYHbYZ8168L43cLj44dxlLq4t449QvsVUqotXx4bef/qoq3JeXr2GhcNZ5ZTdnXqibCT5YHcQTXTBmoTtKO1ikskRXt7K99fo2vSTZXL6KchrX4BlCH0JiOdvlIPOYoV6DgggqVfmRCicxHB1SuE7K+WhmCrH4AEayGSysr+D9Sxfw7IOP4W/fflkaYE/e/ShWtjcwOzKO77/+d/An9wO1ddxz6BCO7jvixA1ZpzP1Sy+E9AiSliOZAfPGSrMO1Ow0pPA5OT5pwuXKv0wbwRsJQQmmk5fOo1LPqQjJOYoK5+b2DAlrU6gk2rQLjrxKrNPV9f7dUghjy9pyuujTERitUu6R3QzG88yUepsdYmGWx4Su9YFduGaaWewSM9n6tWWOEfPh+cc+hXcvn5fbpiUezAxj38wuLGyugdPN/ujJR/AfXn0Tv/XgAwiSKMg8R4lcV2LQ/KQj6QTSFGvzQZ5oxnUGesQ8oxkS7rSQxT65XQIefu8wWb3E2yA7UJoOazukn6OK4Z+9fgYLxYpKqCODA1gplNTHzmoxXTjJcE/cehB3HdivwZR8TRv0ayvLOsK7p8+hUCriJ2//EFuFkqRSH73zUdFfzl07h+XyORtprXNqn4VeyoPGHeHW9W6b5dopZzjgxWNPSOzPeUMr+Nozqt3WXS0DVuwWy6Q6T2Ighu27PIgjMYZ9lGmiQqcPoX4IvmAMeyf2abDR1nYOH7/1GF794FdYyq3h2IFb8f3XfoZHjt6LVz48rWSeI9buO3wMeyd2KXzTPBMHnTmNaYd2eUjYDsHPcpodLMwnpcpgyHTXOIOEwhaq3HfaaNQbOHf9MgK+DquCmF9bRLVWhm9u93DfikZOVcOrObj38SQsva41r0AmqoVDGKyCaw1UylMUhNpieam44lMXRjg5Eu0q35mX02N+Nlt9ZFIRJKJpbOdr2C6QghyQAPGj9z4sBRXPKlLgbaG0iQcPHsAX7rpdCIZ1v7lwRZCm9W94hs+etYeV9S1Mj1Jn18XYHm3cE2fYYfU5mNerDewE7/QYN2lG7qQYdCnL7cN3f/Uh5je2MZqK4/JmHk0eHDU5uZHa7Tbu3D2NJ47dJnTKiqrcCc4XbODK9UVs5fLIlXP42ds/VaxMivfzn/qaWpFPnj+JYm8enZ4phNjPWv5hzVsOhXKhrJf/0WhYI5sDIDzmg1gMHlbs7Jq0xDx2kCGSJlrhDIK7zMxPOC0s7A9hbmwvbmzNqyuUe6uwvMeMJYxAnzNC2HCVRsQXxa7JObx/6Ywu8J37j+A7r7+EmewwShsb2Oz7MTcxgqO7D2sMhUY5u32wfOVmaGuu13l0V5z2+HDemohvzCIspxi4y5bJZISAlSo1nL1+BbsmJvRjLDqWytvwTc1l7W1Ey7bJqio0Oc6RcHHXWE6aiMnAmFWhm5Jf9SRgvAuj6rj19Jpkv2kcefI25gaNJmJn10IX6l6XK21MjYzgyOwRvP3huyr+sQeABbIvP/Wc2MWcY3Hx2kV0eg20/H783lOPY26YItbOmzkxB7ugrkq+E9tTsM3VWFyhQBwrrYGxiGUZnaKG57LNUtK7OUehcNSthygvBoV6ZD1+75n5NfzdyQu4a88UXjp/DcOUHyVr2qmE8KcyiTi+/sknxMVyjBQdljOXLuInv3wNdx65E5eXL+HE2V+h2uAgyy6ef+qrSCfSeP3UW6j1l1Eju8GBH1p6eml6JD2PIVS2b1ZrsAKo7ZHV6+xSudhBBkQTqpw3U7ir1zfQxsUHog1JoUZnwa/msW6bgnpx9P0tjfoWcdMzumrkIhTMM+bHnrE9SEeGsFEghSaC/VOzePfiOfiDYQz2A7ixvonIYAK37z6gycSWAthzeJ/WohXv7Lqk2bvArkbjdWdaWuDCZtXfbF48k6zhoayGglJAjrMvuY+tZge+qdmsfkxSoJKgNNlFr+AnYTYJODhkxH04Vs7NpbrmHPO9O2vBf/dIjx7Z0LsQFrPclHXxhs5Xaz3RRXaP78YzDz6OH7/+Ioo1jnjjLJEgjt96nybNXli5iql0El984B788N3T+N3HH0WXXXn6DJY104LbqTdoWUIFZVI1qN9FXSuj6MteO6CBT+k5Dn7JmvwlPeC+z/7NLrWFVeRRMVF3Sjc2JEYIqx+bxSr+9p13sXdqEu9dX9K/EZmhNH+70RBjld7if/zyF91EKndoQbp1SZek1w7jrTOv4eLCVQljs+//qfs/KV3bV999DcXOIpqdqvtcNy+CPiGTaSfDqoPtTrrAD0qFUjDDJfHqknR5oHGljALiHX79rKP+iL6innhjgbNJjU8s8EbQptVaBf074+N5dQuxyWjuq3d8OD6KscyUxrONDY5gcWMdo+kMysWyiKbJgbTqZlSFMc9rzV/8bfWpHfdm0YgUGbyE3SgZ4vM5Lpr9g5kzqeOorteSPnQoEtBsmS7PNuc38mcmZzIyIoLE3KLYC94UDPMeynqznUXy0AMnP+NBX7pg7hK5iGvH5HrJoAo1bnaFOD79LpLhLBbXtnVryUl65hOfVdWWDVRsxifct7mxgi3O5/AD/+SZp5FNxDUKjjqwRJwUwWsjiS65opNzyrSaVxaXJao2wkU3t3nTc7jGHt2rHmNd05rlQbBk10WzZnKtq895QQ4YYlnHy8d4MOldWHj6sxd/gV2TU1jKF1HnWLBuR4xXFqJoGKiE/98994Wduoqx2MwY1ao1nPzgEt678CbOXDmvcchkOHzhsS9hdGAIL/7qBfhCJcGSaqf1G4rEUQz6LAIhjFUlio6XH/T9KOWayAyHiE04PS/7/B7kb4CFGRZDtey10ecI5bZNhXWHz3IYizyIBmknvGlSTkPMO8yu8qUz0u1SXLCLQD+MW2c+hkAgKUqO2Aaa1NVVR6fCohoNS1ghtFAz8Qztc7nAxYWXxjq3CHMH8TDD/ZEai6tSO3a5hcq8KIKJe/Z8g4OD8E3OZvpeVu8Rx7xkzwynEyGm+gdL9Rwq4t5X8jU7Ik9mbTRdyvGrzIQbWuQhDh5axktSKtRVtRwbnEIslMG7F066JDmIT9z1sOY7sF84Gkni6vwV+Nl0FY7Kiv7hkw+YIJrj6SyX2TZKrJsr08XR2aS1vHr1lo80DOmxvJ50Z4A8L7Kj5qVL7mraujVMfkmRcPI7LrcJ8ntkNC2f8uJ64Sz+IN6/toDXL17V1+LhEOZGpqSGHw5ENITzvWsf4vnHH1EPBIUtQmEq1NsM7+18ARcuXsdrp17BtaUrEmImwfH4HQ/jY3tvwc/eeRHRGNUoN40H5wEKCl3tQngJthkue57ipolFDI4zbLH9UY7pOgt3MlsrngjqtiKxD7Pjd6LRKCBXuKrQhmiRh2DKW7hir5y5+xyGMhkoY+tjg31M6pSzLO3i7R3Zj5HUmGjrlKqVjyLViblNLIKtbQ4tJbM8bKiru6CWs9tZsL21YrauvNqaHenSRTuMDmTEdY4d3OS8Iv+Fa8mOS8408Y1Pp/sMlVyZw2HZFrx5BD4vROLF9eQ8LZ5zb/CRGNNYlLYgO0xNlySzhdcW0eLVjdUSBjNDChmopPGdV36sC0cxt+nRUdx15G4koil8eP2SGvj/0TOfxi8vXMOe0QEcmBg1F9inpm4FPzt1GblaS8qJo8kInrv/DqdG6C6JR51xoReBBQ3ivAka7WQpsuIOcXBNo0bVV1jl1UKM9cqR1jZ20Thqlr54/7cL9S/+9kUkIlRM6WIgmcHidtXYyz1yw7p4+vhdOHbwMC5ePINd+29R+MPXW15ZxfXri/jxmz/B6taqlCOP37IfXWTx0N0fx0vvvIaebxv5+prNlnSqih5Yok8qiSVTpGRox8+3eqOFdruOydmUKZJoDVybsyUxOzwtXioZTJenxCMZ7Jv7OIqVZVxdelfSOIzh1U/ieuNVU3GhnYum7YJ4ITj7Uvhbaon8sQACPY557iMaSuKuPbeh07V5LZo740CXaDQm3WRKJ6mIy4Yrd+GsTdvlR46yZLU7C8cEYXstxw599S6uwj/j5ewYOdWEGIWMT6ecP/Cak6yiqYTXhRDq+VBl1YN2LXaXeLLzKIL2vKRP19g17YiZ6mJFF+/TqReLDdRKbcRiMXz1yWclL3RleQlN9lFQfDiT0WGaX1/AZrWCz917Dx49clgTrEhd9pJSS6L7OHttEfvnxnFtaRO375/FexduYNfUOF49dQYPHD2CfKWGqdEBCzX6FLZ2CIg23img8FOLTesgTqFgZgkt7jYCp1W7zcp7CazlYt7fA1hYXdfP7Z4ax//98zeQTcZwZnkFA/EkNsolhQpW9wngjn278OSxu/DBydex+9BtCi2pvHLp8kWsra9LHvUX77+Jaq2B5x95AGvVNPbNzuDt0yfQ7udRaK1rTABHdMvYfSR85FrqUnOaq9qdSb3oYX2phrHJOAIRrz5iDUseKGFG04qHO9T+HtUqqVmQkRo7G5cY1mmF3AFUSNoHosGICWpzFLXFZtZWoNDPCO12rtw+qL+HH5Z7E8LRmVsxlnbAi9MxZkGbnoNNZfSm9VpVox7E13NCHab7dRMV3bkYQhcd/O3Eu4V6aYNv5iM7IIYbOeibnE33zR15VtB4RcTy/qsEizfU81/23Sa16SW5Cims+V8/7vo8+DeNJCAa5oqRlHzZ3Kw4Gjzw5D1PYGZyTlAnRxOYjlIFy1tryDWIXUfxvz73DDIRyrK45MwpNfK9tooVvHvhGh69+yj++qU38PHbDuPdC1dxYHYK19ZXcXBiDpvFLdx36xHbSC6moia1zVkc6m2yS6Y+egGFfLh8xAsbbW082f+b/Spajz51josyMKPZAbz44SXkqnWcXV5THC9qu2bOs/DqQzYaxUMfO4B8PoeT7/xEdRhWk8eGJlGs1VAubmN0iCzYABaLbdxyyyclm/n2qdfQ9VVR7qzbBXDQu0YUuXBHeRIFOMjT0jQnhkR+FPJNxJOUbiJaZSxmq0pb5CCvocTeQA4N83SIEb/HhjQ490sP4jFwyXYOhHHn7ntRb4TFoqUItirtDim1yM3muAsrUzhm8/lohIYSMezbNSedNfLGVjc2ceHSDcf0tk5NqsHzRTk6gZ5EkY1mWVpKIBlWWkFR8LyLYYJ8fEvPaOzkzgJ5brLUvVZp3+FDc5by82c99+piO02qdUQ14fs+n+b6qbXWcE9nYQ3l8UIriz1Znae1CKDVIKGN3YkRZGJj8Pei+OAqlUfsMh3Zcxj3336/Qguu8+rmqqZXjWUTmBjJYKNcxR888bDlPzoEFlvapfPh56cuoNHqg6PkqLvb7AAzgymsVWq4e88u/Pz0WTx05AA+NjttcKxT2/BcrhEob7JSFZa43MXZNwudtPiKvB1Zz+oCl+aXsW92XF5BZEbnScx1+3B9q4j3bqzg1OKK9md4IIDVjQZnBSETsxFnB8dHd/hP1+bPIb9+BZPZFErVBtYKRayWK2j7mZ+E8Mnjn9Tc9rNXzqLW3Ealven4Wy4HcPNO6A1pszSSwTFgueRbm3XUam2MT8ZVuzCNcS9vceGId3J0B1wRznlTBSMeiVBewS6Wzp74OH48etvDCAQyuLY4rzESRIVkQB3E32o3sbi5qh4RY074Fft3Wk1Mj40i2Otg1+wcRkdGte43FpZw8doNk5yS46Haf0iQMGfc66wygRdvj4CFKb3rhDlr56FWnsSMNzBH4aXHInB1PGs468H3tU9/tW8Snq4gpGKrxeajg9aZVaUki8+Pta0NfHDjXWyW1uUoeAHkJmUCjAAn3v1HClC8srmNmiq/B2f34+O3Hdeo4h+88lMnBQrcduA2PHL3g0JULty4hrOXP8SBqVH84aesYjy/WcTh6cmdeJJZF5mrJy5cw9z4GP79z19VwhsAB2pyfALHBbQUJlLxooEgjs5M4TN334bxbFLJpnP2O+wBC0vM4tiluJnwKUbfEY+zA8FwkzEqk9TvvvQq0pkBPHP8qBJCvictroIPvx+5ShP/6fXTmN/cwkAqjkzcj4X1sghyR2f3ChqOhgJi6q5urOLi5XcwneH8QE5M6ghKztf7GBubQyw5pklY7Ps20Wj2cLeUS9he8EAbq5ebZBfArL317vRRLBaQK+YwmMlgeGDYSffQi1hvOLW6nPydad86EQ9JjtPTqLfCIGq/n5fQrDZHtXEN+R6kniejKZMWcmeKLQ9SrG9UJdOaKxcRDkbU5Ebkkp2WtPwcNNRsVhHod7Bv914MD4/o9ZdX13Hi1GnpR/O5rLJA8QeiXh0UiiU1p/GiaDKyujkNYLCgyPKrncY+x3qwUIuAgYVaXoFRhvi2vYccN12pjCm89304sGcfbtl3i7qzmGhubW+gXC3gyvpFrBWprO24Sw5G9Sgk7Erj+5pogV8qjcV8E6loEr/+5BcxmM7g/PWrWN7aQK3NOethDKUHMTU6gmsrC1jNryMZ8eNff41FQR96sjpcWFPLUI7AGentLr735im8ubyGcLODpa1FzA7vxvL2PDKxLDZKOUwPjyFXKWBibBdWNtfwufvuwjcevlswKJm10veS27fEWp/bEfaM3u1hWuYqb0KmFnfTMBSqZfzDf/P/4vLiEt78V/9M+ctrJ8/j0WNH3Fg4WsY+/uTVkzi/yklIThG928PhiVmkOS8kAOQreayur+PClTOaRjUZo0pHT9SaTt+Ppn8IudyCdLxKTfawG02HbQMEQ4xc6UkXGWpoVtVganOVGwAAIABJREFUJWL7tO6ewJvtk+kC8Ac9RMgOkvVLEECQRpYOkqstuE5Qfp2iEjTn/LKEP+SxvEKRYaEKRPvA9PgMDu47JC/DfazWarg0f0Vj5R688260WxzBYDwpWu96o4Jet4lGpYKPHbkVA9mMwrql9XW8f/a89MDklZynoxhFJBZDbptt4aSyM4FnhBFUmCaPIIPi0C0HeYtcqtqILIiD9K2HXkHEUw88rRmFxsTlkJEesvGYFNWp1VuocYJSG7ntNWn1Lm0vYCF3w9yiw7ud2bLYVQiFI7URby+1Ua+bgMGT9z2C3VN7VCDiTOxmh9VWWqwultcWUWgUUO8Cv3HfHXjm7luVk/Az3QTwDFamIXj/+iq+8945bFcr0k9qthqIxRLYym/KcrE2kE0Na552IpZEsdXA44f34HeeOC59LXLa6bGEZDmxaNeUhz/5wU/xjU89LvVHC5c8wMHN43A+hheIw3f+4P/8j7ixsoIf/dP/AYlYBJeXNnB4dlJ91Fx8hql/8+4F/OLykg5SKhLDWHIAnD7LTeFn3MhRNqiNbY3VTiJYXUSusKq8jXqzofQ+FAsrGM+GEE+NIF/nPMG2ZiQq7POkhhzJkQaqVC1K5d0gV6s2mziCYzKwl8PlmqFoQq2m9AKantuHhhSZMovBqKLxSAmf07/cFCjCoo6qzoAmX+Eo5wG9lnUi2mWLhGMYGRi2Hn0Vbm9Oq+JnZy+5PD4Fw5XfdlCvVxBgzNrrYnpyBrsmJyRmeHV+EWfPX1a9xAQ77ALzNSk9SnUVdl8KuHD5CT+vTQZw4t0uSrrZvejiBgfMeKCT70tPfaXP5GRxbUkTZxki3b5/L1IxTikKqKhFC7K+vaKDvFHYwJX18ypnWUHwZrca30JYt5xvGNFASrOwteDw4ciu/Xj4rofFqeF0IM7NJt/l/PwljKdjeOSOj+HP3zyJf/31Z5VvGD2bSa0PGxWg2u5jaXVN9OWXTryK969eVU2EvCXmNyUOwwwE0FaTj09ztimtWa/WEYjEcHzXML71mYd1EHfICo5CYoEVsLxZxj/6v/4D/vj3fwOTI0OuCu999SZrQqeOnqzVwj/9s7/B6SvX8dI//59t9DGLl2Qm8D/FxEGcmK/i/HoOjXodCXUx2hSrrdwmCoUcovEoGp0eVjY3dPjalRU0a+s6nKPDM9iz736srM4j0F5HJp3GuZWS1tGjhJiR46GOYWxgxHXddaWjzP7s9dwmipW8TbBy32uIDUOzEGZnbpUKZr9JYqeFzfzeje119X1TJZPzCdm/zSaxICVKd1BJQq7kmEHat5zVzhCTDFp9Lg4tchOlKIzHS0PPRmYtlVx4ZjiJi8zbgfSAQBTR6nvUKyvijlv2o7Cdx+5duzEzNq5138xt480TJ7XvnJjrImOtgS4FxQvrDeTzResnYm+6E/v2ciivkGjq/VYn0jXRuTOEy/ebn//tPkll5McHgmxZbCMTCWJ8ZATBQET90vVWE61mHevbqzh3+SyawTJalLR0rneHNCasPYSwL4mJ7CxGsln8+M0XXSwINfR//pFPK67myObNfA6X5q9idnwQ//0Xn0Gl3cKFpRXcvXfO4e4W9r10+hreupSXunmluIlcp4JYC5hfu4p9k7txZW0B49kRLG0uY3xwDBuFTUxM7Jb0ZCJDAeMgWo0qjoyl8T999TMKebxfolO6lmFao3/5Vz/Bd199E//8d5/HPYd3yVoqvJAiiyE5uriOScBFfvn9D/GjN9/F//aNL6knnUopGpbTA9aLFbx1aRXlTgwxNrP3uiLLbee2pPPEjU1nB9H2+6W4PjYwJW/Qbm7g2oVXlB+Mju9DMDqFPTMzOPneDzGYSqDQZl2lj5HBYeyf3S/LTGG+dDytWRetDscyt6S1y5oDT/PCyrLJunoj3HjQKahFSkowjPHBUXlia11m7zwrykGUKxWtQYLq8JoS5crHrsuQYtGM9tnSSiF0qsjTfmjCluoJPHAmrcq/S0hBM2mMz0dl/lq9gkg0rhoHOxBNF8GvfCQcMSifvTtH9h1yoxyAlbV1nLt4WaEj8w2v09MrSrLyzvRgbWPd1UssHGShkQ9hHtUTSbSE/qbInIP+H73rsT57NTj6mdj19eUbGM5mNLx9bGQCoVBEODYZoKcvnMGrp9+UAHQgSE49a6zEplkVb8HX7mPXzB7MDM/i1gOH8f7Fs3jlvTdMJigYwmh2BPccuR2pVBpLa6tY3FpDs9vFH33+M/jYnjlHFvTbiGb1mlh9Olcq4+ziCi4sbmN+Ywucsxvs+aXmOJAcwOLaAsaGJzC/sojdM3twdeEy9swcwHZhG/FEBoFeTUWqiVQE//grn5XMDWsGQubEozKYl+H6P/v2d/D2+Uv4t3/0OxgfyjrAw0pQ/MXN8II+wZ4+H145dQ7L2yU13CTDETzz4P0o1rvI1dp45eRpvPvhKTx+7/0qelGBo1DaVujCZDPMQ9FqI1cta8orC52LSzeQTkSxvHBSCXg8M4HtSgsHd+3H1sYVFRjHRueAQEj91If23ILRoaysMQcACWIm1ia9KA4b5UBRm5vIZ+Zrco05Mo9cKoMjLcdjNKkaiDfp1uWUyjFdtZlfZ96jUM0z3erXsrqGCmyu+1CGROgNw9E8FjeXNcN9cmgMs2MzCqlUX9Lr36zKW85nwI9AI+fpNcBJhtl0CTY2trCR25LBYj5LD2cexRr7eBn9oRCKVJAvlg1wkCZY2NGIvF4kpxe20xPvAvtvfvGbfQ5Nl4RkuYIry/OYGZ9Bu1NHlQnuyASGB0fU/fbyiTfw+ul38MT9D2O7kcPKxg2pnfAC5Ldamjg6MzYnWjqPNuPRrcL2Dq8rGo5jZHAQK5uLyJXy6Pl9GMpm8d8++3kMpZM7LFElitosG+lFKzCcSeCP/o9/j81yVSC2BFdIb1fRqC6pTH4v/x8MJ0RPqVTLmBQCwuGNwGikj2w2K6SDQz1nRwawZ3wIo9mYsHIiUs1mE9/643+Hf/K1L0mG0nB0m/+3g27RurniZ67Uwo9PnNF8xx++8TL2jE3iE3c9Iq9bqBSRy2+gUa/qou/bfUBhCqcoWX++p4trE7YsjzAMn4d3Y3tNyOFAiqGeqS02mlVMZNNIJwfRIg2DyA8tvlIpg6oFNIDfW8fjxx9FrlzF/PKCOU0dRkfqI2mwx/HeNsraJj05BqeD6hnGUQOYF459Jkx+2bJrLQR2QZgvqEfdCfnRe7Kgy/Zlbzwbw62TF98TfUPsWr8fg+lR3Lbvds0c4fOOpAfsvjmBOZFnJfjhsdzskqr4x7mKoT5mx0YUqjM/Yl1uc31LxozhG8NPmwvTQ4Tz4P0+rK5voN8xoQcicR6R1VUcdi6k5Ph40b/22a/3q/UKBlNZJGJxPdC11SVk0knBbFtbWyokkRx3Y3UVr516E19+8lk17rDqvVnewNXlq7ixsIjtUh5BfwRPffwpDA0MibFJPVeN5RJXqIf1rVW0+i2kM2msbhdEsfj1Jx9zlIid9iSn3kD0rIC3P7iA+XIDl86fwXYxh9nRaVxfX1RYtZbf1PRUTkryBcIYSA8hFOYEJxuYmfJxmEpUhaHBiB/xzBDCnE3X70jRm9q/A8kYjh+ew67RrC7Z//5fvoOvPfmwettdgdiGhvaAcrWNjVIVK9tVrBdr6mfvUAWw08R3Xv4Bdo1PYXxgXOOaGZ4RcgxFEgoBDu/ej2q1qNkUgUAYyVRSHsPjEvEQ8YLKQ3GuX2UDuXzOTcnyugSBAaJ+E3Po8bD3+5JRNcIme7c5I9JGTjcbTcxOzAqmv7Z03cTUOMdEE5XCUt0XqZBi5bxofV40owpZCGlhiNGHegJtKG/E7xcTwE81eO4rq/RBm0/ZtUvEvIfTf5WM+4k+LeHEufc+6nB0ET71wNPKUQgLr28XMDHANmmypK2AaEOYTK/YKDH8bY1d/n4NiUAbExO7kEwPqq+j02xhdW1DoRtHuLFtlnU7Hnb2/ociUQ3VKRZLej4OFtUkY3ffvZ5LlS5pwH79U8/3N3KrmBqZwvjwqNzxytY68qUSRqQKAVSqRdRrZfUsvHP+Mu49fAhTgxwZkEY2lUIkEJSix7/56/+o8QHffPY30GJY1uZo5xY2C3nh3hyxRct937Hb8NC99+Ff/Omf4XMPPogj+/aYNKfTcGVo5Y08e/P9M3jz7EWUWx2sry1oA8P+ILYqeYykBnF9fRl7J2cxv7mMsZFZHdZgMI7RgQHkqw3MZALwsQDV6yEeDmJmapesCaVJmYpQRZJ5A/fjgSO7lYP98X/+U/zj3/g6OAKDlOtClUOCODeiJVZpq92Qigb7p+kdNOOj18Gvzp2WmuOte29BkJ4sZLO6K9WqoMbDs7tQKOXw4Y2rEmSenRxWiGPwqFlj5hJqLOu2EOp15GkFbWs4jZOsCUYxNDSKYDiJTptDJy00sozNJwVCjlneMzmjWeK8yK+c/qm8LT0QDzXngi9v3LBWBivY6DIr7FQh1AlRO71kMXtVDreUTXK0DM+cQKDomkqsTQrWkt2b/SdUVdxaL6HZ8ETjgEgsiJHRtFlyCjO0Azg4eQuiobhyWbEX+J+rV3hMYJFG2OLbriMebAqJHBoax/DIuIQ76GXW1laxukJAI6v2BptP0lVdJhZPIhQJq25CUTuvNOEBwF6oIA//red+r8/bGouFdLC281tG/eVsjW5XyXs0EhSqQLf5ixO/wsHZcVU8xWIi4hAKIRVP4sbKDQwkk3j6gUc1Y3wom1IszU3jraUmLy0Mk6QOQtKhuufOWx3VwwpZEo8QVbqH+dUN/PkLb6DRaUrgbTtvs8YJ/9Fuhf20gnWhOssryxgdnkSt2UIqOYwEylgtNbBnIKxLRch4bGQKmUQa40MDGsLZ67clJE0OEMcSF8oVTak6dfk8RgdGNAqarE6TZW1ZXUQkO8PYSd1gMsu4l8W8F958Aftm9+HWg7dJaobTctUC2+1h1/gEEtEIWs0qLi0uKJzLxDlsx7hfYeZpVPfo0CPxcHIoUEQjriXjo/qP8cG4frFYVGEep++yoMhDwnDJhlWy/tTGnUceEEU+X+3gp7/6jpvLshNpuT844WrHn1Nbq3hYrguMuQChWUWYVlDjBZAmlYpqNr9+R91mp/Xaa5AzEISC1BTgqFc4p6UnATdO4PWHXG3CwcHDyXGMZ+YQC8edZXczYpz3MMo++V0c15fnMG4MJqPyZiODE5ienkMikdKhb9RquHjpqtYgkUgoBeNgHE69HcgOIJVMi/2dy2+bQINyNEeJcpfb98VHv9jnolsfsX2RHXyRYBBXF29gz9xuVDUYsSH1hwvXr+HY4UPC7uv1qtxWR4NYjEfFUIr8GOLzkUhcMTd7MJ48fi+OHtonuZvLC2s4dfkabizdwD/41u8ZCfkj5D+GF3zNP/3Rj/HL99+zxEpCys6y0Z0zHFA8TVw+hGg8g0Qii1KphOHhSYyFa9io9zGRYEcbEI6nJOtyz6FZZFMJXFlaxQ9eeQ3FCmV12IJpISDZAeQSqYimcdXUrjXFdY4pULENXXXAhSNh67Lr9HSJ3z71piggVBWkNQ5zjLA/gGotj/tuOYpweBD5KpXJyyhK9pKv01OIJy4VRcyyo2rAqlTKaHRaWFhbkQaZnyFjv6dQhHMD4/EkhgayKJZy8Pc7iET42YgUMaRlONTBwV1HpHZYqvnwwomfo1jfdLUqFzo5Jq9YA66DUoxgd1iNbmNMX6+fwgiDruDo+Fc7LGI3t0WaaaKzdxViG1rkxUemz+whh1pnR/WxGqMfcf8Ibpk6pCIuQyz7HuY9BHBodBiBklZU17SydDSkHJbUE6q8D2ZHMDgwrCm6DO/Pnj1rYEc0IQiYRqhWKUt+KZ3Oysjn8nnlusYKsH4fFY+/8MizfSJMrGISeotRoS4aFT5Py5aIJw1r77Zx7sY8FtdWMDUyKK+xkVvHYHZY7Z+cb9hqch5dXVaVybImtrYauP/oUTx2/D4pD569No93z55CqVwSQvat3/4dfd+O2rcb4vPXL72Cs1cuY3F1SY0sPBiVUh6pZFaHK5MdQq1aQjo1IBoF+5yTsTR8oRh8/RZ2ZQJYLlQwmUmq12B8YjcOTo9j79QoFte38MLbv1KPBUXZYuGYc7M224O/6S1jsbgsNteFSCVDJYY8lXoJ6WhUlJbp8Tl5CeL1Zy6ewvDgMG4/eFQh5fWFS4p/04kYnrz3YXywuI1CsagQgHAnr1o2GcBd+8eRSMRQrvsQjGSQ215HrV7GdiFv8jUMBcNk+JJ5YGPyOBaOVnhieFAHcXwwLaNET0ZrysT2ytVrKnRWW34UShXU2g2nCkbIwCreFOHzRiJw4GkkzOcNQiVS5etOEop9N46qYhpldqk0hFSoirG96WVNmJyWvoMLS2exmLthF80hWtb153r6HbvN6PT2flTcmhs4iIH4sOsh8XQDPjJar8ex2y1V4mu1ElLRCEYHUojRaPUDSCYHMDQ4Ik/B87uyuoq1tXVJ0pJBzgvGdlsK8KVTHBIb1Wz4SpXTcW2khrpO/9Hzf79P+JHepViuYGM7JxdOq8iqJW+biGx+P5a3VqV8zgorBzPygcqq1mbh79mIrXy1oh4PhkJEMe4/ehh3HtwnOPfEmYu4QVXyyx8gncggHo7gd3/zNxXLis2vwlUAp85ewP/zox+KlnL1xjUV0diiyhxIrrNew/DQOPKFLQwNT6LTrmuK69jQEPLlBiayCWSjXVQbHTUYTU/tluTl0X0zkp95+cQpLLDoFo5pM5mg8llJGmo2qDLZEyeKcxnz5S0rsKn3HsLsaamiwSCy6SwO7b1DoYaGWhZyqDdqSCSSCs0yiSCiIb9gyKce+CR+9qv3LTzheOJOF61WA4PpFA7uGlGnIEdsh6NJFEsF5HU5mroUYiw4HQAaFUKUFKdLpZII+/s4OD1qSvFSeiQEa4qPm5sbaDfaKNZbWNnM4fX3X5ehoee1VmTrD5F/8tqIXYhmvC7Xu+9kmBwY7nrZdziuBsESsep2VZd5+K77lZfxCwsbC/j5yR/rsoi6Ivher2yX1UnQCg0TQdAUWiL+KIbjsxhKWR2LXsSQQ5YWXA1jh7ZSRb64jfFsAsOZtNWEOhA/LpXKaLxgNBLW3p87d05rnU5ndAmYQnTbHRkbGh0Sctm4Vi7VVAPy/S/f+Id9JkjkNl26cUk0EBaNxLVx8wM7vTbarIT2e9JapXo36cYseHVbXQwMDmpWNd9kaX0ZV+evIZNK4NP3P4TbD+6XFfzg8nVcW1rCteUb2iTmInSXf/DN/0ZJlKu94eLla3jrvfdwfmML/k4bqxtrSGUzKG3n9Z6kvXAgDi1/vV5XssrR0dn0KCK9CtqBDJL+OoaTUSXiM1N7MDUxjcNzlgN8cPkG3vzgFCKREK4uMlmua3N5cKcndmFqdFLtsJRdjcfjItERpDjxwWsolQsynQxfiBoxt0qnBpWMW4cDSYot5LY3MTY4iN969td1EDaLOXz3pz9FJjOm14iE48orGAsTJKDl5uHhumgmJEMcMpddfYJf85qYrKvBPC5DP+YCmvJLOSM3ftpLvFkg5MFkTkFqDek94iYFSBUJKESkhzTpWYuC+BqcBSMpBJVH2BIVEMHPq/+IHSxPbwdVdSQfxKSmVM6Dd9yPbDKLvo85lg8vnXgB55bPONoQK9YdCWNY4dqJ7Xkj4JTqGFIW7CdwcOyWHcEGI+FbGsADY4AGZ8w3BOmXqyVJO1F3S6/ggId0KotsZlBGm15vZWVVF4DiDDTOzDHbrYaAAurx8pxxPZj/+X7/ud/sbxUqin/Z/82RzIQupYjhJF8Ym0eCLCjZxFombYzFOV/OHwjLojY1qgvotljNDePI3Ax2zcyi0epiaW0N11dWNQbaVDCoH0upmgDuPXYctWbbTdNt4sbCPEq1sjhZbc1sN6oLi2le4kU4l/MwuCGs2tIiszI/FI+g1gkiEeiC+ui8dNPjU6InJGIhNJttvPL++1jLrYnHtLo+r5HBojr7gpiZ2I3B7KjzmAxToPyEB/TyjQ/FJhjMZJFNp2SFpkYnEA0HcP7aJc2n4IqxgYeI4JEDh7BrardmYnAt//z738bU2D6srK+oYMgPR8MBdFAsb1ktg5XfdktrrLBux1Ja/wWfU12aO70p1pPDQ+j1uOtyuNnrSiFcj4eEJXxh1S9YYBNLl3vJuJ7KM67eRPiXBUfmRB5bW/iVQg5TfCE6xRzLVE5YPzI5HYYnfN0Hj94r3TINcvVzgGoD/+XlbyPfzEnEXMm95IOsJsObSfPCEM7KTd5sSh9G4qOYyu41r6MHcpfE9X+IzkMlRYZbzIubVUwOZjHMmSA0xI41EYkmkEymwcvCeZX5QgGrqyvKE7ln/BACYzoGOmiaMZG0f/CV3+tzpG8qwdZGQ5KEWnDehEtYPPH2hfV1zI5OoNYyLN1gOOvyMogWyKSiOHbLfiwvrWBueka1EvZWs11SlobsUI3wY2jDhKmD6yvLmJuYQJSXkNZTnWicgW4JHheGVpuWkgu4vLaByfFpFcqsiZ+9Bq6Zn1sopUQyXRuIhoNIRK33eqNQwbd/8j3ce+h2FCrb0mpVvtinwgbHO/iRiWcUbnmVY1rOWq2iNuBd05NaXNZDCEjkyxVNyF3PbWArv67aAes/gwND4mKpC4BFM8Ljp9/BQGYEK6tLOoC8oB69e2XzulXp1cjDOYCGJN2ESm8yjbzWX6+yrD1wHlAH2lWd7b0VjBiMG/Sr9qFpxQGib9ZAxfzTcf1cZ6UVCuV5vB51inZrlEFfSKQEGJzEu9UmGDr50Wi0sF2s4KkHnkAkwPHZNlCHodHy1gr+8pW/0BAjtQe7S+Jxn0TFF/nVqPREFokskY6SCU9jMDqs0N+bQmWNc0aTUdsBOXCtliB40lbmRkdUx2I4yoJyvdMUTy0ZTys0jsXj6LRa2Fjf0Lg+nk9V74kA0nD1Yeruf/Tlr/d5c0YGBgVxJmMxJS4mRG0WgsNH+OFPXriA0WHOyw5jZnRUuQgtpA2F6eCdc2cwv7Jht7lWUr8DrQITfzJqbcvsPzX7q0uxh2KloPpJKp61qq6boccYPeij/ArDMSrekeRYUbslqc2hUFxq4XxdDqNhfsADwIPABIyHu1jYQCY5iG6niXw5h4fvvBfTI6OWKItQRy8IXF9dFmo3NTKJMTbpcDCMJv92JSzBTTNx5Dq2S9sCGC4vLWNyeEAFVnb7EXJmLkYWAENMDf/p97G6ncPCxgpmR/cr/GJIyU3gJq/lNmw4ZZ8VX+szUahjFFonV2N0HlNYcb/cnTHdMguT+HVabUOeLETipSHCpSE+LqRgAY8sWY04cO3GfFUVzFS4tHcxD2LNdGKKC+lyREYhj67JyhlKQsuFShWH99yOZCSLSDQlo8dRD9zz1z74JU7Pvy+pIZdIOHDrIwqcovy4CQFsjhLCCkyn9iof0WY5CNZDMWWgmdf12g5er8v4zY2NIhmJKQHnI9XqNcQTMaSSgwJ7UsmEzsvWZg657W3116snxhknUZ4eueexvkrxIVZSqUlrs6y9/nJh/a7PuNVlSEAXHdL38f9y8a5dlaiCp9JI7o+f1knkBePO0GrR5ZoggrlM3n6+Lt0t6xXevEGP1uH1r/BHGC+aWEVAyEM4FEM8nkJKxaCYGKLcQB6+Wp3N/SzqtYR9M2lsMVxyBTcJAbDmIBjSoFGGN6JzM8ZlostY2Q2jJNTMIqJUwht1hXvXNy6iVCNbNCBEi/0yrBeFpalkoAOFBziRaTI7gNmRI5hfXUY8Rm+qETmaCdLgHPlOC2ubVzWGQXUVzgMkdZ1z1P1QWGbz6XV9TKBB1tNqR+VaQxciHosor6k2O+j12irMPnzfYxgfmdQMEl5aeUjNUNcm2GF1HXW2MU6EwY7vTu+LMbdvKrxL/zZg0KuNyeiiXq9h4cYV7J09IhHARDyDZDSGWDyKQmkL33vrO6i2SX609/RE4LzeJfN69rnU0t03ik0ymMFMZq/OHOtQJnToWovV0GbelyES95o6V/z/+EAWmWRC59vuOn8mJMMaTySRSiTFiaPRXV1dQ6VcVZPezmSxT338s0rPeDA95QprFrJQx2JEQxAk0e+0dI0xaUffI7HpL07QQB1nzs2zyqxeYVkamxolmNHJrnxUFkjL45RPxMMhrybGwx9WopXJDlr7RoiFJiqFW1/E0tKS64vooVwuyKLQcupBJadvjGQiYWoZdvuuJiw3TMYYFt5EVlfZ18GxfxOVgtg+9a06dVxcPanLyEMyPb4fe6YO4P1zv1TibyMMaFwCKmge2XUUxSrj9LIdSkY9gRDi8YRCMC7KhctvKmEnMCADxcKfNKiIskWcnKs1HGmpVTRrKxxazVURD/sxkIrKW1fbPWxyKm48iicffAq3f+xuJaFqaJIx4nY66RxBvk6GUIiUeS9rb3bWnqGvyz+Y2Gs2SLeLC5cvY/fcjPW+uDzh1Vd/pByk3fQhGskolEzHKdgXweunX8d7N06YwqELjwxUcAosXi+9+GRM5I1fxnA/ExnFYGwM0WDUxBtopGWMeopabGaIuTvucaVe1l7snZ4SQBMjszkcQrPREkN5ZmoG0Ugc0VhCv3mBCvk8trbyIjwyz/J9+uOfEV5HV+Y6eC1+ltqiFeJUqGFYpA61m8MdLf51WZaLfbmxRFfojXiY2J7Jh/E6EM1SeXq3N6mgfDBae7OMVEIx6NWSM8PsLSGzZp5AKIzR0SnN9yCaxcJaKpWS8JeQKSIv7Y4wbx4wEur4bpbbdHQABEWHwtguGqHS2lhtZqInqi0KjPRljf/Dy9jtdLBRWcb8xkWtB3Mpq5ibxzGNWE+0zFo5E+EsBuOTxm1SAYy5jHHURsf2oefr4Z33/w4BvzM8pocjzhjXQDPsNW7BRu1Q1Z4HjM+VK1QFGyfCfiTiEam3pEC1AAAft0lEQVRHNtpsxCojHg3ivmMP4v57H1NuqbHUXhHMoVRex6DntQ0B2jHkO3+2C8KaWB+FfEkX7PTZk5osvH/fAUU/9HbLKzdw6tRruOPIcayubSOZGJBwQzoZlyH+7ms/wPXNS67WYCCDOh0doOBFkTuCfX0bYc31j/uGMMK24wgr4xaCGQLqpgsINu44kmtLRW4OhlW4JUNrQhnieYVCuiCkHvESMxphfsgBpLkcRQxb8D19/9N9olBq8LHWs53md3tTZ+ndOGFyinamS7mJqEZHZjjwEQq002ISL0dfdrMHDcVzEKYhYQwxGqSPuAYsfh5af8b2OzL1zpJ5l9WqqaaFxAOs274zgIWvf5OVSlTCAAhvtJeFPzIERJPkUZzgtou5xVD19JRc1xxX1ZRcuri8fgH5ysrOUBlVEp2oi3fg5KScp0pFBzGV2StSI8M0xr6mvOHH3r13iPX7i3e+j16/JRqMntMAf2egbj6P1SPk13SJVHfzhOxI71YxmMTEngp/+3cfwpOP/ZqsJ9+PPRZV0utHxpzUqlH4bW1vBlXuiojNK68OoNXoodv0q35Ag7CwMq+hNIf2HVYjG4ePBkJtvPyL76vSn45xwpfpWyWjxrDlTMy//OVfoNltulqI5V48GBr+KvlWHmKnSuao7j4qWLaBseQ0hhNDAhi0r6qAm6rJTqToxjuTL1epc3alH7snxo0F3u0jFooqUddQK4am8aQQLYa3bLLjs3Iise/pBz7bZ8xNq++FPHwIIQZO/c6chBcv2uB5CTA7ujYvCC3rRzWIlPQ5pXVTmHDK3Dwx7hDydVkl5xATzu6gx0olUrLs5oGcJLQH8XkmzmMtqLfcwjANjNxhZDJssmTTGzPNMMir1ssbMFRUH3dAh96TyuQBinHATSImNjALgNTsqtQ5Pti8hC/Yw8lrb6PbY8ecJcO2v26DhBy5bkttSBe8IHNDBy00kiFy+USvh9tvvQ/zq9fxpjyIMVD11R2lQtfrrbjdTUB1RTarQRDaNePG6Id7SS/stZMOZofwxc/9rqBwWv1atYqN1SXsP3jYsXm5l85bMxF3crIWxgkrtoCOgMPqKlYXlzEwMCbOE8OtYnFbyocMN4uFHI7dfScWFy7hxDsv4Ojhe9HvR9X+zNzI4S84eeV9vHr2l4ayuTmXikhU47BWBoNozVhYzuJCU18Yk8ndGthKWjufn15PcDP3laOnDWK1Ds92S3B9LBzA3PioXpdQejbDBrCAanhETPk8bNsWpT8c1Wv7nvnE5/vcEGmqMtTy+hI+IuxlMalBwF5S50n2CNd2qtnSXLKRn66t006swZb2oPZVM6vcRCZ1bOmUAJgIeybXopmIbsCJCQi4e+Uwc76CxkjTe5BV6sn9k0zIA0a6hZs5IupAMKBkUhi7VDvslnkUIdUBVKTzYXQwjUSUraD0lj1sFIooVdmbb1ywa+uXsVVddOMc6IkYDzt8zgkg6DK6nIY1n3R0CHtGbnHvacmlhW19fOKeB3Fx/hLeOPkzpJK2Dl6YYzm0QxQVp/Pi2BrSElqI+9Gim0285bfUW11p3RJtfPbzv48YC2WUfC0WcfX6edx17AGL/b0cXd7dqtsWJNrl38gVBZXH4hEsLd3ACy9/D+FgDAHmAhp7wWfhKLsGIrEovvKl39El+9lP/rMS9JHsLJIkkMZTQvi4MWRo/PWrf4GN4pohZt6cdvWq2MWQwiXLDrw0O4ieWaNkMItMaEQ0J+21y4UZRqp9VroDbC+2+hERSaqpUFxy7/Ss9MAIpvBCeFR98v+YewRCEYVdRCp9zz32rLX0ezIyIrzZoosGvCP85g64wijHs3d6sEzWSYvwvIwkLrW4DG0saeICsHpL1IivIAiSvH+nZMjXlCixpwPrpCp1EJzSCA+c8hnh5RZnmiiAwZqKSYnv+4KOC2biZN7cDCa0fB8WQuVRpPzB12GuZPPFzfOZsJhFOKZ0bqie0azfvvQWAkGS5ozxKvyB6JAKPGZ1vZ4FKyX0kYoMYM/wLa5/wvI7hXC9Ph6770GcvHQaJz78JbLJpCE1bo6IGSdLYNVXw5qDelOsTqSD5eoHntA06epqcOoylNNYYTz72W+KxKmQst3GmbOncfsdd4t3Zbq8TuvKjdYjf80q531s5UqaJ+/lCtv5Ddy4cU71hsI2i649DKr9YRhzcwfsffpAPreCl1/8K9x9+8OolOqYmz2ELpFCd+FXc2v4q1f+1KFztv9mGJ0gtdPa8iSXBKKopGMjFYLdOKYGZxEO0NpTMohfo6E3YquU9h0NhuvF3LTSKEsQe8/4uCYchwjhIyBmBnMOU4JsA34Wo6PwffXJL/VZ/MkVOJjG4F6LZ4MIR0M6TLoujkJNWnsiElGiqcqnDmpXlXbefL2Rm4HNIiATZV4YfvAdrSLSz5stHUgnVSRVO14gD+vXjAvRGEwOxpVYdUHYQdgULZydYTaeQGGWcg1zw+qQc7wiHi5+Vn4PQ0GR/4IcHGnTfY2MSeqGgRNWzCXEaKqDEjTjM3X7qLWquL5+FcGgXXpFIKR0EIkS2kc5a9PLUu9KKIZGs4JkJI3JzJxQNFpPWnWBIH0fbj/0MQlXXFs6p8q8lxXb1ChrLRWq5MIdelwLI9zoM4ajrC6YyzUyihVTTKneD3z8nsdwaB+VYszzvvj6W7jztqNSPaGggRyqads4npStl9VjPtKWyn/lnXOX8+yZt7B79yHEk1mL7xy8bdyVLl577UeI+AOYGturXITIIxWrWYfhE71x5g28d+UdIWy2c57GriM3OkDHEna7QCw7qBDc7SMbHcVgfBjhIGsdrPjTENOLuG7EHVk7g6F5caj2MpRMYNfEuHIj7gf3jdVzvo9aFRpNXXzfo3c92qdV4i+OBeMEIzEZu2R2hhVWUYpmq1hQ0jw5MqbCHxeNogCkEbATbiBNindIH44Hjxu7XSrZbZdUpFHDjQbOiq6FPDxYCsmkccTPYImkffCOFXfYu00L0e8JYSCBj6GcPIoq72SkhnRRaR2pZiH+EvpiFzOs42UhjT0VtxgzHo0IGtwuFXUIOD1W4EDIBtPzsMnbkVEQZJ7i+qUdJEqaiCfEzZ4Ssn9Zc6AnYw7Az2GVbTt8DPv4+jQ4ZASzX4aHzBMW4LFmjUiv64xJqVq293aSO6yxqF+E5EgpwVP9wybASizN50OpVlUvCA2dBWdM1MNIJ9MYyFLtxA6eKP4B0nVY0Q8iHCYx1UAWejAepBbVTNhzEolqHSlsl4rFkYhb56mBM2QssIvRipnqIxf8yjqZXx2UVy5/iMnR3cbyddEDX5MDPsnn2yyvyDN6nDBbL+vGNFFqkxH1YFyRQ1nE7XcQ9EdlfDgBmeEVIXivO1CGnVJAYRYqTSWeXxRkz7A3TtWbqPJpGiGikbzkXGMZABqw+48e73NhKcfPD80DxEtCK8RvvLa8gHqrhaHUgGZH8xDw79FQRBvBuW9DAwNIxhO4wkYgFg7p4ojnU99JYY8tPukcE8ND1kyvrrM+UlHOf/CpCKcD6rSYuEmVSk2vI11ZFwLyAiV4EAkLN7lIHL1cl4YVX5Obx0MoHaRQGOVaRTUQb/AjLyVn0zXa1n+9lV9DNBRDJpFASYPmrROOk634vjzswwODutD1Bi+mG/PQYS8HoVZTBqGyIfMoEiTpnbjhhTJrHn4xClR7YdNZo4FasyY3TziWB488MyaS06PjKFfYsw2xFxhbsxItgXBAa841ZKGRwmtknZJLxmCoodZfA0pooDhGmfws9Vb3gYnhYbsIkhyyGgY/PMMKFlT5i9w2NpypVdhdRvXhSMqoLUCF1ZBEPLFDI+GFLlaplFjRYeZ7so5jc8+5jiUUqC08OKpaFntceOnEUVOLrjMkDCldNyXXhe9vyKo5VF4YKe+w+s+D3qOBbhpZ0gFG3HOuE9eTbA/+u4ilar8gatjTfBbz3BSnqxs5M8jio4X33jnkqGrV+Y7fen+fVpIKf7wxdLkMo8rVChaolRUIYDjDfvWkblUsEgd72FlJD4ZZQ8grzOJl4QemtyClgYedC0R0SfKZglR6SCdTmj1Or0B2MO08Ey0+HPlN9BoMediIJXSMTVJuZgOtE5PBcr2KKkdnsZbBzWChqN2UxGUqkVEzExGJVCIt/L2Ptg4u8w1uqOQpg0zEori+cEWuWszYbssKgZ2ODiE/B9tx+X5E1kg5oTIGN0hjAShZ02oiGUsgETNYmnE/UTk+o/WGd1TlL1aqspZe89AQO9oSSbUjVxvsaajh0Nwu4fEkjbIVlPQd/hpIZ4Xhs8fGo3uY/har5Qwb2jpo2WRaVrdQLqBC2hBF47o9VKs1hcgjQyyyslXWIgP1mPQ4RZgTlupK/pPhqN6Tl2Jze9tB6dZzTr4SD5WmiwUplVpVAkweHY3p8vqq9pEHmWtvUUZD2lrch8mRKR1ClgrqLZtfqJ5z5oVOUkm94zIc7Pe32hPXlkaX/8Z95Ncp3s11lUpjlXUgrrONTmNIHYvGZejoyQniKCxT7G2Xk/uyndvQmSc7nZfIQ2U9yg3Piu9Txz/Zt0KexfEmEdNGpVaWpRjODOkmcQHs67R2Hj07KjSAG5or5PXh6H3EgoRffCg+IK1xOpnUA3Fj6NrS8ZQWz1OgsHc3HVi+Hi0BF5tunhNIDUbu6oAzjOABlBfipUilZAV462NxVkSpYt4xAWM3osA0bF1i73qn6Y3o1nl3ufHscTGOGKkdEblsFiG3iwWN5qKH4PPlS0X1s3ADuGE0KsxR1ArKzkDmDUG/3o8bwcVnGEitKh5mhompeEpeIhyNitIv+nkoKgtMHhE9hXVQ0jNFdAllDEhzDwblRSUQzrCs2cTa5rpZXCbhzbqMCteKFW6K1dUaLY0xY0jhzW3h1C7mXkRvRD4UXb+NTDqlz04aealS1jMOprN6DnobDU5SzYm5KscpdDEyNCR6D0fMsUA5qmalLNqSIcop0hjJDsqTkJxEgy35IcGyJkQtJKzD0D4kXp0EH2QU3Sx2jfJuKKdlXkodLW4wjQv7cKSUkhkAybfab7EmrEBMo8A9oBYAOVbKZXkJ5XVN8JAtHzSUFKOTVgDP5BP3PC5dLN4wxuRruU1Zi+mxMVVvKeSVYrysi9EWP8kSXFouxnsW0zEm5IeJs3TPpNoHtejq4PS7ekMWYbjAbB8dzg7KpfIbldi6ZJmvR0UMJujJaFwaSmyG4QEhDZ4PzdwnpV6NBFptqgdmZPEZznB2SK6Qk3vl+1kYWFIPNzeJMTcPIyNbMnPpuqt03aYaq7jctVrL0snLiV5jAg+8xLT49IBGCzd2qokm9ITmSQDapfssytEreAbI5s1zOAzl+33yqGs5ji8gQmZUdG4Qv58HnqqRXB96cdIueAB9TCj5PS7G5kVmT0y+WDDFkjDDwmG0ajV5d853XMtRVbFvlPqO5RYCWTQNzI9kMqU+laW1JYXStNA0AApJvDqEIw9yb0ulsp6RQnODA1nki2UNQeJe85LxMtPyM9zh4VtbX9U6HZjdo3xieDCtQh9lYCmeYJbMCrg8CzIkzOPIVA5aAh0NGIDEC86wPF+h+HUA8QgH67BlIyAvzrVkZMa1Z1TD76HBkhgGfFJb5IVMpOLysB6qKf23NlVlLHfU/n/hE5/qK96naEGJiuMRTI9P6yZVG1UTjW63tBBG4DL9XX54Wm2GNrR6TMrIdKV1FILUp25RWHH3YDajD+E9sMS/GKI5d8iHZ7ig2Jjjr+p1/Tw9jGoTElM2dIUHmtV3PiAJixyNnCatOhhAuVYXXi/hCXozXhzKvBRyuqiMsbnp9EyCnUlBUcJKYYaWiUnImgWFylEFRJ2VmlvBZyYVhm67pWezS2J5CEMxXTzCj6EQcsW862V3fCZByhZyMURgATMlBQ5Iskg0GkHKfQxQmKLZQKluIQUtKsMAKpWQ9cwQgLymGGN1N2WJ3nVxZUn0fjEjwlHJ/pClmkzGEYsRBjUQgGtMg6V2XjcHhGvB5ydgtprb1DhnL59T3cXnk76A9oUGjH3+kbDyKSGYYlwzjwxor2nEuE98n0x6QMbkg4vnlYPOTcwob+HMeE8BhV7EY1jwnDHs85RNeNGkGi+rY5pfLOKp552gRddQPXlvtks3SW0nVy9qYAvXXYIW1pJhaBYNpY1yU87cNrCIe8Dz4HEPfY8f+0RfE3kCEcnhswedP+jK6mi1m7KKhjCYkBszh1qDiu0JMR8Jt4pp65ixRLDo9vmGrN7yw0rKx80Gs3zEJ4TKqCgMRywBVoXb6R7RKjC0UejAYmI4qkXjZaIXo4eQJxNcbBwxejFumPpHJMNv1Hc+Iw8mL7EVRilOYVOQ6P0qVWOYMs7nZjMJTsfjQkCYnLJbks9FVy2sXlOTrLvNLrBdIibdPTW/Bqz1tl6Xpab30fwTb7g9IXVnWGhRK3VDn7xaEC8x142HnD/DMJVrz9BCdZV4QqocTOSZDxLMWF5bEa1CHZJ+hoek8vO543pmu8CeAjuVT6jnxSjAL9CAr0sImWouTGL57FwfIpEW9vpkENQspQihhkK5qDPCsI+fTSrvTn6OSCgJpnwWPjs9L+Vgh2i42N7a60v9kvvJQ03jpVqI6jcs4nGalQlUs07l1a3E7GarRcvCJ/4yqNboJjTSOhMO8hVfS6LqjkfYNfSM604DxfyNa62EPRTWeSfIorTi+JF7+kySJ8emXExrlppVcYHoGjVg1kB925rgSmkep4ASZjhgcqHbpQIyiZQLnRhjdiXeTHq42jj7pLAwnOopjIqGwkJmyvUKKoRjRfYjumU6ULxcJpBsi8ADJRoArbYjp0kEWl14RCqC0q1SLhYIoNZsirKhUI5zJCRCxmdjjGo1A1o75lrcbE2F1bAZVUeRTMRNPwvG2+JB4PuzeYpGxOspocaSCUKbBq3378wvvM2it5TndYgQAQ/G90St5qam9X38cclwgg08UdVIaOV5wUjCpPtnWMnQhF6CzxMP2xRYikbwGWgZaXEZEVDbjHs5NsSeGVbW6/J6UfXg0/u3JbS2kt9UDWd2fAL50jYKzLFSaaF7yXhMobIJO7NizosTlvhdo1VDmo1G6Ot7sum0PhcPKveRf2a1mq6B60wjytenxyXowSYsKm+2Wob80QjtUJpI6JRXo+JLx2tI0Xp4Ro4HmfWwTDxlvfbKlV1jnRvHzTVtybuH9CxeTYtDd2iQ+DnIABBgEKaEE0EKGwgkLsGXHvliP5FMGRWEF6Nr3H4VTHggQiSmsa7hoepU1wvpg9lkHqd+51ishvdz8Ivd4g5vc5+UB5MGVc0jRDUMS3CZNKk0pze18IYJM9EoxsHqwWBLreomLZEYFT6o68uk95VQCYdn+NUSmsFjpjoG8yIlt3bRlIyS0asOtCZKtYpQO2MLA4koCWxWUOJlYZ8GV4PWxIp29E59HTQeRs1c7zCsMlfNZxchUEXMoOJgtQpTgIF1nRrDR8bQJp/D8CASYg2GShwZlErWU6KEv9NBlGgfkZdOW2IVRGfkqUW8hOBMFtmKlbK1yfpZ7I04Gk7XadASGg3qEvJQ87lGB4a1dwRcmFxr3nmHyBnDaYpFdBAkF0nVw46MCKFhMjhoBEQilYIJQ2NvXDS7Wazwyj4YUvlpJOlVue5i0vZ62NzeVM44NDCoNeX+MlTnYVZxmUhmwCB/77IpHOTX29ZKbXw2KqMwbyC6GjGxa9aAGPo1WtrfnWGWMGF1ETKdOATPOKMHKm8ypCUIQwEHGlzuBwEZ3zc+87zYOKSNa1a663FmiMLjTHhOE0ClhmkZPz84F6vRbugg8MEIgZoFNbqW9JBYyfbxgpkiCReVIQ8fmnEhcwJaOV5E/iAXkK6eL6Ouu3bXki4nwmw6GFQODKPOsQyuI06S/OqhZvzLmSPmpaxtVVdSvxkH8xctiajrRJU0Qy8ib8NLRu/AyyvImngLE26R6YzYSIyeYQ0vrkAKV4VXbzer5yJoGlZPGDSToGwSXTkxebbTsqXUkBlaPI8uI4xeSieWVErMgR/SMQIkTtA0ETsZAB8vb0fKMISDGY7yQjLJTzF8Yazu4nL+n0ABDU+1UdEBJoLGw8hOTL4NLSy/zvXyGuE6fV5oDvJhaGWAB1+X+SjDNeZFXCcJOrjeEcLyuiDsYpRXt+lPEqFwiBzDKmoOjw0NYyAzYEhVv6/14pbxMsjbu5mWan+W97LWBuWIKlZ7vSrWaqw2BvfL0gHr3REowc+UIBhlk3F5MVgxpxflZaVzUA1ExFvXYkDC7leeeK5PxEddZDpIpsuqSqYKN46f5GcVmImTqWIwfqNF54uqP0ExXBDlclVjCvh9pMNIVC7IekJjh6DIMIeHksdd48PIMG3UlXTSyhEpIwoiIWqnoCGLTmhRLFcuItthe7L4pC8wT+DBU13A1TvYe81Qjh6EdQUdum5fzfvNThMx10Wpn6XgQsw8ExNzxsvpRFwLxwtutZOQDj6vHDeTHoQqgfwl0l/AJ7RNGLxEAAwa9yY4iU8lGVErwioUdFVzITfkV7W7slzemDNeYB0QymayUMdLJZoHe1c6goZ5OPjczAFULPNzfSyXcNIhiEYSUj4pl4oqHtKg8XLSgys5V5HNRsdx7ymkRt3j4YEBWXm9t8+PhNpXrWeH4zGEKnW5tkSYeOGpvm6Cex/l8zGh597qs/r6WN9c14EfGxpx4g1ivimn4Fmgzq7XNciLIIOkqMRqXsYMJgOAoxc0EE+fwZttQgPJw29cvK4ZJ59V+D3lSSuoGmNEoRl/pknDaLQl9uz4nnvomT5V1j1ujxIeIi26+eb6IoEwEjEOqqkZiU5UeJ+643jjGLcxdTdtV6OgpFMJq4KyDlKvWQ6gBMzmC3JxCNXRKpqShkkNUQiMHogHSZbQKd7wkIh24hAvhgWEeqmawn8TsdLRHWg1aAX5miVOKXID7A2J6ijBpUuVGgtdN3V7Y1FZa14GzVl0eRUPHkei0esx8aWJY3LLC8qDykTSgAUeNiJhUb0vv8ZnEKHRU4MRdcKFnSLsWV7FMIwHjT/L9zdmAw2MzQpUQ5bkbRiqGLGUxkI909xwX0CNYURfTIzaEnC+Ji+gQlAS+Zxn5R57pEBDbEyNha9nCic2pJTvR7E83jiGoWRR8P1FBNRoARcGkVclQY2+1lekTkoRCdqnYbEcUAednZ2dDkrVCrYKWxhMZZBJOqEMB6nzoHpUGcLc3Ffr6bH+JOZifC6GVgzDPZIpjbLRXswIaZIwi72tlqGgYjKYYRWxU5rAgR2qjO1ZRyWNII0NHcHT936SwbAVVLhhhA2ljWRdeHRVnhoGL4jYyqwSk0fED92H6ghUnwj6OT3IEkt2tlHlQhpT7GUXpOsYwSwGRUj3aMpSif7AOYRCkUz3lYvP6rGEAYhdl0sKvSRO7QsogebFJO+KnyOqXmVSPijQzAJZTDwvFtyU1IWsEtyj1H7ImvzpOBlzazPE47KxA0oOIyGsb25oQflMrFdkkmkdQF5wbrAAXLEtDUWTl/MHMTg4pEo/P7vRZGyuu41nsFyA1p0XgDUmQpqy5PRo4jhZHK8QKBJzjF2uc80mRDlxBYWzomSYrizDHW4+jQPzKM0jYdjmPA7zFRo/gi4WiprkrBd60oPxYMsYOPEM0sZ5qI3dTKXNmCXKDYP3Ge7ZzA5LI7lvjOENLCAKZkwK0sgVAjkPynO1srmqz02DlUgQbHANYMpBWGyl2Bv7hExYW7mOPrMhTHx+hn667E6bS7PZWWB1LRNiiWtSs/2mwSqVK06PjOGkkUYZGgoQ8lvRmDmQhOo+9+Cn+zzw3BxafoVbPatO01t4XChaNOLwtLz8JcKacH2zOJaoOSRHcGAIN1aXdNkkn+LzIZM0jg4TKVoEizlZ+mcibygJ1e2MFWrJP923xvuKrGYuiRBsi2opEeLcpmroWTm2qBrpzq/Ykgkb0Z1Y1OBoQ4XMQ3oiEbx4y+vrFipGoqLH0Bqxgs5fDPl4SSkqJ6vtDfwUvs6Qzir/hvBEkUll5GFYcR9KZ3VwqaBRrlZ1GRmucNNp2XhgO9QFIwLEMJYWzLX9ypMwsVRuxaKZwXlW/bWL4oWg9BiM+3ngeBCZL8jzER3imALmQJo/yGTfCrF2aK3ORGicQmmknrCdl57NBOSYWJs35PdwLXhO+Dl5PqzmZR6H+0SKD/eE60IDws/Iw2siEQaE2EH0az3y5aJkmlgyoAeS8kowgKJyqpD2XeclZJaeF4RrYuorBDks7+M50WdigS8YNBCJQ4A6xtdj6EshQOtgtaK26l4dAkAsURjtxVOu4eeUoPXnH/psnzfcagPWXMKnIGzGS8OF5ybwh4vULWUVxPVNUETZ61dwInmCJAmJMlugDCkRAh4q4tx8OA2kZ+smK85SA4kJHuYC012ySUUkb2Lz8SiKpZJaN2mJSBbkBvOi+PtMtGh5qYVEBXpjEtOjMLFXjYEhQDSCQqmkP/MUMxciB0pMXBIdmw3rW9bMReP9EHlLJpMKMVRpZhIbDgshSyfJBjYhaX6Nn4HvnyCNRvJDpi/G7yF1Re9Lg5NMaA34RV5QHjITwzP0yzwHK+TGdLa7YHQOzcvghooaw6TTMYxdrzwNDa0d+XImvmz6uEqSg2Fddu+CcO9U/XfdlNIe5utyLTtNrY8gbNZciJCpkck8P0NXMhLIbJB+GrXIWKUWgucEIVx+SZhZ+SevAxu4yI9i3un6zunB2XhDeVQauJGhARkwkyQyYqHaqd3UW64dL4lV+K0NnIfaVGfssDPncG1ruiCaUEbIGY5yJDoWwRA2dxGBjOhM/f8D1WBgMdCdiuC1WqC1bZBFtwALhwIIOrhvswAAAABJRU5ErkJggg==","e":1}],"layers":[{"ddd":0,"ind":1,"ty":2,"nm":"img_0.png","cl":"png","refId":"image_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[81]},{"t":59}],"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[100,150,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":60,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/image_test.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/image_test.json deleted file mode 100644 index e60c9553..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/image_test.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.4.3","fr":60,"ip":0,"op":60,"w":800,"h":800,"nm":"test","ddd":0,"assets":[{"id":"image_0","w":200,"h":300,"u":"images/","p":"img_0.png","e":0}],"layers":[{"ddd":0,"ind":1,"ty":2,"nm":"img_0.png","cl":"png","refId":"image_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[56]},{"t":50}],"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[100,150,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[99,99,100],"e":[152,152,100]},{"t":50}],"ix":6}},"ao":0,"ip":0,"op":60,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/images/img_0.png b/presentation/src/main/cpp/third_party/rlottie/example/resource/images/img_0.png deleted file mode 100644 index 35ee257c..00000000 Binary files a/presentation/src/main/cpp/third_party/rlottie/example/resource/images/img_0.png and /dev/null differ diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/imprint.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/imprint.json deleted file mode 100644 index cf7c2f41..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/imprint.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.2.1","fr":24,"ip":0,"op":72,"w":320,"h":320,"nm":"preloader","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"check","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[20.5,20.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":48,"s":[{"i":[[0,0],[-2.667,-3.777],[-10.816,0],[0,18.02],[0,0]],"o":[[0,11.59],[5.826,8.251],[18.02,0],[0,0],[0,-3.948]],"v":[[-32.763,9.036],[-26.427,28.344],[0,41.799],[32.763,9.036],[32.763,-30.549]],"c":false}],"e":[{"i":[[0,0],[-3.336,-3.703],[-2.453,-8.306],[-11.95,19.02],[0,0]],"o":[[12.513,5.208],[6.552,7.274],[2.797,-12.556],[0,0],[0,-3.948]],"v":[[-32.763,-2.964],[-14.177,9.844],[-3.047,30.049],[12.451,-8.276],[37.388,-39.049]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":53,"s":[{"i":[[0,0],[-3.336,-3.703],[-2.453,-8.306],[-11.95,19.02],[0,0]],"o":[[12.513,5.208],[6.552,7.274],[2.797,-12.556],[0,0],[0,-3.948]],"v":[[-32.763,-2.964],[-14.177,9.844],[-3.047,30.049],[12.451,-8.276],[37.388,-39.049]],"c":false}],"e":[{"i":[[0,0],[-3.336,-3.703],[-5.953,-4.306],[-12.138,20.582],[-3.612,11.708]],"o":[[5.263,9.708],[6.552,7.274],[10.547,-8.556],[9.99,-16.941],[3.612,-11.708]],"v":[[-32.763,9.036],[-20.302,27.719],[-3.047,42.049],[23.138,8.161],[37.388,-27.049]],"c":false}]},{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"n":"0_1_0p333_0","t":58,"s":[{"i":[[0,0],[-3.336,-3.703],[-5.953,-4.306],[-12.138,20.582],[-3.612,11.708]],"o":[[5.263,9.708],[6.552,7.274],[10.547,-8.556],[9.99,-16.941],[3.612,-11.708]],"v":[[-32.763,9.036],[-20.302,27.719],[-3.047,42.049],[23.138,8.161],[37.388,-27.049]],"c":false}],"e":[{"i":[[0,0],[-3.336,-3.703],[-4.453,-5.306],[-9.638,15.832],[0,0]],"o":[[8.326,9.208],[6.552,7.274],[8.047,-13.056],[0,0],[0,-3.948]],"v":[[-32.763,-2.964],[-17.427,13.844],[-3.047,30.049],[18.263,-5.214],[37.388,-39.049]],"c":false}]},{"t":63}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":48,"s":[0.109999997008,0.109999997008,0.105999995213,1],"e":[0.713725507259,0.792156875134,0.282352954149,1]},{"t":53}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":48,"s":[4],"e":[8]},{"t":58}],"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[140,150.756],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"check ","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.307],"y":[1]},"o":{"x":[0.013],"y":[0.99]},"n":["0p307_1_0p013_0p99"],"t":0,"s":[100],"e":[0]},{"t":24}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.312],"y":[1]},"o":{"x":[0.294],"y":[0.878]},"n":["0p312_1_0p294_0p878"],"t":28,"s":[100],"e":[99.722]},{"i":{"x":[0.962],"y":[0.161]},"o":{"x":[0.75],"y":[0]},"n":["0p962_0p161_0p75_0"],"t":30,"s":[99.722],"e":[100]},{"t":48}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Обрезать контуры 2","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Обрезать контуры 3","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":72,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Кривые preloader","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[160,160,0],"ix":2},"a":{"a":0,"k":[140,140,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-5.442,0],[-1.701,-1.379]],"o":[[0,0],[0,-5.442],[2.347,0],[0,0]],"v":[[-8.053,8.917],[-8.053,0.979],[1.841,-8.916],[8.053,-6.709]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[138.158,129.583],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[5.442,0],[0,5.442]],"o":[[0,0],[0,5.442],[-5.442,0],[0,0]],"v":[[9.895,-14.386],[9.895,4.491],[0,14.386],[-9.895,4.491]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[140,144.947],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-5.088,0],[-1.541,-0.357]],"o":[[3.676,-3.002],[1.645,0],[0,0]],"v":[[-9.12,2.404],[4.331,-2.404],[9.12,-1.858]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[135.669,106.459],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 3","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-3.236],[0,0]],"o":[[1.304,2.754],[0,0],[0,0]],"v":[[-1.017,-9.027],[1.017,0.037],[1.017,9.027]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[160.312,125.348],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 4","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.72,-3.921]],"o":[[0,6.579],[0,0]],"v":[[3.869,-8.203],[-3.869,8.204]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[157.46,162.819],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 5","np":2,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[2.714,5.348]],"o":[[-5.895,-1.591],[0,0]],"v":[[6.757,5.505],[-6.757,-5.504]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[127.72,169.71],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 6","np":2,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[118.671,144.313],[118.671,125.385]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 7","np":2,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[107.237,135.045],[107.237,147.876]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 8","np":2,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-18.02,0],[-5.913,-8.655]],"o":[[0,-18.02],[11.213,0],[0,0]],"v":[[-29.916,16.382],[2.847,-16.382],[29.917,-2.018]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[137.153,103.826],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 10","np":2,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,4.519]],"o":[[-1.275,-4.114],[0,0]],"v":[[0.981,6.499],[-0.981,-6.499]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[96.784,171.468],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 11","np":2,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-12.185,7.891]],"o":[[0,0],[0,-15.517],[0,0]],"v":[[-10.145,29.214],[-10.145,7.911],[10.145,-29.214]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[105.947,107.12],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 12","np":2,"cix":2,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-2.212,0],[0,-24.309],[0,0]],"o":[[2.127,-0.318],[24.309,0],[0,0],[0,0]],"v":[[-25.356,-38.039],[-18.841,-38.521],[25.356,5.676],[25.356,38.521]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[158.841,109.355],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 13","np":2,"cix":2,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[24.308,0],[8.114,9.172]],"o":[[0,24.309],[-13.135,0],[0,0]],"v":[[38.645,-22.098],[-5.553,22.098],[-38.645,7.12]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[145.553,187.068],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 14","np":2,"cix":2,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.026,0.7]],"o":[[0,0],[0,-0.707],[0,0]],"v":[[-0.02,14.982],[-0.02,-12.871],[0.02,-14.982]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[84.388,122.726],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 15","np":2,"cix":2,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-16.128,0],[-9.757,-8.423]],"o":[[10.186,-11.06],[13.822,0],[0,0]],"v":[[-38.581,9.008],[2.315,-9.008],[38.581,4.524]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[137.684,63.23],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 16","np":2,"cix":2,"ix":15,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[28.867,-1.944]],"o":[[0,0],[0,29.338],[0,0]],"v":[[25.941,-57.899],[25.941,2.393],[-25.942,57.899]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[169.69,167.753],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 17","np":2,"cix":2,"ix":16,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,27.37],[0,0]],"o":[[-26.126,-4.53],[0,0],[0,0]],"v":[[23.079,38.774],[-23.079,-16.045],[-23.079,-38.774]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[107.447,186.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 18","np":2,"cix":2,"ix":17,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-36.886,0],[-4.666,-1.038]],"o":[[0,-36.886],[4.966,0],[0,0]],"v":[[-40.771,33.533],[26.294,-33.533],[40.771,-31.949]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[113.706,71.144],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 19","np":2,"cix":2,"ix":18,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-24.615],[0,0]],"o":[[19.903,11.667],[0,0],[0,0]],"v":[[-16.671,-53.46],[16.671,4.45],[16.671,53.46]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[190.395,100.228],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 20","np":2,"cix":2,"ix":19,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[36.886,0],[4.528,0.973]],"o":[[0,36.886],[-4.807,0],[0,0]],"v":[[40.547,-33.533],[-26.519,33.533],[-40.547,32.048]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[166.519,208.856],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 21","np":2,"cix":2,"ix":20,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,24.684],[0,0]],"o":[[-19.997,-11.643],[0,0],[0,0]],"v":[[16.757,53.666],[-16.757,-4.342],[-16.757,-53.666]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[89.69,179.665],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 22","np":2,"cix":2,"ix":21,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-7.026,11.748]],"o":[[0,0],[0,-14.611],[0,0]],"v":[[-5.536,32.629],[-5.536,7.442],[5.536,-32.629]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[67.035,92.059],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 23","np":2,"cix":2,"ix":22,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-15.423,4.252]],"o":[[10.099,-11.889],[0,0]],"v":[[-19.541,12.505],[19.541,-12.505]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[99.723,36.303],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 24","np":2,"cix":2,"ix":23,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-13.318,-10.399]],"o":[[0,0],[18.106,0],[0,0]],"v":[[-24.075,-8.306],[-24.075,-8.306],[24.075,8.306]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.075,29.306],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 25","np":2,"cix":2,"ix":24,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-18.945],[0,0]],"o":[[11.283,13.601],[0,0],[0,0]],"v":[[-9.042,-32.053],[9.042,17.928],[9.042,32.053]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[209.457,81.572],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 26","np":2,"cix":2,"ix":25,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[218.5,126.813],[218.5,173.139]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 27","np":2,"cix":2,"ix":26,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[12.315,-11.279]],"o":[[-3.194,17.022],[0,0]],"v":[[12.123,-21.717],[-12.122,21.716]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[205.041,216.638],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 28","np":2,"cix":2,"ix":27,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[13.521,0],[8.502,3.175]],"o":[[-11.138,6.085],[-9.574,0],[0,0]],"v":[[32.337,-4.775],[-5.073,4.775],[-32.337,-0.137]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[145.073,254.225],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 29","np":2,"cix":2,"ix":28,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[6.827,13.957]],"o":[[-13.338,-7.843],[0,0]],"v":[[15.508,16.734],[-15.508,-16.733]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[84.928,231.495],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 30","np":2,"cix":2,"ix":29,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,4.795],[0,0]],"o":[[-0.833,-4.563],[0,0],[0,0]],"v":[[0.635,25.746],[-0.635,11.69],[-0.635,-25.746]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.109999997008,0.109999997008,0.105999995213,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[62.134,168.809],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Группа 31","np":2,"cix":2,"ix":30,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.03],"y":[0.978]},"n":["0p667_1_0p03_0p978"],"t":0,"s":[100],"e":[0]},{"t":16}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.986],"y":[0.477]},"o":{"x":[0.769],"y":[0]},"n":["0p986_0p477_0p769_0"],"t":31,"s":[100],"e":[0]},{"t":48}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":31,"nm":"Обрезать контуры 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":48,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/insta_camera.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/insta_camera.json deleted file mode 100644 index 945c3b2f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/insta_camera.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.0.1","fr":30.0000305175781,"ip":0,"op":124.000126139323,"w":800,"h":600,"nm":"Camera_003_render","ddd":0,"assets":[{"id":"comp_4","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"flash ring","parent":19,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[133,-67,0],"ix":2},"a":{"a":0,"k":[74,-135,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.09,0.09],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p09_1_0p167_0p167","0p09_1_0p167_0p167"],"t":73,"s":[0,0],"e":[148,148]},{"t":79.0000803629557}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.09],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p09_1_0p167_0p167"],"t":73,"s":[23],"e":[0]},{"t":82.0000834147135}],"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[74,-135],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":73.0000742594401,"op":83.0000844319661,"st":73.0000742594401,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"button lines","parent":19,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-35.5,-60.5,0],"ix":2},"a":{"a":0,"k":[72.5,-149.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[91,-152.25],[108,-160.75]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 5","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[60.25,-161.75],[49,-177.25]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[4.25,2.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 6","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[73.75,-162.5],[80.75,-179]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[4.25,2.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 4","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[53,-150.5],[34.25,-159.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.08],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p08_1_0p167_0p167"],"t":73.539,"s":[0],"e":[100]},{"t":80.0000813802083}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.08],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p08_1_0p167_0p167"],"t":71,"s":[0],"e":[100]},{"t":80.0000813802083}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":5,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":71.0000722249349,"op":81.0000823974609,"st":71.0000722249349,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"flash light","parent":19,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":71,"s":[35.264],"e":[102.264]},{"t":80.0000813802083}],"ix":10},"p":{"a":0,"k":[132,-68,0],"ix":2},"a":{"a":0,"k":[-340,-162,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":4,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":143.286,"ix":5},"ir":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":71,"s":[0],"e":[25]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":76,"s":[25],"e":[0]},{"t":80.0000813802083}],"ix":6},"is":{"a":0,"k":193,"ix":8},"or":{"a":0,"k":73.6,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.992156862745,1,0.988235294118,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-340,-162],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":71.0000722249349,"op":81.0000823974609,"st":71.0000722249349,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"face button mask","parent":19,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.45],"y":[0]},"n":["0p833_0p833_0p45_0"],"t":0,"s":[0],"e":[-90]},{"t":17.0000172932943}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"p":{"a":0,"k":[60,60,0],"ix":2},"a":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-27,"s":[-2,-6.5,0],"e":[-2,-6.5,0],"to":[0,0,0],"ti":[0,0,0]},{"t":56,"s":[-2,-6.5,0],"h":1},{"t":66.0000671386719,"s":[-2,-6.5,0],"h":1}],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":126,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.14,0.14],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p14_1_0p167_0p167","0p14_1_0p167_0p167"],"t":-27,"s":[0,0],"e":[200,1]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.45,0.45],"y":[0,0]},"n":["0p833_0p833_0p45_0","0p833_0p833_0p45_0"],"t":0,"s":[200,1],"e":[216,302]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":17,"s":[216,302],"e":[216,302]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":101,"s":[216,302],"e":[0,302]},{"t":110.000111897786}],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('body').content('Rectangle 1').content('Rectangle Path 1').size;"},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.204152006261,0.019608000213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-6.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":-27.0000274658203,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"face button","parent":20,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":89.999,"ix":10},"p":{"a":0,"k":[34.724,96.498,0],"ix":2},"a":{"a":0,"k":[3,4,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.35,0.35],"y":[1,1]},"o":{"x":[0.54,0.54],"y":[0,0]},"n":["0p35_1_0p54_0","0p35_1_0p54_0"],"t":28,"s":[0,0],"e":[32,32]},{"i":{"x":[0.833,0.833],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0,0]},"n":["0p833_1_0p167_0","0p833_1_0p167_0"],"t":48,"s":[32,32],"e":[32,32]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.53,0.53],"y":[0,0]},"n":["0p833_0p833_0p53_0","0p833_0p833_0p53_0"],"t":97,"s":[32,32],"e":[105,105]},{"t":135.000137329102}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[3,4],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":28.0000284830729,"op":124.000126139323,"st":28.0000284830729,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"line mask","parent":19,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.45],"y":[0]},"n":["0p833_0p833_0p45_0"],"t":0,"s":[0],"e":[-90]},{"t":17.0000172932943}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"p":{"a":0,"k":[60,60,0],"ix":2},"a":{"a":0,"k":[-2,-6.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":126,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.14,0.14],"y":[1,1]},"o":{"x":[0.54,0.54],"y":[0,0]},"n":["0p14_1_0p54_0","0p14_1_0p54_0"],"t":-27,"s":[0,0],"e":[200,1]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.45,0.45],"y":[0,0]},"n":["0p833_0p833_0p45_0","0p833_0p833_0p45_0"],"t":0,"s":[200,1],"e":[216,302]},{"t":17.0000172932943}],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('body').content('Rectangle 1').content('Rectangle Path 1').size;"},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.929412004059,0.929412004059,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-6.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":-27.0000274658203,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"line","parent":20,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90.084,"ix":10},"p":{"a":0,"k":[68.999,-5.896,0],"ix":2},"a":{"a":0,"k":[0.5,-56,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-171.5,-56],[165.5,-56]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.59],"y":[1]},"o":{"x":[0.29],"y":[0]},"n":["0p59_1_0p29_0"],"t":16,"s":[50],"e":[0]},{"t":33.0000335693359}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.59],"y":[1]},"o":{"x":[0.29],"y":[0]},"n":["0p59_1_0p29_0"],"t":16,"s":[50],"e":[100]},{"t":33.0000335693359}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.929412004059,0.929412004059,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":16.0000162760417,"op":124.000126139323,"st":16.0000162760417,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"flash mask","parent":19,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.45],"y":[0]},"n":["0p833_0p833_0p45_0"],"t":0,"s":[0],"e":[-90]},{"t":17.0000172932943}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"p":{"a":0,"k":[60,60,0],"ix":2},"a":{"a":0,"k":[-2,-6.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":126,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.14,0.14],"y":[1,1]},"o":{"x":[0.54,0.54],"y":[0,0]},"n":["0p14_1_0p54_0","0p14_1_0p54_0"],"t":-27,"s":[0,0],"e":[200,1]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.45,0.45],"y":[0,0]},"n":["0p833_0p833_0p45_0","0p833_0p833_0p45_0"],"t":0,"s":[200,1],"e":[216,302]},{"t":17.0000172932943}],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('body').content('Rectangle 1').content('Rectangle Path 1').size;"},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.929412004059,0.929412004059,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-6.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":-27.0000274658203,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"button","parent":20,"tt":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90.004,"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":29,"s":[70.511],"e":[102.512]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":47,"s":[102.512],"e":[102.512]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":71,"s":[102.512],"e":[92.512]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":74,"s":[92.512],"e":[102.512]},{"i":{"x":[0.823],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p823_1_0p167_0"],"t":77,"s":[102.512],"e":[102.512]},{"i":{"x":[0.745],"y":[1]},"o":{"x":[1],"y":[-0.47]},"n":["0p745_1_1_-0p47"],"t":93,"s":[102.512],"e":[72.512]},{"t":105.000106811523}],"ix":3,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n amp = div(effect('X Position - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('X Position - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('X Position - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"y":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":29,"s":[-176.891],"e":[-176.421]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":47,"s":[-176.421],"e":[-176.421]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":71,"s":[-176.421],"e":[-176.421]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":74,"s":[-176.421],"e":[-176.421]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":77,"s":[-176.421],"e":[-176.421]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":93,"s":[-176.421],"e":[-176.421]},{"t":105.000106811523}],"ix":4}},"a":{"a":0,"k":[94,-107.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"X Position - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"X Position - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"X Position - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":100,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[26,86],"ix":2},"p":{"a":0,"k":[74,24],"ix":3},"r":{"a":0,"k":24,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[94,-107.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":29.0000295003255,"op":106.000107828776,"st":29.0000295003255,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"body mask","parent":19,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.45],"y":[0]},"n":["0p833_0p833_0p45_0"],"t":0,"s":[0],"e":[-90]},{"t":17.0000172932943}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"p":{"a":0,"k":[60,60,0],"ix":2},"a":{"a":0,"k":[-2,-6.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":126,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.14,0.14],"y":[1,1]},"o":{"x":[0.54,0.54],"y":[0,0]},"n":["0p14_1_0p54_0","0p14_1_0p54_0"],"t":-27,"s":[0,0],"e":[200,1]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.45,0.45],"y":[0,0]},"n":["0p833_0p833_0p45_0","0p833_0p833_0p45_0"],"t":0,"s":[200,1],"e":[216,302]},{"t":17.0000172932943}],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('body').content('Rectangle 1').content('Rectangle Path 1').size;"},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.929412004059,0.929412004059,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-6.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":-27.0000274658203,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"flash","parent":20,"tt":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90.004,"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[71.498],"e":[129.499]},{"i":{"x":[0.885],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p885_1_0p167_0"],"t":39,"s":[129.499],"e":[129.499]},{"i":{"x":[0.683],"y":[1]},"o":{"x":[0.688],"y":[-0.339]},"n":["0p683_1_0p688_-0p339"],"t":99,"s":[129.499],"e":[69.499]},{"t":110.000111897786}],"ix":3,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n amp = div(effect('X Position - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('X Position - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('X Position - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"y":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.59],"y":[0]},"n":["0p833_0p833_0p59_0"],"t":27,"s":[-6.965],"e":[-6.42]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[-6.42],"e":[-6.42]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":99,"s":[-6.42],"e":[-6.42]},{"t":110.000111897786}],"ix":4,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n amp = div(effect('Y Position - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Y Position - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Y Position - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"}},"a":{"a":0,"k":[94,-107.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Y Position - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Y Position - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Y Position - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":100,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"X Position - Overshoot","np":3,"mn":"ADBE Slider Control","ix":4,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"X Position - Bounce","np":3,"mn":"ADBE Slider Control","ix":5,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"X Position - Friction","np":3,"mn":"ADBE Slider Control","ix":6,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":100,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[79,72.861],"ix":2},"p":{"a":0,"k":[72,22],"ix":3},"r":{"a":0,"k":9,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[94,-107.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":27.0000274658203,"op":107.000108846029,"st":27.0000274658203,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"lens mask 2","parent":19,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.45],"y":[0]},"n":["0p833_0p833_0p45_0"],"t":0,"s":[0],"e":[-90]},{"t":17.0000172932943}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"p":{"a":0,"k":[60,60,0],"ix":2},"a":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-27,"s":[-2,-6.5,0],"e":[-2,-6.5,0],"to":[0,0,0],"ti":[0,0,0]},{"t":56,"s":[-2,-6.5,0],"h":1},{"t":66.0000671386719,"s":[-2,-6.5,0],"h":1}],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":126,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.14,0.14],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p14_1_0p167_0p167","0p14_1_0p167_0p167"],"t":-27,"s":[0,0],"e":[200,1]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.45,0.45],"y":[0,0]},"n":["0p833_0p833_0p45_0","0p833_0p833_0p45_0"],"t":0,"s":[200,1],"e":[216,302]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":17,"s":[216,302],"e":[216,302]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":101,"s":[216,302],"e":[0,302]},{"t":110.000111897786}],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('body').content('Rectangle 1').content('Rectangle Path 1').size;"},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.204152006261,0.019608000213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-6.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":-27.0000274658203,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"lens","parent":20,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[-22,-28.5,0],"ix":2},"a":{"a":0,"k":[3,4,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Size - Ellipse Path 1 - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Size - Ellipse Path 1 - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Size - Ellipse Path 1 - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":100,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.54,0.54],"y":[0,0]},"n":["0p833_0p833_0p54_0","0p833_0p833_0p54_0"],"t":21,"s":[0,0],"e":[94,94]},{"i":{"x":[0.833,0.833],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0,0]},"n":["0p833_1_0p167_0","0p833_1_0p167_0"],"t":41,"s":[94,94],"e":[94,94]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.87,0.87],"y":[0,0]},"n":["0p833_0p833_0p87_0","0p833_0p833_0p87_0"],"t":97,"s":[94,94],"e":[183,183]},{"t":123.00012512207}],"ix":2,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n amp = div(effect('Size - Ellipse Path 1 - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Size - Ellipse Path 1 - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Size - Ellipse Path 1 - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[3,4],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":21.0000213623047,"op":124.000126139323,"st":21.0000213623047,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"lens mask","parent":19,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.45],"y":[0]},"n":["0p833_0p833_0p45_0"],"t":0,"s":[0],"e":[-90]},{"t":17.0000172932943}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"p":{"a":0,"k":[60,60,0],"ix":2},"a":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-27,"s":[-2,-6.5,0],"e":[-2,-6.5,0],"to":[0,0,0],"ti":[0,0,0]},{"t":56,"s":[-2,-6.5,0],"h":1},{"t":66.0000671386719,"s":[-2,-6.5,0],"h":1}],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":126,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.14,0.14],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p14_1_0p167_0p167","0p14_1_0p167_0p167"],"t":-27,"s":[0,0],"e":[200,1]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.45,0.45],"y":[0,0]},"n":["0p833_0p833_0p45_0","0p833_0p833_0p45_0"],"t":0,"s":[200,1],"e":[216,302]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":17,"s":[216,302],"e":[216,302]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":101,"s":[216,302],"e":[0,302]},{"t":110.000111897786}],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('body').content('Rectangle 1').content('Rectangle Path 1').size;"},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.204152006261,0.019608000213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-6.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":-27.0000274658203,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"lens","parent":20,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[-22,-28.5,0],"ix":2},"a":{"a":0,"k":[3,4,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Size - Ellipse Path 1 - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Size - Ellipse Path 1 - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Size - Ellipse Path 1 - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":100,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.54,0.54],"y":[0,0]},"n":["0p833_0p833_0p54_0","0p833_0p833_0p54_0"],"t":15,"s":[0,0],"e":[136,136]},{"i":{"x":[0.833,0.833],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0,0]},"n":["0p833_1_0p167_0","0p833_1_0p167_0"],"t":35,"s":[136,136],"e":[136,136]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.87,0.87],"y":[0,0]},"n":["0p833_0p833_0p87_0","0p833_0p833_0p87_0"],"t":97,"s":[136,136],"e":[212,212]},{"t":123.00012512207}],"ix":2,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n amp = div(effect('Size - Ellipse Path 1 - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Size - Ellipse Path 1 - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Size - Ellipse Path 1 - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[3,4],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":15.0000152587891,"op":124.000126139323,"st":15.0000152587891,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".gannon-gram","cl":"gannon-gram","parent":20,"sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":90.004,"ix":10},"p":{"a":0,"k":[85.672,-6.451,0],"ix":2},"a":{"a":0,"k":[-0.257,-6.362,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-4.887],[-4.517,0],[-1.575,1.76],[0,0],[0,0],[0,0],[0,0],[0,0],[1.413,0],[0,2.919],[-2.803,0],[-0.718,-1.089],[0,0],[3.196,0]],"o":[[0,4.864],[2.803,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.672,0.602],[-2.803,0],[0,-2.919],[1.621,0],[0,0],[-1.181,-1.83],[-4.517,0]],"v":[[-101.849,-7.713],[-93.626,0.301],[-87.048,-2.617],[-87.048,-8.524],[-94.414,-8.524],[-94.414,-5.698],[-90.291,-5.698],[-90.291,-3.822],[-93.626,-2.641],[-98.467,-7.713],[-93.626,-12.786],[-89.966,-10.84],[-87.233,-12.323],[-93.626,-15.704]],"c":true},"ix":2},"nm":"G","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"G","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-69.614,0],[-66.024,0],[-71.976,-15.45],[-76.099,-15.45],[-82.075,0],[-78.462,0],[-77.489,-2.664],[-70.587,-2.664]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-74.038,-12.601],[-71.49,-5.513],[-76.609,-5.513]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":5,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-49.766,0],[-46.593,0],[-46.593,-15.45],[-49.882,-15.45],[-49.882,-5.443],[-57.039,-15.45],[-60.421,-15.45],[-60.421,0],[-57.132,0],[-57.132,-10.377]],"c":true},"ix":2},"nm":"N","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"N","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-28.721,0],[-25.548,0],[-25.548,-15.45],[-28.837,-15.45],[-28.837,-5.443],[-35.995,-15.45],[-39.376,-15.45],[-39.376,0],[-36.087,0],[-36.087,-10.377]],"c":true},"ix":2},"nm":"N","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"N","np":3,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-4.656],[-4.656,0],[0,4.656],[4.679,0]],"o":[[0,4.656],[4.679,0],[0,-4.656],[-4.656,0]],"v":[[-19.073,-7.713],[-11.012,0.278],[-2.928,-7.713],[-11.012,-15.704]],"c":true},"ix":2},"nm":"O","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,-2.895],[2.849,0],[0,2.872],[-2.849,0]],"o":[[0,2.872],[-2.849,0],[0,-2.895],[2.849,0]],"v":[[-6.31,-7.713],[-11.012,-2.641],[-15.691,-7.713],[-11.012,-12.786]],"c":true},"ix":2},"nm":"O","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"O","np":5,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[14.196,0],[17.37,0],[17.37,-15.45],[14.081,-15.45],[14.081,-5.443],[6.923,-15.45],[3.541,-15.45],[3.541,0],[6.831,0],[6.831,-10.377]],"c":true},"ix":2},"nm":"N","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"N","np":3,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-4.887],[-4.517,0],[-1.575,1.76],[0,0],[0,0],[0,0],[0,0],[0,0],[1.413,0],[0,2.919],[-2.803,0],[-0.718,-1.089],[0,0],[3.196,0]],"o":[[0,4.864],[2.803,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.672,0.602],[-2.803,0],[0,-2.919],[1.621,0],[0,0],[-1.181,-1.83],[-4.517,0]],"v":[[23.845,-7.713],[32.068,0.301],[38.646,-2.617],[38.646,-8.524],[31.28,-8.524],[31.28,-5.698],[35.403,-5.698],[35.403,-3.822],[32.068,-2.641],[27.227,-7.713],[32.068,-12.786],[35.727,-10.84],[38.461,-12.323],[32.068,-15.704]],"c":true},"ix":2},"nm":"G","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"G","np":3,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,2.733],[3.22,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[1.668,-0.394],[0,-2.872],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[54.156,0],[57.932,0],[54.457,-5.883],[57.839,-10.47],[52.651,-15.45],[45.424,-15.45],[45.424,0],[48.713,0],[48.713,-5.536],[51.122,-5.536]],"c":true},"ix":2},"nm":"R","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,-1.297],[1.32,0],[0,0],[0,0],[0,0]],"o":[[0,1.297],[0,0],[0,0],[0,0],[1.32,0]],"v":[[54.48,-10.493],[52.164,-8.362],[48.713,-8.362],[48.713,-12.624],[52.164,-12.624]],"c":true},"ix":2},"nm":"R","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"R","np":5,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[75.308,0],[78.898,0],[72.945,-15.45],[68.822,-15.45],[62.846,0],[66.459,0],[67.432,-2.664],[74.335,-2.664]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[70.884,-12.601],[73.431,-5.513],[68.312,-5.513]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":5,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[97.935,0],[101.247,0],[101.247,-15.45],[96.615,-15.45],[92.862,-5.814],[89.11,-15.45],[84.5,-15.45],[84.5,0],[87.79,0],[87.79,-11.118],[92.144,0],[93.58,0],[97.935,-11.118]],"c":true},"ix":2},"nm":"M","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"M","np":3,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false}],"ip":16.0000162760417,"op":110.000111897786,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":3,"nm":".chris-gannon-lottie-animation","cl":"chris-gannon-lottie-animation","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.45],"y":[1]},"o":{"x":[0.55],"y":[0]},"n":["0p45_1_0p55_0"],"t":72,"s":[0],"e":[-2]},{"i":{"x":[0.45],"y":[1]},"o":{"x":[0.55],"y":[0]},"n":["0p45_1_0p55_0"],"t":74,"s":[-2],"e":[0]},{"t":84.0000854492187}],"ix":10},"p":{"a":0,"k":[518,386,0],"ix":2},"a":{"a":0,"k":[178,146,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":124.000126139323,"st":-27.0000274658203,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"body","parent":19,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.45],"y":[0]},"n":["0p833_0p833_0p45_0"],"t":0,"s":[0],"e":[-90]},{"t":17.0000172932943}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"p":{"a":0,"k":[60,60,0],"ix":2},"a":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-27,"s":[-2,-6.5,0],"e":[-2,-6.5,0],"to":[0,0,0],"ti":[0,0,0]},{"t":56,"s":[-2,-6.5,0],"h":1},{"t":66.0000671386719,"s":[-2,-6.5,0],"h":1}],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":126,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.14,0.14],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p14_1_0p167_0p167","0p14_1_0p167_0p167"],"t":-27,"s":[0,0],"e":[200,1]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.45,0.45],"y":[0,0]},"n":["0p833_0p833_0p45_0","0p833_0p833_0p45_0"],"t":0,"s":[200,1],"e":[216,302]},{"i":{"x":[0.833,0.833],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0,0]},"n":["0p833_1_0p167_0","0p833_1_0p167_0"],"t":17,"s":[216,302],"e":[216,302]},{"i":{"x":[0.197,0.45],"y":[1,1]},"o":{"x":[0.872,0.59],"y":[-0.522,0]},"n":["0p197_1_0p872_-0p522","0p45_1_0p59_0"],"t":97,"s":[216,302],"e":[0,200]},{"t":123.00012512207}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-6.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":-27.0000274658203,"bm":0}]}],"layers":[{"ddd":0,"ind":3,"ty":0,"nm":".chris-gannon-instagram-lottie","cl":"chris-gannon-instagram-lottie","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,323,0],"ix":2},"a":{"a":0,"k":[400,300,0],"ix":1},"s":{"a":0,"k":[129,129,100],"ix":6}},"ao":0,"w":800,"h":600,"ip":0,"op":124.000126139323,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"blueToPurple","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[800,600],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"g":{"p":5,"k":{"a":0,"k":[0.007,0.298,0.404,0.851,0.307,0.431,0.308,0.735,0.6,0.565,0.212,0.62,0.8,0.565,0.212,0.62,1,0.565,0.212,0.62,0,1,0.199,1,0.397,1,0.592,0.5,0.788,0],"ix":9}},"s":{"a":0,"k":[-258,-522],"ix":5},"e":{"a":0,"k":[-943,-866],"ix":6},"t":2,"h":{"a":0,"k":18.494,"ix":7},"a":{"a":0,"k":-100.276,"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"yellowToOrange","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[800,600],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"g":{"p":7,"k":{"a":0,"k":[0.007,0.984,0.847,0.482,0.193,0.969,0.657,0.325,0.375,0.953,0.467,0.169,0.545,0.882,0.263,0.314,0.715,0.812,0.059,0.459,0.857,0.688,0.135,0.539,1,0.565,0.212,0.62,0,1,0.259,1,0.517,1,0.75,0.5,0.983,0],"ix":9}},"s":{"a":0,"k":[-140,330],"ix":5},"e":{"a":0,"k":[-637,989],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"bg","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[800,600],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.811764705882,0.058823529412,0.458823529412,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":0,"bm":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/intelia_logo_animation.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/intelia_logo_animation.json deleted file mode 100644 index a82c26a5..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/intelia_logo_animation.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.3","fr":24,"ip":0,"op":207,"w":850,"h":850,"nm":"Comp 1","ddd":0,"assets":[{"id":"comp_25","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 7","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":10,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":12.372,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":36.085,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":92.997,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":116.71,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":130.938,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":152.281,"s":[0],"e":[100]},{"t":175.994140625}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[-45],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":10,"s":[0],"e":[360]},{"t":175.994140625}],"ix":10},"p":{"a":0,"k":[580.426,1041.493,0],"ix":2},"a":{"a":0,"k":[-356.047,-391.199,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[156.703,156.703],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-194.047,-395.199],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":582,"st":0,"bm":3},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 5","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":10,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":19.484,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":43.199,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":55.056,"s":[0],"e":[67]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":78.77,"s":[67],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":102.482,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":152.281,"s":[0],"e":[100]},{"t":175.994140625}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-468.047,-441.199,0],"ix":2},"a":{"a":0,"k":[-194.047,-395.199,0],"ix":1},"s":{"a":0,"k":[53,53,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[156.703,156.703],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-194.047,-395.199],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":582,"st":0,"bm":3}]},{"id":"comp_26","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35.253,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":71.7,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":127.79,"s":[100],"e":[0]},{"t":165.1826171875}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[742.953,606.801,0],"e":[448.953,366.801,0],"to":[-49,-40,0],"ti":[49,40,0]},{"t":166.0048828125}],"ix":2},"a":{"a":0,"k":[-194.047,-395.199,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[156.703,156.703],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-194.047,-395.199],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":582,"st":0,"bm":3},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 4","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":10,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":93.365,"s":[100],"e":[0]},{"t":166.0048828125}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-426.047,-547.199,0],"ix":2},"a":{"a":0,"k":[-194.047,-395.199,0],"ix":1},"s":{"a":0,"k":[39,39,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[156.703,156.703],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-194.047,-395.199],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":582,"st":0,"bm":3},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 3","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":10,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":23.598,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":93.365,"s":[100],"e":[0]},{"t":166.0048828125}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-267.047,-558.199,0],"ix":2},"a":{"a":0,"k":[-194.047,-395.199,0],"ix":1},"s":{"a":0,"k":[78,78,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[156.703,156.703],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-194.047,-395.199],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":582,"st":0,"bm":3}]},{"id":"comp_27","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Combined Shape 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[100]},{"t":10}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.525,25.765,0],"ix":2},"a":{"a":0,"k":[38.73,33.425,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[20,0],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[21.5,1.5],"ix":2},"a":{"a":0,"k":[21.5,1.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[14,5],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[15.5,6.5],"ix":2},"a":{"a":0,"k":[15.5,6.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy 2","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[10,10],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[11.5,11.5],"ix":2},"a":{"a":0,"k":[11.5,11.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy 4","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[5,15],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[6.5,16.5],"ix":2},"a":{"a":0,"k":[6.5,16.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy 6","np":1,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[0,20],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[1.5,21.5],"ix":2},"a":{"a":0,"k":[1.5,21.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy 8","np":1,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[26,6],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[27.5,7.5],"ix":2},"a":{"a":0,"k":[27.5,7.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy","np":1,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[20,11],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[21.5,12.5],"ix":2},"a":{"a":0,"k":[21.5,12.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy 3","np":1,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[16,16],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[17.5,17.5],"ix":2},"a":{"a":0,"k":[17.5,17.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy 5","np":1,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[11,21],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[12.5,22.5],"ix":2},"a":{"a":0,"k":[12.5,22.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy 7","np":1,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[6,26],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[7.5,27.5],"ix":2},"a":{"a":0,"k":[7.5,27.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy 9","np":1,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[13.479,8.174],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[174.15,174.15],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Combined Shape","np":11,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":582,"st":0,"bm":3},{"ddd":0,"ind":2,"ty":4,"nm":"Combined Shape","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[100]},{"t":10}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.525,25.765,0],"ix":2},"a":{"a":0,"k":[38.73,33.425,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[20,0],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[21.5,1.5],"ix":2},"a":{"a":0,"k":[21.5,1.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[14,5],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[15.5,6.5],"ix":2},"a":{"a":0,"k":[15.5,6.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy 2","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[10,10],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[11.5,11.5],"ix":2},"a":{"a":0,"k":[11.5,11.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy 4","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[5,15],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[6.5,16.5],"ix":2},"a":{"a":0,"k":[6.5,16.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy 6","np":1,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[0,20],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[1.5,21.5],"ix":2},"a":{"a":0,"k":[1.5,21.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy 8","np":1,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[26,6],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[27.5,7.5],"ix":2},"a":{"a":0,"k":[27.5,7.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy","np":1,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[20,11],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[21.5,12.5],"ix":2},"a":{"a":0,"k":[21.5,12.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy 3","np":1,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[16,16],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[17.5,17.5],"ix":2},"a":{"a":0,"k":[17.5,17.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy 5","np":1,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[11,21],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[12.5,22.5],"ix":2},"a":{"a":0,"k":[12.5,22.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy 7","np":1,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3,3],"ix":2},"p":{"a":0,"k":[6,26],"ix":3,"x":"var $bm_rt;\n$bm_rt = sum(div(thisProperty.propertyGroup(1)(2), 2), value);"},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[7.5,27.5],"ix":2},"a":{"a":0,"k":[7.5,27.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Oval Copy 9","np":1,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[13.479,8.174],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[174.15,174.15],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Combined Shape","np":11,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":582,"st":0,"bm":3}]},{"id":"comp_28","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"top gradient 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[676.793,592.214,0],"ix":2},"a":{"a":0,"k":[161.771,185.625,0],"ix":1},"s":{"a":0,"k":[167.414,156.485,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-32.615,36.219],[38.821,39.666],[0,0],[30.168,-34.428],[-34.643,-35.416]],"o":[[0,0],[35.421,36.573],[33.486,-37.186],[0,0],[-34.643,-35.408],[-32.698,37.315],[0,0]],"v":[[145.847,276.337],[188.716,320.16],[308.833,322.591],[302.799,191.193],[166.892,47.089],[45.018,50.252],[50.711,177.105]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":2,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.918,0.078,0.482,0.5,0.488,0.41,0.645,1,0.059,0.741,0.808],"ix":8}},"s":{"a":0,"k":[20.389,22.001],"ix":4},"e":{"a":0,"k":[333.534,351.158],"ix":5},"t":1,"lc":2,"lj":2,"d":[{"n":"d","nm":"dash","v":{"a":0,"k":0,"ix":1}},{"n":"g","nm":"gap","v":{"a":0,"k":6,"ix":2}},{"n":"o","nm":"offset","v":{"a":0,"k":0,"ix":7}}],"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.016,0.071],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":0,"s":[0],"e":[100]},{"t":40}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[360]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":40,"s":[360],"e":[432]},{"t":206}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":582,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"bottom gradient 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[704.229,761.465,0],"ix":2},"a":{"a":0,"k":[178.51,145.63,0],"ix":1},"s":{"a":0,"k":[166.241,155.588,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-31.766,-33.004],[-34.481,35.437],[0,0],[32.662,35.352],[34.489,-35.437]],"o":[[0,0],[-34.481,35.437],[32.568,33.837],[0,0],[34.481,-35.429],[-32.658,-35.348],[0,0]],"v":[[122.383,118.689],[50.12,195.537],[46.83,323.705],[168.402,323.543],[307.278,175.855],[309.169,47.695],[188.989,47.857]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":2,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.918,0.078,0.482,0.5,0.488,0.41,0.645,1,0.059,0.741,0.808],"ix":8}},"s":{"a":0,"k":[20.389,22.001],"ix":4},"e":{"a":0,"k":[333.534,351.158],"ix":5},"t":1,"lc":2,"lj":2,"d":[{"n":"d","nm":"dash","v":{"a":0,"k":0,"ix":1}},{"n":"g","nm":"gap","v":{"a":0,"k":6,"ix":2}},{"n":"o","nm":"offset","v":{"a":0,"k":0,"ix":7}}],"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":0,"s":[0],"e":[100]},{"t":40}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[360]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":40,"s":[360],"e":[432]},{"t":206}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":582,"st":0,"bm":0}]},{"id":"comp_29","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"top gradient 2","sr":1,"ks":{"o":{"a":0,"k":10,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[630.311,697.664,0],"ix":2},"a":{"a":0,"k":[129.266,259.367,0],"ix":1},"s":{"a":0,"k":[143,143,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-32.615,36.219],[38.821,39.666],[0,0],[30.168,-34.428],[-34.643,-35.416]],"o":[[0,0],[35.421,36.573],[33.486,-37.186],[0,0],[-34.643,-35.408],[-32.698,37.315],[0,0]],"v":[[145.847,276.337],[188.716,320.16],[308.833,322.591],[302.799,191.193],[166.892,47.089],[45.018,50.252],[50.711,177.105]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":51,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.918,0.078,0.482,0.5,0.488,0.41,0.645,1,0.059,0.741,0.808],"ix":8}},"s":{"a":0,"k":[20.389,22.001],"ix":4},"e":{"a":0,"k":[333.534,351.158],"ix":5},"t":1,"lc":2,"lj":2,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.016,0.071],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":582,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"bottom gradient 2","parent":1,"sr":1,"ks":{"o":{"a":0,"k":10,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,151.01,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-31.766,-33.004],[-34.481,35.437],[0,0],[32.662,35.352],[34.489,-35.437]],"o":[[0,0],[-34.481,35.437],[32.568,33.837],[0,0],[34.481,-35.429],[-32.658,-35.348],[0,0]],"v":[[122.383,118.689],[50.12,195.537],[46.83,323.705],[168.402,323.543],[307.278,175.855],[309.169,47.695],[188.989,47.857]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":51,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.918,0.078,0.482,0.5,0.488,0.41,0.645,1,0.059,0.741,0.808],"ix":8}},"s":{"a":0,"k":[23.323,352.344],"ix":4},"e":{"a":0,"k":[333.867,22.766],"ix":5},"t":1,"lc":2,"lj":2,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":582,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"bottom left","refId":"comp_25","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[425,425,0],"ix":2},"a":{"a":0,"k":[700,700,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[19.3,-20.909],[-77.841,-87.143],[-26.626,37],[0,0],[0,0],[3.979,-3.943],[21.354,-8.993],[33.25,31.25],[-10.06,22.855],[0,0],[0,0],[0,0],[0,0]],"o":[[-18,19.501],[79.5,89],[4.366,-6.067],[0,0],[0,0],[-27.626,27.375],[-21.341,8.987],[-35.098,-32.987],[10.863,-24.679],[0,0],[0,0],[0,0],[0,0]],"v":[[478,811.999],[484,1028.5],[710.626,1031.25],[906.174,825.585],[828.745,800.692],[708.251,928.75],[636.146,997.493],[543.5,985],[522.637,879.679],[549.5,841.499],[726.796,651.11],[671.014,605.492],[511.727,774.458]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"w":1400,"h":1400,"ip":30,"op":207,"st":30,"bm":3},{"ddd":0,"ind":2,"ty":0,"nm":"Shape Layer 2 Comp 1","refId":"comp_26","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[425,425,0],"ix":2},"a":{"a":0,"k":[700,700,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[60.5,-58.625],[0,0],[-29.176,-33.894],[0,0],[0,0],[2.138,9.397],[-42.42,36.582],[-11.955,-11.937],[0,0],[0,0],[10.352,8.203]],"o":[[0,0],[-61.774,59.859],[0,0],[15.824,18.981],[0,0],[0,0],[-15.362,-24.603],[39.578,-34.132],[9.545,1.063],[0,0],[0,0],[-24.898,-22.047]],"v":[[627.3,325.45],[491.5,365.625],[442.454,504.046],[478.176,589.519],[603.472,718.436],[649.702,663.18],[528.362,535.103],[543.17,417.168],[643.955,408.437],[868.819,643.157],[915.114,587.104],[693.648,354.297]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"w":1400,"h":1400,"ip":40,"op":207,"st":40,"bm":3},{"ddd":0,"ind":3,"ty":0,"nm":"dot dot","refId":"comp_27","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":87.39,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":111.085,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":134.78,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":182.17,"s":[100],"e":[0]},{"t":205.865234375}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[356,425,0],"ix":2},"a":{"a":0,"k":[25.5,26,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":51,"h":52,"ip":40,"op":207,"st":40,"bm":3},{"ddd":0,"ind":4,"ty":0,"nm":"dot dot 3","refId":"comp_27","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":132.41,"s":[100],"e":[0]},{"t":156.10546875}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":49.478,"s":[97],"e":[103]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":54.217,"s":[103],"e":[151]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":66.064,"s":[151],"e":[205]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":82.651,"s":[205],"e":[254]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":103.977,"s":[254],"e":[267]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":118.193,"s":[267],"e":[273]},{"t":156.10546875}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.171,"y":0.523},"o":{"x":0.202,"y":0},"n":"0p171_0p523_0p202_0","t":40,"s":[478.5,197,0],"e":[605.211,514.635,0],"to":[190.990447998047,160.949462890625,0],"ti":[57.1761779785156,-54.6577949523926,0]},{"i":{"x":0.46,"y":1},"o":{"x":0.166,"y":0.528},"n":"0p46_1_0p166_0p528","t":75.542,"s":[605.211,514.635,0],"e":[391,454,0],"to":[-53.2955093383789,50.9480514526367,0],"ti":[55.3542785644531,99.6731643676758,0]},{"t":205.865234375}],"ix":2},"a":{"a":0,"k":[25.5,26,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":51,"h":52,"ip":40,"op":207,"st":40,"bm":3},{"ddd":0,"ind":5,"ty":4,"nm":"circle 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[408.811,344.164,0],"ix":2},"a":{"a":0,"k":[178.217,185.94,0],"ix":1},"s":{"a":0,"k":[143,143,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[141.106,206.717],[110.43,239.196],[145.39,275.784],[176.591,242.256]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":85,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":40,"s":[185.289,276.851],"e":[108.695,204.332],"to":[-12.7656526565552,-12.0863838195801],"ti":[12.7656526565552,12.0863838195801]},{"t":158.474609375}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[34.114,34.114],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":40,"s":[0],"e":[100]},{"t":63.6953125}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":40,"op":207,"st":40,"bm":3},{"ddd":0,"ind":6,"ty":4,"nm":"bottom intersect","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[170.46,267.714,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[143,143,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[124.626,32.564],[39.976,108.706],[124.626,184.848],[209.277,108.706]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-31.766,-33.004],[-34.481,35.437],[0,0],[32.662,35.352],[34.489,-35.437]],"o":[[0,0],[-34.481,35.437],[32.568,33.837],[0,0],[34.481,-35.429],[-32.658,-35.348],[0,0]],"v":[[122.383,118.689],[50.12,195.537],[46.83,323.705],[168.402,323.543],[307.278,175.855],[310.568,47.695],[188.989,47.857]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":51,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.918,0.078,0.482,0.5,0.488,0.41,0.645,1,0.059,0.741,0.808],"ix":8}},"s":{"a":0,"k":[23.323,352.344],"ix":4},"e":{"a":0,"k":[333.867,22.766],"ix":5},"t":1,"lc":2,"lj":2,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":5,"s":[0],"e":[100]},{"t":40}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":5,"s":[0],"e":[360]},{"t":40}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":5,"op":207,"st":5,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"circle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[425.311,317.664,0],"ix":2},"a":{"a":0,"k":[178.217,185.94,0],"ix":1},"s":{"a":0,"k":[143,143,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[110.862,203.395],[71.706,235.962],[161.474,328.756],[199.493,295.053]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":85,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":87.39,"s":[125.589,217.812],"e":[100.818,262.368],"to":[-4.1284236907959,7.42597246170044],"ti":[4.1284236907959,-7.42597246170044]},{"t":205.865234375}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[34.114,34.114],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":87.39,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":111.085,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":182.17,"s":[100],"e":[0]},{"t":205.865234375}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":40,"op":207,"st":40,"bm":3},{"ddd":0,"ind":8,"ty":0,"nm":"dot dot 2","refId":"comp_27","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":96.868,"s":[100],"e":[0]},{"t":108.7158203125}],"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.21,"y":1},"o":{"x":0.996,"y":0},"n":"0p21_1_0p996_0","t":63.695,"s":[438.5,506,0],"e":[354.5,426,0],"to":[-14,-13.3333330154419,0],"ti":[14,13.3333330154419,0]},{"t":134.7802734375}],"ix":2},"a":{"a":0,"k":[25.5,26,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":51,"h":52,"ip":50,"op":207,"st":50,"bm":3},{"ddd":0,"ind":9,"ty":4,"nm":"top intersect","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[0],"e":[50]},{"t":30}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[425.311,317.664,0],"ix":2},"a":{"a":0,"k":[178.217,185.94,0],"ix":1},"s":{"a":0,"k":[143,143,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[91.194,150.86],[25.552,210.787],[167.942,347.812],[223.269,294.703]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-32.615,36.219],[38.821,39.666],[0,0],[30.168,-34.428],[-34.643,-35.416]],"o":[[0,0],[35.421,36.573],[33.486,-37.186],[0,0],[-34.643,-35.408],[-32.698,37.315],[0,0]],"v":[[144.798,275.288],[192.388,323.656],[308.833,322.591],[302.799,191.193],[166.892,47.089],[45.018,50.252],[50.711,177.105]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":51,"ix":10},"g":{"p":7,"k":{"a":0,"k":[0,0.639,0.294,0.588,0.177,0.32,0.147,0.369,0.354,0,0,0.149,0.528,0,0,0.149,0.701,0,0,0.149,0.85,0.139,0.286,0.437,0.999,0.278,0.573,0.725],"ix":8}},"s":{"a":0,"k":[62.14,189.033],"ix":4},"e":{"a":0,"k":[193.065,322.973],"ix":5},"t":1,"lc":2,"lj":2,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.016,0.071],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":5,"s":[0],"e":[100]},{"t":45}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":5,"s":[0],"e":[360]},{"t":45}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[177.755,185.625],"ix":2},"a":{"a":0,"k":[177.755,185.625],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"path animation","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":5,"op":207,"st":5,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"top gradient","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[425.311,317.664,0],"ix":2},"a":{"a":0,"k":[178.217,185.94,0],"ix":1},"s":{"a":0,"k":[143,143,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-32.615,36.219],[38.821,39.666],[0,0],[30.168,-34.428],[-34.643,-35.416]],"o":[[0,0],[35.421,36.573],[33.486,-37.186],[0,0],[-34.643,-35.408],[-32.698,37.315],[0,0]],"v":[[145.847,276.337],[188.716,320.16],[308.833,322.591],[302.799,191.193],[166.892,47.089],[45.018,50.252],[50.711,177.105]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":51,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.918,0.078,0.482,0.5,0.488,0.41,0.645,1,0.059,0.741,0.808],"ix":8}},"s":{"a":0,"k":[20.389,22.001],"ix":4},"e":{"a":0,"k":[333.534,351.158],"ix":5},"t":1,"lc":2,"lj":2,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.016,0.071],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":5,"s":[0],"e":[100]},{"t":45}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":5,"s":[0],"e":[360]},{"t":45}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":5,"op":207,"st":5,"bm":0},{"ddd":0,"ind":11,"ty":0,"nm":"dot dot 4","refId":"comp_27","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0,"y":0},"n":"0_1_0_0","t":40,"s":[484,655,0],"e":[455,682.5,0],"to":[-4.83333349227905,4.58333349227905,0],"ti":[-18.1666660308838,18.25,0]},{"i":{"x":0,"y":1},"o":{"x":0.013,"y":0},"n":"0_1_0p013_0","t":87.39,"s":[455,682.5,0],"e":[593,545.5,0],"to":[18.1666660308838,-18.25,0],"ti":[-23,22.8333339691162,0]},{"t":111.0849609375}],"ix":2},"a":{"a":0,"k":[25.5,26,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":51,"h":52,"ip":40,"op":207,"st":40,"bm":3},{"ddd":0,"ind":12,"ty":4,"nm":"botto center shadow","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":22,"s":[0],"e":[50]},{"t":32}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[170.46,267.714,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[143,143,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[222.668,-8.017],[147.58,16.983],[253,122.403],[292.86,67.857]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-31.766,-33.004],[-34.481,35.437],[0,0],[32.662,35.352],[34.489,-35.437]],"o":[[0,0],[-34.481,35.437],[32.568,33.837],[0,0],[34.481,-35.429],[-32.658,-35.348],[0,0]],"v":[[122.383,118.689],[50.12,195.537],[46.83,323.705],[168.402,323.543],[307.278,175.855],[309.169,47.695],[188.989,47.857]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":51,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0,0,0.149,0.5,0.149,0.278,0.433,1,0.298,0.557,0.718],"ix":8}},"s":{"a":0,"k":[252.962,23.148],"ix":4},"e":{"a":0,"k":[186.511,57.098],"ix":5},"t":1,"lc":2,"lj":2,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":5,"s":[0],"e":[100]},{"t":45}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":5,"s":[0],"e":[360]},{"t":45}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":5,"op":207,"st":5,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"bottom right shadow","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":23,"s":[0],"e":[50]},{"t":33}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[170.46,267.714,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[143,143,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[27.966,-20.988]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[-43.954,32.986]],"v":[[229.381,220.652],[163.13,232.882],[245.771,315.523],[345.496,189.019],[355.903,137.559],[314.719,201.432]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-31.766,-33.004],[-34.481,35.437],[0,0],[32.662,35.352],[34.489,-35.437]],"o":[[0,0],[-34.481,35.437],[32.568,33.837],[0,0],[34.481,-35.429],[-32.658,-35.348],[0,0]],"v":[[122.383,118.689],[50.12,195.537],[46.83,323.705],[168.402,323.543],[307.278,175.855],[309.169,47.695],[188.989,47.857]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":51,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.576,0.341,0.612,0.5,0.288,0.171,0.38,1,0,0,0.149],"ix":8}},"s":{"a":0,"k":[209.954,279.226],"ix":4},"e":{"a":0,"k":[289.12,209.59],"ix":5},"t":1,"lc":2,"lj":2,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":5,"s":[0],"e":[100]},{"t":45}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":5,"s":[0],"e":[360]},{"t":45}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":5,"op":207,"st":5,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"bottom gradient","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[170.46,267.714,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[143,143,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-31.766,-33.004],[-34.481,35.437],[0,0],[32.662,35.352],[34.489,-35.437]],"o":[[0,0],[-34.481,35.437],[32.568,33.837],[0,0],[34.481,-35.429],[-32.658,-35.348],[0,0]],"v":[[122.383,118.689],[50.12,195.537],[46.83,323.705],[168.402,323.543],[307.278,175.855],[309.169,47.695],[188.989,47.857]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":51,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.918,0.078,0.482,0.5,0.488,0.41,0.645,1,0.059,0.741,0.808],"ix":8}},"s":{"a":0,"k":[23.323,352.344],"ix":4},"e":{"a":0,"k":[333.867,22.766],"ix":5},"t":1,"lc":2,"lj":2,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":5,"s":[0],"e":[100]},{"t":45}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":5,"s":[0],"e":[360]},{"t":45}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":5,"op":207,"st":5,"bm":0},{"ddd":0,"ind":15,"ty":0,"nm":"Ub=nder Lines Tones","refId":"comp_28","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.31],"y":[0]},"n":["0_1_0p31_0"],"t":20,"s":[0],"e":[-27]},{"t":40}],"ix":10},"p":{"a":0,"k":[435,415,0],"ix":2},"a":{"a":0,"k":[700,700,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1400,"h":1400,"ip":0,"op":207,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":0,"nm":"underTone","refId":"comp_29","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[0],"e":[50]},{"t":30}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0],"y":[0]},"o":{"x":[0.32],"y":[0]},"n":["0_0_0p32_0"],"t":20,"s":[0],"e":[-30]},{"t":40}],"ix":10},"p":{"a":0,"k":[357,421,0],"ix":2},"a":{"a":0,"k":[632,696,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1400,"h":1400,"ip":5,"op":207,"st":5,"bm":0},{"ddd":0,"ind":17,"ty":0,"nm":"underTone","refId":"comp_29","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[0],"e":[100]},{"t":30}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0],"y":[0]},"o":{"x":[0.32],"y":[0]},"n":["0_0_0p32_0"],"t":20,"s":[0],"e":[-12]},{"t":40}],"ix":10},"p":{"a":0,"k":[357,421,0],"ix":2},"a":{"a":0,"k":[632,696,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1400,"h":1400,"ip":5,"op":207,"st":5,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"pre-top 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[425.311,317.664,0],"ix":2},"a":{"a":0,"k":[178.217,185.94,0],"ix":1},"s":{"a":0,"k":[143,143,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[30.168,-34.428],[-34.643,-35.416],[0,0],[0,0],[-32.615,36.219],[38.821,39.666]],"o":[[-34.643,-35.408],[-32.698,37.315],[0,0],[0,0],[35.421,36.573],[33.486,-37.186],[0,0]],"v":[[166.892,47.089],[45.018,50.252],[50.711,177.105],[145.148,276.687],[188.716,320.16],[308.833,322.591],[302.799,191.193]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.226922487745,0.270561427696,0.314200367647,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":51,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.016,0.071],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":0,"s":[0],"e":[30]},{"t":40}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":0,"s":[0],"e":[360]},{"t":40}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":41,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"pre-top","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[425.311,317.664,0],"ix":2},"a":{"a":0,"k":[178.217,185.94,0],"ix":1},"s":{"a":0,"k":[143,143,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-32.615,36.219],[38.821,39.666],[0,0],[30.168,-34.428],[-34.643,-35.416],[0,0],[0,0]],"o":[[33.486,-37.186],[0,0],[-34.643,-35.408],[-32.698,37.315],[0,0],[0,0],[35.421,36.573]],"v":[[308.833,322.591],[302.799,191.193],[166.892,47.089],[45.018,50.252],[50.711,177.105],[145.148,276.687],[188.716,320.16]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.226922487745,0.270561427696,0.314200367647,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":51,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.016,0.071],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":0,"s":[0],"e":[30]},{"t":40}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":0,"s":[0],"e":[360]},{"t":40}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":41,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"pre-bottom 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[170.46,267.714,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[143,143,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-34.481,35.437],[0,0],[32.662,35.352],[34.489,-35.437],[0,0],[0,0],[-31.766,-33.004]],"o":[[0,0],[34.481,-35.429],[-32.658,-35.348],[0,0],[0,0],[-34.481,35.437],[32.568,33.837]],"v":[[168.402,323.543],[307.278,175.855],[310.568,47.695],[188.989,47.857],[122.383,118.689],[50.12,195.537],[46.83,323.705]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.226922487745,0.270561427696,0.314200367647,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":51,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":0,"s":[0],"e":[30]},{"t":40}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":0,"s":[0],"e":[360]},{"t":40}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":41,"st":0,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"pre-bottom","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[170.46,267.714,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[143,143,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-31.766,-33.004],[-34.481,35.437],[0,0],[32.662,35.352],[34.489,-35.437]],"o":[[0,0],[-34.481,35.437],[32.568,33.837],[0,0],[34.481,-35.429],[-32.658,-35.348],[0,0]],"v":[[122.383,118.689],[50.12,195.537],[46.83,323.705],[168.402,323.543],[307.278,175.855],[310.568,47.695],[188.989,47.857]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.226922487745,0.270561427696,0.314200367647,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":51,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":0,"s":[0],"e":[30]},{"t":40}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.13],"y":[1]},"o":{"x":[0.437],"y":[0]},"n":["0p13_1_0p437_0"],"t":0,"s":[0],"e":[360]},{"t":40}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":41,"st":0,"bm":0}],"markers":[{"tm":0.06944444444444,"cm":"1","dr":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/it's_lunch_time!.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/it's_lunch_time!.json deleted file mode 100644 index 20e5dbb6..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/it's_lunch_time!.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.20","fr":25,"ip":0,"op":74,"w":512,"h":512,"nm":"Layers-estaPronto","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"dente 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[140.225,174.571,0],"ix":2},"a":{"a":0,"k":[2.5,34.346,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[2.5,2.5],[2.5,66.191]],"c":false},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.808000033509,0,0.344999994016,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Traçado 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[1],"y":[0]},"n":["0_1_1_0"],"t":18.85,"s":[0],"e":[100]},{"t":37}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Aparar caminhos 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":75,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"dente 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[152.553,174.571,0],"ix":2},"a":{"a":0,"k":[2.5,34.346,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[2.5,2.5],[2.5,66.191]],"c":false},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.808000033509,0,0.344999994016,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Traçado 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.016],"y":[0.993]},"o":{"x":[1],"y":[-0.014]},"n":["0p016_0p993_1_-0p014"],"t":18.85,"s":[100],"e":[0]},{"t":37}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Aparar caminhos 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":75,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"garfo","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[146.389,255.725,0],"ix":2},"a":{"a":0,"k":[30.991,125.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.585,-4.361],[0,-8.218],[2.054,-18.491],[0,-14.382],[-9.077,0],[0,9.077],[2.055,18.491],[0,0],[-4.109,6.163],[-0.109,5.068],[0,0]],"o":[[0,0],[0.109,5.068],[4.109,6.163],[0,0],[-2.055,18.491],[0,9.077],[9.077,0],[0,-14.382],[-2.054,-18.491],[0,-8.218],[2.585,-4.361],[0,0],[0,0]],"v":[[-18.491,-113],[-18.491,-49.309],[-14.382,-34.927],[-6.164,-18.491],[-8.218,26.709],[-16.436,96.564],[0,113],[16.436,96.564],[8.218,26.709],[6.164,-18.491],[14.382,-34.927],[18.491,-49.309],[18.491,-113]],"c":false},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.808000033509,0,0.344999994016,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Traçado 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[30.991,125.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.884],"y":[0.022]},"n":["0p667_1_0p884_0p022"],"t":19,"s":[100],"e":[0]},{"t":40}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Aparar caminhos 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":75,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"faca","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[282.826,255.753,0],"ix":2},"a":{"a":0,"k":[116.446,124.473,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[84.5,11.171],[84.5,236.171],[302.392,236.171],[302.392,11.171]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Máscara 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-2.788,0.039],[2.055,-18.491],[0,-14.381],[-9.077,0],[0,9.078],[2.054,18.491],[0,0],[0,0],[8.218,-22.6],[2.3,-13]],"o":[[2.654,0.856],[0,0],[-2.055,18.491],[0,9.078],[9.078,0],[0,-14.381],[-2.055,-18.491],[0,0],[0,0],[-4.738,12.322],[0,0]],"v":[[-9.091,-8.424],[-0.872,-7.191],[-2.928,38.009],[-11.146,95.536],[5.29,111.973],[21.727,95.536],[13.509,38.009],[11.454,-7.191],[11.454,-111.973],[-11.146,-89.373],[-21.727,-51.302]],"c":false},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.808000033509,0,0.344999994016,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Traçado 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[198.666,124.473],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[2.5,11.445],[2.5,75.137]],"c":false},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.808000033509,0,0.344999994016,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Traçado 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":100,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":19,"s":[100],"e":[0]},{"t":40}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Aparar caminhos 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":75,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"prato int","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[41],"e":[401]},{"t":40}],"ix":10},"p":{"a":0,"k":[257.28,260.671,0],"ix":2},"a":{"a":0,"k":[73.269,73.269,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[40.327,0],[0,-40.327],[-40.327,0],[0,40.328]],"o":[[-40.327,0],[0,40.328],[40.327,0],[0,-40.327]],"v":[[0,-73.019],[-73.019,-0.001],[0,73.019],[73.019,-0.001]],"c":true},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.807843137255,0,0.345098039216,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Traçado 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[73.269,73.269],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.833],"y":[0]},"n":["0p667_1_0p833_0"],"t":0,"s":[0],"e":[100]},{"t":20}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Aparar caminhos 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":75,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"prato ext","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[-23],"e":[401]},{"t":40}],"ix":10},"p":{"a":0,"k":[257.28,260.671,0],"ix":2},"a":{"a":0,"k":[73.269,73.269,0],"ix":1},"s":{"a":0,"k":[139,139,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[40.327,0],[0,-40.327],[-40.327,0],[0,40.328]],"o":[[-40.327,0],[0,40.328],[40.327,0],[0,-40.327]],"v":[[0,-73.019],[-73.019,-0.001],[0,73.019],[73.019,-0.001]],"c":true},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.807843137255,0,0.345098039216,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Traçado 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[73.269,73.269],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.829],"y":[0]},"n":["0p667_1_0p829_0"],"t":0,"s":[100],"e":[0]},{"t":20}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Aparar caminhos 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":75,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/jolly_walker.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/jolly_walker.json deleted file mode 100644 index f2203642..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/jolly_walker.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.7","fr":60,"ip":0,"op":64,"w":1000,"h":1000,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 18","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[116,48.775,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[29,21],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.874509803922,0.472901018928,0.332656650917,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-61.5,-268.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":-5.37,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 9","parent":10,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[62,-208.226,0],"ix":2},"a":{"a":0,"k":[66,-203,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.75,-10.109],[50.39,14.18]],"o":[[2.75,10.109],[-199.5,-56.141]],"v":[[22.75,-166.25],[187,-207.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.515529318417,0.158323714312,0.56862745098,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.295640145096,0.337768345253,0.423529411765,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"NULL CONTROL","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[473.375,533.528,0],"ix":2},"a":{"a":0,"k":[60,60,0],"ix":1},"s":{"a":0,"k":[64,64,100],"ix":6}},"ao":0,"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 16","parent":10,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[112,81.633,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[45.25,43.75],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.149019607843,0.138734346278,0.129734727448,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-26.875,-228.375],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 7","parent":11,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-722.596,-191.386,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[190.549,190.549,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[0,0],[12,-54],[0,-36]],"o":[[0,0],[-13.019,58.587],[0,32.803]],"v":[[54,-76],[-36,25],[21,152]],"c":false}],"e":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-3,30],[65,155]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":10,"s":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-3,30],[65,155]],"c":false}],"e":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[21,30],[113,135]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17.5,"s":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[21,30],[113,135]],"c":false}],"e":[{"i":[[0,0],[-2.031,-21.152],[10,-25.348]],"o":[[0,0],[4,41.652],[-14.837,37.609]],"v":[[54,-76],[35,45],[157,53]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":27.5,"s":[{"i":[[0,0],[-2.031,-21.152],[10,-25.348]],"o":[[0,0],[4,41.652],[-14.837,37.609]],"v":[[54,-76],[35,45],[157,53]],"c":false}],"e":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-2,50],[92,115]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":35,"s":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-2,50],[92,115]],"c":false}],"e":[{"i":[[0,0],[20,-44.091],[22,-33.92]],"o":[[0,0],[-24.793,54.656],[-22,33.92]],"v":[[54,-76],[-27,23],[20,140]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42.5,"s":[{"i":[[0,0],[20,-44.091],[22,-33.92]],"o":[[0,0],[-24.793,54.656],[-22,33.92]],"v":[[54,-76],[-27,23],[20,140]],"c":false}],"e":[{"i":[[0,0],[11.429,-44.49],[36.429,-47.205]],"o":[[0,0],[-14.932,58.129],[-9.825,31.173]],"v":[[54,-76],[-46.429,16.143],[-59.429,144.857]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":50,"s":[{"i":[[0,0],[11.429,-44.49],[36.429,-47.205]],"o":[[0,0],[-14.932,58.129],[-9.825,31.173]],"v":[[54,-76],[-46.429,16.143],[-59.429,144.857]],"c":false}],"e":[{"i":[[0,0],[11.657,-48.294],[16.257,-68.462]],"o":[[0,0],[-14.167,58.313],[-13.895,29.104]],"v":[[54,-76],[-33.457,16.086],[-17.257,158.114]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":55,"s":[{"i":[[0,0],[11.657,-48.294],[16.257,-68.462]],"o":[[0,0],[-14.167,58.313],[-13.895,29.104]],"v":[[54,-76],[-33.457,16.086],[-17.257,158.114]],"c":false}],"e":[{"i":[[0,0],[12,-54],[0,-36]],"o":[[0,0],[-13.019,58.587],[0,32.803]],"v":[[54,-76],[-36,25],[21,152]],"c":false}]},{"t":62.5}],"ix":2,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').content('Path 1').path;"},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":88,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.980392156863,0.792156862745,0.627450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":38,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-34.433,21.811],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[0,0],[12,-54],[0,-36]],"o":[[0,0],[-13.019,58.587],[0,32.803]],"v":[[54,-76],[-36,25],[21,152]],"c":false}],"e":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-3,30],[65,155]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":10,"s":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-3,30],[65,155]],"c":false}],"e":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[21,30],[113,135]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17.5,"s":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[21,30],[113,135]],"c":false}],"e":[{"i":[[0,0],[-2.031,-21.152],[10,-25.348]],"o":[[0,0],[4,41.652],[-14.837,37.609]],"v":[[54,-76],[35,45],[157,53]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":27.5,"s":[{"i":[[0,0],[-2.031,-21.152],[10,-25.348]],"o":[[0,0],[4,41.652],[-14.837,37.609]],"v":[[54,-76],[35,45],[157,53]],"c":false}],"e":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-2,50],[92,115]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":35,"s":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-2,50],[92,115]],"c":false}],"e":[{"i":[[0,0],[20,-44.091],[22,-33.92]],"o":[[0,0],[-24.793,54.656],[-22,33.92]],"v":[[54,-76],[-27,23],[20,140]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42.5,"s":[{"i":[[0,0],[20,-44.091],[22,-33.92]],"o":[[0,0],[-24.793,54.656],[-22,33.92]],"v":[[54,-76],[-27,23],[20,140]],"c":false}],"e":[{"i":[[0,0],[11.429,-44.49],[36.429,-47.205]],"o":[[0,0],[-14.932,58.129],[-9.825,31.173]],"v":[[54,-76],[-46.429,16.143],[-59.429,144.857]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":50,"s":[{"i":[[0,0],[11.429,-44.49],[36.429,-47.205]],"o":[[0,0],[-14.932,58.129],[-9.825,31.173]],"v":[[54,-76],[-46.429,16.143],[-59.429,144.857]],"c":false}],"e":[{"i":[[0,0],[11.657,-48.294],[16.257,-68.462]],"o":[[0,0],[-14.167,58.313],[-13.895,29.104]],"v":[[54,-76],[-33.457,16.086],[-17.257,158.114]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":55,"s":[{"i":[[0,0],[11.657,-48.294],[16.257,-68.462]],"o":[[0,0],[-14.167,58.313],[-13.895,29.104]],"v":[[54,-76],[-33.457,16.086],[-17.257,158.114]],"c":false}],"e":[{"i":[[0,0],[12,-54],[0,-36]],"o":[[0,0],[-13.019,58.587],[0,32.803]],"v":[[54,-76],[-36,25],[21,152]],"c":false}]},{"t":62.5}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.3505421358,0.408821913775,0.513725490196,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":38,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-34.433,21.811],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 13","parent":10,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[114.5,60.633,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[81,-30.5],[1,-55],[4.822,26.865],[12,-3.5]],"o":[[17,0.5],[-1,55],[-3.5,-19.5],[-12.517,3.651]],"v":[[26,-151],[90.5,-115],[134,-114],[103.5,-116]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.980392156863,0.792156862745,0.627450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.333333333333,0.302657961378,0.275817003437,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 15","parent":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.5,-15.534,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[7,9],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.980392156863,0.792156862745,0.627450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.066666666667,0.06220479853,0.058300654093,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[29.75,-136.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Shape Layer 17","parent":4,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,-15.876,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[0,0],[-46,-106],[-1,-39],[0.333,-16.457]],"o":[[0,0],[19.372,44.64],[1,39],[-0.264,13.036]],"v":[[-46.5,-199.5],[-26,-73],[-74,-17],[-55,62]],"c":false}],"e":[{"i":[[0,0],[-45,-76.444],[-1,-39],[-7,-11]],"o":[[0,0],[48.57,82.508],[1,39],[7,11]],"v":[[-46.5,-199.5],[-34,-69],[-87,3],[-55,52.667]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":16,"s":[{"i":[[0,0],[-45,-76.444],[-1,-39],[-7,-11]],"o":[[0,0],[48.57,82.508],[1,39],[7,11]],"v":[[-46.5,-199.5],[-34,-69],[-87,3],[-55,52.667]],"c":false}],"e":[{"i":[[0,0],[-45.25,-83.833],[-1,-39],[-7,-11]],"o":[[0,0],[53,114.666],[1,39],[7,11]],"v":[[-46.5,-199.5],[-32,-70],[-83.75,-2],[-56,47]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":28,"s":[{"i":[[0,0],[-45.25,-83.833],[-1,-39],[-7,-11]],"o":[[0,0],[53,114.666],[1,39],[7,11]],"v":[[-46.5,-199.5],[-32,-70],[-83.75,-2],[-56,47]],"c":false}],"e":[{"i":[[0,0],[-46,-106],[-1,-39],[7.333,-21.791]],"o":[[0,0],[19.372,44.64],[1,39],[-4.159,12.357]],"v":[[-46.5,-199.5],[-26,-73],[-74,-17],[-54.667,62]],"c":false}]},{"t":64}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Smoke","sr":1,"ks":{"o":{"a":0,"k":80,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[500,500,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[112.981,9.615],[-55.288,-84.135],[31.25,-50.481],[-21.635,-103.365],[0,0],[-60.096,2.404],[36.058,33.654],[-36.058,48.077]],"o":[[-112.981,-9.615],[55.288,84.135],[-31.25,50.481],[21.635,103.365],[0,0],[60.096,-2.404],[-36.058,-33.654],[36.058,-48.077]],"v":[[242.788,-550.481],[55.288,-444.712],[144.231,-322.115],[91.346,-230.769],[114.192,-111.808],[170.673,-230.769],[199.519,-341.346],[225.962,-432.692]],"c":true}],"e":[{"i":[[112.981,9.615],[-96.264,-29.473],[57.824,13.462],[-21.635,-103.365],[0,0],[-48.542,-35.51],[36.058,33.654],[-36.058,48.077]],"o":[[-112.981,-9.615],[80.712,24.712],[-68.231,-15.885],[21.635,103.365],[0,0],[39.327,28.769],[-36.058,-33.654],[36.058,-48.077]],"v":[[242.788,-550.481],[55.288,-444.712],[144.231,-322.115],[91.346,-230.769],[114.192,-80.808],[154.673,-258.769],[201.519,-387.346],[229.962,-470.692]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":8,"s":[{"i":[[112.981,9.615],[-96.264,-29.473],[57.824,13.462],[-21.635,-103.365],[0,0],[-48.542,-35.51],[36.058,33.654],[-36.058,48.077]],"o":[[-112.981,-9.615],[80.712,24.712],[-68.231,-15.885],[21.635,103.365],[0,0],[39.327,28.769],[-36.058,-33.654],[36.058,-48.077]],"v":[[242.788,-550.481],[55.288,-444.712],[144.231,-322.115],[91.346,-230.769],[114.192,-80.808],[154.673,-258.769],[201.519,-387.346],[229.962,-470.692]],"c":true}],"e":[{"i":[[112.981,9.615],[-87.484,-41.186],[41.769,-49.885],[0.654,-89.231],[0,0],[-62.101,24.769],[26.909,45.489],[-2.598,62.232]],"o":[[-112.981,-9.615],[75.264,37.445],[-64.231,34.115],[-0.774,105.602],[0,0],[51.899,-21.231],[-25.112,-42.451],[0.896,-21.451]],"v":[[242.788,-550.481],[33.288,-480.712],[112.231,-358.115],[109.346,-230.769],[114.192,-111.808],[158.101,-346.769],[189.091,-441.489],[297.104,-496.549]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[{"i":[[112.981,9.615],[-87.484,-41.186],[41.769,-49.885],[0.654,-89.231],[0,0],[-62.101,24.769],[26.909,45.489],[-2.598,62.232]],"o":[[-112.981,-9.615],[75.264,37.445],[-64.231,34.115],[-0.774,105.602],[0,0],[51.899,-21.231],[-25.112,-42.451],[0.896,-21.451]],"v":[[242.788,-550.481],[33.288,-480.712],[112.231,-358.115],[109.346,-230.769],[114.192,-111.808],[158.101,-346.769],[189.091,-441.489],[297.104,-496.549]],"c":true}],"e":[{"i":[[112.981,9.615],[-78.703,-52.9],[50.042,-32.703],[-3.126,-89.638],[0,0],[-53.494,-19.261],[103.637,2.208],[-57.183,4.784]],"o":[[-112.981,-9.615],[69.816,50.179],[-54.958,42.297],[5.338,104.992],[0,0],[131.178,5.041],[-45.661,-7.411],[49.753,-19.593]],"v":[[118.788,-608.481],[13.288,-504.893],[126.958,-456.297],[102.437,-230.769],[109.192,-104.808],[217.53,-428.769],[217.026,-526.541],[342.247,-542.407]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":32,"s":[{"i":[[112.981,9.615],[-78.703,-52.9],[50.042,-32.703],[-3.126,-89.638],[0,0],[-53.494,-19.261],[103.637,2.208],[-57.183,4.784]],"o":[[-112.981,-9.615],[69.816,50.179],[-54.958,42.297],[5.338,104.992],[0,0],[131.178,5.041],[-45.661,-7.411],[49.753,-19.593]],"v":[[118.788,-608.481],[13.288,-504.893],[126.958,-456.297],[102.437,-230.769],[109.192,-104.808],[217.53,-428.769],[217.026,-526.541],[342.247,-542.407]],"c":true}],"e":[{"i":[[112.981,9.615],[-69.923,-64.613],[36.032,-50.21],[-11.503,-96.941],[0,0],[-55.97,-11.137],[42.808,17.215],[-49.261,21.019]],"o":[[-112.981,-9.615],[34.962,26.325],[-46.241,43.042],[11.449,104.382],[0,0],[59.791,-10.481],[-42.06,-17.252],[46.571,-21.492]],"v":[[242.788,-550.481],[-8.962,-482.325],[146.435,-431.729],[99.528,-230.769],[114.192,-80.808],[174.209,-325.519],[220.711,-395.843],[317.89,-488.764]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":44,"s":[{"i":[[112.981,9.615],[-69.923,-64.613],[36.032,-50.21],[-11.503,-96.941],[0,0],[-55.97,-11.137],[42.808,17.215],[-49.261,21.019]],"o":[[-112.981,-9.615],[34.962,26.325],[-46.241,43.042],[11.449,104.382],[0,0],[59.791,-10.481],[-42.06,-17.252],[46.571,-21.492]],"v":[[242.788,-550.481],[-8.962,-482.325],[146.435,-431.729],[99.528,-230.769],[114.192,-80.808],[174.209,-325.519],[220.711,-395.843],[317.89,-488.764]],"c":true}],"e":[{"i":[[112.981,9.615],[-61.142,-76.326],[-60.613,-54.039],[12.381,-73.231],[0,0],[-60.087,14.469],[38.758,27.078],[-33.533,19.121]],"o":[[-112.981,-9.615],[52.912,36.257],[58.387,63.961],[-3.619,30.769],[0,0],[63.913,-24.531],[-27.996,-27.255],[48.467,-34.879]],"v":[[242.788,-550.481],[29.588,-459.757],[157.613,-402.961],[123.619,-244.769],[116.192,-125.808],[208.087,-297.469],[213.496,-414.245],[295.533,-471.121]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":56,"s":[{"i":[[112.981,9.615],[-61.142,-76.326],[-60.613,-54.039],[12.381,-73.231],[0,0],[-60.087,14.469],[38.758,27.078],[-33.533,19.121]],"o":[[-112.981,-9.615],[52.912,36.257],[58.387,63.961],[-3.619,30.769],[0,0],[63.913,-24.531],[-27.996,-27.255],[48.467,-34.879]],"v":[[242.788,-550.481],[29.588,-459.757],[157.613,-402.961],[123.619,-244.769],[116.192,-125.808],[208.087,-297.469],[213.496,-414.245],[295.533,-471.121]],"c":true}],"e":[{"i":[[112.981,9.615],[-55.288,-84.135],[31.25,-50.481],[-21.635,-103.365],[0,0],[-60.096,2.404],[36.058,33.654],[-36.058,48.077]],"o":[[-112.981,-9.615],[55.288,84.135],[-31.25,50.481],[21.635,103.365],[0,0],[60.096,-2.404],[-36.058,-33.654],[36.058,-48.077]],"v":[[242.788,-550.481],[55.288,-444.712],[144.231,-322.115],[91.346,-230.769],[114.192,-120.808],[170.673,-230.769],[199.519,-341.346],[225.962,-432.692]],"c":true}]},{"t":64}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.980392156863,0.792156862745,0.627450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.639215686275,0.572369624119,0.513879274854,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Shape Layer 6","parent":11,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[-734.029,-245.947,0],"e":[-734.029,-219.947,0],"to":[0,4.33333349227905,0],"ti":[0,-0.16666667163372,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":10,"s":[-734.029,-219.947,0],"e":[-734.029,-244.947,0],"to":[0,0.16666667163372,0],"ti":[0,-0.66666668653488,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":25,"s":[-734.029,-244.947,0],"e":[-734.029,-215.947,0],"to":[0,0.66666668653488,0],"ti":[0,0.16666667163372,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42.5,"s":[-734.029,-215.947,0],"e":[-734.029,-245.947,0],"to":[0,-0.16666667163372,0],"ti":[0,5,0]},{"t":62.5}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[190.549,190.549,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[86,46],[0,81.5]],"o":[[5.25,65.5],[-13.5,23.75]],"v":[[21.75,-128.617],[187.5,-124.617]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.462745008282,0.11613999909,0.11613999909,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.839215686275,0.488893965179,0.075693960751,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 5","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.462745008282,0.11613999909,0.11613999909,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039215686,0.369550158931,0.369550158931,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 4","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[14,12],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.462745008282,0.11613999909,0.11613999909,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.202591765161,0.294117647059,0.184544417437,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[149,-145.016],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 2","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[26,22],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.462745008282,0.11613999909,0.11613999909,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.294117647059,0.18431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[83,-147.016],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[90,10],[-112,-29]],"o":[[-76.632,-8.515],[183,31]],"v":[[103,-245],[75,-101]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.462745008282,0.11613999909,0.11613999909,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.980392156863,0.793133844114,0.6266820571,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[8,10],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[93.244,89.796],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 3","np":3,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Shape Layer 5","parent":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-534,-91.727,0],"ix":2},"a":{"a":0,"k":[-534,-93,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-53.354,-5.716],[11.433,4.764]],"o":[[0,0],[53.354,5.716],[-11.433,-4.764]],"v":[[-593.975,-391.175],[-512.039,-350.208],[-472.024,-394.987]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.462745098039,0.116139939252,0.116139939252,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.819607843137,0.634472895604,0.472479816512,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 3","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-70.621,-35.311],[0,0],[53.354,102.896]],"o":[[60.976,30.488],[0,0],[-53.354,-102.896]],"v":[[-612.077,-360.852],[-406.285,-183.642],[-432.961,-362.757]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.462745098039,0.116139939252,0.116139939252,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.820607503255,0.90875453575,0.909803921569,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[156.945,-46.504],[-81.707,-337.869],[-82.422,-4.303],[-8.438,24.609]],"o":[[-47.894,-0.995],[142.121,77.797],[103.681,2.048],[36.658,-97.977]],"v":[[-541.317,-407.522],[-758.009,-69.107],[-472.491,14.264],[-337.506,-50.217]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.462745098039,0.116139939252,0.116139939252,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.25731640984,0.296602675494,0.36862745098,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0.635],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.462745098039,0.116139939252,0.116139939252,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.25731640984,0.296602675494,0.36862745098,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Shape Layer 4","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.64,"y":1},"o":{"x":0.36,"y":0},"n":"0p64_1_0p36_0","t":0,"s":[90.625,22.472,0],"e":[90.625,69.472,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.64,"y":1},"o":{"x":0.36,"y":0},"n":"0p64_1_0p36_0","t":10,"s":[90.625,69.472,0],"e":[90.625,1.14,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.64,"y":1},"o":{"x":0.36,"y":0},"n":"0p64_1_0p36_0","t":25,"s":[90.625,1.14,0],"e":[90.625,22.472,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.64,"y":1},"o":{"x":0.36,"y":0},"n":"0p64_1_0p36_0","t":32.5,"s":[90.625,22.472,0],"e":[90.625,69.472,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.64,"y":1},"o":{"x":0.36,"y":0},"n":"0p64_1_0p36_0","t":40,"s":[90.625,69.472,0],"e":[90.625,1.14,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.64,"y":1},"o":{"x":0.36,"y":0},"n":"0p64_1_0p36_0","t":55,"s":[90.625,1.14,0],"e":[90.625,22.472,0],"to":[0,0,0],"ti":[0,-3.55530524253845,0]},{"t":62.5}],"ix":2},"a":{"a":0,"k":[-534,-71,0],"ix":1},"s":{"a":0,"k":[82,82,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[79.512,-28.718],[128.927,-3.537],[-105.08,0],[-2.52,105.05]],"o":[[-104.42,37.713],[-2.52,105.05],[105.08,0],[-117.463,-15.766]],"v":[[19.512,30.024],[-216.488,6.098],[0,209],[210.39,8.537]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.462745098039,0.116139939252,0.116139939252,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.698039215686,0.369550158931,0.369550158931,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-544,-76],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Shape Layer 2","parent":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-632.018,37.043,0],"ix":2},"a":{"a":0,"k":[-60,14,0],"ix":1},"s":{"a":0,"k":[121.951,121.951,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.698039215686,0.36862745098,0.36862745098,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":60,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 3","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[-211.78,-154.468],[58.25,-115.367]],"o":[[202.25,147.517],[0,0]],"v":[[-90,-8.717],[-32,356.915]],"c":false}],"e":[{"i":[[-133.513,-186.523],[173.558,-170.346]],"o":[[111.25,101.551],[-158.442,143.306]],"v":[[-90,-8.717],[-76.308,313.653]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":10,"s":[{"i":[[-133.513,-186.523],[173.558,-170.346]],"o":[[111.25,101.551],[-158.442,143.306]],"v":[[-90,-8.717],[-76.308,313.653]],"c":false}],"e":[{"i":[[-55.245,-218.577],[164.087,-143.863]],"o":[[57.635,179.132],[-150.018,116.536]],"v":[[-90,-8.717],[-170.15,338.802]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[{"i":[[-55.245,-218.577],[164.087,-143.863]],"o":[[57.635,179.132],[-150.018,116.536]],"v":[[-90,-8.717],[-170.15,338.802]],"c":false}],"e":[{"i":[[-16.111,-234.604],[138.952,-127.777]],"o":[[21.481,187.035],[-125.216,98.487]],"v":[[-90,-22.8],[-191.59,327.852]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":25,"s":[{"i":[[-16.111,-234.604],[138.952,-127.777]],"o":[[21.481,187.035],[-125.216,98.487]],"v":[[-90,-22.8],[-191.59,327.852]],"c":false}],"e":[{"i":[[-65.833,-253.727],[124.101,-98.778]],"o":[[49.727,191.652],[-57.787,45.995]],"v":[[-90,-8.717],[-201.875,297.204]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":32,"s":[{"i":[[-65.833,-253.727],[124.101,-98.778]],"o":[[49.727,191.652],[-57.787,45.995]],"v":[[-90,-8.717],[-201.875,297.204]],"c":false}],"e":[{"i":[[-21.003,-232.601],[107.195,-65.321]],"o":[[99.25,220.522],[-193.086,117.66]],"v":[[-90,-8.717],[-190.937,279.009]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":40,"s":[{"i":[[-21.003,-232.601],[107.195,-65.321]],"o":[[99.25,220.522],[-193.086,117.66]],"v":[[-90,-8.717],[-190.937,279.009]],"c":false}],"e":[{"i":[[-148.188,-180.512],[224.852,-167.321]],"o":[[140.352,98.004],[-61.947,30.61]],"v":[[-90,-8.717],[-40.125,310.123]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":55,"s":[{"i":[[-148.188,-180.512],[224.852,-167.321]],"o":[[140.352,98.004],[-61.947,30.61]],"v":[[-90,-8.717],[-40.125,310.123]],"c":false}],"e":[{"i":[[-211.78,-154.468],[58.25,-115.367]],"o":[[202.25,147.517],[0,0]],"v":[[-90,-8.717],[-32,356.915]],"c":false}]},{"t":64}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.698039233685,0.368627458811,0.368627458811,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":84,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[6,-3.125],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,110.951],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[-211.78,-154.468],[58.25,-115.367]],"o":[[202.25,147.517],[0,0]],"v":[[-90,-8.717],[-32,356.915]],"c":false}],"e":[{"i":[[-55.245,-218.577],[164.087,-143.863]],"o":[[57.635,179.132],[-150.018,116.536]],"v":[[-90,-8.717],[-170.15,338.802]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[{"i":[[-55.245,-218.577],[164.087,-143.863]],"o":[[57.635,179.132],[-150.018,116.536]],"v":[[-90,-8.717],[-170.15,338.802]],"c":false}],"e":[{"i":[[-16.111,-234.604],[138.952,-127.777]],"o":[[21.481,187.035],[-125.216,98.487]],"v":[[-90,-22.8],[-191.59,327.852]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":25,"s":[{"i":[[-16.111,-234.604],[138.952,-127.777]],"o":[[21.481,187.035],[-125.216,98.487]],"v":[[-90,-22.8],[-191.59,327.852]],"c":false}],"e":[{"i":[[42.589,-258.645],[101.25,-103.65]],"o":[[-32.75,198.891],[-51.609,52.833]],"v":[[-90,-8.717],[-201.875,297.204]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":32,"s":[{"i":[[42.589,-258.645],[101.25,-103.65]],"o":[[-32.75,198.891],[-51.609,52.833]],"v":[[-90,-8.717],[-201.875,297.204]],"c":false}],"e":[{"i":[[-21.003,-232.601],[107.195,-65.321]],"o":[[99.25,220.522],[-193.086,117.66]],"v":[[-90,-8.717],[-190.937,279.009]],"c":false}]},{"t":40}],"ix":2,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').content('Path 1').path;"},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":100,"ix":1},"e":{"a":0,"k":82,"ix":2},"o":{"a":0,"k":3,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.301545565736,0.301545565736,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":85,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[6,-3.125],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,110.951],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":4,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Shape Layer 1","parent":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-518.22,-17.104,0],"ix":2},"a":{"a":0,"k":[-15,0,0],"ix":1},"s":{"a":0,"k":[121.951,121.951,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[0,0],[90.037,-113.557]],"o":[[0,0],[-9.963,20.23]],"v":[[-14,-0.605],[-155.438,325.087]],"c":false}],"e":[{"i":[[0,0],[297.769,-151.903]],"o":[[0,0],[-379.918,193.811]],"v":[[-14,-0.605],[-156.769,291.605]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":12,"s":[{"i":[[0,0],[297.769,-151.903]],"o":[[0,0],[-379.918,193.811]],"v":[[-14,-0.605],[-156.769,291.605]],"c":false}],"e":[{"i":[[-90.055,-74.065],[232.29,-219.388]],"o":[[112.662,92.658],[-307.839,225.975]],"v":[[-14,-0.605],[33.559,333.973]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":24,"s":[{"i":[[-90.055,-74.065],[232.29,-219.388]],"o":[[112.662,92.658],[-307.839,225.975]],"v":[[-14,-0.605],[33.559,333.973]],"c":false}],"e":[{"i":[[-38.901,-103.432],[102.224,-185.126]],"o":[[97.037,74.012],[-206.978,304.292]],"v":[[-14,-0.605],[74.562,328.242]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":40,"s":[{"i":[[-38.901,-103.432],[102.224,-185.126]],"o":[[97.037,74.012],[-206.978,304.292]],"v":[[-14,-0.605],[74.562,328.242]],"c":false}],"e":[{"i":[[0,0],[196.5,-285.56]],"o":[[0,0],[-196.5,285.56]],"v":[[-14,-0.605],[-154.125,358.267]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":55,"s":[{"i":[[0,0],[196.5,-285.56]],"o":[[0,0],[-196.5,285.56]],"v":[[-14,-0.605],[-154.125,358.267]],"c":false}],"e":[{"i":[[0,0],[128.141,-141.768]],"o":[[0,0],[-72.142,108.673]],"v":[[-14,-0.605],[-160.729,329.106]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":61,"s":[{"i":[[0,0],[128.141,-141.768]],"o":[[0,0],[-72.142,108.673]],"v":[[-14,-0.605],[-160.729,329.106]],"c":false}],"e":[{"i":[[0,0],[90.037,-113.557]],"o":[[0,0],[-9.963,20.23]],"v":[[-14,-0.605],[-155.438,325.087]],"c":false}]},{"t":64}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.564705908298,0.325536340475,0.325536340475,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":84,"ix":5},"lc":1,"lj":1,"ml":1,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,110.951],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-38.901,-103.432],[160.037,-206.954]],"o":[[97.037,74.012],[-206.978,304.292]],"v":[[-14,-0.605],[74.562,328.242]],"c":false},"ix":2,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').content('Path 1').path;"},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":100,"ix":1},"e":{"a":0,"k":82,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.298039227724,0.257131874561,0.257131874561,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":83,"ix":5},"lc":2,"lj":1,"ml":1,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,110.951],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.462745098039,0.116139939252,0.116139939252,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":21,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Shape Layer 11","parent":11,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-473.929,-195.197,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[190.549,190.549,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-2.031,-21.152],[10,-25.348]],"o":[[0,0],[4,41.652],[-14.837,37.609]],"v":[[54,-76],[35,45],[157,53]],"c":false},"ix":2,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').content('Path 1').path;"},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":87,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.980392158031,0.792156875134,0.627451002598,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":34,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-23,18],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":37.5,"s":[{"i":[[0,0],[12,-54],[0,-36]],"o":[[0,0],[-13.019,58.587],[0,32.803]],"v":[[54,-76],[-36,25],[21,152]],"c":false}],"e":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-3,30],[65,155]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":47.5,"s":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-3,30],[65,155]],"c":false}],"e":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[21,30],[113,135]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":55,"s":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[21,30],[113,135]],"c":false}],"e":[{"i":[[0,0],[-0.628,-24.436],[11.2,-26.205]],"o":[[0,0],[2.298,43.346],[-15.553,37.24]],"v":[[53.75,-76],[33.35,43.5],[152.35,61.2]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":64,"s":[{"i":[[0,0],[-0.628,-24.436],[11.2,-26.205]],"o":[[0,0],[2.298,43.346],[-15.553,37.24]],"v":[[53.75,-76],[33.35,43.5],[152.35,61.2]],"c":false}],"e":[{"i":[[0,0],[-2.031,-21.152],[10,-25.348]],"o":[[0,0],[4,41.652],[-14.837,37.609]],"v":[[54,-76],[35,45],[157,53]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":65,"s":[{"i":[[0,0],[-2.031,-21.152],[10,-25.348]],"o":[[0,0],[4,41.652],[-14.837,37.609]],"v":[[54,-76],[35,45],[157,53]],"c":false}],"e":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-2,50],[92,115]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":72.5,"s":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-2,50],[92,115]],"c":false}],"e":[{"i":[[0,0],[20,-44.091],[22,-33.92]],"o":[[0,0],[-24.793,54.656],[-22,33.92]],"v":[[54,-76],[-27,23],[20,140]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":80,"s":[{"i":[[0,0],[20,-44.091],[22,-33.92]],"o":[[0,0],[-24.793,54.656],[-22,33.92]],"v":[[54,-76],[-27,23],[20,140]],"c":false}],"e":[{"i":[[0,0],[11.429,-44.49],[36.429,-47.205]],"o":[[0,0],[-14.932,58.129],[-9.825,31.173]],"v":[[54,-76],[-46.429,16.143],[-59.429,144.857]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":87.5,"s":[{"i":[[0,0],[11.429,-44.49],[36.429,-47.205]],"o":[[0,0],[-14.932,58.129],[-9.825,31.173]],"v":[[54,-76],[-46.429,16.143],[-59.429,144.857]],"c":false}],"e":[{"i":[[0,0],[11.657,-48.294],[16.257,-68.462]],"o":[[0,0],[-14.167,58.313],[-13.895,29.104]],"v":[[54,-76],[-33.457,16.086],[-17.257,158.114]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":92.5,"s":[{"i":[[0,0],[11.657,-48.294],[16.257,-68.462]],"o":[[0,0],[-14.167,58.313],[-13.895,29.104]],"v":[[54,-76],[-33.457,16.086],[-17.257,158.114]],"c":false}],"e":[{"i":[[0,0],[12,-54],[0,-36]],"o":[[0,0],[-13.019,58.587],[0,32.803]],"v":[[54,-76],[-36,25],[21,152]],"c":false}]},{"t":100}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.3505421358,0.408821913775,0.513725490196,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":34,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-23,18],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":98,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":37.5,"op":637.5,"st":37.5,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Shape Layer 10","parent":11,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[100],"e":[0]},{"t":37.5}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-467.26,-195.197,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[190.549,190.549,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-25,"s":[{"i":[[0,0],[12,-54],[0,-36]],"o":[[0,0],[-13.019,58.587],[0,32.803]],"v":[[54,-76],[-36,25],[21,152]],"c":false}],"e":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-3,30],[65,155]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-15,"s":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-3,30],[65,155]],"c":false}],"e":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[21,30],[113,135]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-7.5,"s":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[21,30],[113,135]],"c":false}],"e":[{"i":[[0,0],[-2.031,-21.152],[10,-25.348]],"o":[[0,0],[4,41.652],[-14.837,37.609]],"v":[[54,-76],[35,45],[157,53]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":2.5,"s":[{"i":[[0,0],[-2.031,-21.152],[10,-25.348]],"o":[[0,0],[4,41.652],[-14.837,37.609]],"v":[[54,-76],[35,45],[157,53]],"c":false}],"e":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-2,50],[92,115]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":10,"s":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-2,50],[92,115]],"c":false}],"e":[{"i":[[0,0],[20,-44.091],[22,-33.92]],"o":[[0,0],[-24.793,54.656],[-22,33.92]],"v":[[54,-76],[-27,23],[20,140]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17.5,"s":[{"i":[[0,0],[20,-44.091],[22,-33.92]],"o":[[0,0],[-24.793,54.656],[-22,33.92]],"v":[[54,-76],[-27,23],[20,140]],"c":false}],"e":[{"i":[[0,0],[11.429,-44.49],[36.429,-47.205]],"o":[[0,0],[-14.932,58.129],[-9.825,31.173]],"v":[[54,-76],[-46.429,16.143],[-59.429,144.857]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":25,"s":[{"i":[[0,0],[11.429,-44.49],[36.429,-47.205]],"o":[[0,0],[-14.932,58.129],[-9.825,31.173]],"v":[[54,-76],[-46.429,16.143],[-59.429,144.857]],"c":false}],"e":[{"i":[[0,0],[11.657,-48.294],[16.257,-68.462]],"o":[[0,0],[-14.167,58.313],[-13.895,29.104]],"v":[[54,-76],[-33.457,16.086],[-17.257,158.114]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":30,"s":[{"i":[[0,0],[11.657,-48.294],[16.257,-68.462]],"o":[[0,0],[-14.167,58.313],[-13.895,29.104]],"v":[[54,-76],[-33.457,16.086],[-17.257,158.114]],"c":false}],"e":[{"i":[[0,0],[12,-54],[0,-36]],"o":[[0,0],[-13.019,58.587],[0,32.803]],"v":[[54,-76],[-36,25],[21,152]],"c":false}]},{"t":37.5}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":89,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.980392158031,0.792156875134,0.627451002598,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":34,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-33.48,18],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-25,"s":[{"i":[[0,0],[12,-54],[0,-36]],"o":[[0,0],[-13.019,58.587],[0,32.803]],"v":[[54,-76],[-36,25],[21,152]],"c":false}],"e":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-3,30],[65,155]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-15,"s":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-3,30],[65,155]],"c":false}],"e":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[21,30],[113,135]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-7.5,"s":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[21,30],[113,135]],"c":false}],"e":[{"i":[[0,0],[-2.031,-21.152],[10,-25.348]],"o":[[0,0],[4,41.652],[-14.837,37.609]],"v":[[54,-76],[35,45],[157,53]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":2.5,"s":[{"i":[[0,0],[-2.031,-21.152],[10,-25.348]],"o":[[0,0],[4,41.652],[-14.837,37.609]],"v":[[54,-76],[35,45],[157,53]],"c":false}],"e":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-2,50],[92,115]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":10,"s":[{"i":[[0,0],[12,-54],[22,-33.92]],"o":[[0,0],[-13.019,58.587],[-22,33.92]],"v":[[54,-76],[-2,50],[92,115]],"c":false}],"e":[{"i":[[0,0],[20,-44.091],[22,-33.92]],"o":[[0,0],[-24.793,54.656],[-22,33.92]],"v":[[54,-76],[-27,23],[20,140]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17.5,"s":[{"i":[[0,0],[20,-44.091],[22,-33.92]],"o":[[0,0],[-24.793,54.656],[-22,33.92]],"v":[[54,-76],[-27,23],[20,140]],"c":false}],"e":[{"i":[[0,0],[11.429,-44.49],[36.429,-47.205]],"o":[[0,0],[-14.932,58.129],[-9.825,31.173]],"v":[[54,-76],[-46.429,16.143],[-59.429,144.857]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":25,"s":[{"i":[[0,0],[11.429,-44.49],[36.429,-47.205]],"o":[[0,0],[-14.932,58.129],[-9.825,31.173]],"v":[[54,-76],[-46.429,16.143],[-59.429,144.857]],"c":false}],"e":[{"i":[[0,0],[11.657,-48.294],[16.257,-68.462]],"o":[[0,0],[-14.167,58.313],[-13.895,29.104]],"v":[[54,-76],[-33.457,16.086],[-17.257,158.114]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":30,"s":[{"i":[[0,0],[11.657,-48.294],[16.257,-68.462]],"o":[[0,0],[-14.167,58.313],[-13.895,29.104]],"v":[[54,-76],[-33.457,16.086],[-17.257,158.114]],"c":false}],"e":[{"i":[[0,0],[12,-54],[0,-36]],"o":[[0,0],[-13.019,58.587],[0,32.803]],"v":[[54,-76],[-36,25],[21,152]],"c":false}]},{"t":37.5}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.3505421358,0.408821913775,0.513725490196,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":34,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-33.48,18],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-25,"op":575,"st":-25,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Shape Layer 21","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[500,500,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[819.189,10],"ix":2},"p":{"a":0,"k":[0,40],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.498039215686,0.473137260886,0.462883504232,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[3,-269],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[214.09,100],"ix":3},"r":{"a":0,"k":17,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 3","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[819.189,25],"ix":2},"p":{"a":0,"k":[0,40],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.364705882353,0.328235312069,0.313218000823,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-1,-263],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[214.09,100],"ix":3},"r":{"a":0,"k":17,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 2","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[819.189,10],"ix":2},"p":{"a":0,"k":[0,40],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.498039215686,0.474509803922,0.462745098039,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2.5,-175],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[214.09,100],"ix":3},"r":{"a":0,"k":17,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 4","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[819.189,25],"ix":2},"p":{"a":0,"k":[0,40],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.364705882353,0.329411764706,0.313725490196,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-3,-167],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[214.09,100],"ix":3},"r":{"a":0,"k":17,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Shape Layer 20","parent":20,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-33.339,76.282,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":2,"s":{"a":0,"k":[53.057,259],"ix":2},"p":{"a":0,"k":[0,14],"ix":3},"r":{"a":0,"k":36,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.4,0.347681681315,0.329411764706,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"rp","c":{"a":0,"k":45,"ix":1},"o":{"a":0,"k":-14,"ix":2},"m":1,"ix":4,"tr":{"ty":"tr","p":{"a":0,"k":[99,30],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":4},"so":{"a":0,"k":100,"ix":5},"eo":{"a":0,"k":100,"ix":6},"nm":"Transform"},"nm":"Repeater 1","mn":"ADBE Vector Filter - Repeater","hd":false},{"ty":"tr","p":{"a":0,"k":[-513,-315],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[75,100],"ix":3},"r":{"a":0,"k":-6,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":4,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 2","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"rc","d":2,"s":{"a":0,"k":[53.057,259],"ix":2},"p":{"a":0,"k":[0,14],"ix":3},"r":{"a":0,"k":36,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.592156887054,0.511262953281,0.483014255762,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"rp","c":{"a":0,"k":45,"ix":1},"o":{"a":0,"k":-14,"ix":2},"m":1,"ix":4,"tr":{"ty":"tr","p":{"a":0,"k":[99,30],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":4},"so":{"a":0,"k":100,"ix":5},"eo":{"a":0,"k":100,"ix":6},"nm":"Transform"},"nm":"Repeater 1","mn":"ADBE Vector Filter - Repeater","hd":false},{"ty":"tr","p":{"a":0,"k":[-506,-317],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[75,100],"ix":3},"r":{"a":0,"k":-6,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":4,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"Shape Layer 12","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[484,827,0],"ix":2},"a":{"a":0,"k":[-55,362,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.859,0.859,1.183]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,-0.183]},"n":["0p833_0p859_0p167_0p167","0p833_0p859_0p167_0p167","0p833_1p183_0p167_-0p183"],"t":0,"s":[83,83,100],"e":[74,74,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.873,0.873,1.796]},"o":{"x":[0.167,0.167,0.167],"y":[0.128,0.128,-0.796]},"n":["0p833_0p873_0p167_0p128","0p833_0p873_0p167_0p128","0p833_1p796_0p167_-0p796"],"t":12,"s":[74,74,100],"e":[85,85,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.856,0.856,0.651]},"o":{"x":[0.167,0.167,0.167],"y":[0.142,0.142,0.349]},"n":["0p833_0p856_0p167_0p142","0p833_0p856_0p167_0p142","0p833_0p651_0p167_0p349"],"t":24,"s":[85,85,100],"e":[75,75,100]},{"i":{"x":[0.77,0.77,0.833],"y":[0.809,0.809,0.97]},"o":{"x":[0.186,0.186,0.167],"y":[0.154,0.154,0.03]},"n":["0p77_0p809_0p186_0p154","0p77_0p809_0p186_0p154","0p833_0p97_0p167_0p03"],"t":40,"s":[75,75,100],"e":[87,87,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.868,0.868,0.607]},"o":{"x":[0.167,0.167,0.167],"y":[0.135,0.135,0.393]},"n":["0p833_0p868_0p167_0p135","0p833_0p868_0p167_0p135","0p833_0p607_0p167_0p393"],"t":56,"s":[87,87,100],"e":[83,83,100]},{"t":64}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[520,178],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.3505421358,0.408821913775,0.513725490196,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.57647061348,0.454901963472,0.411764711142,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-54,361],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[92,92],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":16,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Shape Layer 19","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[556.846,775.484,0],"e":[182.5,664.5,0],"to":[-62.3910217285156,-18.4974060058594,0],"ti":[62.3910217285156,18.4974060058594,0]},{"t":64}],"ix":2},"a":{"a":0,"k":[-1035,52,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[46,43.579],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.576470588235,0.454155117858,0.411441788019,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-1430,303],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[67,67],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":-46,"ix":4},"sa":{"a":0,"k":18,"ix":5},"nm":"Transform"}],"nm":"Ellipse 6","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[76,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.576470588235,0.454155117858,0.411441788019,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-401.563,351.938],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":-46,"ix":4},"sa":{"a":0,"k":18,"ix":5},"nm":"Transform"}],"nm":"Ellipse 10","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[76,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.576470588235,0.454155117858,0.411441788019,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-776,241],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":-46,"ix":4},"sa":{"a":0,"k":18,"ix":5},"nm":"Transform"}],"nm":"Ellipse 5","np":3,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[46.444,44],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.576470588235,0.454155117858,0.411441788019,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-790,-54],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":-46,"ix":4},"sa":{"a":0,"k":18,"ix":5},"nm":"Transform"}],"nm":"Ellipse 4","np":3,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[46,43.579],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.576470588235,0.454155117858,0.411441788019,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-1248,296],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":-46,"ix":4},"sa":{"a":0,"k":18,"ix":5},"nm":"Transform"}],"nm":"Ellipse 3","np":3,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[76,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.576470588235,0.454155117858,0.411441788019,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-1230,134],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[58,58],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":-46,"ix":4},"sa":{"a":0,"k":18,"ix":5},"nm":"Transform"}],"nm":"Ellipse 8","np":3,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[69.667,66],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.576470588235,0.454155117858,0.411441788019,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-1502,-247],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":-46,"ix":4},"sa":{"a":0,"k":18,"ix":5},"nm":"Transform"}],"nm":"Ellipse 9","np":3,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[69.667,66],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.576470588235,0.454155117858,0.411441788019,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-1127.625,-136.063],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":-46,"ix":4},"sa":{"a":0,"k":18,"ix":5},"nm":"Transform"}],"nm":"Ellipse 2","np":3,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[46.444,44],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.576470588235,0.454155117858,0.411441788019,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-415.562,57],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":-46,"ix":4},"sa":{"a":0,"k":18,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2416,-620],[-2648,8],[864,1156],[1088,444]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.454901960784,0.416844805549,0.383544802198,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.945098039216,0.739073211072,0.667128020642,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-256,-165],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":12,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":22,"ty":1,"nm":"Medium Turquoise Solid 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[500,500,0],"ix":2},"a":{"a":0,"k":[1750,519,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"sw":3500,"sh":1038,"sc":"#45d28b","ip":0,"op":600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/layout.edc b/presentation/src/main/cpp/third_party/rlottie/example/resource/layout.edc deleted file mode 100644 index 4021200f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/layout.edc +++ /dev/null @@ -1,93 +0,0 @@ -collections { - group { "layout"; - parts { - rect { "bg"; - desc { "default"; - color: 225 225 225 225; - } - } - spacer { "lottie_base"; - desc { "default"; - rel1.to_y: "text"; - rel1.relative: 0.0 1.0; - rel2.to_y: "slider"; - rel2.relative: 1.0 0.0; - } - } - swallow { "lottie"; - desc { "default"; - rel1.to: "lottie_base"; - rel2.to: "lottie_base"; - } - } - text { "text"; - desc { "default"; - rel1.relative: 1.0 0.0; - rel2.relative: 1.0 0.0; - rel1.offset: -20 20; - rel2.offset: -20 20; - align: 1.0 0.0; - color: 0 0 0 255; - min: 200 30; - text { - font: "arial"; - size: 25; - align: 1.0 0.5; - } - } - } - swallow { "slider"; - desc { "default"; - min: 0 100; - max: -1 100; - align: 0.5 1.0; - rel1.to_x: "left_pad"; - rel1.relative: 1.0 1.0; - rel2.to_x: "button_left_pad"; - rel2.relative: 0.0 1.0; - fixed: 0 1; - } - } - spacer { "left_pad"; - desc { "default"; - fixed: 1 0; - min: 20 0; - align: 0.0 0.5; - rel2.relative: 0.0 0.0; - } - } - spacer { "right_pad"; - desc { "default"; - fixed: 1 0; - min: 20 0; - align: 1.0 0.5; - rel1.relative: 1.0 0.0; - } - } - swallow { "button"; - desc { "default"; - fixed: 1 1; - min: 80 55; - align: 1.0 0.5; - rel1.to_x: "right_pad"; - rel1.to_y: "slider"; - rel1.relative: 0.0 0.5; - rel2.to_x: "right_pad"; - rel2.to_y: "slider"; - rel2.relative: 0.0 0.5; - } - } - spacer { "button_left_pad"; - desc { "default"; - fixed: 1 0; - min: 20 0; - align: 1.0 0.5; - rel1.to_x: "button"; - rel1.relative: 0.0 0.0; - rel2.to_x: "button"; - rel2.relative: 0.0 1.0; - } - } - } - } -} diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/layout.edj b/presentation/src/main/cpp/third_party/rlottie/example/resource/layout.edj deleted file mode 100644 index 4efc5139..00000000 Binary files a/presentation/src/main/cpp/third_party/rlottie/example/resource/layout.edj and /dev/null differ diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/leap_frog_loader.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/leap_frog_loader.json deleted file mode 100644 index cac502df..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/leap_frog_loader.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.10","fr":24,"ip":24,"op":72,"w":600,"h":600,"nm":"Loader 7","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"n":"0p7_1_0p3_0","t":24,"s":[388.699,300,0],"e":[268.699,300,0],"to":[-34,49,0],"ti":[25.30078125,45.5,0]},{"t":36,"s":[268.699,300,0],"h":1},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"n":"0p7_1_0p3_0","t":48,"s":[268.699,300,0],"e":[208.699,300,0],"to":[-19.69921875,-42,0],"ti":[2.5,-26,0]},{"t":60,"s":[208.699,300,0],"h":1},{"t":72,"s":[208.699,300,0],"h":1}],"ix":2,"x":"var $bm_rt;\nvar amp, freq, decay, n, t, v;\ntry {\n amp = div(effect('Position - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Position - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Position - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"a":{"a":0,"k":[-247.301,-57.301,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Position - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":20,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Position - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":40,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Position - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":40,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Position - Overshoot","np":3,"mn":"ADBE Slider Control","ix":4,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":20,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Position - Bounce","np":3,"mn":"ADBE Slider Control","ix":5,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":40,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Position - Friction","np":3,"mn":"ADBE Slider Control","ix":6,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":40,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[25.398,25.398],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.532643995098,0.532643995098,0.532643995098,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.298039215686,0.298039215686,0.298039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-247.301,-57.301],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"n":"0p7_1_0p3_0","t":24,"s":[328.699,300,0],"e":[388.699,300,0],"to":[15.80078125,-29.5,0],"ti":[-20.4083786010742,-15.2806444168091,0]},{"t":36,"s":[388.699,300,0],"h":1},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"n":"0p7_1_0p3_0","t":48,"s":[388.699,300,0],"e":[268.699,300,0],"to":[-21.9206390380859,-56.3496513366699,0],"ti":[22.5,-58.25,0]},{"t":60,"s":[268.699,300,0],"h":1},{"t":72,"s":[268.699,300,0],"h":1}],"ix":2,"x":"var $bm_rt;\nvar amp, freq, decay, n, t, v;\ntry {\n amp = div(effect('Position - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Position - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Position - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"a":{"a":0,"k":[-247.301,-57.301,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Position - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":20,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Position - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":40,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Position - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":40,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[25.398,25.398],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.532643995098,0.532643995098,0.532643995098,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.298039215686,0.298039215686,0.298039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-247.301,-57.301],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"n":"0p7_1_0p3_0","t":24,"s":[268.699,300,0],"e":[208.699,300,0],"to":[-12,25,0],"ti":[2.80078125,18,0]},{"t":36,"s":[208.699,300,0],"h":1},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"n":"0p7_1_0p3_0","t":48,"s":[208.699,300,0],"e":[328.699,300,0],"to":[30.80078125,67,0],"ti":[-17.5,54,0]},{"t":60,"s":[328.699,300,0],"h":1},{"t":72,"s":[328.699,300,0],"h":1}],"ix":2,"x":"var $bm_rt;\nvar amp, freq, decay, n, t, v;\ntry {\n amp = div(effect('Position - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Position - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Position - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"a":{"a":0,"k":[-247.301,-57.301,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Position - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":20,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Position - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":40,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Position - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":40,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[25.398,25.398],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.532643995098,0.532643995098,0.532643995098,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.298039215686,0.298039215686,0.298039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-247.301,-57.301],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"n":"0p7_1_0p3_0","t":24,"s":[208.699,300,0],"e":[328.699,300,0],"to":[18.30078125,-59.5,0],"ti":[-12,-47.5,0]},{"t":36,"s":[328.699,300,0],"h":1},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"n":"0p7_1_0p3_0","t":48,"s":[328.699,300,0],"e":[388.699,300,0],"to":[7.66105842590332,31.200023651123,0],"ti":[-8.19921875,40,0]},{"t":60,"s":[388.699,300,0],"h":1},{"t":72,"s":[388.699,300,0],"h":1}],"ix":2,"x":"var $bm_rt;\nvar amp, freq, decay, n, t, v;\ntry {\n amp = div(effect('Position - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Position - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Position - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"a":{"a":0,"k":[-247.301,-57.301,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Position - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":20,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Position - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":40,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Position - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":40,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[25.398,25.398],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.532643995098,0.532643995098,0.532643995098,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.298039215686,0.298039215686,0.298039215686,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-247.301,-57.301],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/like.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/like.json deleted file mode 100644 index 95c14168..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/like.json +++ /dev/null @@ -1 +0,0 @@ -{"assets":[],"layers":[{"ddd":0,"ind":0,"ty":1,"nm":"品蓝色 纯色 1","ks":{"o":{"k":[{"i":{"x":[0.667],"y":[0.667]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_0p667_0p167_0p167"],"t":0,"s":[100],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.537],"y":[0]},"n":["0p667_1_0p537_0"],"t":5,"s":[100],"e":[0]},{"t":17}]},"r":{"k":0},"p":{"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":5,"s":[400,320,0],"e":[408,274,0],"to":[1.33333337306976,-7.66666650772095,0],"ti":[-1.33333337306976,7.66666650772095,0]},{"t":17}]},"a":{"k":[400,300,0]},"s":{"k":[{"i":{"x":[0.518,0.518,0.667],"y":[1,1,0.667]},"o":{"x":[0.16,0.16,0.333],"y":[0.329,0.329,0.333]},"n":["0p518_1_0p16_0p329","0p518_1_0p16_0p329","0p667_0p667_0p333_0p333"],"t":5,"s":[0,0,100],"e":[160,160,100]},{"t":17}]}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"f","pt":{"k":{"i":[[0,0],[3.675,0],[0,0],[2.623,1.039],[10.49,18.686],[8.393,0],[0,0],[5.767,-5.706],[-0.526,-6.747],[8.391,-4.158],[2.101,0],[0,0],[0,-4.152],[0,0],[-4.196,0],[0,0],[-1.574,1.04],[-1.051,-0.52],[-31.47,0],[-9.441,41.527],[-2.097,6.748],[5.768,7.267]],"o":[[-7.342,-8.823],[0,0],[-12.065,0],[14.688,-23.358],[-5.772,-9.866],[0,0],[-3.671,-0.52],[-3.672,3.633],[4.198,46.715],[-1.572,-1.556],[0,0],[-4.198,0],[0,0],[0,4.155],[0,0],[2.097,0],[0.525,1.036],[0,0],[31.47,0],[2.098,-9.345],[3.671,-14.014],[0,0]],"v":[[521.158,276.64],[498.604,267.817],[454.021,267.817],[433.565,265.741],[435.663,188.92],[414.159,173.864],[413.112,173.864],[395.279,178.534],[390.561,194.626],[337.06,270.932],[331.816,268.856],[280.411,268.856],[272.544,276.642],[272.544,419.386],[280.411,427.172],[332.339,427.172],[338.111,425.096],[340.208,427.172],[464.514,426.652],[517.49,333.736],[523.785,308.82],[521.16,276.637]],"c":true}},"o":{"k":100},"x":{"k":0},"nm":"蒙版 1"}],"sw":800,"sh":600,"sc":"#00b1ff","ip":0,"op":50,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":1,"nm":"品蓝色 纯色 3","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":11,"s":[0],"e":[100]},{"t":15}]},"r":{"k":0},"p":{"k":[400,300,0]},"a":{"k":[400,300,0]},"s":{"k":[100,100,100]}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"k":{"i":[[0,0],[3.675,0],[0,0],[2.623,1.039],[10.49,18.686],[8.393,0],[0,0],[5.767,-5.706],[-0.526,-6.747],[8.391,-4.158],[2.101,0],[0,0],[0,-4.152],[0,0],[-4.196,0],[0,0],[-1.574,1.04],[-1.051,-0.52],[-31.47,0],[-9.441,41.527],[-2.097,6.748],[5.768,7.267]],"o":[[-7.342,-8.823],[0,0],[-12.065,0],[14.688,-23.358],[-5.772,-9.866],[0,0],[-3.671,-0.52],[-3.672,3.633],[4.198,46.715],[-1.572,-1.556],[0,0],[-4.198,0],[0,0],[0,4.155],[0,0],[2.097,0],[0.525,1.036],[0,0],[31.47,0],[2.098,-9.345],[3.671,-14.014],[0,0]],"v":[[521.158,276.64],[498.604,267.817],[454.021,267.817],[433.565,265.741],[435.663,188.92],[414.159,173.864],[413.112,173.864],[395.279,178.534],[390.561,194.626],[337.06,270.932],[331.816,268.856],[280.411,268.856],[272.544,276.642],[272.544,419.386],[280.411,427.172],[332.339,427.172],[338.111,425.096],[340.208,427.172],[464.514,426.652],[517.49,333.736],[523.785,308.82],[521.16,276.637]],"c":true}},"o":{"k":100},"x":{"k":0},"nm":"蒙版 3"},{"inv":false,"mode":"s","pt":{"k":{"i":[[0,0],[2.097,-9.861],[18.887,0],[6.816,0],[0,0],[-1.052,0.52],[5.769,62.291],[0.525,0],[-3.147,0],[0,0],[-2.098,-4.669],[12.067,-18.166],[-1.052,-2.596],[-21.503,0],[0,0],[-2.101,-2.597],[2.618,-8.822]],"o":[[-2.098,7.267],[-7.343,32.183],[-30.419,0],[0,0],[1.047,0],[2.624,-1.036],[0,-2.597],[0.525,-0.52],[0,0],[2.098,0],[8.392,15.571],[-4.199,6.23],[4.198,7.267],[0,0],[2.098,0],[3.671,2.597],[0,0]],"v":[[508.045,304.672],[501.75,330.626],[463.984,411.599],[339.679,412.119],[339.679,287.025],[342.303,286.505],[406.292,193.589],[406.292,189.956],[411.537,189.435],[413.634,189.435],[420.977,196.702],[418.353,259.51],[416.781,273.524],[452.971,283.903],[498.081,283.903],[507.524,286.5],[508.049,304.668]],"c":true}},"o":{"k":100},"x":{"k":0},"nm":"蒙版 1"},{"inv":false,"mode":"s","pt":{"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[323.943,411.599],[287.753,411.599],[287.753,284.428],[323.943,284.428]],"c":true}},"o":{"k":100},"x":{"k":0},"nm":"蒙版 2"}],"sw":800,"sh":600,"sc":"#00b1ff","ip":0,"op":50,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":1,"nm":"品蓝色 纯色 2","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":11,"s":[0],"e":[27]},{"t":16}]},"r":{"k":0},"p":{"k":[400,300,0]},"a":{"k":[400,300,0]},"s":{"k":[100,100,100]}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"f","pt":{"k":{"i":[[0,0],[3.675,0],[0,0],[2.623,1.039],[10.49,18.686],[8.393,0],[0,0],[5.767,-5.706],[-0.526,-6.747],[8.391,-4.158],[2.101,0],[0,0],[0,-4.152],[0,0],[-4.196,0],[0,0],[-1.574,1.04],[-1.051,-0.52],[-31.47,0],[-9.441,41.527],[-2.097,6.748],[5.768,7.267]],"o":[[-7.342,-8.823],[0,0],[-12.065,0],[14.688,-23.358],[-5.772,-9.866],[0,0],[-3.671,-0.52],[-3.672,3.633],[4.198,46.715],[-1.572,-1.556],[0,0],[-4.198,0],[0,0],[0,4.155],[0,0],[2.097,0],[0.525,1.036],[0,0],[31.47,0],[2.098,-9.345],[3.671,-14.014],[0,0]],"v":[[521.158,276.64],[498.604,267.817],[454.021,267.817],[433.565,265.741],[435.663,188.92],[414.159,173.864],[413.112,173.864],[395.279,178.534],[390.561,194.626],[337.06,270.932],[331.816,268.856],[280.411,268.856],[272.544,276.642],[272.544,419.386],[280.411,427.172],[332.339,427.172],[338.111,425.096],[340.208,427.172],[464.514,426.652],[517.49,333.736],[523.785,308.82],[521.16,276.637]],"c":true}},"o":{"k":100},"x":{"k":0},"nm":"蒙版 1"}],"sw":800,"sh":600,"sc":"#00b1ff","ip":0,"op":50,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":1,"nm":"灰色 纯色 1","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[400,300,0]},"a":{"k":[400,300,0]},"s":{"k":[100,100,100]}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"k":{"i":[[0,0],[3.675,0],[0,0],[2.623,1.039],[10.49,18.686],[8.393,0],[0,0],[5.767,-5.706],[-0.526,-6.747],[8.391,-4.158],[2.101,0],[0,0],[0,-4.152],[0,0],[-4.196,0],[0,0],[-1.574,1.04],[-1.051,-0.52],[-31.47,0],[-9.441,41.527],[-2.097,6.748],[5.768,7.267]],"o":[[-7.342,-8.823],[0,0],[-12.065,0],[14.688,-23.358],[-5.772,-9.866],[0,0],[-3.671,-0.52],[-3.672,3.633],[4.198,46.715],[-1.572,-1.556],[0,0],[-4.198,0],[0,0],[0,4.155],[0,0],[2.097,0],[0.525,1.036],[0,0],[31.47,0],[2.098,-9.345],[3.671,-14.014],[0,0]],"v":[[521.158,276.64],[498.604,267.817],[454.021,267.817],[433.565,265.741],[435.663,188.92],[414.159,173.864],[413.112,173.864],[395.279,178.534],[390.561,194.626],[337.06,270.932],[331.816,268.856],[280.411,268.856],[272.544,276.642],[272.544,419.386],[280.411,427.172],[332.339,427.172],[338.111,425.096],[340.208,427.172],[464.514,426.652],[517.49,333.736],[523.785,308.82],[521.16,276.637]],"c":true}},"o":{"k":100},"x":{"k":0},"nm":"蒙版 3"},{"inv":false,"mode":"s","pt":{"k":{"i":[[0,0],[2.097,-9.861],[18.887,0],[6.816,0],[0,0],[-1.052,0.52],[5.769,62.291],[0.525,0],[-3.147,0],[0,0],[-2.098,-4.669],[12.067,-18.166],[-1.052,-2.596],[-21.503,0],[0,0],[-2.101,-2.597],[2.618,-8.822]],"o":[[-2.098,7.267],[-7.343,32.183],[-30.419,0],[0,0],[1.047,0],[2.624,-1.036],[0,-2.597],[0.525,-0.52],[0,0],[2.098,0],[8.392,15.571],[-4.199,6.23],[4.198,7.267],[0,0],[2.098,0],[3.671,2.597],[0,0]],"v":[[508.045,304.672],[501.75,330.626],[463.984,411.599],[339.679,412.119],[339.679,287.025],[342.303,286.505],[406.292,193.589],[406.292,189.956],[411.537,189.435],[413.634,189.435],[420.977,196.702],[418.353,259.51],[416.781,273.524],[452.971,283.903],[498.081,283.903],[507.524,286.5],[508.049,304.668]],"c":true}},"o":{"k":100},"x":{"k":0},"nm":"蒙版 1"},{"inv":false,"mode":"s","pt":{"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[323.943,411.599],[287.753,411.599],[287.753,284.428],[323.943,284.428]],"c":true}},"o":{"k":100},"x":{"k":0},"nm":"蒙版 2"}],"sw":800,"sh":600,"sc":"#8c8c8c","ip":0,"op":37,"st":0,"bm":0,"sr":1}],"v":"4.5.4","ddd":0,"ip":0,"op":50,"fr":25,"w":800,"h":600} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/loader.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/loader.json deleted file mode 100644 index fe28cdf9..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/loader.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.5.7","fr":25,"ip":0,"op":250,"w":800,"h":600,"ddd":0,"assets":[],"layers":[{"ddd":0,"ind":0,"ty":3,"nm":"Resize","ks":{"o":{"a":0,"k":0},"r":{"a":0,"k":0},"p":{"a":0,"k":[400,300,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[150,150,100]}},"ao":0,"ip":0,"op":250,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"Rectangle","parent":0,"ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":40,"s":[-180],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":55,"s":[0],"e":[5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[5],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":64,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":75,"s":[0],"e":[36]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":81,"s":[36],"e":[90]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":85,"s":[90],"e":[95]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":86,"s":[95],"e":[90]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":95,"s":[90],"e":[90]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":105,"s":[90],"e":[270]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":115,"s":[270],"e":[-180]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":116,"s":[-180],"e":[-180]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":135,"s":[-180],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":150,"s":[0],"e":[5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":151,"s":[5],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":159,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":170,"s":[0],"e":[36]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":176,"s":[36],"e":[90]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":180,"s":[90],"e":[95]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":181,"s":[95],"e":[90]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":190,"s":[90],"e":[90]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":200,"s":[90],"e":[270]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":210,"s":[270],"e":[-180]},{"t":211}]},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":75,"s":[0,0,0],"e":[0,-5,0],"to":[0,-0.83333331346512,0],"ti":[0,0.83333331346512,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":85,"s":[0,-5,0],"e":[0,-5,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":105,"s":[0,-5,0],"e":[0,0,0],"to":[0,0.83333331346512,0],"ti":[0.08333333581686,-0.91666668653488,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":115,"s":[0,0,0],"e":[-0.5,0.5,0],"to":[-0.08333333581686,0.91666668653488,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":116,"s":[-0.5,0.5,0],"e":[0,0,0],"to":[0,0,0],"ti":[-0.08333333581686,0.91666668653488,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":170,"s":[0,0,0],"e":[0,-5,0],"to":[0.08333333581686,-0.91666668653488,0],"ti":[0,0.83333331346512,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":180,"s":[0,-5,0],"e":[0,-5,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":200,"s":[0,-5,0],"e":[0,0,0],"to":[0,0.83333331346512,0],"ti":[0.08333333581686,-0.91666668653488,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":210,"s":[0,0,0],"e":[-0.5,0.5,0],"to":[-0.08333333581686,0.91666668653488,0],"ti":[0.08333333581686,-0.08333333581686,0]},{"t":211}]},"a":{"a":0,"k":[-0.5,0,0]},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":18,"s":[0,0,100],"e":[80,80,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":23,"s":[80,80,100],"e":[110,110,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":25,"s":[110,110,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":30,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":40,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":116,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":135,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":211,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":220,"s":[100,100,100],"e":[110,110,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":225,"s":[110,110,100],"e":[80,80,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":228,"s":[80,80,100],"e":[0,0,100]},{"t":231}]}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[35,-35],[-35,-35],[-35,35],[35,35]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[35,-36.5],[-35,-21],[-35,21],[35,36.75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":81,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[35,-36.5],[-35,-21],[-35,21],[35,36.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[35,-38.75],[-35,0],[-35,0],[35,39.375]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":85,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[35,-38.75],[-35,0],[-35,0],[35,39.375]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[35,-38.75],[-35,0],[-35,0],[35,39.375]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":105,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[35,-38.75],[-35,0],[-35,0],[35,39.375]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[34,-35.25],[-36,-35],[-36,35],[34,34.875]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":115,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[34,-35.25],[-36,-35],[-36,35],[34,34.875]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[35,-35],[-35,-35],[-35,35],[35,35]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":170,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[35,-35],[-35,-35],[-35,35],[35,35]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[35,-36.5],[-35,-21],[-35,21],[35,36.75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":176,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[35,-36.5],[-35,-21],[-35,21],[35,36.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[35,-38.75],[-35,0],[-35,0],[35,39.375]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[35,-38.75],[-35,0],[-35,0],[35,39.375]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[35,-38.75],[-35,0],[-35,0],[35,39.375]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":200,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[35,-38.75],[-35,0],[-35,0],[35,39.375]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[34,-35.25],[-36,-35],[-36,35],[34,34.875]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":210,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[34,-35.25],[-36,-35],[-36,35],[34,34.875]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[34,-35.25],[-36,-35],[-36,35],[34,34.875]],"c":true}]},{"t":220}]},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0,0,0,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"rd","nm":"Round Corners 1","r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":30,"s":[50],"e":[34]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":40,"s":[34],"e":[27.778]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":45,"s":[27.778],"e":[8.333]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":50,"s":[8.333],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":55,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":75,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":105,"s":[0],"e":[50]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":115,"s":[50],"e":[50]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":116,"s":[50],"e":[34]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":135,"s":[34],"e":[27.778]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":140,"s":[27.778],"e":[8.333]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":145,"s":[8.333],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":150,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":170,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":200,"s":[0],"e":[50]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":210,"s":[50],"e":[50]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":211,"s":[50],"e":[64]},{"t":220}]},"mn":"ADBE Vector Filter - RC"}],"ip":0,"op":250,"st":0,"bm":0,"sr":1}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/loader_4.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/loader_4.json deleted file mode 100644 index 69248a72..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/loader_4.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.6.9","fr":29.9700012207031,"ip":0,"op":34.0000013848484,"w":800,"h":600,"nm":"Loader","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 2","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[400,300,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[36.812,0],[0,-19.33],[-19.33,0],[-37.125,0],[0,-19.33],[19.33,0]],"o":[[-19.33,0],[0,19.33],[36.688,0],[19.33,0],[0,19.33],[-37.25,0]],"v":[[-44.844,-35],[-79.844,0],[-44.844,35],[44.844,-35],[79.844,0],[44.844,35]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.105882,0.105882,0.105882,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":12},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":5.834,"s":[0],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":17.11,"s":[20],"e":[20]},{"i":{"x":[0.611],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p611_1_0p167_0p167"],"t":23.334,"s":[20],"e":[40]},{"t":35.0000014255792}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":0,"s":[12],"e":[32]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":11.666,"s":[32],"e":[32]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p5_1_0p167_0p167"],"t":17.11,"s":[32],"e":[53]},{"t":29.1662511879657}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":0,"s":[-22],"e":[82.925]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":17.11,"s":[82.925],"e":[193]},{"t":35.0000014255792}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"}],"ip":0,"op":300.00001221925,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 1","ks":{"o":{"a":0,"k":25},"r":{"a":0,"k":0},"p":{"a":0,"k":[400,300,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[36.812,0],[0,-19.33],[-19.33,0],[-37.125,0],[0,-19.33],[19.33,0]],"o":[[-19.33,0],[0,19.33],[36.688,0],[19.33,0],[0,19.33],[-37.25,0]],"v":[[-44.844,-35],[-79.844,0],[-44.844,35],[44.844,-35],[79.844,0],[44.844,35]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.105882,0.105882,0.105882,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":12},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":300.00001221925,"st":0,"bm":0,"sr":1}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/loader_animation.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/loader_animation.json deleted file mode 100644 index c6453f8b..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/loader_animation.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.1","fr":74,"ip":0,"op":171,"w":128,"h":199,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 12","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":143,"s":[100],"e":[0]},{"t":156}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":47,"s":[67.5,-5,0],"e":[67.5,116.75,0],"to":[0,20.2916660308838,0],"ti":[1.04942238330841,18.8896026611328,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":98,"s":[67.5,116.75,0],"e":[39.5,116.75,0],"to":[-0.04166666790843,-0.75,0],"ti":[7.02829837799072,-5.70764303207397,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":130,"s":[39.5,116.75,0],"e":[15.25,131,0],"to":[-13.0033321380615,10.5599355697632,0],"ti":[0,0,0]},{"t":156}],"ix":2},"a":{"a":0,"k":[1,-1.5,0],"ix":1},"s":{"a":0,"k":[29.167,29.167,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[12,12],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.980392156863,0.123029596665,0.123029596665,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1,-1.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":47,"op":172,"st":47,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 11","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":98,"s":[1],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":100,"s":[100],"e":[0]},{"t":111}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":100,"s":[71,120,0],"e":[80,116.625,0],"to":[1.5,-0.5625,0],"ti":[-1.5,0.5625,0]},{"t":110}],"ix":2},"a":{"a":0,"k":[19.552,26.661,0],"ix":1},"s":{"a":0,"k":[14.065,14.065,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.5,-0.375],[10.625,-5.625],[0,0],[0.375,0.125]],"o":[[-3.375,-0.5],[-10.625,5.625],[0,0],[7.875,-5.25]],"v":[[28.125,22],[11.75,25.875],[14.5,31.25],[27,27.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.980392156863,0.121568627451,0.121568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":98,"op":172,"st":98,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":98,"s":[1],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":100,"s":[100],"e":[0]},{"t":111}],"ix":11},"r":{"a":0,"k":206.765,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":100,"s":[62.25,119.125,0],"e":[49.25,117.625,0],"to":[-2.16666674613953,-0.25,0],"ti":[2.16666674613953,0.25,0]},{"t":111}],"ix":2},"a":{"a":0,"k":[19.552,26.661,0],"ix":1},"s":{"a":0,"k":[-11.341,-16.193,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.5,-0.375],[10.625,-5.625],[0,0],[0.375,0.125]],"o":[[-3.375,-0.5],[-10.625,5.625],[0,0],[7.875,-5.25]],"v":[[28.125,22],[11.75,25.875],[14.5,31.25],[27,27.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.980392156863,0.121568627451,0.121568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":98,"op":172,"st":98,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 9","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":125,"s":[100],"e":[0]},{"t":138}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":29,"s":[67.5,-5,0],"e":[67.5,116.75,0],"to":[0,20.2916660308838,0],"ti":[1.04942238330841,18.8896026611328,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":80,"s":[67.5,116.75,0],"e":[33.5,111.25,0],"to":[-0.04166666790843,-0.75,0],"ti":[7.02829837799072,-5.70764303207397,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":112,"s":[33.5,111.25,0],"e":[3,121.75,0],"to":[-13.0033321380615,10.5599355697632,0],"ti":[0,0,0]},{"t":138}],"ix":2},"a":{"a":0,"k":[1,-1.5,0],"ix":1},"s":{"a":0,"k":[29.167,29.167,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[12,12],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.138299740062,0.81568627451,0.047981542699,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1,-1.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":29,"op":172,"st":29,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 8","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":80,"s":[1],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":82,"s":[100],"e":[0]},{"t":93}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":82,"s":[71,120,0],"e":[80,116.625,0],"to":[1.5,-0.5625,0],"ti":[-1.5,0.5625,0]},{"t":92}],"ix":2},"a":{"a":0,"k":[19.552,26.661,0],"ix":1},"s":{"a":0,"k":[14.065,14.065,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.5,-0.375],[10.625,-5.625],[0,0],[0.375,0.125]],"o":[[-3.375,-0.5],[-10.625,5.625],[0,0],[7.875,-5.25]],"v":[[28.125,22],[11.75,25.875],[14.5,31.25],[27,27.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.137254901961,0.81568627451,0.047058823529,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":172,"st":80,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 7","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":80,"s":[1],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":82,"s":[100],"e":[0]},{"t":93}],"ix":11},"r":{"a":0,"k":206.765,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":82,"s":[62.25,119.125,0],"e":[49.25,117.625,0],"to":[-2.16666674613953,-0.25,0],"ti":[2.16666674613953,0.25,0]},{"t":93}],"ix":2},"a":{"a":0,"k":[19.552,26.661,0],"ix":1},"s":{"a":0,"k":[-11.341,-16.193,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.5,-0.375],[10.625,-5.625],[0,0],[0.375,0.125]],"o":[[-3.375,-0.5],[-10.625,5.625],[0,0],[7.875,-5.25]],"v":[[28.125,22],[11.75,25.875],[14.5,31.25],[27,27.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.137254901961,0.81568627451,0.047058823529,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":172,"st":80,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 6","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":65,"s":[1],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":67,"s":[100],"e":[0]},{"t":78}],"ix":11},"r":{"a":0,"k":206.765,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":67,"s":[62.25,119.125,0],"e":[49.25,117.625,0],"to":[-2.16666674613953,-0.25,0],"ti":[2.16666674613953,0.25,0]},{"t":78}],"ix":2},"a":{"a":0,"k":[19.552,26.661,0],"ix":1},"s":{"a":0,"k":[-11.341,-16.193,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.5,-0.375],[10.625,-5.625],[0,0],[0.375,0.125]],"o":[[-3.375,-0.5],[-10.625,5.625],[0,0],[7.875,-5.25]],"v":[[28.125,22],[11.75,25.875],[14.5,31.25],[27,27.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.996078431373,0.858823529412,0.090196078431,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":65,"op":172,"st":65,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":65,"s":[1],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":67,"s":[100],"e":[0]},{"t":78}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":67,"s":[71,120,0],"e":[80,116.625,0],"to":[1.5,-0.5625,0],"ti":[-1.5,0.5625,0]},{"t":77}],"ix":2},"a":{"a":0,"k":[19.552,26.661,0],"ix":1},"s":{"a":0,"k":[14.065,14.065,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.5,-0.375],[10.625,-5.625],[0,0],[0.375,0.125]],"o":[[-3.375,-0.5],[-10.625,5.625],[0,0],[7.875,-5.25]],"v":[[28.125,22],[11.75,25.875],[14.5,31.25],[27,27.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.996078431373,0.858823529412,0.090196078431,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":65,"op":172,"st":65,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":111,"s":[100],"e":[0]},{"t":124}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":14,"s":[67.5,-5,0],"e":[67.5,116.75,0],"to":[0,20.2916660308838,0],"ti":[1.04942238330841,18.8896026611328,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":65,"s":[67.5,116.75,0],"e":[34.25,108.5,0],"to":[-0.04166666790843,-0.75,0],"ti":[7.74652624130249,-6.27588701248169,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":97,"s":[34.25,108.5,0],"e":[10.25,114.25,0],"to":[-11.3133344650269,9.16555500030518,0],"ti":[0,0,0]},{"t":123}],"ix":2},"a":{"a":0,"k":[1,-1.5,0],"ix":1},"s":{"a":0,"k":[29.167,29.167,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[12,12],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.996078431373,0.857477644378,0.089842366237,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1,-1.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":14,"op":172,"st":14,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Shape Layer 18","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":152,"s":[100],"e":[0]},{"t":165}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":56,"s":[67.5,-5,0],"e":[67.5,116.75,0],"to":[0,20.2916660308838,0],"ti":[1.04942238330841,18.8896026611328,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":107,"s":[67.5,116.75,0],"e":[91.25,106,0],"to":[-0.04166666790843,-0.75,0],"ti":[-18.7426891326904,-16.4572200775146,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":139,"s":[91.25,106,0],"e":[121.25,105.25,0],"to":[16.5734615325928,14.5525054931641,0],"ti":[0,0,0]},{"t":165}],"ix":2},"a":{"a":0,"k":[1,-1.5,0],"ix":1},"s":{"a":0,"k":[29.167,29.167,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[12,12],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.568120021446,0.007843136787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1,-1.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":56,"op":172,"st":56,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Shape Layer 17","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":105,"s":[1],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":107,"s":[100],"e":[0]},{"t":118}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":107,"s":[71,120,0],"e":[80,116.625,0],"to":[1.5,-0.5625,0],"ti":[-1.5,0.5625,0]},{"t":117}],"ix":2},"a":{"a":0,"k":[19.552,26.661,0],"ix":1},"s":{"a":0,"k":[14.065,14.065,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.5,-0.375],[10.625,-5.625],[0,0],[0.375,0.125]],"o":[[-3.375,-0.5],[-10.625,5.625],[0,0],[7.875,-5.25]],"v":[[28.125,22],[11.75,25.875],[14.5,31.25],[27,27.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.56862745098,0.007843137255,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":105,"op":172,"st":105,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Shape Layer 16","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":105,"s":[0],"e":[85]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":107,"s":[85],"e":[0]},{"t":118}],"ix":11},"r":{"a":0,"k":206.765,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":107,"s":[62.25,119.125,0],"e":[49.25,117.625,0],"to":[-2.16666674613953,-0.25,0],"ti":[2.16666674613953,0.25,0]},{"t":118}],"ix":2},"a":{"a":0,"k":[19.552,26.661,0],"ix":1},"s":{"a":0,"k":[-11.341,-16.193,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.5,-0.375],[10.625,-5.625],[0,0],[0.375,0.125]],"o":[[-3.375,-0.5],[-10.625,5.625],[0,0],[7.875,-5.25]],"v":[[28.125,22],[11.75,25.875],[14.5,31.25],[27,27.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.56862745098,0.007843137255,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":105,"op":172,"st":105,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Shape Layer 15","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":134,"s":[100],"e":[0]},{"t":147}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":37,"s":[67.5,-5,0],"e":[67.5,116.75,0],"to":[0,20.2916660308838,0],"ti":[1.04942238330841,18.8896026611328,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":88,"s":[67.5,116.75,0],"e":[91.25,106,0],"to":[-0.04166666790843,-0.75,0],"ti":[-12.3503103256226,-21.6702175140381,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":120,"s":[91.25,106,0],"e":[121.25,122.75,0],"to":[10.5734605789185,18.5525054931641,0],"ti":[0,0,0]},{"t":146}],"ix":2},"a":{"a":0,"k":[1,-1.5,0],"ix":1},"s":{"a":0,"k":[29.167,29.167,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[12,12],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.107927718817,0.642268401501,0.949019607843,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1,-1.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":37,"op":172,"st":37,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Shape Layer 14","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":86,"s":[1],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":88,"s":[100],"e":[0]},{"t":99}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":88,"s":[71,120,0],"e":[80,116.625,0],"to":[1.5,-0.5625,0],"ti":[-1.5,0.5625,0]},{"t":98}],"ix":2},"a":{"a":0,"k":[19.552,26.661,0],"ix":1},"s":{"a":0,"k":[14.065,14.065,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.5,-0.375],[10.625,-5.625],[0,0],[0.375,0.125]],"o":[[-3.375,-0.5],[-10.625,5.625],[0,0],[7.875,-5.25]],"v":[[28.125,22],[11.75,25.875],[14.5,31.25],[27,27.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.109803921569,0.643137254902,0.949019607843,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":86,"op":172,"st":86,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Shape Layer 13","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":86,"s":[0],"e":[85]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":88,"s":[85],"e":[0]},{"t":99}],"ix":11},"r":{"a":0,"k":206.765,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":88,"s":[62.25,119.125,0],"e":[49.25,117.625,0],"to":[-2.16666674613953,-0.25,0],"ti":[2.16666674613953,0.25,0]},{"t":99}],"ix":2},"a":{"a":0,"k":[19.552,26.661,0],"ix":1},"s":{"a":0,"k":[-11.341,-16.193,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.5,-0.375],[10.625,-5.625],[0,0],[0.375,0.125]],"o":[[-3.375,-0.5],[-10.625,5.625],[0,0],[7.875,-5.25]],"v":[[28.125,22],[11.75,25.875],[14.5,31.25],[27,27.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.109803921569,0.643137254902,0.949019607843,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":86,"op":172,"st":86,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":49,"s":[0],"e":[85]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":51,"s":[85],"e":[0]},{"t":62}],"ix":11},"r":{"a":0,"k":206.765,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":51,"s":[62.25,119.125,0],"e":[49.25,117.625,0],"to":[-2.16666674613953,-0.25,0],"ti":[2.16666674613953,0.25,0]},{"t":62}],"ix":2},"a":{"a":0,"k":[19.552,26.661,0],"ix":1},"s":{"a":0,"k":[-11.341,-16.193,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.5,-0.375],[10.625,-5.625],[0,0],[0.375,0.125]],"o":[[-3.375,-0.5],[-10.625,5.625],[0,0],[7.875,-5.25]],"v":[[28.125,22],[11.75,25.875],[14.5,31.25],[27,27.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.925490196078,0,0.549019607843,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":49,"op":172,"st":49,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":49,"s":[1],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":51,"s":[100],"e":[0]},{"t":62}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":51,"s":[71,120,0],"e":[80,116.625,0],"to":[1.5,-0.5625,0],"ti":[-1.5,0.5625,0]},{"t":61}],"ix":2},"a":{"a":0,"k":[19.552,26.661,0],"ix":1},"s":{"a":0,"k":[14.065,14.065,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.5,-0.375],[10.625,-5.625],[0,0],[0.375,0.125]],"o":[[-3.375,-0.5],[-10.625,5.625],[0,0],[7.875,-5.25]],"v":[[28.125,22],[11.75,25.875],[14.5,31.25],[27,27.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.925490196078,0,0.549019607843,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":49,"op":172,"st":49,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":96,"s":[100],"e":[0]},{"t":109}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[67.5,-5,0],"e":[67.5,116.75,0],"to":[0,20.2916660308838,0],"ti":[1.04942238330841,18.8896026611328,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":51,"s":[67.5,116.75,0],"e":[91.25,106,0],"to":[-0.04166666790843,-0.75,0],"ti":[-16.4489860534668,-18.7499160766602,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":83,"s":[91.25,106,0],"e":[116.75,116,0],"to":[10.5734605789185,12.0525054931641,0],"ti":[0,0,0]},{"t":109}],"ix":2},"a":{"a":0,"k":[1,-1.5,0],"ix":1},"s":{"a":0,"k":[29.167,29.167,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[12,12],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.925490196078,0,0.549019607843,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1,-1.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":172,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/loading.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/loading.json deleted file mode 100644 index b6605b8c..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/loading.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.2.1","fr":29.9700012207031,"ip":0,"op":900.000036657751,"w":237,"h":237,"nm":"final","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"flight","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.9]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p9_0p167_0p167"],"t":0,"s":[-50],"e":[0]},{"t":180.00000733155}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.894},"o":{"x":0.167,"y":0.167},"n":"0p833_0p894_0p167_0p167","t":0,"s":[-50,141.805,0],"e":[118,38.61,0],"to":[28,-17.1991653442383,0],"ti":[-78,4.31500005722046,0]},{"i":{"x":0.538,"y":0.736},"o":{"x":0.05,"y":1},"n":"0p538_0p736_0p05_1","t":180,"s":[118,38.61,0],"e":[118,38.61,0],"to":[0.02864627912641,-2.52048540115356,0],"ti":[0.00681143719703,0.76931047439575,0]},{"i":{"x":0.833,"y":0.761},"o":{"x":0.422,"y":0.048},"n":"0p833_0p761_0p422_0p048","t":242,"s":[118,38.61,0],"e":[118,33,0],"to":[-0.00714083854109,-0.80651438236237,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.821},"o":{"x":0.167,"y":0.126},"n":"0p833_0p821_0p167_0p126","t":274,"s":[118,33,0],"e":[118,43,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.845},"o":{"x":0.167,"y":0.155},"n":"0p833_0p845_0p167_0p155","t":304,"s":[118,43,0],"e":[118,33,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.179},"n":"0p833_0p833_0p167_0p179","t":330,"s":[118,33,0],"e":[118,43,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.828},"o":{"x":0.167,"y":0.178},"n":"0p833_0p828_0p167_0p178","t":360,"s":[118,43,0],"e":[118,33,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.161},"n":"0p833_0p833_0p167_0p161","t":392,"s":[118,33,0],"e":[118,43,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.831},"o":{"x":0.167,"y":0.172},"n":"0p833_0p831_0p167_0p172","t":422,"s":[118,43,0],"e":[118,33,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.164},"n":"0p833_0p833_0p167_0p164","t":453,"s":[118,33,0],"e":[118,43,0],"to":[0,0,0],"ti":[0,0,0]},{"t":483.000019672993}],"ix":2},"a":{"a":0,"k":[45.5,50.5,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"ef":[{"ty":25,"nm":"Drop Shadow","np":9,"mn":"ADBE Drop Shadow","ix":1,"en":1,"ef":[{"ty":2,"nm":"Shadow Color","mn":"ADBE Drop Shadow-0001","ix":1,"v":{"a":0,"k":[0,0,0,1],"ix":1}},{"ty":0,"nm":"Opacity","mn":"ADBE Drop Shadow-0002","ix":2,"v":{"a":0,"k":51,"ix":2}},{"ty":0,"nm":"Direction","mn":"ADBE Drop Shadow-0003","ix":3,"v":{"a":0,"k":135,"ix":3}},{"ty":0,"nm":"Distance","mn":"ADBE Drop Shadow-0004","ix":4,"v":{"a":0,"k":6,"ix":4}},{"ty":0,"nm":"Softness","mn":"ADBE Drop Shadow-0005","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":7,"nm":"Shadow Only","mn":"ADBE Drop Shadow-0006","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":7,"v":{"a":0,"k":1,"ix":7}}]}],"w":91,"h":101,"ip":0,"op":900.000036657751,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"may","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[118.233,118.5,0],"ix":2},"a":{"a":0,"k":[219.5,200.5,0],"ix":1},"s":{"a":0,"k":[54.504,54.504,100],"ix":6}},"ao":0,"tm":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[14.114]},{"t":423.000017229143}],"ix":2,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle', 0);"},"w":439,"h":401,"ip":0,"op":900.000036657751,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"loading 2","refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[119,221,0],"ix":2},"a":{"a":0,"k":[219.5,200.5,0],"ix":1},"s":{"a":0,"k":[78,78,100],"ix":6}},"ao":0,"w":439,"h":401,"ip":0,"op":900.000036657751,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[118.5,118.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[237,237],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":true},{"ty":"fl","c":{"a":0,"k":[0.780392169952,0.898039221764,0.941176474094,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900.000036657751,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"flight Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[45.5,50.5,0],"ix":2},"a":{"a":0,"k":[45.5,50.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.198,-0.314],[6.473,-9.04],[-0.216,0.302],[-5.936,9.402]],"o":[[-5.936,9.401],[-0.215,0.301],[6.472,-9.04],[0.195,-0.31]],"v":[[9.09,-14.003],[-9.523,13.66],[-9.07,14.016],[9.544,-13.648]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.808000033509,0.808000033509,0.808000033509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[44.956,79.611],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.205,-0.309],[-5.842,-8.82],[0.205,0.308],[5.843,8.821]],"o":[[5.842,8.821],[0.204,0.309],[-5.841,-8.822],[-0.204,-0.309]],"v":[[-8.993,-13.058],[8.533,13.405],[8.993,13.059],[-8.534,-13.404]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.808000033509,0.808000033509,0.808000033509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[44.114,19.044],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.369,0.039],[0.49,-2.332],[-0.076,0.362],[-1.761,-0.183]],"o":[[-2.103,-0.219],[-0.077,0.364],[0.422,-2.007],[0.368,0.039]],"v":[[2.336,-1.493],[-2.628,1.262],[-2.059,1.35],[2.249,-0.924]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.808000033509,0.808000033509,0.808000033509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[4.746,46.668],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.37,0.025],[13.095,0.205],[-0.366,-0.005],[-13.016,-0.89]],"o":[[-13.065,-0.895],[-0.37,-0.005],[13.044,0.203],[0.368,0.025]],"v":[[19.622,0.529],[-19.622,-1.118],[-19.559,-0.544],[19.535,1.098]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.808000033509,0.808000033509,0.808000033509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[42.202,55.706],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.165,0.168],[0,0],[4.254,-5.523]],"o":[[4.098,-5.319],[0,0],[1.888,1.922],[0,0]],"v":[[-3.046,4.854],[-2.941,-4.643],[-1.288,-6.268],[-1.208,6.269]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.067000003889,0.513999968884,0.819999964097,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[84.149,50.261],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.005,3.843],[0,0],[-3.843,-0.005],[0,0],[0.005,-3.844],[0,0],[2.605,0.003]],"o":[[-3.843,-0.005],[0,0],[0.004,-3.843],[0,0],[2.605,0.003],[0,0],[-0.005,3.844],[0,0]],"v":[[-38.359,6.178],[-45.216,0.139],[-45.216,-0.324],[-38.345,-6.346],[35.679,-8.583],[45.217,-0.223],[45.217,0.241],[35.66,8.579]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[45.217,50.14],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":4,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4.985,6.836],[-2.241,-6.833],[-4.654,-6.836],[-4.985,6.722]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.067000003889,0.513999968884,0.819999964097,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[9.21,41.265],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":2,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4.985,-6.447],[-2.27,6.639],[-4.684,6.635],[-4.985,-6.639]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.067000003889,0.513999968884,0.819999964097,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[9.206,58.417],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[19.148,21.952],[-9.561,-21.942],[-19.148,-21.952],[-6.827,21.947]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929000016755,0.941000007181,0.957000014361,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[43.136,21.953],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":2,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[19.197,-21.96],[-9.609,21.966],[-19.197,21.955],[-6.778,-21.965]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.929000016755,0.941000007181,0.957000014361,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[43.073,79.006],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10","np":4,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.002,-1.534],[-1.66,-0.002],[0,0],[-0.001,1.534],[1.659,0.002]],"o":[[-1.659,-0.002],[-0.002,1.534],[0,0],[1.66,0.002],[0.002,-1.534],[0,0]],"v":[[-4.503,-2.876],[-7.511,-0.008],[-4.509,2.865],[4.503,2.876],[7.511,0.008],[4.51,-2.866]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.067000003889,0.513999968884,0.819999964097,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[52.114,70.847],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11","np":2,"cix":2,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.002,-1.534],[-1.66,-0.002],[0,0],[-0.001,1.533],[1.659,0.002]],"o":[[-1.659,-0.002],[-0.001,1.533],[0,0],[1.659,0.001],[0.002,-1.534],[0,0]],"v":[[-4.503,-2.876],[-7.512,-0.008],[-4.51,2.865],[4.504,2.876],[7.51,0.008],[4.51,-2.866]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.067000003889,0.513999968884,0.819999964097,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[46.54,78.497],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12","np":2,"cix":2,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.001,-1.534],[-1.66,-0.002],[0,0],[-0.001,1.534],[1.659,0.002]],"o":[[-1.659,-0.002],[-0.002,1.534],[0,0],[1.659,0.002],[0.002,-1.533],[0,0]],"v":[[-4.503,-2.876],[-7.51,-0.009],[-4.51,2.865],[4.504,2.876],[7.51,0.008],[4.51,-2.866]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.067000003889,0.513999968884,0.819999964097,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[41.892,86.626],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":2,"cix":2,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.002,1.534],[-1.659,-0.002],[0,0],[0.001,-1.533],[1.659,0.002]],"o":[[-1.659,-0.002],[0.001,-1.533],[0,0],[1.659,0.002],[-0.002,1.534],[0,0]],"v":[[-4.51,3.105],[-7.51,-0.009],[-4.503,-3.115],[4.51,-3.105],[7.512,0.008],[4.503,3.115]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.067000003889,0.513999968884,0.819999964097,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[52.16,29.937],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 14","np":2,"cix":2,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.002,1.534],[-1.659,-0.002],[0,0],[0.001,-1.534],[1.659,0.002]],"o":[[-1.659,-0.001],[0.001,-1.534],[0,0],[1.659,0.001],[-0.002,1.534],[0,0]],"v":[[-4.51,2.866],[-7.51,-0.008],[-4.504,-2.876],[4.51,-2.865],[7.512,0.009],[4.503,2.876]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.067000003889,0.513999968884,0.819999964097,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[46.602,22.036],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 15","np":2,"cix":2,"ix":15,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.002,1.533],[-1.659,-0.002],[0,0],[0.001,-1.534],[1.659,0.002]],"o":[[-1.659,-0.002],[0.001,-1.534],[0,0],[1.659,0.002],[-0.002,1.534],[0,0]],"v":[[-4.51,2.626],[-7.51,-0.008],[-4.504,-2.636],[4.51,-2.626],[7.512,0.008],[4.503,2.637]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.067000003889,0.513999968884,0.819999964097,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[41.973,14.136],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 16","np":2,"cix":2,"ix":16,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900.000036657751,"st":0,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"may Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[659.5,200.5,0],"e":[219.5,200.5,0],"to":[-73.3333358764648,0,0],"ti":[147.91667175293,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":210,"s":[219.5,200.5,0],"e":[-228,200.5,0],"to":[-147.91667175293,0,0],"ti":[74.5833358764648,0,0]},{"t":422.000017188412}],"ix":2},"a":{"a":0,"k":[219.5,200.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.095,0],[1.385,-0.513],[7.344,0],[2.766,-3.613],[1.865,0],[0,-4.831],[-0.005,-0.121],[0,-5.671],[-6.637,0],[0,0],[0,7.132]],"o":[[-1.562,0],[-1.373,-6.977],[-4.885,0],[-1.417,-1.005],[-4.806,0],[0,0.123],[-5.243,1.3],[0,6.672],[0,0],[7.095,0],[0,-7.132]],"v":[[20.617,-7.197],[16.18,-6.39],[1.346,-18.63],[-10.637,-12.678],[-15.644,-14.279],[-24.347,-5.531],[-24.328,-5.167],[-33.464,6.549],[-21.446,18.63],[20.617,18.63],[33.464,5.716]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[327.953,358.029],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[18.395,0],[3.59,-1.33],[19.04,0],[7.17,-9.368],[4.838,0],[0,-12.526],[-0.013,-0.316],[0,-14.703],[-17.209,0],[0,0],[0,18.491]],"o":[[-4.049,0],[-3.559,-18.09],[-12.667,0],[-3.674,-2.606],[-12.462,0],[0,0.319],[-13.592,3.37],[0,17.298],[0,0],[18.395,0],[0,-18.49]],"v":[[53.453,-18.66],[41.951,-16.567],[3.492,-48.3],[-27.576,-32.87],[-40.559,-37.02],[-63.123,-14.34],[-63.075,-13.395],[-86.76,16.98],[-55.601,48.3],[53.453,48.3],[86.76,14.82]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":60,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[86.76,129.24],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[10.854,0.878],[0,2.671],[16.764,0],[5.258,-3.936],[2.695,0],[2.314,-7.548],[2.282,0],[0.843,-5.282],[0,-11.883],[-14.669,0],[0,0],[0,10.595]],"o":[[0.792,-2.44],[0,-15.106],[-7.37,0],[-2.342,-0.877],[-9.112,0],[-1.821,-0.989],[-6.095,0],[-12.599,1.871],[0,13.217],[0,0],[11.759,0],[0,-10.01]],"v":[[48.09,-1.622],[49.326,-9.308],[18.972,-36.66],[-0.409,-30.355],[-8.011,-31.722],[-27.093,-18.623],[-33.306,-20.215],[-45.236,-10.86],[-67.455,12.727],[-40.894,36.66],[46.164,36.66],[67.455,17.475]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":60,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[356.554,258.559],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":4,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.611,0.849],[0,0.379],[2.987,0],[0.684,-0.314],[5.387,0],[1.96,-3.103],[1.255,0],[0,-3.264],[-0.012,-0.153],[0,-4.09],[-4.849,0],[0,0],[0,3.612]],"o":[[0.073,-0.358],[0,-3.003],[-0.801,0],[-0.98,-5.128],[-3.926,0],[-0.955,-0.674],[-3.247,0],[0,0.156],[-3.756,1],[0,4.874],[0,0],[3.593,0],[0,-2.908]],"v":[[19.483,1.147],[19.595,0.04],[14.186,-5.397],[11.944,-4.903],[1.096,-13.906],[-8.23,-8.737],[-11.6,-9.809],[-17.479,-3.9],[-17.456,-3.439],[-23.984,5.082],[-15.206,13.906],[17.478,13.906],[23.984,7.367]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":28,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[414.784,81.916],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":4,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.3,0.748],[0,0.334],[2.63,0],[0.602,-0.277],[4.743,0],[1.725,-2.733],[1.105,0],[0,-2.874],[-0.011,-0.135],[0,-3.602],[-4.27,0],[0,0],[0,3.179]],"o":[[0.064,-0.314],[0,-2.643],[-0.705,0],[-0.862,-4.515],[-3.458,0],[-0.841,-0.593],[-2.859,0],[0,0.136],[-3.308,0.881],[0,4.291],[0,0],[3.164,0],[0,-2.562]],"v":[[17.155,1.009],[17.254,0.034],[12.492,-4.753],[10.517,-4.318],[0.966,-12.245],[-7.247,-7.694],[-10.215,-8.637],[-15.391,-3.434],[-15.37,-3.027],[-21.119,4.475],[-13.389,12.245],[15.39,12.245],[21.119,6.487]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":28,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[57.252,358.911],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":4,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.302,1.074],[0,0.48],[3.776,0],[0.864,-0.397],[6.809,0],[2.478,-3.923],[1.586,0],[0,-4.125],[-0.015,-0.193],[0,-5.17],[-6.129,0],[0,0],[0,4.566]],"o":[[0.093,-0.452],[0,-3.795],[-1.012,0],[-1.239,-6.482],[-4.965,0],[-1.207,-0.851],[-4.104,0],[0,0.196],[-4.748,1.264],[0,6.161],[0,0],[4.542,0],[0,-3.676]],"v":[[24.627,1.449],[24.77,0.049],[17.933,-6.822],[15.099,-6.198],[1.387,-17.579],[-10.404,-11.045],[-14.664,-12.4],[-22.095,-4.93],[-22.065,-4.347],[-30.318,6.423],[-19.221,17.578],[22.094,17.578],[30.318,9.311]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":28,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[178.451,17.578],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":4,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.038,1.313],[0,0.587],[4.619,0],[1.057,-0.485],[8.328,0],[3.032,-4.798],[1.941,0],[0,-5.045],[-0.019,-0.236],[0,-6.324],[-7.496,0],[0,0],[0,5.584]],"o":[[0.114,-0.553],[0,-4.642],[-1.238,0],[-1.515,-7.927],[-6.072,0],[-1.475,-1.041],[-5.019,0],[0,0.241],[-5.808,1.547],[0,7.535],[0,0],[5.556,0],[0,-4.497]],"v":[[30.121,1.772],[30.296,0.061],[21.933,-8.344],[18.467,-7.581],[1.696,-21.501],[-12.726,-13.51],[-17.936,-15.166],[-27.025,-6.031],[-26.988,-5.318],[-37.082,7.856],[-23.51,21.501],[27.023,21.501],[37.082,11.389]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[387.882,97.702],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":4,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.89,1.231],[0,2.922],[12.448,0],[3.63,-7.622],[3.085,0],[0,-8.534],[-0.029,-0.39],[0.106,0],[0,-7.229],[-7.192,0],[0,0],[0,6.247]],"o":[[1.002,-2.564],[0,-12.512],[-8.968,0],[-2.408,-1.573],[-8.491,0],[0,0.398],[-0.105,-0.002],[-7.192,0],[0,7.229],[0,0],[6.215,0],[0,-5.297]],"v":[[34.89,4.326],[36.461,-3.943],[13.922,-26.6],[-6.397,-13.699],[-14.758,-16.195],[-30.131,-0.743],[-30.072,0.436],[-30.385,0.421],[-43.407,13.51],[-30.385,26.6],[32.153,26.6],[43.407,15.288]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[204.97,46.37],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":4,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.864,0.973],[0,2.308],[9.837,0],[2.868,-6.024],[2.438,0],[0,-6.744],[-0.023,-0.309],[0.084,0],[0,-5.712],[-5.683,0],[0,0],[0,4.937]],"o":[[0.792,-2.026],[0,-9.888],[-7.087,0],[-1.903,-1.244],[-6.709,0],[0,0.315],[-0.083,-0.002],[-5.683,0],[0,5.713],[0,0],[4.911,0],[0,-4.185]],"v":[[27.571,3.418],[28.813,-3.116],[11.002,-21.019],[-5.054,-10.825],[-11.661,-12.799],[-23.809,-0.588],[-23.762,0.344],[-24.01,0.331],[-34.3,10.675],[-24.01,21.019],[25.408,21.019],[34.3,12.08]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[74.011,377.794],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":4,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":423.000017229143,"st":0,"bm":0}]},{"id":"comp_3","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"loading 2 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[-360]},{"t":899.000036617021}],"ix":10},"p":{"a":0,"k":[219.5,200.5,0],"ix":2},"a":{"a":0,"k":[219.5,200.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-13.817,-12.686],[-0.161,0.161],[-0.619,-0.249],[-0.372,0.747],[0.557,0.56],[-0.248,0.498],[0,0.499],[0.682,0.686],[1.61,0.872],[0.744,0.747],[0.62,0.872],[1.115,0.498],[0.868,0.872],[0.682,0.685],[0.992,0],[0.455,-0.595]],"o":[[0.366,-0.521],[0.42,-0.423],[0.62,0.249],[0.372,-0.748],[-0.558,-0.561],[0.247,-0.499],[0,-0.498],[-0.682,-0.685],[-1.612,-0.873],[-0.743,-0.748],[-0.62,-0.872],[-1.116,-0.499],[-0.867,-0.872],[-0.681,-0.685],[-0.475,0],[5.873,18.33]],"v":[[11.83,24.201],[12.704,23.046],[16.546,23.017],[18.034,21.024],[16.051,16.788],[16.299,13.798],[18.034,9.436],[15.307,5.077],[8.119,-0.155],[1.797,-4.516],[-2.045,-10.869],[-6.011,-13.112],[-8.738,-18.345],[-13.2,-21.709],[-16.918,-24.2],[-18.406,-23.034]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.481999984442,0.779999976065,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[134.939,259.809],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.079,-0.079],[-0.246,-0.247],[-0.281,0.282],[-0.351,0.494],[-0.069,0.282],[0.633,0.141],[0.099,0.171],[0.673,-1.216]],"o":[[0.175,0.176],[0.246,0.247],[0.281,-0.283],[0.352,-0.495],[0.071,-0.283],[-0.135,-0.03],[-0.717,1.186],[0.231,0.013]],"v":[[-1.315,1.19],[-0.894,2.249],[-0.051,2.249],[0.862,0.344],[1.775,-1.281],[0.581,-2.199],[0.235,-2.531],[-1.846,1.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.481999984442,0.779999976065,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[126.84,148.991],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.22,0],[-0.14,0.283],[-0.14,0.141],[-0.176,0.176],[0.07,0.283],[0.211,0.353],[0.405,0.177],[0.836,-1.85]],"o":[[0.421,0],[0.141,-0.282],[0.141,-0.141],[0.176,-0.176],[-0.071,-0.282],[-0.166,-0.281],[-0.935,1.793],[0.562,0.215]],"v":[[-1.029,2.926],[-0.327,1.938],[-0.257,0.243],[2.272,1.161],[1.992,-0.674],[1.429,-2.015],[0.214,-2.926],[-2.448,2.538]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.481999984442,0.779999976065,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[123.463,155.445],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":4,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.479,-0.481],[0,-0.412],[-0.205,0.206],[0,0.344],[0,0.481],[0.342,0],[0,0]],"o":[[0.479,0.481],[0,0.413],[0.205,-0.206],[0,-0.344],[0,-0.481],[0,0],[-0.068,0.206]],"v":[[-0.956,-0.995],[-0.752,1.34],[0.068,2.302],[1.025,1.203],[1.436,-1.82],[0.82,-2.507],[-0.752,-2.507]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.481999984442,0.779999976065,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[209.388,194.4],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":4,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.137,0.343],[0.359,-0.328],[0.068,-0.344],[-0.329,0]],"o":[[-0.137,-0.344],[0,0],[-0.068,0.343],[0.329,0]],"v":[[0.786,0.748],[0.102,-1.038],[-0.855,0.061],[-0.227,1.367]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.481999984442,0.779999976065,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[209.765,189.496],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":4,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.41,-0.069],[-0.342,0],[0.136,0.137],[0.479,-0.138],[0.41,-0.619],[-0.41,-0.138]],"o":[[0.41,0.068],[0.341,0],[-0.137,-0.138],[0,0],[0,0],[0.41,0.136]],"v":[[-0.307,0.515],[1.606,0.927],[2.154,0.173],[0.512,-0.103],[-1.88,-0.309],[-1.88,0.653]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.481999984442,0.779999976065,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[235.393,203.88],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":4,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.479,-0.137],[0,0],[0,0.413],[0.41,0],[0.342,0],[0,0],[-0.342,-0.069]],"o":[[0.479,0.137],[0.957,-0.275],[0,-0.412],[-0.41,0],[-0.341,0],[0,0],[0.341,0.069]],"v":[[0.205,0.549],[1.435,1.443],[2.324,-0.275],[1.435,-1.305],[-0.957,-1.442],[-2.392,-1.03],[-1.572,-0.206]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.481999984442,0.779999976065,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[217.59,199.587],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":4,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.544,0.21],[0,0.799],[0.293,0.546],[0.669,-0.042],[0.209,0.294],[0.334,-0.337],[0.502,-0.169],[-0.137,-0.137],[1.004,0.042],[0.167,-0.378],[-0.167,-0.252],[-0.065,-0.252],[0,0],[0,0],[0.23,-0.231],[-0.209,-0.505],[-0.376,0],[-0.419,0.421],[-0.878,0],[-0.418,0.126],[-0.168,0.505],[-0.041,0.421],[0.125,0.463]],"o":[[0.543,-0.21],[0,-0.799],[-0.293,-0.547],[-0.669,0.042],[-0.209,-0.294],[-0.188,0.189],[-0.502,0.168],[0.136,0.137],[-1.004,-0.042],[-0.167,0.378],[0.168,0.252],[0.064,0.252],[0,0],[0,0],[-0.23,0.231],[0.209,0.504],[0.377,0],[0.418,-0.42],[0.879,0],[0.418,-0.126],[0.167,-0.504],[0.042,-0.42],[-0.126,-0.463]],"v":[[2.615,-1.43],[3.576,-2.061],[3.451,-3.532],[2.572,-4.289],[1.317,-3.995],[-0.021,-4.415],[-0.816,-3.49],[-1.276,-2.419],[-1.151,-1.682],[-2.991,-1.598],[-3.033,-0.505],[-3.139,0.168],[-2.531,0.924],[-2.74,1.808],[-3.326,2.691],[-3.535,3.784],[-3.075,4.709],[-1.569,4.33],[-0.482,3.405],[1.401,3.027],[2.238,2.312],[2.53,0.924],[2.405,-0.505]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.481999984442,0.779999976065,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[183.841,165.018],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":4,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.14,0.635],[-0.14,0.847],[0.386,0.388],[0,0.212],[-0.14,0.424],[-0.351,0.353],[-0.07,0.353],[0.14,0.706],[-0.176,0.177],[-0.07,-0.283],[-0.141,-0.353],[0,0],[-0.457,0.459],[-0.211,0.353],[0.351,-0.141],[0.562,0.071],[0.211,0.211],[-0.176,0.176],[0.421,0],[0.211,-0.353],[0.211,-0.212],[-0.07,0.423],[-0.141,0.424],[-0.597,0.6],[-0.632,0.283],[-0.421,0.211],[-0.351,0.494],[-0.246,0.247],[0,0.442],[0.211,0.565],[0.731,0.494],[-0.141,0.424],[0,0.283],[0.28,0.282],[0.312,-0.313],[0.352,0.07],[-0.141,0.424],[0.07,0.212],[0.159,-0.015],[0,-15.127],[-0.033,-1.1],[-0.36,0.726]],"o":[[0.139,-0.636],[0.14,-0.847],[-0.387,-0.388],[0,-0.211],[0.14,-0.423],[0.351,-0.354],[0.071,-0.353],[-0.141,-0.707],[0.176,-0.176],[0.071,0.282],[0.14,0.353],[0,0],[0.456,-0.459],[0.21,-0.353],[-0.351,0.141],[-0.562,-0.07],[-0.21,-0.212],[0.175,-0.177],[-0.421,0],[-0.211,0.353],[-0.21,0.212],[0.071,-0.424],[0.141,-0.424],[0.597,-0.6],[0.632,-0.282],[0.422,-0.212],[0.352,-0.494],[0.246,-0.247],[0,-0.443],[-0.21,-0.565],[-0.731,-0.494],[0.14,-0.424],[0,-0.282],[-0.281,-0.282],[-0.312,0.314],[-0.351,-0.071],[0.14,-0.423],[-0.025,-0.073],[-5.521,13.103],[0,1.107],[0.262,-0.377],[0.632,-1.27]],"v":[[-7.011,19.531],[-6.378,16.989],[-6.869,15.506],[-6.729,14.235],[-5.816,12.823],[-5.465,10.776],[-3.709,9.152],[-3.568,6.822],[-2.023,4.915],[-0.899,4.421],[-0.828,5.974],[0.085,5.339],[1.63,3.503],[2.965,2.514],[2.403,2.02],[0.787,1.949],[-0.197,0.114],[0.717,-2.075],[-0.056,-2.923],[-1.531,-1.299],[-2.655,0.961],[-2.936,-0.451],[-2.093,-3.064],[-0.688,-4.688],[1.068,-5.465],[3.807,-5.888],[5.282,-8.077],[7.671,-9.419],[8.233,-10.991],[7.6,-13.373],[4.762,-15.844],[4.44,-17.609],[4.931,-20.01],[3.878,-21.916],[2.543,-20.937],[1.208,-19.515],[0.647,-20.716],[0.647,-22.905],[0.343,-22.967],[-8.233,19.673],[-8.179,22.982],[-7.221,21.366]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.481999984442,0.779999976065,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[119.54,183.536],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":4,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.374,-0.15],[0,-0.376],[0.149,-0.528],[-0.599,0],[-0.525,0.15],[-0.3,0.602],[-0.299,0.452],[0,0.602],[0.899,-0.452],[1.198,-0.828],[0.674,-0.301],[0,-0.376],[-0.149,-0.301]],"o":[[-0.375,0.15],[0,0.377],[-0.151,0.526],[0.599,0],[0.523,-0.151],[0.299,-0.602],[0.3,-0.452],[0,-0.602],[0,0],[-1.198,0.827],[-0.674,0.301],[0,0.376],[0.149,0.302]],"v":[[-4.004,3.273],[-5.277,4.552],[-4.902,6.585],[-3.78,7.788],[-1.234,7.036],[2.358,1.844],[4.229,-3.122],[5.277,-5.003],[4.229,-7.335],[2.358,-4.401],[-1.16,-2.595],[-3.481,-0.714],[-3.256,1.317]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.481999984442,0.779999976065,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[262.589,286.337],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10","np":4,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.219,-0.514],[0.145,-0.146],[-0.584,-0.22],[-0.072,-0.806],[0,-0.513],[0.658,-0.147],[0.657,0.294],[0,0.367],[-0.145,0.293],[0.219,0.586],[0.438,0.953],[0.146,0.733],[0.364,0.366],[-0.511,0.514],[-0.548,0.55],[-1.167,0],[-1.022,0.366],[-0.366,-0.66],[-0.147,-0.807],[-0.729,-0.147],[0.219,-0.514],[0,0],[0.292,0.66],[0.511,0.073],[0.218,-0.367],[-0.146,-0.44],[0,-0.514],[-0.73,-0.22],[-0.219,-0.366],[-0.219,-0.367],[-0.328,0.33],[-0.219,-0.44]],"o":[[-0.219,0.513],[-0.147,0.147],[0.584,0.22],[0.073,0.807],[0,0.513],[-0.656,0.146],[-0.657,-0.293],[0,-0.367],[0.146,-0.293],[-0.219,-0.587],[-0.438,-0.953],[-0.146,-0.733],[-0.365,-0.367],[0.51,-0.513],[0.547,-0.55],[1.167,0],[1.021,-0.367],[0.364,0.66],[0.145,0.806],[0.73,0.147],[-0.219,0.513],[-0.073,-1.027],[-0.292,-0.659],[-0.51,-0.073],[-0.219,0.367],[0.146,0.44],[0,0.513],[0.729,0.22],[0.219,0.367],[0.219,0.366],[0.328,-0.33],[0.219,0.44]],"v":[[31.062,-18.783],[28.655,-18.856],[29.311,-17.902],[30.478,-15.336],[30.406,-11.082],[28.508,-10.495],[24.204,-11.889],[23.329,-13.429],[23.839,-16.802],[24.569,-19.076],[21.286,-23.329],[21.067,-26.262],[19.681,-27.142],[21.578,-29.416],[23.183,-30.882],[25.298,-31.469],[27.706,-32.642],[28.874,-31.762],[29.166,-29.562],[30.478,-29.049],[30.77,-28.095],[29.457,-26.63],[28.363,-28.316],[26.684,-28.462],[26.247,-27.362],[25.736,-26.555],[26.174,-25.455],[27.195,-23.77],[28.363,-22.229],[28.363,-20.542],[29.603,-21.716],[30.916,-20.322]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[17.287,19.368],[0.068,0.023],[0.236,-0.238],[-0.052,-0.476],[-0.183,-0.185],[0.132,0.132],[0.236,0.237],[0.262,-0.106],[0.211,0],[0,0.529],[0.052,-0.158],[0,0],[-0.132,-0.132],[-0.316,-0.159],[-0.052,-0.369],[0.105,-0.211],[0.157,0.159],[-0.105,0.317],[0.053,0.158],[0,0],[-0.106,0.317],[0.159,0.158],[0.368,0],[0.211,-0.211],[0,-0.528],[0.21,-0.211],[-0.21,-0.211],[0.236,-0.237],[-0.342,-0.343],[0,0],[2.863,1.466],[0.918,0.434],[2.647,0.326],[0.055,0.327],[0.055,0.435],[0.918,0.271],[1.08,0.272],[0.378,0.76],[-0.216,0.869],[-0.432,0.435],[-1.135,0.434],[-1.135,0],[-0.324,0.109],[0.054,0.326],[0.432,0],[1.188,0.109],[0.703,-0.109],[1.026,0.109],[0.486,-0.217],[0.135,-0.136],[0.162,-0.543],[0.189,-0.19],[0.378,-0.598],[0.324,-0.815],[-0.756,-0.325],[0.595,-0.109],[-0.378,-0.706],[-0.27,-1.249],[0.35,-0.353],[0.378,0.815],[-0.055,-0.38],[0.216,-0.217],[0.27,0.271],[0.433,-0.217],[0.053,-0.217],[0.109,-0.108],[0.379,0.108],[0.162,-0.272],[-0.431,-0.163],[0.189,-0.189],[0.595,0.163],[0.757,0.435],[0,0.434],[-0.162,0.814],[0.216,0.434],[-0.432,0],[-0.648,-0.163],[-0.919,-0.326],[-0.486,0],[-0.325,0.435],[-0.107,0.489],[0.243,0.244],[0.649,0.38],[0.27,0.108],[0.27,0],[0.135,0.136],[0.81,-0.108],[0.324,0.054],[-0.324,0.162],[-0.298,0.298],[0.324,0.326],[0.702,0],[0.324,0.163],[0.405,-0.408],[0.216,-0.054],[0.27,0.055],[0.325,0],[0.379,-0.217],[0.864,-0.488],[1.08,-0.163],[1.188,-0.435],[0.622,-0.624],[0.676,-0.679],[0.433,-0.76],[0.405,-0.407],[0.54,-0.326],[0.27,-0.651],[-0.054,-0.76],[-0.595,-0.109],[-0.919,0.217],[-0.243,0.244],[-0.648,-0.163],[-0.054,-0.597],[-0.487,-0.489],[-0.27,-0.706],[-0.54,0],[-0.162,0.326],[-0.756,0.163],[-0.486,0.489],[-0.054,1.25],[-0.109,0.761],[-0.487,0.326],[-0.108,0.488],[0,0.272],[0.162,0.163],[0.378,0.108],[0.298,0.299],[0,0.489],[-0.54,0.923],[-0.595,0.381],[-0.486,0.109],[0.216,0.326],[-0.324,0.543],[-0.866,0.271],[-0.54,-0.325],[-0.108,-0.434],[0.323,-0.327],[0.459,-0.462],[0.648,-0.651],[0.188,-0.19],[-0.216,-0.434],[-0.324,-0.163],[-0.702,-0.435],[-0.81,0.054],[-0.81,0.163],[-0.378,0.163],[-0.324,-0.325],[0,-0.434],[0.323,0],[0.648,0],[0.648,0],[0.135,-0.136],[-0.217,-0.325],[-0.593,-0.109],[0.109,-0.489],[0.324,-0.163],[0.136,0.135],[0.19,-0.19],[0.108,-0.597],[-0.054,-0.217],[0.433,0],[0.162,-0.38],[0.378,0],[0.136,0.136],[0.163,-0.162],[0.27,-0.271],[0.54,-0.163],[-0.054,-0.435],[0.216,0.217],[0.109,0.109],[0.324,0],[0.27,-0.109],[0.107,0.489],[0.216,0.217],[0.054,0.434],[-0.243,0.245],[-0.107,0.272],[-0.055,0.325],[0.136,-0.136],[0.54,-0.109],[0.378,-0.489],[0.053,-0.652],[-0.297,-0.298],[-0.108,-0.326],[0.27,-0.543],[0.486,0.108],[0.325,0],[0.593,-0.163],[0.325,-0.435],[0.216,-0.543],[0.756,-0.271],[0.217,-0.326],[0.162,-0.272],[0.271,0],[0.108,-0.271],[0.163,0.163],[0.27,-0.054],[-0.162,-0.327],[0.122,-0.122],[0.324,0.109],[0.324,-0.108],[0.216,-0.326],[0,-0.434],[-0.594,-0.434],[-0.54,0],[-0.215,-0.652],[-0.297,-0.298],[0.054,-0.652],[0.487,-0.325],[1.08,0],[0.649,0.217],[0.378,-0.109],[0.216,-0.217],[0,0],[-0.27,-0.924],[0,-1.086],[0.162,-0.434],[-0.594,-0.706],[-0.108,-0.271],[-0.324,-0.326],[-0.487,-0.108],[-0.189,0.19],[-0.432,-0.055],[0,0.434],[-0.756,0.435],[-0.216,0.434],[0.108,0.489],[-0.27,0.815],[-0.648,0.272],[-0.324,0.543],[0,1.086],[-0.27,0.271],[-0.54,0],[-0.756,0.597],[-0.486,0],[-0.432,-0.651],[-0.297,-0.299],[-0.594,-0.434],[-0.324,-0.326],[-0.405,-0.407],[-0.053,-0.543],[0,-0.163],[-0.378,0],[-0.216,0.543],[-0.162,0.49],[0,0.271],[0.459,0.461],[-0.163,0.38],[-0.431,-0.054],[-0.162,-0.271],[0,0],[0.297,0.299],[0.594,0.327],[0.513,0.516],[0.594,0.598],[0.27,0.652],[0.702,0.543],[-0.054,1.032],[-0.811,0.163],[-0.108,-0.272],[-0.324,0.326],[-0.27,-0.597],[-0.216,-0.488],[-0.972,-0.217],[-0.433,-0.434],[-0.108,-0.977],[-0.432,-0.108],[-0.054,-0.598],[-0.486,-0.272],[0.054,-0.543],[-0.702,-0.163],[-0.216,-0.217],[-0.162,0.272],[-0.109,0.651],[-0.217,0.218],[0.379,0.101],[-0.216,0.326],[0.379,0.489],[-0.108,0.217],[-0.431,-0.055],[-0.054,0.38],[-1.027,0],[-0.379,-0.38],[-0.703,0.49],[-0.541,0],[0.431,0.434],[0.325,0.489],[-0.595,0.598],[-0.162,0.325],[-0.648,0.163],[0.162,0.706],[-0.595,0.38],[-0.702,-0.217],[-0.405,-0.407],[-0.217,-0.434],[-0.055,-0.381],[-0.432,-0.272],[-0.217,0.217],[-0.271,0.272],[0.594,0.38],[-0.162,0.38],[-1.297,0.218],[-0.595,-0.217],[0.271,-0.272],[0.378,0],[0,-0.488],[0.055,-0.217],[-0.486,-0.163],[-0.485,-0.326],[-0.161,-1.574],[0.648,-0.218],[1.189,0.271],[0.716,0.239],[0.299,-0.3],[0.477,0],[0.716,-0.119],[0.478,-0.479],[-0.477,0],[-0.238,-0.839],[-0.835,0],[-0.954,-0.599],[-1.669,0.719],[-0.477,0],[0,-1.079],[0.477,-1.438],[0.954,-0.6],[1.074,0.24],[0.596,-0.6],[1.192,0.24],[0.657,0.659],[1.075,-0.599],[0,-0.6],[1.193,0.359],[0.716,0.719],[1.551,0.36],[0.358,1.439],[-0.357,0.6],[0.716,0],[1.192,-0.36],[1.074,0],[0.835,-0.479],[1.073,0],[0.358,-0.36],[1.312,-1.318],[0.239,-0.48],[0.358,-1.799],[1.073,-1.078],[0.239,-1.079],[0,-1.078],[-0.358,-2.279],[0,-0.96],[-1.074,-1.439],[-0.835,-0.839],[-0.477,0],[-1.312,0],[-1.192,0],[-1.193,-0.359],[-1.67,0.24],[-0.656,-0.66],[-1.431,0],[-1.431,-1.678],[0,-0.959],[-1.55,-1.798],[-0.358,-0.959],[0.239,-1.319],[0,-0.6],[-0.835,-1.799],[-0.358,-1.559],[-1.313,-0.36],[-0.596,-1.079],[-0.476,-0.48],[-1.073,0],[-1.67,0.72],[-0.955,0.959],[0,0],[-0.656,0.659],[0,0.839],[-0.775,0.779],[-1.133,1.14],[0,0.839],[0,0.839],[0,0.481],[-0.835,1.319],[-1.073,1.079],[-1.312,1.559],[-0.238,0.839],[0,0],[0.597,0],[0.596,-0.6],[0.418,0.42],[0.417,0.42],[0.477,0],[0.358,0.72],[0.239,0.72],[0.716,0.72],[0,0.839],[0.536,0.539],[0.238,0.599],[0.477,0.72],[-0.358,0],[0,0],[0,0],[-0.476,-0.479],[-0.597,-0.839],[0,-0.36],[-0.537,-0.539],[-0.477,-1.318],[0,-1.199],[0,0],[-0.357,0.359],[-0.597,0],[-1.073,0.599],[-0.835,0.479],[0,0],[0.418,0.419],[0.716,0.359],[0,0],[0.835,-0.241],[0,0],[0.299,-0.299],[0.536,0.539],[0,0.838],[-1.193,0],[-0.298,-0.3],[-0.715,-0.719],[-1.194,0],[0,0],[-0.716,-0.24],[-1.075,0],[0,0],[-0.537,-0.539],[0.358,-0.36],[0,-0.839],[-0.716,0],[0,0],[0.238,-1.079],[-1.073,-1.798],[0,0],[-0.298,0.3],[0,-0.239],[-0.596,0.6],[0,0],[0,0.48],[0,0.359],[-1.074,0.72],[-0.656,0.66],[0,0],[-0.239,-0.6],[0.358,-0.6],[-0.478,0],[0,0],[0,0],[0,-0.599],[-0.358,-1.079],[-0.002,-0.007],[-0.176,0.457],[0,0.152],[0,0],[0,0],[-0.835,-0.36],[-0.088,-0.109],[0,11.336]],"o":[[-0.124,-0.059],[-0.314,-0.105],[-0.237,0.238],[0.052,0.475],[0.185,0.185],[-0.131,-0.133],[-0.238,-0.238],[-0.263,0.106],[-0.21,0],[0,-0.528],[-0.053,0.159],[0,0],[0.131,0.132],[0.315,0.158],[0.053,0.371],[-0.105,0.212],[-0.158,-0.158],[0.106,-0.317],[-0.052,-0.159],[0,0],[0.104,-0.317],[-0.157,-0.159],[-0.368,0],[-0.21,0.212],[0,0.528],[-0.211,0.212],[0.211,0.211],[-0.237,0.238],[0.341,0.343],[-0.108,0.271],[-2.864,-1.466],[-0.919,-0.435],[-2.648,-0.325],[-0.053,-0.325],[-0.053,-0.434],[-0.919,-0.272],[-1.081,-0.271],[-0.378,-0.761],[0.216,-0.869],[0.433,-0.434],[1.135,-0.435],[1.134,0],[0.324,-0.108],[-0.054,-0.326],[-0.432,0],[-1.189,-0.108],[-0.703,0.109],[-1.027,-0.109],[-0.485,0.217],[-0.135,0.136],[-0.162,0.543],[-0.188,0.19],[-0.378,0.597],[-0.324,0.814],[0.756,0.326],[-0.594,0.108],[0.378,0.706],[0.271,1.249],[-0.352,0.353],[-0.378,-0.815],[0.053,0.38],[-0.216,0.217],[-0.27,-0.272],[-0.432,0.218],[-0.054,0.217],[-0.108,0.109],[-0.378,-0.109],[-0.162,0.271],[0.433,0.163],[-0.189,0.19],[-0.595,-0.162],[-0.756,-0.434],[0,-0.435],[0.162,-0.815],[-0.216,-0.435],[0.433,0],[0.649,0.163],[0.918,0.326],[0.486,0],[0.324,-0.434],[0.108,-0.489],[-0.243,-0.245],[-0.648,-0.38],[-0.27,-0.109],[-0.27,0],[-0.135,-0.136],[-0.811,0.109],[-0.324,-0.055],[0.324,-0.163],[0.297,-0.299],[-0.324,-0.325],[-0.703,0],[-0.324,-0.164],[-0.405,0.407],[-0.215,0.055],[-0.271,-0.054],[-0.323,0],[-0.378,0.217],[-0.864,0.489],[-1.081,0.163],[-1.189,0.434],[-0.621,0.625],[-0.675,0.679],[-0.432,0.76],[-0.405,0.408],[-0.541,0.326],[-0.27,0.652],[0.054,0.76],[0.594,0.108],[0.918,-0.218],[0.243,-0.245],[0.648,0.163],[0.054,0.598],[0.485,0.489],[0.271,0.706],[0.54,0],[0.162,-0.326],[0.757,-0.162],[0.486,-0.489],[0.055,-1.249],[0.107,-0.76],[0.486,-0.325],[0.108,-0.489],[0,-0.271],[-0.162,-0.163],[-0.379,-0.109],[-0.297,-0.299],[0,-0.489],[0.54,-0.923],[0.595,-0.38],[0.486,-0.108],[-0.216,-0.326],[0.324,-0.543],[0.864,-0.272],[0.54,0.327],[0.108,0.435],[-0.324,0.325],[-0.459,0.461],[-0.649,0.652],[-0.19,0.19],[0.216,0.435],[0.324,0.163],[0.702,0.434],[0.811,-0.054],[0.811,-0.163],[0.378,-0.163],[0.324,0.326],[0,0.435],[-0.324,0],[-0.649,0],[-0.648,0],[-0.136,0.136],[0.216,0.326],[0.595,0.108],[-0.107,0.488],[-0.324,0.162],[-0.135,-0.136],[-0.189,0.19],[-0.108,0.597],[0.053,0.217],[-0.432,0],[-0.162,0.38],[-0.378,0],[-0.135,-0.136],[-0.162,0.163],[-0.27,0.272],[-0.54,0.163],[0.054,0.434],[-0.216,-0.218],[-0.107,-0.109],[-0.324,0],[-0.27,0.108],[-0.108,-0.489],[-0.216,-0.217],[-0.054,-0.434],[0.243,-0.244],[0.109,-0.271],[0.053,-0.326],[-0.135,0.136],[-0.541,0.109],[-0.378,0.488],[-0.054,0.651],[0.297,0.299],[0.108,0.326],[-0.27,0.543],[-0.486,-0.109],[-0.324,0],[-0.595,0.163],[-0.323,0.435],[-0.216,0.543],[-0.757,0.272],[-0.216,0.326],[-0.162,0.271],[-0.27,0],[-0.108,0.272],[-0.162,-0.163],[-0.27,0.055],[0.162,0.325],[-0.121,0.122],[-0.324,-0.108],[-0.324,0.109],[-0.216,0.325],[0,0.435],[0.595,0.435],[0.54,0],[0.217,0.651],[0.298,0.299],[-0.054,0.651],[-0.486,0.326],[-1.08,0],[-0.648,-0.217],[-0.378,0.109],[-0.216,0.217],[0,0],[0.27,0.923],[0,1.086],[-0.163,0.434],[0.594,0.706],[0.108,0.272],[0.324,0.326],[0.486,0.108],[0.189,-0.19],[0.433,0.054],[0,-0.435],[0.756,-0.435],[0.216,-0.435],[-0.108,-0.489],[0.27,-0.814],[0.649,-0.271],[0.325,-0.543],[0,-1.086],[0.27,-0.272],[0.541,0],[0.757,-0.598],[0.486,0],[0.432,0.652],[0.297,0.298],[0.594,0.435],[0.324,0.326],[0.405,0.407],[0.055,0.543],[0,0.164],[0.378,0],[0.217,-0.543],[0.162,-0.488],[0,-0.272],[-0.459,-0.462],[0.162,-0.38],[0.433,0.055],[0.163,0.272],[0,0],[-0.298,-0.299],[-0.595,-0.325],[-0.513,-0.515],[-0.595,-0.597],[-0.27,-0.651],[-0.702,-0.543],[0.054,-1.032],[0.81,-0.163],[0.108,0.271],[0.325,-0.326],[0.27,0.597],[0.217,0.489],[0.973,0.217],[0.431,0.435],[0.107,0.978],[0.432,0.109],[0.053,0.597],[0.486,0.272],[-0.054,0.543],[0.703,0.163],[0.217,0.217],[0.162,-0.272],[0.108,-0.652],[0.215,-0.217],[-0.378,-0.101],[0.215,-0.326],[-0.378,-0.488],[0.108,-0.217],[0.433,0.054],[0.054,-0.38],[1.026,0],[0.377,0.38],[0.703,-0.488],[0.54,0],[-0.433,-0.435],[-0.324,-0.489],[0.593,-0.597],[0.162,-0.326],[0.649,-0.163],[-0.162,-0.706],[0.593,-0.38],[0.702,0.217],[0.406,0.407],[0.216,0.435],[0.054,0.38],[0.432,0.271],[0.216,-0.218],[0.27,-0.271],[-0.595,-0.38],[0.162,-0.38],[1.297,-0.217],[0.593,0.218],[-0.269,0.271],[-0.379,0],[0,0.489],[-0.053,0.217],[0.487,0.163],[0.486,0.326],[0.162,1.576],[-0.648,0.217],[-1.188,-0.272],[-0.715,-0.24],[-0.298,0.299],[-0.477,0],[-0.716,0.12],[-0.477,0.48],[0.478,0],[0.24,0.839],[0.835,0],[0.954,0.6],[1.67,-0.72],[0.477,0],[0,1.079],[-0.477,1.44],[-0.954,0.598],[-1.073,-0.24],[-0.597,0.6],[-1.193,-0.24],[-0.655,-0.659],[-1.073,0.6],[0,0.6],[-1.192,-0.361],[-0.715,-0.719],[-1.551,-0.359],[-0.358,-1.439],[0.358,-0.599],[-0.716,0],[-1.193,0.36],[-1.073,0],[-0.834,0.48],[-1.074,0],[-0.357,0.359],[-1.312,1.32],[-0.238,0.48],[-0.358,1.798],[-1.073,1.08],[-0.238,1.078],[0,1.08],[0.357,2.278],[0,0.959],[1.073,1.439],[0.835,0.84],[0.477,0],[1.312,0],[1.193,0],[1.193,0.361],[1.67,-0.24],[0.656,0.659],[1.431,0],[1.431,1.679],[0,0.959],[1.551,1.799],[0.358,0.959],[-0.239,1.318],[0,0.6],[0.835,1.798],[0.358,1.558],[1.311,0.36],[0.596,1.079],[0.478,0.479],[1.073,0],[1.669,-0.719],[0.954,-0.96],[0,0],[0.656,-0.659],[0,-0.839],[0.776,-0.779],[1.133,-1.139],[0,-0.84],[0,-0.839],[0,-0.479],[0.835,-1.319],[1.074,-1.079],[1.312,-1.559],[0.239,-0.84],[0,0],[-0.596,0],[-0.596,0.599],[-0.417,-0.42],[-0.418,-0.42],[-0.477,0],[-0.358,-0.72],[-0.238,-0.72],[-0.716,-0.72],[0,-0.84],[-0.537,-0.54],[-0.239,-0.599],[-0.477,-0.719],[0.358,0],[0,0],[0,0],[0.478,0.48],[0.596,0.839],[0,0.359],[0.536,0.54],[0.478,1.319],[0,1.199],[0,0],[0.358,-0.36],[0.596,0],[1.074,-0.599],[0.835,-0.48],[0,0],[-0.417,-0.42],[-0.716,-0.36],[0,0],[-0.835,0.239],[0,0],[-0.298,0.3],[-0.537,-0.54],[0,-0.84],[1.193,0],[0.298,0.299],[0.716,0.719],[1.192,0],[0,0],[0.716,0.239],[1.073,0],[0,0],[0.537,0.54],[-0.358,0.36],[0,0.84],[0.714,0],[0,0],[-0.238,1.08],[1.073,1.799],[0,0],[0.298,-0.299],[0,0.24],[0.597,-0.6],[0,0],[0,-0.48],[0,-0.36],[1.073,-0.72],[0.656,-0.659],[0,0],[0.239,0.6],[-0.357,0.599],[0.476,0],[0,0],[0,1.079],[0,0.6],[0.002,0.007],[0.181,-0.455],[-0.098,-0.522],[0,0],[0,-0.838],[0,0],[0.13,0.056],[3.184,-10.283],[0,-28.068]],"v":[[51.736,-81.983],[51.435,-82.115],[50.49,-82.062],[50.542,-81.111],[51.382,-80.319],[50.647,-79.896],[49.702,-80.477],[48.283,-80.319],[48.387,-79.051],[46.968,-80.425],[46.496,-81.534],[45.498,-81.111],[45.445,-80.214],[46.443,-79.262],[46.758,-77.467],[46.338,-75.671],[45.235,-75.988],[45.129,-77.942],[44.551,-79.685],[43.658,-80.583],[43.816,-82.485],[43.132,-83.488],[41.556,-84.016],[40.294,-84.546],[40.084,-82.643],[38.824,-82.168],[39.191,-80.847],[39.402,-79.844],[40.663,-77.889],[41.251,-76.796],[37.74,-78.153],[35.525,-79.402],[32.121,-79.837],[31.634,-81.033],[31.256,-82.335],[29.204,-83.312],[27.205,-84.073],[26.07,-85.81],[26.232,-87.711],[26.772,-89.178],[28.555,-90.318],[35.579,-91.404],[38.226,-91.676],[37.902,-92.436],[36.119,-92.925],[33.04,-93.251],[30.338,-93.142],[27.313,-92.979],[25.313,-92.654],[24.233,-91.947],[23.531,-90.861],[22.936,-90.102],[22.18,-88.797],[20.559,-86.516],[22.504,-84.943],[20.559,-84.344],[18.668,-83.149],[19.046,-80.651],[16.832,-78.589],[13.86,-78.153],[12.996,-77.61],[14.4,-75.492],[12.455,-76.253],[9.267,-75.927],[7.539,-74.623],[7.376,-72.615],[3.756,-74.514],[2.676,-73.754],[3.918,-72.559],[4.567,-71.365],[2.352,-71.528],[-0.133,-72.777],[-0.673,-73.809],[-0.62,-75.709],[-1.376,-77.012],[-1.268,-77.882],[0.461,-77.61],[2.623,-76.741],[5.972,-76.198],[8.079,-76.633],[8.727,-78.099],[7.863,-79.999],[4.135,-81.466],[-1.268,-83.909],[-3.591,-84.073],[-3.321,-85.159],[-5.806,-85.159],[-8.183,-85.43],[-8.237,-86.353],[-6.724,-86.68],[-7.697,-87.44],[-10.074,-87.386],[-10.615,-88.471],[-12.181,-87.766],[-13.208,-87.82],[-14.342,-87.386],[-14.451,-88.526],[-15.801,-88.201],[-17.53,-87.06],[-19.907,-86.734],[-22.878,-85.81],[-27.039,-83.421],[-31.199,-79.783],[-33.414,-76.253],[-35.899,-73.483],[-42.76,-68.812],[-44.597,-67.346],[-44.597,-60.123],[-42.922,-58.439],[-40.491,-58.439],[-37.79,-61.643],[-36.277,-61.915],[-35.737,-59.906],[-35.358,-57.679],[-33.198,-54.095],[-32.441,-52.574],[-31.469,-52.954],[-29.686,-54.421],[-27.633,-55.344],[-27.309,-57.572],[-27.092,-59.526],[-25.417,-61.318],[-23.959,-62.512],[-24.175,-63.219],[-24.769,-63.653],[-25.742,-64.141],[-26.823,-65.229],[-27.254,-66.531],[-26.174,-68.975],[-23.689,-71.528],[-20.285,-72.94],[-20.393,-73.754],[-19.961,-75.655],[-17.421,-76.958],[-15.044,-76.633],[-13.964,-74.895],[-14.774,-74.352],[-16.017,-73.048],[-18.34,-71.039],[-20.393,-69.681],[-20.177,-68.921],[-19.637,-64.686],[-18.178,-63.598],[-15.369,-63.49],[-11.911,-64.25],[-8.994,-64.74],[-8.021,-63.816],[-6.67,-62.567],[-9.263,-62.35],[-11.046,-61.806],[-14.126,-61.97],[-16.395,-61.535],[-16.233,-60.069],[-14.991,-59.199],[-14.991,-57.408],[-15.855,-55.995],[-17.476,-57.354],[-19.205,-57.679],[-19.961,-55.725],[-20.177,-52.031],[-21.528,-51.434],[-22.987,-50.565],[-24.067,-50.186],[-25.148,-50.945],[-26.499,-50.729],[-28.119,-49.859],[-30.172,-49.37],[-30.496,-48.229],[-31.523,-48.501],[-32.604,-49.859],[-34.116,-50.076],[-35.845,-48.936],[-36.709,-50.24],[-38.06,-50.783],[-38.222,-52.194],[-37.304,-53.552],[-36.602,-54.638],[-37.195,-56.158],[-37.574,-57.299],[-38.924,-56.757],[-40.545,-55.615],[-41.031,-53.824],[-40.275,-52.466],[-39.681,-51.162],[-40.113,-48.827],[-41.788,-48.393],[-42.977,-47.632],[-45.299,-47.199],[-46.813,-45.677],[-47.569,-43.342],[-50.216,-42.311],[-51.513,-41.604],[-51.891,-39.594],[-53.404,-39.486],[-53.728,-38.4],[-55.187,-38.237],[-56.429,-39.052],[-56.699,-38.182],[-56.916,-36.689],[-58.266,-36.608],[-59.887,-36.608],[-61.021,-36.337],[-61.129,-35.359],[-59.887,-34.327],[-57.942,-34.11],[-57.078,-32.48],[-55.781,-31.177],[-55.781,-28.408],[-57.078,-25.149],[-59.725,-24.931],[-63.345,-25.529],[-65.56,-25.04],[-66.856,-25.203],[-68.423,-24.443],[-68.153,-23.085],[-68.207,-18.306],[-68.963,-16.188],[-68.369,-14.667],[-68.045,-11.844],[-64.371,-11.41],[-63.128,-10.16],[-61.994,-10.867],[-58.645,-10.811],[-57.564,-11.464],[-56.375,-12.821],[-54.484,-14.776],[-54.484,-16.405],[-53.782,-18.904],[-51.513,-20.75],[-49.082,-22.108],[-49.514,-24.117],[-47.947,-25.583],[-45.354,-24.714],[-43.841,-25.094],[-39.627,-27.375],[-37.844,-25.529],[-35.575,-22.596],[-31.793,-20.153],[-30.658,-18.306],[-29.146,-17.22],[-28.66,-15.591],[-28.984,-13.636],[-28.227,-13.311],[-27.471,-13.908],[-27.147,-15.211],[-26.552,-16.405],[-27.201,-17.274],[-27.254,-18.74],[-25.959,-18.632],[-25.04,-17.546],[-24.284,-18.089],[-24.769,-19.066],[-26.876,-20.153],[-28.713,-21.565],[-31.09,-23.303],[-32.063,-25.258],[-34.224,-26.669],[-34.386,-29.059],[-32.711,-30.688],[-32.063,-29.493],[-31.037,-29.602],[-29.848,-28.354],[-28.984,-25.692],[-26.661,-24.66],[-22.932,-21.945],[-22.608,-19.555],[-21.96,-16.949],[-20.879,-16.079],[-19.475,-14.233],[-19.961,-12.658],[-18.665,-11.3],[-17.476,-10.594],[-16.935,-11.083],[-16.503,-12.929],[-15.422,-13.636],[-16.288,-14.551],[-16.881,-15.862],[-17.314,-17.383],[-17.692,-18.849],[-16.666,-18.36],[-16.017,-19.339],[-13.045,-19.772],[-11.586,-18.632],[-10.128,-19.61],[-8.399,-20.098],[-7.588,-20.858],[-9.534,-22.759],[-9.209,-24.823],[-8.021,-26.832],[-6.617,-28.354],[-6.508,-29.711],[-5.049,-32.046],[-2.186,-32.372],[-1.7,-31.177],[-0.241,-30.634],[-0.889,-29.167],[0.137,-28.19],[1.272,-27.701],[3.271,-29.059],[1.974,-29.928],[1.866,-31.829],[5.053,-32.752],[8.62,-33.404],[7.214,-31.938],[6.783,-30.852],[6.404,-29.548],[5.593,-28.733],[6.512,-28.027],[11.104,-24.497],[12.779,-22.108],[10.564,-19.936],[5.972,-19.882],[2.043,-22.579],[-1.774,-21.62],[-4.994,-20.421],[-6.425,-19.104],[-10.481,-17.904],[-10.481,-16.945],[-10.243,-12.868],[-6.187,-9.751],[-2.966,-10.59],[0.85,-10.35],[3.713,-11.189],[4.071,-8.552],[3.117,-3.277],[0.135,-0.158],[-4.279,-0.279],[-7.26,0.201],[-11.554,-0.039],[-15.372,-1.598],[-20.501,-2.438],[-22.05,1.28],[-25.152,0.921],[-29.208,-1.358],[-33.024,-3.158],[-37.795,-5.554],[-36.603,-8.552],[-38.153,-11.91],[-43.043,-11.549],[-49.723,-10.83],[-54.375,-9.751],[-58.549,-8.192],[-63.917,-8.791],[-65.706,-5.436],[-69.165,-2.798],[-70.119,2.359],[-73.22,4.635],[-76.202,9.913],[-79.542,16.266],[-78.11,24.42],[-79.065,28.976],[-74.651,34.37],[-71.073,40.725],[-66.183,44.922],[-63.678,45.882],[-60.1,44.802],[-56.402,45.521],[-51.631,43.603],[-45.906,44.323],[-42.805,46.841],[-38.511,48.159],[-38.988,55.953],[-34.933,59.909],[-32.189,67.582],[-32.547,70.699],[-34.694,75.616],[-32.905,79.332],[-30.4,85.327],[-27.895,87.844],[-25.629,90.962],[-23.244,92.88],[-17.637,92.16],[-11.912,89.763],[-7.379,86.286],[-5.829,83.409],[-2.37,81.729],[-3.205,78.612],[-0.581,75.854],[4.667,72.617],[6.099,67.703],[5.263,63.385],[5.383,60.388],[7.649,56.792],[13.732,50.557],[19.458,44.323],[24.109,36.769],[24.467,34.01],[20.054,35.57],[16.595,36.41],[14.329,35.689],[13.255,33.532],[10.273,29.814],[8.484,28.736],[7.172,23.939],[5.025,22.861],[4.548,17.226],[2.64,14.948],[0.97,10.392],[-1.416,5.236],[-1.416,3.558],[0.97,5.956],[1.924,4.038],[4.309,9.193],[6.099,12.79],[8.842,17.586],[8.842,19.624],[12.42,24.898],[13.852,28.976],[14.209,32.691],[15.879,31.614],[19.816,30.415],[22.797,28.495],[27.21,26.458],[36.157,16.027],[36.633,13.989],[33.89,11.711],[32.458,10.392],[29.119,12.551],[26.853,12.43],[25.779,10.991],[24.229,10.392],[21.843,2.839],[24.109,1.519],[25.541,2.839],[27.449,5.836],[30.074,7.394],[33.89,6.915],[35.56,9.312],[39.616,10.152],[46.175,9.312],[47.249,12.189],[49.754,13.629],[48.442,14.708],[49.874,16.385],[52.378,14.468],[51.901,21.301],[52.974,27.176],[54.763,34.491],[56.791,32.092],[56.791,35.57],[58.103,35.57],[57.268,30.535],[57.865,28.495],[58.938,23.461],[62.159,19.743],[65.737,13.148],[69.434,11.111],[70.508,14.948],[70.269,18.545],[70.747,19.984],[72.178,18.185],[72.178,21.782],[70.747,27.057],[71.701,31.853],[71.706,31.872],[72.243,30.505],[72.058,29.336],[72.058,26.098],[73.251,22.141],[74.325,23.34],[74.643,23.601],[79.542,-8.951]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.481999984442,0.779999976065,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[249.445,212.16],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11","np":6,"cix":2,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.076,-0.152],[-0.566,0.228],[-0.792,-0.455],[-0.792,0.796],[-1.132,0.683],[-1.019,0.683],[0,0.569],[0.679,0.341],[0,0],[0.202,-0.05],[0.378,-0.077],[0.152,-0.711],[0.48,0.025],[0.151,-0.356],[0.177,0],[0,0.127],[-0.101,0.305],[0.202,0.076],[0.227,-0.102],[0.303,0.076],[0.151,-0.077],[0.051,-0.432],[0,-0.254],[-0.303,-0.076],[-0.253,0.153],[-0.177,-0.076],[0,-0.102],[0.127,0],[0.05,-0.127],[-0.278,0.076],[-0.202,-0.255]],"o":[[0.076,0.152],[0.566,-0.227],[0.792,0.455],[0.793,-0.797],[1.132,-0.682],[1.019,-0.682],[0,-0.569],[-0.679,-0.341],[0,0],[-0.203,0.051],[-0.379,0.076],[-0.151,0.711],[-0.48,-0.026],[-0.152,0.355],[-0.176,0],[0,-0.127],[0.101,-0.304],[-0.202,-0.076],[-0.227,0.102],[-0.303,-0.076],[-0.152,0.076],[-0.05,0.432],[0,0.254],[0.303,0.076],[0.252,-0.152],[0.177,0.076],[0,0.102],[-0.126,0],[-0.051,0.127],[0.278,-0.076],[0.202,0.254]],"v":[[-4.595,2.448],[-3.507,2.389],[-2.149,3.413],[-0.112,2.617],[2.718,1.365],[5.321,-0.228],[6.793,-2.503],[5.208,-3.527],[3.51,-3.755],[2.049,-3.317],[0.887,-3.189],[0.179,-2.174],[-1.437,-1.818],[-2.574,-1.386],[-3.282,-0.777],[-3.559,-1.285],[-3.155,-2.377],[-3.787,-2.834],[-4.671,-2.834],[-5.328,-2.351],[-6.035,-2.554],[-6.187,-1.488],[-6.793,-1.006],[-6.035,-0.574],[-5.075,-0.879],[-4.368,-0.625],[-4.57,0.01],[-5.606,0.365],[-6.136,0.645],[-5.353,0.848],[-4.671,1.331]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.481999984442,0.779999976065,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[170.849,140.674],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12","np":4,"cix":2,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.251,0.378],[0.335,0],[0.125,0.379],[0.126,0.337],[0.376,0.378],[-0.052,0.505],[0.292,0.042],[0.084,0.084],[-0.146,0.147],[-0.167,0.169],[-0.188,0.189],[0.083,0.168],[0.168,0.042],[0.251,0.126],[-0.272,0.273],[-0.085,0.178],[0,0],[0.167,0],[0.168,-0.042],[0.083,-0.63],[0.229,-0.231],[-0.125,-0.253],[-0.041,-0.253],[-0.083,-0.336],[-0.167,-0.252],[-0.376,-0.21],[0.042,-0.673],[0,-0.504],[-0.418,-0.042],[-0.251,0],[0.125,-0.379],[-0.293,-0.294],[0.167,-0.421],[0.126,0],[0.083,-0.252],[-0.377,-0.378],[0.293,-0.378],[0,-0.211],[-0.46,-0.085],[0.104,-0.105],[0.168,0.042],[0.126,-0.21],[0.084,-0.21],[-0.251,-0.252],[-0.67,0.168],[-0.083,0.21],[-0.377,-0.085],[-0.168,0.252],[-0.334,-0.043],[-0.377,0],[-0.419,-0.084],[0,0.168],[0.334,0.126],[-0.189,0.189]],"o":[[-0.251,-0.378],[-0.334,0],[-0.126,-0.378],[-0.125,-0.336],[-0.377,-0.378],[0.051,-0.504],[-0.293,-0.042],[-0.083,-0.084],[0.147,-0.147],[0.168,-0.168],[0.188,-0.19],[-0.084,-0.168],[-0.287,-0.072],[-0.251,-0.127],[0.209,-0.211],[0.025,-0.052],[0.413,-0.729],[-0.167,0],[-0.167,0.042],[-0.084,0.631],[-0.23,0.232],[0.126,0.252],[0.042,0.252],[0.084,0.337],[0.168,0.253],[0.377,0.21],[-0.042,0.673],[0,0.505],[0.419,0.042],[0.251,0],[-0.126,0.378],[0.293,0.294],[-0.167,0.42],[-0.125,0],[-0.084,0.253],[0.376,0.379],[-0.293,0.379],[0,0.21],[0.46,0.084],[-0.105,0.106],[-0.167,-0.042],[-0.125,0.211],[-0.083,0.21],[0.251,0.253],[0.669,-0.169],[0.084,-0.21],[0.376,0.084],[0.167,-0.252],[0.335,0.042],[0.376,0],[0.418,0.084],[0,-0.169],[-0.335,-0.126],[0.188,-0.189]],"v":[[5.459,3.581],[4.161,3.329],[3.326,2.782],[2.949,1.268],[1.568,-0.708],[0.784,-2.39],[-0.062,-3.189],[-1.527,-3.525],[-1.192,-4.24],[-0.23,-4.871],[0.188,-5.879],[0.773,-6.931],[-0.021,-7.141],[-2.908,-7.351],[-1.904,-8.57],[-1.399,-9.369],[-1.359,-9.454],[-2.699,-9.748],[-3.786,-9.664],[-4.329,-8.613],[-5.249,-7.604],[-5.585,-6.594],[-5.208,-5.879],[-5.041,-5.039],[-4.999,-4.114],[-3.995,-3.735],[-3.911,-2.642],[-4.078,-1.549],[-3.535,-0.918],[-2.154,-1.086],[-2.322,-0.077],[-1.652,1.058],[-1.694,2.446],[-3.242,2.488],[-3.827,2.908],[-3.326,3.959],[-3.702,5.431],[-4.664,6.23],[-2.656,6.861],[-2.113,7.491],[-3.535,7.66],[-3.953,8.584],[-5.041,9.173],[-4.873,9.93],[-3.326,9.636],[-2.531,8.963],[-1.317,8.753],[-0.355,8.206],[0.857,7.618],[2.029,8.122],[4.372,7.744],[5.417,6.987],[4.12,6.692],[5.124,5.137]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.481999984442,0.779999976065,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[192.416,162.531],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":4,"cix":2,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.042,0.476],[10.285,-12.495],[-0.05,-0.5],[0.227,-0.797],[-0.565,-0.113],[-0.453,-0.113],[0.792,-0.455],[0.453,-0.455],[-0.113,-1.365],[-0.114,-1.024],[-0.906,-0.342],[-0.566,0],[-0.34,1.252],[0,0],[-1.019,0.228],[-0.566,0.228],[-0.567,0.797],[-0.68,0.683],[-0.679,0.682],[-0.679,0.683],[0,0.91],[-0.114,1.252],[0,0],[-0.34,0.57],[0.679,0.341],[-0.34,0.342],[-0.397,0.398],[0.226,0.227],[-0.736,0.74],[-0.679,0.227],[-0.566,0],[0.905,0],[0.906,-0.626],[0.679,0],[0,0],[-0.509,0.512]],"o":[[-14.8,6.914],[0.118,0.526],[0.113,1.138],[-0.226,0.796],[0.566,0.114],[0.452,0.114],[-0.793,0.455],[-0.452,0.455],[0.113,1.365],[0.113,1.024],[0.905,0.341],[0.566,0],[0.339,-1.251],[0,0],[1.019,-0.227],[0.566,-0.227],[0.566,-0.796],[0.679,-0.683],[0.679,-0.683],[0.679,-0.682],[0,-0.91],[0.113,-1.251],[0,0],[0.34,-0.568],[-0.679,-0.341],[0.339,-0.341],[0.396,-0.398],[-0.226,-0.228],[0.736,-0.739],[0.679,-0.228],[0.566,0],[-0.906,0],[-0.905,0.626],[-0.679,0],[0,0],[0.28,-0.282]],"v":[[14.18,-26.157],[-23.904,3.405],[-23.6,4.995],[-24.165,7.271],[-24.279,9.432],[-21.674,8.977],[-23.939,11.48],[-25.523,13.87],[-25.863,17.852],[-25.184,22.403],[-22.807,25.816],[-20.09,26.157],[-18.506,22.971],[-14.658,13.983],[-12.281,12.504],[-7.188,9.546],[-4.471,6.474],[-0.057,4.654],[5.262,0.9],[8.658,-1.49],[8.884,-4.106],[9.904,-6.837],[12.281,-8.999],[13.751,-11.047],[13.298,-13.208],[13.072,-14.915],[15.337,-16.621],[13.751,-17.645],[15.109,-19.466],[19.751,-22.651],[25.41,-25.211],[24.164,-25.95],[19.41,-25.211],[16.354,-24.358],[13.979,-23.561],[13.751,-24.813]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.481999984442,0.779999976065,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[160.155,130.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 14","np":4,"cix":2,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-60.423],[60.112,0],[0,60.423],[-60.11,0]],"o":[[0,60.423],[-60.11,0],[0,-60.423],[60.112,0]],"v":[[108.84,0],[-0.001,109.406],[-108.84,0],[-0.001,-109.406]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.051000000449,0.340999977261,0.670999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[220.147,203.209],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 15","np":4,"cix":2,"ix":15,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[9.496,10.504],[-2.392,-10.504],[-9.495,-6.484],[-2.823,-2.401],[-4.845,-1.258],[1.825,2.824],[0.518,3.563],[5.262,6.466],[4.033,7.161]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.141000007181,0.670999983245,0.081999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[282.776,302.485],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 16","np":4,"cix":2,"ix":16,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-9.496,-4.475],[-2.824,-0.392],[-4.846,0.753],[1.824,4.834],[0.518,5.572],[5.261,8.475],[4.032,9.171],[9.495,12.513],[9.441,6.109],[8.214,6.805],[8.167,1.244],[6.861,1.983],[6.796,-5.836],[4.775,-4.693],[4.71,-12.514]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.090000002992,0.788000009574,0.008000000785,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[282.776,300.475],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 17","np":4,"cix":2,"ix":17,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-3.833,11.759],[4.551,-8.924],[-2.442,-11.759],[-1.566,-4.58],[-3.555,-5.387],[-2.679,1.79],[-3.965,1.269],[-3.342,6.372],[-4.551,5.882]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.141000007181,0.670999983245,0.081999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[176.517,311.743],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 18","np":4,"cix":2,"ix":18,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-5.939,-11.759],[-5.064,-4.58],[-7.053,-5.387],[-6.176,1.79],[-7.462,1.268],[-6.839,6.372],[-8.048,5.882],[-7.331,11.759],[-2.723,8.04],[-3.932,7.55],[0.069,4.321],[-1.217,3.8],[4.41,-0.74],[2.419,-1.547],[8.048,-6.089]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.090000002992,0.788000009574,0.008000000785,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[180.014,311.743],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 19","np":4,"cix":2,"ix":19,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-6.057,14.554],[6.378,-10.349],[-2.042,-14.554],[-1.65,-5.543],[-4.045,-6.739],[-3.653,2.269],[-5.202,1.496],[-4.922,7.903],[-6.378,7.176]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.141000007181,0.670999983245,0.081999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[166.017,309.236],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 20","np":4,"cix":2,"ix":20,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-6.252,-14.554],[-5.859,-5.542],[-8.255,-6.739],[-7.863,2.269],[-9.411,1.497],[-9.132,7.903],[-10.589,7.176],[-10.268,14.554],[-4.176,10.378],[-5.632,9.651],[-0.343,6.025],[-1.891,5.252],[5.545,0.153],[3.15,-1.043],[10.589,-6.145]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.090000002992,0.788000009574,0.008000000785,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[170.228,309.236],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 21","np":4,"cix":2,"ix":21,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[13.814,8.682],[-7.943,-8.681],[-13.814,-1.325],[-4.918,0.174],[-6.589,2.267],[2.302,3.765],[1.223,5.118],[7.546,6.183],[6.531,7.454]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.141000007181,0.670999983245,0.081999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[311.184,278.988],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 22","np":4,"cix":2,"ix":22,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-13.814,2.353],[-4.918,3.852],[-6.589,5.945],[2.302,7.443],[1.223,8.795],[7.546,9.861],[6.531,11.132],[13.814,12.36],[11.001,5.531],[9.987,6.802],[7.545,0.873],[6.465,2.226],[3.033,-6.112],[1.363,-4.019],[-2.072,-12.36]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.090000002992,0.788000009574,0.008000000785,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[311.184,275.31],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 23","np":4,"cix":2,"ix":23,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-13.418,-9.441],[7.033,9.442],[13.418,2.527],[4.654,0.392],[6.47,-1.575],[-2.29,-3.709],[-1.116,-4.981],[-7.347,-6.498],[-6.243,-7.693]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.141000007181,0.670999983245,0.081999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[129.631,128.631],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 24","np":4,"cix":2,"ix":24,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[13.418,-0.931],[4.654,-3.066],[6.47,-5.033],[-2.29,-7.166],[-1.116,-8.438],[-7.347,-9.955],[-6.243,-11.151],[-13.418,-12.899],[-11.104,-5.885],[-10,-7.081],[-7.992,-0.991],[-6.818,-2.263],[-3.994,6.3],[-2.177,4.333],[0.648,12.899]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.090000002992,0.788000009574,0.008000000785,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[129.631,132.088],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 25","np":4,"cix":2,"ix":25,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-18.781,-14.691],[8.846,14.691],[18.781,5.35],[6.333,1.368],[9.16,-1.289],[-3.285,-5.269],[-1.458,-6.986],[-10.307,-9.816],[-8.59,-11.432]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.141000007181,0.670999983245,0.081999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[140.776,111.29],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 26","np":4,"cix":2,"ix":26,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[18.782,0.678],[6.333,-3.303],[9.16,-5.96],[-3.285,-9.939],[-1.458,-11.658],[-10.307,-14.488],[-8.589,-16.102],[-18.781,-19.363],[-16.156,-8.989],[-14.438,-10.605],[-12.156,-1.597],[-10.329,-3.314],[-7.124,9.35],[-4.296,6.692],[-1.089,19.363]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.090000002992,0.788000009574,0.008000000785,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[140.776,115.962],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 27","np":4,"cix":2,"ix":27,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.473,2.159],[0.281,-0.053],[2.266,3.786],[-0.345,-1.85],[-4.577,0.852]],"o":[[-0.274,0.065],[-5.764,1.072],[-1.427,1.317],[0.574,3.086],[3.234,-0.602]],"v":[[7.973,-0.129],[7.141,0.051],[-6.302,-4.736],[-7.866,0.217],[-0.062,4.545]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.470999983245,0.689999988032,0.081999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[339.28,193.918],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 28","np":4,"cix":2,"ix":28,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.577,-0.853],[0.575,3.086],[-4.578,0.852],[-0.574,-3.086]],"o":[[-4.577,0.852],[-0.575,-3.086],[4.577,-0.852],[0.576,3.085]],"v":[[-0.484,5.587],[-8.288,1.259],[-2.564,-5.587],[8.288,-1.827]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.8,0.097999999102,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[339.702,192.875],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 29","np":4,"cix":2,"ix":29,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-3.663,1.391],[-3.919,0.021],[3.664,-1.391],[3.919,-0.02]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.344999994016,0.246999987434,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[331.293,194.007],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 30","np":4,"cix":2,"ix":30,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.207,1.606],[-0.046,-0.295],[4.024,-2.245],[-1.942,0.301],[0.744,4.805]],"o":[[0.06,0.288],[0.937,6.051],[1.33,1.531],[3.239,-0.502],[-0.526,-3.395]],"v":[[0.249,-8.311],[0.41,-7.437],[-5.014,6.443],[0.106,8.233],[4.872,0.225]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.470999983245,0.689999988032,0.081999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[215.704,83.975],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 31","np":4,"cix":2,"ix":31,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.744,-4.805],[3.24,-0.502],[0.743,4.805],[-3.24,0.501]],"o":[[0.744,4.805],[-3.238,0.501],[-0.745,-4.805],[3.239,-0.502]],"v":[[5.865,0.693],[1.099,8.701],[-5.864,2.509],[-1.594,-8.7]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.8,0.097999999102,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[214.711,83.507],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 32","np":4,"cix":2,"ix":32,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.336,3.868],[-0.103,4.092],[-1.336,-3.869],[0.104,-4.092]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.344999994016,0.246999987434,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[215.673,92.329],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 33","np":4,"cix":2,"ix":33,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.26,3.274],[0.08,-0.428],[6.617,-1.146],[-2.815,-0.524],[-1.296,6.967]],"o":[[-0.058,0.425],[-1.632,8.773],[1.089,2.748],[4.697,0.873],[0.915,-4.923]],"v":[[5.882,-11.423],[5.681,-10.143],[-8.476,6.328],[-2.299,11.261],[8.12,2.547]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.470999983245,0.689999988032,0.081999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[232.538,81.807],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 34","np":4,"cix":2,"ix":34,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.296,-6.967],[4.696,0.874],[-1.295,6.967],[-4.696,-0.873]],"o":[[-1.296,6.967],[-4.696,-0.873],[1.296,-6.967],[4.697,0.873]],"v":[[8.504,3.902],[-1.915,12.615],[-8.505,0.739],[2.777,-12.616]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.8,0.097999999102,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[232.155,80.452],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 35","np":4,"cix":2,"ix":35,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.029,5.965],[-2.117,5.578],[0.03,-5.965],[2.117,-5.576]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.344999994016,0.246999987434,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[229.993,93.169],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 36","np":4,"cix":2,"ix":36,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.029,-3.263],[-0.256,0.25],[-4.982,-2.353],[1.642,1.679],[4.158,-4.063]],"o":[[0.239,-0.259],[5.235,-5.117],[0.565,-2.357],[-2.739,-2.803],[-2.938,2.872]],"v":[[-9.1,6.738],[-8.361,5.974],[8.912,1.602],[7.094,-4.622],[-4.009,-3.693]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.470999983245,0.689999988032,0.081999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[137.579,291.88],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 37","np":4,"cix":2,"ix":37,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.157,4.064],[-2.739,-2.802],[4.158,-4.063],[2.739,2.803]],"o":[[4.158,-4.063],[2.739,2.802],[-4.157,4.065],[-2.739,-2.803]],"v":[[-3.693,-6.263],[7.41,-7.193],[6.227,3.885],[-7.646,7.523]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.8,0.097999999102,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[137.264,294.45],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 38","np":4,"cix":2,"ix":38,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.835,-3.989],[4.053,-2.743],[-2.834,3.989],[-4.052,2.743]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.344999994016,0.246999987434,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[144.887,287.306],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 39","np":4,"cix":2,"ix":39,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.32,-1.556],[-0.3,-0.06],[-0.744,-4.659],[-0.394,1.972],[4.881,0.974]],"o":[[0.298,0.044],[6.146,1.228],[1.939,-0.741],[0.657,-3.29],[-3.449,-0.689]],"v":[[-7.992,-4.259],[-7.095,-4.106],[4.341,5.99],[7.862,1.697],[1.84,-5.7]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.470999983245,0.689999988032,0.081999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[109.648,153.918],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 40","np":4,"cix":2,"ix":40,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.881,-0.975],[0.657,-3.29],[4.88,0.974],[-0.657,3.29]],"o":[[4.881,0.975],[-0.657,3.291],[-4.881,-0.975],[0.657,-3.29]],"v":[[2.816,-5.957],[8.838,1.44],[0.437,5.958],[-8.837,-2.089]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.8,0.097999999102,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[108.672,154.174],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 41","np":4,"cix":2,"ix":41,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4.189,0.076],[3.896,1.538],[-4.189,-0.076],[-3.897,-1.538]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.344999994016,0.246999987434,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[117.579,155.789],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 42","np":4,"cix":2,"ix":42,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.785,-1.197],[-0.231,-0.046],[-0.572,-3.583],[-0.303,1.517],[3.755,0.75]],"o":[[0.229,0.034],[4.728,0.945],[1.492,-0.57],[0.506,-2.531],[-2.652,-0.53]],"v":[[-6.148,-3.276],[-5.458,-3.159],[3.339,4.607],[6.047,1.305],[1.414,-4.385]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.470999983245,0.689999988032,0.081999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[111.808,163.788],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 43","np":4,"cix":2,"ix":43,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.754,-0.75],[0.505,-2.53],[3.754,0.75],[-0.506,2.531]],"o":[[3.755,0.75],[-0.506,2.531],[-3.754,-0.75],[0.505,-2.531]],"v":[[2.166,-4.583],[6.799,1.107],[0.336,4.583],[-6.798,-1.607]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.8,0.097999999102,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[111.057,163.985],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 44","np":4,"cix":2,"ix":44,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[3.222,0.058],[2.997,1.183],[-3.222,-0.059],[-2.998,-1.184]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.344999994016,0.246999987434,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[117.908,165.227],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 45","np":4,"cix":2,"ix":45,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.864,-2.582],[-0.134,0.267],[-4.569,-0.504],[1.752,0.88],[2.176,-4.335]],"o":[[0.118,-0.269],[2.74,-5.46],[-0.195,-2.014],[-2.922,-1.467],[-1.537,3.063]],"v":[[-6.198,7.009],[-5.823,6.206],[6.617,-1.934],[3.492,-6.352],[-5.015,-2.602]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.470999983245,0.689999988032,0.081999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[152.53,299.31],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 46","np":4,"cix":2,"ix":46,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.176,4.335],[-2.923,-1.467],[2.176,-4.335],[2.922,1.467]],"o":[[2.176,-4.335],[2.922,1.467],[-2.176,4.335],[-2.922,-1.468]],"v":[[-5.231,-4.1],[3.275,-7.85],[5.352,1.212],[-4.605,7.85]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.8,0.097999999102,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[152.747,300.807],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 47","np":4,"cix":2,"ix":47,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.153,-3.917],[2.452,-3.265],[-1.153,3.917],[-2.452,3.266]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.344999994016,0.246999987434,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[156.204,292.938],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 48","np":4,"cix":2,"ix":48,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.045,-0.438],[0.278,0.348],[-3.536,5.89],[2.287,-1.83],[-4.529,-5.659]],"o":[[-0.291,-0.328],[-5.703,-7.127],[-2.856,-0.993],[-3.814,3.053],[3.201,4]],"v":[[7.674,11.722],[6.817,10.711],[3.526,-11.258],[-4.423,-9.771],[-4.639,4.118]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.470999983245,0.689999988032,0.081999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[301.735,296.291],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 49","np":4,"cix":2,"ix":49,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.528,5.659],[-3.815,3.053],[-4.529,-5.659],[3.816,-3.052]],"o":[[-4.529,-5.659],[3.815,-3.052],[4.529,5.659],[-3.814,3.053]],"v":[[-7.951,3.642],[-7.735,-10.248],[5.864,-7.413],[8.664,10.247]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.8,0.097999999102,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[305.048,296.768],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 50","np":4,"cix":2,"ix":50,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-4.599,-4.01],[-2.904,-5.366],[4.599,4.009],[2.903,5.366]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.344999994016,0.246999987434,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[297.4,286.261],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 51","np":4,"cix":2,"ix":51,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.372,-7.247],[4.985,3.736],[-5.373,7.247],[-4.986,-3.735]],"o":[[-5.372,7.246],[-4.985,-3.734],[5.372,-7.246],[4.986,3.735]],"v":[[9.027,6.762],[-9.728,13.12],[-9.028,-6.762],[9.727,-13.121]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.375999989229,0.702000038297,0.195999998205,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[321.291,233.272],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 52","np":4,"cix":2,"ix":52,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.181,-8.96],[6.164,0.821],[-1.18,8.96],[-6.165,-0.821]],"o":[[-1.18,8.959],[-6.164,-0.82],[1.18,-8.959],[6.164,0.82]],"v":[[11.16,1.486],[-2.138,16.222],[-11.162,-1.486],[2.137,-16.222]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.375999989229,0.702000038297,0.195999998205,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[323.532,212.715],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 53","np":4,"cix":2,"ix":53,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.648,-4.751],[3.269,5.316],[-7.648,4.751],[-3.269,-5.318]],"o":[[-7.648,4.751],[-3.268,-5.318],[7.649,-4.751],[3.268,5.316]],"v":[[5.918,9.627],[-13.849,8.603],[-5.919,-9.627],[13.848,-8.602]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.375999989229,0.702000038297,0.195999998205,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[312.889,252.882],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 54","np":4,"cix":2,"ix":54,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[1.176,0.066],[-0.063,1.147],[0,0]],"o":[[0,0],[-0.062,1.149],[-1.175,-0.064],[0,0],[0,0]],"v":[[2.284,-3.182],[2.035,1.389],[-0.206,3.35],[-2.221,1.156],[-1.971,-3.417]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.760999971278,0.4,0.136999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[209.543,357.135],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 55","np":4,"cix":2,"ix":55,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-17.278,-1.892],[17.382,0.013],[17.28,1.892],[-17.382,-0.013]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.760999971278,0.4,0.136999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[210.392,341.086],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 56","np":4,"cix":2,"ix":56,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-17.278,-1.892],[17.382,0.014],[17.28,1.893],[-17.382,-0.012]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.760999971278,0.4,0.136999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[211.327,323.889],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 57","np":4,"cix":2,"ix":57,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[1.641,0.091],[-0.087,1.601],[0,0]],"o":[[0,0],[-0.088,1.601],[-1.64,-0.09],[0,0],[0,0]],"v":[[3.187,-4.442],[2.84,1.941],[-0.288,4.677],[-3.1,1.615],[-2.752,-4.768]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588000009574,0.310000011968,0.105999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[201.052,331.91],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 58","np":4,"cix":2,"ix":58,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[1.64,0.09],[-0.087,1.601],[0,0]],"o":[[0,0],[-0.087,1.601],[-1.64,-0.091],[0,0],[0,0]],"v":[[3.187,-4.442],[2.839,1.941],[-0.288,4.678],[-3.1,1.615],[-2.753,-4.768]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588000009574,0.310000011968,0.105999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[210.896,332.451],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 59","np":4,"cix":2,"ix":59,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[1.641,0.09],[-0.088,1.601],[0,0]],"o":[[0,0],[-0.087,1.601],[-1.64,-0.091],[0,0],[0,0]],"v":[[3.188,-4.441],[2.839,1.941],[-0.289,4.678],[-3.1,1.615],[-2.753,-4.768]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588000009574,0.310000011968,0.105999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[220.738,332.992],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 60","np":4,"cix":2,"ix":60,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-16.199,-21.743],[18.461,-19.838],[16.199,21.743],[-18.461,19.838]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.877999997606,0.532999973671,0.141000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[211.274,324.872],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 61","np":4,"cix":2,"ix":61,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.637,0.035],[-0.034,0.622],[0,0]],"o":[[0,0],[-0.034,0.622],[-0.637,-0.035],[0,0],[0,0]],"v":[[1.238,-1.725],[1.102,0.754],[-0.112,1.816],[-1.204,0.627],[-1.069,-1.851]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.760999971278,0.4,0.136999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[190.908,320.988],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 62","np":4,"cix":2,"ix":62,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.637,0.035],[-0.034,0.622],[0,0]],"o":[[0,0],[-0.033,0.622],[-0.637,-0.035],[0,0],[0,0]],"v":[[1.238,-1.724],[1.102,0.754],[-0.112,1.816],[-1.204,0.627],[-1.069,-1.851]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.760999971278,0.4,0.136999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[185.605,320.696],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 63","np":4,"cix":2,"ix":63,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.638,0.035],[-0.034,0.622],[0,0]],"o":[[0,0],[-0.034,0.622],[-0.636,-0.035],[0,0],[0,0]],"v":[[1.238,-1.725],[1.102,0.754],[-0.113,1.816],[-1.204,0.628],[-1.069,-1.852]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.760999971278,0.4,0.136999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[180.302,320.405],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 64","np":4,"cix":2,"ix":64,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.637,0.035],[-0.034,0.622],[0,0]],"o":[[0,0],[-0.034,0.622],[-0.637,-0.034],[0,0],[0,0]],"v":[[1.238,-1.724],[1.102,0.754],[-0.112,1.816],[-1.204,0.627],[-1.069,-1.851]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.760999971278,0.4,0.136999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[175,320.113],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 65","np":4,"cix":2,"ix":65,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.579,-2.785],[-1.269,-2.941],[-1.58,2.783],[1.267,2.94]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.642999985639,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[192.604,326.537],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 66","np":4,"cix":2,"ix":66,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.58,-2.785],[-1.268,-2.941],[-1.579,2.784],[1.268,2.941]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.642999985639,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[187.763,326.271],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 67","np":4,"cix":2,"ix":67,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.579,-2.784],[-1.269,-2.941],[-1.58,2.784],[1.267,2.941]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.642999985639,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[182.922,326.004],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 68","np":4,"cix":2,"ix":68,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.579,-2.785],[-1.269,-2.941],[-1.58,2.783],[1.268,2.941]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.642999985639,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[178.08,325.738],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 69","np":4,"cix":2,"ix":69,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.58,-2.784],[-1.268,-2.941],[-1.58,2.784],[1.268,2.941]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.642999985639,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[173.239,325.472],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 70","np":4,"cix":2,"ix":70,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[15.477,-10.777],[-14.215,-12.41],[-15.477,10.778],[14.214,12.41]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.642999985639,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[187.307,314.33],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 71","np":4,"cix":2,"ix":71,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.637,-0.035],[-0.033,0.623],[0,0]],"o":[[0,0],[-0.034,0.622],[0.637,0.035],[0,0],[0,0]],"v":[[-1.068,-1.851],[-1.204,0.627],[-0.112,1.816],[1.102,0.753],[1.238,-1.724]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.760999971278,0.4,0.136999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[231.967,323.245],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 72","np":4,"cix":2,"ix":72,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.638,-0.035],[-0.034,0.623],[0,0]],"o":[[0,0],[-0.034,0.622],[0.637,0.035],[0,0],[0,0]],"v":[[-1.068,-1.852],[-1.204,0.628],[-0.112,1.816],[1.102,0.753],[1.238,-1.724]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.760999971278,0.4,0.136999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[237.27,323.536],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 73","np":4,"cix":2,"ix":73,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.637,-0.034],[-0.034,0.623],[0,0]],"o":[[0,0],[-0.033,0.622],[0.637,0.035],[0,0],[0,0]],"v":[[-1.069,-1.851],[-1.204,0.627],[-0.113,1.816],[1.103,0.753],[1.238,-1.724]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.760999971278,0.4,0.136999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[242.572,323.828],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 74","np":4,"cix":2,"ix":74,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.637,-0.035],[-0.034,0.623],[0,0]],"o":[[0,0],[-0.033,0.622],[0.637,0.035],[0,0],[0,0]],"v":[[-1.069,-1.851],[-1.204,0.627],[-0.113,1.816],[1.103,0.753],[1.238,-1.725]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.760999971278,0.4,0.136999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[247.875,324.12],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 75","np":4,"cix":2,"ix":75,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.268,-2.941],[1.58,-2.784],[1.268,2.941],[-1.58,2.785]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.642999985639,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[229.653,328.573],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 76","np":4,"cix":2,"ix":76,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.268,-2.941],[1.58,-2.785],[1.268,2.941],[-1.58,2.784]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.642999985639,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[234.494,328.84],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 77","np":4,"cix":2,"ix":77,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.268,-2.941],[1.58,-2.784],[1.268,2.941],[-1.58,2.785]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.642999985639,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[239.335,329.105],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 78","np":4,"cix":2,"ix":78,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.268,-2.941],[1.58,-2.785],[1.268,2.941],[-1.58,2.784]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.642999985639,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[244.176,329.372],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 79","np":4,"cix":2,"ix":79,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.268,-2.941],[1.58,-2.784],[1.268,2.941],[-1.58,2.785]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.642999985639,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[249.018,329.638],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 80","np":4,"cix":2,"ix":80,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-14.214,-12.41],[15.477,-10.777],[14.215,12.41],[-15.477,10.777]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.642999985639,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[236.242,317.02],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 81","np":4,"cix":2,"ix":81,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.223,-3.981],[2.643,-3.713],[2.225,3.981],[-2.643,3.713]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.877999997606,0.532999973671,0.141000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[195.246,344.844],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 82","np":4,"cix":2,"ix":82,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.224,-3.982],[2.643,-3.714],[2.224,3.982],[-2.643,3.714]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.877999997606,0.532999973671,0.141000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[202.695,345.253],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 83","np":4,"cix":2,"ix":83,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.223,-3.982],[2.643,-3.712],[2.225,3.982],[-2.643,3.714]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.877999997606,0.532999973671,0.141000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[210.143,345.663],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 84","np":4,"cix":2,"ix":84,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.224,-3.981],[2.643,-3.713],[2.224,3.981],[-2.643,3.713]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.877999997606,0.532999973671,0.141000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[217.592,346.072],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 85","np":4,"cix":2,"ix":85,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.223,-3.981],[2.643,-3.713],[2.223,3.982],[-2.643,3.714]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.877999997606,0.532999973671,0.141000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[225.04,346.482],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 86","np":4,"cix":2,"ix":86,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-0.518,4.388],[-14.252,-7.465],[-14.42,-4.386],[-0.685,7.465],[14.253,-2.81],[14.42,-5.888]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.760999971278,0.4,0.136999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[209.559,361.528],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 87","np":4,"cix":2,"ix":87,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-0.979,14.031],[10.549,6.1],[11.579,-12.815],[0.515,-13.423],[-10.549,-14.031],[-11.579,4.885]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.642999985639,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[210.003,352.197],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 88","np":4,"cix":2,"ix":88,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-0.418,3.544],[-11.511,-6.029],[-11.647,-3.544],[-0.553,6.029],[11.513,-2.27],[11.647,-4.756]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.877999997606,0.532999973671,0.141000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[209.355,364.277],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 89","np":4,"cix":2,"ix":89,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-0.394,3.329],[-10.817,-5.665],[-10.944,-3.33],[-0.521,5.665],[10.816,-2.134],[10.944,-4.469]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.760999971278,0.4,0.136999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[209.257,365.852],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 90","np":4,"cix":2,"ix":90,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.722,0.457],[0.441,0.705],[0,0]],"o":[[0,0],[0.442,0.704],[0.722,-0.457],[0,0],[0,0]],"v":[[-2.622,-1.371],[-0.433,2.122],[1.674,2.57],[2.181,0.466],[-0.01,-3.027]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[293.365,335.847],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 91","np":4,"cix":2,"ix":91,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.722,0.457],[0.441,0.705],[0,0]],"o":[[0,0],[0.442,0.704],[0.722,-0.457],[0,0],[0,0]],"v":[[-2.622,-1.371],[-0.433,2.122],[1.674,2.57],[2.181,0.466],[-0.01,-3.027]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[297.604,333.161],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 92","np":4,"cix":2,"ix":92,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.722,0.457],[0.441,0.705],[0,0]],"o":[[0,0],[0.442,0.704],[0.722,-0.458],[0,0],[0,0]],"v":[[-2.622,-1.371],[-0.433,2.122],[1.674,2.57],[2.181,0.466],[-0.009,-3.027]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[301.843,330.476],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 93","np":4,"cix":2,"ix":93,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.722,0.457],[0.442,0.705],[0,0]],"o":[[0,0],[0.442,0.704],[0.722,-0.458],[0,0],[0,0]],"v":[[-2.623,-1.371],[-0.433,2.122],[1.674,2.57],[2.181,0.466],[-0.01,-3.027]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[306.083,327.79],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 94","np":4,"cix":2,"ix":94,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.722,0.457],[0.442,0.705],[0,0]],"o":[[0,0],[0.442,0.704],[0.722,-0.458],[0,0],[0,0]],"v":[[-2.623,-1.371],[-0.433,2.122],[1.674,2.57],[2.181,0.466],[-0.009,-3.027]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[310.322,325.105],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 95","np":4,"cix":2,"ix":95,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-12.56,5.379],[9.664,-8.7],[12.56,-7.09],[-12.365,8.7]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.477999997606,0.250999989229,0.122000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[299.853,326.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 96","np":4,"cix":2,"ix":96,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-3.406,-2.865],[-1.101,-4.324],[3.406,2.865],[1.101,4.325]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.477999997606,0.250999989229,0.122000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[289.759,319.834],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 97","np":4,"cix":2,"ix":97,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-3.406,-2.865],[-1.101,-4.324],[3.406,2.865],[1.101,4.324]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.477999997606,0.250999989229,0.122000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[297.596,314.869],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 98","np":4,"cix":2,"ix":98,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[3.457,6.447],[4.294,5.917],[-3.457,-6.447],[-4.294,-5.915]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[285.166,322.52],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 99","np":4,"cix":2,"ix":99,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[3.457,6.447],[4.294,5.917],[-3.457,-6.447],[-4.294,-5.915]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[287.096,321.297],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 100","np":4,"cix":2,"ix":100,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.137,1.884],[2.613,-1.126],[2.138,-1.884],[-2.613,1.126]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[290.75,329.277],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 101","np":4,"cix":2,"ix":101,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.343,0.919],[1.838,-1.728],[2.344,-0.921],[-1.836,1.728]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.477999997606,0.250999989229,0.122000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[290.259,328.495],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 102","np":4,"cix":2,"ix":102,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.823,-0.197],[1.041,-2.645],[2.823,0.197],[-1.042,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.477999997606,0.250999989229,0.122000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[281.365,314.307],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 103","np":4,"cix":2,"ix":103,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[3.457,6.446],[4.294,5.917],[-3.457,-6.447],[-4.294,-5.916]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[292.612,317.802],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 104","np":4,"cix":2,"ix":104,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[3.457,6.446],[4.294,5.916],[-3.457,-6.446],[-4.294,-5.916]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[294.542,316.58],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 105","np":4,"cix":2,"ix":105,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.138,1.884],[2.613,-1.126],[2.138,-1.884],[-2.613,1.126]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[298.197,324.559],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 106","np":4,"cix":2,"ix":106,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.344,0.92],[1.837,-1.728],[2.343,-0.921],[-1.837,1.728]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.477999997606,0.250999989229,0.122000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[297.706,323.777],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 107","np":4,"cix":2,"ix":107,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.823,-0.197],[1.042,-2.645],[2.823,0.196],[-1.042,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.477999997606,0.250999989229,0.122000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[288.811,309.59],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 108","np":4,"cix":2,"ix":108,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[3.457,6.446],[4.293,5.917],[-3.457,-6.447],[-4.293,-5.916]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[300.059,313.085],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 109","np":4,"cix":2,"ix":109,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[3.457,6.447],[4.293,5.917],[-3.457,-6.447],[-4.293,-5.915]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[301.989,311.862],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 110","np":4,"cix":2,"ix":110,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.137,1.884],[2.613,-1.126],[2.138,-1.884],[-2.613,1.126]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[305.643,319.842],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 111","np":4,"cix":2,"ix":111,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.344,0.919],[1.837,-1.728],[2.343,-0.921],[-1.837,1.729]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.477999997606,0.250999989229,0.122000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[305.152,319.059],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 112","np":4,"cix":2,"ix":112,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.823,-0.196],[1.042,-2.645],[2.823,0.197],[-1.042,2.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.477999997606,0.250999989229,0.122000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[296.258,304.872],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 113","np":4,"cix":2,"ix":113,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.272,0.435],[-0.433,0.274],[0,0],[-0.273,-0.435],[0.431,-0.274],[0,0]],"o":[[-0.272,-0.435],[0,0],[0.433,-0.275],[0.272,0.434],[0,0],[-0.432,0.274]],"v":[[-10.149,6.43],[-9.859,5.147],[8.872,-6.719],[10.149,-6.428],[9.86,-5.146],[-8.873,6.72]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[309.021,341.823],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 114","np":4,"cix":2,"ix":114,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.272,0.435],[-0.433,0.273],[0,0],[-0.273,-0.435],[0.431,-0.274],[0,0]],"o":[[-0.272,-0.435],[0,0],[0.432,-0.274],[0.272,0.434],[0,0],[-0.432,0.273]],"v":[[-11.794,7.472],[-11.505,6.19],[10.518,-7.762],[11.794,-7.471],[11.505,-6.189],[-10.519,7.763]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[287.427,307.382],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 115","np":4,"cix":2,"ix":115,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-1.347,0.854],[0.824,1.316],[0,0]],"o":[[0,0],[0.826,1.316],[1.348,-0.853],[0,0],[0,0]],"v":[[-4.219,-1.482],[-1.483,2.882],[2.449,3.719],[3.396,-0.208],[0.66,-4.573]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[273.306,300.204],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 116","np":4,"cix":2,"ix":116,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-1.348,0.854],[0.825,1.317],[0,0]],"o":[[0,0],[0.825,1.316],[1.347,-0.853],[0,0],[0,0]],"v":[[-4.22,-1.482],[-1.484,2.882],[2.449,3.719],[3.394,-0.209],[0.658,-4.573]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[280.108,295.896],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 117","np":4,"cix":2,"ix":117,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-1.347,0.854],[0.824,1.317],[0,0]],"o":[[0,0],[0.826,1.316],[1.348,-0.853],[0,0],[0,0]],"v":[[-4.219,-1.482],[-1.483,2.882],[2.449,3.719],[3.396,-0.209],[0.66,-4.573]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[286.909,291.587],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 118","np":4,"cix":2,"ix":118,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-6.616,9.517],[11.396,-1.893],[6.616,-9.517],[-11.396,1.893]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.638999968884,0.430999995213,0.246999987434,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[306.833,338.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 119","np":4,"cix":2,"ix":119,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-13.298,3.002],[8.431,-10.764],[13.298,-3.003],[-8.432,10.764]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.702000038297,0.510000011968,0.337000020345,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[302.01,330.642],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 120","np":4,"cix":2,"ix":120,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-16.378,-1.911],[5.352,-15.677],[16.379,1.911],[-5.352,15.678]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.702000038297,0.510000011968,0.337000020345,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[292.941,316.177],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 121","np":4,"cix":2,"ix":121,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-15.818,-0.149],[6.69,-14.409],[15.817,0.149],[-6.691,14.409]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.702000038297,0.510000011968,0.337000020345,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[282.95,300.241],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 122","np":4,"cix":2,"ix":122,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.942,1.863],[1.801,2.873],[0,0]],"o":[[0,0],[1.8,2.872],[2.942,-1.865],[0,0],[0,0]],"v":[[-7.277,-0.146],[-5.177,3.205],[3.41,5.032],[5.477,-3.544],[3.375,-6.895]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.702000038297,0.510000011968,0.337000020345,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[310.038,343.854],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 123","np":4,"cix":2,"ix":123,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-4.478,2.836],[2.741,4.372],[0,0]],"o":[[0,0],[2.741,4.372],[4.476,-2.836],[0,0],[0,0]],"v":[[-11.074,-0.221],[-7.879,4.876],[5.191,7.656],[8.333,-5.395],[5.137,-10.492]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.477999997606,0.250999989229,0.122000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[310.924,345.482],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 124","np":4,"cix":2,"ix":124,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-4.196,0.047],[1.853,-3.785],[4.197,-0.047],[-1.853,3.785]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.702000038297,0.510000011968,0.337000020345,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[315.836,352.693],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 125","np":4,"cix":2,"ix":125,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-1.28,0.81],[0.784,1.251],[0,0]],"o":[[0,0],[0.784,1.251],[1.282,-0.812],[0,0],[0,0]],"v":[[-3.168,-0.063],[-2.254,1.395],[1.484,2.191],[2.384,-1.543],[1.47,-3.001]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.356999984442,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[316.958,354.662],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 126","np":4,"cix":2,"ix":126,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.021,0.658],[0.533,-0.017],[-0.02,-0.659],[-0.533,0.017]],"o":[[-0.021,-0.657],[-0.534,0.016],[0.021,0.658],[0.533,-0.017]],"v":[[0.966,-0.031],[-0.038,-1.191],[-0.966,0.031],[0.036,1.191]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.702000038297,0.510000011968,0.337000020345,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[319.313,360.217],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 127","np":4,"cix":2,"ix":127,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.732,0.381],[-0.308,0.599],[-0.732,-0.381],[0.308,-0.6]],"o":[[-0.732,-0.381],[0.31,-0.6],[0.733,0.381],[-0.309,0.6]],"v":[[-0.559,1.086],[-1.327,-0.69],[0.56,-1.087],[1.327,0.69]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.702000038297,0.510000011968,0.337000020345,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[321.627,358.875],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 128","np":4,"cix":2,"ix":128,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.339,0.216],[-0.214,-0.341],[0,0],[0.339,-0.214],[0.214,0.341]],"o":[[-0.215,-0.341],[0.339,-0.215],[0,0],[0.213,0.341],[-0.34,0.215],[0,0]],"v":[[-1.634,-1.238],[-1.408,-2.247],[-0.406,-2.018],[1.637,1.24],[1.409,2.246],[0.406,2.018]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.702000038297,0.510000011968,0.337000020345,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[319.795,358.93],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 129","np":4,"cix":2,"ix":129,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-6.069,4.668],[3.245,-6.955],[6.069,-4.669],[-3.246,6.955]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.102000000898,0.39199999641,0.451000019148,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[350.065,306.346],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 130","np":4,"cix":2,"ix":130,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-8.401,-6.124],[-7.742,-6.947],[8.401,6.125],[7.742,6.947]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.128999986836,0.486000001197,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[365.958,314.296],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 131","np":4,"cix":2,"ix":131,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-28.177,-21.734],[-27.124,-23.047],[28.177,21.733],[27.124,23.046]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.294000004787,0.564999988032,0.620000023935,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[338.879,290.608],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 132","np":4,"cix":2,"ix":132,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.558,1.943],[0,0],[2.022,1.638],[0,0]],"o":[[0,0],[1.557,-1.943],[0,0],[2.021,1.637]],"v":[[-7.211,14.216],[12.134,-9.924],[11.293,-16.407],[-13.691,14.77]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.102000000898,0.39199999641,0.451000019148,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[300.702,276.136],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 133","np":4,"cix":2,"ix":133,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-7.965,8.484],[6.551,-9.629],[7.966,-8.483],[-6.549,9.63]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.128999986836,0.486000001197,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[306.679,285.872],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 134","np":4,"cix":2,"ix":134,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-7.966,8.483],[6.55,-9.629],[7.965,-8.483],[-6.55,9.629]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.128999986836,0.486000001197,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[311.184,289.52],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 135","np":4,"cix":2,"ix":135,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-7.965,8.484],[6.551,-9.629],[7.966,-8.483],[-6.551,9.63]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.128999986836,0.486000001197,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[315.689,293.168],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 136","np":4,"cix":2,"ix":136,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-7.966,8.484],[6.55,-9.629],[7.966,-8.483],[-6.55,9.63]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.128999986836,0.486000001197,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[320.193,296.816],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 137","np":4,"cix":2,"ix":137,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-7.966,8.483],[6.55,-9.629],[7.966,-8.483],[-6.55,9.629]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.128999986836,0.486000001197,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[324.698,300.464],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 138","np":4,"cix":2,"ix":138,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-7.759,8.224],[6.342,-9.371],[7.758,-8.224],[-6.343,9.37]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.128999986836,0.486000001197,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[329.411,303.852],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 139","np":4,"cix":2,"ix":139,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-7.344,7.707],[5.927,-8.854],[7.344,-7.707],[-5.928,8.853]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.128999986836,0.486000001197,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[334.33,306.982],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 140","np":4,"cix":2,"ix":140,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-6.462,6.608],[5.046,-7.753],[6.462,-6.607],[-5.047,7.754]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.128999986836,0.486000001197,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[339.716,309.531],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 141","np":4,"cix":2,"ix":141,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-5.639,5.581],[4.223,-6.727],[5.639,-5.58],[-4.224,6.727]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.128999986836,0.486000001197,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[345.044,312.152],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 142","np":4,"cix":2,"ix":142,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-4.388,4.02],[2.973,-5.166],[4.388,-4.019],[-2.974,5.166]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.128999986836,0.486000001197,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[350.8,314.238],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 143","np":4,"cix":2,"ix":143,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-16.192,5.918],[0,0],[0,0]],"o":[[0,0],[0,0],[19.978,24.842]],"v":[[31.623,17.799],[-19.648,-23.718],[-31.622,-8.777]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.294000004787,0.564999988032,0.620000023935,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[328.395,297.61],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 144","np":4,"cix":2,"ix":144,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-19.335,8.236],[0,0],[0,0]],"o":[[0,0],[0,0],[21.613,28.38]],"v":[[36.026,18.967],[-20.992,-27.203],[-36.026,-8.443]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.128999986836,0.486000001197,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[328.586,298.031],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 145","np":4,"cix":2,"ix":145,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-3.261,0.536],[-0.172,-3.318],[3.261,-0.537],[0.173,3.318]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.102000000898,0.39199999641,0.451000019148,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[359.816,310.907],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 146","np":4,"cix":2,"ix":146,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-4.62,2.13],[4.62,-0.918],[4.133,-2.13]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.811999990426,0.435000011968,0.187999994615,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[49.677,258.559],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 147","np":4,"cix":2,"ix":147,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.73,-1.817],[-1.755,0.713],[0,0]],"o":[[0,0],[-1.755,0.713],[0.73,1.816],[0,0],[0,0]],"v":[[3.631,-5.132],[-3.688,-2.158],[-5.544,2.421],[-1.045,4.419],[6.274,1.446]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.322000002394,0.128999986836,0.105999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[114.128,232.659],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 148","np":4,"cix":2,"ix":148,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[5.668,-6.721],[8.398,0.072],[-7.976,6.721],[-8.398,-1.008]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8,0.216000007181,0.216000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[107.627,223.141],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 149","np":4,"cix":2,"ix":149,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[9.552,0.54],[6.822,-6.253],[-9.551,0.396],[-4.514,6.253]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8,0.216000007181,0.216000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[115.071,244.064],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 150","np":4,"cix":2,"ix":150,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[5.253,-10.624],[11.12,3.975],[-5.253,10.624],[-11.12,-3.975]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.184000007779,0.184000007779,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[110.772,233.837],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 151","np":4,"cix":2,"ix":151,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.39,-0.97],[-0.389,-0.97],[0,0],[-0.39,-0.969],[-0.39,-0.97],[0,0],[0.634,1.577],[0,0],[0.634,1.577],[0,0]],"o":[[0.39,0.971],[0.391,0.97],[0,0],[0.39,0.971],[0.39,0.971],[0,0],[-0.633,-1.577],[0,0],[-0.634,-1.576],[0,0]],"v":[[-7.078,-15.726],[-6.952,-7.03],[-3.653,1.175],[-0.355,9.381],[5.563,15.725],[6.733,18.636],[7.614,14.892],[1.294,-0.833],[-5.027,-16.559],[-8.248,-18.636]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.322000002394,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[104.392,236.736],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 152","np":4,"cix":2,"ix":152,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.529,-1.318],[-1.274,0.517],[0,0]],"o":[[0,0],[-1.274,0.518],[0.53,1.319],[0,0],[0,0]],"v":[[2.635,-3.725],[-2.678,-1.567],[-4.026,1.757],[-0.759,3.208],[4.555,1.049]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.322000002394,0.128999986836,0.105999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[99.08,238.777],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 153","np":4,"cix":2,"ix":153,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[3.236,-5.234],[5.657,0.79],[-5.282,5.234],[-5.657,-1.622]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8,0.216000007181,0.216000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[95.152,229.563],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 154","np":4,"cix":2,"ix":154,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[6.68,1.206],[4.259,-4.817],[-6.68,-0.375],[-2.213,4.818]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8,0.216000007181,0.216000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[101.755,248.118],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 155","np":4,"cix":2,"ix":155,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.868,-8.695],[8.072,4.252],[-2.867,8.695],[-8.072,-4.252]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.184000007779,0.184000007779,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[97.942,239.048],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 156","np":4,"cix":2,"ix":156,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.346,-0.86],[-0.345,-0.86],[0,0],[-0.345,-0.861],[-0.346,-0.861],[0,0],[0.562,1.399],[0,0],[0.562,1.398],[0,0]],"o":[[0.346,0.86],[0.346,0.861],[0,0],[0.346,0.86],[0.346,0.86],[0,0],[-0.562,-1.398],[0,0],[-0.562,-1.399],[0,0]],"v":[[-6.277,-13.946],[-6.165,-6.234],[-3.239,1.042],[-0.315,8.32],[4.934,13.947],[5.972,16.527],[6.753,13.207],[1.147,-0.739],[-4.458,-14.685],[-7.315,-16.527]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.322000002394,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[94.074,240.891],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 157","np":4,"cix":2,"ix":157,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.475,-1.184],[-1.143,0.464],[0,0]],"o":[[0,0],[-1.143,0.464],[0.476,1.183],[0,0],[0,0]],"v":[[2.365,-3.342],[-2.403,-1.406],[-3.612,1.577],[-0.681,2.878],[4.087,0.941]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.322000002394,0.128999986836,0.105999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[89.263,242.744],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 158","np":4,"cix":2,"ix":158,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.903,-4.696],[5.076,0.709],[-4.74,4.696],[-5.076,-1.456]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8,0.216000007181,0.216000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[85.74,234.477],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 159","np":4,"cix":2,"ix":159,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[5.994,1.081],[3.822,-4.323],[-5.993,-0.338],[-1.986,4.322]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8,0.216000007181,0.216000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[91.663,251.126],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 160","np":4,"cix":2,"ix":160,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.573,-7.801],[7.242,3.816],[-2.573,7.802],[-7.242,-3.815]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.184000007779,0.184000007779,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[88.242,242.987],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 161","np":4,"cix":2,"ix":161,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.311,-0.772],[-0.31,-0.772],[0,0],[-0.31,-0.773],[-0.31,-0.772],[0,0],[0.504,1.255],[0,0],[0.504,1.255],[0,0]],"o":[[0.31,0.771],[0.31,0.772],[0,0],[0.31,0.772],[0.31,0.772],[0,0],[-0.504,-1.255],[0,0],[-0.504,-1.255],[0,0]],"v":[[-5.632,-12.514],[-5.531,-5.595],[-2.907,0.934],[-0.282,7.465],[4.427,12.512],[5.358,14.829],[6.059,11.849],[1.03,-0.663],[-4,-13.177],[-6.563,-14.83]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.322000002394,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[84.772,244.642],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 162","np":4,"cix":2,"ix":162,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.414,-1.031],[-0.996,0.405],[0,0]],"o":[[0,0],[-0.996,0.405],[0.415,1.031],[0,0],[0,0]],"v":[[2.062,-2.914],[-2.094,-1.226],[-3.148,1.374],[-0.593,2.508],[3.562,0.82]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.322000002394,0.128999986836,0.105999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[80.445,246.303],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 163","np":4,"cix":2,"ix":163,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.531,-4.093],[4.425,0.618],[-4.131,4.093],[-4.425,-1.269]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8,0.216000007181,0.216000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[77.374,239.096],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 164","np":4,"cix":2,"ix":164,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[5.225,0.943],[3.331,-3.768],[-5.225,-0.293],[-1.73,3.768]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8,0.216000007181,0.216000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[82.537,253.609],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 165","np":4,"cix":2,"ix":165,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.243,-6.801],[6.313,3.326],[-2.243,6.801],[-6.313,-3.326]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.184000007779,0.184000007779,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[79.555,246.515],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 166","np":4,"cix":2,"ix":166,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.271,-0.673],[-0.27,-0.673],[0,0],[-0.27,-0.673],[-0.27,-0.672],[0,0],[0.439,1.094],[0,0],[0.44,1.094],[0,0]],"o":[[0.271,0.673],[0.271,0.673],[0,0],[0.271,0.673],[0,0],[0,0],[-0.44,-1.093],[0,0],[-0.439,-1.094],[0,0]],"v":[[-4.909,-10.907],[-4.822,-4.876],[-2.534,0.817],[-0.246,6.508],[3.859,10.908],[4.671,12.927],[5.282,10.33],[0.898,-0.577],[-3.487,-11.485],[-5.721,-12.927]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.322000002394,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[76.531,247.956],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 167","np":4,"cix":2,"ix":167,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.364,-0.905],[-0.874,0.355],[0,0]],"o":[[0,0],[-0.874,0.355],[0.363,0.905],[0,0],[0,0]],"v":[[1.809,-2.556],[-1.837,-1.075],[-2.762,1.206],[-0.52,2.201],[3.126,0.72]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.322000002394,0.128999986836,0.105999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[72.684,249.436],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 168","np":4,"cix":2,"ix":168,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.22,-3.591],[3.882,0.543],[-3.625,3.591],[-3.882,-1.112]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8,0.216000007181,0.216000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[69.99,243.114],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 169","np":4,"cix":2,"ix":169,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4.584,0.827],[2.922,-3.307],[-4.584,-0.258],[-1.519,3.306]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8,0.216000007181,0.216000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[74.52,255.847],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 170","np":4,"cix":2,"ix":170,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.968,-5.967],[5.539,2.917],[-1.969,5.967],[-5.538,-2.919]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.184000007779,0.184000007779,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[71.904,249.623],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 171","np":4,"cix":2,"ix":171,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.237,-0.59],[-0.237,-0.591],[0,0],[-0.237,-0.591],[-0.237,-0.591],[0,0],[0.386,0.96],[0,0],[0.386,0.96],[0,0]],"o":[[0.237,0.591],[0.237,0.591],[0,0],[0.238,0.591],[0.237,0.59],[0,0],[-0.386,-0.959],[0,0],[-0.386,-0.959],[0,0]],"v":[[-4.307,-9.57],[-4.23,-4.278],[-2.223,0.716],[-0.217,5.709],[3.385,9.57],[4.098,11.341],[4.633,9.063],[0.788,-0.507],[-3.06,-10.077],[-5.02,-11.341]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.322000002394,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[69.25,250.888],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 172","np":4,"cix":2,"ix":172,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.331,-0.823],[-0.795,0.323],[0,0]],"o":[[0,0],[-0.796,0.323],[0.33,0.823],[0,0],[0,0]],"v":[[1.645,-2.325],[-1.671,-0.978],[-2.512,1.097],[-0.474,2.002],[2.843,0.655]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.322000002394,0.128999986836,0.105999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[65.806,252.218],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 173","np":4,"cix":2,"ix":173,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.02,-3.266],[3.531,0.495],[-3.297,3.267],[-3.531,-1.011]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8,0.216000007181,0.216000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[63.354,246.466],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 174","np":4,"cix":2,"ix":174,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4.17,0.753],[2.658,-3.007],[-4.17,-0.234],[-1.381,3.008]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8,0.216000007181,0.216000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[67.476,258.049],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 175","np":4,"cix":2,"ix":175,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.79,-5.427],[5.038,2.654],[-1.79,5.427],[-5.038,-2.655]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.184000007779,0.184000007779,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[65.096,252.387],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 176","np":4,"cix":2,"ix":176,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.216,-0.537],[0,0],[-0.216,-0.537],[-0.216,-0.537],[0,0],[0.351,0.872],[0,0],[0.35,0.873],[0,0]],"o":[[0.216,0.537],[0.216,0.538],[0,0],[0.216,0.538],[0,0],[0,0],[-0.351,-0.873],[0,0],[-0.351,-0.872],[0,0]],"v":[[-3.919,-8.705],[-3.848,-3.892],[-2.023,0.65],[-0.197,5.193],[3.079,8.705],[3.728,10.316],[4.215,8.244],[0.715,-0.462],[-2.783,-9.167],[-4.566,-10.316]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.322000002394,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[62.682,253.538],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 177","np":4,"cix":2,"ix":177,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.276,-0.686],[-0.663,0.27],[0,0]],"o":[[0,0],[-0.663,0.27],[0.276,0.687],[0,0],[0,0]],"v":[[1.373,-1.939],[-1.394,-0.816],[-2.096,0.915],[-0.395,1.669],[2.372,0.547]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.322000002394,0.128999986836,0.105999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[59.426,254.789],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 178","np":4,"cix":2,"ix":178,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.685,-2.725],[2.946,0.412],[-2.751,2.725],[-2.946,-0.844]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8,0.216000007181,0.216000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[57.381,249.991],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 179","np":4,"cix":2,"ix":179,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[3.479,0.628],[2.217,-2.509],[-3.479,-0.195],[-1.152,2.509]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8,0.216000007181,0.216000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[60.819,259.654],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 180","np":4,"cix":2,"ix":180,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.493,-4.528],[4.203,2.214],[-1.493,4.528],[-4.203,-2.215]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.184000007779,0.184000007779,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[58.834,254.931],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 181","np":4,"cix":2,"ix":181,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.18,-0.448],[-0.181,-0.449],[0,0],[-0.18,-0.449],[-0.179,-0.448],[0,0],[0.293,0.728],[0,0],[0.293,0.729],[0,0]],"o":[[0.18,0.448],[0.179,0.448],[0,0],[0.181,0.448],[0.181,0.449],[0,0],[-0.293,-0.729],[0,0],[-0.293,-0.727],[0,0]],"v":[[-3.269,-7.262],[-3.21,-3.246],[-1.687,0.544],[-0.165,4.333],[2.568,7.262],[3.109,8.606],[3.516,6.878],[0.598,-0.384],[-2.322,-7.647],[-3.81,-8.606]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.322000002394,0.560999971278,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[56.82,255.89],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 182","np":4,"cix":2,"ix":182,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.475,-1.179],[-1.141,0.463],[0,0]],"o":[[0,0],[-1.14,0.463],[0.474,1.181],[0,0],[0,0]],"v":[[1.027,-2.793],[-1.063,-1.943],[-2.269,1.031],[0.655,2.329],[2.744,1.48]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.811999990426,0.435000011968,0.187999994615,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[54.389,256.789],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 183","np":4,"cix":2,"ix":183,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-1.2,-1.533],[-1.482,1.172],[0,0]],"o":[[0,0],[-1.482,1.172],[1.201,1.533],[0,0],[0,0]],"v":[[0.871,-5.095],[-3.51,-1.628],[-4.018,3.27],[0.839,3.923],[5.219,0.456]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.322000002394,0.128999986836,0.105999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[109.612,267.586],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 184","np":4,"cix":2,"ix":184,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-1.2,-1.533],[-1.482,1.172],[0,0]],"o":[[0,0],[-1.481,1.172],[1.201,1.533],[0,0],[0,0]],"v":[[0.87,-5.095],[-3.51,-1.628],[-4.019,3.27],[0.838,3.923],[5.218,0.456]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.322000002394,0.128999986836,0.105999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[134.953,299.937],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 185","np":4,"cix":2,"ix":185,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.779,-0.994],[-0.961,0.761],[0,0]],"o":[[0,0],[-0.96,0.761],[0.779,0.994],[0,0],[0,0]],"v":[[1.059,-3.696],[-2.771,-0.666],[-3.1,2.511],[0.049,2.934],[3.879,-0.095]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.322000002394,0.128999986836,0.105999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[119.347,286.117],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 186","np":4,"cix":2,"ix":186,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-1.197,-1.528],[-1.477,1.169],[0,0]],"o":[[0,0],[-1.477,1.169],[1.197,1.529],[0,0],[0,0]],"v":[[1.628,-5.681],[-4.258,-1.023],[-4.765,3.861],[0.077,4.512],[5.963,-0.147]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.322000002394,0.128999986836,0.105999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[137.758,271.513],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 187","np":4,"cix":2,"ix":187,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-1.95,-2.49],[-2.406,1.905],[0,0]],"o":[[0,0],[-2.406,1.904],[1.95,2.489],[0,0],[0,0]],"v":[[2.968,-9.505],[-7.254,-1.415],[-8.08,6.542],[-0.192,7.601],[10.03,-0.488]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588000009574,0.224000010771,0.184000007779,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[135.055,273.597],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 188","np":4,"cix":2,"ix":188,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-1.95,-2.489],[-2.407,1.904],[0,0]],"o":[[0,0],[-2.406,1.904],[1.951,2.49],[0,0],[0,0]],"v":[[7.253,-12.897],[-11.539,1.976],[-12.365,9.932],[-4.476,10.993],[14.315,-3.88]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.870999983245,0.380000005984,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[120.956,284.755],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 189","np":4,"cix":2,"ix":189,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-3.993,-5.098],[-4.927,3.9],[0,0]],"o":[[0,0],[-4.927,3.9],[3.994,5.099],[0,0],[0,0]],"v":[[6.078,-19.465],[-14.855,-2.898],[-16.546,13.395],[-0.392,15.565],[20.54,-1.001]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.842999985639,0.560999971278,0.411999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[128.245,278.833],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 190","np":4,"cix":2,"ix":190,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-16.867,-24.393],[19.632,22.206],[16.868,24.393],[-19.632,-22.204]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.322000002394,0.128999986836,0.105999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[126.349,280.632],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 191","np":4,"cix":2,"ix":191,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-16.712,-25.623],[20.858,22.341],[16.711,25.623],[-20.858,-22.342]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588000009574,0.224000010771,0.184000007779,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[139.481,270.241],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 192","np":4,"cix":2,"ix":192,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-3.994,-5.099],[-4.927,3.9],[0,0]],"o":[[0,0],[-4.928,3.9],[3.994,5.1],[0,0],[0,0]],"v":[[-2.232,-12.889],[-6.546,-9.475],[-8.237,6.818],[7.917,8.989],[12.23,5.576]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.769000004787,0.298000021542,0.19199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[112.771,291.08],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 193","np":4,"cix":2,"ix":193,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-4.153,-33.883],[31.792,12.008],[4.153,33.883],[-31.792,-12.008]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.769000004787,0.298000021542,0.19199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[124.555,282.053],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 194","np":4,"cix":2,"ix":194,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-5.499,-7.02],[-6.784,5.369],[0,0]],"o":[[0,0],[-6.784,5.369],[5.498,7.019],[0,0],[0,0]],"v":[[-2.41,-18.27],[-9.674,-12.52],[-12.002,9.913],[10.237,12.901],[17.501,7.152]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.842999985639,0.560999971278,0.411999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[112.506,291.176],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 195","np":4,"cix":2,"ix":195,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-16.003,-24.654],[19.942,21.237],[17.235,24.654],[-19.942,-22.81]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.842999985639,0.560999971278,0.411999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[108.766,294.699],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 196","np":4,"cix":2,"ix":196,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.29,0.229],[-0.228,-0.29],[0,0],[0.289,-0.228],[0.228,0.29],[0,0]],"o":[[0.289,-0.229],[0,0],[0.228,0.291],[-0.289,0.23],[0,0],[-0.227,-0.291]],"v":[[-4.372,-5.582],[-3.436,-5.471],[4.483,4.64],[4.372,5.581],[3.436,5.47],[-4.484,-4.641]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588000009574,0.224000010771,0.184000007779,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[79.584,291.558],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 197","np":4,"cix":2,"ix":197,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.853,-0.532],[-0.316,-0.958],[0.852,0.533],[0.314,0.958]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.769000004787,0.298000021542,0.19199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[70.542,298.713],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 198","np":4,"cix":2,"ix":198,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.036,-1.258],[1.458,-0.717],[-1.036,1.258],[-1.459,0.717]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.769000004787,0.298000021542,0.19199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[70.811,298.501],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 199","np":4,"cix":2,"ix":199,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.002,-1.714],[1.657,0.404],[0.002,1.714],[-1.657,-0.404]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.842999985639,0.560999971278,0.411999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[73.47,296.396],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 200","np":4,"cix":2,"ix":200,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.677,-1.469],[1.262,1.007],[0.677,1.469],[-1.262,-1.006]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588000009574,0.224000010771,0.184000007779,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[72.351,297.282],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 201","np":4,"cix":2,"ix":201,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.475,-1.816],[1.646,0.891],[0.475,1.816],[-1.646,-0.889]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588000009574,0.224000010771,0.184000007779,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[74.883,295.278],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 202","np":4,"cix":2,"ix":202,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.871,-1.111],[-2.291,1.813],[0,0]],"o":[[0,0],[-2.291,1.812],[0.871,1.112],[0,0],[0,0]],"v":[[-0.055,-3.003],[-0.236,-2.86],[-2.807,2.434],[2.918,1.164],[3.098,1.022]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.722000002394,0.451000019148,0.310000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[78.098,292.52],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 203","np":4,"cix":2,"ix":203,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.22,-2.835],[-2.291,1.813],[0,0]],"o":[[0,0],[-2.291,1.812],[2.221,2.835],[0,0],[0,0]],"v":[[-2.758,-6.111],[-2.938,-5.968],[-3.065,2.448],[5.105,4.298],[5.285,4.156]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.842999985639,0.560999971278,0.411999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[78.356,292.507],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 204","np":4,"cix":2,"ix":204,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-1.004,-1.282],[-1.239,0.981],[0,0]],"o":[[0,0],[-1.239,0.981],[1.004,1.281],[0,0],[0,0]],"v":[[0.728,-4.26],[-2.934,-1.362],[-3.359,2.734],[0.701,3.279],[4.363,0.381]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588000009574,0.224000010771,0.184000007779,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[92.219,281.482],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 205","np":4,"cix":2,"ix":205,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-5.68,-5.34],[3.736,6.681],[5.68,4.3],[-2.921,-6.681]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.842999985639,0.560999971278,0.411999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[84.168,288.028],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 206","np":4,"cix":2,"ix":206,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.286,-7.29],[6.749,2.966],[1.285,7.29],[-6.749,-2.967]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.769000004787,0.298000021542,0.19199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[82.352,289.368],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 207","np":4,"cix":2,"ix":207,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0.611,-9.378],[9.212,1.603],[-0.611,9.378],[-9.212,-1.604]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.769000004787,0.298000021542,0.19199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[90.459,282.95],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 208","np":4,"cix":2,"ix":208,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.289,0.229],[-0.229,-0.291],[0,0],[0.289,-0.229],[0.228,0.291],[0,0]],"o":[[0.29,-0.229],[0,0],[0.227,0.291],[-0.29,0.229],[0,0],[-0.228,-0.291]],"v":[[-4.372,-5.582],[-3.435,-5.47],[4.484,4.641],[4.373,5.582],[3.436,5.47],[-4.483,-4.641]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588000009574,0.224000010771,0.184000007779,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[104.812,323.766],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 209","np":4,"cix":2,"ix":209,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.852,-0.533],[-0.316,-0.958],[0.853,0.533],[0.316,0.958]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.769000004787,0.298000021542,0.19199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[95.77,330.922],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 210","np":4,"cix":2,"ix":210,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.036,-1.257],[1.459,-0.717],[-1.035,1.257],[-1.459,0.718]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.769000004787,0.298000021542,0.19199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[96.039,330.71],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 211","np":4,"cix":2,"ix":211,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.002,-1.714],[1.657,0.405],[0.002,1.714],[-1.657,-0.404]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.842999985639,0.560999971278,0.411999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[98.699,328.604],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 212","np":4,"cix":2,"ix":212,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.677,-1.469],[1.262,1.006],[0.677,1.469],[-1.262,-1.006]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588000009574,0.224000010771,0.184000007779,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[97.579,329.491],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 213","np":4,"cix":2,"ix":213,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.475,-1.816],[1.645,0.889],[0.474,1.816],[-1.645,-0.89]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588000009574,0.224000010771,0.184000007779,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[100.112,327.487],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 214","np":4,"cix":2,"ix":214,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.871,-1.111],[-2.291,1.812],[0,0]],"o":[[0,0],[-2.291,1.812],[0.871,1.113],[0,0],[0,0]],"v":[[-0.056,-3.003],[-0.236,-2.86],[-2.807,2.434],[2.917,1.165],[3.098,1.022]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.722000002394,0.451000019148,0.310000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[103.327,324.728],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 215","np":4,"cix":2,"ix":215,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.22,-2.835],[-2.291,1.813],[0,0]],"o":[[0,0],[-2.29,1.813],[2.221,2.835],[0,0],[0,0]],"v":[[-2.758,-6.111],[-2.938,-5.969],[-3.065,2.447],[5.105,4.298],[5.285,4.156]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.842999985639,0.560999971278,0.411999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[103.584,324.716],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 216","np":4,"cix":2,"ix":216,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-1.004,-1.281],[-1.239,0.981],[0,0]],"o":[[0,0],[-1.238,0.981],[1.004,1.281],[0,0],[0,0]],"v":[[0.727,-4.26],[-2.935,-1.363],[-3.36,2.733],[0.702,3.279],[4.363,0.381]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.588000009574,0.224000010771,0.184000007779,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[117.448,313.691],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 217","np":4,"cix":2,"ix":217,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-5.68,-5.34],[3.736,6.681],[5.68,4.3],[-2.921,-6.681]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.842999985639,0.560999971278,0.411999990426,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[109.397,320.236],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 218","np":4,"cix":2,"ix":218,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.285,-7.29],[6.749,2.966],[1.286,7.29],[-6.749,-2.966]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.769000004787,0.298000021542,0.19199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[107.58,321.576],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 219","np":4,"cix":2,"ix":219,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0.611,-9.377],[9.212,1.603],[-0.611,9.377],[-9.212,-1.604]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.769000004787,0.298000021542,0.19199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[115.688,315.159],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 220","np":4,"cix":2,"ix":220,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-8.038,-2.556],[-1.698,21.509],[8.038,-21.509]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.783999992819,0.722000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[64.603,173.777],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 221","np":4,"cix":2,"ix":221,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-12.322,-3.919],[-2.603,32.971],[12.323,-32.971]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.541000007181,0.569000004787,0.522000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[65.901,174.458],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 222","np":4,"cix":2,"ix":222,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.863,-1.797],[1.809,2.861],[-2.863,1.796],[-1.808,-2.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.541000007181,0.569000004787,0.522000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[110.337,159.752],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 223","np":4,"cix":2,"ix":223,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.923,-2.01],[0.869,2.648],[-1.923,2.011],[-0.869,-2.647]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.541000007181,0.569000004787,0.522000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[79.989,152.831],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 224","np":4,"cix":2,"ix":224,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[15.31,1.459],[14.492,5.074],[-15.31,-2.014],[-14.617,-5.074]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.783999992819,0.722000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[95.401,156.478],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 225","np":4,"cix":2,"ix":225,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.863,-1.797],[1.809,2.861],[-2.863,1.796],[-1.809,-2.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.541000007181,0.569000004787,0.522000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[108.294,168.779],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 226","np":4,"cix":2,"ix":226,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.924,-2.011],[0.868,2.647],[-1.924,2.01],[-0.869,-2.648]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.541000007181,0.569000004787,0.522000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[77.946,161.858],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 227","np":4,"cix":2,"ix":227,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[15.31,1.459],[14.492,5.074],[-15.31,-2.014],[-14.617,-5.074]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.783999992819,0.722000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[93.358,165.504],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 228","np":4,"cix":2,"ix":228,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.863,-1.797],[1.809,2.861],[-2.863,1.796],[-1.809,-2.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.541000007181,0.569000004787,0.522000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[106.251,177.805],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 229","np":4,"cix":2,"ix":229,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.923,-2.01],[0.869,2.648],[-1.923,2.011],[-0.869,-2.647]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.541000007181,0.569000004787,0.522000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[75.903,170.884],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 230","np":4,"cix":2,"ix":230,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[15.31,1.459],[14.492,5.074],[-15.31,-2.014],[-14.617,-5.074]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.783999992819,0.722000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[91.316,174.531],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 231","np":4,"cix":2,"ix":231,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.863,-1.797],[1.809,2.861],[-2.863,1.796],[-1.809,-2.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.541000007181,0.569000004787,0.522000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[104.208,186.832],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 232","np":4,"cix":2,"ix":232,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.924,-2.01],[0.87,2.648],[-1.924,2.011],[-0.869,-2.647]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.541000007181,0.569000004787,0.522000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[73.86,179.911],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 233","np":4,"cix":2,"ix":233,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[15.31,1.459],[14.492,5.074],[-15.31,-2.014],[-14.617,-5.074]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.783999992819,0.722000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[89.272,183.557],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 234","np":4,"cix":2,"ix":234,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.863,-1.797],[1.809,2.861],[-2.863,1.796],[-1.808,-2.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.541000007181,0.569000004787,0.522000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[102.165,195.858],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 235","np":4,"cix":2,"ix":235,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.924,-2.011],[0.87,2.647],[-1.924,2.01],[-0.869,-2.648]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.541000007181,0.569000004787,0.522000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[71.817,188.938],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 236","np":4,"cix":2,"ix":236,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[15.31,1.459],[14.492,5.074],[-15.31,-2.014],[-14.617,-5.074]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.783999992819,0.722000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[87.23,192.584],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 237","np":4,"cix":2,"ix":237,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.863,-1.797],[1.808,2.861],[-2.863,1.796],[-1.808,-2.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.541000007181,0.569000004787,0.522000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[100.122,204.885],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 238","np":4,"cix":2,"ix":238,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.924,-2.01],[0.87,2.648],[-1.924,2.011],[-0.869,-2.647]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.541000007181,0.569000004787,0.522000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[69.774,197.964],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 239","np":4,"cix":2,"ix":239,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[15.31,1.46],[14.492,5.074],[-15.31,-2.013],[-14.617,-5.074]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.783999992819,0.722000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[85.187,201.61],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 240","np":4,"cix":2,"ix":240,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[9.137,-29.077],[-4.276,30.186],[-9.138,29.077],[4.275,-30.186]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.783999992819,0.722000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[114.023,184.324],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 241","np":4,"cix":2,"ix":241,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[7.367,-26.217],[-4.642,26.84],[-7.367,26.219],[4.641,-26.839]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.62400004069,0.658999992819,0.603999956916,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[72.123,174.768],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 242","np":4,"cix":2,"ix":242,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[9.033,-27.251],[-3.583,28.494],[-9.033,27.25],[3.583,-28.494]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.62400004069,0.658999992819,0.603999956916,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[110.29,183.473],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 243","np":4,"cix":2,"ix":243,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.529,-0.369],[0.367,-0.531],[0.529,0.369],[-0.367,0.532]],"o":[[0.529,0.369],[-0.367,0.532],[-0.529,-0.369],[0.367,-0.531]],"v":[[0.665,-0.963],[0.958,0.668],[-0.665,0.963],[-0.958,-0.669]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.689999988032,0.113999998803,0.023999999551,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[89.582,110.001],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 244","np":4,"cix":2,"ix":244,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[15.573,-5.379],[16.13,3.332],[-15.573,5.379],[-16.13,-3.332]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.889999988032,0.654999976065,0.337000020345,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[111.641,103.762],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 245","np":4,"cix":2,"ix":245,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[15.573,-5.379],[16.13,3.332],[-15.573,5.379],[-16.13,-3.332]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.889999988032,0.654999976065,0.337000020345,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[67.523,116.24],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 246","np":4,"cix":2,"ix":246,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.015,-0.243],[0.242,-0.015],[0,0],[0.015,0.242],[-0.241,0.015]],"o":[[0.242,-0.016],[0.016,0.242],[0,0],[-0.242,0.016],[-0.015,-0.243],[0,0]],"v":[[38.929,-2.955],[39.394,-2.542],[38.985,-2.075],[-38.929,2.955],[-39.395,2.544],[-38.986,2.076]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.298000021542,0.078000005086,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[89.582,110.001],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 247","np":4,"cix":2,"ix":247,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[5.351,15.654],[-3.315,16.214],[-5.351,-15.654],[3.315,-16.214]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.889999988032,0.654999976065,0.337000020345,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[95.788,132.175],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 248","np":4,"cix":2,"ix":248,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[5.351,15.654],[-3.314,16.214],[-5.351,-15.654],[3.314,-16.214]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.889999988032,0.654999976065,0.337000020345,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[83.376,87.827],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 249","np":4,"cix":2,"ix":249,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.242,-0.015],[0.016,0.242],[0,0],[-0.241,0.016],[-0.016,-0.243]],"o":[[0.016,0.243],[-0.242,0.016],[0,0],[-0.016,-0.243],[0.241,-0.016],[0,0]],"v":[[2.939,39.131],[2.53,39.599],[2.064,39.188],[-2.939,-39.132],[-2.53,-39.6],[-2.064,-39.188]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.54900004069,0.298000021542,0.078000005086,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[89.582,110.001],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 250","np":4,"cix":2,"ix":250,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.912,-0.636],[0.633,-0.916],[0.912,0.636],[-0.633,0.916]],"o":[[0.911,0.636],[-0.633,0.916],[-0.912,-0.636],[0.633,-0.916]],"v":[[1.146,-1.659],[1.65,1.152],[-1.146,1.659],[-1.651,-1.151]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.093999997307,0.019999999626,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[89.582,110.001],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 251","np":4,"cix":2,"ix":251,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.29,-0.251],[0.566,2.244],[-2.29,0.251],[-0.567,-2.244]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.093999997307,0.019999999626,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[115.794,125.908],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 252","np":4,"cix":2,"ix":252,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.29,-0.251],[0.566,2.244],[-2.29,0.251],[-0.567,-2.244]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.093999997307,0.019999999626,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[113.576,129.12],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 253","np":4,"cix":2,"ix":253,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.29,-0.252],[0.567,2.244],[-2.29,0.251],[-0.566,-2.244]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.093999997307,0.019999999626,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[112.221,123.416],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 254","np":4,"cix":2,"ix":254,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.29,-0.251],[0.566,2.244],[-2.29,0.251],[-0.566,-2.244]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.093999997307,0.019999999626,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[110.003,126.628],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 255","np":4,"cix":2,"ix":255,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[6.314,-0.868],[1.4,6.25],[-6.314,0.868],[-1.4,-6.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.630999995213,0.141000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[112.899,126.268],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 256","np":4,"cix":2,"ix":256,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.29,-0.251],[0.566,2.244],[-2.29,0.251],[-0.566,-2.244]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.093999997307,0.019999999626,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[104.289,117.882],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 257","np":4,"cix":2,"ix":257,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.29,-0.251],[0.566,2.244],[-2.29,0.251],[-0.567,-2.244]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.093999997307,0.019999999626,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[102.071,121.094],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 258","np":4,"cix":2,"ix":258,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.29,-0.251],[0.566,2.244],[-2.29,0.251],[-0.567,-2.244]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.093999997307,0.019999999626,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[100.716,115.389],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 259","np":4,"cix":2,"ix":259,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[2.29,-0.251],[0.566,2.244],[-2.29,0.251],[-0.566,-2.244]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.093999997307,0.019999999626,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[98.499,118.601],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 260","np":4,"cix":2,"ix":260,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[6.314,-0.868],[1.399,6.25],[-6.314,0.868],[-1.4,-6.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.630999995213,0.141000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[101.394,118.242],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 261","np":4,"cix":2,"ix":261,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.396,-0.276],[0.275,-0.398],[0,0],[0.396,0.277],[-0.275,0.398],[0,0]],"o":[[0.396,0.276],[0,0],[-0.275,0.398],[-0.396,-0.276],[0,0],[0.275,-0.398]],"v":[[8.087,-11.714],[8.307,-10.493],[-6.873,11.493],[-8.088,11.713],[-8.307,10.492],[6.873,-11.494]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.638999968884,0.344999994016,0.090000002992,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[93.23,112.546],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 262","np":4,"cix":2,"ix":262,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[2.078,-3.009],[-4.613,-3.35]],"o":[[-4.736,-3.172],[-2.078,3.01],[0,0]],"v":[[7.165,-3.878],[-5.087,-4.207],[-0.495,7.216]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.830999995213,0.352999997606,0.102000000898,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[89.998,110.948],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 263","np":4,"cix":2,"ix":263,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.037,-5.847],[-5.656,-4.202]],"o":[[-5.895,-3.856],[-4.037,5.847],[0,0]],"v":[[10.942,-8.849],[-6.904,-5.331],[-3.941,12.705]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.870999983245,0.470999983245,0.125,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[89.832,110.689],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 264","np":4,"cix":2,"ix":264,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[19.542,13.634],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[19.542,13.633],[0,0],[0,0],[0,0]],"v":[[-14.505,-19.931],[-18.518,-14.118],[-22.531,-8.306],[8.119,19.931],[15.325,9.493],[22.531,-0.944]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.122000002394,0.027000000898,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[111.244,126.312],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 265","np":4,"cix":2,"ix":265,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[19.542,13.634],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[19.542,13.634],[0,0],[0,0],[0,0]],"v":[[-12.749,-25.833],[-19.678,-15.798],[-26.607,-5.764],[1.725,25.833],[14.166,7.814],[26.607,-10.206]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.093999997307,0.019999999626,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[112.403,127.992],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 266","np":4,"cix":2,"ix":266,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.214,-0.15],[0.149,-0.216],[0,0],[0.214,0.149],[-0.149,0.216],[0,0]],"o":[[0.214,0.149],[0,0],[-0.149,0.215],[-0.215,-0.15],[0,0],[0.148,-0.215]],"v":[[3.087,-4.471],[3.206,-3.809],[-2.43,4.353],[-3.087,4.471],[-3.206,3.811],[2.43,-4.351]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.638999968884,0.344999994016,0.090000002992,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[136.061,142.427],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 267","np":4,"cix":2,"ix":267,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[6.169,0.076],[2.228,5.783],[-6.17,-0.076],[-2.23,-5.783]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.579999976065,0.093999997307,0.019999999626,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[132.25,139.769],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 268","np":4,"cix":2,"ix":268,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-5.569,8.065],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[5.569,-8.065],[0,0]],"v":[[4.473,-18.39],[-4.437,-3.484],[-15.213,10.12],[-6.546,18.39],[6.147,3.9],[15.212,-13.121]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.870999983245,0.470999983245,0.125,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[129.891,138.511],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 269","np":4,"cix":2,"ix":269,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[1.164,-1.685],[-1.629,-1.211]],"o":[[-1.699,-1.111],[-1.163,1.686],[0,0]],"v":[[3.154,-2.551],[-1.991,-1.537],[-1.137,3.662]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.630999995213,0.141000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[82.974,105.539],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 270","np":4,"cix":2,"ix":270,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.058,-0.129],[0.128,0.058],[0,0],[-0.057,0.129],[-0.128,-0.058],[0,0]],"o":[[-0.058,0.129],[0,0],[-0.128,-0.057],[0.058,-0.13],[0,0],[0.128,0.058]],"v":[[7.781,3.51],[7.444,3.64],[-7.654,-3.173],[-7.781,-3.511],[-7.444,-3.64],[7.652,3.171]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[288.09,18.685],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 271","np":4,"cix":2,"ix":271,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.115,0.908],[-0.598,0.69],[0.115,-0.908],[0.599,-0.69]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[294.732,22.661],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 272","np":4,"cix":2,"ix":272,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.116,0.908],[-0.598,0.69],[0.114,-0.908],[0.598,-0.69]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[293.331,22.028],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 273","np":4,"cix":2,"ix":273,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.116,0.908],[-0.598,0.69],[0.115,-0.908],[0.598,-0.69]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[291.93,21.396],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 274","np":4,"cix":2,"ix":274,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.115,0.908],[-0.598,0.69],[0.115,-0.908],[0.598,-0.69]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[290.528,20.764],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 275","np":4,"cix":2,"ix":275,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.115,0.908],[-0.598,0.69],[0.115,-0.908],[0.598,-0.69]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[289.127,20.132],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 276","np":4,"cix":2,"ix":276,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.115,0.908],[-0.598,0.69],[0.115,-0.908],[0.599,-0.69]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[287.726,19.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 277","np":4,"cix":2,"ix":277,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.116,0.908],[-0.599,0.69],[0.114,-0.908],[0.598,-0.69]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[286.325,18.867],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 278","np":4,"cix":2,"ix":278,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.116,0.908],[-0.599,0.69],[0.114,-0.908],[0.598,-0.69]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[284.923,18.235],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 279","np":4,"cix":2,"ix":279,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.116,0.908],[-0.598,0.69],[0.114,-0.908],[0.598,-0.69]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[283.522,17.603],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 280","np":4,"cix":2,"ix":280,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.116,0.908],[-0.598,0.69],[0.115,-0.908],[0.598,-0.69]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[282.121,16.97],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 281","np":4,"cix":2,"ix":281,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.115,0.908],[-0.598,0.69],[0.115,-0.908],[0.598,-0.69]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[280.719,16.338],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 282","np":4,"cix":2,"ix":282,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.275,4.328],[-8.716,-3.339],[-8.275,-4.328],[8.716,3.339]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[283.362,29.271],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 283","np":4,"cix":2,"ix":283,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.586,0.265],[0.262,-0.589],[0,0]],"o":[[0,0],[0.264,-0.59],[-0.587,-0.264],[0,0],[0,0]],"v":[[-0.116,3.245],[1.974,-1.435],[1.39,-2.981],[-0.148,-2.393],[-2.238,2.287]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[290.316,29.062],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 284","np":4,"cix":2,"ix":284,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.586,0.264],[0.262,-0.59],[0,0]],"o":[[0,0],[0.264,-0.589],[-0.586,-0.265],[0,0],[0,0]],"v":[[-0.115,3.245],[1.975,-1.436],[1.389,-2.98],[-0.147,-2.392],[-2.238,2.288]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[286.477,27.329],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 285","np":4,"cix":2,"ix":285,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.586,0.265],[0.263,-0.589],[0,0]],"o":[[0,0],[0.263,-0.59],[-0.586,-0.264],[0,0],[0,0]],"v":[[-0.115,3.245],[1.975,-1.435],[1.39,-2.981],[-0.148,-2.393],[-2.238,2.287]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[282.637,25.597],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 286","np":4,"cix":2,"ix":286,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.586,0.265],[0.263,-0.589],[0,0]],"o":[[0,0],[0.263,-0.59],[-0.586,-0.264],[0,0],[0,0]],"v":[[-0.116,3.245],[1.975,-1.435],[1.39,-2.981],[-0.148,-2.393],[-2.238,2.287]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[278.799,23.865],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 287","np":4,"cix":2,"ix":287,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[11.154,5.673],[-11.63,-4.608],[-11.155,-5.673],[11.63,4.608]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[279.016,39.004],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 288","np":4,"cix":2,"ix":288,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.631,0.286],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.284],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.211],[-0.159,-2.577],[-2.41,2.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[288.655,39.749],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 289","np":4,"cix":2,"ix":289,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.631,0.286],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.284],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.211],[-0.159,-2.577],[-2.41,2.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[284.521,37.883],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 290","np":4,"cix":2,"ix":290,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.286],[0.284,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.284],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.211],[-0.159,-2.577],[-2.41,2.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[280.386,36.018],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 291","np":4,"cix":2,"ix":291,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.285],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.21],[-0.158,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[276.251,34.152],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 292","np":4,"cix":2,"ix":292,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.285],[0,0],[0,0]],"v":[[-0.125,3.495],[2.126,-1.546],[1.496,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[272.117,32.286],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 293","np":4,"cix":2,"ix":293,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[11.154,5.673],[-11.63,-4.608],[-11.155,-5.673],[11.63,4.608]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[275.12,47.726],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 294","np":4,"cix":2,"ix":294,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.286],[0.284,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.284],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.211],[-0.159,-2.577],[-2.41,2.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[284.76,48.472],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 295","np":4,"cix":2,"ix":295,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.286],[0.284,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.284],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.211],[-0.159,-2.577],[-2.41,2.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[280.625,46.606],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 296","np":4,"cix":2,"ix":296,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.284,-0.634],[-0.631,-0.285],[0,0],[0,0]],"v":[[-0.125,3.495],[2.126,-1.546],[1.496,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[276.491,44.74],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 297","np":4,"cix":2,"ix":297,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.284,-0.634],[-0.631,-0.285],[0,0],[0,0]],"v":[[-0.125,3.495],[2.126,-1.546],[1.496,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[272.356,42.875],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 298","np":4,"cix":2,"ix":298,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.631,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.632,-0.285],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[268.222,41.009],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 299","np":4,"cix":2,"ix":299,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[11.154,5.673],[-11.631,-4.608],[-11.156,-5.673],[11.63,4.608]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[271.225,56.449],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 300","np":4,"cix":2,"ix":300,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.284,-0.634],[-0.631,-0.285],[0,0],[0,0]],"v":[[-0.125,3.495],[2.126,-1.546],[1.496,-3.21],[-0.159,-2.577],[-2.41,2.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[280.865,57.194],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 301","np":4,"cix":2,"ix":301,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.284,-0.634],[-0.631,-0.285],[0,0],[0,0]],"v":[[-0.124,3.495],[2.126,-1.546],[1.496,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[276.73,55.329],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 302","np":4,"cix":2,"ix":302,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.631,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.632,-0.285],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[272.596,53.463],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 303","np":4,"cix":2,"ix":303,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.631,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.632,-0.285],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[268.461,51.597],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 304","np":4,"cix":2,"ix":304,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.631,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.632,-0.284],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.211],[-0.159,-2.577],[-2.41,2.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[264.326,49.732],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 305","np":4,"cix":2,"ix":305,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[11.155,5.673],[-11.63,-4.608],[-11.156,-5.673],[11.63,4.608]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[267.33,65.172],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 306","np":4,"cix":2,"ix":306,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.631,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.632,-0.285],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[276.97,65.917],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 307","np":4,"cix":2,"ix":307,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.631,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.632,-0.285],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[272.835,64.051],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 308","np":4,"cix":2,"ix":308,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.631,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.632,-0.285],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[268.7,62.186],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 309","np":4,"cix":2,"ix":309,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.631,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.284],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.211],[-0.159,-2.577],[-2.41,2.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[264.565,60.32],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 310","np":4,"cix":2,"ix":310,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.631,0.286],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.284],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.211],[-0.159,-2.577],[-2.41,2.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[260.431,58.455],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 311","np":4,"cix":2,"ix":311,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[11.154,5.673],[-11.63,-4.608],[-11.155,-5.673],[11.63,4.608]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[263.435,73.895],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 312","np":4,"cix":2,"ix":312,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.631,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.632,-0.285],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[273.074,74.64],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 313","np":4,"cix":2,"ix":313,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.631,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.285],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[268.939,72.774],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 314","np":4,"cix":2,"ix":314,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.631,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.285],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[264.805,70.908],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 315","np":4,"cix":2,"ix":315,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.286],[0.284,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.284],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.211],[-0.159,-2.577],[-2.41,2.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[260.67,69.043],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 316","np":4,"cix":2,"ix":316,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.286],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.284],[0,0],[0,0]],"v":[[-0.124,3.495],[2.126,-1.546],[1.496,-3.211],[-0.159,-2.577],[-2.409,2.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[256.536,67.177],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 317","np":4,"cix":2,"ix":317,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[11.154,5.673],[-11.63,-4.608],[-11.155,-5.673],[11.63,4.608]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[259.539,82.617],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 318","np":4,"cix":2,"ix":318,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.631,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.285],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[269.179,83.362],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 319","np":4,"cix":2,"ix":319,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.285],[0.284,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.285],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[265.044,81.497],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 320","np":4,"cix":2,"ix":320,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.286],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.284],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.211],[-0.158,-2.577],[-2.41,2.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[260.909,79.631],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 321","np":4,"cix":2,"ix":321,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.284,-0.634],[-0.631,-0.285],[0,0],[0,0]],"v":[[-0.125,3.495],[2.126,-1.546],[1.496,-3.21],[-0.159,-2.577],[-2.41,2.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[256.775,77.766],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 322","np":4,"cix":2,"ix":322,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.285],[0,0],[0,0]],"v":[[-0.125,3.495],[2.127,-1.546],[1.496,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[252.641,75.9],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 323","np":4,"cix":2,"ix":323,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[11.154,5.673],[-11.63,-4.608],[-11.155,-5.673],[11.63,4.608]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.779999976065,0.556999954523,0.39199999641,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[255.644,91.34],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 324","np":4,"cix":2,"ix":324,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.286],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.631,-0.284],[0,0],[0,0]],"v":[[-0.124,3.495],[2.126,-1.546],[1.496,-3.211],[-0.159,-2.577],[-2.409,2.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[265.284,92.086],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 325","np":4,"cix":2,"ix":325,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.286],[0.283,-0.635],[0,0]],"o":[[0,0],[0.284,-0.634],[-0.631,-0.284],[0,0],[0,0]],"v":[[-0.125,3.495],[2.126,-1.546],[1.496,-3.211],[-0.159,-2.577],[-2.41,2.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[261.149,90.22],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 326","np":4,"cix":2,"ix":326,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.632,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.284,-0.634],[-0.631,-0.285],[0,0],[0,0]],"v":[[-0.125,3.495],[2.126,-1.546],[1.496,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[257.015,88.354],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 327","np":4,"cix":2,"ix":327,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.631,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.632,-0.285],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[252.88,86.488],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 328","np":4,"cix":2,"ix":328,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.631,0.285],[0.283,-0.635],[0,0]],"o":[[0,0],[0.283,-0.634],[-0.632,-0.285],[0,0],[0,0]],"v":[[-0.124,3.495],[2.127,-1.546],[1.497,-3.21],[-0.159,-2.577],[-2.41,2.464]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741000007181,0.505999995213,0.33300000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[248.745,84.623],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 329","np":4,"cix":2,"ix":329,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.677,0.305],[0.305,-0.681],[0,0]],"o":[[0,0],[0.304,-0.681],[-0.677,-0.306],[0,0],[0,0]],"v":[[-0.133,3.75],[2.282,-1.658],[1.606,-3.444],[-0.171,-2.765],[-2.586,2.643]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.689999988032,0.470999983245,0.310000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[262.242,103.539],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 330","np":4,"cix":2,"ix":330,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.678,0.306],[0.304,-0.68],[0,0]],"o":[[0,0],[0.305,-0.681],[-0.677,-0.306],[0,0],[0,0]],"v":[[-0.134,3.75],[2.281,-1.658],[1.605,-3.444],[-0.171,-2.765],[-2.586,2.644]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.689999988032,0.470999983245,0.310000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[257.201,101.265],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 331","np":4,"cix":2,"ix":331,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.678,0.306],[0.304,-0.68],[0,0]],"o":[[0,0],[0.304,-0.68],[-0.677,-0.306],[0,0],[0,0]],"v":[[-0.133,3.75],[2.282,-1.658],[1.606,-3.444],[-0.17,-2.765],[-2.585,2.644]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.689999988032,0.470999983245,0.310000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[252.16,98.99],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 332","np":4,"cix":2,"ix":332,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.677,0.305],[0.305,-0.681],[0,0]],"o":[[0,0],[0.304,-0.681],[-0.677,-0.306],[0,0],[0,0]],"v":[[-0.133,3.75],[2.282,-1.658],[1.606,-3.444],[-0.171,-2.765],[-2.586,2.643]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.689999988032,0.470999983245,0.310000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[247.118,96.715],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 333","np":4,"cix":2,"ix":333,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.677,0.306],[0.305,-0.68],[0,0]],"o":[[0,0],[0.304,-0.681],[-0.677,-0.306],[0,0],[0,0]],"v":[[-0.133,3.75],[2.282,-1.658],[1.606,-3.444],[-0.171,-2.765],[-2.586,2.644]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.689999988032,0.470999983245,0.310000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[242.077,94.44],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 334","np":4,"cix":2,"ix":334,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.927,-0.418],[0.156,-0.961],[0,0],[0,0],[-0.926,-0.418],[0.156,-0.962],[0,0],[0,0],[-0.927,-0.418],[-0.031,-0.015],[-0.031,-0.015],[0.156,-0.962],[0,0],[0,0],[-0.927,-0.418],[0.157,-0.962],[0,0],[0,0],[-0.927,-0.418],[0.156,-0.963],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.612,-0.757],[0.927,0.419],[0,0],[0,0],[0.611,-0.757],[0.927,0.418],[0,0],[0,0],[0.611,-0.757],[0.031,0.014],[0.032,0.013],[0.927,0.418],[0,0],[0,0],[0.611,-0.758],[0.926,0.418],[0,0],[0,0],[0.612,-0.756],[0.927,0.418],[0,0],[0,0],[0,0]],"v":[[8.541,2.335],[3.223,-0.064],[0.564,-1.264],[-2.094,-2.463],[-7.411,-4.863],[-12.729,-7.262],[-13.857,-4.734],[-13.222,-4.447],[-10.623,-5.07],[-9.358,-2.705],[-8.54,-2.335],[-7.904,-2.048],[-5.306,-2.67],[-4.041,-0.305],[-3.223,0.064],[-2.587,0.351],[0.012,-0.271],[0.1,-0.222],[0.195,-0.188],[1.459,2.177],[2.094,2.464],[2.913,2.834],[5.512,2.211],[6.775,4.576],[7.411,4.863],[8.23,5.232],[10.829,4.61],[12.093,6.976],[12.729,7.262],[13.857,4.734]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.689999988032,0.470999983245,0.310000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[254.841,93.137],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 335","np":4,"cix":2,"ix":335,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.589,-0.266],[0.1,-0.611],[0,0],[0,0],[-0.589,-0.266],[0.1,-0.612],[0,0],[0,0],[-0.589,-0.265],[-0.02,-0.01],[-0.02,-0.009],[0.1,-0.611],[0,0],[0,0],[-0.59,-0.266],[0.1,-0.611],[0,0],[0,0],[-0.589,-0.266],[0.099,-0.612],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.389,-0.48],[0.589,0.266],[0,0],[0,0],[0.389,-0.482],[0.589,0.266],[0,0],[0,0],[0.388,-0.481],[0.021,0.009],[0.019,0.007],[0.589,0.266],[0,0],[0,0],[0.389,-0.481],[0.589,0.266],[0,0],[0,0],[0.388,-0.482],[0.589,0.266],[0,0],[0,0],[0,0]],"v":[[5.429,1.484],[2.049,-0.041],[0.36,-0.804],[-1.331,-1.566],[-4.711,-3.092],[-8.091,-4.617],[-8.809,-3.01],[-8.404,-2.827],[-6.753,-3.222],[-5.949,-1.719],[-5.428,-1.485],[-5.024,-1.301],[-3.373,-1.697],[-2.569,-0.193],[-2.049,0.041],[-1.645,0.223],[0.007,-0.173],[0.064,-0.141],[0.124,-0.119],[0.927,1.383],[1.331,1.566],[1.852,1.8],[3.504,1.406],[4.307,2.908],[4.711,3.092],[5.232,3.326],[6.884,2.93],[7.688,4.434],[8.092,4.617],[8.809,3.01]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.689999988032,0.470999983245,0.310000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[287.01,21.102],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 336","np":4,"cix":2,"ix":336,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[10.876,5.852],[-11.578,-4.28],[-10.876,-5.852],[11.578,4.28]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.689999988032,0.470999983245,0.310000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[282.79,30.551],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 337","np":4,"cix":2,"ix":337,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.789,35.576],[-24.593,25.739],[2.789,-35.576],[24.593,-25.738]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.830999995213,0.651000019148,0.481999984442,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[268.816,61.843],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 338","np":4,"cix":2,"ix":338,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[10.659,10.784],[-15.1,-0.839],[-10.658,-10.784],[15.099,0.838]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.830999995213,0.651000019148,0.481999984442,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[253.02,97.214],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 339","np":4,"cix":2,"ix":339,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[5.339,9.721],[-10.774,2.452],[-5.338,-9.721],[10.775,-2.451]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.830999995213,0.651000019148,0.481999984442,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[284.613,26.47],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 340","np":4,"cix":2,"ix":340,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.14,14.106],[0,0],[0.352,-1.079],[2.671,-17.61],[-0.014,-1.135],[0,0]],"o":[[2.14,-14.106],[0,0],[-0.351,1.078],[-2.671,17.611],[0.017,1.135],[0,0]],"v":[[-0.242,-0.126],[5.604,-33.1],[4.004,-31.835],[-1.159,-0.267],[-5.59,31.414],[-4.437,33.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.969000004787,0.216000007181,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[361.935,234.045],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 341","np":4,"cix":2,"ix":341,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-4.213,2.202],[-3.368,-3.364],[4.213,-2.202],[3.369,3.364]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.380000005984,0.216000007181,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[366.562,234.665],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 342","np":4,"cix":2,"ix":342,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.008,6.288],[-0.053,-6.604],[2.007,-6.288],[0.052,6.604]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.380000005984,0.216000007181,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[370.166,235.216],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 343","np":4,"cix":2,"ix":343,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.738,31.241],[0,0],[0.747,-1.137],[3.297,-21.738],[-1.122,-3.907],[0,0]],"o":[[4.738,-31.241],[0,0],[-2.23,3.393],[-3.296,21.737],[0.376,1.31],[0,0]],"v":[[-2.773,-0.646],[8.13,-40.957],[5.202,-39.961],[-4.833,-0.961],[-6.816,39.271],[-4.315,41.098]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.564999988032,0.670999983245,0.62400004069,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[376.684,236.437],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 344","np":4,"cix":2,"ix":344,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-5.124,12.31],[0.689,-0.76],[2.484,-16.374],[-0.434,-0.933],[0,0]],"o":[[0,0],[0,0],[-0.691,0.762],[-2.483,16.373],[0.434,0.932],[-1.241,-13.285]],"v":[[-1.989,-0.544],[7.506,-39.145],[4.405,-38.273],[-4.423,-0.917],[-7.071,37.385],[-4.369,39.146]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.380000005984,0.216000007181,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[374.776,236.163],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 345","np":4,"cix":2,"ix":345,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-4.76,12.173],[0.623,-0.675],[2.041,-13.457],[-0.393,-0.831],[0,0]],"o":[[0,0],[0,0],[-0.622,0.676],[-2.041,13.456],[0.395,0.831],[-0.935,-13.046]],"v":[[-1.123,-0.437],[6.991,-34.723],[3.536,-33.905],[-4.173,-0.904],[-6.598,32.907],[-3.542,34.723]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.969000004787,0.216000007181,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[372.092,235.776],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 346","np":4,"cix":2,"ix":346,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-4.584,11.015],[0.613,-0.605],[1.854,-12.221],[-0.404,-0.761],[0,0]],"o":[[0,0],[0,0],[-0.611,0.606],[-1.853,12.221],[0.406,0.761],[-1.109,-11.889]],"v":[[-0.69,-0.419],[6.94,-31.518],[2.667,-30.949],[-3.741,-0.886],[-6.536,29.73],[-2.627,31.554]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.830999995213,0.172999991623,0.176000004189,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[369.039,235.357],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 347","np":4,"cix":2,"ix":347,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.2,0.03],[0.012,-0.075],[0,0],[-0.201,-0.03],[-0.011,0.075],[0,0]],"o":[[-0.201,-0.031],[0,0],[-0.011,0.075],[0.201,0.031],[0,0],[0.011,-0.075]],"v":[[0.281,-1.853],[-0.104,-1.772],[-0.624,1.661],[-0.281,1.853],[0.103,1.772],[0.624,-1.661]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.380000005984,0.216000007181,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[349.386,251.729],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 348","np":4,"cix":2,"ix":348,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.243,0.038],[0.024,-0.159],[0,0],[-0.243,-0.038],[-0.024,0.159],[0,0]],"o":[[-0.243,-0.037],[0,0],[-0.025,0.159],[0.243,0.037],[0,0],[0.025,-0.159]],"v":[[0.589,-3.885],[0.106,-3.664],[-0.985,3.529],[-0.589,3.885],[-0.105,3.664],[0.985,-3.53]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.380000005984,0.216000007181,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[348.809,251.641],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 349","np":4,"cix":2,"ix":349,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.001,0.153],[0.764,0.117],[0,0],[0,0],[0,0],[-0.762,-0.118],[-1.002,-0.154],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.002,-0.153],[-0.763,-0.117],[0,0],[0,0],[0,0],[0.764,0.117],[1.002,0.154],[0,0]],"v":[[14.155,-0.799],[15.576,-0.581],[15.138,2.296],[14.702,5.174],[13.281,4.956],[12.681,4.079],[-8.835,0.781],[-11.091,1.173],[-15.576,0.484],[-15.147,-2.344],[-14.717,-5.174],[-10.233,-4.486],[-8.195,-3.439],[13.323,-0.141]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.969000004787,0.216000007181,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[333.302,249.288],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 350","np":4,"cix":2,"ix":350,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.757,-2.967],[-1.602,2.605],[0.757,2.967],[1.601,-2.605]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.969000004787,0.216000007181,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[362.83,250.742],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 351","np":4,"cix":2,"ix":351,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-21.609,-4.707],[-22.023,-1.98],[21.609,4.706],[22.023,1.98]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.830999995213,0.172999991623,0.176000004189,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[340.424,247.309],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 352","np":4,"cix":2,"ix":352,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.2,0.031],[-0.011,0.075],[0,0],[-0.201,-0.031],[0.012,-0.075],[0,0]],"o":[[-0.201,-0.03],[0,0],[0.011,-0.075],[0.201,0.03],[0,0],[-0.012,0.075]],"v":[[-0.281,1.853],[-0.624,1.661],[-0.103,-1.772],[0.281,-1.853],[0.623,-1.661],[0.103,1.772]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.380000005984,0.216000007181,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[355.225,213.229],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 353","np":4,"cix":2,"ix":353,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.243,0.037],[-0.024,0.159],[0,0],[-0.243,-0.037],[0.025,-0.159],[0,0]],"o":[[-0.243,-0.037],[0,0],[0.024,-0.159],[0.243,0.038],[0,0],[-0.024,0.159]],"v":[[-0.59,3.885],[-0.986,3.53],[0.105,-3.664],[0.589,-3.885],[0.985,-3.529],[-0.106,3.664]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.380000005984,0.216000007181,0.156999999402,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[354.65,213.141],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 354","np":4,"cix":2,"ix":354,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.002,0.155],[0.764,0.117],[0,0],[0,0],[0,0],[-0.764,-0.117],[-1.002,-0.153],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.002,-0.153],[-0.763,-0.118],[0,0],[0,0],[0,0],[0.764,0.116],[1.002,0.154],[0,0]],"v":[[13.281,4.956],[14.702,5.174],[15.138,2.297],[15.575,-0.58],[14.154,-0.798],[13.322,-0.141],[-8.195,-3.439],[-10.233,-4.486],[-14.717,-5.174],[-15.147,-2.345],[-15.575,0.484],[-11.091,1.173],[-8.835,0.782],[12.682,4.079]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.969000004787,0.216000007181,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[339.142,210.788],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 355","np":4,"cix":2,"ix":355,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.602,2.605],[-0.757,-2.966],[1.602,-2.605],[0.756,2.966]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.969000004787,0.216000007181,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[367.766,218.199],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 356","np":4,"cix":2,"ix":356,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-22.023,-1.98],[-21.61,-4.707],[22.023,1.981],[21.61,4.707]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.830999995213,0.172999991623,0.176000004189,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[345.36,214.765],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 357","np":4,"cix":2,"ix":357,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.944,31.167],[6.43,-30.633],[2.943,-31.167],[-6.43,30.633]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.902000038297,0.2,0.204000001795,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[359.584,233.595],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 358","np":4,"cix":2,"ix":358,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.163,0.311],[-1.017,-0.645],[1.164,-0.311],[1.018,0.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.788000009574,0.626999978458,0.313999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[362.181,235.895],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 359","np":4,"cix":2,"ix":359,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.163,0.311],[-1.018,-0.645],[1.163,-0.311],[1.019,0.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.788000009574,0.626999978458,0.313999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[362.745,232.178],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 360","np":4,"cix":2,"ix":360,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.146,-0.117],[-0.092,-0.117],[0,0],[-0.145,0.116],[0.093,0.117],[0,0]],"o":[[-0.146,0.117],[0,0],[0.093,0.117],[0.147,-0.117],[0,0],[-0.093,-0.117]],"v":[[-6.637,-8.401],[-6.734,-7.977],[6.204,8.401],[6.637,8.402],[6.733,7.978],[-6.204,-8.4]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[283.964,119.033],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 361","np":4,"cix":2,"ix":361,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.073,-0.058],[0.047,0.058],[0,0],[-0.073,0.059],[-0.046,-0.058],[0,0]],"o":[[-0.073,0.059],[0,0],[-0.046,-0.059],[0.073,-0.059],[0,0],[0.047,0.059]],"v":[[5.209,6.593],[4.992,6.593],[-5.258,-6.382],[-5.209,-6.594],[-4.993,-6.594],[5.257,6.382]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[291.843,124.362],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 362","np":4,"cix":2,"ix":362,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.073,0.059],[0.046,0.059],[0,0],[0.074,-0.058],[-0.047,-0.058],[0,0]],"o":[[0.073,-0.058],[0,0],[-0.047,-0.059],[-0.073,0.059],[0,0],[0.047,0.058]],"v":[[3.613,4.572],[3.661,4.361],[-3.396,-4.573],[-3.613,-4.574],[-3.66,-4.362],[3.396,4.572]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[288.573,114.486],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 363","np":4,"cix":2,"ix":363,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.11,0.087],[0.07,0.088],[0,0],[0.11,-0.088],[-0.07,-0.087],[0,0]],"o":[[0.109,-0.087],[0,0],[-0.069,-0.088],[-0.109,0.087],[0,0],[0.069,0.088]],"v":[[5.251,6.647],[5.323,6.329],[-4.927,-6.645],[-5.252,-6.646],[-5.324,-6.329],[4.926,6.646]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[293.466,113.44],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 364","np":4,"cix":2,"ix":364,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.109,0.087],[-0.069,-0.088],[0,0],[0.11,-0.087],[0.07,0.088],[0,0]],"o":[[0.109,-0.087],[0,0],[0.07,0.087],[-0.11,0.088],[0,0],[-0.07,-0.088]],"v":[[-2.1,-2.659],[-1.776,-2.658],[2.173,2.341],[2.101,2.658],[1.776,2.657],[-2.172,-2.341]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[302.492,119.675],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 365","np":4,"cix":2,"ix":365,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.109,-0.087],[0.07,0.088],[0,0],[-0.11,0.088],[-0.069,-0.088],[0,0]],"o":[[-0.11,0.088],[0,0],[-0.069,-0.089],[0.109,-0.087],[0,0],[0.07,0.089]],"v":[[5.419,6.859],[5.094,6.858],[-5.492,-6.541],[-5.419,-6.86],[-5.095,-6.859],[5.491,6.541]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[300.296,111.976],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 366","np":4,"cix":2,"ix":366,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.109,-0.087],[-0.07,-0.088],[0,0],[-0.11,0.087],[0.069,0.088],[0,0]],"o":[[-0.109,0.087],[0,0],[0.07,0.088],[0.109,-0.087],[0,0],[-0.069,-0.088]],"v":[[-3.654,-4.626],[-3.727,-4.308],[3.331,4.625],[3.656,4.626],[3.728,4.308],[-3.331,-4.625]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[306.496,113.269],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 367","np":4,"cix":2,"ix":367,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.073,-0.059],[0.047,0.059],[0,0],[-0.073,0.058],[-0.046,-0.059],[0,0]],"o":[[-0.073,0.058],[0,0],[-0.046,-0.059],[0.073,-0.058],[0,0],[0.047,0.059]],"v":[[2.899,3.669],[2.682,3.668],[-2.947,-3.457],[-2.898,-3.669],[-2.682,-3.668],[2.947,3.457]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[306.605,107.805],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 368","np":4,"cix":2,"ix":368,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.109,-0.087],[0.069,0.088],[0,0],[-0.109,0.087],[-0.069,-0.089],[0,0]],"o":[[-0.109,0.087],[0,0],[-0.07,-0.088],[0.11,-0.088],[0,0],[0.07,0.088]],"v":[[2.94,3.722],[2.616,3.722],[-3.013,-3.403],[-2.941,-3.721],[-2.617,-3.721],[3.013,3.404]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[312.688,107.718],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 369","np":4,"cix":2,"ix":369,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[16.782,-28.377],[-16.781,10.519],[-2.672,28.377]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[309.207,129.334],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 370","np":4,"cix":2,"ix":370,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[30.833,-28.377],[-30.833,-25.055],[11.379,28.377]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.957000014361,0.713999968884,0.365000017952,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[295.155,129.334],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 371","np":4,"cix":2,"ix":371,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.12,-0.096],[-0.076,-0.097],[0,0],[-0.12,0.096],[0.076,0.097],[0,0]],"o":[[-0.12,0.095],[0,0],[0.076,0.096],[0.119,-0.095],[0,0],[-0.076,-0.096]],"v":[[-5.456,-6.907],[-5.534,-6.559],[5.103,6.905],[5.457,6.906],[5.535,6.559],[-5.103,-6.906]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[304.841,147.293],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 372","np":4,"cix":2,"ix":372,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.061,-0.048],[0.038,0.048],[0,0],[-0.06,0.048],[-0.038,-0.049],[0,0]],"o":[[-0.06,0.047],[0,0],[-0.038,-0.048],[0.06,-0.048],[0,0],[0.038,0.048]],"v":[[4.282,5.421],[4.105,5.42],[-4.322,-5.246],[-4.282,-5.42],[-4.105,-5.419],[4.322,5.247]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[311.311,151.68],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 373","np":4,"cix":2,"ix":373,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.06,0.048],[0.038,0.049],[0,0],[0.059,-0.048],[-0.038,-0.048],[0,0]],"o":[[0.061,-0.048],[0,0],[-0.038,-0.048],[-0.06,0.048],[0,0],[0.038,0.048]],"v":[[2.97,3.759],[3.01,3.585],[-2.792,-3.759],[-2.969,-3.76],[-3.009,-3.586],[2.793,3.758]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[308.613,143.568],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 374","np":4,"cix":2,"ix":374,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.09,0.072],[0.057,0.073],[0,0],[0.09,-0.072],[-0.058,-0.073],[0,0]],"o":[[0.09,-0.071],[0,0],[-0.058,-0.073],[-0.09,0.071],[0,0],[0.058,0.072]],"v":[[4.317,5.464],[4.376,5.203],[-4.05,-5.463],[-4.317,-5.464],[-4.375,-5.203],[4.05,5.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[312.624,142.718],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 375","np":4,"cix":2,"ix":375,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.09,0.072],[-0.057,-0.072],[0,0],[0.09,-0.072],[0.056,0.072],[0,0]],"o":[[0.09,-0.072],[0,0],[0.056,0.073],[-0.09,0.071],[0,0],[-0.056,-0.073]],"v":[[-1.726,-2.186],[-1.46,-2.184],[1.786,1.924],[1.727,2.187],[1.462,2.185],[-1.786,-1.924]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[320.036,147.849],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 376","np":4,"cix":2,"ix":376,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.09,-0.071],[0.058,0.072],[0,0],[-0.09,0.072],[-0.056,-0.073],[0,0]],"o":[[-0.09,0.072],[0,0],[-0.056,-0.072],[0.09,-0.072],[0,0],[0.056,0.073]],"v":[[4.454,5.639],[4.188,5.638],[-4.515,-5.378],[-4.455,-5.639],[-4.19,-5.637],[4.514,5.378]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[318.222,141.527],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 377","np":4,"cix":2,"ix":377,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.09,-0.071],[-0.057,-0.073],[0,0],[-0.09,0.072],[0.057,0.073],[0,0]],"o":[[-0.09,0.072],[0,0],[0.057,0.072],[0.09,-0.071],[0,0],[-0.058,-0.072]],"v":[[-3.004,-3.804],[-3.064,-3.542],[2.738,3.801],[3.004,3.802],[3.064,3.541],[-2.737,-3.803]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[323.309,142.599],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 378","np":4,"cix":2,"ix":378,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.06,-0.048],[0.038,0.047],[0,0],[-0.06,0.048],[-0.038,-0.049],[0,0]],"o":[[-0.061,0.048],[0,0],[-0.039,-0.049],[0.06,-0.048],[0,0],[0.038,0.049]],"v":[[2.384,3.016],[2.206,3.016],[-2.422,-2.842],[-2.383,-3.016],[-2.206,-3.015],[2.422,2.842]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[323.389,138.115],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 379","np":4,"cix":2,"ix":379,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.09,-0.072],[0.058,0.072],[0,0],[-0.09,0.072],[-0.057,-0.072],[0,0]],"o":[[-0.089,0.072],[0,0],[-0.056,-0.073],[0.09,-0.071],[0,0],[0.056,0.073]],"v":[[2.417,3.059],[2.151,3.059],[-2.477,-2.799],[-2.417,-3.061],[-2.151,-3.06],[2.477,2.798]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[328.377,138.054],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 380","np":4,"cix":2,"ix":380,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[13.729,-23.276],[-13.729,8.593],[-2.13,23.275]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.838999968884,0.616000007181,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[325.543,155.801],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 381","np":4,"cix":2,"ix":381,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[25.281,-23.276],[-25.281,-20.651],[9.422,23.275]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.957000014361,0.713999968884,0.365000017952,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[313.991,155.801],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 382","np":4,"cix":2,"ix":382,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.216,0.812],[0.807,-0.216],[0,0]],"o":[[0,0],[0.807,-0.217],[-0.217,-0.812],[0,0],[0,0]],"v":[[-0.587,1.668],[0.085,1.488],[1.155,-0.375],[-0.699,-1.452],[-1.371,-1.271]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.435000011968,0.603999956916,0.620000023935,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[403.621,156.959],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 383","np":4,"cix":2,"ix":383,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.347,6.395],[-3.484,-5.365],[0.347,-6.394],[3.484,5.366]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.365000017952,0.552999997606,0.569000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[351.999,170.762],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 384","np":4,"cix":2,"ix":384,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.465,2.385],[-1.59,-1.833],[0.465,-2.385],[1.59,1.834]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.325,0.493999974868,0.510000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[401.614,157.434],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 385","np":4,"cix":2,"ix":385,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0.44,5.775],[-2.495,-5.223],[-0.439,-5.775],[2.495,5.223]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.325,0.493999974868,0.510000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[354.942,169.971],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 386","np":4,"cix":2,"ix":386,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.713,10.552],[-3.768,-10],[-1.714,-10.552],[3.768,10]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.325,0.493999974868,0.510000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[338.772,174.315],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 387","np":4,"cix":2,"ix":387,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-53.848,15.365],[0,0],[0,0],[0,0],[0,0],[0,0],[8.542,-5.382],[0,0]],"o":[[0,0],[0,0],[-54.296,13.685],[0,0],[10.078,0.379],[0,0],[0,0],[0,0]],"v":[[32.053,-10.041],[31.604,-11.721],[31.156,-13.4],[-32.052,-3.88],[-30.35,1.063],[2.001,-3.77],[-28.43,8.264],[-27.443,13.4]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.435000011968,0.603999956916,0.620000023935,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[368.983,169.431],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 388","np":4,"cix":2,"ix":388,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.087,0.328],[0,0],[0.326,-0.088],[0,0]],"o":[[0,0],[0.327,-0.087],[0,0],[-0.087,-0.328],[0,0],[0,0]],"v":[[0.283,3.88],[1.179,3.639],[1.612,2.886],[-0.054,-3.357],[-0.803,-3.792],[-1.699,-3.552]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.325,0.493999974868,0.510000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[325.957,191.789],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 389","np":4,"cix":2,"ix":389,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.087,0.328],[0,0],[0.326,-0.088],[0,0]],"o":[[0,0],[0.327,-0.087],[0,0],[-0.087,-0.328],[0,0],[0,0]],"v":[[0.283,3.88],[1.179,3.639],[1.612,2.886],[-0.054,-3.357],[-0.803,-3.792],[-1.699,-3.552]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.325,0.493999974868,0.510000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[318.986,165.65],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 390","np":4,"cix":2,"ix":390,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[8.104,2.135],[0,0],[-2.291,-8.591],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[2.291,8.59],[0,0],[5.957,-5.913]],"v":[[10.713,6.111],[8.044,-3.893],[5.376,-13.898],[-10.713,-15.985],[-9.118,-10.004],[2.42,-2.382],[-3.781,10.005],[-2.185,15.986]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.435000011968,0.603999956916,0.620000023935,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[329.7,178.485],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 391","np":4,"cix":2,"ix":391,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.037,0.137],[-0.137,0.037],[0,0],[-0.037,-0.137],[0.135,-0.036]],"o":[[-0.136,0.037],[-0.037,-0.136],[0,0],[0.135,-0.037],[0.036,0.137],[0,0]],"v":[[-4.193,1.391],[-4.505,1.21],[-4.325,0.896],[4.194,-1.391],[4.506,-1.21],[4.326,-0.897]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.325,0.493999974868,0.510000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[405.537,156.38],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 392","np":4,"cix":2,"ix":392,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0.716,0.496],[-0.456,0.745],[-0.715,-0.496],[0.457,-0.745]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[194.855,50.699],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 393","np":4,"cix":2,"ix":393,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0.715,0.496],[-0.457,0.745],[-0.716,-0.496],[0.456,-0.745]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[192.387,51.221],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 394","np":4,"cix":2,"ix":394,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0.715,0.496],[-0.457,0.745],[-0.716,-0.496],[0.456,-0.745]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[189.919,51.742],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 395","np":4,"cix":2,"ix":395,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0.715,0.496],[-0.457,0.745],[-0.716,-0.497],[0.456,-0.745]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[187.451,52.263],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 396","np":4,"cix":2,"ix":396,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0.715,0.496],[-0.457,0.745],[-0.716,-0.496],[0.456,-0.745]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[184.982,52.784],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 397","np":4,"cix":2,"ix":397,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0.716,0.496],[-0.456,0.745],[-0.716,-0.497],[0.457,-0.745]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[182.514,53.306],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 398","np":4,"cix":2,"ix":398,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0.716,0.496],[-0.456,0.745],[-0.715,-0.496],[0.457,-0.745]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[180.046,53.827],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 399","np":4,"cix":2,"ix":399,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.268,-1.287],[-8.084,2.166],[-8.268,1.287],[8.084,-2.166]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[187.85,54.178],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 400","np":4,"cix":2,"ix":400,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.261,-0.393],[-7.721,2.982],[-8.261,0.393],[7.72,-2.982]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.630999995213,0.528999956916,0.455000005984,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[187.851,54.178],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 401","np":4,"cix":2,"ix":401,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[3.869,3.23],[-2.248,4.523],[-3.868,-3.231],[2.248,-4.523]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.322000002394,0.26699999641,0.231000010173,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[188.814,58.788],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 402","np":4,"cix":2,"ix":402,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[7.581,-0.292],[-7.057,2.799],[-7.581,0.291],[7.057,-2.799]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.722000002394,0.62400004069,0.54900004069,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[188.847,58.946],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 403","np":4,"cix":2,"ix":403,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.272,3.015],[-6.366,6.106],[-8.272,-3.015],[6.365,-6.106]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[188.671,58.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 404","np":4,"cix":2,"ix":404,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-6.038,0.608],[-6.04,1.838],[6.039,-0.712],[5.546,-1.838]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[192.11,73.996],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 405","np":4,"cix":2,"ix":405,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-7.317,0.878],[-7.318,2.108],[7.318,-0.982],[6.825,-2.108]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[193.382,80.083],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 406","np":4,"cix":2,"ix":406,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-6.678,0.743],[-6.679,1.973],[6.679,-0.847],[6.185,-1.973]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[192.746,77.04],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 407","np":4,"cix":2,"ix":407,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-4.12,0.203],[-4.121,1.433],[4.121,-0.307],[3.628,-1.433]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[190.202,64.866],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 408","np":4,"cix":2,"ix":408,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-5.399,0.473],[-5.4,1.703],[5.4,-0.577],[4.906,-1.703]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[191.474,70.953],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 409","np":4,"cix":2,"ix":409,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-4.759,0.338],[-4.76,1.568],[4.76,-0.442],[4.266,-1.568]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[190.838,67.91],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 410","np":4,"cix":2,"ix":410,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-7.957,1.013],[-7.958,2.243],[7.958,-1.117],[7.464,-2.243]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[194.018,83.127],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 411","np":4,"cix":2,"ix":411,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[12.434,-2.063],[11.94,-3.188],[-12.434,1.959],[-12.435,3.188]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[198.47,104.43],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 412","np":4,"cix":2,"ix":412,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-11.794,1.823],[-11.795,3.053],[11.794,-1.927],[11.3,-3.053]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[197.835,101.387],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 413","np":4,"cix":2,"ix":413,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-11.154,1.688],[-11.155,2.919],[11.155,-1.792],[10.661,-2.919]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[197.198,98.343],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 414","np":4,"cix":2,"ix":414,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-8.596,1.148],[-8.597,2.378],[8.597,-1.252],[8.104,-2.378]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[194.654,86.17],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 415","np":4,"cix":2,"ix":415,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-10.515,1.553],[-10.516,2.783],[10.516,-1.658],[10.022,-2.783]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[196.562,95.3],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 416","np":4,"cix":2,"ix":416,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-9.236,1.283],[-9.237,2.513],[9.237,-1.388],[8.743,-2.513]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[195.291,89.214],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 417","np":4,"cix":2,"ix":417,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-9.875,1.418],[-9.876,2.648],[9.876,-1.522],[9.383,-2.648]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[195.926,92.257],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 418","np":4,"cix":2,"ix":418,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-5.638,-23.681],[-9.178,-22.932],[-12.719,-22.185],[-12.768,23.681],[0,20.984],[12.768,18.289]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.630999995213,0.528999956916,0.455000005984,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[198.802,85.596],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 419","np":4,"cix":2,"ix":419,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-4.355,-24.304],[-9.178,-23.286],[-14.001,-22.267],[-17.392,24.304],[0,20.631],[17.393,16.959]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.722000002394,0.62400004069,0.54900004069,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[198.802,85.949],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 420","np":4,"cix":2,"ix":420,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[14.949,-1.88],[-14.438,4.326],[-14.949,1.88],[14.438,-4.326]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.630999995213,0.528999956916,0.455000005984,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[189.88,63.886],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 421","np":4,"cix":2,"ix":421,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[15.349,0.034],[-14.038,6.24],[-15.349,-0.034],[14.038,-6.24]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[190.279,65.801],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 422","np":4,"cix":2,"ix":422,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[19.908,-2.927],[-19.396,5.373],[-19.908,2.927],[19.396,-5.373]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.630999995213,0.528999956916,0.455000005984,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[191.191,70.16],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 423","np":4,"cix":2,"ix":423,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[20.266,-1.215],[-19.038,7.085],[-20.266,1.215],[19.038,-7.085]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[191.633,72.276],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 424","np":4,"cix":2,"ix":424,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[23.637,-3.715],[-23.127,6.16],[-23.637,3.715],[23.126,-6.16]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.630999995213,0.528999956916,0.455000005984,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[192.502,76.434],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 425","np":4,"cix":2,"ix":425,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[23.995,-2.003],[-22.768,7.872],[-23.995,2.003],[22.768,-7.872]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[192.944,78.55],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 426","np":4,"cix":2,"ix":426,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[27.52,-4.534],[-27.009,6.98],[-27.52,4.535],[27.008,-6.98]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.630999995213,0.528999956916,0.455000005984,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[193.813,82.708],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 427","np":4,"cix":2,"ix":427,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[27.878,-2.823],[-26.65,8.693],[-27.878,2.823],[26.65,-8.693]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[194.255,84.824],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 428","np":4,"cix":2,"ix":428,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[31.832,-5.445],[-31.321,7.891],[-31.832,5.445],[31.321,-7.891]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.630999995213,0.528999956916,0.455000005984,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[195.124,88.982],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 429","np":4,"cix":2,"ix":429,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[32.189,-3.733],[-30.963,9.603],[-32.189,3.733],[30.962,-9.603]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[195.566,91.098],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 430","np":4,"cix":2,"ix":430,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[35.752,-6.273],[-35.241,8.718],[-35.752,6.272],[35.24,-8.718]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.630999995213,0.528999956916,0.455000005984,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[196.436,95.256],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 431","np":4,"cix":2,"ix":431,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[36.109,-4.561],[-34.883,10.431],[-36.11,4.561],[34.882,-10.431]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[196.878,97.372],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 432","np":4,"cix":2,"ix":432,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[40.16,-7.204],[-39.65,9.65],[-40.161,7.203],[39.648,-9.65]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.630999995213,0.528999956916,0.455000005984,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[197.747,101.53],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 433","np":4,"cix":2,"ix":433,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[40.518,-5.492],[-39.292,11.362],[-40.519,5.491],[39.291,-11.362]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.411999990426,0.352999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[198.189,103.646],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 434","np":4,"cix":2,"ix":434,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.113,0.029],[-0.028,-0.114],[0,0],[0.114,-0.027],[0.027,0.114]],"o":[[-0.027,-0.114],[0.115,-0.027],[0,0],[0.028,0.114],[-0.114,0.028],[0,0]],"v":[[-0.977,-3.079],[-0.822,-3.339],[-0.564,-3.182],[0.975,3.079],[0.82,3.337],[0.563,3.182]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.569000004787,0.470999983245,0.317999985639,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[272.868,377.794],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 435","np":4,"cix":2,"ix":435,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.114,0.029],[-0.028,-0.114],[0,0],[0.113,-0.028],[0.028,0.114]],"o":[[-0.028,-0.114],[0.115,-0.028],[0,0],[0.028,0.115],[-0.114,0.028],[0,0]],"v":[[-0.976,-3.079],[-0.821,-3.338],[-0.563,-3.182],[0.976,3.079],[0.821,3.338],[0.563,3.182]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.569000004787,0.470999983245,0.317999985639,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[274.348,377.426],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 436","np":4,"cix":2,"ix":436,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.114,0.029],[-0.027,-0.114],[0,0],[0.113,-0.028],[0.028,0.114]],"o":[[-0.028,-0.114],[0.115,-0.028],[0,0],[0.027,0.114],[-0.114,0.028],[0,0]],"v":[[-0.975,-3.079],[-0.82,-3.338],[-0.564,-3.182],[0.977,3.08],[0.822,3.338],[0.563,3.183]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.569000004787,0.470999983245,0.317999985639,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[275.828,377.058],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 437","np":4,"cix":2,"ix":437,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.114,0.029],[-0.028,-0.114],[0,0],[0.114,-0.028],[0.028,0.114]],"o":[[-0.028,-0.115],[0.114,-0.028],[0,0],[0.028,0.114],[-0.113,0.028],[0,0]],"v":[[-0.975,-3.079],[-0.82,-3.338],[-0.563,-3.182],[0.976,3.079],[0.821,3.338],[0.564,3.182]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.569000004787,0.470999983245,0.317999985639,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[277.308,376.691],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 438","np":4,"cix":2,"ix":438,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.114,0.029],[-0.028,-0.114],[0,0],[0.114,-0.028],[0.028,0.114]],"o":[[-0.028,-0.114],[0.114,-0.028],[0,0],[0.028,0.114],[-0.114,0.028],[0,0]],"v":[[-0.975,-3.079],[-0.82,-3.338],[-0.564,-3.182],[0.975,3.08],[0.82,3.338],[0.563,3.183]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.569000004787,0.470999983245,0.317999985639,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[278.789,376.323],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 439","np":4,"cix":2,"ix":439,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.113,0.029],[-0.028,-0.115],[0,0],[0.114,-0.028],[0.028,0.114]],"o":[[-0.028,-0.115],[0.115,-0.028],[0,0],[0.028,0.114],[-0.114,0.028],[0,0]],"v":[[-0.976,-3.079],[-0.821,-3.338],[-0.563,-3.182],[0.976,3.079],[0.821,3.338],[0.563,3.182]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.569000004787,0.470999983245,0.317999985639,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[280.269,375.955],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 440","np":4,"cix":2,"ix":440,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.084,0.343],[-0.34,0.084],[0,0],[-0.084,-0.343],[0.339,-0.084],[0,0]],"o":[[-0.085,-0.342],[0,0],[0.341,-0.084],[0.084,0.341],[0,0],[-0.34,0.084]],"v":[[-0.97,0.241],[-0.507,-0.531],[0.203,-0.707],[0.971,-0.241],[0.508,0.53],[-0.202,0.707]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.752999997606,0.62400004069,0.416000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[281.451,396.734],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 441","np":4,"cix":2,"ix":441,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-2.801,8.642],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[6.483,6.337]],"v":[[3.407,8.54],[3.849,8.43],[4.292,8.319],[5.288,-8.54],[0.001,-7.227],[-5.287,-5.913]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[277.615,388.357],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 442","np":4,"cix":2,"ix":442,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-2.655,4.555],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[4.46,2.788]],"v":[[-3.119,5.734],[1.911,4.486],[2.02,4.458],[7.05,3.21],[8.905,-5.734],[0.055,-3.536],[-0.055,-3.508],[-8.905,-1.31]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[273.524,368.015],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 443","np":4,"cix":2,"ix":443,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-8.516,1.53],[8.245,-2.633],[8.515,-1.53],[-8.245,2.634]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.811999990426,0.709999952129,0.552999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[273.388,363.942],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 444","np":4,"cix":2,"ix":444,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.149,0.037],[-0.037,-0.149],[0,0],[0.149,-0.037],[0.037,0.15]],"o":[[-0.037,-0.15],[0.15,-0.037],[0,0],[0.037,0.151],[-0.151,0.037],[0,0]],"v":[[-0.859,-2.327],[-0.656,-2.666],[-0.318,-2.462],[0.859,2.328],[0.656,2.667],[0.318,2.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.569000004787,0.470999983245,0.317999985639,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[265.898,361.511],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 445","np":4,"cix":2,"ix":445,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.149,0.037],[-0.037,-0.15],[0,0],[0.149,-0.037],[0.037,0.15]],"o":[[-0.036,-0.15],[0.15,-0.037],[0,0],[0.036,0.151],[-0.15,0.037],[0,0]],"v":[[-0.86,-2.328],[-0.656,-2.667],[-0.318,-2.463],[0.86,2.327],[0.656,2.666],[0.318,2.461]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.569000004787,0.470999983245,0.317999985639,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[267.522,361.108],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 446","np":4,"cix":2,"ix":446,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.149,0.037],[-0.037,-0.15],[0,0],[0.149,-0.037],[0.037,0.15]],"o":[[-0.037,-0.15],[0.151,-0.037],[0,0],[0.037,0.15],[-0.15,0.037],[0,0]],"v":[[-0.859,-2.327],[-0.657,-2.667],[-0.319,-2.462],[0.859,2.328],[0.655,2.667],[0.317,2.462]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.569000004787,0.470999983245,0.317999985639,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[269.147,360.704],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 447","np":4,"cix":2,"ix":447,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.149,0.037],[-0.036,-0.15],[0,0],[0.15,-0.037],[0.037,0.15]],"o":[[-0.037,-0.15],[0.15,-0.037],[0,0],[0.037,0.151],[-0.15,0.037],[0,0]],"v":[[-0.859,-2.327],[-0.655,-2.667],[-0.318,-2.462],[0.86,2.327],[0.656,2.667],[0.319,2.462]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.569000004787,0.470999983245,0.317999985639,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[270.771,360.301],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 448","np":4,"cix":2,"ix":448,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.149,0.037],[-0.037,-0.15],[0,0],[0.149,-0.037],[0.037,0.15]],"o":[[-0.037,-0.15],[0.15,-0.037],[0,0],[0.037,0.151],[-0.15,0.037],[0,0]],"v":[[-0.859,-2.327],[-0.655,-2.667],[-0.317,-2.462],[0.86,2.327],[0.657,2.667],[0.319,2.462]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.569000004787,0.470999983245,0.317999985639,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[272.395,359.898],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 449","np":4,"cix":2,"ix":449,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.149,0.037],[-0.037,-0.15],[0,0],[0.149,-0.037],[0.037,0.15]],"o":[[-0.037,-0.149],[0.15,-0.037],[0,0],[0.037,0.151],[-0.15,0.037],[0,0]],"v":[[-0.859,-2.328],[-0.656,-2.667],[-0.318,-2.462],[0.86,2.327],[0.656,2.667],[0.318,2.462]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.569000004787,0.470999983245,0.317999985639,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[274.02,359.494],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 450","np":4,"cix":2,"ix":450,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.15,0.037],[-0.037,-0.15],[0,0],[0.149,-0.037],[0.036,0.15]],"o":[[-0.037,-0.15],[0.15,-0.037],[0,0],[0.037,0.151],[-0.15,0.037],[0,0]],"v":[[-0.859,-2.327],[-0.655,-2.666],[-0.318,-2.461],[0.86,2.328],[0.656,2.667],[0.319,2.463]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.569000004787,0.470999983245,0.317999985639,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[275.644,359.091],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 451","np":4,"cix":2,"ix":451,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.149,0.037],[-0.036,-0.15],[0,0],[0.149,-0.037],[0.037,0.15]],"o":[[-0.037,-0.15],[0.15,-0.037],[0,0],[0.037,0.151],[-0.151,0.037],[0,0]],"v":[[-0.859,-2.328],[-0.656,-2.667],[-0.319,-2.463],[0.859,2.327],[0.656,2.666],[0.318,2.461]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.569000004787,0.470999983245,0.317999985639,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[277.268,358.687],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 452","np":4,"cix":2,"ix":452,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.149,0.037],[-0.037,-0.15],[0,0],[0.149,-0.037],[0.037,0.15]],"o":[[-0.036,-0.15],[0.15,-0.037],[0,0],[0.036,0.15],[-0.15,0.037],[0,0]],"v":[[-0.86,-2.327],[-0.656,-2.667],[-0.318,-2.462],[0.86,2.328],[0.656,2.667],[0.318,2.462]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.569000004787,0.470999983245,0.317999985639,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[278.892,358.284],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 453","np":4,"cix":2,"ix":453,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.06,-0.103],[0.102,-0.06],[0,0],[0.059,0.103],[-0.103,0.06]],"o":[[0.103,-0.06],[0.059,0.104],[0,0],[-0.103,0.06],[-0.06,-0.103],[0,0]],"v":[[0.706,-0.659],[0.999,-0.58],[0.921,-0.285],[-0.706,0.659],[-0.999,0.581],[-0.921,0.286]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[269.049,349.477],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 454","np":4,"cix":2,"ix":454,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.097,0.069],[-0.068,-0.098],[0,0],[0.097,-0.069],[0.067,0.098]],"o":[[-0.067,-0.098],[0.097,-0.068],[0,0],[0.067,0.098],[-0.098,0.068],[0,0]],"v":[[-0.715,-0.649],[-0.663,-0.95],[-0.363,-0.897],[0.716,0.649],[0.663,0.95],[0.363,0.897]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[270.401,349.776],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 455","np":4,"cix":2,"ix":455,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.041,0.026],[-0.026,0.041],[0,0],[-0.041,-0.024],[0.025,-0.042]],"o":[[-0.025,0.041],[-0.041,-0.024],[0,0],[0.026,-0.042],[0.041,0.025],[0,0]],"v":[[-0.226,0.547],[-0.346,0.576],[-0.375,0.456],[0.227,-0.548],[0.347,-0.578],[0.377,-0.457]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[268.029,351.99],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 456","np":4,"cix":2,"ix":456,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.042,0.026],[-0.026,0.041],[0,0],[-0.041,-0.025],[0.024,-0.042]],"o":[[-0.024,0.041],[-0.041,-0.025],[0,0],[0.026,-0.042],[0.042,0.025],[0,0]],"v":[[-0.227,0.548],[-0.347,0.577],[-0.376,0.457],[0.226,-0.547],[0.346,-0.577],[0.377,-0.456]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[271.593,346.055],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 457","np":4,"cix":2,"ix":457,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.025,0.042],[-0.041,-0.026],[0,0],[0.026,-0.042],[0.042,0.026]],"o":[[-0.042,-0.025],[0.025,-0.041],[0,0],[0.041,0.025],[-0.024,0.042],[0,0]],"v":[[-0.544,-0.227],[-0.574,-0.348],[-0.454,-0.377],[0.545,0.228],[0.574,0.349],[0.454,0.378]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[266.86,347.231],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 458","np":4,"cix":2,"ix":458,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.025,0.042],[-0.041,-0.026],[0,0],[0.026,-0.041],[0.042,0.025]],"o":[[-0.041,-0.025],[0.025,-0.041],[0,0],[0.041,0.024],[-0.024,0.042],[0,0]],"v":[[-0.546,-0.228],[-0.575,-0.349],[-0.455,-0.378],[0.544,0.228],[0.573,0.348],[0.453,0.379]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[272.763,350.813],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 459","np":4,"cix":2,"ix":459,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.01,0.046],[-0.047,0.012],[0,0],[-0.011,-0.047],[0.047,-0.012]],"o":[[-0.047,0.012],[-0.012,-0.047],[0,0],[0.047,-0.012],[0.012,0.047],[0,0]],"v":[[-0.546,0.226],[-0.651,0.162],[-0.588,0.055],[0.545,-0.226],[0.65,-0.162],[0.587,-0.055]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[266.464,349.854],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 460","np":4,"cix":2,"ix":460,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.011,0.047],[-0.047,0.011],[0,0],[-0.011,-0.047],[0.047,-0.012]],"o":[[-0.047,0.012],[-0.012,-0.047],[0,0],[0.048,-0.011],[0.012,0.047],[0,0]],"v":[[-0.545,0.225],[-0.651,0.161],[-0.587,0.055],[0.545,-0.227],[0.651,-0.163],[0.587,-0.056]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[273.158,348.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 461","np":4,"cix":2,"ix":461,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.046,0.011],[-0.011,-0.048],[0,0],[0.047,-0.012],[0.012,0.047]],"o":[[-0.012,-0.047],[0.047,-0.012],[0,0],[0.012,0.048],[-0.046,0.012],[0,0]],"v":[[-0.224,-0.548],[-0.161,-0.654],[-0.056,-0.59],[0.224,0.548],[0.16,0.654],[0.055,0.591]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[268.984,345.658],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 462","np":4,"cix":2,"ix":462,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.046,0.011],[-0.012,-0.047],[0,0],[0.047,-0.012],[0.012,0.047]],"o":[[-0.011,-0.047],[0.047,-0.012],[0,0],[0.012,0.047],[-0.047,0.012],[0,0]],"v":[[-0.225,-0.548],[-0.161,-0.654],[-0.055,-0.59],[0.225,0.549],[0.161,0.655],[0.055,0.591]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[270.639,352.387],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 463","np":4,"cix":2,"ix":463,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.609,2.478],[-2.463,0.613],[-0.61,-2.477],[2.464,-0.612]],"o":[[-0.608,-2.477],[2.464,-0.612],[0.608,2.477],[-2.463,0.612]],"v":[[-4.462,1.108],[-1.103,-4.485],[4.462,-1.108],[1.102,4.485]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.969000004787,0.933000033509,0.882000014361,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[269.73,349.055],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 464","np":4,"cix":2,"ix":464,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.691,2.813],[-2.797,0.696],[-0.692,-2.812],[2.798,-0.695]],"o":[[-0.691,-2.813],[2.798,-0.695],[0.691,2.813],[-2.797,0.695]],"v":[[-5.066,1.259],[-1.252,-5.092],[5.066,-1.258],[1.252,5.092]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[269.729,349.055],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 465","np":4,"cix":2,"ix":465,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-4.06,8.892],[7.714,5.967],[4.06,-8.892],[-7.714,-5.967]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.811999990426,0.709999952129,0.552999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[269.729,349.056],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 466","np":4,"cix":2,"ix":466,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-5.18,9.171],[8.833,5.691],[5.179,-9.17],[-8.833,-5.689]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.752999997606,0.62400004069,0.416000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[269.73,349.055],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 467","np":4,"cix":2,"ix":467,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-6.22,9.428],[9.873,5.431],[6.219,-9.428],[-9.873,-5.431]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.811999990426,0.709999952129,0.552999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[269.73,349.055],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 468","np":4,"cix":2,"ix":468,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-4.715,2.687],[5.417,0.17],[4.715,-2.687],[-5.417,-0.17]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.811999990426,0.709999952129,0.552999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[277.264,379.702],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 469","np":4,"cix":2,"ix":469,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-3.914,5.941],[6.217,3.424],[3.914,-5.941],[-6.217,-3.424]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.752999997606,0.62400004069,0.416000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[276.463,376.448],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 470","np":4,"cix":2,"ix":470,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-6.924,6.565],[9.169,2.568],[6.925,-6.564],[-9.168,-2.566]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.752999997606,0.62400004069,0.416000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[272.165,358.96],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 471","np":4,"cix":2,"ix":471,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-7.003,9.623],[10.655,5.236],[7.002,-9.624],[-10.655,-5.237]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.752999997606,0.62400004069,0.416000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[269.73,349.056],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 472","np":4,"cix":2,"ix":472,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-9.001,1.492],[8.657,-2.893],[9.001,-1.492],[-8.656,2.893]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.630999995213,0.510000011968,0.313999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[267.73,340.925],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 473","np":4,"cix":2,"ix":473,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-8.598,1.876],[8.478,-2.366],[8.598,-1.875],[-8.478,2.366]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.477999997606,0.40800000359,0.344999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[265.541,332.02],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 474","np":4,"cix":2,"ix":474,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-8.598,1.876],[8.478,-2.366],[8.598,-1.875],[-8.477,2.366]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.477999997606,0.40800000359,0.344999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[262.068,317.892],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 475","np":4,"cix":2,"ix":475,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-4.693,-18.09],[-4.229,-18.205],[4.694,18.089],[4.229,18.205]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[258.47,323.303],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 476","np":4,"cix":2,"ix":476,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-4.694,-18.09],[-4.229,-18.205],[4.694,18.09],[4.229,18.205]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[260.328,322.841],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 477","np":4,"cix":2,"ix":477,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-4.693,-18.089],[-4.228,-18.204],[4.694,18.09],[4.23,18.204]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[262.186,322.38],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 478","np":4,"cix":2,"ix":478,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-4.694,-18.09],[-4.229,-18.205],[4.694,18.09],[4.229,18.205]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[264.044,321.918],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 479","np":4,"cix":2,"ix":479,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-4.693,-18.089],[-4.228,-18.205],[4.694,18.09],[4.229,18.205]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[265.901,321.457],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 480","np":4,"cix":2,"ix":480,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-4.693,-18.09],[-4.228,-18.205],[4.694,18.089],[4.23,18.205]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[267.76,320.995],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 481","np":4,"cix":2,"ix":481,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-5.493,0.953],[5.302,-1.729],[5.493,-0.951],[-5.302,1.73]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[258.275,302.464],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 482","np":4,"cix":2,"ix":482,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-10.802,-18.167],[1.14,-21.134],[10.802,18.167],[-1.141,21.134]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.811999990426,0.709999952129,0.552999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[262.9,321.275],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 483","np":4,"cix":2,"ix":483,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-10.049,0.893],[9.305,-3.915],[10.048,-0.894],[-9.307,3.914]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[258.287,302.509],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 484","np":4,"cix":2,"ix":484,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-13.133,-16.569],[3.943,-20.811],[13.133,16.569],[-3.944,20.811]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.752999997606,0.62400004069,0.416000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[263.136,322.235],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 485","np":4,"cix":2,"ix":485,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.017,0.073],[-0.072,0.018],[0,0],[-0.019,-0.072],[0.072,-0.018]],"o":[[-0.071,0.018],[-0.018,-0.072],[0,0],[0.072,-0.017],[0.017,0.072],[0,0]],"v":[[-0.716,0.316],[-0.878,0.217],[-0.78,0.055],[0.717,-0.318],[0.88,-0.219],[0.781,-0.056]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[281.947,398.753],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 486","np":4,"cix":2,"ix":486,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.073,0.018],[-0.018,-0.073],[0,0],[0.072,-0.018],[0.018,0.072]],"o":[[-0.018,-0.072],[0.071,-0.018],[0,0],[0.019,0.072],[-0.073,0.017],[0,0]],"v":[[-0.867,-2.958],[-0.768,-3.122],[-0.607,-3.023],[0.866,2.973],[0.77,3.136],[0.607,3.037]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.255000005984,0.234999997008,0.219999994016,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[281.5,396.928],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 487","np":4,"cix":2,"ix":487,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-10.651,3.533],[1.644,9.921],[10.651,-0.57],[-7.347,-9.921]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[165.606,301.3],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 488","np":4,"cix":2,"ix":488,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-11.465,2.06],[4.32,10.259],[11.465,-0.909],[-6.533,-10.26]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458999992819,0.328999986836,0.161000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[164.793,301.639],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 489","np":4,"cix":2,"ix":489,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.253,0.198],[-0.389,-0.126],[-0.526,-0.35],[1.083,-0.046],[0.665,0.473],[0.23,-0.006],[-0.022,0.191]],"o":[[0.253,-0.198],[0.389,0.126],[0.527,0.349],[0,0],[0,0],[-0.231,0.007],[0.023,-0.19]],"v":[[-1.934,-0.974],[-0.74,-1.089],[0.986,-0.421],[1.204,1.215],[-1.285,-0.029],[-1.872,0.427],[-2.266,-0.182]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[111.566,344.783],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 490","np":4,"cix":2,"ix":490,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.374,0.814],[0,0],[0,0],[-2.154,0.469],[-0.197,-0.101],[0,0],[0,0],[0,0],[0.995,-0.357],[0.045,0.023],[0.413,0.215],[0,0]],"o":[[0,0],[0,0],[0,0],[2.155,-0.47],[0.197,0.103],[0,0],[0,0],[0,0],[-0.181,-0.091],[-0.149,-0.077],[-0.23,-0.12],[0,0]],"v":[[-2.229,-3.073],[1.021,-1.386],[-3.163,0.037],[1.442,-0.748],[4.695,-1.25],[6.673,-0.163],[-2.276,1.71],[4.044,0.825],[-1.896,3.073],[-2.259,2.89],[-3.569,2.042],[-6.673,0.555]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[120.398,346.308],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 491","np":4,"cix":2,"ix":491,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.804,0.641],[-0.068,0.132],[-0.221,0.428],[0,0],[0,0],[0,0],[-0.136,0.263],[0,0],[0,0],[0,0],[0.127,0.4],[0.063,0.2],[0.064,0.201],[-0.374,0.12],[0,0],[0.234,-0.129],[0,0],[0,0],[0.196,0.102],[0,0],[-0.672,0.216],[-0.068,0.132],[0.055,0.175],[0.699,-0.389],[0,0],[0.098,0.051],[0.638,0.321],[0,0]],"o":[[2.404,-0.549],[0.068,-0.132],[0.221,-0.43],[0,0],[0,0],[0,0],[0.135,-0.265],[0,0],[0,0],[0,0],[-0.127,-0.401],[-0.064,-0.2],[-0.063,-0.2],[0.373,-0.119],[0,0],[-0.232,0.13],[0,0],[0,0],[-0.198,-0.102],[0,0],[0.672,-0.214],[0.068,-0.132],[-0.056,-0.175],[-0.7,0.389],[0,0],[-0.069,-0.036],[0.256,-0.019],[6.179,-1.304]],"v":[[-3.785,5.051],[-0.005,4.171],[0.521,3.15],[9.954,-16.41],[10.873,-15.932],[-2.68,12.691],[-2.349,12.697],[11.128,-15.216],[13.298,-14.256],[-1.396,16.41],[-3.98,14.734],[-4.968,13.258],[-6.189,11.913],[-5.521,11.34],[-2.832,10.48],[-2.678,10.016],[-5.948,11.118],[-6.794,11.146],[-7.454,10.085],[-8.11,9.66],[-3.115,8.116],[-1.854,7.768],[-1.244,6.663],[-5.876,8.229],[-8.29,9.526],[-11.639,7.869],[-13.298,7.039],[-12.768,6.99]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[131.994,342.438],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 492","np":4,"cix":2,"ix":492,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.851,0.088],[0.002,-0.186],[0,0],[0.27,0.077],[-0.027,0.111]],"o":[[0.851,-0.088],[-0.002,0.186],[-0.175,0.159],[-0.27,-0.078],[0.026,-0.111]],"v":[[-0.483,-1.315],[1.894,-1.358],[0.577,1.384],[-1.062,1.438],[-1.869,-0.789]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[145.428,325.224],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 493","np":4,"cix":2,"ix":493,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.428,-1.157],[1.013,-0.221]],"o":[[0,0],[0,0],[0,0]],"v":[[-0.002,-1.388],[1.554,1.072],[-1.554,1.389]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[146.014,321.895],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 494","np":4,"cix":2,"ix":494,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[3.212,-7.204],[3.989,-6.8],[-3.211,7.204],[-3.989,6.8]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[150.583,313.526],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 495","np":4,"cix":2,"ix":495,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[3.372,-7.514],[4.149,-7.111],[-3.371,7.514],[-4.149,7.111]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[151.485,314.389],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 496","np":4,"cix":2,"ix":496,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[3.473,-7.711],[4.249,-7.307],[-3.473,7.711],[-4.249,7.308]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[152.568,315.2],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 497","np":4,"cix":2,"ix":497,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[3.738,-7.987],[4.32,-7.685],[-3.739,7.987],[-4.32,7.685]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[153.46,316.078],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 498","np":4,"cix":2,"ix":498,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.238,-3.904],[0,0],[2.561,3.698],[0.096,-4.467],[0.267,0.263],[0.027,-0.173],[0,0],[3.749,7.255],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[-0.268,-0.264],[-0.027,0.173],[0,0],[0,0],[0,0]],"v":[[3.639,-0.208],[2.236,2.458],[-0.561,-3.917],[0.488,6.16],[-0.529,5.727],[-1.075,6.004],[-2.708,9.361],[-3.639,-8.6],[-3.185,-9.361]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[151.564,333.341],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 499","np":4,"cix":2,"ix":499,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[3.756,-8.517],[4.74,-8.006],[-3.756,8.517],[-4.74,8.006]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[157.471,319.074],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 500","np":4,"cix":2,"ix":500,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4.079,-8.784],[4.77,-8.426],[-4.079,8.785],[-4.77,8.426]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[158.714,320.155],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 501","np":4,"cix":2,"ix":501,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[4.393,-9.161],[4.895,-8.9],[-4.392,9.161],[-4.895,8.901]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[159.546,321.126],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 502","np":4,"cix":2,"ix":502,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[-0.312,0.289],[0,0],[0.957,0.99]],"v":[[4.152,-5.349],[-3.169,7.303],[-3.202,7.368],[-4.152,6.999],[3.018,-7.658]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[147.536,348.199],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 503","np":4,"cix":2,"ix":503,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.083,-0.162],[0.18,-0.192],[0,0]],"o":[[0,0],[-0.083,0.162],[-0.181,0.192],[0,0]],"v":[[3.159,-6.43],[3.993,-5.914],[-3.028,6.238],[-4.076,5.898]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[148.625,350.599],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 504","np":4,"cix":2,"ix":504,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.435,-0.989],[0,0],[0,0],[-0.095,-0.3],[0,0],[0,0],[-0.867,-1.372],[0,0],[0.08,0.387],[-0.004,-0.001],[-0.005,-0.023],[0,0],[0,0],[-0.035,-0.111],[0,0],[0,0],[-0.246,-0.286],[0,0],[0.662,0.345],[0.229,0.013],[0.966,0.212],[0.03,0.095],[0.057,0.346],[0.09,0.284],[0.165,0.139],[0,0],[-0.281,-0.014],[-1.035,-1.249]],"o":[[0.435,0.99],[0,0],[0,0],[0.095,0.3],[0,0],[0,0],[0.867,1.373],[0,0],[-0.011,-0.027],[0.004,0.002],[0.17,0.396],[0,0],[0,0],[0.036,0.11],[0,0],[0,0],[0.247,0.286],[0,0],[-0.662,-0.344],[-0.229,-0.014],[-0.965,-0.212],[-0.03,-0.094],[-0.058,-0.347],[-0.09,-0.283],[-0.165,-0.138],[0,0],[0.281,0.014],[1.036,1.25]],"v":[[-1.037,0.488],[-0.18,2.646],[0.193,0.389],[1.105,2.287],[1.546,2.858],[0.654,-0.61],[2.266,1.15],[3.941,4.523],[3.616,0.883],[3.604,0.843],[3.616,0.883],[5.512,4.576],[4.314,-0.131],[6.152,2.669],[7.292,3.92],[5.096,-2.518],[8.378,-0.997],[9.223,7.506],[3.447,4.82],[0.217,3.249],[-1.919,3.272],[-3.654,2.264],[-3.982,1.119],[-6.036,-2.689],[-7.69,-5.182],[-9.223,-7.506],[-6.374,-7.08],[-4.18,-5.282]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[149.103,363.486],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 505","np":4,"cix":2,"ix":505,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.222,0.108],[0,0],[0,0]],"o":[[-0.702,-0.343],[2.719,2.639],[-0.309,0.116]],"v":[[0.227,3.168],[-2.071,-3.796],[2.071,3.68]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[142.854,361.943],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 506","np":4,"cix":2,"ix":506,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.257,0.368],[0,0],[0,0],[-0.149,-0.291],[0,0]],"o":[[-0.257,-0.369],[0,0],[0,0],[0.148,0.291],[-0.881,0.099]],"v":[[-1.391,1.44],[-1.559,-3.118],[0.012,-2.366],[0.356,-1.545],[1.648,3.019]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[140.613,361.923],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 507","np":4,"cix":2,"ix":507,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.067,0.212],[-0.078,0.151],[-0.171,-0.089],[0,0]],"o":[[-0.067,-0.212],[0.077,-0.15],[0.171,0.089],[-0.309,0.098]],"v":[[-0.616,1.818],[-0.376,-2.442],[0.512,-2.062],[0.527,2.493]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[138.25,360.775],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 508","np":4,"cix":2,"ix":508,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.333,-0.456],[0.137,-0.045],[0.129,0.408],[0,0],[0.276,-0.153],[0,0],[0.13,0.129],[0,0],[-0.158,0.117],[-0.183,0.103],[-0.104,-0.054],[0,0],[0,0]],"o":[[-0.333,0.456],[0,0],[-0.13,-0.409],[0,0],[-0.275,0.154],[0,0],[-0.129,-0.131],[0,0],[0.158,-0.115],[0.184,-0.102],[0.103,0.053],[0,0],[0,0]],"v":[[1.495,1.628],[0.243,3.617],[0.149,2.25],[-0.201,0.809],[-1.443,1.027],[-2.818,1.599],[-1.921,-0.146],[-2.497,-1.003],[-2.279,-1.682],[-0.288,-3.514],[0.363,-3.439],[2.818,-1.966],[2.713,2]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[134.657,360.349],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 509","np":4,"cix":2,"ix":509,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.354,0.102],[-0.23,0.343],[-0.129,-0.013],[0,0],[0.177,-0.345]],"o":[[0,0],[0.231,-0.343],[0.129,0.012],[0,0],[-0.176,0.344]],"v":[[-1.434,1.799],[0.253,-1.272],[1.058,-1.888],[1.434,-1.776],[0.149,0.88]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[135.508,364.608],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 510","np":4,"cix":2,"ix":510,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.183,0.014],[0.235,0.176],[-0.045,0.086],[-0.159,-0.218]],"o":[[0,0],[-0.183,-0.014],[-0.234,-0.176],[0.044,-0.086],[0.158,0.218]],"v":[[0.447,0.416],[0.026,0.497],[-0.485,0.068],[-0.23,-0.426],[0.561,-0.014]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[132.671,366.638],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 511","np":4,"cix":2,"ix":511,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.036,0.114],[-0.007,0.188],[0.149,0.132],[-0.055,0.107],[-0.329,-0.416],[0,0]],"o":[[-0.036,-0.114],[0.007,-0.186],[-0.149,-0.132],[0.055,-0.108],[0.328,0.415],[-0.082,0.148]],"v":[[-0.034,0.636],[-0.184,0.122],[-0.665,-0.454],[-0.378,-1.013],[0.486,-0.374],[0.248,0.973]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[133.881,364.21],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 512","np":4,"cix":2,"ix":512,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.689,0.878],[0,0],[-0.128,-0.013],[-0.033,0.064],[-0.055,0.107],[0.159,0.11],[0,0],[-0.142,0.118],[-0.146,0.047],[-0.236,-0.068],[0.056,-0.108],[0.13,-0.041],[0.122,-0.291],[0.089,-0.172],[-0.171,-0.089],[-0.037,-0.114],[0.122,-0.236],[-0.138,-0.153],[-0.211,0.068],[-0.107,-0.055],[0,0]],"o":[[-1.689,-0.877],[0,0],[0.13,0.012],[0.033,-0.065],[0.056,-0.108],[-0.16,-0.11],[0,0],[0.141,-0.117],[0.146,-0.047],[0.236,0.069],[-0.055,0.107],[-0.13,0.042],[-0.122,0.29],[-0.088,0.171],[0.171,0.088],[0.036,0.114],[-0.121,0.236],[0.137,0.153],[0.21,-0.067],[0.107,0.055],[0,0]],"v":[[-0.748,2.811],[-1.826,0.481],[-0.498,0.954],[-0.139,0.731],[-0.069,0.278],[-0.386,-0.105],[-1.377,-0.865],[-0.491,-2.747],[1.187,-3.481],[2.071,-3.621],[2.381,-2.643],[1.84,-2.434],[0.966,-2.261],[0.704,-1.172],[0.569,-0.698],[1.372,-0.363],[1.342,0.221],[0.645,1.683],[1.522,2.084],[1.901,1.873],[2.253,2.137]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[130.604,365.952],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 513","np":4,"cix":2,"ix":513,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.253,-0.44],[0,0],[-0.166,0.322],[-0.208,-0.018],[0.111,-0.214],[0.11,-0.161]],"o":[[-0.253,0.439],[0,0],[0.166,-0.322],[0.207,0.018],[-0.11,0.215],[-0.11,0.161]],"v":[[-0.025,0.177],[-1.835,2.695],[0.31,-2.372],[0.922,-2.455],[1.725,-1.964],[0.927,-0.2]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[130.303,361.971],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 514","np":4,"cix":2,"ix":514,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-1.14,0.656],[-0.465,-0.656],[1.14,0.125]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[135.298,351.525],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 515","np":4,"cix":2,"ix":515,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[1.336,0.826],[0,0],[0,0]],"v":[[-0.283,-1.236],[1.02,1.237],[-1.053,0.16]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[136.059,350.27],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 516","np":4,"cix":2,"ix":516,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.053,-0.103],[0,0],[-0.159,0.308],[0,0]],"o":[[-0.053,0.103],[0,0],[0.157,-0.306],[0,0]],"v":[[2.512,-4.471],[-2.239,4.768],[-2.406,4.176],[2.107,-4.768]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[143.378,333.834],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 517","np":4,"cix":2,"ix":517,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.305,0.029],[0,0],[-0.105,3.974],[-0.02,0.123],[-0.125,0.245],[0,0],[0.497,-5.277],[0.172,-0.646]],"o":[[-0.264,-0.025],[0,0],[0.105,-3.973],[0.019,-0.123],[0.126,-0.245],[0,0],[-0.497,5.275],[-0.164,0.617]],"v":[[-1.201,11.206],[-1.367,10.667],[-0.539,1.943],[-0.659,-7.416],[-0.271,-9.029],[0.511,-11.234],[0.968,-1.701],[-0.617,10.403]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[147.094,336.948],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 518","np":4,"cix":2,"ix":518,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.131,0.414],[2.724,2.152],[-0.141,0.273],[0,0],[0.296,-5.513],[0.208,-0.237],[0.936,1.611],[0,0],[-0.406,-1.638],[0.074,-0.394],[0.225,-0.072]],"o":[[-0.131,-0.415],[0,0],[0.14,-0.273],[0,0],[-0.296,5.514],[-0.208,0.239],[-0.936,-1.611],[0,0],[0.406,1.639],[-0.073,0.395],[-0.226,0.072]],"v":[[0.849,8.787],[-3.764,2.021],[-0.022,-5.421],[2.212,-10.1],[3.467,-1.748],[2.827,6.527],[1.211,3.395],[-0.065,1.607],[1.253,5.406],[1.977,8.767],[1.406,10.027]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[141.458,344.537],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 519","np":4,"cix":2,"ix":519,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.861,-2.886],[1.674,2.308]],"o":[[0,0],[0,0],[0,0]],"v":[[0.629,-4.361],[0.497,4.362],[-1.358,-0.457]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[145.361,334.167],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 520","np":4,"cix":2,"ix":520,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.845,1.575],[0.113,0.138],[0,0]],"o":[[-0.926,0.522],[-0.845,-1.575],[-0.113,-0.137],[2.095,1.088]],"v":[[2.163,2.525],[-0.141,-0.151],[-2.049,-2.569],[-1.751,-3.047]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[138.958,349.708],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 521","np":4,"cix":2,"ix":521,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.303,0.027],[0,0]],"o":[[0,0],[0,0],[0.304,-0.027],[0,0]],"v":[[-2.438,1.053],[-1.699,-0.385],[0.883,-1.025],[2.439,-0.013]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[135.844,353.115],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 522","np":4,"cix":2,"ix":522,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.124,-0.115],[0.2,-0.196],[0,0],[-0.146,0.323],[0,0],[-0.093,-0.128]],"o":[[-0.124,0.115],[-0.199,0.195],[0,0],[0.147,-0.323],[0,0],[0.093,0.128]],"v":[[1.099,-0.741],[-0.639,0.892],[-1.294,1.509],[-1.468,0.92],[-0.43,-0.866],[1.521,-1.38]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[132.719,357.486],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 523","np":4,"cix":2,"ix":523,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[1.458,0.758],[0,0],[-0.213,0.068],[-0.434,-0.332]],"o":[[0,0],[-1.459,-0.758],[0,0],[0.213,-0.068],[0.433,0.333]],"v":[[2.58,1.761],[-0.228,0.587],[-2.58,-0.921],[0.127,-1.693],[1.546,-1.135]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[137.617,357.154],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 524","np":4,"cix":2,"ix":524,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.207,0.16],[0.188,-0.007],[0,0],[0,0],[-0.142,0.045],[-0.734,-0.461],[0,0],[0.094,-0.03]],"o":[[-0.207,-0.16],[-0.188,0.008],[0,0],[0,0],[0.141,-0.046],[0.735,0.461],[0,0],[-0.095,0.03]],"v":[[1.386,0.774],[-0.69,0.672],[-4.874,1.298],[-4.051,-0.097],[1.194,-1.253],[4.139,0.171],[4.816,1.103],[2.154,1.12]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[137.426,354.669],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 525","np":4,"cix":2,"ix":525,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[2.496,1.481],[-0.623,0.6],[-0.312,-1.642],[0,0]],"v":[[-1.267,-2.428],[1.589,1.828],[0.162,1.589],[-1.589,-1.751]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[137.668,349.991],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 526","np":4,"cix":2,"ix":526,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.336,-0.102],[-0.325,-0.218],[0.025,-0.426],[0.117,-0.086],[0.115,0.06],[0.026,0.233],[0.096,0.05],[0,0],[-0.041,0.222]],"o":[[0.335,0.102],[0.325,0.217],[-0.025,0.424],[-0.116,0.085],[-0.115,-0.059],[-0.026,-0.232],[-0.095,-0.05],[-0.345,-0.179],[0.042,-0.221]],"v":[[-1.183,-1.476],[0.817,-0.558],[1.748,0.413],[1.599,1.456],[1.203,1.518],[0.949,1.069],[0.466,0.453],[-0.232,0.163],[-1.732,-0.787]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[162.128,372.124],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 527","np":4,"cix":2,"ix":527,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.516,-1.062],[-1.227,-0.525],[-1.339,-0.417],[-2.011,-1.158],[-0.832,-0.431],[-0.064,-0.2],[-0.569,-0.296],[-0.569,-0.296],[0,0],[0.708,-1.917],[-2.32,-1.205],[-0.627,0.789],[0,0],[-1.119,-0.304],[-0.525,-0.273],[-0.459,-0.294],[-0.308,-0.049],[-0.242,-0.069],[-0.219,-0.114],[0,0],[-0.846,-0.357],[-0.256,0.119],[0,0],[-0.497,-0.063],[-0.15,0.51],[0.406,0.238],[0,0],[0.07,0.568],[0.251,0.213],[0,0],[0.656,0.713],[0,0],[-0.003,0.217],[0,0],[0.041,0.13],[0,0],[-0.004,0.261],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.158,-0.308],[1.089,-2.333],[0,0],[0.597,-0.191],[0,0],[0,0],[1.087,-0.494],[0.429,-0.725],[1.03,0.369],[0.294,-0.572]],"o":[[0,0],[1.227,0.526],[1.338,0.417],[0,0],[0.831,0.433],[0.063,0.201],[0.569,0.295],[0.569,0.296],[0,0],[-0.709,1.918],[2.32,1.205],[0.628,-0.789],[0,0],[1.12,0.303],[0.525,0.273],[0.459,0.294],[0.308,0.048],[0.241,0.071],[0.219,0.113],[0,0],[0.847,0.355],[0.255,-0.118],[0,0],[0.496,0.061],[0.15,-0.508],[-0.406,-0.239],[0,0],[-0.069,-0.568],[-0.252,-0.215],[0,0],[-0.656,-0.713],[0,0],[0.002,-0.218],[0,0],[-0.042,-0.131],[0,0],[0.003,-0.261],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.159,0.309],[-1.089,2.333],[0,0],[-0.598,0.192],[0,0],[0,0],[-1.086,0.495],[0,0],[-1.031,-0.368],[-0.294,0.572]],"v":[[-29.099,4.568],[-28.263,5.733],[-23.456,7.172],[-13.888,11.753],[-12.913,13.094],[-11.827,14.216],[-9.57,16.839],[-8.023,18.144],[-6.36,19.008],[-8.724,24.469],[-7.206,29.607],[-2.743,28.692],[0.885,22.716],[4.89,24.742],[7.592,25.42],[8.998,25.705],[10.77,26.681],[11.961,26.63],[13.041,26.579],[22.478,31.732],[24.091,33.41],[26.835,34.89],[27.207,34.329],[29.283,35.324],[30.19,34.424],[28.766,31.784],[22.577,28.4],[23.131,26.619],[21.677,21.334],[15.246,17.881],[13.906,15.558],[11.769,13.748],[17.484,3.31],[16.815,2.875],[17.713,1.045],[17.251,0.63],[19.81,-4.515],[19.698,-5.186],[31.615,-27.882],[30.346,-28.541],[19.985,-8.392],[19.591,-8.596],[29.641,-28.574],[29.071,-28.758],[19.114,-9.178],[18.856,-9.647],[28.657,-29.14],[24.695,-31.143],[15.986,-14.204],[14.892,-14.773],[23.447,-31.736],[22.835,-32.054],[14.464,-15.776],[13.72,-16.162],[22.068,-32.397],[18.48,-34.371],[17.87,-34.912],[17.282,-35.385],[9.788,-20.379],[9.396,-20.695],[9.612,-22.087],[9.063,-22.205],[5.58,-15.43],[5.094,-15.348],[-1.439,-1.348],[-4.387,4.925],[-5.816,4.684],[-8.195,4.564],[-16.756,0.506],[-18.857,1.031],[-23.08,3.743],[-28.268,1.214],[-31.161,1.663]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458999992819,0.328999986836,0.161000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[136.592,340.403],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 528","np":4,"cix":2,"ix":528,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.747,-15.272],[12.825,-8.22],[0.747,15.271],[-12.825,8.219]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.677999997606,0.545000023935,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[155.195,319.305],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 529","np":4,"cix":2,"ix":529,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-1.224,-2.305],[0,0]],"o":[[0,0],[-0.384,2.093],[1.223,2.306],[-2.306,-4.925]],"v":[[-3.009,-7.531],[-3.075,-7.628],[0.382,2.305],[3.459,7.628]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.144999994016,0.493999974868,0.510000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[137.317,103.786],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 530","np":4,"cix":2,"ix":530,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.455,-0.975],[0,0],[0.052,0.18],[0.258,0.897],[0,0]],"o":[[0.455,0.976],[0,0],[-0.051,-0.179],[-0.258,-0.896],[0,0]],"v":[[-0.247,0.887],[1.085,2.831],[0.942,1.999],[-0.358,-1.042],[-1.085,-2.831]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.144999994016,0.493999974868,0.510000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[126.849,94.111],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 531","np":4,"cix":2,"ix":531,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.01,-3.242],[-0.392,-2.237],[0,0],[-0.081,1.131],[2.573,8.539]],"o":[[0,0],[1.011,3.243],[0.335,1.911],[0,0],[0.08,-1.131],[-2.572,-8.538]],"v":[[-4.982,-16.176],[-0.083,-1.796],[3.755,12.747],[4.393,16.176],[4.902,14.318],[1.665,1.794]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.144999994016,0.493999974868,0.510000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[128.301,86.358],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 532","np":4,"cix":2,"ix":532,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.144,-0.544],[-0.299,-0.437],[-0.432,-0.297],[0,0],[0.122,1.111],[-0.245,2.377],[-0.157,-0.029],[-0.175,-0.522],[0,0],[0,0],[0.175,-1.546],[0.183,0.034],[-0.286,4.521],[0,0],[0.206,-3.637],[-0.187,-0.606],[-0.185,-0.47],[0,0],[0,0]],"o":[[0.144,0.544],[0.299,0.436],[0.433,0.298],[0,0],[-0.121,-1.112],[0.246,-2.377],[0.158,0.029],[0.176,0.522],[-0.667,-3.308],[0,0],[-0.175,1.547],[-0.183,-0.034],[0.287,-4.52],[-0.668,1.427],[-0.205,3.637],[0.187,0.606],[0.185,0.469],[-0.628,-0.116],[0,0]],"v":[[-1.935,7.67],[-1.132,9.643],[-0.256,10.92],[1.141,11.424],[0.396,9.136],[0.176,0.874],[1.129,-2.407],[1.711,-0.557],[2.238,0.412],[1.256,-9.896],[-0.342,0.451],[-0.907,3.831],[-1.255,-2.549],[0.209,-11.424],[-1.806,-2.351],[-1.436,4.06],[-0.835,5.805],[-0.406,8.633],[-2.238,5.627]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.144999994016,0.493999974868,0.510000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[119.965,77.019],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 533","np":4,"cix":2,"ix":533,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.131,-0.191],[-0.295,-0.055],[-0.089,-0.267],[0.065,0.096],[0,0],[-0.088,-0.128],[-0.241,-0.045],[-0.112,-0.299],[0.064,-0.35],[-0.112,-0.299],[0,0],[0,0],[0,0],[0,0],[0.288,-0.058],[0.484,0.229],[0.393,0.573],[0.365,0.123],[0.319,-0.08],[0.365,0.123],[0.194,0.148],[0.066,0.095],[-0.127,0.088],[0.109,0.159],[0,0],[0,0],[-0.03,0.162],[0,0],[0.107,0.02],[0,0],[0,0],[0.19,-0.132],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.133,-0.025],[0,0],[0,0],[0.034,-0.188],[0,0],[0,0],[-0.19,0.132],[0,0],[0,0],[0.134,0.025],[0.134,0.025],[0.175,0.256],[0.35,0.51],[0.151,0.084],[0.216,0.179],[0.087,0.128],[0.153,0.223],[0.248,0.157],[0.161,0.03],[0,0],[0,0],[0.109,0.159],[-0.105,0.119],[0.109,0.159],[-0.389,0.458],[0.08,0.321],[0.377,0.209],[0.096,-0.066],[0.111,0.299],[0.128,0.664],[0,0],[0.137,-0.142],[0,0],[0.516,-0.545],[0,0],[-0.627,0.245],[-0.095,0.066],[0.049,-0.269],[-0.424,0.2],[-0.214,-0.04],[0.027,-0.149],[0.7,-0.344],[0.168,-0.028],[0,0],[0,0],[-0.585,0.922],[-0.107,-0.02],[0.286,-0.197],[0.178,-0.218],[0.025,-0.135],[-0.204,-0.094],[-0.285,0.197],[-0.283,0.337],[-0.175,-0.254],[0.096,-0.066],[0,0],[-0.321,-0.059],[-0.294,-0.054],[-0.133,-0.331],[-0.307,0.165],[-0.173,-0.115],[-0.068,-0.235],[0.254,-0.175],[-0.222,0.154],[-0.292,-0.222],[-0.109,-0.159],[-0.431,-0.219],[-0.509,-0.4],[-0.284,-0.414],[-0.065,-0.095],[0.006,0.419],[-0.256,0.036],[-0.136,-0.471],[-0.087,-1.491],[0.431,0.22],[0.058,0.289],[-0.054,0.296],[0.109,0.16],[0,0],[-0.026,-0.311],[-0.132,-0.191],[0,0],[-0.457,-0.53],[-0.222,1.212],[0.014,0.225],[0,0],[-0.18,-0.534],[0.177,-1.721],[0,0],[-0.134,-0.025],[0.049,-0.269],[-0.257,-0.103],[-0.244,0.121],[0.109,0.16],[0,0],[-0.131,-0.191],[-0.131,-0.191],[-0.13,-0.191],[0,0],[0.014,0.226],[-0.03,0.162],[0.109,0.159],[0.014,0.226],[-0.105,0.12],[0,0],[0.06,0.429],[0,0],[-0.059,-0.289],[-0.197,-0.287],[0,0],[0.101,0.353],[-0.05,0.269],[-0.307,0.165],[0,0],[0.066,0.095],[0,0],[-0.044,0.242],[0.095,-0.066],[0.066,0.096],[-0.049,0.27],[0,0],[-0.066,-0.095],[0.095,-0.066],[0,0],[0,0],[0,0],[-0.087,-0.128],[-0.241,-0.044],[-0.087,-0.128],[-0.244,0.121],[-0.058,-0.289],[0.346,-0.381],[0,0],[-0.309,0.026],[-0.428,-0.079],[-0.248,-0.157],[-0.284,0.337],[0,0],[-0.28,-0.135],[-0.554,0.148],[-0.788,-0.536],[0,0],[0.333,0.146],[0,0],[0.04,-0.215],[0.476,-1.693],[-1.357,-0.001],[0.455,-0.973],[0.309,-0.778],[-0.218,-0.318],[-0.312,-0.113],[-0.928,-1.285],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.132,0.191],[0.196,0.287],[0,0],[0,0],[0,0],[0,0],[0,0],[1.029,1.638],[-0.005,0.333],[-0.081,-0.015],[-0.455,-0.391],[0,0],[0.261,0.382],[0,0],[0.281,0.887],[0,0],[-0.049,0.27],[0.132,0.192],[0,0],[0,0],[-0.223,0.154],[-0.196,0.465],[0.094,0.546],[0.286,0.554],[0,0],[-0.145,0.335],[0.175,0.255],[0.194,0.148],[-0.125,0.227],[0.109,0.159],[0,0]],"o":[[0,0],[0,0],[0.131,0.192],[0.294,0.054],[0.09,0.267],[-0.066,-0.095],[0,0],[0.087,0.127],[0.241,0.045],[0.111,0.299],[-0.064,0.351],[0.111,0.299],[0,0],[0,0],[0,0],[0,0],[-0.287,0.058],[-0.484,-0.228],[-0.393,-0.574],[-0.365,-0.124],[-0.32,0.08],[-0.365,-0.124],[-0.195,-0.147],[-0.065,-0.096],[0.127,-0.087],[-0.11,-0.159],[0,0],[0,0],[0.03,-0.161],[0,0],[-0.107,-0.02],[0,0],[0,0],[-0.191,0.132],[0,0],[0,0],[0,0],[0,0],[0,0],[0.135,0.025],[0,0],[0,0],[-0.035,0.189],[0,0],[0,0],[0.19,-0.131],[0,0],[0,0],[-0.134,-0.024],[-0.134,-0.024],[-0.175,-0.255],[-0.349,-0.51],[-0.151,-0.083],[-0.216,-0.179],[-0.088,-0.127],[-0.153,-0.223],[-0.248,-0.157],[-0.161,-0.03],[0,0],[0,0],[-0.109,-0.16],[0.105,-0.12],[-0.109,-0.16],[0.388,-0.457],[-0.08,-0.321],[-0.377,-0.209],[-0.094,0.066],[-0.111,-0.299],[-0.127,-0.663],[0,0],[-0.137,0.141],[0.247,0.769],[-0.515,0.545],[0.243,1.241],[0.627,-0.246],[0.095,-0.066],[-0.049,0.269],[0.425,-0.2],[0.215,0.04],[-0.027,0.148],[-0.7,0.343],[-0.168,0.028],[0,0],[0,0],[0.584,-0.921],[0.107,0.019],[-0.285,0.198],[-0.178,0.217],[-0.024,0.135],[0.205,0.093],[0.285,-0.198],[0.284,-0.338],[0.174,0.256],[-0.095,0.066],[0,0],[0.322,0.06],[0.295,0.055],[0.134,0.331],[0.307,-0.166],[0.173,0.115],[0.067,0.235],[-0.254,0.176],[0.222,-0.154],[0.292,0.221],[0.11,0.16],[0.43,0.219],[0.508,0.401],[0.284,0.415],[0.066,0.096],[-0.007,-0.419],[0.256,-0.036],[0.135,0.47],[0.087,1.492],[-0.431,-0.218],[-0.058,-0.289],[0.054,-0.297],[-0.11,-0.159],[0,0],[0.027,0.311],[0.131,0.191],[0,0],[0.457,0.53],[0.222,-1.212],[-0.014,-0.225],[0,0],[0.179,0.534],[-0.176,1.721],[0.523,0.014],[0.134,0.025],[-0.05,0.269],[0.259,0.103],[0.244,-0.122],[-0.109,-0.159],[0,0],[0.131,0.192],[0.132,0.192],[0.132,0.192],[0,0],[-0.014,-0.225],[0.029,-0.162],[-0.109,-0.16],[-0.014,-0.225],[0.105,-0.12],[0,0],[-0.06,-0.428],[0,0],[0.057,0.289],[0.196,0.286],[0,0],[-0.102,-0.352],[0.049,-0.269],[0.308,-0.166],[0,0],[-0.065,-0.096],[0,0],[0.045,-0.242],[-0.095,0.066],[-0.066,-0.096],[0.049,-0.269],[0,0],[0.066,0.096],[-0.095,0.066],[0,0],[0,0],[0,0],[0.088,0.127],[0.241,0.045],[0.088,0.128],[0.244,-0.122],[0.057,0.289],[-0.347,0.381],[0,0],[0.31,-0.026],[0.429,0.08],[0.248,0.157],[0.283,-0.338],[0,0],[0.28,0.135],[0.553,-0.148],[0.788,0.535],[0,0],[-0.333,-0.145],[0,0],[-0.039,0.215],[-0.477,1.694],[1.357,0.001],[-0.456,0.974],[-0.308,0.778],[0.219,0.319],[0.312,0.114],[0.928,1.286],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.13,-0.192],[-0.197,-0.287],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.029,-1.638],[0.006,-0.333],[0.08,0.015],[0.455,0.39],[0,0],[-0.263,-0.383],[0,0],[-0.281,-0.887],[0,0],[0.05,-0.269],[-0.131,-0.191],[0,0],[0,0],[0.222,-0.154],[0.196,-0.465],[-0.094,-0.547],[-0.286,-0.554],[0,0],[0.145,-0.335],[-0.174,-0.255],[-0.195,-0.147],[0.125,-0.228],[-0.11,-0.16],[0,0]],"v":[[15.677,-19.352],[14.888,-19.275],[15.115,-16.283],[16.213,-15.773],[16.868,-14.816],[16.067,-14.826],[15.281,-15.222],[15.061,-14.928],[15.966,-14.427],[16.467,-13.833],[16.198,-12.519],[16.481,-11.492],[15.822,-11.224],[15.642,-10.394],[16.119,-3.624],[9.311,-14.99],[8.559,-15.269],[6.821,-15.758],[4.976,-17.63],[2.123,-19.745],[0.437,-19.612],[-1.246,-19.951],[-3.129,-20.857],[-4.343,-21.944],[-4.171,-22.581],[-4.546,-23.402],[-5.569,-23.87],[-6.711,-25.194],[-8.036,-27.333],[-4.027,-31.379],[-8.827,-28.76],[-9.281,-29.15],[-7.266,-33.649],[-10.859,-29.609],[-11.782,-29.864],[-12.259,-34.518],[-13.222,-29.713],[-14.045,-29.002],[-18.198,-32.332],[-15.3,-27.898],[-16.196,-27.089],[-21.744,-27.337],[-16.89,-25.715],[-16.556,-24.817],[-19.607,-22.375],[-16.156,-23.825],[-15.539,-23.265],[-17.096,-21.716],[-17.753,-21.309],[-19.394,-21.724],[-20.383,-22.826],[-21.863,-24.575],[-24.333,-26.814],[-26.225,-28.278],[-27.138,-29.338],[-30.164,-33.684],[-31.03,-34.401],[-32.619,-34.194],[-32.956,-34.619],[-32.814,-35.093],[-33.263,-35.816],[-33.111,-36.345],[-33.641,-36.777],[-33.013,-37.636],[-32.594,-38.866],[-34.127,-40.625],[-36.212,-39.981],[-36.595,-40.609],[-36.635,-42.51],[-37.574,-43.881],[-37.517,-42.227],[-39.516,-45.075],[-39.427,-41.328],[-40.599,-41.127],[-38.496,-39.151],[-37.146,-40.321],[-37.08,-39.474],[-36.342,-39.421],[-34.821,-39.863],[-34.589,-39.388],[-37.116,-37.615],[-38.483,-36.334],[-39.153,-35.264],[-38.575,-35.241],[-38.237,-36.181],[-35.66,-38.153],[-35.696,-37.659],[-37.487,-36.041],[-38.086,-35.345],[-37.875,-34.832],[-36.914,-35.069],[-35.912,-35.722],[-34.868,-35.975],[-35.794,-35.004],[-36.289,-34.567],[-35.879,-34.241],[-35.363,-34.034],[-34.648,-33.4],[-33.832,-33.165],[-32.83,-33.342],[-32.428,-32.21],[-33.239,-31.414],[-32.693,-31.368],[-31.045,-31.146],[-28.664,-27.059],[-27.04,-26.396],[-23.473,-24.4],[-21.398,-22.123],[-18.295,-17.595],[-18.176,-18.241],[-17.746,-20.138],[-16.889,-18.615],[-17.032,-14.661],[-17.757,-11.761],[-18.656,-13.959],[-18.681,-14.882],[-19.126,-16.079],[-20.163,-16.771],[-19.754,-14.469],[-19.417,-13.432],[-18.839,-14.021],[-17.891,-10.727],[-16.633,-12.304],[-16.786,-16.759],[-16.637,-18.179],[-16.183,-17.176],[-16.194,-11.527],[-16.848,-9.616],[-15.883,-10.049],[-15.661,-8.839],[-14.945,-8.066],[-14.05,-8.262],[-13.975,-8.973],[-14.801,-11.269],[-14.111,-10.195],[-12.959,-8.172],[-12.589,-7.018],[-11.951,-6.565],[-11.898,-7.308],[-12.032,-8.39],[-13.151,-10.295],[-13.728,-11.683],[-13.743,-12.66],[-12.511,-11.068],[-12.411,-12.219],[-12.193,-14.016],[-10.805,-5.713],[-10.454,-3.699],[-8.75,-3.328],[-11.771,-15.107],[-11.745,-16.912],[-10.498,-17.07],[-9.863,-17.51],[-12.77,-21.75],[-12.676,-22.568],[-12.085,-23.071],[-12.617,-23.643],[-13.25,-23.816],[-12.985,-24.658],[-12.595,-25.727],[-10.403,-25.6],[-11.255,-24.727],[-11.439,-24.177],[-10.424,-22.764],[-10.983,-22.283],[-10.935,-21.939],[-10.27,-21.789],[-9.865,-21.129],[-9.046,-21.367],[-8.547,-20.913],[-9.349,-19.558],[-10.815,-18.966],[-9.855,-19.067],[-8.462,-18.81],[-6.164,-18.05],[-4.949,-17.574],[-2.877,-18.305],[-1.357,-18.134],[0.276,-18.278],[3.024,-17.407],[5.457,-14.813],[0.801,-16.761],[0.559,-16.499],[22.375,12.873],[19.103,19.7],[21.114,21.27],[22.36,23.087],[18.995,29.508],[18.848,31.067],[19.864,31.116],[21.899,32.857],[23.512,37.053],[20.265,39.208],[18.656,43.002],[20.076,45.075],[20.14,45.031],[40.599,30.862],[40.074,30.097],[38.969,29.029],[37.182,28.197],[36.548,27.273],[35.724,27.844],[36.165,28.761],[34.198,30.123],[29.491,22.709],[28.085,19.498],[28.649,19.296],[34.002,26.356],[35.205,27.497],[34.169,26.053],[32.695,23.97],[32.563,21.663],[28.121,15.523],[28.727,14.633],[26.891,11.955],[27.004,10.89],[18.979,1.025],[19.443,0.61],[19.959,-0.547],[20.395,-3.529],[19.855,-6.023],[17.862,-9.204],[18.468,-10.094],[18.47,-11.318],[17.962,-12.471],[17.818,-13.499],[17.634,-15.064],[16.202,-16.471]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.144999994016,0.493999974868,0.510000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[123.667,81.505],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 534","np":4,"cix":2,"ix":534,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.646,6.982],[-3.286,-5.465],[0,0],[0.699,1.02]],"o":[[0,0],[3.285,5.465],[0,0],[-0.699,-1.021]],"v":[[-7.863,-13.761],[-0.826,-1.148],[7.863,13.761],[6.77,12.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.144999994016,0.493999974868,0.510000011968,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[133.511,85.627],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 535","np":4,"cix":2,"ix":535,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.141,0.577],[-0.225,-0.443],[0,0],[0.35,0.916],[0.041,-1.187],[-0.029,-0.101],[-0.108,0.075],[-0.091,-0.017],[-0.012,-0.192],[0.114,-0.239],[-0.057,-0.2],[0,0],[-0.335,0.032],[-0.175,-0.197],[0,0],[-0.083,-0.063],[-0.12,-0.117],[0,0],[-0.029,-0.1],[0,0],[0,0],[-0.029,0.16],[0,0],[0,0],[-0.047,-0.127],[-0.085,-0.181],[-0.167,-0.243],[0,0],[-0.205,-0.038],[-0.165,-0.125],[-0.093,-0.135],[0,0],[0,0],[0.112,0.162],[0,0],[0,0],[0,0],[0,0],[-0.056,-0.081],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.148,-0.215],[0,0],[-0.123,-0.179],[-0.074,-0.107],[0,0],[-0.025,-0.036],[-0.097,-0.143],[-0.041,-0.059],[-0.028,-0.067],[-0.033,-0.048],[0,0],[0,0],[0,0],[0.036,-0.024],[0,0],[0,0],[0,0],[0,0],[0.141,0.026],[0.072,0.055],[0,0],[0.851,1.243],[0.277,0.301],[0.49,0.613],[0.279,0.406],[0.113,0.062],[1.144,1.67],[0,0],[0.643,0.119],[0.618,0.594],[0.488,0.917],[0,0],[0.569,0.523],[0.318,1.436],[0,0],[0.328,0.478],[0,0],[0.195,0.182],[0,0],[0.366,0.169],[-0.04,0.556],[0,0],[0.415,-0.111],[0.636,0.723],[0.296,0.994],[0.036,0.257],[0.25,0.108],[0.551,0.394],[1.485,1.756],[0.275,0.197],[0.254,0.142],[0.482,0.653],[0.389,0.26],[0.132,0.295],[0.065,0.095],[0.272,-0.013],[0,0],[0.422,0.307],[0.375,-0.118],[0.115,0.167],[-0.305,0.987],[0,0],[0.179,0.158],[0.062,0.091],[0.002,0.668],[0,0],[-0.24,-0.045]],"o":[[0,0],[0.224,0.444],[0,0],[0,0],[-0.041,1.186],[0.029,0.099],[0.108,-0.074],[0.091,0.017],[0.013,0.191],[-0.114,0.239],[0.058,0.199],[0,0],[0.335,-0.033],[0.176,0.198],[0,0],[0.083,0.062],[0.12,0.116],[0,0],[0.028,0.1],[0,0],[0,0],[0.03,-0.16],[0,0],[0,0],[0.047,0.127],[0.084,0.181],[0.167,0.244],[0,0],[0.204,0.037],[0.165,0.125],[0,0],[0,0],[0,0],[-0.111,-0.163],[0,0],[0,0],[0,0],[0,0],[0.056,0.081],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.147,0.215],[0,0],[0.122,0.179],[0.074,0.108],[0,0],[0.024,0.035],[0.097,0.142],[0.04,0.06],[0.029,0.067],[0.032,0.047],[0,0],[0,0],[0,0],[-0.035,0.025],[0,0],[0,0],[0,0],[0,0],[-0.14,-0.026],[-0.073,-0.055],[0,0],[-0.852,-1.242],[-0.277,-0.302],[-0.49,-0.612],[-0.278,-0.406],[-0.113,-0.063],[-1.145,-1.67],[0,0],[-0.642,-0.119],[-0.617,-0.594],[-0.488,-0.917],[0,0],[-0.569,-0.522],[-0.319,-1.437],[0,0],[-0.327,-0.478],[0,0],[-0.195,-0.182],[0,0],[-0.367,-0.169],[0.039,-0.556],[0,0],[-0.415,0.111],[-0.635,-0.723],[-0.295,-0.993],[-0.036,-0.257],[-0.25,-0.109],[-0.55,-0.394],[-1.484,-1.757],[-0.275,-0.197],[-0.255,-0.141],[-0.482,-0.652],[-0.388,-0.259],[-0.133,-0.296],[-0.066,-0.096],[-0.272,0.012],[0,0],[-0.42,-0.308],[-0.374,0.118],[-0.114,-0.168],[0.306,-0.986],[0,0],[-0.178,-0.158],[-0.063,-0.09],[-0.002,-0.668],[0,0],[0.242,0.044]],"v":[[-37.618,-43.177],[-36.311,-41.966],[-35.938,-41.306],[-35.918,-42.957],[-34.346,-39.533],[-34.273,-37.427],[-33.958,-36.968],[-32.196,-37.469],[-31.222,-36.626],[-31.299,-35.175],[-31.556,-33.52],[-30.703,-32.393],[-29.748,-32.216],[-28.673,-31.923],[-27.885,-30.831],[-23.579,-24.549],[-21.421,-22.849],[-18.625,-20.393],[-17.14,-18.227],[-15.295,-18.028],[-13.039,-18.792],[-11.985,-21.079],[-10.985,-23.329],[-9.981,-24.183],[-5.956,-22.02],[-4.686,-19.704],[-2.889,-17.835],[2.489,-16.248],[3.933,-16.17],[6.311,-14.903],[8.396,-12.673],[10.684,-11.942],[12.109,-12.529],[12.57,-12.609],[12.102,-15.958],[17.295,-16.501],[18.038,-15.238],[18.05,-13.888],[18.586,-13.221],[19.534,-12.361],[19.866,-10.833],[19.933,-9.402],[19.263,-5.802],[20.124,-2.858],[20.214,-0.118],[19.534,2.573],[20.083,4.677],[27.556,15.504],[28.679,18.6],[30.791,20.838],[32.104,21.832],[33.18,23.095],[34.227,25.065],[34.544,26.313],[35.121,27.206],[35.624,27.888],[36.133,28.531],[36.477,28.905],[36.848,29.346],[38.424,31.189],[38.828,31.626],[38.496,32.257],[37.553,32.91],[31.344,37.476],[29.578,40.321],[26.504,42.485],[24.015,43.151],[23.19,42.56],[22.749,42.019],[21.889,39.69],[19.688,36.633],[18.158,35.014],[15.92,32.159],[15.237,31.469],[12.463,27.677],[6.676,18.262],[5.533,17.926],[3.157,16.505],[0.567,11.907],[-0.027,10.887],[-2.376,9.659],[-4.277,5.761],[-6.082,-0.249],[-8.269,-0.779],[-9.136,-3.068],[-10.021,-3.336],[-11.288,-5.031],[-12.526,-5.055],[-13.186,-6.113],[-13.34,-7.769],[-14.39,-6.795],[-16.485,-7.6],[-18.047,-11.311],[-18.544,-14.032],[-18.556,-14.764],[-20.923,-16.684],[-23.195,-19.128],[-26.604,-23.745],[-27.962,-24.32],[-30.139,-27.112],[-31.679,-28.336],[-32.853,-29.742],[-32.979,-30.642],[-33.628,-31.179],[-34.264,-31.902],[-35.22,-31.557],[-36.239,-32.226],[-36.965,-32.569],[-37.008,-34.372],[-36.16,-36.051],[-36.989,-37.31],[-38.164,-38.23],[-38.826,-40.196],[-38.608,-41.616],[-37.803,-40.799]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.33300000359,0.773000021542,0.819999964097,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[121.261,78.73],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 536","np":4,"cix":2,"ix":536,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1.038,30.58],[23.2,21.794],[-10.607,-16.366],[-23.2,-30.58],[-23.199,-30.556]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[170.409,92.42],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 537","np":4,"cix":2,"ix":537,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-2.249,10.088],[-1.253,5.833],[2.492,7.914],[2.826,4.155],[5.567,6.197],[6.296,4.126],[-6.297,-10.088],[-5.745,8.367],[-4.088,6.205]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[153.505,71.928],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 538","np":2,"cix":2,"ix":538,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[22.924,10.297],[-10.883,-27.863],[-11.611,-25.791],[-14.354,-27.833],[-14.687,-24.074],[-18.432,-26.156],[-19.429,-21.9],[-21.266,-25.783],[-22.924,-23.621],[-21.385,27.863]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.352999997606,0.556999954523,0.607999973671,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[170.684,103.917],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 539","np":2,"cix":2,"ix":539,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[9.091,-19.047],[-7.888,-25.911],[-8.765,11.847],[-9.092,25.912],[-9.079,25.898]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[173.428,318.32],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 540","np":4,"cix":2,"ix":540,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[3.574,-5.388],[0.804,-3.655],[-0.212,-6.701],[-2.351,-4.885],[-2.827,-7.391],[-4.311,-6.673],[-4.638,7.392],[4.637,-2.661],[2.586,-2.379]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[168.974,336.84],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 541","np":2,"cix":2,"ix":541,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-16.535,-21.026],[-17.412,16.732],[-15.928,16.014],[-15.452,18.52],[-13.313,16.703],[-12.296,19.75],[-9.528,18.017],[-10.514,21.026],[-8.463,20.744],[17.412,-7.302]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.352999997606,0.556999954523,0.607999973671,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[182.075,313.435],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 542","np":2,"cix":2,"ix":542,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-13.727,20.469],[4.822,30.464],[11.31,-13.927],[13.726,-30.464],[13.71,-30.449]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[278.67,98.383],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 543","np":4,"cix":2,"ix":543,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-5.238,5.529],[-1.8,3.798],[-1.071,7.502],[1.655,5.603],[1.839,8.607],[3.652,7.929],[6.068,-8.607],[-6.068,2.198],[-3.666,2.094]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[286.329,76.527],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 544","np":2,"cix":2,"ix":544,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[15.299,25.113],[21.786,-19.279],[19.975,-18.6],[19.79,-21.605],[17.065,-19.706],[16.336,-23.41],[12.898,-21.678],[14.47,-25.113],[12.068,-25.01],[-21.786,5.13]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.352999997606,0.556999954523,0.607999973671,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[268.194,103.735],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 545","np":2,"cix":2,"ix":545,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[6.665,-29.901],[-13.451,-27.618],[6.146,14.29],[13.447,29.901],[13.451,29.88]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[233.759,340.562],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 546","np":4,"cix":2,"ix":546,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[2.903,-9.378],[1.169,-5.878],[-1.463,-8.632],[-2.546,-5.404],[-4.363,-7.876],[-5.408,-6.232],[1.893,9.379],[5.408,-7.004],[3.58,-5.508]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[245.313,361.084],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 547","np":2,"cix":2,"ix":547,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-20.109,-19.086],[-0.511,22.823],[0.534,21.178],[2.35,23.651],[3.433,20.423],[6.065,23.177],[7.799,19.677],[8.476,23.547],[10.304,22.051],[20.109,-23.651]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.352999997606,0.556999954523,0.607999973671,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[240.417,332.029],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 548","np":2,"cix":2,"ix":548,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-27.04,-4.975],[-25.066,11.466],[12.898,-5.24],[27.04,-11.462],[27.022,-11.466]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[349.024,204.557],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 549","np":4,"cix":2,"ix":549,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-8.474,-2.335],[-5.318,-0.969],[-7.818,1.23],[-4.906,2.067],[-7.148,3.593],[-5.667,4.423],[8.474,-1.8],[-6.316,-4.423],[-4.974,-2.949]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[367.59,194.894],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 550","np":2,"cix":2,"ix":550,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-17.39,16.436],[20.576,-0.27],[19.094,-1.1],[21.337,-2.626],[18.424,-3.463],[20.924,-5.662],[17.768,-7.028],[21.269,-7.642],[19.926,-9.116],[-21.336,-16.436]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.352999997606,0.556999954523,0.607999973671,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[341.347,199.587],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 551","np":2,"cix":2,"ix":551,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[39.939,4.311],[36.251,-17.694],[-19.262,8.086],[-39.939,17.69],[-39.911,17.693]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[80.966,207.006],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 552","np":4,"cix":2,"ix":552,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[12.577,2.936],[7.833,1.364],[11.439,-1.816],[7.083,-2.695],[10.337,-4.945],[8.102,-5.938],[-12.577,3.665],[9.475,5.938],[7.415,4.065]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[53.603,221.031],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 553","np":2,"cix":2,"ix":553,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[24.579,-21.997],[-30.934,3.783],[-28.699,4.776],[-31.953,7.026],[-27.597,7.905],[-31.202,11.085],[-26.459,12.657],[-31.621,13.786],[-29.561,15.659],[31.953,21.997]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.352999997606,0.556999954523,0.607999973671,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[92.639,211.31],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 554","np":2,"cix":2,"ix":554,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900.000036657751,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Comp 1","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[118.5,118.5,0],"ix":2},"a":{"a":0,"k":[118.5,118.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[64.805,0],[0,-64.805],[-64.805,0],[0,64.805]],"o":[[-64.805,0],[0,64.805],[64.805,0],[0,-64.805]],"v":[[118.34,1],[1,118.34],[118.34,235.68],[235.68,118.34]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 2"}],"w":237,"h":237,"ip":0,"op":900.000036657751,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/loading_.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/loading_.json deleted file mode 100644 index 106bb561..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/loading_.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.2.1","fr":29.9700012207031,"ip":0,"op":61.0000024845809,"w":400,"h":400,"nm":"Comp 1","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Pre-comp 2","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.372,"y":0.995},"o":{"x":0.333,"y":0},"n":"0p372_0p995_0p333_0","t":-1,"s":[-63.707,132,0],"e":[508.793,132,0],"to":[95.4166641235352,0,0],"ti":[-95.4166641235352,0,0]},{"t":65.0000026475043}],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":400,"h":400,"ip":-1.00000004073083,"op":899.000036617021,"st":-1.00000004073083,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"Pre-comp 2","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.663,"y":0.994},"o":{"x":0.333,"y":0},"n":"0p663_0p994_0p333_0","t":47,"s":[-120.707,132,0],"e":[480.293,132,0],"to":[100.166664123535,0,0],"ti":[-100.166664123535,0,0]},{"t":120.0000048877}],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":400,"h":400,"ip":47.0000019143492,"op":947.000038572101,"st":47.0000019143492,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Master","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[198,192,0],"ix":2},"a":{"a":0,"k":[146.5,5.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.858,0],[0,0],[0,-2.858],[2.859,0],[0,0],[0,2.858]],"o":[[0,0],[2.859,0],[0,2.858],[0,0],[-2.858,0],[0,-2.858]],"v":[[-140.825,-5.175],[140.825,-5.175],[146,0.001],[140.825,5.175],[-140.825,5.175],[-146,0.001]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.913725490196,0.325490196078,0.129411764706,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[146.25,5.425],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900.000036657751,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Layer 5/progressbar-final Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[296,260,0],"ix":2},"a":{"a":0,"k":[76.5,5.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.858,0],[0,0],[0,-2.859],[2.859,0],[0,0],[0,2.857]],"o":[[0,0],[2.859,0],[0,2.857],[0,0],[-2.858,0],[0,-2.859]],"v":[[-70.825,-5.175],[70.825,-5.175],[76,0],[70.825,5.175],[-70.825,5.175],[-76,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.329411764706,0.709803921569,0.776470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[76.25,5.425],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900.000036657751,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Layer 3/progressbar-final Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[164,260,0],"ix":2},"a":{"a":0,"k":[40,5.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.858,0],[0,0],[0,-2.859],[2.858,0],[0,0],[0,2.857]],"o":[[0,0],[2.858,0],[0,2.857],[0,0],[-2.858,0],[0,-2.859]],"v":[[-34.325,-5.175],[34.325,-5.175],[39.5,0],[34.325,5.175],[-34.325,5.175],[-39.5,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.705882370472,0.243137255311,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[39.75,5.425],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900.000036657751,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Pre-comp 1","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[202.032,208.014,0],"ix":2},"a":{"a":0,"k":[200,200,0],"ix":1},"s":{"a":0,"k":[99.979,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[4.821,0],[0,0],[0,-4.821],[-4.821,0],[0,0],[0,2.771]],"o":[[0,0],[-4.821,0],[0,4.821],[0,0],[4.821,0],[0,-2.417]],"v":[[337.122,186.522],[59.625,186.49],[52.02,192.229],[59.708,197.449],[337.205,197.481],[343.914,191.917]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 2"}],"w":400,"h":400,"ip":0,"op":900.000036657751,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/loading_animation.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/loading_animation.json deleted file mode 100644 index c7de61b8..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/loading_animation.json +++ /dev/null @@ -1 +0,0 @@ -{"assets":[],"layers":[{"ddd":0,"ind":0,"ty":4,"nm":"形状图层 5","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":8,"s":[100],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":24,"s":[30],"e":[100]},{"t":40}]},"r":{"k":0},"p":{"k":[187.875,77.125,0]},"a":{"k":[-76.375,-2.875,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":8,"s":[100,100,100],"e":[200,200,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":24,"s":[200,200,100],"e":[100,100,100]},{"t":40}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[18,18]},"p":{"k":[0,0]},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0.87,0.42,0.56,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[-76.482,-3.482],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":40,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"形状图层 4","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":6,"s":[100],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":22,"s":[30],"e":[100]},{"t":36}]},"r":{"k":0},"p":{"k":[162.125,76.625,0]},"a":{"k":[-76.375,-2.875,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":6,"s":[100,100,100],"e":[200,200,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":22,"s":[200,200,100],"e":[100,100,100]},{"t":36}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[18,18]},"p":{"k":[0,0]},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0.81,0.55,0.82,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[-76.482,-3.482],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":40,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"形状图层 3","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":4,"s":[100],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":20,"s":[30],"e":[100]},{"t":32}]},"r":{"k":0},"p":{"k":[135.625,76.625,0]},"a":{"k":[-76.375,-2.875,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":4,"s":[100,100,100],"e":[200,200,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":20,"s":[200,200,100],"e":[100,100,100]},{"t":32}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[18,18]},"p":{"k":[0,0]},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0.47,0.31,0.62,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[-76.482,-3.482],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":40,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"形状图层 2","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":2,"s":[100],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":16,"s":[30],"e":[100]},{"t":28}]},"r":{"k":0},"p":{"k":[109.375,76.625,0]},"a":{"k":[-76.625,-3.125,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":2,"s":[100,100,100],"e":[200,200,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":16,"s":[200,200,100],"e":[100,100,100]},{"t":28}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[18,18]},"p":{"k":[0,0]},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0.54,0.81,0.89,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[-76.482,-3.482],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":40,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":4,"ty":4,"nm":"形状图层 1","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":0,"s":[100],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":12,"s":[30],"e":[100]},{"t":24}]},"r":{"k":0},"p":{"k":[82.625,76.625,0]},"a":{"k":[-76.625,-3.375,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":0,"s":[100,100,100],"e":[200,200,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_0p833_0p333_0","0p833_0p833_0p333_0","0p833_0p833_0p333_0p333"],"t":12,"s":[200,200,100],"e":[100,100,100]},{"t":24}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[18,18]},"p":{"k":[0,0]},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0.34,0.45,0.78,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[-76.482,-3.482],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":40,"st":0,"bm":0,"sr":1}],"v":"4.5.4","ddd":0,"ip":0,"op":40,"fr":24,"w":280,"h":160} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/loading_rectangles.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/loading_rectangles.json deleted file mode 100644 index eeb22358..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/loading_rectangles.json +++ /dev/null @@ -1 +0,0 @@ -{"ip":0,"fr":60,"v":"5.1.20","assets":[],"layers":[{"ty":4,"nm":"Rectangle","ip":0,"st":0,"ind":16,"hix":10,"ks":{"o":{"a":0,"k":100},"or":{"a":0,"k":[0,0,0]},"a":{"a":0,"k":[3.5,3.5,0]},"p":{"s":true,"x":{"a":1,"k":[{"t":0,"s":[35],"e":[42],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":20,"s":[42],"e":[42],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":153,"s":[42],"e":[35],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":173,"s":[35],"e":[35],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":179}]},"y":{"a":0,"k":12}},"rx":{"a":0,"k":0},"ry":{"a":0,"k":0},"rz":{"a":1,"k":[{"t":0,"s":[0],"e":[89.95437383553926],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":20,"s":[89.95437383553926],"e":[89.95437383553926],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":153,"s":[89.95437383553926],"e":[0],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":173}]},"s":{"a":0,"k":[100,100,100]}},"shapes":[{"ty":"gr","it":[{"ty":"rc","s":{"a":0,"k":[7,7]},"r":{"a":0,"k":0},"p":{"a":0,"k":[103.5,203.5]}},{"ty":"st","o":{"a":0,"k":0},"w":{"a":0,"k":0},"c":{"a":0,"k":[0,0,0,0]},"lc":3,"lj":1},{"ty":"fl","o":{"a":0,"k":100},"r":2,"c":{"a":0,"k":[0.07450980392156863,0.6941176470588235,0.8235294117647058,1]}},{"ty":"tr","o":{"a":0,"k":100},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[-100,-200]},"r":{"a":0,"k":0}}]}],"op":179},{"ty":4,"nm":"Rectangle","ip":0,"st":0,"ind":15,"hix":14,"ks":{"o":{"a":0,"k":100},"or":{"a":0,"k":[0,0,0]},"a":{"a":0,"k":[3.5,3.5,0]},"p":{"s":true,"x":{"a":1,"k":[{"t":0,"s":[34.961],"e":[42],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":20,"s":[42],"e":[42],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":153,"s":[42],"e":[35],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":173}]},"y":{"a":0,"k":20.509}},"rx":{"a":0,"k":0},"ry":{"a":0,"k":0},"rz":{"a":1,"k":[{"t":0,"s":[0],"e":[89.95437383553926],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":20,"s":[89.95437383553926],"e":[89.95437383553926],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":153,"s":[89.95437383553926],"e":[0],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":173}]},"s":{"a":0,"k":[100,100,100]}},"shapes":[{"ty":"gr","it":[{"ty":"rc","s":{"a":0,"k":[7,7]},"r":{"a":0,"k":0},"p":{"a":0,"k":[103.5,203.5]}},{"ty":"st","o":{"a":0,"k":0},"w":{"a":0,"k":0},"c":{"a":0,"k":[0,0,0,0]},"lc":3,"lj":1},{"ty":"fl","o":{"a":0,"k":100},"r":2,"c":{"a":0,"k":[0.07450980392156863,0.6941176470588235,0.8235294117647058,1]}},{"ty":"tr","o":{"a":0,"k":100},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[-100,-200]},"r":{"a":0,"k":0}}]}],"op":179},{"ty":4,"nm":"Rectangle","ip":0,"st":0,"ind":14,"hix":3,"ks":{"o":{"a":0,"k":100},"or":{"a":0,"k":[0,0,0]},"a":{"a":0,"k":[3.5,3.5,0]},"p":{"s":true,"x":{"a":1,"k":[{"t":0,"s":[35],"e":[42],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":20,"s":[42],"e":[42],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":153,"s":[42],"e":[35],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":173}]},"y":{"a":0,"k":30}},"rx":{"a":0,"k":0},"ry":{"a":0,"k":0},"rz":{"a":1,"k":[{"t":0,"s":[0],"e":[89.95437383553926],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":20,"s":[89.95437383553926],"e":[89.95437383553926],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":153,"s":[89.95437383553926],"e":[0],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":173}]},"s":{"a":0,"k":[100,100,100]}},"shapes":[{"ty":"gr","it":[{"ty":"rc","s":{"a":0,"k":[7,7]},"r":{"a":0,"k":0},"p":{"a":0,"k":[103.5,203.5]}},{"ty":"st","o":{"a":0,"k":0},"w":{"a":0,"k":0},"c":{"a":0,"k":[0,0,0,0]},"lc":3,"lj":1},{"ty":"fl","o":{"a":0,"k":100},"r":2,"c":{"a":0,"k":[0.07450980392156863,0.6941176470588235,0.8235294117647058,1]}},{"ty":"tr","o":{"a":0,"k":100},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[-100,-200]},"r":{"a":0,"k":0}}]}],"op":179},{"ty":4,"nm":"Rectangle","ip":0,"st":0,"ind":13,"hix":6,"ks":{"o":{"a":0,"k":100},"or":{"a":0,"k":[0,0,0]},"a":{"a":0,"k":[3.5,3.5,0]},"p":{"s":true,"x":{"a":1,"k":[{"t":0,"s":[35],"e":[42],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":20,"s":[42],"e":[42],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":153,"s":[42],"e":[35],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":173}]},"y":{"a":0,"k":39}},"rx":{"a":0,"k":0},"ry":{"a":0,"k":0},"rz":{"a":1,"k":[{"t":0,"s":[0],"e":[89.95437383553926],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":20,"s":[89.95437383553926],"e":[89.95437383553926],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":153,"s":[89.95437383553926],"e":[0],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":173}]},"s":{"a":0,"k":[100,100,100]}},"shapes":[{"ty":"gr","it":[{"ty":"rc","s":{"a":0,"k":[7,7]},"r":{"a":0,"k":0},"p":{"a":0,"k":[103.5,203.5]}},{"ty":"st","o":{"a":0,"k":0},"w":{"a":0,"k":0},"c":{"a":0,"k":[0,0,0,0]},"lc":3,"lj":1},{"ty":"fl","o":{"a":0,"k":100},"r":2,"c":{"a":0,"k":[0.07450980392156863,0.6941176470588235,0.8235294117647058,1]}},{"ty":"tr","o":{"a":0,"k":100},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[-100,-200]},"r":{"a":0,"k":0}}]}],"op":179},{"ty":4,"nm":"Rectangle","ip":0,"st":0,"ind":12,"hix":9,"ks":{"o":{"a":0,"k":100},"or":{"a":0,"k":[0,0,0]},"a":{"a":0,"k":[3.5,3.5,0]},"p":{"s":true,"x":{"a":1,"k":[{"t":0,"s":[26],"e":[26],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":21,"s":[26],"e":[33],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":41,"s":[33],"e":[33],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":132,"s":[33],"e":[26],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":152}]},"y":{"a":0,"k":12}},"rx":{"a":0,"k":0},"ry":{"a":0,"k":0},"rz":{"a":1,"k":[{"t":0,"s":[0],"e":[0],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":21,"s":[0],"e":[89.95437383553926],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":41,"s":[89.95437383553926],"e":[89.95437383553926],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":132,"s":[89.95437383553926],"e":[0],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":152}]},"s":{"a":0,"k":[100,100,100]}},"shapes":[{"ty":"gr","it":[{"ty":"rc","s":{"a":0,"k":[7,7]},"r":{"a":0,"k":0},"p":{"a":0,"k":[103.5,203.5]}},{"ty":"st","o":{"a":0,"k":0},"w":{"a":0,"k":0},"c":{"a":0,"k":[0,0,0,0]},"lc":3,"lj":1},{"ty":"fl","o":{"a":0,"k":100},"r":2,"c":{"a":0,"k":[0.07450980392156863,0.6941176470588235,0.8235294117647058,1]}},{"ty":"tr","o":{"a":0,"k":100},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[-100,-200]},"r":{"a":0,"k":0}}]}],"op":179},{"ty":4,"nm":"Rectangle","ip":0,"st":0,"ind":11,"hix":13,"ks":{"o":{"a":0,"k":100},"or":{"a":0,"k":[0,0,0]},"a":{"a":0,"k":[3.5,3.5,0]},"p":{"s":true,"x":{"a":1,"k":[{"t":0,"s":[26],"e":[26],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":21,"s":[26],"e":[33],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":41,"s":[33],"e":[33],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":132,"s":[33],"e":[26],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":152}]},"y":{"a":0,"k":21}},"rx":{"a":0,"k":0},"ry":{"a":0,"k":0},"rz":{"a":1,"k":[{"t":0,"s":[0],"e":[0],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":21,"s":[0],"e":[89.95437383553926],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":41,"s":[89.95437383553926],"e":[89.95437383553926],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":132,"s":[89.95437383553926],"e":[0],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":152}]},"s":{"a":0,"k":[100,100,100]}},"shapes":[{"ty":"gr","it":[{"ty":"rc","s":{"a":0,"k":[7,7]},"r":{"a":0,"k":0},"p":{"a":0,"k":[103.5,203.5]}},{"ty":"st","o":{"a":0,"k":0},"w":{"a":0,"k":0},"c":{"a":0,"k":[0,0,0,0]},"lc":3,"lj":1},{"ty":"fl","o":{"a":0,"k":100},"r":2,"c":{"a":0,"k":[0.07450980392156863,0.6941176470588235,0.8235294117647058,1]}},{"ty":"tr","o":{"a":0,"k":100},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[-100,-200]},"r":{"a":0,"k":0}}]}],"op":179},{"ty":4,"nm":"Rectangle","ip":0,"st":0,"ind":10,"hix":4,"ks":{"o":{"a":0,"k":100},"or":{"a":0,"k":[0,0,0]},"a":{"a":0,"k":[3.5,3.5,0]},"p":{"s":true,"x":{"a":1,"k":[{"t":0,"s":[26],"e":[26],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":21,"s":[26],"e":[33],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":41,"s":[33],"e":[33],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":132,"s":[33],"e":[26],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":152}]},"y":{"a":0,"k":30}},"rx":{"a":0,"k":0},"ry":{"a":0,"k":0},"rz":{"a":1,"k":[{"t":0,"s":[0],"e":[0],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":21,"s":[0],"e":[89.95437383553926],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":41,"s":[89.95437383553926],"e":[89.95437383553926],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":132,"s":[89.95437383553926],"e":[0],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":152}]},"s":{"a":0,"k":[100,100,100]}},"shapes":[{"ty":"gr","it":[{"ty":"rc","s":{"a":0,"k":[7,7]},"r":{"a":0,"k":0},"p":{"a":0,"k":[103.5,203.5]}},{"ty":"st","o":{"a":0,"k":0},"w":{"a":0,"k":0},"c":{"a":0,"k":[0,0,0,0]},"lc":3,"lj":1},{"ty":"fl","o":{"a":0,"k":100},"r":2,"c":{"a":0,"k":[0.07450980392156863,0.6941176470588235,0.8235294117647058,1]}},{"ty":"tr","o":{"a":0,"k":100},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[-100,-200]},"r":{"a":0,"k":0}}]}],"op":179},{"ty":4,"nm":"Rectangle","ip":0,"st":0,"ind":9,"hix":5,"ks":{"o":{"a":0,"k":100},"or":{"a":0,"k":[0,0,0]},"a":{"a":0,"k":[3.5,3.5,0]},"p":{"s":true,"x":{"a":1,"k":[{"t":0,"s":[26],"e":[26],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":21,"s":[26],"e":[33],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":41,"s":[33],"e":[33],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":132,"s":[33],"e":[26],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":152}]},"y":{"a":0,"k":39}},"rx":{"a":0,"k":0},"ry":{"a":0,"k":0},"rz":{"a":1,"k":[{"t":0,"s":[0],"e":[0],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":21,"s":[0],"e":[89.95437383553926],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":41,"s":[89.95437383553926],"e":[89.95437383553926],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":132,"s":[89.95437383553926],"e":[0],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":152}]},"s":{"a":0,"k":[100,100,100]}},"shapes":[{"ty":"gr","it":[{"ty":"rc","s":{"a":0,"k":[7,7]},"r":{"a":0,"k":0},"p":{"a":0,"k":[103.5,203.5]}},{"ty":"st","o":{"a":0,"k":0},"w":{"a":0,"k":0},"c":{"a":0,"k":[0,0,0,0]},"lc":3,"lj":1},{"ty":"fl","o":{"a":0,"k":100},"r":2,"c":{"a":0,"k":[0.07450980392156863,0.6941176470588235,0.8235294117647058,1]}},{"ty":"tr","o":{"a":0,"k":100},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[-100,-200]},"r":{"a":0,"k":0}}]}],"op":179},{"ty":4,"nm":"Rectangle","ip":0,"st":0,"ind":8,"hix":16,"ks":{"o":{"a":0,"k":100},"or":{"a":0,"k":[0,0,0]},"a":{"a":0,"k":[3.5,3.5,0]},"p":{"s":true,"x":{"a":1,"k":[{"t":0,"s":[17],"e":[17],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":43,"s":[17],"e":[24],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":63,"s":[24],"e":[24],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":111,"s":[24],"e":[17],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":131}]},"y":{"a":0,"k":12}},"rx":{"a":0,"k":0},"ry":{"a":0,"k":0},"rz":{"a":1,"k":[{"t":0,"s":[0],"e":[0],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":43,"s":[0],"e":[89.95437383553926],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":63,"s":[89.95437383553926],"e":[89.95437383553926],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":111,"s":[89.95437383553926],"e":[0],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":131}]},"s":{"a":0,"k":[100,100,100]}},"shapes":[{"ty":"gr","it":[{"ty":"rc","s":{"a":0,"k":[7,7]},"r":{"a":0,"k":0},"p":{"a":0,"k":[103.5,203.5]}},{"ty":"st","o":{"a":0,"k":0},"w":{"a":0,"k":0},"c":{"a":0,"k":[0,0,0,0]},"lc":3,"lj":1},{"ty":"fl","o":{"a":0,"k":100},"r":2,"c":{"a":0,"k":[0.07450980392156863,0.6941176470588235,0.8235294117647058,1]}},{"ty":"tr","o":{"a":0,"k":100},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[-100,-200]},"r":{"a":0,"k":0}}]}],"op":179},{"ty":4,"nm":"Rectangle","ip":0,"st":0,"ind":7,"hix":12,"ks":{"o":{"a":0,"k":100},"or":{"a":0,"k":[0,0,0]},"a":{"a":0,"k":[3.5,3.5,0]},"p":{"s":true,"x":{"a":1,"k":[{"t":0,"s":[17],"e":[17],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":43,"s":[17],"e":[24],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":63,"s":[24],"e":[24],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":111,"s":[24],"e":[17],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":131}]},"y":{"a":0,"k":21}},"rx":{"a":0,"k":0},"ry":{"a":0,"k":0},"rz":{"a":1,"k":[{"t":0,"s":[0],"e":[0],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":43,"s":[0],"e":[89.95437383553926],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":63,"s":[89.95437383553926],"e":[89.95437383553926],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":111,"s":[89.95437383553926],"e":[0],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":131}]},"s":{"a":0,"k":[100,100,100]}},"shapes":[{"ty":"gr","it":[{"ty":"rc","s":{"a":0,"k":[7,7]},"r":{"a":0,"k":0},"p":{"a":0,"k":[103.5,203.5]}},{"ty":"st","o":{"a":0,"k":0},"w":{"a":0,"k":0},"c":{"a":0,"k":[0,0,0,0]},"lc":3,"lj":1},{"ty":"fl","o":{"a":0,"k":100},"r":2,"c":{"a":0,"k":[0.07450980392156863,0.6941176470588235,0.8235294117647058,1]}},{"ty":"tr","o":{"a":0,"k":100},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[-100,-200]},"r":{"a":0,"k":0}}]}],"op":179},{"ty":4,"nm":"Rectangle","ip":0,"st":0,"ind":6,"hix":8,"ks":{"o":{"a":0,"k":100},"or":{"a":0,"k":[0,0,0]},"a":{"a":0,"k":[3.5,3.5,0]},"p":{"s":true,"x":{"a":1,"k":[{"t":0,"s":[17],"e":[17],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":43,"s":[17],"e":[24],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":63,"s":[24],"e":[24],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":111,"s":[24],"e":[17],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":131}]},"y":{"a":0,"k":30}},"rx":{"a":0,"k":0},"ry":{"a":0,"k":0},"rz":{"a":1,"k":[{"t":0,"s":[0],"e":[0],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":43,"s":[0],"e":[89.95437383553926],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":63,"s":[89.95437383553926],"e":[89.95437383553926],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":111,"s":[89.95437383553926],"e":[0],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":131}]},"s":{"a":0,"k":[100,100,100]}},"shapes":[{"ty":"gr","it":[{"ty":"rc","s":{"a":0,"k":[7,7]},"r":{"a":0,"k":0},"p":{"a":0,"k":[103.5,203.5]}},{"ty":"st","o":{"a":0,"k":0},"w":{"a":0,"k":0},"c":{"a":0,"k":[0,0,0,0]},"lc":3,"lj":1},{"ty":"fl","o":{"a":0,"k":100},"r":2,"c":{"a":0,"k":[0.07450980392156863,0.6941176470588235,0.8235294117647058,1]}},{"ty":"tr","o":{"a":0,"k":100},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[-100,-200]},"r":{"a":0,"k":0}}]}],"op":179},{"ty":4,"nm":"Rectangle","ip":0,"st":0,"ind":5,"hix":1,"ks":{"o":{"a":0,"k":100},"or":{"a":0,"k":[0,0,0]},"a":{"a":0,"k":[3.5,3.5,0]},"p":{"s":true,"x":{"a":1,"k":[{"t":0,"s":[17],"e":[17],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":43,"s":[17],"e":[24],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":63,"s":[24],"e":[24],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":111,"s":[24],"e":[17],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":131}]},"y":{"a":0,"k":39}},"rx":{"a":0,"k":0},"ry":{"a":0,"k":0},"rz":{"a":1,"k":[{"t":0,"s":[0],"e":[0],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":43,"s":[0],"e":[89.95437383553926],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":63,"s":[89.95437383553926],"e":[89.95437383553926],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":111,"s":[89.95437383553926],"e":[0],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":131}]},"s":{"a":0,"k":[100,100]}},"shapes":[{"ty":"gr","it":[{"ty":"rc","s":{"a":0,"k":[7,7]},"r":{"a":0,"k":0},"p":{"a":0,"k":[103.5,203.5]}},{"ty":"st","o":{"a":0,"k":0},"w":{"a":0,"k":0},"c":{"a":0,"k":[0,0,0,0]},"lc":3,"lj":1},{"ty":"fl","o":{"a":0,"k":100},"r":2,"c":{"a":0,"k":[0.07450980392156863,0.6941176470588235,0.8235294117647058,1]}},{"ty":"tr","o":{"a":0,"k":100},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[-100,-200]},"r":{"a":0,"k":0}}]}],"op":179},{"ty":4,"nm":"Rectangle","ip":0,"st":0,"ind":4,"hix":11,"ks":{"o":{"a":0,"k":100},"or":{"a":0,"k":[0,0,0]},"a":{"a":0,"k":[3.5,3.5,0]},"p":{"s":true,"x":{"a":1,"k":[{"t":0,"s":[8],"e":[8],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":64,"s":[8],"e":[15],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":84,"s":[15],"e":[15],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":90,"s":[15],"e":[8],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":110}]},"y":{"a":0,"k":12}},"rx":{"a":0,"k":0},"ry":{"a":0,"k":0},"rz":{"a":1,"k":[{"t":0,"s":[0],"e":[0],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":64,"s":[0],"e":[89.95437383553926],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":84,"s":[89.95437383553926],"e":[89.95437383553926],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":90,"s":[89.95437383553926],"e":[0],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":110}]},"s":{"a":0,"k":[100,100,100]}},"shapes":[{"ty":"gr","it":[{"ty":"rc","s":{"a":0,"k":[7,7]},"r":{"a":0,"k":0},"p":{"a":0,"k":[103.5,203.5]}},{"ty":"st","o":{"a":0,"k":0},"w":{"a":0,"k":0},"c":{"a":0,"k":[0,0,0,0]},"lc":3,"lj":1},{"ty":"fl","o":{"a":0,"k":100},"r":2,"c":{"a":0,"k":[0.07450980392156863,0.6941176470588235,0.8235294117647058,1]}},{"ty":"tr","o":{"a":0,"k":100},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[-100,-200]},"r":{"a":0,"k":0}}]}],"op":179},{"ty":4,"nm":"Rectangle","ip":0,"st":0,"ind":3,"hix":15,"ks":{"o":{"a":0,"k":100},"or":{"a":0,"k":[0,0,0]},"a":{"a":0,"k":[3.5,3.5,0]},"p":{"s":true,"x":{"a":1,"k":[{"t":0,"s":[8],"e":[8],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":64,"s":[8],"e":[15],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":84,"s":[15],"e":[15],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":90,"s":[15],"e":[8],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":110}]},"y":{"a":0,"k":21}},"rx":{"a":0,"k":0},"ry":{"a":0,"k":0},"rz":{"a":1,"k":[{"t":0,"s":[0],"e":[0],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":64,"s":[0],"e":[89.95437383553926],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":84,"s":[89.95437383553926],"e":[89.95437383553926],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":90,"s":[89.95437383553926],"e":[0],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":110}]},"s":{"a":0,"k":[100,100,100]}},"shapes":[{"ty":"gr","it":[{"ty":"rc","s":{"a":0,"k":[7,7]},"r":{"a":0,"k":0},"p":{"a":0,"k":[103.5,203.5]}},{"ty":"st","o":{"a":0,"k":0},"w":{"a":0,"k":0},"c":{"a":0,"k":[0,0,0,0]},"lc":3,"lj":1},{"ty":"fl","o":{"a":0,"k":100},"r":2,"c":{"a":0,"k":[0.07450980392156863,0.6941176470588235,0.8235294117647058,1]}},{"ty":"tr","o":{"a":0,"k":100},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[-100,-200]},"r":{"a":0,"k":0}}]}],"op":179},{"ty":4,"nm":"Rectangle","ip":0,"st":0,"ind":2,"hix":2,"ks":{"o":{"a":0,"k":100},"or":{"a":0,"k":[0,0,0]},"a":{"a":0,"k":[3.5,3.5,0]},"p":{"s":true,"x":{"a":1,"k":[{"t":0,"s":[8],"e":[8],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":64,"s":[8],"e":[15],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":84,"s":[15],"e":[15],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":90,"s":[15],"e":[8],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":110}]},"y":{"a":0,"k":30}},"rx":{"a":0,"k":0},"ry":{"a":0,"k":0},"rz":{"a":1,"k":[{"t":0,"s":[0],"e":[0],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":64,"s":[0],"e":[89.95437383553926],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":84,"s":[89.95437383553926],"e":[89.95437383553926],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":90,"s":[89.95437383553926],"e":[0],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":110}]},"s":{"a":0,"k":[100,100,100]}},"shapes":[{"ty":"gr","it":[{"ty":"rc","s":{"a":0,"k":[7,7]},"r":{"a":0,"k":0},"p":{"a":0,"k":[103.5,203.5]}},{"ty":"st","o":{"a":0,"k":0},"w":{"a":0,"k":0},"c":{"a":0,"k":[0,0,0,0]},"lc":3,"lj":1},{"ty":"fl","o":{"a":0,"k":100},"r":2,"c":{"a":0,"k":[0.07450980392156863,0.6941176470588235,0.8235294117647058,1]}},{"ty":"tr","o":{"a":0,"k":100},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[-100,-200]},"r":{"a":0,"k":0}}]}],"op":179},{"ty":4,"nm":"Rectangle","ip":0,"st":0,"ind":1,"hix":7,"ks":{"o":{"a":0,"k":100},"or":{"a":0,"k":[0,0,0]},"a":{"a":0,"k":[3.5,3.5,0]},"p":{"s":true,"x":{"a":1,"k":[{"t":0,"s":[8],"e":[8],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":64,"s":[8],"e":[15],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":84,"s":[15],"e":[15],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":90,"s":[15],"e":[8],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":110}]},"y":{"a":0,"k":39}},"rx":{"a":0,"k":0},"ry":{"a":0,"k":0},"rz":{"a":1,"k":[{"t":0,"s":[0],"e":[0],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":64,"s":[0],"e":[89.95437383553926],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":84,"s":[89.95437383553926],"e":[89.95437383553926],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":90,"s":[89.95437383553926],"e":[0],"i":{"x":[0.165],"y":[1]},"o":{"x":[0.075],"y":[0.82]}},{"t":110}]},"s":{"a":0,"k":[100,100,100]}},"shapes":[{"ty":"gr","it":[{"ty":"rc","s":{"a":0,"k":[7,7]},"r":{"a":0,"k":0},"p":{"a":0,"k":[103.5,203.5]}},{"ty":"st","o":{"a":0,"k":0},"w":{"a":0,"k":0},"c":{"a":0,"k":[0,0,0,0]},"lc":3,"lj":1},{"ty":"fl","o":{"a":0,"k":100},"r":2,"c":{"a":0,"k":[0.07450980392156863,0.6941176470588235,0.8235294117647058,1]}},{"ty":"tr","o":{"a":0,"k":100},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[-100,-200]},"r":{"a":0,"k":0}}]}],"op":179}],"op":179,"w":50,"h":50} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/looping_landscape_+_plane_+_clouds.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/looping_landscape_+_plane_+_clouds.json deleted file mode 100644 index 69667d5e..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/looping_landscape_+_plane_+_clouds.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.15","fr":29.9700012207031,"ip":0,"op":181.000007372281,"w":500,"h":500,"nm":"Comp 3","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"airplane Outlines Comp 2","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":0,"k":250,"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.483],"y":[1]},"o":{"x":[0.522],"y":[0]},"n":["0p483_1_0p522_0"],"t":0,"s":[286],"e":[247]},{"i":{"x":[0.483],"y":[1]},"o":{"x":[0.522],"y":[0]},"n":["0p483_1_0p522_0"],"t":45,"s":[247],"e":[286]},{"i":{"x":[0.483],"y":[1]},"o":{"x":[0.522],"y":[0]},"n":["0p483_1_0p522_0"],"t":90,"s":[286],"e":[247]},{"i":{"x":[0.483],"y":[1]},"o":{"x":[0.522],"y":[0]},"n":["0p483_1_0p522_0"],"t":135,"s":[247],"e":[286]},{"t":180.00000733155}],"ix":4}},"a":{"a":0,"k":[250,250,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":500,"h":500,"ip":0,"op":181.000007372281,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"airplane Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":0,"k":171,"ix":3},"y":{"a":0,"k":156,"ix":4}},"a":{"a":0,"k":[308,162,0],"ix":1},"s":{"a":0,"k":[33,33,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.598,1.031],[0.598,1.926],[1.367,2.859],[1.463,3.714],[3.834,9.806],[1.497,3.899],[-1.59,1.074],[-2.369,0.222]],"o":[[-2.597,-1.031],[-0.943,-3.036],[-1.723,-3.603],[-3.859,-9.796],[-1.521,-3.891],[-0.562,-1.466],[2.121,-1.434],[5.039,-0.471]],"v":[[14.439,35.096],[9.947,33.409],[5.171,22.045],[0.63,10.96],[-10.921,-18.438],[-15.535,-30.092],[-15.447,-34.507],[-10.602,-35.656]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.388000009574,0.109999997008,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[135.925,110.265],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.926,-2.258],[5.937,-0.916],[3.381,-0.041],[0.462,1.437],[0.228,1.682],[-0.76,0.55],[-0.841,-0.027],[-3.235,0.843],[-1.475,0.757],[-1.577,-0.747]],"o":[[-4.423,4.373],[-3.344,0.516],[-1.515,0.019],[-0.517,-1.606],[-0.113,-0.838],[0.675,-0.488],[3.344,0.11],[1.6,-0.418],[1.538,-0.789],[2.697,1.278]],"v":[[15.802,-0.585],[-1.706,6.298],[-11.804,7.074],[-14.306,5.769],[-14.953,0.346],[-15.042,-3.188],[-10.771,-2.931],[-0.857,-4.084],[3.778,-5.748],[7.276,-6.459]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[420.578,125.587],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.37,-2.974],[3.221,0.231],[-0.021,2.561],[-3.424,-0.271]],"o":[[-0.138,2.891],[-3.424,-0.246],[0.028,-3.477],[3.599,0.285]],"v":[[3.543,1.655],[-0.827,5.514],[-3.583,-1.527],[0.652,-5.475]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[246.836,143.219],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.219,-2.11],[0.935,-0.653],[0.791,0.21],[0.147,2.178],[-1.083,0.816],[-0.98,-0.109]],"o":[[-0.056,1.165],[-0.742,0.519],[-2.676,-0.711],[-0.077,-1.146],[0.8,-0.602],[2.792,0.308]],"v":[[3.586,2.477],[2.769,5.208],[-1.883,5.585],[-3.608,-1.783],[-2.914,-5.193],[1.768,-5.628]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[233.43,143.281],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.305,-1.54],[1.409,-0.465],[0.62,0.345],[-0.007,1.447],[-0.196,1.413],[-0.959,0.446],[-0.998,-0.352],[0.005,-1.349]],"o":[[-0.069,1.452],[-0.695,0.229],[-1.574,-0.881],[0.008,-1.423],[0.153,-1.107],[1.008,-0.467],[1.355,0.478],[-0.005,1.658]],"v":[[3.754,2.898],[2.365,5.494],[-2.484,5.459],[-3.348,0.791],[-3.503,-3.577],[-2.383,-5.202],[2.234,-5.453],[3.695,-2.683]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[220.185,143.344],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.342,-2.738],[4.203,0.301],[-0.02,2.559],[-3.424,-0.271]],"o":[[-0.161,3.412],[-3.425,-0.246],[0.029,-3.479],[3.149,0.249]],"v":[[3.726,0.217],[-0.643,5.48],[-3.4,-1.56],[0.836,-5.51]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[284.039,142.455],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.219,-2.11],[0.934,-0.653],[0.791,0.21],[0.147,2.178],[-1.083,0.816],[-0.98,-0.109]],"o":[[-0.056,1.165],[-0.743,0.519],[-2.675,-0.711],[-0.077,-1.145],[0.8,-0.602],[2.793,0.308]],"v":[[3.585,2.477],[2.769,5.208],[-1.884,5.585],[-3.609,-1.783],[-2.915,-5.193],[1.767,-5.628]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[271.62,142.483],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":2,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.305,-1.541],[1.41,-0.464],[0.619,0.346],[-0.007,1.447],[-0.196,1.414],[-0.959,0.446],[-0.998,-0.352],[0.005,-1.349]],"o":[[-0.068,1.451],[-0.695,0.229],[-1.575,-0.881],[0.008,-1.423],[0.154,-1.107],[1.008,-0.467],[1.355,0.478],[-0.005,1.658]],"v":[[3.754,2.899],[2.365,5.494],[-2.484,5.459],[-3.348,0.791],[-3.503,-3.577],[-2.384,-5.202],[2.234,-5.453],[3.695,-2.683]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[259.376,142.545],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.21,-2.737],[3.975,-0.155],[0.173,2.595],[-3.625,-0.115]],"o":[[0,3.365],[-3.587,0.141],[-0.239,-3.581],[3.095,0.099]],"v":[[3.628,0.036],[-0.231,5.519],[-3.598,-1.002],[0.403,-5.545]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[323.248,140.229],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":2,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.317,-2.093],[0.905,-0.698],[0.8,0.173],[0.275,2.164],[-1.039,0.862],[-0.983,-0.061]],"o":[[0,1.167],[-0.715,0.552],[-2.67,-0.576],[-0.146,-1.137],[0.771,-0.639],[2.762,0.174]],"v":[[3.745,2.267],[3.058,5.035],[-1.57,5.63],[-3.705,-1.646],[-3.177,-5.085],[1.478,-5.743]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[309.891,140.916],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10","np":2,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.234,-1.572],[1.385,-0.53],[0.634,0.316],[0.082,1.448],[-0.128,1.428],[-0.936,0.49],[-1.014,-0.304],[-0.067,-1.348]],"o":[[0,1.453],[-0.684,0.262],[-1.618,-0.807],[-0.081,-1.423],[0.1,-1.112],[0.985,-0.514],[1.379,0.415],[0.083,1.671]],"v":[[3.758,2.702],[2.494,5.36],[-2.351,5.555],[-3.448,0.933],[-3.863,-3.421],[-2.823,-5.097],[1.779,-5.567],[3.369,-2.869]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[297.841,141.537],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11","np":2,"cix":2,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.211,-2.737],[3.975,-0.155],[0.174,2.595],[-3.624,-0.115]],"o":[[0,3.365],[-3.588,0.141],[-0.239,-3.581],[3.095,0.099]],"v":[[3.627,0.036],[-0.231,5.519],[-3.599,-1.002],[0.402,-5.545]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[361.356,137.621],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12","np":2,"cix":2,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.317,-2.093],[0.904,-0.698],[0.799,0.173],[0.276,2.164],[-1.038,0.862],[-0.984,-0.061]],"o":[[0,1.167],[-0.716,0.552],[-2.67,-0.576],[-0.145,-1.137],[0.771,-0.639],[2.762,0.174]],"v":[[3.745,2.267],[3.058,5.035],[-1.57,5.63],[-3.706,-1.646],[-3.178,-5.085],[1.478,-5.743]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[347.999,138.309],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":2,"cix":2,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.099,-0.661],[1.385,-0.53],[0.634,0.316],[0.082,1.448],[-0.128,1.428],[-0.936,0.49],[-1.013,-0.303],[-0.077,-1.349],[-0.149,-1.144]],"o":[[0,1.453],[-0.683,0.263],[-1.617,-0.807],[-0.081,-1.423],[0.099,-1.112],[0.984,-0.514],[1.387,0.417],[0.067,1.147],[0.087,0.669]],"v":[[3.814,2.701],[2.549,5.359],[-2.296,5.555],[-3.392,0.932],[-3.807,-3.421],[-2.767,-5.098],[1.835,-5.568],[3.424,-2.87],[3.426,0.592]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[335.893,138.93],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 14","np":2,"cix":2,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.016,-1.26],[1.398,0.369],[2.542,0.926],[-1.355,1.046],[-1.081,-0.434]],"o":[[-0.473,1.62],[-2.612,-0.69],[0.826,-1.505],[0.93,-0.718],[-0.422,3.717]],"v":[[7.381,4.512],[0.405,3.532],[-7.38,1.283],[-2.685,-2.435],[2.368,-5.699]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[313.406,184.939],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 15","np":2,"cix":2,"ix":15,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.015,-1.26],[1.398,0.369],[2.542,0.927],[-1.355,1.045],[-1.081,-0.433]],"o":[[-0.472,1.621],[-2.612,-0.69],[0.826,-1.504],[0.93,-0.719],[-0.422,3.717]],"v":[[7.38,4.512],[0.405,3.532],[-7.38,1.283],[-2.685,-2.434],[2.368,-5.699]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[282.919,207.202],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 16","np":2,"cix":2,"ix":16,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-3.715,2.756]],"o":[[3.531,-2.62],[0,0]],"v":[[-5.388,3.997],[5.388,-3.997]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[309.889,183.041],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 17","np":2,"cix":2,"ix":17,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.492,1.688],[0.272,5.355],[1.081,-4.537],[2.1,-1.118]],"o":[[2.645,-4.72],[5.573,0.263],[-0.518,2.175],[-1.106,0.589]],"v":[[-4.549,7.195],[-1.272,-8.883],[3.961,1.907],[0.149,8.017]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.388000009574,0.109999997008,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[294.848,204.518],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 18","np":2,"cix":2,"ix":18,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.25,1.554],[0.077,4.041],[-2.095,0.215],[-0.541,-0.995],[1.77,-3.279],[1.349,-0.473]],"o":[[1.688,-3.707],[-0.024,-1.321],[1.348,-0.138],[1.825,3.365],[-0.654,1.212],[-1.244,0.434]],"v":[[-4.272,7.354],[-2.189,-4.542],[-0.702,-8.771],[2.697,-6.206],[2.419,5.562],[-0.419,8.404]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.388000009574,0.109999997008,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[324.796,181.514],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 19","np":2,"cix":2,"ix":19,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.791,-0.918],[1.427,0.118],[3.156,0.231],[6.602,0.452],[6.331,0.306],[3.053,0.088],[3.261,-0.433],[1.073,-0.072],[0.704,0.026],[1.62,0.091],[3.378,0.207],[6.39,0.592],[-1.025,1.446],[-1.367,-0.009],[-12.747,-0.079],[-13.231,0.001],[-13.377,-0.04],[-13.226,0.316],[-26.896,9.966],[3.97,-2.176],[4.464,-1.808],[10.053,-1.864],[10.403,0.282],[4.954,0.336]],"o":[[-0.766,-1.438],[-3.155,-0.261],[-6.6,-0.482],[-6.323,-0.433],[-3.051,-0.147],[-3.293,-0.095],[-0.732,0.098],[-0.695,0.046],[-1.621,-0.056],[-3.379,-0.189],[-6.406,-0.391],[-5.173,-0.48],[0.836,-1.179],[12.75,0.088],[13.219,0.083],[13.37,-0.001],[13.227,0.039],[28.623,-0.682],[-3.092,3.403],[-4.216,2.312],[-9.484,3.844],[-10.249,1.898],[-4.963,-0.134],[-4.907,-0.332]],"v":[[10.172,11.387],[2.9,10.612],[-6.57,9.959],[-26.37,8.534],[-45.341,7.383],[-54.492,6.915],[-64.758,6.786],[-66.46,7.219],[-68.623,7.159],[-73.485,6.923],[-83.623,6.372],[-102.811,4.641],[-124.922,1.099],[-116.123,0.665],[-77.897,2.227],[-38.229,3.641],[1.883,3.145],[41.568,2.997],[125.948,-12.505],[113.624,-4.824],[100.776,1.626],[71.219,10.064],[40.289,12.224],[25.409,11.583]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.388000009574,0.109999997008,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[318.804,156.823],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 20","np":2,"cix":2,"ix":20,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[1.871,-1.481]],"o":[[-2.036,1.259],[0,0]],"v":[[2.89,-2.113],[-2.89,2.113]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.736999990426,0.630999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[281.515,203.92],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 21","np":2,"cix":2,"ix":21,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[7.528,-5.601],[9.285,-2.444],[8.841,3.684],[-0.52,1.706],[-1.297,1.673],[-3.319,4.226],[-12.027,16.478],[-2.711,-0.042],[-2.578,-0.099],[-4.976,-0.27],[-10.094,-0.758],[-5.453,-0.195],[0.618,-1.37],[0.129,-1.813],[1.251,-1.933],[1.034,0.874],[0.503,0.884],[0.815,2.194],[4.162,-3.059],[2.24,-1.633],[0.098,-2.946],[0.553,-2.388],[1.286,-0.043],[0.538,1.071],[-0.249,2.195],[0.239,-0.262]],"o":[[-7.299,5.776],[-7.567,5.63],[-9.264,2.44],[-1.454,-0.606],[0.614,-2.018],[3.294,-4.246],[12.602,-16.045],[1.643,-2.252],[2.579,0.039],[4.979,0.192],[10.108,0.548],[5.448,0.409],[5.477,0.196],[-0.727,1.611],[-0.157,2.227],[-0.703,1.087],[-0.78,-0.659],[-1.2,-2.109],[-4.148,3.077],[-2.233,1.644],[-2.402,1.751],[-0.083,2.45],[-0.291,1.258],[-1.47,0.049],[-0.994,-1.982],[-0.35,-0.06],[0,0]],"v":[[12.576,4.679],[-10.116,21.414],[-34.467,35.704],[-62.215,33.783],[-65.924,31.119],[-61.282,25.09],[-51.357,12.387],[-13.544,-35.892],[-8.37,-37.708],[-0.631,-37.58],[14.31,-36.812],[44.615,-34.69],[60.967,-33.742],[56.585,-27.424],[56.454,-20.777],[54.854,-13.374],[52.959,-13.334],[51.033,-15.81],[49.228,-22.31],[36.776,-13.086],[30.07,-8.165],[27.54,-3.215],[26.585,4.09],[23.951,10.245],[20.323,6.638],[19.237,0.15],[18.355,0.454]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.736999990426,0.630999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[266.049,201.353],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 22","np":2,"cix":2,"ix":22,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[7.84,0.511],[7.063,1.032],[3.913,0.507],[1.482,2.51],[-10.394,2.32],[-2.203,1.462],[0.599,1.927],[1.367,2.858],[1.464,3.714],[3.834,9.807],[1.497,3.899],[-1.589,1.074],[-2.368,0.222],[-5.06,0.224],[-3.236,-2.538],[-2.264,-2.834],[-5.829,-7.099],[-7.289,0.926],[-4.326,0.434],[-5.253,0.419],[-21.223,1.596],[-21.192,1.79],[-10.319,-1.167],[-8.513,-2.913],[-2.975,-1.362],[-0.881,-2.233],[0,0],[-1.664,-4.53],[3.777,-2.334],[3.878,-0.953],[6.169,-1.391],[27.984,0.029],[28.318,1.106],[13.616,-0.203],[2.667,-0.879]],"o":[[-7.719,1.461],[-7.146,-0.466],[-3.903,-0.57],[-2.455,-0.317],[10.38,-2.385],[2.549,-0.57],[2.039,-1.354],[-0.942,-3.035],[-1.723,-3.604],[-3.859,-9.796],[-1.521,-3.89],[-0.563,-1.466],[2.122,-1.434],[5.04,-0.47],[4.009,-0.177],[2.875,2.255],[5.738,7.185],[3.94,4.798],[4.264,-0.542],[5.243,-0.527],[21.214,-1.694],[21.21,-1.595],[10.319,-0.873],[8.987,1.016],[3.094,1.059],[1.955,0.895],[0.394,0.997],[0,0],[1.563,4.255],[-3.454,2.135],[-6.137,1.51],[-27.392,6.18],[-28.338,-0.03],[-13.606,-0.531],[-2.788,0.042],[0,0]],"v":[[-105.346,43.51],[-128.865,44.958],[-150.003,41.878],[-161.777,40.638],[-171.746,37.675],[-140.602,30.525],[-131.998,28.917],[-131.476,22.615],[-135.249,13.86],[-139.79,2.775],[-151.341,-26.624],[-155.954,-38.278],[-155.867,-42.693],[-147.011,-43.842],[-131.896,-45.292],[-121.455,-42.588],[-114.079,-34.524],[-95.625,-14.056],[-79.528,-1.36],[-66.934,-3.816],[-51.172,-5.102],[12.498,-9.857],[76.074,-15.094],[107.163,-15.325],[133.099,-8.749],[142.261,-5.24],[149.265,-0.516],[159.633,6.553],[170.183,15.666],[166.337,26.531],[154.813,30.252],[136.442,34.908],[53.146,42.067],[-31.845,41.102],[-72.761,39.135],[-81.873,39.739]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.736999990426,0.630999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[276.746,118.45],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 23","np":2,"cix":2,"ix":23,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":181.000007372281,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"clouds","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[1033.524,248,0],"e":[187.524,248,0],"to":[-141,0,0],"ti":[141,0,0]},{"t":180.00000733155}],"ix":2},"a":{"a":0,"k":[2196,540,0],"ix":1},"s":{"a":0,"k":[47,47,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[11.064,4.762],[30.951,0],[8.265,-4.207],[21.629,0],[7.059,-25.76],[2.464,0],[0,-17.171],[-17.171,0],[-5.25,4.052],[-16.434,-1.579],[-7.154,0],[-5.251,4.051],[-18.832,0],[-10,7.225],[-4.433,0],[0,17.172]],"o":[[-3.807,-29.917],[-9.909,0],[-10.776,-17.013],[-28,0],[-2.298,-0.542],[-17.171,0],[0,17.172],[7.145,0],[9.976,12.028],[5.254,4.061],[7.145,0],[11.151,13.445],[13.28,0],[3.816,1.672],[17.171,0],[0,-12.809]],"v":[[-47.811,16.25],[-108.117,-36.795],[-135.641,-30.208],[-187.025,-58.523],[-245.66,-13.833],[-252.817,-14.663],[-283.909,16.429],[-252.817,47.521],[-233.841,41.057],[-192.903,62.765],[-173.909,69.249],[-154.932,62.786],[-108.117,84.795],[-72.555,73.31],[-60.091,75.912],[-29,44.82]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[5.786,2.49],[16.188,0],[3.692,-13.473],[1.289,0],[0,-8.98],[-8.98,0],[-2.746,2.118],[-9.849,0],[-5.23,3.778],[-2.318,0],[0,8.98]],"o":[[-1.991,-15.646],[-14.643,0],[-1.201,-0.284],[-8.98,0],[0,8.981],[3.737,0],[5.832,7.031],[6.945,0],[1.996,0.874],[8.981,0],[0,-6.7]],"v":[[-360.792,-57.053],[-392.332,-84.795],[-422.997,-61.422],[-426.74,-61.856],[-443,-45.596],[-426.74,-29.335],[-416.815,-32.715],[-392.332,-21.205],[-373.733,-27.211],[-367.215,-25.851],[-350.954,-42.111]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[11.064,4.762],[30.951,0],[7.059,-25.76],[2.464,0],[0,-17.172],[-17.171,0],[-5.251,4.051],[-18.832,0],[-10,7.225],[-4.433,0],[0,17.172]],"o":[[-3.807,-29.917],[-28,0],[-2.298,-0.542],[-17.171,0],[0,17.171],[7.145,0],[11.151,13.445],[13.28,0],[3.816,1.672],[17.171,0],[0,-12.809]],"v":[[-608.811,4.25],[-669.117,-48.795],[-727.751,-4.104],[-734.909,-4.934],[-766,26.158],[-734.909,57.249],[-715.932,50.786],[-669.117,72.795],[-633.555,61.31],[-621.091,63.912],[-590,32.82]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1825,154.205],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":5,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":181.000007372281,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"airplane Outlines Comp 1","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,210,0],"ix":2},"a":{"a":0,"k":[250,250,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":500,"h":500,"ip":0,"op":181.000007372281,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"mtns","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[1030,248,0],"e":[-188.5,248,0],"to":[-143.601577758789,0,0],"ti":[59.4817504882812,0,0]},{"t":180.00000733155}],"ix":2},"a":{"a":0,"k":[2196,540,0],"ix":1},"s":{"a":0,"k":[47,47,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.61,14.489],[0.21,0.149],[0,0],[0.211,0.009],[9.57,1.577],[0.341,0.064],[0.657,0.125],[13.041,3.439],[0.002,0],[1.507,0.41],[0.854,0.238],[0.611,0.172],[14.896,5.526],[60.277,62.679],[0.714,0.751],[1.274,1.366],[2.05,2.269],[0.018,0.02],[60.958,35.551],[7.491,3.977],[17.887,2.208],[5.46,0.026],[0.208,0],[1.066,-0.038],[0.349,-0.016],[0.929,-0.072],[0.396,-0.036],[0.915,-0.111],[0.366,-0.049],[1.25,-0.223],[0,0],[26.206,-14.118],[32.43,-30.952],[26.356,-29.184],[9.457,-9.595],[0.547,-0.552],[1.679,-1.67],[0.768,-0.76],[1.883,-1.831],[0.056,-0.054],[64.854,-35.334],[0.999,-0.538],[0.527,-0.283],[54.805,-3.732],[50.327,10.812],[4.412,1.089],[54.866,50.32],[0.912,1.21],[92.009,21.187],[1.955,0.414],[65.354,-60.475],[93.453,-26.693],[0.767,-0.215],[0.815,-0.225],[28.373,-0.015],[21.028,3.594],[1.666,0.301],[65.797,36.602],[0.66,0.371],[1.298,0.742],[7.052,4.451],[0.002,0.002],[71.948,65.843],[1.275,1.159],[0.007,0.006],[0.001,0.001],[49.021,-8.766],[0,0],[22.944,-11.286],[69.483,-69.397],[89.857,-48.282],[109.69,27.082],[189.604,40.129],[65.837,-56.311],[96.237,-27.193],[115.625,46.105],[75.301,78.995],[46.655,30.06],[18.918,-20.976],[0,-11.732],[0,-59.755],[0,-65.086],[-8.345,-44.467],[-10.661,-7.061],[-11.985,-0.023],[-454.578,-0.86],[-317.816,0],[-68.671,0.146],[0,0],[0,0],[0,0],[-402.384,0],[-248.062,0.554],[0,0],[0,0],[0,0],[0,39.129]],"o":[[-0.146,-0.156],[0,0],[-0.208,-0.009],[-7.431,-4.979],[-0.339,-0.063],[-0.657,-0.123],[-11.479,-2.209],[-0.001,0],[-1.488,-0.393],[-0.854,-0.234],[-0.608,-0.169],[-15.296,-4.32],[-81.578,-30.265],[-0.715,-0.745],[-1.287,-1.353],[-2.064,-2.216],[-0.018,-0.02],[-46.922,-51.959],[-7.749,-5.085],[-15.299,-9.572],[-5.639,-0.932],[-0.209,-0.001],[-1.073,0.002],[-0.35,0.012],[-0.935,0.044],[-0.397,0.031],[-0.92,0.083],[-0.367,0.045],[-1.26,0.17],[0,0],[-22.062,2.882],[-39.957,20.896],[-23.477,21.714],[-9.209,10.197],[-0.547,0.553],[-1.673,1.689],[-0.765,0.762],[-1.876,1.854],[-0.056,0.054],[-81.074,78.801],[-0.997,0.541],[-0.53,0.286],[-52.262,27.962],[-37.521,1.141],[-4.387,-0.981],[-78.168,-19.3],[-0.925,-1.189],[-61.212,-81.228],[-1.931,-0.447],[-87.139,-18.567],[-71.182,60.954],[-0.769,0.219],[-0.812,0.228],[-78.988,21.739],[-21.497,-0.675],[-1.668,-0.285],[-47.385,-8.71],[-0.661,-0.369],[-1.296,-0.728],[-7.251,-4.154],[-0.002,-0.001],[-83.553,-52.732],[-1.281,-1.178],[-0.007,-0.006],[-0.001,-0.001],[-64.051,-58.195],[0,0],[-20.423,1.711],[-90.114,44.325],[-72.161,72.071],[-98.652,53.009],[-183.691,-45.353],[-83.528,-17.678],[-73.713,63.046],[-119.458,33.754],[-102.983,-41.064],[-38.102,-39.971],[-15.687,-10.107],[-8.21,9.104],[0,59.755],[0,65.086],[0,45.114],[3.437,18.313],[10.202,6.756],[454.579,0.86],[317.816,0.601],[68.879,0],[0,0],[0,0],[0,0],[402.383,0.761],[250.056,0],[0,0],[0,0],[0,0],[0,-39.129],[0,-19.006]],"v":[[3636.482,83.226],[3635.941,82.768],[3636.482,82.727],[3635.839,82.696],[3576.718,75.489],[3575.705,75.301],[3573.735,74.924],[3536.878,66.517],[3536.874,66.516],[3532.373,65.303],[3529.81,64.599],[3527.977,64.084],[3482.667,49.281],[3266.653,-92.077],[3264.513,-94.331],[3260.663,-98.402],[3254.489,-105.125],[3254.437,-105.184],[3093.159,-255.292],[3070.293,-268.923],[3020.618,-286.821],[3003.969,-288.272],[3003.344,-288.268],[3000.134,-288.21],[2999.087,-288.166],[2996.292,-287.992],[2995.102,-287.897],[2992.351,-287.6],[2991.249,-287.469],[2987.482,-286.886],[2987.482,-286.556],[2915.225,-261.374],[2808.165,-181.338],[2733.476,-105.125],[2705.453,-75.439],[2703.811,-73.785],[2698.784,-68.744],[2696.48,-66.465],[2690.845,-60.928],[2690.679,-60.767],[2458.021,110.474],[2455.03,112.1],[2453.452,112.948],[2293.164,159.492],[2156.967,147.841],[2143.77,144.742],[1953.247,28.472],[1950.49,24.875],[1706.802,-135.827],[1700.978,-137.125],[1460.493,-80.263],[1236.844,59.061],[1234.537,59.719],[1232.095,60.394],[1055.004,82.945],[991.105,76.639],[986.104,75.75],[809.755,12.112],[807.772,11.005],[803.88,8.791],[782.416,-4.11],[782.408,-4.115],[569.203,-200.89],[565.37,-204.393],[565.349,-204.412],[565.347,-204.414],[395.483,-286.886],[395.483,-284.227],[330.668,-265.165],[107.855,-69.803],[-137.804,112.554],[-448.23,144.742],[-891.023,-137.125],[-1127.019,-84.104],[-1356.307,59.4],[-1714.042,44.391],[-1965.898,-144.477],[-2090.674,-255.062],[-2196.518,-286.886],[-2196.518,-212.645],[-2196.518,-33.379],[-2196.518,161.879],[-2196.518,305.79],[-2189.578,330.091],[-2128.795,330.206],[-765.061,332.786],[188.39,332.993],[394.672,332.747],[391.483,332.993],[1935.942,332.993],[1149.726,331.505],[2356.871,332.993],[3103.482,330.909],[3103.482,332.993],[3636.482,332.993],[3636.482,331.306],[3636.482,213.918]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.573000021542,0.423999980852,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[2196,747.209],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":181.000007372281,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"landscape Outlines 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[1030,248,0],"e":[-188.5,248,0],"to":[-203.08332824707,0,0],"ti":[203.08332824707,0,0]},{"t":180.00000733155}],"ix":2},"a":{"a":0,"k":[2196,540,0],"ix":1},"s":{"a":0,"k":[47,47,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.751,2.675],[-1.086,0.713],[-1.737,-2.684],[1.215,-0.768],[0.896,1.36]],"o":[[1.087,-0.713],[1.748,2.679],[0.897,1.386],[-1.133,0.716],[-1.761,-2.669]],"v":[[-4.698,-3.733],[-1.438,-5.872],[3.801,2.164],[3.342,5.155],[0.559,4.292]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.388000009574,0.109999997008,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[2439.327,541.702],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.283,-0.337],[-0.653,-1.408],[-1.484,-2.785],[-2.939,-4.867],[-2.639,-4.691],[-2.361,-5.025],[-1.359,-2.146],[-3.768,-5.981],[-2.447,-4.186],[-2.471,-3.836],[-0.651,-0.763],[3.766,-2.518],[0.367,0.847],[3.237,7.443],[5.035,11.603],[5.232,12.05],[2.95,6.762],[0.025,0.696]],"o":[[0.177,1.625],[1.335,2.876],[2.677,5.023],[2.783,4.609],[2.709,4.817],[1.076,2.292],[3.782,5.969],[2.576,4.09],[2.3,3.937],[0.527,0.818],[-3.785,2.492],[-0.807,0.54],[-3.216,-7.453],[-5.046,-11.599],[-5.229,-12.051],[-2.94,-6.767],[-0.233,-0.536],[0.285,0.338]],"v":[[-30.485,-57.183],[-28.527,-52.954],[-23.667,-44.802],[-15.093,-30.067],[-7.061,-16.047],[1.13,-1.623],[5.057,4.933],[15.762,23.21],[22.986,35.822],[29.979,47.575],[31.336,50.171],[19.99,57.656],[18.502,57.158],[8.784,34.83],[-6.335,0.027],[-22.013,-36.132],[-30.866,-56.418],[-31.336,-58.196]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[2399.309,490.258],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.177,1.625],[-5.21,-5.619],[-8.72,-9.418],[-12.031,-12.99],[-2.042,-2.197],[1.604,-1.051],[4.902,-3.215],[1.087,-0.713],[1.327,-0.82],[0.527,0.818],[2.3,3.937],[2.576,4.09],[3.782,5.969],[1.076,2.292],[2.709,4.817],[2.783,4.609],[2.677,5.023],[1.335,2.876]],"o":[[5.229,5.602],[8.727,9.411],[12.028,12.993],[2.038,2.2],[1.328,1.429],[-4.902,3.213],[-1.085,0.713],[-1.328,0.819],[-0.651,-0.763],[-2.471,-3.836],[-2.447,-4.186],[-3.768,-5.981],[-1.359,-2.146],[-2.361,-5.025],[-2.639,-4.691],[-2.939,-4.867],[-1.484,-2.785],[-0.653,-1.408]],"v":[[-42.686,-53.677],[-27.003,-36.868],[-0.854,-8.606],[35.24,30.364],[41.355,36.963],[41.081,39.434],[26.378,49.079],[23.119,51.218],[19.135,53.677],[17.778,51.081],[10.785,39.328],[3.561,26.716],[-7.144,8.439],[-11.071,1.883],[-19.262,-12.541],[-27.294,-26.561],[-35.868,-41.296],[-40.728,-49.448]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.736999990426,0.630999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[2411.51,486.752],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[2410.901,490.14],"ix":2},"a":{"a":0,"k":[2410.901,490.14],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"tree","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.11,1.983],[-0.806,0.046],[-0.1,-1.984],[0.893,-0.036],[0.06,1.01]],"o":[[0.807,-0.046],[0.108,1.986],[0.052,1.025],[-0.832,0.033],[-0.117,-1.983]],"v":[[-1.396,-3.589],[1.023,-3.727],[1.343,2.227],[0.166,3.694],[-1.063,2.363]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.388000009574,0.109999997008,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1212.631,600.389],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.047,-0.27],[0.086,-0.96],[0.067,-1.959],[-0.068,-3.532],[0.039,-3.344],[0.293,-3.437],[-0.065,-1.578],[-0.167,-4.39],[-0.015,-3.013],[-0.137,-2.833],[-0.113,-0.614],[2.81,-0.184],[-0.066,0.57],[-0.573,5.013],[-0.9,7.81],[-0.932,8.112],[-0.516,4.557],[-0.203,0.383]],"o":[[-0.411,0.93],[-0.176,1.963],[-0.122,3.536],[0.063,3.346],[-0.041,3.434],[-0.133,1.568],[0.178,4.388],[0.115,3.003],[0.013,2.833],[0.028,0.604],[-2.811,0.164],[-0.602,0.039],[0.588,-5.011],[0.893,-7.809],[0.934,-8.11],[0.523,-4.555],[0.041,-0.361],[0.048,0.27]],"v":[[4.623,-38.36],[4.36,-35.476],[4.441,-29.578],[4.472,-18.983],[4.432,-8.94],[4.354,1.368],[4.428,6.118],[4.504,19.281],[4.469,28.315],[4.577,36.814],[4.499,38.633],[-3.934,39.132],[-4.58,38.401],[-2.865,23.363],[-0.176,-0.066],[2.634,-24.398],[4.179,-38.067],[4.479,-39.17]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1203.828,558.252],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.411,0.93],[-1.056,-4.644],[-1.762,-7.779],[-2.434,-10.732],[-0.416,-1.817],[1.19,-0.068],[3.637,-0.205],[0.806,-0.046],[0.97,-0.029],[0.028,0.604],[0.013,2.833],[0.115,3.003],[0.178,4.388],[-0.133,1.568],[-0.041,3.434],[0.063,3.346],[-0.122,3.536],[-0.176,1.963]],"o":[[1.071,4.641],[1.769,7.779],[2.431,10.733],[0.413,1.817],[0.27,1.182],[-3.637,0.204],[-0.807,0.046],[-0.97,0.027],[-0.113,-0.614],[-0.137,-2.833],[-0.015,-3.013],[-0.167,-4.39],[-0.065,-1.578],[0.293,-3.437],[0.039,-3.344],[-0.068,-3.532],[0.067,-1.959],[0.086,-0.96]],"v":[[-8.433,-38.497],[-5.223,-24.574],[0.058,-1.234],[7.359,30.961],[8.598,36.414],[7.682,37.659],[-3.229,38.274],[-5.648,38.412],[-8.557,38.497],[-8.479,36.677],[-8.587,28.179],[-8.552,19.144],[-8.627,5.982],[-8.702,1.232],[-8.623,-9.076],[-8.584,-19.12],[-8.615,-29.714],[-8.695,-35.612]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.736999990426,0.630999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1216.884,558.388],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[1212.43,561.583],"ix":2},"a":{"a":0,"k":[1212.43,561.583],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"tree","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.774,2.661],[-1.082,-0.72],[1.787,-2.652],[1.183,0.816],[-0.899,1.358]],"o":[[1.082,0.721],[-1.778,2.658],[-0.923,1.368],[-1.103,-0.761],[1.764,-2.666]],"v":[[1.486,-5.849],[4.732,-3.69],[-0.605,4.282],[-3.536,5.034],[-3.833,2.133]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.388000009574,0.109999997008,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1451.969,669.11],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.199,-0.394],[1.039,-1.153],[1.979,-2.457],[3.324,-4.611],[3.28,-4.268],[3.696,-4.144],[1.441,-2.092],[4.024,-5.81],[2.891,-3.892],[2.56,-3.777],[0.446,-0.898],[3.794,2.477],[-0.636,0.669],[-5.577,5.897],[-8.699,9.183],[-9.031,9.541],[-5.064,5.366],[-0.631,0.295]],"o":[[-1.426,0.799],[-2.122,2.356],[-3.571,4.433],[-3.149,4.368],[-3.368,4.381],[-1.686,1.89],[-4.008,5.82],[-2.751,3.975],[-2.718,3.661],[-0.545,0.806],[-3.776,-2.504],[-0.813,-0.531],[5.594,-5.882],[8.69,-9.191],[9.034,-9.537],[5.072,-5.358],[0.401,-0.425],[-0.2,0.393]],"v":[[43.026,-48.898],[39.904,-45.439],[34.312,-37.771],[24.121,-24.105],[14.374,-11.216],[4.32,1.976],[-0.171,8.16],[-12.784,25.175],[-21.552,36.768],[-29.62,47.811],[-31.475,50.078],[-42.811,42.577],[-42.936,41.013],[-26.21,23.315],[-0.126,-4.244],[26.984,-32.849],[42.173,-48.949],[43.624,-50.078]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1481.105,610.484],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.426,0.799],[3.125,-6.998],[5.243,-11.715],[7.229,-16.163],[1.22,-2.74],[1.597,1.063],[4.88,3.247],[1.082,0.721],[1.274,0.9],[-0.545,0.806],[-2.718,3.661],[-2.751,3.975],[-4.008,5.82],[-1.686,1.89],[-3.368,4.381],[-3.149,4.368],[-3.571,4.433],[-2.122,2.356]],"o":[[-3.102,7.007],[-5.233,11.718],[-7.233,16.16],[-1.224,2.738],[-0.793,1.784],[-4.877,-3.249],[-1.082,-0.72],[-1.275,-0.9],[0.446,-0.898],[2.56,-3.777],[2.891,-3.892],[4.024,-5.81],[1.441,-2.092],[3.696,-4.144],[3.28,-4.268],[3.324,-4.611],[1.979,-2.457],[1.039,-1.153]],"v":[[37.25,-57.321],[27.939,-36.302],[12.199,-1.163],[-9.489,47.324],[-13.161,55.537],[-15.542,56.255],[-30.18,46.514],[-33.426,44.354],[-37.251,41.655],[-35.396,39.388],[-27.328,28.345],[-18.56,16.752],[-5.947,-0.263],[-1.456,-6.447],[8.598,-19.639],[18.345,-32.528],[28.536,-46.194],[34.128,-53.862]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.736999990426,0.630999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1486.881,618.907],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[1481.209,618.147],"ix":2},"a":{"a":0,"k":[1481.209,618.147],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"tree","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.808,2.126],[-0.864,-0.328],[0.82,-2.122],[0.95,0.379],[-0.408,1.084]],"o":[[0.865,0.328],[-0.811,2.125],[-0.422,1.096],[-0.885,-0.353],[0.801,-2.129]],"v":[[0.119,-4.361],[2.712,-3.378],[0.275,2.996],[-1.638,3.982],[-2.304,2.018]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.388000009574,0.109999997008,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1394.337,637.817],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.076,-0.304],[0.537,-0.964],[0.983,-2.018],[1.574,-3.724],[1.599,-3.479],[1.905,-3.459],[0.668,-1.68],[1.869,-4.667],[1.387,-3.158],[1.176,-3.025],[0.168,-0.693],[3.023,1.116],[-0.335,0.564],[-2.931,4.973],[-4.575,7.746],[-4.75,8.048],[-2.661,4.523],[-0.391,0.305]],"o":[[-0.862,0.78],[-1.098,1.97],[-1.773,3.639],[-1.49,3.529],[-1.64,3.572],[-0.87,1.577],[-1.856,4.671],[-1.277,3.192],[-1.305,2.969],[-0.251,0.645],[-3.015,-1.137],[-0.648,-0.239],[2.947,-4.966],[4.569,-7.751],[4.753,-8.046],[2.667,-4.519],[0.211,-0.359],[-0.076,0.304]],"v":[[22.729,-39.765],[21.113,-36.87],[18.451,-30.667],[13.551,-19.576],[8.836,-9.094],[3.957,1.648],[1.823,6.648],[-4.225,20.446],[-8.466,29.875],[-12.31,38.812],[-13.238,40.677],[-22.287,37.273],[-22.622,36.209],[-13.83,21.286],[-0.113,-1.958],[14.151,-26.092],[22.13,-39.664],[22.957,-40.677]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1404.613,591.514],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 14","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.862,0.78],[1.057,-5.347],[1.778,-8.954],[2.45,-12.354],[0.411,-2.093],[1.275,0.484],[3.898,1.478],[0.865,0.328],[0,0],[-0.251,0.645],[-1.305,2.969],[-1.277,3.192],[-1.856,4.671],[-0.87,1.577],[-1.64,3.572],[-1.49,3.529],[-1.773,3.639],[-1.098,1.97]],"o":[[-1.04,5.351],[-1.771,8.956],[-2.453,12.353],[-0.415,2.091],[-0.268,1.362],[-3.898,-1.479],[-0.864,-0.328],[0,0],[0.168,-0.693],[1.176,-3.025],[1.387,-3.158],[1.869,-4.667],[0.668,-1.68],[1.905,-3.459],[1.599,-3.479],[1.574,-3.724],[0.983,-2.018],[0.537,-0.964]],"v":[[17.984,-43.805],[14.86,-27.754],[9.517,-0.893],[2.167,36.167],[0.922,42.443],[-0.615,43.318],[-12.31,38.885],[-14.903,37.902],[-17.984,36.636],[-17.056,34.771],[-13.212,25.835],[-8.971,16.406],[-2.922,2.608],[-0.789,-2.392],[4.09,-13.134],[8.805,-23.616],[13.705,-34.707],[16.367,-40.911]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.736999990426,0.630999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1409.359,595.554],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 15","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[1404.674,596.399],"ix":2},"a":{"a":0,"k":[1404.674,596.399],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"tree","np":3,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.242,3.188],[-1.296,-0.097],[0.258,-3.187],[1.431,0.132],[-0.117,1.623]],"o":[[1.296,0.098],[-0.247,3.188],[-0.133,1.645],[-1.335,-0.122],[0.231,-3.189]],"v":[[-1.523,-6.039],[2.365,-5.747],[1.62,3.817],[-0.567,5.908],[-2.248,3.527]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.388000009574,0.109999997008,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1340.408,615.814],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 16","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.019,-0.44],[0.339,-1.513],[0.521,-3.112],[0.638,-5.649],[0.768,-5.327],[1.191,-5.422],[0.231,-2.53],[0.659,-7.038],[0.611,-4.809],[0.379,-4.547],[-0.051,-1.002],[4.521,0.299],[-0.227,0.894],[-1.97,7.875],[-3.08,12.267],[-3.196,12.742],[-1.784,7.159],[-0.405,0.567]],"o":[[-0.851,1.396],[-0.695,3.094],[-0.939,5.614],[-0.603,5.352],[-0.788,5.469],[-0.543,2.474],[-0.64,7.037],[-0.45,4.813],[-0.576,4.523],[-0.081,0.97],[-4.518,-0.332],[-0.969,-0.065],[1.993,-7.869],[3.07,-12.27],[3.201,-12.741],[1.795,-7.156],[0.141,-0.567],[0.019,0.441]],"v":[[15.542,-60.733],[14.517,-56.188],[13.4,-46.763],[11.216,-29.856],[9.038,-13.844],[6.74,2.582],[5.857,10.174],[3.204,31.188],[1.244,45.59],[-0.376,59.169],[-0.883,62.055],[-14.44,61.074],[-15.315,59.772],[-9.411,36.146],[-0.184,-0.659],[9.426,-38.881],[14.774,-60.359],[15.485,-62.055]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995999983245,0.313999998803,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1335.109,547.242],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 17","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.851,1.396],[-0.706,-7.63],[-1.172,-12.782],[-1.621,-17.632],[-0.28,-2.985],[1.912,0.145],[5.845,0.438],[1.296,0.097],[1.553,0.159],[-0.081,0.97],[-0.576,4.523],[-0.45,4.813],[-0.64,7.037],[-0.543,2.474],[-0.788,5.469],[-0.603,5.352],[-0.939,5.614],[-0.695,3.094]],"o":[[0.73,7.628],[1.183,12.78],[1.616,17.63],[0.274,2.986],[0.183,1.943],[-5.844,-0.441],[-1.296,-0.097],[-1.553,-0.16],[-0.051,-1.002],[0.379,-4.547],[0.611,-4.809],[0.659,-7.038],[0.231,-2.53],[1.191,-5.422],[0.768,-5.327],[0.638,-5.649],[0.521,-3.112],[0.339,-1.513]],"v":[[2.455,-62.511],[4.641,-39.627],[8.146,-1.282],[13.008,51.611],[13.833,60.569],[12.109,62.362],[-5.424,61.047],[-9.312,60.755],[-13.97,60.277],[-13.464,57.391],[-11.844,43.812],[-9.883,29.41],[-7.23,8.396],[-6.347,0.804],[-4.049,-15.622],[-1.871,-31.634],[0.312,-48.541],[1.43,-57.966]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.736999990426,0.630999995213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1348.197,549.02],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 18","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[1340.902,553.463],"ix":2},"a":{"a":0,"k":[1340.902,553.463],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"tree","np":3,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":181.000007372281,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"landscape Outlines 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[1030,248,0],"e":[-188.5,248,0],"to":[-203.08332824707,0,0],"ti":[203.08332824707,0,0]},{"t":180.00000733155}],"ix":2},"a":{"a":0,"k":[2196,540,0],"ix":1},"s":{"a":0,"k":[47,47,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[433.5,98.5],[-433.5,98.5],[-433.5,-98.5],[433.5,-98.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.788000009574,0.204000001795,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1928.5,867.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"water","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":181.000007372281,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"bg","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[637.372,248,0],"ix":2},"a":{"a":0,"k":[2196,540,0],"ix":1},"s":{"a":0,"k":[47,47,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2195.5,539],[2195.5,539],[2195.5,-539],[-2195.5,-539]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.75117534399,0.894179105759,0.96685051918,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[2195.5,541],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"bg","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":181.000007372281,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/maps.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/maps.json deleted file mode 100644 index 7bb4d8dd..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/maps.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.16","fr":30,"ip":0,"op":132,"w":200,"h":85,"nm":"city 200x85","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[8.25,92.375,0],"e":[9,73.375,0],"to":[0.125,-3.16666674613953,0],"ti":[-1.29166662693024,5.75,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":5,"s":[9,73.375,0],"e":[16,57.875,0],"to":[1.29166662693024,-5.75,0],"ti":[-2.22916674613953,0.60416668653488,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":12.5,"s":[16,57.875,0],"e":[22.375,69.75,0],"to":[2.22916674613953,-0.60416668653488,0],"ti":[-2.75,-2.9375,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":13.75,"s":[22.375,69.75,0],"e":[32.5,75.5,0],"to":[2.75,2.9375,0],"ti":[-3.20833325386047,-1.41666662693024,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":15,"s":[32.5,75.5,0],"e":[41.625,78.25,0],"to":[3.20833325386047,1.41666662693024,0],"ti":[-2.39583325386047,0.60416668653488,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":16.25,"s":[41.625,78.25,0],"e":[46.875,71.875,0],"to":[2.39583325386047,-0.60416668653488,0],"ti":[-2.3125,0.10416666418314,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17.5,"s":[46.875,71.875,0],"e":[55.5,77.625,0],"to":[2.3125,-0.10416666418314,0],"ti":[-1.64583337306976,1.89583337306976,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":18.75,"s":[55.5,77.625,0],"e":[56.75,60.5,0],"to":[1.64583337306976,-1.89583337306976,0],"ti":[-0.20833332836628,5.29166650772095,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[56.75,60.5,0],"e":[56.75,45.875,0],"to":[0.20833332836628,-5.29166650772095,0],"ti":[-0.20833332836628,4.41666650772095,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":21.25,"s":[56.75,45.875,0],"e":[58,34,0],"to":[0.20833332836628,-4.41666650772095,0],"ti":[-0.95833331346512,3.02083325386047,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22.5,"s":[58,34,0],"e":[62.5,27.75,0],"to":[0.95833331346512,-3.02083325386047,0],"ti":[-1.66666662693024,1.52083337306976,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":23.75,"s":[62.5,27.75,0],"e":[68,24.875,0],"to":[1.66666662693024,-1.52083337306976,0],"ti":[-0.9375,2.79166674613953,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":27.5,"s":[68,24.875,0],"e":[68.125,11,0],"to":[0.9375,-2.79166674613953,0],"ti":[-0.33333334326744,3.14583325386047,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":28.75,"s":[68.125,11,0],"e":[70,6,0],"to":[0.33333334326744,-3.14583325386047,0],"ti":[-0.70833331346512,-2.25,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":30,"s":[70,6,0],"e":[72.375,24.5,0],"to":[0.70833331346512,2.25,0],"ti":[-0.39583334326744,-3.08333325386047,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":31.25,"s":[72.375,24.5,0],"e":[72.375,24.5,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":35,"s":[72.375,24.5,0],"e":[78.125,27,0],"to":[0.95833331346512,0.41666665673256,0],"ti":[-1.64583337306976,-1.60416662693024,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":36.25,"s":[78.125,27,0],"e":[82.25,34.125,0],"to":[1.64583337306976,1.60416662693024,0],"ti":[-0.6875,-4.79166650772095,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":37.5,"s":[82.25,34.125,0],"e":[82.25,55.75,0],"to":[0.6875,4.79166650772095,0],"ti":[-1.27083337306976,-3.60416674613953,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":38.75,"s":[82.25,55.75,0],"e":[89.875,55.75,0],"to":[1.27083337306976,3.60416674613953,0],"ti":[-1.27083337306976,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":40,"s":[89.875,55.75,0],"e":[89.875,55.75,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":43.75,"s":[89.875,55.75,0],"e":[93.875,73,0],"to":[0.66666668653488,2.875,0],"ti":[-0.875,-4.39583349227905,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":45,"s":[93.875,73,0],"e":[95.125,82.125,0],"to":[0.875,4.39583349227905,0],"ti":[-0.20833332836628,2.89583325386047,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":46.25,"s":[95.125,82.125,0],"e":[95.162,83.291,0],"to":[0.08235409110785,-1.14472186565399,0],"ti":[0.03311010077596,4.17439985275269,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":47.5,"s":[95.162,83.291,0],"e":[95.125,55.625,0],"to":[-0.05064940080047,-6.38569068908691,0],"ti":[-0.113381318748,3.3510479927063,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":50,"s":[95.125,55.625,0],"e":[96.25,48.875,0],"to":[0.1875,-5.54166650772095,0],"ti":[-2.8125,1.10416662693024,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":56.25,"s":[96.25,48.875,0],"e":[112,49,0],"to":[2.8125,-1.10416662693024,0],"ti":[-2.625,-3.1875,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":62.5,"s":[112,49,0],"e":[112,68,0],"to":[2.625,3.1875,0],"ti":[0,-4.64583349227905,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":65,"s":[112,68,0],"e":[112,76.875,0],"to":[0,4.64583349227905,0],"ti":[-2.5625,-1.47916662693024,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":67.5,"s":[112,76.875,0],"e":[127.375,76.875,0],"to":[2.5625,1.47916662693024,0],"ti":[-2.5625,6.52083349227905,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":75,"s":[127.375,76.875,0],"e":[127.375,37.75,0],"to":[2.5625,-6.52083349227905,0],"ti":[-2.20833325386047,7.75,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":80,"s":[127.375,37.75,0],"e":[140.625,30.375,0],"to":[2.20833325386047,-7.75,0],"ti":[-2.4375,4,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":82.5,"s":[140.625,30.375,0],"e":[142,13.75,0],"to":[2.4375,-4,0],"ti":[-2.77083325386047,-3.08333325386047,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":83.75,"s":[142,13.75,0],"e":[157.25,48.875,0],"to":[2.77083325386047,3.08333325386047,0],"ti":[-8.125,-6.14583349227905,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":85,"s":[157.25,48.875,0],"e":[190.75,50.625,0],"to":[8.125,6.14583349227905,0],"ti":[-5.58333349227905,-7.95833349227905,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":92.5,"s":[190.75,50.625,0],"e":[190.75,96.625,0],"to":[5.58333349227905,7.95833349227905,0],"ti":[0,-7.66666650772095,0]},{"t":97.5}],"ix":2},"a":{"a":0,"k":[-12,-6.5,0],"ix":1},"s":{"a":0,"k":[39.083,39.083,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[26.875,26.875],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.941176530427,0.466666696586,0.18431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-12.393,-6.871],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":132,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"melbourne_orange Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":80,"s":[100.25,42.75,0],"e":[100,42.5,0],"to":[-0.04166666790843,-0.04166666790843,0],"ti":[0.04166666790843,0.04166666790843,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":97.5,"s":[100,42.5,0],"e":[100,42.5,0],"to":[0,0,0],"ti":[0,0,0]},{"t":195}],"ix":2},"a":{"a":0,"k":[92.5,42.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[6,86],[-11,86],[-8,102],[6,102.5],[6,96.899],[6,96.152],[6,95.43],[6,95.335],[6,95.291],[6,95.253],[6,95.253],[6,95.253],[6,95.253],[6,95.243],[6,95.241],[6,95.189],[6,95.107],[6,94.9],[6,94.729],[6,93.699]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[6,73.656],[-11,73.656],[-8,89.656],[6,90.156],[6,84.556],[6,83.808],[6,83.086],[6,82.991],[6,82.947],[6,82.909],[6,82.909],[6,82.909],[6,82.909],[6,82.899],[6,82.897],[6,82.845],[6,82.763],[6,82.556],[6,82.385],[6,81.355]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":5,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[6,73.656],[-11,73.656],[-8,89.656],[6,90.156],[6,84.556],[6,83.808],[6,83.086],[6,82.991],[6,82.947],[6,82.909],[6,82.909],[6,82.909],[6,82.909],[6,82.899],[6,82.897],[6,82.845],[6,82.763],[6,82.556],[6,82.385],[6,81.355]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[3.5,41.5],[-13.5,41.5],[-8,89.5],[6,90],[5.151,73.537],[5.038,71.339],[4.929,69.217],[4.914,68.939],[4.908,68.809],[4.902,68.698],[4.902,68.698],[4.902,68.698],[4.902,68.697],[4.9,68.668],[4.9,68.663],[4.892,68.509],[4.88,68.269],[4.848,67.661],[4.823,67.158],[4.667,64.131]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":12.5,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[3.5,41.5],[-13.5,41.5],[-8,89.5],[6,90],[5.151,73.537],[5.038,71.339],[4.929,69.217],[4.914,68.939],[4.908,68.809],[4.902,68.698],[4.902,68.698],[4.902,68.698],[4.902,68.697],[4.9,68.668],[4.9,68.663],[4.892,68.509],[4.88,68.269],[4.848,67.661],[4.823,67.158],[4.667,64.131]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[46,51],[-13.5,41.5],[-8,89.5],[6,90],[46.522,85.525],[46.486,83.156],[46.452,80.869],[46.447,80.569],[46.445,80.429],[46.443,80.309],[46.443,80.309],[46.443,80.309],[46.443,80.309],[46.443,80.278],[46.442,80.272],[46.44,80.106],[46.436,79.847],[46.426,79.192],[46.418,78.65],[46.369,75.388]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":18.75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[46,51],[-13.5,41.5],[-8,89.5],[6,90],[46.522,85.525],[46.486,83.156],[46.452,80.869],[46.447,80.569],[46.445,80.429],[46.443,80.309],[46.443,80.309],[46.443,80.309],[46.443,80.309],[46.443,80.278],[46.442,80.272],[46.44,80.106],[46.436,79.847],[46.426,79.192],[46.418,78.65],[46.369,75.388]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-15.5],[-13.5,41.5],[-8,89.5],[6,90],[46.522,85.525],[61.438,75.001],[59.396,48.603],[59.127,45.134],[59.002,43.519],[58.895,42.138],[58.895,42.135],[58.895,42.135],[58.895,42.13],[58.867,41.77],[58.862,41.702],[58.714,39.791],[58.483,36.802],[57.897,29.236],[57.413,22.983],[54.499,-14.678]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":26.25,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-15.5],[-13.5,41.5],[-8,89.5],[6,90],[46.522,85.525],[61.438,75.001],[59.396,48.603],[59.127,45.134],[59.002,43.519],[58.895,42.138],[58.895,42.135],[58.895,42.135],[58.895,42.13],[58.867,41.77],[58.862,41.702],[58.714,39.791],[58.483,36.802],[57.897,29.236],[57.413,22.983],[54.499,-14.678]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-15.5],[-13.5,41.5],[-8,89.5],[6,90],[46.522,85.525],[61.438,75.001],[63.736,48.78],[64.038,45.335],[64.178,43.731],[64.298,42.359],[64.299,42.357],[64.299,42.356],[64.299,42.352],[64.33,41.994],[64.336,41.926],[64.503,40.028],[64.763,37.059],[65.421,29.545],[64.827,-14.457],[54.499,-14.678]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":35,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-15.5],[-13.5,41.5],[-8,89.5],[6,90],[46.522,85.525],[61.438,75.001],[63.736,48.78],[64.038,45.335],[64.178,43.731],[64.298,42.359],[64.299,42.357],[64.299,42.356],[64.299,42.352],[64.33,41.994],[64.336,41.926],[64.503,40.028],[64.763,37.059],[65.421,29.545],[64.827,-14.457],[54.499,-14.678]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-15.5],[-13.5,41.5],[-8,89.5],[6,90],[46.522,85.525],[61.438,75.001],[81.251,58.077],[81.371,51.622],[81.427,48.619],[81.475,46.048],[81.475,46.044],[81.475,46.043],[81.475,46.035],[81.488,45.365],[81.49,45.237],[81.556,41.682],[81.659,36.12],[81.921,22.045],[64.827,-14.457],[54.499,-14.678]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":41.25,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-15.5],[-13.5,41.5],[-8,89.5],[6,90],[46.522,85.525],[61.438,75.001],[81.251,58.077],[81.371,51.622],[81.427,48.619],[81.475,46.048],[81.475,46.044],[81.475,46.043],[81.475,46.035],[81.488,45.365],[81.49,45.237],[81.556,41.682],[81.659,36.12],[81.921,22.045],[64.827,-14.457],[54.499,-14.678]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.336,2.318],[0.38,2.831],[0,0],[0.002,0.016],[0.01,0.074],[0.147,1.172],[0.048,0.39],[-0.398,0.146],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.303,-2.09],[-0.005,-0.04],[0,0],[-0.01,-0.074],[-0.158,-1.185],[-0.05,-0.398],[-0.617,-5.064],[0.985,-0.361],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-15.5],[-13.5,41.5],[-8,89.5],[6,90],[46.522,85.525],[61.438,75.001],[71.251,96.577],[91.432,85.489],[90.865,81.643],[89.794,73.991],[89.778,73.87],[89.772,73.822],[89.742,73.599],[89.281,70.045],[89.135,68.862],[88.515,59.361],[79.814,42.439],[81.921,22.045],[64.827,-14.457],[54.499,-14.678]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":50,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.336,2.318],[0.38,2.831],[0,0],[0.002,0.016],[0.01,0.074],[0.147,1.172],[0.048,0.39],[-0.398,0.146],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.303,-2.09],[-0.005,-0.04],[0,0],[-0.01,-0.074],[-0.158,-1.185],[-0.05,-0.398],[-0.617,-5.064],[0.985,-0.361],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-15.5],[-13.5,41.5],[-8,89.5],[6,90],[46.522,85.525],[61.438,75.001],[71.251,96.577],[91.432,85.489],[90.865,81.643],[89.794,73.991],[89.778,73.87],[89.772,73.822],[89.742,73.599],[89.281,70.045],[89.135,68.862],[88.515,59.361],[79.814,42.439],[81.921,22.045],[64.827,-14.457],[54.499,-14.678]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.605,4.652],[0.707,5.67],[0.01,0.081],[0.004,0.032],[0.019,0.149],[0.282,2.343],[0.093,0.78],[-0.398,0.146],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.546,-4.194],[-0.01,-0.081],[-0.004,-0.032],[-0.019,-0.149],[-0.295,-2.373],[-0.096,-0.796],[-1.201,-10.121],[0.985,-0.361],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-15.5],[-13.5,41.5],[-8,89.5],[6,90],[46.522,85.525],[61.438,75.001],[71.251,96.577],[91.432,85.489],[90.417,77.766],[88.46,62.424],[88.43,62.183],[88.418,62.088],[88.362,61.641],[87.491,54.526],[87.208,52.161],[85.515,33.361],[79.814,42.439],[81.921,22.045],[64.827,-14.457],[54.499,-14.678]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":55,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.605,4.652],[0.707,5.67],[0.01,0.081],[0.004,0.032],[0.019,0.149],[0.282,2.343],[0.093,0.78],[-0.398,0.146],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.546,-4.194],[-0.01,-0.081],[-0.004,-0.032],[-0.019,-0.149],[-0.295,-2.373],[-0.096,-0.796],[-1.201,-10.121],[0.985,-0.361],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-15.5],[-13.5,41.5],[-8,89.5],[6,90],[46.522,85.525],[61.438,75.001],[71.251,96.577],[91.432,85.489],[90.417,77.766],[88.46,62.424],[88.43,62.183],[88.418,62.088],[88.362,61.641],[87.491,54.526],[87.208,52.161],[85.515,33.361],[79.814,42.439],[81.921,22.045],[64.827,-14.457],[54.499,-14.678]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-4.677,11.764],[-1.163,5.562],[-0.02,0.137],[-0.007,0.052],[0.001,0.218],[1.949,-0.257],[0.001,0.004],[-0.427,0.157],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[3.026,-7.611],[0.031,-0.146],[0.008,-0.054],[0.031,-0.246],[-0.016,-3.466],[-0.662,0.087],[0.935,-0.532],[0.985,-0.361],[0,0],[0,0],[0,0],[0,0]],"v":[[41,-15.5],[-3.5,41.5],[-6,90.5],[16,90],[56.522,85.525],[71.438,75.001],[81.251,96.577],[101.432,85.489],[105.72,51.786],[109.753,42.158],[111.33,42.983],[112.602,41.824],[109.895,40.878],[112.587,37.251],[111.48,37.442],[95.515,33.361],[89.814,42.439],[91.921,22.045],[74.827,-14.457],[64.499,-14.678]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":63.75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-4.677,11.764],[-1.163,5.562],[-0.02,0.137],[-0.007,0.052],[0.001,0.218],[1.949,-0.257],[0.001,0.004],[-0.427,0.157],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[3.026,-7.611],[0.031,-0.146],[0.008,-0.054],[0.031,-0.246],[-0.016,-3.466],[-0.662,0.087],[0.935,-0.532],[0.985,-0.361],[0,0],[0,0],[0,0],[0,0]],"v":[[41,-15.5],[-3.5,41.5],[-6,90.5],[16,90],[56.522,85.525],[71.438,75.001],[81.251,96.577],[101.432,85.489],[105.72,51.786],[109.753,42.158],[111.33,42.983],[112.602,41.824],[109.895,40.878],[112.587,37.251],[111.48,37.442],[95.515,33.361],[89.814,42.439],[91.921,22.045],[74.827,-14.457],[64.499,-14.678]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-4.677,11.764],[-1.163,5.562],[2.392,3.689],[1.083,1.699],[0.034,3.46],[0.009,12.741],[0.001,0.004],[-0.427,0.157],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[3.026,-7.611],[0.049,-0.233],[-0.939,-1.449],[-5.086,-7.973],[-0.045,-4.534],[-0.003,-4.327],[0.935,-0.532],[0.985,-0.361],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-15.5],[-13.5,41.5],[-8,89.5],[6,90],[46.522,85.525],[61.438,75.001],[71.251,96.577],[91.432,85.489],[97.72,111.786],[122.753,116.658],[118.697,110.115],[115.63,105.354],[108.31,84.18],[108.237,41.212],[108.23,34.048],[85.515,33.361],[79.814,42.439],[81.921,22.045],[64.827,-14.457],[54.499,-14.678]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":68.75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-4.677,11.764],[-1.163,5.562],[2.392,3.689],[1.083,1.699],[0.034,3.46],[0.009,12.741],[0.001,0.004],[-0.427,0.157],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[3.026,-7.611],[0.049,-0.233],[-0.939,-1.449],[-5.086,-7.973],[-0.045,-4.534],[-0.003,-4.327],[0.935,-0.532],[0.985,-0.361],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-15.5],[-13.5,41.5],[-8,89.5],[6,90],[46.522,85.525],[61.438,75.001],[71.251,96.577],[91.432,85.489],[97.72,111.786],[122.753,116.658],[118.697,110.115],[115.63,105.354],[108.31,84.18],[108.237,41.212],[108.23,34.048],[85.515,33.361],[79.814,42.439],[81.921,22.045],[64.827,-14.457],[54.499,-14.678]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-4.677,11.764],[-1.163,5.562],[0.347,3.557],[0.161,1.639],[0.034,3.46],[4.388,13.024],[0.001,0.004],[-0.427,0.157],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[3.026,-7.611],[0.049,-0.233],[-0.136,-1.397],[-0.757,-7.694],[-0.045,-4.534],[-1.49,-4.423],[0.935,-0.532],[0.985,-0.361],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-35.5],[-13.5,21.5],[-7.818,96.275],[6.182,96.775],[46.704,92.299],[60.87,81.751],[70.683,103.327],[90.864,92.239],[97.095,91.786],[122.753,96.658],[122.222,90.342],[121.771,85.75],[120.06,65.074],[106.97,21.266],[104.48,13.942],[85.515,13.361],[79.814,22.439],[81.921,2.045],[64.827,-34.457],[54.499,-34.678]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-4.677,11.764],[-1.163,5.562],[0.347,3.557],[0.161,1.639],[0.034,3.46],[4.388,13.024],[0.001,0.004],[-0.427,0.157],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[3.026,-7.611],[0.049,-0.233],[-0.136,-1.397],[-0.757,-7.694],[-0.045,-4.534],[-1.49,-4.423],[0.935,-0.532],[0.985,-0.361],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-35.5],[-13.5,21.5],[-7.818,96.275],[6.182,96.775],[46.704,92.299],[60.87,81.751],[70.683,103.327],[90.864,92.239],[97.095,91.786],[122.753,96.658],[122.222,90.342],[121.771,85.75],[120.06,65.074],[106.97,21.266],[104.48,13.942],[85.515,13.361],[79.814,22.439],[81.921,2.045],[64.827,-34.457],[54.499,-34.678]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-4.677,11.764],[-1.163,5.562],[0.545,11.145],[0.25,5.06],[0.034,3.46],[3.965,-3.222],[0.001,0.004],[-0.427,0.157],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[3.026,-7.611],[0.049,-0.233],[-0.214,-4.377],[-1.176,-23.754],[-0.045,-4.534],[-1.346,1.094],[0.935,-0.532],[0.985,-0.361],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-25.5],[-13.5,31.5],[-8,89.5],[6,90],[47.522,84.275],[62.438,73.751],[71.183,100.327],[91.364,89.239],[97.72,101.786],[122.753,106.658],[121.881,87.265],[121.177,72.969],[118.56,17.574],[106.73,22.054],[104.48,23.942],[85.515,23.361],[79.814,32.439],[81.921,12.045],[64.827,-24.457],[54.499,-24.678]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":80,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-4.677,11.764],[-1.163,5.562],[0.545,11.145],[0.25,5.06],[0.034,3.46],[3.965,-3.222],[0.001,0.004],[-0.427,0.157],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[3.026,-7.611],[0.049,-0.233],[-0.214,-4.377],[-1.176,-23.754],[-0.045,-4.534],[-1.346,1.094],[0.935,-0.532],[0.985,-0.361],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-25.5],[-13.5,31.5],[-8,89.5],[6,90],[47.522,84.275],[62.438,73.751],[71.183,100.327],[91.364,89.239],[97.72,101.786],[122.753,106.658],[121.881,87.265],[121.177,72.969],[118.56,17.574],[106.73,22.054],[104.48,23.942],[85.515,23.361],[79.814,32.439],[81.921,12.045],[64.827,-24.457],[54.499,-24.678]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-4.677,11.764],[-1.163,5.562],[-19.442,26.716],[-2.668,8.81],[0.032,3.273],[-0.42,-3.904],[0.002,0.005],[-0.427,0.157],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[3.026,-7.611],[0.052,-0.25],[7.635,-10.492],[11.052,-36.494],[-0.04,-4.114],[0.42,3.904],[0.935,-0.532],[0.985,-0.361],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-15.5],[-13.5,41.5],[-8,89.5],[6,90],[46.522,85.525],[61.438,75.001],[71.251,96.577],[91.432,85.489],[97.72,111.786],[122.753,116.658],[170.518,62.793],[187.094,33.028],[164.06,-23.426],[106.08,-11.904],[104.48,33.942],[85.515,33.361],[79.814,42.439],[81.921,22.045],[64.827,-14.457],[54.499,-14.678]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":92.5,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-4.677,11.764],[-1.163,5.562],[-19.442,26.716],[-2.668,8.81],[0.032,3.273],[-0.42,-3.904],[0.002,0.005],[-0.427,0.157],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[3.026,-7.611],[0.052,-0.25],[7.635,-10.492],[11.052,-36.494],[-0.04,-4.114],[0.42,3.904],[0.935,-0.532],[0.985,-0.361],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-15.5],[-13.5,41.5],[-8,89.5],[6,90],[46.522,85.525],[61.438,75.001],[71.251,96.577],[91.432,85.489],[97.72,111.786],[122.753,116.658],[170.518,62.793],[187.094,33.028],[164.06,-23.426],[106.08,-11.904],[104.48,33.942],[85.515,33.361],[79.814,42.439],[81.921,22.045],[64.827,-14.457],[54.499,-14.678]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-4.677,11.764],[-1.163,5.562],[-19.414,27.8],[-2.375,7.842],[0.032,3.273],[-0.42,-3.904],[0.002,0.005],[-0.427,0.157],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[3.026,-7.611],[0.054,-0.261],[6.505,-9.315],[11.052,-36.494],[-0.04,-4.114],[0.42,3.904],[0.935,-0.532],[0.985,-0.361],[0,0],[0,0],[0,0],[0,0]],"v":[[31,-15.5],[-13.5,41.5],[-8,89.5],[6,90],[46.522,85.525],[61.438,75.001],[71.251,96.577],[91.432,85.489],[97.72,111.786],[122.753,116.658],[219.983,107.837],[187.094,33.028],[164.06,-23.426],[106.08,-11.904],[104.48,33.942],[85.515,33.361],[79.814,42.439],[81.921,22.045],[64.827,-14.457],[54.499,-14.678]],"c":true}]},{"t":103.75}],"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-92.43,41.943],[-92.43,29.503],[-89.412,29.503],[-89.412,19.37],[-86.393,19.37],[-86.393,16.331],[-85.89,16.331],[-85.265,9.743],[-82.75,9.743],[-83.375,16.331],[-82.369,16.331],[-82.369,15.824],[-80.86,15.824],[-80.86,16.331],[-79.854,16.331],[-79.854,24.943],[-72.811,24.943],[-72.811,30.01],[-70.296,30.01],[-70.296,31.023],[-69.793,31.023],[-69.793,30.516],[-64.763,30.516],[-64.763,33.049],[-56.211,33.049],[-56.211,27.984],[-54.199,27.984],[-54.199,25.958],[-50.678,25.958],[-50.678,25.451],[-48.665,25.451],[-48.665,25.958],[-47.156,25.958],[-47.156,28.49],[-45.647,28.49],[-45.647,35.077],[-43.635,35.077],[-43.01,-12.549],[-39.489,-12.549],[-39.489,-18.122],[-34.458,-18.122],[-34.458,-21.163],[-30.938,-21.163],[-30.938,-42.443],[-27.919,-42.443],[-27.919,-21.163],[-23.895,-21.163],[-23.895,-18.122],[-19.367,-18.122],[-19.367,-12.044],[-16.852,-12.044],[-16.852,10.251],[-6.288,10.251],[-6.913,40.65],[-5.908,40.65],[-5.908,23.93],[-5.404,23.93],[-4.779,3.663],[0.755,3.663],[0.755,-0.389],[3.774,-0.389],[3.774,2.144],[7.798,2.144],[7.798,3.663],[13.834,3.663],[13.834,33.049],[16.349,33.049],[16.349,31.023],[26.913,31.023],[26.913,-8.497],[31.441,-8.497],[31.441,-10.016],[34.458,-10.016],[34.458,-13.564],[39.489,-13.564],[39.489,-15.589],[40.997,-15.589],[40.997,-34.337],[44.017,-34.337],[44.017,-15.589],[45.525,-15.589],[45.525,-13.564],[50.557,-13.564],[50.557,-10.016],[53.574,-10.016],[53.574,-7.99],[57.599,-7.99],[57.599,3.663],[62.629,3.663],[62.629,0.118],[72.188,0.118],[72.188,1.131],[76.212,1.131],[76.212,4.171],[82.247,4.171],[82.247,3.157],[88.788,3.157],[88.788,5.691],[91.805,5.691],[91.805,42.443]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.941176474094,0.466666668653,0.184313729405,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[92.187,43.056],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":165,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"melbourne_purple Outlines Comp 1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,42.5,0],"ix":2},"a":{"a":0,"k":[100,42.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":200,"h":85,"ip":0,"op":165,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"melbourne_purple Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,42.5,0],"ix":2},"a":{"a":0,"k":[92.5,42.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-91.805,41.943],[-91.805,29.503],[-88.787,29.503],[-88.787,19.37],[-85.768,19.37],[-85.768,16.331],[-85.265,16.331],[-85.265,9.743],[-82.75,9.743],[-82.75,16.331],[-81.744,16.331],[-81.744,15.824],[-80.235,15.824],[-80.235,16.331],[-79.229,16.331],[-79.229,24.943],[-72.186,24.943],[-72.186,30.01],[-69.671,30.01],[-69.671,31.023],[-69.168,31.023],[-69.168,30.516],[-64.138,30.516],[-64.138,33.049],[-55.586,33.049],[-55.586,27.984],[-53.574,27.984],[-53.574,25.958],[-50.053,25.958],[-50.053,25.451],[-48.04,25.451],[-48.04,25.958],[-46.531,25.958],[-46.531,28.49],[-45.022,28.49],[-45.022,35.077],[-43.01,35.077],[-43.01,-12.549],[-39.489,-12.549],[-39.489,-18.122],[-34.458,-18.122],[-34.458,-21.163],[-30.938,-21.163],[-30.938,-42.443],[-27.919,-42.443],[-27.919,-21.163],[-23.895,-21.163],[-23.895,-18.122],[-19.367,-18.122],[-19.367,-12.044],[-16.852,-12.044],[-16.852,10.251],[-6.288,10.251],[-6.288,40.65],[-5.283,40.65],[-5.283,23.93],[-4.779,23.93],[-4.779,3.663],[0.755,3.663],[0.755,-0.389],[3.774,-0.389],[3.774,2.144],[7.798,2.144],[7.798,3.663],[13.834,3.663],[13.834,33.049],[16.35,33.049],[16.35,31.023],[26.913,31.023],[26.913,-8.497],[31.441,-8.497],[31.441,-10.016],[34.459,-10.016],[34.459,-13.564],[39.489,-13.564],[39.489,-15.589],[40.997,-15.589],[40.997,-34.337],[44.017,-34.337],[44.017,-15.589],[45.525,-15.589],[45.525,-13.564],[50.557,-13.564],[50.557,-10.016],[53.574,-10.016],[53.574,-7.99],[57.599,-7.99],[57.599,3.663],[62.629,3.663],[62.629,0.118],[72.188,0.118],[72.188,1.131],[76.212,1.131],[76.212,4.171],[82.247,4.171],[82.247,3.157],[88.788,3.157],[88.788,5.691],[91.805,5.691],[91.805,42.443]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.458999992819,0.372999991623,0.638999968884,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[92.187,43.056],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":165,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"melbourne","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,42.5,0],"ix":2},"a":{"a":0,"k":[100,42.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":200,"h":85,"ip":0,"op":165,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/marker.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/marker.json deleted file mode 100644 index d846b110..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/marker.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.5.9","fr":29.9700012207031,"ip":0,"op":208.000008472014,"w":1920,"h":1080,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"third Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1276,844,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.211,0.188],[-0.305,0],[-0.211,-0.164],[0,-0.352],[0,0],[0,0],[0,-0.633],[0.609,0],[0,0],[0,0],[-0.235,-0.281],[-0.516,0],[0,0],[-0.211,-0.187],[0,-0.281],[0.187,-0.188],[0.328,0],[0,0],[0.609,0.726],[0,0.914],[0,0],[0,0],[0,0.656],[-0.539,0],[0,0],[0,0]],"o":[[0.211,-0.164],[0.304,0],[0.234,0.188],[0,0],[0,0],[0.609,0],[0,0.656],[0,0],[0,0],[0,0.422],[0.281,0.352],[0,0],[0.328,0],[0.187,0.188],[0,0.258],[-0.211,0.211],[0,0],[-1.078,0],[-0.563,-0.633],[0,0],[0,0],[-0.539,0],[0,-0.633],[0,0],[0,0],[0,-0.352]],"v":[[4.324,-24.504],[5.098,-24.75],[5.871,-24.504],[6.223,-23.695],[6.223,-18.809],[9.105,-18.809],[10.02,-17.859],[9.105,-16.875],[6.223,-16.875],[6.223,-2.918],[6.574,-1.863],[7.77,-1.336],[9.035,-1.336],[9.844,-1.055],[10.125,-0.352],[9.844,0.316],[9.035,0.633],[7.383,0.633],[4.852,-0.457],[4.008,-2.777],[4.008,-16.875],[2.109,-16.875],[1.301,-17.859],[2.109,-18.809],[4.008,-18.809],[4.008,-23.695]],"c":true},"ix":2},"nm":"t","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"t","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.211,0.211],[-0.305,0],[-0.211,-0.187],[0,-0.352],[0,0],[-0.867,0.469],[-1.36,0],[-1.125,-1.148],[0,-1.523],[0,0],[0.234,-0.235],[0.304,0],[0.211,0.187],[0,0.352],[0,0],[0.656,0.656],[1.218,0],[1.055,-0.656],[0.867,-1.218],[0,0],[0.234,-0.235],[0.281,-0.024],[0.211,0.211],[0,0.375],[0,0]],"o":[[0.211,-0.187],[0.281,0],[0.234,0.211],[0,0],[0.773,-0.89],[1.101,-0.586],[1.898,0],[1.031,1.032],[0,0],[0,0.352],[-0.211,0.187],[-0.305,0],[-0.211,-0.235],[0,0],[0,-1.007],[-0.703,-0.75],[-1.219,0],[-0.961,0.61],[0,0],[0,0.375],[-0.211,0.187],[-0.305,0],[-0.211,-0.211],[0,0],[0,-0.352]],"v":[[14.66,-26.156],[15.434,-26.438],[16.172,-26.156],[16.523,-25.313],[16.523,-16.488],[18.984,-18.527],[22.676,-19.406],[27.211,-17.684],[28.758,-13.852],[28.758,-0.527],[28.406,0.352],[27.633,0.633],[26.859,0.352],[26.543,-0.527],[26.543,-13.852],[25.559,-16.348],[22.676,-17.473],[19.266,-16.488],[16.523,-13.746],[16.523,-0.563],[16.172,0.352],[15.434,0.668],[14.66,0.352],[14.344,-0.527],[14.344,-25.313]],"c":true},"ix":2},"nm":"h","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"h","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.211,0.164],[-0.305,0],[-0.211,-0.164],[0,-0.328],[0,0],[0.234,-0.211],[0.304,0],[0.211,0.187],[0,0.352],[0,0]],"o":[[0.211,-0.187],[0.304,0],[0.234,0.188],[0,0],[0,0.352],[-0.211,0.211],[-0.305,0],[-0.211,-0.235],[0,0],[0,-0.328]],"v":[[35.578,-19.16],[36.352,-19.441],[37.125,-19.195],[37.477,-18.422],[37.477,-0.527],[37.125,0.316],[36.352,0.633],[35.578,0.352],[35.262,-0.527],[35.262,-18.422]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-0.328,-0.375],[0,-0.515],[0.304,-0.352],[0.539,0],[0.304,0.375],[0,0.492],[-0.281,0.352],[-0.563,0]],"o":[[0.304,0.352],[0,0.469],[-0.328,0.375],[-0.563,0],[-0.281,-0.328],[0,-0.515],[0.304,-0.375],[0.539,0]],"v":[[37.652,-25.875],[38.109,-24.574],[37.652,-23.344],[36.352,-22.781],[35.051,-23.344],[34.629,-24.574],[35.051,-25.875],[36.352,-26.438]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"i","np":5,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.211,0.188],[-0.305,0],[-0.211,-0.141],[0,-0.328],[0,0],[-0.68,0.422],[-1.125,0],[-0.024,-0.703],[0.586,0],[0.89,-0.586],[0.422,-0.914],[0,0],[0.234,-0.211],[0.281,0],[0.211,0.187],[0,0.352],[0,0]],"o":[[0.211,-0.164],[0.281,0],[0.234,0.188],[0,0],[0.586,-0.82],[0.89,-0.563],[0.515,0],[0.023,0.727],[-1.149,0],[-0.797,0.516],[0,0],[0,0.352],[-0.211,0.187],[-0.305,0],[-0.211,-0.211],[0,0],[0,-0.304]],"v":[[43.91,-18.879],[44.684,-19.125],[45.422,-18.914],[45.773,-18.141],[45.773,-16.699],[47.672,-18.563],[50.695,-19.406],[51.504,-18.352],[50.66,-17.262],[47.602,-16.383],[45.773,-14.238],[45.773,-0.527],[45.422,0.316],[44.684,0.598],[43.91,0.316],[43.594,-0.527],[43.594,-18.141]],"c":true},"ix":2},"nm":"r","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"r","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.234,-0.211],[0.304,0],[0.211,0.187],[0,0.328],[0,0],[0.984,-0.563],[1.406,0],[1.5,2.086],[0,2.766],[-1.336,1.828],[-2.695,0],[-0.984,-0.515],[-0.727,-1.101],[0,0],[-0.211,0.211],[-0.305,0],[-0.211,-0.187],[0,-0.375]],"o":[[-0.024,0.375],[-0.188,0.164],[-0.281,-0.024],[-0.211,-0.211],[0,0],[-0.516,0.821],[-1.149,0.633],[-2.695,0],[-1.336,-1.828],[0,-2.789],[1.5,-2.062],[1.336,0],[1.007,0.516],[0,0],[0,-0.352],[0.211,-0.164],[0.281,0],[0.234,0.211],[0,0]],"v":[[71.332,-0.809],[70.945,0.07],[70.207,0.316],[69.469,0],[69.152,-0.809],[69.152,-2.32],[66.902,-0.246],[63.07,0.703],[56.777,-2.426],[54.773,-9.316],[56.777,-16.242],[63.07,-19.336],[66.551,-18.563],[69.152,-16.137],[69.152,-25.277],[69.469,-26.121],[70.242,-26.367],[70.98,-26.086],[71.332,-25.207]],"c":true},"ix":2},"nm":"d","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.101,-1.664],[0,-2.25],[-0.961,-1.477],[-1.992,0],[-1.102,1.664],[0,2.227],[0.984,1.477],[1.969,0]],"o":[[-0.961,1.477],[0,2.227],[1.101,1.664],[1.969,0],[0.984,-1.477],[0,-2.25],[-1.102,-1.664],[-1.992,0]],"v":[[58.43,-14.906],[56.988,-9.316],[58.43,-3.762],[63.07,-1.266],[67.676,-3.762],[69.152,-9.316],[67.676,-14.906],[63.07,-17.402]],"c":true},"ix":2},"nm":"d","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"d","np":5,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":-2.00000008146167,"op":898.00003657629,"st":-2.00000008146167,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"second Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[792,847,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100.824,100.824,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.219,-1.007],[-0.118,-1.429],[0.234,-0.234],[0.328,-0.047],[0.234,0.164],[0.023,0.328],[0.75,0.539],[1.57,0],[0.797,-0.492],[0,-0.82],[-0.703,-0.563],[-2.016,-0.515],[-1.008,-0.961],[0,-1.57],[1.148,-0.961],[2.32,0],[1.242,0.961],[0.07,1.828],[-0.235,0.211],[-0.305,0],[-0.211,-0.164],[-0.024,-0.328],[-0.773,-0.633],[-1.828,0],[-0.867,0.68],[0,1.032],[0.703,0.539],[2.297,0.563],[0.937,0.821],[0,1.453],[-1.243,0.891],[-1.898,0]],"o":[[1.031,0.867],[0.023,0.328],[-0.211,0.188],[-0.305,0.024],[-0.258,-0.187],[-0.094,-1.031],[-0.797,-0.586],[-1.195,0],[-0.797,0.539],[0,0.961],[0.75,0.586],[2.461,0.563],[0.961,0.891],[0,1.57],[-1.243,1.078],[-2.32,0],[-1.243,-0.961],[-0.024,-0.328],[0.187,-0.187],[0.304,-0.023],[0.234,0.164],[0,1.219],[0.82,0.68],[1.523,0],[0.82,-0.609],[0,-0.961],[-0.844,-0.68],[-2.086,-0.539],[-1.032,-0.867],[0,-1.57],[1.172,-0.844],[2.367,0]],"v":[[14.344,-17.895],[16.066,-14.449],[15.75,-13.605],[14.941,-13.254],[14.133,-13.465],[13.711,-14.238],[12.445,-16.594],[8.895,-17.473],[5.906,-16.734],[4.711,-14.695],[5.766,-12.41],[9.914,-10.758],[15.117,-8.473],[16.559,-4.781],[14.836,-0.984],[9.492,0.633],[4.148,-0.809],[2.18,-4.992],[2.496,-5.801],[3.234,-6.082],[4.008,-5.871],[4.395,-5.133],[5.555,-2.355],[9.527,-1.336],[13.113,-2.355],[14.344,-4.816],[13.289,-7.066],[8.578,-8.93],[4.043,-10.969],[2.496,-14.449],[4.359,-18.141],[8.965,-19.406]],"c":true},"ix":2},"nm":"s","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"s","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.305,0.141],[-0.305,-0.117],[-0.118,-0.258],[0.141,-0.352],[1.289,-0.867],[1.781,0],[1.477,2.063],[0,2.719],[-1.336,1.898],[-2.508,0],[-1.5,-2.062],[0,-2.742],[0,0],[0,0],[-0.914,-1.359],[-1.781,0],[-0.938,0.821],[-0.563,1.219]],"o":[[0.281,-0.093],[0.281,0.094],[0.141,0.305],[-0.68,1.641],[-1.313,0.914],[-2.508,0],[-1.336,-1.875],[0,-2.742],[1.477,-2.062],[2.508,0],[1.359,1.898],[0,0],[0,0],[0.093,1.992],[1.055,1.617],[1.406,0],[0.726,-0.609],[0.141,-0.352]],"v":[[35.156,-6.047],[36.035,-6.012],[36.633,-5.484],[36.633,-4.5],[33.68,-0.738],[29.039,0.633],[23.063,-2.461],[21.059,-9.352],[23.063,-16.313],[29.039,-19.406],[35.051,-16.313],[37.09,-9.352],[37.09,-8.789],[23.273,-8.789],[24.785,-3.762],[29.039,-1.336],[32.555,-2.566],[34.488,-5.309]],"c":true},"ix":2},"nm":"e","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.867,1.266],[1.734,0],[1.055,-1.523],[0.141,-1.711]],"o":[[-0.141,-1.664],[-1.078,-1.547],[-1.735,0],[-0.867,1.243],[0,0]],"v":[[34.77,-10.758],[33.258,-15.152],[29.039,-17.473],[24.855,-15.188],[23.344,-10.758]],"c":true},"ix":2},"nm":"e","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"e","np":5,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.523,-2.062],[0,-2.789],[-1.289,-1.758],[-2.836,0],[-1.336,0.961],[-0.703,1.477],[0.164,0.235],[0.328,0.07],[0.281,-0.117],[0.093,-0.328],[0.867,-0.515],[1.664,0],[1.055,1.594],[0,2.32],[-0.961,1.453],[-1.992,0],[-0.844,-0.492],[-0.352,-1.101],[-0.305,-0.141],[-0.328,0.07],[-0.164,0.235],[0.07,0.305],[1.148,0.844],[2.062,0]],"o":[[-1.336,1.852],[0,2.883],[1.477,2.016],[2.18,0],[1.007,-0.75],[0.141,-0.352],[-0.141,-0.234],[-0.305,-0.07],[-0.328,0.141],[-0.422,1.219],[-0.867,0.516],[-2.016,0],[-0.961,-1.453],[0,-2.273],[1.078,-1.664],[1.477,0],[0.844,0.516],[0.07,0.328],[0.258,0.118],[0.304,-0.07],[0.187,-0.234],[-0.375,-1.242],[-1.383,-0.984],[-2.742,0]],"v":[[43.805,-16.313],[41.801,-9.352],[43.734,-2.391],[50.203,0.633],[55.477,-0.809],[58.043,-4.148],[58.008,-5.027],[57.305,-5.484],[56.426,-5.414],[55.793,-4.711],[53.859,-2.109],[50.063,-1.336],[45.457,-3.727],[44.016,-9.387],[45.457,-14.977],[50.063,-17.473],[53.543,-16.734],[55.336,-14.309],[55.898,-13.605],[56.777,-13.535],[57.48,-13.992],[57.656,-14.801],[55.371,-17.93],[50.203,-19.406]],"c":true},"ix":2},"nm":"c","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"c","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.57,-2.062],[0,-2.789],[1.406,-1.828],[2.765,0],[1.57,2.086],[0,2.766],[-1.383,1.828],[-2.789,0]],"o":[[1.406,1.828],[0,2.766],[-1.57,2.086],[-2.789,0],[-1.383,-1.828],[0,-2.789],[1.57,-2.062],[2.765,0]],"v":[[77.309,-16.242],[79.418,-9.316],[77.309,-2.426],[70.805,0.703],[64.266,-2.426],[62.191,-9.316],[64.266,-16.242],[70.805,-19.336]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.172,-1.664],[0,-2.25],[-1.008,-1.477],[-2.086,0],[-1.149,1.664],[0,2.203],[1.055,1.477],[2.062,0]],"o":[[-1.008,1.477],[0,2.227],[1.172,1.664],[2.062,0],[1.055,-1.5],[0,-2.25],[-1.149,-1.664],[-2.086,0]],"v":[[65.918,-14.906],[64.406,-9.316],[65.918,-3.762],[70.805,-1.266],[75.621,-3.762],[77.203,-9.316],[75.621,-14.906],[70.805,-17.402]],"c":true},"ix":2},"nm":"o","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"o","np":5,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.211,0.211],[-0.305,0],[-0.211,-0.187],[0,-0.352],[0,0],[-1.055,0.61],[-1.477,0],[-1.125,-1.148],[0,-1.523],[0,0],[0.234,-0.235],[0.281,0],[0.211,0.187],[0,0.352],[0,0],[0.656,0.656],[1.218,0],[1.055,-0.703],[0.82,-1.5],[0,0],[0.234,-0.235],[0.281,-0.024],[0.211,0.211],[0,0.375],[0,0]],"o":[[0.211,-0.187],[0.281,0],[0.234,0.211],[0,0],[0.68,-1.148],[1.101,-0.633],[1.898,0],[1.031,1.032],[0,0],[0,0.352],[-0.211,0.187],[-0.305,0],[-0.211,-0.235],[0,0],[0,-1.007],[-0.727,-0.75],[-1.336,0],[-1.102,0.727],[0,0],[0,0.375],[-0.211,0.187],[-0.305,0],[-0.211,-0.211],[0,0],[0,-0.352]],"v":[[85.113,-18.844],[85.887,-19.125],[86.625,-18.844],[86.977,-18],[86.977,-15.82],[89.578,-18.457],[93.445,-19.406],[97.98,-17.684],[99.527,-13.852],[99.527,-0.527],[99.176,0.352],[98.438,0.633],[97.664,0.352],[97.348,-0.527],[97.348,-13.852],[96.363,-16.348],[93.445,-17.473],[89.859,-16.418],[86.977,-13.078],[86.977,-0.563],[86.625,0.352],[85.887,0.668],[85.113,0.352],[84.797,-0.527],[84.797,-18]],"c":true},"ix":2},"nm":"n","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"n","np":3,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.234,-0.211],[0.304,0],[0.211,0.187],[0,0.328],[0,0],[0.984,-0.563],[1.406,0],[1.5,2.086],[0,2.766],[-1.336,1.828],[-2.695,0],[-0.984,-0.515],[-0.727,-1.101],[0,0],[-0.211,0.211],[-0.305,0],[-0.211,-0.187],[0,-0.375]],"o":[[-0.024,0.375],[-0.188,0.164],[-0.281,-0.024],[-0.211,-0.211],[0,0],[-0.516,0.821],[-1.149,0.633],[-2.695,0],[-1.336,-1.828],[0,-2.789],[1.5,-2.062],[1.336,0],[1.007,0.516],[0,0],[0,-0.352],[0.211,-0.164],[0.281,0],[0.234,0.211],[0,0]],"v":[[121.43,-0.809],[121.043,0.07],[120.305,0.316],[119.566,0],[119.25,-0.809],[119.25,-2.32],[117,-0.246],[113.168,0.703],[106.875,-2.426],[104.871,-9.316],[106.875,-16.242],[113.168,-19.336],[116.648,-18.563],[119.25,-16.137],[119.25,-25.277],[119.566,-26.121],[120.34,-26.367],[121.078,-26.086],[121.43,-25.207]],"c":true},"ix":2},"nm":"d","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[1.101,-1.664],[0,-2.25],[-0.961,-1.477],[-1.992,0],[-1.102,1.664],[0,2.227],[0.984,1.477],[1.969,0]],"o":[[-0.961,1.477],[0,2.227],[1.101,1.664],[1.969,0],[0.984,-1.477],[0,-2.25],[-1.102,-1.664],[-1.992,0]],"v":[[108.527,-14.906],[107.086,-9.316],[108.527,-3.762],[113.168,-1.266],[117.773,-3.762],[119.25,-9.316],[117.773,-14.906],[113.168,-17.402]],"c":true},"ix":2},"nm":"d","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"d","np":5,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false}],"ip":-2.00000008146167,"op":898.00003657629,"st":-2.00000008146167,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"first Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[413,844,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.539,0.633],[-1.078,0],[0,0],[-0.211,-0.187],[0,-0.281],[0.187,-0.187],[0.352,0],[0,0],[0.281,-0.328],[0,-0.445],[0,0],[0,0],[-0.211,-0.187],[0,-0.258],[0.187,-0.187],[0.352,0],[0,0],[0,0],[0.234,-0.235],[0.281,0],[0.211,0.187],[0,0.375],[0,0],[0,0],[0.211,0.211],[0,0.258],[-0.188,0.188],[-0.352,0],[0,0]],"o":[[0,-0.937],[0.609,-0.703],[0,0],[0.352,0],[0.187,0.188],[0,0.258],[-0.211,0.211],[0,0],[-0.516,0],[-0.235,0.281],[0,0],[0,0],[0.352,0],[0.187,0.188],[0,0.258],[-0.211,0.211],[0,0],[0,0],[0,0.352],[-0.211,0.211],[-0.305,0],[-0.211,-0.235],[0,0],[0,0],[-0.352,0],[-0.188,-0.187],[0,-0.258],[0.211,-0.187],[0,0],[0,0]],"v":[[4.781,-23.027],[5.59,-25.383],[8.121,-26.438],[9.527,-26.438],[10.371,-26.156],[10.652,-25.453],[10.371,-24.785],[9.527,-24.469],[8.508,-24.469],[7.313,-23.977],[6.961,-22.887],[6.961,-18.809],[9.527,-18.809],[10.371,-18.527],[10.652,-17.859],[10.371,-17.191],[9.527,-16.875],[6.961,-16.875],[6.961,-0.563],[6.609,0.316],[5.871,0.633],[5.098,0.352],[4.781,-0.563],[4.781,-16.875],[3.023,-16.875],[2.18,-17.191],[1.898,-17.859],[2.18,-18.527],[3.023,-18.809],[4.781,-18.809]],"c":true},"ix":2},"nm":"f","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"f","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.211,0.164],[-0.305,0],[-0.211,-0.164],[0,-0.328],[0,0],[0.234,-0.211],[0.304,0],[0.211,0.187],[0,0.352],[0,0]],"o":[[0.211,-0.187],[0.304,0],[0.234,0.188],[0,0],[0,0.352],[-0.211,0.211],[-0.305,0],[-0.211,-0.235],[0,0],[0,-0.328]],"v":[[16.031,-19.16],[16.805,-19.441],[17.578,-19.195],[17.93,-18.422],[17.93,-0.527],[17.578,0.316],[16.805,0.633],[16.031,0.352],[15.715,-0.527],[15.715,-18.422]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-0.328,-0.375],[0,-0.515],[0.304,-0.352],[0.539,0],[0.304,0.375],[0,0.492],[-0.281,0.352],[-0.563,0]],"o":[[0.304,0.352],[0,0.469],[-0.328,0.375],[-0.563,0],[-0.281,-0.328],[0,-0.515],[0.304,-0.375],[0.539,0]],"v":[[18.105,-25.875],[18.563,-24.574],[18.105,-23.344],[16.805,-22.781],[15.504,-23.344],[15.082,-24.574],[15.504,-25.875],[16.805,-26.438]],"c":true},"ix":2},"nm":"i","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"i","np":5,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.211,0.188],[-0.305,0],[-0.211,-0.141],[0,-0.328],[0,0],[-0.68,0.422],[-1.125,0],[-0.024,-0.703],[0.586,0],[0.89,-0.586],[0.422,-0.914],[0,0],[0.234,-0.211],[0.281,0],[0.211,0.187],[0,0.352],[0,0]],"o":[[0.211,-0.164],[0.281,0],[0.234,0.188],[0,0],[0.586,-0.82],[0.89,-0.563],[0.515,0],[0.023,0.727],[-1.149,0],[-0.797,0.516],[0,0],[0,0.352],[-0.211,0.187],[-0.305,0],[-0.211,-0.211],[0,0],[0,-0.304]],"v":[[24.363,-18.879],[25.137,-19.125],[25.875,-18.914],[26.227,-18.141],[26.227,-16.699],[28.125,-18.563],[31.148,-19.406],[31.957,-18.352],[31.113,-17.262],[28.055,-16.383],[26.227,-14.238],[26.227,-0.527],[25.875,0.316],[25.137,0.598],[24.363,0.316],[24.047,-0.527],[24.047,-18.141]],"c":true},"ix":2},"nm":"r","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"r","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.219,-1.007],[-0.118,-1.429],[0.234,-0.234],[0.328,-0.047],[0.234,0.164],[0.023,0.328],[0.75,0.539],[1.57,0],[0.797,-0.492],[0,-0.82],[-0.703,-0.563],[-2.016,-0.515],[-1.008,-0.961],[0,-1.57],[1.148,-0.961],[2.32,0],[1.242,0.961],[0.07,1.828],[-0.235,0.211],[-0.305,0],[-0.211,-0.164],[-0.024,-0.328],[-0.773,-0.633],[-1.828,0],[-0.867,0.68],[0,1.032],[0.703,0.539],[2.297,0.563],[0.937,0.821],[0,1.453],[-1.243,0.891],[-1.898,0]],"o":[[1.031,0.867],[0.023,0.328],[-0.211,0.188],[-0.305,0.024],[-0.258,-0.187],[-0.094,-1.031],[-0.797,-0.586],[-1.195,0],[-0.797,0.539],[0,0.961],[0.75,0.586],[2.461,0.563],[0.961,0.891],[0,1.57],[-1.243,1.078],[-2.32,0],[-1.243,-0.961],[-0.024,-0.328],[0.187,-0.187],[0.304,-0.023],[0.234,0.164],[0,1.219],[0.82,0.68],[1.523,0],[0.82,-0.609],[0,-0.961],[-0.844,-0.68],[-2.086,-0.539],[-1.032,-0.867],[0,-1.57],[1.172,-0.844],[2.367,0]],"v":[[47.32,-17.895],[49.043,-14.449],[48.727,-13.605],[47.918,-13.254],[47.109,-13.465],[46.688,-14.238],[45.422,-16.594],[41.871,-17.473],[38.883,-16.734],[37.688,-14.695],[38.742,-12.41],[42.891,-10.758],[48.094,-8.473],[49.535,-4.781],[47.813,-0.984],[42.469,0.633],[37.125,-0.809],[35.156,-4.992],[35.473,-5.801],[36.211,-6.082],[36.984,-5.871],[37.371,-5.133],[38.531,-2.355],[42.504,-1.336],[46.09,-2.355],[47.32,-4.816],[46.266,-7.066],[41.555,-8.93],[37.02,-10.969],[35.473,-14.449],[37.336,-18.141],[41.941,-19.406]],"c":true},"ix":2},"nm":"s","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"s","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.211,0.188],[-0.305,0],[-0.211,-0.164],[0,-0.352],[0,0],[0,0],[0,-0.633],[0.609,0],[0,0],[0,0],[-0.235,-0.281],[-0.516,0],[0,0],[-0.211,-0.187],[0,-0.281],[0.187,-0.188],[0.328,0],[0,0],[0.609,0.726],[0,0.914],[0,0],[0,0],[0,0.656],[-0.539,0],[0,0],[0,0]],"o":[[0.211,-0.164],[0.304,0],[0.234,0.188],[0,0],[0,0],[0.609,0],[0,0.656],[0,0],[0,0],[0,0.422],[0.281,0.352],[0,0],[0.328,0],[0.187,0.188],[0,0.258],[-0.211,0.211],[0,0],[-1.078,0],[-0.563,-0.633],[0,0],[0,0],[-0.539,0],[0,-0.633],[0,0],[0,0],[0,-0.352]],"v":[[56.215,-24.504],[56.988,-24.75],[57.762,-24.504],[58.113,-23.695],[58.113,-18.809],[60.996,-18.809],[61.91,-17.859],[60.996,-16.875],[58.113,-16.875],[58.113,-2.918],[58.465,-1.863],[59.66,-1.336],[60.926,-1.336],[61.734,-1.055],[62.016,-0.352],[61.734,0.316],[60.926,0.633],[59.273,0.633],[56.742,-0.457],[55.898,-2.777],[55.898,-16.875],[54,-16.875],[53.191,-17.859],[54,-18.809],[55.898,-18.809],[55.898,-23.695]],"c":true},"ix":2},"nm":"t","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.921568986481,0.921568986481,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"t","np":3,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":-2.00000008146167,"op":898.00003657629,"st":-2.00000008146167,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[962,539.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[118.823,95.694,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[226,7],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":0,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.290196090937,0.290196090937,0.290196090937,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20.695,309.194],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[108.969,468.415],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-2.00000008146167,"op":898.00003657629,"st":-2.00000008146167,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[1586,30],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.023529307917,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-19,241],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-2.00000008146167,"op":898.00003657629,"st":-2.00000008146167,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":-2,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":78,"s":[9]},{"t":204.00000830909,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":-2,"s":[389,531,0],"to":[202,0,0],"ti":[-202,0,0]},{"t":204.00000830909,"s":[1601,531,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[217.139,372.284,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[311,155],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0.972549021244,0.015255670063,0.015255670063,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":95,"s":[0.972549021244,0.893713116646,0.015255670063,1]},{"t":204.00000830909,"s":[0.015255670063,0.127878397703,0.972549021244,1]}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-24.5,-5.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[56.381,56.381],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-2.00000008146167,"op":898.00003657629,"st":-2.00000008146167,"bm":0}],"markers":[{"tm":14.0000005702317,"cm":"first","dr":0},{"tm":86.0000035028518,"cm":"second","dr":37.0000015070409},{"tm":164.000006679857,"cm":"third","dr":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/mask.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/mask.json deleted file mode 100644 index 29437b72..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/mask.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.0.6","fr":60,"ip":0,"op":30,"w":500,"h":500,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":1,"nm":"Red Solid 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2},"a":{"a":0,"k":[100,100,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"s","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[27.614,0],[0,-27.614],[-27.614,0],[0,27.614]],"o":[[-27.614,0],[0,27.614],[27.614,0],[0,-27.614]],"v":[[100,50],[50,100],[100,150],[150,100]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[50,50],[50,150],[150,150],[150,50]],"c":true}]},{"t":29}],"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"sw":200,"sh":200,"sc":"#ea0c11","ip":0,"op":30,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/material_wave_loading.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/material_wave_loading.json deleted file mode 100644 index cafcccf1..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/material_wave_loading.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.6.8","fr":29.9700012207031,"ip":0,"op":40.0000016292334,"w":256,"h":256,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 3","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[208.6,127.969,0],"e":[208.6,88,0],"to":[0,-6.66145849227905,0],"ti":[0,-0.00520833348855,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":30,"s":[208.6,88,0],"e":[208.6,128,0],"to":[0,0.00520833348855,0],"ti":[0,-6.66666650772095,0]},{"t":40.0000016292334}]},"a":{"a":0,"k":[-70,-0.5,0]},"s":{"a":0,"k":[75,75,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[33.75,34.5]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"fl","c":{"a":0,"k":[0.9843137,0.5490196,0,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-70.125,-0.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":300.00001221925,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 2","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":15,"s":[168.6,128,0],"e":[168.6,88,0],"to":[0,-6.66666650772095,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":25,"s":[168.6,88,0],"e":[168.6,128,0],"to":[0,0,0],"ti":[0,-6.66666650772095,0]},{"t":35.0000014255792}]},"a":{"a":0,"k":[-70,-0.5,0]},"s":{"a":0,"k":[75,75,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[33.75,34.5]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"fl","c":{"a":0,"k":[0.9921569,0.8470588,0.2078431,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-70.125,-0.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":300.00001221925,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":10,"s":[128.594,127.969,0],"e":[128.594,88,0],"to":[0,-6.66145849227905,0],"ti":[0,-0.00520833348855,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[128.594,88,0],"e":[128.594,128,0],"to":[0,0.00520833348855,0],"ti":[0,-6.66666650772095,0]},{"t":30.0000012219251}]},"a":{"a":0,"k":[-70,-0.5,0]},"s":{"a":0,"k":[75,75,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[33.75,34.5]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"fl","c":{"a":0,"k":[0.2627451,0.627451,0.2784314,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-70.125,-0.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":300.00001221925,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 4","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":5,"s":[88.6,127.969,0],"e":[88.6,88,0],"to":[0,-6.66145849227905,0],"ti":[0,-0.00520833348855,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":15,"s":[88.6,88,0],"e":[88.6,128,0],"to":[0,0.00520833348855,0],"ti":[0,-6.66666650772095,0]},{"t":25.0000010182709}]},"a":{"a":0,"k":[-70,-0.5,0]},"s":{"a":0,"k":[75,75,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[33.75,34.5]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"fl","c":{"a":0,"k":[0.1176471,0.5333334,0.8980392,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-70.125,-0.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":300.00001221925,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 5","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[48.6,127.969,0],"e":[48.6,88,0],"to":[0,-6.66145849227905,0],"ti":[0,-0.00520833348855,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":10,"s":[48.6,88,0],"e":[48.6,128,0],"to":[0,0.00520833348855,0],"ti":[0,-6.66666650772095,0]},{"t":20.0000008146167}]},"a":{"a":0,"k":[-70,-0.5,0]},"s":{"a":0,"k":[75,75,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[33.75,34.5]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"fl","c":{"a":0,"k":[0.8980392,0.2235294,0.2078431,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[-70.125,-0.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":300.00001221925,"st":0,"bm":0,"sr":1}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/matte_two_item_with_lowerlayer.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/matte_two_item_with_lowerlayer.json deleted file mode 100644 index 747380d9..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/matte_two_item_with_lowerlayer.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.17","fr":29.9700012207031,"ip":0,"op":150.000006109625,"w":300,"h":300,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 2","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[30,30],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":5,"ix":3},"p":{"a":0,"k":[-42,3],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":41,"ix":6},"is":{"a":0,"k":31,"ix":8},"or":{"a":0,"k":70,"ix":7},"os":{"a":0,"k":37,"ix":9},"ix":2,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"fl","c":{"a":0,"k":[0.847843170166,0.072482459247,0.605201482773,1],"ix":4},"o":{"a":0,"k":65,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 1","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"d":1,"ty":"el","s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":150.000006109625,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[1,0],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[163,44.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[0,0.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-182.5,76.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"rc","d":1,"s":{"a":0,"k":[48,48],"ix":2},"p":{"a":0,"k":[-32,25],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":150.000006109625,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/mnemonics.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/mnemonics.json deleted file mode 100644 index 5c2020b2..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/mnemonics.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.0.0","fr":25,"ip":0,"op":101,"w":1080,"h":1080,"nm":"mnemonics","ddd":1,"assets":[{"id":"comp_15","layers":[{"ddd":1,"ind":1,"ty":4,"nm":"pink circle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"rx":{"a":0,"k":0,"ix":8},"ry":{"a":0,"k":-7,"ix":9},"rz":{"a":0,"k":0,"ix":10},"or":{"a":0,"k":[0,0,0],"ix":7},"p":{"a":0,"k":[933.891,385.891,0],"ix":2,"x":"var $bm_rt;\nvar l;\nl = thisComp.layer('pink line.Point1');\nvar point = thisComp.layer('pink line.Point1').content('Simple Path').content('Path 1').path.pointOnPath(div(thisComp.layer('pink line.Point1').content('Point Trim').offset, 360));\n$bm_rt = hasParent ? parent.fromComp(l.toComp(point)) : l.toComp(point);"},"a":{"a":0,"k":[-33.109,-122.109,0],"ix":1},"s":{"a":0,"k":[61,61,61],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wayfinder Follower","np":4,"mn":"Pseudo/WayfinderFollower","ix":1,"en":1,"ef":[{"ty":0,"nm":"Position","mn":"Pseudo/WayfinderFollower-0001","ix":1,"v":{"a":1,"k":[{"i":{"x":[0.502],"y":[1]},"o":{"x":[0.503],"y":[0]},"n":["0p502_1_0p503_0"],"t":0,"s":[97],"e":[3]},{"i":{"x":[0.502],"y":[1]},"o":{"x":[0.495],"y":[0]},"n":["0p502_1_0p495_0"],"t":50,"s":[3],"e":[97]},{"t":100}],"ix":1}},{"ty":0,"nm":"Offset","mn":"Pseudo/WayfinderFollower-0002","ix":2,"v":{"a":0,"k":0,"ix":2}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[49.781,49.781],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.98431372549,0.721568627451,0.756862745098,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":22.1,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-33.109,-122.109],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":226,"st":0,"bm":0},{"ddd":1,"ind":2,"ty":4,"nm":"pink line","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"rx":{"a":0,"k":0,"ix":8},"ry":{"a":0,"k":0,"ix":9},"rz":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p5_1_0p333_0"],"t":0,"s":[-10],"e":[10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.498],"y":[0]},"n":["0p667_1_0p498_0"],"t":50,"s":[10],"e":[-10]},{"t":100}],"ix":10},"or":{"a":0,"k":[0,0,0],"ix":7},"p":{"a":0,"k":[540,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wayfinder Leader","np":5,"mn":"Pseudo/WayfinderLeader","ix":1,"en":1,"ef":[{"ty":0,"nm":"Start","mn":"Pseudo/WayfinderLeader-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":0,"nm":"End","mn":"Pseudo/WayfinderLeader-0002","ix":2,"v":{"a":0,"k":100,"ix":2}},{"ty":0,"nm":"Offset","mn":"Pseudo/WayfinderLeader-0003","ix":3,"v":{"a":0,"k":0,"ix":3}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-100,0],[-100,0],[-100,0],[-100,0]],"o":[[100,0],[100,0],[100,0],[100,0],[0,0]],"v":[[-400,-25],[-200,25],[0,-25],[200,25],[400,-25]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.941176470588,0.486274509804,0.521568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Simple Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1,"x":"var $bm_rt;\n$bm_rt = effect('Wayfinder Leader')(1).value;"},"e":{"a":0,"k":100,"ix":2,"x":"var $bm_rt;\n$bm_rt = effect('Wayfinder Leader')(2).value;"},"o":{"a":0,"k":0,"ix":3,"x":"var $bm_rt;\n$bm_rt = effect('Wayfinder Leader')(3).value;"},"m":2,"ix":2,"nm":"Main Path Trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":226,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"pink line.Point1","cl":"Point1","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-100,0],[-100,0],[-100,0],[-100,0]],"o":[[100,0],[100,0],[100,0],[100,0],[0,0]],"v":[[-400,-25],[-200,25],[0,-25],[200,25],[400,-25]],"c":false},"ix":2,"x":"var $bm_rt;\n$bm_rt = parent.content('Simple Path')('Contents')('Path 1')('Path');"},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = parent.content('Simple Path')('Transform')('Position');"},"a":{"a":0,"k":[0,0],"ix":1,"x":"var $bm_rt;\n$bm_rt = parent.content('Simple Path')('Transform')('Anchor Point');"},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\n$bm_rt = parent.content('Simple Path')('Transform')('Scale');"},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\n$bm_rt = parent.content('Simple Path')('Transform')('Rotation');"},"o":{"a":0,"k":100,"ix":7,"x":"var $bm_rt;\n$bm_rt = parent.content('Simple Path')('Transform')('Opacity');"},"sk":{"a":0,"k":0,"ix":4,"x":"var $bm_rt;\n$bm_rt = parent.content('Simple Path')('Transform')('Skew');"},"sa":{"a":0,"k":0,"ix":5,"x":"var $bm_rt;\n$bm_rt = parent.content('Simple Path')('Transform')('Skew Axis');"},"nm":"Transform"}],"nm":"Simple Path","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2,"x":"var $bm_rt;\n$bm_rt = 0.0001;"},"o":{"a":0,"k":0,"ix":3,"x":"var $bm_rt;\nvar mainTrim, start, end, pos, offset, trim, pointOffset, pointOffset, point;\nmainTrim = parent.content('Main Path Trim');\nstart = mainTrim.start;\nend = mainTrim.end;\npos = thisComp.layer('pink circle').effect('Wayfinder Follower')(1);\noffset = mainTrim.offset;\ntrim = sub(360, mul(thisProperty.propertyGroup(1).end, 3.6));\npointOffset = thisComp.layer('pink circle').effect('Wayfinder Follower')(2);\nif (pointOffset < 0)\n pointOffset = sub(360, mod(Math.abs(pointOffset), 360));\npoint = mod(sum(mul(div(pos, 100), trim), pointOffset), 360);\n$bm_rt = sum(linear(point, 0, 360, mul(div(start, 100), 360), mul(div(end, 100), trim)), offset);"},"m":2,"ix":3,"nm":"Point Trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":226,"st":0,"bm":0}]},{"id":"comp_16","layers":[{"ddd":1,"ind":1,"ty":4,"nm":"purple line","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"rx":{"a":0,"k":0,"ix":8},"ry":{"a":0,"k":0,"ix":9},"rz":{"a":1,"k":[{"i":{"x":[0.503],"y":[1]},"o":{"x":[0.496],"y":[0]},"n":["0p503_1_0p496_0"],"t":0,"s":[10],"e":[-10]},{"i":{"x":[0.497],"y":[1]},"o":{"x":[0.495],"y":[0]},"n":["0p497_1_0p495_0"],"t":50,"s":[-10],"e":[10]},{"t":100}],"ix":10},"or":{"a":0,"k":[0,0,0],"ix":7},"p":{"a":0,"k":[540,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wayfinder Leader","np":5,"mn":"Pseudo/WayfinderLeader","ix":1,"en":1,"ef":[{"ty":0,"nm":"Start","mn":"Pseudo/WayfinderLeader-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":0,"nm":"End","mn":"Pseudo/WayfinderLeader-0002","ix":2,"v":{"a":0,"k":100,"ix":2}},{"ty":0,"nm":"Offset","mn":"Pseudo/WayfinderLeader-0003","ix":3,"v":{"a":0,"k":0,"ix":3}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-57.143,0],[-57.143,0],[-57.143,0],[-57.143,0],[-57.143,0],[-57.143,0],[-57.143,0]],"o":[[57.143,0],[57.143,0],[57.143,0],[57.143,0],[57.143,0],[57.143,0],[57.143,0],[0,0]],"v":[[-400,-25],[-285.714,25],[-171.429,-25],[-57.143,25],[57.143,-25],[171.429,25],[285.714,-25],[400,25]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.470588235294,0.356862745098,0.654901960784,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":15,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Simple Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1,"x":"var $bm_rt;\n$bm_rt = effect('Wayfinder Leader')(1).value;"},"e":{"a":0,"k":100,"ix":2,"x":"var $bm_rt;\n$bm_rt = effect('Wayfinder Leader')(2).value;"},"o":{"a":0,"k":0,"ix":3,"x":"var $bm_rt;\n$bm_rt = effect('Wayfinder Leader')(3).value;"},"m":2,"ix":2,"nm":"Main Path Trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":226,"st":0,"bm":0},{"ddd":1,"ind":2,"ty":4,"nm":"small purple circle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"rx":{"a":0,"k":0,"ix":8},"ry":{"a":0,"k":-2,"ix":9},"rz":{"a":0,"k":0,"ix":10},"or":{"a":0,"k":[0,0,0],"ix":7},"p":{"a":0,"k":[138.573,471.552,0],"ix":2,"x":"var $bm_rt;\nvar l;\nl = thisComp.layer('purple line.Point1');\nvar point = thisComp.layer('purple line.Point1').content('Simple Path').content('Path 1').path.pointOnPath(div(thisComp.layer('purple line.Point1').content('Point Trim').offset, 360));\n$bm_rt = hasParent ? parent.fromComp(l.toComp(point)) : l.toComp(point);"},"a":{"a":0,"k":[106.148,-378.979,0],"ix":1},"s":{"a":0,"k":[127.821,127.821,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wayfinder Follower","np":4,"mn":"Pseudo/WayfinderFollower","ix":1,"en":1,"ef":[{"ty":0,"nm":"Position","mn":"Pseudo/WayfinderFollower-0001","ix":1,"v":{"a":1,"k":[{"i":{"x":[0.485],"y":[1]},"o":{"x":[0.495],"y":[0]},"n":["0p485_1_0p495_0"],"t":0,"s":[3],"e":[97]},{"i":{"x":[0.503],"y":[1]},"o":{"x":[0.508],"y":[0]},"n":["0p503_1_0p508_0"],"t":50,"s":[97],"e":[3]},{"t":100}],"ix":1}},{"ty":0,"nm":"Offset","mn":"Pseudo/WayfinderFollower-0002","ix":2,"v":{"a":0,"k":0,"ix":2}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[32.712,32.712],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176470588,0.682352941176,0.803921568627,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[106.148,-378.979],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":226,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"purple line.Point1","cl":"Point1","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-57.143,0],[-57.143,0],[-57.143,0],[-57.143,0],[-57.143,0],[-57.143,0],[-57.143,0]],"o":[[57.143,0],[57.143,0],[57.143,0],[57.143,0],[57.143,0],[57.143,0],[57.143,0],[0,0]],"v":[[-400,-25],[-285.714,25],[-171.429,-25],[-57.143,25],[57.143,-25],[171.429,25],[285.714,-25],[400,25]],"c":false},"ix":2,"x":"var $bm_rt;\n$bm_rt = parent.content('Simple Path')('Contents')('Path 1')('Path');"},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[1.345,81.745],"ix":2,"x":"var $bm_rt;\n$bm_rt = parent.content('Simple Path')('Transform')('Position');"},"a":{"a":0,"k":[0,0],"ix":1,"x":"var $bm_rt;\n$bm_rt = parent.content('Simple Path')('Transform')('Anchor Point');"},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\n$bm_rt = parent.content('Simple Path')('Transform')('Scale');"},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\n$bm_rt = parent.content('Simple Path')('Transform')('Rotation');"},"o":{"a":0,"k":100,"ix":7,"x":"var $bm_rt;\n$bm_rt = parent.content('Simple Path')('Transform')('Opacity');"},"sk":{"a":0,"k":0,"ix":4,"x":"var $bm_rt;\n$bm_rt = parent.content('Simple Path')('Transform')('Skew');"},"sa":{"a":0,"k":0,"ix":5,"x":"var $bm_rt;\n$bm_rt = parent.content('Simple Path')('Transform')('Skew Axis');"},"nm":"Transform"}],"nm":"Simple Path","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2,"x":"var $bm_rt;\n$bm_rt = 0.0001;"},"o":{"a":0,"k":0,"ix":3,"x":"var $bm_rt;\nvar mainTrim, start, end, pos, offset, trim, pointOffset, pointOffset, point;\nmainTrim = parent.content('Main Path Trim');\nstart = mainTrim.start;\nend = mainTrim.end;\npos = thisComp.layer('small purple circle').effect('Wayfinder Follower')(1);\noffset = mainTrim.offset;\ntrim = sub(360, mul(thisProperty.propertyGroup(1).end, 3.6));\npointOffset = thisComp.layer('small purple circle').effect('Wayfinder Follower')(2);\nif (pointOffset < 0)\n pointOffset = sub(360, mod(Math.abs(pointOffset), 360));\npoint = mod(sum(mul(div(pos, 100), trim), pointOffset), 360);\n$bm_rt = sum(linear(point, 0, 360, mul(div(start, 100), 360), mul(div(end, 100), trim)), offset);"},"m":2,"ix":3,"nm":"Point Trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":226,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"NULL CONTROL","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,541,0],"ix":2},"a":{"a":0,"k":[60,60,0],"ix":1},"s":{"a":0,"k":[76,76,100],"ix":6}},"ao":0,"ip":0,"op":101,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"centre yellow circle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,540,0],"ix":2},"a":{"a":0,"k":[-411.797,-229.797,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.234,0.234,0.667],"y":[0.954,0.954,1]},"o":{"x":[0.125,0.125,0.333],"y":[0.419,0.419,0]},"n":["0p234_0p954_0p125_0p419","0p234_0p954_0p125_0p419","0p667_1_0p333_0"],"t":24,"s":[100,100,100],"e":[127.4,127.4,100]},{"i":{"x":[0.552,0.552,0.667],"y":[0.914,0.914,1]},"o":{"x":[0.456,0.456,0.333],"y":[-0.096,-0.096,0]},"n":["0p552_0p914_0p456_-0p096","0p552_0p914_0p456_-0p096","0p667_1_0p333_0"],"t":26,"s":[127.4,127.4,100],"e":[96,96,100]},{"i":{"x":[0.198,0.198,0.667],"y":[1,1,1]},"o":{"x":[0.358,0.358,0.167],"y":[-0.128,-0.128,0]},"n":["0p198_1_0p358_-0p128","0p198_1_0p358_-0p128","0p667_1_0p167_0"],"t":34,"s":[96,96,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"n":["0p667_1_0p167_0","0p667_1_0p167_0","0p667_1_0p167_0"],"t":38,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.234,0.234,0.667],"y":[0.954,0.954,1]},"o":{"x":[0.125,0.125,0.333],"y":[0.419,0.419,0]},"n":["0p234_0p954_0p125_0p419","0p234_0p954_0p125_0p419","0p667_1_0p333_0"],"t":74,"s":[100,100,100],"e":[127.4,127.4,100]},{"i":{"x":[0.552,0.552,0.667],"y":[0.914,0.914,1]},"o":{"x":[0.456,0.456,0.333],"y":[-0.096,-0.096,0]},"n":["0p552_0p914_0p456_-0p096","0p552_0p914_0p456_-0p096","0p667_1_0p333_0"],"t":76,"s":[127.4,127.4,100],"e":[96,96,100]},{"i":{"x":[0.198,0.198,0.667],"y":[1,1,1]},"o":{"x":[0.358,0.358,0.167],"y":[-0.128,-0.128,0]},"n":["0p198_1_0p358_-0p128","0p198_1_0p358_-0p128","0p667_1_0p167_0"],"t":84,"s":[96,96,100],"e":[100,100,100]},{"t":88}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-12.262,0],[0,-12.262],[12.262,0],[0,12.262]],"o":[[12.262,0],[0,12.262],[-12.262,0],[0,-12.262]],"v":[[0,-22.203],[22.203,0],[0,22.203],[-22.203,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[-411.797,-229.797],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.988235294819,0.929411768913,0.35686275363,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":101,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"large circle R","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60,59,0],"ix":2},"a":{"a":0,"k":[41.106,-37.462,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[398.419,-356.462],[39.106,-356.462],[39.106,302.245],[398.419,302.245]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"ef":[{"ty":5,"nm":"Wayfinder Leader","np":5,"mn":"Pseudo/WayfinderLeader","ix":1,"en":1,"ef":[{"ty":0,"nm":"Start","mn":"Pseudo/WayfinderLeader-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":0,"nm":"End","mn":"Pseudo/WayfinderLeader-0002","ix":2,"v":{"a":0,"k":100,"ix":2}},{"ty":0,"nm":"Offset","mn":"Pseudo/WayfinderLeader-0003","ix":3,"v":{"a":0,"k":0,"ix":3}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-153.567,0],[0,-153.567],[153.567,0],[0,153.567]],"o":[[153.567,0],[0,153.567],[-153.567,0],[0,-153.567]],"v":[[0,-278.058],[278.058,0],[0,278.058],[-278.058,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.629320750517,0.552072622262,0.71171875,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":30,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[41.106,-37.462],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1,"x":"var $bm_rt;\n$bm_rt = effect('Wayfinder Leader')(1).value;"},"e":{"a":0,"k":100,"ix":2,"x":"var $bm_rt;\n$bm_rt = effect('Wayfinder Leader')(2).value;"},"o":{"a":0,"k":0,"ix":3,"x":"var $bm_rt;\n$bm_rt = effect('Wayfinder Leader')(3).value;"},"m":2,"ix":2,"nm":"Main Path Trim","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":101,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"pink line & circle","parent":1,"refId":"comp_15","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[58.026,82.711,0],"ix":2},"a":{"a":0,"k":[540,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1080,"h":1080,"ip":0,"op":101,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"purple line and circle","parent":1,"refId":"comp_16","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[52.105,65.921,0],"ix":2},"a":{"a":0,"k":[540,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1080,"h":1080,"ip":0,"op":101,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"large circle L","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60,59,0],"ix":2},"a":{"a":0,"k":[41.106,-37.462,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[42.419,-356.462],[-316.894,-356.462],[-316.894,302.245],[42.419,302.245]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[556.115,556.115],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.629320750517,0.552072622262,0.71171875,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":30,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[41.106,-37.462],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":101,"st":0,"bm":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/movie_loading.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/movie_loading.json deleted file mode 100644 index 93990ccc..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/movie_loading.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.1","fr":29.9700012207031,"ip":0,"op":150.000006109625,"w":100,"h":100,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 12","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":0,"s":[287.27],"e":[646.501]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":48,"s":[646.501],"e":[1006.517]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":79,"s":[1006.517],"e":[1366.011]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":109,"s":[1366.011],"e":[1725.391]},{"t":149.000006068894}],"ix":10},"p":{"a":0,"k":[49.123,50.123,0],"ix":2},"a":{"a":0,"k":[-17.377,-13.377,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[78.246,78.246],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.623,-1.377],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[25.928,25.928],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":163.000006639126,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 11","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":0,"s":[214.668],"e":[574.301]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":48,"s":[574.301],"e":[935.271]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":79,"s":[935.271],"e":[1295.556]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":109,"s":[1295.556],"e":[1655.136]},{"t":149.000006068894}],"ix":10},"p":{"a":0,"k":[49.123,50.123,0],"ix":2},"a":{"a":0,"k":[-17.377,-13.377,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[78.246,78.246],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.623,-1.377],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[25.928,25.928],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":163.000006639126,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":0,"s":[143.536],"e":[503.692]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":48,"s":[503.692],"e":[863.287]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":79,"s":[863.287],"e":[1223.296]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":109,"s":[1223.296],"e":[1582.854]},{"t":149.000006068894}],"ix":10},"p":{"a":0,"k":[49.123,50.123,0],"ix":2},"a":{"a":0,"k":[-17.377,-13.377,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[78.246,78.246],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.623,-1.377],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[25.928,25.928],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":163.000006639126,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":0,"s":[70.817],"e":[430.711]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":48,"s":[430.711],"e":[791.651]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":79,"s":[791.651],"e":[1150.155]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":109,"s":[1150.155],"e":[1510.652]},{"t":149.000006068894}],"ix":10},"p":{"a":0,"k":[49.123,50.123,0],"ix":2},"a":{"a":0,"k":[-17.377,-13.377,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[78.246,78.246],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.623,-1.377],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[25.928,25.928],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":163.000006639126,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":0,"s":[0],"e":[360]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":48,"s":[360],"e":[720]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":79,"s":[720],"e":[1080]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":109,"s":[1080],"e":[1440]},{"t":149.000006068894}],"ix":10},"p":{"a":0,"k":[49.123,50.123,0],"ix":2},"a":{"a":0,"k":[-17.377,-13.377,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[78.246,78.246],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.623,-1.377],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[25.928,25.928],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":163.000006639126,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[49.373,50.123,0],"ix":2},"a":{"a":0,"k":[1.623,-1.377,0],"ix":1},"s":{"a":0,"k":[45.779,45.779,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[78.246,78.246],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.623,-1.377],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[25.928,25.928],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":167.000006802049,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[49.123,50.623,0],"ix":2},"a":{"a":0,"k":[1.623,-1.377,0],"ix":1},"s":{"a":0,"k":[101.278,101.278,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[78.246,78.246],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.623,-1.377],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162.000006598395,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Shape Layer 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[34.906,4.721],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[23.498,36.876],"ix":2},"a":{"a":0,"k":[0.344,0.2],"ix":1},"s":{"a":0,"k":[100,92.67],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":167.000006802049,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/mughead.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/mughead.json deleted file mode 100644 index ffbb6e0e..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/mughead.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.10.2","fr":12,"ip":0,"op":6,"w":800,"h":600,"nm":"Mughead","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"head tip","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,-17,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.51,"y":1},"o":{"x":0.49,"y":0},"n":"0p51_1_0p49_0","t":0,"s":[{"i":[[101.998,-0.478],[0,0],[-55.505,1.557],[0,0]],"o":[[-101.998,0.478],[0,0],[55.505,-1.557],[0,0]],"v":[[4.002,-70.022],[-121,-64],[2.495,-70.943],[123,-62]],"c":true}],"e":[{"i":[[101.998,-0.478],[5.5,-3],[-55.505,1.557],[-1.5,2.75]],"o":[[-101.998,0.478],[-5.5,3],[55.505,-1.557],[1.5,-2.75]],"v":[[7.002,-70.522],[-121,-64],[6.995,-60.693],[123,-63.25]],"c":true}]},{"i":{"x":0.51,"y":1},"o":{"x":0.49,"y":0},"n":"0p51_1_0p49_0","t":3,"s":[{"i":[[101.998,-0.478],[5.5,-3],[-55.505,1.557],[-1.5,2.75]],"o":[[-101.998,0.478],[-5.5,3],[55.505,-1.557],[1.5,-2.75]],"v":[[7.002,-70.522],[-121,-64],[6.995,-60.693],[123,-63.25]],"c":true}],"e":[{"i":[[101.998,-0.478],[0,0],[-55.505,1.557],[0,0]],"o":[[-101.998,0.478],[0,0],[55.505,-1.557],[0,0]],"v":[[4.002,-70.022],[-121,-64],[2.495,-70.943],[123,-62]],"c":true}]},{"t":6}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Hose 2::Wrist","hd":true,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\ntry {\n var parentRot = hasParent ? parentTotal() : 0;\n var rotCalc = sub(thisLayer('ADBE Root Vectors Group')('Admin')('Transform')('Rotation'), parentRot);\n $bm_rt = sum(rotCalc, value);\n} catch (err) {\n $bm_rt = value;\n}\n;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain += '.parent';\n parentVal += eval([layerChain][0]).rotation;\n }\n return parentVal;\n}"},"p":{"a":1,"k":[{"i":{"x":0.49,"y":1},"o":{"x":0.37,"y":0},"n":"0p49_1_0p37_0","t":0,"s":[288,409,0],"e":[321,415,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.49,"y":1},"o":{"x":0.37,"y":0},"n":"0p49_1_0p37_0","t":3,"s":[321,415,0],"e":[288,409,0],"to":[0,0,0],"ti":[0,0,0]},{"t":6}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6,"x":"var $bm_rt;\n$bm_rt = [\n 100,\n 100\n];"}},"ao":0,"ef":[{"ty":5,"nm":"RubberHose 2","np":18,"mn":"Pseudo/3bf5uID/RubberHose_2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Hose Length","mn":"Pseudo/3bf5uID/RubberHose_2-0001","ix":1,"v":{"a":0,"k":220,"ix":1}},{"ty":0,"nm":"Bend Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0002","ix":2,"v":{"a":0,"k":100,"ix":2}},{"ty":0,"nm":"Realism","mn":"Pseudo/3bf5uID/RubberHose_2-0003","ix":3,"v":{"a":0,"k":0,"ix":3}},{"ty":0,"nm":"Bend Direction","mn":"Pseudo/3bf5uID/RubberHose_2-0004","ix":4,"v":{"a":0,"k":-100,"ix":4}},{"ty":7,"nm":"Auto Rotate Start","mn":"Pseudo/3bf5uID/RubberHose_2-0005","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":7,"nm":"Auto Rotate End","mn":"Pseudo/3bf5uID/RubberHose_2-0006","ix":6,"v":{"a":0,"k":1,"ix":6}},{"ty":6,"nm":"Math Stuff","mn":"Pseudo/3bf5uID/RubberHose_2-0007","ix":7,"v":0},{"ty":3,"nm":"A","mn":"Pseudo/3bf5uID/RubberHose_2-0008","ix":8,"v":{"a":0,"k":[44,38],"ix":8,"x":"var $bm_rt;\n$bm_rt = thisLayer.toComp([\n 0,\n 0,\n 0\n]);"}},{"ty":3,"nm":"B","mn":"Pseudo/3bf5uID/RubberHose_2-0009","ix":9,"v":{"a":0,"k":[0,0],"ix":9,"x":"var $bm_rt;\ntry {\n var b = thisLayer(2)('Admin')(2)('B')(2)(1)._name;\n $bm_rt = thisComp.layer(b).toComp([\n 0,\n 0,\n 0\n ]);\n} catch (err) {\n $bm_rt = value;\n}"}},{"ty":0,"nm":"Outer Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0010","ix":10,"v":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\nvar a = thisLayer(4)('RubberHose 2')('A');\nvar b = thisLayer(4)('RubberHose 2')('B');\nvar s = length(a, b);\n$bm_rt = mul(Math.sin(0.78539816339), s);"}},{"ty":0,"nm":"Inner Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0011","ix":11,"v":{"a":0,"k":0,"ix":11,"x":"var $bm_rt;\nvar eff = thisLayer(4)('RubberHose 2');\nvar bendRad = eff('Bend Radius');\nvar hoseLength = div(eff('Hose Length'), 2);\nvar realism = eff('Realism');\nvar bendDir = div(eff('Bend Direction'), 100);\nvar sFac = eff('Parent Scale');\nvar straight = eff('Straight');\nvar autoFlop = eff('AutoFlop');\nvar roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\nvar innerRad;\nif (hoseLength > straight) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n} else {\n innerRad = straight;\n}\ninnerRad *= Math.abs(sFac);\ninnerRad = linear(Math.abs(autoFlop), mul(straight, Math.max(Math.abs(sFac), 0.001)), innerRad);\n$bm_rt = innerRad;"}},{"ty":0,"nm":"Straight","mn":"Pseudo/3bf5uID/RubberHose_2-0012","ix":12,"v":{"a":0,"k":0,"ix":12,"x":"var $bm_rt;\nvar sFac = thisLayer(4)('RubberHose 2')('Parent Scale');\nvar outerRad = div(thisLayer(4)('RubberHose 2')('Outer Radius'), Math.max(Math.abs(sFac), 0.001));\n;\n$bm_rt = div(mul(1.4142135623731, outerRad), 2);"}},{"ty":0,"nm":"Base Rotation","mn":"Pseudo/3bf5uID/RubberHose_2-0013","ix":13,"v":{"a":0,"k":0,"ix":13,"x":"var $bm_rt;\nvar a = thisLayer(4)('RubberHose 2')('A');\nvar b = thisLayer(4)('RubberHose 2')('B');\n$bm_rt = radiansToDegrees(Math.atan2(sub(a[1], b[1]), sub(a[0], b[0])));"}},{"ty":0,"nm":"AutoFlop","mn":"Pseudo/3bf5uID/RubberHose_2-0014","ix":14,"v":{"a":0,"k":0,"ix":14,"x":"var $bm_rt;\nvar hasAF = false, isEnabled = false, output;\ntry {\n var lyrAF = thisComp.layer(sum(thisLayer._name.split('::')[0], '::AutoFlop'));\n isEnabled = lyrAF(4)('Enable')(1);\n var falloffAngle = lyrAF(4)('Falloff')(1);\n hasAF = true;\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = thisLayer(4)('RubberHose 2')('B');\n} catch (e) {\n}\nif (hasAF && isEnabled == 1) {\n var threshRot = lyrAF('ADBE Transform Group')('ADBE Rotate Z');\n threshRot %= 360;\n var ctrlAngle = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var offsetAngle = sub(threshRot, ctrlAngle);\n offsetAngle %= 360;\n var sign = offsetAngle > 0 && offsetAngle < 180 || offsetAngle < -180 ? -1 : 1;\n var absAngle = Math.abs(offsetAngle);\n if (absAngle > 90) {\n absAngle = Math.abs(sub(absAngle, 180));\n }\n if (absAngle > 90) {\n absAngle = Math.abs(sub(absAngle, 180));\n }\n output = linear(absAngle, 0, falloffAngle, 0, 1);\n output *= sign;\n} else {\n output = 1;\n}\n$bm_rt = output;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain += '.parent';\n parentVal += eval([layerChain][0]).rotation;\n }\n return parentVal;\n}"}},{"ty":0,"nm":"Parent Scale","mn":"Pseudo/3bf5uID/RubberHose_2-0015","ix":15,"v":{"a":0,"k":0,"ix":15,"x":"var $bm_rt;\nvar sFactor = 1;\nvar scaleNorm = 0;\nvar layerChain = 'thisLayer';\nwhile (eval([layerChain][0]).hasParent) {\n layerChain += '.parent';\n scaleNorm = div(eval(layerChain)('ADBE Transform Group')('ADBE Scale')[0], 100);\n sFactor = mul(sFactor, scaleNorm);\n}\n$bm_rt = sFactor;"}},{"ty":6,"nm":"","mn":"Pseudo/3bf5uID/RubberHose_2-0016","ix":16,"v":0}]}],"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Hose 2::Wrist","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[20,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Hose 2::Shoulder","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\nvar eff = thisLayer(4)('RubberHose 2');\nvar autoRotate = eff('Auto Rotate End');\nif (autoRotate == 1) {\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = eff('B');\n var s = length(a, b);\n var sFac = eff('Parent Scale');\n var autoFlop = 1;\n var realism = eff('Realism');\n var bendDir = div(eff('Bend Direction'), 100);\n var hoseLength = div(eff('Hose Length'), 2);\n var bendRad = eff('Bend Radius');\n var autoFlop = eff('AutoFlop');\n var baseRot = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var outerRad = mul(Math.sin(0.78539816339), s);\n var straight = div(mul(1.4142135623731, outerRad), 2);\n straight /= Math.max(Math.abs(sFac), 0.001);\n var roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\n var innerRad;\n if (hoseLength > straight) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n } else {\n innerRad = straight;\n }\n innerRad = linear(Math.abs(autoFlop), straight, innerRad);\n var flopDir = 1;\n if (bendDir < 0) {\n flopDir = -1;\n }\n flopDir *= autoFlop;\n var opp = mul(sub(innerRad, straight), flopDir);\n var theta = Math.atan(div(opp, Math.max(straight, 0.001)));\n var bendAngle = radiansToDegrees(theta);\n if (sFac < 0) {\n baseRot *= -1;\n }\n bendRad *= div(div(theta, $bm_neg(Math.PI)), linear(s, hoseLength, 0, 2, 0.9));\n var rotCalc = sub(sum(baseRot, bendAngle), bendRad);\n $bm_rt = rotCalc;\n} else {\n $bm_rt = value;\n}\n;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Circle","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-75,0],[75,0]],"c":false},"ix":2},"nm":"01","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-30],[0,30]],"c":false},"ix":2},"nm":"02","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[20,20],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ControlShape","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.560000002384,0,1],"ix":3,"x":"var $bm_rt;\nif (thisLayer.active) {\n try {\n var eff = thisLayer(4)('RubberHose 2');\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = eff('B');\n var straight = eff('Straight');\n var hoseLength = div(eff('Hose Length'), 2);\n if (straight > hoseLength) {\n $bm_rt = [\n 0.51,\n 0.83,\n 0.98,\n 1\n ];\n } else {\n $bm_rt = value;\n }\n } catch (err) {\n $bm_rt = value;\n }\n} else {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = [\n 0,\n 0\n];"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\n$bm_rt = [\n 100,\n 100\n];"},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Control Point","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Hose 1::Wrist","hd":true,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\ntry {\n var parentRot = hasParent ? parentTotal() : 0;\n var rotCalc = sub(thisLayer('ADBE Root Vectors Group')('Admin')('Transform')('Rotation'), parentRot);\n $bm_rt = sum(rotCalc, value);\n} catch (err) {\n $bm_rt = value;\n}\n;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain += '.parent';\n parentVal += eval([layerChain][0]).rotation;\n }\n return parentVal;\n}"},"p":{"a":1,"k":[{"i":{"x":0.49,"y":1},"o":{"x":0.37,"y":0},"n":"0p49_1_0p37_0","t":0,"s":[522,410,0],"e":[487,420,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.49,"y":1},"o":{"x":0.37,"y":0},"n":"0p49_1_0p37_0","t":3,"s":[487,420,0],"e":[522,410,0],"to":[0,0,0],"ti":[0,0,0]},{"t":6}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6,"x":"var $bm_rt;\n$bm_rt = [\n 100,\n 100\n];"}},"ao":0,"ef":[{"ty":5,"nm":"RubberHose 2","np":18,"mn":"Pseudo/3bf5uID/RubberHose_2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Hose Length","mn":"Pseudo/3bf5uID/RubberHose_2-0001","ix":1,"v":{"a":0,"k":220,"ix":1}},{"ty":0,"nm":"Bend Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0002","ix":2,"v":{"a":0,"k":100,"ix":2}},{"ty":0,"nm":"Realism","mn":"Pseudo/3bf5uID/RubberHose_2-0003","ix":3,"v":{"a":0,"k":0,"ix":3}},{"ty":0,"nm":"Bend Direction","mn":"Pseudo/3bf5uID/RubberHose_2-0004","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":7,"nm":"Auto Rotate Start","mn":"Pseudo/3bf5uID/RubberHose_2-0005","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":7,"nm":"Auto Rotate End","mn":"Pseudo/3bf5uID/RubberHose_2-0006","ix":6,"v":{"a":0,"k":1,"ix":6}},{"ty":6,"nm":"Math Stuff","mn":"Pseudo/3bf5uID/RubberHose_2-0007","ix":7,"v":0},{"ty":3,"nm":"A","mn":"Pseudo/3bf5uID/RubberHose_2-0008","ix":8,"v":{"a":0,"k":[44,38],"ix":8,"x":"var $bm_rt;\n$bm_rt = thisLayer.toComp([\n 0,\n 0,\n 0\n]);"}},{"ty":3,"nm":"B","mn":"Pseudo/3bf5uID/RubberHose_2-0009","ix":9,"v":{"a":0,"k":[0,0],"ix":9,"x":"var $bm_rt;\ntry {\n var b = thisLayer(2)('Admin')(2)('B')(2)(1)._name;\n $bm_rt = thisComp.layer(b).toComp([\n 0,\n 0,\n 0\n ]);\n} catch (err) {\n $bm_rt = value;\n}"}},{"ty":0,"nm":"Outer Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0010","ix":10,"v":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\nvar a = thisLayer(4)('RubberHose 2')('A');\nvar b = thisLayer(4)('RubberHose 2')('B');\nvar s = length(a, b);\n$bm_rt = mul(Math.sin(0.78539816339), s);"}},{"ty":0,"nm":"Inner Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0011","ix":11,"v":{"a":0,"k":0,"ix":11,"x":"var $bm_rt;\nvar eff = thisLayer(4)('RubberHose 2');\nvar bendRad = eff('Bend Radius');\nvar hoseLength = div(eff('Hose Length'), 2);\nvar realism = eff('Realism');\nvar bendDir = div(eff('Bend Direction'), 100);\nvar sFac = eff('Parent Scale');\nvar straight = eff('Straight');\nvar autoFlop = eff('AutoFlop');\nvar roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\nvar innerRad;\nif (hoseLength > straight) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n} else {\n innerRad = straight;\n}\ninnerRad *= Math.abs(sFac);\ninnerRad = linear(Math.abs(autoFlop), mul(straight, Math.max(Math.abs(sFac), 0.001)), innerRad);\n$bm_rt = innerRad;"}},{"ty":0,"nm":"Straight","mn":"Pseudo/3bf5uID/RubberHose_2-0012","ix":12,"v":{"a":0,"k":0,"ix":12,"x":"var $bm_rt;\nvar sFac = thisLayer(4)('RubberHose 2')('Parent Scale');\nvar outerRad = div(thisLayer(4)('RubberHose 2')('Outer Radius'), Math.max(Math.abs(sFac), 0.001));\n;\n$bm_rt = div(mul(1.4142135623731, outerRad), 2);"}},{"ty":0,"nm":"Base Rotation","mn":"Pseudo/3bf5uID/RubberHose_2-0013","ix":13,"v":{"a":0,"k":0,"ix":13,"x":"var $bm_rt;\nvar a = thisLayer(4)('RubberHose 2')('A');\nvar b = thisLayer(4)('RubberHose 2')('B');\n$bm_rt = radiansToDegrees(Math.atan2(sub(a[1], b[1]), sub(a[0], b[0])));"}},{"ty":0,"nm":"AutoFlop","mn":"Pseudo/3bf5uID/RubberHose_2-0014","ix":14,"v":{"a":0,"k":0,"ix":14,"x":"var $bm_rt;\nvar hasAF = false, isEnabled = false, output;\ntry {\n var lyrAF = thisComp.layer(sum(thisLayer._name.split('::')[0], '::AutoFlop'));\n isEnabled = lyrAF(4)('Enable')(1);\n var falloffAngle = lyrAF(4)('Falloff')(1);\n hasAF = true;\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = thisLayer(4)('RubberHose 2')('B');\n} catch (e) {\n}\nif (hasAF && isEnabled == 1) {\n var threshRot = lyrAF('ADBE Transform Group')('ADBE Rotate Z');\n threshRot %= 360;\n var ctrlAngle = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var offsetAngle = sub(threshRot, ctrlAngle);\n offsetAngle %= 360;\n var sign = offsetAngle > 0 && offsetAngle < 180 || offsetAngle < -180 ? -1 : 1;\n var absAngle = Math.abs(offsetAngle);\n if (absAngle > 90) {\n absAngle = Math.abs(sub(absAngle, 180));\n }\n if (absAngle > 90) {\n absAngle = Math.abs(sub(absAngle, 180));\n }\n output = linear(absAngle, 0, falloffAngle, 0, 1);\n output *= sign;\n} else {\n output = 1;\n}\n$bm_rt = output;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain += '.parent';\n parentVal += eval([layerChain][0]).rotation;\n }\n return parentVal;\n}"}},{"ty":0,"nm":"Parent Scale","mn":"Pseudo/3bf5uID/RubberHose_2-0015","ix":15,"v":{"a":0,"k":0,"ix":15,"x":"var $bm_rt;\nvar sFactor = 1;\nvar scaleNorm = 0;\nvar layerChain = 'thisLayer';\nwhile (eval([layerChain][0]).hasParent) {\n layerChain += '.parent';\n scaleNorm = div(eval(layerChain)('ADBE Transform Group')('ADBE Scale')[0], 100);\n sFactor = mul(sFactor, scaleNorm);\n}\n$bm_rt = sFactor;"}},{"ty":6,"nm":"","mn":"Pseudo/3bf5uID/RubberHose_2-0016","ix":16,"v":0}]}],"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Hose 1::Wrist","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[20,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Hose 1::Shoulder","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\nvar eff = thisLayer(4)('RubberHose 2');\nvar autoRotate = eff('Auto Rotate End');\nif (autoRotate == 1) {\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = eff('B');\n var s = length(a, b);\n var sFac = eff('Parent Scale');\n var autoFlop = 1;\n var realism = eff('Realism');\n var bendDir = div(eff('Bend Direction'), 100);\n var hoseLength = div(eff('Hose Length'), 2);\n var bendRad = eff('Bend Radius');\n var autoFlop = eff('AutoFlop');\n var baseRot = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var outerRad = mul(Math.sin(0.78539816339), s);\n var straight = div(mul(1.4142135623731, outerRad), 2);\n straight /= Math.max(Math.abs(sFac), 0.001);\n var roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\n var innerRad;\n if (hoseLength > straight) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n } else {\n innerRad = straight;\n }\n innerRad = linear(Math.abs(autoFlop), straight, innerRad);\n var flopDir = 1;\n if (bendDir < 0) {\n flopDir = -1;\n }\n flopDir *= autoFlop;\n var opp = mul(sub(innerRad, straight), flopDir);\n var theta = Math.atan(div(opp, Math.max(straight, 0.001)));\n var bendAngle = radiansToDegrees(theta);\n if (sFac < 0) {\n baseRot *= -1;\n }\n bendRad *= div(div(theta, $bm_neg(Math.PI)), linear(s, hoseLength, 0, 2, 0.9));\n var rotCalc = sub(sum(baseRot, bendAngle), bendRad);\n $bm_rt = rotCalc;\n} else {\n $bm_rt = value;\n}\n;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Circle","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-75,0],[75,0]],"c":false},"ix":2},"nm":"01","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-30],[0,30]],"c":false},"ix":2},"nm":"02","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[20,20],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ControlShape","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.560000002384,0,1],"ix":3,"x":"var $bm_rt;\nif (thisLayer.active) {\n try {\n var eff = thisLayer(4)('RubberHose 2');\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = eff('B');\n var straight = eff('Straight');\n var hoseLength = div(eff('Hose Length'), 2);\n if (straight > hoseLength) {\n $bm_rt = [\n 0.51,\n 0.83,\n 0.98,\n 1\n ];\n } else {\n $bm_rt = value;\n }\n } catch (err) {\n $bm_rt = value;\n }\n} else {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = [\n 0,\n 0\n];"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\n$bm_rt = [\n 100,\n 100\n];"},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Control Point","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Glove 2","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":215.722,"ix":10},"p":{"a":0,"k":[-9.024,16.45,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[75,-75,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[9.406,-0.333]],"o":[[0,0],[0,0]],"v":[[5.63,-5.5],[-5.631,5.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.078000005086,0.078000005086,0.078000005086,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[434.721,400.782],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[16.333,-1.856],[0,0]],"v":[[-10.333,0.928],[10.333,-0.072]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.078000005086,0.078000005086,0.078000005086,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[421.351,351.021],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[12.964,-1.063],[0,0]],"v":[[-8.982,-1.135],[8.982,2.198]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.078000005086,0.078000005086,0.078000005086,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[433.703,371.083],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[1,15.957],[0,0]],"v":[[3.834,-12],[-4.833,12]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.078000005086,0.078000005086,0.078000005086,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[425.184,406.282],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.175,-0.137],[0.131,-0.101],[0.245,-0.208],[0.778,-0.842],[0.87,-1.172],[0.398,-0.659],[0.375,-0.694],[0.346,-0.705],[0.294,-0.695],[0.227,-0.659],[0.14,-0.593],[0.07,-0.491],[0.055,-0.354],[0,0],[0.054,0.719],[0.037,0.504],[0.007,0.628],[-0.077,0.717],[-0.14,0.778],[-0.2,0.812],[-0.258,0.816],[-0.297,0.796],[-0.311,0.756],[-0.675,1.142],[-0.469,0.655],[-0.17,0.201],[0,0],[-1.292,-1.055],[1.054,-1.293]],"o":[[0,0],[-0.101,0.069],[-0.477,0.419],[-0.792,0.827],[-0.422,0.593],[-0.429,0.644],[-0.406,0.683],[-0.359,0.703],[-0.3,0.695],[-0.231,0.659],[-0.13,0.594],[-0.077,0.493],[-0.11,0.713],[0,0],[-0.027,-0.362],[-0.043,-0.507],[0.002,-0.627],[0.074,-0.715],[0.134,-0.778],[0.187,-0.816],[0.227,-0.829],[0.267,-0.811],[0.65,-1.496],[0.658,-1.153],[0.237,-0.322],[0.14,-0.171],[1.054,-1.292],[1.293,1.054],[-0.146,0.179]],"v":[[5.122,-7.913],[4.921,-7.758],[4.389,-7.327],[2.435,-5.438],[-0.095,-2.403],[-1.37,-0.541],[-2.564,1.478],[-3.625,3.591],[-4.512,5.721],[-5.206,7.781],[-5.715,9.674],[-6.077,11.304],[-6.275,12.58],[-6.448,13.7],[-6.534,12.571],[-6.629,11.265],[-6.646,9.562],[-6.577,7.534],[-6.355,5.265],[-5.948,2.844],[-5.349,0.363],[-4.576,-2.088],[-3.665,-4.424],[-1.646,-8.434],[0.121,-11.167],[0.724,-11.951],[0.938,-12.214],[5.186,-12.645],[5.618,-8.396]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078000005086,0.078000005086,0.078000005086,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[366.726,359.156],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.143,-0.129],[0.265,-0.26],[0.83,-1.04],[0.472,-0.609],[0.435,-0.722],[0.419,-0.789],[0.4,-0.822],[0.367,-0.83],[0.299,-0.817],[0.228,-0.768],[0.148,-0.687],[0.063,-0.567],[0.056,-0.408],[0,0],[0.053,0.825],[0.037,0.578],[0.007,0.717],[-0.083,0.819],[-0.128,0.894],[-0.189,0.936],[-0.271,0.936],[-0.313,0.915],[-0.333,0.866],[-0.33,0.792],[-0.367,0.659],[-0.494,0.765],[-0.18,0.235],[0,0],[-1.336,-0.995],[0.995,-1.336],[0.142,-0.129]],"o":[[0,0],[-0.115,0.094],[-0.517,0.532],[-0.434,0.504],[-0.427,0.636],[-0.454,0.714],[-0.454,0.773],[-0.427,0.814],[-0.353,0.837],[-0.292,0.82],[-0.238,0.769],[-0.131,0.687],[-0.077,0.567],[-0.111,0.82],[0,0],[-0.027,-0.415],[-0.05,-0.581],[0.01,-0.716],[0.074,-0.819],[0.136,-0.892],[0.204,-0.93],[0.245,-0.945],[0.278,-0.928],[0.315,-0.875],[0.378,-0.767],[0.689,-1.34],[0.255,-0.378],[0.149,-0.201],[0.995,-1.336],[1.336,0.995],[-0.119,0.159],[0,0]],"v":[[5.468,-10.041],[5.249,-9.844],[4.663,-9.289],[2.557,-6.932],[1.237,-5.225],[-0.122,-3.214],[-1.457,-0.965],[-2.699,1.451],[-3.793,3.958],[-4.701,6.465],[-5.403,8.871],[-5.916,11.071],[-6.28,12.956],[-6.48,14.426],[-6.654,15.715],[-6.737,14.418],[-6.833,12.921],[-6.848,10.972],[-6.778,8.654],[-6.555,6.061],[-6.141,3.292],[-5.528,0.452],[-4.731,-2.362],[-3.789,-5.051],[-2.757,-7.527],[-1.683,-9.698],[0.183,-12.881],[0.822,-13.794],[1.051,-14.102],[5.272,-14.72],[5.889,-10.499],[5.497,-10.066]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078000005086,0.078000005086,0.078000005086,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[375.606,369.696],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.154,-0.142],[0.285,-0.285],[0.89,-1.136],[0.506,-0.664],[0.466,-0.787],[0.447,-0.857],[0.426,-0.893],[0.391,-0.901],[0.317,-0.886],[0.24,-0.832],[0.155,-0.742],[0.064,-0.613],[0.057,-0.44],[0,0],[0.05,0.89],[0.036,0.624],[0.002,0.773],[-0.095,0.882],[-0.145,0.962],[-0.211,1.006],[-0.299,1.006],[-0.344,0.982],[-0.365,0.929],[-0.36,0.848],[-0.399,0.705],[-0.535,0.816],[-0.192,0.247],[0,0],[-1.33,-1.001],[1.002,-1.33],[0.13,-0.12]],"o":[[0,0],[-0.126,0.107],[-0.558,0.585],[-0.466,0.55],[-0.458,0.693],[-0.484,0.776],[-0.484,0.84],[-0.454,0.884],[-0.373,0.906],[-0.308,0.887],[-0.251,0.832],[-0.136,0.744],[-0.079,0.613],[-0.113,0.886],[0,0],[-0.026,-0.448],[-0.049,-0.626],[0.016,-0.772],[0.086,-0.882],[0.153,-0.96],[0.226,-1.001],[0.27,-1.015],[0.306,-0.997],[0.344,-0.938],[0.412,-0.822],[0.749,-1.434],[0.276,-0.404],[0.161,-0.215],[1.002,-1.33],[1.329,1.002],[-0.11,0.146],[0,0]],"v":[[5.866,-11.157],[5.629,-10.94],[4.995,-10.327],[2.73,-7.747],[1.315,-5.887],[-0.14,-3.697],[-1.565,-1.251],[-2.889,1.374],[-4.051,4.093],[-5.01,6.81],[-5.75,9.415],[-6.286,11.794],[-6.664,13.832],[-6.868,15.421],[-7.046,16.812],[-7.125,15.413],[-7.217,13.797],[-7.218,11.697],[-7.125,9.197],[-6.865,6.405],[-6.398,3.427],[-5.717,0.374],[-4.839,-2.648],[-3.806,-5.535],[-2.678,-8.189],[-1.51,-10.514],[0.515,-13.918],[1.202,-14.889],[1.449,-15.217],[5.671,-15.812],[6.264,-11.59],[5.903,-11.19]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078000005086,0.078000005086,0.078000005086,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[385.397,386.802],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":2,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[16,9.333],[8.667,0.333],[23.897,-4.788],[-8.368,-26.683],[1.748,-1.464],[-4.237,-5.06],[0,0],[-5.06,4.237],[-0.51,2.603],[0,0],[-9.49,9.835]],"o":[[9.667,-10.333],[-1.333,-14.667],[-24.637,4.935],[-2.112,0.313],[-5.06,4.237],[0,0],[4.237,5.06],[2.18,-1.825],[18.318,4.86],[0,0],[10.369,-10.746]],"v":[[41.819,-10.251],[30.819,-32.584],[-17.848,-50.584],[-46.171,9.291],[-52.085,11.932],[-53.582,28.836],[-36.165,49.638],[-19.261,51.135],[-15.21,44.254],[19.486,34.749],[47.45,29.495]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.078000005086,0.078000005086,0.078000005086,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.866,383.533],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":3,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Glove ","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":152.627,"ix":10},"p":{"a":0,"k":[6.654,26.986,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[-75,-75,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[9.406,-0.333]],"o":[[0,0],[0,0]],"v":[[5.63,-5.5],[-5.631,5.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.078000005086,0.078000005086,0.078000005086,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[434.721,400.782],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[16.333,-1.856],[0,0]],"v":[[-10.333,0.928],[10.333,-0.072]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.078000005086,0.078000005086,0.078000005086,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[421.351,351.021],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[12.964,-1.063],[0,0]],"v":[[-8.982,-1.135],[8.982,2.198]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.078000005086,0.078000005086,0.078000005086,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[433.703,371.083],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[1,15.957],[0,0]],"v":[[3.834,-12],[-4.833,12]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.078000005086,0.078000005086,0.078000005086,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[425.184,406.282],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.175,-0.137],[0.131,-0.101],[0.245,-0.208],[0.778,-0.842],[0.87,-1.172],[0.398,-0.659],[0.375,-0.694],[0.346,-0.705],[0.294,-0.695],[0.227,-0.659],[0.14,-0.593],[0.07,-0.491],[0.055,-0.354],[0,0],[0.054,0.719],[0.037,0.504],[0.007,0.628],[-0.077,0.717],[-0.14,0.778],[-0.2,0.812],[-0.258,0.816],[-0.297,0.796],[-0.311,0.756],[-0.675,1.142],[-0.469,0.655],[-0.17,0.201],[0,0],[-1.292,-1.055],[1.054,-1.293]],"o":[[0,0],[-0.101,0.069],[-0.477,0.419],[-0.792,0.827],[-0.422,0.593],[-0.429,0.644],[-0.406,0.683],[-0.359,0.703],[-0.3,0.695],[-0.231,0.659],[-0.13,0.594],[-0.077,0.493],[-0.11,0.713],[0,0],[-0.027,-0.362],[-0.043,-0.507],[0.002,-0.627],[0.074,-0.715],[0.134,-0.778],[0.187,-0.816],[0.227,-0.829],[0.267,-0.811],[0.65,-1.496],[0.658,-1.153],[0.237,-0.322],[0.14,-0.171],[1.054,-1.292],[1.293,1.054],[-0.146,0.179]],"v":[[5.122,-7.913],[4.921,-7.758],[4.389,-7.327],[2.435,-5.438],[-0.095,-2.403],[-1.37,-0.541],[-2.564,1.478],[-3.625,3.591],[-4.512,5.721],[-5.206,7.781],[-5.715,9.674],[-6.077,11.304],[-6.275,12.58],[-6.448,13.7],[-6.534,12.571],[-6.629,11.265],[-6.646,9.562],[-6.577,7.534],[-6.355,5.265],[-5.948,2.844],[-5.349,0.363],[-4.576,-2.088],[-3.665,-4.424],[-1.646,-8.434],[0.121,-11.167],[0.724,-11.951],[0.938,-12.214],[5.186,-12.645],[5.618,-8.396]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078000005086,0.078000005086,0.078000005086,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[366.726,359.156],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.143,-0.129],[0.265,-0.26],[0.83,-1.04],[0.472,-0.609],[0.435,-0.722],[0.419,-0.789],[0.4,-0.822],[0.367,-0.83],[0.299,-0.817],[0.228,-0.768],[0.148,-0.687],[0.063,-0.567],[0.056,-0.408],[0,0],[0.053,0.825],[0.037,0.578],[0.007,0.717],[-0.083,0.819],[-0.128,0.894],[-0.189,0.936],[-0.271,0.936],[-0.313,0.915],[-0.333,0.866],[-0.33,0.792],[-0.367,0.659],[-0.494,0.765],[-0.18,0.235],[0,0],[-1.336,-0.995],[0.995,-1.336],[0.142,-0.129]],"o":[[0,0],[-0.115,0.094],[-0.517,0.532],[-0.434,0.504],[-0.427,0.636],[-0.454,0.714],[-0.454,0.773],[-0.427,0.814],[-0.353,0.837],[-0.292,0.82],[-0.238,0.769],[-0.131,0.687],[-0.077,0.567],[-0.111,0.82],[0,0],[-0.027,-0.415],[-0.05,-0.581],[0.01,-0.716],[0.074,-0.819],[0.136,-0.892],[0.204,-0.93],[0.245,-0.945],[0.278,-0.928],[0.315,-0.875],[0.378,-0.767],[0.689,-1.34],[0.255,-0.378],[0.149,-0.201],[0.995,-1.336],[1.336,0.995],[-0.119,0.159],[0,0]],"v":[[5.468,-10.041],[5.249,-9.844],[4.663,-9.289],[2.557,-6.932],[1.237,-5.225],[-0.122,-3.214],[-1.457,-0.965],[-2.699,1.451],[-3.793,3.958],[-4.701,6.465],[-5.403,8.871],[-5.916,11.071],[-6.28,12.956],[-6.48,14.426],[-6.654,15.715],[-6.737,14.418],[-6.833,12.921],[-6.848,10.972],[-6.778,8.654],[-6.555,6.061],[-6.141,3.292],[-5.528,0.452],[-4.731,-2.362],[-3.789,-5.051],[-2.757,-7.527],[-1.683,-9.698],[0.183,-12.881],[0.822,-13.794],[1.051,-14.102],[5.272,-14.72],[5.889,-10.499],[5.497,-10.066]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078000005086,0.078000005086,0.078000005086,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[375.606,369.696],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.154,-0.142],[0.285,-0.285],[0.89,-1.136],[0.506,-0.664],[0.466,-0.787],[0.447,-0.857],[0.426,-0.893],[0.391,-0.901],[0.317,-0.886],[0.24,-0.832],[0.155,-0.742],[0.064,-0.613],[0.057,-0.44],[0,0],[0.05,0.89],[0.036,0.624],[0.002,0.773],[-0.095,0.882],[-0.145,0.962],[-0.211,1.006],[-0.299,1.006],[-0.344,0.982],[-0.365,0.929],[-0.36,0.848],[-0.399,0.705],[-0.535,0.816],[-0.192,0.247],[0,0],[-1.33,-1.001],[1.002,-1.33],[0.13,-0.12]],"o":[[0,0],[-0.126,0.107],[-0.558,0.585],[-0.466,0.55],[-0.458,0.693],[-0.484,0.776],[-0.484,0.84],[-0.454,0.884],[-0.373,0.906],[-0.308,0.887],[-0.251,0.832],[-0.136,0.744],[-0.079,0.613],[-0.113,0.886],[0,0],[-0.026,-0.448],[-0.049,-0.626],[0.016,-0.772],[0.086,-0.882],[0.153,-0.96],[0.226,-1.001],[0.27,-1.015],[0.306,-0.997],[0.344,-0.938],[0.412,-0.822],[0.749,-1.434],[0.276,-0.404],[0.161,-0.215],[1.002,-1.33],[1.329,1.002],[-0.11,0.146],[0,0]],"v":[[5.866,-11.157],[5.629,-10.94],[4.995,-10.327],[2.73,-7.747],[1.315,-5.887],[-0.14,-3.697],[-1.565,-1.251],[-2.889,1.374],[-4.051,4.093],[-5.01,6.81],[-5.75,9.415],[-6.286,11.794],[-6.664,13.832],[-6.868,15.421],[-7.046,16.812],[-7.125,15.413],[-7.217,13.797],[-7.218,11.697],[-7.125,9.197],[-6.865,6.405],[-6.398,3.427],[-5.717,0.374],[-4.839,-2.648],[-3.806,-5.535],[-2.678,-8.189],[-1.51,-10.514],[0.515,-13.918],[1.202,-14.889],[1.449,-15.217],[5.671,-15.812],[6.264,-11.59],[5.903,-11.19]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.078000005086,0.078000005086,0.078000005086,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[385.397,386.802],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":2,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[16,9.333],[8.667,0.333],[23.897,-4.788],[-8.368,-26.683],[1.748,-1.464],[-4.237,-5.06],[0,0],[-5.06,4.237],[-0.51,2.603],[0,0],[-9.49,9.835]],"o":[[9.667,-10.333],[-1.333,-14.667],[-24.637,4.935],[-2.112,0.313],[-5.06,4.237],[0,0],[4.237,5.06],[2.18,-1.825],[18.318,4.86],[0,0],[10.369,-10.746]],"v":[[41.819,-10.251],[30.819,-32.584],[-17.848,-50.584],[-46.171,9.291],[-52.085,11.932],[-53.582,28.836],[-36.165,49.638],[-19.261,51.135],[-15.21,44.254],[19.486,34.749],[47.45,29.495]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.078000005086,0.078000005086,0.078000005086,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.866,383.533],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":3,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"middle spline","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.49,"y":1},"o":{"x":0.51,"y":0},"n":"0p49_1_0p51_0","t":0,"s":[8,-73,0],"e":[8,-69,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.49,"y":1},"o":{"x":0.51,"y":0},"n":"0p49_1_0p51_0","t":3,"s":[8,-69,0],"e":[8,-73,0],"to":[0,0,0],"ti":[0,0,0]},{"t":6}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[71,71,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[37.665,5.519],[-46.498,-4.641]],"o":[[0,0],[38.998,-4.641],[-42.248,5.186]],"v":[[-0.5,23.319],[-42.248,-17.622],[42.248,-17.622]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"eye left","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.37,"y":0},"n":"0p833_1_0p37_0","t":0,"s":[-32,-34,0],"e":[-32,-25,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.37,"y":0},"n":"0p833_1_0p37_0","t":3,"s":[-32,-25,0],"e":[-32,-34,0],"to":[0,0,0],"ti":[0,0,0]},{"t":6}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[73,73,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[15.855,0],[0,-24.024],[-17,0],[-0.081,21.632]],"o":[[0,0],[-0.072,-21.772],[-17,0],[0,24.024],[15.785,0],[0,0]],"v":[[1.003,0.25],[16.997,-6.754],[0.003,-43.5],[-16.997,0],[0.003,43.5],[16.996,6.958]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"eye right","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.37,"y":0},"n":"0p833_1_0p37_0","t":0,"s":[52,-34,0],"e":[52,-25,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.37,"y":0},"n":"0p833_1_0p37_0","t":3,"s":[52,-25,0],"e":[52,-34,0],"to":[0,0,0],"ti":[0,0,0]},{"t":6}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[73,73,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[15.855,0],[0,-24.024],[-17,0],[-0.081,21.632]],"o":[[0,0],[-0.072,-21.772],[-17,0],[0,24.024],[15.785,0],[0,0]],"v":[[1.003,0.25],[16.997,-6.754],[0.003,-43.5],[-16.997,0],[0.003,43.5],[16.996,6.958]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"nose","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":40,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.6,"y":1},"o":{"x":0.4,"y":0},"n":"0p6_1_0p4_0","t":0,"s":[11.131,-2.66,0],"e":[11.131,7.34,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.6,"y":1},"o":{"x":0.4,"y":0},"n":"0p6_1_0p4_0","t":3,"s":[11.131,7.34,0],"e":[11.131,-2.66,0],"to":[0,0,0],"ti":[0,0,0]},{"t":6}],"ix":2},"a":{"a":0,"k":[-10.369,-211.66,0],"ix":1},"s":{"a":0,"k":[67,67,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.619,8.587],[-10.879,-15.092]],"o":[[-5.619,-8.587],[10.879,15.092]],"v":[[-29,-198],[6,-223]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"mouth 2","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-11,"ix":10},"p":{"a":0,"k":[19,40,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[11.322,0],[19.224,0],[19.051,2.982],[0.002,-11.326],[-19.761,-0.077],[0,27.486]],"o":[[-19.05,2.982],[-19.225,0],[-11.321,0],[0.002,30.415],[31.995,0.124],[0,-11.322]],"v":[[57.5,-28.162],[0.001,-15.69],[-57.5,-27.162],[-78,-6.66],[1.005,28.038],[78,-7.663]],"c":true}],"e":[{"i":[[11.322,0],[19.224,0],[19.051,2.982],[0.002,-11.326],[-19.761,-0.077],[0,27.486]],"o":[[-19.05,2.982],[-19.225,0],[-11.321,0],[0.002,30.415],[31.994,0.124],[0,-11.322]],"v":[[56.611,-23.591],[-1.11,-9.975],[-57.944,-24.877],[-77.334,-10.089],[1.005,28.038],[78.222,-8.805]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":3,"s":[{"i":[[11.322,0],[19.224,0],[19.051,2.982],[0.002,-11.326],[-19.761,-0.077],[0,27.486]],"o":[[-19.05,2.982],[-19.225,0],[-11.321,0],[0.002,30.415],[31.994,0.124],[0,-11.322]],"v":[[56.611,-23.591],[-1.11,-9.975],[-57.944,-24.877],[-77.334,-10.089],[1.005,28.038],[78.222,-8.805]],"c":true}],"e":[{"i":[[11.322,0],[19.224,0],[19.051,2.982],[0.002,-11.326],[-19.761,-0.077],[0,27.486]],"o":[[-19.05,2.982],[-19.225,0],[-11.321,0],[0.002,30.415],[31.995,0.124],[0,-11.322]],"v":[[57.5,-28.162],[0.001,-15.69],[-57.5,-27.162],[-78,-6.66],[1.005,28.038],[78,-7.663]],"c":true}]},{"t":6}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[85.892,85.892],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"tounge","parent":12,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.6,"y":1},"o":{"x":0.4,"y":0},"n":"0p6_1_0p4_0","t":0,"s":[30,3,0],"e":[28.474,10.853,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.6,"y":1},"o":{"x":0.4,"y":0},"n":"0p6_1_0p4_0","t":3,"s":[28.474,10.853,0],"e":[30,3,0],"to":[0,0,0],"ti":[0,0,0]},{"t":6}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[123,123,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.116,2.862],[-0.681,6.787]],"o":[[-5.097,2.581],[1.108,-11.042]],"v":[[8.158,-13.809],[1.067,0.861]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-0.5,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[81.427,81.427],"ix":3},"r":{"a":0,"k":-3.831,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[14.501,1.719],[-17.333,-1.333],[-2.065,-9.013]],"o":[[-7,-0.333],[3.677,-4.62],[2.367,10.333]],"v":[[-9.833,12.833],[0.167,-4.167],[17.167,-4.167]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.874509803922,0.266666666667,0.094117647059,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[182.095,182.095],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"mouth","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-11,"ix":10},"p":{"a":0,"k":[19,40,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.6,"y":1},"o":{"x":0.4,"y":0},"n":"0p6_1_0p4_0","t":0,"s":[{"i":[[11.322,0],[19.224,0],[19.051,2.982],[0.002,-11.326],[-19.761,-0.077],[0,27.486]],"o":[[-19.05,2.982],[-19.225,0],[-11.321,0],[0.002,30.415],[31.995,0.124],[0,-11.322]],"v":[[57.5,-28.162],[0.001,-15.69],[-57.5,-27.162],[-78,-6.66],[1.005,28.038],[78,-7.663]],"c":true}],"e":[{"i":[[11.322,0],[19.224,0],[19.051,2.982],[0.002,-11.326],[-19.761,-0.077],[0,27.486]],"o":[[-19.05,2.982],[-19.225,0],[-11.321,0],[0.002,30.415],[31.994,0.124],[0,-11.322]],"v":[[56.611,-23.591],[-1.11,-9.975],[-57.944,-24.877],[-77.334,-10.089],[1.005,28.038],[78.222,-8.805]],"c":true}]},{"i":{"x":0.6,"y":1},"o":{"x":0.4,"y":0},"n":"0p6_1_0p4_0","t":3,"s":[{"i":[[11.322,0],[19.224,0],[19.051,2.982],[0.002,-11.326],[-19.761,-0.077],[0,27.486]],"o":[[-19.05,2.982],[-19.225,0],[-11.321,0],[0.002,30.415],[31.994,0.124],[0,-11.322]],"v":[[56.611,-23.591],[-1.11,-9.975],[-57.944,-24.877],[-77.334,-10.089],[1.005,28.038],[78.222,-8.805]],"c":true}],"e":[{"i":[[11.322,0],[19.224,0],[19.051,2.982],[0.002,-11.326],[-19.761,-0.077],[0,27.486]],"o":[[-19.05,2.982],[-19.225,0],[-11.321,0],[0.002,30.415],[31.995,0.124],[0,-11.322]],"v":[[57.5,-28.162],[0.001,-15.69],[-57.5,-27.162],[-78,-6.66],[1.005,28.038],[78,-7.663]],"c":true}]},{"t":6}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[85.892,85.892],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"--BODY--","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.34,"y":1},"o":{"x":0.4,"y":0},"n":"0p34_1_0p4_0","t":0,"s":[400,300,0],"e":[400,317,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.34,"y":1},"o":{"x":0.4,"y":0},"n":"0p34_1_0p4_0","t":3,"s":[400,317,0],"e":[400,300,0],"to":[0,0,0],"ti":[0,0,0]},{"t":6}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.344,15.543],[-2.276,0.299],[-30.441,0],[-6.695,-0.878],[0.198,-2.287],[47.291,0]],"o":[[-0.198,-2.287],[6.695,-0.878],[30.441,0],[2.276,0.299],[-1.344,15.543],[-47.291,0]],"v":[[-56.742,-31.993],[-53.043,-36.618],[0,-39],[53.043,-36.618],[56.742,-31.993],[0,39]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[223.275,223.275],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Hose 2::Shoulder","parent":13,"hd":true,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\ntry {\n var parentRot = hasParent ? parentTotal() : 0;\n var rotCalc = sub(thisLayer('ADBE Root Vectors Group')('Admin')('Transform')('Rotation'), parentRot);\n $bm_rt = sum(rotCalc, value);\n} catch (err) {\n $bm_rt = value;\n}\n;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain += '.parent';\n parentVal += eval([layerChain][0]).rotation;\n }\n return parentVal;\n}"},"p":{"a":0,"k":[-86,24,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6,"x":"var $bm_rt;\n$bm_rt = [\n 100,\n 100\n];"}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Hose 2::Wrist","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[20,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Hose 2::Shoulder","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\ntry {\n var eff = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var autoRotate = eff('Auto Rotate Start');\n if (autoRotate == 1) {\n var a = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name).toComp([\n 0,\n 0,\n 0\n ]);\n var b = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var s = length(a, b);\n var sFac = eff('Parent Scale');\n var autoFlop = 1;\n var realism = eff('Realism');\n var bendDir = div(eff('Bend Direction'), 100);\n var hoseLength = div(eff('Hose Length'), 2);\n var bendRad = eff('Bend Radius');\n var autoFlop = eff('AutoFlop');\n var baseRot = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var outerRad = mul(Math.sin(0.78539816339), s);\n var straight = div(mul(1.4142135623731, outerRad), 2);\n straight /= Math.max(Math.abs(sFac), 0.001);\n var roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\n var innerRad;\n if (straight <= hoseLength) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n } else {\n innerRad = straight;\n }\n innerRad = linear(Math.abs(autoFlop), straight, innerRad);\n var flopDir = 1;\n if (bendDir < 0) {\n flopDir = -1;\n }\n flopDir *= autoFlop;\n var opp = mul(sub(innerRad, straight), flopDir);\n var theta = Math.atan(div(opp, Math.max(straight, 0.001)));\n var bendAngle = radiansToDegrees(theta);\n if (sFac < 0) {\n baseRot *= -1;\n }\n bendRad *= div(div(theta, $bm_neg(Math.PI)), linear(s, hoseLength, 0, 2, 0.9));\n var rotCalc = sum(sub(baseRot, bendAngle), bendRad);\n $bm_rt = rotCalc;\n } else {\n $bm_rt = 0;\n }\n ;\n} catch (err) {\n $bm_rt = value;\n}\n;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Circle","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-75,0],[75,0]],"c":false},"ix":2},"nm":"01","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-30],[0,30]],"c":false},"ix":2},"nm":"02","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[20,20],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ControlShape","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.560000002384,0,1],"ix":3,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name);\n $bm_rt = ctrl(2)('Control Point')(2)('Stroke 1')('Color');\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = [\n 0,\n 0\n];"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\n$bm_rt = [\n 100,\n 100\n];"},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Control Point","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Hose 1::Shoulder","parent":13,"hd":true,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\ntry {\n var parentRot = hasParent ? parentTotal() : 0;\n var rotCalc = sub(thisLayer('ADBE Root Vectors Group')('Admin')('Transform')('Rotation'), parentRot);\n $bm_rt = sum(rotCalc, value);\n} catch (err) {\n $bm_rt = value;\n}\n;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain += '.parent';\n parentVal += eval([layerChain][0]).rotation;\n }\n return parentVal;\n}"},"p":{"a":0,"k":[78,24,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6,"x":"var $bm_rt;\n$bm_rt = [\n 100,\n 100\n];"}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Hose 1::Wrist","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[20,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Hose 1::Shoulder","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\ntry {\n var eff = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var autoRotate = eff('Auto Rotate Start');\n if (autoRotate == 1) {\n var a = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name).toComp([\n 0,\n 0,\n 0\n ]);\n var b = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var s = length(a, b);\n var sFac = eff('Parent Scale');\n var autoFlop = 1;\n var realism = eff('Realism');\n var bendDir = div(eff('Bend Direction'), 100);\n var hoseLength = div(eff('Hose Length'), 2);\n var bendRad = eff('Bend Radius');\n var autoFlop = eff('AutoFlop');\n var baseRot = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var outerRad = mul(Math.sin(0.78539816339), s);\n var straight = div(mul(1.4142135623731, outerRad), 2);\n straight /= Math.max(Math.abs(sFac), 0.001);\n var roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\n var innerRad;\n if (straight <= hoseLength) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n } else {\n innerRad = straight;\n }\n innerRad = linear(Math.abs(autoFlop), straight, innerRad);\n var flopDir = 1;\n if (bendDir < 0) {\n flopDir = -1;\n }\n flopDir *= autoFlop;\n var opp = mul(sub(innerRad, straight), flopDir);\n var theta = Math.atan(div(opp, Math.max(straight, 0.001)));\n var bendAngle = radiansToDegrees(theta);\n if (sFac < 0) {\n baseRot *= -1;\n }\n bendRad *= div(div(theta, $bm_neg(Math.PI)), linear(s, hoseLength, 0, 2, 0.9));\n var rotCalc = sum(sub(baseRot, bendAngle), bendRad);\n $bm_rt = rotCalc;\n } else {\n $bm_rt = 0;\n }\n ;\n} catch (err) {\n $bm_rt = value;\n}\n;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Circle","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-75,0],[75,0]],"c":false},"ix":2},"nm":"01","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-30],[0,30]],"c":false},"ix":2},"nm":"02","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[20,20],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ControlShape","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.560000002384,0,1],"ix":3,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name);\n $bm_rt = ctrl(2)('Control Point')(2)('Stroke 1')('Color');\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = [\n 0,\n 0\n];"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\n$bm_rt = [\n 100,\n 100\n];"},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Control Point","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Hose 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11,"x":"var $bm_rt;\n$bm_rt = 100;"},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\nvar r = 0;\nif (thisLayer.hasParent) {\n r = $bm_neg(parentTotal());\n}\n$bm_rt = r;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain += '.parent';\n parentVal += eval([layerChain][0]).rotation;\n }\n return parentVal;\n}"},"p":{"a":0,"k":[236,286,0],"ix":2,"x":"var $bm_rt;\nvar p = [\n 0,\n 0\n ];\ntry {\n if (thisLayer.hasParent) {\n p = parent.fromComp([\n 0,\n 0,\n 0\n ]);\n }\n $bm_rt = p;\n} catch (err) {\n $bm_rt = p;\n}"},"a":{"a":0,"k":[0,0,0],"ix":1,"x":"var $bm_rt;\n$bm_rt = [\n 0,\n 0\n];"},"s":{"a":0,"k":[100,100,100],"ix":6,"x":"var $bm_rt;\nvar s = [\n 100,\n 100\n ];\nif (hasParent) {\n var sFactor = parentTotal();\n s = [\n s[0] * sFactor[0],\n s[1] * sFactor[1]\n ];\n}\n$bm_rt = s;\nfunction parentTotal() {\n var sFactor = [\n 1,\n 1\n ];\n var scaleNorm = [\n 0,\n 0\n ];\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain += '.parent';\n scaleNorm = eval([layerChain][0]).scale;\n if (scaleNorm[0] != 0 && scaleNorm[1] != 0) {\n scaleNorm = [\n 100 / scaleNorm[0],\n 100 / scaleNorm[1]\n ];\n }\n sFactor = [\n sFactor[0] * scaleNorm[0],\n sFactor[1] * scaleNorm[1]\n ];\n }\n return sFactor;\n}"}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":4,"ix":3,"x":"var $bm_rt;\n$bm_rt = 4;"},"p":{"a":0,"k":[0,0],"ix":4,"x":"var $bm_rt;\n$bm_rt = [\n 0,\n 0\n];"},"r":{"a":0,"k":0,"ix":5,"x":"var $bm_rt;\n$bm_rt = 0;"},"ir":{"a":0,"k":500,"ix":6,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"is":{"a":0,"k":0,"ix":8,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"or":{"a":0,"k":113,"ix":7,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"os":{"a":0,"k":0,"ix":9,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"ix":1,"nm":"LineForCurve","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"e":{"a":0,"k":0,"ix":2,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"o":{"a":0,"k":-90,"ix":3,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"m":1,"ix":2,"nm":"Line Halfer","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"a":{"a":0,"k":[0,0],"ix":1,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"r":{"a":0,"k":45,"ix":6,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"o":{"a":0,"k":100,"ix":7,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"sk":{"a":0,"k":0,"ix":4,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"sa":{"a":0,"k":0,"ix":5,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"nm":"Transform"}],"nm":"Arc","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":25,"ix":5,"x":"var $bm_rt;\nvar sFac = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2')('Parent Scale');\n$bm_rt = mul(value, sFac);"},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('A');\n} catch (err) {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"BaseHose","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Style","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Hose 2::Wrist","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[200,200],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Hose 2::Shoulder","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":4,"ix":3,"x":"var $bm_rt;\n$bm_rt = 4;"},"p":{"a":0,"k":[0,0],"ix":4,"x":"var $bm_rt;\n$bm_rt = [\n 0,\n 0\n];"},"r":{"a":0,"k":90,"ix":5,"x":"var $bm_rt;\n$bm_rt = 0;"},"ir":{"a":0,"k":200,"ix":6,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Inner Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"is":{"a":0,"k":100,"ix":8,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Bend Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"or":{"a":0,"k":200,"ix":7,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Outer Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"os":{"a":0,"k":0,"ix":9,"x":"var $bm_rt;\n$bm_rt = 0;"},"ix":1,"nm":"LineForCurve","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"tm","s":{"a":0,"k":0.01,"ix":1,"x":"var $bm_rt;\n$bm_rt = 0.01;"},"e":{"a":0,"k":24.99,"ix":2,"x":"var $bm_rt;\n$bm_rt = 24.99;"},"o":{"a":0,"k":-90,"ix":3,"x":"var $bm_rt;\n$bm_rt = -90;"},"m":1,"ix":2,"nm":"Line Halfer","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = [\n 0,\n 0\n];"},"a":{"a":0,"k":[0,0],"ix":1,"x":"var $bm_rt;\nvar s = thisProperty.propertyGroup(2)(2)(1)(7);\n$bm_rt = [\n -s,\n 0\n];"},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\nvar flop;\ntry {\n var eff = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var bendDir = eff('Bend Direction');\n var autoFlop = eff('AutoFlop');\n flop = bendDir > 0 ? 1 : -1;\n autoFlop > 0 ? 0 : flop *= -1;\n var s = flop == 1 ? [\n -100,\n 100\n ] : [\n 100,\n 100\n ];\n if (eff('Parent Scale') < 0) {\n s = [\n -s[0],\n s[1]\n ];\n }\n $bm_rt = s;\n} catch (err) {\n $bm_rt = value;\n}\n;"},"r":{"a":0,"k":45,"ix":6,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var baseRot = ctrl('Base Rotation');\n var flop = content('Admin').content('ArcMath').transform.scale[0];\n var rotOffset = flop < 0 ? -45 : 225;\n $bm_rt = sum(baseRot, rotOffset);\n} catch (err) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ArcMath","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('A');\n} catch (err) {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Hose 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11,"x":"var $bm_rt;\n$bm_rt = 100;"},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\nvar r = 0;\nif (thisLayer.hasParent) {\n r = $bm_neg(parentTotal());\n}\n$bm_rt = r;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain += '.parent';\n parentVal += eval([layerChain][0]).rotation;\n }\n return parentVal;\n}"},"p":{"a":0,"k":[400,286,0],"ix":2,"x":"var $bm_rt;\nvar p = [\n 0,\n 0\n ];\ntry {\n if (thisLayer.hasParent) {\n p = parent.fromComp([\n 0,\n 0,\n 0\n ]);\n }\n $bm_rt = p;\n} catch (err) {\n $bm_rt = p;\n}"},"a":{"a":0,"k":[0,0,0],"ix":1,"x":"var $bm_rt;\n$bm_rt = [\n 0,\n 0\n];"},"s":{"a":0,"k":[100,100,100],"ix":6,"x":"var $bm_rt;\nvar s = [\n 100,\n 100\n ];\nif (hasParent) {\n var sFactor = parentTotal();\n s = [\n s[0] * sFactor[0],\n s[1] * sFactor[1]\n ];\n}\n$bm_rt = s;\nfunction parentTotal() {\n var sFactor = [\n 1,\n 1\n ];\n var scaleNorm = [\n 0,\n 0\n ];\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain += '.parent';\n scaleNorm = eval([layerChain][0]).scale;\n if (scaleNorm[0] != 0 && scaleNorm[1] != 0) {\n scaleNorm = [\n 100 / scaleNorm[0],\n 100 / scaleNorm[1]\n ];\n }\n sFactor = [\n sFactor[0] * scaleNorm[0],\n sFactor[1] * scaleNorm[1]\n ];\n }\n return sFactor;\n}"}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":4,"ix":3,"x":"var $bm_rt;\n$bm_rt = 4;"},"p":{"a":0,"k":[0,0],"ix":4,"x":"var $bm_rt;\n$bm_rt = [\n 0,\n 0\n];"},"r":{"a":0,"k":0,"ix":5,"x":"var $bm_rt;\n$bm_rt = 0;"},"ir":{"a":0,"k":500,"ix":6,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"is":{"a":0,"k":0,"ix":8,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"or":{"a":0,"k":113,"ix":7,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"os":{"a":0,"k":0,"ix":9,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"ix":1,"nm":"LineForCurve","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"e":{"a":0,"k":0,"ix":2,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"o":{"a":0,"k":-90,"ix":3,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"m":1,"ix":2,"nm":"Line Halfer","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"a":{"a":0,"k":[0,0],"ix":1,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"r":{"a":0,"k":45,"ix":6,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"o":{"a":0,"k":100,"ix":7,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"sk":{"a":0,"k":0,"ix":4,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"sa":{"a":0,"k":0,"ix":5,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"nm":"Transform"}],"nm":"Arc","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":25,"ix":5,"x":"var $bm_rt;\nvar sFac = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2')('Parent Scale');\n$bm_rt = mul(value, sFac);"},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('A');\n} catch (err) {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"BaseHose","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Style","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Hose 1::Wrist","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[200,200],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Hose 1::Shoulder","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":4,"ix":3,"x":"var $bm_rt;\n$bm_rt = 4;"},"p":{"a":0,"k":[0,0],"ix":4,"x":"var $bm_rt;\n$bm_rt = [\n 0,\n 0\n];"},"r":{"a":0,"k":90,"ix":5,"x":"var $bm_rt;\n$bm_rt = 0;"},"ir":{"a":0,"k":200,"ix":6,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Inner Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"is":{"a":0,"k":100,"ix":8,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Bend Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"or":{"a":0,"k":200,"ix":7,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Outer Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"os":{"a":0,"k":0,"ix":9,"x":"var $bm_rt;\n$bm_rt = 0;"},"ix":1,"nm":"LineForCurve","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"tm","s":{"a":0,"k":0.01,"ix":1,"x":"var $bm_rt;\n$bm_rt = 0.01;"},"e":{"a":0,"k":24.99,"ix":2,"x":"var $bm_rt;\n$bm_rt = 24.99;"},"o":{"a":0,"k":-90,"ix":3,"x":"var $bm_rt;\n$bm_rt = -90;"},"m":1,"ix":2,"nm":"Line Halfer","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = [\n 0,\n 0\n];"},"a":{"a":0,"k":[0,0],"ix":1,"x":"var $bm_rt;\nvar s = thisProperty.propertyGroup(2)(2)(1)(7);\n$bm_rt = [\n -s,\n 0\n];"},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\nvar flop;\ntry {\n var eff = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var bendDir = eff('Bend Direction');\n var autoFlop = eff('AutoFlop');\n flop = bendDir > 0 ? 1 : -1;\n autoFlop > 0 ? 0 : flop *= -1;\n var s = flop == 1 ? [\n -100,\n 100\n ] : [\n 100,\n 100\n ];\n if (eff('Parent Scale') < 0) {\n s = [\n -s[0],\n s[1]\n ];\n }\n $bm_rt = s;\n} catch (err) {\n $bm_rt = value;\n}\n;"},"r":{"a":0,"k":45,"ix":6,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var baseRot = ctrl('Base Rotation');\n var flop = content('Admin').content('ArcMath').transform.scale[0];\n var rotOffset = flop < 0 ? -45 : 225;\n $bm_rt = sum(baseRot, rotOffset);\n} catch (err) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ArcMath","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('A');\n} catch (err) {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"handle","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":9,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.6,"y":1},"o":{"x":0.4,"y":0},"n":"0p6_1_0p4_0","t":0,"s":[132,-18,0],"e":[127,-13,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.6,"y":1},"o":{"x":0.4,"y":0},"n":"0p6_1_0p4_0","t":3,"s":[127,-13,0],"e":[132,-18,0],"to":[0,0,0],"ti":[0,0,0]},{"t":6}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[-111,111,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,21.188],[-4.812,-0.367],[0,0],[0,-40],[0,0],[0,0]],"o":[[0,-21.188],[0,0],[0,0],[0,40],[0,0],[-4.812,-0.067]],"v":[[-4.23,0.741],[21.333,-18.726],[21.333,-34],[-21.333,0],[32.877,39.417],[29.029,23.459]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.967,128.967],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"shadow","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,420.824,0],"ix":2},"a":{"a":0,"k":[18,90.824,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,-0.667]},"o":{"x":[0.37,0.37,0.37],"y":[0,0,0]},"n":["0p833_0p833_0p37_0","0p833_0p833_0p37_0","0p833_-0p667_0p37_0"],"t":0,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,2.667]},"o":{"x":[0.37,0.37,0.37],"y":[0,0,0]},"n":["0p833_0p833_0p37_0","0p833_0p833_0p37_0","0p833_2p667_0p37_0"],"t":3,"s":[100,100,100],"e":[90,90,100]},{"t":6}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[112,14.352],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[18,90.824],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"yellow","hd":true,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[800,600],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.121568627451,0.121568627451,0.121568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.811764705882,0.062745098039,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2520,"st":0,"bm":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/night_own.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/night_own.json deleted file mode 100644 index 8295bf07..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/night_own.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.2.1","fr":60,"ip":0,"op":42,"w":800,"h":600,"nm":"both wing","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"left eye Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[388.739,339.119,0],"ix":2},"a":{"a":0,"k":[61.417,54.715,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.463,-1.546],[1.546,0.463],[-0.463,1.546],[-1.546,-0.464]],"o":[[-0.463,1.546],[-1.546,-0.463],[0.463,-1.546],[1.545,0.463]],"v":[[2.799,0.839],[-0.838,2.8],[-2.799,-0.838],[0.839,-2.798]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40800000359,0.40800000359,0.40800000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[63.609,58.09],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-22.228,-35.258]],"o":[[0,0],[0,0]],"v":[[-26.416,-19.715],[26.416,19.715]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[61.416,54.715],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.344,2.108],[0.647,-0.815],[-5.527,-4.393],[-3.38,4.252],[-0.282,0.979],[3.273,2.601]],"o":[[-0.89,0.494],[-3.38,4.252],[5.528,4.394],[0.646,-0.813],[-2.809,-2.782],[-3.272,-2.601]],"v":[[-6.686,-11.062],[-9.011,-9.1],[-5.123,6.554],[11.006,6.809],[12.391,4.102],[3.262,-3.995]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[63.852,55.915],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":4,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.245,3.279],[1.78,-2.239],[-12.224,-9.717],[-6.421,8.079],[-0.147,2.978],[7.182,5.708]],"o":[[-2.869,0.815],[-6.422,8.079],[12.224,9.717],[1.781,-2.238],[-4.829,-6.319],[-7.182,-5.709]],"v":[[-13.249,-23.918],[-20.348,-19.349],[-9.84,12.873],[23.921,15.839],[26.77,7.894],[8.647,-10.387]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.976000019148,0.745000023935,0.023999999551,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[58.543,60.603],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":4,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":123,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"nose Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[428.559,400.809,0],"ix":2},"a":{"a":0,"k":[16.853,34.516,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.412,9.474],[-1.702,7.37],[-2.586,-14.341],[-5.909,-9.193]],"o":[[-1.537,-10.304],[-5.545,2.582],[2.539,14.085],[-3.364,-6.396]],"v":[[0.637,1.503],[1.085,-25.788],[-4.037,-2.421],[6.623,25.788]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.246999987434,0.246999987434,0.246999987434,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[10.345,35.584],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.544,-23.068],[13.188,-16.711],[0.673,20.085],[-11.076,-0.179]],"o":[[-0.426,18.067],[-12.416,-17.378],[-0.683,-20.378],[8.553,0.138]],"v":[[16.059,-8.318],[0.183,34.266],[-15.92,-8.318],[0.569,-34.087]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.853,34.516],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":123,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"right eye Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[467.347,339.161,0],"ix":2},"a":{"a":0,"k":[60.439,55.96,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.537,-1.521],[1.522,-0.538],[0.537,1.522],[-1.522,0.537]],"o":[[0.537,1.521],[-1.522,0.537],[-0.536,-1.522],[1.522,-0.536]],"v":[[2.756,-0.973],[0.971,2.756],[-2.757,0.971],[-0.973,-2.757]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40800000359,0.40800000359,0.40800000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[59.246,58.697],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[],"o":[],"v":[],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.477999997606,0.477999997606,0.477999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.5,0.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[20.509,-36.283]],"o":[[0,0],[0,0]],"v":[[25.44,-20.96],[-25.44,20.96]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[60.439,55.96],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.238,2.267],[-0.686,-0.782],[5.311,-4.654],[3.58,4.085],[0.328,0.964],[-3.143,2.756]],"o":[[0.912,0.451],[3.58,4.085],[-5.309,4.654],[-0.686,-0.782],[2.672,-2.913],[3.144,-2.755]],"v":[[6.165,-11.393],[8.582,-9.546],[5.449,6.277],[-10.647,7.308],[-12.162,4.669],[-3.433,-3.857]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[58.047,57.299],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":4,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-7.079,3.624],[-1.885,-2.152],[11.744,-10.292],[6.803,7.761],[0.291,2.968],[-6.898,6.047]],"o":[[2.905,0.677],[6.802,7.76],[-11.743,10.293],[-1.885,-2.151],[4.52,-6.544],[6.9,-6.046]],"v":[[12.167,-24.629],[19.477,-20.405],[10.529,12.283],[-23.052,16.868],[-26.279,9.068],[-9.056,-10.061]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.976000019148,0.745000023935,0.023999999551,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[63.511,61.806],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":4,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":123,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"details Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[428.769,320.093,0],"ix":2},"a":{"a":0,"k":[114.641,80.52,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.14,4.372],[13.871,-15.765],[29.213,-18.407],[11.999,2.015],[5.112,6.926],[-7.275,16.968],[-17.085,2.144],[-8.485,-3.638],[-0.979,22.103],[-5.514,27.54]],"o":[[-2.202,4.518],[13.475,-15.473],[24.24,-17.783],[-8.484,-3.638],[-10.226,-13.855],[7.276,-16.969],[8.543,-1.073],[8.484,3.638],[4.38,29.362],[-5.355,28.812]],"v":[[47.884,20.297],[31.618,40.86],[7.995,50.305],[-17.964,46.624],[-38.527,30.359],[-44.291,-19.224],[-4.402,-49.232],[21.558,-45.551],[42.121,-29.285],[51.566,-5.662]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[158.736,110.484],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-9.936,-15.563],[7.839,-15.331],[7.78,-4.968],[-27.584,-15.946],[-18.864,-17.228],[0.009,0.015],[7.705,24.703],[0.461,37.074],[-7.943,6.36],[-8.604,0.33]],"o":[[9.936,15.562],[-3.92,7.666],[-8.571,4.707],[-33.006,-15.738],[-19.162,-17.381],[-0.01,-0.015],[7.692,24.374],[2.837,32.427],[7.781,-4.968],[17.206,-0.659]],"v":[[41.087,-26.655],[43.454,23.204],[25.806,42.595],[0.789,50.444],[-24.055,44.961],[-43.444,27.313],[-51.293,2.298],[-45.811,-22.547],[-28.163,-41.936],[-3.146,-49.785]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[67.119,110.342],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.757,1.756],[-30.411,-30.701],[4.379,-8.171],[10.237,3.834],[24.87,23.094]],"o":[[1.503,-3.489],[4.896,4.943],[-3.096,5.775],[-19.305,-7.232],[-13.969,-12.972]],"v":[[-47.559,-34.433],[27.438,1.567],[43.937,30.814],[17.584,34.088],[-23.56,-17.183]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.925,0.709999952129,0.416000007181,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":1,"lj":1,"ml":10,"ml2":{"a":0,"k":10,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[60.816,50.422],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.757,1.756],[-30.411,-30.701],[4.379,-8.171],[10.237,3.834],[24.87,23.094]],"o":[[1.503,-3.489],[4.896,4.943],[-3.096,5.775],[-19.305,-7.232],[-13.969,-12.972]],"v":[[-47.559,-34.433],[27.438,1.567],[43.937,30.814],[17.584,34.088],[-23.56,-17.183]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[60.816,50.422],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":4,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.757,1.756],[30.41,-30.7],[-4.379,-8.171],[-10.237,3.835],[-24.871,23.095]],"o":[[-1.503,-3.49],[-4.897,4.943],[3.096,5.775],[19.306,-7.231],[13.969,-12.971]],"v":[[47.559,-34.432],[-27.437,1.566],[-43.936,30.815],[-17.584,34.087],[23.561,-17.183]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.925,0.709999952129,0.416000007181,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":1,"lj":1,"ml":10,"ml2":{"a":0,"k":10,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[168.467,52.463],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.757,1.756],[30.41,-30.7],[-4.379,-8.171],[-10.237,3.835],[-24.871,23.095]],"o":[[-1.503,-3.49],[-4.897,4.943],[3.096,5.775],[19.306,-7.231],[13.969,-12.971]],"v":[[47.559,-34.432],[-27.437,1.566],[-43.936,30.815],[-17.584,34.087],[23.561,-17.183]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[168.467,52.463],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":4,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":123,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"legs Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[424.502,501.059,0],"ix":2},"a":{"a":0,"k":[107.717,38.642,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.823,0],[0,0],[0.132,-5.156],[-10.987,-1.283],[-1.236,-0.087],[-3.426,-1.329],[-0.28,-0.739],[0.764,-1.376],[0.704,-1.45],[0.695,-1.346],[-1.986,-5.54],[-3.604,-1.548],[-1.933,0],[-1.597,0.845],[-1.021,-1.242],[-4.078,0],[-1.3,0.431],[-1.512,1.707],[-0.609,-1.087],[-1.403,-0.382],[0,0],[-1.468,0],[-2.628,3.253],[1.236,2.264],[11.376,8.595],[14.032,2.425]],"o":[[0,0],[-12.095,0.001],[-0.116,4.464],[1.424,0.166],[3.119,0.219],[1.276,0.495],[0.002,0.56],[-0.621,1.119],[-0.66,1.356],[-3.458,6.696],[0.656,1.829],[2.061,0.884],[2.181,0],[0.404,1.39],[2.337,2.843],[1.445,0],[2.34,-0.776],[0.243,1.352],[2.018,3.599],[0,0],[1.607,0.449],[4.063,0],[7.164,-8.872],[-3.505,-6.415],[-5.749,-4.344],[-3.282,-0.566]],"v":[[-27.017,-37.788],[-27.018,-37.788],[-44.793,-27.428],[-31.753,-16.092],[-27.812,-15.749],[-18.803,-14.027],[-14.259,-11.635],[-16.068,-7.816],[-18.098,-3.979],[-20.173,0.118],[-24.911,18.678],[-19.113,24.56],[-13.095,25.893],[-7.456,24.532],[-5.365,28.508],[4.88,33.048],[9.016,32.398],[14.734,28.543],[16.013,32.191],[22.719,37.066],[22.887,37.112],[27.518,37.788],[37.746,32.814],[33.034,1.569],[11.587,-22.893],[-17.816,-36.934]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-8.908,0.001],[-3.174,-0.549],[-5.729,-4.328],[-2.111,-3.865],[4.266,-5.282],[2.577,0],[1.176,0.327],[-3.781,12.999],[1.242,0.141],[0.017,0],[8.163,-2.707],[0.885,0],[1.436,1.747],[2.122,1.312],[0.097,0],[8.278,0],[1.503,0.645],[-4.552,9.362],[1.264,3.353],[3.239,1.256],[4.954,0.58],[-0.061,2.367]],"o":[[2.404,0],[12.836,2.218],[12.063,9.116],[2.799,5.123],[-1.672,2.069],[-1.018,0],[-2.088,-0.583],[1.221,-4.199],[-0.017,-0.002],[-2.244,0],[-0.804,0.266],[-2.427,0],[-4.418,-5.373],[-0.1,-0.061],[-2.069,-0.001],[-1.201,0],[-7.38,-3.169],[2.54,-5.224],[-1.045,-2.774],[-5.614,-2.177],[-7.737,-0.903],[0.058,-2.28]],"v":[[-27.018,-32.788],[-18.667,-32.005],[8.574,-18.904],[28.645,3.967],[33.855,29.672],[27.518,32.786],[24.23,32.297],[20.862,17.776],[18.431,8.201],[18.379,8.198],[7.443,27.653],[4.88,28.048],[-1.501,25.332],[-0.85,7.577],[-1.145,7.486],[-13.095,20.893],[-17.139,19.965],[-13.6,-1.794],[-9.581,-13.398],[-16.996,-18.689],[-31.173,-21.059],[-39.796,-27.299]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.925,0.709999952129,0.416000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[170.275,39.246],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":6,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.328,0],[1.388,0.387],[0,0],[1.506,2.684],[-1.851,6.366],[0.155,1.02],[6.482,-2.148],[1.177,0],[1.84,2.237],[-0.148,2.566],[3.343,0],[1.747,0.75],[0.71,1.98],[-3.34,6.466],[-0.678,1.394],[-0.607,1.092],[0.51,1.356],[3.107,1.206],[3.199,0.224],[1.367,0.159],[-0.128,4.976],[-10.357,0],[-3.141,-0.543],[-5.928,-4.479],[-3.387,-6.201],[6.248,-7.736]],"o":[[-1.24,0],[0,0],[-1.193,-0.325],[-1.672,-2.982],[0.292,-1.004],[-1.54,5.594],[-1.044,0.347],[-3.288,0],[-1.718,-2.09],[-1.85,2.099],[-1.592,0],[-2.23,-0.958],[-1.618,-4.517],[0.706,-1.368],[0.674,-1.388],[1.64,-2.953],[-0.625,-1.656],[-3.778,-1.465],[-1.207,-0.085],[-7.316,-0.855],[0.097,-3.818],[2.682,0],[13.433,2.322],[11.022,8.328],[0.113,0.207],[-2.168,2.684]],"v":[[27.706,35.287],[23.745,34.704],[23.563,34.654],[18.382,30.969],[18.648,17.077],[18.779,13.953],[8.415,30.025],[5.067,30.548],[-3.247,26.92],[-5.262,19.734],[-12.908,23.392],[-17.941,22.262],[-22.372,17.834],[-17.765,1.266],[-15.662,-2.886],[-13.695,-6.603],[-11.732,-12.516],[-17.713,-16.359],[-27.452,-18.242],[-31.275,-18.574],[-42.107,-27.362],[-26.831,-35.287],[-18.055,-34.47],[10.266,-20.9],[31.027,2.767],[35.988,31.242]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[170.088,39.246],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[12.095,0],[3.283,-0.567],[5.749,-4.345],[3.504,-6.416],[-7.164,-8.871],[-4.062,0],[-1.605,0.448],[0,0],[-2.018,3.598],[-0.244,1.351],[-2.341,-0.777],[-1.445,0],[-2.337,2.844],[-0.403,1.391],[-2.181,0],[-2.059,0.884],[-0.656,1.829],[3.458,6.696],[0.66,1.357],[0.622,1.119],[-0.005,0.595],[-1.277,0.495],[-3.119,0.22],[-1.425,0.166],[0.115,4.463]],"o":[[-2.824,0],[-14.032,2.425],[-11.376,8.594],[-1.237,2.264],[2.628,3.254],[1.467,0],[0,0],[1.403,-0.382],[0.609,-1.087],[1.512,1.707],[1.299,0.43],[4.078,0],[1.022,-1.242],[1.597,0.845],[1.933,0],[3.605,-1.548],[1.986,-5.541],[-0.696,-1.347],[-0.704,-1.45],[-0.763,-1.375],[0.275,-0.705],[3.426,-1.328],[1.237,-0.087],[10.987,-1.283],[-0.132,-5.156]],"v":[[27.019,-37.787],[17.816,-36.933],[-11.587,-22.892],[-33.033,1.569],[-37.745,32.813],[-27.518,37.787],[-22.887,37.112],[-22.718,37.066],[-16.013,32.191],[-14.734,28.543],[-9.015,32.399],[-4.88,33.048],[5.365,28.507],[7.456,24.531],[13.096,25.893],[19.113,24.56],[24.912,18.678],[20.173,0.118],[18.098,-3.979],[16.067,-7.816],[14.263,-11.669],[18.804,-14.028],[27.813,-15.749],[31.753,-16.092],[44.794,-27.428]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-2.404,0],[-0.059,-2.281],[7.736,-0.904],[5.615,-2.178],[1.045,-2.773],[-2.541,-5.225],[7.38,-3.169],[1.201,0],[2.069,0],[0.099,-0.061],[4.417,-5.373],[2.428,0],[0.803,0.267],[2.244,0],[0.017,-0.002],[-1.221,-4.2],[2.088,-0.582],[1.018,0],[1.671,2.069],[-2.798,5.123],[-12.065,9.115],[-12.837,2.219]],"o":[[8.908,0],[0.061,2.367],[-4.954,0.579],[-3.238,1.256],[-1.264,3.354],[4.551,9.361],[-1.503,0.646],[-8.278,0],[-0.097,0],[-2.123,1.312],[-1.437,1.747],[-0.885,0],[-8.164,-2.706],[-0.018,0],[-1.242,0.14],[3.781,12.999],[-1.176,0.328],[-2.577,0],[-4.266,-5.282],[2.112,-3.865],[5.728,-4.329],[3.173,-0.548]],"v":[[27.019,-32.787],[39.796,-27.299],[31.173,-21.058],[16.996,-18.689],[9.581,-13.398],[13.602,-1.793],[17.14,19.965],[13.096,20.893],[1.145,7.485],[0.851,7.577],[1.503,25.332],[-4.88,28.048],[-7.441,27.652],[-18.378,8.198],[-18.43,8.201],[-20.862,17.776],[-24.23,32.296],[-27.518,32.787],[-33.855,29.671],[-28.646,3.966],[-8.573,-18.903],[18.668,-32.006]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.925,0.709999952129,0.416000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[45.159,38.037],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":6,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.241,0],[2.168,2.685],[-0.113,0.207],[-11.021,8.329],[-13.439,2.323],[-2.682,0],[-0.098,-3.817],[7.315,-0.856],[1.208,-0.085],[3.779,-1.465],[0.624,-1.656],[-1.64,-2.953],[-0.675,-1.389],[-0.707,-1.368],[1.619,-4.517],[2.23,-0.958],[1.591,0],[0,0],[1.851,2.099],[1.718,-2.09],[3.288,0],[1.045,0.347],[1.54,5.593],[-0.292,-1.004],[1.672,-2.983],[1.193,-0.325],[0,0]],"o":[[-3.327,0],[-6.248,-7.736],[3.386,-6.2],[5.927,-4.478],[3.142,-0.543],[10.354,0],[0.127,4.976],[-1.367,0.159],[-3.199,0.224],[-3.107,1.206],[-0.511,1.357],[0.606,1.092],[0.677,1.393],[3.34,6.466],[-0.71,1.98],[-1.747,0.75],[0,0],[-3.344,-0.001],[0.149,2.566],[-1.84,2.237],[-1.177,0],[-6.481,-2.148],[-0.155,1.02],[1.852,6.365],[-1.505,2.684],[0,0],[-1.387,0.387]],"v":[[-27.705,35.287],[-35.986,31.241],[-31.025,2.767],[-10.268,-20.899],[18.055,-34.47],[26.833,-35.287],[42.107,-27.363],[31.277,-18.574],[27.452,-18.242],[17.713,-16.359],[11.734,-12.517],[13.695,-6.604],[15.663,-2.886],[17.765,1.265],[22.372,17.834],[17.941,22.262],[12.911,23.392],[12.908,23.392],[5.262,19.733],[3.247,26.92],[-5.067,30.548],[-8.416,30.025],[-18.779,13.952],[-18.649,17.077],[-18.382,30.969],[-23.563,34.654],[-23.745,34.704]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[45.346,38.037],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":4,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":123,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"bg Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[428.705,418.648,0],"ix":2},"a":{"a":0,"k":[119.86,141.181,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-13.594,-28.634],[36.568,-22.904],[22.556,1.736],[6.701,6.605],[2.471,7.033],[6.359,-4.66],[27.431,-11.288],[32.634,16.235],[18.177,23.216],[0.133,23.646],[-8.826,14.793],[-9.401,4.669],[-6.785,1.084],[-8.177,0],[0,0],[1.1,2.061],[-5.126,6.82],[-10.278,10.969],[-20.154,9.286],[-27.504,-2.564],[-21.046,-21.835],[0.526,-13.595],[0,0],[8.952,-7.169],[2.141,-2.85]],"o":[[-28.346,-18.252],[14.862,-23.125],[11.392,-6.975],[-0.876,-5.469],[-2.47,-7.034],[3.102,-19.355],[24.907,-25.239],[32.414,6.973],[23.192,16.38],[8.736,17.83],[1.892,11.581],[-3.365,4.669],[4.662,1.084],[0,0],[11.038,0],[7.891,2.061],[6.68,10.837],[-1.326,18.137],[-15.139,18.741],[-27.504,2.875],[-25.618,-4.153],[-4.046,4.086],[0,10.876],[-4.475,3.584],[-9.666,1.168]],"v":[[30.502,82.407],[-29.512,82.407],[-63.566,42.684],[-63.442,40.188],[-69.8,20.978],[-80.56,11.243],[-106.215,-4.156],[-115.139,-52.248],[-99.21,-71.659],[-72.472,-82.407],[-49.985,-81.703],[-32.9,-75.67],[-25.8,-72.085],[-5.192,-71.001],[18.931,-71.001],[37.148,-73.062],[56.648,-76.709],[78.93,-73.936],[101.385,-60.82],[115.139,-34.324],[106.966,-2.985],[77.963,17.508],[72.202,28.224],[57.694,39.706],[45.754,49.044]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.925000011921,0.709999978542,0.416000008583,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[115.656,199.704],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-9.397],[-31.333,-7.409],[-72.132,21.274],[-39.988,-6.643],[0.016,-23.711],[28.355,-11.054],[55.729,14.667],[42.977,8.342],[0,11.204],[-8.071,12.991],[-14.963,-4.621],[-81.894,14.471],[-9.973,-25.147]],"o":[[0,12.474],[-35.081,10.819],[-72.132,21.274],[-39.988,-6.643],[0.016,-23.711],[28.355,-11.054],[55.729,14.667],[28,-33.334],[0,-7.967],[16.143,-25.984],[57.498,17.762],[20.315,-3.589],[4.986,12.574]],"v":[[119.61,-7.859],[96.099,62.382],[72.295,33.698],[45.955,78.687],[-0.031,94.975],[-41.066,78.687],[-55.705,40.308],[-96.705,62.382],[-119.61,-7.859],[-106.109,-41.409],[-48.296,-90.354],[63.098,-88.692],[111.73,-42.542]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.925,0.709999952129,0.416000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[119.86,95.225],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":123,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Comp 1","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,248,0],"ix":2},"a":{"a":0,"k":[400,248,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"w":800,"h":496,"ip":0,"op":123,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"Comp 1","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":176,"ix":10},"p":{"a":0,"k":[384,250,0],"ix":2},"a":{"a":0,"k":[400,248,0],"ix":1},"s":{"a":0,"k":[130,-130,100],"ix":6}},"ao":0,"w":800,"h":496,"ip":0,"op":123,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"Comp 1","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":176,"ix":10},"p":{"a":0,"k":[384,250,0],"ix":2},"a":{"a":0,"k":[400,248,0],"ix":1},"s":{"a":0,"k":[155,-155,100],"ix":6}},"ao":0,"w":800,"h":496,"ip":0,"op":123,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"Comp 1","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,248,0],"ix":2},"a":{"a":0,"k":[400,248,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":800,"h":496,"ip":0,"op":123,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"Comp 1","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":3,"ix":10},"p":{"a":0,"k":[416,248,0],"ix":2},"a":{"a":0,"k":[400,248,0],"ix":1},"s":{"a":0,"k":[130,130,100],"ix":6}},"ao":0,"w":800,"h":496,"ip":0,"op":123,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"Comp 1","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":3,"ix":10},"p":{"a":0,"k":[416,248,0],"ix":2},"a":{"a":0,"k":[400,248,0],"ix":1},"s":{"a":0,"k":[155,155,100],"ix":6}},"ao":0,"w":800,"h":496,"ip":0,"op":123,"st":0,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[-20],"e":[-20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":24,"s":[-20],"e":[-20]},{"t":41}],"ix":10},"p":{"a":0,"k":[344.75,261.25,0],"ix":2},"a":{"a":0,"k":[165.747,-4.779,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.4,"y":1},"o":{"x":0.333,"y":0},"n":"0p4_1_0p333_0","t":0,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-170,-8],[172,-8]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-170,-8],[172,-8]],"c":false}]},{"t":23}],"ix":2,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').content('Path 1').path;"},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":6,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":35,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.104,-4.784],"ix":2},"a":{"a":0,"k":[164.104,-4.784],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').transform.rotation;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.485,"y":1},"o":{"x":0.333,"y":0},"n":"0p485_1_0p333_0","t":0,"s":[{"i":[[-150,250],[0,0]],"o":[[150,-250],[0,0]],"v":[[-180,10],[172,-8]],"c":false}],"e":[{"i":[[-73.658,-118.409],[-147.395,-96.641]],"o":[[143.69,161.306],[147.395,96.641]],"v":[[-180,10],[164.321,-4.825]],"c":false}]},{"i":{"x":0.576,"y":1},"o":{"x":0.333,"y":0},"n":"0p576_1_0p333_0","t":23,"s":[{"i":[[-73.658,-118.409],[-147.395,-96.641]],"o":[[143.69,161.306],[147.395,96.641]],"v":[[-180,10],[164.321,-4.825]],"c":false}],"e":[{"i":[[-150,250],[0,0]],"o":[[150,-250],[0,0]],"v":[[-180,10],[172,-8]],"c":false}]},{"t":33}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.925490260124,0.709803938866,0.415686309338,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.186,-4.838],"ix":2},"a":{"a":0,"k":[164.186,-4.838],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.563],"y":[0.97]},"o":{"x":[0.349],"y":[0.017]},"n":["0p563_0p97_0p349_0p017"],"t":0,"s":[0],"e":[81.911]},{"i":{"x":[0.687],"y":[1.011]},"o":{"x":[0.389],"y":[-0.009]},"n":["0p687_1p011_0p389_-0p009"],"t":23,"s":[81.911],"e":[0]},{"t":33}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":123,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":1,"s":[-25],"e":[-18]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":25,"s":[-18],"e":[-25]},{"t":41}],"ix":10},"p":{"a":0,"k":[344.75,261.25,0],"ix":2},"a":{"a":0,"k":[165.747,-4.779,0],"ix":1},"s":{"a":0,"k":[48,48,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.4,"y":1},"o":{"x":0.333,"y":0},"n":"0p4_1_0p333_0","t":1,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-170,-8],[172,-8]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-170,-8],[172,-8]],"c":false}]},{"t":24}],"ix":2,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').content('Path 1').path;"},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":6,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":35,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.104,-4.784],"ix":2},"a":{"a":0,"k":[164.104,-4.784],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').transform.rotation;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.485,"y":1},"o":{"x":0.333,"y":0},"n":"0p485_1_0p333_0","t":1,"s":[{"i":[[-150,250],[0,0]],"o":[[150,-250],[0,0]],"v":[[-180,10],[172,-8]],"c":false}],"e":[{"i":[[-73.658,-118.409],[-147.395,-96.641]],"o":[[143.69,161.306],[147.395,96.641]],"v":[[-180,10],[164.321,-4.825]],"c":false}]},{"i":{"x":0.576,"y":1},"o":{"x":0.333,"y":0},"n":"0p576_1_0p333_0","t":24,"s":[{"i":[[-73.658,-118.409],[-147.395,-96.641]],"o":[[143.69,161.306],[147.395,96.641]],"v":[[-180,10],[164.321,-4.825]],"c":false}],"e":[{"i":[[-150,250],[0,0]],"o":[[150,-250],[0,0]],"v":[[-180,10],[172,-8]],"c":false}]},{"t":34}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.925490260124,0.709803938866,0.415686309338,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.186,-4.838],"ix":2},"a":{"a":0,"k":[164.186,-4.838],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.563],"y":[0.97]},"o":{"x":[0.349],"y":[0.017]},"n":["0p563_0p97_0p349_0p017"],"t":1,"s":[0],"e":[81.911]},{"i":{"x":[0.687],"y":[1.011]},"o":{"x":[0.389],"y":[-0.009]},"n":["0p687_1p011_0p389_-0p009"],"t":24,"s":[81.911],"e":[0]},{"t":34}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124,"st":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":2,"s":[-30],"e":[-16]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":26,"s":[-16],"e":[-30]},{"t":41}],"ix":10},"p":{"a":0,"k":[344.75,261.25,0],"ix":2},"a":{"a":0,"k":[165.747,-4.779,0],"ix":1},"s":{"a":0,"k":[46,46,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.4,"y":1},"o":{"x":0.333,"y":0},"n":"0p4_1_0p333_0","t":2,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-170,-8],[172,-8]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-170,-8],[172,-8]],"c":false}]},{"t":25}],"ix":2,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').content('Path 1').path;"},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":6,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":35,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.104,-4.784],"ix":2},"a":{"a":0,"k":[164.104,-4.784],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').transform.rotation;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.485,"y":1},"o":{"x":0.333,"y":0},"n":"0p485_1_0p333_0","t":2,"s":[{"i":[[-150,250],[0,0]],"o":[[150,-250],[0,0]],"v":[[-180,10],[172,-8]],"c":false}],"e":[{"i":[[-73.658,-118.409],[-147.395,-96.641]],"o":[[143.69,161.306],[147.395,96.641]],"v":[[-180,10],[164.321,-4.825]],"c":false}]},{"i":{"x":0.576,"y":1},"o":{"x":0.333,"y":0},"n":"0p576_1_0p333_0","t":25,"s":[{"i":[[-73.658,-118.409],[-147.395,-96.641]],"o":[[143.69,161.306],[147.395,96.641]],"v":[[-180,10],[164.321,-4.825]],"c":false}],"e":[{"i":[[-150,250],[0,0]],"o":[[150,-250],[0,0]],"v":[[-180,10],[172,-8]],"c":false}]},{"t":35}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.925490260124,0.709803938866,0.415686309338,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.186,-4.838],"ix":2},"a":{"a":0,"k":[164.186,-4.838],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.563],"y":[0.97]},"o":{"x":[0.349],"y":[0.017]},"n":["0p563_0p97_0p349_0p017"],"t":2,"s":[0],"e":[81.911]},{"i":{"x":[0.687],"y":[1.011]},"o":{"x":[0.389],"y":[-0.009]},"n":["0p687_1p011_0p389_-0p009"],"t":25,"s":[81.911],"e":[0]},{"t":35}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":125,"st":2,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":3,"s":[-35],"e":[-14]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[-14],"e":[-35]},{"t":41}],"ix":10},"p":{"a":0,"k":[344.75,261.25,0],"ix":2},"a":{"a":0,"k":[165.747,-4.779,0],"ix":1},"s":{"a":0,"k":[44,44,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.4,"y":1},"o":{"x":0.333,"y":0},"n":"0p4_1_0p333_0","t":3,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-170,-8],[172,-8]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-170,-8],[172,-8]],"c":false}]},{"t":26}],"ix":2,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').content('Path 1').path;"},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":6,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":35,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.104,-4.784],"ix":2},"a":{"a":0,"k":[164.104,-4.784],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').transform.rotation;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.485,"y":1},"o":{"x":0.333,"y":0},"n":"0p485_1_0p333_0","t":3,"s":[{"i":[[-150,250],[0,0]],"o":[[150,-250],[0,0]],"v":[[-180,10],[172,-8]],"c":false}],"e":[{"i":[[-73.658,-118.409],[-147.395,-96.641]],"o":[[143.69,161.306],[147.395,96.641]],"v":[[-180,10],[164.321,-4.825]],"c":false}]},{"i":{"x":0.576,"y":1},"o":{"x":0.333,"y":0},"n":"0p576_1_0p333_0","t":26,"s":[{"i":[[-73.658,-118.409],[-147.395,-96.641]],"o":[[143.69,161.306],[147.395,96.641]],"v":[[-180,10],[164.321,-4.825]],"c":false}],"e":[{"i":[[-150,250],[0,0]],"o":[[150,-250],[0,0]],"v":[[-180,10],[172,-8]],"c":false}]},{"t":36}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.925490260124,0.709803938866,0.415686309338,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.186,-4.838],"ix":2},"a":{"a":0,"k":[164.186,-4.838],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.563],"y":[0.97]},"o":{"x":[0.349],"y":[0.017]},"n":["0p563_0p97_0p349_0p017"],"t":3,"s":[0],"e":[81.911]},{"i":{"x":[0.687],"y":[1.011]},"o":{"x":[0.389],"y":[-0.009]},"n":["0p687_1p011_0p389_-0p009"],"t":26,"s":[81.911],"e":[0]},{"t":36}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":126,"st":3,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":4,"s":[-40],"e":[-12]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":28,"s":[-12],"e":[-40]},{"t":41}],"ix":10},"p":{"a":0,"k":[344.75,261.25,0],"ix":2},"a":{"a":0,"k":[165.747,-4.779,0],"ix":1},"s":{"a":0,"k":[42,42,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.4,"y":1},"o":{"x":0.333,"y":0},"n":"0p4_1_0p333_0","t":4,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-170,-8],[172,-8]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-170,-8],[172,-8]],"c":false}]},{"t":27}],"ix":2,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').content('Path 1').path;"},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":6,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":35,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.104,-4.784],"ix":2},"a":{"a":0,"k":[164.104,-4.784],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').transform.rotation;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.485,"y":1},"o":{"x":0.333,"y":0},"n":"0p485_1_0p333_0","t":4,"s":[{"i":[[-150,250],[0,0]],"o":[[150,-250],[0,0]],"v":[[-180,10],[172,-8]],"c":false}],"e":[{"i":[[-73.658,-118.409],[-147.395,-96.641]],"o":[[143.69,161.306],[147.395,96.641]],"v":[[-180,10],[164.321,-4.825]],"c":false}]},{"i":{"x":0.576,"y":1},"o":{"x":0.333,"y":0},"n":"0p576_1_0p333_0","t":27,"s":[{"i":[[-73.658,-118.409],[-147.395,-96.641]],"o":[[143.69,161.306],[147.395,96.641]],"v":[[-180,10],[164.321,-4.825]],"c":false}],"e":[{"i":[[-150,250],[0,0]],"o":[[150,-250],[0,0]],"v":[[-180,10],[172,-8]],"c":false}]},{"t":37}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.925490260124,0.709803938866,0.415686309338,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.186,-4.838],"ix":2},"a":{"a":0,"k":[164.186,-4.838],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.563],"y":[0.97]},"o":{"x":[0.349],"y":[0.017]},"n":["0p563_0p97_0p349_0p017"],"t":4,"s":[0],"e":[81.911]},{"i":{"x":[0.687],"y":[1.011]},"o":{"x":[0.389],"y":[-0.009]},"n":["0p687_1p011_0p389_-0p009"],"t":27,"s":[81.911],"e":[0]},{"t":37}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":127,"st":4,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":5,"s":[-45],"e":[-8]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":29,"s":[-8],"e":[-45]},{"t":41}],"ix":10},"p":{"a":0,"k":[344.75,261.25,0],"ix":2},"a":{"a":0,"k":[165.747,-4.779,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.4,"y":1},"o":{"x":0.333,"y":0},"n":"0p4_1_0p333_0","t":5,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-170,-8],[172,-8]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-170,-8],[172,-8]],"c":false}]},{"t":28}],"ix":2,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').content('Path 1').path;"},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":6,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":35,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.104,-4.784],"ix":2},"a":{"a":0,"k":[164.104,-4.784],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').transform.rotation;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.485,"y":1},"o":{"x":0.333,"y":0},"n":"0p485_1_0p333_0","t":5,"s":[{"i":[[-150,250],[0,0]],"o":[[150,-250],[0,0]],"v":[[-180,10],[172,-8]],"c":false}],"e":[{"i":[[-73.658,-118.409],[-147.395,-96.641]],"o":[[143.69,161.306],[147.395,96.641]],"v":[[-180,10],[164.321,-4.825]],"c":false}]},{"i":{"x":0.576,"y":1},"o":{"x":0.333,"y":0},"n":"0p576_1_0p333_0","t":28,"s":[{"i":[[-73.658,-118.409],[-147.395,-96.641]],"o":[[143.69,161.306],[147.395,96.641]],"v":[[-180,10],[164.321,-4.825]],"c":false}],"e":[{"i":[[-150,250],[0,0]],"o":[[150,-250],[0,0]],"v":[[-180,10],[172,-8]],"c":false}]},{"t":38}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.925490260124,0.709803938866,0.415686309338,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.186,-4.838],"ix":2},"a":{"a":0,"k":[164.186,-4.838],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.563],"y":[0.97]},"o":{"x":[0.349],"y":[0.017]},"n":["0p563_0p97_0p349_0p017"],"t":5,"s":[0],"e":[81.911]},{"i":{"x":[0.687],"y":[1.011]},"o":{"x":[0.389],"y":[-0.009]},"n":["0p687_1p011_0p389_-0p009"],"t":28,"s":[81.911],"e":[0]},{"t":38}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":128,"st":5,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":6,"s":[-50],"e":[-8]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":30,"s":[-8],"e":[-50]},{"t":41}],"ix":10},"p":{"a":0,"k":[344.75,261.25,0],"ix":2},"a":{"a":0,"k":[165.747,-4.779,0],"ix":1},"s":{"a":0,"k":[38,38,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.4,"y":1},"o":{"x":0.333,"y":0},"n":"0p4_1_0p333_0","t":6,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-170,-8],[172,-8]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-170,-8],[172,-8]],"c":false}]},{"t":29}],"ix":2,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').content('Path 1').path;"},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":6,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":35,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.104,-4.784],"ix":2},"a":{"a":0,"k":[164.104,-4.784],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\n$bm_rt = content('Shape 1').transform.rotation;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.485,"y":1},"o":{"x":0.333,"y":0},"n":"0p485_1_0p333_0","t":6,"s":[{"i":[[-150,250],[0,0]],"o":[[150,-250],[0,0]],"v":[[-180,10],[172,-8]],"c":false}],"e":[{"i":[[-73.658,-118.409],[-147.395,-96.641]],"o":[[143.69,161.306],[147.395,96.641]],"v":[[-180,10],[164.321,-4.825]],"c":false}]},{"i":{"x":0.576,"y":1},"o":{"x":0.333,"y":0},"n":"0p576_1_0p333_0","t":29,"s":[{"i":[[-73.658,-118.409],[-147.395,-96.641]],"o":[[143.69,161.306],[147.395,96.641]],"v":[[-180,10],[164.321,-4.825]],"c":false}],"e":[{"i":[[-150,250],[0,0]],"o":[[150,-250],[0,0]],"v":[[-180,10],[172,-8]],"c":false}]},{"t":39}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.925490260124,0.709803938866,0.415686309338,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.186,-4.838],"ix":2},"a":{"a":0,"k":[164.186,-4.838],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.563],"y":[0.97]},"o":{"x":[0.349],"y":[0.017]},"n":["0p563_0p97_0p349_0p017"],"t":6,"s":[0],"e":[81.911]},{"i":{"x":[0.687],"y":[1.011]},"o":{"x":[0.389],"y":[-0.009]},"n":["0p687_1p011_0p389_-0p009"],"t":29,"s":[81.911],"e":[0]},{"t":39}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":129,"st":6,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"newOwl","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[396,290,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('Null 1').transform.position;"},"a":{"a":0,"k":[426,412,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":792,"h":612,"ip":0,"op":123,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"Comp 2","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[634,420,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('Null 1').transform.position;"},"a":{"a":0,"k":[400,248,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":800,"h":496,"ip":0,"op":123,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"Null 1","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.745,"y":1},"o":{"x":0.248,"y":0},"n":"0p745_1_0p248_0","t":0,"s":[397,293,0],"e":[398,308,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.328,"y":1},"o":{"x":0.333,"y":0},"n":"0p328_1_0p333_0","t":24,"s":[398,308,0],"e":[398,293,0],"to":[0,0,0],"ti":[0,2.5,0]},{"t":42}],"ix":2},"a":{"a":0,"k":[49,48,0],"ix":1},"s":{"a":0,"k":[52.471,78,100],"ix":6}},"ao":0,"ip":0,"op":123,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,121.324,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[870.727,558.906],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.929412004059,0.705881993911,0.450980003207,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.11796875,0.114369283938,0.07841090782,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.363,7.453],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":123,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/ondas.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/ondas.json deleted file mode 100644 index 4818f141..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/ondas.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.2.1","fr":25,"ip":0,"op":175,"w":600,"h":200,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Capa de formas 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,88,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0]],"o":[[0,0]],"v":[[-604,-284]],"c":false},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.105882352941,0.376470588235,0.576470588235,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Trazo 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.105882352941,0.376470588235,0.576470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Forma 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[39.5,2.75],[35.924,-1.559],[36.995,-1.156],[44.829,-1.288],[51.088,1.559]],"o":[[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-36.664,-2.553],[-32.262,1.4],[-32,1],[-38.162,1.096],[-56.889,-1.736]],"v":[[-330,7],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[313,-8.5],[283,19],[161,-42],[62.576,25.059],[-18,-10],[-113.838,26.904],[-213.111,-43.264]],"c":true}],"e":[{"i":[[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[28.993,-0.63],[28.406,-1.166],[20.727,-0.691],[43.266,1.9],[29.686,1.497]],"o":[[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-11.26,0.245],[-33.207,1.363],[-35.994,1.2],[-43.642,-1.917],[-25.352,-1.279]],"v":[[-315,-21],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[345,28.5],[309,0],[178,33],[71.844,-20.084],[-7,30],[-128.266,-46.9],[-227.648,31.279]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":25,"s":[{"i":[[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[28.993,-0.63],[28.406,-1.166],[20.727,-0.691],[43.266,1.9],[29.686,1.497]],"o":[[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-11.26,0.245],[-33.207,1.363],[-35.994,1.2],[-43.642,-1.917],[-25.352,-1.279]],"v":[[-315,-21],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[345,28.5],[309,0],[178,33],[71.844,-20.084],[-7,30],[-128.266,-46.9],[-227.648,31.279]],"c":true}],"e":[{"i":[[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[22.099,-6.451],[0.25,0.009],[25.563,-0.691],[41.486,0.99],[60.663,-1.035]],"o":[[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-80.5,23.5],[-28.945,-0.993],[-62.01,1.676],[-71.668,-1.711],[-42.39,0.724]],"v":[[-347,1],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[344,-5.5],[305,18],[187,-34],[44.945,-10.257],[-34,-42],[-137.486,10.01],[-263.61,-34.724]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":50,"s":[{"i":[[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[22.099,-6.451],[0.25,0.009],[25.563,-0.691],[41.486,0.99],[60.663,-1.035]],"o":[[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-80.5,23.5],[-28.945,-0.993],[-62.01,1.676],[-71.668,-1.711],[-42.39,0.724]],"v":[[-347,1],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[344,-5.5],[305,18],[187,-34],[44.945,-10.257],[-34,-42],[-137.486,10.01],[-263.61,-34.724]],"c":true}],"e":[{"i":[[23,-1],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[36.275,-2.267],[46.011,0],[0.306,-0.016],[21.403,-0.856],[43.848,-0.253],[34.576,1.765]],"o":[[-6.319,0.275],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-32,2],[-42,0],[-41.73,2.135],[-50,2],[-30.74,0.178],[-20.412,-1.042]],"v":[[-301,-20],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[309,15.5],[301,-24],[211,15],[53.73,-16.135],[-30,2],[-152.848,-68.747],[-258.576,5.235]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":75,"s":[{"i":[[23,-1],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[36.275,-2.267],[46.011,0],[0.306,-0.016],[21.403,-0.856],[43.848,-0.253],[34.576,1.765]],"o":[[-6.319,0.275],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-32,2],[-42,0],[-41.73,2.135],[-50,2],[-30.74,0.178],[-20.412,-1.042]],"v":[[-301,-20],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[309,15.5],[301,-24],[211,15],[53.73,-16.135],[-30,2],[-152.848,-68.747],[-258.576,5.235]],"c":true}],"e":[{"i":[[-9,-75],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.489,1.067],[28,0],[0.312,0.208],[34.572,0],[33.942,-0.219],[31.15,-0.014]],"o":[[0.754,6.279],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-37,-1],[-29.709,0],[-24.059,-16.072],[-44,0],[-64.06,0.413],[-2.443,0.001]],"v":[[-310,52],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[319,19.5],[221,-17],[88.5,12],[29.175,-2.414],[-53,-43],[-140.94,14.587],[-269.15,-23.986]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":100,"s":[{"i":[[-9,-75],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.489,1.067],[28,0],[0.312,0.208],[34.572,0],[33.942,-0.219],[31.15,-0.014]],"o":[[0.754,6.279],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-37,-1],[-29.709,0],[-24.059,-16.072],[-44,0],[-64.06,0.413],[-2.443,0.001]],"v":[[-310,52],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[319,19.5],[221,-17],[88.5,12],[29.175,-2.414],[-53,-43],[-140.94,14.587],[-269.15,-23.986]],"c":true}],"e":[{"i":[[9,8],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[28.994,0.624],[0.305,0.008],[34.798,0],[42.507,-1.345],[32.057,0.226]],"o":[[-4.727,-4.202],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-45.446,-0.977],[-53.635,-1.448],[-88.006,0],[-41.477,1.313],[-2.79,-0.02]],"v":[[-305,1],[-322,36],[-323,118.5],[314.5,112],[356.5,54],[342,13.5],[356,-16],[300,17],[106.635,-21.552],[-6,36],[-171.523,-5.313],[-276.057,15.774]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":125,"s":[{"i":[[9,8],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[28.994,0.624],[0.305,0.008],[34.798,0],[42.507,-1.345],[32.057,0.226]],"o":[[-4.727,-4.202],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-45.446,-0.977],[-53.635,-1.448],[-88.006,0],[-41.477,1.313],[-2.79,-0.02]],"v":[[-305,1],[-322,36],[-323,118.5],[314.5,112],[356.5,54],[342,13.5],[356,-16],[300,17],[106.635,-21.552],[-6,36],[-171.523,-5.313],[-276.057,15.774]],"c":true}],"e":[{"i":[[20,-8],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[47,-8],[0.236,0.002],[29.708,0],[48.429,1.52],[49.864,-0.786]],"o":[[-5.872,2.349],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-11.65,1.983],[-39.206,-0.383],[-67,0],[-45.549,-1.43],[-59.216,0.933]],"v":[[-305,1],[-322,36],[-323,118.5],[314.5,112],[356.5,54],[342,13.5],[325,-29],[228,3],[106.206,-10.617],[7,22],[-112.451,-29.57],[-222.784,28.067]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":150,"s":[{"i":[[20,-8],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[47,-8],[0.236,0.002],[29.708,0],[48.429,1.52],[49.864,-0.786]],"o":[[-5.872,2.349],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-11.65,1.983],[-39.206,-0.383],[-67,0],[-45.549,-1.43],[-59.216,0.933]],"v":[[-305,1],[-322,36],[-323,118.5],[314.5,112],[356.5,54],[342,13.5],[325,-29],[228,3],[106.206,-10.617],[7,22],[-112.451,-29.57],[-222.784,28.067]],"c":true}],"e":[{"i":[[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[39.5,2.75],[35.924,-1.559],[36.995,-1.156],[44.829,-1.288],[51.088,1.559]],"o":[[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-36.664,-2.553],[-32.262,1.4],[-32,1],[-38.162,1.096],[-56.889,-1.736]],"v":[[-330,7],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[313,-8.5],[283,19],[161,-42],[62.576,25.059],[-18,-10],[-113.838,26.904],[-213.111,-43.264]],"c":true}]},{"t":174}],"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.105882352941,0.376470588235,0.576470588235,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Trazo 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.105882352941,0.376470588235,0.576470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Forma 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[32.5,0],[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[29,0],[40.5,-0.5],[31,-0.484],[40,0]],"o":[[-34.5,0],[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-30.5,0],[-38.51,0.475],[-32,0.5],[-39.513,0]],"v":[[-213,-10],[-300,14],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[313,-8.5],[283,19],[181,-11],[91,21],[-30,-27],[-119.5,21]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":true}],"ip":0,"op":182,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Capa de formas 7","sr":1,"ks":{"o":{"a":0,"k":20,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[383,69,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[145.483,118.069,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[22,0],[21.482,1.006],[20.41,-1.327],[21.5,0.5],[17.059,0.867],[63.749,1.868],[23,0],[20,1],[22.004,0.917],[0,0],[0,0],[0,-6],[-3,0],[3,2],[3.073,2.561]],"o":[[-22.006,0],[-68.647,-3.214],[-19.465,1.266],[-19.521,-0.454],[-36.595,-1.859],[-18.992,-0.557],[-19.026,0],[-20.998,-1.05],[-24,-1],[0,0],[0,0],[0,6],[3,0],[-3,-2],[-6,-5]],"v":[[240,-20],[180,21],[110.189,-28.317],[71.685,22.194],[26.245,-17.806],[-61,21],[-139.559,-0.52],[-183.124,52.185],[-261.621,-20.847],[-300,20.25],[-320.25,38.25],[-321,137],[319,142],[317,37],[300,21]],"c":true}],"e":[{"i":[[22,0],[21.5,0.5],[20.5,0.5],[13.632,-0.169],[20.516,0.334],[24.57,-0.327],[23,0],[19.965,1.547],[22.004,0.917],[0,0],[0,0],[0,-6],[-3,0],[3,2],[3.073,2.561]],"o":[[-22.006,0],[-20.001,-0.465],[-19.501,-0.476],[-13.947,0.173],[-62.676,-1.02],[-18.998,0.253],[-19.026,0],[-15.15,-1.174],[-24,-1],[0,0],[0,0],[0,6],[3,0],[-3,-2],[-6,-5]],"v":[[240,20],[166.253,-43.715],[117.063,32.011],[81.996,-6.949],[48.928,28.97],[-61,-20],[-117.563,36.939],[-161.503,-28.47],[-207.694,36.092],[-299,-19.75],[-320.25,38.25],[-321,137],[319,142],[317,37],[300,-20]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":37,"s":[{"i":[[22,0],[21.5,0.5],[20.5,0.5],[13.632,-0.169],[20.516,0.334],[24.57,-0.327],[23,0],[19.965,1.547],[22.004,0.917],[0,0],[0,0],[0,-6],[-3,0],[3,2],[3.073,2.561]],"o":[[-22.006,0],[-20.001,-0.465],[-19.501,-0.476],[-13.947,0.173],[-62.676,-1.02],[-18.998,0.253],[-19.026,0],[-15.15,-1.174],[-24,-1],[0,0],[0,0],[0,6],[3,0],[-3,-2],[-6,-5]],"v":[[240,20],[166.253,-43.715],[117.063,32.011],[81.996,-6.949],[48.928,28.97],[-61,-20],[-117.563,36.939],[-161.503,-28.47],[-207.694,36.092],[-299,-19.75],[-320.25,38.25],[-321,137],[319,142],[317,37],[300,-20]],"c":true}],"e":[{"i":[[22,0],[21.5,0.5],[20.474,1.15],[21.5,0.5],[22.558,-0.334],[23,0],[33.017,0.52],[20,1],[22.004,0.917],[0,0],[0,0],[0,-6],[-3,0],[3,2],[3.073,2.561]],"o":[[-22.006,0],[-20.001,-0.465],[-38.703,-2.174],[-19.52,-0.454],[-18.7,0.277],[-19,0],[-19.024,-0.299],[-20.998,-1.05],[-24,-1],[0,0],[0,0],[0,6],[3,0],[-3,-2],[-6,-5]],"v":[[240,-20],[180,21],[120.5,-19],[55.188,38.279],[1.5,-42.368],[-61.687,36.245],[-119.625,-11.53],[-179,70.818],[-241,-20],[-269.069,87.16],[-320.25,38.25],[-321,137],[319,142],[317,37],[300,21]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":77,"s":[{"i":[[22,0],[21.5,0.5],[20.474,1.15],[21.5,0.5],[22.558,-0.334],[23,0],[33.017,0.52],[20,1],[22.004,0.917],[0,0],[0,0],[0,-6],[-3,0],[3,2],[3.073,2.561]],"o":[[-22.006,0],[-20.001,-0.465],[-38.703,-2.174],[-19.52,-0.454],[-18.7,0.277],[-19,0],[-19.024,-0.299],[-20.998,-1.05],[-24,-1],[0,0],[0,0],[0,6],[3,0],[-3,-2],[-6,-5]],"v":[[240,-20],[180,21],[120.5,-19],[55.188,38.279],[1.5,-42.368],[-61.687,36.245],[-119.625,-11.53],[-179,70.818],[-241,-20],[-269.069,87.16],[-320.25,38.25],[-321,137],[319,142],[317,37],[300,21]],"c":true}],"e":[{"i":[[22,0],[21.5,0.5],[20.5,0.5],[21.797,0.045],[20.512,0.493],[29.381,-2.453],[40.578,-1.211],[20,1],[22.004,0.917],[0,0],[0,0],[0,-6],[-3,0],[3,2],[3.073,2.561]],"o":[[-22.006,0],[-20.001,-0.465],[-19.501,-0.476],[-21.508,-0.045],[-30.369,-0.729],[-24.835,2.073],[-19.018,0.568],[-20.998,-1.05],[-24,-1],[0,0],[0,0],[0,6],[3,0],[-3,-2],[-6,-5]],"v":[[240,20],[179.313,-8.989],[119.813,37.092],[60.687,-15.418],[4.249,35.745],[-61,-6.941],[-121,20],[-177.313,10.491],[-247.561,33.551],[-299,-19.75],[-320.25,38.25],[-321,137],[319,142],[317,37],[300,-20]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":112,"s":[{"i":[[22,0],[21.5,0.5],[20.5,0.5],[21.797,0.045],[20.512,0.493],[29.381,-2.453],[40.578,-1.211],[20,1],[22.004,0.917],[0,0],[0,0],[0,-6],[-3,0],[3,2],[3.073,2.561]],"o":[[-22.006,0],[-20.001,-0.465],[-19.501,-0.476],[-21.508,-0.045],[-30.369,-0.729],[-24.835,2.073],[-19.018,0.568],[-20.998,-1.05],[-24,-1],[0,0],[0,0],[0,6],[3,0],[-3,-2],[-6,-5]],"v":[[240,20],[179.313,-8.989],[119.813,37.092],[60.687,-15.418],[4.249,35.745],[-61,-6.941],[-121,20],[-177.313,10.491],[-247.561,33.551],[-299,-19.75],[-320.25,38.25],[-321,137],[319,142],[317,37],[300,-20]],"c":true}],"e":[{"i":[[22,0],[21.5,0.5],[20.5,0.5],[21.5,0.5],[19.121,-5.062],[22.966,1.25],[26.143,-0.695],[26.405,-1.112],[29.291,-0.497],[0,0],[0,0],[0,-6],[-3,0],[3,2],[3.073,2.561]],"o":[[-22.006,0],[-20.001,-0.465],[-19.501,-0.476],[-19.52,-0.454],[-21.756,5.76],[-24.921,-1.357],[-24.714,0.657],[-18.952,0.798],[-64.182,1.089],[0,0],[0,0],[0,6],[3,0],[-3,-2],[-6,-5]],"v":[[240,-20],[180,21],[123.249,7.256],[69.623,-13.379],[13.873,1.674],[-61,21],[-124.437,-43.715],[-179.687,31.858],[-241,-20],[-300,20.25],[-320.25,38.25],[-321,137],[319,142],[317,37],[300,21]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":149,"s":[{"i":[[22,0],[21.5,0.5],[20.5,0.5],[21.5,0.5],[19.121,-5.062],[22.966,1.25],[26.143,-0.695],[26.405,-1.112],[29.291,-0.497],[0,0],[0,0],[0,-6],[-3,0],[3,2],[3.073,2.561]],"o":[[-22.006,0],[-20.001,-0.465],[-19.501,-0.476],[-19.52,-0.454],[-21.756,5.76],[-24.921,-1.357],[-24.714,0.657],[-18.952,0.798],[-64.182,1.089],[0,0],[0,0],[0,6],[3,0],[-3,-2],[-6,-5]],"v":[[240,-20],[180,21],[123.249,7.256],[69.623,-13.379],[13.873,1.674],[-61,21],[-124.437,-43.715],[-179.687,31.858],[-241,-20],[-300,20.25],[-320.25,38.25],[-321,137],[319,142],[317,37],[300,21]],"c":true}],"e":[{"i":[[22,0],[21.482,1.006],[20.41,-1.327],[21.5,0.5],[17.059,0.867],[63.749,1.868],[23,0],[20,1],[22.004,0.917],[0,0],[0,0],[0,-6],[-3,0],[3,2],[3.073,2.561]],"o":[[-22.006,0],[-68.647,-3.214],[-19.465,1.266],[-19.521,-0.454],[-36.595,-1.859],[-18.992,-0.557],[-19.026,0],[-20.998,-1.05],[-24,-1],[0,0],[0,0],[0,6],[3,0],[-3,-2],[-6,-5]],"v":[[240,-20],[180,21],[110.189,-28.317],[71.685,22.194],[26.245,-17.806],[-61,21],[-139.559,-0.52],[-183.124,52.185],[-261.621,-20.847],[-300,20.25],[-320.25,38.25],[-321,137],[319,142],[317,37],[300,21]],"c":true}]},{"t":174}],"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.105882352941,0.376470588235,0.576470588235,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Trazo 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.105882352941,0.376470588235,0.576470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,99.171],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Forma 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":178,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Capa de formas 9","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,88,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[165.038,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[27.202,0],[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[29,0],[40.5,-0.5],[31,-0.484],[40,0],[5.609,1.379]],"o":[[-34.5,0],[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-30.5,0],[-38.51,0.475],[-32,0.5],[-6.441,0],[-28.799,-7.08]],"v":[[-213,-10],[-300,14],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[313,-8.5],[283,19],[181,-11],[91,21],[-30,-27],[-119.5,21],[-137.512,18.797]],"c":true}],"e":[{"i":[[27.202,0],[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[29,0],[30,-2],[31,-0.484],[40,0],[5.431,-1.868]],"o":[[-34.5,0],[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-30.5,0],[-38.428,2.562],[-32,0.5],[-6.441,0],[-27.885,9.593]],"v":[[-210,11],[-315,-21],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[345,28.5],[309,0],[154,18],[84,-12],[-6,20],[-120.5,-31],[-138.228,-28.016]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":25,"s":[{"i":[[27.202,0],[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[29,0],[30,-2],[31,-0.484],[40,0],[5.431,-1.868]],"o":[[-34.5,0],[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-30.5,0],[-38.428,2.562],[-32,0.5],[-6.441,0],[-27.885,9.593]],"v":[[-210,11],[-315,-21],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[345,28.5],[309,0],[154,18],[84,-12],[-6,20],[-120.5,-31],[-138.228,-28.016]],"c":true}],"e":[{"i":[[27.202,0],[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[32.996,-0.509],[40.5,-0.5],[26.102,-1.054],[40,0],[8.011,1.557]],"o":[[-34.5,0],[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-129.59,2],[-38.51,0.475],[-24.774,1],[-6.441,0],[-41.132,-7.994]],"v":[[-272,-20],[-347,1],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[344,-5.5],[305,18],[192,-24],[38,18],[-57.631,-55],[-124.5,15],[-146.349,12.513]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":50,"s":[{"i":[[27.202,0],[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[32.996,-0.509],[40.5,-0.5],[26.102,-1.054],[40,0],[8.011,1.557]],"o":[[-34.5,0],[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-129.59,2],[-38.51,0.475],[-24.774,1],[-6.441,0],[-41.132,-7.994]],"v":[[-272,-20],[-347,1],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[344,-5.5],[305,18],[192,-24],[38,18],[-57.631,-55],[-124.5,15],[-146.349,12.513]],"c":true}],"e":[{"i":[[27.202,0],[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[34.781,-18.728],[28.998,-0.31],[37.553,-2],[31.004,0],[30.01,0],[6.81,-2.891]],"o":[[-34.5,0],[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-13,7],[-93.451,1],[-36.936,1.967],[-62.706,0],[-6.441,0],[-34.965,14.846]],"v":[[-262,9],[-301,-20],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[309,15.5],[276,-25],[211,15],[61.212,-50],[-30,2],[-141.5,-56],[-161.431,-51.381]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":75,"s":[{"i":[[27.202,0],[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[34.781,-18.728],[28.998,-0.31],[37.553,-2],[31.004,0],[30.01,0],[6.81,-2.891]],"o":[[-34.5,0],[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-13,7],[-93.451,1],[-36.936,1.967],[-62.706,0],[-6.441,0],[-34.965,14.846]],"v":[[-262,9],[-301,-20],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[309,15.5],[276,-25],[211,15],[61.212,-50],[-30,2],[-141.5,-56],[-161.431,-51.381]],"c":true}],"e":[{"i":[[17.342,0],[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[22.776,0],[69.184,3],[24.31,-1],[69.272,-2],[3.83,2.046]],"o":[[-34.5,0],[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-32.362,0],[-96.933,-4.203],[-18.117,0.745],[-6.439,0.186],[-19.663,-10.506]],"v":[[-187,-27],[-310,52],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[315,-54.5],[225,16],[156.576,-27],[52,14],[-52.788,-71],[-133.5,19],[-148.67,15.731]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":100,"s":[{"i":[[17.342,0],[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[22.776,0],[69.184,3],[24.31,-1],[69.272,-2],[3.83,2.046]],"o":[[-34.5,0],[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-32.362,0],[-96.933,-4.203],[-18.117,0.745],[-6.439,0.186],[-19.663,-10.506]],"v":[[-187,-27],[-310,52],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[315,-54.5],[225,16],[156.576,-27],[52,14],[-52.788,-71],[-133.5,19],[-148.67,15.731]],"c":true}],"e":[{"i":[[27.202,0],[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[29,0],[32.603,17],[51.656,3.506],[23.532,0],[24.687,-2.99]],"o":[[-34.5,0],[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-30.5,0],[-58.529,-30.518],[-117.884,-8],[-23.73,0],[-27.739,3.359]],"v":[[-250,20],[-305,1],[-322,36],[-323,118.5],[314.5,112],[356.5,54],[342,13.5],[356,-16],[290,9],[111,-45],[7,22],[-129.568,-63],[-181.015,-6.01]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":125,"s":[{"i":[[27.202,0],[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[29,0],[32.603,17],[51.656,3.506],[23.532,0],[24.687,-2.99]],"o":[[-34.5,0],[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-30.5,0],[-58.529,-30.518],[-117.884,-8],[-23.73,0],[-27.739,3.359]],"v":[[-250,20],[-305,1],[-322,36],[-323,118.5],[314.5,112],[356.5,54],[342,13.5],[356,-16],[290,9],[111,-45],[7,22],[-129.568,-63],[-181.015,-6.01]],"c":true}],"e":[{"i":[[59,0],[28,-9],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[98.917,4.172],[26.603,1],[79.612,-3.1],[20.518,-1],[7.066,-9.166]],"o":[[-34.5,0],[-6.021,1.935],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-71.121,-3],[-29.189,-1.097],[-102.736,4],[-9.766,0.476],[-19.913,25.833]],"v":[[-231,31],[-305,1],[-322,36],[-323,118.5],[314.5,112],[356.5,54],[342,13.5],[356,-16],[202,12],[117,-55],[7,22],[-116.254,-55],[-143.398,-9.834]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":150,"s":[{"i":[[59,0],[28,-9],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[98.917,4.172],[26.603,1],[79.612,-3.1],[20.518,-1],[7.066,-9.166]],"o":[[-34.5,0],[-6.021,1.935],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-71.121,-3],[-29.189,-1.097],[-102.736,4],[-9.766,0.476],[-19.913,25.833]],"v":[[-231,31],[-305,1],[-322,36],[-323,118.5],[314.5,112],[356.5,54],[342,13.5],[356,-16],[202,12],[117,-55],[7,22],[-116.254,-55],[-143.398,-9.834]],"c":true}],"e":[{"i":[[27.202,0],[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[29,0],[40.5,-0.5],[31,-0.484],[40,0],[5.609,1.379]],"o":[[-34.5,0],[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-30.5,0],[-38.51,0.475],[-32,0.5],[-6.441,0],[-28.799,-7.08]],"v":[[-213,-10],[-300,14],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[313,-8.5],[283,19],[181,-11],[91,21],[-30,-27],[-119.5,21],[-137.512,18.797]],"c":true}]},{"t":174}],"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.105882352941,0.376470588235,0.576470588235,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Trazo 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.105882352941,0.376470588235,0.576470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Forma 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[32.5,0],[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[29,0],[40.5,-0.5],[31,-0.484],[40,0]],"o":[[-34.5,0],[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-30.5,0],[-38.51,0.475],[-32,0.5],[-39.513,0]],"v":[[-213,-10],[-300,14],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[313,-8.5],[283,19],[181,-11],[91,21],[-30,-27],[-119.5,21]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[27.202,0],[15.5,-7],[8,-3],[-0.5,-1.5],[0,0],[1.5,4.5],[6,0],[39.5,-0.5],[29,0],[40.5,-0.5],[31,-0.484],[40,0],[5.609,1.379]],"o":[[-34.5,0],[-5.764,2.603],[-8,3],[0.5,1.5],[0,0],[-1.5,-4.5],[-6,0],[-39.997,0.506],[-30.5,0],[-38.51,0.475],[-32,0.5],[-6.441,0],[-28.799,-7.08]],"v":[[-213,-10],[-300,14],[-322,36],[-323,118.5],[314.5,112],[316.5,10],[313,-8.5],[283,19],[181,-11],[91,21],[-30,-27],[-119.5,21],[-137.512,18.797]],"c":true},"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 2","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":182,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Capa de formas 6","sr":1,"ks":{"o":{"a":0,"k":40,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,83,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[{"i":[[1,5],[-2,-6],[-7,0],[0,4],[14.036,0],[41.129,-12.788],[26.96,-0.808],[1.399,-0.957],[19.256,-0.204],[26.627,-0.522],[21,0],[38,-1],[47.027,-1.206],[2,3]],"o":[[-1,-5],[2,6],[7,0],[0,-4],[-7.061,0],[-30.705,9.547],[-31.026,0.93],[-19,13],[-37.752,0.4],[-18.418,0.361],[-25.08,0],[-52.991,1.395],[-39,1],[-2,-3]],"v":[[-328,-31],[-338,120],[336,139],[326,-6],[333,-52],[273.705,21.453],[196.04,-2.192],[148,15],[96.752,88.6],[17.418,-14.361],[-35,30],[-104,-42],[-222,47],[-309,-23]],"c":true}],"e":[{"i":[[1,5],[-2,-6],[-7,0],[0,4],[14.036,0],[6.641,18.354],[14.109,0.193],[27,1],[39.165,0.801],[19.535,-1.188],[31,0],[44,1],[39,-2],[2,3]],"o":[[-1,-5],[2,6],[7,0],[0,-4],[-7.603,0],[-5.132,-14.182],[-21.95,-0.3],[-36.975,-1.369],[-36.893,-0.755],[-28.506,1.734],[-26.476,0],[-78.986,-1.795],[-33.017,1.693],[-2,-3]],"v":[[-328,-31],[-338,120],[336,139],[326,-6],[326,60],[314.139,25.326],[293.95,-4.7],[230,33],[161.835,-31.801],[59.506,9.266],[-13,-19],[-100,62],[-220,-28],[-298,84]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":32,"s":[{"i":[[1,5],[-2,-6],[-7,0],[0,4],[14.036,0],[6.641,18.354],[14.109,0.193],[27,1],[39.165,0.801],[19.535,-1.188],[31,0],[44,1],[39,-2],[2,3]],"o":[[-1,-5],[2,6],[7,0],[0,-4],[-7.603,0],[-5.132,-14.182],[-21.95,-0.3],[-36.975,-1.369],[-36.893,-0.755],[-28.506,1.734],[-26.476,0],[-78.986,-1.795],[-33.017,1.693],[-2,-3]],"v":[[-328,-31],[-338,120],[336,139],[326,-6],[326,60],[314.139,25.326],[293.95,-4.7],[230,33],[161.835,-31.801],[59.506,9.266],[-13,-19],[-100,62],[-220,-28],[-298,84]],"c":true}],"e":[{"i":[[1,5],[-2,-6],[-7,0],[0,4],[14.036,0],[7.65,-6.414],[7.247,-5.107],[4.918,0.164],[12.569,8.758],[22.573,-8.821],[17.943,0.427],[41,0],[25.988,0.619],[2,3]],"o":[[-1,-5],[2,6],[7,0],[0,-4],[-7.603,0],[-5.911,4.956],[-7.332,5.167],[-14.474,-0.482],[-24.151,-16.829],[-5.86,2.29],[-39.04,-0.93],[-46,0],[-38.989,-0.928],[-2,-3]],"v":[[-328,-31],[-338,120],[336,139],[326,-6],[299,-19],[276.739,-7.642],[257.287,8.255],[218,21],[180.151,0.829],[78.519,-2.331],[0,19],[-89,-30],[-220,20],[-305,-18]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":66,"s":[{"i":[[1,5],[-2,-6],[-7,0],[0,4],[14.036,0],[7.65,-6.414],[7.247,-5.107],[4.918,0.164],[12.569,8.758],[22.573,-8.821],[17.943,0.427],[41,0],[25.988,0.619],[2,3]],"o":[[-1,-5],[2,6],[7,0],[0,-4],[-7.603,0],[-5.911,4.956],[-7.332,5.167],[-14.474,-0.482],[-24.151,-16.829],[-5.86,2.29],[-39.04,-0.93],[-46,0],[-38.989,-0.928],[-2,-3]],"v":[[-328,-31],[-338,120],[336,139],[326,-6],[299,-19],[276.739,-7.642],[257.287,8.255],[218,21],[180.151,0.829],[78.519,-2.331],[0,19],[-89,-30],[-220,20],[-305,-18]],"c":true}],"e":[{"i":[[1,5],[-2,-6],[-7,0],[0,4],[14.036,0],[2.174,-0.262],[4.752,3.855],[26,0],[7.165,-7.199],[23.02,-0.207],[36,0],[45.011,0],[23,-1],[2,3]],"o":[[-1,-5],[2,6],[7,0],[0,-4],[-9.088,0],[-1.05,0.127],[-6.536,-5.303],[-16,0],[-12.471,12.53],[-38.545,0.347],[-43.012,0],[-33,0],[-33.983,1.478],[-2,-3]],"v":[[-328,-31],[-338,120],[336,139],[326,-6],[318,29],[308.787,35.235],[300.95,30.3],[216,-41],[173.835,-10.801],[97.545,33.653],[12,-52],[-91,21],[-219,-19],[-308,21]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":104,"s":[{"i":[[1,5],[-2,-6],[-7,0],[0,4],[14.036,0],[2.174,-0.262],[4.752,3.855],[26,0],[7.165,-7.199],[23.02,-0.207],[36,0],[45.011,0],[23,-1],[2,3]],"o":[[-1,-5],[2,6],[7,0],[0,-4],[-9.088,0],[-1.05,0.127],[-6.536,-5.303],[-16,0],[-12.471,12.53],[-38.545,0.347],[-43.012,0],[-33,0],[-33.983,1.478],[-2,-3]],"v":[[-328,-31],[-338,120],[336,139],[326,-6],[318,29],[308.787,35.235],[300.95,30.3],[216,-41],[173.835,-10.801],[97.545,33.653],[12,-52],[-91,21],[-219,-19],[-308,21]],"c":true}],"e":[{"i":[[1,5],[-2,-6],[-7,0],[0,4],[14.036,0],[7.65,-6.414],[7.247,-5.107],[31.981,3.198],[31.084,18.789],[26.175,-15.755],[17.906,1.226],[26,0],[34,1],[2,3]],"o":[[-1,-5],[2,6],[7,0],[0,-4],[-7.603,0],[-5.911,4.956],[-7.332,5.167],[-20,-2],[-31.151,-18.829],[-10.519,6.331],[-73,-5],[-58.009,0],[-38.983,-1.147],[-2,-3]],"v":[[-328,-31],[-338,120],[336,139],[326,-6],[328,-28],[311.739,-15.642],[303.287,2.255],[243,46],[182.151,-23.171],[75.519,-5.331],[0,19],[-107,-20],[-220,20],[-305,-51]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":140,"s":[{"i":[[1,5],[-2,-6],[-7,0],[0,4],[14.036,0],[7.65,-6.414],[7.247,-5.107],[31.981,3.198],[31.084,18.789],[26.175,-15.755],[17.906,1.226],[26,0],[34,1],[2,3]],"o":[[-1,-5],[2,6],[7,0],[0,-4],[-7.603,0],[-5.911,4.956],[-7.332,5.167],[-20,-2],[-31.151,-18.829],[-10.519,6.331],[-73,-5],[-58.009,0],[-38.983,-1.147],[-2,-3]],"v":[[-328,-31],[-338,120],[336,139],[326,-6],[328,-28],[311.739,-15.642],[303.287,2.255],[243,46],[182.151,-23.171],[75.519,-5.331],[0,19],[-107,-20],[-220,20],[-305,-51]],"c":true}],"e":[{"i":[[1,5],[-2,-6],[-7,0],[0,4],[14.036,0],[41.129,-12.788],[26.96,-0.808],[1.399,-0.957],[19.256,-0.204],[26.627,-0.522],[21,0],[38,-1],[47.027,-1.206],[2,3]],"o":[[-1,-5],[2,6],[7,0],[0,-4],[-7.061,0],[-30.705,9.547],[-31.026,0.93],[-19,13],[-37.752,0.4],[-18.418,0.361],[-25.08,0],[-52.991,1.395],[-39,1],[-2,-3]],"v":[[-328,-31],[-338,120],[336,139],[326,-6],[333,-52],[273.705,21.453],[196.04,-2.192],[148,15],[96.752,88.6],[17.418,-14.361],[-35,30],[-104,-42],[-222,47],[-309,-23]],"c":true}]},{"t":174}],"ix":2},"nm":"Trazado 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.105882352941,0.376470588235,0.576470588235,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Trazo 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.105882352941,0.376470588235,0.576470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Relleno 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Forma 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":181,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/party_penguin.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/party_penguin.json deleted file mode 100644 index 06bb8ac2..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/party_penguin.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.10.2","fr":30,"ip":0,"op":58,"w":800,"h":800,"nm":"Fancy 2","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":2,"ty":3,"nm":"GLOBAL","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[54,551,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":218,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Hat Outlines","parent":9,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.158,"y":1},"o":{"x":0.075,"y":0.312},"n":"0p158_1_0p075_0p312","t":14,"s":[555.632,379.901,0],"e":[568.441,362.019,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.842,"y":1},"o":{"x":1,"y":0},"n":"0p842_1_1_0","t":29,"s":[568.441,362.019,0],"e":[555.632,379.901,0],"to":[0,0,0],"ti":[0,0,0]},{"t":34}],"ix":2},"a":{"a":0,"k":[555.632,379.901,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.296,0.995],[0,0],[0.995,-1.296],[-1.296,-0.995],[0,0],[-0.995,1.296]],"o":[[0,0],[-1.296,-0.995],[-0.996,1.297],[0,0],[1.297,0.995],[0.995,-1.296]],"v":[[28.034,17.79],[-24.43,-22.485],[-28.578,-21.94],[-28.033,-17.791],[24.43,22.484],[28.578,21.939]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[555.56,383.074],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.026,3.091],[0,0],[3.091,-4.026],[0,0],[0,0],[0,0]],"o":[[0,0],[-4.026,-3.091],[0,0],[0,0],[0,0],[3.091,-4.026]],"v":[[19.117,-2.46],[-2.198,-18.822],[-15.085,-17.129],[-23.902,-5.643],[11.993,21.914],[20.811,10.428]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[562.183,374.355],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":218,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Tie Outlines","parent":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[502.404,453,0],"ix":2},"a":{"a":0,"k":[502.404,453,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.852,0.654],[0,0],[0.654,-0.852],[0,0],[-0.852,-0.654],[0,0],[-0.654,0.852],[0,0]],"o":[[0,0],[-0.852,-0.654],[0,0],[-0.654,0.852],[0,0],[0.852,0.654],[0,0],[0.654,-0.852]],"v":[[6.301,-1.525],[-0.156,-6.48],[-2.893,-6.12],[-6.661,-1.214],[-6.301,1.525],[0.155,6.48],[2.893,6.121],[6.66,1.215]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[501.763,453.567],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.864,1.125],[0,0],[1.467,0.227],[0,0],[-0.761,-1.42],[0,0]],"o":[[0,0],[0.904,-1.178],[0,0],[-1.592,-0.246],[0,0],[0.67,1.25]],"v":[[0.98,7.35],[8.825,-2.868],[7.574,-5.988],[-6.948,-8.229],[-8.967,-5.376],[-2.291,7.083]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[512.737,462.455],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.864,1.125],[0,0],[-0.598,-1.359],[0,0],[1.568,0.368],[0,0]],"o":[[0,0],[0.904,-1.178],[0,0],[0.649,1.474],[0,0],[-1.381,-0.324]],"v":[[-8.442,2.354],[-0.597,-7.865],[2.74,-7.462],[8.657,5.987],[6.423,8.675],[-7.339,5.445]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[491.688,444.06],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":218,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Legs Right","parent":9,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[411.027,495.735,0],"ix":2},"a":{"a":0,"k":[411.027,495.735,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-4.8,-3.743],[-3.758,4.746]],"o":[[-3.743,4.8],[4.774,3.723],[0,0]],"v":[[-6.793,-9.596],[-4.88,5.873],[10.536,4.028]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[410.821,497.93],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":218,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Legs Left","parent":9,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[483.024,549.985,0],"ix":2},"a":{"a":0,"k":[483.024,549.985,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-4.8,-3.743],[-3.758,4.746]],"o":[[-3.743,4.8],[4.774,3.723],[0,0]],"v":[[-6.793,-9.596],[-4.88,5.873],[10.536,4.028]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[481.814,552.431],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":218,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Eyes","parent":9,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[528.919,419.966,0],"ix":2},"a":{"a":0,"k":[528.919,419.966,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":19,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[498.824,384.003],[487.435,399.044],[565.432,458.108],[576.822,443.068]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[493.78,392.277],[491.988,393.65],[566.012,450.516],[567.804,449.143]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[493.78,392.277],[491.988,393.65],[566.012,450.516],[567.804,449.143]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[498.824,384.003],[487.435,399.044],[565.432,458.108],[576.822,443.068]],"c":true}]},{"t":25}],"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.335,3.042],[3.043,2.335],[2.336,-3.042],[-3.042,-2.336]],"o":[[2.336,-3.042],[-3.042,-2.336],[-2.335,3.043],[3.042,2.335]],"v":[[5.508,4.229],[4.228,-5.508],[-5.509,-4.229],[-4.229,5.509]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[556.462,441.11],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.335,3.042],[3.043,2.335],[2.336,-3.042],[-3.042,-2.336]],"o":[[2.335,-3.042],[-3.042,-2.336],[-2.335,3.043],[3.042,2.335]],"v":[[5.509,4.229],[4.228,-5.508],[-5.509,-4.229],[-4.229,5.509]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[501.377,398.823],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":218,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"belly","parent":9,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[499.737,455.46,0],"ix":2},"a":{"a":0,"k":[499.737,455.46,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-8.652,-6.643],[6.642,-8.652],[0,0],[0,0]],"o":[[6.642,-8.652],[8.652,6.642],[0,0],[0,0],[0,0]],"v":[[-0.947,-30.385],[26.746,-34.023],[30.385,-6.332],[-5.695,40.667],[-37.027,16.613]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[540.039,460.227],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-8.652,-6.642],[6.642,-8.652],[0,0],[0,0]],"o":[[6.642,-8.652],[8.652,6.642],[0,0],[0,0],[0,0]],"v":[[-0.947,-30.385],[26.746,-34.024],[30.385,-6.332],[-5.695,40.666],[-37.027,16.613]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[483.324,416.688],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.347,9.496],[0,0],[0,0],[0,0],[-13.318,-10.225],[0,0],[-10.132,13.198],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[-10.132,13.199],[0,0],[13.318,10.224],[0,0],[0,0],[0,0],[-8.762,3.9]],"v":[[11.966,-28.935],[18.368,-74.081],[-15.857,-70.098],[-62.668,-9.121],[-56.898,33.289],[-17.082,63.857],[25.379,58.471],[72.799,-3.298],[70.701,-34.535],[29.089,-16.01]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[493.819,462.152],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":218,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Body","parent":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.37],"y":[1]},"o":{"x":[0.45],"y":[0]},"n":["0p37_1_0p45_0"],"t":0,"s":[50],"e":[-14.62]},{"i":{"x":[0.674],"y":[-0.319]},"o":{"x":[0.341],"y":[0]},"n":["0p674_-0p319_0p341_0"],"t":19,"s":[-14.62],"e":[-14.418]},{"i":{"x":[0.56],"y":[1]},"o":{"x":[0.64],"y":[0.067]},"n":["0p56_1_0p64_0p067"],"t":23,"s":[-14.418],"e":[50]},{"t":56}],"ix":10},"p":{"a":0,"k":[459.201,356.344,0],"ix":2},"a":{"a":0,"k":[449.08,358.479,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":6,"s":[100,100,100],"e":[131,78,100]},{"i":{"x":[0.27,0.27,0.27],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0]},"n":["0p27_1_0p167_0p167","0p27_1_0p167_0p167","0p27_1_0p167_0"],"t":10,"s":[131,78,100],"e":[100,100,100]},{"t":17}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.465,7.119],[7.118,5.465],[5.465,-7.118],[-7.119,-5.465]],"o":[[5.465,-7.119],[-7.119,-5.465],[-5.466,7.119],[7.119,5.465]],"v":[[12.89,9.896],[9.896,-12.889],[-12.889,-9.895],[-9.895,12.89]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.952999997606,0.808000033509,0.395999983245,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[555.002,442.372],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.92,1.1],[-3.672,-2.82],[1.116,-4.212],[1.755,1.347]],"o":[[-1.755,-1.348],[3.781,-2.167],[3.673,2.82],[-0.567,2.139],[0,0]],"v":[[-7.978,-1.473],[-7.691,-6.658],[4.632,-5.83],[8.617,5.861],[3.682,7.478]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[521.655,428.655],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[1.126,-0.646],[2.156,1.654],[-0.656,2.472],[-1.03,-0.791]],"o":[[1.03,0.791],[-2.219,1.271],[-2.155,-1.655],[0.332,-1.255],[0,0]],"v":[[4.682,0.864],[4.513,3.908],[-2.719,3.421],[-5.056,-3.44],[-2.161,-4.388]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[519.534,432.603],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-8.652,-6.643],[6.642,-8.652],[0,0],[0,0]],"o":[[6.642,-8.652],[8.652,6.642],[0,0],[0,0],[0,0]],"v":[[-0.947,-30.385],[26.746,-34.023],[30.385,-6.332],[-5.695,40.667],[-37.027,16.613]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[540.039,460.227],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-8.652,-6.642],[6.642,-8.652],[0,0],[0,0]],"o":[[6.642,-8.652],[8.652,6.642],[0,0],[0,0],[0,0]],"v":[[-0.947,-30.385],[26.746,-34.024],[30.385,-6.332],[-5.695,40.666],[-37.027,16.613]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[483.324,416.688],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[7.01,5.381],[-5.087,6.626],[0,0],[0,0]],"o":[[-5.087,6.626],[-7.009,-5.381],[0,0],[0,0],[0,0]],"v":[[1.419,23.922],[-20.483,26.176],[-23.964,4.436],[3.667,-31.556],[29.05,-12.07]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[527.549,419.108],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.347,9.496],[0,0],[0,0],[0,0],[-13.318,-10.225],[0,0],[-10.132,13.198],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[-10.132,13.199],[0,0],[13.318,10.224],[0,0],[0,0],[0,0],[-8.762,3.9]],"v":[[11.966,-28.935],[18.368,-74.081],[-15.857,-70.098],[-62.668,-9.121],[-56.898,33.289],[-17.082,63.857],[25.379,58.471],[72.799,-3.298],[70.701,-34.535],[29.089,-16.01]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[493.819,462.152],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":2,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[35.29,27.092],[0,0],[27.092,-35.29],[0,0],[-14.019,-10.762],[0,0],[-10.762,14.018],[0,0]],"o":[[0,0],[-35.29,-27.092],[0,0],[-10.762,14.018],[0,0],[14.018,10.761],[0,0],[27.092,-35.289]],"v":[[61.762,-78.449],[61.762,-78.449],[-51.19,-63.604],[-92.936,-9.225],[-87.039,35.645],[-10.009,94.779],[34.86,88.882],[76.606,34.503]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[442.313,523.242],"ix":2},"a":{"a":0,"k":[-52.793,64.655],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":218,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Glass Outlines","parent":11,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[601.505,484.344,0],"ix":2},"a":{"a":0,"k":[601.505,484.344,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.306,-5.957],[-6.185,0.826],[-8.305,-3.702],[-3.784,5.958]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[592.294,492.253],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.586,-1.251],[0,0],[1.347,0.192],[0,0],[-0.612,1.05],[0,0]],"o":[[0,0],[0.577,1.232],[0,0],[-1.204,-0.171],[0,0],[0.695,-1.194]],"v":[[1.794,-8.294],[8.957,7.011],[7.165,9.432],[-7.684,7.32],[-8.922,4.763],[-1.237,-8.43]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[609.898,479.757],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":218,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Arm R Outlines","parent":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.41],"y":[1]},"o":{"x":[0.59],"y":[0]},"n":["0p41_1_0p59_0"],"t":0,"s":[38],"e":[-42]},{"i":{"x":[0.41],"y":[1]},"o":{"x":[0.59],"y":[0]},"n":["0p41_1_0p59_0"],"t":28,"s":[-42],"e":[38]},{"t":53}],"ix":10},"p":{"a":0,"k":[575.043,479.064,0],"ix":2},"a":{"a":0,"k":[575.043,479.064,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[22.26,22.26],"ix":2},"p":{"a":0,"k":[4,-5],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646998985,0.121569001441,0.333332974303,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[570.715,484.126],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.105,0.259],[0,0],[0,0],[-2.281,5.643],[5.595,2.31]],"o":[[0,0],[0,0],[5.644,2.281],[2.269,-5.613],[-6.747,-2.786]],"v":[[-7.052,-14.471],[-15.484,6.389],[-1.134,12.19],[13.215,6.102],[7.208,-8.214]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[585.274,482.801],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":218,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Arm L Outlines","parent":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[460.434,386.251,0],"ix":2},"a":{"a":0,"k":[460.434,386.251,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.265,-0.087],[0,0],[0,0],[5.784,-1.897],[-1.843,-5.766]],"o":[[0,0],[0,0],[-1.897,-5.784],[-5.752,1.886],[2.223,6.953]],"v":[[-7.56,15.327],[13.819,8.316],[8.996,-6.392],[-4.91,-13.43],[-11.977,0.394]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[452.776,378.078],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":218,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"chandelier base","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[344.204,-453.167,0],"ix":2},"a":{"a":0,"k":[445.204,67.833,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[10.771,0],[0,0],[0,10.771],[0,0],[-4.486,0],[0,0],[0,-4.486],[0,0]],"o":[[0,0],[-10.771,0],[0,0],[0,-4.486],[0,0],[4.486,0],[0,0],[0,10.771]],"v":[[14.55,16.216],[-14.55,16.216],[-34.053,-3.287],[-34.053,-8.093],[-25.931,-16.216],[25.931,-16.216],[34.053,-8.093],[34.053,-3.287]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[448.062,70.049],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 16","np":2,"cix":2,"ix":16,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.689,0],[0,0],[0,4.69],[0,0],[-1.953,0],[0,0],[0,-1.953],[0,0]],"o":[[0,0],[-4.689,0],[0,0],[0,-1.953],[0,0],[1.953,0],[0,0],[0,4.69]],"v":[[6.334,7.059],[-6.335,7.059],[-14.825,-1.431],[-14.825,-3.523],[-11.289,-7.059],[11.289,-7.059],[14.825,-3.523],[14.825,-1.431]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[448.063,90.319],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 17","np":2,"cix":2,"ix":17,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":218,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"chandelier bottom 2","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.16],"y":[1]},"o":{"x":[0.57],"y":[0]},"n":["0p16_1_0p57_0"],"t":3,"s":[22],"e":[-22]},{"i":{"x":[0.16],"y":[1]},"o":{"x":[0.57],"y":[0]},"n":["0p16_1_0p57_0"],"t":21.473,"s":[-22],"e":[-21.933]},{"i":{"x":[0.16],"y":[1]},"o":{"x":[0.57],"y":[0]},"n":["0p16_1_0p57_0"],"t":26,"s":[-21.933],"e":[22]},{"t":55}],"ix":10},"p":{"a":0,"k":[346.204,-429.167,0],"ix":2},"a":{"a":0,"k":[445.992,91.903,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-7.487,-12.331],[7.486,-12.331],[7.486,12.331],[-7.487,12.331]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.523,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[366.388,306.969],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.393,0],[0,0],[0,5.392],[0,0],[2.246,0],[0,0],[0,-2.245],[0,0]],"o":[[0,0],[5.392,0],[0,0],[0,-2.245],[0,0],[-2.246,0],[0,0],[0,5.392]],"v":[[-7.284,8.118],[7.285,8.118],[17.048,-1.645],[17.048,-4.052],[12.983,-8.118],[-12.983,-8.118],[-17.048,-4.052],[-17.048,-1.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[366.914,315.483],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[7.093,-12.691],[0.261,-4.766],[0,0],[1.729,-3.557],[4.702,22.165]],"o":[[-7.974,-14.081],[-2.124,3.8],[0,0],[-0.232,4.257],[-8.24,16.946],[0,0]],"v":[[36.922,-47.763],[6.956,-47.724],[3.435,-34.5],[-0.245,32.901],[-3.113,44.897],[-36.922,37.465]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.776,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[404.283,275.725],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[10.727,-12.691],[0.393,-4.766],[0,0],[2.616,-3.556],[7.111,22.164]],"o":[[0,0],[-12.059,-14.08],[-3.212,3.8],[0,0],[-0.351,4.256],[-12.461,16.947],[0,0]],"v":[[60.66,-36.493],[51.008,-47.764],[5.693,-47.725],[0.37,-34.501],[-5.196,32.9],[-9.535,44.896],[-60.66,37.464]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.414,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[388.878,273.833],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-5.311,-8.748],[5.311,-8.748],[5.311,8.748],[-5.311,8.748]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.499,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[328.433,304.094],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.826,0],[0,0],[0,3.826],[0,0],[1.593,0],[0,0],[0,-1.593],[0,0]],"o":[[0,0],[3.825,0],[0,0],[0,-1.593],[0,0],[-1.594,0],[0,0],[0,3.826]],"v":[[-5.168,5.759],[5.168,5.759],[12.095,-1.167],[12.095,-2.874],[9.21,-5.759],[-9.21,-5.759],[-12.095,-2.874],[-12.095,-1.167]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[328.807,310.135],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[7.487,-12.331],[-7.487,-12.331],[-7.487,12.331],[7.487,12.331]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.523,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[532.021,305.346],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":2,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.393,0],[0,0],[0,5.392],[0,0],[-2.246,0],[0,0],[0,-2.245],[0,0]],"o":[[0,0],[-5.392,0],[0,0],[0,-2.245],[0,0],[2.246,0],[0,0],[0,5.392]],"v":[[7.285,8.118],[-7.284,8.118],[-17.048,-1.645],[-17.048,-4.052],[-12.982,-8.118],[12.983,-8.118],[17.049,-4.052],[17.049,-1.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[531.494,313.861],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-7.093,-12.691],[-0.261,-4.766],[0,0],[-1.729,-3.557],[-4.702,22.165]],"o":[[7.974,-14.081],[2.124,3.8],[0,0],[0.232,4.257],[8.24,16.946],[0,0]],"v":[[-36.921,-47.763],[-6.956,-47.724],[-3.435,-34.5],[0.245,32.901],[3.113,44.897],[36.922,37.465]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.776,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[494.125,274.103],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":2,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-10.727,-12.691],[-0.393,-4.766],[0,0],[-2.616,-3.556],[-7.111,22.164]],"o":[[0,0],[12.059,-14.081],[3.212,3.8],[0,0],[0.351,4.256],[12.461,16.947],[0,0]],"v":[[-60.66,-36.493],[-51.008,-47.762],[-5.693,-47.725],[-0.37,-34.501],[5.196,32.9],[9.535,44.896],[60.66,37.464]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.414,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[509.53,272.212],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10","np":2,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[5.311,-8.748],[-5.311,-8.748],[-5.311,8.748],[5.311,8.748]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.499,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[569.975,302.473],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11","np":2,"cix":2,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.826,0],[0,0],[0,3.826],[0,0],[-1.593,0],[0,0],[0,-1.593],[0,0]],"o":[[0,0],[-3.825,0],[0,0],[0,-1.593],[0,0],[1.594,0],[0,0],[0,3.826]],"v":[[5.168,5.759],[-5.168,5.759],[-12.095,-1.167],[-12.095,-2.874],[-9.21,-5.759],[9.21,-5.759],[12.095,-2.874],[12.095,-1.167]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[569.601,308.513],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12","np":2,"cix":2,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,3.927],[3.927,0],[0,-3.927],[-3.927,0]],"o":[[0,-3.927],[-3.927,0],[0,3.927],[3.927,0]],"v":[[7.11,0],[0,-7.11],[-7.11,0],[0,7.11]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.188,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[448.063,157.884],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":3,"cix":2,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,5.821],[5.821,0],[0,-5.821],[-5.821,0]],"o":[[0,-5.821],[-5.821,0],[0,5.821],[5.821,0]],"v":[[10.54,0],[0,-10.54],[-10.54,0],[0,10.54]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.243,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[448.063,357.338],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 14","np":3,"cix":2,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[448.062,90.319],[448.062,347.609]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.243,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.944999964097,0.776000019148,0.361000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 15","np":3,"cix":2,"ix":15,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":218,"st":0,"bm":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/peli-canon.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/peli-canon.json deleted file mode 100644 index d7a78c7a..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/peli-canon.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.10.2","fr":24,"ip":0,"op":105,"w":1500,"h":1500,"nm":"Interactive link","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":3,"nm":"RECOIL","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.24],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p24_1_0p167_0p167"],"t":33.6,"s":[0],"e":[-8]},{"i":{"x":[0.24],"y":[1]},"o":{"x":[0.167],"y":[0.182]},"n":["0p24_1_0p167_0p182"],"t":41.6,"s":[-8],"e":[0]},{"t":60.8}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.48,"y":1},"o":{"x":0.52,"y":0},"n":"0p48_1_0p52_0","t":33.6,"s":[960,540,0],"e":[806,540,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.48,"y":1},"o":{"x":0.52,"y":0},"n":"0p48_1_0p52_0","t":36.8,"s":[806,540,0],"e":[960,540,0],"to":[0,0,0],"ti":[0,0,0]},{"t":57.6}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":3,"nm":"Smoke Move","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.64,"y":0},"n":"0p833_1_0p64_0","t":32.8,"s":[960,540,0],"e":[466,540,0],"to":[0,0,0],"ti":[0,0,0]},{"t":72.8}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":15.2,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"Smoke Size","parent":2,"sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[237.027,-106.941,0],"ix":2},"a":{"a":0,"k":[-46,36,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,1]},"o":{"x":[0.56,0.56,0.56],"y":[0,0,0]},"n":["0p833_0p833_0p56_0","0p833_0p833_0p56_0","0p833_1_0p56_0"],"t":32.8,"s":[0,0,100],"e":[100,100,100]},{"t":36}],"ix":6}},"ao":0,"ip":32.8,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Smoke 4","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.56,"y":0},"n":"0p833_0p833_0p56_0","t":32.8,"s":[77,125,0],"e":[102,174,0],"to":[0,0,0],"ti":[0,0,0]},{"t":52}],"ix":2},"a":{"a":0,"k":[434.027,-253.941,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,17.667]},"o":{"x":[0.56,0.56,0.56],"y":[0,0,0]},"n":["0p833_0p833_0p56_0","0p833_0p833_0p56_0","0p833_17p667_0p56_0"],"t":32.8,"s":[48,48,100],"e":[0,0,100]},{"t":52}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[127.148,127.148],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952941176471,0.941176470588,0.921568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[434.027,-253.941],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[117.417,117.417],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":32.8,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Smoke 3","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.56,"y":0},"n":"0p833_0p833_0p56_0","t":32.8,"s":[95,-5,0],"e":[-67,-145,0],"to":[0,0,0],"ti":[0,0,0]},{"t":66.4}],"ix":2},"a":{"a":0,"k":[434.027,-253.941,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,17.667]},"o":{"x":[0.56,0.56,0.56],"y":[0,0,0]},"n":["0p833_0p833_0p56_0","0p833_0p833_0p56_0","0p833_17p667_0p56_0"],"t":32.8,"s":[48,48,100],"e":[0,0,100]},{"t":66.4}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":38.4,"s":[80.71,80.71],"e":[0,0]},{"t":62.4}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":38.4,"s":[-43.263,-88],"e":[-2,-423],"to":[0,0],"ti":[0,0]},{"t":62.4}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952941176471,0.941176470588,0.921568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[483.273,-188.457],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[127.148,127.148],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952941176471,0.941176470588,0.921568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[434.027,-253.941],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[117.417,117.417],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":32.8,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Smoke 2","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.56,"y":0},"n":"0p833_0p833_0p56_0","t":32.8,"s":[117,59,0],"e":[300,308,0],"to":[0,0,0],"ti":[0,0,0]},{"t":68}],"ix":2},"a":{"a":0,"k":[434.027,-253.941,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,17.667]},"o":{"x":[0.56,0.56,0.56],"y":[0,0,0]},"n":["0p833_0p833_0p56_0","0p833_0p833_0p56_0","0p833_17p667_0p56_0"],"t":32.8,"s":[100,100,100],"e":[0,0,100]},{"t":60}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":35.2,"s":[99.664,99.664],"e":[0,0]},{"t":52.8}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":35.2,"s":[0,-59],"e":[204,-115.733],"to":[0,0],"ti":[0,0]},{"t":52.8}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952941176471,0.941176470588,0.921568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[433.914,-183.835],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 4","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":35.2,"s":[99.664,99.664],"e":[0,0]},{"t":62.4}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":35.2,"s":[0,-59],"e":[42,101],"to":[0,0],"ti":[0,0]},{"t":62.4}],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952941176471,0.941176470588,0.921568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[433.914,-183.835],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 2","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[127.148,127.148],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952941176471,0.941176470588,0.921568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[434.027,-253.941],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[117.417,117.417],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":32.8,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Smoke","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.56,"y":0},"n":"0p833_0p833_0p56_0","t":32.8,"s":[23,5,0],"e":[23,-80,0],"to":[0,0,0],"ti":[0,0,0]},{"t":66.4}],"ix":2},"a":{"a":0,"k":[434.027,-253.941,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,17.667]},"o":{"x":[0.56,0.56,0.56],"y":[0,0,0]},"n":["0p833_0p833_0p56_0","0p833_0p833_0p56_0","0p833_17p667_0p56_0"],"t":32.8,"s":[100,100,100],"e":[0,0,100]},{"t":66.4}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[127.148,127.148],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952941176471,0.941176470588,0.921568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[434.027,-253.941],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[117.417,117.417],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":32.8,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"gun mask","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-1.035,"ix":10},"p":{"a":0,"k":[-13.325,60.246,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[133.333,133.333,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[224.133,457.844],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254991718,0.2588239782,0.427451010311,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952940996955,0.941175991881,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[130.066,192.922],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"gun quick","parent":13,"tt":2,"refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-6,"ix":10},"p":{"a":0,"k":[-46.405,49.873,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[133.333,133.333,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":3,"nm":"Body Main","parent":1,"sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p52_1_0p167_0p167"],"t":0,"s":[3],"e":[4]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.48],"y":[0]},"n":["0p52_1_0p48_0"],"t":3.378,"s":[4],"e":[0]},{"i":{"x":[0.833],"y":[0.889]},"o":{"x":[0.48],"y":[0]},"n":["0p833_0p889_0p48_0"],"t":11.822,"s":[0],"e":[3]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.167],"y":[0.333]},"n":["0p52_1_0p167_0p333"],"t":15.2,"s":[3],"e":[4]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.48],"y":[0]},"n":["0p52_1_0p48_0"],"t":18.578,"s":[4],"e":[0]},{"i":{"x":[0.833],"y":[0.889]},"o":{"x":[0.48],"y":[0]},"n":["0p833_0p889_0p48_0"],"t":27.022,"s":[0],"e":[3]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.167],"y":[0.333]},"n":["0p52_1_0p167_0p333"],"t":30.4,"s":[3],"e":[4]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.48],"y":[0]},"n":["0p52_1_0p48_0"],"t":33.778,"s":[4],"e":[0]},{"i":{"x":[0.833],"y":[0.889]},"o":{"x":[0.48],"y":[0]},"n":["0p833_0p889_0p48_0"],"t":42.222,"s":[0],"e":[3]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.167],"y":[0.333]},"n":["0p52_1_0p167_0p333"],"t":45.6,"s":[3],"e":[4]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.48],"y":[0]},"n":["0p52_1_0p48_0"],"t":48.978,"s":[4],"e":[0]},{"i":{"x":[0.833],"y":[0.889]},"o":{"x":[0.48],"y":[0]},"n":["0p833_0p889_0p48_0"],"t":57.422,"s":[0],"e":[3]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.167],"y":[0.333]},"n":["0p52_1_0p167_0p333"],"t":60.8,"s":[3],"e":[4]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.48],"y":[0]},"n":["0p52_1_0p48_0"],"t":64.178,"s":[4],"e":[0]},{"i":{"x":[0.833],"y":[0.889]},"o":{"x":[0.48],"y":[0]},"n":["0p833_0p889_0p48_0"],"t":72.622,"s":[0],"e":[3]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.167],"y":[0.333]},"n":["0p52_1_0p167_0p333"],"t":76,"s":[3],"e":[4]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.48],"y":[0]},"n":["0p52_1_0p48_0"],"t":79.378,"s":[4],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.48],"y":[0]},"n":["0p833_0p833_0p48_0"],"t":87.822,"s":[0],"e":[3]},{"t":91.2}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.52,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p52_1_0p167_0p167","t":0,"s":[10.895,75.112,0],"e":[10.895,57.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.52,"y":1},"o":{"x":0.48,"y":0},"n":"0p52_1_0p48_0","t":4.222,"s":[10.895,57.112,0],"e":[10.895,105.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.9},"o":{"x":0.48,"y":0},"n":"0p833_0p9_0p48_0","t":12.667,"s":[10.895,105.112,0],"e":[10.895,75.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.52,"y":1},"o":{"x":0.167,"y":0.278},"n":"0p52_1_0p167_0p278","t":15.2,"s":[10.895,75.112,0],"e":[10.895,57.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.52,"y":1},"o":{"x":0.48,"y":0},"n":"0p52_1_0p48_0","t":19.422,"s":[10.895,57.112,0],"e":[10.895,105.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.9},"o":{"x":0.48,"y":0},"n":"0p833_0p9_0p48_0","t":27.867,"s":[10.895,105.112,0],"e":[10.895,75.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.52,"y":1},"o":{"x":0.167,"y":0.278},"n":"0p52_1_0p167_0p278","t":30.4,"s":[10.895,75.112,0],"e":[10.895,57.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.52,"y":1},"o":{"x":0.48,"y":0},"n":"0p52_1_0p48_0","t":34.622,"s":[10.895,57.112,0],"e":[10.895,105.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.9},"o":{"x":0.48,"y":0},"n":"0p833_0p9_0p48_0","t":43.067,"s":[10.895,105.112,0],"e":[10.895,75.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.52,"y":1},"o":{"x":0.167,"y":0.278},"n":"0p52_1_0p167_0p278","t":45.6,"s":[10.895,75.112,0],"e":[10.895,57.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.52,"y":1},"o":{"x":0.48,"y":0},"n":"0p52_1_0p48_0","t":49.822,"s":[10.895,57.112,0],"e":[10.895,105.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.9},"o":{"x":0.48,"y":0},"n":"0p833_0p9_0p48_0","t":58.267,"s":[10.895,105.112,0],"e":[10.895,75.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.52,"y":1},"o":{"x":0.167,"y":0.278},"n":"0p52_1_0p167_0p278","t":60.8,"s":[10.895,75.112,0],"e":[10.895,57.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.52,"y":1},"o":{"x":0.48,"y":0},"n":"0p52_1_0p48_0","t":65.022,"s":[10.895,57.112,0],"e":[10.895,105.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.9},"o":{"x":0.48,"y":0},"n":"0p833_0p9_0p48_0","t":73.467,"s":[10.895,105.112,0],"e":[10.895,75.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.52,"y":1},"o":{"x":0.167,"y":0.278},"n":"0p52_1_0p167_0p278","t":76,"s":[10.895,75.112,0],"e":[10.895,57.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.52,"y":1},"o":{"x":0.48,"y":0},"n":"0p52_1_0p48_0","t":80.222,"s":[10.895,57.112,0],"e":[10.895,105.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.9},"o":{"x":0.48,"y":0},"n":"0p833_0p9_0p48_0","t":88.667,"s":[10.895,105.112,0],"e":[10.895,75.112,0],"to":[0,0,0],"ti":[0,0,0]},{"t":91.2}],"ix":2},"a":{"a":0,"k":[60,60,0],"ix":1},"s":{"a":0,"k":[75,75,100],"ix":6}},"ao":0,"ip":0,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"wing 5","parent":10,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.39],"y":[1]},"o":{"x":[0.79],"y":[0]},"n":["0p39_1_0p79_0"],"t":0,"s":[59],"e":[146]},{"i":{"x":[0.39],"y":[1]},"o":{"x":[0.79],"y":[0]},"n":["0p39_1_0p79_0"],"t":10.133,"s":[146],"e":[59]},{"i":{"x":[0.39],"y":[1]},"o":{"x":[0.79],"y":[0]},"n":["0p39_1_0p79_0"],"t":15.2,"s":[59],"e":[146]},{"i":{"x":[0.39],"y":[1]},"o":{"x":[0.79],"y":[0]},"n":["0p39_1_0p79_0"],"t":25.333,"s":[146],"e":[59]},{"i":{"x":[0.39],"y":[1]},"o":{"x":[0.79],"y":[0]},"n":["0p39_1_0p79_0"],"t":30.4,"s":[59],"e":[146]},{"i":{"x":[0.39],"y":[1]},"o":{"x":[0.79],"y":[0]},"n":["0p39_1_0p79_0"],"t":40.533,"s":[146],"e":[59]},{"i":{"x":[0.39],"y":[1]},"o":{"x":[0.79],"y":[0]},"n":["0p39_1_0p79_0"],"t":45.6,"s":[59],"e":[146]},{"i":{"x":[0.39],"y":[1]},"o":{"x":[0.79],"y":[0]},"n":["0p39_1_0p79_0"],"t":55.733,"s":[146],"e":[59]},{"i":{"x":[0.39],"y":[1]},"o":{"x":[0.79],"y":[0]},"n":["0p39_1_0p79_0"],"t":60.8,"s":[59],"e":[146]},{"i":{"x":[0.39],"y":[1]},"o":{"x":[0.79],"y":[0]},"n":["0p39_1_0p79_0"],"t":70.933,"s":[146],"e":[59]},{"i":{"x":[0.39],"y":[1]},"o":{"x":[0.79],"y":[0]},"n":["0p39_1_0p79_0"],"t":76,"s":[59],"e":[146]},{"i":{"x":[0.39],"y":[1]},"o":{"x":[0.79],"y":[0]},"n":["0p39_1_0p79_0"],"t":86.133,"s":[146],"e":[59]},{"t":91.2}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.79,"y":0},"n":"0p833_0p833_0p79_0","t":0,"s":[0.267,50.477,0],"e":[-11.733,50.477,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.79,"y":0},"n":"0p833_1_0p79_0","t":10.133,"s":[-11.733,50.477,0],"e":[0.267,50.477,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.79,"y":0},"n":"0p833_0p833_0p79_0","t":15.2,"s":[0.267,50.477,0],"e":[-11.733,50.477,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.79,"y":0},"n":"0p833_1_0p79_0","t":25.333,"s":[-11.733,50.477,0],"e":[0.267,50.477,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.79,"y":0},"n":"0p833_0p833_0p79_0","t":30.4,"s":[0.267,50.477,0],"e":[-11.733,50.477,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.79,"y":0},"n":"0p833_1_0p79_0","t":40.533,"s":[-11.733,50.477,0],"e":[0.267,50.477,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.79,"y":0},"n":"0p833_0p833_0p79_0","t":45.6,"s":[0.267,50.477,0],"e":[-11.733,50.477,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.79,"y":0},"n":"0p833_1_0p79_0","t":55.733,"s":[-11.733,50.477,0],"e":[0.267,50.477,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.79,"y":0},"n":"0p833_0p833_0p79_0","t":60.8,"s":[0.267,50.477,0],"e":[-11.733,50.477,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.79,"y":0},"n":"0p833_1_0p79_0","t":70.933,"s":[-11.733,50.477,0],"e":[0.267,50.477,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.79,"y":0},"n":"0p833_0p833_0p79_0","t":76,"s":[0.267,50.477,0],"e":[-11.733,50.477,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.79,"y":0},"n":"0p833_1_0p79_0","t":86.133,"s":[-11.733,50.477,0],"e":[0.267,50.477,0],"to":[0,0,0],"ti":[0,0,0]},{"t":91.2}],"ix":2},"a":{"a":0,"k":[336.892,14.647,0],"ix":1},"s":{"a":0,"k":[-65,65,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.75,"y":0},"n":"0p833_0p833_0p75_0","t":0,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[0,0]],"o":[[0.645,95.54],[95.692,0],[0,0],[0,0]],"v":[[-173.975,-86.397],[0,86.397],[173.975,-86.397],[3.736,-86.397]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":5.742,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}],"e":[{"i":[[-24.545,-97.308],[-33.816,0],[-8.099,99.396],[30.355,0.919]],"o":[[24.545,97.308],[33.816,0],[0,0],[-30.355,-0.919]],"v":[[9.497,81.606],[126.549,226.875],[186.89,-79.109],[23.772,-83.224]],"c":true}]},{"i":{"x":0.39,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p39_1_0p167_0p167","t":7.656,"s":[{"i":[[-24.545,-97.308],[-33.816,0],[-8.099,99.396],[30.355,0.919]],"o":[[24.545,97.308],[33.816,0],[0,0],[-30.355,-0.919]],"v":[[9.497,81.606],[126.549,226.875],[186.89,-79.109],[23.772,-83.224]],"c":true}],"e":[{"i":[[-32.666,-125.331],[0,0],[-12.173,101.503],[0,0]],"o":[[32.666,125.331],[0,0],[0,0],[0,0]],"v":[[34.21,123.997],[161.316,256.65],[193.949,-75.126],[41.189,-104.236]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.75,"y":0},"n":"0p833_0p833_0p75_0","t":10.133,"s":[{"i":[[-32.666,-125.331],[0,0],[-12.173,101.503],[0,0]],"o":[[32.666,125.331],[0,0],[0,0],[0,0]],"v":[[34.21,123.997],[161.316,256.65],[193.949,-75.126],[41.189,-104.236]],"c":true}],"e":[{"i":[[-21.953,-84.231],[-31.381,0],[-8.392,99.548],[28.169,0.853]],"o":[[22.165,115.562],[31.381,0],[0,0],[-28.169,-0.853]],"v":[[5.328,68.178],[121.151,203.71],[187.398,-78.822],[25.027,-84.737]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":11.541,"s":[{"i":[[-21.953,-84.231],[-31.381,0],[-8.392,99.548],[28.169,0.853]],"o":[[22.165,115.562],[31.381,0],[0,0],[-28.169,-0.853]],"v":[[5.328,68.178],[121.151,203.71],[187.398,-78.822],[25.027,-84.737]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}]},{"i":{"x":0.39,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p39_1_0p167_0p167","t":13.005,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[0,0]],"o":[[0.645,95.54],[95.692,0],[0,0],[0,0]],"v":[[-173.975,-86.397],[0,86.397],[173.975,-86.397],[3.736,-86.397]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.75,"y":0},"n":"0p833_0p833_0p75_0","t":15.2,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[0,0]],"o":[[0.645,95.54],[95.692,0],[0,0],[0,0]],"v":[[-173.975,-86.397],[0,86.397],[173.975,-86.397],[3.736,-86.397]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20.942,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}],"e":[{"i":[[-24.545,-97.308],[-33.816,0],[-8.099,99.396],[30.355,0.919]],"o":[[24.545,97.308],[33.816,0],[0,0],[-30.355,-0.919]],"v":[[9.497,81.606],[126.549,226.875],[186.89,-79.109],[23.772,-83.224]],"c":true}]},{"i":{"x":0.39,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p39_1_0p167_0p167","t":22.856,"s":[{"i":[[-24.545,-97.308],[-33.816,0],[-8.099,99.396],[30.355,0.919]],"o":[[24.545,97.308],[33.816,0],[0,0],[-30.355,-0.919]],"v":[[9.497,81.606],[126.549,226.875],[186.89,-79.109],[23.772,-83.224]],"c":true}],"e":[{"i":[[-32.666,-125.331],[0,0],[-12.173,101.503],[0,0]],"o":[[32.666,125.331],[0,0],[0,0],[0,0]],"v":[[34.21,123.997],[161.316,256.65],[193.949,-75.126],[41.189,-104.236]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.75,"y":0},"n":"0p833_0p833_0p75_0","t":25.333,"s":[{"i":[[-32.666,-125.331],[0,0],[-12.173,101.503],[0,0]],"o":[[32.666,125.331],[0,0],[0,0],[0,0]],"v":[[34.21,123.997],[161.316,256.65],[193.949,-75.126],[41.189,-104.236]],"c":true}],"e":[{"i":[[-21.953,-84.231],[-31.381,0],[-8.392,99.548],[28.169,0.853]],"o":[[22.165,115.562],[31.381,0],[0,0],[-28.169,-0.853]],"v":[[5.328,68.178],[121.151,203.71],[187.398,-78.822],[25.027,-84.737]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":26.741,"s":[{"i":[[-21.953,-84.231],[-31.381,0],[-8.392,99.548],[28.169,0.853]],"o":[[22.165,115.562],[31.381,0],[0,0],[-28.169,-0.853]],"v":[[5.328,68.178],[121.151,203.71],[187.398,-78.822],[25.027,-84.737]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}]},{"i":{"x":0.39,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p39_1_0p167_0p167","t":28.205,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[0,0]],"o":[[0.645,95.54],[95.692,0],[0,0],[0,0]],"v":[[-173.975,-86.397],[0,86.397],[173.975,-86.397],[3.736,-86.397]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.75,"y":0},"n":"0p833_0p833_0p75_0","t":30.4,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[0,0]],"o":[[0.645,95.54],[95.692,0],[0,0],[0,0]],"v":[[-173.975,-86.397],[0,86.397],[173.975,-86.397],[3.736,-86.397]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":36.142,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}],"e":[{"i":[[-24.545,-97.308],[-33.816,0],[-8.099,99.396],[30.355,0.919]],"o":[[24.545,97.308],[33.816,0],[0,0],[-30.355,-0.919]],"v":[[9.497,81.606],[126.549,226.875],[186.89,-79.109],[23.772,-83.224]],"c":true}]},{"i":{"x":0.39,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p39_1_0p167_0p167","t":38.056,"s":[{"i":[[-24.545,-97.308],[-33.816,0],[-8.099,99.396],[30.355,0.919]],"o":[[24.545,97.308],[33.816,0],[0,0],[-30.355,-0.919]],"v":[[9.497,81.606],[126.549,226.875],[186.89,-79.109],[23.772,-83.224]],"c":true}],"e":[{"i":[[-32.666,-125.331],[0,0],[-12.173,101.503],[0,0]],"o":[[32.666,125.331],[0,0],[0,0],[0,0]],"v":[[34.21,123.997],[161.316,256.65],[193.949,-75.126],[41.189,-104.236]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.75,"y":0},"n":"0p833_0p833_0p75_0","t":40.533,"s":[{"i":[[-32.666,-125.331],[0,0],[-12.173,101.503],[0,0]],"o":[[32.666,125.331],[0,0],[0,0],[0,0]],"v":[[34.21,123.997],[161.316,256.65],[193.949,-75.126],[41.189,-104.236]],"c":true}],"e":[{"i":[[-21.953,-84.231],[-31.381,0],[-8.392,99.548],[28.169,0.853]],"o":[[22.165,115.562],[31.381,0],[0,0],[-28.169,-0.853]],"v":[[5.328,68.178],[121.151,203.71],[187.398,-78.822],[25.027,-84.737]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":41.941,"s":[{"i":[[-21.953,-84.231],[-31.381,0],[-8.392,99.548],[28.169,0.853]],"o":[[22.165,115.562],[31.381,0],[0,0],[-28.169,-0.853]],"v":[[5.328,68.178],[121.151,203.71],[187.398,-78.822],[25.027,-84.737]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}]},{"i":{"x":0.39,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p39_1_0p167_0p167","t":43.405,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[0,0]],"o":[[0.645,95.54],[95.692,0],[0,0],[0,0]],"v":[[-173.975,-86.397],[0,86.397],[173.975,-86.397],[3.736,-86.397]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.75,"y":0},"n":"0p833_0p833_0p75_0","t":45.6,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[0,0]],"o":[[0.645,95.54],[95.692,0],[0,0],[0,0]],"v":[[-173.975,-86.397],[0,86.397],[173.975,-86.397],[3.736,-86.397]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":51.342,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}],"e":[{"i":[[-24.545,-97.308],[-33.816,0],[-8.099,99.396],[30.355,0.919]],"o":[[24.545,97.308],[33.816,0],[0,0],[-30.355,-0.919]],"v":[[9.497,81.606],[126.549,226.875],[186.89,-79.109],[23.772,-83.224]],"c":true}]},{"i":{"x":0.39,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p39_1_0p167_0p167","t":53.256,"s":[{"i":[[-24.545,-97.308],[-33.816,0],[-8.099,99.396],[30.355,0.919]],"o":[[24.545,97.308],[33.816,0],[0,0],[-30.355,-0.919]],"v":[[9.497,81.606],[126.549,226.875],[186.89,-79.109],[23.772,-83.224]],"c":true}],"e":[{"i":[[-32.666,-125.331],[0,0],[-12.173,101.503],[0,0]],"o":[[32.666,125.331],[0,0],[0,0],[0,0]],"v":[[34.21,123.997],[161.316,256.65],[193.949,-75.126],[41.189,-104.236]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.75,"y":0},"n":"0p833_0p833_0p75_0","t":55.733,"s":[{"i":[[-32.666,-125.331],[0,0],[-12.173,101.503],[0,0]],"o":[[32.666,125.331],[0,0],[0,0],[0,0]],"v":[[34.21,123.997],[161.316,256.65],[193.949,-75.126],[41.189,-104.236]],"c":true}],"e":[{"i":[[-21.953,-84.231],[-31.381,0],[-8.392,99.548],[28.169,0.853]],"o":[[22.165,115.562],[31.381,0],[0,0],[-28.169,-0.853]],"v":[[5.328,68.178],[121.151,203.71],[187.398,-78.822],[25.027,-84.737]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":57.141,"s":[{"i":[[-21.953,-84.231],[-31.381,0],[-8.392,99.548],[28.169,0.853]],"o":[[22.165,115.562],[31.381,0],[0,0],[-28.169,-0.853]],"v":[[5.328,68.178],[121.151,203.71],[187.398,-78.822],[25.027,-84.737]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}]},{"i":{"x":0.39,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p39_1_0p167_0p167","t":58.605,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[0,0]],"o":[[0.645,95.54],[95.692,0],[0,0],[0,0]],"v":[[-173.975,-86.397],[0,86.397],[173.975,-86.397],[3.736,-86.397]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.75,"y":0},"n":"0p833_0p833_0p75_0","t":60.8,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[0,0]],"o":[[0.645,95.54],[95.692,0],[0,0],[0,0]],"v":[[-173.975,-86.397],[0,86.397],[173.975,-86.397],[3.736,-86.397]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":66.542,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}],"e":[{"i":[[-24.545,-97.308],[-33.816,0],[-8.099,99.396],[30.355,0.919]],"o":[[24.545,97.308],[33.816,0],[0,0],[-30.355,-0.919]],"v":[[9.497,81.606],[126.549,226.875],[186.89,-79.109],[23.772,-83.224]],"c":true}]},{"i":{"x":0.39,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p39_1_0p167_0p167","t":68.456,"s":[{"i":[[-24.545,-97.308],[-33.816,0],[-8.099,99.396],[30.355,0.919]],"o":[[24.545,97.308],[33.816,0],[0,0],[-30.355,-0.919]],"v":[[9.497,81.606],[126.549,226.875],[186.89,-79.109],[23.772,-83.224]],"c":true}],"e":[{"i":[[-32.666,-125.331],[0,0],[-12.173,101.503],[0,0]],"o":[[32.666,125.331],[0,0],[0,0],[0,0]],"v":[[34.21,123.997],[161.316,256.65],[193.949,-75.126],[41.189,-104.236]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.75,"y":0},"n":"0p833_0p833_0p75_0","t":70.933,"s":[{"i":[[-32.666,-125.331],[0,0],[-12.173,101.503],[0,0]],"o":[[32.666,125.331],[0,0],[0,0],[0,0]],"v":[[34.21,123.997],[161.316,256.65],[193.949,-75.126],[41.189,-104.236]],"c":true}],"e":[{"i":[[-21.953,-84.231],[-31.381,0],[-8.392,99.548],[28.169,0.853]],"o":[[22.165,115.562],[31.381,0],[0,0],[-28.169,-0.853]],"v":[[5.328,68.178],[121.151,203.71],[187.398,-78.822],[25.027,-84.737]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":72.341,"s":[{"i":[[-21.953,-84.231],[-31.381,0],[-8.392,99.548],[28.169,0.853]],"o":[[22.165,115.562],[31.381,0],[0,0],[-28.169,-0.853]],"v":[[5.328,68.178],[121.151,203.71],[187.398,-78.822],[25.027,-84.737]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}]},{"i":{"x":0.39,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p39_1_0p167_0p167","t":73.805,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[0,0]],"o":[[0.645,95.54],[95.692,0],[0,0],[0,0]],"v":[[-173.975,-86.397],[0,86.397],[173.975,-86.397],[3.736,-86.397]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.75,"y":0},"n":"0p833_0p833_0p75_0","t":76,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[0,0]],"o":[[0.645,95.54],[95.692,0],[0,0],[0,0]],"v":[[-173.975,-86.397],[0,86.397],[173.975,-86.397],[3.736,-86.397]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":81.742,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}],"e":[{"i":[[-24.545,-97.308],[-33.816,0],[-8.099,99.396],[30.355,0.919]],"o":[[24.545,97.308],[33.816,0],[0,0],[-30.355,-0.919]],"v":[[9.497,81.606],[126.549,226.875],[186.89,-79.109],[23.772,-83.224]],"c":true}]},{"i":{"x":0.39,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p39_1_0p167_0p167","t":83.656,"s":[{"i":[[-24.545,-97.308],[-33.816,0],[-8.099,99.396],[30.355,0.919]],"o":[[24.545,97.308],[33.816,0],[0,0],[-30.355,-0.919]],"v":[[9.497,81.606],[126.549,226.875],[186.89,-79.109],[23.772,-83.224]],"c":true}],"e":[{"i":[[-32.666,-125.331],[0,0],[-12.173,101.503],[0,0]],"o":[[32.666,125.331],[0,0],[0,0],[0,0]],"v":[[34.21,123.997],[161.316,256.65],[193.949,-75.126],[41.189,-104.236]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.75,"y":0},"n":"0p833_0p833_0p75_0","t":86.133,"s":[{"i":[[-32.666,-125.331],[0,0],[-12.173,101.503],[0,0]],"o":[[32.666,125.331],[0,0],[0,0],[0,0]],"v":[[34.21,123.997],[161.316,256.65],[193.949,-75.126],[41.189,-104.236]],"c":true}],"e":[{"i":[[-21.953,-84.231],[-31.381,0],[-8.392,99.548],[28.169,0.853]],"o":[[22.165,115.562],[31.381,0],[0,0],[-28.169,-0.853]],"v":[[5.328,68.178],[121.151,203.71],[187.398,-78.822],[25.027,-84.737]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":87.541,"s":[{"i":[[-21.953,-84.231],[-31.381,0],[-8.392,99.548],[28.169,0.853]],"o":[[22.165,115.562],[31.381,0],[0,0],[-28.169,-0.853]],"v":[[5.328,68.178],[121.151,203.71],[187.398,-78.822],[25.027,-84.737]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}]},{"i":{"x":0.39,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p39_1_0p167_0p167","t":89.005,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[0,0]],"o":[[0.645,95.54],[95.692,0],[0,0],[0,0]],"v":[[-173.975,-86.397],[0,86.397],[173.975,-86.397],[3.736,-86.397]],"c":true}]},{"t":91.2}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.152941176471,0.2,0.239215686275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[174.225,86.647],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Top Beak Outlines","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.26],"y":[1]},"o":{"x":[0.55],"y":[0]},"n":["0p26_1_0p55_0"],"t":2.109,"s":[0],"e":[-68]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":8.727,"s":[-68],"e":[-62]},{"i":{"x":[0.25],"y":[1]},"o":{"x":[0.161],"y":[0]},"n":["0p25_1_0p161_0"],"t":12.8,"s":[-62],"e":[-62]},{"i":{"x":[0.25],"y":[1]},"o":{"x":[0.396],"y":[0]},"n":["0p25_1_0p396_0"],"t":72,"s":[-62],"e":[-68]},{"i":{"x":[0.25],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p25_1_0p167_0"],"t":75.2,"s":[-68],"e":[0]},{"t":80}],"ix":10},"p":{"a":0,"k":[14.53,13.181,0],"ix":2},"a":{"a":0,"k":[7.365,40.329,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[19.537,0],[0,0],[0,-19.537],[0,0],[0,0],[0,0]],"o":[[0,0],[-19.537,0],[0,0],[0,0],[0,0],[0,-19.537]],"v":[[114.406,-21.413],[-114.407,-21.413],[-149.782,13.962],[-149.782,21.413],[149.781,21.413],[149.781,13.962]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.337000020345,0.258999992819,0.426999978458,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[150.031,21.663],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Bottom Beak Outlines","parent":15,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.26],"y":[1]},"o":{"x":[0.55],"y":[0]},"n":["0p26_1_0p55_0"],"t":1.6,"s":[0],"e":[18]},{"i":{"x":[0.26],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p26_1_0p167_0"],"t":8.8,"s":[18],"e":[18]},{"i":{"x":[0.26],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p26_1_0p167_0"],"t":72,"s":[18],"e":[0]},{"t":77.6}],"ix":10},"p":{"a":0,"k":[112.476,79.031,0],"ix":2},"a":{"a":0,"k":[10.209,15.628,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-77.12,0],[-0.52,76.997]],"o":[[0.52,76.997],[77.119,0],[0,0]],"v":[[-140.209,-69.629],[0,69.629],[140.209,-69.629]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.152999997606,0.2,0.238999998803,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.569000004787,0.866999966491,0.776000019148,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[150.209,79.629],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"small mask 2","parent":15,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":8.868,"ix":10},"p":{"a":0,"k":[162.027,67.974,0],"ix":2},"a":{"a":0,"k":[38.875,-61.949,0],"ix":1},"s":{"a":0,"k":[133.333,133.333,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[53.75,31.898],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254991718,0.2588239782,0.427451010311,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952940996955,0.941175991881,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[38.875,-61.949],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Head","parent":17,"tt":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p52_1_0p167_0p167"],"t":0,"s":[3],"e":[5]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.48],"y":[0]},"n":["0p52_1_0p48_0"],"t":4.222,"s":[5],"e":[-6]},{"i":{"x":[0.833],"y":[0.909]},"o":{"x":[0.48],"y":[0]},"n":["0p833_0p909_0p48_0"],"t":11.822,"s":[-6],"e":[3]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.167],"y":[0.509]},"n":["0p52_1_0p167_0p509"],"t":15.2,"s":[3],"e":[5]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.48],"y":[0]},"n":["0p52_1_0p48_0"],"t":19.422,"s":[5],"e":[-6]},{"i":{"x":[0.833],"y":[0.909]},"o":{"x":[0.48],"y":[0]},"n":["0p833_0p909_0p48_0"],"t":27.022,"s":[-6],"e":[3]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.167],"y":[0.509]},"n":["0p52_1_0p167_0p509"],"t":30.4,"s":[3],"e":[5]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.48],"y":[0]},"n":["0p52_1_0p48_0"],"t":34.622,"s":[5],"e":[-6]},{"i":{"x":[0.833],"y":[0.909]},"o":{"x":[0.48],"y":[0]},"n":["0p833_0p909_0p48_0"],"t":42.222,"s":[-6],"e":[3]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.167],"y":[0.509]},"n":["0p52_1_0p167_0p509"],"t":45.6,"s":[3],"e":[5]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.48],"y":[0]},"n":["0p52_1_0p48_0"],"t":49.822,"s":[5],"e":[-6]},{"i":{"x":[0.833],"y":[0.909]},"o":{"x":[0.48],"y":[0]},"n":["0p833_0p909_0p48_0"],"t":57.422,"s":[-6],"e":[3]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.167],"y":[0.509]},"n":["0p52_1_0p167_0p509"],"t":60.8,"s":[3],"e":[5]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.48],"y":[0]},"n":["0p52_1_0p48_0"],"t":65.022,"s":[5],"e":[-6]},{"i":{"x":[0.833],"y":[0.909]},"o":{"x":[0.48],"y":[0]},"n":["0p833_0p909_0p48_0"],"t":72.622,"s":[-6],"e":[3]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.167],"y":[0.509]},"n":["0p52_1_0p167_0p509"],"t":76,"s":[3],"e":[5]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.48],"y":[0]},"n":["0p52_1_0p48_0"],"t":80.222,"s":[5],"e":[-6]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.48],"y":[0]},"n":["0p833_0p833_0p48_0"],"t":87.822,"s":[-6],"e":[3]},{"t":91.2}],"ix":10},"p":{"a":0,"k":[16.908,51.505,0],"ix":2},"a":{"a":0,"k":[16.908,51.505,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,5.418],[5.418,0],[0,-5.418],[-5.418,0]],"o":[[0,-5.418],[-5.418,0],[0,5.418],[5.418,0]],"v":[[9.81,0],[0,-9.81],[-9.81,0],[0,9.81]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.152999997606,0.2,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.35,"y":1},"o":{"x":0.167,"y":0.075},"n":"0p35_1_0p167_0p075","t":2.4,"s":[93.656,43.492],"e":[80.656,43.492],"to":[0,0],"ti":[0,0]},{"i":{"x":0.35,"y":0.35},"o":{"x":0.167,"y":0.167},"n":"0p35_0p35_0p167_0p167","t":9.6,"s":[80.656,43.492],"e":[80.656,43.492],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":76.8,"s":[80.656,43.492],"e":[93.656,43.492],"to":[0,0],"ti":[0,0]},{"t":80.8}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-34.333],[-34.333,0],[0,34.333],[34.333,0]],"o":[[0,34.333],[34.333,0],[0,-34.333],[-34.333,0]],"v":[[-62.166,0],[0,62.166],[62.166,0],[0,-62.166]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952999997606,0.941000007181,0.922000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[78.067,62.416],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-5.557,0],[0,0]],"o":[[0,0],[-2.85,4.769],[0,0],[0,0]],"v":[[10.193,-21.154],[-8.623,10.328],[-2.48,21.154],[11.473,21.154]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952999997606,0.941000007181,0.922000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[11.723,57.927],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"small mask","parent":15,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":8.868,"ix":10},"p":{"a":0,"k":[157.188,77.464,0],"ix":2},"a":{"a":0,"k":[38.875,-61.949,0],"ix":1},"s":{"a":0,"k":[133.333,133.333,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[53.75,31.898],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254991718,0.2588239782,0.427451010311,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952940996955,0.941175991881,0.921568986481,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[38.875,-61.949],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Neck","parent":10,"tt":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.35],"y":[1]},"o":{"x":[0.167],"y":[0.137]},"n":["0p35_1_0p167_0p137"],"t":0,"s":[0],"e":[-24]},{"i":{"x":[0.35],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p35_1_0p167_0"],"t":23.2,"s":[-24],"e":[-24]},{"i":{"x":[0.35],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p35_1_0p167_0"],"t":75.2,"s":[-24],"e":[0]},{"t":84.8}],"ix":10},"p":{"a":0,"k":[8.184,36.832,0],"ix":2},"a":{"a":0,"k":[20.509,191.313,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-31.721,0],[0,31.721]],"o":[[0,0],[0,0],[0,31.721],[31.721,0],[0,0]],"v":[[57.436,-96.172],[-57.436,-96.172],[-57.436,38.736],[0,96.172],[57.436,38.736]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952999997606,0.941000007181,0.922000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[77.216,158.588],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Front Leg Outlines","parent":10,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p42_1_0p167_0p167"],"t":0,"s":[2.178],"e":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":3.378,"s":[3],"e":[22.178]},{"i":{"x":[0.833],"y":[0.932]},"o":{"x":[0.25],"y":[0]},"n":["0p833_0p932_0p25_0"],"t":12.667,"s":[22.178],"e":[2.178]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[-2.223]},"n":["0p42_1_0p167_-2p223"],"t":15.2,"s":[2.178],"e":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":18.578,"s":[3],"e":[22.178]},{"i":{"x":[0.833],"y":[0.932]},"o":{"x":[0.25],"y":[0]},"n":["0p833_0p932_0p25_0"],"t":27.867,"s":[22.178],"e":[2.178]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[-2.223]},"n":["0p42_1_0p167_-2p223"],"t":30.4,"s":[2.178],"e":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":33.778,"s":[3],"e":[22.178]},{"i":{"x":[0.833],"y":[0.932]},"o":{"x":[0.25],"y":[0]},"n":["0p833_0p932_0p25_0"],"t":43.067,"s":[22.178],"e":[2.178]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[-2.223]},"n":["0p42_1_0p167_-2p223"],"t":45.6,"s":[2.178],"e":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":48.978,"s":[3],"e":[22.178]},{"i":{"x":[0.833],"y":[0.932]},"o":{"x":[0.25],"y":[0]},"n":["0p833_0p932_0p25_0"],"t":58.267,"s":[22.178],"e":[2.178]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[-2.223]},"n":["0p42_1_0p167_-2p223"],"t":60.8,"s":[2.178],"e":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":64.178,"s":[3],"e":[22.178]},{"i":{"x":[0.833],"y":[0.932]},"o":{"x":[0.25],"y":[0]},"n":["0p833_0p932_0p25_0"],"t":73.467,"s":[22.178],"e":[2.178]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[-2.223]},"n":["0p42_1_0p167_-2p223"],"t":76,"s":[2.178],"e":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":79.378,"s":[3],"e":[22.178]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.25],"y":[0]},"n":["0p833_0p833_0p25_0"],"t":88.667,"s":[22.178],"e":[2.178]},{"t":91.2}],"ix":10},"p":{"a":0,"k":[-99.14,166.91,0],"ix":2},"a":{"a":0,"k":[65.762,6.163,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.577,-6.966],[0,0],[0.694,-2.36],[3.024,0.418],[0,0],[0.975,-2.897],[3.412,2.33],[0.591,1.594],[0,0]],"o":[[0,0],[1.688,2.108],[-0.861,2.928],[0,0],[-3.028,-0.418],[-1.319,3.917],[-1.291,-0.881],[0,0],[-3.103,-8.367]],"v":[[-7.838,-25.886],[22.348,11.824],[23.751,18.958],[16.853,23.219],[14.624,22.911],[7.724,27.182],[-1.725,30.521],[-4.652,26.768],[-21.342,-18.242]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.152999997606,0.2,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[15.31,60.893],"ix":2},"a":{"a":0,"k":[-9.385,-16.997],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p42_1_0p167_0p167"],"t":0,"s":[6],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":2.533,"s":[19],"e":[-25]},{"i":{"x":[0.833],"y":[0.882]},"o":{"x":[0.25],"y":[0]},"n":["0p833_0p882_0p25_0"],"t":12.667,"s":[-25],"e":[6]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.282]},"n":["0p42_1_0p167_0p282"],"t":15.2,"s":[6],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":17.733,"s":[19],"e":[-25]},{"i":{"x":[0.833],"y":[0.882]},"o":{"x":[0.25],"y":[0]},"n":["0p833_0p882_0p25_0"],"t":27.867,"s":[-25],"e":[6]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.282]},"n":["0p42_1_0p167_0p282"],"t":30.4,"s":[6],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":32.933,"s":[19],"e":[-25]},{"i":{"x":[0.833],"y":[0.882]},"o":{"x":[0.25],"y":[0]},"n":["0p833_0p882_0p25_0"],"t":43.067,"s":[-25],"e":[6]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.282]},"n":["0p42_1_0p167_0p282"],"t":45.6,"s":[6],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":48.133,"s":[19],"e":[-25]},{"i":{"x":[0.833],"y":[0.882]},"o":{"x":[0.25],"y":[0]},"n":["0p833_0p882_0p25_0"],"t":58.267,"s":[-25],"e":[6]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.282]},"n":["0p42_1_0p167_0p282"],"t":60.8,"s":[6],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":63.333,"s":[19],"e":[-25]},{"i":{"x":[0.833],"y":[0.882]},"o":{"x":[0.25],"y":[0]},"n":["0p833_0p882_0p25_0"],"t":73.467,"s":[-25],"e":[6]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.282]},"n":["0p42_1_0p167_0p282"],"t":76,"s":[6],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":78.533,"s":[19],"e":[-25]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.25],"y":[0]},"n":["0p833_0p833_0p25_0"],"t":88.667,"s":[-25],"e":[6]},{"t":91.2}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.75,2.75],[0,0],[-2.75,2.75],[0,0],[-2.75,-2.75],[2.75,-2.75],[0,0]],"o":[[0,0],[-2.75,-2.75],[0,0],[2.75,-2.75],[2.75,2.75],[0,0],[-2.75,2.75]],"v":[[-31.045,31.045],[-31.045,31.045],[-31.045,21.045],[21.045,-31.045],[31.045,-31.045],[31.045,-21.045],[-21.045,31.045]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.152999997606,0.2,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[41.478,34.045],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"Bottom Body Outlines","parent":10,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-51.067,125.81,0],"ix":2},"a":{"a":0,"k":[174.225,86.647,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[73.071,73.071],"ix":2},"p":{"a":0,"k":[79,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254991718,0.2588239782,0.427451010311,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952999997606,0.941000007181,0.922000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[233.351,-3.486],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-95.692,0],[-0.645,95.54]],"o":[[0.645,95.54],[95.692,0],[0,0]],"v":[[-173.975,-86.397],[0,86.397],[173.975,-86.397]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952999997606,0.941000007181,0.922000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[174.225,86.647],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":91.2,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Back Leg","parent":19,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p42_1_0p167_0p167"],"t":0,"s":[0.178],"e":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":5.067,"s":[3],"e":[22.178]},{"i":{"x":[0.833],"y":[0.964]},"o":{"x":[0.36],"y":[0]},"n":["0p833_0p964_0p36_0"],"t":13.511,"s":[22.178],"e":[0.178]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[-0.85]},"n":["0p42_1_0p167_-0p85"],"t":15.2,"s":[0.178],"e":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20.267,"s":[3],"e":[22.178]},{"i":{"x":[0.833],"y":[0.964]},"o":{"x":[0.36],"y":[0]},"n":["0p833_0p964_0p36_0"],"t":28.711,"s":[22.178],"e":[0.178]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[-0.85]},"n":["0p42_1_0p167_-0p85"],"t":30.4,"s":[0.178],"e":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35.467,"s":[3],"e":[22.178]},{"i":{"x":[0.833],"y":[0.964]},"o":{"x":[0.36],"y":[0]},"n":["0p833_0p964_0p36_0"],"t":43.911,"s":[22.178],"e":[0.178]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[-0.85]},"n":["0p42_1_0p167_-0p85"],"t":45.6,"s":[0.178],"e":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":50.667,"s":[3],"e":[22.178]},{"i":{"x":[0.833],"y":[0.964]},"o":{"x":[0.36],"y":[0]},"n":["0p833_0p964_0p36_0"],"t":59.111,"s":[22.178],"e":[0.178]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[-0.85]},"n":["0p42_1_0p167_-0p85"],"t":60.8,"s":[0.178],"e":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":65.867,"s":[3],"e":[22.178]},{"i":{"x":[0.833],"y":[0.964]},"o":{"x":[0.36],"y":[0]},"n":["0p833_0p964_0p36_0"],"t":74.311,"s":[22.178],"e":[0.178]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[-0.85]},"n":["0p42_1_0p167_-0p85"],"t":76,"s":[0.178],"e":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":81.067,"s":[3],"e":[22.178]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.36],"y":[0]},"n":["0p833_0p833_0p36_0"],"t":89.511,"s":[22.178],"e":[0.178]},{"t":91.2}],"ix":10},"p":{"a":0,"k":[182.152,135.748,0],"ix":2},"a":{"a":0,"k":[65.762,6.163,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.577,-6.966],[0,0],[0.694,-2.36],[3.024,0.418],[0,0],[0.975,-2.897],[3.412,2.33],[0.591,1.594],[0,0]],"o":[[0,0],[1.688,2.108],[-0.861,2.928],[0,0],[-3.028,-0.418],[-1.319,3.917],[-1.291,-0.881],[0,0],[-3.103,-8.367]],"v":[[-7.838,-25.886],[22.348,11.824],[23.751,18.958],[16.853,23.219],[14.624,22.911],[7.724,27.182],[-1.725,30.521],[-4.652,26.768],[-21.342,-18.242]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.152999997606,0.2,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[15.31,60.893],"ix":2},"a":{"a":0,"k":[-9.385,-16.997],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p42_1_0p167_0p167"],"t":0,"s":[0],"e":[17]},{"i":{"x":[0.833],"y":[0.779]},"o":{"x":[0.167],"y":[0.221]},"n":["0p833_0p779_0p167_0p221"],"t":4.222,"s":[17],"e":[-23]},{"i":{"x":[0.833],"y":[0.917]},"o":{"x":[0.36],"y":[0]},"n":["0p833_0p917_0p36_0"],"t":13.511,"s":[-23],"e":[0]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.28]},"n":["0p42_1_0p167_0p28"],"t":15.2,"s":[0],"e":[17]},{"i":{"x":[0.833],"y":[0.779]},"o":{"x":[0.167],"y":[0.221]},"n":["0p833_0p779_0p167_0p221"],"t":19.422,"s":[17],"e":[-23]},{"i":{"x":[0.833],"y":[0.917]},"o":{"x":[0.36],"y":[0]},"n":["0p833_0p917_0p36_0"],"t":28.711,"s":[-23],"e":[0]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.28]},"n":["0p42_1_0p167_0p28"],"t":30.4,"s":[0],"e":[17]},{"i":{"x":[0.833],"y":[0.779]},"o":{"x":[0.167],"y":[0.221]},"n":["0p833_0p779_0p167_0p221"],"t":34.622,"s":[17],"e":[-23]},{"i":{"x":[0.833],"y":[0.917]},"o":{"x":[0.36],"y":[0]},"n":["0p833_0p917_0p36_0"],"t":43.911,"s":[-23],"e":[0]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.28]},"n":["0p42_1_0p167_0p28"],"t":45.6,"s":[0],"e":[17]},{"i":{"x":[0.833],"y":[0.779]},"o":{"x":[0.167],"y":[0.221]},"n":["0p833_0p779_0p167_0p221"],"t":49.822,"s":[17],"e":[-23]},{"i":{"x":[0.833],"y":[0.917]},"o":{"x":[0.36],"y":[0]},"n":["0p833_0p917_0p36_0"],"t":59.111,"s":[-23],"e":[0]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.28]},"n":["0p42_1_0p167_0p28"],"t":60.8,"s":[0],"e":[17]},{"i":{"x":[0.833],"y":[0.779]},"o":{"x":[0.167],"y":[0.221]},"n":["0p833_0p779_0p167_0p221"],"t":65.022,"s":[17],"e":[-23]},{"i":{"x":[0.833],"y":[0.917]},"o":{"x":[0.36],"y":[0]},"n":["0p833_0p917_0p36_0"],"t":74.311,"s":[-23],"e":[0]},{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.28]},"n":["0p42_1_0p167_0p28"],"t":76,"s":[0],"e":[17]},{"i":{"x":[0.833],"y":[0.779]},"o":{"x":[0.167],"y":[0.221]},"n":["0p833_0p779_0p167_0p221"],"t":80.222,"s":[17],"e":[-23]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.36],"y":[0]},"n":["0p833_0p833_0p36_0"],"t":89.511,"s":[-23],"e":[0]},{"t":91.2}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.75,2.75],[0,0],[-2.75,2.75],[0,0],[-2.75,-2.75],[2.75,-2.75],[0,0]],"o":[[0,0],[-2.75,-2.75],[0,0],[2.75,-2.75],[2.75,2.75],[0,0],[-2.75,2.75]],"v":[[-31.045,31.045],[-31.045,31.045],[-31.045,21.045],[21.045,-31.045],[31.045,-31.045],[31.045,-21.045],[-21.045,31.045]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.152999997606,0.2,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[41.478,34.045],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":91.2,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"muzzle top","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0.01},"n":"0p833_1_0p167_0p01","t":0,"s":[1.365,-0.526,0],"e":[107.365,-0.526,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.25,"y":1},"o":{"x":0.167,"y":0.104},"n":"0p25_1_0p167_0p104","t":12,"s":[107.365,-0.526,0],"e":[124.365,-0.526,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.25,"y":1},"o":{"x":0.167,"y":0},"n":"0p25_1_0p167_0","t":32,"s":[124.365,-0.526,0],"e":[81.052,-0.138,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0.016},"n":"0p833_1_0p167_0p016","t":36,"s":[81.052,-0.138,0],"e":[107.365,-0.526,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.48,"y":0.48},"o":{"x":0,"y":0},"n":"0p48_0p48_0_0","t":40.8,"s":[107.365,-0.526,0],"e":[107.365,-0.526,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.48,"y":1},"o":{"x":0.52,"y":0},"n":"0p48_1_0p52_0","t":68,"s":[107.365,-0.526,0],"e":[39.052,-0.138,0],"to":[0,0,0],"ti":[0,0,0]},{"t":74.4}],"ix":2},"a":{"a":0,"k":[-67.077,-188.693,0],"ix":1},"s":{"a":0,"k":[101.719,87.719,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":12,"s":[56.154,114.613],"e":[81.154,114.613]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":32,"s":[81.154,114.613],"e":[56.154,114.613]},{"t":36}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":7,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.152941176471,0.2,0.239215686275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-51.347,-187.696],"ix":2},"a":{"a":0,"k":[28.612,1.172],"ix":1},"s":{"a":0,"k":[84.896,85.078],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":106.4,"st":-91.2,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"cannon tip","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.33,"y":0},"n":"0p833_0p833_0p33_0","t":-4.8,"s":[-71.354,-187.749,0],"e":[-59.36,-187.377,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.67,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p67_1_0p167_0p167","t":-0.8,"s":[-59.36,-187.377,0],"e":[-63.359,-187.305,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.67,"y":0.67},"o":{"x":0.33,"y":0.33},"n":"0p67_0p67_0p33_0p33","t":1.6,"s":[-63.359,-187.305,0],"e":[-63.359,-187.305,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.67,"y":1},"o":{"x":0.33,"y":0},"n":"0p67_1_0p33_0","t":14.4,"s":[-63.359,-187.305,0],"e":[-54.306,-187.474,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.67,"y":1},"o":{"x":0.33,"y":0},"n":"0p67_1_0p33_0","t":32,"s":[-54.306,-187.474,0],"e":[-67.24,-187.253,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.67,"y":1},"o":{"x":0.33,"y":0},"n":"0p67_1_0p33_0","t":36.8,"s":[-67.24,-187.253,0],"e":[-63.359,-187.305,0],"to":[0,0,0],"ti":[0,0,0]},{"t":41.6}],"ix":2},"a":{"a":0,"k":[320.141,-109.805,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[38.281,69.609],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[320.141,-109.805],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":106.4,"st":-91.2,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 11","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75.336,-0.031,0],"ix":2},"a":{"a":0,"k":[-100.117,-188.035,0],"ix":1},"s":{"a":0,"k":[87.719,87.719,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[20.234,77.93],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":5,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.56862745098,0.866666666667,0.776470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-100.117,-188.035],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":10.4,"op":71.2,"st":-91.2,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"circle 4","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[38.329,-2.022,0],"ix":2},"a":{"a":0,"k":[176.195,-111.805,0],"ix":1},"s":{"a":0,"k":[87.719,87.719,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[15.609,15.609],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.56862745098,0.866666666667,0.776470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[176.195,-111.805],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":106.4,"st":-91.2,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"circle 3","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[8.797,-2.022,0],"ix":2},"a":{"a":0,"k":[176.195,-111.805,0],"ix":1},"s":{"a":0,"k":[87.719,87.719,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[15.609,15.609],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.56862745098,0.866666666667,0.776470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[176.195,-111.805],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":106.4,"st":-91.2,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"circle 2","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-20.735,-2.022,0],"ix":2},"a":{"a":0,"k":[176.195,-111.805,0],"ix":1},"s":{"a":0,"k":[87.719,87.719,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[15.609,15.609],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.56862745098,0.866666666667,0.776470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[176.195,-111.805],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":106.4,"st":-91.2,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Main Cannon","parent":10,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.32],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p32_1_0p167_0"],"t":0,"s":[-76.287],"e":[-39.287]},{"i":{"x":[0.32],"y":[1]},"o":{"x":[0.167],"y":[0.227]},"n":["0p32_1_0p167_0p227"],"t":13.6,"s":[-39.287],"e":[7.379]},{"i":{"x":[0.32],"y":[1]},"o":{"x":[0.167],"y":[0.37]},"n":["0p32_1_0p167_0p37"],"t":18.4,"s":[7.379],"e":[4.379]},{"i":{"x":[0.621],"y":[1.105]},"o":{"x":[0.288],"y":[0]},"n":["0p621_1p105_0p288_0"],"t":20,"s":[4.379],"e":[6.847]},{"i":{"x":[0.631],"y":[1]},"o":{"x":[0.299],"y":[0.069]},"n":["0p631_1_0p299_0p069"],"t":24.8,"s":[6.847],"e":[3.379]},{"i":{"x":[0.598],"y":[9.405]},"o":{"x":[0.268],"y":[0]},"n":["0p598_9p405_0p268_0"],"t":30.4,"s":[3.379],"e":[3.178]},{"i":{"x":[0.647],"y":[0.988]},"o":{"x":[0.314],"y":[0.095]},"n":["0p647_0p988_0p314_0p095"],"t":48.8,"s":[3.178],"e":[9.235]},{"i":{"x":[0.644],"y":[1]},"o":{"x":[0.311],"y":[-0.018]},"n":["0p644_1_0p311_-0p018"],"t":56.8,"s":[9.235],"e":[4.379]},{"i":{"x":[0.48],"y":[1]},"o":{"x":[0.52],"y":[0]},"n":["0p48_1_0p52_0"],"t":68,"s":[4.379],"e":[-58.621]},{"t":74.4}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.25,"y":1},"o":{"x":0.167,"y":0.144},"n":"0p25_1_0p167_0p144","t":32.8,"s":[61.277,-85.284,0],"e":[41.255,-85.689,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.25,"y":1},"o":{"x":0.167,"y":0.144},"n":"0p25_1_0p167_0p144","t":36.8,"s":[41.255,-85.689,0],"e":[61.277,-85.284,0],"to":[0,0,0],"ti":[0,0,0]},{"t":42.4}],"ix":2},"a":{"a":0,"k":[-61.324,3.45,0],"ix":1},"s":{"a":0,"k":[69.18,69.18,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-16.8,"s":[{"i":[[0,0],[0,0],[0,-16.108],[0,0],[-16.108,0],[0,0]],"o":[[0,0],[-16.108,0],[0,0],[0,16.108],[0,0],[0,0]],"v":[[40.221,-26.561],[-46.667,-29.167],[-75.833,0],[-75.833,0],[-46.667,29.167],[40.221,31.773]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,-16.108],[0,0],[-16.108,0],[0,0]],"o":[[0,0],[-16.108,0],[0,0],[0,16.108],[0,0],[0,0]],"v":[[75.833,-29.167],[-46.667,-29.167],[-75.833,0],[-75.833,0],[-46.667,29.167],[75.833,29.167]],"c":true}]},{"i":{"x":0.32,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p32_1_0p167_0p167","t":-13.6,"s":[{"i":[[0,0],[0,0],[0,-16.108],[0,0],[-16.108,0],[0,0]],"o":[[0,0],[-16.108,0],[0,0],[0,16.108],[0,0],[0,0]],"v":[[75.833,-29.167],[-46.667,-29.167],[-75.833,0],[-75.833,0],[-46.667,29.167],[75.833,29.167]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,-16.108],[0,0],[-16.108,0],[0,0]],"o":[[0,0],[-16.108,0],[0,0],[0,16.108],[0,0],[0,0]],"v":[[9.87,-28.07],[-46.667,-29.167],[-75.833,0],[-75.833,0],[-46.667,29.167],[9.87,30.263]],"c":true}]},{"i":{"x":0.32,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p32_1_0p167_0p167","t":0,"s":[{"i":[[0,0],[0,0],[0,-16.108],[0,0],[-16.108,0],[0,0]],"o":[[0,0],[-16.108,0],[0,0],[0,16.108],[0,0],[0,0]],"v":[[9.87,-28.07],[-46.667,-29.167],[-75.833,0],[-75.833,0],[-46.667,29.167],[9.87,30.263]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,-16.108],[0,0],[-16.108,0],[0,0]],"o":[[0,0],[-16.108,0],[0,0],[0,16.108],[0,0],[0,0]],"v":[[75.833,-29.167],[-46.667,-29.167],[-75.833,0],[-75.833,0],[-46.667,29.167],[75.833,29.167]],"c":true}]},{"i":{"x":0.48,"y":1},"o":{"x":0.167,"y":0},"n":"0p48_1_0p167_0","t":10.4,"s":[{"i":[[0,0],[0,0],[0,-16.108],[0,0],[-16.108,0],[0,0]],"o":[[0,0],[-16.108,0],[0,0],[0,16.108],[0,0],[0,0]],"v":[[75.833,-29.167],[-46.667,-29.167],[-75.833,0],[-75.833,0],[-46.667,29.167],[75.833,29.167]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,-16.108],[0,0],[-16.108,0],[0,0]],"o":[[0,0],[-16.108,0],[0,0],[0,16.108],[0,0],[0,0]],"v":[[75.833,-29.167],[-46.667,-29.167],[-75.833,0],[-75.833,0],[-46.667,29.167],[75.833,29.167]],"c":true}]},{"i":{"x":0.48,"y":1},"o":{"x":0.52,"y":0},"n":"0p48_1_0p52_0","t":68,"s":[{"i":[[0,0],[0,0],[0,-16.108],[0,0],[-16.108,0],[0,0]],"o":[[0,0],[-16.108,0],[0,0],[0,16.108],[0,0],[0,0]],"v":[[75.833,-29.167],[-46.667,-29.167],[-75.833,0],[-75.833,0],[-46.667,29.167],[75.833,29.167]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,-16.108],[0,0],[-16.108,0],[0,0]],"o":[[0,0],[-16.108,0],[0,0],[0,16.108],[0,0],[0,0]],"v":[[9.87,-28.07],[-46.667,-29.167],[-75.833,0],[-75.833,0],[-46.667,29.167],[9.87,30.263]],"c":true}]},{"t":74.4}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.152941176471,0.2,0.239215686275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":106.4,"st":-91.2,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"tip","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-3.2,"s":[-63.901,-230.501,0],"e":[-63.761,-243.5,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-0.8,"s":[-63.761,-243.5,0],"e":[-63.75,-244.5,0],"to":[0,0,0],"ti":[0,0,0]},{"t":1.6}],"ix":2},"a":{"a":0,"k":[-63.75,-244,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-55.5,-250.5],[-72,-237.5],[-55.5,-238]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":106.4,"st":-91.2,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"sight top 2","parent":7,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.33,"y":0},"n":"0p833_0p833_0p33_0","t":-6.4,"s":[-3.643,-15.564,0],"e":[-2.062,-40.969,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.569,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p569_1_0p167_0p167","t":-1.6,"s":[-2.062,-40.969,0],"e":[-2.174,-7.462,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.66,"y":1},"o":{"x":0.326,"y":0},"n":"0p66_1_0p326_0","t":13.6,"s":[-2.174,-7.462,0],"e":[-2.174,-37.462,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.706,"y":0.706},"o":{"x":0.334,"y":0.334},"n":"0p706_0p706_0p334_0p334","t":16,"s":[-2.174,-37.462,0],"e":[-2.174,-37.462,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.67,"y":1},"o":{"x":0.167,"y":0},"n":"0p67_1_0p167_0","t":32.8,"s":[-2.174,-37.462,0],"e":[-1.941,-21.675,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.67,"y":1},"o":{"x":0.167,"y":0},"n":"0p67_1_0p167_0","t":38.165,"s":[-1.941,-21.675,0],"e":[-2.012,-40.967,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.67,"y":1},"o":{"x":0.167,"y":0},"n":"0p67_1_0p167_0","t":43.53,"s":[-2.012,-40.967,0],"e":[-2.174,-37.462,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.67,"y":0.67},"o":{"x":0.167,"y":0.167},"n":"0p67_0p67_0p167_0p167","t":48,"s":[-2.174,-37.462,0],"e":[-2.174,-37.462,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.67,"y":1},"o":{"x":0.167,"y":0},"n":"0p67_1_0p167_0","t":68,"s":[-2.174,-37.462,0],"e":[-2.174,-4.462,0],"to":[0,0,0],"ti":[0,0,0]},{"t":72}],"ix":2},"a":{"a":0,"k":[170.521,-153.707,0],"ix":1},"s":{"a":0,"k":[55.839,73.652,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[77.043,37.414],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.56862745098,0.866666666667,0.776470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[170.521,-153.707],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":106.4,"st":-91.2,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"swivel","tt":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":2.662,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.32,"y":1},"o":{"x":0.27,"y":0},"n":"0p32_1_0p27_0","t":1.6,"s":[1087.278,777.499,0],"e":[1113.149,531.355,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.332,"y":0.332},"o":{"x":0.173,"y":0.173},"n":"0p332_0p332_0p173_0p173","t":12.8,"s":[1113.149,531.355,0],"e":[1113.149,531.355,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.24,"y":1},"o":{"x":0.325,"y":0},"n":"0p24_1_0p325_0","t":66.4,"s":[1113.149,531.355,0],"e":[1114.638,517.183,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.24,"y":1},"o":{"x":0.43,"y":0},"n":"0p24_1_0p43_0","t":72.8,"s":[1114.638,517.183,0],"e":[1087.278,777.499,0],"to":[0,0,0],"ti":[0,0,0]},{"t":84}],"ix":2},"a":{"a":0,"k":[62.977,-55.023,0],"ix":1},"s":{"a":0,"k":[164.787,164.787,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[62.047,62.047],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.337254901961,0.258823529412,0.427450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.152941176471,0.2,0.239215686275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[62.977,-55.023],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":243.2,"st":-44.8,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Body Main","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p52_1_0p167_0p167"],"t":0,"s":[3],"e":[4]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.48],"y":[0]},"n":["0p52_1_0p48_0"],"t":3.2,"s":[4],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.48],"y":[0]},"n":["0p833_0p833_0p48_0"],"t":11.2,"s":[0],"e":[3]},{"t":14.4}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.52,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p52_1_0p167_0p167","t":0,"s":[970.895,615.112,0],"e":[970.895,597.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.52,"y":1},"o":{"x":0.48,"y":0},"n":"0p52_1_0p48_0","t":4,"s":[970.895,597.112,0],"e":[970.895,645.112,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.48,"y":0},"n":"0p833_0p833_0p48_0","t":12,"s":[970.895,645.112,0],"e":[970.895,615.112,0],"to":[0,0,0],"ti":[0,0,0]},{"t":14.4}],"ix":2},"a":{"a":0,"k":[60,60,0],"ix":1},"s":{"a":0,"k":[75,75,100],"ix":6}},"ao":0,"ip":0,"op":14.4,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"wing 5","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.39],"y":[1]},"o":{"x":[0.79],"y":[0]},"n":["0p39_1_0p79_0"],"t":0,"s":[59],"e":[146]},{"i":{"x":[0.39],"y":[1]},"o":{"x":[0.79],"y":[0]},"n":["0p39_1_0p79_0"],"t":9.6,"s":[146],"e":[59]},{"t":14.4}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.79,"y":0},"n":"0p833_0p833_0p79_0","t":0,"s":[0.267,50.477,0],"e":[-11.733,50.477,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.79,"y":0},"n":"0p833_1_0p79_0","t":9.6,"s":[-11.733,50.477,0],"e":[0.267,50.477,0],"to":[0,0,0],"ti":[0,0,0]},{"t":14.4}],"ix":2},"a":{"a":0,"k":[336.892,14.647,0],"ix":1},"s":{"a":0,"k":[-65,65,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.75,"y":0},"n":"0p833_0p833_0p75_0","t":0,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[0,0]],"o":[[0.645,95.54],[95.692,0],[0,0],[0,0]],"v":[[-173.975,-86.397],[0,86.397],[173.975,-86.397],[3.736,-86.397]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":5.44,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}],"e":[{"i":[[-24.545,-97.308],[-33.816,0],[-8.099,99.396],[30.355,0.919]],"o":[[24.545,97.308],[33.816,0],[0,0],[-30.355,-0.919]],"v":[[9.497,81.606],[126.549,226.875],[186.89,-79.109],[23.772,-83.224]],"c":true}]},{"i":{"x":0.39,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p39_1_0p167_0p167","t":7.253,"s":[{"i":[[-24.545,-97.308],[-33.816,0],[-8.099,99.396],[30.355,0.919]],"o":[[24.545,97.308],[33.816,0],[0,0],[-30.355,-0.919]],"v":[[9.497,81.606],[126.549,226.875],[186.89,-79.109],[23.772,-83.224]],"c":true}],"e":[{"i":[[-32.666,-125.331],[0,0],[-12.173,101.503],[0,0]],"o":[[32.666,125.331],[0,0],[0,0],[0,0]],"v":[[34.21,123.997],[161.316,256.65],[193.949,-75.126],[41.189,-104.236]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.75,"y":0},"n":"0p833_0p833_0p75_0","t":9.6,"s":[{"i":[[-32.666,-125.331],[0,0],[-12.173,101.503],[0,0]],"o":[[32.666,125.331],[0,0],[0,0],[0,0]],"v":[[34.21,123.997],[161.316,256.65],[193.949,-75.126],[41.189,-104.236]],"c":true}],"e":[{"i":[[-21.953,-84.231],[-31.381,0],[-8.392,99.548],[28.169,0.853]],"o":[[22.165,115.562],[31.381,0],[0,0],[-28.169,-0.853]],"v":[[5.328,68.178],[121.151,203.71],[187.398,-78.822],[25.027,-84.737]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":10.934,"s":[{"i":[[-21.953,-84.231],[-31.381,0],[-8.392,99.548],[28.169,0.853]],"o":[[22.165,115.562],[31.381,0],[0,0],[-28.169,-0.853]],"v":[[5.328,68.178],[121.151,203.71],[187.398,-78.822],[25.027,-84.737]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}]},{"i":{"x":0.39,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p39_1_0p167_0p167","t":12.32,"s":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[85.898,2.602]],"o":[[0.645,95.54],[95.692,0],[0,0],[-85.898,-2.602]],"v":[[-173.975,-86.397],[38.84,95.215],[173.975,-86.397],[-8.097,-44.775]],"c":true}],"e":[{"i":[[0,0],[-95.692,0],[-0.645,95.54],[0,0]],"o":[[0.645,95.54],[95.692,0],[0,0],[0,0]],"v":[[-173.975,-86.397],[0,86.397],[173.975,-86.397],[3.736,-86.397]],"c":true}]},{"t":14.4}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.152941176471,0.2,0.239215686275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[174.225,86.647],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":14.4,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Top Beak Outlines","parent":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[116.797,76.583,0],"ix":2},"a":{"a":0,"k":[7.365,40.329,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[19.537,0],[0,0],[0,-19.537],[0,0],[0,0],[0,0]],"o":[[0,0],[-19.537,0],[0,0],[0,0],[0,0],[0,-19.537]],"v":[[114.406,-21.413],[-114.407,-21.413],[-149.782,13.962],[-149.782,21.413],[149.781,21.413],[149.781,13.962]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.337000020345,0.258999992819,0.426999978458,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[150.031,21.663],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":14.4,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Bottom Beak Outlines","parent":5,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[112.476,79.031,0],"ix":2},"a":{"a":0,"k":[10.209,15.628,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-77.12,0],[-0.52,76.997]],"o":[[0.52,76.997],[77.119,0],[0,0]],"v":[[-140.209,-69.629],[0,69.629],[140.209,-69.629]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.152999997606,0.2,0.238999998803,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.569000004787,0.866999966491,0.776000019148,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[150.209,79.629],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":14.4,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Head","parent":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p52_1_0p167_0p167"],"t":0,"s":[3],"e":[5]},{"i":{"x":[0.52],"y":[1]},"o":{"x":[0.48],"y":[0]},"n":["0p52_1_0p48_0"],"t":4,"s":[5],"e":[-6]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.48],"y":[0]},"n":["0p833_0p833_0p48_0"],"t":11.2,"s":[-6],"e":[3]},{"t":14.4}],"ix":10},"p":{"a":0,"k":[16.908,51.505,0],"ix":2},"a":{"a":0,"k":[16.908,51.505,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,5.418],[5.418,0],[0,-5.418],[-5.418,0]],"o":[[0,-5.418],[-5.418,0],[0,5.418],[5.418,0]],"v":[[9.81,0],[0,-9.81],[-9.81,0],[0,9.81]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.152999997606,0.2,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[93.656,43.492],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-34.333],[-34.333,0],[0,34.333],[34.333,0]],"o":[[0,34.333],[34.333,0],[0,-34.333],[-34.333,0]],"v":[[-62.166,0],[0,62.166],[62.166,0],[0,-62.166]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952999997606,0.941000007181,0.922000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[78.067,62.416],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-5.557,0],[0,0]],"o":[[0,0],[-2.85,4.769],[0,0],[0,0]],"v":[[10.193,-21.154],[-8.623,10.328],[-2.48,21.154],[11.473,21.154]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952999997606,0.941000007181,0.922000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[11.723,57.927],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":14.4,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Neck","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[63.25,62.357,0],"ix":2},"a":{"a":0,"k":[75.575,216.838,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-31.721,0],[0,31.721]],"o":[[0,0],[0,0],[0,31.721],[31.721,0],[0,0]],"v":[[57.436,-96.172],[-57.436,-96.172],[-57.436,38.736],[0,96.172],[57.436,38.736]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952999997606,0.941000007181,0.922000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[77.216,158.588],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":14.4,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Front Leg Outlines","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p42_1_0p167_0p167"],"t":0,"s":[2.178],"e":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":3.2,"s":[3],"e":[22.178]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.25],"y":[0]},"n":["0p833_0p833_0p25_0"],"t":12,"s":[22.178],"e":[2.178]},{"t":14.4}],"ix":10},"p":{"a":0,"k":[-99.14,166.91,0],"ix":2},"a":{"a":0,"k":[65.762,6.163,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.577,-6.966],[0,0],[0.694,-2.36],[3.024,0.418],[0,0],[0.975,-2.897],[3.412,2.33],[0.591,1.594],[0,0]],"o":[[0,0],[1.688,2.108],[-0.861,2.928],[0,0],[-3.028,-0.418],[-1.319,3.917],[-1.291,-0.881],[0,0],[-3.103,-8.367]],"v":[[-7.838,-25.886],[22.348,11.824],[23.751,18.958],[16.853,23.219],[14.624,22.911],[7.724,27.182],[-1.725,30.521],[-4.652,26.768],[-21.342,-18.242]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.152999997606,0.2,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[15.31,60.893],"ix":2},"a":{"a":0,"k":[-9.385,-16.997],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p42_1_0p167_0p167"],"t":0,"s":[6],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":2.4,"s":[19],"e":[-25]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.25],"y":[0]},"n":["0p833_0p833_0p25_0"],"t":12,"s":[-25],"e":[6]},{"t":14.4}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.75,2.75],[0,0],[-2.75,2.75],[0,0],[-2.75,-2.75],[2.75,-2.75],[0,0]],"o":[[0,0],[-2.75,-2.75],[0,0],[2.75,-2.75],[2.75,2.75],[0,0],[-2.75,2.75]],"v":[[-31.045,31.045],[-31.045,31.045],[-31.045,21.045],[21.045,-31.045],[31.045,-31.045],[31.045,-21.045],[-21.045,31.045]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.152999997606,0.2,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[41.478,34.045],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":14.4,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Bottom Body Outlines","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-51.067,125.81,0],"ix":2},"a":{"a":0,"k":[174.225,86.647,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-95.692,0],[-0.645,95.54]],"o":[[0.645,95.54],[95.692,0],[0,0]],"v":[[-173.975,-86.397],[0,86.397],[173.975,-86.397]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952999997606,0.941000007181,0.922000002394,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[174.225,86.647],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":14.4,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Back Leg","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p42_1_0p167_0p167"],"t":0,"s":[0.178],"e":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":4.8,"s":[3],"e":[22.178]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.36],"y":[0]},"n":["0p833_0p833_0p36_0"],"t":12.8,"s":[22.178],"e":[0.178]},{"t":14.4}],"ix":10},"p":{"a":0,"k":[-43.14,174.91,0],"ix":2},"a":{"a":0,"k":[65.762,6.163,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.577,-6.966],[0,0],[0.694,-2.36],[3.024,0.418],[0,0],[0.975,-2.897],[3.412,2.33],[0.591,1.594],[0,0]],"o":[[0,0],[1.688,2.108],[-0.861,2.928],[0,0],[-3.028,-0.418],[-1.319,3.917],[-1.291,-0.881],[0,0],[-3.103,-8.367]],"v":[[-7.838,-25.886],[22.348,11.824],[23.751,18.958],[16.853,23.219],[14.624,22.911],[7.724,27.182],[-1.725,30.521],[-4.652,26.768],[-21.342,-18.242]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.152999997606,0.2,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[15.31,60.893],"ix":2},"a":{"a":0,"k":[-9.385,-16.997],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.42],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p42_1_0p167_0p167"],"t":0,"s":[0],"e":[17]},{"i":{"x":[0.833],"y":[0.779]},"o":{"x":[0.167],"y":[0.221]},"n":["0p833_0p779_0p167_0p221"],"t":4,"s":[17],"e":[-23]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.36],"y":[0]},"n":["0p833_0p833_0p36_0"],"t":12.8,"s":[-23],"e":[0]},{"t":14.4}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.75,2.75],[0,0],[-2.75,2.75],[0,0],[-2.75,-2.75],[2.75,-2.75],[0,0]],"o":[[0,0],[-2.75,-2.75],[0,0],[2.75,-2.75],[2.75,2.75],[0,0],[-2.75,2.75]],"v":[[-31.045,31.045],[-31.045,31.045],[-31.045,21.045],[21.045,-31.045],[31.045,-31.045],[31.045,-21.045],[-21.045,31.045]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.152999997606,0.2,0.238999998803,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[41.478,34.045],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":14.4,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Pelican Transition - fast","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[750,750,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[150,150,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":14.4,"op":105.6,"st":14.4,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"Pelican loop","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[750,750,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[150,150,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":14.4,"st":0,"bm":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/personal_character.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/personal_character.json deleted file mode 100644 index a56074e1..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/personal_character.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.14","fr":30,"ip":0,"op":162,"w":900,"h":900,"nm":"Comp 1","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Front Hair","parent":8,"refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.16,"y":0.16},"o":{"x":0.167,"y":0.167},"n":"0p16_0p16_0p167_0p167","t":0,"s":[101.385,187.205,0],"e":[101.385,187.205,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.84,"y":0},"n":"0p15_1_0p84_0","t":6,"s":[101.385,187.205,0],"e":[98.385,187.205,0],"to":[-0.5,0,0],"ti":[0.5,0,0]},{"i":{"x":0.15,"y":0.15},"o":{"x":0.85,"y":0.85},"n":"0p15_0p15_0p85_0p85","t":20,"s":[98.385,187.205,0],"e":[98.385,187.205,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.85,"y":0},"n":"0p833_0p833_0p85_0","t":47,"s":[98.385,187.205,0],"e":[101.385,187.205,0],"to":[0.5,0,0],"ti":[-0.91666668653488,0,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p15_1_0p167_0p167","t":53,"s":[101.385,187.205,0],"e":[103.885,187.205,0],"to":[0.91666668653488,0,0],"ti":[-0.41666665673256,0,0]},{"i":{"x":0.15,"y":0.15},"o":{"x":0.85,"y":0.85},"n":"0p15_0p15_0p85_0p85","t":67,"s":[103.885,187.205,0],"e":[103.885,187.205,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.85,"y":0},"n":"0p833_0p833_0p85_0","t":94,"s":[103.885,187.205,0],"e":[101.385,187.205,0],"to":[-0.41666665673256,0,0],"ti":[0.41666665673256,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":100,"s":[101.385,187.205,0],"e":[101.385,187.205,0],"to":[0,0,0],"ti":[0,0,0]},{"t":114}],"ix":2},"a":{"a":0,"k":[128,239,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":265,"h":166,"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Mouth","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.85],"y":[0]},"n":["0p15_1_0p85_0"],"t":124,"s":[0],"e":[5.203]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.85],"y":[0]},"n":["0p15_1_0p85_0"],"t":136,"s":[5.203],"e":[0]},{"t":148}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.15,"y":1},"o":{"x":0.85,"y":0},"n":"0p15_1_0p85_0","t":124,"s":[19.267,100.511,0],"e":[19.267,98.636,0],"to":[0,-0.3125,0],"ti":[0,0,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.85,"y":0},"n":"0p15_1_0p85_0","t":136,"s":[19.267,98.636,0],"e":[19.267,100.511,0],"to":[0,0,0],"ti":[0,-0.3125,0]},{"t":148}],"ix":2},"a":{"a":0,"k":[42.667,13.167,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-34.167,0],[0,0]],"o":[[0,0],[34.166,0],[0,0]],"v":[[-35.166,-5.667],[1.001,5.667],[35.166,-5.667]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.925,0.455000005984,0.395999983245,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[42.666,13.167],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Nose","parent":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.16],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p16_1_0p167_0"],"t":0,"s":[0],"e":[0]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.84],"y":[0]},"n":["0p15_1_0p84_0"],"t":6,"s":[0],"e":[-4]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.85],"y":[0]},"n":["0p15_1_0p85_0"],"t":20,"s":[-4],"e":[-4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.85],"y":[0]},"n":["0p833_0p833_0p85_0"],"t":47,"s":[-4],"e":[0]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p15_1_0p167_0p167"],"t":53,"s":[0],"e":[4]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p15_1_0p167_0"],"t":67,"s":[4],"e":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":94,"s":[4],"e":[0]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p15_1_0p167_0"],"t":100,"s":[0],"e":[0]},{"t":114}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.16,"y":0.16},"o":{"x":0.167,"y":0.167},"n":"0p16_0p16_0p167_0p167","t":0,"s":[102.885,146.327,0],"e":[102.885,146.327,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.84,"y":0},"n":"0p15_1_0p84_0","t":6,"s":[102.885,146.327,0],"e":[110.885,139.327,0],"to":[1.33333337306976,-1.16666662693024,0],"ti":[-1.33333337306976,1.16666662693024,0]},{"i":{"x":0.15,"y":0.15},"o":{"x":0.85,"y":0.85},"n":"0p15_0p15_0p85_0p85","t":20,"s":[110.885,139.327,0],"e":[110.885,139.327,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.85,"y":0},"n":"0p833_0p833_0p85_0","t":47,"s":[110.885,139.327,0],"e":[102.885,146.327,0],"to":[-1.33333337306976,1.16666662693024,0],"ti":[2.58333325386047,0,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p15_1_0p167_0p167","t":53,"s":[102.885,146.327,0],"e":[95.385,139.327,0],"to":[-2.58333325386047,0,0],"ti":[1.25,1.16666662693024,0]},{"i":{"x":0.15,"y":0.15},"o":{"x":0.167,"y":0.167},"n":"0p15_0p15_0p167_0p167","t":67,"s":[95.385,139.327,0],"e":[95.385,139.327,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":94,"s":[95.385,139.327,0],"e":[102.885,146.327,0],"to":[1.25,1.16666662693024,0],"ti":[-1.25,-1.16666662693024,0]},{"i":{"x":0.15,"y":0.15},"o":{"x":0.167,"y":0.167},"n":"0p15_0p15_0p167_0p167","t":100,"s":[102.885,146.327,0],"e":[102.885,146.327,0],"to":[0,0,0],"ti":[0,0,0]},{"t":114}],"ix":2},"a":{"a":0,"k":[20.266,37.538,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.843,-4.933],[0,0],[0,0],[4.52,8.394],[4.842,4.946],[-2.583,11.623],[-7.426,0],[-2.583,-11.623]],"o":[[-4.843,4.946],[-4.52,8.394],[0,0],[0,0],[-4.843,-4.933],[2.583,-11.623],[7.425,0],[2.583,11.623]],"v":[[14.529,32.213],[7.425,28.895],[0.001,35.351],[-7.425,28.895],[-14.527,32.213],[-17.433,8.232],[0.001,-37.288],[17.434,8.232]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.925,0.455000005984,0.395999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[20.266,37.539],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Eye","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-36.067,12.5,0],"ix":2},"a":{"a":0,"k":[6.333,6.333,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.16,0.16,0.16],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0]},"n":["0p16_1_0p167_0p167","0p16_1_0p167_0p167","0p16_1_0p167_0"],"t":0,"s":[100,100,100],"e":[205,18,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.84,0.84,0.84],"y":[0,0,0]},"n":["0p15_1_0p84_0","0p15_1_0p84_0","0p15_1_0p84_0"],"t":6,"s":[205,18,100],"e":[100,100,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.85,0.85,0.85],"y":[0,0,0]},"n":["0p15_1_0p85_0","0p15_1_0p85_0","0p15_1_0p85_0"],"t":20,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,1]},"o":{"x":[0.85,0.85,0.85],"y":[0,0,0]},"n":["0p833_0p833_0p85_0","0p833_0p833_0p85_0","0p833_1_0p85_0"],"t":30,"s":[100,100,100],"e":[205,18,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0]},"n":["0p15_1_0p167_0p167","0p15_1_0p167_0p167","0p15_1_0p167_0"],"t":36,"s":[205,18,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"n":["0p833_1_0p167_0","0p833_1_0p167_0","0p833_1_0p167_0"],"t":42,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":47,"s":[100,100,100],"e":[205,18,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0]},"n":["0p15_1_0p167_0p167","0p15_1_0p167_0p167","0p15_1_0p167_0"],"t":53,"s":[205,18,100],"e":[100,100,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.85,0.85,0.85],"y":[0,0,0]},"n":["0p15_1_0p85_0","0p15_1_0p85_0","0p15_1_0p85_0"],"t":67,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,1]},"o":{"x":[0.85,0.85,0.85],"y":[0,0,0]},"n":["0p833_0p833_0p85_0","0p833_0p833_0p85_0","0p833_1_0p85_0"],"t":77,"s":[100,100,100],"e":[205,18,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0]},"n":["0p15_1_0p167_0p167","0p15_1_0p167_0p167","0p15_1_0p167_0"],"t":83,"s":[205,18,100],"e":[100,100,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"n":["0p15_1_0p167_0","0p15_1_0p167_0","0p15_1_0p167_0"],"t":89,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,1]},"o":{"x":[0.85,0.85,0.85],"y":[0,0,0]},"n":["0p833_0p833_0p85_0","0p833_0p833_0p85_0","0p833_1_0p85_0"],"t":94,"s":[100,100,100],"e":[205,18,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0]},"n":["0p15_1_0p167_0p167","0p15_1_0p167_0p167","0p15_1_0p167_0"],"t":100,"s":[205,18,100],"e":[100,100,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.85,0.85,0.85],"y":[0,0,0]},"n":["0p15_1_0p85_0","0p15_1_0p85_0","0p15_1_0p85_0"],"t":114,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,1]},"o":{"x":[0.85,0.85,0.85],"y":[0,0,0]},"n":["0p833_0p833_0p85_0","0p833_0p833_0p85_0","0p833_1_0p85_0"],"t":130,"s":[100,100,100],"e":[205,18,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0]},"n":["0p15_1_0p167_0p167","0p15_1_0p167_0p167","0p15_1_0p167_0"],"t":136,"s":[205,18,100],"e":[100,100,100]},{"t":148}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-3.36],[3.359,0],[0,3.359],[-3.36,0]],"o":[[0,3.359],[-3.36,0],[0,-3.36],[3.359,0]],"v":[[6.084,0],[0.001,6.083],[-6.084,0],[0.001,-6.083]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[6.333,6.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Eye","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75.767,12.5,0],"ix":2},"a":{"a":0,"k":[6.333,6.333,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.16,0.16,0.16],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0]},"n":["0p16_1_0p167_0p167","0p16_1_0p167_0p167","0p16_1_0p167_0"],"t":0,"s":[100,100,100],"e":[205,18,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.84,0.84,0.84],"y":[0,0,0]},"n":["0p15_1_0p84_0","0p15_1_0p84_0","0p15_1_0p84_0"],"t":6,"s":[205,18,100],"e":[100,100,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.85,0.85,0.85],"y":[0,0,0]},"n":["0p15_1_0p85_0","0p15_1_0p85_0","0p15_1_0p85_0"],"t":20,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,1]},"o":{"x":[0.85,0.85,0.85],"y":[0,0,0]},"n":["0p833_0p833_0p85_0","0p833_0p833_0p85_0","0p833_1_0p85_0"],"t":30,"s":[100,100,100],"e":[205,18,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0]},"n":["0p15_1_0p167_0p167","0p15_1_0p167_0p167","0p15_1_0p167_0"],"t":36,"s":[205,18,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"n":["0p833_1_0p167_0","0p833_1_0p167_0","0p833_1_0p167_0"],"t":42,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":47,"s":[100,100,100],"e":[205,18,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0]},"n":["0p15_1_0p167_0p167","0p15_1_0p167_0p167","0p15_1_0p167_0"],"t":53,"s":[205,18,100],"e":[100,100,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.85,0.85,0.85],"y":[0,0,0]},"n":["0p15_1_0p85_0","0p15_1_0p85_0","0p15_1_0p85_0"],"t":67,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,1]},"o":{"x":[0.85,0.85,0.85],"y":[0,0,0]},"n":["0p833_0p833_0p85_0","0p833_0p833_0p85_0","0p833_1_0p85_0"],"t":77,"s":[100,100,100],"e":[205,18,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0]},"n":["0p15_1_0p167_0p167","0p15_1_0p167_0p167","0p15_1_0p167_0"],"t":83,"s":[205,18,100],"e":[100,100,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"n":["0p15_1_0p167_0","0p15_1_0p167_0","0p15_1_0p167_0"],"t":89,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,1]},"o":{"x":[0.85,0.85,0.85],"y":[0,0,0]},"n":["0p833_0p833_0p85_0","0p833_0p833_0p85_0","0p833_1_0p85_0"],"t":94,"s":[100,100,100],"e":[205,18,100]},{"i":{"x":[0.15,0.15,0.15],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0]},"n":["0p15_1_0p167_0p167","0p15_1_0p167_0p167","0p15_1_0p167_0"],"t":100,"s":[205,18,100],"e":[100,100,100]},{"t":114}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-3.36],[3.359,0],[0,3.359],[-3.359,0]],"o":[[0,3.359],[-3.359,0],[0,-3.36],[3.359,0]],"v":[[6.083,0],[0,6.083],[-6.083,0],[0,-6.083]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[6.333,6.333],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Left Eye Brow","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.16],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p16_1_0p167_0p167"],"t":0,"s":[0],"e":[9.695]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.84],"y":[0]},"n":["0p15_1_0p84_0"],"t":6,"s":[9.695],"e":[-8.041]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.85],"y":[0]},"n":["0p15_1_0p85_0"],"t":20,"s":[-8.041],"e":[-8.041]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.85],"y":[0]},"n":["0p833_1_0p85_0"],"t":30,"s":[-8.041],"e":[-1.024]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p15_1_0p167_0"],"t":36,"s":[-1.024],"e":[-8.041]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":42,"s":[-8.041],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":47,"s":[0],"e":[9.695]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p15_1_0p167_0p167"],"t":53,"s":[9.695],"e":[-8.041]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.85],"y":[0]},"n":["0p15_1_0p85_0"],"t":67,"s":[-8.041],"e":[-8.041]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.85],"y":[0]},"n":["0p833_1_0p85_0"],"t":77,"s":[-8.041],"e":[-1.024]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p15_1_0p167_0"],"t":83,"s":[-1.024],"e":[-8.041]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p15_1_0p167_0"],"t":89,"s":[-8.041],"e":[-8.041]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.85],"y":[0]},"n":["0p833_0p833_0p85_0"],"t":94,"s":[-8.041],"e":[9.695]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p15_1_0p167_0p167"],"t":100,"s":[9.695],"e":[0]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.85],"y":[0]},"n":["0p15_1_0p85_0"],"t":114,"s":[0],"e":[-8.258]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.85],"y":[0]},"n":["0p833_1_0p85_0"],"t":124,"s":[-8.258],"e":[6.314]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p15_1_0p167_0"],"t":136,"s":[6.314],"e":[0]},{"t":148}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.16,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p16_1_0p167_0p167","t":0,"s":[-34.733,-13.416,0],"e":[-34.733,-4.916,0],"to":[0,1.41666662693024,0],"ti":[0,-0.25,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.84,"y":0},"n":"0p15_1_0p84_0","t":6,"s":[-34.733,-4.916,0],"e":[-34.733,-11.916,0],"to":[0,0.25,0],"ti":[0,1.16666662693024,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.85,"y":0.85},"n":"0p833_0p833_0p85_0p85","t":20,"s":[-34.733,-11.916,0],"e":[-34.733,-11.916,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":30,"s":[-34.733,-11.916,0],"e":[-34.746,-8.158,0],"to":[-0.00203262735158,0.62638407945633,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":36,"s":[-34.746,-8.158,0],"e":[-34.733,-11.916,0],"to":[0,0,0],"ti":[-0.00203262735158,0.87638407945633,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[-34.733,-11.916,0],"e":[-34.733,-13.416,0],"to":[0.00203262735158,-0.87638407945633,0],"ti":[0,-1.16666662693024,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":47,"s":[-34.733,-13.416,0],"e":[-34.733,-4.916,0],"to":[0,1.16666662693024,0],"ti":[0,-0.25,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p15_1_0p167_0p167","t":53,"s":[-34.733,-4.916,0],"e":[-34.733,-11.916,0],"to":[0,0.25,0],"ti":[0,1.16666662693024,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.85,"y":0.85},"n":"0p833_0p833_0p85_0p85","t":67,"s":[-34.733,-11.916,0],"e":[-34.733,-11.916,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":77,"s":[-34.733,-11.916,0],"e":[-34.746,-8.158,0],"to":[-0.00203262735158,0.62638407945633,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":83,"s":[-34.746,-8.158,0],"e":[-34.733,-11.916,0],"to":[0,0,0],"ti":[-0.00203262735158,0.62638407945633,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":89,"s":[-34.733,-11.916,0],"e":[-34.733,-11.916,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":94,"s":[-34.733,-11.916,0],"e":[-34.733,-4.916,0],"to":[0,1.16666662693024,0],"ti":[0,0.25,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p15_1_0p167_0p167","t":100,"s":[-34.733,-4.916,0],"e":[-34.733,-13.416,0],"to":[0,-0.25,0],"ti":[0,3.25,0]},{"i":{"x":0.32,"y":1},"o":{"x":0.85,"y":0},"n":"0p32_1_0p85_0","t":114,"s":[-34.733,-13.416,0],"e":[-34.733,-24.416,0],"to":[0,-3.25,0],"ti":[0.00203262735158,-1.70971739292145,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":124,"s":[-34.733,-24.416,0],"e":[-34.746,-3.158,0],"to":[-0.00203262735158,1.70971739292145,0],"ti":[0,-1.83333337306976,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":136,"s":[-34.746,-3.158,0],"e":[-34.733,-13.416,0],"to":[0,1.83333337306976,0],"ti":[-0.00203262735158,1.70971739292145,0]},{"t":148}],"ix":2},"a":{"a":0,"k":[21.083,8.416,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.492,0],[0,0],[0,4.492],[-4.492,0],[0,0],[0,-4.492]],"o":[[0,0],[-4.492,0],[0,-4.492],[0,0],[4.492,0],[0,4.492]],"v":[[12.667,8.166],[-12.667,8.166],[-20.833,-0.001],[-12.667,-8.166],[12.667,-8.166],[20.833,-0.001]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[21.083,8.417],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Right Eye Brow","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.16],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p16_1_0p167_0p167"],"t":0,"s":[0],"e":[-7.24]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.84],"y":[0]},"n":["0p15_1_0p84_0"],"t":6,"s":[-7.24],"e":[5.892]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.85],"y":[0]},"n":["0p15_1_0p85_0"],"t":20,"s":[5.892],"e":[5.892]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.85],"y":[0]},"n":["0p833_1_0p85_0"],"t":30,"s":[5.892],"e":[-0.716]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p15_1_0p167_0"],"t":36,"s":[-0.716],"e":[5.892]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":42,"s":[5.892],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":47,"s":[0],"e":[-7.24]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p15_1_0p167_0p167"],"t":53,"s":[-7.24],"e":[5.892]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.85],"y":[0]},"n":["0p15_1_0p85_0"],"t":67,"s":[5.892],"e":[5.892]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.85],"y":[0]},"n":["0p833_1_0p85_0"],"t":77,"s":[5.892],"e":[-0.716]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p15_1_0p167_0"],"t":83,"s":[-0.716],"e":[5.892]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p15_1_0p167_0"],"t":89,"s":[5.892],"e":[5.892]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.85],"y":[0]},"n":["0p833_0p833_0p85_0"],"t":94,"s":[5.892],"e":[-7.24]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p15_1_0p167_0p167"],"t":100,"s":[-7.24],"e":[0]},{"t":114}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.16,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p16_1_0p167_0p167","t":0,"s":[75.267,-13.416,0],"e":[75.267,-4.916,0],"to":[0,1.41666662693024,0],"ti":[0,-0.08333333581686,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.84,"y":0},"n":"0p15_1_0p84_0","t":6,"s":[75.267,-4.916,0],"e":[75.267,-12.916,0],"to":[0,0.08333333581686,0],"ti":[0,1.33333337306976,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.85,"y":0.85},"n":"0p833_0p833_0p85_0p85","t":20,"s":[75.267,-12.916,0],"e":[75.267,-12.916,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":30,"s":[75.267,-12.916,0],"e":[75.22,-8.659,0],"to":[-0.00784566719085,0.70951437950134,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":36,"s":[75.22,-8.659,0],"e":[75.267,-12.916,0],"to":[0,0,0],"ti":[-0.00784566719085,0.79284769296646,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[75.267,-12.916,0],"e":[75.267,-13.416,0],"to":[0.00784566719085,-0.79284769296646,0],"ti":[0,-1.33333337306976,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":47,"s":[75.267,-13.416,0],"e":[75.267,-4.916,0],"to":[0,1.33333337306976,0],"ti":[0,-0.08333333581686,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p15_1_0p167_0p167","t":53,"s":[75.267,-4.916,0],"e":[75.267,-12.916,0],"to":[0,0.08333333581686,0],"ti":[0,1.33333337306976,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.85,"y":0.85},"n":"0p833_0p833_0p85_0p85","t":67,"s":[75.267,-12.916,0],"e":[75.267,-12.916,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":77,"s":[75.267,-12.916,0],"e":[75.22,-8.659,0],"to":[-0.00784566719085,0.70951437950134,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":83,"s":[75.22,-8.659,0],"e":[75.267,-12.916,0],"to":[0,0,0],"ti":[-0.00784566719085,0.70951437950134,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":89,"s":[75.267,-12.916,0],"e":[75.267,-12.916,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":94,"s":[75.267,-12.916,0],"e":[75.267,-4.916,0],"to":[0,1.33333337306976,0],"ti":[0,0.08333333581686,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p15_1_0p167_0p167","t":100,"s":[75.267,-4.916,0],"e":[75.267,-13.416,0],"to":[0,-0.08333333581686,0],"ti":[0,1.41666662693024,0]},{"t":114}],"ix":2},"a":{"a":0,"k":[21.083,8.416,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.491,0],[0,0],[0,4.492],[-4.491,0],[0,0],[0,-4.492]],"o":[[0,0],[-4.491,0],[0,-4.492],[0,0],[4.491,0],[0,4.492]],"v":[[12.667,8.166],[-12.667,8.166],[-20.833,-0.001],[-12.667,-8.166],[12.667,-8.166],[20.833,-0.001]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[21.083,8.417],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Face","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.16,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p16_1_0p167_0p167","t":0,"s":[452.198,490.045,0],"e":[452.198,496.045,0],"to":[0,1,0],"ti":[0,0,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.84,"y":0},"n":"0p15_1_0p84_0","t":6,"s":[452.198,496.045,0],"e":[452.198,490.045,0],"to":[0,0,0],"ti":[0,1,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.85,"y":0.85},"n":"0p833_0p833_0p85_0p85","t":20,"s":[452.198,490.045,0],"e":[452.198,490.045,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":47,"s":[452.198,490.045,0],"e":[452.198,496.045,0],"to":[0,1,0],"ti":[0,0,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p15_1_0p167_0p167","t":53,"s":[452.198,496.045,0],"e":[452.198,490.045,0],"to":[0,0,0],"ti":[0,1,0]},{"i":{"x":0.15,"y":0.15},"o":{"x":0.167,"y":0.167},"n":"0p15_0p15_0p167_0p167","t":67,"s":[452.198,490.045,0],"e":[452.198,490.045,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":94,"s":[452.198,490.045,0],"e":[452.198,496.045,0],"to":[0,1,0],"ti":[0,0,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p15_1_0p167_0p167","t":100,"s":[452.198,496.045,0],"e":[452.198,490.045,0],"to":[0,0,0],"ti":[0,2.5,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.85,"y":0},"n":"0p15_1_0p85_0","t":114,"s":[452.198,490.045,0],"e":[452.198,481.045,0],"to":[0,-2.5,0],"ti":[0,-1.16666662693024,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.85,"y":0},"n":"0p15_1_0p85_0","t":124,"s":[452.198,481.045,0],"e":[452.198,497.045,0],"to":[0,1.16666662693024,0],"ti":[0,0,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.85,"y":0},"n":"0p15_1_0p85_0","t":136,"s":[452.198,497.045,0],"e":[452.198,481.045,0],"to":[0,0,0],"ti":[0,2.66666674613953,0]},{"t":148}],"ix":2},"a":{"a":0,"k":[103.583,227.25,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[11.192,0],[0,0],[0,-11.193],[0,0],[-55.733,0],[0,55.733],[0,0]],"o":[[0,0],[-11.192,0],[0,0],[0,55.733],[55.733,0],[0,0],[0,-11.193]],"v":[[80.983,-136],[-80.984,-136],[-101.333,-115.65],[-101.333,34.667],[0,136],[101.333,34.667],[101.333,-115.65]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.976000019148,0.855000035903,0.74900004069,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[101.583,136.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"Ear","parent":8,"refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.16],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p16_1_0p167_0"],"t":0,"s":[0],"e":[0]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.84],"y":[0]},"n":["0p15_1_0p84_0"],"t":6,"s":[0],"e":[-1.475]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.85],"y":[0]},"n":["0p833_1_0p85_0"],"t":20,"s":[-1.475],"e":[-1.475]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":47,"s":[-1.475],"e":[0]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p15_1_0p167_0p167"],"t":53,"s":[0],"e":[1.095]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p15_1_0p167_0"],"t":67,"s":[1.095],"e":[1.095]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":94,"s":[1.095],"e":[0]},{"i":{"x":[0.15],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p15_1_0p167_0"],"t":100,"s":[0],"e":[0]},{"t":114}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.16,"y":0.16},"o":{"x":0.167,"y":0.167},"n":"0p16_0p16_0p167_0p167","t":0,"s":[101.385,187.205,0],"e":[101.385,187.205,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.84,"y":0},"n":"0p15_1_0p84_0","t":6,"s":[101.385,187.205,0],"e":[97.385,190.205,0],"to":[-0.66666668653488,0.5,0],"ti":[0.66666668653488,-0.5,0]},{"i":{"x":0.15,"y":0.15},"o":{"x":0.85,"y":0.85},"n":"0p15_0p15_0p85_0p85","t":20,"s":[97.385,190.205,0],"e":[97.385,190.205,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.85,"y":0},"n":"0p833_0p833_0p85_0","t":47,"s":[97.385,190.205,0],"e":[101.385,187.205,0],"to":[0.66666668653488,-0.5,0],"ti":[-1.41666662693024,0,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p15_1_0p167_0p167","t":53,"s":[101.385,187.205,0],"e":[105.885,190.205,0],"to":[1.41666662693024,0,0],"ti":[-0.75,-0.5,0]},{"i":{"x":0.15,"y":0.15},"o":{"x":0.167,"y":0.167},"n":"0p15_0p15_0p167_0p167","t":67,"s":[105.885,190.205,0],"e":[105.885,190.205,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":94,"s":[105.885,190.205,0],"e":[101.385,187.205,0],"to":[-0.75,-0.5,0],"ti":[0.75,0.5,0]},{"i":{"x":0.15,"y":0.15},"o":{"x":0.167,"y":0.167},"n":"0p15_0p15_0p167_0p167","t":100,"s":[101.385,187.205,0],"e":[101.385,187.205,0],"to":[0,0,0],"ti":[0,0,0]},{"t":114}],"ix":2},"a":{"a":0,"k":[139,89,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":281,"h":539,"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Jakun","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[450.948,579.25,0],"ix":2},"a":{"a":0,"k":[23.375,18.375,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-21.5,-16.5],[-0.464,16.5],[21.5,-16.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.925,0.455000005984,0.395999983245,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0.75,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[23.375,18.375],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Neck 2","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[450.948,524.25,0],"ix":2},"a":{"a":0,"k":[74.083,116.25,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[8.823,0],[0,0],[0,-8.823],[0,0],[-40.608,0],[0,40.608],[0,0]],"o":[[0,0],[-8.823,0],[0,0],[0,40.608],[40.608,0],[0,0],[0,-8.823]],"v":[[57.79,-116],[-57.792,-116],[-73.833,-99.958],[-73.833,42.167],[-0.001,116],[73.833,42.167],[73.833,-99.958]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.878431379795,0.731532931328,0.602845072746,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[74.084,116.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Shape Layer 1","parent":8,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-9.776,"ix":10},"p":{"a":0,"k":[95.385,220.205,0],"ix":2},"a":{"a":0,"k":[-2,100,0],"ix":1},"s":{"a":0,"k":[116.328,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[148,148],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.686274509804,0.585274849686,0.495194169587,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,100],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Neck","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[450.948,524.25,0],"ix":2},"a":{"a":0,"k":[74.083,116.25,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[8.823,0],[0,0],[0,-8.823],[0,0],[-40.608,0],[0,40.608],[0,0]],"o":[[0,0],[-8.823,0],[0,0],[0,40.608],[40.608,0],[0,0],[0,-8.823]],"v":[[57.79,-116],[-57.792,-116],[-73.833,-99.958],[-73.833,42.167],[-0.001,116],[73.833,42.167],[73.833,-99.958]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.878431379795,0.731532931328,0.602845072746,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[74.084,116.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":0,"nm":"Back Hair","parent":8,"refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.16,"y":0.16},"o":{"x":0.167,"y":0.167},"n":"0p16_0p16_0p167_0p167","t":0,"s":[101.385,187.205,0],"e":[101.385,187.205,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.84,"y":0},"n":"0p15_1_0p84_0","t":6,"s":[101.385,187.205,0],"e":[92.385,190.205,0],"to":[-1.5,0.5,0],"ti":[1.5,-0.5,0]},{"i":{"x":0.15,"y":0.15},"o":{"x":0.85,"y":0.85},"n":"0p15_0p15_0p85_0p85","t":20,"s":[92.385,190.205,0],"e":[92.385,190.205,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.85,"y":0},"n":"0p833_0p833_0p85_0","t":47,"s":[92.385,190.205,0],"e":[101.385,187.205,0],"to":[1.5,-0.5,0],"ti":[-3.16666674613953,0,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p15_1_0p167_0p167","t":53,"s":[101.385,187.205,0],"e":[111.385,190.205,0],"to":[3.16666674613953,0,0],"ti":[-1.66666662693024,-0.5,0]},{"i":{"x":0.15,"y":0.15},"o":{"x":0.85,"y":0.85},"n":"0p15_0p15_0p85_0p85","t":67,"s":[111.385,190.205,0],"e":[111.385,190.205,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.85,"y":0},"n":"0p833_0p833_0p85_0","t":94,"s":[111.385,190.205,0],"e":[101.385,187.205,0],"to":[-1.66666662693024,-0.5,0],"ti":[1.66666662693024,0.5,0]},{"i":{"x":0.15,"y":0.15},"o":{"x":0.167,"y":0.167},"n":"0p15_0p15_0p167_0p167","t":100,"s":[101.385,187.205,0],"e":[101.385,187.205,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.85,"y":0},"n":"0p15_1_0p85_0","t":114,"s":[101.385,187.205,0],"e":[101.385,194.205,0],"to":[0,1.16666662693024,0],"ti":[0,-1.16666662693024,0]},{"i":{"x":0.15,"y":0.15},"o":{"x":0.85,"y":0.85},"n":"0p15_0p15_0p85_0p85","t":124,"s":[101.385,194.205,0],"e":[101.385,194.205,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.85,"y":0},"n":"0p15_1_0p85_0","t":136,"s":[101.385,194.205,0],"e":[101.385,187.205,0],"to":[0,-1.16666662693024,0],"ti":[0,1.16666662693024,0]},{"t":148}],"ix":2},"a":{"a":0,"k":[165,271,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":342,"h":349,"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Rope","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[421.395,712.446,0],"ix":2},"a":{"a":0,"k":[9.25,9.458,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.233,0],[0,0],[0,4.233],[0,0],[-4.234,0],[0,0],[0,-4.233],[0,0]],"o":[[0,0],[-4.234,0],[0,0],[0,-4.233],[0,0],[4.233,0],[0,0],[0,4.233]],"v":[[1.303,52.208],[-1.302,52.208],[-9,44.512],[-9,-44.512],[-1.302,-52.208],[1.303,-52.208],[9,-44.512],[9,44.512]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[9.25,52.458],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Rope","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[479.395,711.946,0],"ix":2},"a":{"a":0,"k":[9.25,8.958,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.233,0],[0,0],[0,4.233],[0,0],[-4.234,0],[0,0],[0,-4.233],[0,0]],"o":[[0,0],[-4.234,0],[0,0],[0,-4.233],[0,0],[4.233,0],[0,0],[0,4.233]],"v":[[1.303,52.208],[-1.302,52.208],[-9,44.512],[-9,-44.512],[-1.302,-52.208],[1.303,-52.208],[9,-44.512],[9,44.512]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[9.25,52.458],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Inshirt Shirt","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[450.395,650.725,0],"ix":2},"a":{"a":0,"k":[69.863,60.025,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[69.613,-59.775],[-0.499,59.775],[-69.613,-59.775]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[69.863,60.025],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Jacket","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[450.197,693.825,0],"ix":2},"a":{"a":0,"k":[226.25,151.425,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[226,54.165],[226,151.175],[-226,151.175],[-226,54.165],[-164,-21.175],[-176,-41.175],[-134.67,-151.175],[134.67,-151.175],[176,-41.175],[164,-21.175]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[226.25,151.425],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Layer 3 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[233.642,107.465,0],"ix":2},"a":{"a":0,"k":[31.489,31.489,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-17.253],[17.253,0],[0,17.252],[-17.253,0]],"o":[[0,17.252],[-17.253,0],[0,-17.253],[17.253,0]],"v":[[31.239,0],[0,31.239],[-31.239,0],[0,-31.239]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[31.489,31.489],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Layer 4 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[93.334,36.893,0],"ix":2},"a":{"a":0,"k":[37.143,37.143,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-20.375],[20.375,0],[0,20.375],[-20.376,0]],"o":[[0,20.375],[-20.376,0],[0,-20.375],[20.375,0]],"v":[[36.893,0],[0,36.893],[-36.893,0],[0,-36.893]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[37.143,37.143],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Layer 5 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[41.962,64.692,0],"ix":2},"a":{"a":0,"k":[37.143,37.143,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-20.375],[20.375,0],[0,20.375],[-20.376,0]],"o":[[0,20.375],[-20.376,0],[0,-20.375],[20.375,0]],"v":[[36.893,0],[0,36.893],[-36.893,0],[0,-36.893]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[37.143,37.143],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Layer 6 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[133.774,35.547,0],"ix":2},"a":{"a":0,"k":[27.036,27.036,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-14.793],[14.794,0],[0,14.793],[-14.794,0]],"o":[[0,14.793],[-14.794,0],[0,-14.793],[14.794,0]],"v":[[26.786,0],[0,26.786],[-26.786,0],[0,-26.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.036,27.036],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Layer 7 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[222.916,62.334,0],"ix":2},"a":{"a":0,"k":[27.035,27.036,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-14.793],[14.794,0],[0,14.793],[-14.793,0]],"o":[[0,14.793],[-14.793,0],[0,-14.793],[14.794,0]],"v":[[26.786,0],[0,26.786],[-26.786,0],[0,-26.786]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.035,27.036],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Layer 8 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[170.636,47,0],"ix":2},"a":{"a":0,"k":[32.018,32.017,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-17.544],[17.545,0],[0,17.544],[-17.545,0]],"o":[[0,17.544],[-17.545,0],[0,-17.544],[17.545,0]],"v":[[31.768,0],[-0.001,31.767],[-31.768,0],[-0.001,-31.767]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[32.018,32.017],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Layer 9 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[232.333,148.072,0],"ix":2},"a":{"a":0,"k":[17.618,17.618,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-9.592],[9.593,0],[0,9.592],[-9.592,0]],"o":[[0,9.592],[-9.592,0],[0,-9.592],[9.593,0]],"v":[[17.368,0],[0,17.368],[-17.368,0],[0,-17.368]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[17.618,17.618],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Layer 10 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[24.499,112.956,0],"ix":2},"a":{"a":0,"k":[24.522,24.522,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-13.405],[13.405,0],[0,13.405],[-13.406,0]],"o":[[0,13.405],[-13.406,0],[0,-13.405],[13.405,0]],"v":[[24.273,0],[0.001,24.272],[-24.273,0],[0.001,-24.272]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[24.523,24.522],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Layer 11 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[23.094,141.428,0],"ix":2},"a":{"a":0,"k":[19.118,19.118,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-10.42],[10.421,0],[0,10.42],[-10.421,0]],"o":[[0,10.42],[-10.421,0],[0,-10.42],[10.421,0]],"v":[[18.868,0],[0,18.868],[-18.868,0],[0,-18.868]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[19.118,19.118],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"EarPhone","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[139.395,284.625,0],"ix":2},"a":{"a":0,"k":[119.538,256.875,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[4.049,-6.086],[0,0],[0,0]],"o":[[0,0],[0,7.31],[0,0],[0,0],[0,0]],"v":[[57.966,-236.685],[57.966,-223.667],[51.756,-203.125],[-57.966,-38.23],[-57.966,236.686]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[177.583,274.564],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-4.049,-6.086],[0,0],[0,0]],"o":[[0,0],[0,7.31],[0,0],[0,0],[0,0]],"v":[[-57.965,-236.685],[-57.965,-223.667],[-51.757,-203.125],[57.965,-38.23],[57.965,236.686]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[61.653,274.564],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-6.548],[-6.547,0],[0,6.547],[6.548,0]],"o":[[0,6.547],[6.548,0],[0,-6.548],[-6.547,0]],"v":[[-11.855,0],[-0.001,11.855],[11.855,0],[-0.001,-11.855]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[12.708,12.105],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.89,0],[0,0],[0,-1.891],[0,0],[-1.89,0],[0,1.89],[0,0]],"o":[[0,0],[-1.89,0],[0,0],[0,1.89],[1.89,0],[0,0],[0,-1.891]],"v":[[0,-14.777],[0,-14.777],[-3.437,-11.34],[-3.437,11.34],[0,14.777],[3.437,11.34],[3.437,-11.34]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[3.687,25.852],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-6.548],[6.547,0],[0,6.547],[-6.548,0]],"o":[[0,6.547],[-6.548,0],[0,-6.548],[6.547,0]],"v":[[11.856,0],[0,11.855],[-11.856,0],[0,-11.855]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[226.369,12.105],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.89,0],[0,0],[0,-1.891],[0,0],[1.891,0],[0,1.89],[0,0]],"o":[[0,0],[1.891,0],[0,0],[0,1.89],[-1.89,0],[0,0],[0,-1.891]],"v":[[0,-14.777],[0,-14.777],[3.437,-11.34],[3.437,11.34],[0,14.777],[-3.437,11.34],[-3.437,-11.34]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[235.389,25.852],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Left Ear","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[22.943,37.833,0],"ix":2},"a":{"a":0,"k":[30.75,43.75,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[21,14.5],[12.666,-14.666],[-14.667,-9.333],[-0.666,7]],"o":[[0,0],[-12.667,14.667],[14.666,9.334],[0.667,-7]],"v":[[9.5,-34.667],[-17.833,-28.834],[2.167,34.166],[29.833,34.166]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952999997606,0.635000011968,0.603999956916,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[30.75,43.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Right Ear","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[258.058,37.833,0],"ix":2},"a":{"a":0,"k":[30.75,43.75,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-21,14.5],[-12.667,-14.666],[14.667,-9.333],[0.667,7]],"o":[[0,0],[12.667,14.667],[-14.667,9.334],[-0.666,-7]],"v":[[-9.5,-34.667],[17.833,-28.834],[-2.167,34.166],[-29.834,34.166]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952999997606,0.635000011968,0.603999956916,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[30.75,43.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0}]},{"id":"comp_3","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Layer 19 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[266.333,98.881,0],"ix":2},"a":{"a":0,"k":[49.69,49.69,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-27.305],[27.305,0],[0,27.305],[-27.305,0]],"o":[[0,27.305],[-27.305,0],[0,-27.305],[27.305,0]],"v":[[49.441,0],[0.001,49.44],[-49.441,0],[0.001,-49.44]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[49.69,49.69],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Layer 21 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[126.214,49.44,0],"ix":2},"a":{"a":0,"k":[49.69,49.69,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-27.305],[27.305,0],[0,27.305],[-27.306,0]],"o":[[0,27.305],[-27.306,0],[0,-27.305],[27.305,0]],"v":[[49.441,0],[0.001,49.44],[-49.441,0],[0.001,-49.44]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[49.69,49.69],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Layer 24 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[56.522,90.44,0],"ix":2},"a":{"a":0,"k":[49.69,49.69,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-27.305],[27.305,0],[0,27.305],[-27.305,0]],"o":[[0,27.305],[-27.305,0],[0,-27.305],[27.305,0]],"v":[[49.44,0],[0,49.44],[-49.44,0],[0,-49.44]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[49.69,49.69],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Layer 25 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[291.773,208.44,0],"ix":2},"a":{"a":0,"k":[49.69,49.69,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-27.305],[27.305,0],[0,27.305],[-27.305,0]],"o":[[0,27.305],[-27.305,0],[0,-27.305],[27.305,0]],"v":[[49.441,0],[0.001,49.44],[-49.441,0],[0.001,-49.44]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[49.691,49.69],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Layer 26 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[49.774,208.44,0],"ix":2},"a":{"a":0,"k":[49.69,49.69,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-27.305],[27.305,0],[0,27.305],[-27.305,0]],"o":[[0,27.305],[-27.305,0],[0,-27.305],[27.305,0]],"v":[[49.44,0],[0,49.44],[-49.44,0],[0,-49.44]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[49.69,49.69],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Layer 27 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[206.785,54.893,0],"ix":2},"a":{"a":0,"k":[35.798,35.797,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-19.632],[19.632,0],[0,19.632],[-19.633,0]],"o":[[0,19.632],[-19.633,0],[0,-19.632],[19.632,0]],"v":[[35.548,0],[0,35.547],[-35.548,0],[0,-35.547]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[35.798,35.797],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Layer 28 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200.666,67.547,0],"ix":2},"a":{"a":0,"k":[35.798,35.797,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-19.632],[19.632,0],[0,19.632],[-19.633,0]],"o":[[0,19.632],[-19.633,0],[0,-19.632],[19.632,0]],"v":[[35.548,0],[0,35.547],[-35.548,0],[0,-35.547]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[35.798,35.797],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Layer 29 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[266.333,280.547,0],"ix":2},"a":{"a":0,"k":[35.798,35.798,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-19.632],[19.633,0],[0,19.633],[-19.632,0]],"o":[[0,19.633],[-19.632,0],[0,-19.632],[19.633,0]],"v":[[35.548,-0.001],[-0.001,35.548],[-35.548,-0.001],[-0.001,-35.548]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[35.798,35.798],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Layer 30 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[52.891,276.547,0],"ix":2},"a":{"a":0,"k":[35.798,35.798,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-19.632],[19.632,0],[0,19.633],[-19.633,0]],"o":[[0,19.633],[-19.633,0],[0,-19.632],[19.632,0]],"v":[[35.548,-0.001],[0,35.548],[-35.548,-0.001],[0,-35.548]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[35.797,35.798],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Layer 31 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[72.214,49.44,0],"ix":2},"a":{"a":0,"k":[27.25,27.25,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-14.912],[14.912,0],[0,14.912],[-14.912,0]],"o":[[0,14.912],[-14.912,0],[0,-14.912],[14.912,0]],"v":[[27,0],[0,27],[-27,0],[0,-27]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.25,27.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Layer 32 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[289.518,155.529,0],"ix":2},"a":{"a":0,"k":[35.731,35.731,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-19.596],[19.595,0],[0,19.596],[-19.596,0]],"o":[[0,19.596],[-19.596,0],[0,-19.596],[19.595,0]],"v":[[35.482,0],[0,35.481],[-35.482,0],[0,-35.481]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[35.731,35.731],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Layer 33 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[41.928,155.529,0],"ix":2},"a":{"a":0,"k":[35.096,35.096,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-19.245],[19.245,0],[0,19.245],[-19.244,0]],"o":[[0,19.245],[-19.244,0],[0,-19.245],[19.245,0]],"v":[[34.846,0],[-0.001,34.846],[-34.846,0],[-0.001,-34.846]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[35.096,35.096],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Layer 34 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[175.654,32,0],"ix":2},"a":{"a":0,"k":[27.25,27.25,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-14.912],[14.912,0],[0,14.912],[-14.912,0]],"o":[[0,14.912],[-14.912,0],[0,-14.912],[14.912,0]],"v":[[27,0],[0,27],[-27,0],[0,-27]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.25,27.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Layer 36 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[249.576,53.315,0],"ix":2},"a":{"a":0,"k":[37.376,37.376,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-20.504],[20.504,0],[0,20.504],[-20.504,0]],"o":[[0,20.504],[-20.504,0],[0,-20.504],[20.504,0]],"v":[[37.126,-0.001],[0.001,37.126],[-37.126,-0.001],[0.001,-37.126]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[37.375,37.376],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Layer 42 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[78.962,320.095,0],"ix":2},"a":{"a":0,"k":[27.25,27.25,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-14.912],[14.912,0],[0,14.911],[-14.912,0]],"o":[[0,14.911],[-14.912,0],[0,-14.912],[14.912,0]],"v":[[27,0],[0,27],[-27,0],[0,-27]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.25,27.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Layer 43 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[242.333,321.364,0],"ix":2},"a":{"a":0,"k":[27.25,27.25,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-14.911],[14.912,0],[0,14.912],[-14.911,0]],"o":[[0,14.912],[-14.911,0],[0,-14.911],[14.912,0]],"v":[[27,0],[0,27],[-27,0],[0,-27]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.176000004189,0.204000001795,0.270999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.25,27.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":320,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[450,450,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[900,900],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.686274509804,0.585274849686,0.495194169587,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"ME","tt":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[450,450,0],"ix":2},"a":{"a":0,"k":[450,450,0],"ix":1},"s":{"a":0,"k":[123.111,123.111,100],"ix":6}},"ao":0,"w":900,"h":900,"ip":0,"op":162,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[450,450,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[900,900],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":162,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/polystar_anim.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/polystar_anim.json deleted file mode 100644 index 1c8dfbdf..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/polystar_anim.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.17","fr":29.9700012207031,"ip":0,"op":150.000006109625,"w":300,"h":300,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[152,152,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"sr","sy":1,"d":2,"pt":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[5],"e":[11]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":90,"s":[11],"e":[15]},{"t":146.000005946702}],"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[64]},{"t":90.0000036657751}],"ix":5},"ir":{"a":0,"k":106,"ix":6},"is":{"a":0,"k":231,"ix":8},"or":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[102],"e":[142]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":90,"s":[142],"e":[34]},{"t":146.000005946702}],"ix":7},"os":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[79],"e":[265]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":90,"s":[265],"e":[88]},{"t":146.000005946702}],"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 2","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":150.000006109625,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/polystar_line_clockwise_trim.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/polystar_line_clockwise_trim.json deleted file mode 100644 index 14178b72..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/polystar_line_clockwise_trim.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.17","fr":29.9700012207031,"ip":0,"op":150.000006109625,"w":300,"h":300,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[152,152,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"sr","sy":1,"d":2,"pt":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[5],"e":[11]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":90,"s":[11],"e":[15]},{"t":146.000005946702}],"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[64]},{"t":90.0000036657751}],"ix":5},"ir":{"a":0,"k":106,"ix":6},"is":{"a":0,"k":0,"ix":8},"or":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[102],"e":[142]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":90,"s":[142],"e":[34]},{"t":146.000005946702}],"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 2","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[3],"e":[100]},{"t":149.000006068894}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":150.000006109625,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/pumped_up.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/pumped_up.json deleted file mode 100644 index 81a32653..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/pumped_up.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.2.1","fr":29.9700012207031,"ip":0,"op":37.0000015070409,"w":1000,"h":1000,"nm":"Weight Lifter","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"BODY CONTROL","hd":true,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.206,"y":0},"n":"0p833_0p833_0p206_0","t":0,"s":[-178.625,485.375,0],"e":[-94.353,536.037,0],"to":[0,0.30916449427605,0],"ti":[-36.4811401367188,18.4873828887939,0]},{"i":{"x":0.618,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p618_1_0p167_0p167","t":4,"s":[-94.353,536.037,0],"e":[-53.625,422.375,0],"to":[22.5184211730957,-11.4115581512451,0],"ti":[0,0,0]},{"i":{"x":0.79,"y":1},"o":{"x":0.167,"y":0},"n":"0p79_1_0p167_0","t":8,"s":[-53.625,422.375,0],"e":[-47.625,464.375,0],"to":[0,0,0],"ti":[5.375,-12.625,0]},{"i":{"x":0.79,"y":1},"o":{"x":0.96,"y":0},"n":"0p79_1_0p96_0","t":14,"s":[-47.625,464.375,0],"e":[-109.625,533.375,0],"to":[-5.375,12.625,0],"ti":[77.375,3.375,0]},{"i":{"x":0.36,"y":1},"o":{"x":0.96,"y":0},"n":"0p36_1_0p96_0","t":24,"s":[-109.625,533.375,0],"e":[-169.625,422.375,0],"to":[-77.375,-3.375,0],"ti":[0,0.5,0]},{"i":{"x":0.36,"y":1},"o":{"x":0.167,"y":0},"n":"0p36_1_0p167_0","t":29,"s":[-169.625,422.375,0],"e":[-178.625,485.375,0],"to":[0,-0.5,0],"ti":[0,-0.5,0]},{"t":34.0000013848484}],"ix":2},"a":{"a":0,"k":[-599.625,40.375,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[96.75,96.75],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":19,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.98431372549,0.498039215686,0.235294117647,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.98431372549,0.498039215686,0.235294117647,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[-599.625,40.375],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":1,"nm":"Face Rig","parent":3,"hd":true,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.224,"y":0},"n":"0p833_0p833_0p224_0","t":0,"s":[-78,-57,0],"e":[-22.954,97.206,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.598,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p598_1_0p167_0p167","t":5,"s":[-22.954,97.206,0],"e":[36,-69,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.5,"y":1},"o":{"x":0.167,"y":0},"n":"0p5_1_0p167_0","t":11,"s":[36,-69,0],"e":[36,-54,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.592,"y":0.413},"o":{"x":0.258,"y":0},"n":"0p592_0p413_0p258_0","t":18,"s":[36,-54,0],"e":[36,-50.936,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.268,"y":0.016},"n":"0p833_0p833_0p268_0p016","t":20.668,"s":[36,-50.936,0],"e":[-5.418,87.869,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.626,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p626_1_0p167_0p167","t":26,"s":[-5.418,87.869,0],"e":[-78,-99,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.626,"y":1},"o":{"x":0.167,"y":0},"n":"0p626_1_0p167_0","t":30,"s":[-78,-99,0],"e":[-78,-57,0],"to":[0,0,0],"ti":[0,0,0]},{"t":35.0000014255792}],"ix":2},"a":{"a":0,"k":[37.5,37.5,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"joystickLimit","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":86,"ix":1}}]},{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":2,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":0,"k":[0.235294118524,0.784313738346,0.721568644047,1],"ix":3}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]}],"sw":75,"sh":75,"sc":"#ffffff","ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Face Rig Origin","hd":true,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-108,272,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[251.383,200],"ix":2,"x":"var $bm_rt;\nvar temp;\ntemp = mul(thisComp.layer('Face Rig')('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001'), 2);\n$bm_rt = [\n temp,\n temp\n];"},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":28,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.294117629528,0.310726553202,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"d":[{"n":"d","nm":"dash","v":{"a":0,"k":14,"ix":1}},{"n":"o","nm":"offset","v":{"a":0,"k":0,"ix":7}}],"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Left foot","parent":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":2,"s":[0],"e":[-36]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":5,"s":[-36],"e":[-9]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":8,"s":[-9],"e":[-9]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":21,"s":[-9],"e":[0]},{"t":25.0000010182709}],"ix":10},"p":{"a":0,"k":[4.453,6.875,0],"ix":2},"a":{"a":0,"k":[148.453,332.875,0],"ix":1},"s":{"a":0,"k":[100,132.877,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[86.906,18.25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":142,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.219607843137,0.227873439415,0.678431372549,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.568626972273,0.866666965859,0.776471007104,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[121.453,332.875],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Right foot","parent":17,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[21],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":3,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":28,"s":[0],"e":[45]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":31,"s":[45],"e":[12]},{"t":35.0000014255792}],"ix":10},"p":{"a":0,"k":[-12.547,6.875,0],"ix":2},"a":{"a":0,"k":[88.453,332.875,0],"ix":1},"s":{"a":0,"k":[100,132.877,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[86.906,18.25],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":136,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.219607843137,0.227873439415,0.678431372549,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.568626972273,0.866666965859,0.776471007104,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[121.453,332.875],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Head","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-47.758,-107.962,0],"ix":2},"a":{"a":0,"k":[42.637,-115.363,0],"ix":1},"s":{"a":0,"k":[125,125,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[7.869,15.146],"ix":2,"x":"var $bm_rt;\n$bm_rt = joystick(value);\nfunction joystick(inputResult) {\n var slideR, slideL, slideU, slideD;\n var easeOverride_right = null;\n var easeOverride_left = null;\n var easeOverride_up = null;\n var easeOverride_down = null;\n var contrl = thisComp.layer('Face Rig');\n var myLimit = contrl('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001');\n var contrlCurVal = contrl('ADBE Transform Group')('ADBE Position');\n var resultVal;\n var key1 = [\n 7.869140625,\n 15.146484375\n ];\n var key2 = [\n 7.869140625,\n 15.146484375\n ];\n var key3 = [\n 7.869140625,\n 15.146484375\n ];\n var key4 = [\n 7.869140625,\n 15.146484375\n ];\n var key5 = [\n 7.869140625,\n 15.146484375\n ];\n key1 = unArray(key1);\n key2 = unArray(key2);\n key3 = unArray(key3);\n key4 = unArray(key4);\n key5 = unArray(key5);\n try {\n if (!thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB').active) {\n throw 'inactive';\n }\n slideR = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0001');\n slideL = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0002');\n slideU = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0003');\n slideD = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0004');\n } catch (err) {\n slideR = 0;\n slideL = 0;\n slideU = 0;\n slideD = 0;\n }\n if (easeOverride_right !== null && !isNaN(easeOverride_right)) {\n slideR = moClamp(easeOverride_right, -100, 100);\n }\n if (easeOverride_left !== null && !isNaN(easeOverride_left)) {\n slideL = moClamp(easeOverride_left, -100, 100);\n }\n if (easeOverride_up !== null && !isNaN(easeOverride_up)) {\n slideU = moClamp(easeOverride_up, -100, 100);\n }\n if (easeOverride_down !== null && !isNaN(easeOverride_down)) {\n slideD = moClamp(easeOverride_down, -100, 100);\n }\n var easeResultX, easeResultY;\n if (contrlCurVal[0] >= 0) {\n resultVal = linear(contrlCurVal[0], 0, myLimit, key1, key2);\n if (slideR !== 0) {\n easeResultX = easeSwitch(contrlCurVal[0], 0, myLimit, key1, key2, slideR);\n resultVal = linear(Math.abs(slideR), 0, 100, resultVal, easeResultX);\n }\n } else {\n resultVal = linear($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3);\n if (slideL !== 0) {\n easeResultX = easeSwitch($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3, slideL);\n resultVal = linear(Math.abs(slideL), 0, 100, resultVal, easeResultX);\n }\n }\n var resultAdd = 0;\n if (contrlCurVal[1] <= 0) {\n resultAdd = sub(linear($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4), key1);\n if (slideU !== 0) {\n easeResultY = sub(easeSwitch($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4, slideU), key1);\n resultAdd = linear(Math.abs(slideU), 0, 100, resultAdd, easeResultY);\n }\n } else {\n resultAdd = sub(linear(contrlCurVal[1], 0, myLimit, key1, key5), key1);\n if (slideD !== 0) {\n easeResultY = sub(easeSwitch(contrlCurVal[1], 0, myLimit, key1, key5, slideD), key1);\n resultAdd = linear(Math.abs(slideD), 0, 100, resultAdd, easeResultY);\n }\n }\n return sum(sum(resultVal, resultAdd), sub(inputResult, key1));\n}\nfunction cosEase(val, min1, max1, input1, input2) {\n var myCos = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n myCos.push(getMeCos(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n myCos = getMeCos(val, min1, max1, input1, input2);\n }\n return myCos;\n function getMeCos(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var myCos2 = sum(sum(mul($bm_neg(c), Math.cos(mul(mapVal, div(Math.PI, 2)))), c), input1);\n return myCos2;\n }\n}\nfunction sinEase(val, min1, max1, input1, input2) {\n var mySin = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n mySin.push(getMeSin(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n mySin = getMeSin(val, min1, max1, input1, input2);\n }\n return mySin;\n function getMeSin(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var mySin2 = sum(mul(c, Math.sin(mul(mapVal, div(Math.PI, 2)))), input1);\n return mySin2;\n }\n}\nfunction easeSwitch(val, min1, max1, input1, input2, morph) {\n if (morph < 0) {\n return cosEase(val, min1, max1, input1, input2);\n } else {\n return sinEase(val, min1, max1, input1, input2);\n }\n}\nfunction unArray(inKey) {\n if (inKey instanceof Array && inKey.length === 1) {\n return inKey[0];\n } else {\n return inKey;\n }\n}\nfunction moClamp(a, b, c) {\n if (!(a instanceof Array)) {\n return Math.max(b, Math.min(c, a));\n } else {\n var aryHold = [];\n for (var x = 0; x < a.length; x++) {\n aryHold.push(Math.max(b, Math.min(c, a[x])));\n }\n return aryHold;\n }\n}"},"p":{"a":0,"k":[0,34],"ix":3,"x":"var $bm_rt;\n$bm_rt = joystick(value);\nfunction joystick(inputResult) {\n var slideR, slideL, slideU, slideD;\n var easeOverride_right = null;\n var easeOverride_left = null;\n var easeOverride_up = null;\n var easeOverride_down = null;\n var contrl = thisComp.layer('Face Rig');\n var myLimit = contrl('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001');\n var contrlCurVal = contrl('ADBE Transform Group')('ADBE Position');\n var resultVal;\n var key1 = [\n 0,\n 34\n ];\n var key2 = [\n 0,\n 34\n ];\n var key3 = [\n 0,\n 34\n ];\n var key4 = [\n 0,\n 8\n ];\n var key5 = [\n 0,\n 8\n ];\n key1 = unArray(key1);\n key2 = unArray(key2);\n key3 = unArray(key3);\n key4 = unArray(key4);\n key5 = unArray(key5);\n try {\n if (!thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB').active) {\n throw 'inactive';\n }\n slideR = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0001');\n slideL = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0002');\n slideU = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0003');\n slideD = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0004');\n } catch (err) {\n slideR = 0;\n slideL = 0;\n slideU = 0;\n slideD = 0;\n }\n if (easeOverride_right !== null && !isNaN(easeOverride_right)) {\n slideR = moClamp(easeOverride_right, -100, 100);\n }\n if (easeOverride_left !== null && !isNaN(easeOverride_left)) {\n slideL = moClamp(easeOverride_left, -100, 100);\n }\n if (easeOverride_up !== null && !isNaN(easeOverride_up)) {\n slideU = moClamp(easeOverride_up, -100, 100);\n }\n if (easeOverride_down !== null && !isNaN(easeOverride_down)) {\n slideD = moClamp(easeOverride_down, -100, 100);\n }\n var easeResultX, easeResultY;\n if (contrlCurVal[0] >= 0) {\n resultVal = linear(contrlCurVal[0], 0, myLimit, key1, key2);\n if (slideR !== 0) {\n easeResultX = easeSwitch(contrlCurVal[0], 0, myLimit, key1, key2, slideR);\n resultVal = linear(Math.abs(slideR), 0, 100, resultVal, easeResultX);\n }\n } else {\n resultVal = linear($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3);\n if (slideL !== 0) {\n easeResultX = easeSwitch($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3, slideL);\n resultVal = linear(Math.abs(slideL), 0, 100, resultVal, easeResultX);\n }\n }\n var resultAdd = 0;\n if (contrlCurVal[1] <= 0) {\n resultAdd = sub(linear($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4), key1);\n if (slideU !== 0) {\n easeResultY = sub(easeSwitch($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4, slideU), key1);\n resultAdd = linear(Math.abs(slideU), 0, 100, resultAdd, easeResultY);\n }\n } else {\n resultAdd = sub(linear(contrlCurVal[1], 0, myLimit, key1, key5), key1);\n if (slideD !== 0) {\n easeResultY = sub(easeSwitch(contrlCurVal[1], 0, myLimit, key1, key5, slideD), key1);\n resultAdd = linear(Math.abs(slideD), 0, 100, resultAdd, easeResultY);\n }\n }\n return sum(sum(resultVal, resultAdd), sub(inputResult, key1));\n}\nfunction cosEase(val, min1, max1, input1, input2) {\n var myCos = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n myCos.push(getMeCos(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n myCos = getMeCos(val, min1, max1, input1, input2);\n }\n return myCos;\n function getMeCos(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var myCos2 = sum(sum(mul($bm_neg(c), Math.cos(mul(mapVal, div(Math.PI, 2)))), c), input1);\n return myCos2;\n }\n}\nfunction sinEase(val, min1, max1, input1, input2) {\n var mySin = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n mySin.push(getMeSin(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n mySin = getMeSin(val, min1, max1, input1, input2);\n }\n return mySin;\n function getMeSin(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var mySin2 = sum(mul(c, Math.sin(mul(mapVal, div(Math.PI, 2)))), input1);\n return mySin2;\n }\n}\nfunction easeSwitch(val, min1, max1, input1, input2, morph) {\n if (morph < 0) {\n return cosEase(val, min1, max1, input1, input2);\n } else {\n return sinEase(val, min1, max1, input1, input2);\n }\n}\nfunction unArray(inKey) {\n if (inKey instanceof Array && inKey.length === 1) {\n return inKey[0];\n } else {\n return inKey;\n }\n}\nfunction moClamp(a, b, c) {\n if (!(a instanceof Array)) {\n return Math.max(b, Math.min(c, a));\n } else {\n var aryHold = [];\n for (var x = 0; x < a.length; x++) {\n aryHold.push(Math.max(b, Math.min(c, a[x])));\n }\n return aryHold;\n }\n}"},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509998396,0.141176006841,0.168626987233,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.733333333333,0.380392156863,0.188235294118,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[43.538,-130.608],"ix":2,"x":"var $bm_rt;\n$bm_rt = joystick(value);\nfunction joystick(inputResult) {\n var slideR, slideL, slideU, slideD;\n var easeOverride_right = null;\n var easeOverride_left = null;\n var easeOverride_up = null;\n var easeOverride_down = null;\n var contrl = thisComp.layer('Face Rig');\n var myLimit = contrl('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001');\n var contrlCurVal = contrl('ADBE Transform Group')('ADBE Position');\n var resultVal;\n var key1 = [\n 43.5380859375,\n -130.6083984375\n ];\n var key2 = [\n 63.5380859375,\n -130.6083984375\n ];\n var key3 = [\n 21.5380859375,\n -130.6083984375\n ];\n var key4 = [\n 43.5380859375,\n -146.2333984375\n ];\n var key5 = [\n 43.5380859375,\n -88.7333984375\n ];\n key1 = unArray(key1);\n key2 = unArray(key2);\n key3 = unArray(key3);\n key4 = unArray(key4);\n key5 = unArray(key5);\n try {\n if (!thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB').active) {\n throw 'inactive';\n }\n slideR = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0001');\n slideL = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0002');\n slideU = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0003');\n slideD = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0004');\n } catch (err) {\n slideR = 0;\n slideL = 0;\n slideU = 0;\n slideD = 0;\n }\n if (easeOverride_right !== null && !isNaN(easeOverride_right)) {\n slideR = moClamp(easeOverride_right, -100, 100);\n }\n if (easeOverride_left !== null && !isNaN(easeOverride_left)) {\n slideL = moClamp(easeOverride_left, -100, 100);\n }\n if (easeOverride_up !== null && !isNaN(easeOverride_up)) {\n slideU = moClamp(easeOverride_up, -100, 100);\n }\n if (easeOverride_down !== null && !isNaN(easeOverride_down)) {\n slideD = moClamp(easeOverride_down, -100, 100);\n }\n var easeResultX, easeResultY;\n if (contrlCurVal[0] >= 0) {\n resultVal = linear(contrlCurVal[0], 0, myLimit, key1, key2);\n if (slideR !== 0) {\n easeResultX = easeSwitch(contrlCurVal[0], 0, myLimit, key1, key2, slideR);\n resultVal = linear(Math.abs(slideR), 0, 100, resultVal, easeResultX);\n }\n } else {\n resultVal = linear($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3);\n if (slideL !== 0) {\n easeResultX = easeSwitch($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3, slideL);\n resultVal = linear(Math.abs(slideL), 0, 100, resultVal, easeResultX);\n }\n }\n var resultAdd = 0;\n if (contrlCurVal[1] <= 0) {\n resultAdd = sub(linear($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4), key1);\n if (slideU !== 0) {\n easeResultY = sub(easeSwitch($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4, slideU), key1);\n resultAdd = linear(Math.abs(slideU), 0, 100, resultAdd, easeResultY);\n }\n } else {\n resultAdd = sub(linear(contrlCurVal[1], 0, myLimit, key1, key5), key1);\n if (slideD !== 0) {\n easeResultY = sub(easeSwitch(contrlCurVal[1], 0, myLimit, key1, key5, slideD), key1);\n resultAdd = linear(Math.abs(slideD), 0, 100, resultAdd, easeResultY);\n }\n }\n return sum(sum(resultVal, resultAdd), sub(inputResult, key1));\n}\nfunction cosEase(val, min1, max1, input1, input2) {\n var myCos = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n myCos.push(getMeCos(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n myCos = getMeCos(val, min1, max1, input1, input2);\n }\n return myCos;\n function getMeCos(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var myCos2 = sum(sum(mul($bm_neg(c), Math.cos(mul(mapVal, div(Math.PI, 2)))), c), input1);\n return myCos2;\n }\n}\nfunction sinEase(val, min1, max1, input1, input2) {\n var mySin = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n mySin.push(getMeSin(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n mySin = getMeSin(val, min1, max1, input1, input2);\n }\n return mySin;\n function getMeSin(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var mySin2 = sum(mul(c, Math.sin(mul(mapVal, div(Math.PI, 2)))), input1);\n return mySin2;\n }\n}\nfunction easeSwitch(val, min1, max1, input1, input2, morph) {\n if (morph < 0) {\n return cosEase(val, min1, max1, input1, input2);\n } else {\n return sinEase(val, min1, max1, input1, input2);\n }\n}\nfunction unArray(inKey) {\n if (inKey instanceof Array && inKey.length === 1) {\n return inKey[0];\n } else {\n return inKey;\n }\n}\nfunction moClamp(a, b, c) {\n if (!(a instanceof Array)) {\n return Math.max(b, Math.min(c, a));\n } else {\n var aryHold = [];\n for (var x = 0; x < a.length; x++) {\n aryHold.push(Math.max(b, Math.min(c, a[x])));\n }\n return aryHold;\n }\n}"},"a":{"a":0,"k":[0.217,8.715],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"nose","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[14.25,-0.25],[0,0],[0,0]],"o":[[-14.25,0.25],[0,0],[0,0]],"v":[[73.637,-102.75],[55.137,-93.75],[93.637,-93.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509998396,0.141176006841,0.168626987233,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.98431372549,0.498039215686,0.235294117647,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[14,-92.5],"ix":2,"x":"var $bm_rt;\n$bm_rt = joystick(value);\nfunction joystick(inputResult) {\n var slideR, slideL, slideU, slideD;\n var easeOverride_right = null;\n var easeOverride_left = null;\n var easeOverride_up = null;\n var easeOverride_down = null;\n var contrl = thisComp.layer('Face Rig');\n var myLimit = contrl('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001');\n var contrlCurVal = contrl('ADBE Transform Group')('ADBE Position');\n var resultVal;\n var key1 = [\n 14,\n -92.5\n ];\n var key2 = [\n 34,\n -92.5\n ];\n var key3 = [\n -3,\n -92.5\n ];\n var key4 = [\n 12.15234375,\n -126.50390625\n ];\n var key5 = [\n 12.15234375,\n -82.75390625\n ];\n key1 = unArray(key1);\n key2 = unArray(key2);\n key3 = unArray(key3);\n key4 = unArray(key4);\n key5 = unArray(key5);\n try {\n if (!thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB').active) {\n throw 'inactive';\n }\n slideR = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0001');\n slideL = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0002');\n slideU = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0003');\n slideD = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0004');\n } catch (err) {\n slideR = 0;\n slideL = 0;\n slideU = 0;\n slideD = 0;\n }\n if (easeOverride_right !== null && !isNaN(easeOverride_right)) {\n slideR = moClamp(easeOverride_right, -100, 100);\n }\n if (easeOverride_left !== null && !isNaN(easeOverride_left)) {\n slideL = moClamp(easeOverride_left, -100, 100);\n }\n if (easeOverride_up !== null && !isNaN(easeOverride_up)) {\n slideU = moClamp(easeOverride_up, -100, 100);\n }\n if (easeOverride_down !== null && !isNaN(easeOverride_down)) {\n slideD = moClamp(easeOverride_down, -100, 100);\n }\n var easeResultX, easeResultY;\n if (contrlCurVal[0] >= 0) {\n resultVal = linear(contrlCurVal[0], 0, myLimit, key1, key2);\n if (slideR !== 0) {\n easeResultX = easeSwitch(contrlCurVal[0], 0, myLimit, key1, key2, slideR);\n resultVal = linear(Math.abs(slideR), 0, 100, resultVal, easeResultX);\n }\n } else {\n resultVal = linear($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3);\n if (slideL !== 0) {\n easeResultX = easeSwitch($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3, slideL);\n resultVal = linear(Math.abs(slideL), 0, 100, resultVal, easeResultX);\n }\n }\n var resultAdd = 0;\n if (contrlCurVal[1] <= 0) {\n resultAdd = sub(linear($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4), key1);\n if (slideU !== 0) {\n easeResultY = sub(easeSwitch($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4, slideU), key1);\n resultAdd = linear(Math.abs(slideU), 0, 100, resultAdd, easeResultY);\n }\n } else {\n resultAdd = sub(linear(contrlCurVal[1], 0, myLimit, key1, key5), key1);\n if (slideD !== 0) {\n easeResultY = sub(easeSwitch(contrlCurVal[1], 0, myLimit, key1, key5, slideD), key1);\n resultAdd = linear(Math.abs(slideD), 0, 100, resultAdd, easeResultY);\n }\n }\n return sum(sum(resultVal, resultAdd), sub(inputResult, key1));\n}\nfunction cosEase(val, min1, max1, input1, input2) {\n var myCos = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n myCos.push(getMeCos(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n myCos = getMeCos(val, min1, max1, input1, input2);\n }\n return myCos;\n function getMeCos(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var myCos2 = sum(sum(mul($bm_neg(c), Math.cos(mul(mapVal, div(Math.PI, 2)))), c), input1);\n return myCos2;\n }\n}\nfunction sinEase(val, min1, max1, input1, input2) {\n var mySin = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n mySin.push(getMeSin(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n mySin = getMeSin(val, min1, max1, input1, input2);\n }\n return mySin;\n function getMeSin(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var mySin2 = sum(mul(c, Math.sin(mul(mapVal, div(Math.PI, 2)))), input1);\n return mySin2;\n }\n}\nfunction easeSwitch(val, min1, max1, input1, input2, morph) {\n if (morph < 0) {\n return cosEase(val, min1, max1, input1, input2);\n } else {\n return sinEase(val, min1, max1, input1, input2);\n }\n}\nfunction unArray(inKey) {\n if (inKey instanceof Array && inKey.length === 1) {\n return inKey[0];\n } else {\n return inKey;\n }\n}\nfunction moClamp(a, b, c) {\n if (!(a instanceof Array)) {\n return Math.max(b, Math.min(c, a));\n } else {\n var aryHold = [];\n for (var x = 0; x < a.length; x++) {\n aryHold.push(Math.max(b, Math.min(c, a[x])));\n }\n return aryHold;\n }\n}"},"a":{"a":0,"k":[73.152,-93.629],"ix":1},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\n$bm_rt = joystick(value);\nfunction joystick(inputResult) {\n var slideR, slideL, slideU, slideD;\n var easeOverride_right = null;\n var easeOverride_left = null;\n var easeOverride_up = null;\n var easeOverride_down = null;\n var contrl = thisComp.layer('Face Rig');\n var myLimit = contrl('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001');\n var contrlCurVal = contrl('ADBE Transform Group')('ADBE Position');\n var resultVal;\n var key1 = [\n 100,\n 100\n ];\n var key2 = [\n 100,\n 100\n ];\n var key3 = [\n 53,\n 100\n ];\n var key4 = [\n 100,\n 134\n ];\n var key5 = [\n 100,\n 59\n ];\n key1 = unArray(key1);\n key2 = unArray(key2);\n key3 = unArray(key3);\n key4 = unArray(key4);\n key5 = unArray(key5);\n try {\n if (!thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB').active) {\n throw 'inactive';\n }\n slideR = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0001');\n slideL = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0002');\n slideU = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0003');\n slideD = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0004');\n } catch (err) {\n slideR = 0;\n slideL = 0;\n slideU = 0;\n slideD = 0;\n }\n if (easeOverride_right !== null && !isNaN(easeOverride_right)) {\n slideR = moClamp(easeOverride_right, -100, 100);\n }\n if (easeOverride_left !== null && !isNaN(easeOverride_left)) {\n slideL = moClamp(easeOverride_left, -100, 100);\n }\n if (easeOverride_up !== null && !isNaN(easeOverride_up)) {\n slideU = moClamp(easeOverride_up, -100, 100);\n }\n if (easeOverride_down !== null && !isNaN(easeOverride_down)) {\n slideD = moClamp(easeOverride_down, -100, 100);\n }\n var easeResultX, easeResultY;\n if (contrlCurVal[0] >= 0) {\n resultVal = linear(contrlCurVal[0], 0, myLimit, key1, key2);\n if (slideR !== 0) {\n easeResultX = easeSwitch(contrlCurVal[0], 0, myLimit, key1, key2, slideR);\n resultVal = linear(Math.abs(slideR), 0, 100, resultVal, easeResultX);\n }\n } else {\n resultVal = linear($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3);\n if (slideL !== 0) {\n easeResultX = easeSwitch($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3, slideL);\n resultVal = linear(Math.abs(slideL), 0, 100, resultVal, easeResultX);\n }\n }\n var resultAdd = 0;\n if (contrlCurVal[1] <= 0) {\n resultAdd = sub(linear($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4), key1);\n if (slideU !== 0) {\n easeResultY = sub(easeSwitch($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4, slideU), key1);\n resultAdd = linear(Math.abs(slideU), 0, 100, resultAdd, easeResultY);\n }\n } else {\n resultAdd = sub(linear(contrlCurVal[1], 0, myLimit, key1, key5), key1);\n if (slideD !== 0) {\n easeResultY = sub(easeSwitch(contrlCurVal[1], 0, myLimit, key1, key5, slideD), key1);\n resultAdd = linear(Math.abs(slideD), 0, 100, resultAdd, easeResultY);\n }\n }\n return sum(sum(resultVal, resultAdd), sub(inputResult, key1));\n}\nfunction cosEase(val, min1, max1, input1, input2) {\n var myCos = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n myCos.push(getMeCos(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n myCos = getMeCos(val, min1, max1, input1, input2);\n }\n return myCos;\n function getMeCos(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var myCos2 = sum(sum(mul($bm_neg(c), Math.cos(mul(mapVal, div(Math.PI, 2)))), c), input1);\n return myCos2;\n }\n}\nfunction sinEase(val, min1, max1, input1, input2) {\n var mySin = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n mySin.push(getMeSin(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n mySin = getMeSin(val, min1, max1, input1, input2);\n }\n return mySin;\n function getMeSin(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var mySin2 = sum(mul(c, Math.sin(mul(mapVal, div(Math.PI, 2)))), input1);\n return mySin2;\n }\n}\nfunction easeSwitch(val, min1, max1, input1, input2, morph) {\n if (morph < 0) {\n return cosEase(val, min1, max1, input1, input2);\n } else {\n return sinEase(val, min1, max1, input1, input2);\n }\n}\nfunction unArray(inKey) {\n if (inKey instanceof Array && inKey.length === 1) {\n return inKey[0];\n } else {\n return inKey;\n }\n}\nfunction moClamp(a, b, c) {\n if (!(a instanceof Array)) {\n return Math.max(b, Math.min(c, a));\n } else {\n var aryHold = [];\n for (var x = 0; x < a.length; x++) {\n aryHold.push(Math.max(b, Math.min(c, a[x])));\n }\n return aryHold;\n }\n}"},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"lid right","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[14.25,-0.25],[0,0],[0,0]],"o":[[-14.25,0.25],[0,0],[0,0]],"v":[[73.637,-102.75],[55.137,-93.75],[93.637,-93.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509998396,0.141176006841,0.168626987233,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.98431372549,0.498039215686,0.235294117647,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[75,-92.5],"ix":2,"x":"var $bm_rt;\n$bm_rt = joystick(value);\nfunction joystick(inputResult) {\n var slideR, slideL, slideU, slideD;\n var easeOverride_right = null;\n var easeOverride_left = null;\n var easeOverride_up = null;\n var easeOverride_down = null;\n var contrl = thisComp.layer('Face Rig');\n var myLimit = contrl('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001');\n var contrlCurVal = contrl('ADBE Transform Group')('ADBE Position');\n var resultVal;\n var key1 = [\n 75,\n -92.5\n ];\n var key2 = [\n 84,\n -92.5\n ];\n var key3 = [\n 55,\n -92.5\n ];\n var key4 = [\n 73.875,\n -125.546875\n ];\n var key5 = [\n 73.875,\n -81.796875\n ];\n key1 = unArray(key1);\n key2 = unArray(key2);\n key3 = unArray(key3);\n key4 = unArray(key4);\n key5 = unArray(key5);\n try {\n if (!thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB').active) {\n throw 'inactive';\n }\n slideR = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0001');\n slideL = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0002');\n slideU = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0003');\n slideD = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0004');\n } catch (err) {\n slideR = 0;\n slideL = 0;\n slideU = 0;\n slideD = 0;\n }\n if (easeOverride_right !== null && !isNaN(easeOverride_right)) {\n slideR = moClamp(easeOverride_right, -100, 100);\n }\n if (easeOverride_left !== null && !isNaN(easeOverride_left)) {\n slideL = moClamp(easeOverride_left, -100, 100);\n }\n if (easeOverride_up !== null && !isNaN(easeOverride_up)) {\n slideU = moClamp(easeOverride_up, -100, 100);\n }\n if (easeOverride_down !== null && !isNaN(easeOverride_down)) {\n slideD = moClamp(easeOverride_down, -100, 100);\n }\n var easeResultX, easeResultY;\n if (contrlCurVal[0] >= 0) {\n resultVal = linear(contrlCurVal[0], 0, myLimit, key1, key2);\n if (slideR !== 0) {\n easeResultX = easeSwitch(contrlCurVal[0], 0, myLimit, key1, key2, slideR);\n resultVal = linear(Math.abs(slideR), 0, 100, resultVal, easeResultX);\n }\n } else {\n resultVal = linear($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3);\n if (slideL !== 0) {\n easeResultX = easeSwitch($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3, slideL);\n resultVal = linear(Math.abs(slideL), 0, 100, resultVal, easeResultX);\n }\n }\n var resultAdd = 0;\n if (contrlCurVal[1] <= 0) {\n resultAdd = sub(linear($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4), key1);\n if (slideU !== 0) {\n easeResultY = sub(easeSwitch($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4, slideU), key1);\n resultAdd = linear(Math.abs(slideU), 0, 100, resultAdd, easeResultY);\n }\n } else {\n resultAdd = sub(linear(contrlCurVal[1], 0, myLimit, key1, key5), key1);\n if (slideD !== 0) {\n easeResultY = sub(easeSwitch(contrlCurVal[1], 0, myLimit, key1, key5, slideD), key1);\n resultAdd = linear(Math.abs(slideD), 0, 100, resultAdd, easeResultY);\n }\n }\n return sum(sum(resultVal, resultAdd), sub(inputResult, key1));\n}\nfunction cosEase(val, min1, max1, input1, input2) {\n var myCos = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n myCos.push(getMeCos(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n myCos = getMeCos(val, min1, max1, input1, input2);\n }\n return myCos;\n function getMeCos(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var myCos2 = sum(sum(mul($bm_neg(c), Math.cos(mul(mapVal, div(Math.PI, 2)))), c), input1);\n return myCos2;\n }\n}\nfunction sinEase(val, min1, max1, input1, input2) {\n var mySin = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n mySin.push(getMeSin(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n mySin = getMeSin(val, min1, max1, input1, input2);\n }\n return mySin;\n function getMeSin(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var mySin2 = sum(mul(c, Math.sin(mul(mapVal, div(Math.PI, 2)))), input1);\n return mySin2;\n }\n}\nfunction easeSwitch(val, min1, max1, input1, input2, morph) {\n if (morph < 0) {\n return cosEase(val, min1, max1, input1, input2);\n } else {\n return sinEase(val, min1, max1, input1, input2);\n }\n}\nfunction unArray(inKey) {\n if (inKey instanceof Array && inKey.length === 1) {\n return inKey[0];\n } else {\n return inKey;\n }\n}\nfunction moClamp(a, b, c) {\n if (!(a instanceof Array)) {\n return Math.max(b, Math.min(c, a));\n } else {\n var aryHold = [];\n for (var x = 0; x < a.length; x++) {\n aryHold.push(Math.max(b, Math.min(c, a[x])));\n }\n return aryHold;\n }\n}"},"a":{"a":0,"k":[73.875,-93.047],"ix":1},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\n$bm_rt = joystick(value);\nfunction joystick(inputResult) {\n var slideR, slideL, slideU, slideD;\n var easeOverride_right = null;\n var easeOverride_left = null;\n var easeOverride_up = null;\n var easeOverride_down = null;\n var contrl = thisComp.layer('Face Rig');\n var myLimit = contrl('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001');\n var contrlCurVal = contrl('ADBE Transform Group')('ADBE Position');\n var resultVal;\n var key1 = [\n 100,\n 100\n ];\n var key2 = [\n 65,\n 100\n ];\n var key3 = [\n 100,\n 100\n ];\n var key4 = [\n 100,\n 132\n ];\n var key5 = [\n 100,\n 73\n ];\n key1 = unArray(key1);\n key2 = unArray(key2);\n key3 = unArray(key3);\n key4 = unArray(key4);\n key5 = unArray(key5);\n try {\n if (!thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB').active) {\n throw 'inactive';\n }\n slideR = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0001');\n slideL = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0002');\n slideU = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0003');\n slideD = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0004');\n } catch (err) {\n slideR = 0;\n slideL = 0;\n slideU = 0;\n slideD = 0;\n }\n if (easeOverride_right !== null && !isNaN(easeOverride_right)) {\n slideR = moClamp(easeOverride_right, -100, 100);\n }\n if (easeOverride_left !== null && !isNaN(easeOverride_left)) {\n slideL = moClamp(easeOverride_left, -100, 100);\n }\n if (easeOverride_up !== null && !isNaN(easeOverride_up)) {\n slideU = moClamp(easeOverride_up, -100, 100);\n }\n if (easeOverride_down !== null && !isNaN(easeOverride_down)) {\n slideD = moClamp(easeOverride_down, -100, 100);\n }\n var easeResultX, easeResultY;\n if (contrlCurVal[0] >= 0) {\n resultVal = linear(contrlCurVal[0], 0, myLimit, key1, key2);\n if (slideR !== 0) {\n easeResultX = easeSwitch(contrlCurVal[0], 0, myLimit, key1, key2, slideR);\n resultVal = linear(Math.abs(slideR), 0, 100, resultVal, easeResultX);\n }\n } else {\n resultVal = linear($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3);\n if (slideL !== 0) {\n easeResultX = easeSwitch($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3, slideL);\n resultVal = linear(Math.abs(slideL), 0, 100, resultVal, easeResultX);\n }\n }\n var resultAdd = 0;\n if (contrlCurVal[1] <= 0) {\n resultAdd = sub(linear($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4), key1);\n if (slideU !== 0) {\n easeResultY = sub(easeSwitch($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4, slideU), key1);\n resultAdd = linear(Math.abs(slideU), 0, 100, resultAdd, easeResultY);\n }\n } else {\n resultAdd = sub(linear(contrlCurVal[1], 0, myLimit, key1, key5), key1);\n if (slideD !== 0) {\n easeResultY = sub(easeSwitch(contrlCurVal[1], 0, myLimit, key1, key5, slideD), key1);\n resultAdd = linear(Math.abs(slideD), 0, 100, resultAdd, easeResultY);\n }\n }\n return sum(sum(resultVal, resultAdd), sub(inputResult, key1));\n}\nfunction cosEase(val, min1, max1, input1, input2) {\n var myCos = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n myCos.push(getMeCos(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n myCos = getMeCos(val, min1, max1, input1, input2);\n }\n return myCos;\n function getMeCos(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var myCos2 = sum(sum(mul($bm_neg(c), Math.cos(mul(mapVal, div(Math.PI, 2)))), c), input1);\n return myCos2;\n }\n}\nfunction sinEase(val, min1, max1, input1, input2) {\n var mySin = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n mySin.push(getMeSin(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n mySin = getMeSin(val, min1, max1, input1, input2);\n }\n return mySin;\n function getMeSin(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var mySin2 = sum(mul(c, Math.sin(mul(mapVal, div(Math.PI, 2)))), input1);\n return mySin2;\n }\n}\nfunction easeSwitch(val, min1, max1, input1, input2, morph) {\n if (morph < 0) {\n return cosEase(val, min1, max1, input1, input2);\n } else {\n return sinEase(val, min1, max1, input1, input2);\n }\n}\nfunction unArray(inKey) {\n if (inKey instanceof Array && inKey.length === 1) {\n return inKey[0];\n } else {\n return inKey;\n }\n}\nfunction moClamp(a, b, c) {\n if (!(a instanceof Array)) {\n return Math.max(b, Math.min(c, a));\n } else {\n var aryHold = [];\n for (var x = 0; x < a.length; x++) {\n aryHold.push(Math.max(b, Math.min(c, a[x])));\n }\n return aryHold;\n }\n}"},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"lid left","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-41.598,-0.006]],"o":[[0,0],[0,0],[41.598,0.006]],"v":[[87.137,-91.5],[-1.863,-91],[42.637,-62]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509998396,0.141176006841,0.168626987233,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[43.146,-80.344],"ix":2,"x":"var $bm_rt;\n$bm_rt = joystick(value);\nfunction joystick(inputResult) {\n var slideR, slideL, slideU, slideD;\n var easeOverride_right = null;\n var easeOverride_left = null;\n var easeOverride_up = null;\n var easeOverride_down = null;\n var contrl = thisComp.layer('Face Rig');\n var myLimit = contrl('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001');\n var contrlCurVal = contrl('ADBE Transform Group')('ADBE Position');\n var resultVal;\n var key1 = [\n 43.146484375,\n -80.34375\n ];\n var key2 = [\n 64.146484375,\n -80.34375\n ];\n var key3 = [\n 21.646484375,\n -80.34375\n ];\n var key4 = [\n 43.146484375,\n -119.84375\n ];\n var key5 = [\n 43.146484375,\n -69.84375\n ];\n key1 = unArray(key1);\n key2 = unArray(key2);\n key3 = unArray(key3);\n key4 = unArray(key4);\n key5 = unArray(key5);\n try {\n if (!thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB').active) {\n throw 'inactive';\n }\n slideR = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0001');\n slideL = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0002');\n slideU = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0003');\n slideD = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0004');\n } catch (err) {\n slideR = 0;\n slideL = 0;\n slideU = 0;\n slideD = 0;\n }\n if (easeOverride_right !== null && !isNaN(easeOverride_right)) {\n slideR = moClamp(easeOverride_right, -100, 100);\n }\n if (easeOverride_left !== null && !isNaN(easeOverride_left)) {\n slideL = moClamp(easeOverride_left, -100, 100);\n }\n if (easeOverride_up !== null && !isNaN(easeOverride_up)) {\n slideU = moClamp(easeOverride_up, -100, 100);\n }\n if (easeOverride_down !== null && !isNaN(easeOverride_down)) {\n slideD = moClamp(easeOverride_down, -100, 100);\n }\n var easeResultX, easeResultY;\n if (contrlCurVal[0] >= 0) {\n resultVal = linear(contrlCurVal[0], 0, myLimit, key1, key2);\n if (slideR !== 0) {\n easeResultX = easeSwitch(contrlCurVal[0], 0, myLimit, key1, key2, slideR);\n resultVal = linear(Math.abs(slideR), 0, 100, resultVal, easeResultX);\n }\n } else {\n resultVal = linear($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3);\n if (slideL !== 0) {\n easeResultX = easeSwitch($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3, slideL);\n resultVal = linear(Math.abs(slideL), 0, 100, resultVal, easeResultX);\n }\n }\n var resultAdd = 0;\n if (contrlCurVal[1] <= 0) {\n resultAdd = sub(linear($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4), key1);\n if (slideU !== 0) {\n easeResultY = sub(easeSwitch($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4, slideU), key1);\n resultAdd = linear(Math.abs(slideU), 0, 100, resultAdd, easeResultY);\n }\n } else {\n resultAdd = sub(linear(contrlCurVal[1], 0, myLimit, key1, key5), key1);\n if (slideD !== 0) {\n easeResultY = sub(easeSwitch(contrlCurVal[1], 0, myLimit, key1, key5, slideD), key1);\n resultAdd = linear(Math.abs(slideD), 0, 100, resultAdd, easeResultY);\n }\n }\n return sum(sum(resultVal, resultAdd), sub(inputResult, key1));\n}\nfunction cosEase(val, min1, max1, input1, input2) {\n var myCos = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n myCos.push(getMeCos(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n myCos = getMeCos(val, min1, max1, input1, input2);\n }\n return myCos;\n function getMeCos(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var myCos2 = sum(sum(mul($bm_neg(c), Math.cos(mul(mapVal, div(Math.PI, 2)))), c), input1);\n return myCos2;\n }\n}\nfunction sinEase(val, min1, max1, input1, input2) {\n var mySin = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n mySin.push(getMeSin(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n mySin = getMeSin(val, min1, max1, input1, input2);\n }\n return mySin;\n function getMeSin(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var mySin2 = sum(mul(c, Math.sin(mul(mapVal, div(Math.PI, 2)))), input1);\n return mySin2;\n }\n}\nfunction easeSwitch(val, min1, max1, input1, input2, morph) {\n if (morph < 0) {\n return cosEase(val, min1, max1, input1, input2);\n } else {\n return sinEase(val, min1, max1, input1, input2);\n }\n}\nfunction unArray(inKey) {\n if (inKey instanceof Array && inKey.length === 1) {\n return inKey[0];\n } else {\n return inKey;\n }\n}\nfunction moClamp(a, b, c) {\n if (!(a instanceof Array)) {\n return Math.max(b, Math.min(c, a));\n } else {\n var aryHold = [];\n for (var x = 0; x < a.length; x++) {\n aryHold.push(Math.max(b, Math.min(c, a[x])));\n }\n return aryHold;\n }\n}"},"a":{"a":0,"k":[43.591,-78.546],"ix":1},"s":{"a":0,"k":[67.022,67.022],"ix":3,"x":"var $bm_rt;\n$bm_rt = joystick(value);\nfunction joystick(inputResult) {\n var slideR, slideL, slideU, slideD;\n var easeOverride_right = null;\n var easeOverride_left = null;\n var easeOverride_up = null;\n var easeOverride_down = null;\n var contrl = thisComp.layer('Face Rig');\n var myLimit = contrl('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001');\n var contrlCurVal = contrl('ADBE Transform Group')('ADBE Position');\n var resultVal;\n var key1 = [\n 67.0221619132623,\n 67.0221619132623\n ];\n var key2 = [\n 51.0221633911133,\n 67.0221633911133\n ];\n var key3 = [\n 45.0221633911133,\n 67.0221633911133\n ];\n var key4 = [\n 67.0221619132623,\n 42.0221619132623\n ];\n var key5 = [\n 67.0221619132623,\n 42.0221619132623\n ];\n key1 = unArray(key1);\n key2 = unArray(key2);\n key3 = unArray(key3);\n key4 = unArray(key4);\n key5 = unArray(key5);\n try {\n if (!thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB').active) {\n throw 'inactive';\n }\n slideR = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0001');\n slideL = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0002');\n slideU = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0003');\n slideD = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0004');\n } catch (err) {\n slideR = 0;\n slideL = 0;\n slideU = 0;\n slideD = 0;\n }\n if (easeOverride_right !== null && !isNaN(easeOverride_right)) {\n slideR = moClamp(easeOverride_right, -100, 100);\n }\n if (easeOverride_left !== null && !isNaN(easeOverride_left)) {\n slideL = moClamp(easeOverride_left, -100, 100);\n }\n if (easeOverride_up !== null && !isNaN(easeOverride_up)) {\n slideU = moClamp(easeOverride_up, -100, 100);\n }\n if (easeOverride_down !== null && !isNaN(easeOverride_down)) {\n slideD = moClamp(easeOverride_down, -100, 100);\n }\n var easeResultX, easeResultY;\n if (contrlCurVal[0] >= 0) {\n resultVal = linear(contrlCurVal[0], 0, myLimit, key1, key2);\n if (slideR !== 0) {\n easeResultX = easeSwitch(contrlCurVal[0], 0, myLimit, key1, key2, slideR);\n resultVal = linear(Math.abs(slideR), 0, 100, resultVal, easeResultX);\n }\n } else {\n resultVal = linear($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3);\n if (slideL !== 0) {\n easeResultX = easeSwitch($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3, slideL);\n resultVal = linear(Math.abs(slideL), 0, 100, resultVal, easeResultX);\n }\n }\n var resultAdd = 0;\n if (contrlCurVal[1] <= 0) {\n resultAdd = sub(linear($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4), key1);\n if (slideU !== 0) {\n easeResultY = sub(easeSwitch($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4, slideU), key1);\n resultAdd = linear(Math.abs(slideU), 0, 100, resultAdd, easeResultY);\n }\n } else {\n resultAdd = sub(linear(contrlCurVal[1], 0, myLimit, key1, key5), key1);\n if (slideD !== 0) {\n easeResultY = sub(easeSwitch(contrlCurVal[1], 0, myLimit, key1, key5, slideD), key1);\n resultAdd = linear(Math.abs(slideD), 0, 100, resultAdd, easeResultY);\n }\n }\n return sum(sum(resultVal, resultAdd), sub(inputResult, key1));\n}\nfunction cosEase(val, min1, max1, input1, input2) {\n var myCos = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n myCos.push(getMeCos(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n myCos = getMeCos(val, min1, max1, input1, input2);\n }\n return myCos;\n function getMeCos(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var myCos2 = sum(sum(mul($bm_neg(c), Math.cos(mul(mapVal, div(Math.PI, 2)))), c), input1);\n return myCos2;\n }\n}\nfunction sinEase(val, min1, max1, input1, input2) {\n var mySin = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n mySin.push(getMeSin(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n mySin = getMeSin(val, min1, max1, input1, input2);\n }\n return mySin;\n function getMeSin(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var mySin2 = sum(mul(c, Math.sin(mul(mapVal, div(Math.PI, 2)))), input1);\n return mySin2;\n }\n}\nfunction easeSwitch(val, min1, max1, input1, input2, morph) {\n if (morph < 0) {\n return cosEase(val, min1, max1, input1, input2);\n } else {\n return sinEase(val, min1, max1, input1, input2);\n }\n}\nfunction unArray(inKey) {\n if (inKey instanceof Array && inKey.length === 1) {\n return inKey[0];\n } else {\n return inKey;\n }\n}\nfunction moClamp(a, b, c) {\n if (!(a instanceof Array)) {\n return Math.max(b, Math.min(c, a));\n } else {\n var aryHold = [];\n for (var x = 0; x < a.length; x++) {\n aryHold.push(Math.max(b, Math.min(c, a[x])));\n }\n return aryHold;\n }\n}"},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"mouth","np":3,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[16.676,16.676],"ix":2},"p":{"a":0,"k":[58,-10],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509998396,0.141176006841,0.168626987233,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.219607843137,0.678431372549,0.627450980392,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[12.975,-104.662],"ix":2,"x":"var $bm_rt;\n$bm_rt = joystick(value);\nfunction joystick(inputResult) {\n var slideR, slideL, slideU, slideD;\n var easeOverride_right = null;\n var easeOverride_left = null;\n var easeOverride_up = null;\n var easeOverride_down = null;\n var contrl = thisComp.layer('Face Rig');\n var myLimit = contrl('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001');\n var contrlCurVal = contrl('ADBE Transform Group')('ADBE Position');\n var resultVal;\n var key1 = [\n 12.974609375,\n -104.662109375\n ];\n var key2 = [\n 57.974609375,\n -104.662109375\n ];\n var key3 = [\n 3.974609375,\n -104.662109375\n ];\n var key4 = [\n 12.974609375,\n -139.662109375\n ];\n var key5 = [\n 12.974609375,\n -85.912109375\n ];\n key1 = unArray(key1);\n key2 = unArray(key2);\n key3 = unArray(key3);\n key4 = unArray(key4);\n key5 = unArray(key5);\n try {\n if (!thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB').active) {\n throw 'inactive';\n }\n slideR = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0001');\n slideL = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0002');\n slideU = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0003');\n slideD = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0004');\n } catch (err) {\n slideR = 0;\n slideL = 0;\n slideU = 0;\n slideD = 0;\n }\n if (easeOverride_right !== null && !isNaN(easeOverride_right)) {\n slideR = moClamp(easeOverride_right, -100, 100);\n }\n if (easeOverride_left !== null && !isNaN(easeOverride_left)) {\n slideL = moClamp(easeOverride_left, -100, 100);\n }\n if (easeOverride_up !== null && !isNaN(easeOverride_up)) {\n slideU = moClamp(easeOverride_up, -100, 100);\n }\n if (easeOverride_down !== null && !isNaN(easeOverride_down)) {\n slideD = moClamp(easeOverride_down, -100, 100);\n }\n var easeResultX, easeResultY;\n if (contrlCurVal[0] >= 0) {\n resultVal = linear(contrlCurVal[0], 0, myLimit, key1, key2);\n if (slideR !== 0) {\n easeResultX = easeSwitch(contrlCurVal[0], 0, myLimit, key1, key2, slideR);\n resultVal = linear(Math.abs(slideR), 0, 100, resultVal, easeResultX);\n }\n } else {\n resultVal = linear($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3);\n if (slideL !== 0) {\n easeResultX = easeSwitch($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3, slideL);\n resultVal = linear(Math.abs(slideL), 0, 100, resultVal, easeResultX);\n }\n }\n var resultAdd = 0;\n if (contrlCurVal[1] <= 0) {\n resultAdd = sub(linear($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4), key1);\n if (slideU !== 0) {\n easeResultY = sub(easeSwitch($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4, slideU), key1);\n resultAdd = linear(Math.abs(slideU), 0, 100, resultAdd, easeResultY);\n }\n } else {\n resultAdd = sub(linear(contrlCurVal[1], 0, myLimit, key1, key5), key1);\n if (slideD !== 0) {\n easeResultY = sub(easeSwitch(contrlCurVal[1], 0, myLimit, key1, key5, slideD), key1);\n resultAdd = linear(Math.abs(slideD), 0, 100, resultAdd, easeResultY);\n }\n }\n return sum(sum(resultVal, resultAdd), sub(inputResult, key1));\n}\nfunction cosEase(val, min1, max1, input1, input2) {\n var myCos = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n myCos.push(getMeCos(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n myCos = getMeCos(val, min1, max1, input1, input2);\n }\n return myCos;\n function getMeCos(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var myCos2 = sum(sum(mul($bm_neg(c), Math.cos(mul(mapVal, div(Math.PI, 2)))), c), input1);\n return myCos2;\n }\n}\nfunction sinEase(val, min1, max1, input1, input2) {\n var mySin = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n mySin.push(getMeSin(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n mySin = getMeSin(val, min1, max1, input1, input2);\n }\n return mySin;\n function getMeSin(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var mySin2 = sum(mul(c, Math.sin(mul(mapVal, div(Math.PI, 2)))), input1);\n return mySin2;\n }\n}\nfunction easeSwitch(val, min1, max1, input1, input2, morph) {\n if (morph < 0) {\n return cosEase(val, min1, max1, input1, input2);\n } else {\n return sinEase(val, min1, max1, input1, input2);\n }\n}\nfunction unArray(inKey) {\n if (inKey instanceof Array && inKey.length === 1) {\n return inKey[0];\n } else {\n return inKey;\n }\n}\nfunction moClamp(a, b, c) {\n if (!(a instanceof Array)) {\n return Math.max(b, Math.min(c, a));\n } else {\n var aryHold = [];\n for (var x = 0; x < a.length; x++) {\n aryHold.push(Math.max(b, Math.min(c, a[x])));\n }\n return aryHold;\n }\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\n$bm_rt = joystick(value);\nfunction joystick(inputResult) {\n var slideR, slideL, slideU, slideD;\n var easeOverride_right = null;\n var easeOverride_left = null;\n var easeOverride_up = null;\n var easeOverride_down = null;\n var contrl = thisComp.layer('Face Rig');\n var myLimit = contrl('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001');\n var contrlCurVal = contrl('ADBE Transform Group')('ADBE Position');\n var resultVal;\n var key1 = [\n 100,\n 100\n ];\n var key2 = [\n 54,\n 100\n ];\n var key3 = [\n 76,\n 100\n ];\n var key4 = [\n 100,\n 80\n ];\n var key5 = [\n 100,\n 80\n ];\n key1 = unArray(key1);\n key2 = unArray(key2);\n key3 = unArray(key3);\n key4 = unArray(key4);\n key5 = unArray(key5);\n try {\n if (!thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB').active) {\n throw 'inactive';\n }\n slideR = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0001');\n slideL = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0002');\n slideU = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0003');\n slideD = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0004');\n } catch (err) {\n slideR = 0;\n slideL = 0;\n slideU = 0;\n slideD = 0;\n }\n if (easeOverride_right !== null && !isNaN(easeOverride_right)) {\n slideR = moClamp(easeOverride_right, -100, 100);\n }\n if (easeOverride_left !== null && !isNaN(easeOverride_left)) {\n slideL = moClamp(easeOverride_left, -100, 100);\n }\n if (easeOverride_up !== null && !isNaN(easeOverride_up)) {\n slideU = moClamp(easeOverride_up, -100, 100);\n }\n if (easeOverride_down !== null && !isNaN(easeOverride_down)) {\n slideD = moClamp(easeOverride_down, -100, 100);\n }\n var easeResultX, easeResultY;\n if (contrlCurVal[0] >= 0) {\n resultVal = linear(contrlCurVal[0], 0, myLimit, key1, key2);\n if (slideR !== 0) {\n easeResultX = easeSwitch(contrlCurVal[0], 0, myLimit, key1, key2, slideR);\n resultVal = linear(Math.abs(slideR), 0, 100, resultVal, easeResultX);\n }\n } else {\n resultVal = linear($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3);\n if (slideL !== 0) {\n easeResultX = easeSwitch($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3, slideL);\n resultVal = linear(Math.abs(slideL), 0, 100, resultVal, easeResultX);\n }\n }\n var resultAdd = 0;\n if (contrlCurVal[1] <= 0) {\n resultAdd = sub(linear($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4), key1);\n if (slideU !== 0) {\n easeResultY = sub(easeSwitch($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4, slideU), key1);\n resultAdd = linear(Math.abs(slideU), 0, 100, resultAdd, easeResultY);\n }\n } else {\n resultAdd = sub(linear(contrlCurVal[1], 0, myLimit, key1, key5), key1);\n if (slideD !== 0) {\n easeResultY = sub(easeSwitch(contrlCurVal[1], 0, myLimit, key1, key5, slideD), key1);\n resultAdd = linear(Math.abs(slideD), 0, 100, resultAdd, easeResultY);\n }\n }\n return sum(sum(resultVal, resultAdd), sub(inputResult, key1));\n}\nfunction cosEase(val, min1, max1, input1, input2) {\n var myCos = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n myCos.push(getMeCos(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n myCos = getMeCos(val, min1, max1, input1, input2);\n }\n return myCos;\n function getMeCos(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var myCos2 = sum(sum(mul($bm_neg(c), Math.cos(mul(mapVal, div(Math.PI, 2)))), c), input1);\n return myCos2;\n }\n}\nfunction sinEase(val, min1, max1, input1, input2) {\n var mySin = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n mySin.push(getMeSin(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n mySin = getMeSin(val, min1, max1, input1, input2);\n }\n return mySin;\n function getMeSin(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var mySin2 = sum(mul(c, Math.sin(mul(mapVal, div(Math.PI, 2)))), input1);\n return mySin2;\n }\n}\nfunction easeSwitch(val, min1, max1, input1, input2, morph) {\n if (morph < 0) {\n return cosEase(val, min1, max1, input1, input2);\n } else {\n return sinEase(val, min1, max1, input1, input2);\n }\n}\nfunction unArray(inKey) {\n if (inKey instanceof Array && inKey.length === 1) {\n return inKey[0];\n } else {\n return inKey;\n }\n}\nfunction moClamp(a, b, c) {\n if (!(a instanceof Array)) {\n return Math.max(b, Math.min(c, a));\n } else {\n var aryHold = [];\n for (var x = 0; x < a.length; x++) {\n aryHold.push(Math.max(b, Math.min(c, a[x])));\n }\n return aryHold;\n }\n}"},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"pupil right","np":3,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[16.676,16.676],"ix":2},"p":{"a":0,"k":[1,-10],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509998396,0.141176006841,0.168626987233,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.219607843137,0.678431372549,0.627450980392,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[12.975,-104.662],"ix":2,"x":"var $bm_rt;\n$bm_rt = joystick(value);\nfunction joystick(inputResult) {\n var slideR, slideL, slideU, slideD;\n var easeOverride_right = null;\n var easeOverride_left = null;\n var easeOverride_up = null;\n var easeOverride_down = null;\n var contrl = thisComp.layer('Face Rig');\n var myLimit = contrl('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001');\n var contrlCurVal = contrl('ADBE Transform Group')('ADBE Position');\n var resultVal;\n var key1 = [\n 12.974609375,\n -104.662109375\n ];\n var key2 = [\n 39.974609375,\n -104.662109375\n ];\n var key3 = [\n -5.025390625,\n -104.662109375\n ];\n var key4 = [\n 12.974609375,\n -139.662109375\n ];\n var key5 = [\n 12.974609375,\n -85.912109375\n ];\n key1 = unArray(key1);\n key2 = unArray(key2);\n key3 = unArray(key3);\n key4 = unArray(key4);\n key5 = unArray(key5);\n try {\n if (!thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB').active) {\n throw 'inactive';\n }\n slideR = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0001');\n slideL = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0002');\n slideU = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0003');\n slideD = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0004');\n } catch (err) {\n slideR = 0;\n slideL = 0;\n slideU = 0;\n slideD = 0;\n }\n if (easeOverride_right !== null && !isNaN(easeOverride_right)) {\n slideR = moClamp(easeOverride_right, -100, 100);\n }\n if (easeOverride_left !== null && !isNaN(easeOverride_left)) {\n slideL = moClamp(easeOverride_left, -100, 100);\n }\n if (easeOverride_up !== null && !isNaN(easeOverride_up)) {\n slideU = moClamp(easeOverride_up, -100, 100);\n }\n if (easeOverride_down !== null && !isNaN(easeOverride_down)) {\n slideD = moClamp(easeOverride_down, -100, 100);\n }\n var easeResultX, easeResultY;\n if (contrlCurVal[0] >= 0) {\n resultVal = linear(contrlCurVal[0], 0, myLimit, key1, key2);\n if (slideR !== 0) {\n easeResultX = easeSwitch(contrlCurVal[0], 0, myLimit, key1, key2, slideR);\n resultVal = linear(Math.abs(slideR), 0, 100, resultVal, easeResultX);\n }\n } else {\n resultVal = linear($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3);\n if (slideL !== 0) {\n easeResultX = easeSwitch($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3, slideL);\n resultVal = linear(Math.abs(slideL), 0, 100, resultVal, easeResultX);\n }\n }\n var resultAdd = 0;\n if (contrlCurVal[1] <= 0) {\n resultAdd = sub(linear($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4), key1);\n if (slideU !== 0) {\n easeResultY = sub(easeSwitch($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4, slideU), key1);\n resultAdd = linear(Math.abs(slideU), 0, 100, resultAdd, easeResultY);\n }\n } else {\n resultAdd = sub(linear(contrlCurVal[1], 0, myLimit, key1, key5), key1);\n if (slideD !== 0) {\n easeResultY = sub(easeSwitch(contrlCurVal[1], 0, myLimit, key1, key5, slideD), key1);\n resultAdd = linear(Math.abs(slideD), 0, 100, resultAdd, easeResultY);\n }\n }\n return sum(sum(resultVal, resultAdd), sub(inputResult, key1));\n}\nfunction cosEase(val, min1, max1, input1, input2) {\n var myCos = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n myCos.push(getMeCos(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n myCos = getMeCos(val, min1, max1, input1, input2);\n }\n return myCos;\n function getMeCos(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var myCos2 = sum(sum(mul($bm_neg(c), Math.cos(mul(mapVal, div(Math.PI, 2)))), c), input1);\n return myCos2;\n }\n}\nfunction sinEase(val, min1, max1, input1, input2) {\n var mySin = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n mySin.push(getMeSin(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n mySin = getMeSin(val, min1, max1, input1, input2);\n }\n return mySin;\n function getMeSin(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var mySin2 = sum(mul(c, Math.sin(mul(mapVal, div(Math.PI, 2)))), input1);\n return mySin2;\n }\n}\nfunction easeSwitch(val, min1, max1, input1, input2, morph) {\n if (morph < 0) {\n return cosEase(val, min1, max1, input1, input2);\n } else {\n return sinEase(val, min1, max1, input1, input2);\n }\n}\nfunction unArray(inKey) {\n if (inKey instanceof Array && inKey.length === 1) {\n return inKey[0];\n } else {\n return inKey;\n }\n}\nfunction moClamp(a, b, c) {\n if (!(a instanceof Array)) {\n return Math.max(b, Math.min(c, a));\n } else {\n var aryHold = [];\n for (var x = 0; x < a.length; x++) {\n aryHold.push(Math.max(b, Math.min(c, a[x])));\n }\n return aryHold;\n }\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\n$bm_rt = joystick(value);\nfunction joystick(inputResult) {\n var slideR, slideL, slideU, slideD;\n var easeOverride_right = null;\n var easeOverride_left = null;\n var easeOverride_up = null;\n var easeOverride_down = null;\n var contrl = thisComp.layer('Face Rig');\n var myLimit = contrl('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001');\n var contrlCurVal = contrl('ADBE Transform Group')('ADBE Position');\n var resultVal;\n var key1 = [\n 100,\n 100\n ];\n var key2 = [\n 67,\n 100\n ];\n var key3 = [\n 57,\n 100\n ];\n var key4 = [\n 100,\n 80\n ];\n var key5 = [\n 100,\n 80\n ];\n key1 = unArray(key1);\n key2 = unArray(key2);\n key3 = unArray(key3);\n key4 = unArray(key4);\n key5 = unArray(key5);\n try {\n if (!thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB').active) {\n throw 'inactive';\n }\n slideR = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0001');\n slideL = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0002');\n slideU = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0003');\n slideD = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0004');\n } catch (err) {\n slideR = 0;\n slideL = 0;\n slideU = 0;\n slideD = 0;\n }\n if (easeOverride_right !== null && !isNaN(easeOverride_right)) {\n slideR = moClamp(easeOverride_right, -100, 100);\n }\n if (easeOverride_left !== null && !isNaN(easeOverride_left)) {\n slideL = moClamp(easeOverride_left, -100, 100);\n }\n if (easeOverride_up !== null && !isNaN(easeOverride_up)) {\n slideU = moClamp(easeOverride_up, -100, 100);\n }\n if (easeOverride_down !== null && !isNaN(easeOverride_down)) {\n slideD = moClamp(easeOverride_down, -100, 100);\n }\n var easeResultX, easeResultY;\n if (contrlCurVal[0] >= 0) {\n resultVal = linear(contrlCurVal[0], 0, myLimit, key1, key2);\n if (slideR !== 0) {\n easeResultX = easeSwitch(contrlCurVal[0], 0, myLimit, key1, key2, slideR);\n resultVal = linear(Math.abs(slideR), 0, 100, resultVal, easeResultX);\n }\n } else {\n resultVal = linear($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3);\n if (slideL !== 0) {\n easeResultX = easeSwitch($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3, slideL);\n resultVal = linear(Math.abs(slideL), 0, 100, resultVal, easeResultX);\n }\n }\n var resultAdd = 0;\n if (contrlCurVal[1] <= 0) {\n resultAdd = sub(linear($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4), key1);\n if (slideU !== 0) {\n easeResultY = sub(easeSwitch($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4, slideU), key1);\n resultAdd = linear(Math.abs(slideU), 0, 100, resultAdd, easeResultY);\n }\n } else {\n resultAdd = sub(linear(contrlCurVal[1], 0, myLimit, key1, key5), key1);\n if (slideD !== 0) {\n easeResultY = sub(easeSwitch(contrlCurVal[1], 0, myLimit, key1, key5, slideD), key1);\n resultAdd = linear(Math.abs(slideD), 0, 100, resultAdd, easeResultY);\n }\n }\n return sum(sum(resultVal, resultAdd), sub(inputResult, key1));\n}\nfunction cosEase(val, min1, max1, input1, input2) {\n var myCos = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n myCos.push(getMeCos(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n myCos = getMeCos(val, min1, max1, input1, input2);\n }\n return myCos;\n function getMeCos(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var myCos2 = sum(sum(mul($bm_neg(c), Math.cos(mul(mapVal, div(Math.PI, 2)))), c), input1);\n return myCos2;\n }\n}\nfunction sinEase(val, min1, max1, input1, input2) {\n var mySin = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n mySin.push(getMeSin(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n mySin = getMeSin(val, min1, max1, input1, input2);\n }\n return mySin;\n function getMeSin(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var mySin2 = sum(mul(c, Math.sin(mul(mapVal, div(Math.PI, 2)))), input1);\n return mySin2;\n }\n}\nfunction easeSwitch(val, min1, max1, input1, input2, morph) {\n if (morph < 0) {\n return cosEase(val, min1, max1, input1, input2);\n } else {\n return sinEase(val, min1, max1, input1, input2);\n }\n}\nfunction unArray(inKey) {\n if (inKey instanceof Array && inKey.length === 1) {\n return inKey[0];\n } else {\n return inKey;\n }\n}\nfunction moClamp(a, b, c) {\n if (!(a instanceof Array)) {\n return Math.max(b, Math.min(c, a));\n } else {\n var aryHold = [];\n for (var x = 0; x < a.length; x++) {\n aryHold.push(Math.max(b, Math.min(c, a[x])));\n }\n return aryHold;\n }\n}"},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"pupil left","np":3,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[37.258,37.258],"ix":2},"p":{"a":0,"k":[53,-27],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509998396,0.141176006841,0.168626987233,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[19.266,-88.371],"ix":2,"x":"var $bm_rt;\n$bm_rt = joystick(value);\nfunction joystick(inputResult) {\n var slideR, slideL, slideU, slideD;\n var easeOverride_right = null;\n var easeOverride_left = null;\n var easeOverride_up = null;\n var easeOverride_down = null;\n var contrl = thisComp.layer('Face Rig');\n var myLimit = contrl('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001');\n var contrlCurVal = contrl('ADBE Transform Group')('ADBE Position');\n var resultVal;\n var key1 = [\n 19.265625,\n -88.37109375\n ];\n var key2 = [\n 52.265625,\n -88.37109375\n ];\n var key3 = [\n 12.265625,\n -88.37109375\n ];\n var key4 = [\n 19.265625,\n -120.87109375\n ];\n var key5 = [\n 19.265625,\n -77.12109375\n ];\n key1 = unArray(key1);\n key2 = unArray(key2);\n key3 = unArray(key3);\n key4 = unArray(key4);\n key5 = unArray(key5);\n try {\n if (!thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB').active) {\n throw 'inactive';\n }\n slideR = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0001');\n slideL = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0002');\n slideU = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0003');\n slideD = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0004');\n } catch (err) {\n slideR = 0;\n slideL = 0;\n slideU = 0;\n slideD = 0;\n }\n if (easeOverride_right !== null && !isNaN(easeOverride_right)) {\n slideR = moClamp(easeOverride_right, -100, 100);\n }\n if (easeOverride_left !== null && !isNaN(easeOverride_left)) {\n slideL = moClamp(easeOverride_left, -100, 100);\n }\n if (easeOverride_up !== null && !isNaN(easeOverride_up)) {\n slideU = moClamp(easeOverride_up, -100, 100);\n }\n if (easeOverride_down !== null && !isNaN(easeOverride_down)) {\n slideD = moClamp(easeOverride_down, -100, 100);\n }\n var easeResultX, easeResultY;\n if (contrlCurVal[0] >= 0) {\n resultVal = linear(contrlCurVal[0], 0, myLimit, key1, key2);\n if (slideR !== 0) {\n easeResultX = easeSwitch(contrlCurVal[0], 0, myLimit, key1, key2, slideR);\n resultVal = linear(Math.abs(slideR), 0, 100, resultVal, easeResultX);\n }\n } else {\n resultVal = linear($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3);\n if (slideL !== 0) {\n easeResultX = easeSwitch($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3, slideL);\n resultVal = linear(Math.abs(slideL), 0, 100, resultVal, easeResultX);\n }\n }\n var resultAdd = 0;\n if (contrlCurVal[1] <= 0) {\n resultAdd = sub(linear($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4), key1);\n if (slideU !== 0) {\n easeResultY = sub(easeSwitch($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4, slideU), key1);\n resultAdd = linear(Math.abs(slideU), 0, 100, resultAdd, easeResultY);\n }\n } else {\n resultAdd = sub(linear(contrlCurVal[1], 0, myLimit, key1, key5), key1);\n if (slideD !== 0) {\n easeResultY = sub(easeSwitch(contrlCurVal[1], 0, myLimit, key1, key5, slideD), key1);\n resultAdd = linear(Math.abs(slideD), 0, 100, resultAdd, easeResultY);\n }\n }\n return sum(sum(resultVal, resultAdd), sub(inputResult, key1));\n}\nfunction cosEase(val, min1, max1, input1, input2) {\n var myCos = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n myCos.push(getMeCos(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n myCos = getMeCos(val, min1, max1, input1, input2);\n }\n return myCos;\n function getMeCos(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var myCos2 = sum(sum(mul($bm_neg(c), Math.cos(mul(mapVal, div(Math.PI, 2)))), c), input1);\n return myCos2;\n }\n}\nfunction sinEase(val, min1, max1, input1, input2) {\n var mySin = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n mySin.push(getMeSin(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n mySin = getMeSin(val, min1, max1, input1, input2);\n }\n return mySin;\n function getMeSin(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var mySin2 = sum(mul(c, Math.sin(mul(mapVal, div(Math.PI, 2)))), input1);\n return mySin2;\n }\n}\nfunction easeSwitch(val, min1, max1, input1, input2, morph) {\n if (morph < 0) {\n return cosEase(val, min1, max1, input1, input2);\n } else {\n return sinEase(val, min1, max1, input1, input2);\n }\n}\nfunction unArray(inKey) {\n if (inKey instanceof Array && inKey.length === 1) {\n return inKey[0];\n } else {\n return inKey;\n }\n}\nfunction moClamp(a, b, c) {\n if (!(a instanceof Array)) {\n return Math.max(b, Math.min(c, a));\n } else {\n var aryHold = [];\n for (var x = 0; x < a.length; x++) {\n aryHold.push(Math.max(b, Math.min(c, a[x])));\n }\n return aryHold;\n }\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\n$bm_rt = joystick(value);\nfunction joystick(inputResult) {\n var slideR, slideL, slideU, slideD;\n var easeOverride_right = null;\n var easeOverride_left = null;\n var easeOverride_up = null;\n var easeOverride_down = null;\n var contrl = thisComp.layer('Face Rig');\n var myLimit = contrl('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001');\n var contrlCurVal = contrl('ADBE Transform Group')('ADBE Position');\n var resultVal;\n var key1 = [\n 100,\n 100\n ];\n var key2 = [\n 63,\n 100\n ];\n var key3 = [\n 75,\n 100\n ];\n var key4 = [\n 100,\n 80\n ];\n var key5 = [\n 100,\n 80\n ];\n key1 = unArray(key1);\n key2 = unArray(key2);\n key3 = unArray(key3);\n key4 = unArray(key4);\n key5 = unArray(key5);\n try {\n if (!thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB').active) {\n throw 'inactive';\n }\n slideR = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0001');\n slideL = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0002');\n slideU = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0003');\n slideD = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0004');\n } catch (err) {\n slideR = 0;\n slideL = 0;\n slideU = 0;\n slideD = 0;\n }\n if (easeOverride_right !== null && !isNaN(easeOverride_right)) {\n slideR = moClamp(easeOverride_right, -100, 100);\n }\n if (easeOverride_left !== null && !isNaN(easeOverride_left)) {\n slideL = moClamp(easeOverride_left, -100, 100);\n }\n if (easeOverride_up !== null && !isNaN(easeOverride_up)) {\n slideU = moClamp(easeOverride_up, -100, 100);\n }\n if (easeOverride_down !== null && !isNaN(easeOverride_down)) {\n slideD = moClamp(easeOverride_down, -100, 100);\n }\n var easeResultX, easeResultY;\n if (contrlCurVal[0] >= 0) {\n resultVal = linear(contrlCurVal[0], 0, myLimit, key1, key2);\n if (slideR !== 0) {\n easeResultX = easeSwitch(contrlCurVal[0], 0, myLimit, key1, key2, slideR);\n resultVal = linear(Math.abs(slideR), 0, 100, resultVal, easeResultX);\n }\n } else {\n resultVal = linear($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3);\n if (slideL !== 0) {\n easeResultX = easeSwitch($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3, slideL);\n resultVal = linear(Math.abs(slideL), 0, 100, resultVal, easeResultX);\n }\n }\n var resultAdd = 0;\n if (contrlCurVal[1] <= 0) {\n resultAdd = sub(linear($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4), key1);\n if (slideU !== 0) {\n easeResultY = sub(easeSwitch($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4, slideU), key1);\n resultAdd = linear(Math.abs(slideU), 0, 100, resultAdd, easeResultY);\n }\n } else {\n resultAdd = sub(linear(contrlCurVal[1], 0, myLimit, key1, key5), key1);\n if (slideD !== 0) {\n easeResultY = sub(easeSwitch(contrlCurVal[1], 0, myLimit, key1, key5, slideD), key1);\n resultAdd = linear(Math.abs(slideD), 0, 100, resultAdd, easeResultY);\n }\n }\n return sum(sum(resultVal, resultAdd), sub(inputResult, key1));\n}\nfunction cosEase(val, min1, max1, input1, input2) {\n var myCos = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n myCos.push(getMeCos(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n myCos = getMeCos(val, min1, max1, input1, input2);\n }\n return myCos;\n function getMeCos(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var myCos2 = sum(sum(mul($bm_neg(c), Math.cos(mul(mapVal, div(Math.PI, 2)))), c), input1);\n return myCos2;\n }\n}\nfunction sinEase(val, min1, max1, input1, input2) {\n var mySin = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n mySin.push(getMeSin(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n mySin = getMeSin(val, min1, max1, input1, input2);\n }\n return mySin;\n function getMeSin(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var mySin2 = sum(mul(c, Math.sin(mul(mapVal, div(Math.PI, 2)))), input1);\n return mySin2;\n }\n}\nfunction easeSwitch(val, min1, max1, input1, input2, morph) {\n if (morph < 0) {\n return cosEase(val, min1, max1, input1, input2);\n } else {\n return sinEase(val, min1, max1, input1, input2);\n }\n}\nfunction unArray(inKey) {\n if (inKey instanceof Array && inKey.length === 1) {\n return inKey[0];\n } else {\n return inKey;\n }\n}\nfunction moClamp(a, b, c) {\n if (!(a instanceof Array)) {\n return Math.max(b, Math.min(c, a));\n } else {\n var aryHold = [];\n for (var x = 0; x < a.length; x++) {\n aryHold.push(Math.max(b, Math.min(c, a[x])));\n }\n return aryHold;\n }\n}"},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"eye ball right","np":3,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[37.258,37.258],"ix":2},"p":{"a":0,"k":[-5,-27],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509998396,0.141176006841,0.168626987233,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[19.266,-88.371],"ix":2,"x":"var $bm_rt;\n$bm_rt = joystick(value);\nfunction joystick(inputResult) {\n var slideR, slideL, slideU, slideD;\n var easeOverride_right = null;\n var easeOverride_left = null;\n var easeOverride_up = null;\n var easeOverride_down = null;\n var contrl = thisComp.layer('Face Rig');\n var myLimit = contrl('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001');\n var contrlCurVal = contrl('ADBE Transform Group')('ADBE Position');\n var resultVal;\n var key1 = [\n 19.265625,\n -88.37109375\n ];\n var key2 = [\n 39.265625,\n -88.37109375\n ];\n var key3 = [\n 2.265625,\n -88.37109375\n ];\n var key4 = [\n 19.265625,\n -120.87109375\n ];\n var key5 = [\n 19.265625,\n -77.12109375\n ];\n key1 = unArray(key1);\n key2 = unArray(key2);\n key3 = unArray(key3);\n key4 = unArray(key4);\n key5 = unArray(key5);\n try {\n if (!thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB').active) {\n throw 'inactive';\n }\n slideR = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0001');\n slideL = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0002');\n slideU = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0003');\n slideD = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0004');\n } catch (err) {\n slideR = 0;\n slideL = 0;\n slideU = 0;\n slideD = 0;\n }\n if (easeOverride_right !== null && !isNaN(easeOverride_right)) {\n slideR = moClamp(easeOverride_right, -100, 100);\n }\n if (easeOverride_left !== null && !isNaN(easeOverride_left)) {\n slideL = moClamp(easeOverride_left, -100, 100);\n }\n if (easeOverride_up !== null && !isNaN(easeOverride_up)) {\n slideU = moClamp(easeOverride_up, -100, 100);\n }\n if (easeOverride_down !== null && !isNaN(easeOverride_down)) {\n slideD = moClamp(easeOverride_down, -100, 100);\n }\n var easeResultX, easeResultY;\n if (contrlCurVal[0] >= 0) {\n resultVal = linear(contrlCurVal[0], 0, myLimit, key1, key2);\n if (slideR !== 0) {\n easeResultX = easeSwitch(contrlCurVal[0], 0, myLimit, key1, key2, slideR);\n resultVal = linear(Math.abs(slideR), 0, 100, resultVal, easeResultX);\n }\n } else {\n resultVal = linear($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3);\n if (slideL !== 0) {\n easeResultX = easeSwitch($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3, slideL);\n resultVal = linear(Math.abs(slideL), 0, 100, resultVal, easeResultX);\n }\n }\n var resultAdd = 0;\n if (contrlCurVal[1] <= 0) {\n resultAdd = sub(linear($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4), key1);\n if (slideU !== 0) {\n easeResultY = sub(easeSwitch($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4, slideU), key1);\n resultAdd = linear(Math.abs(slideU), 0, 100, resultAdd, easeResultY);\n }\n } else {\n resultAdd = sub(linear(contrlCurVal[1], 0, myLimit, key1, key5), key1);\n if (slideD !== 0) {\n easeResultY = sub(easeSwitch(contrlCurVal[1], 0, myLimit, key1, key5, slideD), key1);\n resultAdd = linear(Math.abs(slideD), 0, 100, resultAdd, easeResultY);\n }\n }\n return sum(sum(resultVal, resultAdd), sub(inputResult, key1));\n}\nfunction cosEase(val, min1, max1, input1, input2) {\n var myCos = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n myCos.push(getMeCos(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n myCos = getMeCos(val, min1, max1, input1, input2);\n }\n return myCos;\n function getMeCos(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var myCos2 = sum(sum(mul($bm_neg(c), Math.cos(mul(mapVal, div(Math.PI, 2)))), c), input1);\n return myCos2;\n }\n}\nfunction sinEase(val, min1, max1, input1, input2) {\n var mySin = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n mySin.push(getMeSin(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n mySin = getMeSin(val, min1, max1, input1, input2);\n }\n return mySin;\n function getMeSin(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var mySin2 = sum(mul(c, Math.sin(mul(mapVal, div(Math.PI, 2)))), input1);\n return mySin2;\n }\n}\nfunction easeSwitch(val, min1, max1, input1, input2, morph) {\n if (morph < 0) {\n return cosEase(val, min1, max1, input1, input2);\n } else {\n return sinEase(val, min1, max1, input1, input2);\n }\n}\nfunction unArray(inKey) {\n if (inKey instanceof Array && inKey.length === 1) {\n return inKey[0];\n } else {\n return inKey;\n }\n}\nfunction moClamp(a, b, c) {\n if (!(a instanceof Array)) {\n return Math.max(b, Math.min(c, a));\n } else {\n var aryHold = [];\n for (var x = 0; x < a.length; x++) {\n aryHold.push(Math.max(b, Math.min(c, a[x])));\n }\n return aryHold;\n }\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\n$bm_rt = joystick(value);\nfunction joystick(inputResult) {\n var slideR, slideL, slideU, slideD;\n var easeOverride_right = null;\n var easeOverride_left = null;\n var easeOverride_up = null;\n var easeOverride_down = null;\n var contrl = thisComp.layer('Face Rig');\n var myLimit = contrl('ADBE Effect Parade')('joystickLimit')('ADBE Slider Control-0001');\n var contrlCurVal = contrl('ADBE Transform Group')('ADBE Position');\n var resultVal;\n var key1 = [\n 100,\n 100\n ];\n var key2 = [\n 82,\n 100\n ];\n var key3 = [\n 61,\n 100\n ];\n var key4 = [\n 100,\n 80\n ];\n var key5 = [\n 100,\n 80\n ];\n key1 = unArray(key1);\n key2 = unArray(key2);\n key3 = unArray(key3);\n key4 = unArray(key4);\n key5 = unArray(key5);\n try {\n if (!thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB').active) {\n throw 'inactive';\n }\n slideR = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0001');\n slideL = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0002');\n slideU = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0003');\n slideD = thisLayer('ADBE Effect Parade')('Pseudo/1k48264d77gIB')('Pseudo/1k48264d77gIB-0004');\n } catch (err) {\n slideR = 0;\n slideL = 0;\n slideU = 0;\n slideD = 0;\n }\n if (easeOverride_right !== null && !isNaN(easeOverride_right)) {\n slideR = moClamp(easeOverride_right, -100, 100);\n }\n if (easeOverride_left !== null && !isNaN(easeOverride_left)) {\n slideL = moClamp(easeOverride_left, -100, 100);\n }\n if (easeOverride_up !== null && !isNaN(easeOverride_up)) {\n slideU = moClamp(easeOverride_up, -100, 100);\n }\n if (easeOverride_down !== null && !isNaN(easeOverride_down)) {\n slideD = moClamp(easeOverride_down, -100, 100);\n }\n var easeResultX, easeResultY;\n if (contrlCurVal[0] >= 0) {\n resultVal = linear(contrlCurVal[0], 0, myLimit, key1, key2);\n if (slideR !== 0) {\n easeResultX = easeSwitch(contrlCurVal[0], 0, myLimit, key1, key2, slideR);\n resultVal = linear(Math.abs(slideR), 0, 100, resultVal, easeResultX);\n }\n } else {\n resultVal = linear($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3);\n if (slideL !== 0) {\n easeResultX = easeSwitch($bm_neg(contrlCurVal[0]), 0, myLimit, key1, key3, slideL);\n resultVal = linear(Math.abs(slideL), 0, 100, resultVal, easeResultX);\n }\n }\n var resultAdd = 0;\n if (contrlCurVal[1] <= 0) {\n resultAdd = sub(linear($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4), key1);\n if (slideU !== 0) {\n easeResultY = sub(easeSwitch($bm_neg(contrlCurVal[1]), 0, myLimit, key1, key4, slideU), key1);\n resultAdd = linear(Math.abs(slideU), 0, 100, resultAdd, easeResultY);\n }\n } else {\n resultAdd = sub(linear(contrlCurVal[1], 0, myLimit, key1, key5), key1);\n if (slideD !== 0) {\n easeResultY = sub(easeSwitch(contrlCurVal[1], 0, myLimit, key1, key5, slideD), key1);\n resultAdd = linear(Math.abs(slideD), 0, 100, resultAdd, easeResultY);\n }\n }\n return sum(sum(resultVal, resultAdd), sub(inputResult, key1));\n}\nfunction cosEase(val, min1, max1, input1, input2) {\n var myCos = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n myCos.push(getMeCos(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n myCos = getMeCos(val, min1, max1, input1, input2);\n }\n return myCos;\n function getMeCos(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var myCos2 = sum(sum(mul($bm_neg(c), Math.cos(mul(mapVal, div(Math.PI, 2)))), c), input1);\n return myCos2;\n }\n}\nfunction sinEase(val, min1, max1, input1, input2) {\n var mySin = [];\n if ($bm_isInstanceOfArray(input1)) {\n for (var x = 0; x < input1.length; x++) {\n mySin.push(getMeSin(val, min1, max1, input1[x], input2[x]));\n }\n } else {\n mySin = getMeSin(val, min1, max1, input1, input2);\n }\n return mySin;\n function getMeSin(val, min1, max1, input1, input2) {\n var mapVal = moClamp(div(val, sub(max1, min1)), 0, 1);\n var c = sub(input2, input1);\n var mySin2 = sum(mul(c, Math.sin(mul(mapVal, div(Math.PI, 2)))), input1);\n return mySin2;\n }\n}\nfunction easeSwitch(val, min1, max1, input1, input2, morph) {\n if (morph < 0) {\n return cosEase(val, min1, max1, input1, input2);\n } else {\n return sinEase(val, min1, max1, input1, input2);\n }\n}\nfunction unArray(inKey) {\n if (inKey instanceof Array && inKey.length === 1) {\n return inKey[0];\n } else {\n return inKey;\n }\n}\nfunction moClamp(a, b, c) {\n if (!(a instanceof Array)) {\n return Math.max(b, Math.min(c, a));\n } else {\n var aryHold = [];\n for (var x = 0; x < a.length; x++) {\n aryHold.push(Math.max(b, Math.min(c, a[x])));\n }\n return aryHold;\n }\n}"},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"eye ball left","np":3,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[117.273,117.273],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509998396,0.141176006841,0.168626987233,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.98431372549,0.498039215686,0.235294117647,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[42.637,-115.363],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"head","np":3,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Body","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[18,84,0],"ix":2},"a":{"a":0,"k":[-47.758,106.242,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-46.758,233.242],[-47.258,1.242]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.219607843137,0.678431372549,0.627450980392,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-47.721,117.488],"ix":2},"a":{"a":0,"k":[-47.721,117.488],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 3","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[17.505,-0.028]],"o":[[0,0],[0,0],[0,0],[-17.505,0.028]],"v":[[-72.258,-19.758],[-47.258,1.492],[-19.758,-18.758],[-47.253,-22.286]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509998396,0.141176006841,0.168626987233,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-0.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-69.758,76.242],[-116.758,76.242],[-116.758,101.242],[-92.758,116.242],[-69.758,101.242]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509998396,0.141176006841,0.168626987233,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.219604716581,0.678232230392,0.62581763174,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-95.807,47.773],"ix":2},"a":{"a":0,"k":[-91.96,91.668],"ix":1},"s":{"a":0,"k":[83.641,83.641],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[256.484,256.484],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509998396,0.141176006841,0.168626987233,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.235294117647,0.78431372549,0.721568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-47.758,106.242],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Left arm 2::Wrist","hd":true,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\ntry {\n var parentRot = hasParent ? parentTotal() : 0;\n var rotCalc = sub(thisLayer('ADBE Root Vectors Group')('Admin')('Transform')('Rotation'), parentRot);\n $bm_rt = sum(rotCalc, value);\n} catch (err) {\n $bm_rt = value;\n}\n;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n parentVal = sum(parentVal, eval([layerChain][0]).rotation);\n }\n return parentVal;\n}"},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[595.189,372.865,0],"e":[681.676,159.27,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":9,"s":[681.676,159.27,0],"e":[681.676,210.27,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":15,"s":[681.676,210.27,0],"e":[681.676,210.27,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":21.429,"s":[681.676,210.27,0],"e":[643.622,455.892,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":26,"s":[643.622,455.892,0],"e":[595.189,320.973,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":30,"s":[595.189,320.973,0],"e":[595.189,372.865,0],"to":[0,0,0],"ti":[0,0,0]},{"t":33.0000013441176}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"RubberHose 2","np":18,"mn":"Pseudo/3bf5uID/RubberHose_2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Hose Length","mn":"Pseudo/3bf5uID/RubberHose_2-0001","ix":1,"v":{"a":0,"k":280,"ix":1}},{"ty":0,"nm":"Bend Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0002","ix":2,"v":{"a":0,"k":40,"ix":2}},{"ty":0,"nm":"Realism","mn":"Pseudo/3bf5uID/RubberHose_2-0003","ix":3,"v":{"a":0,"k":0,"ix":3}},{"ty":0,"nm":"Bend Direction","mn":"Pseudo/3bf5uID/RubberHose_2-0004","ix":4,"v":{"a":0,"k":-100,"ix":4}},{"ty":7,"nm":"Auto Rotate Start","mn":"Pseudo/3bf5uID/RubberHose_2-0005","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":7,"nm":"Auto Rotate End","mn":"Pseudo/3bf5uID/RubberHose_2-0006","ix":6,"v":{"a":0,"k":1,"ix":6}},{"ty":6,"nm":"Math Stuff","mn":"Pseudo/3bf5uID/RubberHose_2-0007","ix":7,"v":0},{"ty":3,"nm":"A","mn":"Pseudo/3bf5uID/RubberHose_2-0008","ix":8,"v":{"a":0,"k":[0,0],"ix":8,"x":"var $bm_rt;\n$bm_rt = thisLayer.toComp([\n 0,\n 0,\n 0\n]);"}},{"ty":3,"nm":"B","mn":"Pseudo/3bf5uID/RubberHose_2-0009","ix":9,"v":{"a":0,"k":[0,0],"ix":9,"x":"var $bm_rt;\ntry {\n var b = thisLayer(2)('Admin')(2)('B')(2)(1)._name;\n $bm_rt = thisComp.layer(b).toComp([\n 0,\n 0,\n 0\n ]);\n} catch (err) {\n $bm_rt = value;\n}"}},{"ty":0,"nm":"Outer Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0010","ix":10,"v":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\nvar a = thisLayer(4)('RubberHose 2')('A');\nvar b = thisLayer(4)('RubberHose 2')('B');\nvar s = length(a, b);\n$bm_rt = mul(Math.sin(0.78539816339), s);"}},{"ty":0,"nm":"Inner Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0011","ix":11,"v":{"a":0,"k":0,"ix":11,"x":"var $bm_rt;\nvar eff = thisLayer(4)('RubberHose 2');\nvar bendRad = eff('Bend Radius');\nvar hoseLength = div(eff('Hose Length'), 2);\nvar realism = eff('Realism');\nvar bendDir = div(eff('Bend Direction'), 100);\nvar sFac = eff('Parent Scale');\nvar straight = eff('Straight');\nvar autoFlop = eff('AutoFlop');\nvar roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\nvar innerRad;\nif (hoseLength > straight) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n} else {\n innerRad = straight;\n}\ninnerRad *= Math.abs(sFac);\ninnerRad = linear(Math.abs(autoFlop), mul(straight, Math.max(Math.abs(sFac), 0.001)), innerRad);\n$bm_rt = innerRad;"}},{"ty":0,"nm":"Straight","mn":"Pseudo/3bf5uID/RubberHose_2-0012","ix":12,"v":{"a":0,"k":0,"ix":12,"x":"var $bm_rt;\nvar sFac = thisLayer(4)('RubberHose 2')('Parent Scale');\nvar outerRad = div(thisLayer(4)('RubberHose 2')('Outer Radius'), Math.max(Math.abs(sFac), 0.001));\n;\n$bm_rt = div(mul(1.4142135623731, outerRad), 2);"}},{"ty":0,"nm":"Base Rotation","mn":"Pseudo/3bf5uID/RubberHose_2-0013","ix":13,"v":{"a":0,"k":0,"ix":13,"x":"var $bm_rt;\nvar a = thisLayer(4)('RubberHose 2')('A');\nvar b = thisLayer(4)('RubberHose 2')('B');\n$bm_rt = radiansToDegrees(Math.atan2(sub(a[1], b[1]), sub(a[0], b[0])));"}},{"ty":0,"nm":"AutoFlop","mn":"Pseudo/3bf5uID/RubberHose_2-0014","ix":14,"v":{"a":0,"k":0,"ix":14,"x":"var $bm_rt;\nvar hasAF = false, isEnabled = false, output;\ntry {\n var lyrAF = thisComp.layer(sum(thisLayer._name.split('::')[0], '::AutoFlop'));\n isEnabled = lyrAF(4)('Enable')(1);\n var falloffAngle = lyrAF(4)('Falloff')(1);\n hasAF = true;\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = thisLayer(4)('RubberHose 2')('B');\n} catch (e) {\n}\nif (hasAF && isEnabled == 1) {\n var threshRot = lyrAF('ADBE Transform Group')('ADBE Rotate Z');\n threshRot %= 360;\n var ctrlAngle = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var offsetAngle = sub(threshRot, ctrlAngle);\n offsetAngle %= 360;\n var sign = offsetAngle > 0 && offsetAngle < 180 || offsetAngle < -180 ? -1 : 1;\n var absAngle = Math.abs(offsetAngle);\n if (absAngle > 90) {\n absAngle = Math.abs(sub(absAngle, 180));\n }\n if (absAngle > 90) {\n absAngle = Math.abs(sub(absAngle, 180));\n }\n output = linear(absAngle, 0, falloffAngle, 0, 1);\n output *= sign;\n} else {\n output = 1;\n}\n$bm_rt = output;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n parentVal = sum(parentVal, eval([layerChain][0]).rotation);\n }\n return parentVal;\n}"}},{"ty":0,"nm":"Parent Scale","mn":"Pseudo/3bf5uID/RubberHose_2-0015","ix":15,"v":{"a":0,"k":0,"ix":15,"x":"var $bm_rt;\nvar sFactor = 1;\nvar scaleNorm = 0;\nvar layerChain = 'thisLayer';\nwhile (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n scaleNorm = div(eval(layerChain)('ADBE Transform Group')('ADBE Scale')[0], 100);\n sFactor = mul(sFactor, scaleNorm);\n}\n$bm_rt = sFactor;"}},{"ty":6,"nm":"","mn":"Pseudo/3bf5uID/RubberHose_2-0016","ix":16,"v":0}]}],"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left arm 2::Wrist","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[20,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left arm 2::Shoulder","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\nvar eff = thisLayer(4)('RubberHose 2');\nvar autoRotate = eff('Auto Rotate End');\nif (autoRotate == 1) {\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = eff('B');\n var s = length(a, b);\n var sFac = eff('Parent Scale');\n var autoFlop = 1;\n var realism = eff('Realism');\n var bendDir = div(eff('Bend Direction'), 100);\n var hoseLength = div(eff('Hose Length'), 2);\n var bendRad = eff('Bend Radius');\n var autoFlop = eff('AutoFlop');\n var baseRot = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var outerRad = mul(Math.sin(0.78539816339), s);\n var straight = div(mul(1.4142135623731, outerRad), 2);\n straight /= Math.max(Math.abs(sFac), 0.001);\n var roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\n var innerRad;\n if (hoseLength > straight) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n } else {\n innerRad = straight;\n }\n innerRad = linear(Math.abs(autoFlop), straight, innerRad);\n var flopDir = 1;\n if (bendDir < 0) {\n flopDir = -1;\n }\n flopDir *= autoFlop;\n var opp = mul(sub(innerRad, straight), flopDir);\n var theta = Math.atan(div(opp, Math.max(straight, 0.001)));\n var bendAngle = radiansToDegrees(theta);\n if (sFac < 0) {\n baseRot *= -1;\n }\n bendRad *= div(div(theta, $bm_neg(Math.PI)), linear(s, hoseLength, 0, 2, 0.9));\n var rotCalc = sub(sum(baseRot, bendAngle), bendRad);\n $bm_rt = rotCalc;\n} else {\n $bm_rt = value;\n}\n;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Circle","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-75,0],[75,0]],"c":false},"ix":2},"nm":"01","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-30],[0,30]],"c":false},"ix":2},"nm":"02","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[15,15],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ControlShape","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.560000002384,0,1],"ix":3,"x":"var $bm_rt;\nif (thisLayer.active) {\n try {\n var eff = thisLayer(4)('RubberHose 2');\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = eff('B');\n var straight = eff('Straight');\n var hoseLength = div(eff('Hose Length'), 2);\n if (straight > hoseLength) {\n $bm_rt = [\n 0.51,\n 0.83,\n 0.98,\n 1\n ];\n } else {\n $bm_rt = value;\n }\n } catch (err) {\n $bm_rt = value;\n }\n} else {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Control Point","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Left arm 2::Shoulder","parent":7,"hd":true,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\ntry {\n var parentRot = hasParent ? parentTotal() : 0;\n var rotCalc = sub(thisLayer('ADBE Root Vectors Group')('Admin')('Transform')('Rotation'), parentRot);\n $bm_rt = sum(rotCalc, value);\n} catch (err) {\n $bm_rt = value;\n}\n;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n parentVal = sum(parentVal, eval([layerChain][0]).rotation);\n }\n return parentVal;\n}"},"p":{"a":0,"k":[9.742,3.742,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left arm 2::Wrist","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[20,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left arm 2::Shoulder","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\ntry {\n var eff = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var autoRotate = eff('Auto Rotate Start');\n if (autoRotate == 1) {\n var a = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name).toComp([\n 0,\n 0,\n 0\n ]);\n var b = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var s = length(a, b);\n var sFac = eff('Parent Scale');\n var autoFlop = 1;\n var realism = eff('Realism');\n var bendDir = div(eff('Bend Direction'), 100);\n var hoseLength = div(eff('Hose Length'), 2);\n var bendRad = eff('Bend Radius');\n var autoFlop = eff('AutoFlop');\n var baseRot = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var outerRad = mul(Math.sin(0.78539816339), s);\n var straight = div(mul(1.4142135623731, outerRad), 2);\n straight /= Math.max(Math.abs(sFac), 0.001);\n var roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\n var innerRad;\n if (straight <= hoseLength) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n } else {\n innerRad = straight;\n }\n innerRad = linear(Math.abs(autoFlop), straight, innerRad);\n var flopDir = 1;\n if (bendDir < 0) {\n flopDir = -1;\n }\n flopDir *= autoFlop;\n var opp = mul(sub(innerRad, straight), flopDir);\n var theta = Math.atan(div(opp, Math.max(straight, 0.001)));\n var bendAngle = radiansToDegrees(theta);\n if (sFac < 0) {\n baseRot *= -1;\n }\n bendRad *= div(div(theta, $bm_neg(Math.PI)), linear(s, hoseLength, 0, 2, 0.9));\n var rotCalc = sum(sub(baseRot, bendAngle), bendRad);\n $bm_rt = rotCalc;\n } else {\n $bm_rt = 0;\n }\n ;\n} catch (err) {\n $bm_rt = value;\n}\n;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Circle","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-75,0],[75,0]],"c":false},"ix":2},"nm":"01","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-30],[0,30]],"c":false},"ix":2},"nm":"02","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[15,15],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ControlShape","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.560000002384,0,1],"ix":3,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name);\n $bm_rt = ctrl(2)('Control Point')(2)('Stroke 1')('Color');\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Control Point","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Left arm 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\nvar r = 0;\nif (thisLayer.hasParent) {\n r = $bm_neg(parentTotal());\n}\n$bm_rt = r;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n parentVal = sum(parentVal, eval([layerChain][0]).rotation);\n }\n return parentVal;\n}"},"p":{"a":0,"k":[820,500,0],"ix":2,"x":"var $bm_rt;\nvar p = [\n 0,\n 0\n ];\ntry {\n if (thisLayer.hasParent) {\n p = parent.fromComp([\n 0,\n 0,\n 0\n ]);\n }\n $bm_rt = p;\n} catch (err) {\n $bm_rt = p;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6,"x":"var $bm_rt;\nvar s = [\n 100,\n 100\n ];\nif (hasParent) {\n var sFactor = parentTotal();\n s = [\n s[0] * sFactor[0],\n s[1] * sFactor[1]\n ];\n}\n$bm_rt = s;\nfunction parentTotal() {\n var sFactor = [\n 1,\n 1\n ];\n var scaleNorm = [\n 0,\n 0\n ];\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n scaleNorm = eval([layerChain][0]).scale;\n if (scaleNorm[0] != 0 && scaleNorm[1] != 0) {\n scaleNorm = [\n 100 / scaleNorm[0],\n 100 / scaleNorm[1]\n ];\n }\n sFactor = [\n sFactor[0] * scaleNorm[0],\n sFactor[1] * scaleNorm[1]\n ];\n }\n return sFactor;\n}"}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":4,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":500,"ix":6,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"is":{"a":0,"k":0,"ix":8,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"or":{"a":0,"k":113,"ix":7,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"os":{"a":0,"k":0,"ix":9,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"ix":1,"nm":"LineForCurve","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"e":{"a":0,"k":0,"ix":2,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"o":{"a":0,"k":-90,"ix":3,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"m":1,"ix":2,"nm":"Line Halfer","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"a":{"a":0,"k":[0,0],"ix":1,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"r":{"a":0,"k":45,"ix":6,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"o":{"a":0,"k":100,"ix":7,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"sk":{"a":0,"k":0,"ix":4,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"sa":{"a":0,"k":0,"ix":5,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"nm":"Transform"}],"nm":"Arc","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":67,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.98431372549,0.498039215686,0.235294117647,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":28,"ix":5,"x":"var $bm_rt;\nvar sFac = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2')('Parent Scale');\n$bm_rt = mul(value, sFac);"},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('A');\n} catch (err) {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"hand","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":4,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":500,"ix":6,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"is":{"a":0,"k":0,"ix":8,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"or":{"a":0,"k":113,"ix":7,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"os":{"a":0,"k":0,"ix":9,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"ix":1,"nm":"LineForCurve","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"e":{"a":0,"k":0,"ix":2,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"o":{"a":0,"k":-90,"ix":3,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"m":1,"ix":2,"nm":"Line Halfer","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"a":{"a":0,"k":[0,0],"ix":1,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"r":{"a":0,"k":45,"ix":6,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"o":{"a":0,"k":100,"ix":7,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"sk":{"a":0,"k":0,"ix":4,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"sa":{"a":0,"k":0,"ix":5,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"nm":"Transform"}],"nm":"Arc","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.235294117647,0.78431372549,0.721568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":28,"ix":5,"x":"var $bm_rt;\nvar sFac = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2')('Parent Scale');\n$bm_rt = mul(value, sFac);"},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('A');\n} catch (err) {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"BaseHose","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Style","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left arm 2::Wrist","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[200,200],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left arm 2::Shoulder","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":4,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":200,"ix":6,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Inner Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"is":{"a":0,"k":100,"ix":8,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Bend Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"or":{"a":0,"k":200,"ix":7,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Outer Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"LineForCurve","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"tm","s":{"a":0,"k":0.01,"ix":1},"e":{"a":0,"k":24.99,"ix":2},"o":{"a":0,"k":-90,"ix":3,"x":"var $bm_rt;\n$bm_rt = -90;"},"m":1,"ix":2,"nm":"Line Halfer","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1,"x":"var $bm_rt;\nvar s = thisProperty.propertyGroup(2)(2)(1)(7);\n$bm_rt = [\n -s,\n 0\n];"},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\nvar flop;\ntry {\n var eff = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var bendDir = eff('Bend Direction');\n var autoFlop = eff('AutoFlop');\n flop = bendDir > 0 ? 1 : -1;\n autoFlop > 0 ? 0 : flop *= -1;\n var s = flop == 1 ? [\n -100,\n 100\n ] : [\n 100,\n 100\n ];\n if (eff('Parent Scale') < 0) {\n s = [\n -s[0],\n s[1]\n ];\n }\n $bm_rt = s;\n} catch (err) {\n $bm_rt = value;\n}\n;"},"r":{"a":0,"k":45,"ix":6,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var baseRot = ctrl('Base Rotation');\n var flop = content('Admin').content('ArcMath').transform.scale[0];\n var rotOffset = flop < 0 ? -45 : 225;\n $bm_rt = sum(baseRot, rotOffset);\n} catch (err) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ArcMath","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('A');\n} catch (err) {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Left arm::Wrist","hd":true,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\ntry {\n var parentRot = hasParent ? parentTotal() : 0;\n var rotCalc = sub(thisLayer('ADBE Root Vectors Group')('Admin')('Transform')('Rotation'), parentRot);\n $bm_rt = sum(rotCalc, value);\n} catch (err) {\n $bm_rt = value;\n}\n;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n parentVal = sum(parentVal, eval([layerChain][0]).rotation);\n }\n return parentVal;\n}"},"p":{"a":1,"k":[{"i":{"x":0.5,"y":1},"o":{"x":0.167,"y":0},"n":"0p5_1_0p167_0","t":0,"s":[289.865,231.541,0],"e":[383.73,370.27,0],"to":[0,0,0],"ti":[-34.270263671875,-2.729736328125,0]},{"i":{"x":0.5,"y":1},"o":{"x":0.167,"y":0.138},"n":"0p5_1_0p167_0p138","t":7,"s":[383.73,370.27,0],"e":[410.73,340.27,0],"to":[34.270263671875,2.729736328125,0],"ti":[0,0,0]},{"i":{"x":0.5,"y":1},"o":{"x":0.167,"y":0},"n":"0p5_1_0p167_0","t":12,"s":[410.73,340.27,0],"e":[419.73,352.27,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.5,"y":0.5},"o":{"x":0.167,"y":0.167},"n":"0p5_0p5_0p167_0p167","t":17,"s":[419.73,352.27,0],"e":[419.73,352.27,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.5,"y":1},"o":{"x":0.167,"y":0},"n":"0p5_1_0p167_0","t":20.273,"s":[419.73,352.27,0],"e":[357.459,456.054,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.5,"y":1},"o":{"x":0.167,"y":0},"n":"0p5_1_0p167_0","t":26,"s":[357.459,456.054,0],"e":[324.459,145.054,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.5,"y":1},"o":{"x":0.167,"y":0},"n":"0p5_1_0p167_0","t":31,"s":[324.459,145.054,0],"e":[289.865,231.541,0],"to":[0,0,0],"ti":[0,0,0]},{"t":35.0000014255792}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"RubberHose 2","np":18,"mn":"Pseudo/3bf5uID/RubberHose_2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Hose Length","mn":"Pseudo/3bf5uID/RubberHose_2-0001","ix":1,"v":{"a":0,"k":280,"ix":1}},{"ty":0,"nm":"Bend Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0002","ix":2,"v":{"a":0,"k":40,"ix":2}},{"ty":0,"nm":"Realism","mn":"Pseudo/3bf5uID/RubberHose_2-0003","ix":3,"v":{"a":0,"k":0,"ix":3}},{"ty":0,"nm":"Bend Direction","mn":"Pseudo/3bf5uID/RubberHose_2-0004","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":7,"nm":"Auto Rotate Start","mn":"Pseudo/3bf5uID/RubberHose_2-0005","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":7,"nm":"Auto Rotate End","mn":"Pseudo/3bf5uID/RubberHose_2-0006","ix":6,"v":{"a":0,"k":1,"ix":6}},{"ty":6,"nm":"Math Stuff","mn":"Pseudo/3bf5uID/RubberHose_2-0007","ix":7,"v":0},{"ty":3,"nm":"A","mn":"Pseudo/3bf5uID/RubberHose_2-0008","ix":8,"v":{"a":0,"k":[0,0],"ix":8,"x":"var $bm_rt;\n$bm_rt = thisLayer.toComp([\n 0,\n 0,\n 0\n]);"}},{"ty":3,"nm":"B","mn":"Pseudo/3bf5uID/RubberHose_2-0009","ix":9,"v":{"a":0,"k":[0,0],"ix":9,"x":"var $bm_rt;\ntry {\n var b = thisLayer(2)('Admin')(2)('B')(2)(1)._name;\n $bm_rt = thisComp.layer(b).toComp([\n 0,\n 0,\n 0\n ]);\n} catch (err) {\n $bm_rt = value;\n}"}},{"ty":0,"nm":"Outer Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0010","ix":10,"v":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\nvar a = thisLayer(4)('RubberHose 2')('A');\nvar b = thisLayer(4)('RubberHose 2')('B');\nvar s = length(a, b);\n$bm_rt = mul(Math.sin(0.78539816339), s);"}},{"ty":0,"nm":"Inner Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0011","ix":11,"v":{"a":0,"k":0,"ix":11,"x":"var $bm_rt;\nvar eff = thisLayer(4)('RubberHose 2');\nvar bendRad = eff('Bend Radius');\nvar hoseLength = div(eff('Hose Length'), 2);\nvar realism = eff('Realism');\nvar bendDir = div(eff('Bend Direction'), 100);\nvar sFac = eff('Parent Scale');\nvar straight = eff('Straight');\nvar autoFlop = eff('AutoFlop');\nvar roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\nvar innerRad;\nif (hoseLength > straight) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n} else {\n innerRad = straight;\n}\ninnerRad *= Math.abs(sFac);\ninnerRad = linear(Math.abs(autoFlop), mul(straight, Math.max(Math.abs(sFac), 0.001)), innerRad);\n$bm_rt = innerRad;"}},{"ty":0,"nm":"Straight","mn":"Pseudo/3bf5uID/RubberHose_2-0012","ix":12,"v":{"a":0,"k":0,"ix":12,"x":"var $bm_rt;\nvar sFac = thisLayer(4)('RubberHose 2')('Parent Scale');\nvar outerRad = div(thisLayer(4)('RubberHose 2')('Outer Radius'), Math.max(Math.abs(sFac), 0.001));\n;\n$bm_rt = div(mul(1.4142135623731, outerRad), 2);"}},{"ty":0,"nm":"Base Rotation","mn":"Pseudo/3bf5uID/RubberHose_2-0013","ix":13,"v":{"a":0,"k":0,"ix":13,"x":"var $bm_rt;\nvar a = thisLayer(4)('RubberHose 2')('A');\nvar b = thisLayer(4)('RubberHose 2')('B');\n$bm_rt = radiansToDegrees(Math.atan2(sub(a[1], b[1]), sub(a[0], b[0])));"}},{"ty":0,"nm":"AutoFlop","mn":"Pseudo/3bf5uID/RubberHose_2-0014","ix":14,"v":{"a":0,"k":0,"ix":14,"x":"var $bm_rt;\nvar hasAF = false, isEnabled = false, output;\ntry {\n var lyrAF = thisComp.layer(sum(thisLayer._name.split('::')[0], '::AutoFlop'));\n isEnabled = lyrAF(4)('Enable')(1);\n var falloffAngle = lyrAF(4)('Falloff')(1);\n hasAF = true;\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = thisLayer(4)('RubberHose 2')('B');\n} catch (e) {\n}\nif (hasAF && isEnabled == 1) {\n var threshRot = lyrAF('ADBE Transform Group')('ADBE Rotate Z');\n threshRot %= 360;\n var ctrlAngle = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var offsetAngle = sub(threshRot, ctrlAngle);\n offsetAngle %= 360;\n var sign = offsetAngle > 0 && offsetAngle < 180 || offsetAngle < -180 ? -1 : 1;\n var absAngle = Math.abs(offsetAngle);\n if (absAngle > 90) {\n absAngle = Math.abs(sub(absAngle, 180));\n }\n if (absAngle > 90) {\n absAngle = Math.abs(sub(absAngle, 180));\n }\n output = linear(absAngle, 0, falloffAngle, 0, 1);\n output *= sign;\n} else {\n output = 1;\n}\n$bm_rt = output;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n parentVal = sum(parentVal, eval([layerChain][0]).rotation);\n }\n return parentVal;\n}"}},{"ty":0,"nm":"Parent Scale","mn":"Pseudo/3bf5uID/RubberHose_2-0015","ix":15,"v":{"a":0,"k":0,"ix":15,"x":"var $bm_rt;\nvar sFactor = 1;\nvar scaleNorm = 0;\nvar layerChain = 'thisLayer';\nwhile (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n scaleNorm = div(eval(layerChain)('ADBE Transform Group')('ADBE Scale')[0], 100);\n sFactor = mul(sFactor, scaleNorm);\n}\n$bm_rt = sFactor;"}},{"ty":6,"nm":"","mn":"Pseudo/3bf5uID/RubberHose_2-0016","ix":16,"v":0}]}],"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left arm::Wrist","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[20,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left arm::Shoulder","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\nvar eff = thisLayer(4)('RubberHose 2');\nvar autoRotate = eff('Auto Rotate End');\nif (autoRotate == 1) {\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = eff('B');\n var s = length(a, b);\n var sFac = eff('Parent Scale');\n var autoFlop = 1;\n var realism = eff('Realism');\n var bendDir = div(eff('Bend Direction'), 100);\n var hoseLength = div(eff('Hose Length'), 2);\n var bendRad = eff('Bend Radius');\n var autoFlop = eff('AutoFlop');\n var baseRot = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var outerRad = mul(Math.sin(0.78539816339), s);\n var straight = div(mul(1.4142135623731, outerRad), 2);\n straight /= Math.max(Math.abs(sFac), 0.001);\n var roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\n var innerRad;\n if (hoseLength > straight) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n } else {\n innerRad = straight;\n }\n innerRad = linear(Math.abs(autoFlop), straight, innerRad);\n var flopDir = 1;\n if (bendDir < 0) {\n flopDir = -1;\n }\n flopDir *= autoFlop;\n var opp = mul(sub(innerRad, straight), flopDir);\n var theta = Math.atan(div(opp, Math.max(straight, 0.001)));\n var bendAngle = radiansToDegrees(theta);\n if (sFac < 0) {\n baseRot *= -1;\n }\n bendRad *= div(div(theta, $bm_neg(Math.PI)), linear(s, hoseLength, 0, 2, 0.9));\n var rotCalc = sub(sum(baseRot, bendAngle), bendRad);\n $bm_rt = rotCalc;\n} else {\n $bm_rt = value;\n}\n;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Circle","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-75,0],[75,0]],"c":false},"ix":2},"nm":"01","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-30],[0,30]],"c":false},"ix":2},"nm":"02","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[15,15],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ControlShape","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.560000002384,0,1],"ix":3,"x":"var $bm_rt;\nif (thisLayer.active) {\n try {\n var eff = thisLayer(4)('RubberHose 2');\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = eff('B');\n var straight = eff('Straight');\n var hoseLength = div(eff('Hose Length'), 2);\n if (straight > hoseLength) {\n $bm_rt = [\n 0.51,\n 0.83,\n 0.98,\n 1\n ];\n } else {\n $bm_rt = value;\n }\n } catch (err) {\n $bm_rt = value;\n }\n} else {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Control Point","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Left arm::Shoulder","parent":7,"hd":true,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\ntry {\n var parentRot = hasParent ? parentTotal() : 0;\n var rotCalc = sub(thisLayer('ADBE Root Vectors Group')('Admin')('Transform')('Rotation'), parentRot);\n $bm_rt = sum(rotCalc, value);\n} catch (err) {\n $bm_rt = value;\n}\n;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n parentVal = sum(parentVal, eval([layerChain][0]).rotation);\n }\n return parentVal;\n}"},"p":{"a":0,"k":[-107.758,1.242,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left arm::Wrist","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[20,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left arm::Shoulder","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\ntry {\n var eff = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var autoRotate = eff('Auto Rotate Start');\n if (autoRotate == 1) {\n var a = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name).toComp([\n 0,\n 0,\n 0\n ]);\n var b = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var s = length(a, b);\n var sFac = eff('Parent Scale');\n var autoFlop = 1;\n var realism = eff('Realism');\n var bendDir = div(eff('Bend Direction'), 100);\n var hoseLength = div(eff('Hose Length'), 2);\n var bendRad = eff('Bend Radius');\n var autoFlop = eff('AutoFlop');\n var baseRot = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var outerRad = mul(Math.sin(0.78539816339), s);\n var straight = div(mul(1.4142135623731, outerRad), 2);\n straight /= Math.max(Math.abs(sFac), 0.001);\n var roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\n var innerRad;\n if (straight <= hoseLength) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n } else {\n innerRad = straight;\n }\n innerRad = linear(Math.abs(autoFlop), straight, innerRad);\n var flopDir = 1;\n if (bendDir < 0) {\n flopDir = -1;\n }\n flopDir *= autoFlop;\n var opp = mul(sub(innerRad, straight), flopDir);\n var theta = Math.atan(div(opp, Math.max(straight, 0.001)));\n var bendAngle = radiansToDegrees(theta);\n if (sFac < 0) {\n baseRot *= -1;\n }\n bendRad *= div(div(theta, $bm_neg(Math.PI)), linear(s, hoseLength, 0, 2, 0.9));\n var rotCalc = sum(sub(baseRot, bendAngle), bendRad);\n $bm_rt = rotCalc;\n } else {\n $bm_rt = 0;\n }\n ;\n} catch (err) {\n $bm_rt = value;\n}\n;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Circle","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-75,0],[75,0]],"c":false},"ix":2},"nm":"01","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-30],[0,30]],"c":false},"ix":2},"nm":"02","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[15,15],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ControlShape","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.560000002384,0,1],"ix":3,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name);\n $bm_rt = ctrl(2)('Control Point')(2)('Stroke 1')('Color');\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Control Point","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Left arm","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\nvar r = 0;\nif (thisLayer.hasParent) {\n r = $bm_neg(parentTotal());\n}\n$bm_rt = r;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n parentVal = sum(parentVal, eval([layerChain][0]).rotation);\n }\n return parentVal;\n}"},"p":{"a":0,"k":[425,500,0],"ix":2,"x":"var $bm_rt;\nvar p = [\n 0,\n 0\n ];\ntry {\n if (thisLayer.hasParent) {\n p = parent.fromComp([\n 0,\n 0,\n 0\n ]);\n }\n $bm_rt = p;\n} catch (err) {\n $bm_rt = p;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6,"x":"var $bm_rt;\nvar s = [\n 100,\n 100\n ];\nif (hasParent) {\n var sFactor = parentTotal();\n s = [\n s[0] * sFactor[0],\n s[1] * sFactor[1]\n ];\n}\n$bm_rt = s;\nfunction parentTotal() {\n var sFactor = [\n 1,\n 1\n ];\n var scaleNorm = [\n 0,\n 0\n ];\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n scaleNorm = eval([layerChain][0]).scale;\n if (scaleNorm[0] != 0 && scaleNorm[1] != 0) {\n scaleNorm = [\n 100 / scaleNorm[0],\n 100 / scaleNorm[1]\n ];\n }\n sFactor = [\n sFactor[0] * scaleNorm[0],\n sFactor[1] * scaleNorm[1]\n ];\n }\n return sFactor;\n}"}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":4,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":500,"ix":6,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"is":{"a":0,"k":0,"ix":8,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"or":{"a":0,"k":113,"ix":7,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"os":{"a":0,"k":0,"ix":9,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"ix":1,"nm":"LineForCurve","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"e":{"a":0,"k":0,"ix":2,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"o":{"a":0,"k":-90,"ix":3,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"m":1,"ix":2,"nm":"Line Halfer","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"a":{"a":0,"k":[0,0],"ix":1,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"r":{"a":0,"k":45,"ix":6,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"o":{"a":0,"k":100,"ix":7,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"sk":{"a":0,"k":0,"ix":4,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"sa":{"a":0,"k":0,"ix":5,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"nm":"Transform"}],"nm":"Arc","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":67,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.98431372549,0.498039215686,0.235294117647,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":28,"ix":5,"x":"var $bm_rt;\nvar sFac = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2')('Parent Scale');\n$bm_rt = mul(value, sFac);"},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('A');\n} catch (err) {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"hand","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":4,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":500,"ix":6,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"is":{"a":0,"k":0,"ix":8,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"or":{"a":0,"k":113,"ix":7,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"os":{"a":0,"k":0,"ix":9,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"ix":1,"nm":"LineForCurve","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"e":{"a":0,"k":0,"ix":2,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"o":{"a":0,"k":-90,"ix":3,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"m":1,"ix":2,"nm":"Line Halfer","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"a":{"a":0,"k":[0,0],"ix":1,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"r":{"a":0,"k":45,"ix":6,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"o":{"a":0,"k":100,"ix":7,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"sk":{"a":0,"k":0,"ix":4,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"sa":{"a":0,"k":0,"ix":5,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"nm":"Transform"}],"nm":"Arc","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.235294117647,0.78431372549,0.721568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":28,"ix":5,"x":"var $bm_rt;\nvar sFac = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2')('Parent Scale');\n$bm_rt = mul(value, sFac);"},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('A');\n} catch (err) {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"BaseHose","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Style","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left arm::Wrist","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[200,200],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left arm::Shoulder","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":4,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":200,"ix":6,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Inner Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"is":{"a":0,"k":100,"ix":8,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Bend Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"or":{"a":0,"k":200,"ix":7,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Outer Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"LineForCurve","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"tm","s":{"a":0,"k":0.01,"ix":1},"e":{"a":0,"k":24.99,"ix":2},"o":{"a":0,"k":-90,"ix":3,"x":"var $bm_rt;\n$bm_rt = -90;"},"m":1,"ix":2,"nm":"Line Halfer","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1,"x":"var $bm_rt;\nvar s = thisProperty.propertyGroup(2)(2)(1)(7);\n$bm_rt = [\n -s,\n 0\n];"},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\nvar flop;\ntry {\n var eff = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var bendDir = eff('Bend Direction');\n var autoFlop = eff('AutoFlop');\n flop = bendDir > 0 ? 1 : -1;\n autoFlop > 0 ? 0 : flop *= -1;\n var s = flop == 1 ? [\n -100,\n 100\n ] : [\n 100,\n 100\n ];\n if (eff('Parent Scale') < 0) {\n s = [\n -s[0],\n s[1]\n ];\n }\n $bm_rt = s;\n} catch (err) {\n $bm_rt = value;\n}\n;"},"r":{"a":0,"k":45,"ix":6,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var baseRot = ctrl('Base Rotation');\n var flop = content('Admin').content('ArcMath').transform.scale[0];\n var rotOffset = flop < 0 ? -45 : 225;\n $bm_rt = sum(baseRot, rotOffset);\n} catch (err) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ArcMath","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('A');\n} catch (err) {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Left Leg::Ankle","hd":true,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\ntry {\n var parentRot = hasParent ? parentTotal() : 0;\n var rotCalc = sub(thisLayer('ADBE Root Vectors Group')('Admin')('Transform')('Rotation'), parentRot);\n $bm_rt = sum(rotCalc, value);\n} catch (err) {\n $bm_rt = value;\n}\n;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n parentVal = sum(parentVal, eval([layerChain][0]).rotation);\n }\n return parentVal;\n}"},"p":{"a":1,"k":[{"i":{"x":0.5,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p5_1_0p167_0p167","t":2,"s":[419,830,0],"e":[425,643,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.5,"y":1},"o":{"x":0.167,"y":0},"n":"0p5_1_0p167_0","t":8,"s":[425,643,0],"e":[413,685,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.5,"y":0.5},"o":{"x":0.167,"y":0.167},"n":"0p5_0p5_0p167_0p167","t":13,"s":[413,685,0],"e":[413,685,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":21,"s":[413,685,0],"e":[419,830,0],"to":[0,0,0],"ti":[0,0,0]},{"t":25.0000010182709}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"RubberHose 2","np":18,"mn":"Pseudo/3bf5uID/RubberHose_2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Hose Length","mn":"Pseudo/3bf5uID/RubberHose_2-0001","ix":1,"v":{"a":0,"k":280,"ix":1}},{"ty":0,"nm":"Bend Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0002","ix":2,"v":{"a":0,"k":40,"ix":2}},{"ty":0,"nm":"Realism","mn":"Pseudo/3bf5uID/RubberHose_2-0003","ix":3,"v":{"a":0,"k":0,"ix":3}},{"ty":0,"nm":"Bend Direction","mn":"Pseudo/3bf5uID/RubberHose_2-0004","ix":4,"v":{"a":0,"k":-100,"ix":4}},{"ty":7,"nm":"Auto Rotate Start","mn":"Pseudo/3bf5uID/RubberHose_2-0005","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":7,"nm":"Auto Rotate End","mn":"Pseudo/3bf5uID/RubberHose_2-0006","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":6,"nm":"Math Stuff","mn":"Pseudo/3bf5uID/RubberHose_2-0007","ix":7,"v":0},{"ty":3,"nm":"A","mn":"Pseudo/3bf5uID/RubberHose_2-0008","ix":8,"v":{"a":0,"k":[0,0],"ix":8,"x":"var $bm_rt;\n$bm_rt = thisLayer.toComp([\n 0,\n 0,\n 0\n]);"}},{"ty":3,"nm":"B","mn":"Pseudo/3bf5uID/RubberHose_2-0009","ix":9,"v":{"a":0,"k":[0,0],"ix":9,"x":"var $bm_rt;\ntry {\n var b = thisLayer(2)('Admin')(2)('B')(2)(1)._name;\n $bm_rt = thisComp.layer(b).toComp([\n 0,\n 0,\n 0\n ]);\n} catch (err) {\n $bm_rt = value;\n}"}},{"ty":0,"nm":"Outer Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0010","ix":10,"v":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\nvar a = thisLayer(4)('RubberHose 2')('A');\nvar b = thisLayer(4)('RubberHose 2')('B');\nvar s = length(a, b);\n$bm_rt = mul(Math.sin(0.78539816339), s);"}},{"ty":0,"nm":"Inner Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0011","ix":11,"v":{"a":0,"k":0,"ix":11,"x":"var $bm_rt;\nvar eff = thisLayer(4)('RubberHose 2');\nvar bendRad = eff('Bend Radius');\nvar hoseLength = div(eff('Hose Length'), 2);\nvar realism = eff('Realism');\nvar bendDir = div(eff('Bend Direction'), 100);\nvar sFac = eff('Parent Scale');\nvar straight = eff('Straight');\nvar autoFlop = eff('AutoFlop');\nvar roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\nvar innerRad;\nif (hoseLength > straight) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n} else {\n innerRad = straight;\n}\ninnerRad *= Math.abs(sFac);\ninnerRad = linear(Math.abs(autoFlop), mul(straight, Math.max(Math.abs(sFac), 0.001)), innerRad);\n$bm_rt = innerRad;"}},{"ty":0,"nm":"Straight","mn":"Pseudo/3bf5uID/RubberHose_2-0012","ix":12,"v":{"a":0,"k":0,"ix":12,"x":"var $bm_rt;\nvar sFac = thisLayer(4)('RubberHose 2')('Parent Scale');\nvar outerRad = div(thisLayer(4)('RubberHose 2')('Outer Radius'), Math.max(Math.abs(sFac), 0.001));\n;\n$bm_rt = div(mul(1.4142135623731, outerRad), 2);"}},{"ty":0,"nm":"Base Rotation","mn":"Pseudo/3bf5uID/RubberHose_2-0013","ix":13,"v":{"a":0,"k":0,"ix":13,"x":"var $bm_rt;\nvar a = thisLayer(4)('RubberHose 2')('A');\nvar b = thisLayer(4)('RubberHose 2')('B');\n$bm_rt = radiansToDegrees(Math.atan2(sub(a[1], b[1]), sub(a[0], b[0])));"}},{"ty":0,"nm":"AutoFlop","mn":"Pseudo/3bf5uID/RubberHose_2-0014","ix":14,"v":{"a":0,"k":0,"ix":14,"x":"var $bm_rt;\nvar hasAF = false, isEnabled = false, output;\ntry {\n var lyrAF = thisComp.layer(sum(thisLayer._name.split('::')[0], '::AutoFlop'));\n isEnabled = lyrAF(4)('Enable')(1);\n var falloffAngle = lyrAF(4)('Falloff')(1);\n hasAF = true;\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = thisLayer(4)('RubberHose 2')('B');\n} catch (e) {\n}\nif (hasAF && isEnabled == 1) {\n var threshRot = lyrAF('ADBE Transform Group')('ADBE Rotate Z');\n threshRot %= 360;\n var ctrlAngle = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var offsetAngle = sub(threshRot, ctrlAngle);\n offsetAngle %= 360;\n var sign = offsetAngle > 0 && offsetAngle < 180 || offsetAngle < -180 ? -1 : 1;\n var absAngle = Math.abs(offsetAngle);\n if (absAngle > 90) {\n absAngle = Math.abs(sub(absAngle, 180));\n }\n if (absAngle > 90) {\n absAngle = Math.abs(sub(absAngle, 180));\n }\n output = linear(absAngle, 0, falloffAngle, 0, 1);\n output *= sign;\n} else {\n output = 1;\n}\n$bm_rt = output;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n parentVal = sum(parentVal, eval([layerChain][0]).rotation);\n }\n return parentVal;\n}"}},{"ty":0,"nm":"Parent Scale","mn":"Pseudo/3bf5uID/RubberHose_2-0015","ix":15,"v":{"a":0,"k":0,"ix":15,"x":"var $bm_rt;\nvar sFactor = 1;\nvar scaleNorm = 0;\nvar layerChain = 'thisLayer';\nwhile (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n scaleNorm = div(eval(layerChain)('ADBE Transform Group')('ADBE Scale')[0], 100);\n sFactor = mul(sFactor, scaleNorm);\n}\n$bm_rt = sFactor;"}},{"ty":6,"nm":"","mn":"Pseudo/3bf5uID/RubberHose_2-0016","ix":16,"v":0}]}],"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left Leg::Ankle","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[20,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left Leg::Hip","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\nvar eff = thisLayer(4)('RubberHose 2');\nvar autoRotate = eff('Auto Rotate End');\nif (autoRotate == 1) {\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = eff('B');\n var s = length(a, b);\n var sFac = eff('Parent Scale');\n var autoFlop = 1;\n var realism = eff('Realism');\n var bendDir = div(eff('Bend Direction'), 100);\n var hoseLength = div(eff('Hose Length'), 2);\n var bendRad = eff('Bend Radius');\n var autoFlop = eff('AutoFlop');\n var baseRot = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var outerRad = mul(Math.sin(0.78539816339), s);\n var straight = div(mul(1.4142135623731, outerRad), 2);\n straight /= Math.max(Math.abs(sFac), 0.001);\n var roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\n var innerRad;\n if (hoseLength > straight) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n } else {\n innerRad = straight;\n }\n innerRad = linear(Math.abs(autoFlop), straight, innerRad);\n var flopDir = 1;\n if (bendDir < 0) {\n flopDir = -1;\n }\n flopDir *= autoFlop;\n var opp = mul(sub(innerRad, straight), flopDir);\n var theta = Math.atan(div(opp, Math.max(straight, 0.001)));\n var bendAngle = radiansToDegrees(theta);\n if (sFac < 0) {\n baseRot *= -1;\n }\n bendRad *= div(div(theta, $bm_neg(Math.PI)), linear(s, hoseLength, 0, 2, 0.9));\n var rotCalc = sub(sum(baseRot, bendAngle), bendRad);\n $bm_rt = rotCalc;\n} else {\n $bm_rt = value;\n}\n;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Circle","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-75,0],[75,0]],"c":false},"ix":2},"nm":"01","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-30],[0,30]],"c":false},"ix":2},"nm":"02","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[15,15],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ControlShape","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.560000002384,0,1],"ix":3,"x":"var $bm_rt;\nif (thisLayer.active) {\n try {\n var eff = thisLayer(4)('RubberHose 2');\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = eff('B');\n var straight = eff('Straight');\n var hoseLength = div(eff('Hose Length'), 2);\n if (straight > hoseLength) {\n $bm_rt = [\n 0.51,\n 0.83,\n 0.98,\n 1\n ];\n } else {\n $bm_rt = value;\n }\n } catch (err) {\n $bm_rt = value;\n }\n} else {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Control Point","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Left Leg::Hip","parent":7,"hd":true,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\ntry {\n var parentRot = hasParent ? parentTotal() : 0;\n var rotCalc = sub(thisLayer('ADBE Root Vectors Group')('Admin')('Transform')('Rotation'), parentRot);\n $bm_rt = sum(rotCalc, value);\n} catch (err) {\n $bm_rt = value;\n}\n;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n parentVal = sum(parentVal, eval([layerChain][0]).rotation);\n }\n return parentVal;\n}"},"p":{"a":0,"k":[-87.758,188.742,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left Leg::Ankle","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[20,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left Leg::Hip","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\ntry {\n var eff = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var autoRotate = eff('Auto Rotate Start');\n if (autoRotate == 1) {\n var a = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name).toComp([\n 0,\n 0,\n 0\n ]);\n var b = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var s = length(a, b);\n var sFac = eff('Parent Scale');\n var autoFlop = 1;\n var realism = eff('Realism');\n var bendDir = div(eff('Bend Direction'), 100);\n var hoseLength = div(eff('Hose Length'), 2);\n var bendRad = eff('Bend Radius');\n var autoFlop = eff('AutoFlop');\n var baseRot = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var outerRad = mul(Math.sin(0.78539816339), s);\n var straight = div(mul(1.4142135623731, outerRad), 2);\n straight /= Math.max(Math.abs(sFac), 0.001);\n var roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\n var innerRad;\n if (straight <= hoseLength) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n } else {\n innerRad = straight;\n }\n innerRad = linear(Math.abs(autoFlop), straight, innerRad);\n var flopDir = 1;\n if (bendDir < 0) {\n flopDir = -1;\n }\n flopDir *= autoFlop;\n var opp = mul(sub(innerRad, straight), flopDir);\n var theta = Math.atan(div(opp, Math.max(straight, 0.001)));\n var bendAngle = radiansToDegrees(theta);\n if (sFac < 0) {\n baseRot *= -1;\n }\n bendRad *= div(div(theta, $bm_neg(Math.PI)), linear(s, hoseLength, 0, 2, 0.9));\n var rotCalc = sum(sub(baseRot, bendAngle), bendRad);\n $bm_rt = rotCalc;\n } else {\n $bm_rt = 0;\n }\n ;\n} catch (err) {\n $bm_rt = value;\n}\n;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Circle","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-75,0],[75,0]],"c":false},"ix":2},"nm":"01","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-30],[0,30]],"c":false},"ix":2},"nm":"02","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[15,15],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ControlShape","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.560000002384,0,1],"ix":3,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name);\n $bm_rt = ctrl(2)('Control Point')(2)('Stroke 1')('Color');\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Control Point","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Left Leg","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\nvar r = 0;\nif (thisLayer.hasParent) {\n r = $bm_neg(parentTotal());\n}\n$bm_rt = r;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n parentVal = sum(parentVal, eval([layerChain][0]).rotation);\n }\n return parentVal;\n}"},"p":{"a":0,"k":[425,500,0],"ix":2,"x":"var $bm_rt;\nvar p = [\n 0,\n 0\n ];\ntry {\n if (thisLayer.hasParent) {\n p = parent.fromComp([\n 0,\n 0,\n 0\n ]);\n }\n $bm_rt = p;\n} catch (err) {\n $bm_rt = p;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6,"x":"var $bm_rt;\nvar s = [\n 100,\n 100\n ];\nif (hasParent) {\n var sFactor = parentTotal();\n s = [\n s[0] * sFactor[0],\n s[1] * sFactor[1]\n ];\n}\n$bm_rt = s;\nfunction parentTotal() {\n var sFactor = [\n 1,\n 1\n ];\n var scaleNorm = [\n 0,\n 0\n ];\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n scaleNorm = eval([layerChain][0]).scale;\n if (scaleNorm[0] != 0 && scaleNorm[1] != 0) {\n scaleNorm = [\n 100 / scaleNorm[0],\n 100 / scaleNorm[1]\n ];\n }\n sFactor = [\n sFactor[0] * scaleNorm[0],\n sFactor[1] * scaleNorm[1]\n ];\n }\n return sFactor;\n}"}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":4,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":500,"ix":6,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"is":{"a":0,"k":0,"ix":8,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"or":{"a":0,"k":113,"ix":7,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"os":{"a":0,"k":0,"ix":9,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"ix":1,"nm":"LineForCurve","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"e":{"a":0,"k":0,"ix":2,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"o":{"a":0,"k":-90,"ix":3,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"m":1,"ix":2,"nm":"Line Halfer","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"a":{"a":0,"k":[0,0],"ix":1,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"r":{"a":0,"k":45,"ix":6,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"o":{"a":0,"k":100,"ix":7,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"sk":{"a":0,"k":0,"ix":4,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"sa":{"a":0,"k":0,"ix":5,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"nm":"Transform"}],"nm":"Arc","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.219607843137,0.227873439415,0.678431372549,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":36,"ix":5,"x":"var $bm_rt;\nvar sFac = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2')('Parent Scale');\n$bm_rt = mul(value, sFac);"},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('A');\n} catch (err) {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"BaseHose","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Style","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left Leg::Ankle","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[200,200],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Left Leg::Hip","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":4,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":200,"ix":6,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Inner Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"is":{"a":0,"k":100,"ix":8,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Bend Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"or":{"a":0,"k":200,"ix":7,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Outer Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"LineForCurve","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"tm","s":{"a":0,"k":0.01,"ix":1},"e":{"a":0,"k":24.99,"ix":2},"o":{"a":0,"k":-90,"ix":3,"x":"var $bm_rt;\n$bm_rt = -90;"},"m":1,"ix":2,"nm":"Line Halfer","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1,"x":"var $bm_rt;\nvar s = thisProperty.propertyGroup(2)(2)(1)(7);\n$bm_rt = [\n -s,\n 0\n];"},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\nvar flop;\ntry {\n var eff = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var bendDir = eff('Bend Direction');\n var autoFlop = eff('AutoFlop');\n flop = bendDir > 0 ? 1 : -1;\n autoFlop > 0 ? 0 : flop *= -1;\n var s = flop == 1 ? [\n -100,\n 100\n ] : [\n 100,\n 100\n ];\n if (eff('Parent Scale') < 0) {\n s = [\n -s[0],\n s[1]\n ];\n }\n $bm_rt = s;\n} catch (err) {\n $bm_rt = value;\n}\n;"},"r":{"a":0,"k":45,"ix":6,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var baseRot = ctrl('Base Rotation');\n var flop = content('Admin').content('ArcMath').transform.scale[0];\n var rotOffset = flop < 0 ? -45 : 225;\n $bm_rt = sum(baseRot, rotOffset);\n} catch (err) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ArcMath","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('A');\n} catch (err) {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Right Leg::Ankle","hd":true,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\ntry {\n var parentRot = hasParent ? parentTotal() : 0;\n var rotCalc = sub(thisLayer('ADBE Root Vectors Group')('Admin')('Transform')('Rotation'), parentRot);\n $bm_rt = sum(rotCalc, value);\n} catch (err) {\n $bm_rt = value;\n}\n;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n parentVal = sum(parentVal, eval([layerChain][0]).rotation);\n }\n return parentVal;\n}"},"p":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":0,"s":[584.541,716.568,0],"e":[588,830,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":3,"s":[588,830,0],"e":[588,830,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.36,"y":1},"o":{"x":0.167,"y":0.321},"n":"0p36_1_0p167_0p321","t":26.334,"s":[588,830,0],"e":[584.541,683.568,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.36,"y":1},"o":{"x":0.167,"y":0.152},"n":"0p36_1_0p167_0p152","t":33,"s":[584.541,683.568,0],"e":[584.541,716.568,0],"to":[0,0,0],"ti":[0,0,0]},{"t":36.333751479904}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"RubberHose 2","np":18,"mn":"Pseudo/3bf5uID/RubberHose_2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Hose Length","mn":"Pseudo/3bf5uID/RubberHose_2-0001","ix":1,"v":{"a":0,"k":280,"ix":1}},{"ty":0,"nm":"Bend Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0002","ix":2,"v":{"a":0,"k":40,"ix":2}},{"ty":0,"nm":"Realism","mn":"Pseudo/3bf5uID/RubberHose_2-0003","ix":3,"v":{"a":0,"k":0,"ix":3}},{"ty":0,"nm":"Bend Direction","mn":"Pseudo/3bf5uID/RubberHose_2-0004","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":7,"nm":"Auto Rotate Start","mn":"Pseudo/3bf5uID/RubberHose_2-0005","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":7,"nm":"Auto Rotate End","mn":"Pseudo/3bf5uID/RubberHose_2-0006","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":6,"nm":"Math Stuff","mn":"Pseudo/3bf5uID/RubberHose_2-0007","ix":7,"v":0},{"ty":3,"nm":"A","mn":"Pseudo/3bf5uID/RubberHose_2-0008","ix":8,"v":{"a":0,"k":[0,0],"ix":8,"x":"var $bm_rt;\n$bm_rt = thisLayer.toComp([\n 0,\n 0,\n 0\n]);"}},{"ty":3,"nm":"B","mn":"Pseudo/3bf5uID/RubberHose_2-0009","ix":9,"v":{"a":0,"k":[0,0],"ix":9,"x":"var $bm_rt;\ntry {\n var b = thisLayer(2)('Admin')(2)('B')(2)(1)._name;\n $bm_rt = thisComp.layer(b).toComp([\n 0,\n 0,\n 0\n ]);\n} catch (err) {\n $bm_rt = value;\n}"}},{"ty":0,"nm":"Outer Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0010","ix":10,"v":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\nvar a = thisLayer(4)('RubberHose 2')('A');\nvar b = thisLayer(4)('RubberHose 2')('B');\nvar s = length(a, b);\n$bm_rt = mul(Math.sin(0.78539816339), s);"}},{"ty":0,"nm":"Inner Radius","mn":"Pseudo/3bf5uID/RubberHose_2-0011","ix":11,"v":{"a":0,"k":0,"ix":11,"x":"var $bm_rt;\nvar eff = thisLayer(4)('RubberHose 2');\nvar bendRad = eff('Bend Radius');\nvar hoseLength = div(eff('Hose Length'), 2);\nvar realism = eff('Realism');\nvar bendDir = div(eff('Bend Direction'), 100);\nvar sFac = eff('Parent Scale');\nvar straight = eff('Straight');\nvar autoFlop = eff('AutoFlop');\nvar roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\nvar innerRad;\nif (hoseLength > straight) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n} else {\n innerRad = straight;\n}\ninnerRad *= Math.abs(sFac);\ninnerRad = linear(Math.abs(autoFlop), mul(straight, Math.max(Math.abs(sFac), 0.001)), innerRad);\n$bm_rt = innerRad;"}},{"ty":0,"nm":"Straight","mn":"Pseudo/3bf5uID/RubberHose_2-0012","ix":12,"v":{"a":0,"k":0,"ix":12,"x":"var $bm_rt;\nvar sFac = thisLayer(4)('RubberHose 2')('Parent Scale');\nvar outerRad = div(thisLayer(4)('RubberHose 2')('Outer Radius'), Math.max(Math.abs(sFac), 0.001));\n;\n$bm_rt = div(mul(1.4142135623731, outerRad), 2);"}},{"ty":0,"nm":"Base Rotation","mn":"Pseudo/3bf5uID/RubberHose_2-0013","ix":13,"v":{"a":0,"k":0,"ix":13,"x":"var $bm_rt;\nvar a = thisLayer(4)('RubberHose 2')('A');\nvar b = thisLayer(4)('RubberHose 2')('B');\n$bm_rt = radiansToDegrees(Math.atan2(sub(a[1], b[1]), sub(a[0], b[0])));"}},{"ty":0,"nm":"AutoFlop","mn":"Pseudo/3bf5uID/RubberHose_2-0014","ix":14,"v":{"a":0,"k":0,"ix":14,"x":"var $bm_rt;\nvar hasAF = false, isEnabled = false, output;\ntry {\n var lyrAF = thisComp.layer(sum(thisLayer._name.split('::')[0], '::AutoFlop'));\n isEnabled = lyrAF(4)('Enable')(1);\n var falloffAngle = lyrAF(4)('Falloff')(1);\n hasAF = true;\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = thisLayer(4)('RubberHose 2')('B');\n} catch (e) {\n}\nif (hasAF && isEnabled == 1) {\n var threshRot = lyrAF('ADBE Transform Group')('ADBE Rotate Z');\n threshRot %= 360;\n var ctrlAngle = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var offsetAngle = sub(threshRot, ctrlAngle);\n offsetAngle %= 360;\n var sign = offsetAngle > 0 && offsetAngle < 180 || offsetAngle < -180 ? -1 : 1;\n var absAngle = Math.abs(offsetAngle);\n if (absAngle > 90) {\n absAngle = Math.abs(sub(absAngle, 180));\n }\n if (absAngle > 90) {\n absAngle = Math.abs(sub(absAngle, 180));\n }\n output = linear(absAngle, 0, falloffAngle, 0, 1);\n output *= sign;\n} else {\n output = 1;\n}\n$bm_rt = output;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n parentVal = sum(parentVal, eval([layerChain][0]).rotation);\n }\n return parentVal;\n}"}},{"ty":0,"nm":"Parent Scale","mn":"Pseudo/3bf5uID/RubberHose_2-0015","ix":15,"v":{"a":0,"k":0,"ix":15,"x":"var $bm_rt;\nvar sFactor = 1;\nvar scaleNorm = 0;\nvar layerChain = 'thisLayer';\nwhile (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n scaleNorm = div(eval(layerChain)('ADBE Transform Group')('ADBE Scale')[0], 100);\n sFactor = mul(sFactor, scaleNorm);\n}\n$bm_rt = sFactor;"}},{"ty":6,"nm":"","mn":"Pseudo/3bf5uID/RubberHose_2-0016","ix":16,"v":0}]}],"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Right Leg::Ankle","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[20,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Right Leg::Hip","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\nvar eff = thisLayer(4)('RubberHose 2');\nvar autoRotate = eff('Auto Rotate End');\nif (autoRotate == 1) {\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = eff('B');\n var s = length(a, b);\n var sFac = eff('Parent Scale');\n var autoFlop = 1;\n var realism = eff('Realism');\n var bendDir = div(eff('Bend Direction'), 100);\n var hoseLength = div(eff('Hose Length'), 2);\n var bendRad = eff('Bend Radius');\n var autoFlop = eff('AutoFlop');\n var baseRot = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var outerRad = mul(Math.sin(0.78539816339), s);\n var straight = div(mul(1.4142135623731, outerRad), 2);\n straight /= Math.max(Math.abs(sFac), 0.001);\n var roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\n var innerRad;\n if (hoseLength > straight) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n } else {\n innerRad = straight;\n }\n innerRad = linear(Math.abs(autoFlop), straight, innerRad);\n var flopDir = 1;\n if (bendDir < 0) {\n flopDir = -1;\n }\n flopDir *= autoFlop;\n var opp = mul(sub(innerRad, straight), flopDir);\n var theta = Math.atan(div(opp, Math.max(straight, 0.001)));\n var bendAngle = radiansToDegrees(theta);\n if (sFac < 0) {\n baseRot *= -1;\n }\n bendRad *= div(div(theta, $bm_neg(Math.PI)), linear(s, hoseLength, 0, 2, 0.9));\n var rotCalc = sub(sum(baseRot, bendAngle), bendRad);\n $bm_rt = rotCalc;\n} else {\n $bm_rt = value;\n}\n;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Circle","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-75,0],[75,0]],"c":false},"ix":2},"nm":"01","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-30],[0,30]],"c":false},"ix":2},"nm":"02","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[15,15],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ControlShape","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.560000002384,0,1],"ix":3,"x":"var $bm_rt;\nif (thisLayer.active) {\n try {\n var eff = thisLayer(4)('RubberHose 2');\n var a = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var b = eff('B');\n var straight = eff('Straight');\n var hoseLength = div(eff('Hose Length'), 2);\n if (straight > hoseLength) {\n $bm_rt = [\n 0.51,\n 0.83,\n 0.98,\n 1\n ];\n } else {\n $bm_rt = value;\n }\n } catch (err) {\n $bm_rt = value;\n }\n} else {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Control Point","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Right Leg::Hip","parent":7,"hd":true,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\ntry {\n var parentRot = hasParent ? parentTotal() : 0;\n var rotCalc = sub(thisLayer('ADBE Root Vectors Group')('Admin')('Transform')('Rotation'), parentRot);\n $bm_rt = sum(rotCalc, value);\n} catch (err) {\n $bm_rt = value;\n}\n;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n parentVal = sum(parentVal, eval([layerChain][0]).rotation);\n }\n return parentVal;\n}"},"p":{"a":0,"k":[-12.758,188.742,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Right Leg::Ankle","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[20,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Right Leg::Hip","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6,"x":"var $bm_rt;\ntry {\n var eff = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var autoRotate = eff('Auto Rotate Start');\n if (autoRotate == 1) {\n var a = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name).toComp([\n 0,\n 0,\n 0\n ]);\n var b = thisLayer.toComp([\n 0,\n 0,\n 0\n ]);\n var s = length(a, b);\n var sFac = eff('Parent Scale');\n var autoFlop = 1;\n var realism = eff('Realism');\n var bendDir = div(eff('Bend Direction'), 100);\n var hoseLength = div(eff('Hose Length'), 2);\n var bendRad = eff('Bend Radius');\n var autoFlop = eff('AutoFlop');\n var baseRot = $bm_neg(radiansToDegrees(Math.atan2(sub(b[0], a[0]), sub(b[1], a[1]))));\n var outerRad = mul(Math.sin(0.78539816339), s);\n var straight = div(mul(1.4142135623731, outerRad), 2);\n straight /= Math.max(Math.abs(sFac), 0.001);\n var roundShrink = linear(Math.abs(bendRad), 0, 100, 1, 0.87);\n var innerRad;\n if (straight <= hoseLength) {\n innerRad = sum(straight, mul(Math.sqrt(sub(Math.pow(hoseLength, 2), Math.pow(straight, 2))), roundShrink));\n innerRad = linear(realism, 0, 100, hoseLength, innerRad);\n innerRad = linear(Math.abs(bendDir), straight, innerRad);\n } else {\n innerRad = straight;\n }\n innerRad = linear(Math.abs(autoFlop), straight, innerRad);\n var flopDir = 1;\n if (bendDir < 0) {\n flopDir = -1;\n }\n flopDir *= autoFlop;\n var opp = mul(sub(innerRad, straight), flopDir);\n var theta = Math.atan(div(opp, Math.max(straight, 0.001)));\n var bendAngle = radiansToDegrees(theta);\n if (sFac < 0) {\n baseRot *= -1;\n }\n bendRad *= div(div(theta, $bm_neg(Math.PI)), linear(s, hoseLength, 0, 2, 0.9));\n var rotCalc = sum(sub(baseRot, bendAngle), bendRad);\n $bm_rt = rotCalc;\n } else {\n $bm_rt = 0;\n }\n ;\n} catch (err) {\n $bm_rt = value;\n}\n;"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Circle","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-75,0],[75,0]],"c":false},"ix":2},"nm":"01","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-30],[0,30]],"c":false},"ix":2},"nm":"02","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[15,15],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ControlShape","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.560000002384,0,1],"ix":3,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name);\n $bm_rt = ctrl(2)('Control Point')(2)('Stroke 1')('Color');\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Control Point","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"Right Leg","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10,"x":"var $bm_rt;\nvar r = 0;\nif (thisLayer.hasParent) {\n r = $bm_neg(parentTotal());\n}\n$bm_rt = r;\nfunction parentTotal() {\n var parentVal = 0;\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n parentVal = sum(parentVal, eval([layerChain][0]).rotation);\n }\n return parentVal;\n}"},"p":{"a":0,"k":[500,500,0],"ix":2,"x":"var $bm_rt;\nvar p = [\n 0,\n 0\n ];\ntry {\n if (thisLayer.hasParent) {\n p = parent.fromComp([\n 0,\n 0,\n 0\n ]);\n }\n $bm_rt = p;\n} catch (err) {\n $bm_rt = p;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6,"x":"var $bm_rt;\nvar s = [\n 100,\n 100\n ];\nif (hasParent) {\n var sFactor = parentTotal();\n s = [\n s[0] * sFactor[0],\n s[1] * sFactor[1]\n ];\n}\n$bm_rt = s;\nfunction parentTotal() {\n var sFactor = [\n 1,\n 1\n ];\n var scaleNorm = [\n 0,\n 0\n ];\n var layerChain = 'thisLayer';\n while (eval([layerChain][0]).hasParent) {\n layerChain = sum(layerChain, '.parent');\n scaleNorm = eval([layerChain][0]).scale;\n if (scaleNorm[0] != 0 && scaleNorm[1] != 0) {\n scaleNorm = [\n 100 / scaleNorm[0],\n 100 / scaleNorm[1]\n ];\n }\n sFactor = [\n sFactor[0] * scaleNorm[0],\n sFactor[1] * scaleNorm[1]\n ];\n }\n return sFactor;\n}"}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":4,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":500,"ix":6,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"is":{"a":0,"k":0,"ix":8,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"or":{"a":0,"k":113,"ix":7,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"os":{"a":0,"k":0,"ix":9,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"ix":1,"nm":"LineForCurve","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"e":{"a":0,"k":0,"ix":2,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"o":{"a":0,"k":-90,"ix":3,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(1).propertyIndex;\n$bm_rt = thisLayer(2)('Admin')(2)('ArcMath')(2)(grp)(p);"},"m":1,"ix":2,"nm":"Line Halfer","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"a":{"a":0,"k":[0,0],"ix":1,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"r":{"a":0,"k":45,"ix":6,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"o":{"a":0,"k":100,"ix":7,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"sk":{"a":0,"k":0,"ix":4,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"sa":{"a":0,"k":0,"ix":5,"x":"var $bm_rt;\nvar p = thisProperty.propertyIndex;\nvar grp = thisProperty.propertyGroup(2).propertyIndex;\n$bm_rt = content('Admin').content('ArcMath')('ADBE Vector Transform Group')(p);"},"nm":"Transform"}],"nm":"Arc","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.219607843137,0.227873439415,0.678431372549,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":36,"ix":5,"x":"var $bm_rt;\nvar sFac = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2')('Parent Scale');\n$bm_rt = mul(value, sFac);"},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('A');\n} catch (err) {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"BaseHose","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Style","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Right Leg::Ankle","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[135,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[200,200],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Right Leg::Hip","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"2.04","np":0,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false,"cl":"04"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Version","np":1,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":4,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":200,"ix":6,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Inner Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"is":{"a":0,"k":100,"ix":8,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Bend Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"or":{"a":0,"k":200,"ix":7,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('Outer Radius');\n} catch (err) {\n $bm_rt = value;\n}"},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"LineForCurve","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"tm","s":{"a":0,"k":0.01,"ix":1},"e":{"a":0,"k":24.99,"ix":2},"o":{"a":0,"k":-90,"ix":3,"x":"var $bm_rt;\n$bm_rt = -90;"},"m":1,"ix":2,"nm":"Line Halfer","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1,"x":"var $bm_rt;\nvar s = thisProperty.propertyGroup(2)(2)(1)(7);\n$bm_rt = [\n -s,\n 0\n];"},"s":{"a":0,"k":[100,100],"ix":3,"x":"var $bm_rt;\nvar flop;\ntry {\n var eff = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var bendDir = eff('Bend Direction');\n var autoFlop = eff('AutoFlop');\n flop = bendDir > 0 ? 1 : -1;\n autoFlop > 0 ? 0 : flop *= -1;\n var s = flop == 1 ? [\n -100,\n 100\n ] : [\n 100,\n 100\n ];\n if (eff('Parent Scale') < 0) {\n s = [\n -s[0],\n s[1]\n ];\n }\n $bm_rt = s;\n} catch (err) {\n $bm_rt = value;\n}\n;"},"r":{"a":0,"k":45,"ix":6,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n var baseRot = ctrl('Base Rotation');\n var flop = content('Admin').content('ArcMath').transform.scale[0];\n var rotOffset = flop < 0 ? -45 : 225;\n $bm_rt = sum(baseRot, rotOffset);\n} catch (err) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"ArcMath","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\ntry {\n var ctrl = thisComp.layer(thisLayer(2)('Admin')(2)('A')(2)(1)._name)(4)('RubberHose 2');\n $bm_rt = ctrl('A');\n} catch (err) {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Admin","np":4,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/red_box.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/red_box.json deleted file mode 100644 index 65bb77ce..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/red_box.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.5.6","fr":29.9700012207031,"ip":0,"op":60.0000024438501,"w":612,"h":792,"ddd":0,"assets":[],"layers":[{"ddd":0,"ind":0,"ty":4,"nm":"Line Box Outlines","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[306,396,0]},"a":{"a":0,"k":[306,396,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[194.5,441.875],[503.125,441.875]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.979]},"o":{"x":[0.333],"y":[0]},"n":["0_0p979_0p333_0"],"t":0,"s":[50],"e":[0]},{"t":30.0000012219251}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.004],"y":[0.919]},"o":{"x":[0.333],"y":[0]},"n":["0p004_0p919_0p333_0"],"t":0,"s":[50],"e":[100]},{"t":30.0000012219251}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":0,"k":[0.91,0.23,0.23,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":15},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Back bot","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[194.5,144.5],[500.25,144.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.91,0.23,0.23,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":15},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.979]},"o":{"x":[0.333],"y":[0]},"n":["0_0p979_0p333_0"],"t":0,"s":[50],"e":[0]},{"t":30.0000012219251}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.004],"y":[0.919]},"o":{"x":[0.333],"y":[0]},"n":["0p004_0p919_0p333_0"],"t":0,"s":[50],"e":[100]},{"t":30.0000012219251}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Back top","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[405,238],[101,238]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.91,0.23,0.23,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":15},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.979]},"o":{"x":[0.333],"y":[0]},"n":["0_0p979_0p333_0"],"t":0,"s":[50],"e":[0]},{"t":30.0000012219251}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.004],"y":[0.919]},"o":{"x":[0.333],"y":[0]},"n":["0p004_0p919_0p333_0"],"t":0,"s":[50],"e":[100]},{"t":30.0000012219251}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Front top","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[101,540],[405,540]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.91,0.23,0.23,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":15},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.979]},"o":{"x":[0.333],"y":[0]},"n":["0_0p979_0p333_0"],"t":0,"s":[50],"e":[0]},{"t":30.0000012219251}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.004],"y":[0.919]},"o":{"x":[0.333],"y":[0]},"n":["0p004_0p919_0p333_0"],"t":0,"s":[50],"e":[100]},{"t":30.0000012219251}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Front bot","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[47.906,-47.906],[-47.907,47.906]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":23,"s":[50],"e":[0]},{"t":45.0000018328876}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":23,"s":[50],"e":[100]},{"t":45.0000018328876}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":0,"k":[0.91,0.23,0.23,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":15},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.985]},"o":{"x":[0.333],"y":[0]},"n":["0_0p985_0p333_0"],"t":23,"s":[50],"e":[0]},{"t":45.0000018328876}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.004],"y":[0.941]},"o":{"x":[0.333],"y":[0]},"n":["0p004_0p941_0p333_0"],"t":23,"s":[50],"e":[100]},{"t":45.0000018328876}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":4,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[146.594,489.781],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Bot left","np":4,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[194.5,144.5],[194.5,441.875]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":23,"s":[50],"e":[0]},{"t":45.0000018328876}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":23,"s":[50],"e":[100]},{"t":45.0000018328876}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":0,"k":[0.91,0.23,0.23,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":15},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.985]},"o":{"x":[0.333],"y":[0]},"n":["0_0p985_0p333_0"],"t":23,"s":[50],"e":[0]},{"t":45.0000018328876}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.004],"y":[0.941]},"o":{"x":[0.333],"y":[0]},"n":["0p004_0p941_0p333_0"],"t":23,"s":[50],"e":[100]},{"t":45.0000018328876}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":4,"nm":"Trim Paths 3","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Back left","np":4,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[500.25,144.5],[500.25,441.875]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.91,0.23,0.23,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":15},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.985]},"o":{"x":[0.333],"y":[0]},"n":["0_0p985_0p333_0"],"t":23,"s":[50],"e":[0]},{"t":45.0000018328876}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.004],"y":[0.941]},"o":{"x":[0.333],"y":[0]},"n":["0p004_0p941_0p333_0"],"t":23,"s":[50],"e":[100]},{"t":45.0000018328876}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Back right","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-49.063,49.063],[49.063,-49.063]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.91,0.23,0.23,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":15},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.985]},"o":{"x":[0.333],"y":[0]},"n":["0_0p985_0p333_0"],"t":23,"s":[50],"e":[0]},{"t":45.0000018328876}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.004],"y":[0.941]},"o":{"x":[0.333],"y":[0]},"n":["0p004_0p941_0p333_0"],"t":23,"s":[50],"e":[100]},{"t":45.0000018328876}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[454.063,490.938],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Bot right","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-47.625,47.625],[47.625,-47.625]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.91,0.23,0.23,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":15},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.985]},"o":{"x":[0.333],"y":[0]},"n":["0_0p985_0p333_0"],"t":23,"s":[50],"e":[0]},{"t":45.0000018328876}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.004],"y":[0.941]},"o":{"x":[0.333],"y":[0]},"n":["0p004_0p941_0p333_0"],"t":23,"s":[50],"e":[100]},{"t":45.0000018328876}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[452.625,190.375],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Top right","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-46.75,46.75],[46.75,-46.75]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.91,0.23,0.23,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":15},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.985]},"o":{"x":[0.333],"y":[0]},"n":["0_0p985_0p333_0"],"t":23,"s":[50],"e":[0]},{"t":45.0000018328876}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.004],"y":[0.941]},"o":{"x":[0.333],"y":[0]},"n":["0p004_0p941_0p333_0"],"t":23,"s":[50],"e":[100]},{"t":45.0000018328876}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[147.75,191.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Top left","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[405,542],[405,238]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.91,0.23,0.23,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":15},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.985]},"o":{"x":[0.333],"y":[0]},"n":["0_0p985_0p333_0"],"t":23,"s":[50],"e":[0]},{"t":45.0000018328876}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.004],"y":[0.941]},"o":{"x":[0.333],"y":[0]},"n":["0p004_0p941_0p333_0"],"t":23,"s":[50],"e":[100]},{"t":45.0000018328876}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Front right","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[101,236],[101,540]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.91,0.23,0.23,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":15},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[0.985]},"o":{"x":[0.333],"y":[0]},"n":["0_0p985_0p333_0"],"t":23,"s":[50],"e":[0]},{"t":45.0000018328876}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.004],"y":[0.941]},"o":{"x":[0.333],"y":[0]},"n":["0p004_0p941_0p333_0"],"t":23,"s":[50],"e":[100]},{"t":45.0000018328876}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Front left","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":241.000009816131,"st":0,"bm":0,"sr":1}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/ripple_loading_animation.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/ripple_loading_animation.json deleted file mode 100644 index 1935a034..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/ripple_loading_animation.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.10.1","fr":60,"ip":0,"op":120,"w":800,"h":800,"nm":"loading_animation","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":23,"s":[20],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":34,"s":[100],"e":[20]},{"t":69}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0,0],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0_1_0p333_0","0_1_0p333_0"],"t":23,"s":[400,400],"e":[440,440]},{"i":{"x":[0.009,0.009],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p009_1_0p333_0","0p009_1_0p333_0"],"t":34,"s":[440,440],"e":[400,400]},{"t":59}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":23,"s":[5],"e":[10]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":34,"s":[10],"e":[5]},{"t":59}],"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0,0.627,1,0.5,0.496,0.314,1,1,0.992,0,1],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":1,"lj":1,"ml":4,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":16,"s":[20],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":27,"s":[100],"e":[20]},{"t":62}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":16,"s":[320,320],"e":[360,360]},{"i":{"x":[0.025,0.025],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p025_1_0p333_0","0p025_1_0p333_0"],"t":27,"s":[360,360],"e":[320,320]},{"t":52}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":16,"s":[5],"e":[10]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[10],"e":[5]},{"t":52}],"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0,0.627,1,0.5,0.496,0.314,1,1,0.992,0,1],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":1,"lj":1,"ml":4,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":9,"s":[20],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":20,"s":[100],"e":[20]},{"t":55}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":9,"s":[240,240],"e":[280,280]},{"i":{"x":[0.051,0.051],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p051_1_0p333_0","0p051_1_0p333_0"],"t":20,"s":[280,280],"e":[240,240]},{"t":45}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":9,"s":[5],"e":[10]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[10],"e":[5]},{"t":45}],"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0,0.627,1,0.5,0.496,0.314,1,1,0.992,0,1],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":1,"lj":1,"ml":4,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":2,"s":[20],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":13,"s":[100],"e":[20]},{"t":48}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":2,"s":[160,160],"e":[200,200]},{"i":{"x":[0.034,0.034],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p034_1_0p333_0","0p034_1_0p333_0"],"t":13,"s":[200,200],"e":[160,160]},{"t":38}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":2,"s":[5],"e":[10]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":13,"s":[10],"e":[5]},{"t":38}],"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0,0.627,1,0.5,0.496,0.314,1,1,0.992,0,1],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":1,"lj":1,"ml":4,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[20],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":11,"s":[100],"e":[20]},{"t":46}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0"],"t":0,"s":[80,80],"e":[120,120]},{"i":{"x":[0,0],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"n":["0_1_0p333_0","0_1_0p333_0"],"t":11,"s":[120,120],"e":[80,80]},{"t":36}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[5],"e":[10]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":11,"s":[10],"e":[5]},{"t":35}],"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0,0.627,1,0.5,0.496,0.314,1,1,0.992,0,1],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":1,"lj":1,"ml":4,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/settings.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/settings.json deleted file mode 100644 index 5dc781b5..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/settings.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.16","fr":29.9700012207031,"ip":0,"op":143.000005824509,"w":200,"h":100,"nm":"Composição 2","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"settings contornos","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2},"a":{"a":0,"k":[500,500,0],"ix":1},"s":{"a":0,"k":[10,10,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-48.351],[48.351,0],[0,48.351],[-48.35,0]],"o":[[0,48.351],[-48.35,0],[0,-48.351],[48.351,0]],"v":[[87.547,0],[0,87.546],[-87.547,0],[0,-87.546]],"c":true},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":15,"s":[0.36862745098,0.486274509804,0.701960784314,1],"e":[1,1,1,1]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":30,"s":[1,1,1,1],"e":[1,1,1,1]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":120,"s":[1,1,1,1],"e":[0.368627458811,0.486274510622,0.701960802078,1]},{"t":135.000005498663}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Preenchimento 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[508.477,496.992],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-17.498,0],[-30.346,-22.349],[2.857,-40.794],[0,0],[-0.017,-0.034],[-21.335,-0.186],[0,0],[-1.049,1.032],[-0.068,1.267],[-46.372,32.628],[0,0],[-36.939,-23.297],[-7.963,-4.615],[-0.981,26.154],[0,0],[18.376,16.162],[-4.04,40.134],[-35.266,20.186],[-0.372,1.86],[32.273,42.197],[5.022,3.314],[2.586,-2.35],[35.671,22.401],[2.925,1.707],[-14.454,69.043],[27.641,0],[0,0],[0,0],[4.97,-6.83],[31.816,-28.79],[3.753,-3.483],[32.104,3.432],[7.016,7.489],[2.839,-0.034],[10.498,-12.594],[-59.694,-56.194],[0,0],[20.084,-76.532],[33.981,-17.261],[4.919,-2.587],[-28.655,-54.809],[-6.34,-1.826],[-18.512,10.905],[-4.328,2.349],[-1.809,1.049]],"o":[[21.03,0],[59.34,43.685],[0,0],[-0.355,10.583],[6.526,6.847],[0,0],[57.412,0.693],[-0.034,-0.085],[3.11,-66.592],[0,0],[65.358,-46.221],[6.323,3.973],[27.268,-12.088],[0,0],[-14.251,-11.936],[-26.897,-23.583],[4.581,-45.51],[33.338,-19.086],[0.812,-4.057],[-21.368,-27.946],[-1.403,1.015],[-70.734,64.157],[-2.958,-1.843],[-23.989,-14.066],[-10.397,-7.607],[0,0],[0,0],[-28.029,-1.521],[0.186,54.47],[-3.111,2.807],[-38.325,35.671],[-22.536,-2.299],[-24.547,-22.045],[-15.03,1.031],[-35.807,42.924],[0,0],[29.788,27.067],[-8.689,33.118],[-4.902,2.485],[-7.946,4.192],[23.398,44.8],[10.295,2.958],[4.751,-2.806],[1.961,-1.048],[16.162,-9.399]],"v":[[-202.259,227.105],[-127.215,258.229],[-53.506,368.472],[-53.708,371.852],[-52.035,385.766],[15.52,393.137],[18.445,393.154],[88.266,382.317],[88.452,380.306],[145.39,266.141],[149.887,262.963],[290.374,264.079],[311.625,277.079],[390,171.942],[367.176,152.788],[330.88,121.631],[297.795,2.513],[359.569,-99.378],[396.846,-130.552],[363.812,-190.787],[325.757,-231.784],[319.807,-226.864],[153.691,-222.638],[144.849,-227.929],[90.835,-337.107],[18.682,-351.865],[18.209,-351.865],[15.469,-351.95],[-49.195,-339.456],[-93.792,-239.104],[-104.054,-229.721],[-208.666,-181.574],[-252.182,-202.452],[-290.084,-225.41],[-347.581,-173.476],[-322.544,-73.293],[-314.209,-65.533],[-279.705,73.652],[-354.479,140.346],[-369.271,147.953],[-360.582,213.294],[-313.583,268.965],[-270.88,253.563],[-257.237,245.753],[-251.607,242.574]],"c":true},"ix":2},"nm":"Caminho 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[98.662,0],[1.351,0.017],[0,0],[31.833,33.186],[-1.048,31.985],[-0.153,2.147],[-0.018,0.321],[26.982,19.881],[2.739,0.897],[1.961,-1.133],[2.807,-1.522],[3.737,-2.214],[46.829,13.388],[29.027,55.553],[-43.887,23.16],[-5.292,2.687],[-6.712,4.903],[11.598,10.532],[0,0],[-88.011,105.525],[-47.962,3.263],[-23.601,-20.844],[-17.227,16.044],[-3.382,3.06],[0,20.946],[-18.004,16.922],[-17.244,-0.93],[-35.992,-44.733],[5.63,-25.342],[-0.017,-1.369],[-4.582,-2.688],[-3.72,-2.333],[-21.369,19.374],[-32.19,-2.723],[-28.519,-37.294],[8.707,-43.144],[32.171,-18.427],[3.939,-15.755],[-4.43,-8.892],[-12.916,-10.802],[0,0],[46.711,-68.062],[54.521,30.025],[9.45,5.968],[3.754,0.389],[14.1,-9.975],[0,0],[1.911,-2.248],[0.423,-9.095]],"o":[[-1.352,0],[0,0],[-47.911,-0.407],[-18.123,-18.866],[0.085,-2.266],[0.017,-0.321],[-2.79,-3.703],[-13.592,-10.009],[-1.69,0.846],[-2.603,1.521],[-3.431,1.825],[-25.324,14.894],[-38.207,-10.939],[-56.685,-108.433],[5.325,-2.806],[10.279,-5.224],[7.235,-30.853],[0,0],[-59.086,-55.637],[34.86,-41.791],[41.385,-2.874],[5.46,-2.163],[4.057,-3.787],[16.297,-14.742],[0,-24.953],[39.965,-37.548],[25.68,0.067],[15.638,19.424],[-1.015,4.53],[2.756,2.367],[3.651,2.147],[35.924,22.536],[14.962,-13.575],[39.931,3.634],[35.774,46.778],[-8.875,43.988],[-5.343,3.043],[-5.664,22.637],[15.333,13.441],[0,0],[39.357,33.151],[-40.151,58.494],[-12.798,-7.032],[-9.112,-5.732],[0.034,0],[0,0],[-7.371,5.189],[-1.217,3.702],[-2.959,63.312]],"v":[[21.758,479.728],[17.702,479.711],[14.777,479.678],[-114.501,445.663],[-140.232,369.013],[-139.86,362.419],[-139.792,361.473],[-178.541,327.915],[-202.006,313.984],[-208.143,317.416],[-216.224,321.998],[-226.976,328.168],[-337.387,352.175],[-437.3,253.377],[-409.676,71.404],[-393.683,63.171],[-361.883,45.521],[-372.416,-1.46],[-381.866,-10.251],[-414.055,-228.926],[-295.951,-311.765],[-196.714,-268.96],[-163.021,-293.084],[-151.863,-303.295],[-135.566,-338.983],[-108.044,-402.988],[19.307,-438.422],[160.216,-389.632],[175.736,-320.217],[174.603,-311.579],[188.619,-302.602],[199.709,-295.941],[261.651,-290.971],[332.233,-319.321],[432.584,-243.364],[481.696,-113.443],[402.578,-24.249],[385.756,0.433],[390.659,58.944],[422.729,86.399],[449.795,109.121],[438.045,270.773],[277.221,357.043],[244.221,337.298],[218.896,323.316],[199.843,333.663],[195.195,336.926],[177.545,350.247],[174.908,384.346]],"c":true},"ix":2},"nm":"Caminho 4","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[1],"y":[0]},"n":["0p667_1_1_0"],"t":15,"s":[0.36862745098,0.486274509804,0.701960784314,1],"e":[1,1,1,1]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":30,"s":[1,1,1,1],"e":[1,1,1,1]},{"i":{"x":[0.05],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p05_1_0p333_0"],"t":120,"s":[1,1,1,1],"e":[0.368627458811,0.486274510622,0.701960802078,1]},{"t":135.000005498663}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Preenchimento 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[490.403,479.728],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Grupo 2","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":137.000005580124,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"settings","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,50,0],"ix":2},"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[56,56,100],"ix":6}},"ao":0,"w":100,"h":100,"ip":0,"op":6.00000024438501,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"settings","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,50,0],"ix":2},"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[56,56,100],"ix":6}},"ao":0,"w":100,"h":100,"ip":-0.30272728505761,"op":0,"st":-12.00000048877,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"settings","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,50,0],"ix":2},"a":{"a":0,"k":[50,50,0],"ix":1},"s":{"a":0,"k":[56,56,100],"ix":6}},"ao":0,"w":100,"h":100,"ip":6.00000024438501,"op":143.000005824509,"st":6.00000024438501,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Camada de forma 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[103,51,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[97.826,93.75,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[185.893,83.764],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":489,"ix":4},"nm":"Caminho do retângulo 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.36862745098,0.486274509804,0.701960784314,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":9,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Traçado 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-2.947,-2.161],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Retângulo 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143.000005824509,"st":-12.00000048877,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Camada de forma 2","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[103,51.12,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,93.447,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[185.893,83.764],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":489,"ix":4},"nm":"Caminho do retângulo 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.36862745098,0.486274509804,0.701960784314,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":9,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Traçado 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.36862745098,0.486274509804,0.701960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Preenchimento 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"fl","c":{"a":0,"k":[0.36862745098,0.486274509804,0.701960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Preenchimento 2","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2.947,-2.161],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Retângulo 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143.000005824509,"st":-12.00000048877,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Camada de forma 3","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,50,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":18,"s":[0,0,100],"e":[569,569,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":33,"s":[569,569,100],"e":[569,569,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":127,"s":[569,569,100],"e":[0,0,100]},{"t":142.000005783779}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[15.12,0],[0,-15.12],[-15.12,0],[0,15.12]],"o":[[-15.12,0],[0,15.12],[15.12,0],[0,-15.12]],"v":[[0,-27.376],[-27.376,0],[0,27.376],[27.376,0]],"c":true},"ix":2},"nm":"Caminho 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.36862745098,0.486274509804,0.701960784314,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":9,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Traçado 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.36862745098,0.486274509804,0.701960784314,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Preenchimento 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-0.955,1.286],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformar"}],"nm":"Elipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143.000005824509,"st":-12.00000048877,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/spin,_lil_loader_v2.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/spin,_lil_loader_v2.json deleted file mode 100644 index 64b71e8c..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/spin,_lil_loader_v2.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.16","fr":30,"ip":0,"op":50,"w":90,"h":90,"nm":"stick 2","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"stick 1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":6,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":21,"s":[100],"e":[0]},{"t":36}],"ix":11},"r":{"a":0,"k":45,"ix":10},"p":{"a":0,"k":[45,45,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.1,0],[0,0],[0,1.1],[0,0],[-1.1,0],[0,-1.1],[0,0]],"o":[[0,0],[-1.1,0],[0,0],[0,-1.1],[1.1,0],[0,0],[0,1.1]],"v":[[0,7.5],[0,7.5],[-2,5.5],[-2,-5.5],[0,-7.5],[2,-5.5],[2,5.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.752941191196,0.874509811401,0.086274512112,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":6,"op":186,"st":6,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"stick 8","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":3,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":18,"s":[100],"e":[0]},{"t":33}],"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[45,45,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.1,0],[0,0],[0,1.1],[0,0],[-1.1,0],[0,-1.1],[0,0]],"o":[[0,0],[-1.1,0],[0,0],[0,-1.1],[1.1,0],[0,0],[0,1.1]],"v":[[0,7.5],[0,7.5],[-2,5.5],[-2,-5.5],[0,-7.5],[2,-5.5],[2,5.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.752941191196,0.874509811401,0.086274512112,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":3,"op":183,"st":3,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"stick 7","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":6,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":21,"s":[100],"e":[0]},{"t":36}],"ix":11},"r":{"a":0,"k":135,"ix":10},"p":{"a":0,"k":[45,45,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.1,0],[0,0],[0,1.1],[0,0],[-1.1,0],[0,-1.1],[0,0]],"o":[[0,0],[-1.1,0],[0,0],[0,-1.1],[1.1,0],[0,0],[0,1.1]],"v":[[0,7.5],[0,7.5],[-2,5.5],[-2,-5.5],[0,-7.5],[2,-5.5],[2,5.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.752941191196,0.874509811401,0.086274512112,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":6,"op":186,"st":6,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"stick 6","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":9,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":24,"s":[100],"e":[0]},{"t":39}],"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[45,45,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.1,0],[0,0],[0,1.1],[0,0],[-1.1,0],[0,-1.1],[0,0]],"o":[[0,0],[-1.1,0],[0,0],[0,-1.1],[1.1,0],[0,0],[0,1.1]],"v":[[0,7.5],[0,7.5],[-2,5.5],[-2,-5.5],[0,-7.5],[2,-5.5],[2,5.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.752941191196,0.874509811401,0.086274512112,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":9,"op":189,"st":9,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"stick 5","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":12,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[100],"e":[0]},{"t":42}],"ix":11},"r":{"a":0,"k":225,"ix":10},"p":{"a":0,"k":[45,45,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.1,0],[0,0],[0,1.1],[0,0],[-1.1,0],[0,-1.1],[0,0]],"o":[[0,0],[-1.1,0],[0,0],[0,-1.1],[1.1,0],[0,0],[0,1.1]],"v":[[0,7.5],[0,7.5],[-2,5.5],[-2,-5.5],[0,-7.5],[2,-5.5],[2,5.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.752941191196,0.874509811401,0.086274512112,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":12,"op":192,"st":12,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"stick 4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":30,"s":[100],"e":[0]},{"t":45}],"ix":11},"r":{"a":0,"k":270,"ix":10},"p":{"a":0,"k":[45,45,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.1,0],[0,0],[0,1.1],[0,0],[-1.1,0],[0,-1.1],[0,0]],"o":[[0,0],[-1.1,0],[0,0],[0,-1.1],[1.1,0],[0,0],[0,1.1]],"v":[[0,7.5],[0,7.5],[-2,5.5],[-2,-5.5],[0,-7.5],[2,-5.5],[2,5.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.752941191196,0.874509811401,0.086274512112,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":15,"op":195,"st":15,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"stick 3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":17,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":32,"s":[100],"e":[0]},{"t":47}],"ix":11},"r":{"a":0,"k":315,"ix":10},"p":{"a":0,"k":[45,45,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.1,0],[0,0],[0,1.1],[0,0],[-1.1,0],[0,-1.1],[0,0]],"o":[[0,0],[-1.1,0],[0,0],[0,-1.1],[1.1,0],[0,0],[0,1.1]],"v":[[0,7.5],[0,7.5],[-2,5.5],[-2,-5.5],[0,-7.5],[2,-5.5],[2,5.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.752941191196,0.874509811401,0.086274512112,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":17,"op":197,"st":17,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"stick 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[100],"e":[0]},{"t":50}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[45,45,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.1,0],[0,0],[0,1.1],[0,0],[-1.1,0],[0,-1.1],[0,0]],"o":[[0,0],[-1.1,0],[0,0],[0,-1.1],[1.1,0],[0,0],[0,1.1]],"v":[[0,7.5],[0,7.5],[-2,5.5],[-2,-5.5],[0,-7.5],[2,-5.5],[2,5.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.752941191196,0.874509811401,0.086274512112,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,20],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":20,"op":200,"st":20,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/square_wheel.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/square_wheel.json deleted file mode 100644 index 1543adbe..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/square_wheel.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.20","fr":60,"ip":0,"op":120,"w":256,"h":256,"nm":"square wheel","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"roda","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[810]},{"t":119}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[-24,231.5,0],"e":[-21.87,229.6,0],"to":[0.35499998927116,-0.31666666269302,0],"ti":[-0.74666666984558,0.58666664361954,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":1,"s":[-21.87,229.6,0],"e":[-19.52,227.98,0],"to":[0.74666666984558,-0.58666664361954,0],"ti":[-0.8116666674614,0.49333333969116,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":2,"s":[-19.52,227.98,0],"e":[-17,226.64,0],"to":[0.8116666674614,-0.49333333969116,0],"ti":[-0.86333334445953,0.39500001072884,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":3,"s":[-17,226.64,0],"e":[-14.34,225.61,0],"to":[0.86333334445953,-0.39500001072884,0],"ti":[-0.90499997138977,0.28999999165535,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.166},"n":"0p833_0p833_0p167_0p166","t":4,"s":[-14.34,225.61,0],"e":[-11.57,224.9,0],"to":[0.90499997138977,-0.28999999165535,0],"ti":[-0.93333333730698,0.18166667222977,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":5,"s":[-11.57,224.9,0],"e":[-8.74,224.52,0],"to":[0.93333333730698,-0.18166667222977,0],"ti":[-0.94666665792465,0.07000000029802,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":6,"s":[-8.74,224.52,0],"e":[-5.89,224.48,0],"to":[0.94666665792465,-0.07000000029802,0],"ti":[-0.94833332300186,-0.04333333298564,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":7,"s":[-5.89,224.48,0],"e":[-3.05,224.78,0],"to":[0.94833332300186,0.04333333298564,0],"ti":[-0.9366666674614,-0.1566666662693,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":8,"s":[-3.05,224.78,0],"e":[-0.27,225.42,0],"to":[0.9366666674614,0.1566666662693,0],"ti":[-0.91166669130325,-0.26666668057442,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.167},"n":"0p833_0p834_0p167_0p167","t":9,"s":[-0.27,225.42,0],"e":[2.42,226.38,0],"to":[0.91166669130325,0.26666668057442,0],"ti":[-0.87333333492279,-0.37166666984558,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":10,"s":[2.42,226.38,0],"e":[4.97,227.65,0],"to":[0.87333333492279,0.37166666984558,0],"ti":[-0.82333332300186,-0.47333332896233,0]},{"i":{"x":0.833,"y":0.832},"o":{"x":0.167,"y":0.166},"n":"0p833_0p832_0p167_0p166","t":11,"s":[4.97,227.65,0],"e":[7.36,229.22,0],"to":[0.82333332300186,0.47333332896233,0],"ti":[-0.76333332061768,-0.56833332777023,0]},{"i":{"x":0.833,"y":0.847},"o":{"x":0.167,"y":0.166},"n":"0p833_0p847_0p167_0p166","t":12,"s":[7.36,229.22,0],"e":[9.55,231.06,0],"to":[0.76333332061768,0.56833332777023,0],"ti":[-0.71333330869675,-0.12999999523163,0]},{"i":{"x":0.833,"y":0.818},"o":{"x":0.167,"y":0.184},"n":"0p833_0p818_0p167_0p184","t":13,"s":[9.55,231.06,0],"e":[11.64,230,0],"to":[0.71333330869675,0.12999999523163,0],"ti":[-0.7316666841507,0.45833334326744,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.153},"n":"0p833_0p833_0p167_0p153","t":14,"s":[11.64,230,0],"e":[13.94,228.31,0],"to":[0.7316666841507,-0.45833334326744,0],"ti":[-0.79833334684372,0.51499998569489,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.167},"n":"0p833_0p834_0p167_0p167","t":15,"s":[13.94,228.31,0],"e":[16.43,226.91,0],"to":[0.79833334684372,-0.51499998569489,0],"ti":[-0.85333335399628,0.41666665673256,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":16,"s":[16.43,226.91,0],"e":[19.06,225.81,0],"to":[0.85333335399628,-0.41666665673256,0],"ti":[-0.89666664600372,0.3133333325386,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.166},"n":"0p833_0p834_0p167_0p166","t":17,"s":[19.06,225.81,0],"e":[21.81,225.03,0],"to":[0.89666664600372,-0.3133333325386,0],"ti":[-0.92666667699814,0.20499999821186,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":18,"s":[21.81,225.03,0],"e":[24.62,224.58,0],"to":[0.92666667699814,-0.20499999821186,0],"ti":[-0.94499999284744,0.09499999880791,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.166},"n":"0p833_0p834_0p167_0p166","t":19,"s":[24.62,224.58,0],"e":[27.48,224.46,0],"to":[0.94499999284744,-0.09499999880791,0],"ti":[-0.94999998807907,-0.01833333261311,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[27.48,224.46,0],"e":[30.32,224.69,0],"to":[0.94999998807907,0.01833333261311,0],"ti":[-0.93999999761581,-0.13166666030884,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.166},"n":"0p833_0p833_0p167_0p166","t":21,"s":[30.32,224.69,0],"e":[33.12,225.25,0],"to":[0.93999999761581,0.13166666030884,0],"ti":[-0.91833335161209,-0.24166665971279,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[33.12,225.25,0],"e":[35.83,226.14,0],"to":[0.91833335161209,0.24166665971279,0],"ti":[-0.88333332538605,-0.34833332896233,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":23,"s":[35.83,226.14,0],"e":[38.42,227.34,0],"to":[0.88333332538605,0.34833332896233,0],"ti":[-0.83666664361954,-0.45166665315628,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.166},"n":"0p833_0p833_0p167_0p166","t":24,"s":[38.42,227.34,0],"e":[40.85,228.85,0],"to":[0.83666664361954,0.45166665315628,0],"ti":[-0.77666664123535,-0.54833334684372,0]},{"i":{"x":0.833,"y":0.854},"o":{"x":0.167,"y":0.167},"n":"0p833_0p854_0p167_0p167","t":25,"s":[40.85,228.85,0],"e":[43.08,230.63,0],"to":[0.77666664123535,0.54833334684372,0],"ti":[-0.71833330392838,-0.26166665554047,0]},{"i":{"x":0.833,"y":0.806},"o":{"x":0.167,"y":0.194},"n":"0p833_0p806_0p167_0p194","t":26,"s":[43.08,230.63,0],"e":[45.16,230.42,0],"to":[0.71833330392838,0.26166665554047,0],"ti":[-0.72166669368744,0.32666665315628,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.146},"n":"0p833_0p833_0p167_0p146","t":27,"s":[45.16,230.42,0],"e":[47.41,228.67,0],"to":[0.72166669368744,-0.32666665315628,0],"ti":[-0.78333336114883,0.53666669130325,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.167},"n":"0p833_0p834_0p167_0p167","t":28,"s":[47.41,228.67,0],"e":[49.86,227.2,0],"to":[0.78333336114883,-0.53666669130325,0],"ti":[-0.84166663885117,0.43999999761581,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":29,"s":[49.86,227.2,0],"e":[52.46,226.03,0],"to":[0.84166663885117,-0.43999999761581,0],"ti":[-0.88833332061768,0.33833333849907,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.166},"n":"0p833_0p834_0p167_0p166","t":30,"s":[52.46,226.03,0],"e":[55.19,225.17,0],"to":[0.88833332061768,-0.33833333849907,0],"ti":[-0.92166668176651,0.23000000417233,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":31,"s":[55.19,225.17,0],"e":[57.99,224.65,0],"to":[0.92166668176651,-0.23000000417233,0],"ti":[-0.94166666269302,0.11833333224058,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.166},"n":"0p833_0p833_0p167_0p166","t":32,"s":[57.99,224.65,0],"e":[60.84,224.46,0],"to":[0.94166666269302,-0.11833333224058,0],"ti":[-0.94999998807907,0.0066666668281,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":33,"s":[60.84,224.46,0],"e":[63.69,224.61,0],"to":[0.94999998807907,-0.0066666668281,0],"ti":[-0.94333332777023,-0.10666666924953,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":34,"s":[63.69,224.61,0],"e":[66.5,225.1,0],"to":[0.94333332777023,0.10666666924953,0],"ti":[-0.92500001192093,-0.21666666865349,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":35,"s":[66.5,225.1,0],"e":[69.24,225.91,0],"to":[0.92500001192093,0.21666666865349,0],"ti":[-0.8933333158493,-0.32499998807907,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.167},"n":"0p833_0p834_0p167_0p167","t":36,"s":[69.24,225.91,0],"e":[71.86,227.05,0],"to":[0.8933333158493,0.32499998807907,0],"ti":[-0.84666669368744,-0.43000000715256,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":37,"s":[71.86,227.05,0],"e":[74.32,228.49,0],"to":[0.84666669368744,0.43000000715256,0],"ti":[-0.79000002145767,-0.52666664123535,0]},{"i":{"x":0.833,"y":0.851},"o":{"x":0.167,"y":0.166},"n":"0p833_0p851_0p167_0p166","t":38,"s":[74.32,228.49,0],"e":[76.6,230.21,0],"to":[0.79000002145767,0.52666664123535,0],"ti":[-0.72833335399628,-0.39166668057442,0]},{"i":{"x":0.833,"y":0.81},"o":{"x":0.167,"y":0.19},"n":"0p833_0p81_0p167_0p19","t":39,"s":[76.6,230.21,0],"e":[78.69,230.84,0],"to":[0.72833335399628,0.39166668057442,0],"ti":[-0.71499997377396,0.19666667282581,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.148},"n":"0p833_0p834_0p167_0p148","t":40,"s":[78.69,230.84,0],"e":[80.89,229.03,0],"to":[0.71499997377396,-0.19666667282581,0],"ti":[-0.7683333158493,0.55666667222977,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":41,"s":[80.89,229.03,0],"e":[83.3,227.5,0],"to":[0.7683333158493,-0.55666667222977,0],"ti":[-0.8299999833107,0.46166667342186,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[83.3,227.5,0],"e":[85.87,226.26,0],"to":[0.8299999833107,-0.46166667342186,0],"ti":[-0.87833333015442,0.36166667938232,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":43,"s":[85.87,226.26,0],"e":[88.57,225.33,0],"to":[0.87833333015442,-0.36166667938232,0],"ti":[-0.91500002145767,0.25499999523163,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":44,"s":[88.57,225.33,0],"e":[91.36,224.73,0],"to":[0.91500002145767,-0.25499999523163,0],"ti":[-0.93999999761581,0.14333333075047,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.166},"n":"0p833_0p834_0p167_0p166","t":45,"s":[91.36,224.73,0],"e":[94.21,224.47,0],"to":[0.93999999761581,-0.14333333075047,0],"ti":[-0.94999998807907,0.02999999932945,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":46,"s":[94.21,224.47,0],"e":[97.06,224.55,0],"to":[0.94999998807907,-0.02999999932945,0],"ti":[-0.94499999284744,-0.08166666328907,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":47,"s":[97.06,224.55,0],"e":[99.88,224.96,0],"to":[0.94499999284744,0.08166666328907,0],"ti":[-0.93000000715256,-0.19166666269302,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.166},"n":"0p833_0p833_0p167_0p166","t":48,"s":[99.88,224.96,0],"e":[102.64,225.7,0],"to":[0.93000000715256,0.19166666269302,0],"ti":[-0.90166664123535,-0.30166667699814,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.167},"n":"0p833_0p834_0p167_0p167","t":49,"s":[102.64,225.7,0],"e":[105.29,226.77,0],"to":[0.90166664123535,0.30166667699814,0],"ti":[-0.85833334922791,-0.4066666662693,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":50,"s":[105.29,226.77,0],"e":[107.79,228.14,0],"to":[0.85833334922791,0.4066666662693,0],"ti":[-0.80333334207535,-0.50499999523163,0]},{"i":{"x":0.833,"y":0.839},"o":{"x":0.167,"y":0.167},"n":"0p833_0p839_0p167_0p167","t":51,"s":[107.79,228.14,0],"e":[110.11,229.8,0],"to":[0.80333334207535,0.50499999523163,0],"ti":[-0.74000000953674,-0.52333331108093,0]},{"i":{"x":0.833,"y":0.825},"o":{"x":0.167,"y":0.173},"n":"0p833_0p825_0p167_0p173","t":52,"s":[110.11,229.8,0],"e":[112.23,231.28,0],"to":[0.74000000953674,0.52333331108093,0],"ti":[-0.71333330869675,0.06499999761581,0]},{"i":{"x":0.833,"y":0.835},"o":{"x":0.167,"y":0.159},"n":"0p833_0p835_0p167_0p159","t":53,"s":[112.23,231.28,0],"e":[114.39,229.41,0],"to":[0.71333330869675,-0.06499999761581,0],"ti":[-0.75333333015442,0.57833331823349,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.168},"n":"0p833_0p833_0p167_0p168","t":54,"s":[114.39,229.41,0],"e":[116.75,227.81,0],"to":[0.75333333015442,-0.57833331823349,0],"ti":[-0.81666666269302,0.48333331942558,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":55,"s":[116.75,227.81,0],"e":[119.29,226.51,0],"to":[0.81666666269302,-0.48333331942558,0],"ti":[-0.86833333969116,0.38333332538605,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":56,"s":[119.29,226.51,0],"e":[121.96,225.51,0],"to":[0.86833333969116,-0.38333332538605,0],"ti":[-0.90833336114883,0.27833333611488,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.166},"n":"0p833_0p834_0p167_0p166","t":57,"s":[121.96,225.51,0],"e":[124.74,224.84,0],"to":[0.90833336114883,-0.27833333611488,0],"ti":[-0.93500000238419,0.16833333671093,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":58,"s":[124.74,224.84,0],"e":[127.57,224.5,0],"to":[0.93500000238419,-0.16833333671093,0],"ti":[-0.94833332300186,0.05666666850448,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.166},"n":"0p833_0p834_0p167_0p166","t":59,"s":[127.57,224.5,0],"e":[130.43,224.5,0],"to":[0.94833332300186,-0.05666666850448,0],"ti":[-0.94833332300186,-0.05666666850448,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":60,"s":[130.43,224.5,0],"e":[133.26,224.84,0],"to":[0.94833332300186,0.05666666850448,0],"ti":[-0.93500000238419,-0.16833333671093,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.166},"n":"0p833_0p834_0p167_0p166","t":61,"s":[133.26,224.84,0],"e":[136.04,225.51,0],"to":[0.93500000238419,0.16833333671093,0],"ti":[-0.90833336114883,-0.27833333611488,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":62,"s":[136.04,225.51,0],"e":[138.71,226.51,0],"to":[0.90833336114883,0.27833333611488,0],"ti":[-0.86833333969116,-0.38333332538605,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":63,"s":[138.71,226.51,0],"e":[141.25,227.81,0],"to":[0.86833333969116,0.38333332538605,0],"ti":[-0.81666666269302,-0.48333331942558,0]},{"i":{"x":0.833,"y":0.832},"o":{"x":0.167,"y":0.167},"n":"0p833_0p832_0p167_0p167","t":64,"s":[141.25,227.81,0],"e":[143.61,229.41,0],"to":[0.81666666269302,0.48333331942558,0],"ti":[-0.75333333015442,-0.57833331823349,0]},{"i":{"x":0.833,"y":0.841},"o":{"x":0.167,"y":0.165},"n":"0p833_0p841_0p167_0p165","t":65,"s":[143.61,229.41,0],"e":[145.77,231.28,0],"to":[0.75333333015442,0.57833331823349,0],"ti":[-0.71333330869675,-0.06499999761581,0]},{"i":{"x":0.833,"y":0.827},"o":{"x":0.167,"y":0.175},"n":"0p833_0p827_0p167_0p175","t":66,"s":[145.77,231.28,0],"e":[147.89,229.8,0],"to":[0.71333330869675,0.06499999761581,0],"ti":[-0.74000000953674,0.52333331108093,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.161},"n":"0p833_0p833_0p167_0p161","t":67,"s":[147.89,229.8,0],"e":[150.21,228.14,0],"to":[0.74000000953674,-0.52333331108093,0],"ti":[-0.80333334207535,0.50499999523163,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":68,"s":[150.21,228.14,0],"e":[152.71,226.77,0],"to":[0.80333334207535,-0.50499999523163,0],"ti":[-0.85833334922791,0.4066666662693,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.166},"n":"0p833_0p833_0p167_0p166","t":69,"s":[152.71,226.77,0],"e":[155.36,225.7,0],"to":[0.85833334922791,-0.4066666662693,0],"ti":[-0.90166664123535,0.30166667699814,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.167},"n":"0p833_0p834_0p167_0p167","t":70,"s":[155.36,225.7,0],"e":[158.12,224.96,0],"to":[0.90166664123535,-0.30166667699814,0],"ti":[-0.93000000715256,0.19166666269302,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":71,"s":[158.12,224.96,0],"e":[160.94,224.55,0],"to":[0.93000000715256,-0.19166666269302,0],"ti":[-0.94499999284744,0.08166666328907,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":72,"s":[160.94,224.55,0],"e":[163.79,224.47,0],"to":[0.94499999284744,-0.08166666328907,0],"ti":[-0.94999998807907,-0.02999999932945,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.166},"n":"0p833_0p834_0p167_0p166","t":73,"s":[163.79,224.47,0],"e":[166.64,224.73,0],"to":[0.94999998807907,0.02999999932945,0],"ti":[-0.93999999761581,-0.14333333075047,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":74,"s":[166.64,224.73,0],"e":[169.43,225.33,0],"to":[0.93999999761581,0.14333333075047,0],"ti":[-0.91500002145767,-0.25499999523163,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":75,"s":[169.43,225.33,0],"e":[172.13,226.26,0],"to":[0.91500002145767,0.25499999523163,0],"ti":[-0.87833333015442,-0.36166667938232,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":76,"s":[172.13,226.26,0],"e":[174.7,227.5,0],"to":[0.87833333015442,0.36166667938232,0],"ti":[-0.8299999833107,-0.46166667342186,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":77,"s":[174.7,227.5,0],"e":[177.11,229.03,0],"to":[0.8299999833107,0.46166667342186,0],"ti":[-0.7683333158493,-0.55666667222977,0]},{"i":{"x":0.833,"y":0.852},"o":{"x":0.167,"y":0.166},"n":"0p833_0p852_0p167_0p166","t":78,"s":[177.11,229.03,0],"e":[179.31,230.84,0],"to":[0.7683333158493,0.55666667222977,0],"ti":[-0.71499997377396,-0.19666667282581,0]},{"i":{"x":0.833,"y":0.81},"o":{"x":0.167,"y":0.19},"n":"0p833_0p81_0p167_0p19","t":79,"s":[179.31,230.84,0],"e":[181.4,230.21,0],"to":[0.71499997377396,0.19666667282581,0],"ti":[-0.72833335399628,0.39166668057442,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.149},"n":"0p833_0p834_0p167_0p149","t":80,"s":[181.4,230.21,0],"e":[183.68,228.49,0],"to":[0.72833335399628,-0.39166668057442,0],"ti":[-0.79000002145767,0.52666664123535,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":81,"s":[183.68,228.49,0],"e":[186.14,227.05,0],"to":[0.79000002145767,-0.52666664123535,0],"ti":[-0.84666669368744,0.43000000715256,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.166},"n":"0p833_0p833_0p167_0p166","t":82,"s":[186.14,227.05,0],"e":[188.76,225.91,0],"to":[0.84666669368744,-0.43000000715256,0],"ti":[-0.8933333158493,0.32499998807907,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":83,"s":[188.76,225.91,0],"e":[191.5,225.1,0],"to":[0.8933333158493,-0.32499998807907,0],"ti":[-0.92500001192093,0.21666666865349,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":84,"s":[191.5,225.1,0],"e":[194.31,224.61,0],"to":[0.92500001192093,-0.21666666865349,0],"ti":[-0.94333332777023,0.10666666924953,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":85,"s":[194.31,224.61,0],"e":[197.16,224.46,0],"to":[0.94333332777023,-0.10666666924953,0],"ti":[-0.94999998807907,-0.0066666668281,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.167},"n":"0p833_0p834_0p167_0p167","t":86,"s":[197.16,224.46,0],"e":[200.01,224.65,0],"to":[0.94999998807907,0.0066666668281,0],"ti":[-0.94166666269302,-0.11833333224058,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":87,"s":[200.01,224.65,0],"e":[202.81,225.17,0],"to":[0.94166666269302,0.11833333224058,0],"ti":[-0.92166668176651,-0.23000000417233,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.166},"n":"0p833_0p834_0p167_0p166","t":88,"s":[202.81,225.17,0],"e":[205.54,226.03,0],"to":[0.92166668176651,0.23000000417233,0],"ti":[-0.88833332061768,-0.33833333849907,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":89,"s":[205.54,226.03,0],"e":[208.14,227.2,0],"to":[0.88833332061768,0.33833333849907,0],"ti":[-0.84166663885117,-0.43999999761581,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.166},"n":"0p833_0p833_0p167_0p166","t":90,"s":[208.14,227.2,0],"e":[210.59,228.67,0],"to":[0.84166663885117,0.43999999761581,0],"ti":[-0.78333336114883,-0.53666669130325,0]},{"i":{"x":0.833,"y":0.854},"o":{"x":0.167,"y":0.167},"n":"0p833_0p854_0p167_0p167","t":91,"s":[210.59,228.67,0],"e":[212.84,230.42,0],"to":[0.78333336114883,0.53666669130325,0],"ti":[-0.72166669368744,-0.32666665315628,0]},{"i":{"x":0.833,"y":0.806},"o":{"x":0.167,"y":0.194},"n":"0p833_0p806_0p167_0p194","t":92,"s":[212.84,230.42,0],"e":[214.92,230.63,0],"to":[0.72166669368744,0.32666665315628,0],"ti":[-0.71833330392838,0.26166665554047,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.146},"n":"0p833_0p833_0p167_0p146","t":93,"s":[214.92,230.63,0],"e":[217.15,228.85,0],"to":[0.71833330392838,-0.26166665554047,0],"ti":[-0.77666664123535,0.54833334684372,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.167},"n":"0p833_0p834_0p167_0p167","t":94,"s":[217.15,228.85,0],"e":[219.58,227.34,0],"to":[0.77666664123535,-0.54833334684372,0],"ti":[-0.83666664361954,0.45166665315628,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":95,"s":[219.58,227.34,0],"e":[222.17,226.14,0],"to":[0.83666664361954,-0.45166665315628,0],"ti":[-0.88333332538605,0.34833332896233,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":96,"s":[222.17,226.14,0],"e":[224.88,225.25,0],"to":[0.88333332538605,-0.34833332896233,0],"ti":[-0.91833335161209,0.24166665971279,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.167},"n":"0p833_0p834_0p167_0p167","t":97,"s":[224.88,225.25,0],"e":[227.68,224.69,0],"to":[0.91833335161209,-0.24166665971279,0],"ti":[-0.93999999761581,0.13166666030884,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":98,"s":[227.68,224.69,0],"e":[230.52,224.46,0],"to":[0.93999999761581,-0.13166666030884,0],"ti":[-0.94999998807907,0.01833333261311,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.166},"n":"0p833_0p834_0p167_0p166","t":99,"s":[230.52,224.46,0],"e":[233.38,224.58,0],"to":[0.94999998807907,-0.01833333261311,0],"ti":[-0.94499999284744,-0.09499999880791,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":100,"s":[233.38,224.58,0],"e":[236.19,225.03,0],"to":[0.94499999284744,0.09499999880791,0],"ti":[-0.92666667699814,-0.20499999821186,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.166},"n":"0p833_0p834_0p167_0p166","t":101,"s":[236.19,225.03,0],"e":[238.94,225.81,0],"to":[0.92666667699814,0.20499999821186,0],"ti":[-0.89666664600372,-0.3133333325386,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":102,"s":[238.94,225.81,0],"e":[241.57,226.91,0],"to":[0.89666664600372,0.3133333325386,0],"ti":[-0.85333335399628,-0.41666665673256,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.166},"n":"0p833_0p833_0p167_0p166","t":103,"s":[241.57,226.91,0],"e":[244.06,228.31,0],"to":[0.85333335399628,0.41666665673256,0],"ti":[-0.79833334684372,-0.51499998569489,0]},{"i":{"x":0.833,"y":0.847},"o":{"x":0.167,"y":0.167},"n":"0p833_0p847_0p167_0p167","t":104,"s":[244.06,228.31,0],"e":[246.36,230,0],"to":[0.79833334684372,0.51499998569489,0],"ti":[-0.7316666841507,-0.45833334326744,0]},{"i":{"x":0.833,"y":0.816},"o":{"x":0.167,"y":0.182},"n":"0p833_0p816_0p167_0p182","t":105,"s":[246.36,230,0],"e":[248.45,231.06,0],"to":[0.7316666841507,0.45833334326744,0],"ti":[-0.71333330869675,0.12999999523163,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.153},"n":"0p833_0p834_0p167_0p153","t":106,"s":[248.45,231.06,0],"e":[250.64,229.22,0],"to":[0.71333330869675,-0.12999999523163,0],"ti":[-0.76333332061768,0.56833332777023,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.168},"n":"0p833_0p834_0p167_0p168","t":107,"s":[250.64,229.22,0],"e":[253.03,227.65,0],"to":[0.76333332061768,-0.56833332777023,0],"ti":[-0.82333332300186,0.47333332896233,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":108,"s":[253.03,227.65,0],"e":[255.58,226.38,0],"to":[0.82333332300186,-0.47333332896233,0],"ti":[-0.87333333492279,0.37166666984558,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.166},"n":"0p833_0p833_0p167_0p166","t":109,"s":[255.58,226.38,0],"e":[258.27,225.42,0],"to":[0.87333333492279,-0.37166666984558,0],"ti":[-0.91166669130325,0.26666668057442,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":110,"s":[258.27,225.42,0],"e":[261.05,224.78,0],"to":[0.91166669130325,-0.26666668057442,0],"ti":[-0.9366666674614,0.1566666662693,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":111,"s":[261.05,224.78,0],"e":[263.89,224.48,0],"to":[0.9366666674614,-0.1566666662693,0],"ti":[-0.94833332300186,0.04333333298564,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":112,"s":[263.89,224.48,0],"e":[266.74,224.52,0],"to":[0.94833332300186,-0.04333333298564,0],"ti":[-0.94666665792465,-0.07000000029802,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":113,"s":[266.74,224.52,0],"e":[269.57,224.9,0],"to":[0.94666665792465,0.07000000029802,0],"ti":[-0.93333333730698,-0.18166667222977,0]},{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.167},"n":"0p833_0p834_0p167_0p167","t":114,"s":[269.57,224.9,0],"e":[272.34,225.61,0],"to":[0.93333333730698,0.18166667222977,0],"ti":[-0.90499997138977,-0.28999999165535,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":115,"s":[272.34,225.61,0],"e":[275,226.64,0],"to":[0.90499997138977,0.28999999165535,0],"ti":[-0.86333334445953,-0.39500001072884,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":116,"s":[275,226.64,0],"e":[277.52,227.98,0],"to":[0.86333334445953,0.39500001072884,0],"ti":[-0.8116666674614,-0.49333333969116,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":117,"s":[277.52,227.98,0],"e":[279.87,229.6,0],"to":[0.8116666674614,0.49333333969116,0],"ti":[-0.74666666984558,-0.58666664361954,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":118,"s":[279.87,229.6,0],"e":[282,231.5,0],"to":[0.74666666984558,0.58666664361954,0],"ti":[-0.35499998927116,-0.31666666269302,0]},{"t":119}],"ix":2},"a":{"a":0,"k":[-96,98.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[34,34],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.243137000589,0.082353001015,0.768627989526,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.378575882257,0.034678967794,0.803921568627,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-96,98.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"_square wheel","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[128,128,0],"ix":2},"a":{"a":0,"k":[128,128,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":256,"h":256,"ip":0,"op":120,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/starts_transparent.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/starts_transparent.json deleted file mode 100644 index 2735edf4..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/starts_transparent.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.5.6","fr":30,"ip":0,"op":91,"w":800,"h":800,"ddd":0,"assets":[],"layers":[{"ddd":0,"ind":0,"ty":3,"nm":"Master","ks":{"o":{"a":0,"k":0},"r":{"a":0,"k":0},"p":{"a":0,"k":[400,461.657,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"ip":0,"op":600,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"Star_03","parent":0,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":64,"s":[100],"e":[0]},{"t":84}]},"r":{"a":1,"k":[{"i":{"x":[0.006],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p006_1_0p167_0p167"],"t":14,"s":[-720],"e":[-1149]},{"t":90}]},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":14,"s":[-72.808,4.062,0],"e":[2.192,-72.938,0],"to":[7.80815124511719,-75.0615844726562,0],"ti":[0,0,0]},{"t":84}]},"a":{"a":0,"k":[231.37,449.226,0]},"s":{"a":1,"k":[{"i":{"x":[0,0,0.667],"y":[1,1,0.667]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_1_0p167_0p167","0_1_0p167_0p167","0p667_0p667_0p167_0p167"],"t":14,"s":[0,0,100],"e":[100,100,100]},{"t":54}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-36.571,-9.612],[-27.799,-1.99],[-36.683,5.428]],"c":false}},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ind":1,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[3.95,-9.308],[-4.935,-1.817],[3.838,5.731]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.79,0.56,0.22,1]},"o":{"a":1,"k":[{"t":14,"s":[100],"h":1},{"t":34,"s":[0],"h":1}]},"w":{"a":0,"k":2.641},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[247.846,433.746],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eyes_Closed","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":34,"s":[{"i":[[0.013,-0.202],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.096,-0.1],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.733,-0.323]],"c":true}],"e":[{"i":[[0.054,-2.972],[2.972,0.054],[-0.054,2.973],[-2.976,-0.054]],"o":[[-0.054,2.976],[-2.972,-0.054],[0.054,-2.973],[2.971,0.054]],"v":[[-18.385,0.097],[-23.869,5.385],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":44,"s":[{"i":[[0.054,-2.972],[2.972,0.054],[-0.054,2.973],[-2.976,-0.054]],"o":[[-0.054,2.976],[-2.972,-0.054],[0.054,-2.973],[2.971,0.054]],"v":[[-18.385,0.097],[-23.869,5.385],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.054,-2.972],[2.972,0.054],[-0.054,2.973],[-2.976,-0.054]],"o":[[-0.054,2.976],[-2.972,-0.054],[0.054,-2.973],[2.971,0.054]],"v":[[-18.385,0.097],[-23.869,5.385],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":54,"s":[{"i":[[0.054,-2.972],[2.972,0.054],[-0.054,2.973],[-2.976,-0.054]],"o":[[-0.054,2.976],[-2.972,-0.054],[0.054,-2.973],[2.971,0.054]],"v":[[-18.385,0.097],[-23.869,5.385],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":62,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":68,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":71,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":74,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":77,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":80,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":83,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":86,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":89,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":92,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":95,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":98,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":101,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":104,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":107,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"t":110}]},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ind":1,"ty":"sh","ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":34,"s":[{"i":[[0.023,-0.016],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[0.014,-0.036],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.014,-0.105]],"c":true}],"e":[{"i":[[0.003,-2.973],[2.973,0.003],[-0.003,2.973],[-2.976,-0.003]],"o":[[-0.003,2.976],[-2.974,-0.003],[0.003,-2.973],[2.971,0.003]],"v":[[5.386,0.004],[-0.006,5.385],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":44,"s":[{"i":[[0.003,-2.973],[2.973,0.003],[-0.003,2.973],[-2.976,-0.003]],"o":[[-0.003,2.976],[-2.974,-0.003],[0.003,-2.973],[2.971,0.003]],"v":[[5.386,0.004],[-0.006,5.385],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.003,-2.973],[2.973,0.003],[-0.003,2.973],[-2.976,-0.003]],"o":[[-0.003,2.976],[-2.974,-0.003],[0.003,-2.973],[2.971,0.003]],"v":[[5.386,0.004],[-0.006,5.385],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":54,"s":[{"i":[[0.003,-2.973],[2.973,0.003],[-0.003,2.973],[-2.976,-0.003]],"o":[[-0.003,2.976],[-2.974,-0.003],[0.003,-2.973],[2.971,0.003]],"v":[[5.386,0.004],[-0.006,5.385],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":62,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":68,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":71,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":74,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":77,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":80,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":83,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":86,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":89,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":92,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":95,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":98,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":101,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":104,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":107,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"t":110}]},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.79,0.56,0.22,1]},"o":{"a":1,"k":[{"t":14,"s":[0],"h":1},{"t":34,"s":[100],"h":1}]},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[242.997,431.73],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eyes_Open","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":54,"s":[{"i":[[0,0],[0.109,-0.906],[13.65,0.572],[1.781,12.531],[0,0],[-24,-0.295]],"o":[[0,0],[-1.541,12.793],[-13.007,-0.545],[-0.128,-0.903],[0,0],[22.624,0.278]],"v":[[23.024,-8.94],[22.994,-8.863],[-2.946,14.608],[-28.522,-7.528],[-28.716,-8.86],[-2.671,14.6]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,14.608],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":62,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,14.608],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,17.108],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":65,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,17.108],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":68,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":71,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":74,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":77,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":80,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":83,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":86,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":89,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":92,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":95,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":98,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":101,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":104,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":107,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"t":110}]},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.79,0.56,0.22,1]},"o":{"a":1,"k":[{"t":14,"s":[0],"h":1},{"t":54,"s":[100],"h":1}]},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"st","c":{"a":0,"k":[0.79,0.56,0.22,1]},"o":{"a":1,"k":[{"t":14,"s":[0],"h":1},{"t":54,"s":[100],"h":1}]},"w":{"a":0,"k":2.641},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[233.421,461.195],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Open Smile","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[-13.602,0.167],[-0.817,13.364]],"o":[[1.145,13.34],[13.603,-0.166],[0,0]],"v":[[-25.719,-11.551],[0.292,12.014],[25.719,-12.182]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":14,"s":[45],"e":[0]},{"t":34}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":14,"s":[55],"e":[100]},{"t":34}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":0,"k":[0.79,0.56,0.22,1]},"o":{"a":1,"k":[{"t":14,"s":[100],"h":1},{"t":54,"s":[0],"h":1}]},"w":{"a":0,"k":2.641},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[230.43,463.945],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Smile","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[10.322,1.475],[0,0],[4.634,9.335],[0,0],[3.041,-0.007],[0,0],[-4.62,-2.413],[0,0],[1.789,10.268],[0,0],[-7.447,7.297],[0,0]],"o":[[0,0],[-10.319,-1.474],[0,0],[-2.319,-4.67],[0,0],[6.08,-0.016],[0,0],[9.237,4.826],[0,0],[-1.79,-10.269],[0,0],[7.447,-7.294]],"v":[[30.878,-26.746],[4.089,-30.567],[-23.103,-50.22],[-35.144,-74.456],[-43.549,-81.447],[-43.189,60.499],[-26.405,64.095],[-2.419,76.628],[11.128,66.733],[6.486,40.071],[16.773,8.136],[36.102,-10.803]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[1,0.77,0.07,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[275.242,440.626],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Body_shader","np":2,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[-4.636,-9.336],[0,0],[-10.32,-1.474],[0,0],[7.448,-7.294],[0,0],[-1.789,-10.269],[0,0],[9.237,4.826],[0,0],[9.213,-4.873],[0,0],[-1.735,10.277],[0,0],[7.482,7.258],[0,0],[-10.314,1.526],[0,0],[-4.59,9.36]],"o":[[4.59,-9.359],[0,0],[4.634,9.335],[0,0],[10.322,1.475],[0,0],[-7.446,7.297],[0,0],[1.788,10.269],[0,0],[-9.237,-4.826],[0,0],[-9.215,4.873],[0,0],[1.736,-10.28],[0,0],[-7.482,-7.256],[0,0],[10.315,-1.525],[0,0]],"v":[[-8.533,-73.371],[8.244,-73.413],[20.285,-49.178],[47.477,-29.525],[74.265,-25.704],[79.489,-9.76],[60.16,9.178],[49.874,41.114],[54.515,67.775],[40.969,77.671],[16.983,65.137],[-16.569,65.22],[-40.491,77.876],[-54.088,68.051],[-49.58,41.366],[-60.029,9.483],[-79.455,-9.358],[-74.312,-25.327],[-47.543,-29.285],[-20.447,-49.076]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[1,0.83,0.44,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[231.695,439.583],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Body","np":2,"mn":"ADBE Vector Group"}],"ip":14,"op":90,"st":14,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"Star_02","parent":0,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":79,"s":[100],"e":[0]},{"t":89}]},"r":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":7,"s":[-720],"e":[-1509]},{"t":107}]},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":7,"s":[-55.808,-64.938,0],"e":[-234.808,76.062,0],"to":[-20,-147.83332824707,0],"ti":[-2,-323.166656494141,0]},{"t":90}]},"a":{"a":0,"k":[231.37,449.226,0]},"s":{"a":1,"k":[{"i":{"x":[0,0,0.667],"y":[1,1,0.667]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_1_0p167_0p167","0_1_0p167_0p167","0p667_0p667_0p167_0p167"],"t":7,"s":[0,0,100],"e":[100,100,100]},{"t":47}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-36.571,-9.612],[-27.799,-1.99],[-36.683,5.428]],"c":false}},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ind":1,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[3.95,-9.308],[-4.935,-1.817],[3.838,5.731]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.79,0.56,0.22,1]},"o":{"a":1,"k":[{"t":7,"s":[100],"h":1},{"t":27,"s":[0],"h":1}]},"w":{"a":0,"k":2.641},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[247.846,433.746],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eyes_Closed","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":27,"s":[{"i":[[0.013,-0.202],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.096,-0.1],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.733,-0.323]],"c":true}],"e":[{"i":[[0.054,-2.972],[2.972,0.054],[-0.054,2.973],[-2.976,-0.054]],"o":[[-0.054,2.976],[-2.972,-0.054],[0.054,-2.973],[2.971,0.054]],"v":[[-18.385,0.097],[-23.869,5.385],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":37,"s":[{"i":[[0.054,-2.972],[2.972,0.054],[-0.054,2.973],[-2.976,-0.054]],"o":[[-0.054,2.976],[-2.972,-0.054],[0.054,-2.973],[2.971,0.054]],"v":[[-18.385,0.097],[-23.869,5.385],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.054,-2.972],[2.972,0.054],[-0.054,2.973],[-2.976,-0.054]],"o":[[-0.054,2.976],[-2.972,-0.054],[0.054,-2.973],[2.971,0.054]],"v":[[-18.385,0.097],[-23.869,5.385],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":47,"s":[{"i":[[0.054,-2.972],[2.972,0.054],[-0.054,2.973],[-2.976,-0.054]],"o":[[-0.054,2.976],[-2.972,-0.054],[0.054,-2.973],[2.971,0.054]],"v":[[-18.385,0.097],[-23.869,5.385],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":55,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":61,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":64,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":67,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":70,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":73,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":76,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":79,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":82,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":85,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":88,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":91,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":94,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":97,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":100,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"t":103}]},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ind":1,"ty":"sh","ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":27,"s":[{"i":[[0.023,-0.016],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[0.014,-0.036],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.014,-0.105]],"c":true}],"e":[{"i":[[0.003,-2.973],[2.973,0.003],[-0.003,2.973],[-2.976,-0.003]],"o":[[-0.003,2.976],[-2.974,-0.003],[0.003,-2.973],[2.971,0.003]],"v":[[5.386,0.004],[-0.006,5.385],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":37,"s":[{"i":[[0.003,-2.973],[2.973,0.003],[-0.003,2.973],[-2.976,-0.003]],"o":[[-0.003,2.976],[-2.974,-0.003],[0.003,-2.973],[2.971,0.003]],"v":[[5.386,0.004],[-0.006,5.385],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.003,-2.973],[2.973,0.003],[-0.003,2.973],[-2.976,-0.003]],"o":[[-0.003,2.976],[-2.974,-0.003],[0.003,-2.973],[2.971,0.003]],"v":[[5.386,0.004],[-0.006,5.385],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":47,"s":[{"i":[[0.003,-2.973],[2.973,0.003],[-0.003,2.973],[-2.976,-0.003]],"o":[[-0.003,2.976],[-2.974,-0.003],[0.003,-2.973],[2.971,0.003]],"v":[[5.386,0.004],[-0.006,5.385],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":55,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":61,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":64,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":67,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":70,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":73,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":76,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":79,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":82,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":85,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":88,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":91,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":94,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":97,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":100,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"t":103}]},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.79,0.56,0.22,1]},"o":{"a":1,"k":[{"t":7,"s":[0],"h":1},{"t":27,"s":[100],"h":1}]},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[242.997,431.73],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eyes_Open","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":47,"s":[{"i":[[0,0],[0.109,-0.906],[13.65,0.572],[1.781,12.531],[0,0],[-24,-0.295]],"o":[[0,0],[-1.541,12.793],[-13.007,-0.545],[-0.128,-0.903],[0,0],[22.624,0.278]],"v":[[23.024,-8.94],[22.994,-8.863],[-2.946,14.608],[-28.522,-7.528],[-28.716,-8.86],[-2.671,14.6]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,14.608],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":55,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,14.608],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,17.108],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":58,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,17.108],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":61,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":64,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":67,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":70,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":73,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":76,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":79,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":82,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":85,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":88,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":91,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":94,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":97,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":100,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"t":103}]},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.79,0.56,0.22,1]},"o":{"a":1,"k":[{"t":7,"s":[0],"h":1},{"t":47,"s":[100],"h":1}]},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"st","c":{"a":0,"k":[0.79,0.56,0.22,1]},"o":{"a":1,"k":[{"t":7,"s":[0],"h":1},{"t":47,"s":[100],"h":1}]},"w":{"a":0,"k":2.641},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[233.421,461.195],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Open Smile","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[-13.602,0.167],[-0.817,13.364]],"o":[[1.145,13.34],[13.603,-0.166],[0,0]],"v":[[-25.719,-11.551],[0.292,12.014],[25.719,-12.182]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":7,"s":[45],"e":[0]},{"t":27}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":7,"s":[55],"e":[100]},{"t":27}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":0,"k":[0.79,0.56,0.22,1]},"o":{"a":1,"k":[{"t":7,"s":[100],"h":1},{"t":47,"s":[0],"h":1}]},"w":{"a":0,"k":2.641},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[230.43,463.945],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Smile","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[10.322,1.475],[0,0],[4.634,9.335],[0,0],[3.041,-0.007],[0,0],[-4.62,-2.413],[0,0],[1.789,10.268],[0,0],[-7.447,7.297],[0,0]],"o":[[0,0],[-10.319,-1.474],[0,0],[-2.319,-4.67],[0,0],[6.08,-0.016],[0,0],[9.237,4.826],[0,0],[-1.79,-10.269],[0,0],[7.447,-7.294]],"v":[[30.878,-26.746],[4.089,-30.567],[-23.103,-50.22],[-35.144,-74.456],[-43.549,-81.447],[-43.189,60.499],[-26.405,64.095],[-2.419,76.628],[11.128,66.733],[6.486,40.071],[16.773,8.136],[36.102,-10.803]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[1,0.77,0.07,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[275.242,440.626],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Body_shader","np":2,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[-4.636,-9.336],[0,0],[-10.32,-1.474],[0,0],[7.448,-7.294],[0,0],[-1.789,-10.269],[0,0],[9.237,4.826],[0,0],[9.213,-4.873],[0,0],[-1.735,10.277],[0,0],[7.482,7.258],[0,0],[-10.314,1.526],[0,0],[-4.59,9.36]],"o":[[4.59,-9.359],[0,0],[4.634,9.335],[0,0],[10.322,1.475],[0,0],[-7.446,7.297],[0,0],[1.788,10.269],[0,0],[-9.237,-4.826],[0,0],[-9.215,4.873],[0,0],[1.736,-10.28],[0,0],[-7.482,-7.256],[0,0],[10.315,-1.525],[0,0]],"v":[[-8.533,-73.371],[8.244,-73.413],[20.285,-49.178],[47.477,-29.525],[74.265,-25.704],[79.489,-9.76],[60.16,9.178],[49.874,41.114],[54.515,67.775],[40.969,77.671],[16.983,65.137],[-16.569,65.22],[-40.491,77.876],[-54.088,68.051],[-49.58,41.366],[-60.029,9.483],[-79.455,-9.358],[-74.312,-25.327],[-47.543,-29.285],[-20.447,-49.076]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[1,0.83,0.44,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[231.695,439.583],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Body","np":2,"mn":"ADBE Vector Group"}],"ip":7,"op":90,"st":7,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"Star_01","parent":0,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":66,"s":[100],"e":[0]},{"t":75}]},"r":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":0,"s":[-720],"e":[60]},{"t":90}]},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":0,"s":[31.192,-0.938,0],"e":[223.192,87.062,0],"to":[27,-133.83332824707,0],"ti":[-7,-196.16667175293,0]},{"t":90}]},"a":{"a":0,"k":[231.37,449.226,0]},"s":{"a":1,"k":[{"i":{"x":[0,0,0.667],"y":[1,1,0.667]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_1_0p167_0p167","0_1_0p167_0p167","0p667_0p667_0p167_0p167"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"t":40}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-36.571,-9.612],[-27.799,-1.99],[-36.683,5.428]],"c":false}},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ind":1,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[3.95,-9.308],[-4.935,-1.817],[3.838,5.731]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.79,0.56,0.22,1]},"o":{"a":1,"k":[{"t":0,"s":[100],"h":1},{"t":20,"s":[0],"h":1}]},"w":{"a":0,"k":2.641},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[247.846,433.746],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eyes_Closed","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0.013,-0.202],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.096,-0.1],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.733,-0.323]],"c":true}],"e":[{"i":[[0.054,-2.972],[2.972,0.054],[-0.054,2.973],[-2.976,-0.054]],"o":[[-0.054,2.976],[-2.972,-0.054],[0.054,-2.973],[2.971,0.054]],"v":[[-18.385,0.097],[-23.869,5.385],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":30,"s":[{"i":[[0.054,-2.972],[2.972,0.054],[-0.054,2.973],[-2.976,-0.054]],"o":[[-0.054,2.976],[-2.972,-0.054],[0.054,-2.973],[2.971,0.054]],"v":[[-18.385,0.097],[-23.869,5.385],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.054,-2.972],[2.972,0.054],[-0.054,2.973],[-2.976,-0.054]],"o":[[-0.054,2.976],[-2.972,-0.054],[0.054,-2.973],[2.971,0.054]],"v":[[-18.385,0.097],[-23.869,5.385],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":40,"s":[{"i":[[0.054,-2.972],[2.972,0.054],[-0.054,2.973],[-2.976,-0.054]],"o":[[-0.054,2.976],[-2.972,-0.054],[0.054,-2.973],[2.971,0.054]],"v":[[-18.385,0.097],[-23.869,5.385],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":48,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":54,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":57,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":60,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":63,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":66,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":69,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":72,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":75,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":78,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":81,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":84,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":87,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":90,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":93,"s":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.769,-0.053],[-29.155,-0.099],[-23.671,-5.385]],"c":true}],"e":[{"i":[[0.049,-2.972],[2.972,0.054],[0.096,-0.006],[-2.976,-0.054]],"o":[[0.013,-0.015],[-2.972,-0.054],[0.083,-2.972],[2.971,0.054]],"v":[[-18.385,0.097],[-23.644,-0.884],[-29.155,-0.099],[-23.671,-5.385]],"c":true}]},{"t":96}]},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ind":1,"ty":"sh","ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0.023,-0.016],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[0.014,-0.036],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.014,-0.105]],"c":true}],"e":[{"i":[[0.003,-2.973],[2.973,0.003],[-0.003,2.973],[-2.976,-0.003]],"o":[[-0.003,2.976],[-2.974,-0.003],[0.003,-2.973],[2.971,0.003]],"v":[[5.386,0.004],[-0.006,5.385],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":30,"s":[{"i":[[0.003,-2.973],[2.973,0.003],[-0.003,2.973],[-2.976,-0.003]],"o":[[-0.003,2.976],[-2.974,-0.003],[0.003,-2.973],[2.971,0.003]],"v":[[5.386,0.004],[-0.006,5.385],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.003,-2.973],[2.973,0.003],[-0.003,2.973],[-2.976,-0.003]],"o":[[-0.003,2.976],[-2.974,-0.003],[0.003,-2.973],[2.971,0.003]],"v":[[5.386,0.004],[-0.006,5.385],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":40,"s":[{"i":[[0.003,-2.973],[2.973,0.003],[-0.003,2.973],[-2.976,-0.003]],"o":[[-0.003,2.976],[-2.974,-0.003],[0.003,-2.973],[2.971,0.003]],"v":[[5.386,0.004],[-0.006,5.385],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":48,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":54,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":57,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":60,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":63,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":66,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":69,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":72,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":75,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":78,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":81,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":84,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":87,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":90,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":93,"s":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.02,-0.021],[-5.386,-0.006],[0.007,-5.386]],"c":true}],"e":[{"i":[[0.116,-2.97],[2.973,0.003],[0.014,0.057],[-2.976,-0.003]],"o":[[0.054,0.078],[-2.974,-0.003],[-0.236,-3.255],[2.971,0.003]],"v":[[5.386,0.004],[0.145,-0.852],[-5.386,-0.006],[0.007,-5.386]],"c":true}]},{"t":96}]},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.79,0.56,0.22,1]},"o":{"a":1,"k":[{"t":0,"s":[0],"h":1},{"t":20,"s":[100],"h":1}]},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[242.997,431.73],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eyes_Open","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":40,"s":[{"i":[[0,0],[0.109,-0.906],[13.65,0.572],[1.781,12.531],[0,0],[-24,-0.295]],"o":[[0,0],[-1.541,12.793],[-13.007,-0.545],[-0.128,-0.903],[0,0],[22.624,0.278]],"v":[[23.024,-8.94],[22.994,-8.863],[-2.946,14.608],[-28.522,-7.528],[-28.716,-8.86],[-2.671,14.6]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,14.608],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":48,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,14.608],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,17.108],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":51,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,17.108],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":54,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":57,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":60,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":63,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":66,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":69,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":72,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":75,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":78,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":81,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":84,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":87,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":90,"s":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}],"e":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":93,"s":[{"i":[[0,0],[0.123,-0.904],[13.118,0.071],[1.781,12.531],[-0.771,0.001],[-13.559,-0.008]],"o":[[0.771,-0.001],[-1.708,12.576],[-13.016,-0.067],[-0.128,-0.903],[0,0],[13.343,0.006]],"v":[[21.337,-9.257],[22.625,-7.808],[-2.946,14.608],[-28.522,-7.528],[-27.263,-9.176],[-2.671,-5.545]],"c":true}],"e":[{"i":[[0,0],[0.125,-0.904],[13.019,-0.021],[1.781,12.531],[-0.913,0.001],[-11.625,0.045]],"o":[[0.913,-0.002],[-1.74,12.536],[-13.018,0.021],[-0.128,-0.903],[0,0],[11.625,-0.045]],"v":[[21.024,-9.315],[22.557,-7.613],[-2.946,17.295],[-28.522,-7.528],[-26.994,-9.235],[-2.671,-9.275]],"c":true}]},{"t":96}]},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.79,0.56,0.22,1]},"o":{"a":1,"k":[{"t":0,"s":[0],"h":1},{"t":40,"s":[100],"h":1}]},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"st","c":{"a":0,"k":[0.79,0.56,0.22,1]},"o":{"a":1,"k":[{"t":0,"s":[0],"h":1},{"t":40,"s":[100],"h":1}]},"w":{"a":0,"k":2.641},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[233.421,461.195],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Open Smile","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[-13.602,0.167],[-0.817,13.364]],"o":[[1.145,13.34],[13.603,-0.166],[0,0]],"v":[[-25.719,-11.551],[0.292,12.014],[25.719,-12.182]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[45],"e":[0]},{"t":20}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[55],"e":[100]},{"t":20}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":0,"k":[0.79,0.56,0.22,1]},"o":{"a":1,"k":[{"t":0,"s":[100],"h":1},{"t":40,"s":[0],"h":1}]},"w":{"a":0,"k":2.641},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[230.43,463.945],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Smile","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[10.322,1.475],[0,0],[4.634,9.335],[0,0],[3.041,-0.007],[0,0],[-4.62,-2.413],[0,0],[1.789,10.268],[0,0],[-7.447,7.297],[0,0]],"o":[[0,0],[-10.319,-1.474],[0,0],[-2.319,-4.67],[0,0],[6.08,-0.016],[0,0],[9.237,4.826],[0,0],[-1.79,-10.269],[0,0],[7.447,-7.294]],"v":[[30.878,-26.746],[4.089,-30.567],[-23.103,-50.22],[-35.144,-74.456],[-43.549,-81.447],[-43.189,60.499],[-26.405,64.095],[-2.419,76.628],[11.128,66.733],[6.486,40.071],[16.773,8.136],[36.102,-10.803]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[1,0.77,0.07,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[275.242,440.626],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Body_shader","np":2,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[-4.636,-9.336],[0,0],[-10.32,-1.474],[0,0],[7.448,-7.294],[0,0],[-1.789,-10.269],[0,0],[9.237,4.826],[0,0],[9.213,-4.873],[0,0],[-1.735,10.277],[0,0],[7.482,7.258],[0,0],[-10.314,1.526],[0,0],[-4.59,9.36]],"o":[[4.59,-9.359],[0,0],[4.634,9.335],[0,0],[10.322,1.475],[0,0],[-7.446,7.297],[0,0],[1.788,10.269],[0,0],[-9.237,-4.826],[0,0],[-9.215,4.873],[0,0],[1.736,-10.28],[0,0],[-7.482,-7.256],[0,0],[10.315,-1.525],[0,0]],"v":[[-8.533,-73.371],[8.244,-73.413],[20.285,-49.178],[47.477,-29.525],[74.265,-25.704],[79.489,-9.76],[60.16,9.178],[49.874,41.114],[54.515,67.775],[40.969,77.671],[16.983,65.137],[-16.569,65.22],[-40.491,77.876],[-54.088,68.051],[-49.58,41.366],[-60.029,9.483],[-79.455,-9.358],[-74.312,-25.327],[-47.543,-29.285],[-20.447,-49.076]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[1,0.83,0.44,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[231.695,439.583],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Body","np":2,"mn":"ADBE Vector Group"}],"ip":0,"op":90,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":4,"ty":4,"nm":"Fireworks_08","parent":0,"ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[-41,-125.553,0]},"a":{"a":0,"k":[312.5,177.5,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[-3.733,3.212],[3.516,3.448],[1.007,-0.109],[-0.831,-1.602],[-1.804,-0.048],[-1.498,2.82],[1.857,2.598],[1.894,4.895],[-2.186,3.33],[0.394,3.963],[4.488,1.512],[0.67,2.591],[-1.061,1.667],[3.352,6.121],[-0.017,5.733],[-0.824,5.056],[1.288,6.795],[2.266,9.62],[0.775,2.384],[-2.086,5.33]],"o":[[4.912,0.354],[3.734,-3.212],[-0.723,-0.709],[-1.794,0.194],[0.831,1.602],[3.192,0.085],[1.498,-2.82],[-3.052,-4.27],[-1.438,-3.716],[2.186,-3.33],[-0.468,-4.712],[-2.536,-0.855],[-0.495,-1.913],[3.747,-5.888],[-2.754,-5.028],[0.015,-5.123],[1.113,-6.827],[-1.84,-9.71],[-0.575,-2.44],[-1.769,-5.444],[0,0]],"v":[[19.657,33.614],[33.618,30.114],[35.047,17.054],[32.352,15.881],[30.503,20.092],[35.067,22.494],[42.924,17.911],[42.323,8.835],[30.752,-1.506],[33.523,-12.651],[37.839,-23.525],[28.4,-33.073],[22.087,-37.425],[23.799,-42.917],[27.536,-62.474],[17.953,-76.278],[24.534,-89.921],[16.335,-108.508],[24.585,-136.227],[21.753,-143.18],[24.179,-159.818]],"c":false}},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.67,0.87,0.87,1]},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":14,"s":[100],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":46.381,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":68.762,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":70,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":103,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":104,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":643,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":644,"s":[100],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":676.381,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":698.762,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":700,"s":[0],"e":[0]},{"t":733}]},"w":{"a":0,"k":4.829},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":14,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":25,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":67,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":70,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":103,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1_0p167_0p167"],"t":104,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":643,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":644,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":655,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":697,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":700,"s":[100],"e":[100]},{"t":733}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":14,"s":[0],"e":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":24,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":68.762,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":70,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":103,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1_0p167_0p167"],"t":104,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":643,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":644,"s":[0],"e":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":654,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":698.762,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":700,"s":[100],"e":[100]},{"t":733}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[312.078,177.185],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"mn":"ADBE Vector Group"}],"ip":14,"op":450,"st":24,"bm":0,"sr":1},{"ddd":0,"ind":5,"ty":4,"nm":"Fireworks_07","parent":0,"ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[-41,-125.553,0]},"a":{"a":0,"k":[312.5,177.5,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[-3.987,2.255],[-3.851,-0.605],[-3.81,0.826],[0.199,3.894],[-0.057,1.725],[-3.528,0.655],[-3.35,1.286],[-0.385,4.173],[-1.666,2.264],[-4.338,1.184],[0.652,6.571],[-0.575,1.771],[-4.258,0.478],[-2.004,3.788],[0.798,2.901],[-1.515,4.958],[-6.098,3.216],[-0.018,8.318],[-2.756,4.522]],"o":[[-1.536,-4.314],[3.393,-1.919],[3.852,0.605],[3.811,-0.825],[-0.088,-1.723],[0.118,-3.586],[3.529,-0.654],[3.912,-1.503],[0.258,-2.799],[2.666,-3.621],[6.371,-1.74],[-0.183,-1.853],[1.322,-4.076],[4.258,-0.479],[1.407,-2.659],[-1.374,-4.999],[2.015,-6.594],[7.358,-3.88],[0.011,-5.295],[0,0]],"v":[[168.47,147.842],[172.892,135.992],[184.314,134.937],[195.915,135.611],[203.185,127.697],[202.336,122.605],[209.757,115.984],[220.374,114.415],[227.58,104.899],[228.797,96.697],[241.534,93.832],[249.311,77.395],[249.402,71.854],[260.021,65.997],[271.274,60.989],[271.241,52.188],[269.636,36.947],[284.659,23.584],[299.994,5.52],[299.485,-10.017]],"c":false}},"nm":"Path 6","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.91,0.32,0.61,1]},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":12,"s":[100],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":41.048,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":60.096,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":68,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":101,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":102,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":641,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":642,"s":[100],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":671.048,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":690.096,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":698,"s":[0],"e":[0]},{"t":731}]},"w":{"a":0,"k":4.829},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":12,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":23.904,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":62,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":68,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":101,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1_0p167_0p167"],"t":102,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":641,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":642,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":653.904,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":692,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":698,"s":[100],"e":[100]},{"t":731}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":12,"s":[0],"e":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":22,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":60.096,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":68,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":101,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1_0p167_0p167"],"t":102,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":641,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":642,"s":[0],"e":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":652,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":690.096,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":698,"s":[100],"e":[100]},{"t":731}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[312.078,177.185],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"mn":"ADBE Vector Group"}],"ip":12,"op":450,"st":22,"bm":0,"sr":1},{"ddd":0,"ind":6,"ty":4,"nm":"Fireworks_06","parent":0,"ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[-41,-125.553,0]},"a":{"a":0,"k":[312.5,177.5,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[-5.281,4.43],[-0.914,3.014],[5.89,1.428],[1.278,-0.706],[-0.398,-2.024],[-1.595,-1.307],[-5.767,2.717],[-1.596,6.171],[3.096,3.922],[3.061,0.395],[-0.362,-3.113],[-0.844,-0.845],[-5.948,1.68],[-4.203,4.531],[-0.402,6.099],[7.253,2.417],[1.355,-3.406],[-1.315,-1.81],[-5.511,1.088],[-3.533,4.367],[0.195,7.031],[5.769,4.024],[2.472,-0.019],[1.072,-2.228],[-1.583,-1.944],[-2.424,-0.639],[-4.257,7.616],[6.316,6.022],[2.637,-1.208],[-1.496,-2.496],[-2.893,0.316],[-2.212,1.892],[-0.927,3.55],[2.473,2.71]],"o":[[6.373,2.623],[2.413,-2.024],[1.757,-5.8],[-1.419,-0.345],[-1.805,0.998],[0.397,2.024],[4.929,4.043],[5.767,-2.716],[1.252,-4.838],[-1.912,-2.422],[-3.109,-0.402],[0.138,1.187],[4.367,4.372],[5.948,-1.679],[4.157,-4.48],[0.503,-7.629],[-3.478,-1.159],[-0.826,2.079],[3.303,4.544],[5.511,-1.089],[4.423,-5.47],[-0.195,-7.031],[-2.027,-1.414],[-2.472,0.019],[-1.087,2.258],[1.582,1.944],[8.437,2.224],[4.257,-7.617],[-2.098,-2.001],[-2.645,1.213],[1.495,2.497],[2.892,-0.316],[2.788,-2.385],[0.926,-3.551],[0,0]],"v":[[155.107,26.434],[174.284,22.087],[179.759,14.55],[171.698,0.45],[167.431,0.768],[165.247,6.125],[168.605,11.174],[186.637,13.021],[198.146,-1.482],[195.964,-15.777],[188.107,-20.228],[181.374,-15.649],[183.12,-12.598],[200.404,-8.883],[215.596,-19.099],[223.786,-35.098],[211.8,-52.728],[202.231,-49.982],[203.534,-43.686],[218.597,-38.425],[232.409,-47.474],[239.401,-66.919],[230.087,-85.004],[223.214,-87.454],[217.117,-83.941],[218.253,-76.909],[224.63,-73.166],[247.016,-82.674],[243.387,-106.723],[235.556,-109.098],[233.618,-101.608],[241.18,-98.275],[248.909,-102.043],[254.954,-111.038],[252.759,-121.366]],"c":false}},"nm":"Path 7","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0,0.73,0.73,1]},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":10,"s":[100],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":40,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":60.001,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":66,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":99,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":100,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":639,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":640,"s":[100],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":670,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":690.001,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":696,"s":[0],"e":[0]},{"t":729}]},"w":{"a":0,"k":4.829},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":10,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":22,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":62,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":66,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":99,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1_0p167_0p167"],"t":100,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":639,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":640,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":652,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":692,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":696,"s":[100],"e":[100]},{"t":729}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":10,"s":[0],"e":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":20,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":60.001,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":66,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":99,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1_0p167_0p167"],"t":100,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":639,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":640,"s":[0],"e":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":650,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":690.001,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":696,"s":[100],"e":[100]},{"t":729}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[312.078,177.185],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"mn":"ADBE Vector Group"}],"ip":10,"op":450,"st":20,"bm":0,"sr":1},{"ddd":0,"ind":7,"ty":4,"nm":"Fireworks_05","parent":0,"ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[-41,-125.553,0]},"a":{"a":0,"k":[312.5,177.5,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[4.131,7.797],[-5.227,7.109],[-8.766,-1.006],[-2.056,-1.844],[1.011,-2.57],[2.071,-1.017],[11.297,8.656],[-0.667,11.76],[-11.746,0.887],[-2.541,-1.671],[0.36,-3.02],[2.745,-1.724],[12.069,6.836],[4.344,10.921],[-2.995,9.212],[-2.692,2.073],[-2.84,0.366],[-3.616,-4.508],[6.115,-4.567],[7.593,0.777],[7.683,3.722],[3.783,5.39],[0.942,5.093],[-3.631,7.488],[-8.288,0.753]],"o":[[-8.772,0.947],[-4.13,-7.797],[5.226,-7.109],[2.743,0.315],[2.056,1.843],[-0.844,2.146],[-12.773,6.277],[-9.35,-7.164],[0.667,-11.759],[3.033,-0.229],[2.541,1.671],[-0.384,3.219],[-11.744,7.379],[-10.227,-5.792],[-3.581,-9.002],[1.05,-3.231],[2.268,-1.747],[5.732,-0.739],[4.777,5.954],[-6.116,4.567],[-8.493,-0.868],[-5.926,-2.871],[-2.976,-4.239],[-1.513,-8.184],[3.631,-7.489],[0,0]],"v":[[21.947,19.676],[-0.004,7.853],[1.987,-17.173],[25.207,-27.138],[32.799,-24.171],[34.978,-16.7],[29.978,-12.152],[-10.184,-17.613],[-25.547,-47.891],[-3.824,-71.879],[4.928,-69.965],[8.88,-62.255],[3.165,-54.794],[-36.376,-57.061],[-59.814,-82.497],[-60.73,-110.966],[-55.446,-119.498],[-47.461,-122.373],[-31.596,-117.55],[-35.706,-97.459],[-57.634,-93.077],[-82.148,-100.034],[-97.524,-112.094],[-103.116,-126.461],[-100.635,-150.883],[-81.46,-165.113]],"c":false}},"nm":"Path 4","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0,0.73,0.73,1]},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":8,"s":[100],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":34.667,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":51.334,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":64,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":97,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":98,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":637,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":638,"s":[100],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":664.667,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":681.334,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":694,"s":[0],"e":[0]},{"t":727}]},"w":{"a":0,"k":4.829},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":8,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":19.666,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":53,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":64,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":97,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1_0p167_0p167"],"t":98,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":637,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":638,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":649.666,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":683,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":694,"s":[100],"e":[100]},{"t":727}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":8,"s":[0],"e":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":18,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":51.334,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":64,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":97,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1_0p167_0p167"],"t":98,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":637,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":638,"s":[0],"e":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":648,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":681.334,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":694,"s":[100],"e":[100]},{"t":727}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[312.078,177.185],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"mn":"ADBE Vector Group"}],"ip":8,"op":450,"st":18,"bm":0,"sr":1},{"ddd":0,"ind":8,"ty":4,"nm":"Fireworks_04","parent":0,"ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[-41,-125.553,0]},"a":{"a":0,"k":[312.5,177.5,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[-0.913,5.269],[1.635,5.641],[2.07,9.641],[-1.235,6.159],[3.608,2.85],[2.872,6.752],[1.643,6.444],[3.337,2.11],[2.014,7.467],[0.352,3.318],[3.517,3.226],[3.39,3.021],[1.953,8.137]],"o":[[-4.197,-3.313],[1.002,-5.787],[-2.745,-9.471],[-1.319,-6.142],[0.904,-4.508],[-5.759,-4.546],[-2.603,-6.119],[-0.976,-3.826],[-6.538,-4.133],[-0.869,-3.222],[-0.503,-4.746],[-3.347,-3.069],[-6.248,-5.568],[0,0]],"v":[[-57.252,23.762],[-62.715,9.49],[-58.964,-7.44],[-80.304,-26.391],[-74.597,-44.016],[-79.12,-56.32],[-97.537,-67.369],[-96.248,-86.954],[-103.868,-95.641],[-120.542,-110.88],[-121.281,-120.84],[-127.589,-133.348],[-138.641,-141.284],[-149.101,-163.655]],"c":false}},"nm":"Path 3","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.91,0.32,0.61,1]},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":6,"s":[100],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":33.144,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":50.286,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":62,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":95,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":96,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":635,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":636,"s":[100],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":663.144,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":680.286,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":692,"s":[0],"e":[0]},{"t":725}]},"w":{"a":0,"k":4.829},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":6,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":17.714,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":52,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":62,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":95,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1_0p167_0p167"],"t":96,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":635,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":636,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":647.714,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":682,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":692,"s":[100],"e":[100]},{"t":725}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":6,"s":[0],"e":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":16,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":50.286,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":62,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":95,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1_0p167_0p167"],"t":96,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":635,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":636,"s":[0],"e":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":646,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":680.286,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":692,"s":[100],"e":[100]},{"t":725}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[312.078,177.185],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"mn":"ADBE Vector Group"}],"ip":6,"op":450,"st":16,"bm":0,"sr":1},{"ddd":0,"ind":9,"ty":4,"nm":"Fireworks_03","parent":0,"ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[-41,-125.553,0]},"a":{"a":0,"k":[312.5,177.5,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[6.04,1.773],[1.254,-6.169],[-0.817,-1.005],[-1.139,2.006],[1.203,1.968],[4.066,-0.354],[1.495,-3.798],[3.934,-5.435],[5.091,0.029],[3.978,-3.177],[-1.497,-5.865],[2.314,-2.52],[2.526,-0.02],[4.235,-7.851],[6.161,-3.967],[5.996,-2.631],[6.393,-6.106],[8.746,-9.115],[2.019,-2.488],[7.167,-1.468]],"o":[[-3.035,-5.515],[-6.041,-1.772],[-0.258,1.269],[1.455,1.789],[1.14,-2.005],[-2.128,-3.483],[-4.066,0.354],[-2.458,6.242],[-2.986,4.125],[-5.092,-0.03],[-4.729,3.778],[0.846,3.314],[-1.708,1.861],[-8.921,0.074],[-3.479,6.449],[-5.505,3.545],[-8.096,3.552],[-9.136,8.724],[-2.218,2.313],[-4.609,5.682],[0,0]],"v":[[-89.377,35.497],[-102.837,22.955],[-117.839,30.501],[-117.223,34.207],[-111.421,33.263],[-112.017,26.697],[-122.395,21.455],[-131.712,28.41],[-134.761,48.01],[-148.642,52.786],[-163.307,55.715],[-166.986,72.477],[-167.266,82.274],[-174.347,84.255],[-197.923,93.843],[-206.068,113.718],[-225.276,116.143],[-239.515,137.858],[-274.982,148.278],[-280.472,156.15],[-300.005,165.113]],"c":false}},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.91,0.32,0.61,1]},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":4,"s":[100],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":33.524,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":53.048,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":60,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":93,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":94,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":633,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":634,"s":[100],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":663.524,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":683.048,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":690,"s":[0],"e":[0]},{"t":723}]},"w":{"a":0,"k":4.829},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":4,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":15.952,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":55,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":60,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":93,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1_0p167_0p167"],"t":94,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":633,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":634,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":645.952,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":685,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":690,"s":[100],"e":[100]},{"t":723}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":4,"s":[0],"e":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":14,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":53.048,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":60,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":93,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1_0p167_0p167"],"t":94,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":633,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":634,"s":[0],"e":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":644,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":683.048,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":690,"s":[100],"e":[100]},{"t":723}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[312.078,177.185],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"mn":"ADBE Vector Group"}],"ip":4,"op":450,"st":14,"bm":0,"sr":1},{"ddd":0,"ind":10,"ty":4,"nm":"Fireworks_02","parent":0,"ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[-41,-125.553,0]},"a":{"a":0,"k":[312.5,177.5,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[-7.933,14.672],[0.349,16.675],[5.473,5.656],[4.908,1.164],[4.876,-2.608],[-1.549,-5.308],[-6.55,-0.009],[-1.872,0.928],[-0.997,4.469],[2.661,12.031],[2.233,3.641],[3.652,2.818],[8.412,2.835]],"o":[[11.892,-11.695],[7.932,-14.672],[-0.166,-7.869],[-3.508,-3.625],[-5.381,-1.276],[-4.876,2.608],[1.834,6.288],[2.089,0.003],[4.103,-2.034],[2.684,-12.026],[-0.923,-4.171],[-2.412,-3.933],[-7.029,-5.423],[0,0]],"v":[[119.191,30.962],[149.872,-8.329],[162.384,-56.202],[155.159,-78.093],[141.943,-85.036],[125.763,-83.813],[119.055,-70.028],[134.91,-60.892],[141.017,-62.022],[147.861,-73.389],[147.896,-110.061],[143.478,-122.026],[133.96,-131.966],[110.582,-144.469]],"c":false}},"nm":"Path 5","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[1,0.77,0.07,1]},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":2,"s":[100],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":27.715,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":43.429,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":58,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":91,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":92,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":631,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":632,"s":[100],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":657.715,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":673.429,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":688,"s":[0],"e":[0]},{"t":721}]},"w":{"a":0,"k":4.829},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":2,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":13.571,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":45,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":58,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":91,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1_0p167_0p167"],"t":92,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":631,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":632,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":643.571,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":675,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":688,"s":[100],"e":[100]},{"t":721}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":2,"s":[0],"e":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":12,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":43.429,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":58,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":91,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1_0p167_0p167"],"t":92,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":631,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":632,"s":[0],"e":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":642,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":673.429,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":688,"s":[100],"e":[100]},{"t":721}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[312.078,177.185],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"mn":"ADBE Vector Group"}],"ip":2,"op":450,"st":12,"bm":0,"sr":1},{"ddd":0,"ind":11,"ty":4,"nm":"Fireworks_01","parent":0,"ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[-41,-125.553,0]},"a":{"a":0,"k":[312.5,177.5,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[11.69,6.335],[-0.042,3.716],[-1.247,1.266],[-2.612,-1.139],[1.105,-2.627],[5.141,2.153],[1.829,8.959],[3.076,2.136],[3.312,2.666],[6.996,6.602],[3.62,1.755],[1.41,3.485],[2.977,4.448],[4.619,1.026],[4.136,2.297],[3.748,5.272],[6.456,0.411]],"o":[[-11.36,6.845],[-3.267,-1.77],[0.02,-1.777],[2,-2.029],[2.611,1.139],[-2.791,6.636],[-9.286,-3.889],[-0.75,-3.67],[-3.493,-2.425],[-7.686,-6.189],[-2.926,-2.762],[-3.383,-1.641],[-2.008,-4.961],[-2.632,-3.932],[-4.619,-1.026],[-5.656,-3.142],[-3.749,-5.273],[0,0]],"v":[[-87.104,119.435],[-125.246,120.525],[-131.776,112.185],[-129.676,107.427],[-121.832,105.665],[-118.75,112.73],[-140.586,115.83],[-152.583,96.072],[-157.893,86.484],[-169.572,81.55],[-177.838,56.291],[-188.771,51.385],[-196.302,43.331],[-200.687,27.987],[-212.76,21.213],[-226.362,17.374],[-239.172,3.039],[-254.425,-7.871]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[1,0.77,0.07,1]},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":24.762,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39.524,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":89,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":90,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":629,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":630,"s":[100],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":654.762,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":669.524,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":686,"s":[0],"e":[0]},{"t":719}]},"w":{"a":0,"k":4.829},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":11.477,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":41,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":89,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1_0p167_0p167"],"t":90,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":629,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":630,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":641.477,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":671,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":686,"s":[100],"e":[100]},{"t":719}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":10,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39.524,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":89,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1_0p167_0p167"],"t":90,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":629,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":630,"s":[0],"e":[0]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":640,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":669.524,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":686,"s":[100],"e":[100]},{"t":719}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[312.078,177.185],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":450,"st":10,"bm":0,"sr":1},{"ddd":0,"ind":12,"ty":4,"nm":"Fireworks","parent":0,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":53,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":90,"s":[0],"e":[100]},{"t":93}]},"r":{"a":0,"k":0},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":0,"s":[7.784,-100.71,0],"e":[7.784,99.29,0],"to":[0,33.3333320617676,0],"ti":[0,-33.3333320617676,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":56,"s":[7.784,99.29,0],"e":[7.784,99.29,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":89,"s":[7.784,99.29,0],"e":[7.784,-100.71,0],"to":[0,-33.3333320617676,0],"ti":[0,33.3333320617676,0]},{"t":90}]},"a":{"a":0,"k":[225.631,140.499,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.091,10.526],[-8.034,1.938],[-1.091,-10.526],[8.034,-1.938]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.91,0.32,0.61,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":0,"s":[218.951,244.775],"e":[-64.365,214.365],"to":[-47.2194023132324,-5.068359375],"ti":[47.2194023132324,5.068359375]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":50,"s":[-64.365,214.365],"e":[-64.365,214.365],"to":[0,0],"ti":[0,0]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":56,"s":[-64.365,214.365],"e":[-64.365,214.365],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":89,"s":[-64.365,214.365],"e":[218.951,244.775],"to":[47.2194023132324,5.068359375],"ti":[-47.2194023132324,-5.068359375]},{"t":90}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":0,"s":[-1996],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":50,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":89,"s":[0],"e":[-1996]},{"t":90}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15.834,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":50,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":89,"s":[0],"e":[100]},{"t":90}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[10.032,-3.369],[3.65,7.414],[-10.032,3.37],[-3.65,-7.414]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[1,0.77,0.07,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":0,"s":[217.823,241.687],"e":[62.624,26.913],"to":[-25.8665370941162,-35.7955741882324],"ti":[25.8665370941162,35.7955741882324]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":33,"s":[62.624,26.913],"e":[62.624,26.913],"to":[0,0],"ti":[0,0]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":56,"s":[62.624,26.913],"e":[62.624,26.913],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":89,"s":[62.624,26.913],"e":[217.823,241.687],"to":[25.8665370941162,35.7955741882324],"ti":[-25.8665370941162,-35.7955741882324]},{"t":90}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":0,"s":[1909],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":33,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":89,"s":[0],"e":[1909]},{"t":90}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":10.45,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":33,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":89,"s":[0],"e":[100]},{"t":90}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[5.439,-9.079],[7.591,3.266],[-5.438,9.079],[-7.591,-3.265]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.91,0.32,0.61,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":0,"s":[216.419,243.707],"e":[310.345,5.738],"to":[15.654296875,-39.6614570617676],"ti":[-15.654296875,39.6614570617676]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":44,"s":[310.345,5.738],"e":[310.345,5.738],"to":[0,0],"ti":[0,0]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":56,"s":[310.345,5.738],"e":[310.345,5.738],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":89,"s":[310.345,5.738],"e":[216.419,243.707],"to":[-15.654296875,39.6614570617676],"ti":[15.654296875,-39.6614570617676]},{"t":90}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":0,"s":[-1082],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":89,"s":[0],"e":[-1082]},{"t":90}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":13.934,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":89,"s":[0],"e":[100]},{"t":90}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[10.032,-3.369],[3.649,7.414],[-10.032,3.37],[-3.65,-7.414]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.91,0.32,0.61,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":0,"s":[220.852,243.393],"e":[503.969,162.999],"to":[47.1861991882324,-13.3990888595581],"ti":[-47.1861991882324,13.3990888595581]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":56,"s":[503.969,162.999],"e":[503.969,162.999],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":89,"s":[503.969,162.999],"e":[220.852,243.393],"to":[-47.1861991882324,13.3990888595581],"ti":[47.1861991882324,-13.3990888595581]},{"t":90}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":0,"s":[-1636],"e":[0]},{"i":{"x":[0],"y":[0]},"o":{"x":[0.167],"y":[0.167]},"n":["0_0_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":89,"s":[0],"e":[-1636]},{"t":90}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":17.733,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":89,"s":[0],"e":[100]},{"t":90}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[5.635,-8.958],[7.518,3.43],[-5.635,8.958],[-7.518,-3.431]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.65,0.86,0.87,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":0,"s":[216.978,239.574],"e":[167.638,-20.883],"to":[-8.22330760955811,-43.4095039367676],"ti":[8.22330760955811,43.4095039367676]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":34,"s":[167.638,-20.883],"e":[167.638,-20.883],"to":[0,0],"ti":[0,0]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":56,"s":[167.638,-20.883],"e":[167.638,-20.883],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":89,"s":[167.638,-20.883],"e":[216.978,239.574],"to":[8.22330760955811,43.4095039367676],"ti":[-8.22330760955811,-43.4095039367676]},{"t":90}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":0,"s":[791],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":34,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":89,"s":[0],"e":[791]},{"t":90}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":10.767,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":34,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":89,"s":[0],"e":[100]},{"t":90}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[12.714,-4.27],[4.625,9.396],[-12.714,4.27],[-4.625,-9.396]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[1,0.77,0.07,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":0,"s":[216.807,247.359],"e":[306.713,-26.422],"to":[14.984375,-45.6302070617676],"ti":[-14.984375,45.6302070617676]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":35,"s":[306.713,-26.422],"e":[306.713,-26.422],"to":[0,0],"ti":[0,0]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":56,"s":[306.713,-26.422],"e":[306.713,-26.422],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":89,"s":[306.713,-26.422],"e":[216.807,247.359],"to":[-14.984375,45.6302070617676],"ti":[14.984375,-45.6302070617676]},{"t":90}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":0,"s":[-1349],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":89,"s":[0],"e":[-1349]},{"t":90}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":11.084,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":89,"s":[0],"e":[100]},{"t":90}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16.462,-5.529],[5.988,12.166],[-16.462,5.529],[-5.99,-12.166]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.89,0.91,0.92,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":0,"s":[220.337,243.096],"e":[496.388,105.69],"to":[46.0084648132324,-22.9010410308838],"ti":[-46.0084648132324,22.9010410308838]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":50,"s":[496.388,105.69],"e":[496.388,105.69],"to":[0,0],"ti":[0,0]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":56,"s":[496.388,105.69],"e":[496.388,105.69],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":89,"s":[496.388,105.69],"e":[220.337,243.096],"to":[-46.0084648132324,22.9010410308838],"ti":[46.0084648132324,-22.9010410308838]},{"t":90}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":0,"s":[1085],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":50,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":89,"s":[0],"e":[1085]},{"t":90}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15.834,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":50,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":89,"s":[0],"e":[100]},{"t":90}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":2,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[7.21,-15.799],[12.976,3.938],[-7.209,15.799],[-12.976,-3.938]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.89,0.91,0.92,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":0,"s":[216.862,239.004],"e":[502.475,218.079],"to":[47.6022148132324,-3.48763012886047],"ti":[-47.6022148132324,3.48763012886047]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":28,"s":[502.475,218.079],"e":[502.475,218.079],"to":[0,0],"ti":[0,0]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":56,"s":[502.475,218.079],"e":[502.475,218.079],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":89,"s":[502.475,218.079],"e":[216.862,239.004],"to":[-47.6022148132324,3.48763012886047],"ti":[47.6022148132324,-3.48763012886047]},{"t":90}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":0,"s":[544],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":28,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":89,"s":[0],"e":[544]},{"t":90}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":8.867,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":28,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":89,"s":[0],"e":[100]},{"t":90}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[11.889,12.659],[-8.563,10.515],[-11.889,-12.659],[8.562,-10.516]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.89,0.91,0.92,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":0,"s":[219.276,237.668],"e":[218.221,-27.157],"to":[-0.17578125,-44.1373710632324],"ti":[0.17578125,44.1373710632324]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":42,"s":[218.221,-27.157],"e":[218.221,-27.157],"to":[0,0],"ti":[0,0]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":56,"s":[218.221,-27.157],"e":[218.221,-27.157],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":89,"s":[218.221,-27.157],"e":[219.276,237.668],"to":[0.17578125,44.1373710632324],"ti":[-0.17578125,-44.1373710632324]},{"t":90}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":0,"s":[-1017],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":42,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":89,"s":[0],"e":[-1017]},{"t":90}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":13.301,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":42,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":89,"s":[0],"e":[100]},{"t":90}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":2,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[11.889,12.66],[-8.562,10.516],[-11.889,-12.66],[8.562,-10.515]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.89,0.91,0.92,1]},"o":{"a":0,"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.167,"y":0.167},"n":"0_1_0p167_0p167","t":0,"s":[219.081,240.186],"e":[-48.224,-10.22],"to":[-44.55078125,-41.734375],"ti":[44.55078125,41.734375]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":25,"s":[-48.224,-10.22],"e":[-48.224,-10.22],"to":[0,0],"ti":[0,0]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":56,"s":[-48.224,-10.22],"e":[-48.224,-10.22],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"n":"0p833_0p833_0p167_0","t":89,"s":[-48.224,-10.22],"e":[219.081,240.186],"to":[44.55078125,41.734375],"ti":[-44.55078125,-41.734375]},{"t":90}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":0,"s":[1408],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":25,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0]},"n":["0p833_0p833_0p167_0"],"t":89,"s":[0],"e":[1408]},{"t":90}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":7.917,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":25,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":89,"s":[0],"e":[100]},{"t":90}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10","np":2,"mn":"ADBE Vector Group"}],"ip":0,"op":450,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":13,"ty":1,"nm":"White Solid 1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[400,398,0]},"a":{"a":0,"k":[400,400,0]},"s":{"a":0,"k":[100,100,100]}},"ao":0,"sw":800,"sh":800,"sc":"","ip":0,"op":600,"st":0,"bm":0,"sr":1}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/static_dynamic_dash.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/static_dynamic_dash.json deleted file mode 100644 index 9ebce590..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/static_dynamic_dash.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.17","fr":29.9700012207031,"ip":0,"op":150.000006109625,"w":300,"h":300,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,150.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":20,"s":[135,135],"e":[116,116]},{"t":137.000005580124}],"ix":2},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[24,25],"e":[57,52],"to":[5.5,4.5],"ti":[-5.5,-4.5]},{"t":129.000005254278}],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[54]},{"t":149.000006068894}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.402888119221,0.437488675117,0.552941203117,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[100,100],"e":[50,50]},{"t":40.0000016292334}],"ix":2},"p":{"a":0,"k":[-26,-37],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.145327582955,0.057777773589,0.866666674614,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 2","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":5,"ix":3},"p":{"a":0,"k":[26,-54],"ix":4},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":110,"s":[0],"e":[184]},{"t":149.000006068894}],"ix":5},"ir":{"a":0,"k":30,"ix":6},"is":{"a":0,"k":27,"ix":8},"or":{"a":0,"k":59,"ix":7},"os":{"a":0,"k":73,"ix":9},"ix":6,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"fl","c":{"a":0,"k":[0.07993286103,0.716212213039,0.766274511814,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 3","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":15,"ix":5},"lc":2,"lj":1,"ml":4,"d":[{"n":"d","nm":"dash","v":{"a":0,"k":25,"ix":1}},{"n":"o","nm":"offset","v":{"a":0,"k":0,"ix":7}}],"nm":"Stroke 2","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":150.000006109625,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/telegram.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/telegram.json deleted file mode 100644 index c0bb08e3..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/telegram.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.10.1","fr":29.9700012207031,"ip":0,"op":120.0000048877,"w":200,"h":320,"nm":"telegram","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"paperplane","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.953,-6.222,0],"ix":2},"a":{"a":0,"k":[-2.453,-6.222,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.132,-4.625],[0,0],[0,0],[-2.25,-2.25],[0,0],[0,0],[-5.125,0.312],[0,0],[0,0],[2.75,3.5]],"o":[[0,0],[0,0],[-0.125,4.375],[0,0],[0,0],[2.25,2.25],[0,0],[0,0],[4.243,-0.259],[0,0],[0,0],[-3.169,-4.033]],"v":[[27.125,-46.625],[-39.25,-23.5],[-44.75,-17.125],[-40.125,-10.25],[-22.625,-2.125],[-13.25,3.125],[-8,11],[0.75,29.625],[8.5,35.813],[15.125,29.25],[38.75,-36.25],[38.5,-46.375]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"logo circle","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1.5,-15,0],"ix":2},"a":{"a":0,"k":[1.5,-14.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[175,175],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.172549019608,0.647058823529,0.878431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.5,-14.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"mother","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":0,"s":[102,239,0],"e":[102,160,0],"to":[0,-13.1666669845581,0],"ti":[0,26.3333339691162,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":6,"s":[102,160,0],"e":[102,81,0],"to":[0,-26.3333339691162,0],"ti":[0,13.1666669845581,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.167,"y":0.167},"n":"0p667_0p667_0p167_0p167","t":19,"s":[102,81,0],"e":[102,81,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":21,"s":[102,81,0],"e":[102,156,0],"to":[0,12.5,0],"ti":[0,-26.3333339691162,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":25,"s":[102,156,0],"e":[102,239,0],"to":[0,26.3333339691162,0],"ti":[0,-0.66666668653488,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":28,"s":[102,239,0],"e":[102,160,0],"to":[0,0.66666668653488,0],"ti":[0,26.3333339691162,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":34,"s":[102,160,0],"e":[102,81,0],"to":[0,-26.3333339691162,0],"ti":[0,13.1666669845581,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.167,"y":0.167},"n":"0p667_0p667_0p167_0p167","t":47,"s":[102,81,0],"e":[102,81,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":49,"s":[102,81,0],"e":[102,156,0],"to":[0,12.5,0],"ti":[0,-26.3333339691162,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":53,"s":[102,156,0],"e":[102,239,0],"to":[0,26.3333339691162,0],"ti":[0,-9.83333301544189,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":56,"s":[102,239,0],"e":[102,215,0],"to":[0,9.83333301544189,0],"ti":[0,4,0]},{"t":60.0000024438501}],"ix":2},"a":{"a":0,"k":[1.5,-14.5,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":0,"s":[100,71.429,100],"e":[82,98.966,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":6,"s":[82,98.966,100],"e":[100,77.143,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"n":["0p667_1_0p167_0","0p667_1_0p167_0","0p667_1_0p167_0"],"t":19,"s":[100,77.143,100],"e":[100,77.143,100]},{"i":{"x":[0.703,0.703,0.703],"y":[1,1,1]},"o":{"x":[0.185,0.185,0.185],"y":[0,0,0]},"n":["0p703_1_0p185_0","0p703_1_0p185_0","0p703_1_0p185_0"],"t":21,"s":[100,77.143,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":25,"s":[100,100,100],"e":[100,71.429,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":28,"s":[100,71.429,100],"e":[82.857,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":34,"s":[82.857,100,100],"e":[100,77.143,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"n":["0p667_1_0p167_0","0p667_1_0p167_0","0p667_1_0p167_0"],"t":47,"s":[100,77.143,100],"e":[100,77.143,100]},{"i":{"x":[0.703,0.703,0.703],"y":[1,1,1]},"o":{"x":[0.185,0.185,0.185],"y":[0,0,0]},"n":["0p703_1_0p185_0","0p703_1_0p185_0","0p703_1_0p185_0"],"t":49,"s":[100,77.143,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":53,"s":[100,100,100],"e":[100,71.429,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":56,"s":[100,71.429,100],"e":[100,100,100]},{"t":60.0000024438501}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[175,175],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.172549019608,0.647058823529,0.878431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.5,-14.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"shadow","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[102,303.6,0],"ix":2},"a":{"a":0,"k":[-4,329,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":0,"s":[60,60,100],"e":[42,42,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":6,"s":[42,42,100],"e":[60,60,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_1_0p333_0","0p833_1_0p333_0","0p833_1_0p333_0"],"t":19,"s":[60,60,100],"e":[55,55,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"n":["0p667_1_0p167_0","0p667_1_0p167_0","0p667_1_0p167_0"],"t":25,"s":[55,55,100],"e":[60,60,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":28,"s":[60,60,100],"e":[42,42,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":34,"s":[42,42,100],"e":[60,60,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_1_0p333_0","0p833_1_0p333_0","0p833_1_0p333_0"],"t":47,"s":[60,60,100],"e":[55,55,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"n":["0p667_1_0p167_0","0p667_1_0p167_0","0p667_1_0p167_0"],"t":53,"s":[55,55,100],"e":[60,60,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"n":["0p833_1_0p167_0","0p833_1_0p167_0","0p833_1_0p167_0"],"t":56,"s":[60,60,100],"e":[55,55,100]},{"t":60.0000024438501}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[380,26],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333333333,0.933333333333,0.933333333333,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-4,329],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[74.737,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.00001221925,"st":0,"bm":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/test/repro_infinite_loop.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/test/repro_infinite_loop.json deleted file mode 100644 index d31293cc..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/test/repro_infinite_loop.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.16","fr":15,"ip":0,"op":51,"w":500,"h":500,"nm":"El 28","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Circle Abstract","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":49,"s":[100],"e":[0]},{"t":51}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250.316,250.684,0],"ix":2},"a":{"a":0,"k":[280,0,0],"ix":1},"s":{"a":0,"k":[225,225,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[145,145],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"A - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.1901,0.8897,0.972549019608,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.583]},"o":{"x":[0.01],"y":[0.006]},"n":["0p833_0p583_0p01_0p006"],"t":22.2,"s":[3],"e":[0]},{"t":49.2001953125}],"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[236,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.99,0.99],"y":[0.997,0.997]},"o":{"x":[1,1],"y":[1,1]},"n":["0p99_0p997_1_1","0p99_0p997_1_1"],"t":0,"s":[0,0],"e":[50,50]},{"i":{"x":[0.833,0.833],"y":[0.676,0.676]},"o":{"x":[0.01,0.01],"y":[0.043,0.043]},"n":["0p833_0p676_0p01_0p043","0pp043"],"t":6,"s":[50,50],"e":[75,75]},{"t":49.20}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"rp","c":{"a":1,"k":[{"i":{"x":[0.99],"y":[0.985]},"o":{"x":[1],"y":[2.692]},"n":["0p99_0p985_1_2p692"],"t":0,"s":[0],"e":[18]},{"i":{"x":[0.833],"y":[0.288]},"o":{"x":[0.01],"y":[-0.02]},"n":["0p833_0p288_0p01_-0p02"],"t":21,"s":[18],"e":[0]},{"t":49.2001953125}],"ix":1},"o":{"a":0,"k":5,"ix":2},"m":1,"ix":2,"tr":{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[280,0],"ix":1},"s":{"a":0,"k":[900,100],"ix":3},"r":{"a":0,"k":20,"ix":4},"so":{"a":0,"k":100,"ix":5},"eo":{"a":0,"k":100,"ix":6},"nm":"Transform"},"nm":"Repeater 1","mn":"ADBE Vector Filter - Repeater","hd":false}],"ip":0,"op":51,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/test/repro_propertyhelper_type_confusion1.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/test/repro_propertyhelper_type_confusion1.json deleted file mode 100644 index 283f4011..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/test/repro_propertyhelper_type_confusion1.json +++ /dev/null @@ -1,356 +0,0 @@ -{ - "v": "5.1.17", - "fr": 29.9700012207031, - "ip": 0, - "op": 150.000006109625, - "w": 300, - "h": 300, - "nm": "Comp 1", - "ddd": 0, - "assets": [], - "layers": [ - { - "ddd": 0, - "ind": 1, - "ty": 4, - "nm": "Shape Layer 1", - "sr": 1, - "ks": { - "o": { - "a": 0, - "k": [{"t": 24}], - "k": 100, - "ix": 11 - }, - "r": { - "a": 0, - "k": 0, - "ix": 10 - }, - "p": { - "a": 0, - "k": [ - 152, - 152, - 0 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100, - 100 - ], - "ix": 6 - } - }, - "ao": 0, - "shapes": [ - { - "ty": "sr", - "sy": 1, - "d": 2, - "pt": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 0, - "s": [ - 5 - ], - "e": [ - 11 - ] - }, - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 90, - "s": [ - 11 - ], - "e": [ - 15 - ] - }, - { - "t": 146.000005946702 - } - ], - "ix": 3 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 4 - }, - "r": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 0, - "s": [ - 0 - ], - "e": [ - 64 - ] - }, - { - "t": 90.0000036657751 - } - ], - "ix": 5 - }, - "ir": { - "a": 0, - "k": 106, - "ix": 6 - }, - "is": { - "a": 0, - "k": 231, - "ix": 8 - }, - "or": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 0, - "s": [ - 102 - ], - "e": [ - 142 - ] - }, - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 90, - "s": [ - 142 - ], - "e": [ - 34 - ] - }, - { - "t": 146.000005946702 - } - ], - "ix": 7 - }, - "os": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 0, - "s": [ - 79 - ], - "e": [ - 265 - ] - }, - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 90, - "s": [ - 265 - ], - "e": [ - 88 - ] - }, - { - "t": 146.000005946702 - } - ], - "ix": 9 - }, - "ix": 1, - "nm": "Polystar Path 1", - "mn": "ADBE Vector Shape - Star", - "hd": false - }, - { - "ty": "st", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ], - "ix": 3 - }, - "o": { - "a": 0, - "k": 100, - "ix": 4 - }, - "w": { - "a": 0, - "k": 2, - "ix": 5 - }, - "lc": 1, - "lj": 1, - "ml": 4, - "nm": "Stroke 2", - "mn": "ADBE Vector Graphic - Stroke", - "hd": false - } - ], - "ip": 0, - "op": 150.000006109625, - "st": 0, - "bm": 0 - } - ], - "markers": [] -} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/test/repro_propertyhelper_type_confusion2.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/test/repro_propertyhelper_type_confusion2.json deleted file mode 100644 index 6e4c223f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/test/repro_propertyhelper_type_confusion2.json +++ /dev/null @@ -1,355 +0,0 @@ -{ - "v": "5.1.17", - "fr": 29.9700012207031, - "ip": 0, - "op": 150.000006109625, - "w": 300, - "h": 300, - "nm": "Comp 1", - "ddd": 0, - "assets": [], - "layers": [ - { - "ddd": 0, - "ind": 1, - "ty": 4, - "nm": "Shape Layer 1", - "sr": 1, - "ks": { - "o": { - "a": 0, - "k": [{"t": 24}, 239, 239, 239], - "ix": 11 - }, - "r": { - "a": 0, - "k": 0, - "ix": 10 - }, - "p": { - "a": 0, - "k": [ - 152, - 152, - 0 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100, - 100 - ], - "ix": 6 - } - }, - "ao": 0, - "shapes": [ - { - "ty": "sr", - "sy": 1, - "d": 2, - "pt": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 0, - "s": [ - 5 - ], - "e": [ - 11 - ] - }, - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 90, - "s": [ - 11 - ], - "e": [ - 15 - ] - }, - { - "t": 146.000005946702 - } - ], - "ix": 3 - }, - "p": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 4 - }, - "r": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 0, - "s": [ - 0 - ], - "e": [ - 64 - ] - }, - { - "t": 90.0000036657751 - } - ], - "ix": 5 - }, - "ir": { - "a": 0, - "k": 106, - "ix": 6 - }, - "is": { - "a": 0, - "k": 231, - "ix": 8 - }, - "or": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 0, - "s": [ - 102 - ], - "e": [ - 142 - ] - }, - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 90, - "s": [ - 142 - ], - "e": [ - 34 - ] - }, - { - "t": 146.000005946702 - } - ], - "ix": 7 - }, - "os": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 0, - "s": [ - 79 - ], - "e": [ - 265 - ] - }, - { - "i": { - "x": [ - 0.833 - ], - "y": [ - 0.833 - ] - }, - "o": { - "x": [ - 0.167 - ], - "y": [ - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167" - ], - "t": 90, - "s": [ - 265 - ], - "e": [ - 88 - ] - }, - { - "t": 146.000005946702 - } - ], - "ix": 9 - }, - "ix": 1, - "nm": "Polystar Path 1", - "mn": "ADBE Vector Shape - Star", - "hd": false - }, - { - "ty": "st", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ], - "ix": 3 - }, - "o": { - "a": 0, - "k": 100, - "ix": 4 - }, - "w": { - "a": 0, - "k": 2, - "ix": 5 - }, - "lc": 1, - "lj": 1, - "ml": 4, - "nm": "Stroke 2", - "mn": "ADBE Vector Graphic - Stroke", - "hd": false - } - ], - "ip": 0, - "op": 150.000006109625, - "st": 0, - "bm": 0 - } - ], - "markers": [] -} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/test/repro_sbof.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/test/repro_sbof.json deleted file mode 100644 index 6e6b7749..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/test/repro_sbof.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.8","fr":23.97547,"ip":0,"op":29140721,"w":300,"h":300,"nm":"Syroto_Loader","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Layer 2 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[-180],"e":[180]},{"t":239.9974}],"ix":10},"p":{"a":0,"k":[150.125,150,0],"ix":2},"a":{"a":0,"k":[533,533,0],"ix":1},"s":{"a":0,"k":[16E16,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[65.74,-27.805],[48.897,-48.895],[26.837,-63.449],[0,-71.877],[-27.805,-65.739],[-48.894,-48.896],[-63.449,-26.837],[-71.878,0],[-65.739,27.805],[-48.895,48.895],[-26.837,63.449],[0,71.878],[27.805,65.739],[48.896,48.896],[63.449,26.837],[71.877,0]],"o":[[-63.449,26.837],[-48.894,48.896],[-27.805,65.739],[0,71.878],[26.837,63.449],[48.897,48.895],[65.74,27.805],[71.877,0],[63.449,-26.837],[48.896,-48.896],[27.805,-65.739],[0,-71.877],[-26.837,-63.449],[-48.895,-48.895],[-65.739,-27.805],[-71.878,0]],"v":[[-207.395,-490.833],[-376.703,-376.703],[-490.833,-207.394],[-532.735,0],[-490.833,207.393],[-376.703,376.702],[-207.395,490.833],[0,532.735],[207.394,490.833],[376.702,376.702],[490.833,207.393],[532.738,0],[490.833,-207.394],[376.702,-376.703],[207.394,-490.833],[0,-532.738]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Voup","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[65.201,65.2],[0,92.206],[-65.199,65.2],[-92.207,0],[-65.2,-65.2],[0,-92.206],[65.2,-65.201],[92.206,0]],"o":[[-65.199,-65.201],[0,-92.206],[65.201,-65.2],[92.206,0],[65.2,65.2],[0,92.206],[-65.2,65.2],[-92.207,0]],"v":[[-244.095,244.094],[-345.202,0],[-244.095,-244.094],[0,-345.202],[244.095,-244.094],[345.202,0],[244.095,244.094],[0,345.202]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"g":{"p":3,"k":{"a":0,"k":[0,0.133,0.063,0.282,0.5,0.386,0.257,0.459,1,0.639,0.451,0.635],"ix":9}},"s":{"a":0,"k":[661,0],"ix":5},"e":{"a":0,"k":[-690,0],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[533,533],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":720.5269,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Layer 1 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[180],"e":[-180]},{"t":239.9274}],"ix":10},"p":{"a":0,"k":[150.125,150,0],"ix":2},"a":{"a":0,"k":[726,726,0],"ix":1},"s":{"a":0,"k":[16,16,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-400.378],[-400.379,0],[0,400.378],[400.378,0]],"o":[[0,400.378],[400.378,0],[0,-400.378],[-400.379,0]],"v":[[-724.948,0],[0,724.949],[724.948,0],[0,-724.949]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"g":{"p":3,"k":{"a":0,"k":[0,0.133,0.063,0.282,0.5,0.386,0.257,0.459,1,0.639,0.451,0.635],"ix":9}},"s":{"a":0,"k":[200,0],"ix":5},"e":{"a":0,"k":[-608,0],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":false},{"ty":"tr","p":{"a":0,"k":[726,726],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":180,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":72095269,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/test/repro_shapeproperty_type_confusion1.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/test/repro_shapeproperty_type_confusion1.json deleted file mode 100644 index 02b4a3f2..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/test/repro_shapeproperty_type_confusion1.json +++ /dev/null @@ -1,8681 +0,0 @@ -{ - "v": "4.10.2", - "fr": 30, - "ip": 0, - "op": 58, - "w": 800, - "h": 800, - "nm": "Fancy 2", - "ddd": 0, - "assets": [], - "layers": [ - { - "ddd": 0, - "ind": 2, - "ty": 3, - "nm": "GLOBAL", - "sr": 1, - "ks": { - "o": { - "a": 0, - "k": 0, - "ix": 11 - }, - "r": { - "a": 0, - "k": 0, - "ix": 10 - }, - "p": { - "a": 0, - "k": [ - 54, - 551, - 0 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100, - 100 - ], - "ix": 6 - } - }, - "ao": 0, - "ip": 0, - "op": 218, - "st": 0, - "bm": 0 - }, - { - "ddd": 0, - "ind": 3, - "ty": 4, - "nm": "Hat Outlines", - "parent": 9, - "sr": 1, - "ks": { - "o": { - "a": 0, - "k": 100, - "ix": 11 - }, - "r": { - "a": 0, - "k": 0, - "ix": 10 - }, - "p": { - "a": 1, - "k": [ - { - "i": { - "x": 0.158, - "y": 1 - }, - "o": { - "x": 0.075, - "y": 0.312 - }, - "n": "0p158_1_0p075_0p312", - "t": 14, - "s": [ - 555.632, - 379.901, - 0 - ], - "e": [ - 568.441, - 362.019, - 0 - ], - "to": [ - 0, - 0, - 0 - ], - "ti": [ - 0, - 0, - 0 - ] - }, - { - "i": { - "x": 0.842, - "y": 1 - }, - "o": { - "x": 1, - "y": 0 - }, - "n": "0p842_1_1_0", - "t": 29, - "s": [ - 568.441, - 362.019, - 0 - ], - "e": [ - 555.632, - 379.901, - 0 - ], - "to": [ - 0, - 0, - 0 - ], - "ti": [ - 0, - 0, - 0 - ] - }, - { - "t": 34 - } - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 555.632, - 379.901, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100, - 100 - ], - "ix": 6 - } - }, - "ao": 0, - "shapes": [ - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": [{"t": 239}], - "k": { - "i": [ - [ - 1.296, - 0.995 - ], - [ - 0, - 0 - ], - [ - 0.995, - -1.296 - ], - [ - -1.296, - -0.995 - ], - [ - 0, - 0 - ], - [ - -0.995, - 1.296 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - -1.296, - -0.995 - ], - [ - -0.996, - 1.297 - ], - [ - 0, - 0 - ], - [ - 1.297, - 0.995 - ], - [ - 0.995, - -1.296 - ] - ], - "v": [ - [ - 28.034, - 17.79 - ], - [ - -24.43, - -22.485 - ], - [ - -28.578, - -21.94 - ], - [ - -28.033, - -17.791 - ], - [ - 24.43, - 22.484 - ], - [ - 28.578, - 21.939 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 555.56, - 383.074 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 1", - "np": 2, - "cix": 2, - "ix": 1, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 4.026, - 3.091 - ], - [ - 0, - 0 - ], - [ - 3.091, - -4.026 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - -4.026, - -3.091 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 3.091, - -4.026 - ] - ], - "v": [ - [ - 19.117, - -2.46 - ], - [ - -2.198, - -18.822 - ], - [ - -15.085, - -17.129 - ], - [ - -23.902, - -5.643 - ], - [ - 11.993, - 21.914 - ], - [ - 20.811, - 10.428 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 562.183, - 374.355 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 2", - "np": 2, - "cix": 2, - "ix": 2, - "mn": "ADBE Vector Group", - "hd": false - } - ], - "ip": 0, - "op": 218, - "st": 0, - "bm": 0 - }, - { - "ddd": 0, - "ind": 4, - "ty": 4, - "nm": "Tie Outlines", - "parent": 8, - "sr": 1, - "ks": { - "o": { - "a": 0, - "k": 100, - "ix": 11 - }, - "r": { - "a": 0, - "k": 0, - "ix": 10 - }, - "p": { - "a": 0, - "k": [ - 502.404, - 453, - 0 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 502.404, - 453, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100, - 100 - ], - "ix": 6 - } - }, - "ao": 0, - "shapes": [ - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0.852, - 0.654 - ], - [ - 0, - 0 - ], - [ - 0.654, - -0.852 - ], - [ - 0, - 0 - ], - [ - -0.852, - -0.654 - ], - [ - 0, - 0 - ], - [ - -0.654, - 0.852 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - -0.852, - -0.654 - ], - [ - 0, - 0 - ], - [ - -0.654, - 0.852 - ], - [ - 0, - 0 - ], - [ - 0.852, - 0.654 - ], - [ - 0, - 0 - ], - [ - 0.654, - -0.852 - ] - ], - "v": [ - [ - 6.301, - -1.525 - ], - [ - -0.156, - -6.48 - ], - [ - -2.893, - -6.12 - ], - [ - -6.661, - -1.214 - ], - [ - -6.301, - 1.525 - ], - [ - 0.155, - 6.48 - ], - [ - 2.893, - 6.121 - ], - [ - 6.66, - 1.215 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 501.763, - 453.567 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 1", - "np": 2, - "cix": 2, - "ix": 1, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - -0.864, - 1.125 - ], - [ - 0, - 0 - ], - [ - 1.467, - 0.227 - ], - [ - 0, - 0 - ], - [ - -0.761, - -1.42 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 0.904, - -1.178 - ], - [ - 0, - 0 - ], - [ - -1.592, - -0.246 - ], - [ - 0, - 0 - ], - [ - 0.67, - 1.25 - ] - ], - "v": [ - [ - 0.98, - 7.35 - ], - [ - 8.825, - -2.868 - ], - [ - 7.574, - -5.988 - ], - [ - -6.948, - -8.229 - ], - [ - -8.967, - -5.376 - ], - [ - -2.291, - 7.083 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 512.737, - 462.455 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 2", - "np": 2, - "cix": 2, - "ix": 2, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - -0.864, - 1.125 - ], - [ - 0, - 0 - ], - [ - -0.598, - -1.359 - ], - [ - 0, - 0 - ], - [ - 1.568, - 0.368 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 0.904, - -1.178 - ], - [ - 0, - 0 - ], - [ - 0.649, - 1.474 - ], - [ - 0, - 0 - ], - [ - -1.381, - -0.324 - ] - ], - "v": [ - [ - -8.442, - 2.354 - ], - [ - -0.597, - -7.865 - ], - [ - 2.74, - -7.462 - ], - [ - 8.657, - 5.987 - ], - [ - 6.423, - 8.675 - ], - [ - -7.339, - 5.445 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 491.688, - 444.06 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 3", - "np": 2, - "cix": 2, - "ix": 3, - "mn": "ADBE Vector Group", - "hd": false - } - ], - "ip": 0, - "op": 218, - "st": 0, - "bm": 0 - }, - { - "ddd": 0, - "ind": 5, - "ty": 4, - "nm": "Legs Right", - "parent": 9, - "sr": 1, - "ks": { - "o": { - "a": 0, - "k": 100, - "ix": 11 - }, - "r": { - "a": 0, - "k": 0, - "ix": 10 - }, - "p": { - "a": 0, - "k": [ - 411.027, - 495.735, - 0 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 411.027, - 495.735, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100, - 100 - ], - "ix": 6 - } - }, - "ao": 0, - "shapes": [ - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - -4.8, - -3.743 - ], - [ - -3.758, - 4.746 - ] - ], - "o": [ - [ - -3.743, - 4.8 - ], - [ - 4.774, - 3.723 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - -6.793, - -9.596 - ], - [ - -4.88, - 5.873 - ], - [ - 10.536, - 4.028 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 410.821, - 497.93 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 2", - "np": 2, - "cix": 2, - "ix": 2, - "mn": "ADBE Vector Group", - "hd": false - } - ], - "ip": 0, - "op": 218, - "st": 0, - "bm": 0 - }, - { - "ddd": 0, - "ind": 6, - "ty": 4, - "nm": "Legs Left", - "parent": 9, - "sr": 1, - "ks": { - "o": { - "a": 0, - "k": 100, - "ix": 11 - }, - "r": { - "a": 0, - "k": 0, - "ix": 10 - }, - "p": { - "a": 0, - "k": [ - 483.024, - 549.985, - 0 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 483.024, - 549.985, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100, - 100 - ], - "ix": 6 - } - }, - "ao": 0, - "shapes": [ - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - -4.8, - -3.743 - ], - [ - -3.758, - 4.746 - ] - ], - "o": [ - [ - -3.743, - 4.8 - ], - [ - 4.774, - 3.723 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - -6.793, - -9.596 - ], - [ - -4.88, - 5.873 - ], - [ - 10.536, - 4.028 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 481.814, - 552.431 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 1", - "np": 2, - "cix": 2, - "ix": 1, - "mn": "ADBE Vector Group", - "hd": false - } - ], - "ip": 0, - "op": 218, - "st": 0, - "bm": 0 - }, - { - "ddd": 0, - "ind": 7, - "ty": 4, - "nm": "Eyes", - "parent": 9, - "sr": 1, - "ks": { - "o": { - "a": 0, - "k": 100, - "ix": 11 - }, - "r": { - "a": 0, - "k": 0, - "ix": 10 - }, - "p": { - "a": 0, - "k": [ - 528.919, - 419.966, - 0 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 528.919, - 419.966, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100, - 100 - ], - "ix": 6 - } - }, - "ao": 0, - "hasMask": true, - "masksProperties": [ - { - "inv": false, - "mode": "a", - "pt": { - "a": 1, - "k": [ - { - "i": { - "x": 0.833, - "y": 0.833 - }, - "o": { - "x": 0.167, - "y": 0.167 - }, - "n": "0p833_0p833_0p167_0p167", - "t": 19, - "s": [ - { - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 498.824, - 384.003 - ], - [ - 487.435, - 399.044 - ], - [ - 565.432, - 458.108 - ], - [ - 576.822, - 443.068 - ] - ], - "c": true - } - ], - "e": [ - { - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 493.78, - 392.277 - ], - [ - 491.988, - 393.65 - ], - [ - 566.012, - 450.516 - ], - [ - 567.804, - 449.143 - ] - ], - "c": true - } - ] - }, - { - "i": { - "x": 0.833, - "y": 0.833 - }, - "o": { - "x": 0.167, - "y": 0.167 - }, - "n": "0p833_0p833_0p167_0p167", - "t": 22, - "s": [ - { - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 493.78, - 392.277 - ], - [ - 491.988, - 393.65 - ], - [ - 566.012, - 450.516 - ], - [ - 567.804, - 449.143 - ] - ], - "c": true - } - ], - "e": [ - { - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 498.824, - 384.003 - ], - [ - 487.435, - 399.044 - ], - [ - 565.432, - 458.108 - ], - [ - 576.822, - 443.068 - ] - ], - "c": true - } - ] - }, - { - "t": 25 - } - ], - "ix": 1 - }, - "o": { - "a": 0, - "k": 100, - "ix": 3 - }, - "x": { - "a": 0, - "k": 0, - "ix": 4 - }, - "nm": "Mask 1" - } - ], - "shapes": [ - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - -2.335, - 3.042 - ], - [ - 3.043, - 2.335 - ], - [ - 2.336, - -3.042 - ], - [ - -3.042, - -2.336 - ] - ], - "o": [ - [ - 2.336, - -3.042 - ], - [ - -3.042, - -2.336 - ], - [ - -2.335, - 3.043 - ], - [ - 3.042, - 2.335 - ] - ], - "v": [ - [ - 5.508, - 4.229 - ], - [ - 4.228, - -5.508 - ], - [ - -5.509, - -4.229 - ], - [ - -4.229, - 5.509 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 556.462, - 441.11 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 1", - "np": 2, - "cix": 2, - "ix": 1, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - -2.335, - 3.042 - ], - [ - 3.043, - 2.335 - ], - [ - 2.336, - -3.042 - ], - [ - -3.042, - -2.336 - ] - ], - "o": [ - [ - 2.335, - -3.042 - ], - [ - -3.042, - -2.336 - ], - [ - -2.335, - 3.043 - ], - [ - 3.042, - 2.335 - ] - ], - "v": [ - [ - 5.509, - 4.229 - ], - [ - 4.228, - -5.508 - ], - [ - -5.509, - -4.229 - ], - [ - -4.229, - 5.509 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 501.377, - 398.823 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 2", - "np": 2, - "cix": 2, - "ix": 2, - "mn": "ADBE Vector Group", - "hd": false - } - ], - "ip": 0, - "op": 218, - "st": 0, - "bm": 0 - }, - { - "ddd": 0, - "ind": 8, - "ty": 4, - "nm": "belly", - "parent": 9, - "sr": 1, - "ks": { - "o": { - "a": 0, - "k": 100, - "ix": 11 - }, - "r": { - "a": 0, - "k": 0, - "ix": 10 - }, - "p": { - "a": 0, - "k": [ - 499.737, - 455.46, - 0 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 499.737, - 455.46, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100, - 100 - ], - "ix": 6 - } - }, - "ao": 0, - "shapes": [ - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - -8.652, - -6.643 - ], - [ - 6.642, - -8.652 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 6.642, - -8.652 - ], - [ - 8.652, - 6.642 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - -0.947, - -30.385 - ], - [ - 26.746, - -34.023 - ], - [ - 30.385, - -6.332 - ], - [ - -5.695, - 40.667 - ], - [ - -37.027, - 16.613 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 540.039, - 460.227 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 4", - "np": 2, - "cix": 2, - "ix": 1, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - -8.652, - -6.642 - ], - [ - 6.642, - -8.652 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 6.642, - -8.652 - ], - [ - 8.652, - 6.642 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - -0.947, - -30.385 - ], - [ - 26.746, - -34.024 - ], - [ - 30.385, - -6.332 - ], - [ - -5.695, - 40.666 - ], - [ - -37.027, - 16.613 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 483.324, - 416.688 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 5", - "np": 2, - "cix": 2, - "ix": 2, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - -1.347, - 9.496 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - -13.318, - -10.225 - ], - [ - 0, - 0 - ], - [ - -10.132, - 13.198 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - -10.132, - 13.199 - ], - [ - 0, - 0 - ], - [ - 13.318, - 10.224 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - -8.762, - 3.9 - ] - ], - "v": [ - [ - 11.966, - -28.935 - ], - [ - 18.368, - -74.081 - ], - [ - -15.857, - -70.098 - ], - [ - -62.668, - -9.121 - ], - [ - -56.898, - 33.289 - ], - [ - -17.082, - 63.857 - ], - [ - 25.379, - 58.471 - ], - [ - 72.799, - -3.298 - ], - [ - 70.701, - -34.535 - ], - [ - 29.089, - -16.01 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 493.819, - 462.152 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 7", - "np": 2, - "cix": 2, - "ix": 3, - "mn": "ADBE Vector Group", - "hd": false - } - ], - "ip": 0, - "op": 218, - "st": 0, - "bm": 0 - }, - { - "ddd": 0, - "ind": 9, - "ty": 4, - "nm": "Body", - "parent": 14, - "sr": 1, - "ks": { - "o": { - "a": 0, - "k": 100, - "ix": 11 - }, - "r": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.37 - ], - "y": [ - 1 - ] - }, - "o": { - "x": [ - 0.45 - ], - "y": [ - 0 - ] - }, - "n": [ - "0p37_1_0p45_0" - ], - "t": 0, - "s": [ - 50 - ], - "e": [ - -14.62 - ] - }, - { - "i": { - "x": [ - 0.674 - ], - "y": [ - -0.319 - ] - }, - "o": { - "x": [ - 0.341 - ], - "y": [ - 0 - ] - }, - "n": [ - "0p674_-0p319_0p341_0" - ], - "t": 19, - "s": [ - -14.62 - ], - "e": [ - -14.418 - ] - }, - { - "i": { - "x": [ - 0.56 - ], - "y": [ - 1 - ] - }, - "o": { - "x": [ - 0.64 - ], - "y": [ - 0.067 - ] - }, - "n": [ - "0p56_1_0p64_0p067" - ], - "t": 23, - "s": [ - -14.418 - ], - "e": [ - 50 - ] - }, - { - "t": 56 - } - ], - "ix": 10 - }, - "p": { - "a": 0, - "k": [ - 459.201, - 356.344, - 0 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 449.08, - 358.479, - 0 - ], - "ix": 1 - }, - "s": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.833, - 0.833, - 0.833 - ], - "y": [ - 0.833, - 0.833, - 0.833 - ] - }, - "o": { - "x": [ - 0.167, - 0.167, - 0.167 - ], - "y": [ - 0.167, - 0.167, - 0.167 - ] - }, - "n": [ - "0p833_0p833_0p167_0p167", - "0p833_0p833_0p167_0p167", - "0p833_0p833_0p167_0p167" - ], - "t": 6, - "s": [ - 100, - 100, - 100 - ], - "e": [ - 131, - 78, - 100 - ] - }, - { - "i": { - "x": [ - 0.27, - 0.27, - 0.27 - ], - "y": [ - 1, - 1, - 1 - ] - }, - "o": { - "x": [ - 0.167, - 0.167, - 0.167 - ], - "y": [ - 0.167, - 0.167, - 0 - ] - }, - "n": [ - "0p27_1_0p167_0p167", - "0p27_1_0p167_0p167", - "0p27_1_0p167_0" - ], - "t": 10, - "s": [ - 131, - 78, - 100 - ], - "e": [ - 100, - 100, - 100 - ] - }, - { - "t": 17 - } - ], - "ix": 6 - } - }, - "ao": 0, - "shapes": [ - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - -5.465, - 7.119 - ], - [ - 7.118, - 5.465 - ], - [ - 5.465, - -7.118 - ], - [ - -7.119, - -5.465 - ] - ], - "o": [ - [ - 5.465, - -7.119 - ], - [ - -7.119, - -5.465 - ], - [ - -5.466, - 7.119 - ], - [ - 7.119, - 5.465 - ] - ], - "v": [ - [ - 12.89, - 9.896 - ], - [ - 9.896, - -12.889 - ], - [ - -12.889, - -9.895 - ], - [ - -9.895, - 12.89 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "st", - "c": { - "a": 0, - "k": [ - 0.952999997606, - 0.808000033509, - 0.395999983245, - 1 - ], - "ix": 3 - }, - "o": { - "a": 0, - "k": 100, - "ix": 4 - }, - "w": { - "a": 0, - "k": 3, - "ix": 5 - }, - "lc": 1, - "lj": 1, - "ml": 10, - "nm": "Stroke 1", - "mn": "ADBE Vector Graphic - Stroke", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 555.002, - 442.372 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 1", - "np": 2, - "cix": 2, - "ix": 1, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - -1.92, - 1.1 - ], - [ - -3.672, - -2.82 - ], - [ - 1.116, - -4.212 - ], - [ - 1.755, - 1.347 - ] - ], - "o": [ - [ - -1.755, - -1.348 - ], - [ - 3.781, - -2.167 - ], - [ - 3.673, - 2.82 - ], - [ - -0.567, - 2.139 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - -7.978, - -1.473 - ], - [ - -7.691, - -6.658 - ], - [ - 4.632, - -5.83 - ], - [ - 8.617, - 5.861 - ], - [ - 3.682, - 7.478 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 521.655, - 428.655 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 2", - "np": 2, - "cix": 2, - "ix": 2, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - 1.126, - -0.646 - ], - [ - 2.156, - 1.654 - ], - [ - -0.656, - 2.472 - ], - [ - -1.03, - -0.791 - ] - ], - "o": [ - [ - 1.03, - 0.791 - ], - [ - -2.219, - 1.271 - ], - [ - -2.155, - -1.655 - ], - [ - 0.332, - -1.255 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 4.682, - 0.864 - ], - [ - 4.513, - 3.908 - ], - [ - -2.719, - 3.421 - ], - [ - -5.056, - -3.44 - ], - [ - -2.161, - -4.388 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 519.534, - 432.603 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 3", - "np": 2, - "cix": 2, - "ix": 3, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - -8.652, - -6.643 - ], - [ - 6.642, - -8.652 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 6.642, - -8.652 - ], - [ - 8.652, - 6.642 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - -0.947, - -30.385 - ], - [ - 26.746, - -34.023 - ], - [ - 30.385, - -6.332 - ], - [ - -5.695, - 40.667 - ], - [ - -37.027, - 16.613 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 540.039, - 460.227 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 4", - "np": 2, - "cix": 2, - "ix": 4, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - -8.652, - -6.642 - ], - [ - 6.642, - -8.652 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 6.642, - -8.652 - ], - [ - 8.652, - 6.642 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - -0.947, - -30.385 - ], - [ - 26.746, - -34.024 - ], - [ - 30.385, - -6.332 - ], - [ - -5.695, - 40.666 - ], - [ - -37.027, - 16.613 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 483.324, - 416.688 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 5", - "np": 2, - "cix": 2, - "ix": 5, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - 7.01, - 5.381 - ], - [ - -5.087, - 6.626 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - -5.087, - 6.626 - ], - [ - -7.009, - -5.381 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 1.419, - 23.922 - ], - [ - -20.483, - 26.176 - ], - [ - -23.964, - 4.436 - ], - [ - 3.667, - -31.556 - ], - [ - 29.05, - -12.07 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 527.549, - 419.108 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 6", - "np": 2, - "cix": 2, - "ix": 6, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - -1.347, - 9.496 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - -13.318, - -10.225 - ], - [ - 0, - 0 - ], - [ - -10.132, - 13.198 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - -10.132, - 13.199 - ], - [ - 0, - 0 - ], - [ - 13.318, - 10.224 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - -8.762, - 3.9 - ] - ], - "v": [ - [ - 11.966, - -28.935 - ], - [ - 18.368, - -74.081 - ], - [ - -15.857, - -70.098 - ], - [ - -62.668, - -9.121 - ], - [ - -56.898, - 33.289 - ], - [ - -17.082, - 63.857 - ], - [ - 25.379, - 58.471 - ], - [ - 72.799, - -3.298 - ], - [ - 70.701, - -34.535 - ], - [ - 29.089, - -16.01 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 493.819, - 462.152 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 7", - "np": 2, - "cix": 2, - "ix": 7, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 35.29, - 27.092 - ], - [ - 0, - 0 - ], - [ - 27.092, - -35.29 - ], - [ - 0, - 0 - ], - [ - -14.019, - -10.762 - ], - [ - 0, - 0 - ], - [ - -10.762, - 14.018 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - -35.29, - -27.092 - ], - [ - 0, - 0 - ], - [ - -10.762, - 14.018 - ], - [ - 0, - 0 - ], - [ - 14.018, - 10.761 - ], - [ - 0, - 0 - ], - [ - 27.092, - -35.289 - ] - ], - "v": [ - [ - 61.762, - -78.449 - ], - [ - 61.762, - -78.449 - ], - [ - -51.19, - -63.604 - ], - [ - -92.936, - -9.225 - ], - [ - -87.039, - 35.645 - ], - [ - -10.009, - 94.779 - ], - [ - 34.86, - 88.882 - ], - [ - 76.606, - 34.503 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 442.313, - 523.242 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - -52.793, - 64.655 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 8", - "np": 2, - "cix": 2, - "ix": 8, - "mn": "ADBE Vector Group", - "hd": false - } - ], - "ip": 0, - "op": 218, - "st": 0, - "bm": 0 - }, - { - "ddd": 0, - "ind": 10, - "ty": 4, - "nm": "Glass Outlines", - "parent": 11, - "sr": 1, - "ks": { - "o": { - "a": 0, - "k": 100, - "ix": 11 - }, - "r": { - "a": 0, - "k": 0, - "ix": 10 - }, - "p": { - "a": 0, - "k": [ - 601.505, - 484.344, - 0 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 601.505, - 484.344, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100, - 100 - ], - "ix": 6 - } - }, - "ao": 0, - "shapes": [ - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 8.306, - -5.957 - ], - [ - -6.185, - 0.826 - ], - [ - -8.305, - -3.702 - ], - [ - -3.784, - 5.958 - ] - ], - "c": false - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "st", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 3 - }, - "o": { - "a": 0, - "k": 100, - "ix": 4 - }, - "w": { - "a": 0, - "k": 2, - "ix": 5 - }, - "lc": 1, - "lj": 1, - "ml": 10, - "nm": "Stroke 1", - "mn": "ADBE Vector Graphic - Stroke", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 592.294, - 492.253 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 1", - "np": 2, - "cix": 2, - "ix": 1, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - -0.586, - -1.251 - ], - [ - 0, - 0 - ], - [ - 1.347, - 0.192 - ], - [ - 0, - 0 - ], - [ - -0.612, - 1.05 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 0.577, - 1.232 - ], - [ - 0, - 0 - ], - [ - -1.204, - -0.171 - ], - [ - 0, - 0 - ], - [ - 0.695, - -1.194 - ] - ], - "v": [ - [ - 1.794, - -8.294 - ], - [ - 8.957, - 7.011 - ], - [ - 7.165, - 9.432 - ], - [ - -7.684, - 7.32 - ], - [ - -8.922, - 4.763 - ], - [ - -1.237, - -8.43 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "st", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 3 - }, - "o": { - "a": 0, - "k": 100, - "ix": 4 - }, - "w": { - "a": 0, - "k": 2, - "ix": 5 - }, - "lc": 1, - "lj": 1, - "ml": 10, - "nm": "Stroke 1", - "mn": "ADBE Vector Graphic - Stroke", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 609.898, - 479.757 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 2", - "np": 3, - "cix": 2, - "ix": 2, - "mn": "ADBE Vector Group", - "hd": false - } - ], - "ip": 0, - "op": 218, - "st": 0, - "bm": 0 - }, - { - "ddd": 0, - "ind": 11, - "ty": 4, - "nm": "Arm R Outlines", - "parent": 8, - "sr": 1, - "ks": { - "o": { - "a": 0, - "k": 100, - "ix": 11 - }, - "r": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.41 - ], - "y": [ - 1 - ] - }, - "o": { - "x": [ - 0.59 - ], - "y": [ - 0 - ] - }, - "n": [ - "0p41_1_0p59_0" - ], - "t": 0, - "s": [ - 38 - ], - "e": [ - -42 - ] - }, - { - "i": { - "x": [ - 0.41 - ], - "y": [ - 1 - ] - }, - "o": { - "x": [ - 0.59 - ], - "y": [ - 0 - ] - }, - "n": [ - "0p41_1_0p59_0" - ], - "t": 28, - "s": [ - -42 - ], - "e": [ - 38 - ] - }, - { - "t": 53 - } - ], - "ix": 10 - }, - "p": { - "a": 0, - "k": [ - 575.043, - 479.064, - 0 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 575.043, - 479.064, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100, - 100 - ], - "ix": 6 - } - }, - "ao": 0, - "shapes": [ - { - "ty": "gr", - "it": [ - { - "d": 1, - "ty": "el", - "s": { - "a": 0, - "k": [ - 22.26, - 22.26 - ], - "ix": 2 - }, - "p": { - "a": 0, - "k": [ - 4, - -5 - ], - "ix": 3 - }, - "nm": "Ellipse Path 1", - "mn": "ADBE Vector Shape - Ellipse", - "hd": false - }, - { - "ty": "st", - "c": { - "a": 0, - "k": [ - 0.117646998985, - 0.121569001441, - 0.333332974303, - 1 - ], - "ix": 3 - }, - "o": { - "a": 0, - "k": 100, - "ix": 4 - }, - "w": { - "a": 0, - "k": 0, - "ix": 5 - }, - "lc": 1, - "lj": 1, - "ml": 4, - "nm": "Stroke 1", - "mn": "ADBE Vector Graphic - Stroke", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 570.715, - 484.126 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Ellipse 1", - "np": 3, - "cix": 2, - "ix": 1, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - -0.105, - 0.259 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - -2.281, - 5.643 - ], - [ - 5.595, - 2.31 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 5.644, - 2.281 - ], - [ - 2.269, - -5.613 - ], - [ - -6.747, - -2.786 - ] - ], - "v": [ - [ - -7.052, - -14.471 - ], - [ - -15.484, - 6.389 - ], - [ - -1.134, - 12.19 - ], - [ - 13.215, - 6.102 - ], - [ - 7.208, - -8.214 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 585.274, - 482.801 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 1", - "np": 2, - "cix": 2, - "ix": 2, - "mn": "ADBE Vector Group", - "hd": false - } - ], - "ip": 0, - "op": 218, - "st": 0, - "bm": 0 - }, - { - "ddd": 0, - "ind": 12, - "ty": 4, - "nm": "Arm L Outlines", - "parent": 8, - "sr": 1, - "ks": { - "o": { - "a": 0, - "k": 100, - "ix": 11 - }, - "r": { - "a": 0, - "k": 0, - "ix": 10 - }, - "p": { - "a": 0, - "k": [ - 460.434, - 386.251, - 0 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 460.434, - 386.251, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100, - 100 - ], - "ix": 6 - } - }, - "ao": 0, - "shapes": [ - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0.265, - -0.087 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 5.784, - -1.897 - ], - [ - -1.843, - -5.766 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - -1.897, - -5.784 - ], - [ - -5.752, - 1.886 - ], - [ - 2.223, - 6.953 - ] - ], - "v": [ - [ - -7.56, - 15.327 - ], - [ - 13.819, - 8.316 - ], - [ - 8.996, - -6.392 - ], - [ - -4.91, - -13.43 - ], - [ - -11.977, - 0.394 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0, - 0, - 0, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 452.776, - 378.078 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 1", - "np": 2, - "cix": 2, - "ix": 1, - "mn": "ADBE Vector Group", - "hd": false - } - ], - "ip": 0, - "op": 218, - "st": 0, - "bm": 0 - }, - { - "ddd": 0, - "ind": 13, - "ty": 4, - "nm": "chandelier base", - "parent": 2, - "sr": 1, - "ks": { - "o": { - "a": 0, - "k": 100, - "ix": 11 - }, - "r": { - "a": 0, - "k": 0, - "ix": 10 - }, - "p": { - "a": 0, - "k": [ - 344.204, - -453.167, - 0 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 445.204, - 67.833, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100, - 100 - ], - "ix": 6 - } - }, - "ao": 0, - "shapes": [ - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 10.771, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 10.771 - ], - [ - 0, - 0 - ], - [ - -4.486, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -4.486 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - -10.771, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -4.486 - ], - [ - 0, - 0 - ], - [ - 4.486, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 10.771 - ] - ], - "v": [ - [ - 14.55, - 16.216 - ], - [ - -14.55, - 16.216 - ], - [ - -34.053, - -3.287 - ], - [ - -34.053, - -8.093 - ], - [ - -25.931, - -16.216 - ], - [ - 25.931, - -16.216 - ], - [ - 34.053, - -8.093 - ], - [ - 34.053, - -3.287 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 448.062, - 70.049 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 16", - "np": 2, - "cix": 2, - "ix": 16, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 4.689, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 4.69 - ], - [ - 0, - 0 - ], - [ - -1.953, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.953 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - -4.689, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.953 - ], - [ - 0, - 0 - ], - [ - 1.953, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 4.69 - ] - ], - "v": [ - [ - 6.334, - 7.059 - ], - [ - -6.335, - 7.059 - ], - [ - -14.825, - -1.431 - ], - [ - -14.825, - -3.523 - ], - [ - -11.289, - -7.059 - ], - [ - 11.289, - -7.059 - ], - [ - 14.825, - -3.523 - ], - [ - 14.825, - -1.431 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 448.063, - 90.319 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 17", - "np": 2, - "cix": 2, - "ix": 17, - "mn": "ADBE Vector Group", - "hd": false - } - ], - "ip": 0, - "op": 218, - "st": 0, - "bm": 0 - }, - { - "ddd": 0, - "ind": 14, - "ty": 4, - "nm": "chandelier bottom 2", - "parent": 2, - "sr": 1, - "ks": { - "o": { - "a": 0, - "k": 100, - "ix": 11 - }, - "r": { - "a": 1, - "k": [ - { - "i": { - "x": [ - 0.16 - ], - "y": [ - 1 - ] - }, - "o": { - "x": [ - 0.57 - ], - "y": [ - 0 - ] - }, - "n": [ - "0p16_1_0p57_0" - ], - "t": 3, - "s": [ - 22 - ], - "e": [ - -22 - ] - }, - { - "i": { - "x": [ - 0.16 - ], - "y": [ - 1 - ] - }, - "o": { - "x": [ - 0.57 - ], - "y": [ - 0 - ] - }, - "n": [ - "0p16_1_0p57_0" - ], - "t": 21.473, - "s": [ - -22 - ], - "e": [ - -21.933 - ] - }, - { - "i": { - "x": [ - 0.16 - ], - "y": [ - 1 - ] - }, - "o": { - "x": [ - 0.57 - ], - "y": [ - 0 - ] - }, - "n": [ - "0p16_1_0p57_0" - ], - "t": 26, - "s": [ - -21.933 - ], - "e": [ - 22 - ] - }, - { - "t": 55 - } - ], - "ix": 10 - }, - "p": { - "a": 0, - "k": [ - 346.204, - -429.167, - 0 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 445.992, - 91.903, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100, - 100 - ], - "ix": 6 - } - }, - "ao": 0, - "shapes": [ - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - -7.487, - -12.331 - ], - [ - 7.486, - -12.331 - ], - [ - 7.486, - 12.331 - ], - [ - -7.487, - 12.331 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "st", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 3 - }, - "o": { - "a": 0, - "k": 100, - "ix": 4 - }, - "w": { - "a": 0, - "k": 3.523, - "ix": 5 - }, - "lc": 1, - "lj": 1, - "ml": 10, - "nm": "Stroke 1", - "mn": "ADBE Vector Graphic - Stroke", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 366.388, - 306.969 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 1", - "np": 2, - "cix": 2, - "ix": 1, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - -5.393, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 5.392 - ], - [ - 0, - 0 - ], - [ - 2.246, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -2.245 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 5.392, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -2.245 - ], - [ - 0, - 0 - ], - [ - -2.246, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 5.392 - ] - ], - "v": [ - [ - -7.284, - 8.118 - ], - [ - 7.285, - 8.118 - ], - [ - 17.048, - -1.645 - ], - [ - 17.048, - -4.052 - ], - [ - 12.983, - -8.118 - ], - [ - -12.983, - -8.118 - ], - [ - -17.048, - -4.052 - ], - [ - -17.048, - -1.645 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 366.914, - 315.483 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 2", - "np": 2, - "cix": 2, - "ix": 2, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - 7.093, - -12.691 - ], - [ - 0.261, - -4.766 - ], - [ - 0, - 0 - ], - [ - 1.729, - -3.557 - ], - [ - 4.702, - 22.165 - ] - ], - "o": [ - [ - -7.974, - -14.081 - ], - [ - -2.124, - 3.8 - ], - [ - 0, - 0 - ], - [ - -0.232, - 4.257 - ], - [ - -8.24, - 16.946 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 36.922, - -47.763 - ], - [ - 6.956, - -47.724 - ], - [ - 3.435, - -34.5 - ], - [ - -0.245, - 32.901 - ], - [ - -3.113, - 44.897 - ], - [ - -36.922, - 37.465 - ] - ], - "c": false - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "st", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 3 - }, - "o": { - "a": 0, - "k": 100, - "ix": 4 - }, - "w": { - "a": 0, - "k": 2.776, - "ix": 5 - }, - "lc": 1, - "lj": 1, - "ml": 10, - "nm": "Stroke 1", - "mn": "ADBE Vector Graphic - Stroke", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 404.283, - 275.725 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 3", - "np": 2, - "cix": 2, - "ix": 3, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 10.727, - -12.691 - ], - [ - 0.393, - -4.766 - ], - [ - 0, - 0 - ], - [ - 2.616, - -3.556 - ], - [ - 7.111, - 22.164 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - -12.059, - -14.08 - ], - [ - -3.212, - 3.8 - ], - [ - 0, - 0 - ], - [ - -0.351, - 4.256 - ], - [ - -12.461, - 16.947 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 60.66, - -36.493 - ], - [ - 51.008, - -47.764 - ], - [ - 5.693, - -47.725 - ], - [ - 0.37, - -34.501 - ], - [ - -5.196, - 32.9 - ], - [ - -9.535, - 44.896 - ], - [ - -60.66, - 37.464 - ] - ], - "c": false - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "st", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 3 - }, - "o": { - "a": 0, - "k": 100, - "ix": 4 - }, - "w": { - "a": 0, - "k": 3.414, - "ix": 5 - }, - "lc": 1, - "lj": 1, - "ml": 10, - "nm": "Stroke 1", - "mn": "ADBE Vector Graphic - Stroke", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 388.878, - 273.833 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 4", - "np": 2, - "cix": 2, - "ix": 4, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - -5.311, - -8.748 - ], - [ - 5.311, - -8.748 - ], - [ - 5.311, - 8.748 - ], - [ - -5.311, - 8.748 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "st", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 3 - }, - "o": { - "a": 0, - "k": 100, - "ix": 4 - }, - "w": { - "a": 0, - "k": 2.499, - "ix": 5 - }, - "lc": 1, - "lj": 1, - "ml": 10, - "nm": "Stroke 1", - "mn": "ADBE Vector Graphic - Stroke", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 328.433, - 304.094 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 5", - "np": 2, - "cix": 2, - "ix": 5, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - -3.826, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 3.826 - ], - [ - 0, - 0 - ], - [ - 1.593, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.593 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 3.825, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.593 - ], - [ - 0, - 0 - ], - [ - -1.594, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 3.826 - ] - ], - "v": [ - [ - -5.168, - 5.759 - ], - [ - 5.168, - 5.759 - ], - [ - 12.095, - -1.167 - ], - [ - 12.095, - -2.874 - ], - [ - 9.21, - -5.759 - ], - [ - -9.21, - -5.759 - ], - [ - -12.095, - -2.874 - ], - [ - -12.095, - -1.167 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 328.807, - 310.135 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 6", - "np": 2, - "cix": 2, - "ix": 6, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 7.487, - -12.331 - ], - [ - -7.487, - -12.331 - ], - [ - -7.487, - 12.331 - ], - [ - 7.487, - 12.331 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "st", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 3 - }, - "o": { - "a": 0, - "k": 100, - "ix": 4 - }, - "w": { - "a": 0, - "k": 3.523, - "ix": 5 - }, - "lc": 1, - "lj": 1, - "ml": 10, - "nm": "Stroke 1", - "mn": "ADBE Vector Graphic - Stroke", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 532.021, - 305.346 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 7", - "np": 2, - "cix": 2, - "ix": 7, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 5.393, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 5.392 - ], - [ - 0, - 0 - ], - [ - -2.246, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -2.245 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - -5.392, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -2.245 - ], - [ - 0, - 0 - ], - [ - 2.246, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 5.392 - ] - ], - "v": [ - [ - 7.285, - 8.118 - ], - [ - -7.284, - 8.118 - ], - [ - -17.048, - -1.645 - ], - [ - -17.048, - -4.052 - ], - [ - -12.982, - -8.118 - ], - [ - 12.983, - -8.118 - ], - [ - 17.049, - -4.052 - ], - [ - 17.049, - -1.645 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 531.494, - 313.861 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 8", - "np": 2, - "cix": 2, - "ix": 8, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - -7.093, - -12.691 - ], - [ - -0.261, - -4.766 - ], - [ - 0, - 0 - ], - [ - -1.729, - -3.557 - ], - [ - -4.702, - 22.165 - ] - ], - "o": [ - [ - 7.974, - -14.081 - ], - [ - 2.124, - 3.8 - ], - [ - 0, - 0 - ], - [ - 0.232, - 4.257 - ], - [ - 8.24, - 16.946 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - -36.921, - -47.763 - ], - [ - -6.956, - -47.724 - ], - [ - -3.435, - -34.5 - ], - [ - 0.245, - 32.901 - ], - [ - 3.113, - 44.897 - ], - [ - 36.922, - 37.465 - ] - ], - "c": false - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "st", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 3 - }, - "o": { - "a": 0, - "k": 100, - "ix": 4 - }, - "w": { - "a": 0, - "k": 2.776, - "ix": 5 - }, - "lc": 1, - "lj": 1, - "ml": 10, - "nm": "Stroke 1", - "mn": "ADBE Vector Graphic - Stroke", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 494.125, - 274.103 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 9", - "np": 2, - "cix": 2, - "ix": 9, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - -10.727, - -12.691 - ], - [ - -0.393, - -4.766 - ], - [ - 0, - 0 - ], - [ - -2.616, - -3.556 - ], - [ - -7.111, - 22.164 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 12.059, - -14.081 - ], - [ - 3.212, - 3.8 - ], - [ - 0, - 0 - ], - [ - 0.351, - 4.256 - ], - [ - 12.461, - 16.947 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - -60.66, - -36.493 - ], - [ - -51.008, - -47.762 - ], - [ - -5.693, - -47.725 - ], - [ - -0.37, - -34.501 - ], - [ - 5.196, - 32.9 - ], - [ - 9.535, - 44.896 - ], - [ - 60.66, - 37.464 - ] - ], - "c": false - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "st", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 3 - }, - "o": { - "a": 0, - "k": 100, - "ix": 4 - }, - "w": { - "a": 0, - "k": 3.414, - "ix": 5 - }, - "lc": 1, - "lj": 1, - "ml": 10, - "nm": "Stroke 1", - "mn": "ADBE Vector Graphic - Stroke", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 509.53, - 272.212 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 10", - "np": 2, - "cix": 2, - "ix": 10, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 5.311, - -8.748 - ], - [ - -5.311, - -8.748 - ], - [ - -5.311, - 8.748 - ], - [ - 5.311, - 8.748 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "st", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 3 - }, - "o": { - "a": 0, - "k": 100, - "ix": 4 - }, - "w": { - "a": 0, - "k": 2.499, - "ix": 5 - }, - "lc": 1, - "lj": 1, - "ml": 10, - "nm": "Stroke 1", - "mn": "ADBE Vector Graphic - Stroke", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 569.975, - 302.473 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 11", - "np": 2, - "cix": 2, - "ix": 11, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 3.826, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 3.826 - ], - [ - 0, - 0 - ], - [ - -1.593, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.593 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - -3.825, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.593 - ], - [ - 0, - 0 - ], - [ - 1.594, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - 3.826 - ] - ], - "v": [ - [ - 5.168, - 5.759 - ], - [ - -5.168, - 5.759 - ], - [ - -12.095, - -1.167 - ], - [ - -12.095, - -2.874 - ], - [ - -9.21, - -5.759 - ], - [ - 9.21, - -5.759 - ], - [ - 12.095, - -2.874 - ], - [ - 12.095, - -1.167 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 569.601, - 308.513 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 12", - "np": 2, - "cix": 2, - "ix": 12, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 3.927 - ], - [ - 3.927, - 0 - ], - [ - 0, - -3.927 - ], - [ - -3.927, - 0 - ] - ], - "o": [ - [ - 0, - -3.927 - ], - [ - -3.927, - 0 - ], - [ - 0, - 3.927 - ], - [ - 3.927, - 0 - ] - ], - "v": [ - [ - 7.11, - 0 - ], - [ - 0, - -7.11 - ], - [ - -7.11, - 0 - ], - [ - 0, - 7.11 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "st", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 3 - }, - "o": { - "a": 0, - "k": 100, - "ix": 4 - }, - "w": { - "a": 0, - "k": 2.188, - "ix": 5 - }, - "lc": 1, - "lj": 1, - "ml": 10, - "nm": "Stroke 1", - "mn": "ADBE Vector Graphic - Stroke", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 448.063, - 157.884 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 13", - "np": 3, - "cix": 2, - "ix": 13, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 5.821 - ], - [ - 5.821, - 0 - ], - [ - 0, - -5.821 - ], - [ - -5.821, - 0 - ] - ], - "o": [ - [ - 0, - -5.821 - ], - [ - -5.821, - 0 - ], - [ - 0, - 5.821 - ], - [ - 5.821, - 0 - ] - ], - "v": [ - [ - 10.54, - 0 - ], - [ - 0, - -10.54 - ], - [ - -10.54, - 0 - ], - [ - 0, - 10.54 - ] - ], - "c": true - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "st", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 3 - }, - "o": { - "a": 0, - "k": 100, - "ix": 4 - }, - "w": { - "a": 0, - "k": 3.243, - "ix": 5 - }, - "lc": 1, - "lj": 1, - "ml": 10, - "nm": "Stroke 1", - "mn": "ADBE Vector Graphic - Stroke", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 1, - 1, - 1, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 448.063, - 357.338 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 14", - "np": 3, - "cix": 2, - "ix": 14, - "mn": "ADBE Vector Group", - "hd": false - }, - { - "ty": "gr", - "it": [ - { - "ind": 0, - "ty": "sh", - "ix": 1, - "ks": { - "a": 0, - "k": { - "i": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "o": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ] - ], - "v": [ - [ - 448.062, - 90.319 - ], - [ - 448.062, - 347.609 - ] - ], - "c": false - }, - "ix": 2 - }, - "nm": "Path 1", - "mn": "ADBE Vector Shape - Group", - "hd": false - }, - { - "ty": "st", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 3 - }, - "o": { - "a": 0, - "k": 100, - "ix": 4 - }, - "w": { - "a": 0, - "k": 3.243, - "ix": 5 - }, - "lc": 1, - "lj": 1, - "ml": 10, - "nm": "Stroke 1", - "mn": "ADBE Vector Graphic - Stroke", - "hd": false - }, - { - "ty": "fl", - "c": { - "a": 0, - "k": [ - 0.944999964097, - 0.776000019148, - 0.361000001197, - 1 - ], - "ix": 4 - }, - "o": { - "a": 0, - "k": 100, - "ix": 5 - }, - "r": 1, - "nm": "Fill 1", - "mn": "ADBE Vector Graphic - Fill", - "hd": false - }, - { - "ty": "tr", - "p": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 2 - }, - "a": { - "a": 0, - "k": [ - 0, - 0 - ], - "ix": 1 - }, - "s": { - "a": 0, - "k": [ - 100, - 100 - ], - "ix": 3 - }, - "r": { - "a": 0, - "k": 0, - "ix": 6 - }, - "o": { - "a": 0, - "k": 100, - "ix": 7 - }, - "sk": { - "a": 0, - "k": 0, - "ix": 4 - }, - "sa": { - "a": 0, - "k": 0, - "ix": 5 - }, - "nm": "Transform" - } - ], - "nm": "Group 15", - "np": 3, - "cix": 2, - "ix": 15, - "mn": "ADBE Vector Group", - "hd": false - } - ], - "ip": 0, - "op": 218, - "st": 0, - "bm": 0 - } - ] -} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/tile_grid_loading_animation.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/tile_grid_loading_animation.json deleted file mode 100644 index 4530a779..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/tile_grid_loading_animation.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.16","fr":60,"ip":0,"op":120,"w":800,"h":800,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"e1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":25,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[336,337],[304,337],[304,305],[336,305]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,401],[240,401],[240,241],[400,241]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":55,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,401],[240,401],[240,241],[400,241]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,401],[240,401],[240,241],[400,241]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":85,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,401],[240,401],[240,241],[400,241]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[336,337],[304,337],[304,305],[336,305]],"c":true}]},{"t":115}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"e1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"d1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[176,337],[144,337],[144,305],[176,305]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,401],[80,401],[80,241],[240,241]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":50,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,401],[80,401],[80,241],[240,241]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,401],[80,401],[80,241],[240,241]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":80,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,401],[80,401],[80,241],[240,241]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[176,337],[144,337],[144,305],[176,305]],"c":true}]},{"t":110}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"d1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"c1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":15,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16,337],[-16,337],[-16,305],[16,305]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,401],[-80,401],[-80,241],[80,241]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":45,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,401],[-80,401],[-80,241],[80,241]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,401],[-80,401],[-80,241],[80,241]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,401],[-80,401],[-80,241],[80,241]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16,337],[-16,337],[-16,305],[16,305]],"c":true}]},{"t":105}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"c1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"b1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":10,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-144,337],[-176,337],[-176,305],[-144,305]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,401],[-240,401],[-240,241],[-80,241]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":40,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,401],[-240,401],[-240,241],[-80,241]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,401],[-240,401],[-240,241],[-80,241]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":70,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,401],[-240,401],[-240,241],[-80,241]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-144,337],[-176,337],[-176,305],[-144,305]],"c":true}]},{"t":100}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"b1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"a1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":5,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-304,337],[-336,337],[-336,305],[-304,305]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,401],[-400,401],[-400,241],[-240,241]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":35,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,401],[-400,401],[-400,241],[-240,241]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,401],[-400,401],[-400,241],[-240,241]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":65,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,401],[-400,401],[-400,241],[-240,241]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-304,337],[-336,337],[-336,305],[-304,305]],"c":true}]},{"t":95}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"a1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"e2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":30,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[336,177],[304,177],[304,145],[336,145]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,241],[240,241],[240,81],[400,81]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":60,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,241],[240,241],[240,81],[400,81]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,241],[240,241],[240,81],[400,81]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,241],[240,241],[240,81],[400,81]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[336,177],[304,177],[304,145],[336,145]],"c":true}]},{"t":120}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"e2","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"d2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":25,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[176,177],[144,177],[144,145],[176,145]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,241],[80,241],[80,81],[240,81]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":55,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,241],[80,241],[80,81],[240,81]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,241],[80,241],[80,81],[240,81]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":85,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,241],[80,241],[80,81],[240,81]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[176,177],[144,177],[144,145],[176,145]],"c":true}]},{"t":115}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"d2","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"c2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16,177],[-16,177],[-16,145],[16,145]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,241],[-80,241],[-80,81],[80,81]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":50,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,241],[-80,241],[-80,81],[80,81]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,241],[-80,241],[-80,81],[80,81]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":80,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,241],[-80,241],[-80,81],[80,81]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16,177],[-16,177],[-16,145],[16,145]],"c":true}]},{"t":110}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"c2","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"b2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":15,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-144,177],[-176,177],[-176,145],[-144,145]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,241],[-240,241],[-240,81],[-80,81]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":45,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,241],[-240,241],[-240,81],[-80,81]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,241],[-240,241],[-240,81],[-80,81]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,241],[-240,241],[-240,81],[-80,81]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-144,177],[-176,177],[-176,145],[-144,145]],"c":true}]},{"t":105}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"b2","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"a2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":10,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-304,177],[-336,177],[-336,145],[-304,145]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,241],[-400,241],[-400,81],[-240,81]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":40,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,241],[-400,241],[-400,81],[-240,81]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,241],[-400,241],[-400,81],[-240,81]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":70,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,241],[-400,241],[-400,81],[-240,81]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-304,177],[-336,177],[-336,145],[-304,145]],"c":true}]},{"t":100}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"a2","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"e3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p833_1_0p167_0p167","t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[344.976,25.976],[295.024,25.976],[295.024,-23.976],[344.976,-23.976]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[336,17],[304,17],[304,-15],[336,-15]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":5,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[336,17],[304,17],[304,-15],[336,-15]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[336,17],[304,17],[304,-15],[336,-15]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":35,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[336,17],[304,17],[304,-15],[336,-15]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,81],[240,81],[240,-79],[400,-79]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":65,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,81],[240,81],[240,-79],[400,-79]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,81],[240,81],[240,-79],[400,-79]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":95,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,81],[240,81],[240,-79],[400,-79]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[344.976,25.976],[295.024,25.976],[295.024,-23.976],[344.976,-23.976]],"c":true}]},{"t":120}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"e3","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"d3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":30,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[176,17],[144,17],[144,-15],[176,-15]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,81],[80,81],[80,-79],[240,-79]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":60,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,81],[80,81],[80,-79],[240,-79]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,81],[80,81],[80,-79],[240,-79]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,81],[80,81],[80,-79],[240,-79]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[176,17],[144,17],[144,-15],[176,-15]],"c":true}]},{"t":120}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"d3","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"c3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":25,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16,17],[-16,17],[-16,-15],[16,-15]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,81],[-80,81],[-80,-79],[80,-79]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":55,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,81],[-80,81],[-80,-79],[80,-79]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,81],[-80,81],[-80,-79],[80,-79]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":85,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,81],[-80,81],[-80,-79],[80,-79]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16,17],[-16,17],[-16,-15],[16,-15]],"c":true}]},{"t":115}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"c3","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"b3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-144,17],[-176,17],[-176,-15],[-144,-15]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,81],[-240,81],[-240,-79],[-80,-79]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":50,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,81],[-240,81],[-240,-79],[-80,-79]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,81],[-240,81],[-240,-79],[-80,-79]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":80,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,81],[-240,81],[-240,-79],[-80,-79]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-144,17],[-176,17],[-176,-15],[-144,-15]],"c":true}]},{"t":110}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"b3","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"a3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":15,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-304,17],[-336,17],[-336,-15],[-304,-15]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,81],[-400,81],[-400,-79],[-240,-79]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":45,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,81],[-400,81],[-400,-79],[-240,-79]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,81],[-400,81],[-400,-79],[-240,-79]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,81],[-400,81],[-400,-79],[-240,-79]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-304,17],[-336,17],[-336,-15],[-304,-15]],"c":true}]},{"t":105}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"a3","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"e4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[352.593,-126.407],[287.407,-126.407],[287.407,-191.593],[352.593,-191.593]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[336,-143],[304,-143],[304,-175],[336,-175]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":10,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[336,-143],[304,-143],[304,-175],[336,-175]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[336,-143],[304,-143],[304,-175],[336,-175]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":40,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[336,-143],[304,-143],[304,-175],[336,-175]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,-79],[240,-79],[240,-239],[400,-239]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":70,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,-79],[240,-79],[240,-239],[400,-239]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,-79],[240,-79],[240,-239],[400,-239]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":100,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,-79],[240,-79],[240,-239],[400,-239]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[352.593,-126.407],[287.407,-126.407],[287.407,-191.593],[352.593,-191.593]],"c":true}]},{"t":120}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"e4","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"d4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[180.741,-138.259],[139.259,-138.259],[139.259,-179.741],[180.741,-179.741]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[176,-143],[144,-143],[144,-175],[176,-175]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":5,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[176,-143],[144,-143],[144,-175],[176,-175]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[176,-143],[144,-143],[144,-175],[176,-175]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":35,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[176,-143],[144,-143],[144,-175],[176,-175]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,-79],[80,-79],[80,-239],[240,-239]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":65,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,-79],[80,-79],[80,-239],[240,-239]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,-79],[80,-79],[80,-239],[240,-239]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":95,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,-79],[80,-79],[80,-239],[240,-239]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[180.741,-138.259],[139.259,-138.259],[139.259,-179.741],[180.741,-179.741]],"c":true}]},{"t":120}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"d4","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"c4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":30,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16,-143],[-16,-143],[-16,-175],[16,-175]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,-79],[-80,-79],[-80,-239],[80,-239]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":60,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,-79],[-80,-79],[-80,-239],[80,-239]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,-79],[-80,-79],[-80,-239],[80,-239]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,-79],[-80,-79],[-80,-239],[80,-239]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16,-143],[-16,-143],[-16,-175],[16,-175]],"c":true}]},{"t":120}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"c4","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"b4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":25,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-144,-143],[-176,-143],[-176,-175],[-144,-175]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,-79],[-240,-79],[-240,-239],[-80,-239]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":55,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,-79],[-240,-79],[-240,-239],[-80,-239]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,-79],[-240,-79],[-240,-239],[-80,-239]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":85,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,-79],[-240,-79],[-240,-239],[-80,-239]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-144,-143],[-176,-143],[-176,-175],[-144,-175]],"c":true}]},{"t":115}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"b4","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"a4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-304,-143],[-336,-143],[-336,-175],[-304,-175]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,-79],[-400,-79],[-400,-239],[-240,-239]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":50,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,-79],[-400,-79],[-400,-239],[-240,-239]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,-79],[-400,-79],[-400,-239],[-240,-239]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":80,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,-79],[-400,-79],[-400,-239],[-240,-239]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-304,-143],[-336,-143],[-336,-175],[-304,-175]],"c":true}]},{"t":110}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"a4","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"e5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[368,-271],[272,-271],[272,-367],[368,-367]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[336,-303],[304,-303],[304,-335],[336,-335]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":15,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[336,-303],[304,-303],[304,-335],[336,-335]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[336,-303],[304,-303],[304,-335],[336,-335]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":45,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[336,-303],[304,-303],[304,-335],[336,-335]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,-239],[240,-239],[240,-399],[400,-399]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,-239],[240,-239],[240,-399],[400,-399]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,-239],[240,-239],[240,-399],[400,-399]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":105,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[400,-239],[240,-239],[240,-399],[400,-399]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[368,-271],[272,-271],[272,-367],[368,-367]],"c":true}]},{"t":120}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"e5","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":"d5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[192.593,-286.407],[127.407,-286.407],[127.407,-351.593],[192.593,-351.593]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[176,-303],[144,-303],[144,-335],[176,-335]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":10,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[176,-303],[144,-303],[144,-335],[176,-335]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[176,-303],[144,-303],[144,-335],[176,-335]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":40,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[176,-303],[144,-303],[144,-335],[176,-335]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,-239],[80,-239],[80,-399],[240,-399]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":70,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,-239],[80,-239],[80,-399],[240,-399]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,-239],[80,-239],[80,-399],[240,-399]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":100,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[240,-239],[80,-239],[80,-399],[240,-399]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[192.593,-286.407],[127.407,-286.407],[127.407,-351.593],[192.593,-351.593]],"c":true}]},{"t":120}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"d5","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":23,"ty":4,"nm":"c5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[20.741,-298.259],[-20.741,-298.259],[-20.741,-339.741],[20.741,-339.741]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16,-303],[-16,-303],[-16,-335],[16,-335]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":5,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16,-303],[-16,-303],[-16,-335],[16,-335]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16,-303],[-16,-303],[-16,-335],[16,-335]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":35,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[16,-303],[-16,-303],[-16,-335],[16,-335]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,-239],[-80,-239],[-80,-399],[80,-399]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":65,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,-239],[-80,-239],[-80,-399],[80,-399]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,-239],[-80,-239],[-80,-399],[80,-399]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":95,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,-239],[-80,-239],[-80,-399],[80,-399]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[20.741,-298.259],[-20.741,-298.259],[-20.741,-339.741],[20.741,-339.741]],"c":true}]},{"t":120}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"c5","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":24,"ty":4,"nm":"b5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":30,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-144,-303],[-176,-303],[-176,-335],[-144,-335]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,-239],[-240,-239],[-240,-399],[-80,-399]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":60,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,-239],[-240,-239],[-240,-399],[-80,-399]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,-239],[-240,-239],[-240,-399],[-80,-399]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-80,-239],[-240,-239],[-240,-399],[-80,-399]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-144,-303],[-176,-303],[-176,-335],[-144,-335]],"c":true}]},{"t":120}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"b5","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":25,"ty":4,"nm":"a5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":25,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-304,-303],[-336,-303],[-336,-335],[-304,-335]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,-239],[-400,-239],[-400,-399],[-240,-399]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":55,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,-239],[-400,-239],[-400,-399],[-240,-399]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,-239],[-400,-239],[-400,-399],[-240,-399]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":85,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-240,-239],[-400,-239],[-400,-399],[-240,-399]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-304,-303],[-336,-303],[-336,-335],[-304,-335]],"c":true}]},{"t":115}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"a5","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/tractor.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/tractor.json deleted file mode 100644 index 4c094702..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/tractor.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.10","fr":24,"ip":0,"op":427,"w":400,"h":310,"nm":"Tractor","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Tractor Master Ctrl","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[184.028,155,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Dark 4 Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[31.53,14.503,0],"ix":2},"a":{"a":0,"k":[1.973,2.877,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-1.973,1.877],[1.049,1.877],[1.049,-2.877],[1.973,-2.877],[1.973,2.877],[-1.973,2.877]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.936999990426,0.169000004787,0.149000010771,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.972,2.877],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Light 4 Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[31.53,14.474,0],"ix":2},"a":{"a":0,"k":[2.223,3.156,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-0.571],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[-0.571,0]],"v":[[-1.973,-1.872],[-1.973,2.906],[1.973,2.906],[1.973,-2.906],[-0.939,-2.906]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.936999990426,0.169000004787,0.149000010771,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[2.222,3.156],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Seat Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[11.031,12.997,0],"ix":2},"a":{"a":0,"k":[3.729,2.891,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.076,-0.343],[0,0],[-1.082,-3.101],[0,0],[0,0],[1.244,1.246],[0.753,0.226]],"o":[[0,0],[0,0],[0,0],[0,0],[-0.935,-1.469],[-0.551,-0.552],[-0.25,-0.075]],"v":[[-3.728,-2.69],[-3.238,-0.466],[1.48,2.214],[1.716,2.892],[3.73,2.795],[0.786,-1.544],[-1.154,-2.773]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.957000014361,0.463000009574,0.451000019148,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[3.729,2.891],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Steering Outlines","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0.577,-0.554,0],"ix":2},"a":{"a":0,"k":[6.578,4.658,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.146,-0.95],[0.194,0.437],[-2.146,0.951],[-0.193,-0.437]],"o":[[-2.146,0.951],[-0.194,-0.438],[2.145,-0.95],[0.195,0.437]],"v":[[0.351,0.791],[-3.885,1.721],[-0.351,-0.792],[3.883,-1.721]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.368999974868,0.356999984442,0.356999984442,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[6.578,4.658],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Steering Pipe Light Outlines","parent":7,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3.217,3.754,0],"ix":2},"a":{"a":0,"k":[2.101,3.505,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.101,-3.378],[1.622,3.504],[2.102,3.365],[-1.731,-3.504]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.301999978458,0.301999978458,0.301999978458,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[2.102,3.505],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Steering Pipe Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[23.047,12.53,0],"ix":2},"a":{"a":0,"k":[2.785,3.9,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2.535,-3.229],[-1.299,-3.651],[2.535,3.22],[1.045,3.651]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501999978458,0.501999978458,0.501999978458,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[2.784,3.901],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Hood Pipe Outlines","parent":10,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1.907,-2.469,0],"ix":2},"a":{"a":0,"k":[1.613,3.172,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-2.051,0.373],[-0.021,-0.14],[0,0],[0.117,-0.038],[-0.07,-0.698],[0.019,-0.684],[0.145,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0.151,-0.027],[0,0],[0.016,0.114],[-0.385,0.128],[0.076,0.751],[-0.004,0.133],[0,0],[0,0]],"v":[[-1.363,2.922],[-1.093,2.826],[-1.093,-1.217],[0.958,-2.895],[1.275,-2.682],[1.347,-2.167],[1.177,-1.906],[0.061,-0.727],[0.069,2.685],[-0.199,2.922],[-1.151,2.922]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8,0.8,0.8,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.613,3.172],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Hood Pipe Base Light Outlines","parent":10,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1.34,2.435,0],"ix":2},"a":{"a":0,"k":[1.336,2.435,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.209,0],[0,0],[0.196,0],[0,0],[0,-0.197],[0,0],[0,0],[0,0]],"o":[[0,0],[-0.017,-0.182],[0,0],[-0.209,0],[0,0],[0,0],[0,0],[0,-0.196]],"v":[[-0.328,-1.859],[1.087,-1.859],[0.717,-2.185],[-0.71,-2.185],[-1.087,-1.829],[-1.087,2.185],[-0.706,2.185],[-0.706,-1.503]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.8,0.8,0.8,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.336,2.435],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Hood Pipe Base Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[47.012,10.26,0],"ix":2},"a":{"a":0,"k":[1.34,4.62,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.208,0],[0,0],[0,-0.197],[0,0]],"o":[[0,0],[0,-0.197],[0,0],[0.208,0],[0,0],[0,0]],"v":[[-1.09,2.185],[-1.09,-1.828],[-0.713,-2.185],[0.713,-2.185],[1.09,-1.828],[1.09,2.185]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501999978458,0.501999978458,0.501999978458,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.34,2.435],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Shape Light 3 Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[34.404,22.26,0],"ix":2},"a":{"a":0,"k":[4.204,1.828,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.085,-0.014],[-0.019,-0.459],[0.041,-0.614],[0.461,0.004],[1.33,0],[0.801,0.003],[0.002,0.563],[-0.002,0.539],[-0.545,0],[-1.048,0]],"o":[[1.085,0],[0.468,0.007],[0.026,0.616],[-0.025,0.376],[-1.331,-0.011],[-0.803,0],[-0.56,-0.002],[-0.002,-0.538],[0.001,-0.538],[1.047,-0.001],[0,0]],"v":[[-0.037,-1.556],[3.218,-1.552],[3.909,-0.889],[3.913,0.96],[3.207,1.574],[-0.785,1.57],[-3.192,1.57],[-3.951,0.801],[-3.952,-0.814],[-3.179,-1.577],[-0.037,-1.577]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.957000014361,0.463000009574,0.451000019148,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[4.204,1.828],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Shape Light 2 Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[49,23.93,0],"ix":2},"a":{"a":0,"k":[1.966,2.095,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0.519],[-0.002,0.528],[0.182,0.003],[0.643,-0.303],[-0.946,-0.689],[-0.808,0.022],[0.001,0.138]],"o":[[0,-0.528],[0,-0.142],[-0.701,-0.015],[-1.058,0.498],[0.696,0.507],[0.185,-0.005],[-0.004,-0.518]],"v":[[1.714,0.003],[1.715,-1.581],[1.514,-1.831],[-0.518,-1.477],[-0.771,1.322],[1.531,1.824],[1.716,1.559]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.957000014361,0.541000007181,0.528999956916,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.966,2.096],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Shape Light 1 Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[42.524,22.557,0],"ix":2},"a":{"a":0,"k":[3.128,1.472,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.715,-0.001],[-0.006,-0.522],[0.009,-0.361],[0.421,-0.002],[1.489,0.006],[0.002,0.435],[-0.01,0.371],[-0.428,0.004],[-0.744,0]],"o":[[0.715,0],[0.517,0.001],[0.004,0.363],[-0.008,0.419],[-1.488,0.007],[-0.425,-0.001],[-0.001,-0.372],[0.012,-0.428],[0.744,-0.007],[0,0]],"v":[[0.014,-1.221],[2.158,-1.221],[2.87,-0.509],[2.868,0.577],[2.23,1.215],[-2.236,1.215],[-2.877,0.549],[-2.854,-0.566],[-2.219,-1.203],[0.014,-1.205]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.957000014361,0.463000009574,0.451000019148,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[3.128,1.472],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Shape Dark 3 Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[38.849,17.379,0],"ix":2},"a":{"a":0,"k":[2.196,1.873,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.138,-0.1],[-0.055,0.001],[-0.518,-0.01],[0.003,0.214],[0.011,0.734],[-0.238,-0.009],[-0.411,0],[-0.001,0.231],[0.161,0],[0.872,0.012],[-0.004,-0.209],[-0.002,-0.597],[0.251,-0.24]],"o":[[0.112,0.02],[0.518,-0.003],[0.225,0.005],[-0.01,-0.734],[-0.003,-0.225],[0.411,0.017],[0.147,0],[0.002,-0.216],[-0.872,0.002],[-0.228,-0.002],[0.012,0.598],[0.001,0.355],[-0.08,0.077]],"v":[[-1.945,1.585],[-1.725,1.622],[-0.17,1.611],[0.113,1.323],[0.104,-0.878],[0.406,-1.186],[1.639,-1.181],[1.943,-1.388],[1.652,-1.618],[-0.964,-1.621],[-1.24,-1.327],[-1.234,0.465],[-1.629,1.351]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.936999990426,0.169000004787,0.149000010771,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[2.195,1.873],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Shape Dark 2 Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[41.961,15.21,0],"ix":2},"a":{"a":0,"k":[4.607,1.242,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.011,0.075],[0.846,0.001],[2.016,0.004],[-0.003,-0.249],[-0.166,0.001],[-0.891,-0.011],[-0.033,-0.792],[-0.209,0.001],[-1.284,0]],"o":[[-0.014,-0.119],[-0.151,-0.969],[-2.016,-0.003],[-0.191,-0.001],[0.003,0.244],[0.89,-0.002],[0.797,0.009],[0.009,0.251],[1.282,-0.006],[0,0]],"v":[[4.357,0.987],[4.326,0.719],[2.004,-0.988],[-4.045,-0.991],[-4.354,-0.732],[-4.051,-0.497],[-1.378,-0.495],[-0.127,0.707],[0.197,0.99],[4.045,0.987]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.936999990426,0.169000004787,0.149000010771,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[4.607,1.242],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Shape Dark 1 Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[44.06,18.414,0],"ix":2},"a":{"a":0,"k":[2.565,1.488,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.646,0],[0,0],[0.567,-0.005],[-0.001,-0.653],[-0.025,-0.506],[-0.226,0.002],[-1.283,-0.007],[0.004,0.211],[-0.013,0.616],[0.219,-0.003]],"o":[[0,0],[-0.567,0],[-0.67,0.006],[0,0.508],[0.011,0.205],[1.282,-0.008],[0.196,0.001],[-0.01,-0.617],[0.006,-0.241],[-0.645,0.01]],"v":[[0.058,-1.168],[0.058,-1.169],[-1.645,-1.168],[-2.213,-0.585],[-2.165,0.937],[-1.816,1.236],[2.031,1.236],[2.309,0.972],[2.309,-0.878],[1.995,-1.172]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.936999990426,0.169000004787,0.149000010771,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[2.565,1.488],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Back Nut 4 Outlines","parent":24,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[9.805,6.221,0],"ix":2},"a":{"a":0,"k":[3.063,1.81,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.074,0.157],[-0.131,0.127],[-1.789,0.124],[-0.015,-0.29],[0.345,-0.026],[0.884,-0.566],[0.385,-0.314],[0.223,0.252]],"o":[[0.108,-0.158],[1.3,-1.262],[0.342,-0.024],[0.014,0.283],[-1.041,0.077],[-0.417,0.267],[-0.285,0.233],[-0.078,-0.088]],"v":[[-2.814,0.934],[-2.491,0.472],[2.178,-1.536],[2.799,-1.056],[2.234,-0.495],[-0.683,0.397],[-1.857,1.316],[-2.631,1.308]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[3.063,1.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Back Nut 3 Outlines","parent":24,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[6.191,15.057,0],"ix":2},"a":{"a":0,"k":[1.842,3.074,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.026,0.006],[-0.274,0.019],[-0.028,-0.302],[-0.37,-0.791],[-0.472,-0.498],[0.202,-0.206],[0.249,0.232],[0.326,0.963],[0.192,0.773]],"o":[[0,-0.292],[0.273,-0.019],[0.082,0.862],[0.294,0.629],[0.222,0.234],[-0.22,0.224],[-0.749,-0.699],[-0.255,-0.753],[0.026,-0.007]],"v":[[-1.513,-2.246],[-1.019,-2.805],[-0.47,-2.31],[0.16,0.178],[1.346,1.837],[1.39,2.593],[0.635,2.592],[-1.002,0.093],[-1.592,-2.226]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.842,3.074],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"Back Nut 2 Outlines","parent":24,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[15.068,18.658,0],"ix":2},"a":{"a":0,"k":[3.064,1.834,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.019,0.312],[-0.323,0.03],[-0.658,0.249],[-0.607,0.577],[-0.197,-0.197],[0.242,-0.246],[0.996,-0.312],[0.727,-0.179]],"o":[[-0.356,0.008],[-0.017,-0.291],[0.695,-0.062],[0.793,-0.301],[0.249,-0.236],[0.208,0.209],[-0.729,0.745],[-0.714,0.224],[0,0]],"v":[[-2.21,1.501],[-2.797,1.026],[-2.28,0.459],[-0.25,0.027],[1.823,-1.321],[2.606,-1.387],[2.565,-0.596],[-0.009,1.039],[-2.189,1.584]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[3.064,1.834],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Back Nut 1 Outlines","parent":24,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[18.641,9.799,0],"ix":2},"a":{"a":0,"k":[1.816,3.073,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.087,-0.47],[0.292,-0.034],[0.077,0.388],[0.191,0.621],[0.633,0.629],[-0.15,0.237],[-0.251,-0.082],[-0.062,-0.06],[-0.297,-1.3]],"o":[[-0.032,0.38],[-0.32,0.038],[-0.127,-0.64],[-0.264,-0.853],[-0.2,-0.201],[0.143,-0.229],[0.078,0.026],[0.958,0.928],[0.108,0.465]],"v":[[1.566,2.154],[1.091,2.785],[0.497,2.242],[0.08,0.329],[-1.329,-1.871],[-1.416,-2.533],[-0.802,-2.741],[-0.589,-2.596],[1.3,0.747]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.816,3.073],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"Back Center Light Outlines","parent":24,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[12.438,12.414,0],"ix":2},"a":{"a":0,"k":[2.336,2.343,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.011,1.149],[1.123,0.012],[0.004,-1.145],[-1.12,-0.001]],"o":[[0.009,-1.123],[-1.142,-0.012],[-0.004,1.137],[1.153,0.001]],"v":[[2.077,0.014],[0.02,-2.081],[-2.082,-0.004],[-0.027,2.092]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.6,0.6,0.6,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[2.336,2.343],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":"Back Center Dark Outlines","parent":24,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[12.443,12.418,0],"ix":2},"a":{"a":0,"k":[4.432,4.441,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.321,-0.046],[0.019,-2.297],[2.345,0.03],[-0.009,2.302]],"o":[[2.309,-0.045],[-0.019,2.285],[-2.288,-0.03],[0.009,-2.285]],"v":[[-0.005,-4.146],[4.163,0.027],[-0.057,4.161],[-4.173,-0.008]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[4.431,4.441],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":23,"ty":4,"nm":"Back Wheel Inner Outlines","parent":24,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[12.438,12.427,0],"ix":2},"a":{"a":0,"k":[9.201,9.201,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,4.944],[4.943,0],[0,-4.943],[-4.945,0]],"o":[[0,-4.943],[-4.945,0],[0,4.944],[4.943,0]],"v":[[8.952,-0.001],[0.001,-8.952],[-8.952,-0.001],[0.001,8.952]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.6,0.6,0.6,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[9.201,9.202],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":24,"ty":4,"nm":"Back Wheel Body Outlines","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[720]},{"t":142}],"ix":10},"p":{"s":true,"x":{"a":0,"k":1.969,"ix":3},"y":{"a":0,"k":17.435,"ix":4}},"a":{"a":0,"k":[12.411,12.481,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.004,0.008],[0.011,0.198],[0.134,0.191],[0.399,0.578],[0.09,0.03],[0.213,0.853],[-0.494,0.223],[0.023,0.194],[0.086,0.835],[0.072,0.082],[-0.206,0.794],[-0.081,0.253],[-0.18,-0.026],[-0.063,0.144],[-0.363,0.82],[0.018,0.105],[-0.521,0.554],[-0.168,0.216],[-0.033,-0.034],[-0.008,-0.004],[-0.19,0.009],[-0.189,0.134],[-0.597,0.423],[-0.037,0.089],[-0.748,0.181],[-0.193,0.068],[-0.084,-0.185],[-0.529,0.073],[-0.758,0.076],[-0.094,0.077],[-0.761,-0.205],[-0.056,-0.018],[0.053,-0.53],[-0.153,-0.066],[-0.793,-0.346],[-0.113,0.017],[-0.597,-0.665],[0.3,-0.417],[-0.114,-0.154],[-0.517,-0.709],[-0.081,-0.03],[-0.19,-0.794],[-0.018,-0.076],[0.494,-0.222],[-0.023,-0.172],[-0.106,-0.834],[-0.108,-0.155],[0.104,-0.596],[0.061,-0.277],[0.2,0.022],[0.184,-0.434],[0.309,-0.695],[-0.019,-0.139],[0.636,-0.566],[0.014,-0.013],[0.467,0.306],[0.052,-0.057],[0.682,-0.399],[0.123,-0.316],[0.684,-0.136],[0.191,-0.071],[0.067,0.144],[0.608,-0.087],[0.71,-0.071],[0.123,-0.1],[0.905,0.305],[-0.002,0.078],[0.518,0.222],[0.675,0.307],[0.113,-0.016],[0.57,0.635],[0.168,0.148]],"o":[[0,-0.01],[0.123,-0.206],[-0.01,-0.187],[-0.401,-0.576],[-0.059,-0.085],[-0.889,-0.297],[-0.13,-0.515],[0.199,-0.09],[-0.099,-0.834],[-0.012,-0.121],[-0.568,-0.643],[0.059,-0.227],[0.178,0.017],[0.154,0.023],[0.359,-0.822],[0.045,-0.1],[-0.128,-0.768],[0.187,-0.198],[0.033,0.034],[0.009,0.001],[0.196,0.126],[0.186,-0.009],[0.597,-0.423],[0.081,-0.057],[0.29,-0.691],[0.199,-0.048],[0.182,-0.065],[0.223,0.491],[0.754,-0.104],[0.13,-0.014],[0.636,-0.517],[0.056,0.015],[0.513,0.162],[-0.017,0.168],[0.796,0.341],[0.112,0.049],[0.911,-0.14],[0.348,0.389],[-0.113,0.156],[0.526,0.703],[0.054,0.075],[0.762,0.29],[0.018,0.076],[0.13,0.533],[-0.15,0.068],[0.109,0.834],[0.024,0.192],[0.348,0.503],[-0.048,0.279],[-0.046,0.207],[-0.468,-0.052],[-0.297,0.701],[-0.062,0.137],[0.123,0.865],[-0.015,0.013],[-0.4,0.372],[-0.081,-0.052],[-0.543,0.592],[-0.268,0.157],[-0.251,0.645],[-0.199,0.04],[-0.156,0.058],[-0.247,-0.527],[-0.705,0.102],[-0.164,0.017],[-0.845,0.677],[-0.054,-0.019],[0.015,-0.559],[-0.68,-0.292],[-0.11,-0.051],[-0.841,0.119],[-0.149,-0.166],[0,0]],"v":[[-8.696,8.471],[-8.694,8.443],[-8.356,7.827],[-8.775,7.285],[-9.964,5.545],[-10.188,5.327],[-11.701,3.495],[-11.35,2.743],[-11.166,2.367],[-11.421,-0.141],[-11.512,-0.492],[-11.955,-2.665],[-11.732,-3.365],[-11.191,-3.313],[-10.911,-3.492],[-9.812,-5.949],[-9.757,-6.281],[-9.111,-8.236],[-8.604,-8.88],[-8.505,-8.779],[-8.477,-8.774],[-7.89,-8.426],[-7.347,-8.833],[-5.548,-10.09],[-5.355,-10.324],[-3.847,-11.678],[-3.257,-11.85],[-2.893,-11.688],[-2.136,-11.311],[0.141,-11.533],[0.519,-11.646],[2.624,-12.026],[2.793,-11.977],[3.26,-11.283],[3.45,-10.982],[5.827,-9.936],[6.186,-9.85],[8.401,-8.982],[8.469,-8.182],[8.484,-7.776],[10.032,-5.647],[10.238,-5.46],[11.67,-3.841],[11.732,-3.615],[11.37,-2.855],[11.21,-2.544],[11.5,-0.038],[11.685,0.521],[12.058,2.163],[11.863,2.99],[11.498,3.219],[10.87,3.62],[9.928,5.7],[9.818,6.139],[9.001,8.258],[8.957,8.299],[8.095,8.357],[7.766,8.359],[5.868,9.764],[5.271,10.406],[3.827,11.557],[3.243,11.738],[2.957,11.6],[2.101,11.201],[-0.031,11.391],[-0.507,11.554],[-3.153,11.738],[-3.25,11.507],[-3.758,10.747],[-5.777,9.816],[-6.134,9.728],[-8.245,8.967],[-8.747,8.521]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[12.411,12.482],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":25,"ty":4,"nm":"Nut 4 Outlines","parent":32,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[10.16,5.586,0],"ix":2},"a":{"a":0,"k":[0.723,0.73,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.004,-0.262],[-0.271,-0.001],[0.003,0.281],[0.281,-0.005]],"o":[[-0.005,0.275],[0.276,0.001],[-0.002,-0.285],[-0.257,0.005]],"v":[[-0.468,-0.006],[-0.001,0.479],[0.47,-0.003],[-0.009,-0.475]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.723,0.731],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":26,"ty":4,"nm":"Nut 3 Outlines","parent":32,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[5.621,4.868,0],"ix":2},"a":{"a":0,"k":[0.743,0.744,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.008,0.258],[0.249,0.002],[0.018,-0.246],[-0.245,-0.012]],"o":[[0.009,-0.251],[-0.239,-0.002],[-0.018,0.245],[0.253,0.012]],"v":[[0.485,0.008],[0.01,-0.492],[-0.475,-0.032],[-0.018,0.482]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.743,0.744],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":27,"ty":4,"nm":"Nut 2 Outlines","parent":32,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[4.904,9.394,0],"ix":2},"a":{"a":0,"k":[0.739,0.746,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.219,-0.01],[-0.004,-0.262],[-0.265,0.002],[0.005,0.25]],"o":[[-0.262,0.012],[0.004,0.265],[0.25,-0.002],[-0.003,-0.229]],"v":[[-0.013,-0.486],[-0.485,0.017],[0.004,0.494],[0.484,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.739,0.746],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":28,"ty":4,"nm":"Nut 1 Outlines","parent":32,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[9.434,10.125,0],"ix":2},"a":{"a":0,"k":[0.741,0.729,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.281,0.005],[0.004,-0.263],[-0.272,-0.005],[-0.006,0.282]],"o":[[-0.272,-0.004],[-0.004,0.265],[0.287,0.005],[0.005,-0.276]],"v":[[0.012,-0.475],[-0.486,-0.009],[-0.006,0.474],[0.486,0.008]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.74,0.729],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":29,"ty":4,"nm":"Front Center Light Outlines","parent":32,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[7.54,7.509,0],"ix":2},"a":{"a":0,"k":[1.142,1.137,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.441,-0.001],[-0.009,0.483],[-0.509,-0.002],[0.003,-0.475]],"o":[[-0.474,0.002],[0.009,-0.504],[0.487,0.002],[-0.002,0.446]],"v":[[0.001,0.884],[-0.883,-0.029],[0.003,-0.885],[0.889,-0.012]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.6,0.6,0.6,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.142,1.137],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":30,"ty":4,"nm":"Front Center Dark Outlines","parent":32,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[7.546,7.513,0],"ix":2},"a":{"a":0,"k":[2.188,2.185,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.084,0.003],[0.004,-1.083],[-1.081,-0.013],[-0.006,1.034]],"o":[[-1.089,-0.003],[-0.004,1.084],[1.027,0.013],[0.007,-1.067]],"v":[[-0.012,-1.932],[-1.934,-0.033],[-0.016,1.922],[1.931,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[2.188,2.185],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":31,"ty":4,"nm":"Front Wheel Inner Outlines","parent":32,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[7.508,7.508,0],"ix":2},"a":{"a":0,"k":[4.693,4.692,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,2.454],[2.454,0],[0,-2.453],[-2.453,0]],"o":[[0,-2.453],[-2.453,0],[0,2.454],[2.454,0]],"v":[[4.443,0],[0,-4.442],[-4.443,0],[0,4.442]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.6,0.6,0.6,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[4.693,4.692],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":32,"ty":4,"nm":"Front Wheel Body Outlines","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[1440]},{"t":142}],"ix":10},"p":{"s":true,"x":{"a":0,"k":38.472,"ix":3},"y":{"a":0,"k":22.138,"ix":4}},"a":{"a":0,"k":[7.508,7.508,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.009,0],[0,-4.008],[-4.008,0],[0,4.009]],"o":[[-4.008,0],[0,4.009],[4.009,0],[0,-4.008]],"v":[[0,-7.258],[-7.258,0],[0,7.258],[7.258,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.2,0.2,0.2,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[7.508,7.508],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":33,"ty":4,"nm":"Body Top Back Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[51.891,12.164,0],"ix":2},"a":{"a":0,"k":[4.035,2.441,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.267,0.002],[-1.524,-0.002],[0.001,-1.02],[0.012,-0.274],[-0.089,-0.038],[0,0],[-0.058,0.003],[0.003,0.351],[0.457,0.012],[0.009,-0.002],[-0.009,0.207],[0,0.274],[1.021,0.002],[1.523,-0.012],[0.005,0.222],[0.004,-0.44]],"o":[[1.523,-0.012],[1.021,0.002],[0,0.274],[-0.006,0.141],[0,0],[0.097,-0.008],[0.433,-0.018],[-0.004,-0.355],[-0.01,-0.001],[-0.23,0.032],[0.012,-0.274],[0.001,-1.021],[-1.524,-0.002],[-0.252,0.001],[0,0.44],[-0.002,0.252]],"v":[[-3.454,-0.532],[1.118,-0.537],[2.74,1.094],[2.738,1.917],[2.852,2.191],[2.852,2.076],[3.064,2.058],[3.783,1.442],[3.046,0.853],[3.016,0.853],[2.738,0.561],[2.74,-0.261],[1.118,-1.893],[-3.454,-1.887],[-3.781,-2.191],[-3.784,-0.87]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.957000014361,0.463000009574,0.451000019148,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[4.035,2.441],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":34,"ty":4,"nm":"Body Top Front Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[36.774,12.109,0],"ix":2},"a":{"a":0,"k":[9.459,2.378,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.938,0],[-5.172,-0.009],[0.004,0.301],[0,0.427],[0.267,0],[5.172,-0.002],[0.005,-0.933],[0,-0.403],[0.106,-0.008],[0.009,-0.328],[-0.345,-0.036],[-0.11,-0.012],[-0.002,0.342]],"o":[[5.172,-0.002],[0.297,0.001],[-0.007,-0.427],[-0.014,0.23],[-5.172,-0.01],[-0.938,0.001],[-0.003,0.379],[-0.139,0.008],[-0.351,0.028],[-0.009,0.326],[0.11,0.011],[0,-0.359],[0.005,-0.932]],"v":[[-6.691,-0.481],[8.826,-0.476],[9.205,-0.847],[9.199,-2.128],[8.826,-1.831],[-6.691,-1.837],[-8.265,-0.273],[-8.266,0.889],[-8.616,0.91],[-9.2,1.489],[-8.619,2.112],[-8.266,2.128],[-8.265,1.082]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.957000014361,0.463000009574,0.451000019148,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[9.459,2.378],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":35,"ty":4,"nm":"Body Main Outlines","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":0,"k":17.757,"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.465]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p465_0p167_0p167"],"t":0,"s":[8.208],"e":[8.174]},{"i":{"x":[0.833],"y":[0.83]},"o":{"x":[0.167],"y":[0.099]},"n":["0p833_0p83_0p167_0p099"],"t":1,"s":[8.174],"e":[7.99]},{"i":{"x":[0.833],"y":[0.903]},"o":{"x":[0.167],"y":[0.163]},"n":["0p833_0p903_0p167_0p163"],"t":2,"s":[7.99],"e":[7.799]},{"i":{"x":[0.833],"y":[1.228]},"o":{"x":[0.167],"y":[0.584]},"n":["0p833_1p228_0p167_0p584"],"t":3,"s":[7.799],"e":[7.767]},{"i":{"x":[0.833],"y":[0.739]},"o":{"x":[0.167],"y":[0.061]},"n":["0p833_0p739_0p167_0p061"],"t":4,"s":[7.767],"e":[7.886]},{"i":{"x":[0.833],"y":[0.804]},"o":{"x":[0.167],"y":[0.122]},"n":["0p833_0p804_0p167_0p122"],"t":5,"s":[7.886],"e":[8.141]},{"i":{"x":[0.833],"y":[0.831]},"o":{"x":[0.167],"y":[0.145]},"n":["0p833_0p831_0p167_0p145"],"t":6,"s":[8.141],"e":[8.483]},{"i":{"x":[0.833],"y":[0.859]},"o":{"x":[0.167],"y":[0.165]},"n":["0p833_0p859_0p167_0p165"],"t":7,"s":[8.483],"e":[8.834]},{"i":{"x":[0.833],"y":[0.921]},"o":{"x":[0.167],"y":[0.203]},"n":["0p833_0p921_0p167_0p203"],"t":8,"s":[8.834],"e":[9.078]},{"i":{"x":[0.833],"y":[-1.176]},"o":{"x":[0.167],"y":[-1.612]},"n":["0p833_-1p176_0p167_-1p612"],"t":9,"s":[9.078],"e":[9.066]},{"i":{"x":[0.833],"y":[0.781]},"o":{"x":[0.167],"y":[0.087]},"n":["0p833_0p781_0p167_0p087"],"t":10,"s":[9.066],"e":[8.765]},{"i":{"x":[0.833],"y":[0.822]},"o":{"x":[0.167],"y":[0.134]},"n":["0p833_0p822_0p167_0p134"],"t":11,"s":[8.765],"e":[8.275]},{"i":{"x":[0.833],"y":[0.844]},"o":{"x":[0.167],"y":[0.156]},"n":["0p833_0p844_0p167_0p156"],"t":12,"s":[8.275],"e":[7.715]},{"i":{"x":[0.833],"y":[0.872]},"o":{"x":[0.167],"y":[0.178]},"n":["0p833_0p872_0p167_0p178"],"t":13,"s":[7.715],"e":[7.225]},{"i":{"x":[0.833],"y":[0.953]},"o":{"x":[0.167],"y":[0.238]},"n":["0p833_0p953_0p167_0p238"],"t":14,"s":[7.225],"e":[6.961]},{"i":{"x":[0.833],"y":[0.66]},"o":{"x":[0.167],"y":[-0.107]},"n":["0p833_0p66_0p167_-0p107"],"t":15,"s":[6.961],"e":[7.077]},{"i":{"x":[0.833],"y":[0.84]},"o":{"x":[0.167],"y":[0.11]},"n":["0p833_0p84_0p167_0p11"],"t":16,"s":[7.077],"e":[7.433]},{"i":{"x":[0.833],"y":[0.883]},"o":{"x":[0.167],"y":[0.174]},"n":["0p833_0p883_0p167_0p174"],"t":17,"s":[7.433],"e":[7.76]},{"i":{"x":[0.833],"y":[1.002]},"o":{"x":[0.167],"y":[0.293]},"n":["0p833_1p002_0p167_0p293"],"t":18,"s":[7.76],"e":[7.891]},{"i":{"x":[0.833],"y":[0.69]},"o":{"x":[0.167],"y":[0.002]},"n":["0p833_0p69_0p167_0p002"],"t":19,"s":[7.891],"e":[7.757]},{"i":{"x":[0.833],"y":[0.784]},"o":{"x":[0.167],"y":[0.114]},"n":["0p833_0p784_0p167_0p114"],"t":20,"s":[7.757],"e":[7.393]},{"i":{"x":[0.833],"y":[0.819]},"o":{"x":[0.167],"y":[0.135]},"n":["0p833_0p819_0p167_0p135"],"t":21,"s":[7.393],"e":[6.812]},{"i":{"x":[0.833],"y":[0.87]},"o":{"x":[0.167],"y":[0.154]},"n":["0p833_0p87_0p167_0p154"],"t":22,"s":[6.812],"e":[6.129]},{"i":{"x":[0.833],"y":[0.94]},"o":{"x":[0.167],"y":[0.233]},"n":["0p833_0p94_0p167_0p233"],"t":23,"s":[6.129],"e":[5.748]},{"i":{"x":[0.833],"y":[0.488]},"o":{"x":[0.167],"y":[-0.212]},"n":["0p833_0p488_0p167_-0p212"],"t":24,"s":[5.748],"e":[5.855]},{"i":{"x":[0.833],"y":[0.807]},"o":{"x":[0.167],"y":[0.1]},"n":["0p833_0p807_0p167_0p1"],"t":25,"s":[5.855],"e":[6.408]},{"i":{"x":[0.833],"y":[0.863]},"o":{"x":[0.167],"y":[0.147]},"n":["0p833_0p863_0p167_0p147"],"t":26,"s":[6.408],"e":[7.134]},{"i":{"x":[0.833],"y":[0.897]},"o":{"x":[0.167],"y":[0.212]},"n":["0p833_0p897_0p167_0p212"],"t":27,"s":[7.134],"e":[7.603]},{"i":{"x":[0.833],"y":[1.043]},"o":{"x":[0.167],"y":[0.443]},"n":["0p833_1p043_0p167_0p443"],"t":28,"s":[7.603],"e":[7.711]},{"i":{"x":[0.833],"y":[0.763]},"o":{"x":[0.167],"y":[0.028]},"n":["0p833_0p763_0p167_0p028"],"t":29,"s":[7.711],"e":[7.547]},{"i":{"x":[0.833],"y":[0.845]},"o":{"x":[0.167],"y":[0.129]},"n":["0p833_0p845_0p167_0p129"],"t":30,"s":[7.547],"e":[7.243]},{"i":{"x":[0.833],"y":[0.92]},"o":{"x":[0.167],"y":[0.18]},"n":["0p833_0p92_0p167_0p18"],"t":31,"s":[7.243],"e":[6.982]},{"i":{"x":[0.833],"y":[-0.784]},"o":{"x":[0.167],"y":[-1.91]},"n":["0p833_-0p784_0p167_-1p91"],"t":32,"s":[6.982],"e":[6.993]},{"i":{"x":[0.833],"y":[0.964]},"o":{"x":[0.167],"y":[0.087]},"n":["0p833_0p964_0p167_0p087"],"t":33,"s":[6.993],"e":[7.215]},{"i":{"x":[0.833],"y":[0.656]},"o":{"x":[0.167],"y":[-0.062]},"n":["0p833_0p656_0p167_-0p062"],"t":34,"s":[7.215],"e":[7.088]},{"i":{"x":[0.833],"y":[0.807]},"o":{"x":[0.167],"y":[0.11]},"n":["0p833_0p807_0p167_0p11"],"t":35,"s":[7.088],"e":[6.689]},{"i":{"x":[0.833],"y":[0.843]},"o":{"x":[0.167],"y":[0.147]},"n":["0p833_0p843_0p167_0p147"],"t":36,"s":[6.689],"e":[6.164]},{"i":{"x":[0.833],"y":[0.885]},"o":{"x":[0.167],"y":[0.177]},"n":["0p833_0p885_0p167_0p177"],"t":37,"s":[6.164],"e":[5.698]},{"i":{"x":[0.833],"y":[1.009]},"o":{"x":[0.167],"y":[0.3]},"n":["0p833_1p009_0p167_0p3"],"t":38,"s":[5.698],"e":[5.518]},{"i":{"x":[0.833],"y":[0.789]},"o":{"x":[0.167],"y":[0.008]},"n":["0p833_0p789_0p167_0p008"],"t":39,"s":[5.518],"e":[5.717]},{"i":{"x":[0.833],"y":[0.818]},"o":{"x":[0.167],"y":[0.138]},"n":["0p833_0p818_0p167_0p138"],"t":40,"s":[5.717],"e":[6.021]},{"i":{"x":[0.833],"y":[0.83]},"o":{"x":[0.167],"y":[0.153]},"n":["0p833_0p83_0p167_0p153"],"t":41,"s":[6.021],"e":[6.383]},{"i":{"x":[0.833],"y":[0.839]},"o":{"x":[0.167],"y":[0.163]},"n":["0p833_0p839_0p167_0p163"],"t":42,"s":[6.383],"e":[6.761]},{"i":{"x":[0.833],"y":[0.851]},"o":{"x":[0.167],"y":[0.173]},"n":["0p833_0p851_0p167_0p173"],"t":43,"s":[6.761],"e":[7.112]},{"i":{"x":[0.833],"y":[0.907]},"o":{"x":[0.167],"y":[0.189]},"n":["0p833_0p907_0p167_0p189"],"t":44,"s":[7.112],"e":[7.388]},{"i":{"x":[0.833],"y":[1.9]},"o":{"x":[0.167],"y":[0.792]},"n":["0p833_1p9_0p167_0p792"],"t":45,"s":[7.388],"e":[7.42]},{"i":{"x":[0.833],"y":[0.786]},"o":{"x":[0.167],"y":[0.076]},"n":["0p833_0p786_0p167_0p076"],"t":46,"s":[7.42],"e":[7.037]},{"i":{"x":[0.833],"y":[0.831]},"o":{"x":[0.167],"y":[0.137]},"n":["0p833_0p831_0p167_0p137"],"t":47,"s":[7.037],"e":[6.438]},{"i":{"x":[0.833],"y":[0.857]},"o":{"x":[0.167],"y":[0.164]},"n":["0p833_0p857_0p167_0p164"],"t":48,"s":[6.438],"e":[5.823]},{"i":{"x":[0.833],"y":[0.898]},"o":{"x":[0.167],"y":[0.199]},"n":["0p833_0p898_0p167_0p199"],"t":49,"s":[5.823],"e":[5.379]},{"i":{"x":[0.833],"y":[1.272]},"o":{"x":[0.167],"y":[0.463]},"n":["0p833_1p272_0p167_0p463"],"t":50,"s":[5.379],"e":[5.282]},{"i":{"x":[0.833],"y":[0.765]},"o":{"x":[0.167],"y":[0.064]},"n":["0p833_0p765_0p167_0p064"],"t":51,"s":[5.282],"e":[5.697]},{"i":{"x":[0.833],"y":[0.838]},"o":{"x":[0.167],"y":[0.129]},"n":["0p833_0p838_0p167_0p129"],"t":52,"s":[5.697],"e":[6.453]},{"i":{"x":[0.833],"y":[0.866]},"o":{"x":[0.167],"y":[0.171]},"n":["0p833_0p866_0p167_0p171"],"t":53,"s":[6.453],"e":[7.169]},{"i":{"x":[0.833],"y":[0.906]},"o":{"x":[0.167],"y":[0.221]},"n":["0p833_0p906_0p167_0p221"],"t":54,"s":[7.169],"e":[7.603]},{"i":{"x":[0.833],"y":[1.307]},"o":{"x":[0.167],"y":[0.712]},"n":["0p833_1p307_0p167_0p712"],"t":55,"s":[7.603],"e":[7.661]},{"i":{"x":[0.833],"y":[0.818]},"o":{"x":[0.167],"y":[0.066]},"n":["0p833_0p818_0p167_0p066"],"t":56,"s":[7.661],"e":[7.391]},{"i":{"x":[0.833],"y":[0.904]},"o":{"x":[0.167],"y":[0.154]},"n":["0p833_0p904_0p167_0p154"],"t":57,"s":[7.391],"e":[7.072]},{"i":{"x":[0.833],"y":[1.255]},"o":{"x":[0.167],"y":[0.627]},"n":["0p833_1p255_0p167_0p627"],"t":58,"s":[7.072],"e":[7.023]},{"i":{"x":[0.833],"y":[0.768]},"o":{"x":[0.167],"y":[0.063]},"n":["0p833_0p768_0p167_0p063"],"t":59,"s":[7.023],"e":[7.221]},{"i":{"x":[0.833],"y":[0.832]},"o":{"x":[0.167],"y":[0.13]},"n":["0p833_0p832_0p167_0p13"],"t":60,"s":[7.221],"e":[7.576]},{"i":{"x":[0.833],"y":[0.88]},"o":{"x":[0.167],"y":[0.165]},"n":["0p833_0p88_0p167_0p165"],"t":61,"s":[7.576],"e":[7.936]},{"i":{"x":[0.833],"y":[1.009]},"o":{"x":[0.167],"y":[0.275]},"n":["0p833_1p009_0p167_0p275"],"t":62,"s":[7.936],"e":[8.093]},{"i":{"x":[0.833],"y":[0.821]},"o":{"x":[0.167],"y":[0.008]},"n":["0p833_0p821_0p167_0p008"],"t":63,"s":[8.093],"e":[7.919]},{"i":{"x":[0.833],"y":[0.902]},"o":{"x":[0.167],"y":[0.156]},"n":["0p833_0p902_0p167_0p156"],"t":64,"s":[7.919],"e":[7.721]},{"i":{"x":[0.833],"y":[1.417]},"o":{"x":[0.167],"y":[0.571]},"n":["0p833_1p417_0p167_0p571"],"t":65,"s":[7.721],"e":[7.687]},{"i":{"x":[0.833],"y":[0.751]},"o":{"x":[0.167],"y":[0.069]},"n":["0p833_0p751_0p167_0p069"],"t":66,"s":[7.687],"e":[7.891]},{"i":{"x":[0.833],"y":[0.822]},"o":{"x":[0.167],"y":[0.125]},"n":["0p833_0p822_0p167_0p125"],"t":67,"s":[7.891],"e":[8.296]},{"i":{"x":[0.833],"y":[0.869]},"o":{"x":[0.167],"y":[0.157]},"n":["0p833_0p869_0p167_0p157"],"t":68,"s":[8.296],"e":[8.754]},{"i":{"x":[0.833],"y":[0.95]},"o":{"x":[0.167],"y":[0.229]},"n":["0p833_0p95_0p167_0p229"],"t":69,"s":[8.754],"e":[9.017]},{"i":{"x":[0.833],"y":[0.534]},"o":{"x":[0.167],"y":[-0.128]},"n":["0p833_0p534_0p167_-0p128"],"t":70,"s":[9.017],"e":[8.913]},{"i":{"x":[0.833],"y":[0.786]},"o":{"x":[0.167],"y":[0.101]},"n":["0p833_0p786_0p167_0p101"],"t":71,"s":[8.913],"e":[8.436]},{"i":{"x":[0.833],"y":[0.827]},"o":{"x":[0.167],"y":[0.136]},"n":["0p833_0p827_0p167_0p136"],"t":72,"s":[8.436],"e":[7.688]},{"i":{"x":[0.833],"y":[0.86]},"o":{"x":[0.167],"y":[0.16]},"n":["0p833_0p86_0p167_0p16"],"t":73,"s":[7.688],"e":[6.88]},{"i":{"x":[0.833],"y":[0.894]},"o":{"x":[0.167],"y":[0.206]},"n":["0p833_0p894_0p167_0p206"],"t":74,"s":[6.88],"e":[6.329]},{"i":{"x":[0.833],"y":[0.855]},"o":{"x":[0.167],"y":[0.384]},"n":["0p833_0p855_0p167_0p384"],"t":75,"s":[6.329],"e":[6.176]},{"i":{"x":[0.833],"y":[0.887]},"o":{"x":[0.167],"y":[0.195]},"n":["0p833_0p887_0p167_0p195"],"t":76,"s":[6.176],"e":[6.062]},{"i":{"x":[0.833],"y":[1.012]},"o":{"x":[0.167],"y":[0.316]},"n":["0p833_1p012_0p167_0p316"],"t":77,"s":[6.062],"e":[6.021]},{"i":{"x":[0.833],"y":[0.722]},"o":{"x":[0.167],"y":[0.01]},"n":["0p833_0p722_0p167_0p01"],"t":78,"s":[6.021],"e":[6.068]},{"i":{"x":[0.833],"y":[0.835]},"o":{"x":[0.167],"y":[0.119]},"n":["0p833_0p835_0p167_0p119"],"t":79,"s":[6.068],"e":[6.177]},{"i":{"x":[0.833],"y":[0.83]},"o":{"x":[0.167],"y":[0.168]},"n":["0p833_0p83_0p167_0p168"],"t":80,"s":[6.177],"e":[6.285]},{"i":{"x":[0.833],"y":[0.733]},"o":{"x":[0.167],"y":[0.163]},"n":["0p833_0p733_0p167_0p163"],"t":81,"s":[6.285],"e":[6.397]},{"i":{"x":[0.833],"y":[0.816]},"o":{"x":[0.167],"y":[0.121]},"n":["0p833_0p816_0p167_0p121"],"t":82,"s":[6.397],"e":[6.644]},{"i":{"x":[0.833],"y":[0.84]},"o":{"x":[0.167],"y":[0.152]},"n":["0p833_0p84_0p167_0p152"],"t":83,"s":[6.644],"e":[6.942]},{"i":{"x":[0.833],"y":[0.858]},"o":{"x":[0.167],"y":[0.174]},"n":["0p833_0p858_0p167_0p174"],"t":84,"s":[6.942],"e":[7.218]},{"i":{"x":[0.833],"y":[0.885]},"o":{"x":[0.167],"y":[0.201]},"n":["0p833_0p885_0p167_0p201"],"t":85,"s":[7.218],"e":[7.413]},{"i":{"x":[0.833],"y":[0.967]},"o":{"x":[0.167],"y":[0.303]},"n":["0p833_0p967_0p167_0p303"],"t":86,"s":[7.413],"e":[7.487]},{"i":{"x":[0.833],"y":[0.777]},"o":{"x":[0.167],"y":[-0.056]},"n":["0p833_0p777_0p167_-0p056"],"t":87,"s":[7.487],"e":[7.442]},{"i":{"x":[0.833],"y":[0.861]},"o":{"x":[0.167],"y":[0.133]},"n":["0p833_0p861_0p167_0p133"],"t":88,"s":[7.442],"e":[7.368]},{"i":{"x":[0.833],"y":[0.921]},"o":{"x":[0.167],"y":[0.207]},"n":["0p833_0p921_0p167_0p207"],"t":89,"s":[7.368],"e":[7.318]},{"i":{"x":[0.833],"y":[-1.111]},"o":{"x":[0.167],"y":[-1.691]},"n":["0p833_-1p111_0p167_-1p691"],"t":90,"s":[7.318],"e":[7.321]},{"i":{"x":[0.833],"y":[0.787]},"o":{"x":[0.167],"y":[0.087]},"n":["0p833_0p787_0p167_0p087"],"t":91,"s":[7.321],"e":[7.378]},{"i":{"x":[0.833],"y":[0.781]},"o":{"x":[0.167],"y":[0.137]},"n":["0p833_0p781_0p167_0p137"],"t":92,"s":[7.378],"e":[7.466]},{"i":{"x":[0.833],"y":[0.796]},"o":{"x":[0.167],"y":[0.135]},"n":["0p833_0p796_0p167_0p135"],"t":93,"s":[7.466],"e":[7.61]},{"i":{"x":[0.833],"y":[0.872]},"o":{"x":[0.167],"y":[0.141]},"n":["0p833_0p872_0p167_0p141"],"t":94,"s":[7.61],"e":[7.819]},{"i":{"x":[0.833],"y":[0.969]},"o":{"x":[0.167],"y":[0.24]},"n":["0p833_0p969_0p167_0p24"],"t":95,"s":[7.819],"e":[7.931]},{"i":{"x":[0.833],"y":[0.622]},"o":{"x":[0.167],"y":[-0.048]},"n":["0p833_0p622_0p167_-0p048"],"t":96,"s":[7.931],"e":[7.86]},{"i":{"x":[0.833],"y":[0.804]},"o":{"x":[0.167],"y":[0.107]},"n":["0p833_0p804_0p167_0p107"],"t":97,"s":[7.86],"e":[7.611]},{"i":{"x":[0.833],"y":[0.84]},"o":{"x":[0.167],"y":[0.145]},"n":["0p833_0p84_0p167_0p145"],"t":98,"s":[7.611],"e":[7.275]},{"i":{"x":[0.833],"y":[0.849]},"o":{"x":[0.167],"y":[0.174]},"n":["0p833_0p849_0p167_0p174"],"t":99,"s":[7.275],"e":[6.964]},{"i":{"x":[0.833],"y":[0.877]},"o":{"x":[0.167],"y":[0.186]},"n":["0p833_0p877_0p167_0p186"],"t":100,"s":[6.964],"e":[6.712]},{"i":{"x":[0.833],"y":[0.935]},"o":{"x":[0.167],"y":[0.259]},"n":["0p833_0p935_0p167_0p259"],"t":101,"s":[6.712],"e":[6.592]},{"i":{"x":[0.833],"y":[0.535]},"o":{"x":[0.167],"y":[-0.293]},"n":["0p833_0p535_0p167_-0p293"],"t":102,"s":[6.592],"e":[6.619]},{"i":{"x":[0.833],"y":[0.848]},"o":{"x":[0.167],"y":[0.102]},"n":["0p833_0p848_0p167_0p102"],"t":103,"s":[6.619],"e":[6.74]},{"i":{"x":[0.833],"y":[0.892]},"o":{"x":[0.167],"y":[0.184]},"n":["0p833_0p892_0p167_0p184"],"t":104,"s":[6.74],"e":[6.841]},{"i":{"x":[0.833],"y":[0.656]},"o":{"x":[0.167],"y":[0.36]},"n":["0p833_0p656_0p167_0p36"],"t":105,"s":[6.841],"e":[6.871]},{"i":{"x":[0.833],"y":[0.84]},"o":{"x":[0.167],"y":[0.11]},"n":["0p833_0p84_0p167_0p11"],"t":106,"s":[6.871],"e":[6.966]},{"i":{"x":[0.833],"y":[0.89]},"o":{"x":[0.167],"y":[0.174]},"n":["0p833_0p89_0p167_0p174"],"t":107,"s":[6.966],"e":[7.052]},{"i":{"x":[0.833],"y":[1.075]},"o":{"x":[0.167],"y":[0.346]},"n":["0p833_1p075_0p167_0p346"],"t":108,"s":[7.052],"e":[7.08]},{"i":{"x":[0.833],"y":[0.722]},"o":{"x":[0.167],"y":[0.039]},"n":["0p833_0p722_0p167_0p039"],"t":109,"s":[7.08],"e":[7.028]},{"i":{"x":[0.833],"y":[0.817]},"o":{"x":[0.167],"y":[0.119]},"n":["0p833_0p817_0p167_0p119"],"t":110,"s":[7.028],"e":[6.905]},{"i":{"x":[0.833],"y":[0.891]},"o":{"x":[0.167],"y":[0.153]},"n":["0p833_0p891_0p167_0p153"],"t":111,"s":[6.905],"e":[6.759]},{"i":{"x":[0.833],"y":[1.212]},"o":{"x":[0.167],"y":[0.355]},"n":["0p833_1p212_0p167_0p355"],"t":112,"s":[6.759],"e":[6.715]},{"i":{"x":[0.833],"y":[0.722]},"o":{"x":[0.167],"y":[0.06]},"n":["0p833_0p722_0p167_0p06"],"t":113,"s":[6.715],"e":[6.873]},{"i":{"x":[0.833],"y":[0.804]},"o":{"x":[0.167],"y":[0.119]},"n":["0p833_0p804_0p167_0p119"],"t":114,"s":[6.873],"e":[7.244]},{"i":{"x":[0.833],"y":[0.841]},"o":{"x":[0.167],"y":[0.145]},"n":["0p833_0p841_0p167_0p145"],"t":115,"s":[7.244],"e":[7.744]},{"i":{"x":[0.833],"y":[0.885]},"o":{"x":[0.167],"y":[0.176]},"n":["0p833_0p885_0p167_0p176"],"t":116,"s":[7.744],"e":[8.195]},{"i":{"x":[0.833],"y":[0.959]},"o":{"x":[0.167],"y":[0.3]},"n":["0p833_0p959_0p167_0p3"],"t":117,"s":[8.195],"e":[8.369]},{"i":{"x":[0.833],"y":[0.72]},"o":{"x":[0.167],"y":[-0.082]},"n":["0p833_0p72_0p167_-0p082"],"t":118,"s":[8.369],"e":[8.281]},{"i":{"x":[0.833],"y":[0.836]},"o":{"x":[0.167],"y":[0.119]},"n":["0p833_0p836_0p167_0p119"],"t":119,"s":[8.281],"e":[8.074]},{"i":{"x":[0.833],"y":[0.883]},"o":{"x":[0.167],"y":[0.17]},"n":["0p833_0p883_0p167_0p17"],"t":120,"s":[8.074],"e":[7.875]},{"i":{"x":[0.833],"y":[1.056]},"o":{"x":[0.167],"y":[0.29]},"n":["0p833_1p056_0p167_0p29"],"t":121,"s":[7.875],"e":[7.795]},{"i":{"x":[0.833],"y":[0.643]},"o":{"x":[0.167],"y":[0.033]},"n":["0p833_0p643_0p167_0p033"],"t":122,"s":[7.795],"e":[7.929]},{"i":{"x":[0.833],"y":[0.811]},"o":{"x":[0.167],"y":[0.109]},"n":["0p833_0p811_0p167_0p109"],"t":123,"s":[7.929],"e":[8.371]},{"i":{"x":[0.833],"y":[0.868]},"o":{"x":[0.167],"y":[0.149]},"n":["0p833_0p868_0p167_0p149"],"t":124,"s":[8.371],"e":[8.93]},{"i":{"x":[0.833],"y":[0.934]},"o":{"x":[0.167],"y":[0.225]},"n":["0p833_0p934_0p167_0p225"],"t":125,"s":[8.93],"e":[9.259]},{"i":{"x":[0.833],"y":[0.375]},"o":{"x":[0.167],"y":[-0.319]},"n":["0p833_0p375_0p167_-0p319"],"t":126,"s":[9.259],"e":[9.191]},{"i":{"x":[0.833],"y":[0.802]},"o":{"x":[0.167],"y":[0.096]},"n":["0p833_0p802_0p167_0p096"],"t":127,"s":[9.191],"e":[8.749]},{"i":{"x":[0.833],"y":[0.841]},"o":{"x":[0.167],"y":[0.144]},"n":["0p833_0p841_0p167_0p144"],"t":128,"s":[8.749],"e":[8.142]},{"i":{"x":[0.833],"y":[0.844]},"o":{"x":[0.167],"y":[0.175]},"n":["0p833_0p844_0p167_0p175"],"t":129,"s":[8.142],"e":[7.59]},{"i":{"x":[0.833],"y":[0.882]},"o":{"x":[0.167],"y":[0.179]},"n":["0p833_0p882_0p167_0p179"],"t":130,"s":[7.59],"e":[7.108]},{"i":{"x":[0.833],"y":[0.979]},"o":{"x":[0.167],"y":[0.284]},"n":["0p833_0p979_0p167_0p284"],"t":131,"s":[7.108],"e":[6.908]},{"i":{"x":[0.833],"y":[0.689]},"o":{"x":[0.167],"y":[-0.028]},"n":["0p833_0p689_0p167_-0p028"],"t":132,"s":[6.908],"e":[7.057]},{"i":{"x":[0.833],"y":[0.831]},"o":{"x":[0.167],"y":[0.114]},"n":["0p833_0p831_0p167_0p114"],"t":133,"s":[7.057],"e":[7.465]},{"i":{"x":[0.833],"y":[0.899]},"o":{"x":[0.167],"y":[0.165]},"n":["0p833_0p899_0p167_0p165"],"t":134,"s":[7.465],"e":[7.883]},{"i":{"x":[0.833],"y":[1.108]},"o":{"x":[0.167],"y":[0.476]},"n":["0p833_1p108_0p167_0p476"],"t":135,"s":[7.883],"e":[7.972]},{"i":{"x":[0.833],"y":[0.796]},"o":{"x":[0.167],"y":[0.047]},"n":["0p833_0p796_0p167_0p047"],"t":136,"s":[7.972],"e":[7.768]},{"i":{"x":[0.833],"y":[0.852]},"o":{"x":[0.167],"y":[0.141]},"n":["0p833_0p852_0p167_0p141"],"t":137,"s":[7.768],"e":[7.473]},{"i":{"x":[0.833],"y":[0.899]},"o":{"x":[0.167],"y":[0.191]},"n":["0p833_0p899_0p167_0p191"],"t":138,"s":[7.473],"e":[7.245]},{"i":{"x":[0.833],"y":[1.278]},"o":{"x":[0.167],"y":[0.488]},"n":["0p833_1p278_0p167_0p488"],"t":139,"s":[7.245],"e":[7.198]},{"i":{"x":[0.833],"y":[0.785]},"o":{"x":[0.167],"y":[0.064]},"n":["0p833_0p785_0p167_0p064"],"t":140,"s":[7.198],"e":[7.402]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.136]},"n":["0p833_0p833_0p167_0p136"],"t":141,"s":[7.402],"e":[7.723]},{"t":142}],"ix":4}},"a":{"a":0,"k":[28.441,21.711,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.745,0.472],[0.129,0.165],[0.024,0.263],[-0.243,-0.001],[-1.293,-0.012],[0.002,0.24],[-0.01,1.272],[0.239,-0.005],[0.744,0.004],[-0.007,0.291],[-0.336,0.003],[-0.657,0.005],[-0.021,0.646],[0.223,-0.003],[0.735,0.005],[0.1,0.048],[-0.043,0.221],[-0.246,0.001],[-0.676,0.005],[-0.026,0.629],[0.227,-0.003],[0.735,0.005],[-0.01,0.279],[-0.362,0.01],[-0.059,0],[-0.676,-0.012],[0.041,0.257],[-0.009,0.057],[0.3,-0.008],[0.725,0.008],[-0.139,0.326],[-0.227,-0.001],[-0.686,0.001],[-0.029,0.54],[0.297,-0.009],[0.734,0.009],[-0.223,0.299],[-0.172,0.007],[-0.685,-0.001],[-0.001,0.465],[0,0],[-0.057,0.003],[0.003,0.351],[0.455,0.012],[0.01,-0.002],[-0.01,0.208],[0,0.275],[1.017,0.001],[1.518,-0.012],[-0.002,0.251],[-0.005,1.214],[0.263,-0.019],[0.001,0.07],[-0.007,1.175],[-0.335,0.147],[-0.09,0.155],[0.025,0.233],[-0.001,0.02],[0.153,-0.032],[-0.005,-1.331],[-0.008,-1.078],[0.241,0.036],[-0.003,-0.245],[-0.018,-1.204],[0.296,0],[5.152,-0.001],[0.005,-0.933],[0,-0.403],[0.104,-0.008],[0.008,-0.328],[-0.344,-0.036],[-0.085,-0.1],[-0.006,-0.185],[-0.004,-0.049],[0.164,-0.027],[0.97,-0.181],[0,0],[0.369,-0.231],[0.371,-0.281],[-0.024,-0.014],[-0.804,-0.805],[-0.642,-1.238],[-0.19,0.005],[-0.588,-0.013],[-0.002,0.213],[-0.007,0.627],[0,0.753],[0,0],[0.013,-0.662],[-0.278,0.006],[-1.136,0],[-1.184,-0.016],[0.003,0.206],[0.023,0.713],[-0.242,-0.003],[0.008,-0.336],[-0.038,-0.596],[-0.89,0.001],[-1.245,0.013],[0.003,-0.268],[0,-1.058],[0.42,0],[6.181,-0.028],[0.21,0.448],[1.071,1.103],[1.514,0.737],[1.612,0.228],[0.062,0.094],[0.63,0.942],[0.369,0.48],[1.249,-0.024],[0.463,-0.063],[-0.221,-0.992],[-0.2,-0.877],[0.237,-0.061],[0.323,-0.11],[1.135,-0.883],[0.335,-0.266],[-0.006,0.075],[0.42,0.306],[0.759,-0.034],[-0.009,-0.978],[-0.05,0.003],[-0.377,0.04],[-0.167,0.032],[0.209,-0.26],[-0.554,-0.433],[-0.904,0.64],[-1.694,0.332],[-2.888,-1.396],[-1.017,-1.094],[-0.566,-2.211],[0.014,-1.23],[-0.241,0.007],[-0.499,-0.018],[0.016,0.237],[0.069,0.652],[0.108,0.691],[0,0],[-6.25,-0.002],[-0.127,-0.141],[-0.03,-0.278],[0.243,-0.048]],"o":[[-0.252,-0.069],[-0.13,-0.167],[-0.022,-0.246],[1.293,0.011],[0.247,0.002],[-0.01,-1.273],[0.002,-0.228],[-0.744,0.014],[-0.364,-0.003],[0.006,-0.264],[0.656,-0.005],[0.643,-0.005],[0.007,-0.216],[-0.734,0.011],[-0.115,-0.001],[-0.195,-0.094],[0.054,-0.271],[0.677,-0.004],[0.632,-0.005],[0.011,-0.262],[-0.734,0.009],[-0.349,-0.003],[0.01,-0.277],[0.058,-0.002],[0.675,0],[0.233,0.005],[-0.008,-0.057],[0.05,-0.298],[-0.723,0.02],[-0.402,-0.005],[0.091,-0.214],[0.686,0.003],[0.545,-0.001],[0.017,-0.303],[-0.733,0.021],[-0.413,-0.005],[0.097,-0.13],[0.684,-0.025],[0.451,0],[0,0],[0.097,-0.008],[0.432,-0.018],[-0.003,-0.355],[-0.01,-0.001],[-0.228,0.032],[0.013,-0.273],[0.002,-1.02],[-1.518,-0.002],[-0.266,0.001],[0.011,-1.215],[0.001,-0.202],[-0.065,0.005],[-0.01,-1.175],[0.003,-0.368],[0.21,-0.091],[0.094,-0.163],[-0.003,-0.019],[0.001,-0.178],[-1.11,0.238],[0.003,1.078],[0.001,0.22],[-0.245,-0.037],[0.012,1.204],[0.005,0.302],[-5.152,-0.009],[-0.936,0.001],[-0.001,0.379],[-0.138,0.009],[-0.351,0.028],[-0.009,0.326],[0.18,0.019],[0.094,0.111],[0.002,0.049],[0.016,0.178],[-0.972,0.163],[0,0],[-0.439,0.224],[-0.364,0.227],[0.092,0.073],[1.006,0.542],[0.991,0.993],[0.079,0.153],[0.587,-0.013],[0.221,0.005],[0.006,-0.626],[0.008,-0.722],[0,0],[0.665,-0.001],[-0.005,0.264],[1.135,-0.022],[1.183,0],[0.231,0.004],[-0.009,-0.714],[-0.011,-0.327],[0.233,0.004],[-0.014,0.596],[0.057,0.891],[1.244,-0.001],[0.273,-0.003],[-0.013,1.058],[0,0.411],[-6.179,0],[-0.554,0.003],[-0.653,-1.394],[-1.177,-1.212],[-1.462,-0.712],[-0.122,-0.017],[-0.624,-0.945],[-0.336,-0.502],[-0.799,-1.04],[-0.45,0.008],[0.232,1.049],[0.196,0.878],[0.041,0.179],[-0.33,0.085],[-1.363,0.466],[-0.278,0.215],[0.023,-0.166],[0.035,-0.494],[-0.618,-0.451],[0,1.008],[0.001,0.053],[0.378,-0.023],[0.087,-0.01],[-0.251,0.311],[0.559,0.437],[0.686,-0.918],[1.407,-0.998],[3.172,-0.622],[1.339,0.647],[1.571,1.688],[0.304,1.186],[-0.002,0.221],[0.499,-0.014],[0.228,0.009],[-0.046,-0.655],[-0.07,-0.657],[0,0],[6.249,0],[0.272,0],[0.146,0.163],[0.024,0.242],[-1.106,0.22]],"v":[[22.506,7.187],[21.773,6.964],[21.719,6.195],[22.032,5.88],[25.911,5.891],[26.223,5.573],[26.224,1.754],[25.929,1.451],[23.696,1.455],[23.144,0.993],[23.694,0.553],[25.664,0.549],[26.223,-0.018],[25.942,-0.308],[23.738,-0.308],[23.395,-0.358],[23.156,-0.845],[23.652,-1.208],[25.68,-1.21],[26.224,-1.757],[25.896,-2.063],[23.692,-2.062],[23.141,-2.535],[23.699,-2.966],[23.876,-2.966],[25.903,-2.962],[26.22,-3.271],[26.22,-3.447],[25.85,-3.826],[23.676,-3.824],[23.181,-4.455],[23.677,-4.748],[25.734,-4.747],[26.227,-5.236],[25.851,-5.609],[23.648,-5.605],[23.216,-6.268],[23.712,-6.496],[25.768,-6.507],[26.22,-6.971],[26.22,-7.471],[26.431,-7.489],[27.148,-8.105],[26.414,-8.694],[26.384,-8.694],[26.108,-8.986],[26.11,-9.809],[24.493,-11.439],[19.94,-11.434],[19.611,-11.772],[19.619,-15.416],[19.339,-15.739],[19.138,-15.936],[19.136,-19.462],[19.667,-20.239],[20.283,-20.505],[20.232,-21.187],[20.228,-21.246],[19.977,-21.429],[18.083,-19.266],[18.086,-16.033],[17.791,-15.727],[17.477,-15.418],[17.49,-11.805],[17.113,-11.433],[1.656,-11.439],[0.087,-9.875],[0.087,-8.713],[-0.261,-8.692],[-0.843,-8.113],[-0.265,-7.49],[0.254,-7.412],[0.296,-6.874],[0.297,-6.727],[0.055,-6.478],[-2.859,-5.962],[-4.349,-5.53],[-5.564,-4.901],[-6.626,-4.107],[-6.488,-3.999],[-3.788,-1.955],[-1.397,1.433],[-1.039,1.664],[0.724,1.663],[1.014,1.375],[1.056,-0.505],[1.058,-2.703],[3.331,-2.703],[3.994,-2.042],[4.336,-1.694],[7.743,-1.72],[11.295,-1.697],[11.568,-1.994],[11.559,-4.136],[11.954,-4.47],[12.358,-4.143],[12.402,-2.353],[13.85,-1.016],[17.583,-1.022],[17.931,-0.67],[17.925,2.504],[17.504,2.915],[-1.037,2.932],[-2.038,2.282],[-4.671,-1.434],[-8.734,-4.322],[-10.748,-5.53],[-11.844,-7.053],[-15.53,-8.77],[-16.616,-10.226],[-19.776,-11.583],[-21.138,-11.405],[-20.468,-8.371],[-19.872,-5.739],[-20.058,-5.368],[-21.03,-5.044],[-24.773,-3.009],[-25.659,-2.307],[-25.615,-2.623],[-26.095,-3.88],[-28.188,-4.339],[-28.182,-1.376],[-28.03,-1.225],[-26.897,-1.33],[-26.558,-1.396],[-27.212,-0.587],[-25.565,0.701],[-23.169,-1.606],[-18.511,-3.589],[-9.424,-2.352],[-5.907,0.297],[-2.771,6.189],[-2.341,9.825],[-2.049,10.132],[-0.551,10.142],[-0.25,9.849],[-0.372,7.885],[-0.677,5.885],[-0.162,5.885],[18.587,5.887],[19.373,5.946],[19.456,6.758],[19.148,7.15]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.282000014361,0.234999997008,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[28.441,21.711],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":36,"ty":4,"nm":"Body Inner Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[31.531,19.277,0],"ix":2},"a":{"a":0,"k":[20.528,7.309,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-0.218,-0.175],[0,0],[0,0],[0,0],[0,0],[0,0],[4.679,1.44]],"o":[[0,0],[0,0],[0,0],[0,0],[0.216,0.175],[0,0],[0,0],[0,0],[0,0],[0,0],[-4.68,-1.44]],"v":[[-20.279,-4.067],[-8.201,-1.906],[0.723,-3.519],[7.318,-7.059],[16.61,-5.058],[18.459,1.058],[19.185,1.406],[20.279,5.544],[19.185,7.059],[-5.48,7.059],[-11.9,-0.832]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.936999990426,0.169000004787,0.149000010771,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[20.528,7.309],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":37,"ty":4,"nm":"Face Light Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[52.842,19.272,0],"ix":2},"a":{"a":0,"k":[1.967,5.302,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.717,5.052],[-1.717,5.052],[-1.717,-5.052],[1.717,-5.052]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.976000019148,0.741000007181,0.741000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.967,5.302],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":38,"ty":4,"nm":"Back Wheel Cover Black Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[13.81,24.179,0],"ix":2},"a":{"a":0,"k":[12.831,7.913,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-12.581,-3.056],[-8.625,0.145],[2.856,-2.465],[7.819,4.492],[9.671,7.652],[12.581,7.663],[12.059,1.58],[7.568,-5.178],[-0.965,-7.663],[-9.441,-5.327]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.4,0.395999983245,0.395999983245,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[12.831,7.914],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":39,"ty":4,"nm":"Back Light Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-0.814,18.853,0],"ix":2},"a":{"a":0,"k":[1.324,1.731,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-2.147,-1.482]],"o":[[0,0],[0,0]],"v":[[1.067,-1.482],[1.074,1.482]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.957000014361,0.804000016755,0.616000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.323,1.732],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":40,"ty":4,"nm":"Driver Head Outlines","parent":42,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3.692,-1.422,0],"ix":2},"a":{"a":0,"k":[2.431,2.553,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-0.417,0.242],[0,0],[0,0],[-1.696,0.048],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.485,-0.146],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[1.697,-0.049],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.485,0.145],[0,0],[0,0],[0,0]],"v":[[-1.289,1.811],[-1.289,-0.266],[-2.182,-0.266],[-1.503,-0.654],[0.049,-2.253],[1.62,-0.799],[2.182,-0.221],[1.62,-0.221],[1.62,0.413],[1.62,0.799],[1.357,0.799],[0.825,2.158],[0.243,2.012],[0.146,2.303],[-0.969,1.867]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.317999985639,0.2,0.165000002992,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[2.431,2.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":41,"ty":4,"nm":"Driver Hand Outlines","parent":42,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[7.378,5.125,0],"ix":2},"a":{"a":0,"k":[3.936,2.259,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-2.279,-2.009],[-0.874,-1.19],[1.161,-1.19],[2.664,-1.599],[2.664,-0.899],[3.246,-0.899],[1.84,0.119],[-1.117,0.119],[-2.508,-1.332],[1.226,0.952],[3.686,-0.528],[1.314,2.009],[-3.686,0.47]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.317999985639,0.2,0.165000002992,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[3.936,2.259],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":42,"ty":4,"nm":"Driver Body Outlines","parent":35,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[16.33,11.297,0],"ix":2},"a":{"a":0,"k":[7.401,8.225,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-2.432,-0.534],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[1.552,-4.945],[0,0],[0,0],[0,0],[-1.745,2.667],[0,0],[2.431,0.533],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-2.593,-0.606],[-3.563,-6.957],[-3.563,-7.344],[-5.406,-7.975],[-5.406,-7.296],[-5.841,-0.606],[-4.201,2.304],[1.43,2.546],[3.223,5.891],[3.999,7.975],[5.745,6.957],[7.15,5.503],[4.581,5.746],[2.788,1.188],[-2.786,-0.267]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.317999985639,0.2,0.165000002992,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[7.4,8.225],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":43,"ty":3,"nm":"Front Particles Ctrl","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[227,170,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":44,"ty":4,"nm":"particle 200","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":135,"s":[100],"e":[0]},{"t":145}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":125,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":145}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":125,"op":146,"st":125,"bm":0},{"ddd":0,"ind":45,"ty":4,"nm":"particle 199","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":133,"s":[100],"e":[0]},{"t":143}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":123,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":143}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":123,"op":144,"st":123,"bm":0},{"ddd":0,"ind":46,"ty":4,"nm":"particle 198","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":132,"s":[100],"e":[0]},{"t":142}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":122,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":142}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":122,"op":143,"st":122,"bm":0},{"ddd":0,"ind":47,"ty":4,"nm":"particle 197","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":130,"s":[100],"e":[0]},{"t":140}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":120,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":140}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":120,"op":141,"st":120,"bm":0},{"ddd":0,"ind":48,"ty":4,"nm":"particle 196","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":131,"s":[100],"e":[0]},{"t":141}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":121,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":141}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":121,"op":142,"st":121,"bm":0},{"ddd":0,"ind":49,"ty":4,"nm":"particle 195","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":128,"s":[100],"e":[0]},{"t":138}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":118,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":138}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":118,"op":139,"st":118,"bm":0},{"ddd":0,"ind":50,"ty":4,"nm":"particle 194","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":126,"s":[100],"e":[0]},{"t":136}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":116,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":136}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":116,"op":137,"st":116,"bm":0},{"ddd":0,"ind":51,"ty":4,"nm":"particle 193","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":125,"s":[100],"e":[0]},{"t":135}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":115,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":135}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":115,"op":136,"st":115,"bm":0},{"ddd":0,"ind":52,"ty":4,"nm":"particle 192","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":123,"s":[100],"e":[0]},{"t":133}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":113,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":133}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":113,"op":134,"st":113,"bm":0},{"ddd":0,"ind":53,"ty":4,"nm":"particle 191","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":124,"s":[100],"e":[0]},{"t":134}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":114,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":134}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":114,"op":135,"st":114,"bm":0},{"ddd":0,"ind":54,"ty":4,"nm":"particle 190","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":121,"s":[100],"e":[0]},{"t":131}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":111,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":131}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":111,"op":132,"st":111,"bm":0},{"ddd":0,"ind":55,"ty":4,"nm":"particle 189","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":119,"s":[100],"e":[0]},{"t":129}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":109,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":129}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":109,"op":130,"st":109,"bm":0},{"ddd":0,"ind":56,"ty":4,"nm":"particle 188","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":118,"s":[100],"e":[0]},{"t":128}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":108,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":128}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":108,"op":129,"st":108,"bm":0},{"ddd":0,"ind":57,"ty":4,"nm":"particle 187","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":116,"s":[100],"e":[0]},{"t":126}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":106,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":126}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":106,"op":127,"st":106,"bm":0},{"ddd":0,"ind":58,"ty":4,"nm":"particle 186","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":117,"s":[100],"e":[0]},{"t":127}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":107,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":127}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":107,"op":128,"st":107,"bm":0},{"ddd":0,"ind":59,"ty":4,"nm":"particle 185","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":115,"s":[100],"e":[0]},{"t":125}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":105,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":125}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":105,"op":126,"st":105,"bm":0},{"ddd":0,"ind":60,"ty":4,"nm":"particle 184","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":114,"s":[100],"e":[0]},{"t":124}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":104,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":124}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":104,"op":125,"st":104,"bm":0},{"ddd":0,"ind":61,"ty":4,"nm":"particle 183","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":112,"s":[100],"e":[0]},{"t":122}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":102,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":122}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":102,"op":123,"st":102,"bm":0},{"ddd":0,"ind":62,"ty":4,"nm":"particle 182","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":111,"s":[100],"e":[0]},{"t":121}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":101,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":121}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":101,"op":122,"st":101,"bm":0},{"ddd":0,"ind":63,"ty":4,"nm":"particle 181","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":109,"s":[100],"e":[0]},{"t":119}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":99,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":119}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":99,"op":120,"st":99,"bm":0},{"ddd":0,"ind":64,"ty":4,"nm":"particle 180","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":108,"s":[100],"e":[0]},{"t":118}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":98,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":118}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":98,"op":119,"st":98,"bm":0},{"ddd":0,"ind":65,"ty":4,"nm":"particle 179","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":106,"s":[100],"e":[0]},{"t":116}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":96,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":116}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":96,"op":117,"st":96,"bm":0},{"ddd":0,"ind":66,"ty":4,"nm":"particle 178","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":107,"s":[100],"e":[0]},{"t":117}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":97,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":117}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":97,"op":118,"st":97,"bm":0},{"ddd":0,"ind":67,"ty":4,"nm":"particle 177","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":105,"s":[100],"e":[0]},{"t":115}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":95,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":115}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":95,"op":116,"st":95,"bm":0},{"ddd":0,"ind":68,"ty":4,"nm":"particle 176","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":104,"s":[100],"e":[0]},{"t":114}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":94,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":114}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":94,"op":115,"st":94,"bm":0},{"ddd":0,"ind":69,"ty":4,"nm":"particle 175","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":102,"s":[100],"e":[0]},{"t":112}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":92,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":112}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":92,"op":113,"st":92,"bm":0},{"ddd":0,"ind":70,"ty":4,"nm":"particle 148","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":100,"s":[100],"e":[0]},{"t":110}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":90,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":110}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":90,"op":111,"st":90,"bm":0},{"ddd":0,"ind":71,"ty":4,"nm":"particle 147","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":98,"s":[100],"e":[0]},{"t":108}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":88,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":108}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":88,"op":109,"st":88,"bm":0},{"ddd":0,"ind":72,"ty":4,"nm":"particle 146","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":97,"s":[100],"e":[0]},{"t":107}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":87,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":107}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":87,"op":108,"st":87,"bm":0},{"ddd":0,"ind":73,"ty":4,"nm":"particle 145","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":95,"s":[100],"e":[0]},{"t":105}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":85,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":105}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":85,"op":106,"st":85,"bm":0},{"ddd":0,"ind":74,"ty":4,"nm":"particle 144","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":96,"s":[100],"e":[0]},{"t":106}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":86,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":106}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":86,"op":107,"st":86,"bm":0},{"ddd":0,"ind":75,"ty":4,"nm":"particle 143","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":93,"s":[100],"e":[0]},{"t":103}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":83,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":103}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":83,"op":104,"st":83,"bm":0},{"ddd":0,"ind":76,"ty":4,"nm":"particle 142","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":91,"s":[100],"e":[0]},{"t":101}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":81,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":101}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":81,"op":102,"st":81,"bm":0},{"ddd":0,"ind":77,"ty":4,"nm":"particle 141","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":90,"s":[100],"e":[0]},{"t":100}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":80,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":100}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":101,"st":80,"bm":0},{"ddd":0,"ind":78,"ty":4,"nm":"particle 140","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":88,"s":[100],"e":[0]},{"t":98}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":78,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":98}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":78,"op":99,"st":78,"bm":0},{"ddd":0,"ind":79,"ty":4,"nm":"particle 139","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":89,"s":[100],"e":[0]},{"t":99}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":79,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":99}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":79,"op":100,"st":79,"bm":0},{"ddd":0,"ind":80,"ty":4,"nm":"particle 138","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":86,"s":[100],"e":[0]},{"t":96}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":76,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":96}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":76,"op":97,"st":76,"bm":0},{"ddd":0,"ind":81,"ty":4,"nm":"particle 137","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":84,"s":[100],"e":[0]},{"t":94}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":74,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":94}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":74,"op":95,"st":74,"bm":0},{"ddd":0,"ind":82,"ty":4,"nm":"particle 136","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":83,"s":[100],"e":[0]},{"t":93}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":73,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":93}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":73,"op":94,"st":73,"bm":0},{"ddd":0,"ind":83,"ty":4,"nm":"particle 135","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":81,"s":[100],"e":[0]},{"t":91}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":71,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":91}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":71,"op":92,"st":71,"bm":0},{"ddd":0,"ind":84,"ty":4,"nm":"particle 134","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":82,"s":[100],"e":[0]},{"t":92}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":72,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":92}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":72,"op":93,"st":72,"bm":0},{"ddd":0,"ind":85,"ty":4,"nm":"particle 133","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":80,"s":[100],"e":[0]},{"t":90}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":70,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":90}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":70,"op":91,"st":70,"bm":0},{"ddd":0,"ind":86,"ty":4,"nm":"particle 132","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":79,"s":[100],"e":[0]},{"t":89}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":69,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":89}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":69,"op":90,"st":69,"bm":0},{"ddd":0,"ind":87,"ty":4,"nm":"particle 131","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":77,"s":[100],"e":[0]},{"t":87}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":67,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":87}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":67,"op":88,"st":67,"bm":0},{"ddd":0,"ind":88,"ty":4,"nm":"particle 130","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":76,"s":[100],"e":[0]},{"t":86}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":66,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":86}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":66,"op":87,"st":66,"bm":0},{"ddd":0,"ind":89,"ty":4,"nm":"particle 129","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":74,"s":[100],"e":[0]},{"t":84}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":64,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":84}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":64,"op":85,"st":64,"bm":0},{"ddd":0,"ind":90,"ty":4,"nm":"particle 128","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":73,"s":[100],"e":[0]},{"t":83}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":63,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":83}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":63,"op":84,"st":63,"bm":0},{"ddd":0,"ind":91,"ty":4,"nm":"particle 127","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":71,"s":[100],"e":[0]},{"t":81}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":61,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":81}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":61,"op":82,"st":61,"bm":0},{"ddd":0,"ind":92,"ty":4,"nm":"particle 126","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":72,"s":[100],"e":[0]},{"t":82}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":62,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":82}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":62,"op":83,"st":62,"bm":0},{"ddd":0,"ind":93,"ty":4,"nm":"particle 125","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":70,"s":[100],"e":[0]},{"t":80}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":60,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":80}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":60,"op":81,"st":60,"bm":0},{"ddd":0,"ind":94,"ty":4,"nm":"particle 124","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":69,"s":[100],"e":[0]},{"t":79}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":59,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":79}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":59,"op":80,"st":59,"bm":0},{"ddd":0,"ind":95,"ty":4,"nm":"particle 123","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":67,"s":[100],"e":[0]},{"t":77}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":57,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":77}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":57,"op":78,"st":57,"bm":0},{"ddd":0,"ind":96,"ty":4,"nm":"particle 122","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":68,"s":[100],"e":[0]},{"t":78}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":58,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":78}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":58,"op":79,"st":58,"bm":0},{"ddd":0,"ind":97,"ty":4,"nm":"particle 121","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":66,"s":[100],"e":[0]},{"t":76}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":56,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":76}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":56,"op":77,"st":56,"bm":0},{"ddd":0,"ind":98,"ty":4,"nm":"particle 120","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":65,"s":[100],"e":[0]},{"t":75}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":55,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":75}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":55,"op":76,"st":55,"bm":0},{"ddd":0,"ind":99,"ty":4,"nm":"particle 119","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":63,"s":[100],"e":[0]},{"t":73}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":53,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":73}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":53,"op":74,"st":53,"bm":0},{"ddd":0,"ind":100,"ty":4,"nm":"particle 118","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":64,"s":[100],"e":[0]},{"t":74}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":54,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":74}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":54,"op":75,"st":54,"bm":0},{"ddd":0,"ind":101,"ty":4,"nm":"particle 117","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":62,"s":[100],"e":[0]},{"t":72}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":52,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":72}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":52,"op":73,"st":52,"bm":0},{"ddd":0,"ind":102,"ty":4,"nm":"particle 116","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":61,"s":[100],"e":[0]},{"t":71}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":51,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":71}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":51,"op":72,"st":51,"bm":0},{"ddd":0,"ind":103,"ty":4,"nm":"particle 115","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":59,"s":[100],"e":[0]},{"t":69}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":49,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":69}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":49,"op":70,"st":49,"bm":0},{"ddd":0,"ind":104,"ty":4,"nm":"particle 114","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":58,"s":[100],"e":[0]},{"t":68}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":48,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":68}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":48,"op":69,"st":48,"bm":0},{"ddd":0,"ind":105,"ty":4,"nm":"particle 113","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[100],"e":[0]},{"t":66}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":46,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":66}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":46,"op":67,"st":46,"bm":0},{"ddd":0,"ind":106,"ty":4,"nm":"particle 112","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":55,"s":[100],"e":[0]},{"t":65}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":45,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":65}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":45,"op":66,"st":45,"bm":0},{"ddd":0,"ind":107,"ty":4,"nm":"particle 111","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":53,"s":[100],"e":[0]},{"t":63}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":43,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":63}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":43,"op":64,"st":43,"bm":0},{"ddd":0,"ind":108,"ty":4,"nm":"particle 110","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":54,"s":[100],"e":[0]},{"t":64}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":44,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":64}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":44,"op":65,"st":44,"bm":0},{"ddd":0,"ind":109,"ty":4,"nm":"particle 109","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":52,"s":[100],"e":[0]},{"t":62}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":62}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":42,"op":63,"st":42,"bm":0},{"ddd":0,"ind":110,"ty":4,"nm":"particle 108","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":51,"s":[100],"e":[0]},{"t":61}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":41,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":61}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":41,"op":62,"st":41,"bm":0},{"ddd":0,"ind":111,"ty":4,"nm":"particle 107","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":49,"s":[100],"e":[0]},{"t":59}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":39,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":59}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":39,"op":60,"st":39,"bm":0},{"ddd":0,"ind":112,"ty":4,"nm":"particle 106","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":47,"s":[100],"e":[0]},{"t":57}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":37,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":57}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":37,"op":58,"st":37,"bm":0},{"ddd":0,"ind":113,"ty":4,"nm":"particle 105","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":45,"s":[100],"e":[0]},{"t":55}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":35,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":55}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":35,"op":56,"st":35,"bm":0},{"ddd":0,"ind":114,"ty":4,"nm":"particle 104","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[100],"e":[0]},{"t":54}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":34,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":54}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":34,"op":55,"st":34,"bm":0},{"ddd":0,"ind":115,"ty":4,"nm":"particle 103","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":42,"s":[100],"e":[0]},{"t":52}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":32,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":52}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":32,"op":53,"st":32,"bm":0},{"ddd":0,"ind":116,"ty":4,"nm":"particle 102","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":43,"s":[100],"e":[0]},{"t":53}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":33,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":53}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":33,"op":54,"st":33,"bm":0},{"ddd":0,"ind":117,"ty":4,"nm":"particle 101","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":41,"s":[100],"e":[0]},{"t":51}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":31,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":51}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":31,"op":52,"st":31,"bm":0},{"ddd":0,"ind":118,"ty":4,"nm":"particle 100","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":40,"s":[100],"e":[0]},{"t":50}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":30,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":50}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":51,"st":30,"bm":0},{"ddd":0,"ind":119,"ty":4,"nm":"particle 99","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":38,"s":[100],"e":[0]},{"t":48}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":28,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":48}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":28,"op":49,"st":28,"bm":0},{"ddd":0,"ind":120,"ty":4,"nm":"particle 98","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":37,"s":[100],"e":[0]},{"t":47}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":27,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":47}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":27,"op":48,"st":27,"bm":0},{"ddd":0,"ind":121,"ty":4,"nm":"particle 97","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[100],"e":[0]},{"t":45}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":25,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":45}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":25,"op":46,"st":25,"bm":0},{"ddd":0,"ind":122,"ty":4,"nm":"particle 96","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":34,"s":[100],"e":[0]},{"t":44}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":24,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":44}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":24,"op":45,"st":24,"bm":0},{"ddd":0,"ind":123,"ty":4,"nm":"particle 95","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":32,"s":[100],"e":[0]},{"t":42}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":42}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":22,"op":43,"st":22,"bm":0},{"ddd":0,"ind":124,"ty":4,"nm":"particle 94","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":33,"s":[100],"e":[0]},{"t":43}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":23,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":43}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":23,"op":44,"st":23,"bm":0},{"ddd":0,"ind":125,"ty":4,"nm":"particle 93","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":31,"s":[100],"e":[0]},{"t":41}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":21,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":41}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":21,"op":42,"st":21,"bm":0},{"ddd":0,"ind":126,"ty":4,"nm":"particle 92","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":30,"s":[100],"e":[0]},{"t":40}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":40}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":20,"op":41,"st":20,"bm":0},{"ddd":0,"ind":127,"ty":4,"nm":"particle 91","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":28,"s":[100],"e":[0]},{"t":38}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":18,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":38}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":18,"op":39,"st":18,"bm":0},{"ddd":0,"ind":128,"ty":4,"nm":"particle 90","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":29,"s":[100],"e":[0]},{"t":39}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":19,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":39}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":19,"op":40,"st":19,"bm":0},{"ddd":0,"ind":129,"ty":4,"nm":"particle 89","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[100],"e":[0]},{"t":37}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":37}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":17,"op":38,"st":17,"bm":0},{"ddd":0,"ind":130,"ty":4,"nm":"particle 88","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":26,"s":[100],"e":[0]},{"t":36}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":16,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":36}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":16,"op":37,"st":16,"bm":0},{"ddd":0,"ind":131,"ty":4,"nm":"particle 87","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":24,"s":[100],"e":[0]},{"t":34}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":14,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":34}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":14,"op":35,"st":14,"bm":0},{"ddd":0,"ind":132,"ty":4,"nm":"particle 86","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":25,"s":[100],"e":[0]},{"t":35}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":15,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":35}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":15,"op":36,"st":15,"bm":0},{"ddd":0,"ind":133,"ty":4,"nm":"particle 85","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":23,"s":[100],"e":[0]},{"t":33}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":13,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":33}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":13,"op":34,"st":13,"bm":0},{"ddd":0,"ind":134,"ty":4,"nm":"particle 84","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":22,"s":[100],"e":[0]},{"t":32}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":12,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":32}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":12,"op":33,"st":12,"bm":0},{"ddd":0,"ind":135,"ty":4,"nm":"particle 83","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[100],"e":[0]},{"t":30}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":10,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":30}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":10,"op":31,"st":10,"bm":0},{"ddd":0,"ind":136,"ty":4,"nm":"particle 82","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":19,"s":[100],"e":[0]},{"t":29}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":9,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":29}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":9,"op":30,"st":9,"bm":0},{"ddd":0,"ind":137,"ty":4,"nm":"particle 81","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":17,"s":[100],"e":[0]},{"t":27}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":7,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":27}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":7,"op":28,"st":7,"bm":0},{"ddd":0,"ind":138,"ty":4,"nm":"particle 80","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":16,"s":[100],"e":[0]},{"t":26}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":6,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":26}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":6,"op":27,"st":6,"bm":0},{"ddd":0,"ind":139,"ty":4,"nm":"particle 79","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":14,"s":[100],"e":[0]},{"t":24}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":4,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":24}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":4,"op":25,"st":4,"bm":0},{"ddd":0,"ind":140,"ty":4,"nm":"particle 78","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[100],"e":[0]},{"t":25}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":5,"s":[-7,-4,0],"e":[-27,-4,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":25}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":5,"op":26,"st":5,"bm":0},{"ddd":0,"ind":141,"ty":4,"nm":"particle 77","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":13,"s":[100],"e":[0]},{"t":23}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":3,"s":[-7,-2,0],"e":[-27,-2,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":23}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":3,"op":24,"st":3,"bm":0},{"ddd":0,"ind":142,"ty":4,"nm":"particle 76","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":12,"s":[100],"e":[0]},{"t":22}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":2,"s":[-6,-8,0],"e":[-26,-8,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":22}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2,"op":23,"st":2,"bm":0},{"ddd":0,"ind":143,"ty":4,"nm":"particle 75","parent":43,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":10,"s":[100],"e":[0]},{"t":20}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[0,0,0],"e":[-20,0,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":20}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":21,"st":0,"bm":0},{"ddd":0,"ind":144,"ty":4,"nm":"particle 174","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":135,"s":[100],"e":[0]},{"t":145}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":125,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":145}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":125,"op":146,"st":125,"bm":0},{"ddd":0,"ind":145,"ty":4,"nm":"particle 173","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":133,"s":[100],"e":[0]},{"t":143}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":123,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":143}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":123,"op":144,"st":123,"bm":0},{"ddd":0,"ind":146,"ty":4,"nm":"particle 172","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":132,"s":[100],"e":[0]},{"t":142}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":122,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":142}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":122,"op":143,"st":122,"bm":0},{"ddd":0,"ind":147,"ty":4,"nm":"particle 171","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":130,"s":[100],"e":[0]},{"t":140}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":120,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":140}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":120,"op":141,"st":120,"bm":0},{"ddd":0,"ind":148,"ty":4,"nm":"particle 170","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":131,"s":[100],"e":[0]},{"t":141}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":121,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":141}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":121,"op":142,"st":121,"bm":0},{"ddd":0,"ind":149,"ty":4,"nm":"particle 169","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":128,"s":[100],"e":[0]},{"t":138}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":118,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":138}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":118,"op":139,"st":118,"bm":0},{"ddd":0,"ind":150,"ty":4,"nm":"particle 168","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":126,"s":[100],"e":[0]},{"t":136}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":116,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":136}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":116,"op":137,"st":116,"bm":0},{"ddd":0,"ind":151,"ty":4,"nm":"particle 167","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":125,"s":[100],"e":[0]},{"t":135}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":115,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":135}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":115,"op":136,"st":115,"bm":0},{"ddd":0,"ind":152,"ty":4,"nm":"particle 166","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":123,"s":[100],"e":[0]},{"t":133}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":113,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":133}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":113,"op":134,"st":113,"bm":0},{"ddd":0,"ind":153,"ty":4,"nm":"particle 165","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":124,"s":[100],"e":[0]},{"t":134}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":114,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":134}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":114,"op":135,"st":114,"bm":0},{"ddd":0,"ind":154,"ty":4,"nm":"particle 164","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":121,"s":[100],"e":[0]},{"t":131}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":111,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":131}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":111,"op":132,"st":111,"bm":0},{"ddd":0,"ind":155,"ty":4,"nm":"particle 163","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":119,"s":[100],"e":[0]},{"t":129}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":109,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":129}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":109,"op":130,"st":109,"bm":0},{"ddd":0,"ind":156,"ty":4,"nm":"particle 162","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":118,"s":[100],"e":[0]},{"t":128}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":108,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":128}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":108,"op":129,"st":108,"bm":0},{"ddd":0,"ind":157,"ty":4,"nm":"particle 161","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":116,"s":[100],"e":[0]},{"t":126}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":106,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":126}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":106,"op":127,"st":106,"bm":0},{"ddd":0,"ind":158,"ty":4,"nm":"particle 160","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":117,"s":[100],"e":[0]},{"t":127}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":107,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":127}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":107,"op":128,"st":107,"bm":0},{"ddd":0,"ind":159,"ty":4,"nm":"particle 159","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":115,"s":[100],"e":[0]},{"t":125}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":105,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":125}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":105,"op":126,"st":105,"bm":0},{"ddd":0,"ind":160,"ty":4,"nm":"particle 158","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":114,"s":[100],"e":[0]},{"t":124}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":104,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":124}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":104,"op":125,"st":104,"bm":0},{"ddd":0,"ind":161,"ty":4,"nm":"particle 157","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":112,"s":[100],"e":[0]},{"t":122}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":102,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":122}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":102,"op":123,"st":102,"bm":0},{"ddd":0,"ind":162,"ty":4,"nm":"particle 156","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":111,"s":[100],"e":[0]},{"t":121}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":101,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":121}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":101,"op":122,"st":101,"bm":0},{"ddd":0,"ind":163,"ty":4,"nm":"particle 155","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":109,"s":[100],"e":[0]},{"t":119}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":99,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":119}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":99,"op":120,"st":99,"bm":0},{"ddd":0,"ind":164,"ty":4,"nm":"particle 154","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":108,"s":[100],"e":[0]},{"t":118}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":98,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":118}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":98,"op":119,"st":98,"bm":0},{"ddd":0,"ind":165,"ty":4,"nm":"particle 153","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":106,"s":[100],"e":[0]},{"t":116}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":96,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":116}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":96,"op":117,"st":96,"bm":0},{"ddd":0,"ind":166,"ty":4,"nm":"particle 152","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":107,"s":[100],"e":[0]},{"t":117}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":97,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":117}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":97,"op":118,"st":97,"bm":0},{"ddd":0,"ind":167,"ty":4,"nm":"particle 151","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":105,"s":[100],"e":[0]},{"t":115}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":95,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":115}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":95,"op":116,"st":95,"bm":0},{"ddd":0,"ind":168,"ty":4,"nm":"particle 150","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":104,"s":[100],"e":[0]},{"t":114}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":94,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":114}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":94,"op":115,"st":94,"bm":0},{"ddd":0,"ind":169,"ty":4,"nm":"particle 149","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":102,"s":[100],"e":[0]},{"t":112}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":92,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":112}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":92,"op":113,"st":92,"bm":0},{"ddd":0,"ind":170,"ty":4,"nm":"particle 74","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":100,"s":[100],"e":[0]},{"t":110}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":90,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":110}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":90,"op":111,"st":90,"bm":0},{"ddd":0,"ind":171,"ty":4,"nm":"particle 73","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":98,"s":[100],"e":[0]},{"t":108}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":88,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":108}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":88,"op":109,"st":88,"bm":0},{"ddd":0,"ind":172,"ty":4,"nm":"particle 72","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":97,"s":[100],"e":[0]},{"t":107}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":87,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":107}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":87,"op":108,"st":87,"bm":0},{"ddd":0,"ind":173,"ty":4,"nm":"particle 71","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":95,"s":[100],"e":[0]},{"t":105}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":85,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":105}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":85,"op":106,"st":85,"bm":0},{"ddd":0,"ind":174,"ty":4,"nm":"particle 70","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":96,"s":[100],"e":[0]},{"t":106}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":86,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":106}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":86,"op":107,"st":86,"bm":0},{"ddd":0,"ind":175,"ty":4,"nm":"particle 69","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":93,"s":[100],"e":[0]},{"t":103}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":83,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":103}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":83,"op":104,"st":83,"bm":0},{"ddd":0,"ind":176,"ty":4,"nm":"particle 68","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":91,"s":[100],"e":[0]},{"t":101}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":81,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":101}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":81,"op":102,"st":81,"bm":0},{"ddd":0,"ind":177,"ty":4,"nm":"particle 67","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":90,"s":[100],"e":[0]},{"t":100}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":80,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":100}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":80,"op":101,"st":80,"bm":0},{"ddd":0,"ind":178,"ty":4,"nm":"particle 66","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":88,"s":[100],"e":[0]},{"t":98}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":78,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":98}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":78,"op":99,"st":78,"bm":0},{"ddd":0,"ind":179,"ty":4,"nm":"particle 65","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":89,"s":[100],"e":[0]},{"t":99}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":79,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":99}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":79,"op":100,"st":79,"bm":0},{"ddd":0,"ind":180,"ty":4,"nm":"particle 64","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":86,"s":[100],"e":[0]},{"t":96}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":76,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":96}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":76,"op":97,"st":76,"bm":0},{"ddd":0,"ind":181,"ty":4,"nm":"particle 63","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":84,"s":[100],"e":[0]},{"t":94}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":74,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":94}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":74,"op":95,"st":74,"bm":0},{"ddd":0,"ind":182,"ty":4,"nm":"particle 62","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":83,"s":[100],"e":[0]},{"t":93}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":73,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":93}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":73,"op":94,"st":73,"bm":0},{"ddd":0,"ind":183,"ty":4,"nm":"particle 61","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":81,"s":[100],"e":[0]},{"t":91}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":71,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":91}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":71,"op":92,"st":71,"bm":0},{"ddd":0,"ind":184,"ty":4,"nm":"particle 60","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":82,"s":[100],"e":[0]},{"t":92}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":72,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":92}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":72,"op":93,"st":72,"bm":0},{"ddd":0,"ind":185,"ty":4,"nm":"particle 59","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":80,"s":[100],"e":[0]},{"t":90}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":70,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":90}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":70,"op":91,"st":70,"bm":0},{"ddd":0,"ind":186,"ty":4,"nm":"particle 58","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":79,"s":[100],"e":[0]},{"t":89}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":69,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":89}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":69,"op":90,"st":69,"bm":0},{"ddd":0,"ind":187,"ty":4,"nm":"particle 57","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":77,"s":[100],"e":[0]},{"t":87}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":67,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":87}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":67,"op":88,"st":67,"bm":0},{"ddd":0,"ind":188,"ty":4,"nm":"particle 56","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":76,"s":[100],"e":[0]},{"t":86}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":66,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":86}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":66,"op":87,"st":66,"bm":0},{"ddd":0,"ind":189,"ty":4,"nm":"particle 55","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":74,"s":[100],"e":[0]},{"t":84}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":64,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":84}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":64,"op":85,"st":64,"bm":0},{"ddd":0,"ind":190,"ty":4,"nm":"particle 54","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":73,"s":[100],"e":[0]},{"t":83}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":63,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":83}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":63,"op":84,"st":63,"bm":0},{"ddd":0,"ind":191,"ty":4,"nm":"particle 53","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":71,"s":[100],"e":[0]},{"t":81}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":61,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":81}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":61,"op":82,"st":61,"bm":0},{"ddd":0,"ind":192,"ty":4,"nm":"particle 52","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":72,"s":[100],"e":[0]},{"t":82}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":62,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":82}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":62,"op":83,"st":62,"bm":0},{"ddd":0,"ind":193,"ty":4,"nm":"particle 51","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":70,"s":[100],"e":[0]},{"t":80}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":60,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":80}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":60,"op":81,"st":60,"bm":0},{"ddd":0,"ind":194,"ty":4,"nm":"particle 50","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":69,"s":[100],"e":[0]},{"t":79}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":59,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":79}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":59,"op":80,"st":59,"bm":0},{"ddd":0,"ind":195,"ty":4,"nm":"particle 49","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":67,"s":[100],"e":[0]},{"t":77}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":57,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":77}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":57,"op":78,"st":57,"bm":0},{"ddd":0,"ind":196,"ty":4,"nm":"particle 48","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":68,"s":[100],"e":[0]},{"t":78}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":58,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":78}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":58,"op":79,"st":58,"bm":0},{"ddd":0,"ind":197,"ty":4,"nm":"particle 47","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":66,"s":[100],"e":[0]},{"t":76}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":56,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":76}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":56,"op":77,"st":56,"bm":0},{"ddd":0,"ind":198,"ty":4,"nm":"particle 46","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":65,"s":[100],"e":[0]},{"t":75}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":55,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":75}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":55,"op":76,"st":55,"bm":0},{"ddd":0,"ind":199,"ty":4,"nm":"particle 45","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":63,"s":[100],"e":[0]},{"t":73}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":53,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":73}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":53,"op":74,"st":53,"bm":0},{"ddd":0,"ind":200,"ty":4,"nm":"particle 44","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":64,"s":[100],"e":[0]},{"t":74}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":54,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":74}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":54,"op":75,"st":54,"bm":0},{"ddd":0,"ind":201,"ty":4,"nm":"particle 43","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":62,"s":[100],"e":[0]},{"t":72}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":52,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":72}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":52,"op":73,"st":52,"bm":0},{"ddd":0,"ind":202,"ty":4,"nm":"particle 42","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":61,"s":[100],"e":[0]},{"t":71}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":51,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":71}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":51,"op":72,"st":51,"bm":0},{"ddd":0,"ind":203,"ty":4,"nm":"particle 41","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":59,"s":[100],"e":[0]},{"t":69}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":49,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":69}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":49,"op":70,"st":49,"bm":0},{"ddd":0,"ind":204,"ty":4,"nm":"particle 40","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":58,"s":[100],"e":[0]},{"t":68}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":48,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":68}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":48,"op":69,"st":48,"bm":0},{"ddd":0,"ind":205,"ty":4,"nm":"particle 39","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":56,"s":[100],"e":[0]},{"t":66}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":46,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":66}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":46,"op":67,"st":46,"bm":0},{"ddd":0,"ind":206,"ty":4,"nm":"particle 38","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":55,"s":[100],"e":[0]},{"t":65}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":45,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":65}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":45,"op":66,"st":45,"bm":0},{"ddd":0,"ind":207,"ty":4,"nm":"particle 37","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":53,"s":[100],"e":[0]},{"t":63}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":43,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":63}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":43,"op":64,"st":43,"bm":0},{"ddd":0,"ind":208,"ty":4,"nm":"particle 36","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":54,"s":[100],"e":[0]},{"t":64}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":44,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":64}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":44,"op":65,"st":44,"bm":0},{"ddd":0,"ind":209,"ty":4,"nm":"particle 35","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":52,"s":[100],"e":[0]},{"t":62}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":42,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":62}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":42,"op":63,"st":42,"bm":0},{"ddd":0,"ind":210,"ty":4,"nm":"particle 34","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":51,"s":[100],"e":[0]},{"t":61}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":41,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":61}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":41,"op":62,"st":41,"bm":0},{"ddd":0,"ind":211,"ty":4,"nm":"particle 33","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":49,"s":[100],"e":[0]},{"t":59}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":39,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":59}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":39,"op":60,"st":39,"bm":0},{"ddd":0,"ind":212,"ty":4,"nm":"particle 32","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":47,"s":[100],"e":[0]},{"t":57}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":37,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":57}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":37,"op":58,"st":37,"bm":0},{"ddd":0,"ind":213,"ty":4,"nm":"particle 31","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":45,"s":[100],"e":[0]},{"t":55}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":35,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":55}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":35,"op":56,"st":35,"bm":0},{"ddd":0,"ind":214,"ty":4,"nm":"particle 30","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[100],"e":[0]},{"t":54}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":34,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":54}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":34,"op":55,"st":34,"bm":0},{"ddd":0,"ind":215,"ty":4,"nm":"particle 29","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":42,"s":[100],"e":[0]},{"t":52}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":32,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":52}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":32,"op":53,"st":32,"bm":0},{"ddd":0,"ind":216,"ty":4,"nm":"particle 28","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":43,"s":[100],"e":[0]},{"t":53}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":33,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":53}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":33,"op":54,"st":33,"bm":0},{"ddd":0,"ind":217,"ty":4,"nm":"particle 27","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":41,"s":[100],"e":[0]},{"t":51}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":31,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":51}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":31,"op":52,"st":31,"bm":0},{"ddd":0,"ind":218,"ty":4,"nm":"particle 26","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":40,"s":[100],"e":[0]},{"t":50}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":30,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":50}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":51,"st":30,"bm":0},{"ddd":0,"ind":219,"ty":4,"nm":"particle 25","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":38,"s":[100],"e":[0]},{"t":48}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":28,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":48}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":28,"op":49,"st":28,"bm":0},{"ddd":0,"ind":220,"ty":4,"nm":"particle 24","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":37,"s":[100],"e":[0]},{"t":47}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":27,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":47}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":27,"op":48,"st":27,"bm":0},{"ddd":0,"ind":221,"ty":4,"nm":"particle 23","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[100],"e":[0]},{"t":45}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":25,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":45}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":25,"op":46,"st":25,"bm":0},{"ddd":0,"ind":222,"ty":4,"nm":"particle 22","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":34,"s":[100],"e":[0]},{"t":44}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":24,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":44}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":24,"op":45,"st":24,"bm":0},{"ddd":0,"ind":223,"ty":4,"nm":"particle 21","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":32,"s":[100],"e":[0]},{"t":42}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":22,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":42}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":22,"op":43,"st":22,"bm":0},{"ddd":0,"ind":224,"ty":4,"nm":"particle 20","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":33,"s":[100],"e":[0]},{"t":43}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":23,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":43}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":23,"op":44,"st":23,"bm":0},{"ddd":0,"ind":225,"ty":4,"nm":"particle 19","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":31,"s":[100],"e":[0]},{"t":41}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":21,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":41}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":21,"op":42,"st":21,"bm":0},{"ddd":0,"ind":226,"ty":4,"nm":"particle 18","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":30,"s":[100],"e":[0]},{"t":40}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":20,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":40}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":20,"op":41,"st":20,"bm":0},{"ddd":0,"ind":227,"ty":4,"nm":"particle 17","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":28,"s":[100],"e":[0]},{"t":38}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":18,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":38}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":18,"op":39,"st":18,"bm":0},{"ddd":0,"ind":228,"ty":4,"nm":"particle 16","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":29,"s":[100],"e":[0]},{"t":39}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":19,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":39}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":19,"op":40,"st":19,"bm":0},{"ddd":0,"ind":229,"ty":4,"nm":"particle 15","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[100],"e":[0]},{"t":37}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":37}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":17,"op":38,"st":17,"bm":0},{"ddd":0,"ind":230,"ty":4,"nm":"particle 14","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":26,"s":[100],"e":[0]},{"t":36}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":16,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":36}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":16,"op":37,"st":16,"bm":0},{"ddd":0,"ind":231,"ty":4,"nm":"particle 13","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":24,"s":[100],"e":[0]},{"t":34}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":14,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":34}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":14,"op":35,"st":14,"bm":0},{"ddd":0,"ind":232,"ty":4,"nm":"particle 12","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":25,"s":[100],"e":[0]},{"t":35}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":15,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":35}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":15,"op":36,"st":15,"bm":0},{"ddd":0,"ind":233,"ty":4,"nm":"particle 11","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":23,"s":[100],"e":[0]},{"t":33}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":13,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":33}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":13,"op":34,"st":13,"bm":0},{"ddd":0,"ind":234,"ty":4,"nm":"particle 10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":22,"s":[100],"e":[0]},{"t":32}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":12,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":32}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":12,"op":33,"st":12,"bm":0},{"ddd":0,"ind":235,"ty":4,"nm":"particle 9","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":20,"s":[100],"e":[0]},{"t":30}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":10,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":30}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":10,"op":31,"st":10,"bm":0},{"ddd":0,"ind":236,"ty":4,"nm":"particle 8","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":19,"s":[100],"e":[0]},{"t":29}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":9,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":29}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":9,"op":30,"st":9,"bm":0},{"ddd":0,"ind":237,"ty":4,"nm":"particle 7","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":17,"s":[100],"e":[0]},{"t":27}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":7,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":27}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":7,"op":28,"st":7,"bm":0},{"ddd":0,"ind":238,"ty":4,"nm":"particle 6","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":16,"s":[100],"e":[0]},{"t":26}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":6,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":26}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":6,"op":27,"st":6,"bm":0},{"ddd":0,"ind":239,"ty":4,"nm":"particle 5","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":14,"s":[100],"e":[0]},{"t":24}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":4,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":24}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":4,"op":25,"st":4,"bm":0},{"ddd":0,"ind":240,"ty":4,"nm":"particle 4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[100],"e":[0]},{"t":25}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":5,"s":[193,151,0],"e":[173,151,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":25}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":5,"op":26,"st":5,"bm":0},{"ddd":0,"ind":241,"ty":4,"nm":"particle 3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":13,"s":[100],"e":[0]},{"t":23}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":3,"s":[193,153,0],"e":[173,153,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":23}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":3,"op":24,"st":3,"bm":0},{"ddd":0,"ind":242,"ty":4,"nm":"particle 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":12,"s":[100],"e":[0]},{"t":22}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":2,"s":[194,147,0],"e":[174,147,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":22}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2,"op":23,"st":2,"bm":0},{"ddd":0,"ind":243,"ty":4,"nm":"particle","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":10,"s":[100],"e":[0]},{"t":20}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[200,155,0],"e":[180,155,0],"to":[-0.58333331346512,-14,0],"ti":[3.58333325386047,-16,0]},{"t":20}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[2,2],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458823531866,0.349019616842,0.247058823705,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-20,28.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":21,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"matte 3","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200.235,155.416,0],"ix":2},"a":{"a":0,"k":[159.625,99.679,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[159.375,99.43],[-159.375,99.43],[-159.375,-99.43],[159.375,-99.43]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.987999949736,0.898000021542,0.773000021542,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[159.625,99.679],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":284,"op":427,"st":284,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"Tractor","tt":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":284,"s":[-8],"e":[-5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":341.404,"s":[-5],"e":[7]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":348.957,"s":[7],"e":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":364.063,"s":[3],"e":[-1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":379.17,"s":[-1],"e":[-5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":391.255,"s":[-5],"e":[-12]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":400.319,"s":[-12],"e":[-6]},{"t":418.447265625}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":284,"s":[-151.709],"e":[252.291]},{"t":426}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":284,"s":[284.709],"e":[271.709]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":320.255,"s":[271.709],"e":[262.709]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":341.404,"s":[262.709],"e":[232.709]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":348.957,"s":[232.709],"e":[247.709]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":364.063,"s":[247.709],"e":[262.709]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":379.17,"s":[262.709],"e":[271.209]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":391.255,"s":[271.209],"e":[286.209]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":400.319,"s":[286.209],"e":[268.209]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":413.915,"s":[268.209],"e":[257.209]},{"t":418.447265625}],"ix":4}},"a":{"a":0,"k":[84.07,197.084,0],"ix":1},"s":{"a":0,"k":[130,130,100],"ix":6}},"ao":0,"w":400,"h":310,"ip":284,"op":427,"st":284,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"matte 2","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200.235,155.416,0],"ix":2},"a":{"a":0,"k":[159.625,99.679,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[159.375,99.43],[-159.375,99.43],[-159.375,-99.43],[159.375,-99.43]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.987999949736,0.898000021542,0.773000021542,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[159.625,99.679],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":142,"op":285,"st":142,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"Tractor","tt":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":152.574,"s":[2],"e":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":161.639,"s":[1],"e":[-10.952]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":167.681,"s":[-10.952],"e":[-10]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":175.234,"s":[-10],"e":[-3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":182.787,"s":[-3],"e":[-2.895]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":219.043,"s":[-2.895],"e":[-6]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":240.191,"s":[-6],"e":[-7]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":249.255,"s":[-7],"e":[-8]},{"t":284}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":142,"s":[521.291],"e":[108.291]},{"t":284}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.486],"y":[0.936]},"o":{"x":[0.017],"y":[-0.006]},"n":["0p486_0p936_0p017_-0p006"],"t":161.639,"s":[214.709],"e":[189.887]},{"i":{"x":[0.673],"y":[1.24]},"o":{"x":[0.332],"y":[-0.185]},"n":["0p673_1p24_0p332_-0p185"],"t":167.681,"s":[189.887],"e":[196.785]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[-0.047]},"n":["0p833_1_0p167_-0p047"],"t":175.234,"s":[196.785],"e":[214.785]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":182.787,"s":[214.785],"e":[218.785]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":199.404,"s":[218.785],"e":[219.285]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":228.106,"s":[219.285],"e":[216.785]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":240.191,"s":[216.785],"e":[218.785]},{"i":{"x":[0.596],"y":[0.694]},"o":{"x":[0.163],"y":[0]},"n":["0p596_0p694_0p163_0"],"t":249.255,"s":[218.785],"e":[226.676]},{"t":284}],"ix":4}},"a":{"a":0,"k":[84.07,197.084,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"w":400,"h":310,"ip":142,"op":285,"st":142,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"matte","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200.235,155.416,0],"ix":2},"a":{"a":0,"k":[159.625,99.679,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[159.375,99.43],[-159.375,99.43],[-159.375,-99.43],[159.375,-99.43]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.987999949736,0.898000021542,0.773000021542,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[159.625,99.679],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"Tractor","tt":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":19.639,"s":[0],"e":[-4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":51.361,"s":[-4],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":64.915,"s":[0],"e":[1]},{"t":107.5146484375}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[-81.709],"e":[291.291]},{"t":142}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.984],"y":[1.174]},"o":{"x":[0.016],"y":[0.174]},"n":["0p984_1p174_0p016_0p174"],"t":19.639,"s":[194.709],"e":[198.709]},{"i":{"x":[0.966],"y":[0.841]},"o":{"x":[0.034],"y":[0.08]},"n":["0p966_0p841_0p034_0p08"],"t":51.361,"s":[198.709],"e":[190.709]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0],"y":[0]},"n":["0p833_1_0_0"],"t":64.915,"s":[190.709],"e":[192.709]},{"t":119.685546875}],"ix":4}},"a":{"a":0,"k":[84.07,197.084,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":310,"ip":0,"op":143,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Cloud 4 Outlines","sr":1,"ks":{"o":{"a":0,"k":53,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[329.596,137.146,0],"ix":2},"a":{"a":0,"k":[30.206,5.341,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-10,4.659],[-1.334,-0.341],[-7.921,-8.999],[0,0]],"o":[[0,0],[10,-4.66],[1.333,0.34],[0,0],[0,0]],"v":[[-30.207,3.854],[-11.54,-2.153],[7.127,-2.153],[30.206,-1.146],[30.206,5.341]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[30.206,5.341],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":427,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Cloud 3 Outlines","sr":1,"ks":{"o":{"a":0,"k":52,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[268.783,90.652,0],"ix":2},"a":{"a":0,"k":[84.003,12.222,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.003,0.005],[-8.101,1.603],[-6.328,1.682],[-7.071,1.057],[-13.586,3.264],[-3.685,1.116],[-13.401,-4.884],[-9.333,0]],"o":[[4.506,-6.796],[6.536,-1.294],[6.669,-1.772],[13.806,-2.053],[3.743,-0.899],[15.499,-4.694],[9.374,3.415],[-0.01,0]],"v":[[-84.003,11.935],[-63.714,-2.419],[-44.506,-2.117],[-26.836,-12.075],[6.28,2.766],[17.099,-1.228],[57.435,9.92],[84.003,11.94]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[84.003,12.222],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":427,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Cloud 2 Outlines","sr":1,"ks":{"o":{"a":0,"k":45,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100.443,84.782,0],"ix":2},"a":{"a":0,"k":[25.947,5.87,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.521,-2],[-6.836,-6.333],[-11.393,-9.333]],"o":[[0,0],[6.52,2],[6.835,6.333],[0,0]],"v":[[-25.946,5.87],[-16.573,0.552],[0.779,-4.115],[25.947,5.87]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[25.947,5.87],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":427,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Cloud 1 Outlines","sr":1,"ks":{"o":{"a":0,"k":60,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[110.659,122.68,0],"ix":2},"a":{"a":0,"k":[69.872,6.118,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-12.785,-4.018],[-11.344,0.301],[-6.857,-1.046],[-20.404,-0.256],[19.213,2.083],[4.157,-0.297],[0,0]],"o":[[0,0],[7.99,2.511],[7.15,-0.19],[8.506,1.298],[0,0],[-19.213,-2.083],[-4.157,0.298],[0,0]],"v":[[-69.872,-4.332],[-30.482,-4.332],[5.474,-2.052],[26.647,-0.763],[69.871,2.364],[10.608,5.637],[-19.114,2.661],[-69.872,6.118]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[69.871,6.118],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":427,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Mud Dark 4 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200.453,241.443,0],"ix":2},"a":{"a":0,"k":[159.646,16.692,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-38.708,-12.333],[-4.874,18.621],[0,0],[54.391,12.981],[11.076,-1.083],[0,0]],"o":[[0,0],[38.708,12.334],[0,0],[0,0],[-10.825,-2.583],[0,0],[0,0]],"v":[[-159.396,8.557],[0.229,-4.109],[159.396,-10.154],[159.396,7.225],[-4.514,3.462],[-37.574,1.094],[-159.359,13.001]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.317999985639,0.2,0.165000002992,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[159.646,16.693],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":427,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Mud Dark 3 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200.311,208.501,0],"ix":2},"a":{"a":0,"k":[159.55,20.417,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-21.595,3.035],[-14.459,0.76],[-6.037,-0.293],[-10.699,-0.618],[-8.022,0.299],[-17.772,2.532],[-9.316,2.166],[-3.166,3.226],[0,0],[0,0],[12.667,-10.666],[12.365,1.981],[0,0]],"o":[[21.354,-4.439],[14.332,-2.015],[6.033,-0.317],[10.688,0.518],[8.018,0.463],[17.942,-0.671],[9.463,-1.349],[4.131,-0.961],[7.333,-7.472],[0,0],[0,0],[-12.666,10.667],[-12.366,-1.98],[0,0]],"v":[[-159.3,13.458],[-94.798,2.303],[-51.598,-2.203],[-33.469,-2.395],[-1.814,2.234],[22.277,2.308],[75.914,-2.665],[104.164,-7.71],[118.413,-12.695],[159.3,-16.527],[159.3,-6.501],[123.079,-6.501],[-26.555,5.146],[-159.283,20.167]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.317999985639,0.2,0.165000002992,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[159.55,20.417],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":427,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Mud Light 3 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200.592,234.246,0],"ix":2},"a":{"a":0,"k":[159.461,20.849,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-38.926,-12.378],[-9.254,21.314],[0,0],[0,0]],"o":[[0,0],[38.927,12.378],[-0.027,4.686],[0,0],[0,0]],"v":[[-159.211,10.768],[25.798,-6.497],[159.211,-20.598],[159.211,20.598],[-158.826,20.598]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458999992819,0.349000010771,0.246999987434,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[159.461,20.849],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":427,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Mud Dark 2 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200.384,229.469,0],"ix":2},"a":{"a":0,"k":[159.785,25.625,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-51.667,-13.666],[0.069,-4],[0,0],[0,0]],"o":[[0,0],[51.667,13.667],[-0.07,4.001],[0,0],[0,0]],"v":[[-159.535,2.977],[67.465,-8.357],[159.466,-21.375],[159.227,25.375],[-158.618,24.644]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.317999985639,0.2,0.165000002992,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[159.785,25.625],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":427,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Mud Light 2 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200.278,195.068,0],"ix":2},"a":{"a":0,"k":[159.583,13.261,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-21.871,-1.621],[0,0],[-24.66,-1.98],[0,0],[21.285,-10.8],[18.04,-0.099],[16.789,1],[8.846,-0.447],[0,0]],"o":[[0,0],[21.871,1.621],[0,0],[0,0],[0,0],[-8.011,4.064],[-16.439,0.09],[-19.585,-1.166],[-24.75,1.25],[0,0]],"v":[[-159.333,1.093],[-41.388,-7.771],[38.817,-8.512],[159.333,-11.032],[159.333,-1.219],[74.862,-2.068],[33.729,1.809],[-18.042,1.201],[-64.138,-0.318],[-159.302,13.012]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458999992819,0.349000010771,0.246999987434,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[159.583,13.262],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":427,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Mud Dark 1 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200.236,195.086,0],"ix":2},"a":{"a":0,"k":[159.625,18.812,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-36.717,-5.6],[-49.373,-15.377],[0,0],[21.107,-4.577],[0,0]],"o":[[0,0],[41.567,6.337],[0,0],[0,0],[-21.108,4.576],[0,0]],"v":[[-159.375,18.561],[-5.739,6.581],[159.375,-3.113],[159.375,-10.641],[-59.887,-13.984],[-159.321,-10.607]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.317999985639,0.2,0.165000002992,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[159.625,18.811],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":427,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Mud Light 1 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200.262,217.559,0],"ix":2},"a":{"a":0,"k":[159.598,37.536,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-38.35,3.168],[-22.338,0.489],[0,0],[0,0],[0,0]],"o":[[0,0],[41.282,-3.41],[25.387,-0.556],[0,0],[0,0],[0,0]],"v":[[-159.348,-33.079],[-57.499,-33.876],[106.231,-33.008],[159.348,-33.522],[159.348,37.286],[-159.169,36.886]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.458999992819,0.349000010771,0.246999987434,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[159.598,37.536],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":427,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Grass Light Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200.229,180.691,0],"ix":2},"a":{"a":0,"k":[159.381,6.727,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-19.854,-6.958],[-24.927,2.87],[-21.286,-0.394],[-21.984,-2.691],[-27.896,1.102],[0,0],[27.765,3.4],[22.112,0.409],[21.206,-2.442],[19.853,6.958],[0,0]],"o":[[0,0],[19.853,6.958],[21.206,-2.442],[22.112,0.409],[27.765,3.4],[0,0],[-27.896,1.101],[-21.984,-2.692],[-21.286,-0.393],[-24.927,2.87],[-19.854,-6.959],[0,0]],"v":[[-159.381,1.434],[-117.316,3.177],[-56.388,2.339],[8.047,1.4],[74.731,4.395],[159.381,3.344],[159.381,-1.012],[74.731,-2.415],[8.047,-5.411],[-56.388,-4.471],[-117.316,-3.633],[-159.315,-3.633]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.470999983245,0.528999956916,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[159.381,6.727],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":427,"st":0,"bm":2},{"ddd":0,"ind":19,"ty":4,"nm":"Grass Dark Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200.262,178.289,0],"ix":2},"a":{"a":0,"k":[159.598,18.123,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-19.854,-6.958],[-24.927,2.871],[-21.286,-0.394],[-21.984,-2.692],[-27.895,1.102],[0,0],[0,0]],"o":[[0,0],[19.853,6.959],[21.206,-2.441],[22.113,0.409],[27.765,3.4],[0,0],[0,0],[0,0]],"v":[[-159.348,-11.232],[-116.393,-10.915],[-55.464,-11.753],[8.969,-12.691],[75.654,-9.695],[159.348,-8.611],[159.348,5.747],[-159.318,17.872]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.470999983245,0.528999956916,0.294000004787,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[159.598,18.123],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":427,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"BG Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200.235,155.416,0],"ix":2},"a":{"a":0,"k":[159.625,99.679,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[159.375,99.43],[-159.375,99.43],[-159.375,-99.43],[159.375,-99.43]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.987999949736,0.898000021542,0.773000021542,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[159.625,99.679],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":427,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/triib_manage.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/triib_manage.json deleted file mode 100644 index 0a5b27e8..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/triib_manage.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.10","fr":29.9700012207031,"ip":0,"op":177.000007209358,"w":174,"h":149,"nm":"Untitled-1","ddd":0,"comps":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 5","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75.75,74.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":10047.0004092227,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":3,"nm":"Null 1","parent":1,"sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"n":"0_1_0p333_0","t":66,"s":[-46,31,0],"e":[-46,-33.75,0],"to":[0,-10.7916669845581,0],"ti":[0,10.7916669845581,0]},{"t":95.0000038694293}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[20,25.5,100],"ix":6}},"ao":0,"ip":0,"op":10047.0004092227,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Layer 2 Outlines","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"n":"0_1_0p333_0","t":0,"s":[629.172,75.232,0],"e":[171.672,48.761,0],"to":[-138.75,67.1568603515625,0],"ti":[80.8209686279297,45.4995231628418,0]},{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"n":"0_1_0p333_0","t":36,"s":[171.672,48.761,0],"e":[171.672,48.761,0],"to":[-1.93182694911957,-1.08755445480347,0],"ti":[0,0,0]},{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"n":"0_1_0p333_0","t":132,"s":[171.672,48.761,0],"e":[631.672,331.114,0],"to":[0,0,0],"ti":[0,0,0]},{"t":152.000006191087}],"ix":2},"a":{"a":0,"k":[16.521,14.514,0],"ix":1},"s":{"a":0,"k":[500,392.157,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.168,0.319],[0,0],[-0.599,-1.491],[0,0],[-0.566,1.885],[-3.712,3.085],[-3.228,1.079]],"o":[[0,0],[-1.59,-0.233],[0,0],[0.732,1.826],[1.386,-4.61],[2.391,-1.987],[2.077,-0.695]],"v":[[13.832,-10.021],[-13.436,-14.031],[-15.672,-11.194],[-6.19,12.438],[-2.268,12.272],[5.237,-1.438],[14.194,-5.99]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.791999966491,0.19199999641,0.286000001197,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.52,14.514],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":10047.0004092227,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Layer 4 Outlines","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-132.498,2.875,0],"ix":2},"a":{"a":0,"k":[10,19.267,0],"ix":1},"s":{"a":0,"k":[500,392.157,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.105,"y":0},"n":"0_1_0p105_0","t":135,"s":[{"i":[[5.117,0],[0,0],[0,5.118],[-5.118,0],[0,0],[0,-5.118]],"o":[[0,0],[-5.118,0],[0,-5.118],[0,0],[5.117,0],[0,5.118]],"v":[[40.483,9.267],[-40.483,9.267],[-49.75,0],[-40.483,-9.267],[40.483,-9.267],[49.75,0]],"c":true}],"e":[{"i":[[5.117,0],[0,0],[0,5.118],[-5.118,0],[0,0],[0,-5.118]],"o":[[0,0],[-5.118,0],[0,-5.118],[0,0],[5.117,0],[0,5.118]],"v":[[69.671,9.116],[-40.483,9.267],[-49.75,0],[-40.483,-9.267],[69.671,-9.418],[78.938,-0.151]],"c":true}]},{"t":148.000006028164}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.397579656863,0,0,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":44,"s":[0],"e":[33]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":45,"s":[33],"e":[33]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":112,"s":[33],"e":[0]},{"t":115.000004684046}],"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"st","c":{"a":0,"k":[0.607999973671,0.13300000359,0.211999990426,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[59.75,19.267],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":10047.0004092227,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Layer 5 Outlines","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"n":"0_1_0p333_0","t":81,"s":[-72.5,-0.702,0],"e":[-72.5,32.048,0],"to":[0,5.45833349227905,0],"ti":[0,-5.45833349227905,0]},{"t":113.000004602584}],"ix":2},"a":{"a":0,"k":[10,19.267,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":135,"s":[{"i":[[5.117,0],[0,0],[0,5.118],[-5.118,0],[0,0],[0,-5.118]],"o":[[0,0],[-5.118,0],[0,-5.118],[0,0],[5.117,0],[0,5.118]],"v":[[61.328,9.267],[-61.328,9.267],[-70.595,0],[-61.328,-9.267],[61.328,-9.267],[70.595,0]],"c":true}],"e":[{"i":[[5.117,0],[0,0],[0,5.118],[-5.118,0],[0,0],[0,-5.118]],"o":[[0,0],[-5.118,0],[0,-5.118],[0,0],[5.117,0],[0,5.118]],"v":[[18.828,9.403],[-61.328,9.267],[-70.595,0],[-61.328,-9.267],[18.828,-9.131],[28.095,0.136]],"c":true}]},{"t":148.000006028164}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.607999973671,0.13300000359,0.211999990426,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[80.595,19.017],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-10.0000004073083,"op":10037.0004088154,"st":-10.0000004073083,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Layer 3 Outlines","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"n":"0_1_0p333_0","t":86,"s":[-72.5,-33.137,0],"e":[-72.5,-1.137,0],"to":[0,5.33333349227905,0],"ti":[0,-5.33333349227905,0]},{"t":113.000004602584}],"ix":2},"a":{"a":0,"k":[10,19.267,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.105,"y":0},"n":"0_1_0p105_0","t":135,"s":[{"i":[[5.118,0],[0,0],[0,5.118],[-5.118,0],[0,0],[0,-5.118]],"o":[[0,0],[-5.118,0],[0,-5.118],[0,0],[5.118,0],[0,5.118]],"v":[[54.455,9.267],[-54.454,9.267],[-63.722,0],[-54.454,-9.267],[54.455,-9.267],[63.722,0]],"c":true}],"e":[{"i":[[5.118,0],[0,0],[0,5.118],[-5.118,0],[0,0],[0,-5.118]],"o":[[0,0],[-5.118,0],[0,-5.118],[0,0],[5.118,0],[0,5.118]],"v":[[69.705,9.346],[-54.454,9.267],[-63.722,0],[-54.454,-9.267],[69.705,-9.188],[78.972,0.079]],"c":true}]},{"t":148.000006028164}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.607999973671,0.13300000359,0.211999990426,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[73.722,19.267],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-10.0000004073083,"op":10037.0004088154,"st":-10.0000004073083,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/waves_.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/waves_.json deleted file mode 100644 index f7396e1a..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/waves_.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.8","fr":23.9759979248047,"ip":0,"op":239.999979227274,"w":300,"h":300,"nm":"SleepJounrey_Anim_Card","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 6","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[55,1909,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[130,130,100],"e":[122,122,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":120,"s":[122,122,100],"e":[130,130,100]},{"t":239.999979227274}],"ix":6}},"ao":0,"ip":0,"op":360.999968754358,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":3,"nm":"Null 7","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,1069,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":360.999968754358,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 4","parent":2,"sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[-25],"e":[-115]},{"t":239.999979227274}],"ix":10},"p":{"a":0,"k":[-485,949,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[130,130,100],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[113.773,-33.791],[0,0],[27.159,-50.107],[0,0],[104.344,56.556],[0,0],[54.636,-16.227],[0,0],[33.791,113.773],[0,0],[50.107,27.159],[0,0],[-56.556,104.344],[0,0],[16.227,54.636],[0,0],[-113.773,33.791],[0,0],[-27.159,50.108],[0,0],[-104.344,-56.556],[0,0],[-54.636,16.227],[0,0],[-33.791,-113.773],[0,0],[-50.107,-27.159],[0,0],[56.556,-104.344],[0,0],[-16.227,-54.636],[0,0]],"o":[[0,0],[-54.636,16.227],[0,0],[-56.556,104.344],[0,0],[-50.108,-27.159],[0,0],[-113.773,33.791],[0,0],[-16.227,-54.636],[0,0],[-104.344,-56.556],[0,0],[27.159,-50.107],[0,0],[-33.791,-113.773],[0,0],[54.636,-16.227],[0,0],[56.556,-104.344],[0,0],[50.108,27.159],[0,0],[113.773,-33.791],[0,0],[16.227,54.636],[0,0],[104.344,56.556],[0,0],[-27.159,50.107],[0,0],[33.791,113.773]],"v":[[745.996,577.184],[607.363,618.358],[479.616,721.959],[410.702,849.102],[119.368,935.629],[-7.775,866.716],[-171.363,849.642],[-309.996,890.816],[-577.184,745.996],[-618.358,607.362],[-721.959,479.616],[-849.102,410.702],[-935.629,119.368],[-866.715,-7.775],[-849.642,-171.363],[-890.816,-309.996],[-745.996,-577.184],[-607.363,-618.358],[-479.616,-721.959],[-410.702,-849.102],[-119.368,-935.629],[7.775,-866.715],[171.363,-849.642],[309.996,-890.816],[577.184,-745.996],[618.358,-607.363],[721.959,-479.616],[849.102,-410.702],[935.629,-119.368],[866.715,7.775],[849.642,171.362],[890.816,309.996]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"g":{"p":3,"k":{"a":0,"k":[0.47,0.475,0.725,0.816,0.735,0.457,0.59,0.837,1,0.439,0.455,0.859],"ix":9}},"s":{"a":0,"k":[0,0],"ix":5},"e":{"a":0,"k":[264,742],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":0,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360.999968754358,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 3","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.839],"y":[1]},"o":{"x":[0.198],"y":[0]},"n":["0p839_1_0p198_0"],"t":0,"s":[0],"e":[-90]},{"t":239.999979227274}],"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[113.773,-33.791],[0,0],[27.159,-50.107],[0,0],[104.344,56.556],[0,0],[54.636,-16.227],[0,0],[33.791,113.773],[0,0],[50.107,27.159],[0,0],[-56.556,104.344],[0,0],[16.227,54.636],[0,0],[-113.773,33.791],[0,0],[-27.159,50.108],[0,0],[-104.344,-56.556],[0,0],[-54.636,16.227],[0,0],[-33.791,-113.773],[0,0],[-50.107,-27.159],[0,0],[56.556,-104.344],[0,0],[-16.227,-54.636],[0,0]],"o":[[0,0],[-54.636,16.227],[0,0],[-56.556,104.344],[0,0],[-50.108,-27.159],[0,0],[-113.773,33.791],[0,0],[-16.227,-54.636],[0,0],[-104.344,-56.556],[0,0],[27.159,-50.107],[0,0],[-33.791,-113.773],[0,0],[54.636,-16.227],[0,0],[56.556,-104.344],[0,0],[50.108,27.159],[0,0],[113.773,-33.791],[0,0],[16.227,54.636],[0,0],[104.344,56.556],[0,0],[-27.159,50.107],[0,0],[33.791,113.773]],"v":[[745.996,577.184],[607.363,618.358],[479.616,721.959],[410.702,849.102],[119.368,935.629],[-7.775,866.716],[-171.363,849.642],[-309.996,890.816],[-577.184,745.996],[-618.358,607.362],[-721.959,479.616],[-849.102,410.702],[-935.629,119.368],[-866.715,-7.775],[-849.642,-171.363],[-890.816,-309.996],[-745.996,-577.184],[-607.363,-618.358],[-479.616,-721.959],[-410.702,-849.102],[-119.368,-935.629],[7.775,-866.715],[171.363,-849.642],[309.996,-890.816],[577.184,-745.996],[618.358,-607.363],[721.959,-479.616],[849.102,-410.702],[935.629,-119.368],[866.715,7.775],[849.642,171.362],[890.816,309.996]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"g":{"p":3,"k":{"a":0,"k":[0.47,0.475,0.725,0.816,0.735,0.457,0.59,0.837,1,0.439,0.455,0.859],"ix":9}},"s":{"a":0,"k":[0,0],"ix":5},"e":{"a":0,"k":[264,742],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":0,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360.999968754358,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[540,960,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[140,140,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[1362.031,2140.766],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"g":{"p":3,"k":{"a":0,"k":[0,0.799,0.545,0.301,0.406,0.456,0.302,0.318,1,0.113,0.06,0.334],"ix":9}},"s":{"a":0,"k":[1228.306,-624.67],"ix":5},"e":{"a":0,"k":[85.869,7.393],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[30.375,6.68],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":4533.99960756859,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":2,"ty":0,"nm":"OceanSlumber","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,182,0],"ix":2},"a":{"a":0,"k":[540,960,0],"ix":1},"s":{"a":0,"k":[31,31,100],"ix":6}},"ao":0,"w":1080,"h":1920,"ip":0,"op":360.999968754358,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/windmill.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/windmill.json deleted file mode 100644 index 69874abc..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/windmill.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.2.0","fr":30,"ip":0,"op":90,"w":128,"h":128,"nm":"icons/features/windmill","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"▽ ic_windmill","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[19,-121,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":3,"nm":"▽ propeler","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":90,"s":[0],"e":[0]},{"t":95}],"ix":10,"x":"var $bm_rt;\n$bm_rt = transform.rotation;"},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":9,"s":[0,0,0],"e":[0,125,0],"to":[0,20.8333339691162,0],"ti":[0,-20.8333339691162,0]},{"t":14}],"ix":2,"x":"var $bm_rt;\nvar amp, freq, decay, n, time_max, n, t, t, v;\namp = 0.05;\nfreq = 2;\ndecay = 2;\nn = 0;\n$bm_rt = time_max = 2;\nif (numKeys > 0) {\n $bm_rt = n = nearestKey(time).index;\n if (key(n).time > time) {\n n--;\n }\n}\nif (n == 0) {\n $bm_rt = t = 0;\n} else {\n $bm_rt = t = sub(time, key(n).time);\n}\nif (n > 0 && t < time_max) {\n v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10)));\n $bm_rt = sum(value, div(mul(mul(v, amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))));\n} else {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Stroke 45","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[48.43,38.07,0],"ix":2},"a":{"a":0,"k":[5.08,5.08,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[10.16,0],[0,10.16]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.039216000587,0.141176000237,0.207843005657,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Fill 43","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[48.43,38.07,0],"ix":2},"a":{"a":0,"k":[5.08,5.08,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[10.16,0],[0,10.16]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995509028435,0.995630025864,0.995441973209,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Stroke 13","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[38.26,48.24,0],"ix":2},"a":{"a":0,"k":[5.08,5.08,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,10.16],[10.16,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.039216000587,0.141176000237,0.207843005657,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Fill 11","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[38.26,48.24,0],"ix":2},"a":{"a":0,"k":[5.08,5.08,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,10.16],[10.16,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995509028435,0.995630025864,0.995441973209,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Stroke 9","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[20.075,64.8,0],"ix":2},"a":{"a":0,"k":[19.065,17.44,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-3.07,3.08],[0,0]],"o":[[0,0],[0,0],[3.07,3.08],[0,0],[0,0]],"v":[[26.2,0],[0,26.2],[6.37,32.57],[17.49,32.57],[38.13,11.93]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.039216000587,0.141176000237,0.207843005657,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Stroke 41","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[64.991,19.88,0],"ix":2},"a":{"a":0,"k":[17.441,19.07,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[3.07,-3.08],[0,0]],"o":[[0,0],[0,0],[3.07,3.07],[0,0],[0,0]],"v":[[0,26.21],[26.21,0],[32.58,6.37],[32.58,17.5],[11.93,38.14]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.039216000587,0.141176000237,0.207843005657,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Stroke 33","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[48.445,48.245,0],"ix":2},"a":{"a":0,"k":[5.085,5.085,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[10.17,10.17],[0,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.039216000587,0.141176000237,0.207843005657,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Stroke 31","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[66.66,64.831,0],"ix":2},"a":{"a":0,"k":[19.09,17.461,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[3.08,3.07],[0,0]],"o":[[0,0],[0,0],[-3.07,3.07],[0,0],[0,0]],"v":[[11.93,0],[38.18,26.25],[31.81,32.62],[20.68,32.62],[0,11.93]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.039216000587,0.141176000237,0.207843005657,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Stroke 23","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[38.28,38.08,0],"ix":2},"a":{"a":0,"k":[5.08,5.08,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,0],[10.16,10.16]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.039216000587,0.141176000237,0.207843005657,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Stroke 21","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[21.719,19.895,0],"ix":2},"a":{"a":0,"k":[17.439,19.065,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-3.07,-3.07],[0,0]],"o":[[0,0],[0,0],[-3.07,3.07],[0,0],[0,0]],"v":[[34.88,26.2],[8.67,0],[2.3,6.37],[2.3,17.49],[22.95,38.13]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.039216000587,0.141176000237,0.207843005657,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Combined Shape","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[43.335,41.448,0],"ix":2},"a":{"a":0,"k":[42.295,40.648,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[11.89,20.62],[20.62,11.89],[8.73,0],[0,8.73]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[17.44,46.55],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Fill 3","np":1,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[11.89,20.62],[20.62,11.89],[8.73,0],[0,8.73]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[8.73,55.3],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Fill 5","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":2,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[-3.21,3.21]],"o":[[0,0],[0,0],[0,0],[0,0],[3.2,3.21],[0,0]],"v":[[17.7,14.81],[20.62,11.89],[8.73,0],[0,8.73],[6.09,14.81],[17.7,14.81]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,64.02],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Fill 7","np":1,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":2,"nm":"Merge Paths 2","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,11.85],[8.73,20.58],[20.58,8.73],[11.85,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[17.52,17.49],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Fill 15","np":1,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":2,"nm":"Merge Paths 3","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[0,11.85],[8.73,20.58],[20.58,8.73],[11.85,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[8.76,8.77],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Fill 17","np":1,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":2,"nm":"Merge Paths 4","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[-3.2,-3.2]],"o":[[0,0],[0,0],[0,0],[0,0],[-3.2,3.21],[0,0]],"v":[[2.4,17.66],[5.33,20.59],[17.19,8.73],[8.46,0],[2.4,6.05],[2.4,17.66]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[3.44,0.04],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Fill 19","np":1,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":2,"nm":"Merge Paths 5","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.73,20.59],[0,11.86],[11.85,0],[20.58,8.73]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[46.55,46.62],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Fill 25","np":1,"cix":2,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":2,"nm":"Merge Paths 6","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.73,20.59],[0,11.86],[11.85,0],[20.58,8.73]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[55.27,55.38],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Fill 27","np":1,"cix":2,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":2,"nm":"Merge Paths 7","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[3.2,3.21]],"o":[[0,0],[0,0],[0,0],[0,0],[-3.21,3.21],[0,0]],"v":[[2.93,14.78],[0,11.85],[11.85,0],[20.59,8.73],[14.54,14.78],[2.93,14.78]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[64,64.11],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Fill 29","np":1,"cix":2,"ix":16,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":2,"nm":"Merge Paths 8","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[20.62,11.89],[11.89,20.62],[0,8.73],[8.73,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[46.49,17.46],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Fill 35","np":1,"cix":2,"ix":18,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":2,"nm":"Merge Paths 9","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[20.62,11.89],[11.89,20.62],[0,8.73],[8.73,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[55.25,8.73],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Fill 37","np":1,"cix":2,"ix":20,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":2,"nm":"Merge Paths 10","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[3.2,-3.21]],"o":[[0,0],[0,0],[0,0],[0,0],[3.2,3.2],[0,0]],"v":[[14.82,17.7],[11.89,20.62],[0,8.73],[8.73,0],[14.82,6.09],[14.82,17.7]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[63.99,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Fill 39","np":1,"cix":2,"ix":22,"mn":"ADBE Vector Group","hd":false},{"ty":"mm","mm":2,"nm":"Merge Paths 11","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.850979983807,0.231372997165,0.125489994884,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 40","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Combined Shape","np":24,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"door","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":6,"s":[43.33,89.975,0],"e":[43.33,210.475,0],"to":[0,20.0833339691162,0],"ti":[0,-20.0833339691162,0]},{"t":11}],"ix":2,"x":"var $bm_rt;\nvar amp, freq, decay, n, time_max, n, t, t, v;\namp = 0.05;\nfreq = 2;\ndecay = 2;\nn = 0;\n$bm_rt = time_max = 2;\nif (numKeys > 0) {\n $bm_rt = n = nearestKey(time).index;\n if (key(n).time > time) {\n n--;\n }\n}\nif (n == 0) {\n $bm_rt = t = 0;\n} else {\n $bm_rt = t = sub(time, key(n).time);\n}\nif (n > 0 && t < time_max) {\n v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10)));\n $bm_rt = sum(value, div(mul(mul(v, amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))));\n} else {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[9.84,15.655,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-4.34,0],[0,0],[0,-4.34]],"o":[[0,0],[0,0],[0,-4.34],[0,0],[4.35,0],[0,0]],"v":[[19.68,31.31],[0,31.31],[0,7.87],[7.87,0],[11.81,0],[19.68,7.87]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.039216000587,0.141176000237,0.207843005657,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":3,"nm":"▽ bottom","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[0,105,0],"e":[0,225,0],"to":[0,20,0],"ti":[0,-20,0]},{"t":5}],"ix":2,"x":"var $bm_rt;\nvar amp, freq, decay, n, time_max, n, t, t, v;\namp = 0.05;\nfreq = 2;\ndecay = 2;\nn = 0;\n$bm_rt = time_max = 2;\nif (numKeys > 0) {\n $bm_rt = n = nearestKey(time).index;\n if (key(n).time > time) {\n n--;\n }\n}\nif (n == 0) {\n $bm_rt = t = 0;\n} else {\n $bm_rt = t = sub(time, key(n).time);\n}\nif (n > 0 && t < time_max) {\n v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10)));\n $bm_rt = sum(value, div(mul(mul(v, amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))));\n} else {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Fill 51","parent":15,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[43.335,13.395,0],"ix":2},"a":{"a":0,"k":[1.955,1.955,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[1.07,0],[0,1.08],[-1.09,0],[0,-1.09]],"o":[[0,1.08],[-1.09,0],[0,-1.09],[1.07,0],[0,0]],"v":[[3.91,1.96],[1.96,3.91],[0,1.96],[1.96,0],[3.91,1.96]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.039216000587,0.141176000237,0.207843005657,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Stroke 47","parent":15,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[43.33,7.395,0],"ix":2},"a":{"a":0,"k":[43.33,6.025,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-2.58,0],[0,0],[0,-2.17],[0,0],[0,0]],"o":[[0,0],[0,0],[0,-2.17],[0,0],[2.58,0],[0,0],[0,0],[0,0]],"v":[[33.97,12.05],[0,12.05],[0,3.93],[4.67,0],[81.99,0],[86.66,3.93],[86.66,12.05],[52.66,12.05]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.039216000587,0.141176000237,0.207843005657,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"top","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":3,"s":[42.55,59.74,0],"e":[42.55,179.5,0],"to":[0,19.9599990844727,0],"ti":[0,-20.2099990844727,0]},{"t":8}],"ix":2,"x":"var $bm_rt;\nvar amp, freq, decay, n, time_max, n, t, t, v;\namp = 0.05;\nfreq = 2;\ndecay = 2;\nn = 0;\n$bm_rt = time_max = 2;\nif (numKeys > 0) {\n $bm_rt = n = nearestKey(time).index;\n if (key(n).time > time) {\n n--;\n }\n}\nif (n == 0) {\n $bm_rt = t = 0;\n} else {\n $bm_rt = t = sub(time, key(n).time);\n}\nif (n > 0 && t < time_max) {\n v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10)));\n $bm_rt = sum(value, div(mul(mul(v, amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))));\n} else {\n $bm_rt = value;\n}"},"a":{"a":0,"k":[21.22,45.9,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-10.86,0],[0,0],[0,-10.86]],"o":[[0,0],[0,0],[0,-10.86],[0,0],[10.87,0],[0,0]],"v":[[42.44,91.8],[0,91.8],[0,19.67],[19.67,0],[22.76,0],[42.44,19.67]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.039216000587,0.141176000237,0.207843005657,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0}],"markers":[{"tm":90,"cm":"1","dr":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/world_locations.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/world_locations.json deleted file mode 100644 index 519200ec..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/world_locations.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.0.1","fr":60,"ip":0,"op":301,"w":800,"h":600,"nm":"World","ddd":0,"assets":[{"id":"comp_5","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"here 4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":45,"s":[100],"e":[0]},{"t":75}],"ix":11,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"r":{"a":0,"k":-22.856,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2},"a":{"a":0,"k":[-252.5,-48.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.14,0.14],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p14_1_0p167_0p167","0p14_1_0p167_0p167"],"t":15,"s":[2,2],"e":[40,40]},{"t":75}],"ix":2,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.972549019608,0.576470588235,0.188235294118,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.14],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p14_1_0p167_0p167"],"t":15,"s":[10],"e":[0]},{"t":75}],"ix":5,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-252.5,-48.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":15,"op":715,"st":15,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"here","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":30,"s":[100],"e":[0]},{"t":60}],"ix":11,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"r":{"a":0,"k":-22.856,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2},"a":{"a":0,"k":[-252.5,-48.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.14,0.14],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p14_1_0p167_0p167","0p14_1_0p167_0p167"],"t":0,"s":[2,2],"e":[60,60]},{"t":60}],"ix":2,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.972549019608,0.576470588235,0.188235294118,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.14],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p14_1_0p167_0p167"],"t":0,"s":[10],"e":[0]},{"t":60}],"ix":5,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-252.5,-48.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":730,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":2,"ty":3,"nm":"NULL CONTROL","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":-9,"ix":10},"p":{"a":0,"k":[396,281,0],"ix":2},"a":{"a":0,"k":[60,60,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":72,"op":301,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"rings 4","parent":2,"sr":1,"ks":{"o":{"a":0,"k":35,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[58.436,59.877,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[334,66.48],"ix":2},"p":{"a":0,"k":[0,55],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.686274509804,0.933333333333,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.5,-9.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":210,"s":[21.5],"e":[26]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":225.6,"s":[26],"e":[79]},{"t":262}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":210,"s":[21.5],"e":[79]},{"t":236}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":210,"op":301,"st":210,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"rings 3","parent":2,"sr":1,"ks":{"o":{"a":0,"k":35,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60,70,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[417,83],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.686274509804,0.933333333333,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.5,-9.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":202,"s":[15],"e":[26]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":217.6,"s":[26],"e":[84]},{"t":254}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":202,"s":[15],"e":[84]},{"t":228}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":202,"op":301,"st":202,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"rings 2","parent":2,"sr":1,"ks":{"o":{"a":0,"k":35,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[58.436,59.877,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[334,66.48],"ix":2},"p":{"a":0,"k":[0,55],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.686274509804,0.933333333333,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.5,-9.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":60,"s":[21.5],"e":[26]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":75.6,"s":[26],"e":[79]},{"t":112}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":60,"s":[21.5],"e":[79]},{"t":86}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":60,"op":301,"st":60,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"rings","parent":2,"sr":1,"ks":{"o":{"a":0,"k":35,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60,70,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[417,83],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.686274509804,0.933333333333,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0.5,-9.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":52,"s":[15],"e":[26]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":67.6,"s":[26],"e":[84]},{"t":104}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":52,"s":[15],"e":[84]},{"t":78}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":52,"op":301,"st":52,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"maspMask 5","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[-18.5,-5.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-81.462,0],[0,-81.462],[81.462,0],[0,81.462]],"o":[[81.462,0],[0,81.462],[-81.462,0],[0,-81.462]],"v":[[-18.5,-153],[129,-5.5],[-18.5,142],[-166,-5.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"fl","c":{"a":0,"k":[0.662744978362,0.67843095368,0.650979973288,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":301,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"Here rings","parent":16,"tt":1,"refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[70.408,63.975,0],"ix":2},"a":{"a":0,"k":[75,75,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":150,"h":150,"ip":0,"op":301,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"maspMask 4","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[-18.5,-5.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-81.462,0],[0,-81.462],[81.462,0],[0,81.462]],"o":[[81.462,0],[0,81.462],[-81.462,0],[0,-81.462]],"v":[[-18.5,-153],[129,-5.5],[-18.5,142],[-166,-5.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"fl","c":{"a":0,"k":[0.662744978362,0.67843095368,0.650979973288,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":301,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"Here rings","parent":16,"tt":1,"refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-80.007,318.38,0],"ix":2},"a":{"a":0,"k":[75,75,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":150,"h":150,"ip":0,"op":301,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"maspMask 3","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[-18.5,-5.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-81.462,0],[0,-81.462],[81.462,0],[0,81.462]],"o":[[81.462,0],[0,81.462],[-81.462,0],[0,-81.462]],"v":[[-18.5,-153],[129,-5.5],[-18.5,142],[-166,-5.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"fl","c":{"a":0,"k":[0.662744978362,0.67843095368,0.650979973288,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":301,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":0,"nm":"Here rings","parent":16,"tt":1,"refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-170.998,95.543,0],"ix":2},"a":{"a":0,"k":[75,75,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":150,"h":150,"ip":0,"op":301,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"maspMask 2","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[-18.5,-5.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-81.462,0],[0,-81.462],[81.462,0],[0,81.462]],"o":[[81.462,0],[0,81.462],[-81.462,0],[0,-81.462]],"v":[[-18.5,-153],[129,-5.5],[-18.5,142],[-166,-5.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"fl","c":{"a":0,"k":[0.662744978362,0.67843095368,0.650979973288,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":301,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":0,"nm":"Here rings","parent":16,"tt":1,"refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-191.425,-28.874,0],"ix":2},"a":{"a":0,"k":[75,75,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":150,"h":150,"ip":0,"op":301,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"maspMask","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[-18.5,-5.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-81.462,0],[0,-81.462],[81.462,0],[0,81.462]],"o":[[81.462,0],[0,81.462],[-81.462,0],[0,-81.462]],"v":[[-18.5,-153],[129,-5.5],[-18.5,142],[-166,-5.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"fl","c":{"a":0,"k":[0.662744978362,0.67843095368,0.650979973288,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":301,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"map","tt":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.95],"y":[0]},"n":["0p833_0p833_0p95_0"],"t":16,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":86,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.95],"y":[0]},"n":["0p833_0p833_0p95_0"],"t":180,"s":[100],"e":[0]},{"t":239}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.14],"y":[1]},"o":{"x":[0.58],"y":[0]},"n":["0p14_1_0p58_0"],"t":16,"s":[-22.856],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":146,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.72],"y":[0]},"n":["0p833_0p833_0p72_0"],"t":180,"s":[0],"e":[51]},{"t":246}],"ix":10},"p":{"a":0,"k":[240.55,-287.518,0],"ix":2},"a":{"a":0,"k":[-409.527,-960.177,0],"ix":1},"s":{"a":0,"k":[53.851,53.851,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.207,0.165],[0.867,1.221],[-0.146,-1.605],[-0.425,-1.251],[1.443,0.861]],"o":[[0.99,-1.532],[0.914,1.268],[0.125,1.365],[-0.831,-1.273],[0.19,-0.107]],"v":[[53.422,-169.413],[53.886,-174.034],[55.387,-169.683],[56.25,-165.777],[52.829,-169.024]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-0.221,0.036],[0.202,-0.081]],"o":[[-0.202,0.081],[0.179,-0.142]],"v":[[79.925,-218.282],[79.321,-218.037]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-0.097,0.141],[0.026,-0.316],[0.23,-0.223],[-0.222,0.297]],"o":[[-0.005,0.307],[-0.328,0.057],[0.146,-0.325],[0.107,-0.144]],"v":[[70.501,91.15],[70.466,92.085],[69.632,92.509],[70.199,91.575]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[-0.302,-0.569],[-2.966,1.735],[-0.508,0.195],[-0.288,0.188],[-0.146,-0.057],[0.432,-0.165],[-0.447,-1.656],[2.425,0.115],[0.108,0.207],[0.313,1.452]],"o":[[1.559,2.949],[0.534,-0.286],[0.261,-0.182],[0.144,0.056],[-0.41,0.1],[-2.584,1.813],[-1.28,-1.834],[-0.111,-0.206],[0.406,-1.54],[0.28,0.576]],"v":[[58.462,-160.873],[65.125,-158.758],[66.684,-159.461],[67.511,-160.019],[67.945,-159.848],[66.684,-159.461],[63.503,-154.417],[57.797,-157.441],[57.467,-158.059],[57.588,-162.59]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":4,"ty":"sh","ix":5,"ks":{"a":0,"k":{"i":[[2.019,-0.203],[1.848,1.224],[0.979,0.677],[0.668,0.287],[0.085,0.232],[0.382,0.604],[3.152,1.27],[0.544,4.318],[2.55,2.615],[0,0],[-1.086,3.211],[3.016,0.917],[1.605,3.901],[0,0.003],[-1.369,0.237],[-0.134,-0.385],[-2.91,-12.044],[-0.776,-0.561],[-4.493,-5.058],[-1.334,-0.655],[-1.389,-3.659],[-0.091,-0.245]],"o":[[-1.847,-1.226],[-0.005,-1.235],[-0.657,-0.321],[-0.084,-0.232],[0.504,-0.437],[-1.885,-2.146],[-2.966,-2.857],[-0.431,-3.362],[0,0],[-2.126,-1.468],[1.301,-3.024],[-3.297,-2.917],[0,0],[0.67,-1.565],[0.184,0.361],[6.125,10.035],[0.229,0.933],[5.65,4.112],[0.963,1.083],[-2.97,3.861],[0.093,0.263],[-2.088,0.607]],"v":[[-9.095,165.196],[-14.642,161.523],[-16.196,158.702],[-18.175,157.758],[-18.433,157.066],[-18.231,155.506],[-22.932,148.401],[-28.253,137.917],[-32.158,128.44],[-32.158,128.44],[-35.338,122.303],[-38.049,116.461],[-44.127,105.489],[-44.127,105.486],[-41.037,102.837],[-40.546,103.952],[-22.555,134.295],[-21.068,136.785],[-8.533,152.74],[-5.465,155.753],[-3.832,166.843],[-3.559,167.585]],"c":true},"ix":2},"nm":"Path 5","mn":"ADBE Vector Shape - Group","hd":false},{"ind":5,"ty":"sh","ix":6,"ks":{"a":0,"k":{"i":[[-1.611,0.833],[-2.113,1.572],[-0.011,0.004],[1.444,9.227],[-1.949,0.979],[-1.452,5.235],[-1.205,-0.651],[-4.261,3.828],[-1.263,0.803],[-0.064,-0.102],[-2.206,-0.692],[0.03,-0.378],[-5.151,-1.208],[-0.767,-0.452],[-0.467,0.059],[0.03,-0.127],[-1.628,0.466],[0.059,-0.628],[6.221,-0.498],[0.058,-3.047],[-2.229,-0.301],[-0.498,0.26],[-1.904,3.28],[-0.126,-0.064],[-1.598,0.955],[-0.054,0.758],[0,0],[-0.512,3.445],[0,0],[-0.487,1.3],[0.803,0.474],[1.709,0.909],[1.051,5.31],[-0.615,4.649],[-0.034,0.039],[-3.736,-3.599],[-2.427,1.091],[-0.07,-0.076],[-1.559,-0.503],[-0.899,-1.636],[-1.047,0.186],[-0.034,-0.256],[-1.297,-0.448],[-0.139,-0.02],[-0.027,-0.276],[0,0],[-0.999,-2.421],[0,0],[1.108,-0.057],[-0.083,-1.499],[-0.989,0.016],[-2.42,0.89],[-4.521,6.094],[-0.582,0.696],[-0.485,0.149],[-0.209,0.003],[1.303,1.458],[1.388,-0.047],[0.247,0.085],[0.344,1.099],[-0.115,0.437],[0,0.003],[-0.003,-0.003],[-4.402,-0.406],[-3.696,-5.259],[-0.385,-0.139],[-2.098,0.334],[-0.023,-0.097],[-8.01,-2.744],[-1.77,1.139],[-0.63,0.44],[-2.018,-2.544],[-0.091,-1.878],[-0.222,-0.482],[0.301,-0.402],[0.104,-0.517],[-0.023,-0.642],[0.47,-0.164],[-0.034,-0.892],[-0.07,-0.18],[0.831,-2.62],[-0.003,-0.054],[0.615,-0.059],[3.769,-1.769],[5.721,0.761],[2.154,-0.758],[0.06,-0.102],[3.676,1.63],[2.718,-0.603],[2.103,-3.244],[1.166,0.107],[-0.016,0.057],[1.988,1.048],[1.886,1.985],[4.131,0.57],[1.834,1.419],[1.213,-0.773],[0.02,-0.177],[0.928,0.318],[0.218,0.508],[-0.088,0.127],[-1.262,0.764],[0.092,1.911],[0.298,2.018],[2.657,0.046],[1.323,-1.104],[5.808,0.145],[4.091,-2.217],[7.579,1.333],[0,0]],"o":[[2.34,-0.055],[0.008,-0.006],[6.339,-3.243],[-0.341,-2.19],[4.754,-2.396],[0.447,-1.605],[6.806,3.662],[1.155,-1.247],[0.038,0.107],[1.46,1.238],[0.768,0.07],[1.181,5.686],[0.766,0.451],[0.466,-0.065],[-0.034,0.112],[0.248,1.67],[-0.321,0.486],[1.331,3.842],[-2.368,0.19],[0.314,2.527],[0.493,-0.291],[2.456,0.85],[0.123,0.054],[1.885,-0.534],[0.057,-0.76],[0,0],[2.081,-3.217],[0,0],[1.063,-0.279],[0.408,-1.091],[-1.668,-0.984],[-2.968,-3.323],[-2.772,-2.806],[0.032,-0.039],[3.051,4.341],[2.424,0.062],[0.066,0.078],[1.276,1.041],[-0.368,1.915],[0.798,0.638],[0.046,0.251],[0.357,1.338],[0.139,0.031],[0.026,0.271],[0,0],[-0.497,3.113],[0,0],[-1.104,0.053],[0.084,1.498],[0.988,-0.014],[0.416,1.976],[4.432,5.832],[0.542,-0.729],[0.485,-0.148],[0.203,0.027],[1.449,-1.446],[-1.389,0.047],[-0.23,-0.122],[-0.345,-1.097],[0.115,-0.44],[0,-0.003],[0,0.003],[3.945,-0.73],[-2.902,4.527],[0.383,0.134],[-0.168,1.234],[0.026,0.097],[6.16,9.39],[1.782,0.611],[0.65,-0.42],[2.869,-2.015],[-2.336,1.185],[0.378,0.528],[-0.305,0.402],[-0.349,0.39],[0.02,0.645],[-0.364,0.196],[-0.571,0.665],[0.081,0.175],[-2.24,1.809],[0.003,0.053],[-0.613,0.055],[-4.027,0.405],[-6.048,2.836],[-2.042,-0.274],[-0.073,0.102],[-3.675,-1.638],[-2.72,-2.133],[-3.403,2.794],[-0.918,0.868],[0.02,-0.053],[-0.621,-2.811],[-2.199,-1.156],[-2.232,-4.026],[-2.065,-0.284],[-1.066,-0.812],[-0.037,0.195],[-0.929,-0.321],[-0.219,-0.509],[0.085,-0.126],[-0.144,-1.586],[1.259,-1.353],[-0.249,-2.031],[-1.116,-2.459],[-1.873,0.022],[-5.796,-0.195],[-4.63,-0.114],[-6.651,3.599],[0,0],[-3.783,-2.584]],"v":[[-201.566,62.709],[-194.681,61.622],[-194.655,61.608],[-183.507,45.949],[-180.181,40.758],[-170.687,29.554],[-167.799,27.419],[-152.89,22.353],[-148.702,21.522],[-148.572,21.84],[-145.009,26.319],[-144.486,27.273],[-134.181,36.711],[-131.879,38.065],[-130.483,37.875],[-130.585,38.214],[-128.112,40.538],[-128.689,42.202],[-132.312,50.08],[-136.83,55.238],[-132.614,59.013],[-131.128,58.178],[-124.193,57.479],[-123.824,57.651],[-119.271,54.426],[-119.103,52.147],[-119.337,51.87],[-117.907,41.525],[-117.911,41.525],[-114.869,40.42],[-116.404,38.211],[-121.52,35.461],[-130.877,25.963],[-136.711,16.196],[-136.612,16.074],[-125.442,26.945],[-118.188,27.941],[-117.982,28.172],[-113.845,30.7],[-111.917,35.777],[-109.302,36.953],[-109.169,37.714],[-106.71,40.417],[-106.296,40.482],[-106.216,41.3],[-106.216,41.3],[-103.035,48.467],[-103.035,48.467],[-106.357,48.631],[-106.11,53.128],[-103.145,53.081],[-99.585,55.694],[-90.636,55.43],[-88.891,53.342],[-87.434,52.895],[-86.822,52.931],[-86.808,48.574],[-90.976,48.715],[-91.689,48.411],[-92.718,45.108],[-92.371,43.79],[-92.371,43.785],[-92.368,43.79],[-81.592,38.933],[-80.377,54.881],[-79.229,55.302],[-76.788,56.965],[-76.71,57.257],[-52.36,64.331],[-46.798,63.699],[-46.333,63.351],[-39.024,64.139],[-39.642,69.508],[-38.749,71.019],[-39.653,72.228],[-40.336,73.588],[-40.267,75.519],[-41.517,76.057],[-42.337,78.395],[-42.119,78.927],[-45.435,86.313],[-45.422,86.477],[-47.266,86.651],[-58.981,85.35],[-76.231,84.787],[-82.382,84.095],[-82.566,84.399],[-93.591,79.497],[-101.744,79.508],[-105.271,90.199],[-108.457,91.09],[-108.39,90.932],[-113.533,86.784],[-120.418,84.2],[-130.54,78.38],[-136.647,77.044],[-140.045,76.711],[-140.12,77.255],[-142.905,76.291],[-143.561,74.77],[-143.301,74.392],[-141.42,70.987],[-139.529,66.158],[-139.967,60.053],[-145.607,56.263],[-150.687,57.382],[-168.093,58.274],[-181.952,61.6],[-202.708,66.412],[-202.708,66.412]],"c":true},"ix":2},"nm":"Path 6","mn":"ADBE Vector Shape - Group","hd":false},{"ind":6,"ty":"sh","ix":7,"ks":{"a":0,"k":{"i":[[-1.116,3.287],[-0.344,0.171],[-1.207,1.991],[0.318,2.654],[-0.707,2.084],[-0.673,0.718],[5.35,5.919],[0.21,1.62],[-2.657,4.037],[-1.909,2.382],[-0.008,0.005],[0,0],[-0.238,-0.085],[-0.011,0.762],[-3.676,3.086],[-0.295,-1.163],[-0.144,-0.482],[1.821,-1.878],[-2.039,-8.125],[-3.893,1.121],[-4.719,3.957],[0.33,-1.953],[5.02,-5.165],[0.073,-0.259],[-3.032,-5.406],[-2.358,-4.092],[-0.176,-0.314],[-0.062,-0.051],[2.156,0.831],[6.284,-4.668],[2.378,-0.054],[-0.382,0.781]],"o":[[0.302,-0.138],[2.953,-0.811],[1.253,-1.586],[-0.255,-2.098],[0.361,-0.94],[5.4,-5.754],[-1.156,-1.281],[-0.64,-4.967],[1.909,-2.383],[0.011,-0.006],[0,0],[0.177,0.107],[0.781,-0.149],[0.069,-5.266],[0.276,1.173],[0.039,0.486],[0.628,3.093],[-5.884,6.076],[1.032,4.123],[5.479,-1.58],[0.846,1.802],[-5.823,-1.471],[-0.099,0.259],[-3.071,2.233],[-4.573,5.976],[0.069,0.309],[0.066,0.051],[-1.594,1.491],[-8.455,-3.258],[-1.886,-1.498],[0.38,-0.781],[0.879,-3.651]],"v":[[-133.233,-45.102],[-132.261,-45.565],[-126.05,-49.778],[-124.521,-55.992],[-123.943,-62.386],[-122.303,-64.802],[-122.196,-77.796],[-123.883,-82.015],[-120.423,-95.355],[-114.695,-102.503],[-114.664,-102.52],[-114.664,-102.52],[-114.048,-102.227],[-112.273,-103.47],[-105.785,-115.441],[-104.018,-112.477],[-103.792,-111.005],[-106.7,-103.64],[-111.81,-82.533],[-100.901,-72.481],[-84.436,-77.663],[-83.989,-71.987],[-100.637,-69.66],[-100.888,-68.883],[-105.265,-59.672],[-108.594,-44.484],[-108.231,-43.553],[-108.041,-43.4],[-113.651,-42.339],[-134.728,-36.408],[-141.209,-38.32],[-140.065,-40.663]],"c":true},"ix":2},"nm":"Path 7","mn":"ADBE Vector Shape - Group","hd":false},{"ind":7,"ty":"sh","ix":8,"ks":{"a":0,"k":{"i":[[0.003,0],[0,0],[-0.003,-0.003]],"o":[[0,-0.003],[0.003,0.003],[-0.003,0]],"v":[[310.8,75.721],[310.8,75.715],[310.806,75.721]],"c":true},"ix":2},"nm":"Path 8","mn":"ADBE Vector Shape - Group","hd":false},{"ind":8,"ty":"sh","ix":9,"ks":{"a":0,"k":{"i":[[0.01,0.008],[0,0],[-0.005,-0.005],[0.003,-0.003]],"o":[[0,0],[0.009,0.008],[0,0.003],[-0.008,-0.011]],"v":[[-185.481,178.021],[-185.478,178.021],[-185.455,178.05],[-185.458,178.055]],"c":true},"ix":2},"nm":"Path 9","mn":"ADBE Vector Shape - Group","hd":false},{"ind":9,"ty":"sh","ix":10,"ks":{"a":0,"k":{"i":[[-0.011,0.005],[0,-0.026],[0,0],[0,0],[0.011,0.018]],"o":[[0.003,0.023],[0,0],[0,0],[-0.012,-0.018],[0.008,-0.003]],"v":[[-99.502,344.448],[-99.498,344.516],[-99.498,344.516],[-99.498,344.516],[-99.533,344.462]],"c":true},"ix":2},"nm":"Path 10","mn":"ADBE Vector Shape - Group","hd":false},{"ind":10,"ty":"sh","ix":11,"ks":{"a":0,"k":{"i":[[-0.108,-0.217],[0.471,0.573],[0.233,0.213],[0.886,0.39],[1.429,-0.141],[-1.49,-0.653],[-0.849,-0.764],[-0.754,-0.144]],"o":[[-0.658,0.102],[-0.222,-0.274],[-0.911,-0.44],[-1.575,-0.307],[1.639,-1.078],[0.925,0.18],[0.707,0.344],[0.066,0.234]],"v":[[-49.604,-113.833],[-51.367,-114.558],[-52.056,-115.276],[-54.738,-116.618],[-59.361,-116.48],[-54.738,-116.618],[-52.056,-115.276],[-49.866,-114.513]],"c":true},"ix":2},"nm":"Path 11","mn":"ADBE Vector Shape - Group","hd":false},{"ind":11,"ty":"sh","ix":12,"ks":{"a":0,"k":{"i":[[0.139,-0.083],[-0.154,0.068]],"o":[[0.149,-0.083],[-0.154,0.074]],"v":[[-36.011,3.559],[-35.554,3.341]],"c":true},"ix":2},"nm":"Path 12","mn":"ADBE Vector Shape - Group","hd":false},{"ind":12,"ty":"sh","ix":13,"ks":{"a":0,"k":{"i":[[-0.061,0.01],[-0.003,-0.001],[0.066,-0.008]],"o":[[0.001,0],[-0.062,0.007],[0.06,-0.01]],"v":[[-32.657,-59.234],[-32.646,-59.228],[-32.83,-59.219]],"c":true},"ix":2},"nm":"Path 13","mn":"ADBE Vector Shape - Group","hd":false},{"ind":13,"ty":"sh","ix":14,"ks":{"a":0,"k":{"i":[[0.007,-0.003],[0.003,0.003],[0,0],[0,-0.005]],"o":[[-0.005,0],[0,0],[0.006,0.005],[-0.008,0.005]],"v":[[-27.527,88.936],[-27.538,88.93],[-27.511,88.902],[-27.503,88.918]],"c":true},"ix":2},"nm":"Path 14","mn":"ADBE Vector Shape - Group","hd":false},{"ind":14,"ty":"sh","ix":15,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.026,0],[0.032,-0.027],[-0.009,0.019]],"o":[[0,0],[0.011,0.016],[0.028,-0.003],[-0.032,0.019],[0.008,-0.019],[0,0]],"v":[[-28.811,89.04],[-28.811,89.037],[-28.785,89.077],[-28.707,89.071],[-28.813,89.129],[-28.785,89.077]],"c":true},"ix":2},"nm":"Path 15","mn":"ADBE Vector Shape - Group","hd":false},{"ind":15,"ty":"sh","ix":16,"ks":{"a":0,"k":{"i":[[-0.018,-0.001],[0,0],[0.008,-0.022],[0.008,0.026]],"o":[[0,0],[-0.01,0.023],[-0.008,-0.024],[0.013,0.003]],"v":[[-71.66,-97.691],[-71.66,-97.691],[-71.683,-97.626],[-71.704,-97.702]],"c":true},"ix":2},"nm":"Path 16","mn":"ADBE Vector Shape - Group","hd":false},{"ind":16,"ty":"sh","ix":17,"ks":{"a":0,"k":{"i":[[0.177,-0.039],[0.104,0.042],[-0.173,0.068],[0.008,0.013],[-0.158,-0.039],[-0.049,-0.084],[0.028,-0.003],[0.072,-0.023]],"o":[[-0.106,-0.045],[0.173,-0.042],[-0.005,-0.012],[-0.168,-0.31],[0.049,0.088],[-0.023,0.005],[-0.068,0.031],[0.043,0.123]],"v":[[-95.533,34.766],[-95.851,34.646],[-95.331,34.508],[-95.339,34.477],[-95.207,34.154],[-95.06,34.414],[-95.12,34.435],[-95.331,34.508]],"c":true},"ix":2},"nm":"Path 17","mn":"ADBE Vector Shape - Group","hd":false},{"ind":17,"ty":"sh","ix":18,"ks":{"a":0,"k":{"i":[[2.527,-1.28],[0.267,1.108],[-1.144,0.263],[-0.364,0.852],[-2.1,1.244],[0.589,-2.386]],"o":[[-0.267,-1.108],[1.143,-0.232],[0.871,-0.437],[2.811,1.19],[-2.084,1.297],[-2.77,-0.317]],"v":[[-47.475,12.071],[-48.274,8.747],[-44.841,7.984],[-42.88,6.145],[-36.207,3.677],[-39.671,9.604]],"c":true},"ix":2},"nm":"Path 18","mn":"ADBE Vector Shape - Group","hd":false},{"ind":18,"ty":"sh","ix":19,"ks":{"a":0,"k":{"i":[[2.326,-0.569],[2.464,5.289],[0.217,1.67],[2.272,3.953],[0.753,-0.057],[1.62,3.556],[-3.727,2.745],[-0.019,0.055],[-3.113,-1.19],[-7.056,-8.008],[-0.68,-1.657],[-1.373,-0.446],[-2.937,-5.949]],"o":[[-5.159,1.258],[0.677,-1.331],[1.93,-5.086],[-0.696,-0.516],[-0.023,-4.294],[-1.992,-4.385],[0.018,-0.055],[2.945,0.789],[-5.583,9.238],[1.164,1.323],[0.601,1.473],[1.77,6.553],[0.116,2.49]],"v":[[29.439,56.595],[15.329,48.478],[16.1,44.011],[12.809,31.195],[10.654,30.33],[5.95,19.415],[7.881,9.355],[7.94,9.19],[16.648,7.13],[18.286,26.251],[21.18,30.589],[24.056,33.625],[32.894,51.476]],"c":true},"ix":2},"nm":"Path 19","mn":"ADBE Vector Shape - Group","hd":false},{"ind":19,"ty":"sh","ix":20,"ks":{"a":0,"k":{"i":[[5.909,-2.578],[3.184,-1.656],[1.664,2.897],[-0.902,1.963],[-0.374,0.81],[1.932,1.4],[-0.264,0.271],[-0.182,0.508],[-0.199,0.865],[-0.735,1.217],[-3.293,-2.581],[-0.175,-0.065],[0.022,-0.177],[-0.563,-0.414],[0,0],[0,0],[0.13,-0.341],[-4.339,3.307],[-0.043,-0.065],[-0.673,0.646],[-2.567,-1.178],[-1.068,-0.649],[-4.329,-5.037],[0.253,-0.693],[1.165,-0.428],[4.804,2.149]],"o":[[-3.267,1.461],[-2.478,0.014],[-0.906,-1.966],[0.378,-0.81],[0.815,-1.729],[0.265,-0.276],[0.376,-0.456],[0.515,-0.565],[1.999,0.942],[2.131,-3.532],[0.183,0.054],[-0.024,0.175],[0.566,0.412],[0,0],[0,0],[-0.064,0.362],[3.166,6.834],[0.039,0.065],[0.826,0.393],[2.638,-1.45],[0.697,0.802],[5.652,3.444],[-0.038,0.57],[-1.22,0.085],[-5.069,0.609],[-5.562,-2.485]],"v":[[-56.802,30.617],[-66.388,35.498],[-72.809,31.836],[-72.809,25.944],[-71.683,23.515],[-71.995,18.663],[-71.198,17.84],[-70.361,16.393],[-69.309,14.232],[-66.234,11.502],[-58.273,9.815],[-57.734,9.993],[-57.803,10.521],[-56.109,11.761],[-56.107,11.761],[-56.107,11.761],[-56.396,12.813],[-48.462,16.592],[-48.356,16.782],[-46.108,16.444],[-38.561,16.483],[-35.892,18.647],[-20.681,31.097],[-21.129,32.987],[-24.742,33.5],[-39.374,31.275]],"c":true},"ix":2},"nm":"Path 20","mn":"ADBE Vector Shape - Group","hd":false},{"ind":20,"ty":"sh","ix":21,"ks":{"a":0,"k":{"i":[[0.099,-0.104],[-0.362,0.765],[-0.715,2.416],[-0.046,0.421],[0.588,1.469],[-0.808,-0.642],[-0.022,-0.167],[-0.02,-0.056],[0.441,-1.194],[0.066,-0.215],[1.086,-2.298],[0.608,-0.708]],"o":[[0.574,-0.674],[0.945,-2.377],[0.042,-0.429],[0.221,-2.034],[0.466,0.589],[0.02,0.169],[0.019,0.057],[-0.771,0.922],[-0.076,0.21],[-0.241,2.527],[-0.316,0.793],[-0.088,0.088]],"v":[[61.858,-136.661],[63.232,-138.833],[64.818,-146.287],[64.948,-147.562],[64.345,-152.843],[66.262,-151.002],[66.323,-150.499],[66.373,-150.333],[65.031,-146.926],[64.818,-146.287],[63.232,-138.833],[61.882,-136.571]],"c":true},"ix":2},"nm":"Path 21","mn":"ADBE Vector Shape - Group","hd":false},{"ind":21,"ty":"sh","ix":22,"ks":{"a":0,"k":{"i":[[-0.807,-3.649],[-1.399,-4.245],[-0.712,-1.1],[0.574,-4.915],[-1.324,-0.956],[-0.976,-0.487],[-1.391,-1.193],[-0.225,-0.16],[-1.304,-1.701],[0,0],[0.001,-0.076],[-0.242,-1.433],[-0.488,-0.288],[-0.344,-0.125],[-5.449,-1.576],[0.567,1.506],[-0.028,0.956],[0,0],[1.128,-0.037],[1.167,2.823],[1.564,1.207],[0,0],[2.28,1.802],[-0.023,0.184],[1.901,2.264],[-1.429,3.142],[0.034,0.295],[-0.226,0.122],[-0.261,0.559],[-0.265,1.487],[-0.138,0.074],[-0.321,-0.539],[-0.542,-0.24],[-1.567,-0.244],[-3.629,-3.523],[-0.072,-1.182],[-0.573,0.325],[-0.108,0.118],[-1.744,0.383],[-0.022,1.913],[0.944,10.711],[0.494,0.431],[-0.004,0.394],[0,0],[3.534,2.829],[0.348,3.396],[-1.645,2.172],[0.111,1.036],[-0.474,0.199],[-2.643,-3.472],[-1.381,1.467],[-1.609,0.758],[-0.494,0.226],[-1.618,1.036],[-1.691,0.232],[-4.585,5.144],[-2.095,3.047],[-1.703,3.467],[2.53,4.066],[0.073,1.768],[0.241,1.242],[-0.012,0.817],[0.119,-0.008],[0.012,0.325],[1.752,3.587],[2.276,-0.336],[0,0],[-1.448,1.813],[-3.936,0.745],[0.037,1.759],[1.407,0.049],[4.088,-3.545],[1.492,1.274],[-0.956,0.748],[-4.453,1.698],[-1.905,-1.334],[-1.262,0.226],[-2.595,2.039],[-0.089,-0.12],[-0.187,-2.248],[-4.186,1.261],[-0.481,0.454],[2.348,-3.207],[0.291,-2.826],[-2.102,-0.682],[-0.925,2.14],[0.034,0.301],[-0.157,0.107],[0.655,4.438],[0,0],[0,0],[-0.295,0.011],[0.206,0.516],[0.436,1.109],[0.381,0.562],[-0.079,0.077],[0.494,0.466],[0,0],[2.941,0.883],[0,0],[0.55,0.742],[0.449,0.945],[0.45,0.341],[0.123,0.107],[-0.752,2.795],[0.115,0.102],[-0.004,1.839],[-6.347,0.454],[-0.5,5.495],[-0.636,1.477],[1.678,14.476],[0.21,0.594],[1.433,4.343],[-0.033,-0.052],[-1.319,-0.896],[-0.318,-0.118],[-3.097,-3.1],[0.16,-0.314],[0.435,-3.068],[-0.234,-0.526],[-1.862,-1.808],[-0.256,-0.096],[-0.413,1.41],[-1.774,-1.653],[-0.273,0.028],[0.221,1.591],[1.523,0.626],[1.647,3.857],[0.068,0.357],[0,0],[-0.001,0],[-0.516,0.301],[0.98,2.026],[3.138,9.498],[1.829,1.555],[0.385,1.163],[-1.003,-2.729],[-0.802,-0.018],[0.309,-1.326],[2.995,1.481],[1.842,-0.764],[1.215,-0.798],[0.371,-0.257],[-0.156,2.279],[-0.455,1.075],[0.318,0.153],[0.737,-1.357],[0.173,-0.175],[0.064,0.054],[-0.409,2.177],[-1.16,7.173],[-10.416,2.261],[-0.157,0.225],[-0.409,0.379],[-0.754,0.276],[-0.772,1.35],[-0.404,0.459],[-3.725,-1.453],[-0.963,-0.196],[-2.554,0.386],[-2.512,-0.18],[0,0],[-0.103,-0.337],[0,0],[0,0],[5.675,0.762],[0.141,1.23],[-0.042,0.345],[-0.023,0.066],[-0.127,2.156],[0.139,1.649],[0.045,0.218],[-0.007,0.152],[-0.628,1.479],[-3.273,-1.667],[-0.608,-0.663],[-1.526,-0.271],[-0.238,1.242],[-0.576,0.645],[-0.571,1.301],[-0.937,0],[0.035,-0.394],[0.477,-1.395],[0.692,-7.284],[3.383,-3.274],[-0.008,-0.259],[1.077,-2.578],[-0.994,-3.453],[-2.554,-4.171],[-4.011,-6.665],[-2.329,0.473],[-0.402,2.133],[-1.285,3.606],[2.779,2.398],[0,0],[-3.205,1.714],[1.959,2.708],[-4.146,3.303],[-0.036,0.854],[1.383,0.15],[0.003,0],[0,0],[-0.8,3.858],[3.93,-1.915],[0,0],[0.099,2.058],[1.051,3.217],[-2.828,1.427],[-0.088,0.126],[-0.445,-0.233],[-0.501,1.487],[-0.647,-0.008],[-1.014,-0.041],[0,1.133],[0,0],[-5.72,-3.465],[-1.605,0.334],[-7.3,9.258],[-0.962,3.635],[2.918,1.709],[1.587,2.631],[0.198,0.533],[-1.481,3.857],[0.004,0],[6.409,5.404],[-1.336,1.748],[-0.94,-0.585],[-1.793,0.026],[-4.432,-1.916],[-3.111,1.82],[0,0],[-1.083,0.868],[0.111,1.519],[1.449,0.421],[0.177,0.118],[3.01,1.369],[0.003,0],[-0.234,1.397],[2.631,2.707],[0,0],[3.541,0.288],[0,0],[2.336,0.708],[0.968,-2.901],[1.135,0.421],[2.135,-2.58],[-0.004,-0.001],[0,0],[2.543,0.326],[4.76,1.236],[8.932,-4.175],[2.573,0.688],[-2.045,-2.011],[1.722,-3.863],[3.49,2.098],[0.367,0.509],[3.797,-1.129],[-0.148,-0.374],[0.056,-0.05],[4.058,-0.097],[1.693,-1.355],[-0.024,0.009],[0,0],[-0.007,0.004],[1.572,-1.174],[2.631,4.89],[1.209,0.712],[0.368,0.404],[5.423,-4.199],[4.473,5.058],[0.917,2.928],[4.796,-2.159],[0,0],[1.188,-0.149],[2.914,-1.374],[0,0],[0.232,-7.153],[-0.2,-2.077],[-1.086,0.643],[0,0],[8.845,-2.674],[1.904,-0.299],[0,0],[1.307,-0.301],[2.544,-0.594],[0.144,-0.096],[0.517,-0.431],[-0.536,-0.766],[0.05,-0.423],[-0.904,-2.237],[5.945,1.767],[0.061,0.605],[-0.043,1.693],[2.113,0.255],[0,0],[0.198,0.322],[0.746,1.479],[4.325,-4.347],[0,0],[1.836,-0.004],[-0.727,-3.593],[3.027,-1.448],[3.553,3.098],[0.493,-0.046],[0.849,0.142],[0.326,0.133],[0.053,1.991],[4.274,-0.78],[4.132,1.378],[-0.536,-4.567],[-0.29,-0.767],[-0.003,0],[0,0],[3.996,-0.186],[0.315,0.414],[0,0],[0,0],[-3.008,9.428],[1.148,1.272],[0.091,0.375],[0,0],[5.807,2.783],[0,0],[1.521,-0.827],[0.849,-0.585],[0,0.001],[1.58,0.315],[0,0],[0,0],[0.666,-0.16],[0.425,5.946],[2.108,0.173],[0.414,-1.815],[-3.724,-3.965],[-0.015,-1.228],[-0.003,0],[0,-0.001],[0.815,-0.054],[0.223,-0.704],[0.145,-0.395],[0,0],[0.473,-0.39],[0,-0.001],[3.005,5.111],[2.046,-2.306],[0.12,-1.464],[0,-0.001],[1.721,-1.511],[0.244,-7.916],[-1.098,-0.38],[0,0],[-0.819,-0.459],[0,0],[0.626,-1.522],[0.753,-0.077],[3.687,-1.093],[-1.315,-3.533],[-3.709,-3.07],[1.674,-0.108],[0.233,0.088],[4.429,-1.278],[1.303,0.096],[-1.693,-1.484],[0.779,-0.45],[0.008,-0.386],[0,0],[0.001,-0.001],[0.099,0.103],[1.11,0.394],[0.498,0.773],[0.854,-1.8],[0,0],[0.328,-0.019],[-3.225,-3.158],[-0.18,-0.222],[0.213,0.127],[0.777,5.163],[0.739,0.821],[2.91,-0.412],[-0.232,-1.848],[-0.031,-0.387],[-0.19,-0.971],[-0.047,-0.918],[0.479,-2.657],[0.026,-0.062],[-0.034,-0.596],[0.087,-1.224],[-0.161,-2.433],[-3.579,-1.731],[-0.008,-0.007],[4.74,2.206],[2.811,-1.406],[2.251,2.689],[-2.283,-1.541],[-1.921,-1.075],[-0.176,-0.329],[4.599,1.297],[0.514,-0.257],[0.374,-0.222],[0.594,0.005],[1.697,0.976],[3.425,-1.782],[0.552,-0.588],[0.598,-0.275],[0.344,-0.44],[0.176,-0.406],[0.603,-0.371],[0.753,-0.423],[0.711,-1.93],[1.805,1.021],[-0.329,1.628],[0.003,0],[0,0],[0,0],[4.402,-0.418],[-0.915,-3.134],[-0.222,-1.58],[-0.355,-0.456],[-0.031,-0.039],[0.032,-0.042],[-0.362,-0.325],[2.386,0.054],[0.202,4.087],[1.618,0.813],[0.038,-0.015],[0.088,0.073],[0.563,0.596],[3.483,3.1],[5.932,-0.571],[2.164,6.149],[0,0],[5.104,-1.989],[3.096,-3.499],[0,0],[0.003,-0.003],[0,0],[0.502,-0.301],[0.5,-0.32],[1.406,-0.279],[3.074,-1.634],[0.692,-0.741],[1.033,-1.301],[1.362,-0.229],[-1.106,-3.477],[-0.085,-0.638],[-0.171,-1.009],[1.637,-1.047],[-0.726,-1.198],[-0.114,-0.077],[0,0],[0.232,-0.121],[4.607,-3.434],[0.623,-1.28],[4.335,-3.542],[-2.306,-6.346],[0.118,-3.965],[-6.062,1.783],[-2.539,2.613],[-0.852,-2.71],[-1.636,-0.779],[-0.023,-0.077],[-0.211,-0.539],[-0.36,-0.589],[0.027,-0.6],[1.099,-1.086],[0.45,0.129],[0.214,-0.073],[-0.062,0.219],[0.978,3.047],[2.007,-0.479],[-2.674,-5.847],[-0.013,-0.024],[0.165,-0.015],[-0.932,-1.477],[0,0],[-0.053,-0.49],[0.861,-0.844],[0.232,-0.081],[2.007,-6.069],[4.382,-0.961],[-0.67,1.652],[2.31,1.293],[1.124,0.624],[0.034,0.416],[1.816,1.239],[0,0],[-0.018,5.31],[2.886,3.173],[3.522,-1.743],[-1.205,-4.66],[7.166,-1.587],[0.175,-0.352],[1.171,-1.189],[0.05,-2.841],[1.354,-2.295],[0,0],[-4.268,-0.781],[-1.533,0.062],[-2.05,0.853],[2.354,4.06],[-0.175,1.686],[-1.682,1.351],[-0.066,0.186],[-0.543,-0.26],[-0.003,0.004],[-0.795,-0.746],[0,0],[0.716,0.011],[-0.188,-0.41],[0.853,-0.891],[0.443,-0.542],[-1.067,-1.102],[0,0],[0,-0.001],[-0.095,-0.083],[0.035,-0.037],[0.103,-0.619],[0.003,-0.362],[-0.418,-1.909],[-0.666,0.028],[0.005,-2.014],[1.075,-0.754],[-1.324,-0.252],[-0.385,-0.406],[-1.119,0.164],[-1.04,0.295],[-1.209,0.497],[1.471,-0.416],[1.089,-0.164],[0.542,-1.487],[0.02,-0.387],[0,0],[-1.132,-2.378],[-0.822,0.273],[-0.769,-0.039],[2.497,-5.881],[0,0],[2.819,0.482],[6.447,0.176],[-1.251,-4.047],[1.102,-3.372],[-0.914,-1.467],[0.638,-0.039],[0.023,-0.367],[-0.749,-1.596],[-2.684,-1.477],[-1.556,-0.367],[-0.742,-3.18],[0,0],[0,0],[0.042,-1.171],[-0.035,-0.275],[0.26,-0.257],[1.905,-0.753],[0.585,-5.937],[6.563,-2.544],[-1.393,-2.279],[0.963,-4.657],[0,0],[0.13,-0.689],[3.496,-3.12],[-0.865,-1.743],[-0.36,-0.398],[-0.378,-0.042],[-0.02,-0.226],[1.328,-5.318],[-0.104,-0.467],[-2.127,-4.531],[-0.15,-0.902],[0.046,-0.305],[-0.813,-1.007],[0,0],[-0.012,-0.84],[-2.218,0.014],[-3.677,-2.576],[-0.043,-1.156],[-0.393,-0.383],[-0.032,-0.44],[0,0],[-3.647,-0.956],[-0.406,-0.191],[-1.564,-0.776],[0,0],[0,0],[-2.168,-1.323],[0,0],[0,0],[-2.112,1.077],[-6.09,-1.156],[0,0.003],[-3.942,2.565],[-5.958,-2.25],[0,0],[-0.417,-0.821],[-0.558,-1.074],[0,0],[-3.955,1.005],[0,0],[-1.081,-0.417],[0.527,-3.766],[-0.007,-0.037],[0.336,-0.533],[0.107,-0.81],[-0.481,-0.02],[-8.822,-5.763],[-0.367,-0.445],[0,-0.003],[-0.248,-0.293],[-0.005,0],[0,-0.003],[-0.146,-0.737],[-0.624,-0.409],[0,0.003],[0,0],[-2.14,-1.82],[0,0],[-2.1,-5.427],[2.349,-2.341],[0.248,-7.189],[-1.485,-2.547],[-0.937,-7.016],[-7.77,-8.623],[-0.072,0.2],[0,0],[-0.115,-0.034],[0.153,-0.184],[0.11,-6.744],[-5.36,1.089],[-4.519,-0.471],[-5.621,4.118],[-6.52,6.975],[0.519,2.934],[-1.044,2.412],[-1.958,3.579],[2.299,3.839],[0,0],[0.135,0.386],[-0.349,1.779],[0.003,-0.003],[0,0],[-2.563,2.07],[-0.802,1.649],[0,0],[-0.543,0.539],[0,0],[0,0],[-0.012,8.503],[-0.143,3.72],[2.318,1.334],[1.289,4.305],[-1.801,4.037],[-2.455,4.425],[0,0],[-0.08,0.375],[-7.348,2.897],[-0.799,0.691],[0.429,0.527],[-0.119,0.221],[-0.364,0.122],[-0.389,0.397],[-0.668,0.699],[-0.326,0.042],[-1.063,1.693],[-0.446,-0.028],[-1.578,3.54],[0.19,0.333],[-0.142,0.104],[-0.859,2.714],[2.191,3.19],[3.073,-0.214],[8.345,2.373],[-0.03,0.245],[0.284,0.313],[-1.569,0.706],[-1.811,0.465],[-3.954,1.993],[-0.031,2.841],[0.064,0.157],[0.06,0.078],[0,0],[0.018,0.007],[0.009,0.015],[0,0.034],[-0.064,-0.164],[-0.225,-0.16],[-3.523,1.915],[-2.237,2.331],[0,0],[-3.515,3.336],[-2.133,0.825],[-2.066,2.378],[6.161,6.603],[-0.004,0.003],[2.574,0.485],[1.231,1.969],[0,0],[0,0],[-0.061,0.428],[2.194,0.497],[0.241,-1.066],[0,0],[1.476,-1.308],[0.424,-1.139],[1.128,-0.46],[2.802,1.816],[0,0],[0.391,1.597],[0,0],[-0.362,0.364],[1.324,0.192],[0.238,-0.872],[0.929,0.548],[3.346,1.774],[0,0],[0.857,1.559],[1.077,0.922],[0,0],[0,0.003],[-0.309,1.06],[-0.789,-0.013],[-1.383,-2.205],[-3.67,-2.813],[-0.879,-0.224],[-1.113,-0.167],[-1.492,0.362],[-1.147,-0.37],[-1.885,-1.339],[-6.972,1.368],[-0.627,-0.474],[-1.556,0.046],[-4.902,-7.687],[-1.555,1.15],[-1.11,-2.922],[-7.365,2.975],[-0.408,-1.495],[-0.819,-2.513],[-6.512,-14.625],[-3.354,2.93],[-1.301,3.18],[-0.007,0.054],[-0.141,1.503],[-6.411,8.54],[-1.373,1.354],[-9.085,3.303],[-1.471,-0.046],[-2.227,0.055],[-1.647,-1.794],[0.52,-8.358],[-0.764,-0.62],[-2.417,0.857]],"o":[[0.984,4.44],[0.58,1.308],[-0.074,4.942],[0.037,1.676],[0.967,0.513],[0.808,1.69],[0.229,0.158],[0.378,2.02],[0,0],[-0.005,0.077],[-2.261,1.018],[0.019,0.576],[0.362,0.073],[3.352,4.434],[1.514,-1.515],[0.031,-0.956],[0,0],[-0.539,-0.895],[-0.289,-2.962],[-1.564,-1.208],[0,0],[-2.276,-1.806],[0.033,-0.169],[0.245,-3.384],[-2.322,-2.753],[-0.032,-0.297],[0.207,-0.096],[0.471,-0.383],[0.707,-1.378],[0.118,-0.099],[0.326,0.544],[0.419,0.42],[1.517,0.547],[3.625,3.522],[0.074,1.185],[0.475,0.46],[0.141,-0.115],[2.095,0.589],[0.578,-1.575],[9.253,-2.987],[-0.49,-0.425],[0.003,-0.393],[0,0],[-0.169,-4.948],[-5.716,-4.578],[1.175,-2.458],[0.678,-0.742],[0.422,0.37],[3.704,-1.555],[1.196,1.574],[1.173,-1.246],[0.517,-0.156],[1.625,-1.032],[1.393,-1.125],[7.145,-0.984],[2.593,-2.914],[1.104,-3.758],[1.94,-3.942],[-0.964,-1.549],[-0.603,-1.159],[0.011,-0.815],[-0.118,0.007],[-0.024,-0.328],[-1.942,-3.383],[-0.98,-2.011],[0,0],[-1.085,-1.504],[2.144,-2.693],[1.741,-0.326],[-0.03,-1.513],[-3.783,-0.127],[-1.72,1.49],[-1.089,-0.932],[3.352,-2.615],[1.07,1.919],[0.963,0.727],[2.681,-1.848],[0.091,0.12],[2.146,1.713],[0.338,4.076],[0.57,-0.345],[2.06,1.461],[-0.111,2.761],[-0.213,2.061],[2.127,0.695],[0.064,-0.329],[0.183,-0.019],[5.282,1.337],[0,0],[0,0],[0.288,0.064],[-0.207,-0.519],[-0.436,-1.114],[-0.379,-0.562],[0.079,-0.07],[0.363,-0.581],[0,0],[-0.138,-3.06],[0,0],[-0.139,-1.167],[-0.41,-0.971],[-0.325,-0.46],[-0.129,-0.096],[1.185,-2.555],[-0.118,-0.099],[1.205,-1.25],[0.008,-6.589],[4.872,-0.352],[1.53,-0.149],[5.575,-12.967],[-0.036,-0.63],[-3.716,-3.586],[0.034,0.05],[0.938,1.33],[0.303,0.158],[-0.696,4.539],[-0.2,0.234],[-0.546,3.089],[0.095,0.565],[1.018,2.29],[0.26,0.093],[0.758,0.237],[1.238,-4.213],[0.273,0.005],[2.053,-2.202],[-0.961,-1.255],[-4.443,-2.826],[0.073,-0.357],[0,0],[0,0],[0.515,-0.301],[1.232,-0.058],[-4.443,-8.767],[0.259,-2.876],[-0.383,-1.162],[-1.508,-0.024],[0.506,0.559],[-0.844,0.947],[-2.217,-2.528],[-1.935,-0.52],[-1.166,0.891],[-0.401,0.195],[-1.097,-1.567],[0.894,0.039],[0.15,-0.356],[-1.354,-0.666],[-0.171,0.175],[-0.062,-0.054],[-2.206,-2.153],[1.346,-7.131],[1.781,-11.005],[0.154,-0.229],[0.19,-0.831],[0.775,-0.227],[1.661,-0.062],[0.357,-0.626],[3.398,-2.008],[0.903,0.429],[-0.614,1.086],[2.301,-0.349],[0,0],[0.064,0.348],[0,0],[0,0],[-0.567,-1.456],[-1.441,-0.551],[0.024,-0.348],[0.018,-0.065],[0.764,-2.083],[0.28,-1.61],[-0.064,-0.229],[0.007,-0.154],[1.037,-1.208],[2.854,-2.267],[0.796,0.995],[0.755,1.617],[1.632,0.288],[0.47,-0.462],[0.049,-1.381],[0.538,-0.607],[0.018,0.38],[0.104,1.359],[-2.435,7.094],[-0.456,4.803],[0.133,0.219],[3.138,1.162],[-1.495,3.584],[1.379,4.784],[4.062,6.633],[0.967,1.609],[2.196,-0.447],[0.668,-3.554],[3.108,-0.845],[0,0],[-0.364,-3.098],[4.685,-2.508],[-2.072,-2.863],[0.773,0.414],[0.045,-1.12],[0,0],[0,0],[-0.129,-3.299],[1.016,-4.535],[0,0],[-2.5,-0.971],[-0.158,-3.334],[-1.095,-2.596],[0.092,-0.122],[0.44,0.234],[0.5,-1.486],[0.647,0.008],[0.031,0.961],[1.613,0.061],[0,0],[3.695,-5.842],[1.338,0.808],[-1.844,-12.259],[2.305,-0.913],[1.017,-3.831],[-2.762,-1.617],[-0.198,-0.532],[-0.947,-2.191],[0,0],[2.676,-8.425],[-1.534,-1.295],[1.98,-2.59],[1.483,0.93],[0.856,-3.014],[2.288,3.866],[0.003,0],[1.117,0.945],[1.281,0.026],[-0.137,-1.934],[-0.059,-0.209],[0.473,-3.013],[0,0],[-0.662,-1.07],[2.552,-1.621],[0,0],[0.687,-3.859],[0,0],[-2.339,-0.71],[-1.1,2.768],[-1.135,-0.422],[-1.926,-0.672],[0,0.001],[0,0],[-1.894,-2.589],[-4.916,-0.628],[-8.887,-2.306],[-2.232,1.045],[-4.148,3.717],[2.307,2.271],[-2.949,-2.994],[-0.395,-0.421],[-0.027,-2.061],[0.146,0.372],[-0.053,0.045],[-0.429,3.789],[-1.785,0.042],[0.024,-0.011],[0,0],[0.007,-0.005],[-1.748,0.757],[-4.593,3.442],[-0.678,-1.258],[-0.371,-0.404],[-6.569,-3.724],[-5.285,4.092],[-3.802,1.87],[-2.741,-8.755],[0,0],[-1.186,0.15],[-3.016,-0.561],[0,0],[-3.005,1.273],[-1.383,0.502],[0.118,1.179],[0,0.001],[1.054,3.257],[-1.892,0.303],[0.003,0.001],[-1.304,0.301],[-1.73,3.231],[-0.15,0.088],[-0.538,-0.515],[-1.005,0.837],[-0.148,0.347],[0.613,2.295],[-6.488,-0.5],[-0.058,-0.607],[1.068,0.295],[0.06,-2.257],[0,0],[-0.045,-0.379],[-0.746,-1.477],[-3.357,-1.633],[0,0.001],[-1.839,-0.552],[-2.287,0.007],[0.328,1.628],[-2.963,1.42],[-0.497,0.05],[-1.358,0.688],[-0.326,-0.142],[-0.869,-0.659],[-4.274,0.781],[-3.43,3.203],[-2.733,-0.911],[0.288,0.768],[0,0],[-0.003,0.001],[-1.655,3.039],[-0.315,-0.412],[0,0.001],[0,0],[3.709,-9.216],[-1.147,-1.273],[0.047,-0.383],[0,0],[-4.16,-5.358],[0,0],[-1.368,1.16],[-0.848,0.588],[0,0],[-2.903,1.427],[0,0],[0,0],[-0.738,-0.156],[-3.048,0.726],[-0.154,-2.167],[-2.164,-0.179],[-1.078,4.685],[0.018,1.231],[0,0],[0,0],[-0.812,0.055],[-0.221,0.703],[-0.144,0.394],[0,0],[-0.468,0.39],[0,0],[-1.885,1.469],[-0.594,-1.013],[-0.93,0.116],[0,0],[-1.052,2.325],[-5.204,4.562],[1.096,0.382],[0,0],[0.821,0.46],[0,0],[0.781,1.063],[-0.754,0.081],[-2.994,2.692],[-3.403,1.009],[1.988,5.331],[0.356,3.037],[-0.225,-0.095],[-3.375,-2.238],[-0.081,-1.461],[-0.917,1.473],[-0.779,0.451],[-0.008,0.383],[0,-0.001],[0,0.003],[-0.1,-0.104],[-1.109,-0.394],[-0.5,-0.773],[-0.248,2.095],[0,0],[-0.33,0.055],[-1.388,3.817],[0.207,0.207],[-0.157,-0.161],[-5.112,-3.063],[-0.482,-1.06],[-2.123,-2.367],[-1.517,0.214],[0.049,0.389],[-0.487,0.707],[0.188,0.945],[-0.299,2.683],[-0.024,0.062],[-0.222,0.562],[-0.19,1.212],[1.014,2.088],[0.261,4.064],[0.038,0.023],[-4.756,-2.149],[-3.035,-0.129],[-3.07,-0.611],[-2.849,1.458],[1.819,1.227],[-0.024,0.355],[2.321,4.378],[-0.532,-0.149],[-0.376,0.206],[-0.595,-0.004],[-2.572,0.621],[-4.622,-2.665],[-0.55,0.589],[-0.657,0.177],[-0.494,0.247],[-0.047,0.508],[-0.6,0.37],[-0.75,0.423],[-2.163,0.815],[-0.917,1.139],[-1.997,-1.125],[-0.003,0],[0,0],[0,0],[-0.163,-5.221],[-5.174,0.489],[0.437,1.504],[0.165,0.562],[0.03,0.039],[-0.031,0.036],[-0.176,0.236],[0.869,2.011],[-1.862,-0.042],[1.155,-2.049],[-0.035,0.016],[-0.085,-0.073],[0.294,-0.654],[-2.693,-4.264],[-4.302,-3.831],[-4.955,-1.649],[0,0],[-4.534,-1.468],[-3.613,-0.952],[0.003,0],[0,0],[0,0],[-0.479,0.34],[-0.509,0.305],[-1.292,0.623],[-2.137,3.555],[-0.787,0.612],[-1.36,0.989],[-0.994,0.733],[-3.112,1.839],[0.221,0.687],[-0.248,0.96],[-0.433,1.449],[-0.955,0.982],[0.116,0.104],[0,0],[-0.234,0.12],[-3.733,3.916],[-0.83,1.062],[-2.229,5.637],[-6.772,4.607],[1.393,3.833],[-0.19,6.431],[3.538,-1.04],[-0.251,2.845],[0.872,1.664],[0.026,0.076],[0.095,0.571],[0.44,0.737],[-0.027,0.6],[-1.606,0.055],[-0.424,0.031],[-0.242,0.024],[0.047,-0.222],[2.592,-3.151],[-0.58,-1.809],[-5.762,1.369],[0.015,0.024],[-0.152,0.004],[-1.101,1.637],[0,0],[0.394,0.665],[-0.592,1.035],[-0.218,0.088],[-4.525,2.114],[-1.553,4.714],[-1.025,-1.766],[0.917,-2.24],[-0.848,-1.362],[-0.035,-0.414],[1.786,-2.123],[0,0],[-2.966,-4.348],[0.018,-4.337],[-1.815,-1.996],[-3.553,1.755],[1.79,6.902],[-0.233,0.052],[-1.17,1.189],[-2.612,0.598],[-0.045,2.305],[0,0],[-2.177,4.494],[1.583,0.288],[1.819,-1.555],[3.328,-1.381],[2.387,0.108],[0.245,-2.391],[0.095,-0.177],[0.542,0.259],[0,0],[0.795,0.746],[0,0],[-0.711,-0.012],[0.187,0.409],[-1.169,0.38],[-0.441,0.54],[-1.46,1.144],[0,0],[0,0],[0.089,0.081],[-0.038,0.035],[-0.357,0.506],[-0.007,0.361],[-1.121,0.443],[0.668,-0.029],[0.84,2.148],[-1.078,0.753],[-1.036,2.6],[0.389,0.409],[1.311,0.597],[0.953,-0.516],[1.311,-0.687],[-0.876,1.154],[-0.967,0.508],[-1.066,0.573],[-0.034,0.38],[0,0],[-1.591,2.443],[0.819,0.635],[0.657,0.404],[6.836,5.625],[0,0],[-0.976,4.439],[-6.428,-1.097],[-2.947,2.716],[1.078,3.487],[-0.309,1.616],[-0.632,0.039],[-0.003,0.37],[0.749,1.597],[-2.152,2.546],[1.559,0.366],[3.106,0.139],[0,0],[0,0],[-0.042,1.169],[0.039,0.272],[-0.181,0.303],[-0.534,2.095],[-6.014,2.378],[-0.777,7.968],[-2.39,0.925],[-3.327,2.883],[-0.003,0],[-0.133,0.685],[-5.143,1.824],[-0.506,1.477],[0.357,0.398],[0.32,0.385],[0.02,0.21],[-0.909,5.349],[-0.008,0.498],[-1.266,3.893],[0.84,0.894],[0,0.311],[-0.894,1.571],[0,0],[0.01,0.834],[2.213,-0.019],[2.57,3.732],[0.045,1.159],[0.394,0.384],[0.035,0.437],[0,0],[0.959,4.183],[0.41,0.195],[0.34,2.096],[0,0],[0,0],[1.342,2.433],[0,0],[0,0],[2.065,1.831],[5.689,-2.906],[0,-0.003],[5.018,2.107],[5.7,-1.661],[0.003,0],[0.414,0.821],[0.556,1.075],[0.003,0],[3.458,4.672],[0,0],[0.247,1.304],[3.689,1.427],[0.011,0.037],[-0.49,0.156],[-0.103,0.803],[0.481,0.02],[-4.014,10.272],[0.364,0.445],[0,0.003],[0.081,0.385],[0,0],[-0.005,0],[0.145,0.742],[0.625,0.412],[0,0],[0,0.003],[-0.632,2.68],[0,0],[0.83,5.626],[1.156,2.993],[-5.352,5.334],[-0.845,2.898],[3.532,6.047],[1.476,11.017],[0.005,-0.221],[0,0],[0.116,0.039],[-0.154,0.18],[0.742,6.314],[-0.088,5.323],[4.299,-0.88],[7.104,0.739],[7.839,-5.74],[1.797,-1.927],[1.031,-2.408],[4.089,-0.666],[1.882,-4.188],[0,0.003],[-0.137,-0.387],[0.349,-1.778],[-0.003,0],[0,0],[2.559,-2.073],[1.877,-0.229],[0,0],[0.54,-0.539],[0,-0.003],[0,0],[8.484,-2.425],[0.009,-3.722],[0.102,-2.534],[-1.117,-4.601],[-1.48,-4.953],[2.18,-4.886],[0,0],[0.249,-0.283],[5.981,-4.604],[0.796,-0.691],[0.387,-0.584],[0.119,-0.229],[0.358,-0.045],[0.504,-0.219],[0.825,-0.576],[0.302,-0.15],[1.06,-1.69],[0.447,0.028],[1.58,-3.541],[0.311,-0.427],[0.126,-0.122],[1.096,-2.534],[1.07,-3.385],[-2.448,-3.556],[-8.042,0.554],[0.047,-0.078],[0.045,-0.352],[-0.349,-2.62],[1.16,-0.11],[4.107,-1.521],[1.825,-0.919],[-0.053,-0.186],[-0.057,-0.082],[0.012,-0.01],[-0.016,-0.011],[-0.008,-0.013],[-0.003,-0.031],[0.076,0.141],[0.175,0.228],[4.206,0.723],[1.966,-2.576],[0,0],[5.106,-0.628],[2.73,0.635],[0.998,-2.618],[5.693,-6.539],[0,0],[-2.578,-0.488],[-1.234,-1.974],[0,0],[0,0],[0.062,-0.435],[-0.413,-1.453],[-0.925,-0.209],[0,0],[-1.473,1.305],[-0.423,1.143],[-1.125,0.46],[-2.944,-1.278],[0,-0.003],[-0.389,-1.594],[0,0],[0.363,-0.367],[-0.364,-1.274],[-0.229,0.875],[-0.928,-0.552],[-0.387,-3.802],[0,0],[-0.861,-1.56],[-0.149,-1.332],[0,0],[0,0],[0.301,-1.059],[0.88,-0.181],[2.278,0.719],[2.566,4.087],[0.669,0.62],[1.067,0.42],[1.397,0.654],[1.182,0.138],[2.635,-0.482],[6.011,4.279],[0.019,0.727],[1.473,0.708],[6.676,-0.789],[0.956,1.5],[0.199,3.366],[2.906,7.61],[2.91,0.05],[0.096,2.531],[4.975,15.332],[1.85,4.153],[2.46,-2.148],[0.006,-0.05],[1.077,-0.443],[0.955,-10.279],[1.416,-1.312],[6.658,-6.57],[1.327,0.691],[2.164,-1.067],[-0.642,2.758],[5.074,5.534],[-0.061,0.951],[2.481,1.104],[3.277,-1.159]],"v":[[229.306,161.004],[234.246,173.453],[235.961,177.415],[234.814,192.198],[236.897,196.127],[239.817,197.622],[243.442,201.67],[244.115,202.155],[246.197,207.887],[246.197,207.889],[246.201,208.121],[245.658,212.21],[246.404,213.515],[247.459,213.814],[260.108,223.578],[260.093,219.049],[260.181,216.177],[260.18,216.158],[257.967,214.416],[256.639,205.605],[251.943,201.989],[251.943,201.989],[245.104,196.573],[245.197,196.065],[241.788,187.655],[240.412,179.201],[240.311,178.31],[240.953,178.001],[242.058,176.597],[242.916,172.143],[243.302,171.883],[244.287,173.5],[245.715,174.516],[250.314,175.833],[261.19,186.402],[261.405,189.95],[262.979,190.153],[263.347,189.806],[268.205,187.59],[270.661,183.298],[280.962,166.312],[279.487,165.027],[279.505,163.848],[279.504,163.848],[272.931,152.782],[264.467,142.605],[267.482,134.941],[268.654,132.397],[270.029,132.823],[279.395,135.116],[283.88,134.783],[287.586,131.269],[289.106,130.699],[294.373,128.732],[299.122,126.815],[315.602,116.052],[320.298,106.095],[325.157,95.591],[325.406,83.424],[323.973,78.487],[322.75,74.877],[322.787,72.429],[322.435,72.45],[322.381,71.467],[316.014,61.65],[311.116,58.208],[311.116,58.208],[310.772,53.47],[318.165,46.517],[320.65,43.027],[318.443,39.957],[307.017,39.517],[301.871,38.133],[300.761,34.567],[308.93,25.015],[311.689,30.736],[314.936,31.791],[323.889,28.322],[324.156,28.685],[325.824,35.125],[332.19,39.935],[333.735,38.693],[335.03,45.012],[335.643,53.239],[338.529,57.862],[343.217,55.574],[343.255,54.634],[343.769,54.458],[349.329,48.465],[349.328,48.465],[349.329,48.462],[350.208,48.541],[349.587,46.986],[348.275,43.652],[347.134,41.968],[347.375,41.762],[347.178,40.194],[346.949,40.389],[342.482,34.352],[342.498,34.346],[341.458,31.487],[339.948,28.702],[338.812,27.487],[338.441,27.174],[342.84,19.972],[342.491,19.67],[344.116,15.112],[352.351,6.114],[359.95,-2.139],[362.934,-4.934],[370.991,-45.634],[370.627,-47.465],[366.477,-60.555],[366.569,-60.402],[370.079,-57.202],[371.012,-56.793],[375.769,-41.198],[375.222,-40.394],[376.27,-31.452],[376.732,-29.809],[380.267,-23.23],[381.042,-22.944],[383.282,-22.616],[387.957,-23.223],[388.781,-23.261],[387.593,-27.889],[384.193,-31.076],[380.032,-42.932],[380.038,-44.006],[380.038,-44.006],[380.04,-44.006],[381.587,-44.904],[383.261,-46.878],[369.356,-72.851],[365.804,-78.741],[364.646,-82.228],[362.265,-79.944],[363.909,-78.492],[361.632,-75.474],[353.644,-81.256],[347.985,-80.82],[344.445,-78.25],[343.279,-77.575],[340.469,-82.546],[342.855,-83.299],[342.407,-84.706],[339.211,-83.555],[338.697,-83.031],[338.515,-83.198],[338.452,-89.724],[344.35,-110.563],[357.196,-124.625],[357.661,-125.307],[358.581,-127.074],[360.872,-127.835],[365.109,-128.854],[366.256,-130.47],[376.783,-131.583],[379.559,-130.562],[381.738,-129.195],[387.688,-132.106],[387.688,-132.105],[387.937,-131.078],[388.317,-131.149],[388.704,-131.149],[388.118,-135.669],[385.589,-138.629],[385.685,-139.672],[385.73,-139.869],[386.897,-146.246],[387.213,-151.122],[387.087,-151.778],[387.107,-152.237],[389.011,-156.663],[398.192,-157.695],[400.275,-155.221],[404.252,-152.499],[406.248,-154.838],[407.797,-156.487],[408.996,-160.477],[411.145,-161.476],[411.128,-160.315],[411.484,-156.237],[409.06,-134.339],[404.417,-122.337],[404.631,-121.616],[406.91,-115.381],[407.304,-105.091],[413.484,-91.825],[425.747,-71.974],[429.176,-67.962],[432.108,-73.257],[431.253,-83.674],[432.43,-88.357],[432.43,-88.358],[434.166,-96.96],[434.601,-103.975],[434.246,-113.435],[435.861,-114.05],[434.066,-116.398],[434.063,-116.397],[434.063,-116.398],[429.751,-123.942],[425.186,-127.617],[425.184,-127.617],[422.637,-133.011],[421.498,-142.903],[423.277,-149.179],[423.544,-149.557],[424.868,-148.855],[426.374,-153.315],[428.315,-153.289],[429.273,-150.842],[430.573,-153.482],[430.573,-153.482],[441.355,-156.249],[445.536,-155.018],[455.446,-186.725],[462.425,-188.449],[457.481,-196.742],[451.249,-203.129],[450.655,-204.728],[446.812,-210.617],[446.808,-210.617],[442.402,-227.075],[441.362,-231.552],[444.438,-230.343],[449.199,-228.638],[455.082,-233.115],[463.442,-231.85],[463.445,-231.85],[466.738,-231.919],[468.821,-233.842],[465.737,-236.583],[465.379,-237.073],[462.278,-243.978],[462.275,-243.979],[461.063,-247.47],[462.303,-253.675],[462.303,-253.673],[457.588,-259.526],[457.588,-259.525],[450.577,-261.648],[444.912,-255.709],[441.512,-256.973],[435.635,-257.37],[435.639,-257.366],[435.642,-257.347],[428.34,-259.575],[413.603,-261.441],[387.1,-261.674],[379.747,-260.731],[381.621,-253.373],[386.007,-245.645],[375.632,-252.09],[374.508,-253.546],[369.421,-255.492],[369.861,-254.372],[369.706,-254.243],[363.487,-248.448],[357.794,-247.266],[357.864,-247.297],[357.774,-247.253],[357.794,-247.266],[352.712,-244.641],[341.745,-246.839],[339.079,-249.86],[337.967,-251.072],[319.297,-249.47],[305.507,-249.887],[295.404,-251.458],[283.349,-254.705],[283.349,-254.705],[279.788,-254.257],[270.86,-253.741],[270.86,-253.741],[262.093,-249.402],[259.219,-246.563],[261.175,-245.634],[261.175,-245.633],[260.643,-236.082],[254.956,-235.177],[254.961,-235.175],[251.046,-234.273],[243.604,-231.854],[243.164,-231.577],[241.479,-232.011],[241.446,-229.621],[241.137,-228.476],[242.342,-221.45],[225.726,-229.562],[225.545,-231.378],[228.216,-232.148],[224.44,-235.715],[224.44,-235.716],[224.072,-236.77],[221.834,-241.203],[211.261,-243.003],[211.261,-243.001],[205.747,-244.548],[201.668,-240.416],[201.684,-235.494],[192.228,-234.317],[190.748,-234.174],[187.458,-233.38],[186.48,-233.791],[185.118,-237.806],[172.301,-235.462],[160.733,-233.414],[156.168,-230.706],[157.032,-228.405],[157.034,-228.407],[157.032,-228.405],[149.738,-222.128],[148.792,-223.365],[148.792,-223.364],[148.792,-223.364],[156.8,-251.936],[153.355,-255.755],[153.286,-256.892],[153.285,-256.892],[137.36,-267.571],[137.268,-267.602],[132.592,-265.373],[130.051,-263.614],[130.049,-263.615],[126.665,-266.33],[126.665,-266.33],[126.665,-266.33],[124.464,-266.754],[117.786,-269.924],[112.382,-272.381],[108.81,-269.223],[110.783,-255.889],[110.831,-252.199],[110.834,-252.199],[110.831,-252.197],[108.389,-252.035],[107.725,-249.921],[107.293,-248.738],[107.293,-248.738],[105.882,-247.566],[105.882,-247.564],[99.679,-246.809],[93.531,-243.207],[92.055,-240.668],[92.055,-240.666],[86.882,-236.139],[76.03,-219.176],[79.321,-218.034],[79.318,-218.034],[81.777,-216.655],[81.777,-216.655],[82.897,-213.064],[80.638,-212.823],[70.221,-208.031],[67.729,-201.89],[78.204,-191.867],[74.787,-189.219],[74.098,-189.492],[62.972,-192.863],[60.706,-194.984],[60.689,-190.552],[58.355,-189.2],[58.33,-188.047],[58.63,-187.741],[58.628,-187.735],[58.33,-188.047],[55.001,-189.227],[53.504,-191.55],[52.636,-185.739],[52.636,-185.739],[51.649,-185.626],[53.094,-174.968],[53.672,-174.323],[53.124,-174.76],[46.482,-188.022],[44.998,-191.168],[37.092,-193.456],[33.955,-190.622],[34.068,-189.46],[33.569,-186.926],[33.917,-184.132],[32.569,-176.14],[32.5,-175.956],[32.239,-174.208],[31.808,-170.557],[34.087,-164.011],[40.089,-155.455],[40.307,-155.271],[25.444,-159.575],[16.379,-159.609],[8.445,-164.618],[8.255,-159.886],[13.935,-156.547],[14.122,-155.512],[10.626,-151.038],[8.998,-150.648],[7.877,-150.001],[6.095,-150.02],[-1.48,-148.415],[-12.447,-146.437],[-14.097,-144.671],[-16.06,-144.066],[-17.317,-143.038],[-17.668,-141.68],[-19.471,-140.568],[-21.73,-139.303],[-25.206,-134.545],[-28.606,-132.3],[-28.887,-137.031],[-28.892,-137.031],[-28.889,-137.031],[-28.781,-137.05],[-35.399,-144.02],[-38.164,-137.169],[-37.847,-132.437],[-37.155,-130.862],[-37.059,-130.745],[-37.155,-130.648],[-36.875,-129.809],[-38.757,-126.366],[-43.736,-128.607],[-45.384,-132.472],[-45.495,-132.424],[-45.758,-132.642],[-46.133,-134.518],[-57.564,-142.032],[-72.804,-147.631],[-85.581,-155.946],[-85.581,-155.946],[-99.515,-158.357],[-109.876,-157.097],[-109.873,-157.097],[-109.876,-157.094],[-109.979,-157.19],[-111.451,-156.23],[-112.958,-155.289],[-116.875,-153.557],[-126.166,-148.801],[-128.356,-146.732],[-131.925,-143.255],[-135.399,-141.734],[-138.432,-133.716],[-137.996,-131.739],[-138.165,-128.775],[-141.219,-125.017],[-141.624,-121.754],[-141.28,-121.51],[-141.28,-121.51],[-141.984,-121.148],[-149.28,-107.248],[-152.103,-104.406],[-163.566,-92.227],[-169.594,-78.191],[-167.983,-66.632],[-157.406,-58.486],[-148.16,-63.69],[-145.802,-55.535],[-141.904,-52.028],[-141.831,-51.805],[-141.377,-50.127],[-140.191,-48.159],[-140.276,-46.358],[-144.278,-44.542],[-145.578,-44.655],[-146.257,-44.492],[-146.111,-45.163],[-146.311,-54.508],[-150.379,-56.804],[-156.271,-43.003],[-156.229,-42.927],[-156.691,-42.905],[-156.348,-38.28],[-156.342,-38.266],[-155.693,-36.544],[-157.983,-33.804],[-158.656,-33.551],[-171.347,-25.769],[-180.502,-17.958],[-180.127,-22.97],[-181.727,-28.478],[-185.275,-29.856],[-185.373,-31.1],[-186.485,-35.88],[-186.485,-35.882],[-193.945,-49.588],[-197.441,-59.927],[-203.31,-63.523],[-211.093,-55.338],[-217.257,-42.82],[-217.783,-41.803],[-221.294,-38.236],[-224.919,-33.252],[-224.781,-26.377],[-224.793,-26.367],[-221.569,-18.268],[-217,-18.756],[-210.737,-21.084],[-207.177,-28.439],[-204.179,-32.129],[-201.108,-37.409],[-200.887,-37.962],[-199.258,-37.183],[-199.255,-37.187],[-196.869,-34.95],[-196.991,-34.464],[-199.131,-34.495],[-198.569,-33.265],[-201.499,-31.195],[-202.821,-29.57],[-202.765,-26.21],[-202.765,-26.21],[-202.765,-26.208],[-202.49,-25.961],[-202.607,-25.865],[-203.297,-24.183],[-203.307,-23.102],[-205.069,-20.253],[-203.069,-20.339],[-204.159,-14.44],[-207.388,-12.177],[-205.093,-9.758],[-203.934,-8.533],[-200.309,-7.989],[-197.24,-9.086],[-193.495,-11.096],[-197.24,-9.086],[-200.309,-7.989],[-202.832,-5.069],[-202.913,-3.919],[-202.913,-3.919],[-202.753,3.291],[-200.293,3.931],[-198.14,4.554],[-192.333,19.947],[-192.348,19.967],[-199.678,23.306],[-218.997,22.262],[-221.867,32.216],[-222.602,42.521],[-222.922,47.285],[-224.824,47.403],[-224.865,48.507],[-222.618,53.296],[-221.363,59.23],[-216.69,60.326],[-210.793,65.144],[-210.793,65.144],[-210.795,65.144],[-210.919,68.651],[-210.806,69.47],[-211.448,70.324],[-215.283,74.431],[-225.352,87.832],[-236.938,102.194],[-239.044,106.997],[-246.47,117.555],[-246.473,117.555],[-246.867,119.612],[-255.189,130.685],[-256.031,135.251],[-254.956,136.444],[-253.912,137.064],[-253.854,137.699],[-255.384,153.885],[-255.253,155.337],[-257.304,167.34],[-257.277,170.05],[-257.348,170.973],[-256.266,174.442],[-255.985,174.437],[-255.952,176.949],[-249.307,176.899],[-239.894,186.314],[-239.758,189.786],[-238.579,190.934],[-238.468,192.249],[-238.466,192.249],[-230.757,198.987],[-229.531,199.566],[-225.944,203.084],[-225.944,203.081],[-225.944,203.084],[-219.967,207.759],[-219.967,207.759],[-219.967,207.759],[-213.612,207.969],[-195.889,206.084],[-195.889,206.079],[-183.009,202.967],[-165.662,201.766],[-165.659,201.766],[-164.414,204.225],[-162.74,207.449],[-162.737,207.449],[-151.256,208.812],[-151.256,208.812],[-149.051,211.387],[-144.752,219.359],[-144.73,219.469],[-145.847,220.815],[-146.163,223.234],[-144.723,223.294],[-136.766,247.084],[-135.669,248.42],[-135.669,248.425],[-135.172,249.441],[-135.164,249.441],[-135.17,249.444],[-134.734,251.665],[-132.857,252.891],[-132.857,252.889],[-132.857,252.891],[-130.835,259.717],[-130.835,259.717],[-127.991,276.545],[-129.764,284.671],[-136.436,304.101],[-134.719,311.762],[-126.449,331.05],[-115.826,361.523],[-115.711,360.896],[-115.711,360.896],[-115.364,360.981],[-115.826,361.523],[-112.052,380.234],[-102.549,386.039],[-89.537,383.822],[-70.739,377.834],[-51.905,356.273],[-49.853,348.473],[-46.746,341.242],[-37.947,334.497],[-38.929,322.495],[-38.929,322.498],[-39.338,321.336],[-38.295,316.005],[-38.301,316.007],[-38.298,316.005],[-30.616,309.791],[-26.789,306.728],[-26.792,306.728],[-25.168,305.111],[-25.168,305.108],[-25.168,305.108],[-13.582,290.175],[-13.416,279.009],[-16.118,273.003],[-18.142,259.085],[-16.131,247.055],[-7.073,235.017],[-7.073,235.017],[-6.577,234.03],[10.73,219.432],[13.124,217.359],[13.051,215.692],[13.407,215.018],[14.486,214.778],[15.828,213.85],[18.041,211.915],[18.977,211.608],[22.164,206.53],[23.505,206.612],[28.233,195.992],[28.395,194.861],[28.793,194.52],[32.973,187.457],[33.688,177.245],[24.58,176.839],[0.556,179.555],[0.671,179.076],[0.311,178.078],[2.83,173.776],[7.221,172.882],[19.646,168.663],[23.842,164.567],[23.67,164.048],[23.502,163.803],[23.528,163.785],[23.478,163.765],[23.451,163.723],[23.451,163.624],[23.67,164.048],[24.255,164.648],[35.516,161.56],[41.691,154.079],[41.691,154.076],[53.575,146.331],[59.876,143.617],[63.458,136.022],[62.723,122.35],[62.604,122.475],[54.875,121.016],[51.176,115.099],[51.175,115.099],[51.175,115.099],[51.358,113.807],[50.113,109.596],[48.923,112.416],[48.922,112.416],[44.497,116.337],[43.225,119.761],[39.841,121.141],[30.675,118.557],[30.675,118.555],[29.502,113.768],[29.502,113.768],[30.594,112.672],[28.143,110.38],[27.448,113],[24.667,111.347],[19.169,102.91],[19.169,102.913],[16.592,98.237],[15.113,94.696],[15.113,94.696],[15.113,94.693],[16.021,91.519],[18.516,91.296],[24.21,95.425],[34.068,105.108],[36.403,106.363],[39.687,107.184],[44.017,107.661],[47.52,108.354],[53.511,111.138],[73.223,114.523],[74.338,116.263],[78.931,116.777],[97.487,121.138],[101.749,121.855],[106.573,129.266],[119.325,134.8],[121.549,138.723],[122.279,146.299],[141.346,190.398],[149.744,192.139],[155.912,184.509],[155.929,184.35],[157.461,180.969],[166.207,152.023],[170.444,148.083],[191.156,129.373],[195.474,129.904],[202.147,129.432],[204.662,136.001],[214.007,155.495],[215.594,157.842],[222.809,157.422]],"c":true},"ix":2},"nm":"Path 22","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"null","np":23,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":301,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"outline fill","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.58],"y":[0]},"n":["0p833_0p833_0p58_0"],"t":30,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":114,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.72],"y":[0]},"n":["0p833_0p833_0p72_0"],"t":180,"s":[100],"e":[0]},{"t":262}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[-18.5,-5.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-81.462,0],[0,-81.462],[81.462,0],[0,81.462]],"o":[[81.462,0],[0,81.462],[-81.462,0],[0,-81.462]],"v":[[-18.5,-153],[129,-5.5],[-18.5,142],[-166,-5.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":7,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":301,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"outline","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.37],"y":[1]},"o":{"x":[0.58],"y":[0]},"n":["0p37_1_0p58_0"],"t":0,"s":[180],"e":[785]},{"i":{"x":[0.564],"y":[1]},"o":{"x":[0.182],"y":[0]},"n":["0p564_1_0p182_0"],"t":120,"s":[785],"e":[809]},{"i":{"x":[0.41],"y":[1]},"o":{"x":[0.339],"y":[0]},"n":["0p41_1_0p339_0"],"t":180,"s":[809],"e":[1260]},{"t":300}],"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[-18.5,-5.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-81.462,0],[0,-81.462],[81.462,0],[0,81.462]],"o":[[81.462,0],[0,81.462],[-81.462,0],[0,-81.462]],"v":[[-18.5,-153],[129,-5.5],[-18.5,142],[-166,-5.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.37],"y":[1]},"o":{"x":[0.58],"y":[0]},"n":["0p37_1_0p58_0"],"t":0,"s":[99.9],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":120,"s":[0],"e":[0]},{"i":{"x":[0.41],"y":[1]},"o":{"x":[0.58],"y":[0]},"n":["0p41_1_0p58_0"],"t":180,"s":[0],"e":[99.9]},{"t":300}],"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.5],"y":[0]},"n":["0p833_0p833_0p5_0"],"t":0,"s":[23],"e":[4]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":60,"s":[4],"e":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.5],"y":[0]},"n":["0p833_0p833_0p5_0"],"t":248,"s":[4],"e":[23]},{"t":300}],"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":301,"st":0,"bm":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/worm.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/worm.json deleted file mode 100644 index 37e108ea..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/worm.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"4.12.3","fr":60,"ip":0,"op":241,"w":800,"h":600,"nm":"worm_lottie","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.75,-5.5]],"o":[[0,0],[-4.75,5.5]],"v":[[67.125,146.75],[59.375,147.75]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.286274509804,0.301960784314,0.419607873056,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":241,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[406.875,329,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.071,0],[0,-2.071],[-2.071,0],[0,2.071]],"o":[[-2.071,0],[0,2.071],[2.071,0],[0,-2.071]],"v":[[0,-3.75],[-3.75,0],[0,3.75],[3.75,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.286274509804,0.301960784314,0.419607873056,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[54.125,110.875],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[44.414,44.414],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":241,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-167,157],[141,157]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":1,"ml":4,"d":[{"n":"d","nm":"dash","v":{"a":0,"k":10,"ix":1}},{"n":"o","nm":"offset","v":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_1_0p167_0p167"],"t":0,"s":[0],"e":[60]},{"t":60,"s":[60],"h":1},{"t":120,"s":[60],"h":1}],"ix":7,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"}}],"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":241,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 5","parent":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.77],"y":[0]},"n":["0p833_0p833_0p77_0"],"t":120,"s":[21],"e":[11]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":171,"s":[11],"e":[21]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":175,"s":[21],"e":[21]},{"t":240}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"p":{"a":0,"k":[0.08,-1.677,0],"ix":2},"a":{"a":0,"k":[245.226,98.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":60,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.579,0],[0,-2.579],[-2.579,0],[0,2.579]],"o":[[-2.579,0],[0,2.579],[2.579,0],[0,-2.579]],"v":[[-18.5,3.33],[-23.17,8],[-18.5,12.67],[-13.83,8]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[280,66],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-18,3]],"o":[[0,0],[18,-3]],"v":[[245.5,98.5],[260,75]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":120,"op":241,"st":120,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 4","parent":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.859],"y":[1]},"o":{"x":[0.709],"y":[0]},"n":["0p859_1_0p709_0"],"t":120,"s":[0],"e":[-10]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.325],"y":[0]},"n":["0p833_0p833_0p325_0"],"t":172,"s":[-10],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":177,"s":[0],"e":[0]},{"t":240}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"p":{"a":0,"k":[1.226,-4,0],"ix":2},"a":{"a":0,"k":[245.226,98.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":60,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.485,0],[0,-2.485],[-2.485,0],[0,2.485]],"o":[[-2.485,0],[0,2.485],[2.485,0],[0,-2.485]],"v":[[-18.5,3.5],[-23,8],[-18.5,12.5],[-14,8]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[280,66],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-18,3]],"o":[[0,0],[18,-3]],"v":[[245.5,98.5],[260,75]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":120,"op":241,"st":120,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 3","parent":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.77],"y":[0]},"n":["0p833_0p833_0p77_0"],"t":0,"s":[21],"e":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":51,"s":[4],"e":[21]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":55,"s":[21],"e":[21]},{"t":120}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"p":{"a":0,"k":[0.08,-1.677,0],"ix":2},"a":{"a":0,"k":[245.226,98.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":60,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.579,0],[0,-2.579],[-2.579,0],[0,2.579]],"o":[[-2.579,0],[0,2.579],[2.579,0],[0,-2.579]],"v":[[-18.5,3.33],[-23.17,8],[-18.5,12.67],[-13.83,8]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[280,66],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-18,3]],"o":[[0,0],[18,-3]],"v":[[245.5,98.5],[260,75]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":121,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 2","parent":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.709],"y":[0]},"n":["0p833_0p833_0p709_0"],"t":0,"s":[0],"e":[-22]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":53,"s":[-22],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":57,"s":[0],"e":[0]},{"t":120}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n $bm_rt = value = value;\n}"},"p":{"a":0,"k":[1.226,-4,0],"ix":2},"a":{"a":0,"k":[245.226,98.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":60,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.485,0],[0,-2.485],[-2.485,0],[0,2.485]],"o":[[-2.485,0],[0,2.485],[2.485,0],[0,-2.485]],"v":[[-18.5,3.5],[-23,8],[-18.5,12.5],[-14,8]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[280,66],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-18,3]],"o":[[0,0],[18,-3]],"v":[[245.5,98.5],[260,75]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":121,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":3,"nm":"front head","parent":13,"sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[121,202,0],"e":[181,202,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":60,"s":[181,202,0],"e":[181,202,0],"to":[0,0,0],"ti":[0,0,0]},{"t":120}],"ix":2,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":241,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":3,"nm":"front","parent":13,"sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[68,202,0],"e":[128,202,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":60,"s":[128,202,0],"e":[128,202,0],"to":[0,0,0],"ti":[0,0,0]},{"t":120}],"ix":2,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":241,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":3,"nm":"hump","parent":13,"sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[47,155,0],"e":[67,202,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":60,"s":[67,202,0],"e":[107,155,0],"to":[0,0,0],"ti":[0,0,0]},{"t":120}],"ix":2,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":241,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":3,"nm":"back","parent":13,"sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[17,202,0],"e":[-3,202,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":60,"s":[-3,202,0],"e":[77,202,0],"to":[0,0,0],"ti":[0,0,0]},{"t":120}],"ix":2,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":241,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":3,"nm":"back","parent":13,"sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[-25,202,0],"e":[-45,202,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":60,"s":[-45,202,0],"e":[35,202,0],"to":[0,0,0],"ti":[0,0,0]},{"t":120}],"ix":2,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":241,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":3,"nm":"NULL CONTROL","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[400,300,0],"e":[340,300,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":60,"s":[340,300,0],"e":[340,300,0],"to":[0,0,0],"ti":[0,0,0]},{"t":120}],"ix":2,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"a":{"a":0,"k":[60,60,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":241,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Shape Layer 1: Path 1 [1.1.0]","np":3,"mn":"ADBE Layer Control","ix":1,"en":1,"ef":[{"ty":10,"nm":"Layer","mn":"ADBE Layer Control-0001","ix":1,"v":{"a":0,"k":12,"ix":1}}]},{"ty":5,"nm":"Shape Layer 1: Path 1 [1.1.1]","np":3,"mn":"ADBE Layer Control","ix":2,"en":1,"ef":[{"ty":10,"nm":"Layer","mn":"ADBE Layer Control-0001","ix":1,"v":{"a":0,"k":11,"ix":1}}]},{"ty":5,"nm":"Shape Layer 1: Path 1 [1.1.2]","np":3,"mn":"ADBE Layer Control","ix":3,"en":1,"ef":[{"ty":10,"nm":"Layer","mn":"ADBE Layer Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1}}]},{"ty":5,"nm":"Shape Layer 1: Path 1 [1.1.3]","np":3,"mn":"ADBE Layer Control","ix":4,"en":1,"ef":[{"ty":10,"nm":"Layer","mn":"ADBE Layer Control-0001","ix":1,"v":{"a":0,"k":9,"ix":1}}]},{"ty":5,"nm":"Shape Layer 1: Path 1 [1.1.4]","np":3,"mn":"ADBE Layer Control","ix":5,"en":1,"ef":[{"ty":10,"nm":"Layer","mn":"ADBE Layer Control-0001","ix":1,"v":{"a":0,"k":8,"ix":1}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-28,0],[-26,0],[-17,0],[0,0]],"o":[[0,0],[28,0],[29,0],[17,0],[0,0]],"v":[[-105,142],[-63,142],[-23,95],[8,142],[61,142]],"c":false},"ix":2,"x":"var $bm_rt;\nvar nullLayerNames = [\n 'Shape Layer 1: Path 1 [1.1.0]',\n 'Shape Layer 1: Path 1 [1.1.1]',\n 'Shape Layer 1: Path 1 [1.1.2]',\n 'Shape Layer 1: Path 1 [1.1.3]',\n 'Shape Layer 1: Path 1 [1.1.4]'\n ];\nvar origPath = thisProperty;\nvar origPoints = origPath.points();\nvar origInTang = origPath.inTangents();\nvar origOutTang = origPath.outTangents();\nvar getNullLayers = [];\nfor (var i = 0; i < nullLayerNames.length; i++) {\n try {\n getNullLayers.push(effect(nullLayerNames[i])('ADBE Layer Control-0001'));\n } catch (err) {\n getNullLayers.push(null);\n }\n}\nfor (var i = 0; i < getNullLayers.length; i++) {\n if (getNullLayers[i] != null && getNullLayers[i].index != thisLayer.index) {\n origPoints[i] = fromCompToSurface(getNullLayers[i].toComp(getNullLayers[i].anchorPoint));\n }\n}\n$bm_rt = createPath(origPoints, origInTang, origOutTang, origPath.isClosed());"},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":17,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":241,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"worm","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[434,115,0],"ix":2},"a":{"a":0,"k":[400,300,0],"ix":1},"s":{"a":0,"k":[211,211,100],"ix":6}},"ao":0,"tm":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[4.017]},{"t":241}],"ix":2},"w":800,"h":600,"ip":0,"op":241,"st":0,"bm":0}]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/resource/you're_in!.json b/presentation/src/main/cpp/third_party/rlottie/example/resource/you're_in!.json deleted file mode 100644 index d261bea8..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/resource/you're_in!.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.2.1","fr":30,"ip":0,"op":231,"w":800,"h":800,"nm":"Code","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Rope Movement","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":136.136136136136,"op":528.528528528529,"st":136.136136136136,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"Rope Movement","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":136.136136136136,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"people line","refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-60,691.205,0],"ix":2},"a":{"a":0,"k":[600,183,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":1,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":0,"k":[0.792156875134,0.800000011921,0.807843148708,1],"ix":3}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]}],"w":1200,"h":366,"ip":0,"op":528.528528528529,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"Blue Member 2","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,532,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"s","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1558.356,382.617],[1110,382.617],[1110,982],[1558.356,982]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"w":1920,"h":1080,"ip":136.136136136136,"op":528.528528528529,"st":136.136136136136,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"Blue Member","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,532,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"s","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1558.356,382.617],[1110,382.617],[1110,982],[1558.356,982]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"w":1920,"h":1080,"ip":0,"op":528.528528528529,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"people line","refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-4,693.205,0],"ix":2},"a":{"a":0,"k":[600,183,0],"ix":1},"s":{"a":0,"k":[95,95,100],"ix":6}},"ao":0,"ef":[{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":1,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":0,"k":[0.701960802078,0.709803938866,0.717647075653,1],"ix":3}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]}],"w":1200,"h":366,"ip":-23.023023023023,"op":528.528528528529,"st":-23.023023023023,"bm":0},{"ddd":0,"ind":11,"ty":0,"nm":"pole","refId":"comp_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1217,728.37,0],"ix":2},"a":{"a":0,"k":[121,123,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":242,"h":246,"ip":0,"op":528.528528528529,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":0,"nm":"pole","refId":"comp_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[701,727.37,0],"ix":2},"a":{"a":0,"k":[121,123,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"sy":[{"ty":0,"nm":"Stroke","c":{"a":0,"k":[0.615686297417,0.623529434204,0.631372570992,1],"ix":2},"s":{"a":0,"k":4,"ix":3}}],"w":242,"h":246,"ip":0,"op":528.528528528529,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":0,"nm":"Party","refId":"comp_8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,542,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[-84.071,0],[0,-84.071],[0,0]],"o":[[0,0],[0,-84.071],[84.071,0],[0,0],[0,0]],"v":[[807,820.5],[807,498.467],[959.467,346],[1111.934,498.467],[1111.934,820.5]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"w":1920,"h":1080,"ip":0,"op":528.528528528529,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":0,"nm":"Party","refId":"comp_8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,544,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[109,109,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[0,0],[0,0],[-84.071,0],[0,-84.071],[0,0]],"o":[[0,0],[0,-84.071],[84.071,0],[0,0],[0,0]],"v":[[807,795.729],[807,498.467],[959.467,346],[1111.934,498.467],[1111.934,795.729]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"ef":[{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":1,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":0,"k":[0.792156875134,0.800000011921,0.807843148708,1],"ix":3}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]}],"w":1920,"h":1080,"ip":0,"op":528.528528528529,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[945.75,491,0],"ix":2},"a":{"a":0,"k":[201.25,-332,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":74.074,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[196.5,-329],[206,-335]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[74.637,-258.274],[93.137,-269.274]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":75.075,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[74.637,-258.274],[93.137,-269.274]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-12.5,-142.5],[-11.5,-148.5]],"c":false}]},{"t":76.0760760760761}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.952941176471,0.541176470588,0.470588235294,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":8,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952941176471,0.541176470588,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":74.0740740740741,"op":77.0770770770771,"st":23.023023023023,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[950.75,472,0],"ix":2},"a":{"a":0,"k":[202.75,-324.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":74.074,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[198,-321.5],[207.5,-327.5]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[63,-248],[79.5,-258]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":75.075,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[63,-248],[79.5,-258]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-26.5,-117.5],[-25.5,-125]],"c":false}]},{"t":76.0760760760761}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.96862745098,0.874509803922,0.549019607843,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952941176471,0.541176470588,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":74.0740740740741,"op":77.0770770770771,"st":23.023023023023,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[959.75,451.75,0],"ix":2},"a":{"a":0,"k":[197.25,-334.75,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":74.074,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[206,-340.5],[188.5,-329]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[71,-270.5],[39,-250.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":75.075,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[71,-270.5],[39,-250.5]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-51.5,-122.5],[-54.5,-111.5]],"c":false}]},{"t":76.0760760760761}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.96862745098,0.874509803922,0.549019607843,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952941176471,0.541176470588,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":74.0740740740741,"op":77.0770770770771,"st":23.023023023023,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Shape Layer 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[966.5,573,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":51.051,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[196.5,-329],[206,-335]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[260,-323.5],[220,-322.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":52.052,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[260,-323.5],[220,-322.5]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[289,-314.5],[277,-322.5]],"c":false}]},{"t":53.053053053053}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.952941176471,0.541176470588,0.470588235294,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":8,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952941176471,0.541176470588,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":51.0510510510511,"op":54.0540540540541,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Shape Layer 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,548,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":51.051,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[198,-321.5],[207.5,-327.5]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[260,-323.5],[220,-322.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":52.052,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[260,-323.5],[220,-322.5]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[308,-304.5],[296,-312.5]],"c":false}]},{"t":53.053053053053}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.96862745098,0.874509803922,0.549019607843,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952941176471,0.541176470588,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":51.0510510510511,"op":54.0540540540541,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":51.051,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[206,-340.5],[188.5,-329]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[263.5,-337.5],[196.5,-337.5]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":52.052,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[263.5,-337.5],[196.5,-337.5]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[327,-304],[304,-322.5]],"c":false}]},{"t":53.053053053053}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.96862745098,0.874509803922,0.549019607843,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.952941176471,0.541176470588,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":51.0510510510511,"op":54.0540540540541,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":0,"nm":"Rope","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":509.509509509509,"st":0,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"ROPE","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":37.037,"s":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,202.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-157.997,69.524],[0,0]],"o":[[0,0],[89.76,-39.498],[0,0]],"v":[[-256,145],[53.997,60.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":41.041,"s":[{"i":[[0,0],[-157.997,69.524],[0,0]],"o":[[0,0],[89.76,-39.498],[0,0]],"v":[[-256,145],[53.997,60.476],[261,144]],"c":false}],"e":[{"i":[[-131,67],[-167.543,-41.544],[0,0]],"o":[[131,-67],[111.003,27.524],[0,0]],"v":[[-85,118],[177.997,-67.524],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":44.044,"s":[{"i":[[-131,67],[-167.543,-41.544],[0,0]],"o":[[131,-67],[111.003,27.524],[0,0]],"v":[[-85,118],[177.997,-67.524],[261,144]],"c":false}],"e":[{"i":[[-58.242,135.122],[-109.997,-11.476],[0,0]],"o":[[25,-58],[113.747,11.867],[0,0]],"v":[[95,56],[209.997,-128.524],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":46.046,"s":[{"i":[[-58.242,135.122],[-109.997,-11.476],[0,0]],"o":[[25,-58],[113.747,11.867],[0,0]],"v":[[95,56],[209.997,-128.524],[261,144]],"c":false}],"e":[{"i":[[-19.414,45.041],[-62.35,-12.578],[-16.222,-23.945]],"o":[[11.785,-72.253],[87.466,32.993],[30.606,47.27]],"v":[[156.215,-94.747],[225.35,-195.422],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":48.048,"s":[{"i":[[-19.414,45.041],[-62.35,-12.578],[-16.222,-23.945]],"o":[[11.785,-72.253],[87.466,32.993],[30.606,47.27]],"v":[[156.215,-94.747],[225.35,-195.422],[261,144]],"c":false}],"e":[{"i":[[0,0],[-63.35,-42.078],[-16.222,-23.945]],"o":[[0,0],[68.058,37.708],[30.606,47.27]],"v":[[161.715,-174.747],[260.35,-234.922],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":49.049,"s":[{"i":[[0,0],[-63.35,-42.078],[-16.222,-23.945]],"o":[[0,0],[68.058,37.708],[30.606,47.27]],"v":[[161.715,-174.747],[260.35,-234.922],[261,144]],"c":false}],"e":[{"i":[[-19.414,45.041],[-15.35,-48.578],[-16.222,-23.945]],"o":[[47.785,-55.253],[19.448,61.549],[30.606,47.27]],"v":[[163.215,-255.747],[295.35,-226.422],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":50.05,"s":[{"i":[[-19.414,45.041],[-15.35,-48.578],[-16.222,-23.945]],"o":[[47.785,-55.253],[19.448,61.549],[30.606,47.27]],"v":[[163.215,-255.747],[295.35,-226.422],[261,144]],"c":false}],"e":[{"i":[[0,0],[48.063,-75.399],[-16.181,-61.782]],"o":[[0,0],[-55.924,87.73],[0,0]],"v":[[201.995,-337.25],[261.924,-145.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":51.051,"s":[{"i":[[0,0],[48.063,-75.399],[-16.181,-61.782]],"o":[[0,0],[-55.924,87.73],[0,0]],"v":[[201.995,-337.25],[261.924,-145.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[25.07,-76.834],[-16.181,-61.782]],"o":[[0,0],[-29.695,91.056],[0,0]],"v":[[262.495,-339.75],[237.924,-129.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":52.052,"s":[{"i":[[0,0],[25.07,-76.834],[-16.181,-61.782]],"o":[[0,0],[-29.695,91.056],[0,0]],"v":[[262.495,-339.75],[237.924,-129.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[331.995,-309.25],[213.924,-128.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":53.053,"s":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[331.995,-309.25],[213.924,-128.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[371.495,-284.75],[217.924,-132.23],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":54.054,"s":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[371.495,-284.75],[217.924,-132.23],[261,144]],"c":false}],"e":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[395.995,-254.25],[228.924,-130.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":55.055,"s":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[395.995,-254.25],[228.924,-130.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[407.502,-239.456],[219.061,-134.017],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":69.069,"s":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[407.502,-239.456],[219.061,-134.017],[261,144]],"c":false}],"e":[{"i":[[0,0],[30.019,-141.415],[-16.181,-61.782]],"o":[[0,0],[-30.019,141.415],[0,0]],"v":[[422.296,-193.428],[222.348,-132.373],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":71.071,"s":[{"i":[[0,0],[30.019,-141.415],[-16.181,-61.782]],"o":[[0,0],[-30.019,141.415],[0,0]],"v":[[422.296,-193.428],[222.348,-132.373],[261,144]],"c":false}],"e":[{"i":[[0,0],[-32.611,-39.166],[-42.089,-15.667]],"o":[[-66,58],[41.234,49.522],[0,0]],"v":[[114,-144],[87.497,51.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":73.073,"s":[{"i":[[0,0],[-32.611,-39.166],[-42.089,-15.667]],"o":[[-66,58],[41.234,49.522],[0,0]],"v":[[114,-144],[87.497,51.476],[261,144]],"c":false}],"e":[{"i":[[-13,-44],[-165.271,-51.701],[-66,8]],"o":[[13,44],[72.003,22.524],[167.916,-20.353]],"v":[[-150,-19],[16.997,141.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":74.95,"s":[{"i":[[-13,-44],[-165.271,-51.701],[-66,8]],"o":[[13,44],[72.003,22.524],[167.916,-20.353]],"v":[[-150,-19],[16.997,141.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[-7.003,178.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":75.888,"s":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[-7.003,178.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[1.997,220.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":78.704,"s":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[1.997,220.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[6.997,159.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":81.519,"s":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[6.997,159.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,209.051],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":84.334,"s":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,209.051],[261,144]],"c":false}],"e":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,202.476],[261,144]],"c":false}]},{"t":88.0880880880881}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":99,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.96862745098,0.874509803922,0.549019607843,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":30,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 5","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":37.037,"s":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,202.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-157.997,69.524],[0,0]],"o":[[0,0],[89.76,-39.498],[0,0]],"v":[[-256,145],[53.997,60.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":41.041,"s":[{"i":[[0,0],[-157.997,69.524],[0,0]],"o":[[0,0],[89.76,-39.498],[0,0]],"v":[[-256,145],[53.997,60.476],[261,144]],"c":false}],"e":[{"i":[[-131,67],[-167.543,-41.544],[0,0]],"o":[[131,-67],[111.003,27.524],[0,0]],"v":[[-85,118],[177.997,-67.524],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":44.044,"s":[{"i":[[-131,67],[-167.543,-41.544],[0,0]],"o":[[131,-67],[111.003,27.524],[0,0]],"v":[[-85,118],[177.997,-67.524],[261,144]],"c":false}],"e":[{"i":[[-58.242,135.122],[-109.997,-11.476],[0,0]],"o":[[25,-58],[113.747,11.867],[0,0]],"v":[[95,56],[209.997,-128.524],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":46.046,"s":[{"i":[[-58.242,135.122],[-109.997,-11.476],[0,0]],"o":[[25,-58],[113.747,11.867],[0,0]],"v":[[95,56],[209.997,-128.524],[261,144]],"c":false}],"e":[{"i":[[-19.414,45.041],[-62.35,-12.578],[-16.222,-23.945]],"o":[[11.785,-72.253],[87.466,32.993],[30.606,47.27]],"v":[[156.215,-94.747],[225.35,-195.422],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":48.048,"s":[{"i":[[-19.414,45.041],[-62.35,-12.578],[-16.222,-23.945]],"o":[[11.785,-72.253],[87.466,32.993],[30.606,47.27]],"v":[[156.215,-94.747],[225.35,-195.422],[261,144]],"c":false}],"e":[{"i":[[0,0],[-63.35,-42.078],[-16.222,-23.945]],"o":[[0,0],[68.058,37.708],[30.606,47.27]],"v":[[161.715,-174.747],[260.35,-234.922],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":49.049,"s":[{"i":[[0,0],[-63.35,-42.078],[-16.222,-23.945]],"o":[[0,0],[68.058,37.708],[30.606,47.27]],"v":[[161.715,-174.747],[260.35,-234.922],[261,144]],"c":false}],"e":[{"i":[[-19.414,45.041],[-15.35,-48.578],[-16.222,-23.945]],"o":[[47.785,-55.253],[19.448,61.549],[30.606,47.27]],"v":[[163.215,-255.747],[295.35,-226.422],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":50.05,"s":[{"i":[[-19.414,45.041],[-15.35,-48.578],[-16.222,-23.945]],"o":[[47.785,-55.253],[19.448,61.549],[30.606,47.27]],"v":[[163.215,-255.747],[295.35,-226.422],[261,144]],"c":false}],"e":[{"i":[[0,0],[48.063,-75.399],[-16.181,-61.782]],"o":[[0,0],[-55.924,87.73],[0,0]],"v":[[201.995,-337.25],[261.924,-145.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":51.051,"s":[{"i":[[0,0],[48.063,-75.399],[-16.181,-61.782]],"o":[[0,0],[-55.924,87.73],[0,0]],"v":[[201.995,-337.25],[261.924,-145.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[25.07,-76.834],[-16.181,-61.782]],"o":[[0,0],[-29.695,91.056],[0,0]],"v":[[262.495,-339.75],[237.924,-129.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":52.052,"s":[{"i":[[0,0],[25.07,-76.834],[-16.181,-61.782]],"o":[[0,0],[-29.695,91.056],[0,0]],"v":[[262.495,-339.75],[237.924,-129.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[331.995,-309.25],[213.924,-128.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":53.053,"s":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[331.995,-309.25],[213.924,-128.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[371.495,-284.75],[217.924,-132.23],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":54.054,"s":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[371.495,-284.75],[217.924,-132.23],[261,144]],"c":false}],"e":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[395.995,-254.25],[228.924,-130.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":55.055,"s":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[395.995,-254.25],[228.924,-130.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[407.502,-239.456],[219.061,-134.017],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":69.069,"s":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[407.502,-239.456],[219.061,-134.017],[261,144]],"c":false}],"e":[{"i":[[0,0],[30.019,-141.415],[-16.181,-61.782]],"o":[[0,0],[-30.019,141.415],[0,0]],"v":[[422.296,-193.428],[222.348,-132.373],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":71.071,"s":[{"i":[[0,0],[30.019,-141.415],[-16.181,-61.782]],"o":[[0,0],[-30.019,141.415],[0,0]],"v":[[422.296,-193.428],[222.348,-132.373],[261,144]],"c":false}],"e":[{"i":[[0,0],[-32.611,-39.166],[-42.089,-15.667]],"o":[[-66,58],[41.234,49.522],[0,0]],"v":[[114,-144],[87.497,51.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":73.073,"s":[{"i":[[0,0],[-32.611,-39.166],[-42.089,-15.667]],"o":[[-66,58],[41.234,49.522],[0,0]],"v":[[114,-144],[87.497,51.476],[261,144]],"c":false}],"e":[{"i":[[-13,-44],[-165.271,-51.701],[-66,8]],"o":[[13,44],[72.003,22.524],[167.916,-20.353]],"v":[[-150,-19],[16.997,141.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":74.95,"s":[{"i":[[-13,-44],[-165.271,-51.701],[-66,8]],"o":[[13,44],[72.003,22.524],[167.916,-20.353]],"v":[[-150,-19],[16.997,141.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[-7.003,178.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":75.888,"s":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[-7.003,178.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[1.997,220.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":78.704,"s":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[1.997,220.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[6.997,159.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":81.519,"s":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[6.997,159.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,209.051],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":84.334,"s":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,209.051],[261,144]],"c":false}],"e":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,202.476],[261,144]],"c":false}]},{"t":88.0880880880881}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":96,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.96862745098,0.874509803922,0.549019607843,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":30,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 4","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":37.037,"s":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,202.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-157.997,69.524],[0,0]],"o":[[0,0],[89.76,-39.498],[0,0]],"v":[[-256,145],[53.997,60.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":41.041,"s":[{"i":[[0,0],[-157.997,69.524],[0,0]],"o":[[0,0],[89.76,-39.498],[0,0]],"v":[[-256,145],[53.997,60.476],[261,144]],"c":false}],"e":[{"i":[[-131,67],[-167.543,-41.544],[0,0]],"o":[[131,-67],[111.003,27.524],[0,0]],"v":[[-85,118],[177.997,-67.524],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":44.044,"s":[{"i":[[-131,67],[-167.543,-41.544],[0,0]],"o":[[131,-67],[111.003,27.524],[0,0]],"v":[[-85,118],[177.997,-67.524],[261,144]],"c":false}],"e":[{"i":[[-58.242,135.122],[-109.997,-11.476],[0,0]],"o":[[25,-58],[113.747,11.867],[0,0]],"v":[[95,56],[209.997,-128.524],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":46.046,"s":[{"i":[[-58.242,135.122],[-109.997,-11.476],[0,0]],"o":[[25,-58],[113.747,11.867],[0,0]],"v":[[95,56],[209.997,-128.524],[261,144]],"c":false}],"e":[{"i":[[-19.414,45.041],[-62.35,-12.578],[-16.222,-23.945]],"o":[[11.785,-72.253],[87.466,32.993],[30.606,47.27]],"v":[[156.215,-94.747],[225.35,-195.422],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":48.048,"s":[{"i":[[-19.414,45.041],[-62.35,-12.578],[-16.222,-23.945]],"o":[[11.785,-72.253],[87.466,32.993],[30.606,47.27]],"v":[[156.215,-94.747],[225.35,-195.422],[261,144]],"c":false}],"e":[{"i":[[0,0],[-63.35,-42.078],[-16.222,-23.945]],"o":[[0,0],[68.058,37.708],[30.606,47.27]],"v":[[161.715,-174.747],[260.35,-234.922],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":49.049,"s":[{"i":[[0,0],[-63.35,-42.078],[-16.222,-23.945]],"o":[[0,0],[68.058,37.708],[30.606,47.27]],"v":[[161.715,-174.747],[260.35,-234.922],[261,144]],"c":false}],"e":[{"i":[[-19.414,45.041],[-15.35,-48.578],[-16.222,-23.945]],"o":[[47.785,-55.253],[19.448,61.549],[30.606,47.27]],"v":[[163.215,-255.747],[295.35,-226.422],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":50.05,"s":[{"i":[[-19.414,45.041],[-15.35,-48.578],[-16.222,-23.945]],"o":[[47.785,-55.253],[19.448,61.549],[30.606,47.27]],"v":[[163.215,-255.747],[295.35,-226.422],[261,144]],"c":false}],"e":[{"i":[[0,0],[48.063,-75.399],[-16.181,-61.782]],"o":[[0,0],[-55.924,87.73],[0,0]],"v":[[201.995,-337.25],[261.924,-145.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":51.051,"s":[{"i":[[0,0],[48.063,-75.399],[-16.181,-61.782]],"o":[[0,0],[-55.924,87.73],[0,0]],"v":[[201.995,-337.25],[261.924,-145.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[25.07,-76.834],[-16.181,-61.782]],"o":[[0,0],[-29.695,91.056],[0,0]],"v":[[262.495,-339.75],[237.924,-129.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":52.052,"s":[{"i":[[0,0],[25.07,-76.834],[-16.181,-61.782]],"o":[[0,0],[-29.695,91.056],[0,0]],"v":[[262.495,-339.75],[237.924,-129.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[331.995,-309.25],[213.924,-128.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":53.053,"s":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[331.995,-309.25],[213.924,-128.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[371.495,-284.75],[217.924,-132.23],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":54.054,"s":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[371.495,-284.75],[217.924,-132.23],[261,144]],"c":false}],"e":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[395.995,-254.25],[228.924,-130.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":55.055,"s":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[395.995,-254.25],[228.924,-130.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[407.502,-239.456],[219.061,-134.017],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":69.069,"s":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[407.502,-239.456],[219.061,-134.017],[261,144]],"c":false}],"e":[{"i":[[0,0],[30.019,-141.415],[-16.181,-61.782]],"o":[[0,0],[-30.019,141.415],[0,0]],"v":[[422.296,-193.428],[222.348,-132.373],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":71.071,"s":[{"i":[[0,0],[30.019,-141.415],[-16.181,-61.782]],"o":[[0,0],[-30.019,141.415],[0,0]],"v":[[422.296,-193.428],[222.348,-132.373],[261,144]],"c":false}],"e":[{"i":[[0,0],[-32.611,-39.166],[-42.089,-15.667]],"o":[[-66,58],[41.234,49.522],[0,0]],"v":[[114,-144],[87.497,51.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":73.073,"s":[{"i":[[0,0],[-32.611,-39.166],[-42.089,-15.667]],"o":[[-66,58],[41.234,49.522],[0,0]],"v":[[114,-144],[87.497,51.476],[261,144]],"c":false}],"e":[{"i":[[-13,-44],[-165.271,-51.701],[-66,8]],"o":[[13,44],[72.003,22.524],[167.916,-20.353]],"v":[[-150,-19],[16.997,141.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":74.95,"s":[{"i":[[-13,-44],[-165.271,-51.701],[-66,8]],"o":[[13,44],[72.003,22.524],[167.916,-20.353]],"v":[[-150,-19],[16.997,141.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[-7.003,178.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":75.888,"s":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[-7.003,178.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[1.997,220.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":78.704,"s":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[1.997,220.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[6.997,159.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":81.519,"s":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[6.997,159.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,209.051],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":84.334,"s":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,209.051],[261,144]],"c":false}],"e":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,202.476],[261,144]],"c":false}]},{"t":88.0880880880881}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":5,"ix":1},"e":{"a":0,"k":1,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.96862745098,0.874509803922,0.549019607843,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":30,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 3","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":37.037,"s":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,202.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-157.997,69.524],[0,0]],"o":[[0,0],[89.76,-39.498],[0,0]],"v":[[-256,145],[53.997,60.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":41.041,"s":[{"i":[[0,0],[-157.997,69.524],[0,0]],"o":[[0,0],[89.76,-39.498],[0,0]],"v":[[-256,145],[53.997,60.476],[261,144]],"c":false}],"e":[{"i":[[-131,67],[-167.543,-41.544],[0,0]],"o":[[131,-67],[111.003,27.524],[0,0]],"v":[[-85,118],[177.997,-67.524],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":44.044,"s":[{"i":[[-131,67],[-167.543,-41.544],[0,0]],"o":[[131,-67],[111.003,27.524],[0,0]],"v":[[-85,118],[177.997,-67.524],[261,144]],"c":false}],"e":[{"i":[[-58.242,135.122],[-109.997,-11.476],[0,0]],"o":[[25,-58],[113.747,11.867],[0,0]],"v":[[95,56],[209.997,-128.524],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":46.046,"s":[{"i":[[-58.242,135.122],[-109.997,-11.476],[0,0]],"o":[[25,-58],[113.747,11.867],[0,0]],"v":[[95,56],[209.997,-128.524],[261,144]],"c":false}],"e":[{"i":[[-19.414,45.041],[-62.35,-12.578],[-16.222,-23.945]],"o":[[11.785,-72.253],[87.466,32.993],[30.606,47.27]],"v":[[156.215,-94.747],[225.35,-195.422],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":48.048,"s":[{"i":[[-19.414,45.041],[-62.35,-12.578],[-16.222,-23.945]],"o":[[11.785,-72.253],[87.466,32.993],[30.606,47.27]],"v":[[156.215,-94.747],[225.35,-195.422],[261,144]],"c":false}],"e":[{"i":[[0,0],[-63.35,-42.078],[-16.222,-23.945]],"o":[[0,0],[68.058,37.708],[30.606,47.27]],"v":[[161.715,-174.747],[260.35,-234.922],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":49.049,"s":[{"i":[[0,0],[-63.35,-42.078],[-16.222,-23.945]],"o":[[0,0],[68.058,37.708],[30.606,47.27]],"v":[[161.715,-174.747],[260.35,-234.922],[261,144]],"c":false}],"e":[{"i":[[-19.414,45.041],[-15.35,-48.578],[-16.222,-23.945]],"o":[[47.785,-55.253],[19.448,61.549],[30.606,47.27]],"v":[[163.215,-255.747],[295.35,-226.422],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":50.05,"s":[{"i":[[-19.414,45.041],[-15.35,-48.578],[-16.222,-23.945]],"o":[[47.785,-55.253],[19.448,61.549],[30.606,47.27]],"v":[[163.215,-255.747],[295.35,-226.422],[261,144]],"c":false}],"e":[{"i":[[0,0],[48.063,-75.399],[-16.181,-61.782]],"o":[[0,0],[-55.924,87.73],[0,0]],"v":[[201.995,-337.25],[261.924,-145.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":51.051,"s":[{"i":[[0,0],[48.063,-75.399],[-16.181,-61.782]],"o":[[0,0],[-55.924,87.73],[0,0]],"v":[[201.995,-337.25],[261.924,-145.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[25.07,-76.834],[-16.181,-61.782]],"o":[[0,0],[-29.695,91.056],[0,0]],"v":[[262.495,-339.75],[237.924,-129.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":52.052,"s":[{"i":[[0,0],[25.07,-76.834],[-16.181,-61.782]],"o":[[0,0],[-29.695,91.056],[0,0]],"v":[[262.495,-339.75],[237.924,-129.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[331.995,-309.25],[213.924,-128.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":53.053,"s":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[331.995,-309.25],[213.924,-128.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[371.495,-284.75],[217.924,-132.23],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":54.054,"s":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[371.495,-284.75],[217.924,-132.23],[261,144]],"c":false}],"e":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[395.995,-254.25],[228.924,-130.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":55.055,"s":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[395.995,-254.25],[228.924,-130.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[407.502,-239.456],[219.061,-134.017],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":69.069,"s":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[407.502,-239.456],[219.061,-134.017],[261,144]],"c":false}],"e":[{"i":[[0,0],[30.019,-141.415],[-16.181,-61.782]],"o":[[0,0],[-30.019,141.415],[0,0]],"v":[[422.296,-193.428],[222.348,-132.373],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":71.071,"s":[{"i":[[0,0],[30.019,-141.415],[-16.181,-61.782]],"o":[[0,0],[-30.019,141.415],[0,0]],"v":[[422.296,-193.428],[222.348,-132.373],[261,144]],"c":false}],"e":[{"i":[[0,0],[-32.611,-39.166],[-42.089,-15.667]],"o":[[-66,58],[41.234,49.522],[0,0]],"v":[[114,-144],[87.497,51.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":73.073,"s":[{"i":[[0,0],[-32.611,-39.166],[-42.089,-15.667]],"o":[[-66,58],[41.234,49.522],[0,0]],"v":[[114,-144],[87.497,51.476],[261,144]],"c":false}],"e":[{"i":[[-13,-44],[-165.271,-51.701],[-66,8]],"o":[[13,44],[72.003,22.524],[167.916,-20.353]],"v":[[-150,-19],[16.997,141.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":74.95,"s":[{"i":[[-13,-44],[-165.271,-51.701],[-66,8]],"o":[[13,44],[72.003,22.524],[167.916,-20.353]],"v":[[-150,-19],[16.997,141.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[-7.003,178.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":75.888,"s":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[-7.003,178.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[1.997,220.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":78.704,"s":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[1.997,220.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[6.997,159.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":81.519,"s":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[6.997,159.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,209.051],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":84.334,"s":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,209.051],[261,144]],"c":false}],"e":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,202.476],[261,144]],"c":false}]},{"t":88.0880880880881}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":2,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.96862745098,0.874509803922,0.549019607843,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":30,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":37.037,"s":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,202.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-157.997,69.524],[0,0]],"o":[[0,0],[89.76,-39.498],[0,0]],"v":[[-256,145],[53.997,60.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":41.041,"s":[{"i":[[0,0],[-157.997,69.524],[0,0]],"o":[[0,0],[89.76,-39.498],[0,0]],"v":[[-256,145],[53.997,60.476],[261,144]],"c":false}],"e":[{"i":[[-131,67],[-167.543,-41.544],[0,0]],"o":[[131,-67],[111.003,27.524],[0,0]],"v":[[-85,118],[177.997,-67.524],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":44.044,"s":[{"i":[[-131,67],[-167.543,-41.544],[0,0]],"o":[[131,-67],[111.003,27.524],[0,0]],"v":[[-85,118],[177.997,-67.524],[261,144]],"c":false}],"e":[{"i":[[-58.242,135.122],[-109.997,-11.476],[0,0]],"o":[[25,-58],[113.747,11.867],[0,0]],"v":[[95,56],[209.997,-128.524],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":46.046,"s":[{"i":[[-58.242,135.122],[-109.997,-11.476],[0,0]],"o":[[25,-58],[113.747,11.867],[0,0]],"v":[[95,56],[209.997,-128.524],[261,144]],"c":false}],"e":[{"i":[[-19.414,45.041],[-62.35,-12.578],[-16.222,-23.945]],"o":[[11.785,-72.253],[87.466,32.993],[30.606,47.27]],"v":[[156.215,-94.747],[225.35,-195.422],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":48.048,"s":[{"i":[[-19.414,45.041],[-62.35,-12.578],[-16.222,-23.945]],"o":[[11.785,-72.253],[87.466,32.993],[30.606,47.27]],"v":[[156.215,-94.747],[225.35,-195.422],[261,144]],"c":false}],"e":[{"i":[[0,0],[-63.35,-42.078],[-16.222,-23.945]],"o":[[0,0],[68.058,37.708],[30.606,47.27]],"v":[[161.715,-174.747],[260.35,-234.922],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":49.049,"s":[{"i":[[0,0],[-63.35,-42.078],[-16.222,-23.945]],"o":[[0,0],[68.058,37.708],[30.606,47.27]],"v":[[161.715,-174.747],[260.35,-234.922],[261,144]],"c":false}],"e":[{"i":[[-19.414,45.041],[-15.35,-48.578],[-16.222,-23.945]],"o":[[47.785,-55.253],[19.448,61.549],[30.606,47.27]],"v":[[163.215,-255.747],[295.35,-226.422],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":50.05,"s":[{"i":[[-19.414,45.041],[-15.35,-48.578],[-16.222,-23.945]],"o":[[47.785,-55.253],[19.448,61.549],[30.606,47.27]],"v":[[163.215,-255.747],[295.35,-226.422],[261,144]],"c":false}],"e":[{"i":[[0,0],[48.063,-75.399],[-16.181,-61.782]],"o":[[0,0],[-55.924,87.73],[0,0]],"v":[[201.995,-337.25],[261.924,-145.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":51.051,"s":[{"i":[[0,0],[48.063,-75.399],[-16.181,-61.782]],"o":[[0,0],[-55.924,87.73],[0,0]],"v":[[201.995,-337.25],[261.924,-145.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[25.07,-76.834],[-16.181,-61.782]],"o":[[0,0],[-29.695,91.056],[0,0]],"v":[[262.495,-339.75],[237.924,-129.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":52.052,"s":[{"i":[[0,0],[25.07,-76.834],[-16.181,-61.782]],"o":[[0,0],[-29.695,91.056],[0,0]],"v":[[262.495,-339.75],[237.924,-129.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[331.995,-309.25],[213.924,-128.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":53.053,"s":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[331.995,-309.25],[213.924,-128.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[371.495,-284.75],[217.924,-132.23],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":54.054,"s":[{"i":[[0,0],[2.076,-78.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.383],[0,0]],"v":[[371.495,-284.75],[217.924,-132.23],[261,144]],"c":false}],"e":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[395.995,-254.25],[228.924,-130.73],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":55.055,"s":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[395.995,-254.25],[228.924,-130.73],[261,144]],"c":false}],"e":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[407.502,-239.456],[219.061,-134.017],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":69.069,"s":[{"i":[[0,0],[0,-112.27],[-16.181,-61.782]],"o":[[0,0],[-3.467,94.382],[0,0]],"v":[[407.502,-239.456],[219.061,-134.017],[261,144]],"c":false}],"e":[{"i":[[0,0],[30.019,-141.415],[-16.181,-61.782]],"o":[[0,0],[-30.019,141.415],[0,0]],"v":[[422.296,-193.428],[222.348,-132.373],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":71.071,"s":[{"i":[[0,0],[30.019,-141.415],[-16.181,-61.782]],"o":[[0,0],[-30.019,141.415],[0,0]],"v":[[422.296,-193.428],[222.348,-132.373],[261,144]],"c":false}],"e":[{"i":[[0,0],[-32.611,-39.166],[-42.089,-15.667]],"o":[[-66,58],[41.234,49.522],[0,0]],"v":[[114,-144],[87.497,51.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":73.073,"s":[{"i":[[0,0],[-32.611,-39.166],[-42.089,-15.667]],"o":[[-66,58],[41.234,49.522],[0,0]],"v":[[114,-144],[87.497,51.476],[261,144]],"c":false}],"e":[{"i":[[-13,-44],[-165.271,-51.701],[-66,8]],"o":[[13,44],[72.003,22.524],[167.916,-20.353]],"v":[[-150,-19],[16.997,141.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":74.95,"s":[{"i":[[-13,-44],[-165.271,-51.701],[-66,8]],"o":[[13,44],[72.003,22.524],[167.916,-20.353]],"v":[[-150,-19],[16.997,141.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[-7.003,178.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":75.888,"s":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[-7.003,178.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[1.997,220.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":78.704,"s":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[1.997,220.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[6.997,159.476],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":81.519,"s":[{"i":[[0,0],[-124.003,0.476],[-66,8]],"o":[[0,0],[124.003,-0.476],[167.916,-20.353]],"v":[[-254,144],[6.997,159.476],[261,144]],"c":false}],"e":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,209.051],[261,144]],"c":false}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":84.334,"s":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,209.051],[261,144]],"c":false}],"e":[{"i":[[0,0],[-98.003,-3.524],[0,0]],"o":[[0,0],[98.003,3.524],[0,0]],"v":[[-256,145],[12.997,202.476],[261,144]],"c":false}]},{"t":88.0880880880881}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":2,"ix":1},"e":{"a":0,"k":95,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.952941176471,0.541176470588,0.470588235294,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":25,"ix":5},"lc":3,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":-26.026026026026,"op":637.637637637638,"st":37.037037037037,"bm":0}]},{"id":"comp_3","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Person","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1052,212,0],"ix":2},"a":{"a":0,"k":[62,101,0],"ix":1},"s":{"a":0,"k":[130,130,100],"ix":6}},"ao":0,"ef":[{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":1,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":0,"k":[0,0,0.027450980619,1],"ix":3,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]},{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":2,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":1,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":3,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":3,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"w":124,"h":202,"ip":-7.00700700700701,"op":593.593593593594,"st":-7.00700700700701,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"Person","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[850,212,0],"ix":2},"a":{"a":0,"k":[62,101,0],"ix":1},"s":{"a":0,"k":[130,130,100],"ix":6}},"ao":0,"ef":[{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":1,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":0,"k":[0,0,0.027450980619,1],"ix":3,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]},{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":2,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":1,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":3,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":3,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"w":124,"h":202,"ip":-7.00700700700701,"op":593.593593593594,"st":-7.00700700700701,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"Person","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[958,212,0],"ix":2},"a":{"a":0,"k":[62,101,0],"ix":1},"s":{"a":0,"k":[130,130,100],"ix":6}},"ao":0,"ef":[{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":1,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":0,"k":[0,0,0.027450980619,1],"ix":3,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]},{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":2,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":1,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":3,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":3,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":" ","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"w":124,"h":202,"ip":-7.00700700700701,"op":593.593593593594,"st":-7.00700700700701,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"Person","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[756,212,0],"ix":2},"a":{"a":0,"k":[62,101,0],"ix":1},"s":{"a":0,"k":[130,130,100],"ix":6}},"ao":0,"ef":[{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":1,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":0,"k":[0,0,0.027450980619,1],"ix":3,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]},{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":2,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":1,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":3,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":3,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"w":124,"h":202,"ip":-7.00700700700701,"op":593.593593593594,"st":-7.00700700700701,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"Person","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[668,212,0],"ix":2},"a":{"a":0,"k":[62,101,0],"ix":1},"s":{"a":0,"k":[130,130,100],"ix":6}},"ao":0,"ef":[{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":1,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":0,"k":[0,0,0.027450980619,1],"ix":3,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]},{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":2,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":1,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":3,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":3,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"w":124,"h":202,"ip":-7.00700700700701,"op":593.593593593594,"st":-7.00700700700701,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"Person","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[466,212,0],"ix":2},"a":{"a":0,"k":[62,101,0],"ix":1},"s":{"a":0,"k":[130,130,100],"ix":6}},"ao":0,"ef":[{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":1,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":0,"k":[0,0,0.027450980619,1],"ix":3,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]},{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":2,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":1,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":3,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":3,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"w":124,"h":202,"ip":-7.00700700700701,"op":593.593593593594,"st":-7.00700700700701,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"Person","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[574,212,0],"ix":2},"a":{"a":0,"k":[62,101,0],"ix":1},"s":{"a":0,"k":[130,130,100],"ix":6}},"ao":0,"ef":[{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":1,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":0,"k":[0,0,0.027450980619,1],"ix":3,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]},{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":2,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":1,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":3,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":3,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"w":124,"h":202,"ip":-7.00700700700701,"op":593.593593593594,"st":-7.00700700700701,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"Person","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[372,212,0],"ix":2},"a":{"a":0,"k":[62,101,0],"ix":1},"s":{"a":0,"k":[130,130,100],"ix":6}},"ao":0,"ef":[{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":1,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":0,"k":[0,0,0.027450980619,1],"ix":3,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]},{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":2,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":1,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":3,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":3,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"w":124,"h":202,"ip":-7.00700700700701,"op":593.593593593594,"st":-7.00700700700701,"bm":0}]},{"id":"comp_4","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"body 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60.83,132,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[31,31,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-59,0],[0,-59],[0,0]],"o":[[0,0],[0,-59],[59,0],[0,0],[0,0]],"v":[[-107,166.5],[-107,-59.5],[0,-166.5],[107,-59.5],[107,166.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0.023529412225,1],"ix":3,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0.023529412225,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-8.00800800800801,"op":592.592592592593,"st":-8.00800800800801,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Head 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60,45.305,0],"ix":2},"a":{"a":0,"k":[-156.695,39.305,0],"ix":1},"s":{"a":0,"k":[68,68,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[105.391,105.391],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0.023529412225,1],"ix":3,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0.023529412225,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-156.695,39.305],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-3.003003003003,"op":597.597597597598,"st":-3.003003003003,"bm":0}]},{"id":"comp_5","layers":[{"ddd":0,"ind":3,"ty":0,"nm":"Person","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[-15],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":4.505,"s":[0],"e":[8]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":9.009,"s":[8],"e":[-11]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":13.514,"s":[-11],"e":[13]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":18.018,"s":[13],"e":[13]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":24.024,"s":[13],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":30.03,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":42.042,"s":[0],"e":[-6]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":55.055,"s":[-6],"e":[-17.016]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":60.06,"s":[-17.016],"e":[17]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":64.064,"s":[17],"e":[-13]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":69.069,"s":[-13],"e":[23]},{"t":75.0750750750751}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[-52.424,794.634,0],"e":[94.576,820.634,0],"to":[62.4243774414062,-102.634155273438,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":4.505,"s":[94.576,820.634,0],"e":[271.576,820.634,0],"to":[0,0,0],"ti":[-93.5756225585938,-156.634155273438,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":9.009,"s":[271.576,820.634,0],"e":[448.576,806.634,0],"to":[2.57562255859375,-2.3658447265625,0],"ti":[-99.5756225585938,-121.634155273438,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":13.514,"s":[448.576,806.634,0],"e":[530.576,821.634,0],"to":[45.5756225585938,-49.3658447265625,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":18.018,"s":[530.576,821.634,0],"e":[603.576,821.634,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.578,"y":0.578},"o":{"x":0.167,"y":0.167},"n":"0p578_0p578_0p167_0p167","t":27.027,"s":[603.576,821.634,0],"e":[603.576,821.634,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.578,"y":1},"o":{"x":0.344,"y":0},"n":"0p578_1_0p344_0","t":42.042,"s":[603.576,821.634,0],"e":[603.576,812.634,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.344,"y":0},"n":"0p833_0p833_0p344_0","t":55.055,"s":[603.576,812.634,0],"e":[797.576,798.634,0],"to":[0,0,0],"ti":[-84,-62.1666679382324,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":60.06,"s":[797.576,798.634,0],"e":[951.576,823.634,0],"to":[23,-36.8333320617676,0],"ti":[-27.4243774414062,-58.3658447265625,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":64.064,"s":[951.576,823.634,0],"e":[1157.576,803.634,0],"to":[61.6717796325684,-103.519493103027,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":69.069,"s":[1157.576,803.634,0],"e":[1378.576,825.634,0],"to":[0,0,0],"ti":[-82.5756225585938,-100.634155273438,0]},{"t":75.0750750750751}],"ix":2},"a":{"a":0,"k":[94.308,184.077,0],"ix":1},"s":{"a":0,"k":[130,130,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"n","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-17.31,-0.493],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[17.31,0.493],[0,0],[0,0]],"v":[[128.48,-7.642],[-6.054,-7.642],[-6.054,79.804],[41.173,86.727],[62.708,80.403],[81.173,87.112],[128.48,79.804]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"ef":[{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":1,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":0,"k":[0.203921571374,0.701960802078,0.89411765337,1],"ix":3,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]}],"w":124,"h":202,"ip":-7.00700700700701,"op":593.593593593594,"st":-7.00700700700701,"bm":0}]},{"id":"comp_6","layers":[{"ddd":0,"ind":2,"ty":0,"nm":"ball top","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[123,36,0],"ix":2},"a":{"a":0,"k":[55.5,55.5,0],"ix":1},"s":{"a":0,"k":[53,53,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Change to Color 3","np":13,"mn":"ADBE Change To Color","ix":1,"en":1,"ef":[{"ty":2,"nm":"From","mn":"ADBE Change To Color-0001","ix":1,"v":{"a":0,"k":[0.917647063732,0.921568632126,0.937254905701,1],"ix":1}},{"ty":2,"nm":"To","mn":"ADBE Change To Color-0002","ix":2,"v":{"a":0,"k":[0.792156875134,0.800000011921,0.807843148708,1],"ix":2}},{"ty":7,"nm":"Change","mn":"ADBE Change To Color-0003","ix":3,"v":{"a":0,"k":4,"ix":3}},{"ty":7,"nm":"Change By","mn":"ADBE Change To Color-0004","ix":4,"v":{"a":0,"k":1,"ix":4}},{"ty":6,"nm":"Tolerance","mn":"ADBE Change To Color-0010","ix":5,"v":0},{"ty":0,"nm":"Hue","mn":"ADBE Change To Color-0005","ix":6,"v":{"a":0,"k":0.03,"ix":6}},{"ty":0,"nm":"Lightness","mn":"ADBE Change To Color-0006","ix":7,"v":{"a":0,"k":1,"ix":7}},{"ty":0,"nm":"Saturation","mn":"ADBE Change To Color-0007","ix":8,"v":{"a":0,"k":1,"ix":8}},{"ty":6,"nm":"Saturation","mn":"ADBE Change To Color-0011","ix":9,"v":0},{"ty":0,"nm":"Softness","mn":"ADBE Change To Color-0008","ix":10,"v":{"a":0,"k":0.5,"ix":10}},{"ty":7,"nm":"View Correction Matte","mn":"ADBE Change To Color-0009","ix":11,"v":{"a":0,"k":0,"ix":11}}]},{"ty":5,"nm":"Change to Color 2","np":13,"mn":"ADBE Change To Color","ix":2,"en":1,"ef":[{"ty":2,"nm":"From","mn":"ADBE Change To Color-0001","ix":1,"v":{"a":0,"k":[0.819607853889,0.831372559071,0.858823537827,1],"ix":1}},{"ty":2,"nm":"To","mn":"ADBE Change To Color-0002","ix":2,"v":{"a":0,"k":[0.615686297417,0.623529434204,0.631372570992,1],"ix":2}},{"ty":7,"nm":"Change","mn":"ADBE Change To Color-0003","ix":3,"v":{"a":0,"k":4,"ix":3}},{"ty":7,"nm":"Change By","mn":"ADBE Change To Color-0004","ix":4,"v":{"a":0,"k":1,"ix":4}},{"ty":6,"nm":"Tolerance","mn":"ADBE Change To Color-0010","ix":5,"v":0},{"ty":0,"nm":"Hue","mn":"ADBE Change To Color-0005","ix":6,"v":{"a":0,"k":0.03,"ix":6}},{"ty":0,"nm":"Lightness","mn":"ADBE Change To Color-0006","ix":7,"v":{"a":0,"k":1,"ix":7}},{"ty":0,"nm":"Saturation","mn":"ADBE Change To Color-0007","ix":8,"v":{"a":0,"k":1,"ix":8}},{"ty":6,"nm":"Saturation","mn":"ADBE Change To Color-0011","ix":9,"v":0},{"ty":0,"nm":"Softness","mn":"ADBE Change To Color-0008","ix":10,"v":{"a":0,"k":0.5,"ix":10}},{"ty":7,"nm":"View Correction Matte","mn":"ADBE Change To Color-0009","ix":11,"v":{"a":0,"k":0,"ix":11}}]}],"sy":[{"ty":0,"nm":"Stroke","c":{"a":0,"k":[0.615686297417,0.623529434204,0.631372570992,1],"ix":2},"s":{"a":0,"k":1,"ix":3}}],"w":111,"h":111,"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[123.676,138.221,0],"ix":2},"a":{"a":0,"k":[-349.324,174.221,0],"ix":1},"s":{"a":0,"k":[157.387,91,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[9.352,225.559],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0.027450980619,1],"ix":3,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156862745,0.8,0.807843137255,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-349.324,174.221],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[476,-48,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[54.023,17.809],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.61568627451,0.623529411765,0.63137254902,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156862745,0.8,0.807843137255,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-352.988,139.096],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[122.001,225.774,0],"ix":2},"a":{"a":0,"k":[0.001,0.957,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.597,0],[0,0],[2.123,1.482],[0,0],[10.938,-7.532],[0,0]],"o":[[0,0],[2.589,0],[0,0],[-10.891,-7.6],[0,0],[-2.139,1.473]],"v":[[-42.541,15.183],[42.544,15.183],[44.058,10.367],[18.4,-7.538],[-17.892,-7.651],[-44.042,10.358]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.61568627451,0.623529411765,0.63137254902,1],"ix":3,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156862745,0.8,0.807843137255,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0}]},{"id":"comp_7","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 5","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[55.697,55.697,0],"ix":2},"a":{"a":0,"k":[-325.303,-176.303,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[107.395,107.395],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0.027450980619,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0.027450980619,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-325.303,-176.303],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 3","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,232,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[171.367,158.457],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0.023529412225,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.917647058824,0.921568627451,0.937254901961,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-349.512,-215.295],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[55.697,55.697,0],"ix":2},"a":{"a":0,"k":[-325.303,-176.303,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[107.395,107.395],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0.027450980619,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.819607843137,0.83137254902,0.858823529412,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-325.303,-176.303],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0}]},{"id":"comp_8","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"party thing","refId":"comp_9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[869,465,0],"ix":2},"a":{"a":0,"k":[942,467,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Spotlight 2","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":-17.017,"s":[0],"e":[-39]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":17.017,"s":[-39],"e":[-11]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":53.053,"s":[-11],"e":[-39]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":87.087,"s":[-39],"e":[-11]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":123.123,"s":[-11],"e":[-39]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":152.152,"s":[-39],"e":[-11]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":188.188,"s":[-11],"e":[-39]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":222.222,"s":[-39],"e":[-11]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":258.258,"s":[-11],"e":[-39]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":292.292,"s":[-39],"e":[-11]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":328.328,"s":[-11],"e":[-39]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":357.357,"s":[-39],"e":[-11]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":393.393,"s":[-11],"e":[-39]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":427.427,"s":[-39],"e":[-11]},{"t":463.463463463463}],"ix":10},"p":{"a":0,"k":[1108,378,0],"ix":2},"a":{"a":0,"k":[-158,-162,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-166,-182],[-140,416],[296,268]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.639215686275,0.862745098039,0.952941176471,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-17.017017017017,"op":583.583583583584,"st":-17.017017017017,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,508,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[575.859,143.445],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[25.93,266.277],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"body 13","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[813.83,684,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[31,31,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-59,0],[0,-59],[0,0]],"o":[[0,0],[0,-59],[59,0],[0,0],[0,0]],"v":[[-107,166.5],[-107,-59.5],[0,-166.5],[107,-59.5],[107,166.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"body 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1066.83,674,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[31,31,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-59,0],[0,-59],[0,0]],"o":[[0,0],[0,-59],[59,0],[0,0],[0,0]],"v":[[-107,166.5],[-107,-59.5],[0,-166.5],[107,-59.5],[107,166.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"body 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[942.83,670,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[31,31,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-59,0],[0,-59],[0,0]],"o":[[0,0],[0,-59],[59,0],[0,0],[0,0]],"v":[[-107,166.5],[-107,-59.5],[0,-166.5],[107,-59.5],[107,166.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"body 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[910.83,698,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[31,31,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-59,0],[0,-59],[0,0]],"o":[[0,0],[0,-59],[59,0],[0,0],[0,0]],"v":[[-107,166.5],[-107,-59.5],[0,-166.5],[107,-59.5],[107,166.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"body 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1002.83,730,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[31,31,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-59,0],[0,-59],[0,0]],"o":[[0,0],[0,-59],[59,0],[0,0],[0,0]],"v":[[-107,166.5],[-107,-59.5],[0,-166.5],[107,-59.5],[107,166.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"body 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1066.83,690,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[31,31,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-59,0],[0,-59],[0,0]],"o":[[0,0],[0,-59],[59,0],[0,0],[0,0]],"v":[[-107,166.5],[-107,-59.5],[0,-166.5],[107,-59.5],[107,166.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"body 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[947.17,716,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[31,31,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-59,0],[0,-59],[0,0]],"o":[[0,0],[0,-59],[59,0],[0,0],[0,0]],"v":[[-107,166.5],[-107,-59.5],[0,-166.5],[107,-59.5],[107,166.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"body 10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1092,724,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[31,31,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-59,0],[0,-59],[0,0]],"o":[[0,0],[0,-59],[59,0],[0,0],[0,0]],"v":[[-107,166.5],[-107,-59.5],[0,-166.5],[107,-59.5],[107,166.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"body 9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[875.17,690,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[31,31,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-59,0],[0,-59],[0,0]],"o":[[0,0],[0,-59],[59,0],[0,0],[0,0]],"v":[[-107,166.5],[-107,-59.5],[0,-166.5],[107,-59.5],[107,166.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"body 11","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[985.17,664,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[31,31,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-59,0],[0,-59],[0,0]],"o":[[0,0],[0,-59],[59,0],[0,0],[0,0]],"v":[[-107,166.5],[-107,-59.5],[0,-166.5],[107,-59.5],[107,166.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"body","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[908,686,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[31,31,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-59,0],[0,-59],[0,0]],"o":[[0,0],[0,-59],[59,0],[0,0],[0,0]],"v":[[-107,166.5],[-107,-59.5],[0,-166.5],[107,-59.5],[107,166.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":0,"nm":"party thing","refId":"comp_9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[994.5,416.5,0],"ix":2},"a":{"a":0,"k":[942,467,0],"ix":1},"s":{"a":0,"k":[103,103,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":0,"nm":"party thing","refId":"comp_9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1053,525.5,0],"ix":2},"a":{"a":0,"k":[942,467,0],"ix":1},"s":{"a":0,"k":[47,47,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Head 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1100,657.305,0],"ix":2},"a":{"a":0,"k":[-156.695,39.305,0],"ix":1},"s":{"a":0,"k":[68,68,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[105.391,105.391],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-156.695,39.305],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Head 12","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[815.305,609.305,0],"ix":2},"a":{"a":0,"k":[-156.695,39.305,0],"ix":1},"s":{"a":0,"k":[68,68,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[105.391,105.391],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-156.695,39.305],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"Head 10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[874.305,608.305,0],"ix":2},"a":{"a":0,"k":[-156.695,39.305,0],"ix":1},"s":{"a":0,"k":[68,68,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[105.391,105.391],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-156.695,39.305],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Head 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1013.305,659.305,0],"ix":2},"a":{"a":0,"k":[-156.695,39.305,0],"ix":1},"s":{"a":0,"k":[68,68,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[105.391,105.391],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-156.695,39.305],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"Head 9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[961.305,661.305,0],"ix":2},"a":{"a":0,"k":[-156.695,39.305,0],"ix":1},"s":{"a":0,"k":[68,68,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[105.391,105.391],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-156.695,39.305],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":"Head 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[885.305,661.305,0],"ix":2},"a":{"a":0,"k":[-156.695,39.305,0],"ix":1},"s":{"a":0,"k":[68,68,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[105.391,105.391],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-156.695,39.305],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":24,"ty":4,"nm":"Spotlight","sr":1,"ks":{"o":{"a":0,"k":55,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":0,"s":[0],"e":[41]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":34.034,"s":[41],"e":[0]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":70.07,"s":[0],"e":[41]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":104.104,"s":[41],"e":[0]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":140.14,"s":[0],"e":[41]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":174.174,"s":[41],"e":[0]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":210.21,"s":[0],"e":[41]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":244.244,"s":[41],"e":[0]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":280.28,"s":[0],"e":[41]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":314.314,"s":[41],"e":[0]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":350.35,"s":[0],"e":[41]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":384.384,"s":[41],"e":[0]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":420.42,"s":[0],"e":[41]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":454.454,"s":[41],"e":[0]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":490.49,"s":[0],"e":[41]},{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.4],"y":[0]},"n":["0p4_1_0p4_0"],"t":524.525,"s":[41],"e":[0]},{"t":560.560560560561}],"ix":10},"p":{"a":0,"k":[802,378,0],"ix":2},"a":{"a":0,"k":[-158,-162,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-166,-182],[-140,416],[296,268]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.811764705882,0.929411764706,0.98431372549,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":25,"ty":4,"nm":"Head 11","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[804.305,610.305,0],"ix":2},"a":{"a":0,"k":[-156.695,39.305,0],"ix":1},"s":{"a":0,"k":[68,68,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[105.391,105.391],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-156.695,39.305],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":26,"ty":4,"nm":"body 12","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[804.17,686,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[31,31,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-59,0],[0,-59],[0,0]],"o":[[0,0],[0,-59],[59,0],[0,0],[0,0]],"v":[[-107,166.5],[-107,-59.5],[0,-166.5],[107,-59.5],[107,166.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":27,"ty":4,"nm":"body 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[861.17,686,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[31,31,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-59,0],[0,-59],[0,0]],"o":[[0,0],[0,-59],[59,0],[0,0],[0,0]],"v":[[-107,166.5],[-107,-59.5],[0,-166.5],[107,-59.5],[107,166.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":28,"ty":4,"nm":"Head 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1061.305,609.305,0],"ix":2},"a":{"a":0,"k":[-156.695,39.305,0],"ix":1},"s":{"a":0,"k":[68,68,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[105.391,105.391],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-156.695,39.305],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":29,"ty":4,"nm":"Head 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[991.305,609.305,0],"ix":2},"a":{"a":0,"k":[-156.695,39.305,0],"ix":1},"s":{"a":0,"k":[68,68,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[105.391,105.391],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-156.695,39.305],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":30,"ty":4,"nm":"Head 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[919.305,609.305,0],"ix":2},"a":{"a":0,"k":[-156.695,39.305,0],"ix":1},"s":{"a":0,"k":[68,68,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[105.391,105.391],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-156.695,39.305],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":31,"ty":4,"nm":"Head","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[853.305,609.305,0],"ix":2},"a":{"a":0,"k":[-156.695,39.305,0],"ix":1},"s":{"a":0,"k":[68,68,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Wiggle - position","np":4,"mn":"ADBE CM WigglePosition","ix":1,"en":1,"ef":[{"ty":0,"nm":"Wiggle Speed (wigs/sec)","mn":"ADBE CM WigglePosition-0001","ix":1,"v":{"a":0,"k":2,"ix":1}},{"ty":0,"nm":"Wiggle Amount (pixels)","mn":"ADBE CM WigglePosition-0002","ix":2,"v":{"a":0,"k":15,"ix":2}}]},{"ty":5,"nm":"(Transform)","np":15,"mn":"ADBE Geometry2","ix":2,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[0,0],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[0,0],"ix":2,"x":"var $bm_rt;\n$bm_rt = wiggle(effect('Wiggle - position')('Wiggle Speed (wigs/sec)'), effect('Wiggle - position')('Wiggle Amount (pixels)'));"}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale Height","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":"Scale Width","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":13,"v":{"a":0,"k":1,"ix":13}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[105.391,105.391],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921568627,0.701960784314,0.894117647059,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-156.695,39.305],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0},{"ddd":0,"ind":32,"ty":4,"nm":"background","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Gradient Ramp","np":11,"mn":"ADBE Ramp","ix":1,"en":1,"ef":[{"ty":3,"nm":"Start of Ramp","mn":"ADBE Ramp-0001","ix":1,"v":{"a":0,"k":[952,297],"ix":1}},{"ty":2,"nm":"Start Color","mn":"ADBE Ramp-0002","ix":2,"v":{"a":0,"k":[0.811764717102,0.929411768913,0.984313726425,1],"ix":2}},{"ty":3,"nm":"End of Ramp","mn":"ADBE Ramp-0003","ix":3,"v":{"a":0,"k":[953,632],"ix":3}},{"ty":2,"nm":"End Color","mn":"ADBE Ramp-0004","ix":4,"v":{"a":0,"k":[0.423529416323,0.780392169952,0.917647063732,1],"ix":4}},{"ty":7,"nm":"Ramp Shape","mn":"ADBE Ramp-0005","ix":5,"v":{"a":0,"k":1,"ix":5}},{"ty":0,"nm":"Ramp Scatter","mn":"ADBE Ramp-0006","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Blend With Original","mn":"ADBE Ramp-0007","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":6,"nm":"","mn":"ADBE Ramp-0008","ix":8,"v":0},{"ty":7,"nm":"GPU Rendering","mn":"ADBE Force CPU GPU","ix":9,"v":{"a":0,"k":1,"ix":9}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[1920,1080],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.407843137255,0.780392156863,0.925490196078,1],"ix":4,"x":"var $bm_rt;\nvar rayColorPalette, rayColorSwatch;\ntry {\n rayColorPalette = 'Ray - palette 01';\n rayColorSwatch = Math.floor(mul(value[2], 255));\n $bm_rt = comp(rayColorPalette).layer(1)(4)(rayColorSwatch)(1);\n} catch (e) {\n $bm_rt = value;\n}"},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-2.002002002002,"op":598.598598598599,"st":-2.002002002002,"bm":0}]},{"id":"comp_9","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":61,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[16],"e":[1816]},{"t":463.463463463463}],"ix":10},"p":{"a":0,"k":[944,466,0],"ix":2},"a":{"a":0,"k":[-16,-74,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":0,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":6.006,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":15.015,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":21.021,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":30.03,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":36.036,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":45.045,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":51.051,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":60.06,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":66.066,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":75.075,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":81.081,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":90.09,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":96.096,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":105.105,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":111.111,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":120.12,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":126.126,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":135.135,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":141.141,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":150.15,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":156.156,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":165.165,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":171.171,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":180.18,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":186.186,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":195.195,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":201.201,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":210.21,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":216.216,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":225.225,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":231.231,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":240.24,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":246.246,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":255.255,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":261.261,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":270.27,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":276.276,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":285.285,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":291.291,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":300.3,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":306.306,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":315.315,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":321.321,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":330.33,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":336.336,"s":[131,131,100],"e":[47,47,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":345.345,"s":[47,47,100],"e":[131,131,100]},{"i":{"x":[0.4,0.4,0.4],"y":[1,1,1]},"o":{"x":[0.6,0.6,0.6],"y":[0,0,0]},"n":["0p4_1_0p6_0","0p4_1_0p6_0","0p4_1_0p6_0"],"t":351.351,"s":[131,131,100],"e":[47,47,100]},{"t":360.36036036036}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-28.016,-70.555],[-4.603,-77.788]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.901960784314,0.952941176471,0.98431372549,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-20,-86],[-13.032,-63.785]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.901960784314,0.952941176471,0.98431372549,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":14,"ix":5},"lc":2,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600.600600600601,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Members First","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[531,420,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[64,64,100],"ix":6}},"ao":0,"w":1920,"h":1080,"ip":0,"op":600.600600600601,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/uxsampletest.cpp b/presentation/src/main/cpp/third_party/rlottie/example/uxsampletest.cpp deleted file mode 100644 index 519e6003..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/uxsampletest.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include"evasapp.h" -#include "lottieview.h" -#include -#include -#include - -class UxSampleTest -{ -public: - UxSampleTest(EvasApp *app, bool renderMode) { - mApp = app; - mRenderMode = renderMode; - mResourceList = EvasApp::jsonFiles(std::string(DEMO_DIR) + "UXSample_1920x1080/"); - mRepeatMode = LottieView::RepeatMode::Restart; - } - - void showPrev() { - if (mResourceList.empty()) return; - mCurIndex--; - if (mCurIndex < 0) - mCurIndex = mResourceList.size() - 1; - show(); - } - - void showNext() { - if (mResourceList.empty()) return; - - mCurIndex++; - if (mCurIndex >= int(mResourceList.size())) - mCurIndex = 0; - show(); - } - - void resize() { - if (mView) { - mView->setSize(mApp->width(), mApp->height()); - } - } - -private: - void show() { - mView = std::make_unique(mApp->evas(), Strategy::renderCAsync); - mView->setFilePath(mResourceList[mCurIndex].c_str()); - mView->setPos(0, 0); - mView->setSize(mApp->width(), mApp->height()); - mView->show(); - mView->play(); - mView->loop(true); - mView->setRepeatMode(mRepeatMode); - } - -public: - EvasApp *mApp; - bool mRenderMode = false; - int mCurIndex = -1; - std::vector mResourceList; - std::unique_ptr mView; - LottieView::RepeatMode mRepeatMode; -}; - -static void -onExitCb(void *data, void */*extra*/) -{ - UxSampleTest *view = (UxSampleTest *)data; - delete view; -} - -static void -onKeyCb(void *data, void *extra) -{ - UxSampleTest *view = (UxSampleTest *)data; - char *keyname = (char *)extra; - - if (!strcmp(keyname, "Right") || !strcmp(keyname, "n")) { - view->showNext(); - } else if (!strcmp(keyname, "Left") || !strcmp(keyname, "p")) { - view->showPrev(); - } else if (!strcmp(keyname,"r")) { - if (view->mRepeatMode == LottieView::RepeatMode::Restart) { - view->mRepeatMode = LottieView::RepeatMode::Reverse; - } else - view->mRepeatMode = LottieView::RepeatMode::Restart; - if (view->mView) - view->mView->setRepeatMode(view->mRepeatMode); - } -} - -static void -onResizeCb(void *data, void */*extra*/) -{ - UxSampleTest *view = (UxSampleTest *)data; - view->resize(); -} - -int -main(int argc, char **argv) -{ - EvasApp *app = new EvasApp(800, 800); - app->setup(); - - bool renderMode = true; - if (argc > 1) { - if (!strcmp(argv[1],"--disable-render")) - renderMode = false; - } - UxSampleTest *view = new UxSampleTest(app, renderMode); - view->showNext(); - - app->addExitCb(onExitCb, view); - app->addKeyCb(onKeyCb, view); - app->addResizeCb(onResizeCb, view); - - app->run(); - delete app; - return 0; -} diff --git a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/Source.cpp b/presentation/src/main/cpp/third_party/rlottie/example/win32Player/Source.cpp deleted file mode 100644 index 99ea876d..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/Source.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "rlottie.h" -#include "animation.h" -using namespace rlottie; - -std::unique_ptr anim; -uint32_t *buffer; -size_t width, height; -size_t bytesPerLine; -uint32_t curColor = UINT32_MAX; - -void setAnimationSize(size_t w, size_t h) -{ - width = w; - height = h; - bytesPerLine = width * sizeof(uint32_t); - - if (buffer != NULL) freeAnimation(); - buffer = (uint32_t*)calloc(bytesPerLine * height, sizeof(uint32_t)); -} - -void setAnimation(char* path, size_t* w, size_t* h) -{ - anim = Animation::loadFromFile(path); - anim->size(*w, *h); - setAnimationSize(*w, *h); -} - -uint32_t* renderRLottieAnimation(uint32_t frameNum) -{ - Surface surface = Surface(buffer, width, height, bytesPerLine); - anim->renderSync(frameNum, surface); - // background color - for (int i = 0; i < height; i++) - for (int j = 0; j < width; ++j) - { - uint32_t* v = buffer + i * width + j; - if (*v == 0) *v = curColor; - } - return buffer; -} - -void setAnimationColor(int r, int g, int b) -{ - curColor = ((255 << 16) * r) + ((255 << 8) * g) + 255 * b; -} - -size_t getTotalFrame() -{ - return anim->totalFrame(); -} - -bool isAnimNULL() -{ - return anim == NULL; -} - -void freeAnimation() -{ - free(buffer); -} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/animation.h b/presentation/src/main/cpp/third_party/rlottie/example/win32Player/animation.h deleted file mode 100644 index 483cb3fa..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/animation.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include - -void setAnimation(char* path, size_t* w, size_t* h); -void setAnimationSize(size_t w, size_t h); -uint32_t* renderRLottieAnimation(uint32_t frameNum); -size_t getTotalFrame(); -bool isAnimNULL(); -void setAnimationColor(int r, int g, int b); -void freeAnimation(); \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/framework.h b/presentation/src/main/cpp/third_party/rlottie/example/win32Player/framework.h deleted file mode 100644 index 33a6be64..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/framework.h +++ /dev/null @@ -1,15 +0,0 @@ -// header.h : include file for standard system include files, -// or project specific include files -// - -#pragma once - -#include "targetver.h" -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -// Windows Header Files -#include -// C RunTime Header Files -#include -#include -#include -#include diff --git a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/resource.h b/presentation/src/main/cpp/third_party/rlottie/example/win32Player/resource.h deleted file mode 100644 index ac46939a..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/resource.h +++ /dev/null @@ -1,40 +0,0 @@ -//{{NO_DEPENDENCIES}} -// This is an include file generated by Microsoft Visual C++. -// It is being used in rlottiePlayer.rc. -// -#define IDC_MYICON 2 -#define IDD_RLOTTIEPLAYER_DIALOG 102 -#define IDS_APP_TITLE 103 -#define IDD_ABOUTBOX 103 -#define IDM_ABOUT 104 -#define IDM_EXIT 105 -#define IDI_RLOTTIEPLAYER 107 -#define IDI_SMALL 108 -#define IDC_RLOTTIEPLAYER 109 -#define IDR_MAINFRAME 128 -#define MAIN_WINDOW 130 -#define BTN_BROWSE 1004 -#define BTN_WHITE 1005 -#define BTN_BLACK 1006 -#define BTN_RED 1007 -#define BTN_GREEN 1008 -#define BTN_BLUE 1009 -#define SLIDER_CANVAS_RESIZE 1010 -#define BTN_PLAY 1011 -#define SLIDER_PLAY 1012 -#define TEXT_FILENAME 1013 -#define PICCTRL_RLOTTIE 1014 -#define TIMER_PLAY_ANIM 1015 -#define IDC_STATIC -1 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 131 -#define _APS_NEXT_COMMAND_VALUE 32771 -#define _APS_NEXT_CONTROL_VALUE 1017 -#define _APS_NEXT_SYMED_VALUE 110 -#endif -#endif diff --git a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottie.dll b/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottie.dll deleted file mode 100644 index 296f70a0..00000000 Binary files a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottie.dll and /dev/null differ diff --git a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottie.lib b/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottie.lib deleted file mode 100644 index 2625916f..00000000 Binary files a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottie.lib and /dev/null differ diff --git a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.cpp b/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.cpp deleted file mode 100644 index b2d0431f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.cpp +++ /dev/null @@ -1,521 +0,0 @@ -// rlottiePlayer.cpp : Defines the entry point for the application. -// - - -#include "framework.h" -#include "rlottiePlayer.h" -using namespace Gdiplus; - -#define MAX_LOADSTRING 100 - -// Global Variables: -HINSTANCE hInst; // current instance -WCHAR szTitle[MAX_LOADSTRING]; // The title bar text -WCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name -HWND mainWindow; // Main Window Instance -HWND hTextFileToBeOpened; // openDialog file path -HWND hBtnPlay; -HWND hSliderPlay, hSliderCanvasResize; -UINT curFrame = 0; -RlottieBitmap anim; // rendered Animation Bitmap -RECT animRect, backRect; -size_t animWidth, animHeight; -Gdiplus::Color backColor(255, 255, 255, 255); -Gdiplus::Color borderColor(255, 0, 0, 0); -bool isViewChanged = false; - -// Forward declarations of functions included in this code module: -ATOM MyRegisterClass(HINSTANCE hInstance); -BOOL InitInstance(HINSTANCE, int); -LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); -INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); -void openJSONFileDialog(HWND); -void initUIControl(HWND); -void dlgUICommand(HWND, WPARAM); -void resizeCanvas(HWND, int); -void changeBackgroundColor(int r, int g, int b); - -// Animation Rendering Functions -void draw(HDC); -Bitmap* CreateBitmap(void* data, unsigned int width, unsigned int height); -void renderAnimation(UINT); - -int APIENTRY wWinMain(_In_ HINSTANCE hInstance, - _In_opt_ HINSTANCE hPrevInstance, - _In_ LPWSTR lpCmdLine, - _In_ int nCmdShow) -{ - UNREFERENCED_PARAMETER(hPrevInstance); - UNREFERENCED_PARAMETER(lpCmdLine); - - // initialize Gdiplus - Gdiplus::GdiplusStartupInput gdiplusStartUpInput; - ULONG_PTR gdiplustoken; - Gdiplus::GdiplusStartup(&gdiplustoken, &gdiplusStartUpInput, nullptr); - - // Initialize global strings - LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); - LoadStringW(hInstance, IDC_RLOTTIEPLAYER, szWindowClass, MAX_LOADSTRING); - MyRegisterClass(hInstance); - - // Perform application initialization: - if (!InitInstance(hInstance, nCmdShow)) - { - return FALSE; - } - - HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_RLOTTIEPLAYER)); - - MSG msg; - - // Main message loop: - while (GetMessage(&msg, nullptr, 0, 0)) - { - if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - Gdiplus::GdiplusShutdown(gdiplustoken); - return (int)msg.wParam; -} - - - -// -// FUNCTION: MyRegisterClass() -// -// PURPOSE: Registers the window class. -// -ATOM MyRegisterClass(HINSTANCE hInstance) -{ - WNDCLASSEXW wcex; - - wcex.cbSize = sizeof(WNDCLASSEX); - - wcex.style = CS_HREDRAW | CS_VREDRAW; - wcex.lpfnWndProc = WndProc; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = hInstance; - wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_RLOTTIEPLAYER)); - wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); - wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); - wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_RLOTTIEPLAYER); - wcex.lpszClassName = szWindowClass; - wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); - - return RegisterClassExW(&wcex); -} - -// -// FUNCTION: InitInstance(HINSTANCE, int) -// -// PURPOSE: Saves instance handle and creates main window -// -// COMMENTS: -// -// In this function, we save the instance handle in a global variable and -// create and display the main program window. -// -BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) -{ - hInst = hInstance; // Store instance handle in our global variable - - DWORD dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; - mainWindow = CreateWindowEx(0, szWindowClass, szTitle, dwStyle, - CW_USEDEFAULT, CW_USEDEFAULT, WND_WIDTH, WND_HEIGHT, nullptr, nullptr, hInstance, nullptr); - - if (!mainWindow) - { - return FALSE; - } - - ShowWindow(mainWindow, nCmdShow); - UpdateWindow(mainWindow); - SetMenu(mainWindow, NULL); - - return TRUE; -} - -// -// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) -// -// PURPOSE: Processes messages for the main window. -// -// WM_COMMAND - process the application menu -// WM_PAINT - Paint the main window -// WM_DESTROY - post a quit message and return -// -// -LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - static bool isplay = false; - int wmId = LOWORD(wParam); - - switch (message) - { - case WM_CREATE: - { - initUIControl(hWnd); - break; - } - case WM_TIMER: - { - switch (wmId) - { - case TIMER_PLAY_ANIM: - { - renderAnimation(curFrame + 1); - SendMessage(hSliderPlay, TBM_SETPOS, TRUE, curFrame); - break; - } - default: - break; - } - break; - } - case WM_COMMAND: - { - // Parse the menu selections: - switch (wmId) - { - case IDM_ABOUT: - DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); - break; - - case IDM_EXIT: - DestroyWindow(hWnd); - break; - - case BTN_BROWSE: - openJSONFileDialog(hWnd); - break; - - case BTN_PLAY: - { - LPWSTR textBtnPlay; - USES_CONVERSION; - if (isplay) - { - isplay = false; - textBtnPlay = A2W("Play"); - KillTimer(hWnd, TIMER_PLAY_ANIM); - } - else - { - isplay = true; - textBtnPlay = A2W("Pause"); - SetTimer(hWnd, TIMER_PLAY_ANIM, 10, NULL); - } - SetWindowText(hBtnPlay, textBtnPlay); - break; - } - - case WM_DROPFILES: - break; - case BTN_WHITE: - changeBackgroundColor(1, 1, 1); - break; - case BTN_BLACK: - changeBackgroundColor(0, 0, 0); - break; - case BTN_RED: - changeBackgroundColor(1, 0, 0); - break; - case BTN_GREEN: - changeBackgroundColor(0, 1, 0); - break; - case BTN_BLUE: - changeBackgroundColor(0, 0, 1); - break; - - default: - return DefWindowProc(hWnd, message, wParam, lParam); - } - } - break; - - case WM_HSCROLL: - { - if ((lParam != 0) && (reinterpret_cast(lParam) == hSliderPlay)) - { - UINT frameNum = SendDlgItemMessage(hWnd, SLIDER_PLAY, TBM_GETPOS, 0, 0); - renderAnimation(frameNum); - } - else if ((lParam != 0) && (reinterpret_cast(lParam) == hSliderCanvasResize)) - { - static int curSize = anim.width / RESIZE_LENGTH; - int newSize = SendDlgItemMessage(hWnd, SLIDER_CANVAS_RESIZE, TBM_GETPOS, 0, 0); - resizeCanvas(hWnd, (curSize - newSize) * RESIZE_LENGTH); - curSize = newSize; - } - break; - } - - case WM_PAINT: - { - PAINTSTRUCT ps; - HDC hdc = BeginPaint(hWnd, &ps); - draw(hdc); - EndPaint(hWnd, &ps); - } - break; - case WM_CTLCOLORSTATIC: - { - static HBRUSH hBrushEdit = CreateSolidBrush(RGB(255, 255, 255)); - return (LRESULT)hBrushEdit; - } - - case WM_DESTROY: - freeAnimation(); - PostQuitMessage(0); - break; - - default: - return DefWindowProc(hWnd, message, wParam, lParam); - } - return 0; -} - -// Message handler for about box. -INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - UNREFERENCED_PARAMETER(lParam); - switch (message) - { - case WM_INITDIALOG: - return (INT_PTR)TRUE; - - case WM_COMMAND: - if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) - { - EndDialog(hDlg, LOWORD(wParam)); - return (INT_PTR)TRUE; - } - break; - } - return (INT_PTR)FALSE; -} - -void openJSONFileDialog(HWND hDlg) -{ - OPENFILENAME ofn; // common dialog box structure - TCHAR szFile[260] = { 0 }; // if using TCHAR macros - - // Initialize OPENFILENAME - ZeroMemory(&ofn, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = hDlg; - ofn.lpstrFile = szFile; - ofn.nMaxFile = sizeof(szFile); - ofn.lpstrFilter = _T("JSON\0*.json\0"); - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = NULL; - ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; - - isViewChanged = true; - if (GetOpenFileName(&ofn)) - { - isViewChanged = true; - SetWindowText(hTextFileToBeOpened, ofn.lpstrFile); - // LPWSTR(w_char*) -> LPSTR(char*) - USES_CONVERSION; - LPSTR path = W2A(ofn.lpstrFile); - - setAnimation(path, &animWidth, &animHeight); - // init play slider - SendMessage(hSliderPlay, TBM_SETRANGE, FALSE, MAKELPARAM(0, getTotalFrame())); - SendMessage(hSliderPlay, TBM_SETPOS, TRUE, 0); - renderAnimation(0); - } -} - -void draw(HDC hdc) -{ - Graphics gf(hdc); - int half_interval = UI_INTERVAL / 2; - - // background - SolidBrush brush(backColor); - int back_y = half_interval + BTN_HEIGHT; - int back_height = back_y + BMP_MAX_LEN + UI_INTERVAL; - if (isViewChanged) - { - isViewChanged = false; - gf.FillRectangle(&brush, 0, back_y, WND_WIDTH, back_height); - } - - // image borderline - Pen pen(borderColor); - gf.DrawRectangle(&pen, anim.x - half_interval, anim.y - half_interval, anim.width + half_interval * 2, anim.height + half_interval * 2); - - // image - if (anim.image != NULL) - { - gf.DrawImage(anim.image, anim.x, anim.y, anim.width, anim.height); - } -} - -Bitmap* CreateBitmap(void* data, unsigned int width, unsigned int height) -{ - BITMAPINFO Info; - memset(&Info, 0, sizeof(Info)); - - Info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - Info.bmiHeader.biWidth = width; - Info.bmiHeader.biHeight = height; - Info.bmiHeader.biPlanes = 1; - Info.bmiHeader.biBitCount = 32; - Info.bmiHeader.biCompression = BI_RGB; - Info.bmiHeader.biSizeImage = 0; //(((32 * width + 31) & ~31) / 8) * height; - - return new Gdiplus::Bitmap(&Info, data); -} - -void renderAnimation(UINT frameNum) -{ - if (isAnimNULL()) return; - if (anim.image != NULL) delete anim.image; - - curFrame = frameNum % getTotalFrame(); - - // render - UINT* resRender = renderRLottieAnimation(curFrame); - anim.image = CreateBitmap(resRender, animWidth, animHeight); - anim.image->RotateFlip(RotateNoneFlipY); - // call WM_PAINT message - InvalidateRect(mainWindow, &animRect, FALSE); -} - -void initUIControl(HWND hWnd) -{ - int half_ui_interval = UI_INTERVAL / 2; - - // button browse - int browse_x = UI_INTERVAL; - int browse_y = half_ui_interval; - CreateWindow(L"button", L"Browse", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, - browse_x, browse_y, BTN_WIDTH, BTN_HEIGHT, hWnd, (HMENU)BTN_BROWSE, hInst, NULL); - - // textbox FilePath - int textFile_x = browse_x + BTN_WIDTH + UI_INTERVAL; - int textFile_y = browse_y; - hTextFileToBeOpened = CreateWindowEx(0, L"static", L"No file selected.", WS_CHILD | WS_VISIBLE | ES_LEFT, - textFile_x, textFile_y, WND_WIDTH * 0.6, TEXT_HEIGHT, hWnd, (HMENU)TEXT_FILENAME, hInst, 0); - - // image - anim.x = WND_WIDTH / 4; - anim.y = browse_y + BTN_HEIGHT + UI_INTERVAL * 2; - anim.width = BMP_MAX_LEN; - anim.height = anim.width; - - // animating range - SetRect(&animRect, - anim.x - UI_INTERVAL, - anim.y - UI_INTERVAL, - anim.x + anim.width + UI_INTERVAL * 2, - anim.y + anim.height + UI_INTERVAL * 2 - ); - - // background range - SetRect(&backRect, - 0, - anim.y - UI_INTERVAL, - WND_WIDTH, - anim.y + anim.height + UI_INTERVAL * 2 - ); - - // text Background Color - int textBC_x = WND_WIDTH / 20; - int textBC_y = anim.y + anim.height + UI_INTERVAL * 2; - CreateWindowEx(0, L"static", L"Background Color", WS_CHILD | WS_VISIBLE | ES_LEFT, - textBC_x, textBC_y, 120, TEXT_HEIGHT, hWnd, (HMENU)TEXT_FILENAME, hInst, 0); - - // radio button - // white - int white_x = WND_WIDTH / 20; - int white_y = textBC_y + TEXT_HEIGHT + half_ui_interval; - CreateWindowEx(0, L"button", L"White", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, - white_x, white_y, RDOBTN_WIDTH, RDOBTN_HEIGHT, hWnd, (HMENU)BTN_WHITE, hInst, NULL); - - // black - int black_x = white_x + RDOBTN_WIDTH + half_ui_interval; - int black_y = white_y; - CreateWindowEx(0, L"button", L"Black", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, - black_x, black_y, RDOBTN_WIDTH, RDOBTN_HEIGHT, hWnd, (HMENU)BTN_BLACK, hInst, NULL); - - // red - int red_x = black_x + RDOBTN_WIDTH + half_ui_interval; - int red_y = white_y; - CreateWindowEx(0, L"button", L"Red", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, - red_x, red_y, RDOBTN_WIDTH, RDOBTN_HEIGHT, hWnd, (HMENU)BTN_RED, hInst, NULL); - - // green - int green_x = red_x + RDOBTN_WIDTH + half_ui_interval; - int green_y = white_y; - CreateWindowEx(0, L"button", L"Green", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, - green_x, green_y, RDOBTN_WIDTH, RDOBTN_HEIGHT, hWnd, (HMENU)BTN_GREEN, hInst, NULL); - - // blue - int blue_x = green_x + RDOBTN_WIDTH + half_ui_interval; - int blue_y = white_y; - CreateWindowEx(0, L"button", L"Blue", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, - blue_x, blue_y, RDOBTN_WIDTH, RDOBTN_HEIGHT, hWnd, (HMENU)BTN_BLUE, hInst, NULL); - - CheckRadioButton(hWnd, BTN_WHITE, BTN_BLUE, BTN_WHITE); - - // text Canvas Resize - int textCR_x = WND_WIDTH / 2; - int textCR_y = textBC_y; - CreateWindowEx(0, L"static", L"Canvas Resize", WS_CHILD | WS_VISIBLE | ES_LEFT, - textCR_x, textCR_y, 120, TEXT_HEIGHT, hWnd, (HMENU)TEXT_FILENAME, hInst, 0); - - // slider Canvas Resize - int sliderCR_x = textCR_x; - int sliderCR_y = textCR_y + TEXT_HEIGHT + half_ui_interval; - hSliderCanvasResize = CreateWindowExW(0, TRACKBAR_CLASSW, NULL, WS_CHILD | WS_VISIBLE | TBS_FIXEDLENGTH | TBS_NOTICKS, - sliderCR_x, sliderCR_y, WND_WIDTH * 0.2, SLIDER_HEIGHT, hWnd, (HMENU)SLIDER_CANVAS_RESIZE, hInst, NULL); - - // init resize slider - UINT sizeSlider = anim.width / RESIZE_LENGTH; - SendMessage(hSliderCanvasResize, TBM_SETRANGE, FALSE, MAKELPARAM(0, sizeSlider)); - SendMessage(hSliderCanvasResize, TBM_SETPOS, TRUE, sizeSlider); - - // button play - int btnPlay_x = WND_WIDTH / 10; - int btnPlay_y = red_y + RDOBTN_HEIGHT + UI_INTERVAL * 2; - hBtnPlay = CreateWindow(L"button", L"Play", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, - btnPlay_x, btnPlay_y, BTN_WIDTH, BTN_HEIGHT, hWnd, (HMENU)BTN_PLAY, hInst, NULL); - - // slider play - int sliderPlay_x = btnPlay_x + BTN_WIDTH + UI_INTERVAL; - int sliderPlay_y = btnPlay_y; - hSliderPlay = CreateWindowExW(0, TRACKBAR_CLASSW, NULL, WS_CHILD | WS_VISIBLE | TBS_FIXEDLENGTH | TBS_NOTICKS, - sliderPlay_x, sliderPlay_y, WND_WIDTH * 0.6, SLIDER_HEIGHT, hWnd, (HMENU)SLIDER_PLAY, hInst, NULL); -} - -void resizeCanvas(HWND hWnd, int resizeValue) -{ - isViewChanged = true; - anim.x += resizeValue / 2; - anim.y += resizeValue / 2; - anim.width -= resizeValue; - anim.height -= resizeValue; - InvalidateRect(hWnd, &animRect, TRUE); -} - -void changeBackgroundColor(int r, int g, int b) -{ - isViewChanged = true; - backColor = Gdiplus::Color(r * 255, g * 255, b * 255); - if (r + g + b == 0) borderColor = Gdiplus::Color(255, 255, 255); - else borderColor = Gdiplus::Color(0, 0, 0); - setAnimationColor(r, g, b); - renderAnimation(curFrame); - InvalidateRect(mainWindow, &backRect, FALSE); -} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.exe b/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.exe deleted file mode 100644 index b52a4cb7..00000000 Binary files a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.exe and /dev/null differ diff --git a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.h b/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.h deleted file mode 100644 index 07e5fd24..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "resource.h" -#include "animation.h" -#include // OPENFILENAME -#include "atlconv.h" // String cast. (ex. LPWSTR <-> LPSTR) -#include -#include // slider handle - -// interval -#define UI_INTERVAL 20 - -// length -#define WND_WIDTH 1000 -#define WND_HEIGHT 800 -#define BMP_MAX_LEN 500 -#define BTN_WIDTH 100 -#define BTN_HEIGHT 30 -#define TEXT_HEIGHT 20 -#define SLIDER_HEIGHT 25 -#define RDOBTN_WIDTH 60 -#define RDOBTN_HEIGHT 20 -#define RESIZE_LENGTH 10 - -typedef struct RlottieBitmap -{ - Gdiplus::Bitmap* image = NULL; - int x = 0; - int y = 0; - unsigned int width = 0; - unsigned int height = 0; -}RlottieBitmap; \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.ico b/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.ico deleted file mode 100644 index b3ec03bd..00000000 Binary files a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.ico and /dev/null differ diff --git a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.rc b/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.rc deleted file mode 100644 index 0c7935ff..00000000 Binary files a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.rc and /dev/null differ diff --git a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.sln b/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.sln deleted file mode 100644 index d1c8f0dc..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.sln +++ /dev/null @@ -1,31 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30503.244 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rlottiePlayer", "rlottiePlayer.vcxproj", "{CC7AD634-4D29-4D8E-997D-9727DABB44EE}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {CC7AD634-4D29-4D8E-997D-9727DABB44EE}.Debug|x64.ActiveCfg = Debug|x64 - {CC7AD634-4D29-4D8E-997D-9727DABB44EE}.Debug|x64.Build.0 = Debug|x64 - {CC7AD634-4D29-4D8E-997D-9727DABB44EE}.Debug|x86.ActiveCfg = Debug|Win32 - {CC7AD634-4D29-4D8E-997D-9727DABB44EE}.Debug|x86.Build.0 = Debug|Win32 - {CC7AD634-4D29-4D8E-997D-9727DABB44EE}.Release|x64.ActiveCfg = Release|x64 - {CC7AD634-4D29-4D8E-997D-9727DABB44EE}.Release|x64.Build.0 = Release|x64 - {CC7AD634-4D29-4D8E-997D-9727DABB44EE}.Release|x86.ActiveCfg = Release|Win32 - {CC7AD634-4D29-4D8E-997D-9727DABB44EE}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {57EEA15F-28FB-4C19-96B4-7B62BFA0CFE5} - EndGlobalSection -EndGlobal diff --git a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.vcxproj b/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.vcxproj deleted file mode 100644 index e61b03b2..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.vcxproj +++ /dev/null @@ -1,166 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {cc7ad634-4d29-4d8e-997d-9727dabb44ee} - rlottiePlayer - 10.0 - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - false - - - true - ..\..\inc;$(IncludePath) - - - false - ..\..\inc;$(IncludePath) - - - - Level3 - true - WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - true - - - Windows - true - - - - - Level3 - true - true - true - WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - true - - - Windows - true - true - true - - - - - Level3 - true - _DEBUG;_WINDOWS;%(PreprocessorDefinitions) - true - - - Windows - true - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;rlottie.lib;gdiplus.lib;%(AdditionalDependencies) - - - - - Level3 - true - true - true - NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - true - - - Windows - true - true - true - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;rlottie.lib;gdiplus.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.vcxproj.filters b/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.vcxproj.filters deleted file mode 100644 index c8cf65ba..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.vcxproj.filters +++ /dev/null @@ -1,55 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - - - Resource Files - - - - - Resource Files - - - Resource Files - - - \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.vcxproj.user b/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.vcxproj.user deleted file mode 100644 index 88a55094..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/rlottiePlayer.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/small.ico b/presentation/src/main/cpp/third_party/rlottie/example/win32Player/small.ico deleted file mode 100644 index b3ec03bd..00000000 Binary files a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/small.ico and /dev/null differ diff --git a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/targetver.h b/presentation/src/main/cpp/third_party/rlottie/example/win32Player/targetver.h deleted file mode 100644 index bf75e089..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/example/win32Player/targetver.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -// // Including SDKDDKVer.h defines the highest available Windows platform. -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. -#include diff --git a/presentation/src/main/cpp/third_party/rlottie/format b/presentation/src/main/cpp/third_party/rlottie/format deleted file mode 100644 index c5630b48..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/format +++ /dev/null @@ -1 +0,0 @@ -git diff -U0 --no-color HEAD^ | clang-format-diff -i -p1 \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/inc/CMakeLists.txt b/presentation/src/main/cpp/third_party/rlottie/inc/CMakeLists.txt deleted file mode 100644 index 96114430..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/inc/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -target_include_directories(rlottie - PRIVATE - "${CMAKE_CURRENT_LIST_DIR}" - ) diff --git a/presentation/src/main/cpp/third_party/rlottie/inc/meson.build b/presentation/src/main/cpp/third_party/rlottie/inc/meson.build deleted file mode 100644 index 0349fac2..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/inc/meson.build +++ /dev/null @@ -1,5 +0,0 @@ -install_headers([ - 'rlottie.h', - 'rlottie_capi.h', - 'rlottiecommon.h', - ]) diff --git a/presentation/src/main/cpp/third_party/rlottie/inc/rlottie.h b/presentation/src/main/cpp/third_party/rlottie/inc/rlottie.h deleted file mode 100644 index ec50d2db..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/inc/rlottie.h +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _RLOTTIE_H_ -#define _RLOTTIE_H_ - -#include -#include -#include - -#if defined _WIN32 || defined __CYGWIN__ - #ifdef RLOTTIE_BUILD - #define RLOTTIE_API __declspec(dllexport) - #else - #define RLOTTIE_API __declspec(dllimport) - #endif -#else - #ifdef RLOTTIE_BUILD - #define RLOTTIE_API __attribute__ ((visibility ("default"))) - #else - #define RLOTTIE_API - #endif -#endif - -class AnimationImpl; -struct LOTNode; -struct LOTLayerNode; - -namespace rlottie { - -/** - * @brief Configures rlottie model cache policy. - * - * Provides Library level control to configure model cache - * policy. Setting it to 0 will disable - * the cache as well as flush all the previously cached content. - * - * @param[in] cacheSize Maximum Model Cache size. - * - * @note to disable Caching configure with 0 size. - * @note to flush the current Cache content configure it with 0 and - * then reconfigure with the new size. - * - * @internal - */ -RLOTTIE_API void configureModelCacheSize(size_t cacheSize); - -struct Color { - Color() = default; - Color(float r, float g , float b):_r(r), _g(g), _b(b){} - float r() const {return _r;} - float g() const {return _g;} - float b() const {return _b;} -private: - float _r{0}; - float _g{0}; - float _b{0}; -}; - -struct Size { - Size() = default; - Size(float w, float h):_w(w), _h(h){} - float w() const {return _w;} - float h() const {return _h;} -private: - float _w{0}; - float _h{0}; -}; - -struct Point { - Point() = default; - Point(float x, float y):_x(x), _y(y){} - float x() const {return _x;} - float y() const {return _y;} -private: - float _x{0}; - float _y{0}; -}; - -struct FrameInfo { - explicit FrameInfo(uint32_t frame): _frameNo(frame){} - uint32_t curFrame() const {return _frameNo;} -private: - uint32_t _frameNo; -}; - -enum class Property { - FillColor, /*!< Color property of Fill object , value type is rlottie::Color */ - FillOpacity, /*!< Opacity property of Fill object , value type is float [ 0 .. 100] */ - StrokeColor, /*!< Color property of Stroke object , value type is rlottie::Color */ - StrokeOpacity, /*!< Opacity property of Stroke object , value type is float [ 0 .. 100] */ - StrokeWidth, /*!< stroke width property of Stroke object , value type is float */ - TrAnchor, /*!< Transform Anchor property of Layer and Group object , value type is rlottie::Point */ - TrPosition, /*!< Transform Position property of Layer and Group object , value type is rlottie::Point */ - TrScale, /*!< Transform Scale property of Layer and Group object , value type is rlottie::Size. range[0 ..100] */ - TrRotation, /*!< Transform Rotation property of Layer and Group object , value type is float. range[0 .. 360] in degrees*/ - TrOpacity, /*!< Transform Opacity property of Layer and Group object , value type is float [ 0 .. 100] */ - TrimStart, /*!< Trim Start property of Shape object , value type is float [ 0 .. 100] */ - TrimEnd /*!< Trim End property of Shape object , value type is rlottie::Point [ 0 .. 100] */ -}; - -struct Color_Type{}; -struct Point_Type{}; -struct Size_Type{}; -struct Float_Type{}; -template struct MapType; - -class RLOTTIE_API Surface { -public: - /** - * @brief Surface object constructor. - * - * @param[in] buffer surface buffer. - * @param[in] width surface width. - * @param[in] height surface height. - * @param[in] bytesPerLine number of bytes in a surface scanline. - * - * @note Default surface format is ARGB32_Premultiplied. - * - * @internal - */ - Surface(uint32_t *buffer, size_t width, size_t height, size_t bytesPerLine); - - /** - * @brief Sets the Draw Area available on the Surface. - * - * Lottie will use the draw region size to generate frame image - * and will update only the draw rgion of the surface. - * - * @param[in] x region area x position. - * @param[in] y region area y position. - * @param[in] width region area width. - * @param[in] height region area height. - * - * @note Default surface format is ARGB32_Premultiplied. - * @note Default draw region area is [ 0 , 0, surface width , surface height] - * - * @internal - */ - void setDrawRegion(size_t x, size_t y, size_t width, size_t height); - - /** - * @brief Returns width of the surface. - * - * @return surface width - * - * @internal - * - */ - size_t width() const {return mWidth;} - - /** - * @brief Returns height of the surface. - * - * @return surface height - * - * @internal - */ - size_t height() const {return mHeight;} - - /** - * @brief Returns number of bytes in the surface scanline. - * - * @return number of bytes in scanline. - * - * @internal - */ - size_t bytesPerLine() const {return mBytesPerLine;} - - /** - * @brief Returns buffer attached tp the surface. - * - * @return buffer attaced to the Surface. - * - * @internal - */ - uint32_t *buffer() const {return mBuffer;} - - /** - * @brief Returns drawable area width of the surface. - * - * @return drawable area width - * - * @note Default value is width() of the surface - * - * @internal - * - */ - size_t drawRegionWidth() const {return mDrawArea.w;} - - /** - * @brief Returns drawable area height of the surface. - * - * @return drawable area height - * - * @note Default value is height() of the surface - * - * @internal - */ - size_t drawRegionHeight() const {return mDrawArea.h;} - - /** - * @brief Returns drawable area's x position of the surface. - * - * @return drawable area's x potition. - * - * @note Default value is 0 - * - * @internal - */ - size_t drawRegionPosX() const {return mDrawArea.x;} - - /** - * @brief Returns drawable area's y position of the surface. - * - * @return drawable area's y potition. - * - * @note Default value is 0 - * - * @internal - */ - size_t drawRegionPosY() const {return mDrawArea.y;} - - /** - * @brief Default constructor. - */ - Surface() = default; -private: - uint32_t *mBuffer{nullptr}; - size_t mWidth{0}; - size_t mHeight{0}; - size_t mBytesPerLine{0}; - struct { - size_t x{0}; - size_t y{0}; - size_t w{0}; - size_t h{0}; - }mDrawArea; -}; - -using MarkerList = std::vector>; -/** - * @brief https://helpx.adobe.com/after-effects/using/layer-markers-composition-markers.html - * Markers exported form AE are used to describe a segmnet of an animation {comment/tag , startFrame, endFrame} - * Marker can be use to devide a resource in to separate animations by tagging the segment with comment string , - * start frame and duration of that segment. - */ - -using LayerInfoList = std::vector>; - - -using ColorFilter = std::function; - -class RLOTTIE_API Animation { -public: - - /** - * @brief Constructs an animation object from file path. - * - * @param[in] path Lottie resource file path - * @param[in] cachePolicy whether to cache or not the model data. - * use only when need to explicit disabl caching for a - * particular resource. To disable caching at library level - * use @see configureModelCacheSize() instead. - * - * @return Animation object that can render the contents of the - * Lottie resource represented by file path. - * - * @internal - */ - static std::unique_ptr - loadFromFile(const std::string &path, bool cachePolicy=true); - - /** - * @brief Constructs an animation object from JSON string data. - * - * @param[in] jsonData The JSON string data. - * @param[in] key the string that will be used to cache the JSON string data. - * @param[in] resourcePath the path will be used to search for external resource. - * @param[in] cachePolicy whether to cache or not the model data. - * use only when need to explicit disabl caching for a - * particular resource. To disable caching at library level - * use @see configureModelCacheSize() instead. - * - * @return Animation object that can render the contents of the - * Lottie resource represented by JSON string data. - * - * @internal - */ - static std::unique_ptr - loadFromData(std::string jsonData, const std::string &key, - const std::string &resourcePath="", bool cachePolicy=true); - - /** - * @brief Constructs an animation object from JSON string data and update. - * the color properties using ColorFilter. - - * @param[in] jsonData The JSON string data. - * @param[in] resourcePath the path will be used to search for external resource. - * @param[in] filter The color filter that will be applied for each color property - * found during parsing. - - * @return Animation object that can render the contents of the - * Lottie resource represented by JSON string data. - * - * @internal - */ - static std::unique_ptr - loadFromData(std::string jsonData, std::string resourcePath, ColorFilter filter); - - /** - * @brief Returns default framerate of the Lottie resource. - * - * @return framerate of the Lottie resource - * - * @internal - * - */ - double frameRate() const; - - /** - * @brief Returns total number of frames present in the Lottie resource. - * - * @return frame count of the Lottie resource. - * - * @note frame number starts with 0. - * - * @internal - */ - size_t totalFrame() const; - - /** - * @brief Returns default viewport size of the Lottie resource. - * - * @param[out] width default width of the viewport. - * @param[out] height default height of the viewport. - * - * @internal - * - */ - void size(size_t &width, size_t &height) const; - - /** - * @brief Returns total animation duration of Lottie resource in second. - * it uses totalFrame() and frameRate() to calculate the duration. - * duration = totalFrame() / frameRate(). - * - * @return total animation duration in second. - * @retval 0 if the Lottie resource has no animation. - * - * @see totalFrame() - * @see frameRate() - * - * @internal - */ - double duration() const; - - /** - * @brief Returns frame number for a given position. - * this function helps to map the position value retuned - * by the animator to a frame number in side the Lottie resource. - * frame_number = lerp(start_frame, endframe, pos); - * - * @param[in] pos normalized position value [0 ... 1] - * - * @return frame numer maps to the position value [startFrame .... endFrame] - * - * @internal - */ - size_t frameAtPos(double pos); - - /** - * @brief Renders the content to surface Asynchronously. - * it gives a future in return to get the result of the - * rendering at a future point. - * To get best performance user has to start rendering as soon as - * it finds that content at {frameNo} has to be rendered and get the - * result from the future at the last moment when the surface is needed - * to draw into the screen. - * - * - * @param[in] frameNo Content corresponds to the @p frameNo needs to be drawn - * @param[in] surface Surface in which content will be drawn - * @param[in] keepAspectRatio whether to keep the aspect ratio while scaling the content. - * - * @return future that will hold the result when rendering finished. - * - * for Synchronus rendering @see renderSync - * - * @see Surface - * @internal - */ - std::future render(size_t frameNo, Surface surface, bool keepAspectRatio=true); - - /** - * @brief Renders the content to surface synchronously. - * for performance use the async rendering @see render - * - * @param[in] frameNo Content corresponds to the @p frameNo needs to be drawn - * @param[in] surface Surface in which content will be drawn - * @param[in] keepAspectRatio whether to keep the aspect ratio while scaling the content. - * - * @internal - */ - void renderSync(size_t frameNo, Surface surface, bool keepAspectRatio=true); - - /** - * @brief Returns root layer of the composition updated with - * content of the Lottie resource at frame number @p frameNo. - * - * @param[in] frameNo Content corresponds to the @p frameNo needs to be extracted. - * @param[in] width content viewbox width - * @param[in] height content viewbox height - * - * @return Root layer node. - * - * @internal - */ - const LOTLayerNode * renderTree(size_t frameNo, size_t width, size_t height) const; - - /** - * @brief Returns Composition Markers. - * - * - * @return returns MarkerList of the Composition. - * - * @see MarkerList - * @internal - */ - const MarkerList& markers() const; - - /** - * @brief Returns Layer information{name, inFrame, outFrame} of all the child layers of the composition. - * - * - * @return List of Layer Information of the Composition. - * - * @see LayerInfoList - * @internal - */ - const LayerInfoList& layers() const; - - /** - * @brief Sets property value for the specified {@link KeyPath}. This {@link KeyPath} can resolve - * to multiple contents. In that case, the callback's value will apply to all of them. - * - * Keypath should conatin object names separated by (.) and can handle globe(**) or wildchar(*). - * - * @usage - * To change fillcolor property of fill1 object in the layer1->group1->fill1 hirarchy to RED color - * - * player->setValue("layer1.group1.fill1", rlottie::Color(1, 0, 0); - * - * if all the color property inside group1 needs to be changed to GREEN color - * - * player->setValue("**.group1.**", rlottie::Color(0, 1, 0); - * - * @internal - */ - template - void setValue(const std::string &keypath, AnyValue value) - { - setValue(MapType>{}, prop, keypath, value); - } - - /** - * @brief default destructor - * - * @internal - */ - ~Animation(); - -private: - void setValue(Color_Type, Property, const std::string &, Color); - void setValue(Float_Type, Property, const std::string &, float); - void setValue(Size_Type, Property, const std::string &, Size); - void setValue(Point_Type, Property, const std::string &, Point); - - void setValue(Color_Type, Property, const std::string &, std::function &&); - void setValue(Float_Type, Property, const std::string &, std::function &&); - void setValue(Size_Type, Property, const std::string &, std::function &&); - void setValue(Point_Type, Property, const std::string &, std::function &&); - /** - * @brief default constructor - * - * @internal - */ - Animation(); - - std::unique_ptr d; -}; - -//Map Property to Value type -template<> struct MapType>: Color_Type{}; -template<> struct MapType>: Color_Type{}; -template<> struct MapType>: Float_Type{}; -template<> struct MapType>: Float_Type{}; -template<> struct MapType>: Float_Type{}; -template<> struct MapType>: Float_Type{}; -template<> struct MapType>: Float_Type{}; -template<> struct MapType>: Point_Type{}; -template<> struct MapType>: Point_Type{}; -template<> struct MapType>: Size_Type{}; -template<> struct MapType>: Float_Type{}; -template<> struct MapType>: Point_Type{}; -} // namespace lotplayer - -#endif // _RLOTTIE_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/inc/rlottie_capi.h b/presentation/src/main/cpp/third_party/rlottie/inc/rlottie_capi.h deleted file mode 100644 index bf91ae41..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/inc/rlottie_capi.h +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _RLOTTIE_CAPI_H_ -#define _RLOTTIE_CAPI_H_ - -#include -#include -#include "rlottiecommon.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - LOTTIE_ANIMATION_PROPERTY_FILLCOLOR, /*!< Color property of Fill object , value type is float [0 ... 1] */ - LOTTIE_ANIMATION_PROPERTY_FILLOPACITY, /*!< Opacity property of Fill object , value type is float [ 0 .. 100] */ - LOTTIE_ANIMATION_PROPERTY_STROKECOLOR, /*!< Color property of Stroke object , value type is float [0 ... 1] */ - LOTTIE_ANIMATION_PROPERTY_STROKEOPACITY, /*!< Opacity property of Stroke object , value type is float [ 0 .. 100] */ - LOTTIE_ANIMATION_PROPERTY_STROKEWIDTH, /*!< stroke with property of Stroke object , value type is float */ - LOTTIE_ANIMATION_PROPERTY_TR_ANCHOR, /*!< Transform Anchor property of Layer and Group object , value type is int */ - LOTTIE_ANIMATION_PROPERTY_TR_POSITION, /*!< Transform Position property of Layer and Group object , value type is int */ - LOTTIE_ANIMATION_PROPERTY_TR_SCALE, /*!< Transform Scale property of Layer and Group object , value type is float range[0 ..100] */ - LOTTIE_ANIMATION_PROPERTY_TR_ROTATION, /*!< Transform Scale property of Layer and Group object , value type is float. range[0 .. 360] in degrees*/ - LOTTIE_ANIMATION_PROPERTY_TR_OPACITY, /*!< Transform Opacity property of Layer and Group object , value type is float [ 0 .. 100] */ - LOTTIE_ANIMATION_PROPERTY_TRIM_PATH_START, /*!< Trim Path Start property of Shape object , value type is float [0 .. 100] */ - LOTTIE_ANIMATION_PROPERTY_TRIM_PATH_END /*!< Trim Path End property of Shape object , value type is float [0 .. 100] */ -}Lottie_Animation_Property; - -typedef struct Lottie_Animation_S Lottie_Animation; - -/** - * @brief Runs lottie initialization code when rlottie library is loaded - * dynamically. - * - * - * This api should be called before any other api when rlottie library - * is loaded using dlopen() or equivalent. - * - * @see lottie_shutdown() - * - * @ingroup Lottie_Animation - * @internal - */ -RLOTTIE_API void lottie_init(void); - -/** - * @brief Runs lottie teardown code when rlottie library is loaded - * dynamically. - * - * This api should be called before unloading the rlottie library for - * proper cleanup of the resource without doing so will result in undefined - * behaviour. - * - * @see lottie_init() - * - * @ingroup Lottie_Animation - * @internal - */ -RLOTTIE_API void lottie_shutdown(void); - -/** - * @brief Constructs an animation object from file path. - * - * @param[in] path Lottie resource file path - * - * @return Animation object that can build the contents of the - * Lottie resource represented by file path. - * - * @see lottie_animation_destroy() - * - * @ingroup Lottie_Animation - * @internal - */ -RLOTTIE_API Lottie_Animation *lottie_animation_from_file(const char *path); - -/** - * @brief Constructs an animation object from JSON string data. - * - * @param[in] data The JSON string data. - * @param[in] key the string that will be used to cache the JSON string data. - * @param[in] resource_path the path that will be used to load external resource needed by the JSON data. - * - * @return Animation object that can build the contents of the - * Lottie resource represented by JSON string data. - * - * @ingroup Lottie_Animation - * @internal - */ -RLOTTIE_API Lottie_Animation *lottie_animation_from_data(const char *data, const char *key, const char *resource_path); - -/** - * @brief Free given Animation object resource. - * - * @param[in] animation Animation object to free. - * - * @see lottie_animation_from_file() - * @see lottie_animation_from_data() - * - * @ingroup Lottie_Animation - * @internal - */ -RLOTTIE_API void lottie_animation_destroy(Lottie_Animation *animation); - -/** - * @brief Returns default viewport size of the Lottie resource. - * - * @param[in] animation Animation object. - * @param[out] w default width of the viewport. - * @param[out] h default height of the viewport. - * - * @ingroup Lottie_Animation - * @internal - */ -RLOTTIE_API void lottie_animation_get_size(const Lottie_Animation *animation, size_t *width, size_t *height); - -/** - * @brief Returns total animation duration of Lottie resource in second. - * it uses totalFrame() and frameRate() to calculate the duration. - * duration = totalFrame() / frameRate(). - * - * @param[in] animation Animation object. - * - * @return total animation duration in second. - * @c 0 if the Lottie resource has no animation. - * - * @see lottie_animation_get_totalframe() - * @see lottie_animation_get_framerate() - * - * @ingroup Lottie_Animation - * @internal - */ -RLOTTIE_API double lottie_animation_get_duration(const Lottie_Animation *animation); - -/** - * @brief Returns total number of frames present in the Lottie resource. - * - * @param[in] animation Animation object. - * - * @return frame count of the Lottie resource.* - * - * @note frame number starts with 0. - * - * @see lottie_animation_get_duration() - * @see lottie_animation_get_framerate() - * - * @ingroup Lottie_Animation - * @internal - */ -RLOTTIE_API size_t lottie_animation_get_totalframe(const Lottie_Animation *animation); - -/** - * @brief Returns default framerate of the Lottie resource. - * - * @param[in] animation Animation object. - * - * @return framerate of the Lottie resource - * - * @ingroup Lottie_Animation - * @internal - * - */ -RLOTTIE_API double lottie_animation_get_framerate(const Lottie_Animation *animation); - -/** - * @brief Get the render tree which contains the snapshot of the animation object - * at frame = @c frame_num, the content of the animation in that frame number. - * - * @param[in] animation Animation object. - * @param[in] frame_num Content corresponds to the @p frame_num needs to be drawn - * @param[in] width requested snapshot viewport width. - * @param[in] height requested snapshot viewport height. - * - * @return Animation snapshot tree. - * - * @note: User has to traverse the tree for rendering. - * - * @see LOTLayerNode - * @see LOTNode - * - * @ingroup Lottie_Animation - * @internal - */ -RLOTTIE_API const LOTLayerNode *lottie_animation_render_tree(Lottie_Animation *animation, size_t frame_num, size_t width, size_t height); - -/** - * @brief Maps position to frame number and returns it. - * - * @param[in] animation Animation object. - * @param[in] pos position in the range [ 0.0 .. 1.0 ]. - * - * @return mapped frame numbe in the range [ start_frame .. end_frame ]. - * @c 0 if the Lottie resource has no animation. - * - * - * @ingroup Lottie_Animation - * @internal - */ -RLOTTIE_API size_t lottie_animation_get_frame_at_pos(const Lottie_Animation *animation, float pos); - -/** - * @brief Request to render the content of the frame @p frame_num to buffer @p buffer. - * - * @param[in] animation Animation object. - * @param[in] frame_num the frame number needs to be rendered. - * @param[in] buffer surface buffer use for rendering. - * @param[in] width width of the surface - * @param[in] height height of the surface - * @param[in] bytes_per_line stride of the surface in bytes. - * - * - * @ingroup Lottie_Animation - * @internal - */ -RLOTTIE_API void lottie_animation_render(Lottie_Animation *animation, size_t frame_num, uint32_t *buffer, size_t width, size_t height, size_t bytes_per_line); - -/** - * @brief Request to render the content of the frame @p frame_num to buffer @p buffer asynchronously. - * - * @param[in] animation Animation object. - * @param[in] frame_num the frame number needs to be rendered. - * @param[in] buffer surface buffer use for rendering. - * @param[in] width width of the surface - * @param[in] height height of the surface - * @param[in] bytes_per_line stride of the surface in bytes. - * - * @note user must call lottie_animation_render_flush() to make sure render is finished. - * - * @ingroup Lottie_Animation - * @internal - */ -RLOTTIE_API void lottie_animation_render_async(Lottie_Animation *animation, size_t frame_num, uint32_t *buffer, size_t width, size_t height, size_t bytes_per_line); - -/** - * @brief Request to finish the current async renderer job for this animation object. - * If render is finished then this call returns immidiately. - * If not, it waits till render job finish and then return. - * - * @param[in] animation Animation object. - * - * @warning User must call lottie_animation_render_async() and lottie_animation_render_flush() - * in pair to get the benefit of async rendering. - * - * @return the pixel buffer it finished rendering. - * - * @ingroup Lottie_Animation - * @internal - */ -RLOTTIE_API uint32_t *lottie_animation_render_flush(Lottie_Animation *animation); - - -/** - * @brief Request to change the properties of this animation object. - * Keypath should conatin object names separated by (.) and can handle globe(**) or wildchar(*) - * - * @usage - * To change fillcolor property of fill1 object in the layer1->group1->fill1 hirarchy to RED color - * - * lottie_animation_property_override(animation, LOTTIE_ANIMATION_PROPERTY_FILLCOLOR, "layer1.group1.fill1", 1.0, 0.0, 0.0); - * - * if all the color property inside group1 needs to be changed to GREEN color - * - * lottie_animation_property_override(animation, LOTTIE_ANIMATION_PROPERTY_FILLCOLOR, "**.group1.**", 1.0, 0.0, 0.0); - * - * @param[in] animation Animation object. - * @param[in] type Property type. (@p Lottie_Animation_Property) - * @param[in] keypath Specific content of target. - * @param[in] ... Property values. - * - * @ingroup Lottie_Animation - * @internal - * */ -RLOTTIE_API void lottie_animation_property_override(Lottie_Animation *animation, const Lottie_Animation_Property type, const char *keypath, ...); - - -/** - * @brief Returns list of markers in the Lottie resource - * @p LOTMarkerList has a @p LOTMarker list and size of list - * @p LOTMarker has the marker's name, start frame, and end frame. - * - * @param[in] animation Animation object. - * - * @return The list of marker. If there is no marker, return null. - * - * @ingroup Lottie_Animation - * @internal - * */ -RLOTTIE_API const LOTMarkerList* lottie_animation_get_markerlist(Lottie_Animation *animation); - -/** - * @brief Configures rlottie model cache policy. - * - * Provides Library level control to configure model cache - * policy. Setting it to 0 will disable - * the cache as well as flush all the previously cached content. - * - * @param[in] cacheSize Maximum Model Cache size. - * - * @note to disable Caching configure with 0 size. - * @note to flush the current Cache content configure it with 0 and - * then reconfigure with the new size. - * - * @internal - */ -RLOTTIE_API void lottie_configure_model_cache_size(size_t cacheSize); - -#ifdef __cplusplus -} -#endif - -#endif //_RLOTTIE_CAPI_H_ - diff --git a/presentation/src/main/cpp/third_party/rlottie/inc/rlottiecommon.h b/presentation/src/main/cpp/third_party/rlottie/inc/rlottiecommon.h deleted file mode 100644 index 784fbe28..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/inc/rlottiecommon.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _RLOTTIE_COMMON_H_ -#define _RLOTTIE_COMMON_H_ - -#if defined _WIN32 || defined __CYGWIN__ - #ifdef RLOTTIE_BUILD - #define RLOTTIE_API __declspec(dllexport) - #else - #define RLOTTIE_API __declspec(dllimport) - #endif -#else - #ifdef RLOTTIE_BUILD - #define RLOTTIE_API __attribute__ ((visibility ("default"))) - #else - #define RLOTTIE_API - #endif -#endif - - -/** - * @defgroup Lottie_Animation Lottie_Animation - * - * Lottie Animation is a modern style vector based animation design. Its animation - * resource(within json format) could be generated by Adobe After Effect using - * bodymovin plugin. You can find a good examples in Lottie Community which - * shares many free resources(see: www.lottiefiles.com). - * - * This Lottie_Animation is a common engine to manipulate, control Lottie - * Animation from the Lottie resource - json file. It provides a scene-graph - * node tree per frames by user demand as well as rasterized frame images. - * - */ - -/** - * @ingroup Lottie_Animation - */ - -typedef enum -{ - BrushSolid = 0, - BrushGradient -} LOTBrushType; - -typedef enum -{ - FillEvenOdd = 0, - FillWinding -} LOTFillRule; - -typedef enum -{ - JoinMiter = 0, - JoinBevel, - JoinRound -} LOTJoinStyle; - -typedef enum -{ - CapFlat = 0, - CapSquare, - CapRound -} LOTCapStyle; - -typedef enum -{ - GradientLinear = 0, - GradientRadial -} LOTGradientType; - -typedef struct LOTGradientStop -{ - float pos; - unsigned char r, g, b, a; -} LOTGradientStop; - -typedef enum -{ - MaskAdd = 0, - MaskSubstract, - MaskIntersect, - MaskDifference -} LOTMaskType; - -typedef struct LOTMask { - struct { - const float *ptPtr; - size_t ptCount; - const char* elmPtr; - size_t elmCount; - } mPath; - LOTMaskType mMode; - unsigned char mAlpha; -}LOTMask; - -typedef enum -{ - MatteNone = 0, - MatteAlpha, - MatteAlphaInv, - MatteLuma, - MatteLumaInv -} LOTMatteType; - -typedef struct LOTMarker { - char *name; - size_t startframe; - size_t endframe; -} LOTMarker; - -typedef struct LOTMarkerList { - LOTMarker *ptr; - size_t size; -} LOTMarkerList; - -typedef struct LOTNode { - -#define ChangeFlagNone 0x0000 -#define ChangeFlagPath 0x0001 -#define ChangeFlagPaint 0x0010 -#define ChangeFlagAll (ChangeFlagPath & ChangeFlagPaint) - - struct { - const float *ptPtr; - size_t ptCount; - const char *elmPtr; - size_t elmCount; - } mPath; - - struct { - unsigned char r, g, b, a; - } mColor; - - struct { - unsigned char enable; - float width; - LOTCapStyle cap; - LOTJoinStyle join; - float miterLimit; - float *dashArray; - int dashArraySize; - } mStroke; - - struct { - LOTGradientType type; - LOTGradientStop *stopPtr; - size_t stopCount; - struct { - float x, y; - } start, end, center, focal; - float cradius; - float fradius; - } mGradient; - - struct { - unsigned char *data; - size_t width; - size_t height; - unsigned char mAlpha; - struct { - float m11; float m12; float m13; - float m21; float m22; float m23; - float m31; float m32; float m33; - } mMatrix; - } mImageInfo; - - int mFlag; - LOTBrushType mBrushType; - LOTFillRule mFillRule; - - const char *keypath; -} LOTNode; - - - -typedef struct LOTLayerNode { - - struct { - LOTMask *ptr; - size_t size; - } mMaskList; - - struct { - const float *ptPtr; - size_t ptCount; - const char *elmPtr; - size_t elmCount; - } mClipPath; - - struct { - struct LOTLayerNode **ptr; - size_t size; - } mLayerList; - - struct { - LOTNode **ptr; - size_t size; - } mNodeList; - - LOTMatteType mMatte; - int mVisible; - unsigned char mAlpha; - const char *keypath; - -} LOTLayerNode; - -/** - * @} - */ - -#endif // _RLOTTIE_COMMON_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.FTL b/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.FTL deleted file mode 100644 index 5f673ffa..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.FTL +++ /dev/null @@ -1,166 +0,0 @@ - The FreeType Project LICENSE - ---------------------------- - - 2006-Jan-27 - - Copyright 1996-2002, 2006 by - David Turner, Robert Wilhelm, and Werner Lemberg - - - -Introduction -============ - - The FreeType Project is distributed in several archive packages; - some of them may contain, in addition to the FreeType font engine, - various tools and contributions which rely on, or relate to, the - FreeType Project. - - This license applies to all files found in such packages, and - which do not fall under their own explicit license. The license - affects thus the FreeType font engine, the test programs, - documentation and makefiles, at the very least. - - This license was inspired by the BSD, Artistic, and IJG - (Independent JPEG Group) licenses, which all encourage inclusion - and use of free software in commercial and freeware products - alike. As a consequence, its main points are that: - - o We don't promise that this software works. However, we will be - interested in any kind of bug reports. (`as is' distribution) - - o You can use this software for whatever you want, in parts or - full form, without having to pay us. (`royalty-free' usage) - - o You may not pretend that you wrote this software. If you use - it, or only parts of it, in a program, you must acknowledge - somewhere in your documentation that you have used the - FreeType code. (`credits') - - We specifically permit and encourage the inclusion of this - software, with or without modifications, in commercial products. - We disclaim all warranties covering The FreeType Project and - assume no liability related to The FreeType Project. - - - Finally, many people asked us for a preferred form for a - credit/disclaimer to use in compliance with this license. We thus - encourage you to use the following text: - - """ - Portions of this software are copyright � The FreeType - Project (www.freetype.org). All rights reserved. - """ - - Please replace with the value from the FreeType version you - actually use. - - -Legal Terms -=========== - -0. Definitions --------------- - - Throughout this license, the terms `package', `FreeType Project', - and `FreeType archive' refer to the set of files originally - distributed by the authors (David Turner, Robert Wilhelm, and - Werner Lemberg) as the `FreeType Project', be they named as alpha, - beta or final release. - - `You' refers to the licensee, or person using the project, where - `using' is a generic term including compiling the project's source - code as well as linking it to form a `program' or `executable'. - This program is referred to as `a program using the FreeType - engine'. - - This license applies to all files distributed in the original - FreeType Project, including all source code, binaries and - documentation, unless otherwise stated in the file in its - original, unmodified form as distributed in the original archive. - If you are unsure whether or not a particular file is covered by - this license, you must contact us to verify this. - - The FreeType Project is copyright (C) 1996-2000 by David Turner, - Robert Wilhelm, and Werner Lemberg. All rights reserved except as - specified below. - -1. No Warranty --------------- - - THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY - KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO - USE, OF THE FREETYPE PROJECT. - -2. Redistribution ------------------ - - This license grants a worldwide, royalty-free, perpetual and - irrevocable right and license to use, execute, perform, compile, - display, copy, create derivative works of, distribute and - sublicense the FreeType Project (in both source and object code - forms) and derivative works thereof for any purpose; and to - authorize others to exercise some or all of the rights granted - herein, subject to the following conditions: - - o Redistribution of source code must retain this license file - (`FTL.TXT') unaltered; any additions, deletions or changes to - the original files must be clearly indicated in accompanying - documentation. The copyright notices of the unaltered, - original files must be preserved in all copies of source - files. - - o Redistribution in binary form must provide a disclaimer that - states that the software is based in part of the work of the - FreeType Team, in the distribution documentation. We also - encourage you to put an URL to the FreeType web page in your - documentation, though this isn't mandatory. - - These conditions apply to any software derived from or based on - the FreeType Project, not just the unmodified files. If you use - our work, you must acknowledge us. However, no fee need be paid - to us. - -3. Advertising --------------- - - Neither the FreeType authors and contributors nor you shall use - the name of the other for commercial, advertising, or promotional - purposes without specific prior written permission. - - We suggest, but do not require, that you use one or more of the - following phrases to refer to this software in your documentation - or advertising materials: `FreeType Project', `FreeType Engine', - `FreeType library', or `FreeType Distribution'. - - As you have not signed this license, you are not required to - accept it. However, as the FreeType Project is copyrighted - material, only this license, or another one contracted with the - authors, grants you the right to use, distribute, and modify it. - Therefore, by using, distributing, or modifying the FreeType - Project, you indicate that you understand and accept all the terms - of this license. - -4. Contacts ------------ - - There are two mailing lists related to FreeType: - - o freetype@nongnu.org - - Discusses general use and applications of FreeType, as well as - future and wanted additions to the library and distribution. - If you are looking for support, start in this list if you - haven't found anything to help you in the documentation. - - o freetype-devel@nongnu.org - - Discusses bugs, as well as engine internals, design issues, - specific licenses, porting, etc. - - Our home page can be found at - - http://www.freetype.org diff --git a/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.MIT b/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.MIT deleted file mode 100644 index 8becbac1..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.MIT +++ /dev/null @@ -1,7 +0,0 @@ -Copyright 2020 (see AUTHORS) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.MPL b/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.MPL deleted file mode 100644 index 14e2f777..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.MPL +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. diff --git a/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.PIX b/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.PIX deleted file mode 100644 index 5826f3c7..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.PIX +++ /dev/null @@ -1,42 +0,0 @@ -The following is the MIT license, agreed upon by most contributors. -Copyright holders of new code should use this license statement where -possible. They may also add themselves to the list below. - -/* - * Copyright 1987, 1988, 1989, 1998 The Open Group - * Copyright 1987, 1988, 1989 Digital Equipment Corporation - * Copyright 1999, 2004, 2008 Keith Packard - * Copyright 2000 SuSE, Inc. - * Copyright 2000 Keith Packard, member of The XFree86 Project, Inc. - * Copyright 2004, 2005, 2007, 2008, 2009, 2010 Red Hat, Inc. - * Copyright 2004 Nicholas Miell - * Copyright 2005 Lars Knoll & Zack Rusin, Trolltech - * Copyright 2005 Trolltech AS - * Copyright 2007 Luca Barbato - * Copyright 2008 Aaron Plattner, NVIDIA Corporation - * Copyright 2008 Rodrigo Kumpera - * Copyright 2008 André Tupinambá - * Copyright 2008 Mozilla Corporation - * Copyright 2008 Frederic Plourde - * Copyright 2009, Oracle and/or its affiliates. All rights reserved. - * Copyright 2009, 2010 Nokia Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ diff --git a/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.RPD b/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.RPD deleted file mode 100644 index 7ccc161c..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.RPD +++ /dev/null @@ -1,57 +0,0 @@ -Tencent is pleased to support the open source community by making RapidJSON available. - -Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. - -If you have downloaded a copy of the RapidJSON binary from Tencent, please note that the RapidJSON binary is licensed under the MIT License. -If you have downloaded a copy of the RapidJSON source code from Tencent, please note that RapidJSON source code is licensed under the MIT License, except for the third-party components listed below which are subject to different license terms. Your integration of RapidJSON into your own projects may require compliance with the MIT License, as well as the other licenses applicable to the third-party components included within RapidJSON. To avoid the problematic JSON license in your own projects, it's sufficient to exclude the bin/jsonchecker/ directory, as it's the only code under the JSON license. -A copy of the MIT License is included in this file. - -Other dependencies and licenses: - -Open Source Software Licensed Under the BSD License: --------------------------------------------------------------------- - -The msinttypes r29 -Copyright (c) 2006-2013 Alexander Chemeris -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -* Neither the name of copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Open Source Software Licensed Under the JSON License: --------------------------------------------------------------------- - -json.org -Copyright (c) 2002 JSON.org -All Rights Reserved. - -JSON_checker -Copyright (c) 2002 JSON.org -All Rights Reserved. - - -Terms of the JSON License: ---------------------------------------------------- - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -Terms of the MIT License: --------------------------------------------------------------------- - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.SKIA b/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.SKIA deleted file mode 100644 index e32636d5..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.SKIA +++ /dev/null @@ -1,29 +0,0 @@ -Copyright (c) 2011 Google Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.STB b/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.STB deleted file mode 100644 index 1da71ca8..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/licenses/COPYING.STB +++ /dev/null @@ -1,17 +0,0 @@ - MIT License -Copyright (c) 2017 Sean Barrett -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/presentation/src/main/cpp/third_party/rlottie/meson.build b/presentation/src/main/cpp/third_party/rlottie/meson.build deleted file mode 100644 index 50404c58..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/meson.build +++ /dev/null @@ -1,121 +0,0 @@ -project('rlottie', - 'cpp', - default_options : ['cpp_std=c++14', 'optimization=s'], - version : '0.2', - license : 'MIT', - meson_version : '>=0.49', - ) - -add_project_arguments('-DDEMO_DIR="@0@/example/resource/"'.format(meson.current_source_dir()), language : 'cpp') - -inc = [include_directories('inc')] -config_dir = include_directories('.') -inc += config_dir - -config_h = configuration_data() - -if get_option('thread') == true - config_h.set10('LOTTIE_THREAD_SUPPORT', true) -endif - -if get_option('module') == true - config_h.set10('LOTTIE_IMAGE_MODULE_SUPPORT', true) - - if meson.get_compiler('cpp').get_id() != 'msvc' - lib_prefix = 'lib' - else - lib_prefix = '' - endif - if host_machine.system() == 'darwin' - lib_suffix = '.dylib' - elif host_machine.system() == 'windows' - lib_suffix = '.dll' - else - lib_suffix = '.so' - endif - if get_option('moduledir') != '' - config_h.set_quoted('LOTTIE_IMAGE_MODULE_PLUGIN', - get_option('prefix') / get_option('moduledir') / lib_prefix + 'rlottie-image-loader' + lib_suffix) - else - config_h.set_quoted('LOTTIE_IMAGE_MODULE_PLUGIN', lib_prefix + 'rlottie-image-loader' + lib_suffix) - endif -endif - -if get_option('cache') == true - config_h.set10('LOTTIE_CACHE_SUPPORT', true) -endif - -if get_option('log') == true - config_h.set10('LOTTIE_LOGGING_SUPPORT', true) -endif - -if get_option('dumptree') == true - config_h.set10('LOTTIE_LOGGING_SUPPORT', true) - config_h.set10('LOTTIE_DUMP_TREE_SUPPORT', true) -endif - - -configure_file( - output: 'config.h', - configuration: config_h -) - - -subdir('inc') -subdir('src') - -if get_option('example') == true - subdir('example') -endif - -if get_option('test') == true - subdir('test') -endif - - -if get_option('cmake') == true and host_machine.system() != 'windows' - cmake_bin = find_program('cmake', required: false) - if cmake_bin.found() - cmake = import('cmake') - cmake.write_basic_package_version_file( - version: meson.project_version(), - name: 'rlottie', - ) - - cmakeconf = configuration_data() - cmakeconf.set('VERSION', meson.project_version()) - - cmake.configure_package_config_file( - input: meson.current_source_dir() + '/cmake/rlottieConfig.cmake.in', - name: 'rlottie', - configuration: cmakeconf, - ) - endif -endif - -summary = ''' - -Summary: - rlottie version : @0@ - Build type : @1@ - Thread Support : @2@ - Module Support : @3@ - Cache Support : @4@ - Example : @5@ - Test : @6@ - Prefix : @7@ -'''.format( - meson.project_version(), - get_option('buildtype'), - get_option('thread'), - get_option('module'), - get_option('cache'), - get_option('example'), - get_option('test'), - get_option('prefix'), - ) - -message(summary) - - - diff --git a/presentation/src/main/cpp/third_party/rlottie/meson_options.txt b/presentation/src/main/cpp/third_party/rlottie/meson_options.txt deleted file mode 100644 index 25d8ec38..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/meson_options.txt +++ /dev/null @@ -1,46 +0,0 @@ -option('thread', - type: 'boolean', - value: true, - description: 'Enable threading in rlottie') - -option('cache', - type: 'boolean', - value: true, - description: 'Enable cache support in rlottie') - -option('module', - type: 'boolean', - value: true, - description: 'Enable module support in rlottie') - -option('moduledir', - type: 'string', - description: 'Dynamic plugins directory') - -option('log', - type: 'boolean', - value: false, - description: 'Enable logging in rlottie') - -option('dumptree', - type: 'boolean', - value: false, - description: 'Enable logging the rlottie tree in rlottie') - -option('test', - type: 'boolean', - value: false, - description: 'Enable building unit tests') - -option('example', - type: 'boolean', - value: true, - description: 'Enable building examples') - -option('cmake', - type: 'boolean', - value: false, - description: 'Enable Generating CMake config files') - - - diff --git a/presentation/src/main/cpp/third_party/rlottie/packaging/rlottie.manifest b/presentation/src/main/cpp/third_party/rlottie/packaging/rlottie.manifest deleted file mode 100644 index 017d22d3..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/packaging/rlottie.manifest +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/presentation/src/main/cpp/third_party/rlottie/packaging/rlottie.spec b/presentation/src/main/cpp/third_party/rlottie/packaging/rlottie.spec deleted file mode 100644 index 55cdee8e..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/packaging/rlottie.spec +++ /dev/null @@ -1,85 +0,0 @@ -%define major 0 -%define libname %mklibname rlottie %{major} -%define devel %mklibname rlottie -d - -%define git 20200408 -%define rel 2 - -Name: rlottie -Version: 0.2 -Release: %mkrel %{?git:-c git%{git}} %{rel} -Summary: Platform independent standalone library that plays Lottie Animation -Group: System/Libraries -License: MIT and BSD and MPL-2.0 -URL: http://www.tizen.org/ -Source0: https://github.com/Samsung/rlottie/archive/master/%{name}-%{version}%{?git:-git%{git}}.tar.gz - -BuildRequires: meson - -%description -rlottie is a platform independent standalone c++ library for rendering vector -based animations and art in realtime. - -Lottie loads and renders animations and vectors exported in the bodymovin JSON -format. Bodymovin JSON can be created and exported from After Effects with -bodymovin, Sketch with Lottie Sketch Export, and from Haiku. - -For the first time, designers can create and ship beautiful animations without -an engineer painstakingly recreating it by hand. Since the animation is backed -by JSON they are extremely small in size but can be large in complexity! - -%package -n %{devel} -Summary: Development libraries for rlottie -Group: System/Libraries - -%description -n %{devel} -rlottie is a platform independent standalone c++ library for rendering vector -based animations and art in realtime. - -Lottie loads and renders animations and vectors exported in the bodymovin JSON -format. Bodymovin JSON can be created and exported from After Effects with -bodymovin, Sketch with Lottie Sketch Export, and from Haiku. - -For the first time, designers can create and ship beautiful animations without -an engineer painstakingly recreating it by hand. Since the animation is backed -by JSON they are extremely small in size but can be large in complexity! - -This is the development libraries for rlottie. - -%package -n %{libname} -Summary: Platform independent standalone library that plays Lottie Animation -Group: System/Libraries - -%description -n %{libname} -rlottie is a platform independent standalone c++ library for rendering vector -based animations and art in realtime. - -Lottie loads and renders animations and vectors exported in the bodymovin JSON -format. Bodymovin JSON can be created and exported from After Effects with -bodymovin, Sketch with Lottie Sketch Export, and from Haiku. - -For the first time, designers can create and ship beautiful animations without -an engineer painstakingly recreating it by hand. Since the animation is backed -by JSON they are extremely small in size but can be large in complexity! - -%prep -%autosetup -n %{name}-master - -%build -%meson - -%install -%meson_install - -%files -n %{devel} -%{_includedir}/rlottie.h -%{_includedir}/rlottie_capi.h -%{_includedir}/rlottiecommon.h -%{_libdir}/pkgconfig/rlottie.pc -%{_libdir}/librlottie.so - -%files -n %{libname} -%license COPYING -%doc README.md AUTHORS -%{_libdir}/librlottie-image-loader.so -%{_libdir}/librlottie.so.%{major}{,.*} diff --git a/presentation/src/main/cpp/third_party/rlottie/rlottie.expmap b/presentation/src/main/cpp/third_party/rlottie/rlottie.expmap deleted file mode 100644 index cfc38287..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/rlottie.expmap +++ /dev/null @@ -1,8 +0,0 @@ -/* This version script for ld exposes only (r)lottie namespace. */ -{ -global: - lottie_*; - extern "C++" { rlottie::* }; -local: - *; -}; diff --git a/presentation/src/main/cpp/third_party/rlottie/rlottie.pc.in b/presentation/src/main/cpp/third_party/rlottie/rlottie.pc.in deleted file mode 100644 index 3cee683a..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/rlottie.pc.in +++ /dev/null @@ -1,6 +0,0 @@ -Name: rlottie -Description: A rlottie library -Version: @player_version@ -Requires: -Libs: -L@LIBDIR@ -lrlottie -Cflags: -I@INCDIR@ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/CMakeLists.txt b/presentation/src/main/cpp/third_party/rlottie/src/CMakeLists.txt deleted file mode 100644 index 8bdefec0..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ - -add_subdirectory(vector) - -add_subdirectory(lottie) - -add_subdirectory(binding) diff --git a/presentation/src/main/cpp/third_party/rlottie/src/binding/CMakeLists.txt b/presentation/src/main/cpp/third_party/rlottie/src/binding/CMakeLists.txt deleted file mode 100644 index 20bc4cc4..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/binding/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_subdirectory(c) diff --git a/presentation/src/main/cpp/third_party/rlottie/src/binding/c/CMakeLists.txt b/presentation/src/main/cpp/third_party/rlottie/src/binding/c/CMakeLists.txt deleted file mode 100644 index 30a049ad..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/binding/c/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -target_sources(rlottie - PRIVATE - "${CMAKE_CURRENT_LIST_DIR}/lottieanimation_capi.cpp" - ) - -target_include_directories(rlottie - PRIVATE - "${CMAKE_CURRENT_LIST_DIR}" - ) diff --git a/presentation/src/main/cpp/third_party/rlottie/src/binding/c/lottieanimation_capi.cpp b/presentation/src/main/cpp/third_party/rlottie/src/binding/c/lottieanimation_capi.cpp deleted file mode 100644 index e93b0554..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/binding/c/lottieanimation_capi.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "rlottie.h" -#include "rlottie_capi.h" -#include "vdebug.h" - -using namespace rlottie; - -extern void lottie_init_impl(); -extern void lottie_shutdown_impl(); - -extern "C" { -#include -#include - -struct Lottie_Animation_S -{ - std::unique_ptr mAnimation; - std::future mRenderTask; - uint32_t *mBufferRef; - LOTMarkerList *mMarkerList; -}; - -static uint32_t _lottie_lib_ref_count = 0; - -RLOTTIE_API void lottie_init(void) -{ - if (_lottie_lib_ref_count > 0) { - _lottie_lib_ref_count++; - return; - } - lottie_init_impl(); - - _lottie_lib_ref_count = 1; -} - -RLOTTIE_API void lottie_shutdown(void) -{ - if (_lottie_lib_ref_count <= 0) { - // lottie_init() is not called before lottie_shutdown() - // or multiple shutdown is getting called. - return; - } - - _lottie_lib_ref_count--; - - if (_lottie_lib_ref_count == 0) { - lottie_shutdown_impl(); - } -} - -RLOTTIE_API Lottie_Animation_S *lottie_animation_from_file(const char *path) -{ - if (auto animation = Animation::loadFromFile(path) ) { - Lottie_Animation_S *handle = new Lottie_Animation_S(); - handle->mAnimation = std::move(animation); - return handle; - } else { - return nullptr; - } -} - -RLOTTIE_API Lottie_Animation_S *lottie_animation_from_data(const char *data, const char *key, const char *resourcePath) -{ - if (auto animation = Animation::loadFromData(data, key, resourcePath) ) { - Lottie_Animation_S *handle = new Lottie_Animation_S(); - handle->mAnimation = std::move(animation); - return handle; - } else { - return nullptr; - } -} - -RLOTTIE_API void lottie_animation_destroy(Lottie_Animation_S *animation) -{ - if (animation) { - if (animation->mMarkerList) { - for(size_t i = 0; i < animation->mMarkerList->size; i++) { - if (animation->mMarkerList->ptr[i].name) free(animation->mMarkerList->ptr[i].name); - } - delete[] animation->mMarkerList->ptr; - delete animation->mMarkerList; - } - - if (animation->mRenderTask.valid()) { - animation->mRenderTask.get(); - } - animation->mAnimation = nullptr; - delete animation; - } -} - -RLOTTIE_API void lottie_animation_get_size(const Lottie_Animation_S *animation, size_t *width, size_t *height) -{ - if (!animation) return; - - animation->mAnimation->size(*width, *height); -} - -RLOTTIE_API double lottie_animation_get_duration(const Lottie_Animation_S *animation) -{ - if (!animation) return 0; - - return animation->mAnimation->duration(); -} - -RLOTTIE_API size_t lottie_animation_get_totalframe(const Lottie_Animation_S *animation) -{ - if (!animation) return 0; - - return animation->mAnimation->totalFrame(); -} - - -RLOTTIE_API double lottie_animation_get_framerate(const Lottie_Animation_S *animation) -{ - if (!animation) return 0; - - return animation->mAnimation->frameRate(); -} - -RLOTTIE_API const LOTLayerNode * lottie_animation_render_tree(Lottie_Animation_S *animation, size_t frame_num, size_t width, size_t height) -{ - if (!animation) return nullptr; - - return animation->mAnimation->renderTree(frame_num, width, height); -} - -RLOTTIE_API size_t -lottie_animation_get_frame_at_pos(const Lottie_Animation_S *animation, float pos) -{ - if (!animation) return 0; - - return animation->mAnimation->frameAtPos(pos); -} - -RLOTTIE_API void -lottie_animation_render(Lottie_Animation_S *animation, - size_t frame_number, - uint32_t *buffer, - size_t width, - size_t height, - size_t bytes_per_line) -{ - if (!animation) return; - - rlottie::Surface surface(buffer, width, height, bytes_per_line); - animation->mAnimation->renderSync(frame_number, surface); -} - -RLOTTIE_API void -lottie_animation_render_async(Lottie_Animation_S *animation, - size_t frame_number, - uint32_t *buffer, - size_t width, - size_t height, - size_t bytes_per_line) -{ - if (!animation) return; - - rlottie::Surface surface(buffer, width, height, bytes_per_line); - animation->mRenderTask = animation->mAnimation->render(frame_number, surface); - animation->mBufferRef = buffer; -} - -RLOTTIE_API uint32_t * -lottie_animation_render_flush(Lottie_Animation_S *animation) -{ - if (!animation) return nullptr; - - if (animation->mRenderTask.valid()) { - animation->mRenderTask.get(); - } - - return animation->mBufferRef; -} - -RLOTTIE_API void -lottie_animation_property_override(Lottie_Animation_S *animation, - const Lottie_Animation_Property type, - const char *keypath, - ...) -{ - va_list prop; - va_start(prop, keypath); - const int arg_count = [type](){ - switch (type) { - case LOTTIE_ANIMATION_PROPERTY_FILLCOLOR: - case LOTTIE_ANIMATION_PROPERTY_STROKECOLOR: - return 3; - case LOTTIE_ANIMATION_PROPERTY_FILLOPACITY: - case LOTTIE_ANIMATION_PROPERTY_STROKEOPACITY: - case LOTTIE_ANIMATION_PROPERTY_STROKEWIDTH: - case LOTTIE_ANIMATION_PROPERTY_TR_ROTATION: - case LOTTIE_ANIMATION_PROPERTY_TRIM_PATH_START: - return 1; - case LOTTIE_ANIMATION_PROPERTY_TR_POSITION: - case LOTTIE_ANIMATION_PROPERTY_TR_SCALE: - case LOTTIE_ANIMATION_PROPERTY_TRIM_PATH_END: - return 2; - default: - return 0; - } - }(); - double v[3] = {0}; - for (int i = 0; i < arg_count ; i++) { - v[i] = va_arg(prop, double); - } - va_end(prop); - - switch(type) { - case LOTTIE_ANIMATION_PROPERTY_FILLCOLOR: { - double r = v[0]; - double g = v[1]; - double b = v[2]; - if (r > 1 || r < 0 || g > 1 || g < 0 || b > 1 || b < 0) break; - animation->mAnimation->setValue(keypath, rlottie::Color(r, g, b)); - break; - } - case LOTTIE_ANIMATION_PROPERTY_FILLOPACITY: { - double opacity = v[0]; - if (opacity > 100 || opacity < 0) break; - animation->mAnimation->setValue(keypath, (float)opacity); - break; - } - case LOTTIE_ANIMATION_PROPERTY_STROKECOLOR: { - double r = v[0]; - double g = v[1]; - double b = v[2]; - if (r > 1 || r < 0 || g > 1 || g < 0 || b > 1 || b < 0) break; - animation->mAnimation->setValue(keypath, rlottie::Color(r, g, b)); - break; - } - case LOTTIE_ANIMATION_PROPERTY_STROKEOPACITY: { - double opacity = v[0]; - if (opacity > 100 || opacity < 0) break; - animation->mAnimation->setValue(keypath, (float)opacity); - break; - } - case LOTTIE_ANIMATION_PROPERTY_STROKEWIDTH: { - double width = v[0]; - if (width < 0) break; - animation->mAnimation->setValue(keypath, (float)width); - break; - } - case LOTTIE_ANIMATION_PROPERTY_TR_POSITION: { - double x = v[0]; - double y = v[1]; - animation->mAnimation->setValue(keypath, rlottie::Point((float)x, (float)y)); - break; - } - case LOTTIE_ANIMATION_PROPERTY_TR_SCALE: { - double w = v[0]; - double h = v[1]; - animation->mAnimation->setValue(keypath, rlottie::Size((float)w, (float)h)); - break; - } - case LOTTIE_ANIMATION_PROPERTY_TR_ROTATION: { - double r = v[0]; - animation->mAnimation->setValue(keypath, (float)r); - break; - } - case LOTTIE_ANIMATION_PROPERTY_TRIM_PATH_START: { - double start = v[0]; - if (start < 0 || start > 100) break; - animation->mAnimation->setValue(keypath, (float)start); - break; - } - case LOTTIE_ANIMATION_PROPERTY_TRIM_PATH_END: { - double start = v[0]; - double end = v[1]; - if (start < 0 || start > 100 || end < 0 || end > 100) break; - animation->mAnimation->setValue(keypath, rlottie::Point((float)start, (float)end)); - break; - } - case LOTTIE_ANIMATION_PROPERTY_TR_ANCHOR: - case LOTTIE_ANIMATION_PROPERTY_TR_OPACITY: - //@TODO handle propery update. - break; - } -} - -RLOTTIE_API const LOTMarkerList* -lottie_animation_get_markerlist(Lottie_Animation_S *animation) -{ - if (!animation) return nullptr; - - auto markers = animation->mAnimation->markers(); - if (markers.size() == 0) return nullptr; - if (animation->mMarkerList) return (const LOTMarkerList*)animation->mMarkerList; - - animation->mMarkerList = new LOTMarkerList(); - animation->mMarkerList->size = markers.size(); - animation->mMarkerList->ptr = new LOTMarker[markers.size()](); - - for(size_t i = 0; i < markers.size(); i++) { - animation->mMarkerList->ptr[i].name = strdup(std::get<0>(markers[i]).c_str()); - animation->mMarkerList->ptr[i].startframe= std::get<1>(markers[i]); - animation->mMarkerList->ptr[i].endframe= std::get<2>(markers[i]); - } - return (const LOTMarkerList*)animation->mMarkerList; -} - -RLOTTIE_API void -lottie_configure_model_cache_size(size_t cacheSize) -{ - rlottie::configureModelCacheSize(cacheSize); -} - -} diff --git a/presentation/src/main/cpp/third_party/rlottie/src/binding/c/meson.build b/presentation/src/main/cpp/third_party/rlottie/src/binding/c/meson.build deleted file mode 100644 index 182aba59..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/binding/c/meson.build +++ /dev/null @@ -1,6 +0,0 @@ -source_file = files('lottieanimation_capi.cpp') - -binding_c_dep = declare_dependency( - include_directories : include_directories('.'), - sources : source_file - ) diff --git a/presentation/src/main/cpp/third_party/rlottie/src/binding/meson.build b/presentation/src/main/cpp/third_party/rlottie/src/binding/meson.build deleted file mode 100644 index 4be25091..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/binding/meson.build +++ /dev/null @@ -1,2 +0,0 @@ -subdir('c') -binding_dep = binding_c_dep diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/CMakeLists.txt b/presentation/src/main/cpp/third_party/rlottie/src/lottie/CMakeLists.txt deleted file mode 100644 index a5895b0a..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -add_subdirectory(zip) - -target_sources(rlottie - PRIVATE - "${CMAKE_CURRENT_LIST_DIR}/lottieitem.cpp" - "${CMAKE_CURRENT_LIST_DIR}/lottieitem_capi.cpp" - "${CMAKE_CURRENT_LIST_DIR}/lottieloader.cpp" - "${CMAKE_CURRENT_LIST_DIR}/lottiemodel.cpp" - "${CMAKE_CURRENT_LIST_DIR}/lottieproxymodel.cpp" - "${CMAKE_CURRENT_LIST_DIR}/lottieparser.cpp" - "${CMAKE_CURRENT_LIST_DIR}/lottieanimation.cpp" - "${CMAKE_CURRENT_LIST_DIR}/lottiekeypath.cpp" - ) - -target_include_directories(rlottie - PRIVATE - "${CMAKE_CURRENT_LIST_DIR}" - ) diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieanimation.cpp b/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieanimation.cpp deleted file mode 100644 index afcc400b..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieanimation.cpp +++ /dev/null @@ -1,495 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "config.h" -#include "lottieitem.h" -#include "lottiemodel.h" -#include "rlottie.h" - -#include - -using namespace rlottie; -using namespace rlottie::internal; - -RLOTTIE_API void rlottie::configureModelCacheSize(size_t cacheSize) -{ - internal::model::configureModelCacheSize(cacheSize); -} - -struct RenderTask { - RenderTask() { receiver = sender.get_future(); } - std::promise sender; - std::future receiver; - AnimationImpl * playerImpl{nullptr}; - size_t frameNo{0}; - Surface surface; - bool keepAspectRatio{true}; -}; -using SharedRenderTask = std::shared_ptr; - -class AnimationImpl { -public: - void init(std::shared_ptr composition); - bool update(size_t frameNo, const VSize &size, bool keepAspectRatio); - VSize size() const { return mModel->size(); } - double duration() const { return mModel->duration(); } - double frameRate() const { return mModel->frameRate(); } - size_t totalFrame() const { return mModel->totalFrame(); } - size_t frameAtPos(double pos) const { return mModel->frameAtPos(pos); } - Surface render(size_t frameNo, const Surface &surface, - bool keepAspectRatio); - std::future renderAsync(size_t frameNo, Surface &&surface, - bool keepAspectRatio); - const LOTLayerNode * renderTree(size_t frameNo, const VSize &size); - - const LayerInfoList &layerInfoList() const - { - if (mLayerList.empty()) { - mLayerList = mModel->layerInfoList(); - } - return mLayerList; - } - const MarkerList &markers() const { return mModel->markers(); } - void setValue(const std::string &keypath, LOTVariant &&value); - void removeFilter(const std::string &keypath, Property prop); - -private: - mutable LayerInfoList mLayerList; - model::Composition * mModel; - SharedRenderTask mTask; - std::atomic mRenderInProgress; - std::unique_ptr mRenderer{nullptr}; -}; - -void AnimationImpl::setValue(const std::string &keypath, LOTVariant &&value) -{ - if (keypath.empty()) return; - mRenderer->setValue(keypath, value); -} - -const LOTLayerNode *AnimationImpl::renderTree(size_t frameNo, const VSize &size) -{ - if (update(frameNo, size, true)) { - mRenderer->buildRenderTree(); - } - return mRenderer->renderTree(); -} - -bool AnimationImpl::update(size_t frameNo, const VSize &size, - bool keepAspectRatio) -{ - frameNo += mModel->startFrame(); - - if (frameNo > mModel->endFrame()) frameNo = mModel->endFrame(); - - if (frameNo < mModel->startFrame()) frameNo = mModel->startFrame(); - - return mRenderer->update(int(frameNo), size, keepAspectRatio); -} - -Surface AnimationImpl::render(size_t frameNo, const Surface &surface, - bool keepAspectRatio) -{ - bool renderInProgress = mRenderInProgress.load(); - if (renderInProgress) { - vCritical << "Already Rendering Scheduled for this Animation"; - return surface; - } - - mRenderInProgress.store(true); - update( - frameNo, - VSize(int(surface.drawRegionWidth()), int(surface.drawRegionHeight())), - keepAspectRatio); - mRenderer->render(surface); - mRenderInProgress.store(false); - - return surface; -} - -void AnimationImpl::init(std::shared_ptr composition) -{ - mModel = composition.get(); - mRenderer = std::make_unique(composition); - mRenderInProgress = false; -} - -#ifdef LOTTIE_THREAD_SUPPORT - -#include -#include "vtaskqueue.h" - -/* - * Implement a task stealing schduler to perform render task - * As each player draws into its own buffer we can delegate this - * task to a slave thread. The scheduler creates a threadpool depending - * on the number of cores available in the system and does a simple fair - * scheduling by assigning the task in a round-robin fashion. Each thread - * in the threadpool has its own queue. once it finishes all the task on its - * own queue it goes through rest of the queue and looks for task if it founds - * one it steals the task from it and executes. if it couldn't find one then it - * just waits for new task on its own queue. - */ -class RenderTaskScheduler { - const unsigned _count{std::thread::hardware_concurrency()}; - std::vector _threads; - std::vector> _q{_count}; - std::atomic _index{0}; - - void run(unsigned i) - { - while (true) { - bool success = false; - SharedRenderTask task; - for (unsigned n = 0; n != _count * 2; ++n) { - if (_q[(i + n) % _count].try_pop(task)) { - success = true; - break; - } - } - if (!success && !_q[i].pop(task)) break; - - auto result = task->playerImpl->render(task->frameNo, task->surface, - task->keepAspectRatio); - task->sender.set_value(result); - } - } - - RenderTaskScheduler() - { - for (unsigned n = 0; n != _count; ++n) { - _threads.emplace_back([&, n] { run(n); }); - } - - IsRunning = true; - } - -public: - static bool IsRunning; - - static RenderTaskScheduler &instance() - { - static RenderTaskScheduler singleton; - return singleton; - } - - ~RenderTaskScheduler() { stop(); } - - void stop() - { - if (IsRunning) { - IsRunning = false; - - for (auto &e : _q) e.done(); - for (auto &e : _threads) e.join(); - } - } - - std::future process(SharedRenderTask task) - { - auto receiver = std::move(task->receiver); - auto i = _index++; - - for (unsigned n = 0; n != _count; ++n) { - if (_q[(i + n) % _count].try_push(std::move(task))) return receiver; - } - - if (_count > 0) { - _q[i % _count].push(std::move(task)); - } - - return receiver; - } -}; - -#else -class RenderTaskScheduler { -public: - static bool IsRunning; - - static RenderTaskScheduler &instance() - { - static RenderTaskScheduler singleton; - return singleton; - } - - void stop() {} - - std::future process(SharedRenderTask task) - { - auto result = task->playerImpl->render(task->frameNo, task->surface, - task->keepAspectRatio); - task->sender.set_value(result); - return std::move(task->receiver); - } -}; - -#endif - -bool RenderTaskScheduler::IsRunning{false}; - -std::future AnimationImpl::renderAsync(size_t frameNo, - Surface &&surface, - bool keepAspectRatio) -{ - if (!mTask) { - mTask = std::make_shared(); - } else { - mTask->sender = std::promise(); - mTask->receiver = mTask->sender.get_future(); - } - mTask->playerImpl = this; - mTask->frameNo = frameNo; - mTask->surface = std::move(surface); - mTask->keepAspectRatio = keepAspectRatio; - - return RenderTaskScheduler::instance().process(mTask); -} - -/** - * \breif Brief abput the Api. - * Description about the setFilePath Api - * @param path add the details - */ -std::unique_ptr Animation::loadFromData( - std::string jsonData, const std::string &key, - const std::string &resourcePath, bool cachePolicy) -{ - if (jsonData.empty()) { - vWarning << "jason data is empty"; - return nullptr; - } - - auto composition = model::loadFromData(std::move(jsonData), key, - resourcePath, cachePolicy); - if (composition) { - auto animation = std::unique_ptr(new Animation); - animation->d->init(std::move(composition)); - return animation; - } - - return nullptr; -} - -std::unique_ptr Animation::loadFromData(std::string jsonData, - std::string resourcePath, - ColorFilter filter) -{ - if (jsonData.empty()) { - vWarning << "jason data is empty"; - return nullptr; - } - - auto composition = model::loadFromData( - std::move(jsonData), std::move(resourcePath), std::move(filter)); - if (composition) { - auto animation = std::unique_ptr(new Animation); - animation->d->init(std::move(composition)); - return animation; - } - return nullptr; -} - -std::unique_ptr Animation::loadFromFile(const std::string &path, - bool cachePolicy) -{ - if (path.empty()) { - vWarning << "File path is empty"; - return nullptr; - } - - auto composition = model::loadFromFile(path, cachePolicy); - if (composition) { - auto animation = std::unique_ptr(new Animation); - animation->d->init(std::move(composition)); - return animation; - } - return nullptr; -} - -void Animation::size(size_t &width, size_t &height) const -{ - VSize sz = d->size(); - - width = sz.width(); - height = sz.height(); -} - -double Animation::duration() const -{ - return d->duration(); -} - -double Animation::frameRate() const -{ - return d->frameRate(); -} - -size_t Animation::totalFrame() const -{ - return d->totalFrame(); -} - -size_t Animation::frameAtPos(double pos) -{ - return d->frameAtPos(pos); -} - -const LOTLayerNode *Animation::renderTree(size_t frameNo, size_t width, - size_t height) const -{ - return d->renderTree(frameNo, VSize(int(width), int(height))); -} - -std::future Animation::render(size_t frameNo, Surface surface, - bool keepAspectRatio) -{ - return d->renderAsync(frameNo, std::move(surface), keepAspectRatio); -} - -void Animation::renderSync(size_t frameNo, Surface surface, - bool keepAspectRatio) -{ - d->render(frameNo, surface, keepAspectRatio); -} - -const LayerInfoList &Animation::layers() const -{ - return d->layerInfoList(); -} - -const MarkerList &Animation::markers() const -{ - return d->markers(); -} - -void Animation::setValue(Color_Type, Property prop, const std::string &keypath, - Color value) -{ - d->setValue(keypath, - LOTVariant(prop, [value](const FrameInfo &) { return value; })); -} - -void Animation::setValue(Float_Type, Property prop, const std::string &keypath, - float value) -{ - d->setValue(keypath, - LOTVariant(prop, [value](const FrameInfo &) { return value; })); -} - -void Animation::setValue(Size_Type, Property prop, const std::string &keypath, - Size value) -{ - d->setValue(keypath, - LOTVariant(prop, [value](const FrameInfo &) { return value; })); -} - -void Animation::setValue(Point_Type, Property prop, const std::string &keypath, - Point value) -{ - d->setValue(keypath, - LOTVariant(prop, [value](const FrameInfo &) { return value; })); -} - -void Animation::setValue(Color_Type, Property prop, const std::string &keypath, - std::function &&value) -{ - d->setValue(keypath, LOTVariant(prop, value)); -} - -void Animation::setValue(Float_Type, Property prop, const std::string &keypath, - std::function &&value) -{ - d->setValue(keypath, LOTVariant(prop, value)); -} - -void Animation::setValue(Size_Type, Property prop, const std::string &keypath, - std::function &&value) -{ - d->setValue(keypath, LOTVariant(prop, value)); -} - -void Animation::setValue(Point_Type, Property prop, const std::string &keypath, - std::function &&value) -{ - d->setValue(keypath, LOTVariant(prop, value)); -} - -Animation::~Animation() = default; -Animation::Animation() : d(std::make_unique()) {} - -Surface::Surface(uint32_t *buffer, size_t width, size_t height, - size_t bytesPerLine) - : mBuffer(buffer), - mWidth(width), - mHeight(height), - mBytesPerLine(bytesPerLine) -{ - mDrawArea.w = mWidth; - mDrawArea.h = mHeight; -} - -void Surface::setDrawRegion(size_t x, size_t y, size_t width, size_t height) -{ - if ((x + width > mWidth) || (y + height > mHeight)) return; - - mDrawArea.x = x; - mDrawArea.y = y; - mDrawArea.w = width; - mDrawArea.h = height; -} - -namespace { -void lottieShutdownRenderTaskScheduler() -{ - if (RenderTaskScheduler::IsRunning) { - RenderTaskScheduler::instance().stop(); - } -} -} // namespace - -// private apis exposed to c interface -void lottie_init_impl() -{ - // do nothing for now. -} - -extern void lottieShutdownRasterTaskScheduler(); - -void lottie_shutdown_impl() -{ - lottieShutdownRenderTaskScheduler(); - lottieShutdownRasterTaskScheduler(); -} - -#ifdef LOTTIE_LOGGING_SUPPORT -void initLogging() -{ -#if defined(__ARM_NEON__) - set_log_level(LogLevel::OFF); -#else - initialize(GuaranteedLogger(), "/tmp/", "rlottie", 1); - set_log_level(LogLevel::INFO); -#endif -} - -V_CONSTRUCTOR_FUNCTION(initLogging) -#endif diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottiefiltermodel.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottiefiltermodel.h deleted file mode 100644 index 015e9cb4..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottiefiltermodel.h +++ /dev/null @@ -1,454 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef LOTTIEFILTERMODEL_H -#define LOTTIEFILTERMODEL_H - -#include -#include -#include -#include "lottiemodel.h" -#include "rlottie.h" - -using namespace rlottie::internal; -// Naive way to implement std::variant -// refactor it when we move to c++17 -// users should make sure proper combination -// of id and value are passed while creating the object. -class LOTVariant { -public: - using ValueFunc = std::function; - using ColorFunc = std::function; - using PointFunc = std::function; - using SizeFunc = std::function; - - LOTVariant(rlottie::Property prop, const ValueFunc& v) - : mPropery(prop), mTag(Value) - { - construct(impl.valueFunc, v); - } - - LOTVariant(rlottie::Property prop, ValueFunc&& v) - : mPropery(prop), mTag(Value) - { - moveConstruct(impl.valueFunc, std::move(v)); - } - - LOTVariant(rlottie::Property prop, const ColorFunc& v) - : mPropery(prop), mTag(Color) - { - construct(impl.colorFunc, v); - } - - LOTVariant(rlottie::Property prop, ColorFunc&& v) - : mPropery(prop), mTag(Color) - { - moveConstruct(impl.colorFunc, std::move(v)); - } - - LOTVariant(rlottie::Property prop, const PointFunc& v) - : mPropery(prop), mTag(Point) - { - construct(impl.pointFunc, v); - } - - LOTVariant(rlottie::Property prop, PointFunc&& v) - : mPropery(prop), mTag(Point) - { - moveConstruct(impl.pointFunc, std::move(v)); - } - - LOTVariant(rlottie::Property prop, const SizeFunc& v) - : mPropery(prop), mTag(Size) - { - construct(impl.sizeFunc, v); - } - - LOTVariant(rlottie::Property prop, SizeFunc&& v) - : mPropery(prop), mTag(Size) - { - moveConstruct(impl.sizeFunc, std::move(v)); - } - - rlottie::Property property() const { return mPropery; } - - const ColorFunc& color() const - { - assert(mTag == Color); - return impl.colorFunc; - } - - const ValueFunc& value() const - { - assert(mTag == Value); - return impl.valueFunc; - } - - const PointFunc& point() const - { - assert(mTag == Point); - return impl.pointFunc; - } - - const SizeFunc& size() const - { - assert(mTag == Size); - return impl.sizeFunc; - } - - LOTVariant() = default; - ~LOTVariant() noexcept { Destroy(); } - LOTVariant(const LOTVariant& other) { Copy(other); } - LOTVariant(LOTVariant&& other) noexcept { Move(std::move(other)); } - LOTVariant& operator=(LOTVariant&& other) - { - Destroy(); - Move(std::move(other)); - return *this; - } - LOTVariant& operator=(const LOTVariant& other) - { - Destroy(); - Copy(other); - return *this; - } - -private: - template - void construct(T& member, const T& val) - { - new (&member) T(val); - } - - template - void moveConstruct(T& member, T&& val) - { - new (&member) T(std::move(val)); - } - - void Move(LOTVariant&& other) - { - switch (other.mTag) { - case Type::Value: - moveConstruct(impl.valueFunc, std::move(other.impl.valueFunc)); - break; - case Type::Color: - moveConstruct(impl.colorFunc, std::move(other.impl.colorFunc)); - break; - case Type::Point: - moveConstruct(impl.pointFunc, std::move(other.impl.pointFunc)); - break; - case Type::Size: - moveConstruct(impl.sizeFunc, std::move(other.impl.sizeFunc)); - break; - default: - break; - } - mTag = other.mTag; - mPropery = other.mPropery; - other.mTag = MonoState; - } - - void Copy(const LOTVariant& other) - { - switch (other.mTag) { - case Type::Value: - construct(impl.valueFunc, other.impl.valueFunc); - break; - case Type::Color: - construct(impl.colorFunc, other.impl.colorFunc); - break; - case Type::Point: - construct(impl.pointFunc, other.impl.pointFunc); - break; - case Type::Size: - construct(impl.sizeFunc, other.impl.sizeFunc); - break; - default: - break; - } - mTag = other.mTag; - mPropery = other.mPropery; - } - - void Destroy() - { - switch (mTag) { - case MonoState: { - break; - } - case Value: { - impl.valueFunc.~ValueFunc(); - break; - } - case Color: { - impl.colorFunc.~ColorFunc(); - break; - } - case Point: { - impl.pointFunc.~PointFunc(); - break; - } - case Size: { - impl.sizeFunc.~SizeFunc(); - break; - } - } - } - - enum Type { MonoState, Value, Color, Point, Size }; - rlottie::Property mPropery; - Type mTag{MonoState}; - union details { - ColorFunc colorFunc; - ValueFunc valueFunc; - PointFunc pointFunc; - SizeFunc sizeFunc; - details() {} - ~details() noexcept {} - } impl; -}; - -namespace rlottie { - -namespace internal { - -namespace model { - -class FilterData { -public: - void addValue(LOTVariant& value) - { - uint32_t index = static_cast(value.property()); - if (mBitset.test(index)) { - std::replace_if(mFilters.begin(), mFilters.end(), - [&value](const LOTVariant& e) { - return e.property() == value.property(); - }, - value); - } else { - mBitset.set(index); - mFilters.push_back(value); - } - } - - void removeValue(LOTVariant& value) - { - uint32_t index = static_cast(value.property()); - if (mBitset.test(index)) { - mBitset.reset(index); - mFilters.erase(std::remove_if(mFilters.begin(), mFilters.end(), - [&value](const LOTVariant& e) { - return e.property() == - value.property(); - }), - mFilters.end()); - } - } - bool hasFilter(rlottie::Property prop) const - { - return mBitset.test(static_cast(prop)); - } - model::Color color(rlottie::Property prop, int frame) const - { - rlottie::FrameInfo info(frame); - rlottie::Color col = data(prop).color()(info); - return model::Color(col.r(), col.g(), col.b()); - } - VPointF point(rlottie::Property prop, int frame) const - { - rlottie::FrameInfo info(frame); - rlottie::Point pt = data(prop).point()(info); - return VPointF(pt.x(), pt.y()); - } - VSize scale(rlottie::Property prop, int frame) const - { - rlottie::FrameInfo info(frame); - rlottie::Size sz = data(prop).size()(info); - return VSize(sz.w(), sz.h()); - } - float opacity(rlottie::Property prop, int frame) const - { - rlottie::FrameInfo info(frame); - float val = data(prop).value()(info); - return val / 100; - } - float value(rlottie::Property prop, int frame) const - { - rlottie::FrameInfo info(frame); - return data(prop).value()(info); - } - -private: - const LOTVariant& data(rlottie::Property prop) const - { - auto result = std::find_if( - mFilters.begin(), mFilters.end(), - [prop](const LOTVariant& e) { return e.property() == prop; }); - return *result; - } - std::bitset<32> mBitset{0}; - std::vector mFilters; -}; - -template -struct FilterBase -{ - FilterBase(T *model): model_(model){} - - const char* name() const { return model_->name(); } - - FilterData* filter() { - if (!filterData_) filterData_ = std::make_unique(); - return filterData_.get(); - } - - const FilterData * filter() const { return filterData_.get(); } - const T* model() const { return model_;} - - bool hasFilter(rlottie::Property prop) const { - return filterData_ ? filterData_->hasFilter(prop) - : false; - } - - T* model_{nullptr}; - std::unique_ptr filterData_{nullptr}; -}; - - -template -class Filter : public FilterBase { -public: - Filter(T* model): FilterBase(model){} - model::Color color(int frame) const - { - if (this->hasFilter(rlottie::Property::StrokeColor)) { - return this->filter()->color(rlottie::Property::StrokeColor, frame); - } - return this->model()->color(frame); - } - float opacity(int frame) const - { - if (this->hasFilter(rlottie::Property::StrokeOpacity)) { - return this->filter()->opacity(rlottie::Property::StrokeOpacity, frame); - } - return this->model()->opacity(frame); - } - - float strokeWidth(int frame) const - { - if (this->hasFilter(rlottie::Property::StrokeWidth)) { - return this->filter()->value(rlottie::Property::StrokeWidth, frame); - } - return this->model()->strokeWidth(frame); - } - - float miterLimit() const { return this->model()->miterLimit(); } - CapStyle capStyle() const { return this->model()->capStyle(); } - JoinStyle joinStyle() const { return this->model()->joinStyle(); } - bool hasDashInfo() const { return this->model()->hasDashInfo(); } - void getDashInfo(int frameNo, std::vector& result) const - { - return this->model()->getDashInfo(frameNo, result); - } -}; - - -template <> -class Filter: public FilterBase -{ -public: - Filter(model::Fill* model) : FilterBase(model) {} - - model::Color color(int frame) const - { - if (this->hasFilter(rlottie::Property::FillColor)) { - return this->filter()->color(rlottie::Property::FillColor, frame); - } - return this->model()->color(frame); - } - - float opacity(int frame) const - { - if (this->hasFilter(rlottie::Property::FillOpacity)) { - return this->filter()->opacity(rlottie::Property::FillOpacity, frame); - } - return this->model()->opacity(frame); - } - - FillRule fillRule() const { return this->model()->fillRule(); } -}; - -template <> -class Filter : public FilterBase -{ -public: - Filter(model::Group* model = nullptr) : FilterBase(model) {} - - bool hasModel() const { return this->model() ? true : false; } - - model::Transform* transform() const { return this->model() ? this->model()->mTransform : nullptr; } - VMatrix matrix(int frame) const - { - VMatrix mS, mR, mT; - if (this->hasFilter(rlottie::Property::TrScale)) { - VSize s = this->filter()->scale(rlottie::Property::TrScale, frame); - mS.scale(s.width() / 100.0, s.height() / 100.0); - } - if (this->hasFilter(rlottie::Property::TrRotation)) { - mR.rotate(this->filter()->value(rlottie::Property::TrRotation, frame)); - } - if (this->hasFilter(rlottie::Property::TrPosition)) { - mT.translate(this->filter()->point(rlottie::Property::TrPosition, frame)); - } - - return this->model()->mTransform->matrix(frame) * mS * mR * mT; - } -}; - -template <> -class Filter: public FilterBase -{ -public: - Filter(model::Trim* model) : FilterBase(model) {} - - model::Trim::Segment segment(int frameNo) const - { - if (this->hasFilter(rlottie::Property::TrimStart)) { - this->model_->updateTrimStartValue(this->filter()->value(rlottie::Property::TrimStart, frameNo)); - } - if (this->hasFilter(rlottie::Property::TrimEnd)) { - this->model_->updateTrimEndValue(this->filter()->point(rlottie::Property::TrimEnd, frameNo)); - } - model::Trim::Segment segment = this->model()->segment(frameNo); - return segment; - } -}; - - -} // namespace model - -} // namespace internal - -} // namespace rlottie - -#endif // LOTTIEFILTERMODEL_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieitem.cpp b/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieitem.cpp deleted file mode 100644 index c70f3273..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieitem.cpp +++ /dev/null @@ -1,1540 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "lottieitem.h" -#include -#include -#include -#include "lottiekeypath.h" -#include "vbitmap.h" -#include "vpainter.h" -#include "vraster.h" - -/* Lottie Layer Rules - * 1. time stretch is pre calculated and applied to all the properties of the - * lottilayer model and all its children - * 2. The frame property could be reversed using,time-reverse layer property in - * AE. which means (start frame > endFrame) 3. - */ - -static bool transformProp(rlottie::Property prop) -{ - switch (prop) { - case rlottie::Property::TrAnchor: - case rlottie::Property::TrScale: - case rlottie::Property::TrOpacity: - case rlottie::Property::TrPosition: - case rlottie::Property::TrRotation: - return true; - default: - return false; - } -} -static bool fillProp(rlottie::Property prop) -{ - switch (prop) { - case rlottie::Property::FillColor: - case rlottie::Property::FillOpacity: - return true; - default: - return false; - } -} - -static bool strokeProp(rlottie::Property prop) -{ - switch (prop) { - case rlottie::Property::StrokeColor: - case rlottie::Property::StrokeOpacity: - case rlottie::Property::StrokeWidth: - return true; - default: - return false; - } -} - -static bool trimProp(rlottie::Property prop) -{ - switch (prop) { - case rlottie::Property::TrimStart: - case rlottie::Property::TrimEnd: - return true; - default: - return false; - } -} - -static renderer::Layer *createLayerItem(model::Layer *layerData, - VArenaAlloc * allocator) -{ - switch (layerData->mLayerType) { - case model::Layer::Type::Precomp: { - return allocator->make(layerData, allocator); - } - case model::Layer::Type::Solid: { - return allocator->make(layerData); - } - case model::Layer::Type::Shape: { - return allocator->make(layerData, allocator); - } - case model::Layer::Type::Null: { - return allocator->make(layerData); - } - case model::Layer::Type::Image: { - return allocator->make(layerData); - } - default: - return nullptr; - break; - } -} - -renderer::Composition::Composition(std::shared_ptr model) - : mCurFrameNo(-1) -{ - mModel = std::move(model); - mRootLayer = createLayerItem(mModel->mRootLayer, &mAllocator); - mRootLayer->setComplexContent(false); - mViewSize = mModel->size(); -} - -void renderer::Composition::setValue(const std::string &keypath, - LOTVariant & value) -{ - mHasDynamicValue = true; - LOTKeyPath key(keypath); - mRootLayer->resolveKeyPath(key, 0, value); -} - -bool renderer::Composition::update(int frameNo, const VSize &size, - bool keepAspectRatio) -{ - // check if cached frame is same as requested frame. - if (!mHasDynamicValue && (mViewSize == size) && (mCurFrameNo == frameNo) && - (mKeepAspectRatio == keepAspectRatio)) - return false; - - mViewSize = size; - mCurFrameNo = frameNo; - mKeepAspectRatio = keepAspectRatio; - - /* - * if viewbox dosen't scale exactly to the viewport - * we scale the viewbox keeping AspectRatioPreserved and then align the - * viewbox to the viewport using AlignCenter rule. - */ - VMatrix m; - VSize viewPort = mViewSize; - VSize viewBox = mModel->size(); - float sx = float(viewPort.width()) / viewBox.width(); - float sy = float(viewPort.height()) / viewBox.height(); - if (mKeepAspectRatio) { - float scale = std::min(sx, sy); - float tx = (viewPort.width() - viewBox.width() * scale) * 0.5f; - float ty = (viewPort.height() - viewBox.height() * scale) * 0.5f; - m.translate(tx, ty).scale(scale, scale); - } else { - m.scale(sx, sy); - } - mRootLayer->update(frameNo, m, 1.0); - return true; -} - -bool renderer::Composition::render(const rlottie::Surface &surface) -{ - mSurface.reset(reinterpret_cast(surface.buffer()), - uint32_t(surface.width()), uint32_t(surface.height()), - uint32_t(surface.bytesPerLine()), - VBitmap::Format::ARGB32_Premultiplied); - - /* schedule all preprocess task for this frame at once. - */ - VRect clip(0, 0, int(surface.drawRegionWidth()), - int(surface.drawRegionHeight())); - mRootLayer->preprocess(clip); - - VPainter painter(&mSurface); - // set sub surface area for drawing. - painter.setDrawRegion( - VRect(int(surface.drawRegionPosX()), int(surface.drawRegionPosY()), - int(surface.drawRegionWidth()), int(surface.drawRegionHeight()))); - mRootLayer->render(&painter, {}, {}, mSurfaceCache); - painter.end(); - return true; -} - -void renderer::Mask::update(int frameNo, const VMatrix &parentMatrix, - float /*parentAlpha*/, const DirtyFlag &flag) -{ - bool dirtyPath = false; - - if (flag.testFlag(DirtyFlagBit::None) && mData->isStatic()) return; - - if (mData->mShape.isStatic()) { - if (mLocalPath.empty()) { - dirtyPath = true; - mData->mShape.value(frameNo, mLocalPath); - } - } else { - dirtyPath = true; - mData->mShape.value(frameNo, mLocalPath); - } - /* mask item dosen't inherit opacity */ - mCombinedAlpha = mData->opacity(frameNo); - - if ( flag.testFlag(DirtyFlagBit::Matrix) || dirtyPath ) { - mFinalPath.clone(mLocalPath); - mFinalPath.transform(parentMatrix); - mRasterRequest = true; - } -} - -VRle renderer::Mask::rle() -{ - if (!vCompare(mCombinedAlpha, 1.0f)) { - VRle obj = mRasterizer.rle(); - obj *= uint8_t(mCombinedAlpha * 255); - return obj; - } else { - return mRasterizer.rle(); - } -} - -void renderer::Mask::preprocess(const VRect &clip) -{ - if (mRasterRequest) - mRasterizer.rasterize(mFinalPath, FillRule::Winding, clip); -} - -void renderer::Layer::render(VPainter *painter, const VRle &inheritMask, - const VRle &matteRle, SurfaceCache &) -{ - auto renderlist = renderList(); - - if (renderlist.empty()) return; - - VRle mask; - if (mLayerMask) { - mask = mLayerMask->maskRle(painter->clipBoundingRect()); - if (!inheritMask.empty()) mask = mask & inheritMask; - // if resulting mask is empty then return. - if (mask.empty()) return; - } else { - mask = inheritMask; - } - - for (auto &i : renderlist) { - painter->setBrush(i->mBrush); - VRle rle = i->rle(); - if (matteRle.empty()) { - if (mask.empty()) { - // no mask no matte - painter->drawRle(VPoint(), rle); - } else { - // only mask - painter->drawRle(rle, mask); - } - - } else { - if (!mask.empty()) rle = rle & mask; - - if (rle.empty()) continue; - if (matteType() == model::MatteType::AlphaInv) { - rle = rle - matteRle; - painter->drawRle(VPoint(), rle); - } else { - // render with matteRle as clip. - painter->drawRle(rle, matteRle); - } - } - } -} - -void renderer::LayerMask::preprocess(const VRect &clip) -{ - for (auto &i : mMasks) { - i.preprocess(clip); - } -} - -renderer::LayerMask::LayerMask(model::Layer *layerData) -{ - if (!layerData->mExtra) return; - - mMasks.reserve(layerData->mExtra->mMasks.size()); - - for (auto &i : layerData->mExtra->mMasks) { - mMasks.emplace_back(i); - mStatic &= i->isStatic(); - } -} - -void renderer::LayerMask::update(int frameNo, const VMatrix &parentMatrix, - float parentAlpha, const DirtyFlag &flag) -{ - if (flag.testFlag(DirtyFlagBit::None) && isStatic()) return; - - for (auto &i : mMasks) { - i.update(frameNo, parentMatrix, parentAlpha, flag); - } - mDirty = true; -} - -VRle renderer::LayerMask::maskRle(const VRect &clipRect) -{ - if (!mDirty) return mRle; - - VRle rle; - for (auto &e : mMasks) { - const auto cur = [&]() { - if (e.inverted()) - return clipRect - e.rle(); - else - return e.rle(); - }(); - - switch (e.maskMode()) { - case model::Mask::Mode::Add: { - rle = rle + cur; - break; - } - case model::Mask::Mode::Substarct: { - if (rle.empty() && !clipRect.empty()) - rle = clipRect - cur; - else - rle = rle - cur; - break; - } - case model::Mask::Mode::Intersect: { - if (rle.empty() && !clipRect.empty()) - rle = clipRect & cur; - else - rle = rle & cur; - break; - } - case model::Mask::Mode::Difference: { - rle = rle ^ cur; - break; - } - default: - break; - } - } - - if (!rle.empty() && !rle.unique()) { - mRle.clone(rle); - } else { - mRle = rle; - } - mDirty = false; - return mRle; -} - -renderer::Layer::Layer(model::Layer *layerData) : mLayerData(layerData) -{ - if (mLayerData->mHasMask) - mLayerMask = std::make_unique(mLayerData); -} - -bool renderer::Layer::resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, - LOTVariant &value) -{ - if (!keyPath.matches(name(), depth)) { - return false; - } - - if (!keyPath.skip(name())) { - if (keyPath.fullyResolvesTo(name(), depth) && - transformProp(value.property())) { - //@TODO handle propery update. - } - } - return true; -} - -bool renderer::ShapeLayer::resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, - LOTVariant &value) -{ - if (renderer::Layer::resolveKeyPath(keyPath, depth, value)) { - if (keyPath.propagate(name(), depth)) { - uint32_t newDepth = keyPath.nextDepth(name(), depth); - mRoot->resolveKeyPath(keyPath, newDepth, value); - } - return true; - } - return false; -} - -bool renderer::CompLayer::resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, - LOTVariant &value) -{ - if (renderer::Layer::resolveKeyPath(keyPath, depth, value)) { - if (keyPath.propagate(name(), depth)) { - uint32_t newDepth = keyPath.nextDepth(name(), depth); - for (const auto &layer : mLayers) { - layer->resolveKeyPath(keyPath, newDepth, value); - } - } - return true; - } - return false; -} - -void renderer::Layer::update(int frameNumber, const VMatrix &parentMatrix, - float parentAlpha) -{ - mFrameNo = frameNumber; - // 1. check if the layer is part of the current frame - if (!visible()) return; - - float alpha = parentAlpha * opacity(frameNo()); - if (vIsZero(alpha)) { - mCombinedAlpha = 0; - return; - } - - // 2. calculate the parent matrix and alpha - VMatrix m = matrix(frameNo()); - m *= parentMatrix; - - // 3. update the dirty flag based on the change - if (mCombinedMatrix != m) { - mDirtyFlag |= DirtyFlagBit::Matrix; - mCombinedMatrix = m; - } - - if (!vCompare(mCombinedAlpha, alpha)) { - mDirtyFlag |= DirtyFlagBit::Alpha; - mCombinedAlpha = alpha; - } - - // 4. update the mask - if (mLayerMask) { - mLayerMask->update(frameNo(), mCombinedMatrix, mCombinedAlpha, - mDirtyFlag); - } - - // 5. if no parent property change and layer is static then nothing to do. - if (!mLayerData->precompLayer() && flag().testFlag(DirtyFlagBit::None) && - isStatic()) - return; - - // 6. update the content of the layer - updateContent(); - - // 7. reset the dirty flag - mDirtyFlag = DirtyFlagBit::None; -} - -VMatrix renderer::Layer::matrix(int frameNo) const -{ - return mParentLayer - ? (mLayerData->matrix(frameNo) * mParentLayer->matrix(frameNo)) - : mLayerData->matrix(frameNo); -} - -bool renderer::Layer::visible() const -{ - return (frameNo() >= mLayerData->inFrame() && - frameNo() <= mLayerData->outFrame()); -} - -void renderer::Layer::preprocess(const VRect &clip) -{ - // layer dosen't contribute to the frame - if (skipRendering()) return; - - // preprocess layer masks - if (mLayerMask) mLayerMask->preprocess(clip); - - preprocessStage(clip); -} - -renderer::CompLayer::CompLayer(model::Layer *layerModel, VArenaAlloc *allocator) - : renderer::Layer(layerModel) -{ - if (!mLayerData->mChildren.empty()) - mLayers.reserve(mLayerData->mChildren.size()); - - // 1. keep the layer in back-to-front order. - // as lottie model keeps the data in front-toback-order. - for (auto it = mLayerData->mChildren.crbegin(); - it != mLayerData->mChildren.rend(); ++it) { - if ((*it)->type() != model::Object::Type::Layer) continue; - auto model = static_cast(*it); - auto item = createLayerItem(model, allocator); - if (item) mLayers.push_back(item); - } - - // 2. update parent layer - for (const auto &layer : mLayers) { - int id = layer->parentId(); - if (id >= 0) { - auto search = - std::find_if(mLayers.begin(), mLayers.end(), - [id](const auto &val) { return val->id() == id; }); - if (search != mLayers.end()) layer->setParentLayer(*search); - } - } - - // 4. check if its a nested composition - if (!layerModel->layerSize().empty()) { - mClipper = std::make_unique(layerModel->layerSize()); - } - - if (mLayers.size() > 1) setComplexContent(true); -} - -void renderer::CompLayer::render(VPainter *painter, const VRle &inheritMask, - const VRle &matteRle, SurfaceCache &cache) -{ - if (vIsZero(combinedAlpha())) return; - - if (vCompare(combinedAlpha(), 1.0)) { - renderHelper(painter, inheritMask, matteRle, cache); - } else { - if (complexContent()) { - VSize size = painter->clipBoundingRect().size(); - VPainter srcPainter; - VBitmap srcBitmap = cache.make_surface(size.width(), size.height()); - srcPainter.begin(&srcBitmap); - renderHelper(&srcPainter, inheritMask, matteRle, cache); - srcPainter.end(); - painter->drawBitmap(VPoint(), srcBitmap, - uint8_t(combinedAlpha() * 255.0f)); - cache.release_surface(srcBitmap); - } else { - renderHelper(painter, inheritMask, matteRle, cache); - } - } -} - -void renderer::CompLayer::renderHelper(VPainter * painter, - const VRle & inheritMask, - const VRle & matteRle, - SurfaceCache &cache) -{ - VRle mask; - if (mLayerMask) { - mask = mLayerMask->maskRle(painter->clipBoundingRect()); - if (!inheritMask.empty()) mask = mask & inheritMask; - // if resulting mask is empty then return. - if (mask.empty()) return; - } else { - mask = inheritMask; - } - - if (mClipper) { - mask = mClipper->rle(mask); - if (mask.empty()) return; - } - - renderer::Layer *matte = nullptr; - for (const auto &layer : mLayers) { - if (layer->hasMatte()) { - matte = layer; - } else { - if (layer->visible()) { - if (matte) { - if (matte->visible()) - renderMatteLayer(painter, mask, matteRle, matte, layer, - cache); - } else { - layer->render(painter, mask, matteRle, cache); - } - } - matte = nullptr; - } - } -} - -void renderer::CompLayer::renderMatteLayer(VPainter *painter, const VRle &mask, - const VRle & matteRle, - renderer::Layer *layer, - renderer::Layer *src, - SurfaceCache & cache) -{ - VSize size = painter->clipBoundingRect().size(); - // Decide if we can use fast matte. - // 1. draw src layer to matte buffer - VPainter srcPainter; - VBitmap srcBitmap = cache.make_surface(size.width(), size.height()); - srcPainter.begin(&srcBitmap); - src->render(&srcPainter, mask, matteRle, cache); - srcPainter.end(); - - // 2. draw layer to layer buffer - VPainter layerPainter; - VBitmap layerBitmap = cache.make_surface(size.width(), size.height()); - layerPainter.begin(&layerBitmap); - layer->render(&layerPainter, mask, matteRle, cache); - - // 2.1update composition mode - switch (layer->matteType()) { - case model::MatteType::Alpha: - case model::MatteType::Luma: { - layerPainter.setBlendMode(BlendMode::DestIn); - break; - } - case model::MatteType::AlphaInv: - case model::MatteType::LumaInv: { - layerPainter.setBlendMode(BlendMode::DestOut); - break; - } - default: - break; - } - - // 2.2 update srcBuffer if the matte is luma type - if (layer->matteType() == model::MatteType::Luma || - layer->matteType() == model::MatteType::LumaInv) { - srcBitmap.updateLuma(); - } - - auto clip = layerPainter.clipBoundingRect(); - - // if the layer has only one renderer then use it as the clip rect - // when blending 2 buffer and copy back to final buffer to avoid - // unnecessary pixel processing. - if (layer->renderList().size() == 1) - { - clip = layer->renderList()[0]->rle().boundingRect(); - } - - // 2.3 draw src buffer as mask - layerPainter.drawBitmap(clip, srcBitmap, clip); - layerPainter.end(); - // 3. draw the result buffer into painter - painter->drawBitmap(clip, layerBitmap, clip); - - cache.release_surface(srcBitmap); - cache.release_surface(layerBitmap); -} - -void renderer::Clipper::update(const VMatrix &matrix) -{ - mPath.reset(); - mPath.addRect(VRectF(0, 0, mSize.width(), mSize.height())); - mPath.transform(matrix); - mRasterRequest = true; -} - -void renderer::Clipper::preprocess(const VRect &clip) -{ - if (mRasterRequest) mRasterizer.rasterize(mPath, FillRule::Winding, clip); - - mRasterRequest = false; -} - -VRle renderer::Clipper::rle(const VRle &mask) -{ - if (mask.empty()) return mRasterizer.rle(); - - mMaskedRle.clone(mask); - mMaskedRle &= mRasterizer.rle(); - return mMaskedRle; -} - -void renderer::CompLayer::updateContent() -{ - if (mClipper && flag().testFlag(DirtyFlagBit::Matrix)) { - mClipper->update(combinedMatrix()); - } - int mappedFrame = mLayerData->timeRemap(frameNo()); - float alpha = combinedAlpha(); - if (complexContent()) alpha = 1; - for (const auto &layer : mLayers) { - layer->update(mappedFrame, combinedMatrix(), alpha); - } -} - -void renderer::CompLayer::preprocessStage(const VRect &clip) -{ - // if layer has clipper - if (mClipper) mClipper->preprocess(clip); - - renderer::Layer *matte = nullptr; - for (const auto &layer : mLayers) { - if (layer->hasMatte()) { - matte = layer; - } else { - if (layer->visible()) { - if (matte) { - if (matte->visible()) { - layer->preprocess(clip); - matte->preprocess(clip); - } - } else { - layer->preprocess(clip); - } - } - matte = nullptr; - } - } -} - -renderer::SolidLayer::SolidLayer(model::Layer *layerData) - : renderer::Layer(layerData) -{ - mDrawableList = &mRenderNode; -} - -void renderer::SolidLayer::updateContent() -{ - if (flag() & DirtyFlagBit::Matrix) { - mPath.reset(); - mPath.addRect(VRectF(0, 0, mLayerData->layerSize().width(), - mLayerData->layerSize().height())); - mPath.transform(combinedMatrix()); - mRenderNode.mFlag |= VDrawable::DirtyState::Path; - mRenderNode.mPath = mPath; - } - if (flag() & DirtyFlagBit::Alpha) { - model::Color color = mLayerData->solidColor(); - VBrush brush(color.toColor(combinedAlpha())); - mRenderNode.setBrush(brush); - mRenderNode.mFlag |= VDrawable::DirtyState::Brush; - } -} - -void renderer::SolidLayer::preprocessStage(const VRect &clip) -{ - mRenderNode.preprocess(clip); -} - -renderer::DrawableList renderer::SolidLayer::renderList() -{ - if (skipRendering()) return {}; - - return {&mDrawableList, 1}; -} - -renderer::ImageLayer::ImageLayer(model::Layer *layerData) - : renderer::Layer(layerData) -{ - mDrawableList = &mRenderNode; - - if (!mLayerData->asset()) return; - - mTexture.mBitmap = mLayerData->asset()->bitmap(); - VBrush brush(&mTexture); - mRenderNode.setBrush(brush); -} - -void renderer::ImageLayer::updateContent() -{ - if (!mLayerData->asset()) return; - - if (flag() & DirtyFlagBit::Matrix) { - mPath.reset(); - mPath.addRect(VRectF(0, 0, mLayerData->asset()->mWidth, - mLayerData->asset()->mHeight)); - mPath.transform(combinedMatrix()); - mRenderNode.mFlag |= VDrawable::DirtyState::Path; - mRenderNode.mPath = mPath; - mTexture.mMatrix = combinedMatrix(); - } - - if (flag() & DirtyFlagBit::Alpha) { - mTexture.mAlpha = int(combinedAlpha() * 255); - } -} - -void renderer::ImageLayer::preprocessStage(const VRect &clip) -{ - mRenderNode.preprocess(clip); -} - -renderer::DrawableList renderer::ImageLayer::renderList() -{ - if (skipRendering()) return {}; - - return {&mDrawableList, 1}; -} - -renderer::NullLayer::NullLayer(model::Layer *layerData) - : renderer::Layer(layerData) -{ -} -void renderer::NullLayer::updateContent() {} - -static renderer::Object *createContentItem(model::Object *contentData, - VArenaAlloc * allocator) -{ - switch (contentData->type()) { - case model::Object::Type::Group: { - return allocator->make( - static_cast(contentData), allocator); - } - case model::Object::Type::Rect: { - return allocator->make( - static_cast(contentData)); - } - case model::Object::Type::Ellipse: { - return allocator->make( - static_cast(contentData)); - } - case model::Object::Type::Path: { - return allocator->make( - static_cast(contentData)); - } - case model::Object::Type::Polystar: { - return allocator->make( - static_cast(contentData)); - } - case model::Object::Type::Fill: { - return allocator->make( - static_cast(contentData)); - } - case model::Object::Type::GFill: { - return allocator->make( - static_cast(contentData)); - } - case model::Object::Type::Stroke: { - return allocator->make( - static_cast(contentData)); - } - case model::Object::Type::GStroke: { - return allocator->make( - static_cast(contentData)); - } - case model::Object::Type::Repeater: { - return allocator->make( - static_cast(contentData), allocator); - } - case model::Object::Type::Trim: { - return allocator->make( - static_cast(contentData)); - } - default: - return nullptr; - break; - } -} - -renderer::ShapeLayer::ShapeLayer(model::Layer *layerData, - VArenaAlloc * allocator) - : renderer::Layer(layerData), - mRoot(allocator->make(nullptr, allocator)) -{ - mRoot->addChildren(layerData, allocator); - - std::vector list; - mRoot->processPaintItems(list); - - if (layerData->hasPathOperator()) { - list.clear(); - mRoot->processTrimItems(list); - } -} - -void renderer::ShapeLayer::updateContent() -{ - mRoot->update(frameNo(), combinedMatrix(), 1.0f , flag()); - - if (mLayerData->hasPathOperator()) { - mRoot->applyTrim(); - } -} - -void renderer::ShapeLayer::preprocessStage(const VRect &clip) -{ - mDrawableList.clear(); - mRoot->renderList(mDrawableList); - - for (auto &drawable : mDrawableList) drawable->preprocess(clip); -} - -renderer::DrawableList renderer::ShapeLayer::renderList() -{ - if (skipRendering()) return {}; - - mDrawableList.clear(); - mRoot->renderList(mDrawableList); - - if (mDrawableList.empty()) return {}; - - return {mDrawableList.data(), mDrawableList.size()}; -} - -void renderer::ShapeLayer::render(VPainter *painter, const VRle &inheritMask, - const VRle &matteRle, SurfaceCache &cache) -{ - if (vIsZero(combinedAlpha())) return; - - if (vCompare(combinedAlpha(), 1.0)) { - Layer::render(painter, inheritMask, matteRle, cache); - } else { - //do offscreen rendering - VSize size = painter->clipBoundingRect().size(); - VPainter srcPainter; - VBitmap srcBitmap = cache.make_surface(size.width(), size.height()); - srcPainter.begin(&srcBitmap); - Layer::render(&srcPainter, inheritMask, matteRle, cache); - srcPainter.end(); - painter->drawBitmap(VPoint(), srcBitmap, - uint8_t(combinedAlpha() * 255.0f)); - cache.release_surface(srcBitmap); - } -} - -bool renderer::Group::resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, - LOTVariant &value) -{ - if (!keyPath.skip(name())) { - if (!keyPath.matches(mModel.name(), depth)) { - return false; - } - - if (!keyPath.skip(mModel.name())) { - if (keyPath.fullyResolvesTo(mModel.name(), depth) && - transformProp(value.property())) { - mModel.filter()->addValue(value); - } - } - } - - if (keyPath.propagate(name(), depth)) { - uint32_t newDepth = keyPath.nextDepth(name(), depth); - for (auto &child : mContents) { - child->resolveKeyPath(keyPath, newDepth, value); - } - } - return true; -} - -bool renderer::Fill::resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, - LOTVariant &value) -{ - if (!keyPath.matches(mModel.name(), depth)) { - return false; - } - - if (keyPath.fullyResolvesTo(mModel.name(), depth) && - fillProp(value.property())) { - mModel.filter()->addValue(value); - return true; - } - return false; -} - -bool renderer::Stroke::resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, - LOTVariant &value) -{ - if (!keyPath.matches(mModel.name(), depth)) { - return false; - } - - if (keyPath.fullyResolvesTo(mModel.name(), depth) && - strokeProp(value.property())) { - mModel.filter()->addValue(value); - return true; - } - return false; -} - -renderer::Group::Group(model::Group *data, VArenaAlloc *allocator) - : mModel(data) -{ - addChildren(data, allocator); -} - -void renderer::Group::addChildren(model::Group *data, VArenaAlloc *allocator) -{ - if (!data) return; - - if (!data->mChildren.empty()) mContents.reserve(data->mChildren.size()); - - // keep the content in back-to-front order. - // as lottie model keeps it in front-to-back order. - for (auto it = data->mChildren.crbegin(); it != data->mChildren.rend(); - ++it) { - auto content = createContentItem(*it, allocator); - if (content) { - mContents.push_back(content); - } - } -} - -void renderer::Group::update(int frameNo, const VMatrix &parentMatrix, - float parentAlpha, const DirtyFlag &flag) -{ - DirtyFlag newFlag = flag; - float alpha; - - if (mModel.hasModel() && mModel.transform()) { - VMatrix m = mModel.matrix(frameNo); - - m *= parentMatrix; - if (!(flag & DirtyFlagBit::Matrix) && !mModel.transform()->isStatic() && - (m != mMatrix)) { - newFlag |= DirtyFlagBit::Matrix; - } - - mMatrix = m; - - alpha = parentAlpha * mModel.transform()->opacity(frameNo); - if (!vCompare(alpha, parentAlpha)) { - newFlag |= DirtyFlagBit::Alpha; - } - } else { - mMatrix = parentMatrix; - alpha = parentAlpha; - } - - for (const auto &content : mContents) { - content->update(frameNo, matrix(), alpha, newFlag); - } -} - -void renderer::Group::applyTrim() -{ - for (auto i = mContents.rbegin(); i != mContents.rend(); ++i) { - auto content = (*i); - switch (content->type()) { - case renderer::Object::Type::Trim: { - static_cast(content)->update(); - break; - } - case renderer::Object::Type::Group: { - static_cast(content)->applyTrim(); - break; - } - default: - break; - } - } -} - -void renderer::Group::renderList(std::vector &list) -{ - for (const auto &content : mContents) { - content->renderList(list); - } -} - -void renderer::Group::processPaintItems(std::vector &list) -{ - size_t curOpCount = list.size(); - for (auto i = mContents.rbegin(); i != mContents.rend(); ++i) { - auto content = (*i); - switch (content->type()) { - case renderer::Object::Type::Shape: { - auto pathItem = static_cast(content); - pathItem->setParent(this); - list.push_back(pathItem); - break; - } - case renderer::Object::Type::Paint: { - static_cast(content)->addPathItems(list, - curOpCount); - break; - } - case renderer::Object::Type::Group: { - static_cast(content)->processPaintItems(list); - break; - } - default: - break; - } - } -} - -void renderer::Group::processTrimItems(std::vector &list) -{ - size_t curOpCount = list.size(); - for (auto i = mContents.rbegin(); i != mContents.rend(); ++i) { - auto content = (*i); - - switch (content->type()) { - case renderer::Object::Type::Shape: { - list.push_back(static_cast(content)); - break; - } - case renderer::Object::Type::Trim: { - static_cast(content)->addPathItems(list, - curOpCount); - break; - } - case renderer::Object::Type::Group: { - static_cast(content)->processTrimItems(list); - break; - } - default: - break; - } - } -} - -/* - * renderer::Shape uses 2 path objects for path object reuse. - * mLocalPath - keeps track of the local path of the item before - * applying path operation and transformation. - * mTemp - keeps a referece to the mLocalPath and can be updated by the - * path operation objects(trim, merge path), - * We update the DirtyPath flag if the path needs to be updated again - * beacuse of local path or matrix or some path operation has changed which - * affects the final path. - * The PaintObject queries the dirty flag to check if it needs to compute the - * final path again and calls finalPath() api to do the same. - * finalPath() api passes a result Object so that we keep only one copy of - * the path object in the paintItem (for memory efficiency). - * NOTE: As path objects are COW objects we have to be - * carefull about the refcount so that we don't generate deep copy while - * modifying the path objects. - */ -void renderer::Shape::update(int frameNo, const VMatrix &, float, - const DirtyFlag &flag) -{ - mDirtyPath = false; - - // 1. update the local path if needed - if (hasChanged(frameNo)) { - // loose the reference to mLocalPath if any - // from the last frame update. - mTemp = VPath(); - - updatePath(mLocalPath, frameNo); - mDirtyPath = true; - } - // 2. keep a reference path in temp in case there is some - // path operation like trim which will update the path. - // we don't want to update the local path. - mTemp = mLocalPath; - - // 3. mark the path dirty if matrix has changed. - if (flag & DirtyFlagBit::Matrix) { - mDirtyPath = true; - } -} - -void renderer::Shape::finalPath(VPath &result) -{ - result.addPath(mTemp, static_cast(parent())->matrix()); -} - -renderer::Rect::Rect(model::Rect *data) - : renderer::Shape(data->isStatic()), mData(data) -{ -} - -void renderer::Rect::updatePath(VPath &path, int frameNo) -{ - VPointF pos = mData->mPos.value(frameNo); - VPointF size = mData->mSize.value(frameNo); - float roundness = mData->roundness(frameNo); - VRectF r(pos.x() - size.x() / 2, pos.y() - size.y() / 2, size.x(), - size.y()); - - path.reset(); - path.addRoundRect(r, roundness, mData->direction()); -} - -renderer::Ellipse::Ellipse(model::Ellipse *data) - : renderer::Shape(data->isStatic()), mData(data) -{ -} - -void renderer::Ellipse::updatePath(VPath &path, int frameNo) -{ - VPointF pos = mData->mPos.value(frameNo); - VPointF size = mData->mSize.value(frameNo); - VRectF r(pos.x() - size.x() / 2, pos.y() - size.y() / 2, size.x(), - size.y()); - - path.reset(); - path.addOval(r, mData->direction()); -} - -renderer::Path::Path(model::Path *data) - : renderer::Shape(data->isStatic()), mData(data) -{ -} - -void renderer::Path::updatePath(VPath &path, int frameNo) -{ - mData->mShape.value(frameNo, path); -} - -renderer::Polystar::Polystar(model::Polystar *data) - : renderer::Shape(data->isStatic()), mData(data) -{ -} - -void renderer::Polystar::updatePath(VPath &path, int frameNo) -{ - VPointF pos = mData->mPos.value(frameNo); - float points = mData->mPointCount.value(frameNo); - float innerRadius = mData->mInnerRadius.value(frameNo); - float outerRadius = mData->mOuterRadius.value(frameNo); - float innerRoundness = mData->mInnerRoundness.value(frameNo); - float outerRoundness = mData->mOuterRoundness.value(frameNo); - float rotation = mData->mRotation.value(frameNo); - - path.reset(); - VMatrix m; - - if (mData->mPolyType == model::Polystar::PolyType::Star) { - path.addPolystar(points, innerRadius, outerRadius, innerRoundness, - outerRoundness, 0.0, 0.0, 0.0, mData->direction()); - } else { - path.addPolygon(points, outerRadius, outerRoundness, 0.0, 0.0, 0.0, - mData->direction()); - } - - m.translate(pos.x(), pos.y()).rotate(rotation); - m.rotate(rotation); - path.transform(m); -} - -/* - * PaintData Node handling - * - */ -renderer::Paint::Paint(bool staticContent) : mStaticContent(staticContent) {} - -void renderer::Paint::update(int frameNo, const VMatrix &parentMatrix, - float parentAlpha, const DirtyFlag & /*flag*/) -{ - mRenderNodeUpdate = true; - mContentToRender = updateContent(frameNo, parentMatrix, parentAlpha); -} - -void renderer::Paint::updateRenderNode() -{ - bool dirty = false; - for (auto &i : mPathItems) { - if (i->dirty()) { - dirty = true; - break; - } - } - - if (dirty) { - mPath.reset(); - for (const auto &i : mPathItems) { - i->finalPath(mPath); - } - mDrawable.setPath(mPath); - } else { - if (mDrawable.mFlag & VDrawable::DirtyState::Path) - mDrawable.mPath = mPath; - } -} - -void renderer::Paint::renderList(std::vector &list) -{ - if (mRenderNodeUpdate) { - updateRenderNode(); - mRenderNodeUpdate = false; - } - - // Q: Why we even update the final path if we don't have content - // to render ? - // Ans: We update the render nodes because we will loose the - // dirty path information at end of this frame. - // so if we return early without updating the final path. - // in the subsequent frame when we have content to render but - // we may not able to update our final path properly as we - // don't know what paths got changed in between. - if (mContentToRender) list.push_back(&mDrawable); -} - -void renderer::Paint::addPathItems(std::vector &list, - size_t startOffset) -{ - std::copy(list.begin() + startOffset, list.end(), - back_inserter(mPathItems)); -} - -renderer::Fill::Fill(model::Fill *data) - : renderer::Paint(data->isStatic()), mModel(data) -{ - mDrawable.setName(mModel.name()); -} - -bool renderer::Fill::updateContent(int frameNo, const VMatrix &, float alpha) -{ - auto combinedAlpha = alpha * mModel.opacity(frameNo); - auto color = mModel.color(frameNo).toColor(combinedAlpha); - - VBrush brush(color); - mDrawable.setBrush(brush); - mDrawable.setFillRule(mModel.fillRule()); - - return !color.isTransparent(); -} - -renderer::GradientFill::GradientFill(model::GradientFill *data) - : renderer::Paint(data->isStatic()), mData(data) -{ - mDrawable.setName(mData->name()); -} - -bool renderer::GradientFill::updateContent(int frameNo, const VMatrix &matrix, - float alpha) -{ - float combinedAlpha = alpha * mData->opacity(frameNo); - - mData->update(mGradient, frameNo); - mGradient->setAlpha(combinedAlpha); - mGradient->mMatrix = matrix; - mDrawable.setBrush(VBrush(mGradient.get())); - mDrawable.setFillRule(mData->fillRule()); - - return !vIsZero(combinedAlpha); -} - -renderer::Stroke::Stroke(model::Stroke *data) - : renderer::Paint(data->isStatic()), mModel(data) -{ - mDrawable.setName(mModel.name()); - if (mModel.hasDashInfo()) { - mDrawable.setType(VDrawable::Type::StrokeWithDash); - } else { - mDrawable.setType(VDrawable::Type::Stroke); - } -} - -static vthread_local std::vector Dash_Vector; - -bool renderer::Stroke::updateContent(int frameNo, const VMatrix &matrix, - float alpha) -{ - auto combinedAlpha = alpha * mModel.opacity(frameNo); - auto color = mModel.color(frameNo).toColor(combinedAlpha); - - VBrush brush(color); - mDrawable.setBrush(brush); - float scale = matrix.scale(); - mDrawable.setStrokeInfo(mModel.capStyle(), mModel.joinStyle(), - mModel.miterLimit(), - mModel.strokeWidth(frameNo) * scale); - - if (mModel.hasDashInfo()) { - Dash_Vector.clear(); - mModel.getDashInfo(frameNo, Dash_Vector); - if (!Dash_Vector.empty()) { - for (auto &elm : Dash_Vector) elm *= scale; - mDrawable.setDashInfo(Dash_Vector); - } - } - - return !color.isTransparent(); -} - -renderer::GradientStroke::GradientStroke(model::GradientStroke *data) - : renderer::Paint(data->isStatic()), mData(data) -{ - mDrawable.setName(mData->name()); - if (mData->hasDashInfo()) { - mDrawable.setType(VDrawable::Type::StrokeWithDash); - } else { - mDrawable.setType(VDrawable::Type::Stroke); - } -} - -bool renderer::GradientStroke::updateContent(int frameNo, const VMatrix &matrix, - float alpha) -{ - float combinedAlpha = alpha * mData->opacity(frameNo); - - mData->update(mGradient, frameNo); - mGradient->setAlpha(combinedAlpha); - mGradient->mMatrix = matrix; - auto scale = mGradient->mMatrix.scale(); - mDrawable.setBrush(VBrush(mGradient.get())); - mDrawable.setStrokeInfo(mData->capStyle(), mData->joinStyle(), - mData->miterLimit(), mData->width(frameNo) * scale); - - if (mData->hasDashInfo()) { - Dash_Vector.clear(); - mData->getDashInfo(frameNo, Dash_Vector); - if (!Dash_Vector.empty()) { - for (auto &elm : Dash_Vector) elm *= scale; - mDrawable.setDashInfo(Dash_Vector); - } - } - - return !vIsZero(combinedAlpha); -} - -bool renderer::Trim::resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, - LOTVariant &value) -{ - if (!keyPath.matches(mModel.name(), depth)) { - return false; - } - - if (keyPath.fullyResolvesTo(mModel.name(), depth) && - trimProp(value.property())) { - mModel.filter()->addValue(value); - return true; - } - return false; -} - -void renderer::Trim::update(int frameNo, const VMatrix & /*parentMatrix*/, - float /*parentAlpha*/, const DirtyFlag & /*flag*/) -{ - mDirty = false; - - if (mCache.mFrameNo == frameNo) return; - - model::Trim::Segment segment = mModel.segment(frameNo); - - if (!(vCompare(mCache.mSegment.start, segment.start) && - vCompare(mCache.mSegment.end, segment.end))) { - mDirty = true; - mCache.mSegment = segment; - } - mCache.mFrameNo = frameNo; -} - -void renderer::Trim::update() -{ - // when both path and trim are not dirty - if (!(mDirty || pathDirty())) return; - - if (vCompare(mCache.mSegment.start, mCache.mSegment.end)) { - for (auto &i : mPathItems) { - i->updatePath(VPath()); - } - return; - } - - if (vCompare(std::fabs(mCache.mSegment.start - mCache.mSegment.end), 1)) { - for (auto &i : mPathItems) { - i->updatePath(i->localPath()); - } - return; - } - - if (mData->type() == model::Trim::TrimType::Simultaneously) { - for (auto &i : mPathItems) { - mPathMesure.setRange(mCache.mSegment.start, mCache.mSegment.end); - i->updatePath(mPathMesure.trim(i->localPath())); - } - } else { // model::Trim::TrimType::Individually - float totalLength = 0.0; - for (auto &i : mPathItems) { - totalLength += i->localPath().length(); - } - float start = totalLength * mCache.mSegment.start; - float end = totalLength * mCache.mSegment.end; - - if (start < end) { - float curLen = 0.0; - for (auto &i : mPathItems) { - if (curLen > end) { - // update with empty path. - i->updatePath(VPath()); - continue; - } - float len = i->localPath().length(); - - if (curLen < start && curLen + len < start) { - curLen += len; - // update with empty path. - i->updatePath(VPath()); - continue; - } else if (start <= curLen && end >= curLen + len) { - // inside segment - curLen += len; - continue; - } else { - float local_start = start > curLen ? start - curLen : 0; - local_start /= len; - float local_end = curLen + len < end ? len : end - curLen; - local_end /= len; - mPathMesure.setRange(local_start, local_end); - i->updatePath(mPathMesure.trim(i->localPath())); - curLen += len; - } - } - } - } -} - -void renderer::Trim::addPathItems(std::vector &list, - size_t startOffset) -{ - std::copy(list.begin() + startOffset, list.end(), - back_inserter(mPathItems)); -} - -renderer::Repeater::Repeater(model::Repeater *data, VArenaAlloc *allocator) - : mRepeaterData(data) -{ - assert(mRepeaterData->content()); - - mCopies = mRepeaterData->maxCopies(); - - for (int i = 0; i < mCopies; i++) { - auto content = allocator->make( - mRepeaterData->content(), allocator); - // content->setParent(this); - mContents.push_back(content); - } -} - -void renderer::Repeater::update(int frameNo, const VMatrix &parentMatrix, - float parentAlpha, const DirtyFlag &flag) -{ - DirtyFlag newFlag = flag; - - float copies = mRepeaterData->copies(frameNo); - int visibleCopies = int(copies); - - if (visibleCopies == 0) { - mHidden = true; - return; - } - - mHidden = false; - - if (!mRepeaterData->isStatic()) newFlag |= DirtyFlagBit::Matrix; - - float offset = mRepeaterData->offset(frameNo); - float startOpacity = mRepeaterData->mTransform.startOpacity(frameNo); - float endOpacity = mRepeaterData->mTransform.endOpacity(frameNo); - - newFlag |= DirtyFlagBit::Alpha; - - for (int i = 0; i < mCopies; ++i) { - float newAlpha = - parentAlpha * lerp(startOpacity, endOpacity, i / copies); - - // hide rest of the copies , @TODO find a better solution. - if (i >= visibleCopies) newAlpha = 0; - - VMatrix result = mRepeaterData->mTransform.matrix(frameNo, i + offset) * - parentMatrix; - mContents[i]->update(frameNo, result, newAlpha, newFlag); - } -} - -void renderer::Repeater::renderList(std::vector &list) -{ - if (mHidden) return; - return renderer::Group::renderList(list); -} diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieitem.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieitem.h deleted file mode 100644 index 1a50ec89..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieitem.h +++ /dev/null @@ -1,634 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef LOTTIEITEM_H -#define LOTTIEITEM_H - -#include -#include - -#include "lottiekeypath.h" -#include "lottiefiltermodel.h" -#include "rlottie.h" -#include "rlottiecommon.h" -#include "varenaalloc.h" -#include "vdrawable.h" -#include "vmatrix.h" -#include "vpainter.h" -#include "vpath.h" -#include "vpathmesure.h" -#include "vpoint.h" - -V_USE_NAMESPACE - -namespace rlottie { - -namespace internal { - -template -class VSpan { -public: - using reference = T &; - using pointer = T *; - using const_pointer = T const *; - using const_reference = T const &; - using index_type = size_t; - - using iterator = pointer; - using const_iterator = const_pointer; - - VSpan() = default; - VSpan(pointer data, index_type size) : _data(data), _size(size) {} - - constexpr pointer data() const noexcept { return _data; } - constexpr index_type size() const noexcept { return _size; } - constexpr bool empty() const noexcept { return size() == 0; } - constexpr iterator begin() const noexcept { return data(); } - constexpr iterator end() const noexcept { return data() + size(); } - constexpr const_iterator cbegin() const noexcept { return data(); } - constexpr const_iterator cend() const noexcept { return data() + size(); } - constexpr reference operator[](index_type idx) const - { - return *(data() + idx); - } - -private: - pointer _data{nullptr}; - index_type _size{0}; -}; - -namespace renderer { - -using DrawableList = VSpan; - -enum class DirtyFlagBit : uint8_t { - None = 0x00, - Matrix = 0x01, - Alpha = 0x02, - All = (Matrix | Alpha) -}; -typedef vFlag DirtyFlag; - -class SurfaceCache { -public: - SurfaceCache() { mCache.reserve(10); } - - VBitmap make_surface( - size_t width, size_t height, - VBitmap::Format format = VBitmap::Format::ARGB32_Premultiplied) - { - if (mCache.empty()) return {width, height, format}; - - auto surface = mCache.back(); - surface.reset(width, height, format); - - mCache.pop_back(); - return surface; - } - - void release_surface(VBitmap &surface) { mCache.push_back(surface); } - -private: - std::vector mCache; -}; - -class Drawable final : public VDrawable { -public: - void sync(); - -public: - std::unique_ptr mCNode{nullptr}; - - ~Drawable() noexcept - { - if (mCNode && mCNode->mGradient.stopPtr) - free(mCNode->mGradient.stopPtr); - } -}; - -struct CApiData { - CApiData(); - LOTLayerNode mLayer; - std::vector mMasks; - std::vector mLayers; - std::vector mCNodeList; -}; - -class Clipper { -public: - explicit Clipper(VSize size) : mSize(size) {} - void update(const VMatrix &matrix); - void preprocess(const VRect &clip); - VRle rle(const VRle &mask); - -public: - VSize mSize; - VPath mPath; - VRle mMaskedRle; - VRasterizer mRasterizer; - bool mRasterRequest{false}; -}; - -class Mask { -public: - explicit Mask(model::Mask *data) : mData(data) {} - void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, - const DirtyFlag &flag); - model::Mask::Mode maskMode() const { return mData->mMode; } - VRle rle(); - void preprocess(const VRect &clip); - bool inverted() const { return mData->mInv; } -public: - model::Mask *mData{nullptr}; - VPath mLocalPath; - VPath mFinalPath; - VRasterizer mRasterizer; - float mCombinedAlpha{0}; - bool mRasterRequest{false}; -}; - -/* - * Handels mask property of a layer item - */ -class LayerMask { -public: - explicit LayerMask(model::Layer *layerData); - void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, - const DirtyFlag &flag); - bool isStatic() const { return mStatic; } - VRle maskRle(const VRect &clipRect); - void preprocess(const VRect &clip); - -public: - std::vector mMasks; - VRle mRle; - bool mStatic{true}; - bool mDirty{true}; -}; - -class Layer; - -class Composition { -public: - explicit Composition(std::shared_ptr composition); - bool update(int frameNo, const VSize &size, bool keepAspectRatio); - VSize size() const { return mViewSize; } - void buildRenderTree(); - const LOTLayerNode *renderTree() const; - bool render(const rlottie::Surface &surface); - void setValue(const std::string &keypath, LOTVariant &value); - -private: - SurfaceCache mSurfaceCache; - VBitmap mSurface; - VMatrix mScaleMatrix; - VSize mViewSize; - std::shared_ptr mModel; - Layer * mRootLayer{nullptr}; - VArenaAlloc mAllocator{2048}; - int mCurFrameNo; - bool mKeepAspectRatio{true}; - bool mHasDynamicValue{false}; -}; - -class Layer { -public: - virtual ~Layer() = default; - Layer &operator=(Layer &&) noexcept = delete; - Layer(model::Layer *layerData); - int id() const { return mLayerData->id(); } - int parentId() const { return mLayerData->parentId(); } - void setParentLayer(Layer *parent) { mParentLayer = parent; } - void setComplexContent(bool value) { mComplexContent = value; } - bool complexContent() const { return mComplexContent; } - virtual void update(int frameNo, const VMatrix &parentMatrix, - float parentAlpha); - VMatrix matrix(int frameNo) const; - void preprocess(const VRect &clip); - virtual DrawableList renderList() { return {}; } - virtual void render(VPainter *painter, const VRle &mask, - const VRle &matteRle, SurfaceCache &cache); - bool hasMatte() - { - if (mLayerData->mMatteType == model::MatteType::None) return false; - return true; - } - model::MatteType matteType() const { return mLayerData->mMatteType; } - bool visible() const; - virtual void buildLayerNode(); - LOTLayerNode & clayer() { return mCApiData->mLayer; } - std::vector &clayers() { return mCApiData->mLayers; } - std::vector & cmasks() { return mCApiData->mMasks; } - std::vector & cnodes() { return mCApiData->mCNodeList; } - const char * name() const { return mLayerData->name(); } - virtual bool resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, - LOTVariant &value); - -protected: - virtual void preprocessStage(const VRect &clip) = 0; - virtual void updateContent() = 0; - inline VMatrix combinedMatrix() const { return mCombinedMatrix; } - inline int frameNo() const { return mFrameNo; } - inline float combinedAlpha() const { return mCombinedAlpha; } - inline bool isStatic() const { return mLayerData->isStatic(); } - float opacity(int frameNo) const { return mLayerData->opacity(frameNo); } - inline DirtyFlag flag() const { return mDirtyFlag; } - bool skipRendering() const - { - return (!visible() || vIsZero(combinedAlpha())); - } - -protected: - std::unique_ptr mLayerMask; - model::Layer * mLayerData{nullptr}; - Layer * mParentLayer{nullptr}; - VMatrix mCombinedMatrix; - float mCombinedAlpha{0.0}; - int mFrameNo{-1}; - DirtyFlag mDirtyFlag{DirtyFlagBit::All}; - bool mComplexContent{false}; - std::unique_ptr mCApiData; -}; - -class CompLayer final : public Layer { -public: - explicit CompLayer(model::Layer *layerData, VArenaAlloc *allocator); - - void render(VPainter *painter, const VRle &mask, const VRle &matteRle, - SurfaceCache &cache) final; - void buildLayerNode() final; - bool resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, - LOTVariant &value) override; - -protected: - void preprocessStage(const VRect &clip) final; - void updateContent() final; - -private: - void renderHelper(VPainter *painter, const VRle &mask, const VRle &matteRle, - SurfaceCache &cache); - void renderMatteLayer(VPainter *painter, const VRle &inheritMask, - const VRle &matteRle, Layer *layer, Layer *src, - SurfaceCache &cache); - -private: - std::vector mLayers; - std::unique_ptr mClipper; -}; - -class SolidLayer final : public Layer { -public: - explicit SolidLayer(model::Layer *layerData); - void buildLayerNode() final; - DrawableList renderList() final; - -protected: - void preprocessStage(const VRect &clip) final; - void updateContent() final; - -private: - Drawable mRenderNode; - VPath mPath; - VDrawable *mDrawableList{nullptr}; // to work with the Span api -}; - -class Group; - -class ShapeLayer final : public Layer { -public: - explicit ShapeLayer(model::Layer *layerData, VArenaAlloc *allocator); - DrawableList renderList() final; - void buildLayerNode() final; - bool resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, - LOTVariant &value) override; - void render(VPainter *painter, const VRle &mask, const VRle &matteRle, - SurfaceCache &cache) final; - -protected: - void preprocessStage(const VRect &clip) final; - void updateContent() final; - std::vector mDrawableList; - Group * mRoot{nullptr}; -}; - -class NullLayer final : public Layer { -public: - explicit NullLayer(model::Layer *layerData); - -protected: - void preprocessStage(const VRect &) final {} - void updateContent() final; -}; - -class ImageLayer final : public Layer { -public: - explicit ImageLayer(model::Layer *layerData); - void buildLayerNode() final; - DrawableList renderList() final; - -protected: - void preprocessStage(const VRect &clip) final; - void updateContent() final; - -private: - Drawable mRenderNode; - VTexture mTexture; - VPath mPath; - VDrawable *mDrawableList{nullptr}; // to work with the Span api -}; - -class Object { -public: - enum class Type : uint8_t { Unknown, Group, Shape, Paint, Trim }; - virtual ~Object() = default; - Object & operator=(Object &&) noexcept = delete; - virtual void update(int frameNo, const VMatrix &parentMatrix, - float parentAlpha, const DirtyFlag &flag) = 0; - virtual void renderList(std::vector &) {} - virtual bool resolveKeyPath(LOTKeyPath &, uint32_t, LOTVariant &) - { - return false; - } - virtual Object::Type type() const { return Object::Type::Unknown; } -}; - -class Shape; -class Group : public Object { -public: - Group() = default; - explicit Group(model::Group *data, VArenaAlloc *allocator); - void addChildren(model::Group *data, VArenaAlloc *allocator); - void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, - const DirtyFlag &flag) override; - void applyTrim(); - void processTrimItems(std::vector &list); - void processPaintItems(std::vector &list); - void renderList(std::vector &list) override; - Object::Type type() const final { return Object::Type::Group; } - const VMatrix &matrix() const { return mMatrix; } - const char * name() const - { - static const char *TAG = "__"; - return mModel.hasModel() ? mModel.name() : TAG; - } - bool resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, - LOTVariant &value) override; - -protected: - std::vector mContents; - VMatrix mMatrix; - -private: - model::Filter mModel; -}; - -class Shape : public Object { -public: - Shape(bool staticPath) : mStaticPath(staticPath) {} - void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, - const DirtyFlag &flag) final; - Object::Type type() const final { return Object::Type::Shape; } - bool dirty() const { return mDirtyPath; } - const VPath &localPath() const { return mTemp; } - void finalPath(VPath &result); - void updatePath(const VPath &path) - { - mTemp = path; - mDirtyPath = true; - } - bool staticPath() const { return mStaticPath; } - void setParent(Group *parent) { mParent = parent; } - Group *parent() const { return mParent; } - -protected: - virtual void updatePath(VPath &path, int frameNo) = 0; - virtual bool hasChanged(int prevFrame, int curFrame) = 0; - -private: - bool hasChanged(int frameNo) - { - int prevFrame = mFrameNo; - mFrameNo = frameNo; - if (prevFrame == -1) return true; - if (mStaticPath || (prevFrame == frameNo)) return false; - return hasChanged(prevFrame, frameNo); - } - Group *mParent{nullptr}; - VPath mLocalPath; - VPath mTemp; - int mFrameNo{-1}; - bool mDirtyPath{true}; - bool mStaticPath; -}; - -class Rect final : public Shape { -public: - explicit Rect(model::Rect *data); - -protected: - void updatePath(VPath &path, int frameNo) final; - model::Rect *mData{nullptr}; - - bool hasChanged(int prevFrame, int curFrame) final - { - return (mData->mPos.changed(prevFrame, curFrame) || - mData->mSize.changed(prevFrame, curFrame) || - mData->roundnessChanged(prevFrame, curFrame)); - } -}; - -class Ellipse final : public Shape { -public: - explicit Ellipse(model::Ellipse *data); - -private: - void updatePath(VPath &path, int frameNo) final; - model::Ellipse *mData{nullptr}; - bool hasChanged(int prevFrame, int curFrame) final - { - return (mData->mPos.changed(prevFrame, curFrame) || - mData->mSize.changed(prevFrame, curFrame)); - } -}; - -class Path final : public Shape { -public: - explicit Path(model::Path *data); - -private: - void updatePath(VPath &path, int frameNo) final; - model::Path *mData{nullptr}; - bool hasChanged(int prevFrame, int curFrame) final - { - return mData->mShape.changed(prevFrame, curFrame); - } -}; - -class Polystar final : public Shape { -public: - explicit Polystar(model::Polystar *data); - -private: - void updatePath(VPath &path, int frameNo) final; - model::Polystar *mData{nullptr}; - - bool hasChanged(int prevFrame, int curFrame) final - { - return (mData->mPos.changed(prevFrame, curFrame) || - mData->mPointCount.changed(prevFrame, curFrame) || - mData->mInnerRadius.changed(prevFrame, curFrame) || - mData->mOuterRadius.changed(prevFrame, curFrame) || - mData->mInnerRoundness.changed(prevFrame, curFrame) || - mData->mOuterRoundness.changed(prevFrame, curFrame) || - mData->mRotation.changed(prevFrame, curFrame)); - } -}; - -class Paint : public Object { -public: - Paint(bool staticContent); - void addPathItems(std::vector &list, size_t startOffset); - void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, - const DirtyFlag &flag) override; - void renderList(std::vector &list) final; - Object::Type type() const final { return Object::Type::Paint; } - -protected: - virtual bool updateContent(int frameNo, const VMatrix &matrix, - float alpha) = 0; - -private: - void updateRenderNode(); - -protected: - std::vector mPathItems; - Drawable mDrawable; - VPath mPath; - DirtyFlag mFlag; - bool mStaticContent; - bool mRenderNodeUpdate{true}; - bool mContentToRender{true}; -}; - -class Fill final : public Paint { -public: - explicit Fill(model::Fill *data); - -protected: - bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final; - bool resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, - LOTVariant &value) final; - -private: - model::Filter mModel; -}; - -class GradientFill final : public Paint { -public: - explicit GradientFill(model::GradientFill *data); - -protected: - bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final; - -private: - model::GradientFill * mData{nullptr}; - std::unique_ptr mGradient; -}; - -class Stroke : public Paint { -public: - explicit Stroke(model::Stroke *data); - -protected: - bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final; - bool resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, - LOTVariant &value) final; - -private: - model::Filter mModel; -}; - -class GradientStroke final : public Paint { -public: - explicit GradientStroke(model::GradientStroke *data); - -protected: - bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final; - -private: - model::GradientStroke * mData{nullptr}; - std::unique_ptr mGradient; -}; - -class Trim final : public Object { -public: - explicit Trim(model::Trim *data) : mData(data), mModel(data) {} - void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, - const DirtyFlag &flag) final; - Object::Type type() const final { return Object::Type::Trim; } - void update(); - void addPathItems(std::vector &list, size_t startOffset); - -protected: - bool resolveKeyPath(LOTKeyPath &keyPath, uint32_t depth, - LOTVariant &value) final; -private: - bool pathDirty() const - { - for (auto &i : mPathItems) { - if (i->dirty()) return true; - } - return false; - } - struct Cache { - int mFrameNo{-1}; - model::Trim::Segment mSegment{}; - }; - Cache mCache; - std::vector mPathItems; - model::Trim * mData{nullptr}; - VPathMesure mPathMesure; - bool mDirty{true}; - - model::Filter mModel; -}; - -class Repeater final : public Group { -public: - explicit Repeater(model::Repeater *data, VArenaAlloc *allocator); - void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha, - const DirtyFlag &flag) final; - void renderList(std::vector &list) final; - -private: - model::Repeater *mRepeaterData{nullptr}; - bool mHidden{false}; - int mCopies{0}; -}; - -} // namespace renderer - -} // namespace internal - -} // namespace rlottie - -#endif // LOTTIEITEM_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieitem_capi.cpp b/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieitem_capi.cpp deleted file mode 100644 index 048e356d..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieitem_capi.cpp +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Implements LottieItem functions needed - * to support renderTree() api. - * Moving all those implementation to its own - * file make clear separation as well easy of - * maintenance. - */ - -#include "lottieitem.h" -#include "vdasher.h" - -using namespace rlottie::internal; - -renderer::CApiData::CApiData() -{ - mLayer.mMaskList.ptr = nullptr; - mLayer.mMaskList.size = 0; - mLayer.mLayerList.ptr = nullptr; - mLayer.mLayerList.size = 0; - mLayer.mNodeList.ptr = nullptr; - mLayer.mNodeList.size = 0; - mLayer.mMatte = MatteNone; - mLayer.mVisible = 0; - mLayer.mAlpha = 255; - mLayer.mClipPath.ptPtr = nullptr; - mLayer.mClipPath.elmPtr = nullptr; - mLayer.mClipPath.ptCount = 0; - mLayer.mClipPath.elmCount = 0; - mLayer.keypath = nullptr; -} - -void renderer::Composition::buildRenderTree() -{ - mRootLayer->buildLayerNode(); -} - -const LOTLayerNode *renderer::Composition::renderTree() const -{ - return &mRootLayer->clayer(); -} - -void renderer::CompLayer::buildLayerNode() -{ - renderer::Layer::buildLayerNode(); - if (mClipper) { - const auto &elm = mClipper->mPath.elements(); - const auto &pts = mClipper->mPath.points(); - auto ptPtr = reinterpret_cast(pts.data()); - auto elmPtr = reinterpret_cast(elm.data()); - clayer().mClipPath.ptPtr = ptPtr; - clayer().mClipPath.elmPtr = elmPtr; - clayer().mClipPath.ptCount = 2 * pts.size(); - clayer().mClipPath.elmCount = elm.size(); - } - if (mLayers.size() != clayers().size()) { - for (const auto &layer : mLayers) { - layer->buildLayerNode(); - clayers().push_back(&layer->clayer()); - } - clayer().mLayerList.ptr = clayers().data(); - clayer().mLayerList.size = clayers().size(); - } else { - for (const auto &layer : mLayers) { - layer->buildLayerNode(); - } - } -} - -void renderer::ShapeLayer::buildLayerNode() -{ - renderer::Layer::buildLayerNode(); - - auto renderlist = renderList(); - - cnodes().clear(); - for (auto &i : renderlist) { - auto lotDrawable = static_cast(i); - lotDrawable->sync(); - cnodes().push_back(lotDrawable->mCNode.get()); - } - clayer().mNodeList.ptr = cnodes().data(); - clayer().mNodeList.size = cnodes().size(); -} - -void renderer::Layer::buildLayerNode() -{ - if (!mCApiData) { - mCApiData = std::make_unique(); - clayer().keypath = name(); - } - if (!complexContent()) clayer().mAlpha = uint8_t(combinedAlpha() * 255.f); - clayer().mVisible = visible(); - // update matte - if (hasMatte()) { - switch (mLayerData->mMatteType) { - case model::MatteType::Alpha: - clayer().mMatte = MatteAlpha; - break; - case model::MatteType::AlphaInv: - clayer().mMatte = MatteAlphaInv; - break; - case model::MatteType::Luma: - clayer().mMatte = MatteLuma; - break; - case model::MatteType::LumaInv: - clayer().mMatte = MatteLumaInv; - break; - default: - clayer().mMatte = MatteNone; - break; - } - } - if (mLayerMask) { - cmasks().clear(); - cmasks().resize(mLayerMask->mMasks.size()); - size_t i = 0; - for (const auto &mask : mLayerMask->mMasks) { - auto & cNode = cmasks()[i++]; - const auto &elm = mask.mFinalPath.elements(); - const auto &pts = mask.mFinalPath.points(); - auto ptPtr = reinterpret_cast(pts.data()); - auto elmPtr = reinterpret_cast(elm.data()); - cNode.mPath.ptPtr = ptPtr; - cNode.mPath.ptCount = 2 * pts.size(); - cNode.mPath.elmPtr = elmPtr; - cNode.mPath.elmCount = elm.size(); - cNode.mAlpha = uint8_t(mask.mCombinedAlpha * 255.0f); - switch (mask.maskMode()) { - case model::Mask::Mode::Add: - cNode.mMode = MaskAdd; - break; - case model::Mask::Mode::Substarct: - cNode.mMode = MaskSubstract; - break; - case model::Mask::Mode::Intersect: - cNode.mMode = MaskIntersect; - break; - case model::Mask::Mode::Difference: - cNode.mMode = MaskDifference; - break; - default: - cNode.mMode = MaskAdd; - break; - } - } - clayer().mMaskList.ptr = cmasks().data(); - clayer().mMaskList.size = cmasks().size(); - } -} - -void renderer::SolidLayer::buildLayerNode() -{ - renderer::Layer::buildLayerNode(); - - auto renderlist = renderList(); - - cnodes().clear(); - for (auto &i : renderlist) { - auto lotDrawable = static_cast(i); - lotDrawable->sync(); - cnodes().push_back(lotDrawable->mCNode.get()); - } - clayer().mNodeList.ptr = cnodes().data(); - clayer().mNodeList.size = cnodes().size(); -} - -void renderer::ImageLayer::buildLayerNode() -{ - renderer::Layer::buildLayerNode(); - - auto renderlist = renderList(); - - cnodes().clear(); - for (auto &i : renderlist) { - auto lotDrawable = static_cast(i); - lotDrawable->sync(); - - lotDrawable->mCNode->mImageInfo.data = - lotDrawable->mBrush.mTexture->mBitmap.data(); - lotDrawable->mCNode->mImageInfo.width = - int(lotDrawable->mBrush.mTexture->mBitmap.width()); - lotDrawable->mCNode->mImageInfo.height = - int(lotDrawable->mBrush.mTexture->mBitmap.height()); - - lotDrawable->mCNode->mImageInfo.mMatrix.m11 = combinedMatrix().m_11(); - lotDrawable->mCNode->mImageInfo.mMatrix.m12 = combinedMatrix().m_12(); - lotDrawable->mCNode->mImageInfo.mMatrix.m13 = combinedMatrix().m_13(); - - lotDrawable->mCNode->mImageInfo.mMatrix.m21 = combinedMatrix().m_21(); - lotDrawable->mCNode->mImageInfo.mMatrix.m22 = combinedMatrix().m_22(); - lotDrawable->mCNode->mImageInfo.mMatrix.m23 = combinedMatrix().m_23(); - - lotDrawable->mCNode->mImageInfo.mMatrix.m31 = combinedMatrix().m_tx(); - lotDrawable->mCNode->mImageInfo.mMatrix.m32 = combinedMatrix().m_ty(); - lotDrawable->mCNode->mImageInfo.mMatrix.m33 = combinedMatrix().m_33(); - - // Alpha calculation already combined. - lotDrawable->mCNode->mImageInfo.mAlpha = - uint8_t(lotDrawable->mBrush.mTexture->mAlpha); - - cnodes().push_back(lotDrawable->mCNode.get()); - } - clayer().mNodeList.ptr = cnodes().data(); - clayer().mNodeList.size = cnodes().size(); -} - -static void updateGStops(LOTNode *n, const VGradient *grad) -{ - if (grad->mStops.size() != n->mGradient.stopCount) { - if (n->mGradient.stopCount) free(n->mGradient.stopPtr); - n->mGradient.stopCount = grad->mStops.size(); - n->mGradient.stopPtr = (LOTGradientStop *)malloc( - n->mGradient.stopCount * sizeof(LOTGradientStop)); - } - - LOTGradientStop *ptr = n->mGradient.stopPtr; - for (const auto &i : grad->mStops) { - ptr->pos = i.first; - ptr->a = uint8_t(i.second.alpha() * grad->alpha()); - ptr->r = i.second.red(); - ptr->g = i.second.green(); - ptr->b = i.second.blue(); - ptr++; - } -} - -void renderer::Drawable::sync() -{ - if (!mCNode) { - mCNode = std::make_unique(); - mCNode->mGradient.stopPtr = nullptr; - mCNode->mGradient.stopCount = 0; - } - - mCNode->mFlag = ChangeFlagNone; - if (mFlag & DirtyState::None) return; - - if (mFlag & DirtyState::Path) { - applyDashOp(); - const std::vector &elm = mPath.elements(); - const std::vector & pts = mPath.points(); - const float *ptPtr = reinterpret_cast(pts.data()); - const char * elmPtr = reinterpret_cast(elm.data()); - mCNode->mPath.elmPtr = elmPtr; - mCNode->mPath.elmCount = elm.size(); - mCNode->mPath.ptPtr = ptPtr; - mCNode->mPath.ptCount = 2 * pts.size(); - mCNode->mFlag |= ChangeFlagPath; - mCNode->keypath = name(); - } - - if (mStrokeInfo) { - mCNode->mStroke.width = mStrokeInfo->width; - mCNode->mStroke.miterLimit = mStrokeInfo->miterLimit; - mCNode->mStroke.enable = 1; - - switch (mStrokeInfo->cap) { - case CapStyle::Flat: - mCNode->mStroke.cap = LOTCapStyle::CapFlat; - break; - case CapStyle::Square: - mCNode->mStroke.cap = LOTCapStyle::CapSquare; - break; - case CapStyle::Round: - mCNode->mStroke.cap = LOTCapStyle::CapRound; - break; - } - - switch (mStrokeInfo->join) { - case JoinStyle::Miter: - mCNode->mStroke.join = LOTJoinStyle::JoinMiter; - break; - case JoinStyle::Bevel: - mCNode->mStroke.join = LOTJoinStyle::JoinBevel; - break; - case JoinStyle::Round: - mCNode->mStroke.join = LOTJoinStyle::JoinRound; - break; - default: - mCNode->mStroke.join = LOTJoinStyle::JoinMiter; - break; - } - } else { - mCNode->mStroke.enable = 0; - } - - switch (mFillRule) { - case FillRule::EvenOdd: - mCNode->mFillRule = LOTFillRule::FillEvenOdd; - break; - default: - mCNode->mFillRule = LOTFillRule::FillWinding; - break; - } - - switch (mBrush.type()) { - case VBrush::Type::Solid: - mCNode->mBrushType = LOTBrushType::BrushSolid; - mCNode->mColor.r = mBrush.mColor.r; - mCNode->mColor.g = mBrush.mColor.g; - mCNode->mColor.b = mBrush.mColor.b; - mCNode->mColor.a = mBrush.mColor.a; - break; - case VBrush::Type::LinearGradient: { - mCNode->mBrushType = LOTBrushType::BrushGradient; - mCNode->mGradient.type = LOTGradientType::GradientLinear; - VPointF s = mBrush.mGradient->mMatrix.map( - {mBrush.mGradient->linear.x1, mBrush.mGradient->linear.y1}); - VPointF e = mBrush.mGradient->mMatrix.map( - {mBrush.mGradient->linear.x2, mBrush.mGradient->linear.y2}); - mCNode->mGradient.start.x = s.x(); - mCNode->mGradient.start.y = s.y(); - mCNode->mGradient.end.x = e.x(); - mCNode->mGradient.end.y = e.y(); - updateGStops(mCNode.get(), mBrush.mGradient); - break; - } - case VBrush::Type::RadialGradient: { - mCNode->mBrushType = LOTBrushType::BrushGradient; - mCNode->mGradient.type = LOTGradientType::GradientRadial; - VPointF c = mBrush.mGradient->mMatrix.map( - {mBrush.mGradient->radial.cx, mBrush.mGradient->radial.cy}); - VPointF f = mBrush.mGradient->mMatrix.map( - {mBrush.mGradient->radial.fx, mBrush.mGradient->radial.fy}); - mCNode->mGradient.center.x = c.x(); - mCNode->mGradient.center.y = c.y(); - mCNode->mGradient.focal.x = f.x(); - mCNode->mGradient.focal.y = f.y(); - - float scale = mBrush.mGradient->mMatrix.scale(); - mCNode->mGradient.cradius = mBrush.mGradient->radial.cradius * scale; - mCNode->mGradient.fradius = mBrush.mGradient->radial.fradius * scale; - updateGStops(mCNode.get(), mBrush.mGradient); - break; - } - default: - break; - } -} diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottiekeypath.cpp b/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottiekeypath.cpp deleted file mode 100644 index 21b01aac..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottiekeypath.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "lottiekeypath.h" - -#include - -LOTKeyPath::LOTKeyPath(const std::string &keyPath) -{ - std::stringstream ss(keyPath); - std::string item; - - while (getline(ss, item, '.')) { - mKeys.push_back(item); - } -} - -bool LOTKeyPath::matches(const std::string &key, uint32_t depth) -{ - if (skip(key)) { - // This is an object we programatically create. - return true; - } - if (depth > size()) { - return false; - } - if ((mKeys[depth] == key) || (mKeys[depth] == "*") || - (mKeys[depth] == "**")) { - return true; - } - return false; -} - -uint32_t LOTKeyPath::nextDepth(const std::string key, uint32_t depth) -{ - if (skip(key)) { - // If it's a container then we added programatically and it isn't a part - // of the keypath. - return depth; - } - if (mKeys[depth] != "**") { - // If it's not a globstar then it is part of the keypath. - return depth + 1; - } - if (depth == size()) { - // The last key is a globstar. - return depth; - } - if (mKeys[depth + 1] == key) { - // We are a globstar and the next key is our current key so consume - // both. - return depth + 2; - } - return depth; -} - -bool LOTKeyPath::fullyResolvesTo(const std::string key, uint32_t depth) -{ - if (depth > mKeys.size()) { - return false; - } - - bool isLastDepth = (depth == size()); - - if (!isGlobstar(depth)) { - bool matches = (mKeys[depth] == key) || isGlob(depth); - return (isLastDepth || (depth == size() - 1 && endsWithGlobstar())) && - matches; - } - - bool isGlobstarButNextKeyMatches = !isLastDepth && mKeys[depth + 1] == key; - if (isGlobstarButNextKeyMatches) { - return depth == size() - 1 || - (depth == size() - 2 && endsWithGlobstar()); - } - - if (isLastDepth) { - return true; - } - - if (depth + 1 < size()) { - // We are a globstar but there is more than 1 key after the globstar we - // we can't fully match. - return false; - } - // Return whether the next key (which we now know is the last one) is the - // same as the current key. - return mKeys[depth + 1] == key; -} diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottiekeypath.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottiekeypath.h deleted file mode 100644 index 2c53287e..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottiekeypath.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef LOTTIEKEYPATH_H -#define LOTTIEKEYPATH_H - -#include -#include -#include "vglobal.h" - -class LOTKeyPath { -public: - LOTKeyPath(const std::string &keyPath); - bool matches(const std::string &key, uint32_t depth); - uint32_t nextDepth(const std::string key, uint32_t depth); - bool fullyResolvesTo(const std::string key, uint32_t depth); - - bool propagate(const std::string key, uint32_t depth) - { - return skip(key) ? true : (depth < size()) || (mKeys[depth] == "**"); - } - bool skip(const std::string &key) const { return key == "__"; } - -private: - bool isGlobstar(uint32_t depth) const { return mKeys[depth] == "**"; } - bool isGlob(uint32_t depth) const { return mKeys[depth] == "*"; } - bool endsWithGlobstar() const { return mKeys.back() == "**"; } - size_t size() const { return mKeys.size() - 1; } - -private: - std::vector mKeys; -}; - -#endif // LOTTIEKEYPATH_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieloader.cpp b/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieloader.cpp deleted file mode 100644 index 0c938db9..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieloader.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include -#include - -#include "lottiemodel.h" - -using namespace rlottie::internal; - -#ifdef LOTTIE_CACHE_SUPPORT - -#include -#include - -class ModelCache { -public: - static ModelCache &instance() - { - static ModelCache singleton; - return singleton; - } - std::shared_ptr find(const std::string &key) - { - std::lock_guard guard(mMutex); - - if (!mcacheSize) return nullptr; - - auto search = mHash.find(key); - - return (search != mHash.end()) ? search->second : nullptr; - } - void add(const std::string &key, std::shared_ptr value) - { - std::lock_guard guard(mMutex); - - if (!mcacheSize) return; - - //@TODO just remove the 1st element - // not the best of LRU logic - if (mcacheSize == mHash.size()) mHash.erase(mHash.cbegin()); - - mHash[key] = std::move(value); - } - - void configureCacheSize(size_t cacheSize) - { - std::lock_guard guard(mMutex); - mcacheSize = cacheSize; - - if (!mcacheSize) mHash.clear(); - } - -private: - ModelCache() = default; - - std::unordered_map> mHash; - std::mutex mMutex; - size_t mcacheSize{10}; -}; - -#else - -class ModelCache { -public: - static ModelCache &instance() - { - static ModelCache singleton; - return singleton; - } - std::shared_ptr find(const std::string &) - { - return nullptr; - } - void add(const std::string &, std::shared_ptr) {} - void configureCacheSize(size_t) {} -}; - -#endif - -static std::string dirname(const std::string &path) -{ - const char *ptr = strrchr(path.c_str(), '/'); -#ifdef _WIN32 - if (ptr) ptr = strrchr(ptr + 1, '\\'); -#endif - int len = int(ptr + 1 - path.c_str()); // +1 to include '/' - return std::string(path, 0, len); -} - -void model::configureModelCacheSize(size_t cacheSize) -{ - ModelCache::instance().configureCacheSize(cacheSize); -} - -std::shared_ptr model::loadFromFile(const std::string &path, - bool cachePolicy) -{ - if (cachePolicy) { - auto obj = ModelCache::instance().find(path); - if (obj) return obj; - } - - std::ifstream f; - f.open(path); - - if (!f.is_open()) { - vCritical << "failed to open file = " << path.c_str(); - return {}; - } else { - std::string content; - f.seekg(0, std::ios::end); - auto fsize = f.tellg(); - - //read the given file - content.reserve(fsize); - f.seekg(0, std::ios::beg); - content.assign((std::istreambuf_iterator(f)), std::istreambuf_iterator()); - - f.close(); - - if (fsize == 0) return {}; - - auto obj = internal::model::parse(const_cast(content.c_str()), fsize, - dirname(path)); - - if (obj && cachePolicy) ModelCache::instance().add(path, obj); - - return obj; - } -} - -std::shared_ptr model::loadFromData( - std::string jsonData, const std::string &key, std::string resourcePath, - bool cachePolicy) -{ - if (cachePolicy) { - auto obj = ModelCache::instance().find(key); - if (obj) return obj; - } - - auto obj = internal::model::parse(const_cast(jsonData.c_str()), jsonData.size(), - std::move(resourcePath)); - - if (obj && cachePolicy) ModelCache::instance().add(key, obj); - - return obj; -} - -std::shared_ptr model::loadFromData( - std::string jsonData, std::string resourcePath, model::ColorFilter filter) -{ - return internal::model::parse(const_cast(jsonData.c_str()), jsonData.size(), - std::move(resourcePath), std::move(filter)); -} diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottiemodel.cpp b/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottiemodel.cpp deleted file mode 100644 index 0f816f6f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottiemodel.cpp +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "lottiemodel.h" -#include -#include -#include -#include "vimageloader.h" -#include "vline.h" - -using namespace rlottie::internal; - -/* - * We process the iterator objects in the children list - * by iterating from back to front. when we find a repeater object - * we remove the objects from satrt till repeater object and then place - * under a new shape group object which we add it as children to the repeater - * object. - * Then we visit the childrens of the newly created shape group object to - * process the remaining repeater object(when children list contains more than - * one repeater). - * - */ -class LottieRepeaterProcesser { -public: - void visitChildren(model::Group *obj) - { - for (auto i = obj->mChildren.rbegin(); i != obj->mChildren.rend(); - ++i) { - auto child = (*i); - if (child->type() == model::Object::Type::Repeater) { - model::Repeater *repeater = - static_cast(child); - // check if this repeater is already processed - // can happen if the layer is an asset and referenced by - // multiple layer. - if (repeater->processed()) continue; - - repeater->markProcessed(); - - auto content = repeater->content(); - // 1. increment the reverse iterator to point to the - // object before the repeater - ++i; - // 2. move all the children till repater to the group - std::move(obj->mChildren.begin(), i.base(), - back_inserter(content->mChildren)); - // 3. erase the objects from the original children list - obj->mChildren.erase(obj->mChildren.begin(), i.base()); - - // 5. visit newly created group to process remaining repeater - // object. - visitChildren(content); - // 6. exit the loop as the current iterators are invalid - break; - } - visit(child); - } - } - - void visit(model::Object *obj) - { - switch (obj->type()) { - case model::Object::Type::Group: - case model::Object::Type::Layer: { - visitChildren(static_cast(obj)); - break; - } - default: - break; - } - } -}; - -class LottieUpdateStatVisitor { - model::Composition::Stats *stat; - -public: - explicit LottieUpdateStatVisitor(model::Composition::Stats *s) : stat(s) {} - void visitChildren(model::Group *obj) - { - for (const auto &child : obj->mChildren) { - if (child) visit(child); - } - } - void visitLayer(model::Layer *layer) - { - switch (layer->mLayerType) { - case model::Layer::Type::Precomp: - stat->precompLayerCount++; - break; - case model::Layer::Type::Null: - stat->nullLayerCount++; - break; - case model::Layer::Type::Shape: - stat->shapeLayerCount++; - break; - case model::Layer::Type::Solid: - stat->solidLayerCount++; - break; - case model::Layer::Type::Image: - stat->imageLayerCount++; - break; - default: - break; - } - visitChildren(layer); - } - void visit(model::Object *obj) - { - switch (obj->type()) { - case model::Object::Type::Layer: { - visitLayer(static_cast(obj)); - break; - } - case model::Object::Type::Repeater: { - visitChildren(static_cast(obj)->content()); - break; - } - case model::Object::Type::Group: { - visitChildren(static_cast(obj)); - break; - } - default: - break; - } - } -}; - -void model::Composition::processRepeaterObjects() -{ - LottieRepeaterProcesser visitor; - visitor.visit(mRootLayer); -} - -void model::Composition::updateStats() -{ - LottieUpdateStatVisitor visitor(&mStats); - visitor.visit(mRootLayer); -} - -VMatrix model::Repeater::Transform::matrix(int frameNo, float multiplier) const -{ - VPointF scale = mScale.value(frameNo) / 100.f; - scale.setX(std::pow(scale.x(), multiplier)); - scale.setY(std::pow(scale.y(), multiplier)); - VMatrix m; - m.translate(mPosition.value(frameNo) * multiplier) - .translate(mAnchor.value(frameNo)) - .scale(scale) - .rotate(mRotation.value(frameNo) * multiplier) - .translate(-mAnchor.value(frameNo)); - - return m; -} - -VMatrix model::Transform::Data::matrix(int frameNo, bool autoOrient) const -{ - VMatrix m; - VPointF position; - if (mExtra && mExtra->mSeparate) { - position.setX(mExtra->mSeparateX.value(frameNo)); - position.setY(mExtra->mSeparateY.value(frameNo)); - } else { - position = mPosition.value(frameNo); - } - - float angle = autoOrient ? mPosition.angle(frameNo) : 0; - if (mExtra && mExtra->m3DData) { - m.translate(position) - .rotate(mExtra->m3DRz.value(frameNo) + angle) - .rotate(mExtra->m3DRy.value(frameNo), VMatrix::Axis::Y) - .rotate(mExtra->m3DRx.value(frameNo), VMatrix::Axis::X) - .scale(mScale.value(frameNo) / 100.f) - .translate(-mAnchor.value(frameNo)); - } else { - m.translate(position) - .rotate(mRotation.value(frameNo) + angle) - .scale(mScale.value(frameNo) / 100.f) - .translate(-mAnchor.value(frameNo)); - } - return m; -} - -void model::Dash::getDashInfo(int frameNo, std::vector &result) const -{ - result.clear(); - - if (mData.size() <= 1) return; - - if (result.capacity() < mData.size()) result.reserve(mData.size() + 1); - - for (const auto &elm : mData) result.push_back(elm.value(frameNo)); - - // if the size is even then we are missing last - // gap information which is same as the last dash value - // copy it from the last dash value. - // NOTE: last value is the offset and last-1 is the last dash value. - auto size = result.size(); - if ((size % 2) == 0) { - // copy offset value to end. - result.push_back(result.back()); - // copy dash value to gap. - result[size - 1] = result[size - 2]; - } -} - -/** - * Both the color stops and opacity stops are in the same array. - * There are {@link #colorPoints} colors sequentially as: - * [ - * ..., - * position, - * red, - * green, - * blue, - * ... - * ] - * - * The remainder of the array is the opacity stops sequentially as: - * [ - * ..., - * position, - * opacity, - * ... - * ] - */ -void model::Gradient::populate(VGradientStops &stops, int frameNo) -{ - model::Gradient::Data gradData = mGradient.value(frameNo); - auto size = gradData.mGradient.size(); - float * ptr = gradData.mGradient.data(); - int colorPoints = mColorPoints; - size_t colorPointsSize = colorPoints * 4; - if (!ptr) return; - if (colorPoints < 0 || colorPointsSize > size) { // for legacy bodymovin (ref: lottie-android) - colorPoints = int(size / 4); - } - auto opacityArraySize = size - colorPointsSize; - if (opacityArraySize % 2 != 0) { - opacityArraySize = 0; - } - float *opacityPtr = ptr + colorPointsSize; - stops.clear(); - for (int i = 0; i < colorPoints; i++) { - float colorStop = ptr[0]; - model::Color color = model::Color(ptr[1], ptr[2], ptr[3]); - if (opacityArraySize) { - float opacity = getOpacityAtPosition(opacityPtr, opacityArraySize, colorStop); - stops.push_back(std::make_pair(colorStop, color.toColor(opacity))); - } else { - stops.push_back(std::make_pair(colorStop, color.toColor())); - } - ptr += 4; - } - - if (stops.empty()) { - stops.push_back(std::make_pair(0.0f, VColor(255, 255, 255, 255))); - } -} - -float model::Gradient::getOpacityAtPosition(float *opacities, size_t opacityArraySize, float position) -{ - for (size_t i = 2; i < opacityArraySize; i += 2) - { - float lastPosition = opacities[i - 2]; - float thisPosition = opacities[i]; - if (opacities[i] >= position) { - float progress = (position - lastPosition) / (thisPosition - lastPosition); - progress = progress < 0.0f ? 0.0f : 1.0f < progress ? 1.0f : progress; //clamp(progress, 0, 1) - return opacities[i - 1] + progress * (opacities[i + 1] - opacities[i - 1]); - } - } - return 0.0f; -} - -void model::Gradient::update(std::unique_ptr &grad, int frameNo) -{ - bool init = false; - if (!grad) { - if (mGradientType == 1) - grad = std::make_unique(VGradient::Type::Linear); - else - grad = std::make_unique(VGradient::Type::Radial); - grad->mSpread = VGradient::Spread::Pad; - init = true; - } - - if (!mGradient.isStatic() || init) { - populate(grad->mStops, frameNo); - } - - if (mGradientType == 1) { // linear gradient - VPointF start = mStartPoint.value(frameNo); - VPointF end = mEndPoint.value(frameNo); - grad->linear.x1 = start.x(); - grad->linear.y1 = start.y(); - grad->linear.x2 = end.x(); - grad->linear.y2 = end.y(); - } else { // radial gradient - VPointF start = mStartPoint.value(frameNo); - VPointF end = mEndPoint.value(frameNo); - grad->radial.cx = start.x(); - grad->radial.cy = start.y(); - grad->radial.cradius = - VLine::length(start.x(), start.y(), end.x(), end.y()); - /* - * Focal point is the point lives in highlight length distance from - * center along the line (start, end) and rotated by highlight angle. - * below calculation first finds the quadrant(angle) on which the point - * lives by applying inverse slope formula then adds the rotation angle - * to find the final angle. then point is retrived using circle equation - * of center, angle and distance. - */ - float progress = mHighlightLength.value(frameNo) / 100.0f; - if (vCompare(progress, 1.0f)) progress = 0.99f; - float startAngle = VLine(start, end).angle(); - float highlightAngle = mHighlightAngle.value(frameNo); - static constexpr float K_PI = 3.1415926f; - float angle = (startAngle + highlightAngle) * (K_PI / 180.0f); - grad->radial.fx = - grad->radial.cx + std::cos(angle) * progress * grad->radial.cradius; - grad->radial.fy = - grad->radial.cy + std::sin(angle) * progress * grad->radial.cradius; - // Lottie dosen't have any focal radius concept. - grad->radial.fradius = 0; - } -} - -void model::Asset::loadImageData(std::string data) -{ - if (!data.empty()) - mBitmap = VImageLoader::instance().load(data.c_str(), data.length()); -} - -void model::Asset::loadImagePath(std::string path) -{ - if (!path.empty()) mBitmap = VImageLoader::instance().load(path.c_str()); -} - -std::vector model::Composition::layerInfoList() const -{ - if (!mRootLayer || mRootLayer->mChildren.empty()) return {}; - - std::vector result; - - result.reserve(mRootLayer->mChildren.size()); - - for (auto it : mRootLayer->mChildren) { - auto layer = static_cast(it); - result.emplace_back(layer->name(), layer->mInFrame, layer->mOutFrame); - } - - return result; -} diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottiemodel.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottiemodel.h deleted file mode 100644 index c51cc4a2..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottiemodel.h +++ /dev/null @@ -1,1168 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef LOTModel_H -#define LOTModel_H - -#include -#include -#include -#include -#include -#include -#include -#include "varenaalloc.h" -#include "vbezier.h" -#include "vbrush.h" -#include "vinterpolator.h" -#include "vmatrix.h" -#include "vpath.h" -#include "vpoint.h" -#include "vrect.h" - -V_USE_NAMESPACE - -namespace rlottie { - -namespace internal { - -using Marker = std::tuple; - -using LayerInfo = Marker; - -template -inline T lerp(const T &start, const T &end, float t) -{ - return start + t * (end - start); -} - -namespace model { - -enum class MatteType : uint8_t { None = 0, Alpha = 1, AlphaInv, Luma, LumaInv }; - -enum class BlendMode : uint8_t { - Normal = 0, - Multiply = 1, - Screen = 2, - OverLay = 3 -}; - -class Color { -public: - Color() = default; - Color(float red, float green, float blue) : r(red), g(green), b(blue) {} - VColor toColor(float a = 1) - { - return VColor(uint8_t(255 * r), uint8_t(255 * g), uint8_t(255 * b), - uint8_t(255 * a)); - } - friend inline Color operator+(const Color &c1, const Color &c2); - friend inline Color operator-(const Color &c1, const Color &c2); - -public: - float r{1}; - float g{1}; - float b{1}; -}; - -inline Color operator-(const Color &c1, const Color &c2) -{ - return Color(c1.r - c2.r, c1.g - c2.g, c1.b - c2.b); -} -inline Color operator+(const Color &c1, const Color &c2) -{ - return Color(c1.r + c2.r, c1.g + c2.g, c1.b + c2.b); -} - -inline const Color operator*(const Color &c, float m) -{ - return Color(c.r * m, c.g * m, c.b * m); -} - -inline const Color operator*(float m, const Color &c) -{ - return Color(c.r * m, c.g * m, c.b * m); -} - -struct PathData { - std::vector mPoints; - bool mClosed = false; /* "c" */ - void reserve(size_t size) { mPoints.reserve(mPoints.size() + size); } - static void lerp(const PathData &start, const PathData &end, float t, - VPath &result) - { - result.reset(); - // test for empty animation data. - if (start.mPoints.empty() || end.mPoints.empty()) - { - return; - } - auto size = std::min(start.mPoints.size(), end.mPoints.size()); - /* reserve exact memory requirement at once - * ptSize = size + 1(size + close) - * elmSize = size/3 cubic + 1 move + 1 close - */ - result.reserve(size + 1, size / 3 + 2); - result.moveTo(start.mPoints[0] + - t * (end.mPoints[0] - start.mPoints[0])); - for (size_t i = 1; i < size; i += 3) { - result.cubicTo( - start.mPoints[i] + t * (end.mPoints[i] - start.mPoints[i]), - start.mPoints[i + 1] + - t * (end.mPoints[i + 1] - start.mPoints[i + 1]), - start.mPoints[i + 2] + - t * (end.mPoints[i + 2] - start.mPoints[i + 2])); - } - if (start.mClosed) result.close(); - } - void toPath(VPath &path) const - { - path.reset(); - - if (mPoints.empty()) return; - - auto size = mPoints.size(); - auto points = mPoints.data(); - /* reserve exact memory requirement at once - * ptSize = size + 1(size + close) - * elmSize = size/3 cubic + 1 move + 1 close - */ - path.reserve(size + 1, size / 3 + 2); - path.moveTo(points[0]); - for (size_t i = 1; i < size; i += 3) { - path.cubicTo(points[i], points[i + 1], points[i + 2]); - } - if (mClosed) path.close(); - } -}; - -template -struct Value { - T start_; - T end_; - T at(float t) const { return lerp(start_, end_, t); } - float angle(float) const { return 0; } - void cache() {} -}; - -struct Position; - -template -struct Value { - T start_; - T end_; - T inTangent_; - T outTangent_; - float length_{0}; - bool hasTangent_{false}; - - void cache() - { - if (hasTangent_) { - inTangent_ = end_ + inTangent_; - outTangent_ = start_ + outTangent_; - length_ = VBezier::fromPoints(start_, outTangent_, inTangent_, end_) - .length(); - if (vIsZero(length_)) { - // this segment has zero length. - // so disable expensive path computaion. - hasTangent_ = false; - } - } - } - - T at(float t) const - { - if (hasTangent_) { - /* - * position along the path calcualated - * using bezier at progress length (t * bezlen) - */ - VBezier b = - VBezier::fromPoints(start_, outTangent_, inTangent_, end_); - return b.pointAt(b.tAtLength(t * length_, length_)); - } - return lerp(start_, end_, t); - } - - float angle(float t) const - { - if (hasTangent_) { - VBezier b = - VBezier::fromPoints(start_, outTangent_, inTangent_, end_); - return b.angleAt(b.tAtLength(t * length_, length_)); - } - return 0; - } -}; - -template -class KeyFrames { -public: - struct Frame { - float progress(int frameNo) const - { - return interpolator_ ? interpolator_->value((frameNo - start_) / - (end_ - start_)) - : 0; - } - T value(int frameNo) const { return value_.at(progress(frameNo)); } - float angle(int frameNo) const - { - return value_.angle(progress(frameNo)); - } - - float start_{0}; - float end_{0}; - VInterpolator *interpolator_{nullptr}; - Value value_; - }; - - T value(int frameNo) const - { - if (!frames_.empty()) { - if (frames_.front().start_ >= frameNo) - return frames_.front().value_.start_; - if (frames_.back().end_ <= frameNo) return frames_.back().value_.end_; - - for (const auto &keyFrame : frames_) { - if (frameNo >= keyFrame.start_ && frameNo < keyFrame.end_) - return keyFrame.value(frameNo); - } - } - return {}; - } - - float angle(int frameNo) const - { - if (frames_.empty() || - (frames_.front().start_ >= frameNo) || - (frames_.back().end_ <= frameNo)) - return 0; - - for (const auto &frame : frames_) { - if (frameNo >= frame.start_ && frameNo < frame.end_) - return frame.angle(frameNo); - } - return 0; - } - - bool changed(int prevFrame, int curFrame) const - { - if (frames_.empty()) return false; - - auto first = frames_.front().start_; - auto last = frames_.back().end_; - - return !((first > prevFrame && first > curFrame) || - (last < prevFrame && last < curFrame)); - } - void cache() - { - for (auto &e : frames_) e.value_.cache(); - } - -public: - std::vector frames_; -}; - -template -class Property { -public: - using Animation = KeyFrames; - - Property() { construct(impl_.value_, {}); } - explicit Property(T value) { construct(impl_.value_, std::move(value)); } - - const Animation &animation() const { return *(impl_.animation_.get()); } - const T & value() const { return impl_.value_; } - - Animation &animation() - { - if (isValue_) { - destroy(); - construct(impl_.animation_, std::make_unique()); - isValue_ = false; - } - return *(impl_.animation_.get()); - } - - T &value() - { - assert(isValue_); - return impl_.value_; - } - - Property(Property &&other) noexcept - { - if (!other.isValue_) { - construct(impl_.animation_, std::move(other.impl_.animation_)); - isValue_ = false; - } else { - construct(impl_.value_, std::move(other.impl_.value_)); - isValue_ = true; - } - } - // delete special member functions - Property(const Property &) = delete; - Property &operator=(const Property &) = delete; - Property &operator=(Property &&) = delete; - - ~Property() { destroy(); } - - bool isStatic() const { return isValue_; } - - T value(int frameNo) const - { - return isStatic() ? value() : animation().value(frameNo); - } - - // special function only for type T=PathData - template - auto value(int frameNo, VPath &path) const -> - typename std::enable_if_t::value, void> - { - if (isStatic()) { - value().toPath(path); - } else { - const auto &vec = animation().frames_; - if (vec.front().start_ >= frameNo) - return vec.front().value_.start_.toPath(path); - if (vec.back().end_ <= frameNo) - return vec.back().value_.end_.toPath(path); - - for (const auto &keyFrame : vec) { - if (frameNo >= keyFrame.start_ && frameNo < keyFrame.end_) { - T::lerp(keyFrame.value_.start_, keyFrame.value_.end_, - keyFrame.progress(frameNo), path); - } - } - } - } - - float angle(int frameNo) const - { - return isStatic() ? 0 : animation().angle(frameNo); - } - - bool changed(int prevFrame, int curFrame) const - { - return isStatic() ? false : animation().changed(prevFrame, curFrame); - } - void cache() - { - if (!isStatic()) animation().cache(); - } - -private: - template - void construct(Tp &member, Tp &&val) - { - new (&member) Tp(std::move(val)); - } - - void destroy() - { - if (isValue_) { - impl_.value_.~T(); - } else { - using std::unique_ptr; - impl_.animation_.~unique_ptr(); - } - } - union details { - std::unique_ptr animation_; - T value_; - details(){}; - details(const details &) = delete; - details(details &&) = delete; - details &operator=(details &&) = delete; - details &operator=(const details &) = delete; - ~details() noexcept {}; - } impl_; - bool isValue_{true}; -}; - -class Path; -struct PathData; -struct Dash { - std::vector> mData; - bool empty() const { return mData.empty(); } - size_t size() const { return mData.size(); } - bool isStatic() const - { - for (const auto &elm : mData) - if (!elm.isStatic()) return false; - return true; - } - void getDashInfo(int frameNo, std::vector &result) const; -}; - -class Mask { -public: - enum class Mode { None, Add, Substarct, Intersect, Difference }; - float opacity(int frameNo) const - { - return mOpacity.value(frameNo) / 100.0f; - } - bool isStatic() const { return mIsStatic; } - -public: - Property mShape; - Property mOpacity{100}; - bool mInv{false}; - bool mIsStatic{true}; - Mask::Mode mMode; -}; - -class Object { -public: - enum class Type : unsigned char { - Composition = 1, - Layer, - Group, - Transform, - Fill, - Stroke, - GFill, - GStroke, - Rect, - Ellipse, - Path, - Polystar, - Trim, - Repeater, - RoundedCorner - }; - - explicit Object(Object::Type type) : mPtr(nullptr) - { - mData._type = type; - mData._static = true; - mData._shortString = true; - mData._hidden = false; - } - ~Object() noexcept - { - if (!shortString() && mPtr) free(mPtr); - } - Object(const Object &) = delete; - Object &operator=(const Object &) = delete; - - void setStatic(bool value) { mData._static = value; } - bool isStatic() const { return mData._static; } - bool hidden() const { return mData._hidden; } - void setHidden(bool value) { mData._hidden = value; } - void setType(Object::Type type) { mData._type = type; } - Object::Type type() const { return mData._type; } - void setName(const char *name) - { - if (name) { - auto len = strlen(name); - if (len < maxShortStringLength) { - setShortString(true); - strncpy(mData._buffer, name, len + 1); - } else { - setShortString(false); - mPtr = strdup(name); - } - } - } - const char *name() const { return shortString() ? mData._buffer : mPtr; } - -private: - static constexpr unsigned char maxShortStringLength = 14; - void setShortString(bool value) { mData._shortString = value; } - bool shortString() const { return mData._shortString; } - struct Data { - char _buffer[maxShortStringLength]; - Object::Type _type; - bool _static : 1; - bool _hidden : 1; - bool _shortString : 1; - }; - union { - Data mData; - char *mPtr{nullptr}; - }; -}; - -struct Asset { - enum class Type : unsigned char { Precomp, Image, Char }; - bool isStatic() const { return mStatic; } - void setStatic(bool value) { mStatic = value; } - VBitmap bitmap() const { return mBitmap; } - void loadImageData(std::string data); - void loadImagePath(std::string Path); - Type mAssetType{Type::Precomp}; - bool mStatic{true}; - std::string mRefId; // ref id - std::vector mLayers; - // image asset data - int mWidth{0}; - int mHeight{0}; - VBitmap mBitmap; -}; - -class Layer; - -class Composition : public Object { -public: - Composition() : Object(Object::Type::Composition) {} - std::vector layerInfoList() const; - const std::vector &markers() const { return mMarkers; } - double duration() const - { - return frameDuration() / frameRate(); // in second - } - size_t frameAtPos(double pos) const - { - if (pos < 0) pos = 0; - if (pos > 1) pos = 1; - return size_t(round(pos * frameDuration())); - } - long frameAtTime(double timeInSec) const - { - return long(frameAtPos(timeInSec / duration())); - } - size_t totalFrame() const { return mEndFrame - mStartFrame + 1; } - long frameDuration() const { return mEndFrame - mStartFrame; } - float frameRate() const { return mFrameRate; } - size_t startFrame() const { return mStartFrame; } - size_t endFrame() const { return mEndFrame; } - VSize size() const { return mSize; } - void processRepeaterObjects(); - void updateStats(); - -public: - struct Stats { - uint16_t precompLayerCount{0}; - uint16_t solidLayerCount{0}; - uint16_t shapeLayerCount{0}; - uint16_t imageLayerCount{0}; - uint16_t nullLayerCount{0}; - }; - -public: - std::string mVersion; - VSize mSize; - long mStartFrame{0}; - long mEndFrame{0}; - float mFrameRate{60}; - BlendMode mBlendMode{BlendMode::Normal}; - Layer * mRootLayer{nullptr}; - std::unordered_map mAssets; - - std::vector mMarkers; - VArenaAlloc mArenaAlloc{2048}; - Stats mStats; -}; - -class Transform : public Object { -public: - struct Data { - struct Extra { - Property m3DRx{0}; - Property m3DRy{0}; - Property m3DRz{0}; - Property mSeparateX{0}; - Property mSeparateY{0}; - bool mSeparate{false}; - bool m3DData{false}; - }; - VMatrix matrix(int frameNo, bool autoOrient = false) const; - float opacity(int frameNo) const - { - return mOpacity.value(frameNo) / 100.0f; - } - void createExtraData() - { - if (!mExtra) mExtra = std::make_unique(); - } - Property mRotation{0}; /* "r" */ - Property mScale{{100, 100}}; /* "s" */ - Property mPosition; /* "p" */ - Property mAnchor; /* "a" */ - Property mOpacity{100}; /* "o" */ - std::unique_ptr mExtra; - }; - - Transform() : Object(Object::Type::Transform) {} - void set(Transform::Data *data, bool staticFlag) - { - setStatic(staticFlag); - if (isStatic()) { - new (&impl.mStaticData) - StaticData(data->matrix(0), data->opacity(0)); - } else { - impl.mData = data; - } - } - VMatrix matrix(int frameNo, bool autoOrient = false) const - { - if (isStatic()) return impl.mStaticData.mMatrix; - return impl.mData->matrix(frameNo, autoOrient); - } - float opacity(int frameNo) const - { - if (isStatic()) return impl.mStaticData.mOpacity; - return impl.mData->opacity(frameNo); - } - Transform(const Transform &) = delete; - Transform(Transform &&) = delete; - Transform &operator=(Transform &) = delete; - Transform &operator=(Transform &&) = delete; - ~Transform() noexcept { destroy(); } - -private: - void destroy() - { - if (isStatic()) { - impl.mStaticData.~StaticData(); - } - } - struct StaticData { - StaticData(VMatrix &&m, float opacity) - : mOpacity(opacity), mMatrix(std::move(m)) - { - } - float mOpacity; - VMatrix mMatrix; - }; - union details { - Data * mData{nullptr}; - StaticData mStaticData; - details(){}; - details(const details &) = delete; - details(details &&) = delete; - details &operator=(details &&) = delete; - details &operator=(const details &) = delete; - ~details() noexcept {}; - } impl; -}; - -class Group : public Object { -public: - Group() : Object(Object::Type::Group) {} - explicit Group(Object::Type type) : Object(type) {} - -public: - std::vector mChildren; - Transform * mTransform{nullptr}; -}; - -class Layer : public Group { -public: - enum class Type : uint8_t { - Precomp = 0, - Solid = 1, - Image = 2, - Null = 3, - Shape = 4, - Text = 5 - }; - Layer() : Group(Object::Type::Layer) {} - bool hasRoundedCorner() const noexcept { return mHasRoundedCorner; } - bool hasPathOperator() const noexcept { return mHasPathOperator; } - bool hasGradient() const noexcept { return mHasGradient; } - bool hasMask() const noexcept { return mHasMask; } - bool hasRepeater() const noexcept { return mHasRepeater; } - int id() const noexcept { return mId; } - int parentId() const noexcept { return mParentId; } - bool hasParent() const noexcept { return mParentId != -1; } - int inFrame() const noexcept { return mInFrame; } - int outFrame() const noexcept { return mOutFrame; } - int startFrame() const noexcept { return mStartFrame; } - Color solidColor() const noexcept - { - return mExtra ? mExtra->mSolidColor : Color(); - } - bool autoOrient() const noexcept { return mAutoOrient; } - int timeRemap(int frameNo) const; - VSize layerSize() const { return mLayerSize; } - bool precompLayer() const { return mLayerType == Type::Precomp; } - VMatrix matrix(int frameNo) const - { - return mTransform ? mTransform->matrix(frameNo, autoOrient()) - : VMatrix{}; - } - float opacity(int frameNo) const - { - return mTransform ? mTransform->opacity(frameNo) : 1.0f; - } - Asset *asset() const { return mExtra ? mExtra->mAsset : nullptr; } - struct Extra { - Color mSolidColor; - std::string mPreCompRefId; - Property mTimeRemap; /* "tm" */ - Composition * mCompRef{nullptr}; - Asset * mAsset{nullptr}; - std::vector mMasks; - }; - - Layer::Extra *extra() - { - if (!mExtra) mExtra = std::make_unique(); - return mExtra.get(); - } - -public: - MatteType mMatteType{MatteType::None}; - Type mLayerType{Layer::Type::Null}; - BlendMode mBlendMode{BlendMode::Normal}; - bool mHasRoundedCorner{false}; - bool mHasPathOperator{false}; - bool mHasMask{false}; - bool mHasRepeater{false}; - bool mHasGradient{false}; - bool mAutoOrient{false}; - VSize mLayerSize; - int mParentId{-1}; // Lottie the id of the parent in the composition - int mId{-1}; // Lottie the group id used for parenting. - float mTimeStreatch{1.0f}; - int mInFrame{0}; - int mOutFrame{0}; - int mStartFrame{0}; - std::unique_ptr mExtra{nullptr}; -}; - -/** - * TimeRemap has the value in time domain(in sec) - * To get the proper mapping first we get the mapped time at the current frame - * Number then we need to convert mapped time to frame number using the - * composition time line Ex: at frame 10 the mappend time is 0.5(500 ms) which - * will be convert to frame number 30 if the frame rate is 60. or will result to - * frame number 15 if the frame rate is 30. - */ -inline int Layer::timeRemap(int frameNo) const -{ - /* - * only consider startFrame() when there is no timeRemap. - * when a layer has timeremap bodymovin updates the startFrame() - * of all child layer so we don't have to take care of it. - */ - if (!mExtra || mExtra->mTimeRemap.isStatic()) - frameNo = frameNo - startFrame(); - else - frameNo = - mExtra->mCompRef->frameAtTime(mExtra->mTimeRemap.value(frameNo)); - /* Apply time streatch if it has any. - * Time streatch is just a factor by which the animation will speedup or - * slow down with respect to the overal animation. Time streach factor is - * already applied to the layers inFrame and outFrame. - * @TODO need to find out if timestreatch also affects the in and out frame - * of the child layers or not. */ - return int(frameNo / mTimeStreatch); -} - -class Stroke : public Object { -public: - Stroke() : Object(Object::Type::Stroke) {} - Color color(int frameNo) const { return mColor.value(frameNo); } - float opacity(int frameNo) const - { - return mOpacity.value(frameNo) / 100.0f; - } - float strokeWidth(int frameNo) const { return mWidth.value(frameNo); } - CapStyle capStyle() const { return mCapStyle; } - JoinStyle joinStyle() const { return mJoinStyle; } - float miterLimit() const { return mMiterLimit; } - bool hasDashInfo() const { return !mDash.empty(); } - void getDashInfo(int frameNo, std::vector &result) const - { - return mDash.getDashInfo(frameNo, result); - } - -public: - Property mColor; /* "c" */ - Property mOpacity{100}; /* "o" */ - Property mWidth{0}; /* "w" */ - CapStyle mCapStyle{CapStyle::Flat}; /* "lc" */ - JoinStyle mJoinStyle{JoinStyle::Miter}; /* "lj" */ - float mMiterLimit{0}; /* "ml" */ - Dash mDash; - bool mEnabled{true}; /* "fillEnabled" */ -}; - -class Gradient : public Object { -public: - class Data { - public: - friend inline Gradient::Data operator+(const Gradient::Data &g1, - const Gradient::Data &g2); - friend inline Gradient::Data operator-(const Gradient::Data &g1, - const Gradient::Data &g2); - friend inline Gradient::Data operator*(float m, - const Gradient::Data &g); - - public: - std::vector mGradient; - }; - explicit Gradient(Object::Type type) : Object(type) {} - inline float opacity(int frameNo) const - { - return mOpacity.value(frameNo) / 100.0f; - } - void update(std::unique_ptr &grad, int frameNo); - -private: - void populate(VGradientStops &stops, int frameNo); - float getOpacityAtPosition(float *opacities, size_t opacityArraySize, float position); - -public: - int mGradientType{1}; /* "t" Linear=1 , Radial = 2*/ - Property mStartPoint; /* "s" */ - Property mEndPoint; /* "e" */ - Property mHighlightLength{0}; /* "h" */ - Property mHighlightAngle{0}; /* "a" */ - Property mOpacity{100}; /* "o" */ - Property mGradient; /* "g" */ - int mColorPoints{-1}; - bool mEnabled{true}; /* "fillEnabled" */ -}; - -class GradientStroke : public Gradient { -public: - GradientStroke() : Gradient(Object::Type::GStroke) {} - float width(int frameNo) const { return mWidth.value(frameNo); } - CapStyle capStyle() const { return mCapStyle; } - JoinStyle joinStyle() const { return mJoinStyle; } - float miterLimit() const { return mMiterLimit; } - bool hasDashInfo() const { return !mDash.empty(); } - void getDashInfo(int frameNo, std::vector &result) const - { - return mDash.getDashInfo(frameNo, result); - } - -public: - Property mWidth; /* "w" */ - CapStyle mCapStyle{CapStyle::Flat}; /* "lc" */ - JoinStyle mJoinStyle{JoinStyle::Miter}; /* "lj" */ - float mMiterLimit{0}; /* "ml" */ - Dash mDash; -}; - -class GradientFill : public Gradient { -public: - GradientFill() : Gradient(Object::Type::GFill) {} - FillRule fillRule() const { return mFillRule; } - -public: - FillRule mFillRule{FillRule::Winding}; /* "r" */ -}; - -class Fill : public Object { -public: - Fill() : Object(Object::Type::Fill) {} - Color color(int frameNo) const { return mColor.value(frameNo); } - float opacity(int frameNo) const - { - return mOpacity.value(frameNo) / 100.0f; - } - FillRule fillRule() const { return mFillRule; } - -public: - FillRule mFillRule{FillRule::Winding}; /* "r" */ - bool mEnabled{true}; /* "fillEnabled" */ - Property mColor; /* "c" */ - Property mOpacity{100}; /* "o" */ -}; - -class Shape : public Object { -public: - explicit Shape(Object::Type type) : Object(type) {} - VPath::Direction direction() - { - return (mDirection == 3) ? VPath::Direction::CCW : VPath::Direction::CW; - } - -public: - int mDirection{1}; -}; - -class Path : public Shape { -public: - Path() : Shape(Object::Type::Path) {} - -public: - Property mShape; -}; - -class RoundedCorner : public Object { -public: - RoundedCorner() : Object(Object::Type::RoundedCorner) {} - float radius(int frameNo) const { return mRadius.value(frameNo);} -public: - Property mRadius{0}; -}; - -class Rect : public Shape { -public: - Rect() : Shape(Object::Type::Rect) {} - float roundness(int frameNo) - { - return mRoundedCorner ? mRoundedCorner->radius(frameNo) : - mRound.value(frameNo); - } - - bool roundnessChanged(int prevFrame, int curFrame) - { - return mRoundedCorner ? mRoundedCorner->mRadius.changed(prevFrame, curFrame) : - mRound.changed(prevFrame, curFrame); - } -public: - RoundedCorner* mRoundedCorner{nullptr}; - Property mPos; - Property mSize; - Property mRound{0}; -}; - -class Ellipse : public Shape { -public: - Ellipse() : Shape(Object::Type::Ellipse) {} - -public: - Property mPos; - Property mSize; -}; - -class Polystar : public Shape { -public: - enum class PolyType { Star = 1, Polygon = 2 }; - Polystar() : Shape(Object::Type::Polystar) {} - -public: - Polystar::PolyType mPolyType{PolyType::Polygon}; - Property mPos; - Property mPointCount{0}; - Property mInnerRadius{0}; - Property mOuterRadius{0}; - Property mInnerRoundness{0}; - Property mOuterRoundness{0}; - Property mRotation{0}; -}; - -class Repeater : public Object { -public: - struct Transform { - VMatrix matrix(int frameNo, float multiplier) const; - float startOpacity(int frameNo) const - { - return mStartOpacity.value(frameNo) / 100; - } - float endOpacity(int frameNo) const - { - return mEndOpacity.value(frameNo) / 100; - } - bool isStatic() const - { - return mRotation.isStatic() && mScale.isStatic() && - mPosition.isStatic() && mAnchor.isStatic() && - mStartOpacity.isStatic() && mEndOpacity.isStatic(); - } - Property mRotation{0}; /* "r" */ - Property mScale{{100, 100}}; /* "s" */ - Property mPosition; /* "p" */ - Property mAnchor; /* "a" */ - Property mStartOpacity{100}; /* "so" */ - Property mEndOpacity{100}; /* "eo" */ - }; - Repeater() : Object(Object::Type::Repeater) {} - Group *content() const { return mContent ? mContent : nullptr; } - void setContent(Group *content) { mContent = content; } - int maxCopies() const { return int(mMaxCopies); } - float copies(int frameNo) const { return mCopies.value(frameNo); } - float offset(int frameNo) const { return mOffset.value(frameNo); } - bool processed() const { return mProcessed; } - void markProcessed() { mProcessed = true; } - -public: - Group * mContent{nullptr}; - Transform mTransform; - Property mCopies{0}; - Property mOffset{0}; - float mMaxCopies{0.0}; - bool mProcessed{false}; -}; - -class Trim : public Object { -public: - struct Segment { - float start{0}; - float end{0}; - Segment() = default; - explicit Segment(float s, float e) : start(s), end(e) {} - }; - enum class TrimType { Simultaneously, Individually }; - Trim() : Object(Object::Type::Trim) {} - - void updateTrimStartValue(float start) - { - mStart.value() = start; - } - - void updateTrimEndValue(VPointF pos) - { - for (auto &keyFrame : mEnd.animation().frames_) { - keyFrame.value_.start_ = pos.x(); - keyFrame.value_.end_ = pos.y(); - } - } - - /* - * if start > end vector trims the path as a loop ( 2 segment) - * if start < end vector trims the path without loop ( 1 segment). - * if no offset then there is no loop. - */ - Segment segment(int frameNo) const - { - float start = mStart.value(frameNo) / 100.0f; - float end = mEnd.value(frameNo) / 100.0f; - float offset = std::fmod(mOffset.value(frameNo), 360.0f) / 360.0f; - - float diff = std::abs(start - end); - if (vCompare(diff, 0.0f)) return Segment(0, 0); - if (vCompare(diff, 1.0f)) return Segment(0, 1); - - if (offset > 0) { - start += offset; - end += offset; - if (start <= 1 && end <= 1) { - return noloop(start, end); - } else if (start > 1 && end > 1) { - return noloop(start - 1, end - 1); - } else { - return (start > 1) ? loop(start - 1, end) - : loop(start, end - 1); - } - } else { - start += offset; - end += offset; - if (start >= 0 && end >= 0) { - return noloop(start, end); - } else if (start < 0 && end < 0) { - return noloop(1 + start, 1 + end); - } else { - return (start < 0) ? loop(1 + start, end) - : loop(start, 1 + end); - } - } - } - Trim::TrimType type() const { return mTrimType; } - -private: - Segment noloop(float start, float end) const - { - assert(start >= 0); - assert(end >= 0); - Segment s; - s.start = std::min(start, end); - s.end = std::max(start, end); - return s; - } - Segment loop(float start, float end) const - { - assert(start >= 0); - assert(end >= 0); - Segment s; - s.start = std::max(start, end); - s.end = std::min(start, end); - return s; - } - -public: - Property mStart{0}; - Property mEnd{0}; - Property mOffset{0}; - Trim::TrimType mTrimType{TrimType::Simultaneously}; -}; - -inline Gradient::Data operator+(const Gradient::Data &g1, - const Gradient::Data &g2) -{ - if (g1.mGradient.size() != g2.mGradient.size()) return g1; - - Gradient::Data newG; - newG.mGradient = g1.mGradient; - - auto g2It = g2.mGradient.begin(); - for (auto &i : newG.mGradient) { - i = i + *g2It; - g2It++; - } - - return newG; -} - -inline Gradient::Data operator-(const Gradient::Data &g1, - const Gradient::Data &g2) -{ - if (g1.mGradient.size() != g2.mGradient.size()) return g1; - Gradient::Data newG; - newG.mGradient = g1.mGradient; - - auto g2It = g2.mGradient.begin(); - for (auto &i : newG.mGradient) { - i = i - *g2It; - g2It++; - } - - return newG; -} - -inline Gradient::Data operator*(float m, const Gradient::Data &g) -{ - Gradient::Data newG; - newG.mGradient = g.mGradient; - - for (auto &i : newG.mGradient) { - i = i * m; - } - return newG; -} - -using ColorFilter = std::function; - -void configureModelCacheSize(size_t cacheSize); - -std::shared_ptr loadFromFile(const std::string &filePath, - bool cachePolicy); - -std::shared_ptr loadFromData(std::string jsonData, - const std::string &key, - std::string resourcePath, - bool cachePolicy); - -std::shared_ptr loadFromData(std::string jsonData, - std::string resourcePath, - ColorFilter filter); - -std::shared_ptr parse(char *str, size_t length, std::string dir_path, - ColorFilter filter = {}); - -} // namespace model - -} // namespace internal - -} // namespace rlottie - -#endif // LOTModel_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieparser.cpp b/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieparser.cpp deleted file mode 100644 index f54c3589..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieparser.cpp +++ /dev/null @@ -1,2572 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -//#define DEBUG_PARSER - -// This parser implements JSON token-by-token parsing with an API that is -// more direct; we don't have to create handler object and -// callbacks. Instead, we retrieve values from the JSON stream by calling -// GetInt(), GetDouble(), GetString() and GetBool(), traverse into structures -// by calling EnterObject() and EnterArray(), and skip over unwanted data by -// calling SkipValue(). As we know the lottie file structure this way will be -// the efficient way of parsing the file. -// -// If you aren't sure of what's next in the JSON data, you can use PeekType() -// and PeekValue() to look ahead to the next object before reading it. -// -// If you call the wrong retrieval method--e.g. GetInt when the next JSON token -// is not an int, EnterObject or EnterArray when there isn't actually an object -// or array to read--the stream parsing will end immediately and no more data -// will be delivered. -// -// After calling EnterObject, you retrieve keys via NextObjectKey() and values -// via the normal getters. When NextObjectKey() returns null, you have exited -// the object, or you can call SkipObject() to skip to the end of the object -// immediately. If you fetch the entire object (i.e. NextObjectKey() returned -// null), you should not call SkipObject(). -// -// After calling EnterArray(), you must alternate between calling -// NextArrayValue() to see if the array has more data, and then retrieving -// values via the normal getters. You can call SkipArray() to skip to the end of -// the array immediately. If you fetch the entire array (i.e. NextArrayValue() -// returned null), you should not call SkipArray(). -// -// This parser uses in-situ strings, so the JSON buffer will be altered during -// the parse. - -#include - -#include "lottiemodel.h" -#include "rapidjson/document.h" -#include "zip/zip.h" - -RAPIDJSON_DIAG_PUSH -#ifdef __GNUC__ -RAPIDJSON_DIAG_OFF(effc++) -#endif - -#ifdef _WIN32 -#include -#include - -#endif - -#ifndef PATH_MAX -#define PATH_MAX MAX_PATH -#endif - -using namespace rapidjson; - -using namespace rlottie::internal; - -class LookaheadParserHandler { -public: - bool Null() - { - st_ = kHasNull; - v_.SetNull(); - return true; - } - bool Bool(bool b) - { - st_ = kHasBool; - v_.SetBool(b); - return true; - } - bool Int(int i) - { - st_ = kHasNumber; - v_.SetInt(i); - return true; - } - bool Uint(unsigned u) - { - st_ = kHasNumber; - v_.SetUint(u); - return true; - } - bool Int64(int64_t i) - { - st_ = kHasNumber; - v_.SetInt64(i); - return true; - } - bool Uint64(int64_t u) - { - st_ = kHasNumber; - v_.SetUint64(u); - return true; - } - bool Double(double d) - { - st_ = kHasNumber; - v_.SetDouble(d); - return true; - } - bool RawNumber(const char *, SizeType, bool) { return false; } - bool String(const char *str, SizeType length, bool) - { - st_ = kHasString; - v_.SetString(str, length); - return true; - } - bool StartObject() - { - st_ = kEnteringObject; - return true; - } - bool Key(const char *str, SizeType length, bool) - { - st_ = kHasKey; - v_.SetString(str, length); - return true; - } - bool EndObject(SizeType) - { - st_ = kExitingObject; - return true; - } - bool StartArray() - { - st_ = kEnteringArray; - return true; - } - bool EndArray(SizeType) - { - st_ = kExitingArray; - return true; - } - - void Error() - { - st_ = kError; - } -protected: - explicit LookaheadParserHandler(char *str); - -protected: - enum LookaheadParsingState { - kInit, - kError, - kHasNull, - kHasBool, - kHasNumber, - kHasString, - kHasKey, - kEnteringObject, - kExitingObject, - kEnteringArray, - kExitingArray - }; - - Value v_; - LookaheadParsingState st_; - Reader r_; - InsituStringStream ss_; - - static const int parseFlags = kParseDefaultFlags | kParseInsituFlag; -}; - -class LottieParserImpl : public LookaheadParserHandler { -public: - LottieParserImpl(char *str, std::string dir_path, model::ColorFilter filter) - : LookaheadParserHandler(str), - mColorFilter(std::move(filter)), - mDirPath(std::move(dir_path)) - { - } - bool VerifyType(); - bool ParseNext(); - -public: - VArenaAlloc &allocator() { return compRef->mArenaAlloc; } - bool EnterObject(); - bool EnterArray(); - const char * NextObjectKey(); - bool NextArrayValue(); - int GetInt(); - double GetDouble(); - const char * GetString(); - std::string GetStringObject(); - bool GetBool(); - void GetNull(); - - void SkipObject(); - void SkipArray(); - void SkipValue(); - Value *PeekValue(); - int PeekType() const; - bool IsValid() { return st_ != kError; } - - void Skip(const char *key); - model::BlendMode getBlendMode(); - CapStyle getLineCap(); - JoinStyle getLineJoin(); - FillRule getFillRule(); - model::Trim::TrimType getTrimType(); - model::MatteType getMatteType(); - model::Layer::Type getLayerType(); - - std::shared_ptr composition() const - { - return mComposition; - } - void parseComposition(); - void parseMarkers(); - void parseMarker(); - void parseAssets(model::Composition *comp); - model::Asset * parseAsset(); - void parseLayers(model::Composition *comp); - model::Layer * parseLayer(); - void parseMaskProperty(model::Layer *layer); - void parseShapesAttr(model::Layer *layer); - void parseObject(model::Group *parent); - model::Mask * parseMaskObject(); - model::Object * parseObjectTypeAttr(); - model::Object * parseGroupObject(); - model::Rect * parseRectObject(); - model::RoundedCorner * parseRoundedCorner(); - void updateRoundedCorner(model::Group *parent, model::RoundedCorner *rc); - - model::Ellipse * parseEllipseObject(); - model::Path * parseShapeObject(); - model::Polystar *parsePolystarObject(); - - model::Transform * parseTransformObject(bool ddd = false); - model::Fill * parseFillObject(); - model::GradientFill * parseGFillObject(); - model::Stroke * parseStrokeObject(); - model::GradientStroke *parseGStrokeObject(); - model::Trim * parseTrimObject(); - model::Repeater * parseReapeaterObject(); - - void parseGradientProperty(model::Gradient *gradient, const char *key); - - VPointF parseInperpolatorPoint(); - - void getValue(VPointF &pt); - void getValue(float &fval); - void getValue(model::Color &color); - void getValue(int &ival); - void getValue(model::PathData &shape); - void getValue(model::Gradient::Data &gradient); - void getValue(std::vector &v); - void getValue(model::Repeater::Transform &); - - template - bool parseKeyFrameValue(const char *, model::Value &) - { - return false; - } - - template - bool parseKeyFrameValue(const char * key, - model::Value &value); - template - void parseKeyFrame(model::KeyFrames &obj); - template - void parseProperty(model::Property &obj); - template - void parsePropertyHelper(model::Property &obj); - - void parseShapeProperty(model::Property &obj); - void parseDashProperty(model::Dash &dash); - - VInterpolator *interpolator(VPointF, VPointF, std::string); - - model::Color toColor(const char *str); - - void resolveLayerRefs(); - void parsePathInfo(); - -private: - model::ColorFilter mColorFilter; - struct { - std::vector mInPoint; /* "i" */ - std::vector mOutPoint; /* "o" */ - std::vector mVertices; /* "v" */ - std::vector mResult; - bool mClosed{false}; - - void convert() - { - // shape data could be empty. - if (mInPoint.empty() || mOutPoint.empty() || mVertices.empty()) { - mResult.clear(); - return; - } - - /* - * Convert the AE shape format to - * list of bazier curves - * The final structure will be Move +size*Cubic + Cubic (if the path - * is closed one) - */ - if (mInPoint.size() != mOutPoint.size() || - mInPoint.size() != mVertices.size()) { - mResult.clear(); - } else { - auto size = mVertices.size(); - mResult.push_back(mVertices[0]); - for (size_t i = 1; i < size; i++) { - mResult.push_back( - mVertices[i - 1] + - mOutPoint[i - 1]); // CP1 = start + outTangent - mResult.push_back(mVertices[i] + - mInPoint[i]); // CP2 = end + inTangent - mResult.push_back(mVertices[i]); // end point - } - - if (mClosed) { - mResult.push_back( - mVertices[size - 1] + - mOutPoint[size - 1]); // CP1 = start + outTangent - mResult.push_back(mVertices[0] + - mInPoint[0]); // CP2 = end + inTangent - mResult.push_back(mVertices[0]); // end point - } - } - } - void reset() - { - mInPoint.clear(); - mOutPoint.clear(); - mVertices.clear(); - mResult.clear(); - mClosed = false; - } - void updatePath(VPath &out) - { - if (mResult.empty()) return; - - auto size = mResult.size(); - auto points = mResult.data(); - /* reserve exact memory requirement at once - * ptSize = size + 1(size + close) - * elmSize = size/3 cubic + 1 move + 1 close - */ - out.reserve(size + 1, size / 3 + 2); - out.moveTo(points[0]); - for (size_t i = 1; i < size; i += 3) { - out.cubicTo(points[i], points[i + 1], points[i + 2]); - } - if (mClosed) out.close(); - } - } mPathInfo; - -protected: - std::unordered_map mInterpolatorCache; - std::shared_ptr mComposition; - model::Composition * compRef{nullptr}; - model::Layer * curLayerRef{nullptr}; - std::vector mLayersToUpdate; - std::string mDirPath; - void SkipOut(int depth); -}; - -LookaheadParserHandler::LookaheadParserHandler(char *str) - : v_(), st_(kInit), ss_(str) -{ - r_.IterativeParseInit(); -} - -bool LottieParserImpl::VerifyType() -{ - /* Verify the media type is lottie json. - Could add more strict check. */ - return ParseNext(); -} - -bool LottieParserImpl::ParseNext() -{ - if (r_.HasParseError()) { - st_ = kError; - return false; - } - - if (!r_.IterativeParseNext(ss_, *this)) { - vCritical << "Lottie file parsing error"; - st_ = kError; - return false; - } - return true; -} - -bool LottieParserImpl::EnterObject() -{ - if (st_ != kEnteringObject) { - st_ = kError; - return false; - } - - ParseNext(); - return true; -} - -bool LottieParserImpl::EnterArray() -{ - if (st_ != kEnteringArray) { - st_ = kError; - return false; - } - - ParseNext(); - return true; -} - -const char *LottieParserImpl::NextObjectKey() -{ - if (st_ == kHasKey) { - const char *result = v_.GetString(); - ParseNext(); - return result; - } - - /* SPECIAL CASE - * The parser works with a prdefined rule that it will be only - * while (NextObjectKey()) for each object but in case of our nested group - * object we can call multiple time NextObjectKey() while exiting the object - * so ignore those and don't put parser in the error state. - * */ - if (st_ == kExitingArray || st_ == kEnteringObject) { - // #ifdef DEBUG_PARSER - // vDebug<<"Object: Exiting nested loop"; - // #endif - return nullptr; - } - - if (st_ != kExitingObject) { - st_ = kError; - return nullptr; - } - - ParseNext(); - return nullptr; -} - -bool LottieParserImpl::NextArrayValue() -{ - if (st_ == kExitingArray) { - ParseNext(); - return false; - } - - /* SPECIAL CASE - * same as NextObjectKey() - */ - if (st_ == kExitingObject) { - return false; - } - - if (st_ == kError || st_ == kHasKey) { - st_ = kError; - return false; - } - - return true; -} - -int LottieParserImpl::GetInt() -{ - if (st_ != kHasNumber || !v_.IsInt()) { - st_ = kError; - return 0; - } - - int result = v_.GetInt(); - ParseNext(); - return result; -} - -double LottieParserImpl::GetDouble() -{ - if (st_ != kHasNumber) { - st_ = kError; - return 0.; - } - - double result = v_.GetDouble(); - ParseNext(); - return result; -} - -bool LottieParserImpl::GetBool() -{ - if (st_ != kHasBool) { - st_ = kError; - return false; - } - - bool result = v_.GetBool(); - ParseNext(); - return result; -} - -void LottieParserImpl::GetNull() -{ - if (st_ != kHasNull) { - st_ = kError; - return; - } - - ParseNext(); -} - -const char *LottieParserImpl::GetString() -{ - if (st_ != kHasString) { - st_ = kError; - return nullptr; - } - - const char *result = v_.GetString(); - ParseNext(); - return result; -} - -std::string LottieParserImpl::GetStringObject() -{ - auto str = GetString(); - - if (str) { - return std::string(str); - } - - return {}; -} - -void LottieParserImpl::SkipOut(int depth) -{ - do { - if (st_ == kEnteringArray || st_ == kEnteringObject) { - ++depth; - } else if (st_ == kExitingArray || st_ == kExitingObject) { - --depth; - } else if (st_ == kError) { - return; - } - - ParseNext(); - } while (depth > 0); -} - -void LottieParserImpl::SkipValue() -{ - SkipOut(0); -} - -void LottieParserImpl::SkipArray() -{ - SkipOut(1); -} - -void LottieParserImpl::SkipObject() -{ - SkipOut(1); -} - -Value *LottieParserImpl::PeekValue() -{ - if (st_ >= kHasNull && st_ <= kHasKey) { - return &v_; - } - - return nullptr; -} - -// returns a rapidjson::Type, or -1 for no value (at end of -// object/array) -int LottieParserImpl::PeekType() const -{ - if (st_ >= kHasNull && st_ <= kHasKey) { - return v_.GetType(); - } - - if (st_ == kEnteringArray) { - return kArrayType; - } - - if (st_ == kEnteringObject) { - return kObjectType; - } - - return -1; -} - -void LottieParserImpl::Skip(const char * /*key*/) -{ - if (PeekType() == kArrayType) { - EnterArray(); - SkipArray(); - } else if (PeekType() == kObjectType) { - EnterObject(); - SkipObject(); - } else { - SkipValue(); - } -} - -model::BlendMode LottieParserImpl::getBlendMode() -{ - auto mode = model::BlendMode::Normal; - - switch (GetInt()) { - case 1: - mode = model::BlendMode::Multiply; - break; - case 2: - mode = model::BlendMode::Screen; - break; - case 3: - mode = model::BlendMode::OverLay; - break; - default: - break; - } - return mode; -} - -void LottieParserImpl::resolveLayerRefs() -{ - for (const auto &layer : mLayersToUpdate) { - auto search = compRef->mAssets.find(layer->extra()->mPreCompRefId); - if (search != compRef->mAssets.end()) { - if (layer->mLayerType == model::Layer::Type::Image) { - layer->extra()->mAsset = search->second; - } else if (layer->mLayerType == model::Layer::Type::Precomp) { - layer->mChildren = search->second->mLayers; - layer->setStatic(layer->isStatic() && - search->second->isStatic()); - } - } - } -} - -void LottieParserImpl::parseComposition() -{ - EnterObject(); - std::shared_ptr sharedComposition = - std::make_shared(); - model::Composition *comp = sharedComposition.get(); - compRef = comp; - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "v")) { - comp->mVersion = GetStringObject(); - } else if (0 == strcmp(key, "w")) { - comp->mSize.setWidth(GetInt()); - } else if (0 == strcmp(key, "h")) { - comp->mSize.setHeight(GetInt()); - } else if (0 == strcmp(key, "ip")) { - comp->mStartFrame = std::lround(GetDouble()); - } else if (0 == strcmp(key, "op")) { - comp->mEndFrame = std::lround(GetDouble()); - } else if (0 == strcmp(key, "fr")) { - comp->mFrameRate = GetDouble(); - } else if (0 == strcmp(key, "assets")) { - parseAssets(comp); - } else if (0 == strcmp(key, "layers")) { - parseLayers(comp); - } else if (0 == strcmp(key, "markers")) { - parseMarkers(); - } else { -#ifdef DEBUG_PARSER - vWarning << "Composition Attribute Skipped : " << key; -#endif - Skip(key); - } - } - - if (comp->mVersion.empty() || !comp->mRootLayer) { - // don't have a valid bodymovin header - return; - } - if (comp->mStartFrame > comp->mEndFrame) { - // reveresed animation? missing data? - return; - } - if (!IsValid()) { - return; - } - - resolveLayerRefs(); - comp->setStatic(comp->mRootLayer->isStatic()); - comp->mRootLayer->mInFrame = comp->mStartFrame; - comp->mRootLayer->mOutFrame = comp->mEndFrame; - - mComposition = sharedComposition; -} - -void LottieParserImpl::parseMarker() -{ - EnterObject(); - std::string comment; - int timeframe{0}; - int duration{0}; - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "cm")) { - comment = GetStringObject(); - } else if (0 == strcmp(key, "tm")) { - timeframe = GetDouble(); - } else if (0 == strcmp(key, "dr")) { - duration = GetDouble(); - - } else { -#ifdef DEBUG_PARSER - vWarning << "Marker Attribute Skipped : " << key; -#endif - Skip(key); - } - } - compRef->mMarkers.emplace_back(std::move(comment), timeframe, - timeframe + duration); -} - -void LottieParserImpl::parseMarkers() -{ - EnterArray(); - while (NextArrayValue()) { - parseMarker(); - } - // update the precomp layers with the actual layer object -} - -void LottieParserImpl::parseAssets(model::Composition *composition) -{ - EnterArray(); - while (NextArrayValue()) { - auto asset = parseAsset(); - composition->mAssets[asset->mRefId] = asset; - } - // update the precomp layers with the actual layer object -} - -static constexpr const unsigned char B64index[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 62, 63, 62, 62, 63, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 0, 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51}; - -std::string b64decode(const char *data, const size_t len) -{ - auto p = reinterpret_cast(data); - int pad = len > 0 && (len % 4 || p[len - 1] == '='); - const size_t L = ((len + 3) / 4 - pad) * 4; - std::string str(L / 4 * 3 + pad, '\0'); - - for (size_t i = 0, j = 0; i < L; i += 4) { - int n = B64index[p[i]] << 18 | B64index[p[i + 1]] << 12 | - B64index[p[i + 2]] << 6 | B64index[p[i + 3]]; - str[j++] = n >> 16; - str[j++] = n >> 8 & 0xFF; - str[j++] = n & 0xFF; - } - if (pad) { - int n = B64index[p[L]] << 18 | B64index[p[L + 1]] << 12; - str[str.size() - 1] = n >> 16; - - if (len > L + 2 && p[L + 2] != '=') { - n |= B64index[p[L + 2]] << 6; - str.push_back(n >> 8 & 0xFF); - } - } - return str; -} - -static std::string convertFromBase64(const std::string &str) -{ - // usual header look like "data:image/png;base64," - // so need to skip till ','. - size_t startIndex = str.find(",", 0); - startIndex += 1; // skip "," - size_t length = str.length() - startIndex; - - const char *b64Data = str.c_str() + startIndex; - - return b64decode(b64Data, length); -} - -namespace -{ - #ifdef _WIN32 - std::wstring ToStdWString( const std::string& str ) - { - std::wstring wstr; - int nchars = ::MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.length(), 0, 0); - if ( nchars > 0 ) - { - wstr.resize( nchars ); - ::MultiByteToWideChar( CP_UTF8, 0, str.data(), (int)str.length(), - const_cast( wstr.c_str() ), - nchars ); - } - - return wstr; - } - - std::string ToStdString( const std::wstring& wstr ) - { - std::string str; - int nchars = ::WideCharToMultiByte( CP_UTF8, 0, wstr.data(), (int)wstr.length(), NULL, NULL, NULL, NULL ); - if ( nchars > 0 ) - { - str.resize(nchars); - ::WideCharToMultiByte( CP_UTF8, 0, wstr.data(), (int)wstr.length(), - const_cast(str.c_str()), nchars, NULL, NULL ); - } - - return str; - } - #endif - - bool Canonicalize(const char *path, char *resolved_path) - { -#ifdef _WIN32 - std::wstring wpath = ToStdWString( path ); - std::wstring wresolved_path; - wresolved_path.resize( PATH_MAX ); - if ( PathCanonicalizeW( const_cast(wresolved_path.data()), wpath.c_str() ) ) - { - std::string path = ToStdString(wresolved_path); - strcpy_s( resolved_path, path.length() * sizeof( char ), path.c_str() ); - - return true; - } - - return false; -#else - return realpath(path, resolved_path); -#endif - } -} - -static bool isResourcePathSafe(const std::string& baseDir, const std::string& userPath) -{ - char resolvedBase[PATH_MAX] = {}; - char resolvedTarget[PATH_MAX] = {}; - - // Resolve base directory - if (!Canonicalize(baseDir.c_str(), resolvedBase)) - { - -#ifdef DEBUG_PARSER - vWarning << "Error: Cannot resolve base path: " << baseDir.c_str(); -#endif - return false; - } - - // Resolve target path - std::string fullPath = baseDir; - if (!baseDir.empty() && baseDir.back() != '/') fullPath += "/"; - fullPath += userPath; - - if (!Canonicalize(fullPath.c_str(), resolvedTarget)) { -#ifdef DEBUG_PARSER - vWarning << "Error: Cannot resolve target path: " << fullPath.c_str(); -#endif - return false; - } - - std::string base(resolvedBase); - std::string target(resolvedTarget); - - // Ensure target starts with base - bool result = target.compare(0, base.length(), base) == 0 && - (target.length() == base.length() || target[base.length()] == '/'); - - if (!result) { -#ifdef DEBUG_PARSER - vWarning << "Error: Dangerous path blocked: " << fullPath.c_str(); -#endif - } - return result; -} - -/* - * std::to_string() function is missing in VS2017 - * so this is workaround for windows build - */ -#include -template -static std::string toString(const T &value) -{ - std::ostringstream os; - os << value; - return os.str(); -} - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/layers/shape.json - * - */ -model::Asset *LottieParserImpl::parseAsset() -{ - auto asset = allocator().make(); - std::string filename; - std::string relativePath; - bool embeddedResource = false; - EnterObject(); - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "w")) { - asset->mWidth = GetInt(); - } else if (0 == strcmp(key, "h")) { - asset->mHeight = GetInt(); - } else if (0 == strcmp(key, "p")) { /* image name */ - asset->mAssetType = model::Asset::Type::Image; - filename = GetStringObject(); - } else if (0 == strcmp(key, "u")) { /* relative image path */ - relativePath = GetStringObject(); - } else if (0 == strcmp(key, "e")) { /* relative image path */ - embeddedResource = GetInt(); - } else if (0 == strcmp(key, "id")) { /* reference id*/ - if (PeekType() == kStringType) { - asset->mRefId = GetStringObject(); - } else { - asset->mRefId = toString(GetInt()); - } - } else if (0 == strcmp(key, "layers")) { - asset->mAssetType = model::Asset::Type::Precomp; - EnterArray(); - bool staticFlag = true; - while (NextArrayValue()) { - auto layer = parseLayer(); - if (layer) { - staticFlag = staticFlag && layer->isStatic(); - asset->mLayers.push_back(layer); - } - } - asset->setStatic(staticFlag); - } else { -#ifdef DEBUG_PARSER - vWarning << "Asset Attribute Skipped : " << key; -#endif - Skip(key); - } - } - - if (asset->mAssetType == model::Asset::Type::Image && !filename.empty()) { - if (embeddedResource) { - // embedded resource should start with "data:" - // URL Scheme: "data:[][;base64]," - if (filename.compare(0, 5, "data:") == 0 && filename.find(',') != std::string::npos) { - asset->loadImageData(convertFromBase64(filename)); - } - } else { - // reject dangerous paths - if (isResourcePathSafe(mDirPath, relativePath + filename)) { - asset->loadImagePath(mDirPath + relativePath + filename); - } - } - } - - return asset; -} - -void LottieParserImpl::parseLayers(model::Composition *comp) -{ - comp->mRootLayer = allocator().make(); - comp->mRootLayer->mLayerType = model::Layer::Type::Precomp; - comp->mRootLayer->setName("__"); - bool staticFlag = true; - EnterArray(); - while (NextArrayValue()) { - auto layer = parseLayer(); - if (layer) { - staticFlag = staticFlag && layer->isStatic(); - comp->mRootLayer->mChildren.push_back(layer); - } - } - comp->mRootLayer->setStatic(staticFlag); -} - -model::Color LottieParserImpl::toColor(const char *str) -{ - if (!str) return {}; - - model::Color color; - auto len = strlen(str); - - // some resource has empty color string - // return a default color for those cases. - if (len != 7 || str[0] != '#') return color; - - char tmp[3] = {'\0', '\0', '\0'}; - tmp[0] = str[1]; - tmp[1] = str[2]; - color.r = std::strtol(tmp, nullptr, 16) / 255.0f; - - tmp[0] = str[3]; - tmp[1] = str[4]; - color.g = std::strtol(tmp, nullptr, 16) / 255.0f; - - tmp[0] = str[5]; - tmp[1] = str[6]; - color.b = std::strtol(tmp, nullptr, 16) / 255.0f; - - return color; -} - -model::MatteType LottieParserImpl::getMatteType() -{ - switch (GetInt()) { - case 1: - return model::MatteType::Alpha; - break; - case 2: - return model::MatteType::AlphaInv; - break; - case 3: - return model::MatteType::Luma; - break; - case 4: - return model::MatteType::LumaInv; - break; - default: - return model::MatteType::None; - break; - } -} - -model::Layer::Type LottieParserImpl::getLayerType() -{ - switch (GetInt()) { - case 0: - return model::Layer::Type::Precomp; - break; - case 1: - return model::Layer::Type::Solid; - break; - case 2: - return model::Layer::Type::Image; - break; - case 3: - return model::Layer::Type::Null; - break; - case 4: - return model::Layer::Type::Shape; - break; - case 5: - return model::Layer::Type::Text; - break; - default: - return model::Layer::Type::Null; - break; - } -} - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/layers/shape.json - * - */ -model::Layer *LottieParserImpl::parseLayer() -{ - model::Layer *layer = allocator().make(); - curLayerRef = layer; - bool ddd = true; - EnterObject(); - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "ty")) { /* Type of layer*/ - layer->mLayerType = getLayerType(); - } else if (0 == strcmp(key, "nm")) { /*Layer name*/ - layer->setName(GetString()); - } else if (0 == strcmp(key, "ind")) { /*Layer index in AE. Used for - parenting and expressions.*/ - layer->mId = GetInt(); - } else if (0 == strcmp(key, "ddd")) { /*3d layer */ - ddd = GetInt(); - } else if (0 == - strcmp(key, - "parent")) { /*Layer Parent. Uses "ind" of parent.*/ - layer->mParentId = GetInt(); - } else if (0 == strcmp(key, "refId")) { /*preComp Layer reference id*/ - layer->extra()->mPreCompRefId = GetStringObject(); - layer->mHasGradient = true; - mLayersToUpdate.push_back(layer); - } else if (0 == strcmp(key, "sr")) { // "Layer Time Stretching" - layer->mTimeStreatch = GetDouble(); - } else if (0 == strcmp(key, "tm")) { // time remapping - parseProperty(layer->extra()->mTimeRemap); - } else if (0 == strcmp(key, "ip")) { - layer->mInFrame = std::lround(GetDouble()); - } else if (0 == strcmp(key, "op")) { - layer->mOutFrame = std::lround(GetDouble()); - } else if (0 == strcmp(key, "st")) { - layer->mStartFrame = GetDouble(); - } else if (0 == strcmp(key, "bm")) { - layer->mBlendMode = getBlendMode(); - } else if (0 == strcmp(key, "ks")) { - EnterObject(); - layer->mTransform = parseTransformObject(ddd); - } else if (0 == strcmp(key, "shapes")) { - parseShapesAttr(layer); - } else if (0 == strcmp(key, "w")) { - layer->mLayerSize.setWidth(GetInt()); - } else if (0 == strcmp(key, "h")) { - layer->mLayerSize.setHeight(GetInt()); - } else if (0 == strcmp(key, "sw")) { - layer->mLayerSize.setWidth(GetInt()); - } else if (0 == strcmp(key, "sh")) { - layer->mLayerSize.setHeight(GetInt()); - } else if (0 == strcmp(key, "sc")) { - layer->extra()->mSolidColor = toColor(GetString()); - } else if (0 == strcmp(key, "tt")) { - layer->mMatteType = getMatteType(); - } else if (0 == strcmp(key, "hasMask")) { - layer->mHasMask = GetBool(); - } else if (0 == strcmp(key, "masksProperties")) { - parseMaskProperty(layer); - } else if (0 == strcmp(key, "ao")) { - layer->mAutoOrient = GetInt(); - } else if (0 == strcmp(key, "hd")) { - layer->setHidden(GetBool()); - } else { -#ifdef DEBUG_PARSER - vWarning << "Layer Attribute Skipped : " << key; -#endif - Skip(key); - } - } - - if (!layer->mTransform) { - // not a valid layer - return nullptr; - } - - // make sure layer data is not corrupted. - if (layer->hasParent() && (layer->id() == layer->parentId())) - return nullptr; - - if (layer->mExtra) layer->mExtra->mCompRef = compRef; - - if (layer->hidden()) { - // if layer is hidden, only data that is usefull is its - // transform matrix(when it is a parent of some other layer) - // so force it to be a Null Layer and release all resource. - layer->setStatic(layer->mTransform->isStatic()); - layer->mLayerType = model::Layer::Type::Null; - layer->mChildren = {}; - return layer; - } - - // update the static property of layer - bool staticFlag = true; - for (const auto &child : layer->mChildren) { - staticFlag &= child->isStatic(); - } - - if (layer->hasMask() && layer->mExtra) { - for (const auto &mask : layer->mExtra->mMasks) { - staticFlag &= mask->isStatic(); - } - } - - layer->setStatic(staticFlag && layer->mTransform->isStatic()); - - return layer; -} - -void LottieParserImpl::parseMaskProperty(model::Layer *layer) -{ - EnterArray(); - while (NextArrayValue()) { - layer->extra()->mMasks.push_back(parseMaskObject()); - } -} - -model::Mask *LottieParserImpl::parseMaskObject() -{ - auto obj = allocator().make(); - - EnterObject(); - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "inv")) { - obj->mInv = GetBool(); - } else if (0 == strcmp(key, "mode")) { - const char *str = GetString(); - if (!str) { - obj->mMode = model::Mask::Mode::None; - continue; - } - switch (str[0]) { - case 'n': - obj->mMode = model::Mask::Mode::None; - break; - case 'a': - obj->mMode = model::Mask::Mode::Add; - break; - case 's': - obj->mMode = model::Mask::Mode::Substarct; - break; - case 'i': - obj->mMode = model::Mask::Mode::Intersect; - break; - case 'f': - obj->mMode = model::Mask::Mode::Difference; - break; - default: - obj->mMode = model::Mask::Mode::None; - break; - } - } else if (0 == strcmp(key, "pt")) { - parseShapeProperty(obj->mShape); - } else if (0 == strcmp(key, "o")) { - parseProperty(obj->mOpacity); - } else { - Skip(key); - } - } - obj->mIsStatic = obj->mShape.isStatic() && obj->mOpacity.isStatic(); - return obj; -} - -void LottieParserImpl::parseShapesAttr(model::Layer *layer) -{ - EnterArray(); - while (NextArrayValue()) { - parseObject(layer); - } -} - -model::Object *LottieParserImpl::parseObjectTypeAttr() -{ - const char *type = GetString(); - if (!type) { - vWarning << "No object type specified"; - return nullptr; - } - if (0 == strcmp(type, "gr")) { - return parseGroupObject(); - } else if (0 == strcmp(type, "rc")) { - return parseRectObject(); - } else if (0 == strcmp(type, "rd")) { - curLayerRef->mHasRoundedCorner = true; - return parseRoundedCorner(); - } else if (0 == strcmp(type, "el")) { - return parseEllipseObject(); - } else if (0 == strcmp(type, "tr")) { - return parseTransformObject(); - } else if (0 == strcmp(type, "fl")) { - return parseFillObject(); - } else if (0 == strcmp(type, "st")) { - return parseStrokeObject(); - } else if (0 == strcmp(type, "gf")) { - curLayerRef->mHasGradient = true; - return parseGFillObject(); - } else if (0 == strcmp(type, "gs")) { - curLayerRef->mHasGradient = true; - return parseGStrokeObject(); - } else if (0 == strcmp(type, "sh")) { - return parseShapeObject(); - } else if (0 == strcmp(type, "sr")) { - return parsePolystarObject(); - } else if (0 == strcmp(type, "tm")) { - curLayerRef->mHasPathOperator = true; - return parseTrimObject(); - } else if (0 == strcmp(type, "rp")) { - curLayerRef->mHasRepeater = true; - return parseReapeaterObject(); - } else if (0 == strcmp(type, "mm")) { - vWarning << "Merge Path is not supported yet"; - return nullptr; - } else { -#ifdef DEBUG_PARSER - vDebug << "The Object Type not yet handled = " << type; -#endif - return nullptr; - } -} - -void LottieParserImpl::parseObject(model::Group *parent) -{ - EnterObject(); - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "ty")) { - auto child = parseObjectTypeAttr(); - if (child && !child->hidden()) { - if (child->type() == model::Object::Type::RoundedCorner) { - updateRoundedCorner(parent, static_cast(child)); - } - parent->mChildren.push_back(child); - } - } else { - Skip(key); - } - } -} - -void LottieParserImpl::updateRoundedCorner(model::Group *group, model::RoundedCorner *rc) -{ - for(auto &e : group->mChildren) - { - if (e->type() == model::Object::Type::Rect) { - static_cast(e)->mRoundedCorner = rc; - if (!rc->isStatic()) { - e->setStatic(false); - group->setStatic(false); - //@TODO need to propagate. - } - } else if ( e->type() == model::Object::Type::Group) { - updateRoundedCorner(static_cast(e), rc); - } - } -} - -model::Object *LottieParserImpl::parseGroupObject() -{ - auto group = allocator().make(); - - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "nm")) { - group->setName(GetString()); - } else if (0 == strcmp(key, "it")) { - EnterArray(); - while (NextArrayValue()) { - parseObject(group); - } - if (!group->mChildren.empty() - && group->mChildren.back()->type() - == model::Object::Type::Transform) { - group->mTransform = - static_cast(group->mChildren.back()); - group->mChildren.pop_back(); - } - } else { - Skip(key); - } - } - bool staticFlag = true; - for (const auto &child : group->mChildren) { - staticFlag &= child->isStatic(); - } - - if (group->mTransform) { - group->setStatic(staticFlag && group->mTransform->isStatic()); - } - - return group; -} - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/rect.json - */ -model::Rect *LottieParserImpl::parseRectObject() -{ - auto obj = allocator().make(); - - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "nm")) { - obj->setName(GetString()); - } else if (0 == strcmp(key, "p")) { - parseProperty(obj->mPos); - } else if (0 == strcmp(key, "s")) { - parseProperty(obj->mSize); - } else if (0 == strcmp(key, "r")) { - parseProperty(obj->mRound); - } else if (0 == strcmp(key, "d")) { - obj->mDirection = GetInt(); - } else if (0 == strcmp(key, "hd")) { - obj->setHidden(GetBool()); - } else { - Skip(key); - } - } - obj->setStatic(obj->mPos.isStatic() && obj->mSize.isStatic() && - obj->mRound.isStatic()); - return obj; -} - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/rect.json - */ -model::RoundedCorner *LottieParserImpl::parseRoundedCorner() -{ - auto obj = allocator().make(); - - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "nm")) { - obj->setName(GetString()); - } else if (0 == strcmp(key, "r")) { - parseProperty(obj->mRadius); - } else if (0 == strcmp(key, "hd")) { - obj->setHidden(GetBool()); - } else { - Skip(key); - } - } - obj->setStatic(obj->mRadius.isStatic()); - return obj; -} - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/ellipse.json - */ -model::Ellipse *LottieParserImpl::parseEllipseObject() -{ - auto obj = allocator().make(); - - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "nm")) { - obj->setName(GetString()); - } else if (0 == strcmp(key, "p")) { - parseProperty(obj->mPos); - } else if (0 == strcmp(key, "s")) { - parseProperty(obj->mSize); - } else if (0 == strcmp(key, "d")) { - obj->mDirection = GetInt(); - } else if (0 == strcmp(key, "hd")) { - obj->setHidden(GetBool()); - } else { - Skip(key); - } - } - obj->setStatic(obj->mPos.isStatic() && obj->mSize.isStatic()); - return obj; -} - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/shape.json - */ -model::Path *LottieParserImpl::parseShapeObject() -{ - auto obj = allocator().make(); - - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "nm")) { - obj->setName(GetString()); - } else if (0 == strcmp(key, "ks")) { - parseShapeProperty(obj->mShape); - } else if (0 == strcmp(key, "d")) { - obj->mDirection = GetInt(); - } else if (0 == strcmp(key, "hd")) { - obj->setHidden(GetBool()); - } else { -#ifdef DEBUG_PARSER - vDebug << "Shape property ignored :" << key; -#endif - Skip(key); - } - } - obj->setStatic(obj->mShape.isStatic()); - - return obj; -} - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/star.json - */ -model::Polystar *LottieParserImpl::parsePolystarObject() -{ - auto obj = allocator().make(); - - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "nm")) { - obj->setName(GetString()); - } else if (0 == strcmp(key, "p")) { - parseProperty(obj->mPos); - } else if (0 == strcmp(key, "pt")) { - parseProperty(obj->mPointCount); - } else if (0 == strcmp(key, "ir")) { - parseProperty(obj->mInnerRadius); - } else if (0 == strcmp(key, "is")) { - parseProperty(obj->mInnerRoundness); - } else if (0 == strcmp(key, "or")) { - parseProperty(obj->mOuterRadius); - } else if (0 == strcmp(key, "os")) { - parseProperty(obj->mOuterRoundness); - } else if (0 == strcmp(key, "r")) { - parseProperty(obj->mRotation); - } else if (0 == strcmp(key, "sy")) { - int starType = GetInt(); - if (starType == 1) obj->mPolyType = model::Polystar::PolyType::Star; - if (starType == 2) - obj->mPolyType = model::Polystar::PolyType::Polygon; - } else if (0 == strcmp(key, "d")) { - obj->mDirection = GetInt(); - } else if (0 == strcmp(key, "hd")) { - obj->setHidden(GetBool()); - } else { -#ifdef DEBUG_PARSER - vDebug << "Polystar property ignored :" << key; -#endif - Skip(key); - } - } - obj->setStatic( - obj->mPos.isStatic() && obj->mPointCount.isStatic() && - obj->mInnerRadius.isStatic() && obj->mInnerRoundness.isStatic() && - obj->mOuterRadius.isStatic() && obj->mOuterRoundness.isStatic() && - obj->mRotation.isStatic()); - - return obj; -} - -model::Trim::TrimType LottieParserImpl::getTrimType() -{ - switch (GetInt()) { - case 1: - return model::Trim::TrimType::Simultaneously; - break; - case 2: - return model::Trim::TrimType::Individually; - break; - default: - Error(); - return model::Trim::TrimType::Simultaneously; - break; - } -} - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/trim.json - */ -model::Trim *LottieParserImpl::parseTrimObject() -{ - auto obj = allocator().make(); - - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "nm")) { - obj->setName(GetString()); - } else if (0 == strcmp(key, "s")) { - parseProperty(obj->mStart); - } else if (0 == strcmp(key, "e")) { - parseProperty(obj->mEnd); - } else if (0 == strcmp(key, "o")) { - parseProperty(obj->mOffset); - } else if (0 == strcmp(key, "m")) { - obj->mTrimType = getTrimType(); - } else if (0 == strcmp(key, "hd")) { - obj->setHidden(GetBool()); - } else { -#ifdef DEBUG_PARSER - vDebug << "Trim property ignored :" << key; -#endif - Skip(key); - } - } - obj->setStatic(obj->mStart.isStatic() && obj->mEnd.isStatic() && - obj->mOffset.isStatic()); - return obj; -} - -void LottieParserImpl::getValue(model::Repeater::Transform &obj) -{ - EnterObject(); - - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "a")) { - parseProperty(obj.mAnchor); - } else if (0 == strcmp(key, "p")) { - parseProperty(obj.mPosition); - } else if (0 == strcmp(key, "r")) { - parseProperty(obj.mRotation); - } else if (0 == strcmp(key, "s")) { - parseProperty(obj.mScale); - } else if (0 == strcmp(key, "so")) { - parseProperty(obj.mStartOpacity); - } else if (0 == strcmp(key, "eo")) { - parseProperty(obj.mEndOpacity); - } else { - Skip(key); - } - } -} - -model::Repeater *LottieParserImpl::parseReapeaterObject() -{ - auto obj = allocator().make(); - - obj->setContent(allocator().make()); - - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "nm")) { - obj->setName(GetString()); - } else if (0 == strcmp(key, "c")) { - parseProperty(obj->mCopies); - float maxCopy = 0.0; - if (!obj->mCopies.isStatic()) { - for (auto &keyFrame : obj->mCopies.animation().frames_) { - if (maxCopy < keyFrame.value_.start_) - maxCopy = keyFrame.value_.start_; - if (maxCopy < keyFrame.value_.end_) - maxCopy = keyFrame.value_.end_; - } - } else { - maxCopy = obj->mCopies.value(); - } - obj->mMaxCopies = maxCopy; - } else if (0 == strcmp(key, "o")) { - parseProperty(obj->mOffset); - } else if (0 == strcmp(key, "tr")) { - getValue(obj->mTransform); - } else if (0 == strcmp(key, "hd")) { - obj->setHidden(GetBool()); - } else { -#ifdef DEBUG_PARSER - vDebug << "Repeater property ignored :" << key; -#endif - Skip(key); - } - } - obj->setStatic(obj->mCopies.isStatic() && obj->mOffset.isStatic() && - obj->mTransform.isStatic()); - - return obj; -} - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/transform.json - */ -model::Transform *LottieParserImpl::parseTransformObject(bool ddd) -{ - auto objT = allocator().make(); - - auto obj = allocator().make(); - if (ddd) { - obj->createExtraData(); - obj->mExtra->m3DData = true; - } - - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "nm")) { - objT->setName(GetString()); - } else if (0 == strcmp(key, "a")) { - parseProperty(obj->mAnchor); - } else if (0 == strcmp(key, "p")) { - EnterObject(); - bool separate = false; - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "k")) { - parsePropertyHelper(obj->mPosition); - } else if (0 == strcmp(key, "s")) { - obj->createExtraData(); - obj->mExtra->mSeparate = GetBool(); - separate = true; - } else if (separate && (0 == strcmp(key, "x"))) { - parseProperty(obj->mExtra->mSeparateX); - } else if (separate && (0 == strcmp(key, "y"))) { - parseProperty(obj->mExtra->mSeparateY); - } else { - Skip(key); - } - } - } else if (0 == strcmp(key, "r")) { - parseProperty(obj->mRotation); - } else if (0 == strcmp(key, "s")) { - parseProperty(obj->mScale); - } else if (0 == strcmp(key, "o")) { - parseProperty(obj->mOpacity); - } else if (0 == strcmp(key, "hd")) { - objT->setHidden(GetBool()); - } else if (0 == strcmp(key, "rx")) { - if (!obj->mExtra) return nullptr; - parseProperty(obj->mExtra->m3DRx); - } else if (0 == strcmp(key, "ry")) { - if (!obj->mExtra) return nullptr; - parseProperty(obj->mExtra->m3DRy); - } else if (0 == strcmp(key, "rz")) { - if (!obj->mExtra) return nullptr; - parseProperty(obj->mExtra->m3DRz); - } else { - Skip(key); - } - } - bool isStatic = obj->mAnchor.isStatic() && obj->mPosition.isStatic() && - obj->mRotation.isStatic() && obj->mScale.isStatic() && - obj->mOpacity.isStatic(); - if (obj->mExtra) { - isStatic = isStatic && obj->mExtra->m3DRx.isStatic() && - obj->mExtra->m3DRy.isStatic() && - obj->mExtra->m3DRz.isStatic() && - obj->mExtra->mSeparateX.isStatic() && - obj->mExtra->mSeparateY.isStatic(); - } - - objT->set(obj, isStatic); - - return objT; -} - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/fill.json - */ -model::Fill *LottieParserImpl::parseFillObject() -{ - auto obj = allocator().make(); - - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "nm")) { - obj->setName(GetString()); - } else if (0 == strcmp(key, "c")) { - parseProperty(obj->mColor); - } else if (0 == strcmp(key, "o")) { - parseProperty(obj->mOpacity); - } else if (0 == strcmp(key, "fillEnabled")) { - obj->mEnabled = GetBool(); - } else if (0 == strcmp(key, "r")) { - obj->mFillRule = getFillRule(); - } else if (0 == strcmp(key, "hd")) { - obj->setHidden(GetBool()); - } else { -#ifdef DEBUG_PARSER - vWarning << "Fill property skipped = " << key; -#endif - Skip(key); - } - } - obj->setStatic(obj->mColor.isStatic() && obj->mOpacity.isStatic()); - - return obj; -} - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/helpers/lineCap.json - */ -CapStyle LottieParserImpl::getLineCap() -{ - switch (GetInt()) { - case 1: - return CapStyle::Flat; - break; - case 2: - return CapStyle::Round; - break; - default: - return CapStyle::Square; - break; - } -} - -FillRule LottieParserImpl::getFillRule() -{ - switch (GetInt()) { - case 1: - return FillRule::Winding; - break; - case 2: - return FillRule::EvenOdd; - break; - default: - return FillRule::Winding; - break; - } -} - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/helpers/lineJoin.json - */ -JoinStyle LottieParserImpl::getLineJoin() -{ - switch (GetInt()) { - case 1: - return JoinStyle::Miter; - break; - case 2: - return JoinStyle::Round; - break; - default: - return JoinStyle::Bevel; - break; - } -} - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/stroke.json - */ -model::Stroke *LottieParserImpl::parseStrokeObject() -{ - auto obj = allocator().make(); - - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "nm")) { - obj->setName(GetString()); - } else if (0 == strcmp(key, "c")) { - parseProperty(obj->mColor); - } else if (0 == strcmp(key, "o")) { - parseProperty(obj->mOpacity); - } else if (0 == strcmp(key, "w")) { - parseProperty(obj->mWidth); - } else if (0 == strcmp(key, "fillEnabled")) { - obj->mEnabled = GetBool(); - } else if (0 == strcmp(key, "lc")) { - obj->mCapStyle = getLineCap(); - } else if (0 == strcmp(key, "lj")) { - obj->mJoinStyle = getLineJoin(); - } else if (0 == strcmp(key, "ml")) { - obj->mMiterLimit = GetDouble(); - } else if (0 == strcmp(key, "d")) { - parseDashProperty(obj->mDash); - } else if (0 == strcmp(key, "hd")) { - obj->setHidden(GetBool()); - } else { -#ifdef DEBUG_PARSER - vWarning << "Stroke property skipped = " << key; -#endif - Skip(key); - } - } - obj->setStatic(obj->mColor.isStatic() && obj->mOpacity.isStatic() && - obj->mWidth.isStatic() && obj->mDash.isStatic()); - return obj; -} - -void LottieParserImpl::parseGradientProperty(model::Gradient *obj, - const char * key) -{ - if (0 == strcmp(key, "t")) { - obj->mGradientType = GetInt(); - } else if (0 == strcmp(key, "o")) { - parseProperty(obj->mOpacity); - } else if (0 == strcmp(key, "s")) { - parseProperty(obj->mStartPoint); - } else if (0 == strcmp(key, "e")) { - parseProperty(obj->mEndPoint); - } else if (0 == strcmp(key, "h")) { - parseProperty(obj->mHighlightLength); - } else if (0 == strcmp(key, "a")) { - parseProperty(obj->mHighlightAngle); - } else if (0 == strcmp(key, "g")) { - EnterObject(); - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "k")) { - parseProperty(obj->mGradient); - } else if (0 == strcmp(key, "p")) { - obj->mColorPoints = GetInt(); - } else { - Skip(nullptr); - } - } - } else if (0 == strcmp(key, "hd")) { - obj->setHidden(GetBool()); - } else { -#ifdef DEBUG_PARSER - vWarning << "Gradient property skipped = " << key; -#endif - Skip(key); - } - obj->setStatic( - obj->mOpacity.isStatic() && obj->mStartPoint.isStatic() && - obj->mEndPoint.isStatic() && obj->mHighlightAngle.isStatic() && - obj->mHighlightLength.isStatic() && obj->mGradient.isStatic()); -} - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/gfill.json - */ -model::GradientFill *LottieParserImpl::parseGFillObject() -{ - auto obj = allocator().make(); - - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "nm")) { - obj->setName(GetString()); - } else if (0 == strcmp(key, "r")) { - obj->mFillRule = getFillRule(); - } else { - parseGradientProperty(obj, key); - } - } - return obj; -} - -void LottieParserImpl::parseDashProperty(model::Dash &dash) -{ - EnterArray(); - while (NextArrayValue()) { - EnterObject(); - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "v")) { - dash.mData.emplace_back(); - parseProperty(dash.mData.back()); - } else { - Skip(key); - } - } - } -} - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/gstroke.json - */ -model::GradientStroke *LottieParserImpl::parseGStrokeObject() -{ - auto obj = allocator().make(); - - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "nm")) { - obj->setName(GetString()); - } else if (0 == strcmp(key, "w")) { - parseProperty(obj->mWidth); - } else if (0 == strcmp(key, "lc")) { - obj->mCapStyle = getLineCap(); - } else if (0 == strcmp(key, "lj")) { - obj->mJoinStyle = getLineJoin(); - } else if (0 == strcmp(key, "ml")) { - obj->mMiterLimit = GetDouble(); - } else if (0 == strcmp(key, "d")) { - parseDashProperty(obj->mDash); - } else { - parseGradientProperty(obj, key); - } - } - - obj->setStatic(obj->isStatic() && obj->mWidth.isStatic() && - obj->mDash.isStatic()); - return obj; -} - -void LottieParserImpl::getValue(std::vector &v) -{ - EnterArray(); - while (NextArrayValue()) { - EnterArray(); - VPointF pt; - getValue(pt); - v.push_back(pt); - } -} - -void LottieParserImpl::getValue(VPointF &pt) -{ - float val[4] = {0.f}; - int i = 0; - - if (PeekType() == kArrayType) EnterArray(); - - while (NextArrayValue()) { - const auto value = GetDouble(); - if (i < 4) { - val[i++] = value; - } - } - pt.setX(val[0]); - pt.setY(val[1]); -} - -void LottieParserImpl::getValue(float &val) -{ - if (PeekType() == kArrayType) { - EnterArray(); - if (NextArrayValue()) val = GetDouble(); - // discard rest - while (NextArrayValue()) { - GetDouble(); - } - } else if (PeekType() == kNumberType) { - val = GetDouble(); - } else { - Error(); - } -} - -void LottieParserImpl::getValue(model::Color &color) -{ - float val[4] = {0.f}; - int i = 0; - if (PeekType() == kArrayType) EnterArray(); - - while (NextArrayValue()) { - const auto value = GetDouble(); - if (i < 4) { - val[i++] = value; - } - } - - if (mColorFilter) mColorFilter(val[0], val[1], val[2]); - - color.r = val[0]; - color.g = val[1]; - color.b = val[2]; -} - -void LottieParserImpl::getValue(model::Gradient::Data &grad) -{ - if (PeekType() == kArrayType) EnterArray(); - - while (NextArrayValue()) { - grad.mGradient.push_back(GetDouble()); - } -} - -void LottieParserImpl::getValue(int &val) -{ - if (PeekType() == kArrayType) { - EnterArray(); - while (NextArrayValue()) { - val = GetInt(); - } - } else if (PeekType() == kNumberType) { - val = GetInt(); - } else { - Error(); - } -} - -void LottieParserImpl::parsePathInfo() -{ - mPathInfo.reset(); - - /* - * The shape object could be wrapped by a array - * if its part of the keyframe object - */ - bool arrayWrapper = (PeekType() == kArrayType); - if (arrayWrapper) EnterArray(); - - EnterObject(); - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "i")) { - getValue(mPathInfo.mInPoint); - } else if (0 == strcmp(key, "o")) { - getValue(mPathInfo.mOutPoint); - } else if (0 == strcmp(key, "v")) { - getValue(mPathInfo.mVertices); - } else if (0 == strcmp(key, "c")) { - mPathInfo.mClosed = GetBool(); - } else { - Error(); - Skip(nullptr); - } - } - // exit properly from the array - if (arrayWrapper) NextArrayValue(); - - mPathInfo.convert(); -} - -void LottieParserImpl::getValue(model::PathData &obj) -{ - parsePathInfo(); - obj.mPoints = mPathInfo.mResult; - obj.mClosed = mPathInfo.mClosed; -} - -VPointF LottieParserImpl::parseInperpolatorPoint() -{ - VPointF cp; - EnterObject(); - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "x")) { - getValue(cp.rx()); - } - if (0 == strcmp(key, "y")) { - getValue(cp.ry()); - } - } - return cp; -} - -template -bool LottieParserImpl::parseKeyFrameValue( - const char *key, model::Value &value) -{ - if (0 == strcmp(key, "ti")) { - value.hasTangent_ = true; - getValue(value.inTangent_); - } else if (0 == strcmp(key, "to")) { - value.hasTangent_ = true; - getValue(value.outTangent_); - } else { - return false; - } - return true; -} - -VInterpolator *LottieParserImpl::interpolator(VPointF inTangent, - VPointF outTangent, - std::string key) -{ - if (key.empty()) { - std::array temp; - snprintf(temp.data(), temp.size(), "%.2f_%.2f_%.2f_%.2f", inTangent.x(), - inTangent.y(), outTangent.x(), outTangent.y()); - key = temp.data(); - } - - auto search = mInterpolatorCache.find(key); - - if (search != mInterpolatorCache.end()) { - return search->second; - } - - auto obj = allocator().make(outTangent, inTangent); - mInterpolatorCache[std::move(key)] = obj; - return obj; -} - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/properties/multiDimensionalKeyframed.json - */ -template -void LottieParserImpl::parseKeyFrame(model::KeyFrames &obj) -{ - struct ParsedField { - std::string interpolatorKey; - bool interpolator{false}; - bool value{false}; - bool hold{false}; - bool noEndValue{true}; - }; - - EnterObject(); - ParsedField parsed; - typename model::KeyFrames::Frame keyframe; - VPointF inTangent; - VPointF outTangent; - - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "i")) { - parsed.interpolator = true; - inTangent = parseInperpolatorPoint(); - } else if (0 == strcmp(key, "o")) { - outTangent = parseInperpolatorPoint(); - } else if (0 == strcmp(key, "t")) { - keyframe.start_ = GetDouble(); - } else if (0 == strcmp(key, "s")) { - parsed.value = true; - getValue(keyframe.value_.start_); - continue; - } else if (0 == strcmp(key, "e")) { - parsed.noEndValue = false; - getValue(keyframe.value_.end_); - continue; - } else if (0 == strcmp(key, "n")) { - if (PeekType() == kStringType) { - parsed.interpolatorKey = GetStringObject(); - } else { - EnterArray(); - while (NextArrayValue()) { - if (parsed.interpolatorKey.empty()) { - parsed.interpolatorKey = GetStringObject(); - } else { - // skip rest of the string - Skip(nullptr); - } - } - } - continue; - } else if (parseKeyFrameValue(key, keyframe.value_)) { - continue; - } else if (0 == strcmp(key, "h")) { - parsed.hold = GetInt(); - continue; - } else { -#ifdef DEBUG_PARSER - vDebug << "key frame property skipped = " << key; -#endif - Skip(key); - } - } - - auto &list = obj.frames_; - if (!list.empty()) { - // update the endFrame value of current keyframe - list.back().end_ = keyframe.start_; - // if no end value provided, copy start value to previous frame - if (parsed.value && parsed.noEndValue) { - list.back().value_.end_ = keyframe.value_.start_; - } - } - - if (parsed.hold) { - keyframe.value_.end_ = keyframe.value_.start_; - keyframe.end_ = keyframe.start_; - list.push_back(std::move(keyframe)); - } else if (parsed.interpolator) { - keyframe.interpolator_ = interpolator( - inTangent, outTangent, std::move(parsed.interpolatorKey)); - list.push_back(std::move(keyframe)); - } else { - // its the last frame discard. - } -} - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/properties/shapeKeyframed.json - */ - -/* - * https://github.com/airbnb/lottie-web/blob/master/docs/json/properties/shape.json - */ -void LottieParserImpl::parseShapeProperty(model::Property &obj) -{ - EnterObject(); - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "k")) { - if (PeekType() == kArrayType) { - EnterArray(); - while (NextArrayValue()) { - parseKeyFrame(obj.animation()); - } - } else { - if (!obj.isStatic()) { - st_ = kError; - return; - } - getValue(obj.value()); - } - } else { -#ifdef DEBUG_PARSER - vDebug << "shape property ignored = " << key; -#endif - Skip(nullptr); - } - } - obj.cache(); -} - -template -void LottieParserImpl::parsePropertyHelper(model::Property &obj) -{ - if (PeekType() == kNumberType) { - if (!obj.isStatic()) { - st_ = kError; - return; - } - /*single value property with no animation*/ - getValue(obj.value()); - } else { - EnterArray(); - while (NextArrayValue()) { - /* property with keyframe info*/ - if (PeekType() == kObjectType) { - parseKeyFrame(obj.animation()); - } else { - /* Read before modifying. - * as there is no way of knowing if the - * value of the array is either array of numbers - * or array of object without entering the array - * thats why this hack is there - */ - if (!obj.isStatic()) { - st_ = kError; - return; - } - /*multi value property with no animation*/ - getValue(obj.value()); - /*break here as we already reached end of array*/ - break; - } - } - obj.cache(); - } -} - -/* - * https://github.com/airbnb/lottie-web/tree/master/docs/json/properties - */ -template -void LottieParserImpl::parseProperty(model::Property &obj) -{ - EnterObject(); - while (const char *key = NextObjectKey()) { - if (0 == strcmp(key, "k")) { - parsePropertyHelper(obj); - } else { - Skip(key); - } - } -} - -#ifdef LOTTIE_DUMP_TREE_SUPPORT - -class ObjectInspector { -public: - void visit(model::Composition *obj, std::string level) - { - vDebug << " { " << level << "Composition:: a: " << !obj->isStatic() - << ", v: " << obj->mVersion << ", stFm: " << obj->startFrame() - << ", endFm: " << obj->endFrame() - << ", W: " << obj->size().width() - << ", H: " << obj->size().height() << "\n"; - level.append("\t"); - visit(obj->mRootLayer, level); - level.erase(level.end() - 1, level.end()); - vDebug << " } " << level << "Composition End\n"; - } - void visit(model::Layer *obj, std::string level) - { - vDebug << level << "{ " << layerType(obj->mLayerType) - << ", name: " << obj->name() << ", id:" << obj->mId - << " Pid:" << obj->mParentId << ", a:" << !obj->isStatic() - << ", " << matteType(obj->mMatteType) - << ", mask:" << obj->hasMask() << ", inFm:" << obj->mInFrame - << ", outFm:" << obj->mOutFrame << ", stFm:" << obj->mStartFrame - << ", ts:" << obj->mTimeStreatch << ", ao:" << obj->autoOrient() - << ", W:" << obj->layerSize().width() - << ", H:" << obj->layerSize().height(); - - if (obj->mLayerType == model::Layer::Type::Image) - vDebug << level << "\t{ " - << "ImageInfo:" - << " W :" << obj->extra()->mAsset->mWidth - << ", H :" << obj->extra()->mAsset->mHeight << " }" - << "\n"; - else { - vDebug << level; - } - visitChildren(static_cast(obj), level); - vDebug << level << "} " << layerType(obj->mLayerType).c_str() - << ", id: " << obj->mId << "\n"; - } - void visitChildren(model::Group *obj, std::string level) - { - level.append("\t"); - for (const auto &child : obj->mChildren) visit(child, level); - if (obj->mTransform) visit(obj->mTransform, level); - } - - void visit(model::Object *obj, std::string level) - { - switch (obj->type()) { - case model::Object::Type::Repeater: { - auto r = static_cast(obj); - vDebug << level << "{ Repeater: name: " << obj->name() - << " , a:" << !obj->isStatic() - << ", copies:" << r->maxCopies() - << ", offset:" << r->offset(0); - visitChildren(r->mContent, level); - vDebug << level << "} Repeater"; - break; - } - case model::Object::Type::Group: { - vDebug << level << "{ Group: name: " << obj->name() - << " , a:" << !obj->isStatic(); - visitChildren(static_cast(obj), level); - vDebug << level << "} Group"; - break; - } - case model::Object::Type::Layer: { - visit(static_cast(obj), level); - break; - } - case model::Object::Type::Trim: { - vDebug << level << "{ Trim: name: " << obj->name() - << " , a:" << !obj->isStatic() << " }"; - break; - } - case model::Object::Type::Rect: { - vDebug << level << "{ Rect: name: " << obj->name() - << " , a:" << !obj->isStatic() << " }"; - break; - } - case model::Object::Type::RoundedCorner: { - vDebug << level << "{ RoundedCorner: name: " << obj->name() - << " , a:" << !obj->isStatic() << " }"; - break; - } - case model::Object::Type::Ellipse: { - vDebug << level << "{ Ellipse: name: " << obj->name() - << " , a:" << !obj->isStatic() << " }"; - break; - } - case model::Object::Type::Path: { - vDebug << level << "{ Shape: name: " << obj->name() - << " , a:" << !obj->isStatic() << " }"; - break; - } - case model::Object::Type::Polystar: { - vDebug << level << "{ Polystar: name: " << obj->name() - << " , a:" << !obj->isStatic() << " }"; - break; - } - case model::Object::Type::Transform: { - vDebug << level << "{ Transform: name: " << obj->name() - << " , a: " << !obj->isStatic() << " }"; - break; - } - case model::Object::Type::Stroke: { - vDebug << level << "{ Stroke: name: " << obj->name() - << " , a:" << !obj->isStatic() << " }"; - break; - } - case model::Object::Type::GStroke: { - vDebug << level << "{ GStroke: name: " << obj->name() - << " , a:" << !obj->isStatic() << " }"; - break; - } - case model::Object::Type::Fill: { - vDebug << level << "{ Fill: name: " << obj->name() - << " , a:" << !obj->isStatic() << " }"; - break; - } - case model::Object::Type::GFill: { - auto f = static_cast(obj); - vDebug << level << "{ GFill: name: " << obj->name() - << " , a:" << !f->isStatic() << ", ty:" << f->mGradientType - << ", s:" << f->mStartPoint.value(0) - << ", e:" << f->mEndPoint.value(0) << " }"; - break; - } - default: - break; - } - } - - std::string matteType(model::MatteType type) - { - switch (type) { - case model::MatteType::None: - return "Matte::None"; - break; - case model::MatteType::Alpha: - return "Matte::Alpha"; - break; - case model::MatteType::AlphaInv: - return "Matte::AlphaInv"; - break; - case model::MatteType::Luma: - return "Matte::Luma"; - break; - case model::MatteType::LumaInv: - return "Matte::LumaInv"; - break; - default: - return "Matte::Unknown"; - break; - } - } - std::string layerType(model::Layer::Type type) - { - switch (type) { - case model::Layer::Type::Precomp: - return "Layer::Precomp"; - break; - case model::Layer::Type::Null: - return "Layer::Null"; - break; - case model::Layer::Type::Shape: - return "Layer::Shape"; - break; - case model::Layer::Type::Solid: - return "Layer::Solid"; - break; - case model::Layer::Type::Image: - return "Layer::Image"; - break; - case model::Layer::Type::Text: - return "Layer::Text"; - break; - default: - return "Layer::Unknown"; - break; - } - } -}; - -#endif - -static char* uncompressZip(const char * str, size_t length) -{ - auto zip = zip_stream_open(str, length, 0, 'r'); - if (!zip) { - vCritical << "Failed to unzip dotLottie: read fail!"; - return nullptr; - } - - // Read a representative animation - if (zip_entry_openbyindex(zip, 1)) { - vCritical << "Failed to unzip dotLottie: open by index fail!"; - zip_stream_close(zip); - return nullptr; - } - - char* buf = nullptr; - size_t bufSize; - zip_entry_read(zip, (void**)&buf, &bufSize); - - zip_entry_close(zip); - zip_stream_close(zip); - - if (buf == nullptr || bufSize == 0) { - vCritical << "Failed to unzip dotLottie: buffer is empty!"; - return nullptr; - } - - char* terminatedBuf = static_cast(realloc(buf, bufSize + 1)); - if (!terminatedBuf) { - free(buf); - vCritical << "Failed to unzip dotLottie: failed to allocate!"; - return nullptr; - } - - terminatedBuf[bufSize] = '\0'; - return terminatedBuf; -} - -static bool checkDotLottie(const char * str) -{ - //check the .Lottie signature. - if (str[0] == 0x50 && str[1] == 0x4B && str[2] == 0x03 && str[3] == 0x04) return true; - else return false; -} - -std::shared_ptr parseImpl(char* input, - std::string dir_path, - model::ColorFilter filter) -{ - LottieParserImpl obj(input, std::move(dir_path), std::move(filter)); - - if (!obj.VerifyType()) { - vWarning << "Input data is not Lottie format!"; - return {}; - } - - obj.parseComposition(); - auto composition = obj.composition(); - if (composition) { - composition->processRepeaterObjects(); - composition->updateStats(); - -#ifdef LOTTIE_DUMP_TREE_SUPPORT - ObjectInspector inspector; - inspector.visit(composition.get(), ""); -#endif - } - - return composition; -} - -std::shared_ptr model::parse(char * str, - size_t length, - std::string dir_path, - model::ColorFilter filter) -{ - auto input = str; - - auto dotLottie = checkDotLottie(str); - if (dotLottie) { - input = uncompressZip(str, length); - if (!input) { - vWarning << "Failed to decompress .lottie archive."; - return {}; - } - } - - auto result = parseImpl(input, std::move(dir_path), std::move(filter)); - - if (dotLottie) free(input); - return result; -} - -RAPIDJSON_DIAG_POP diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieproxymodel.cpp b/presentation/src/main/cpp/third_party/rlottie/src/lottie/lottieproxymodel.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/meson.build b/presentation/src/main/cpp/third_party/rlottie/src/lottie/meson.build deleted file mode 100644 index 8bfe69cd..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/meson.build +++ /dev/null @@ -1,17 +0,0 @@ -subdir('zip') - -source_file = [ - 'lottieparser.cpp', - 'lottieloader.cpp', - 'lottiemodel.cpp', - 'lottieproxymodel.cpp', - 'lottieanimation.cpp', - 'lottieitem.cpp', - 'lottieitem_capi.cpp', - 'lottiekeypath.cpp' -] - -lottie_dep = declare_dependency( - include_directories : include_directories('.'), - sources : source_file - ) diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/allocators.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/allocators.h deleted file mode 100644 index 0b8f5e14..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/allocators.h +++ /dev/null @@ -1,284 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_ALLOCATORS_H_ -#define RAPIDJSON_ALLOCATORS_H_ - -#include "rapidjson.h" - -RAPIDJSON_NAMESPACE_BEGIN - -/////////////////////////////////////////////////////////////////////////////// -// Allocator - -/*! \class rapidjson::Allocator - \brief Concept for allocating, resizing and freeing memory block. - - Note that Malloc() and Realloc() are non-static but Free() is static. - - So if an allocator need to support Free(), it needs to put its pointer in - the header of memory block. - -\code -concept Allocator { - static const bool kNeedFree; //!< Whether this allocator needs to call Free(). - - // Allocate a memory block. - // \param size of the memory block in bytes. - // \returns pointer to the memory block. - void* Malloc(size_t size); - - // Resize a memory block. - // \param originalPtr The pointer to current memory block. Null pointer is permitted. - // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.) - // \param newSize the new size in bytes. - void* Realloc(void* originalPtr, size_t originalSize, size_t newSize); - - // Free a memory block. - // \param pointer to the memory block. Null pointer is permitted. - static void Free(void *ptr); -}; -\endcode -*/ - - -/*! \def RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY - \ingroup RAPIDJSON_CONFIG - \brief User-defined kDefaultChunkCapacity definition. - - User can define this as any \c size that is a power of 2. -*/ - -#ifndef RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY -#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY (64 * 1024) -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// CrtAllocator - -//! C-runtime library allocator. -/*! This class is just wrapper for standard C library memory routines. - \note implements Allocator concept -*/ -class CrtAllocator { -public: - static const bool kNeedFree = true; - void* Malloc(size_t size) { - if (size) // behavior of malloc(0) is implementation defined. - return RAPIDJSON_MALLOC(size); - else - return NULL; // standardize to returning NULL. - } - void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { - (void)originalSize; - if (newSize == 0) { - RAPIDJSON_FREE(originalPtr); - return NULL; - } - return RAPIDJSON_REALLOC(originalPtr, newSize); - } - static void Free(void *ptr) { RAPIDJSON_FREE(ptr); } -}; - -/////////////////////////////////////////////////////////////////////////////// -// MemoryPoolAllocator - -//! Default memory allocator used by the parser and DOM. -/*! This allocator allocate memory blocks from pre-allocated memory chunks. - - It does not free memory blocks. And Realloc() only allocate new memory. - - The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default. - - User may also supply a buffer as the first chunk. - - If the user-buffer is full then additional chunks are allocated by BaseAllocator. - - The user-buffer is not deallocated by this allocator. - - \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator. - \note implements Allocator concept -*/ -template -class MemoryPoolAllocator { -public: - static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator) - - //! Constructor with chunkSize. - /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. - \param baseAllocator The allocator for allocating memory chunks. - */ - MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : - chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0) - { - } - - //! Constructor with user-supplied buffer. - /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size. - - The user buffer will not be deallocated when this allocator is destructed. - - \param buffer User supplied buffer. - \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader). - \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. - \param baseAllocator The allocator for allocating memory chunks. - */ - MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : - chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0) - { - RAPIDJSON_ASSERT(buffer != 0); - RAPIDJSON_ASSERT(size > sizeof(ChunkHeader)); - chunkHead_ = reinterpret_cast(buffer); - chunkHead_->capacity = size - sizeof(ChunkHeader); - chunkHead_->size = 0; - chunkHead_->next = 0; - } - - //! Destructor. - /*! This deallocates all memory chunks, excluding the user-supplied buffer. - */ - ~MemoryPoolAllocator() { - Clear(); - RAPIDJSON_DELETE(ownBaseAllocator_); - } - - //! Deallocates all memory chunks, excluding the user-supplied buffer. - void Clear() { - while (chunkHead_ && chunkHead_ != userBuffer_) { - ChunkHeader* next = chunkHead_->next; - baseAllocator_->Free(chunkHead_); - chunkHead_ = next; - } - if (chunkHead_ && chunkHead_ == userBuffer_) - chunkHead_->size = 0; // Clear user buffer - } - - //! Computes the total capacity of allocated memory chunks. - /*! \return total capacity in bytes. - */ - size_t Capacity() const { - size_t capacity = 0; - for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) - capacity += c->capacity; - return capacity; - } - - //! Computes the memory blocks allocated. - /*! \return total used bytes. - */ - size_t Size() const { - size_t size = 0; - for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) - size += c->size; - return size; - } - - //! Allocates a memory block. (concept Allocator) - void* Malloc(size_t size) { - if (!size) - return NULL; - - size = RAPIDJSON_ALIGN(size); - if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity) - if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size)) - return NULL; - - void *buffer = reinterpret_cast(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size; - chunkHead_->size += size; - return buffer; - } - - //! Resizes a memory block (concept Allocator) - void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { - if (originalPtr == 0) - return Malloc(newSize); - - if (newSize == 0) - return NULL; - - originalSize = RAPIDJSON_ALIGN(originalSize); - newSize = RAPIDJSON_ALIGN(newSize); - - // Do not shrink if new size is smaller than original - if (originalSize >= newSize) - return originalPtr; - - // Simply expand it if it is the last allocation and there is sufficient space - if (originalPtr == reinterpret_cast(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) { - size_t increment = static_cast(newSize - originalSize); - if (chunkHead_->size + increment <= chunkHead_->capacity) { - chunkHead_->size += increment; - return originalPtr; - } - } - - // Realloc process: allocate and copy memory, do not free original buffer. - if (void* newBuffer = Malloc(newSize)) { - if (originalSize) - std::memcpy(newBuffer, originalPtr, originalSize); - return newBuffer; - } - else - return NULL; - } - - //! Frees a memory block (concept Allocator) - static void Free(void *ptr) { (void)ptr; } // Do nothing - -private: - //! Copy constructor is not permitted. - MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */; - //! Copy assignment operator is not permitted. - MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */; - - //! Creates a new chunk. - /*! \param capacity Capacity of the chunk in bytes. - \return true if success. - */ - bool AddChunk(size_t capacity) { - if (!baseAllocator_) - ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)(); - if (ChunkHeader* chunk = reinterpret_cast(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) { - chunk->capacity = capacity; - chunk->size = 0; - chunk->next = chunkHead_; - chunkHead_ = chunk; - return true; - } - else - return false; - } - - static const int kDefaultChunkCapacity = RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY; //!< Default chunk capacity. - - //! Chunk header for perpending to each chunk. - /*! Chunks are stored as a singly linked list. - */ - struct ChunkHeader { - size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself). - size_t size; //!< Current size of allocated memory in bytes. - ChunkHeader *next; //!< Next chunk in the linked list. - }; - - ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation. - size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated. - void *userBuffer_; //!< User supplied buffer. - BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks. - BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object. -}; - -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/cursorstreamwrapper.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/cursorstreamwrapper.h deleted file mode 100644 index 52c11a7c..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/cursorstreamwrapper.h +++ /dev/null @@ -1,78 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_CURSORSTREAMWRAPPER_H_ -#define RAPIDJSON_CURSORSTREAMWRAPPER_H_ - -#include "stream.h" - -#if defined(__GNUC__) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(effc++) -#endif - -#if defined(_MSC_VER) && _MSC_VER <= 1800 -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(4702) // unreachable code -RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated -#endif - -RAPIDJSON_NAMESPACE_BEGIN - - -//! Cursor stream wrapper for counting line and column number if error exists. -/*! - \tparam InputStream Any stream that implements Stream Concept -*/ -template > -class CursorStreamWrapper : public GenericStreamWrapper { -public: - typedef typename Encoding::Ch Ch; - - CursorStreamWrapper(InputStream& is): - GenericStreamWrapper(is), line_(1), col_(0) {} - - // counting line and column number - Ch Take() { - Ch ch = this->is_.Take(); - if(ch == '\n') { - line_ ++; - col_ = 0; - } else { - col_ ++; - } - return ch; - } - - //! Get the error line number, if error exists. - size_t GetLine() const { return line_; } - //! Get the error column number, if error exists. - size_t GetColumn() const { return col_; } - -private: - size_t line_; //!< Current Line - size_t col_; //!< Current Column -}; - -#if defined(_MSC_VER) && _MSC_VER <= 1800 -RAPIDJSON_DIAG_POP -#endif - -#if defined(__GNUC__) -RAPIDJSON_DIAG_POP -#endif - -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_CURSORSTREAMWRAPPER_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/document.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/document.h deleted file mode 100644 index 68aaae7e..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/document.h +++ /dev/null @@ -1,2732 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_DOCUMENT_H_ -#define RAPIDJSON_DOCUMENT_H_ - -/*! \file document.h */ - -#include "reader.h" -#include "internal/meta.h" -#include "internal/strfunc.h" -#include "memorystream.h" -#include "encodedstream.h" -#include // placement new -#include -#ifdef __cpp_lib_three_way_comparison -#include -#endif - -RAPIDJSON_DIAG_PUSH -#ifdef __clang__ -RAPIDJSON_DIAG_OFF(padded) -RAPIDJSON_DIAG_OFF(switch-enum) -RAPIDJSON_DIAG_OFF(c++98-compat) -#elif defined(_MSC_VER) -RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant -RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data -#endif - -#ifdef __GNUC__ -RAPIDJSON_DIAG_OFF(effc++) -#endif // __GNUC__ - -#ifndef RAPIDJSON_NOMEMBERITERATORCLASS -#include // std::random_access_iterator_tag -#endif - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS -#include // std::move -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -// Forward declaration. -template -class GenericValue; - -template -class GenericDocument; - -/*! \def RAPIDJSON_DEFAULT_ALLOCATOR - \ingroup RAPIDJSON_CONFIG - \brief Allows to choose default allocator. - - User can define this to use CrtAllocator or MemoryPoolAllocator. -*/ -#ifndef RAPIDJSON_DEFAULT_ALLOCATOR -#define RAPIDJSON_DEFAULT_ALLOCATOR MemoryPoolAllocator -#endif - -/*! \def RAPIDJSON_DEFAULT_STACK_ALLOCATOR - \ingroup RAPIDJSON_CONFIG - \brief Allows to choose default stack allocator for Document. - - User can define this to use CrtAllocator or MemoryPoolAllocator. -*/ -#ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR -#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR CrtAllocator -#endif - -/*! \def RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY - \ingroup RAPIDJSON_CONFIG - \brief User defined kDefaultObjectCapacity value. - - User can define this as any natural number. -*/ -#ifndef RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY -// number of objects that rapidjson::Value allocates memory for by default -#define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY 16 -#endif - -/*! \def RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY - \ingroup RAPIDJSON_CONFIG - \brief User defined kDefaultArrayCapacity value. - - User can define this as any natural number. -*/ -#ifndef RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY -// number of array elements that rapidjson::Value allocates memory for by default -#define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY 16 -#endif - -//! Name-value pair in a JSON object value. -/*! - This class was internal to GenericValue. It used to be a inner struct. - But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct. - https://code.google.com/p/rapidjson/issues/detail?id=64 -*/ -template -class GenericMember { -public: - GenericValue name; //!< name of member (must be a string) - GenericValue value; //!< value of member. - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - //! Move constructor in C++11 - GenericMember(GenericMember&& rhs) RAPIDJSON_NOEXCEPT - : name(std::move(rhs.name)), - value(std::move(rhs.value)) - { - } - - //! Move assignment in C++11 - GenericMember& operator=(GenericMember&& rhs) RAPIDJSON_NOEXCEPT { - return *this = static_cast(rhs); - } -#endif - - //! Assignment with move semantics. - /*! \param rhs Source of the assignment. Its name and value will become a null value after assignment. - */ - GenericMember& operator=(GenericMember& rhs) RAPIDJSON_NOEXCEPT { - if (RAPIDJSON_LIKELY(this != &rhs)) { - name = rhs.name; - value = rhs.value; - } - return *this; - } - - // swap() for std::sort() and other potential use in STL. - friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT { - a.name.Swap(b.name); - a.value.Swap(b.value); - } - -private: - //! Copy constructor is not permitted. - GenericMember(const GenericMember& rhs); -}; - -/////////////////////////////////////////////////////////////////////////////// -// GenericMemberIterator - -#ifndef RAPIDJSON_NOMEMBERITERATORCLASS - -//! (Constant) member iterator for a JSON object value -/*! - \tparam Const Is this a constant iterator? - \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) - \tparam Allocator Allocator type for allocating memory of object, array and string. - - This class implements a Random Access Iterator for GenericMember elements - of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements]. - - \note This iterator implementation is mainly intended to avoid implicit - conversions from iterator values to \c NULL, - e.g. from GenericValue::FindMember. - - \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a - pointer-based implementation, if your platform doesn't provide - the C++ header. - - \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator - */ -template -class GenericMemberIterator { - - friend class GenericValue; - template friend class GenericMemberIterator; - - typedef GenericMember PlainType; - typedef typename internal::MaybeAddConst::Type ValueType; - -public: - //! Iterator type itself - typedef GenericMemberIterator Iterator; - //! Constant iterator type - typedef GenericMemberIterator ConstIterator; - //! Non-constant iterator type - typedef GenericMemberIterator NonConstIterator; - - /** \name std::iterator_traits support */ - //@{ - typedef ValueType value_type; - typedef ValueType * pointer; - typedef ValueType & reference; - typedef std::ptrdiff_t difference_type; - typedef std::random_access_iterator_tag iterator_category; - //@} - - //! Pointer to (const) GenericMember - typedef pointer Pointer; - //! Reference to (const) GenericMember - typedef reference Reference; - //! Signed integer type (e.g. \c ptrdiff_t) - typedef difference_type DifferenceType; - - //! Default constructor (singular value) - /*! Creates an iterator pointing to no element. - \note All operations, except for comparisons, are undefined on such values. - */ - GenericMemberIterator() : ptr_() {} - - //! Iterator conversions to more const - /*! - \param it (Non-const) iterator to copy from - - Allows the creation of an iterator from another GenericMemberIterator - that is "less const". Especially, creating a non-constant iterator - from a constant iterator are disabled: - \li const -> non-const (not ok) - \li const -> const (ok) - \li non-const -> const (ok) - \li non-const -> non-const (ok) - - \note If the \c Const template parameter is already \c false, this - constructor effectively defines a regular copy-constructor. - Otherwise, the copy constructor is implicitly defined. - */ - GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {} - Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; } - - //! @name stepping - //@{ - Iterator& operator++(){ ++ptr_; return *this; } - Iterator& operator--(){ --ptr_; return *this; } - Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; } - Iterator operator--(int){ Iterator old(*this); --ptr_; return old; } - //@} - - //! @name increment/decrement - //@{ - Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); } - Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); } - - Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; } - Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; } - //@} - - //! @name relations - //@{ - template bool operator==(const GenericMemberIterator& that) const { return ptr_ == that.ptr_; } - template bool operator!=(const GenericMemberIterator& that) const { return ptr_ != that.ptr_; } - template bool operator<=(const GenericMemberIterator& that) const { return ptr_ <= that.ptr_; } - template bool operator>=(const GenericMemberIterator& that) const { return ptr_ >= that.ptr_; } - template bool operator< (const GenericMemberIterator& that) const { return ptr_ < that.ptr_; } - template bool operator> (const GenericMemberIterator& that) const { return ptr_ > that.ptr_; } - -#ifdef __cpp_lib_three_way_comparison - template std::strong_ordering operator<=>(const GenericMemberIterator& that) const { return ptr_ <=> that.ptr_; } -#endif - //@} - - //! @name dereference - //@{ - Reference operator*() const { return *ptr_; } - Pointer operator->() const { return ptr_; } - Reference operator[](DifferenceType n) const { return ptr_[n]; } - //@} - - //! Distance - DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; } - -private: - //! Internal constructor from plain pointer - explicit GenericMemberIterator(Pointer p) : ptr_(p) {} - - Pointer ptr_; //!< raw pointer -}; - -#else // RAPIDJSON_NOMEMBERITERATORCLASS - -// class-based member iterator implementation disabled, use plain pointers - -template -class GenericMemberIterator; - -//! non-const GenericMemberIterator -template -class GenericMemberIterator { - //! use plain pointer as iterator type - typedef GenericMember* Iterator; -}; -//! const GenericMemberIterator -template -class GenericMemberIterator { - //! use plain const pointer as iterator type - typedef const GenericMember* Iterator; -}; - -#endif // RAPIDJSON_NOMEMBERITERATORCLASS - -/////////////////////////////////////////////////////////////////////////////// -// GenericStringRef - -//! Reference to a constant string (not taking a copy) -/*! - \tparam CharType character type of the string - - This helper class is used to automatically infer constant string - references for string literals, especially from \c const \b (!) - character arrays. - - The main use is for creating JSON string values without copying the - source string via an \ref Allocator. This requires that the referenced - string pointers have a sufficient lifetime, which exceeds the lifetime - of the associated GenericValue. - - \b Example - \code - Value v("foo"); // ok, no need to copy & calculate length - const char foo[] = "foo"; - v.SetString(foo); // ok - - const char* bar = foo; - // Value x(bar); // not ok, can't rely on bar's lifetime - Value x(StringRef(bar)); // lifetime explicitly guaranteed by user - Value y(StringRef(bar, 3)); // ok, explicitly pass length - \endcode - - \see StringRef, GenericValue::SetString -*/ -template -struct GenericStringRef { - typedef CharType Ch; //!< character type of the string - - //! Create string reference from \c const character array -#ifndef __clang__ // -Wdocumentation - /*! - This constructor implicitly creates a constant string reference from - a \c const character array. It has better performance than - \ref StringRef(const CharType*) by inferring the string \ref length - from the array length, and also supports strings containing null - characters. - - \tparam N length of the string, automatically inferred - - \param str Constant character array, lifetime assumed to be longer - than the use of the string in e.g. a GenericValue - - \post \ref s == str - - \note Constant complexity. - \note There is a hidden, private overload to disallow references to - non-const character arrays to be created via this constructor. - By this, e.g. function-scope arrays used to be filled via - \c snprintf are excluded from consideration. - In such cases, the referenced string should be \b copied to the - GenericValue instead. - */ -#endif - template - GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT - : s(str), length(N-1) {} - - //! Explicitly create string reference from \c const character pointer -#ifndef __clang__ // -Wdocumentation - /*! - This constructor can be used to \b explicitly create a reference to - a constant string pointer. - - \see StringRef(const CharType*) - - \param str Constant character pointer, lifetime assumed to be longer - than the use of the string in e.g. a GenericValue - - \post \ref s == str - - \note There is a hidden, private overload to disallow references to - non-const character arrays to be created via this constructor. - By this, e.g. function-scope arrays used to be filled via - \c snprintf are excluded from consideration. - In such cases, the referenced string should be \b copied to the - GenericValue instead. - */ -#endif - explicit GenericStringRef(const CharType* str) - : s(str), length(NotNullStrLen(str)) {} - - //! Create constant string reference from pointer and length -#ifndef __clang__ // -Wdocumentation - /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue - \param len length of the string, excluding the trailing NULL terminator - - \post \ref s == str && \ref length == len - \note Constant complexity. - */ -#endif - GenericStringRef(const CharType* str, SizeType len) - : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { RAPIDJSON_ASSERT(str != 0 || len == 0u); } - - GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {} - - //! implicit conversion to plain CharType pointer - operator const Ch *() const { return s; } - - const Ch* const s; //!< plain CharType pointer - const SizeType length; //!< length of the string (excluding the trailing NULL terminator) - -private: - SizeType NotNullStrLen(const CharType* str) { - RAPIDJSON_ASSERT(str != 0); - return internal::StrLen(str); - } - - /// Empty string - used when passing in a NULL pointer - static const Ch emptyString[]; - - //! Disallow construction from non-const array - template - GenericStringRef(CharType (&str)[N]) /* = delete */; - //! Copy assignment operator not permitted - immutable type - GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */; -}; - -template -const CharType GenericStringRef::emptyString[] = { CharType() }; - -//! Mark a character pointer as constant string -/*! Mark a plain character pointer as a "string literal". This function - can be used to avoid copying a character string to be referenced as a - value in a JSON GenericValue object, if the string's lifetime is known - to be valid long enough. - \tparam CharType Character type of the string - \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue - \return GenericStringRef string reference object - \relatesalso GenericStringRef - - \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember -*/ -template -inline GenericStringRef StringRef(const CharType* str) { - return GenericStringRef(str); -} - -//! Mark a character pointer as constant string -/*! Mark a plain character pointer as a "string literal". This function - can be used to avoid copying a character string to be referenced as a - value in a JSON GenericValue object, if the string's lifetime is known - to be valid long enough. - - This version has better performance with supplied length, and also - supports string containing null characters. - - \tparam CharType character type of the string - \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue - \param length The length of source string. - \return GenericStringRef string reference object - \relatesalso GenericStringRef -*/ -template -inline GenericStringRef StringRef(const CharType* str, size_t length) { - return GenericStringRef(str, SizeType(length)); -} - -#if RAPIDJSON_HAS_STDSTRING -//! Mark a string object as constant string -/*! Mark a string object (e.g. \c std::string) as a "string literal". - This function can be used to avoid copying a string to be referenced as a - value in a JSON GenericValue object, if the string's lifetime is known - to be valid long enough. - - \tparam CharType character type of the string - \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue - \return GenericStringRef string reference object - \relatesalso GenericStringRef - \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. -*/ -template -inline GenericStringRef StringRef(const std::basic_string& str) { - return GenericStringRef(str.data(), SizeType(str.size())); -} -#endif - -/////////////////////////////////////////////////////////////////////////////// -// GenericValue type traits -namespace internal { - -template -struct IsGenericValueImpl : FalseType {}; - -// select candidates according to nested encoding and allocator types -template struct IsGenericValueImpl::Type, typename Void::Type> - : IsBaseOf, T>::Type {}; - -// helper to match arbitrary GenericValue instantiations, including derived classes -template struct IsGenericValue : IsGenericValueImpl::Type {}; - -} // namespace internal - -/////////////////////////////////////////////////////////////////////////////// -// TypeHelper - -namespace internal { - -template -struct TypeHelper {}; - -template -struct TypeHelper { - static bool Is(const ValueType& v) { return v.IsBool(); } - static bool Get(const ValueType& v) { return v.GetBool(); } - static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); } - static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); } -}; - -template -struct TypeHelper { - static bool Is(const ValueType& v) { return v.IsInt(); } - static int Get(const ValueType& v) { return v.GetInt(); } - static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); } - static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); } -}; - -template -struct TypeHelper { - static bool Is(const ValueType& v) { return v.IsUint(); } - static unsigned Get(const ValueType& v) { return v.GetUint(); } - static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); } - static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); } -}; - -#ifdef _MSC_VER -RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int)); -template -struct TypeHelper { - static bool Is(const ValueType& v) { return v.IsInt(); } - static long Get(const ValueType& v) { return v.GetInt(); } - static ValueType& Set(ValueType& v, long data) { return v.SetInt(data); } - static ValueType& Set(ValueType& v, long data, typename ValueType::AllocatorType&) { return v.SetInt(data); } -}; - -RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned)); -template -struct TypeHelper { - static bool Is(const ValueType& v) { return v.IsUint(); } - static unsigned long Get(const ValueType& v) { return v.GetUint(); } - static ValueType& Set(ValueType& v, unsigned long data) { return v.SetUint(data); } - static ValueType& Set(ValueType& v, unsigned long data, typename ValueType::AllocatorType&) { return v.SetUint(data); } -}; -#endif - -template -struct TypeHelper { - static bool Is(const ValueType& v) { return v.IsInt64(); } - static int64_t Get(const ValueType& v) { return v.GetInt64(); } - static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); } - static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); } -}; - -template -struct TypeHelper { - static bool Is(const ValueType& v) { return v.IsUint64(); } - static uint64_t Get(const ValueType& v) { return v.GetUint64(); } - static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); } - static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); } -}; - -template -struct TypeHelper { - static bool Is(const ValueType& v) { return v.IsDouble(); } - static double Get(const ValueType& v) { return v.GetDouble(); } - static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); } - static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); } -}; - -template -struct TypeHelper { - static bool Is(const ValueType& v) { return v.IsFloat(); } - static float Get(const ValueType& v) { return v.GetFloat(); } - static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); } - static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); } -}; - -template -struct TypeHelper { - typedef const typename ValueType::Ch* StringType; - static bool Is(const ValueType& v) { return v.IsString(); } - static StringType Get(const ValueType& v) { return v.GetString(); } - static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); } - static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); } -}; - -#if RAPIDJSON_HAS_STDSTRING -template -struct TypeHelper > { - typedef std::basic_string StringType; - static bool Is(const ValueType& v) { return v.IsString(); } - static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); } - static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); } -}; -#endif - -template -struct TypeHelper { - typedef typename ValueType::Array ArrayType; - static bool Is(const ValueType& v) { return v.IsArray(); } - static ArrayType Get(ValueType& v) { return v.GetArray(); } - static ValueType& Set(ValueType& v, ArrayType data) { return v = data; } - static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; } -}; - -template -struct TypeHelper { - typedef typename ValueType::ConstArray ArrayType; - static bool Is(const ValueType& v) { return v.IsArray(); } - static ArrayType Get(const ValueType& v) { return v.GetArray(); } -}; - -template -struct TypeHelper { - typedef typename ValueType::Object ObjectType; - static bool Is(const ValueType& v) { return v.IsObject(); } - static ObjectType Get(ValueType& v) { return v.GetObject(); } - static ValueType& Set(ValueType& v, ObjectType data) { return v = data; } - static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { return v = data; } -}; - -template -struct TypeHelper { - typedef typename ValueType::ConstObject ObjectType; - static bool Is(const ValueType& v) { return v.IsObject(); } - static ObjectType Get(const ValueType& v) { return v.GetObject(); } -}; - -} // namespace internal - -// Forward declarations -template class GenericArray; -template class GenericObject; - -/////////////////////////////////////////////////////////////////////////////// -// GenericValue - -//! Represents a JSON value. Use Value for UTF8 encoding and default allocator. -/*! - A JSON value can be one of 7 types. This class is a variant type supporting - these types. - - Use the Value if UTF8 and default allocator - - \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) - \tparam Allocator Allocator type for allocating memory of object, array and string. -*/ -template -class GenericValue { -public: - //! Name-value pair in an object. - typedef GenericMember Member; - typedef Encoding EncodingType; //!< Encoding type from template parameter. - typedef Allocator AllocatorType; //!< Allocator type from template parameter. - typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. - typedef GenericStringRef StringRefType; //!< Reference to a constant string - typedef typename GenericMemberIterator::Iterator MemberIterator; //!< Member iterator for iterating in object. - typedef typename GenericMemberIterator::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object. - typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array. - typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array. - typedef GenericValue ValueType; //!< Value type of itself. - typedef GenericArray Array; - typedef GenericArray ConstArray; - typedef GenericObject Object; - typedef GenericObject ConstObject; - - //!@name Constructors and destructor. - //@{ - - //! Default constructor creates a null value. - GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - //! Move constructor in C++11 - GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) { - rhs.data_.f.flags = kNullFlag; // give up contents - } -#endif - -private: - //! Copy constructor is not permitted. - GenericValue(const GenericValue& rhs); - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - //! Moving from a GenericDocument is not permitted. - template - GenericValue(GenericDocument&& rhs); - - //! Move assignment from a GenericDocument is not permitted. - template - GenericValue& operator=(GenericDocument&& rhs); -#endif - -public: - - //! Constructor with JSON value type. - /*! This creates a Value of specified type with default content. - \param type Type of the value. - \note Default content for number is zero. - */ - explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() { - static const uint16_t defaultFlags[] = { - kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag, - kNumberAnyFlag - }; - RAPIDJSON_NOEXCEPT_ASSERT(type >= kNullType && type <= kNumberType); - data_.f.flags = defaultFlags[type]; - - // Use ShortString to store empty string. - if (type == kStringType) - data_.ss.SetLength(0); - } - - //! Explicit copy constructor (with allocator) - /*! Creates a copy of a Value by using the given Allocator - \tparam SourceAllocator allocator of \c rhs - \param rhs Value to copy from (read-only) - \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator(). - \param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer) - \see CopyFrom() - */ - template - GenericValue(const GenericValue& rhs, Allocator& allocator, bool copyConstStrings = false) { - switch (rhs.GetType()) { - case kObjectType: { - SizeType count = rhs.data_.o.size; - Member* lm = reinterpret_cast(allocator.Malloc(count * sizeof(Member))); - const typename GenericValue::Member* rm = rhs.GetMembersPointer(); - for (SizeType i = 0; i < count; i++) { - new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings); - new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings); - } - data_.f.flags = kObjectFlag; - data_.o.size = data_.o.capacity = count; - SetMembersPointer(lm); - } - break; - case kArrayType: { - SizeType count = rhs.data_.a.size; - GenericValue* le = reinterpret_cast(allocator.Malloc(count * sizeof(GenericValue))); - const GenericValue* re = rhs.GetElementsPointer(); - for (SizeType i = 0; i < count; i++) - new (&le[i]) GenericValue(re[i], allocator, copyConstStrings); - data_.f.flags = kArrayFlag; - data_.a.size = data_.a.capacity = count; - SetElementsPointer(le); - } - break; - case kStringType: - if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) { - data_.f.flags = rhs.data_.f.flags; - data_ = *reinterpret_cast(&rhs.data_); - } - else - SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator); - break; - default: - data_.f.flags = rhs.data_.f.flags; - data_ = *reinterpret_cast(&rhs.data_); - break; - } - } - - //! Constructor for boolean value. - /*! \param b Boolean value - \note This constructor is limited to \em real boolean values and rejects - implicitly converted types like arbitrary pointers. Use an explicit cast - to \c bool, if you want to construct a boolean JSON value in such cases. - */ -#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen - template - explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame))) RAPIDJSON_NOEXCEPT // See #472 -#else - explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT -#endif - : data_() { - // safe-guard against failing SFINAE - RAPIDJSON_STATIC_ASSERT((internal::IsSame::Value)); - data_.f.flags = b ? kTrueFlag : kFalseFlag; - } - - //! Constructor for int value. - explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() { - data_.n.i64 = i; - data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag; - } - - //! Constructor for unsigned value. - explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() { - data_.n.u64 = u; - data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag); - } - - //! Constructor for int64_t value. - explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() { - data_.n.i64 = i64; - data_.f.flags = kNumberInt64Flag; - if (i64 >= 0) { - data_.f.flags |= kNumberUint64Flag; - if (!(static_cast(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) - data_.f.flags |= kUintFlag; - if (!(static_cast(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) - data_.f.flags |= kIntFlag; - } - else if (i64 >= static_cast(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) - data_.f.flags |= kIntFlag; - } - - //! Constructor for uint64_t value. - explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() { - data_.n.u64 = u64; - data_.f.flags = kNumberUint64Flag; - if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000))) - data_.f.flags |= kInt64Flag; - if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) - data_.f.flags |= kUintFlag; - if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) - data_.f.flags |= kIntFlag; - } - - //! Constructor for double value. - explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; } - - //! Constructor for float value. - explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast(f); data_.f.flags = kNumberDoubleFlag; } - - //! Constructor for constant string (i.e. do not make a copy of string) - GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); } - - //! Constructor for constant string (i.e. do not make a copy of string) - explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); } - - //! Constructor for copy-string (i.e. do make a copy of string) - GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); } - - //! Constructor for copy-string (i.e. do make a copy of string) - GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); } - -#if RAPIDJSON_HAS_STDSTRING - //! Constructor for copy-string from a string object (i.e. do make a copy of string) - /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. - */ - GenericValue(const std::basic_string& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); } -#endif - - //! Constructor for Array. - /*! - \param a An array obtained by \c GetArray(). - \note \c Array is always pass-by-value. - \note the source array is moved into this value and the sourec array becomes empty. - */ - GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) { - a.value_.data_ = Data(); - a.value_.data_.f.flags = kArrayFlag; - } - - //! Constructor for Object. - /*! - \param o An object obtained by \c GetObject(). - \note \c Object is always pass-by-value. - \note the source object is moved into this value and the sourec object becomes empty. - */ - GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) { - o.value_.data_ = Data(); - o.value_.data_.f.flags = kObjectFlag; - } - - //! Destructor. - /*! Need to destruct elements of array, members of object, or copy-string. - */ - ~GenericValue() { - if (Allocator::kNeedFree) { // Shortcut by Allocator's trait - switch(data_.f.flags) { - case kArrayFlag: - { - GenericValue* e = GetElementsPointer(); - for (GenericValue* v = e; v != e + data_.a.size; ++v) - v->~GenericValue(); - Allocator::Free(e); - } - break; - - case kObjectFlag: - for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) - m->~Member(); - Allocator::Free(GetMembersPointer()); - break; - - case kCopyStringFlag: - Allocator::Free(const_cast(GetStringPointer())); - break; - - default: - break; // Do nothing for other types. - } - } - } - - //@} - - //!@name Assignment operators - //@{ - - //! Assignment with move semantics. - /*! \param rhs Source of the assignment. It will become a null value after assignment. - */ - GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT { - if (RAPIDJSON_LIKELY(this != &rhs)) { - this->~GenericValue(); - RawAssign(rhs); - } - return *this; - } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - //! Move assignment in C++11 - GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT { - return *this = rhs.Move(); - } -#endif - - //! Assignment of constant string reference (no copy) - /*! \param str Constant string reference to be assigned - \note This overload is needed to avoid clashes with the generic primitive type assignment overload below. - \see GenericStringRef, operator=(T) - */ - GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT { - GenericValue s(str); - return *this = s; - } - - //! Assignment with primitive types. - /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t - \param value The value to be assigned. - - \note The source type \c T explicitly disallows all pointer types, - especially (\c const) \ref Ch*. This helps avoiding implicitly - referencing character strings with insufficient lifetime, use - \ref SetString(const Ch*, Allocator&) (for copying) or - \ref StringRef() (to explicitly mark the pointer as constant) instead. - All other pointer types would implicitly convert to \c bool, - use \ref SetBool() instead. - */ - template - RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer), (GenericValue&)) - operator=(T value) { - GenericValue v(value); - return *this = v; - } - - //! Deep-copy assignment from Value - /*! Assigns a \b copy of the Value to the current Value object - \tparam SourceAllocator Allocator type of \c rhs - \param rhs Value to copy from (read-only) - \param allocator Allocator to use for copying - \param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer) - */ - template - GenericValue& CopyFrom(const GenericValue& rhs, Allocator& allocator, bool copyConstStrings = false) { - RAPIDJSON_ASSERT(static_cast(this) != static_cast(&rhs)); - this->~GenericValue(); - new (this) GenericValue(rhs, allocator, copyConstStrings); - return *this; - } - - //! Exchange the contents of this value with those of other. - /*! - \param other Another value. - \note Constant complexity. - */ - GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT { - GenericValue temp; - temp.RawAssign(*this); - RawAssign(other); - other.RawAssign(temp); - return *this; - } - - //! free-standing swap function helper - /*! - Helper function to enable support for common swap implementation pattern based on \c std::swap: - \code - void swap(MyClass& a, MyClass& b) { - using std::swap; - swap(a.value, b.value); - // ... - } - \endcode - \see Swap() - */ - friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } - - //! Prepare Value for move semantics - /*! \return *this */ - GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; } - //@} - - //!@name Equal-to and not-equal-to operators - //@{ - //! Equal-to operator - /*! - \note If an object contains duplicated named member, comparing equality with any object is always \c false. - \note Complexity is quadratic in Object's member number and linear for the rest (number of all values in the subtree and total lengths of all strings). - */ - template - bool operator==(const GenericValue& rhs) const { - typedef GenericValue RhsType; - if (GetType() != rhs.GetType()) - return false; - - switch (GetType()) { - case kObjectType: // Warning: O(n^2) inner-loop - if (data_.o.size != rhs.data_.o.size) - return false; - for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) { - typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name); - if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value) - return false; - } - return true; - - case kArrayType: - if (data_.a.size != rhs.data_.a.size) - return false; - for (SizeType i = 0; i < data_.a.size; i++) - if ((*this)[i] != rhs[i]) - return false; - return true; - - case kStringType: - return StringEqual(rhs); - - case kNumberType: - if (IsDouble() || rhs.IsDouble()) { - double a = GetDouble(); // May convert from integer to double. - double b = rhs.GetDouble(); // Ditto - return a >= b && a <= b; // Prevent -Wfloat-equal - } - else - return data_.n.u64 == rhs.data_.n.u64; - - default: - return true; - } - } - - //! Equal-to operator with const C-string pointer - bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); } - -#if RAPIDJSON_HAS_STDSTRING - //! Equal-to operator with string object - /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. - */ - bool operator==(const std::basic_string& rhs) const { return *this == GenericValue(StringRef(rhs)); } -#endif - - //! Equal-to operator with primitive types - /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false - */ - template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr,internal::IsGenericValue >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); } - - //! Not-equal-to operator - /*! \return !(*this == rhs) - */ - template - bool operator!=(const GenericValue& rhs) const { return !(*this == rhs); } - - //! Not-equal-to operator with const C-string pointer - bool operator!=(const Ch* rhs) const { return !(*this == rhs); } - - //! Not-equal-to operator with arbitrary types - /*! \return !(*this == rhs) - */ - template RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); } - - //! Equal-to operator with arbitrary types (symmetric version) - /*! \return (rhs == lhs) - */ - template friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; } - - //! Not-Equal-to operator with arbitrary types (symmetric version) - /*! \return !(rhs == lhs) - */ - template friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); } - //@} - - //!@name Type - //@{ - - Type GetType() const { return static_cast(data_.f.flags & kTypeMask); } - bool IsNull() const { return data_.f.flags == kNullFlag; } - bool IsFalse() const { return data_.f.flags == kFalseFlag; } - bool IsTrue() const { return data_.f.flags == kTrueFlag; } - bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; } - bool IsObject() const { return data_.f.flags == kObjectFlag; } - bool IsArray() const { return data_.f.flags == kArrayFlag; } - bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; } - bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; } - bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; } - bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; } - bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; } - bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; } - bool IsString() const { return (data_.f.flags & kStringFlag) != 0; } - - // Checks whether a number can be losslessly converted to a double. - bool IsLosslessDouble() const { - if (!IsNumber()) return false; - if (IsUint64()) { - uint64_t u = GetUint64(); - volatile double d = static_cast(u); - return (d >= 0.0) - && (d < static_cast((std::numeric_limits::max)())) - && (u == static_cast(d)); - } - if (IsInt64()) { - int64_t i = GetInt64(); - volatile double d = static_cast(i); - return (d >= static_cast((std::numeric_limits::min)())) - && (d < static_cast((std::numeric_limits::max)())) - && (i == static_cast(d)); - } - return true; // double, int, uint are always lossless - } - - // Checks whether a number is a float (possible lossy). - bool IsFloat() const { - if ((data_.f.flags & kDoubleFlag) == 0) - return false; - double d = GetDouble(); - return d >= -3.4028234e38 && d <= 3.4028234e38; - } - // Checks whether a number can be losslessly converted to a float. - bool IsLosslessFloat() const { - if (!IsNumber()) return false; - double a = GetDouble(); - if (a < static_cast(-(std::numeric_limits::max)()) - || a > static_cast((std::numeric_limits::max)())) - return false; - double b = static_cast(static_cast(a)); - return a >= b && a <= b; // Prevent -Wfloat-equal - } - - //@} - - //!@name Null - //@{ - - GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; } - - //@} - - //!@name Bool - //@{ - - bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; } - //!< Set boolean value - /*! \post IsBool() == true */ - GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; } - - //@} - - //!@name Object - //@{ - - //! Set this value as an empty object. - /*! \post IsObject() == true */ - GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; } - - //! Get the number of members in the object. - SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; } - - //! Get the capacity of object. - SizeType MemberCapacity() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.capacity; } - - //! Check whether the object is empty. - bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; } - - //! Get a value from an object associated with the name. - /*! \pre IsObject() == true - \tparam T Either \c Ch or \c const \c Ch (template used for disambiguation with \ref operator[](SizeType)) - \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7. - Since 0.2, if the name is not correct, it will assert. - If user is unsure whether a member exists, user should use HasMember() first. - A better approach is to use FindMember(). - \note Linear time complexity. - */ - template - RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >),(GenericValue&)) operator[](T* name) { - GenericValue n(StringRef(name)); - return (*this)[n]; - } - template - RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >),(const GenericValue&)) operator[](T* name) const { return const_cast(*this)[name]; } - - //! Get a value from an object associated with the name. - /*! \pre IsObject() == true - \tparam SourceAllocator Allocator of the \c name value - - \note Compared to \ref operator[](T*), this version is faster because it does not need a StrLen(). - And it can also handle strings with embedded null characters. - - \note Linear time complexity. - */ - template - GenericValue& operator[](const GenericValue& name) { - MemberIterator member = FindMember(name); - if (member != MemberEnd()) - return member->value; - else { - RAPIDJSON_ASSERT(false); // see above note - - // This will generate -Wexit-time-destructors in clang - // static GenericValue NullValue; - // return NullValue; - - // Use static buffer and placement-new to prevent destruction - static char buffer[sizeof(GenericValue)]; - return *new (buffer) GenericValue(); - } - } - template - const GenericValue& operator[](const GenericValue& name) const { return const_cast(*this)[name]; } - -#if RAPIDJSON_HAS_STDSTRING - //! Get a value from an object associated with name (string object). - GenericValue& operator[](const std::basic_string& name) { return (*this)[GenericValue(StringRef(name))]; } - const GenericValue& operator[](const std::basic_string& name) const { return (*this)[GenericValue(StringRef(name))]; } -#endif - - //! Const member iterator - /*! \pre IsObject() == true */ - ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); } - //! Const \em past-the-end member iterator - /*! \pre IsObject() == true */ - ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); } - //! Member iterator - /*! \pre IsObject() == true */ - MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); } - //! \em Past-the-end member iterator - /*! \pre IsObject() == true */ - MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); } - - //! Request the object to have enough capacity to store members. - /*! \param newCapacity The capacity that the object at least need to have. - \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \note Linear time complexity. - */ - GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) { - RAPIDJSON_ASSERT(IsObject()); - if (newCapacity > data_.o.capacity) { - SetMembersPointer(reinterpret_cast(allocator.Realloc(GetMembersPointer(), data_.o.capacity * sizeof(Member), newCapacity * sizeof(Member)))); - data_.o.capacity = newCapacity; - } - return *this; - } - - //! Check whether a member exists in the object. - /*! - \param name Member name to be searched. - \pre IsObject() == true - \return Whether a member with that name exists. - \note It is better to use FindMember() directly if you need the obtain the value as well. - \note Linear time complexity. - */ - bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); } - -#if RAPIDJSON_HAS_STDSTRING - //! Check whether a member exists in the object with string object. - /*! - \param name Member name to be searched. - \pre IsObject() == true - \return Whether a member with that name exists. - \note It is better to use FindMember() directly if you need the obtain the value as well. - \note Linear time complexity. - */ - bool HasMember(const std::basic_string& name) const { return FindMember(name) != MemberEnd(); } -#endif - - //! Check whether a member exists in the object with GenericValue name. - /*! - This version is faster because it does not need a StrLen(). It can also handle string with null character. - \param name Member name to be searched. - \pre IsObject() == true - \return Whether a member with that name exists. - \note It is better to use FindMember() directly if you need the obtain the value as well. - \note Linear time complexity. - */ - template - bool HasMember(const GenericValue& name) const { return FindMember(name) != MemberEnd(); } - - //! Find member by name. - /*! - \param name Member name to be searched. - \pre IsObject() == true - \return Iterator to member, if it exists. - Otherwise returns \ref MemberEnd(). - - \note Earlier versions of Rapidjson returned a \c NULL pointer, in case - the requested member doesn't exist. For consistency with e.g. - \c std::map, this has been changed to MemberEnd() now. - \note Linear time complexity. - */ - MemberIterator FindMember(const Ch* name) { - GenericValue n(StringRef(name)); - return FindMember(n); - } - - ConstMemberIterator FindMember(const Ch* name) const { return const_cast(*this).FindMember(name); } - - //! Find member by name. - /*! - This version is faster because it does not need a StrLen(). It can also handle string with null character. - \param name Member name to be searched. - \pre IsObject() == true - \return Iterator to member, if it exists. - Otherwise returns \ref MemberEnd(). - - \note Earlier versions of Rapidjson returned a \c NULL pointer, in case - the requested member doesn't exist. For consistency with e.g. - \c std::map, this has been changed to MemberEnd() now. - \note Linear time complexity. - */ - template - MemberIterator FindMember(const GenericValue& name) { - RAPIDJSON_ASSERT(IsObject()); - RAPIDJSON_ASSERT(name.IsString()); - MemberIterator member = MemberBegin(); - for ( ; member != MemberEnd(); ++member) - if (name.StringEqual(member->name)) - break; - return member; - } - template ConstMemberIterator FindMember(const GenericValue& name) const { return const_cast(*this).FindMember(name); } - -#if RAPIDJSON_HAS_STDSTRING - //! Find member by string object name. - /*! - \param name Member name to be searched. - \pre IsObject() == true - \return Iterator to member, if it exists. - Otherwise returns \ref MemberEnd(). - */ - MemberIterator FindMember(const std::basic_string& name) { return FindMember(GenericValue(StringRef(name))); } - ConstMemberIterator FindMember(const std::basic_string& name) const { return FindMember(GenericValue(StringRef(name))); } -#endif - - //! Add a member (name-value pair) to the object. - /*! \param name A string value as name of member. - \param value Value of any type. - \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \note The ownership of \c name and \c value will be transferred to this object on success. - \pre IsObject() && name.IsString() - \post name.IsNull() && value.IsNull() - \note Amortized Constant time complexity. - */ - GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { - RAPIDJSON_ASSERT(IsObject()); - RAPIDJSON_ASSERT(name.IsString()); - - ObjectData& o = data_.o; - if (o.size >= o.capacity) - MemberReserve(o.capacity == 0 ? kDefaultObjectCapacity : (o.capacity + (o.capacity + 1) / 2), allocator); - Member* members = GetMembersPointer(); - members[o.size].name.RawAssign(name); - members[o.size].value.RawAssign(value); - o.size++; - return *this; - } - - //! Add a constant string value as member (name-value pair) to the object. - /*! \param name A string value as name of member. - \param value constant string reference as value of member. - \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \pre IsObject() - \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. - \note Amortized Constant time complexity. - */ - GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) { - GenericValue v(value); - return AddMember(name, v, allocator); - } - -#if RAPIDJSON_HAS_STDSTRING - //! Add a string object as member (name-value pair) to the object. - /*! \param name A string value as name of member. - \param value constant string reference as value of member. - \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \pre IsObject() - \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. - \note Amortized Constant time complexity. - */ - GenericValue& AddMember(GenericValue& name, std::basic_string& value, Allocator& allocator) { - GenericValue v(value, allocator); - return AddMember(name, v, allocator); - } -#endif - - //! Add any primitive value as member (name-value pair) to the object. - /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t - \param name A string value as name of member. - \param value Value of primitive type \c T as value of member - \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \pre IsObject() - - \note The source type \c T explicitly disallows all pointer types, - especially (\c const) \ref Ch*. This helps avoiding implicitly - referencing character strings with insufficient lifetime, use - \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref - AddMember(StringRefType, StringRefType, Allocator&). - All other pointer types would implicitly convert to \c bool, - use an explicit cast instead, if needed. - \note Amortized Constant time complexity. - */ - template - RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) - AddMember(GenericValue& name, T value, Allocator& allocator) { - GenericValue v(value); - return AddMember(name, v, allocator); - } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) { - return AddMember(name, value, allocator); - } - GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) { - return AddMember(name, value, allocator); - } - GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) { - return AddMember(name, value, allocator); - } - GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) { - GenericValue n(name); - return AddMember(n, value, allocator); - } -#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS - - - //! Add a member (name-value pair) to the object. - /*! \param name A constant string reference as name of member. - \param value Value of any type. - \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \note The ownership of \c value will be transferred to this object on success. - \pre IsObject() - \post value.IsNull() - \note Amortized Constant time complexity. - */ - GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) { - GenericValue n(name); - return AddMember(n, value, allocator); - } - - //! Add a constant string value as member (name-value pair) to the object. - /*! \param name A constant string reference as name of member. - \param value constant string reference as value of member. - \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \pre IsObject() - \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below. - \note Amortized Constant time complexity. - */ - GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) { - GenericValue v(value); - return AddMember(name, v, allocator); - } - - //! Add any primitive value as member (name-value pair) to the object. - /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t - \param name A constant string reference as name of member. - \param value Value of primitive type \c T as value of member - \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \pre IsObject() - - \note The source type \c T explicitly disallows all pointer types, - especially (\c const) \ref Ch*. This helps avoiding implicitly - referencing character strings with insufficient lifetime, use - \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref - AddMember(StringRefType, StringRefType, Allocator&). - All other pointer types would implicitly convert to \c bool, - use an explicit cast instead, if needed. - \note Amortized Constant time complexity. - */ - template - RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) - AddMember(StringRefType name, T value, Allocator& allocator) { - GenericValue n(name); - return AddMember(n, value, allocator); - } - - //! Remove all members in the object. - /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged. - \note Linear time complexity. - */ - void RemoveAllMembers() { - RAPIDJSON_ASSERT(IsObject()); - for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) - m->~Member(); - data_.o.size = 0; - } - - //! Remove a member in object by its name. - /*! \param name Name of member to be removed. - \return Whether the member existed. - \note This function may reorder the object members. Use \ref - EraseMember(ConstMemberIterator) if you need to preserve the - relative order of the remaining members. - \note Linear time complexity. - */ - bool RemoveMember(const Ch* name) { - GenericValue n(StringRef(name)); - return RemoveMember(n); - } - -#if RAPIDJSON_HAS_STDSTRING - bool RemoveMember(const std::basic_string& name) { return RemoveMember(GenericValue(StringRef(name))); } -#endif - - template - bool RemoveMember(const GenericValue& name) { - MemberIterator m = FindMember(name); - if (m != MemberEnd()) { - RemoveMember(m); - return true; - } - else - return false; - } - - //! Remove a member in object by iterator. - /*! \param m member iterator (obtained by FindMember() or MemberBegin()). - \return the new iterator after removal. - \note This function may reorder the object members. Use \ref - EraseMember(ConstMemberIterator) if you need to preserve the - relative order of the remaining members. - \note Constant time complexity. - */ - MemberIterator RemoveMember(MemberIterator m) { - RAPIDJSON_ASSERT(IsObject()); - RAPIDJSON_ASSERT(data_.o.size > 0); - RAPIDJSON_ASSERT(GetMembersPointer() != 0); - RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd()); - - MemberIterator last(GetMembersPointer() + (data_.o.size - 1)); - if (data_.o.size > 1 && m != last) - *m = *last; // Move the last one to this place - else - m->~Member(); // Only one left, just destroy - --data_.o.size; - return m; - } - - //! Remove a member from an object by iterator. - /*! \param pos iterator to the member to remove - \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd() - \return Iterator following the removed element. - If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned. - \note This function preserves the relative order of the remaining object - members. If you do not need this, use the more efficient \ref RemoveMember(MemberIterator). - \note Linear time complexity. - */ - MemberIterator EraseMember(ConstMemberIterator pos) { - return EraseMember(pos, pos +1); - } - - //! Remove members in the range [first, last) from an object. - /*! \param first iterator to the first member to remove - \param last iterator following the last member to remove - \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd() - \return Iterator following the last removed element. - \note This function preserves the relative order of the remaining object - members. - \note Linear time complexity. - */ - MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) { - RAPIDJSON_ASSERT(IsObject()); - RAPIDJSON_ASSERT(data_.o.size > 0); - RAPIDJSON_ASSERT(GetMembersPointer() != 0); - RAPIDJSON_ASSERT(first >= MemberBegin()); - RAPIDJSON_ASSERT(first <= last); - RAPIDJSON_ASSERT(last <= MemberEnd()); - - MemberIterator pos = MemberBegin() + (first - MemberBegin()); - for (MemberIterator itr = pos; itr != last; ++itr) - itr->~Member(); - std::memmove(static_cast(&*pos), &*last, static_cast(MemberEnd() - last) * sizeof(Member)); - data_.o.size -= static_cast(last - first); - return pos; - } - - //! Erase a member in object by its name. - /*! \param name Name of member to be removed. - \return Whether the member existed. - \note Linear time complexity. - */ - bool EraseMember(const Ch* name) { - GenericValue n(StringRef(name)); - return EraseMember(n); - } - -#if RAPIDJSON_HAS_STDSTRING - bool EraseMember(const std::basic_string& name) { return EraseMember(GenericValue(StringRef(name))); } -#endif - - template - bool EraseMember(const GenericValue& name) { - MemberIterator m = FindMember(name); - if (m != MemberEnd()) { - EraseMember(m); - return true; - } - else - return false; - } - - Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); } - ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); } - - //@} - - //!@name Array - //@{ - - //! Set this value as an empty array. - /*! \post IsArray == true */ - GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; } - - //! Get the number of elements in array. - SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; } - - //! Get the capacity of array. - SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; } - - //! Check whether the array is empty. - bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; } - - //! Remove all elements in the array. - /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged. - \note Linear time complexity. - */ - void Clear() { - RAPIDJSON_ASSERT(IsArray()); - GenericValue* e = GetElementsPointer(); - for (GenericValue* v = e; v != e + data_.a.size; ++v) - v->~GenericValue(); - data_.a.size = 0; - } - - //! Get an element from array by index. - /*! \pre IsArray() == true - \param index Zero-based index of element. - \see operator[](T*) - */ - GenericValue& operator[](SizeType index) { - RAPIDJSON_ASSERT(IsArray()); - RAPIDJSON_ASSERT(index < data_.a.size); - return GetElementsPointer()[index]; - } - const GenericValue& operator[](SizeType index) const { return const_cast(*this)[index]; } - - //! Element iterator - /*! \pre IsArray() == true */ - ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); } - //! \em Past-the-end element iterator - /*! \pre IsArray() == true */ - ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; } - //! Constant element iterator - /*! \pre IsArray() == true */ - ConstValueIterator Begin() const { return const_cast(*this).Begin(); } - //! Constant \em past-the-end element iterator - /*! \pre IsArray() == true */ - ConstValueIterator End() const { return const_cast(*this).End(); } - - //! Request the array to have enough capacity to store elements. - /*! \param newCapacity The capacity that the array at least need to have. - \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \note Linear time complexity. - */ - GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) { - RAPIDJSON_ASSERT(IsArray()); - if (newCapacity > data_.a.capacity) { - SetElementsPointer(reinterpret_cast(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)))); - data_.a.capacity = newCapacity; - } - return *this; - } - - //! Append a GenericValue at the end of the array. - /*! \param value Value to be appended. - \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). - \pre IsArray() == true - \post value.IsNull() == true - \return The value itself for fluent API. - \note The ownership of \c value will be transferred to this array on success. - \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. - \note Amortized constant time complexity. - */ - GenericValue& PushBack(GenericValue& value, Allocator& allocator) { - RAPIDJSON_ASSERT(IsArray()); - if (data_.a.size >= data_.a.capacity) - Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator); - GetElementsPointer()[data_.a.size++].RawAssign(value); - return *this; - } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - GenericValue& PushBack(GenericValue&& value, Allocator& allocator) { - return PushBack(value, allocator); - } -#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS - - //! Append a constant string reference at the end of the array. - /*! \param value Constant string reference to be appended. - \param allocator Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator(). - \pre IsArray() == true - \return The value itself for fluent API. - \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. - \note Amortized constant time complexity. - \see GenericStringRef - */ - GenericValue& PushBack(StringRefType value, Allocator& allocator) { - return (*this).template PushBack(value, allocator); - } - - //! Append a primitive value at the end of the array. - /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t - \param value Value of primitive type T to be appended. - \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). - \pre IsArray() == true - \return The value itself for fluent API. - \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. - - \note The source type \c T explicitly disallows all pointer types, - especially (\c const) \ref Ch*. This helps avoiding implicitly - referencing character strings with insufficient lifetime, use - \ref PushBack(GenericValue&, Allocator&) or \ref - PushBack(StringRefType, Allocator&). - All other pointer types would implicitly convert to \c bool, - use an explicit cast instead, if needed. - \note Amortized constant time complexity. - */ - template - RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) - PushBack(T value, Allocator& allocator) { - GenericValue v(value); - return PushBack(v, allocator); - } - - //! Remove the last element in the array. - /*! - \note Constant time complexity. - */ - GenericValue& PopBack() { - RAPIDJSON_ASSERT(IsArray()); - RAPIDJSON_ASSERT(!Empty()); - GetElementsPointer()[--data_.a.size].~GenericValue(); - return *this; - } - - //! Remove an element of array by iterator. - /*! - \param pos iterator to the element to remove - \pre IsArray() == true && \ref Begin() <= \c pos < \ref End() - \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned. - \note Linear time complexity. - */ - ValueIterator Erase(ConstValueIterator pos) { - return Erase(pos, pos + 1); - } - - //! Remove elements in the range [first, last) of the array. - /*! - \param first iterator to the first element to remove - \param last iterator following the last element to remove - \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End() - \return Iterator following the last removed element. - \note Linear time complexity. - */ - ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) { - RAPIDJSON_ASSERT(IsArray()); - RAPIDJSON_ASSERT(data_.a.size > 0); - RAPIDJSON_ASSERT(GetElementsPointer() != 0); - RAPIDJSON_ASSERT(first >= Begin()); - RAPIDJSON_ASSERT(first <= last); - RAPIDJSON_ASSERT(last <= End()); - ValueIterator pos = Begin() + (first - Begin()); - for (ValueIterator itr = pos; itr != last; ++itr) - itr->~GenericValue(); - std::memmove(static_cast(pos), last, static_cast(End() - last) * sizeof(GenericValue)); - data_.a.size -= static_cast(last - first); - return pos; - } - - Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); } - ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); } - - //@} - - //!@name Number - //@{ - - int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; } - unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; } - int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; } - uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; } - - //! Get the value as double type. - /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessDouble() to check whether the converison is lossless. - */ - double GetDouble() const { - RAPIDJSON_ASSERT(IsNumber()); - if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion. - if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double - if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double - if ((data_.f.flags & kInt64Flag) != 0) return static_cast(data_.n.i64); // int64_t -> double (may lose precision) - RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast(data_.n.u64); // uint64_t -> double (may lose precision) - } - - //! Get the value as float type. - /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessFloat() to check whether the converison is lossless. - */ - float GetFloat() const { - return static_cast(GetDouble()); - } - - GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; } - GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; } - GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; } - GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; } - GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; } - GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(static_cast(f)); return *this; } - - //@} - - //!@name String - //@{ - - const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); } - - //! Get the length of string. - /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength(). - */ - SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); } - - //! Set this value as a string without copying source string. - /*! This version has better performance with supplied length, and also support string containing null character. - \param s source string pointer. - \param length The length of source string, excluding the trailing null terminator. - \return The value itself for fluent API. - \post IsString() == true && GetString() == s && GetStringLength() == length - \see SetString(StringRefType) - */ - GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); } - - //! Set this value as a string without copying source string. - /*! \param s source string reference - \return The value itself for fluent API. - \post IsString() == true && GetString() == s && GetStringLength() == s.length - */ - GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; } - - //! Set this value as a string by copying from source string. - /*! This version has better performance with supplied length, and also support string containing null character. - \param s source string. - \param length The length of source string, excluding the trailing null terminator. - \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length - */ - GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { return SetString(StringRef(s, length), allocator); } - - //! Set this value as a string by copying from source string. - /*! \param s source string. - \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length - */ - GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(StringRef(s), allocator); } - - //! Set this value as a string by copying from source string. - /*! \param s source string reference - \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \post IsString() == true && GetString() != s.s && strcmp(GetString(),s) == 0 && GetStringLength() == length - */ - GenericValue& SetString(StringRefType s, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, allocator); return *this; } - -#if RAPIDJSON_HAS_STDSTRING - //! Set this value as a string by copying from source string. - /*! \param s source string. - \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size() - \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. - */ - GenericValue& SetString(const std::basic_string& s, Allocator& allocator) { return SetString(StringRef(s), allocator); } -#endif - - //@} - - //!@name Array - //@{ - - //! Templated version for checking whether this value is type T. - /*! - \tparam T Either \c bool, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c float, \c const \c char*, \c std::basic_string - */ - template - bool Is() const { return internal::TypeHelper::Is(*this); } - - template - T Get() const { return internal::TypeHelper::Get(*this); } - - template - T Get() { return internal::TypeHelper::Get(*this); } - - template - ValueType& Set(const T& data) { return internal::TypeHelper::Set(*this, data); } - - template - ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper::Set(*this, data, allocator); } - - //@} - - //! Generate events of this value to a Handler. - /*! This function adopts the GoF visitor pattern. - Typical usage is to output this JSON value as JSON text via Writer, which is a Handler. - It can also be used to deep clone this value via GenericDocument, which is also a Handler. - \tparam Handler type of handler. - \param handler An object implementing concept Handler. - */ - template - bool Accept(Handler& handler) const { - switch(GetType()) { - case kNullType: return handler.Null(); - case kFalseType: return handler.Bool(false); - case kTrueType: return handler.Bool(true); - - case kObjectType: - if (RAPIDJSON_UNLIKELY(!handler.StartObject())) - return false; - for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) { - RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator. - if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0))) - return false; - if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler))) - return false; - } - return handler.EndObject(data_.o.size); - - case kArrayType: - if (RAPIDJSON_UNLIKELY(!handler.StartArray())) - return false; - for (const GenericValue* v = Begin(); v != End(); ++v) - if (RAPIDJSON_UNLIKELY(!v->Accept(handler))) - return false; - return handler.EndArray(data_.a.size); - - case kStringType: - return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0); - - default: - RAPIDJSON_ASSERT(GetType() == kNumberType); - if (IsDouble()) return handler.Double(data_.n.d); - else if (IsInt()) return handler.Int(data_.n.i.i); - else if (IsUint()) return handler.Uint(data_.n.u.u); - else if (IsInt64()) return handler.Int64(data_.n.i64); - else return handler.Uint64(data_.n.u64); - } - } - -private: - template friend class GenericValue; - template friend class GenericDocument; - - enum { - kBoolFlag = 0x0008, - kNumberFlag = 0x0010, - kIntFlag = 0x0020, - kUintFlag = 0x0040, - kInt64Flag = 0x0080, - kUint64Flag = 0x0100, - kDoubleFlag = 0x0200, - kStringFlag = 0x0400, - kCopyFlag = 0x0800, - kInlineStrFlag = 0x1000, - - // Initial flags of different types. - kNullFlag = kNullType, - kTrueFlag = kTrueType | kBoolFlag, - kFalseFlag = kFalseType | kBoolFlag, - kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag, - kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag, - kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag, - kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag, - kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag, - kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag, - kConstStringFlag = kStringType | kStringFlag, - kCopyStringFlag = kStringType | kStringFlag | kCopyFlag, - kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag, - kObjectFlag = kObjectType, - kArrayFlag = kArrayType, - - kTypeMask = 0x07 - }; - - static const SizeType kDefaultArrayCapacity = RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY; - static const SizeType kDefaultObjectCapacity = RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY; - - struct Flag { -#if RAPIDJSON_48BITPOINTER_OPTIMIZATION - char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer -#elif RAPIDJSON_64BIT - char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes -#else - char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes -#endif - uint16_t flags; - }; - - struct String { - SizeType length; - SizeType hashcode; //!< reserved - const Ch* str; - }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode - - // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars - // (excluding the terminating zero) and store a value to determine the length of the contained - // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string - // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as - // the string terminator as well. For getting the string length back from that value just use - // "MaxSize - str[LenPos]". - // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode, - // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings). - struct ShortString { - enum { MaxChars = sizeof(static_cast(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize }; - Ch str[MaxChars]; - - inline static bool Usable(SizeType len) { return (MaxSize >= len); } - inline void SetLength(SizeType len) { str[LenPos] = static_cast(MaxSize - len); } - inline SizeType GetLength() const { return static_cast(MaxSize - str[LenPos]); } - }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode - - // By using proper binary layout, retrieval of different integer types do not need conversions. - union Number { -#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN - struct I { - int i; - char padding[4]; - }i; - struct U { - unsigned u; - char padding2[4]; - }u; -#else - struct I { - char padding[4]; - int i; - }i; - struct U { - char padding2[4]; - unsigned u; - }u; -#endif - int64_t i64; - uint64_t u64; - double d; - }; // 8 bytes - - struct ObjectData { - SizeType size; - SizeType capacity; - Member* members; - }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode - - struct ArrayData { - SizeType size; - SizeType capacity; - GenericValue* elements; - }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode - - union Data { - String s; - ShortString ss; - Number n; - ObjectData o; - ArrayData a; - Flag f; - }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION - - RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); } - RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); } - RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); } - RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); } - RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); } - RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); } - - // Initialize this value as array with initial data, without calling destructor. - void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) { - data_.f.flags = kArrayFlag; - if (count) { - GenericValue* e = static_cast(allocator.Malloc(count * sizeof(GenericValue))); - SetElementsPointer(e); - std::memcpy(static_cast(e), values, count * sizeof(GenericValue)); - } - else - SetElementsPointer(0); - data_.a.size = data_.a.capacity = count; - } - - //! Initialize this value as object with initial data, without calling destructor. - void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) { - data_.f.flags = kObjectFlag; - if (count) { - Member* m = static_cast(allocator.Malloc(count * sizeof(Member))); - SetMembersPointer(m); - std::memcpy(static_cast(m), members, count * sizeof(Member)); - } - else - SetMembersPointer(0); - data_.o.size = data_.o.capacity = count; - } - - //! Initialize this value as constant string, without calling destructor. - void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT { - data_.f.flags = kConstStringFlag; - SetStringPointer(s); - data_.s.length = s.length; - } - - //! Initialize this value as copy string with initial data, without calling destructor. - void SetStringRaw(StringRefType s, Allocator& allocator) { - Ch* str = 0; - if (ShortString::Usable(s.length)) { - data_.f.flags = kShortStringFlag; - data_.ss.SetLength(s.length); - str = data_.ss.str; - } else { - data_.f.flags = kCopyStringFlag; - data_.s.length = s.length; - str = static_cast(allocator.Malloc((s.length + 1) * sizeof(Ch))); - SetStringPointer(str); - } - std::memcpy(str, s, s.length * sizeof(Ch)); - str[s.length] = '\0'; - } - - //! Assignment without calling destructor - void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT { - data_ = rhs.data_; - // data_.f.flags = rhs.data_.f.flags; - rhs.data_.f.flags = kNullFlag; - } - - template - bool StringEqual(const GenericValue& rhs) const { - RAPIDJSON_ASSERT(IsString()); - RAPIDJSON_ASSERT(rhs.IsString()); - - const SizeType len1 = GetStringLength(); - const SizeType len2 = rhs.GetStringLength(); - if(len1 != len2) { return false; } - - const Ch* const str1 = GetString(); - const Ch* const str2 = rhs.GetString(); - if(str1 == str2) { return true; } // fast path for constant string - - return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0); - } - - Data data_; -}; - -//! GenericValue with UTF8 encoding -typedef GenericValue > Value; - -/////////////////////////////////////////////////////////////////////////////// -// GenericDocument - -//! A document for parsing JSON text as DOM. -/*! - \note implements Handler concept - \tparam Encoding Encoding for both parsing and string storage. - \tparam Allocator Allocator for allocating memory for the DOM - \tparam StackAllocator Allocator for allocating memory for stack during parsing. - \warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor. To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue. -*/ -template -class GenericDocument : public GenericValue { -public: - typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. - typedef GenericValue ValueType; //!< Value type of the document. - typedef Allocator AllocatorType; //!< Allocator type from template parameter. - - //! Constructor - /*! Creates an empty document of specified type. - \param type Mandatory type of object to create. - \param allocator Optional allocator for allocating memory. - \param stackCapacity Optional initial capacity of stack in bytes. - \param stackAllocator Optional allocator for allocating memory for stack. - */ - explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : - GenericValue(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() - { - if (!allocator_) - ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); - } - - //! Constructor - /*! Creates an empty document which type is Null. - \param allocator Optional allocator for allocating memory. - \param stackCapacity Optional initial capacity of stack in bytes. - \param stackAllocator Optional allocator for allocating memory for stack. - */ - GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : - allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() - { - if (!allocator_) - ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); - } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - //! Move constructor in C++11 - GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT - : ValueType(std::forward(rhs)), // explicit cast to avoid prohibited move from Document - allocator_(rhs.allocator_), - ownAllocator_(rhs.ownAllocator_), - stack_(std::move(rhs.stack_)), - parseResult_(rhs.parseResult_) - { - rhs.allocator_ = 0; - rhs.ownAllocator_ = 0; - rhs.parseResult_ = ParseResult(); - } -#endif - - ~GenericDocument() { - Destroy(); - } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - //! Move assignment in C++11 - GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT - { - // The cast to ValueType is necessary here, because otherwise it would - // attempt to call GenericValue's templated assignment operator. - ValueType::operator=(std::forward(rhs)); - - // Calling the destructor here would prematurely call stack_'s destructor - Destroy(); - - allocator_ = rhs.allocator_; - ownAllocator_ = rhs.ownAllocator_; - stack_ = std::move(rhs.stack_); - parseResult_ = rhs.parseResult_; - - rhs.allocator_ = 0; - rhs.ownAllocator_ = 0; - rhs.parseResult_ = ParseResult(); - - return *this; - } -#endif - - //! Exchange the contents of this document with those of another. - /*! - \param rhs Another document. - \note Constant complexity. - \see GenericValue::Swap - */ - GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT { - ValueType::Swap(rhs); - stack_.Swap(rhs.stack_); - internal::Swap(allocator_, rhs.allocator_); - internal::Swap(ownAllocator_, rhs.ownAllocator_); - internal::Swap(parseResult_, rhs.parseResult_); - return *this; - } - - // Allow Swap with ValueType. - // Refer to Effective C++ 3rd Edition/Item 33: Avoid hiding inherited names. - using ValueType::Swap; - - //! free-standing swap function helper - /*! - Helper function to enable support for common swap implementation pattern based on \c std::swap: - \code - void swap(MyClass& a, MyClass& b) { - using std::swap; - swap(a.doc, b.doc); - // ... - } - \endcode - \see Swap() - */ - friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } - - //! Populate this document by a generator which produces SAX events. - /*! \tparam Generator A functor with bool f(Handler) prototype. - \param g Generator functor which sends SAX events to the parameter. - \return The document itself for fluent API. - */ - template - GenericDocument& Populate(Generator& g) { - ClearStackOnExit scope(*this); - if (g(*this)) { - RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object - ValueType::operator=(*stack_.template Pop(1));// Move value from stack to document - } - return *this; - } - - //!@name Parse from stream - //!@{ - - //! Parse JSON text from an input stream (with Encoding conversion) - /*! \tparam parseFlags Combination of \ref ParseFlag. - \tparam SourceEncoding Encoding of input stream - \tparam InputStream Type of input stream, implementing Stream concept - \param is Input stream to be parsed. - \return The document itself for fluent API. - */ - template - GenericDocument& ParseStream(InputStream& is) { - GenericReader reader( - stack_.HasAllocator() ? &stack_.GetAllocator() : 0); - ClearStackOnExit scope(*this); - parseResult_ = reader.template Parse(is, *this); - if (parseResult_) { - RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object - ValueType::operator=(*stack_.template Pop(1));// Move value from stack to document - } - return *this; - } - - //! Parse JSON text from an input stream - /*! \tparam parseFlags Combination of \ref ParseFlag. - \tparam InputStream Type of input stream, implementing Stream concept - \param is Input stream to be parsed. - \return The document itself for fluent API. - */ - template - GenericDocument& ParseStream(InputStream& is) { - return ParseStream(is); - } - - //! Parse JSON text from an input stream (with \ref kParseDefaultFlags) - /*! \tparam InputStream Type of input stream, implementing Stream concept - \param is Input stream to be parsed. - \return The document itself for fluent API. - */ - template - GenericDocument& ParseStream(InputStream& is) { - return ParseStream(is); - } - //!@} - - //!@name Parse in-place from mutable string - //!@{ - - //! Parse JSON text from a mutable string - /*! \tparam parseFlags Combination of \ref ParseFlag. - \param str Mutable zero-terminated string to be parsed. - \return The document itself for fluent API. - */ - template - GenericDocument& ParseInsitu(Ch* str) { - GenericInsituStringStream s(str); - return ParseStream(s); - } - - //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags) - /*! \param str Mutable zero-terminated string to be parsed. - \return The document itself for fluent API. - */ - GenericDocument& ParseInsitu(Ch* str) { - return ParseInsitu(str); - } - //!@} - - //!@name Parse from read-only string - //!@{ - - //! Parse JSON text from a read-only string (with Encoding conversion) - /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). - \tparam SourceEncoding Transcoding from input Encoding - \param str Read-only zero-terminated string to be parsed. - */ - template - GenericDocument& Parse(const typename SourceEncoding::Ch* str) { - RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); - GenericStringStream s(str); - return ParseStream(s); - } - - //! Parse JSON text from a read-only string - /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). - \param str Read-only zero-terminated string to be parsed. - */ - template - GenericDocument& Parse(const Ch* str) { - return Parse(str); - } - - //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags) - /*! \param str Read-only zero-terminated string to be parsed. - */ - GenericDocument& Parse(const Ch* str) { - return Parse(str); - } - - template - GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) { - RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); - MemoryStream ms(reinterpret_cast(str), length * sizeof(typename SourceEncoding::Ch)); - EncodedInputStream is(ms); - ParseStream(is); - return *this; - } - - template - GenericDocument& Parse(const Ch* str, size_t length) { - return Parse(str, length); - } - - GenericDocument& Parse(const Ch* str, size_t length) { - return Parse(str, length); - } - -#if RAPIDJSON_HAS_STDSTRING - template - GenericDocument& Parse(const std::basic_string& str) { - // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t) - return Parse(str.c_str()); - } - - template - GenericDocument& Parse(const std::basic_string& str) { - return Parse(str.c_str()); - } - - GenericDocument& Parse(const std::basic_string& str) { - return Parse(str); - } -#endif // RAPIDJSON_HAS_STDSTRING - - //!@} - - //!@name Handling parse errors - //!@{ - - //! Whether a parse error has occurred in the last parsing. - bool HasParseError() const { return parseResult_.IsError(); } - - //! Get the \ref ParseErrorCode of last parsing. - ParseErrorCode GetParseError() const { return parseResult_.Code(); } - - //! Get the position of last parsing error in input, 0 otherwise. - size_t GetErrorOffset() const { return parseResult_.Offset(); } - - //! Implicit conversion to get the last parse result -#ifndef __clang // -Wdocumentation - /*! \return \ref ParseResult of the last parse operation - - \code - Document doc; - ParseResult ok = doc.Parse(json); - if (!ok) - printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset()); - \endcode - */ -#endif - operator ParseResult() const { return parseResult_; } - //!@} - - //! Get the allocator of this document. - Allocator& GetAllocator() { - RAPIDJSON_ASSERT(allocator_); - return *allocator_; - } - - //! Get the capacity of stack in bytes. - size_t GetStackCapacity() const { return stack_.GetCapacity(); } - -private: - // clear stack on any exit from ParseStream, e.g. due to exception - struct ClearStackOnExit { - explicit ClearStackOnExit(GenericDocument& d) : d_(d) {} - ~ClearStackOnExit() { d_.ClearStack(); } - private: - ClearStackOnExit(const ClearStackOnExit&); - ClearStackOnExit& operator=(const ClearStackOnExit&); - GenericDocument& d_; - }; - - // callers of the following private Handler functions - // template friend class GenericReader; // for parsing - template friend class GenericValue; // for deep copying - -public: - // Implementation of Handler - bool Null() { new (stack_.template Push()) ValueType(); return true; } - bool Bool(bool b) { new (stack_.template Push()) ValueType(b); return true; } - bool Int(int i) { new (stack_.template Push()) ValueType(i); return true; } - bool Uint(unsigned i) { new (stack_.template Push()) ValueType(i); return true; } - bool Int64(int64_t i) { new (stack_.template Push()) ValueType(i); return true; } - bool Uint64(uint64_t i) { new (stack_.template Push()) ValueType(i); return true; } - bool Double(double d) { new (stack_.template Push()) ValueType(d); return true; } - - bool RawNumber(const Ch* str, SizeType length, bool copy) { - if (copy) - new (stack_.template Push()) ValueType(str, length, GetAllocator()); - else - new (stack_.template Push()) ValueType(str, length); - return true; - } - - bool String(const Ch* str, SizeType length, bool copy) { - if (copy) - new (stack_.template Push()) ValueType(str, length, GetAllocator()); - else - new (stack_.template Push()) ValueType(str, length); - return true; - } - - bool StartObject() { new (stack_.template Push()) ValueType(kObjectType); return true; } - - bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); } - - bool EndObject(SizeType memberCount) { - typename ValueType::Member* members = stack_.template Pop(memberCount); - stack_.template Top()->SetObjectRaw(members, memberCount, GetAllocator()); - return true; - } - - bool StartArray() { new (stack_.template Push()) ValueType(kArrayType); return true; } - - bool EndArray(SizeType elementCount) { - ValueType* elements = stack_.template Pop(elementCount); - stack_.template Top()->SetArrayRaw(elements, elementCount, GetAllocator()); - return true; - } - -private: - //! Prohibit copying - GenericDocument(const GenericDocument&); - //! Prohibit assignment - GenericDocument& operator=(const GenericDocument&); - - void ClearStack() { - if (Allocator::kNeedFree) - while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects) - (stack_.template Pop(1))->~ValueType(); - else - stack_.Clear(); - stack_.ShrinkToFit(); - } - - void Destroy() { - RAPIDJSON_DELETE(ownAllocator_); - } - - static const size_t kDefaultStackCapacity = 1024; - Allocator* allocator_; - Allocator* ownAllocator_; - internal::Stack stack_; - ParseResult parseResult_; -}; - -//! GenericDocument with UTF8 encoding -typedef GenericDocument > Document; - - -//! Helper class for accessing Value of array type. -/*! - Instance of this helper class is obtained by \c GenericValue::GetArray(). - In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1. -*/ -template -class GenericArray { -public: - typedef GenericArray ConstArray; - typedef GenericArray Array; - typedef ValueT PlainType; - typedef typename internal::MaybeAddConst::Type ValueType; - typedef ValueType* ValueIterator; // This may be const or non-const iterator - typedef const ValueT* ConstValueIterator; - typedef typename ValueType::AllocatorType AllocatorType; - typedef typename ValueType::StringRefType StringRefType; - - template - friend class GenericValue; - - GenericArray(const GenericArray& rhs) : value_(rhs.value_) {} - GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; } - ~GenericArray() {} - - SizeType Size() const { return value_.Size(); } - SizeType Capacity() const { return value_.Capacity(); } - bool Empty() const { return value_.Empty(); } - void Clear() const { value_.Clear(); } - ValueType& operator[](SizeType index) const { return value_[index]; } - ValueIterator Begin() const { return value_.Begin(); } - ValueIterator End() const { return value_.End(); } - GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; } - GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } -#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS - GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } - template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (const GenericArray&)) PushBack(T value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } - GenericArray PopBack() const { value_.PopBack(); return *this; } - ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); } - ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); } - -#if RAPIDJSON_HAS_CXX11_RANGE_FOR - ValueIterator begin() const { return value_.Begin(); } - ValueIterator end() const { return value_.End(); } -#endif - -private: - GenericArray(); - GenericArray(ValueType& value) : value_(value) {} - ValueType& value_; -}; - -//! Helper class for accessing Value of object type. -/*! - Instance of this helper class is obtained by \c GenericValue::GetObject(). - In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1. -*/ -template -class GenericObject { -public: - typedef GenericObject ConstObject; - typedef GenericObject Object; - typedef ValueT PlainType; - typedef typename internal::MaybeAddConst::Type ValueType; - typedef GenericMemberIterator MemberIterator; // This may be const or non-const iterator - typedef GenericMemberIterator ConstMemberIterator; - typedef typename ValueType::AllocatorType AllocatorType; - typedef typename ValueType::StringRefType StringRefType; - typedef typename ValueType::EncodingType EncodingType; - typedef typename ValueType::Ch Ch; - - template - friend class GenericValue; - - GenericObject(const GenericObject& rhs) : value_(rhs.value_) {} - GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; } - ~GenericObject() {} - - SizeType MemberCount() const { return value_.MemberCount(); } - SizeType MemberCapacity() const { return value_.MemberCapacity(); } - bool ObjectEmpty() const { return value_.ObjectEmpty(); } - template ValueType& operator[](T* name) const { return value_[name]; } - template ValueType& operator[](const GenericValue& name) const { return value_[name]; } -#if RAPIDJSON_HAS_STDSTRING - ValueType& operator[](const std::basic_string& name) const { return value_[name]; } -#endif - MemberIterator MemberBegin() const { return value_.MemberBegin(); } - MemberIterator MemberEnd() const { return value_.MemberEnd(); } - GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const { value_.MemberReserve(newCapacity, allocator); return *this; } - bool HasMember(const Ch* name) const { return value_.HasMember(name); } -#if RAPIDJSON_HAS_STDSTRING - bool HasMember(const std::basic_string& name) const { return value_.HasMember(name); } -#endif - template bool HasMember(const GenericValue& name) const { return value_.HasMember(name); } - MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); } - template MemberIterator FindMember(const GenericValue& name) const { return value_.FindMember(name); } -#if RAPIDJSON_HAS_STDSTRING - MemberIterator FindMember(const std::basic_string& name) const { return value_.FindMember(name); } -#endif - GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } - GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } -#if RAPIDJSON_HAS_STDSTRING - GenericObject AddMember(ValueType& name, std::basic_string& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } -#endif - template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } - GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } - GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } - GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } -#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS - GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } - GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } - template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } - void RemoveAllMembers() { value_.RemoveAllMembers(); } - bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); } -#if RAPIDJSON_HAS_STDSTRING - bool RemoveMember(const std::basic_string& name) const { return value_.RemoveMember(name); } -#endif - template bool RemoveMember(const GenericValue& name) const { return value_.RemoveMember(name); } - MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); } - MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); } - MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); } - bool EraseMember(const Ch* name) const { return value_.EraseMember(name); } -#if RAPIDJSON_HAS_STDSTRING - bool EraseMember(const std::basic_string& name) const { return EraseMember(ValueType(StringRef(name))); } -#endif - template bool EraseMember(const GenericValue& name) const { return value_.EraseMember(name); } - -#if RAPIDJSON_HAS_CXX11_RANGE_FOR - MemberIterator begin() const { return value_.MemberBegin(); } - MemberIterator end() const { return value_.MemberEnd(); } -#endif - -private: - GenericObject(); - GenericObject(ValueType& value) : value_(value) {} - ValueType& value_; -}; - -RAPIDJSON_NAMESPACE_END -RAPIDJSON_DIAG_POP - -#endif // RAPIDJSON_DOCUMENT_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/encodedstream.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/encodedstream.h deleted file mode 100644 index 223601c0..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/encodedstream.h +++ /dev/null @@ -1,299 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_ENCODEDSTREAM_H_ -#define RAPIDJSON_ENCODEDSTREAM_H_ - -#include "stream.h" -#include "memorystream.h" - -#ifdef __GNUC__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(effc++) -#endif - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(padded) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! Input byte stream wrapper with a statically bound encoding. -/*! - \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. - \tparam InputByteStream Type of input byte stream. For example, FileReadStream. -*/ -template -class EncodedInputStream { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); -public: - typedef typename Encoding::Ch Ch; - - EncodedInputStream(InputByteStream& is) : is_(is) { - current_ = Encoding::TakeBOM(is_); - } - - Ch Peek() const { return current_; } - Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; } - size_t Tell() const { return is_.Tell(); } - - // Not implemented - void Put(Ch) { RAPIDJSON_ASSERT(false); } - void Flush() { RAPIDJSON_ASSERT(false); } - Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } - -private: - EncodedInputStream(const EncodedInputStream&); - EncodedInputStream& operator=(const EncodedInputStream&); - - InputByteStream& is_; - Ch current_; -}; - -//! Specialized for UTF8 MemoryStream. -template <> -class EncodedInputStream, MemoryStream> { -public: - typedef UTF8<>::Ch Ch; - - EncodedInputStream(MemoryStream& is) : is_(is) { - if (static_cast(is_.Peek()) == 0xEFu) is_.Take(); - if (static_cast(is_.Peek()) == 0xBBu) is_.Take(); - if (static_cast(is_.Peek()) == 0xBFu) is_.Take(); - } - Ch Peek() const { return is_.Peek(); } - Ch Take() { return is_.Take(); } - size_t Tell() const { return is_.Tell(); } - - // Not implemented - void Put(Ch) {} - void Flush() {} - Ch* PutBegin() { return 0; } - size_t PutEnd(Ch*) { return 0; } - - MemoryStream& is_; - -private: - EncodedInputStream(const EncodedInputStream&); - EncodedInputStream& operator=(const EncodedInputStream&); -}; - -//! Output byte stream wrapper with statically bound encoding. -/*! - \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. - \tparam OutputByteStream Type of input byte stream. For example, FileWriteStream. -*/ -template -class EncodedOutputStream { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); -public: - typedef typename Encoding::Ch Ch; - - EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) { - if (putBOM) - Encoding::PutBOM(os_); - } - - void Put(Ch c) { Encoding::Put(os_, c); } - void Flush() { os_.Flush(); } - - // Not implemented - Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} - Ch Take() { RAPIDJSON_ASSERT(false); return 0;} - size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } - Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } - -private: - EncodedOutputStream(const EncodedOutputStream&); - EncodedOutputStream& operator=(const EncodedOutputStream&); - - OutputByteStream& os_; -}; - -#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8::x, UTF16LE::x, UTF16BE::x, UTF32LE::x, UTF32BE::x - -//! Input stream wrapper with dynamically bound encoding and automatic encoding detection. -/*! - \tparam CharType Type of character for reading. - \tparam InputByteStream type of input byte stream to be wrapped. -*/ -template -class AutoUTFInputStream { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); -public: - typedef CharType Ch; - - //! Constructor. - /*! - \param is input stream to be wrapped. - \param type UTF encoding type if it is not detected from the stream. - */ - AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) { - RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); - DetectType(); - static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) }; - takeFunc_ = f[type_]; - current_ = takeFunc_(*is_); - } - - UTFType GetType() const { return type_; } - bool HasBOM() const { return hasBOM_; } - - Ch Peek() const { return current_; } - Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; } - size_t Tell() const { return is_->Tell(); } - - // Not implemented - void Put(Ch) { RAPIDJSON_ASSERT(false); } - void Flush() { RAPIDJSON_ASSERT(false); } - Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } - -private: - AutoUTFInputStream(const AutoUTFInputStream&); - AutoUTFInputStream& operator=(const AutoUTFInputStream&); - - // Detect encoding type with BOM or RFC 4627 - void DetectType() { - // BOM (Byte Order Mark): - // 00 00 FE FF UTF-32BE - // FF FE 00 00 UTF-32LE - // FE FF UTF-16BE - // FF FE UTF-16LE - // EF BB BF UTF-8 - - const unsigned char* c = reinterpret_cast(is_->Peek4()); - if (!c) - return; - - unsigned bom = static_cast(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24)); - hasBOM_ = false; - if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } - else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } - else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); } - else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take(); } - else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); } - - // RFC 4627: Section 3 - // "Since the first two characters of a JSON text will always be ASCII - // characters [RFC0020], it is possible to determine whether an octet - // stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking - // at the pattern of nulls in the first four octets." - // 00 00 00 xx UTF-32BE - // 00 xx 00 xx UTF-16BE - // xx 00 00 00 UTF-32LE - // xx 00 xx 00 UTF-16LE - // xx xx xx xx UTF-8 - - if (!hasBOM_) { - int pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0); - switch (pattern) { - case 0x08: type_ = kUTF32BE; break; - case 0x0A: type_ = kUTF16BE; break; - case 0x01: type_ = kUTF32LE; break; - case 0x05: type_ = kUTF16LE; break; - case 0x0F: type_ = kUTF8; break; - default: break; // Use type defined by user. - } - } - - // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. - if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); - if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); - } - - typedef Ch (*TakeFunc)(InputByteStream& is); - InputByteStream* is_; - UTFType type_; - Ch current_; - TakeFunc takeFunc_; - bool hasBOM_; -}; - -//! Output stream wrapper with dynamically bound encoding and automatic encoding detection. -/*! - \tparam CharType Type of character for writing. - \tparam OutputByteStream type of output byte stream to be wrapped. -*/ -template -class AutoUTFOutputStream { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); -public: - typedef CharType Ch; - - //! Constructor. - /*! - \param os output stream to be wrapped. - \param type UTF encoding type. - \param putBOM Whether to write BOM at the beginning of the stream. - */ - AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) { - RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); - - // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. - if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); - if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); - - static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) }; - putFunc_ = f[type_]; - - if (putBOM) - PutBOM(); - } - - UTFType GetType() const { return type_; } - - void Put(Ch c) { putFunc_(*os_, c); } - void Flush() { os_->Flush(); } - - // Not implemented - Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} - Ch Take() { RAPIDJSON_ASSERT(false); return 0;} - size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } - Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } - -private: - AutoUTFOutputStream(const AutoUTFOutputStream&); - AutoUTFOutputStream& operator=(const AutoUTFOutputStream&); - - void PutBOM() { - typedef void (*PutBOMFunc)(OutputByteStream&); - static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) }; - f[type_](*os_); - } - - typedef void (*PutFunc)(OutputByteStream&, Ch); - - OutputByteStream* os_; - UTFType type_; - PutFunc putFunc_; -}; - -#undef RAPIDJSON_ENCODINGS_FUNC - -RAPIDJSON_NAMESPACE_END - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -#ifdef __GNUC__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/encodings.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/encodings.h deleted file mode 100644 index 0b244679..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/encodings.h +++ /dev/null @@ -1,716 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_ENCODINGS_H_ -#define RAPIDJSON_ENCODINGS_H_ - -#include "rapidjson.h" - -#if defined(_MSC_VER) && !defined(__clang__) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data -RAPIDJSON_DIAG_OFF(4702) // unreachable code -#elif defined(__GNUC__) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(effc++) -RAPIDJSON_DIAG_OFF(overflow) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -/////////////////////////////////////////////////////////////////////////////// -// Encoding - -/*! \class rapidjson::Encoding - \brief Concept for encoding of Unicode characters. - -\code -concept Encoding { - typename Ch; //! Type of character. A "character" is actually a code unit in unicode's definition. - - enum { supportUnicode = 1 }; // or 0 if not supporting unicode - - //! \brief Encode a Unicode codepoint to an output stream. - //! \param os Output stream. - //! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively. - template - static void Encode(OutputStream& os, unsigned codepoint); - - //! \brief Decode a Unicode codepoint from an input stream. - //! \param is Input stream. - //! \param codepoint Output of the unicode codepoint. - //! \return true if a valid codepoint can be decoded from the stream. - template - static bool Decode(InputStream& is, unsigned* codepoint); - - //! \brief Validate one Unicode codepoint from an encoded stream. - //! \param is Input stream to obtain codepoint. - //! \param os Output for copying one codepoint. - //! \return true if it is valid. - //! \note This function just validating and copying the codepoint without actually decode it. - template - static bool Validate(InputStream& is, OutputStream& os); - - // The following functions are deal with byte streams. - - //! Take a character from input byte stream, skip BOM if exist. - template - static CharType TakeBOM(InputByteStream& is); - - //! Take a character from input byte stream. - template - static Ch Take(InputByteStream& is); - - //! Put BOM to output byte stream. - template - static void PutBOM(OutputByteStream& os); - - //! Put a character to output byte stream. - template - static void Put(OutputByteStream& os, Ch c); -}; -\endcode -*/ - -/////////////////////////////////////////////////////////////////////////////// -// UTF8 - -//! UTF-8 encoding. -/*! http://en.wikipedia.org/wiki/UTF-8 - http://tools.ietf.org/html/rfc3629 - \tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char. - \note implements Encoding concept -*/ -template -struct UTF8 { - typedef CharType Ch; - - enum { supportUnicode = 1 }; - - template - static void Encode(OutputStream& os, unsigned codepoint) { - if (codepoint <= 0x7F) - os.Put(static_cast(codepoint & 0xFF)); - else if (codepoint <= 0x7FF) { - os.Put(static_cast(0xC0 | ((codepoint >> 6) & 0xFF))); - os.Put(static_cast(0x80 | ((codepoint & 0x3F)))); - } - else if (codepoint <= 0xFFFF) { - os.Put(static_cast(0xE0 | ((codepoint >> 12) & 0xFF))); - os.Put(static_cast(0x80 | ((codepoint >> 6) & 0x3F))); - os.Put(static_cast(0x80 | (codepoint & 0x3F))); - } - else { - RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); - os.Put(static_cast(0xF0 | ((codepoint >> 18) & 0xFF))); - os.Put(static_cast(0x80 | ((codepoint >> 12) & 0x3F))); - os.Put(static_cast(0x80 | ((codepoint >> 6) & 0x3F))); - os.Put(static_cast(0x80 | (codepoint & 0x3F))); - } - } - - template - static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { - if (codepoint <= 0x7F) - PutUnsafe(os, static_cast(codepoint & 0xFF)); - else if (codepoint <= 0x7FF) { - PutUnsafe(os, static_cast(0xC0 | ((codepoint >> 6) & 0xFF))); - PutUnsafe(os, static_cast(0x80 | ((codepoint & 0x3F)))); - } - else if (codepoint <= 0xFFFF) { - PutUnsafe(os, static_cast(0xE0 | ((codepoint >> 12) & 0xFF))); - PutUnsafe(os, static_cast(0x80 | ((codepoint >> 6) & 0x3F))); - PutUnsafe(os, static_cast(0x80 | (codepoint & 0x3F))); - } - else { - RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); - PutUnsafe(os, static_cast(0xF0 | ((codepoint >> 18) & 0xFF))); - PutUnsafe(os, static_cast(0x80 | ((codepoint >> 12) & 0x3F))); - PutUnsafe(os, static_cast(0x80 | ((codepoint >> 6) & 0x3F))); - PutUnsafe(os, static_cast(0x80 | (codepoint & 0x3F))); - } - } - - template - static bool Decode(InputStream& is, unsigned* codepoint) { -#define RAPIDJSON_COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast(c) & 0x3Fu) -#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast(c)) & mask) != 0) -#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70) - typename InputStream::Ch c = is.Take(); - if (!(c & 0x80)) { - *codepoint = static_cast(c); - return true; - } - - unsigned char type = GetRange(static_cast(c)); - if (type >= 32) { - *codepoint = 0; - } else { - *codepoint = (0xFFu >> type) & static_cast(c); - } - bool result = true; - switch (type) { - case 2: RAPIDJSON_TAIL(); return result; - case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; - case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result; - case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; - case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; - case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result; - case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; - default: return false; - } -#undef RAPIDJSON_COPY -#undef RAPIDJSON_TRANS -#undef RAPIDJSON_TAIL - } - - template - static bool Validate(InputStream& is, OutputStream& os) { -#define RAPIDJSON_COPY() os.Put(c = is.Take()) -#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast(c)) & mask) != 0) -#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70) - Ch c; - RAPIDJSON_COPY(); - if (!(c & 0x80)) - return true; - - bool result = true; - switch (GetRange(static_cast(c))) { - case 2: RAPIDJSON_TAIL(); return result; - case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; - case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result; - case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; - case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; - case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result; - case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; - default: return false; - } -#undef RAPIDJSON_COPY -#undef RAPIDJSON_TRANS -#undef RAPIDJSON_TAIL - } - - static unsigned char GetRange(unsigned char c) { - // Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ - // With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types. - static const unsigned char type[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, - 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, - 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, - 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, - 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, - }; - return type[c]; - } - - template - static CharType TakeBOM(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - typename InputByteStream::Ch c = Take(is); - if (static_cast(c) != 0xEFu) return c; - c = is.Take(); - if (static_cast(c) != 0xBBu) return c; - c = is.Take(); - if (static_cast(c) != 0xBFu) return c; - c = is.Take(); - return c; - } - - template - static Ch Take(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - return static_cast(is.Take()); - } - - template - static void PutBOM(OutputByteStream& os) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast(0xEFu)); - os.Put(static_cast(0xBBu)); - os.Put(static_cast(0xBFu)); - } - - template - static void Put(OutputByteStream& os, Ch c) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast(c)); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// UTF16 - -//! UTF-16 encoding. -/*! http://en.wikipedia.org/wiki/UTF-16 - http://tools.ietf.org/html/rfc2781 - \tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead. - \note implements Encoding concept - - \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. - For streaming, use UTF16LE and UTF16BE, which handle endianness. -*/ -template -struct UTF16 { - typedef CharType Ch; - RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2); - - enum { supportUnicode = 1 }; - - template - static void Encode(OutputStream& os, unsigned codepoint) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); - if (codepoint <= 0xFFFF) { - RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair - os.Put(static_cast(codepoint)); - } - else { - RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); - unsigned v = codepoint - 0x10000; - os.Put(static_cast((v >> 10) | 0xD800)); - os.Put(static_cast((v & 0x3FF) | 0xDC00)); - } - } - - - template - static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); - if (codepoint <= 0xFFFF) { - RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair - PutUnsafe(os, static_cast(codepoint)); - } - else { - RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); - unsigned v = codepoint - 0x10000; - PutUnsafe(os, static_cast((v >> 10) | 0xD800)); - PutUnsafe(os, static_cast((v & 0x3FF) | 0xDC00)); - } - } - - template - static bool Decode(InputStream& is, unsigned* codepoint) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); - typename InputStream::Ch c = is.Take(); - if (c < 0xD800 || c > 0xDFFF) { - *codepoint = static_cast(c); - return true; - } - else if (c <= 0xDBFF) { - *codepoint = (static_cast(c) & 0x3FF) << 10; - c = is.Take(); - *codepoint |= (static_cast(c) & 0x3FF); - *codepoint += 0x10000; - return c >= 0xDC00 && c <= 0xDFFF; - } - return false; - } - - template - static bool Validate(InputStream& is, OutputStream& os) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); - typename InputStream::Ch c; - os.Put(static_cast(c = is.Take())); - if (c < 0xD800 || c > 0xDFFF) - return true; - else if (c <= 0xDBFF) { - os.Put(c = is.Take()); - return c >= 0xDC00 && c <= 0xDFFF; - } - return false; - } -}; - -//! UTF-16 little endian encoding. -template -struct UTF16LE : UTF16 { - template - static CharType TakeBOM(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - CharType c = Take(is); - return static_cast(c) == 0xFEFFu ? Take(is) : c; - } - - template - static CharType Take(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - unsigned c = static_cast(is.Take()); - c |= static_cast(static_cast(is.Take())) << 8; - return static_cast(c); - } - - template - static void PutBOM(OutputByteStream& os) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast(0xFFu)); - os.Put(static_cast(0xFEu)); - } - - template - static void Put(OutputByteStream& os, CharType c) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast(static_cast(c) & 0xFFu)); - os.Put(static_cast((static_cast(c) >> 8) & 0xFFu)); - } -}; - -//! UTF-16 big endian encoding. -template -struct UTF16BE : UTF16 { - template - static CharType TakeBOM(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - CharType c = Take(is); - return static_cast(c) == 0xFEFFu ? Take(is) : c; - } - - template - static CharType Take(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - unsigned c = static_cast(static_cast(is.Take())) << 8; - c |= static_cast(static_cast(is.Take())); - return static_cast(c); - } - - template - static void PutBOM(OutputByteStream& os) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast(0xFEu)); - os.Put(static_cast(0xFFu)); - } - - template - static void Put(OutputByteStream& os, CharType c) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast((static_cast(c) >> 8) & 0xFFu)); - os.Put(static_cast(static_cast(c) & 0xFFu)); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// UTF32 - -//! UTF-32 encoding. -/*! http://en.wikipedia.org/wiki/UTF-32 - \tparam CharType Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead. - \note implements Encoding concept - - \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. - For streaming, use UTF32LE and UTF32BE, which handle endianness. -*/ -template -struct UTF32 { - typedef CharType Ch; - RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4); - - enum { supportUnicode = 1 }; - - template - static void Encode(OutputStream& os, unsigned codepoint) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); - RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); - os.Put(codepoint); - } - - template - static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); - RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); - PutUnsafe(os, codepoint); - } - - template - static bool Decode(InputStream& is, unsigned* codepoint) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); - Ch c = is.Take(); - *codepoint = c; - return c <= 0x10FFFF; - } - - template - static bool Validate(InputStream& is, OutputStream& os) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); - Ch c; - os.Put(c = is.Take()); - return c <= 0x10FFFF; - } -}; - -//! UTF-32 little endian enocoding. -template -struct UTF32LE : UTF32 { - template - static CharType TakeBOM(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - CharType c = Take(is); - return static_cast(c) == 0x0000FEFFu ? Take(is) : c; - } - - template - static CharType Take(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - unsigned c = static_cast(is.Take()); - c |= static_cast(static_cast(is.Take())) << 8; - c |= static_cast(static_cast(is.Take())) << 16; - c |= static_cast(static_cast(is.Take())) << 24; - return static_cast(c); - } - - template - static void PutBOM(OutputByteStream& os) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast(0xFFu)); - os.Put(static_cast(0xFEu)); - os.Put(static_cast(0x00u)); - os.Put(static_cast(0x00u)); - } - - template - static void Put(OutputByteStream& os, CharType c) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast(c & 0xFFu)); - os.Put(static_cast((c >> 8) & 0xFFu)); - os.Put(static_cast((c >> 16) & 0xFFu)); - os.Put(static_cast((c >> 24) & 0xFFu)); - } -}; - -//! UTF-32 big endian encoding. -template -struct UTF32BE : UTF32 { - template - static CharType TakeBOM(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - CharType c = Take(is); - return static_cast(c) == 0x0000FEFFu ? Take(is) : c; - } - - template - static CharType Take(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - unsigned c = static_cast(static_cast(is.Take())) << 24; - c |= static_cast(static_cast(is.Take())) << 16; - c |= static_cast(static_cast(is.Take())) << 8; - c |= static_cast(static_cast(is.Take())); - return static_cast(c); - } - - template - static void PutBOM(OutputByteStream& os) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast(0x00u)); - os.Put(static_cast(0x00u)); - os.Put(static_cast(0xFEu)); - os.Put(static_cast(0xFFu)); - } - - template - static void Put(OutputByteStream& os, CharType c) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast((c >> 24) & 0xFFu)); - os.Put(static_cast((c >> 16) & 0xFFu)); - os.Put(static_cast((c >> 8) & 0xFFu)); - os.Put(static_cast(c & 0xFFu)); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// ASCII - -//! ASCII encoding. -/*! http://en.wikipedia.org/wiki/ASCII - \tparam CharType Code unit for storing 7-bit ASCII data. Default is char. - \note implements Encoding concept -*/ -template -struct ASCII { - typedef CharType Ch; - - enum { supportUnicode = 0 }; - - template - static void Encode(OutputStream& os, unsigned codepoint) { - RAPIDJSON_ASSERT(codepoint <= 0x7F); - os.Put(static_cast(codepoint & 0xFF)); - } - - template - static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { - RAPIDJSON_ASSERT(codepoint <= 0x7F); - PutUnsafe(os, static_cast(codepoint & 0xFF)); - } - - template - static bool Decode(InputStream& is, unsigned* codepoint) { - uint8_t c = static_cast(is.Take()); - *codepoint = c; - return c <= 0X7F; - } - - template - static bool Validate(InputStream& is, OutputStream& os) { - uint8_t c = static_cast(is.Take()); - os.Put(static_cast(c)); - return c <= 0x7F; - } - - template - static CharType TakeBOM(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - uint8_t c = static_cast(Take(is)); - return static_cast(c); - } - - template - static Ch Take(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - return static_cast(is.Take()); - } - - template - static void PutBOM(OutputByteStream& os) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - (void)os; - } - - template - static void Put(OutputByteStream& os, Ch c) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast(c)); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// AutoUTF - -//! Runtime-specified UTF encoding type of a stream. -enum UTFType { - kUTF8 = 0, //!< UTF-8. - kUTF16LE = 1, //!< UTF-16 little endian. - kUTF16BE = 2, //!< UTF-16 big endian. - kUTF32LE = 3, //!< UTF-32 little endian. - kUTF32BE = 4 //!< UTF-32 big endian. -}; - -//! Dynamically select encoding according to stream's runtime-specified UTF encoding type. -/*! \note This class can be used with AutoUTFInputtStream and AutoUTFOutputStream, which provides GetType(). -*/ -template -struct AutoUTF { - typedef CharType Ch; - - enum { supportUnicode = 1 }; - -#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8::x, UTF16LE::x, UTF16BE::x, UTF32LE::x, UTF32BE::x - - template - static RAPIDJSON_FORCEINLINE void Encode(OutputStream& os, unsigned codepoint) { - typedef void (*EncodeFunc)(OutputStream&, unsigned); - static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) }; - (*f[os.GetType()])(os, codepoint); - } - - template - static RAPIDJSON_FORCEINLINE void EncodeUnsafe(OutputStream& os, unsigned codepoint) { - typedef void (*EncodeFunc)(OutputStream&, unsigned); - static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) }; - (*f[os.GetType()])(os, codepoint); - } - - template - static RAPIDJSON_FORCEINLINE bool Decode(InputStream& is, unsigned* codepoint) { - typedef bool (*DecodeFunc)(InputStream&, unsigned*); - static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) }; - return (*f[is.GetType()])(is, codepoint); - } - - template - static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) { - typedef bool (*ValidateFunc)(InputStream&, OutputStream&); - static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) }; - return (*f[is.GetType()])(is, os); - } - -#undef RAPIDJSON_ENCODINGS_FUNC -}; - -/////////////////////////////////////////////////////////////////////////////// -// Transcoder - -//! Encoding conversion. -template -struct Transcoder { - //! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream. - template - static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) { - unsigned codepoint; - if (!SourceEncoding::Decode(is, &codepoint)) - return false; - TargetEncoding::Encode(os, codepoint); - return true; - } - - template - static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) { - unsigned codepoint; - if (!SourceEncoding::Decode(is, &codepoint)) - return false; - TargetEncoding::EncodeUnsafe(os, codepoint); - return true; - } - - //! Validate one Unicode codepoint from an encoded stream. - template - static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) { - return Transcode(is, os); // Since source/target encoding is different, must transcode. - } -}; - -// Forward declaration. -template -inline void PutUnsafe(Stream& stream, typename Stream::Ch c); - -//! Specialization of Transcoder with same source and target encoding. -template -struct Transcoder { - template - static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) { - os.Put(is.Take()); // Just copy one code unit. This semantic is different from primary template class. - return true; - } - - template - static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) { - PutUnsafe(os, is.Take()); // Just copy one code unit. This semantic is different from primary template class. - return true; - } - - template - static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) { - return Encoding::Validate(is, os); // source/target encoding are the same - } -}; - -RAPIDJSON_NAMESPACE_END - -#if defined(__GNUC__) || (defined(_MSC_VER) && !defined(__clang__)) -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/error/en.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/error/en.h deleted file mode 100644 index 2db838bf..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/error/en.h +++ /dev/null @@ -1,74 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_ERROR_EN_H_ -#define RAPIDJSON_ERROR_EN_H_ - -#include "error.h" - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(switch-enum) -RAPIDJSON_DIAG_OFF(covered-switch-default) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! Maps error code of parsing into error message. -/*! - \ingroup RAPIDJSON_ERRORS - \param parseErrorCode Error code obtained in parsing. - \return the error message. - \note User can make a copy of this function for localization. - Using switch-case is safer for future modification of error codes. -*/ -inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) { - switch (parseErrorCode) { - case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); - - case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty."); - case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values."); - - case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value."); - - case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member."); - case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member."); - case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member."); - - case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element."); - - case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string."); - case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid."); - case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string."); - case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string."); - case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string."); - - case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double."); - case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number."); - case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number."); - - case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error."); - case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error."); - - default: return RAPIDJSON_ERROR_STRING("Unknown error."); - } -} - -RAPIDJSON_NAMESPACE_END - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_ERROR_EN_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/error/error.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/error/error.h deleted file mode 100644 index 9311d2f0..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/error/error.h +++ /dev/null @@ -1,161 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_ERROR_ERROR_H_ -#define RAPIDJSON_ERROR_ERROR_H_ - -#include "../rapidjson.h" - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(padded) -#endif - -/*! \file error.h */ - -/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */ - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_ERROR_CHARTYPE - -//! Character type of error messages. -/*! \ingroup RAPIDJSON_ERRORS - The default character type is \c char. - On Windows, user can define this macro as \c TCHAR for supporting both - unicode/non-unicode settings. -*/ -#ifndef RAPIDJSON_ERROR_CHARTYPE -#define RAPIDJSON_ERROR_CHARTYPE char -#endif - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_ERROR_STRING - -//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[]. -/*! \ingroup RAPIDJSON_ERRORS - By default this conversion macro does nothing. - On Windows, user can define this macro as \c _T(x) for supporting both - unicode/non-unicode settings. -*/ -#ifndef RAPIDJSON_ERROR_STRING -#define RAPIDJSON_ERROR_STRING(x) x -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -/////////////////////////////////////////////////////////////////////////////// -// ParseErrorCode - -//! Error code of parsing. -/*! \ingroup RAPIDJSON_ERRORS - \see GenericReader::Parse, GenericReader::GetParseErrorCode -*/ -enum ParseErrorCode { - kParseErrorNone = 0, //!< No error. - - kParseErrorDocumentEmpty, //!< The document is empty. - kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values. - - kParseErrorValueInvalid, //!< Invalid value. - - kParseErrorObjectMissName, //!< Missing a name for object member. - kParseErrorObjectMissColon, //!< Missing a colon after a name of object member. - kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member. - - kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element. - - kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string. - kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid. - kParseErrorStringEscapeInvalid, //!< Invalid escape character in string. - kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string. - kParseErrorStringInvalidEncoding, //!< Invalid encoding in string. - - kParseErrorNumberTooBig, //!< Number too big to be stored in double. - kParseErrorNumberMissFraction, //!< Miss fraction part in number. - kParseErrorNumberMissExponent, //!< Miss exponent in number. - - kParseErrorTermination, //!< Parsing was terminated. - kParseErrorUnspecificSyntaxError //!< Unspecific syntax error. -}; - -//! Result of parsing (wraps ParseErrorCode) -/*! - \ingroup RAPIDJSON_ERRORS - \code - Document doc; - ParseResult ok = doc.Parse("[42]"); - if (!ok) { - fprintf(stderr, "JSON parse error: %s (%u)", - GetParseError_En(ok.Code()), ok.Offset()); - exit(EXIT_FAILURE); - } - \endcode - \see GenericReader::Parse, GenericDocument::Parse -*/ -struct ParseResult { - //!! Unspecified boolean type - typedef bool (ParseResult::*BooleanType)() const; -public: - //! Default constructor, no error. - ParseResult() : code_(kParseErrorNone), offset_(0) {} - //! Constructor to set an error. - ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {} - - //! Get the error code. - ParseErrorCode Code() const { return code_; } - //! Get the error offset, if \ref IsError(), 0 otherwise. - size_t Offset() const { return offset_; } - - //! Explicit conversion to \c bool, returns \c true, iff !\ref IsError(). - operator BooleanType() const { return !IsError() ? &ParseResult::IsError : NULL; } - //! Whether the result is an error. - bool IsError() const { return code_ != kParseErrorNone; } - - bool operator==(const ParseResult& that) const { return code_ == that.code_; } - bool operator==(ParseErrorCode code) const { return code_ == code; } - friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; } - - bool operator!=(const ParseResult& that) const { return !(*this == that); } - bool operator!=(ParseErrorCode code) const { return !(*this == code); } - friend bool operator!=(ParseErrorCode code, const ParseResult & err) { return err != code; } - - //! Reset error code. - void Clear() { Set(kParseErrorNone); } - //! Update error code and offset. - void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; } - -private: - ParseErrorCode code_; - size_t offset_; -}; - -//! Function pointer type of GetParseError(). -/*! \ingroup RAPIDJSON_ERRORS - - This is the prototype for \c GetParseError_X(), where \c X is a locale. - User can dynamically change locale in runtime, e.g.: -\code - GetParseErrorFunc GetParseError = GetParseError_En; // or whatever - const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode()); -\endcode -*/ -typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode); - -RAPIDJSON_NAMESPACE_END - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_ERROR_ERROR_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/filereadstream.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/filereadstream.h deleted file mode 100644 index 6b343707..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/filereadstream.h +++ /dev/null @@ -1,99 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_FILEREADSTREAM_H_ -#define RAPIDJSON_FILEREADSTREAM_H_ - -#include "stream.h" -#include - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(padded) -RAPIDJSON_DIAG_OFF(unreachable-code) -RAPIDJSON_DIAG_OFF(missing-noreturn) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! File byte stream for input using fread(). -/*! - \note implements Stream concept -*/ -class FileReadStream { -public: - typedef char Ch; //!< Character type (byte). - - //! Constructor. - /*! - \param fp File pointer opened for read. - \param buffer user-supplied buffer. - \param bufferSize size of buffer in bytes. Must >=4 bytes. - */ - FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { - RAPIDJSON_ASSERT(fp_ != 0); - RAPIDJSON_ASSERT(bufferSize >= 4); - Read(); - } - - Ch Peek() const { return *current_; } - Ch Take() { Ch c = *current_; Read(); return c; } - size_t Tell() const { return count_ + static_cast(current_ - buffer_); } - - // Not implemented - void Put(Ch) { RAPIDJSON_ASSERT(false); } - void Flush() { RAPIDJSON_ASSERT(false); } - Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } - - // For encoding detection only. - const Ch* Peek4() const { - return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0; - } - -private: - void Read() { - if (current_ < bufferLast_) - ++current_; - else if (!eof_) { - count_ += readCount_; - readCount_ = std::fread(buffer_, 1, bufferSize_, fp_); - bufferLast_ = buffer_ + readCount_ - 1; - current_ = buffer_; - - if (readCount_ < bufferSize_) { - buffer_[readCount_] = '\0'; - ++bufferLast_; - eof_ = true; - } - } - } - - std::FILE* fp_; - Ch *buffer_; - size_t bufferSize_; - Ch *bufferLast_; - Ch *current_; - size_t readCount_; - size_t count_; //!< Number of characters read - bool eof_; -}; - -RAPIDJSON_NAMESPACE_END - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/filewritestream.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/filewritestream.h deleted file mode 100644 index 8b48fee1..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/filewritestream.h +++ /dev/null @@ -1,104 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_FILEWRITESTREAM_H_ -#define RAPIDJSON_FILEWRITESTREAM_H_ - -#include "stream.h" -#include - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(unreachable-code) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! Wrapper of C file stream for output using fwrite(). -/*! - \note implements Stream concept -*/ -class FileWriteStream { -public: - typedef char Ch; //!< Character type. Only support char. - - FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { - RAPIDJSON_ASSERT(fp_ != 0); - } - - void Put(char c) { - if (current_ >= bufferEnd_) - Flush(); - - *current_++ = c; - } - - void PutN(char c, size_t n) { - size_t avail = static_cast(bufferEnd_ - current_); - while (n > avail) { - std::memset(current_, c, avail); - current_ += avail; - Flush(); - n -= avail; - avail = static_cast(bufferEnd_ - current_); - } - - if (n > 0) { - std::memset(current_, c, n); - current_ += n; - } - } - - void Flush() { - if (current_ != buffer_) { - size_t result = std::fwrite(buffer_, 1, static_cast(current_ - buffer_), fp_); - if (result < static_cast(current_ - buffer_)) { - // failure deliberately ignored at this time - // added to avoid warn_unused_result build errors - } - current_ = buffer_; - } - } - - // Not implemented - char Peek() const { RAPIDJSON_ASSERT(false); return 0; } - char Take() { RAPIDJSON_ASSERT(false); return 0; } - size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } - char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } - -private: - // Prohibit copy constructor & assignment operator. - FileWriteStream(const FileWriteStream&); - FileWriteStream& operator=(const FileWriteStream&); - - std::FILE* fp_; - char *buffer_; - char *bufferEnd_; - char *current_; -}; - -//! Implement specialized version of PutN() with memset() for better performance. -template<> -inline void PutN(FileWriteStream& stream, char c, size_t n) { - stream.PutN(c, n); -} - -RAPIDJSON_NAMESPACE_END - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/fwd.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/fwd.h deleted file mode 100644 index b74a2b81..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/fwd.h +++ /dev/null @@ -1,151 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_FWD_H_ -#define RAPIDJSON_FWD_H_ - -#include "rapidjson.h" - -RAPIDJSON_NAMESPACE_BEGIN - -// encodings.h - -template struct UTF8; -template struct UTF16; -template struct UTF16BE; -template struct UTF16LE; -template struct UTF32; -template struct UTF32BE; -template struct UTF32LE; -template struct ASCII; -template struct AutoUTF; - -template -struct Transcoder; - -// allocators.h - -class CrtAllocator; - -template -class MemoryPoolAllocator; - -// stream.h - -template -struct GenericStringStream; - -typedef GenericStringStream > StringStream; - -template -struct GenericInsituStringStream; - -typedef GenericInsituStringStream > InsituStringStream; - -// stringbuffer.h - -template -class GenericStringBuffer; - -typedef GenericStringBuffer, CrtAllocator> StringBuffer; - -// filereadstream.h - -class FileReadStream; - -// filewritestream.h - -class FileWriteStream; - -// memorybuffer.h - -template -struct GenericMemoryBuffer; - -typedef GenericMemoryBuffer MemoryBuffer; - -// memorystream.h - -struct MemoryStream; - -// reader.h - -template -struct BaseReaderHandler; - -template -class GenericReader; - -typedef GenericReader, UTF8, CrtAllocator> Reader; - -// writer.h - -template -class Writer; - -// prettywriter.h - -template -class PrettyWriter; - -// document.h - -template -class GenericMember; - -template -class GenericMemberIterator; - -template -struct GenericStringRef; - -template -class GenericValue; - -typedef GenericValue, MemoryPoolAllocator > Value; - -template -class GenericDocument; - -typedef GenericDocument, MemoryPoolAllocator, CrtAllocator> Document; - -// pointer.h - -template -class GenericPointer; - -typedef GenericPointer Pointer; - -// schema.h - -template -class IGenericRemoteSchemaDocumentProvider; - -template -class GenericSchemaDocument; - -typedef GenericSchemaDocument SchemaDocument; -typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProvider; - -template < - typename SchemaDocumentType, - typename OutputHandler, - typename StateAllocator> -class GenericSchemaValidator; - -typedef GenericSchemaValidator, void>, CrtAllocator> SchemaValidator; - -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_RAPIDJSONFWD_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/biginteger.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/biginteger.h deleted file mode 100644 index 8eb87c7c..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/biginteger.h +++ /dev/null @@ -1,290 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_BIGINTEGER_H_ -#define RAPIDJSON_BIGINTEGER_H_ - -#include "../rapidjson.h" - -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && defined(_M_AMD64) -#include // for _umul128 -#pragma intrinsic(_umul128) -#endif - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -class BigInteger { -public: - typedef uint64_t Type; - - BigInteger(const BigInteger& rhs) : count_(rhs.count_) { - std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type)); - } - - explicit BigInteger(uint64_t u) : count_(1) { - digits_[0] = u; - } - - BigInteger(const char* decimals, size_t length) : count_(1) { - RAPIDJSON_ASSERT(length > 0); - digits_[0] = 0; - size_t i = 0; - const size_t kMaxDigitPerIteration = 19; // 2^64 = 18446744073709551616 > 10^19 - while (length >= kMaxDigitPerIteration) { - AppendDecimal64(decimals + i, decimals + i + kMaxDigitPerIteration); - length -= kMaxDigitPerIteration; - i += kMaxDigitPerIteration; - } - - if (length > 0) - AppendDecimal64(decimals + i, decimals + i + length); - } - - BigInteger& operator=(const BigInteger &rhs) - { - if (this != &rhs) { - count_ = rhs.count_; - std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type)); - } - return *this; - } - - BigInteger& operator=(uint64_t u) { - digits_[0] = u; - count_ = 1; - return *this; - } - - BigInteger& operator+=(uint64_t u) { - Type backup = digits_[0]; - digits_[0] += u; - for (size_t i = 0; i < count_ - 1; i++) { - if (digits_[i] >= backup) - return *this; // no carry - backup = digits_[i + 1]; - digits_[i + 1] += 1; - } - - // Last carry - if (digits_[count_ - 1] < backup) - PushBack(1); - - return *this; - } - - BigInteger& operator*=(uint64_t u) { - if (u == 0) return *this = 0; - if (u == 1) return *this; - if (*this == 1) return *this = u; - - uint64_t k = 0; - for (size_t i = 0; i < count_; i++) { - uint64_t hi; - digits_[i] = MulAdd64(digits_[i], u, k, &hi); - k = hi; - } - - if (k > 0) - PushBack(k); - - return *this; - } - - BigInteger& operator*=(uint32_t u) { - if (u == 0) return *this = 0; - if (u == 1) return *this; - if (*this == 1) return *this = u; - - uint64_t k = 0; - for (size_t i = 0; i < count_; i++) { - const uint64_t c = digits_[i] >> 32; - const uint64_t d = digits_[i] & 0xFFFFFFFF; - const uint64_t uc = u * c; - const uint64_t ud = u * d; - const uint64_t p0 = ud + k; - const uint64_t p1 = uc + (p0 >> 32); - digits_[i] = (p0 & 0xFFFFFFFF) | (p1 << 32); - k = p1 >> 32; - } - - if (k > 0) - PushBack(k); - - return *this; - } - - BigInteger& operator<<=(size_t shift) { - if (IsZero() || shift == 0) return *this; - - size_t offset = shift / kTypeBit; - size_t interShift = shift % kTypeBit; - RAPIDJSON_ASSERT(count_ + offset <= kCapacity); - - if (interShift == 0) { - std::memmove(digits_ + offset, digits_, count_ * sizeof(Type)); - count_ += offset; - } - else { - digits_[count_] = 0; - for (size_t i = count_; i > 0; i--) - digits_[i + offset] = (digits_[i] << interShift) | (digits_[i - 1] >> (kTypeBit - interShift)); - digits_[offset] = digits_[0] << interShift; - count_ += offset; - if (digits_[count_]) - count_++; - } - - std::memset(digits_, 0, offset * sizeof(Type)); - - return *this; - } - - bool operator==(const BigInteger& rhs) const { - return count_ == rhs.count_ && std::memcmp(digits_, rhs.digits_, count_ * sizeof(Type)) == 0; - } - - bool operator==(const Type rhs) const { - return count_ == 1 && digits_[0] == rhs; - } - - BigInteger& MultiplyPow5(unsigned exp) { - static const uint32_t kPow5[12] = { - 5, - 5 * 5, - 5 * 5 * 5, - 5 * 5 * 5 * 5, - 5 * 5 * 5 * 5 * 5, - 5 * 5 * 5 * 5 * 5 * 5, - 5 * 5 * 5 * 5 * 5 * 5 * 5, - 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, - 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, - 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, - 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, - 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 - }; - if (exp == 0) return *this; - for (; exp >= 27; exp -= 27) *this *= RAPIDJSON_UINT64_C2(0X6765C793, 0XFA10079D); // 5^27 - for (; exp >= 13; exp -= 13) *this *= static_cast(1220703125u); // 5^13 - if (exp > 0) *this *= kPow5[exp - 1]; - return *this; - } - - // Compute absolute difference of this and rhs. - // Assume this != rhs - bool Difference(const BigInteger& rhs, BigInteger* out) const { - int cmp = Compare(rhs); - RAPIDJSON_ASSERT(cmp != 0); - const BigInteger *a, *b; // Makes a > b - bool ret; - if (cmp < 0) { a = &rhs; b = this; ret = true; } - else { a = this; b = &rhs; ret = false; } - - Type borrow = 0; - for (size_t i = 0; i < a->count_; i++) { - Type d = a->digits_[i] - borrow; - if (i < b->count_) - d -= b->digits_[i]; - borrow = (d > a->digits_[i]) ? 1 : 0; - out->digits_[i] = d; - if (d != 0) - out->count_ = i + 1; - } - - return ret; - } - - int Compare(const BigInteger& rhs) const { - if (count_ != rhs.count_) - return count_ < rhs.count_ ? -1 : 1; - - for (size_t i = count_; i-- > 0;) - if (digits_[i] != rhs.digits_[i]) - return digits_[i] < rhs.digits_[i] ? -1 : 1; - - return 0; - } - - size_t GetCount() const { return count_; } - Type GetDigit(size_t index) const { RAPIDJSON_ASSERT(index < count_); return digits_[index]; } - bool IsZero() const { return count_ == 1 && digits_[0] == 0; } - -private: - void AppendDecimal64(const char* begin, const char* end) { - uint64_t u = ParseUint64(begin, end); - if (IsZero()) - *this = u; - else { - unsigned exp = static_cast(end - begin); - (MultiplyPow5(exp) <<= exp) += u; // *this = *this * 10^exp + u - } - } - - void PushBack(Type digit) { - RAPIDJSON_ASSERT(count_ < kCapacity); - digits_[count_++] = digit; - } - - static uint64_t ParseUint64(const char* begin, const char* end) { - uint64_t r = 0; - for (const char* p = begin; p != end; ++p) { - RAPIDJSON_ASSERT(*p >= '0' && *p <= '9'); - r = r * 10u + static_cast(*p - '0'); - } - return r; - } - - // Assume a * b + k < 2^128 - static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* outHigh) { -#if defined(_MSC_VER) && defined(_M_AMD64) - uint64_t low = _umul128(a, b, outHigh) + k; - if (low < k) - (*outHigh)++; - return low; -#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) - __extension__ typedef unsigned __int128 uint128; - uint128 p = static_cast(a) * static_cast(b); - p += k; - *outHigh = static_cast(p >> 64); - return static_cast(p); -#else - const uint64_t a0 = a & 0xFFFFFFFF, a1 = a >> 32, b0 = b & 0xFFFFFFFF, b1 = b >> 32; - uint64_t x0 = a0 * b0, x1 = a0 * b1, x2 = a1 * b0, x3 = a1 * b1; - x1 += (x0 >> 32); // can't give carry - x1 += x2; - if (x1 < x2) - x3 += (static_cast(1) << 32); - uint64_t lo = (x1 << 32) + (x0 & 0xFFFFFFFF); - uint64_t hi = x3 + (x1 >> 32); - - lo += k; - if (lo < k) - hi++; - *outHigh = hi; - return lo; -#endif - } - - static const size_t kBitCount = 3328; // 64bit * 54 > 10^1000 - static const size_t kCapacity = kBitCount / sizeof(Type); - static const size_t kTypeBit = sizeof(Type) * 8; - - Type digits_[kCapacity]; - size_t count_; -}; - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_BIGINTEGER_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/clzll.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/clzll.h deleted file mode 100644 index 47bb7ab1..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/clzll.h +++ /dev/null @@ -1,71 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_CLZLL_H_ -#define RAPIDJSON_CLZLL_H_ - -#include "../rapidjson.h" - -#if defined(_MSC_VER) && !defined(UNDER_CE) -#include -#if defined(_WIN64) -#pragma intrinsic(_BitScanReverse64) -#else -#pragma intrinsic(_BitScanReverse) -#endif -#endif - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -inline uint32_t clzll(uint64_t x) { - // Passing 0 to __builtin_clzll is UB in GCC and results in an - // infinite loop in the software implementation. - RAPIDJSON_ASSERT(x != 0); - -#if defined(_MSC_VER) && !defined(UNDER_CE) - unsigned long r = 0; -#if defined(_WIN64) - _BitScanReverse64(&r, x); -#else - // Scan the high 32 bits. - if (_BitScanReverse(&r, static_cast(x >> 32))) - return 63 - (r + 32); - - // Scan the low 32 bits. - _BitScanReverse(&r, static_cast(x & 0xFFFFFFFF)); -#endif // _WIN64 - - return 63 - r; -#elif (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll) - // __builtin_clzll wrapper - return static_cast(__builtin_clzll(x)); -#else - // naive version - uint32_t r = 0; - while (!(x & (static_cast(1) << 63))) { - x <<= 1; - ++r; - } - - return r; -#endif // _MSC_VER -} - -#define RAPIDJSON_CLZLL RAPIDJSON_NAMESPACE::internal::clzll - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_CLZLL_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/diyfp.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/diyfp.h deleted file mode 100644 index 8f7d853a..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/diyfp.h +++ /dev/null @@ -1,257 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -// This is a C++ header-only implementation of Grisu2 algorithm from the publication: -// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with -// integers." ACM Sigplan Notices 45.6 (2010): 233-243. - -#ifndef RAPIDJSON_DIYFP_H_ -#define RAPIDJSON_DIYFP_H_ - -#include "../rapidjson.h" -#include "clzll.h" -#include - -#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER) -#include -#pragma intrinsic(_umul128) -#endif - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -#ifdef __GNUC__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(effc++) -#endif - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(padded) -#endif - -struct DiyFp { - DiyFp() : f(), e() {} - - DiyFp(uint64_t fp, int exp) : f(fp), e(exp) {} - - explicit DiyFp(double d) { - union { - double d; - uint64_t u64; - } u = { d }; - - int biased_e = static_cast((u.u64 & kDpExponentMask) >> kDpSignificandSize); - uint64_t significand = (u.u64 & kDpSignificandMask); - if (biased_e != 0) { - f = significand + kDpHiddenBit; - e = biased_e - kDpExponentBias; - } - else { - f = significand; - e = kDpMinExponent + 1; - } - } - - DiyFp operator-(const DiyFp& rhs) const { - return DiyFp(f - rhs.f, e); - } - - DiyFp operator*(const DiyFp& rhs) const { -#if defined(_MSC_VER) && defined(_M_AMD64) - uint64_t h; - uint64_t l = _umul128(f, rhs.f, &h); - if (l & (uint64_t(1) << 63)) // rounding - h++; - return DiyFp(h, e + rhs.e + 64); -#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) - __extension__ typedef unsigned __int128 uint128; - uint128 p = static_cast(f) * static_cast(rhs.f); - uint64_t h = static_cast(p >> 64); - uint64_t l = static_cast(p); - if (l & (uint64_t(1) << 63)) // rounding - h++; - return DiyFp(h, e + rhs.e + 64); -#else - const uint64_t M32 = 0xFFFFFFFF; - const uint64_t a = f >> 32; - const uint64_t b = f & M32; - const uint64_t c = rhs.f >> 32; - const uint64_t d = rhs.f & M32; - const uint64_t ac = a * c; - const uint64_t bc = b * c; - const uint64_t ad = a * d; - const uint64_t bd = b * d; - uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32); - tmp += 1U << 31; /// mult_round - return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64); -#endif - } - - DiyFp Normalize() const { - int s = static_cast(clzll(f)); - return DiyFp(f << s, e - s); - } - - DiyFp NormalizeBoundary() const { - DiyFp res = *this; - while (!(res.f & (kDpHiddenBit << 1))) { - res.f <<= 1; - res.e--; - } - res.f <<= (kDiySignificandSize - kDpSignificandSize - 2); - res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2); - return res; - } - - void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const { - DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary(); - DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1); - mi.f <<= mi.e - pl.e; - mi.e = pl.e; - *plus = pl; - *minus = mi; - } - - double ToDouble() const { - union { - double d; - uint64_t u64; - }u; - RAPIDJSON_ASSERT(f <= kDpHiddenBit + kDpSignificandMask); - if (e < kDpDenormalExponent) { - // Underflow. - return 0.0; - } - if (e >= kDpMaxExponent) { - // Overflow. - return std::numeric_limits::infinity(); - } - const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 : - static_cast(e + kDpExponentBias); - u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize); - return u.d; - } - - static const int kDiySignificandSize = 64; - static const int kDpSignificandSize = 52; - static const int kDpExponentBias = 0x3FF + kDpSignificandSize; - static const int kDpMaxExponent = 0x7FF - kDpExponentBias; - static const int kDpMinExponent = -kDpExponentBias; - static const int kDpDenormalExponent = -kDpExponentBias + 1; - static const uint64_t kDpExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); - static const uint64_t kDpSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); - static const uint64_t kDpHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); - - uint64_t f; - int e; -}; - -inline DiyFp GetCachedPowerByIndex(size_t index) { - // 10^-348, 10^-340, ..., 10^340 - static const uint64_t kCachedPowers_F[] = { - RAPIDJSON_UINT64_C2(0xfa8fd5a0, 0x081c0288), RAPIDJSON_UINT64_C2(0xbaaee17f, 0xa23ebf76), - RAPIDJSON_UINT64_C2(0x8b16fb20, 0x3055ac76), RAPIDJSON_UINT64_C2(0xcf42894a, 0x5dce35ea), - RAPIDJSON_UINT64_C2(0x9a6bb0aa, 0x55653b2d), RAPIDJSON_UINT64_C2(0xe61acf03, 0x3d1a45df), - RAPIDJSON_UINT64_C2(0xab70fe17, 0xc79ac6ca), RAPIDJSON_UINT64_C2(0xff77b1fc, 0xbebcdc4f), - RAPIDJSON_UINT64_C2(0xbe5691ef, 0x416bd60c), RAPIDJSON_UINT64_C2(0x8dd01fad, 0x907ffc3c), - RAPIDJSON_UINT64_C2(0xd3515c28, 0x31559a83), RAPIDJSON_UINT64_C2(0x9d71ac8f, 0xada6c9b5), - RAPIDJSON_UINT64_C2(0xea9c2277, 0x23ee8bcb), RAPIDJSON_UINT64_C2(0xaecc4991, 0x4078536d), - RAPIDJSON_UINT64_C2(0x823c1279, 0x5db6ce57), RAPIDJSON_UINT64_C2(0xc2109436, 0x4dfb5637), - RAPIDJSON_UINT64_C2(0x9096ea6f, 0x3848984f), RAPIDJSON_UINT64_C2(0xd77485cb, 0x25823ac7), - RAPIDJSON_UINT64_C2(0xa086cfcd, 0x97bf97f4), RAPIDJSON_UINT64_C2(0xef340a98, 0x172aace5), - RAPIDJSON_UINT64_C2(0xb23867fb, 0x2a35b28e), RAPIDJSON_UINT64_C2(0x84c8d4df, 0xd2c63f3b), - RAPIDJSON_UINT64_C2(0xc5dd4427, 0x1ad3cdba), RAPIDJSON_UINT64_C2(0x936b9fce, 0xbb25c996), - RAPIDJSON_UINT64_C2(0xdbac6c24, 0x7d62a584), RAPIDJSON_UINT64_C2(0xa3ab6658, 0x0d5fdaf6), - RAPIDJSON_UINT64_C2(0xf3e2f893, 0xdec3f126), RAPIDJSON_UINT64_C2(0xb5b5ada8, 0xaaff80b8), - RAPIDJSON_UINT64_C2(0x87625f05, 0x6c7c4a8b), RAPIDJSON_UINT64_C2(0xc9bcff60, 0x34c13053), - RAPIDJSON_UINT64_C2(0x964e858c, 0x91ba2655), RAPIDJSON_UINT64_C2(0xdff97724, 0x70297ebd), - RAPIDJSON_UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), RAPIDJSON_UINT64_C2(0xf8a95fcf, 0x88747d94), - RAPIDJSON_UINT64_C2(0xb9447093, 0x8fa89bcf), RAPIDJSON_UINT64_C2(0x8a08f0f8, 0xbf0f156b), - RAPIDJSON_UINT64_C2(0xcdb02555, 0x653131b6), RAPIDJSON_UINT64_C2(0x993fe2c6, 0xd07b7fac), - RAPIDJSON_UINT64_C2(0xe45c10c4, 0x2a2b3b06), RAPIDJSON_UINT64_C2(0xaa242499, 0x697392d3), - RAPIDJSON_UINT64_C2(0xfd87b5f2, 0x8300ca0e), RAPIDJSON_UINT64_C2(0xbce50864, 0x92111aeb), - RAPIDJSON_UINT64_C2(0x8cbccc09, 0x6f5088cc), RAPIDJSON_UINT64_C2(0xd1b71758, 0xe219652c), - RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), RAPIDJSON_UINT64_C2(0xe8d4a510, 0x00000000), - RAPIDJSON_UINT64_C2(0xad78ebc5, 0xac620000), RAPIDJSON_UINT64_C2(0x813f3978, 0xf8940984), - RAPIDJSON_UINT64_C2(0xc097ce7b, 0xc90715b3), RAPIDJSON_UINT64_C2(0x8f7e32ce, 0x7bea5c70), - RAPIDJSON_UINT64_C2(0xd5d238a4, 0xabe98068), RAPIDJSON_UINT64_C2(0x9f4f2726, 0x179a2245), - RAPIDJSON_UINT64_C2(0xed63a231, 0xd4c4fb27), RAPIDJSON_UINT64_C2(0xb0de6538, 0x8cc8ada8), - RAPIDJSON_UINT64_C2(0x83c7088e, 0x1aab65db), RAPIDJSON_UINT64_C2(0xc45d1df9, 0x42711d9a), - RAPIDJSON_UINT64_C2(0x924d692c, 0xa61be758), RAPIDJSON_UINT64_C2(0xda01ee64, 0x1a708dea), - RAPIDJSON_UINT64_C2(0xa26da399, 0x9aef774a), RAPIDJSON_UINT64_C2(0xf209787b, 0xb47d6b85), - RAPIDJSON_UINT64_C2(0xb454e4a1, 0x79dd1877), RAPIDJSON_UINT64_C2(0x865b8692, 0x5b9bc5c2), - RAPIDJSON_UINT64_C2(0xc83553c5, 0xc8965d3d), RAPIDJSON_UINT64_C2(0x952ab45c, 0xfa97a0b3), - RAPIDJSON_UINT64_C2(0xde469fbd, 0x99a05fe3), RAPIDJSON_UINT64_C2(0xa59bc234, 0xdb398c25), - RAPIDJSON_UINT64_C2(0xf6c69a72, 0xa3989f5c), RAPIDJSON_UINT64_C2(0xb7dcbf53, 0x54e9bece), - RAPIDJSON_UINT64_C2(0x88fcf317, 0xf22241e2), RAPIDJSON_UINT64_C2(0xcc20ce9b, 0xd35c78a5), - RAPIDJSON_UINT64_C2(0x98165af3, 0x7b2153df), RAPIDJSON_UINT64_C2(0xe2a0b5dc, 0x971f303a), - RAPIDJSON_UINT64_C2(0xa8d9d153, 0x5ce3b396), RAPIDJSON_UINT64_C2(0xfb9b7cd9, 0xa4a7443c), - RAPIDJSON_UINT64_C2(0xbb764c4c, 0xa7a44410), RAPIDJSON_UINT64_C2(0x8bab8eef, 0xb6409c1a), - RAPIDJSON_UINT64_C2(0xd01fef10, 0xa657842c), RAPIDJSON_UINT64_C2(0x9b10a4e5, 0xe9913129), - RAPIDJSON_UINT64_C2(0xe7109bfb, 0xa19c0c9d), RAPIDJSON_UINT64_C2(0xac2820d9, 0x623bf429), - RAPIDJSON_UINT64_C2(0x80444b5e, 0x7aa7cf85), RAPIDJSON_UINT64_C2(0xbf21e440, 0x03acdd2d), - RAPIDJSON_UINT64_C2(0x8e679c2f, 0x5e44ff8f), RAPIDJSON_UINT64_C2(0xd433179d, 0x9c8cb841), - RAPIDJSON_UINT64_C2(0x9e19db92, 0xb4e31ba9), RAPIDJSON_UINT64_C2(0xeb96bf6e, 0xbadf77d9), - RAPIDJSON_UINT64_C2(0xaf87023b, 0x9bf0ee6b) - }; - static const int16_t kCachedPowers_E[] = { - -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, - -954, -927, -901, -874, -847, -821, -794, -768, -741, -715, - -688, -661, -635, -608, -582, -555, -529, -502, -475, -449, - -422, -396, -369, -343, -316, -289, -263, -236, -210, -183, - -157, -130, -103, -77, -50, -24, 3, 30, 56, 83, - 109, 136, 162, 189, 216, 242, 269, 295, 322, 348, - 375, 402, 428, 455, 481, 508, 534, 561, 588, 614, - 641, 667, 694, 720, 747, 774, 800, 827, 853, 880, - 907, 933, 960, 986, 1013, 1039, 1066 - }; - RAPIDJSON_ASSERT(index < 87); - return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]); -} - -inline DiyFp GetCachedPower(int e, int* K) { - - //int k = static_cast(ceil((-61 - e) * 0.30102999566398114)) + 374; - double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive - int k = static_cast(dk); - if (dk - k > 0.0) - k++; - - unsigned index = static_cast((k >> 3) + 1); - *K = -(-348 + static_cast(index << 3)); // decimal exponent no need lookup table - - return GetCachedPowerByIndex(index); -} - -inline DiyFp GetCachedPower10(int exp, int *outExp) { - RAPIDJSON_ASSERT(exp >= -348); - unsigned index = static_cast(exp + 348) / 8u; - *outExp = -348 + static_cast(index) * 8; - return GetCachedPowerByIndex(index); -} - -#ifdef __GNUC__ -RAPIDJSON_DIAG_POP -#endif - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -RAPIDJSON_DIAG_OFF(padded) -#endif - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_DIYFP_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/dtoa.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/dtoa.h deleted file mode 100644 index bf2e9b2e..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/dtoa.h +++ /dev/null @@ -1,245 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -// This is a C++ header-only implementation of Grisu2 algorithm from the publication: -// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with -// integers." ACM Sigplan Notices 45.6 (2010): 233-243. - -#ifndef RAPIDJSON_DTOA_ -#define RAPIDJSON_DTOA_ - -#include "itoa.h" // GetDigitsLut() -#include "diyfp.h" -#include "ieee754.h" - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -#ifdef __GNUC__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(effc++) -RAPIDJSON_DIAG_OFF(array-bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124 -#endif - -inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) { - while (rest < wp_w && delta - rest >= ten_kappa && - (rest + ten_kappa < wp_w || /// closer - wp_w - rest > rest + ten_kappa - wp_w)) { - buffer[len - 1]--; - rest += ten_kappa; - } -} - -inline int CountDecimalDigit32(uint32_t n) { - // Simple pure C++ implementation was faster than __builtin_clz version in this situation. - if (n < 10) return 1; - if (n < 100) return 2; - if (n < 1000) return 3; - if (n < 10000) return 4; - if (n < 100000) return 5; - if (n < 1000000) return 6; - if (n < 10000000) return 7; - if (n < 100000000) return 8; - // Will not reach 10 digits in DigitGen() - //if (n < 1000000000) return 9; - //return 10; - return 9; -} - -inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) { - static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; - const DiyFp one(uint64_t(1) << -Mp.e, Mp.e); - const DiyFp wp_w = Mp - W; - uint32_t p1 = static_cast(Mp.f >> -one.e); - uint64_t p2 = Mp.f & (one.f - 1); - int kappa = CountDecimalDigit32(p1); // kappa in [0, 9] - *len = 0; - - while (kappa > 0) { - uint32_t d = 0; - switch (kappa) { - case 9: d = p1 / 100000000; p1 %= 100000000; break; - case 8: d = p1 / 10000000; p1 %= 10000000; break; - case 7: d = p1 / 1000000; p1 %= 1000000; break; - case 6: d = p1 / 100000; p1 %= 100000; break; - case 5: d = p1 / 10000; p1 %= 10000; break; - case 4: d = p1 / 1000; p1 %= 1000; break; - case 3: d = p1 / 100; p1 %= 100; break; - case 2: d = p1 / 10; p1 %= 10; break; - case 1: d = p1; p1 = 0; break; - default:; - } - if (d || *len) - buffer[(*len)++] = static_cast('0' + static_cast(d)); - kappa--; - uint64_t tmp = (static_cast(p1) << -one.e) + p2; - if (tmp <= delta) { - *K += kappa; - GrisuRound(buffer, *len, delta, tmp, static_cast(kPow10[kappa]) << -one.e, wp_w.f); - return; - } - } - - // kappa = 0 - for (;;) { - p2 *= 10; - delta *= 10; - char d = static_cast(p2 >> -one.e); - if (d || *len) - buffer[(*len)++] = static_cast('0' + d); - p2 &= one.f - 1; - kappa--; - if (p2 < delta) { - *K += kappa; - int index = -kappa; - GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[index] : 0)); - return; - } - } -} - -inline void Grisu2(double value, char* buffer, int* length, int* K) { - const DiyFp v(value); - DiyFp w_m, w_p; - v.NormalizedBoundaries(&w_m, &w_p); - - const DiyFp c_mk = GetCachedPower(w_p.e, K); - const DiyFp W = v.Normalize() * c_mk; - DiyFp Wp = w_p * c_mk; - DiyFp Wm = w_m * c_mk; - Wm.f++; - Wp.f--; - DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K); -} - -inline char* WriteExponent(int K, char* buffer) { - if (K < 0) { - *buffer++ = '-'; - K = -K; - } - - if (K >= 100) { - *buffer++ = static_cast('0' + static_cast(K / 100)); - K %= 100; - const char* d = GetDigitsLut() + K * 2; - *buffer++ = d[0]; - *buffer++ = d[1]; - } - else if (K >= 10) { - const char* d = GetDigitsLut() + K * 2; - *buffer++ = d[0]; - *buffer++ = d[1]; - } - else - *buffer++ = static_cast('0' + static_cast(K)); - - return buffer; -} - -inline char* Prettify(char* buffer, int length, int k, int maxDecimalPlaces) { - const int kk = length + k; // 10^(kk-1) <= v < 10^kk - - if (0 <= k && kk <= 21) { - // 1234e7 -> 12340000000 - for (int i = length; i < kk; i++) - buffer[i] = '0'; - buffer[kk] = '.'; - buffer[kk + 1] = '0'; - return &buffer[kk + 2]; - } - else if (0 < kk && kk <= 21) { - // 1234e-2 -> 12.34 - std::memmove(&buffer[kk + 1], &buffer[kk], static_cast(length - kk)); - buffer[kk] = '.'; - if (0 > k + maxDecimalPlaces) { - // When maxDecimalPlaces = 2, 1.2345 -> 1.23, 1.102 -> 1.1 - // Remove extra trailing zeros (at least one) after truncation. - for (int i = kk + maxDecimalPlaces; i > kk + 1; i--) - if (buffer[i] != '0') - return &buffer[i + 1]; - return &buffer[kk + 2]; // Reserve one zero - } - else - return &buffer[length + 1]; - } - else if (-6 < kk && kk <= 0) { - // 1234e-6 -> 0.001234 - const int offset = 2 - kk; - std::memmove(&buffer[offset], &buffer[0], static_cast(length)); - buffer[0] = '0'; - buffer[1] = '.'; - for (int i = 2; i < offset; i++) - buffer[i] = '0'; - if (length - kk > maxDecimalPlaces) { - // When maxDecimalPlaces = 2, 0.123 -> 0.12, 0.102 -> 0.1 - // Remove extra trailing zeros (at least one) after truncation. - for (int i = maxDecimalPlaces + 1; i > 2; i--) - if (buffer[i] != '0') - return &buffer[i + 1]; - return &buffer[3]; // Reserve one zero - } - else - return &buffer[length + offset]; - } - else if (kk < -maxDecimalPlaces) { - // Truncate to zero - buffer[0] = '0'; - buffer[1] = '.'; - buffer[2] = '0'; - return &buffer[3]; - } - else if (length == 1) { - // 1e30 - buffer[1] = 'e'; - return WriteExponent(kk - 1, &buffer[2]); - } - else { - // 1234e30 -> 1.234e33 - std::memmove(&buffer[2], &buffer[1], static_cast(length - 1)); - buffer[1] = '.'; - buffer[length + 1] = 'e'; - return WriteExponent(kk - 1, &buffer[0 + length + 2]); - } -} - -inline char* dtoa(double value, char* buffer, int maxDecimalPlaces = 324) { - RAPIDJSON_ASSERT(maxDecimalPlaces >= 1); - Double d(value); - if (d.IsZero()) { - if (d.Sign()) - *buffer++ = '-'; // -0.0, Issue #289 - buffer[0] = '0'; - buffer[1] = '.'; - buffer[2] = '0'; - return &buffer[3]; - } - else { - if (value < 0) { - *buffer++ = '-'; - value = -value; - } - int length, K; - Grisu2(value, buffer, &length, &K); - return Prettify(buffer, length, K, maxDecimalPlaces); - } -} - -#ifdef __GNUC__ -RAPIDJSON_DIAG_POP -#endif - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_DTOA_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/ieee754.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/ieee754.h deleted file mode 100644 index c2684ba2..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/ieee754.h +++ /dev/null @@ -1,78 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_IEEE754_ -#define RAPIDJSON_IEEE754_ - -#include "../rapidjson.h" - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -class Double { -public: - Double() {} - Double(double d) : d_(d) {} - Double(uint64_t u) : u_(u) {} - - double Value() const { return d_; } - uint64_t Uint64Value() const { return u_; } - - double NextPositiveDouble() const { - RAPIDJSON_ASSERT(!Sign()); - return Double(u_ + 1).Value(); - } - - bool Sign() const { return (u_ & kSignMask) != 0; } - uint64_t Significand() const { return u_ & kSignificandMask; } - int Exponent() const { return static_cast(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); } - - bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; } - bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; } - bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; } - bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; } - bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; } - - uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); } - int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; } - uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; } - - static int EffectiveSignificandSize(int order) { - if (order >= -1021) - return 53; - else if (order <= -1074) - return 0; - else - return order + 1074; - } - -private: - static const int kSignificandSize = 52; - static const int kExponentBias = 0x3FF; - static const int kDenormalExponent = 1 - kExponentBias; - static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000); - static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); - static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); - static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); - - union { - double d_; - uint64_t u_; - }; -}; - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_IEEE754_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/itoa.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/itoa.h deleted file mode 100644 index 9b1c45cc..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/itoa.h +++ /dev/null @@ -1,308 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_ITOA_ -#define RAPIDJSON_ITOA_ - -#include "../rapidjson.h" - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -inline const char* GetDigitsLut() { - static const char cDigitsLut[200] = { - '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9', - '1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9', - '2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9', - '3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9', - '4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9', - '5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9', - '6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9', - '7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9', - '8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9', - '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9' - }; - return cDigitsLut; -} - -inline char* u32toa(uint32_t value, char* buffer) { - RAPIDJSON_ASSERT(buffer != 0); - - const char* cDigitsLut = GetDigitsLut(); - - if (value < 10000) { - const uint32_t d1 = (value / 100) << 1; - const uint32_t d2 = (value % 100) << 1; - - if (value >= 1000) - *buffer++ = cDigitsLut[d1]; - if (value >= 100) - *buffer++ = cDigitsLut[d1 + 1]; - if (value >= 10) - *buffer++ = cDigitsLut[d2]; - *buffer++ = cDigitsLut[d2 + 1]; - } - else if (value < 100000000) { - // value = bbbbcccc - const uint32_t b = value / 10000; - const uint32_t c = value % 10000; - - const uint32_t d1 = (b / 100) << 1; - const uint32_t d2 = (b % 100) << 1; - - const uint32_t d3 = (c / 100) << 1; - const uint32_t d4 = (c % 100) << 1; - - if (value >= 10000000) - *buffer++ = cDigitsLut[d1]; - if (value >= 1000000) - *buffer++ = cDigitsLut[d1 + 1]; - if (value >= 100000) - *buffer++ = cDigitsLut[d2]; - *buffer++ = cDigitsLut[d2 + 1]; - - *buffer++ = cDigitsLut[d3]; - *buffer++ = cDigitsLut[d3 + 1]; - *buffer++ = cDigitsLut[d4]; - *buffer++ = cDigitsLut[d4 + 1]; - } - else { - // value = aabbbbcccc in decimal - - const uint32_t a = value / 100000000; // 1 to 42 - value %= 100000000; - - if (a >= 10) { - const unsigned i = a << 1; - *buffer++ = cDigitsLut[i]; - *buffer++ = cDigitsLut[i + 1]; - } - else - *buffer++ = static_cast('0' + static_cast(a)); - - const uint32_t b = value / 10000; // 0 to 9999 - const uint32_t c = value % 10000; // 0 to 9999 - - const uint32_t d1 = (b / 100) << 1; - const uint32_t d2 = (b % 100) << 1; - - const uint32_t d3 = (c / 100) << 1; - const uint32_t d4 = (c % 100) << 1; - - *buffer++ = cDigitsLut[d1]; - *buffer++ = cDigitsLut[d1 + 1]; - *buffer++ = cDigitsLut[d2]; - *buffer++ = cDigitsLut[d2 + 1]; - *buffer++ = cDigitsLut[d3]; - *buffer++ = cDigitsLut[d3 + 1]; - *buffer++ = cDigitsLut[d4]; - *buffer++ = cDigitsLut[d4 + 1]; - } - return buffer; -} - -inline char* i32toa(int32_t value, char* buffer) { - RAPIDJSON_ASSERT(buffer != 0); - uint32_t u = static_cast(value); - if (value < 0) { - *buffer++ = '-'; - u = ~u + 1; - } - - return u32toa(u, buffer); -} - -inline char* u64toa(uint64_t value, char* buffer) { - RAPIDJSON_ASSERT(buffer != 0); - const char* cDigitsLut = GetDigitsLut(); - const uint64_t kTen8 = 100000000; - const uint64_t kTen9 = kTen8 * 10; - const uint64_t kTen10 = kTen8 * 100; - const uint64_t kTen11 = kTen8 * 1000; - const uint64_t kTen12 = kTen8 * 10000; - const uint64_t kTen13 = kTen8 * 100000; - const uint64_t kTen14 = kTen8 * 1000000; - const uint64_t kTen15 = kTen8 * 10000000; - const uint64_t kTen16 = kTen8 * kTen8; - - if (value < kTen8) { - uint32_t v = static_cast(value); - if (v < 10000) { - const uint32_t d1 = (v / 100) << 1; - const uint32_t d2 = (v % 100) << 1; - - if (v >= 1000) - *buffer++ = cDigitsLut[d1]; - if (v >= 100) - *buffer++ = cDigitsLut[d1 + 1]; - if (v >= 10) - *buffer++ = cDigitsLut[d2]; - *buffer++ = cDigitsLut[d2 + 1]; - } - else { - // value = bbbbcccc - const uint32_t b = v / 10000; - const uint32_t c = v % 10000; - - const uint32_t d1 = (b / 100) << 1; - const uint32_t d2 = (b % 100) << 1; - - const uint32_t d3 = (c / 100) << 1; - const uint32_t d4 = (c % 100) << 1; - - if (value >= 10000000) - *buffer++ = cDigitsLut[d1]; - if (value >= 1000000) - *buffer++ = cDigitsLut[d1 + 1]; - if (value >= 100000) - *buffer++ = cDigitsLut[d2]; - *buffer++ = cDigitsLut[d2 + 1]; - - *buffer++ = cDigitsLut[d3]; - *buffer++ = cDigitsLut[d3 + 1]; - *buffer++ = cDigitsLut[d4]; - *buffer++ = cDigitsLut[d4 + 1]; - } - } - else if (value < kTen16) { - const uint32_t v0 = static_cast(value / kTen8); - const uint32_t v1 = static_cast(value % kTen8); - - const uint32_t b0 = v0 / 10000; - const uint32_t c0 = v0 % 10000; - - const uint32_t d1 = (b0 / 100) << 1; - const uint32_t d2 = (b0 % 100) << 1; - - const uint32_t d3 = (c0 / 100) << 1; - const uint32_t d4 = (c0 % 100) << 1; - - const uint32_t b1 = v1 / 10000; - const uint32_t c1 = v1 % 10000; - - const uint32_t d5 = (b1 / 100) << 1; - const uint32_t d6 = (b1 % 100) << 1; - - const uint32_t d7 = (c1 / 100) << 1; - const uint32_t d8 = (c1 % 100) << 1; - - if (value >= kTen15) - *buffer++ = cDigitsLut[d1]; - if (value >= kTen14) - *buffer++ = cDigitsLut[d1 + 1]; - if (value >= kTen13) - *buffer++ = cDigitsLut[d2]; - if (value >= kTen12) - *buffer++ = cDigitsLut[d2 + 1]; - if (value >= kTen11) - *buffer++ = cDigitsLut[d3]; - if (value >= kTen10) - *buffer++ = cDigitsLut[d3 + 1]; - if (value >= kTen9) - *buffer++ = cDigitsLut[d4]; - - *buffer++ = cDigitsLut[d4 + 1]; - *buffer++ = cDigitsLut[d5]; - *buffer++ = cDigitsLut[d5 + 1]; - *buffer++ = cDigitsLut[d6]; - *buffer++ = cDigitsLut[d6 + 1]; - *buffer++ = cDigitsLut[d7]; - *buffer++ = cDigitsLut[d7 + 1]; - *buffer++ = cDigitsLut[d8]; - *buffer++ = cDigitsLut[d8 + 1]; - } - else { - const uint32_t a = static_cast(value / kTen16); // 1 to 1844 - value %= kTen16; - - if (a < 10) - *buffer++ = static_cast('0' + static_cast(a)); - else if (a < 100) { - const uint32_t i = a << 1; - *buffer++ = cDigitsLut[i]; - *buffer++ = cDigitsLut[i + 1]; - } - else if (a < 1000) { - *buffer++ = static_cast('0' + static_cast(a / 100)); - - const uint32_t i = (a % 100) << 1; - *buffer++ = cDigitsLut[i]; - *buffer++ = cDigitsLut[i + 1]; - } - else { - const uint32_t i = (a / 100) << 1; - const uint32_t j = (a % 100) << 1; - *buffer++ = cDigitsLut[i]; - *buffer++ = cDigitsLut[i + 1]; - *buffer++ = cDigitsLut[j]; - *buffer++ = cDigitsLut[j + 1]; - } - - const uint32_t v0 = static_cast(value / kTen8); - const uint32_t v1 = static_cast(value % kTen8); - - const uint32_t b0 = v0 / 10000; - const uint32_t c0 = v0 % 10000; - - const uint32_t d1 = (b0 / 100) << 1; - const uint32_t d2 = (b0 % 100) << 1; - - const uint32_t d3 = (c0 / 100) << 1; - const uint32_t d4 = (c0 % 100) << 1; - - const uint32_t b1 = v1 / 10000; - const uint32_t c1 = v1 % 10000; - - const uint32_t d5 = (b1 / 100) << 1; - const uint32_t d6 = (b1 % 100) << 1; - - const uint32_t d7 = (c1 / 100) << 1; - const uint32_t d8 = (c1 % 100) << 1; - - *buffer++ = cDigitsLut[d1]; - *buffer++ = cDigitsLut[d1 + 1]; - *buffer++ = cDigitsLut[d2]; - *buffer++ = cDigitsLut[d2 + 1]; - *buffer++ = cDigitsLut[d3]; - *buffer++ = cDigitsLut[d3 + 1]; - *buffer++ = cDigitsLut[d4]; - *buffer++ = cDigitsLut[d4 + 1]; - *buffer++ = cDigitsLut[d5]; - *buffer++ = cDigitsLut[d5 + 1]; - *buffer++ = cDigitsLut[d6]; - *buffer++ = cDigitsLut[d6 + 1]; - *buffer++ = cDigitsLut[d7]; - *buffer++ = cDigitsLut[d7 + 1]; - *buffer++ = cDigitsLut[d8]; - *buffer++ = cDigitsLut[d8 + 1]; - } - - return buffer; -} - -inline char* i64toa(int64_t value, char* buffer) { - RAPIDJSON_ASSERT(buffer != 0); - uint64_t u = static_cast(value); - if (value < 0) { - *buffer++ = '-'; - u = ~u + 1; - } - - return u64toa(u, buffer); -} - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_ITOA_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/meta.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/meta.h deleted file mode 100644 index d401edf8..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/meta.h +++ /dev/null @@ -1,186 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_INTERNAL_META_H_ -#define RAPIDJSON_INTERNAL_META_H_ - -#include "../rapidjson.h" - -#ifdef __GNUC__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(effc++) -#endif - -#if defined(_MSC_VER) && !defined(__clang__) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(6334) -#endif - -#if RAPIDJSON_HAS_CXX11_TYPETRAITS -#include -#endif - -//@cond RAPIDJSON_INTERNAL -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching -template struct Void { typedef void Type; }; - -/////////////////////////////////////////////////////////////////////////////// -// BoolType, TrueType, FalseType -// -template struct BoolType { - static const bool Value = Cond; - typedef BoolType Type; -}; -typedef BoolType TrueType; -typedef BoolType FalseType; - - -/////////////////////////////////////////////////////////////////////////////// -// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr -// - -template struct SelectIfImpl { template struct Apply { typedef T1 Type; }; }; -template <> struct SelectIfImpl { template struct Apply { typedef T2 Type; }; }; -template struct SelectIfCond : SelectIfImpl::template Apply {}; -template struct SelectIf : SelectIfCond {}; - -template struct AndExprCond : FalseType {}; -template <> struct AndExprCond : TrueType {}; -template struct OrExprCond : TrueType {}; -template <> struct OrExprCond : FalseType {}; - -template struct BoolExpr : SelectIf::Type {}; -template struct NotExpr : SelectIf::Type {}; -template struct AndExpr : AndExprCond::Type {}; -template struct OrExpr : OrExprCond::Type {}; - - -/////////////////////////////////////////////////////////////////////////////// -// AddConst, MaybeAddConst, RemoveConst -template struct AddConst { typedef const T Type; }; -template struct MaybeAddConst : SelectIfCond {}; -template struct RemoveConst { typedef T Type; }; -template struct RemoveConst { typedef T Type; }; - - -/////////////////////////////////////////////////////////////////////////////// -// IsSame, IsConst, IsMoreConst, IsPointer -// -template struct IsSame : FalseType {}; -template struct IsSame : TrueType {}; - -template struct IsConst : FalseType {}; -template struct IsConst : TrueType {}; - -template -struct IsMoreConst - : AndExpr::Type, typename RemoveConst::Type>, - BoolType::Value >= IsConst::Value> >::Type {}; - -template struct IsPointer : FalseType {}; -template struct IsPointer : TrueType {}; - -/////////////////////////////////////////////////////////////////////////////// -// IsBaseOf -// -#if RAPIDJSON_HAS_CXX11_TYPETRAITS - -template struct IsBaseOf - : BoolType< ::std::is_base_of::value> {}; - -#else // simplified version adopted from Boost - -template struct IsBaseOfImpl { - RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0); - RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0); - - typedef char (&Yes)[1]; - typedef char (&No) [2]; - - template - static Yes Check(const D*, T); - static No Check(const B*, int); - - struct Host { - operator const B*() const; - operator const D*(); - }; - - enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) }; -}; - -template struct IsBaseOf - : OrExpr, BoolExpr > >::Type {}; - -#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS - - -////////////////////////////////////////////////////////////////////////// -// EnableIf / DisableIf -// -template struct EnableIfCond { typedef T Type; }; -template struct EnableIfCond { /* empty */ }; - -template struct DisableIfCond { typedef T Type; }; -template struct DisableIfCond { /* empty */ }; - -template -struct EnableIf : EnableIfCond {}; - -template -struct DisableIf : DisableIfCond {}; - -// SFINAE helpers -struct SfinaeTag {}; -template struct RemoveSfinaeTag; -template struct RemoveSfinaeTag { typedef T Type; }; - -#define RAPIDJSON_REMOVEFPTR_(type) \ - typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \ - < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type - -#define RAPIDJSON_ENABLEIF(cond) \ - typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ - ::Type * = NULL - -#define RAPIDJSON_DISABLEIF(cond) \ - typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ - ::Type * = NULL - -#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \ - typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ - ::Type - -#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \ - typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ - ::Type - -} // namespace internal -RAPIDJSON_NAMESPACE_END -//@endcond - -#if defined(_MSC_VER) && !defined(__clang__) -RAPIDJSON_DIAG_POP -#endif - -#ifdef __GNUC__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_INTERNAL_META_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/pow10.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/pow10.h deleted file mode 100644 index 02f475d7..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/pow10.h +++ /dev/null @@ -1,55 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_POW10_ -#define RAPIDJSON_POW10_ - -#include "../rapidjson.h" - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -//! Computes integer powers of 10 in double (10.0^n). -/*! This function uses lookup table for fast and accurate results. - \param n non-negative exponent. Must <= 308. - \return 10.0^n -*/ -inline double Pow10(int n) { - static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes - 1e+0, - 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, - 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, - 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, - 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, - 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, - 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, - 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, - 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, - 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, - 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, - 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, - 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, - 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, - 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, - 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, - 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 - }; - RAPIDJSON_ASSERT(n >= 0 && n <= 308); - return e[n]; -} - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_POW10_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/regex.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/regex.h deleted file mode 100644 index af7e06de..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/regex.h +++ /dev/null @@ -1,739 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_INTERNAL_REGEX_H_ -#define RAPIDJSON_INTERNAL_REGEX_H_ - -#include "../allocators.h" -#include "../stream.h" -#include "stack.h" - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(padded) -RAPIDJSON_DIAG_OFF(switch-enum) -#elif defined(_MSC_VER) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated -#endif - -#ifdef __GNUC__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(effc++) -#endif - -#ifndef RAPIDJSON_REGEX_VERBOSE -#define RAPIDJSON_REGEX_VERBOSE 0 -#endif - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -/////////////////////////////////////////////////////////////////////////////// -// DecodedStream - -template -class DecodedStream { -public: - DecodedStream(SourceStream& ss) : ss_(ss), codepoint_() { Decode(); } - unsigned Peek() { return codepoint_; } - unsigned Take() { - unsigned c = codepoint_; - if (c) // No further decoding when '\0' - Decode(); - return c; - } - -private: - void Decode() { - if (!Encoding::Decode(ss_, &codepoint_)) - codepoint_ = 0; - } - - SourceStream& ss_; - unsigned codepoint_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// GenericRegex - -static const SizeType kRegexInvalidState = ~SizeType(0); //!< Represents an invalid index in GenericRegex::State::out, out1 -static const SizeType kRegexInvalidRange = ~SizeType(0); - -template -class GenericRegexSearch; - -//! Regular expression engine with subset of ECMAscript grammar. -/*! - Supported regular expression syntax: - - \c ab Concatenation - - \c a|b Alternation - - \c a? Zero or one - - \c a* Zero or more - - \c a+ One or more - - \c a{3} Exactly 3 times - - \c a{3,} At least 3 times - - \c a{3,5} 3 to 5 times - - \c (ab) Grouping - - \c ^a At the beginning - - \c a$ At the end - - \c . Any character - - \c [abc] Character classes - - \c [a-c] Character class range - - \c [a-z0-9_] Character class combination - - \c [^abc] Negated character classes - - \c [^a-c] Negated character class range - - \c [\b] Backspace (U+0008) - - \c \\| \\\\ ... Escape characters - - \c \\f Form feed (U+000C) - - \c \\n Line feed (U+000A) - - \c \\r Carriage return (U+000D) - - \c \\t Tab (U+0009) - - \c \\v Vertical tab (U+000B) - - \note This is a Thompson NFA engine, implemented with reference to - Cox, Russ. "Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby,...).", - https://swtch.com/~rsc/regexp/regexp1.html -*/ -template -class GenericRegex { -public: - typedef Encoding EncodingType; - typedef typename Encoding::Ch Ch; - template friend class GenericRegexSearch; - - GenericRegex(const Ch* source, Allocator* allocator = 0) : - ownAllocator_(allocator ? 0 : RAPIDJSON_NEW(Allocator)()), allocator_(allocator ? allocator : ownAllocator_), - states_(allocator_, 256), ranges_(allocator_, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(), - anchorBegin_(), anchorEnd_() - { - GenericStringStream ss(source); - DecodedStream, Encoding> ds(ss); - Parse(ds); - } - - ~GenericRegex() - { - RAPIDJSON_DELETE(ownAllocator_); - } - - bool IsValid() const { - return root_ != kRegexInvalidState; - } - -private: - enum Operator { - kZeroOrOne, - kZeroOrMore, - kOneOrMore, - kConcatenation, - kAlternation, - kLeftParenthesis - }; - - static const unsigned kAnyCharacterClass = 0xFFFFFFFF; //!< For '.' - static const unsigned kRangeCharacterClass = 0xFFFFFFFE; - static const unsigned kRangeNegationFlag = 0x80000000; - - struct Range { - unsigned start; // - unsigned end; - SizeType next; - }; - - struct State { - SizeType out; //!< Equals to kInvalid for matching state - SizeType out1; //!< Equals to non-kInvalid for split - SizeType rangeStart; - unsigned codepoint; - }; - - struct Frag { - Frag(SizeType s, SizeType o, SizeType m) : start(s), out(o), minIndex(m) {} - SizeType start; - SizeType out; //!< link-list of all output states - SizeType minIndex; - }; - - State& GetState(SizeType index) { - RAPIDJSON_ASSERT(index < stateCount_); - return states_.template Bottom()[index]; - } - - const State& GetState(SizeType index) const { - RAPIDJSON_ASSERT(index < stateCount_); - return states_.template Bottom()[index]; - } - - Range& GetRange(SizeType index) { - RAPIDJSON_ASSERT(index < rangeCount_); - return ranges_.template Bottom()[index]; - } - - const Range& GetRange(SizeType index) const { - RAPIDJSON_ASSERT(index < rangeCount_); - return ranges_.template Bottom()[index]; - } - - template - void Parse(DecodedStream& ds) { - Stack operandStack(allocator_, 256); // Frag - Stack operatorStack(allocator_, 256); // Operator - Stack atomCountStack(allocator_, 256); // unsigned (Atom per parenthesis) - - *atomCountStack.template Push() = 0; - - unsigned codepoint; - while (ds.Peek() != 0) { - switch (codepoint = ds.Take()) { - case '^': - anchorBegin_ = true; - break; - - case '$': - anchorEnd_ = true; - break; - - case '|': - while (!operatorStack.Empty() && *operatorStack.template Top() < kAlternation) - if (!Eval(operandStack, *operatorStack.template Pop(1))) - return; - *operatorStack.template Push() = kAlternation; - *atomCountStack.template Top() = 0; - break; - - case '(': - *operatorStack.template Push() = kLeftParenthesis; - *atomCountStack.template Push() = 0; - break; - - case ')': - while (!operatorStack.Empty() && *operatorStack.template Top() != kLeftParenthesis) - if (!Eval(operandStack, *operatorStack.template Pop(1))) - return; - if (operatorStack.Empty()) - return; - operatorStack.template Pop(1); - atomCountStack.template Pop(1); - ImplicitConcatenation(atomCountStack, operatorStack); - break; - - case '?': - if (!Eval(operandStack, kZeroOrOne)) - return; - break; - - case '*': - if (!Eval(operandStack, kZeroOrMore)) - return; - break; - - case '+': - if (!Eval(operandStack, kOneOrMore)) - return; - break; - - case '{': - { - unsigned n, m; - if (!ParseUnsigned(ds, &n)) - return; - - if (ds.Peek() == ',') { - ds.Take(); - if (ds.Peek() == '}') - m = kInfinityQuantifier; - else if (!ParseUnsigned(ds, &m) || m < n) - return; - } - else - m = n; - - if (!EvalQuantifier(operandStack, n, m) || ds.Peek() != '}') - return; - ds.Take(); - } - break; - - case '.': - PushOperand(operandStack, kAnyCharacterClass); - ImplicitConcatenation(atomCountStack, operatorStack); - break; - - case '[': - { - SizeType range; - if (!ParseRange(ds, &range)) - return; - SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, kRangeCharacterClass); - GetState(s).rangeStart = range; - *operandStack.template Push() = Frag(s, s, s); - } - ImplicitConcatenation(atomCountStack, operatorStack); - break; - - case '\\': // Escape character - if (!CharacterEscape(ds, &codepoint)) - return; // Unsupported escape character - // fall through to default - RAPIDJSON_DELIBERATE_FALLTHROUGH; - - default: // Pattern character - PushOperand(operandStack, codepoint); - ImplicitConcatenation(atomCountStack, operatorStack); - } - } - - while (!operatorStack.Empty()) - if (!Eval(operandStack, *operatorStack.template Pop(1))) - return; - - // Link the operand to matching state. - if (operandStack.GetSize() == sizeof(Frag)) { - Frag* e = operandStack.template Pop(1); - Patch(e->out, NewState(kRegexInvalidState, kRegexInvalidState, 0)); - root_ = e->start; - -#if RAPIDJSON_REGEX_VERBOSE - printf("root: %d\n", root_); - for (SizeType i = 0; i < stateCount_ ; i++) { - State& s = GetState(i); - printf("[%2d] out: %2d out1: %2d c: '%c'\n", i, s.out, s.out1, (char)s.codepoint); - } - printf("\n"); -#endif - } - } - - SizeType NewState(SizeType out, SizeType out1, unsigned codepoint) { - State* s = states_.template Push(); - s->out = out; - s->out1 = out1; - s->codepoint = codepoint; - s->rangeStart = kRegexInvalidRange; - return stateCount_++; - } - - void PushOperand(Stack& operandStack, unsigned codepoint) { - SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, codepoint); - *operandStack.template Push() = Frag(s, s, s); - } - - void ImplicitConcatenation(Stack& atomCountStack, Stack& operatorStack) { - if (*atomCountStack.template Top()) - *operatorStack.template Push() = kConcatenation; - (*atomCountStack.template Top())++; - } - - SizeType Append(SizeType l1, SizeType l2) { - SizeType old = l1; - while (GetState(l1).out != kRegexInvalidState) - l1 = GetState(l1).out; - GetState(l1).out = l2; - return old; - } - - void Patch(SizeType l, SizeType s) { - for (SizeType next; l != kRegexInvalidState; l = next) { - next = GetState(l).out; - GetState(l).out = s; - } - } - - bool Eval(Stack& operandStack, Operator op) { - switch (op) { - case kConcatenation: - RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag) * 2); - { - Frag e2 = *operandStack.template Pop(1); - Frag e1 = *operandStack.template Pop(1); - Patch(e1.out, e2.start); - *operandStack.template Push() = Frag(e1.start, e2.out, Min(e1.minIndex, e2.minIndex)); - } - return true; - - case kAlternation: - if (operandStack.GetSize() >= sizeof(Frag) * 2) { - Frag e2 = *operandStack.template Pop(1); - Frag e1 = *operandStack.template Pop(1); - SizeType s = NewState(e1.start, e2.start, 0); - *operandStack.template Push() = Frag(s, Append(e1.out, e2.out), Min(e1.minIndex, e2.minIndex)); - return true; - } - return false; - - case kZeroOrOne: - if (operandStack.GetSize() >= sizeof(Frag)) { - Frag e = *operandStack.template Pop(1); - SizeType s = NewState(kRegexInvalidState, e.start, 0); - *operandStack.template Push() = Frag(s, Append(e.out, s), e.minIndex); - return true; - } - return false; - - case kZeroOrMore: - if (operandStack.GetSize() >= sizeof(Frag)) { - Frag e = *operandStack.template Pop(1); - SizeType s = NewState(kRegexInvalidState, e.start, 0); - Patch(e.out, s); - *operandStack.template Push() = Frag(s, s, e.minIndex); - return true; - } - return false; - - case kOneOrMore: - if (operandStack.GetSize() >= sizeof(Frag)) { - Frag e = *operandStack.template Pop(1); - SizeType s = NewState(kRegexInvalidState, e.start, 0); - Patch(e.out, s); - *operandStack.template Push() = Frag(e.start, s, e.minIndex); - return true; - } - return false; - - default: - // syntax error (e.g. unclosed kLeftParenthesis) - return false; - } - } - - bool EvalQuantifier(Stack& operandStack, unsigned n, unsigned m) { - RAPIDJSON_ASSERT(n <= m); - RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag)); - - if (n == 0) { - if (m == 0) // a{0} not support - return false; - else if (m == kInfinityQuantifier) - Eval(operandStack, kZeroOrMore); // a{0,} -> a* - else { - Eval(operandStack, kZeroOrOne); // a{0,5} -> a? - for (unsigned i = 0; i < m - 1; i++) - CloneTopOperand(operandStack); // a{0,5} -> a? a? a? a? a? - for (unsigned i = 0; i < m - 1; i++) - Eval(operandStack, kConcatenation); // a{0,5} -> a?a?a?a?a? - } - return true; - } - - for (unsigned i = 0; i < n - 1; i++) // a{3} -> a a a - CloneTopOperand(operandStack); - - if (m == kInfinityQuantifier) - Eval(operandStack, kOneOrMore); // a{3,} -> a a a+ - else if (m > n) { - CloneTopOperand(operandStack); // a{3,5} -> a a a a - Eval(operandStack, kZeroOrOne); // a{3,5} -> a a a a? - for (unsigned i = n; i < m - 1; i++) - CloneTopOperand(operandStack); // a{3,5} -> a a a a? a? - for (unsigned i = n; i < m; i++) - Eval(operandStack, kConcatenation); // a{3,5} -> a a aa?a? - } - - for (unsigned i = 0; i < n - 1; i++) - Eval(operandStack, kConcatenation); // a{3} -> aaa, a{3,} -> aaa+, a{3.5} -> aaaa?a? - - return true; - } - - static SizeType Min(SizeType a, SizeType b) { return a < b ? a : b; } - - void CloneTopOperand(Stack& operandStack) { - const Frag src = *operandStack.template Top(); // Copy constructor to prevent invalidation - SizeType count = stateCount_ - src.minIndex; // Assumes top operand contains states in [src->minIndex, stateCount_) - State* s = states_.template Push(count); - memcpy(s, &GetState(src.minIndex), count * sizeof(State)); - for (SizeType j = 0; j < count; j++) { - if (s[j].out != kRegexInvalidState) - s[j].out += count; - if (s[j].out1 != kRegexInvalidState) - s[j].out1 += count; - } - *operandStack.template Push() = Frag(src.start + count, src.out + count, src.minIndex + count); - stateCount_ += count; - } - - template - bool ParseUnsigned(DecodedStream& ds, unsigned* u) { - unsigned r = 0; - if (ds.Peek() < '0' || ds.Peek() > '9') - return false; - while (ds.Peek() >= '0' && ds.Peek() <= '9') { - if (r >= 429496729 && ds.Peek() > '5') // 2^32 - 1 = 4294967295 - return false; // overflow - r = r * 10 + (ds.Take() - '0'); - } - *u = r; - return true; - } - - template - bool ParseRange(DecodedStream& ds, SizeType* range) { - bool isBegin = true; - bool negate = false; - int step = 0; - SizeType start = kRegexInvalidRange; - SizeType current = kRegexInvalidRange; - unsigned codepoint; - while ((codepoint = ds.Take()) != 0) { - if (isBegin) { - isBegin = false; - if (codepoint == '^') { - negate = true; - continue; - } - } - - switch (codepoint) { - case ']': - if (start == kRegexInvalidRange) - return false; // Error: nothing inside [] - if (step == 2) { // Add trailing '-' - SizeType r = NewRange('-'); - RAPIDJSON_ASSERT(current != kRegexInvalidRange); - GetRange(current).next = r; - } - if (negate) - GetRange(start).start |= kRangeNegationFlag; - *range = start; - return true; - - case '\\': - if (ds.Peek() == 'b') { - ds.Take(); - codepoint = 0x0008; // Escape backspace character - } - else if (!CharacterEscape(ds, &codepoint)) - return false; - // fall through to default - RAPIDJSON_DELIBERATE_FALLTHROUGH; - - default: - switch (step) { - case 1: - if (codepoint == '-') { - step++; - break; - } - // fall through to step 0 for other characters - RAPIDJSON_DELIBERATE_FALLTHROUGH; - - case 0: - { - SizeType r = NewRange(codepoint); - if (current != kRegexInvalidRange) - GetRange(current).next = r; - if (start == kRegexInvalidRange) - start = r; - current = r; - } - step = 1; - break; - - default: - RAPIDJSON_ASSERT(step == 2); - GetRange(current).end = codepoint; - step = 0; - } - } - } - return false; - } - - SizeType NewRange(unsigned codepoint) { - Range* r = ranges_.template Push(); - r->start = r->end = codepoint; - r->next = kRegexInvalidRange; - return rangeCount_++; - } - - template - bool CharacterEscape(DecodedStream& ds, unsigned* escapedCodepoint) { - unsigned codepoint; - switch (codepoint = ds.Take()) { - case '^': - case '$': - case '|': - case '(': - case ')': - case '?': - case '*': - case '+': - case '.': - case '[': - case ']': - case '{': - case '}': - case '\\': - *escapedCodepoint = codepoint; return true; - case 'f': *escapedCodepoint = 0x000C; return true; - case 'n': *escapedCodepoint = 0x000A; return true; - case 'r': *escapedCodepoint = 0x000D; return true; - case 't': *escapedCodepoint = 0x0009; return true; - case 'v': *escapedCodepoint = 0x000B; return true; - default: - return false; // Unsupported escape character - } - } - - Allocator* ownAllocator_; - Allocator* allocator_; - Stack states_; - Stack ranges_; - SizeType root_; - SizeType stateCount_; - SizeType rangeCount_; - - static const unsigned kInfinityQuantifier = ~0u; - - // For SearchWithAnchoring() - bool anchorBegin_; - bool anchorEnd_; -}; - -template -class GenericRegexSearch { -public: - typedef typename RegexType::EncodingType Encoding; - typedef typename Encoding::Ch Ch; - - GenericRegexSearch(const RegexType& regex, Allocator* allocator = 0) : - regex_(regex), allocator_(allocator), ownAllocator_(0), - state0_(allocator, 0), state1_(allocator, 0), stateSet_() - { - RAPIDJSON_ASSERT(regex_.IsValid()); - if (!allocator_) - ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); - stateSet_ = static_cast(allocator_->Malloc(GetStateSetSize())); - state0_.template Reserve(regex_.stateCount_); - state1_.template Reserve(regex_.stateCount_); - } - - ~GenericRegexSearch() { - Allocator::Free(stateSet_); - RAPIDJSON_DELETE(ownAllocator_); - } - - template - bool Match(InputStream& is) { - return SearchWithAnchoring(is, true, true); - } - - bool Match(const Ch* s) { - GenericStringStream is(s); - return Match(is); - } - - template - bool Search(InputStream& is) { - return SearchWithAnchoring(is, regex_.anchorBegin_, regex_.anchorEnd_); - } - - bool Search(const Ch* s) { - GenericStringStream is(s); - return Search(is); - } - -private: - typedef typename RegexType::State State; - typedef typename RegexType::Range Range; - - template - bool SearchWithAnchoring(InputStream& is, bool anchorBegin, bool anchorEnd) { - DecodedStream ds(is); - - state0_.Clear(); - Stack *current = &state0_, *next = &state1_; - const size_t stateSetSize = GetStateSetSize(); - std::memset(stateSet_, 0, stateSetSize); - - bool matched = AddState(*current, regex_.root_); - unsigned codepoint; - while (!current->Empty() && (codepoint = ds.Take()) != 0) { - std::memset(stateSet_, 0, stateSetSize); - next->Clear(); - matched = false; - for (const SizeType* s = current->template Bottom(); s != current->template End(); ++s) { - const State& sr = regex_.GetState(*s); - if (sr.codepoint == codepoint || - sr.codepoint == RegexType::kAnyCharacterClass || - (sr.codepoint == RegexType::kRangeCharacterClass && MatchRange(sr.rangeStart, codepoint))) - { - matched = AddState(*next, sr.out) || matched; - if (!anchorEnd && matched) - return true; - } - if (!anchorBegin) - AddState(*next, regex_.root_); - } - internal::Swap(current, next); - } - - return matched; - } - - size_t GetStateSetSize() const { - return (regex_.stateCount_ + 31) / 32 * 4; - } - - // Return whether the added states is a match state - bool AddState(Stack& l, SizeType index) { - RAPIDJSON_ASSERT(index != kRegexInvalidState); - - const State& s = regex_.GetState(index); - if (s.out1 != kRegexInvalidState) { // Split - bool matched = AddState(l, s.out); - return AddState(l, s.out1) || matched; - } - else if (!(stateSet_[index >> 5] & (1u << (index & 31)))) { - stateSet_[index >> 5] |= (1u << (index & 31)); - *l.template PushUnsafe() = index; - } - return s.out == kRegexInvalidState; // by using PushUnsafe() above, we can ensure s is not validated due to reallocation. - } - - bool MatchRange(SizeType rangeIndex, unsigned codepoint) const { - bool yes = (regex_.GetRange(rangeIndex).start & RegexType::kRangeNegationFlag) == 0; - while (rangeIndex != kRegexInvalidRange) { - const Range& r = regex_.GetRange(rangeIndex); - if (codepoint >= (r.start & ~RegexType::kRangeNegationFlag) && codepoint <= r.end) - return yes; - rangeIndex = r.next; - } - return !yes; - } - - const RegexType& regex_; - Allocator* allocator_; - Allocator* ownAllocator_; - Stack state0_; - Stack state1_; - uint32_t* stateSet_; -}; - -typedef GenericRegex > Regex; -typedef GenericRegexSearch RegexSearch; - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#ifdef __GNUC__ -RAPIDJSON_DIAG_POP -#endif - -#if defined(__clang__) || defined(_MSC_VER) -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_INTERNAL_REGEX_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/stack.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/stack.h deleted file mode 100644 index 45dca6a8..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/stack.h +++ /dev/null @@ -1,232 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_INTERNAL_STACK_H_ -#define RAPIDJSON_INTERNAL_STACK_H_ - -#include "../allocators.h" -#include "swap.h" -#include - -#if defined(__clang__) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(c++98-compat) -#endif - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -/////////////////////////////////////////////////////////////////////////////// -// Stack - -//! A type-unsafe stack for storing different types of data. -/*! \tparam Allocator Allocator for allocating stack memory. -*/ -template -class Stack { -public: - // Optimization note: Do not allocate memory for stack_ in constructor. - // Do it lazily when first Push() -> Expand() -> Resize(). - Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) { - } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - Stack(Stack&& rhs) - : allocator_(rhs.allocator_), - ownAllocator_(rhs.ownAllocator_), - stack_(rhs.stack_), - stackTop_(rhs.stackTop_), - stackEnd_(rhs.stackEnd_), - initialCapacity_(rhs.initialCapacity_) - { - rhs.allocator_ = 0; - rhs.ownAllocator_ = 0; - rhs.stack_ = 0; - rhs.stackTop_ = 0; - rhs.stackEnd_ = 0; - rhs.initialCapacity_ = 0; - } -#endif - - ~Stack() { - Destroy(); - } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - Stack& operator=(Stack&& rhs) { - if (&rhs != this) - { - Destroy(); - - allocator_ = rhs.allocator_; - ownAllocator_ = rhs.ownAllocator_; - stack_ = rhs.stack_; - stackTop_ = rhs.stackTop_; - stackEnd_ = rhs.stackEnd_; - initialCapacity_ = rhs.initialCapacity_; - - rhs.allocator_ = 0; - rhs.ownAllocator_ = 0; - rhs.stack_ = 0; - rhs.stackTop_ = 0; - rhs.stackEnd_ = 0; - rhs.initialCapacity_ = 0; - } - return *this; - } -#endif - - void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT { - internal::Swap(allocator_, rhs.allocator_); - internal::Swap(ownAllocator_, rhs.ownAllocator_); - internal::Swap(stack_, rhs.stack_); - internal::Swap(stackTop_, rhs.stackTop_); - internal::Swap(stackEnd_, rhs.stackEnd_); - internal::Swap(initialCapacity_, rhs.initialCapacity_); - } - - void Clear() { stackTop_ = stack_; } - - void ShrinkToFit() { - if (Empty()) { - // If the stack is empty, completely deallocate the memory. - Allocator::Free(stack_); // NOLINT (+clang-analyzer-unix.Malloc) - stack_ = 0; - stackTop_ = 0; - stackEnd_ = 0; - } - else - Resize(GetSize()); - } - - // Optimization note: try to minimize the size of this function for force inline. - // Expansion is run very infrequently, so it is moved to another (probably non-inline) function. - template - RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) { - // Expand the stack if needed - if (RAPIDJSON_UNLIKELY(static_cast(sizeof(T) * count) > (stackEnd_ - stackTop_))) - Expand(count); - } - - template - RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) { - Reserve(count); - return PushUnsafe(count); - } - - template - RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) { - RAPIDJSON_ASSERT(stackTop_); - RAPIDJSON_ASSERT(static_cast(sizeof(T) * count) <= (stackEnd_ - stackTop_)); - T* ret = reinterpret_cast(stackTop_); - stackTop_ += sizeof(T) * count; - return ret; - } - - template - T* Pop(size_t count) { - RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T)); - stackTop_ -= count * sizeof(T); - return reinterpret_cast(stackTop_); - } - - template - T* Top() { - RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); - return reinterpret_cast(stackTop_ - sizeof(T)); - } - - template - const T* Top() const { - RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); - return reinterpret_cast(stackTop_ - sizeof(T)); - } - - template - T* End() { return reinterpret_cast(stackTop_); } - - template - const T* End() const { return reinterpret_cast(stackTop_); } - - template - T* Bottom() { return reinterpret_cast(stack_); } - - template - const T* Bottom() const { return reinterpret_cast(stack_); } - - bool HasAllocator() const { - return allocator_ != 0; - } - - Allocator& GetAllocator() { - RAPIDJSON_ASSERT(allocator_); - return *allocator_; - } - - bool Empty() const { return stackTop_ == stack_; } - size_t GetSize() const { return static_cast(stackTop_ - stack_); } - size_t GetCapacity() const { return static_cast(stackEnd_ - stack_); } - -private: - template - void Expand(size_t count) { - // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity. - size_t newCapacity; - if (stack_ == 0) { - if (!allocator_) - ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); - newCapacity = initialCapacity_; - } else { - newCapacity = GetCapacity(); - newCapacity += (newCapacity + 1) / 2; - } - size_t newSize = GetSize() + sizeof(T) * count; - if (newCapacity < newSize) - newCapacity = newSize; - - Resize(newCapacity); - } - - void Resize(size_t newCapacity) { - const size_t size = GetSize(); // Backup the current size - stack_ = static_cast(allocator_->Realloc(stack_, GetCapacity(), newCapacity)); - stackTop_ = stack_ + size; - stackEnd_ = stack_ + newCapacity; - } - - void Destroy() { - Allocator::Free(stack_); - RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack - } - - // Prohibit copy constructor & assignment operator. - Stack(const Stack&); - Stack& operator=(const Stack&); - - Allocator* allocator_; - Allocator* ownAllocator_; - char *stack_; - char *stackTop_; - char *stackEnd_; - size_t initialCapacity_; -}; - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#if defined(__clang__) -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_STACK_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/strfunc.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/strfunc.h deleted file mode 100644 index 226439a7..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/strfunc.h +++ /dev/null @@ -1,69 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ -#define RAPIDJSON_INTERNAL_STRFUNC_H_ - -#include "../stream.h" -#include - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -//! Custom strlen() which works on different character types. -/*! \tparam Ch Character type (e.g. char, wchar_t, short) - \param s Null-terminated input string. - \return Number of characters in the string. - \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. -*/ -template -inline SizeType StrLen(const Ch* s) { - RAPIDJSON_ASSERT(s != 0); - const Ch* p = s; - while (*p) ++p; - return SizeType(p - s); -} - -template <> -inline SizeType StrLen(const char* s) { - return SizeType(std::strlen(s)); -} - -template <> -inline SizeType StrLen(const wchar_t* s) { - return SizeType(std::wcslen(s)); -} - -//! Returns number of code points in a encoded string. -template -bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) { - RAPIDJSON_ASSERT(s != 0); - RAPIDJSON_ASSERT(outCount != 0); - GenericStringStream is(s); - const typename Encoding::Ch* end = s + length; - SizeType count = 0; - while (is.src_ < end) { - unsigned codepoint; - if (!Encoding::Decode(is, &codepoint)) - return false; - count++; - } - *outCount = count; - return true; -} - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_INTERNAL_STRFUNC_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/strtod.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/strtod.h deleted file mode 100644 index dfca22b6..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/strtod.h +++ /dev/null @@ -1,290 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_STRTOD_ -#define RAPIDJSON_STRTOD_ - -#include "ieee754.h" -#include "biginteger.h" -#include "diyfp.h" -#include "pow10.h" -#include -#include - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -inline double FastPath(double significand, int exp) { - if (exp < -308) - return 0.0; - else if (exp >= 0) - return significand * internal::Pow10(exp); - else - return significand / internal::Pow10(-exp); -} - -inline double StrtodNormalPrecision(double d, int p) { - if (p < -308) { - // Prevent expSum < -308, making Pow10(p) = 0 - d = FastPath(d, -308); - d = FastPath(d, p + 308); - } - else - d = FastPath(d, p); - return d; -} - -template -inline T Min3(T a, T b, T c) { - T m = a; - if (m > b) m = b; - if (m > c) m = c; - return m; -} - -inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) { - const Double db(b); - const uint64_t bInt = db.IntegerSignificand(); - const int bExp = db.IntegerExponent(); - const int hExp = bExp - 1; - - int dS_Exp2 = 0, dS_Exp5 = 0, bS_Exp2 = 0, bS_Exp5 = 0, hS_Exp2 = 0, hS_Exp5 = 0; - - // Adjust for decimal exponent - if (dExp >= 0) { - dS_Exp2 += dExp; - dS_Exp5 += dExp; - } - else { - bS_Exp2 -= dExp; - bS_Exp5 -= dExp; - hS_Exp2 -= dExp; - hS_Exp5 -= dExp; - } - - // Adjust for binary exponent - if (bExp >= 0) - bS_Exp2 += bExp; - else { - dS_Exp2 -= bExp; - hS_Exp2 -= bExp; - } - - // Adjust for half ulp exponent - if (hExp >= 0) - hS_Exp2 += hExp; - else { - dS_Exp2 -= hExp; - bS_Exp2 -= hExp; - } - - // Remove common power of two factor from all three scaled values - int common_Exp2 = Min3(dS_Exp2, bS_Exp2, hS_Exp2); - dS_Exp2 -= common_Exp2; - bS_Exp2 -= common_Exp2; - hS_Exp2 -= common_Exp2; - - BigInteger dS = d; - dS.MultiplyPow5(static_cast(dS_Exp5)) <<= static_cast(dS_Exp2); - - BigInteger bS(bInt); - bS.MultiplyPow5(static_cast(bS_Exp5)) <<= static_cast(bS_Exp2); - - BigInteger hS(1); - hS.MultiplyPow5(static_cast(hS_Exp5)) <<= static_cast(hS_Exp2); - - BigInteger delta(0); - dS.Difference(bS, &delta); - - return delta.Compare(hS); -} - -inline bool StrtodFast(double d, int p, double* result) { - // Use fast path for string-to-double conversion if possible - // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ - if (p > 22 && p < 22 + 16) { - // Fast Path Cases In Disguise - d *= internal::Pow10(p - 22); - p = 22; - } - - if (p >= -22 && p <= 22 && d <= 9007199254740991.0) { // 2^53 - 1 - *result = FastPath(d, p); - return true; - } - else - return false; -} - -// Compute an approximation and see if it is within 1/2 ULP -inline bool StrtodDiyFp(const char* decimals, int dLen, int dExp, double* result) { - uint64_t significand = 0; - int i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999 - for (; i < dLen; i++) { - if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || - (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5')) - break; - significand = significand * 10u + static_cast(decimals[i] - '0'); - } - - if (i < dLen && decimals[i] >= '5') // Rounding - significand++; - - int remaining = dLen - i; - const int kUlpShift = 3; - const int kUlp = 1 << kUlpShift; - int64_t error = (remaining == 0) ? 0 : kUlp / 2; - - DiyFp v(significand, 0); - v = v.Normalize(); - error <<= -v.e; - - dExp += remaining; - - int actualExp; - DiyFp cachedPower = GetCachedPower10(dExp, &actualExp); - if (actualExp != dExp) { - static const DiyFp kPow10[] = { - DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 0x00000000), -60), // 10^1 - DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 0x00000000), -57), // 10^2 - DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 0x00000000), -54), // 10^3 - DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), -50), // 10^4 - DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 0x00000000), -47), // 10^5 - DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 0x00000000), -44), // 10^6 - DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 0x00000000), -40) // 10^7 - }; - int adjustment = dExp - actualExp; - RAPIDJSON_ASSERT(adjustment >= 1 && adjustment < 8); - v = v * kPow10[adjustment - 1]; - if (dLen + adjustment > 19) // has more digits than decimal digits in 64-bit - error += kUlp / 2; - } - - v = v * cachedPower; - - error += kUlp + (error == 0 ? 0 : 1); - - const int oldExp = v.e; - v = v.Normalize(); - error <<= oldExp - v.e; - - const int effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e); - int precisionSize = 64 - effectiveSignificandSize; - if (precisionSize + kUlpShift >= 64) { - int scaleExp = (precisionSize + kUlpShift) - 63; - v.f >>= scaleExp; - v.e += scaleExp; - error = (error >> scaleExp) + 1 + kUlp; - precisionSize -= scaleExp; - } - - DiyFp rounded(v.f >> precisionSize, v.e + precisionSize); - const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp; - const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp; - if (precisionBits >= halfWay + static_cast(error)) { - rounded.f++; - if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340) - rounded.f >>= 1; - rounded.e++; - } - } - - *result = rounded.ToDouble(); - - return halfWay - static_cast(error) >= precisionBits || precisionBits >= halfWay + static_cast(error); -} - -inline double StrtodBigInteger(double approx, const char* decimals, int dLen, int dExp) { - RAPIDJSON_ASSERT(dLen >= 0); - const BigInteger dInt(decimals, static_cast(dLen)); - Double a(approx); - int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp); - if (cmp < 0) - return a.Value(); // within half ULP - else if (cmp == 0) { - // Round towards even - if (a.Significand() & 1) - return a.NextPositiveDouble(); - else - return a.Value(); - } - else // adjustment - return a.NextPositiveDouble(); -} - -inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) { - RAPIDJSON_ASSERT(d >= 0.0); - RAPIDJSON_ASSERT(length >= 1); - - double result = 0.0; - if (StrtodFast(d, p, &result)) - return result; - - RAPIDJSON_ASSERT(length <= INT_MAX); - int dLen = static_cast(length); - - RAPIDJSON_ASSERT(length >= decimalPosition); - RAPIDJSON_ASSERT(length - decimalPosition <= INT_MAX); - int dExpAdjust = static_cast(length - decimalPosition); - - RAPIDJSON_ASSERT(exp >= INT_MIN + dExpAdjust); - int dExp = exp - dExpAdjust; - - // Make sure length+dExp does not overflow - RAPIDJSON_ASSERT(dExp <= INT_MAX - dLen); - - // Trim leading zeros - while (dLen > 0 && *decimals == '0') { - dLen--; - decimals++; - } - - // Trim trailing zeros - while (dLen > 0 && decimals[dLen - 1] == '0') { - dLen--; - dExp++; - } - - if (dLen == 0) { // Buffer only contains zeros. - return 0.0; - } - - // Trim right-most digits - const int kMaxDecimalDigit = 767 + 1; - if (dLen > kMaxDecimalDigit) { - dExp += dLen - kMaxDecimalDigit; - dLen = kMaxDecimalDigit; - } - - // If too small, underflow to zero. - // Any x <= 10^-324 is interpreted as zero. - if (dLen + dExp <= -324) - return 0.0; - - // If too large, overflow to infinity. - // Any x >= 10^309 is interpreted as +infinity. - if (dLen + dExp > 309) - return std::numeric_limits::infinity(); - - if (StrtodDiyFp(decimals, dLen, dExp, &result)) - return result; - - // Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison - return StrtodBigInteger(result, decimals, dLen, dExp); -} - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_STRTOD_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/swap.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/swap.h deleted file mode 100644 index 666e49f9..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/internal/swap.h +++ /dev/null @@ -1,46 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_INTERNAL_SWAP_H_ -#define RAPIDJSON_INTERNAL_SWAP_H_ - -#include "../rapidjson.h" - -#if defined(__clang__) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(c++98-compat) -#endif - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -//! Custom swap() to avoid dependency on C++ header -/*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only. - \note This has the same semantics as std::swap(). -*/ -template -inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT { - T tmp = a; - a = b; - b = tmp; -} - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#if defined(__clang__) -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_INTERNAL_SWAP_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/istreamwrapper.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/istreamwrapper.h deleted file mode 100644 index c4950b9d..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/istreamwrapper.h +++ /dev/null @@ -1,128 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_ISTREAMWRAPPER_H_ -#define RAPIDJSON_ISTREAMWRAPPER_H_ - -#include "stream.h" -#include -#include - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(padded) -#elif defined(_MSC_VER) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! Wrapper of \c std::basic_istream into RapidJSON's Stream concept. -/*! - The classes can be wrapped including but not limited to: - - - \c std::istringstream - - \c std::stringstream - - \c std::wistringstream - - \c std::wstringstream - - \c std::ifstream - - \c std::fstream - - \c std::wifstream - - \c std::wfstream - - \tparam StreamType Class derived from \c std::basic_istream. -*/ - -template -class BasicIStreamWrapper { -public: - typedef typename StreamType::char_type Ch; - - //! Constructor. - /*! - \param stream stream opened for read. - */ - BasicIStreamWrapper(StreamType &stream) : stream_(stream), buffer_(peekBuffer_), bufferSize_(4), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { - Read(); - } - - //! Constructor. - /*! - \param stream stream opened for read. - \param buffer user-supplied buffer. - \param bufferSize size of buffer in bytes. Must >=4 bytes. - */ - BasicIStreamWrapper(StreamType &stream, char* buffer, size_t bufferSize) : stream_(stream), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { - RAPIDJSON_ASSERT(bufferSize >= 4); - Read(); - } - - Ch Peek() const { return *current_; } - Ch Take() { Ch c = *current_; Read(); return c; } - size_t Tell() const { return count_ + static_cast(current_ - buffer_); } - - // Not implemented - void Put(Ch) { RAPIDJSON_ASSERT(false); } - void Flush() { RAPIDJSON_ASSERT(false); } - Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } - - // For encoding detection only. - const Ch* Peek4() const { - return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0; - } - -private: - BasicIStreamWrapper(); - BasicIStreamWrapper(const BasicIStreamWrapper&); - BasicIStreamWrapper& operator=(const BasicIStreamWrapper&); - - void Read() { - if (current_ < bufferLast_) - ++current_; - else if (!eof_) { - count_ += readCount_; - readCount_ = bufferSize_; - bufferLast_ = buffer_ + readCount_ - 1; - current_ = buffer_; - - if (!stream_.read(buffer_, static_cast(bufferSize_))) { - readCount_ = static_cast(stream_.gcount()); - *(bufferLast_ = buffer_ + readCount_) = '\0'; - eof_ = true; - } - } - } - - StreamType &stream_; - Ch peekBuffer_[4], *buffer_; - size_t bufferSize_; - Ch *bufferLast_; - Ch *current_; - size_t readCount_; - size_t count_; //!< Number of characters read - bool eof_; -}; - -typedef BasicIStreamWrapper IStreamWrapper; -typedef BasicIStreamWrapper WIStreamWrapper; - -#if defined(__clang__) || defined(_MSC_VER) -RAPIDJSON_DIAG_POP -#endif - -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_ISTREAMWRAPPER_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/memorybuffer.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/memorybuffer.h deleted file mode 100644 index 39bee1de..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/memorybuffer.h +++ /dev/null @@ -1,70 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_MEMORYBUFFER_H_ -#define RAPIDJSON_MEMORYBUFFER_H_ - -#include "stream.h" -#include "internal/stack.h" - -RAPIDJSON_NAMESPACE_BEGIN - -//! Represents an in-memory output byte stream. -/*! - This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream. - - It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file. - - Differences between MemoryBuffer and StringBuffer: - 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer. - 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator. - - \tparam Allocator type for allocating memory buffer. - \note implements Stream concept -*/ -template -struct GenericMemoryBuffer { - typedef char Ch; // byte - - GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} - - void Put(Ch c) { *stack_.template Push() = c; } - void Flush() {} - - void Clear() { stack_.Clear(); } - void ShrinkToFit() { stack_.ShrinkToFit(); } - Ch* Push(size_t count) { return stack_.template Push(count); } - void Pop(size_t count) { stack_.template Pop(count); } - - const Ch* GetBuffer() const { - return stack_.template Bottom(); - } - - size_t GetSize() const { return stack_.GetSize(); } - - static const size_t kDefaultCapacity = 256; - mutable internal::Stack stack_; -}; - -typedef GenericMemoryBuffer<> MemoryBuffer; - -//! Implement specialized version of PutN() with memset() for better performance. -template<> -inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) { - std::memset(memoryBuffer.stack_.Push(n), c, n * sizeof(c)); -} - -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/memorystream.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/memorystream.h deleted file mode 100644 index 1d71d8a4..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/memorystream.h +++ /dev/null @@ -1,71 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_MEMORYSTREAM_H_ -#define RAPIDJSON_MEMORYSTREAM_H_ - -#include "stream.h" - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(unreachable-code) -RAPIDJSON_DIAG_OFF(missing-noreturn) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! Represents an in-memory input byte stream. -/*! - This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream. - - It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file. - - Differences between MemoryStream and StringStream: - 1. StringStream has encoding but MemoryStream is a byte stream. - 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source. - 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4(). - \note implements Stream concept -*/ -struct MemoryStream { - typedef char Ch; // byte - - MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {} - - Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_; } - Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; } - size_t Tell() const { return static_cast(src_ - begin_); } - - Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - void Put(Ch) { RAPIDJSON_ASSERT(false); } - void Flush() { RAPIDJSON_ASSERT(false); } - size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } - - // For encoding detection only. - const Ch* Peek4() const { - return Tell() + 4 <= size_ ? src_ : 0; - } - - const Ch* src_; //!< Current read position. - const Ch* begin_; //!< Original head of the string. - const Ch* end_; //!< End of stream. - size_t size_; //!< Size of the stream. -}; - -RAPIDJSON_NAMESPACE_END - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/msinttypes/inttypes.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/msinttypes/inttypes.h deleted file mode 100644 index 18111286..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/msinttypes/inttypes.h +++ /dev/null @@ -1,316 +0,0 @@ -// ISO C9x compliant inttypes.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2013 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the product nor the names of its contributors may -// be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////////// - -// The above software in this distribution may have been modified by -// THL A29 Limited ("Tencent Modifications"). -// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_INTTYPES_H_ // [ -#define _MSC_INTTYPES_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include "stdint.h" - -// miloyip: VC supports inttypes.h since VC2013 -#if _MSC_VER >= 1800 -#include -#else - -// 7.8 Format conversion of integer types - -typedef struct { - intmax_t quot; - intmax_t rem; -} imaxdiv_t; - -// 7.8.1 Macros for format specifiers - -#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 - -// The fprintf macros for signed integers are: -#define PRId8 "d" -#define PRIi8 "i" -#define PRIdLEAST8 "d" -#define PRIiLEAST8 "i" -#define PRIdFAST8 "d" -#define PRIiFAST8 "i" - -#define PRId16 "hd" -#define PRIi16 "hi" -#define PRIdLEAST16 "hd" -#define PRIiLEAST16 "hi" -#define PRIdFAST16 "hd" -#define PRIiFAST16 "hi" - -#define PRId32 "I32d" -#define PRIi32 "I32i" -#define PRIdLEAST32 "I32d" -#define PRIiLEAST32 "I32i" -#define PRIdFAST32 "I32d" -#define PRIiFAST32 "I32i" - -#define PRId64 "I64d" -#define PRIi64 "I64i" -#define PRIdLEAST64 "I64d" -#define PRIiLEAST64 "I64i" -#define PRIdFAST64 "I64d" -#define PRIiFAST64 "I64i" - -#define PRIdMAX "I64d" -#define PRIiMAX "I64i" - -#define PRIdPTR "Id" -#define PRIiPTR "Ii" - -// The fprintf macros for unsigned integers are: -#define PRIo8 "o" -#define PRIu8 "u" -#define PRIx8 "x" -#define PRIX8 "X" -#define PRIoLEAST8 "o" -#define PRIuLEAST8 "u" -#define PRIxLEAST8 "x" -#define PRIXLEAST8 "X" -#define PRIoFAST8 "o" -#define PRIuFAST8 "u" -#define PRIxFAST8 "x" -#define PRIXFAST8 "X" - -#define PRIo16 "ho" -#define PRIu16 "hu" -#define PRIx16 "hx" -#define PRIX16 "hX" -#define PRIoLEAST16 "ho" -#define PRIuLEAST16 "hu" -#define PRIxLEAST16 "hx" -#define PRIXLEAST16 "hX" -#define PRIoFAST16 "ho" -#define PRIuFAST16 "hu" -#define PRIxFAST16 "hx" -#define PRIXFAST16 "hX" - -#define PRIo32 "I32o" -#define PRIu32 "I32u" -#define PRIx32 "I32x" -#define PRIX32 "I32X" -#define PRIoLEAST32 "I32o" -#define PRIuLEAST32 "I32u" -#define PRIxLEAST32 "I32x" -#define PRIXLEAST32 "I32X" -#define PRIoFAST32 "I32o" -#define PRIuFAST32 "I32u" -#define PRIxFAST32 "I32x" -#define PRIXFAST32 "I32X" - -#define PRIo64 "I64o" -#define PRIu64 "I64u" -#define PRIx64 "I64x" -#define PRIX64 "I64X" -#define PRIoLEAST64 "I64o" -#define PRIuLEAST64 "I64u" -#define PRIxLEAST64 "I64x" -#define PRIXLEAST64 "I64X" -#define PRIoFAST64 "I64o" -#define PRIuFAST64 "I64u" -#define PRIxFAST64 "I64x" -#define PRIXFAST64 "I64X" - -#define PRIoMAX "I64o" -#define PRIuMAX "I64u" -#define PRIxMAX "I64x" -#define PRIXMAX "I64X" - -#define PRIoPTR "Io" -#define PRIuPTR "Iu" -#define PRIxPTR "Ix" -#define PRIXPTR "IX" - -// The fscanf macros for signed integers are: -#define SCNd8 "d" -#define SCNi8 "i" -#define SCNdLEAST8 "d" -#define SCNiLEAST8 "i" -#define SCNdFAST8 "d" -#define SCNiFAST8 "i" - -#define SCNd16 "hd" -#define SCNi16 "hi" -#define SCNdLEAST16 "hd" -#define SCNiLEAST16 "hi" -#define SCNdFAST16 "hd" -#define SCNiFAST16 "hi" - -#define SCNd32 "ld" -#define SCNi32 "li" -#define SCNdLEAST32 "ld" -#define SCNiLEAST32 "li" -#define SCNdFAST32 "ld" -#define SCNiFAST32 "li" - -#define SCNd64 "I64d" -#define SCNi64 "I64i" -#define SCNdLEAST64 "I64d" -#define SCNiLEAST64 "I64i" -#define SCNdFAST64 "I64d" -#define SCNiFAST64 "I64i" - -#define SCNdMAX "I64d" -#define SCNiMAX "I64i" - -#ifdef _WIN64 // [ -# define SCNdPTR "I64d" -# define SCNiPTR "I64i" -#else // _WIN64 ][ -# define SCNdPTR "ld" -# define SCNiPTR "li" -#endif // _WIN64 ] - -// The fscanf macros for unsigned integers are: -#define SCNo8 "o" -#define SCNu8 "u" -#define SCNx8 "x" -#define SCNX8 "X" -#define SCNoLEAST8 "o" -#define SCNuLEAST8 "u" -#define SCNxLEAST8 "x" -#define SCNXLEAST8 "X" -#define SCNoFAST8 "o" -#define SCNuFAST8 "u" -#define SCNxFAST8 "x" -#define SCNXFAST8 "X" - -#define SCNo16 "ho" -#define SCNu16 "hu" -#define SCNx16 "hx" -#define SCNX16 "hX" -#define SCNoLEAST16 "ho" -#define SCNuLEAST16 "hu" -#define SCNxLEAST16 "hx" -#define SCNXLEAST16 "hX" -#define SCNoFAST16 "ho" -#define SCNuFAST16 "hu" -#define SCNxFAST16 "hx" -#define SCNXFAST16 "hX" - -#define SCNo32 "lo" -#define SCNu32 "lu" -#define SCNx32 "lx" -#define SCNX32 "lX" -#define SCNoLEAST32 "lo" -#define SCNuLEAST32 "lu" -#define SCNxLEAST32 "lx" -#define SCNXLEAST32 "lX" -#define SCNoFAST32 "lo" -#define SCNuFAST32 "lu" -#define SCNxFAST32 "lx" -#define SCNXFAST32 "lX" - -#define SCNo64 "I64o" -#define SCNu64 "I64u" -#define SCNx64 "I64x" -#define SCNX64 "I64X" -#define SCNoLEAST64 "I64o" -#define SCNuLEAST64 "I64u" -#define SCNxLEAST64 "I64x" -#define SCNXLEAST64 "I64X" -#define SCNoFAST64 "I64o" -#define SCNuFAST64 "I64u" -#define SCNxFAST64 "I64x" -#define SCNXFAST64 "I64X" - -#define SCNoMAX "I64o" -#define SCNuMAX "I64u" -#define SCNxMAX "I64x" -#define SCNXMAX "I64X" - -#ifdef _WIN64 // [ -# define SCNoPTR "I64o" -# define SCNuPTR "I64u" -# define SCNxPTR "I64x" -# define SCNXPTR "I64X" -#else // _WIN64 ][ -# define SCNoPTR "lo" -# define SCNuPTR "lu" -# define SCNxPTR "lx" -# define SCNXPTR "lX" -#endif // _WIN64 ] - -#endif // __STDC_FORMAT_MACROS ] - -// 7.8.2 Functions for greatest-width integer types - -// 7.8.2.1 The imaxabs function -#define imaxabs _abs64 - -// 7.8.2.2 The imaxdiv function - -// This is modified version of div() function from Microsoft's div.c found -// in %MSVC.NET%\crt\src\div.c -#ifdef STATIC_IMAXDIV // [ -static -#else // STATIC_IMAXDIV ][ -_inline -#endif // STATIC_IMAXDIV ] -imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) -{ - imaxdiv_t result; - - result.quot = numer / denom; - result.rem = numer % denom; - - if (numer < 0 && result.rem > 0) { - // did division wrong; must fix up - ++result.quot; - result.rem -= denom; - } - - return result; -} - -// 7.8.2.3 The strtoimax and strtoumax functions -#define strtoimax _strtoi64 -#define strtoumax _strtoui64 - -// 7.8.2.4 The wcstoimax and wcstoumax functions -#define wcstoimax _wcstoi64 -#define wcstoumax _wcstoui64 - -#endif // _MSC_VER >= 1800 - -#endif // _MSC_INTTYPES_H_ ] diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/msinttypes/stdint.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/msinttypes/stdint.h deleted file mode 100644 index 3d4477b9..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/msinttypes/stdint.h +++ /dev/null @@ -1,300 +0,0 @@ -// ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2013 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the product nor the names of its contributors may -// be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////////// - -// The above software in this distribution may have been modified by -// THL A29 Limited ("Tencent Modifications"). -// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_STDINT_H_ // [ -#define _MSC_STDINT_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010. -#if _MSC_VER >= 1600 // [ -#include - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -#undef INT8_C -#undef INT16_C -#undef INT32_C -#undef INT64_C -#undef UINT8_C -#undef UINT16_C -#undef UINT32_C -#undef UINT64_C - -// 7.18.4.1 Macros for minimum-width integer constants - -#define INT8_C(val) val##i8 -#define INT16_C(val) val##i16 -#define INT32_C(val) val##i32 -#define INT64_C(val) val##i64 - -#define UINT8_C(val) val##ui8 -#define UINT16_C(val) val##ui16 -#define UINT32_C(val) val##ui32 -#define UINT64_C(val) val##ui64 - -// 7.18.4.2 Macros for greatest-width integer constants -// These #ifndef's are needed to prevent collisions with . -// Check out Issue 9 for the details. -#ifndef INTMAX_C // [ -# define INTMAX_C INT64_C -#endif // INTMAX_C ] -#ifndef UINTMAX_C // [ -# define UINTMAX_C UINT64_C -#endif // UINTMAX_C ] - -#endif // __STDC_CONSTANT_MACROS ] - -#else // ] _MSC_VER >= 1700 [ - -#include - -// For Visual Studio 6 in C++ mode and for many Visual Studio versions when -// compiling for ARM we have to wrap include with 'extern "C++" {}' -// or compiler would give many errors like this: -// error C2733: second C linkage of overloaded function 'wmemchr' not allowed -#if defined(__cplusplus) && !defined(_M_ARM) -extern "C" { -#endif -# include -#if defined(__cplusplus) && !defined(_M_ARM) -} -#endif - -// Define _W64 macros to mark types changing their size, like intptr_t. -#ifndef _W64 -# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 -# define _W64 __w64 -# else -# define _W64 -# endif -#endif - - -// 7.18.1 Integer types - -// 7.18.1.1 Exact-width integer types - -// Visual Studio 6 and Embedded Visual C++ 4 doesn't -// realize that, e.g. char has the same size as __int8 -// so we give up on __intX for them. -#if (_MSC_VER < 1300) - typedef signed char int8_t; - typedef signed short int16_t; - typedef signed int int32_t; - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; -#else - typedef signed __int8 int8_t; - typedef signed __int16 int16_t; - typedef signed __int32 int32_t; - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; -#endif -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; - - -// 7.18.1.2 Minimum-width integer types -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -// 7.18.1.3 Fastest minimum-width integer types -typedef int8_t int_fast8_t; -typedef int16_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef int64_t int_fast64_t; -typedef uint8_t uint_fast8_t; -typedef uint16_t uint_fast16_t; -typedef uint32_t uint_fast32_t; -typedef uint64_t uint_fast64_t; - -// 7.18.1.4 Integer types capable of holding object pointers -#ifdef _WIN64 // [ - typedef signed __int64 intptr_t; - typedef unsigned __int64 uintptr_t; -#else // _WIN64 ][ - typedef _W64 signed int intptr_t; - typedef _W64 unsigned int uintptr_t; -#endif // _WIN64 ] - -// 7.18.1.5 Greatest-width integer types -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - - -// 7.18.2 Limits of specified-width integer types - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 - -// 7.18.2.1 Limits of exact-width integer types -#define INT8_MIN ((int8_t)_I8_MIN) -#define INT8_MAX _I8_MAX -#define INT16_MIN ((int16_t)_I16_MIN) -#define INT16_MAX _I16_MAX -#define INT32_MIN ((int32_t)_I32_MIN) -#define INT32_MAX _I32_MAX -#define INT64_MIN ((int64_t)_I64_MIN) -#define INT64_MAX _I64_MAX -#define UINT8_MAX _UI8_MAX -#define UINT16_MAX _UI16_MAX -#define UINT32_MAX _UI32_MAX -#define UINT64_MAX _UI64_MAX - -// 7.18.2.2 Limits of minimum-width integer types -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -// 7.18.2.3 Limits of fastest minimum-width integer types -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST16_MIN INT16_MIN -#define INT_FAST16_MAX INT16_MAX -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST16_MAX UINT16_MAX -#define UINT_FAST32_MAX UINT32_MAX -#define UINT_FAST64_MAX UINT64_MAX - -// 7.18.2.4 Limits of integer types capable of holding object pointers -#ifdef _WIN64 // [ -# define INTPTR_MIN INT64_MIN -# define INTPTR_MAX INT64_MAX -# define UINTPTR_MAX UINT64_MAX -#else // _WIN64 ][ -# define INTPTR_MIN INT32_MIN -# define INTPTR_MAX INT32_MAX -# define UINTPTR_MAX UINT32_MAX -#endif // _WIN64 ] - -// 7.18.2.5 Limits of greatest-width integer types -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -// 7.18.3 Limits of other integer types - -#ifdef _WIN64 // [ -# define PTRDIFF_MIN _I64_MIN -# define PTRDIFF_MAX _I64_MAX -#else // _WIN64 ][ -# define PTRDIFF_MIN _I32_MIN -# define PTRDIFF_MAX _I32_MAX -#endif // _WIN64 ] - -#define SIG_ATOMIC_MIN INT_MIN -#define SIG_ATOMIC_MAX INT_MAX - -#ifndef SIZE_MAX // [ -# ifdef _WIN64 // [ -# define SIZE_MAX _UI64_MAX -# else // _WIN64 ][ -# define SIZE_MAX _UI32_MAX -# endif // _WIN64 ] -#endif // SIZE_MAX ] - -// WCHAR_MIN and WCHAR_MAX are also defined in -#ifndef WCHAR_MIN // [ -# define WCHAR_MIN 0 -#endif // WCHAR_MIN ] -#ifndef WCHAR_MAX // [ -# define WCHAR_MAX _UI16_MAX -#endif // WCHAR_MAX ] - -#define WINT_MIN 0 -#define WINT_MAX _UI16_MAX - -#endif // __STDC_LIMIT_MACROS ] - - -// 7.18.4 Limits of other integer types - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -// 7.18.4.1 Macros for minimum-width integer constants - -#define INT8_C(val) val##i8 -#define INT16_C(val) val##i16 -#define INT32_C(val) val##i32 -#define INT64_C(val) val##i64 - -#define UINT8_C(val) val##ui8 -#define UINT16_C(val) val##ui16 -#define UINT32_C(val) val##ui32 -#define UINT64_C(val) val##ui64 - -// 7.18.4.2 Macros for greatest-width integer constants -// These #ifndef's are needed to prevent collisions with . -// Check out Issue 9 for the details. -#ifndef INTMAX_C // [ -# define INTMAX_C INT64_C -#endif // INTMAX_C ] -#ifndef UINTMAX_C // [ -# define UINTMAX_C UINT64_C -#endif // UINTMAX_C ] - -#endif // __STDC_CONSTANT_MACROS ] - -#endif // _MSC_VER >= 1600 ] - -#endif // _MSC_STDINT_H_ ] diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/ostreamwrapper.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/ostreamwrapper.h deleted file mode 100644 index 6f4667c0..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/ostreamwrapper.h +++ /dev/null @@ -1,81 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_OSTREAMWRAPPER_H_ -#define RAPIDJSON_OSTREAMWRAPPER_H_ - -#include "stream.h" -#include - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(padded) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept. -/*! - The classes can be wrapped including but not limited to: - - - \c std::ostringstream - - \c std::stringstream - - \c std::wpstringstream - - \c std::wstringstream - - \c std::ifstream - - \c std::fstream - - \c std::wofstream - - \c std::wfstream - - \tparam StreamType Class derived from \c std::basic_ostream. -*/ - -template -class BasicOStreamWrapper { -public: - typedef typename StreamType::char_type Ch; - BasicOStreamWrapper(StreamType& stream) : stream_(stream) {} - - void Put(Ch c) { - stream_.put(c); - } - - void Flush() { - stream_.flush(); - } - - // Not implemented - char Peek() const { RAPIDJSON_ASSERT(false); return 0; } - char Take() { RAPIDJSON_ASSERT(false); return 0; } - size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } - char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } - -private: - BasicOStreamWrapper(const BasicOStreamWrapper&); - BasicOStreamWrapper& operator=(const BasicOStreamWrapper&); - - StreamType& stream_; -}; - -typedef BasicOStreamWrapper OStreamWrapper; -typedef BasicOStreamWrapper WOStreamWrapper; - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_OSTREAMWRAPPER_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/pointer.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/pointer.h deleted file mode 100644 index b8143b63..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/pointer.h +++ /dev/null @@ -1,1415 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_POINTER_H_ -#define RAPIDJSON_POINTER_H_ - -#include "document.h" -#include "internal/itoa.h" - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(switch-enum) -#elif defined(_MSC_VER) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token - -//! Error code of parsing. -/*! \ingroup RAPIDJSON_ERRORS - \see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode -*/ -enum PointerParseErrorCode { - kPointerParseErrorNone = 0, //!< The parse is successful - - kPointerParseErrorTokenMustBeginWithSolidus, //!< A token must begin with a '/' - kPointerParseErrorInvalidEscape, //!< Invalid escape - kPointerParseErrorInvalidPercentEncoding, //!< Invalid percent encoding in URI fragment - kPointerParseErrorCharacterMustPercentEncode //!< A character must percent encoded in URI fragment -}; - -/////////////////////////////////////////////////////////////////////////////// -// GenericPointer - -//! Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator. -/*! - This class implements RFC 6901 "JavaScript Object Notation (JSON) Pointer" - (https://tools.ietf.org/html/rfc6901). - - A JSON pointer is for identifying a specific value in a JSON document - (GenericDocument). It can simplify coding of DOM tree manipulation, because it - can access multiple-level depth of DOM tree with single API call. - - After it parses a string representation (e.g. "/foo/0" or URI fragment - representation (e.g. "#/foo/0") into its internal representation (tokens), - it can be used to resolve a specific value in multiple documents, or sub-tree - of documents. - - Contrary to GenericValue, Pointer can be copy constructed and copy assigned. - Apart from assignment, a Pointer cannot be modified after construction. - - Although Pointer is very convenient, please aware that constructing Pointer - involves parsing and dynamic memory allocation. A special constructor with user- - supplied tokens eliminates these. - - GenericPointer depends on GenericDocument and GenericValue. - - \tparam ValueType The value type of the DOM tree. E.g. GenericValue > - \tparam Allocator The allocator type for allocating memory for internal representation. - - \note GenericPointer uses same encoding of ValueType. - However, Allocator of GenericPointer is independent of Allocator of Value. -*/ -template -class GenericPointer { -public: - typedef typename ValueType::EncodingType EncodingType; //!< Encoding type from Value - typedef typename ValueType::Ch Ch; //!< Character type from Value - - //! A token is the basic units of internal representation. - /*! - A JSON pointer string representation "/foo/123" is parsed to two tokens: - "foo" and 123. 123 will be represented in both numeric form and string form. - They are resolved according to the actual value type (object or array). - - For token that are not numbers, or the numeric value is out of bound - (greater than limits of SizeType), they are only treated as string form - (i.e. the token's index will be equal to kPointerInvalidIndex). - - This struct is public so that user can create a Pointer without parsing and - allocation, using a special constructor. - */ - struct Token { - const Ch* name; //!< Name of the token. It has null character at the end but it can contain null character. - SizeType length; //!< Length of the name. - SizeType index; //!< A valid array index, if it is not equal to kPointerInvalidIndex. - }; - - //!@name Constructors and destructor. - //@{ - - //! Default constructor. - GenericPointer(Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {} - - //! Constructor that parses a string or URI fragment representation. - /*! - \param source A null-terminated, string or URI fragment representation of JSON pointer. - \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. - */ - explicit GenericPointer(const Ch* source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { - Parse(source, internal::StrLen(source)); - } - -#if RAPIDJSON_HAS_STDSTRING - //! Constructor that parses a string or URI fragment representation. - /*! - \param source A string or URI fragment representation of JSON pointer. - \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. - \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. - */ - explicit GenericPointer(const std::basic_string& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { - Parse(source.c_str(), source.size()); - } -#endif - - //! Constructor that parses a string or URI fragment representation, with length of the source string. - /*! - \param source A string or URI fragment representation of JSON pointer. - \param length Length of source. - \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. - \note Slightly faster than the overload without length. - */ - GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { - Parse(source, length); - } - - //! Constructor with user-supplied tokens. - /*! - This constructor let user supplies const array of tokens. - This prevents the parsing process and eliminates allocation. - This is preferred for memory constrained environments. - - \param tokens An constant array of tokens representing the JSON pointer. - \param tokenCount Number of tokens. - - \b Example - \code - #define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex } - #define INDEX(i) { #i, sizeof(#i) - 1, i } - - static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(123) }; - static const Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0])); - // Equivalent to static const Pointer p("/foo/123"); - - #undef NAME - #undef INDEX - \endcode - */ - GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {} - - //! Copy constructor. - GenericPointer(const GenericPointer& rhs) : allocator_(rhs.allocator_), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { - *this = rhs; - } - - //! Copy constructor. - GenericPointer(const GenericPointer& rhs, Allocator* allocator) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { - *this = rhs; - } - - //! Destructor. - ~GenericPointer() { - if (nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated. - Allocator::Free(tokens_); - RAPIDJSON_DELETE(ownAllocator_); - } - - //! Assignment operator. - GenericPointer& operator=(const GenericPointer& rhs) { - if (this != &rhs) { - // Do not delete ownAllcator - if (nameBuffer_) - Allocator::Free(tokens_); - - tokenCount_ = rhs.tokenCount_; - parseErrorOffset_ = rhs.parseErrorOffset_; - parseErrorCode_ = rhs.parseErrorCode_; - - if (rhs.nameBuffer_) - CopyFromRaw(rhs); // Normally parsed tokens. - else { - tokens_ = rhs.tokens_; // User supplied const tokens. - nameBuffer_ = 0; - } - } - return *this; - } - - //! Swap the content of this pointer with an other. - /*! - \param other The pointer to swap with. - \note Constant complexity. - */ - GenericPointer& Swap(GenericPointer& other) RAPIDJSON_NOEXCEPT { - internal::Swap(allocator_, other.allocator_); - internal::Swap(ownAllocator_, other.ownAllocator_); - internal::Swap(nameBuffer_, other.nameBuffer_); - internal::Swap(tokens_, other.tokens_); - internal::Swap(tokenCount_, other.tokenCount_); - internal::Swap(parseErrorOffset_, other.parseErrorOffset_); - internal::Swap(parseErrorCode_, other.parseErrorCode_); - return *this; - } - - //! free-standing swap function helper - /*! - Helper function to enable support for common swap implementation pattern based on \c std::swap: - \code - void swap(MyClass& a, MyClass& b) { - using std::swap; - swap(a.pointer, b.pointer); - // ... - } - \endcode - \see Swap() - */ - friend inline void swap(GenericPointer& a, GenericPointer& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } - - //@} - - //!@name Append token - //@{ - - //! Append a token and return a new Pointer - /*! - \param token Token to be appended. - \param allocator Allocator for the newly return Pointer. - \return A new Pointer with appended token. - */ - GenericPointer Append(const Token& token, Allocator* allocator = 0) const { - GenericPointer r; - r.allocator_ = allocator; - Ch *p = r.CopyFromRaw(*this, 1, token.length + 1); - std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch)); - r.tokens_[tokenCount_].name = p; - r.tokens_[tokenCount_].length = token.length; - r.tokens_[tokenCount_].index = token.index; - return r; - } - - //! Append a name token with length, and return a new Pointer - /*! - \param name Name to be appended. - \param length Length of name. - \param allocator Allocator for the newly return Pointer. - \return A new Pointer with appended token. - */ - GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const { - Token token = { name, length, kPointerInvalidIndex }; - return Append(token, allocator); - } - - //! Append a name token without length, and return a new Pointer - /*! - \param name Name (const Ch*) to be appended. - \param allocator Allocator for the newly return Pointer. - \return A new Pointer with appended token. - */ - template - RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >), (GenericPointer)) - Append(T* name, Allocator* allocator = 0) const { - return Append(name, internal::StrLen(name), allocator); - } - -#if RAPIDJSON_HAS_STDSTRING - //! Append a name token, and return a new Pointer - /*! - \param name Name to be appended. - \param allocator Allocator for the newly return Pointer. - \return A new Pointer with appended token. - */ - GenericPointer Append(const std::basic_string& name, Allocator* allocator = 0) const { - return Append(name.c_str(), static_cast(name.size()), allocator); - } -#endif - - //! Append a index token, and return a new Pointer - /*! - \param index Index to be appended. - \param allocator Allocator for the newly return Pointer. - \return A new Pointer with appended token. - */ - GenericPointer Append(SizeType index, Allocator* allocator = 0) const { - char buffer[21]; - char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer); - SizeType length = static_cast(end - buffer); - buffer[length] = '\0'; - - if (sizeof(Ch) == 1) { - Token token = { reinterpret_cast(buffer), length, index }; - return Append(token, allocator); - } - else { - Ch name[21]; - for (size_t i = 0; i <= length; i++) - name[i] = static_cast(buffer[i]); - Token token = { name, length, index }; - return Append(token, allocator); - } - } - - //! Append a token by value, and return a new Pointer - /*! - \param token token to be appended. - \param allocator Allocator for the newly return Pointer. - \return A new Pointer with appended token. - */ - GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const { - if (token.IsString()) - return Append(token.GetString(), token.GetStringLength(), allocator); - else { - RAPIDJSON_ASSERT(token.IsUint64()); - RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0)); - return Append(static_cast(token.GetUint64()), allocator); - } - } - - //!@name Handling Parse Error - //@{ - - //! Check whether this is a valid pointer. - bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; } - - //! Get the parsing error offset in code unit. - size_t GetParseErrorOffset() const { return parseErrorOffset_; } - - //! Get the parsing error code. - PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; } - - //@} - - //! Get the allocator of this pointer. - Allocator& GetAllocator() { return *allocator_; } - - //!@name Tokens - //@{ - - //! Get the token array (const version only). - const Token* GetTokens() const { return tokens_; } - - //! Get the number of tokens. - size_t GetTokenCount() const { return tokenCount_; } - - //@} - - //!@name Equality/inequality operators - //@{ - - //! Equality operator. - /*! - \note When any pointers are invalid, always returns false. - */ - bool operator==(const GenericPointer& rhs) const { - if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_) - return false; - - for (size_t i = 0; i < tokenCount_; i++) { - if (tokens_[i].index != rhs.tokens_[i].index || - tokens_[i].length != rhs.tokens_[i].length || - (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0)) - { - return false; - } - } - - return true; - } - - //! Inequality operator. - /*! - \note When any pointers are invalid, always returns true. - */ - bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); } - - //! Less than operator. - /*! - \note Invalid pointers are always greater than valid ones. - */ - bool operator<(const GenericPointer& rhs) const { - if (!IsValid()) - return false; - if (!rhs.IsValid()) - return true; - - if (tokenCount_ != rhs.tokenCount_) - return tokenCount_ < rhs.tokenCount_; - - for (size_t i = 0; i < tokenCount_; i++) { - if (tokens_[i].index != rhs.tokens_[i].index) - return tokens_[i].index < rhs.tokens_[i].index; - - if (tokens_[i].length != rhs.tokens_[i].length) - return tokens_[i].length < rhs.tokens_[i].length; - - if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length)) - return cmp < 0; - } - - return false; - } - - //@} - - //!@name Stringify - //@{ - - //! Stringify the pointer into string representation. - /*! - \tparam OutputStream Type of output stream. - \param os The output stream. - */ - template - bool Stringify(OutputStream& os) const { - return Stringify(os); - } - - //! Stringify the pointer into URI fragment representation. - /*! - \tparam OutputStream Type of output stream. - \param os The output stream. - */ - template - bool StringifyUriFragment(OutputStream& os) const { - return Stringify(os); - } - - //@} - - //!@name Create value - //@{ - - //! Create a value in a subtree. - /*! - If the value is not exist, it creates all parent values and a JSON Null value. - So it always succeed and return the newly created or existing value. - - Remind that it may change types of parents according to tokens, so it - potentially removes previously stored values. For example, if a document - was an array, and "/foo" is used to create a value, then the document - will be changed to an object, and all existing array elements are lost. - - \param root Root value of a DOM subtree to be resolved. It can be any value other than document root. - \param allocator Allocator for creating the values if the specified value or its parents are not exist. - \param alreadyExist If non-null, it stores whether the resolved value is already exist. - \return The resolved newly created (a JSON Null value), or already exists value. - */ - ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const { - RAPIDJSON_ASSERT(IsValid()); - ValueType* v = &root; - bool exist = true; - for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { - if (v->IsArray() && t->name[0] == '-' && t->length == 1) { - v->PushBack(ValueType().Move(), allocator); - v = &((*v)[v->Size() - 1]); - exist = false; - } - else { - if (t->index == kPointerInvalidIndex) { // must be object name - if (!v->IsObject()) - v->SetObject(); // Change to Object - } - else { // object name or array index - if (!v->IsArray() && !v->IsObject()) - v->SetArray(); // Change to Array - } - - if (v->IsArray()) { - if (t->index >= v->Size()) { - v->Reserve(t->index + 1, allocator); - while (t->index >= v->Size()) - v->PushBack(ValueType().Move(), allocator); - exist = false; - } - v = &((*v)[t->index]); - } - else { - typename ValueType::MemberIterator m = v->FindMember(GenericValue(GenericStringRef(t->name, t->length))); - if (m == v->MemberEnd()) { - v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator); - m = v->MemberEnd(); - v = &(--m)->value; // Assumes AddMember() appends at the end - exist = false; - } - else - v = &m->value; - } - } - } - - if (alreadyExist) - *alreadyExist = exist; - - return *v; - } - - //! Creates a value in a document. - /*! - \param document A document to be resolved. - \param alreadyExist If non-null, it stores whether the resolved value is already exist. - \return The resolved newly created, or already exists value. - */ - template - ValueType& Create(GenericDocument& document, bool* alreadyExist = 0) const { - return Create(document, document.GetAllocator(), alreadyExist); - } - - //@} - - //!@name Query value - //@{ - - //! Query a value in a subtree. - /*! - \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. - \param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token. - \return Pointer to the value if it can be resolved. Otherwise null. - - \note - There are only 3 situations when a value cannot be resolved: - 1. A value in the path is not an array nor object. - 2. An object value does not contain the token. - 3. A token is out of range of an array value. - - Use unresolvedTokenIndex to retrieve the token index. - */ - ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const { - RAPIDJSON_ASSERT(IsValid()); - ValueType* v = &root; - for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { - switch (v->GetType()) { - case kObjectType: - { - typename ValueType::MemberIterator m = v->FindMember(GenericValue(GenericStringRef(t->name, t->length))); - if (m == v->MemberEnd()) - break; - v = &m->value; - } - continue; - case kArrayType: - if (t->index == kPointerInvalidIndex || t->index >= v->Size()) - break; - v = &((*v)[t->index]); - continue; - default: - break; - } - - // Error: unresolved token - if (unresolvedTokenIndex) - *unresolvedTokenIndex = static_cast(t - tokens_); - return 0; - } - return v; - } - - //! Query a const value in a const subtree. - /*! - \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. - \return Pointer to the value if it can be resolved. Otherwise null. - */ - const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const { - return Get(const_cast(root), unresolvedTokenIndex); - } - - //@} - - //!@name Query a value with default - //@{ - - //! Query a value in a subtree with default value. - /*! - Similar to Get(), but if the specified value do not exists, it creates all parents and clone the default value. - So that this function always succeed. - - \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. - \param defaultValue Default value to be cloned if the value was not exists. - \param allocator Allocator for creating the values if the specified value or its parents are not exist. - \see Create() - */ - ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const { - bool alreadyExist; - ValueType& v = Create(root, allocator, &alreadyExist); - return alreadyExist ? v : v.CopyFrom(defaultValue, allocator); - } - - //! Query a value in a subtree with default null-terminated string. - ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const { - bool alreadyExist; - ValueType& v = Create(root, allocator, &alreadyExist); - return alreadyExist ? v : v.SetString(defaultValue, allocator); - } - -#if RAPIDJSON_HAS_STDSTRING - //! Query a value in a subtree with default std::basic_string. - ValueType& GetWithDefault(ValueType& root, const std::basic_string& defaultValue, typename ValueType::AllocatorType& allocator) const { - bool alreadyExist; - ValueType& v = Create(root, allocator, &alreadyExist); - return alreadyExist ? v : v.SetString(defaultValue, allocator); - } -#endif - - //! Query a value in a subtree with default primitive value. - /*! - \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool - */ - template - RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) - GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const { - return GetWithDefault(root, ValueType(defaultValue).Move(), allocator); - } - - //! Query a value in a document with default value. - template - ValueType& GetWithDefault(GenericDocument& document, const ValueType& defaultValue) const { - return GetWithDefault(document, defaultValue, document.GetAllocator()); - } - - //! Query a value in a document with default null-terminated string. - template - ValueType& GetWithDefault(GenericDocument& document, const Ch* defaultValue) const { - return GetWithDefault(document, defaultValue, document.GetAllocator()); - } - -#if RAPIDJSON_HAS_STDSTRING - //! Query a value in a document with default std::basic_string. - template - ValueType& GetWithDefault(GenericDocument& document, const std::basic_string& defaultValue) const { - return GetWithDefault(document, defaultValue, document.GetAllocator()); - } -#endif - - //! Query a value in a document with default primitive value. - /*! - \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool - */ - template - RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) - GetWithDefault(GenericDocument& document, T defaultValue) const { - return GetWithDefault(document, defaultValue, document.GetAllocator()); - } - - //@} - - //!@name Set a value - //@{ - - //! Set a value in a subtree, with move semantics. - /*! - It creates all parents if they are not exist or types are different to the tokens. - So this function always succeeds but potentially remove existing values. - - \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. - \param value Value to be set. - \param allocator Allocator for creating the values if the specified value or its parents are not exist. - \see Create() - */ - ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const { - return Create(root, allocator) = value; - } - - //! Set a value in a subtree, with copy semantics. - ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const { - return Create(root, allocator).CopyFrom(value, allocator); - } - - //! Set a null-terminated string in a subtree. - ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const { - return Create(root, allocator) = ValueType(value, allocator).Move(); - } - -#if RAPIDJSON_HAS_STDSTRING - //! Set a std::basic_string in a subtree. - ValueType& Set(ValueType& root, const std::basic_string& value, typename ValueType::AllocatorType& allocator) const { - return Create(root, allocator) = ValueType(value, allocator).Move(); - } -#endif - - //! Set a primitive value in a subtree. - /*! - \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool - */ - template - RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) - Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const { - return Create(root, allocator) = ValueType(value).Move(); - } - - //! Set a value in a document, with move semantics. - template - ValueType& Set(GenericDocument& document, ValueType& value) const { - return Create(document) = value; - } - - //! Set a value in a document, with copy semantics. - template - ValueType& Set(GenericDocument& document, const ValueType& value) const { - return Create(document).CopyFrom(value, document.GetAllocator()); - } - - //! Set a null-terminated string in a document. - template - ValueType& Set(GenericDocument& document, const Ch* value) const { - return Create(document) = ValueType(value, document.GetAllocator()).Move(); - } - -#if RAPIDJSON_HAS_STDSTRING - //! Sets a std::basic_string in a document. - template - ValueType& Set(GenericDocument& document, const std::basic_string& value) const { - return Create(document) = ValueType(value, document.GetAllocator()).Move(); - } -#endif - - //! Set a primitive value in a document. - /*! - \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool - */ - template - RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) - Set(GenericDocument& document, T value) const { - return Create(document) = value; - } - - //@} - - //!@name Swap a value - //@{ - - //! Swap a value with a value in a subtree. - /*! - It creates all parents if they are not exist or types are different to the tokens. - So this function always succeeds but potentially remove existing values. - - \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. - \param value Value to be swapped. - \param allocator Allocator for creating the values if the specified value or its parents are not exist. - \see Create() - */ - ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const { - return Create(root, allocator).Swap(value); - } - - //! Swap a value with a value in a document. - template - ValueType& Swap(GenericDocument& document, ValueType& value) const { - return Create(document).Swap(value); - } - - //@} - - //! Erase a value in a subtree. - /*! - \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. - \return Whether the resolved value is found and erased. - - \note Erasing with an empty pointer \c Pointer(""), i.e. the root, always fail and return false. - */ - bool Erase(ValueType& root) const { - RAPIDJSON_ASSERT(IsValid()); - if (tokenCount_ == 0) // Cannot erase the root - return false; - - ValueType* v = &root; - const Token* last = tokens_ + (tokenCount_ - 1); - for (const Token *t = tokens_; t != last; ++t) { - switch (v->GetType()) { - case kObjectType: - { - typename ValueType::MemberIterator m = v->FindMember(GenericValue(GenericStringRef(t->name, t->length))); - if (m == v->MemberEnd()) - return false; - v = &m->value; - } - break; - case kArrayType: - if (t->index == kPointerInvalidIndex || t->index >= v->Size()) - return false; - v = &((*v)[t->index]); - break; - default: - return false; - } - } - - switch (v->GetType()) { - case kObjectType: - return v->EraseMember(GenericStringRef(last->name, last->length)); - case kArrayType: - if (last->index == kPointerInvalidIndex || last->index >= v->Size()) - return false; - v->Erase(v->Begin() + last->index); - return true; - default: - return false; - } - } - -private: - //! Clone the content from rhs to this. - /*! - \param rhs Source pointer. - \param extraToken Extra tokens to be allocated. - \param extraNameBufferSize Extra name buffer size (in number of Ch) to be allocated. - \return Start of non-occupied name buffer, for storing extra names. - */ - Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) { - if (!allocator_) // allocator is independently owned. - ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); - - size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens - for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t) - nameBufferSize += t->length; - - tokenCount_ = rhs.tokenCount_ + extraToken; - tokens_ = static_cast(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch))); - nameBuffer_ = reinterpret_cast(tokens_ + tokenCount_); - if (rhs.tokenCount_ > 0) { - std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token)); - } - if (nameBufferSize > 0) { - std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch)); - } - - // Adjust pointers to name buffer - std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_; - for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t) - t->name += diff; - - return nameBuffer_ + nameBufferSize; - } - - //! Check whether a character should be percent-encoded. - /*! - According to RFC 3986 2.3 Unreserved Characters. - \param c The character (code unit) to be tested. - */ - bool NeedPercentEncode(Ch c) const { - return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~'); - } - - //! Parse a JSON String or its URI fragment representation into tokens. -#ifndef __clang__ // -Wdocumentation - /*! - \param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated. - \param length Length of the source string. - \note Source cannot be JSON String Representation of JSON Pointer, e.g. In "/\u0000", \u0000 will not be unescaped. - */ -#endif - void Parse(const Ch* source, size_t length) { - RAPIDJSON_ASSERT(source != NULL); - RAPIDJSON_ASSERT(nameBuffer_ == 0); - RAPIDJSON_ASSERT(tokens_ == 0); - - // Create own allocator if user did not supply. - if (!allocator_) - ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); - - // Count number of '/' as tokenCount - tokenCount_ = 0; - for (const Ch* s = source; s != source + length; s++) - if (*s == '/') - tokenCount_++; - - Token* token = tokens_ = static_cast(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch))); - Ch* name = nameBuffer_ = reinterpret_cast(tokens_ + tokenCount_); - size_t i = 0; - - // Detect if it is a URI fragment - bool uriFragment = false; - if (source[i] == '#') { - uriFragment = true; - i++; - } - - if (i != length && source[i] != '/') { - parseErrorCode_ = kPointerParseErrorTokenMustBeginWithSolidus; - goto error; - } - - while (i < length) { - RAPIDJSON_ASSERT(source[i] == '/'); - i++; // consumes '/' - - token->name = name; - bool isNumber = true; - - while (i < length && source[i] != '/') { - Ch c = source[i]; - if (uriFragment) { - // Decoding percent-encoding for URI fragment - if (c == '%') { - PercentDecodeStream is(&source[i], source + length); - GenericInsituStringStream os(name); - Ch* begin = os.PutBegin(); - if (!Transcoder, EncodingType>().Validate(is, os) || !is.IsValid()) { - parseErrorCode_ = kPointerParseErrorInvalidPercentEncoding; - goto error; - } - size_t len = os.PutEnd(begin); - i += is.Tell() - 1; - if (len == 1) - c = *name; - else { - name += len; - isNumber = false; - i++; - continue; - } - } - else if (NeedPercentEncode(c)) { - parseErrorCode_ = kPointerParseErrorCharacterMustPercentEncode; - goto error; - } - } - - i++; - - // Escaping "~0" -> '~', "~1" -> '/' - if (c == '~') { - if (i < length) { - c = source[i]; - if (c == '0') c = '~'; - else if (c == '1') c = '/'; - else { - parseErrorCode_ = kPointerParseErrorInvalidEscape; - goto error; - } - i++; - } - else { - parseErrorCode_ = kPointerParseErrorInvalidEscape; - goto error; - } - } - - // First check for index: all of characters are digit - if (c < '0' || c > '9') - isNumber = false; - - *name++ = c; - } - token->length = static_cast(name - token->name); - if (token->length == 0) - isNumber = false; - *name++ = '\0'; // Null terminator - - // Second check for index: more than one digit cannot have leading zero - if (isNumber && token->length > 1 && token->name[0] == '0') - isNumber = false; - - // String to SizeType conversion - SizeType n = 0; - if (isNumber) { - for (size_t j = 0; j < token->length; j++) { - SizeType m = n * 10 + static_cast(token->name[j] - '0'); - if (m < n) { // overflow detection - isNumber = false; - break; - } - n = m; - } - } - - token->index = isNumber ? n : kPointerInvalidIndex; - token++; - } - - RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer - parseErrorCode_ = kPointerParseErrorNone; - return; - - error: - Allocator::Free(tokens_); - nameBuffer_ = 0; - tokens_ = 0; - tokenCount_ = 0; - parseErrorOffset_ = i; - return; - } - - //! Stringify to string or URI fragment representation. - /*! - \tparam uriFragment True for stringifying to URI fragment representation. False for string representation. - \tparam OutputStream type of output stream. - \param os The output stream. - */ - template - bool Stringify(OutputStream& os) const { - RAPIDJSON_ASSERT(IsValid()); - - if (uriFragment) - os.Put('#'); - - for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { - os.Put('/'); - for (size_t j = 0; j < t->length; j++) { - Ch c = t->name[j]; - if (c == '~') { - os.Put('~'); - os.Put('0'); - } - else if (c == '/') { - os.Put('~'); - os.Put('1'); - } - else if (uriFragment && NeedPercentEncode(c)) { - // Transcode to UTF8 sequence - GenericStringStream source(&t->name[j]); - PercentEncodeStream target(os); - if (!Transcoder >().Validate(source, target)) - return false; - j += source.Tell() - 1; - } - else - os.Put(c); - } - } - return true; - } - - //! A helper stream for decoding a percent-encoded sequence into code unit. - /*! - This stream decodes %XY triplet into code unit (0-255). - If it encounters invalid characters, it sets output code unit as 0 and - mark invalid, and to be checked by IsValid(). - */ - class PercentDecodeStream { - public: - typedef typename ValueType::Ch Ch; - - //! Constructor - /*! - \param source Start of the stream - \param end Past-the-end of the stream. - */ - PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {} - - Ch Take() { - if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet - valid_ = false; - return 0; - } - src_++; - Ch c = 0; - for (int j = 0; j < 2; j++) { - c = static_cast(c << 4); - Ch h = *src_; - if (h >= '0' && h <= '9') c = static_cast(c + h - '0'); - else if (h >= 'A' && h <= 'F') c = static_cast(c + h - 'A' + 10); - else if (h >= 'a' && h <= 'f') c = static_cast(c + h - 'a' + 10); - else { - valid_ = false; - return 0; - } - src_++; - } - return c; - } - - size_t Tell() const { return static_cast(src_ - head_); } - bool IsValid() const { return valid_; } - - private: - const Ch* src_; //!< Current read position. - const Ch* head_; //!< Original head of the string. - const Ch* end_; //!< Past-the-end position. - bool valid_; //!< Whether the parsing is valid. - }; - - //! A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence. - template - class PercentEncodeStream { - public: - PercentEncodeStream(OutputStream& os) : os_(os) {} - void Put(char c) { // UTF-8 must be byte - unsigned char u = static_cast(c); - static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - os_.Put('%'); - os_.Put(static_cast(hexDigits[u >> 4])); - os_.Put(static_cast(hexDigits[u & 15])); - } - private: - OutputStream& os_; - }; - - Allocator* allocator_; //!< The current allocator. It is either user-supplied or equal to ownAllocator_. - Allocator* ownAllocator_; //!< Allocator owned by this Pointer. - Ch* nameBuffer_; //!< A buffer containing all names in tokens. - Token* tokens_; //!< A list of tokens. - size_t tokenCount_; //!< Number of tokens in tokens_. - size_t parseErrorOffset_; //!< Offset in code unit when parsing fail. - PointerParseErrorCode parseErrorCode_; //!< Parsing error code. -}; - -//! GenericPointer for Value (UTF-8, default allocator). -typedef GenericPointer Pointer; - -//!@name Helper functions for GenericPointer -//@{ - -////////////////////////////////////////////////////////////////////////////// - -template -typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer& pointer, typename T::AllocatorType& a) { - return pointer.Create(root, a); -} - -template -typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) { - return GenericPointer(source, N - 1).Create(root, a); -} - -// No allocator parameter - -template -typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer& pointer) { - return pointer.Create(document); -} - -template -typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) { - return GenericPointer(source, N - 1).Create(document); -} - -////////////////////////////////////////////////////////////////////////////// - -template -typename T::ValueType* GetValueByPointer(T& root, const GenericPointer& pointer, size_t* unresolvedTokenIndex = 0) { - return pointer.Get(root, unresolvedTokenIndex); -} - -template -const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer& pointer, size_t* unresolvedTokenIndex = 0) { - return pointer.Get(root, unresolvedTokenIndex); -} - -template -typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) { - return GenericPointer(source, N - 1).Get(root, unresolvedTokenIndex); -} - -template -const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) { - return GenericPointer(source, N - 1).Get(root, unresolvedTokenIndex); -} - -////////////////////////////////////////////////////////////////////////////// - -template -typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) { - return pointer.GetWithDefault(root, defaultValue, a); -} - -template -typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) { - return pointer.GetWithDefault(root, defaultValue, a); -} - -#if RAPIDJSON_HAS_STDSTRING -template -typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const std::basic_string& defaultValue, typename T::AllocatorType& a) { - return pointer.GetWithDefault(root, defaultValue, a); -} -#endif - -template -RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) -GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, T2 defaultValue, typename T::AllocatorType& a) { - return pointer.GetWithDefault(root, defaultValue, a); -} - -template -typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) { - return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); -} - -template -typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) { - return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); -} - -#if RAPIDJSON_HAS_STDSTRING -template -typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string& defaultValue, typename T::AllocatorType& a) { - return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); -} -#endif - -template -RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) -GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) { - return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); -} - -// No allocator parameter - -template -typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::ValueType& defaultValue) { - return pointer.GetWithDefault(document, defaultValue); -} - -template -typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::Ch* defaultValue) { - return pointer.GetWithDefault(document, defaultValue); -} - -#if RAPIDJSON_HAS_STDSTRING -template -typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const std::basic_string& defaultValue) { - return pointer.GetWithDefault(document, defaultValue); -} -#endif - -template -RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) -GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, T2 defaultValue) { - return pointer.GetWithDefault(document, defaultValue); -} - -template -typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) { - return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); -} - -template -typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) { - return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); -} - -#if RAPIDJSON_HAS_STDSTRING -template -typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string& defaultValue) { - return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); -} -#endif - -template -RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) -GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) { - return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); -} - -////////////////////////////////////////////////////////////////////////////// - -template -typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, typename T::ValueType& value, typename T::AllocatorType& a) { - return pointer.Set(root, value, a); -} - -template -typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) { - return pointer.Set(root, value, a); -} - -template -typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const typename T::Ch* value, typename T::AllocatorType& a) { - return pointer.Set(root, value, a); -} - -#if RAPIDJSON_HAS_STDSTRING -template -typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const std::basic_string& value, typename T::AllocatorType& a) { - return pointer.Set(root, value, a); -} -#endif - -template -RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) -SetValueByPointer(T& root, const GenericPointer& pointer, T2 value, typename T::AllocatorType& a) { - return pointer.Set(root, value, a); -} - -template -typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) { - return GenericPointer(source, N - 1).Set(root, value, a); -} - -template -typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) { - return GenericPointer(source, N - 1).Set(root, value, a); -} - -template -typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) { - return GenericPointer(source, N - 1).Set(root, value, a); -} - -#if RAPIDJSON_HAS_STDSTRING -template -typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string& value, typename T::AllocatorType& a) { - return GenericPointer(source, N - 1).Set(root, value, a); -} -#endif - -template -RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) -SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) { - return GenericPointer(source, N - 1).Set(root, value, a); -} - -// No allocator parameter - -template -typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, typename DocumentType::ValueType& value) { - return pointer.Set(document, value); -} - -template -typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::ValueType& value) { - return pointer.Set(document, value); -} - -template -typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::Ch* value) { - return pointer.Set(document, value); -} - -#if RAPIDJSON_HAS_STDSTRING -template -typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const std::basic_string& value) { - return pointer.Set(document, value); -} -#endif - -template -RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) -SetValueByPointer(DocumentType& document, const GenericPointer& pointer, T2 value) { - return pointer.Set(document, value); -} - -template -typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) { - return GenericPointer(source, N - 1).Set(document, value); -} - -template -typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) { - return GenericPointer(source, N - 1).Set(document, value); -} - -template -typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) { - return GenericPointer(source, N - 1).Set(document, value); -} - -#if RAPIDJSON_HAS_STDSTRING -template -typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string& value) { - return GenericPointer(source, N - 1).Set(document, value); -} -#endif - -template -RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) -SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) { - return GenericPointer(source, N - 1).Set(document, value); -} - -////////////////////////////////////////////////////////////////////////////// - -template -typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer& pointer, typename T::ValueType& value, typename T::AllocatorType& a) { - return pointer.Swap(root, value, a); -} - -template -typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) { - return GenericPointer(source, N - 1).Swap(root, value, a); -} - -template -typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer& pointer, typename DocumentType::ValueType& value) { - return pointer.Swap(document, value); -} - -template -typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) { - return GenericPointer(source, N - 1).Swap(document, value); -} - -////////////////////////////////////////////////////////////////////////////// - -template -bool EraseValueByPointer(T& root, const GenericPointer& pointer) { - return pointer.Erase(root); -} - -template -bool EraseValueByPointer(T& root, const CharType(&source)[N]) { - return GenericPointer(source, N - 1).Erase(root); -} - -//@} - -RAPIDJSON_NAMESPACE_END - -#if defined(__clang__) || defined(_MSC_VER) -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_POINTER_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/prettywriter.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/prettywriter.h deleted file mode 100644 index 94eeb69d..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/prettywriter.h +++ /dev/null @@ -1,277 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_PRETTYWRITER_H_ -#define RAPIDJSON_PRETTYWRITER_H_ - -#include "writer.h" - -#ifdef __GNUC__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(effc++) -#endif - -#if defined(__clang__) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(c++98-compat) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! Combination of PrettyWriter format flags. -/*! \see PrettyWriter::SetFormatOptions - */ -enum PrettyFormatOptions { - kFormatDefault = 0, //!< Default pretty formatting. - kFormatSingleLineArray = 1 //!< Format arrays on a single line. -}; - -//! Writer with indentation and spacing. -/*! - \tparam OutputStream Type of output os. - \tparam SourceEncoding Encoding of source string. - \tparam TargetEncoding Encoding of output stream. - \tparam StackAllocator Type of allocator for allocating memory of stack. -*/ -template, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags> -class PrettyWriter : public Writer { -public: - typedef Writer Base; - typedef typename Base::Ch Ch; - - //! Constructor - /*! \param os Output stream. - \param allocator User supplied allocator. If it is null, it will create a private one. - \param levelDepth Initial capacity of stack. - */ - explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : - Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {} - - - explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : - Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {} - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - PrettyWriter(PrettyWriter&& rhs) : - Base(std::forward(rhs)), indentChar_(rhs.indentChar_), indentCharCount_(rhs.indentCharCount_), formatOptions_(rhs.formatOptions_) {} -#endif - - //! Set custom indentation. - /*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r'). - \param indentCharCount Number of indent characters for each indentation level. - \note The default indentation is 4 spaces. - */ - PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) { - RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r'); - indentChar_ = indentChar; - indentCharCount_ = indentCharCount; - return *this; - } - - //! Set pretty writer formatting options. - /*! \param options Formatting options. - */ - PrettyWriter& SetFormatOptions(PrettyFormatOptions options) { - formatOptions_ = options; - return *this; - } - - /*! @name Implementation of Handler - \see Handler - */ - //@{ - - bool Null() { PrettyPrefix(kNullType); return Base::EndValue(Base::WriteNull()); } - bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::EndValue(Base::WriteBool(b)); } - bool Int(int i) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt(i)); } - bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint(u)); } - bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt64(i64)); } - bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint64(u64)); } - bool Double(double d) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteDouble(d)); } - - bool RawNumber(const Ch* str, SizeType length, bool copy = false) { - RAPIDJSON_ASSERT(str != 0); - (void)copy; - PrettyPrefix(kNumberType); - return Base::EndValue(Base::WriteString(str, length)); - } - - bool String(const Ch* str, SizeType length, bool copy = false) { - RAPIDJSON_ASSERT(str != 0); - (void)copy; - PrettyPrefix(kStringType); - return Base::EndValue(Base::WriteString(str, length)); - } - -#if RAPIDJSON_HAS_STDSTRING - bool String(const std::basic_string& str) { - return String(str.data(), SizeType(str.size())); - } -#endif - - bool StartObject() { - PrettyPrefix(kObjectType); - new (Base::level_stack_.template Push()) typename Base::Level(false); - return Base::WriteStartObject(); - } - - bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } - -#if RAPIDJSON_HAS_STDSTRING - bool Key(const std::basic_string& str) { - return Key(str.data(), SizeType(str.size())); - } -#endif - - bool EndObject(SizeType memberCount = 0) { - (void)memberCount; - RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); // not inside an Object - RAPIDJSON_ASSERT(!Base::level_stack_.template Top()->inArray); // currently inside an Array, not Object - RAPIDJSON_ASSERT(0 == Base::level_stack_.template Top()->valueCount % 2); // Object has a Key without a Value - - bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; - - if (!empty) { - Base::os_->Put('\n'); - WriteIndent(); - } - bool ret = Base::EndValue(Base::WriteEndObject()); - (void)ret; - RAPIDJSON_ASSERT(ret == true); - if (Base::level_stack_.Empty()) // end of json text - Base::Flush(); - return true; - } - - bool StartArray() { - PrettyPrefix(kArrayType); - new (Base::level_stack_.template Push()) typename Base::Level(true); - return Base::WriteStartArray(); - } - - bool EndArray(SizeType memberCount = 0) { - (void)memberCount; - RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); - RAPIDJSON_ASSERT(Base::level_stack_.template Top()->inArray); - bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; - - if (!empty && !(formatOptions_ & kFormatSingleLineArray)) { - Base::os_->Put('\n'); - WriteIndent(); - } - bool ret = Base::EndValue(Base::WriteEndArray()); - (void)ret; - RAPIDJSON_ASSERT(ret == true); - if (Base::level_stack_.Empty()) // end of json text - Base::Flush(); - return true; - } - - //@} - - /*! @name Convenience extensions */ - //@{ - - //! Simpler but slower overload. - bool String(const Ch* str) { return String(str, internal::StrLen(str)); } - bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } - - //@} - - //! Write a raw JSON value. - /*! - For user to write a stringified JSON as a value. - - \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range. - \param length Length of the json. - \param type Type of the root of json. - \note When using PrettyWriter::RawValue(), the result json may not be indented correctly. - */ - bool RawValue(const Ch* json, size_t length, Type type) { - RAPIDJSON_ASSERT(json != 0); - PrettyPrefix(type); - return Base::EndValue(Base::WriteRawValue(json, length)); - } - -protected: - void PrettyPrefix(Type type) { - (void)type; - if (Base::level_stack_.GetSize() != 0) { // this value is not at root - typename Base::Level* level = Base::level_stack_.template Top(); - - if (level->inArray) { - if (level->valueCount > 0) { - Base::os_->Put(','); // add comma if it is not the first element in array - if (formatOptions_ & kFormatSingleLineArray) - Base::os_->Put(' '); - } - - if (!(formatOptions_ & kFormatSingleLineArray)) { - Base::os_->Put('\n'); - WriteIndent(); - } - } - else { // in object - if (level->valueCount > 0) { - if (level->valueCount % 2 == 0) { - Base::os_->Put(','); - Base::os_->Put('\n'); - } - else { - Base::os_->Put(':'); - Base::os_->Put(' '); - } - } - else - Base::os_->Put('\n'); - - if (level->valueCount % 2 == 0) - WriteIndent(); - } - if (!level->inArray && level->valueCount % 2 == 0) - RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name - level->valueCount++; - } - else { - RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root. - Base::hasRoot_ = true; - } - } - - void WriteIndent() { - size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_; - PutN(*Base::os_, static_cast(indentChar_), count); - } - - Ch indentChar_; - unsigned indentCharCount_; - PrettyFormatOptions formatOptions_; - -private: - // Prohibit copy constructor & assignment operator. - PrettyWriter(const PrettyWriter&); - PrettyWriter& operator=(const PrettyWriter&); -}; - -RAPIDJSON_NAMESPACE_END - -#if defined(__clang__) -RAPIDJSON_DIAG_POP -#endif - -#ifdef __GNUC__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/rapidjson.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/rapidjson.h deleted file mode 100644 index c5f4d65f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/rapidjson.h +++ /dev/null @@ -1,692 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_RAPIDJSON_H_ -#define RAPIDJSON_RAPIDJSON_H_ - -/*!\file rapidjson.h - \brief common definitions and configuration - - \see RAPIDJSON_CONFIG - */ - -/*! \defgroup RAPIDJSON_CONFIG RapidJSON configuration - \brief Configuration macros for library features - - Some RapidJSON features are configurable to adapt the library to a wide - variety of platforms, environments and usage scenarios. Most of the - features can be configured in terms of overridden or predefined - preprocessor macros at compile-time. - - Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs. - - \note These macros should be given on the compiler command-line - (where applicable) to avoid inconsistent values when compiling - different translation units of a single application. - */ - -#include // malloc(), realloc(), free(), size_t -#include // memset(), memcpy(), memmove(), memcmp() - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_VERSION_STRING -// -// ALWAYS synchronize the following 3 macros with corresponding variables in /CMakeLists.txt. -// - -//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN -// token stringification -#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x) -#define RAPIDJSON_DO_STRINGIFY(x) #x - -// token concatenation -#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y) -#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y) -#define RAPIDJSON_DO_JOIN2(X, Y) X##Y -//!@endcond - -/*! \def RAPIDJSON_MAJOR_VERSION - \ingroup RAPIDJSON_CONFIG - \brief Major version of RapidJSON in integer. -*/ -/*! \def RAPIDJSON_MINOR_VERSION - \ingroup RAPIDJSON_CONFIG - \brief Minor version of RapidJSON in integer. -*/ -/*! \def RAPIDJSON_PATCH_VERSION - \ingroup RAPIDJSON_CONFIG - \brief Patch version of RapidJSON in integer. -*/ -/*! \def RAPIDJSON_VERSION_STRING - \ingroup RAPIDJSON_CONFIG - \brief Version of RapidJSON in ".." string format. -*/ -#define RAPIDJSON_MAJOR_VERSION 1 -#define RAPIDJSON_MINOR_VERSION 1 -#define RAPIDJSON_PATCH_VERSION 0 -#define RAPIDJSON_VERSION_STRING \ - RAPIDJSON_STRINGIFY(RAPIDJSON_MAJOR_VERSION.RAPIDJSON_MINOR_VERSION.RAPIDJSON_PATCH_VERSION) - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_NAMESPACE_(BEGIN|END) -/*! \def RAPIDJSON_NAMESPACE - \ingroup RAPIDJSON_CONFIG - \brief provide custom rapidjson namespace - - In order to avoid symbol clashes and/or "One Definition Rule" errors - between multiple inclusions of (different versions of) RapidJSON in - a single binary, users can customize the name of the main RapidJSON - namespace. - - In case of a single nesting level, defining \c RAPIDJSON_NAMESPACE - to a custom name (e.g. \c MyRapidJSON) is sufficient. If multiple - levels are needed, both \ref RAPIDJSON_NAMESPACE_BEGIN and \ref - RAPIDJSON_NAMESPACE_END need to be defined as well: - - \code - // in some .cpp file - #define RAPIDJSON_NAMESPACE my::rapidjson - #define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapidjson { - #define RAPIDJSON_NAMESPACE_END } } - #include "rapidjson/..." - \endcode - - \see rapidjson - */ -/*! \def RAPIDJSON_NAMESPACE_BEGIN - \ingroup RAPIDJSON_CONFIG - \brief provide custom rapidjson namespace (opening expression) - \see RAPIDJSON_NAMESPACE -*/ -/*! \def RAPIDJSON_NAMESPACE_END - \ingroup RAPIDJSON_CONFIG - \brief provide custom rapidjson namespace (closing expression) - \see RAPIDJSON_NAMESPACE -*/ -#ifndef RAPIDJSON_NAMESPACE -#define RAPIDJSON_NAMESPACE rapidjson -#endif -#ifndef RAPIDJSON_NAMESPACE_BEGIN -#define RAPIDJSON_NAMESPACE_BEGIN namespace RAPIDJSON_NAMESPACE { -#endif -#ifndef RAPIDJSON_NAMESPACE_END -#define RAPIDJSON_NAMESPACE_END } -#endif - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_HAS_STDSTRING - -#ifndef RAPIDJSON_HAS_STDSTRING -#ifdef RAPIDJSON_DOXYGEN_RUNNING -#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation -#else -#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default -#endif -/*! \def RAPIDJSON_HAS_STDSTRING - \ingroup RAPIDJSON_CONFIG - \brief Enable RapidJSON support for \c std::string - - By defining this preprocessor symbol to \c 1, several convenience functions for using - \ref rapidjson::GenericValue with \c std::string are enabled, especially - for construction and comparison. - - \hideinitializer -*/ -#endif // !defined(RAPIDJSON_HAS_STDSTRING) - -#if RAPIDJSON_HAS_STDSTRING -#include -#endif // RAPIDJSON_HAS_STDSTRING - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_NO_INT64DEFINE - -/*! \def RAPIDJSON_NO_INT64DEFINE - \ingroup RAPIDJSON_CONFIG - \brief Use external 64-bit integer types. - - RapidJSON requires the 64-bit integer types \c int64_t and \c uint64_t types - to be available at global scope. - - If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to - prevent RapidJSON from defining its own types. -*/ -#ifndef RAPIDJSON_NO_INT64DEFINE -//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN -#if defined(_MSC_VER) && (_MSC_VER < 1800) // Visual Studio 2013 -#include "msinttypes/stdint.h" -#include "msinttypes/inttypes.h" -#else -// Other compilers should have this. -#include -#include -#endif -//!@endcond -#ifdef RAPIDJSON_DOXYGEN_RUNNING -#define RAPIDJSON_NO_INT64DEFINE -#endif -#endif // RAPIDJSON_NO_INT64TYPEDEF - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_FORCEINLINE - -#ifndef RAPIDJSON_FORCEINLINE -//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN -#if defined(_MSC_VER) && defined(NDEBUG) -#define RAPIDJSON_FORCEINLINE __forceinline -#elif defined(__GNUC__) && __GNUC__ >= 4 && defined(NDEBUG) -#define RAPIDJSON_FORCEINLINE __attribute__((always_inline)) -#else -#define RAPIDJSON_FORCEINLINE -#endif -//!@endcond -#endif // RAPIDJSON_FORCEINLINE - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_ENDIAN -#define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine -#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine - -//! Endianness of the machine. -/*! - \def RAPIDJSON_ENDIAN - \ingroup RAPIDJSON_CONFIG - - GCC 4.6 provided macro for detecting endianness of the target machine. But other - compilers may not have this. User can define RAPIDJSON_ENDIAN to either - \ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN. - - Default detection implemented with reference to - \li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html - \li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp -*/ -#ifndef RAPIDJSON_ENDIAN -// Detect with GCC 4.6's macro -# ifdef __BYTE_ORDER__ -# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN -# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN -# else -# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN. -# endif // __BYTE_ORDER__ -// Detect with GLIBC's endian.h -# elif defined(__GLIBC__) -# include -# if (__BYTE_ORDER == __LITTLE_ENDIAN) -# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN -# elif (__BYTE_ORDER == __BIG_ENDIAN) -# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN -# else -# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN. -# endif // __GLIBC__ -// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro -# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) -# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN -# elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) -# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN -// Detect with architecture macros -# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__) -# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN -# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__) -# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN -# elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) -# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN -# elif defined(RAPIDJSON_DOXYGEN_RUNNING) -# define RAPIDJSON_ENDIAN -# else -# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN. -# endif -#endif // RAPIDJSON_ENDIAN - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_64BIT - -//! Whether using 64-bit architecture -#ifndef RAPIDJSON_64BIT -#if defined(__LP64__) || (defined(__x86_64__) && defined(__ILP32__)) || defined(_WIN64) || defined(__EMSCRIPTEN__) -#define RAPIDJSON_64BIT 1 -#else -#define RAPIDJSON_64BIT 0 -#endif -#endif // RAPIDJSON_64BIT - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_ALIGN - -//! Data alignment of the machine. -/*! \ingroup RAPIDJSON_CONFIG - \param x pointer to align - - Some machines require strict data alignment. The default is 8 bytes. - User can customize by defining the RAPIDJSON_ALIGN function macro. -*/ -#ifndef RAPIDJSON_ALIGN -#define RAPIDJSON_ALIGN(x) (((x) + static_cast(7u)) & ~static_cast(7u)) -#endif - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_UINT64_C2 - -//! Construct a 64-bit literal by a pair of 32-bit integer. -/*! - 64-bit literal with or without ULL suffix is prone to compiler warnings. - UINT64_C() is C macro which cause compilation problems. - Use this macro to define 64-bit constants by a pair of 32-bit integer. -*/ -#ifndef RAPIDJSON_UINT64_C2 -#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast(high32) << 32) | static_cast(low32)) -#endif - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_48BITPOINTER_OPTIMIZATION - -//! Use only lower 48-bit address for some pointers. -/*! - \ingroup RAPIDJSON_CONFIG - - This optimization uses the fact that current X86-64 architecture only implement lower 48-bit virtual address. - The higher 16-bit can be used for storing other data. - \c GenericValue uses this optimization to reduce its size form 24 bytes to 16 bytes in 64-bit architecture. -*/ -#ifndef RAPIDJSON_48BITPOINTER_OPTIMIZATION -#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) -#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 1 -#else -#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 0 -#endif -#endif // RAPIDJSON_48BITPOINTER_OPTIMIZATION - -#if RAPIDJSON_48BITPOINTER_OPTIMIZATION == 1 -#if RAPIDJSON_64BIT != 1 -#error RAPIDJSON_48BITPOINTER_OPTIMIZATION can only be set to 1 when RAPIDJSON_64BIT=1 -#endif -#define RAPIDJSON_SETPOINTER(type, p, x) (p = reinterpret_cast((reinterpret_cast(p) & static_cast(RAPIDJSON_UINT64_C2(0xFFFF0000, 0x00000000))) | reinterpret_cast(reinterpret_cast(x)))) -#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast(reinterpret_cast(p) & static_cast(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF)))) -#else -#define RAPIDJSON_SETPOINTER(type, p, x) (p = (x)) -#define RAPIDJSON_GETPOINTER(type, p) (p) -#endif - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_NEON/RAPIDJSON_SIMD - -/*! \def RAPIDJSON_SIMD - \ingroup RAPIDJSON_CONFIG - \brief Enable SSE2/SSE4.2/Neon optimization. - - RapidJSON supports optimized implementations for some parsing operations - based on the SSE2, SSE4.2 or NEon SIMD extensions on modern Intel - or ARM compatible processors. - - To enable these optimizations, three different symbols can be defined; - \code - // Enable SSE2 optimization. - #define RAPIDJSON_SSE2 - - // Enable SSE4.2 optimization. - #define RAPIDJSON_SSE42 - \endcode - - // Enable ARM Neon optimization. - #define RAPIDJSON_NEON - \endcode - - \c RAPIDJSON_SSE42 takes precedence over SSE2, if both are defined. - - If any of these symbols is defined, RapidJSON defines the macro - \c RAPIDJSON_SIMD to indicate the availability of the optimized code. -*/ -#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \ - || defined(RAPIDJSON_NEON) || defined(RAPIDJSON_DOXYGEN_RUNNING) -#define RAPIDJSON_SIMD -#endif - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_NO_SIZETYPEDEFINE - -#ifndef RAPIDJSON_NO_SIZETYPEDEFINE -/*! \def RAPIDJSON_NO_SIZETYPEDEFINE - \ingroup RAPIDJSON_CONFIG - \brief User-provided \c SizeType definition. - - In order to avoid using 32-bit size types for indexing strings and arrays, - define this preprocessor symbol and provide the type rapidjson::SizeType - before including RapidJSON: - \code - #define RAPIDJSON_NO_SIZETYPEDEFINE - namespace rapidjson { typedef ::std::size_t SizeType; } - #include "rapidjson/..." - \endcode - - \see rapidjson::SizeType -*/ -#ifdef RAPIDJSON_DOXYGEN_RUNNING -#define RAPIDJSON_NO_SIZETYPEDEFINE -#endif -RAPIDJSON_NAMESPACE_BEGIN -//! Size type (for string lengths, array sizes, etc.) -/*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms, - instead of using \c size_t. Users may override the SizeType by defining - \ref RAPIDJSON_NO_SIZETYPEDEFINE. -*/ -typedef unsigned SizeType; -RAPIDJSON_NAMESPACE_END -#endif - -// always import std::size_t to rapidjson namespace -RAPIDJSON_NAMESPACE_BEGIN -using std::size_t; -RAPIDJSON_NAMESPACE_END - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_ASSERT - -//! Assertion. -/*! \ingroup RAPIDJSON_CONFIG - By default, rapidjson uses C \c assert() for internal assertions. - User can override it by defining RAPIDJSON_ASSERT(x) macro. - - \note Parsing errors are handled and can be customized by the - \ref RAPIDJSON_ERRORS APIs. -*/ -#ifndef RAPIDJSON_ASSERT -#include -#define RAPIDJSON_ASSERT(x) assert(x) -#endif // RAPIDJSON_ASSERT - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_STATIC_ASSERT - -// Prefer C++11 static_assert, if available -#ifndef RAPIDJSON_STATIC_ASSERT -#if __cplusplus >= 201103L || ( defined(_MSC_VER) && _MSC_VER >= 1800 ) -#define RAPIDJSON_STATIC_ASSERT(x) \ - static_assert(x, RAPIDJSON_STRINGIFY(x)) -#endif // C++11 -#endif // RAPIDJSON_STATIC_ASSERT - -// Adopt C++03 implementation from boost -#ifndef RAPIDJSON_STATIC_ASSERT -#ifndef __clang__ -//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN -#endif -RAPIDJSON_NAMESPACE_BEGIN -template struct STATIC_ASSERTION_FAILURE; -template <> struct STATIC_ASSERTION_FAILURE { enum { value = 1 }; }; -template struct StaticAssertTest {}; -RAPIDJSON_NAMESPACE_END - -#if defined(__GNUC__) || defined(__clang__) -#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) -#else -#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE -#endif -#ifndef __clang__ -//!@endcond -#endif - -/*! \def RAPIDJSON_STATIC_ASSERT - \brief (Internal) macro to check for conditions at compile-time - \param x compile-time condition - \hideinitializer - */ -#define RAPIDJSON_STATIC_ASSERT(x) \ - typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \ - sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE)> \ - RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE -#endif // RAPIDJSON_STATIC_ASSERT - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_LIKELY, RAPIDJSON_UNLIKELY - -//! Compiler branching hint for expression with high probability to be true. -/*! - \ingroup RAPIDJSON_CONFIG - \param x Boolean expression likely to be true. -*/ -#ifndef RAPIDJSON_LIKELY -#if defined(__GNUC__) || defined(__clang__) -#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1) -#else -#define RAPIDJSON_LIKELY(x) (x) -#endif -#endif - -//! Compiler branching hint for expression with low probability to be true. -/*! - \ingroup RAPIDJSON_CONFIG - \param x Boolean expression unlikely to be true. -*/ -#ifndef RAPIDJSON_UNLIKELY -#if defined(__GNUC__) || defined(__clang__) -#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0) -#else -#define RAPIDJSON_UNLIKELY(x) (x) -#endif -#endif - -/////////////////////////////////////////////////////////////////////////////// -// Helpers - -//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN - -#define RAPIDJSON_MULTILINEMACRO_BEGIN do { -#define RAPIDJSON_MULTILINEMACRO_END \ -} while((void)0, 0) - -// adopted from Boost -#define RAPIDJSON_VERSION_CODE(x,y,z) \ - (((x)*100000) + ((y)*100) + (z)) - -#if defined(__has_builtin) -#define RAPIDJSON_HAS_BUILTIN(x) __has_builtin(x) -#else -#define RAPIDJSON_HAS_BUILTIN(x) 0 -#endif - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF - -#if defined(__GNUC__) -#define RAPIDJSON_GNUC \ - RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) -#endif - -#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0)) - -#define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x)) -#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x) -#define RAPIDJSON_DIAG_OFF(x) \ - RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x))) - -// push/pop support in Clang and GCC>=4.6 -#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) -#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) -#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) -#else // GCC >= 4.2, < 4.6 -#define RAPIDJSON_DIAG_PUSH /* ignored */ -#define RAPIDJSON_DIAG_POP /* ignored */ -#endif - -#elif defined(_MSC_VER) - -// pragma (MSVC specific) -#define RAPIDJSON_PRAGMA(x) __pragma(x) -#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x)) - -#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x) -#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) -#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) - -#else - -#define RAPIDJSON_DIAG_OFF(x) /* ignored */ -#define RAPIDJSON_DIAG_PUSH /* ignored */ -#define RAPIDJSON_DIAG_POP /* ignored */ - -#endif // RAPIDJSON_DIAG_* - -/////////////////////////////////////////////////////////////////////////////// -// C++11 features - -#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS -#if defined(__clang__) -#if __has_feature(cxx_rvalue_references) && \ - (defined(_MSC_VER) || defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306) -#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 -#else -#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 -#endif -#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ - (defined(_MSC_VER) && _MSC_VER >= 1600) || \ - (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__)) - -#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 -#else -#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 -#endif -#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS - -#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT -#if defined(__clang__) -#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept) -#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ - (defined(_MSC_VER) && _MSC_VER >= 1900) || \ - (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__)) -#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1 -#else -#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0 -#endif -#endif -#if RAPIDJSON_HAS_CXX11_NOEXCEPT -#define RAPIDJSON_NOEXCEPT noexcept -#else -#define RAPIDJSON_NOEXCEPT /* noexcept */ -#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT - -// no automatic detection, yet -#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS -#if (defined(_MSC_VER) && _MSC_VER >= 1700) -#define RAPIDJSON_HAS_CXX11_TYPETRAITS 1 -#else -#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0 -#endif -#endif - -#ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR -#if defined(__clang__) -#define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for) -#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ - (defined(_MSC_VER) && _MSC_VER >= 1700) || \ - (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__)) -#define RAPIDJSON_HAS_CXX11_RANGE_FOR 1 -#else -#define RAPIDJSON_HAS_CXX11_RANGE_FOR 0 -#endif -#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR - -/////////////////////////////////////////////////////////////////////////////// -// C++17 features - -#if defined(__has_cpp_attribute) -# if __has_cpp_attribute(fallthrough) -# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[fallthrough]] -# else -# define RAPIDJSON_DELIBERATE_FALLTHROUGH -# endif -#else -# define RAPIDJSON_DELIBERATE_FALLTHROUGH -#endif - -//!@endcond - -//! Assertion (in non-throwing contexts). - /*! \ingroup RAPIDJSON_CONFIG - Some functions provide a \c noexcept guarantee, if the compiler supports it. - In these cases, the \ref RAPIDJSON_ASSERT macro cannot be overridden to - throw an exception. This macro adds a separate customization point for - such cases. - - Defaults to C \c assert() (as \ref RAPIDJSON_ASSERT), if \c noexcept is - supported, and to \ref RAPIDJSON_ASSERT otherwise. - */ - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_NOEXCEPT_ASSERT - -#ifndef RAPIDJSON_NOEXCEPT_ASSERT -#ifdef RAPIDJSON_ASSERT_THROWS -#if RAPIDJSON_HAS_CXX11_NOEXCEPT -#define RAPIDJSON_NOEXCEPT_ASSERT(x) -#else -#include -#define RAPIDJSON_NOEXCEPT_ASSERT(x) assert(x) -#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT -#else -#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x) -#endif // RAPIDJSON_ASSERT_THROWS -#endif // RAPIDJSON_NOEXCEPT_ASSERT - -/////////////////////////////////////////////////////////////////////////////// -// malloc/realloc/free - -#ifndef RAPIDJSON_MALLOC -///! customization point for global \c malloc -#define RAPIDJSON_MALLOC(size) std::malloc(size) -#endif -#ifndef RAPIDJSON_REALLOC -///! customization point for global \c realloc -#define RAPIDJSON_REALLOC(ptr, new_size) std::realloc(ptr, new_size) -#endif -#ifndef RAPIDJSON_FREE -///! customization point for global \c free -#define RAPIDJSON_FREE(ptr) std::free(ptr) -#endif - -/////////////////////////////////////////////////////////////////////////////// -// new/delete - -#ifndef RAPIDJSON_NEW -///! customization point for global \c new -#define RAPIDJSON_NEW(TypeName) new TypeName -#endif -#ifndef RAPIDJSON_DELETE -///! customization point for global \c delete -#define RAPIDJSON_DELETE(x) delete x -#endif - -/////////////////////////////////////////////////////////////////////////////// -// Type - -/*! \namespace rapidjson - \brief main RapidJSON namespace - \see RAPIDJSON_NAMESPACE -*/ -RAPIDJSON_NAMESPACE_BEGIN - -//! Type of JSON value -enum Type { - kNullType = 0, //!< null - kFalseType = 1, //!< false - kTrueType = 2, //!< true - kObjectType = 3, //!< object - kArrayType = 4, //!< array - kStringType = 5, //!< string - kNumberType = 6 //!< number -}; - -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/reader.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/reader.h deleted file mode 100644 index 30e45e1f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/reader.h +++ /dev/null @@ -1,2244 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_READER_H_ -#define RAPIDJSON_READER_H_ - -/*! \file reader.h */ - -#include "allocators.h" -#include "stream.h" -#include "encodedstream.h" -#include "internal/clzll.h" -#include "internal/meta.h" -#include "internal/stack.h" -#include "internal/strtod.h" -#include - -#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) -#include -#pragma intrinsic(_BitScanForward) -#endif -#ifdef RAPIDJSON_SSE42 -#include -#elif defined(RAPIDJSON_SSE2) -#include -#elif defined(RAPIDJSON_NEON) -#include -#endif - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(old-style-cast) -RAPIDJSON_DIAG_OFF(padded) -RAPIDJSON_DIAG_OFF(switch-enum) -#elif defined(_MSC_VER) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant -RAPIDJSON_DIAG_OFF(4702) // unreachable code -#endif - -#ifdef __GNUC__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(effc++) -#endif - -//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN -#define RAPIDJSON_NOTHING /* deliberately empty */ -#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN -#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \ - RAPIDJSON_MULTILINEMACRO_BEGIN \ - if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \ - RAPIDJSON_MULTILINEMACRO_END -#endif -#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \ - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING) -//!@endcond - -/*! \def RAPIDJSON_PARSE_ERROR_NORETURN - \ingroup RAPIDJSON_ERRORS - \brief Macro to indicate a parse error. - \param parseErrorCode \ref rapidjson::ParseErrorCode of the error - \param offset position of the error in JSON input (\c size_t) - - This macros can be used as a customization point for the internal - error handling mechanism of RapidJSON. - - A common usage model is to throw an exception instead of requiring the - caller to explicitly check the \ref rapidjson::GenericReader::Parse's - return value: - - \code - #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \ - throw ParseException(parseErrorCode, #parseErrorCode, offset) - - #include // std::runtime_error - #include "rapidjson/error/error.h" // rapidjson::ParseResult - - struct ParseException : std::runtime_error, rapidjson::ParseResult { - ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset) - : std::runtime_error(msg), ParseResult(code, offset) {} - }; - - #include "rapidjson/reader.h" - \endcode - - \see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse - */ -#ifndef RAPIDJSON_PARSE_ERROR_NORETURN -#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \ - RAPIDJSON_MULTILINEMACRO_BEGIN \ - RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \ - SetParseError(parseErrorCode, offset); \ - RAPIDJSON_MULTILINEMACRO_END -#endif - -/*! \def RAPIDJSON_PARSE_ERROR - \ingroup RAPIDJSON_ERRORS - \brief (Internal) macro to indicate and handle a parse error. - \param parseErrorCode \ref rapidjson::ParseErrorCode of the error - \param offset position of the error in JSON input (\c size_t) - - Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing. - - \see RAPIDJSON_PARSE_ERROR_NORETURN - \hideinitializer - */ -#ifndef RAPIDJSON_PARSE_ERROR -#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \ - RAPIDJSON_MULTILINEMACRO_BEGIN \ - RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \ - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \ - RAPIDJSON_MULTILINEMACRO_END -#endif - -#include "error/error.h" // ParseErrorCode, ParseResult - -RAPIDJSON_NAMESPACE_BEGIN - -/////////////////////////////////////////////////////////////////////////////// -// ParseFlag - -/*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS - \ingroup RAPIDJSON_CONFIG - \brief User-defined kParseDefaultFlags definition. - - User can define this as any \c ParseFlag combinations. -*/ -#ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS -#define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags -#endif - -//! Combination of parseFlags -/*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream - */ -enum ParseFlag { - kParseNoFlags = 0, //!< No flags are set. - kParseInsituFlag = 1, //!< In-situ(destructive) parsing. - kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings. - kParseIterativeFlag = 4, //!< Iterative(constant complexity in terms of function call stack size) parsing. - kParseStopWhenDoneFlag = 8, //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error. - kParseFullPrecisionFlag = 16, //!< Parse number in full precision (but slower). - kParseCommentsFlag = 32, //!< Allow one-line (//) and multi-line (/**/) comments. - kParseNumbersAsStringsFlag = 64, //!< Parse all numbers (ints/doubles) as strings. - kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays. - kParseNanAndInfFlag = 256, //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles. - kParseEscapedApostropheFlag = 512, //!< Allow escaped apostrophe in strings. - kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS -}; - -/////////////////////////////////////////////////////////////////////////////// -// Handler - -/*! \class rapidjson::Handler - \brief Concept for receiving events from GenericReader upon parsing. - The functions return true if no error occurs. If they return false, - the event publisher should terminate the process. -\code -concept Handler { - typename Ch; - - bool Null(); - bool Bool(bool b); - bool Int(int i); - bool Uint(unsigned i); - bool Int64(int64_t i); - bool Uint64(uint64_t i); - bool Double(double d); - /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) - bool RawNumber(const Ch* str, SizeType length, bool copy); - bool String(const Ch* str, SizeType length, bool copy); - bool StartObject(); - bool Key(const Ch* str, SizeType length, bool copy); - bool EndObject(SizeType memberCount); - bool StartArray(); - bool EndArray(SizeType elementCount); -}; -\endcode -*/ -/////////////////////////////////////////////////////////////////////////////// -// BaseReaderHandler - -//! Default implementation of Handler. -/*! This can be used as base class of any reader handler. - \note implements Handler concept -*/ -template, typename Derived = void> -struct BaseReaderHandler { - typedef typename Encoding::Ch Ch; - - typedef typename internal::SelectIf, BaseReaderHandler, Derived>::Type Override; - - bool Default() { return true; } - bool Null() { return static_cast(*this).Default(); } - bool Bool(bool) { return static_cast(*this).Default(); } - bool Int(int) { return static_cast(*this).Default(); } - bool Uint(unsigned) { return static_cast(*this).Default(); } - bool Int64(int64_t) { return static_cast(*this).Default(); } - bool Uint64(uint64_t) { return static_cast(*this).Default(); } - bool Double(double) { return static_cast(*this).Default(); } - /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) - bool RawNumber(const Ch* str, SizeType len, bool copy) { return static_cast(*this).String(str, len, copy); } - bool String(const Ch*, SizeType, bool) { return static_cast(*this).Default(); } - bool StartObject() { return static_cast(*this).Default(); } - bool Key(const Ch* str, SizeType len, bool copy) { return static_cast(*this).String(str, len, copy); } - bool EndObject(SizeType) { return static_cast(*this).Default(); } - bool StartArray() { return static_cast(*this).Default(); } - bool EndArray(SizeType) { return static_cast(*this).Default(); } -}; - -/////////////////////////////////////////////////////////////////////////////// -// StreamLocalCopy - -namespace internal { - -template::copyOptimization> -class StreamLocalCopy; - -//! Do copy optimization. -template -class StreamLocalCopy { -public: - StreamLocalCopy(Stream& original) : s(original), original_(original) {} - ~StreamLocalCopy() { original_ = s; } - - Stream s; - -private: - StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; - - Stream& original_; -}; - -//! Keep reference. -template -class StreamLocalCopy { -public: - StreamLocalCopy(Stream& original) : s(original) {} - - Stream& s; - -private: - StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; -}; - -} // namespace internal - -/////////////////////////////////////////////////////////////////////////////// -// SkipWhitespace - -//! Skip the JSON white spaces in a stream. -/*! \param is A input stream for skipping white spaces. - \note This function has SSE2/SSE4.2 specialization. -*/ -template -void SkipWhitespace(InputStream& is) { - internal::StreamLocalCopy copy(is); - InputStream& s(copy.s); - - typename InputStream::Ch c; - while ((c = s.Peek()) == ' ' || c == '\n' || c == '\r' || c == '\t') - s.Take(); -} - -inline const char* SkipWhitespace(const char* p, const char* end) { - while (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) - ++p; - return p; -} - -#ifdef RAPIDJSON_SSE42 -//! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once. -inline const char *SkipWhitespace_SIMD(const char* p) { - // Fast return for single non-whitespace - if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') - ++p; - else - return p; - - // 16-byte align to the next boundary - const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); - while (p != nextAligned) - if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') - ++p; - else - return p; - - // The rest of string using SIMD - static const char whitespace[16] = " \n\r\t"; - const __m128i w = _mm_loadu_si128(reinterpret_cast(&whitespace[0])); - - for (;; p += 16) { - const __m128i s = _mm_load_si128(reinterpret_cast(p)); - const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY); - if (r != 16) // some of characters is non-whitespace - return p + r; - } -} - -inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { - // Fast return for single non-whitespace - if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) - ++p; - else - return p; - - // The middle of string using SIMD - static const char whitespace[16] = " \n\r\t"; - const __m128i w = _mm_loadu_si128(reinterpret_cast(&whitespace[0])); - - for (; p <= end - 16; p += 16) { - const __m128i s = _mm_loadu_si128(reinterpret_cast(p)); - const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY); - if (r != 16) // some of characters is non-whitespace - return p + r; - } - - return SkipWhitespace(p, end); -} - -#elif defined(RAPIDJSON_SSE2) - -//! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once. -inline const char *SkipWhitespace_SIMD(const char* p) { - // Fast return for single non-whitespace - if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') - ++p; - else - return p; - - // 16-byte align to the next boundary - const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); - while (p != nextAligned) - if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') - ++p; - else - return p; - - // The rest of string - #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c } - static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') }; - #undef C16 - - const __m128i w0 = _mm_loadu_si128(reinterpret_cast(&whitespaces[0][0])); - const __m128i w1 = _mm_loadu_si128(reinterpret_cast(&whitespaces[1][0])); - const __m128i w2 = _mm_loadu_si128(reinterpret_cast(&whitespaces[2][0])); - const __m128i w3 = _mm_loadu_si128(reinterpret_cast(&whitespaces[3][0])); - - for (;; p += 16) { - const __m128i s = _mm_load_si128(reinterpret_cast(p)); - __m128i x = _mm_cmpeq_epi8(s, w0); - x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); - x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); - x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); - unsigned short r = static_cast(~_mm_movemask_epi8(x)); - if (r != 0) { // some of characters may be non-whitespace -#ifdef _MSC_VER // Find the index of first non-whitespace - unsigned long offset; - _BitScanForward(&offset, r); - return p + offset; -#else - return p + __builtin_ffs(r) - 1; -#endif - } - } -} - -inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { - // Fast return for single non-whitespace - if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) - ++p; - else - return p; - - // The rest of string - #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c } - static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') }; - #undef C16 - - const __m128i w0 = _mm_loadu_si128(reinterpret_cast(&whitespaces[0][0])); - const __m128i w1 = _mm_loadu_si128(reinterpret_cast(&whitespaces[1][0])); - const __m128i w2 = _mm_loadu_si128(reinterpret_cast(&whitespaces[2][0])); - const __m128i w3 = _mm_loadu_si128(reinterpret_cast(&whitespaces[3][0])); - - for (; p <= end - 16; p += 16) { - const __m128i s = _mm_loadu_si128(reinterpret_cast(p)); - __m128i x = _mm_cmpeq_epi8(s, w0); - x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); - x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); - x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); - unsigned short r = static_cast(~_mm_movemask_epi8(x)); - if (r != 0) { // some of characters may be non-whitespace -#ifdef _MSC_VER // Find the index of first non-whitespace - unsigned long offset; - _BitScanForward(&offset, r); - return p + offset; -#else - return p + __builtin_ffs(r) - 1; -#endif - } - } - - return SkipWhitespace(p, end); -} - -#elif defined(RAPIDJSON_NEON) - -//! Skip whitespace with ARM Neon instructions, testing 16 8-byte characters at once. -inline const char *SkipWhitespace_SIMD(const char* p) { - // Fast return for single non-whitespace - if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') - ++p; - else - return p; - - // 16-byte align to the next boundary - const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); - while (p != nextAligned) - if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') - ++p; - else - return p; - - const uint8x16_t w0 = vmovq_n_u8(' '); - const uint8x16_t w1 = vmovq_n_u8('\n'); - const uint8x16_t w2 = vmovq_n_u8('\r'); - const uint8x16_t w3 = vmovq_n_u8('\t'); - - for (;; p += 16) { - const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); - uint8x16_t x = vceqq_u8(s, w0); - x = vorrq_u8(x, vceqq_u8(s, w1)); - x = vorrq_u8(x, vceqq_u8(s, w2)); - x = vorrq_u8(x, vceqq_u8(s, w3)); - - x = vmvnq_u8(x); // Negate - x = vrev64q_u8(x); // Rev in 64 - uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract - uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract - - if (low == 0) { - if (high != 0) { - uint32_t lz = internal::clzll(high); - return p + 8 + (lz >> 3); - } - } else { - uint32_t lz = internal::clzll(low); - return p + (lz >> 3); - } - } -} - -inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { - // Fast return for single non-whitespace - if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) - ++p; - else - return p; - - const uint8x16_t w0 = vmovq_n_u8(' '); - const uint8x16_t w1 = vmovq_n_u8('\n'); - const uint8x16_t w2 = vmovq_n_u8('\r'); - const uint8x16_t w3 = vmovq_n_u8('\t'); - - for (; p <= end - 16; p += 16) { - const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); - uint8x16_t x = vceqq_u8(s, w0); - x = vorrq_u8(x, vceqq_u8(s, w1)); - x = vorrq_u8(x, vceqq_u8(s, w2)); - x = vorrq_u8(x, vceqq_u8(s, w3)); - - x = vmvnq_u8(x); // Negate - x = vrev64q_u8(x); // Rev in 64 - uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract - uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract - - if (low == 0) { - if (high != 0) { - uint32_t lz = internal::clzll(high); - return p + 8 + (lz >> 3); - } - } else { - uint32_t lz = internal::clzll(low); - return p + (lz >> 3); - } - } - - return SkipWhitespace(p, end); -} - -#endif // RAPIDJSON_NEON - -#ifdef RAPIDJSON_SIMD -//! Template function specialization for InsituStringStream -template<> inline void SkipWhitespace(InsituStringStream& is) { - is.src_ = const_cast(SkipWhitespace_SIMD(is.src_)); -} - -//! Template function specialization for StringStream -template<> inline void SkipWhitespace(StringStream& is) { - is.src_ = SkipWhitespace_SIMD(is.src_); -} - -template<> inline void SkipWhitespace(EncodedInputStream, MemoryStream>& is) { - is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_); -} -#endif // RAPIDJSON_SIMD - -/////////////////////////////////////////////////////////////////////////////// -// GenericReader - -//! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator. -/*! GenericReader parses JSON text from a stream, and send events synchronously to an - object implementing Handler concept. - - It needs to allocate a stack for storing a single decoded string during - non-destructive parsing. - - For in-situ parsing, the decoded string is directly written to the source - text string, no temporary buffer is required. - - A GenericReader object can be reused for parsing multiple JSON text. - - \tparam SourceEncoding Encoding of the input stream. - \tparam TargetEncoding Encoding of the parse output. - \tparam StackAllocator Allocator type for stack. -*/ -template -class GenericReader { -public: - typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type - - //! Constructor. - /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing) - \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing) - */ - GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : - stack_(stackAllocator, stackCapacity), parseResult_(), state_(IterativeParsingStartState) {} - - //! Parse JSON text. - /*! \tparam parseFlags Combination of \ref ParseFlag. - \tparam InputStream Type of input stream, implementing Stream concept. - \tparam Handler Type of handler, implementing Handler concept. - \param is Input stream to be parsed. - \param handler The handler to receive events. - \return Whether the parsing is successful. - */ - template - ParseResult Parse(InputStream& is, Handler& handler) { - if (parseFlags & kParseIterativeFlag) - return IterativeParse(is, handler); - - parseResult_.Clear(); - - ClearStackOnExit scope(*this); - - SkipWhitespaceAndComments(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); - - if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) { - RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell()); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); - } - else { - ParseValue(is, handler); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); - - if (!(parseFlags & kParseStopWhenDoneFlag)) { - SkipWhitespaceAndComments(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); - - if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) { - RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell()); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); - } - } - } - - return parseResult_; - } - - //! Parse JSON text (with \ref kParseDefaultFlags) - /*! \tparam InputStream Type of input stream, implementing Stream concept - \tparam Handler Type of handler, implementing Handler concept. - \param is Input stream to be parsed. - \param handler The handler to receive events. - \return Whether the parsing is successful. - */ - template - ParseResult Parse(InputStream& is, Handler& handler) { - return Parse(is, handler); - } - - //! Initialize JSON text token-by-token parsing - /*! - */ - void IterativeParseInit() { - parseResult_.Clear(); - state_ = IterativeParsingStartState; - } - - //! Parse one token from JSON text - /*! \tparam InputStream Type of input stream, implementing Stream concept - \tparam Handler Type of handler, implementing Handler concept. - \param is Input stream to be parsed. - \param handler The handler to receive events. - \return Whether the parsing is successful. - */ - template - bool IterativeParseNext(InputStream& is, Handler& handler) { - while (RAPIDJSON_LIKELY(is.Peek() != '\0')) { - SkipWhitespaceAndComments(is); - - Token t = Tokenize(is.Peek()); - IterativeParsingState n = Predict(state_, t); - IterativeParsingState d = Transit(state_, t, n, is, handler); - - // If we've finished or hit an error... - if (RAPIDJSON_UNLIKELY(IsIterativeParsingCompleteState(d))) { - // Report errors. - if (d == IterativeParsingErrorState) { - HandleError(state_, is); - return false; - } - - // Transition to the finish state. - RAPIDJSON_ASSERT(d == IterativeParsingFinishState); - state_ = d; - - // If StopWhenDone is not set... - if (!(parseFlags & kParseStopWhenDoneFlag)) { - // ... and extra non-whitespace data is found... - SkipWhitespaceAndComments(is); - if (is.Peek() != '\0') { - // ... this is considered an error. - HandleError(state_, is); - return false; - } - } - - // Success! We are done! - return true; - } - - // Transition to the new state. - state_ = d; - - // If we parsed anything other than a delimiter, we invoked the handler, so we can return true now. - if (!IsIterativeParsingDelimiterState(n)) - return true; - } - - // We reached the end of file. - stack_.Clear(); - - if (state_ != IterativeParsingFinishState) { - HandleError(state_, is); - return false; - } - - return true; - } - - //! Check if token-by-token parsing JSON text is complete - /*! \return Whether the JSON has been fully decoded. - */ - RAPIDJSON_FORCEINLINE bool IterativeParseComplete() const { - return IsIterativeParsingCompleteState(state_); - } - - //! Whether a parse error has occurred in the last parsing. - bool HasParseError() const { return parseResult_.IsError(); } - - //! Get the \ref ParseErrorCode of last parsing. - ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); } - - //! Get the position of last parsing error in input, 0 otherwise. - size_t GetErrorOffset() const { return parseResult_.Offset(); } - -protected: - void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); } - -private: - // Prohibit copy constructor & assignment operator. - GenericReader(const GenericReader&); - GenericReader& operator=(const GenericReader&); - - void ClearStack() { stack_.Clear(); } - - // clear stack on any exit from ParseStream, e.g. due to exception - struct ClearStackOnExit { - explicit ClearStackOnExit(GenericReader& r) : r_(r) {} - ~ClearStackOnExit() { r_.ClearStack(); } - private: - GenericReader& r_; - ClearStackOnExit(const ClearStackOnExit&); - ClearStackOnExit& operator=(const ClearStackOnExit&); - }; - - template - void SkipWhitespaceAndComments(InputStream& is) { - SkipWhitespace(is); - - if (parseFlags & kParseCommentsFlag) { - while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) { - if (Consume(is, '*')) { - while (true) { - if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) - RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); - else if (Consume(is, '*')) { - if (Consume(is, '/')) - break; - } - else - is.Take(); - } - } - else if (RAPIDJSON_LIKELY(Consume(is, '/'))) - while (is.Peek() != '\0' && is.Take() != '\n') {} - else - RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); - - SkipWhitespace(is); - } - } - } - - // Parse object: { string : value, ... } - template - void ParseObject(InputStream& is, Handler& handler) { - RAPIDJSON_ASSERT(is.Peek() == '{'); - is.Take(); // Skip '{' - - if (RAPIDJSON_UNLIKELY(!handler.StartObject())) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - - SkipWhitespaceAndComments(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - if (Consume(is, '}')) { - if (RAPIDJSON_UNLIKELY(!handler.EndObject(0))) // empty object - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - return; - } - - for (SizeType memberCount = 0;;) { - if (RAPIDJSON_UNLIKELY(is.Peek() != '"')) - RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); - - ParseString(is, handler, true); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - SkipWhitespaceAndComments(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - if (RAPIDJSON_UNLIKELY(!Consume(is, ':'))) - RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); - - SkipWhitespaceAndComments(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - ParseValue(is, handler); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - SkipWhitespaceAndComments(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - ++memberCount; - - switch (is.Peek()) { - case ',': - is.Take(); - SkipWhitespaceAndComments(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - break; - case '}': - is.Take(); - if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - return; - default: - RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy - } - - if (parseFlags & kParseTrailingCommasFlag) { - if (is.Peek() == '}') { - if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - is.Take(); - return; - } - } - } - } - - // Parse array: [ value, ... ] - template - void ParseArray(InputStream& is, Handler& handler) { - RAPIDJSON_ASSERT(is.Peek() == '['); - is.Take(); // Skip '[' - - if (RAPIDJSON_UNLIKELY(!handler.StartArray())) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - - SkipWhitespaceAndComments(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - if (Consume(is, ']')) { - if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - return; - } - - for (SizeType elementCount = 0;;) { - ParseValue(is, handler); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - ++elementCount; - SkipWhitespaceAndComments(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - if (Consume(is, ',')) { - SkipWhitespaceAndComments(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - } - else if (Consume(is, ']')) { - if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount))) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - return; - } - else - RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); - - if (parseFlags & kParseTrailingCommasFlag) { - if (is.Peek() == ']') { - if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount))) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - is.Take(); - return; - } - } - } - } - - template - void ParseNull(InputStream& is, Handler& handler) { - RAPIDJSON_ASSERT(is.Peek() == 'n'); - is.Take(); - - if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) { - if (RAPIDJSON_UNLIKELY(!handler.Null())) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - } - else - RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); - } - - template - void ParseTrue(InputStream& is, Handler& handler) { - RAPIDJSON_ASSERT(is.Peek() == 't'); - is.Take(); - - if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) { - if (RAPIDJSON_UNLIKELY(!handler.Bool(true))) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - } - else - RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); - } - - template - void ParseFalse(InputStream& is, Handler& handler) { - RAPIDJSON_ASSERT(is.Peek() == 'f'); - is.Take(); - - if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) { - if (RAPIDJSON_UNLIKELY(!handler.Bool(false))) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - } - else - RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); - } - - template - RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) { - if (RAPIDJSON_LIKELY(is.Peek() == expect)) { - is.Take(); - return true; - } - else - return false; - } - - // Helper function to parse four hexadecimal digits in \uXXXX in ParseString(). - template - unsigned ParseHex4(InputStream& is, size_t escapeOffset) { - unsigned codepoint = 0; - for (int i = 0; i < 4; i++) { - Ch c = is.Peek(); - codepoint <<= 4; - codepoint += static_cast(c); - if (c >= '0' && c <= '9') - codepoint -= '0'; - else if (c >= 'A' && c <= 'F') - codepoint -= 'A' - 10; - else if (c >= 'a' && c <= 'f') - codepoint -= 'a' - 10; - else { - RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, escapeOffset); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0); - } - is.Take(); - } - return codepoint; - } - - template - class StackStream { - public: - typedef CharType Ch; - - StackStream(internal::Stack& stack) : stack_(stack), length_(0) {} - RAPIDJSON_FORCEINLINE void Put(Ch c) { - *stack_.template Push() = c; - ++length_; - } - - RAPIDJSON_FORCEINLINE void* Push(SizeType count) { - length_ += count; - return stack_.template Push(count); - } - - size_t Length() const { return length_; } - - Ch* Pop() { - return stack_.template Pop(length_); - } - - private: - StackStream(const StackStream&); - StackStream& operator=(const StackStream&); - - internal::Stack& stack_; - SizeType length_; - }; - - // Parse string and generate String event. Different code paths for kParseInsituFlag. - template - void ParseString(InputStream& is, Handler& handler, bool isKey = false) { - internal::StreamLocalCopy copy(is); - InputStream& s(copy.s); - - RAPIDJSON_ASSERT(s.Peek() == '\"'); - s.Take(); // Skip '\"' - - bool success = false; - if (parseFlags & kParseInsituFlag) { - typename InputStream::Ch *head = s.PutBegin(); - ParseStringToStream(s, s); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - size_t length = s.PutEnd(head) - 1; - RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); - const typename TargetEncoding::Ch* const str = reinterpret_cast(head); - success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false)); - } - else { - StackStream stackStream(stack_); - ParseStringToStream(s, stackStream); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - SizeType length = static_cast(stackStream.Length()) - 1; - const typename TargetEncoding::Ch* const str = stackStream.Pop(); - success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true)); - } - if (RAPIDJSON_UNLIKELY(!success)) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); - } - - // Parse string to an output is - // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation. - template - RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) { -//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN -#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - static const char escape[256] = { - Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '/', - Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, - 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0, - 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 - }; -#undef Z16 -//!@endcond - - for (;;) { - // Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation. - if (!(parseFlags & kParseValidateEncodingFlag)) - ScanCopyUnescapedString(is, os); - - Ch c = is.Peek(); - if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape - size_t escapeOffset = is.Tell(); // For invalid escaping, report the initial '\\' as error offset - is.Take(); - Ch e = is.Peek(); - if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast(e)])) { - is.Take(); - os.Put(static_cast(escape[static_cast(e)])); - } - else if ((parseFlags & kParseEscapedApostropheFlag) && RAPIDJSON_LIKELY(e == '\'')) { // Allow escaped apostrophe - is.Take(); - os.Put('\''); - } - else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode - is.Take(); - unsigned codepoint = ParseHex4(is, escapeOffset); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDFFF)) { - // high surrogate, check if followed by valid low surrogate - if (RAPIDJSON_LIKELY(codepoint <= 0xDBFF)) { - // Handle UTF-16 surrogate pair - if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u'))) - RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); - unsigned codepoint2 = ParseHex4(is, escapeOffset); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF)) - RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); - codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000; - } - // single low surrogate - else - { - RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); - } - } - TEncoding::Encode(os, codepoint); - } - else - RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset); - } - else if (RAPIDJSON_UNLIKELY(c == '"')) { // Closing double quote - is.Take(); - os.Put('\0'); // null-terminate the string - return; - } - else if (RAPIDJSON_UNLIKELY(static_cast(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF - if (c == '\0') - RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell()); - else - RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, is.Tell()); - } - else { - size_t offset = is.Tell(); - if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ? - !Transcoder::Validate(is, os) : - !Transcoder::Transcode(is, os)))) - RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset); - } - } - } - - template - static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) { - // Do nothing for generic version - } - -#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) - // StringStream -> StackStream - static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream& os) { - const char* p = is.src_; - - // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) - const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); - while (p != nextAligned) - if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { - is.src_ = p; - return; - } - else - os.Put(*p++); - - // The rest of string using SIMD - static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; - static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; - static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }; - const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); - const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); - const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); - - for (;; p += 16) { - const __m128i s = _mm_load_si128(reinterpret_cast(p)); - const __m128i t1 = _mm_cmpeq_epi8(s, dq); - const __m128i t2 = _mm_cmpeq_epi8(s, bs); - const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F - const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); - unsigned short r = static_cast(_mm_movemask_epi8(x)); - if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped - SizeType length; - #ifdef _MSC_VER // Find the index of first escaped - unsigned long offset; - _BitScanForward(&offset, r); - length = offset; - #else - length = static_cast(__builtin_ffs(r) - 1); - #endif - if (length != 0) { - char* q = reinterpret_cast(os.Push(length)); - for (size_t i = 0; i < length; i++) - q[i] = p[i]; - - p += length; - } - break; - } - _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s); - } - - is.src_ = p; - } - - // InsituStringStream -> InsituStringStream - static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) { - RAPIDJSON_ASSERT(&is == &os); - (void)os; - - if (is.src_ == is.dst_) { - SkipUnescapedString(is); - return; - } - - char* p = is.src_; - char *q = is.dst_; - - // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) - const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); - while (p != nextAligned) - if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { - is.src_ = p; - is.dst_ = q; - return; - } - else - *q++ = *p++; - - // The rest of string using SIMD - static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; - static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; - static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }; - const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); - const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); - const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); - - for (;; p += 16, q += 16) { - const __m128i s = _mm_load_si128(reinterpret_cast(p)); - const __m128i t1 = _mm_cmpeq_epi8(s, dq); - const __m128i t2 = _mm_cmpeq_epi8(s, bs); - const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F - const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); - unsigned short r = static_cast(_mm_movemask_epi8(x)); - if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped - size_t length; -#ifdef _MSC_VER // Find the index of first escaped - unsigned long offset; - _BitScanForward(&offset, r); - length = offset; -#else - length = static_cast(__builtin_ffs(r) - 1); -#endif - for (const char* pend = p + length; p != pend; ) - *q++ = *p++; - break; - } - _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s); - } - - is.src_ = p; - is.dst_ = q; - } - - // When read/write pointers are the same for insitu stream, just skip unescaped characters - static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) { - RAPIDJSON_ASSERT(is.src_ == is.dst_); - char* p = is.src_; - - // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) - const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); - for (; p != nextAligned; p++) - if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { - is.src_ = is.dst_ = p; - return; - } - - // The rest of string using SIMD - static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; - static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; - static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }; - const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); - const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); - const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); - - for (;; p += 16) { - const __m128i s = _mm_load_si128(reinterpret_cast(p)); - const __m128i t1 = _mm_cmpeq_epi8(s, dq); - const __m128i t2 = _mm_cmpeq_epi8(s, bs); - const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F - const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); - unsigned short r = static_cast(_mm_movemask_epi8(x)); - if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped - size_t length; -#ifdef _MSC_VER // Find the index of first escaped - unsigned long offset; - _BitScanForward(&offset, r); - length = offset; -#else - length = static_cast(__builtin_ffs(r) - 1); -#endif - p += length; - break; - } - } - - is.src_ = is.dst_ = p; - } -#elif defined(RAPIDJSON_NEON) - // StringStream -> StackStream - static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream& os) { - const char* p = is.src_; - - // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) - const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); - while (p != nextAligned) - if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { - is.src_ = p; - return; - } - else - os.Put(*p++); - - // The rest of string using SIMD - const uint8x16_t s0 = vmovq_n_u8('"'); - const uint8x16_t s1 = vmovq_n_u8('\\'); - const uint8x16_t s2 = vmovq_n_u8('\b'); - const uint8x16_t s3 = vmovq_n_u8(32); - - for (;; p += 16) { - const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); - uint8x16_t x = vceqq_u8(s, s0); - x = vorrq_u8(x, vceqq_u8(s, s1)); - x = vorrq_u8(x, vceqq_u8(s, s2)); - x = vorrq_u8(x, vcltq_u8(s, s3)); - - x = vrev64q_u8(x); // Rev in 64 - uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract - uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract - - SizeType length = 0; - bool escaped = false; - if (low == 0) { - if (high != 0) { - uint32_t lz = internal::clzll(high); - length = 8 + (lz >> 3); - escaped = true; - } - } else { - uint32_t lz = internal::clzll(low); - length = lz >> 3; - escaped = true; - } - if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped - if (length != 0) { - char* q = reinterpret_cast(os.Push(length)); - for (size_t i = 0; i < length; i++) - q[i] = p[i]; - - p += length; - } - break; - } - vst1q_u8(reinterpret_cast(os.Push(16)), s); - } - - is.src_ = p; - } - - // InsituStringStream -> InsituStringStream - static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) { - RAPIDJSON_ASSERT(&is == &os); - (void)os; - - if (is.src_ == is.dst_) { - SkipUnescapedString(is); - return; - } - - char* p = is.src_; - char *q = is.dst_; - - // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) - const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); - while (p != nextAligned) - if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { - is.src_ = p; - is.dst_ = q; - return; - } - else - *q++ = *p++; - - // The rest of string using SIMD - const uint8x16_t s0 = vmovq_n_u8('"'); - const uint8x16_t s1 = vmovq_n_u8('\\'); - const uint8x16_t s2 = vmovq_n_u8('\b'); - const uint8x16_t s3 = vmovq_n_u8(32); - - for (;; p += 16, q += 16) { - const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); - uint8x16_t x = vceqq_u8(s, s0); - x = vorrq_u8(x, vceqq_u8(s, s1)); - x = vorrq_u8(x, vceqq_u8(s, s2)); - x = vorrq_u8(x, vcltq_u8(s, s3)); - - x = vrev64q_u8(x); // Rev in 64 - uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract - uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract - - SizeType length = 0; - bool escaped = false; - if (low == 0) { - if (high != 0) { - uint32_t lz = internal::clzll(high); - length = 8 + (lz >> 3); - escaped = true; - } - } else { - uint32_t lz = internal::clzll(low); - length = lz >> 3; - escaped = true; - } - if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped - for (const char* pend = p + length; p != pend; ) { - *q++ = *p++; - } - break; - } - vst1q_u8(reinterpret_cast(q), s); - } - - is.src_ = p; - is.dst_ = q; - } - - // When read/write pointers are the same for insitu stream, just skip unescaped characters - static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) { - RAPIDJSON_ASSERT(is.src_ == is.dst_); - char* p = is.src_; - - // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) - const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); - for (; p != nextAligned; p++) - if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { - is.src_ = is.dst_ = p; - return; - } - - // The rest of string using SIMD - const uint8x16_t s0 = vmovq_n_u8('"'); - const uint8x16_t s1 = vmovq_n_u8('\\'); - const uint8x16_t s2 = vmovq_n_u8('\b'); - const uint8x16_t s3 = vmovq_n_u8(32); - - for (;; p += 16) { - const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); - uint8x16_t x = vceqq_u8(s, s0); - x = vorrq_u8(x, vceqq_u8(s, s1)); - x = vorrq_u8(x, vceqq_u8(s, s2)); - x = vorrq_u8(x, vcltq_u8(s, s3)); - - x = vrev64q_u8(x); // Rev in 64 - uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract - uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract - - if (low == 0) { - if (high != 0) { - uint32_t lz = internal::clzll(high); - p += 8 + (lz >> 3); - break; - } - } else { - uint32_t lz = internal::clzll(low); - p += lz >> 3; - break; - } - } - - is.src_ = is.dst_ = p; - } -#endif // RAPIDJSON_NEON - - template - class NumberStream; - - template - class NumberStream { - public: - typedef typename InputStream::Ch Ch; - - NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader; } - - RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); } - RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); } - RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); } - RAPIDJSON_FORCEINLINE void Push(char) {} - - size_t Tell() { return is.Tell(); } - size_t Length() { return 0; } - const char* Pop() { return 0; } - - protected: - NumberStream& operator=(const NumberStream&); - - InputStream& is; - }; - - template - class NumberStream : public NumberStream { - typedef NumberStream Base; - public: - NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {} - - RAPIDJSON_FORCEINLINE Ch TakePush() { - stackStream.Put(static_cast(Base::is.Peek())); - return Base::is.Take(); - } - - RAPIDJSON_FORCEINLINE void Push(char c) { - stackStream.Put(c); - } - - size_t Length() { return stackStream.Length(); } - - const char* Pop() { - stackStream.Put('\0'); - return stackStream.Pop(); - } - - private: - StackStream stackStream; - }; - - template - class NumberStream : public NumberStream { - typedef NumberStream Base; - public: - NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {} - - RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); } - }; - - template - void ParseNumber(InputStream& is, Handler& handler) { - internal::StreamLocalCopy copy(is); - NumberStream s(*this, copy.s); - - size_t startOffset = s.Tell(); - double d = 0.0; - bool useNanOrInf = false; - - // Parse minus - bool minus = Consume(s, '-'); - - // Parse int: zero / ( digit1-9 *DIGIT ) - unsigned i = 0; - uint64_t i64 = 0; - bool use64bit = false; - int significandDigit = 0; - if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) { - i = 0; - s.TakePush(); - } - else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) { - i = static_cast(s.TakePush() - '0'); - - if (minus) - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648 - if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) { - i64 = i; - use64bit = true; - break; - } - } - i = i * 10 + static_cast(s.TakePush() - '0'); - significandDigit++; - } - else - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295 - if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) { - i64 = i; - use64bit = true; - break; - } - } - i = i * 10 + static_cast(s.TakePush() - '0'); - significandDigit++; - } - } - // Parse NaN or Infinity here - else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) { - if (Consume(s, 'N')) { - if (Consume(s, 'a') && Consume(s, 'N')) { - d = std::numeric_limits::quiet_NaN(); - useNanOrInf = true; - } - } - else if (RAPIDJSON_LIKELY(Consume(s, 'I'))) { - if (Consume(s, 'n') && Consume(s, 'f')) { - d = (minus ? -std::numeric_limits::infinity() : std::numeric_limits::infinity()); - useNanOrInf = true; - - if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n') - && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) { - RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); - } - } - } - - if (RAPIDJSON_UNLIKELY(!useNanOrInf)) { - RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); - } - } - else - RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); - - // Parse 64bit int - bool useDouble = false; - if (use64bit) { - if (minus) - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808 - if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) { - d = static_cast(i64); - useDouble = true; - break; - } - i64 = i64 * 10 + static_cast(s.TakePush() - '0'); - significandDigit++; - } - else - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615 - if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) { - d = static_cast(i64); - useDouble = true; - break; - } - i64 = i64 * 10 + static_cast(s.TakePush() - '0'); - significandDigit++; - } - } - - // Force double for big integer - if (useDouble) { - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - d = d * 10 + (s.TakePush() - '0'); - } - } - - // Parse frac = decimal-point 1*DIGIT - int expFrac = 0; - size_t decimalPosition; - if (Consume(s, '.')) { - decimalPosition = s.Length(); - - if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9'))) - RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell()); - - if (!useDouble) { -#if RAPIDJSON_64BIT - // Use i64 to store significand in 64-bit architecture - if (!use64bit) - i64 = i; - - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path - break; - else { - i64 = i64 * 10 + static_cast(s.TakePush() - '0'); - --expFrac; - if (i64 != 0) - significandDigit++; - } - } - - d = static_cast(i64); -#else - // Use double to store significand in 32-bit architecture - d = static_cast(use64bit ? i64 : i); -#endif - useDouble = true; - } - - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - if (significandDigit < 17) { - d = d * 10.0 + (s.TakePush() - '0'); - --expFrac; - if (RAPIDJSON_LIKELY(d > 0.0)) - significandDigit++; - } - else - s.TakePush(); - } - } - else - decimalPosition = s.Length(); // decimal position at the end of integer. - - // Parse exp = e [ minus / plus ] 1*DIGIT - int exp = 0; - if (Consume(s, 'e') || Consume(s, 'E')) { - if (!useDouble) { - d = static_cast(use64bit ? i64 : i); - useDouble = true; - } - - bool expMinus = false; - if (Consume(s, '+')) - ; - else if (Consume(s, '-')) - expMinus = true; - - if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - exp = static_cast(s.Take() - '0'); - if (expMinus) { - // (exp + expFrac) must not underflow int => we're detecting when -exp gets - // dangerously close to INT_MIN (a pessimistic next digit 9 would push it into - // underflow territory): - // - // -(exp * 10 + 9) + expFrac >= INT_MIN - // <=> exp <= (expFrac - INT_MIN - 9) / 10 - RAPIDJSON_ASSERT(expFrac <= 0); - int maxExp = (expFrac + 2147483639) / 10; - - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - exp = exp * 10 + static_cast(s.Take() - '0'); - if (RAPIDJSON_UNLIKELY(exp > maxExp)) { - while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent - s.Take(); - } - } - } - else { // positive exp - int maxExp = 308 - expFrac; - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - exp = exp * 10 + static_cast(s.Take() - '0'); - if (RAPIDJSON_UNLIKELY(exp > maxExp)) - RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset); - } - } - } - else - RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell()); - - if (expMinus) - exp = -exp; - } - - // Finish parsing, call event according to the type of number. - bool cont = true; - - if (parseFlags & kParseNumbersAsStringsFlag) { - if (parseFlags & kParseInsituFlag) { - s.Pop(); // Pop stack no matter if it will be used or not. - typename InputStream::Ch* head = is.PutBegin(); - const size_t length = s.Tell() - startOffset; - RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); - // unable to insert the \0 character here, it will erase the comma after this number - const typename TargetEncoding::Ch* const str = reinterpret_cast(head); - cont = handler.RawNumber(str, SizeType(length), false); - } - else { - SizeType numCharsToCopy = static_cast(s.Length()); - StringStream srcStream(s.Pop()); - StackStream dstStream(stack_); - while (numCharsToCopy--) { - Transcoder, TargetEncoding>::Transcode(srcStream, dstStream); - } - dstStream.Put('\0'); - const typename TargetEncoding::Ch* str = dstStream.Pop(); - const SizeType length = static_cast(dstStream.Length()) - 1; - cont = handler.RawNumber(str, SizeType(length), true); - } - } - else { - size_t length = s.Length(); - const char* decimal = s.Pop(); // Pop stack no matter if it will be used or not. - - if (useDouble) { - int p = exp + expFrac; - if (parseFlags & kParseFullPrecisionFlag) - d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp); - else - d = internal::StrtodNormalPrecision(d, p); - - // Use > max, instead of == inf, to fix bogus warning -Wfloat-equal - if (d > (std::numeric_limits::max)()) { - // Overflow - // TODO: internal::StrtodX should report overflow (or underflow) - RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset); - } - - cont = handler.Double(minus ? -d : d); - } - else if (useNanOrInf) { - cont = handler.Double(d); - } - else { - if (use64bit) { - if (minus) - cont = handler.Int64(static_cast(~i64 + 1)); - else - cont = handler.Uint64(i64); - } - else { - if (minus) - cont = handler.Int(static_cast(~i + 1)); - else - cont = handler.Uint(i); - } - } - } - if (RAPIDJSON_UNLIKELY(!cont)) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, startOffset); - } - - // Parse any JSON value - template - void ParseValue(InputStream& is, Handler& handler) { - switch (is.Peek()) { - case 'n': ParseNull (is, handler); break; - case 't': ParseTrue (is, handler); break; - case 'f': ParseFalse (is, handler); break; - case '"': ParseString(is, handler); break; - case '{': ParseObject(is, handler); break; - case '[': ParseArray (is, handler); break; - default : - ParseNumber(is, handler); - break; - - } - } - - // Iterative Parsing - - // States - enum IterativeParsingState { - IterativeParsingFinishState = 0, // sink states at top - IterativeParsingErrorState, // sink states at top - IterativeParsingStartState, - - // Object states - IterativeParsingObjectInitialState, - IterativeParsingMemberKeyState, - IterativeParsingMemberValueState, - IterativeParsingObjectFinishState, - - // Array states - IterativeParsingArrayInitialState, - IterativeParsingElementState, - IterativeParsingArrayFinishState, - - // Single value state - IterativeParsingValueState, - - // Delimiter states (at bottom) - IterativeParsingElementDelimiterState, - IterativeParsingMemberDelimiterState, - IterativeParsingKeyValueDelimiterState, - - cIterativeParsingStateCount - }; - - // Tokens - enum Token { - LeftBracketToken = 0, - RightBracketToken, - - LeftCurlyBracketToken, - RightCurlyBracketToken, - - CommaToken, - ColonToken, - - StringToken, - FalseToken, - TrueToken, - NullToken, - NumberToken, - - kTokenCount - }; - - RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) const { - -//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN -#define N NumberToken -#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N - // Maps from ASCII to Token - static const unsigned char tokenMap[256] = { - N16, // 00~0F - N16, // 10~1F - N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F - N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F - N16, // 40~4F - N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F - N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F - N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F - N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF - }; -#undef N -#undef N16 -//!@endcond - - if (sizeof(Ch) == 1 || static_cast(c) < 256) - return static_cast(tokenMap[static_cast(c)]); - else - return NumberToken; - } - - RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) const { - // current state x one lookahead token -> new state - static const char G[cIterativeParsingStateCount][kTokenCount] = { - // Finish(sink state) - { - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState - }, - // Error(sink state) - { - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState - }, - // Start - { - IterativeParsingArrayInitialState, // Left bracket - IterativeParsingErrorState, // Right bracket - IterativeParsingObjectInitialState, // Left curly bracket - IterativeParsingErrorState, // Right curly bracket - IterativeParsingErrorState, // Comma - IterativeParsingErrorState, // Colon - IterativeParsingValueState, // String - IterativeParsingValueState, // False - IterativeParsingValueState, // True - IterativeParsingValueState, // Null - IterativeParsingValueState // Number - }, - // ObjectInitial - { - IterativeParsingErrorState, // Left bracket - IterativeParsingErrorState, // Right bracket - IterativeParsingErrorState, // Left curly bracket - IterativeParsingObjectFinishState, // Right curly bracket - IterativeParsingErrorState, // Comma - IterativeParsingErrorState, // Colon - IterativeParsingMemberKeyState, // String - IterativeParsingErrorState, // False - IterativeParsingErrorState, // True - IterativeParsingErrorState, // Null - IterativeParsingErrorState // Number - }, - // MemberKey - { - IterativeParsingErrorState, // Left bracket - IterativeParsingErrorState, // Right bracket - IterativeParsingErrorState, // Left curly bracket - IterativeParsingErrorState, // Right curly bracket - IterativeParsingErrorState, // Comma - IterativeParsingKeyValueDelimiterState, // Colon - IterativeParsingErrorState, // String - IterativeParsingErrorState, // False - IterativeParsingErrorState, // True - IterativeParsingErrorState, // Null - IterativeParsingErrorState // Number - }, - // MemberValue - { - IterativeParsingErrorState, // Left bracket - IterativeParsingErrorState, // Right bracket - IterativeParsingErrorState, // Left curly bracket - IterativeParsingObjectFinishState, // Right curly bracket - IterativeParsingMemberDelimiterState, // Comma - IterativeParsingErrorState, // Colon - IterativeParsingErrorState, // String - IterativeParsingErrorState, // False - IterativeParsingErrorState, // True - IterativeParsingErrorState, // Null - IterativeParsingErrorState // Number - }, - // ObjectFinish(sink state) - { - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState - }, - // ArrayInitial - { - IterativeParsingArrayInitialState, // Left bracket(push Element state) - IterativeParsingArrayFinishState, // Right bracket - IterativeParsingObjectInitialState, // Left curly bracket(push Element state) - IterativeParsingErrorState, // Right curly bracket - IterativeParsingErrorState, // Comma - IterativeParsingErrorState, // Colon - IterativeParsingElementState, // String - IterativeParsingElementState, // False - IterativeParsingElementState, // True - IterativeParsingElementState, // Null - IterativeParsingElementState // Number - }, - // Element - { - IterativeParsingErrorState, // Left bracket - IterativeParsingArrayFinishState, // Right bracket - IterativeParsingErrorState, // Left curly bracket - IterativeParsingErrorState, // Right curly bracket - IterativeParsingElementDelimiterState, // Comma - IterativeParsingErrorState, // Colon - IterativeParsingErrorState, // String - IterativeParsingErrorState, // False - IterativeParsingErrorState, // True - IterativeParsingErrorState, // Null - IterativeParsingErrorState // Number - }, - // ArrayFinish(sink state) - { - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState - }, - // Single Value (sink state) - { - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState - }, - // ElementDelimiter - { - IterativeParsingArrayInitialState, // Left bracket(push Element state) - IterativeParsingArrayFinishState, // Right bracket - IterativeParsingObjectInitialState, // Left curly bracket(push Element state) - IterativeParsingErrorState, // Right curly bracket - IterativeParsingErrorState, // Comma - IterativeParsingErrorState, // Colon - IterativeParsingElementState, // String - IterativeParsingElementState, // False - IterativeParsingElementState, // True - IterativeParsingElementState, // Null - IterativeParsingElementState // Number - }, - // MemberDelimiter - { - IterativeParsingErrorState, // Left bracket - IterativeParsingErrorState, // Right bracket - IterativeParsingErrorState, // Left curly bracket - IterativeParsingObjectFinishState, // Right curly bracket - IterativeParsingErrorState, // Comma - IterativeParsingErrorState, // Colon - IterativeParsingMemberKeyState, // String - IterativeParsingErrorState, // False - IterativeParsingErrorState, // True - IterativeParsingErrorState, // Null - IterativeParsingErrorState // Number - }, - // KeyValueDelimiter - { - IterativeParsingArrayInitialState, // Left bracket(push MemberValue state) - IterativeParsingErrorState, // Right bracket - IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state) - IterativeParsingErrorState, // Right curly bracket - IterativeParsingErrorState, // Comma - IterativeParsingErrorState, // Colon - IterativeParsingMemberValueState, // String - IterativeParsingMemberValueState, // False - IterativeParsingMemberValueState, // True - IterativeParsingMemberValueState, // Null - IterativeParsingMemberValueState // Number - }, - }; // End of G - - return static_cast(G[state][token]); - } - - // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit(). - // May return a new state on state pop. - template - RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) { - (void)token; - - switch (dst) { - case IterativeParsingErrorState: - return dst; - - case IterativeParsingObjectInitialState: - case IterativeParsingArrayInitialState: - { - // Push the state(Element or MemeberValue) if we are nested in another array or value of member. - // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop. - IterativeParsingState n = src; - if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState) - n = IterativeParsingElementState; - else if (src == IterativeParsingKeyValueDelimiterState) - n = IterativeParsingMemberValueState; - // Push current state. - *stack_.template Push(1) = n; - // Initialize and push the member/element count. - *stack_.template Push(1) = 0; - // Call handler - bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray(); - // On handler short circuits the parsing. - if (!hr) { - RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); - return IterativeParsingErrorState; - } - else { - is.Take(); - return dst; - } - } - - case IterativeParsingMemberKeyState: - ParseString(is, handler, true); - if (HasParseError()) - return IterativeParsingErrorState; - else - return dst; - - case IterativeParsingKeyValueDelimiterState: - RAPIDJSON_ASSERT(token == ColonToken); - is.Take(); - return dst; - - case IterativeParsingMemberValueState: - // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. - ParseValue(is, handler); - if (HasParseError()) { - return IterativeParsingErrorState; - } - return dst; - - case IterativeParsingElementState: - // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. - ParseValue(is, handler); - if (HasParseError()) { - return IterativeParsingErrorState; - } - return dst; - - case IterativeParsingMemberDelimiterState: - case IterativeParsingElementDelimiterState: - is.Take(); - // Update member/element count. - *stack_.template Top() = *stack_.template Top() + 1; - return dst; - - case IterativeParsingObjectFinishState: - { - // Transit from delimiter is only allowed when trailing commas are enabled - if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) { - RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell()); - return IterativeParsingErrorState; - } - // Get member count. - SizeType c = *stack_.template Pop(1); - // If the object is not empty, count the last member. - if (src == IterativeParsingMemberValueState) - ++c; - // Restore the state. - IterativeParsingState n = static_cast(*stack_.template Pop(1)); - // Transit to Finish state if this is the topmost scope. - if (n == IterativeParsingStartState) - n = IterativeParsingFinishState; - // Call handler - bool hr = handler.EndObject(c); - // On handler short circuits the parsing. - if (!hr) { - RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); - return IterativeParsingErrorState; - } - else { - is.Take(); - return n; - } - } - - case IterativeParsingArrayFinishState: - { - // Transit from delimiter is only allowed when trailing commas are enabled - if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) { - RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell()); - return IterativeParsingErrorState; - } - // Get element count. - SizeType c = *stack_.template Pop(1); - // If the array is not empty, count the last element. - if (src == IterativeParsingElementState) - ++c; - // Restore the state. - IterativeParsingState n = static_cast(*stack_.template Pop(1)); - // Transit to Finish state if this is the topmost scope. - if (n == IterativeParsingStartState) - n = IterativeParsingFinishState; - // Call handler - bool hr = handler.EndArray(c); - // On handler short circuits the parsing. - if (!hr) { - RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); - return IterativeParsingErrorState; - } - else { - is.Take(); - return n; - } - } - - default: - // This branch is for IterativeParsingValueState actually. - // Use `default:` rather than - // `case IterativeParsingValueState:` is for code coverage. - - // The IterativeParsingStartState is not enumerated in this switch-case. - // It is impossible for that case. And it can be caught by following assertion. - - // The IterativeParsingFinishState is not enumerated in this switch-case either. - // It is a "derivative" state which cannot triggered from Predict() directly. - // Therefore it cannot happen here. And it can be caught by following assertion. - RAPIDJSON_ASSERT(dst == IterativeParsingValueState); - - // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. - ParseValue(is, handler); - if (HasParseError()) { - return IterativeParsingErrorState; - } - return IterativeParsingFinishState; - } - } - - template - void HandleError(IterativeParsingState src, InputStream& is) { - if (HasParseError()) { - // Error flag has been set. - return; - } - - switch (src) { - case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return; - case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return; - case IterativeParsingObjectInitialState: - case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return; - case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return; - case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return; - case IterativeParsingKeyValueDelimiterState: - case IterativeParsingArrayInitialState: - case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return; - default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return; - } - } - - RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) const { - return s >= IterativeParsingElementDelimiterState; - } - - RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) const { - return s <= IterativeParsingErrorState; - } - - template - ParseResult IterativeParse(InputStream& is, Handler& handler) { - parseResult_.Clear(); - ClearStackOnExit scope(*this); - IterativeParsingState state = IterativeParsingStartState; - - SkipWhitespaceAndComments(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); - while (is.Peek() != '\0') { - Token t = Tokenize(is.Peek()); - IterativeParsingState n = Predict(state, t); - IterativeParsingState d = Transit(state, t, n, is, handler); - - if (d == IterativeParsingErrorState) { - HandleError(state, is); - break; - } - - state = d; - - // Do not further consume streams if a root JSON has been parsed. - if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState) - break; - - SkipWhitespaceAndComments(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); - } - - // Handle the end of file. - if (state != IterativeParsingFinishState) - HandleError(state, is); - - return parseResult_; - } - - static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string. - internal::Stack stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing. - ParseResult parseResult_; - IterativeParsingState state_; -}; // class GenericReader - -//! Reader with UTF8 encoding and default allocator. -typedef GenericReader, UTF8<> > Reader; - -RAPIDJSON_NAMESPACE_END - -#if defined(__clang__) || defined(_MSC_VER) -RAPIDJSON_DIAG_POP -#endif - - -#ifdef __GNUC__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_READER_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/schema.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/schema.h deleted file mode 100644 index fc39d06c..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/schema.h +++ /dev/null @@ -1,2496 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available-> -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip-> All rights reserved-> -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License-> You may obtain a copy of the License at -// -// http://opensource->org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied-> See the License for the -// specific language governing permissions and limitations under the License-> - -#ifndef RAPIDJSON_SCHEMA_H_ -#define RAPIDJSON_SCHEMA_H_ - -#include "document.h" -#include "pointer.h" -#include "stringbuffer.h" -#include // abs, floor - -#if !defined(RAPIDJSON_SCHEMA_USE_INTERNALREGEX) -#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1 -#else -#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 0 -#endif - -#if !RAPIDJSON_SCHEMA_USE_INTERNALREGEX && defined(RAPIDJSON_SCHEMA_USE_STDREGEX) && (__cplusplus >=201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)) -#define RAPIDJSON_SCHEMA_USE_STDREGEX 1 -#else -#define RAPIDJSON_SCHEMA_USE_STDREGEX 0 -#endif - -#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX -#include "internal/regex.h" -#elif RAPIDJSON_SCHEMA_USE_STDREGEX -#include -#endif - -#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX || RAPIDJSON_SCHEMA_USE_STDREGEX -#define RAPIDJSON_SCHEMA_HAS_REGEX 1 -#else -#define RAPIDJSON_SCHEMA_HAS_REGEX 0 -#endif - -#ifndef RAPIDJSON_SCHEMA_VERBOSE -#define RAPIDJSON_SCHEMA_VERBOSE 0 -#endif - -#if RAPIDJSON_SCHEMA_VERBOSE -#include "stringbuffer.h" -#endif - -RAPIDJSON_DIAG_PUSH - -#if defined(__GNUC__) -RAPIDJSON_DIAG_OFF(effc++) -#endif - -#ifdef __clang__ -RAPIDJSON_DIAG_OFF(weak-vtables) -RAPIDJSON_DIAG_OFF(exit-time-destructors) -RAPIDJSON_DIAG_OFF(c++98-compat-pedantic) -RAPIDJSON_DIAG_OFF(variadic-macros) -#elif defined(_MSC_VER) -RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -/////////////////////////////////////////////////////////////////////////////// -// Verbose Utilities - -#if RAPIDJSON_SCHEMA_VERBOSE - -namespace internal { - -inline void PrintInvalidKeyword(const char* keyword) { - printf("Fail keyword: %s\n", keyword); -} - -inline void PrintInvalidKeyword(const wchar_t* keyword) { - wprintf(L"Fail keyword: %ls\n", keyword); -} - -inline void PrintInvalidDocument(const char* document) { - printf("Fail document: %s\n\n", document); -} - -inline void PrintInvalidDocument(const wchar_t* document) { - wprintf(L"Fail document: %ls\n\n", document); -} - -inline void PrintValidatorPointers(unsigned depth, const char* s, const char* d) { - printf("S: %*s%s\nD: %*s%s\n\n", depth * 4, " ", s, depth * 4, " ", d); -} - -inline void PrintValidatorPointers(unsigned depth, const wchar_t* s, const wchar_t* d) { - wprintf(L"S: %*ls%ls\nD: %*ls%ls\n\n", depth * 4, L" ", s, depth * 4, L" ", d); -} - -} // namespace internal - -#endif // RAPIDJSON_SCHEMA_VERBOSE - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_INVALID_KEYWORD_RETURN - -#if RAPIDJSON_SCHEMA_VERBOSE -#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) internal::PrintInvalidKeyword(keyword) -#else -#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) -#endif - -#define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)\ -RAPIDJSON_MULTILINEMACRO_BEGIN\ - context.invalidKeyword = keyword.GetString();\ - RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword.GetString());\ - return false;\ -RAPIDJSON_MULTILINEMACRO_END - -/////////////////////////////////////////////////////////////////////////////// -// Forward declarations - -template -class GenericSchemaDocument; - -namespace internal { - -template -class Schema; - -/////////////////////////////////////////////////////////////////////////////// -// ISchemaValidator - -class ISchemaValidator { -public: - virtual ~ISchemaValidator() {} - virtual bool IsValid() const = 0; -}; - -/////////////////////////////////////////////////////////////////////////////// -// ISchemaStateFactory - -template -class ISchemaStateFactory { -public: - virtual ~ISchemaStateFactory() {} - virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&) = 0; - virtual void DestroySchemaValidator(ISchemaValidator* validator) = 0; - virtual void* CreateHasher() = 0; - virtual uint64_t GetHashCode(void* hasher) = 0; - virtual void DestroryHasher(void* hasher) = 0; - virtual void* MallocState(size_t size) = 0; - virtual void FreeState(void* p) = 0; -}; - -/////////////////////////////////////////////////////////////////////////////// -// IValidationErrorHandler - -template -class IValidationErrorHandler { -public: - typedef typename SchemaType::Ch Ch; - typedef typename SchemaType::SValue SValue; - - virtual ~IValidationErrorHandler() {} - - virtual void NotMultipleOf(int64_t actual, const SValue& expected) = 0; - virtual void NotMultipleOf(uint64_t actual, const SValue& expected) = 0; - virtual void NotMultipleOf(double actual, const SValue& expected) = 0; - virtual void AboveMaximum(int64_t actual, const SValue& expected, bool exclusive) = 0; - virtual void AboveMaximum(uint64_t actual, const SValue& expected, bool exclusive) = 0; - virtual void AboveMaximum(double actual, const SValue& expected, bool exclusive) = 0; - virtual void BelowMinimum(int64_t actual, const SValue& expected, bool exclusive) = 0; - virtual void BelowMinimum(uint64_t actual, const SValue& expected, bool exclusive) = 0; - virtual void BelowMinimum(double actual, const SValue& expected, bool exclusive) = 0; - - virtual void TooLong(const Ch* str, SizeType length, SizeType expected) = 0; - virtual void TooShort(const Ch* str, SizeType length, SizeType expected) = 0; - virtual void DoesNotMatch(const Ch* str, SizeType length) = 0; - - virtual void DisallowedItem(SizeType index) = 0; - virtual void TooFewItems(SizeType actualCount, SizeType expectedCount) = 0; - virtual void TooManyItems(SizeType actualCount, SizeType expectedCount) = 0; - virtual void DuplicateItems(SizeType index1, SizeType index2) = 0; - - virtual void TooManyProperties(SizeType actualCount, SizeType expectedCount) = 0; - virtual void TooFewProperties(SizeType actualCount, SizeType expectedCount) = 0; - virtual void StartMissingProperties() = 0; - virtual void AddMissingProperty(const SValue& name) = 0; - virtual bool EndMissingProperties() = 0; - virtual void PropertyViolations(ISchemaValidator** subvalidators, SizeType count) = 0; - virtual void DisallowedProperty(const Ch* name, SizeType length) = 0; - - virtual void StartDependencyErrors() = 0; - virtual void StartMissingDependentProperties() = 0; - virtual void AddMissingDependentProperty(const SValue& targetName) = 0; - virtual void EndMissingDependentProperties(const SValue& sourceName) = 0; - virtual void AddDependencySchemaError(const SValue& souceName, ISchemaValidator* subvalidator) = 0; - virtual bool EndDependencyErrors() = 0; - - virtual void DisallowedValue() = 0; - virtual void StartDisallowedType() = 0; - virtual void AddExpectedType(const typename SchemaType::ValueType& expectedType) = 0; - virtual void EndDisallowedType(const typename SchemaType::ValueType& actualType) = 0; - virtual void NotAllOf(ISchemaValidator** subvalidators, SizeType count) = 0; - virtual void NoneOf(ISchemaValidator** subvalidators, SizeType count) = 0; - virtual void NotOneOf(ISchemaValidator** subvalidators, SizeType count) = 0; - virtual void Disallowed() = 0; -}; - - -/////////////////////////////////////////////////////////////////////////////// -// Hasher - -// For comparison of compound value -template -class Hasher { -public: - typedef typename Encoding::Ch Ch; - - Hasher(Allocator* allocator = 0, size_t stackCapacity = kDefaultSize) : stack_(allocator, stackCapacity) {} - - bool Null() { return WriteType(kNullType); } - bool Bool(bool b) { return WriteType(b ? kTrueType : kFalseType); } - bool Int(int i) { Number n; n.u.i = i; n.d = static_cast(i); return WriteNumber(n); } - bool Uint(unsigned u) { Number n; n.u.u = u; n.d = static_cast(u); return WriteNumber(n); } - bool Int64(int64_t i) { Number n; n.u.i = i; n.d = static_cast(i); return WriteNumber(n); } - bool Uint64(uint64_t u) { Number n; n.u.u = u; n.d = static_cast(u); return WriteNumber(n); } - bool Double(double d) { - Number n; - if (d < 0) n.u.i = static_cast(d); - else n.u.u = static_cast(d); - n.d = d; - return WriteNumber(n); - } - - bool RawNumber(const Ch* str, SizeType len, bool) { - WriteBuffer(kNumberType, str, len * sizeof(Ch)); - return true; - } - - bool String(const Ch* str, SizeType len, bool) { - WriteBuffer(kStringType, str, len * sizeof(Ch)); - return true; - } - - bool StartObject() { return true; } - bool Key(const Ch* str, SizeType len, bool copy) { return String(str, len, copy); } - bool EndObject(SizeType memberCount) { - uint64_t h = Hash(0, kObjectType); - uint64_t* kv = stack_.template Pop(memberCount * 2); - for (SizeType i = 0; i < memberCount; i++) - h ^= Hash(kv[i * 2], kv[i * 2 + 1]); // Use xor to achieve member order insensitive - *stack_.template Push() = h; - return true; - } - - bool StartArray() { return true; } - bool EndArray(SizeType elementCount) { - uint64_t h = Hash(0, kArrayType); - uint64_t* e = stack_.template Pop(elementCount); - for (SizeType i = 0; i < elementCount; i++) - h = Hash(h, e[i]); // Use hash to achieve element order sensitive - *stack_.template Push() = h; - return true; - } - - bool IsValid() const { return stack_.GetSize() == sizeof(uint64_t); } - - uint64_t GetHashCode() const { - RAPIDJSON_ASSERT(IsValid()); - return *stack_.template Top(); - } - -private: - static const size_t kDefaultSize = 256; - struct Number { - union U { - uint64_t u; - int64_t i; - }u; - double d; - }; - - bool WriteType(Type type) { return WriteBuffer(type, 0, 0); } - - bool WriteNumber(const Number& n) { return WriteBuffer(kNumberType, &n, sizeof(n)); } - - bool WriteBuffer(Type type, const void* data, size_t len) { - // FNV-1a from http://isthe.com/chongo/tech/comp/fnv/ - uint64_t h = Hash(RAPIDJSON_UINT64_C2(0x84222325, 0xcbf29ce4), type); - const unsigned char* d = static_cast(data); - for (size_t i = 0; i < len; i++) - h = Hash(h, d[i]); - *stack_.template Push() = h; - return true; - } - - static uint64_t Hash(uint64_t h, uint64_t d) { - static const uint64_t kPrime = RAPIDJSON_UINT64_C2(0x00000100, 0x000001b3); - h ^= d; - h *= kPrime; - return h; - } - - Stack stack_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// SchemaValidationContext - -template -struct SchemaValidationContext { - typedef Schema SchemaType; - typedef ISchemaStateFactory SchemaValidatorFactoryType; - typedef IValidationErrorHandler ErrorHandlerType; - typedef typename SchemaType::ValueType ValueType; - typedef typename ValueType::Ch Ch; - - enum PatternValidatorType { - kPatternValidatorOnly, - kPatternValidatorWithProperty, - kPatternValidatorWithAdditionalProperty - }; - - SchemaValidationContext(SchemaValidatorFactoryType& f, ErrorHandlerType& eh, const SchemaType* s) : - factory(f), - error_handler(eh), - schema(s), - valueSchema(), - invalidKeyword(), - hasher(), - arrayElementHashCodes(), - validators(), - validatorCount(), - patternPropertiesValidators(), - patternPropertiesValidatorCount(), - patternPropertiesSchemas(), - patternPropertiesSchemaCount(), - valuePatternValidatorType(kPatternValidatorOnly), - propertyExist(), - inArray(false), - valueUniqueness(false), - arrayUniqueness(false) - { - } - - ~SchemaValidationContext() { - if (hasher) - factory.DestroryHasher(hasher); - if (validators) { - for (SizeType i = 0; i < validatorCount; i++) - factory.DestroySchemaValidator(validators[i]); - factory.FreeState(validators); - } - if (patternPropertiesValidators) { - for (SizeType i = 0; i < patternPropertiesValidatorCount; i++) - factory.DestroySchemaValidator(patternPropertiesValidators[i]); - factory.FreeState(patternPropertiesValidators); - } - if (patternPropertiesSchemas) - factory.FreeState(patternPropertiesSchemas); - if (propertyExist) - factory.FreeState(propertyExist); - } - - SchemaValidatorFactoryType& factory; - ErrorHandlerType& error_handler; - const SchemaType* schema; - const SchemaType* valueSchema; - const Ch* invalidKeyword; - void* hasher; // Only validator access - void* arrayElementHashCodes; // Only validator access this - ISchemaValidator** validators; - SizeType validatorCount; - ISchemaValidator** patternPropertiesValidators; - SizeType patternPropertiesValidatorCount; - const SchemaType** patternPropertiesSchemas; - SizeType patternPropertiesSchemaCount; - PatternValidatorType valuePatternValidatorType; - PatternValidatorType objectPatternValidatorType; - SizeType arrayElementIndex; - bool* propertyExist; - bool inArray; - bool valueUniqueness; - bool arrayUniqueness; -}; - -/////////////////////////////////////////////////////////////////////////////// -// Schema - -template -class Schema { -public: - typedef typename SchemaDocumentType::ValueType ValueType; - typedef typename SchemaDocumentType::AllocatorType AllocatorType; - typedef typename SchemaDocumentType::PointerType PointerType; - typedef typename ValueType::EncodingType EncodingType; - typedef typename EncodingType::Ch Ch; - typedef SchemaValidationContext Context; - typedef Schema SchemaType; - typedef GenericValue SValue; - typedef IValidationErrorHandler ErrorHandler; - friend class GenericSchemaDocument; - - Schema(SchemaDocumentType* schemaDocument, const PointerType& p, const ValueType& value, const ValueType& document, AllocatorType* allocator) : - allocator_(allocator), - uri_(schemaDocument->GetURI(), *allocator), - pointer_(p, allocator), - typeless_(schemaDocument->GetTypeless()), - enum_(), - enumCount_(), - not_(), - type_((1 << kTotalSchemaType) - 1), // typeless - validatorCount_(), - notValidatorIndex_(), - properties_(), - additionalPropertiesSchema_(), - patternProperties_(), - patternPropertyCount_(), - propertyCount_(), - minProperties_(), - maxProperties_(SizeType(~0)), - additionalProperties_(true), - hasDependencies_(), - hasRequired_(), - hasSchemaDependencies_(), - additionalItemsSchema_(), - itemsList_(), - itemsTuple_(), - itemsTupleCount_(), - minItems_(), - maxItems_(SizeType(~0)), - additionalItems_(true), - uniqueItems_(false), - pattern_(), - minLength_(0), - maxLength_(~SizeType(0)), - exclusiveMinimum_(false), - exclusiveMaximum_(false), - defaultValueLength_(0) - { - typedef typename ValueType::ConstValueIterator ConstValueIterator; - typedef typename ValueType::ConstMemberIterator ConstMemberIterator; - - if (!value.IsObject()) - return; - - if (const ValueType* v = GetMember(value, GetTypeString())) { - type_ = 0; - if (v->IsString()) - AddType(*v); - else if (v->IsArray()) - for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) - AddType(*itr); - } - - if (const ValueType* v = GetMember(value, GetEnumString())) - if (v->IsArray() && v->Size() > 0) { - enum_ = static_cast(allocator_->Malloc(sizeof(uint64_t) * v->Size())); - for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) { - typedef Hasher > EnumHasherType; - char buffer[256u + 24]; - MemoryPoolAllocator<> hasherAllocator(buffer, sizeof(buffer)); - EnumHasherType h(&hasherAllocator, 256); - itr->Accept(h); - enum_[enumCount_++] = h.GetHashCode(); - } - } - - if (schemaDocument) { - AssignIfExist(allOf_, *schemaDocument, p, value, GetAllOfString(), document); - AssignIfExist(anyOf_, *schemaDocument, p, value, GetAnyOfString(), document); - AssignIfExist(oneOf_, *schemaDocument, p, value, GetOneOfString(), document); - } - - if (const ValueType* v = GetMember(value, GetNotString())) { - schemaDocument->CreateSchema(¬_, p.Append(GetNotString(), allocator_), *v, document); - notValidatorIndex_ = validatorCount_; - validatorCount_++; - } - - // Object - - const ValueType* properties = GetMember(value, GetPropertiesString()); - const ValueType* required = GetMember(value, GetRequiredString()); - const ValueType* dependencies = GetMember(value, GetDependenciesString()); - { - // Gather properties from properties/required/dependencies - SValue allProperties(kArrayType); - - if (properties && properties->IsObject()) - for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) - AddUniqueElement(allProperties, itr->name); - - if (required && required->IsArray()) - for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr) - if (itr->IsString()) - AddUniqueElement(allProperties, *itr); - - if (dependencies && dependencies->IsObject()) - for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) { - AddUniqueElement(allProperties, itr->name); - if (itr->value.IsArray()) - for (ConstValueIterator i = itr->value.Begin(); i != itr->value.End(); ++i) - if (i->IsString()) - AddUniqueElement(allProperties, *i); - } - - if (allProperties.Size() > 0) { - propertyCount_ = allProperties.Size(); - properties_ = static_cast(allocator_->Malloc(sizeof(Property) * propertyCount_)); - for (SizeType i = 0; i < propertyCount_; i++) { - new (&properties_[i]) Property(); - properties_[i].name = allProperties[i]; - properties_[i].schema = typeless_; - } - } - } - - if (properties && properties->IsObject()) { - PointerType q = p.Append(GetPropertiesString(), allocator_); - for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) { - SizeType index; - if (FindPropertyIndex(itr->name, &index)) - schemaDocument->CreateSchema(&properties_[index].schema, q.Append(itr->name, allocator_), itr->value, document); - } - } - - if (const ValueType* v = GetMember(value, GetPatternPropertiesString())) { - PointerType q = p.Append(GetPatternPropertiesString(), allocator_); - patternProperties_ = static_cast(allocator_->Malloc(sizeof(PatternProperty) * v->MemberCount())); - patternPropertyCount_ = 0; - - for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) { - new (&patternProperties_[patternPropertyCount_]) PatternProperty(); - patternProperties_[patternPropertyCount_].pattern = CreatePattern(itr->name); - schemaDocument->CreateSchema(&patternProperties_[patternPropertyCount_].schema, q.Append(itr->name, allocator_), itr->value, document); - patternPropertyCount_++; - } - } - - if (required && required->IsArray()) - for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr) - if (itr->IsString()) { - SizeType index; - if (FindPropertyIndex(*itr, &index)) { - properties_[index].required = true; - hasRequired_ = true; - } - } - - if (dependencies && dependencies->IsObject()) { - PointerType q = p.Append(GetDependenciesString(), allocator_); - hasDependencies_ = true; - for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) { - SizeType sourceIndex; - if (FindPropertyIndex(itr->name, &sourceIndex)) { - if (itr->value.IsArray()) { - properties_[sourceIndex].dependencies = static_cast(allocator_->Malloc(sizeof(bool) * propertyCount_)); - std::memset(properties_[sourceIndex].dependencies, 0, sizeof(bool)* propertyCount_); - for (ConstValueIterator targetItr = itr->value.Begin(); targetItr != itr->value.End(); ++targetItr) { - SizeType targetIndex; - if (FindPropertyIndex(*targetItr, &targetIndex)) - properties_[sourceIndex].dependencies[targetIndex] = true; - } - } - else if (itr->value.IsObject()) { - hasSchemaDependencies_ = true; - schemaDocument->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name, allocator_), itr->value, document); - properties_[sourceIndex].dependenciesValidatorIndex = validatorCount_; - validatorCount_++; - } - } - } - } - - if (const ValueType* v = GetMember(value, GetAdditionalPropertiesString())) { - if (v->IsBool()) - additionalProperties_ = v->GetBool(); - else if (v->IsObject()) - schemaDocument->CreateSchema(&additionalPropertiesSchema_, p.Append(GetAdditionalPropertiesString(), allocator_), *v, document); - } - - AssignIfExist(minProperties_, value, GetMinPropertiesString()); - AssignIfExist(maxProperties_, value, GetMaxPropertiesString()); - - // Array - if (const ValueType* v = GetMember(value, GetItemsString())) { - PointerType q = p.Append(GetItemsString(), allocator_); - if (v->IsObject()) // List validation - schemaDocument->CreateSchema(&itemsList_, q, *v, document); - else if (v->IsArray()) { // Tuple validation - itemsTuple_ = static_cast(allocator_->Malloc(sizeof(const Schema*) * v->Size())); - SizeType index = 0; - for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++) - schemaDocument->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index, allocator_), *itr, document); - } - } - - AssignIfExist(minItems_, value, GetMinItemsString()); - AssignIfExist(maxItems_, value, GetMaxItemsString()); - - if (const ValueType* v = GetMember(value, GetAdditionalItemsString())) { - if (v->IsBool()) - additionalItems_ = v->GetBool(); - else if (v->IsObject()) - schemaDocument->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString(), allocator_), *v, document); - } - - AssignIfExist(uniqueItems_, value, GetUniqueItemsString()); - - // String - AssignIfExist(minLength_, value, GetMinLengthString()); - AssignIfExist(maxLength_, value, GetMaxLengthString()); - - if (const ValueType* v = GetMember(value, GetPatternString())) - pattern_ = CreatePattern(*v); - - // Number - if (const ValueType* v = GetMember(value, GetMinimumString())) - if (v->IsNumber()) - minimum_.CopyFrom(*v, *allocator_); - - if (const ValueType* v = GetMember(value, GetMaximumString())) - if (v->IsNumber()) - maximum_.CopyFrom(*v, *allocator_); - - AssignIfExist(exclusiveMinimum_, value, GetExclusiveMinimumString()); - AssignIfExist(exclusiveMaximum_, value, GetExclusiveMaximumString()); - - if (const ValueType* v = GetMember(value, GetMultipleOfString())) - if (v->IsNumber() && v->GetDouble() > 0.0) - multipleOf_.CopyFrom(*v, *allocator_); - - // Default - if (const ValueType* v = GetMember(value, GetDefaultValueString())) - if (v->IsString()) - defaultValueLength_ = v->GetStringLength(); - - } - - ~Schema() { - AllocatorType::Free(enum_); - if (properties_) { - for (SizeType i = 0; i < propertyCount_; i++) - properties_[i].~Property(); - AllocatorType::Free(properties_); - } - if (patternProperties_) { - for (SizeType i = 0; i < patternPropertyCount_; i++) - patternProperties_[i].~PatternProperty(); - AllocatorType::Free(patternProperties_); - } - AllocatorType::Free(itemsTuple_); -#if RAPIDJSON_SCHEMA_HAS_REGEX - if (pattern_) { - pattern_->~RegexType(); - AllocatorType::Free(pattern_); - } -#endif - } - - const SValue& GetURI() const { - return uri_; - } - - const PointerType& GetPointer() const { - return pointer_; - } - - bool BeginValue(Context& context) const { - if (context.inArray) { - if (uniqueItems_) - context.valueUniqueness = true; - - if (itemsList_) - context.valueSchema = itemsList_; - else if (itemsTuple_) { - if (context.arrayElementIndex < itemsTupleCount_) - context.valueSchema = itemsTuple_[context.arrayElementIndex]; - else if (additionalItemsSchema_) - context.valueSchema = additionalItemsSchema_; - else if (additionalItems_) - context.valueSchema = typeless_; - else { - context.error_handler.DisallowedItem(context.arrayElementIndex); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetItemsString()); - } - } - else - context.valueSchema = typeless_; - - context.arrayElementIndex++; - } - return true; - } - - RAPIDJSON_FORCEINLINE bool EndValue(Context& context) const { - if (context.patternPropertiesValidatorCount > 0) { - bool otherValid = false; - SizeType count = context.patternPropertiesValidatorCount; - if (context.objectPatternValidatorType != Context::kPatternValidatorOnly) - otherValid = context.patternPropertiesValidators[--count]->IsValid(); - - bool patternValid = true; - for (SizeType i = 0; i < count; i++) - if (!context.patternPropertiesValidators[i]->IsValid()) { - patternValid = false; - break; - } - - if (context.objectPatternValidatorType == Context::kPatternValidatorOnly) { - if (!patternValid) { - context.error_handler.PropertyViolations(context.patternPropertiesValidators, count); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); - } - } - else if (context.objectPatternValidatorType == Context::kPatternValidatorWithProperty) { - if (!patternValid || !otherValid) { - context.error_handler.PropertyViolations(context.patternPropertiesValidators, count + 1); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); - } - } - else if (!patternValid && !otherValid) { // kPatternValidatorWithAdditionalProperty) - context.error_handler.PropertyViolations(context.patternPropertiesValidators, count + 1); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); - } - } - - if (enum_) { - const uint64_t h = context.factory.GetHashCode(context.hasher); - for (SizeType i = 0; i < enumCount_; i++) - if (enum_[i] == h) - goto foundEnum; - context.error_handler.DisallowedValue(); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetEnumString()); - foundEnum:; - } - - if (allOf_.schemas) - for (SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++) - if (!context.validators[i]->IsValid()) { - context.error_handler.NotAllOf(&context.validators[allOf_.begin], allOf_.count); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetAllOfString()); - } - - if (anyOf_.schemas) { - for (SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++) - if (context.validators[i]->IsValid()) - goto foundAny; - context.error_handler.NoneOf(&context.validators[anyOf_.begin], anyOf_.count); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetAnyOfString()); - foundAny:; - } - - if (oneOf_.schemas) { - bool oneValid = false; - for (SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++) - if (context.validators[i]->IsValid()) { - if (oneValid) { - context.error_handler.NotOneOf(&context.validators[oneOf_.begin], oneOf_.count); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString()); - } else - oneValid = true; - } - if (!oneValid) { - context.error_handler.NotOneOf(&context.validators[oneOf_.begin], oneOf_.count); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString()); - } - } - - if (not_ && context.validators[notValidatorIndex_]->IsValid()) { - context.error_handler.Disallowed(); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetNotString()); - } - - return true; - } - - bool Null(Context& context) const { - if (!(type_ & (1 << kNullSchemaType))) { - DisallowedType(context, GetNullString()); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); - } - return CreateParallelValidator(context); - } - - bool Bool(Context& context, bool) const { - if (!(type_ & (1 << kBooleanSchemaType))) { - DisallowedType(context, GetBooleanString()); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); - } - return CreateParallelValidator(context); - } - - bool Int(Context& context, int i) const { - if (!CheckInt(context, i)) - return false; - return CreateParallelValidator(context); - } - - bool Uint(Context& context, unsigned u) const { - if (!CheckUint(context, u)) - return false; - return CreateParallelValidator(context); - } - - bool Int64(Context& context, int64_t i) const { - if (!CheckInt(context, i)) - return false; - return CreateParallelValidator(context); - } - - bool Uint64(Context& context, uint64_t u) const { - if (!CheckUint(context, u)) - return false; - return CreateParallelValidator(context); - } - - bool Double(Context& context, double d) const { - if (!(type_ & (1 << kNumberSchemaType))) { - DisallowedType(context, GetNumberString()); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); - } - - if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d)) - return false; - - if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d)) - return false; - - if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d)) - return false; - - return CreateParallelValidator(context); - } - - bool String(Context& context, const Ch* str, SizeType length, bool) const { - if (!(type_ & (1 << kStringSchemaType))) { - DisallowedType(context, GetStringString()); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); - } - - if (minLength_ != 0 || maxLength_ != SizeType(~0)) { - SizeType count; - if (internal::CountStringCodePoint(str, length, &count)) { - if (count < minLength_) { - context.error_handler.TooShort(str, length, minLength_); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinLengthString()); - } - if (count > maxLength_) { - context.error_handler.TooLong(str, length, maxLength_); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxLengthString()); - } - } - } - - if (pattern_ && !IsPatternMatch(pattern_, str, length)) { - context.error_handler.DoesNotMatch(str, length); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternString()); - } - - return CreateParallelValidator(context); - } - - bool StartObject(Context& context) const { - if (!(type_ & (1 << kObjectSchemaType))) { - DisallowedType(context, GetObjectString()); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); - } - - if (hasDependencies_ || hasRequired_) { - context.propertyExist = static_cast(context.factory.MallocState(sizeof(bool) * propertyCount_)); - std::memset(context.propertyExist, 0, sizeof(bool) * propertyCount_); - } - - if (patternProperties_) { // pre-allocate schema array - SizeType count = patternPropertyCount_ + 1; // extra for valuePatternValidatorType - context.patternPropertiesSchemas = static_cast(context.factory.MallocState(sizeof(const SchemaType*) * count)); - context.patternPropertiesSchemaCount = 0; - std::memset(context.patternPropertiesSchemas, 0, sizeof(SchemaType*) * count); - } - - return CreateParallelValidator(context); - } - - bool Key(Context& context, const Ch* str, SizeType len, bool) const { - if (patternProperties_) { - context.patternPropertiesSchemaCount = 0; - for (SizeType i = 0; i < patternPropertyCount_; i++) - if (patternProperties_[i].pattern && IsPatternMatch(patternProperties_[i].pattern, str, len)) { - context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = patternProperties_[i].schema; - context.valueSchema = typeless_; - } - } - - SizeType index = 0; - if (FindPropertyIndex(ValueType(str, len).Move(), &index)) { - if (context.patternPropertiesSchemaCount > 0) { - context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema; - context.valueSchema = typeless_; - context.valuePatternValidatorType = Context::kPatternValidatorWithProperty; - } - else - context.valueSchema = properties_[index].schema; - - if (context.propertyExist) - context.propertyExist[index] = true; - - return true; - } - - if (additionalPropertiesSchema_) { - if (additionalPropertiesSchema_ && context.patternPropertiesSchemaCount > 0) { - context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = additionalPropertiesSchema_; - context.valueSchema = typeless_; - context.valuePatternValidatorType = Context::kPatternValidatorWithAdditionalProperty; - } - else - context.valueSchema = additionalPropertiesSchema_; - return true; - } - else if (additionalProperties_) { - context.valueSchema = typeless_; - return true; - } - - if (context.patternPropertiesSchemaCount == 0) { // patternProperties are not additional properties - context.error_handler.DisallowedProperty(str, len); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetAdditionalPropertiesString()); - } - - return true; - } - - bool EndObject(Context& context, SizeType memberCount) const { - if (hasRequired_) { - context.error_handler.StartMissingProperties(); - for (SizeType index = 0; index < propertyCount_; index++) - if (properties_[index].required && !context.propertyExist[index]) - if (properties_[index].schema->defaultValueLength_ == 0 ) - context.error_handler.AddMissingProperty(properties_[index].name); - if (context.error_handler.EndMissingProperties()) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetRequiredString()); - } - - if (memberCount < minProperties_) { - context.error_handler.TooFewProperties(memberCount, minProperties_); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinPropertiesString()); - } - - if (memberCount > maxProperties_) { - context.error_handler.TooManyProperties(memberCount, maxProperties_); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxPropertiesString()); - } - - if (hasDependencies_) { - context.error_handler.StartDependencyErrors(); - for (SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++) { - const Property& source = properties_[sourceIndex]; - if (context.propertyExist[sourceIndex]) { - if (source.dependencies) { - context.error_handler.StartMissingDependentProperties(); - for (SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++) - if (source.dependencies[targetIndex] && !context.propertyExist[targetIndex]) - context.error_handler.AddMissingDependentProperty(properties_[targetIndex].name); - context.error_handler.EndMissingDependentProperties(source.name); - } - else if (source.dependenciesSchema) { - ISchemaValidator* dependenciesValidator = context.validators[source.dependenciesValidatorIndex]; - if (!dependenciesValidator->IsValid()) - context.error_handler.AddDependencySchemaError(source.name, dependenciesValidator); - } - } - } - if (context.error_handler.EndDependencyErrors()) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString()); - } - - return true; - } - - bool StartArray(Context& context) const { - if (!(type_ & (1 << kArraySchemaType))) { - DisallowedType(context, GetArrayString()); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); - } - - context.arrayElementIndex = 0; - context.inArray = true; - - return CreateParallelValidator(context); - } - - bool EndArray(Context& context, SizeType elementCount) const { - context.inArray = false; - - if (elementCount < minItems_) { - context.error_handler.TooFewItems(elementCount, minItems_); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinItemsString()); - } - - if (elementCount > maxItems_) { - context.error_handler.TooManyItems(elementCount, maxItems_); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxItemsString()); - } - - return true; - } - - // Generate functions for string literal according to Ch -#define RAPIDJSON_STRING_(name, ...) \ - static const ValueType& Get##name##String() {\ - static const Ch s[] = { __VA_ARGS__, '\0' };\ - static const ValueType v(s, static_cast(sizeof(s) / sizeof(Ch) - 1));\ - return v;\ - } - - RAPIDJSON_STRING_(Null, 'n', 'u', 'l', 'l') - RAPIDJSON_STRING_(Boolean, 'b', 'o', 'o', 'l', 'e', 'a', 'n') - RAPIDJSON_STRING_(Object, 'o', 'b', 'j', 'e', 'c', 't') - RAPIDJSON_STRING_(Array, 'a', 'r', 'r', 'a', 'y') - RAPIDJSON_STRING_(String, 's', 't', 'r', 'i', 'n', 'g') - RAPIDJSON_STRING_(Number, 'n', 'u', 'm', 'b', 'e', 'r') - RAPIDJSON_STRING_(Integer, 'i', 'n', 't', 'e', 'g', 'e', 'r') - RAPIDJSON_STRING_(Type, 't', 'y', 'p', 'e') - RAPIDJSON_STRING_(Enum, 'e', 'n', 'u', 'm') - RAPIDJSON_STRING_(AllOf, 'a', 'l', 'l', 'O', 'f') - RAPIDJSON_STRING_(AnyOf, 'a', 'n', 'y', 'O', 'f') - RAPIDJSON_STRING_(OneOf, 'o', 'n', 'e', 'O', 'f') - RAPIDJSON_STRING_(Not, 'n', 'o', 't') - RAPIDJSON_STRING_(Properties, 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') - RAPIDJSON_STRING_(Required, 'r', 'e', 'q', 'u', 'i', 'r', 'e', 'd') - RAPIDJSON_STRING_(Dependencies, 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'i', 'e', 's') - RAPIDJSON_STRING_(PatternProperties, 'p', 'a', 't', 't', 'e', 'r', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') - RAPIDJSON_STRING_(AdditionalProperties, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') - RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') - RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') - RAPIDJSON_STRING_(Items, 'i', 't', 'e', 'm', 's') - RAPIDJSON_STRING_(MinItems, 'm', 'i', 'n', 'I', 't', 'e', 'm', 's') - RAPIDJSON_STRING_(MaxItems, 'm', 'a', 'x', 'I', 't', 'e', 'm', 's') - RAPIDJSON_STRING_(AdditionalItems, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'I', 't', 'e', 'm', 's') - RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e', 'm', 's') - RAPIDJSON_STRING_(MinLength, 'm', 'i', 'n', 'L', 'e', 'n', 'g', 't', 'h') - RAPIDJSON_STRING_(MaxLength, 'm', 'a', 'x', 'L', 'e', 'n', 'g', 't', 'h') - RAPIDJSON_STRING_(Pattern, 'p', 'a', 't', 't', 'e', 'r', 'n') - RAPIDJSON_STRING_(Minimum, 'm', 'i', 'n', 'i', 'm', 'u', 'm') - RAPIDJSON_STRING_(Maximum, 'm', 'a', 'x', 'i', 'm', 'u', 'm') - RAPIDJSON_STRING_(ExclusiveMinimum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm') - RAPIDJSON_STRING_(ExclusiveMaximum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm') - RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f') - RAPIDJSON_STRING_(DefaultValue, 'd', 'e', 'f', 'a', 'u', 'l', 't') - -#undef RAPIDJSON_STRING_ - -private: - enum SchemaValueType { - kNullSchemaType, - kBooleanSchemaType, - kObjectSchemaType, - kArraySchemaType, - kStringSchemaType, - kNumberSchemaType, - kIntegerSchemaType, - kTotalSchemaType - }; - -#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX - typedef internal::GenericRegex RegexType; -#elif RAPIDJSON_SCHEMA_USE_STDREGEX - typedef std::basic_regex RegexType; -#else - typedef char RegexType; -#endif - - struct SchemaArray { - SchemaArray() : schemas(), count() {} - ~SchemaArray() { AllocatorType::Free(schemas); } - const SchemaType** schemas; - SizeType begin; // begin index of context.validators - SizeType count; - }; - - template - void AddUniqueElement(V1& a, const V2& v) { - for (typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr) - if (*itr == v) - return; - V1 c(v, *allocator_); - a.PushBack(c, *allocator_); - } - - static const ValueType* GetMember(const ValueType& value, const ValueType& name) { - typename ValueType::ConstMemberIterator itr = value.FindMember(name); - return itr != value.MemberEnd() ? &(itr->value) : 0; - } - - static void AssignIfExist(bool& out, const ValueType& value, const ValueType& name) { - if (const ValueType* v = GetMember(value, name)) - if (v->IsBool()) - out = v->GetBool(); - } - - static void AssignIfExist(SizeType& out, const ValueType& value, const ValueType& name) { - if (const ValueType* v = GetMember(value, name)) - if (v->IsUint64() && v->GetUint64() <= SizeType(~0)) - out = static_cast(v->GetUint64()); - } - - void AssignIfExist(SchemaArray& out, SchemaDocumentType& schemaDocument, const PointerType& p, const ValueType& value, const ValueType& name, const ValueType& document) { - if (const ValueType* v = GetMember(value, name)) { - if (v->IsArray() && v->Size() > 0) { - PointerType q = p.Append(name, allocator_); - out.count = v->Size(); - out.schemas = static_cast(allocator_->Malloc(out.count * sizeof(const Schema*))); - memset(out.schemas, 0, sizeof(Schema*)* out.count); - for (SizeType i = 0; i < out.count; i++) - schemaDocument.CreateSchema(&out.schemas[i], q.Append(i, allocator_), (*v)[i], document); - out.begin = validatorCount_; - validatorCount_ += out.count; - } - } - } - -#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX - template - RegexType* CreatePattern(const ValueType& value) { - if (value.IsString()) { - RegexType* r = new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString(), allocator_); - if (!r->IsValid()) { - r->~RegexType(); - AllocatorType::Free(r); - r = 0; - } - return r; - } - return 0; - } - - static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType) { - GenericRegexSearch rs(*pattern); - return rs.Search(str); - } -#elif RAPIDJSON_SCHEMA_USE_STDREGEX - template - RegexType* CreatePattern(const ValueType& value) { - if (value.IsString()) { - RegexType *r = static_cast(allocator_->Malloc(sizeof(RegexType))); - try { - return new (r) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript); - } - catch (const std::regex_error&) { - AllocatorType::Free(r); - } - } - return 0; - } - - static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType length) { - std::match_results r; - return std::regex_search(str, str + length, r, *pattern); - } -#else - template - RegexType* CreatePattern(const ValueType&) { return 0; } - - static bool IsPatternMatch(const RegexType*, const Ch *, SizeType) { return true; } -#endif // RAPIDJSON_SCHEMA_USE_STDREGEX - - void AddType(const ValueType& type) { - if (type == GetNullString() ) type_ |= 1 << kNullSchemaType; - else if (type == GetBooleanString()) type_ |= 1 << kBooleanSchemaType; - else if (type == GetObjectString() ) type_ |= 1 << kObjectSchemaType; - else if (type == GetArrayString() ) type_ |= 1 << kArraySchemaType; - else if (type == GetStringString() ) type_ |= 1 << kStringSchemaType; - else if (type == GetIntegerString()) type_ |= 1 << kIntegerSchemaType; - else if (type == GetNumberString() ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType); - } - - bool CreateParallelValidator(Context& context) const { - if (enum_ || context.arrayUniqueness) - context.hasher = context.factory.CreateHasher(); - - if (validatorCount_) { - RAPIDJSON_ASSERT(context.validators == 0); - context.validators = static_cast(context.factory.MallocState(sizeof(ISchemaValidator*) * validatorCount_)); - context.validatorCount = validatorCount_; - - if (allOf_.schemas) - CreateSchemaValidators(context, allOf_); - - if (anyOf_.schemas) - CreateSchemaValidators(context, anyOf_); - - if (oneOf_.schemas) - CreateSchemaValidators(context, oneOf_); - - if (not_) - context.validators[notValidatorIndex_] = context.factory.CreateSchemaValidator(*not_); - - if (hasSchemaDependencies_) { - for (SizeType i = 0; i < propertyCount_; i++) - if (properties_[i].dependenciesSchema) - context.validators[properties_[i].dependenciesValidatorIndex] = context.factory.CreateSchemaValidator(*properties_[i].dependenciesSchema); - } - } - - return true; - } - - void CreateSchemaValidators(Context& context, const SchemaArray& schemas) const { - for (SizeType i = 0; i < schemas.count; i++) - context.validators[schemas.begin + i] = context.factory.CreateSchemaValidator(*schemas.schemas[i]); - } - - // O(n) - bool FindPropertyIndex(const ValueType& name, SizeType* outIndex) const { - SizeType len = name.GetStringLength(); - const Ch* str = name.GetString(); - for (SizeType index = 0; index < propertyCount_; index++) - if (properties_[index].name.GetStringLength() == len && - (std::memcmp(properties_[index].name.GetString(), str, sizeof(Ch) * len) == 0)) - { - *outIndex = index; - return true; - } - return false; - } - - bool CheckInt(Context& context, int64_t i) const { - if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) { - DisallowedType(context, GetIntegerString()); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); - } - - if (!minimum_.IsNull()) { - if (minimum_.IsInt64()) { - if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64()) { - context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); - } - } - else if (minimum_.IsUint64()) { - context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); // i <= max(int64_t) < minimum.GetUint64() - } - else if (!CheckDoubleMinimum(context, static_cast(i))) - return false; - } - - if (!maximum_.IsNull()) { - if (maximum_.IsInt64()) { - if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64()) { - context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); - } - } - else if (maximum_.IsUint64()) { } - /* do nothing */ // i <= max(int64_t) < maximum_.GetUint64() - else if (!CheckDoubleMaximum(context, static_cast(i))) - return false; - } - - if (!multipleOf_.IsNull()) { - if (multipleOf_.IsUint64()) { - if (static_cast(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0) { - context.error_handler.NotMultipleOf(i, multipleOf_); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); - } - } - else if (!CheckDoubleMultipleOf(context, static_cast(i))) - return false; - } - - return true; - } - - bool CheckUint(Context& context, uint64_t i) const { - if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) { - DisallowedType(context, GetIntegerString()); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); - } - - if (!minimum_.IsNull()) { - if (minimum_.IsUint64()) { - if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64()) { - context.error_handler.BelowMinimum(i, minimum_, exclusiveMinimum_); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); - } - } - else if (minimum_.IsInt64()) - /* do nothing */; // i >= 0 > minimum.Getint64() - else if (!CheckDoubleMinimum(context, static_cast(i))) - return false; - } - - if (!maximum_.IsNull()) { - if (maximum_.IsUint64()) { - if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64()) { - context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); - } - } - else if (maximum_.IsInt64()) { - context.error_handler.AboveMaximum(i, maximum_, exclusiveMaximum_); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); // i >= 0 > maximum_ - } - else if (!CheckDoubleMaximum(context, static_cast(i))) - return false; - } - - if (!multipleOf_.IsNull()) { - if (multipleOf_.IsUint64()) { - if (i % multipleOf_.GetUint64() != 0) { - context.error_handler.NotMultipleOf(i, multipleOf_); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); - } - } - else if (!CheckDoubleMultipleOf(context, static_cast(i))) - return false; - } - - return true; - } - - bool CheckDoubleMinimum(Context& context, double d) const { - if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble()) { - context.error_handler.BelowMinimum(d, minimum_, exclusiveMinimum_); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); - } - return true; - } - - bool CheckDoubleMaximum(Context& context, double d) const { - if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble()) { - context.error_handler.AboveMaximum(d, maximum_, exclusiveMaximum_); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); - } - return true; - } - - bool CheckDoubleMultipleOf(Context& context, double d) const { - double a = std::abs(d), b = std::abs(multipleOf_.GetDouble()); - double q = std::floor(a / b); - double r = a - q * b; - if (r > 0.0) { - context.error_handler.NotMultipleOf(d, multipleOf_); - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); - } - return true; - } - - void DisallowedType(Context& context, const ValueType& actualType) const { - ErrorHandler& eh = context.error_handler; - eh.StartDisallowedType(); - - if (type_ & (1 << kNullSchemaType)) eh.AddExpectedType(GetNullString()); - if (type_ & (1 << kBooleanSchemaType)) eh.AddExpectedType(GetBooleanString()); - if (type_ & (1 << kObjectSchemaType)) eh.AddExpectedType(GetObjectString()); - if (type_ & (1 << kArraySchemaType)) eh.AddExpectedType(GetArrayString()); - if (type_ & (1 << kStringSchemaType)) eh.AddExpectedType(GetStringString()); - - if (type_ & (1 << kNumberSchemaType)) eh.AddExpectedType(GetNumberString()); - else if (type_ & (1 << kIntegerSchemaType)) eh.AddExpectedType(GetIntegerString()); - - eh.EndDisallowedType(actualType); - } - - struct Property { - Property() : schema(), dependenciesSchema(), dependenciesValidatorIndex(), dependencies(), required(false) {} - ~Property() { AllocatorType::Free(dependencies); } - SValue name; - const SchemaType* schema; - const SchemaType* dependenciesSchema; - SizeType dependenciesValidatorIndex; - bool* dependencies; - bool required; - }; - - struct PatternProperty { - PatternProperty() : schema(), pattern() {} - ~PatternProperty() { - if (pattern) { - pattern->~RegexType(); - AllocatorType::Free(pattern); - } - } - const SchemaType* schema; - RegexType* pattern; - }; - - AllocatorType* allocator_; - SValue uri_; - PointerType pointer_; - const SchemaType* typeless_; - uint64_t* enum_; - SizeType enumCount_; - SchemaArray allOf_; - SchemaArray anyOf_; - SchemaArray oneOf_; - const SchemaType* not_; - unsigned type_; // bitmask of kSchemaType - SizeType validatorCount_; - SizeType notValidatorIndex_; - - Property* properties_; - const SchemaType* additionalPropertiesSchema_; - PatternProperty* patternProperties_; - SizeType patternPropertyCount_; - SizeType propertyCount_; - SizeType minProperties_; - SizeType maxProperties_; - bool additionalProperties_; - bool hasDependencies_; - bool hasRequired_; - bool hasSchemaDependencies_; - - const SchemaType* additionalItemsSchema_; - const SchemaType* itemsList_; - const SchemaType** itemsTuple_; - SizeType itemsTupleCount_; - SizeType minItems_; - SizeType maxItems_; - bool additionalItems_; - bool uniqueItems_; - - RegexType* pattern_; - SizeType minLength_; - SizeType maxLength_; - - SValue minimum_; - SValue maximum_; - SValue multipleOf_; - bool exclusiveMinimum_; - bool exclusiveMaximum_; - - SizeType defaultValueLength_; -}; - -template -struct TokenHelper { - RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) { - *documentStack.template Push() = '/'; - char buffer[21]; - size_t length = static_cast((sizeof(SizeType) == 4 ? u32toa(index, buffer) : u64toa(index, buffer)) - buffer); - for (size_t i = 0; i < length; i++) - *documentStack.template Push() = static_cast(buffer[i]); - } -}; - -// Partial specialized version for char to prevent buffer copying. -template -struct TokenHelper { - RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) { - if (sizeof(SizeType) == 4) { - char *buffer = documentStack.template Push(1 + 10); // '/' + uint - *buffer++ = '/'; - const char* end = internal::u32toa(index, buffer); - documentStack.template Pop(static_cast(10 - (end - buffer))); - } - else { - char *buffer = documentStack.template Push(1 + 20); // '/' + uint64 - *buffer++ = '/'; - const char* end = internal::u64toa(index, buffer); - documentStack.template Pop(static_cast(20 - (end - buffer))); - } - } -}; - -} // namespace internal - -/////////////////////////////////////////////////////////////////////////////// -// IGenericRemoteSchemaDocumentProvider - -template -class IGenericRemoteSchemaDocumentProvider { -public: - typedef typename SchemaDocumentType::Ch Ch; - - virtual ~IGenericRemoteSchemaDocumentProvider() {} - virtual const SchemaDocumentType* GetRemoteDocument(const Ch* uri, SizeType length) = 0; -}; - -/////////////////////////////////////////////////////////////////////////////// -// GenericSchemaDocument - -//! JSON schema document. -/*! - A JSON schema document is a compiled version of a JSON schema. - It is basically a tree of internal::Schema. - - \note This is an immutable class (i.e. its instance cannot be modified after construction). - \tparam ValueT Type of JSON value (e.g. \c Value ), which also determine the encoding. - \tparam Allocator Allocator type for allocating memory of this document. -*/ -template -class GenericSchemaDocument { -public: - typedef ValueT ValueType; - typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProviderType; - typedef Allocator AllocatorType; - typedef typename ValueType::EncodingType EncodingType; - typedef typename EncodingType::Ch Ch; - typedef internal::Schema SchemaType; - typedef GenericPointer PointerType; - typedef GenericValue URIType; - friend class internal::Schema; - template - friend class GenericSchemaValidator; - - //! Constructor. - /*! - Compile a JSON document into schema document. - - \param document A JSON document as source. - \param uri The base URI of this schema document for purposes of violation reporting. - \param uriLength Length of \c name, in code points. - \param remoteProvider An optional remote schema document provider for resolving remote reference. Can be null. - \param allocator An optional allocator instance for allocating memory. Can be null. - */ - explicit GenericSchemaDocument(const ValueType& document, const Ch* uri = 0, SizeType uriLength = 0, - IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0) : - remoteProvider_(remoteProvider), - allocator_(allocator), - ownAllocator_(), - root_(), - typeless_(), - schemaMap_(allocator, kInitialSchemaMapSize), - schemaRef_(allocator, kInitialSchemaRefSize) - { - if (!allocator_) - ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)(); - - Ch noUri[1] = {0}; - uri_.SetString(uri ? uri : noUri, uriLength, *allocator_); - - typeless_ = static_cast(allocator_->Malloc(sizeof(SchemaType))); - new (typeless_) SchemaType(this, PointerType(), ValueType(kObjectType).Move(), ValueType(kObjectType).Move(), allocator_); - - // Generate root schema, it will call CreateSchema() to create sub-schemas, - // And call AddRefSchema() if there are $ref. - CreateSchemaRecursive(&root_, PointerType(), document, document); - - // Resolve $ref - while (!schemaRef_.Empty()) { - SchemaRefEntry* refEntry = schemaRef_.template Pop(1); - if (const SchemaType* s = GetSchema(refEntry->target)) { - if (refEntry->schema) - *refEntry->schema = s; - - // Create entry in map if not exist - if (!GetSchema(refEntry->source)) { - new (schemaMap_.template Push()) SchemaEntry(refEntry->source, const_cast(s), false, allocator_); - } - } - else if (refEntry->schema) - *refEntry->schema = typeless_; - - refEntry->~SchemaRefEntry(); - } - - RAPIDJSON_ASSERT(root_ != 0); - - schemaRef_.ShrinkToFit(); // Deallocate all memory for ref - } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - //! Move constructor in C++11 - GenericSchemaDocument(GenericSchemaDocument&& rhs) RAPIDJSON_NOEXCEPT : - remoteProvider_(rhs.remoteProvider_), - allocator_(rhs.allocator_), - ownAllocator_(rhs.ownAllocator_), - root_(rhs.root_), - typeless_(rhs.typeless_), - schemaMap_(std::move(rhs.schemaMap_)), - schemaRef_(std::move(rhs.schemaRef_)), - uri_(std::move(rhs.uri_)) - { - rhs.remoteProvider_ = 0; - rhs.allocator_ = 0; - rhs.ownAllocator_ = 0; - rhs.typeless_ = 0; - } -#endif - - //! Destructor - ~GenericSchemaDocument() { - while (!schemaMap_.Empty()) - schemaMap_.template Pop(1)->~SchemaEntry(); - - if (typeless_) { - typeless_->~SchemaType(); - Allocator::Free(typeless_); - } - - RAPIDJSON_DELETE(ownAllocator_); - } - - const URIType& GetURI() const { return uri_; } - - //! Get the root schema. - const SchemaType& GetRoot() const { return *root_; } - -private: - //! Prohibit copying - GenericSchemaDocument(const GenericSchemaDocument&); - //! Prohibit assignment - GenericSchemaDocument& operator=(const GenericSchemaDocument&); - - struct SchemaRefEntry { - SchemaRefEntry(const PointerType& s, const PointerType& t, const SchemaType** outSchema, Allocator *allocator) : source(s, allocator), target(t, allocator), schema(outSchema) {} - PointerType source; - PointerType target; - const SchemaType** schema; - }; - - struct SchemaEntry { - SchemaEntry(const PointerType& p, SchemaType* s, bool o, Allocator* allocator) : pointer(p, allocator), schema(s), owned(o) {} - ~SchemaEntry() { - if (owned) { - schema->~SchemaType(); - Allocator::Free(schema); - } - } - PointerType pointer; - SchemaType* schema; - bool owned; - }; - - void CreateSchemaRecursive(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) { - if (schema) - *schema = typeless_; - - if (v.GetType() == kObjectType) { - const SchemaType* s = GetSchema(pointer); - if (!s) - CreateSchema(schema, pointer, v, document); - - for (typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) - CreateSchemaRecursive(0, pointer.Append(itr->name, allocator_), itr->value, document); - } - else if (v.GetType() == kArrayType) - for (SizeType i = 0; i < v.Size(); i++) - CreateSchemaRecursive(0, pointer.Append(i, allocator_), v[i], document); - } - - void CreateSchema(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) { - RAPIDJSON_ASSERT(pointer.IsValid()); - if (v.IsObject()) { - if (!HandleRefSchema(pointer, schema, v, document)) { - SchemaType* s = new (allocator_->Malloc(sizeof(SchemaType))) SchemaType(this, pointer, v, document, allocator_); - new (schemaMap_.template Push()) SchemaEntry(pointer, s, true, allocator_); - if (schema) - *schema = s; - } - } - } - - bool HandleRefSchema(const PointerType& source, const SchemaType** schema, const ValueType& v, const ValueType& document) { - static const Ch kRefString[] = { '$', 'r', 'e', 'f', '\0' }; - static const ValueType kRefValue(kRefString, 4); - - typename ValueType::ConstMemberIterator itr = v.FindMember(kRefValue); - if (itr == v.MemberEnd()) - return false; - - if (itr->value.IsString()) { - SizeType len = itr->value.GetStringLength(); - if (len > 0) { - const Ch* s = itr->value.GetString(); - SizeType i = 0; - while (i < len && s[i] != '#') // Find the first # - i++; - - if (i > 0) { // Remote reference, resolve immediately - if (remoteProvider_) { - if (const GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(s, i)) { - PointerType pointer(&s[i], len - i, allocator_); - if (pointer.IsValid()) { - if (const SchemaType* sc = remoteDocument->GetSchema(pointer)) { - if (schema) - *schema = sc; - new (schemaMap_.template Push()) SchemaEntry(source, const_cast(sc), false, allocator_); - return true; - } - } - } - } - } - else if (s[i] == '#') { // Local reference, defer resolution - PointerType pointer(&s[i], len - i, allocator_); - if (pointer.IsValid()) { - if (const ValueType* nv = pointer.Get(document)) - if (HandleRefSchema(source, schema, *nv, document)) - return true; - - new (schemaRef_.template Push()) SchemaRefEntry(source, pointer, schema, allocator_); - return true; - } - } - } - } - return false; - } - - const SchemaType* GetSchema(const PointerType& pointer) const { - for (const SchemaEntry* target = schemaMap_.template Bottom(); target != schemaMap_.template End(); ++target) - if (pointer == target->pointer) - return target->schema; - return 0; - } - - PointerType GetPointer(const SchemaType* schema) const { - for (const SchemaEntry* target = schemaMap_.template Bottom(); target != schemaMap_.template End(); ++target) - if (schema == target->schema) - return target->pointer; - return PointerType(); - } - - const SchemaType* GetTypeless() const { return typeless_; } - - static const size_t kInitialSchemaMapSize = 64; - static const size_t kInitialSchemaRefSize = 64; - - IRemoteSchemaDocumentProviderType* remoteProvider_; - Allocator *allocator_; - Allocator *ownAllocator_; - const SchemaType* root_; //!< Root schema. - SchemaType* typeless_; - internal::Stack schemaMap_; // Stores created Pointer -> Schemas - internal::Stack schemaRef_; // Stores Pointer from $ref and schema which holds the $ref - URIType uri_; -}; - -//! GenericSchemaDocument using Value type. -typedef GenericSchemaDocument SchemaDocument; -//! IGenericRemoteSchemaDocumentProvider using SchemaDocument. -typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProvider; - -/////////////////////////////////////////////////////////////////////////////// -// GenericSchemaValidator - -//! JSON Schema Validator. -/*! - A SAX style JSON schema validator. - It uses a \c GenericSchemaDocument to validate SAX events. - It delegates the incoming SAX events to an output handler. - The default output handler does nothing. - It can be reused multiple times by calling \c Reset(). - - \tparam SchemaDocumentType Type of schema document. - \tparam OutputHandler Type of output handler. Default handler does nothing. - \tparam StateAllocator Allocator for storing the internal validation states. -*/ -template < - typename SchemaDocumentType, - typename OutputHandler = BaseReaderHandler, - typename StateAllocator = CrtAllocator> -class GenericSchemaValidator : - public internal::ISchemaStateFactory, - public internal::ISchemaValidator, - public internal::IValidationErrorHandler -{ -public: - typedef typename SchemaDocumentType::SchemaType SchemaType; - typedef typename SchemaDocumentType::PointerType PointerType; - typedef typename SchemaType::EncodingType EncodingType; - typedef typename SchemaType::SValue SValue; - typedef typename EncodingType::Ch Ch; - typedef GenericStringRef StringRefType; - typedef GenericValue ValueType; - - //! Constructor without output handler. - /*! - \param schemaDocument The schema document to conform to. - \param allocator Optional allocator for storing internal validation states. - \param schemaStackCapacity Optional initial capacity of schema path stack. - \param documentStackCapacity Optional initial capacity of document path stack. - */ - GenericSchemaValidator( - const SchemaDocumentType& schemaDocument, - StateAllocator* allocator = 0, - size_t schemaStackCapacity = kDefaultSchemaStackCapacity, - size_t documentStackCapacity = kDefaultDocumentStackCapacity) - : - schemaDocument_(&schemaDocument), - root_(schemaDocument.GetRoot()), - stateAllocator_(allocator), - ownStateAllocator_(0), - schemaStack_(allocator, schemaStackCapacity), - documentStack_(allocator, documentStackCapacity), - outputHandler_(0), - error_(kObjectType), - currentError_(), - missingDependents_(), - valid_(true) -#if RAPIDJSON_SCHEMA_VERBOSE - , depth_(0) -#endif - { - } - - //! Constructor with output handler. - /*! - \param schemaDocument The schema document to conform to. - \param allocator Optional allocator for storing internal validation states. - \param schemaStackCapacity Optional initial capacity of schema path stack. - \param documentStackCapacity Optional initial capacity of document path stack. - */ - GenericSchemaValidator( - const SchemaDocumentType& schemaDocument, - OutputHandler& outputHandler, - StateAllocator* allocator = 0, - size_t schemaStackCapacity = kDefaultSchemaStackCapacity, - size_t documentStackCapacity = kDefaultDocumentStackCapacity) - : - schemaDocument_(&schemaDocument), - root_(schemaDocument.GetRoot()), - stateAllocator_(allocator), - ownStateAllocator_(0), - schemaStack_(allocator, schemaStackCapacity), - documentStack_(allocator, documentStackCapacity), - outputHandler_(&outputHandler), - error_(kObjectType), - currentError_(), - missingDependents_(), - valid_(true) -#if RAPIDJSON_SCHEMA_VERBOSE - , depth_(0) -#endif - { - } - - //! Destructor. - ~GenericSchemaValidator() { - Reset(); - RAPIDJSON_DELETE(ownStateAllocator_); - } - - //! Reset the internal states. - void Reset() { - while (!schemaStack_.Empty()) - PopSchema(); - documentStack_.Clear(); - error_.SetObject(); - currentError_.SetNull(); - missingDependents_.SetNull(); - valid_ = true; - } - - //! Checks whether the current state is valid. - // Implementation of ISchemaValidator - virtual bool IsValid() const { return valid_; } - - //! Gets the error object. - ValueType& GetError() { return error_; } - const ValueType& GetError() const { return error_; } - - //! Gets the JSON pointer pointed to the invalid schema. - PointerType GetInvalidSchemaPointer() const { - return schemaStack_.Empty() ? PointerType() : CurrentSchema().GetPointer(); - } - - //! Gets the keyword of invalid schema. - const Ch* GetInvalidSchemaKeyword() const { - return schemaStack_.Empty() ? 0 : CurrentContext().invalidKeyword; - } - - //! Gets the JSON pointer pointed to the invalid value. - PointerType GetInvalidDocumentPointer() const { - if (documentStack_.Empty()) { - return PointerType(); - } - else { - return PointerType(documentStack_.template Bottom(), documentStack_.GetSize() / sizeof(Ch)); - } - } - - void NotMultipleOf(int64_t actual, const SValue& expected) { - AddNumberError(SchemaType::GetMultipleOfString(), ValueType(actual).Move(), expected); - } - void NotMultipleOf(uint64_t actual, const SValue& expected) { - AddNumberError(SchemaType::GetMultipleOfString(), ValueType(actual).Move(), expected); - } - void NotMultipleOf(double actual, const SValue& expected) { - AddNumberError(SchemaType::GetMultipleOfString(), ValueType(actual).Move(), expected); - } - void AboveMaximum(int64_t actual, const SValue& expected, bool exclusive) { - AddNumberError(SchemaType::GetMaximumString(), ValueType(actual).Move(), expected, - exclusive ? &SchemaType::GetExclusiveMaximumString : 0); - } - void AboveMaximum(uint64_t actual, const SValue& expected, bool exclusive) { - AddNumberError(SchemaType::GetMaximumString(), ValueType(actual).Move(), expected, - exclusive ? &SchemaType::GetExclusiveMaximumString : 0); - } - void AboveMaximum(double actual, const SValue& expected, bool exclusive) { - AddNumberError(SchemaType::GetMaximumString(), ValueType(actual).Move(), expected, - exclusive ? &SchemaType::GetExclusiveMaximumString : 0); - } - void BelowMinimum(int64_t actual, const SValue& expected, bool exclusive) { - AddNumberError(SchemaType::GetMinimumString(), ValueType(actual).Move(), expected, - exclusive ? &SchemaType::GetExclusiveMinimumString : 0); - } - void BelowMinimum(uint64_t actual, const SValue& expected, bool exclusive) { - AddNumberError(SchemaType::GetMinimumString(), ValueType(actual).Move(), expected, - exclusive ? &SchemaType::GetExclusiveMinimumString : 0); - } - void BelowMinimum(double actual, const SValue& expected, bool exclusive) { - AddNumberError(SchemaType::GetMinimumString(), ValueType(actual).Move(), expected, - exclusive ? &SchemaType::GetExclusiveMinimumString : 0); - } - - void TooLong(const Ch* str, SizeType length, SizeType expected) { - AddNumberError(SchemaType::GetMaxLengthString(), - ValueType(str, length, GetStateAllocator()).Move(), SValue(expected).Move()); - } - void TooShort(const Ch* str, SizeType length, SizeType expected) { - AddNumberError(SchemaType::GetMinLengthString(), - ValueType(str, length, GetStateAllocator()).Move(), SValue(expected).Move()); - } - void DoesNotMatch(const Ch* str, SizeType length) { - currentError_.SetObject(); - currentError_.AddMember(GetActualString(), ValueType(str, length, GetStateAllocator()).Move(), GetStateAllocator()); - AddCurrentError(SchemaType::GetPatternString()); - } - - void DisallowedItem(SizeType index) { - currentError_.SetObject(); - currentError_.AddMember(GetDisallowedString(), ValueType(index).Move(), GetStateAllocator()); - AddCurrentError(SchemaType::GetAdditionalItemsString(), true); - } - void TooFewItems(SizeType actualCount, SizeType expectedCount) { - AddNumberError(SchemaType::GetMinItemsString(), - ValueType(actualCount).Move(), SValue(expectedCount).Move()); - } - void TooManyItems(SizeType actualCount, SizeType expectedCount) { - AddNumberError(SchemaType::GetMaxItemsString(), - ValueType(actualCount).Move(), SValue(expectedCount).Move()); - } - void DuplicateItems(SizeType index1, SizeType index2) { - ValueType duplicates(kArrayType); - duplicates.PushBack(index1, GetStateAllocator()); - duplicates.PushBack(index2, GetStateAllocator()); - currentError_.SetObject(); - currentError_.AddMember(GetDuplicatesString(), duplicates, GetStateAllocator()); - AddCurrentError(SchemaType::GetUniqueItemsString(), true); - } - - void TooManyProperties(SizeType actualCount, SizeType expectedCount) { - AddNumberError(SchemaType::GetMaxPropertiesString(), - ValueType(actualCount).Move(), SValue(expectedCount).Move()); - } - void TooFewProperties(SizeType actualCount, SizeType expectedCount) { - AddNumberError(SchemaType::GetMinPropertiesString(), - ValueType(actualCount).Move(), SValue(expectedCount).Move()); - } - void StartMissingProperties() { - currentError_.SetArray(); - } - void AddMissingProperty(const SValue& name) { - currentError_.PushBack(ValueType(name, GetStateAllocator()).Move(), GetStateAllocator()); - } - bool EndMissingProperties() { - if (currentError_.Empty()) - return false; - ValueType error(kObjectType); - error.AddMember(GetMissingString(), currentError_, GetStateAllocator()); - currentError_ = error; - AddCurrentError(SchemaType::GetRequiredString()); - return true; - } - void PropertyViolations(ISchemaValidator** subvalidators, SizeType count) { - for (SizeType i = 0; i < count; ++i) - MergeError(static_cast(subvalidators[i])->GetError()); - } - void DisallowedProperty(const Ch* name, SizeType length) { - currentError_.SetObject(); - currentError_.AddMember(GetDisallowedString(), ValueType(name, length, GetStateAllocator()).Move(), GetStateAllocator()); - AddCurrentError(SchemaType::GetAdditionalPropertiesString(), true); - } - - void StartDependencyErrors() { - currentError_.SetObject(); - } - void StartMissingDependentProperties() { - missingDependents_.SetArray(); - } - void AddMissingDependentProperty(const SValue& targetName) { - missingDependents_.PushBack(ValueType(targetName, GetStateAllocator()).Move(), GetStateAllocator()); - } - void EndMissingDependentProperties(const SValue& sourceName) { - if (!missingDependents_.Empty()) - currentError_.AddMember(ValueType(sourceName, GetStateAllocator()).Move(), - missingDependents_, GetStateAllocator()); - } - void AddDependencySchemaError(const SValue& sourceName, ISchemaValidator* subvalidator) { - currentError_.AddMember(ValueType(sourceName, GetStateAllocator()).Move(), - static_cast(subvalidator)->GetError(), GetStateAllocator()); - } - bool EndDependencyErrors() { - if (currentError_.ObjectEmpty()) - return false; - ValueType error(kObjectType); - error.AddMember(GetErrorsString(), currentError_, GetStateAllocator()); - currentError_ = error; - AddCurrentError(SchemaType::GetDependenciesString()); - return true; - } - - void DisallowedValue() { - currentError_.SetObject(); - AddCurrentError(SchemaType::GetEnumString()); - } - void StartDisallowedType() { - currentError_.SetArray(); - } - void AddExpectedType(const typename SchemaType::ValueType& expectedType) { - currentError_.PushBack(ValueType(expectedType, GetStateAllocator()).Move(), GetStateAllocator()); - } - void EndDisallowedType(const typename SchemaType::ValueType& actualType) { - ValueType error(kObjectType); - error.AddMember(GetExpectedString(), currentError_, GetStateAllocator()); - error.AddMember(GetActualString(), ValueType(actualType, GetStateAllocator()).Move(), GetStateAllocator()); - currentError_ = error; - AddCurrentError(SchemaType::GetTypeString()); - } - void NotAllOf(ISchemaValidator** subvalidators, SizeType count) { - for (SizeType i = 0; i < count; ++i) { - MergeError(static_cast(subvalidators[i])->GetError()); - } - } - void NoneOf(ISchemaValidator** subvalidators, SizeType count) { - AddErrorArray(SchemaType::GetAnyOfString(), subvalidators, count); - } - void NotOneOf(ISchemaValidator** subvalidators, SizeType count) { - AddErrorArray(SchemaType::GetOneOfString(), subvalidators, count); - } - void Disallowed() { - currentError_.SetObject(); - AddCurrentError(SchemaType::GetNotString()); - } - -#define RAPIDJSON_STRING_(name, ...) \ - static const StringRefType& Get##name##String() {\ - static const Ch s[] = { __VA_ARGS__, '\0' };\ - static const StringRefType v(s, static_cast(sizeof(s) / sizeof(Ch) - 1)); \ - return v;\ - } - - RAPIDJSON_STRING_(InstanceRef, 'i', 'n', 's', 't', 'a', 'n', 'c', 'e', 'R', 'e', 'f') - RAPIDJSON_STRING_(SchemaRef, 's', 'c', 'h', 'e', 'm', 'a', 'R', 'e', 'f') - RAPIDJSON_STRING_(Expected, 'e', 'x', 'p', 'e', 'c', 't', 'e', 'd') - RAPIDJSON_STRING_(Actual, 'a', 'c', 't', 'u', 'a', 'l') - RAPIDJSON_STRING_(Disallowed, 'd', 'i', 's', 'a', 'l', 'l', 'o', 'w', 'e', 'd') - RAPIDJSON_STRING_(Missing, 'm', 'i', 's', 's', 'i', 'n', 'g') - RAPIDJSON_STRING_(Errors, 'e', 'r', 'r', 'o', 'r', 's') - RAPIDJSON_STRING_(Duplicates, 'd', 'u', 'p', 'l', 'i', 'c', 'a', 't', 'e', 's') - -#undef RAPIDJSON_STRING_ - -#if RAPIDJSON_SCHEMA_VERBOSE -#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() \ -RAPIDJSON_MULTILINEMACRO_BEGIN\ - *documentStack_.template Push() = '\0';\ - documentStack_.template Pop(1);\ - internal::PrintInvalidDocument(documentStack_.template Bottom());\ -RAPIDJSON_MULTILINEMACRO_END -#else -#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() -#endif - -#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\ - if (!valid_) return false; \ - if (!BeginValue() || !CurrentSchema().method arg1) {\ - RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_();\ - return valid_ = false;\ - } - -#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\ - for (Context* context = schemaStack_.template Bottom(); context != schemaStack_.template End(); context++) {\ - if (context->hasher)\ - static_cast(context->hasher)->method arg2;\ - if (context->validators)\ - for (SizeType i_ = 0; i_ < context->validatorCount; i_++)\ - static_cast(context->validators[i_])->method arg2;\ - if (context->patternPropertiesValidators)\ - for (SizeType i_ = 0; i_ < context->patternPropertiesValidatorCount; i_++)\ - static_cast(context->patternPropertiesValidators[i_])->method arg2;\ - } - -#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\ - return valid_ = EndValue() && (!outputHandler_ || outputHandler_->method arg2) - -#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \ - RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\ - RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\ - RAPIDJSON_SCHEMA_HANDLE_END_ (method, arg2) - - bool Null() { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Null, (CurrentContext()), ( )); } - bool Bool(bool b) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Bool, (CurrentContext(), b), (b)); } - bool Int(int i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int, (CurrentContext(), i), (i)); } - bool Uint(unsigned u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint, (CurrentContext(), u), (u)); } - bool Int64(int64_t i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int64, (CurrentContext(), i), (i)); } - bool Uint64(uint64_t u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint64, (CurrentContext(), u), (u)); } - bool Double(double d) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Double, (CurrentContext(), d), (d)); } - bool RawNumber(const Ch* str, SizeType length, bool copy) - { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); } - bool String(const Ch* str, SizeType length, bool copy) - { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); } - - bool StartObject() { - RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext())); - RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartObject, ()); - return valid_ = !outputHandler_ || outputHandler_->StartObject(); - } - - bool Key(const Ch* str, SizeType len, bool copy) { - if (!valid_) return false; - AppendToken(str, len); - if (!CurrentSchema().Key(CurrentContext(), str, len, copy)) return valid_ = false; - RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(Key, (str, len, copy)); - return valid_ = !outputHandler_ || outputHandler_->Key(str, len, copy); - } - - bool EndObject(SizeType memberCount) { - if (!valid_) return false; - RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndObject, (memberCount)); - if (!CurrentSchema().EndObject(CurrentContext(), memberCount)) return valid_ = false; - RAPIDJSON_SCHEMA_HANDLE_END_(EndObject, (memberCount)); - } - - bool StartArray() { - RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartArray, (CurrentContext())); - RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartArray, ()); - return valid_ = !outputHandler_ || outputHandler_->StartArray(); - } - - bool EndArray(SizeType elementCount) { - if (!valid_) return false; - RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndArray, (elementCount)); - if (!CurrentSchema().EndArray(CurrentContext(), elementCount)) return valid_ = false; - RAPIDJSON_SCHEMA_HANDLE_END_(EndArray, (elementCount)); - } - -#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_ -#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_ -#undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_ -#undef RAPIDJSON_SCHEMA_HANDLE_VALUE_ - - // Implementation of ISchemaStateFactory - virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root) { - return new (GetStateAllocator().Malloc(sizeof(GenericSchemaValidator))) GenericSchemaValidator(*schemaDocument_, root, documentStack_.template Bottom(), documentStack_.GetSize(), -#if RAPIDJSON_SCHEMA_VERBOSE - depth_ + 1, -#endif - &GetStateAllocator()); - } - - virtual void DestroySchemaValidator(ISchemaValidator* validator) { - GenericSchemaValidator* v = static_cast(validator); - v->~GenericSchemaValidator(); - StateAllocator::Free(v); - } - - virtual void* CreateHasher() { - return new (GetStateAllocator().Malloc(sizeof(HasherType))) HasherType(&GetStateAllocator()); - } - - virtual uint64_t GetHashCode(void* hasher) { - return static_cast(hasher)->GetHashCode(); - } - - virtual void DestroryHasher(void* hasher) { - HasherType* h = static_cast(hasher); - h->~HasherType(); - StateAllocator::Free(h); - } - - virtual void* MallocState(size_t size) { - return GetStateAllocator().Malloc(size); - } - - virtual void FreeState(void* p) { - StateAllocator::Free(p); - } - -private: - typedef typename SchemaType::Context Context; - typedef GenericValue, StateAllocator> HashCodeArray; - typedef internal::Hasher HasherType; - - GenericSchemaValidator( - const SchemaDocumentType& schemaDocument, - const SchemaType& root, - const char* basePath, size_t basePathSize, -#if RAPIDJSON_SCHEMA_VERBOSE - unsigned depth, -#endif - StateAllocator* allocator = 0, - size_t schemaStackCapacity = kDefaultSchemaStackCapacity, - size_t documentStackCapacity = kDefaultDocumentStackCapacity) - : - schemaDocument_(&schemaDocument), - root_(root), - stateAllocator_(allocator), - ownStateAllocator_(0), - schemaStack_(allocator, schemaStackCapacity), - documentStack_(allocator, documentStackCapacity), - outputHandler_(0), - error_(kObjectType), - currentError_(), - missingDependents_(), - valid_(true) -#if RAPIDJSON_SCHEMA_VERBOSE - , depth_(depth) -#endif - { - if (basePath && basePathSize) - memcpy(documentStack_.template Push(basePathSize), basePath, basePathSize); - } - - StateAllocator& GetStateAllocator() { - if (!stateAllocator_) - stateAllocator_ = ownStateAllocator_ = RAPIDJSON_NEW(StateAllocator)(); - return *stateAllocator_; - } - - bool BeginValue() { - if (schemaStack_.Empty()) - PushSchema(root_); - else { - if (CurrentContext().inArray) - internal::TokenHelper, Ch>::AppendIndexToken(documentStack_, CurrentContext().arrayElementIndex); - - if (!CurrentSchema().BeginValue(CurrentContext())) - return false; - - SizeType count = CurrentContext().patternPropertiesSchemaCount; - const SchemaType** sa = CurrentContext().patternPropertiesSchemas; - typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType; - bool valueUniqueness = CurrentContext().valueUniqueness; - RAPIDJSON_ASSERT(CurrentContext().valueSchema); - PushSchema(*CurrentContext().valueSchema); - - if (count > 0) { - CurrentContext().objectPatternValidatorType = patternValidatorType; - ISchemaValidator**& va = CurrentContext().patternPropertiesValidators; - SizeType& validatorCount = CurrentContext().patternPropertiesValidatorCount; - va = static_cast(MallocState(sizeof(ISchemaValidator*) * count)); - for (SizeType i = 0; i < count; i++) - va[validatorCount++] = CreateSchemaValidator(*sa[i]); - } - - CurrentContext().arrayUniqueness = valueUniqueness; - } - return true; - } - - bool EndValue() { - if (!CurrentSchema().EndValue(CurrentContext())) - return false; - -#if RAPIDJSON_SCHEMA_VERBOSE - GenericStringBuffer sb; - schemaDocument_->GetPointer(&CurrentSchema()).Stringify(sb); - - *documentStack_.template Push() = '\0'; - documentStack_.template Pop(1); - internal::PrintValidatorPointers(depth_, sb.GetString(), documentStack_.template Bottom()); -#endif - - uint64_t h = CurrentContext().arrayUniqueness ? static_cast(CurrentContext().hasher)->GetHashCode() : 0; - - PopSchema(); - - if (!schemaStack_.Empty()) { - Context& context = CurrentContext(); - if (context.valueUniqueness) { - HashCodeArray* a = static_cast(context.arrayElementHashCodes); - if (!a) - CurrentContext().arrayElementHashCodes = a = new (GetStateAllocator().Malloc(sizeof(HashCodeArray))) HashCodeArray(kArrayType); - for (typename HashCodeArray::ConstValueIterator itr = a->Begin(); itr != a->End(); ++itr) - if (itr->GetUint64() == h) { - DuplicateItems(static_cast(itr - a->Begin()), a->Size()); - RAPIDJSON_INVALID_KEYWORD_RETURN(SchemaType::GetUniqueItemsString()); - } - a->PushBack(h, GetStateAllocator()); - } - } - - // Remove the last token of document pointer - while (!documentStack_.Empty() && *documentStack_.template Pop(1) != '/') - ; - - return true; - } - - void AppendToken(const Ch* str, SizeType len) { - documentStack_.template Reserve(1 + len * 2); // worst case all characters are escaped as two characters - *documentStack_.template PushUnsafe() = '/'; - for (SizeType i = 0; i < len; i++) { - if (str[i] == '~') { - *documentStack_.template PushUnsafe() = '~'; - *documentStack_.template PushUnsafe() = '0'; - } - else if (str[i] == '/') { - *documentStack_.template PushUnsafe() = '~'; - *documentStack_.template PushUnsafe() = '1'; - } - else - *documentStack_.template PushUnsafe() = str[i]; - } - } - - RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType& schema) { new (schemaStack_.template Push()) Context(*this, *this, &schema); } - - RAPIDJSON_FORCEINLINE void PopSchema() { - Context* c = schemaStack_.template Pop(1); - if (HashCodeArray* a = static_cast(c->arrayElementHashCodes)) { - a->~HashCodeArray(); - StateAllocator::Free(a); - } - c->~Context(); - } - - void AddErrorLocation(ValueType& result, bool parent) { - GenericStringBuffer sb; - PointerType instancePointer = GetInvalidDocumentPointer(); - ((parent && instancePointer.GetTokenCount() > 0) - ? PointerType(instancePointer.GetTokens(), instancePointer.GetTokenCount() - 1) - : instancePointer).StringifyUriFragment(sb); - ValueType instanceRef(sb.GetString(), static_cast(sb.GetSize() / sizeof(Ch)), - GetStateAllocator()); - result.AddMember(GetInstanceRefString(), instanceRef, GetStateAllocator()); - sb.Clear(); - memcpy(sb.Push(CurrentSchema().GetURI().GetStringLength()), - CurrentSchema().GetURI().GetString(), - CurrentSchema().GetURI().GetStringLength() * sizeof(Ch)); - GetInvalidSchemaPointer().StringifyUriFragment(sb); - ValueType schemaRef(sb.GetString(), static_cast(sb.GetSize() / sizeof(Ch)), - GetStateAllocator()); - result.AddMember(GetSchemaRefString(), schemaRef, GetStateAllocator()); - } - - void AddError(ValueType& keyword, ValueType& error) { - typename ValueType::MemberIterator member = error_.FindMember(keyword); - if (member == error_.MemberEnd()) - error_.AddMember(keyword, error, GetStateAllocator()); - else { - if (member->value.IsObject()) { - ValueType errors(kArrayType); - errors.PushBack(member->value, GetStateAllocator()); - member->value = errors; - } - member->value.PushBack(error, GetStateAllocator()); - } - } - - void AddCurrentError(const typename SchemaType::ValueType& keyword, bool parent = false) { - AddErrorLocation(currentError_, parent); - AddError(ValueType(keyword, GetStateAllocator(), false).Move(), currentError_); - } - - void MergeError(ValueType& other) { - for (typename ValueType::MemberIterator it = other.MemberBegin(), end = other.MemberEnd(); it != end; ++it) { - AddError(it->name, it->value); - } - } - - void AddNumberError(const typename SchemaType::ValueType& keyword, ValueType& actual, const SValue& expected, - const typename SchemaType::ValueType& (*exclusive)() = 0) { - currentError_.SetObject(); - currentError_.AddMember(GetActualString(), actual, GetStateAllocator()); - currentError_.AddMember(GetExpectedString(), ValueType(expected, GetStateAllocator()).Move(), GetStateAllocator()); - if (exclusive) - currentError_.AddMember(ValueType(exclusive(), GetStateAllocator()).Move(), true, GetStateAllocator()); - AddCurrentError(keyword); - } - - void AddErrorArray(const typename SchemaType::ValueType& keyword, - ISchemaValidator** subvalidators, SizeType count) { - ValueType errors(kArrayType); - for (SizeType i = 0; i < count; ++i) - errors.PushBack(static_cast(subvalidators[i])->GetError(), GetStateAllocator()); - currentError_.SetObject(); - currentError_.AddMember(GetErrorsString(), errors, GetStateAllocator()); - AddCurrentError(keyword); - } - - const SchemaType& CurrentSchema() const { return *schemaStack_.template Top()->schema; } - Context& CurrentContext() { return *schemaStack_.template Top(); } - const Context& CurrentContext() const { return *schemaStack_.template Top(); } - - static const size_t kDefaultSchemaStackCapacity = 1024; - static const size_t kDefaultDocumentStackCapacity = 256; - const SchemaDocumentType* schemaDocument_; - const SchemaType& root_; - StateAllocator* stateAllocator_; - StateAllocator* ownStateAllocator_; - internal::Stack schemaStack_; //!< stack to store the current path of schema (BaseSchemaType *) - internal::Stack documentStack_; //!< stack to store the current path of validating document (Ch) - OutputHandler* outputHandler_; - ValueType error_; - ValueType currentError_; - ValueType missingDependents_; - bool valid_; -#if RAPIDJSON_SCHEMA_VERBOSE - unsigned depth_; -#endif -}; - -typedef GenericSchemaValidator SchemaValidator; - -/////////////////////////////////////////////////////////////////////////////// -// SchemaValidatingReader - -//! A helper class for parsing with validation. -/*! - This helper class is a functor, designed as a parameter of \ref GenericDocument::Populate(). - - \tparam parseFlags Combination of \ref ParseFlag. - \tparam InputStream Type of input stream, implementing Stream concept. - \tparam SourceEncoding Encoding of the input stream. - \tparam SchemaDocumentType Type of schema document. - \tparam StackAllocator Allocator type for stack. -*/ -template < - unsigned parseFlags, - typename InputStream, - typename SourceEncoding, - typename SchemaDocumentType = SchemaDocument, - typename StackAllocator = CrtAllocator> -class SchemaValidatingReader { -public: - typedef typename SchemaDocumentType::PointerType PointerType; - typedef typename InputStream::Ch Ch; - typedef GenericValue ValueType; - - //! Constructor - /*! - \param is Input stream. - \param sd Schema document. - */ - SchemaValidatingReader(InputStream& is, const SchemaDocumentType& sd) : is_(is), sd_(sd), invalidSchemaKeyword_(), error_(kObjectType), isValid_(true) {} - - template - bool operator()(Handler& handler) { - GenericReader reader; - GenericSchemaValidator validator(sd_, handler); - parseResult_ = reader.template Parse(is_, validator); - - isValid_ = validator.IsValid(); - if (isValid_) { - invalidSchemaPointer_ = PointerType(); - invalidSchemaKeyword_ = 0; - invalidDocumentPointer_ = PointerType(); - error_.SetObject(); - } - else { - invalidSchemaPointer_ = validator.GetInvalidSchemaPointer(); - invalidSchemaKeyword_ = validator.GetInvalidSchemaKeyword(); - invalidDocumentPointer_ = validator.GetInvalidDocumentPointer(); - error_.CopyFrom(validator.GetError(), allocator_); - } - - return parseResult_; - } - - const ParseResult& GetParseResult() const { return parseResult_; } - bool IsValid() const { return isValid_; } - const PointerType& GetInvalidSchemaPointer() const { return invalidSchemaPointer_; } - const Ch* GetInvalidSchemaKeyword() const { return invalidSchemaKeyword_; } - const PointerType& GetInvalidDocumentPointer() const { return invalidDocumentPointer_; } - const ValueType& GetError() const { return error_; } - -private: - InputStream& is_; - const SchemaDocumentType& sd_; - - ParseResult parseResult_; - PointerType invalidSchemaPointer_; - const Ch* invalidSchemaKeyword_; - PointerType invalidDocumentPointer_; - StackAllocator allocator_; - ValueType error_; - bool isValid_; -}; - -RAPIDJSON_NAMESPACE_END -RAPIDJSON_DIAG_POP - -#endif // RAPIDJSON_SCHEMA_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/stream.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/stream.h deleted file mode 100644 index 7f2643e4..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/stream.h +++ /dev/null @@ -1,223 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#include "rapidjson.h" - -#ifndef RAPIDJSON_STREAM_H_ -#define RAPIDJSON_STREAM_H_ - -#include "encodings.h" - -RAPIDJSON_NAMESPACE_BEGIN - -/////////////////////////////////////////////////////////////////////////////// -// Stream - -/*! \class rapidjson::Stream - \brief Concept for reading and writing characters. - - For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd(). - - For write-only stream, only need to implement Put() and Flush(). - -\code -concept Stream { - typename Ch; //!< Character type of the stream. - - //! Read the current character from stream without moving the read cursor. - Ch Peek() const; - - //! Read the current character from stream and moving the read cursor to next character. - Ch Take(); - - //! Get the current read cursor. - //! \return Number of characters read from start. - size_t Tell(); - - //! Begin writing operation at the current read pointer. - //! \return The begin writer pointer. - Ch* PutBegin(); - - //! Write a character. - void Put(Ch c); - - //! Flush the buffer. - void Flush(); - - //! End the writing operation. - //! \param begin The begin write pointer returned by PutBegin(). - //! \return Number of characters written. - size_t PutEnd(Ch* begin); -} -\endcode -*/ - -//! Provides additional information for stream. -/*! - By using traits pattern, this type provides a default configuration for stream. - For custom stream, this type can be specialized for other configuration. - See TEST(Reader, CustomStringStream) in readertest.cpp for example. -*/ -template -struct StreamTraits { - //! Whether to make local copy of stream for optimization during parsing. - /*! - By default, for safety, streams do not use local copy optimization. - Stream that can be copied fast should specialize this, like StreamTraits. - */ - enum { copyOptimization = 0 }; -}; - -//! Reserve n characters for writing to a stream. -template -inline void PutReserve(Stream& stream, size_t count) { - (void)stream; - (void)count; -} - -//! Write character to a stream, presuming buffer is reserved. -template -inline void PutUnsafe(Stream& stream, typename Stream::Ch c) { - stream.Put(c); -} - -//! Put N copies of a character to a stream. -template -inline void PutN(Stream& stream, Ch c, size_t n) { - PutReserve(stream, n); - for (size_t i = 0; i < n; i++) - PutUnsafe(stream, c); -} - -/////////////////////////////////////////////////////////////////////////////// -// GenericStreamWrapper - -//! A Stream Wrapper -/*! \tThis string stream is a wrapper for any stream by just forwarding any - \treceived message to the origin stream. - \note implements Stream concept -*/ - -#if defined(_MSC_VER) && _MSC_VER <= 1800 -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(4702) // unreachable code -RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated -#endif - -template > -class GenericStreamWrapper { -public: - typedef typename Encoding::Ch Ch; - GenericStreamWrapper(InputStream& is): is_(is) {} - - Ch Peek() const { return is_.Peek(); } - Ch Take() { return is_.Take(); } - size_t Tell() { return is_.Tell(); } - Ch* PutBegin() { return is_.PutBegin(); } - void Put(Ch ch) { is_.Put(ch); } - void Flush() { is_.Flush(); } - size_t PutEnd(Ch* ch) { return is_.PutEnd(ch); } - - // wrapper for MemoryStream - const Ch* Peek4() const { return is_.Peek4(); } - - // wrapper for AutoUTFInputStream - UTFType GetType() const { return is_.GetType(); } - bool HasBOM() const { return is_.HasBOM(); } - -protected: - InputStream& is_; -}; - -#if defined(_MSC_VER) && _MSC_VER <= 1800 -RAPIDJSON_DIAG_POP -#endif - -/////////////////////////////////////////////////////////////////////////////// -// StringStream - -//! Read-only string stream. -/*! \note implements Stream concept -*/ -template -struct GenericStringStream { - typedef typename Encoding::Ch Ch; - - GenericStringStream(const Ch *src) : src_(src), head_(src) {} - - Ch Peek() const { return *src_; } - Ch Take() { return *src_++; } - size_t Tell() const { return static_cast(src_ - head_); } - - Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - void Put(Ch) { RAPIDJSON_ASSERT(false); } - void Flush() { RAPIDJSON_ASSERT(false); } - size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } - - const Ch* src_; //!< Current read position. - const Ch* head_; //!< Original head of the string. -}; - -template -struct StreamTraits > { - enum { copyOptimization = 1 }; -}; - -//! String stream with UTF8 encoding. -typedef GenericStringStream > StringStream; - -/////////////////////////////////////////////////////////////////////////////// -// InsituStringStream - -//! A read-write string stream. -/*! This string stream is particularly designed for in-situ parsing. - \note implements Stream concept -*/ -template -struct GenericInsituStringStream { - typedef typename Encoding::Ch Ch; - - GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {} - - // Read - Ch Peek() { return *src_; } - Ch Take() { return *src_++; } - size_t Tell() { return static_cast(src_ - head_); } - - // Write - void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } - - Ch* PutBegin() { return dst_ = src_; } - size_t PutEnd(Ch* begin) { return static_cast(dst_ - begin); } - void Flush() {} - - Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; } - void Pop(size_t count) { dst_ -= count; } - - Ch* src_; - Ch* dst_; - Ch* head_; -}; - -template -struct StreamTraits > { - enum { copyOptimization = 1 }; -}; - -//! Insitu string stream with UTF8 encoding. -typedef GenericInsituStringStream > InsituStringStream; - -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_STREAM_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/stringbuffer.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/stringbuffer.h deleted file mode 100644 index 4e38b82c..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/stringbuffer.h +++ /dev/null @@ -1,121 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_STRINGBUFFER_H_ -#define RAPIDJSON_STRINGBUFFER_H_ - -#include "stream.h" -#include "internal/stack.h" - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS -#include // std::move -#endif - -#include "internal/stack.h" - -#if defined(__clang__) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(c++98-compat) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! Represents an in-memory output stream. -/*! - \tparam Encoding Encoding of the stream. - \tparam Allocator type for allocating memory buffer. - \note implements Stream concept -*/ -template -class GenericStringBuffer { -public: - typedef typename Encoding::Ch Ch; - - GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {} - GenericStringBuffer& operator=(GenericStringBuffer&& rhs) { - if (&rhs != this) - stack_ = std::move(rhs.stack_); - return *this; - } -#endif - - void Put(Ch c) { *stack_.template Push() = c; } - void PutUnsafe(Ch c) { *stack_.template PushUnsafe() = c; } - void Flush() {} - - void Clear() { stack_.Clear(); } - void ShrinkToFit() { - // Push and pop a null terminator. This is safe. - *stack_.template Push() = '\0'; - stack_.ShrinkToFit(); - stack_.template Pop(1); - } - - void Reserve(size_t count) { stack_.template Reserve(count); } - Ch* Push(size_t count) { return stack_.template Push(count); } - Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe(count); } - void Pop(size_t count) { stack_.template Pop(count); } - - const Ch* GetString() const { - // Push and pop a null terminator. This is safe. - *stack_.template Push() = '\0'; - stack_.template Pop(1); - - return stack_.template Bottom(); - } - - //! Get the size of string in bytes in the string buffer. - size_t GetSize() const { return stack_.GetSize(); } - - //! Get the length of string in Ch in the string buffer. - size_t GetLength() const { return stack_.GetSize() / sizeof(Ch); } - - static const size_t kDefaultCapacity = 256; - mutable internal::Stack stack_; - -private: - // Prohibit copy constructor & assignment operator. - GenericStringBuffer(const GenericStringBuffer&); - GenericStringBuffer& operator=(const GenericStringBuffer&); -}; - -//! String buffer with UTF8 encoding -typedef GenericStringBuffer > StringBuffer; - -template -inline void PutReserve(GenericStringBuffer& stream, size_t count) { - stream.Reserve(count); -} - -template -inline void PutUnsafe(GenericStringBuffer& stream, typename Encoding::Ch c) { - stream.PutUnsafe(c); -} - -//! Implement specialized version of PutN() with memset() for better performance. -template<> -inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { - std::memset(stream.stack_.Push(n), c, n * sizeof(c)); -} - -RAPIDJSON_NAMESPACE_END - -#if defined(__clang__) -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_STRINGBUFFER_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/writer.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/writer.h deleted file mode 100644 index 51dd86d5..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/rapidjson/writer.h +++ /dev/null @@ -1,710 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_WRITER_H_ -#define RAPIDJSON_WRITER_H_ - -#include "stream.h" -#include "internal/clzll.h" -#include "internal/meta.h" -#include "internal/stack.h" -#include "internal/strfunc.h" -#include "internal/dtoa.h" -#include "internal/itoa.h" -#include "stringbuffer.h" -#include // placement new - -#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) -#include -#pragma intrinsic(_BitScanForward) -#endif -#ifdef RAPIDJSON_SSE42 -#include -#elif defined(RAPIDJSON_SSE2) -#include -#elif defined(RAPIDJSON_NEON) -#include -#endif - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(padded) -RAPIDJSON_DIAG_OFF(unreachable-code) -RAPIDJSON_DIAG_OFF(c++98-compat) -#elif defined(_MSC_VER) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -/////////////////////////////////////////////////////////////////////////////// -// WriteFlag - -/*! \def RAPIDJSON_WRITE_DEFAULT_FLAGS - \ingroup RAPIDJSON_CONFIG - \brief User-defined kWriteDefaultFlags definition. - - User can define this as any \c WriteFlag combinations. -*/ -#ifndef RAPIDJSON_WRITE_DEFAULT_FLAGS -#define RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNoFlags -#endif - -//! Combination of writeFlags -enum WriteFlag { - kWriteNoFlags = 0, //!< No flags are set. - kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings. - kWriteNanAndInfFlag = 2, //!< Allow writing of Infinity, -Infinity and NaN. - kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS -}; - -//! JSON writer -/*! Writer implements the concept Handler. - It generates JSON text by events to an output os. - - User may programmatically calls the functions of a writer to generate JSON text. - - On the other side, a writer can also be passed to objects that generates events, - - for example Reader::Parse() and Document::Accept(). - - \tparam OutputStream Type of output stream. - \tparam SourceEncoding Encoding of source string. - \tparam TargetEncoding Encoding of output stream. - \tparam StackAllocator Type of allocator for allocating memory of stack. - \note implements Handler concept -*/ -template, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags> -class Writer { -public: - typedef typename SourceEncoding::Ch Ch; - - static const int kDefaultMaxDecimalPlaces = 324; - - //! Constructor - /*! \param os Output stream. - \param stackAllocator User supplied allocator. If it is null, it will create a private one. - \param levelDepth Initial capacity of stack. - */ - explicit - Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) : - os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {} - - explicit - Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : - os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {} - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - Writer(Writer&& rhs) : - os_(rhs.os_), level_stack_(std::move(rhs.level_stack_)), maxDecimalPlaces_(rhs.maxDecimalPlaces_), hasRoot_(rhs.hasRoot_) { - rhs.os_ = 0; - } -#endif - - //! Reset the writer with a new stream. - /*! - This function reset the writer with a new stream and default settings, - in order to make a Writer object reusable for output multiple JSONs. - - \param os New output stream. - \code - Writer writer(os1); - writer.StartObject(); - // ... - writer.EndObject(); - - writer.Reset(os2); - writer.StartObject(); - // ... - writer.EndObject(); - \endcode - */ - void Reset(OutputStream& os) { - os_ = &os; - hasRoot_ = false; - level_stack_.Clear(); - } - - //! Checks whether the output is a complete JSON. - /*! - A complete JSON has a complete root object or array. - */ - bool IsComplete() const { - return hasRoot_ && level_stack_.Empty(); - } - - int GetMaxDecimalPlaces() const { - return maxDecimalPlaces_; - } - - //! Sets the maximum number of decimal places for double output. - /*! - This setting truncates the output with specified number of decimal places. - - For example, - - \code - writer.SetMaxDecimalPlaces(3); - writer.StartArray(); - writer.Double(0.12345); // "0.123" - writer.Double(0.0001); // "0.0" - writer.Double(1.234567890123456e30); // "1.234567890123456e30" (do not truncate significand for positive exponent) - writer.Double(1.23e-4); // "0.0" (do truncate significand for negative exponent) - writer.EndArray(); - \endcode - - The default setting does not truncate any decimal places. You can restore to this setting by calling - \code - writer.SetMaxDecimalPlaces(Writer::kDefaultMaxDecimalPlaces); - \endcode - */ - void SetMaxDecimalPlaces(int maxDecimalPlaces) { - maxDecimalPlaces_ = maxDecimalPlaces; - } - - /*!@name Implementation of Handler - \see Handler - */ - //@{ - - bool Null() { Prefix(kNullType); return EndValue(WriteNull()); } - bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return EndValue(WriteBool(b)); } - bool Int(int i) { Prefix(kNumberType); return EndValue(WriteInt(i)); } - bool Uint(unsigned u) { Prefix(kNumberType); return EndValue(WriteUint(u)); } - bool Int64(int64_t i64) { Prefix(kNumberType); return EndValue(WriteInt64(i64)); } - bool Uint64(uint64_t u64) { Prefix(kNumberType); return EndValue(WriteUint64(u64)); } - - //! Writes the given \c double value to the stream - /*! - \param d The value to be written. - \return Whether it is succeed. - */ - bool Double(double d) { Prefix(kNumberType); return EndValue(WriteDouble(d)); } - - bool RawNumber(const Ch* str, SizeType length, bool copy = false) { - RAPIDJSON_ASSERT(str != 0); - (void)copy; - Prefix(kNumberType); - return EndValue(WriteString(str, length)); - } - - bool String(const Ch* str, SizeType length, bool copy = false) { - RAPIDJSON_ASSERT(str != 0); - (void)copy; - Prefix(kStringType); - return EndValue(WriteString(str, length)); - } - -#if RAPIDJSON_HAS_STDSTRING - bool String(const std::basic_string& str) { - return String(str.data(), SizeType(str.size())); - } -#endif - - bool StartObject() { - Prefix(kObjectType); - new (level_stack_.template Push()) Level(false); - return WriteStartObject(); - } - - bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } - -#if RAPIDJSON_HAS_STDSTRING - bool Key(const std::basic_string& str) - { - return Key(str.data(), SizeType(str.size())); - } -#endif - - bool EndObject(SizeType memberCount = 0) { - (void)memberCount; - RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); // not inside an Object - RAPIDJSON_ASSERT(!level_stack_.template Top()->inArray); // currently inside an Array, not Object - RAPIDJSON_ASSERT(0 == level_stack_.template Top()->valueCount % 2); // Object has a Key without a Value - level_stack_.template Pop(1); - return EndValue(WriteEndObject()); - } - - bool StartArray() { - Prefix(kArrayType); - new (level_stack_.template Push()) Level(true); - return WriteStartArray(); - } - - bool EndArray(SizeType elementCount = 0) { - (void)elementCount; - RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); - RAPIDJSON_ASSERT(level_stack_.template Top()->inArray); - level_stack_.template Pop(1); - return EndValue(WriteEndArray()); - } - //@} - - /*! @name Convenience extensions */ - //@{ - - //! Simpler but slower overload. - bool String(const Ch* const& str) { return String(str, internal::StrLen(str)); } - bool Key(const Ch* const& str) { return Key(str, internal::StrLen(str)); } - - //@} - - //! Write a raw JSON value. - /*! - For user to write a stringified JSON as a value. - - \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range. - \param length Length of the json. - \param type Type of the root of json. - */ - bool RawValue(const Ch* json, size_t length, Type type) { - RAPIDJSON_ASSERT(json != 0); - Prefix(type); - return EndValue(WriteRawValue(json, length)); - } - - //! Flush the output stream. - /*! - Allows the user to flush the output stream immediately. - */ - void Flush() { - os_->Flush(); - } - - static const size_t kDefaultLevelDepth = 32; - -protected: - //! Information for each nested level - struct Level { - Level(bool inArray_) : valueCount(0), inArray(inArray_) {} - size_t valueCount; //!< number of values in this level - bool inArray; //!< true if in array, otherwise in object - }; - - bool WriteNull() { - PutReserve(*os_, 4); - PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true; - } - - bool WriteBool(bool b) { - if (b) { - PutReserve(*os_, 4); - PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'r'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'e'); - } - else { - PutReserve(*os_, 5); - PutUnsafe(*os_, 'f'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 's'); PutUnsafe(*os_, 'e'); - } - return true; - } - - bool WriteInt(int i) { - char buffer[11]; - const char* end = internal::i32toa(i, buffer); - PutReserve(*os_, static_cast(end - buffer)); - for (const char* p = buffer; p != end; ++p) - PutUnsafe(*os_, static_cast(*p)); - return true; - } - - bool WriteUint(unsigned u) { - char buffer[10]; - const char* end = internal::u32toa(u, buffer); - PutReserve(*os_, static_cast(end - buffer)); - for (const char* p = buffer; p != end; ++p) - PutUnsafe(*os_, static_cast(*p)); - return true; - } - - bool WriteInt64(int64_t i64) { - char buffer[21]; - const char* end = internal::i64toa(i64, buffer); - PutReserve(*os_, static_cast(end - buffer)); - for (const char* p = buffer; p != end; ++p) - PutUnsafe(*os_, static_cast(*p)); - return true; - } - - bool WriteUint64(uint64_t u64) { - char buffer[20]; - char* end = internal::u64toa(u64, buffer); - PutReserve(*os_, static_cast(end - buffer)); - for (char* p = buffer; p != end; ++p) - PutUnsafe(*os_, static_cast(*p)); - return true; - } - - bool WriteDouble(double d) { - if (internal::Double(d).IsNanOrInf()) { - if (!(writeFlags & kWriteNanAndInfFlag)) - return false; - if (internal::Double(d).IsNan()) { - PutReserve(*os_, 3); - PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N'); - return true; - } - if (internal::Double(d).Sign()) { - PutReserve(*os_, 9); - PutUnsafe(*os_, '-'); - } - else - PutReserve(*os_, 8); - PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f'); - PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y'); - return true; - } - - char buffer[25]; - char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); - PutReserve(*os_, static_cast(end - buffer)); - for (char* p = buffer; p != end; ++p) - PutUnsafe(*os_, static_cast(*p)); - return true; - } - - bool WriteString(const Ch* str, SizeType length) { - static const typename OutputStream::Ch hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - static const char escape[256] = { -#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - //0 1 2 3 4 5 6 7 8 9 A B C D E F - 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00 - 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10 - 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 - Z16, Z16, // 30~4F - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50 - Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF -#undef Z16 - }; - - if (TargetEncoding::supportUnicode) - PutReserve(*os_, 2 + length * 6); // "\uxxxx..." - else - PutReserve(*os_, 2 + length * 12); // "\uxxxx\uyyyy..." - - PutUnsafe(*os_, '\"'); - GenericStringStream is(str); - while (ScanWriteUnescapedString(is, length)) { - const Ch c = is.Peek(); - if (!TargetEncoding::supportUnicode && static_cast(c) >= 0x80) { - // Unicode escaping - unsigned codepoint; - if (RAPIDJSON_UNLIKELY(!SourceEncoding::Decode(is, &codepoint))) - return false; - PutUnsafe(*os_, '\\'); - PutUnsafe(*os_, 'u'); - if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) { - PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]); - PutUnsafe(*os_, hexDigits[(codepoint >> 8) & 15]); - PutUnsafe(*os_, hexDigits[(codepoint >> 4) & 15]); - PutUnsafe(*os_, hexDigits[(codepoint ) & 15]); - } - else { - RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF); - // Surrogate pair - unsigned s = codepoint - 0x010000; - unsigned lead = (s >> 10) + 0xD800; - unsigned trail = (s & 0x3FF) + 0xDC00; - PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]); - PutUnsafe(*os_, hexDigits[(lead >> 8) & 15]); - PutUnsafe(*os_, hexDigits[(lead >> 4) & 15]); - PutUnsafe(*os_, hexDigits[(lead ) & 15]); - PutUnsafe(*os_, '\\'); - PutUnsafe(*os_, 'u'); - PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]); - PutUnsafe(*os_, hexDigits[(trail >> 8) & 15]); - PutUnsafe(*os_, hexDigits[(trail >> 4) & 15]); - PutUnsafe(*os_, hexDigits[(trail ) & 15]); - } - } - else if ((sizeof(Ch) == 1 || static_cast(c) < 256) && RAPIDJSON_UNLIKELY(escape[static_cast(c)])) { - is.Take(); - PutUnsafe(*os_, '\\'); - PutUnsafe(*os_, static_cast(escape[static_cast(c)])); - if (escape[static_cast(c)] == 'u') { - PutUnsafe(*os_, '0'); - PutUnsafe(*os_, '0'); - PutUnsafe(*os_, hexDigits[static_cast(c) >> 4]); - PutUnsafe(*os_, hexDigits[static_cast(c) & 0xF]); - } - } - else if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? - Transcoder::Validate(is, *os_) : - Transcoder::TranscodeUnsafe(is, *os_)))) - return false; - } - PutUnsafe(*os_, '\"'); - return true; - } - - bool ScanWriteUnescapedString(GenericStringStream& is, size_t length) { - return RAPIDJSON_LIKELY(is.Tell() < length); - } - - bool WriteStartObject() { os_->Put('{'); return true; } - bool WriteEndObject() { os_->Put('}'); return true; } - bool WriteStartArray() { os_->Put('['); return true; } - bool WriteEndArray() { os_->Put(']'); return true; } - - bool WriteRawValue(const Ch* json, size_t length) { - PutReserve(*os_, length); - GenericStringStream is(json); - while (RAPIDJSON_LIKELY(is.Tell() < length)) { - RAPIDJSON_ASSERT(is.Peek() != '\0'); - if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? - Transcoder::Validate(is, *os_) : - Transcoder::TranscodeUnsafe(is, *os_)))) - return false; - } - return true; - } - - void Prefix(Type type) { - (void)type; - if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root - Level* level = level_stack_.template Top(); - if (level->valueCount > 0) { - if (level->inArray) - os_->Put(','); // add comma if it is not the first element in array - else // in object - os_->Put((level->valueCount % 2 == 0) ? ',' : ':'); - } - if (!level->inArray && level->valueCount % 2 == 0) - RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name - level->valueCount++; - } - else { - RAPIDJSON_ASSERT(!hasRoot_); // Should only has one and only one root. - hasRoot_ = true; - } - } - - // Flush the value if it is the top level one. - bool EndValue(bool ret) { - if (RAPIDJSON_UNLIKELY(level_stack_.Empty())) // end of json text - Flush(); - return ret; - } - - OutputStream* os_; - internal::Stack level_stack_; - int maxDecimalPlaces_; - bool hasRoot_; - -private: - // Prohibit copy constructor & assignment operator. - Writer(const Writer&); - Writer& operator=(const Writer&); -}; - -// Full specialization for StringStream to prevent memory copying - -template<> -inline bool Writer::WriteInt(int i) { - char *buffer = os_->Push(11); - const char* end = internal::i32toa(i, buffer); - os_->Pop(static_cast(11 - (end - buffer))); - return true; -} - -template<> -inline bool Writer::WriteUint(unsigned u) { - char *buffer = os_->Push(10); - const char* end = internal::u32toa(u, buffer); - os_->Pop(static_cast(10 - (end - buffer))); - return true; -} - -template<> -inline bool Writer::WriteInt64(int64_t i64) { - char *buffer = os_->Push(21); - const char* end = internal::i64toa(i64, buffer); - os_->Pop(static_cast(21 - (end - buffer))); - return true; -} - -template<> -inline bool Writer::WriteUint64(uint64_t u) { - char *buffer = os_->Push(20); - const char* end = internal::u64toa(u, buffer); - os_->Pop(static_cast(20 - (end - buffer))); - return true; -} - -template<> -inline bool Writer::WriteDouble(double d) { - if (internal::Double(d).IsNanOrInf()) { - // Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag). - if (!(kWriteDefaultFlags & kWriteNanAndInfFlag)) - return false; - if (internal::Double(d).IsNan()) { - PutReserve(*os_, 3); - PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N'); - return true; - } - if (internal::Double(d).Sign()) { - PutReserve(*os_, 9); - PutUnsafe(*os_, '-'); - } - else - PutReserve(*os_, 8); - PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f'); - PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y'); - return true; - } - - char *buffer = os_->Push(25); - char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); - os_->Pop(static_cast(25 - (end - buffer))); - return true; -} - -#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) -template<> -inline bool Writer::ScanWriteUnescapedString(StringStream& is, size_t length) { - if (length < 16) - return RAPIDJSON_LIKELY(is.Tell() < length); - - if (!RAPIDJSON_LIKELY(is.Tell() < length)) - return false; - - const char* p = is.src_; - const char* end = is.head_ + length; - const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); - const char* endAligned = reinterpret_cast(reinterpret_cast(end) & static_cast(~15)); - if (nextAligned > end) - return true; - - while (p != nextAligned) - if (*p < 0x20 || *p == '\"' || *p == '\\') { - is.src_ = p; - return RAPIDJSON_LIKELY(is.Tell() < length); - } - else - os_->PutUnsafe(*p++); - - // The rest of string using SIMD - static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; - static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; - static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }; - const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); - const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); - const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); - - for (; p != endAligned; p += 16) { - const __m128i s = _mm_load_si128(reinterpret_cast(p)); - const __m128i t1 = _mm_cmpeq_epi8(s, dq); - const __m128i t2 = _mm_cmpeq_epi8(s, bs); - const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F - const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); - unsigned short r = static_cast(_mm_movemask_epi8(x)); - if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped - SizeType len; -#ifdef _MSC_VER // Find the index of first escaped - unsigned long offset; - _BitScanForward(&offset, r); - len = offset; -#else - len = static_cast(__builtin_ffs(r) - 1); -#endif - char* q = reinterpret_cast(os_->PushUnsafe(len)); - for (size_t i = 0; i < len; i++) - q[i] = p[i]; - - p += len; - break; - } - _mm_storeu_si128(reinterpret_cast<__m128i *>(os_->PushUnsafe(16)), s); - } - - is.src_ = p; - return RAPIDJSON_LIKELY(is.Tell() < length); -} -#elif defined(RAPIDJSON_NEON) -template<> -inline bool Writer::ScanWriteUnescapedString(StringStream& is, size_t length) { - if (length < 16) - return RAPIDJSON_LIKELY(is.Tell() < length); - - if (!RAPIDJSON_LIKELY(is.Tell() < length)) - return false; - - const char* p = is.src_; - const char* end = is.head_ + length; - const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); - const char* endAligned = reinterpret_cast(reinterpret_cast(end) & static_cast(~15)); - if (nextAligned > end) - return true; - - while (p != nextAligned) - if (*p < 0x20 || *p == '\"' || *p == '\\') { - is.src_ = p; - return RAPIDJSON_LIKELY(is.Tell() < length); - } - else - os_->PutUnsafe(*p++); - - // The rest of string using SIMD - const uint8x16_t s0 = vmovq_n_u8('"'); - const uint8x16_t s1 = vmovq_n_u8('\\'); - const uint8x16_t s2 = vmovq_n_u8('\b'); - const uint8x16_t s3 = vmovq_n_u8(32); - - for (; p != endAligned; p += 16) { - const uint8x16_t s = vld1q_u8(reinterpret_cast(p)); - uint8x16_t x = vceqq_u8(s, s0); - x = vorrq_u8(x, vceqq_u8(s, s1)); - x = vorrq_u8(x, vceqq_u8(s, s2)); - x = vorrq_u8(x, vcltq_u8(s, s3)); - - x = vrev64q_u8(x); // Rev in 64 - uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract - uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract - - SizeType len = 0; - bool escaped = false; - if (low == 0) { - if (high != 0) { - uint32_t lz = internal::clzll(high); - len = 8 + (lz >> 3); - escaped = true; - } - } else { - uint32_t lz = internal::clzll(low); - len = lz >> 3; - escaped = true; - } - if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped - char* q = reinterpret_cast(os_->PushUnsafe(len)); - for (size_t i = 0; i < len; i++) - q[i] = p[i]; - - p += len; - break; - } - vst1q_u8(reinterpret_cast(os_->PushUnsafe(16)), s); - } - - is.src_ = p; - return RAPIDJSON_LIKELY(is.Tell() < length); -} -#endif // RAPIDJSON_NEON - -RAPIDJSON_NAMESPACE_END - -#if defined(_MSC_VER) || defined(__clang__) -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/zip/CMakeLists.txt b/presentation/src/main/cpp/third_party/rlottie/src/lottie/zip/CMakeLists.txt deleted file mode 100644 index 05ed8d03..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/zip/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -target_sources(rlottie - PRIVATE - "${CMAKE_CURRENT_LIST_DIR}/zip.cpp" - ) - -target_include_directories(rlottie - PRIVATE - "${CMAKE_CURRENT_LIST_DIR}" - ) diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/zip/meson.build b/presentation/src/main/cpp/third_party/rlottie/src/lottie/zip/meson.build deleted file mode 100644 index fe8657ee..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/zip/meson.build +++ /dev/null @@ -1,9 +0,0 @@ - -source_file = [ - 'zip.cpp' -] - -zip_dep = [declare_dependency( - include_directories : include_directories('.'), - sources : source_file -)] diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/zip/miniz.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/zip/miniz.h deleted file mode 100644 index 04756ade..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/zip/miniz.h +++ /dev/null @@ -1,10130 +0,0 @@ -#define MINIZ_EXPORT -/* miniz.c 2.2.0 - public domain deflate/inflate, zlib-subset, ZIP - reading/writing/appending, PNG writing See "unlicense" statement at the end - of this file. Rich Geldreich , last updated Oct. 13, - 2013 Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: - http://www.ietf.org/rfc/rfc1951.txt - - Most API's defined in miniz.c are optional. For example, to disable the - archive related functions just define MINIZ_NO_ARCHIVE_APIS, or to get rid of - all stdio usage define MINIZ_NO_STDIO (see the list below for more macros). - - * Low-level Deflate/Inflate implementation notes: - - Compression: Use the "tdefl" API's. The compressor supports raw, static, - and dynamic blocks, lazy or greedy parsing, match length filtering, RLE-only, - and Huffman-only streams. It performs and compresses approximately as well as - zlib. - - Decompression: Use the "tinfl" API's. The entire decompressor is - implemented as a single function coroutine: see tinfl_decompress(). It - supports decompression into a 32KB (or larger power of 2) wrapping buffer, or - into a memory block large enough to hold the entire file. - - The low-level tdefl/tinfl API's do not make any use of dynamic memory - allocation. - - * zlib-style API notes: - - miniz.c implements a fairly large subset of zlib. There's enough - functionality present for it to be a drop-in zlib replacement in many apps: - The z_stream struct, optional memory allocation callbacks - deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound - inflateInit/inflateInit2/inflate/inflateReset/inflateEnd - compress, compress2, compressBound, uncompress - CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly - routines. Supports raw deflate streams or standard zlib streams with adler-32 - checking. - - Limitations: - The callback API's are not implemented yet. No support for gzip headers or - zlib static dictionaries. I've tried to closely emulate zlib's various - flavors of stream flushing and return status codes, but there are no - guarantees that miniz.c pulls this off perfectly. - - * PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, - originally written by Alex Evans. Supports 1-4 bytes/pixel images. - - * ZIP archive API notes: - - The ZIP archive API's where designed with simplicity and efficiency in - mind, with just enough abstraction to get the job done with minimal fuss. - There are simple API's to retrieve file information, read files from existing - archives, create new archives, append new files to existing archives, or - clone archive data from one archive to another. It supports archives located - in memory or the heap, on disk (using stdio.h), or you can specify custom - file read/write callbacks. - - - Archive reading: Just call this function to read a single file from a - disk archive: - - void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const - char *pArchive_name, size_t *pSize, mz_uint zip_flags); - - For more complex cases, use the "mz_zip_reader" functions. Upon opening an - archive, the entire central directory is located and read as-is into memory, - and subsequent file access only occurs when reading individual files. - - - Archives file scanning: The simple way is to use this function to scan a - loaded archive for a specific file: - - int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, - const char *pComment, mz_uint flags); - - The locate operation can optionally check file comments too, which (as one - example) can be used to identify multiple versions of the same file in an - archive. This function uses a simple linear search through the central - directory, so it's not very fast. - - Alternately, you can iterate through all the files in an archive (using - mz_zip_reader_get_num_files()) and retrieve detailed info on each file by - calling mz_zip_reader_file_stat(). - - - Archive creation: Use the "mz_zip_writer" functions. The ZIP writer - immediately writes compressed file data to disk and builds an exact image of - the central directory in memory. The central directory image is written all - at once at the end of the archive file when the archive is finalized. - - The archive writer can optionally align each file's local header and file - data to any power of 2 alignment, which can be useful when the archive will - be read from optical media. Also, the writer supports placing arbitrary data - blobs at the very beginning of ZIP archives. Archives written using either - feature are still readable by any ZIP tool. - - - Archive appending: The simple way to add a single file to an archive is - to call this function: - - mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, - const char *pArchive_name, const void *pBuf, size_t buf_size, const void - *pComment, mz_uint16 comment_size, mz_uint level_and_flags); - - The archive will be created if it doesn't already exist, otherwise it'll be - appended to. Note the appending is done in-place and is not an atomic - operation, so if something goes wrong during the operation it's possible the - archive could be left without a central directory (although the local file - headers and file data will be fine, so the archive will be recoverable). - - For more complex archive modification scenarios: - 1. The safest way is to use a mz_zip_reader to read the existing archive, - cloning only those bits you want to preserve into a new archive using using - the mz_zip_writer_add_from_zip_reader() function (which compiles the - compressed file data as-is). When you're done, delete the old archive and - rename the newly written archive, and you're done. This is safe but requires - a bunch of temporary disk space or heap memory. - - 2. Or, you can convert an mz_zip_reader in-place to an mz_zip_writer using - mz_zip_writer_init_from_reader(), append new files as needed, then finalize - the archive which will write an updated central directory to the original - archive. (This is basically what mz_zip_add_mem_to_archive_file_in_place() - does.) There's a possibility that the archive's central directory could be - lost with this method if anything goes wrong, though. - - - ZIP archive support limitations: - No spanning support. Extraction functions can only handle unencrypted, - stored or deflated files. Requires streams capable of seeking. - - * This is a header file library, like stb_image.c. To get only a header file, - either cut and paste the below header, or create miniz.h, #define - MINIZ_HEADER_FILE_ONLY, and then include miniz.c from it. - - * Important: For best perf. be sure to customize the below macros for your - target platform: #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 #define - MINIZ_LITTLE_ENDIAN 1 #define MINIZ_HAS_64BIT_REGISTERS 1 - - * On platforms using glibc, Be sure to "#define _LARGEFILE64_SOURCE 1" before - including miniz.c to ensure miniz uses the 64-bit variants: fopen64(), - stat64(), etc. Otherwise you won't be able to process large files (i.e. - 32-bit stat() fails for me on files > 0x7FFFFFFF bytes). -*/ -#pragma once - -/* Defines to completely disable specific portions of miniz.c: - If all macros here are defined the only functionality remaining will be - CRC-32, adler-32, tinfl, and tdefl. */ - -/* Define MINIZ_NO_STDIO to disable all usage and any functions which rely on - * stdio for file I/O. */ -/*#define MINIZ_NO_STDIO */ - -/* If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able - * to get the current time, or */ -/* get/set file times, and the C run-time funcs that get/set times won't be - * called. */ -/* The current downside is the times written to your archives will be from 1979. - */ -/*#define MINIZ_NO_TIME */ - -/* Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's. */ -/*#define MINIZ_NO_ARCHIVE_APIS */ - -/* Define MINIZ_NO_ARCHIVE_WRITING_APIS to disable all writing related ZIP - * archive API's. */ -/*#define MINIZ_NO_ARCHIVE_WRITING_APIS */ - -/* Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression - * API's. */ -/*#define MINIZ_NO_ZLIB_APIS */ - -/* Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent - * conflicts against stock zlib. */ -/*#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES */ - -/* Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc. - Note if MINIZ_NO_MALLOC is defined then the user must always provide custom - user alloc/free/realloc callbacks to the zlib and archive API's, and a few - stand-alone helper API's which don't provide custom user functions (such as - tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. - */ -/*#define MINIZ_NO_MALLOC */ - -#if defined(__TINYC__) && (defined(__linux) || defined(__linux__)) -/* TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc - * on Linux */ -#define MINIZ_NO_TIME -#endif - -#include - -#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS) -#include -#endif - -#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \ - defined(__i386) || defined(__i486__) || defined(__i486) || \ - defined(i386) || defined(__ia64__) || defined(__x86_64__) -/* MINIZ_X86_OR_X64_CPU is only used to help set the below macros. */ -#define MINIZ_X86_OR_X64_CPU 1 -#else -#define MINIZ_X86_OR_X64_CPU 0 -#endif - -#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU -/* Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. */ -#define MINIZ_LITTLE_ENDIAN 1 -#else -#define MINIZ_LITTLE_ENDIAN 0 -#endif - -/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES only if not set */ -#if !defined(MINIZ_USE_UNALIGNED_LOADS_AND_STORES) -#if MINIZ_X86_OR_X64_CPU -/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient - * integer loads and stores from unaligned addresses. */ -#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 -#define MINIZ_UNALIGNED_USE_MEMCPY -#else -#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0 -#endif -#endif - -#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || \ - defined(_LP64) || defined(__LP64__) || defined(__ia64__) || \ - defined(__x86_64__) -/* Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are - * reasonably fast (and don't involve compiler generated calls to helper - * functions). */ -#define MINIZ_HAS_64BIT_REGISTERS 1 -#else -#define MINIZ_HAS_64BIT_REGISTERS 0 -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* ------------------- zlib-style API Definitions. */ - -/* For more compatibility with zlib, miniz.c uses unsigned long for some - * parameters/struct members. Beware: mz_ulong can be either 32 or 64-bits! */ -typedef unsigned long mz_ulong; - -/* mz_free() internally uses the MZ_FREE() macro (which by default calls free() - * unless you've modified the MZ_MALLOC macro) to release a block allocated from - * the heap. */ -MINIZ_EXPORT void mz_free(void *p); - -#define MZ_ADLER32_INIT (1) -/* mz_adler32() returns the initial adler-32 value to use when called with - * ptr==NULL. */ -MINIZ_EXPORT mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, - size_t buf_len); - -#define MZ_CRC32_INIT (0) -/* mz_crc32() returns the initial CRC-32 value to use when called with - * ptr==NULL. */ -MINIZ_EXPORT mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, - size_t buf_len); - -/* Compression strategies. */ -enum { - MZ_DEFAULT_STRATEGY = 0, - MZ_FILTERED = 1, - MZ_HUFFMAN_ONLY = 2, - MZ_RLE = 3, - MZ_FIXED = 4 -}; - -/* Method */ -#define MZ_DEFLATED 8 - -/* Heap allocation callbacks. -Note that mz_alloc_func parameter types purposely differ from zlib's: items/size -is size_t, not unsigned long. */ -typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size); -typedef void (*mz_free_func)(void *opaque, void *address); -typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, - size_t size); - -/* Compression levels: 0-9 are the standard zlib-style levels, 10 is best - * possible compression (not zlib compatible, and may be very slow), - * MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL. */ -enum { - MZ_NO_COMPRESSION = 0, - MZ_BEST_SPEED = 1, - MZ_BEST_COMPRESSION = 9, - MZ_UBER_COMPRESSION = 10, - MZ_DEFAULT_LEVEL = 6, - MZ_DEFAULT_COMPRESSION = -1 -}; - -#define MZ_VERSION "10.2.0" -#define MZ_VERNUM 0xA100 -#define MZ_VER_MAJOR 10 -#define MZ_VER_MINOR 2 -#define MZ_VER_REVISION 0 -#define MZ_VER_SUBREVISION 0 - -#ifndef MINIZ_NO_ZLIB_APIS - -/* Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The - * other values are for advanced use (refer to the zlib docs). */ -enum { - MZ_NO_FLUSH = 0, - MZ_PARTIAL_FLUSH = 1, - MZ_SYNC_FLUSH = 2, - MZ_FULL_FLUSH = 3, - MZ_FINISH = 4, - MZ_BLOCK = 5 -}; - -/* Return status codes. MZ_PARAM_ERROR is non-standard. */ -enum { - MZ_OK = 0, - MZ_STREAM_END = 1, - MZ_NEED_DICT = 2, - MZ_ERRNO = -1, - MZ_STREAM_ERROR = -2, - MZ_DATA_ERROR = -3, - MZ_MEM_ERROR = -4, - MZ_BUF_ERROR = -5, - MZ_VERSION_ERROR = -6, - MZ_PARAM_ERROR = -10000 -}; - -/* Window bits */ -#define MZ_DEFAULT_WINDOW_BITS 15 - -struct mz_internal_state; - -/* Compression/decompression stream struct. */ -typedef struct mz_stream_s { - const unsigned char *next_in; /* pointer to next byte to read */ - unsigned int avail_in; /* number of bytes available at next_in */ - mz_ulong total_in; /* total number of bytes consumed so far */ - - unsigned char *next_out; /* pointer to next byte to write */ - unsigned int avail_out; /* number of bytes that can be written to next_out */ - mz_ulong total_out; /* total number of bytes produced so far */ - - char *msg; /* error msg (unused) */ - struct mz_internal_state - *state; /* internal state, allocated by zalloc/zfree */ - - mz_alloc_func - zalloc; /* optional heap allocation function (defaults to malloc) */ - mz_free_func zfree; /* optional heap free function (defaults to free) */ - void *opaque; /* heap alloc function user pointer */ - - int data_type; /* data_type (unused) */ - mz_ulong adler; /* adler32 of the source or uncompressed data */ - mz_ulong reserved; /* not used */ -} mz_stream; - -typedef mz_stream *mz_streamp; - -/* Returns the version string of miniz.c. */ -MINIZ_EXPORT const char *mz_version(void); - -/* mz_deflateInit() initializes a compressor with default options: */ -/* Parameters: */ -/* pStream must point to an initialized mz_stream struct. */ -/* level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION]. */ -/* level 1 enables a specially optimized compression function that's been - * optimized purely for performance, not ratio. */ -/* (This special func. is currently only enabled when - * MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.) */ -/* Return values: */ -/* MZ_OK on success. */ -/* MZ_STREAM_ERROR if the stream is bogus. */ -/* MZ_PARAM_ERROR if the input parameters are bogus. */ -/* MZ_MEM_ERROR on out of memory. */ -MINIZ_EXPORT int mz_deflateInit(mz_streamp pStream, int level); - -/* mz_deflateInit2() is like mz_deflate(), except with more control: */ -/* Additional parameters: */ -/* method must be MZ_DEFLATED */ -/* window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with - * zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no - * header or footer) */ -/* mem_level must be between [1, 9] (it's checked but ignored by miniz.c) */ -MINIZ_EXPORT int mz_deflateInit2(mz_streamp pStream, int level, int method, - int window_bits, int mem_level, int strategy); - -/* Quickly resets a compressor without having to reallocate anything. Same as - * calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2(). */ -MINIZ_EXPORT int mz_deflateReset(mz_streamp pStream); - -/* mz_deflate() compresses the input to output, consuming as much of the input - * and producing as much output as possible. */ -/* Parameters: */ -/* pStream is the stream to read from and write to. You must initialize/update - * the next_in, avail_in, next_out, and avail_out members. */ -/* flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or - * MZ_FINISH. */ -/* Return values: */ -/* MZ_OK on success (when flushing, or if more input is needed but not - * available, and/or there's more output to be written but the output buffer is - * full). */ -/* MZ_STREAM_END if all input has been consumed and all output bytes have been - * written. Don't call mz_deflate() on the stream anymore. */ -/* MZ_STREAM_ERROR if the stream is bogus. */ -/* MZ_PARAM_ERROR if one of the parameters is invalid. */ -/* MZ_BUF_ERROR if no forward progress is possible because the input and/or - * output buffers are empty. (Fill up the input buffer or free up some output - * space and try again.) */ -MINIZ_EXPORT int mz_deflate(mz_streamp pStream, int flush); - -/* mz_deflateEnd() deinitializes a compressor: */ -/* Return values: */ -/* MZ_OK on success. */ -/* MZ_STREAM_ERROR if the stream is bogus. */ -MINIZ_EXPORT int mz_deflateEnd(mz_streamp pStream); - -/* mz_deflateBound() returns a (very) conservative upper bound on the amount of - * data that could be generated by deflate(), assuming flush is set to only - * MZ_NO_FLUSH or MZ_FINISH. */ -MINIZ_EXPORT mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len); - -/* Single-call compression functions mz_compress() and mz_compress2(): */ -/* Returns MZ_OK on success, or one of the error codes from mz_deflate() on - * failure. */ -MINIZ_EXPORT int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, - const unsigned char *pSource, mz_ulong source_len); -MINIZ_EXPORT int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, - const unsigned char *pSource, mz_ulong source_len, - int level); - -/* mz_compressBound() returns a (very) conservative upper bound on the amount of - * data that could be generated by calling mz_compress(). */ -MINIZ_EXPORT mz_ulong mz_compressBound(mz_ulong source_len); - -/* Initializes a decompressor. */ -MINIZ_EXPORT int mz_inflateInit(mz_streamp pStream); - -/* mz_inflateInit2() is like mz_inflateInit() with an additional option that - * controls the window size and whether or not the stream has been wrapped with - * a zlib header/footer: */ -/* window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or - * -MZ_DEFAULT_WINDOW_BITS (raw deflate). */ -MINIZ_EXPORT int mz_inflateInit2(mz_streamp pStream, int window_bits); - -/* Quickly resets a compressor without having to reallocate anything. Same as - * calling mz_inflateEnd() followed by mz_inflateInit()/mz_inflateInit2(). */ -MINIZ_EXPORT int mz_inflateReset(mz_streamp pStream); - -/* Decompresses the input stream to the output, consuming only as much of the - * input as needed, and writing as much to the output as possible. */ -/* Parameters: */ -/* pStream is the stream to read from and write to. You must initialize/update - * the next_in, avail_in, next_out, and avail_out members. */ -/* flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH. */ -/* On the first call, if flush is MZ_FINISH it's assumed the input and output - * buffers are both sized large enough to decompress the entire stream in a - * single call (this is slightly faster). */ -/* MZ_FINISH implies that there are no more source bytes available beside - * what's already in the input buffer, and that the output buffer is large - * enough to hold the rest of the decompressed data. */ -/* Return values: */ -/* MZ_OK on success. Either more input is needed but not available, and/or - * there's more output to be written but the output buffer is full. */ -/* MZ_STREAM_END if all needed input has been consumed and all output bytes - * have been written. For zlib streams, the adler-32 of the decompressed data - * has also been verified. */ -/* MZ_STREAM_ERROR if the stream is bogus. */ -/* MZ_DATA_ERROR if the deflate stream is invalid. */ -/* MZ_PARAM_ERROR if one of the parameters is invalid. */ -/* MZ_BUF_ERROR if no forward progress is possible because the input buffer is - * empty but the inflater needs more input to continue, or if the output buffer - * is not large enough. Call mz_inflate() again */ -/* with more input data, or with more room in the output buffer (except when - * using single call decompression, described above). */ -MINIZ_EXPORT int mz_inflate(mz_streamp pStream, int flush); - -/* Deinitializes a decompressor. */ -MINIZ_EXPORT int mz_inflateEnd(mz_streamp pStream); - -/* Single-call decompression. */ -/* Returns MZ_OK on success, or one of the error codes from mz_inflate() on - * failure. */ -MINIZ_EXPORT int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, - const unsigned char *pSource, - mz_ulong source_len); -MINIZ_EXPORT int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, - const unsigned char *pSource, - mz_ulong *pSource_len); - -/* Returns a string description of the specified error code, or NULL if the - * error code is invalid. */ -MINIZ_EXPORT const char *mz_error(int err); - -/* Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used - * as a drop-in replacement for the subset of zlib that miniz.c supports. */ -/* Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you - * use zlib in the same project. */ -#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES -typedef unsigned char Byte; -typedef unsigned int uInt; -typedef mz_ulong uLong; -typedef Byte Bytef; -typedef uInt uIntf; -typedef char charf; -typedef int intf; -typedef void *voidpf; -typedef uLong uLongf; -typedef void *voidp; -typedef void *const voidpc; -#define Z_NULL 0 -#define Z_NO_FLUSH MZ_NO_FLUSH -#define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH -#define Z_SYNC_FLUSH MZ_SYNC_FLUSH -#define Z_FULL_FLUSH MZ_FULL_FLUSH -#define Z_FINISH MZ_FINISH -#define Z_BLOCK MZ_BLOCK -#define Z_OK MZ_OK -#define Z_STREAM_END MZ_STREAM_END -#define Z_NEED_DICT MZ_NEED_DICT -#define Z_ERRNO MZ_ERRNO -#define Z_STREAM_ERROR MZ_STREAM_ERROR -#define Z_DATA_ERROR MZ_DATA_ERROR -#define Z_MEM_ERROR MZ_MEM_ERROR -#define Z_BUF_ERROR MZ_BUF_ERROR -#define Z_VERSION_ERROR MZ_VERSION_ERROR -#define Z_PARAM_ERROR MZ_PARAM_ERROR -#define Z_NO_COMPRESSION MZ_NO_COMPRESSION -#define Z_BEST_SPEED MZ_BEST_SPEED -#define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION -#define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION -#define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY -#define Z_FILTERED MZ_FILTERED -#define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY -#define Z_RLE MZ_RLE -#define Z_FIXED MZ_FIXED -#define Z_DEFLATED MZ_DEFLATED -#define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS -#define alloc_func mz_alloc_func -#define free_func mz_free_func -#define internal_state mz_internal_state -#define z_stream mz_stream -#define deflateInit mz_deflateInit -#define deflateInit2 mz_deflateInit2 -#define deflateReset mz_deflateReset -#define deflate mz_deflate -#define deflateEnd mz_deflateEnd -#define deflateBound mz_deflateBound -#define compress mz_compress -#define compress2 mz_compress2 -#define compressBound mz_compressBound -#define inflateInit mz_inflateInit -#define inflateInit2 mz_inflateInit2 -#define inflateReset mz_inflateReset -#define inflate mz_inflate -#define inflateEnd mz_inflateEnd -#define uncompress mz_uncompress -#define uncompress2 mz_uncompress2 -#define crc32 mz_crc32 -#define adler32 mz_adler32 -#define MAX_WBITS 15 -#define MAX_MEM_LEVEL 9 -#define zError mz_error -#define ZLIB_VERSION MZ_VERSION -#define ZLIB_VERNUM MZ_VERNUM -#define ZLIB_VER_MAJOR MZ_VER_MAJOR -#define ZLIB_VER_MINOR MZ_VER_MINOR -#define ZLIB_VER_REVISION MZ_VER_REVISION -#define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION -#define zlibVersion mz_version -#define zlib_version mz_version() -#endif /* #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES */ - -#endif /* MINIZ_NO_ZLIB_APIS */ - -#ifdef __cplusplus -} -#endif - -#pragma once -#include -#include -#include -#include - -/* ------------------- Types and macros */ -typedef unsigned char mz_uint8; -typedef signed short mz_int16; -typedef unsigned short mz_uint16; -typedef unsigned int mz_uint32; -typedef unsigned int mz_uint; -typedef int64_t mz_int64; -typedef uint64_t mz_uint64; -typedef int mz_bool; - -#define MZ_FALSE (0) -#define MZ_TRUE (1) - -/* Works around MSVC's spammy "warning C4127: conditional expression is - * constant" message. */ -#ifdef _MSC_VER -#define MZ_MACRO_END while (0, 0) -#else -#define MZ_MACRO_END while (0) -#endif - -#ifdef MINIZ_NO_STDIO -#define MZ_FILE void * -#else -#include -#define MZ_FILE FILE -#endif /* #ifdef MINIZ_NO_STDIO */ - -#ifdef MINIZ_NO_TIME -typedef struct mz_dummy_time_t_tag { - int m_dummy; -} mz_dummy_time_t; -#define MZ_TIME_T mz_dummy_time_t -#else -#define MZ_TIME_T time_t -#endif - -#define MZ_ASSERT(x) assert(x) - -#ifdef MINIZ_NO_MALLOC -#define MZ_MALLOC(x) NULL -#define MZ_FREE(x) (void)x, ((void)0) -#define MZ_REALLOC(p, x) NULL -#else -#define MZ_MALLOC(x) malloc(x) -#define MZ_FREE(x) free(x) -#define MZ_REALLOC(p, x) realloc(p, x) -#endif - -#define MZ_MAX(a, b) (((a) > (b)) ? (a) : (b)) -#define MZ_MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj)) - -#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN -#define MZ_READ_LE16(p) *((const mz_uint16 *)(p)) -#define MZ_READ_LE32(p) *((const mz_uint32 *)(p)) -#else -#define MZ_READ_LE16(p) \ - ((mz_uint32)(((const mz_uint8 *)(p))[0]) | \ - ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U)) -#define MZ_READ_LE32(p) \ - ((mz_uint32)(((const mz_uint8 *)(p))[0]) | \ - ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | \ - ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | \ - ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U)) -#endif - -#define MZ_READ_LE64(p) \ - (((mz_uint64)MZ_READ_LE32(p)) | \ - (((mz_uint64)MZ_READ_LE32((const mz_uint8 *)(p) + sizeof(mz_uint32))) \ - << 32U)) - -#ifdef _MSC_VER -#define MZ_FORCEINLINE __forceinline -#elif defined(__GNUC__) -#define MZ_FORCEINLINE __inline__ __attribute__((__always_inline__)) -#else -#define MZ_FORCEINLINE inline -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -extern MINIZ_EXPORT void *miniz_def_alloc_func(void *opaque, size_t items, - size_t size); -extern MINIZ_EXPORT void miniz_def_free_func(void *opaque, void *address); -extern MINIZ_EXPORT void *miniz_def_realloc_func(void *opaque, void *address, - size_t items, size_t size); - -#define MZ_UINT16_MAX (0xFFFFU) -#define MZ_UINT32_MAX (0xFFFFFFFFU) - -#ifdef __cplusplus -} -#endif -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif -/* ------------------- Low-level Compression API Definitions */ - -/* Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly - * slower, and raw/dynamic blocks will be output more frequently). */ -#define TDEFL_LESS_MEMORY 0 - -/* tdefl_init() compression flags logically OR'd together (low 12 bits contain - * the max. number of probes per dictionary search): */ -/* TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes - * per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap - * compression), 4095=Huffman+LZ (slowest/best compression). */ -enum { - TDEFL_HUFFMAN_ONLY = 0, - TDEFL_DEFAULT_MAX_PROBES = 128, - TDEFL_MAX_PROBES_MASK = 0xFFF -}; - -/* TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before - * the deflate data, and the Adler-32 of the source data at the end. Otherwise, - * you'll get raw deflate data. */ -/* TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even - * when not writing zlib headers). */ -/* TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more - * efficient lazy parsing. */ -/* TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's - * initialization time to the minimum, but the output may vary from run to run - * given the same input (depending on the contents of memory). */ -/* TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1) - */ -/* TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled. */ -/* TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables. */ -/* TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks. */ -/* The low 12 bits are reserved to control the max # of hash probes per - * dictionary lookup (see TDEFL_MAX_PROBES_MASK). */ -enum { - TDEFL_WRITE_ZLIB_HEADER = 0x01000, - TDEFL_COMPUTE_ADLER32 = 0x02000, - TDEFL_GREEDY_PARSING_FLAG = 0x04000, - TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000, - TDEFL_RLE_MATCHES = 0x10000, - TDEFL_FILTER_MATCHES = 0x20000, - TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000, - TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000 -}; - -/* High level compression functions: */ -/* tdefl_compress_mem_to_heap() compresses a block in memory to a heap block - * allocated via malloc(). */ -/* On entry: */ -/* pSrc_buf, src_buf_len: Pointer and size of source block to compress. */ -/* flags: The max match finder probes (default is 128) logically OR'd against - * the above flags. Higher probes are slower but improve compression. */ -/* On return: */ -/* Function returns a pointer to the compressed data, or NULL on failure. */ -/* *pOut_len will be set to the compressed data's size, which could be larger - * than src_buf_len on uncompressible data. */ -/* The caller must free() the returned block when it's no longer needed. */ -MINIZ_EXPORT void *tdefl_compress_mem_to_heap(const void *pSrc_buf, - size_t src_buf_len, - size_t *pOut_len, int flags); - -/* tdefl_compress_mem_to_mem() compresses a block in memory to another block in - * memory. */ -/* Returns 0 on failure. */ -MINIZ_EXPORT size_t tdefl_compress_mem_to_mem(void *pOut_buf, - size_t out_buf_len, - const void *pSrc_buf, - size_t src_buf_len, int flags); - -/* Compresses an image to a compressed PNG file in memory. */ -/* On entry: */ -/* pImage, w, h, and num_chans describe the image to compress. num_chans may be - * 1, 2, 3, or 4. */ -/* The image pitch in bytes per scanline will be w*num_chans. The leftmost - * pixel on the top scanline is stored first in memory. */ -/* level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, - * MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL */ -/* If flip is true, the image will be flipped on the Y axis (useful for OpenGL - * apps). */ -/* On return: */ -/* Function returns a pointer to the compressed data, or NULL on failure. */ -/* *pLen_out will be set to the size of the PNG image file. */ -/* The caller must mz_free() the returned heap block (which will typically be - * larger than *pLen_out) when it's no longer needed. */ -MINIZ_EXPORT void * -tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, - int num_chans, size_t *pLen_out, - mz_uint level, mz_bool flip); -MINIZ_EXPORT void *tdefl_write_image_to_png_file_in_memory(const void *pImage, - int w, int h, - int num_chans, - size_t *pLen_out); - -/* Output stream interface. The compressor uses this interface to write - * compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time. */ -typedef mz_bool (*tdefl_put_buf_func_ptr)(const void *pBuf, int len, - void *pUser); - -/* tdefl_compress_mem_to_output() compresses a block to an output stream. The - * above helpers use this function internally. */ -MINIZ_EXPORT mz_bool tdefl_compress_mem_to_output( - const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, - void *pPut_buf_user, int flags); - -enum { - TDEFL_MAX_HUFF_TABLES = 3, - TDEFL_MAX_HUFF_SYMBOLS_0 = 288, - TDEFL_MAX_HUFF_SYMBOLS_1 = 32, - TDEFL_MAX_HUFF_SYMBOLS_2 = 19, - TDEFL_LZ_DICT_SIZE = 32768, - TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1, - TDEFL_MIN_MATCH_LEN = 3, - TDEFL_MAX_MATCH_LEN = 258 -}; - -/* TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed - * output block (using static/fixed Huffman codes). */ -#if TDEFL_LESS_MEMORY -enum { - TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024, - TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10, - TDEFL_MAX_HUFF_SYMBOLS = 288, - TDEFL_LZ_HASH_BITS = 12, - TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, - TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, - TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS -}; -#else -enum { - TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024, - TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10, - TDEFL_MAX_HUFF_SYMBOLS = 288, - TDEFL_LZ_HASH_BITS = 15, - TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, - TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, - TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS -}; -#endif - -/* The low-level tdefl functions below may be used directly if the above helper - * functions aren't flexible enough. The low-level functions don't make any heap - * allocations, unlike the above helper functions. */ -typedef enum { - TDEFL_STATUS_BAD_PARAM = -2, - TDEFL_STATUS_PUT_BUF_FAILED = -1, - TDEFL_STATUS_OKAY = 0, - TDEFL_STATUS_DONE = 1 -} tdefl_status; - -/* Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums */ -typedef enum { - TDEFL_NO_FLUSH = 0, - TDEFL_SYNC_FLUSH = 2, - TDEFL_FULL_FLUSH = 3, - TDEFL_FINISH = 4 -} tdefl_flush; - -/* tdefl's compression state structure. */ -typedef struct { - tdefl_put_buf_func_ptr m_pPut_buf_func; - void *m_pPut_buf_user; - mz_uint m_flags, m_max_probes[2]; - int m_greedy_parsing; - mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size; - mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end; - mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, - m_bit_buffer; - mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, - m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, - m_wants_to_finish; - tdefl_status m_prev_return_status; - const void *m_pIn_buf; - void *m_pOut_buf; - size_t *m_pIn_buf_size, *m_pOut_buf_size; - tdefl_flush m_flush; - const mz_uint8 *m_pSrc; - size_t m_src_buf_left, m_out_buf_ofs; - mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1]; - mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; - mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; - mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; - mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE]; - mz_uint16 m_next[TDEFL_LZ_DICT_SIZE]; - mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE]; - mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE]; -} tdefl_compressor; - -/* Initializes the compressor. */ -/* There is no corresponding deinit() function because the tdefl API's do not - * dynamically allocate memory. */ -/* pBut_buf_func: If NULL, output data will be supplied to the specified - * callback. In this case, the user should call the tdefl_compress_buffer() API - * for compression. */ -/* If pBut_buf_func is NULL the user should always call the tdefl_compress() - * API. */ -/* flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, - * etc.) */ -MINIZ_EXPORT tdefl_status tdefl_init(tdefl_compressor *d, - tdefl_put_buf_func_ptr pPut_buf_func, - void *pPut_buf_user, int flags); - -/* Compresses a block of data, consuming as much of the specified input buffer - * as possible, and writing as much compressed data to the specified output - * buffer as possible. */ -MINIZ_EXPORT tdefl_status tdefl_compress(tdefl_compressor *d, - const void *pIn_buf, - size_t *pIn_buf_size, void *pOut_buf, - size_t *pOut_buf_size, - tdefl_flush flush); - -/* tdefl_compress_buffer() is only usable when the tdefl_init() is called with a - * non-NULL tdefl_put_buf_func_ptr. */ -/* tdefl_compress_buffer() always consumes the entire input buffer. */ -MINIZ_EXPORT tdefl_status tdefl_compress_buffer(tdefl_compressor *d, - const void *pIn_buf, - size_t in_buf_size, - tdefl_flush flush); - -MINIZ_EXPORT tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d); -MINIZ_EXPORT mz_uint32 tdefl_get_adler32(tdefl_compressor *d); - -/* Create tdefl_compress() flags given zlib-style compression parameters. */ -/* level may range from [0,10] (where 10 is absolute max compression, but may be - * much slower on some files) */ -/* window_bits may be -15 (raw deflate) or 15 (zlib) */ -/* strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, - * MZ_RLE, or MZ_FIXED */ -MINIZ_EXPORT mz_uint tdefl_create_comp_flags_from_zip_params(int level, - int window_bits, - int strategy); - -#ifndef MINIZ_NO_MALLOC -/* Allocate the tdefl_compressor structure in C so that */ -/* non-C language bindings to tdefl_ API don't need to worry about */ -/* structure size and allocation mechanism. */ -MINIZ_EXPORT tdefl_compressor *tdefl_compressor_alloc(void); -MINIZ_EXPORT void tdefl_compressor_free(tdefl_compressor *pComp); -#endif - -#ifdef __cplusplus -} -#endif -#pragma once - -/* ------------------- Low-level Decompression API Definitions */ - -#ifdef __cplusplus -extern "C" { -#endif -/* Decompression flags used by tinfl_decompress(). */ -/* TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and - * ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the - * input is a raw deflate stream. */ -/* TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available - * beyond the end of the supplied input buffer. If clear, the input buffer - * contains all remaining input. */ -/* TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large - * enough to hold the entire decompressed stream. If clear, the output buffer is - * at least the size of the dictionary (typically 32KB). */ -/* TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the - * decompressed bytes. */ -enum { - TINFL_FLAG_PARSE_ZLIB_HEADER = 1, - TINFL_FLAG_HAS_MORE_INPUT = 2, - TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4, - TINFL_FLAG_COMPUTE_ADLER32 = 8 -}; - -/* High level decompression functions: */ -/* tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block - * allocated via malloc(). */ -/* On entry: */ -/* pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data - * to decompress. */ -/* On return: */ -/* Function returns a pointer to the decompressed data, or NULL on failure. */ -/* *pOut_len will be set to the decompressed data's size, which could be larger - * than src_buf_len on uncompressible data. */ -/* The caller must call mz_free() on the returned block when it's no longer - * needed. */ -MINIZ_EXPORT void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, - size_t src_buf_len, - size_t *pOut_len, int flags); - -/* tinfl_decompress_mem_to_mem() decompresses a block in memory to another block - * in memory. */ -/* Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes - * written on success. */ -#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1)) -MINIZ_EXPORT size_t tinfl_decompress_mem_to_mem(void *pOut_buf, - size_t out_buf_len, - const void *pSrc_buf, - size_t src_buf_len, int flags); - -/* tinfl_decompress_mem_to_callback() decompresses a block in memory to an - * internal 32KB buffer, and a user provided callback function will be called to - * flush the buffer. */ -/* Returns 1 on success or 0 on failure. */ -typedef int (*tinfl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser); -MINIZ_EXPORT int -tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, - tinfl_put_buf_func_ptr pPut_buf_func, - void *pPut_buf_user, int flags); - -struct tinfl_decompressor_tag; -typedef struct tinfl_decompressor_tag tinfl_decompressor; - -#ifndef MINIZ_NO_MALLOC -/* Allocate the tinfl_decompressor structure in C so that */ -/* non-C language bindings to tinfl_ API don't need to worry about */ -/* structure size and allocation mechanism. */ -MINIZ_EXPORT tinfl_decompressor *tinfl_decompressor_alloc(void); -MINIZ_EXPORT void tinfl_decompressor_free(tinfl_decompressor *pDecomp); -#endif - -/* Max size of LZ dictionary. */ -#define TINFL_LZ_DICT_SIZE 32768 - -/* Return status. */ -typedef enum { - /* This flags indicates the inflator needs 1 or more input bytes to make - forward progress, but the caller is indicating that no more are available. - The compressed data */ - /* is probably corrupted. If you call the inflator again with more bytes it'll - try to continue processing the input but this is a BAD sign (either the - data is corrupted or you called it incorrectly). */ - /* If you call it again with no input you'll just get - TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS again. */ - TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS = -4, - - /* This flag indicates that one or more of the input parameters was obviously - bogus. (You can try calling it again, but if you get this error the calling - code is wrong.) */ - TINFL_STATUS_BAD_PARAM = -3, - - /* This flags indicate the inflator is finished but the adler32 check of the - uncompressed data didn't match. If you call it again it'll return - TINFL_STATUS_DONE. */ - TINFL_STATUS_ADLER32_MISMATCH = -2, - - /* This flags indicate the inflator has somehow failed (bad code, corrupted - input, etc.). If you call it again without resetting via tinfl_init() it - it'll just keep on returning the same status failure code. */ - TINFL_STATUS_FAILED = -1, - - /* Any status code less than TINFL_STATUS_DONE must indicate a failure. */ - - /* This flag indicates the inflator has returned every byte of uncompressed - data that it can, has consumed every byte that it needed, has successfully - reached the end of the deflate stream, and */ - /* if zlib headers and adler32 checking enabled that it has successfully - checked the uncompressed data's adler32. If you call it again you'll just - get TINFL_STATUS_DONE over and over again. */ - TINFL_STATUS_DONE = 0, - - /* This flag indicates the inflator MUST have more input data (even 1 byte) - before it can make any more forward progress, or you need to clear the - TINFL_FLAG_HAS_MORE_INPUT */ - /* flag on the next call if you don't have any more source data. If the source - data was somehow corrupted it's also possible (but unlikely) for the - inflator to keep on demanding input to */ - /* proceed, so be sure to properly set the TINFL_FLAG_HAS_MORE_INPUT flag. */ - TINFL_STATUS_NEEDS_MORE_INPUT = 1, - - /* This flag indicates the inflator definitely has 1 or more bytes of - uncompressed data available, but it cannot write this data into the output - buffer. */ - /* Note if the source compressed data was corrupted it's possible for the - inflator to return a lot of uncompressed data to the caller. I've been - assuming you know how much uncompressed data to expect */ - /* (either exact or worst case) and will stop calling the inflator and fail - after receiving too much. In pure streaming scenarios where you have no - idea how many bytes to expect this may not be possible */ - /* so I may need to add some code to address this. */ - TINFL_STATUS_HAS_MORE_OUTPUT = 2 -} tinfl_status; - -/* Initializes the decompressor to its initial state. */ -#define tinfl_init(r) \ - do { \ - (r)->m_state = 0; \ - } \ - MZ_MACRO_END -#define tinfl_get_adler32(r) (r)->m_check_adler32 - -/* Main low-level decompressor coroutine function. This is the only function - * actually needed for decompression. All the other functions are just - * high-level helpers for improved usability. */ -/* This is a universal API, i.e. it can be used as a building block to build any - * desired higher level decompression API. In the limit case, it can be called - * once per every byte input or output. */ -MINIZ_EXPORT tinfl_status tinfl_decompress( - tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, - mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, - const mz_uint32 decomp_flags); - -/* Internal/private bits follow. */ -enum { - TINFL_MAX_HUFF_TABLES = 3, - TINFL_MAX_HUFF_SYMBOLS_0 = 288, - TINFL_MAX_HUFF_SYMBOLS_1 = 32, - TINFL_MAX_HUFF_SYMBOLS_2 = 19, - TINFL_FAST_LOOKUP_BITS = 10, - TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS -}; - -typedef struct { - mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0]; - mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], - m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2]; -} tinfl_huff_table; - -#if MINIZ_HAS_64BIT_REGISTERS -#define TINFL_USE_64BIT_BITBUF 1 -#else -#define TINFL_USE_64BIT_BITBUF 0 -#endif - -#if TINFL_USE_64BIT_BITBUF -typedef mz_uint64 tinfl_bit_buf_t; -#define TINFL_BITBUF_SIZE (64) -#else -typedef mz_uint32 tinfl_bit_buf_t; -#define TINFL_BITBUF_SIZE (32) -#endif - -struct tinfl_decompressor_tag { - mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, - m_check_adler32, m_dist, m_counter, m_num_extra, - m_table_sizes[TINFL_MAX_HUFF_TABLES]; - tinfl_bit_buf_t m_bit_buf; - size_t m_dist_from_out_buf_start; - tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES]; - mz_uint8 m_raw_header[4], - m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137]; -}; - -#ifdef __cplusplus -} -#endif - -#pragma once - -/* ------------------- ZIP archive reading/writing */ - -#ifndef MINIZ_NO_ARCHIVE_APIS - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - /* Note: These enums can be reduced as needed to save memory or stack space - - they are pretty conservative. */ - MZ_ZIP_MAX_IO_BUF_SIZE = 8 * 1024, - MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 512, - MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 512 -}; - -typedef struct { - /* Central directory file index. */ - mz_uint32 m_file_index; - - /* Byte offset of this entry in the archive's central directory. Note we - * currently only support up to UINT_MAX or less bytes in the central dir. */ - mz_uint64 m_central_dir_ofs; - - /* These fields are copied directly from the zip's central dir. */ - mz_uint16 m_version_made_by; - mz_uint16 m_version_needed; - mz_uint16 m_bit_flag; - mz_uint16 m_method; - -#ifndef MINIZ_NO_TIME - MZ_TIME_T m_time; -#endif - - /* CRC-32 of uncompressed data. */ - mz_uint32 m_crc32; - - /* File's compressed size. */ - mz_uint64 m_comp_size; - - /* File's uncompressed size. Note, I've seen some old archives where directory - * entries had 512 bytes for their uncompressed sizes, but when you try to - * unpack them you actually get 0 bytes. */ - mz_uint64 m_uncomp_size; - - /* Zip internal and external file attributes. */ - mz_uint16 m_internal_attr; - mz_uint32 m_external_attr; - - /* Entry's local header file offset in bytes. */ - mz_uint64 m_local_header_ofs; - - /* Size of comment in bytes. */ - mz_uint32 m_comment_size; - - /* MZ_TRUE if the entry appears to be a directory. */ - mz_bool m_is_directory; - - /* MZ_TRUE if the entry uses encryption/strong encryption (which miniz_zip - * doesn't support) */ - mz_bool m_is_encrypted; - - /* MZ_TRUE if the file is not encrypted, a patch file, and if it uses a - * compression method we support. */ - mz_bool m_is_supported; - - /* Filename. If string ends in '/' it's a subdirectory entry. */ - /* Guaranteed to be zero terminated, may be truncated to fit. */ - char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE]; - - /* Comment field. */ - /* Guaranteed to be zero terminated, may be truncated to fit. */ - char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE]; - -} mz_zip_archive_file_stat; - -typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, - void *pBuf, size_t n); -typedef size_t (*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, - const void *pBuf, size_t n); -typedef mz_bool (*mz_file_needs_keepalive)(void *pOpaque); - -struct mz_zip_internal_state_tag; -typedef struct mz_zip_internal_state_tag mz_zip_internal_state; - -typedef enum { - MZ_ZIP_MODE_INVALID = 0, - MZ_ZIP_MODE_READING = 1, - MZ_ZIP_MODE_WRITING = 2, - MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3 -} mz_zip_mode; - -typedef enum { - MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100, - MZ_ZIP_FLAG_IGNORE_PATH = 0x0200, - MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400, - MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800, - MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG = - 0x1000, /* if enabled, mz_zip_reader_locate_file() will be called on each - file as its validated to ensure the func finds the file in the - central dir (intended for testing) */ - MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY = - 0x2000, /* validate the local headers, but don't decompress the entire - file and check the crc32 */ - MZ_ZIP_FLAG_WRITE_ZIP64 = - 0x4000, /* always use the zip64 file format, instead of the original zip - file format with automatic switch to zip64. Use as flags - parameter with mz_zip_writer_init*_v2 */ - MZ_ZIP_FLAG_WRITE_ALLOW_READING = 0x8000, - MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000, - /*After adding a compressed file, seek back - to local file header and set the correct sizes*/ - MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE = 0x20000 -} mz_zip_flags; - -typedef enum { - MZ_ZIP_TYPE_INVALID = 0, - MZ_ZIP_TYPE_USER, - MZ_ZIP_TYPE_MEMORY, - MZ_ZIP_TYPE_HEAP, - MZ_ZIP_TYPE_FILE, - MZ_ZIP_TYPE_CFILE, - MZ_ZIP_TOTAL_TYPES -} mz_zip_type; - -/* miniz error codes. Be sure to update mz_zip_get_error_string() if you add or - * modify this enum. */ -typedef enum { - MZ_ZIP_NO_ERROR = 0, - MZ_ZIP_UNDEFINED_ERROR, - MZ_ZIP_TOO_MANY_FILES, - MZ_ZIP_FILE_TOO_LARGE, - MZ_ZIP_UNSUPPORTED_METHOD, - MZ_ZIP_UNSUPPORTED_ENCRYPTION, - MZ_ZIP_UNSUPPORTED_FEATURE, - MZ_ZIP_FAILED_FINDING_CENTRAL_DIR, - MZ_ZIP_NOT_AN_ARCHIVE, - MZ_ZIP_INVALID_HEADER_OR_CORRUPTED, - MZ_ZIP_UNSUPPORTED_MULTIDISK, - MZ_ZIP_DECOMPRESSION_FAILED, - MZ_ZIP_COMPRESSION_FAILED, - MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE, - MZ_ZIP_CRC_CHECK_FAILED, - MZ_ZIP_UNSUPPORTED_CDIR_SIZE, - MZ_ZIP_ALLOC_FAILED, - MZ_ZIP_FILE_OPEN_FAILED, - MZ_ZIP_FILE_CREATE_FAILED, - MZ_ZIP_FILE_WRITE_FAILED, - MZ_ZIP_FILE_READ_FAILED, - MZ_ZIP_FILE_CLOSE_FAILED, - MZ_ZIP_FILE_SEEK_FAILED, - MZ_ZIP_FILE_STAT_FAILED, - MZ_ZIP_INVALID_PARAMETER, - MZ_ZIP_INVALID_FILENAME, - MZ_ZIP_BUF_TOO_SMALL, - MZ_ZIP_INTERNAL_ERROR, - MZ_ZIP_FILE_NOT_FOUND, - MZ_ZIP_ARCHIVE_TOO_LARGE, - MZ_ZIP_VALIDATION_FAILED, - MZ_ZIP_WRITE_CALLBACK_FAILED, - MZ_ZIP_TOTAL_ERRORS -} mz_zip_error; - -typedef struct { - mz_uint64 m_archive_size; - mz_uint64 m_central_directory_file_ofs; - - /* We only support up to UINT32_MAX files in zip64 mode. */ - mz_uint32 m_total_files; - mz_zip_mode m_zip_mode; - mz_zip_type m_zip_type; - mz_zip_error m_last_error; - - mz_uint64 m_file_offset_alignment; - - mz_alloc_func m_pAlloc; - mz_free_func m_pFree; - mz_realloc_func m_pRealloc; - void *m_pAlloc_opaque; - - mz_file_read_func m_pRead; - mz_file_write_func m_pWrite; - mz_file_needs_keepalive m_pNeeds_keepalive; - void *m_pIO_opaque; - - mz_zip_internal_state *m_pState; - -} mz_zip_archive; - -typedef struct { - mz_zip_archive *pZip; - mz_uint flags; - - int status; -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - mz_uint file_crc32; -#endif - mz_uint64 read_buf_size, read_buf_ofs, read_buf_avail, comp_remaining, - out_buf_ofs, cur_file_ofs; - mz_zip_archive_file_stat file_stat; - void *pRead_buf; - void *pWrite_buf; - - size_t out_blk_remain; - - tinfl_decompressor inflator; - -} mz_zip_reader_extract_iter_state; - -/* -------- ZIP reading */ - -/* Inits a ZIP archive reader. */ -/* These functions read and validate the archive's central directory. */ -MINIZ_EXPORT mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, - mz_uint flags); - -MINIZ_EXPORT mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, - const void *pMem, size_t size, - mz_uint flags); - -#ifndef MINIZ_NO_STDIO -/* Read a archive from a disk file. */ -/* file_start_ofs is the file offset where the archive actually begins, or 0. */ -/* actual_archive_size is the true total size of the archive, which may be - * smaller than the file's actual size on disk. If zero the entire file is - * treated as the archive. */ -MINIZ_EXPORT mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, - const char *pFilename, - mz_uint32 flags); -MINIZ_EXPORT mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, - const char *pFilename, - mz_uint flags, - mz_uint64 file_start_ofs, - mz_uint64 archive_size); -MINIZ_EXPORT mz_bool mz_zip_reader_init_file_v2_rpb(mz_zip_archive *pZip, - const char *pFilename, - mz_uint flags, - mz_uint64 file_start_ofs, - mz_uint64 archive_size); - -/* Read an archive from an already opened FILE, beginning at the current file - * position. */ -/* The archive is assumed to be archive_size bytes long. If archive_size is 0, - * then the entire rest of the file is assumed to contain the archive. */ -/* The FILE will NOT be closed when mz_zip_reader_end() is called. */ -MINIZ_EXPORT mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, - MZ_FILE *pFile, - mz_uint64 archive_size, - mz_uint flags); -#endif - -/* Ends archive reading, freeing all allocations, and closing the input archive - * file if mz_zip_reader_init_file() was used. */ -MINIZ_EXPORT mz_bool mz_zip_reader_end(mz_zip_archive *pZip); - -/* -------- ZIP reading or writing */ - -/* Clears a mz_zip_archive struct to all zeros. */ -/* Important: This must be done before passing the struct to any mz_zip - * functions. */ -MINIZ_EXPORT void mz_zip_zero_struct(mz_zip_archive *pZip); - -MINIZ_EXPORT mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip); -MINIZ_EXPORT mz_zip_type mz_zip_get_type(mz_zip_archive *pZip); - -/* Returns the total number of files in the archive. */ -MINIZ_EXPORT mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip); - -MINIZ_EXPORT mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip); -MINIZ_EXPORT mz_uint64 -mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip); -MINIZ_EXPORT MZ_FILE *mz_zip_get_cfile(mz_zip_archive *pZip); - -/* Reads n bytes of raw archive data, starting at file offset file_ofs, to pBuf. - */ -MINIZ_EXPORT size_t mz_zip_read_archive_data(mz_zip_archive *pZip, - mz_uint64 file_ofs, void *pBuf, - size_t n); - -/* All mz_zip funcs set the m_last_error field in the mz_zip_archive struct. - * These functions retrieve/manipulate this field. */ -/* Note that the m_last_error functionality is not thread safe. */ -MINIZ_EXPORT mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, - mz_zip_error err_num); -MINIZ_EXPORT mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip); -MINIZ_EXPORT mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip); -MINIZ_EXPORT mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip); -MINIZ_EXPORT const char *mz_zip_get_error_string(mz_zip_error mz_err); - -/* MZ_TRUE if the archive file entry is a directory entry. */ -MINIZ_EXPORT mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, - mz_uint file_index); - -/* MZ_TRUE if the file is encrypted/strong encrypted. */ -MINIZ_EXPORT mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, - mz_uint file_index); - -/* MZ_TRUE if the compression method is supported, and the file is not - * encrypted, and the file is not a compressed patch file. */ -MINIZ_EXPORT mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, - mz_uint file_index); - -/* Retrieves the filename of an archive file entry. */ -/* Returns the number of bytes written to pFilename, or if filename_buf_size is - * 0 this function returns the number of bytes needed to fully store the - * filename. */ -MINIZ_EXPORT mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, - mz_uint file_index, - char *pFilename, - mz_uint filename_buf_size); - -/* Attempts to locates a file in the archive's central directory. */ -/* Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH */ -/* Returns -1 if the file cannot be found. */ -MINIZ_EXPORT int mz_zip_reader_locate_file(mz_zip_archive *pZip, - const char *pName, - const char *pComment, mz_uint flags); -MINIZ_EXPORT mz_bool mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, - const char *pName, - const char *pComment, - mz_uint flags, - mz_uint32 *file_index); - -/* Returns detailed information about an archive file entry. */ -MINIZ_EXPORT mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, - mz_uint file_index, - mz_zip_archive_file_stat *pStat); - -/* MZ_TRUE if the file is in zip64 format. */ -/* A file is considered zip64 if it contained a zip64 end of central directory - * marker, or if it contained any zip64 extended file information fields in the - * central directory. */ -MINIZ_EXPORT mz_bool mz_zip_is_zip64(mz_zip_archive *pZip); - -/* Returns the total central directory size in bytes. */ -/* The current max supported size is <= MZ_UINT32_MAX. */ -MINIZ_EXPORT size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip); - -/* Extracts a archive file to a memory buffer using no memory allocation. */ -/* There must be at least enough room on the stack to store the inflator's state - * (~34KB or so). */ -MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_mem_no_alloc( - mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, - mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size); -MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_mem_no_alloc( - mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, - mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size); - -/* Extracts a archive file to a memory buffer. */ -MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, - mz_uint file_index, - void *pBuf, size_t buf_size, - mz_uint flags); -MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, - const char *pFilename, - void *pBuf, - size_t buf_size, - mz_uint flags); - -/* Extracts a archive file to a dynamically allocated heap buffer. */ -/* The memory will be allocated via the mz_zip_archive's alloc/realloc - * functions. */ -/* Returns NULL and sets the last error on failure. */ -MINIZ_EXPORT void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, - mz_uint file_index, - size_t *pSize, mz_uint flags); -MINIZ_EXPORT void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, - const char *pFilename, - size_t *pSize, - mz_uint flags); - -/* Extracts a archive file using a callback function to output the file's data. - */ -MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_callback( - mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, - void *pOpaque, mz_uint flags); -MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_callback( - mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, - void *pOpaque, mz_uint flags); - -/* Extract a file iteratively */ -MINIZ_EXPORT mz_zip_reader_extract_iter_state * -mz_zip_reader_extract_iter_new(mz_zip_archive *pZip, mz_uint file_index, - mz_uint flags); -MINIZ_EXPORT mz_zip_reader_extract_iter_state * -mz_zip_reader_extract_file_iter_new(mz_zip_archive *pZip, const char *pFilename, - mz_uint flags); -MINIZ_EXPORT size_t mz_zip_reader_extract_iter_read( - mz_zip_reader_extract_iter_state *pState, void *pvBuf, size_t buf_size); -MINIZ_EXPORT mz_bool -mz_zip_reader_extract_iter_free(mz_zip_reader_extract_iter_state *pState); - -#ifndef MINIZ_NO_STDIO -/* Extracts a archive file to a disk file and sets its last accessed and - * modified times. */ -/* This function only extracts files, not archive directory records. */ -MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, - mz_uint file_index, - const char *pDst_filename, - mz_uint flags); -MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_file( - mz_zip_archive *pZip, const char *pArchive_filename, - const char *pDst_filename, mz_uint flags); - -/* Extracts a archive file starting at the current position in the destination - * FILE stream. */ -MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, - mz_uint file_index, - MZ_FILE *File, - mz_uint flags); -MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_cfile( - mz_zip_archive *pZip, const char *pArchive_filename, MZ_FILE *pFile, - mz_uint flags); -#endif - -#if 0 -/* TODO */ - typedef void *mz_zip_streaming_extract_state_ptr; - mz_zip_streaming_extract_state_ptr mz_zip_streaming_extract_begin(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags); - uint64_t mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); - uint64_t mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); - mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, uint64_t new_ofs); - size_t mz_zip_streaming_extract_read(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, void *pBuf, size_t buf_size); - mz_bool mz_zip_streaming_extract_end(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); -#endif - -/* This function compares the archive's local headers, the optional local zip64 - * extended information block, and the optional descriptor following the - * compressed data vs. the data in the central directory. */ -/* It also validates that each file can be successfully uncompressed unless the - * MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY is specified. */ -MINIZ_EXPORT mz_bool mz_zip_validate_file(mz_zip_archive *pZip, - mz_uint file_index, mz_uint flags); - -/* Validates an entire archive by calling mz_zip_validate_file() on each file. - */ -MINIZ_EXPORT mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, - mz_uint flags); - -/* Misc utils/helpers, valid for ZIP reading or writing */ -MINIZ_EXPORT mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, - mz_uint flags, - mz_zip_error *pErr); -MINIZ_EXPORT mz_bool mz_zip_validate_file_archive(const char *pFilename, - mz_uint flags, - mz_zip_error *pErr); - -/* Universal end function - calls either mz_zip_reader_end() or - * mz_zip_writer_end(). */ -MINIZ_EXPORT mz_bool mz_zip_end(mz_zip_archive *pZip); - -/* -------- ZIP writing */ - -#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS - -/* Inits a ZIP archive writer. */ -/*Set pZip->m_pWrite (and pZip->m_pIO_opaque) before calling mz_zip_writer_init - * or mz_zip_writer_init_v2*/ -/*The output is streamable, i.e. file_ofs in mz_file_write_func always increases - * only by n*/ -MINIZ_EXPORT mz_bool mz_zip_writer_init(mz_zip_archive *pZip, - mz_uint64 existing_size); -MINIZ_EXPORT mz_bool mz_zip_writer_init_v2(mz_zip_archive *pZip, - mz_uint64 existing_size, - mz_uint flags); - -MINIZ_EXPORT mz_bool mz_zip_writer_init_heap( - mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, - size_t initial_allocation_size); -MINIZ_EXPORT mz_bool mz_zip_writer_init_heap_v2( - mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, - size_t initial_allocation_size, mz_uint flags); - -#ifndef MINIZ_NO_STDIO -MINIZ_EXPORT mz_bool -mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, - mz_uint64 size_to_reserve_at_beginning); -MINIZ_EXPORT mz_bool mz_zip_writer_init_file_v2( - mz_zip_archive *pZip, const char *pFilename, - mz_uint64 size_to_reserve_at_beginning, mz_uint flags); -MINIZ_EXPORT mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, - MZ_FILE *pFile, mz_uint flags); -#endif - -/* Converts a ZIP archive reader object into a writer object, to allow efficient - * in-place file appends to occur on an existing archive. */ -/* For archives opened using mz_zip_reader_init_file, pFilename must be the - * archive's filename so it can be reopened for writing. If the file can't be - * reopened, mz_zip_reader_end() will be called. */ -/* For archives opened using mz_zip_reader_init_mem, the memory block must be - * growable using the realloc callback (which defaults to realloc unless you've - * overridden it). */ -/* Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's - * user provided m_pWrite function cannot be NULL. */ -/* Note: In-place archive modification is not recommended unless you know what - * you're doing, because if execution stops or something goes wrong before */ -/* the archive is finalized the file's central directory will be hosed. */ -MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, - const char *pFilename); -MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, - const char *pFilename, - mz_uint flags); -MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader_v2_noreopen( - mz_zip_archive *pZip, const char *pFilename, mz_uint flags); - -/* Adds the contents of a memory buffer to an archive. These functions record - * the current local time into the archive. */ -/* To add a directory entry, call this method with an archive name ending in a - * forwardslash with an empty buffer. */ -/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, - * MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or - * just set to MZ_DEFAULT_COMPRESSION. */ -MINIZ_EXPORT mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, - const char *pArchive_name, - const void *pBuf, size_t buf_size, - mz_uint level_and_flags); - -/* Like mz_zip_writer_add_mem(), except you can specify a file comment field, - * and optionally supply the function with already compressed data. */ -/* uncomp_size/uncomp_crc32 are only used if the MZ_ZIP_FLAG_COMPRESSED_DATA - * flag is specified. */ -MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex( - mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, - size_t buf_size, const void *pComment, mz_uint16 comment_size, - mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32); - -MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex_v2( - mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, - size_t buf_size, const void *pComment, mz_uint16 comment_size, - mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, - MZ_TIME_T *last_modified, const char *user_extra_data_local, - mz_uint user_extra_data_local_len, const char *user_extra_data_central, - mz_uint user_extra_data_central_len); - -/* Adds the contents of a file to an archive. This function also records the - * disk file's modified time into the archive. */ -/* File data is supplied via a read callback function. User - * mz_zip_writer_add_(c)file to add a file directly.*/ -MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback( - mz_zip_archive *pZip, const char *pArchive_name, - mz_file_read_func read_callback, void *callback_opaque, mz_uint64 max_size, - const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, - mz_uint level_and_flags, mz_uint32 ext_attributes, - const char *user_extra_data_local, mz_uint user_extra_data_local_len, - const char *user_extra_data_central, mz_uint user_extra_data_central_len); - -#ifndef MINIZ_NO_STDIO -/* Adds the contents of a disk file to an archive. This function also records - * the disk file's modified time into the archive. */ -/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, - * MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or - * just set to MZ_DEFAULT_COMPRESSION. */ -MINIZ_EXPORT mz_bool mz_zip_writer_add_file( - mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, - const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, - mz_uint32 ext_attributes); - -/* Like mz_zip_writer_add_file(), except the file data is read from the - * specified FILE stream. */ -MINIZ_EXPORT mz_bool mz_zip_writer_add_cfile( - mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, - mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, - mz_uint16 comment_size, mz_uint level_and_flags, mz_uint32 ext_attributes, - const char *user_extra_data_local, mz_uint user_extra_data_local_len, - const char *user_extra_data_central, mz_uint user_extra_data_central_len); -#endif - -/* Adds a file to an archive by fully cloning the data from another archive. */ -/* This function fully clones the source file's compressed data (no - * recompression), along with its full filename, extra data (it may add or - * modify the zip64 local header extra data field), and the optional descriptor - * following the compressed data. */ -MINIZ_EXPORT mz_bool mz_zip_writer_add_from_zip_reader( - mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint src_file_index); - -/* Finalizes the archive by writing the central directory records followed by - * the end of central directory record. */ -/* After an archive is finalized, the only valid call on the mz_zip_archive - * struct is mz_zip_writer_end(). */ -/* An archive must be manually finalized by calling this function for it to be - * valid. */ -MINIZ_EXPORT mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip); - -/* Finalizes a heap archive, returning a pointer to the heap block and its size. - */ -/* The heap block will be allocated using the mz_zip_archive's alloc/realloc - * callbacks. */ -MINIZ_EXPORT mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, - void **ppBuf, - size_t *pSize); - -/* Ends archive writing, freeing all allocations, and closing the output file if - * mz_zip_writer_init_file() was used. */ -/* Note for the archive to be valid, it *must* have been finalized before ending - * (this function will not do it for you). */ -MINIZ_EXPORT mz_bool mz_zip_writer_end(mz_zip_archive *pZip); - -/* -------- Misc. high-level helper functions: */ - -/* mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) - * appends a memory blob to a ZIP archive. */ -/* Note this is NOT a fully safe operation. If it crashes or dies in some way - * your archive can be left in a screwed up state (without a central directory). - */ -/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, - * MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or - * just set to MZ_DEFAULT_COMPRESSION. */ -/* TODO: Perhaps add an option to leave the existing central dir in place in - * case the add dies? We could then truncate the file (so the old central dir - * would be at the end) if something goes wrong. */ -MINIZ_EXPORT mz_bool mz_zip_add_mem_to_archive_file_in_place( - const char *pZip_filename, const char *pArchive_name, const void *pBuf, - size_t buf_size, const void *pComment, mz_uint16 comment_size, - mz_uint level_and_flags); -MINIZ_EXPORT mz_bool mz_zip_add_mem_to_archive_file_in_place_v2( - const char *pZip_filename, const char *pArchive_name, const void *pBuf, - size_t buf_size, const void *pComment, mz_uint16 comment_size, - mz_uint level_and_flags, mz_zip_error *pErr); - -/* Reads a single file from an archive into a heap block. */ -/* If pComment is not NULL, only the file with the specified comment will be - * extracted. */ -/* Returns NULL on failure. */ -MINIZ_EXPORT void * -mz_zip_extract_archive_file_to_heap(const char *pZip_filename, - const char *pArchive_name, size_t *pSize, - mz_uint flags); -MINIZ_EXPORT void *mz_zip_extract_archive_file_to_heap_v2( - const char *pZip_filename, const char *pArchive_name, const char *pComment, - size_t *pSize, mz_uint flags, mz_zip_error *pErr); - -#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */ - -#ifdef __cplusplus -} -#endif - -#endif /* MINIZ_NO_ARCHIVE_APIS */ -/************************************************************************** - * - * Copyright 2013-2014 RAD Game Tools and Valve Software - * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - **************************************************************************/ - -typedef unsigned char mz_validate_uint16[sizeof(mz_uint16) == 2 ? 1 : -1]; -typedef unsigned char mz_validate_uint32[sizeof(mz_uint32) == 4 ? 1 : -1]; -typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1]; - -#ifdef __cplusplus -extern "C" { -#endif - -/* ------------------- zlib-style API's */ - -mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len) { - mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16); - size_t block_len = buf_len % 5552; - if (!ptr) - return MZ_ADLER32_INIT; - while (buf_len) { - for (i = 0; i + 7 < block_len; i += 8, ptr += 8) { - s1 += ptr[0], s2 += s1; - s1 += ptr[1], s2 += s1; - s1 += ptr[2], s2 += s1; - s1 += ptr[3], s2 += s1; - s1 += ptr[4], s2 += s1; - s1 += ptr[5], s2 += s1; - s1 += ptr[6], s2 += s1; - s1 += ptr[7], s2 += s1; - } - for (; i < block_len; ++i) - s1 += *ptr++, s2 += s1; - s1 %= 65521U, s2 %= 65521U; - buf_len -= block_len; - block_len = 5552; - } - return (s2 << 16) + s1; -} - -/* Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C - * implementation that balances processor cache usage against speed": - * http://www.geocities.com/malbrain/ */ -#if 0 - mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len) - { - static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, - 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c }; - mz_uint32 crcu32 = (mz_uint32)crc; - if (!ptr) - return MZ_CRC32_INIT; - crcu32 = ~crcu32; - while (buf_len--) - { - mz_uint8 b = *ptr++; - crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)]; - crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)]; - } - return ~crcu32; - } -#elif defined(USE_EXTERNAL_MZCRC) -/* If USE_EXTERNAL_CRC is defined, an external module will export the - * mz_crc32() symbol for us to use, e.g. an SSE-accelerated version. - * Depending on the impl, it may be necessary to ~ the input/output crc values. - */ -mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len); -#else -/* Faster, but larger CPU cache footprint. - */ -mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len) { - static const mz_uint32 s_crc_table[256] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, - 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, - 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, - 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, - 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, - 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, - 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, - 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, - 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, - 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, - 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, - 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, - 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, - 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, - 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, - 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, - 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, - 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, - 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, - 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, - 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, - 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D}; - - mz_uint32 crc32 = (mz_uint32)crc ^ 0xFFFFFFFF; - const mz_uint8 *pByte_buf = (const mz_uint8 *)ptr; - - while (buf_len >= 4) { - crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF]; - crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[1]) & 0xFF]; - crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[2]) & 0xFF]; - crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[3]) & 0xFF]; - pByte_buf += 4; - buf_len -= 4; - } - - while (buf_len) { - crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF]; - ++pByte_buf; - --buf_len; - } - - return ~crc32; -} -#endif - -void mz_free(void *p) { MZ_FREE(p); } - -MINIZ_EXPORT void *miniz_def_alloc_func(void *opaque, size_t items, - size_t size) { - (void)opaque, (void)items, (void)size; - return MZ_MALLOC(items * size); -} -MINIZ_EXPORT void miniz_def_free_func(void *opaque, void *address) { - (void)opaque, (void)address; - MZ_FREE(address); -} -MINIZ_EXPORT void *miniz_def_realloc_func(void *opaque, void *address, - size_t items, size_t size) { - (void)opaque, (void)address, (void)items, (void)size; - return MZ_REALLOC(address, items * size); -} - -const char *mz_version(void) { return MZ_VERSION; } - -#ifndef MINIZ_NO_ZLIB_APIS - -int mz_deflateInit(mz_streamp pStream, int level) { - return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, - MZ_DEFAULT_STRATEGY); -} - -int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, - int mem_level, int strategy) { - tdefl_compressor *pComp; - mz_uint comp_flags = - TDEFL_COMPUTE_ADLER32 | - tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy); - - if (!pStream) - return MZ_STREAM_ERROR; - if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || - ((window_bits != MZ_DEFAULT_WINDOW_BITS) && - (-window_bits != MZ_DEFAULT_WINDOW_BITS))) - return MZ_PARAM_ERROR; - - pStream->data_type = 0; - pStream->adler = MZ_ADLER32_INIT; - pStream->msg = NULL; - pStream->reserved = 0; - pStream->total_in = 0; - pStream->total_out = 0; - if (!pStream->zalloc) - pStream->zalloc = miniz_def_alloc_func; - if (!pStream->zfree) - pStream->zfree = miniz_def_free_func; - - pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, - sizeof(tdefl_compressor)); - if (!pComp) - return MZ_MEM_ERROR; - - pStream->state = (struct mz_internal_state *)pComp; - - if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY) { - mz_deflateEnd(pStream); - return MZ_PARAM_ERROR; - } - - return MZ_OK; -} - -int mz_deflateReset(mz_streamp pStream) { - if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || - (!pStream->zfree)) - return MZ_STREAM_ERROR; - pStream->total_in = pStream->total_out = 0; - tdefl_init((tdefl_compressor *)pStream->state, NULL, NULL, - ((tdefl_compressor *)pStream->state)->m_flags); - return MZ_OK; -} - -int mz_deflate(mz_streamp pStream, int flush) { - size_t in_bytes, out_bytes; - mz_ulong orig_total_in, orig_total_out; - int mz_status = MZ_OK; - - if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || - (!pStream->next_out)) - return MZ_STREAM_ERROR; - if (!pStream->avail_out) - return MZ_BUF_ERROR; - - if (flush == MZ_PARTIAL_FLUSH) - flush = MZ_SYNC_FLUSH; - - if (((tdefl_compressor *)pStream->state)->m_prev_return_status == - TDEFL_STATUS_DONE) - return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR; - - orig_total_in = pStream->total_in; - orig_total_out = pStream->total_out; - for (;;) { - tdefl_status defl_status; - in_bytes = pStream->avail_in; - out_bytes = pStream->avail_out; - - defl_status = tdefl_compress((tdefl_compressor *)pStream->state, - pStream->next_in, &in_bytes, pStream->next_out, - &out_bytes, (tdefl_flush)flush); - pStream->next_in += (mz_uint)in_bytes; - pStream->avail_in -= (mz_uint)in_bytes; - pStream->total_in += (mz_uint)in_bytes; - pStream->adler = tdefl_get_adler32((tdefl_compressor *)pStream->state); - - pStream->next_out += (mz_uint)out_bytes; - pStream->avail_out -= (mz_uint)out_bytes; - pStream->total_out += (mz_uint)out_bytes; - - if (defl_status < 0) { - mz_status = MZ_STREAM_ERROR; - break; - } else if (defl_status == TDEFL_STATUS_DONE) { - mz_status = MZ_STREAM_END; - break; - } else if (!pStream->avail_out) - break; - else if ((!pStream->avail_in) && (flush != MZ_FINISH)) { - if ((flush) || (pStream->total_in != orig_total_in) || - (pStream->total_out != orig_total_out)) - break; - return MZ_BUF_ERROR; /* Can't make forward progress without some input. - */ - } - } - return mz_status; -} - -int mz_deflateEnd(mz_streamp pStream) { - if (!pStream) - return MZ_STREAM_ERROR; - if (pStream->state) { - pStream->zfree(pStream->opaque, pStream->state); - pStream->state = NULL; - } - return MZ_OK; -} - -mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len) { - (void)pStream; - /* This is really over conservative. (And lame, but it's actually pretty - * tricky to compute a true upper bound given the way tdefl's blocking works.) - */ - return MZ_MAX(128 + (source_len * 110) / 100, - 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5); -} - -int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, - const unsigned char *pSource, mz_ulong source_len, int level) { - int status; - mz_stream stream; - memset(&stream, 0, sizeof(stream)); - - /* In case mz_ulong is 64-bits (argh I hate longs). */ - if ((source_len | *pDest_len) > 0xFFFFFFFFU) - return MZ_PARAM_ERROR; - - stream.next_in = pSource; - stream.avail_in = (mz_uint32)source_len; - stream.next_out = pDest; - stream.avail_out = (mz_uint32)*pDest_len; - - status = mz_deflateInit(&stream, level); - if (status != MZ_OK) - return status; - - status = mz_deflate(&stream, MZ_FINISH); - if (status != MZ_STREAM_END) { - mz_deflateEnd(&stream); - return (status == MZ_OK) ? MZ_BUF_ERROR : status; - } - - *pDest_len = stream.total_out; - return mz_deflateEnd(&stream); -} - -int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, - const unsigned char *pSource, mz_ulong source_len) { - return mz_compress2(pDest, pDest_len, pSource, source_len, - MZ_DEFAULT_COMPRESSION); -} - -mz_ulong mz_compressBound(mz_ulong source_len) { - return mz_deflateBound(NULL, source_len); -} - -typedef struct { - tinfl_decompressor m_decomp; - mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; - int m_window_bits; - mz_uint8 m_dict[TINFL_LZ_DICT_SIZE]; - tinfl_status m_last_status; -} inflate_state; - -int mz_inflateInit2(mz_streamp pStream, int window_bits) { - inflate_state *pDecomp; - if (!pStream) - return MZ_STREAM_ERROR; - if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && - (-window_bits != MZ_DEFAULT_WINDOW_BITS)) - return MZ_PARAM_ERROR; - - pStream->data_type = 0; - pStream->adler = 0; - pStream->msg = NULL; - pStream->total_in = 0; - pStream->total_out = 0; - pStream->reserved = 0; - if (!pStream->zalloc) - pStream->zalloc = miniz_def_alloc_func; - if (!pStream->zfree) - pStream->zfree = miniz_def_free_func; - - pDecomp = (inflate_state *)pStream->zalloc(pStream->opaque, 1, - sizeof(inflate_state)); - if (!pDecomp) - return MZ_MEM_ERROR; - - pStream->state = (struct mz_internal_state *)pDecomp; - - tinfl_init(&pDecomp->m_decomp); - pDecomp->m_dict_ofs = 0; - pDecomp->m_dict_avail = 0; - pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT; - pDecomp->m_first_call = 1; - pDecomp->m_has_flushed = 0; - pDecomp->m_window_bits = window_bits; - - return MZ_OK; -} - -int mz_inflateInit(mz_streamp pStream) { - return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS); -} - -int mz_inflateReset(mz_streamp pStream) { - inflate_state *pDecomp; - if (!pStream) - return MZ_STREAM_ERROR; - - pStream->data_type = 0; - pStream->adler = 0; - pStream->msg = NULL; - pStream->total_in = 0; - pStream->total_out = 0; - pStream->reserved = 0; - - pDecomp = (inflate_state *)pStream->state; - - tinfl_init(&pDecomp->m_decomp); - pDecomp->m_dict_ofs = 0; - pDecomp->m_dict_avail = 0; - pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT; - pDecomp->m_first_call = 1; - pDecomp->m_has_flushed = 0; - /* pDecomp->m_window_bits = window_bits */; - - return MZ_OK; -} - -int mz_inflate(mz_streamp pStream, int flush) { - inflate_state *pState; - mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32; - size_t in_bytes, out_bytes, orig_avail_in; - tinfl_status status; - - if ((!pStream) || (!pStream->state)) - return MZ_STREAM_ERROR; - if (flush == MZ_PARTIAL_FLUSH) - flush = MZ_SYNC_FLUSH; - if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) - return MZ_STREAM_ERROR; - - pState = (inflate_state *)pStream->state; - if (pState->m_window_bits > 0) - decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER; - orig_avail_in = pStream->avail_in; - - first_call = pState->m_first_call; - pState->m_first_call = 0; - if (pState->m_last_status < 0) - return MZ_DATA_ERROR; - - if (pState->m_has_flushed && (flush != MZ_FINISH)) - return MZ_STREAM_ERROR; - pState->m_has_flushed |= (flush == MZ_FINISH); - - if ((flush == MZ_FINISH) && (first_call)) { - /* MZ_FINISH on the first call implies that the input and output buffers are - * large enough to hold the entire compressed/decompressed file. */ - decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF; - in_bytes = pStream->avail_in; - out_bytes = pStream->avail_out; - status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, - pStream->next_out, pStream->next_out, &out_bytes, - decomp_flags); - pState->m_last_status = status; - pStream->next_in += (mz_uint)in_bytes; - pStream->avail_in -= (mz_uint)in_bytes; - pStream->total_in += (mz_uint)in_bytes; - pStream->adler = tinfl_get_adler32(&pState->m_decomp); - pStream->next_out += (mz_uint)out_bytes; - pStream->avail_out -= (mz_uint)out_bytes; - pStream->total_out += (mz_uint)out_bytes; - - if (status < 0) - return MZ_DATA_ERROR; - else if (status != TINFL_STATUS_DONE) { - pState->m_last_status = TINFL_STATUS_FAILED; - return MZ_BUF_ERROR; - } - return MZ_STREAM_END; - } - /* flush != MZ_FINISH then we must assume there's more input. */ - if (flush != MZ_FINISH) - decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT; - - if (pState->m_dict_avail) { - n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); - memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); - pStream->next_out += n; - pStream->avail_out -= n; - pStream->total_out += n; - pState->m_dict_avail -= n; - pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); - return ((pState->m_last_status == TINFL_STATUS_DONE) && - (!pState->m_dict_avail)) - ? MZ_STREAM_END - : MZ_OK; - } - - for (;;) { - in_bytes = pStream->avail_in; - out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs; - - status = tinfl_decompress( - &pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, - pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags); - pState->m_last_status = status; - - pStream->next_in += (mz_uint)in_bytes; - pStream->avail_in -= (mz_uint)in_bytes; - pStream->total_in += (mz_uint)in_bytes; - pStream->adler = tinfl_get_adler32(&pState->m_decomp); - - pState->m_dict_avail = (mz_uint)out_bytes; - - n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); - memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); - pStream->next_out += n; - pStream->avail_out -= n; - pStream->total_out += n; - pState->m_dict_avail -= n; - pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); - - if (status < 0) - return MZ_DATA_ERROR; /* Stream is corrupted (there could be some - uncompressed data left in the output dictionary - - oh well). */ - else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in)) - return MZ_BUF_ERROR; /* Signal caller that we can't make forward progress - without supplying more input or by setting flush - to MZ_FINISH. */ - else if (flush == MZ_FINISH) { - /* The output buffer MUST be large to hold the remaining uncompressed data - * when flush==MZ_FINISH. */ - if (status == TINFL_STATUS_DONE) - return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END; - /* status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's - * at least 1 more byte on the way. If there's no more room left in the - * output buffer then something is wrong. */ - else if (!pStream->avail_out) - return MZ_BUF_ERROR; - } else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || - (!pStream->avail_out) || (pState->m_dict_avail)) - break; - } - - return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) - ? MZ_STREAM_END - : MZ_OK; -} - -int mz_inflateEnd(mz_streamp pStream) { - if (!pStream) - return MZ_STREAM_ERROR; - if (pStream->state) { - pStream->zfree(pStream->opaque, pStream->state); - pStream->state = NULL; - } - return MZ_OK; -} -int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, - const unsigned char *pSource, mz_ulong *pSource_len) { - mz_stream stream; - int status; - memset(&stream, 0, sizeof(stream)); - - /* In case mz_ulong is 64-bits (argh I hate longs). */ - if ((*pSource_len | *pDest_len) > 0xFFFFFFFFU) - return MZ_PARAM_ERROR; - - stream.next_in = pSource; - stream.avail_in = (mz_uint32)*pSource_len; - stream.next_out = pDest; - stream.avail_out = (mz_uint32)*pDest_len; - - status = mz_inflateInit(&stream); - if (status != MZ_OK) - return status; - - status = mz_inflate(&stream, MZ_FINISH); - *pSource_len = *pSource_len - stream.avail_in; - if (status != MZ_STREAM_END) { - mz_inflateEnd(&stream); - return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR - : status; - } - *pDest_len = stream.total_out; - - return mz_inflateEnd(&stream); -} - -int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, - const unsigned char *pSource, mz_ulong source_len) { - return mz_uncompress2(pDest, pDest_len, pSource, &source_len); -} - -const char *mz_error(int err) { - static struct { - int m_err; - const char *m_pDesc; - } s_error_descs[] = {{MZ_OK, ""}, - {MZ_STREAM_END, "stream end"}, - {MZ_NEED_DICT, "need dictionary"}, - {MZ_ERRNO, "file error"}, - {MZ_STREAM_ERROR, "stream error"}, - {MZ_DATA_ERROR, "data error"}, - {MZ_MEM_ERROR, "out of memory"}, - {MZ_BUF_ERROR, "buf error"}, - {MZ_VERSION_ERROR, "version error"}, - {MZ_PARAM_ERROR, "parameter error"}}; - mz_uint i; - for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i) - if (s_error_descs[i].m_err == err) - return s_error_descs[i].m_pDesc; - return NULL; -} - -#endif /*MINIZ_NO_ZLIB_APIS */ - -#ifdef __cplusplus -} -#endif - -/* - This is free and unencumbered software released into the public domain. - - Anyone is free to copy, modify, publish, use, compile, sell, or - distribute this software, either in source code form or as a compiled - binary, for any purpose, commercial or non-commercial, and by any - means. - - In jurisdictions that recognize copyright laws, the author or authors - of this software dedicate any and all copyright interest in the - software to the public domain. We make this dedication for the benefit - of the public at large and to the detriment of our heirs and - successors. We intend this dedication to be an overt act of - relinquishment in perpetuity of all present and future rights to this - software under copyright law. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - For more information, please refer to -*/ -/************************************************************************** - * - * Copyright 2013-2014 RAD Game Tools and Valve Software - * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - **************************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -/* ------------------- Low-level Compression (independent from all decompression - * API's) */ - -/* Purposely making these tables static for faster init and thread safety. */ -static const mz_uint16 s_tdefl_len_sym[256] = { - 257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268, - 268, 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272, - 272, 272, 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274, - 274, 274, 274, 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276, - 276, 276, 276, 276, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 279, 279, 279, 279, 279, 279, 279, 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, 281, 281, 281, 281, 281, 281, 281, - 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 284, - 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, - 285}; - -static const mz_uint8 s_tdefl_len_extra[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0}; - -static const mz_uint8 s_tdefl_small_dist_sym[512] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, - 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17}; - -static const mz_uint8 s_tdefl_small_dist_extra[512] = { - 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}; - -static const mz_uint8 s_tdefl_large_dist_sym[128] = { - 0, 0, 18, 19, 20, 20, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, - 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29}; - -static const mz_uint8 s_tdefl_large_dist_extra[128] = { - 0, 0, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}; - -/* Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted - * values. */ -typedef struct { - mz_uint16 m_key, m_sym_index; -} tdefl_sym_freq; -static tdefl_sym_freq *tdefl_radix_sort_syms(mz_uint num_syms, - tdefl_sym_freq *pSyms0, - tdefl_sym_freq *pSyms1) { - mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2]; - tdefl_sym_freq *pCur_syms = pSyms0, *pNew_syms = pSyms1; - MZ_CLEAR_OBJ(hist); - for (i = 0; i < num_syms; i++) { - mz_uint freq = pSyms0[i].m_key; - hist[freq & 0xFF]++; - hist[256 + ((freq >> 8) & 0xFF)]++; - } - while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) - total_passes--; - for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8) { - const mz_uint32 *pHist = &hist[pass << 8]; - mz_uint offsets[256], cur_ofs = 0; - for (i = 0; i < 256; i++) { - offsets[i] = cur_ofs; - cur_ofs += pHist[i]; - } - for (i = 0; i < num_syms; i++) - pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = - pCur_syms[i]; - { - tdefl_sym_freq *t = pCur_syms; - pCur_syms = pNew_syms; - pNew_syms = t; - } - } - return pCur_syms; -} - -/* tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, - * alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996. */ -static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n) { - int root, leaf, next, avbl, used, dpth; - if (n == 0) - return; - else if (n == 1) { - A[0].m_key = 1; - return; - } - A[0].m_key += A[1].m_key; - root = 0; - leaf = 2; - for (next = 1; next < n - 1; next++) { - if (leaf >= n || A[root].m_key < A[leaf].m_key) { - A[next].m_key = A[root].m_key; - A[root++].m_key = (mz_uint16)next; - } else - A[next].m_key = A[leaf++].m_key; - if (leaf >= n || (root < next && A[root].m_key < A[leaf].m_key)) { - A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key); - A[root++].m_key = (mz_uint16)next; - } else - A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key); - } - A[n - 2].m_key = 0; - for (next = n - 3; next >= 0; next--) - A[next].m_key = A[A[next].m_key].m_key + 1; - avbl = 1; - used = dpth = 0; - root = n - 2; - next = n - 1; - while (avbl > 0) { - while (root >= 0 && (int)A[root].m_key == dpth) { - used++; - root--; - } - while (avbl > used) { - A[next--].m_key = (mz_uint16)(dpth); - avbl--; - } - avbl = 2 * used; - dpth++; - used = 0; - } -} - -/* Limits canonical Huffman code table's max code size. */ -enum { TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 }; -static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, - int code_list_len, - int max_code_size) { - int i; - mz_uint32 total = 0; - if (code_list_len <= 1) - return; - for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++) - pNum_codes[max_code_size] += pNum_codes[i]; - for (i = max_code_size; i > 0; i--) - total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i)); - while (total != (1UL << max_code_size)) { - pNum_codes[max_code_size]--; - for (i = max_code_size - 1; i > 0; i--) - if (pNum_codes[i]) { - pNum_codes[i]--; - pNum_codes[i + 1] += 2; - break; - } - total--; - } -} - -static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, - int table_len, int code_size_limit, - int static_table) { - int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE]; - mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1]; - MZ_CLEAR_OBJ(num_codes); - if (static_table) { - for (i = 0; i < table_len; i++) - num_codes[d->m_huff_code_sizes[table_num][i]]++; - } else { - tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], - *pSyms; - int num_used_syms = 0; - const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0]; - for (i = 0; i < table_len; i++) - if (pSym_count[i]) { - syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i]; - syms0[num_used_syms++].m_sym_index = (mz_uint16)i; - } - - pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1); - tdefl_calculate_minimum_redundancy(pSyms, num_used_syms); - - for (i = 0; i < num_used_syms; i++) - num_codes[pSyms[i].m_key]++; - - tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, - code_size_limit); - - MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]); - MZ_CLEAR_OBJ(d->m_huff_codes[table_num]); - for (i = 1, j = num_used_syms; i <= code_size_limit; i++) - for (l = num_codes[i]; l > 0; l--) - d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i); - } - - next_code[1] = 0; - for (j = 0, i = 2; i <= code_size_limit; i++) - next_code[i] = j = ((j + num_codes[i - 1]) << 1); - - for (i = 0; i < table_len; i++) { - mz_uint rev_code = 0, code, code_size; - if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) - continue; - code = next_code[code_size]++; - for (l = code_size; l > 0; l--, code >>= 1) - rev_code = (rev_code << 1) | (code & 1); - d->m_huff_codes[table_num][i] = (mz_uint16)rev_code; - } -} - -#define TDEFL_PUT_BITS(b, l) \ - do { \ - mz_uint bits = b; \ - mz_uint len = l; \ - MZ_ASSERT(bits <= ((1U << len) - 1U)); \ - d->m_bit_buffer |= (bits << d->m_bits_in); \ - d->m_bits_in += len; \ - while (d->m_bits_in >= 8) { \ - if (d->m_pOutput_buf < d->m_pOutput_buf_end) \ - *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \ - d->m_bit_buffer >>= 8; \ - d->m_bits_in -= 8; \ - } \ - } \ - MZ_MACRO_END - -#define TDEFL_RLE_PREV_CODE_SIZE() \ - { \ - if (rle_repeat_count) { \ - if (rle_repeat_count < 3) { \ - d->m_huff_count[2][prev_code_size] = \ - (mz_uint16)(d->m_huff_count[2][prev_code_size] + \ - rle_repeat_count); \ - while (rle_repeat_count--) \ - packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \ - } else { \ - d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); \ - packed_code_sizes[num_packed_code_sizes++] = 16; \ - packed_code_sizes[num_packed_code_sizes++] = \ - (mz_uint8)(rle_repeat_count - 3); \ - } \ - rle_repeat_count = 0; \ - } \ - } - -#define TDEFL_RLE_ZERO_CODE_SIZE() \ - { \ - if (rle_z_count) { \ - if (rle_z_count < 3) { \ - d->m_huff_count[2][0] = \ - (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); \ - while (rle_z_count--) \ - packed_code_sizes[num_packed_code_sizes++] = 0; \ - } else if (rle_z_count <= 10) { \ - d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); \ - packed_code_sizes[num_packed_code_sizes++] = 17; \ - packed_code_sizes[num_packed_code_sizes++] = \ - (mz_uint8)(rle_z_count - 3); \ - } else { \ - d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); \ - packed_code_sizes[num_packed_code_sizes++] = 18; \ - packed_code_sizes[num_packed_code_sizes++] = \ - (mz_uint8)(rle_z_count - 11); \ - } \ - rle_z_count = 0; \ - } \ - } - -static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -static void tdefl_start_dynamic_block(tdefl_compressor *d) { - int num_lit_codes, num_dist_codes, num_bit_lengths; - mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, - rle_repeat_count, packed_code_sizes_index; - mz_uint8 - code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], - packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], - prev_code_size = 0xFF; - - d->m_huff_count[0][256] = 1; - - tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE); - tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE); - - for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--) - if (d->m_huff_code_sizes[0][num_lit_codes - 1]) - break; - for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--) - if (d->m_huff_code_sizes[1][num_dist_codes - 1]) - break; - - memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes); - memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], - num_dist_codes); - total_code_sizes_to_pack = num_lit_codes + num_dist_codes; - num_packed_code_sizes = 0; - rle_z_count = 0; - rle_repeat_count = 0; - - memset(&d->m_huff_count[2][0], 0, - sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2); - for (i = 0; i < total_code_sizes_to_pack; i++) { - mz_uint8 code_size = code_sizes_to_pack[i]; - if (!code_size) { - TDEFL_RLE_PREV_CODE_SIZE(); - if (++rle_z_count == 138) { - TDEFL_RLE_ZERO_CODE_SIZE(); - } - } else { - TDEFL_RLE_ZERO_CODE_SIZE(); - if (code_size != prev_code_size) { - TDEFL_RLE_PREV_CODE_SIZE(); - d->m_huff_count[2][code_size] = - (mz_uint16)(d->m_huff_count[2][code_size] + 1); - packed_code_sizes[num_packed_code_sizes++] = code_size; - } else if (++rle_repeat_count == 6) { - TDEFL_RLE_PREV_CODE_SIZE(); - } - } - prev_code_size = code_size; - } - if (rle_repeat_count) { - TDEFL_RLE_PREV_CODE_SIZE(); - } else { - TDEFL_RLE_ZERO_CODE_SIZE(); - } - - tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE); - - TDEFL_PUT_BITS(2, 2); - - TDEFL_PUT_BITS(num_lit_codes - 257, 5); - TDEFL_PUT_BITS(num_dist_codes - 1, 5); - - for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--) - if (d->m_huff_code_sizes - [2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]]) - break; - num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1)); - TDEFL_PUT_BITS(num_bit_lengths - 4, 4); - for (i = 0; (int)i < num_bit_lengths; i++) - TDEFL_PUT_BITS( - d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3); - - for (packed_code_sizes_index = 0; - packed_code_sizes_index < num_packed_code_sizes;) { - mz_uint code = packed_code_sizes[packed_code_sizes_index++]; - MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2); - TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]); - if (code >= 16) - TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], - "\02\03\07"[code - 16]); - } -} - -static void tdefl_start_static_block(tdefl_compressor *d) { - mz_uint i; - mz_uint8 *p = &d->m_huff_code_sizes[0][0]; - - for (i = 0; i <= 143; ++i) - *p++ = 8; - for (; i <= 255; ++i) - *p++ = 9; - for (; i <= 279; ++i) - *p++ = 7; - for (; i <= 287; ++i) - *p++ = 8; - - memset(d->m_huff_code_sizes[1], 5, 32); - - tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE); - tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE); - - TDEFL_PUT_BITS(1, 2); -} - -static const mz_uint mz_bitmasks[17] = { - 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, - 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF}; - -#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && \ - MINIZ_HAS_64BIT_REGISTERS -static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) { - mz_uint flags; - mz_uint8 *pLZ_codes; - mz_uint8 *pOutput_buf = d->m_pOutput_buf; - mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf; - mz_uint64 bit_buffer = d->m_bit_buffer; - mz_uint bits_in = d->m_bits_in; - -#define TDEFL_PUT_BITS_FAST(b, l) \ - { \ - bit_buffer |= (((mz_uint64)(b)) << bits_in); \ - bits_in += (l); \ - } - - flags = 1; - for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; - flags >>= 1) { - if (flags == 1) - flags = *pLZ_codes++ | 0x100; - - if (flags & 1) { - mz_uint s0, s1, n0, n1, sym, num_extra_bits; - mz_uint match_len = pLZ_codes[0], - match_dist = *(const mz_uint16 *)(pLZ_codes + 1); - pLZ_codes += 3; - - MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); - TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], - d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); - TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], - s_tdefl_len_extra[match_len]); - - /* This sequence coaxes MSVC into using cmov's vs. jmp's. */ - s0 = s_tdefl_small_dist_sym[match_dist & 511]; - n0 = s_tdefl_small_dist_extra[match_dist & 511]; - s1 = s_tdefl_large_dist_sym[match_dist >> 8]; - n1 = s_tdefl_large_dist_extra[match_dist >> 8]; - sym = (match_dist < 512) ? s0 : s1; - num_extra_bits = (match_dist < 512) ? n0 : n1; - - MZ_ASSERT(d->m_huff_code_sizes[1][sym]); - TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], - d->m_huff_code_sizes[1][sym]); - TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], - num_extra_bits); - } else { - mz_uint lit = *pLZ_codes++; - MZ_ASSERT(d->m_huff_code_sizes[0][lit]); - TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], - d->m_huff_code_sizes[0][lit]); - - if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) { - flags >>= 1; - lit = *pLZ_codes++; - MZ_ASSERT(d->m_huff_code_sizes[0][lit]); - TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], - d->m_huff_code_sizes[0][lit]); - - if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) { - flags >>= 1; - lit = *pLZ_codes++; - MZ_ASSERT(d->m_huff_code_sizes[0][lit]); - TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], - d->m_huff_code_sizes[0][lit]); - } - } - } - - if (pOutput_buf >= d->m_pOutput_buf_end) - return MZ_FALSE; - - *(mz_uint64 *)pOutput_buf = bit_buffer; - pOutput_buf += (bits_in >> 3); - bit_buffer >>= (bits_in & ~7); - bits_in &= 7; - } - -#undef TDEFL_PUT_BITS_FAST - - d->m_pOutput_buf = pOutput_buf; - d->m_bits_in = 0; - d->m_bit_buffer = 0; - - while (bits_in) { - mz_uint32 n = MZ_MIN(bits_in, 16); - TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n); - bit_buffer >>= n; - bits_in -= n; - } - - TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); - - return (d->m_pOutput_buf < d->m_pOutput_buf_end); -} -#else -static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) { - mz_uint flags; - mz_uint8 *pLZ_codes; - - flags = 1; - for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; - flags >>= 1) { - if (flags == 1) - flags = *pLZ_codes++ | 0x100; - if (flags & 1) { - mz_uint sym, num_extra_bits; - mz_uint match_len = pLZ_codes[0], - match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); - pLZ_codes += 3; - - MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); - TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], - d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); - TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], - s_tdefl_len_extra[match_len]); - - if (match_dist < 512) { - sym = s_tdefl_small_dist_sym[match_dist]; - num_extra_bits = s_tdefl_small_dist_extra[match_dist]; - } else { - sym = s_tdefl_large_dist_sym[match_dist >> 8]; - num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8]; - } - MZ_ASSERT(d->m_huff_code_sizes[1][sym]); - TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); - TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); - } else { - mz_uint lit = *pLZ_codes++; - MZ_ASSERT(d->m_huff_code_sizes[0][lit]); - TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); - } - } - - TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); - - return (d->m_pOutput_buf < d->m_pOutput_buf_end); -} -#endif /* MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && \ - MINIZ_HAS_64BIT_REGISTERS */ - -static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block) { - if (static_block) - tdefl_start_static_block(d); - else - tdefl_start_dynamic_block(d); - return tdefl_compress_lz_codes(d); -} - -static int tdefl_flush_block(tdefl_compressor *d, int flush) { - mz_uint saved_bit_buf, saved_bits_in; - mz_uint8 *pSaved_output_buf; - mz_bool comp_block_succeeded = MZ_FALSE; - int n, use_raw_block = - ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && - (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size; - mz_uint8 *pOutput_buf_start = - ((d->m_pPut_buf_func == NULL) && - ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) - ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs) - : d->m_output_buf; - - d->m_pOutput_buf = pOutput_buf_start; - d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16; - - MZ_ASSERT(!d->m_output_flush_remaining); - d->m_output_flush_ofs = 0; - d->m_output_flush_remaining = 0; - - *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left); - d->m_pLZ_code_buf -= (d->m_num_flags_left == 8); - - if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index)) { - TDEFL_PUT_BITS(0x78, 8); - TDEFL_PUT_BITS(0x01, 8); - } - - TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1); - - pSaved_output_buf = d->m_pOutput_buf; - saved_bit_buf = d->m_bit_buffer; - saved_bits_in = d->m_bits_in; - - if (!use_raw_block) - comp_block_succeeded = - tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || - (d->m_total_lz_bytes < 48)); - - /* If the block gets expanded, forget the current contents of the output - * buffer and send a raw block instead. */ - if (((use_raw_block) || - ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= - d->m_total_lz_bytes))) && - ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size)) { - mz_uint i; - d->m_pOutput_buf = pSaved_output_buf; - d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; - TDEFL_PUT_BITS(0, 2); - if (d->m_bits_in) { - TDEFL_PUT_BITS(0, 8 - d->m_bits_in); - } - for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF) { - TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16); - } - for (i = 0; i < d->m_total_lz_bytes; ++i) { - TDEFL_PUT_BITS( - d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], - 8); - } - } - /* Check for the extremely unlikely (if not impossible) case of the compressed - block not fitting into the output buffer when using dynamic codes. */ - else if (!comp_block_succeeded) { - d->m_pOutput_buf = pSaved_output_buf; - d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; - tdefl_compress_block(d, MZ_TRUE); - } - - if (flush) { - if (flush == TDEFL_FINISH) { - if (d->m_bits_in) { - TDEFL_PUT_BITS(0, 8 - d->m_bits_in); - } - if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER) { - mz_uint i, a = d->m_adler32; - for (i = 0; i < 4; i++) { - TDEFL_PUT_BITS((a >> 24) & 0xFF, 8); - a <<= 8; - } - } - } else { - mz_uint i, z = 0; - TDEFL_PUT_BITS(0, 3); - if (d->m_bits_in) { - TDEFL_PUT_BITS(0, 8 - d->m_bits_in); - } - for (i = 2; i; --i, z ^= 0xFFFF) { - TDEFL_PUT_BITS(z & 0xFFFF, 16); - } - } - } - - MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end); - - memset(&d->m_huff_count[0][0], 0, - sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); - memset(&d->m_huff_count[1][0], 0, - sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); - - d->m_pLZ_code_buf = d->m_lz_code_buf + 1; - d->m_pLZ_flags = d->m_lz_code_buf; - d->m_num_flags_left = 8; - d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes; - d->m_total_lz_bytes = 0; - d->m_block_index++; - - if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0) { - if (d->m_pPut_buf_func) { - *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; - if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user)) - return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED); - } else if (pOutput_buf_start == d->m_output_buf) { - int bytes_to_copy = (int)MZ_MIN( - (size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs)); - memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, - bytes_to_copy); - d->m_out_buf_ofs += bytes_to_copy; - if ((n -= bytes_to_copy) != 0) { - d->m_output_flush_ofs = bytes_to_copy; - d->m_output_flush_remaining = n; - } - } else { - d->m_out_buf_ofs += n; - } - } - - return d->m_output_flush_remaining; -} - -#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES -#ifdef MINIZ_UNALIGNED_USE_MEMCPY -static mz_uint16 TDEFL_READ_UNALIGNED_WORD(const mz_uint8 *p) { - mz_uint16 ret; - memcpy(&ret, p, sizeof(mz_uint16)); - return ret; -} -static mz_uint16 TDEFL_READ_UNALIGNED_WORD2(const mz_uint16 *p) { - mz_uint16 ret; - memcpy(&ret, p, sizeof(mz_uint16)); - return ret; -} -#else -#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16 *)(p) -#define TDEFL_READ_UNALIGNED_WORD2(p) *(const mz_uint16 *)(p) -#endif -static MZ_FORCEINLINE void -tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, - mz_uint max_match_len, mz_uint *pMatch_dist, - mz_uint *pMatch_len) { - mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, - match_len = *pMatch_len, probe_pos = pos, next_probe_pos, - probe_len; - mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; - const mz_uint16 *s = (const mz_uint16 *)(d->m_dict + pos), *p, *q; - mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), - s01 = TDEFL_READ_UNALIGNED_WORD2(s); - MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); - if (max_match_len <= match_len) - return; - for (;;) { - for (;;) { - if (--num_probes_left == 0) - return; -#define TDEFL_PROBE \ - next_probe_pos = d->m_next[probe_pos]; \ - if ((!next_probe_pos) || \ - ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \ - return; \ - probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ - if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) \ - break; - TDEFL_PROBE; - TDEFL_PROBE; - TDEFL_PROBE; - } - if (!dist) - break; - q = (const mz_uint16 *)(d->m_dict + probe_pos); - if (TDEFL_READ_UNALIGNED_WORD2(q) != s01) - continue; - p = s; - probe_len = 32; - do { - } while ( - (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && - (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && - (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && - (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && - (--probe_len > 0)); - if (!probe_len) { - *pMatch_dist = dist; - *pMatch_len = MZ_MIN(max_match_len, (mz_uint)TDEFL_MAX_MATCH_LEN); - break; - } else if ((probe_len = ((mz_uint)(p - s) * 2) + - (mz_uint)(*(const mz_uint8 *)p == - *(const mz_uint8 *)q)) > match_len) { - *pMatch_dist = dist; - if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == - max_match_len) - break; - c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]); - } - } -} -#else -static MZ_FORCEINLINE void -tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, - mz_uint max_match_len, mz_uint *pMatch_dist, - mz_uint *pMatch_len) { - mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, - match_len = *pMatch_len, probe_pos = pos, next_probe_pos, - probe_len; - mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; - const mz_uint8 *s = d->m_dict + pos, *p, *q; - mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1]; - MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); - if (max_match_len <= match_len) - return; - for (;;) { - for (;;) { - if (--num_probes_left == 0) - return; -#define TDEFL_PROBE \ - next_probe_pos = d->m_next[probe_pos]; \ - if ((!next_probe_pos) || \ - ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \ - return; \ - probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ - if ((d->m_dict[probe_pos + match_len] == c0) && \ - (d->m_dict[probe_pos + match_len - 1] == c1)) \ - break; - TDEFL_PROBE; - TDEFL_PROBE; - TDEFL_PROBE; - } - if (!dist) - break; - p = s; - q = d->m_dict + probe_pos; - for (probe_len = 0; probe_len < max_match_len; probe_len++) - if (*p++ != *q++) - break; - if (probe_len > match_len) { - *pMatch_dist = dist; - if ((*pMatch_len = match_len = probe_len) == max_match_len) - return; - c0 = d->m_dict[pos + match_len]; - c1 = d->m_dict[pos + match_len - 1]; - } - } -} -#endif /* #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES */ - -#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN -#ifdef MINIZ_UNALIGNED_USE_MEMCPY -static mz_uint32 TDEFL_READ_UNALIGNED_WORD32(const mz_uint8 *p) { - mz_uint32 ret; - memcpy(&ret, p, sizeof(mz_uint32)); - return ret; -} -#else -#define TDEFL_READ_UNALIGNED_WORD32(p) *(const mz_uint32 *)(p) -#endif -static mz_bool tdefl_compress_fast(tdefl_compressor *d) { - /* Faster, minimally featured LZRW1-style match+parse loop with better - * register utilization. Intended for applications where raw throughput is - * valued more highly than ratio. */ - mz_uint lookahead_pos = d->m_lookahead_pos, - lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size, - total_lz_bytes = d->m_total_lz_bytes, - num_flags_left = d->m_num_flags_left; - mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags; - mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; - - while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size))) { - const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096; - mz_uint dst_pos = - (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; - mz_uint num_bytes_to_process = (mz_uint)MZ_MIN( - d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size); - d->m_src_buf_left -= num_bytes_to_process; - lookahead_size += num_bytes_to_process; - - while (num_bytes_to_process) { - mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process); - memcpy(d->m_dict + dst_pos, d->m_pSrc, n); - if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) - memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, - MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos)); - d->m_pSrc += n; - dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK; - num_bytes_to_process -= n; - } - - dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size); - if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE)) - break; - - while (lookahead_size >= 4) { - mz_uint cur_match_dist, cur_match_len = 1; - mz_uint8 *pCur_dict = d->m_dict + cur_pos; - mz_uint first_trigram = TDEFL_READ_UNALIGNED_WORD32(pCur_dict) & 0xFFFFFF; - mz_uint hash = - (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & - TDEFL_LEVEL1_HASH_SIZE_MASK; - mz_uint probe_pos = d->m_hash[hash]; - d->m_hash[hash] = (mz_uint16)lookahead_pos; - - if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= - dict_size) && - ((TDEFL_READ_UNALIGNED_WORD32( - d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & - 0xFFFFFF) == first_trigram)) { - const mz_uint16 *p = (const mz_uint16 *)pCur_dict; - const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos); - mz_uint32 probe_len = 32; - do { - } while ((TDEFL_READ_UNALIGNED_WORD2(++p) == - TDEFL_READ_UNALIGNED_WORD2(++q)) && - (TDEFL_READ_UNALIGNED_WORD2(++p) == - TDEFL_READ_UNALIGNED_WORD2(++q)) && - (TDEFL_READ_UNALIGNED_WORD2(++p) == - TDEFL_READ_UNALIGNED_WORD2(++q)) && - (TDEFL_READ_UNALIGNED_WORD2(++p) == - TDEFL_READ_UNALIGNED_WORD2(++q)) && - (--probe_len > 0)); - cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + - (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q); - if (!probe_len) - cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0; - - if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || - ((cur_match_len == TDEFL_MIN_MATCH_LEN) && - (cur_match_dist >= 8U * 1024U))) { - cur_match_len = 1; - *pLZ_code_buf++ = (mz_uint8)first_trigram; - *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); - d->m_huff_count[0][(mz_uint8)first_trigram]++; - } else { - mz_uint32 s0, s1; - cur_match_len = MZ_MIN(cur_match_len, lookahead_size); - - MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && - (cur_match_dist >= 1) && - (cur_match_dist <= TDEFL_LZ_DICT_SIZE)); - - cur_match_dist--; - - pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN); -#ifdef MINIZ_UNALIGNED_USE_MEMCPY - memcpy(&pLZ_code_buf[1], &cur_match_dist, sizeof(cur_match_dist)); -#else - *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist; -#endif - pLZ_code_buf += 3; - *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80); - - s0 = s_tdefl_small_dist_sym[cur_match_dist & 511]; - s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8]; - d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++; - - d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - - TDEFL_MIN_MATCH_LEN]]++; - } - } else { - *pLZ_code_buf++ = (mz_uint8)first_trigram; - *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); - d->m_huff_count[0][(mz_uint8)first_trigram]++; - } - - if (--num_flags_left == 0) { - num_flags_left = 8; - pLZ_flags = pLZ_code_buf++; - } - - total_lz_bytes += cur_match_len; - lookahead_pos += cur_match_len; - dict_size = - MZ_MIN(dict_size + cur_match_len, (mz_uint)TDEFL_LZ_DICT_SIZE); - cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK; - MZ_ASSERT(lookahead_size >= cur_match_len); - lookahead_size -= cur_match_len; - - if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) { - int n; - d->m_lookahead_pos = lookahead_pos; - d->m_lookahead_size = lookahead_size; - d->m_dict_size = dict_size; - d->m_total_lz_bytes = total_lz_bytes; - d->m_pLZ_code_buf = pLZ_code_buf; - d->m_pLZ_flags = pLZ_flags; - d->m_num_flags_left = num_flags_left; - if ((n = tdefl_flush_block(d, 0)) != 0) - return (n < 0) ? MZ_FALSE : MZ_TRUE; - total_lz_bytes = d->m_total_lz_bytes; - pLZ_code_buf = d->m_pLZ_code_buf; - pLZ_flags = d->m_pLZ_flags; - num_flags_left = d->m_num_flags_left; - } - } - - while (lookahead_size) { - mz_uint8 lit = d->m_dict[cur_pos]; - - total_lz_bytes++; - *pLZ_code_buf++ = lit; - *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); - if (--num_flags_left == 0) { - num_flags_left = 8; - pLZ_flags = pLZ_code_buf++; - } - - d->m_huff_count[0][lit]++; - - lookahead_pos++; - dict_size = MZ_MIN(dict_size + 1, (mz_uint)TDEFL_LZ_DICT_SIZE); - cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; - lookahead_size--; - - if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) { - int n; - d->m_lookahead_pos = lookahead_pos; - d->m_lookahead_size = lookahead_size; - d->m_dict_size = dict_size; - d->m_total_lz_bytes = total_lz_bytes; - d->m_pLZ_code_buf = pLZ_code_buf; - d->m_pLZ_flags = pLZ_flags; - d->m_num_flags_left = num_flags_left; - if ((n = tdefl_flush_block(d, 0)) != 0) - return (n < 0) ? MZ_FALSE : MZ_TRUE; - total_lz_bytes = d->m_total_lz_bytes; - pLZ_code_buf = d->m_pLZ_code_buf; - pLZ_flags = d->m_pLZ_flags; - num_flags_left = d->m_num_flags_left; - } - } - } - - d->m_lookahead_pos = lookahead_pos; - d->m_lookahead_size = lookahead_size; - d->m_dict_size = dict_size; - d->m_total_lz_bytes = total_lz_bytes; - d->m_pLZ_code_buf = pLZ_code_buf; - d->m_pLZ_flags = pLZ_flags; - d->m_num_flags_left = num_flags_left; - return MZ_TRUE; -} -#endif /* MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN */ - -static MZ_FORCEINLINE void tdefl_record_literal(tdefl_compressor *d, - mz_uint8 lit) { - d->m_total_lz_bytes++; - *d->m_pLZ_code_buf++ = lit; - *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1); - if (--d->m_num_flags_left == 0) { - d->m_num_flags_left = 8; - d->m_pLZ_flags = d->m_pLZ_code_buf++; - } - d->m_huff_count[0][lit]++; -} - -static MZ_FORCEINLINE void -tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist) { - mz_uint32 s0, s1; - - MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && - (match_dist <= TDEFL_LZ_DICT_SIZE)); - - d->m_total_lz_bytes += match_len; - - d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN); - - match_dist -= 1; - d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF); - d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8); - d->m_pLZ_code_buf += 3; - - *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80); - if (--d->m_num_flags_left == 0) { - d->m_num_flags_left = 8; - d->m_pLZ_flags = d->m_pLZ_code_buf++; - } - - s0 = s_tdefl_small_dist_sym[match_dist & 511]; - s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127]; - d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++; - d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++; -} - -static mz_bool tdefl_compress_normal(tdefl_compressor *d) { - const mz_uint8 *pSrc = d->m_pSrc; - size_t src_buf_left = d->m_src_buf_left; - tdefl_flush flush = d->m_flush; - - while ((src_buf_left) || ((flush) && (d->m_lookahead_size))) { - mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos; - /* Update dictionary and hash chains. Keeps the lookahead size equal to - * TDEFL_MAX_MATCH_LEN. */ - if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1)) { - mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & - TDEFL_LZ_DICT_SIZE_MASK, - ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2; - mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] - << TDEFL_LZ_HASH_SHIFT) ^ - d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK]; - mz_uint num_bytes_to_process = (mz_uint)MZ_MIN( - src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size); - const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process; - src_buf_left -= num_bytes_to_process; - d->m_lookahead_size += num_bytes_to_process; - while (pSrc != pSrc_end) { - mz_uint8 c = *pSrc++; - d->m_dict[dst_pos] = c; - if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) - d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; - hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); - d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; - d->m_hash[hash] = (mz_uint16)(ins_pos); - dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; - ins_pos++; - } - } else { - while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) { - mz_uint8 c = *pSrc++; - mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & - TDEFL_LZ_DICT_SIZE_MASK; - src_buf_left--; - d->m_dict[dst_pos] = c; - if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) - d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; - if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN) { - mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2; - mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] - << (TDEFL_LZ_HASH_SHIFT * 2)) ^ - (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] - << TDEFL_LZ_HASH_SHIFT) ^ - c) & - (TDEFL_LZ_HASH_SIZE - 1); - d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; - d->m_hash[hash] = (mz_uint16)(ins_pos); - } - } - } - d->m_dict_size = - MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size); - if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) - break; - - /* Simple lazy/greedy parsing state machine. */ - len_to_move = 1; - cur_match_dist = 0; - cur_match_len = - d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1); - cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; - if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS)) { - if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) { - mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK]; - cur_match_len = 0; - while (cur_match_len < d->m_lookahead_size) { - if (d->m_dict[cur_pos + cur_match_len] != c) - break; - cur_match_len++; - } - if (cur_match_len < TDEFL_MIN_MATCH_LEN) - cur_match_len = 0; - else - cur_match_dist = 1; - } - } else { - tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, - d->m_lookahead_size, &cur_match_dist, &cur_match_len); - } - if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && - (cur_match_dist >= 8U * 1024U)) || - (cur_pos == cur_match_dist) || - ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5))) { - cur_match_dist = cur_match_len = 0; - } - if (d->m_saved_match_len) { - if (cur_match_len > d->m_saved_match_len) { - tdefl_record_literal(d, (mz_uint8)d->m_saved_lit); - if (cur_match_len >= 128) { - tdefl_record_match(d, cur_match_len, cur_match_dist); - d->m_saved_match_len = 0; - len_to_move = cur_match_len; - } else { - d->m_saved_lit = d->m_dict[cur_pos]; - d->m_saved_match_dist = cur_match_dist; - d->m_saved_match_len = cur_match_len; - } - } else { - tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist); - len_to_move = d->m_saved_match_len - 1; - d->m_saved_match_len = 0; - } - } else if (!cur_match_dist) - tdefl_record_literal(d, - d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]); - else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || - (cur_match_len >= 128)) { - tdefl_record_match(d, cur_match_len, cur_match_dist); - len_to_move = cur_match_len; - } else { - d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]; - d->m_saved_match_dist = cur_match_dist; - d->m_saved_match_len = cur_match_len; - } - /* Move the lookahead forward by len_to_move bytes. */ - d->m_lookahead_pos += len_to_move; - MZ_ASSERT(d->m_lookahead_size >= len_to_move); - d->m_lookahead_size -= len_to_move; - d->m_dict_size = - MZ_MIN(d->m_dict_size + len_to_move, (mz_uint)TDEFL_LZ_DICT_SIZE); - /* Check if it's time to flush the current LZ codes to the internal output - * buffer. */ - if ((d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) || - ((d->m_total_lz_bytes > 31 * 1024) && - (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= - d->m_total_lz_bytes) || - (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))) { - int n; - d->m_pSrc = pSrc; - d->m_src_buf_left = src_buf_left; - if ((n = tdefl_flush_block(d, 0)) != 0) - return (n < 0) ? MZ_FALSE : MZ_TRUE; - } - } - - d->m_pSrc = pSrc; - d->m_src_buf_left = src_buf_left; - return MZ_TRUE; -} - -static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d) { - if (d->m_pIn_buf_size) { - *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; - } - - if (d->m_pOut_buf_size) { - size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, - d->m_output_flush_remaining); - memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, - d->m_output_buf + d->m_output_flush_ofs, n); - d->m_output_flush_ofs += (mz_uint)n; - d->m_output_flush_remaining -= (mz_uint)n; - d->m_out_buf_ofs += n; - - *d->m_pOut_buf_size = d->m_out_buf_ofs; - } - - return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE - : TDEFL_STATUS_OKAY; -} - -tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, - size_t *pIn_buf_size, void *pOut_buf, - size_t *pOut_buf_size, tdefl_flush flush) { - if (!d) { - if (pIn_buf_size) - *pIn_buf_size = 0; - if (pOut_buf_size) - *pOut_buf_size = 0; - return TDEFL_STATUS_BAD_PARAM; - } - - d->m_pIn_buf = pIn_buf; - d->m_pIn_buf_size = pIn_buf_size; - d->m_pOut_buf = pOut_buf; - d->m_pOut_buf_size = pOut_buf_size; - d->m_pSrc = (const mz_uint8 *)(pIn_buf); - d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0; - d->m_out_buf_ofs = 0; - d->m_flush = flush; - - if (((d->m_pPut_buf_func != NULL) == - ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || - (d->m_prev_return_status != TDEFL_STATUS_OKAY) || - (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || - (pIn_buf_size && *pIn_buf_size && !pIn_buf) || - (pOut_buf_size && *pOut_buf_size && !pOut_buf)) { - if (pIn_buf_size) - *pIn_buf_size = 0; - if (pOut_buf_size) - *pOut_buf_size = 0; - return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM); - } - d->m_wants_to_finish |= (flush == TDEFL_FINISH); - - if ((d->m_output_flush_remaining) || (d->m_finished)) - return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); - -#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN - if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) && - ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) && - ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS | - TDEFL_RLE_MATCHES)) == 0)) { - if (!tdefl_compress_fast(d)) - return d->m_prev_return_status; - } else -#endif /* #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN */ - { - if (!tdefl_compress_normal(d)) - return d->m_prev_return_status; - } - - if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && - (pIn_buf)) - d->m_adler32 = - (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, - d->m_pSrc - (const mz_uint8 *)pIn_buf); - - if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && - (!d->m_output_flush_remaining)) { - if (tdefl_flush_block(d, flush) < 0) - return d->m_prev_return_status; - d->m_finished = (flush == TDEFL_FINISH); - if (flush == TDEFL_FULL_FLUSH) { - MZ_CLEAR_OBJ(d->m_hash); - MZ_CLEAR_OBJ(d->m_next); - d->m_dict_size = 0; - } - } - - return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); -} - -tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, - size_t in_buf_size, tdefl_flush flush) { - MZ_ASSERT(d->m_pPut_buf_func); - return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush); -} - -tdefl_status tdefl_init(tdefl_compressor *d, - tdefl_put_buf_func_ptr pPut_buf_func, - void *pPut_buf_user, int flags) { - d->m_pPut_buf_func = pPut_buf_func; - d->m_pPut_buf_user = pPut_buf_user; - d->m_flags = (mz_uint)(flags); - d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3; - d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0; - d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3; - if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) - MZ_CLEAR_OBJ(d->m_hash); - d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = - d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0; - d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = - d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0; - d->m_pLZ_code_buf = d->m_lz_code_buf + 1; - d->m_pLZ_flags = d->m_lz_code_buf; - *d->m_pLZ_flags = 0; - d->m_num_flags_left = 8; - d->m_pOutput_buf = d->m_output_buf; - d->m_pOutput_buf_end = d->m_output_buf; - d->m_prev_return_status = TDEFL_STATUS_OKAY; - d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0; - d->m_adler32 = 1; - d->m_pIn_buf = NULL; - d->m_pOut_buf = NULL; - d->m_pIn_buf_size = NULL; - d->m_pOut_buf_size = NULL; - d->m_flush = TDEFL_NO_FLUSH; - d->m_pSrc = NULL; - d->m_src_buf_left = 0; - d->m_out_buf_ofs = 0; - if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) - MZ_CLEAR_OBJ(d->m_dict); - memset(&d->m_huff_count[0][0], 0, - sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); - memset(&d->m_huff_count[1][0], 0, - sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); - return TDEFL_STATUS_OKAY; -} - -tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d) { - return d->m_prev_return_status; -} - -mz_uint32 tdefl_get_adler32(tdefl_compressor *d) { return d->m_adler32; } - -mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, - tdefl_put_buf_func_ptr pPut_buf_func, - void *pPut_buf_user, int flags) { - tdefl_compressor *pComp; - mz_bool succeeded; - if (((buf_len) && (!pBuf)) || (!pPut_buf_func)) - return MZ_FALSE; - pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); - if (!pComp) - return MZ_FALSE; - succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == - TDEFL_STATUS_OKAY); - succeeded = - succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == - TDEFL_STATUS_DONE); - MZ_FREE(pComp); - return succeeded; -} - -typedef struct { - size_t m_size, m_capacity; - mz_uint8 *m_pBuf; - mz_bool m_expandable; -} tdefl_output_buffer; - -static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, - void *pUser) { - tdefl_output_buffer *p = (tdefl_output_buffer *)pUser; - size_t new_size = p->m_size + len; - if (new_size > p->m_capacity) { - size_t new_capacity = p->m_capacity; - mz_uint8 *pNew_buf; - if (!p->m_expandable) - return MZ_FALSE; - do { - new_capacity = MZ_MAX(128U, new_capacity << 1U); - } while (new_size > new_capacity); - pNew_buf = (mz_uint8 *)MZ_REALLOC(p->m_pBuf, new_capacity); - if (!pNew_buf) - return MZ_FALSE; - p->m_pBuf = pNew_buf; - p->m_capacity = new_capacity; - } - memcpy((mz_uint8 *)p->m_pBuf + p->m_size, pBuf, len); - p->m_size = new_size; - return MZ_TRUE; -} - -void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, - size_t *pOut_len, int flags) { - tdefl_output_buffer out_buf; - MZ_CLEAR_OBJ(out_buf); - if (!pOut_len) - return MZ_FALSE; - else - *pOut_len = 0; - out_buf.m_expandable = MZ_TRUE; - if (!tdefl_compress_mem_to_output( - pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) - return NULL; - *pOut_len = out_buf.m_size; - return out_buf.m_pBuf; -} - -size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, - const void *pSrc_buf, size_t src_buf_len, - int flags) { - tdefl_output_buffer out_buf; - MZ_CLEAR_OBJ(out_buf); - if (!pOut_buf) - return 0; - out_buf.m_pBuf = (mz_uint8 *)pOut_buf; - out_buf.m_capacity = out_buf_len; - if (!tdefl_compress_mem_to_output( - pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) - return 0; - return out_buf.m_size; -} - -static const mz_uint s_tdefl_num_probes[11] = {0, 1, 6, 32, 16, 32, - 128, 256, 512, 768, 1500}; - -/* level may actually range from [0,10] (10 is a "hidden" max level, where we - * want a bit more compression and it's fine if throughput to fall off a cliff - * on some files). */ -mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, - int strategy) { - mz_uint comp_flags = - s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | - ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); - if (window_bits > 0) - comp_flags |= TDEFL_WRITE_ZLIB_HEADER; - - if (!level) - comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; - else if (strategy == MZ_FILTERED) - comp_flags |= TDEFL_FILTER_MATCHES; - else if (strategy == MZ_HUFFMAN_ONLY) - comp_flags &= ~TDEFL_MAX_PROBES_MASK; - else if (strategy == MZ_FIXED) - comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS; - else if (strategy == MZ_RLE) - comp_flags |= TDEFL_RLE_MATCHES; - - return comp_flags; -} - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4204) /* nonstandard extension used : non-constant \ - aggregate initializer (also supported by \ - GNU C and C99, so no big deal) */ -#endif - -/* Simple PNG writer function by Alex Evans, 2011. Released into the public - domain: https://gist.github.com/908299, more context at - http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/. - This is actually a modification of Alex's original code so PNG files generated - by this function pass pngcheck. */ -void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, - int h, int num_chans, - size_t *pLen_out, - mz_uint level, mz_bool flip) { - /* Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was - * defined. */ - static const mz_uint s_tdefl_png_num_probes[11] = { - 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500}; - tdefl_compressor *pComp = - (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); - tdefl_output_buffer out_buf; - int i, bpl = w * num_chans, y, z; - mz_uint32 c; - *pLen_out = 0; - if (!pComp) - return NULL; - MZ_CLEAR_OBJ(out_buf); - out_buf.m_expandable = MZ_TRUE; - out_buf.m_capacity = 57 + MZ_MAX(64, (1 + bpl) * h); - if (NULL == (out_buf.m_pBuf = (mz_uint8 *)MZ_MALLOC(out_buf.m_capacity))) { - MZ_FREE(pComp); - return NULL; - } - /* write dummy header */ - for (z = 41; z; --z) - tdefl_output_buffer_putter(&z, 1, &out_buf); - /* compress image data */ - tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, - s_tdefl_png_num_probes[MZ_MIN(10, level)] | - TDEFL_WRITE_ZLIB_HEADER); - for (y = 0; y < h; ++y) { - tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH); - tdefl_compress_buffer(pComp, - (mz_uint8 *)pImage + (flip ? (h - 1 - y) : y) * bpl, - bpl, TDEFL_NO_FLUSH); - } - if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != - TDEFL_STATUS_DONE) { - MZ_FREE(pComp); - MZ_FREE(out_buf.m_pBuf); - return NULL; - } - /* write real header */ - *pLen_out = out_buf.m_size - 41; - { - static const mz_uint8 chans[] = {0x00, 0x00, 0x04, 0x02, 0x06}; - mz_uint8 pnghdr[41] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, - 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x49, 0x44, 0x41, 0x54}; - pnghdr[18] = (mz_uint8)(w >> 8); - pnghdr[19] = (mz_uint8)w; - pnghdr[22] = (mz_uint8)(h >> 8); - pnghdr[23] = (mz_uint8)h; - pnghdr[25] = chans[num_chans]; - pnghdr[33] = (mz_uint8)(*pLen_out >> 24); - pnghdr[34] = (mz_uint8)(*pLen_out >> 16); - pnghdr[35] = (mz_uint8)(*pLen_out >> 8); - pnghdr[36] = (mz_uint8)*pLen_out; - c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, pnghdr + 12, 17); - for (i = 0; i < 4; ++i, c <<= 8) - ((mz_uint8 *)(pnghdr + 29))[i] = (mz_uint8)(c >> 24); - memcpy(out_buf.m_pBuf, pnghdr, 41); - } - /* write footer (IDAT CRC-32, followed by IEND chunk) */ - if (!tdefl_output_buffer_putter( - "\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) { - *pLen_out = 0; - MZ_FREE(pComp); - MZ_FREE(out_buf.m_pBuf); - return NULL; - } - c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, out_buf.m_pBuf + 41 - 4, - *pLen_out + 4); - for (i = 0; i < 4; ++i, c <<= 8) - (out_buf.m_pBuf + out_buf.m_size - 16)[i] = (mz_uint8)(c >> 24); - /* compute final size of file, grab compressed data buffer and return */ - *pLen_out += 57; - MZ_FREE(pComp); - return out_buf.m_pBuf; -} -void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, - int num_chans, size_t *pLen_out) { - /* Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we - * can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's - * where #defined out) */ - return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, - pLen_out, 6, MZ_FALSE); -} - -#ifndef MINIZ_NO_MALLOC -/* Allocate the tdefl_compressor and tinfl_decompressor structures in C so that - */ -/* non-C language bindings to tdefL_ and tinfl_ API don't need to worry about */ -/* structure size and allocation mechanism. */ -tdefl_compressor *tdefl_compressor_alloc(void) { - return (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); -} - -void tdefl_compressor_free(tdefl_compressor *pComp) { MZ_FREE(pComp); } -#endif - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#ifdef __cplusplus -} -#endif -/************************************************************************** - * - * Copyright 2013-2014 RAD Game Tools and Valve Software - * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - **************************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -/* ------------------- Low-level Decompression (completely independent from all - * compression API's) */ - -#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l) -#define TINFL_MEMSET(p, c, l) memset(p, c, l) - -#define TINFL_CR_BEGIN \ - switch (r->m_state) { \ - case 0: -#define TINFL_CR_RETURN(state_index, result) \ - do { \ - status = result; \ - r->m_state = state_index; \ - goto common_exit; \ - case state_index:; \ - } \ - MZ_MACRO_END -#define TINFL_CR_RETURN_FOREVER(state_index, result) \ - do { \ - for (;;) { \ - TINFL_CR_RETURN(state_index, result); \ - } \ - } \ - MZ_MACRO_END -#define TINFL_CR_FINISH } - -#define TINFL_GET_BYTE(state_index, c) \ - do { \ - while (pIn_buf_cur >= pIn_buf_end) { \ - TINFL_CR_RETURN(state_index, \ - (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) \ - ? TINFL_STATUS_NEEDS_MORE_INPUT \ - : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); \ - } \ - c = *pIn_buf_cur++; \ - } \ - MZ_MACRO_END - -#define TINFL_NEED_BITS(state_index, n) \ - do { \ - mz_uint c; \ - TINFL_GET_BYTE(state_index, c); \ - bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \ - num_bits += 8; \ - } while (num_bits < (mz_uint)(n)) -#define TINFL_SKIP_BITS(state_index, n) \ - do { \ - if (num_bits < (mz_uint)(n)) { \ - TINFL_NEED_BITS(state_index, n); \ - } \ - bit_buf >>= (n); \ - num_bits -= (n); \ - } \ - MZ_MACRO_END -#define TINFL_GET_BITS(state_index, b, n) \ - do { \ - if (num_bits < (mz_uint)(n)) { \ - TINFL_NEED_BITS(state_index, n); \ - } \ - b = bit_buf & ((1 << (n)) - 1); \ - bit_buf >>= (n); \ - num_bits -= (n); \ - } \ - MZ_MACRO_END - -/* TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes - * remaining in the input buffer falls below 2. */ -/* It reads just enough bytes from the input stream that are needed to decode - * the next Huffman code (and absolutely no more). It works by trying to fully - * decode a */ -/* Huffman code by using whatever bits are currently present in the bit buffer. - * If this fails, it reads another byte, and tries again until it succeeds or - * until the */ -/* bit buffer contains >=15 bits (deflate's max. Huffman code size). */ -#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \ - do { \ - temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ - if (temp >= 0) { \ - code_len = temp >> 9; \ - if ((code_len) && (num_bits >= code_len)) \ - break; \ - } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \ - code_len = TINFL_FAST_LOOKUP_BITS; \ - do { \ - temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ - } while ((temp < 0) && (num_bits >= (code_len + 1))); \ - if (temp >= 0) \ - break; \ - } \ - TINFL_GET_BYTE(state_index, c); \ - bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \ - num_bits += 8; \ - } while (num_bits < 15); - -/* TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex - * than you would initially expect because the zlib API expects the decompressor - * to never read */ -/* beyond the final byte of the deflate stream. (In other words, when this macro - * wants to read another byte from the input, it REALLY needs another byte in - * order to fully */ -/* decode the next Huffman code.) Handling this properly is particularly - * important on raw deflate (non-zlib) streams, which aren't followed by a byte - * aligned adler-32. */ -/* The slow path is only executed at the very end of the input buffer. */ -/* v1.16: The original macro handled the case at the very end of the passed-in - * input buffer, but we also need to handle the case where the user passes in - * 1+zillion bytes */ -/* following the deflate data and our non-conservative read-ahead path won't - * kick in here on this code. This is much trickier. */ -#define TINFL_HUFF_DECODE(state_index, sym, pHuff) \ - do { \ - int temp; \ - mz_uint code_len, c; \ - if (num_bits < 15) { \ - if ((pIn_buf_end - pIn_buf_cur) < 2) { \ - TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \ - } else { \ - bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | \ - (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); \ - pIn_buf_cur += 2; \ - num_bits += 16; \ - } \ - } \ - if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= \ - 0) \ - code_len = temp >> 9, temp &= 511; \ - else { \ - code_len = TINFL_FAST_LOOKUP_BITS; \ - do { \ - temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ - } while (temp < 0); \ - } \ - sym = temp; \ - bit_buf >>= code_len; \ - num_bits -= code_len; \ - } \ - MZ_MACRO_END - -tinfl_status tinfl_decompress(tinfl_decompressor *r, - const mz_uint8 *pIn_buf_next, - size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, - mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, - const mz_uint32 decomp_flags) { - static const int s_length_base[31] = { - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const int s_length_extra[31] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, - 4, 4, 5, 5, 5, 5, 0, 0, 0}; - static const int s_dist_base[32] = { - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, - 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, - 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0}; - static const int s_dist_extra[32] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, - 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; - static const mz_uint8 s_length_dezigzag[19] = { - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - static const int s_min_table_sizes[3] = {257, 1, 4}; - - tinfl_status status = TINFL_STATUS_FAILED; - mz_uint32 num_bits, dist, counter, num_extra; - tinfl_bit_buf_t bit_buf; - const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = - pIn_buf_next + *pIn_buf_size; - mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = - pOut_buf_next + *pOut_buf_size; - size_t out_buf_size_mask = - (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) - ? (size_t)-1 - : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, - dist_from_out_buf_start; - - /* Ensure the output buffer's size is a power of 2, unless the output buffer - * is large enough to hold the entire output file (in which case it doesn't - * matter). */ - if (((out_buf_size_mask + 1) & out_buf_size_mask) || - (pOut_buf_next < pOut_buf_start)) { - *pIn_buf_size = *pOut_buf_size = 0; - return TINFL_STATUS_BAD_PARAM; - } - - num_bits = r->m_num_bits; - bit_buf = r->m_bit_buf; - dist = r->m_dist; - counter = r->m_counter; - num_extra = r->m_num_extra; - dist_from_out_buf_start = r->m_dist_from_out_buf_start; - TINFL_CR_BEGIN - - bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; - r->m_z_adler32 = r->m_check_adler32 = 1; - if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) { - TINFL_GET_BYTE(1, r->m_zhdr0); - TINFL_GET_BYTE(2, r->m_zhdr1); - counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || - (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8)); - if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) - counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || - ((out_buf_size_mask + 1) < - (size_t)(1U << (8U + (r->m_zhdr0 >> 4))))); - if (counter) { - TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); - } - } - - do { - TINFL_GET_BITS(3, r->m_final, 3); - r->m_type = r->m_final >> 1; - if (r->m_type == 0) { - TINFL_SKIP_BITS(5, num_bits & 7); - for (counter = 0; counter < 4; ++counter) { - if (num_bits) - TINFL_GET_BITS(6, r->m_raw_header[counter], 8); - else - TINFL_GET_BYTE(7, r->m_raw_header[counter]); - } - if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != - (mz_uint)(0xFFFF ^ - (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) { - TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); - } - while ((counter) && (num_bits)) { - TINFL_GET_BITS(51, dist, 8); - while (pOut_buf_cur >= pOut_buf_end) { - TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); - } - *pOut_buf_cur++ = (mz_uint8)dist; - counter--; - } - while (counter) { - size_t n; - while (pOut_buf_cur >= pOut_buf_end) { - TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); - } - while (pIn_buf_cur >= pIn_buf_end) { - TINFL_CR_RETURN(38, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) - ? TINFL_STATUS_NEEDS_MORE_INPUT - : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); - } - n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), - (size_t)(pIn_buf_end - pIn_buf_cur)), - counter); - TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); - pIn_buf_cur += n; - pOut_buf_cur += n; - counter -= (mz_uint)n; - } - } else if (r->m_type == 3) { - TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED); - } else { - if (r->m_type == 1) { - mz_uint8 *p = r->m_tables[0].m_code_size; - mz_uint i; - r->m_table_sizes[0] = 288; - r->m_table_sizes[1] = 32; - TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32); - for (i = 0; i <= 143; ++i) - *p++ = 8; - for (; i <= 255; ++i) - *p++ = 9; - for (; i <= 279; ++i) - *p++ = 7; - for (; i <= 287; ++i) - *p++ = 8; - } else { - for (counter = 0; counter < 3; counter++) { - TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); - r->m_table_sizes[counter] += s_min_table_sizes[counter]; - } - MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); - for (counter = 0; counter < r->m_table_sizes[2]; counter++) { - mz_uint s; - TINFL_GET_BITS(14, s, 3); - r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; - } - r->m_table_sizes[2] = 19; - } - for (; (int)r->m_type >= 0; r->m_type--) { - int tree_next, tree_cur; - tinfl_huff_table *pTable; - mz_uint i, j, used_syms, total, sym_index, next_code[17], - total_syms[16]; - pTable = &r->m_tables[r->m_type]; - MZ_CLEAR_OBJ(total_syms); - MZ_CLEAR_OBJ(pTable->m_look_up); - MZ_CLEAR_OBJ(pTable->m_tree); - for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) - total_syms[pTable->m_code_size[i]]++; - used_syms = 0, total = 0; - next_code[0] = next_code[1] = 0; - for (i = 1; i <= 15; ++i) { - used_syms += total_syms[i]; - next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); - } - if ((65536 != total) && (used_syms > 1)) { - TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED); - } - for (tree_next = -1, sym_index = 0; - sym_index < r->m_table_sizes[r->m_type]; ++sym_index) { - mz_uint rev_code = 0, l, cur_code, - code_size = pTable->m_code_size[sym_index]; - - if (!code_size) - continue; - cur_code = next_code[code_size]++; - for (l = code_size; l > 0; l--, cur_code >>= 1) - rev_code = (rev_code << 1) | (cur_code & 1); - if (code_size <= TINFL_FAST_LOOKUP_BITS) { - mz_int16 k = (mz_int16)((code_size << 9) | sym_index); - while (rev_code < TINFL_FAST_LOOKUP_SIZE) { - pTable->m_look_up[rev_code] = k; - rev_code += (1 << code_size); - } - continue; - } - if (0 == - (tree_cur = pTable->m_look_up[rev_code & - (TINFL_FAST_LOOKUP_SIZE - 1)])) { - pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = - (mz_int16)tree_next; - tree_cur = tree_next; - tree_next -= 2; - } - rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1); - for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) { - tree_cur -= ((rev_code >>= 1) & 1); - if (!pTable->m_tree[-tree_cur - 1]) { - pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; - tree_cur = tree_next; - tree_next -= 2; - } else - tree_cur = pTable->m_tree[-tree_cur - 1]; - } - tree_cur -= ((rev_code >>= 1) & 1); - (void)rev_code; // unused - pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index; - } - if (r->m_type == 2) { - for (counter = 0; - counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);) { - mz_uint s; - TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); - if (dist < 16) { - r->m_len_codes[counter++] = (mz_uint8)dist; - continue; - } - if ((dist == 16) && (!counter)) { - TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED); - } - num_extra = "\02\03\07"[dist - 16]; - TINFL_GET_BITS(18, s, num_extra); - s += "\03\03\013"[dist - 16]; - TINFL_MEMSET(r->m_len_codes + counter, - (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); - counter += s; - } - if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter) { - TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED); - } - TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, - r->m_table_sizes[0]); - TINFL_MEMCPY(r->m_tables[1].m_code_size, - r->m_len_codes + r->m_table_sizes[0], - r->m_table_sizes[1]); - } - } - for (;;) { - mz_uint8 *pSrc; - for (;;) { - if (((pIn_buf_end - pIn_buf_cur) < 4) || - ((pOut_buf_end - pOut_buf_cur) < 2)) { - TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]); - if (counter >= 256) - break; - while (pOut_buf_cur >= pOut_buf_end) { - TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); - } - *pOut_buf_cur++ = (mz_uint8)counter; - } else { - int sym2; - mz_uint code_len; -#if TINFL_USE_64BIT_BITBUF - if (num_bits < 30) { - bit_buf |= - (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); - pIn_buf_cur += 4; - num_bits += 32; - } -#else - if (num_bits < 15) { - bit_buf |= - (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); - pIn_buf_cur += 2; - num_bits += 16; - } -#endif - if ((sym2 = - r->m_tables[0] - .m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= - 0) - code_len = sym2 >> 9; - else { - code_len = TINFL_FAST_LOOKUP_BITS; - do { - sym2 = r->m_tables[0] - .m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; - } while (sym2 < 0); - } - counter = sym2; - bit_buf >>= code_len; - num_bits -= code_len; - if (counter & 256) - break; - -#if !TINFL_USE_64BIT_BITBUF - if (num_bits < 15) { - bit_buf |= - (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); - pIn_buf_cur += 2; - num_bits += 16; - } -#endif - if ((sym2 = - r->m_tables[0] - .m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= - 0) - code_len = sym2 >> 9; - else { - code_len = TINFL_FAST_LOOKUP_BITS; - do { - sym2 = r->m_tables[0] - .m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; - } while (sym2 < 0); - } - bit_buf >>= code_len; - num_bits -= code_len; - - pOut_buf_cur[0] = (mz_uint8)counter; - if (sym2 & 256) { - pOut_buf_cur++; - counter = sym2; - break; - } - pOut_buf_cur[1] = (mz_uint8)sym2; - pOut_buf_cur += 2; - } - } - if ((counter &= 511) == 256) - break; - - num_extra = s_length_extra[counter - 257]; - counter = s_length_base[counter - 257]; - if (num_extra) { - mz_uint extra_bits; - TINFL_GET_BITS(25, extra_bits, num_extra); - counter += extra_bits; - } - - TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]); - num_extra = s_dist_extra[dist]; - dist = s_dist_base[dist]; - if (num_extra) { - mz_uint extra_bits; - TINFL_GET_BITS(27, extra_bits, num_extra); - dist += extra_bits; - } - - dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start; - if ((dist == 0 || dist > dist_from_out_buf_start || - dist_from_out_buf_start == 0) && - (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) { - TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED); - } - - pSrc = pOut_buf_start + - ((dist_from_out_buf_start - dist) & out_buf_size_mask); - - if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end) { - while (counter--) { - while (pOut_buf_cur >= pOut_buf_end) { - TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); - } - *pOut_buf_cur++ = - pOut_buf_start[(dist_from_out_buf_start++ - dist) & - out_buf_size_mask]; - } - continue; - } -#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES - else if ((counter >= 9) && (counter <= dist)) { - const mz_uint8 *pSrc_end = pSrc + (counter & ~7); - do { -#ifdef MINIZ_UNALIGNED_USE_MEMCPY - memcpy(pOut_buf_cur, pSrc, sizeof(mz_uint32) * 2); -#else - ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0]; - ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1]; -#endif - pOut_buf_cur += 8; - } while ((pSrc += 8) < pSrc_end); - if ((counter &= 7) < 3) { - if (counter) { - pOut_buf_cur[0] = pSrc[0]; - if (counter > 1) - pOut_buf_cur[1] = pSrc[1]; - pOut_buf_cur += counter; - } - continue; - } - } -#endif - while (counter > 2) { - pOut_buf_cur[0] = pSrc[0]; - pOut_buf_cur[1] = pSrc[1]; - pOut_buf_cur[2] = pSrc[2]; - pOut_buf_cur += 3; - pSrc += 3; - counter -= 3; - } - if (counter > 0) { - pOut_buf_cur[0] = pSrc[0]; - if (counter > 1) - pOut_buf_cur[1] = pSrc[1]; - pOut_buf_cur += counter; - } - } - } - } while (!(r->m_final & 1)); - - /* Ensure byte alignment and put back any bytes from the bitbuf if we've - * looked ahead too far on gzip, or other Deflate streams followed by - * arbitrary data. */ - /* I'm being super conservative here. A number of simplifications can be made - * to the byte alignment part, and the Adler32 check shouldn't ever need to - * worry about reading from the bitbuf now. */ - TINFL_SKIP_BITS(32, num_bits & 7); - while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8)) { - --pIn_buf_cur; - num_bits -= 8; - } - bit_buf &= (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1); - MZ_ASSERT(!num_bits); /* if this assert fires then we've read beyond the end - of non-deflate/zlib streams with following data (such - as gzip streams). */ - - if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) { - for (counter = 0; counter < 4; ++counter) { - mz_uint s; - if (num_bits) - TINFL_GET_BITS(41, s, 8); - else - TINFL_GET_BYTE(42, s); - r->m_z_adler32 = (r->m_z_adler32 << 8) | s; - } - } - TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE); - - TINFL_CR_FINISH - -common_exit: - /* As long as we aren't telling the caller that we NEED more input to make - * forward progress: */ - /* Put back any bytes from the bitbuf in case we've looked ahead too far on - * gzip, or other Deflate streams followed by arbitrary data. */ - /* We need to be very careful here to NOT push back any bytes we definitely - * know we need to make forward progress, though, or we'll lock the caller up - * into an inf loop. */ - if ((status != TINFL_STATUS_NEEDS_MORE_INPUT) && - (status != TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS)) { - while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8)) { - --pIn_buf_cur; - num_bits -= 8; - } - } - r->m_num_bits = num_bits; - r->m_bit_buf = - bit_buf & (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1); - r->m_dist = dist; - r->m_counter = counter; - r->m_num_extra = num_extra; - r->m_dist_from_out_buf_start = dist_from_out_buf_start; - *pIn_buf_size = pIn_buf_cur - pIn_buf_next; - *pOut_buf_size = pOut_buf_cur - pOut_buf_next; - if ((decomp_flags & - (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && - (status >= 0)) { - const mz_uint8 *ptr = pOut_buf_next; - size_t buf_len = *pOut_buf_size; - mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, - s2 = r->m_check_adler32 >> 16; - size_t block_len = buf_len % 5552; - while (buf_len) { - for (i = 0; i + 7 < block_len; i += 8, ptr += 8) { - s1 += ptr[0], s2 += s1; - s1 += ptr[1], s2 += s1; - s1 += ptr[2], s2 += s1; - s1 += ptr[3], s2 += s1; - s1 += ptr[4], s2 += s1; - s1 += ptr[5], s2 += s1; - s1 += ptr[6], s2 += s1; - s1 += ptr[7], s2 += s1; - } - for (; i < block_len; ++i) - s1 += *ptr++, s2 += s1; - s1 %= 65521U, s2 %= 65521U; - buf_len -= block_len; - block_len = 5552; - } - r->m_check_adler32 = (s2 << 16) + s1; - if ((status == TINFL_STATUS_DONE) && - (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && - (r->m_check_adler32 != r->m_z_adler32)) - status = TINFL_STATUS_ADLER32_MISMATCH; - } - return status; -} - -/* Higher level helper functions. */ -void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, - size_t *pOut_len, int flags) { - tinfl_decompressor decomp; - void *pBuf = NULL, *pNew_buf; - size_t src_buf_ofs = 0, out_buf_capacity = 0; - *pOut_len = 0; - tinfl_init(&decomp); - for (;;) { - size_t src_buf_size = src_buf_len - src_buf_ofs, - dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity; - tinfl_status status = tinfl_decompress( - &decomp, (const mz_uint8 *)pSrc_buf + src_buf_ofs, &src_buf_size, - (mz_uint8 *)pBuf, pBuf ? (mz_uint8 *)pBuf + *pOut_len : NULL, - &dst_buf_size, - (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | - TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); - if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) { - MZ_FREE(pBuf); - *pOut_len = 0; - return NULL; - } - src_buf_ofs += src_buf_size; - *pOut_len += dst_buf_size; - if (status == TINFL_STATUS_DONE) - break; - new_out_buf_capacity = out_buf_capacity * 2; - if (new_out_buf_capacity < 128) - new_out_buf_capacity = 128; - pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity); - if (!pNew_buf) { - MZ_FREE(pBuf); - *pOut_len = 0; - return NULL; - } - pBuf = pNew_buf; - out_buf_capacity = new_out_buf_capacity; - } - return pBuf; -} - -size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, - const void *pSrc_buf, size_t src_buf_len, - int flags) { - tinfl_decompressor decomp; - tinfl_status status; - tinfl_init(&decomp); - status = - tinfl_decompress(&decomp, (const mz_uint8 *)pSrc_buf, &src_buf_len, - (mz_uint8 *)pOut_buf, (mz_uint8 *)pOut_buf, &out_buf_len, - (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | - TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); - return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED - : out_buf_len; -} - -int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, - tinfl_put_buf_func_ptr pPut_buf_func, - void *pPut_buf_user, int flags) { - int result = 0; - tinfl_decompressor decomp; - mz_uint8 *pDict = (mz_uint8 *)MZ_MALLOC(TINFL_LZ_DICT_SIZE); - size_t in_buf_ofs = 0, dict_ofs = 0; - if (!pDict) - return TINFL_STATUS_FAILED; - tinfl_init(&decomp); - for (;;) { - size_t in_buf_size = *pIn_buf_size - in_buf_ofs, - dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs; - tinfl_status status = - tinfl_decompress(&decomp, (const mz_uint8 *)pIn_buf + in_buf_ofs, - &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size, - (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | - TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))); - in_buf_ofs += in_buf_size; - if ((dst_buf_size) && - (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user))) - break; - if (status != TINFL_STATUS_HAS_MORE_OUTPUT) { - result = (status == TINFL_STATUS_DONE); - break; - } - dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1); - } - MZ_FREE(pDict); - *pIn_buf_size = in_buf_ofs; - return result; -} - -#ifndef MINIZ_NO_MALLOC -tinfl_decompressor *tinfl_decompressor_alloc(void) { - tinfl_decompressor *pDecomp = - (tinfl_decompressor *)MZ_MALLOC(sizeof(tinfl_decompressor)); - if (pDecomp) - tinfl_init(pDecomp); - return pDecomp; -} - -void tinfl_decompressor_free(tinfl_decompressor *pDecomp) { MZ_FREE(pDecomp); } -#endif - -#ifdef __cplusplus -} -#endif -/************************************************************************** - * - * Copyright 2013-2014 RAD Game Tools and Valve Software - * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC - * Copyright 2016 Martin Raiber - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - **************************************************************************/ - -#ifndef MINIZ_NO_ARCHIVE_APIS - -#ifdef __cplusplus -extern "C" { -#endif - -/* ------------------- .ZIP archive reading */ - -#ifdef MINIZ_NO_STDIO -#define MZ_FILE void * -#else -#include - -#if defined(_MSC_VER) -#include -#ifndef MINIZ_NO_TIME -#include -#endif -static wchar_t *str2wstr(const char *str) { - size_t len = strlen(str) + 1; - wchar_t *wstr = (wchar_t *)malloc(len * sizeof(wchar_t)); - MultiByteToWideChar(CP_UTF8, 0, str, (int)(len * sizeof(char)), wstr, - (int)len); - return wstr; -} - -static FILE *mz_fopen(const char *pFilename, const char *pMode) { - FILE *pFile = NULL; - wchar_t *wFilename = str2wstr(pFilename); - wchar_t *wMode = str2wstr(pMode); - -#ifdef ZIP_ENABLE_SHARABLE_FILE_OPEN - pFile = _wfopen(wFilename, wMode); -#else - _wfopen_s(&pFile, wFilename, wMode); -#endif - free(wFilename); - free(wMode); - - return pFile; -} - -static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) { - FILE *pFile = NULL; - int res = 0; - - wchar_t *wPath = str2wstr(pPath); - wchar_t *wMode = str2wstr(pMode); - -#ifdef ZIP_ENABLE_SHARABLE_FILE_OPEN - pFile = _wfreopen(wPath, wMode, pStream); -#else - res = _wfreopen_s(&pFile, wPath, wMode, pStream); -#endif - - free(wPath); - free(wMode); - -#ifndef ZIP_ENABLE_SHARABLE_FILE_OPEN - if (res) { - return NULL; - } -#endif - - return pFile; -} - -static int mz_stat(const char *pPath, struct _stat64 *buffer) { - wchar_t *wPath = str2wstr(pPath); - int res = _wstat64(wPath, buffer); - - free(wPath); - - return res; -} - -static int mz_mkdir(const char *pDirname) { - wchar_t *wDirname = str2wstr(pDirname); - int res = _wmkdir(wDirname); - - free(wDirname); - - return res; -} - -#define MZ_FOPEN mz_fopen -#define MZ_FCLOSE fclose -#define MZ_FREAD fread -#define MZ_FWRITE fwrite -#define MZ_FTELL64 _ftelli64 -#define MZ_FSEEK64 _fseeki64 -#define MZ_FILE_STAT_STRUCT _stat64 -#define MZ_FILE_STAT mz_stat -#define MZ_FFLUSH fflush -#define MZ_FREOPEN mz_freopen -#define MZ_DELETE_FILE remove -#define MZ_MKDIR(d) mz_mkdir(d) - -#elif defined(__MINGW32__) || defined(__MINGW64__) -#include -#ifndef MINIZ_NO_TIME -#include -#endif - -#define MZ_FOPEN(f, m) fopen(f, m) -#define MZ_FCLOSE fclose -#define MZ_FREAD fread -#define MZ_FWRITE fwrite -#define MZ_FTELL64 ftell -#define MZ_FSEEK64 fseek -#define MZ_FILE_STAT_STRUCT stat -#define MZ_FILE_STAT stat -#define MZ_FFLUSH fflush -#define MZ_FREOPEN(f, m, s) freopen(f, m, s) -#define MZ_DELETE_FILE remove -#define MZ_MKDIR(d) _mkdir(d) - -#elif defined(__TINYC__) -#ifndef MINIZ_NO_TIME -#include -#endif - -#define MZ_FOPEN(f, m) fopen(f, m) -#define MZ_FCLOSE fclose -#define MZ_FREAD fread -#define MZ_FWRITE fwrite -#define MZ_FTELL64 ftell -#define MZ_FSEEK64 fseek -#define MZ_FILE_STAT_STRUCT stat -#define MZ_FILE_STAT stat -#define MZ_FFLUSH fflush -#define MZ_FREOPEN(f, m, s) freopen(f, m, s) -#define MZ_DELETE_FILE remove -#if defined(_WIN32) || defined(_WIN64) -#define MZ_MKDIR(d) _mkdir(d) -#else -#define MZ_MKDIR(d) mkdir(d, 0755) -#endif - -#elif defined(__USE_LARGEFILE64) /* gcc, clang */ -#ifndef MINIZ_NO_TIME -#include -#endif - -#define MZ_FOPEN(f, m) fopen64(f, m) -#define MZ_FCLOSE fclose -#define MZ_FREAD fread -#define MZ_FWRITE fwrite -#define MZ_FTELL64 ftello64 -#define MZ_FSEEK64 fseeko64 -#define MZ_FILE_STAT_STRUCT stat64 -#define MZ_FILE_STAT stat64 -#define MZ_FFLUSH fflush -#define MZ_FREOPEN(p, m, s) freopen64(p, m, s) -#define MZ_DELETE_FILE remove -#define MZ_MKDIR(d) mkdir(d, 0755) - -#elif defined(__APPLE__) -#ifndef MINIZ_NO_TIME -#include -#endif - -#define MZ_FOPEN(f, m) fopen(f, m) -#define MZ_FCLOSE fclose -#define MZ_FREAD fread -#define MZ_FWRITE fwrite -#define MZ_FTELL64 ftello -#define MZ_FSEEK64 fseeko -#define MZ_FILE_STAT_STRUCT stat -#define MZ_FILE_STAT stat -#define MZ_FFLUSH fflush -#define MZ_FREOPEN(p, m, s) freopen(p, m, s) -#define MZ_DELETE_FILE remove -#define MZ_MKDIR(d) mkdir(d, 0755) - -#else -#pragma message( \ - "Using fopen, ftello, fseeko, stat() etc. path for file I/O - this path may not support large files.") -#ifndef MINIZ_NO_TIME -#include -#endif - -#define MZ_FOPEN(f, m) fopen(f, m) -#define MZ_FCLOSE fclose -#define MZ_FREAD fread -#define MZ_FWRITE fwrite -#ifdef __STRICT_ANSI__ -#define MZ_FTELL64 ftell -#define MZ_FSEEK64 fseek -#else -#define MZ_FTELL64 ftello -#define MZ_FSEEK64 fseeko -#endif -#define MZ_FILE_STAT_STRUCT stat -#define MZ_FILE_STAT stat -#define MZ_FFLUSH fflush -#define MZ_FREOPEN(f, m, s) freopen(f, m, s) -#define MZ_DELETE_FILE remove -#define MZ_MKDIR(d) mkdir(d, 0755) - -#endif /* #ifdef _MSC_VER */ -#endif /* #ifdef MINIZ_NO_STDIO */ - -#ifndef CHMOD -// Upon successful completion, a value of 0 is returned. -// Otherwise, a value of -1 is returned and errno is set to indicate the error. -// int chmod(const char *path, mode_t mode); -#define CHMOD(f, m) chmod(f, m) -#endif - -#define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c)) - -/* Various ZIP archive enums. To completely avoid cross platform compiler - * alignment and platform endian issues, miniz.c doesn't use structs for any of - * this stuff. */ -enum { - /* ZIP archive identifiers and record sizes */ - MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06054b50, - MZ_ZIP_CENTRAL_DIR_HEADER_SIG = 0x02014b50, - MZ_ZIP_LOCAL_DIR_HEADER_SIG = 0x04034b50, - MZ_ZIP_LOCAL_DIR_HEADER_SIZE = 30, - MZ_ZIP_CENTRAL_DIR_HEADER_SIZE = 46, - MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE = 22, - - /* ZIP64 archive identifier and record sizes */ - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06064b50, - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG = 0x07064b50, - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE = 56, - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE = 20, - MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID = 0x0001, - MZ_ZIP_DATA_DESCRIPTOR_ID = 0x08074b50, - MZ_ZIP_DATA_DESCRIPTER_SIZE64 = 24, - MZ_ZIP_DATA_DESCRIPTER_SIZE32 = 16, - - /* Central directory header record offsets */ - MZ_ZIP_CDH_SIG_OFS = 0, - MZ_ZIP_CDH_VERSION_MADE_BY_OFS = 4, - MZ_ZIP_CDH_VERSION_NEEDED_OFS = 6, - MZ_ZIP_CDH_BIT_FLAG_OFS = 8, - MZ_ZIP_CDH_METHOD_OFS = 10, - MZ_ZIP_CDH_FILE_TIME_OFS = 12, - MZ_ZIP_CDH_FILE_DATE_OFS = 14, - MZ_ZIP_CDH_CRC32_OFS = 16, - MZ_ZIP_CDH_COMPRESSED_SIZE_OFS = 20, - MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS = 24, - MZ_ZIP_CDH_FILENAME_LEN_OFS = 28, - MZ_ZIP_CDH_EXTRA_LEN_OFS = 30, - MZ_ZIP_CDH_COMMENT_LEN_OFS = 32, - MZ_ZIP_CDH_DISK_START_OFS = 34, - MZ_ZIP_CDH_INTERNAL_ATTR_OFS = 36, - MZ_ZIP_CDH_EXTERNAL_ATTR_OFS = 38, - MZ_ZIP_CDH_LOCAL_HEADER_OFS = 42, - - /* Local directory header offsets */ - MZ_ZIP_LDH_SIG_OFS = 0, - MZ_ZIP_LDH_VERSION_NEEDED_OFS = 4, - MZ_ZIP_LDH_BIT_FLAG_OFS = 6, - MZ_ZIP_LDH_METHOD_OFS = 8, - MZ_ZIP_LDH_FILE_TIME_OFS = 10, - MZ_ZIP_LDH_FILE_DATE_OFS = 12, - MZ_ZIP_LDH_CRC32_OFS = 14, - MZ_ZIP_LDH_COMPRESSED_SIZE_OFS = 18, - MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS = 22, - MZ_ZIP_LDH_FILENAME_LEN_OFS = 26, - MZ_ZIP_LDH_EXTRA_LEN_OFS = 28, - MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR = 1 << 3, - - /* End of central directory offsets */ - MZ_ZIP_ECDH_SIG_OFS = 0, - MZ_ZIP_ECDH_NUM_THIS_DISK_OFS = 4, - MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS = 6, - MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 8, - MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS = 10, - MZ_ZIP_ECDH_CDIR_SIZE_OFS = 12, - MZ_ZIP_ECDH_CDIR_OFS_OFS = 16, - MZ_ZIP_ECDH_COMMENT_SIZE_OFS = 20, - - /* ZIP64 End of central directory locator offsets */ - MZ_ZIP64_ECDL_SIG_OFS = 0, /* 4 bytes */ - MZ_ZIP64_ECDL_NUM_DISK_CDIR_OFS = 4, /* 4 bytes */ - MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS = 8, /* 8 bytes */ - MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS = 16, /* 4 bytes */ - - /* ZIP64 End of central directory header offsets */ - MZ_ZIP64_ECDH_SIG_OFS = 0, /* 4 bytes */ - MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS = 4, /* 8 bytes */ - MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS = 12, /* 2 bytes */ - MZ_ZIP64_ECDH_VERSION_NEEDED_OFS = 14, /* 2 bytes */ - MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS = 16, /* 4 bytes */ - MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS = 20, /* 4 bytes */ - MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 24, /* 8 bytes */ - MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS = 32, /* 8 bytes */ - MZ_ZIP64_ECDH_CDIR_SIZE_OFS = 40, /* 8 bytes */ - MZ_ZIP64_ECDH_CDIR_OFS_OFS = 48, /* 8 bytes */ - MZ_ZIP_VERSION_MADE_BY_DOS_FILESYSTEM_ID = 0, - MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG = 0x10, - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED = 1, - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG = 32, - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION = 64, - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED = 8192, - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8 = 1 << 11 -}; - -typedef struct { - void *m_p; - size_t m_size, m_capacity; - mz_uint m_element_size; -} mz_zip_array; - -struct mz_zip_internal_state_tag { - mz_zip_array m_central_dir; - mz_zip_array m_central_dir_offsets; - mz_zip_array m_sorted_central_dir_offsets; - - /* The flags passed in when the archive is initially opened. */ - uint32_t m_init_flags; - - /* MZ_TRUE if the archive has a zip64 end of central directory headers, etc. - */ - mz_bool m_zip64; - - /* MZ_TRUE if we found zip64 extended info in the central directory (m_zip64 - * will also be slammed to true too, even if we didn't find a zip64 end of - * central dir header, etc.) */ - mz_bool m_zip64_has_extended_info_fields; - - /* These fields are used by the file, FILE, memory, and memory/heap read/write - * helpers. */ - MZ_FILE *m_pFile; - mz_uint64 m_file_archive_start_ofs; - - void *m_pMem; - size_t m_mem_size; - size_t m_mem_capacity; -}; - -#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) \ - (array_ptr)->m_element_size = element_size - -#if defined(DEBUG) || defined(_DEBUG) -static MZ_FORCEINLINE mz_uint -mz_zip_array_range_check(const mz_zip_array *pArray, mz_uint index) { - MZ_ASSERT(index < pArray->m_size); - return index; -} -#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) \ - ((element_type *)((array_ptr) \ - ->m_p))[mz_zip_array_range_check(array_ptr, index)] -#else -#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) \ - ((element_type *)((array_ptr)->m_p))[index] -#endif - -static MZ_FORCEINLINE void mz_zip_array_init(mz_zip_array *pArray, - mz_uint32 element_size) { - memset(pArray, 0, sizeof(mz_zip_array)); - pArray->m_element_size = element_size; -} - -static MZ_FORCEINLINE void mz_zip_array_clear(mz_zip_archive *pZip, - mz_zip_array *pArray) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p); - memset(pArray, 0, sizeof(mz_zip_array)); -} - -static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip, - mz_zip_array *pArray, - size_t min_new_capacity, - mz_uint growing) { - void *pNew_p; - size_t new_capacity = min_new_capacity; - MZ_ASSERT(pArray->m_element_size); - if (pArray->m_capacity >= min_new_capacity) - return MZ_TRUE; - if (growing) { - new_capacity = MZ_MAX(1, pArray->m_capacity); - while (new_capacity < min_new_capacity) - new_capacity *= 2; - } - if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p, - pArray->m_element_size, new_capacity))) - return MZ_FALSE; - pArray->m_p = pNew_p; - pArray->m_capacity = new_capacity; - return MZ_TRUE; -} - -static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(mz_zip_archive *pZip, - mz_zip_array *pArray, - size_t new_capacity, - mz_uint growing) { - if (new_capacity > pArray->m_capacity) { - if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing)) - return MZ_FALSE; - } - return MZ_TRUE; -} - -static MZ_FORCEINLINE mz_bool mz_zip_array_resize(mz_zip_archive *pZip, - mz_zip_array *pArray, - size_t new_size, - mz_uint growing) { - if (new_size > pArray->m_capacity) { - if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing)) - return MZ_FALSE; - } - pArray->m_size = new_size; - return MZ_TRUE; -} - -static MZ_FORCEINLINE mz_bool mz_zip_array_ensure_room(mz_zip_archive *pZip, - mz_zip_array *pArray, - size_t n) { - return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE); -} - -static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(mz_zip_archive *pZip, - mz_zip_array *pArray, - const void *pElements, - size_t n) { - size_t orig_size = pArray->m_size; - if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE)) - return MZ_FALSE; - if (n > 0) - memcpy((mz_uint8 *)pArray->m_p + orig_size * pArray->m_element_size, - pElements, n * pArray->m_element_size); - return MZ_TRUE; -} - -#ifndef MINIZ_NO_TIME -static MZ_TIME_T mz_zip_dos_to_time_t(int dos_time, int dos_date) { - struct tm tm; - memset(&tm, 0, sizeof(tm)); - tm.tm_isdst = -1; - tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900; - tm.tm_mon = ((dos_date >> 5) & 15) - 1; - tm.tm_mday = dos_date & 31; - tm.tm_hour = (dos_time >> 11) & 31; - tm.tm_min = (dos_time >> 5) & 63; - tm.tm_sec = (dos_time << 1) & 62; - return mktime(&tm); -} - -#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS -static void mz_zip_time_t_to_dos_time(MZ_TIME_T time, mz_uint16 *pDOS_time, - mz_uint16 *pDOS_date) { -#ifdef _MSC_VER - struct tm tm_struct; - struct tm *tm = &tm_struct; - errno_t err = localtime_s(tm, &time); - if (err) { - *pDOS_date = 0; - *pDOS_time = 0; - return; - } -#else - struct tm *tm = localtime(&time); -#endif /* #ifdef _MSC_VER */ - - *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + - ((tm->tm_sec) >> 1)); - *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + - ((tm->tm_mon + 1) << 5) + tm->tm_mday); -} -#endif /* MINIZ_NO_ARCHIVE_WRITING_APIS */ - -#ifndef MINIZ_NO_STDIO -#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS -static mz_bool mz_zip_get_file_modified_time(const char *pFilename, - MZ_TIME_T *pTime) { - struct MZ_FILE_STAT_STRUCT file_stat; - - /* On Linux with x86 glibc, this call will fail on large files (I think >= - * 0x80000000 bytes) unless you compiled with _LARGEFILE64_SOURCE. Argh. */ - if (MZ_FILE_STAT(pFilename, &file_stat) != 0) - return MZ_FALSE; - - *pTime = file_stat.st_mtime; - - return MZ_TRUE; -} -#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS*/ - -static mz_bool mz_zip_set_file_times(const char *pFilename, - MZ_TIME_T access_time, - MZ_TIME_T modified_time) { - struct utimbuf t; - - memset(&t, 0, sizeof(t)); - t.actime = access_time; - t.modtime = modified_time; - - return !utime(pFilename, &t); -} -#endif /* #ifndef MINIZ_NO_STDIO */ -#endif /* #ifndef MINIZ_NO_TIME */ - -static MZ_FORCEINLINE mz_bool mz_zip_set_error(mz_zip_archive *pZip, - mz_zip_error err_num) { - if (pZip) - pZip->m_last_error = err_num; - return MZ_FALSE; -} - -static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, - mz_uint flags) { - (void)flags; - if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (!pZip->m_pAlloc) - pZip->m_pAlloc = miniz_def_alloc_func; - if (!pZip->m_pFree) - pZip->m_pFree = miniz_def_free_func; - if (!pZip->m_pRealloc) - pZip->m_pRealloc = miniz_def_realloc_func; - - pZip->m_archive_size = 0; - pZip->m_central_directory_file_ofs = 0; - pZip->m_total_files = 0; - pZip->m_last_error = MZ_ZIP_NO_ERROR; - - if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc( - pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state)))) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state)); - MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, - sizeof(mz_uint8)); - MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, - sizeof(mz_uint32)); - MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, - sizeof(mz_uint32)); - pZip->m_pState->m_init_flags = flags; - pZip->m_pState->m_zip64 = MZ_FALSE; - pZip->m_pState->m_zip64_has_extended_info_fields = MZ_FALSE; - - pZip->m_zip_mode = MZ_ZIP_MODE_READING; - - return MZ_TRUE; -} - -static MZ_FORCEINLINE mz_bool -mz_zip_reader_filename_less(const mz_zip_array *pCentral_dir_array, - const mz_zip_array *pCentral_dir_offsets, - mz_uint l_index, mz_uint r_index) { - const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT( - pCentral_dir_array, mz_uint8, - MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, - l_index)), - *pE; - const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT( - pCentral_dir_array, mz_uint8, - MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index)); - mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS), - r_len = MZ_READ_LE16(pR + MZ_ZIP_CDH_FILENAME_LEN_OFS); - mz_uint8 l = 0, r = 0; - pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; - pR += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; - pE = pL + MZ_MIN(l_len, r_len); - while (pL < pE) { - if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR))) - break; - pL++; - pR++; - } - return (pL == pE) ? (l_len < r_len) : (l < r); -} - -#define MZ_SWAP_UINT32(a, b) \ - do { \ - mz_uint32 t = a; \ - a = b; \ - b = t; \ - } \ - MZ_MACRO_END - -/* Heap sort of lowercased filenames, used to help accelerate plain central - * directory searches by mz_zip_reader_locate_file(). (Could also use qsort(), - * but it could allocate memory.) */ -static void -mz_zip_reader_sort_central_dir_offsets_by_filename(mz_zip_archive *pZip) { - mz_zip_internal_state *pState = pZip->m_pState; - const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets; - const mz_zip_array *pCentral_dir = &pState->m_central_dir; - mz_uint32 *pIndices; - mz_uint32 start, end; - const mz_uint32 size = pZip->m_total_files; - - if (size <= 1U) - return; - - pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, - mz_uint32, 0); - - start = (size - 2U) >> 1U; - for (;;) { - mz_uint64 child, root = start; - for (;;) { - if ((child = (root << 1U) + 1U) >= size) - break; - child += (((child + 1U) < size) && - (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, - pIndices[child], - pIndices[child + 1U]))); - if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, - pIndices[root], pIndices[child])) - break; - MZ_SWAP_UINT32(pIndices[root], pIndices[child]); - root = child; - } - if (!start) - break; - start--; - } - - end = size - 1; - while (end > 0) { - mz_uint64 child, root = 0; - MZ_SWAP_UINT32(pIndices[end], pIndices[0]); - for (;;) { - if ((child = (root << 1U) + 1U) >= end) - break; - child += - (((child + 1U) < end) && - mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, - pIndices[child], pIndices[child + 1U])); - if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, - pIndices[root], pIndices[child])) - break; - MZ_SWAP_UINT32(pIndices[root], pIndices[child]); - root = child; - } - end--; - } -} - -static mz_bool mz_zip_reader_locate_header_sig(mz_zip_archive *pZip, - mz_uint32 record_sig, - mz_uint32 record_size, - mz_int64 *pOfs) { - mz_int64 cur_file_ofs; - mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; - mz_uint8 *pBuf = (mz_uint8 *)buf_u32; - - /* Basic sanity checks - reject files which are too small */ - if (pZip->m_archive_size < record_size) - return MZ_FALSE; - - /* Find the record by scanning the file from the end towards the beginning. */ - cur_file_ofs = - MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0); - for (;;) { - int i, - n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs); - - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n) - return MZ_FALSE; - - for (i = n - 4; i >= 0; --i) { - mz_uint s = MZ_READ_LE32(pBuf + i); - if (s == record_sig) { - if ((pZip->m_archive_size - (cur_file_ofs + i)) >= record_size) - break; - } - } - - if (i >= 0) { - cur_file_ofs += i; - break; - } - - /* Give up if we've searched the entire file, or we've gone back "too far" - * (~64kb) */ - if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= - (MZ_UINT16_MAX + record_size))) - return MZ_FALSE; - - cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0); - } - - *pOfs = cur_file_ofs; - return MZ_TRUE; -} - -static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, - mz_uint flags) { - mz_uint cdir_size = 0, cdir_entries_on_this_disk = 0, num_this_disk = 0, - cdir_disk_index = 0; - mz_uint64 cdir_ofs = 0; - mz_int64 cur_file_ofs = 0; - const mz_uint8 *p; - - mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; - mz_uint8 *pBuf = (mz_uint8 *)buf_u32; - mz_bool sort_central_dir = - ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0); - mz_uint32 zip64_end_of_central_dir_locator_u32 - [(MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE + sizeof(mz_uint32) - 1) / - sizeof(mz_uint32)]; - mz_uint8 *pZip64_locator = (mz_uint8 *)zip64_end_of_central_dir_locator_u32; - - mz_uint32 zip64_end_of_central_dir_header_u32 - [(MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / - sizeof(mz_uint32)]; - mz_uint8 *pZip64_end_of_central_dir = - (mz_uint8 *)zip64_end_of_central_dir_header_u32; - - mz_uint64 zip64_end_of_central_dir_ofs = 0; - - /* Basic sanity checks - reject files which are too small, and check the first - * 4 bytes of the file to make sure a local header is there. */ - if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); - - if (!mz_zip_reader_locate_header_sig( - pZip, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG, - MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE, &cur_file_ofs)) - return mz_zip_set_error(pZip, MZ_ZIP_FAILED_FINDING_CENTRAL_DIR); - - /* Read and verify the end of central directory record. */ - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, - MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != - MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - - if (MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != - MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) - return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); - - if (cur_file_ofs >= (MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE + - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)) { - if (pZip->m_pRead(pZip->m_pIO_opaque, - cur_file_ofs - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE, - pZip64_locator, - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) == - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) { - if (MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_SIG_OFS) == - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG) { - zip64_end_of_central_dir_ofs = MZ_READ_LE64( - pZip64_locator + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS); - if (zip64_end_of_central_dir_ofs > - (pZip->m_archive_size - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)) - return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); - - if (pZip->m_pRead(pZip->m_pIO_opaque, zip64_end_of_central_dir_ofs, - pZip64_end_of_central_dir, - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) == - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) { - if (MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIG_OFS) == - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG) { - pZip->m_pState->m_zip64 = MZ_TRUE; - } - } - } - } - } - - pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS); - cdir_entries_on_this_disk = - MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS); - num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS); - cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS); - cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS); - cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS); - - if (pZip->m_pState->m_zip64) { - mz_uint32 zip64_total_num_of_disks = - MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS); - mz_uint64 zip64_cdir_total_entries = MZ_READ_LE64( - pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS); - mz_uint64 zip64_cdir_total_entries_on_this_disk = MZ_READ_LE64( - pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS); - mz_uint64 zip64_size_of_end_of_central_dir_record = MZ_READ_LE64( - pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS); - mz_uint64 zip64_size_of_central_directory = - MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_SIZE_OFS); - - if (zip64_size_of_end_of_central_dir_record < - (MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - 12)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - if (zip64_total_num_of_disks != 1U) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK); - - /* Check for miniz's practical limits */ - if (zip64_cdir_total_entries > MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - - pZip->m_total_files = (mz_uint32)zip64_cdir_total_entries; - - if (zip64_cdir_total_entries_on_this_disk > MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - - cdir_entries_on_this_disk = - (mz_uint32)zip64_cdir_total_entries_on_this_disk; - - /* Check for miniz's current practical limits (sorry, this should be enough - * for millions of files) */ - if (zip64_size_of_central_directory > MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); - - cdir_size = (mz_uint32)zip64_size_of_central_directory; - - num_this_disk = MZ_READ_LE32(pZip64_end_of_central_dir + - MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS); - - cdir_disk_index = MZ_READ_LE32(pZip64_end_of_central_dir + - MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS); - - cdir_ofs = - MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_OFS_OFS); - } - - if (pZip->m_total_files != cdir_entries_on_this_disk) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK); - - if (((num_this_disk | cdir_disk_index) != 0) && - ((num_this_disk != 1) || (cdir_disk_index != 1))) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK); - - if (cdir_size < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - pZip->m_central_directory_file_ofs = cdir_ofs; - - if (pZip->m_total_files) { - mz_uint i, n; - /* Read the entire central directory into a heap block, and allocate another - * heap block to hold the unsorted central dir file record offsets, and - * possibly another to hold the sorted indices. */ - if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, - MZ_FALSE)) || - (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets, - pZip->m_total_files, MZ_FALSE))) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - if (sort_central_dir) { - if (!mz_zip_array_resize(pZip, - &pZip->m_pState->m_sorted_central_dir_offsets, - pZip->m_total_files, MZ_FALSE)) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, - pZip->m_pState->m_central_dir.m_p, - cdir_size) != cdir_size) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - - /* Now create an index into the central directory file records, do some - * basic sanity checking on each record */ - p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p; - for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i) { - mz_uint total_header_size, disk_index, bit_flags, filename_size, - ext_data_size; - mz_uint64 comp_size, decomp_size, local_header_ofs; - - if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) || - (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, - i) = - (mz_uint32)(p - (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p); - - if (sort_central_dir) - MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets, - mz_uint32, i) = i; - - comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); - decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); - local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS); - filename_size = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); - ext_data_size = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS); - - if ((!pZip->m_pState->m_zip64_has_extended_info_fields) && - (ext_data_size) && - (MZ_MAX(MZ_MAX(comp_size, decomp_size), local_header_ofs) == - MZ_UINT32_MAX)) { - /* Attempt to find zip64 extended information field in the entry's extra - * data */ - mz_uint32 extra_size_remaining = ext_data_size; - - if (extra_size_remaining) { - const mz_uint8 *pExtra_data; - void *buf = NULL; - - if (MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + ext_data_size > - n) { - buf = MZ_MALLOC(ext_data_size); - if (buf == NULL) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - if (pZip->m_pRead(pZip->m_pIO_opaque, - cdir_ofs + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + - filename_size, - buf, ext_data_size) != ext_data_size) { - MZ_FREE(buf); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - } - - pExtra_data = (mz_uint8 *)buf; - } else { - pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size; - } - - do { - mz_uint32 field_id; - mz_uint32 field_data_size; - - if (extra_size_remaining < (sizeof(mz_uint16) * 2)) { - MZ_FREE(buf); - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - } - - field_id = MZ_READ_LE16(pExtra_data); - field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); - - if ((field_data_size + sizeof(mz_uint16) * 2) > - extra_size_remaining) { - MZ_FREE(buf); - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - } - - if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) { - /* Ok, the archive didn't have any zip64 headers but it uses a - * zip64 extended information field so mark it as zip64 anyway - * (this can occur with infozip's zip util when it reads - * compresses files from stdin). */ - pZip->m_pState->m_zip64 = MZ_TRUE; - pZip->m_pState->m_zip64_has_extended_info_fields = MZ_TRUE; - break; - } - - pExtra_data += sizeof(mz_uint16) * 2 + field_data_size; - extra_size_remaining = - extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size; - } while (extra_size_remaining); - - MZ_FREE(buf); - } - } - - /* I've seen archives that aren't marked as zip64 that uses zip64 ext - * data, argh */ - if ((comp_size != MZ_UINT32_MAX) && (decomp_size != MZ_UINT32_MAX)) { - if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && - (decomp_size != comp_size)) || - (decomp_size && !comp_size)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - } - - disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS); - if ((disk_index == MZ_UINT16_MAX) || - ((disk_index != num_this_disk) && (disk_index != 1))) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK); - - if (comp_size != MZ_UINT32_MAX) { - if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) + - MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - } - - bit_flags = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); - if (bit_flags & MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); - - if ((total_header_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + - MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + - MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS) + - MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS)) > - n) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - n -= total_header_size; - p += total_header_size; - } - } - - if (sort_central_dir) - mz_zip_reader_sort_central_dir_offsets_by_filename(pZip); - - return MZ_TRUE; -} - -void mz_zip_zero_struct(mz_zip_archive *pZip) { - if (pZip) - MZ_CLEAR_OBJ(*pZip); -} - -static mz_bool mz_zip_reader_end_internal(mz_zip_archive *pZip, - mz_bool set_last_error) { - mz_bool status = MZ_TRUE; - - if (!pZip) - return MZ_FALSE; - - if ((!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || - (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) { - if (set_last_error) - pZip->m_last_error = MZ_ZIP_INVALID_PARAMETER; - - return MZ_FALSE; - } - - if (pZip->m_pState) { - mz_zip_internal_state *pState = pZip->m_pState; - pZip->m_pState = NULL; - - mz_zip_array_clear(pZip, &pState->m_central_dir); - mz_zip_array_clear(pZip, &pState->m_central_dir_offsets); - mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets); - -#ifndef MINIZ_NO_STDIO - if (pState->m_pFile) { - if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE) { - if (MZ_FCLOSE(pState->m_pFile) == EOF) { - if (set_last_error) - pZip->m_last_error = MZ_ZIP_FILE_CLOSE_FAILED; - status = MZ_FALSE; - } - } - pState->m_pFile = NULL; - } -#endif /* #ifndef MINIZ_NO_STDIO */ - - pZip->m_pFree(pZip->m_pAlloc_opaque, pState); - } - pZip->m_zip_mode = MZ_ZIP_MODE_INVALID; - - return status; -} - -mz_bool mz_zip_reader_end(mz_zip_archive *pZip) { - return mz_zip_reader_end_internal(pZip, MZ_TRUE); -} -mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, - mz_uint flags) { - if ((!pZip) || (!pZip->m_pRead)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (!mz_zip_reader_init_internal(pZip, flags)) - return MZ_FALSE; - - pZip->m_zip_type = MZ_ZIP_TYPE_USER; - pZip->m_archive_size = size; - - if (!mz_zip_reader_read_central_dir(pZip, flags)) { - mz_zip_reader_end_internal(pZip, MZ_FALSE); - return MZ_FALSE; - } - - return MZ_TRUE; -} - -static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, - void *pBuf, size_t n) { - mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; - size_t s = (file_ofs >= pZip->m_archive_size) - ? 0 - : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n); - memcpy(pBuf, (const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s); - return s; -} - -mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, - size_t size, mz_uint flags) { - if (!pMem) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); - - if (!mz_zip_reader_init_internal(pZip, flags)) - return MZ_FALSE; - - pZip->m_zip_type = MZ_ZIP_TYPE_MEMORY; - pZip->m_archive_size = size; - pZip->m_pRead = mz_zip_mem_read_func; - pZip->m_pIO_opaque = pZip; - pZip->m_pNeeds_keepalive = NULL; - -#ifdef __cplusplus - pZip->m_pState->m_pMem = const_cast(pMem); -#else - pZip->m_pState->m_pMem = (void *)pMem; -#endif - - pZip->m_pState->m_mem_size = size; - - if (!mz_zip_reader_read_central_dir(pZip, flags)) { - mz_zip_reader_end_internal(pZip, MZ_FALSE); - return MZ_FALSE; - } - - return MZ_TRUE; -} - -#ifndef MINIZ_NO_STDIO -static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, - void *pBuf, size_t n) { - mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; - mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile); - - file_ofs += pZip->m_pState->m_file_archive_start_ofs; - - if (((mz_int64)file_ofs < 0) || - (((cur_ofs != (mz_int64)file_ofs)) && - (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET)))) - return 0; - - return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile); -} - -mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, - mz_uint32 flags) { - return mz_zip_reader_init_file_v2(pZip, pFilename, flags, 0, 0); -} - -mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, - mz_uint flags, mz_uint64 file_start_ofs, - mz_uint64 archive_size) { - mz_uint64 file_size; - MZ_FILE *pFile; - - if ((!pZip) || (!pFilename) || - ((archive_size) && - (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE))) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - pFile = MZ_FOPEN(pFilename, "rb"); - if (!pFile) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); - - file_size = archive_size; - if (!file_size) { - if (MZ_FSEEK64(pFile, 0, SEEK_END)) { - MZ_FCLOSE(pFile); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED); - } - - file_size = MZ_FTELL64(pFile); - } - - /* TODO: Better sanity check archive_size and the # of actual remaining bytes - */ - - if (file_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) { - MZ_FCLOSE(pFile); - return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); - } - - if (!mz_zip_reader_init_internal(pZip, flags)) { - MZ_FCLOSE(pFile); - return MZ_FALSE; - } - - pZip->m_zip_type = MZ_ZIP_TYPE_FILE; - pZip->m_pRead = mz_zip_file_read_func; - pZip->m_pIO_opaque = pZip; - pZip->m_pState->m_pFile = pFile; - pZip->m_archive_size = file_size; - pZip->m_pState->m_file_archive_start_ofs = file_start_ofs; - - if (!mz_zip_reader_read_central_dir(pZip, flags)) { - mz_zip_reader_end_internal(pZip, MZ_FALSE); - return MZ_FALSE; - } - - return MZ_TRUE; -} - -mz_bool mz_zip_reader_init_file_v2_rpb(mz_zip_archive *pZip, - const char *pFilename, mz_uint flags, - mz_uint64 file_start_ofs, - mz_uint64 archive_size) { - mz_uint64 file_size; - MZ_FILE *pFile; - - if ((!pZip) || (!pFilename) || - ((archive_size) && - (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE))) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - pFile = MZ_FOPEN(pFilename, "r+b"); - if (!pFile) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); - - file_size = archive_size; - if (!file_size) { - if (MZ_FSEEK64(pFile, 0, SEEK_END)) { - MZ_FCLOSE(pFile); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED); - } - - file_size = MZ_FTELL64(pFile); - } - - /* TODO: Better sanity check archive_size and the # of actual remaining bytes - */ - - if (file_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) { - MZ_FCLOSE(pFile); - return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); - } - - if (!mz_zip_reader_init_internal(pZip, flags)) { - MZ_FCLOSE(pFile); - return MZ_FALSE; - } - - pZip->m_zip_type = MZ_ZIP_TYPE_FILE; - pZip->m_pRead = mz_zip_file_read_func; - pZip->m_pIO_opaque = pZip; - pZip->m_pState->m_pFile = pFile; - pZip->m_archive_size = file_size; - pZip->m_pState->m_file_archive_start_ofs = file_start_ofs; - - if (!mz_zip_reader_read_central_dir(pZip, flags)) { - mz_zip_reader_end_internal(pZip, MZ_FALSE); - return MZ_FALSE; - } - - return MZ_TRUE; -} - -mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, - mz_uint64 archive_size, mz_uint flags) { - mz_uint64 cur_file_ofs; - - if ((!pZip) || (!pFile)) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); - - cur_file_ofs = MZ_FTELL64(pFile); - - if (!archive_size) { - if (MZ_FSEEK64(pFile, 0, SEEK_END)) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED); - - archive_size = MZ_FTELL64(pFile) - cur_file_ofs; - - if (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); - } - - if (!mz_zip_reader_init_internal(pZip, flags)) - return MZ_FALSE; - - pZip->m_zip_type = MZ_ZIP_TYPE_CFILE; - pZip->m_pRead = mz_zip_file_read_func; - - pZip->m_pIO_opaque = pZip; - pZip->m_pState->m_pFile = pFile; - pZip->m_archive_size = archive_size; - pZip->m_pState->m_file_archive_start_ofs = cur_file_ofs; - - if (!mz_zip_reader_read_central_dir(pZip, flags)) { - mz_zip_reader_end_internal(pZip, MZ_FALSE); - return MZ_FALSE; - } - - return MZ_TRUE; -} - -#endif /* #ifndef MINIZ_NO_STDIO */ - -static MZ_FORCEINLINE const mz_uint8 *mz_zip_get_cdh(mz_zip_archive *pZip, - mz_uint file_index) { - if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files)) - return NULL; - return &MZ_ZIP_ARRAY_ELEMENT( - &pZip->m_pState->m_central_dir, mz_uint8, - MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, - file_index)); -} - -mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, - mz_uint file_index) { - mz_uint m_bit_flag; - const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index); - if (!p) { - mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - return MZ_FALSE; - } - - m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); - return (m_bit_flag & - (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION)) != 0; -} - -mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, - mz_uint file_index) { - mz_uint bit_flag; - mz_uint method; - - const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index); - if (!p) { - mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - return MZ_FALSE; - } - - method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS); - bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); - - if ((method != 0) && (method != MZ_DEFLATED)) { - mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD); - return MZ_FALSE; - } - - if (bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION)) { - mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); - return MZ_FALSE; - } - - if (bit_flag & MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG) { - mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE); - return MZ_FALSE; - } - - return MZ_TRUE; -} - -mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, - mz_uint file_index) { - mz_uint filename_len, attribute_mapping_id, external_attr; - const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index); - if (!p) { - mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - return MZ_FALSE; - } - - filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); - if (filename_len) { - if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) == '/') - return MZ_TRUE; - } - - /* Bugfix: This code was also checking if the internal attribute was non-zero, - * which wasn't correct. */ - /* Most/all zip writers (hopefully) set DOS file/directory attributes in the - * low 16-bits, so check for the DOS directory flag and ignore the source OS - * ID in the created by field. */ - /* FIXME: Remove this check? Is it necessary - we already check the filename. - */ - attribute_mapping_id = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS) >> 8; - (void)attribute_mapping_id; - - external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS); - if ((external_attr & MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG) != 0) { - return MZ_TRUE; - } - - return MZ_FALSE; -} - -static mz_bool mz_zip_file_stat_internal(mz_zip_archive *pZip, - mz_uint file_index, - const mz_uint8 *pCentral_dir_header, - mz_zip_archive_file_stat *pStat, - mz_bool *pFound_zip64_extra_data) { - mz_uint n; - const mz_uint8 *p = pCentral_dir_header; - - if (pFound_zip64_extra_data) - *pFound_zip64_extra_data = MZ_FALSE; - - if ((!p) || (!pStat)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - /* Extract fields from the central directory record. */ - pStat->m_file_index = file_index; - pStat->m_central_dir_ofs = MZ_ZIP_ARRAY_ELEMENT( - &pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index); - pStat->m_version_made_by = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS); - pStat->m_version_needed = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_NEEDED_OFS); - pStat->m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); - pStat->m_method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS); -#ifndef MINIZ_NO_TIME - pStat->m_time = - mz_zip_dos_to_time_t(MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_TIME_OFS), - MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_DATE_OFS)); -#endif - pStat->m_crc32 = MZ_READ_LE32(p + MZ_ZIP_CDH_CRC32_OFS); - pStat->m_comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); - pStat->m_uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); - pStat->m_internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS); - pStat->m_external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS); - pStat->m_local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS); - - /* Copy as much of the filename and comment as possible. */ - n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); - n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1); - memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); - pStat->m_filename[n] = '\0'; - - n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS); - n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1); - pStat->m_comment_size = n; - memcpy(pStat->m_comment, - p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + - MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + - MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS), - n); - pStat->m_comment[n] = '\0'; - - /* Set some flags for convienance */ - pStat->m_is_directory = mz_zip_reader_is_file_a_directory(pZip, file_index); - pStat->m_is_encrypted = mz_zip_reader_is_file_encrypted(pZip, file_index); - pStat->m_is_supported = mz_zip_reader_is_file_supported(pZip, file_index); - - /* See if we need to read any zip64 extended information fields. */ - /* Confusingly, these zip64 fields can be present even on non-zip64 archives - * (Debian zip on a huge files from stdin piped to stdout creates them). */ - if (MZ_MAX(MZ_MAX(pStat->m_comp_size, pStat->m_uncomp_size), - pStat->m_local_header_ofs) == MZ_UINT32_MAX) { - /* Attempt to find zip64 extended information field in the entry's extra - * data */ - mz_uint32 extra_size_remaining = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS); - - if (extra_size_remaining) { - const mz_uint8 *pExtra_data = - p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + - MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); - - do { - mz_uint32 field_id; - mz_uint32 field_data_size; - - if (extra_size_remaining < (sizeof(mz_uint16) * 2)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - field_id = MZ_READ_LE16(pExtra_data); - field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); - - if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) { - const mz_uint8 *pField_data = pExtra_data + sizeof(mz_uint16) * 2; - mz_uint32 field_data_remaining = field_data_size; - - if (pFound_zip64_extra_data) - *pFound_zip64_extra_data = MZ_TRUE; - - if (pStat->m_uncomp_size == MZ_UINT32_MAX) { - if (field_data_remaining < sizeof(mz_uint64)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - pStat->m_uncomp_size = MZ_READ_LE64(pField_data); - pField_data += sizeof(mz_uint64); - field_data_remaining -= sizeof(mz_uint64); - } - - if (pStat->m_comp_size == MZ_UINT32_MAX) { - if (field_data_remaining < sizeof(mz_uint64)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - pStat->m_comp_size = MZ_READ_LE64(pField_data); - pField_data += sizeof(mz_uint64); - field_data_remaining -= sizeof(mz_uint64); - } - - if (pStat->m_local_header_ofs == MZ_UINT32_MAX) { - if (field_data_remaining < sizeof(mz_uint64)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - pStat->m_local_header_ofs = MZ_READ_LE64(pField_data); - pField_data += sizeof(mz_uint64); - (void)pField_data; // unused - - field_data_remaining -= sizeof(mz_uint64); - (void)field_data_remaining; // unused - } - - break; - } - - pExtra_data += sizeof(mz_uint16) * 2 + field_data_size; - extra_size_remaining = - extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size; - } while (extra_size_remaining); - } - } - - return MZ_TRUE; -} - -static MZ_FORCEINLINE mz_bool mz_zip_string_equal(const char *pA, - const char *pB, mz_uint len, - mz_uint flags) { - mz_uint i; - if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE) - return 0 == memcmp(pA, pB, len); - for (i = 0; i < len; ++i) - if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i])) - return MZ_FALSE; - return MZ_TRUE; -} - -static MZ_FORCEINLINE int -mz_zip_filename_compare(const mz_zip_array *pCentral_dir_array, - const mz_zip_array *pCentral_dir_offsets, - mz_uint l_index, const char *pR, mz_uint r_len) { - const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT( - pCentral_dir_array, mz_uint8, - MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, - l_index)), - *pE; - mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS); - mz_uint8 l = 0, r = 0; - pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; - pE = pL + MZ_MIN(l_len, r_len); - while (pL < pE) { - if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR))) - break; - pL++; - pR++; - } - return (pL == pE) ? (int)(l_len - r_len) : (l - r); -} - -static mz_bool mz_zip_locate_file_binary_search(mz_zip_archive *pZip, - const char *pFilename, - mz_uint32 *pIndex) { - mz_zip_internal_state *pState = pZip->m_pState; - const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets; - const mz_zip_array *pCentral_dir = &pState->m_central_dir; - mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT( - &pState->m_sorted_central_dir_offsets, mz_uint32, 0); - const uint32_t size = pZip->m_total_files; - const mz_uint filename_len = (mz_uint)strlen(pFilename); - - if (pIndex) - *pIndex = 0; - - if (size) { - /* yes I could use uint32_t's, but then we would have to add some special - * case checks in the loop, argh, and */ - /* honestly the major expense here on 32-bit CPU's will still be the - * filename compare */ - mz_int64 l = 0, h = (mz_int64)size - 1; - - while (l <= h) { - mz_int64 m = l + ((h - l) >> 1); - uint32_t file_index = pIndices[(uint32_t)m]; - - int comp = mz_zip_filename_compare(pCentral_dir, pCentral_dir_offsets, - file_index, pFilename, filename_len); - if (!comp) { - if (pIndex) - *pIndex = file_index; - return MZ_TRUE; - } else if (comp < 0) - l = m + 1; - else - h = m - 1; - } - } - - return mz_zip_set_error(pZip, MZ_ZIP_FILE_NOT_FOUND); -} - -int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, - const char *pComment, mz_uint flags) { - mz_uint32 index; - if (!mz_zip_reader_locate_file_v2(pZip, pName, pComment, flags, &index)) - return -1; - else - return (int)index; -} - -mz_bool mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, - const char *pComment, mz_uint flags, - mz_uint32 *pIndex) { - mz_uint file_index; - size_t name_len, comment_len; - - if (pIndex) - *pIndex = 0; - - if ((!pZip) || (!pZip->m_pState) || (!pName)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - /* See if we can use a binary search */ - if (((pZip->m_pState->m_init_flags & - MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0) && - (pZip->m_zip_mode == MZ_ZIP_MODE_READING) && - ((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && - (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_size)) { - return mz_zip_locate_file_binary_search(pZip, pName, pIndex); - } - - /* Locate the entry by scanning the entire central directory */ - name_len = strlen(pName); - if (name_len > MZ_UINT16_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - comment_len = pComment ? strlen(pComment) : 0; - if (comment_len > MZ_UINT16_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - for (file_index = 0; file_index < pZip->m_total_files; file_index++) { - const mz_uint8 *pHeader = &MZ_ZIP_ARRAY_ELEMENT( - &pZip->m_pState->m_central_dir, mz_uint8, - MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, - file_index)); - mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS); - const char *pFilename = - (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; - if (filename_len < name_len) - continue; - if (comment_len) { - mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS), - file_comment_len = - MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS); - const char *pFile_comment = pFilename + filename_len + file_extra_len; - if ((file_comment_len != comment_len) || - (!mz_zip_string_equal(pComment, pFile_comment, file_comment_len, - flags))) - continue; - } - if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len)) { - int ofs = filename_len - 1; - do { - if ((pFilename[ofs] == '/') || (pFilename[ofs] == '\\') || - (pFilename[ofs] == ':')) - break; - } while (--ofs >= 0); - ofs++; - pFilename += ofs; - filename_len -= ofs; - } - if ((filename_len == name_len) && - (mz_zip_string_equal(pName, pFilename, filename_len, flags))) { - if (pIndex) - *pIndex = file_index; - return MZ_TRUE; - } - } - - return mz_zip_set_error(pZip, MZ_ZIP_FILE_NOT_FOUND); -} - -static mz_bool mz_zip_reader_extract_to_mem_no_alloc1( - mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, - mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size, - const mz_zip_archive_file_stat *st) { - int status = TINFL_STATUS_DONE; - mz_uint64 needed_size, cur_file_ofs, comp_remaining, - out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail; - mz_zip_archive_file_stat file_stat; - void *pRead_buf; - mz_uint32 - local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / - sizeof(mz_uint32)]; - mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; - tinfl_decompressor inflator; - - if ((!pZip) || (!pZip->m_pState) || ((buf_size) && (!pBuf)) || - ((user_read_buf_size) && (!pUser_read_buf)) || (!pZip->m_pRead)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (st) { - file_stat = *st; - } else if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) - return MZ_FALSE; - - /* A directory or zero length file */ - if ((file_stat.m_is_directory) || (!file_stat.m_comp_size)) - return MZ_TRUE; - - /* Encryption and patch files are not supported. */ - if (file_stat.m_bit_flag & - (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION | - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG)) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); - - /* This function only supports decompressing stored and deflate. */ - if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && - (file_stat.m_method != MZ_DEFLATED)) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD); - - /* Ensure supplied output buffer is large enough. */ - needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size - : file_stat.m_uncomp_size; - if (buf_size < needed_size) - return mz_zip_set_error(pZip, MZ_ZIP_BUF_TOO_SMALL); - - /* Read and parse the local directory entry. */ - cur_file_ofs = file_stat.m_local_header_ofs; - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, - MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != - MZ_ZIP_LOCAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - - if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + - MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + - MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); - if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) { - /* The file is stored or the caller has requested the compressed data. */ - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, - (size_t)needed_size) != needed_size) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) == 0) { - if (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, - (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32) - return mz_zip_set_error(pZip, MZ_ZIP_CRC_CHECK_FAILED); - } -#endif - - return MZ_TRUE; - } - - /* Decompress the file either directly from memory or from a file input - * buffer. */ - tinfl_init(&inflator); - - if (pZip->m_pState->m_pMem) { - /* Read directly from the archive in memory. */ - pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs; - read_buf_size = read_buf_avail = file_stat.m_comp_size; - comp_remaining = 0; - } else if (pUser_read_buf) { - /* Use a user provided read buffer. */ - if (!user_read_buf_size) - return MZ_FALSE; - pRead_buf = (mz_uint8 *)pUser_read_buf; - read_buf_size = user_read_buf_size; - read_buf_avail = 0; - comp_remaining = file_stat.m_comp_size; - } else { - /* Temporarily allocate a read buffer. */ - read_buf_size = - MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE); - if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF)) - return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - - if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, - (size_t)read_buf_size))) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - read_buf_avail = 0; - comp_remaining = file_stat.m_comp_size; - } - - do { - /* The size_t cast here should be OK because we've verified that the output - * buffer is >= file_stat.m_uncomp_size above */ - size_t in_buf_size, - out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs); - if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) { - read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, - (size_t)read_buf_avail) != read_buf_avail) { - status = TINFL_STATUS_FAILED; - mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED); - break; - } - cur_file_ofs += read_buf_avail; - comp_remaining -= read_buf_avail; - read_buf_ofs = 0; - } - in_buf_size = (size_t)read_buf_avail; - status = tinfl_decompress( - &inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, - (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size, - TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | - (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0)); - read_buf_avail -= in_buf_size; - read_buf_ofs += in_buf_size; - out_buf_ofs += out_buf_size; - } while (status == TINFL_STATUS_NEEDS_MORE_INPUT); - - if (status == TINFL_STATUS_DONE) { - /* Make sure the entire file was decompressed, and check its CRC. */ - if (out_buf_ofs != file_stat.m_uncomp_size) { - mz_zip_set_error(pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE); - status = TINFL_STATUS_FAILED; - } -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - else if (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, - (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32) { - mz_zip_set_error(pZip, MZ_ZIP_CRC_CHECK_FAILED); - status = TINFL_STATUS_FAILED; - } -#endif - } - - if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf)) - pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); - - return status == TINFL_STATUS_DONE; -} - -mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, - mz_uint file_index, void *pBuf, - size_t buf_size, mz_uint flags, - void *pUser_read_buf, - size_t user_read_buf_size) { - return mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, - buf_size, flags, pUser_read_buf, - user_read_buf_size, NULL); -} - -mz_bool mz_zip_reader_extract_file_to_mem_no_alloc( - mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, - mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size) { - mz_uint32 file_index; - if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index)) - return MZ_FALSE; - return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, - flags, pUser_read_buf, - user_read_buf_size); -} - -mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, - void *pBuf, size_t buf_size, - mz_uint flags) { - return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, - flags, NULL, 0); -} - -mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, - const char *pFilename, void *pBuf, - size_t buf_size, mz_uint flags) { - return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf, - buf_size, flags, NULL, 0); -} - -void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, - size_t *pSize, mz_uint flags) { - mz_zip_archive_file_stat file_stat; - mz_uint64 alloc_size; - void *pBuf; - - if (pSize) - *pSize = 0; - - if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) - return NULL; - - alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size - : file_stat.m_uncomp_size; - if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF)) { - mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - return NULL; - } - - if (NULL == - (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size))) { - mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - return NULL; - } - - if (!mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, - (size_t)alloc_size, flags, NULL, - 0, &file_stat)) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); - return NULL; - } - - if (pSize) - *pSize = (size_t)alloc_size; - return pBuf; -} - -void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, - const char *pFilename, size_t *pSize, - mz_uint flags) { - mz_uint32 file_index; - if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, - &file_index)) { - if (pSize) - *pSize = 0; - return MZ_FALSE; - } - return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags); -} - -mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, - mz_uint file_index, - mz_file_write_func pCallback, - void *pOpaque, mz_uint flags) { - int status = TINFL_STATUS_DONE; -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - mz_uint file_crc32 = MZ_CRC32_INIT; -#endif - mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, - out_buf_ofs = 0, cur_file_ofs; - mz_zip_archive_file_stat file_stat; - void *pRead_buf = NULL; - void *pWrite_buf = NULL; - mz_uint32 - local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / - sizeof(mz_uint32)]; - mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; - - if ((!pZip) || (!pZip->m_pState) || (!pCallback) || (!pZip->m_pRead)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) - return MZ_FALSE; - - /* A directory or zero length file */ - if (file_stat.m_is_directory || (!file_stat.m_comp_size)) - return MZ_TRUE; - - /* Encryption and patch files are not supported. */ - if (file_stat.m_bit_flag & - (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION | - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG)) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); - - /* This function only supports decompressing stored and deflate. */ - if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && - (file_stat.m_method != MZ_DEFLATED)) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD); - - /* Read and do some minimal validation of the local directory entry (this - * doesn't crack the zip64 stuff, which we already have from the central dir) - */ - cur_file_ofs = file_stat.m_local_header_ofs; - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, - MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != - MZ_ZIP_LOCAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - - if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + - MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + - MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); - if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - /* Decompress the file either directly from memory or from a file input - * buffer. */ - if (pZip->m_pState->m_pMem) { - pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs; - read_buf_size = read_buf_avail = file_stat.m_comp_size; - comp_remaining = 0; - } else { - read_buf_size = - MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE); - if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, - (size_t)read_buf_size))) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - read_buf_avail = 0; - comp_remaining = file_stat.m_comp_size; - } - - if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) { - /* The file is stored or the caller has requested the compressed data. */ - if (pZip->m_pState->m_pMem) { - if (((sizeof(size_t) == sizeof(mz_uint32))) && - (file_stat.m_comp_size > MZ_UINT32_MAX)) - return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - - if (pCallback(pOpaque, out_buf_ofs, pRead_buf, - (size_t)file_stat.m_comp_size) != file_stat.m_comp_size) { - mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED); - status = TINFL_STATUS_FAILED; - } else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) { -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - file_crc32 = - (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, - (size_t)file_stat.m_comp_size); -#endif - } - - cur_file_ofs += file_stat.m_comp_size; - out_buf_ofs += file_stat.m_comp_size; - comp_remaining = 0; - } else { - while (comp_remaining) { - read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, - (size_t)read_buf_avail) != read_buf_avail) { - mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - status = TINFL_STATUS_FAILED; - break; - } - -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) { - file_crc32 = (mz_uint32)mz_crc32( - file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail); - } -#endif - - if (pCallback(pOpaque, out_buf_ofs, pRead_buf, - (size_t)read_buf_avail) != read_buf_avail) { - mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED); - status = TINFL_STATUS_FAILED; - break; - } - - cur_file_ofs += read_buf_avail; - out_buf_ofs += read_buf_avail; - comp_remaining -= read_buf_avail; - } - } - } else { - tinfl_decompressor inflator; - tinfl_init(&inflator); - - if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, - TINFL_LZ_DICT_SIZE))) { - mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - status = TINFL_STATUS_FAILED; - } else { - do { - mz_uint8 *pWrite_buf_cur = - (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); - size_t in_buf_size, - out_buf_size = - TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); - if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) { - read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, - (size_t)read_buf_avail) != read_buf_avail) { - mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - status = TINFL_STATUS_FAILED; - break; - } - cur_file_ofs += read_buf_avail; - comp_remaining -= read_buf_avail; - read_buf_ofs = 0; - } - - in_buf_size = (size_t)read_buf_avail; - status = tinfl_decompress( - &inflator, (const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, - (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size, - comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0); - read_buf_avail -= in_buf_size; - read_buf_ofs += in_buf_size; - - if (out_buf_size) { - if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) != - out_buf_size) { - mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED); - status = TINFL_STATUS_FAILED; - break; - } - -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - file_crc32 = - (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size); -#endif - if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size) { - mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED); - status = TINFL_STATUS_FAILED; - break; - } - } - } while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) || - (status == TINFL_STATUS_HAS_MORE_OUTPUT)); - } - } - - if ((status == TINFL_STATUS_DONE) && - (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))) { - /* Make sure the entire file was decompressed, and check its CRC. */ - if (out_buf_ofs != file_stat.m_uncomp_size) { - mz_zip_set_error(pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE); - status = TINFL_STATUS_FAILED; - } -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - else if (file_crc32 != file_stat.m_crc32) { - mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED); - status = TINFL_STATUS_FAILED; - } -#endif - } - - if (!pZip->m_pState->m_pMem) - pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); - - if (pWrite_buf) - pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf); - - return status == TINFL_STATUS_DONE; -} - -mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, - const char *pFilename, - mz_file_write_func pCallback, - void *pOpaque, mz_uint flags) { - mz_uint32 file_index; - if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index)) - return MZ_FALSE; - - return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque, - flags); -} - -mz_zip_reader_extract_iter_state * -mz_zip_reader_extract_iter_new(mz_zip_archive *pZip, mz_uint file_index, - mz_uint flags) { - mz_zip_reader_extract_iter_state *pState; - mz_uint32 - local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / - sizeof(mz_uint32)]; - mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; - - /* Argument sanity check */ - if ((!pZip) || (!pZip->m_pState)) - return NULL; - - /* Allocate an iterator status structure */ - pState = (mz_zip_reader_extract_iter_state *)pZip->m_pAlloc( - pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_reader_extract_iter_state)); - if (!pState) { - mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - return NULL; - } - - /* Fetch file details */ - if (!mz_zip_reader_file_stat(pZip, file_index, &pState->file_stat)) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pState); - return NULL; - } - - /* Encryption and patch files are not supported. */ - if (pState->file_stat.m_bit_flag & - (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION | - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG)) { - mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); - pZip->m_pFree(pZip->m_pAlloc_opaque, pState); - return NULL; - } - - /* This function only supports decompressing stored and deflate. */ - if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && - (pState->file_stat.m_method != 0) && - (pState->file_stat.m_method != MZ_DEFLATED)) { - mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD); - pZip->m_pFree(pZip->m_pAlloc_opaque, pState); - return NULL; - } - - /* Init state - save args */ - pState->pZip = pZip; - pState->flags = flags; - - /* Init state - reset variables to defaults */ - pState->status = TINFL_STATUS_DONE; -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - pState->file_crc32 = MZ_CRC32_INIT; -#endif - pState->read_buf_ofs = 0; - pState->out_buf_ofs = 0; - pState->pRead_buf = NULL; - pState->pWrite_buf = NULL; - pState->out_blk_remain = 0; - - /* Read and parse the local directory entry. */ - pState->cur_file_ofs = pState->file_stat.m_local_header_ofs; - if (pZip->m_pRead(pZip->m_pIO_opaque, pState->cur_file_ofs, pLocal_header, - MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != - MZ_ZIP_LOCAL_DIR_HEADER_SIZE) { - mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - pZip->m_pFree(pZip->m_pAlloc_opaque, pState); - return NULL; - } - - if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) { - mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - pZip->m_pFree(pZip->m_pAlloc_opaque, pState); - return NULL; - } - - pState->cur_file_ofs += - MZ_ZIP_LOCAL_DIR_HEADER_SIZE + - MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + - MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); - if ((pState->cur_file_ofs + pState->file_stat.m_comp_size) > - pZip->m_archive_size) { - mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - pZip->m_pFree(pZip->m_pAlloc_opaque, pState); - return NULL; - } - - /* Decompress the file either directly from memory or from a file input - * buffer. */ - if (pZip->m_pState->m_pMem) { - pState->pRead_buf = - (mz_uint8 *)pZip->m_pState->m_pMem + pState->cur_file_ofs; - pState->read_buf_size = pState->read_buf_avail = - pState->file_stat.m_comp_size; - pState->comp_remaining = pState->file_stat.m_comp_size; - } else { - if (!((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || - (!pState->file_stat.m_method))) { - /* Decompression required, therefore intermediate read buffer required */ - pState->read_buf_size = MZ_MIN(pState->file_stat.m_comp_size, - (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE); - if (NULL == - (pState->pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, - (size_t)pState->read_buf_size))) { - mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - pZip->m_pFree(pZip->m_pAlloc_opaque, pState); - return NULL; - } - } else { - /* Decompression not required - we will be reading directly into user - * buffer, no temp buf required */ - pState->read_buf_size = 0; - } - pState->read_buf_avail = 0; - pState->comp_remaining = pState->file_stat.m_comp_size; - } - - if (!((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || - (!pState->file_stat.m_method))) { - /* Decompression required, init decompressor */ - tinfl_init(&pState->inflator); - - /* Allocate write buffer */ - if (NULL == (pState->pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, - TINFL_LZ_DICT_SIZE))) { - mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - if (pState->pRead_buf) - pZip->m_pFree(pZip->m_pAlloc_opaque, pState->pRead_buf); - pZip->m_pFree(pZip->m_pAlloc_opaque, pState); - return NULL; - } - } - - return pState; -} - -mz_zip_reader_extract_iter_state * -mz_zip_reader_extract_file_iter_new(mz_zip_archive *pZip, const char *pFilename, - mz_uint flags) { - mz_uint32 file_index; - - /* Locate file index by name */ - if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index)) - return NULL; - - /* Construct iterator */ - return mz_zip_reader_extract_iter_new(pZip, file_index, flags); -} - -size_t mz_zip_reader_extract_iter_read(mz_zip_reader_extract_iter_state *pState, - void *pvBuf, size_t buf_size) { - size_t copied_to_caller = 0; - - /* Argument sanity check */ - if ((!pState) || (!pState->pZip) || (!pState->pZip->m_pState) || (!pvBuf)) - return 0; - - if ((pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || - (!pState->file_stat.m_method)) { - /* The file is stored or the caller has requested the compressed data, calc - * amount to return. */ - copied_to_caller = (size_t)MZ_MIN(buf_size, pState->comp_remaining); - - /* Zip is in memory....or requires reading from a file? */ - if (pState->pZip->m_pState->m_pMem) { - /* Copy data to caller's buffer */ - memcpy(pvBuf, pState->pRead_buf, copied_to_caller); - pState->pRead_buf = ((mz_uint8 *)pState->pRead_buf) + copied_to_caller; - } else { - /* Read directly into caller's buffer */ - if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque, - pState->cur_file_ofs, pvBuf, - copied_to_caller) != copied_to_caller) { - /* Failed to read all that was asked for, flag failure and alert user */ - mz_zip_set_error(pState->pZip, MZ_ZIP_FILE_READ_FAILED); - pState->status = TINFL_STATUS_FAILED; - copied_to_caller = 0; - } - } - -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - /* Compute CRC if not returning compressed data only */ - if (!(pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) - pState->file_crc32 = (mz_uint32)mz_crc32( - pState->file_crc32, (const mz_uint8 *)pvBuf, copied_to_caller); -#endif - - /* Advance offsets, dec counters */ - pState->cur_file_ofs += copied_to_caller; - pState->out_buf_ofs += copied_to_caller; - pState->comp_remaining -= copied_to_caller; - } else { - do { - /* Calc ptr to write buffer - given current output pos and block size */ - mz_uint8 *pWrite_buf_cur = - (mz_uint8 *)pState->pWrite_buf + - (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); - - /* Calc max output size - given current output pos and block size */ - size_t in_buf_size, - out_buf_size = TINFL_LZ_DICT_SIZE - - (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); - - if (!pState->out_blk_remain) { - /* Read more data from file if none available (and reading from file) */ - if ((!pState->read_buf_avail) && (!pState->pZip->m_pState->m_pMem)) { - /* Calc read size */ - pState->read_buf_avail = - MZ_MIN(pState->read_buf_size, pState->comp_remaining); - if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque, - pState->cur_file_ofs, pState->pRead_buf, - (size_t)pState->read_buf_avail) != - pState->read_buf_avail) { - mz_zip_set_error(pState->pZip, MZ_ZIP_FILE_READ_FAILED); - pState->status = TINFL_STATUS_FAILED; - break; - } - - /* Advance offsets, dec counters */ - pState->cur_file_ofs += pState->read_buf_avail; - pState->comp_remaining -= pState->read_buf_avail; - pState->read_buf_ofs = 0; - } - - /* Perform decompression */ - in_buf_size = (size_t)pState->read_buf_avail; - pState->status = tinfl_decompress( - &pState->inflator, - (const mz_uint8 *)pState->pRead_buf + pState->read_buf_ofs, - &in_buf_size, (mz_uint8 *)pState->pWrite_buf, pWrite_buf_cur, - &out_buf_size, - pState->comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0); - pState->read_buf_avail -= in_buf_size; - pState->read_buf_ofs += in_buf_size; - - /* Update current output block size remaining */ - pState->out_blk_remain = out_buf_size; - } - - if (pState->out_blk_remain) { - /* Calc amount to return. */ - size_t to_copy = - MZ_MIN((buf_size - copied_to_caller), pState->out_blk_remain); - - /* Copy data to caller's buffer */ - memcpy((uint8_t *)pvBuf + copied_to_caller, pWrite_buf_cur, to_copy); - -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - /* Perform CRC */ - pState->file_crc32 = - (mz_uint32)mz_crc32(pState->file_crc32, pWrite_buf_cur, to_copy); -#endif - - /* Decrement data consumed from block */ - pState->out_blk_remain -= to_copy; - - /* Inc output offset, while performing sanity check */ - if ((pState->out_buf_ofs += to_copy) > - pState->file_stat.m_uncomp_size) { - mz_zip_set_error(pState->pZip, MZ_ZIP_DECOMPRESSION_FAILED); - pState->status = TINFL_STATUS_FAILED; - break; - } - - /* Increment counter of data copied to caller */ - copied_to_caller += to_copy; - } - } while ((copied_to_caller < buf_size) && - ((pState->status == TINFL_STATUS_NEEDS_MORE_INPUT) || - (pState->status == TINFL_STATUS_HAS_MORE_OUTPUT))); - } - - /* Return how many bytes were copied into user buffer */ - return copied_to_caller; -} - -mz_bool -mz_zip_reader_extract_iter_free(mz_zip_reader_extract_iter_state *pState) { - int status; - - /* Argument sanity check */ - if ((!pState) || (!pState->pZip) || (!pState->pZip->m_pState)) - return MZ_FALSE; - - /* Was decompression completed and requested? */ - if ((pState->status == TINFL_STATUS_DONE) && - (!(pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA))) { - /* Make sure the entire file was decompressed, and check its CRC. */ - if (pState->out_buf_ofs != pState->file_stat.m_uncomp_size) { - mz_zip_set_error(pState->pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE); - pState->status = TINFL_STATUS_FAILED; - } -#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS - else if (pState->file_crc32 != pState->file_stat.m_crc32) { - mz_zip_set_error(pState->pZip, MZ_ZIP_DECOMPRESSION_FAILED); - pState->status = TINFL_STATUS_FAILED; - } -#endif - } - - /* Free buffers */ - if (!pState->pZip->m_pState->m_pMem) - pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState->pRead_buf); - if (pState->pWrite_buf) - pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState->pWrite_buf); - - /* Save status */ - status = pState->status; - - /* Free context */ - pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState); - - return status == TINFL_STATUS_DONE; -} - -#ifndef MINIZ_NO_STDIO -static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, - const void *pBuf, size_t n) { - (void)ofs; - - return MZ_FWRITE(pBuf, 1, n, (MZ_FILE *)pOpaque); -} - -mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, - const char *pDst_filename, - mz_uint flags) { - mz_bool status; - mz_zip_archive_file_stat file_stat; - MZ_FILE *pFile; - - if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) - return MZ_FALSE; - - if (file_stat.m_is_directory || (!file_stat.m_is_supported)) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE); - - pFile = MZ_FOPEN(pDst_filename, "wb"); - if (!pFile) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); - - status = mz_zip_reader_extract_to_callback( - pZip, file_index, mz_zip_file_write_callback, pFile, flags); - - if (MZ_FCLOSE(pFile) == EOF) { - if (status) - mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED); - - status = MZ_FALSE; - } - -#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO) - if (status) - mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time); -#endif - - return status; -} - -mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, - const char *pArchive_filename, - const char *pDst_filename, - mz_uint flags) { - mz_uint32 file_index; - if (!mz_zip_reader_locate_file_v2(pZip, pArchive_filename, NULL, flags, - &file_index)) - return MZ_FALSE; - - return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags); -} - -mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, - MZ_FILE *pFile, mz_uint flags) { - mz_zip_archive_file_stat file_stat; - - if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) - return MZ_FALSE; - - if (file_stat.m_is_directory || (!file_stat.m_is_supported)) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE); - - return mz_zip_reader_extract_to_callback( - pZip, file_index, mz_zip_file_write_callback, pFile, flags); -} - -mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, - const char *pArchive_filename, - MZ_FILE *pFile, mz_uint flags) { - mz_uint32 file_index; - if (!mz_zip_reader_locate_file_v2(pZip, pArchive_filename, NULL, flags, - &file_index)) - return MZ_FALSE; - - return mz_zip_reader_extract_to_cfile(pZip, file_index, pFile, flags); -} -#endif /* #ifndef MINIZ_NO_STDIO */ - -static size_t mz_zip_compute_crc32_callback(void *pOpaque, mz_uint64 file_ofs, - const void *pBuf, size_t n) { - mz_uint32 *p = (mz_uint32 *)pOpaque; - (void)file_ofs; - *p = (mz_uint32)mz_crc32(*p, (const mz_uint8 *)pBuf, n); - return n; -} - -mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, - mz_uint flags) { - mz_zip_archive_file_stat file_stat; - mz_zip_internal_state *pState; - const mz_uint8 *pCentral_dir_header; - mz_bool found_zip64_ext_data_in_cdir = MZ_FALSE; - mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE; - mz_uint32 - local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / - sizeof(mz_uint32)]; - mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; - mz_uint64 local_header_ofs = 0; - mz_uint32 local_header_filename_len, local_header_extra_len, - local_header_crc32; - mz_uint64 local_header_comp_size, local_header_uncomp_size; - mz_uint32 uncomp_crc32 = MZ_CRC32_INIT; - mz_bool has_data_descriptor; - mz_uint32 local_header_bit_flags; - - mz_zip_array file_data_array; - mz_zip_array_init(&file_data_array, 1); - - if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || - (!pZip->m_pRead)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (file_index > pZip->m_total_files) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - pState = pZip->m_pState; - - pCentral_dir_header = mz_zip_get_cdh(pZip, file_index); - - if (!mz_zip_file_stat_internal(pZip, file_index, pCentral_dir_header, - &file_stat, &found_zip64_ext_data_in_cdir)) - return MZ_FALSE; - - /* A directory or zero length file */ - if (file_stat.m_is_directory || (!file_stat.m_uncomp_size)) - return MZ_TRUE; - - /* Encryption and patch files are not supported. */ - if (file_stat.m_is_encrypted) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); - - /* This function only supports stored and deflate. */ - if ((file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED)) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD); - - if (!file_stat.m_is_supported) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE); - - /* Read and parse the local directory entry. */ - local_header_ofs = file_stat.m_local_header_ofs; - if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs, pLocal_header, - MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != - MZ_ZIP_LOCAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - - if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - local_header_filename_len = - MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS); - local_header_extra_len = - MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); - local_header_comp_size = - MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS); - local_header_uncomp_size = - MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS); - local_header_crc32 = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_CRC32_OFS); - local_header_bit_flags = - MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS); - has_data_descriptor = (local_header_bit_flags & 8) != 0; - - if (local_header_filename_len != strlen(file_stat.m_filename)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - if ((local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + - local_header_filename_len + local_header_extra_len + - file_stat.m_comp_size) > pZip->m_archive_size) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - if (!mz_zip_array_resize( - pZip, &file_data_array, - MZ_MAX(local_header_filename_len, local_header_extra_len), - MZ_FALSE)) { - mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - goto handle_failure; - } - - if (local_header_filename_len) { - if (pZip->m_pRead(pZip->m_pIO_opaque, - local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE, - file_data_array.m_p, - local_header_filename_len) != local_header_filename_len) { - mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - goto handle_failure; - } - - /* I've seen 1 archive that had the same pathname, but used backslashes in - * the local dir and forward slashes in the central dir. Do we care about - * this? For now, this case will fail validation. */ - if (memcmp(file_stat.m_filename, file_data_array.m_p, - local_header_filename_len) != 0) { - mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED); - goto handle_failure; - } - } - - if ((local_header_extra_len) && - ((local_header_comp_size == MZ_UINT32_MAX) || - (local_header_uncomp_size == MZ_UINT32_MAX))) { - mz_uint32 extra_size_remaining = local_header_extra_len; - const mz_uint8 *pExtra_data = (const mz_uint8 *)file_data_array.m_p; - - if (pZip->m_pRead(pZip->m_pIO_opaque, - local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + - local_header_filename_len, - file_data_array.m_p, - local_header_extra_len) != local_header_extra_len) { - mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - goto handle_failure; - } - - do { - mz_uint32 field_id, field_data_size, field_total_size; - - if (extra_size_remaining < (sizeof(mz_uint16) * 2)) { - mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - goto handle_failure; - } - - field_id = MZ_READ_LE16(pExtra_data); - field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); - field_total_size = field_data_size + sizeof(mz_uint16) * 2; - - if (field_total_size > extra_size_remaining) { - mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - goto handle_failure; - } - - if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) { - const mz_uint8 *pSrc_field_data = pExtra_data + sizeof(mz_uint32); - - if (field_data_size < sizeof(mz_uint64) * 2) { - mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - goto handle_failure; - } - - local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data); - local_header_comp_size = - MZ_READ_LE64(pSrc_field_data + sizeof(mz_uint64)); - - found_zip64_ext_data_in_ldir = MZ_TRUE; - break; - } - - pExtra_data += field_total_size; - extra_size_remaining -= field_total_size; - } while (extra_size_remaining); - } - - /* TODO: parse local header extra data when local_header_comp_size is - * 0xFFFFFFFF! (big_descriptor.zip) */ - /* I've seen zips in the wild with the data descriptor bit set, but proper - * local header values and bogus data descriptors */ - if ((has_data_descriptor) && (!local_header_comp_size) && - (!local_header_crc32)) { - mz_uint8 descriptor_buf[32]; - mz_bool has_id; - const mz_uint8 *pSrc; - mz_uint32 file_crc32; - mz_uint64 comp_size = 0, uncomp_size = 0; - - mz_uint32 num_descriptor_uint32s = - ((pState->m_zip64) || (found_zip64_ext_data_in_ldir)) ? 6 : 4; - - if (pZip->m_pRead(pZip->m_pIO_opaque, - local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + - local_header_filename_len + local_header_extra_len + - file_stat.m_comp_size, - descriptor_buf, - sizeof(mz_uint32) * num_descriptor_uint32s) != - (sizeof(mz_uint32) * num_descriptor_uint32s)) { - mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - goto handle_failure; - } - - has_id = (MZ_READ_LE32(descriptor_buf) == MZ_ZIP_DATA_DESCRIPTOR_ID); - pSrc = has_id ? (descriptor_buf + sizeof(mz_uint32)) : descriptor_buf; - - file_crc32 = MZ_READ_LE32(pSrc); - - if ((pState->m_zip64) || (found_zip64_ext_data_in_ldir)) { - comp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32)); - uncomp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32) + sizeof(mz_uint64)); - } else { - comp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32)); - uncomp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32) + sizeof(mz_uint32)); - } - - if ((file_crc32 != file_stat.m_crc32) || - (comp_size != file_stat.m_comp_size) || - (uncomp_size != file_stat.m_uncomp_size)) { - mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED); - goto handle_failure; - } - } else { - if ((local_header_crc32 != file_stat.m_crc32) || - (local_header_comp_size != file_stat.m_comp_size) || - (local_header_uncomp_size != file_stat.m_uncomp_size)) { - mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED); - goto handle_failure; - } - } - - mz_zip_array_clear(pZip, &file_data_array); - - if ((flags & MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY) == 0) { - if (!mz_zip_reader_extract_to_callback( - pZip, file_index, mz_zip_compute_crc32_callback, &uncomp_crc32, 0)) - return MZ_FALSE; - - /* 1 more check to be sure, although the extract checks too. */ - if (uncomp_crc32 != file_stat.m_crc32) { - mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED); - return MZ_FALSE; - } - } - - return MZ_TRUE; - -handle_failure: - mz_zip_array_clear(pZip, &file_data_array); - return MZ_FALSE; -} - -mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags) { - mz_zip_internal_state *pState; - uint32_t i; - - if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || - (!pZip->m_pRead)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - pState = pZip->m_pState; - - /* Basic sanity checks */ - if (!pState->m_zip64) { - if (pZip->m_total_files > MZ_UINT16_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - - if (pZip->m_archive_size > MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - } else { - if (pZip->m_total_files >= MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - - if (pState->m_central_dir.m_size >= MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - } - - for (i = 0; i < pZip->m_total_files; i++) { - if (MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG & flags) { - mz_uint32 found_index; - mz_zip_archive_file_stat stat; - - if (!mz_zip_reader_file_stat(pZip, i, &stat)) - return MZ_FALSE; - - if (!mz_zip_reader_locate_file_v2(pZip, stat.m_filename, NULL, 0, - &found_index)) - return MZ_FALSE; - - /* This check can fail if there are duplicate filenames in the archive - * (which we don't check for when writing - that's up to the user) */ - if (found_index != i) - return mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED); - } - - if (!mz_zip_validate_file(pZip, i, flags)) - return MZ_FALSE; - } - - return MZ_TRUE; -} - -mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, - mz_uint flags, mz_zip_error *pErr) { - mz_bool success = MZ_TRUE; - mz_zip_archive zip; - mz_zip_error actual_err = MZ_ZIP_NO_ERROR; - - if ((!pMem) || (!size)) { - if (pErr) - *pErr = MZ_ZIP_INVALID_PARAMETER; - return MZ_FALSE; - } - - mz_zip_zero_struct(&zip); - - if (!mz_zip_reader_init_mem(&zip, pMem, size, flags)) { - if (pErr) - *pErr = zip.m_last_error; - return MZ_FALSE; - } - - if (!mz_zip_validate_archive(&zip, flags)) { - actual_err = zip.m_last_error; - success = MZ_FALSE; - } - - if (!mz_zip_reader_end_internal(&zip, success)) { - if (!actual_err) - actual_err = zip.m_last_error; - success = MZ_FALSE; - } - - if (pErr) - *pErr = actual_err; - - return success; -} - -#ifndef MINIZ_NO_STDIO -mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, - mz_zip_error *pErr) { - mz_bool success = MZ_TRUE; - mz_zip_archive zip; - mz_zip_error actual_err = MZ_ZIP_NO_ERROR; - - if (!pFilename) { - if (pErr) - *pErr = MZ_ZIP_INVALID_PARAMETER; - return MZ_FALSE; - } - - mz_zip_zero_struct(&zip); - - if (!mz_zip_reader_init_file_v2(&zip, pFilename, flags, 0, 0)) { - if (pErr) - *pErr = zip.m_last_error; - return MZ_FALSE; - } - - if (!mz_zip_validate_archive(&zip, flags)) { - actual_err = zip.m_last_error; - success = MZ_FALSE; - } - - if (!mz_zip_reader_end_internal(&zip, success)) { - if (!actual_err) - actual_err = zip.m_last_error; - success = MZ_FALSE; - } - - if (pErr) - *pErr = actual_err; - - return success; -} -#endif /* #ifndef MINIZ_NO_STDIO */ - -/* ------------------- .ZIP archive writing */ - -#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS - -static MZ_FORCEINLINE void mz_write_le16(mz_uint8 *p, mz_uint16 v) { - p[0] = (mz_uint8)v; - p[1] = (mz_uint8)(v >> 8); -} -static MZ_FORCEINLINE void mz_write_le32(mz_uint8 *p, mz_uint32 v) { - p[0] = (mz_uint8)v; - p[1] = (mz_uint8)(v >> 8); - p[2] = (mz_uint8)(v >> 16); - p[3] = (mz_uint8)(v >> 24); -} -static MZ_FORCEINLINE void mz_write_le64(mz_uint8 *p, mz_uint64 v) { - mz_write_le32(p, (mz_uint32)v); - mz_write_le32(p + sizeof(mz_uint32), (mz_uint32)(v >> 32)); -} - -#define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v)) -#define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v)) -#define MZ_WRITE_LE64(p, v) mz_write_le64((mz_uint8 *)(p), (mz_uint64)(v)) - -static size_t mz_zip_heap_write_func(void *pOpaque, mz_uint64 file_ofs, - const void *pBuf, size_t n) { - mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; - mz_zip_internal_state *pState = pZip->m_pState; - mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size); - - if (!n) - return 0; - - /* An allocation this big is likely to just fail on 32-bit systems, so don't - * even go there. */ - if ((sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF)) { - mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE); - return 0; - } - - if (new_size > pState->m_mem_capacity) { - void *pNew_block; - size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity); - - while (new_capacity < new_size) - new_capacity *= 2; - - if (NULL == (pNew_block = pZip->m_pRealloc( - pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity))) { - mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - return 0; - } - - pState->m_pMem = pNew_block; - pState->m_mem_capacity = new_capacity; - } - memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n); - pState->m_mem_size = (size_t)new_size; - return n; -} - -static mz_bool mz_zip_writer_end_internal(mz_zip_archive *pZip, - mz_bool set_last_error) { - mz_zip_internal_state *pState; - mz_bool status = MZ_TRUE; - - if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || - ((pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) && - (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED))) { - if (set_last_error) - mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - return MZ_FALSE; - } - - pState = pZip->m_pState; - pZip->m_pState = NULL; - mz_zip_array_clear(pZip, &pState->m_central_dir); - mz_zip_array_clear(pZip, &pState->m_central_dir_offsets); - mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets); - -#ifndef MINIZ_NO_STDIO - if (pState->m_pFile) { - if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE) { - if (MZ_FCLOSE(pState->m_pFile) == EOF) { - if (set_last_error) - mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED); - status = MZ_FALSE; - } - } - - pState->m_pFile = NULL; - } -#endif /* #ifndef MINIZ_NO_STDIO */ - - if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem)) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem); - pState->m_pMem = NULL; - } - - pZip->m_pFree(pZip->m_pAlloc_opaque, pState); - pZip->m_zip_mode = MZ_ZIP_MODE_INVALID; - return status; -} - -mz_bool mz_zip_writer_init_v2(mz_zip_archive *pZip, mz_uint64 existing_size, - mz_uint flags) { - mz_bool zip64 = (flags & MZ_ZIP_FLAG_WRITE_ZIP64) != 0; - - if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) || - (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) { - if (!pZip->m_pRead) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - } - - if (pZip->m_file_offset_alignment) { - /* Ensure user specified file offset alignment is a power of 2. */ - if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - } - - if (!pZip->m_pAlloc) - pZip->m_pAlloc = miniz_def_alloc_func; - if (!pZip->m_pFree) - pZip->m_pFree = miniz_def_free_func; - if (!pZip->m_pRealloc) - pZip->m_pRealloc = miniz_def_realloc_func; - - pZip->m_archive_size = existing_size; - pZip->m_central_directory_file_ofs = 0; - pZip->m_total_files = 0; - - if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc( - pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state)))) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state)); - - MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, - sizeof(mz_uint8)); - MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, - sizeof(mz_uint32)); - MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, - sizeof(mz_uint32)); - - pZip->m_pState->m_zip64 = zip64; - pZip->m_pState->m_zip64_has_extended_info_fields = zip64; - - pZip->m_zip_type = MZ_ZIP_TYPE_USER; - pZip->m_zip_mode = MZ_ZIP_MODE_WRITING; - - return MZ_TRUE; -} - -mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size) { - return mz_zip_writer_init_v2(pZip, existing_size, 0); -} - -mz_bool mz_zip_writer_init_heap_v2(mz_zip_archive *pZip, - size_t size_to_reserve_at_beginning, - size_t initial_allocation_size, - mz_uint flags) { - pZip->m_pWrite = mz_zip_heap_write_func; - pZip->m_pNeeds_keepalive = NULL; - - if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) - pZip->m_pRead = mz_zip_mem_read_func; - - pZip->m_pIO_opaque = pZip; - - if (!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags)) - return MZ_FALSE; - - pZip->m_zip_type = MZ_ZIP_TYPE_HEAP; - - if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size, - size_to_reserve_at_beginning))) { - if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc( - pZip->m_pAlloc_opaque, 1, initial_allocation_size))) { - mz_zip_writer_end_internal(pZip, MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - pZip->m_pState->m_mem_capacity = initial_allocation_size; - } - - return MZ_TRUE; -} - -mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, - size_t size_to_reserve_at_beginning, - size_t initial_allocation_size) { - return mz_zip_writer_init_heap_v2(pZip, size_to_reserve_at_beginning, - initial_allocation_size, 0); -} - -#ifndef MINIZ_NO_STDIO -static size_t mz_zip_file_write_func(void *pOpaque, mz_uint64 file_ofs, - const void *pBuf, size_t n) { - mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; - mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile); - - file_ofs += pZip->m_pState->m_file_archive_start_ofs; - - if (((mz_int64)file_ofs < 0) || - (((cur_ofs != (mz_int64)file_ofs)) && - (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET)))) { - mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED); - return 0; - } - - return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile); -} - -mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, - mz_uint64 size_to_reserve_at_beginning) { - return mz_zip_writer_init_file_v2(pZip, pFilename, - size_to_reserve_at_beginning, 0); -} - -mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename, - mz_uint64 size_to_reserve_at_beginning, - mz_uint flags) { - MZ_FILE *pFile; - - pZip->m_pWrite = mz_zip_file_write_func; - pZip->m_pNeeds_keepalive = NULL; - - if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) - pZip->m_pRead = mz_zip_file_read_func; - - pZip->m_pIO_opaque = pZip; - - if (!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags)) - return MZ_FALSE; - - if (NULL == (pFile = MZ_FOPEN( - pFilename, - (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) ? "w+b" : "wb"))) { - mz_zip_writer_end(pZip); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); - } - - pZip->m_pState->m_pFile = pFile; - pZip->m_zip_type = MZ_ZIP_TYPE_FILE; - - if (size_to_reserve_at_beginning) { - mz_uint64 cur_ofs = 0; - char buf[4096]; - - MZ_CLEAR_OBJ(buf); - - do { - size_t n = (size_t)MZ_MIN(sizeof(buf), size_to_reserve_at_beginning); - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n) { - mz_zip_writer_end(pZip); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - cur_ofs += n; - size_to_reserve_at_beginning -= n; - } while (size_to_reserve_at_beginning); - } - - return MZ_TRUE; -} - -mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, - mz_uint flags) { - pZip->m_pWrite = mz_zip_file_write_func; - pZip->m_pNeeds_keepalive = NULL; - - if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) - pZip->m_pRead = mz_zip_file_read_func; - - pZip->m_pIO_opaque = pZip; - - if (!mz_zip_writer_init_v2(pZip, 0, flags)) - return MZ_FALSE; - - pZip->m_pState->m_pFile = pFile; - pZip->m_pState->m_file_archive_start_ofs = - MZ_FTELL64(pZip->m_pState->m_pFile); - pZip->m_zip_type = MZ_ZIP_TYPE_CFILE; - - return MZ_TRUE; -} -#endif /* #ifndef MINIZ_NO_STDIO */ - -mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, - const char *pFilename, - mz_uint flags) { - mz_zip_internal_state *pState; - - if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (flags & MZ_ZIP_FLAG_WRITE_ZIP64) { - /* We don't support converting a non-zip64 file to zip64 - this seems like - * more trouble than it's worth. (What about the existing 32-bit data - * descriptors that could follow the compressed data?) */ - if (!pZip->m_pState->m_zip64) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - } - - /* No sense in trying to write to an archive that's already at the support max - * size */ - if (pZip->m_pState->m_zip64) { - if (pZip->m_total_files == MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - } else { - if (pZip->m_total_files == MZ_UINT16_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - - if ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + - MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE); - } - - pState = pZip->m_pState; - - if (pState->m_pFile) { -#ifdef MINIZ_NO_STDIO - (void)pFilename; - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); -#else - if (pZip->m_pIO_opaque != pZip) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE) { - if (!pFilename) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - /* Archive is being read from stdio and was originally opened only for - * reading. Try to reopen as writable. */ - if (NULL == - (pState->m_pFile = MZ_FREOPEN(pFilename, "r+b", pState->m_pFile))) { - /* The mz_zip_archive is now in a bogus state because pState->m_pFile is - * NULL, so just close it. */ - mz_zip_reader_end_internal(pZip, MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); - } - } - - pZip->m_pWrite = mz_zip_file_write_func; - pZip->m_pNeeds_keepalive = NULL; -#endif /* #ifdef MINIZ_NO_STDIO */ - } else if (pState->m_pMem) { - /* Archive lives in a memory block. Assume it's from the heap that we can - * resize using the realloc callback. */ - if (pZip->m_pIO_opaque != pZip) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - pState->m_mem_capacity = pState->m_mem_size; - pZip->m_pWrite = mz_zip_heap_write_func; - pZip->m_pNeeds_keepalive = NULL; - } - /* Archive is being read via a user provided read function - make sure the - user has specified a write function too. */ - else if (!pZip->m_pWrite) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - /* Start writing new files at the archive's current central directory - * location. */ - /* TODO: We could add a flag that lets the user start writing immediately - * AFTER the existing central dir - this would be safer. */ - pZip->m_archive_size = pZip->m_central_directory_file_ofs; - pZip->m_central_directory_file_ofs = 0; - - /* Clear the sorted central dir offsets, they aren't useful or maintained now. - */ - /* Even though we're now in write mode, files can still be extracted and - * verified, but file locates will be slow. */ - /* TODO: We could easily maintain the sorted central directory offsets. */ - mz_zip_array_clear(pZip, &pZip->m_pState->m_sorted_central_dir_offsets); - - pZip->m_zip_mode = MZ_ZIP_MODE_WRITING; - - return MZ_TRUE; -} - -mz_bool mz_zip_writer_init_from_reader_v2_noreopen(mz_zip_archive *pZip, - const char *pFilename, - mz_uint flags) { - mz_zip_internal_state *pState; - - if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (flags & MZ_ZIP_FLAG_WRITE_ZIP64) { - /* We don't support converting a non-zip64 file to zip64 - this seems like - * more trouble than it's worth. (What about the existing 32-bit data - * descriptors that could follow the compressed data?) */ - if (!pZip->m_pState->m_zip64) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - } - - /* No sense in trying to write to an archive that's already at the support max - * size */ - if (pZip->m_pState->m_zip64) { - if (pZip->m_total_files == MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - } else { - if (pZip->m_total_files == MZ_UINT16_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - - if ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + - MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE); - } - - pState = pZip->m_pState; - - if (pState->m_pFile) { -#ifdef MINIZ_NO_STDIO - (void)pFilename; - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); -#else - if (pZip->m_pIO_opaque != pZip) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE) { - if (!pFilename) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - } - - pZip->m_pWrite = mz_zip_file_write_func; - pZip->m_pNeeds_keepalive = NULL; -#endif /* #ifdef MINIZ_NO_STDIO */ - } else if (pState->m_pMem) { - /* Archive lives in a memory block. Assume it's from the heap that we can - * resize using the realloc callback. */ - if (pZip->m_pIO_opaque != pZip) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - pState->m_mem_capacity = pState->m_mem_size; - pZip->m_pWrite = mz_zip_heap_write_func; - pZip->m_pNeeds_keepalive = NULL; - } - /* Archive is being read via a user provided read function - make sure the - user has specified a write function too. */ - else if (!pZip->m_pWrite) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - /* Start writing new files at the archive's current central directory - * location. */ - /* TODO: We could add a flag that lets the user start writing immediately - * AFTER the existing central dir - this would be safer. */ - pZip->m_archive_size = pZip->m_central_directory_file_ofs; - pZip->m_central_directory_file_ofs = 0; - - /* Clear the sorted central dir offsets, they aren't useful or maintained now. - */ - /* Even though we're now in write mode, files can still be extracted and - * verified, but file locates will be slow. */ - /* TODO: We could easily maintain the sorted central directory offsets. */ - mz_zip_array_clear(pZip, &pZip->m_pState->m_sorted_central_dir_offsets); - - pZip->m_zip_mode = MZ_ZIP_MODE_WRITING; - - return MZ_TRUE; -} - -mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, - const char *pFilename) { - return mz_zip_writer_init_from_reader_v2(pZip, pFilename, 0); -} - -/* TODO: pArchive_name is a terrible name here! */ -mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, - const void *pBuf, size_t buf_size, - mz_uint level_and_flags) { - return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, - level_and_flags, 0, 0); -} - -typedef struct { - mz_zip_archive *m_pZip; - mz_uint64 m_cur_archive_file_ofs; - mz_uint64 m_comp_size; -} mz_zip_writer_add_state; - -static mz_bool mz_zip_writer_add_put_buf_callback(const void *pBuf, int len, - void *pUser) { - mz_zip_writer_add_state *pState = (mz_zip_writer_add_state *)pUser; - if ((int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque, - pState->m_cur_archive_file_ofs, pBuf, - len) != len) - return MZ_FALSE; - - pState->m_cur_archive_file_ofs += len; - pState->m_comp_size += len; - return MZ_TRUE; -} - -#define MZ_ZIP64_MAX_LOCAL_EXTRA_FIELD_SIZE \ - (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 2) -#define MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE \ - (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 3) -static mz_uint32 -mz_zip_writer_create_zip64_extra_data(mz_uint8 *pBuf, mz_uint64 *pUncomp_size, - mz_uint64 *pComp_size, - mz_uint64 *pLocal_header_ofs) { - mz_uint8 *pDst = pBuf; - mz_uint32 field_size = 0; - - MZ_WRITE_LE16(pDst + 0, MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID); - MZ_WRITE_LE16(pDst + 2, 0); - pDst += sizeof(mz_uint16) * 2; - - if (pUncomp_size) { - MZ_WRITE_LE64(pDst, *pUncomp_size); - pDst += sizeof(mz_uint64); - field_size += sizeof(mz_uint64); - } - - if (pComp_size) { - MZ_WRITE_LE64(pDst, *pComp_size); - pDst += sizeof(mz_uint64); - field_size += sizeof(mz_uint64); - } - - if (pLocal_header_ofs) { - MZ_WRITE_LE64(pDst, *pLocal_header_ofs); - pDst += sizeof(mz_uint64); - field_size += sizeof(mz_uint64); - } - - MZ_WRITE_LE16(pBuf + 2, field_size); - - return (mz_uint32)(pDst - pBuf); -} - -static mz_bool mz_zip_writer_create_local_dir_header( - mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, - mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size, - mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, - mz_uint16 dos_time, mz_uint16 dos_date) { - (void)pZip; - memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE); - MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG); - MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0); - MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags); - MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method); - MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time); - MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date); - MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32); - MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, - MZ_MIN(comp_size, MZ_UINT32_MAX)); - MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, - MZ_MIN(uncomp_size, MZ_UINT32_MAX)); - MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size); - MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size); - return MZ_TRUE; -} - -static mz_bool mz_zip_writer_create_central_dir_header( - mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, - mz_uint16 extra_size, mz_uint16 comment_size, mz_uint64 uncomp_size, - mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, - mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, - mz_uint64 local_header_ofs, mz_uint32 ext_attributes) { - (void)pZip; - memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE); - MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG); - MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0); - MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags); - MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method); - MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time); - MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date); - MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32); - MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, - MZ_MIN(comp_size, MZ_UINT32_MAX)); - MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, - MZ_MIN(uncomp_size, MZ_UINT32_MAX)); - MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size); - MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size); - MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size); - MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes); - MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS, - MZ_MIN(local_header_ofs, MZ_UINT32_MAX)); - return MZ_TRUE; -} - -static mz_bool mz_zip_writer_add_to_central_dir( - mz_zip_archive *pZip, const char *pFilename, mz_uint16 filename_size, - const void *pExtra, mz_uint16 extra_size, const void *pComment, - mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, - mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, - mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, - mz_uint32 ext_attributes, const char *user_extra_data, - mz_uint user_extra_data_len) { - mz_zip_internal_state *pState = pZip->m_pState; - mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size; - size_t orig_central_dir_size = pState->m_central_dir.m_size; - mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE]; - - if (!pZip->m_pState->m_zip64) { - if (local_header_ofs > 0xFFFFFFFF) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE); - } - - /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */ - if (((mz_uint64)pState->m_central_dir.m_size + - MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size + - user_extra_data_len + comment_size) >= MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); - - if (!mz_zip_writer_create_central_dir_header( - pZip, central_dir_header, filename_size, - (mz_uint16)(extra_size + user_extra_data_len), comment_size, - uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, - dos_date, local_header_ofs, ext_attributes)) - return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - - if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header, - MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) || - (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, - filename_size)) || - (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, - extra_size)) || - (!mz_zip_array_push_back(pZip, &pState->m_central_dir, user_extra_data, - user_extra_data_len)) || - (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, - comment_size)) || - (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, - ¢ral_dir_ofs, 1))) { - /* Try to resize the central directory array back into its original state. - */ - mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, - MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - return MZ_TRUE; -} - -static mz_bool mz_zip_writer_validate_archive_name(const char *pArchive_name) { - /* Basic ZIP archive filename validity checks: Valid filenames cannot start - * with a forward slash, cannot contain a drive letter, and cannot use - * DOS-style backward slashes. */ - if (*pArchive_name == '/') - return MZ_FALSE; - - /* Making sure the name does not contain drive letters or DOS style backward - * slashes is the responsibility of the program using miniz*/ - - return MZ_TRUE; -} - -static mz_uint -mz_zip_writer_compute_padding_needed_for_file_alignment(mz_zip_archive *pZip) { - mz_uint32 n; - if (!pZip->m_file_offset_alignment) - return 0; - n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1)); - return (mz_uint)((pZip->m_file_offset_alignment - n) & - (pZip->m_file_offset_alignment - 1)); -} - -static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip, - mz_uint64 cur_file_ofs, mz_uint32 n) { - char buf[4096]; - memset(buf, 0, MZ_MIN(sizeof(buf), n)); - while (n) { - mz_uint32 s = MZ_MIN(sizeof(buf), n); - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_file_ofs += s; - n -= s; - } - return MZ_TRUE; -} - -mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, - const char *pArchive_name, const void *pBuf, - size_t buf_size, const void *pComment, - mz_uint16 comment_size, - mz_uint level_and_flags, mz_uint64 uncomp_size, - mz_uint32 uncomp_crc32) { - return mz_zip_writer_add_mem_ex_v2( - pZip, pArchive_name, pBuf, buf_size, pComment, comment_size, - level_and_flags, uncomp_size, uncomp_crc32, NULL, NULL, 0, NULL, 0); -} - -mz_bool mz_zip_writer_add_mem_ex_v2( - mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, - size_t buf_size, const void *pComment, mz_uint16 comment_size, - mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, - MZ_TIME_T *last_modified, const char *user_extra_data, - mz_uint user_extra_data_len, const char *user_extra_data_central, - mz_uint user_extra_data_central_len) { - mz_uint16 method = 0, dos_time = 0, dos_date = 0; - mz_uint level, ext_attributes = 0, num_alignment_padding_bytes; - mz_uint64 local_dir_header_ofs = 0, cur_archive_file_ofs = 0, comp_size = 0; - size_t archive_name_size; - mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; - tdefl_compressor *pComp = NULL; - mz_bool store_data_uncompressed; - mz_zip_internal_state *pState; - mz_uint8 *pExtra_data = NULL; - mz_uint32 extra_size = 0; - mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE]; - mz_uint16 bit_flags = 0; - - if ((int)level_and_flags < 0) - level_and_flags = MZ_DEFAULT_LEVEL; - - if (uncomp_size || - (buf_size && !(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))) - bit_flags |= MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR; - - if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME)) - bit_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8; - - level = level_and_flags & 0xF; - store_data_uncompressed = - ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)); - - if ((!pZip) || (!pZip->m_pState) || - (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || - (!pArchive_name) || ((comment_size) && (!pComment)) || - (level > MZ_UBER_COMPRESSION)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - pState = pZip->m_pState; - local_dir_header_ofs = pZip->m_archive_size; - cur_archive_file_ofs = pZip->m_archive_size; - - if (pState->m_zip64) { - if (pZip->m_total_files == MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - } else { - if (pZip->m_total_files == MZ_UINT16_MAX) { - pState->m_zip64 = MZ_TRUE; - /*return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); */ - } - if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF)) { - pState->m_zip64 = MZ_TRUE; - /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ - } - } - - if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (!mz_zip_writer_validate_archive_name(pArchive_name)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME); - -#ifndef MINIZ_NO_TIME - if (last_modified != NULL) { - mz_zip_time_t_to_dos_time(*last_modified, &dos_time, &dos_date); - } else { - MZ_TIME_T cur_time; - time(&cur_time); - mz_zip_time_t_to_dos_time(cur_time, &dos_time, &dos_date); - } -#endif /* #ifndef MINIZ_NO_TIME */ - - if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) { - uncomp_crc32 = - (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, buf_size); - uncomp_size = buf_size; - if (uncomp_size <= 3) { - level = 0; - store_data_uncompressed = MZ_TRUE; - } - } - - archive_name_size = strlen(pArchive_name); - if (archive_name_size > MZ_UINT16_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME); - - num_alignment_padding_bytes = - mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); - - /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */ - if (((mz_uint64)pState->m_central_dir.m_size + - MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + - MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE + comment_size) >= MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); - - if (!pState->m_zip64) { - /* Bail early if the archive would obviously become too large */ - if ((pZip->m_archive_size + num_alignment_padding_bytes + - MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + - MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + - user_extra_data_len + pState->m_central_dir.m_size + - MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + user_extra_data_central_len + - MZ_ZIP_DATA_DESCRIPTER_SIZE32) > 0xFFFFFFFF) { - pState->m_zip64 = MZ_TRUE; - /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ - } - } - - if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/')) { - /* Set DOS Subdirectory attribute bit. */ - ext_attributes |= MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG; - - /* Subdirectories cannot contain data. */ - if ((buf_size) || (uncomp_size)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - } - - /* Try to do any allocations before writing to the archive, so if an - * allocation fails the file remains unmodified. (A good idea if we're doing - * an in-place modification.) */ - if ((!mz_zip_array_ensure_room( - pZip, &pState->m_central_dir, - MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + - (pState->m_zip64 ? MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE : 0))) || - (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1))) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - if ((!store_data_uncompressed) && (buf_size)) { - if (NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc( - pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor)))) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, - num_alignment_padding_bytes)) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); - return MZ_FALSE; - } - - local_dir_header_ofs += num_alignment_padding_bytes; - if (pZip->m_file_offset_alignment) { - MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == - 0); - } - cur_archive_file_ofs += num_alignment_padding_bytes; - - MZ_CLEAR_OBJ(local_dir_header); - - if (!store_data_uncompressed || - (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) { - method = MZ_DEFLATED; - } - - if (pState->m_zip64) { - if (uncomp_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX) { - pExtra_data = extra_data; - extra_size = mz_zip_writer_create_zip64_extra_data( - extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, - (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, - (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs - : NULL); - } - - if (!mz_zip_writer_create_local_dir_header( - pZip, local_dir_header, (mz_uint16)archive_name_size, - (mz_uint16)(extra_size + user_extra_data_len), 0, 0, 0, method, - bit_flags, dos_time, dos_date)) - return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, - local_dir_header, - sizeof(local_dir_header)) != sizeof(local_dir_header)) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_archive_file_ofs += sizeof(local_dir_header); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, - archive_name_size) != archive_name_size) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - cur_archive_file_ofs += archive_name_size; - - if (pExtra_data != NULL) { - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, - extra_size) != extra_size) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_archive_file_ofs += extra_size; - } - } else { - if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX)) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - if (!mz_zip_writer_create_local_dir_header( - pZip, local_dir_header, (mz_uint16)archive_name_size, - (mz_uint16)user_extra_data_len, 0, 0, 0, method, bit_flags, - dos_time, dos_date)) - return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, - local_dir_header, - sizeof(local_dir_header)) != sizeof(local_dir_header)) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_archive_file_ofs += sizeof(local_dir_header); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, - archive_name_size) != archive_name_size) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - cur_archive_file_ofs += archive_name_size; - } - - if (user_extra_data_len > 0) { - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, - user_extra_data, - user_extra_data_len) != user_extra_data_len) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_archive_file_ofs += user_extra_data_len; - } - - if (store_data_uncompressed) { - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf, - buf_size) != buf_size) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - - cur_archive_file_ofs += buf_size; - comp_size = buf_size; - } else if (buf_size) { - mz_zip_writer_add_state state; - - state.m_pZip = pZip; - state.m_cur_archive_file_ofs = cur_archive_file_ofs; - state.m_comp_size = 0; - - if ((tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, - tdefl_create_comp_flags_from_zip_params( - level, -15, MZ_DEFAULT_STRATEGY)) != - TDEFL_STATUS_OKAY) || - (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) != - TDEFL_STATUS_DONE)) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); - return mz_zip_set_error(pZip, MZ_ZIP_COMPRESSION_FAILED); - } - - comp_size = state.m_comp_size; - cur_archive_file_ofs = state.m_cur_archive_file_ofs; - } - - pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); - pComp = NULL; - - if (uncomp_size) { - mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64]; - mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32; - - MZ_ASSERT(bit_flags & MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR); - - MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID); - MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32); - if (pExtra_data == NULL) { - if (comp_size > MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - - MZ_WRITE_LE32(local_dir_footer + 8, comp_size); - MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size); - } else { - MZ_WRITE_LE64(local_dir_footer + 8, comp_size); - MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size); - local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64; - } - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, - local_dir_footer, - local_dir_footer_size) != local_dir_footer_size) - return MZ_FALSE; - - cur_archive_file_ofs += local_dir_footer_size; - } - - if (pExtra_data != NULL) { - extra_size = mz_zip_writer_create_zip64_extra_data( - extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, - (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, - (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); - } - - if (!mz_zip_writer_add_to_central_dir( - pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, - (mz_uint16)extra_size, pComment, comment_size, uncomp_size, comp_size, - uncomp_crc32, method, bit_flags, dos_time, dos_date, - local_dir_header_ofs, ext_attributes, user_extra_data_central, - user_extra_data_central_len)) - return MZ_FALSE; - - pZip->m_total_files++; - pZip->m_archive_size = cur_archive_file_ofs; - - return MZ_TRUE; -} - -mz_bool mz_zip_writer_add_read_buf_callback( - mz_zip_archive *pZip, const char *pArchive_name, - mz_file_read_func read_callback, void *callback_opaque, mz_uint64 max_size, - const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, - mz_uint level_and_flags, mz_uint32 ext_attributes, - const char *user_extra_data, mz_uint user_extra_data_len, - const char *user_extra_data_central, mz_uint user_extra_data_central_len) { - mz_uint16 gen_flags = (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE) - ? 0 - : MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR; - mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes; - mz_uint16 method = 0, dos_time = 0, dos_date = 0; - mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = 0, uncomp_size = 0, - comp_size = 0; - size_t archive_name_size; - mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; - mz_uint8 *pExtra_data = NULL; - mz_uint32 extra_size = 0; - mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE]; - mz_zip_internal_state *pState; - mz_uint64 file_ofs = 0, cur_archive_header_file_ofs; - - if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME)) - gen_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8; - - if ((int)level_and_flags < 0) - level_and_flags = MZ_DEFAULT_LEVEL; - level = level_and_flags & 0xF; - - /* Sanity checks */ - if ((!pZip) || (!pZip->m_pState) || - (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || - ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - pState = pZip->m_pState; - cur_archive_file_ofs = pZip->m_archive_size; - - if ((!pState->m_zip64) && (max_size > MZ_UINT32_MAX)) { - /* Source file is too large for non-zip64 */ - /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ - pState->m_zip64 = MZ_TRUE; - } - - /* We could support this, but why? */ - if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (!mz_zip_writer_validate_archive_name(pArchive_name)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME); - - if (pState->m_zip64) { - if (pZip->m_total_files == MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - } else { - if (pZip->m_total_files == MZ_UINT16_MAX) { - pState->m_zip64 = MZ_TRUE; - /*return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); */ - } - } - - archive_name_size = strlen(pArchive_name); - if (archive_name_size > MZ_UINT16_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME); - - num_alignment_padding_bytes = - mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); - - /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */ - if (((mz_uint64)pState->m_central_dir.m_size + - MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + - MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE + comment_size) >= MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); - - if (!pState->m_zip64) { - /* Bail early if the archive would obviously become too large */ - if ((pZip->m_archive_size + num_alignment_padding_bytes + - MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + - MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + - user_extra_data_len + pState->m_central_dir.m_size + - MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 1024 + - MZ_ZIP_DATA_DESCRIPTER_SIZE32 + user_extra_data_central_len) > - 0xFFFFFFFF) { - pState->m_zip64 = MZ_TRUE; - /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ - } - } - -#ifndef MINIZ_NO_TIME - if (pFile_time) { - mz_zip_time_t_to_dos_time(*pFile_time, &dos_time, &dos_date); - } -#endif - - if (max_size <= 3) - level = 0; - - if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, - num_alignment_padding_bytes)) { - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - - cur_archive_file_ofs += num_alignment_padding_bytes; - local_dir_header_ofs = cur_archive_file_ofs; - - if (pZip->m_file_offset_alignment) { - MZ_ASSERT((cur_archive_file_ofs & (pZip->m_file_offset_alignment - 1)) == - 0); - } - - if (max_size && level) { - method = MZ_DEFLATED; - } - - MZ_CLEAR_OBJ(local_dir_header); - if (pState->m_zip64) { - if (max_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX) { - pExtra_data = extra_data; - if (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE) - extra_size = mz_zip_writer_create_zip64_extra_data( - extra_data, (max_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, - (max_size >= MZ_UINT32_MAX) ? &comp_size : NULL, - (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs - : NULL); - else - extra_size = mz_zip_writer_create_zip64_extra_data( - extra_data, NULL, NULL, - (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs - : NULL); - } - - if (!mz_zip_writer_create_local_dir_header( - pZip, local_dir_header, (mz_uint16)archive_name_size, - (mz_uint16)(extra_size + user_extra_data_len), 0, 0, 0, method, - gen_flags, dos_time, dos_date)) - return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, - local_dir_header, - sizeof(local_dir_header)) != sizeof(local_dir_header)) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_archive_file_ofs += sizeof(local_dir_header); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, - archive_name_size) != archive_name_size) { - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - - cur_archive_file_ofs += archive_name_size; - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, - extra_size) != extra_size) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_archive_file_ofs += extra_size; - } else { - if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX)) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - if (!mz_zip_writer_create_local_dir_header( - pZip, local_dir_header, (mz_uint16)archive_name_size, - (mz_uint16)user_extra_data_len, 0, 0, 0, method, gen_flags, - dos_time, dos_date)) - return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, - local_dir_header, - sizeof(local_dir_header)) != sizeof(local_dir_header)) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_archive_file_ofs += sizeof(local_dir_header); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, - archive_name_size) != archive_name_size) { - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - - cur_archive_file_ofs += archive_name_size; - } - - if (user_extra_data_len > 0) { - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, - user_extra_data, - user_extra_data_len) != user_extra_data_len) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_archive_file_ofs += user_extra_data_len; - } - - if (max_size) { - void *pRead_buf = - pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE); - if (!pRead_buf) { - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - if (!level) { - while (1) { - size_t n = read_callback(callback_opaque, file_ofs, pRead_buf, - MZ_ZIP_MAX_IO_BUF_SIZE); - if (n == 0) - break; - - if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size)) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - } - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, - n) != n) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - file_ofs += n; - uncomp_crc32 = - (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n); - cur_archive_file_ofs += n; - } - uncomp_size = file_ofs; - comp_size = uncomp_size; - } else { - mz_bool result = MZ_FALSE; - mz_zip_writer_add_state state; - tdefl_compressor *pComp = (tdefl_compressor *)pZip->m_pAlloc( - pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor)); - if (!pComp) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - state.m_pZip = pZip; - state.m_cur_archive_file_ofs = cur_archive_file_ofs; - state.m_comp_size = 0; - - if (tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, - tdefl_create_comp_flags_from_zip_params( - level, -15, MZ_DEFAULT_STRATEGY)) != - TDEFL_STATUS_OKAY) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); - pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); - return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - } - - for (;;) { - tdefl_status status; - tdefl_flush flush = TDEFL_NO_FLUSH; - - size_t n = read_callback(callback_opaque, file_ofs, pRead_buf, - MZ_ZIP_MAX_IO_BUF_SIZE); - if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size)) { - mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - break; - } - - file_ofs += n; - uncomp_crc32 = - (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n); - - if (pZip->m_pNeeds_keepalive != NULL && - pZip->m_pNeeds_keepalive(pZip->m_pIO_opaque)) - flush = TDEFL_FULL_FLUSH; - - if (n == 0) - flush = TDEFL_FINISH; - - status = tdefl_compress_buffer(pComp, pRead_buf, n, flush); - if (status == TDEFL_STATUS_DONE) { - result = MZ_TRUE; - break; - } else if (status != TDEFL_STATUS_OKAY) { - mz_zip_set_error(pZip, MZ_ZIP_COMPRESSION_FAILED); - break; - } - } - - pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); - - if (!result) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); - return MZ_FALSE; - } - - uncomp_size = file_ofs; - comp_size = state.m_comp_size; - cur_archive_file_ofs = state.m_cur_archive_file_ofs; - } - - pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); - } - - if (!(level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE)) { - mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64]; - mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32; - - MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID); - MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32); - if (pExtra_data == NULL) { - if (comp_size > MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - - MZ_WRITE_LE32(local_dir_footer + 8, comp_size); - MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size); - } else { - MZ_WRITE_LE64(local_dir_footer + 8, comp_size); - MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size); - local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64; - } - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, - local_dir_footer, - local_dir_footer_size) != local_dir_footer_size) - return MZ_FALSE; - - cur_archive_file_ofs += local_dir_footer_size; - } - - if (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE) { - if (pExtra_data != NULL) { - extra_size = mz_zip_writer_create_zip64_extra_data( - extra_data, (max_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, - (max_size >= MZ_UINT32_MAX) ? &comp_size : NULL, - (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs - : NULL); - } - - if (!mz_zip_writer_create_local_dir_header( - pZip, local_dir_header, (mz_uint16)archive_name_size, - (mz_uint16)(extra_size + user_extra_data_len), - (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : uncomp_size, - (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : comp_size, - uncomp_crc32, method, gen_flags, dos_time, dos_date)) - return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); - - cur_archive_header_file_ofs = local_dir_header_ofs; - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, - local_dir_header, - sizeof(local_dir_header)) != sizeof(local_dir_header)) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - if (pExtra_data != NULL) { - cur_archive_header_file_ofs += sizeof(local_dir_header); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, - pArchive_name, - archive_name_size) != archive_name_size) { - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - - cur_archive_header_file_ofs += archive_name_size; - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, - extra_data, extra_size) != extra_size) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_archive_header_file_ofs += extra_size; - } - } - - if (pExtra_data != NULL) { - extra_size = mz_zip_writer_create_zip64_extra_data( - extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, - (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, - (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); - } - - if (!mz_zip_writer_add_to_central_dir( - pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, - (mz_uint16)extra_size, pComment, comment_size, uncomp_size, comp_size, - uncomp_crc32, method, gen_flags, dos_time, dos_date, - local_dir_header_ofs, ext_attributes, user_extra_data_central, - user_extra_data_central_len)) - return MZ_FALSE; - - pZip->m_total_files++; - pZip->m_archive_size = cur_archive_file_ofs; - - return MZ_TRUE; -} - -#ifndef MINIZ_NO_STDIO - -static size_t mz_file_read_func_stdio(void *pOpaque, mz_uint64 file_ofs, - void *pBuf, size_t n) { - MZ_FILE *pSrc_file = (MZ_FILE *)pOpaque; - mz_int64 cur_ofs = MZ_FTELL64(pSrc_file); - - if (((mz_int64)file_ofs < 0) || - (((cur_ofs != (mz_int64)file_ofs)) && - (MZ_FSEEK64(pSrc_file, (mz_int64)file_ofs, SEEK_SET)))) - return 0; - - return MZ_FREAD(pBuf, 1, n, pSrc_file); -} - -mz_bool mz_zip_writer_add_cfile( - mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, - mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, - mz_uint16 comment_size, mz_uint level_and_flags, mz_uint32 ext_attributes, - const char *user_extra_data, mz_uint user_extra_data_len, - const char *user_extra_data_central, mz_uint user_extra_data_central_len) { - return mz_zip_writer_add_read_buf_callback( - pZip, pArchive_name, mz_file_read_func_stdio, pSrc_file, max_size, - pFile_time, pComment, comment_size, level_and_flags, ext_attributes, - user_extra_data, user_extra_data_len, user_extra_data_central, - user_extra_data_central_len); -} - -mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, - const char *pSrc_filename, const void *pComment, - mz_uint16 comment_size, mz_uint level_and_flags, - mz_uint32 ext_attributes) { - MZ_FILE *pSrc_file = NULL; - mz_uint64 uncomp_size = 0; - MZ_TIME_T file_modified_time; - MZ_TIME_T *pFile_time = NULL; - mz_bool status; - - memset(&file_modified_time, 0, sizeof(file_modified_time)); - -#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO) - pFile_time = &file_modified_time; - if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time)) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_STAT_FAILED); -#endif - - pSrc_file = MZ_FOPEN(pSrc_filename, "rb"); - if (!pSrc_file) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); - - MZ_FSEEK64(pSrc_file, 0, SEEK_END); - uncomp_size = MZ_FTELL64(pSrc_file); - MZ_FSEEK64(pSrc_file, 0, SEEK_SET); - - status = mz_zip_writer_add_cfile( - pZip, pArchive_name, pSrc_file, uncomp_size, pFile_time, pComment, - comment_size, level_and_flags, ext_attributes, NULL, 0, NULL, 0); - - MZ_FCLOSE(pSrc_file); - - return status; -} -#endif /* #ifndef MINIZ_NO_STDIO */ - -static mz_bool mz_zip_writer_update_zip64_extension_block( - mz_zip_array *pNew_ext, mz_zip_archive *pZip, const mz_uint8 *pExt, - uint32_t ext_len, mz_uint64 *pComp_size, mz_uint64 *pUncomp_size, - mz_uint64 *pLocal_header_ofs, mz_uint32 *pDisk_start) { - /* + 64 should be enough for any new zip64 data */ - if (!mz_zip_array_reserve(pZip, pNew_ext, ext_len + 64, MZ_FALSE)) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - mz_zip_array_resize(pZip, pNew_ext, 0, MZ_FALSE); - - if ((pUncomp_size) || (pComp_size) || (pLocal_header_ofs) || (pDisk_start)) { - mz_uint8 new_ext_block[64]; - mz_uint8 *pDst = new_ext_block; - mz_write_le16(pDst, MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID); - mz_write_le16(pDst + sizeof(mz_uint16), 0); - pDst += sizeof(mz_uint16) * 2; - - if (pUncomp_size) { - mz_write_le64(pDst, *pUncomp_size); - pDst += sizeof(mz_uint64); - } - - if (pComp_size) { - mz_write_le64(pDst, *pComp_size); - pDst += sizeof(mz_uint64); - } - - if (pLocal_header_ofs) { - mz_write_le64(pDst, *pLocal_header_ofs); - pDst += sizeof(mz_uint64); - } - - if (pDisk_start) { - mz_write_le32(pDst, *pDisk_start); - pDst += sizeof(mz_uint32); - } - - mz_write_le16(new_ext_block + sizeof(mz_uint16), - (mz_uint16)((pDst - new_ext_block) - sizeof(mz_uint16) * 2)); - - if (!mz_zip_array_push_back(pZip, pNew_ext, new_ext_block, - pDst - new_ext_block)) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - if ((pExt) && (ext_len)) { - mz_uint32 extra_size_remaining = ext_len; - const mz_uint8 *pExtra_data = pExt; - - do { - mz_uint32 field_id, field_data_size, field_total_size; - - if (extra_size_remaining < (sizeof(mz_uint16) * 2)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - field_id = MZ_READ_LE16(pExtra_data); - field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); - field_total_size = field_data_size + sizeof(mz_uint16) * 2; - - if (field_total_size > extra_size_remaining) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - if (field_id != MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) { - if (!mz_zip_array_push_back(pZip, pNew_ext, pExtra_data, - field_total_size)) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - pExtra_data += field_total_size; - extra_size_remaining -= field_total_size; - } while (extra_size_remaining); - } - - return MZ_TRUE; -} - -/* TODO: This func is now pretty freakin complex due to zip64, split it up? */ -mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, - mz_zip_archive *pSource_zip, - mz_uint src_file_index) { - mz_uint n, bit_flags, num_alignment_padding_bytes, - src_central_dir_following_data_size; - mz_uint64 src_archive_bytes_remaining, local_dir_header_ofs; - mz_uint64 cur_src_file_ofs, cur_dst_file_ofs; - mz_uint32 - local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / - sizeof(mz_uint32)]; - mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; - mz_uint8 new_central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE]; - size_t orig_central_dir_size; - mz_zip_internal_state *pState; - void *pBuf; - const mz_uint8 *pSrc_central_header; - mz_zip_archive_file_stat src_file_stat; - mz_uint32 src_filename_len, src_comment_len, src_ext_len; - mz_uint32 local_header_filename_size, local_header_extra_len; - mz_uint64 local_header_comp_size, local_header_uncomp_size; - mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE; - - /* Sanity checks */ - if ((!pZip) || (!pZip->m_pState) || - (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pSource_zip->m_pRead)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - pState = pZip->m_pState; - - /* Don't support copying files from zip64 archives to non-zip64, even though - * in some cases this is possible */ - if ((pSource_zip->m_pState->m_zip64) && (!pZip->m_pState->m_zip64)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - /* Get pointer to the source central dir header and crack it */ - if (NULL == - (pSrc_central_header = mz_zip_get_cdh(pSource_zip, src_file_index))) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_SIG_OFS) != - MZ_ZIP_CENTRAL_DIR_HEADER_SIG) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - src_filename_len = - MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS); - src_comment_len = - MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS); - src_ext_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS); - src_central_dir_following_data_size = - src_filename_len + src_ext_len + src_comment_len; - - /* TODO: We don't support central dir's >= MZ_UINT32_MAX bytes right now (+32 - * fudge factor in case we need to add more extra data) */ - if ((pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + - src_central_dir_following_data_size + 32) >= MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); - - num_alignment_padding_bytes = - mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); - - if (!pState->m_zip64) { - if (pZip->m_total_files == MZ_UINT16_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - } else { - /* TODO: Our zip64 support still has some 32-bit limits that may not be - * worth fixing. */ - if (pZip->m_total_files == MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - } - - if (!mz_zip_file_stat_internal(pSource_zip, src_file_index, - pSrc_central_header, &src_file_stat, NULL)) - return MZ_FALSE; - - cur_src_file_ofs = src_file_stat.m_local_header_ofs; - cur_dst_file_ofs = pZip->m_archive_size; - - /* Read the source archive's local dir header */ - if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, - pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != - MZ_ZIP_LOCAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - - if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - - cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE; - - /* Compute the total size we need to copy (filename+extra data+compressed - * data) */ - local_header_filename_size = - MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS); - local_header_extra_len = - MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); - local_header_comp_size = - MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS); - local_header_uncomp_size = - MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS); - src_archive_bytes_remaining = local_header_filename_size + - local_header_extra_len + - src_file_stat.m_comp_size; - - /* Try to find a zip64 extended information field */ - if ((local_header_extra_len) && - ((local_header_comp_size == MZ_UINT32_MAX) || - (local_header_uncomp_size == MZ_UINT32_MAX))) { - mz_zip_array file_data_array; - const mz_uint8 *pExtra_data; - mz_uint32 extra_size_remaining = local_header_extra_len; - - mz_zip_array_init(&file_data_array, 1); - if (!mz_zip_array_resize(pZip, &file_data_array, local_header_extra_len, - MZ_FALSE)) { - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, - src_file_stat.m_local_header_ofs + - MZ_ZIP_LOCAL_DIR_HEADER_SIZE + - local_header_filename_size, - file_data_array.m_p, local_header_extra_len) != - local_header_extra_len) { - mz_zip_array_clear(pZip, &file_data_array); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - } - - pExtra_data = (const mz_uint8 *)file_data_array.m_p; - - do { - mz_uint32 field_id, field_data_size, field_total_size; - - if (extra_size_remaining < (sizeof(mz_uint16) * 2)) { - mz_zip_array_clear(pZip, &file_data_array); - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - } - - field_id = MZ_READ_LE16(pExtra_data); - field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); - field_total_size = field_data_size + sizeof(mz_uint16) * 2; - - if (field_total_size > extra_size_remaining) { - mz_zip_array_clear(pZip, &file_data_array); - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - } - - if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) { - const mz_uint8 *pSrc_field_data = pExtra_data + sizeof(mz_uint32); - - if (field_data_size < sizeof(mz_uint64) * 2) { - mz_zip_array_clear(pZip, &file_data_array); - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - } - - local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data); - local_header_comp_size = MZ_READ_LE64( - pSrc_field_data + - sizeof(mz_uint64)); /* may be 0 if there's a descriptor */ - - found_zip64_ext_data_in_ldir = MZ_TRUE; - break; - } - - pExtra_data += field_total_size; - extra_size_remaining -= field_total_size; - } while (extra_size_remaining); - - mz_zip_array_clear(pZip, &file_data_array); - } - - if (!pState->m_zip64) { - /* Try to detect if the new archive will most likely wind up too big and - * bail early (+(sizeof(mz_uint32) * 4) is for the optional descriptor which - * could be present, +64 is a fudge factor). */ - /* We also check when the archive is finalized so this doesn't need to be - * perfect. */ - mz_uint64 approx_new_archive_size = - cur_dst_file_ofs + num_alignment_padding_bytes + - MZ_ZIP_LOCAL_DIR_HEADER_SIZE + src_archive_bytes_remaining + - (sizeof(mz_uint32) * 4) + pState->m_central_dir.m_size + - MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_central_dir_following_data_size + - MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 64; - - if (approx_new_archive_size >= MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - } - - /* Write dest archive padding */ - if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs, - num_alignment_padding_bytes)) - return MZ_FALSE; - - cur_dst_file_ofs += num_alignment_padding_bytes; - - local_dir_header_ofs = cur_dst_file_ofs; - if (pZip->m_file_offset_alignment) { - MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == - 0); - } - - /* The original zip's local header+ext block doesn't change, even with zip64, - * so we can just copy it over to the dest zip */ - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header, - MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != - MZ_ZIP_LOCAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE; - - /* Copy over the source archive bytes to the dest archive, also ensure we have - * enough buf space to handle optional data descriptor */ - if (NULL == (pBuf = pZip->m_pAlloc( - pZip->m_pAlloc_opaque, 1, - (size_t)MZ_MAX(32U, MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, - src_archive_bytes_remaining))))) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - while (src_archive_bytes_remaining) { - n = (mz_uint)MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, - src_archive_bytes_remaining); - if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, - n) != n) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - } - cur_src_file_ofs += n; - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - cur_dst_file_ofs += n; - - src_archive_bytes_remaining -= n; - } - - /* Now deal with the optional data descriptor */ - bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS); - if (bit_flags & 8) { - /* Copy data descriptor */ - if ((pSource_zip->m_pState->m_zip64) || (found_zip64_ext_data_in_ldir)) { - /* src is zip64, dest must be zip64 */ - - /* name uint32_t's */ - /* id 1 (optional in zip64?) */ - /* crc 1 */ - /* comp_size 2 */ - /* uncomp_size 2 */ - if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, - pBuf, (sizeof(mz_uint32) * 6)) != - (sizeof(mz_uint32) * 6)) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - } - - n = sizeof(mz_uint32) * - ((MZ_READ_LE32(pBuf) == MZ_ZIP_DATA_DESCRIPTOR_ID) ? 6 : 5); - } else { - /* src is NOT zip64 */ - mz_bool has_id; - - if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, - pBuf, sizeof(mz_uint32) * 4) != - sizeof(mz_uint32) * 4) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - } - - has_id = (MZ_READ_LE32(pBuf) == MZ_ZIP_DATA_DESCRIPTOR_ID); - - if (pZip->m_pState->m_zip64) { - /* dest is zip64, so upgrade the data descriptor */ - const mz_uint32 *pSrc_descriptor = - (const mz_uint32 *)((const mz_uint8 *)pBuf + - (has_id ? sizeof(mz_uint32) : 0)); - const mz_uint32 src_crc32 = pSrc_descriptor[0]; - const mz_uint64 src_comp_size = pSrc_descriptor[1]; - const mz_uint64 src_uncomp_size = pSrc_descriptor[2]; - - mz_write_le32((mz_uint8 *)pBuf, MZ_ZIP_DATA_DESCRIPTOR_ID); - mz_write_le32((mz_uint8 *)pBuf + sizeof(mz_uint32) * 1, src_crc32); - mz_write_le64((mz_uint8 *)pBuf + sizeof(mz_uint32) * 2, src_comp_size); - mz_write_le64((mz_uint8 *)pBuf + sizeof(mz_uint32) * 4, - src_uncomp_size); - - n = sizeof(mz_uint32) * 6; - } else { - /* dest is NOT zip64, just copy it as-is */ - n = sizeof(mz_uint32) * (has_id ? 4 : 3); - } - } - - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) { - pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - } - - cur_src_file_ofs += n; - cur_dst_file_ofs += n; - } - pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); - - /* Finally, add the new central dir header */ - orig_central_dir_size = pState->m_central_dir.m_size; - - memcpy(new_central_header, pSrc_central_header, - MZ_ZIP_CENTRAL_DIR_HEADER_SIZE); - - if (pState->m_zip64) { - /* This is the painful part: We need to write a new central dir header + ext - * block with updated zip64 fields, and ensure the old fields (if any) are - * not included. */ - const mz_uint8 *pSrc_ext = - pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_filename_len; - mz_zip_array new_ext_block; - - mz_zip_array_init(&new_ext_block, sizeof(mz_uint8)); - - MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, - MZ_UINT32_MAX); - MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, - MZ_UINT32_MAX); - MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, - MZ_UINT32_MAX); - - if (!mz_zip_writer_update_zip64_extension_block( - &new_ext_block, pZip, pSrc_ext, src_ext_len, - &src_file_stat.m_comp_size, &src_file_stat.m_uncomp_size, - &local_dir_header_ofs, NULL)) { - mz_zip_array_clear(pZip, &new_ext_block); - return MZ_FALSE; - } - - MZ_WRITE_LE16(new_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS, - new_ext_block.m_size); - - if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, - new_central_header, - MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) { - mz_zip_array_clear(pZip, &new_ext_block); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, - pSrc_central_header + - MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, - src_filename_len)) { - mz_zip_array_clear(pZip, &new_ext_block); - mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, - MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_ext_block.m_p, - new_ext_block.m_size)) { - mz_zip_array_clear(pZip, &new_ext_block); - mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, - MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, - pSrc_central_header + - MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + - src_filename_len + src_ext_len, - src_comment_len)) { - mz_zip_array_clear(pZip, &new_ext_block); - mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, - MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - mz_zip_array_clear(pZip, &new_ext_block); - } else { - /* sanity checks */ - if (cur_dst_file_ofs > MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - - if (local_dir_header_ofs >= MZ_UINT32_MAX) - return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); - - MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, - local_dir_header_ofs); - - if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, - new_central_header, - MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, - pSrc_central_header + - MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, - src_central_dir_following_data_size)) { - mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, - MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - } - - /* This shouldn't trigger unless we screwed up during the initial sanity - * checks */ - if (pState->m_central_dir.m_size >= MZ_UINT32_MAX) { - /* TODO: Support central dirs >= 32-bits in size */ - mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, - MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); - } - - n = (mz_uint32)orig_central_dir_size; - if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1)) { - mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, - MZ_FALSE); - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - } - - pZip->m_total_files++; - pZip->m_archive_size = cur_dst_file_ofs; - - return MZ_TRUE; -} - -mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip) { - mz_zip_internal_state *pState; - mz_uint64 central_dir_ofs, central_dir_size; - mz_uint8 hdr[256]; - - if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - pState = pZip->m_pState; - - if (pState->m_zip64) { - if ((pZip->m_total_files > MZ_UINT32_MAX) || - (pState->m_central_dir.m_size >= MZ_UINT32_MAX)) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - } else { - if ((pZip->m_total_files > MZ_UINT16_MAX) || - ((pZip->m_archive_size + pState->m_central_dir.m_size + - MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > MZ_UINT32_MAX)) - return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); - } - - central_dir_ofs = 0; - central_dir_size = 0; - if (pZip->m_total_files) { - /* Write central directory */ - central_dir_ofs = pZip->m_archive_size; - central_dir_size = pState->m_central_dir.m_size; - pZip->m_central_directory_file_ofs = central_dir_ofs; - if (pZip->m_pWrite(pZip->m_pIO_opaque, central_dir_ofs, - pState->m_central_dir.m_p, - (size_t)central_dir_size) != central_dir_size) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - pZip->m_archive_size += central_dir_size; - } - - if (pState->m_zip64) { - /* Write zip64 end of central directory header */ - mz_uint64 rel_ofs_to_zip64_ecdr = pZip->m_archive_size; - - MZ_CLEAR_OBJ(hdr); - MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDH_SIG_OFS, - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG); - MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS, - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - sizeof(mz_uint32) - - sizeof(mz_uint64)); - MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS, - 0x031E); /* TODO: always Unix */ - MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_NEEDED_OFS, 0x002D); - MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, - pZip->m_total_files); - MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS, - pZip->m_total_files); - MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_SIZE_OFS, central_dir_size); - MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_OFS_OFS, central_dir_ofs); - if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) != - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - pZip->m_archive_size += MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE; - - /* Write zip64 end of central directory locator */ - MZ_CLEAR_OBJ(hdr); - MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_SIG_OFS, - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG); - MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS, - rel_ofs_to_zip64_ecdr); - MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS, 1); - if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) != - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - - pZip->m_archive_size += MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE; - } - - /* Write end of central directory record */ - MZ_CLEAR_OBJ(hdr); - MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS, - MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG); - MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, - MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files)); - MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS, - MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files)); - MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS, - MZ_MIN(MZ_UINT32_MAX, central_dir_size)); - MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS, - MZ_MIN(MZ_UINT32_MAX, central_dir_ofs)); - - if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, - MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != - MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - -#ifndef MINIZ_NO_STDIO - if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF)) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED); -#endif /* #ifndef MINIZ_NO_STDIO */ - - pZip->m_archive_size += MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE; - - pZip->m_zip_mode = MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED; - return MZ_TRUE; -} - -mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **ppBuf, - size_t *pSize) { - if ((!ppBuf) || (!pSize)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - *ppBuf = NULL; - *pSize = 0; - - if ((!pZip) || (!pZip->m_pState)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (pZip->m_pWrite != mz_zip_heap_write_func) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - if (!mz_zip_writer_finalize_archive(pZip)) - return MZ_FALSE; - - *ppBuf = pZip->m_pState->m_pMem; - *pSize = pZip->m_pState->m_mem_size; - pZip->m_pState->m_pMem = NULL; - pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0; - - return MZ_TRUE; -} - -mz_bool mz_zip_writer_end(mz_zip_archive *pZip) { - return mz_zip_writer_end_internal(pZip, MZ_TRUE); -} - -#ifndef MINIZ_NO_STDIO -mz_bool mz_zip_add_mem_to_archive_file_in_place( - const char *pZip_filename, const char *pArchive_name, const void *pBuf, - size_t buf_size, const void *pComment, mz_uint16 comment_size, - mz_uint level_and_flags) { - return mz_zip_add_mem_to_archive_file_in_place_v2( - pZip_filename, pArchive_name, pBuf, buf_size, pComment, comment_size, - level_and_flags, NULL); -} - -mz_bool mz_zip_add_mem_to_archive_file_in_place_v2( - const char *pZip_filename, const char *pArchive_name, const void *pBuf, - size_t buf_size, const void *pComment, mz_uint16 comment_size, - mz_uint level_and_flags, mz_zip_error *pErr) { - mz_bool status, created_new_archive = MZ_FALSE; - mz_zip_archive zip_archive; - struct MZ_FILE_STAT_STRUCT file_stat; - mz_zip_error actual_err = MZ_ZIP_NO_ERROR; - - mz_zip_zero_struct(&zip_archive); - if ((int)level_and_flags < 0) - level_and_flags = MZ_DEFAULT_LEVEL; - - if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || - ((comment_size) && (!pComment)) || - ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION)) { - if (pErr) - *pErr = MZ_ZIP_INVALID_PARAMETER; - return MZ_FALSE; - } - - if (!mz_zip_writer_validate_archive_name(pArchive_name)) { - if (pErr) - *pErr = MZ_ZIP_INVALID_FILENAME; - return MZ_FALSE; - } - - /* Important: The regular non-64 bit version of stat() can fail here if the - * file is very large, which could cause the archive to be overwritten. */ - /* So be sure to compile with _LARGEFILE64_SOURCE 1 */ - if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0) { - /* Create a new archive. */ - if (!mz_zip_writer_init_file_v2(&zip_archive, pZip_filename, 0, - level_and_flags)) { - if (pErr) - *pErr = zip_archive.m_last_error; - return MZ_FALSE; - } - - created_new_archive = MZ_TRUE; - } else { - /* Append to an existing archive. */ - if (!mz_zip_reader_init_file_v2( - &zip_archive, pZip_filename, - level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, - 0)) { - if (pErr) - *pErr = zip_archive.m_last_error; - return MZ_FALSE; - } - - if (!mz_zip_writer_init_from_reader_v2(&zip_archive, pZip_filename, - level_and_flags)) { - if (pErr) - *pErr = zip_archive.m_last_error; - - mz_zip_reader_end_internal(&zip_archive, MZ_FALSE); - - return MZ_FALSE; - } - } - - status = - mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, - pComment, comment_size, level_and_flags, 0, 0); - actual_err = zip_archive.m_last_error; - - /* Always finalize, even if adding failed for some reason, so we have a valid - * central directory. (This may not always succeed, but we can try.) */ - if (!mz_zip_writer_finalize_archive(&zip_archive)) { - if (!actual_err) - actual_err = zip_archive.m_last_error; - - status = MZ_FALSE; - } - - if (!mz_zip_writer_end_internal(&zip_archive, status)) { - if (!actual_err) - actual_err = zip_archive.m_last_error; - - status = MZ_FALSE; - } - - if ((!status) && (created_new_archive)) { - /* It's a new archive and something went wrong, so just delete it. */ - int ignoredStatus = MZ_DELETE_FILE(pZip_filename); - (void)ignoredStatus; - } - - if (pErr) - *pErr = actual_err; - - return status; -} - -void *mz_zip_extract_archive_file_to_heap_v2(const char *pZip_filename, - const char *pArchive_name, - const char *pComment, - size_t *pSize, mz_uint flags, - mz_zip_error *pErr) { - mz_uint32 file_index; - mz_zip_archive zip_archive; - void *p = NULL; - - if (pSize) - *pSize = 0; - - if ((!pZip_filename) || (!pArchive_name)) { - if (pErr) - *pErr = MZ_ZIP_INVALID_PARAMETER; - - return NULL; - } - - mz_zip_zero_struct(&zip_archive); - if (!mz_zip_reader_init_file_v2( - &zip_archive, pZip_filename, - flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0)) { - if (pErr) - *pErr = zip_archive.m_last_error; - - return NULL; - } - - if (mz_zip_reader_locate_file_v2(&zip_archive, pArchive_name, pComment, flags, - &file_index)) { - p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags); - } - - mz_zip_reader_end_internal(&zip_archive, p != NULL); - - if (pErr) - *pErr = zip_archive.m_last_error; - - return p; -} - -void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, - const char *pArchive_name, - size_t *pSize, mz_uint flags) { - return mz_zip_extract_archive_file_to_heap_v2(pZip_filename, pArchive_name, - NULL, pSize, flags, NULL); -} - -#endif /* #ifndef MINIZ_NO_STDIO */ - -#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */ - -/* ------------------- Misc utils */ - -mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip) { - return pZip ? pZip->m_zip_mode : MZ_ZIP_MODE_INVALID; -} - -mz_zip_type mz_zip_get_type(mz_zip_archive *pZip) { - return pZip ? pZip->m_zip_type : MZ_ZIP_TYPE_INVALID; -} - -mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num) { - mz_zip_error prev_err; - - if (!pZip) - return MZ_ZIP_INVALID_PARAMETER; - - prev_err = pZip->m_last_error; - - pZip->m_last_error = err_num; - return prev_err; -} - -mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip) { - if (!pZip) - return MZ_ZIP_INVALID_PARAMETER; - - return pZip->m_last_error; -} - -mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip) { - return mz_zip_set_last_error(pZip, MZ_ZIP_NO_ERROR); -} - -mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip) { - mz_zip_error prev_err; - - if (!pZip) - return MZ_ZIP_INVALID_PARAMETER; - - prev_err = pZip->m_last_error; - - pZip->m_last_error = MZ_ZIP_NO_ERROR; - return prev_err; -} - -const char *mz_zip_get_error_string(mz_zip_error mz_err) { - switch (mz_err) { - case MZ_ZIP_NO_ERROR: - return "no error"; - case MZ_ZIP_UNDEFINED_ERROR: - return "undefined error"; - case MZ_ZIP_TOO_MANY_FILES: - return "too many files"; - case MZ_ZIP_FILE_TOO_LARGE: - return "file too large"; - case MZ_ZIP_UNSUPPORTED_METHOD: - return "unsupported method"; - case MZ_ZIP_UNSUPPORTED_ENCRYPTION: - return "unsupported encryption"; - case MZ_ZIP_UNSUPPORTED_FEATURE: - return "unsupported feature"; - case MZ_ZIP_FAILED_FINDING_CENTRAL_DIR: - return "failed finding central directory"; - case MZ_ZIP_NOT_AN_ARCHIVE: - return "not a ZIP archive"; - case MZ_ZIP_INVALID_HEADER_OR_CORRUPTED: - return "invalid header or archive is corrupted"; - case MZ_ZIP_UNSUPPORTED_MULTIDISK: - return "unsupported multidisk archive"; - case MZ_ZIP_DECOMPRESSION_FAILED: - return "decompression failed or archive is corrupted"; - case MZ_ZIP_COMPRESSION_FAILED: - return "compression failed"; - case MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE: - return "unexpected decompressed size"; - case MZ_ZIP_CRC_CHECK_FAILED: - return "CRC-32 check failed"; - case MZ_ZIP_UNSUPPORTED_CDIR_SIZE: - return "unsupported central directory size"; - case MZ_ZIP_ALLOC_FAILED: - return "allocation failed"; - case MZ_ZIP_FILE_OPEN_FAILED: - return "file open failed"; - case MZ_ZIP_FILE_CREATE_FAILED: - return "file create failed"; - case MZ_ZIP_FILE_WRITE_FAILED: - return "file write failed"; - case MZ_ZIP_FILE_READ_FAILED: - return "file read failed"; - case MZ_ZIP_FILE_CLOSE_FAILED: - return "file close failed"; - case MZ_ZIP_FILE_SEEK_FAILED: - return "file seek failed"; - case MZ_ZIP_FILE_STAT_FAILED: - return "file stat failed"; - case MZ_ZIP_INVALID_PARAMETER: - return "invalid parameter"; - case MZ_ZIP_INVALID_FILENAME: - return "invalid filename"; - case MZ_ZIP_BUF_TOO_SMALL: - return "buffer too small"; - case MZ_ZIP_INTERNAL_ERROR: - return "internal error"; - case MZ_ZIP_FILE_NOT_FOUND: - return "file not found"; - case MZ_ZIP_ARCHIVE_TOO_LARGE: - return "archive is too large"; - case MZ_ZIP_VALIDATION_FAILED: - return "validation failed"; - case MZ_ZIP_WRITE_CALLBACK_FAILED: - return "write callback failed"; - case MZ_ZIP_TOTAL_ERRORS: - return "total errors"; - default: - break; - } - - return "unknown error"; -} - -/* Note: Just because the archive is not zip64 doesn't necessarily mean it - * doesn't have Zip64 extended information extra field, argh. */ -mz_bool mz_zip_is_zip64(mz_zip_archive *pZip) { - if ((!pZip) || (!pZip->m_pState)) - return MZ_FALSE; - - return pZip->m_pState->m_zip64; -} - -size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip) { - if ((!pZip) || (!pZip->m_pState)) - return 0; - - return pZip->m_pState->m_central_dir.m_size; -} - -mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip) { - return pZip ? pZip->m_total_files : 0; -} - -mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip) { - if (!pZip) - return 0; - return pZip->m_archive_size; -} - -mz_uint64 mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip) { - if ((!pZip) || (!pZip->m_pState)) - return 0; - return pZip->m_pState->m_file_archive_start_ofs; -} - -MZ_FILE *mz_zip_get_cfile(mz_zip_archive *pZip) { - if ((!pZip) || (!pZip->m_pState)) - return 0; - return pZip->m_pState->m_pFile; -} - -size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, - void *pBuf, size_t n) { - if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pZip->m_pRead)) - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - - return pZip->m_pRead(pZip->m_pIO_opaque, file_ofs, pBuf, n); -} - -mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, - char *pFilename, mz_uint filename_buf_size) { - mz_uint n; - const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index); - if (!p) { - if (filename_buf_size) - pFilename[0] = '\0'; - mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); - return 0; - } - n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); - if (filename_buf_size) { - n = MZ_MIN(n, filename_buf_size - 1); - memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); - pFilename[n] = '\0'; - } - return n + 1; -} - -mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, - mz_zip_archive_file_stat *pStat) { - return mz_zip_file_stat_internal( - pZip, file_index, mz_zip_get_cdh(pZip, file_index), pStat, NULL); -} - -mz_bool mz_zip_end(mz_zip_archive *pZip) { - if (!pZip) - return MZ_FALSE; - - if (pZip->m_zip_mode == MZ_ZIP_MODE_READING) - return mz_zip_reader_end(pZip); -#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS - else if ((pZip->m_zip_mode == MZ_ZIP_MODE_WRITING) || - (pZip->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)) - return mz_zip_writer_end(pZip); -#endif - - return MZ_FALSE; -} - -#ifdef __cplusplus -} -#endif - -#endif /*#ifndef MINIZ_NO_ARCHIVE_APIS*/ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/zip/zip.cpp b/presentation/src/main/cpp/third_party/rlottie/src/lottie/zip/zip.cpp deleted file mode 100644 index d5054c1c..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/zip/zip.cpp +++ /dev/null @@ -1,451 +0,0 @@ -/* - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#define __STDC_WANT_LIB_EXT1__ 1 - -#include -#include -#include - -#if defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER) || \ - defined(__MINGW32__) -/* Win32, DOS, MSVC, MSVS */ -#include - -#define STRCLONE(STR) ((STR) ? _strdup(STR) : NULL) -#define HAS_DEVICE(P) \ - ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) && \ - (P)[1] == ':') -#define FILESYSTEM_PREFIX_LEN(P) (HAS_DEVICE(P) ? 2 : 0) - -#else - -#include // needed for symlink() -#define STRCLONE(STR) ((STR) ? strdup(STR) : NULL) - -#endif - -#ifdef __MINGW32__ -#include -#include -#endif - -#include "miniz.h" -#include "zip.h" - -#ifdef _MSC_VER -#include - -#define ftruncate(fd, sz) (-(_chsize_s((fd), (sz)) != 0)) -#define fileno _fileno -#endif - -#if defined(__TINYC__) && (defined(_WIN32) || defined(_WIN64)) -#include - -#define ftruncate(fd, sz) (-(_chsize_s((fd), (sz)) != 0)) -#define fileno _fileno -#endif - -#ifndef HAS_DEVICE -#define HAS_DEVICE(P) 0 -#endif - -#ifndef FILESYSTEM_PREFIX_LEN -#define FILESYSTEM_PREFIX_LEN(P) 0 -#endif - -#ifndef ISSLASH -#define ISSLASH(C) ((C) == '/' || (C) == '\\') -#endif - -#define CLEANUP(ptr) \ - do { \ - if (ptr) { \ - free((void *)ptr); \ - ptr = NULL; \ - } \ - } while (0) - -#define UNX_IFDIR 0040000 /* Unix directory */ -#define UNX_IFREG 0100000 /* Unix regular file */ -#define UNX_IFSOCK 0140000 /* Unix socket (BSD, not SysV or Amiga) */ -#define UNX_IFLNK 0120000 /* Unix symbolic link (not SysV, Amiga) */ -#define UNX_IFBLK 0060000 /* Unix block special (not Amiga) */ -#define UNX_IFCHR 0020000 /* Unix character special (not Amiga) */ -#define UNX_IFIFO 0010000 /* Unix fifo (BCC, not MSC or Amiga) */ - -struct zip_entry_t { - ssize_t index; - char *name; - mz_uint64 uncomp_size; - mz_uint64 comp_size; - mz_uint32 uncomp_crc32; - mz_uint64 offset; - mz_uint8 header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; - mz_uint64 header_offset; - mz_uint16 method; - mz_zip_writer_add_state state; - tdefl_compressor comp; - mz_uint32 external_attr; - time_t m_time; -}; - -struct zip_t { - mz_zip_archive archive; - mz_uint level; - struct zip_entry_t entry; -}; - -enum zip_modify_t { - MZ_KEEP = 0, - MZ_DELETE = 1, - MZ_MOVE = 2, -}; - -struct zip_entry_mark_t { - ssize_t file_index; - enum zip_modify_t type; - mz_uint64 m_local_header_ofs; - size_t lf_length; -}; - - - -static char *zip_strrpl(const char *str, size_t n, char oldchar, char newchar) { - char c; - size_t i; - char *rpl = (char *)calloc((1 + n), sizeof(char)); - char *begin = rpl; - if (!rpl) { - return NULL; - } - - for (i = 0; (i < n) && (c = *str++); ++i) { - if (c == oldchar) { - c = newchar; - } - *rpl++ = c; - } - - return begin; -} - -static int zip_archive_truncate(mz_zip_archive *pzip) { - mz_zip_internal_state *pState = pzip->m_pState; - mz_uint64 file_size = pzip->m_archive_size; - if ((pzip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem)) { - return 0; - } - if (pzip->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED) { - if (pState->m_pFile) { - int fd = fileno(pState->m_pFile); - return ftruncate(fd, file_size); - } - } - return 0; -} - -static inline void zip_archive_finalize(mz_zip_archive *pzip) { - mz_zip_writer_finalize_archive(pzip); - zip_archive_truncate(pzip); -} - -int zip_entry_openbyindex(struct zip_t *zip, size_t index) { - mz_zip_archive *pZip = NULL; - mz_zip_archive_file_stat stats; - mz_uint namelen; - const mz_uint8 *pHeader; - const char *pFilename; - - if (!zip) { - // zip_t handler is not initialized - return ZIP_ENOINIT; - } - - pZip = &(zip->archive); - if (pZip->m_zip_mode != MZ_ZIP_MODE_READING) { - // open by index requires readonly mode - return ZIP_EINVMODE; - } - - if (index >= (size_t)pZip->m_total_files) { - // index out of range - return ZIP_EINVIDX; - } - - if (!(pHeader = &MZ_ZIP_ARRAY_ELEMENT( - &pZip->m_pState->m_central_dir, mz_uint8, - MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, - mz_uint32, index)))) { - // cannot find header in central directory - return ZIP_ENOHDR; - } - - namelen = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS); - pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; - - /* - .ZIP File Format Specification Version: 6.3.3 - - 4.4.17.1 The name of the file, with optional relative path. - The path stored MUST not contain a drive or - device letter, or a leading slash. All slashes - MUST be forward slashes '/' as opposed to - backwards slashes '\' for compatibility with Amiga - and UNIX file systems etc. If input came from standard - input, there is no file name field. - */ - if (zip->entry.name) { - CLEANUP(zip->entry.name); - } -#ifdef ZIP_RAW_ENTRYNAME - zip->entry.name = STRCLONE(pFilename); -#else - zip->entry.name = zip_strrpl(pFilename, namelen, '\\', '/'); -#endif - - if (!zip->entry.name) { - // local entry name is NULL - return ZIP_EINVENTNAME; - } - - if (!mz_zip_reader_file_stat(pZip, (mz_uint)index, &stats)) { - return ZIP_ENOENT; - } - - zip->entry.index = (ssize_t)index; - zip->entry.comp_size = stats.m_comp_size; - zip->entry.uncomp_size = stats.m_uncomp_size; - zip->entry.uncomp_crc32 = stats.m_crc32; - zip->entry.offset = stats.m_central_dir_ofs; - zip->entry.header_offset = stats.m_local_header_ofs; - zip->entry.method = stats.m_method; - zip->entry.external_attr = stats.m_external_attr; -#ifndef MINIZ_NO_TIME - zip->entry.m_time = stats.m_time; -#endif - - return 0; -} - -int zip_entry_close(struct zip_t *zip) { - mz_zip_archive *pzip = NULL; - mz_uint level; - tdefl_status done; - mz_uint16 entrylen; - mz_uint16 dos_time = 0, dos_date = 0; - int err = 0; - mz_uint8 *pExtra_data = NULL; - mz_uint32 extra_size = 0; - mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE]; - mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64]; - mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64; - - if (!zip) { - // zip_t handler is not initialized - err = ZIP_ENOINIT; - goto cleanup; - } - - pzip = &(zip->archive); - if (pzip->m_zip_mode == MZ_ZIP_MODE_READING) { - goto cleanup; - } - - level = zip->level & 0xF; - if (level) { - done = tdefl_compress_buffer(&(zip->entry.comp), "", 0, TDEFL_FINISH); - if (done != TDEFL_STATUS_DONE && done != TDEFL_STATUS_OKAY) { - // Cannot flush compressed buffer - err = ZIP_ETDEFLBUF; - goto cleanup; - } - zip->entry.comp_size = zip->entry.state.m_comp_size; - zip->entry.offset = zip->entry.state.m_cur_archive_file_ofs; - zip->entry.method = MZ_DEFLATED; - } - - entrylen = (mz_uint16)strlen(zip->entry.name); -#ifndef MINIZ_NO_TIME - mz_zip_time_t_to_dos_time(zip->entry.m_time, &dos_time, &dos_date); -#endif - - MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID); - MZ_WRITE_LE32(local_dir_footer + 4, zip->entry.uncomp_crc32); - MZ_WRITE_LE64(local_dir_footer + 8, zip->entry.comp_size); - MZ_WRITE_LE64(local_dir_footer + 16, zip->entry.uncomp_size); - - if (pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.offset, local_dir_footer, - local_dir_footer_size) != local_dir_footer_size) { - // Cannot write zip entry header - err = ZIP_EWRTHDR; - goto cleanup; - } - zip->entry.offset += local_dir_footer_size; - - pExtra_data = extra_data; - extra_size = mz_zip_writer_create_zip64_extra_data( - extra_data, - (zip->entry.uncomp_size >= MZ_UINT32_MAX) ? &zip->entry.uncomp_size - : NULL, - (zip->entry.comp_size >= MZ_UINT32_MAX) ? &zip->entry.comp_size : NULL, - (zip->entry.header_offset >= MZ_UINT32_MAX) ? &zip->entry.header_offset - : NULL); - - if ((entrylen) && (zip->entry.name[entrylen - 1] == '/') && - !zip->entry.uncomp_size) { - /* Set DOS Subdirectory attribute bit. */ - zip->entry.external_attr |= MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG; - } - - if (!mz_zip_writer_add_to_central_dir( - pzip, zip->entry.name, entrylen, pExtra_data, (mz_uint16)extra_size, - "", 0, zip->entry.uncomp_size, zip->entry.comp_size, - zip->entry.uncomp_crc32, zip->entry.method, - MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8 | - MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR, - dos_time, dos_date, zip->entry.header_offset, - zip->entry.external_attr, NULL, 0)) { - // Cannot write to zip central dir - err = ZIP_EWRTDIR; - goto cleanup; - } - - pzip->m_total_files++; - pzip->m_archive_size = zip->entry.offset; - -cleanup: - if (zip) { - zip->entry.m_time = 0; - CLEANUP(zip->entry.name); - } - return err; -} - -const char *zip_entry_name(struct zip_t *zip) { - if (!zip) { - // zip_t handler is not initialized - return NULL; - } - - return zip->entry.name; -} - -int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize) { - mz_uint level; - mz_zip_archive *pzip = NULL; - tdefl_status status; - - if (!zip) { - // zip_t handler is not initialized - return ZIP_ENOINIT; - } - - pzip = &(zip->archive); - if (buf && bufsize > 0) { - zip->entry.uncomp_size += bufsize; - zip->entry.uncomp_crc32 = (mz_uint32)mz_crc32( - zip->entry.uncomp_crc32, (const mz_uint8 *)buf, bufsize); - - level = zip->level & 0xF; - if (!level) { - if ((pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.offset, buf, - bufsize) != bufsize)) { - // Cannot write buffer - return ZIP_EWRTENT; - } - zip->entry.offset += bufsize; - zip->entry.comp_size += bufsize; - } else { - status = tdefl_compress_buffer(&(zip->entry.comp), buf, bufsize, - TDEFL_NO_FLUSH); - if (status != TDEFL_STATUS_DONE && status != TDEFL_STATUS_OKAY) { - // Cannot compress buffer - return ZIP_ETDEFLBUF; - } - } - } - - return 0; -} - -ssize_t zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize) { - mz_zip_archive *pzip = NULL; - mz_uint idx; - size_t size = 0; - - if (!zip) { - // zip_t handler is not initialized - return (ssize_t)ZIP_ENOINIT; - } - - pzip = &(zip->archive); - if (pzip->m_zip_mode != MZ_ZIP_MODE_READING || - zip->entry.index < (ssize_t)0) { - // the entry is not found or we do not have read access - return (ssize_t)ZIP_ENOENT; - } - - idx = (mz_uint)zip->entry.index; - if (mz_zip_reader_is_file_a_directory(pzip, idx)) { - // the entry is a directory - return (ssize_t)ZIP_EINVENTTYPE; - } - - *buf = mz_zip_reader_extract_to_heap(pzip, idx, &size, 0); - if (*buf && bufsize) { - *bufsize = size; - } - return (ssize_t)size; -} - -struct zip_t *zip_stream_open(const char *stream, size_t size, int level, - char mode) { - struct zip_t *zip = (struct zip_t *)calloc((size_t)1, sizeof(struct zip_t)); - if (!zip) { - return NULL; - } - - if (level < 0) { - level = MZ_DEFAULT_LEVEL; - } - if ((level & 0xF) > MZ_UBER_COMPRESSION) { - // Wrong compression level - goto cleanup; - } - zip->level = (mz_uint)level; - - if ((stream != NULL) && (size > 0) && (mode == 'r')) { - if (!mz_zip_reader_init_mem(&(zip->archive), stream, size, 0)) { - goto cleanup; - } - } else if ((stream == NULL) && (size == 0) && (mode == 'w')) { - // Create a new archive. - if (!mz_zip_writer_init_heap(&(zip->archive), 0, 1024)) { - // Cannot initialize zip_archive writer - goto cleanup; - } - } else { - goto cleanup; - } - return zip; - -cleanup: - CLEANUP(zip); - return NULL; -} - -void zip_stream_close(struct zip_t *zip) { - if (zip) { - mz_zip_writer_end(&(zip->archive)); - mz_zip_reader_end(&(zip->archive)); - CLEANUP(zip); - } -} \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/src/lottie/zip/zip.h b/presentation/src/main/cpp/third_party/rlottie/src/lottie/zip/zip.h deleted file mode 100644 index de4d61be..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/lottie/zip/zip.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#pragma once -#ifndef ZIP_H -#define ZIP_H - -#include -#include -#include - -#if !defined(_POSIX_C_SOURCE) && defined(_MSC_VER) -// 64-bit Windows is the only mainstream platform -// where sizeof(long) != sizeof(void*) -#ifdef _WIN64 -typedef long long ssize_t; /* byte count or error */ -#else -typedef long ssize_t; /* byte count or error */ -#endif -#endif - -/** - * Default zip compression level. - */ -#define ZIP_DEFAULT_COMPRESSION_LEVEL 6 - -/** - * Error codes - */ -#define ZIP_ENOINIT -1 // not initialized -#define ZIP_EINVENTNAME -2 // invalid entry name -#define ZIP_ENOENT -3 // entry not found -#define ZIP_EINVMODE -4 // invalid zip mode -#define ZIP_EINVLVL -5 // invalid compression level -#define ZIP_ENOSUP64 -6 // no zip 64 support -#define ZIP_EMEMSET -7 // memset error -#define ZIP_EWRTENT -8 // cannot write data to entry -#define ZIP_ETDEFLINIT -9 // cannot initialize tdefl compressor -#define ZIP_EINVIDX -10 // invalid index -#define ZIP_ENOHDR -11 // header not found -#define ZIP_ETDEFLBUF -12 // cannot flush tdefl buffer -#define ZIP_ECRTHDR -13 // cannot create entry header -#define ZIP_EWRTHDR -14 // cannot write entry header -#define ZIP_EWRTDIR -15 // cannot write to central dir -#define ZIP_EOPNFILE -16 // cannot open file -#define ZIP_EINVENTTYPE -17 // invalid entry type -#define ZIP_EMEMNOALLOC -18 // extracting data using no memory allocation -#define ZIP_ENOFILE -19 // file not found -#define ZIP_ENOPERM -20 // no permission -#define ZIP_EOOMEM -21 // out of memory -#define ZIP_EINVZIPNAME -22 // invalid zip archive name -#define ZIP_EMKDIR -23 // make dir error -#define ZIP_ESYMLINK -24 // symlink error -#define ZIP_ECLSZIP -25 // close archive error -#define ZIP_ECAPSIZE -26 // capacity size too small -#define ZIP_EFSEEK -27 // fseek error -#define ZIP_EFREAD -28 // fread error -#define ZIP_EFWRITE -29 // fwrite error - -/** - * @struct zip_t - * - * This data structure is used throughout the library to represent zip archive - - * forward declaration. - */ -struct zip_t; - -/** - * Closes the zip archive, releases resources - always finalize. - * - * @param zip zip archive handler. - */ -void zip_close(struct zip_t *zip); - -/** - * Opens a new entry by index in the zip archive. - * - * This function is only valid if zip archive was opened in 'r' (readonly) mode. - * - * @param zip zip archive handler. - * @param index index in local dictionary. - * - * @return the return code - 0 on success, negative number (< 0) on error. - */ -int zip_entry_openbyindex(struct zip_t *zip, size_t index); - -/** - * Closes a zip entry, flushes buffer and releases resources. - * - * @param zip zip archive handler. - * - * @return the return code - 0 on success, negative number (< 0) on error. - */ -int zip_entry_close(struct zip_t *zip); - -/** - * Returns a local name of the current zip entry. - * - * The main difference between user's entry name and local entry name - * is optional relative path. - * Following .ZIP File Format Specification - the path stored MUST not contain - * a drive or device letter, or a leading slash. - * All slashes MUST be forward slashes '/' as opposed to backwards slashes '\' - * for compatibility with Amiga and UNIX file systems etc. - * - * @param zip: zip archive handler. - * - * @return the pointer to the current zip entry name, or NULL on error. - */ -const char *zip_entry_name(struct zip_t *zip); - -/** - * Extracts the current zip entry into output buffer. - * - * The function allocates sufficient memory for a output buffer. - * - * @param zip zip archive handler. - * @param buf output buffer. - * @param bufsize output buffer size (in bytes). - * - * @note remember to release memory allocated for a output buffer. - * for large entries, please take a look at zip_entry_extract function. - * - * @return the return code - the number of bytes actually read on success. - * Otherwise a negative number (< 0) on error. - */ -ssize_t zip_entry_read(struct zip_t *zip, void **buf, - size_t *bufsize); -/** - * Opens zip archive stream into memory. - * - * @param stream zip archive stream. - * @param size stream size. - * - * @return the zip archive handler or NULL on error - */ -struct zip_t *zip_stream_open(const char *stream, size_t size, - int level, char mode); - -/** - * Close zip archive releases resources. - * - * @param zip zip archive handler. - * - * @return - */ -void zip_stream_close(struct zip_t *zip); - -#endif diff --git a/presentation/src/main/cpp/third_party/rlottie/src/meson.build b/presentation/src/main/cpp/third_party/rlottie/src/meson.build deleted file mode 100644 index df6ea2ed..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/meson.build +++ /dev/null @@ -1,57 +0,0 @@ -compiler_flags = ['-DRLOTTIE_BUILD'] - -cc = meson.get_compiler('cpp') -if (cc.get_id() != 'msvc') - compiler_flags += ['-fno-exceptions', '-fno-rtti', - '-fno-unwind-tables' , '-fno-asynchronous-unwind-tables', - '-Woverloaded-virtual', '-Wno-unused-parameter'] -endif - -linker_flags = [] -if (host_machine.system() not in ['darwin', 'windows']) - linker_flags += ['-Wl,--version-script=@0@/../rlottie.expmap'.format(meson.current_source_dir())] -endif - -subdir('vector') -subdir('lottie') -subdir('binding') - -rlottie_lib_dep = [ vector_dep, zip_dep, lottie_dep, binding_dep] - -if get_option('thread') == true - rlottie_lib_dep += dependency('threads') -endif - -rlottie_lib = library('rlottie', - include_directories : inc, - version : meson.project_version(), - dependencies : rlottie_lib_dep, - install : true, - cpp_args : compiler_flags, - link_args : linker_flags, - gnu_symbol_visibility : 'hidden', - ) - -# Make rlottie library usable as a Meson subproject. -rlottie_dep = declare_dependency( - include_directories: inc, - link_with : rlottie_lib) - -if (cc.get_id() == 'emscripten') - - subdir('wasm') - - executable('rlottie-wasm', - [], - dependencies : [rlottie_dep, rlottie_wasm_dep], - ) -endif - -pkg_mod = import('pkgconfig') - -pkg_mod.generate( libraries : rlottie_lib, - version : meson.project_version(), - name : 'librlottie', - filebase : 'rlottie', - description : 'A Library for rendering lottie files.' - ) diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/CMakeLists.txt b/presentation/src/main/cpp/third_party/rlottie/src/vector/CMakeLists.txt deleted file mode 100644 index 01bf1636..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -add_subdirectory(freetype) -add_subdirectory(pixman) -add_subdirectory(stb) - - -target_sources(rlottie - PRIVATE - "${CMAKE_CURRENT_LIST_DIR}/vrect.cpp" - "${CMAKE_CURRENT_LIST_DIR}/vdasher.cpp" - "${CMAKE_CURRENT_LIST_DIR}/vbrush.cpp" - "${CMAKE_CURRENT_LIST_DIR}/vbitmap.cpp" - "${CMAKE_CURRENT_LIST_DIR}/vpainter.cpp" - "${CMAKE_CURRENT_LIST_DIR}/vdrawhelper_common.cpp" - "${CMAKE_CURRENT_LIST_DIR}/vdrawhelper.cpp" - "${CMAKE_CURRENT_LIST_DIR}/vdrawhelper_sse2.cpp" - "${CMAKE_CURRENT_LIST_DIR}/vrle.cpp" - "${CMAKE_CURRENT_LIST_DIR}/vpath.cpp" - "${CMAKE_CURRENT_LIST_DIR}/vpathmesure.cpp" - "${CMAKE_CURRENT_LIST_DIR}/vmatrix.cpp" - "${CMAKE_CURRENT_LIST_DIR}/velapsedtimer.cpp" - "${CMAKE_CURRENT_LIST_DIR}/vdebug.cpp" - "${CMAKE_CURRENT_LIST_DIR}/vinterpolator.cpp" - "${CMAKE_CURRENT_LIST_DIR}/vbezier.cpp" - "${CMAKE_CURRENT_LIST_DIR}/vraster.cpp" - "${CMAKE_CURRENT_LIST_DIR}/vdrawable.cpp" - "${CMAKE_CURRENT_LIST_DIR}/vimageloader.cpp" - "${CMAKE_CURRENT_LIST_DIR}/varenaalloc.cpp" - ) - -target_include_directories(rlottie - PRIVATE - "${CMAKE_CURRENT_LIST_DIR}" - ) diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/CMakeLists.txt b/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/CMakeLists.txt deleted file mode 100644 index add0d422..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -target_sources(rlottie - PRIVATE - "${CMAKE_CURRENT_LIST_DIR}/v_ft_math.cpp" - "${CMAKE_CURRENT_LIST_DIR}/v_ft_raster.cpp" - "${CMAKE_CURRENT_LIST_DIR}/v_ft_stroker.cpp" - ) - -target_include_directories(rlottie - PRIVATE - "${CMAKE_CURRENT_LIST_DIR}" - ) diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/meson.build b/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/meson.build deleted file mode 100644 index 7c1217fe..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/meson.build +++ /dev/null @@ -1,11 +0,0 @@ - -source_file = [ - 'v_ft_math.cpp', - 'v_ft_raster.cpp', - 'v_ft_stroker.cpp', - ] - -freetype_dep = declare_dependency( - include_directories : include_directories('.'), - sources : source_file - ) diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_math.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_math.cpp deleted file mode 100644 index a3f0af2e..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_math.cpp +++ /dev/null @@ -1,461 +0,0 @@ -/***************************************************************************/ -/* */ -/* fttrigon.c */ -/* */ -/* FreeType trigonometric functions (body). */ -/* */ -/* Copyright 2001-2005, 2012-2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -#include "v_ft_math.h" -#include - -//form https://github.com/chromium/chromium/blob/59afd8336009c9d97c22854c52e0382b62b3aa5e/third_party/abseil-cpp/absl/base/internal/bits.h - -#if defined(_MSC_VER) -#include -static unsigned int __inline clz(unsigned int x) { - unsigned long r = 0; - if (x != 0) - { - _BitScanReverse(&r, x); - } - return r; -} -#define SW_FT_MSB(x) (clz(x)) -#elif defined(__GNUC__) -#define SW_FT_MSB(x) (31 - __builtin_clz(x)) -#else -static unsigned int __inline clz(unsigned int x) { - int c = 31; - x &= ~x + 1; - if (n & 0x0000FFFF) c -= 16; - if (n & 0x00FF00FF) c -= 8; - if (n & 0x0F0F0F0F) c -= 4; - if (n & 0x33333333) c -= 2; - if (n & 0x55555555) c -= 1; - return c; -} -#define SW_FT_MSB(x) (clz(x)) -#endif - - - - - -#define SW_FT_PAD_FLOOR(x, n) ((x) & ~((n)-1)) -#define SW_FT_PAD_ROUND(x, n) SW_FT_PAD_FLOOR((x) + ((n) / 2), n) -#define SW_FT_PAD_CEIL(x, n) SW_FT_PAD_FLOOR((x) + ((n)-1), n) - -#define SW_FT_BEGIN_STMNT do { -#define SW_FT_END_STMNT \ - } \ - while (0) -/* transfer sign leaving a positive number */ -#define SW_FT_MOVE_SIGN(x, s) \ - SW_FT_BEGIN_STMNT \ - if (x < 0) { \ - x = -x; \ - s = -s; \ - } \ - SW_FT_END_STMNT - -SW_FT_Long SW_FT_MulFix(SW_FT_Long a, SW_FT_Long b) -{ - SW_FT_Int s = 1; - SW_FT_Long c; - - SW_FT_MOVE_SIGN(a, s); - SW_FT_MOVE_SIGN(b, s); - - c = (SW_FT_Long)(((SW_FT_Int64)a * b + 0x8000L) >> 16); - - return (s > 0) ? c : -c; -} - -SW_FT_Long SW_FT_MulDiv(SW_FT_Long a, SW_FT_Long b, SW_FT_Long c) -{ - SW_FT_Int s = 1; - SW_FT_Long d; - - SW_FT_MOVE_SIGN(a, s); - SW_FT_MOVE_SIGN(b, s); - SW_FT_MOVE_SIGN(c, s); - - d = (SW_FT_Long)(c > 0 ? ((SW_FT_Int64)a * b + (c >> 1)) / c : 0x7FFFFFFFL); - - return (s > 0) ? d : -d; -} - -SW_FT_Long SW_FT_DivFix(SW_FT_Long a, SW_FT_Long b) -{ - SW_FT_Int s = 1; - SW_FT_Long q; - - SW_FT_MOVE_SIGN(a, s); - SW_FT_MOVE_SIGN(b, s); - - q = (SW_FT_Long)(b > 0 ? (((SW_FT_UInt64)a << 16) + (b >> 1)) / b - : 0x7FFFFFFFL); - - return (s < 0 ? -q : q); -} - -/*************************************************************************/ -/* */ -/* This is a fixed-point CORDIC implementation of trigonometric */ -/* functions as well as transformations between Cartesian and polar */ -/* coordinates. The angles are represented as 16.16 fixed-point values */ -/* in degrees, i.e., the angular resolution is 2^-16 degrees. Note that */ -/* only vectors longer than 2^16*180/pi (or at least 22 bits) on a */ -/* discrete Cartesian grid can have the same or better angular */ -/* resolution. Therefore, to maintain this precision, some functions */ -/* require an interim upscaling of the vectors, whereas others operate */ -/* with 24-bit long vectors directly. */ -/* */ -/*************************************************************************/ - -/* the Cordic shrink factor 0.858785336480436 * 2^32 */ -#define SW_FT_TRIG_SCALE 0xDBD95B16UL - -/* the highest bit in overflow-safe vector components, */ -/* MSB of 0.858785336480436 * sqrt(0.5) * 2^30 */ -#define SW_FT_TRIG_SAFE_MSB 29 - -/* this table was generated for SW_FT_PI = 180L << 16, i.e. degrees */ -#define SW_FT_TRIG_MAX_ITERS 23 - -static const SW_FT_Fixed ft_trig_arctan_table[] = { - 1740967L, 919879L, 466945L, 234379L, 117304L, 58666L, 29335L, 14668L, - 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L, 57L, - 29L, 14L, 7L, 4L, 2L, 1L}; - -/* multiply a given value by the CORDIC shrink factor */ -static SW_FT_Fixed ft_trig_downscale(SW_FT_Fixed val) -{ - SW_FT_Fixed s; - SW_FT_Int64 v; - - s = val; - val = SW_FT_ABS(val); - - v = (val * (SW_FT_Int64)SW_FT_TRIG_SCALE) + 0x100000000UL; - val = (SW_FT_Fixed)(v >> 32); - - return (s >= 0) ? val : -val; -} - -/* undefined and never called for zero vector */ -static SW_FT_Int ft_trig_prenorm(SW_FT_Vector* vec) -{ - SW_FT_Pos x, y; - SW_FT_Int shift; - - x = vec->x; - y = vec->y; - - shift = SW_FT_MSB(SW_FT_ABS(x) | SW_FT_ABS(y)); - - if (shift <= SW_FT_TRIG_SAFE_MSB) { - shift = SW_FT_TRIG_SAFE_MSB - shift; - vec->x = (SW_FT_Pos)((SW_FT_ULong)x << shift); - vec->y = (SW_FT_Pos)((SW_FT_ULong)y << shift); - } else { - shift -= SW_FT_TRIG_SAFE_MSB; - vec->x = x >> shift; - vec->y = y >> shift; - shift = -shift; - } - - return shift; -} - -static void ft_trig_pseudo_rotate(SW_FT_Vector* vec, SW_FT_Angle theta) -{ - SW_FT_Int i; - SW_FT_Fixed x, y, xtemp, b; - const SW_FT_Fixed* arctanptr; - - x = vec->x; - y = vec->y; - - /* Rotate inside [-PI/4,PI/4] sector */ - while (theta < -SW_FT_ANGLE_PI4) { - xtemp = y; - y = -x; - x = xtemp; - theta += SW_FT_ANGLE_PI2; - } - - while (theta > SW_FT_ANGLE_PI4) { - xtemp = -y; - y = x; - x = xtemp; - theta -= SW_FT_ANGLE_PI2; - } - - arctanptr = ft_trig_arctan_table; - - /* Pseudorotations, with right shifts */ - for (i = 1, b = 1; i < SW_FT_TRIG_MAX_ITERS; b <<= 1, i++) { - SW_FT_Fixed v1 = ((y + b) >> i); - SW_FT_Fixed v2 = ((x + b) >> i); - if (theta < 0) { - xtemp = x + v1; - y = y - v2; - x = xtemp; - theta += *arctanptr++; - } else { - xtemp = x - v1; - y = y + v2; - x = xtemp; - theta -= *arctanptr++; - } - } - - vec->x = x; - vec->y = y; -} - -static void ft_trig_pseudo_polarize(SW_FT_Vector* vec) -{ - SW_FT_Angle theta; - SW_FT_Int i; - SW_FT_Fixed x, y, xtemp, b; - const SW_FT_Fixed* arctanptr; - - x = vec->x; - y = vec->y; - - /* Get the vector into [-PI/4,PI/4] sector */ - if (y > x) { - if (y > -x) { - theta = SW_FT_ANGLE_PI2; - xtemp = y; - y = -x; - x = xtemp; - } else { - theta = y > 0 ? SW_FT_ANGLE_PI : -SW_FT_ANGLE_PI; - x = -x; - y = -y; - } - } else { - if (y < -x) { - theta = -SW_FT_ANGLE_PI2; - xtemp = -y; - y = x; - x = xtemp; - } else { - theta = 0; - } - } - - arctanptr = ft_trig_arctan_table; - - /* Pseudorotations, with right shifts */ - for (i = 1, b = 1; i < SW_FT_TRIG_MAX_ITERS; b <<= 1, i++) { - SW_FT_Fixed v1 = ((y + b) >> i); - SW_FT_Fixed v2 = ((x + b) >> i); - if (y > 0) { - xtemp = x + v1; - y = y - v2; - x = xtemp; - theta += *arctanptr++; - } else { - xtemp = x - v1; - y = y + v2; - x = xtemp; - theta -= *arctanptr++; - } - } - - /* round theta */ - if (theta >= 0) - theta = SW_FT_PAD_ROUND(theta, 32); - else - theta = -SW_FT_PAD_ROUND(-theta, 32); - - vec->x = x; - vec->y = theta; -} - -/* documentation is in fttrigon.h */ - -SW_FT_Fixed SW_FT_Cos(SW_FT_Angle angle) -{ - SW_FT_Vector v; - - v.x = SW_FT_TRIG_SCALE >> 8; - v.y = 0; - ft_trig_pseudo_rotate(&v, angle); - - return (v.x + 0x80L) >> 8; -} - -/* documentation is in fttrigon.h */ - -SW_FT_Fixed SW_FT_Sin(SW_FT_Angle angle) -{ - return SW_FT_Cos(SW_FT_ANGLE_PI2 - angle); -} - -/* documentation is in fttrigon.h */ - -SW_FT_Fixed SW_FT_Tan(SW_FT_Angle angle) -{ - SW_FT_Vector v; - - v.x = SW_FT_TRIG_SCALE >> 8; - v.y = 0; - ft_trig_pseudo_rotate(&v, angle); - - return SW_FT_DivFix(v.y, v.x); -} - -/* documentation is in fttrigon.h */ - -SW_FT_Angle SW_FT_Atan2(SW_FT_Fixed dx, SW_FT_Fixed dy) -{ - SW_FT_Vector v; - - if (dx == 0 && dy == 0) return 0; - - v.x = dx; - v.y = dy; - ft_trig_prenorm(&v); - ft_trig_pseudo_polarize(&v); - - return v.y; -} - -/* documentation is in fttrigon.h */ - -void SW_FT_Vector_Unit(SW_FT_Vector* vec, SW_FT_Angle angle) -{ - vec->x = SW_FT_TRIG_SCALE >> 8; - vec->y = 0; - ft_trig_pseudo_rotate(vec, angle); - vec->x = (vec->x + 0x80L) >> 8; - vec->y = (vec->y + 0x80L) >> 8; -} - -/* these macros return 0 for positive numbers, - and -1 for negative ones */ -#define SW_FT_SIGN_LONG(x) ((x) >> (SW_FT_SIZEOF_LONG * 8 - 1)) -#define SW_FT_SIGN_INT(x) ((x) >> (SW_FT_SIZEOF_INT * 8 - 1)) -#define SW_FT_SIGN_INT32(x) ((x) >> 31) -#define SW_FT_SIGN_INT16(x) ((x) >> 15) - -/* documentation is in fttrigon.h */ - -void SW_FT_Vector_Rotate(SW_FT_Vector* vec, SW_FT_Angle angle) -{ - SW_FT_Int shift; - SW_FT_Vector v; - - v.x = vec->x; - v.y = vec->y; - - if (angle && (v.x != 0 || v.y != 0)) { - shift = ft_trig_prenorm(&v); - ft_trig_pseudo_rotate(&v, angle); - v.x = ft_trig_downscale(v.x); - v.y = ft_trig_downscale(v.y); - - if (shift > 0) { - SW_FT_Int32 half = (SW_FT_Int32)1L << (shift - 1); - - vec->x = (v.x + half + SW_FT_SIGN_LONG(v.x)) >> shift; - vec->y = (v.y + half + SW_FT_SIGN_LONG(v.y)) >> shift; - } else { - shift = -shift; - vec->x = (SW_FT_Pos)((SW_FT_ULong)v.x << shift); - vec->y = (SW_FT_Pos)((SW_FT_ULong)v.y << shift); - } - } -} - -/* documentation is in fttrigon.h */ - -SW_FT_Fixed SW_FT_Vector_Length(SW_FT_Vector* vec) -{ - SW_FT_Int shift; - SW_FT_Vector v; - - v = *vec; - - /* handle trivial cases */ - if (v.x == 0) { - return SW_FT_ABS(v.y); - } else if (v.y == 0) { - return SW_FT_ABS(v.x); - } - - /* general case */ - shift = ft_trig_prenorm(&v); - ft_trig_pseudo_polarize(&v); - - v.x = ft_trig_downscale(v.x); - - if (shift > 0) return (v.x + (1 << (shift - 1))) >> shift; - - return (SW_FT_Fixed)((SW_FT_UInt32)v.x << -shift); -} - -/* documentation is in fttrigon.h */ - -void SW_FT_Vector_Polarize(SW_FT_Vector* vec, SW_FT_Fixed* length, - SW_FT_Angle* angle) -{ - SW_FT_Int shift; - SW_FT_Vector v; - - v = *vec; - - if (v.x == 0 && v.y == 0) return; - - shift = ft_trig_prenorm(&v); - ft_trig_pseudo_polarize(&v); - - v.x = ft_trig_downscale(v.x); - - *length = (shift >= 0) ? (v.x >> shift) - : (SW_FT_Fixed)((SW_FT_UInt32)v.x << -shift); - *angle = v.y; -} - -/* documentation is in fttrigon.h */ - -void SW_FT_Vector_From_Polar(SW_FT_Vector* vec, SW_FT_Fixed length, - SW_FT_Angle angle) -{ - vec->x = length; - vec->y = 0; - - SW_FT_Vector_Rotate(vec, angle); -} - -/* documentation is in fttrigon.h */ - -SW_FT_Angle SW_FT_Angle_Diff( SW_FT_Angle angle1, SW_FT_Angle angle2 ) -{ - SW_FT_Angle delta = angle2 - angle1; - - while ( delta <= -SW_FT_ANGLE_PI ) - delta += SW_FT_ANGLE_2PI; - - while ( delta > SW_FT_ANGLE_PI ) - delta -= SW_FT_ANGLE_2PI; - - return delta; -} - -/* END */ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_math.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_math.h deleted file mode 100644 index b4611d8d..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_math.h +++ /dev/null @@ -1,438 +0,0 @@ -#ifndef V_FT_MATH_H -#define V_FT_MATH_H - -/***************************************************************************/ -/* */ -/* fttrigon.h */ -/* */ -/* FreeType trigonometric functions (specification). */ -/* */ -/* Copyright 2001, 2003, 2005, 2007, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -#include "v_ft_types.h" - - -/*************************************************************************/ -/* */ -/* The min and max functions missing in C. As usual, be careful not to */ -/* write things like SW_FT_MIN( a++, b++ ) to avoid side effects. */ -/* */ -#define SW_FT_MIN( a, b ) ( (a) < (b) ? (a) : (b) ) -#define SW_FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) ) - -#define SW_FT_ABS( a ) ( (a) < 0 ? -(a) : (a) ) - -/* - * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min' - * algorithm. We use alpha = 1, beta = 3/8, giving us results with a - * largest error less than 7% compared to the exact value. - */ -#define SW_FT_HYPOT( x, y ) \ - ( x = SW_FT_ABS( x ), \ - y = SW_FT_ABS( y ), \ - x > y ? x + ( 3 * y >> 3 ) \ - : y + ( 3 * x >> 3 ) ) - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_MulFix */ -/* */ -/* */ -/* A very simple function used to perform the computation */ -/* `(a*b)/0x10000' with maximum accuracy. Most of the time this is */ -/* used to multiply a given value by a 16.16 fixed-point factor. */ -/* */ -/* */ -/* a :: The first multiplier. */ -/* b :: The second multiplier. Use a 16.16 factor here whenever */ -/* possible (see note below). */ -/* */ -/* */ -/* The result of `(a*b)/0x10000'. */ -/* */ -/* */ -/* This function has been optimized for the case where the absolute */ -/* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */ -/* As this happens mainly when scaling from notional units to */ -/* fractional pixels in FreeType, it resulted in noticeable speed */ -/* improvements between versions 2.x and 1.x. */ -/* */ -/* As a conclusion, always try to place a 16.16 factor as the */ -/* _second_ argument of this function; this can make a great */ -/* difference. */ -/* */ -SW_FT_Long -SW_FT_MulFix( SW_FT_Long a, - SW_FT_Long b ); - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_MulDiv */ -/* */ -/* */ -/* A very simple function used to perform the computation `(a*b)/c' */ -/* with maximum accuracy (it uses a 64-bit intermediate integer */ -/* whenever necessary). */ -/* */ -/* This function isn't necessarily as fast as some processor specific */ -/* operations, but is at least completely portable. */ -/* */ -/* */ -/* a :: The first multiplier. */ -/* b :: The second multiplier. */ -/* c :: The divisor. */ -/* */ -/* */ -/* The result of `(a*b)/c'. This function never traps when trying to */ -/* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ -/* on the signs of `a' and `b'. */ -/* */ -SW_FT_Long -SW_FT_MulDiv( SW_FT_Long a, - SW_FT_Long b, - SW_FT_Long c ); - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_DivFix */ -/* */ -/* */ -/* A very simple function used to perform the computation */ -/* `(a*0x10000)/b' with maximum accuracy. Most of the time, this is */ -/* used to divide a given value by a 16.16 fixed-point factor. */ -/* */ -/* */ -/* a :: The numerator. */ -/* b :: The denominator. Use a 16.16 factor here. */ -/* */ -/* */ -/* The result of `(a*0x10000)/b'. */ -/* */ -SW_FT_Long -SW_FT_DivFix( SW_FT_Long a, - SW_FT_Long b ); - - - - /*************************************************************************/ - /* */ - /*
*/ - /* computations */ - /* */ - /*************************************************************************/ - - - /************************************************************************* - * - * @type: - * SW_FT_Angle - * - * @description: - * This type is used to model angle values in FreeType. Note that the - * angle is a 16.16 fixed-point value expressed in degrees. - * - */ - typedef SW_FT_Fixed SW_FT_Angle; - - - /************************************************************************* - * - * @macro: - * SW_FT_ANGLE_PI - * - * @description: - * The angle pi expressed in @SW_FT_Angle units. - * - */ -#define SW_FT_ANGLE_PI ( 180L << 16 ) - - - /************************************************************************* - * - * @macro: - * SW_FT_ANGLE_2PI - * - * @description: - * The angle 2*pi expressed in @SW_FT_Angle units. - * - */ -#define SW_FT_ANGLE_2PI ( SW_FT_ANGLE_PI * 2 ) - - - /************************************************************************* - * - * @macro: - * SW_FT_ANGLE_PI2 - * - * @description: - * The angle pi/2 expressed in @SW_FT_Angle units. - * - */ -#define SW_FT_ANGLE_PI2 ( SW_FT_ANGLE_PI / 2 ) - - - /************************************************************************* - * - * @macro: - * SW_FT_ANGLE_PI4 - * - * @description: - * The angle pi/4 expressed in @SW_FT_Angle units. - * - */ -#define SW_FT_ANGLE_PI4 ( SW_FT_ANGLE_PI / 4 ) - - - /************************************************************************* - * - * @function: - * SW_FT_Sin - * - * @description: - * Return the sinus of a given angle in fixed-point format. - * - * @input: - * angle :: - * The input angle. - * - * @return: - * The sinus value. - * - * @note: - * If you need both the sinus and cosinus for a given angle, use the - * function @SW_FT_Vector_Unit. - * - */ - SW_FT_Fixed - SW_FT_Sin( SW_FT_Angle angle ); - - - /************************************************************************* - * - * @function: - * SW_FT_Cos - * - * @description: - * Return the cosinus of a given angle in fixed-point format. - * - * @input: - * angle :: - * The input angle. - * - * @return: - * The cosinus value. - * - * @note: - * If you need both the sinus and cosinus for a given angle, use the - * function @SW_FT_Vector_Unit. - * - */ - SW_FT_Fixed - SW_FT_Cos( SW_FT_Angle angle ); - - - /************************************************************************* - * - * @function: - * SW_FT_Tan - * - * @description: - * Return the tangent of a given angle in fixed-point format. - * - * @input: - * angle :: - * The input angle. - * - * @return: - * The tangent value. - * - */ - SW_FT_Fixed - SW_FT_Tan( SW_FT_Angle angle ); - - - /************************************************************************* - * - * @function: - * SW_FT_Atan2 - * - * @description: - * Return the arc-tangent corresponding to a given vector (x,y) in - * the 2d plane. - * - * @input: - * x :: - * The horizontal vector coordinate. - * - * y :: - * The vertical vector coordinate. - * - * @return: - * The arc-tangent value (i.e. angle). - * - */ - SW_FT_Angle - SW_FT_Atan2( SW_FT_Fixed x, - SW_FT_Fixed y ); - - - /************************************************************************* - * - * @function: - * SW_FT_Angle_Diff - * - * @description: - * Return the difference between two angles. The result is always - * constrained to the ]-PI..PI] interval. - * - * @input: - * angle1 :: - * First angle. - * - * angle2 :: - * Second angle. - * - * @return: - * Constrained value of `value2-value1'. - * - */ - SW_FT_Angle - SW_FT_Angle_Diff( SW_FT_Angle angle1, - SW_FT_Angle angle2 ); - - - /************************************************************************* - * - * @function: - * SW_FT_Vector_Unit - * - * @description: - * Return the unit vector corresponding to a given angle. After the - * call, the value of `vec.x' will be `sin(angle)', and the value of - * `vec.y' will be `cos(angle)'. - * - * This function is useful to retrieve both the sinus and cosinus of a - * given angle quickly. - * - * @output: - * vec :: - * The address of target vector. - * - * @input: - * angle :: - * The input angle. - * - */ - void - SW_FT_Vector_Unit( SW_FT_Vector* vec, - SW_FT_Angle angle ); - - - /************************************************************************* - * - * @function: - * SW_FT_Vector_Rotate - * - * @description: - * Rotate a vector by a given angle. - * - * @inout: - * vec :: - * The address of target vector. - * - * @input: - * angle :: - * The input angle. - * - */ - void - SW_FT_Vector_Rotate( SW_FT_Vector* vec, - SW_FT_Angle angle ); - - - /************************************************************************* - * - * @function: - * SW_FT_Vector_Length - * - * @description: - * Return the length of a given vector. - * - * @input: - * vec :: - * The address of target vector. - * - * @return: - * The vector length, expressed in the same units that the original - * vector coordinates. - * - */ - SW_FT_Fixed - SW_FT_Vector_Length( SW_FT_Vector* vec ); - - - /************************************************************************* - * - * @function: - * SW_FT_Vector_Polarize - * - * @description: - * Compute both the length and angle of a given vector. - * - * @input: - * vec :: - * The address of source vector. - * - * @output: - * length :: - * The vector length. - * - * angle :: - * The vector angle. - * - */ - void - SW_FT_Vector_Polarize( SW_FT_Vector* vec, - SW_FT_Fixed *length, - SW_FT_Angle *angle ); - - - /************************************************************************* - * - * @function: - * SW_FT_Vector_From_Polar - * - * @description: - * Compute vector coordinates from a length and angle. - * - * @output: - * vec :: - * The address of source vector. - * - * @input: - * length :: - * The vector length. - * - * angle :: - * The vector angle. - * - */ - void - SW_FT_Vector_From_Polar( SW_FT_Vector* vec, - SW_FT_Fixed length, - SW_FT_Angle angle ); - - -#endif // V_FT_MATH_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_raster.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_raster.cpp deleted file mode 100644 index 24b0d427..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_raster.cpp +++ /dev/null @@ -1,1428 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftgrays.c */ -/* */ -/* A new `perfect' anti-aliasing renderer (body). */ -/* */ -/* Copyright 2000-2003, 2005-2014 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/*************************************************************************/ -/* */ -/* This is a new anti-aliasing scan-converter for FreeType 2. The */ -/* algorithm used here is _very_ different from the one in the standard */ -/* `ftraster' module. Actually, `ftgrays' computes the _exact_ */ -/* coverage of the outline on each pixel cell. */ -/* */ -/* It is based on ideas that I initially found in Raph Levien's */ -/* excellent LibArt graphics library (see http://www.levien.com/libart */ -/* for more information, though the web pages do not tell anything */ -/* about the renderer; you'll have to dive into the source code to */ -/* understand how it works). */ -/* */ -/* Note, however, that this is a _very_ different implementation */ -/* compared to Raph's. Coverage information is stored in a very */ -/* different way, and I don't use sorted vector paths. Also, it doesn't */ -/* use floating point values. */ -/* */ -/* This renderer has the following advantages: */ -/* */ -/* - It doesn't need an intermediate bitmap. Instead, one can supply a */ -/* callback function that will be called by the renderer to draw gray */ -/* spans on any target surface. You can thus do direct composition on */ -/* any kind of bitmap, provided that you give the renderer the right */ -/* callback. */ -/* */ -/* - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on */ -/* each pixel cell. */ -/* */ -/* - It performs a single pass on the outline (the `standard' FT2 */ -/* renderer makes two passes). */ -/* */ -/* - It can easily be modified to render to _any_ number of gray levels */ -/* cheaply. */ -/* */ -/* - For small (< 20) pixel sizes, it is faster than the standard */ -/* renderer. */ -/* */ -/*************************************************************************/ - -#include "v_ft_raster.h" -#include "v_ft_math.h" - -/* Auxiliary macros for token concatenation. */ -#define SW_FT_ERR_XCAT(x, y) x##y -#define SW_FT_ERR_CAT(x, y) SW_FT_ERR_XCAT(x, y) - -#define SW_FT_BEGIN_STMNT do { -#define SW_FT_END_STMNT \ - } \ - while (0) - -#include -#include -#include -#include -#define SW_FT_UINT_MAX UINT_MAX -#define SW_FT_INT_MAX INT_MAX -#define SW_FT_ULONG_MAX ULONG_MAX -#define SW_FT_CHAR_BIT CHAR_BIT - -#define ft_memset memset - -#define ft_setjmp setjmp -#define ft_longjmp longjmp -#define ft_jmp_buf jmp_buf - -typedef ptrdiff_t SW_FT_PtrDist; - -#define ErrRaster_Invalid_Mode -2 -#define ErrRaster_Invalid_Outline -1 -#define ErrRaster_Invalid_Argument -3 -#define ErrRaster_Memory_Overflow -4 - -#define SW_FT_BEGIN_HEADER -#define SW_FT_END_HEADER - -/* This macro is used to indicate that a function parameter is unused. */ -/* Its purpose is simply to reduce compiler warnings. Note also that */ -/* simply defining it as `(void)x' doesn't avoid warnings with certain */ -/* ANSI compilers (e.g. LCC). */ -#define SW_FT_UNUSED(x) (x) = (x) - -#define SW_FT_THROW(e) SW_FT_ERR_CAT(ErrRaster_, e) - -/* The size in bytes of the render pool used by the scan-line converter */ -/* to do all of its work. */ -#define SW_FT_RENDER_POOL_SIZE 16384L - -typedef int (*SW_FT_Outline_MoveToFunc)(const SW_FT_Vector* to, void* user); - -#define SW_FT_Outline_MoveTo_Func SW_FT_Outline_MoveToFunc - -typedef int (*SW_FT_Outline_LineToFunc)(const SW_FT_Vector* to, void* user); - -#define SW_FT_Outline_LineTo_Func SW_FT_Outline_LineToFunc - -typedef int (*SW_FT_Outline_ConicToFunc)(const SW_FT_Vector* control, - const SW_FT_Vector* to, void* user); - -#define SW_FT_Outline_ConicTo_Func SW_FT_Outline_ConicToFunc - -typedef int (*SW_FT_Outline_CubicToFunc)(const SW_FT_Vector* control1, - const SW_FT_Vector* control2, - const SW_FT_Vector* to, void* user); - -#define SW_FT_Outline_CubicTo_Func SW_FT_Outline_CubicToFunc - -typedef struct SW_FT_Outline_Funcs_ { - SW_FT_Outline_MoveToFunc move_to; - SW_FT_Outline_LineToFunc line_to; - SW_FT_Outline_ConicToFunc conic_to; - SW_FT_Outline_CubicToFunc cubic_to; - - int shift; - SW_FT_Pos delta; - -} SW_FT_Outline_Funcs; - -#define SW_FT_DEFINE_OUTLINE_FUNCS(class_, move_to_, line_to_, conic_to_, \ - cubic_to_, shift_, delta_) \ - static const SW_FT_Outline_Funcs class_ = {move_to_, line_to_, conic_to_, \ - cubic_to_, shift_, delta_}; - -#define SW_FT_DEFINE_RASTER_FUNCS(class_, raster_new_, raster_reset_, \ - raster_render_, raster_done_) \ - const SW_FT_Raster_Funcs class_ = {raster_new_, raster_reset_, \ - raster_render_, raster_done_}; - -#ifndef SW_FT_MEM_SET -#define SW_FT_MEM_SET(d, s, c) ft_memset(d, s, c) -#endif - -#ifndef SW_FT_MEM_ZERO -#define SW_FT_MEM_ZERO(dest, count) SW_FT_MEM_SET(dest, 0, count) -#endif - -/* as usual, for the speed hungry :-) */ - -#undef RAS_ARG -#undef RAS_ARG_ -#undef RAS_VAR -#undef RAS_VAR_ - -#ifndef SW_FT_STATIC_RASTER - -#define RAS_ARG gray_PWorker worker -#define RAS_ARG_ gray_PWorker worker, - -#define RAS_VAR worker -#define RAS_VAR_ worker, - -#else /* SW_FT_STATIC_RASTER */ - -#define RAS_ARG /* empty */ -#define RAS_ARG_ /* empty */ -#define RAS_VAR /* empty */ -#define RAS_VAR_ /* empty */ - -#endif /* SW_FT_STATIC_RASTER */ - -/* must be at least 6 bits! */ -#define PIXEL_BITS 8 - -#undef FLOOR -#undef CEILING -#undef TRUNC -#undef SCALED - -#define ONE_PIXEL (1L << PIXEL_BITS) -#define PIXEL_MASK (-1L << PIXEL_BITS) -#define TRUNC(x) ((TCoord)((x) >> PIXEL_BITS)) -#define SUBPIXELS(x) ((TPos)(x) << PIXEL_BITS) -#define FLOOR(x) ((x) & -ONE_PIXEL) -#define CEILING(x) (((x) + ONE_PIXEL - 1) & -ONE_PIXEL) -#define ROUND(x) (((x) + ONE_PIXEL / 2) & -ONE_PIXEL) - -#if PIXEL_BITS >= 6 -#define UPSCALE(x) ((x) << (PIXEL_BITS - 6)) -#define DOWNSCALE(x) ((x) >> (PIXEL_BITS - 6)) -#else -#define UPSCALE(x) ((x) >> (6 - PIXEL_BITS)) -#define DOWNSCALE(x) ((x) << (6 - PIXEL_BITS)) -#endif - -/* Compute `dividend / divisor' and return both its quotient and */ -/* remainder, cast to a specific type. This macro also ensures that */ -/* the remainder is always positive. */ -#define SW_FT_DIV_MOD(type, dividend, divisor, quotient, remainder) \ - SW_FT_BEGIN_STMNT(quotient) = (type)((dividend) / (divisor)); \ - (remainder) = (type)((dividend) % (divisor)); \ - if ((remainder) < 0) { \ - (quotient)--; \ - (remainder) += (type)(divisor); \ - } \ - SW_FT_END_STMNT - -#ifdef __arm__ -/* Work around a bug specific to GCC which make the compiler fail to */ -/* optimize a division and modulo operation on the same parameters */ -/* into a single call to `__aeabi_idivmod'. See */ -/* */ -/* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43721 */ -#undef SW_FT_DIV_MOD -#define SW_FT_DIV_MOD(type, dividend, divisor, quotient, remainder) \ - SW_FT_BEGIN_STMNT(quotient) = (type)((dividend) / (divisor)); \ - (remainder) = (type)((dividend) - (quotient) * (divisor)); \ - if ((remainder) < 0) { \ - (quotient)--; \ - (remainder) += (type)(divisor); \ - } \ - SW_FT_END_STMNT -#endif /* __arm__ */ - -/* These macros speed up repetitive divisions by replacing them */ -/* with multiplications and right shifts. */ -#define SW_FT_UDIVPREP(b) \ - long b##_r = (long)(SW_FT_ULONG_MAX >> PIXEL_BITS) / (b) -#define SW_FT_UDIV(a, b) \ - (((unsigned long)(a) * (unsigned long)(b##_r)) >> \ - (sizeof(long) * SW_FT_CHAR_BIT - PIXEL_BITS)) - -/*************************************************************************/ -/* */ -/* TYPE DEFINITIONS */ -/* */ - -/* don't change the following types to SW_FT_Int or SW_FT_Pos, since we might */ -/* need to define them to "float" or "double" when experimenting with */ -/* new algorithms */ - -typedef long TCoord; /* integer scanline/pixel coordinate */ -typedef long TPos; /* sub-pixel coordinate */ - -/* determine the type used to store cell areas. This normally takes at */ -/* least PIXEL_BITS*2 + 1 bits. On 16-bit systems, we need to use */ -/* `long' instead of `int', otherwise bad things happen */ - -#if PIXEL_BITS <= 7 - -typedef int TArea; - -#else /* PIXEL_BITS >= 8 */ - -/* approximately determine the size of integers using an ANSI-C header */ -#if SW_FT_UINT_MAX == 0xFFFFU -typedef long TArea; -#else -typedef int TArea; -#endif - -#endif /* PIXEL_BITS >= 8 */ - -/* maximum number of gray spans in a call to the span callback */ -#define SW_FT_MAX_GRAY_SPANS 256 - -typedef struct TCell_* PCell; - -typedef struct TCell_ { - TPos x; /* same with gray_TWorker.ex */ - TCoord cover; /* same with gray_TWorker.cover */ - TArea area; - PCell next; - -} TCell; - -#if defined(_MSC_VER) /* Visual C++ (and Intel C++) */ -/* We disable the warning `structure was padded due to */ -/* __declspec(align())' in order to compile cleanly with */ -/* the maximum level of warnings. */ -#pragma warning(push) -#pragma warning(disable : 4324) -#endif /* _MSC_VER */ - -typedef struct gray_TWorker_ { - TCoord ex, ey; - TPos min_ex, max_ex; - TPos min_ey, max_ey; - TPos count_ex, count_ey; - - TArea area; - TCoord cover; - int invalid; - - PCell cells; - SW_FT_PtrDist max_cells; - SW_FT_PtrDist num_cells; - - TPos x, y; - - SW_FT_Vector bez_stack[32 * 3 + 1]; - int lev_stack[32]; - - SW_FT_Outline outline; - SW_FT_BBox clip_box; - - int bound_left; - int bound_top; - int bound_right; - int bound_bottom; - - SW_FT_Span gray_spans[SW_FT_MAX_GRAY_SPANS]; - int num_gray_spans; - - SW_FT_Raster_Span_Func render_span; - void* render_span_data; - - int band_size; - int band_shoot; - - ft_jmp_buf jump_buffer; - - void* buffer; - long buffer_size; - - PCell* ycells; - TPos ycount; - -} gray_TWorker, *gray_PWorker; - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - -#ifndef SW_FT_STATIC_RASTER -#define ras (*worker) -#else -static gray_TWorker ras; -#endif - -typedef struct gray_TRaster_ { - void* memory; - -} gray_TRaster, *gray_PRaster; - -/*************************************************************************/ -/* */ -/* Initialize the cells table. */ -/* */ -static void gray_init_cells(RAS_ARG_ void* buffer, long byte_size) -{ - ras.buffer = buffer; - ras.buffer_size = byte_size; - - ras.ycells = (PCell*)buffer; - ras.cells = NULL; - ras.max_cells = 0; - ras.num_cells = 0; - ras.area = 0; - ras.cover = 0; - ras.invalid = 1; - - ras.bound_left = INT_MAX; - ras.bound_top = INT_MAX; - ras.bound_right = INT_MIN; - ras.bound_bottom = INT_MIN; -} - -/*************************************************************************/ -/* */ -/* Compute the outline bounding box. */ -/* */ -static void gray_compute_cbox(RAS_ARG) -{ - SW_FT_Outline* outline = &ras.outline; - SW_FT_Vector* vec = outline->points; - SW_FT_Vector* limit = vec + outline->n_points; - - if (outline->n_points <= 0) { - ras.min_ex = ras.max_ex = 0; - ras.min_ey = ras.max_ey = 0; - return; - } - - ras.min_ex = ras.max_ex = vec->x; - ras.min_ey = ras.max_ey = vec->y; - - vec++; - - for (; vec < limit; vec++) { - TPos x = vec->x; - TPos y = vec->y; - - if (x < ras.min_ex) ras.min_ex = x; - if (x > ras.max_ex) ras.max_ex = x; - if (y < ras.min_ey) ras.min_ey = y; - if (y > ras.max_ey) ras.max_ey = y; - } - - /* truncate the bounding box to integer pixels */ - ras.min_ex = ras.min_ex >> 6; - ras.min_ey = ras.min_ey >> 6; - ras.max_ex = (ras.max_ex + 63) >> 6; - ras.max_ey = (ras.max_ey + 63) >> 6; -} - -/*************************************************************************/ -/* */ -/* Record the current cell in the table. */ -/* */ -static PCell gray_find_cell(RAS_ARG) -{ - PCell *pcell, cell; - TPos x = ras.ex; - - if (x > ras.count_ex) x = ras.count_ex; - - pcell = &ras.ycells[ras.ey]; - for (;;) { - cell = *pcell; - if (cell == NULL || cell->x > x) break; - - if (cell->x == x) goto Exit; - - pcell = &cell->next; - } - - if (ras.num_cells >= ras.max_cells) ft_longjmp(ras.jump_buffer, 1); - - cell = ras.cells + ras.num_cells++; - cell->x = x; - cell->area = 0; - cell->cover = 0; - - cell->next = *pcell; - *pcell = cell; - -Exit: - return cell; -} - -static void gray_record_cell(RAS_ARG) -{ - if (ras.area | ras.cover) { - PCell cell = gray_find_cell(RAS_VAR); - - cell->area += ras.area; - cell->cover += ras.cover; - } -} - -/*************************************************************************/ -/* */ -/* Set the current cell to a new position. */ -/* */ -static void gray_set_cell(RAS_ARG_ TCoord ex, TCoord ey) -{ - /* Move the cell pointer to a new position. We set the `invalid' */ - /* flag to indicate that the cell isn't part of those we're interested */ - /* in during the render phase. This means that: */ - /* */ - /* . the new vertical position must be within min_ey..max_ey-1. */ - /* . the new horizontal position must be strictly less than max_ex */ - /* */ - /* Note that if a cell is to the left of the clipping region, it is */ - /* actually set to the (min_ex-1) horizontal position. */ - - /* All cells that are on the left of the clipping region go to the */ - /* min_ex - 1 horizontal position. */ - ey -= ras.min_ey; - - if (ex > ras.max_ex) ex = ras.max_ex; - - ex -= ras.min_ex; - if (ex < 0) ex = -1; - - /* are we moving to a different cell ? */ - if (ex != ras.ex || ey != ras.ey) { - /* record the current one if it is valid */ - if (!ras.invalid) gray_record_cell(RAS_VAR); - - ras.area = 0; - ras.cover = 0; - ras.ex = ex; - ras.ey = ey; - } - - ras.invalid = - ((unsigned)ey >= (unsigned)ras.count_ey || ex >= ras.count_ex); -} - -/*************************************************************************/ -/* */ -/* Start a new contour at a given cell. */ -/* */ -static void gray_start_cell(RAS_ARG_ TCoord ex, TCoord ey) -{ - if (ex > ras.max_ex) ex = (TCoord)(ras.max_ex); - - if (ex < ras.min_ex) ex = (TCoord)(ras.min_ex - 1); - - ras.area = 0; - ras.cover = 0; - ras.ex = ex - ras.min_ex; - ras.ey = ey - ras.min_ey; - ras.invalid = 0; - - gray_set_cell(RAS_VAR_ ex, ey); -} - -/*************************************************************************/ -/* */ -/* Render a straight line across multiple cells in any direction. */ -/* */ -static void gray_render_line(RAS_ARG_ TPos to_x, TPos to_y) -{ - TPos dx, dy, fx1, fy1, fx2, fy2; - TCoord ex1, ex2, ey1, ey2; - - ex1 = TRUNC(ras.x); - ex2 = TRUNC(to_x); - ey1 = TRUNC(ras.y); - ey2 = TRUNC(to_y); - - /* perform vertical clipping */ - if ((ey1 >= ras.max_ey && ey2 >= ras.max_ey) || - (ey1 < ras.min_ey && ey2 < ras.min_ey)) - goto End; - - dx = to_x - ras.x; - dy = to_y - ras.y; - - if (SW_FT_ABS(dx) > 10000000 || SW_FT_ABS(dy) > 10000000) { - goto End; - } - - fx1 = ras.x - SUBPIXELS(ex1); - fy1 = ras.y - SUBPIXELS(ey1); - - if (ex1 == ex2 && ey1 == ey2) /* inside one cell */ - ; - else if (dy == 0) /* ex1 != ex2 */ /* any horizontal line */ - { - ex1 = ex2; - gray_set_cell(RAS_VAR_ ex1, ey1); - } else if (dx == 0) { - if (dy > 0) /* vertical line up */ - do { - fy2 = ONE_PIXEL; - ras.cover += (fy2 - fy1); - ras.area += (fy2 - fy1) * fx1 * 2; - fy1 = 0; - ey1++; - gray_set_cell(RAS_VAR_ ex1, ey1); - } while (ey1 != ey2); - else /* vertical line down */ - do { - fy2 = 0; - ras.cover += (fy2 - fy1); - ras.area += (fy2 - fy1) * fx1 * 2; - fy1 = ONE_PIXEL; - ey1--; - gray_set_cell(RAS_VAR_ ex1, ey1); - } while (ey1 != ey2); - } else /* any other line */ - { - TArea prod = dx * fy1 - dy * fx1; - SW_FT_UDIVPREP(dx); - SW_FT_UDIVPREP(dy); - - /* The fundamental value `prod' determines which side and the */ - /* exact coordinate where the line exits current cell. It is */ - /* also easily updated when moving from one cell to the next. */ - do { - if (prod <= 0 && prod - dx * ONE_PIXEL > 0) /* left */ - { - fx2 = 0; - fy2 = (TPos)SW_FT_UDIV(-prod, -dx); - prod -= dy * ONE_PIXEL; - ras.cover += (fy2 - fy1); - ras.area += (fy2 - fy1) * (fx1 + fx2); - fx1 = ONE_PIXEL; - fy1 = fy2; - ex1--; - } else if (prod - dx * ONE_PIXEL <= 0 && - prod - dx * ONE_PIXEL + dy * ONE_PIXEL > 0) /* up */ - { - prod -= dx * ONE_PIXEL; - fx2 = (TPos)SW_FT_UDIV(-prod, dy); - fy2 = ONE_PIXEL; - ras.cover += (fy2 - fy1); - ras.area += (fy2 - fy1) * (fx1 + fx2); - fx1 = fx2; - fy1 = 0; - ey1++; - } else if (prod - dx * ONE_PIXEL + dy * ONE_PIXEL <= 0 && - prod + dy * ONE_PIXEL >= 0) /* right */ - { - prod += dy * ONE_PIXEL; - fx2 = ONE_PIXEL; - fy2 = (TPos)SW_FT_UDIV(prod, dx); - ras.cover += (fy2 - fy1); - ras.area += (fy2 - fy1) * (fx1 + fx2); - fx1 = 0; - fy1 = fy2; - ex1++; - } else /* ( prod + dy * ONE_PIXEL < 0 && - prod > 0 ) down */ - { - fx2 = (TPos)SW_FT_UDIV(prod, -dy); - fy2 = 0; - prod += dx * ONE_PIXEL; - ras.cover += (fy2 - fy1); - ras.area += (fy2 - fy1) * (fx1 + fx2); - fx1 = fx2; - fy1 = ONE_PIXEL; - ey1--; - } - - gray_set_cell(RAS_VAR_ ex1, ey1); - } while (ex1 != ex2 || ey1 != ey2); - } - - fx2 = to_x - SUBPIXELS(ex2); - fy2 = to_y - SUBPIXELS(ey2); - - ras.cover += (fy2 - fy1); - ras.area += (fy2 - fy1) * (fx1 + fx2); - -End: - ras.x = to_x; - ras.y = to_y; -} - -static void gray_split_conic(SW_FT_Vector* base) -{ - TPos a, b; - - base[4].x = base[2].x; - a = base[0].x + base[1].x; - b = base[1].x + base[2].x; - base[3].x = b >> 1; - base[2].x = ( a + b ) >> 2; - base[1].x = a >> 1; - - base[4].y = base[2].y; - a = base[0].y + base[1].y; - b = base[1].y + base[2].y; - base[3].y = b >> 1; - base[2].y = ( a + b ) >> 2; - base[1].y = a >> 1; -} - -static void gray_render_conic(RAS_ARG_ const SW_FT_Vector* control, - const SW_FT_Vector* to) -{ - TPos dx, dy; - TPos min, max, y; - int top, level; - int* levels; - SW_FT_Vector* arc; - - levels = ras.lev_stack; - - arc = ras.bez_stack; - arc[0].x = UPSCALE(to->x); - arc[0].y = UPSCALE(to->y); - arc[1].x = UPSCALE(control->x); - arc[1].y = UPSCALE(control->y); - arc[2].x = ras.x; - arc[2].y = ras.y; - top = 0; - - dx = SW_FT_ABS(arc[2].x + arc[0].x - 2 * arc[1].x); - dy = SW_FT_ABS(arc[2].y + arc[0].y - 2 * arc[1].y); - if (dx < dy) dx = dy; - - if (dx < ONE_PIXEL / 4) goto Draw; - - /* short-cut the arc that crosses the current band */ - min = max = arc[0].y; - - y = arc[1].y; - if (y < min) min = y; - if (y > max) max = y; - - y = arc[2].y; - if (y < min) min = y; - if (y > max) max = y; - - if (TRUNC(min) >= ras.max_ey || TRUNC(max) < ras.min_ey) goto Draw; - - level = 0; - do { - dx >>= 2; - level++; - } while (dx > ONE_PIXEL / 4); - - levels[0] = level; - - do { - level = levels[top]; - if (level > 0) { - gray_split_conic(arc); - arc += 2; - top++; - if (top >= 32) return; // levels size is 32 - levels[top] = levels[top - 1] = level - 1; - continue; - } - - Draw: - gray_render_line(RAS_VAR_ arc[0].x, arc[0].y); - top--; - arc -= 2; - - } while (top >= 0); -} - -static void gray_split_cubic(SW_FT_Vector* base) -{ - TPos a, b, c; - - - base[6].x = base[3].x; - a = base[0].x + base[1].x; - b = base[1].x + base[2].x; - c = base[2].x + base[3].x; - base[5].x = c >> 1; - c += b; - base[4].x = c >> 2; - base[1].x = a >> 1; - a += b; - base[2].x = a >> 2; - base[3].x = ( a + c ) >> 3; - - base[6].y = base[3].y; - a = base[0].y + base[1].y; - b = base[1].y + base[2].y; - c = base[2].y + base[3].y; - base[5].y = c >> 1; - c += b; - base[4].y = c >> 2; - base[1].y = a >> 1; - a += b; - base[2].y = a >> 2; - base[3].y = ( a + c ) >> 3; -} - - -static void -gray_render_cubic(RAS_ARG_ const SW_FT_Vector* control1, - const SW_FT_Vector* control2, - const SW_FT_Vector* to) -{ - SW_FT_Vector* arc = ras.bez_stack; - - arc[0].x = UPSCALE( to->x ); - arc[0].y = UPSCALE( to->y ); - arc[1].x = UPSCALE( control2->x ); - arc[1].y = UPSCALE( control2->y ); - arc[2].x = UPSCALE( control1->x ); - arc[2].y = UPSCALE( control1->y ); - arc[3].x = ras.x; - arc[3].y = ras.y; - - /* short-cut the arc that crosses the current band */ - if ( ( TRUNC( arc[0].y ) >= ras.max_ey && - TRUNC( arc[1].y ) >= ras.max_ey && - TRUNC( arc[2].y ) >= ras.max_ey && - TRUNC( arc[3].y ) >= ras.max_ey ) || - ( TRUNC( arc[0].y ) < ras.min_ey && - TRUNC( arc[1].y ) < ras.min_ey && - TRUNC( arc[2].y ) < ras.min_ey && - TRUNC( arc[3].y ) < ras.min_ey ) ) - { - ras.x = arc[0].x; - ras.y = arc[0].y; - return; - } - - for (;;) - { - /* with each split, control points quickly converge towards */ - /* chord trisection points and the vanishing distances below */ - /* indicate when the segment is flat enough to draw */ - if ( SW_FT_ABS( 2 * arc[0].x - 3 * arc[1].x + arc[3].x ) > ONE_PIXEL / 2 || - SW_FT_ABS( 2 * arc[0].y - 3 * arc[1].y + arc[3].y ) > ONE_PIXEL / 2 || - SW_FT_ABS( arc[0].x - 3 * arc[2].x + 2 * arc[3].x ) > ONE_PIXEL / 2 || - SW_FT_ABS( arc[0].y - 3 * arc[2].y + 2 * arc[3].y ) > ONE_PIXEL / 2 ) - goto Split; - - gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); - - if ( arc == ras.bez_stack ) - return; - - arc -= 3; - continue; - - Split: - gray_split_cubic( arc ); - arc += 3; - } -} - -static int gray_move_to(const SW_FT_Vector* to, gray_PWorker worker) -{ - TPos x, y; - - /* record current cell, if any */ - if (!ras.invalid) gray_record_cell(RAS_VAR); - - /* start to a new position */ - x = UPSCALE(to->x); - y = UPSCALE(to->y); - - gray_start_cell(RAS_VAR_ TRUNC(x), TRUNC(y)); - - worker->x = x; - worker->y = y; - return 0; -} - -static int gray_line_to(const SW_FT_Vector* to, gray_PWorker worker) -{ - gray_render_line(RAS_VAR_ UPSCALE(to->x), UPSCALE(to->y)); - return 0; -} - -static int gray_conic_to(const SW_FT_Vector* control, const SW_FT_Vector* to, - gray_PWorker worker) -{ - gray_render_conic(RAS_VAR_ control, to); - return 0; -} - -static int gray_cubic_to(const SW_FT_Vector* control1, - const SW_FT_Vector* control2, const SW_FT_Vector* to, - gray_PWorker worker) -{ - gray_render_cubic(RAS_VAR_ control1, control2, to); - return 0; -} - -static void gray_hline(RAS_ARG_ TCoord x, TCoord y, TPos area, TCoord acount) -{ - int coverage; - - /* compute the coverage line's coverage, depending on the */ - /* outline fill rule */ - /* */ - /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */ - /* */ - coverage = (int)(area >> (PIXEL_BITS * 2 + 1 - 8)); - /* use range 0..256 */ - if (coverage < 0) coverage = -coverage; - - if (ras.outline.flags & SW_FT_OUTLINE_EVEN_ODD_FILL) { - coverage &= 511; - - if (coverage > 256) - coverage = 512 - coverage; - else if (coverage == 256) - coverage = 255; - } else { - /* normal non-zero winding rule */ - if (coverage >= 256) coverage = 255; - } - - y += (TCoord)ras.min_ey; - x += (TCoord)ras.min_ex; - - /* SW_FT_Span.x is a 16-bit short, so limit our coordinates appropriately */ - if (x >= 32767) x = 32767; - - /* SW_FT_Span.y is an integer, so limit our coordinates appropriately */ - if (y >= SW_FT_INT_MAX) y = SW_FT_INT_MAX; - - if (coverage) { - SW_FT_Span* span; - int count; - - // update bounding box. - if (x < ras.bound_left) ras.bound_left = x; - if (y < ras.bound_top) ras.bound_top = y; - if (y > ras.bound_bottom) ras.bound_bottom = y; - if (x + acount > ras.bound_right) ras.bound_right = x + acount; - - /* see whether we can add this span to the current list */ - count = ras.num_gray_spans; - span = ras.gray_spans + count - 1; - if (count > 0 && span->y == y && (int)span->x + span->len == (int)x && - span->coverage == coverage) { - span->len = (unsigned short)(span->len + acount); - return; - } - - if (count >= SW_FT_MAX_GRAY_SPANS) { - if (ras.render_span && count > 0) - ras.render_span(count, ras.gray_spans, ras.render_span_data); - -#ifdef DEBUG_GRAYS - - if (1) { - int n; - - fprintf(stderr, "count = %3d ", count); - span = ras.gray_spans; - for (n = 0; n < count; n++, span++) - fprintf(stderr, "[%d , %d..%d] : %d ", span->y, span->x, - span->x + span->len - 1, span->coverage); - fprintf(stderr, "\n"); - } - -#endif /* DEBUG_GRAYS */ - - ras.num_gray_spans = 0; - - span = ras.gray_spans; - } else - span++; - - /* add a gray span to the current list */ - span->x = (short)x; - span->y = (short)y; - span->len = (unsigned short)acount; - span->coverage = (unsigned char)coverage; - - ras.num_gray_spans++; - } -} - -static void gray_sweep(RAS_ARG) -{ - int yindex; - - if (ras.num_cells == 0) return; - - ras.num_gray_spans = 0; - - for (yindex = 0; yindex < ras.ycount; yindex++) { - PCell cell = ras.ycells[yindex]; - TCoord cover = 0; - TCoord x = 0; - - for (; cell != NULL; cell = cell->next) { - TPos area; - - if (cell->x > x && cover != 0) - gray_hline(RAS_VAR_ x, yindex, cover * (ONE_PIXEL * 2), - cell->x - x); - - cover += cell->cover; - area = cover * (ONE_PIXEL * 2) - cell->area; - - if (area != 0 && cell->x >= 0) - gray_hline(RAS_VAR_ cell->x, yindex, area, 1); - - x = cell->x + 1; - } - - if (cover != 0) - gray_hline(RAS_VAR_ x, yindex, cover * (ONE_PIXEL * 2), - ras.count_ex - x); - } - - if (ras.render_span && ras.num_gray_spans > 0) - ras.render_span(ras.num_gray_spans, ras.gray_spans, - ras.render_span_data); -} - -/*************************************************************************/ -/* */ -/* The following function should only compile in stand-alone mode, */ -/* i.e., when building this component without the rest of FreeType. */ -/* */ -/*************************************************************************/ - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_Outline_Decompose */ -/* */ -/* */ -/* Walk over an outline's structure to decompose it into individual */ -/* segments and Bézier arcs. This function is also able to emit */ -/* `move to' and `close to' operations to indicate the start and end */ -/* of new contours in the outline. */ -/* */ -/* */ -/* outline :: A pointer to the source target. */ -/* */ -/* func_interface :: A table of `emitters', i.e., function pointers */ -/* called during decomposition to indicate path */ -/* operations. */ -/* */ -/* */ -/* user :: A typeless pointer which is passed to each */ -/* emitter during the decomposition. It can be */ -/* used to store the state during the */ -/* decomposition. */ -/* */ -/* */ -/* Error code. 0 means success. */ -/* */ -static int SW_FT_Outline_Decompose(const SW_FT_Outline* outline, - const SW_FT_Outline_Funcs* func_interface, - void* user) -{ -#undef SCALED -#define SCALED(x) (((x) << shift) - delta) - - SW_FT_Vector v_last; - SW_FT_Vector v_control; - SW_FT_Vector v_start; - - SW_FT_Vector* point; - SW_FT_Vector* limit; - char* tags; - - int error; - - int n; /* index of contour in outline */ - int first; /* index of first point in contour */ - char tag; /* current point's state */ - - int shift; - TPos delta; - - if (!outline || !func_interface) return SW_FT_THROW(Invalid_Argument); - - shift = func_interface->shift; - delta = func_interface->delta; - first = 0; - - for (n = 0; n < outline->n_contours; n++) { - int last; /* index of last point in contour */ - - last = outline->contours[n]; - if (last < 0) goto Invalid_Outline; - limit = outline->points + last; - - v_start = outline->points[first]; - v_start.x = SCALED(v_start.x); - v_start.y = SCALED(v_start.y); - - v_last = outline->points[last]; - v_last.x = SCALED(v_last.x); - v_last.y = SCALED(v_last.y); - - v_control = v_start; - - point = outline->points + first; - tags = outline->tags + first; - tag = SW_FT_CURVE_TAG(tags[0]); - - /* A contour cannot start with a cubic control point! */ - if (tag == SW_FT_CURVE_TAG_CUBIC) goto Invalid_Outline; - - /* check first point to determine origin */ - if (tag == SW_FT_CURVE_TAG_CONIC) { - /* first point is conic control. Yes, this happens. */ - if (SW_FT_CURVE_TAG(outline->tags[last]) == SW_FT_CURVE_TAG_ON) { - /* start at last point if it is on the curve */ - v_start = v_last; - limit--; - } else { - /* if both first and last points are conic, */ - /* start at their middle and record its position */ - /* for closure */ - v_start.x = (v_start.x + v_last.x) / 2; - v_start.y = (v_start.y + v_last.y) / 2; - } - point--; - tags--; - } - - error = func_interface->move_to(&v_start, user); - if (error) goto Exit; - - while (point < limit) { - point++; - tags++; - - tag = SW_FT_CURVE_TAG(tags[0]); - switch (tag) { - case SW_FT_CURVE_TAG_ON: /* emit a single line_to */ - { - SW_FT_Vector vec; - - vec.x = SCALED(point->x); - vec.y = SCALED(point->y); - - error = func_interface->line_to(&vec, user); - if (error) goto Exit; - continue; - } - - case SW_FT_CURVE_TAG_CONIC: /* consume conic arcs */ - v_control.x = SCALED(point->x); - v_control.y = SCALED(point->y); - - Do_Conic: - if (point < limit) { - SW_FT_Vector vec; - SW_FT_Vector v_middle; - - point++; - tags++; - tag = SW_FT_CURVE_TAG(tags[0]); - - vec.x = SCALED(point->x); - vec.y = SCALED(point->y); - - if (tag == SW_FT_CURVE_TAG_ON) { - error = - func_interface->conic_to(&v_control, &vec, user); - if (error) goto Exit; - continue; - } - - if (tag != SW_FT_CURVE_TAG_CONIC) goto Invalid_Outline; - - v_middle.x = (v_control.x + vec.x) / 2; - v_middle.y = (v_control.y + vec.y) / 2; - - error = - func_interface->conic_to(&v_control, &v_middle, user); - if (error) goto Exit; - - v_control = vec; - goto Do_Conic; - } - - error = func_interface->conic_to(&v_control, &v_start, user); - goto Close; - - default: /* SW_FT_CURVE_TAG_CUBIC */ - { - SW_FT_Vector vec1, vec2; - - if (point + 1 > limit || - SW_FT_CURVE_TAG(tags[1]) != SW_FT_CURVE_TAG_CUBIC) - goto Invalid_Outline; - - point += 2; - tags += 2; - - vec1.x = SCALED(point[-2].x); - vec1.y = SCALED(point[-2].y); - - vec2.x = SCALED(point[-1].x); - vec2.y = SCALED(point[-1].y); - - if (point <= limit) { - SW_FT_Vector vec; - - vec.x = SCALED(point->x); - vec.y = SCALED(point->y); - - error = func_interface->cubic_to(&vec1, &vec2, &vec, user); - if (error) goto Exit; - continue; - } - - error = func_interface->cubic_to(&vec1, &vec2, &v_start, user); - goto Close; - } - } - } - - /* close the contour with a line segment */ - error = func_interface->line_to(&v_start, user); - - Close: - if (error) goto Exit; - - first = last + 1; - } - - return 0; - -Exit: - return error; - -Invalid_Outline: - return SW_FT_THROW(Invalid_Outline); -} - -typedef struct gray_TBand_ { - TPos min, max; - -} gray_TBand; - -SW_FT_DEFINE_OUTLINE_FUNCS(func_interface, - (SW_FT_Outline_MoveTo_Func)gray_move_to, - (SW_FT_Outline_LineTo_Func)gray_line_to, - (SW_FT_Outline_ConicTo_Func)gray_conic_to, - (SW_FT_Outline_CubicTo_Func)gray_cubic_to, 0, 0) - -static int gray_convert_glyph_inner(RAS_ARG) -{ - volatile int error = 0; - - if (ft_setjmp(ras.jump_buffer) == 0) { - error = SW_FT_Outline_Decompose(&ras.outline, &func_interface, &ras); - if (!ras.invalid) gray_record_cell(RAS_VAR); - } else - error = SW_FT_THROW(Memory_Overflow); - - return error; -} - -static int gray_convert_glyph(RAS_ARG) -{ - gray_TBand bands[40]; - gray_TBand* volatile band; - int volatile n, num_bands; - TPos volatile min, max, max_y; - SW_FT_BBox* clip; - - /* Set up state in the raster object */ - gray_compute_cbox(RAS_VAR); - - /* clip to target bitmap, exit if nothing to do */ - clip = &ras.clip_box; - - if (ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax || - ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax) - return 0; - - if (ras.min_ex < clip->xMin) ras.min_ex = clip->xMin; - if (ras.min_ey < clip->yMin) ras.min_ey = clip->yMin; - - if (ras.max_ex > clip->xMax) ras.max_ex = clip->xMax; - if (ras.max_ey > clip->yMax) ras.max_ey = clip->yMax; - - ras.count_ex = ras.max_ex - ras.min_ex; - ras.count_ey = ras.max_ey - ras.min_ey; - - /* set up vertical bands */ - num_bands = (int)((ras.max_ey - ras.min_ey) / ras.band_size); - if (num_bands == 0) num_bands = 1; - if (num_bands >= 39) num_bands = 39; - - ras.band_shoot = 0; - - min = ras.min_ey; - max_y = ras.max_ey; - - for (n = 0; n < num_bands; n++, min = max) { - max = min + ras.band_size; - if (n == num_bands - 1 || max > max_y) max = max_y; - - bands[0].min = min; - bands[0].max = max; - band = bands; - - while (band >= bands) { - TPos bottom, top, middle; - int error; - - { - PCell cells_max; - int yindex; - long cell_start, cell_end, cell_mod; - - ras.ycells = (PCell*)ras.buffer; - ras.ycount = band->max - band->min; - - cell_start = sizeof(PCell) * ras.ycount; - cell_mod = cell_start % sizeof(TCell); - if (cell_mod > 0) cell_start += sizeof(TCell) - cell_mod; - - cell_end = ras.buffer_size; - cell_end -= cell_end % sizeof(TCell); - - cells_max = (PCell)((char*)ras.buffer + cell_end); - ras.cells = (PCell)((char*)ras.buffer + cell_start); - if (ras.cells >= cells_max) goto ReduceBands; - - ras.max_cells = cells_max - ras.cells; - if (ras.max_cells < 2) goto ReduceBands; - - for (yindex = 0; yindex < ras.ycount; yindex++) - ras.ycells[yindex] = NULL; - } - - ras.num_cells = 0; - ras.invalid = 1; - ras.min_ey = band->min; - ras.max_ey = band->max; - ras.count_ey = band->max - band->min; - - error = gray_convert_glyph_inner(RAS_VAR); - - if (!error) { - gray_sweep(RAS_VAR); - band--; - continue; - } else if (error != ErrRaster_Memory_Overflow) - return 1; - - ReduceBands: - /* render pool overflow; we will reduce the render band by half */ - bottom = band->min; - top = band->max; - middle = bottom + ((top - bottom) >> 1); - - /* This is too complex for a single scanline; there must */ - /* be some problems. */ - if (middle == bottom) { - return 1; - } - - if (bottom - top >= ras.band_size) ras.band_shoot++; - - band[1].min = bottom; - band[1].max = middle; - band[0].min = middle; - band[0].max = top; - band++; - } - } - - if (ras.band_shoot > 8 && ras.band_size > 16) - ras.band_size = ras.band_size / 2; - - return 0; -} - -static int gray_raster_render(gray_PRaster raster, - const SW_FT_Raster_Params* params) -{ - SW_FT_UNUSED(raster); - const SW_FT_Outline* outline = (const SW_FT_Outline*)params->source; - - gray_TWorker worker[1]; - - TCell buffer[SW_FT_RENDER_POOL_SIZE / sizeof(TCell)]; - long buffer_size = sizeof(buffer); - int band_size = (int)(buffer_size / (long)(sizeof(TCell) * 8)); - - if (!outline) return SW_FT_THROW(Invalid_Outline); - - /* return immediately if the outline is empty */ - if (outline->n_points == 0 || outline->n_contours <= 0) return 0; - - if (!outline->contours || !outline->points) - return SW_FT_THROW(Invalid_Outline); - - if (outline->n_points != outline->contours[outline->n_contours - 1] + 1) - return SW_FT_THROW(Invalid_Outline); - - /* this version does not support monochrome rendering */ - if (!(params->flags & SW_FT_RASTER_FLAG_AA)) - return SW_FT_THROW(Invalid_Mode); - - if (params->flags & SW_FT_RASTER_FLAG_CLIP) - ras.clip_box = params->clip_box; - else { - ras.clip_box.xMin = -32768L; - ras.clip_box.yMin = -32768L; - ras.clip_box.xMax = 32767L; - ras.clip_box.yMax = 32767L; - } - - gray_init_cells(RAS_VAR_ buffer, buffer_size); - - ras.outline = *outline; - ras.num_cells = 0; - ras.invalid = 1; - ras.band_size = band_size; - ras.num_gray_spans = 0; - - ras.render_span = (SW_FT_Raster_Span_Func)params->gray_spans; - ras.render_span_data = params->user; - - gray_convert_glyph(RAS_VAR); - params->bbox_cb(ras.bound_left, ras.bound_top, - ras.bound_right - ras.bound_left, - ras.bound_bottom - ras.bound_top + 1, params->user); - return 1; -} - -/**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/ -/**** a static object. *****/ - -static int gray_raster_new(SW_FT_Raster* araster) -{ - static gray_TRaster the_raster; - - *araster = (SW_FT_Raster)&the_raster; - SW_FT_MEM_ZERO(&the_raster, sizeof(the_raster)); - - return 0; -} - -static void gray_raster_done(SW_FT_Raster raster) -{ - /* nothing */ - SW_FT_UNUSED(raster); -} - -static void gray_raster_reset(SW_FT_Raster raster, char* pool_base, - long pool_size) -{ - SW_FT_UNUSED(raster); - SW_FT_UNUSED(pool_base); - SW_FT_UNUSED(pool_size); -} - -SW_FT_DEFINE_RASTER_FUNCS(sw_ft_grays_raster, - - (SW_FT_Raster_New_Func)gray_raster_new, - (SW_FT_Raster_Reset_Func)gray_raster_reset, - (SW_FT_Raster_Render_Func)gray_raster_render, - (SW_FT_Raster_Done_Func)gray_raster_done) - -/* END */ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_raster.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_raster.h deleted file mode 100644 index 7897289f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_raster.h +++ /dev/null @@ -1,607 +0,0 @@ -#ifndef V_FT_IMG_H -#define V_FT_IMG_H -/***************************************************************************/ -/* */ -/* ftimage.h */ -/* */ -/* FreeType glyph image formats and default raster interface */ -/* (specification). */ -/* */ -/* Copyright 1996-2010, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* Note: A `raster' is simply a scan-line converter, used to render */ - /* SW_FT_Outlines into SW_FT_Bitmaps. */ - /* */ - /*************************************************************************/ - -#include "v_ft_types.h" - - /*************************************************************************/ - /* */ - /* */ - /* FT_BBox */ - /* */ - /* */ - /* A structure used to hold an outline's bounding box, i.e., the */ - /* coordinates of its extrema in the horizontal and vertical */ - /* directions. */ - /* */ - /* */ - /* xMin :: The horizontal minimum (left-most). */ - /* */ - /* yMin :: The vertical minimum (bottom-most). */ - /* */ - /* xMax :: The horizontal maximum (right-most). */ - /* */ - /* yMax :: The vertical maximum (top-most). */ - /* */ - /* */ - /* The bounding box is specified with the coordinates of the lower */ - /* left and the upper right corner. In PostScript, those values are */ - /* often called (llx,lly) and (urx,ury), respectively. */ - /* */ - /* If `yMin' is negative, this value gives the glyph's descender. */ - /* Otherwise, the glyph doesn't descend below the baseline. */ - /* Similarly, if `ymax' is positive, this value gives the glyph's */ - /* ascender. */ - /* */ - /* `xMin' gives the horizontal distance from the glyph's origin to */ - /* the left edge of the glyph's bounding box. If `xMin' is negative, */ - /* the glyph extends to the left of the origin. */ - /* */ - typedef struct SW_FT_BBox_ - { - SW_FT_Pos xMin, yMin; - SW_FT_Pos xMax, yMax; - - } SW_FT_BBox; - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_Outline */ -/* */ -/* */ -/* This structure is used to describe an outline to the scan-line */ -/* converter. */ -/* */ -/* */ -/* n_contours :: The number of contours in the outline. */ -/* */ -/* n_points :: The number of points in the outline. */ -/* */ -/* points :: A pointer to an array of `n_points' @SW_FT_Vector */ -/* elements, giving the outline's point coordinates. */ -/* */ -/* tags :: A pointer to an array of `n_points' chars, giving */ -/* each outline point's type. */ -/* */ -/* If bit~0 is unset, the point is `off' the curve, */ -/* i.e., a Bézier control point, while it is `on' if */ -/* set. */ -/* */ -/* Bit~1 is meaningful for `off' points only. If set, */ -/* it indicates a third-order Bézier arc control point; */ -/* and a second-order control point if unset. */ -/* */ -/* If bit~2 is set, bits 5-7 contain the drop-out mode */ -/* (as defined in the OpenType specification; the value */ -/* is the same as the argument to the SCANMODE */ -/* instruction). */ -/* */ -/* Bits 3 and~4 are reserved for internal purposes. */ -/* */ -/* contours :: An array of `n_contours' shorts, giving the end */ -/* point of each contour within the outline. For */ -/* example, the first contour is defined by the points */ -/* `0' to `contours[0]', the second one is defined by */ -/* the points `contours[0]+1' to `contours[1]', etc. */ -/* */ -/* flags :: A set of bit flags used to characterize the outline */ -/* and give hints to the scan-converter and hinter on */ -/* how to convert/grid-fit it. See @SW_FT_OUTLINE_FLAGS.*/ -/* */ -typedef struct SW_FT_Outline_ -{ - short n_contours; /* number of contours in glyph */ - short n_points; /* number of points in the glyph */ - - SW_FT_Vector* points; /* the outline's points */ - char* tags; /* the points flags */ - short* contours; /* the contour end points */ - char* contours_flag; /* the contour open flags */ - - int flags; /* outline masks */ - -} SW_FT_Outline; - - - /*************************************************************************/ - /* */ - /* */ - /* SW_FT_OUTLINE_FLAGS */ - /* */ - /* */ - /* A list of bit-field constants use for the flags in an outline's */ - /* `flags' field. */ - /* */ - /* */ - /* SW_FT_OUTLINE_NONE :: */ - /* Value~0 is reserved. */ - /* */ - /* SW_FT_OUTLINE_OWNER :: */ - /* If set, this flag indicates that the outline's field arrays */ - /* (i.e., `points', `flags', and `contours') are `owned' by the */ - /* outline object, and should thus be freed when it is destroyed. */ - /* */ - /* SW_FT_OUTLINE_EVEN_ODD_FILL :: */ - /* By default, outlines are filled using the non-zero winding rule. */ - /* If set to 1, the outline will be filled using the even-odd fill */ - /* rule (only works with the smooth rasterizer). */ - /* */ - /* SW_FT_OUTLINE_REVERSE_FILL :: */ - /* By default, outside contours of an outline are oriented in */ - /* clock-wise direction, as defined in the TrueType specification. */ - /* This flag is set if the outline uses the opposite direction */ - /* (typically for Type~1 fonts). This flag is ignored by the scan */ - /* converter. */ - /* */ - /* */ - /* */ - /* There exists a second mechanism to pass the drop-out mode to the */ - /* B/W rasterizer; see the `tags' field in @SW_FT_Outline. */ - /* */ - /* Please refer to the description of the `SCANTYPE' instruction in */ - /* the OpenType specification (in file `ttinst1.doc') how simple */ - /* drop-outs, smart drop-outs, and stubs are defined. */ - /* */ -#define SW_FT_OUTLINE_NONE 0x0 -#define SW_FT_OUTLINE_OWNER 0x1 -#define SW_FT_OUTLINE_EVEN_ODD_FILL 0x2 -#define SW_FT_OUTLINE_REVERSE_FILL 0x4 - - /* */ - -#define SW_FT_CURVE_TAG( flag ) ( flag & 3 ) - -#define SW_FT_CURVE_TAG_ON 1 -#define SW_FT_CURVE_TAG_CONIC 0 -#define SW_FT_CURVE_TAG_CUBIC 2 - - -#define SW_FT_Curve_Tag_On SW_FT_CURVE_TAG_ON -#define SW_FT_Curve_Tag_Conic SW_FT_CURVE_TAG_CONIC -#define SW_FT_Curve_Tag_Cubic SW_FT_CURVE_TAG_CUBIC - - /*************************************************************************/ - /* */ - /* A raster is a scan converter, in charge of rendering an outline into */ - /* a a bitmap. This section contains the public API for rasters. */ - /* */ - /* Note that in FreeType 2, all rasters are now encapsulated within */ - /* specific modules called `renderers'. See `ftrender.h' for more */ - /* details on renderers. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* SW_FT_Raster */ - /* */ - /* */ - /* A handle (pointer) to a raster object. Each object can be used */ - /* independently to convert an outline into a bitmap or pixmap. */ - /* */ - typedef struct SW_FT_RasterRec_* SW_FT_Raster; - - - /*************************************************************************/ - /* */ - /* */ - /* SW_FT_Span */ - /* */ - /* */ - /* A structure used to model a single span of gray (or black) pixels */ - /* when rendering a monochrome or anti-aliased bitmap. */ - /* */ - /* */ - /* x :: The span's horizontal start position. */ - /* */ - /* len :: The span's length in pixels. */ - /* */ - /* coverage :: The span color/coverage, ranging from 0 (background) */ - /* to 255 (foreground). Only used for anti-aliased */ - /* rendering. */ - /* */ - /* */ - /* This structure is used by the span drawing callback type named */ - /* @SW_FT_SpanFunc that takes the y~coordinate of the span as a */ - /* parameter. */ - /* */ - /* The coverage value is always between 0 and 255. If you want less */ - /* gray values, the callback function has to reduce them. */ - /* */ - typedef struct SW_FT_Span_ - { - short x; - short y; - unsigned short len; - unsigned char coverage; - - } SW_FT_Span; - - - /*************************************************************************/ - /* */ - /* */ - /* SW_FT_SpanFunc */ - /* */ - /* */ - /* A function used as a call-back by the anti-aliased renderer in */ - /* order to let client applications draw themselves the gray pixel */ - /* spans on each scan line. */ - /* */ - /* */ - /* y :: The scanline's y~coordinate. */ - /* */ - /* count :: The number of spans to draw on this scanline. */ - /* */ - /* spans :: A table of `count' spans to draw on the scanline. */ - /* */ - /* user :: User-supplied data that is passed to the callback. */ - /* */ - /* */ - /* This callback allows client applications to directly render the */ - /* gray spans of the anti-aliased bitmap to any kind of surfaces. */ - /* */ - /* This can be used to write anti-aliased outlines directly to a */ - /* given background bitmap, and even perform translucency. */ - /* */ - /* Note that the `count' field cannot be greater than a fixed value */ - /* defined by the `SW_FT_MAX_GRAY_SPANS' configuration macro in */ - /* `ftoption.h'. By default, this value is set to~32, which means */ - /* that if there are more than 32~spans on a given scanline, the */ - /* callback is called several times with the same `y' parameter in */ - /* order to draw all callbacks. */ - /* */ - /* Otherwise, the callback is only called once per scan-line, and */ - /* only for those scanlines that do have `gray' pixels on them. */ - /* */ - typedef void - (*SW_FT_SpanFunc)( int count, - const SW_FT_Span* spans, - void* user ); - - typedef void - (*SW_FT_BboxFunc)( int x, int y, int w, int h, - void* user); - -#define SW_FT_Raster_Span_Func SW_FT_SpanFunc - - - - /*************************************************************************/ - /* */ - /* */ - /* SW_FT_RASTER_FLAG_XXX */ - /* */ - /* */ - /* A list of bit flag constants as used in the `flags' field of a */ - /* @SW_FT_Raster_Params structure. */ - /* */ - /* */ - /* SW_FT_RASTER_FLAG_DEFAULT :: This value is 0. */ - /* */ - /* SW_FT_RASTER_FLAG_AA :: This flag is set to indicate that an */ - /* anti-aliased glyph image should be */ - /* generated. Otherwise, it will be */ - /* monochrome (1-bit). */ - /* */ - /* SW_FT_RASTER_FLAG_DIRECT :: This flag is set to indicate direct */ - /* rendering. In this mode, client */ - /* applications must provide their own span */ - /* callback. This lets them directly */ - /* draw or compose over an existing bitmap. */ - /* If this bit is not set, the target */ - /* pixmap's buffer _must_ be zeroed before */ - /* rendering. */ - /* */ - /* Note that for now, direct rendering is */ - /* only possible with anti-aliased glyphs. */ - /* */ - /* SW_FT_RASTER_FLAG_CLIP :: This flag is only used in direct */ - /* rendering mode. If set, the output will */ - /* be clipped to a box specified in the */ - /* `clip_box' field of the */ - /* @SW_FT_Raster_Params structure. */ - /* */ - /* Note that by default, the glyph bitmap */ - /* is clipped to the target pixmap, except */ - /* in direct rendering mode where all spans */ - /* are generated if no clipping box is set. */ - /* */ -#define SW_FT_RASTER_FLAG_DEFAULT 0x0 -#define SW_FT_RASTER_FLAG_AA 0x1 -#define SW_FT_RASTER_FLAG_DIRECT 0x2 -#define SW_FT_RASTER_FLAG_CLIP 0x4 - - - /*************************************************************************/ - /* */ - /* */ - /* SW_FT_Raster_Params */ - /* */ - /* */ - /* A structure to hold the arguments used by a raster's render */ - /* function. */ - /* */ - /* */ - /* target :: The target bitmap. */ - /* */ - /* source :: A pointer to the source glyph image (e.g., an */ - /* @SW_FT_Outline). */ - /* */ - /* flags :: The rendering flags. */ - /* */ - /* gray_spans :: The gray span drawing callback. */ - /* */ - /* black_spans :: The black span drawing callback. UNIMPLEMENTED! */ - /* */ - /* bit_test :: The bit test callback. UNIMPLEMENTED! */ - /* */ - /* bit_set :: The bit set callback. UNIMPLEMENTED! */ - /* */ - /* user :: User-supplied data that is passed to each drawing */ - /* callback. */ - /* */ - /* clip_box :: An optional clipping box. It is only used in */ - /* direct rendering mode. Note that coordinates here */ - /* should be expressed in _integer_ pixels (and not in */ - /* 26.6 fixed-point units). */ - /* */ - /* */ - /* An anti-aliased glyph bitmap is drawn if the @SW_FT_RASTER_FLAG_AA */ - /* bit flag is set in the `flags' field, otherwise a monochrome */ - /* bitmap is generated. */ - /* */ - /* If the @SW_FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the */ - /* raster will call the `gray_spans' callback to draw gray pixel */ - /* spans, in the case of an aa glyph bitmap, it will call */ - /* `black_spans', and `bit_test' and `bit_set' in the case of a */ - /* monochrome bitmap. This allows direct composition over a */ - /* pre-existing bitmap through user-provided callbacks to perform the */ - /* span drawing/composition. */ - /* */ - /* Note that the `bit_test' and `bit_set' callbacks are required when */ - /* rendering a monochrome bitmap, as they are crucial to implement */ - /* correct drop-out control as defined in the TrueType specification. */ - /* */ - typedef struct SW_FT_Raster_Params_ - { - const void* source; - int flags; - SW_FT_SpanFunc gray_spans; - SW_FT_BboxFunc bbox_cb; - void* user; - SW_FT_BBox clip_box; - - } SW_FT_Raster_Params; - - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_Outline_Check */ -/* */ -/* */ -/* Check the contents of an outline descriptor. */ -/* */ -/* */ -/* outline :: A handle to a source outline. */ -/* */ -/* */ -/* FreeType error code. 0~means success. */ -/* */ -SW_FT_Error -SW_FT_Outline_Check( SW_FT_Outline* outline ); - - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_Outline_Get_CBox */ -/* */ -/* */ -/* Return an outline's `control box'. The control box encloses all */ -/* the outline's points, including Bézier control points. Though it */ -/* coincides with the exact bounding box for most glyphs, it can be */ -/* slightly larger in some situations (like when rotating an outline */ -/* that contains Bézier outside arcs). */ -/* */ -/* Computing the control box is very fast, while getting the bounding */ -/* box can take much more time as it needs to walk over all segments */ -/* and arcs in the outline. To get the latter, you can use the */ -/* `ftbbox' component, which is dedicated to this single task. */ -/* */ -/* */ -/* outline :: A pointer to the source outline descriptor. */ -/* */ -/* */ -/* acbox :: The outline's control box. */ -/* */ -/* */ -/* See @SW_FT_Glyph_Get_CBox for a discussion of tricky fonts. */ -/* */ -void -SW_FT_Outline_Get_CBox( const SW_FT_Outline* outline, - SW_FT_BBox *acbox ); - - - /*************************************************************************/ - /* */ - /* */ - /* SW_FT_Raster_NewFunc */ - /* */ - /* */ - /* A function used to create a new raster object. */ - /* */ - /* */ - /* memory :: A handle to the memory allocator. */ - /* */ - /* */ - /* raster :: A handle to the new raster object. */ - /* */ - /* */ - /* Error code. 0~means success. */ - /* */ - /* */ - /* The `memory' parameter is a typeless pointer in order to avoid */ - /* un-wanted dependencies on the rest of the FreeType code. In */ - /* practice, it is an @SW_FT_Memory object, i.e., a handle to the */ - /* standard FreeType memory allocator. However, this field can be */ - /* completely ignored by a given raster implementation. */ - /* */ - typedef int - (*SW_FT_Raster_NewFunc)( SW_FT_Raster* raster ); - -#define SW_FT_Raster_New_Func SW_FT_Raster_NewFunc - - - /*************************************************************************/ - /* */ - /* */ - /* SW_FT_Raster_DoneFunc */ - /* */ - /* */ - /* A function used to destroy a given raster object. */ - /* */ - /* */ - /* raster :: A handle to the raster object. */ - /* */ - typedef void - (*SW_FT_Raster_DoneFunc)( SW_FT_Raster raster ); - -#define SW_FT_Raster_Done_Func SW_FT_Raster_DoneFunc - - - /*************************************************************************/ - /* */ - /* */ - /* SW_FT_Raster_ResetFunc */ - /* */ - /* */ - /* FreeType provides an area of memory called the `render pool', */ - /* available to all registered rasters. This pool can be freely used */ - /* during a given scan-conversion but is shared by all rasters. Its */ - /* content is thus transient. */ - /* */ - /* This function is called each time the render pool changes, or just */ - /* after a new raster object is created. */ - /* */ - /* */ - /* raster :: A handle to the new raster object. */ - /* */ - /* pool_base :: The address in memory of the render pool. */ - /* */ - /* pool_size :: The size in bytes of the render pool. */ - /* */ - /* */ - /* Rasters can ignore the render pool and rely on dynamic memory */ - /* allocation if they want to (a handle to the memory allocator is */ - /* passed to the raster constructor). However, this is not */ - /* recommended for efficiency purposes. */ - /* */ - typedef void - (*SW_FT_Raster_ResetFunc)( SW_FT_Raster raster, - unsigned char* pool_base, - unsigned long pool_size ); - -#define SW_FT_Raster_Reset_Func SW_FT_Raster_ResetFunc - - - /*************************************************************************/ - /* */ - /* */ - /* SW_FT_Raster_RenderFunc */ - /* */ - /* */ - /* Invoke a given raster to scan-convert a given glyph image into a */ - /* target bitmap. */ - /* */ - /* */ - /* raster :: A handle to the raster object. */ - /* */ - /* params :: A pointer to an @SW_FT_Raster_Params structure used to */ - /* store the rendering parameters. */ - /* */ - /* */ - /* Error code. 0~means success. */ - /* */ - /* */ - /* The exact format of the source image depends on the raster's glyph */ - /* format defined in its @SW_FT_Raster_Funcs structure. It can be an */ - /* @SW_FT_Outline or anything else in order to support a large array of */ - /* glyph formats. */ - /* */ - /* Note also that the render function can fail and return a */ - /* `SW_FT_Err_Unimplemented_Feature' error code if the raster used does */ - /* not support direct composition. */ - /* */ - /* XXX: For now, the standard raster doesn't support direct */ - /* composition but this should change for the final release (see */ - /* the files `demos/src/ftgrays.c' and `demos/src/ftgrays2.c' */ - /* for examples of distinct implementations that support direct */ - /* composition). */ - /* */ - typedef int - (*SW_FT_Raster_RenderFunc)( SW_FT_Raster raster, - const SW_FT_Raster_Params* params ); - -#define SW_FT_Raster_Render_Func SW_FT_Raster_RenderFunc - - - /*************************************************************************/ - /* */ - /* */ - /* SW_FT_Raster_Funcs */ - /* */ - /* */ - /* A structure used to describe a given raster class to the library. */ - /* */ - /* */ - /* glyph_format :: The supported glyph format for this raster. */ - /* */ - /* raster_new :: The raster constructor. */ - /* */ - /* raster_reset :: Used to reset the render pool within the raster. */ - /* */ - /* raster_render :: A function to render a glyph into a given bitmap. */ - /* */ - /* raster_done :: The raster destructor. */ - /* */ - typedef struct SW_FT_Raster_Funcs_ - { - SW_FT_Raster_NewFunc raster_new; - SW_FT_Raster_ResetFunc raster_reset; - SW_FT_Raster_RenderFunc raster_render; - SW_FT_Raster_DoneFunc raster_done; - - } SW_FT_Raster_Funcs; - - -extern const SW_FT_Raster_Funcs sw_ft_grays_raster; - -#endif // V_FT_IMG_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_stroker.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_stroker.cpp deleted file mode 100644 index 3160f84f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_stroker.cpp +++ /dev/null @@ -1,1936 +0,0 @@ - -/***************************************************************************/ -/* */ -/* ftstroke.c */ -/* */ -/* FreeType path stroker (body). */ -/* */ -/* Copyright 2002-2006, 2008-2011, 2013 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -#include "v_ft_stroker.h" -#include -#include -#include -#include "v_ft_math.h" - -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** BEZIER COMPUTATIONS *****/ -/***** *****/ -/*************************************************************************/ -/*************************************************************************/ - -#define SW_FT_SMALL_CONIC_THRESHOLD (SW_FT_ANGLE_PI / 6) -#define SW_FT_SMALL_CUBIC_THRESHOLD (SW_FT_ANGLE_PI / 8) - -#define SW_FT_EPSILON 2 - -#define SW_FT_IS_SMALL(x) ((x) > -SW_FT_EPSILON && (x) < SW_FT_EPSILON) - -static SW_FT_Pos ft_pos_abs(SW_FT_Pos x) -{ - return x >= 0 ? x : -x; -} - -static void ft_conic_split(SW_FT_Vector* base) -{ - SW_FT_Pos a, b; - - base[4].x = base[2].x; - a = base[0].x + base[1].x; - b = base[1].x + base[2].x; - base[3].x = b >> 1; - base[2].x = ( a + b ) >> 2; - base[1].x = a >> 1; - - base[4].y = base[2].y; - a = base[0].y + base[1].y; - b = base[1].y + base[2].y; - base[3].y = b >> 1; - base[2].y = ( a + b ) >> 2; - base[1].y = a >> 1; -} - -static SW_FT_Bool ft_conic_is_small_enough(SW_FT_Vector* base, - SW_FT_Angle* angle_in, - SW_FT_Angle* angle_out) -{ - SW_FT_Vector d1, d2; - SW_FT_Angle theta; - SW_FT_Int close1, close2; - - d1.x = base[1].x - base[2].x; - d1.y = base[1].y - base[2].y; - d2.x = base[0].x - base[1].x; - d2.y = base[0].y - base[1].y; - - close1 = SW_FT_IS_SMALL(d1.x) && SW_FT_IS_SMALL(d1.y); - close2 = SW_FT_IS_SMALL(d2.x) && SW_FT_IS_SMALL(d2.y); - - if (close1) { - if (close2) { - /* basically a point; */ - /* do nothing to retain original direction */ - } else { - *angle_in = *angle_out = SW_FT_Atan2(d2.x, d2.y); - } - } else /* !close1 */ - { - if (close2) { - *angle_in = *angle_out = SW_FT_Atan2(d1.x, d1.y); - } else { - *angle_in = SW_FT_Atan2(d1.x, d1.y); - *angle_out = SW_FT_Atan2(d2.x, d2.y); - } - } - - theta = ft_pos_abs(SW_FT_Angle_Diff(*angle_in, *angle_out)); - - return SW_FT_BOOL(theta < SW_FT_SMALL_CONIC_THRESHOLD); -} - -static void ft_cubic_split(SW_FT_Vector* base) -{ - SW_FT_Pos a, b, c; - - base[6].x = base[3].x; - a = base[0].x + base[1].x; - b = base[1].x + base[2].x; - c = base[2].x + base[3].x; - base[5].x = c >> 1; - c += b; - base[4].x = c >> 2; - base[1].x = a >> 1; - a += b; - base[2].x = a >> 2; - base[3].x = ( a + c ) >> 3; - - base[6].y = base[3].y; - a = base[0].y + base[1].y; - b = base[1].y + base[2].y; - c = base[2].y + base[3].y; - base[5].y = c >> 1; - c += b; - base[4].y = c >> 2; - base[1].y = a >> 1; - a += b; - base[2].y = a >> 2; - base[3].y = ( a + c ) >> 3; -} - -/* Return the average of `angle1' and `angle2'. */ -/* This gives correct result even if `angle1' and `angle2' */ -/* have opposite signs. */ -static SW_FT_Angle ft_angle_mean(SW_FT_Angle angle1, SW_FT_Angle angle2) -{ - return angle1 + SW_FT_Angle_Diff(angle1, angle2) / 2; -} - -static SW_FT_Bool ft_cubic_is_small_enough(SW_FT_Vector* base, - SW_FT_Angle* angle_in, - SW_FT_Angle* angle_mid, - SW_FT_Angle* angle_out) -{ - SW_FT_Vector d1, d2, d3; - SW_FT_Angle theta1, theta2; - SW_FT_Int close1, close2, close3; - - d1.x = base[2].x - base[3].x; - d1.y = base[2].y - base[3].y; - d2.x = base[1].x - base[2].x; - d2.y = base[1].y - base[2].y; - d3.x = base[0].x - base[1].x; - d3.y = base[0].y - base[1].y; - - close1 = SW_FT_IS_SMALL(d1.x) && SW_FT_IS_SMALL(d1.y); - close2 = SW_FT_IS_SMALL(d2.x) && SW_FT_IS_SMALL(d2.y); - close3 = SW_FT_IS_SMALL(d3.x) && SW_FT_IS_SMALL(d3.y); - - if (close1) { - if (close2) { - if (close3) { - /* basically a point; */ - /* do nothing to retain original direction */ - } else /* !close3 */ - { - *angle_in = *angle_mid = *angle_out = SW_FT_Atan2(d3.x, d3.y); - } - } else /* !close2 */ - { - if (close3) { - *angle_in = *angle_mid = *angle_out = SW_FT_Atan2(d2.x, d2.y); - } else /* !close3 */ - { - *angle_in = *angle_mid = SW_FT_Atan2(d2.x, d2.y); - *angle_out = SW_FT_Atan2(d3.x, d3.y); - } - } - } else /* !close1 */ - { - if (close2) { - if (close3) { - *angle_in = *angle_mid = *angle_out = SW_FT_Atan2(d1.x, d1.y); - } else /* !close3 */ - { - *angle_in = SW_FT_Atan2(d1.x, d1.y); - *angle_out = SW_FT_Atan2(d3.x, d3.y); - *angle_mid = ft_angle_mean(*angle_in, *angle_out); - } - } else /* !close2 */ - { - if (close3) { - *angle_in = SW_FT_Atan2(d1.x, d1.y); - *angle_mid = *angle_out = SW_FT_Atan2(d2.x, d2.y); - } else /* !close3 */ - { - *angle_in = SW_FT_Atan2(d1.x, d1.y); - *angle_mid = SW_FT_Atan2(d2.x, d2.y); - *angle_out = SW_FT_Atan2(d3.x, d3.y); - } - } - } - - theta1 = ft_pos_abs(SW_FT_Angle_Diff(*angle_in, *angle_mid)); - theta2 = ft_pos_abs(SW_FT_Angle_Diff(*angle_mid, *angle_out)); - - return SW_FT_BOOL(theta1 < SW_FT_SMALL_CUBIC_THRESHOLD && - theta2 < SW_FT_SMALL_CUBIC_THRESHOLD); -} - -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** STROKE BORDERS *****/ -/***** *****/ -/*************************************************************************/ -/*************************************************************************/ - -typedef enum SW_FT_StrokeTags_ { - SW_FT_STROKE_TAG_ON = 1, /* on-curve point */ - SW_FT_STROKE_TAG_CUBIC = 2, /* cubic off-point */ - SW_FT_STROKE_TAG_BEGIN = 4, /* sub-path start */ - SW_FT_STROKE_TAG_END = 8 /* sub-path end */ - -} SW_FT_StrokeTags; - -#define SW_FT_STROKE_TAG_BEGIN_END \ - (SW_FT_STROKE_TAG_BEGIN | SW_FT_STROKE_TAG_END) - -typedef struct SW_FT_StrokeBorderRec_ { - SW_FT_UInt num_points; - SW_FT_UInt max_points; - SW_FT_Vector* points; - SW_FT_Byte* tags; - SW_FT_Bool movable; /* TRUE for ends of lineto borders */ - SW_FT_Int start; /* index of current sub-path start point */ - SW_FT_Bool valid; - -} SW_FT_StrokeBorderRec, *SW_FT_StrokeBorder; - -SW_FT_Error SW_FT_Outline_Check(SW_FT_Outline* outline) -{ - if (outline) { - SW_FT_Int n_points = outline->n_points; - SW_FT_Int n_contours = outline->n_contours; - SW_FT_Int end0, end; - SW_FT_Int n; - - /* empty glyph? */ - if (n_points == 0 && n_contours == 0) return 0; - - /* check point and contour counts */ - if (n_points <= 0 || n_contours <= 0) goto Bad; - - end0 = end = -1; - for (n = 0; n < n_contours; n++) { - end = outline->contours[n]; - - /* note that we don't accept empty contours */ - if (end <= end0 || end >= n_points) goto Bad; - - end0 = end; - } - - if (end != n_points - 1) goto Bad; - - /* XXX: check the tags array */ - return 0; - } - -Bad: - return -1; // SW_FT_THROW( Invalid_Argument ); -} - -void SW_FT_Outline_Get_CBox(const SW_FT_Outline* outline, SW_FT_BBox* acbox) -{ - SW_FT_Pos xMin, yMin, xMax, yMax; - - if (outline && acbox) { - if (outline->n_points == 0) { - xMin = 0; - yMin = 0; - xMax = 0; - yMax = 0; - } else { - SW_FT_Vector* vec = outline->points; - SW_FT_Vector* limit = vec + outline->n_points; - - xMin = xMax = vec->x; - yMin = yMax = vec->y; - vec++; - - for (; vec < limit; vec++) { - SW_FT_Pos x, y; - - x = vec->x; - if (x < xMin) xMin = x; - if (x > xMax) xMax = x; - - y = vec->y; - if (y < yMin) yMin = y; - if (y > yMax) yMax = y; - } - } - acbox->xMin = xMin; - acbox->xMax = xMax; - acbox->yMin = yMin; - acbox->yMax = yMax; - } -} - -static SW_FT_Error ft_stroke_border_grow(SW_FT_StrokeBorder border, - SW_FT_UInt new_points) -{ - SW_FT_UInt old_max = border->max_points; - SW_FT_UInt new_max = border->num_points + new_points; - SW_FT_Error error = 0; - - if (new_max > old_max) { - SW_FT_UInt cur_max = old_max; - - while (cur_max < new_max) cur_max += (cur_max >> 1) + 16; - - border->points = (SW_FT_Vector*)realloc(border->points, - cur_max * sizeof(SW_FT_Vector)); - border->tags = - (SW_FT_Byte*)realloc(border->tags, cur_max * sizeof(SW_FT_Byte)); - - if (!border->points || !border->tags) goto Exit; - - border->max_points = cur_max; - } - -Exit: - return error; -} - -static void ft_stroke_border_close(SW_FT_StrokeBorder border, - SW_FT_Bool reverse) -{ - SW_FT_UInt start = border->start; - SW_FT_UInt count = border->num_points; - - assert(border->start >= 0); - - /* don't record empty paths! */ - if (count <= start + 1U) - border->num_points = start; - else { - /* copy the last point to the start of this sub-path, since */ - /* it contains the `adjusted' starting coordinates */ - border->num_points = --count; - border->points[start] = border->points[count]; - - if (reverse) { - /* reverse the points */ - { - SW_FT_Vector* vec1 = border->points + start + 1; - SW_FT_Vector* vec2 = border->points + count - 1; - - for (; vec1 < vec2; vec1++, vec2--) { - SW_FT_Vector tmp; - - tmp = *vec1; - *vec1 = *vec2; - *vec2 = tmp; - } - } - - /* then the tags */ - { - SW_FT_Byte* tag1 = border->tags + start + 1; - SW_FT_Byte* tag2 = border->tags + count - 1; - - for (; tag1 < tag2; tag1++, tag2--) { - SW_FT_Byte tmp; - - tmp = *tag1; - *tag1 = *tag2; - *tag2 = tmp; - } - } - } - - border->tags[start] |= SW_FT_STROKE_TAG_BEGIN; - border->tags[count - 1] |= SW_FT_STROKE_TAG_END; - } - - border->start = -1; - border->movable = FALSE; -} - -static SW_FT_Error ft_stroke_border_lineto(SW_FT_StrokeBorder border, - SW_FT_Vector* to, SW_FT_Bool movable) -{ - SW_FT_Error error = 0; - - assert(border->start >= 0); - - if (border->movable) { - /* move last point */ - border->points[border->num_points - 1] = *to; - } else { - /* don't add zero-length lineto */ - if (border->num_points > 0 && - SW_FT_IS_SMALL(border->points[border->num_points - 1].x - to->x) && - SW_FT_IS_SMALL(border->points[border->num_points - 1].y - to->y)) - return error; - - /* add one point */ - error = ft_stroke_border_grow(border, 1); - if (!error) { - SW_FT_Vector* vec = border->points + border->num_points; - SW_FT_Byte* tag = border->tags + border->num_points; - - vec[0] = *to; - tag[0] = SW_FT_STROKE_TAG_ON; - - border->num_points += 1; - } - } - border->movable = movable; - return error; -} - -static SW_FT_Error ft_stroke_border_conicto(SW_FT_StrokeBorder border, - SW_FT_Vector* control, - SW_FT_Vector* to) -{ - SW_FT_Error error; - - assert(border->start >= 0); - - error = ft_stroke_border_grow(border, 2); - if (!error) { - SW_FT_Vector* vec = border->points + border->num_points; - SW_FT_Byte* tag = border->tags + border->num_points; - - vec[0] = *control; - vec[1] = *to; - - tag[0] = 0; - tag[1] = SW_FT_STROKE_TAG_ON; - - border->num_points += 2; - } - - border->movable = FALSE; - - return error; -} - -static SW_FT_Error ft_stroke_border_cubicto(SW_FT_StrokeBorder border, - SW_FT_Vector* control1, - SW_FT_Vector* control2, - SW_FT_Vector* to) -{ - SW_FT_Error error; - - assert(border->start >= 0); - - error = ft_stroke_border_grow(border, 3); - if (!error) { - SW_FT_Vector* vec = border->points + border->num_points; - SW_FT_Byte* tag = border->tags + border->num_points; - - vec[0] = *control1; - vec[1] = *control2; - vec[2] = *to; - - tag[0] = SW_FT_STROKE_TAG_CUBIC; - tag[1] = SW_FT_STROKE_TAG_CUBIC; - tag[2] = SW_FT_STROKE_TAG_ON; - - border->num_points += 3; - } - - border->movable = FALSE; - - return error; -} - -#define SW_FT_ARC_CUBIC_ANGLE (SW_FT_ANGLE_PI / 2) - - -static SW_FT_Error -ft_stroke_border_arcto( SW_FT_StrokeBorder border, - SW_FT_Vector* center, - SW_FT_Fixed radius, - SW_FT_Angle angle_start, - SW_FT_Angle angle_diff ) -{ - SW_FT_Fixed coef; - SW_FT_Vector a0, a1, a2, a3; - SW_FT_Int i, arcs = 1; - SW_FT_Error error = 0; - - - /* number of cubic arcs to draw */ - while ( angle_diff > SW_FT_ARC_CUBIC_ANGLE * arcs || - -angle_diff > SW_FT_ARC_CUBIC_ANGLE * arcs ) - arcs++; - - /* control tangents */ - coef = SW_FT_Tan( angle_diff / ( 4 * arcs ) ); - coef += coef / 3; - - /* compute start and first control point */ - SW_FT_Vector_From_Polar( &a0, radius, angle_start ); - a1.x = SW_FT_MulFix( -a0.y, coef ); - a1.y = SW_FT_MulFix( a0.x, coef ); - - a0.x += center->x; - a0.y += center->y; - a1.x += a0.x; - a1.y += a0.y; - - for ( i = 1; i <= arcs; i++ ) - { - /* compute end and second control point */ - SW_FT_Vector_From_Polar( &a3, radius, - angle_start + i * angle_diff / arcs ); - a2.x = SW_FT_MulFix( a3.y, coef ); - a2.y = SW_FT_MulFix( -a3.x, coef ); - - a3.x += center->x; - a3.y += center->y; - a2.x += a3.x; - a2.y += a3.y; - - /* add cubic arc */ - error = ft_stroke_border_cubicto( border, &a1, &a2, &a3 ); - if ( error ) - break; - - /* a0 = a3; */ - a1.x = a3.x - a2.x + a3.x; - a1.y = a3.y - a2.y + a3.y; - } - - return error; -} - -static SW_FT_Error ft_stroke_border_moveto(SW_FT_StrokeBorder border, - SW_FT_Vector* to) -{ - /* close current open path if any ? */ - if (border->start >= 0) ft_stroke_border_close(border, FALSE); - - border->start = border->num_points; - border->movable = FALSE; - - return ft_stroke_border_lineto(border, to, FALSE); -} - -static void ft_stroke_border_init(SW_FT_StrokeBorder border) -{ - border->points = NULL; - border->tags = NULL; - - border->num_points = 0; - border->max_points = 0; - border->start = -1; - border->valid = FALSE; -} - -static void ft_stroke_border_reset(SW_FT_StrokeBorder border) -{ - border->num_points = 0; - border->start = -1; - border->valid = FALSE; -} - -static void ft_stroke_border_done(SW_FT_StrokeBorder border) -{ - free(border->points); - free(border->tags); - - border->num_points = 0; - border->max_points = 0; - border->start = -1; - border->valid = FALSE; -} - -static SW_FT_Error ft_stroke_border_get_counts(SW_FT_StrokeBorder border, - SW_FT_UInt* anum_points, - SW_FT_UInt* anum_contours) -{ - SW_FT_Error error = 0; - SW_FT_UInt num_points = 0; - SW_FT_UInt num_contours = 0; - - SW_FT_UInt count = border->num_points; - SW_FT_Vector* point = border->points; - SW_FT_Byte* tags = border->tags; - SW_FT_Int in_contour = 0; - - for (; count > 0; count--, num_points++, point++, tags++) { - if (tags[0] & SW_FT_STROKE_TAG_BEGIN) { - if (in_contour != 0) goto Fail; - - in_contour = 1; - } else if (in_contour == 0) - goto Fail; - - if (tags[0] & SW_FT_STROKE_TAG_END) { - in_contour = 0; - num_contours++; - } - } - - if (in_contour != 0) goto Fail; - - border->valid = TRUE; - -Exit: - *anum_points = num_points; - *anum_contours = num_contours; - return error; - -Fail: - num_points = 0; - num_contours = 0; - goto Exit; -} - -static void ft_stroke_border_export(SW_FT_StrokeBorder border, - SW_FT_Outline* outline) -{ - /* copy point locations */ - memcpy(outline->points + outline->n_points, border->points, - border->num_points * sizeof(SW_FT_Vector)); - - /* copy tags */ - { - SW_FT_UInt count = border->num_points; - SW_FT_Byte* read = border->tags; - SW_FT_Byte* write = (SW_FT_Byte*)outline->tags + outline->n_points; - - for (; count > 0; count--, read++, write++) { - if (*read & SW_FT_STROKE_TAG_ON) - *write = SW_FT_CURVE_TAG_ON; - else if (*read & SW_FT_STROKE_TAG_CUBIC) - *write = SW_FT_CURVE_TAG_CUBIC; - else - *write = SW_FT_CURVE_TAG_CONIC; - } - } - - /* copy contours */ - { - SW_FT_UInt count = border->num_points; - SW_FT_Byte* tags = border->tags; - SW_FT_Short* write = outline->contours + outline->n_contours; - SW_FT_Short idx = (SW_FT_Short)outline->n_points; - - for (; count > 0; count--, tags++, idx++) { - if (*tags & SW_FT_STROKE_TAG_END) { - *write++ = idx; - outline->n_contours++; - } - } - } - - outline->n_points = (short)(outline->n_points + border->num_points); - - assert(SW_FT_Outline_Check(outline) == 0); -} - -/*************************************************************************/ -/*************************************************************************/ -/***** *****/ -/***** STROKER *****/ -/***** *****/ -/*************************************************************************/ -/*************************************************************************/ - -#define SW_FT_SIDE_TO_ROTATE(s) (SW_FT_ANGLE_PI2 - (s)*SW_FT_ANGLE_PI) - -typedef struct SW_FT_StrokerRec_ { - SW_FT_Angle angle_in; /* direction into curr join */ - SW_FT_Angle angle_out; /* direction out of join */ - SW_FT_Vector center; /* current position */ - SW_FT_Fixed line_length; /* length of last lineto */ - SW_FT_Bool first_point; /* is this the start? */ - SW_FT_Bool subpath_open; /* is the subpath open? */ - SW_FT_Angle subpath_angle; /* subpath start direction */ - SW_FT_Vector subpath_start; /* subpath start position */ - SW_FT_Fixed subpath_line_length; /* subpath start lineto len */ - SW_FT_Bool handle_wide_strokes; /* use wide strokes logic? */ - - SW_FT_Stroker_LineCap line_cap; - SW_FT_Stroker_LineJoin line_join; - SW_FT_Stroker_LineJoin line_join_saved; - SW_FT_Fixed miter_limit; - SW_FT_Fixed radius; - - SW_FT_StrokeBorderRec borders[2]; -} SW_FT_StrokerRec; - -/* documentation is in ftstroke.h */ - -SW_FT_Error SW_FT_Stroker_New(SW_FT_Stroker* astroker) -{ - SW_FT_Error error = 0; /* assigned in SW_FT_NEW */ - SW_FT_Stroker stroker = NULL; - - stroker = (SW_FT_StrokerRec*)calloc(1, sizeof(SW_FT_StrokerRec)); - if (stroker) { - ft_stroke_border_init(&stroker->borders[0]); - ft_stroke_border_init(&stroker->borders[1]); - } - - *astroker = stroker; - - return error; -} - -void SW_FT_Stroker_Rewind(SW_FT_Stroker stroker) -{ - if (stroker) { - ft_stroke_border_reset(&stroker->borders[0]); - ft_stroke_border_reset(&stroker->borders[1]); - } -} - -/* documentation is in ftstroke.h */ - -void SW_FT_Stroker_Set(SW_FT_Stroker stroker, SW_FT_Fixed radius, - SW_FT_Stroker_LineCap line_cap, - SW_FT_Stroker_LineJoin line_join, - SW_FT_Fixed miter_limit) -{ - stroker->radius = radius; - stroker->line_cap = line_cap; - stroker->line_join = line_join; - stroker->miter_limit = miter_limit; - - /* ensure miter limit has sensible value */ - if (stroker->miter_limit < 0x10000) stroker->miter_limit = 0x10000; - - /* save line join style: */ - /* line join style can be temporarily changed when stroking curves */ - stroker->line_join_saved = line_join; - - SW_FT_Stroker_Rewind(stroker); -} - -/* documentation is in ftstroke.h */ - -void SW_FT_Stroker_Done(SW_FT_Stroker stroker) -{ - if (stroker) { - ft_stroke_border_done(&stroker->borders[0]); - ft_stroke_border_done(&stroker->borders[1]); - - free(stroker); - } -} - -/* create a circular arc at a corner or cap */ -static SW_FT_Error ft_stroker_arcto(SW_FT_Stroker stroker, SW_FT_Int side) -{ - SW_FT_Angle total, rotate; - SW_FT_Fixed radius = stroker->radius; - SW_FT_Error error = 0; - SW_FT_StrokeBorder border = stroker->borders + side; - - rotate = SW_FT_SIDE_TO_ROTATE(side); - - total = SW_FT_Angle_Diff(stroker->angle_in, stroker->angle_out); - if (total == SW_FT_ANGLE_PI) total = -rotate * 2; - - error = ft_stroke_border_arcto(border, &stroker->center, radius, - stroker->angle_in + rotate, total); - border->movable = FALSE; - return error; -} - -/* add a cap at the end of an opened path */ -static SW_FT_Error -ft_stroker_cap(SW_FT_Stroker stroker, - SW_FT_Angle angle, - SW_FT_Int side) -{ - SW_FT_Error error = 0; - - if (stroker->line_cap == SW_FT_STROKER_LINECAP_ROUND) - { - /* add a round cap */ - stroker->angle_in = angle; - stroker->angle_out = angle + SW_FT_ANGLE_PI; - - error = ft_stroker_arcto(stroker, side); - } - else - { - /* add a square or butt cap */ - SW_FT_Vector middle, delta; - SW_FT_Fixed radius = stroker->radius; - SW_FT_StrokeBorder border = stroker->borders + side; - - /* compute middle point and first angle point */ - SW_FT_Vector_From_Polar( &middle, radius, angle ); - delta.x = side ? middle.y : -middle.y; - delta.y = side ? -middle.x : middle.x; - - if ( stroker->line_cap == SW_FT_STROKER_LINECAP_SQUARE ) - { - middle.x += stroker->center.x; - middle.y += stroker->center.y; - } - else /* SW_FT_STROKER_LINECAP_BUTT */ - { - middle.x = stroker->center.x; - middle.y = stroker->center.y; - } - - delta.x += middle.x; - delta.y += middle.y; - - error = ft_stroke_border_lineto( border, &delta, FALSE ); - if ( error ) - goto Exit; - - /* compute second angle point */ - delta.x = middle.x - delta.x + middle.x; - delta.y = middle.y - delta.y + middle.y; - - error = ft_stroke_border_lineto( border, &delta, FALSE ); - } - -Exit: - return error; -} - -/* process an inside corner, i.e. compute intersection */ -static SW_FT_Error ft_stroker_inside(SW_FT_Stroker stroker, SW_FT_Int side, - SW_FT_Fixed line_length) -{ - SW_FT_StrokeBorder border = stroker->borders + side; - SW_FT_Angle phi, theta, rotate; - SW_FT_Fixed length; - SW_FT_Vector sigma, delta; - SW_FT_Error error = 0; - SW_FT_Bool intersect; /* use intersection of lines? */ - - rotate = SW_FT_SIDE_TO_ROTATE(side); - - theta = SW_FT_Angle_Diff(stroker->angle_in, stroker->angle_out) / 2; - - /* Only intersect borders if between two lineto's and both */ - /* lines are long enough (line_length is zero for curves). */ - if (!border->movable || line_length == 0 || - theta > 0x59C000 || theta < -0x59C000 ) - intersect = FALSE; - else { - /* compute minimum required length of lines */ - SW_FT_Fixed min_length; - - - SW_FT_Vector_Unit( &sigma, theta ); - min_length = - ft_pos_abs( SW_FT_MulDiv( stroker->radius, sigma.y, sigma.x ) ); - - intersect = SW_FT_BOOL( min_length && - stroker->line_length >= min_length && - line_length >= min_length ); - } - - if (!intersect) { - SW_FT_Vector_From_Polar(&delta, stroker->radius, - stroker->angle_out + rotate); - delta.x += stroker->center.x; - delta.y += stroker->center.y; - - border->movable = FALSE; - } else { - /* compute median angle */ - phi = stroker->angle_in + theta + rotate; - - length = SW_FT_DivFix( stroker->radius, sigma.x ); - - SW_FT_Vector_From_Polar( &delta, length, phi ); - delta.x += stroker->center.x; - delta.y += stroker->center.y; - } - - error = ft_stroke_border_lineto(border, &delta, FALSE); - - return error; -} - - /* process an outside corner, i.e. compute bevel/miter/round */ -static SW_FT_Error -ft_stroker_outside( SW_FT_Stroker stroker, - SW_FT_Int side, - SW_FT_Fixed line_length ) -{ - SW_FT_StrokeBorder border = stroker->borders + side; - SW_FT_Error error; - SW_FT_Angle rotate; - - - if ( stroker->line_join == SW_FT_STROKER_LINEJOIN_ROUND ) - error = ft_stroker_arcto( stroker, side ); - else - { - /* this is a mitered (pointed) or beveled (truncated) corner */ - SW_FT_Fixed radius = stroker->radius; - SW_FT_Vector sigma; - SW_FT_Angle theta = 0, phi = 0; - SW_FT_Bool bevel, fixed_bevel; - - - rotate = SW_FT_SIDE_TO_ROTATE( side ); - - bevel = - SW_FT_BOOL( stroker->line_join == SW_FT_STROKER_LINEJOIN_BEVEL ); - - fixed_bevel = - SW_FT_BOOL( stroker->line_join != SW_FT_STROKER_LINEJOIN_MITER_VARIABLE ); - - /* check miter limit first */ - if ( !bevel ) - { - theta = SW_FT_Angle_Diff( stroker->angle_in, stroker->angle_out ) / 2; - - if ( theta == SW_FT_ANGLE_PI2 ) - theta = -rotate; - - phi = stroker->angle_in + theta + rotate; - - SW_FT_Vector_From_Polar( &sigma, stroker->miter_limit, theta ); - - /* is miter limit exceeded? */ - if ( sigma.x < 0x10000L ) - { - /* don't create variable bevels for very small deviations; */ - /* FT_Sin(x) = 0 for x <= 57 */ - if ( fixed_bevel || ft_pos_abs( theta ) > 57 ) - bevel = TRUE; - } - } - - if ( bevel ) /* this is a bevel (broken angle) */ - { - if ( fixed_bevel ) - { - /* the outer corners are simply joined together */ - SW_FT_Vector delta; - - - /* add bevel */ - SW_FT_Vector_From_Polar( &delta, - radius, - stroker->angle_out + rotate ); - delta.x += stroker->center.x; - delta.y += stroker->center.y; - - border->movable = FALSE; - error = ft_stroke_border_lineto( border, &delta, FALSE ); - } - else /* variable bevel or clipped miter */ - { - /* the miter is truncated */ - SW_FT_Vector middle, delta; - SW_FT_Fixed coef; - - - /* compute middle point and first angle point */ - SW_FT_Vector_From_Polar( &middle, - SW_FT_MulFix( radius, stroker->miter_limit ), - phi ); - - coef = SW_FT_DivFix( 0x10000L - sigma.x, sigma.y ); - delta.x = SW_FT_MulFix( middle.y, coef ); - delta.y = SW_FT_MulFix( -middle.x, coef ); - - middle.x += stroker->center.x; - middle.y += stroker->center.y; - delta.x += middle.x; - delta.y += middle.y; - - error = ft_stroke_border_lineto( border, &delta, FALSE ); - if ( error ) - goto Exit; - - /* compute second angle point */ - delta.x = middle.x - delta.x + middle.x; - delta.y = middle.y - delta.y + middle.y; - - error = ft_stroke_border_lineto( border, &delta, FALSE ); - if ( error ) - goto Exit; - - /* finally, add an end point; only needed if not lineto */ - /* (line_length is zero for curves) */ - if ( line_length == 0 ) - { - SW_FT_Vector_From_Polar( &delta, - radius, - stroker->angle_out + rotate ); - - delta.x += stroker->center.x; - delta.y += stroker->center.y; - - error = ft_stroke_border_lineto( border, &delta, FALSE ); - } - } - } - else /* this is a miter (intersection) */ - { - SW_FT_Fixed length; - SW_FT_Vector delta; - - - length = SW_FT_MulDiv( stroker->radius, stroker->miter_limit, sigma.x ); - - SW_FT_Vector_From_Polar( &delta, length, phi ); - delta.x += stroker->center.x; - delta.y += stroker->center.y; - - error = ft_stroke_border_lineto( border, &delta, FALSE ); - if ( error ) - goto Exit; - - /* now add an end point; only needed if not lineto */ - /* (line_length is zero for curves) */ - if ( line_length == 0 ) - { - SW_FT_Vector_From_Polar( &delta, - stroker->radius, - stroker->angle_out + rotate ); - delta.x += stroker->center.x; - delta.y += stroker->center.y; - - error = ft_stroke_border_lineto( border, &delta, FALSE ); - } - } - } - - Exit: - return error; -} - -static SW_FT_Error ft_stroker_process_corner(SW_FT_Stroker stroker, - SW_FT_Fixed line_length) -{ - SW_FT_Error error = 0; - SW_FT_Angle turn; - SW_FT_Int inside_side; - - turn = SW_FT_Angle_Diff(stroker->angle_in, stroker->angle_out); - - /* no specific corner processing is required if the turn is 0 */ - if (turn == 0) goto Exit; - - /* when we turn to the right, the inside side is 0 */ - inside_side = 0; - - /* otherwise, the inside side is 1 */ - if (turn < 0) inside_side = 1; - - /* process the inside side */ - error = ft_stroker_inside(stroker, inside_side, line_length); - if (error) goto Exit; - - /* process the outside side */ - error = ft_stroker_outside(stroker, 1 - inside_side, line_length); - -Exit: - return error; -} - -/* add two points to the left and right borders corresponding to the */ -/* start of the subpath */ -static SW_FT_Error ft_stroker_subpath_start(SW_FT_Stroker stroker, - SW_FT_Angle start_angle, - SW_FT_Fixed line_length) -{ - SW_FT_Vector delta; - SW_FT_Vector point; - SW_FT_Error error; - SW_FT_StrokeBorder border; - - SW_FT_Vector_From_Polar(&delta, stroker->radius, - start_angle + SW_FT_ANGLE_PI2); - - point.x = stroker->center.x + delta.x; - point.y = stroker->center.y + delta.y; - - border = stroker->borders; - error = ft_stroke_border_moveto(border, &point); - if (error) goto Exit; - - point.x = stroker->center.x - delta.x; - point.y = stroker->center.y - delta.y; - - border++; - error = ft_stroke_border_moveto(border, &point); - - /* save angle, position, and line length for last join */ - /* (line_length is zero for curves) */ - stroker->subpath_angle = start_angle; - stroker->first_point = FALSE; - stroker->subpath_line_length = line_length; - -Exit: - return error; -} - -/* documentation is in ftstroke.h */ - -SW_FT_Error SW_FT_Stroker_LineTo(SW_FT_Stroker stroker, SW_FT_Vector* to) -{ - SW_FT_Error error = 0; - SW_FT_StrokeBorder border; - SW_FT_Vector delta; - SW_FT_Angle angle; - SW_FT_Int side; - SW_FT_Fixed line_length; - - delta.x = to->x - stroker->center.x; - delta.y = to->y - stroker->center.y; - - /* a zero-length lineto is a no-op; avoid creating a spurious corner */ - if (delta.x == 0 && delta.y == 0) goto Exit; - - /* compute length of line */ - line_length = SW_FT_Vector_Length(&delta); - - angle = SW_FT_Atan2(delta.x, delta.y); - SW_FT_Vector_From_Polar(&delta, stroker->radius, angle + SW_FT_ANGLE_PI2); - - /* process corner if necessary */ - if (stroker->first_point) { - /* This is the first segment of a subpath. We need to */ - /* add a point to each border at their respective starting */ - /* point locations. */ - error = ft_stroker_subpath_start(stroker, angle, line_length); - if (error) goto Exit; - } else { - /* process the current corner */ - stroker->angle_out = angle; - error = ft_stroker_process_corner(stroker, line_length); - if (error) goto Exit; - } - - /* now add a line segment to both the `inside' and `outside' paths */ - for (border = stroker->borders, side = 1; side >= 0; side--, border++) { - SW_FT_Vector point; - - point.x = to->x + delta.x; - point.y = to->y + delta.y; - - /* the ends of lineto borders are movable */ - error = ft_stroke_border_lineto(border, &point, TRUE); - if (error) goto Exit; - - delta.x = -delta.x; - delta.y = -delta.y; - } - - stroker->angle_in = angle; - stroker->center = *to; - stroker->line_length = line_length; - -Exit: - return error; -} - -/* documentation is in ftstroke.h */ - -SW_FT_Error SW_FT_Stroker_ConicTo(SW_FT_Stroker stroker, SW_FT_Vector* control, - SW_FT_Vector* to) -{ - SW_FT_Error error = 0; - SW_FT_Vector bez_stack[34]; - SW_FT_Vector* arc; - SW_FT_Vector* limit = bez_stack + 30; - SW_FT_Bool first_arc = TRUE; - - /* if all control points are coincident, this is a no-op; */ - /* avoid creating a spurious corner */ - if (SW_FT_IS_SMALL(stroker->center.x - control->x) && - SW_FT_IS_SMALL(stroker->center.y - control->y) && - SW_FT_IS_SMALL(control->x - to->x) && - SW_FT_IS_SMALL(control->y - to->y)) { - stroker->center = *to; - goto Exit; - } - - arc = bez_stack; - arc[0] = *to; - arc[1] = *control; - arc[2] = stroker->center; - - while (arc >= bez_stack) { - SW_FT_Angle angle_in, angle_out; - - /* initialize with current direction */ - angle_in = angle_out = stroker->angle_in; - - if (arc < limit && - !ft_conic_is_small_enough(arc, &angle_in, &angle_out)) { - if (stroker->first_point) stroker->angle_in = angle_in; - - ft_conic_split(arc); - arc += 2; - continue; - } - - if (first_arc) { - first_arc = FALSE; - - /* process corner if necessary */ - if (stroker->first_point) - error = ft_stroker_subpath_start(stroker, angle_in, 0); - else { - stroker->angle_out = angle_in; - error = ft_stroker_process_corner(stroker, 0); - } - } else if (ft_pos_abs(SW_FT_Angle_Diff(stroker->angle_in, angle_in)) > - SW_FT_SMALL_CONIC_THRESHOLD / 4) { - /* if the deviation from one arc to the next is too great, */ - /* add a round corner */ - stroker->center = arc[2]; - stroker->angle_out = angle_in; - stroker->line_join = SW_FT_STROKER_LINEJOIN_ROUND; - - error = ft_stroker_process_corner(stroker, 0); - - /* reinstate line join style */ - stroker->line_join = stroker->line_join_saved; - } - - if (error) goto Exit; - - /* the arc's angle is small enough; we can add it directly to each */ - /* border */ - { - SW_FT_Vector ctrl, end; - SW_FT_Angle theta, phi, rotate, alpha0 = 0; - SW_FT_Fixed length; - SW_FT_StrokeBorder border; - SW_FT_Int side; - - theta = SW_FT_Angle_Diff(angle_in, angle_out) / 2; - phi = angle_in + theta; - length = SW_FT_DivFix(stroker->radius, SW_FT_Cos(theta)); - - /* compute direction of original arc */ - if (stroker->handle_wide_strokes) - alpha0 = SW_FT_Atan2(arc[0].x - arc[2].x, arc[0].y - arc[2].y); - - for (border = stroker->borders, side = 0; side <= 1; - side++, border++) { - rotate = SW_FT_SIDE_TO_ROTATE(side); - - /* compute control point */ - SW_FT_Vector_From_Polar(&ctrl, length, phi + rotate); - ctrl.x += arc[1].x; - ctrl.y += arc[1].y; - - /* compute end point */ - SW_FT_Vector_From_Polar(&end, stroker->radius, - angle_out + rotate); - end.x += arc[0].x; - end.y += arc[0].y; - - if (stroker->handle_wide_strokes) { - SW_FT_Vector start; - SW_FT_Angle alpha1; - - /* determine whether the border radius is greater than the - */ - /* radius of curvature of the original arc */ - start = border->points[border->num_points - 1]; - - alpha1 = SW_FT_Atan2(end.x - start.x, end.y - start.y); - - /* is the direction of the border arc opposite to */ - /* that of the original arc? */ - if (ft_pos_abs(SW_FT_Angle_Diff(alpha0, alpha1)) > - SW_FT_ANGLE_PI / 2) { - SW_FT_Angle beta, gamma; - SW_FT_Vector bvec, delta; - SW_FT_Fixed blen, sinA, sinB, alen; - - /* use the sine rule to find the intersection point */ - beta = - SW_FT_Atan2(arc[2].x - start.x, arc[2].y - start.y); - gamma = SW_FT_Atan2(arc[0].x - end.x, arc[0].y - end.y); - - bvec.x = end.x - start.x; - bvec.y = end.y - start.y; - - blen = SW_FT_Vector_Length(&bvec); - - sinA = ft_pos_abs(SW_FT_Sin(alpha1 - gamma)); - sinB = ft_pos_abs(SW_FT_Sin(beta - gamma)); - - alen = SW_FT_MulDiv(blen, sinA, sinB); - - SW_FT_Vector_From_Polar(&delta, alen, beta); - delta.x += start.x; - delta.y += start.y; - - /* circumnavigate the negative sector backwards */ - border->movable = FALSE; - error = ft_stroke_border_lineto(border, &delta, FALSE); - if (error) goto Exit; - error = ft_stroke_border_lineto(border, &end, FALSE); - if (error) goto Exit; - error = ft_stroke_border_conicto(border, &ctrl, &start); - if (error) goto Exit; - /* and then move to the endpoint */ - error = ft_stroke_border_lineto(border, &end, FALSE); - if (error) goto Exit; - - continue; - } - - /* else fall through */ - } - - /* simply add an arc */ - error = ft_stroke_border_conicto(border, &ctrl, &end); - if (error) goto Exit; - } - } - - arc -= 2; - - stroker->angle_in = angle_out; - } - - stroker->center = *to; - -Exit: - return error; -} - -/* documentation is in ftstroke.h */ - -SW_FT_Error SW_FT_Stroker_CubicTo(SW_FT_Stroker stroker, SW_FT_Vector* control1, - SW_FT_Vector* control2, SW_FT_Vector* to) -{ - SW_FT_Error error = 0; - SW_FT_Vector bez_stack[37]; - SW_FT_Vector* arc; - SW_FT_Vector* limit = bez_stack + 32; - SW_FT_Bool first_arc = TRUE; - - /* if all control points are coincident, this is a no-op; */ - /* avoid creating a spurious corner */ - if (SW_FT_IS_SMALL(stroker->center.x - control1->x) && - SW_FT_IS_SMALL(stroker->center.y - control1->y) && - SW_FT_IS_SMALL(control1->x - control2->x) && - SW_FT_IS_SMALL(control1->y - control2->y) && - SW_FT_IS_SMALL(control2->x - to->x) && - SW_FT_IS_SMALL(control2->y - to->y)) { - stroker->center = *to; - goto Exit; - } - - arc = bez_stack; - arc[0] = *to; - arc[1] = *control2; - arc[2] = *control1; - arc[3] = stroker->center; - - while (arc >= bez_stack) { - SW_FT_Angle angle_in, angle_mid, angle_out; - - /* initialize with current direction */ - angle_in = angle_out = angle_mid = stroker->angle_in; - - if (arc < limit && - !ft_cubic_is_small_enough(arc, &angle_in, &angle_mid, &angle_out)) { - if (stroker->first_point) stroker->angle_in = angle_in; - - ft_cubic_split(arc); - arc += 3; - continue; - } - - if (first_arc) { - first_arc = FALSE; - - /* process corner if necessary */ - if (stroker->first_point) - error = ft_stroker_subpath_start(stroker, angle_in, 0); - else { - stroker->angle_out = angle_in; - error = ft_stroker_process_corner(stroker, 0); - } - } else if (ft_pos_abs(SW_FT_Angle_Diff(stroker->angle_in, angle_in)) > - SW_FT_SMALL_CUBIC_THRESHOLD / 4) { - /* if the deviation from one arc to the next is too great, */ - /* add a round corner */ - stroker->center = arc[3]; - stroker->angle_out = angle_in; - stroker->line_join = SW_FT_STROKER_LINEJOIN_ROUND; - - error = ft_stroker_process_corner(stroker, 0); - - /* reinstate line join style */ - stroker->line_join = stroker->line_join_saved; - } - - if (error) goto Exit; - - /* the arc's angle is small enough; we can add it directly to each */ - /* border */ - { - SW_FT_Vector ctrl1, ctrl2, end; - SW_FT_Angle theta1, phi1, theta2, phi2, rotate, alpha0 = 0; - SW_FT_Fixed length1, length2; - SW_FT_StrokeBorder border; - SW_FT_Int side; - - theta1 = SW_FT_Angle_Diff(angle_in, angle_mid) / 2; - theta2 = SW_FT_Angle_Diff(angle_mid, angle_out) / 2; - phi1 = ft_angle_mean(angle_in, angle_mid); - phi2 = ft_angle_mean(angle_mid, angle_out); - length1 = SW_FT_DivFix(stroker->radius, SW_FT_Cos(theta1)); - length2 = SW_FT_DivFix(stroker->radius, SW_FT_Cos(theta2)); - - /* compute direction of original arc */ - if (stroker->handle_wide_strokes) - alpha0 = SW_FT_Atan2(arc[0].x - arc[3].x, arc[0].y - arc[3].y); - - for (border = stroker->borders, side = 0; side <= 1; - side++, border++) { - rotate = SW_FT_SIDE_TO_ROTATE(side); - - /* compute control points */ - SW_FT_Vector_From_Polar(&ctrl1, length1, phi1 + rotate); - ctrl1.x += arc[2].x; - ctrl1.y += arc[2].y; - - SW_FT_Vector_From_Polar(&ctrl2, length2, phi2 + rotate); - ctrl2.x += arc[1].x; - ctrl2.y += arc[1].y; - - /* compute end point */ - SW_FT_Vector_From_Polar(&end, stroker->radius, - angle_out + rotate); - end.x += arc[0].x; - end.y += arc[0].y; - - if (stroker->handle_wide_strokes) { - SW_FT_Vector start; - SW_FT_Angle alpha1; - - /* determine whether the border radius is greater than the - */ - /* radius of curvature of the original arc */ - start = border->points[border->num_points - 1]; - - alpha1 = SW_FT_Atan2(end.x - start.x, end.y - start.y); - - /* is the direction of the border arc opposite to */ - /* that of the original arc? */ - if (ft_pos_abs(SW_FT_Angle_Diff(alpha0, alpha1)) > - SW_FT_ANGLE_PI / 2) { - SW_FT_Angle beta, gamma; - SW_FT_Vector bvec, delta; - SW_FT_Fixed blen, sinA, sinB, alen; - - /* use the sine rule to find the intersection point */ - beta = - SW_FT_Atan2(arc[3].x - start.x, arc[3].y - start.y); - gamma = SW_FT_Atan2(arc[0].x - end.x, arc[0].y - end.y); - - bvec.x = end.x - start.x; - bvec.y = end.y - start.y; - - blen = SW_FT_Vector_Length(&bvec); - - sinA = ft_pos_abs(SW_FT_Sin(alpha1 - gamma)); - sinB = ft_pos_abs(SW_FT_Sin(beta - gamma)); - - alen = SW_FT_MulDiv(blen, sinA, sinB); - - SW_FT_Vector_From_Polar(&delta, alen, beta); - delta.x += start.x; - delta.y += start.y; - - /* circumnavigate the negative sector backwards */ - border->movable = FALSE; - error = ft_stroke_border_lineto(border, &delta, FALSE); - if (error) goto Exit; - error = ft_stroke_border_lineto(border, &end, FALSE); - if (error) goto Exit; - error = ft_stroke_border_cubicto(border, &ctrl2, &ctrl1, - &start); - if (error) goto Exit; - /* and then move to the endpoint */ - error = ft_stroke_border_lineto(border, &end, FALSE); - if (error) goto Exit; - - continue; - } - - /* else fall through */ - } - - /* simply add an arc */ - error = ft_stroke_border_cubicto(border, &ctrl1, &ctrl2, &end); - if (error) goto Exit; - } - } - - arc -= 3; - - stroker->angle_in = angle_out; - } - - stroker->center = *to; - -Exit: - return error; -} - -/* documentation is in ftstroke.h */ - -SW_FT_Error SW_FT_Stroker_BeginSubPath(SW_FT_Stroker stroker, SW_FT_Vector* to, - SW_FT_Bool open) -{ - /* We cannot process the first point, because there is not enough */ - /* information regarding its corner/cap. The latter will be processed */ - /* in the `SW_FT_Stroker_EndSubPath' routine. */ - /* */ - stroker->first_point = TRUE; - stroker->center = *to; - stroker->subpath_open = open; - - /* Determine if we need to check whether the border radius is greater */ - /* than the radius of curvature of a curve, to handle this case */ - /* specially. This is only required if bevel joins or butt caps may */ - /* be created, because round & miter joins and round & square caps */ - /* cover the negative sector created with wide strokes. */ - stroker->handle_wide_strokes = - SW_FT_BOOL(stroker->line_join != SW_FT_STROKER_LINEJOIN_ROUND || - (stroker->subpath_open && - stroker->line_cap == SW_FT_STROKER_LINECAP_BUTT)); - - /* record the subpath start point for each border */ - stroker->subpath_start = *to; - - stroker->angle_in = 0; - - return 0; -} - -static SW_FT_Error ft_stroker_add_reverse_left(SW_FT_Stroker stroker, - SW_FT_Bool open) -{ - SW_FT_StrokeBorder right = stroker->borders + 0; - SW_FT_StrokeBorder left = stroker->borders + 1; - SW_FT_Int new_points; - SW_FT_Error error = 0; - - assert(left->start >= 0); - - new_points = left->num_points - left->start; - if (new_points > 0) { - error = ft_stroke_border_grow(right, (SW_FT_UInt)new_points); - if (error) goto Exit; - - { - SW_FT_Vector* dst_point = right->points + right->num_points; - SW_FT_Byte* dst_tag = right->tags + right->num_points; - SW_FT_Vector* src_point = left->points + left->num_points - 1; - SW_FT_Byte* src_tag = left->tags + left->num_points - 1; - - while (src_point >= left->points + left->start) { - *dst_point = *src_point; - *dst_tag = *src_tag; - - if (open) - dst_tag[0] &= ~SW_FT_STROKE_TAG_BEGIN_END; - else { - SW_FT_Byte ttag = - (SW_FT_Byte)(dst_tag[0] & SW_FT_STROKE_TAG_BEGIN_END); - - /* switch begin/end tags if necessary */ - if (ttag == SW_FT_STROKE_TAG_BEGIN || - ttag == SW_FT_STROKE_TAG_END) - dst_tag[0] ^= SW_FT_STROKE_TAG_BEGIN_END; - } - - src_point--; - src_tag--; - dst_point++; - dst_tag++; - } - } - - left->num_points = left->start; - right->num_points += new_points; - - right->movable = FALSE; - left->movable = FALSE; - } - -Exit: - return error; -} - -/* documentation is in ftstroke.h */ - -/* there's a lot of magic in this function! */ -SW_FT_Error SW_FT_Stroker_EndSubPath(SW_FT_Stroker stroker) -{ - SW_FT_Error error = 0; - - if (stroker->subpath_open) { - SW_FT_StrokeBorder right = stroker->borders; - - /* All right, this is an opened path, we need to add a cap between */ - /* right & left, add the reverse of left, then add a final cap */ - /* between left & right. */ - error = ft_stroker_cap(stroker, stroker->angle_in, 0); - if (error) goto Exit; - - /* add reversed points from `left' to `right' */ - error = ft_stroker_add_reverse_left(stroker, TRUE); - if (error) goto Exit; - - /* now add the final cap */ - stroker->center = stroker->subpath_start; - error = - ft_stroker_cap(stroker, stroker->subpath_angle + SW_FT_ANGLE_PI, 0); - if (error) goto Exit; - - /* Now end the right subpath accordingly. The left one is */ - /* rewind and doesn't need further processing. */ - ft_stroke_border_close(right, FALSE); - } else { - SW_FT_Angle turn; - SW_FT_Int inside_side; - - /* close the path if needed */ - if (stroker->center.x != stroker->subpath_start.x || - stroker->center.y != stroker->subpath_start.y) { - error = SW_FT_Stroker_LineTo(stroker, &stroker->subpath_start); - if (error) goto Exit; - } - - /* process the corner */ - stroker->angle_out = stroker->subpath_angle; - turn = SW_FT_Angle_Diff(stroker->angle_in, stroker->angle_out); - - /* no specific corner processing is required if the turn is 0 */ - if (turn != 0) { - /* when we turn to the right, the inside side is 0 */ - inside_side = 0; - - /* otherwise, the inside side is 1 */ - if (turn < 0) inside_side = 1; - - error = ft_stroker_inside(stroker, inside_side, - stroker->subpath_line_length); - if (error) goto Exit; - - /* process the outside side */ - error = ft_stroker_outside(stroker, 1 - inside_side, - stroker->subpath_line_length); - if (error) goto Exit; - } - - /* then end our two subpaths */ - ft_stroke_border_close(stroker->borders + 0, FALSE); - ft_stroke_border_close(stroker->borders + 1, TRUE); - } - -Exit: - return error; -} - -/* documentation is in ftstroke.h */ - -SW_FT_Error SW_FT_Stroker_GetBorderCounts(SW_FT_Stroker stroker, - SW_FT_StrokerBorder border, - SW_FT_UInt* anum_points, - SW_FT_UInt* anum_contours) -{ - SW_FT_UInt num_points = 0, num_contours = 0; - SW_FT_Error error; - - if (!stroker || border > 1) { - error = -1; // SW_FT_THROW( Invalid_Argument ); - goto Exit; - } - - error = ft_stroke_border_get_counts(stroker->borders + border, &num_points, - &num_contours); -Exit: - if (anum_points) *anum_points = num_points; - - if (anum_contours) *anum_contours = num_contours; - - return error; -} - -/* documentation is in ftstroke.h */ - -SW_FT_Error SW_FT_Stroker_GetCounts(SW_FT_Stroker stroker, - SW_FT_UInt* anum_points, - SW_FT_UInt* anum_contours) -{ - SW_FT_UInt count1, count2, num_points = 0; - SW_FT_UInt count3, count4, num_contours = 0; - SW_FT_Error error; - - error = ft_stroke_border_get_counts(stroker->borders + 0, &count1, &count2); - if (error) goto Exit; - - error = ft_stroke_border_get_counts(stroker->borders + 1, &count3, &count4); - if (error) goto Exit; - - num_points = count1 + count3; - num_contours = count2 + count4; - -Exit: - *anum_points = num_points; - *anum_contours = num_contours; - return error; -} - -/* documentation is in ftstroke.h */ - -void SW_FT_Stroker_ExportBorder(SW_FT_Stroker stroker, - SW_FT_StrokerBorder border, - SW_FT_Outline* outline) -{ - if (border == SW_FT_STROKER_BORDER_LEFT || - border == SW_FT_STROKER_BORDER_RIGHT) { - SW_FT_StrokeBorder sborder = &stroker->borders[border]; - - if (sborder->valid) ft_stroke_border_export(sborder, outline); - } -} - -/* documentation is in ftstroke.h */ - -void SW_FT_Stroker_Export(SW_FT_Stroker stroker, SW_FT_Outline* outline) -{ - SW_FT_Stroker_ExportBorder(stroker, SW_FT_STROKER_BORDER_LEFT, outline); - SW_FT_Stroker_ExportBorder(stroker, SW_FT_STROKER_BORDER_RIGHT, outline); -} - -/* documentation is in ftstroke.h */ - -/* - * The following is very similar to SW_FT_Outline_Decompose, except - * that we do support opened paths, and do not scale the outline. - */ -SW_FT_Error SW_FT_Stroker_ParseOutline(SW_FT_Stroker stroker, - const SW_FT_Outline* outline) -{ - SW_FT_Vector v_last; - SW_FT_Vector v_control; - SW_FT_Vector v_start; - - SW_FT_Vector* point; - SW_FT_Vector* limit; - char* tags; - - SW_FT_Error error; - - SW_FT_Int n; /* index of contour in outline */ - SW_FT_UInt first; /* index of first point in contour */ - SW_FT_Int tag; /* current point's state */ - - if (!outline || !stroker) return -1; // SW_FT_THROW( Invalid_Argument ); - - SW_FT_Stroker_Rewind(stroker); - - first = 0; - - for (n = 0; n < outline->n_contours; n++) { - SW_FT_UInt last; /* index of last point in contour */ - - last = outline->contours[n]; - limit = outline->points + last; - - /* skip empty points; we don't stroke these */ - if (last <= first) { - first = last + 1; - continue; - } - - v_start = outline->points[first]; - v_last = outline->points[last]; - - v_control = v_start; - - point = outline->points + first; - tags = outline->tags + first; - tag = SW_FT_CURVE_TAG(tags[0]); - - /* A contour cannot start with a cubic control point! */ - if (tag == SW_FT_CURVE_TAG_CUBIC) goto Invalid_Outline; - - /* check first point to determine origin */ - if (tag == SW_FT_CURVE_TAG_CONIC) { - /* First point is conic control. Yes, this happens. */ - if (SW_FT_CURVE_TAG(outline->tags[last]) == SW_FT_CURVE_TAG_ON) { - /* start at last point if it is on the curve */ - v_start = v_last; - limit--; - } else { - /* if both first and last points are conic, */ - /* start at their middle */ - v_start.x = (v_start.x + v_last.x) / 2; - v_start.y = (v_start.y + v_last.y) / 2; - } - point--; - tags--; - } - - error = SW_FT_Stroker_BeginSubPath(stroker, &v_start, outline->contours_flag[n]); - if (error) goto Exit; - - while (point < limit) { - point++; - tags++; - - tag = SW_FT_CURVE_TAG(tags[0]); - switch (tag) { - case SW_FT_CURVE_TAG_ON: /* emit a single line_to */ - { - SW_FT_Vector vec; - - vec.x = point->x; - vec.y = point->y; - - error = SW_FT_Stroker_LineTo(stroker, &vec); - if (error) goto Exit; - continue; - } - - case SW_FT_CURVE_TAG_CONIC: /* consume conic arcs */ - v_control.x = point->x; - v_control.y = point->y; - - Do_Conic: - if (point < limit) { - SW_FT_Vector vec; - SW_FT_Vector v_middle; - - point++; - tags++; - tag = SW_FT_CURVE_TAG(tags[0]); - - vec = point[0]; - - if (tag == SW_FT_CURVE_TAG_ON) { - error = - SW_FT_Stroker_ConicTo(stroker, &v_control, &vec); - if (error) goto Exit; - continue; - } - - if (tag != SW_FT_CURVE_TAG_CONIC) goto Invalid_Outline; - - v_middle.x = (v_control.x + vec.x) / 2; - v_middle.y = (v_control.y + vec.y) / 2; - - error = - SW_FT_Stroker_ConicTo(stroker, &v_control, &v_middle); - if (error) goto Exit; - - v_control = vec; - goto Do_Conic; - } - - error = SW_FT_Stroker_ConicTo(stroker, &v_control, &v_start); - goto Close; - - default: /* SW_FT_CURVE_TAG_CUBIC */ - { - SW_FT_Vector vec1, vec2; - - if (point + 1 > limit || - SW_FT_CURVE_TAG(tags[1]) != SW_FT_CURVE_TAG_CUBIC) - goto Invalid_Outline; - - point += 2; - tags += 2; - - vec1 = point[-2]; - vec2 = point[-1]; - - if (point <= limit) { - SW_FT_Vector vec; - - vec = point[0]; - - error = SW_FT_Stroker_CubicTo(stroker, &vec1, &vec2, &vec); - if (error) goto Exit; - continue; - } - - error = SW_FT_Stroker_CubicTo(stroker, &vec1, &vec2, &v_start); - goto Close; - } - } - } - - Close: - if (error) goto Exit; - - /* don't try to end the path if no segments have been generated */ - if (!stroker->first_point) { - error = SW_FT_Stroker_EndSubPath(stroker); - if (error) goto Exit; - } - - first = last + 1; - } - - return 0; - -Exit: - return error; - -Invalid_Outline: - return -2; // SW_FT_THROW( Invalid_Outline ); -} - -/* END */ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_stroker.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_stroker.h deleted file mode 100644 index 1514cf3d..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_stroker.h +++ /dev/null @@ -1,319 +0,0 @@ -#ifndef V_FT_STROKER_H -#define V_FT_STROKER_H -/***************************************************************************/ -/* */ -/* ftstroke.h */ -/* */ -/* FreeType path stroker (specification). */ -/* */ -/* Copyright 2002-2006, 2008, 2009, 2011-2012 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -#include "v_ft_raster.h" - - /************************************************************** - * - * @type: - * SW_FT_Stroker - * - * @description: - * Opaque handler to a path stroker object. - */ - typedef struct SW_FT_StrokerRec_* SW_FT_Stroker; - - - /************************************************************** - * - * @enum: - * SW_FT_Stroker_LineJoin - * - * @description: - * These values determine how two joining lines are rendered - * in a stroker. - * - * @values: - * SW_FT_STROKER_LINEJOIN_ROUND :: - * Used to render rounded line joins. Circular arcs are used - * to join two lines smoothly. - * - * SW_FT_STROKER_LINEJOIN_BEVEL :: - * Used to render beveled line joins. The outer corner of - * the joined lines is filled by enclosing the triangular - * region of the corner with a straight line between the - * outer corners of each stroke. - * - * SW_FT_STROKER_LINEJOIN_MITER_FIXED :: - * Used to render mitered line joins, with fixed bevels if the - * miter limit is exceeded. The outer edges of the strokes - * for the two segments are extended until they meet at an - * angle. If the segments meet at too sharp an angle (such - * that the miter would extend from the intersection of the - * segments a distance greater than the product of the miter - * limit value and the border radius), then a bevel join (see - * above) is used instead. This prevents long spikes being - * created. SW_FT_STROKER_LINEJOIN_MITER_FIXED generates a miter - * line join as used in PostScript and PDF. - * - * SW_FT_STROKER_LINEJOIN_MITER_VARIABLE :: - * SW_FT_STROKER_LINEJOIN_MITER :: - * Used to render mitered line joins, with variable bevels if - * the miter limit is exceeded. The intersection of the - * strokes is clipped at a line perpendicular to the bisector - * of the angle between the strokes, at the distance from the - * intersection of the segments equal to the product of the - * miter limit value and the border radius. This prevents - * long spikes being created. - * SW_FT_STROKER_LINEJOIN_MITER_VARIABLE generates a mitered line - * join as used in XPS. SW_FT_STROKER_LINEJOIN_MITER is an alias - * for SW_FT_STROKER_LINEJOIN_MITER_VARIABLE, retained for - * backwards compatibility. - */ - typedef enum SW_FT_Stroker_LineJoin_ - { - SW_FT_STROKER_LINEJOIN_ROUND = 0, - SW_FT_STROKER_LINEJOIN_BEVEL = 1, - SW_FT_STROKER_LINEJOIN_MITER_VARIABLE = 2, - SW_FT_STROKER_LINEJOIN_MITER = SW_FT_STROKER_LINEJOIN_MITER_VARIABLE, - SW_FT_STROKER_LINEJOIN_MITER_FIXED = 3 - - } SW_FT_Stroker_LineJoin; - - - /************************************************************** - * - * @enum: - * SW_FT_Stroker_LineCap - * - * @description: - * These values determine how the end of opened sub-paths are - * rendered in a stroke. - * - * @values: - * SW_FT_STROKER_LINECAP_BUTT :: - * The end of lines is rendered as a full stop on the last - * point itself. - * - * SW_FT_STROKER_LINECAP_ROUND :: - * The end of lines is rendered as a half-circle around the - * last point. - * - * SW_FT_STROKER_LINECAP_SQUARE :: - * The end of lines is rendered as a square around the - * last point. - */ - typedef enum SW_FT_Stroker_LineCap_ - { - SW_FT_STROKER_LINECAP_BUTT = 0, - SW_FT_STROKER_LINECAP_ROUND, - SW_FT_STROKER_LINECAP_SQUARE - - } SW_FT_Stroker_LineCap; - - - /************************************************************** - * - * @enum: - * SW_FT_StrokerBorder - * - * @description: - * These values are used to select a given stroke border - * in @SW_FT_Stroker_GetBorderCounts and @SW_FT_Stroker_ExportBorder. - * - * @values: - * SW_FT_STROKER_BORDER_LEFT :: - * Select the left border, relative to the drawing direction. - * - * SW_FT_STROKER_BORDER_RIGHT :: - * Select the right border, relative to the drawing direction. - * - * @note: - * Applications are generally interested in the `inside' and `outside' - * borders. However, there is no direct mapping between these and the - * `left' and `right' ones, since this really depends on the glyph's - * drawing orientation, which varies between font formats. - * - * You can however use @SW_FT_Outline_GetInsideBorder and - * @SW_FT_Outline_GetOutsideBorder to get these. - */ - typedef enum SW_FT_StrokerBorder_ - { - SW_FT_STROKER_BORDER_LEFT = 0, - SW_FT_STROKER_BORDER_RIGHT - - } SW_FT_StrokerBorder; - - - /************************************************************** - * - * @function: - * SW_FT_Stroker_New - * - * @description: - * Create a new stroker object. - * - * @input: - * library :: - * FreeType library handle. - * - * @output: - * astroker :: - * A new stroker object handle. NULL in case of error. - * - * @return: - * FreeType error code. 0~means success. - */ - SW_FT_Error - SW_FT_Stroker_New( SW_FT_Stroker *astroker ); - - - /************************************************************** - * - * @function: - * SW_FT_Stroker_Set - * - * @description: - * Reset a stroker object's attributes. - * - * @input: - * stroker :: - * The target stroker handle. - * - * radius :: - * The border radius. - * - * line_cap :: - * The line cap style. - * - * line_join :: - * The line join style. - * - * miter_limit :: - * The miter limit for the SW_FT_STROKER_LINEJOIN_MITER_FIXED and - * SW_FT_STROKER_LINEJOIN_MITER_VARIABLE line join styles, - * expressed as 16.16 fixed-point value. - * - * @note: - * The radius is expressed in the same units as the outline - * coordinates. - */ - void - SW_FT_Stroker_Set( SW_FT_Stroker stroker, - SW_FT_Fixed radius, - SW_FT_Stroker_LineCap line_cap, - SW_FT_Stroker_LineJoin line_join, - SW_FT_Fixed miter_limit ); - - /************************************************************** - * - * @function: - * SW_FT_Stroker_ParseOutline - * - * @description: - * A convenience function used to parse a whole outline with - * the stroker. The resulting outline(s) can be retrieved - * later by functions like @SW_FT_Stroker_GetCounts and @SW_FT_Stroker_Export. - * - * @input: - * stroker :: - * The target stroker handle. - * - * outline :: - * The source outline. - * - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * If `opened' is~0 (the default), the outline is treated as a closed - * path, and the stroker generates two distinct `border' outlines. - * - * - * This function calls @SW_FT_Stroker_Rewind automatically. - */ - SW_FT_Error - SW_FT_Stroker_ParseOutline( SW_FT_Stroker stroker, - const SW_FT_Outline* outline); - - - /************************************************************** - * - * @function: - * SW_FT_Stroker_GetCounts - * - * @description: - * Call this function once you have finished parsing your paths - * with the stroker. It returns the number of points and - * contours necessary to export all points/borders from the stroked - * outline/path. - * - * @input: - * stroker :: - * The target stroker handle. - * - * @output: - * anum_points :: - * The number of points. - * - * anum_contours :: - * The number of contours. - * - * @return: - * FreeType error code. 0~means success. - */ - SW_FT_Error - SW_FT_Stroker_GetCounts( SW_FT_Stroker stroker, - SW_FT_UInt *anum_points, - SW_FT_UInt *anum_contours ); - - - /************************************************************** - * - * @function: - * SW_FT_Stroker_Export - * - * @description: - * Call this function after @SW_FT_Stroker_GetBorderCounts to - * export all borders to your own @SW_FT_Outline structure. - * - * Note that this function appends the border points and - * contours to your outline, but does not try to resize its - * arrays. - * - * @input: - * stroker :: - * The target stroker handle. - * - * outline :: - * The target outline handle. - */ - void - SW_FT_Stroker_Export( SW_FT_Stroker stroker, - SW_FT_Outline* outline ); - - - /************************************************************** - * - * @function: - * SW_FT_Stroker_Done - * - * @description: - * Destroy a stroker object. - * - * @input: - * stroker :: - * A stroker handle. Can be NULL. - */ - void - SW_FT_Stroker_Done( SW_FT_Stroker stroker ); - - -#endif // V_FT_STROKER_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_types.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_types.h deleted file mode 100644 index a01c4f28..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/freetype/v_ft_types.h +++ /dev/null @@ -1,160 +0,0 @@ -#ifndef V_FT_TYPES_H -#define V_FT_TYPES_H - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_Fixed */ -/* */ -/* */ -/* This type is used to store 16.16 fixed-point values, like scaling */ -/* values or matrix coefficients. */ -/* */ -typedef signed long SW_FT_Fixed; - - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_Int */ -/* */ -/* */ -/* A typedef for the int type. */ -/* */ -typedef signed int SW_FT_Int; - - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_UInt */ -/* */ -/* */ -/* A typedef for the unsigned int type. */ -/* */ -typedef unsigned int SW_FT_UInt; - - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_Long */ -/* */ -/* */ -/* A typedef for signed long. */ -/* */ -typedef signed long SW_FT_Long; - - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_ULong */ -/* */ -/* */ -/* A typedef for unsigned long. */ -/* */ -typedef unsigned long SW_FT_ULong; - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_Short */ -/* */ -/* */ -/* A typedef for signed short. */ -/* */ -typedef signed short SW_FT_Short; - - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_Byte */ -/* */ -/* */ -/* A simple typedef for the _unsigned_ char type. */ -/* */ -typedef unsigned char SW_FT_Byte; - - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_Bool */ -/* */ -/* */ -/* A typedef of unsigned char, used for simple booleans. As usual, */ -/* values 1 and~0 represent true and false, respectively. */ -/* */ -typedef unsigned char SW_FT_Bool; - - - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_Error */ -/* */ -/* */ -/* The FreeType error code type. A value of~0 is always interpreted */ -/* as a successful operation. */ -/* */ -typedef int SW_FT_Error; - - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_Pos */ -/* */ -/* */ -/* The type SW_FT_Pos is used to store vectorial coordinates. Depending */ -/* on the context, these can represent distances in integer font */ -/* units, or 16.16, or 26.6 fixed-point pixel coordinates. */ -/* */ -typedef signed long SW_FT_Pos; - - -/*************************************************************************/ -/* */ -/* */ -/* SW_FT_Vector */ -/* */ -/* */ -/* A simple structure used to store a 2D vector; coordinates are of */ -/* the SW_FT_Pos type. */ -/* */ -/* */ -/* x :: The horizontal coordinate. */ -/* y :: The vertical coordinate. */ -/* */ -typedef struct SW_FT_Vector_ -{ - SW_FT_Pos x; - SW_FT_Pos y; - -} SW_FT_Vector; - - -typedef long long int SW_FT_Int64; -typedef unsigned long long int SW_FT_UInt64; - -typedef signed int SW_FT_Int32; -typedef unsigned int SW_FT_UInt32; - - -#define SW_FT_BOOL( x ) ( (SW_FT_Bool)( x ) ) - -#define SW_FT_SIZEOF_LONG 4 - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - - -#endif // V_FT_TYPES_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/meson.build b/presentation/src/main/cpp/third_party/rlottie/src/vector/meson.build deleted file mode 100644 index 1526a9ce..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/meson.build +++ /dev/null @@ -1,35 +0,0 @@ - -subdir('freetype') -subdir('pixman') -subdir('stb') - -source_file = [ - 'vdasher.cpp', - 'vbrush.cpp', - 'vbitmap.cpp', - 'vpainter.cpp', - 'vdrawhelper_common.cpp', - 'vdrawhelper.cpp', - 'vdrawhelper_sse2.cpp', - 'vdrawhelper_neon.cpp', - 'vdrawable.cpp', - 'vrect.cpp', - 'vrle.cpp', - 'vpath.cpp', - 'vpathmesure.cpp', - 'vmatrix.cpp', - 'velapsedtimer.cpp', - 'vdebug.cpp', - 'vinterpolator.cpp', - 'vbezier.cpp', - 'vraster.cpp', - 'vimageloader.cpp', - 'varenaalloc.cpp', -] - -vector_dep = declare_dependency( include_directories : include_directories('.'), - sources : source_file, - dependencies : [freetype_dep, pixman_dep, stb_dep], - ) - - diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/pixman/CMakeLists.txt b/presentation/src/main/cpp/third_party/rlottie/src/vector/pixman/CMakeLists.txt deleted file mode 100644 index d904ca8d..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/pixman/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ - -IF("${ARCH}" STREQUAL "arm") -SET(CMAKE_ASM_FLAGS "${CFLAGS} -x assembler-with-cpp") -target_sources(rlottie - PRIVATE - "${CMAKE_CURRENT_LIST_DIR}/pixman-arm-neon-asm.S" - ) -ENDIF("${ARCH}" STREQUAL "arm") - -target_include_directories(rlottie - PRIVATE - "${CMAKE_CURRENT_LIST_DIR}" - ) diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/pixman/meson.build b/presentation/src/main/cpp/third_party/rlottie/src/vector/pixman/meson.build deleted file mode 100644 index 8e097d7b..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/pixman/meson.build +++ /dev/null @@ -1,11 +0,0 @@ - -source_file = [] - -if host_machine.cpu_family() == 'arm' - source_file += 'pixman-arm-neon-asm.S' -endif - -pixman_dep = declare_dependency( - include_directories : include_directories('.'), - sources : source_file - ) diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/pixman/pixman-arm-neon-asm.S b/presentation/src/main/cpp/third_party/rlottie/src/vector/pixman/pixman-arm-neon-asm.S deleted file mode 100644 index f2203c21..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/pixman/pixman-arm-neon-asm.S +++ /dev/null @@ -1,497 +0,0 @@ -/* - * Copyright © 2009 Nokia Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Siarhei Siamashka (siarhei.siamashka@nokia.com) - */ - -/* - * This file contains implementations of NEON optimized pixel processing - * functions. There is no full and detailed tutorial, but some functions - * (those which are exposing some new or interesting features) are - * extensively commented and can be used as examples. - * - * You may want to have a look at the comments for following functions: - * - pixman_composite_over_8888_0565_asm_neon - * - pixman_composite_over_n_8_0565_asm_neon - */ - -/* Prevent the stack from becoming executable for no reason... */ -#if defined(__linux__) && defined(__ELF__) -.section .note.GNU-stack,"",%progbits -#endif - - .text - .fpu neon - .arch armv7a - .object_arch armv4 - .eabi_attribute 10, 0 /* suppress Tag_FP_arch */ - .eabi_attribute 12, 0 /* suppress Tag_Advanced_SIMD_arch */ - .arm - .altmacro - .p2align 2 - - -//#include "pixman-arm-asm.h" -/* Supplementary macro for setting function attributes */ -.macro pixman_asm_function fname - .func fname - .global fname -#ifdef __ELF__ - .hidden fname - .type fname, %function -#endif -fname: -.endm - -//#include "pixman-private.h" -/* - * The defines which are shared between C and assembly code - */ - -/* bilinear interpolation precision (must be < 8) */ -#define BILINEAR_INTERPOLATION_BITS 7 -#define BILINEAR_INTERPOLATION_RANGE (1 << BILINEAR_INTERPOLATION_BITS) - -#include "pixman-arm-neon-asm.h" - -/* Global configuration options and preferences */ - -/* - * The code can optionally make use of unaligned memory accesses to improve - * performance of handling leading/trailing pixels for each scanline. - * Configuration variable RESPECT_STRICT_ALIGNMENT can be set to 0 for - * example in linux if unaligned memory accesses are not configured to - * generate.exceptions. - */ -.set RESPECT_STRICT_ALIGNMENT, 1 - -/* - * Set default prefetch type. There is a choice between the following options: - * - * PREFETCH_TYPE_NONE (may be useful for the ARM cores where PLD is set to work - * as NOP to workaround some HW bugs or for whatever other reason) - * - * PREFETCH_TYPE_SIMPLE (may be useful for simple single-issue ARM cores where - * advanced prefetch intruduces heavy overhead) - * - * PREFETCH_TYPE_ADVANCED (useful for superscalar cores such as ARM Cortex-A8 - * which can run ARM and NEON instructions simultaneously so that extra ARM - * instructions do not add (many) extra cycles, but improve prefetch efficiency) - * - * Note: some types of function can't support advanced prefetch and fallback - * to simple one (those which handle 24bpp pixels) - */ -.set PREFETCH_TYPE_DEFAULT, PREFETCH_TYPE_ADVANCED - -/* Prefetch distance in pixels for simple prefetch */ -.set PREFETCH_DISTANCE_SIMPLE, 64 - -/* - * Implementation of pixman_composite_over_8888_0565_asm_neon - * - * This function takes a8r8g8b8 source buffer, r5g6b5 destination buffer and - * performs OVER compositing operation. Function fast_composite_over_8888_0565 - * from pixman-fast-path.c does the same in C and can be used as a reference. - * - * First we need to have some NEON assembly code which can do the actual - * operation on the pixels and provide it to the template macro. - * - * Template macro quite conveniently takes care of emitting all the necessary - * code for memory reading and writing (including quite tricky cases of - * handling unaligned leading/trailing pixels), so we only need to deal with - * the data in NEON registers. - * - * NEON registers allocation in general is recommented to be the following: - * d0, d1, d2, d3 - contain loaded source pixel data - * d4, d5, d6, d7 - contain loaded destination pixels (if they are needed) - * d24, d25, d26, d27 - contain loading mask pixel data (if mask is used) - * d28, d29, d30, d31 - place for storing the result (destination pixels) - * - * As can be seen above, four 64-bit NEON registers are used for keeping - * intermediate pixel data and up to 8 pixels can be processed in one step - * for 32bpp formats (16 pixels for 16bpp, 32 pixels for 8bpp). - * - * This particular function uses the following registers allocation: - * d0, d1, d2, d3 - contain loaded source pixel data - * d4, d5 - contain loaded destination pixels (they are needed) - * d28, d29 - place for storing the result (destination pixels) - */ - -/* - * Step one. We need to have some code to do some arithmetics on pixel data. - * This is implemented as a pair of macros: '*_head' and '*_tail'. When used - * back-to-back, they take pixel data from {d0, d1, d2, d3} and {d4, d5}, - * perform all the needed calculations and write the result to {d28, d29}. - * The rationale for having two macros and not just one will be explained - * later. In practice, any single monolitic function which does the work can - * be split into two parts in any arbitrary way without affecting correctness. - * - * There is one special trick here too. Common template macro can optionally - * make our life a bit easier by doing R, G, B, A color components - * deinterleaving for 32bpp pixel formats (and this feature is used in - * 'pixman_composite_over_8888_0565_asm_neon' function). So it means that - * instead of having 8 packed pixels in {d0, d1, d2, d3} registers, we - * actually use d0 register for blue channel (a vector of eight 8-bit - * values), d1 register for green, d2 for red and d3 for alpha. This - * simple conversion can be also done with a few NEON instructions: - * - * Packed to planar conversion: - * vuzp.8 d0, d1 - * vuzp.8 d2, d3 - * vuzp.8 d1, d3 - * vuzp.8 d0, d2 - * - * Planar to packed conversion: - * vzip.8 d0, d2 - * vzip.8 d1, d3 - * vzip.8 d2, d3 - * vzip.8 d0, d1 - * - * But pixel can be loaded directly in planar format using VLD4.8 NEON - * instruction. It is 1 cycle slower than VLD1.32, so this is not always - * desirable, that's why deinterleaving is optional. - * - * But anyway, here is the code: - */ - -/* - * OK, now we got almost everything that we need. Using the above two - * macros, the work can be done right. But now we want to optimize - * it a bit. ARM Cortex-A8 is an in-order core, and benefits really - * a lot from good code scheduling and software pipelining. - * - * Let's construct some code, which will run in the core main loop. - * Some pseudo-code of the main loop will look like this: - * head - * while (...) { - * tail - * head - * } - * tail - * - * It may look a bit weird, but this setup allows to hide instruction - * latencies better and also utilize dual-issue capability more - * efficiently (make pairs of load-store and ALU instructions). - * - * So what we need now is a '*_tail_head' macro, which will be used - * in the core main loop. A trivial straightforward implementation - * of this macro would look like this: - * - * pixman_composite_over_8888_0565_process_pixblock_tail - * vst1.16 {d28, d29}, [DST_W, :128]! - * vld1.16 {d4, d5}, [DST_R, :128]! - * vld4.32 {d0, d1, d2, d3}, [SRC]! - * pixman_composite_over_8888_0565_process_pixblock_head - * cache_preload 8, 8 - * - * Now it also got some VLD/VST instructions. We simply can't move from - * processing one block of pixels to the other one with just arithmetics. - * The previously processed data needs to be written to memory and new - * data needs to be fetched. Fortunately, this main loop does not deal - * with partial leading/trailing pixels and can load/store a full block - * of pixels in a bulk. Additionally, destination buffer is already - * 16 bytes aligned here (which is good for performance). - * - * New things here are DST_R, DST_W, SRC and MASK identifiers. These - * are the aliases for ARM registers which are used as pointers for - * accessing data. We maintain separate pointers for reading and writing - * destination buffer (DST_R and DST_W). - * - * Another new thing is 'cache_preload' macro. It is used for prefetching - * data into CPU L2 cache and improve performance when dealing with large - * images which are far larger than cache size. It uses one argument - * (actually two, but they need to be the same here) - number of pixels - * in a block. Looking into 'pixman-arm-neon-asm.h' can provide some - * details about this macro. Moreover, if good performance is needed - * the code from this macro needs to be copied into '*_tail_head' macro - * and mixed with the rest of code for optimal instructions scheduling. - * We are actually doing it below. - * - * Now after all the explanations, here is the optimized code. - * Different instruction streams (originaling from '*_head', '*_tail' - * and 'cache_preload' macro) use different indentation levels for - * better readability. Actually taking the code from one of these - * indentation levels and ignoring a few VLD/VST instructions would - * result in exactly the code from '*_head', '*_tail' or 'cache_preload' - * macro! - */ - -/* - * And now the final part. We are using 'generate_composite_function' macro - * to put all the stuff together. We are specifying the name of the function - * which we want to get, number of bits per pixel for the source, mask and - * destination (0 if unused, like mask in this case). Next come some bit - * flags: - * FLAG_DST_READWRITE - tells that the destination buffer is both read - * and written, for write-only buffer we would use - * FLAG_DST_WRITEONLY flag instead - * FLAG_DEINTERLEAVE_32BPP - tells that we prefer to work with planar data - * and separate color channels for 32bpp format. - * The next things are: - * - the number of pixels processed per iteration (8 in this case, because - * that's the maximum what can fit into four 64-bit NEON registers). - * - prefetch distance, measured in pixel blocks. In this case it is 5 times - * by 8 pixels. That would be 40 pixels, or up to 160 bytes. Optimal - * prefetch distance can be selected by running some benchmarks. - * - * After that we specify some macros, these are 'default_init', - * 'default_cleanup' here which are empty (but it is possible to have custom - * init/cleanup macros to be able to save/restore some extra NEON registers - * like d8-d15 or do anything else) followed by - * 'pixman_composite_over_8888_0565_process_pixblock_head', - * 'pixman_composite_over_8888_0565_process_pixblock_tail' and - * 'pixman_composite_over_8888_0565_process_pixblock_tail_head' - * which we got implemented above. - * - * The last part is the NEON registers allocation scheme. - */ - -/******************************************************************************/ - -/******************************************************************************/ - .macro pixman_composite_out_reverse_8888_8888_process_pixblock_head - vmvn.8 d24, d3 /* get inverted alpha */ - /* do alpha blending */ - vmull.u8 q8, d24, d4 - vmull.u8 q9, d24, d5 - vmull.u8 q10, d24, d6 - vmull.u8 q11, d24, d7 - .endm - - .macro pixman_composite_out_reverse_8888_8888_process_pixblock_tail - vrshr.u16 q14, q8, #8 - vrshr.u16 q15, q9, #8 - vrshr.u16 q12, q10, #8 - vrshr.u16 q13, q11, #8 - vraddhn.u16 d28, q14, q8 - vraddhn.u16 d29, q15, q9 - vraddhn.u16 d30, q12, q10 - vraddhn.u16 d31, q13, q11 - .endm - -/******************************************************************************/ - -.macro pixman_composite_over_8888_8888_process_pixblock_head - pixman_composite_out_reverse_8888_8888_process_pixblock_head -.endm - -.macro pixman_composite_over_8888_8888_process_pixblock_tail - pixman_composite_out_reverse_8888_8888_process_pixblock_tail - vqadd.u8 q14, q0, q14 - vqadd.u8 q15, q1, q15 -.endm - -.macro pixman_composite_over_8888_8888_process_pixblock_tail_head - vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! - vrshr.u16 q14, q8, #8 - PF add PF_X, PF_X, #8 - PF tst PF_CTL, #0xF - vrshr.u16 q15, q9, #8 - vrshr.u16 q12, q10, #8 - vrshr.u16 q13, q11, #8 - PF addne PF_X, PF_X, #8 - PF subne PF_CTL, PF_CTL, #1 - vraddhn.u16 d28, q14, q8 - vraddhn.u16 d29, q15, q9 - PF cmp PF_X, ORIG_W - vraddhn.u16 d30, q12, q10 - vraddhn.u16 d31, q13, q11 - vqadd.u8 q14, q0, q14 - vqadd.u8 q15, q1, q15 - fetch_src_pixblock - PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] - vmvn.8 d22, d3 - PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! - PF subge PF_X, PF_X, ORIG_W - vmull.u8 q8, d22, d4 - PF subges PF_CTL, PF_CTL, #0x10 - vmull.u8 q9, d22, d5 - PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! - vmull.u8 q10, d22, d6 - PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! - vmull.u8 q11, d22, d7 -.endm - -generate_composite_function \ - pixman_composite_over_8888_8888_asm_neon, 32, 0, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - default_init, \ - default_cleanup, \ - pixman_composite_over_8888_8888_process_pixblock_head, \ - pixman_composite_over_8888_8888_process_pixblock_tail, \ - pixman_composite_over_8888_8888_process_pixblock_tail_head - -generate_composite_function_single_scanline \ - pixman_composite_scanline_over_asm_neon, 32, 0, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - default_init, \ - default_cleanup, \ - pixman_composite_over_8888_8888_process_pixblock_head, \ - pixman_composite_over_8888_8888_process_pixblock_tail, \ - pixman_composite_over_8888_8888_process_pixblock_tail_head - -/******************************************************************************/ - -.macro pixman_composite_over_n_8888_process_pixblock_head - /* deinterleaved source pixels in {d0, d1, d2, d3} */ - /* inverted alpha in {d24} */ - /* destination pixels in {d4, d5, d6, d7} */ - vmull.u8 q8, d24, d4 - vmull.u8 q9, d24, d5 - vmull.u8 q10, d24, d6 - vmull.u8 q11, d24, d7 -.endm - -.macro pixman_composite_over_n_8888_process_pixblock_tail - vrshr.u16 q14, q8, #8 - vrshr.u16 q15, q9, #8 - vrshr.u16 q2, q10, #8 - vrshr.u16 q3, q11, #8 - vraddhn.u16 d28, q14, q8 - vraddhn.u16 d29, q15, q9 - vraddhn.u16 d30, q2, q10 - vraddhn.u16 d31, q3, q11 - vqadd.u8 q14, q0, q14 - vqadd.u8 q15, q1, q15 -.endm - -.macro pixman_composite_over_n_8888_process_pixblock_tail_head - vrshr.u16 q14, q8, #8 - vrshr.u16 q15, q9, #8 - vrshr.u16 q2, q10, #8 - vrshr.u16 q3, q11, #8 - vraddhn.u16 d28, q14, q8 - vraddhn.u16 d29, q15, q9 - vraddhn.u16 d30, q2, q10 - vraddhn.u16 d31, q3, q11 - vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! - vqadd.u8 q14, q0, q14 - PF add PF_X, PF_X, #8 - PF tst PF_CTL, #0x0F - PF addne PF_X, PF_X, #8 - PF subne PF_CTL, PF_CTL, #1 - vqadd.u8 q15, q1, q15 - PF cmp PF_X, ORIG_W - vmull.u8 q8, d24, d4 - PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] - vmull.u8 q9, d24, d5 - PF subge PF_X, PF_X, ORIG_W - vmull.u8 q10, d24, d6 - PF subges PF_CTL, PF_CTL, #0x10 - vmull.u8 q11, d24, d7 - PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! -.endm - -.macro pixman_composite_over_n_8888_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vld1.32 {d3[0]}, [DUMMY] - vdup.8 d0, d3[0] - vdup.8 d1, d3[1] - vdup.8 d2, d3[2] - vdup.8 d3, d3[3] - vmvn.8 d24, d3 /* get inverted alpha */ -.endm - -generate_composite_function \ - pixman_composite_over_n_8888_asm_neon, 0, 0, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_over_n_8888_init, \ - default_cleanup, \ - pixman_composite_over_8888_8888_process_pixblock_head, \ - pixman_composite_over_8888_8888_process_pixblock_tail, \ - pixman_composite_over_n_8888_process_pixblock_tail_head - -/******************************************************************************/ - -.macro pixman_composite_src_n_8888_process_pixblock_head -.endm - -.macro pixman_composite_src_n_8888_process_pixblock_tail -.endm - -.macro pixman_composite_src_n_8888_process_pixblock_tail_head - vst1.32 {d0, d1, d2, d3}, [DST_W, :128]! -.endm - -.macro pixman_composite_src_n_8888_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vld1.32 {d0[0]}, [DUMMY] - vsli.u64 d0, d0, #32 - vorr d1, d0, d0 - vorr q1, q0, q0 -.endm - -.macro pixman_composite_src_n_8888_cleanup -.endm - -generate_composite_function \ - pixman_composite_src_n_8888_asm_neon, 0, 0, 32, \ - FLAG_DST_WRITEONLY, \ - 8, /* number of pixels, processed in a single block */ \ - 0, /* prefetch distance */ \ - pixman_composite_src_n_8888_init, \ - pixman_composite_src_n_8888_cleanup, \ - pixman_composite_src_n_8888_process_pixblock_head, \ - pixman_composite_src_n_8888_process_pixblock_tail, \ - pixman_composite_src_n_8888_process_pixblock_tail_head, \ - 0, /* dst_w_basereg */ \ - 0, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 0 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_src_8888_8888_process_pixblock_head -.endm - -.macro pixman_composite_src_8888_8888_process_pixblock_tail -.endm - -.macro pixman_composite_src_8888_8888_process_pixblock_tail_head - vst1.32 {d0, d1, d2, d3}, [DST_W, :128]! - fetch_src_pixblock - cache_preload 8, 8 -.endm - -generate_composite_function \ - pixman_composite_src_8888_8888_asm_neon, 32, 0, 32, \ - FLAG_DST_WRITEONLY, \ - 8, /* number of pixels, processed in a single block */ \ - 10, /* prefetch distance */ \ - default_init, \ - default_cleanup, \ - pixman_composite_src_8888_8888_process_pixblock_head, \ - pixman_composite_src_8888_8888_process_pixblock_tail, \ - pixman_composite_src_8888_8888_process_pixblock_tail_head, \ - 0, /* dst_w_basereg */ \ - 0, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 0 /* mask_basereg */ - -/******************************************************************************/ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/pixman/pixman-arm-neon-asm.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/pixman/pixman-arm-neon-asm.h deleted file mode 100644 index 6add220a..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/pixman/pixman-arm-neon-asm.h +++ /dev/null @@ -1,1126 +0,0 @@ -/* - * Copyright © 2009 Nokia Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Siarhei Siamashka (siarhei.siamashka@nokia.com) - */ - -/* - * This file contains a macro ('generate_composite_function') which can - * construct 2D image processing functions, based on a common template. - * Any combinations of source, destination and mask images with 8bpp, - * 16bpp, 24bpp, 32bpp color formats are supported. - * - * This macro takes care of: - * - handling of leading and trailing unaligned pixels - * - doing most of the work related to L2 cache preload - * - encourages the use of software pipelining for better instructions - * scheduling - * - * The user of this macro has to provide some configuration parameters - * (bit depths for the images, prefetch distance, etc.) and a set of - * macros, which should implement basic code chunks responsible for - * pixels processing. See 'pixman-arm-neon-asm.S' file for the usage - * examples. - * - * TODO: - * - try overlapped pixel method (from Ian Rickards) when processing - * exactly two blocks of pixels - * - maybe add an option to do reverse scanline processing - */ - -/* - * Bit flags for 'generate_composite_function' macro which are used - * to tune generated functions behavior. - */ -.set FLAG_DST_WRITEONLY, 0 -.set FLAG_DST_READWRITE, 1 -.set FLAG_DEINTERLEAVE_32BPP, 2 - -/* - * Offset in stack where mask and source pointer/stride can be accessed - * from 'init' macro. This is useful for doing special handling for solid mask. - */ -.set ARGS_STACK_OFFSET, 40 - -/* - * Constants for selecting preferable prefetch type. - */ -.set PREFETCH_TYPE_NONE, 0 /* No prefetch at all */ -.set PREFETCH_TYPE_SIMPLE, 1 /* A simple, fixed-distance-ahead prefetch */ -.set PREFETCH_TYPE_ADVANCED, 2 /* Advanced fine-grained prefetch */ - -/* - * Definitions of supplementary pixld/pixst macros (for partial load/store of - * pixel data). - */ - -.macro pixldst1 op, elem_size, reg1, mem_operand, abits -.if abits > 0 - op&.&elem_size {d®1}, [&mem_operand&, :&abits&]! -.else - op&.&elem_size {d®1}, [&mem_operand&]! -.endif -.endm - -.macro pixldst2 op, elem_size, reg1, reg2, mem_operand, abits -.if abits > 0 - op&.&elem_size {d®1, d®2}, [&mem_operand&, :&abits&]! -.else - op&.&elem_size {d®1, d®2}, [&mem_operand&]! -.endif -.endm - -.macro pixldst4 op, elem_size, reg1, reg2, reg3, reg4, mem_operand, abits -.if abits > 0 - op&.&elem_size {d®1, d®2, d®3, d®4}, [&mem_operand&, :&abits&]! -.else - op&.&elem_size {d®1, d®2, d®3, d®4}, [&mem_operand&]! -.endif -.endm - -.macro pixldst0 op, elem_size, reg1, idx, mem_operand, abits - op&.&elem_size {d®1[idx]}, [&mem_operand&]! -.endm - -.macro pixldst3 op, elem_size, reg1, reg2, reg3, mem_operand - op&.&elem_size {d®1, d®2, d®3}, [&mem_operand&]! -.endm - -.macro pixldst30 op, elem_size, reg1, reg2, reg3, idx, mem_operand - op&.&elem_size {d®1[idx], d®2[idx], d®3[idx]}, [&mem_operand&]! -.endm - -.macro pixldst numbytes, op, elem_size, basereg, mem_operand, abits -.if numbytes == 32 - pixldst4 op, elem_size, %(basereg+4), %(basereg+5), \ - %(basereg+6), %(basereg+7), mem_operand, abits -.elseif numbytes == 16 - pixldst2 op, elem_size, %(basereg+2), %(basereg+3), mem_operand, abits -.elseif numbytes == 8 - pixldst1 op, elem_size, %(basereg+1), mem_operand, abits -.elseif numbytes == 4 - .if !RESPECT_STRICT_ALIGNMENT || (elem_size == 32) - pixldst0 op, 32, %(basereg+0), 1, mem_operand, abits - .elseif elem_size == 16 - pixldst0 op, 16, %(basereg+0), 2, mem_operand, abits - pixldst0 op, 16, %(basereg+0), 3, mem_operand, abits - .else - pixldst0 op, 8, %(basereg+0), 4, mem_operand, abits - pixldst0 op, 8, %(basereg+0), 5, mem_operand, abits - pixldst0 op, 8, %(basereg+0), 6, mem_operand, abits - pixldst0 op, 8, %(basereg+0), 7, mem_operand, abits - .endif -.elseif numbytes == 2 - .if !RESPECT_STRICT_ALIGNMENT || (elem_size == 16) - pixldst0 op, 16, %(basereg+0), 1, mem_operand, abits - .else - pixldst0 op, 8, %(basereg+0), 2, mem_operand, abits - pixldst0 op, 8, %(basereg+0), 3, mem_operand, abits - .endif -.elseif numbytes == 1 - pixldst0 op, 8, %(basereg+0), 1, mem_operand, abits -.else - .error "unsupported size: numbytes" -.endif -.endm - -.macro pixld numpix, bpp, basereg, mem_operand, abits=0 -.if bpp > 0 -.if (bpp == 32) && (numpix == 8) && (DEINTERLEAVE_32BPP_ENABLED != 0) - pixldst4 vld4, 8, %(basereg+4), %(basereg+5), \ - %(basereg+6), %(basereg+7), mem_operand, abits -.elseif (bpp == 24) && (numpix == 8) - pixldst3 vld3, 8, %(basereg+3), %(basereg+4), %(basereg+5), mem_operand -.elseif (bpp == 24) && (numpix == 4) - pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 4, mem_operand - pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 5, mem_operand - pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 6, mem_operand - pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 7, mem_operand -.elseif (bpp == 24) && (numpix == 2) - pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 2, mem_operand - pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 3, mem_operand -.elseif (bpp == 24) && (numpix == 1) - pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 1, mem_operand -.else - pixldst %(numpix * bpp / 8), vld1, %(bpp), basereg, mem_operand, abits -.endif -.endif -.endm - -.macro pixst numpix, bpp, basereg, mem_operand, abits=0 -.if bpp > 0 -.if (bpp == 32) && (numpix == 8) && (DEINTERLEAVE_32BPP_ENABLED != 0) - pixldst4 vst4, 8, %(basereg+4), %(basereg+5), \ - %(basereg+6), %(basereg+7), mem_operand, abits -.elseif (bpp == 24) && (numpix == 8) - pixldst3 vst3, 8, %(basereg+3), %(basereg+4), %(basereg+5), mem_operand -.elseif (bpp == 24) && (numpix == 4) - pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 4, mem_operand - pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 5, mem_operand - pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 6, mem_operand - pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 7, mem_operand -.elseif (bpp == 24) && (numpix == 2) - pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 2, mem_operand - pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 3, mem_operand -.elseif (bpp == 24) && (numpix == 1) - pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 1, mem_operand -.else - pixldst %(numpix * bpp / 8), vst1, %(bpp), basereg, mem_operand, abits -.endif -.endif -.endm - -.macro pixld_a numpix, bpp, basereg, mem_operand -.if (bpp * numpix) <= 128 - pixld numpix, bpp, basereg, mem_operand, %(bpp * numpix) -.else - pixld numpix, bpp, basereg, mem_operand, 128 -.endif -.endm - -.macro pixst_a numpix, bpp, basereg, mem_operand -.if (bpp * numpix) <= 128 - pixst numpix, bpp, basereg, mem_operand, %(bpp * numpix) -.else - pixst numpix, bpp, basereg, mem_operand, 128 -.endif -.endm - -/* - * Pixel fetcher for nearest scaling (needs TMP1, TMP2, VX, UNIT_X register - * aliases to be defined) - */ -.macro pixld1_s elem_size, reg1, mem_operand -.if elem_size == 16 - mov TMP1, VX, asr #16 - adds VX, VX, UNIT_X -5: subpls VX, VX, SRC_WIDTH_FIXED - bpl 5b - add TMP1, mem_operand, TMP1, asl #1 - mov TMP2, VX, asr #16 - adds VX, VX, UNIT_X -5: subpls VX, VX, SRC_WIDTH_FIXED - bpl 5b - add TMP2, mem_operand, TMP2, asl #1 - vld1.16 {d®1&[0]}, [TMP1, :16] - mov TMP1, VX, asr #16 - adds VX, VX, UNIT_X -5: subpls VX, VX, SRC_WIDTH_FIXED - bpl 5b - add TMP1, mem_operand, TMP1, asl #1 - vld1.16 {d®1&[1]}, [TMP2, :16] - mov TMP2, VX, asr #16 - adds VX, VX, UNIT_X -5: subpls VX, VX, SRC_WIDTH_FIXED - bpl 5b - add TMP2, mem_operand, TMP2, asl #1 - vld1.16 {d®1&[2]}, [TMP1, :16] - vld1.16 {d®1&[3]}, [TMP2, :16] -.elseif elem_size == 32 - mov TMP1, VX, asr #16 - adds VX, VX, UNIT_X -5: subpls VX, VX, SRC_WIDTH_FIXED - bpl 5b - add TMP1, mem_operand, TMP1, asl #2 - mov TMP2, VX, asr #16 - adds VX, VX, UNIT_X -5: subpls VX, VX, SRC_WIDTH_FIXED - bpl 5b - add TMP2, mem_operand, TMP2, asl #2 - vld1.32 {d®1&[0]}, [TMP1, :32] - vld1.32 {d®1&[1]}, [TMP2, :32] -.else - .error "unsupported" -.endif -.endm - -.macro pixld2_s elem_size, reg1, reg2, mem_operand -.if 0 /* elem_size == 32 */ - mov TMP1, VX, asr #16 - add VX, VX, UNIT_X, asl #1 - add TMP1, mem_operand, TMP1, asl #2 - mov TMP2, VX, asr #16 - sub VX, VX, UNIT_X - add TMP2, mem_operand, TMP2, asl #2 - vld1.32 {d®1&[0]}, [TMP1, :32] - mov TMP1, VX, asr #16 - add VX, VX, UNIT_X, asl #1 - add TMP1, mem_operand, TMP1, asl #2 - vld1.32 {d®2&[0]}, [TMP2, :32] - mov TMP2, VX, asr #16 - add VX, VX, UNIT_X - add TMP2, mem_operand, TMP2, asl #2 - vld1.32 {d®1&[1]}, [TMP1, :32] - vld1.32 {d®2&[1]}, [TMP2, :32] -.else - pixld1_s elem_size, reg1, mem_operand - pixld1_s elem_size, reg2, mem_operand -.endif -.endm - -.macro pixld0_s elem_size, reg1, idx, mem_operand -.if elem_size == 16 - mov TMP1, VX, asr #16 - adds VX, VX, UNIT_X -5: subpls VX, VX, SRC_WIDTH_FIXED - bpl 5b - add TMP1, mem_operand, TMP1, asl #1 - vld1.16 {d®1&[idx]}, [TMP1, :16] -.elseif elem_size == 32 - mov TMP1, VX, asr #16 - adds VX, VX, UNIT_X -5: subpls VX, VX, SRC_WIDTH_FIXED - bpl 5b - add TMP1, mem_operand, TMP1, asl #2 - vld1.32 {d®1&[idx]}, [TMP1, :32] -.endif -.endm - -.macro pixld_s_internal numbytes, elem_size, basereg, mem_operand -.if numbytes == 32 - pixld2_s elem_size, %(basereg+4), %(basereg+5), mem_operand - pixld2_s elem_size, %(basereg+6), %(basereg+7), mem_operand - pixdeinterleave elem_size, %(basereg+4) -.elseif numbytes == 16 - pixld2_s elem_size, %(basereg+2), %(basereg+3), mem_operand -.elseif numbytes == 8 - pixld1_s elem_size, %(basereg+1), mem_operand -.elseif numbytes == 4 - .if elem_size == 32 - pixld0_s elem_size, %(basereg+0), 1, mem_operand - .elseif elem_size == 16 - pixld0_s elem_size, %(basereg+0), 2, mem_operand - pixld0_s elem_size, %(basereg+0), 3, mem_operand - .else - pixld0_s elem_size, %(basereg+0), 4, mem_operand - pixld0_s elem_size, %(basereg+0), 5, mem_operand - pixld0_s elem_size, %(basereg+0), 6, mem_operand - pixld0_s elem_size, %(basereg+0), 7, mem_operand - .endif -.elseif numbytes == 2 - .if elem_size == 16 - pixld0_s elem_size, %(basereg+0), 1, mem_operand - .else - pixld0_s elem_size, %(basereg+0), 2, mem_operand - pixld0_s elem_size, %(basereg+0), 3, mem_operand - .endif -.elseif numbytes == 1 - pixld0_s elem_size, %(basereg+0), 1, mem_operand -.else - .error "unsupported size: numbytes" -.endif -.endm - -.macro pixld_s numpix, bpp, basereg, mem_operand -.if bpp > 0 - pixld_s_internal %(numpix * bpp / 8), %(bpp), basereg, mem_operand -.endif -.endm - -.macro vuzp8 reg1, reg2 - vuzp.8 d®1, d®2 -.endm - -.macro vzip8 reg1, reg2 - vzip.8 d®1, d®2 -.endm - -/* deinterleave B, G, R, A channels for eight 32bpp pixels in 4 registers */ -.macro pixdeinterleave bpp, basereg -.if (bpp == 32) && (DEINTERLEAVE_32BPP_ENABLED != 0) - vuzp8 %(basereg+0), %(basereg+1) - vuzp8 %(basereg+2), %(basereg+3) - vuzp8 %(basereg+1), %(basereg+3) - vuzp8 %(basereg+0), %(basereg+2) -.endif -.endm - -/* interleave B, G, R, A channels for eight 32bpp pixels in 4 registers */ -.macro pixinterleave bpp, basereg -.if (bpp == 32) && (DEINTERLEAVE_32BPP_ENABLED != 0) - vzip8 %(basereg+0), %(basereg+2) - vzip8 %(basereg+1), %(basereg+3) - vzip8 %(basereg+2), %(basereg+3) - vzip8 %(basereg+0), %(basereg+1) -.endif -.endm - -/* - * This is a macro for implementing cache preload. The main idea is that - * cache preload logic is mostly independent from the rest of pixels - * processing code. It starts at the top left pixel and moves forward - * across pixels and can jump across scanlines. Prefetch distance is - * handled in an 'incremental' way: it starts from 0 and advances to the - * optimal distance over time. After reaching optimal prefetch distance, - * it is kept constant. There are some checks which prevent prefetching - * unneeded pixel lines below the image (but it still can prefetch a bit - * more data on the right side of the image - not a big issue and may - * be actually helpful when rendering text glyphs). Additional trick is - * the use of LDR instruction for prefetch instead of PLD when moving to - * the next line, the point is that we have a high chance of getting TLB - * miss in this case, and PLD would be useless. - * - * This sounds like it may introduce a noticeable overhead (when working with - * fully cached data). But in reality, due to having a separate pipeline and - * instruction queue for NEON unit in ARM Cortex-A8, normal ARM code can - * execute simultaneously with NEON and be completely shadowed by it. Thus - * we get no performance overhead at all (*). This looks like a very nice - * feature of Cortex-A8, if used wisely. We don't have a hardware prefetcher, - * but still can implement some rather advanced prefetch logic in software - * for almost zero cost! - * - * (*) The overhead of the prefetcher is visible when running some trivial - * pixels processing like simple copy. Anyway, having prefetch is a must - * when working with the graphics data. - */ -.macro PF a, x:vararg -.if (PREFETCH_TYPE_CURRENT == PREFETCH_TYPE_ADVANCED) - a x -.endif -.endm - -.macro cache_preload std_increment, boost_increment -.if (src_bpp_shift >= 0) || (dst_r_bpp != 0) || (mask_bpp_shift >= 0) -.if regs_shortage - PF ldr ORIG_W, [sp] /* If we are short on regs, ORIG_W is kept on stack */ -.endif -.if std_increment != 0 - PF add PF_X, PF_X, #std_increment -.endif - PF tst PF_CTL, #0xF - PF addne PF_X, PF_X, #boost_increment - PF subne PF_CTL, PF_CTL, #1 - PF cmp PF_X, ORIG_W -.if src_bpp_shift >= 0 - PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] -.endif -.if dst_r_bpp != 0 - PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] -.endif -.if mask_bpp_shift >= 0 - PF pld, [PF_MASK, PF_X, lsl #mask_bpp_shift] -.endif - PF subge PF_X, PF_X, ORIG_W - PF subges PF_CTL, PF_CTL, #0x10 -.if src_bpp_shift >= 0 - PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! -.endif -.if dst_r_bpp != 0 - PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! -.endif -.if mask_bpp_shift >= 0 - PF ldrgeb DUMMY, [PF_MASK, MASK_STRIDE, lsl #mask_bpp_shift]! -.endif -.endif -.endm - -.macro cache_preload_simple -.if (PREFETCH_TYPE_CURRENT == PREFETCH_TYPE_SIMPLE) -.if src_bpp > 0 - pld [SRC, #(PREFETCH_DISTANCE_SIMPLE * src_bpp / 8)] -.endif -.if dst_r_bpp > 0 - pld [DST_R, #(PREFETCH_DISTANCE_SIMPLE * dst_r_bpp / 8)] -.endif -.if mask_bpp > 0 - pld [MASK, #(PREFETCH_DISTANCE_SIMPLE * mask_bpp / 8)] -.endif -.endif -.endm - -.macro fetch_mask_pixblock - pixld pixblock_size, mask_bpp, \ - (mask_basereg - pixblock_size * mask_bpp / 64), MASK -.endm - -/* - * Macro which is used to process leading pixels until destination - * pointer is properly aligned (at 16 bytes boundary). When destination - * buffer uses 16bpp format, this is unnecessary, or even pointless. - */ -.macro ensure_destination_ptr_alignment process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head -.if dst_w_bpp != 24 - tst DST_R, #0xF - beq 2f - -.irp lowbit, 1, 2, 4, 8, 16 -local skip1 -.if (dst_w_bpp <= (lowbit * 8)) && ((lowbit * 8) < (pixblock_size * dst_w_bpp)) -.if lowbit < 16 /* we don't need more than 16-byte alignment */ - tst DST_R, #lowbit - beq 1f -.endif - pixld_src (lowbit * 8 / dst_w_bpp), src_bpp, src_basereg, SRC - pixld (lowbit * 8 / dst_w_bpp), mask_bpp, mask_basereg, MASK -.if dst_r_bpp > 0 - pixld_a (lowbit * 8 / dst_r_bpp), dst_r_bpp, dst_r_basereg, DST_R -.else - add DST_R, DST_R, #lowbit -.endif - PF add PF_X, PF_X, #(lowbit * 8 / dst_w_bpp) - sub W, W, #(lowbit * 8 / dst_w_bpp) -1: -.endif -.endr - pixdeinterleave src_bpp, src_basereg - pixdeinterleave mask_bpp, mask_basereg - pixdeinterleave dst_r_bpp, dst_r_basereg - - process_pixblock_head - cache_preload 0, pixblock_size - cache_preload_simple - process_pixblock_tail - - pixinterleave dst_w_bpp, dst_w_basereg -.irp lowbit, 1, 2, 4, 8, 16 -.if (dst_w_bpp <= (lowbit * 8)) && ((lowbit * 8) < (pixblock_size * dst_w_bpp)) -.if lowbit < 16 /* we don't need more than 16-byte alignment */ - tst DST_W, #lowbit - beq 1f -.endif - pixst_a (lowbit * 8 / dst_w_bpp), dst_w_bpp, dst_w_basereg, DST_W -1: -.endif -.endr -.endif -2: -.endm - -/* - * Special code for processing up to (pixblock_size - 1) remaining - * trailing pixels. As SIMD processing performs operation on - * pixblock_size pixels, anything smaller than this has to be loaded - * and stored in a special way. Loading and storing of pixel data is - * performed in such a way that we fill some 'slots' in the NEON - * registers (some slots naturally are unused), then perform compositing - * operation as usual. In the end, the data is taken from these 'slots' - * and saved to memory. - * - * cache_preload_flag - allows to suppress prefetch if - * set to 0 - * dst_aligned_flag - selects whether destination buffer - * is aligned - */ -.macro process_trailing_pixels cache_preload_flag, \ - dst_aligned_flag, \ - process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head - tst W, #(pixblock_size - 1) - beq 2f -.irp chunk_size, 16, 8, 4, 2, 1 -.if pixblock_size > chunk_size - tst W, #chunk_size - beq 1f - pixld_src chunk_size, src_bpp, src_basereg, SRC - pixld chunk_size, mask_bpp, mask_basereg, MASK -.if dst_aligned_flag != 0 - pixld_a chunk_size, dst_r_bpp, dst_r_basereg, DST_R -.else - pixld chunk_size, dst_r_bpp, dst_r_basereg, DST_R -.endif -.if cache_preload_flag != 0 - PF add PF_X, PF_X, #chunk_size -.endif -1: -.endif -.endr - pixdeinterleave src_bpp, src_basereg - pixdeinterleave mask_bpp, mask_basereg - pixdeinterleave dst_r_bpp, dst_r_basereg - - process_pixblock_head -.if cache_preload_flag != 0 - cache_preload 0, pixblock_size - cache_preload_simple -.endif - process_pixblock_tail - pixinterleave dst_w_bpp, dst_w_basereg -.irp chunk_size, 16, 8, 4, 2, 1 -.if pixblock_size > chunk_size - tst W, #chunk_size - beq 1f -.if dst_aligned_flag != 0 - pixst_a chunk_size, dst_w_bpp, dst_w_basereg, DST_W -.else - pixst chunk_size, dst_w_bpp, dst_w_basereg, DST_W -.endif -1: -.endif -.endr -2: -.endm - -/* - * Macro, which performs all the needed operations to switch to the next - * scanline and start the next loop iteration unless all the scanlines - * are already processed. - */ -.macro advance_to_next_scanline start_of_loop_label -.if regs_shortage - ldrd W, [sp] /* load W and H (width and height) from stack */ -.else - mov W, ORIG_W -.endif - add DST_W, DST_W, DST_STRIDE, lsl #dst_bpp_shift -.if src_bpp != 0 - add SRC, SRC, SRC_STRIDE, lsl #src_bpp_shift -.endif -.if mask_bpp != 0 - add MASK, MASK, MASK_STRIDE, lsl #mask_bpp_shift -.endif -.if (dst_w_bpp != 24) - sub DST_W, DST_W, W, lsl #dst_bpp_shift -.endif -.if (src_bpp != 24) && (src_bpp != 0) - sub SRC, SRC, W, lsl #src_bpp_shift -.endif -.if (mask_bpp != 24) && (mask_bpp != 0) - sub MASK, MASK, W, lsl #mask_bpp_shift -.endif - subs H, H, #1 - mov DST_R, DST_W -.if regs_shortage - str H, [sp, #4] /* save updated height to stack */ -.endif - bge start_of_loop_label -.endm - -/* - * Registers are allocated in the following way by default: - * d0, d1, d2, d3 - reserved for loading source pixel data - * d4, d5, d6, d7 - reserved for loading destination pixel data - * d24, d25, d26, d27 - reserved for loading mask pixel data - * d28, d29, d30, d31 - final destination pixel data for writeback to memory - */ -.macro generate_composite_function fname, \ - src_bpp_, \ - mask_bpp_, \ - dst_w_bpp_, \ - flags, \ - pixblock_size_, \ - prefetch_distance, \ - init, \ - cleanup, \ - process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head, \ - dst_w_basereg_ = 28, \ - dst_r_basereg_ = 4, \ - src_basereg_ = 0, \ - mask_basereg_ = 24 - - pixman_asm_function fname - - push {r4-r12, lr} /* save all registers */ - -/* - * Select prefetch type for this function. If prefetch distance is - * set to 0 or one of the color formats is 24bpp, SIMPLE prefetch - * has to be used instead of ADVANCED. - */ - .set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_DEFAULT -.if prefetch_distance == 0 - .set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_NONE -.elseif (PREFETCH_TYPE_CURRENT > PREFETCH_TYPE_SIMPLE) && \ - ((src_bpp_ == 24) || (mask_bpp_ == 24) || (dst_w_bpp_ == 24)) - .set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_SIMPLE -.endif - -/* - * Make some macro arguments globally visible and accessible - * from other macros - */ - .set src_bpp, src_bpp_ - .set mask_bpp, mask_bpp_ - .set dst_w_bpp, dst_w_bpp_ - .set pixblock_size, pixblock_size_ - .set dst_w_basereg, dst_w_basereg_ - .set dst_r_basereg, dst_r_basereg_ - .set src_basereg, src_basereg_ - .set mask_basereg, mask_basereg_ - - .macro pixld_src x:vararg - pixld x - .endm - .macro fetch_src_pixblock - pixld_src pixblock_size, src_bpp, \ - (src_basereg - pixblock_size * src_bpp / 64), SRC - .endm -/* - * Assign symbolic names to registers - */ - W .req r0 /* width (is updated during processing) */ - H .req r1 /* height (is updated during processing) */ - DST_W .req r2 /* destination buffer pointer for writes */ - DST_STRIDE .req r3 /* destination image stride */ - SRC .req r4 /* source buffer pointer */ - SRC_STRIDE .req r5 /* source image stride */ - DST_R .req r6 /* destination buffer pointer for reads */ - - MASK .req r7 /* mask pointer */ - MASK_STRIDE .req r8 /* mask stride */ - - PF_CTL .req r9 /* combined lines counter and prefetch */ - /* distance increment counter */ - PF_X .req r10 /* pixel index in a scanline for current */ - /* pretetch position */ - PF_SRC .req r11 /* pointer to source scanline start */ - /* for prefetch purposes */ - PF_DST .req r12 /* pointer to destination scanline start */ - /* for prefetch purposes */ - PF_MASK .req r14 /* pointer to mask scanline start */ - /* for prefetch purposes */ -/* - * Check whether we have enough registers for all the local variables. - * If we don't have enough registers, original width and height are - * kept on top of stack (and 'regs_shortage' variable is set to indicate - * this for the rest of code). Even if there are enough registers, the - * allocation scheme may be a bit different depending on whether source - * or mask is not used. - */ -.if (PREFETCH_TYPE_CURRENT < PREFETCH_TYPE_ADVANCED) - ORIG_W .req r10 /* saved original width */ - DUMMY .req r12 /* temporary register */ - .set regs_shortage, 0 -.elseif mask_bpp == 0 - ORIG_W .req r7 /* saved original width */ - DUMMY .req r8 /* temporary register */ - .set regs_shortage, 0 -.elseif src_bpp == 0 - ORIG_W .req r4 /* saved original width */ - DUMMY .req r5 /* temporary register */ - .set regs_shortage, 0 -.else - ORIG_W .req r1 /* saved original width */ - DUMMY .req r1 /* temporary register */ - .set regs_shortage, 1 -.endif - - .set mask_bpp_shift, -1 -.if src_bpp == 32 - .set src_bpp_shift, 2 -.elseif src_bpp == 24 - .set src_bpp_shift, 0 -.elseif src_bpp == 16 - .set src_bpp_shift, 1 -.elseif src_bpp == 8 - .set src_bpp_shift, 0 -.elseif src_bpp == 0 - .set src_bpp_shift, -1 -.else - .error "requested src bpp (src_bpp) is not supported" -.endif -.if mask_bpp == 32 - .set mask_bpp_shift, 2 -.elseif mask_bpp == 24 - .set mask_bpp_shift, 0 -.elseif mask_bpp == 8 - .set mask_bpp_shift, 0 -.elseif mask_bpp == 0 - .set mask_bpp_shift, -1 -.else - .error "requested mask bpp (mask_bpp) is not supported" -.endif -.if dst_w_bpp == 32 - .set dst_bpp_shift, 2 -.elseif dst_w_bpp == 24 - .set dst_bpp_shift, 0 -.elseif dst_w_bpp == 16 - .set dst_bpp_shift, 1 -.elseif dst_w_bpp == 8 - .set dst_bpp_shift, 0 -.else - .error "requested dst bpp (dst_w_bpp) is not supported" -.endif - -.if (((flags) & FLAG_DST_READWRITE) != 0) - .set dst_r_bpp, dst_w_bpp -.else - .set dst_r_bpp, 0 -.endif -.if (((flags) & FLAG_DEINTERLEAVE_32BPP) != 0) - .set DEINTERLEAVE_32BPP_ENABLED, 1 -.else - .set DEINTERLEAVE_32BPP_ENABLED, 0 -.endif - -.if prefetch_distance < 0 || prefetch_distance > 15 - .error "invalid prefetch distance (prefetch_distance)" -.endif - -.if src_bpp > 0 - ldr SRC, [sp, #40] -.endif -.if mask_bpp > 0 - ldr MASK, [sp, #48] -.endif - PF mov PF_X, #0 -.if src_bpp > 0 - ldr SRC_STRIDE, [sp, #44] -.endif -.if mask_bpp > 0 - ldr MASK_STRIDE, [sp, #52] -.endif - mov DST_R, DST_W - -.if src_bpp == 24 - sub SRC_STRIDE, SRC_STRIDE, W - sub SRC_STRIDE, SRC_STRIDE, W, lsl #1 -.endif -.if mask_bpp == 24 - sub MASK_STRIDE, MASK_STRIDE, W - sub MASK_STRIDE, MASK_STRIDE, W, lsl #1 -.endif -.if dst_w_bpp == 24 - sub DST_STRIDE, DST_STRIDE, W - sub DST_STRIDE, DST_STRIDE, W, lsl #1 -.endif - -/* - * Setup advanced prefetcher initial state - */ - PF mov PF_SRC, SRC - PF mov PF_DST, DST_R - PF mov PF_MASK, MASK - /* PF_CTL = prefetch_distance | ((h - 1) << 4) */ - PF mov PF_CTL, H, lsl #4 - PF add PF_CTL, #(prefetch_distance - 0x10) - - init -.if regs_shortage - push {r0, r1} -.endif - subs H, H, #1 -.if regs_shortage - str H, [sp, #4] /* save updated height to stack */ -.else - mov ORIG_W, W -.endif - blt 9f - cmp W, #(pixblock_size * 2) - blt 8f -/* - * This is the start of the pipelined loop, which if optimized for - * long scanlines - */ -0: - ensure_destination_ptr_alignment process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head - - /* Implement "head (tail_head) ... (tail_head) tail" loop pattern */ - pixld_a pixblock_size, dst_r_bpp, \ - (dst_r_basereg - pixblock_size * dst_r_bpp / 64), DST_R - fetch_src_pixblock - pixld pixblock_size, mask_bpp, \ - (mask_basereg - pixblock_size * mask_bpp / 64), MASK - PF add PF_X, PF_X, #pixblock_size - process_pixblock_head - cache_preload 0, pixblock_size - cache_preload_simple - subs W, W, #(pixblock_size * 2) - blt 2f -1: - process_pixblock_tail_head - cache_preload_simple - subs W, W, #pixblock_size - bge 1b -2: - process_pixblock_tail - pixst_a pixblock_size, dst_w_bpp, \ - (dst_w_basereg - pixblock_size * dst_w_bpp / 64), DST_W - - /* Process the remaining trailing pixels in the scanline */ - process_trailing_pixels 1, 1, \ - process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head - advance_to_next_scanline 0b - -.if regs_shortage - pop {r0, r1} -.endif - cleanup - pop {r4-r12, pc} /* exit */ -/* - * This is the start of the loop, designed to process images with small width - * (less than pixblock_size * 2 pixels). In this case neither pipelining - * nor prefetch are used. - */ -8: - /* Process exactly pixblock_size pixels if needed */ - tst W, #pixblock_size - beq 1f - pixld pixblock_size, dst_r_bpp, \ - (dst_r_basereg - pixblock_size * dst_r_bpp / 64), DST_R - fetch_src_pixblock - pixld pixblock_size, mask_bpp, \ - (mask_basereg - pixblock_size * mask_bpp / 64), MASK - process_pixblock_head - process_pixblock_tail - pixst pixblock_size, dst_w_bpp, \ - (dst_w_basereg - pixblock_size * dst_w_bpp / 64), DST_W -1: - /* Process the remaining trailing pixels in the scanline */ - process_trailing_pixels 0, 0, \ - process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head - advance_to_next_scanline 8b -9: -.if regs_shortage - pop {r0, r1} -.endif - cleanup - pop {r4-r12, pc} /* exit */ - - .purgem fetch_src_pixblock - .purgem pixld_src - - .unreq SRC - .unreq MASK - .unreq DST_R - .unreq DST_W - .unreq ORIG_W - .unreq W - .unreq H - .unreq SRC_STRIDE - .unreq DST_STRIDE - .unreq MASK_STRIDE - .unreq PF_CTL - .unreq PF_X - .unreq PF_SRC - .unreq PF_DST - .unreq PF_MASK - .unreq DUMMY - .endfunc -.endm - -/* - * A simplified variant of function generation template for a single - * scanline processing (for implementing pixman combine functions) - */ -.macro generate_composite_function_scanline use_nearest_scaling, \ - fname, \ - src_bpp_, \ - mask_bpp_, \ - dst_w_bpp_, \ - flags, \ - pixblock_size_, \ - init, \ - cleanup, \ - process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head, \ - dst_w_basereg_ = 28, \ - dst_r_basereg_ = 4, \ - src_basereg_ = 0, \ - mask_basereg_ = 24 - - pixman_asm_function fname - - .set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_NONE -/* - * Make some macro arguments globally visible and accessible - * from other macros - */ - .set src_bpp, src_bpp_ - .set mask_bpp, mask_bpp_ - .set dst_w_bpp, dst_w_bpp_ - .set pixblock_size, pixblock_size_ - .set dst_w_basereg, dst_w_basereg_ - .set dst_r_basereg, dst_r_basereg_ - .set src_basereg, src_basereg_ - .set mask_basereg, mask_basereg_ - -.if use_nearest_scaling != 0 - /* - * Assign symbolic names to registers for nearest scaling - */ - W .req r0 - DST_W .req r1 - SRC .req r2 - VX .req r3 - UNIT_X .req ip - MASK .req lr - TMP1 .req r4 - TMP2 .req r5 - DST_R .req r6 - SRC_WIDTH_FIXED .req r7 - - .macro pixld_src x:vararg - pixld_s x - .endm - - ldr UNIT_X, [sp] - push {r4-r8, lr} - ldr SRC_WIDTH_FIXED, [sp, #(24 + 4)] - .if mask_bpp != 0 - ldr MASK, [sp, #(24 + 8)] - .endif -.else - /* - * Assign symbolic names to registers - */ - W .req r0 /* width (is updated during processing) */ - DST_W .req r1 /* destination buffer pointer for writes */ - SRC .req r2 /* source buffer pointer */ - DST_R .req ip /* destination buffer pointer for reads */ - MASK .req r3 /* mask pointer */ - - .macro pixld_src x:vararg - pixld x - .endm -.endif - -.if (((flags) & FLAG_DST_READWRITE) != 0) - .set dst_r_bpp, dst_w_bpp -.else - .set dst_r_bpp, 0 -.endif -.if (((flags) & FLAG_DEINTERLEAVE_32BPP) != 0) - .set DEINTERLEAVE_32BPP_ENABLED, 1 -.else - .set DEINTERLEAVE_32BPP_ENABLED, 0 -.endif - - .macro fetch_src_pixblock - pixld_src pixblock_size, src_bpp, \ - (src_basereg - pixblock_size * src_bpp / 64), SRC - .endm - - init - mov DST_R, DST_W - - cmp W, #pixblock_size - blt 8f - - ensure_destination_ptr_alignment process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head - - subs W, W, #pixblock_size - blt 7f - - /* Implement "head (tail_head) ... (tail_head) tail" loop pattern */ - pixld_a pixblock_size, dst_r_bpp, \ - (dst_r_basereg - pixblock_size * dst_r_bpp / 64), DST_R - fetch_src_pixblock - pixld pixblock_size, mask_bpp, \ - (mask_basereg - pixblock_size * mask_bpp / 64), MASK - process_pixblock_head - subs W, W, #pixblock_size - blt 2f -1: - process_pixblock_tail_head - subs W, W, #pixblock_size - bge 1b -2: - process_pixblock_tail - pixst_a pixblock_size, dst_w_bpp, \ - (dst_w_basereg - pixblock_size * dst_w_bpp / 64), DST_W -7: - /* Process the remaining trailing pixels in the scanline (dst aligned) */ - process_trailing_pixels 0, 1, \ - process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head - - cleanup -.if use_nearest_scaling != 0 - pop {r4-r8, pc} /* exit */ -.else - bx lr /* exit */ -.endif -8: - /* Process the remaining trailing pixels in the scanline (dst unaligned) */ - process_trailing_pixels 0, 0, \ - process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head - - cleanup - -.if use_nearest_scaling != 0 - pop {r4-r8, pc} /* exit */ - - .unreq DST_R - .unreq SRC - .unreq W - .unreq VX - .unreq UNIT_X - .unreq TMP1 - .unreq TMP2 - .unreq DST_W - .unreq MASK - .unreq SRC_WIDTH_FIXED - -.else - bx lr /* exit */ - - .unreq SRC - .unreq MASK - .unreq DST_R - .unreq DST_W - .unreq W -.endif - - .purgem fetch_src_pixblock - .purgem pixld_src - - .endfunc -.endm - -.macro generate_composite_function_single_scanline x:vararg - generate_composite_function_scanline 0, x -.endm - -.macro generate_composite_function_nearest_scanline x:vararg - generate_composite_function_scanline 1, x -.endm - -/* Default prologue/epilogue, nothing special needs to be done */ - -.macro default_init -.endm - -.macro default_cleanup -.endm - -/* - * Prologue/epilogue variant which additionally saves/restores d8-d15 - * registers (they need to be saved/restored by callee according to ABI). - * This is required if the code needs to use all the NEON registers. - */ - -.macro default_init_need_all_regs - vpush {d8-d15} -.endm - -.macro default_cleanup_need_all_regs - vpop {d8-d15} -.endm - -/******************************************************************************/ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/stb/CMakeLists.txt b/presentation/src/main/cpp/third_party/rlottie/src/vector/stb/CMakeLists.txt deleted file mode 100644 index b668b43a..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/stb/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -if(LOTTIE_MODULE) - add_library(rlottie-image-loader SHARED - stb_image.cpp - ) - if(NOT MSVC) - target_compile_options(rlottie-image-loader PRIVATE - -fvisibility=hidden - ) - endif() - - get_filename_component(LOTTIE_MODULE_FILENAME ${LOTTIE_MODULE_PATH} NAME) - get_filename_component(LOTTIE_MODULE_DIR ${LOTTIE_MODULE_PATH} DIRECTORY) - if (NOT LOTTIE_MODULE_DIR) - set(LOTTIE_MODULE_DIR ${LIB_INSTALL_DIR}) - endif() - - set_target_properties(rlottie-image-loader PROPERTIES - DEFINE_SYMBOL RLOTTIE_BUILD - PREFIX "" - SUFFIX "" - OUTPUT_NAME ${LOTTIE_MODULE_FILENAME} - ) - install(TARGETS rlottie-image-loader - LIBRARY DESTINATION ${LOTTIE_MODULE_DIR} - ) -else() - target_sources(rlottie - PRIVATE - "${CMAKE_CURRENT_LIST_DIR}/stb_image.cpp" - ) -endif() diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/stb/meson.build b/presentation/src/main/cpp/third_party/rlottie/src/vector/stb/meson.build deleted file mode 100644 index 128114f3..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/stb/meson.build +++ /dev/null @@ -1,22 +0,0 @@ - -source_file = ['stb_image.cpp'] - -if get_option('module') == true - rlottie_image_loader_dir = get_option('moduledir') != '' ? get_option('moduledir') : get_option('libdir') - rlottie_image_loader_lib = shared_module('rlottie-image-loader', - source_file, - include_directories : [include_directories('.'), config_dir], - install : true, - install_dir : rlottie_image_loader_dir, - cpp_args : compiler_flags, - gnu_symbol_visibility : 'hidden', - ) - cc = meson.get_compiler('cpp') - stb_dep = cc.find_library('dl', required : false) -else - stb_dep = declare_dependency( include_directories : include_directories('.'), - sources : source_file - ) -endif - - diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/stb/stb_image.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/stb/stb_image.cpp deleted file mode 100644 index 2c4933e8..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/stb/stb_image.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * configure stb_image about - * the image we will support - */ -#define STB_IMAGE_IMPLEMENTATION - -#define STBI_ONLY_JPEG -#define STBI_ONLY_PNG -#define STBI_NO_HDR -#define STBI_NO_LINEAR -#define STBI_NO_GIF -#define STBI_NO_PIC - -#include "stb_image.h" - -#if defined _WIN32 || defined __CYGWIN__ - #ifdef RLOTTIE_BUILD - #define RLOTTIE_API __declspec(dllexport) - #else - #define RLOTTIE_API __declspec(dllimport) - #endif -#else - #ifdef RLOTTIE_BUILD - #define RLOTTIE_API __attribute__ ((visibility ("default"))) - #else - #define RLOTTIE_API - #endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * exported function wrapper from the library - */ - -RLOTTIE_API unsigned char *lottie_image_load(char const *filename, int *x, - int *y, int *comp, int req_comp) -{ - return stbi_load(filename, x, y, comp, req_comp); -} - -RLOTTIE_API unsigned char *lottie_image_load_from_data(const char *imageData, - int len, int *x, int *y, - int *comp, int req_comp) -{ - unsigned char *data = (unsigned char *)imageData; - return stbi_load_from_memory(data, len, x, y, comp, req_comp); -} - -RLOTTIE_API void lottie_image_free(unsigned char *data) -{ - stbi_image_free(data); -} - -#ifdef __cplusplus -} -#endif diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/stb/stb_image.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/stb/stb_image.h deleted file mode 100644 index 56f81830..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/stb/stb_image.h +++ /dev/null @@ -1,7509 +0,0 @@ -/* stb_image - v2.19 - public domain image loader - http://nothings.org/stb - no warranty implied; use at your own risk - - Do this: - #define STB_IMAGE_IMPLEMENTATION - before you include this file in *one* C or C++ file to create the implementation. - - // i.e. it should look like this: - #include ... - #include ... - #include ... - #define STB_IMAGE_IMPLEMENTATION - #include "stb_image.h" - - You can #define STBI_ASSERT(x) before the #include to avoid using assert.h. - And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free - - - QUICK NOTES: - Primarily of interest to game developers and other people who can - avoid problematic images and only need the trivial interface - - JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib) - PNG 1/2/4/8/16-bit-per-channel - - TGA (not sure what subset, if a subset) - BMP non-1bpp, non-RLE - PSD (composited view only, no extra channels, 8/16 bit-per-channel) - - GIF (*comp always reports as 4-channel) - HDR (radiance rgbE format) - PIC (Softimage PIC) - PNM (PPM and PGM binary only) - - Animated GIF still needs a proper API, but here's one way to do it: - http://gist.github.com/urraka/685d9a6340b26b830d49 - - - decode from memory or through FILE (define STBI_NO_STDIO to remove code) - - decode from arbitrary I/O callbacks - - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON) - - Full documentation under "DOCUMENTATION" below. - - -LICENSE - - See end of file for license information. - -RECENT REVISION HISTORY: - - 2.19 (2018-02-11) fix warning - 2.18 (2018-01-30) fix warnings - 2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings - 2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes - 2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC - 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs - 2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes - 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes - 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64 - RGB-format JPEG; remove white matting in PSD; - allocate large structures on the stack; - correct channel count for PNG & BMP - 2.10 (2016-01-22) avoid warning introduced in 2.09 - 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED - - See end of file for full revision history. - - - ============================ Contributors ========================= - - Image formats Extensions, features - Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info) - Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info) - Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG) - Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks) - Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG) - Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) - Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) - github:urraka (animated gif) Junggon Kim (PNM comments) - Christopher Forseth (animated gif) Daniel Gibson (16-bit TGA) - socks-the-fox (16-bit PNG) - Jeremy Sawicki (handle all ImageNet JPGs) - Optimizations & bugfixes Mikhail Morozov (1-bit BMP) - Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query) - Arseny Kapoulkine - John-Mark Allen - - Bug & warning fixes - Marc LeBlanc David Woo Guillaume George Martins Mozeiko - Christpher Lloyd Jerry Jansson Joseph Thomson Phil Jordan - Dave Moore Roy Eltham Hayaki Saito Nathan Reed - Won Chun Luke Graham Johan Duparc Nick Verigakis - the Horde3D community Thomas Ruf Ronny Chevalier github:rlyeh - Janez Zemva John Bartholomew Michal Cichon github:romigrou - Jonathan Blow Ken Hamada Tero Hanninen github:svdijk - Laurent Gomila Cort Stratton Sergio Gonzalez github:snagar - Aruelien Pocheville Thibault Reuille Cass Everitt github:Zelex - Ryamond Barbiero Paul Du Bois Engin Manap github:grim210 - Aldo Culquicondor Philipp Wiesemann Dale Weiler github:sammyhw - Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus - Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo - Christian Floisand Kevin Schmidt github:darealshinji - Blazej Dariusz Roszkowski github:Michaelangel007 -*/ - -#ifndef STBI_INCLUDE_STB_IMAGE_H -#define STBI_INCLUDE_STB_IMAGE_H - -// DOCUMENTATION -// -// Limitations: -// - no 12-bit-per-channel JPEG -// - no JPEGs with arithmetic coding -// - GIF always returns *comp=4 -// -// Basic usage (see HDR discussion below for HDR usage): -// int x,y,n; -// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); -// // ... process data if not NULL ... -// // ... x = width, y = height, n = # 8-bit components per pixel ... -// // ... replace '0' with '1'..'4' to force that many components per pixel -// // ... but 'n' will always be the number that it would have been if you said 0 -// stbi_image_free(data) -// -// Standard parameters: -// int *x -- outputs image width in pixels -// int *y -- outputs image height in pixels -// int *channels_in_file -- outputs # of image components in image file -// int desired_channels -- if non-zero, # of image components requested in result -// -// The return value from an image loader is an 'unsigned char *' which points -// to the pixel data, or NULL on an allocation failure or if the image is -// corrupt or invalid. The pixel data consists of *y scanlines of *x pixels, -// with each pixel consisting of N interleaved 8-bit components; the first -// pixel pointed to is top-left-most in the image. There is no padding between -// image scanlines or between pixels, regardless of format. The number of -// components N is 'desired_channels' if desired_channels is non-zero, or -// *channels_in_file otherwise. If desired_channels is non-zero, -// *channels_in_file has the number of components that _would_ have been -// output otherwise. E.g. if you set desired_channels to 4, you will always -// get RGBA output, but you can check *channels_in_file to see if it's trivially -// opaque because e.g. there were only 3 channels in the source image. -// -// An output image with N components has the following components interleaved -// in this order in each pixel: -// -// N=#comp components -// 1 grey -// 2 grey, alpha -// 3 red, green, blue -// 4 red, green, blue, alpha -// -// If image loading fails for any reason, the return value will be NULL, -// and *x, *y, *channels_in_file will be unchanged. The function -// stbi_failure_reason() can be queried for an extremely brief, end-user -// unfriendly explanation of why the load failed. Define STBI_NO_FAILURE_STRINGS -// to avoid compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly -// more user-friendly ones. -// -// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. -// -// =========================================================================== -// -// Philosophy -// -// stb libraries are designed with the following priorities: -// -// 1. easy to use -// 2. easy to maintain -// 3. good performance -// -// Sometimes I let "good performance" creep up in priority over "easy to maintain", -// and for best performance I may provide less-easy-to-use APIs that give higher -// performance, in addition to the easy to use ones. Nevertheless, it's important -// to keep in mind that from the standpoint of you, a client of this library, -// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all. -// -// Some secondary priorities arise directly from the first two, some of which -// make more explicit reasons why performance can't be emphasized. -// -// - Portable ("ease of use") -// - Small source code footprint ("easy to maintain") -// - No dependencies ("ease of use") -// -// =========================================================================== -// -// I/O callbacks -// -// I/O callbacks allow you to read from arbitrary sources, like packaged -// files or some other source. Data read from callbacks are processed -// through a small internal buffer (currently 128 bytes) to try to reduce -// overhead. -// -// The three functions you must define are "read" (reads some bytes of data), -// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). -// -// =========================================================================== -// -// SIMD support -// -// The JPEG decoder will try to automatically use SIMD kernels on x86 when -// supported by the compiler. For ARM Neon support, you must explicitly -// request it. -// -// (The old do-it-yourself SIMD API is no longer supported in the current -// code.) -// -// On x86, SSE2 will automatically be used when available based on a run-time -// test; if not, the generic C versions are used as a fall-back. On ARM targets, -// the typical path is to have separate builds for NEON and non-NEON devices -// (at least this is true for iOS and Android). Therefore, the NEON support is -// toggled by a build flag: define STBI_NEON to get NEON loops. -// -// If for some reason you do not want to use any of SIMD code, or if -// you have issues compiling it, you can disable it entirely by -// defining STBI_NO_SIMD. -// -// =========================================================================== -// -// HDR image support (disable by defining STBI_NO_HDR) -// -// stb_image now supports loading HDR images in general, and currently -// the Radiance .HDR file format, although the support is provided -// generically. You can still load any file through the existing interface; -// if you attempt to load an HDR file, it will be automatically remapped to -// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; -// both of these constants can be reconfigured through this interface: -// -// stbi_hdr_to_ldr_gamma(2.2f); -// stbi_hdr_to_ldr_scale(1.0f); -// -// (note, do not use _inverse_ constants; stbi_image will invert them -// appropriately). -// -// Additionally, there is a new, parallel interface for loading files as -// (linear) floats to preserve the full dynamic range: -// -// float *data = stbi_loadf(filename, &x, &y, &n, 0); -// -// If you load LDR images through this interface, those images will -// be promoted to floating point values, run through the inverse of -// constants corresponding to the above: -// -// stbi_ldr_to_hdr_scale(1.0f); -// stbi_ldr_to_hdr_gamma(2.2f); -// -// Finally, given a filename (or an open file or memory block--see header -// file for details) containing image data, you can query for the "most -// appropriate" interface to use (that is, whether the image is HDR or -// not), using: -// -// stbi_is_hdr(char *filename); -// -// =========================================================================== -// -// iPhone PNG support: -// -// By default we convert iphone-formatted PNGs back to RGB, even though -// they are internally encoded differently. You can disable this conversion -// by by calling stbi_convert_iphone_png_to_rgb(0), in which case -// you will always just get the native iphone "format" through (which -// is BGR stored in RGB). -// -// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per -// pixel to remove any premultiplied alpha *only* if the image file explicitly -// says there's premultiplied data (currently only happens in iPhone images, -// and only if iPhone convert-to-rgb processing is on). -// -// =========================================================================== -// -// ADDITIONAL CONFIGURATION -// -// - You can suppress implementation of any of the decoders to reduce -// your code footprint by #defining one or more of the following -// symbols before creating the implementation. -// -// STBI_NO_JPEG -// STBI_NO_PNG -// STBI_NO_BMP -// STBI_NO_PSD -// STBI_NO_TGA -// STBI_NO_GIF -// STBI_NO_HDR -// STBI_NO_PIC -// STBI_NO_PNM (.ppm and .pgm) -// -// - You can request *only* certain decoders and suppress all other ones -// (this will be more forward-compatible, as addition of new decoders -// doesn't require you to disable them explicitly): -// -// STBI_ONLY_JPEG -// STBI_ONLY_PNG -// STBI_ONLY_BMP -// STBI_ONLY_PSD -// STBI_ONLY_TGA -// STBI_ONLY_GIF -// STBI_ONLY_HDR -// STBI_ONLY_PIC -// STBI_ONLY_PNM (.ppm and .pgm) -// -// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still -// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB -// - - -#ifndef STBI_NO_STDIO -#include -#endif // STBI_NO_STDIO - -#if defined _WIN32 || defined __CYGWIN__ -#include -#endif // defined _WIN32 || defined __CYGWIN__ - -#define STBI_VERSION 1 - -enum -{ - STBI_default = 0, // only used for desired_channels - - STBI_grey = 1, - STBI_grey_alpha = 2, - STBI_rgb = 3, - STBI_rgb_alpha = 4 -}; - -typedef unsigned char stbi_uc; -typedef unsigned short stbi_us; - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef STB_IMAGE_STATIC -#define STBIDEF static -#else -#define STBIDEF extern -#endif - -////////////////////////////////////////////////////////////////////////////// -// -// PRIMARY API - works on images of any type -// - -// -// load image by filename, open file, or memory buffer -// - -typedef struct -{ - int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read - void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative - int (*eof) (void *user); // returns nonzero if we are at end of file/data -} stbi_io_callbacks; - -//////////////////////////////////// -// -// 8-bits-per-channel interface -// - -STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels); -STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels); -#ifndef STBI_NO_GIF -STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp); -#endif - - -#ifndef STBI_NO_STDIO -STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); -STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); -// for stbi_load_from_file, file pointer is left pointing immediately after image -#endif - -//////////////////////////////////// -// -// 16-bits-per-channel interface -// - -STBIDEF stbi_us *stbi_load_16_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); -STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); - -#ifndef STBI_NO_STDIO -STBIDEF stbi_us *stbi_load_16 (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); -STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); -#endif - -//////////////////////////////////// -// -// float-per-channel interface -// -#ifndef STBI_NO_LINEAR - STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); - STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); - - #ifndef STBI_NO_STDIO - STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); - STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); - #endif -#endif - -#ifndef STBI_NO_HDR - STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); - STBIDEF void stbi_hdr_to_ldr_scale(float scale); -#endif // STBI_NO_HDR - -#ifndef STBI_NO_LINEAR - STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); - STBIDEF void stbi_ldr_to_hdr_scale(float scale); -#endif // STBI_NO_LINEAR - -// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR -STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); -STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); -#ifndef STBI_NO_STDIO -STBIDEF int stbi_is_hdr (char const *filename); -STBIDEF int stbi_is_hdr_from_file(FILE *f); -#endif // STBI_NO_STDIO - - -// get a VERY brief reason for failure -// NOT THREADSAFE -STBIDEF const char *stbi_failure_reason (void); - -// free the loaded image -- this is just free() -STBIDEF void stbi_image_free (void *retval_from_stbi_load); - -// get image dimensions & components without fully decoding -STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); -STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); -STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len); -STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user); - -#ifndef STBI_NO_STDIO -STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp); -STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); -STBIDEF int stbi_is_16_bit (char const *filename); -STBIDEF int stbi_is_16_bit_from_file(FILE *f); -#endif - - - -// for image formats that explicitly notate that they have premultiplied alpha, -// we just return the colors as stored in the file. set this flag to force -// unpremultiplication. results are undefined if the unpremultiply overflow. -STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); - -// indicate whether we should process iphone images back to canonical format, -// or just pass them through "as-is" -STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); - -// flip the image vertically, so the first pixel in the output array is the bottom left -STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); - -// ZLIB client - used by PNG, available for other purposes - -STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); -STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header); -STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); -STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); - -STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); -STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); - - -#ifdef __cplusplus -} -#endif - -// -// -//// end header file ///////////////////////////////////////////////////// -#endif // STBI_INCLUDE_STB_IMAGE_H - -#ifdef STB_IMAGE_IMPLEMENTATION - -#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \ - || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \ - || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \ - || defined(STBI_ONLY_ZLIB) - #ifndef STBI_ONLY_JPEG - #define STBI_NO_JPEG - #endif - #ifndef STBI_ONLY_PNG - #define STBI_NO_PNG - #endif - #ifndef STBI_ONLY_BMP - #define STBI_NO_BMP - #endif - #ifndef STBI_ONLY_PSD - #define STBI_NO_PSD - #endif - #ifndef STBI_ONLY_TGA - #define STBI_NO_TGA - #endif - #ifndef STBI_ONLY_GIF - #define STBI_NO_GIF - #endif - #ifndef STBI_ONLY_HDR - #define STBI_NO_HDR - #endif - #ifndef STBI_ONLY_PIC - #define STBI_NO_PIC - #endif - #ifndef STBI_ONLY_PNM - #define STBI_NO_PNM - #endif -#endif - -#if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB) -#define STBI_NO_ZLIB -#endif - - -#include -#include // ptrdiff_t on osx -#include -#include -#include - -#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) -#include // ldexp, pow -#endif - -#ifndef STBI_NO_STDIO -#include -#endif - -#ifndef STBI_ASSERT -#include -#define STBI_ASSERT(x) assert(x) -#endif - - -#ifndef _MSC_VER - #ifdef __cplusplus - #define stbi_inline inline - #else - #define stbi_inline - #endif -#else - #define stbi_inline __forceinline -#endif - - -#ifdef _MSC_VER -typedef unsigned short stbi__uint16; -typedef signed short stbi__int16; -typedef unsigned int stbi__uint32; -typedef signed int stbi__int32; -#else -#include -typedef uint16_t stbi__uint16; -typedef int16_t stbi__int16; -typedef uint32_t stbi__uint32; -typedef int32_t stbi__int32; -#endif - -// should produce compiler error if size is wrong -typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; - -#ifdef _MSC_VER -#define STBI_NOTUSED(v) (void)(v) -#else -#define STBI_NOTUSED(v) (void)sizeof(v) -#endif - -#ifdef _MSC_VER -#define STBI_HAS_LROTL -#endif - -#ifdef STBI_HAS_LROTL - #define stbi_lrot(x,y) _lrotl(x,y) -#else - #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) -#endif - -#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) -// ok -#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED) -// ok -#else -#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)." -#endif - -#ifndef STBI_MALLOC -#define STBI_MALLOC(sz) malloc(sz) -#define STBI_REALLOC(p,newsz) realloc(p,newsz) -#define STBI_FREE(p) free(p) -#endif - -#ifndef STBI_REALLOC_SIZED -#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz) -#endif - -// x86/x64 detection -#if defined(__x86_64__) || defined(_M_X64) -#define STBI__X64_TARGET -#elif defined(__i386) || defined(_M_IX86) -#define STBI__X86_TARGET -#endif - -#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) -// gcc doesn't support sse2 intrinsics unless you compile with -msse2, -// which in turn means it gets to use SSE2 everywhere. This is unfortunate, -// but previous attempts to provide the SSE2 functions with runtime -// detection caused numerous issues. The way architecture extensions are -// exposed in GCC/Clang is, sadly, not really suited for one-file libs. -// New behavior: if compiled with -msse2, we use SSE2 without any -// detection; if not, we don't use it at all. -#define STBI_NO_SIMD -#endif - -#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD) -// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET -// -// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the -// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant. -// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not -// simultaneously enabling "-mstackrealign". -// -// See https://github.com/nothings/stb/issues/81 for more information. -// -// So default to no SSE2 on 32-bit MinGW. If you've read this far and added -// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2. -#define STBI_NO_SIMD -#endif - -#if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) -#define STBI_SSE2 -#include - -#ifdef _MSC_VER - -#if _MSC_VER >= 1400 // not VC6 -#include // __cpuid -static int stbi__cpuid3(void) -{ - int info[4]; - __cpuid(info,1); - return info[3]; -} -#else -static int stbi__cpuid3(void) -{ - int res; - __asm { - mov eax,1 - cpuid - mov res,edx - } - return res; -} -#endif - -#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name - -static int stbi__sse2_available(void) -{ - int info3 = stbi__cpuid3(); - return ((info3 >> 26) & 1) != 0; -} -#else // assume GCC-style if not VC++ -#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) - -static int stbi__sse2_available(void) -{ - // If we're even attempting to compile this on GCC/Clang, that means - // -msse2 is on, which means the compiler is allowed to use SSE2 - // instructions at will, and so are we. - return 1; -} -#endif -#endif - -// ARM NEON -#if defined(STBI_NO_SIMD) && defined(STBI_NEON) -#undef STBI_NEON -#endif - -#ifdef STBI_NEON -#include -// assume GCC or Clang on ARM targets -#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) -#endif - -#ifndef STBI_SIMD_ALIGN -#define STBI_SIMD_ALIGN(type, name) type name -#endif - -/////////////////////////////////////////////// -// -// stbi__context struct and start_xxx functions - -// stbi__context structure is our basic context used by all images, so it -// contains all the IO context, plus some basic image information -typedef struct -{ - stbi__uint32 img_x, img_y; - int img_n, img_out_n; - - stbi_io_callbacks io; - void *io_user_data; - - int read_from_callbacks; - int buflen; - stbi_uc buffer_start[128]; - - stbi_uc *img_buffer, *img_buffer_end; - stbi_uc *img_buffer_original, *img_buffer_original_end; -} stbi__context; - - -static void stbi__refill_buffer(stbi__context *s); - -// initialize a memory-decode context -static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len) -{ - s->io.read = NULL; - s->read_from_callbacks = 0; - s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer; - s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len; -} - -// initialize a callback-based context -static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *user) -{ - s->io = *c; - s->io_user_data = user; - s->buflen = sizeof(s->buffer_start); - s->read_from_callbacks = 1; - s->img_buffer_original = s->buffer_start; - stbi__refill_buffer(s); - s->img_buffer_original_end = s->img_buffer_end; -} - -// this is not threadsafe -static const char *stbi__g_failure_reason; - -STBIDEF const char *stbi_failure_reason(void) -{ - return stbi__g_failure_reason; -} - -static int stbi__err(const char *str) -{ - stbi__g_failure_reason = str; - return 0; -} - -static void *stbi__malloc(size_t size) -{ - return STBI_MALLOC(size); -} - - -#ifndef STBI_NO_STDIO - -static int stbi__stdio_read(void *user, char *data, int size) -{ - return (int) fread(data,1,size,(FILE*) user); -} - -static void stbi__stdio_skip(void *user, int n) -{ - if (fseek((FILE*) user, n, SEEK_CUR) == -1) - stbi__err("fseek() error"); -} - -static int stbi__stdio_eof(void *user) -{ - return feof((FILE*) user); -} - -static stbi_io_callbacks stbi__stdio_callbacks = -{ - stbi__stdio_read, - stbi__stdio_skip, - stbi__stdio_eof, -}; - -static void stbi__start_file(stbi__context *s, FILE *f) -{ - stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f); -} - -//static void stop_file(stbi__context *s) { } - -#endif // !STBI_NO_STDIO - -static void stbi__rewind(stbi__context *s) -{ - // conceptually rewind SHOULD rewind to the beginning of the stream, - // but we just rewind to the beginning of the initial buffer, because - // we only use it after doing 'test', which only ever looks at at most 92 bytes - s->img_buffer = s->img_buffer_original; - s->img_buffer_end = s->img_buffer_original_end; -} - -enum -{ - STBI_ORDER_RGB, - STBI_ORDER_BGR -}; - -typedef struct -{ - int bits_per_channel; - int num_channels; - int channel_order; -} stbi__result_info; - -#ifndef STBI_NO_JPEG -static int stbi__jpeg_test(stbi__context *s); -static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_PNG -static int stbi__png_test(stbi__context *s); -static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp); -static int stbi__png_is16(stbi__context *s); -#endif - -#ifndef STBI_NO_BMP -static int stbi__bmp_test(stbi__context *s); -static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_TGA -static int stbi__tga_test(stbi__context *s); -static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_PSD -static int stbi__psd_test(stbi__context *s); -static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc); -static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp); -static int stbi__psd_is16(stbi__context *s); -#endif - -#ifndef STBI_NO_HDR -static int stbi__hdr_test(stbi__context *s); -static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_PIC -static int stbi__pic_test(stbi__context *s); -static void *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_GIF -static int stbi__gif_test(stbi__context *s); -static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp); -static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -#ifndef STBI_NO_PNM -static int stbi__pnm_test(stbi__context *s); -static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); -static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); -#endif - -// stb_image uses ints pervasively, including for offset calculations. -// therefore the largest decoded image size we can support with the -// current code, even on 64-bit targets, is INT_MAX. this is not a -// significant limitation for the intended use case. -// -// we do, however, need to make sure our size calculations don't -// overflow. hence a few helper functions for size calculations that -// multiply integers together, making sure that they're non-negative -// and no overflow occurs. - -// return 1 if the sum is valid, 0 on overflow. -// negative terms are considered invalid. -static int stbi__addsizes_valid(int a, int b) -{ - if (b < 0) return 0; - // now 0 <= b <= INT_MAX, hence also - // 0 <= INT_MAX - b <= INTMAX. - // And "a + b <= INT_MAX" (which might overflow) is the - // same as a <= INT_MAX - b (no overflow) - return a <= INT_MAX - b; -} - -// returns 1 if the product is valid, 0 on overflow. -// negative factors are considered invalid. -static int stbi__mul2sizes_valid(int a, int b) -{ - if (a < 0 || b < 0) return 0; - if (b == 0) return 1; // mul-by-0 is always safe - // portable way to check for no overflows in a*b - return a <= INT_MAX/b; -} - -// returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow -static int stbi__mad2sizes_valid(int a, int b, int add) -{ - return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add); -} - -// returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow -static int stbi__mad3sizes_valid(int a, int b, int c, int add) -{ - return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && - stbi__addsizes_valid(a*b*c, add); -} - -// returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow -#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) -static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) -{ - return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && - stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add); -} -#endif - -// mallocs with size overflow checking -static void *stbi__malloc_mad2(int a, int b, int add) -{ - if (!stbi__mad2sizes_valid(a, b, add)) return NULL; - return stbi__malloc(a*b + add); -} - -static void *stbi__malloc_mad3(int a, int b, int c, int add) -{ - if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; - return stbi__malloc(a*b*c + add); -} - -#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) -static void *stbi__malloc_mad4(int a, int b, int c, int d, int add) -{ - if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; - return stbi__malloc(a*b*c*d + add); -} -#endif - -// stbi__err - error -// stbi__errpf - error returning pointer to float -// stbi__errpuc - error returning pointer to unsigned char - -#ifdef STBI_NO_FAILURE_STRINGS - #define stbi__err(x,y) 0 -#elif defined(STBI_FAILURE_USERMSG) - #define stbi__err(x,y) stbi__err(y) -#else - #define stbi__err(x,y) stbi__err(x) -#endif - -#define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL)) -#define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL)) - -STBIDEF void stbi_image_free(void *retval_from_stbi_load) -{ - STBI_FREE(retval_from_stbi_load); -} - -#ifndef STBI_NO_LINEAR -static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp); -#endif - -#ifndef STBI_NO_HDR -static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp); -#endif - -static int stbi__vertically_flip_on_load = 0; - -STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) -{ - stbi__vertically_flip_on_load = flag_true_if_should_flip; -} - -static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int /*bpc*/) -{ - memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields - ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed - ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order - ri->num_channels = 0; - - #ifndef STBI_NO_JPEG - if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri); - #endif - #ifndef STBI_NO_PNG - if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri); - #endif - #ifndef STBI_NO_BMP - if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp, ri); - #endif - #ifndef STBI_NO_GIF - if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp, ri); - #endif - #ifndef STBI_NO_PSD - if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc); - #endif - #ifndef STBI_NO_PIC - if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri); - #endif - #ifndef STBI_NO_PNM - if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri); - #endif - - #ifndef STBI_NO_HDR - if (stbi__hdr_test(s)) { - float *hdr = stbi__hdr_load(s, x,y,comp,req_comp, ri); - return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); - } - #endif - - #ifndef STBI_NO_TGA - // test tga last because it's a crappy test! - if (stbi__tga_test(s)) - return stbi__tga_load(s,x,y,comp,req_comp, ri); - #endif - - return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); -} - -static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int channels) -{ - int i; - int img_len = w * h * channels; - stbi_uc *reduced; - - reduced = (stbi_uc *) stbi__malloc(img_len); - if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory"); - - for (i = 0; i < img_len; ++i) - reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling - - STBI_FREE(orig); - return reduced; -} - -static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int channels) -{ - int i; - int img_len = w * h * channels; - stbi__uint16 *enlarged; - - enlarged = (stbi__uint16 *) stbi__malloc(img_len*2); - if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); - - for (i = 0; i < img_len; ++i) - enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff - - STBI_FREE(orig); - return enlarged; -} - -static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel) -{ - int row; - size_t bytes_per_row = (size_t)w * bytes_per_pixel; - stbi_uc temp[2048]; - stbi_uc *bytes = (stbi_uc *)image; - - for (row = 0; row < (h>>1); row++) { - stbi_uc *row0 = bytes + row*bytes_per_row; - stbi_uc *row1 = bytes + (h - row - 1)*bytes_per_row; - // swap row0 with row1 - size_t bytes_left = bytes_per_row; - while (bytes_left) { - size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp); - memcpy(temp, row0, bytes_copy); - memcpy(row0, row1, bytes_copy); - memcpy(row1, temp, bytes_copy); - row0 += bytes_copy; - row1 += bytes_copy; - bytes_left -= bytes_copy; - } - } -} - -#ifndef STBI_NO_GIF -static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel) -{ - int slice; - int slice_size = w * h * bytes_per_pixel; - - stbi_uc *bytes = (stbi_uc *)image; - for (slice = 0; slice < z; ++slice) { - stbi__vertical_flip(bytes, w, h, bytes_per_pixel); - bytes += slice_size; - } -} -#endif - -static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) -{ - stbi__result_info ri; - void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8); - - if (result == NULL) - return NULL; - - if (ri.bits_per_channel != 8) { - STBI_ASSERT(ri.bits_per_channel == 16); - result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp); - ri.bits_per_channel = 8; - } - - // @TODO: move stbi__convert_format to here - - if (stbi__vertically_flip_on_load) { - int channels = req_comp ? req_comp : *comp; - stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc)); - } - - return (unsigned char *) result; -} - -static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) -{ - stbi__result_info ri; - void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16); - - if (result == NULL) - return NULL; - - if (ri.bits_per_channel != 16) { - STBI_ASSERT(ri.bits_per_channel == 8); - result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp); - ri.bits_per_channel = 16; - } - - // @TODO: move stbi__convert_format16 to here - // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision - - if (stbi__vertically_flip_on_load) { - int channels = req_comp ? req_comp : *comp; - stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16)); - } - - return (stbi__uint16 *) result; -} - -#if !defined(STBI_NO_HDR) || !defined(STBI_NO_LINEAR) -static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) -{ - if (stbi__vertically_flip_on_load && result != NULL) { - int channels = req_comp ? req_comp : *comp; - stbi__vertical_flip(result, *x, *y, channels * sizeof(float)); - } -} -#endif - -#ifndef STBI_NO_STDIO - -static FILE *stbi__fopen(char const *filename, char const *mode) -{ - FILE *f; -#if defined(_MSC_VER) - DWORD cch = - MultiByteToWideChar(CP_UTF8, 0, filename, -1, nullptr, 0); - wchar_t *filenameU = new wchar_t[cch]; - if(!filenameU) - { - return 0; - } - MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameU, cch); - cch = MultiByteToWideChar(CP_UTF8, 0, mode, -1, nullptr, 0); - wchar_t *modeU = new wchar_t[cch]; - if(!modeU) - { - delete[] filenameU; - return 0; - } - MultiByteToWideChar(CP_UTF8, 0, mode, -1, modeU, cch); -#if _MSC_VER >= 1400 - if(0 != _wfopen_s(&f, filenameU, modeU)) - f = 0; - delete[] filenameU; - delete[] modeU; -#else // _MSC_VER >= 1400 - f = _wfopen(filenameU, modeU); - delete[] filenameU; - delete[] modeU; -#endif // _MSC_VER >= 1400 -#else // _MSC_VER - f = fopen(filename, mode); -#endif //_MSC_VER - return f; -} - - -STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) -{ - FILE *f = stbi__fopen(filename, "rb"); - unsigned char *result; - if (!f) return stbi__errpuc("can't fopen", "Unable to open file"); - result = stbi_load_from_file(f,x,y,comp,req_comp); - fclose(f); - return result; -} - -STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) -{ - unsigned char *result; - stbi__context s; - stbi__start_file(&s,f); - result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); - if (result) { - // need to 'unget' all the characters in the IO buffer - if (fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR) == -1) { - stbi_image_free(result); - return stbi__errpuc("fseek() error", "File Seek Fail"); - } - } - return result; -} - -STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, int req_comp) -{ - stbi__uint16 *result; - stbi__context s; - stbi__start_file(&s,f); - result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp); - if (result) { - // need to 'unget' all the characters in the IO buffer - if (fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR) == -1) { - stbi_image_free(result); - return (stbi__uint16 *) stbi__errpuc("fseek() error", "File Seek Fail"); - } - } - return result; -} - -STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, int req_comp) -{ - FILE *f = stbi__fopen(filename, "rb"); - stbi__uint16 *result; - if (!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file"); - result = stbi_load_from_file_16(f,x,y,comp,req_comp); - fclose(f); - return result; -} - - -#endif //!STBI_NO_STDIO - -STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels) -{ - stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); -} - -STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user); - return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); -} - -STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) -{ - stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); -} - -STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); - return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); -} - -#ifndef STBI_NO_GIF -STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp) -{ - unsigned char *result; - stbi__context s; - stbi__start_mem(&s,buffer,len); - - result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp); - if (stbi__vertically_flip_on_load) { - stbi__vertical_flip_slices( result, *x, *y, *z, *comp ); - } - - return result; -} -#endif - -#ifndef STBI_NO_LINEAR -static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) -{ - unsigned char *data; - #ifndef STBI_NO_HDR - if (stbi__hdr_test(s)) { - stbi__result_info ri; - float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp, &ri); - if (hdr_data) - stbi__float_postprocess(hdr_data,x,y,comp,req_comp); - return hdr_data; - } - #endif - data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp); - if (data) - return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); - return stbi__errpf("unknown image type", "Image not of any known type, or corrupt"); -} - -STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) -{ - stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__loadf_main(&s,x,y,comp,req_comp); -} - -STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); - return stbi__loadf_main(&s,x,y,comp,req_comp); -} - -#ifndef STBI_NO_STDIO -STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) -{ - float *result; - FILE *f = stbi__fopen(filename, "rb"); - if (!f) return stbi__errpf("can't fopen", "Unable to open file"); - result = stbi_loadf_from_file(f,x,y,comp,req_comp); - fclose(f); - return result; -} - -STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) -{ - stbi__context s; - stbi__start_file(&s,f); - return stbi__loadf_main(&s,x,y,comp,req_comp); -} -#endif // !STBI_NO_STDIO - -#endif // !STBI_NO_LINEAR - -// these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is -// defined, for API simplicity; if STBI_NO_LINEAR is defined, it always -// reports false! - -STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) -{ - #ifndef STBI_NO_HDR - stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__hdr_test(&s); - #else - STBI_NOTUSED(buffer); - STBI_NOTUSED(len); - return 0; - #endif -} - -#ifndef STBI_NO_STDIO -STBIDEF int stbi_is_hdr (char const *filename) -{ - FILE *f = stbi__fopen(filename, "rb"); - int result=0; - if (f) { - result = stbi_is_hdr_from_file(f); - fclose(f); - } - return result; -} - -STBIDEF int stbi_is_hdr_from_file(FILE *f) -{ - #ifndef STBI_NO_HDR - long pos = ftell(f); - int res; - stbi__context s; - stbi__start_file(&s,f); - res = stbi__hdr_test(&s); - if (fseek(f, pos, SEEK_SET) == -1) return stbi__err("fseek() error", "File Seek Fail"); - return res; - #else - STBI_NOTUSED(f); - return 0; - #endif -} -#endif // !STBI_NO_STDIO - -STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) -{ - #ifndef STBI_NO_HDR - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); - return stbi__hdr_test(&s); - #else - STBI_NOTUSED(clbk); - STBI_NOTUSED(user); - return 0; - #endif -} - -#ifndef STBI_NO_LINEAR -static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f; - -STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; } -STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } -#endif - -static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f; - -STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; } -STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; } - - -////////////////////////////////////////////////////////////////////////////// -// -// Common code used by all image loaders -// - -enum -{ - STBI__SCAN_load=0, - STBI__SCAN_type, - STBI__SCAN_header -}; - -static void stbi__refill_buffer(stbi__context *s) -{ - int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); - if (n == 0) { - // at end of file, treat same as if from memory, but need to handle case - // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file - s->read_from_callbacks = 0; - s->img_buffer = s->buffer_start; - s->img_buffer_end = s->buffer_start+1; - *s->img_buffer = 0; - } else { - s->img_buffer = s->buffer_start; - s->img_buffer_end = s->buffer_start + n; - } -} - -stbi_inline static stbi_uc stbi__get8(stbi__context *s) -{ - if (s->img_buffer < s->img_buffer_end) - return *s->img_buffer++; - if (s->read_from_callbacks) { - stbi__refill_buffer(s); - return *s->img_buffer++; - } - return 0; -} - -stbi_inline static int stbi__at_eof(stbi__context *s) -{ - if (s->io.read) { - if (!(s->io.eof)(s->io_user_data)) return 0; - // if feof() is true, check if buffer = end - // special case: we've only got the special 0 character at the end - if (s->read_from_callbacks == 0) return 1; - } - - return s->img_buffer >= s->img_buffer_end; -} - -static void stbi__skip(stbi__context *s, int n) -{ - if (n < 0) { - s->img_buffer = s->img_buffer_end; - return; - } - if (s->io.read) { - int blen = (int) (s->img_buffer_end - s->img_buffer); - if (blen < n) { - s->img_buffer = s->img_buffer_end; - (s->io.skip)(s->io_user_data, n - blen); - return; - } - } - s->img_buffer += n; -} - -static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n) -{ - if (s->io.read) { - int blen = (int) (s->img_buffer_end - s->img_buffer); - if (blen < n) { - int res, count; - - memcpy(buffer, s->img_buffer, blen); - - count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); - res = (count == (n-blen)); - s->img_buffer = s->img_buffer_end; - return res; - } - } - - if (s->img_buffer+n <= s->img_buffer_end) { - memcpy(buffer, s->img_buffer, n); - s->img_buffer += n; - return 1; - } else - return 0; -} - -static int stbi__get16be(stbi__context *s) -{ - int z = stbi__get8(s); - return (z << 8) + stbi__get8(s); -} - -static stbi__uint32 stbi__get32be(stbi__context *s) -{ - stbi__uint32 z = stbi__get16be(s); - return (z << 16) + stbi__get16be(s); -} - -#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) -// nothing -#else -static int stbi__get16le(stbi__context *s) -{ - int z = stbi__get8(s); - return z + (stbi__get8(s) << 8); -} -#endif - -#ifndef STBI_NO_BMP -static stbi__uint32 stbi__get32le(stbi__context *s) -{ - stbi__uint32 z = stbi__get16le(s); - return z + (stbi__get16le(s) << 16); -} -#endif - -#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings - - -////////////////////////////////////////////////////////////////////////////// -// -// generic converter from built-in img_n to req_comp -// individual types do this automatically as much as possible (e.g. jpeg -// does all cases internally since it needs to colorspace convert anyway, -// and it never has alpha, so very few cases ). png can automatically -// interleave an alpha=255 channel, but falls back to this for other cases -// -// assume data buffer is malloced, so malloc a new one and free that one -// only failure mode is malloc failing - -static stbi_uc stbi__compute_y(int r, int g, int b) -{ - return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8); -} - -static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y) -{ - int i,j; - unsigned char *good; - - if (req_comp == img_n) return data; - STBI_ASSERT(req_comp >= 1 && req_comp <= 4); - - good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0); - if (good == NULL) { - STBI_FREE(data); - return stbi__errpuc("outofmem", "Out of memory"); - } - - for (j=0; j < (int) y; ++j) { - unsigned char *src = data + j * x * img_n ; - unsigned char *dest = good + j * x * req_comp; - - #define STBI__COMBO(a,b) ((a)*8+(b)) - #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) - // convert source image with img_n components to one with req_comp components; - // avoid switch per pixel, so use switch per scanline and massive macros - switch (STBI__COMBO(img_n, req_comp)) { - STBI__CASE(1,2) { dest[0]=src[0], dest[1]=255; } break; - STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; } break; - STBI__CASE(2,1) { dest[0]=src[0]; } break; - STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break; - STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; } break; - STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; - STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255; } break; - STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; - STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; } break; - STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break; - default: STBI_ASSERT(0); - } - #undef STBI__CASE - } - - STBI_FREE(data); - return good; -} - -static stbi__uint16 stbi__compute_y_16(int r, int g, int b) -{ - return (stbi__uint16) (((r*77) + (g*150) + (29*b)) >> 8); -} - -static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y) -{ - int i,j; - stbi__uint16 *good; - - if (req_comp == img_n) return data; - STBI_ASSERT(req_comp >= 1 && req_comp <= 4); - - good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2); - if (good == NULL) { - STBI_FREE(data); - return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); - } - - for (j=0; j < (int) y; ++j) { - stbi__uint16 *src = data + j * x * img_n ; - stbi__uint16 *dest = good + j * x * req_comp; - - #define STBI__COMBO(a,b) ((a)*8+(b)) - #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) - // convert source image with img_n components to one with req_comp components; - // avoid switch per pixel, so use switch per scanline and massive macros - switch (STBI__COMBO(img_n, req_comp)) { - STBI__CASE(1,2) { dest[0]=src[0], dest[1]=0xffff; } break; - STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=0xffff; } break; - STBI__CASE(2,1) { dest[0]=src[0]; } break; - STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break; - STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=0xffff; } break; - STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; - STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = 0xffff; } break; - STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; - STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = src[3]; } break; - STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break; - default: STBI_ASSERT(0); - } - #undef STBI__CASE - } - - STBI_FREE(data); - return good; -} - -#ifndef STBI_NO_LINEAR -static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) -{ - int i,k,n; - float *output; - if (!data) return NULL; - output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0); - if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } - // compute number of non-alpha components - if (comp & 1) n = comp; else n = comp-1; - for (i=0; i < x*y; ++i) { - for (k=0; k < n; ++k) { - output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale); - } - if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f; - } - STBI_FREE(data); - return output; -} -#endif - -#ifndef STBI_NO_HDR -#define stbi__float2int(x) ((int) (x)) -static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) -{ - int i,k,n; - stbi_uc *output; - if (!data) return NULL; - output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0); - if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } - // compute number of non-alpha components - if (comp & 1) n = comp; else n = comp-1; - for (i=0; i < x*y; ++i) { - for (k=0; k < n; ++k) { - float z = (float) pow(data[i*comp+k]*stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; - if (z < 0) z = 0; - if (z > 255) z = 255; - output[i*comp + k] = (stbi_uc) stbi__float2int(z); - } - if (k < comp) { - float z = data[i*comp+k] * 255 + 0.5f; - if (z < 0) z = 0; - if (z > 255) z = 255; - output[i*comp + k] = (stbi_uc) stbi__float2int(z); - } - } - STBI_FREE(data); - return output; -} -#endif - -////////////////////////////////////////////////////////////////////////////// -// -// "baseline" JPEG/JFIF decoder -// -// simple implementation -// - doesn't support delayed output of y-dimension -// - simple interface (only one output format: 8-bit interleaved RGB) -// - doesn't try to recover corrupt jpegs -// - doesn't allow partial loading, loading multiple at once -// - still fast on x86 (copying globals into locals doesn't help x86) -// - allocates lots of intermediate memory (full size of all components) -// - non-interleaved case requires this anyway -// - allows good upsampling (see next) -// high-quality -// - upsampled channels are bilinearly interpolated, even across blocks -// - quality integer IDCT derived from IJG's 'slow' -// performance -// - fast huffman; reasonable integer IDCT -// - some SIMD kernels for common paths on targets with SSE2/NEON -// - uses a lot of intermediate memory, could cache poorly - -#ifndef STBI_NO_JPEG - -// huffman decoding acceleration -#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache - -typedef struct -{ - stbi_uc fast[1 << FAST_BITS]; - // weirdly, repacking this into AoS is a 10% speed loss, instead of a win - stbi__uint16 code[256]; - stbi_uc values[256]; - stbi_uc size[257]; - unsigned int maxcode[18]; - int delta[17]; // old 'firstsymbol' - old 'firstcode' -} stbi__huffman; - -typedef struct -{ - stbi__context *s; - stbi__huffman huff_dc[4]; - stbi__huffman huff_ac[4]; - stbi__uint16 dequant[4][64]; - stbi__int16 fast_ac[4][1 << FAST_BITS]; - -// sizes for components, interleaved MCUs - int img_h_max, img_v_max; - int img_mcu_x, img_mcu_y; - int img_mcu_w, img_mcu_h; - -// definition of jpeg image component - struct - { - int id; - int h,v; - int tq; - int hd,ha; - int dc_pred; - - int x,y,w2,h2; - stbi_uc *data; - void *raw_data, *raw_coeff; - stbi_uc *linebuf; - short *coeff; // progressive only - int coeff_w, coeff_h; // number of 8x8 coefficient blocks - } img_comp[4]; - - stbi__uint32 code_buffer; // jpeg entropy-coded buffer - int code_bits; // number of valid bits - unsigned char marker; // marker seen while filling entropy buffer - int nomore; // flag if we saw a marker so must stop - - int progressive; - int spec_start; - int spec_end; - int succ_high; - int succ_low; - int eob_run; - int jfif; - int app14_color_transform; // Adobe APP14 tag - int rgb; - - int scan_n, order[4]; - int restart_interval, todo; - -// kernels - void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]); - void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step); - stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs); -} stbi__jpeg; - -static int stbi__build_huffman(stbi__huffman *h, int *count) -{ - int i,j,k=0; - unsigned int code; - // build size list for each symbol (from JPEG spec) - for (i=0; i < 16; ++i) - for (j=0; j < count[i]; ++j) - h->size[k++] = (stbi_uc) (i+1); - h->size[k] = 0; - - // compute actual symbols (from jpeg spec) - code = 0; - k = 0; - for(j=1; j <= 16; ++j) { - // compute delta to add to code to compute symbol id - h->delta[j] = k - code; - if (h->size[k] == j) { - while (h->size[k] == j) - h->code[k++] = (stbi__uint16) (code++); - if (code-1 >= (1u << j)) return stbi__err("bad code lengths","Corrupt JPEG"); - } - // compute largest code + 1 for this size, preshifted as needed later - h->maxcode[j] = code << (16-j); - code <<= 1; - } - h->maxcode[j] = 0xffffffff; - - // build non-spec acceleration table; 255 is flag for not-accelerated - memset(h->fast, 255, 1 << FAST_BITS); - for (i=0; i < k; ++i) { - int s = h->size[i]; - if (s <= FAST_BITS) { - int c = h->code[i] << (FAST_BITS-s); - int m = 1 << (FAST_BITS-s); - for (j=0; j < m; ++j) { - h->fast[c+j] = (stbi_uc) i; - } - } - } - return 1; -} - -// build a table that decodes both magnitude and value of small ACs in -// one go. -static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h) -{ - int i; - for (i=0; i < (1 << FAST_BITS); ++i) { - stbi_uc fast = h->fast[i]; - fast_ac[i] = 0; - if (fast < 255) { - int rs = h->values[fast]; - int run = (rs >> 4) & 15; - int magbits = rs & 15; - int len = h->size[fast]; - - if (magbits && len + magbits <= FAST_BITS) { - // magnitude code followed by receive_extend code - int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); - int m = 1 << (magbits - 1); - if (k < m) k += (~0U << magbits) + 1; - // if the result is small enough, we can fit it in fast_ac table - if (k >= -128 && k <= 127) - fast_ac[i] = (stbi__int16) ((k * 256) + (run * 16) + (len + magbits)); - } - } - } -} - -static void stbi__grow_buffer_unsafe(stbi__jpeg *j) -{ - do { - unsigned int b = j->nomore ? 0 : stbi__get8(j->s); - if (b == 0xff) { - int c = stbi__get8(j->s); - while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes - if (c != 0) { - j->marker = (unsigned char) c; - j->nomore = 1; - return; - } - } - j->code_buffer |= b << (24 - j->code_bits); - j->code_bits += 8; - } while (j->code_bits <= 24); -} - -// (1 << n) - 1 -static const stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; - -// decode a jpeg huffman value from the bitstream -stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) -{ - unsigned int temp; - int c,k; - - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - - // look at the top FAST_BITS and determine what symbol ID it is, - // if the code is <= FAST_BITS - c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); - k = h->fast[c]; - if (k < 255) { - int s = h->size[k]; - if (s > j->code_bits) - return -1; - j->code_buffer <<= s; - j->code_bits -= s; - return h->values[k]; - } - - // naive test is to shift the code_buffer down so k bits are - // valid, then test against maxcode. To speed this up, we've - // preshifted maxcode left so that it has (16-k) 0s at the - // end; in other words, regardless of the number of bits, it - // wants to be compared against something shifted to have 16; - // that way we don't need to shift inside the loop. - temp = j->code_buffer >> 16; - for (k=FAST_BITS+1 ; ; ++k) - if (temp < h->maxcode[k]) - break; - if (k == 17) { - // error! code not found - j->code_bits -= 16; - return -1; - } - - if (k > j->code_bits) - return -1; - - // convert the huffman code to the symbol id - c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; - STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); - - // convert the id to a symbol - j->code_bits -= k; - j->code_buffer <<= k; - return h->values[c]; -} - -// bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); - - sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB - k = stbi_lrot(j->code_buffer, n); - STBI_ASSERT(n >= 0 && n < (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask))); - j->code_buffer = k & ~stbi__bmask[n]; - k &= stbi__bmask[n]; - j->code_bits -= n; - return k + (stbi__jbias[n] & ~sgn); -} - -// get some unsigned bits -stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n) -{ - unsigned int k; - if (j->code_bits < n) stbi__grow_buffer_unsafe(j); - k = stbi_lrot(j->code_buffer, n); - j->code_buffer = k & ~stbi__bmask[n]; - k &= stbi__bmask[n]; - j->code_bits -= n; - return k; -} - -stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j) -{ - unsigned int k; - if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); - k = j->code_buffer; - j->code_buffer <<= 1; - --j->code_bits; - return k & 0x80000000; -} - -// given a value that's at position X in the zigzag stream, -// where does it appear in the 8x8 matrix coded as row-major? -static const stbi_uc stbi__jpeg_dezigzag[64+15] = -{ - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63, - // let corrupt input sample past end - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63 -}; - -// decode one 64-entry block-- -static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant) -{ - int diff,dc,k; - int t; - - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - t = stbi__jpeg_huff_decode(j, hdc); - if (t < 0) return stbi__err("bad huffman code","Corrupt JPEG"); - - // 0 all the ac values now so we can do it 32-bits at a time - memset(data,0,64*sizeof(data[0])); - - diff = t ? stbi__extend_receive(j, t) : 0; - dc = j->img_comp[b].dc_pred + diff; - j->img_comp[b].dc_pred = dc; - data[0] = (short) (dc * dequant[0]); - - // decode AC components, see JPEG spec - k = 1; - do { - unsigned int zig; - int c,r,s; - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); - r = fac[c]; - if (r) { // fast-AC path - k += (r >> 4) & 15; // run - s = r & 15; // combined length - j->code_buffer <<= s; - j->code_bits -= s; - // decode into unzigzag'd location - zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short) ((r >> 8) * dequant[zig]); - } else { - int rs = stbi__jpeg_huff_decode(j, hac); - if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); - s = rs & 15; - r = rs >> 4; - if (s == 0) { - if (rs != 0xf0) break; // end block - k += 16; - } else { - k += r; - // decode into unzigzag'd location - zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short) (stbi__extend_receive(j,s) * dequant[zig]); - } - } - } while (k < 64); - return 1; -} - -static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b) -{ - int diff,dc; - int t; - if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); - - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - - if (j->succ_high == 0) { - // first scan for DC coefficient, must be first - memset(data,0,64*sizeof(data[0])); // 0 all the ac values now - t = stbi__jpeg_huff_decode(j, hdc); - diff = t ? stbi__extend_receive(j, t) : 0; - - dc = j->img_comp[b].dc_pred + diff; - j->img_comp[b].dc_pred = dc; - data[0] = (short) (dc << j->succ_low); - } else { - // refinement scan for DC coefficient - if (stbi__jpeg_get_bit(j)) - data[0] += (short) (1 << j->succ_low); - } - return 1; -} - -// @OPTIMIZE: store non-zigzagged during the decode passes, -// and only de-zigzag when dequantizing -static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac) -{ - int k; - if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); - - if (j->succ_high == 0) { - int shift = j->succ_low; - - if (j->eob_run) { - --j->eob_run; - return 1; - } - - k = j->spec_start; - do { - unsigned int zig; - int c,r,s; - if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); - c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); - r = fac[c]; - if (r) { // fast-AC path - k += (r >> 4) & 15; // run - s = r & 15; // combined length - j->code_buffer <<= s; - j->code_bits -= s; - zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short) ((r >> 8) << shift); - } else { - int rs = stbi__jpeg_huff_decode(j, hac); - if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); - s = rs & 15; - r = rs >> 4; - if (s == 0) { - if (r < 15) { - j->eob_run = (1 << r); - if (r) - j->eob_run += stbi__jpeg_get_bits(j, r); - --j->eob_run; - break; - } - k += 16; - } else { - k += r; - zig = stbi__jpeg_dezigzag[k++]; - data[zig] = (short) (stbi__extend_receive(j,s) << shift); - } - } - } while (k <= j->spec_end); - } else { - // refinement scan for these AC coefficients - - short bit = (short) (1 << j->succ_low); - - if (j->eob_run) { - --j->eob_run; - for (k = j->spec_start; k <= j->spec_end; ++k) { - short *p = &data[stbi__jpeg_dezigzag[k]]; - if (*p != 0) - if (stbi__jpeg_get_bit(j)) - if ((*p & bit)==0) { - if (*p > 0) - *p += bit; - else - *p -= bit; - } - } - } else { - k = j->spec_start; - do { - int r,s; - int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh - if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); - s = rs & 15; - r = rs >> 4; - if (s == 0) { - if (r < 15) { - j->eob_run = (1 << r) - 1; - if (r) - j->eob_run += stbi__jpeg_get_bits(j, r); - r = 64; // force end of block - } else { - // r=15 s=0 should write 16 0s, so we just do - // a run of 15 0s and then write s (which is 0), - // so we don't have to do anything special here - } - } else { - if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); - // sign bit - if (stbi__jpeg_get_bit(j)) - s = bit; - else - s = -bit; - } - - // advance by r - while (k <= j->spec_end) { - short *p = &data[stbi__jpeg_dezigzag[k++]]; - if (*p != 0) { - if (stbi__jpeg_get_bit(j)) - if ((*p & bit)==0) { - if (*p > 0) - *p += bit; - else - *p -= bit; - } - } else { - if (r == 0) { - *p = (short) s; - break; - } - --r; - } - } - } while (k <= j->spec_end); - } - } - return 1; -} - -// take a -128..127 value and stbi__clamp it and convert to 0..255 -stbi_inline static stbi_uc stbi__clamp(int x) -{ - // trick to use a single test to catch both cases - if ((unsigned int) x > 255) { - if (x < 0) return 0; - if (x > 255) return 255; - } - return (stbi_uc) x; -} - -#define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) -#define stbi__fsh(x) ((x) * 4096) - -// derived from jidctint -- DCT_ISLOW -#define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ - int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ - p2 = s2; \ - p3 = s6; \ - p1 = (p2+p3) * stbi__f2f(0.5411961f); \ - t2 = p1 + p3*stbi__f2f(-1.847759065f); \ - t3 = p1 + p2*stbi__f2f( 0.765366865f); \ - p2 = s0; \ - p3 = s4; \ - t0 = stbi__fsh(p2+p3); \ - t1 = stbi__fsh(p2-p3); \ - x0 = t0+t3; \ - x3 = t0-t3; \ - x1 = t1+t2; \ - x2 = t1-t2; \ - t0 = s7; \ - t1 = s5; \ - t2 = s3; \ - t3 = s1; \ - p3 = t0+t2; \ - p4 = t1+t3; \ - p1 = t0+t3; \ - p2 = t1+t2; \ - p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ - t0 = t0*stbi__f2f( 0.298631336f); \ - t1 = t1*stbi__f2f( 2.053119869f); \ - t2 = t2*stbi__f2f( 3.072711026f); \ - t3 = t3*stbi__f2f( 1.501321110f); \ - p1 = p5 + p1*stbi__f2f(-0.899976223f); \ - p2 = p5 + p2*stbi__f2f(-2.562915447f); \ - p3 = p3*stbi__f2f(-1.961570560f); \ - p4 = p4*stbi__f2f(-0.390180644f); \ - t3 += p1+p4; \ - t2 += p2+p3; \ - t1 += p2+p4; \ - t0 += p1+p3; - -static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64]) -{ - int i,val[64],*v=val; - stbi_uc *o; - short *d = data; - - // columns - for (i=0; i < 8; ++i,++d, ++v) { - // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing - if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 - && d[40]==0 && d[48]==0 && d[56]==0) { - // no shortcut 0 seconds - // (1|2|3|4|5|6|7)==0 0 seconds - // all separate -0.047 seconds - // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds - int dcterm = d[0]*4; - v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; - } else { - STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56]) - // constants scaled things up by 1<<12; let's bring them back - // down, but keep 2 extra bits of precision - x0 += 512; x1 += 512; x2 += 512; x3 += 512; - v[ 0] = (x0+t3) >> 10; - v[56] = (x0-t3) >> 10; - v[ 8] = (x1+t2) >> 10; - v[48] = (x1-t2) >> 10; - v[16] = (x2+t1) >> 10; - v[40] = (x2-t1) >> 10; - v[24] = (x3+t0) >> 10; - v[32] = (x3-t0) >> 10; - } - } - - for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { - // no fast case since the first 1D IDCT spread components out - STBI__IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) - // constants scaled things up by 1<<12, plus we had 1<<2 from first - // loop, plus horizontal and vertical each scale by sqrt(8) so together - // we've got an extra 1<<3, so 1<<17 total we need to remove. - // so we want to round that, which means adding 0.5 * 1<<17, - // aka 65536. Also, we'll end up with -128 to 127 that we want - // to encode as 0..255 by adding 128, so we'll add that before the shift - x0 += 65536 + (128<<17); - x1 += 65536 + (128<<17); - x2 += 65536 + (128<<17); - x3 += 65536 + (128<<17); - // tried computing the shifts into temps, or'ing the temps to see - // if any were out of range, but that was slower - o[0] = stbi__clamp((x0+t3) >> 17); - o[7] = stbi__clamp((x0-t3) >> 17); - o[1] = stbi__clamp((x1+t2) >> 17); - o[6] = stbi__clamp((x1-t2) >> 17); - o[2] = stbi__clamp((x2+t1) >> 17); - o[5] = stbi__clamp((x2-t1) >> 17); - o[3] = stbi__clamp((x3+t0) >> 17); - o[4] = stbi__clamp((x3-t0) >> 17); - } -} - -#ifdef STBI_SSE2 -// sse2 integer IDCT. not the fastest possible implementation but it -// produces bit-identical results to the generic C version so it's -// fully "transparent". -static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) -{ - // This is constructed to match our regular (generic) integer IDCT exactly. - __m128i row0, row1, row2, row3, row4, row5, row6, row7; - __m128i tmp; - - // dot product constant: even elems=x, odd elems=y - #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) - - // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) - // out(1) = c1[even]*x + c1[odd]*y - #define dct_rot(out0,out1, x,y,c0,c1) \ - __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ - __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ - __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ - __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ - __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ - __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) - - // out = in << 12 (in 16-bit, out 32-bit) - #define dct_widen(out, in) \ - __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ - __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) - - // wide add - #define dct_wadd(out, a, b) \ - __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ - __m128i out##_h = _mm_add_epi32(a##_h, b##_h) - - // wide sub - #define dct_wsub(out, a, b) \ - __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ - __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) - - // butterfly a/b, add bias, then shift by "s" and pack - #define dct_bfly32o(out0, out1, a,b,bias,s) \ - { \ - __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ - __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ - dct_wadd(sum, abiased, b); \ - dct_wsub(dif, abiased, b); \ - out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ - out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ - } - - // 8-bit interleave step (for transposes) - #define dct_interleave8(a, b) \ - tmp = a; \ - a = _mm_unpacklo_epi8(a, b); \ - b = _mm_unpackhi_epi8(tmp, b) - - // 16-bit interleave step (for transposes) - #define dct_interleave16(a, b) \ - tmp = a; \ - a = _mm_unpacklo_epi16(a, b); \ - b = _mm_unpackhi_epi16(tmp, b) - - #define dct_pass(bias,shift) \ - { \ - /* even part */ \ - dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ - __m128i sum04 = _mm_add_epi16(row0, row4); \ - __m128i dif04 = _mm_sub_epi16(row0, row4); \ - dct_widen(t0e, sum04); \ - dct_widen(t1e, dif04); \ - dct_wadd(x0, t0e, t3e); \ - dct_wsub(x3, t0e, t3e); \ - dct_wadd(x1, t1e, t2e); \ - dct_wsub(x2, t1e, t2e); \ - /* odd part */ \ - dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ - dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ - __m128i sum17 = _mm_add_epi16(row1, row7); \ - __m128i sum35 = _mm_add_epi16(row3, row5); \ - dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ - dct_wadd(x4, y0o, y4o); \ - dct_wadd(x5, y1o, y5o); \ - dct_wadd(x6, y2o, y5o); \ - dct_wadd(x7, y3o, y4o); \ - dct_bfly32o(row0,row7, x0,x7,bias,shift); \ - dct_bfly32o(row1,row6, x1,x6,bias,shift); \ - dct_bfly32o(row2,row5, x2,x5,bias,shift); \ - dct_bfly32o(row3,row4, x3,x4,bias,shift); \ - } - - __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); - __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f( 0.765366865f), stbi__f2f(0.5411961f)); - __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); - __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); - __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f( 0.298631336f), stbi__f2f(-1.961570560f)); - __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f( 3.072711026f)); - __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f)); - __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f)); - - // rounding biases in column/row passes, see stbi__idct_block for explanation. - __m128i bias_0 = _mm_set1_epi32(512); - __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17)); - - // load - row0 = _mm_load_si128((const __m128i *) (data + 0*8)); - row1 = _mm_load_si128((const __m128i *) (data + 1*8)); - row2 = _mm_load_si128((const __m128i *) (data + 2*8)); - row3 = _mm_load_si128((const __m128i *) (data + 3*8)); - row4 = _mm_load_si128((const __m128i *) (data + 4*8)); - row5 = _mm_load_si128((const __m128i *) (data + 5*8)); - row6 = _mm_load_si128((const __m128i *) (data + 6*8)); - row7 = _mm_load_si128((const __m128i *) (data + 7*8)); - - // column pass - dct_pass(bias_0, 10); - - { - // 16bit 8x8 transpose pass 1 - dct_interleave16(row0, row4); - dct_interleave16(row1, row5); - dct_interleave16(row2, row6); - dct_interleave16(row3, row7); - - // transpose pass 2 - dct_interleave16(row0, row2); - dct_interleave16(row1, row3); - dct_interleave16(row4, row6); - dct_interleave16(row5, row7); - - // transpose pass 3 - dct_interleave16(row0, row1); - dct_interleave16(row2, row3); - dct_interleave16(row4, row5); - dct_interleave16(row6, row7); - } - - // row pass - dct_pass(bias_1, 17); - - { - // pack - __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 - __m128i p1 = _mm_packus_epi16(row2, row3); - __m128i p2 = _mm_packus_epi16(row4, row5); - __m128i p3 = _mm_packus_epi16(row6, row7); - - // 8bit 8x8 transpose pass 1 - dct_interleave8(p0, p2); // a0e0a1e1... - dct_interleave8(p1, p3); // c0g0c1g1... - - // transpose pass 2 - dct_interleave8(p0, p1); // a0c0e0g0... - dct_interleave8(p2, p3); // b0d0f0h0... - - // transpose pass 3 - dct_interleave8(p0, p2); // a0b0c0d0... - dct_interleave8(p1, p3); // a4b4c4d4... - - // store - _mm_storel_epi64((__m128i *) out, p0); out += out_stride; - _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; - _mm_storel_epi64((__m128i *) out, p2); out += out_stride; - _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; - _mm_storel_epi64((__m128i *) out, p1); out += out_stride; - _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; - _mm_storel_epi64((__m128i *) out, p3); out += out_stride; - _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e)); - } - -#undef dct_const -#undef dct_rot -#undef dct_widen -#undef dct_wadd -#undef dct_wsub -#undef dct_bfly32o -#undef dct_interleave8 -#undef dct_interleave16 -#undef dct_pass -} - -#endif // STBI_SSE2 - -#ifdef STBI_NEON - -// NEON integer IDCT. should produce bit-identical -// results to the generic C version. -static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) -{ - int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; - - int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); - int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); - int16x4_t rot0_2 = vdup_n_s16(stbi__f2f( 0.765366865f)); - int16x4_t rot1_0 = vdup_n_s16(stbi__f2f( 1.175875602f)); - int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); - int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); - int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); - int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); - int16x4_t rot3_0 = vdup_n_s16(stbi__f2f( 0.298631336f)); - int16x4_t rot3_1 = vdup_n_s16(stbi__f2f( 2.053119869f)); - int16x4_t rot3_2 = vdup_n_s16(stbi__f2f( 3.072711026f)); - int16x4_t rot3_3 = vdup_n_s16(stbi__f2f( 1.501321110f)); - -#define dct_long_mul(out, inq, coeff) \ - int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ - int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) - -#define dct_long_mac(out, acc, inq, coeff) \ - int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ - int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) - -#define dct_widen(out, inq) \ - int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ - int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) - -// wide add -#define dct_wadd(out, a, b) \ - int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ - int32x4_t out##_h = vaddq_s32(a##_h, b##_h) - -// wide sub -#define dct_wsub(out, a, b) \ - int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ - int32x4_t out##_h = vsubq_s32(a##_h, b##_h) - -// butterfly a/b, then shift using "shiftop" by "s" and pack -#define dct_bfly32o(out0,out1, a,b,shiftop,s) \ - { \ - dct_wadd(sum, a, b); \ - dct_wsub(dif, a, b); \ - out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ - out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ - } - -#define dct_pass(shiftop, shift) \ - { \ - /* even part */ \ - int16x8_t sum26 = vaddq_s16(row2, row6); \ - dct_long_mul(p1e, sum26, rot0_0); \ - dct_long_mac(t2e, p1e, row6, rot0_1); \ - dct_long_mac(t3e, p1e, row2, rot0_2); \ - int16x8_t sum04 = vaddq_s16(row0, row4); \ - int16x8_t dif04 = vsubq_s16(row0, row4); \ - dct_widen(t0e, sum04); \ - dct_widen(t1e, dif04); \ - dct_wadd(x0, t0e, t3e); \ - dct_wsub(x3, t0e, t3e); \ - dct_wadd(x1, t1e, t2e); \ - dct_wsub(x2, t1e, t2e); \ - /* odd part */ \ - int16x8_t sum15 = vaddq_s16(row1, row5); \ - int16x8_t sum17 = vaddq_s16(row1, row7); \ - int16x8_t sum35 = vaddq_s16(row3, row5); \ - int16x8_t sum37 = vaddq_s16(row3, row7); \ - int16x8_t sumodd = vaddq_s16(sum17, sum35); \ - dct_long_mul(p5o, sumodd, rot1_0); \ - dct_long_mac(p1o, p5o, sum17, rot1_1); \ - dct_long_mac(p2o, p5o, sum35, rot1_2); \ - dct_long_mul(p3o, sum37, rot2_0); \ - dct_long_mul(p4o, sum15, rot2_1); \ - dct_wadd(sump13o, p1o, p3o); \ - dct_wadd(sump24o, p2o, p4o); \ - dct_wadd(sump23o, p2o, p3o); \ - dct_wadd(sump14o, p1o, p4o); \ - dct_long_mac(x4, sump13o, row7, rot3_0); \ - dct_long_mac(x5, sump24o, row5, rot3_1); \ - dct_long_mac(x6, sump23o, row3, rot3_2); \ - dct_long_mac(x7, sump14o, row1, rot3_3); \ - dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ - dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ - dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ - dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ - } - - // load - row0 = vld1q_s16(data + 0*8); - row1 = vld1q_s16(data + 1*8); - row2 = vld1q_s16(data + 2*8); - row3 = vld1q_s16(data + 3*8); - row4 = vld1q_s16(data + 4*8); - row5 = vld1q_s16(data + 5*8); - row6 = vld1q_s16(data + 6*8); - row7 = vld1q_s16(data + 7*8); - - // add DC bias - row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); - - // column pass - dct_pass(vrshrn_n_s32, 10); - - // 16bit 8x8 transpose - { -// these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. -// whether compilers actually get this is another story, sadly. -#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } -#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } -#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } - - // pass 1 - dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 - dct_trn16(row2, row3); - dct_trn16(row4, row5); - dct_trn16(row6, row7); - - // pass 2 - dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 - dct_trn32(row1, row3); - dct_trn32(row4, row6); - dct_trn32(row5, row7); - - // pass 3 - dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 - dct_trn64(row1, row5); - dct_trn64(row2, row6); - dct_trn64(row3, row7); - -#undef dct_trn16 -#undef dct_trn32 -#undef dct_trn64 - } - - // row pass - // vrshrn_n_s32 only supports shifts up to 16, we need - // 17. so do a non-rounding shift of 16 first then follow - // up with a rounding shift by 1. - dct_pass(vshrn_n_s32, 16); - - { - // pack and round - uint8x8_t p0 = vqrshrun_n_s16(row0, 1); - uint8x8_t p1 = vqrshrun_n_s16(row1, 1); - uint8x8_t p2 = vqrshrun_n_s16(row2, 1); - uint8x8_t p3 = vqrshrun_n_s16(row3, 1); - uint8x8_t p4 = vqrshrun_n_s16(row4, 1); - uint8x8_t p5 = vqrshrun_n_s16(row5, 1); - uint8x8_t p6 = vqrshrun_n_s16(row6, 1); - uint8x8_t p7 = vqrshrun_n_s16(row7, 1); - - // again, these can translate into one instruction, but often don't. -#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } -#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } -#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } - - // sadly can't use interleaved stores here since we only write - // 8 bytes to each scan line! - - // 8x8 8-bit transpose pass 1 - dct_trn8_8(p0, p1); - dct_trn8_8(p2, p3); - dct_trn8_8(p4, p5); - dct_trn8_8(p6, p7); - - // pass 2 - dct_trn8_16(p0, p2); - dct_trn8_16(p1, p3); - dct_trn8_16(p4, p6); - dct_trn8_16(p5, p7); - - // pass 3 - dct_trn8_32(p0, p4); - dct_trn8_32(p1, p5); - dct_trn8_32(p2, p6); - dct_trn8_32(p3, p7); - - // store - vst1_u8(out, p0); out += out_stride; - vst1_u8(out, p1); out += out_stride; - vst1_u8(out, p2); out += out_stride; - vst1_u8(out, p3); out += out_stride; - vst1_u8(out, p4); out += out_stride; - vst1_u8(out, p5); out += out_stride; - vst1_u8(out, p6); out += out_stride; - vst1_u8(out, p7); - -#undef dct_trn8_8 -#undef dct_trn8_16 -#undef dct_trn8_32 - } - -#undef dct_long_mul -#undef dct_long_mac -#undef dct_widen -#undef dct_wadd -#undef dct_wsub -#undef dct_bfly32o -#undef dct_pass -} - -#endif // STBI_NEON - -#define STBI__MARKER_none 0xff -// if there's a pending marker from the entropy stream, return that -// otherwise, fetch from the stream and get a marker. if there's no -// marker, return 0xff, which is never a valid marker value -static stbi_uc stbi__get_marker(stbi__jpeg *j) -{ - stbi_uc x; - if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } - x = stbi__get8(j->s); - if (x != 0xff) return STBI__MARKER_none; - while (x == 0xff) - x = stbi__get8(j->s); // consume repeated 0xff fill bytes - return x; -} - -// in each scan, we'll have scan_n components, and the order -// of the components is specified by order[] -#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) - -// after a restart interval, stbi__jpeg_reset the entropy decoder and -// the dc prediction -static void stbi__jpeg_reset(stbi__jpeg *j) -{ - j->code_bits = 0; - j->code_buffer = 0; - j->nomore = 0; - j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; - j->marker = STBI__MARKER_none; - j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; - j->eob_run = 0; - // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, - // since we don't even allow 1<<30 pixels -} - -static int stbi__parse_entropy_coded_data(stbi__jpeg *z) -{ - stbi__jpeg_reset(z); - if (!z->progressive) { - if (z->scan_n == 1) { - int i,j; - STBI_SIMD_ALIGN(short, data[64]); - int n = z->order[0]; - // non-interleaved data, we just need to process one block at a time, - // in trivial scanline order - // number of blocks to do just depends on how many actual "pixels" this - // component has, independent of interleaved MCU blocking and such - int w = (z->img_comp[n].x+7) >> 3; - int h = (z->img_comp[n].y+7) >> 3; - for (j=0; j < h; ++j) { - for (i=0; i < w; ++i) { - int ha = z->img_comp[n].ha; - if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; - z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); - // every data block is an MCU, so countdown the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - // if it's NOT a restart, then just bail, so we get corrupt data - // rather than no data - if (!STBI__RESTART(z->marker)) return 1; - stbi__jpeg_reset(z); - } - } - } - return 1; - } else { // interleaved - int i,j,k,x,y; - STBI_SIMD_ALIGN(short, data[64]); - for (j=0; j < z->img_mcu_y; ++j) { - for (i=0; i < z->img_mcu_x; ++i) { - // scan an interleaved mcu... process scan_n components in order - for (k=0; k < z->scan_n; ++k) { - int n = z->order[k]; - // scan out an mcu's worth of this component; that's just determined - // by the basic H and V specified for the component - for (y=0; y < z->img_comp[n].v; ++y) { - for (x=0; x < z->img_comp[n].h; ++x) { - int x2 = (i*z->img_comp[n].h + x)*8; - int y2 = (j*z->img_comp[n].v + y)*8; - int ha = z->img_comp[n].ha; - if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; - z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data); - } - } - } - // after all interleaved components, that's an interleaved MCU, - // so now count down the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - if (!STBI__RESTART(z->marker)) return 1; - stbi__jpeg_reset(z); - } - } - } - return 1; - } - } else { - if (z->scan_n == 1) { - int i,j; - int n = z->order[0]; - // non-interleaved data, we just need to process one block at a time, - // in trivial scanline order - // number of blocks to do just depends on how many actual "pixels" this - // component has, independent of interleaved MCU blocking and such - int w = (z->img_comp[n].x+7) >> 3; - int h = (z->img_comp[n].y+7) >> 3; - for (j=0; j < h; ++j) { - for (i=0; i < w; ++i) { - short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); - if (z->spec_start == 0) { - if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) - return 0; - } else { - int ha = z->img_comp[n].ha; - if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) - return 0; - } - // every data block is an MCU, so countdown the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - if (!STBI__RESTART(z->marker)) return 1; - stbi__jpeg_reset(z); - } - } - } - return 1; - } else { // interleaved - int i,j,k,x,y; - for (j=0; j < z->img_mcu_y; ++j) { - for (i=0; i < z->img_mcu_x; ++i) { - // scan an interleaved mcu... process scan_n components in order - for (k=0; k < z->scan_n; ++k) { - int n = z->order[k]; - // scan out an mcu's worth of this component; that's just determined - // by the basic H and V specified for the component - for (y=0; y < z->img_comp[n].v; ++y) { - for (x=0; x < z->img_comp[n].h; ++x) { - int x2 = (i*z->img_comp[n].h + x); - int y2 = (j*z->img_comp[n].v + y); - short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); - if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) - return 0; - } - } - } - // after all interleaved components, that's an interleaved MCU, - // so now count down the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); - if (!STBI__RESTART(z->marker)) return 1; - stbi__jpeg_reset(z); - } - } - } - return 1; - } - } -} - -static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant) -{ - int i; - for (i=0; i < 64; ++i) - data[i] *= dequant[i]; -} - -static void stbi__jpeg_finish(stbi__jpeg *z) -{ - if (z->progressive) { - // dequantize and idct the data - int i,j,n; - for (n=0; n < z->s->img_n; ++n) { - int w = (z->img_comp[n].x+7) >> 3; - int h = (z->img_comp[n].y+7) >> 3; - for (j=0; j < h; ++j) { - for (i=0; i < w; ++i) { - short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); - stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); - z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); - } - } - } - } -} - -static int stbi__process_marker(stbi__jpeg *z, int m) -{ - int L; - switch (m) { - case STBI__MARKER_none: // no marker found - return stbi__err("expected marker","Corrupt JPEG"); - - case 0xDD: // DRI - specify restart interval - if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len","Corrupt JPEG"); - z->restart_interval = stbi__get16be(z->s); - return 1; - - case 0xDB: // DQT - define quantization table - L = stbi__get16be(z->s)-2; - while (L > 0) { - int q = stbi__get8(z->s); - int p = q >> 4, sixteen = (p != 0); - int t = q & 15,i; - if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG"); - if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG"); - - for (i=0; i < 64; ++i) - z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); - L -= (sixteen ? 129 : 65); - } - return L==0; - - case 0xC4: // DHT - define huffman table - L = stbi__get16be(z->s)-2; - while (L > 0) { - stbi_uc *v; - int sizes[16],i,n=0; - int q = stbi__get8(z->s); - int tc = q >> 4; - int th = q & 15; - if (tc > 1 || th > 3) return stbi__err("bad DHT header","Corrupt JPEG"); - for (i=0; i < 16; ++i) { - sizes[i] = stbi__get8(z->s); - n += sizes[i]; - } - L -= 17; - if (tc == 0) { - if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0; - v = z->huff_dc[th].values; - } else { - if (!stbi__build_huffman(z->huff_ac+th, sizes)) return 0; - v = z->huff_ac[th].values; - } - for (i=0; i < n; ++i) - v[i] = stbi__get8(z->s); - if (tc != 0) - stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); - L -= n; - } - return L==0; - } - - // check for comment block or APP blocks - if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { - L = stbi__get16be(z->s); - if (L < 2) { - if (m == 0xFE) - return stbi__err("bad COM len","Corrupt JPEG"); - else - return stbi__err("bad APP len","Corrupt JPEG"); - } - L -= 2; - - if (m == 0xE0 && L >= 5) { // JFIF APP0 segment - static const unsigned char tag[5] = {'J','F','I','F','\0'}; - int ok = 1; - int i; - for (i=0; i < 5; ++i) - if (stbi__get8(z->s) != tag[i]) - ok = 0; - L -= 5; - if (ok) - z->jfif = 1; - } else if (m == 0xEE && L >= 12) { // Adobe APP14 segment - static const unsigned char tag[6] = {'A','d','o','b','e','\0'}; - int ok = 1; - int i; - for (i=0; i < 6; ++i) - if (stbi__get8(z->s) != tag[i]) - ok = 0; - L -= 6; - if (ok) { - stbi__get8(z->s); // version - stbi__get16be(z->s); // flags0 - stbi__get16be(z->s); // flags1 - z->app14_color_transform = stbi__get8(z->s); // color transform - L -= 6; - } - } - - stbi__skip(z->s, L); - return 1; - } - - return stbi__err("unknown marker","Corrupt JPEG"); -} - -// after we see SOS -static int stbi__process_scan_header(stbi__jpeg *z) -{ - int i; - int Ls = stbi__get16be(z->s); - z->scan_n = stbi__get8(z->s); - if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count","Corrupt JPEG"); - if (Ls != 6+2*z->scan_n) return stbi__err("bad SOS len","Corrupt JPEG"); - for (i=0; i < z->scan_n; ++i) { - int id = stbi__get8(z->s), which; - int q = stbi__get8(z->s); - for (which = 0; which < z->s->img_n; ++which) - if (z->img_comp[which].id == id) - break; - if (which == z->s->img_n) return 0; // no match - z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff","Corrupt JPEG"); - z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff","Corrupt JPEG"); - z->order[i] = which; - } - - { - int aa; - z->spec_start = stbi__get8(z->s); - z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 - aa = stbi__get8(z->s); - z->succ_high = (aa >> 4); - z->succ_low = (aa & 15); - if (z->progressive) { - if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) - return stbi__err("bad SOS", "Corrupt JPEG"); - } else { - if (z->spec_start != 0) return stbi__err("bad SOS","Corrupt JPEG"); - if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS","Corrupt JPEG"); - z->spec_end = 63; - } - } - - return 1; -} - -static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why) -{ - int i; - for (i=0; i < ncomp; ++i) { - if (z->img_comp[i].raw_data) { - STBI_FREE(z->img_comp[i].raw_data); - z->img_comp[i].raw_data = NULL; - z->img_comp[i].data = NULL; - } - if (z->img_comp[i].raw_coeff) { - STBI_FREE(z->img_comp[i].raw_coeff); - z->img_comp[i].raw_coeff = 0; - z->img_comp[i].coeff = 0; - } - if (z->img_comp[i].linebuf) { - STBI_FREE(z->img_comp[i].linebuf); - z->img_comp[i].linebuf = NULL; - } - } - return why; -} - -static int stbi__process_frame_header(stbi__jpeg *z, int scan) -{ - stbi__context *s = z->s; - int Lf,p,i,q, h_max=1,v_max=1,c; - Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len","Corrupt JPEG"); // JPEG - p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline - s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG - s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires - c = stbi__get8(s); - if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG"); - s->img_n = c; - for (i=0; i < c; ++i) { - z->img_comp[i].data = NULL; - z->img_comp[i].linebuf = NULL; - } - - if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG"); - - z->rgb = 0; - for (i=0; i < s->img_n; ++i) { - static const unsigned char rgb[3] = { 'R', 'G', 'B' }; - z->img_comp[i].id = stbi__get8(s); - if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) - ++z->rgb; - q = stbi__get8(s); - z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG"); - z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG"); - z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ","Corrupt JPEG"); - } - - if (scan != STBI__SCAN_load) return 1; - - if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); - - for (i=0; i < s->img_n; ++i) { - if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; - if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; - } - - // compute interleaved mcu info - z->img_h_max = h_max; - z->img_v_max = v_max; - z->img_mcu_w = h_max * 8; - z->img_mcu_h = v_max * 8; - // these sizes can't be more than 17 bits - z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; - z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; - - for (i=0; i < s->img_n; ++i) { - // number of effective pixels (e.g. for non-interleaved MCU) - z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; - z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; - // to simplify generation, we'll allocate enough memory to decode - // the bogus oversized data from using interleaved MCUs and their - // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't - // discard the extra data until colorspace conversion - // - // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) - // so these muls can't overflow with 32-bit ints (which we require) - z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; - z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; - z->img_comp[i].coeff = 0; - z->img_comp[i].raw_coeff = 0; - z->img_comp[i].linebuf = NULL; - z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); - if (z->img_comp[i].raw_data == NULL) - return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); - // align blocks for idct using mmx/sse - z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); - if (z->progressive) { - // w2, h2 are multiples of 8 (see above) - z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; - z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; - z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); - if (z->img_comp[i].raw_coeff == NULL) - return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); - z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15); - } - } - - return 1; -} - -// use comparisons since in some cases we handle more than one case (e.g. SOF) -#define stbi__DNL(x) ((x) == 0xdc) -#define stbi__SOI(x) ((x) == 0xd8) -#define stbi__EOI(x) ((x) == 0xd9) -#define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) -#define stbi__SOS(x) ((x) == 0xda) - -#define stbi__SOF_progressive(x) ((x) == 0xc2) - -static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) -{ - int m; - z->jfif = 0; - z->app14_color_transform = -1; // valid values are 0,1,2 - z->marker = STBI__MARKER_none; // initialize cached marker to empty - m = stbi__get_marker(z); - if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG"); - if (scan == STBI__SCAN_type) return 1; - m = stbi__get_marker(z); - while (!stbi__SOF(m)) { - if (!stbi__process_marker(z,m)) return 0; - m = stbi__get_marker(z); - while (m == STBI__MARKER_none) { - // some files have extra padding after their blocks, so ok, we'll scan - if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); - m = stbi__get_marker(z); - } - } - z->progressive = stbi__SOF_progressive(m); - if (!stbi__process_frame_header(z, scan)) return 0; - return 1; -} - -// decode image to YCbCr format -static int stbi__decode_jpeg_image(stbi__jpeg *j) -{ - int m; - for (m = 0; m < 4; m++) { - j->img_comp[m].raw_data = NULL; - j->img_comp[m].raw_coeff = NULL; - } - j->restart_interval = 0; - if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; - m = stbi__get_marker(j); - while (!stbi__EOI(m)) { - if (stbi__SOS(m)) { - if (!stbi__process_scan_header(j)) return 0; - if (!stbi__parse_entropy_coded_data(j)) return 0; - if (j->marker == STBI__MARKER_none ) { - // handle 0s at the end of image data from IP Kamera 9060 - while (!stbi__at_eof(j->s)) { - int x = stbi__get8(j->s); - if (x == 255) { - j->marker = stbi__get8(j->s); - break; - } - } - // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 - } - } else if (stbi__DNL(m)) { - int Ld = stbi__get16be(j->s); - stbi__uint32 NL = stbi__get16be(j->s); - if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); - if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); - } else { - if (!stbi__process_marker(j, m)) return 0; - } - m = stbi__get_marker(j); - } - if (j->progressive) - stbi__jpeg_finish(j); - return 1; -} - -// static jfif-centered resampling (across block boundaries) - -typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1, - int w, int hs); - -#define stbi__div4(x) ((stbi_uc) ((x) >> 2)) - -static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - STBI_NOTUSED(out); - STBI_NOTUSED(in_far); - STBI_NOTUSED(w); - STBI_NOTUSED(hs); - return in_near; -} - -static stbi_uc* stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - // need to generate two samples vertically for every one in input - int i; - STBI_NOTUSED(hs); - for (i=0; i < w; ++i) - out[i] = stbi__div4(3*in_near[i] + in_far[i] + 2); - return out; -} - -static stbi_uc* stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - // need to generate two samples horizontally for every one in input - int i; - stbi_uc *input = in_near; - - if (w == 1) { - // if only one sample, can't do any interpolation - out[0] = out[1] = input[0]; - return out; - } - - out[0] = input[0]; - out[1] = stbi__div4(input[0]*3 + input[1] + 2); - for (i=1; i < w-1; ++i) { - int n = 3*input[i]+2; - out[i*2+0] = stbi__div4(n+input[i-1]); - out[i*2+1] = stbi__div4(n+input[i+1]); - } - out[i*2+0] = stbi__div4(input[w-2]*3 + input[w-1] + 2); - out[i*2+1] = input[w-1]; - - STBI_NOTUSED(in_far); - STBI_NOTUSED(hs); - - return out; -} - -#define stbi__div16(x) ((stbi_uc) ((x) >> 4)) - -static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - // need to generate 2x2 samples for every one in input - int i,t0,t1; - if (w == 1) { - out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); - return out; - } - - t1 = 3*in_near[0] + in_far[0]; - out[0] = stbi__div4(t1+2); - for (i=1; i < w; ++i) { - t0 = t1; - t1 = 3*in_near[i]+in_far[i]; - out[i*2-1] = stbi__div16(3*t0 + t1 + 8); - out[i*2 ] = stbi__div16(3*t1 + t0 + 8); - } - out[w*2-1] = stbi__div4(t1+2); - - STBI_NOTUSED(hs); - - return out; -} - -#if defined(STBI_SSE2) || defined(STBI_NEON) -static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - // need to generate 2x2 samples for every one in input - int i=0,t0,t1; - - if (w == 1) { - out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); - return out; - } - - t1 = 3*in_near[0] + in_far[0]; - // process groups of 8 pixels for as long as we can. - // note we can't handle the last pixel in a row in this loop - // because we need to handle the filter boundary conditions. - for (; i < ((w-1) & ~7); i += 8) { -#if defined(STBI_SSE2) - // load and perform the vertical filtering pass - // this uses 3*x + y = 4*x + (y - x) - __m128i zero = _mm_setzero_si128(); - __m128i farb = _mm_loadl_epi64((__m128i *) (in_far + i)); - __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i)); - __m128i farw = _mm_unpacklo_epi8(farb, zero); - __m128i nearw = _mm_unpacklo_epi8(nearb, zero); - __m128i diff = _mm_sub_epi16(farw, nearw); - __m128i nears = _mm_slli_epi16(nearw, 2); - __m128i curr = _mm_add_epi16(nears, diff); // current row - - // horizontal filter works the same based on shifted vers of current - // row. "prev" is current row shifted right by 1 pixel; we need to - // insert the previous pixel value (from t1). - // "next" is current row shifted left by 1 pixel, with first pixel - // of next block of 8 pixels added in. - __m128i prv0 = _mm_slli_si128(curr, 2); - __m128i nxt0 = _mm_srli_si128(curr, 2); - __m128i prev = _mm_insert_epi16(prv0, t1, 0); - __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7); - - // horizontal filter, polyphase implementation since it's convenient: - // even pixels = 3*cur + prev = cur*4 + (prev - cur) - // odd pixels = 3*cur + next = cur*4 + (next - cur) - // note the shared term. - __m128i bias = _mm_set1_epi16(8); - __m128i curs = _mm_slli_epi16(curr, 2); - __m128i prvd = _mm_sub_epi16(prev, curr); - __m128i nxtd = _mm_sub_epi16(next, curr); - __m128i curb = _mm_add_epi16(curs, bias); - __m128i even = _mm_add_epi16(prvd, curb); - __m128i odd = _mm_add_epi16(nxtd, curb); - - // interleave even and odd pixels, then undo scaling. - __m128i int0 = _mm_unpacklo_epi16(even, odd); - __m128i int1 = _mm_unpackhi_epi16(even, odd); - __m128i de0 = _mm_srli_epi16(int0, 4); - __m128i de1 = _mm_srli_epi16(int1, 4); - - // pack and write output - __m128i outv = _mm_packus_epi16(de0, de1); - _mm_storeu_si128((__m128i *) (out + i*2), outv); -#elif defined(STBI_NEON) - // load and perform the vertical filtering pass - // this uses 3*x + y = 4*x + (y - x) - uint8x8_t farb = vld1_u8(in_far + i); - uint8x8_t nearb = vld1_u8(in_near + i); - int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); - int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); - int16x8_t curr = vaddq_s16(nears, diff); // current row - - // horizontal filter works the same based on shifted vers of current - // row. "prev" is current row shifted right by 1 pixel; we need to - // insert the previous pixel value (from t1). - // "next" is current row shifted left by 1 pixel, with first pixel - // of next block of 8 pixels added in. - int16x8_t prv0 = vextq_s16(curr, curr, 7); - int16x8_t nxt0 = vextq_s16(curr, curr, 1); - int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); - int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7); - - // horizontal filter, polyphase implementation since it's convenient: - // even pixels = 3*cur + prev = cur*4 + (prev - cur) - // odd pixels = 3*cur + next = cur*4 + (next - cur) - // note the shared term. - int16x8_t curs = vshlq_n_s16(curr, 2); - int16x8_t prvd = vsubq_s16(prev, curr); - int16x8_t nxtd = vsubq_s16(next, curr); - int16x8_t even = vaddq_s16(curs, prvd); - int16x8_t odd = vaddq_s16(curs, nxtd); - - // undo scaling and round, then store with even/odd phases interleaved - uint8x8x2_t o; - o.val[0] = vqrshrun_n_s16(even, 4); - o.val[1] = vqrshrun_n_s16(odd, 4); - vst2_u8(out + i*2, o); -#endif - - // "previous" value for next iter - t1 = 3*in_near[i+7] + in_far[i+7]; - } - - t0 = t1; - t1 = 3*in_near[i] + in_far[i]; - out[i*2] = stbi__div16(3*t1 + t0 + 8); - - for (++i; i < w; ++i) { - t0 = t1; - t1 = 3*in_near[i]+in_far[i]; - out[i*2-1] = stbi__div16(3*t0 + t1 + 8); - out[i*2 ] = stbi__div16(3*t1 + t0 + 8); - } - out[w*2-1] = stbi__div4(t1+2); - - STBI_NOTUSED(hs); - - return out; -} -#endif - -static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) -{ - // resample with nearest-neighbor - int i,j; - STBI_NOTUSED(in_far); - for (i=0; i < w; ++i) - for (j=0; j < hs; ++j) - out[i*hs+j] = in_near[i]; - return out; -} - -// this is a reduced-precision calculation of YCbCr-to-RGB introduced -// to make sure the code produces the same results in both SIMD and scalar -#define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) -static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) -{ - int i; - for (i=0; i < count; ++i) { - int y_fixed = (y[i] << 20) + (1<<19); // rounding - int r,g,b; - int cr = pcr[i] - 128; - int cb = pcb[i] - 128; - r = y_fixed + cr* stbi__float2fixed(1.40200f); - g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); - b = y_fixed + cb* stbi__float2fixed(1.77200f); - r >>= 20; - g >>= 20; - b >>= 20; - if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } - if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } - if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } - out[0] = (stbi_uc)r; - out[1] = (stbi_uc)g; - out[2] = (stbi_uc)b; - out[3] = 255; - out += step; - } -} - -#if defined(STBI_SSE2) || defined(STBI_NEON) -static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step) -{ - int i = 0; - -#ifdef STBI_SSE2 - // step == 3 is pretty ugly on the final interleave, and i'm not convinced - // it's useful in practice (you wouldn't use it for textures, for example). - // so just accelerate step == 4 case. - if (step == 4) { - // this is a fairly straightforward implementation and not super-optimized. - __m128i signflip = _mm_set1_epi8(-0x80); - __m128i cr_const0 = _mm_set1_epi16( (short) ( 1.40200f*4096.0f+0.5f)); - __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f)); - __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f)); - __m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f)); - __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128); - __m128i xw = _mm_set1_epi16(255); // alpha channel - - for (; i+7 < count; i += 8) { - // load - __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i)); - __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i)); - __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i)); - __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 - __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 - - // unpack to short (and left-shift cr, cb by 8) - __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); - __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); - __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); - - // color transform - __m128i yws = _mm_srli_epi16(yw, 4); - __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); - __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); - __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); - __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); - __m128i rws = _mm_add_epi16(cr0, yws); - __m128i gwt = _mm_add_epi16(cb0, yws); - __m128i bws = _mm_add_epi16(yws, cb1); - __m128i gws = _mm_add_epi16(gwt, cr1); - - // descale - __m128i rw = _mm_srai_epi16(rws, 4); - __m128i bw = _mm_srai_epi16(bws, 4); - __m128i gw = _mm_srai_epi16(gws, 4); - - // back to byte, set up for transpose - __m128i brb = _mm_packus_epi16(rw, bw); - __m128i gxb = _mm_packus_epi16(gw, xw); - - // transpose to interleave channels - __m128i t0 = _mm_unpacklo_epi8(brb, gxb); - __m128i t1 = _mm_unpackhi_epi8(brb, gxb); - __m128i o0 = _mm_unpacklo_epi16(t0, t1); - __m128i o1 = _mm_unpackhi_epi16(t0, t1); - - // store - _mm_storeu_si128((__m128i *) (out + 0), o0); - _mm_storeu_si128((__m128i *) (out + 16), o1); - out += 32; - } - } -#endif - -#ifdef STBI_NEON - // in this version, step=3 support would be easy to add. but is there demand? - if (step == 4) { - // this is a fairly straightforward implementation and not super-optimized. - uint8x8_t signflip = vdup_n_u8(0x80); - int16x8_t cr_const0 = vdupq_n_s16( (short) ( 1.40200f*4096.0f+0.5f)); - int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f)); - int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f)); - int16x8_t cb_const1 = vdupq_n_s16( (short) ( 1.77200f*4096.0f+0.5f)); - - for (; i+7 < count; i += 8) { - // load - uint8x8_t y_bytes = vld1_u8(y + i); - uint8x8_t cr_bytes = vld1_u8(pcr + i); - uint8x8_t cb_bytes = vld1_u8(pcb + i); - int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); - int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); - - // expand to s16 - int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); - int16x8_t crw = vshll_n_s8(cr_biased, 7); - int16x8_t cbw = vshll_n_s8(cb_biased, 7); - - // color transform - int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); - int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); - int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); - int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); - int16x8_t rws = vaddq_s16(yws, cr0); - int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); - int16x8_t bws = vaddq_s16(yws, cb1); - - // undo scaling, round, convert to byte - uint8x8x4_t o; - o.val[0] = vqrshrun_n_s16(rws, 4); - o.val[1] = vqrshrun_n_s16(gws, 4); - o.val[2] = vqrshrun_n_s16(bws, 4); - o.val[3] = vdup_n_u8(255); - - // store, interleaving r/g/b/a - vst4_u8(out, o); - out += 8*4; - } - } -#endif - - for (; i < count; ++i) { - int y_fixed = (y[i] << 20) + (1<<19); // rounding - int r,g,b; - int cr = pcr[i] - 128; - int cb = pcb[i] - 128; - r = y_fixed + cr* stbi__float2fixed(1.40200f); - g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); - b = y_fixed + cb* stbi__float2fixed(1.77200f); - r >>= 20; - g >>= 20; - b >>= 20; - if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } - if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } - if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } - out[0] = (stbi_uc)r; - out[1] = (stbi_uc)g; - out[2] = (stbi_uc)b; - out[3] = 255; - out += step; - } -} -#endif - -// set up the kernels -static void stbi__setup_jpeg(stbi__jpeg *j) -{ - j->idct_block_kernel = stbi__idct_block; - j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; - j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; - -#ifdef STBI_SSE2 - if (stbi__sse2_available()) { - j->idct_block_kernel = stbi__idct_simd; - j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; - j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; - } -#endif - -#ifdef STBI_NEON - j->idct_block_kernel = stbi__idct_simd; - j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; - j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; -#endif -} - -// clean up the temporary component buffers -static void stbi__cleanup_jpeg(stbi__jpeg *j) -{ - stbi__free_jpeg_components(j, j->s->img_n, 0); -} - -typedef struct -{ - resample_row_func resample; - stbi_uc *line0,*line1; - int hs,vs; // expansion factor in each axis - int w_lores; // horizontal pixels pre-expansion - int ystep; // how far through vertical expansion we are - int ypos; // which pre-expansion row we're on -} stbi__resample; - -// fast 0..255 * 0..255 => 0..255 rounded multiplication -static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) -{ - unsigned int t = x*y + 128; - return (stbi_uc) ((t + (t >>8)) >> 8); -} - -static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) -{ - int n, decode_n, is_rgb; - z->s->img_n = 0; // make stbi__cleanup_jpeg safe - - // validate req_comp - if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); - - // load a jpeg image from whichever source, but leave in YCbCr format - if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } - - // determine actual number of components to generate - n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; - - is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); - - if (z->s->img_n == 3 && n < 3 && !is_rgb) - decode_n = 1; - else - decode_n = z->s->img_n; - - // resample and color-convert - { - int k; - unsigned int i,j; - stbi_uc *output; - stbi_uc *coutput[4]; - - stbi__resample res_comp[4]; - - for (k=0; k < decode_n; ++k) { - stbi__resample *r = &res_comp[k]; - - // allocate line buffer big enough for upsampling off the edges - // with upsample factor of 4 - z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3); - if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } - - r->hs = z->img_h_max / z->img_comp[k].h; - r->vs = z->img_v_max / z->img_comp[k].v; - r->ystep = r->vs >> 1; - r->w_lores = (z->s->img_x + r->hs-1) / r->hs; - r->ypos = 0; - r->line0 = r->line1 = z->img_comp[k].data; - - if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; - else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; - else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; - else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; - else r->resample = stbi__resample_row_generic; - } - - // can't error after this so, this is safe - output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); - if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } - - // now go ahead and resample - for (j=0; j < z->s->img_y; ++j) { - stbi_uc *out = output + n * z->s->img_x * j; - for (k=0; k < decode_n; ++k) { - stbi__resample *r = &res_comp[k]; - int y_bot = r->ystep >= (r->vs >> 1); - coutput[k] = r->resample(z->img_comp[k].linebuf, - y_bot ? r->line1 : r->line0, - y_bot ? r->line0 : r->line1, - r->w_lores, r->hs); - if (++r->ystep >= r->vs) { - r->ystep = 0; - r->line0 = r->line1; - if (++r->ypos < z->img_comp[k].y) - r->line1 += z->img_comp[k].w2; - } - } - if (n >= 3) { - stbi_uc *y = coutput[0]; - if (z->s->img_n == 3) { - if (is_rgb) { - for (i=0; i < z->s->img_x; ++i) { - out[0] = y[i]; - out[1] = coutput[1][i]; - out[2] = coutput[2][i]; - out[3] = 255; - out += n; - } - } else { - z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); - } - } else if (z->s->img_n == 4) { - if (z->app14_color_transform == 0) { // CMYK - for (i=0; i < z->s->img_x; ++i) { - stbi_uc m = coutput[3][i]; - out[0] = stbi__blinn_8x8(coutput[0][i], m); - out[1] = stbi__blinn_8x8(coutput[1][i], m); - out[2] = stbi__blinn_8x8(coutput[2][i], m); - out[3] = 255; - out += n; - } - } else if (z->app14_color_transform == 2) { // YCCK - z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); - for (i=0; i < z->s->img_x; ++i) { - stbi_uc m = coutput[3][i]; - out[0] = stbi__blinn_8x8(255 - out[0], m); - out[1] = stbi__blinn_8x8(255 - out[1], m); - out[2] = stbi__blinn_8x8(255 - out[2], m); - out += n; - } - } else { // YCbCr + alpha? Ignore the fourth channel for now - z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); - } - } else - for (i=0; i < z->s->img_x; ++i) { - out[0] = out[1] = out[2] = y[i]; - out[3] = 255; // not used if n==3 - out += n; - } - } else { - if (is_rgb) { - if (n == 1) - for (i=0; i < z->s->img_x; ++i) - *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); - else { - for (i=0; i < z->s->img_x; ++i, out += 2) { - out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); - out[1] = 255; - } - } - } else if (z->s->img_n == 4 && z->app14_color_transform == 0) { - for (i=0; i < z->s->img_x; ++i) { - stbi_uc m = coutput[3][i]; - stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); - stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); - stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); - out[0] = stbi__compute_y(r, g, b); - out[1] = 255; - out += n; - } - } else if (z->s->img_n == 4 && z->app14_color_transform == 2) { - for (i=0; i < z->s->img_x; ++i) { - out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); - out[1] = 255; - out += n; - } - } else { - stbi_uc *y = coutput[0]; - if (n == 1) - for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; - else - for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; - } - } - } - stbi__cleanup_jpeg(z); - *out_x = z->s->img_x; - *out_y = z->s->img_y; - if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output - return output; - } -} - -static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) -{ - unsigned char* result; - stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); - STBI_NOTUSED(ri); - j->s = s; - stbi__setup_jpeg(j); - result = load_jpeg_image(j, x,y,comp,req_comp); - STBI_FREE(j); - return result; -} - -static int stbi__jpeg_test(stbi__context *s) -{ - int r; - stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); - j->s = s; - stbi__setup_jpeg(j); - r = stbi__decode_jpeg_header(j, STBI__SCAN_type); - stbi__rewind(s); - STBI_FREE(j); - return r; -} - -static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp) -{ - if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { - stbi__rewind( j->s ); - return 0; - } - if (x) *x = j->s->img_x; - if (y) *y = j->s->img_y; - if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; - return 1; -} - -static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp) -{ - int result; - stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg))); - if (!j) { - stbi__errpuc("outofmem", "Out of memory"); - return 0; - } - j->s = s; - result = stbi__jpeg_info_raw(j, x, y, comp); - STBI_FREE(j); - return result; -} -#endif - -// public domain zlib decode v0.2 Sean Barrett 2006-11-18 -// simple implementation -// - all input must be provided in an upfront buffer -// - all output is written to a single output buffer (can malloc/realloc) -// performance -// - fast huffman - -#ifndef STBI_NO_ZLIB - -// fast-way is faster to check than jpeg huffman, but slow way is slower -#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables -#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) - -// zlib-style huffman encoding -// (jpegs packs from left, zlib from right, so can't share code) -typedef struct -{ - stbi__uint16 fast[1 << STBI__ZFAST_BITS]; - stbi__uint16 firstcode[16]; - int maxcode[17]; - stbi__uint16 firstsymbol[16]; - stbi_uc size[288]; - stbi__uint16 value[288]; -} stbi__zhuffman; - -stbi_inline static int stbi__bitreverse16(int n) -{ - n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); - n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); - n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); - n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); - return n; -} - -stbi_inline static int stbi__bit_reverse(int v, int bits) -{ - STBI_ASSERT(bits <= 16); - // to bit reverse n bits, reverse 16 and shift - // e.g. 11 bits, bit reverse and shift away 5 - return stbi__bitreverse16(v) >> (16-bits); -} - -static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num) -{ - int i,k=0; - int code, next_code[16], sizes[17]; - - // DEFLATE spec for generating codes - memset(sizes, 0, sizeof(sizes)); - memset(z->fast, 0, sizeof(z->fast)); - for (i=0; i < num; ++i) - ++sizes[sizelist[i]]; - sizes[0] = 0; - for (i=1; i < 16; ++i) - if (sizes[i] > (1 << i)) - return stbi__err("bad sizes", "Corrupt PNG"); - code = 0; - for (i=1; i < 16; ++i) { - next_code[i] = code; - z->firstcode[i] = (stbi__uint16) code; - z->firstsymbol[i] = (stbi__uint16) k; - code = (code + sizes[i]); - if (sizes[i]) - if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG"); - z->maxcode[i] = code << (16-i); // preshift for inner loop - code <<= 1; - k += sizes[i]; - } - z->maxcode[16] = 0x10000; // sentinel - for (i=0; i < num; ++i) { - int s = sizelist[i]; - if (s) { - int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; - stbi__uint16 fastv = (stbi__uint16) ((s << 9) | i); - z->size [c] = (stbi_uc ) s; - z->value[c] = (stbi__uint16) i; - if (s <= STBI__ZFAST_BITS) { - int j = stbi__bit_reverse(next_code[s],s); - while (j < (1 << STBI__ZFAST_BITS)) { - z->fast[j] = fastv; - j += (1 << s); - } - } - ++next_code[s]; - } - } - return 1; -} - -// zlib-from-memory implementation for PNG reading -// because PNG allows splitting the zlib stream arbitrarily, -// and it's annoying structurally to have PNG call ZLIB call PNG, -// we require PNG read all the IDATs and combine them into a single -// memory buffer - -typedef struct -{ - stbi_uc *zbuffer, *zbuffer_end; - int num_bits; - stbi__uint32 code_buffer; - - char *zout; - char *zout_start; - char *zout_end; - int z_expandable; - - stbi__zhuffman z_length, z_distance; -} stbi__zbuf; - -stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z) -{ - if (z->zbuffer >= z->zbuffer_end) return 0; - return *z->zbuffer++; -} - -static void stbi__fill_bits(stbi__zbuf *z) -{ - do { - STBI_ASSERT(z->code_buffer < (1U << z->num_bits)); - z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits; - z->num_bits += 8; - } while (z->num_bits <= 24); -} - -stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n) -{ - unsigned int k; - if (z->num_bits < n) stbi__fill_bits(z); - k = z->code_buffer & ((1 << n) - 1); - z->code_buffer >>= n; - z->num_bits -= n; - return k; -} - -static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) -{ - int b,s,k; - // not resolved by fast table, so compute it the slow way - // use jpeg approach, which requires MSbits at top - k = stbi__bit_reverse(a->code_buffer, 16); - for (s=STBI__ZFAST_BITS+1; ; ++s) - if (k < z->maxcode[s]) - break; - if (s == 16) return -1; // invalid code! - // code size is s, so: - b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; - STBI_ASSERT(z->size[b] == s); - a->code_buffer >>= s; - a->num_bits -= s; - return z->value[b]; -} - -stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) -{ - int b,s; - if (a->num_bits < 16) stbi__fill_bits(a); - b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; - if (b) { - s = b >> 9; - a->code_buffer >>= s; - a->num_bits -= s; - return b & 511; - } - return stbi__zhuffman_decode_slowpath(a, z); -} - -static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes -{ - char *q; - int cur, limit, old_limit; - z->zout = zout; - if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG"); - cur = (int) (z->zout - z->zout_start); - limit = old_limit = (int) (z->zout_end - z->zout_start); - while (cur + n > limit) - limit *= 2; - q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); - STBI_NOTUSED(old_limit); - if (q == NULL) return stbi__err("outofmem", "Out of memory"); - z->zout_start = q; - z->zout = q + cur; - z->zout_end = q + limit; - return 1; -} - -static const int stbi__zlength_base[31] = { - 3,4,5,6,7,8,9,10,11,13, - 15,17,19,23,27,31,35,43,51,59, - 67,83,99,115,131,163,195,227,258,0,0 }; - -static const int stbi__zlength_extra[31]= -{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; - -static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, -257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; - -static const int stbi__zdist_extra[32] = -{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -static int stbi__parse_huffman_block(stbi__zbuf *a) -{ - char *zout = a->zout; - for(;;) { - int z = stbi__zhuffman_decode(a, &a->z_length); - if (z < 256) { - if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); // error in huffman codes - if (zout >= a->zout_end) { - if (!stbi__zexpand(a, zout, 1)) return 0; - zout = a->zout; - } - *zout++ = (char) z; - } else { - stbi_uc *p; - int len,dist; - if (z == 256) { - a->zout = zout; - return 1; - } - z -= 257; - len = stbi__zlength_base[z]; - if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); - z = stbi__zhuffman_decode(a, &a->z_distance); - if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); - dist = stbi__zdist_base[z]; - if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); - if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG"); - if (zout + len > a->zout_end) { - if (!stbi__zexpand(a, zout, len)) return 0; - zout = a->zout; - } - p = (stbi_uc *) (zout - dist); - if (dist == 1) { // run of one byte; common in images. - stbi_uc v = *p; - if (len) { do *zout++ = v; while (--len); } - } else { - if (len) { do *zout++ = *p++; while (--len); } - } - } - } -} - -static int stbi__compute_huffman_codes(stbi__zbuf *a) -{ - static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; - stbi__zhuffman z_codelength; - stbi_uc lencodes[286+32+137];//padding for maximum single op - stbi_uc codelength_sizes[19]; - int i,n; - - int hlit = stbi__zreceive(a,5) + 257; - int hdist = stbi__zreceive(a,5) + 1; - int hclen = stbi__zreceive(a,4) + 4; - int ntot = hlit + hdist; - - memset(codelength_sizes, 0, sizeof(codelength_sizes)); - for (i=0; i < hclen; ++i) { - int s = stbi__zreceive(a,3); - codelength_sizes[length_dezigzag[i]] = (stbi_uc) s; - } - if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; - - n = 0; - while (n < ntot) { - int c = stbi__zhuffman_decode(a, &z_codelength); - if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); - if (c < 16) - lencodes[n++] = (stbi_uc) c; - else { - stbi_uc fill = 0; - if (c == 16) { - c = stbi__zreceive(a,2)+3; - if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); - fill = lencodes[n-1]; - } else if (c == 17) - c = stbi__zreceive(a,3)+3; - else { - STBI_ASSERT(c == 18); - c = stbi__zreceive(a,7)+11; - } - if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); - memset(lencodes+n, fill, c); - n += c; - } - } - if (n != ntot) return stbi__err("bad codelengths","Corrupt PNG"); - if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; - if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; - return 1; -} - -static int stbi__parse_uncompressed_block(stbi__zbuf *a) -{ - stbi_uc header[4]; - int len,nlen,k; - if (a->num_bits & 7) - stbi__zreceive(a, a->num_bits & 7); // discard - // drain the bit-packed data into header - k = 0; - while (a->num_bits > 0) { - header[k++] = (stbi_uc) (a->code_buffer & 255); // suppress MSVC run-time check - a->code_buffer >>= 8; - a->num_bits -= 8; - } - STBI_ASSERT(a->num_bits == 0); - // now fill header the normal way - while (k < 4) - header[k++] = stbi__zget8(a); - len = header[1] * 256 + header[0]; - nlen = header[3] * 256 + header[2]; - if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG"); - if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG"); - if (a->zout + len > a->zout_end) - if (!stbi__zexpand(a, a->zout, len)) return 0; - memcpy(a->zout, a->zbuffer, len); - a->zbuffer += len; - a->zout += len; - return 1; -} - -static int stbi__parse_zlib_header(stbi__zbuf *a) -{ - int cmf = stbi__zget8(a); - int cm = cmf & 15; - /* int cinfo = cmf >> 4; */ - int flg = stbi__zget8(a); - if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec - if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png - if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png - // window = 1 << (8 + cinfo)... but who cares, we fully buffer output - return 1; -} - -static const stbi_uc stbi__zdefault_length[288] = -{ - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 -}; -static const stbi_uc stbi__zdefault_distance[32] = -{ - 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 -}; -/* -Init algorithm: -{ - int i; // use <= to match clearly with spec - for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; - for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; - for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; - for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; - - for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; -} -*/ - -static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) -{ - int final, type; - if (parse_header) - if (!stbi__parse_zlib_header(a)) return 0; - a->num_bits = 0; - a->code_buffer = 0; - do { - final = stbi__zreceive(a,1); - type = stbi__zreceive(a,2); - if (type == 0) { - if (!stbi__parse_uncompressed_block(a)) return 0; - } else if (type == 3) { - return 0; - } else { - if (type == 1) { - // use fixed code lengths - if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0; - if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; - } else { - if (!stbi__compute_huffman_codes(a)) return 0; - } - if (!stbi__parse_huffman_block(a)) return 0; - } - } while (!final); - return 1; -} - -static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse_header) -{ - a->zout_start = obuf; - a->zout = obuf; - a->zout_end = obuf + olen; - a->z_expandable = exp; - - return stbi__parse_zlib(a, parse_header); -} - -STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) -{ - stbi__zbuf a; - char *p = (char *) stbi__malloc(initial_size); - if (p == NULL) return NULL; - a.zbuffer = (stbi_uc *) buffer; - a.zbuffer_end = (stbi_uc *) buffer + len; - if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { - if (outlen) *outlen = (int) (a.zout - a.zout_start); - return a.zout_start; - } else { - STBI_FREE(a.zout_start); - return NULL; - } -} - -STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) -{ - return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); -} - -STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) -{ - stbi__zbuf a; - char *p = (char *) stbi__malloc(initial_size); - if (p == NULL) return NULL; - a.zbuffer = (stbi_uc *) buffer; - a.zbuffer_end = (stbi_uc *) buffer + len; - if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { - if (outlen) *outlen = (int) (a.zout - a.zout_start); - return a.zout_start; - } else { - STBI_FREE(a.zout_start); - return NULL; - } -} - -STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) -{ - stbi__zbuf a; - a.zbuffer = (stbi_uc *) ibuffer; - a.zbuffer_end = (stbi_uc *) ibuffer + ilen; - if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) - return (int) (a.zout - a.zout_start); - else - return -1; -} - -STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) -{ - stbi__zbuf a; - char *p = (char *) stbi__malloc(16384); - if (p == NULL) return NULL; - a.zbuffer = (stbi_uc *) buffer; - a.zbuffer_end = (stbi_uc *) buffer+len; - if (stbi__do_zlib(&a, p, 16384, 1, 0)) { - if (outlen) *outlen = (int) (a.zout - a.zout_start); - return a.zout_start; - } else { - STBI_FREE(a.zout_start); - return NULL; - } -} - -STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) -{ - stbi__zbuf a; - a.zbuffer = (stbi_uc *) ibuffer; - a.zbuffer_end = (stbi_uc *) ibuffer + ilen; - if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) - return (int) (a.zout - a.zout_start); - else - return -1; -} -#endif - -// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 -// simple implementation -// - only 8-bit samples -// - no CRC checking -// - allocates lots of intermediate memory -// - avoids problem of streaming data between subsystems -// - avoids explicit window management -// performance -// - uses stb_zlib, a PD zlib implementation with fast huffman decoding - -#ifndef STBI_NO_PNG -typedef struct -{ - stbi__uint32 length; - stbi__uint32 type; -} stbi__pngchunk; - -static stbi__pngchunk stbi__get_chunk_header(stbi__context *s) -{ - stbi__pngchunk c; - c.length = stbi__get32be(s); - c.type = stbi__get32be(s); - return c; -} - -static int stbi__check_png_header(stbi__context *s) -{ - static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; - int i; - for (i=0; i < 8; ++i) - if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG"); - return 1; -} - -typedef struct -{ - stbi__context *s; - stbi_uc *idata, *expanded, *out; - int depth; -} stbi__png; - - -enum { - STBI__F_none=0, - STBI__F_sub=1, - STBI__F_up=2, - STBI__F_avg=3, - STBI__F_paeth=4, - // synthetic filters used for first scanline to avoid needing a dummy row of 0s - STBI__F_avg_first, - STBI__F_paeth_first -}; - -static stbi_uc first_row_filter[5] = -{ - STBI__F_none, - STBI__F_sub, - STBI__F_none, - STBI__F_avg_first, - STBI__F_paeth_first -}; - -static int stbi__paeth(int a, int b, int c) -{ - int p = a + b - c; - int pa = abs(p-a); - int pb = abs(p-b); - int pc = abs(p-c); - if (pa <= pb && pa <= pc) return a; - if (pb <= pc) return b; - return c; -} - -static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; - -// create the png data from post-deflated data -static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) -{ - int bytes = (depth == 16? 2 : 1); - stbi__context *s = a->s; - stbi__uint32 i,j,stride = x*out_n*bytes; - stbi__uint32 img_len, img_width_bytes; - int k; - int img_n = s->img_n; // copy it into a local for later - - int output_bytes = out_n*bytes; - int filter_bytes = img_n*bytes; - int width = x; - - STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); - a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into - if (!a->out) return stbi__err("outofmem", "Out of memory"); - - if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); - img_width_bytes = (((img_n * x * depth) + 7) >> 3); - img_len = (img_width_bytes + 1) * y; - - // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, - // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), - // so just check for raw_len < img_len always. - if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); - - for (j=0; j < y; ++j) { - stbi_uc *cur = a->out + stride*j; - stbi_uc *prior; - int filter = *raw++; - - if (filter > 4) - return stbi__err("invalid filter","Corrupt PNG"); - - if (depth < 8) { - STBI_ASSERT(img_width_bytes <= x); - cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place - filter_bytes = 1; - width = img_width_bytes; - } - prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above - - // if first row, use special filter that doesn't sample previous row - if (j == 0) filter = first_row_filter[filter]; - - // handle first byte explicitly - for (k=0; k < filter_bytes; ++k) { - switch (filter) { - case STBI__F_none : cur[k] = raw[k]; break; - case STBI__F_sub : cur[k] = raw[k]; break; - case STBI__F_up : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; - case STBI__F_avg : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break; - case STBI__F_paeth : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break; - case STBI__F_avg_first : cur[k] = raw[k]; break; - case STBI__F_paeth_first: cur[k] = raw[k]; break; - } - } - - if (depth == 8) { - if (img_n != out_n) - cur[img_n] = 255; // first pixel - raw += img_n; - cur += out_n; - prior += out_n; - } else if (depth == 16) { - if (img_n != out_n) { - cur[filter_bytes] = 255; // first pixel top byte - cur[filter_bytes+1] = 255; // first pixel bottom byte - } - raw += filter_bytes; - cur += output_bytes; - prior += output_bytes; - } else { - raw += 1; - cur += 1; - prior += 1; - } - - // this is a little gross, so that we don't switch per-pixel or per-component - if (depth < 8 || img_n == out_n) { - int nk = (width - 1)*filter_bytes; - #define STBI__CASE(f) \ - case f: \ - for (k=0; k < nk; ++k) - switch (filter) { - // "none" filter turns into a memcpy here; make that explicit. - case STBI__F_none: memcpy(cur, raw, nk); break; - STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break; - STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; - STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break; - STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break; - STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break; - STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break; - } - #undef STBI__CASE - raw += nk; - } else { - STBI_ASSERT(img_n+1 == out_n); - #define STBI__CASE(f) \ - case f: \ - for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ - for (k=0; k < filter_bytes; ++k) - switch (filter) { - STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; - STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break; - STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; - STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break; - STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break; - STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break; - STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break; - } - #undef STBI__CASE - - // the loop above sets the high byte of the pixels' alpha, but for - // 16 bit png files we also need the low byte set. we'll do that here. - if (depth == 16) { - cur = a->out + stride*j; // start at the beginning of the row again - for (i=0; i < x; ++i,cur+=output_bytes) { - cur[filter_bytes+1] = 255; - } - } - } - } - - // we make a separate pass to expand bits to pixels; for performance, - // this could run two scanlines behind the above code, so it won't - // intefere with filtering but will still be in the cache. - if (depth < 8) { - for (j=0; j < y; ++j) { - stbi_uc *cur = a->out + stride*j; - stbi_uc *in = a->out + stride*j + x*out_n - img_width_bytes; - // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit - // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop - stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range - - // note that the final byte might overshoot and write more data than desired. - // we can allocate enough data that this never writes out of memory, but it - // could also overwrite the next scanline. can it overwrite non-empty data - // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. - // so we need to explicitly clamp the final ones - - if (depth == 4) { - for (k=x*img_n; k >= 2; k-=2, ++in) { - *cur++ = scale * ((*in >> 4) ); - *cur++ = scale * ((*in ) & 0x0f); - } - if (k > 0) *cur++ = scale * ((*in >> 4) ); - } else if (depth == 2) { - for (k=x*img_n; k >= 4; k-=4, ++in) { - *cur++ = scale * ((*in >> 6) ); - *cur++ = scale * ((*in >> 4) & 0x03); - *cur++ = scale * ((*in >> 2) & 0x03); - *cur++ = scale * ((*in ) & 0x03); - } - if (k > 0) *cur++ = scale * ((*in >> 6) ); - if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); - if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); - } else if (depth == 1) { - for (k=x*img_n; k >= 8; k-=8, ++in) { - *cur++ = scale * ((*in >> 7) ); - *cur++ = scale * ((*in >> 6) & 0x01); - *cur++ = scale * ((*in >> 5) & 0x01); - *cur++ = scale * ((*in >> 4) & 0x01); - *cur++ = scale * ((*in >> 3) & 0x01); - *cur++ = scale * ((*in >> 2) & 0x01); - *cur++ = scale * ((*in >> 1) & 0x01); - *cur++ = scale * ((*in ) & 0x01); - } - if (k > 0) *cur++ = scale * ((*in >> 7) ); - if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); - if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); - if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); - if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); - if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); - if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); - } - if (img_n != out_n) { - int q; - // insert alpha = 255 - cur = a->out + stride*j; - if (img_n == 1) { - for (q=x-1; q >= 0; --q) { - cur[q*2+1] = 255; - cur[q*2+0] = cur[q]; - } - } else { - STBI_ASSERT(img_n == 3); - for (q=x-1; q >= 0; --q) { - cur[q*4+3] = 255; - cur[q*4+2] = cur[q*3+2]; - cur[q*4+1] = cur[q*3+1]; - cur[q*4+0] = cur[q*3+0]; - } - } - } - } - } else if (depth == 16) { - // force the image data from big-endian to platform-native. - // this is done in a separate pass due to the decoding relying - // on the data being untouched, but could probably be done - // per-line during decode if care is taken. - stbi_uc *cur = a->out; - stbi__uint16 *cur16 = (stbi__uint16*)cur; - - for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) { - *cur16 = (cur[0] << 8) | cur[1]; - } - } - - return 1; -} - -static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) -{ - int bytes = (depth == 16 ? 2 : 1); - int out_bytes = out_n * bytes; - stbi_uc *final; - int p; - if (!interlaced) - return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); - - // de-interlacing - final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); - for (p=0; p < 7; ++p) { - int xorig[] = { 0,4,0,2,0,1,0 }; - int yorig[] = { 0,0,4,0,2,0,1 }; - int xspc[] = { 8,8,4,4,2,2,1 }; - int yspc[] = { 8,8,8,4,4,2,2 }; - int i,j,x,y; - // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 - x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; - y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; - if (x && y) { - stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; - if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { - STBI_FREE(final); - return 0; - } - for (j=0; j < y; ++j) { - for (i=0; i < x; ++i) { - int out_y = j*yspc[p]+yorig[p]; - int out_x = i*xspc[p]+xorig[p]; - memcpy(final + out_y*a->s->img_x*out_bytes + out_x*out_bytes, - a->out + (j*x+i)*out_bytes, out_bytes); - } - } - STBI_FREE(a->out); - a->out = NULL; - image_data += img_len; - image_data_len -= img_len; - } - } - a->out = final; - - return 1; -} - -static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n) -{ - stbi__context *s = z->s; - stbi__uint32 i, pixel_count = s->img_x * s->img_y; - stbi_uc *p = z->out; - - // compute color-based transparency, assuming we've - // already got 255 as the alpha value in the output - STBI_ASSERT(out_n == 2 || out_n == 4); - - if (out_n == 2) { - for (i=0; i < pixel_count; ++i) { - p[1] = (p[0] == tc[0] ? 0 : 255); - p += 2; - } - } else { - for (i=0; i < pixel_count; ++i) { - if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) - p[3] = 0; - p += 4; - } - } - return 1; -} - -static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n) -{ - stbi__context *s = z->s; - stbi__uint32 i, pixel_count = s->img_x * s->img_y; - stbi__uint16 *p = (stbi__uint16*) z->out; - - // compute color-based transparency, assuming we've - // already got 65535 as the alpha value in the output - STBI_ASSERT(out_n == 2 || out_n == 4); - - if (out_n == 2) { - for (i = 0; i < pixel_count; ++i) { - p[1] = (p[0] == tc[0] ? 0 : 65535); - p += 2; - } - } else { - for (i = 0; i < pixel_count; ++i) { - if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) - p[3] = 0; - p += 4; - } - } - return 1; -} - -static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n) -{ - stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; - stbi_uc *p, *temp_out, *orig = a->out; - - p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0); - if (p == NULL) return stbi__err("outofmem", "Out of memory"); - - // between here and free(out) below, exitting would leak - temp_out = p; - - if (pal_img_n == 3) { - for (i=0; i < pixel_count; ++i) { - int n = orig[i]*4; - p[0] = palette[n ]; - p[1] = palette[n+1]; - p[2] = palette[n+2]; - p += 3; - } - } else { - for (i=0; i < pixel_count; ++i) { - int n = orig[i]*4; - p[0] = palette[n ]; - p[1] = palette[n+1]; - p[2] = palette[n+2]; - p[3] = palette[n+3]; - p += 4; - } - } - STBI_FREE(a->out); - a->out = temp_out; - - STBI_NOTUSED(len); - - return 1; -} - -static int stbi__unpremultiply_on_load = 0; -static int stbi__de_iphone_flag = 0; - -STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) -{ - stbi__unpremultiply_on_load = flag_true_if_should_unpremultiply; -} - -STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) -{ - stbi__de_iphone_flag = flag_true_if_should_convert; -} - -static void stbi__de_iphone(stbi__png *z) -{ - stbi__context *s = z->s; - stbi__uint32 i, pixel_count = s->img_x * s->img_y; - stbi_uc *p = z->out; - - if (s->img_out_n == 3) { // convert bgr to rgb - for (i=0; i < pixel_count; ++i) { - stbi_uc t = p[0]; - p[0] = p[2]; - p[2] = t; - p += 3; - } - } else { - STBI_ASSERT(s->img_out_n == 4); - if (stbi__unpremultiply_on_load) { - // convert bgr to rgb and unpremultiply - for (i=0; i < pixel_count; ++i) { - stbi_uc a = p[3]; - stbi_uc t = p[0]; - if (a) { - stbi_uc half = a / 2; - p[0] = (p[2] * 255 + half) / a; - p[1] = (p[1] * 255 + half) / a; - p[2] = ( t * 255 + half) / a; - } else { - p[0] = p[2]; - p[2] = t; - } - p += 4; - } - } else { - // convert bgr to rgb - for (i=0; i < pixel_count; ++i) { - stbi_uc t = p[0]; - p[0] = p[2]; - p[2] = t; - p += 4; - } - } - } -} - -#define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) - -static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) -{ - stbi_uc palette[1024], pal_img_n=0; - stbi_uc has_trans=0, tc[3]; - stbi__uint16 tc16[3]; - stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0; - int first=1,k,interlace=0, color=0, is_iphone=0; - stbi__context *s = z->s; - - z->expanded = NULL; - z->idata = NULL; - z->out = NULL; - - if (!stbi__check_png_header(s)) return 0; - - if (scan == STBI__SCAN_type) return 1; - - for (;;) { - stbi__pngchunk c = stbi__get_chunk_header(s); - switch (c.type) { - case STBI__PNG_TYPE('C','g','B','I'): - is_iphone = 1; - stbi__skip(s, c.length); - break; - case STBI__PNG_TYPE('I','H','D','R'): { - int comp,filter; - if (!first) return stbi__err("multiple IHDR","Corrupt PNG"); - first = 0; - if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG"); - s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); - s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); - z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only"); - color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); - if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); - if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG"); - comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG"); - filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG"); - interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG"); - if (!s->img_x || !s->img_y) return stbi__err("0-pixel image","Corrupt PNG"); - if (!pal_img_n) { - s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); - if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); - if (scan == STBI__SCAN_header) return 1; - } else { - // if paletted, then pal_n is our final components, and - // img_n is # components to decompress/filter. - s->img_n = 1; - if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG"); - // if SCAN_header, have to scan to see if we have a tRNS - } - break; - } - - case STBI__PNG_TYPE('P','L','T','E'): { - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG"); - pal_len = c.length / 3; - if (pal_len * 3 != c.length) return stbi__err("invalid PLTE","Corrupt PNG"); - for (i=0; i < pal_len; ++i) { - palette[i*4+0] = stbi__get8(s); - palette[i*4+1] = stbi__get8(s); - palette[i*4+2] = stbi__get8(s); - palette[i*4+3] = 255; - } - break; - } - - case STBI__PNG_TYPE('t','R','N','S'): { - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (z->idata) return stbi__err("tRNS after IDAT","Corrupt PNG"); - if (pal_img_n) { - if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } - if (pal_len == 0) return stbi__err("tRNS before PLTE","Corrupt PNG"); - if (c.length > pal_len) return stbi__err("bad tRNS len","Corrupt PNG"); - pal_img_n = 4; - for (i=0; i < c.length; ++i) - palette[i*4+3] = stbi__get8(s); - } else { - if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG"); - if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG"); - has_trans = 1; - if (z->depth == 16) { - for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is - } else { - for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger - } - } - break; - } - - case STBI__PNG_TYPE('I','D','A','T'): { - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG"); - if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; } - if ((int)(ioff + c.length) < (int)ioff) return 0; - if (ioff + c.length > idata_limit) { - stbi__uint32 idata_limit_old = idata_limit; - stbi_uc *p; - if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; - while (ioff + c.length > idata_limit) - idata_limit *= 2; - STBI_NOTUSED(idata_limit_old); - p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); - z->idata = p; - } - if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG"); - ioff += c.length; - break; - } - - case STBI__PNG_TYPE('I','E','N','D'): { - stbi__uint32 raw_len, bpl; - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if (scan != STBI__SCAN_load) return 1; - if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG"); - // initial guess for decoded data size to avoid unnecessary reallocs - bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component - raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; - z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone); - if (z->expanded == NULL) return 0; // zlib should set error - STBI_FREE(z->idata); z->idata = NULL; - if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) - s->img_out_n = s->img_n+1; - else - s->img_out_n = s->img_n; - if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; - if (has_trans) { - if (z->depth == 16) { - if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; - } else { - if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; - } - } - if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) - stbi__de_iphone(z); - if (pal_img_n) { - // pal_img_n == 3 or 4 - s->img_n = pal_img_n; // record the actual colors we had - s->img_out_n = pal_img_n; - if (req_comp >= 3) s->img_out_n = req_comp; - if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) - return 0; - } else if (has_trans) { - // non-paletted image with tRNS -> source image has (constant) alpha - ++s->img_n; - } - STBI_FREE(z->expanded); z->expanded = NULL; - return 1; - } - - default: - // if critical, fail - if (first) return stbi__err("first not IHDR", "Corrupt PNG"); - if ((c.type & (1 << 29)) == 0) { - #ifndef STBI_NO_FAILURE_STRINGS - // not threadsafe - static char invalid_chunk[] = "XXXX PNG chunk not known"; - invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); - invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); - invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); - invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); - #endif - return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); - } - stbi__skip(s, c.length); - break; - } - // end of PNG chunk, read and skip CRC - stbi__get32be(s); - } -} - -static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri) -{ - void *result=NULL; - if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); - if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { - if (p->depth < 8) - ri->bits_per_channel = 8; - else - ri->bits_per_channel = p->depth; - result = p->out; - p->out = NULL; - if (req_comp && req_comp != p->s->img_out_n) { - if (ri->bits_per_channel == 8) - result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); - else - result = stbi__convert_format16((stbi__uint16 *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); - p->s->img_out_n = req_comp; - if (result == NULL) return result; - } - *x = p->s->img_x; - *y = p->s->img_y; - if (n) *n = p->s->img_n; - } - STBI_FREE(p->out); p->out = NULL; - STBI_FREE(p->expanded); p->expanded = NULL; - STBI_FREE(p->idata); p->idata = NULL; - - return result; -} - -static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) -{ - stbi__png p; - p.s = s; - return stbi__do_png(&p, x,y,comp,req_comp, ri); -} - -static int stbi__png_test(stbi__context *s) -{ - int r; - r = stbi__check_png_header(s); - stbi__rewind(s); - return r; -} - -static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp) -{ - if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { - stbi__rewind( p->s ); - return 0; - } - if (x) *x = p->s->img_x; - if (y) *y = p->s->img_y; - if (comp) *comp = p->s->img_n; - return 1; -} - -static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp) -{ - stbi__png p; - p.s = s; - return stbi__png_info_raw(&p, x, y, comp); -} - -static int stbi__png_is16(stbi__context *s) -{ - stbi__png p; - p.s = s; - if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) - return 0; - if (p.depth != 16) { - stbi__rewind(p.s); - return 0; - } - return 1; -} -#endif - -// Microsoft/Windows BMP image - -#ifndef STBI_NO_BMP -static int stbi__bmp_test_raw(stbi__context *s) -{ - int r; - int sz; - if (stbi__get8(s) != 'B') return 0; - if (stbi__get8(s) != 'M') return 0; - stbi__get32le(s); // discard filesize - stbi__get16le(s); // discard reserved - stbi__get16le(s); // discard reserved - stbi__get32le(s); // discard data offset - sz = stbi__get32le(s); - r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); - return r; -} - -static int stbi__bmp_test(stbi__context *s) -{ - int r = stbi__bmp_test_raw(s); - stbi__rewind(s); - return r; -} - - -// returns 0..31 for the highest set bit -static int stbi__high_bit(unsigned int z) -{ - int n=0; - if (z == 0) return -1; - if (z >= 0x10000) n += 16, z >>= 16; - if (z >= 0x00100) n += 8, z >>= 8; - if (z >= 0x00010) n += 4, z >>= 4; - if (z >= 0x00004) n += 2, z >>= 2; - if (z >= 0x00002) n += 1, z >>= 1; - return n; -} - -static int stbi__bitcount(unsigned int a) -{ - a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 - a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 - a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits - a = (a + (a >> 8)); // max 16 per 8 bits - a = (a + (a >> 16)); // max 32 per 8 bits - return a & 0xff; -} - -// extract an arbitrarily-aligned N-bit value (N=bits) -// from v, and then make it 8-bits long and fractionally -// extend it to full full range. -static int stbi__shiftsigned(int v, int shift, int bits) -{ - static unsigned int mul_table[9] = { - 0, - 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, - 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, - }; - static unsigned int shift_table[9] = { - 0, 0,0,1,0,2,4,6,0, - }; - if (shift < 0) - v <<= -shift; - else - v >>= shift; - STBI_ASSERT(v >= 0 && v < 256); - v >>= (8-bits); - STBI_ASSERT(bits >= 0 && bits <= 8); - return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits]; -} - -typedef struct -{ - int bpp, offset, hsz; - unsigned int mr,mg,mb,ma, all_a; -} stbi__bmp_data; - -static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) -{ - int hsz; - if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); - stbi__get32le(s); // discard filesize - stbi__get16le(s); // discard reserved - stbi__get16le(s); // discard reserved - info->offset = stbi__get32le(s); - info->hsz = hsz = stbi__get32le(s); - info->mr = info->mg = info->mb = info->ma = 0; - - if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); - if (hsz == 12) { - s->img_x = stbi__get16le(s); - s->img_y = stbi__get16le(s); - } else { - s->img_x = stbi__get32le(s); - s->img_y = stbi__get32le(s); - } - if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); - info->bpp = stbi__get16le(s); - if (hsz != 12) { - int compress = stbi__get32le(s); - if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); - stbi__get32le(s); // discard sizeof - stbi__get32le(s); // discard hres - stbi__get32le(s); // discard vres - stbi__get32le(s); // discard colorsused - stbi__get32le(s); // discard max important - if (hsz == 40 || hsz == 56) { - if (hsz == 56) { - stbi__get32le(s); - stbi__get32le(s); - stbi__get32le(s); - stbi__get32le(s); - } - if (info->bpp == 16 || info->bpp == 32) { - if (compress == 0) { - if (info->bpp == 32) { - info->mr = 0xffu << 16; - info->mg = 0xffu << 8; - info->mb = 0xffu << 0; - info->ma = 0xffu << 24; - info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 - } else { - info->mr = 31u << 10; - info->mg = 31u << 5; - info->mb = 31u << 0; - } - } else if (compress == 3) { - info->mr = stbi__get32le(s); - info->mg = stbi__get32le(s); - info->mb = stbi__get32le(s); - // not documented, but generated by photoshop and handled by mspaint - if (info->mr == info->mg && info->mg == info->mb) { - // ?!?!? - return stbi__errpuc("bad BMP", "bad BMP"); - } - } else - return stbi__errpuc("bad BMP", "bad BMP"); - } - } else { - int i; - if (hsz != 108 && hsz != 124) - return stbi__errpuc("bad BMP", "bad BMP"); - info->mr = stbi__get32le(s); - info->mg = stbi__get32le(s); - info->mb = stbi__get32le(s); - info->ma = stbi__get32le(s); - stbi__get32le(s); // discard color space - for (i=0; i < 12; ++i) - stbi__get32le(s); // discard color space parameters - if (hsz == 124) { - stbi__get32le(s); // discard rendering intent - stbi__get32le(s); // discard offset of profile data - stbi__get32le(s); // discard size of profile data - stbi__get32le(s); // discard reserved - } - } - } - return (void *) 1; -} - - -static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) -{ - stbi_uc *out; - unsigned int mr=0,mg=0,mb=0,ma=0, all_a; - stbi_uc pal[256][4]; - int psize=0,i,j,width; - int flip_vertically, pad, target; - stbi__bmp_data info; - STBI_NOTUSED(ri); - - info.all_a = 255; - if (stbi__bmp_parse_header(s, &info) == NULL) - return NULL; // error code already set - - flip_vertically = ((int) s->img_y) > 0; - s->img_y = abs((int) s->img_y); - - mr = info.mr; - mg = info.mg; - mb = info.mb; - ma = info.ma; - all_a = info.all_a; - - if (info.hsz == 12) { - if (info.bpp < 24) - psize = (info.offset - 14 - 24) / 3; - } else { - if (info.bpp < 16) - psize = (info.offset - 14 - info.hsz) >> 2; - } - - s->img_n = ma ? 4 : 3; - if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 - target = req_comp; - else - target = s->img_n; // if they want monochrome, we'll post-convert - - // sanity-check size - if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) - return stbi__errpuc("too large", "Corrupt BMP"); - - out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0); - if (!out) return stbi__errpuc("outofmem", "Out of memory"); - if (info.bpp < 16) { - int z=0; - if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } - for (i=0; i < psize; ++i) { - pal[i][2] = stbi__get8(s); - pal[i][1] = stbi__get8(s); - pal[i][0] = stbi__get8(s); - if (info.hsz != 12) stbi__get8(s); - pal[i][3] = 255; - } - stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); - if (info.bpp == 1) width = (s->img_x + 7) >> 3; - else if (info.bpp == 4) width = (s->img_x + 1) >> 1; - else if (info.bpp == 8) width = s->img_x; - else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } - pad = (-width)&3; - if (info.bpp == 1) { - for (j=0; j < (int) s->img_y; ++j) { - int bit_offset = 7, v = stbi__get8(s); - for (i=0; i < (int) s->img_x; ++i) { - int color = (v>>bit_offset)&0x1; - out[z++] = pal[color][0]; - out[z++] = pal[color][1]; - out[z++] = pal[color][2]; - if((--bit_offset) < 0) { - bit_offset = 7; - v = stbi__get8(s); - } - } - stbi__skip(s, pad); - } - } else { - for (j=0; j < (int) s->img_y; ++j) { - for (i=0; i < (int) s->img_x; i += 2) { - int v=stbi__get8(s),v2=0; - if (info.bpp == 4) { - v2 = v & 15; - v >>= 4; - } - out[z++] = pal[v][0]; - out[z++] = pal[v][1]; - out[z++] = pal[v][2]; - if (target == 4) out[z++] = 255; - if (i+1 == (int) s->img_x) break; - v = (info.bpp == 8) ? stbi__get8(s) : v2; - out[z++] = pal[v][0]; - out[z++] = pal[v][1]; - out[z++] = pal[v][2]; - if (target == 4) out[z++] = 255; - } - stbi__skip(s, pad); - } - } - } else { - int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; - int z = 0; - int easy=0; - stbi__skip(s, info.offset - 14 - info.hsz); - if (info.bpp == 24) width = 3 * s->img_x; - else if (info.bpp == 16) width = 2*s->img_x; - else /* bpp = 32 and pad = 0 */ width=0; - pad = (-width) & 3; - if (info.bpp == 24) { - easy = 1; - } else if (info.bpp == 32) { - if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) - easy = 2; - } - if (!easy) { - if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } - // right shift amt to put high bit in position #7 - rshift = stbi__high_bit(mr)-7; rcount = stbi__bitcount(mr); - gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg); - bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb); - ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma); - } - for (j=0; j < (int) s->img_y; ++j) { - if (easy) { - for (i=0; i < (int) s->img_x; ++i) { - unsigned char a; - out[z+2] = stbi__get8(s); - out[z+1] = stbi__get8(s); - out[z+0] = stbi__get8(s); - z += 3; - a = (easy == 2 ? stbi__get8(s) : 255); - all_a |= a; - if (target == 4) out[z++] = a; - } - } else { - int bpp = info.bpp; - for (i=0; i < (int) s->img_x; ++i) { - stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s)); - unsigned int a; - out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); - out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); - out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); - a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); - all_a |= a; - if (target == 4) out[z++] = STBI__BYTECAST(a); - } - } - stbi__skip(s, pad); - } - } - - // if alpha channel is all 0s, replace with all 255s - if (target == 4 && all_a == 0) - for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4) - out[i] = 255; - - if (flip_vertically) { - stbi_uc t; - for (j=0; j < (int) s->img_y>>1; ++j) { - stbi_uc *p1 = out + j *s->img_x*target; - stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; - for (i=0; i < (int) s->img_x*target; ++i) { - t = p1[i], p1[i] = p2[i], p2[i] = t; - } - } - } - - if (req_comp && req_comp != target) { - out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); - if (out == NULL) return out; // stbi__convert_format frees input on failure - } - - *x = s->img_x; - *y = s->img_y; - if (comp) *comp = s->img_n; - return out; -} -#endif - -// Targa Truevision - TGA -// by Jonathan Dummer -#ifndef STBI_NO_TGA -// returns STBI_rgb or whatever, 0 on error -static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) -{ - // only RGB or RGBA (incl. 16bit) or grey allowed - if (is_rgb16) *is_rgb16 = 0; - switch(bits_per_pixel) { - case 8: return STBI_grey; - case 16: if(is_grey) return STBI_grey_alpha; - // fallthrough - case 15: if(is_rgb16) *is_rgb16 = 1; - return STBI_rgb; - case 24: // fallthrough - case 32: return bits_per_pixel/8; - default: return 0; - } -} - -static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) -{ - int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; - int sz, tga_colormap_type; - stbi__get8(s); // discard Offset - tga_colormap_type = stbi__get8(s); // colormap type - if( tga_colormap_type > 1 ) { - stbi__rewind(s); - return 0; // only RGB or indexed allowed - } - tga_image_type = stbi__get8(s); // image type - if ( tga_colormap_type == 1 ) { // colormapped (paletted) image - if (tga_image_type != 1 && tga_image_type != 9) { - stbi__rewind(s); - return 0; - } - stbi__skip(s,4); // skip index of first colormap entry and number of entries - sz = stbi__get8(s); // check bits per palette color entry - if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) { - stbi__rewind(s); - return 0; - } - stbi__skip(s,4); // skip image x and y origin - tga_colormap_bpp = sz; - } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE - if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) { - stbi__rewind(s); - return 0; // only RGB or grey allowed, +/- RLE - } - stbi__skip(s,9); // skip colormap specification and image x/y origin - tga_colormap_bpp = 0; - } - tga_w = stbi__get16le(s); - if( tga_w < 1 ) { - stbi__rewind(s); - return 0; // test width - } - tga_h = stbi__get16le(s); - if( tga_h < 1 ) { - stbi__rewind(s); - return 0; // test height - } - tga_bits_per_pixel = stbi__get8(s); // bits per pixel - stbi__get8(s); // ignore alpha bits - if (tga_colormap_bpp != 0) { - if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { - // when using a colormap, tga_bits_per_pixel is the size of the indexes - // I don't think anything but 8 or 16bit indexes makes sense - stbi__rewind(s); - return 0; - } - tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); - } else { - tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); - } - if(!tga_comp) { - stbi__rewind(s); - return 0; - } - if (x) *x = tga_w; - if (y) *y = tga_h; - if (comp) *comp = tga_comp; - return 1; // seems to have passed everything -} - -static int stbi__tga_test(stbi__context *s) -{ - int res = 0; - int sz, tga_color_type; - stbi__get8(s); // discard Offset - tga_color_type = stbi__get8(s); // color type - if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed - sz = stbi__get8(s); // image type - if ( tga_color_type == 1 ) { // colormapped (paletted) image - if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 - stbi__skip(s,4); // skip index of first colormap entry and number of entries - sz = stbi__get8(s); // check bits per palette color entry - if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; - stbi__skip(s,4); // skip image x and y origin - } else { // "normal" image w/o colormap - if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE - stbi__skip(s,9); // skip colormap specification and image x/y origin - } - if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width - if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height - sz = stbi__get8(s); // bits per pixel - if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index - if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; - - res = 1; // if we got this far, everything's good and we can return 1 instead of 0 - -errorEnd: - stbi__rewind(s); - return res; -} - -// read 16bit value and convert to 24bit RGB -static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) -{ - stbi__uint16 px = (stbi__uint16)stbi__get16le(s); - stbi__uint16 fiveBitMask = 31; - // we have 3 channels with 5bits each - int r = (px >> 10) & fiveBitMask; - int g = (px >> 5) & fiveBitMask; - int b = px & fiveBitMask; - // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later - out[0] = (stbi_uc)((r * 255)/31); - out[1] = (stbi_uc)((g * 255)/31); - out[2] = (stbi_uc)((b * 255)/31); - - // some people claim that the most significant bit might be used for alpha - // (possibly if an alpha-bit is set in the "image descriptor byte") - // but that only made 16bit test images completely translucent.. - // so let's treat all 15 and 16bit TGAs as RGB with no alpha. -} - -static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) -{ - // read in the TGA header stuff - int tga_offset = stbi__get8(s); - int tga_indexed = stbi__get8(s); - int tga_image_type = stbi__get8(s); - int tga_is_RLE = 0; - int tga_palette_start = stbi__get16le(s); - int tga_palette_len = stbi__get16le(s); - int tga_palette_bits = stbi__get8(s); - int tga_x_origin = stbi__get16le(s); - int tga_y_origin = stbi__get16le(s); - int tga_width = stbi__get16le(s); - int tga_height = stbi__get16le(s); - int tga_bits_per_pixel = stbi__get8(s); - int tga_comp, tga_rgb16=0; - int tga_inverted = stbi__get8(s); - // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) - // image data - unsigned char *tga_data; - unsigned char *tga_palette = NULL; - int i, j; - unsigned char raw_data[4] = {0}; - int RLE_count = 0; - int RLE_repeating = 0; - int read_next_pixel = 1; - STBI_NOTUSED(ri); - - // do a tiny bit of precessing - if ( tga_image_type >= 8 ) - { - tga_image_type -= 8; - tga_is_RLE = 1; - } - tga_inverted = 1 - ((tga_inverted >> 5) & 1); - - // If I'm paletted, then I'll use the number of bits from the palette - if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); - else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); - - if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency - return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); - - // tga info - *x = tga_width; - *y = tga_height; - if (comp) *comp = tga_comp; - - if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) - return stbi__errpuc("too large", "Corrupt TGA"); - - tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); - if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); - - // skip to the data's starting position (offset usually = 0) - stbi__skip(s, tga_offset ); - - if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) { - for (i=0; i < tga_height; ++i) { - int row = tga_inverted ? tga_height -i - 1 : i; - stbi_uc *tga_row = tga_data + row*tga_width*tga_comp; - stbi__getn(s, tga_row, tga_width * tga_comp); - } - } else { - // do I need to load a palette? - if ( tga_indexed) - { - // any data to skip? (offset usually = 0) - stbi__skip(s, tga_palette_start ); - // load the palette - tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); - if (!tga_palette) { - STBI_FREE(tga_data); - return stbi__errpuc("outofmem", "Out of memory"); - } - if (tga_rgb16) { - stbi_uc *pal_entry = tga_palette; - STBI_ASSERT(tga_comp == STBI_rgb); - for (i=0; i < tga_palette_len; ++i) { - stbi__tga_read_rgb16(s, pal_entry); - pal_entry += tga_comp; - } - } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { - STBI_FREE(tga_data); - STBI_FREE(tga_palette); - return stbi__errpuc("bad palette", "Corrupt TGA"); - } - } - // load the data - for (i=0; i < tga_width * tga_height; ++i) - { - // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? - if ( tga_is_RLE ) - { - if ( RLE_count == 0 ) - { - // yep, get the next byte as a RLE command - int RLE_cmd = stbi__get8(s); - RLE_count = 1 + (RLE_cmd & 127); - RLE_repeating = RLE_cmd >> 7; - read_next_pixel = 1; - } else if ( !RLE_repeating ) - { - read_next_pixel = 1; - } - } else - { - read_next_pixel = 1; - } - // OK, if I need to read a pixel, do it now - if ( read_next_pixel ) - { - // load however much data we did have - if ( tga_indexed ) - { - // read in index, then perform the lookup - int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); - if ( pal_idx >= tga_palette_len ) { - // invalid index - pal_idx = 0; - } - pal_idx *= tga_comp; - for (j = 0; j < tga_comp; ++j) { - raw_data[j] = tga_palette[pal_idx+j]; - } - } else if(tga_rgb16) { - STBI_ASSERT(tga_comp == STBI_rgb); - stbi__tga_read_rgb16(s, raw_data); - } else { - // read in the data raw - for (j = 0; j < tga_comp; ++j) { - raw_data[j] = stbi__get8(s); - } - } - // clear the reading flag for the next pixel - read_next_pixel = 0; - } // end of reading a pixel - - // copy data - for (j = 0; j < tga_comp; ++j) - tga_data[i*tga_comp+j] = raw_data[j]; - - // in case we're in RLE mode, keep counting down - --RLE_count; - } - // do I need to invert the image? - if ( tga_inverted ) - { - for (j = 0; j*2 < tga_height; ++j) - { - int index1 = j * tga_width * tga_comp; - int index2 = (tga_height - 1 - j) * tga_width * tga_comp; - for (i = tga_width * tga_comp; i > 0; --i) - { - unsigned char temp = tga_data[index1]; - tga_data[index1] = tga_data[index2]; - tga_data[index2] = temp; - ++index1; - ++index2; - } - } - } - // clear my palette, if I had one - if ( tga_palette != NULL ) - { - STBI_FREE( tga_palette ); - } - } - - // swap RGB - if the source data was RGB16, it already is in the right order - if (tga_comp >= 3 && !tga_rgb16) - { - unsigned char* tga_pixel = tga_data; - for (i=0; i < tga_width * tga_height; ++i) - { - unsigned char temp = tga_pixel[0]; - tga_pixel[0] = tga_pixel[2]; - tga_pixel[2] = temp; - tga_pixel += tga_comp; - } - } - - // convert to target component count - if (req_comp && req_comp != tga_comp) - tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); - - // the things I do to get rid of an error message, and yet keep - // Microsoft's C compilers happy... [8^( - tga_palette_start = tga_palette_len = tga_palette_bits = - tga_x_origin = tga_y_origin = 0; - // OK, done - return tga_data; -} -#endif - -// ************************************************************************************************* -// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB - -#ifndef STBI_NO_PSD -static int stbi__psd_test(stbi__context *s) -{ - int r = (stbi__get32be(s) == 0x38425053); - stbi__rewind(s); - return r; -} - -static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount) -{ - int count, nleft, len; - - count = 0; - while ((nleft = pixelCount - count) > 0) { - len = stbi__get8(s); - if (len == 128) { - // No-op. - } else if (len < 128) { - // Copy next len+1 bytes literally. - len++; - if (len > nleft) return 0; // corrupt data - count += len; - while (len) { - *p = stbi__get8(s); - p += 4; - len--; - } - } else if (len > 128) { - stbi_uc val; - // Next -len+1 bytes in the dest are replicated from next source byte. - // (Interpret len as a negative 8-bit int.) - len = 257 - len; - if (len > nleft) return 0; // corrupt data - val = stbi__get8(s); - count += len; - while (len) { - *p = val; - p += 4; - len--; - } - } - } - - return 1; -} - -static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) -{ - int pixelCount; - int channelCount, compression; - int channel, i; - int bitdepth; - int w,h; - stbi_uc *out; - STBI_NOTUSED(ri); - - // Check identifier - if (stbi__get32be(s) != 0x38425053) // "8BPS" - return stbi__errpuc("not PSD", "Corrupt PSD image"); - - // Check file type version. - if (stbi__get16be(s) != 1) - return stbi__errpuc("wrong version", "Unsupported version of PSD image"); - - // Skip 6 reserved bytes. - stbi__skip(s, 6 ); - - // Read the number of channels (R, G, B, A, etc). - channelCount = stbi__get16be(s); - if (channelCount < 0 || channelCount > 16) - return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); - - // Read the rows and columns of the image. - h = stbi__get32be(s); - w = stbi__get32be(s); - - // Make sure the depth is 8 bits. - bitdepth = stbi__get16be(s); - if (bitdepth != 8 && bitdepth != 16) - return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); - - // Make sure the color mode is RGB. - // Valid options are: - // 0: Bitmap - // 1: Grayscale - // 2: Indexed color - // 3: RGB color - // 4: CMYK color - // 7: Multichannel - // 8: Duotone - // 9: Lab color - if (stbi__get16be(s) != 3) - return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); - - // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) - stbi__skip(s,stbi__get32be(s) ); - - // Skip the image resources. (resolution, pen tool paths, etc) - stbi__skip(s, stbi__get32be(s) ); - - // Skip the reserved data. - stbi__skip(s, stbi__get32be(s) ); - - // Find out if the data is compressed. - // Known values: - // 0: no compression - // 1: RLE compressed - compression = stbi__get16be(s); - if (compression > 1) - return stbi__errpuc("bad compression", "PSD has an unknown compression format"); - - // Check size - if (!stbi__mad3sizes_valid(4, w, h, 0)) - return stbi__errpuc("too large", "Corrupt PSD"); - - // Create the destination image. - - if (!compression && bitdepth == 16 && bpc == 16) { - out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0); - ri->bits_per_channel = 16; - } else - out = (stbi_uc *) stbi__malloc(4 * w*h); - - if (!out) return stbi__errpuc("outofmem", "Out of memory"); - pixelCount = w*h; - - // Initialize the data to zero. - //memset( out, 0, pixelCount * 4 ); - - // Finally, the image data. - if (compression) { - // RLE as used by .PSD and .TIFF - // Loop until you get the number of unpacked bytes you are expecting: - // Read the next source byte into n. - // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. - // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. - // Else if n is 128, noop. - // Endloop - - // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data, - // which we're going to just skip. - stbi__skip(s, h * channelCount * 2 ); - - // Read the RLE data by channel. - for (channel = 0; channel < 4; channel++) { - stbi_uc *p; - - p = out+channel; - if (channel >= channelCount) { - // Fill this channel with default data. - for (i = 0; i < pixelCount; i++, p += 4) - *p = (channel == 3 ? 255 : 0); - } else { - // Read the RLE data. - if (!stbi__psd_decode_rle(s, p, pixelCount)) { - STBI_FREE(out); - return stbi__errpuc("corrupt", "bad RLE data"); - } - } - } - - } else { - // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) - // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. - - // Read the data by channel. - for (channel = 0; channel < 4; channel++) { - if (channel >= channelCount) { - // Fill this channel with default data. - if (bitdepth == 16 && bpc == 16) { - stbi__uint16 *q = ((stbi__uint16 *) out) + channel; - stbi__uint16 val = channel == 3 ? 65535 : 0; - for (i = 0; i < pixelCount; i++, q += 4) - *q = val; - } else { - stbi_uc *p = out+channel; - stbi_uc val = channel == 3 ? 255 : 0; - for (i = 0; i < pixelCount; i++, p += 4) - *p = val; - } - } else { - if (ri->bits_per_channel == 16) { // output bpc - stbi__uint16 *q = ((stbi__uint16 *) out) + channel; - for (i = 0; i < pixelCount; i++, q += 4) - *q = (stbi__uint16) stbi__get16be(s); - } else { - stbi_uc *p = out+channel; - if (bitdepth == 16) { // input bpc - for (i = 0; i < pixelCount; i++, p += 4) - *p = (stbi_uc) (stbi__get16be(s) >> 8); - } else { - for (i = 0; i < pixelCount; i++, p += 4) - *p = stbi__get8(s); - } - } - } - } - } - - // remove weird white matte from PSD - if (channelCount >= 4) { - if (ri->bits_per_channel == 16) { - for (i=0; i < w*h; ++i) { - stbi__uint16 *pixel = (stbi__uint16 *) out + 4*i; - if (pixel[3] != 0 && pixel[3] != 65535) { - float a = pixel[3] / 65535.0f; - float ra = 1.0f / a; - float inv_a = 65535.0f * (1 - ra); - pixel[0] = (stbi__uint16) (pixel[0]*ra + inv_a); - pixel[1] = (stbi__uint16) (pixel[1]*ra + inv_a); - pixel[2] = (stbi__uint16) (pixel[2]*ra + inv_a); - } - } - } else { - for (i=0; i < w*h; ++i) { - unsigned char *pixel = out + 4*i; - if (pixel[3] != 0 && pixel[3] != 255) { - float a = pixel[3] / 255.0f; - float ra = 1.0f / a; - float inv_a = 255.0f * (1 - ra); - pixel[0] = (unsigned char) (pixel[0]*ra + inv_a); - pixel[1] = (unsigned char) (pixel[1]*ra + inv_a); - pixel[2] = (unsigned char) (pixel[2]*ra + inv_a); - } - } - } - } - - // convert to desired output format - if (req_comp && req_comp != 4) { - if (ri->bits_per_channel == 16) - out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h); - else - out = stbi__convert_format(out, 4, req_comp, w, h); - if (out == NULL) return out; // stbi__convert_format frees input on failure - } - - if (comp) *comp = 4; - *y = h; - *x = w; - - return out; -} -#endif - -// ************************************************************************************************* -// Softimage PIC loader -// by Tom Seddon -// -// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format -// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ - -#ifndef STBI_NO_PIC -static int stbi__pic_is4(stbi__context *s,const char *str) -{ - int i; - for (i=0; i<4; ++i) - if (stbi__get8(s) != (stbi_uc)str[i]) - return 0; - - return 1; -} - -static int stbi__pic_test_core(stbi__context *s) -{ - int i; - - if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) - return 0; - - for(i=0;i<84;++i) - stbi__get8(s); - - if (!stbi__pic_is4(s,"PICT")) - return 0; - - return 1; -} - -typedef struct -{ - stbi_uc size,type,channel; -} stbi__pic_packet; - -static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest) -{ - int mask=0x80, i; - - for (i=0; i<4; ++i, mask>>=1) { - if (channel & mask) { - if (stbi__at_eof(s)) return stbi__errpuc("bad file","PIC file too short"); - dest[i]=stbi__get8(s); - } - } - - return dest; -} - -static void stbi__copyval(int channel,stbi_uc *dest,const stbi_uc *src) -{ - int mask=0x80,i; - - for (i=0;i<4; ++i, mask>>=1) - if (channel&mask) - dest[i]=src[i]; -} - -static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *comp, stbi_uc *result) -{ - int act_comp=0,num_packets=0,y,chained; - stbi__pic_packet packets[10]; - - // this will (should...) cater for even some bizarre stuff like having data - // for the same channel in multiple packets. - do { - stbi__pic_packet *packet; - - if (num_packets==sizeof(packets)/sizeof(packets[0])) - return stbi__errpuc("bad format","too many packets"); - - packet = &packets[num_packets++]; - - chained = stbi__get8(s); - packet->size = stbi__get8(s); - packet->type = stbi__get8(s); - packet->channel = stbi__get8(s); - - act_comp |= packet->channel; - - if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (reading packets)"); - if (packet->size != 8) return stbi__errpuc("bad format","packet isn't 8bpp"); - } while (chained); - - *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? - - for(y=0; ytype) { - default: - return stbi__errpuc("bad format","packet has bad compression type"); - - case 0: {//uncompressed - int x; - - for(x=0;xchannel,dest)) - return 0; - break; - } - - case 1://Pure RLE - { - int left=width, i; - - while (left>0) { - stbi_uc count,value[4]; - - count=stbi__get8(s); - if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pure read count)"); - - if (count > left) - count = (stbi_uc) left; - - if (!stbi__readval(s,packet->channel,value)) return 0; - - for(i=0; ichannel,dest,value); - left -= count; - } - } - break; - - case 2: {//Mixed RLE - int left=width; - while (left>0) { - int count = stbi__get8(s), i; - if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (mixed read count)"); - - if (count >= 128) { // Repeated - stbi_uc value[4]; - - if (count==128) - count = stbi__get16be(s); - else - count -= 127; - if (count > left) - return stbi__errpuc("bad file","scanline overrun"); - - if (!stbi__readval(s,packet->channel,value)) - return 0; - - for(i=0;ichannel,dest,value); - } else { // Raw - ++count; - if (count>left) return stbi__errpuc("bad file","scanline overrun"); - - for(i=0;ichannel,dest)) - return 0; - } - left-=count; - } - break; - } - } - } - } - - return result; -} - -static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri) -{ - stbi_uc *result; - int i, x,y, internal_comp; - STBI_NOTUSED(ri); - - if (!comp) comp = &internal_comp; - - for (i=0; i<92; ++i) - stbi__get8(s); - - x = stbi__get16be(s); - y = stbi__get16be(s); - if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)"); - if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); - - stbi__get32be(s); //skip `ratio' - stbi__get16be(s); //skip `fields' - stbi__get16be(s); //skip `pad' - - // intermediate buffer is RGBA - result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0); - memset(result, 0xff, x*y*4); - - if (!stbi__pic_load_core(s,x,y,comp, result)) { - STBI_FREE(result); - result=0; - } - *px = x; - *py = y; - if (req_comp == 0) req_comp = *comp; - result=stbi__convert_format(result,4,req_comp,x,y); - - return result; -} - -static int stbi__pic_test(stbi__context *s) -{ - int r = stbi__pic_test_core(s); - stbi__rewind(s); - return r; -} -#endif - -// ************************************************************************************************* -// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb - -#ifndef STBI_NO_GIF -typedef struct -{ - stbi__int16 prefix; - stbi_uc first; - stbi_uc suffix; -} stbi__gif_lzw; - -typedef struct -{ - int w,h; - stbi_uc *out; // output buffer (always 4 components) - stbi_uc *background; // The current "background" as far as a gif is concerned - stbi_uc *history; - int flags, bgindex, ratio, transparent, eflags; - stbi_uc pal[256][4]; - stbi_uc lpal[256][4]; - stbi__gif_lzw codes[8192]; - stbi_uc *color_table; - int parse, step; - int lflags; - int start_x, start_y; - int max_x, max_y; - int cur_x, cur_y; - int line_size; - int delay; -} stbi__gif; - -static int stbi__gif_test_raw(stbi__context *s) -{ - int sz; - if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; - sz = stbi__get8(s); - if (sz != '9' && sz != '7') return 0; - if (stbi__get8(s) != 'a') return 0; - return 1; -} - -static int stbi__gif_test(stbi__context *s) -{ - int r = stbi__gif_test_raw(s); - stbi__rewind(s); - return r; -} - -static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp) -{ - int i; - for (i=0; i < num_entries; ++i) { - pal[i][2] = stbi__get8(s); - pal[i][1] = stbi__get8(s); - pal[i][0] = stbi__get8(s); - pal[i][3] = transp == i ? 0 : 255; - } -} - -static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info) -{ - stbi_uc version; - if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') - return stbi__err("not GIF", "Corrupt GIF"); - - version = stbi__get8(s); - if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); - if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); - - stbi__g_failure_reason = ""; - g->w = stbi__get16le(s); - g->h = stbi__get16le(s); - g->flags = stbi__get8(s); - g->bgindex = stbi__get8(s); - g->ratio = stbi__get8(s); - g->transparent = -1; - - if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments - - if (is_info) return 1; - - if (g->flags & 0x80) - stbi__gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); - - return 1; -} - -static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) -{ - stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); - if (!stbi__gif_header(s, g, comp, 1)) { - STBI_FREE(g); - stbi__rewind( s ); - return 0; - } - if (x) *x = g->w; - if (y) *y = g->h; - STBI_FREE(g); - return 1; -} - -static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code) -{ - stbi_uc *p, *c; - int idx; - - // recurse to decode the prefixes, since the linked-list is backwards, - // and working backwards through an interleaved image would be nasty - if (g->codes[code].prefix >= 0) - stbi__out_gif_code(g, g->codes[code].prefix); - - if (g->cur_y >= g->max_y) return; - - idx = g->cur_x + g->cur_y; - p = &g->out[idx]; - g->history[idx / 4] = 1; - - c = &g->color_table[g->codes[code].suffix * 4]; - if (c[3] > 128) { // don't render transparent pixels; - p[0] = c[2]; - p[1] = c[1]; - p[2] = c[0]; - p[3] = c[3]; - } - g->cur_x += 4; - - if (g->cur_x >= g->max_x) { - g->cur_x = g->start_x; - g->cur_y += g->step; - - while (g->cur_y >= g->max_y && g->parse > 0) { - g->step = (1 << g->parse) * g->line_size; - g->cur_y = g->start_y + (g->step >> 1); - --g->parse; - } - } -} - -static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) -{ - stbi_uc lzw_cs; - stbi__int32 len, init_code; - stbi__uint32 first; - stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; - stbi__gif_lzw *p; - - lzw_cs = stbi__get8(s); - if (lzw_cs > 12) return NULL; - clear = 1 << lzw_cs; - first = 1; - codesize = lzw_cs + 1; - codemask = (1 << codesize) - 1; - bits = 0; - valid_bits = 0; - for (init_code = 0; init_code < clear; init_code++) { - g->codes[init_code].prefix = -1; - g->codes[init_code].first = (stbi_uc) init_code; - g->codes[init_code].suffix = (stbi_uc) init_code; - } - - // support no starting clear code - avail = clear+2; - oldcode = -1; - - len = 0; - for(;;) { - if (valid_bits < codesize) { - if (len == 0) { - len = stbi__get8(s); // start new block - if (len == 0) - return g->out; - } - --len; - bits |= (stbi__int32) stbi__get8(s) << valid_bits; - valid_bits += 8; - } else { - stbi__int32 code = bits & codemask; - bits >>= codesize; - valid_bits -= codesize; - // @OPTIMIZE: is there some way we can accelerate the non-clear path? - if (code == clear) { // clear code - codesize = lzw_cs + 1; - codemask = (1 << codesize) - 1; - avail = clear + 2; - oldcode = -1; - first = 0; - } else if (code == clear + 1) { // end of stream code - stbi__skip(s, len); - while ((len = stbi__get8(s)) > 0) - stbi__skip(s,len); - return g->out; - } else if (code <= avail) { - if (first) { - return stbi__errpuc("no clear code", "Corrupt GIF"); - } - - if (oldcode >= 0) { - p = &g->codes[avail++]; - if (avail > 8192) { - return stbi__errpuc("too many codes", "Corrupt GIF"); - } - - p->prefix = (stbi__int16) oldcode; - p->first = g->codes[oldcode].first; - p->suffix = (code == avail) ? p->first : g->codes[code].first; - } else if (code == avail) - return stbi__errpuc("illegal code in raster", "Corrupt GIF"); - - stbi__out_gif_code(g, (stbi__uint16) code); - - if ((avail & codemask) == 0 && avail <= 0x0FFF) { - codesize++; - codemask = (1 << codesize) - 1; - } - - oldcode = code; - } else { - return stbi__errpuc("illegal code in raster", "Corrupt GIF"); - } - } - } -} - -// this function is designed to support animated gifs, although stb_image doesn't support it -// two back is the image from two frames ago, used for a very specific disposal format -static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp, stbi_uc *two_back) -{ - int dispose; - int first_frame; - int pi; - int pcount; - - // on first frame, any non-written pixels get the background colour (non-transparent) - first_frame = 0; - if (g->out == 0) { - if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header - g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h); - g->background = (stbi_uc *) stbi__malloc(4 * g->w * g->h); - g->history = (stbi_uc *) stbi__malloc(g->w * g->h); - if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory"); - - // image is treated as "tranparent" at the start - ie, nothing overwrites the current background; - // background colour is only used for pixels that are not rendered first frame, after that "background" - // color refers to teh color that was there the previous frame. - memset( g->out, 0x00, 4 * g->w * g->h ); - memset( g->background, 0x00, 4 * g->w * g->h ); // state of the background (starts transparent) - memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame - first_frame = 1; - } else { - // second frame - how do we dispoase of the previous one? - dispose = (g->eflags & 0x1C) >> 2; - pcount = g->w * g->h; - - if ((dispose == 3) && (two_back == 0)) { - dispose = 2; // if I don't have an image to revert back to, default to the old background - } - - if (dispose == 3) { // use previous graphic - for (pi = 0; pi < pcount; ++pi) { - if (g->history[pi]) { - memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 ); - } - } - } else if (dispose == 2) { - // restore what was changed last frame to background before that frame; - for (pi = 0; pi < pcount; ++pi) { - if (g->history[pi]) { - memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 ); - } - } - } else { - // This is a non-disposal case eithe way, so just - // leave the pixels as is, and they will become the new background - // 1: do not dispose - // 0: not specified. - } - - // background is what out is after the undoing of the previou frame; - memcpy( g->background, g->out, 4 * g->w * g->h ); - } - - // clear my history; - memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame - - for (;;) { - int tag = stbi__get8(s); - switch (tag) { - case 0x2C: /* Image Descriptor */ - { - stbi__int32 x, y, w, h; - stbi_uc *o; - - x = stbi__get16le(s); - y = stbi__get16le(s); - w = stbi__get16le(s); - h = stbi__get16le(s); - if (((x + w) > (g->w)) || ((y + h) > (g->h))) - return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); - - g->line_size = g->w * 4; - g->start_x = x * 4; - g->start_y = y * g->line_size; - g->max_x = g->start_x + w * 4; - g->max_y = g->start_y + h * g->line_size; - g->cur_x = g->start_x; - g->cur_y = g->start_y; - - g->lflags = stbi__get8(s); - - if (g->lflags & 0x40) { - g->step = 8 * g->line_size; // first interlaced spacing - g->parse = 3; - } else { - g->step = g->line_size; - g->parse = 0; - } - - if (g->lflags & 0x80) { - stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); - g->color_table = (stbi_uc *) g->lpal; - } else if (g->flags & 0x80) { - g->color_table = (stbi_uc *) g->pal; - } else - return stbi__errpuc("missing color table", "Corrupt GIF"); - - o = stbi__process_gif_raster(s, g); - if (o == NULL) return NULL; - - // if this was the first frame, - pcount = g->w * g->h; - if (first_frame && (g->bgindex > 0)) { - // if first frame, any pixel not drawn to gets the background color - for (pi = 0; pi < pcount; ++pi) { - if (g->history[pi] == 0) { - g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be; - memcpy( &g->out[pi * 4], &g->pal[g->bgindex], 4 ); - } - } - } - - return o; - } - - case 0x21: // Comment Extension. - { - int len; - int ext = stbi__get8(s); - if (ext == 0xF9) { // Graphic Control Extension. - len = stbi__get8(s); - if (len == 4) { - g->eflags = stbi__get8(s); - g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths. - - // unset old transparent - if (g->transparent >= 0) { - g->pal[g->transparent][3] = 255; - } - if (g->eflags & 0x01) { - g->transparent = stbi__get8(s); - if (g->transparent >= 0) { - g->pal[g->transparent][3] = 0; - } - } else { - // don't need transparent - stbi__skip(s, 1); - g->transparent = -1; - } - } else { - stbi__skip(s, len); - break; - } - } - while ((len = stbi__get8(s)) != 0) { - stbi__skip(s, len); - } - break; - } - - case 0x3B: // gif stream termination code - return (stbi_uc *) s; // using '1' causes warning on some compilers - - default: - return stbi__errpuc("unknown code", "Corrupt GIF"); - } - } -} - -static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp) -{ - if (stbi__gif_test(s)) { - int layers = 0; - stbi_uc *u = 0; - stbi_uc *out = 0; - stbi_uc *two_back = 0; - stbi__gif g; - int stride; - memset(&g, 0, sizeof(g)); - if (delays) { - *delays = 0; - } - - do { - u = stbi__gif_load_next(s, &g, comp, req_comp, two_back); - if (u == (stbi_uc *) s) u = 0; // end of animated gif marker - - if (u) { - *x = g.w; - *y = g.h; - ++layers; - stride = g.w * g.h * 4; - - if (out) { - out = (stbi_uc*) STBI_REALLOC( out, layers * stride ); - if (delays) { - *delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers ); - } - } else { - out = (stbi_uc*)stbi__malloc( layers * stride ); - if (delays) { - *delays = (int*) stbi__malloc( layers * sizeof(int) ); - } - } - memcpy( out + ((layers - 1) * stride), u, stride ); - if (layers >= 2) { - two_back = out - 2 * stride; - } - - if (delays) { - (*delays)[layers - 1U] = g.delay; - } - } - } while (u != 0); - - // free temp buffer; - STBI_FREE(g.out); - STBI_FREE(g.history); - STBI_FREE(g.background); - - // do the final conversion after loading everything; - if (req_comp && req_comp != 4) - out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h); - - *z = layers; - return out; - } else { - return stbi__errpuc("not GIF", "Image was not as a gif type."); - } -} - -static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) -{ - stbi_uc *u = 0; - stbi__gif g; - memset(&g, 0, sizeof(g)); - - u = stbi__gif_load_next(s, &g, comp, req_comp, 0); - if (u == (stbi_uc *) s) u = 0; // end of animated gif marker - if (u) { - *x = g.w; - *y = g.h; - - // moved conversion to after successful load so that the same - // can be done for multiple frames. - if (req_comp && req_comp != 4) - u = stbi__convert_format(u, 4, req_comp, g.w, g.h); - } - - // free buffers needed for multiple frame loading; - STBI_FREE(g.history); - STBI_FREE(g.background); - - return u; -} - -static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp) -{ - return stbi__gif_info_raw(s,x,y,comp); -} -#endif - -// ************************************************************************************************* -// Radiance RGBE HDR loader -// originally by Nicolas Schulz -#ifndef STBI_NO_HDR -static int stbi__hdr_test_core(stbi__context *s, const char *signature) -{ - int i; - for (i=0; signature[i]; ++i) - if (stbi__get8(s) != signature[i]) - return 0; - stbi__rewind(s); - return 1; -} - -static int stbi__hdr_test(stbi__context* s) -{ - int r = stbi__hdr_test_core(s, "#?RADIANCE\n"); - stbi__rewind(s); - if(!r) { - r = stbi__hdr_test_core(s, "#?RGBE\n"); - stbi__rewind(s); - } - return r; -} - -#define STBI__HDR_BUFLEN 1024 -static char *stbi__hdr_gettoken(stbi__context *z, char *buffer) -{ - int len=0; - char c = '\0'; - - c = (char) stbi__get8(z); - - while (!stbi__at_eof(z) && c != '\n') { - buffer[len++] = c; - if (len == STBI__HDR_BUFLEN-1) { - // flush to end of line - while (!stbi__at_eof(z) && stbi__get8(z) != '\n') - ; - break; - } - c = (char) stbi__get8(z); - } - - buffer[len] = 0; - return buffer; -} - -static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp) -{ - if ( input[3] != 0 ) { - float f1; - // Exponent - f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); - if (req_comp <= 2) - output[0] = (input[0] + input[1] + input[2]) * f1 / 3; - else { - output[0] = input[0] * f1; - output[1] = input[1] * f1; - output[2] = input[2] * f1; - } - if (req_comp == 2) output[1] = 1; - if (req_comp == 4) output[3] = 1; - } else { - switch (req_comp) { - case 4: output[3] = 1; /* fallthrough */ - case 3: output[0] = output[1] = output[2] = 0; - break; - case 2: output[1] = 1; /* fallthrough */ - case 1: output[0] = 0; - break; - } - } -} - -static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) -{ - char buffer[STBI__HDR_BUFLEN]; - char *token; - int valid = 0; - int width, height; - stbi_uc *scanline; - float *hdr_data; - int len; - unsigned char count, value; - int i, j, k, c1,c2, z; - const char *headerToken; - STBI_NOTUSED(ri); - - // Check identifier - headerToken = stbi__hdr_gettoken(s,buffer); - if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0) - return stbi__errpf("not HDR", "Corrupt HDR image"); - - // Parse header - for(;;) { - token = stbi__hdr_gettoken(s,buffer); - if (token[0] == 0) break; - if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; - } - - if (!valid) return stbi__errpf("unsupported format", "Unsupported HDR format"); - - // Parse width and height - // can't use sscanf() if we're not using stdio! - token = stbi__hdr_gettoken(s,buffer); - if (strncmp(token, "-Y ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); - token += 3; - height = (int) strtol(token, &token, 10); - while (*token == ' ') ++token; - if (strncmp(token, "+X ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); - token += 3; - width = (int) strtol(token, NULL, 10); - - *x = width; - *y = height; - - if (comp) *comp = 3; - if (req_comp == 0) req_comp = 3; - - if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0)) - return stbi__errpf("too large", "HDR image is too large"); - - // Read data - hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); - if (!hdr_data) - return stbi__errpf("outofmem", "Out of memory"); - - // Load image data - // image data is stored as some number of sca - if ( width < 8 || width >= 32768) { - // Read flat data - for (j=0; j < height; ++j) { - for (i=0; i < width; ++i) { - stbi_uc rgbe[4]; - main_decode_loop: - stbi__getn(s, rgbe, 4); - stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); - } - } - } else { - // Read RLE-encoded data - scanline = NULL; - - for (j = 0; j < height; ++j) { - c1 = stbi__get8(s); - c2 = stbi__get8(s); - len = stbi__get8(s); - if (c1 != 2 || c2 != 2 || (len & 0x80)) { - // not run-length encoded, so we have to actually use THIS data as a decoded - // pixel (note this can't be a valid pixel--one of RGB must be >= 128) - stbi_uc rgbe[4]; - rgbe[0] = (stbi_uc) c1; - rgbe[1] = (stbi_uc) c2; - rgbe[2] = (stbi_uc) len; - rgbe[3] = (stbi_uc) stbi__get8(s); - stbi__hdr_convert(hdr_data, rgbe, req_comp); - i = 1; - j = 0; - STBI_FREE(scanline); - goto main_decode_loop; // yes, this makes no sense - } - len <<= 8; - len |= stbi__get8(s); - if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } - if (scanline == NULL) { - scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0); - if (!scanline) { - STBI_FREE(hdr_data); - return stbi__errpf("outofmem", "Out of memory"); - } - } - - for (k = 0; k < 4; ++k) { - int nleft; - i = 0; - while ((nleft = width - i) > 0) { - count = stbi__get8(s); - if (count > 128) { - // Run - value = stbi__get8(s); - count -= 128; - if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } - for (z = 0; z < count; ++z) - scanline[i++ * 4 + k] = value; - } else { - // Dump - if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } - for (z = 0; z < count; ++z) - scanline[i++ * 4 + k] = stbi__get8(s); - } - } - } - for (i=0; i < width; ++i) - stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); - } - if (scanline) - STBI_FREE(scanline); - } - - return hdr_data; -} - -static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) -{ - char buffer[STBI__HDR_BUFLEN]; - char *token; - int valid = 0; - int dummy; - - if (!x) x = &dummy; - if (!y) y = &dummy; - if (!comp) comp = &dummy; - - if (stbi__hdr_test(s) == 0) { - stbi__rewind( s ); - return 0; - } - - for(;;) { - token = stbi__hdr_gettoken(s,buffer); - if (token[0] == 0) break; - if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; - } - - if (!valid) { - stbi__rewind( s ); - return 0; - } - token = stbi__hdr_gettoken(s,buffer); - if (strncmp(token, "-Y ", 3)) { - stbi__rewind( s ); - return 0; - } - token += 3; - *y = (int) strtol(token, &token, 10); - while (*token == ' ') ++token; - if (strncmp(token, "+X ", 3)) { - stbi__rewind( s ); - return 0; - } - token += 3; - *x = (int) strtol(token, NULL, 10); - *comp = 3; - return 1; -} -#endif // STBI_NO_HDR - -#ifndef STBI_NO_BMP -static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) -{ - void *p; - stbi__bmp_data info; - - info.all_a = 255; - p = stbi__bmp_parse_header(s, &info); - stbi__rewind( s ); - if (p == NULL) - return 0; - if (x) *x = s->img_x; - if (y) *y = s->img_y; - if (comp) *comp = info.ma ? 4 : 3; - return 1; -} -#endif - -#ifndef STBI_NO_PSD -static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) -{ - int channelCount, dummy, depth; - if (!x) x = &dummy; - if (!y) y = &dummy; - if (!comp) comp = &dummy; - if (stbi__get32be(s) != 0x38425053) { - stbi__rewind( s ); - return 0; - } - if (stbi__get16be(s) != 1) { - stbi__rewind( s ); - return 0; - } - stbi__skip(s, 6); - channelCount = stbi__get16be(s); - if (channelCount < 0 || channelCount > 16) { - stbi__rewind( s ); - return 0; - } - *y = stbi__get32be(s); - *x = stbi__get32be(s); - depth = stbi__get16be(s); - if (depth != 8 && depth != 16) { - stbi__rewind( s ); - return 0; - } - if (stbi__get16be(s) != 3) { - stbi__rewind( s ); - return 0; - } - *comp = 4; - return 1; -} - -static int stbi__psd_is16(stbi__context *s) -{ - int channelCount, depth; - if (stbi__get32be(s) != 0x38425053) { - stbi__rewind( s ); - return 0; - } - if (stbi__get16be(s) != 1) { - stbi__rewind( s ); - return 0; - } - stbi__skip(s, 6); - channelCount = stbi__get16be(s); - if (channelCount < 0 || channelCount > 16) { - stbi__rewind( s ); - return 0; - } - (void) stbi__get32be(s); - (void) stbi__get32be(s); - depth = stbi__get16be(s); - if (depth != 16) { - stbi__rewind( s ); - return 0; - } - return 1; -} -#endif - -#ifndef STBI_NO_PIC -static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) -{ - int act_comp=0,num_packets=0,chained,dummy; - stbi__pic_packet packets[10]; - - if (!x) x = &dummy; - if (!y) y = &dummy; - if (!comp) comp = &dummy; - - if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) { - stbi__rewind(s); - return 0; - } - - stbi__skip(s, 88); - - *x = stbi__get16be(s); - *y = stbi__get16be(s); - if (stbi__at_eof(s)) { - stbi__rewind( s); - return 0; - } - if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { - stbi__rewind( s ); - return 0; - } - - stbi__skip(s, 8); - - do { - stbi__pic_packet *packet; - - if (num_packets==sizeof(packets)/sizeof(packets[0])) - return 0; - - packet = &packets[num_packets++]; - chained = stbi__get8(s); - packet->size = stbi__get8(s); - packet->type = stbi__get8(s); - packet->channel = stbi__get8(s); - act_comp |= packet->channel; - - if (stbi__at_eof(s)) { - stbi__rewind( s ); - return 0; - } - if (packet->size != 8) { - stbi__rewind( s ); - return 0; - } - } while (chained); - - *comp = (act_comp & 0x10 ? 4 : 3); - - return 1; -} -#endif - -// ************************************************************************************************* -// Portable Gray Map and Portable Pixel Map loader -// by Ken Miller -// -// PGM: http://netpbm.sourceforge.net/doc/pgm.html -// PPM: http://netpbm.sourceforge.net/doc/ppm.html -// -// Known limitations: -// Does not support comments in the header section -// Does not support ASCII image data (formats P2 and P3) -// Does not support 16-bit-per-channel - -#ifndef STBI_NO_PNM - -static int stbi__pnm_test(stbi__context *s) -{ - char p, t; - p = (char) stbi__get8(s); - t = (char) stbi__get8(s); - if (p != 'P' || (t != '5' && t != '6')) { - stbi__rewind( s ); - return 0; - } - return 1; -} - -static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) -{ - stbi_uc *out; - STBI_NOTUSED(ri); - - if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n)) - return 0; - - *x = s->img_x; - *y = s->img_y; - if (comp) *comp = s->img_n; - - if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0)) - return stbi__errpuc("too large", "PNM too large"); - - out = (stbi_uc *) stbi__malloc_mad3(s->img_n, s->img_x, s->img_y, 0); - if (!out) return stbi__errpuc("outofmem", "Out of memory"); - stbi__getn(s, out, s->img_n * s->img_x * s->img_y); - - if (req_comp && req_comp != s->img_n) { - out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); - if (out == NULL) return out; // stbi__convert_format frees input on failure - } - return out; -} - -static int stbi__pnm_isspace(char c) -{ - return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; -} - -static void stbi__pnm_skip_whitespace(stbi__context *s, char *c) -{ - for (;;) { - while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) - *c = (char) stbi__get8(s); - - if (stbi__at_eof(s) || *c != '#') - break; - - while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' ) - *c = (char) stbi__get8(s); - } -} - -static int stbi__pnm_isdigit(char c) -{ - return c >= '0' && c <= '9'; -} - -static int stbi__pnm_getinteger(stbi__context *s, char *c) -{ - int value = 0; - - while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) { - value = value*10 + (*c - '0'); - *c = (char) stbi__get8(s); - } - - return value; -} - -static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) -{ - int maxv, dummy; - char c, p, t; - - if (!x) x = &dummy; - if (!y) y = &dummy; - if (!comp) comp = &dummy; - - stbi__rewind(s); - - // Get identifier - p = (char) stbi__get8(s); - t = (char) stbi__get8(s); - if (p != 'P' || (t != '5' && t != '6')) { - stbi__rewind(s); - return 0; - } - - *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm - - c = (char) stbi__get8(s); - stbi__pnm_skip_whitespace(s, &c); - - *x = stbi__pnm_getinteger(s, &c); // read width - stbi__pnm_skip_whitespace(s, &c); - - *y = stbi__pnm_getinteger(s, &c); // read height - stbi__pnm_skip_whitespace(s, &c); - - maxv = stbi__pnm_getinteger(s, &c); // read max value - - if (maxv > 255) - return stbi__err("max value > 255", "PPM image not 8-bit"); - else - return 1; -} -#endif - -static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp) -{ - #ifndef STBI_NO_JPEG - if (stbi__jpeg_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_PNG - if (stbi__png_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_GIF - if (stbi__gif_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_BMP - if (stbi__bmp_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_PSD - if (stbi__psd_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_PIC - if (stbi__pic_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_PNM - if (stbi__pnm_info(s, x, y, comp)) return 1; - #endif - - #ifndef STBI_NO_HDR - if (stbi__hdr_info(s, x, y, comp)) return 1; - #endif - - // test tga last because it's a crappy test! - #ifndef STBI_NO_TGA - if (stbi__tga_info(s, x, y, comp)) - return 1; - #endif - return stbi__err("unknown image type", "Image not of any known type, or corrupt"); -} - -static int stbi__is_16_main(stbi__context *s) -{ - #ifndef STBI_NO_PNG - if (stbi__png_is16(s)) return 1; - #endif - - #ifndef STBI_NO_PSD - if (stbi__psd_is16(s)) return 1; - #endif - - return 0; -} - -#ifndef STBI_NO_STDIO -STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp) -{ - FILE *f = stbi__fopen(filename, "rb"); - int result; - if (!f) return stbi__err("can't fopen", "Unable to open file"); - result = stbi_info_from_file(f, x, y, comp); - fclose(f); - return result; -} - -STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) -{ - int r; - stbi__context s; - long pos = ftell(f); - stbi__start_file(&s, f); - r = stbi__info_main(&s,x,y,comp); - if (pos >= 0) { - if (fseek(f,pos,SEEK_SET) == -1) return stbi__err("fseek() error", "File Seek Fail"); - } - return r; -} - -STBIDEF int stbi_is_16_bit(char const *filename) -{ - FILE *f = stbi__fopen(filename, "rb"); - int result; - if (!f) return stbi__err("can't fopen", "Unable to open file"); - result = stbi_is_16_bit_from_file(f); - fclose(f); - return result; -} - -STBIDEF int stbi_is_16_bit_from_file(FILE *f) -{ - int r; - stbi__context s; - long pos = ftell(f); - stbi__start_file(&s, f); - r = stbi__is_16_main(&s); - if (pos >= 0) { - if (fseek(f,pos,SEEK_SET) == -1) return stbi__err("fseek() error", "File Seek Fail"); - } - return r; -} -#endif // !STBI_NO_STDIO - -STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) -{ - stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__info_main(&s,x,y,comp); -} - -STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); - return stbi__info_main(&s,x,y,comp); -} - -STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len) -{ - stbi__context s; - stbi__start_mem(&s,buffer,len); - return stbi__is_16_main(&s); -} - -STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user) -{ - stbi__context s; - stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); - return stbi__is_16_main(&s); -} - -#endif // STB_IMAGE_IMPLEMENTATION - -/* - revision history: - 2.19 (2018-02-11) fix warning - 2.18 (2018-01-30) fix warnings - 2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug - 1-bit BMP - *_is_16_bit api - avoid warnings - 2.16 (2017-07-23) all functions have 16-bit variants; - STBI_NO_STDIO works again; - compilation fixes; - fix rounding in unpremultiply; - optimize vertical flip; - disable raw_len validation; - documentation fixes - 2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode; - warning fixes; disable run-time SSE detection on gcc; - uniform handling of optional "return" values; - thread-safe initialization of zlib tables - 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs - 2.13 (2016-11-29) add 16-bit API, only supported for PNG right now - 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes - 2.11 (2016-04-02) allocate large structures on the stack - remove white matting for transparent PSD - fix reported channel count for PNG & BMP - re-enable SSE2 in non-gcc 64-bit - support RGB-formatted JPEG - read 16-bit PNGs (only as 8-bit) - 2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED - 2.09 (2016-01-16) allow comments in PNM files - 16-bit-per-pixel TGA (not bit-per-component) - info() for TGA could break due to .hdr handling - info() for BMP to shares code instead of sloppy parse - can use STBI_REALLOC_SIZED if allocator doesn't support realloc - code cleanup - 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA - 2.07 (2015-09-13) fix compiler warnings - partial animated GIF support - limited 16-bpc PSD support - #ifdef unused functions - bug with < 92 byte PIC,PNM,HDR,TGA - 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value - 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning - 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit - 2.03 (2015-04-12) extra corruption checking (mmozeiko) - stbi_set_flip_vertically_on_load (nguillemot) - fix NEON support; fix mingw support - 2.02 (2015-01-19) fix incorrect assert, fix warning - 2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2 - 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG - 2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg) - progressive JPEG (stb) - PGM/PPM support (Ken Miller) - STBI_MALLOC,STBI_REALLOC,STBI_FREE - GIF bugfix -- seemingly never worked - STBI_NO_*, STBI_ONLY_* - 1.48 (2014-12-14) fix incorrectly-named assert() - 1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb) - optimize PNG (ryg) - fix bug in interlaced PNG with user-specified channel count (stb) - 1.46 (2014-08-26) - fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG - 1.45 (2014-08-16) - fix MSVC-ARM internal compiler error by wrapping malloc - 1.44 (2014-08-07) - various warning fixes from Ronny Chevalier - 1.43 (2014-07-15) - fix MSVC-only compiler problem in code changed in 1.42 - 1.42 (2014-07-09) - don't define _CRT_SECURE_NO_WARNINGS (affects user code) - fixes to stbi__cleanup_jpeg path - added STBI_ASSERT to avoid requiring assert.h - 1.41 (2014-06-25) - fix search&replace from 1.36 that messed up comments/error messages - 1.40 (2014-06-22) - fix gcc struct-initialization warning - 1.39 (2014-06-15) - fix to TGA optimization when req_comp != number of components in TGA; - fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite) - add support for BMP version 5 (more ignored fields) - 1.38 (2014-06-06) - suppress MSVC warnings on integer casts truncating values - fix accidental rename of 'skip' field of I/O - 1.37 (2014-06-04) - remove duplicate typedef - 1.36 (2014-06-03) - convert to header file single-file library - if de-iphone isn't set, load iphone images color-swapped instead of returning NULL - 1.35 (2014-05-27) - various warnings - fix broken STBI_SIMD path - fix bug where stbi_load_from_file no longer left file pointer in correct place - fix broken non-easy path for 32-bit BMP (possibly never used) - TGA optimization by Arseny Kapoulkine - 1.34 (unknown) - use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case - 1.33 (2011-07-14) - make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements - 1.32 (2011-07-13) - support for "info" function for all supported filetypes (SpartanJ) - 1.31 (2011-06-20) - a few more leak fixes, bug in PNG handling (SpartanJ) - 1.30 (2011-06-11) - added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) - removed deprecated format-specific test/load functions - removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway - error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) - fix inefficiency in decoding 32-bit BMP (David Woo) - 1.29 (2010-08-16) - various warning fixes from Aurelien Pocheville - 1.28 (2010-08-01) - fix bug in GIF palette transparency (SpartanJ) - 1.27 (2010-08-01) - cast-to-stbi_uc to fix warnings - 1.26 (2010-07-24) - fix bug in file buffering for PNG reported by SpartanJ - 1.25 (2010-07-17) - refix trans_data warning (Won Chun) - 1.24 (2010-07-12) - perf improvements reading from files on platforms with lock-heavy fgetc() - minor perf improvements for jpeg - deprecated type-specific functions so we'll get feedback if they're needed - attempt to fix trans_data warning (Won Chun) - 1.23 fixed bug in iPhone support - 1.22 (2010-07-10) - removed image *writing* support - stbi_info support from Jetro Lauha - GIF support from Jean-Marc Lienher - iPhone PNG-extensions from James Brown - warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva) - 1.21 fix use of 'stbi_uc' in header (reported by jon blow) - 1.20 added support for Softimage PIC, by Tom Seddon - 1.19 bug in interlaced PNG corruption check (found by ryg) - 1.18 (2008-08-02) - fix a threading bug (local mutable static) - 1.17 support interlaced PNG - 1.16 major bugfix - stbi__convert_format converted one too many pixels - 1.15 initialize some fields for thread safety - 1.14 fix threadsafe conversion bug - header-file-only version (#define STBI_HEADER_FILE_ONLY before including) - 1.13 threadsafe - 1.12 const qualifiers in the API - 1.11 Support installable IDCT, colorspace conversion routines - 1.10 Fixes for 64-bit (don't use "unsigned long") - optimized upsampling by Fabian "ryg" Giesen - 1.09 Fix format-conversion for PSD code (bad global variables!) - 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz - 1.07 attempt to fix C++ warning/errors again - 1.06 attempt to fix C++ warning/errors again - 1.05 fix TGA loading to return correct *comp and use good luminance calc - 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free - 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR - 1.02 support for (subset of) HDR files, float interface for preferred access to them - 1.01 fix bug: possible bug in handling right-side up bmps... not sure - fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all - 1.00 interface to zlib that skips zlib header - 0.99 correct handling of alpha in palette - 0.98 TGA loader by lonesock; dynamically add loaders (untested) - 0.97 jpeg errors on too large a file; also catch another malloc failure - 0.96 fix detection of invalid v value - particleman@mollyrocket forum - 0.95 during header scan, seek to markers in case of padding - 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same - 0.93 handle jpegtran output; verbose errors - 0.92 read 4,8,16,24,32-bit BMP files of several formats - 0.91 output 24-bit Windows 3.0 BMP files - 0.90 fix a few more warnings; bump version number to approach 1.0 - 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd - 0.60 fix compiling as c++ - 0.59 fix warnings: merge Dave Moore's -Wall fixes - 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian - 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available - 0.56 fix bug: zlib uncompressed mode len vs. nlen - 0.55 fix bug: restart_interval not initialized to 0 - 0.54 allow NULL for 'int *comp' - 0.53 fix bug in png 3->4; speedup png decoding - 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments - 0.51 obey req_comp requests, 1-component jpegs return as 1-component, - on 'test' only check type, not whether we support this variant - 0.50 (2006-11-19) - first released version -*/ - - -/* ------------------------------------------------------------------------------- -This software is available under 2 licenses -- choose whichever you prefer. ------------------------------------------------------------------------------- -ALTERNATIVE A - MIT License -Copyright (c) 2017 Sean Barrett -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. ------------------------------------------------------------------------------- -ALTERNATIVE B - Public Domain (www.unlicense.org) -This is free and unencumbered software released into the public domain. -Anyone is free to copy, modify, publish, use, compile, sell, or distribute this -software, either in source code form or as a compiled binary, for any purpose, -commercial or non-commercial, and by any means. -In jurisdictions that recognize copyright laws, the author or authors of this -software dedicate any and all copyright interest in the software to the public -domain. We make this dedication for the benefit of the public at large and to -the detriment of our heirs and successors. We intend this dedication to be an -overt act of relinquishment in perpetuity of all present and future rights to -this software under copyright law. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------- -*/ diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/varenaalloc.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/varenaalloc.cpp deleted file mode 100644 index 16af3873..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/varenaalloc.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "varenaalloc.h" -#include -#include - -static char* end_chain(char*) { return nullptr; } - -static uint32_t first_allocated_block(uint32_t blockSize, uint32_t firstHeapAllocation) { - return firstHeapAllocation > 0 ? firstHeapAllocation : - blockSize > 0 ? blockSize : 1024; -} - -VArenaAlloc::VArenaAlloc(char* block, size_t size, size_t firstHeapAllocation) - : fDtorCursor {block} - , fCursor {block} - , fEnd {block + ToU32(size)} - , fFirstBlock {block} - , fFirstSize {ToU32(size)} - , fFirstHeapAllocationSize {first_allocated_block(ToU32(size), ToU32(firstHeapAllocation))} -{ - if (size < sizeof(Footer)) { - fEnd = fCursor = fDtorCursor = nullptr; - } - - if (fCursor != nullptr) { - this->installFooter(end_chain, 0); - } -} - -VArenaAlloc::~VArenaAlloc() { - RunDtorsOnBlock(fDtorCursor); -} - -void VArenaAlloc::reset() { - this->~VArenaAlloc(); - new (this) VArenaAlloc{fFirstBlock, fFirstSize, fFirstHeapAllocationSize}; -} - -void VArenaAlloc::installFooter(FooterAction* action, uint32_t padding) { - assert(padding < 64); - int64_t actionInt = (int64_t)(intptr_t)action; - - // The top 14 bits should be either all 0s or all 1s. Check this. - assert((actionInt << 6) >> 6 == actionInt); - Footer encodedFooter = (actionInt << 6) | padding; - memmove(fCursor, &encodedFooter, sizeof(Footer)); - fCursor += sizeof(Footer); - fDtorCursor = fCursor; -} - -void VArenaAlloc::installPtrFooter(FooterAction* action, char* ptr, uint32_t padding) { - memmove(fCursor, &ptr, sizeof(char*)); - fCursor += sizeof(char*); - this->installFooter(action, padding); -} - -char* VArenaAlloc::SkipPod(char* footerEnd) { - char* objEnd = footerEnd - (sizeof(Footer) + sizeof(int32_t)); - int32_t skip; - memmove(&skip, objEnd, sizeof(int32_t)); - return objEnd - skip; -} - -void VArenaAlloc::RunDtorsOnBlock(char* footerEnd) { - while (footerEnd != nullptr) { - Footer footer; - memcpy(&footer, footerEnd - sizeof(Footer), sizeof(Footer)); - - FooterAction* action = (FooterAction*)(footer >> 6); - ptrdiff_t padding = footer & 63; - - footerEnd = action(footerEnd) - padding; - } -} - -char* VArenaAlloc::NextBlock(char* footerEnd) { - char* objEnd = footerEnd - (sizeof(Footer) + sizeof(char*)); - char* next; - memmove(&next, objEnd, sizeof(char*)); - RunDtorsOnBlock(next); - delete [] objEnd; - return nullptr; -} - -void VArenaAlloc::installUint32Footer(FooterAction* action, uint32_t value, uint32_t padding) { - memmove(fCursor, &value, sizeof(uint32_t)); - fCursor += sizeof(uint32_t); - this->installFooter(action, padding); -} - -void VArenaAlloc::ensureSpace(uint32_t size, uint32_t alignment) { - constexpr uint32_t headerSize = sizeof(Footer) + sizeof(ptrdiff_t); - // The chrome c++ library we use does not define std::max_align_t. - // This must be conservative to add the right amount of extra memory to handle the alignment - // padding. - constexpr uint32_t alignof_max_align_t = 8; - constexpr uint32_t maxSize = std::numeric_limits::max(); - constexpr uint32_t overhead = headerSize + sizeof(Footer); - AssertRelease(size <= maxSize - overhead); - uint32_t objSizeAndOverhead = size + overhead; - if (alignment > alignof_max_align_t) { - uint32_t alignmentOverhead = alignment - 1; - AssertRelease(objSizeAndOverhead <= maxSize - alignmentOverhead); - objSizeAndOverhead += alignmentOverhead; - } - - uint32_t minAllocationSize; - if (fFirstHeapAllocationSize <= maxSize / fFib0) { - minAllocationSize = fFirstHeapAllocationSize * fFib0; - fFib0 += fFib1; - std::swap(fFib0, fFib1); - } else { - minAllocationSize = maxSize; - } - uint32_t allocationSize = std::max(objSizeAndOverhead, minAllocationSize); - - // Round up to a nice size. If > 32K align to 4K boundary else up to max_align_t. The > 32K - // heuristic is from the JEMalloc behavior. - { - uint32_t mask = allocationSize > (1 << 15) ? (1 << 12) - 1 : 16 - 1; - AssertRelease(allocationSize <= maxSize - mask); - allocationSize = (allocationSize + mask) & ~mask; - } - - char* newBlock = new char[allocationSize]; - - auto previousDtor = fDtorCursor; - fCursor = newBlock; - fDtorCursor = newBlock; - fEnd = fCursor + allocationSize; - this->installPtrFooter(NextBlock, previousDtor, 0); -} - -char* VArenaAlloc::allocObjectWithFooter(uint32_t sizeIncludingFooter, uint32_t alignment) { - uintptr_t mask = alignment - 1; - -restart: - uint32_t skipOverhead = 0; - bool needsSkipFooter = fCursor != fDtorCursor; - if (needsSkipFooter) { - skipOverhead = sizeof(Footer) + sizeof(uint32_t); - } - char* objStart = (char*)((uintptr_t)(fCursor + skipOverhead + mask) & ~mask); - uint32_t totalSize = sizeIncludingFooter + skipOverhead; - //std::cout<<"non POD object size = "< fEnd - objStart) { - this->ensureSpace(totalSize, alignment); - goto restart; - } - - AssertRelease((ptrdiff_t)totalSize <= fEnd - objStart); - - // Install a skip footer if needed, thus terminating a run of POD data. The calling code is - // responsible for installing the footer after the object. - if (needsSkipFooter) { - this->installUint32Footer(SkipPod, ToU32(fCursor - fDtorCursor), 0); - } - - return objStart; -} diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/varenaalloc.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/varenaalloc.h deleted file mode 100644 index ed03b53f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/varenaalloc.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef VARENAALLOC_H -#define VARENAALLOC_H -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// SkArenaAlloc allocates object and destroys the allocated objects when destroyed. It's designed -// to minimize the number of underlying block allocations. SkArenaAlloc allocates first out of an -// (optional) user-provided block of memory, and when that's exhausted it allocates on the heap, -// starting with an allocation of firstHeapAllocation bytes. If your data (plus a small overhead) -// fits in the user-provided block, SkArenaAlloc never uses the heap, and if it fits in -// firstHeapAllocation bytes, it'll use the heap only once. If 0 is specified for -// firstHeapAllocation, then blockSize is used unless that too is 0, then 1024 is used. -// -// Examples: -// -// char block[mostCasesSize]; -// SkArenaAlloc arena(block, mostCasesSize); -// -// If mostCasesSize is too large for the stack, you can use the following pattern. -// -// std::unique_ptr block{new char[mostCasesSize]}; -// SkArenaAlloc arena(block.get(), mostCasesSize, almostAllCasesSize); -// -// If the program only sometimes allocates memory, use the following pattern. -// -// SkArenaAlloc arena(nullptr, 0, almostAllCasesSize); -// -// The storage does not necessarily need to be on the stack. Embedding the storage in a class also -// works. -// -// class Foo { -// char storage[mostCasesSize]; -// SkArenaAlloc arena (storage, mostCasesSize); -// }; -// -// In addition, the system is optimized to handle POD data including arrays of PODs (where -// POD is really data with no destructors). For POD data it has zero overhead per item, and a -// typical per block overhead of 8 bytes. For non-POD objects there is a per item overhead of 4 -// bytes. For arrays of non-POD objects there is a per array overhead of typically 8 bytes. There -// is an addition overhead when switching from POD data to non-POD data of typically 8 bytes. -// -// If additional blocks are needed they are increased exponentially. This strategy bounds the -// recursion of the RunDtorsOnBlock to be limited to O(log size-of-memory). Block size grow using -// the Fibonacci sequence which means that for 2^32 memory there are 48 allocations, and for 2^48 -// there are 71 allocations. -class VArenaAlloc { -public: - VArenaAlloc(char* block, size_t blockSize, size_t firstHeapAllocation); - - explicit VArenaAlloc(size_t firstHeapAllocation) - : VArenaAlloc(nullptr, 0, firstHeapAllocation) - {} - - ~VArenaAlloc(); - - template - T* make(Args&&... args) { - uint32_t size = ToU32(sizeof(T)); - uint32_t alignment = ToU32(alignof(T)); - char* objStart; - if (std::is_trivially_destructible::value) { - objStart = this->allocObject(size, alignment); - fCursor = objStart + size; - } else { - objStart = this->allocObjectWithFooter(size + sizeof(Footer), alignment); - // Can never be UB because max value is alignof(T). - uint32_t padding = ToU32(objStart - fCursor); - - // Advance to end of object to install footer. - fCursor = objStart + size; - FooterAction* releaser = [](char* objEnd) { - char* objStart = objEnd - (sizeof(T) + sizeof(Footer)); - ((T*)objStart)->~T(); - return objStart; - }; - this->installFooter(releaser, padding); - } - - // This must be last to make objects with nested use of this allocator work. - return new(objStart) T(std::forward(args)...); - } - - template - T* makeArrayDefault(size_t count) { - uint32_t safeCount = ToU32(count); - T* array = (T*)this->commonArrayAlloc(safeCount); - - // If T is primitive then no initialization takes place. - for (size_t i = 0; i < safeCount; i++) { - new (&array[i]) T; - } - return array; - } - - template - T* makeArray(size_t count) { - uint32_t safeCount = ToU32(count); - T* array = (T*)this->commonArrayAlloc(safeCount); - - // If T is primitive then the memory is initialized. For example, an array of chars will - // be zeroed. - for (size_t i = 0; i < safeCount; i++) { - new (&array[i]) T(); - } - return array; - } - - // Only use makeBytesAlignedTo if none of the typed variants are impractical to use. - void* makeBytesAlignedTo(size_t size, size_t align) { - auto objStart = this->allocObject(ToU32(size), ToU32(align)); - fCursor = objStart + size; - return objStart; - } - - // Destroy all allocated objects, free any heap allocations. - void reset(); - -private: - static void AssertRelease(bool cond) { if (!cond) { ::abort(); } } - static uint32_t ToU32(size_t v) { - return (uint32_t)v; - } - - using Footer = int64_t; - using FooterAction = char* (char*); - - static char* SkipPod(char* footerEnd); - static void RunDtorsOnBlock(char* footerEnd); - static char* NextBlock(char* footerEnd); - - void installFooter(FooterAction* releaser, uint32_t padding); - void installUint32Footer(FooterAction* action, uint32_t value, uint32_t padding); - void installPtrFooter(FooterAction* action, char* ptr, uint32_t padding); - - void ensureSpace(uint32_t size, uint32_t alignment); - - char* allocObject(uint32_t size, uint32_t alignment) { - uintptr_t mask = alignment - 1; - uintptr_t alignedOffset = (~reinterpret_cast(fCursor) + 1) & mask; - uintptr_t totalSize = size + alignedOffset; - AssertRelease(totalSize >= size); - - if (totalSize > static_cast(fEnd - fCursor)) { - this->ensureSpace(size, alignment); - alignedOffset = (~reinterpret_cast(fCursor) + 1) & mask; - } - return fCursor + alignedOffset; - } - - char* allocObjectWithFooter(uint32_t sizeIncludingFooter, uint32_t alignment); - - template - char* commonArrayAlloc(uint32_t count) { - char* objStart; - AssertRelease(count <= std::numeric_limits::max() / sizeof(T)); - uint32_t arraySize = ToU32(count * sizeof(T)); - uint32_t alignment = ToU32(alignof(T)); - - if (std::is_trivially_destructible::value) { - objStart = this->allocObject(arraySize, alignment); - fCursor = objStart + arraySize; - } else { - constexpr uint32_t overhead = sizeof(Footer) + sizeof(uint32_t); - AssertRelease(arraySize <= std::numeric_limits::max() - overhead); - uint32_t totalSize = arraySize + overhead; - objStart = this->allocObjectWithFooter(totalSize, alignment); - - // Can never be UB because max value is alignof(T). - uint32_t padding = ToU32(objStart - fCursor); - - // Advance to end of array to install footer.? - fCursor = objStart + arraySize; - this->installUint32Footer( - [](char* footerEnd) { - char* objEnd = footerEnd - (sizeof(Footer) + sizeof(uint32_t)); - uint32_t count; - memmove(&count, objEnd, sizeof(uint32_t)); - char* objStart = objEnd - count * sizeof(T); - T* array = (T*) objStart; - for (uint32_t i = 0; i < count; i++) { - array[i].~T(); - } - return objStart; - }, - ToU32(count), - padding); - } - - return objStart; - } - - char* fDtorCursor; - char* fCursor; - char* fEnd; - char* const fFirstBlock; - const uint32_t fFirstSize; - const uint32_t fFirstHeapAllocationSize; - - // Use the Fibonacci sequence as the growth factor for block size. The size of the block - // allocated is fFib0 * fFirstHeapAllocationSize. Using 2 ^ n * fFirstHeapAllocationSize - // had too much slop for Android. - uint32_t fFib0 {1}, fFib1 {1}; -}; - -// Helper for defining allocators with inline/reserved storage. -// For argument declarations, stick to the base type (SkArenaAlloc). -template -class VSTArenaAlloc : public VArenaAlloc { -public: - explicit VSTArenaAlloc(size_t firstHeapAllocation = InlineStorageSize) - : VArenaAlloc(fInlineStorage, InlineStorageSize, firstHeapAllocation) {} - -private: - char fInlineStorage[InlineStorageSize]; -}; - -#endif // VARENAALLOC_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vbezier.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vbezier.cpp deleted file mode 100644 index 15889299..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vbezier.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "vbezier.h" -#include -#include "vline.h" - -V_BEGIN_NAMESPACE - -VBezier VBezier::fromPoints(const VPointF &p1, const VPointF &p2, - const VPointF &p3, const VPointF &p4) -{ - VBezier b; - b.x1 = p1.x(); - b.y1 = p1.y(); - b.x2 = p2.x(); - b.y2 = p2.y(); - b.x3 = p3.x(); - b.y3 = p3.y(); - b.x4 = p4.x(); - b.y4 = p4.y(); - return b; -} - -float VBezier::length() const -{ - const auto len = VLine::length(x1, y1, x2, y2) + - VLine::length(x2, y2, x3, y3) + - VLine::length(x3, y3, x4, y4); - - const auto chord = VLine::length(x1, y1, x4, y4); - - if ((len - chord) > 0.01) { - VBezier left, right; - split(&left, &right); - return left.length() + right.length(); - } - - return len; -} - -VBezier VBezier::onInterval(float t0, float t1) const -{ - if (t0 == 0 && t1 == 1) return *this; - - VBezier bezier = *this; - - VBezier result; - bezier.parameterSplitLeft(t0, &result); - float trueT = (t1 - t0) / (1 - t0); - bezier.parameterSplitLeft(trueT, &result); - - return result; -} - -float VBezier::tAtLength(float l, float totalLength) const -{ - float t = 1.0; - const float error = 0.01f; - if (l > totalLength || vCompare(l, totalLength)) return t; - - t *= 0.5; - - float lastBigger = 1.0; - for (int num = 0; num < 100500; num++) { - VBezier right = *this; - VBezier left; - right.parameterSplitLeft(t, &left); - float lLen = left.length(); - if (fabs(lLen - l) < error) return t; - - if (lLen < l) { - t += (lastBigger - t) * 0.5f; - } else { - lastBigger = t; - t -= t * 0.5f; - } - } - vWarning << "no convergence"; - return t; -} - -void VBezier::splitAtLength(float len, VBezier *left, VBezier *right) -{ - float t; - - *right = *this; - t = right->tAtLength(len); - right->parameterSplitLeft(t, left); -} - -VPointF VBezier::derivative(float t) const -{ - // p'(t) = 3 * (-(1-2t+t^2) * p0 + (1 - 4 * t + 3 * t^2) * p1 + (2 * t - 3 * - // t^2) * p2 + t^2 * p3) - - float m_t = 1.0f - t; - - float d = t * t; - float a = -m_t * m_t; - float b = 1 - 4 * t + 3 * d; - float c = 2 * t - 3 * d; - - return 3 * VPointF(a * x1 + b * x2 + c * x3 + d * x4, - a * y1 + b * y2 + c * y3 + d * y4); -} - -float VBezier::angleAt(float t) const -{ - if (t < 0 || t > 1) { - return 0; - } - return VLine({}, derivative(t)).angle(); -} - -V_END_NAMESPACE diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vbezier.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vbezier.h deleted file mode 100644 index 18b7c596..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vbezier.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VBEZIER_H -#define VBEZIER_H - -#include - -V_BEGIN_NAMESPACE - -class VBezier { -public: - VBezier() = default; - VPointF pointAt(float t) const; - float angleAt(float t) const; - VBezier onInterval(float t0, float t1) const; - float length() const; - static void coefficients(float t, float &a, float &b, float &c, float &d); - static VBezier fromPoints(const VPointF &start, const VPointF &cp1, - const VPointF &cp2, const VPointF &end); - inline void parameterSplitLeft(float t, VBezier *left); - inline void split(VBezier *firstHalf, VBezier *secondHalf) const; - float tAtLength(float len) const { return tAtLength(len , length());} - float tAtLength(float len, float totalLength) const; - void splitAtLength(float len, VBezier *left, VBezier *right); - VPointF pt1() const { return {x1, y1}; } - VPointF pt2() const { return {x2, y2}; } - VPointF pt3() const { return {x3, y3}; } - VPointF pt4() const { return {x4, y4}; } - -private: - VPointF derivative(float t) const; - float x1, y1, x2, y2, x3, y3, x4, y4; -}; - -inline void VBezier::coefficients(float t, float &a, float &b, float &c, - float &d) -{ - float m_t = 1.0f - t; - b = m_t * m_t; - c = t * t; - d = c * t; - a = b * m_t; - b *= 3.0f * t; - c *= 3.0f * m_t; -} - -inline VPointF VBezier::pointAt(float t) const -{ - // numerically more stable: - float x, y; - - float m_t = 1.0f - t; - { - float a = x1 * m_t + x2 * t; - float b = x2 * m_t + x3 * t; - float c = x3 * m_t + x4 * t; - a = a * m_t + b * t; - b = b * m_t + c * t; - x = a * m_t + b * t; - } - { - float a = y1 * m_t + y2 * t; - float b = y2 * m_t + y3 * t; - float c = y3 * m_t + y4 * t; - a = a * m_t + b * t; - b = b * m_t + c * t; - y = a * m_t + b * t; - } - return {x, y}; -} - -inline void VBezier::parameterSplitLeft(float t, VBezier *left) -{ - left->x1 = x1; - left->y1 = y1; - - left->x2 = x1 + t * (x2 - x1); - left->y2 = y1 + t * (y2 - y1); - - left->x3 = x2 + t * (x3 - x2); // temporary holding spot - left->y3 = y2 + t * (y3 - y2); // temporary holding spot - - x3 = x3 + t * (x4 - x3); - y3 = y3 + t * (y4 - y3); - - x2 = left->x3 + t * (x3 - left->x3); - y2 = left->y3 + t * (y3 - left->y3); - - left->x3 = left->x2 + t * (left->x3 - left->x2); - left->y3 = left->y2 + t * (left->y3 - left->y2); - - left->x4 = x1 = left->x3 + t * (x2 - left->x3); - left->y4 = y1 = left->y3 + t * (y2 - left->y3); -} - -inline void VBezier::split(VBezier *firstHalf, VBezier *secondHalf) const -{ - float c = (x2 + x3) * 0.5f; - firstHalf->x2 = (x1 + x2) * 0.5f; - secondHalf->x3 = (x3 + x4) * 0.5f; - firstHalf->x1 = x1; - secondHalf->x4 = x4; - firstHalf->x3 = (firstHalf->x2 + c) * 0.5f; - secondHalf->x2 = (secondHalf->x3 + c) * 0.5f; - firstHalf->x4 = secondHalf->x1 = (firstHalf->x3 + secondHalf->x2) * 0.5f; - - c = (y2 + y3) / 2; - firstHalf->y2 = (y1 + y2) * 0.5f; - secondHalf->y3 = (y3 + y4) * 0.5f; - firstHalf->y1 = y1; - secondHalf->y4 = y4; - firstHalf->y3 = (firstHalf->y2 + c) * 0.5f; - secondHalf->y2 = (secondHalf->y3 + c) * 0.5f; - firstHalf->y4 = secondHalf->y1 = (firstHalf->y3 + secondHalf->y2) * 0.5f; -} - -V_END_NAMESPACE - -#endif // VBEZIER_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vbitmap.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vbitmap.cpp deleted file mode 100644 index 378db227..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vbitmap.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "vbitmap.h" -#include -#include -#include "vdrawhelper.h" -#include "vglobal.h" - -V_BEGIN_NAMESPACE - -void VBitmap::Impl::reset(size_t width, size_t height, VBitmap::Format format) -{ - mRoData = nullptr; - mWidth = uint32_t(width); - mHeight = uint32_t(height); - mFormat = format; - - mDepth = depth(format); - mStride = ((mWidth * mDepth + 31) >> 5) - << 2; // bytes per scanline (must be multiple of 4) - mOwnData = std::make_unique(mStride * mHeight); -} - -void VBitmap::Impl::reset(uint8_t *data, size_t width, size_t height, - size_t bytesPerLine, VBitmap::Format format) -{ - mRoData = data; - mWidth = uint32_t(width); - mHeight = uint32_t(height); - mStride = uint32_t(bytesPerLine); - mFormat = format; - mDepth = depth(format); - mOwnData = nullptr; -} - -uint8_t VBitmap::Impl::depth(VBitmap::Format format) -{ - uint8_t depth = 1; - switch (format) { - case VBitmap::Format::Alpha8: - depth = 8; - break; - case VBitmap::Format::ARGB32: - case VBitmap::Format::ARGB32_Premultiplied: - depth = 32; - break; - default: - break; - } - return depth; -} - -void VBitmap::Impl::fill(uint32_t /*pixel*/) -{ - //@TODO -} - -void VBitmap::Impl::updateLuma() -{ - if (mFormat != VBitmap::Format::ARGB32_Premultiplied) return; - auto dataPtr = data(); - for (uint32_t col = 0; col < mHeight; col++) { - uint32_t *pixel = (uint32_t *)(dataPtr + mStride * col); - for (uint32_t row = 0; row < mWidth; row++) { - int alpha = vAlpha(*pixel); - if (alpha == 0) { - pixel++; - continue; - } - - int red = vRed(*pixel); - int green = vGreen(*pixel); - int blue = vBlue(*pixel); - - if (alpha != 255) { - // un multiply - red = (red * 255) / alpha; - green = (green * 255) / alpha; - blue = (blue * 255) / alpha; - } - int luminosity = int(0.299f * red + 0.587f * green + 0.114f * blue); - *pixel = luminosity << 24; - pixel++; - } - } -} - -VBitmap::VBitmap(size_t width, size_t height, VBitmap::Format format) -{ - if (width <= 0 || height <= 0 || format == Format::Invalid) return; - - mImpl = rc_ptr(width, height, format); -} - -VBitmap::VBitmap(uint8_t *data, size_t width, size_t height, - size_t bytesPerLine, VBitmap::Format format) -{ - if (!data || width <= 0 || height <= 0 || bytesPerLine <= 0 || - format == Format::Invalid) - return; - - mImpl = rc_ptr(data, width, height, bytesPerLine, format); -} - -void VBitmap::reset(uint8_t *data, size_t w, size_t h, size_t bytesPerLine, - VBitmap::Format format) -{ - if (mImpl) { - mImpl->reset(data, w, h, bytesPerLine, format); - } else { - mImpl = rc_ptr(data, w, h, bytesPerLine, format); - } -} - -void VBitmap::reset(size_t w, size_t h, VBitmap::Format format) -{ - if (mImpl) { - if (w == mImpl->width() && h == mImpl->height() && - format == mImpl->format()) { - return; - } - mImpl->reset(w, h, format); - } else { - mImpl = rc_ptr(w, h, format); - } -} - -size_t VBitmap::stride() const -{ - return mImpl ? mImpl->stride() : 0; -} - -size_t VBitmap::width() const -{ - return mImpl ? mImpl->width() : 0; -} - -size_t VBitmap::height() const -{ - return mImpl ? mImpl->height() : 0; -} - -size_t VBitmap::depth() const -{ - return mImpl ? mImpl->mDepth : 0; -} - -uint8_t *VBitmap::data() -{ - return mImpl ? mImpl->data() : nullptr; -} - -uint8_t *VBitmap::data() const -{ - return mImpl ? mImpl->data() : nullptr; -} - -VRect VBitmap::rect() const -{ - return mImpl ? mImpl->rect() : VRect(); -} - -VSize VBitmap::size() const -{ - return mImpl ? mImpl->size() : VSize(); -} - -bool VBitmap::valid() const -{ - return mImpl; -} - -VBitmap::Format VBitmap::format() const -{ - return mImpl ? mImpl->format() : VBitmap::Format::Invalid; -} - -void VBitmap::fill(uint32_t pixel) -{ - if (mImpl) mImpl->fill(pixel); -} - -/* - * This is special function which converts - * RGB value to Luminosity and stores it in - * the Alpha component of the pixel. - * After this conversion the bitmap data is no more - * in RGB space. but the Alpha component contains the - * Luminosity value of the pixel in HSL color space. - * NOTE: this api has its own special usecase - * make sure you know what you are doing before using - * this api. - */ -void VBitmap::updateLuma() -{ - if (mImpl) mImpl->updateLuma(); -} - -V_END_NAMESPACE diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vbitmap.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vbitmap.h deleted file mode 100644 index bc5059a7..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vbitmap.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VBITMAP_H -#define VBITMAP_H - -#include "vrect.h" -#include - -V_BEGIN_NAMESPACE - -class VBitmap { -public: - enum class Format : uint8_t { - Invalid, - Alpha8, - ARGB32, - ARGB32_Premultiplied - }; - - VBitmap() = default; - VBitmap(size_t w, size_t h, VBitmap::Format format); - VBitmap(uint8_t *data, size_t w, size_t h, size_t bytesPerLine, - VBitmap::Format format); - void reset(uint8_t *data, size_t w, size_t h, size_t stride, - VBitmap::Format format); - void reset(size_t w, size_t h, VBitmap::Format format=Format::ARGB32_Premultiplied); - size_t stride() const; - size_t width() const; - size_t height() const; - size_t depth() const; - VBitmap::Format format() const; - bool valid() const; - uint8_t * data(); - uint8_t * data() const; - VRect rect() const; - VSize size() const; - void fill(uint32_t pixel); - void updateLuma(); -private: - struct Impl { - std::unique_ptr mOwnData{nullptr}; - uint8_t * mRoData{nullptr}; - uint32_t mWidth{0}; - uint32_t mHeight{0}; - uint32_t mStride{0}; - uint8_t mDepth{0}; - VBitmap::Format mFormat{VBitmap::Format::Invalid}; - - explicit Impl(size_t width, size_t height, VBitmap::Format format) - { - reset(width, height, format); - } - explicit Impl(uint8_t *data, size_t w, size_t h, size_t bytesPerLine, - VBitmap::Format format) - { - reset(data, w, h, bytesPerLine, format); - } - VRect rect() const { return VRect(0, 0, mWidth, mHeight);} - VSize size() const { return VSize(mWidth, mHeight); } - size_t stride() const { return mStride; } - size_t width() const { return mWidth; } - size_t height() const { return mHeight; } - uint8_t * data() { return mRoData ? mRoData : mOwnData.get(); } - VBitmap::Format format() const { return mFormat; } - void reset(uint8_t *, size_t, size_t, size_t, VBitmap::Format); - void reset(size_t, size_t, VBitmap::Format); - static uint8_t depth(VBitmap::Format format); - void fill(uint32_t); - void updateLuma(); - }; - - rc_ptr mImpl; -}; - -V_END_NAMESPACE - -#endif // VBITMAP_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vbrush.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vbrush.cpp deleted file mode 100644 index f2ab3387..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vbrush.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "vbrush.h" - -V_BEGIN_NAMESPACE - -VGradient::VGradient(VGradient::Type type) - : mType(type) -{ - if (mType == Type::Linear) - linear.x1 = linear.y1 = linear.x2 = linear.y2 = 0.0f; - else - radial.cx = radial.cy = radial.fx = - radial.fy = radial.cradius = radial.fradius = 0.0f; -} - -void VGradient::setStops(const VGradientStops &stops) -{ - mStops = stops; -} - -VBrush::VBrush(const VColor &color) : mType(VBrush::Type::Solid), mColor(color) -{ -} - -VBrush::VBrush(uint8_t r, uint8_t g, uint8_t b, uint8_t a) - : mType(VBrush::Type::Solid), mColor(r, g, b, a) - -{ -} - -VBrush::VBrush(const VGradient *gradient) -{ - if (!gradient) return; - - mGradient = gradient; - - if (gradient->mType == VGradient::Type::Linear) { - mType = VBrush::Type::LinearGradient; - } else if (gradient->mType == VGradient::Type::Radial) { - mType = VBrush::Type::RadialGradient; - } -} - -VBrush::VBrush(const VTexture *texture):mType(VBrush::Type::Texture), mTexture(texture) -{ -} - -V_END_NAMESPACE diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vbrush.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vbrush.h deleted file mode 100644 index a1abbd34..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vbrush.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VBRUSH_H -#define VBRUSH_H - -#include -#include "vglobal.h" -#include "vmatrix.h" -#include "vpoint.h" -#include "vbitmap.h" - -V_BEGIN_NAMESPACE - -using VGradientStop = std::pair; -using VGradientStops = std::vector; -class VGradient { -public: - enum class Mode { Absolute, Relative }; - enum class Spread { Pad, Repeat, Reflect }; - enum class Type { Linear, Radial }; - explicit VGradient(VGradient::Type type); - void setStops(const VGradientStops &stops); - void setAlpha(float alpha) {mAlpha = alpha;} - float alpha() const {return mAlpha;} - -public: - static constexpr int colorTableSize = 1024; - VGradient::Type mType{Type::Linear}; - VGradient::Spread mSpread{Spread::Pad}; - VGradient::Mode mMode{Mode::Absolute}; - VGradientStops mStops; - float mAlpha{1.0}; - struct Linear{ - float x1{0}, y1{0}, x2{0}, y2{0}; - }; - struct Radial{ - float cx{0}, cy{0}, fx{0}, fy{0}, cradius{0}, fradius{0}; - }; - union { - Linear linear; - Radial radial; - }; - VMatrix mMatrix; -}; - -struct VTexture { - VBitmap mBitmap; - VMatrix mMatrix; - int mAlpha{255}; -}; - -class VBrush { -public: - enum class Type { NoBrush, Solid, LinearGradient, RadialGradient, Texture }; - VBrush():mType(Type::NoBrush),mColor(){}; - explicit VBrush(const VColor &color); - explicit VBrush(const VGradient *gradient); - explicit VBrush(uint8_t r, uint8_t g, uint8_t b, uint8_t a); - explicit VBrush(const VTexture *texture); - inline VBrush::Type type() const { return mType; } -public: - VBrush::Type mType{Type::NoBrush}; - union { - VColor mColor{}; - const VGradient *mGradient; - const VTexture *mTexture; - }; -}; - -V_END_NAMESPACE - -#endif // VBRUSH_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vcowptr.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vcowptr.h deleted file mode 100644 index af2c7f24..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vcowptr.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VCOWPTR_H -#define VCOWPTR_H - -#include -#include - -template -class vcow_ptr { - struct model { - std::atomic mRef{1}; - - model() = default; - - template - explicit model(Args&&... args) : mValue(std::forward(args)...){} - explicit model(const T& other) : mValue(other){} - - T mValue; - }; - model* mModel; - -public: - using element_type = T; - - vcow_ptr() - { - static model default_s; - mModel = &default_s; - ++mModel->mRef; - } - - ~vcow_ptr() - { - if (mModel && (--mModel->mRef == 0)) delete mModel; - } - - template - explicit vcow_ptr(Args&&... args) : mModel(new model(std::forward(args)...)) - { - } - - vcow_ptr(const vcow_ptr& x) noexcept : mModel(x.mModel) - { - assert(mModel); - ++mModel->mRef; - } - vcow_ptr(vcow_ptr&& x) noexcept : mModel(x.mModel) - { - assert(mModel); - x.mModel = nullptr; - } - - auto operator=(const vcow_ptr& x) noexcept -> vcow_ptr& - { - *this = vcow_ptr(x); - return *this; - } - - auto operator=(vcow_ptr&& x) noexcept -> vcow_ptr& - { - auto tmp = std::move(x); - swap(*this, tmp); - return *this; - } - - auto operator*() const noexcept -> const element_type& { return read(); } - - auto operator-> () const noexcept -> const element_type* { return &read(); } - - std::size_t refCount() const noexcept - { - assert(mModel); - - return mModel->mRef; - } - - bool unique() const noexcept - { - assert(mModel); - - return mModel->mRef == 1; - } - - auto write() -> element_type& - { - if (!unique()) *this = vcow_ptr(read()); - - return mModel->mValue; - } - - auto read() const noexcept -> const element_type& - { - assert(mModel); - - return mModel->mValue; - } - - friend inline void swap(vcow_ptr& x, vcow_ptr& y) noexcept - { - std::swap(x.mModel, y.mModel); - } -}; - -#endif // VCOWPTR_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdasher.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vdasher.cpp deleted file mode 100644 index 759e30ac..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdasher.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "vbezier.h" - -#include - -#include "vdasher.h" -#include "vline.h" - -V_BEGIN_NAMESPACE - -static constexpr float tolerance = 0.1f; -VDasher::VDasher(const float *dashArray, size_t size) -{ - mDashArray = reinterpret_cast(dashArray); - mArraySize = size / 2; - if (size % 2) mDashOffset = dashArray[size - 1]; - mIndex = 0; - mCurrentLength = 0; - mDiscard = false; - //if the dash array contains ZERO length - // segments or ZERO lengths gaps we could - // optimize those usecase. - for (size_t i = 0; i < mArraySize; i++) { - if (!vCompare(mDashArray[i].length, 0.0f)) - mNoLength = false; - if (!vCompare(mDashArray[i].gap, 0.0f)) - mNoGap = false; - } -} - -void VDasher::moveTo(const VPointF &p) -{ - mDiscard = false; - mStartNewSegment = true; - mCurPt = p; - mIndex = 0; - - if (!vCompare(mDashOffset, 0.0f)) { - float totalLength = 0.0; - for (size_t i = 0; i < mArraySize; i++) { - totalLength = mDashArray[i].length + mDashArray[i].gap; - } - float normalizeLen = std::fmod(mDashOffset, totalLength); - if (normalizeLen < 0.0f) { - normalizeLen = totalLength + normalizeLen; - } - // now the length is less than total length and +ve - // findout the current dash index , dashlength and gap. - for (size_t i = 0; i < mArraySize; i++) { - if (normalizeLen < mDashArray[i].length) { - mIndex = i; - mCurrentLength = mDashArray[i].length - normalizeLen; - mDiscard = false; - break; - } - normalizeLen -= mDashArray[i].length; - if (normalizeLen < mDashArray[i].gap) { - mIndex = i; - mCurrentLength = mDashArray[i].gap - normalizeLen; - mDiscard = true; - break; - } - normalizeLen -= mDashArray[i].gap; - } - } else { - mCurrentLength = mDashArray[mIndex].length; - } - if (vIsZero(mCurrentLength)) updateActiveSegment(); -} - -void VDasher::addLine(const VPointF &p) -{ - if (mDiscard) return; - - if (mStartNewSegment) { - mResult->moveTo(mCurPt); - mStartNewSegment = false; - } - mResult->lineTo(p); -} - -void VDasher::updateActiveSegment() -{ - mStartNewSegment = true; - - if (mDiscard) { - mDiscard = false; - mIndex = (mIndex + 1) % mArraySize; - mCurrentLength = mDashArray[mIndex].length; - } else { - mDiscard = true; - mCurrentLength = mDashArray[mIndex].gap; - } - if (vIsZero(mCurrentLength)) updateActiveSegment(); -} - -void VDasher::lineTo(const VPointF &p) -{ - VLine left, right; - VLine line(mCurPt, p); - float length = line.length(); - - if (length <= mCurrentLength) { - mCurrentLength -= length; - addLine(p); - } else { - while (length > mCurrentLength) { - length -= mCurrentLength; - line.splitAtLength(mCurrentLength, left, right); - - addLine(left.p2()); - updateActiveSegment(); - - line = right; - mCurPt = line.p1(); - } - // handle remainder - if (length > tolerance) { - mCurrentLength -= length; - addLine(line.p2()); - } - } - - if (mCurrentLength < tolerance) updateActiveSegment(); - - mCurPt = p; -} - -void VDasher::addCubic(const VPointF &cp1, const VPointF &cp2, const VPointF &e) -{ - if (mDiscard) return; - - if (mStartNewSegment) { - mResult->moveTo(mCurPt); - mStartNewSegment = false; - } - mResult->cubicTo(cp1, cp2, e); -} - -void VDasher::cubicTo(const VPointF &cp1, const VPointF &cp2, const VPointF &e) -{ - VBezier left, right; - VBezier b = VBezier::fromPoints(mCurPt, cp1, cp2, e); - float bezLen = b.length(); - - if (bezLen <= mCurrentLength) { - mCurrentLength -= bezLen; - addCubic(cp1, cp2, e); - } else { - while (bezLen > mCurrentLength) { - bezLen -= mCurrentLength; - b.splitAtLength(mCurrentLength, &left, &right); - - addCubic(left.pt2(), left.pt3(), left.pt4()); - updateActiveSegment(); - - b = right; - mCurPt = b.pt1(); - } - // handle remainder - if (bezLen > tolerance) { - mCurrentLength -= bezLen; - addCubic(b.pt2(), b.pt3(), b.pt4()); - } - } - - if (mCurrentLength < tolerance) updateActiveSegment(); - - mCurPt = e; -} - -void VDasher::dashHelper(const VPath &path, VPath &result) -{ - mResult = &result; - mResult->reserve(path.points().size(), path.elements().size()); - mIndex = 0; - const std::vector &elms = path.elements(); - const std::vector & pts = path.points(); - const VPointF * ptPtr = pts.data(); - - for (auto &i : elms) { - switch (i) { - case VPath::Element::MoveTo: { - moveTo(*ptPtr++); - break; - } - case VPath::Element::LineTo: { - lineTo(*ptPtr++); - break; - } - case VPath::Element::CubicTo: { - cubicTo(*ptPtr, *(ptPtr + 1), *(ptPtr + 2)); - ptPtr += 3; - break; - } - case VPath::Element::Close: { - // The point is already joined to start point in VPath - // no need to do anything here. - break; - } - } - } - mResult = nullptr; -} - -void VDasher::dashed(const VPath &path, VPath &result) -{ - if (mNoLength && mNoGap) return result.reset(); - - if (path.empty() || mNoLength) return result.reset(); - - if (mNoGap) return result.clone(path); - - result.reset(); - - dashHelper(path, result); -} - -VPath VDasher::dashed(const VPath &path) -{ - if (mNoLength && mNoGap) return path; - - if (path.empty() || mNoLength) return VPath(); - - if (mNoGap) return path; - - VPath result; - - dashHelper(path, result); - - return result; -} - -V_END_NAMESPACE diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdasher.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vdasher.h deleted file mode 100644 index d9d62c2f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdasher.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VDASHER_H -#define VDASHER_H -#include "vpath.h" - -V_BEGIN_NAMESPACE - -class VDasher { -public: - VDasher(const float *dashArray, size_t size); - VPath dashed(const VPath &path); - void dashed(const VPath &path, VPath &result); - -private: - void moveTo(const VPointF &p); - void lineTo(const VPointF &p); - void cubicTo(const VPointF &cp1, const VPointF &cp2, const VPointF &e); - void close(); - void addLine(const VPointF &p); - void addCubic(const VPointF &cp1, const VPointF &cp2, const VPointF &e); - void updateActiveSegment(); - -private: - void dashHelper(const VPath &path, VPath &result); - struct Dash { - float length; - float gap; - }; - const VDasher::Dash *mDashArray; - size_t mArraySize{0}; - VPointF mCurPt; - size_t mIndex{0}; /* index to the dash Array */ - float mCurrentLength; - float mDashOffset{0}; - VPath *mResult{nullptr}; - bool mDiscard{false}; - bool mStartNewSegment{true}; - bool mNoLength{true}; - bool mNoGap{true}; -}; - -V_END_NAMESPACE - -#endif // VDASHER_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdebug.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vdebug.cpp deleted file mode 100644 index 03196ef3..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdebug.cpp +++ /dev/null @@ -1,758 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "vdebug.h" - -#ifdef LOTTIE_LOGGING_SUPPORT - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace { - -/* Returns microseconds since epoch */ -uint64_t timestamp_now() -{ - return std::chrono::duration_cast( - std::chrono::high_resolution_clock::now().time_since_epoch()) - .count(); -} - -/* I want [2016-10-13 00:01:23.528514] */ -void format_timestamp(std::ostream& os, uint64_t timestamp) -{ - // The next 3 lines do not work on MSVC! - // auto duration = std::chrono::microseconds(timestamp); - // std::chrono::high_resolution_clock::time_point time_point(duration); - // std::time_t time_t = - // std::chrono::high_resolution_clock::to_time_t(time_point); - std::time_t time_t = timestamp / 1000000; - auto gmtime = std::gmtime(&time_t); - char buffer[32]; - strftime(buffer, 32, "%Y-%m-%d %T.", gmtime); - char microseconds[7]; - snprintf(microseconds, 7, "%06llu", - (long long unsigned int)timestamp % 1000000); - os << '[' << buffer << microseconds << ']'; -} - -std::thread::id this_thread_id() -{ - static thread_local const std::thread::id id = std::this_thread::get_id(); - return id; -} - -template -struct TupleIndex; - -template -struct TupleIndex > { - static constexpr const std::size_t value = 0; -}; - -template -struct TupleIndex > { - static constexpr const std::size_t value = - 1 + TupleIndex >::value; -}; - -} // anonymous namespace - -typedef std::tuple - SupportedTypes; - -char const* to_string(LogLevel loglevel) -{ - switch (loglevel) { - case LogLevel::OFF: - return "OFF"; - case LogLevel::INFO: - return "INFO"; - case LogLevel::WARN: - return "WARN"; - case LogLevel::CRIT: - return "CRIT"; - } - return "XXXX"; -} - -template -void VDebug::encode(Arg arg) -{ - *reinterpret_cast(buffer()) = arg; - m_bytes_used += sizeof(Arg); -} - -template -void VDebug::encode(Arg arg, uint8_t type_id) -{ - resize_buffer_if_needed(sizeof(Arg) + sizeof(uint8_t)); - encode(type_id); - encode(arg); -} - -VDebug::VDebug(LogLevel level, char const* file, char const* function, - uint32_t line) - : m_bytes_used(0), m_buffer_size(sizeof(m_stack_buffer)) -{ - encode(timestamp_now()); - encode(this_thread_id()); - encode(string_literal_t(file)); - encode(string_literal_t(function)); - encode(line); - encode(level); - if (level == LogLevel::INFO) { - m_logAll = false; - } else { - m_logAll = true; - } -} - -VDebug::~VDebug() = default; - -void VDebug::stringify(std::ostream& os) -{ - char* b = !m_heap_buffer ? m_stack_buffer : m_heap_buffer.get(); - char const* const end = b + m_bytes_used; - uint64_t timestamp = *reinterpret_cast(b); - b += sizeof(uint64_t); - std::thread::id threadid = *reinterpret_cast(b); - b += sizeof(std::thread::id); - string_literal_t file = *reinterpret_cast(b); - b += sizeof(string_literal_t); - string_literal_t function = *reinterpret_cast(b); - b += sizeof(string_literal_t); - uint32_t line = *reinterpret_cast(b); - b += sizeof(uint32_t); - LogLevel loglevel = *reinterpret_cast(b); - b += sizeof(LogLevel); - if (m_logAll) { - format_timestamp(os, timestamp); - - os << '[' << to_string(loglevel) << ']' << '[' << threadid << ']' << '[' - << file.m_s << ':' << function.m_s << ':' << line << "] "; - } - - stringify(os, b, end); - os << std::endl; - - if (loglevel >= LogLevel::CRIT) os.flush(); -} - -template -char* decode(std::ostream& os, char* b, Arg* /*dummy*/) -{ - Arg arg = *reinterpret_cast(b); - os << arg; - return b + sizeof(Arg); -} - -template <> -char* decode(std::ostream& os, char* b, VDebug::string_literal_t* /*dummy*/) -{ - VDebug::string_literal_t s = - *reinterpret_cast(b); - os << s.m_s; - return b + sizeof(VDebug::string_literal_t); -} - -template <> -char* decode(std::ostream& os, char* b, char** /*dummy*/) -{ - while (*b != '\0') { - os << *b; - ++b; - } - return ++b; -} - -void VDebug::stringify(std::ostream& os, char* start, char const* const end) -{ - if (start == end) return; - - int type_id = static_cast(*start); - start++; - - switch (type_id) { - case 0: - stringify( - os, - decode(os, start, - static_cast::type*>( - nullptr)), - end); - return; - case 1: - stringify( - os, - decode(os, start, - static_cast::type*>( - nullptr)), - end); - return; - case 2: - stringify( - os, - decode(os, start, - static_cast::type*>( - nullptr)), - end); - return; - case 3: - stringify( - os, - decode(os, start, - static_cast::type*>( - nullptr)), - end); - return; - case 4: - stringify( - os, - decode(os, start, - static_cast::type*>( - nullptr)), - end); - return; - case 5: - stringify( - os, - decode(os, start, - static_cast::type*>( - nullptr)), - end); - return; - case 6: - stringify( - os, - decode(os, start, - static_cast::type*>( - nullptr)), - end); - return; - case 7: - stringify( - os, - decode(os, start, - static_cast::type*>( - nullptr)), - end); - return; - } -} - -char* VDebug::buffer() -{ - return !m_heap_buffer ? &m_stack_buffer[m_bytes_used] - : &(m_heap_buffer.get())[m_bytes_used]; -} - -void VDebug::resize_buffer_if_needed(size_t additional_bytes) -{ - size_t const required_size = m_bytes_used + additional_bytes; - - if (required_size <= m_buffer_size) return; - - if (!m_heap_buffer) { - m_buffer_size = std::max(static_cast(512), required_size); - m_heap_buffer = std::make_unique(m_buffer_size); - memcpy(m_heap_buffer.get(), m_stack_buffer, m_bytes_used); - return; - } else { - m_buffer_size = - std::max(static_cast(2 * m_buffer_size), required_size); - std::unique_ptr new_heap_buffer(new char[m_buffer_size]); - memcpy(new_heap_buffer.get(), m_heap_buffer.get(), m_bytes_used); - m_heap_buffer.swap(new_heap_buffer); - } -} - -void VDebug::encode(char const* arg) -{ - if (arg != nullptr) encode_c_string(arg, strlen(arg)); -} - -void VDebug::encode(char* arg) -{ - if (arg != nullptr) encode_c_string(arg, strlen(arg)); -} - -void VDebug::encode_c_string(char const* arg, size_t length) -{ - if (length == 0) return; - - resize_buffer_if_needed(1 + length + 1); - char* b = buffer(); - auto type_id = TupleIndex::value; - *reinterpret_cast(b++) = static_cast(type_id); - memcpy(b, arg, length + 1); - m_bytes_used += 1 + length + 1; -} - -void VDebug::encode(string_literal_t arg) -{ - encode( - arg, TupleIndex::value); -} - -VDebug& VDebug::operator<<(std::string const& arg) -{ - encode_c_string(arg.c_str(), arg.length()); - return *this; -} - -VDebug& VDebug::operator<<(int32_t arg) -{ - encode(arg, TupleIndex::value); - return *this; -} - -VDebug& VDebug::operator<<(uint32_t arg) -{ - encode(arg, TupleIndex::value); - return *this; -} - -// VDebug& VDebug::operator<<(int64_t arg) -// { -// encode < int64_t >(arg, TupleIndex < int64_t, SupportedTypes >::value); -// return *this; -// } - -// VDebug& VDebug::operator<<(uint64_t arg) -// { -// encode < uint64_t >(arg, TupleIndex < uint64_t, SupportedTypes >::value); -// return *this; -// } -VDebug& VDebug::operator<<(unsigned long arg) -{ - encode(arg, TupleIndex::value); - return *this; -} - -VDebug& VDebug::operator<<(long arg) -{ - encode(arg, TupleIndex::value); - return *this; -} - -VDebug& VDebug::operator<<(double arg) -{ - encode(arg, TupleIndex::value); - return *this; -} - -VDebug& VDebug::operator<<(char arg) -{ - encode(arg, TupleIndex::value); - return *this; -} - -struct BufferBase { - virtual ~BufferBase() = default; - virtual void push(VDebug&& logline) = 0; - virtual bool try_pop(VDebug& logline) = 0; -}; - -struct SpinLock { - SpinLock(std::atomic_flag& flag) : m_flag(flag) - { - while (m_flag.test_and_set(std::memory_order_acquire)) - ; - } - - ~SpinLock() { m_flag.clear(std::memory_order_release); } - -private: - std::atomic_flag& m_flag; -}; - -/* Multi Producer Single Consumer Ring Buffer */ -class RingBuffer : public BufferBase { -public: - struct alignas(64) Item { - Item() - : flag(), written(0), logline(LogLevel::INFO, nullptr, nullptr, 0) - { - } - - std::atomic_flag flag; - char written; - char padding[256 - sizeof(std::atomic_flag) - sizeof(char) - - sizeof(VDebug)]; - VDebug logline; - }; - - RingBuffer(size_t const size) - : m_size(size), - m_ring(static_cast(std::malloc(size * sizeof(Item)))), - m_write_index(0), - m_read_index(0) - { - for (size_t i = 0; i < m_size; ++i) { - new (&m_ring[i]) Item(); - } - static_assert(sizeof(Item) == 256, "Unexpected size != 256"); - } - - ~RingBuffer() override - { - for (size_t i = 0; i < m_size; ++i) { - m_ring[i].~Item(); - } - std::free(m_ring); - } - - void push(VDebug&& logline) override - { - unsigned int write_index = - m_write_index.fetch_add(1, std::memory_order_relaxed) % m_size; - Item& item = m_ring[write_index]; - SpinLock spinlock(item.flag); - item.logline = std::move(logline); - item.written = 1; - } - - bool try_pop(VDebug& logline) override - { - Item& item = m_ring[m_read_index % m_size]; - SpinLock spinlock(item.flag); - if (item.written == 1) { - logline = std::move(item.logline); - item.written = 0; - ++m_read_index; - return true; - } - return false; - } - - RingBuffer(RingBuffer const&) = delete; - RingBuffer& operator=(RingBuffer const&) = delete; - -private: - size_t const m_size; - Item* m_ring; - std::atomic m_write_index; - -public: - char pad[64]; - -private: - unsigned int m_read_index; -}; - -class Buffer { -public: - struct Item { - Item(VDebug&& logline) : logline(std::move(logline)) {} - char padding[256 - sizeof(VDebug)]; - VDebug logline; - }; - - static constexpr const size_t size = - 32768; // 8MB. Helps reduce memory fragmentation - - Buffer() : m_buffer(static_cast(std::malloc(size * sizeof(Item)))) - { - for (size_t i = 0; i <= size; ++i) { - m_write_state[i].store(0, std::memory_order_relaxed); - } - static_assert(sizeof(Item) == 256, "Unexpected size != 256"); - } - - ~Buffer() - { - unsigned int write_count = m_write_state[size].load(); - for (size_t i = 0; i < write_count; ++i) { - m_buffer[i].~Item(); - } - std::free(m_buffer); - } - - // Returns true if we need to switch to next buffer - bool push(VDebug&& logline, unsigned int const write_index) - { - new (&m_buffer[write_index]) Item(std::move(logline)); - m_write_state[write_index].store(1, std::memory_order_release); - return m_write_state[size].fetch_add(1, std::memory_order_acquire) + - 1 == - size; - } - - bool try_pop(VDebug& logline, unsigned int const read_index) - { - if (m_write_state[read_index].load(std::memory_order_acquire)) { - Item& item = m_buffer[read_index]; - logline = std::move(item.logline); - return true; - } - return false; - } - - Buffer(Buffer const&) = delete; - Buffer& operator=(Buffer const&) = delete; - -private: - Item* m_buffer; - std::atomic m_write_state[size + 1]; -}; - -class QueueBuffer : public BufferBase { -public: - QueueBuffer(QueueBuffer const&) = delete; - QueueBuffer& operator=(QueueBuffer const&) = delete; - - QueueBuffer() - : m_current_read_buffer{nullptr}, - m_write_index(0), - m_flag(), - m_read_index(0) - { - setup_next_write_buffer(); - } - - void push(VDebug&& logline) override - { - unsigned int write_index = - m_write_index.fetch_add(1, std::memory_order_relaxed); - if (write_index < Buffer::size) { - if (m_current_write_buffer.load(std::memory_order_acquire) - ->push(std::move(logline), write_index)) { - setup_next_write_buffer(); - } - } else { - while (m_write_index.load(std::memory_order_acquire) >= - Buffer::size) - ; - push(std::move(logline)); - } - } - - bool try_pop(VDebug& logline) override - { - if (m_current_read_buffer == nullptr) - m_current_read_buffer = get_next_read_buffer(); - - Buffer* read_buffer = m_current_read_buffer; - - if (read_buffer == nullptr) return false; - - if (read_buffer->try_pop(logline, m_read_index)) { - m_read_index++; - if (m_read_index == Buffer::size) { - m_read_index = 0; - m_current_read_buffer = nullptr; - SpinLock spinlock(m_flag); - m_buffers.pop(); - } - return true; - } - - return false; - } - -private: - void setup_next_write_buffer() - { - std::unique_ptr next_write_buffer(new Buffer()); - m_current_write_buffer.store(next_write_buffer.get(), - std::memory_order_release); - SpinLock spinlock(m_flag); - m_buffers.push(std::move(next_write_buffer)); - m_write_index.store(0, std::memory_order_relaxed); - } - - Buffer* get_next_read_buffer() - { - SpinLock spinlock(m_flag); - return m_buffers.empty() ? nullptr : m_buffers.front().get(); - } - -private: - std::queue > m_buffers; - std::atomic m_current_write_buffer; - Buffer* m_current_read_buffer; - std::atomic m_write_index; - std::atomic_flag m_flag; - unsigned int m_read_index; -}; - -class FileWriter { -public: - FileWriter(std::string const& log_directory, - std::string const& log_file_name, uint32_t log_file_roll_size_mb) - : m_log_file_roll_size_bytes(log_file_roll_size_mb * 1024 * 1024), - m_name(log_directory + log_file_name) - { - roll_file(); - } - - void write(VDebug& logline) - { - auto pos = m_os->tellp(); - logline.stringify(*m_os); - m_bytes_written += m_os->tellp() - pos; - if (m_bytes_written > m_log_file_roll_size_bytes) { - roll_file(); - } - } - -private: - void roll_file() - { - if (m_os) { - m_os->flush(); - m_os->close(); - } - - m_bytes_written = 0; - m_os = std::make_unique(); - // TODO Optimize this part. Does it even matter ? - std::string log_file_name = m_name; - log_file_name.append("."); - log_file_name.append(std::to_string(++m_file_number)); - log_file_name.append(".txt"); - m_os->open(log_file_name, std::ofstream::out | std::ofstream::trunc); - } - -private: - uint32_t m_file_number = 0; - std::streamoff m_bytes_written = 0; - uint32_t const m_log_file_roll_size_bytes; - std::string const m_name; - std::unique_ptr m_os; -}; - -class NanoLogger { -public: - NanoLogger(NonGuaranteedLogger ngl, std::string const& log_directory, - std::string const& log_file_name, uint32_t log_file_roll_size_mb) - : m_state(State::INIT), - m_buffer_base( - new RingBuffer(std::max(1u, ngl.ring_buffer_size_mb) * 1024 * 4)), - m_file_writer(log_directory, log_file_name, - std::max(1u, log_file_roll_size_mb)), - m_thread(&NanoLogger::pop, this) - { - m_state.store(State::READY, std::memory_order_release); - } - - NanoLogger(GuaranteedLogger /*gl*/, std::string const& log_directory, - std::string const& log_file_name, uint32_t log_file_roll_size_mb) - : m_state(State::INIT), - m_buffer_base(new QueueBuffer()), - m_file_writer(log_directory, log_file_name, - std::max(1u, log_file_roll_size_mb)), - m_thread(&NanoLogger::pop, this) - { - m_state.store(State::READY, std::memory_order_release); - } - - ~NanoLogger() - { - m_state.store(State::SHUTDOWN); - m_thread.join(); - } - - void add(VDebug&& logline) { m_buffer_base->push(std::move(logline)); } - - void pop() - { - // Wait for constructor to complete and pull all stores done there to - // this thread / core. - while (m_state.load(std::memory_order_acquire) == State::INIT) - std::this_thread::sleep_for(std::chrono::microseconds(50)); - - VDebug logline(LogLevel::INFO, nullptr, nullptr, 0); - - while (m_state.load() == State::READY) { - if (m_buffer_base->try_pop(logline)) - m_file_writer.write(logline); - else - std::this_thread::sleep_for(std::chrono::microseconds(50)); - } - - // Pop and log all remaining entries - while (m_buffer_base->try_pop(logline)) { - m_file_writer.write(logline); - } - } - -private: - enum class State { INIT, READY, SHUTDOWN }; - - std::atomic m_state; - std::unique_ptr m_buffer_base; - FileWriter m_file_writer; - std::thread m_thread; -}; - -std::unique_ptr nanologger; -std::atomic atomic_nanologger; - -bool VDebugServer::operator==(VDebug& logline) -{ - atomic_nanologger.load(std::memory_order_acquire)->add(std::move(logline)); - return true; -} - -void initialize(NonGuaranteedLogger ngl, std::string const& log_directory, - std::string const& log_file_name, - uint32_t log_file_roll_size_mb) -{ - nanologger = std::make_unique(ngl, log_directory, log_file_name, - log_file_roll_size_mb); - atomic_nanologger.store(nanologger.get(), std::memory_order_seq_cst); -} - -void initialize(GuaranteedLogger gl, std::string const& log_directory, - std::string const& log_file_name, - uint32_t log_file_roll_size_mb) -{ - nanologger = std::make_unique(gl, log_directory, log_file_name, - log_file_roll_size_mb); - atomic_nanologger.store(nanologger.get(), std::memory_order_seq_cst); -} - -std::atomic loglevel = {0}; - -void set_log_level(LogLevel level) -{ - loglevel.store(static_cast(level), std::memory_order_release); -} - -bool is_logged(LogLevel level) -{ - return static_cast(level) >= - loglevel.load(std::memory_order_relaxed); -} - -#endif // LOTTIE_LOGGING_SUPPORT diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdebug.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vdebug.h deleted file mode 100644 index 5b6bef5b..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdebug.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VDEBUG_H -#define VDEBUG_H - -#include "config.h" - -#ifdef LOTTIE_LOGGING_SUPPORT - -#include -#include -#include -#include -#include - -enum class LogLevel : uint8_t { INFO, WARN, CRIT, OFF }; - -class VDebug { -public: - VDebug(); - VDebug& debug() { return *this; } - VDebug(LogLevel level, char const* file, char const* function, - uint32_t line); - ~VDebug(); - - VDebug(VDebug&&) = default; - VDebug& operator=(VDebug&&) = default; - - void stringify(std::ostream& os); - - VDebug& operator<<(char arg); - VDebug& operator<<(int32_t arg); - VDebug& operator<<(uint32_t arg); - // VDebug& operator<<(int64_t arg); - // VDebug& operator<<(uint64_t arg); - - VDebug& operator<<(long arg); - VDebug& operator<<(unsigned long arg); - VDebug& operator<<(double arg); - VDebug& operator<<(std::string const& arg); - - template - VDebug& operator<<(const char (&arg)[N]) - { - encode(string_literal_t(arg)); - return *this; - } - - template - typename std::enable_if::value, - VDebug&>::type - operator<<(Arg const& arg) - { - encode(arg); - return *this; - } - - template - typename std::enable_if::value, VDebug&>::type - operator<<(Arg const& arg) - { - encode(arg); - return *this; - } - - struct string_literal_t { - explicit string_literal_t(char const* s) : m_s(s) {} - char const* m_s; - }; - -private: - char* buffer(); - - template - void encode(Arg arg); - - template - void encode(Arg arg, uint8_t type_id); - - void encode(char* arg); - void encode(char const* arg); - void encode(string_literal_t arg); - void encode_c_string(char const* arg, size_t length); - void resize_buffer_if_needed(size_t additional_bytes); - void stringify(std::ostream& os, char* start, char const* const end); - -private: - size_t m_bytes_used{0}; - size_t m_buffer_size{0}; - std::unique_ptr m_heap_buffer; - bool m_logAll; - char m_stack_buffer[256 - sizeof(bool) - 2 * sizeof(size_t) - - sizeof(decltype(m_heap_buffer)) - 8 /* Reserved */]; -}; - -struct VDebugServer { - /* - * Ideally this should have been operator+= - * Could not get that to compile, so here we are... - */ - bool operator==(VDebug&); -}; - -void set_log_level(LogLevel level); - -bool is_logged(LogLevel level); - -/* - * Non guaranteed logging. Uses a ring buffer to hold log lines. - * When the ring gets full, the previous log line in the slot will be dropped. - * Does not block producer even if the ring buffer is full. - * ring_buffer_size_mb - LogLines are pushed into a mpsc ring buffer whose size - * is determined by this parameter. Since each LogLine is 256 bytes, - * ring_buffer_size = ring_buffer_size_mb * 1024 * 1024 / 256 - */ -struct NonGuaranteedLogger { - NonGuaranteedLogger(uint32_t ring_buffer_size_mb_) - : ring_buffer_size_mb(ring_buffer_size_mb_) - { - } - uint32_t ring_buffer_size_mb; -}; - -/* - * Provides a guarantee log lines will not be dropped. - */ -struct GuaranteedLogger { -}; - -/* - * Ensure initialize() is called prior to any log statements. - * log_directory - where to create the logs. For example - "/tmp/" - * log_file_name - root of the file name. For example - "nanolog" - * This will create log files of the form - - * /tmp/nanolog.1.txt - * /tmp/nanolog.2.txt - * etc. - * log_file_roll_size_mb - mega bytes after which we roll to next log file. - */ -void initialize(GuaranteedLogger gl, std::string const& log_directory, - std::string const& log_file_name, - uint32_t log_file_roll_size_mb); -void initialize(NonGuaranteedLogger ngl, std::string const& log_directory, - std::string const& log_file_name, - uint32_t log_file_roll_size_mb); - -#define VDEBUG_LOG(LEVEL) \ - VDebugServer() == VDebug(LEVEL, __FILE__, __func__, __LINE__).debug() -#define vDebug is_logged(LogLevel::INFO) && VDEBUG_LOG(LogLevel::INFO) -#define vWarning is_logged(LogLevel::WARN) && VDEBUG_LOG(LogLevel::WARN) -#define vCritical is_logged(LogLevel::CRIT) && VDEBUG_LOG(LogLevel::CRIT) - -#else - -struct VDebug -{ - template - VDebug& operator<<(const Args &){return *this;} -}; - -#define vDebug VDebug() -#define vWarning VDebug() -#define vCritical VDebug() - -#endif //LOTTIE_LOGGING_SUPPORT - -#endif // VDEBUG_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawable.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawable.cpp deleted file mode 100644 index 55b1bc84..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawable.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "vdrawable.h" -#include "vdasher.h" -#include "vraster.h" - -VDrawable::VDrawable(VDrawable::Type type) -{ - setType(type); -} - -VDrawable::~VDrawable() noexcept -{ - if (mStrokeInfo) { - if (mType == Type::StrokeWithDash) { - delete static_cast(mStrokeInfo); - } else { - delete mStrokeInfo; - } - } -} - -void VDrawable::setType(VDrawable::Type type) -{ - mType = type; - if (mType == VDrawable::Type::Stroke) { - mStrokeInfo = new StrokeInfo(); - } else if (mType == VDrawable::Type::StrokeWithDash) { - mStrokeInfo = new StrokeWithDashInfo(); - } -} - -void VDrawable::applyDashOp() -{ - if (mStrokeInfo && (mType == Type::StrokeWithDash)) { - auto obj = static_cast(mStrokeInfo); - if (!obj->mDash.empty()) { - VDasher dasher(obj->mDash.data(), obj->mDash.size()); - mPath.clone(dasher.dashed(mPath)); - } - } -} - -void VDrawable::preprocess(const VRect &clip) -{ - if (mFlag & (DirtyState::Path)) { - if (mType == Type::Fill) { - mRasterizer.rasterize(std::move(mPath), mFillRule, clip); - } else { - applyDashOp(); - mRasterizer.rasterize(std::move(mPath), mStrokeInfo->cap, mStrokeInfo->join, - mStrokeInfo->width, mStrokeInfo->miterLimit, clip); - } - mPath = {}; - mFlag &= ~DirtyFlag(DirtyState::Path); - } -} - -VRle VDrawable::rle() -{ - return mRasterizer.rle(); -} - -void VDrawable::setStrokeInfo(CapStyle cap, JoinStyle join, float miterLimit, - float strokeWidth) -{ - assert(mStrokeInfo); - if ((mStrokeInfo->cap == cap) && (mStrokeInfo->join == join) && - vCompare(mStrokeInfo->miterLimit, miterLimit) && - vCompare(mStrokeInfo->width, strokeWidth)) - return; - - mStrokeInfo->cap = cap; - mStrokeInfo->join = join; - mStrokeInfo->miterLimit = miterLimit; - mStrokeInfo->width = strokeWidth; - mFlag |= DirtyState::Path; -} - -void VDrawable::setDashInfo(std::vector &dashInfo) -{ - assert(mStrokeInfo); - assert(mType == VDrawable::Type::StrokeWithDash); - - auto obj = static_cast(mStrokeInfo); - bool hasChanged = false; - - if (obj->mDash.size() == dashInfo.size()) { - for (uint32_t i = 0; i < dashInfo.size(); ++i) { - if (!vCompare(obj->mDash[i], dashInfo[i])) { - hasChanged = true; - break; - } - } - } else { - hasChanged = true; - } - - if (!hasChanged) return; - - obj->mDash = dashInfo; - - mFlag |= DirtyState::Path; -} - -void VDrawable::setPath(const VPath &path) -{ - mPath = path; - mFlag |= DirtyState::Path; -} diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawable.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawable.h deleted file mode 100644 index 357a69fd..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawable.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VDRAWABLE_H -#define VDRAWABLE_H -#include -#include -#include "vbrush.h" -#include "vpath.h" -#include "vrle.h" -#include "vraster.h" - -class VDrawable { -public: - enum class DirtyState : unsigned char { - None = 1<<0, - Path = 1<<1, - Stroke = 1<<2, - Brush = 1<<3, - All = (Path | Stroke | Brush) - }; - - enum class Type : unsigned char{ - Fill, - Stroke, - StrokeWithDash - }; - - explicit VDrawable(VDrawable::Type type = Type::Fill); - void setType(VDrawable::Type type); - ~VDrawable() noexcept; - - typedef vFlag DirtyFlag; - void setPath(const VPath &path); - void setFillRule(FillRule rule) { mFillRule = rule; } - void setBrush(const VBrush &brush) { mBrush = brush; } - void setStrokeInfo(CapStyle cap, JoinStyle join, float miterLimit, - float strokeWidth); - void setDashInfo(std::vector &dashInfo); - void preprocess(const VRect &clip); - void applyDashOp(); - VRle rle(); - void setName(const char *name) - { - mName = name; - } - const char* name() const { return mName; } - -public: - struct StrokeInfo { - float width{0.0}; - float miterLimit{10}; - CapStyle cap{CapStyle::Flat}; - JoinStyle join{JoinStyle::Bevel}; - }; - - struct StrokeWithDashInfo : public StrokeInfo{ - std::vector mDash; - }; - -public: - VPath mPath; - VBrush mBrush; - VRasterizer mRasterizer; - StrokeInfo *mStrokeInfo{nullptr}; - - DirtyFlag mFlag{DirtyState::All}; - FillRule mFillRule{FillRule::Winding}; - VDrawable::Type mType{Type::Fill}; - - const char *mName{nullptr}; -}; - -#endif // VDRAWABLE_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawhelper.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawhelper.cpp deleted file mode 100644 index ab12dc95..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawhelper.cpp +++ /dev/null @@ -1,766 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "vdrawhelper.h" -#include -#include -#include -#include -#include -#include - -static RenderFuncTable RenderTable; - -void VTextureData::setClip(const VRect &clip) -{ - left = clip.left(); - top = clip.top(); - right = std::min(clip.right(), int(width())) - 1; - bottom = std::min(clip.bottom(), int(height())) - 1; -} - -class VGradientCache { -public: - struct CacheInfo : public VColorTable { - inline CacheInfo(VGradientStops s) : stops(std::move(s)) {} - VGradientStops stops; - }; - using VCacheData = std::shared_ptr; - using VCacheKey = int64_t; - using VGradientColorTableHash = - std::unordered_multimap; - - bool generateGradientColorTable(const VGradientStops &stops, float alpha, - uint32_t *colorTable, int size); - VCacheData getBuffer(const VGradient &gradient) - { - VCacheKey hash_val = 0; - VCacheData info; - const VGradientStops &stops = gradient.mStops; - for (uint32_t i = 0; i < stops.size() && i <= 2; i++) - hash_val += - VCacheKey(stops[i].second.premulARGB() * gradient.alpha()); - - { - std::lock_guard guard(mMutex); - - size_t count = mCache.count(hash_val); - if (!count) { - // key is not present in the hash - info = addCacheElement(hash_val, gradient); - } else if (count == 1) { - auto search = mCache.find(hash_val); - if (search->second->stops == stops) { - info = search->second; - } else { - // didn't find an exact match - info = addCacheElement(hash_val, gradient); - } - } else { - // we have a multiple data with same key - auto range = mCache.equal_range(hash_val); - for (auto it = range.first; it != range.second; ++it) { - if (it->second->stops == stops) { - info = it->second; - break; - } - } - if (!info) { - // didn't find an exact match - info = addCacheElement(hash_val, gradient); - } - } - } - return info; - } - - static VGradientCache &instance() - { - static VGradientCache CACHE; - return CACHE; - } - -protected: - uint32_t maxCacheSize() const { return 60; } - VCacheData addCacheElement(VCacheKey hash_val, const VGradient &gradient) - { - if (mCache.size() == maxCacheSize()) { - uint32_t count = maxCacheSize() / 10; - while (count--) { - mCache.erase(mCache.begin()); - } - } - auto cache_entry = std::make_shared(gradient.mStops); - cache_entry->alpha = generateGradientColorTable( - gradient.mStops, gradient.alpha(), cache_entry->buffer32, - VGradient::colorTableSize); - mCache.insert(std::make_pair(hash_val, cache_entry)); - return cache_entry; - } - -private: - VGradientCache() = default; - - VGradientColorTableHash mCache; - std::mutex mMutex; -}; - -bool VGradientCache::generateGradientColorTable(const VGradientStops &stops, - float opacity, - uint32_t *colorTable, int size) -{ - int dist, idist, pos = 0; - size_t i; - bool alpha = false; - size_t stopCount = stops.size(); - const VGradientStop *curr, *next, *start; - uint32_t curColor, nextColor; - float delta, t, incr, fpos; - - if (!vCompare(opacity, 1.0f)) alpha = true; - - start = stops.data(); - curr = start; - if (!curr->second.isOpaque()) alpha = true; - curColor = curr->second.premulARGB(opacity); - incr = 1.0f / (float)size; - fpos = 1.5f * incr; - - colorTable[pos++] = curColor; - - while (fpos <= curr->first && pos < size) { - colorTable[pos] = colorTable[pos - 1]; - pos++; - fpos += incr; - } - - for (i = 0; i < stopCount - 1; ++i) { - curr = (start + i); - next = (start + i + 1); - delta = 1 / (next->first - curr->first); - if (!next->second.isOpaque()) alpha = true; - nextColor = next->second.premulARGB(opacity); - while (fpos < next->first && pos < size) { - t = (fpos - curr->first) * delta; - dist = (int)(255 * t); - idist = 255 - dist; - colorTable[pos] = - interpolate_pixel(curColor, idist, nextColor, dist); - ++pos; - fpos += incr; - } - curColor = nextColor; - } - - for (; pos < size; ++pos) colorTable[pos] = curColor; - - // Make sure the last color stop is represented at the end of the table - colorTable[size - 1] = curColor; - return alpha; -} - -void VRasterBuffer::clear() -{ - memset(mBuffer, 0, mHeight * mBytesPerLine); -} - -VBitmap::Format VRasterBuffer::prepare(const VBitmap *image) -{ - mBuffer = image->data(); - mWidth = image->width(); - mHeight = image->height(); - mBytesPerPixel = 4; - mBytesPerLine = image->stride(); - - mFormat = image->format(); - return mFormat; -} - -void VSpanData::init(VRasterBuffer *image) -{ - mRasterBuffer = image; - setDrawRegion(VRect(0, 0, int(image->width()), int(image->height()))); - mType = VSpanData::Type::None; - mBlendFunc = nullptr; - mUnclippedBlendFunc = nullptr; -} - -/* - * Gradient Draw routines - * - */ - -#define FIXPT_BITS 8 -#define FIXPT_SIZE (1 << FIXPT_BITS) -static inline void getLinearGradientValues(LinearGradientValues *v, - const VSpanData * data) -{ - const VGradientData *grad = &data->mGradient; - v->dx = grad->linear.x2 - grad->linear.x1; - v->dy = grad->linear.y2 - grad->linear.y1; - v->l = v->dx * v->dx + v->dy * v->dy; - v->off = 0; - if (v->l != 0) { - v->dx /= v->l; - v->dy /= v->l; - v->off = -v->dx * grad->linear.x1 - v->dy * grad->linear.y1; - } -} - -static inline void getRadialGradientValues(RadialGradientValues *v, - const VSpanData * data) -{ - const VGradientData &gradient = data->mGradient; - v->dx = gradient.radial.cx - gradient.radial.fx; - v->dy = gradient.radial.cy - gradient.radial.fy; - - v->dr = gradient.radial.cradius - gradient.radial.fradius; - v->sqrfr = gradient.radial.fradius * gradient.radial.fradius; - - v->a = v->dr * v->dr - v->dx * v->dx - v->dy * v->dy; - v->inv2a = 1 / (2 * v->a); - - v->extended = !vIsZero(gradient.radial.fradius) || v->a <= 0; -} - -static inline int gradientClamp(const VGradientData *grad, int ipos) -{ - int limit; - - if (grad->mSpread == VGradient::Spread::Repeat) { - ipos = ipos % VGradient::colorTableSize; - ipos = ipos < 0 ? VGradient::colorTableSize + ipos : ipos; - } else if (grad->mSpread == VGradient::Spread::Reflect) { - limit = VGradient::colorTableSize * 2; - ipos = ipos % limit; - ipos = ipos < 0 ? limit + ipos : ipos; - ipos = ipos >= VGradient::colorTableSize ? limit - 1 - ipos : ipos; - } else { - if (ipos < 0) - ipos = 0; - else if (ipos >= VGradient::colorTableSize) - ipos = VGradient::colorTableSize - 1; - } - return ipos; -} - -static uint32_t gradientPixelFixed(const VGradientData *grad, int fixed_pos) -{ - int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS; - - return grad->mColorTable[gradientClamp(grad, ipos)]; -} - -static inline uint32_t gradientPixel(const VGradientData *grad, float pos) -{ - int ipos = (int)(pos * (VGradient::colorTableSize - 1) + (float)(0.5)); - - return grad->mColorTable[gradientClamp(grad, ipos)]; -} - -void fetch_linear_gradient(uint32_t *buffer, const Operator *op, - const VSpanData *data, int y, int x, int length) -{ - float t, inc; - const VGradientData *gradient = &data->mGradient; - - bool affine = true; - float rx = 0, ry = 0; - if (op->linear.l == 0) { - t = inc = 0; - } else { - rx = data->m21 * (y + float(0.5)) + data->m11 * (x + float(0.5)) + - data->dx; - ry = data->m22 * (y + float(0.5)) + data->m12 * (x + float(0.5)) + - data->dy; - t = op->linear.dx * rx + op->linear.dy * ry + op->linear.off; - inc = op->linear.dx * data->m11 + op->linear.dy * data->m12; - affine = !data->m13 && !data->m23; - - if (affine) { - t *= (VGradient::colorTableSize - 1); - inc *= (VGradient::colorTableSize - 1); - } - } - - const uint32_t *end = buffer + length; - if (affine) { - if (inc > float(-1e-5) && inc < float(1e-5)) { - memfill32(buffer, gradientPixelFixed(gradient, int(t * FIXPT_SIZE)), - length); - } else { - if (t + inc * length < float(INT_MAX >> (FIXPT_BITS + 1)) && - t + inc * length > float(INT_MIN >> (FIXPT_BITS + 1))) { - // we can use fixed point math - int t_fixed = int(t * FIXPT_SIZE); - int inc_fixed = int(inc * FIXPT_SIZE); - while (buffer < end) { - *buffer = gradientPixelFixed(gradient, t_fixed); - t_fixed += inc_fixed; - ++buffer; - } - } else { - // we have to fall back to float math - while (buffer < end) { - *buffer = - gradientPixel(gradient, t / VGradient::colorTableSize); - t += inc; - ++buffer; - } - } - } - } else { // fall back to float math here as well - float rw = data->m23 * (y + float(0.5)) + data->m13 * (x + float(0.5)) + - data->m33; - while (buffer < end) { - float xt = rx / rw; - float yt = ry / rw; - t = (op->linear.dx * xt + op->linear.dy * yt) + op->linear.off; - - *buffer = gradientPixel(gradient, t); - rx += data->m11; - ry += data->m12; - rw += data->m13; - if (!rw) { - rw += data->m13; - } - ++buffer; - } - } -} - -static inline float radialDeterminant(float a, float b, float c) -{ - return (b * b) - (4 * a * c); -} - -static void fetch(uint32_t *buffer, uint32_t *end, const Operator *op, - const VSpanData *data, float det, float delta_det, - float delta_delta_det, float b, float delta_b) -{ - if (op->radial.extended) { - while (buffer < end) { - uint32_t result = 0; - if (det >= 0) { - float w = std::sqrt(det) - b; - if (data->mGradient.radial.fradius + op->radial.dr * w >= 0) - result = gradientPixel(&data->mGradient, w); - } - - *buffer = result; - - det += delta_det; - delta_det += delta_delta_det; - b += delta_b; - - ++buffer; - } - } else { - while (buffer < end) { - *buffer++ = gradientPixel(&data->mGradient, std::sqrt(det) - b); - - det += delta_det; - delta_det += delta_delta_det; - b += delta_b; - } - } -} - -void fetch_radial_gradient(uint32_t *buffer, const Operator *op, - const VSpanData *data, int y, int x, int length) -{ - // avoid division by zero - if (vIsZero(op->radial.a)) { - memfill32(buffer, 0, length); - return; - } - - float rx = - data->m21 * (y + float(0.5)) + data->dx + data->m11 * (x + float(0.5)); - float ry = - data->m22 * (y + float(0.5)) + data->dy + data->m12 * (x + float(0.5)); - bool affine = !data->m13 && !data->m23; - - uint32_t *end = buffer + length; - if (affine) { - rx -= data->mGradient.radial.fx; - ry -= data->mGradient.radial.fy; - - float inv_a = 1 / float(2 * op->radial.a); - - const float delta_rx = data->m11; - const float delta_ry = data->m12; - - float b = 2 * (op->radial.dr * data->mGradient.radial.fradius + - rx * op->radial.dx + ry * op->radial.dy); - float delta_b = - 2 * (delta_rx * op->radial.dx + delta_ry * op->radial.dy); - const float b_delta_b = 2 * b * delta_b; - const float delta_b_delta_b = 2 * delta_b * delta_b; - - const float bb = b * b; - const float delta_bb = delta_b * delta_b; - - b *= inv_a; - delta_b *= inv_a; - - const float rxrxryry = rx * rx + ry * ry; - const float delta_rxrxryry = delta_rx * delta_rx + delta_ry * delta_ry; - const float rx_plus_ry = 2 * (rx * delta_rx + ry * delta_ry); - const float delta_rx_plus_ry = 2 * delta_rxrxryry; - - inv_a *= inv_a; - - float det = - (bb - 4 * op->radial.a * (op->radial.sqrfr - rxrxryry)) * inv_a; - float delta_det = (b_delta_b + delta_bb + - 4 * op->radial.a * (rx_plus_ry + delta_rxrxryry)) * - inv_a; - const float delta_delta_det = - (delta_b_delta_b + 4 * op->radial.a * delta_rx_plus_ry) * inv_a; - - fetch(buffer, end, op, data, det, delta_det, delta_delta_det, b, - delta_b); - } else { - float rw = data->m23 * (y + float(0.5)) + data->m33 + - data->m13 * (x + float(0.5)); - - while (buffer < end) { - if (rw == 0) { - *buffer = 0; - } else { - float invRw = 1 / rw; - float gx = rx * invRw - data->mGradient.radial.fx; - float gy = ry * invRw - data->mGradient.radial.fy; - float b = 2 * (op->radial.dr * data->mGradient.radial.fradius + - gx * op->radial.dx + gy * op->radial.dy); - float det = radialDeterminant( - op->radial.a, b, op->radial.sqrfr - (gx * gx + gy * gy)); - - uint32_t result = 0; - if (det >= 0) { - float detSqrt = std::sqrt(det); - - float s0 = (-b - detSqrt) * op->radial.inv2a; - float s1 = (-b + detSqrt) * op->radial.inv2a; - - float s = vMax(s0, s1); - - if (data->mGradient.radial.fradius + op->radial.dr * s >= 0) - result = gradientPixel(&data->mGradient, s); - } - - *buffer = result; - } - - rx += data->m11; - ry += data->m12; - rw += data->m13; - - ++buffer; - } - } -} - -static inline Operator getOperator(const VSpanData *data) -{ - Operator op; - bool solidSource = false; - - switch (data->mType) { - case VSpanData::Type::Solid: - solidSource = (vAlpha(data->mSolid) == 255); - op.srcFetch = nullptr; - break; - case VSpanData::Type::LinearGradient: - solidSource = false; - getLinearGradientValues(&op.linear, data); - op.srcFetch = &fetch_linear_gradient; - break; - case VSpanData::Type::RadialGradient: - solidSource = false; - getRadialGradientValues(&op.radial, data); - op.srcFetch = &fetch_radial_gradient; - break; - default: - op.srcFetch = nullptr; - break; - } - - op.mode = data->mBlendMode; - if (op.mode == BlendMode::SrcOver && solidSource) op.mode = BlendMode::Src; - - op.funcSolid = RenderTable.color(op.mode); - op.func = RenderTable.src(op.mode); - - return op; -} - -static void blend_color(size_t size, const VRle::Span *array, void *userData) -{ - VSpanData *data = (VSpanData *)(userData); - Operator op = getOperator(data); - const uint32_t color = data->mSolid; - - for (size_t i = 0 ; i < size; ++i) { - const auto &span = array[i]; - op.funcSolid(data->buffer(span.x, span.y), span.len, color, span.coverage); - } -} - -// Signature of Process Object -// void Pocess(uint* scratchBuffer, size_t x, size_t y, uint8_t cov) -template -static inline void process_in_chunk(const VRle::Span *array, size_t size, - Process process) -{ - std::array buf; - for (size_t i = 0; i < size; i++) { - const auto &span = array[i]; - size_t len = span.len; - auto x = span.x; - while (len) { - auto l = std::min(len, buf.size()); - process(buf.data(), x, span.y, l, span.coverage); - x += l; - len -= l; - } - } -} - -static void blend_gradient(size_t size, const VRle::Span *array, - void *userData) -{ - VSpanData *data = (VSpanData *)(userData); - Operator op = getOperator(data); - - if (!op.srcFetch) return; - - process_in_chunk( - array, size, - [&](uint32_t *scratch, size_t x, size_t y, size_t len, uint8_t cov) { - op.srcFetch(scratch, &op, data, (int)y, (int)x, (int)len); - op.func(data->buffer((int)x, (int)y), (int)len, scratch, cov); - }); -} - -template -constexpr const T &clamp(const T &v, const T &lo, const T &hi) -{ - return v < lo ? lo : hi < v ? hi : v; -} - -static constexpr inline uint8_t alpha_mul(uint8_t a, uint8_t b) -{ - return ((a * b) >> 8); -} - -static void blend_image_xform(size_t size, const VRle::Span *array, - void *userData) -{ - const auto data = reinterpret_cast(userData); - const auto &src = data->texture(); - - if (src.format() != VBitmap::Format::ARGB32_Premultiplied && - src.format() != VBitmap::Format::ARGB32) { - //@TODO other formats not yet handled. - return; - } - - Operator op = getOperator(data); - - process_in_chunk( - array, size, - [&](uint32_t *scratch, size_t x, size_t y, size_t len, uint8_t cov) { - const auto coverage = (cov * src.alpha()) >> 8; - const float xfactor = y * data->m21 + data->dx + data->m11; - const float yfactor = y * data->m22 + data->dy + data->m12; - for (size_t i = 0; i < len; i++) { - const float fx = (x + i) * data->m11 + xfactor; - const float fy = (x + i) * data->m12 + yfactor; - const int px = clamp(int(fx), src.left, src.right); - const int py = clamp(int(fy), src.top, src.bottom); - scratch[i] = src.pixel(px, py); - } - op.func(data->buffer((int)x, (int)y), (int)len, scratch, coverage); - }); -} - -static void blend_image(size_t size, const VRle::Span *array, void *userData) -{ - const auto data = reinterpret_cast(userData); - const auto &src = data->texture(); - - if (src.format() != VBitmap::Format::ARGB32_Premultiplied && - src.format() != VBitmap::Format::ARGB32) { - //@TODO other formats not yet handled. - return; - } - - Operator op = getOperator(data); - - for (size_t i = 0; i < size; i++) { - const auto &span = array[i]; - int x = span.x; - int length = span.len; - int sx = x + int(data->dx); - int sy = span.y + int(data->dy); - - // notyhing to copy. - if (sy < 0 || sy >= int(src.height()) || sx >= int(src.width()) || - (sx + length) <= 0) - continue; - - // intersecting left edge of image - if (sx < 0) { - x -= sx; - length += sx; - sx = 0; - } - // intersecting right edge of image - if (sx + length > int(src.width())) length = (int)src.width() - sx; - - op.func(data->buffer(x, span.y), length, src.pixelRef(sx, sy), - alpha_mul(span.coverage, src.alpha())); - } -} - -void VSpanData::setup(const VBrush &brush, BlendMode /*mode*/, int /*alpha*/) -{ - transformType = VMatrix::MatrixType::None; - - switch (brush.type()) { - case VBrush::Type::NoBrush: - mType = VSpanData::Type::None; - break; - case VBrush::Type::Solid: - mType = VSpanData::Type::Solid; - mSolid = brush.mColor.premulARGB(); - break; - case VBrush::Type::LinearGradient: { - mType = VSpanData::Type::LinearGradient; - mColorTable = VGradientCache::instance().getBuffer(*brush.mGradient); - mGradient.mColorTable = mColorTable->buffer32; - mGradient.mColorTableAlpha = mColorTable->alpha; - mGradient.linear.x1 = brush.mGradient->linear.x1; - mGradient.linear.y1 = brush.mGradient->linear.y1; - mGradient.linear.x2 = brush.mGradient->linear.x2; - mGradient.linear.y2 = brush.mGradient->linear.y2; - mGradient.mSpread = brush.mGradient->mSpread; - setupMatrix(brush.mGradient->mMatrix); - break; - } - case VBrush::Type::RadialGradient: { - mType = VSpanData::Type::RadialGradient; - mColorTable = VGradientCache::instance().getBuffer(*brush.mGradient); - mGradient.mColorTable = mColorTable->buffer32; - mGradient.mColorTableAlpha = mColorTable->alpha; - mGradient.radial.cx = brush.mGradient->radial.cx; - mGradient.radial.cy = brush.mGradient->radial.cy; - mGradient.radial.fx = brush.mGradient->radial.fx; - mGradient.radial.fy = brush.mGradient->radial.fy; - mGradient.radial.cradius = brush.mGradient->radial.cradius; - mGradient.radial.fradius = brush.mGradient->radial.fradius; - mGradient.mSpread = brush.mGradient->mSpread; - setupMatrix(brush.mGradient->mMatrix); - break; - } - case VBrush::Type::Texture: { - mType = VSpanData::Type::Texture; - initTexture(&brush.mTexture->mBitmap, brush.mTexture->mAlpha, - brush.mTexture->mBitmap.rect()); - setupMatrix(brush.mTexture->mMatrix); - break; - } - default: - break; - } - updateSpanFunc(); -} - -void VSpanData::setupMatrix(const VMatrix &matrix) -{ - VMatrix inv = matrix.inverted(); - m11 = inv.m11; - m12 = inv.m12; - m13 = inv.m13; - m21 = inv.m21; - m22 = inv.m22; - m23 = inv.m23; - m33 = inv.m33; - dx = inv.mtx; - dy = inv.mty; - transformType = inv.type(); - - const bool affine = inv.isAffine(); - const float f1 = m11 * m11 + m21 * m21; - const float f2 = m12 * m12 + m22 * m22; - fast_matrix = affine && f1 < 1e4 && f2 < 1e4 && f1 > (1.0 / 65536) && - f2 > (1.0 / 65536) && fabs(dx) < 1e4 && fabs(dy) < 1e4; -} - -void VSpanData::initTexture(const VBitmap *bitmap, int alpha, - const VRect &sourceRect) -{ - mType = VSpanData::Type::Texture; - mTexture.prepare(bitmap); - mTexture.setClip(sourceRect); - mTexture.setAlpha(alpha); - updateSpanFunc(); -} - -void VSpanData::updateSpanFunc() -{ - switch (mType) { - case VSpanData::Type::None: - mUnclippedBlendFunc = nullptr; - break; - case VSpanData::Type::Solid: - mUnclippedBlendFunc = &blend_color; - break; - case VSpanData::Type::LinearGradient: - case VSpanData::Type::RadialGradient: { - mUnclippedBlendFunc = &blend_gradient; - break; - } - case VSpanData::Type::Texture: { - //@TODO update proper image function. - if (transformType <= VMatrix::MatrixType::Translate) { - mUnclippedBlendFunc = &blend_image; - } else { - mUnclippedBlendFunc = &blend_image_xform; - } - break; - } - } -} - -#if !defined(__SSE2__) -void memfill32(uint32_t *dest, uint32_t value, int length) -{ - // let compiler do the auto vectorization. - for (int i = 0 ; i < length; i++) { - *dest++ = value; - } -} -#endif - diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawhelper.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawhelper.h deleted file mode 100644 index 7d31e3f3..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawhelper.h +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VDRAWHELPER_H -#define VDRAWHELPER_H - -#include -#include -#include "assert.h" -#include "vbitmap.h" -#include "vbrush.h" -#include "vrect.h" -#include "vrle.h" - -V_USE_NAMESPACE - -struct VSpanData; -struct Operator; - -struct RenderFunc -{ - using Color = void (*)(uint32_t *dest, int length, uint32_t color, uint32_t alpha); - using Src = void (*)(uint32_t *dest, int length, const uint32_t *src, uint32_t alpha); - enum class Type { - Invalid, - Color, - Src, - }; - RenderFunc() = default; - RenderFunc(Type t, Color f):type_(t), color_(f){assert(t == Type::Color);} - RenderFunc(Type t, Src f):type_(t), src_(f){ assert(t == Type::Src);} - - Type type_{Type::Invalid}; - union { - Color color_; - Src src_; - }; -}; - -class RenderFuncTable -{ -public: - RenderFuncTable(); - RenderFunc::Color color(BlendMode mode) const - { - return colorTable[uint32_t(mode)].color_; - } - RenderFunc::Src src(BlendMode mode) const - { - return srcTable[uint32_t(mode)].src_; - } -private: - void neon(); - void sse(); - void updateColor(BlendMode mode, RenderFunc::Color f) - { - colorTable[uint32_t(mode)] = {RenderFunc::Type::Color, f}; - } - void updateSrc(BlendMode mode, RenderFunc::Src f) - { - srcTable[uint32_t(mode)] = {RenderFunc::Type::Src, f}; - } -private: - std::array colorTable; - std::array srcTable; -}; - -typedef void (*SourceFetchProc)(uint32_t *buffer, const Operator *o, - const VSpanData *data, int y, int x, - int length); -typedef void (*ProcessRleSpan)(size_t count, const VRle::Span *spans, - void *userData); - -extern void memfill32(uint32_t *dest, uint32_t value, int count); - -struct LinearGradientValues { - float dx; - float dy; - float l; - float off; -}; - -struct RadialGradientValues { - float dx; - float dy; - float dr; - float sqrfr; - float a; - float inv2a; - bool extended; -}; - -struct Operator { - BlendMode mode; - SourceFetchProc srcFetch; - RenderFunc::Color funcSolid; - RenderFunc::Src func; - union { - LinearGradientValues linear; - RadialGradientValues radial; - }; -}; - -class VRasterBuffer { -public: - VBitmap::Format prepare(const VBitmap *image); - void clear(); - - void resetBuffer(int val = 0); - - inline uint8_t *scanLine(int y) - { - assert(y >= 0); - assert(size_t(y) < mHeight); - return mBuffer + y * mBytesPerLine; - } - uint32_t *pixelRef(int x, int y) const - { - return (uint32_t *)(mBuffer + y * mBytesPerLine + x * mBytesPerPixel); - } - - size_t width() const { return mWidth; } - size_t height() const { return mHeight; } - size_t bytesPerLine() const { return mBytesPerLine; } - size_t bytesPerPixel() const { return mBytesPerPixel; } - VBitmap::Format format() const { return mFormat; } - -private: - VBitmap::Format mFormat{VBitmap::Format::ARGB32_Premultiplied}; - size_t mWidth{0}; - size_t mHeight{0}; - size_t mBytesPerLine{0}; - size_t mBytesPerPixel{0}; - mutable uint8_t *mBuffer{nullptr}; -}; - -struct VGradientData { - VGradient::Spread mSpread; - struct Linear { - float x1, y1, x2, y2; - }; - struct Radial { - float cx, cy, fx, fy, cradius, fradius; - }; - union { - Linear linear; - Radial radial; - }; - const uint32_t *mColorTable; - bool mColorTableAlpha; -}; - -struct VTextureData : public VRasterBuffer { - uint32_t pixel(int x, int y) const { return *pixelRef(x, y); }; - uint8_t alpha() const { return mAlpha; } - void setAlpha(uint8_t alpha) { mAlpha = alpha; } - void setClip(const VRect &clip); - // clip rect - int left; - int right; - int top; - int bottom; - bool hasAlpha; - uint8_t mAlpha; -}; - -struct VColorTable { - uint32_t buffer32[VGradient::colorTableSize]; - bool alpha{true}; -}; - -struct VSpanData { - enum class Type { None, Solid, LinearGradient, RadialGradient, Texture }; - - void updateSpanFunc(); - void init(VRasterBuffer *image); - void setup(const VBrush &brush, BlendMode mode = BlendMode::SrcOver, - int alpha = 255); - void setupMatrix(const VMatrix &matrix); - - VRect clipRect() const - { - return VRect(0, 0, mDrawableSize.width(), mDrawableSize.height()); - } - - void setDrawRegion(const VRect ®ion) - { - mOffset = VPoint(region.left(), region.top()); - mDrawableSize = VSize(region.width(), region.height()); - } - - uint32_t *buffer(int x, int y) const - { - return mRasterBuffer->pixelRef(x + mOffset.x(), y + mOffset.y()); - } - void initTexture(const VBitmap *image, int alpha, const VRect &sourceRect); - const VTextureData &texture() const { return mTexture; } - - BlendMode mBlendMode{BlendMode::SrcOver}; - VRasterBuffer * mRasterBuffer; - ProcessRleSpan mBlendFunc; - ProcessRleSpan mUnclippedBlendFunc; - VSpanData::Type mType; - std::shared_ptr mColorTable{nullptr}; - VPoint mOffset; // offset to the subsurface - VSize mDrawableSize; // suburface size - uint32_t mSolid; - VGradientData mGradient; - VTextureData mTexture; - - float m11, m12, m13, m21, m22, m23, m33, dx, dy; // inverse xform matrix - bool fast_matrix{true}; - VMatrix::MatrixType transformType{VMatrix::MatrixType::None}; -}; - -#define BYTE_MUL(c, a) \ - ((((((c) >> 8) & 0x00ff00ff) * (a)) & 0xff00ff00) + \ - (((((c)&0x00ff00ff) * (a)) >> 8) & 0x00ff00ff)) - -inline constexpr int vRed(uint32_t c) -{ - return ((c >> 16) & 0xff); -} - -inline constexpr int vGreen(uint32_t c) -{ - return ((c >> 8) & 0xff); -} - -inline constexpr int vBlue(uint32_t c) -{ - return (c & 0xff); -} - -inline constexpr int vAlpha(uint32_t c) -{ - return c >> 24; -} - -static inline uint32_t interpolate_pixel(uint32_t x, uint32_t a, uint32_t y, - uint32_t b) -{ - uint32_t t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; - t >>= 8; - t &= 0xff00ff; - x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; - x &= 0xff00ff00; - x |= t; - return x; -} - -#endif // QDRAWHELPER_P_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawhelper_common.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawhelper_common.cpp deleted file mode 100644 index 86c86737..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawhelper_common.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include "vdrawhelper.h" - -/* -result = s -dest = s * ca + d * cia -*/ -static void color_Source(uint32_t *dest, int length, uint32_t color, - uint32_t alpha) -{ - int ialpha, i; - - if (alpha == 255) { - memfill32(dest, color, length); - } else { - ialpha = 255 - alpha; - color = BYTE_MUL(color, alpha); - for (i = 0; i < length; ++i) - dest[i] = color + BYTE_MUL(dest[i], ialpha); - } -} - -/* - r = s + d * sia - dest = r * ca + d * cia - = (s + d * sia) * ca + d * cia - = s * ca + d * (sia * ca + cia) - = s * ca + d * (1 - sa*ca) - = s' + d ( 1 - s'a) -*/ -static void color_SourceOver(uint32_t *dest, int length, uint32_t color, - uint32_t alpha) -{ - int ialpha, i; - - if (alpha != 255) color = BYTE_MUL(color, alpha); - ialpha = 255 - vAlpha(color); - for (i = 0; i < length; ++i) dest[i] = color + BYTE_MUL(dest[i], ialpha); -} - -/* - result = d * sa - dest = d * sa * ca + d * cia - = d * (sa * ca + cia) -*/ -static void color_DestinationIn(uint32_t *dest, int length, uint32_t color, - uint32_t alpha) -{ - uint32_t a = vAlpha(color); - if (alpha != 255) { - a = BYTE_MUL(a, alpha) + 255 - alpha; - } - for (int i = 0; i < length; ++i) { - dest[i] = BYTE_MUL(dest[i], a); - } -} - -/* - result = d * sia - dest = d * sia * ca + d * cia - = d * (sia * ca + cia) -*/ -static void color_DestinationOut(uint32_t *dest, int length, uint32_t color, - uint32_t alpha) -{ - uint32_t a = vAlpha(~color); - if (alpha != 255) a = BYTE_MUL(a, alpha) + 255 - alpha; - for (int i = 0; i < length; ++i) { - dest[i] = BYTE_MUL(dest[i], a); - } -} - -static void src_Source(uint32_t *dest, int length, const uint32_t *src, - uint32_t alpha) -{ - if (alpha == 255) { - memcpy(dest, src, size_t(length) * sizeof(uint32_t)); - } else { - uint32_t ialpha = 255 - alpha; - for (int i = 0; i < length; ++i) { - dest[i] = - interpolate_pixel(src[i], alpha, dest[i], ialpha); - } - } -} - -/* s' = s * ca - * d' = s' + d (1 - s'a) - */ -static void src_SourceOver(uint32_t *dest, int length, const uint32_t *src, - uint32_t alpha) -{ - uint32_t s, sia; - - if (alpha == 255) { - for (int i = 0; i < length; ++i) { - s = src[i]; - if (s >= 0xff000000) - dest[i] = s; - else if (s != 0) { - sia = vAlpha(~s); - dest[i] = s + BYTE_MUL(dest[i], sia); - } - } - } else { - /* source' = source * const_alpha - * dest = source' + dest ( 1- source'a) - */ - for (int i = 0; i < length; ++i) { - s = BYTE_MUL(src[i], alpha); - sia = vAlpha(~s); - dest[i] = s + BYTE_MUL(dest[i], sia); - } - } -} - -static void src_DestinationIn(uint32_t *dest, int length, const uint32_t *src, - uint32_t alpha) -{ - if (alpha == 255) { - for (int i = 0; i < length; ++i) { - dest[i] = BYTE_MUL(dest[i], vAlpha(src[i])); - } - } else { - uint32_t cia = 255 - alpha; - for (int i = 0; i < length; ++i) { - uint32_t a = BYTE_MUL(vAlpha(src[i]), alpha) + cia; - dest[i] = BYTE_MUL(dest[i], a); - } - } -} - -static void src_DestinationOut(uint32_t *dest, int length, const uint32_t *src, - uint32_t alpha) -{ - if (alpha == 255) { - for (int i = 0; i < length; ++i) { - dest[i] = BYTE_MUL(dest[i], vAlpha(~src[i])); - } - } else { - uint32_t cia = 255 - alpha; - for (int i = 0; i < length; ++i) { - uint32_t sia = BYTE_MUL(vAlpha(~src[i]), alpha) + cia; - dest[i] = BYTE_MUL(dest[i], sia); - } - } -} - -RenderFuncTable::RenderFuncTable() -{ - updateColor(BlendMode::Src, color_Source); - updateColor(BlendMode::SrcOver, color_SourceOver); - updateColor(BlendMode::DestIn, color_DestinationIn); - updateColor(BlendMode::DestOut, color_DestinationOut); - - updateSrc(BlendMode::Src, src_Source); - updateSrc(BlendMode::SrcOver, src_SourceOver); - updateSrc(BlendMode::DestIn, src_DestinationIn); - updateSrc(BlendMode::DestOut, src_DestinationOut); - -#if defined(__SSE2__) - sse(); -#endif -} diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawhelper_neon.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawhelper_neon.cpp deleted file mode 100644 index 681eabbc..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawhelper_neon.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#if defined(__ARM_NEON__) - -#include "vdrawhelper.h" - -extern "C" void pixman_composite_src_n_8888_asm_neon(int32_t w, int32_t h, - uint32_t *dst, - int32_t dst_stride, - uint32_t src); - -extern "C" void pixman_composite_over_n_8888_asm_neon(int32_t w, int32_t h, - uint32_t *dst, - int32_t dst_stride, - uint32_t src); - -void memfill32(uint32_t *dest, uint32_t value, int length) -{ - pixman_composite_src_n_8888_asm_neon(length, 1, dest, length, value); -} - -static void color_SourceOver(uint32_t *dest, int length, - uint32_t color, - uint32_t const_alpha) -{ - if (const_alpha != 255) color = BYTE_MUL(color, const_alpha); - - pixman_composite_over_n_8888_asm_neon(length, 1, dest, length, color); -} - -void RenderFuncTable::neon() -{ - updateColor(BlendMode::Src , color_SourceOver); -} -#endif diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawhelper_sse2.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawhelper_sse2.cpp deleted file mode 100644 index fd9b711e..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vdrawhelper_sse2.cpp +++ /dev/null @@ -1,261 +0,0 @@ -#if defined(__SSE2__) - -#include -#include /* for SSE2 intrinsics */ -#include /* for _mm_shuffle_pi16 and _MM_SHUFFLE */ - -#include "vdrawhelper.h" -// Each 32bits components of alphaChannel must be in the form 0x00AA00AA -inline static __m128i v4_byte_mul_sse2(__m128i c, __m128i a) -{ - const __m128i ag_mask = _mm_set1_epi32(0xFF00FF00); - const __m128i rb_mask = _mm_set1_epi32(0x00FF00FF); - - /* for AG */ - __m128i v_ag = _mm_and_si128(ag_mask, c); - v_ag = _mm_srli_epi32(v_ag, 8); - v_ag = _mm_mullo_epi16(a, v_ag); - v_ag = _mm_and_si128(ag_mask, v_ag); - - /* for RB */ - __m128i v_rb = _mm_and_si128(rb_mask, c); - v_rb = _mm_mullo_epi16(a, v_rb); - v_rb = _mm_srli_epi32(v_rb, 8); - v_rb = _mm_and_si128(rb_mask, v_rb); - - /* combine */ - return _mm_add_epi32(v_ag, v_rb); -} - -static inline __m128i v4_interpolate_color_sse2(__m128i a, __m128i c0, - __m128i c1) -{ - const __m128i rb_mask = _mm_set1_epi32(0xFF00FF00); - const __m128i zero = _mm_setzero_si128(); - - __m128i a_l = a; - __m128i a_h = a; - a_l = _mm_unpacklo_epi16(a_l, a_l); - a_h = _mm_unpackhi_epi16(a_h, a_h); - - __m128i a_t = _mm_slli_epi64(a_l, 32); - __m128i a_t0 = _mm_slli_epi64(a_h, 32); - - a_l = _mm_add_epi32(a_l, a_t); - a_h = _mm_add_epi32(a_h, a_t0); - - __m128i c0_l = c0; - __m128i c0_h = c0; - - c0_l = _mm_unpacklo_epi8(c0_l, zero); - c0_h = _mm_unpackhi_epi8(c0_h, zero); - - __m128i c1_l = c1; - __m128i c1_h = c1; - - c1_l = _mm_unpacklo_epi8(c1_l, zero); - c1_h = _mm_unpackhi_epi8(c1_h, zero); - - __m128i cl_sub = _mm_sub_epi16(c0_l, c1_l); - __m128i ch_sub = _mm_sub_epi16(c0_h, c1_h); - - cl_sub = _mm_mullo_epi16(cl_sub, a_l); - ch_sub = _mm_mullo_epi16(ch_sub, a_h); - - __m128i c1ls = _mm_slli_epi16(c1_l, 8); - __m128i c1hs = _mm_slli_epi16(c1_h, 8); - - cl_sub = _mm_add_epi16(cl_sub, c1ls); - ch_sub = _mm_add_epi16(ch_sub, c1hs); - - cl_sub = _mm_and_si128(cl_sub, rb_mask); - ch_sub = _mm_and_si128(ch_sub, rb_mask); - - cl_sub = _mm_srli_epi64(cl_sub, 8); - ch_sub = _mm_srli_epi64(ch_sub, 8); - - cl_sub = _mm_packus_epi16(cl_sub, cl_sub); - ch_sub = _mm_packus_epi16(ch_sub, ch_sub); - - return (__m128i)_mm_shuffle_ps((__m128)cl_sub, (__m128)ch_sub, 0x44); -} - -// Load src and dest vector -#define V4_FETCH_SRC_DEST \ - __m128i v_src = _mm_loadu_si128((__m128i*)src); \ - __m128i v_dest = _mm_load_si128((__m128i*)dest); - -#define V4_FETCH_SRC __m128i v_src = _mm_loadu_si128((__m128i*)src); - -#define V4_STORE_DEST _mm_store_si128((__m128i*)dest, v_src); - -#define V4_SRC_DEST_LEN_INC \ - dest += 4; \ - src += 4; \ - length -= 4; - -// Multiply src color with const_alpha -#define V4_ALPHA_MULTIPLY v_src = v4_byte_mul_sse2(v_src, v_alpha); - - -// dest = src + dest * sia -#define V4_COMP_OP_SRC \ - v_src = v4_interpolate_color_sse2(v_alpha, v_src, v_dest); - -#define LOOP_ALIGNED_U1_A4(DEST, LENGTH, UOP, A4OP) \ - { \ - while ((uintptr_t)DEST & 0xF && LENGTH) \ - UOP \ - \ - while (LENGTH) \ - { \ - switch (LENGTH) { \ - case 3: \ - case 2: \ - case 1: \ - UOP break; \ - default: \ - A4OP break; \ - } \ - } \ - } - -void memfill32(uint32_t* dest, uint32_t value, int length) -{ - __m128i vector_data = _mm_set_epi32(value, value, value, value); - - // run till memory alligned to 16byte memory - while (length && ((uintptr_t)dest & 0xf)) { - *dest++ = value; - length--; - } - - while (length >= 32) { - _mm_store_si128((__m128i*)(dest), vector_data); - _mm_store_si128((__m128i*)(dest + 4), vector_data); - _mm_store_si128((__m128i*)(dest + 8), vector_data); - _mm_store_si128((__m128i*)(dest + 12), vector_data); - _mm_store_si128((__m128i*)(dest + 16), vector_data); - _mm_store_si128((__m128i*)(dest + 20), vector_data); - _mm_store_si128((__m128i*)(dest + 24), vector_data); - _mm_store_si128((__m128i*)(dest + 28), vector_data); - - dest += 32; - length -= 32; - } - - if (length >= 16) { - _mm_store_si128((__m128i*)(dest), vector_data); - _mm_store_si128((__m128i*)(dest + 4), vector_data); - _mm_store_si128((__m128i*)(dest + 8), vector_data); - _mm_store_si128((__m128i*)(dest + 12), vector_data); - - dest += 16; - length -= 16; - } - - if (length >= 8) { - _mm_store_si128((__m128i*)(dest), vector_data); - _mm_store_si128((__m128i*)(dest + 4), vector_data); - - dest += 8; - length -= 8; - } - - if (length >= 4) { - _mm_store_si128((__m128i*)(dest), vector_data); - - dest += 4; - length -= 4; - } - - while (length) { - *dest++ = value; - length--; - } -} - -// dest = color + (dest * alpha) -inline static void copy_helper_sse2(uint32_t* dest, int length, - uint32_t color, uint32_t alpha) -{ - const __m128i v_color = _mm_set1_epi32(color); - const __m128i v_a = _mm_set1_epi16(alpha); - - LOOP_ALIGNED_U1_A4(dest, length, - { /* UOP */ - *dest = color + BYTE_MUL(*dest, alpha); - dest++; - length--; - }, - { /* A4OP */ - __m128i v_dest = _mm_load_si128((__m128i*)dest); - - v_dest = v4_byte_mul_sse2(v_dest, v_a); - v_dest = _mm_add_epi32(v_dest, v_color); - - _mm_store_si128((__m128i*)dest, v_dest); - - dest += 4; - length -= 4; - }) -} - -static void color_Source(uint32_t* dest, int length, uint32_t color, - uint32_t const_alpha) -{ - if (const_alpha == 255) { - memfill32(dest, color, length); - } else { - int ialpha; - - ialpha = 255 - const_alpha; - color = BYTE_MUL(color, const_alpha); - copy_helper_sse2(dest, length, color, ialpha); - } -} - -static void color_SourceOver(uint32_t* dest, int length, - uint32_t color, - uint32_t const_alpha) -{ - int ialpha; - - if (const_alpha != 255) color = BYTE_MUL(color, const_alpha); - ialpha = 255 - vAlpha(color); - copy_helper_sse2(dest, length, color, ialpha); -} - -static void src_Source(uint32_t* dest, int length, const uint32_t* src, - uint32_t const_alpha) -{ - int ialpha; - if (const_alpha == 255) { - memcpy(dest, src, length * sizeof(uint32_t)); - } else { - ialpha = 255 - const_alpha; - __m128i v_alpha = _mm_set1_epi32(const_alpha); - - LOOP_ALIGNED_U1_A4(dest, length, - { /* UOP */ - *dest = interpolate_pixel(*src, const_alpha, - *dest, ialpha); - dest++; - src++; - length--; - }, - {/* A4OP */ - V4_FETCH_SRC_DEST V4_COMP_OP_SRC V4_STORE_DEST - V4_SRC_DEST_LEN_INC}) - } -} - -void RenderFuncTable::sse() -{ - updateColor(BlendMode::Src , color_Source); - updateColor(BlendMode::SrcOver , color_SourceOver); - - updateSrc(BlendMode::Src , src_Source); -} - -#endif diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/velapsedtimer.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/velapsedtimer.cpp deleted file mode 100644 index 42aa4529..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/velapsedtimer.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "velapsedtimer.h" - -void VElapsedTimer::start() -{ - clock = std::chrono::high_resolution_clock::now(); - m_valid = true; -} - -double VElapsedTimer::restart() -{ - double elapsedTime = elapsed(); - start(); - return elapsedTime; -} - -double VElapsedTimer::elapsed() const -{ - if (!isValid()) return 0; - return std::chrono::duration( - std::chrono::high_resolution_clock::now() - clock) - .count(); -} - -bool VElapsedTimer::hasExpired(double time) -{ - double elapsedTime = elapsed(); - if (elapsedTime > time) return true; - return false; -} diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/velapsedtimer.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/velapsedtimer.h deleted file mode 100644 index d53d38ad..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/velapsedtimer.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VELAPSEDTIMER_H -#define VELAPSEDTIMER_H - -#include -#include "vglobal.h" - -class VElapsedTimer { -public: - double elapsed() const; - bool hasExpired(double millsec); - void start(); - double restart(); - inline bool isValid() const { return m_valid; } - -private: - std::chrono::high_resolution_clock::time_point clock; - bool m_valid{false}; -}; -#endif // VELAPSEDTIMER_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vglobal.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vglobal.h deleted file mode 100644 index 0aad7e8c..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vglobal.h +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VGLOBAL_H -#define VGLOBAL_H - -#include -#include -#include -#include -#include - - -#if !defined(V_NAMESPACE) - -#define V_USE_NAMESPACE -#define V_BEGIN_NAMESPACE -#define V_END_NAMESPACE - -#else /* user namespace */ - -#define V_USE_NAMESPACE using namespace ::V_NAMESPACE; -#define V_BEGIN_NAMESPACE namespace V_NAMESPACE { -#define V_END_NAMESPACE } - -#endif - -#ifndef __has_attribute -# define __has_attribute(x) 0 -#endif /* !__has_attribute */ - -#if __has_attribute(unused) -# define V_UNUSED __attribute__((__unused__)) -#else -# define V_UNUSED -#endif /* V_UNUSED */ - -#if __has_attribute(warn_unused_result) -# define V_REQUIRED_RESULT __attribute__((__warn_unused_result__)) -#else -# define V_REQUIRED_RESULT -#endif /* V_REQUIRED_RESULT */ - -#define V_CONSTEXPR constexpr -#define V_NOTHROW noexcept - -#include "vdebug.h" - -#if __GNUC__ >= 7 -#define VECTOR_FALLTHROUGH __attribute__ ((fallthrough)); -#else -#define VECTOR_FALLTHROUGH -#endif - -#ifdef LOTTIE_THREAD_SUPPORT -#define vthread_local thread_local -#else -#define vthread_local -#endif - -#if defined(_MSC_VER) - #define V_ALWAYS_INLINE __forceinline -#else - #define V_ALWAYS_INLINE __attribute__((always_inline)) -#endif - -template -V_CONSTEXPR inline const T &vMin(const T &a, const T &b) -{ - return (a < b) ? a : b; -} -template -V_CONSTEXPR inline const T &vMax(const T &a, const T &b) -{ - return (a < b) ? b : a; -} - -static const double EPSILON_DOUBLE = 0.000000000001f; -static const float EPSILON_FLOAT = 0.000001f; - -static inline bool vCompare(float p1, float p2) -{ - return (std::abs(p1 - p2) < EPSILON_FLOAT); -} - -static inline bool vIsZero(float f) -{ - return (std::abs(f) <= EPSILON_FLOAT); -} - -static inline bool vIsZero(double f) -{ - return (std::abs(f) <= EPSILON_DOUBLE); -} - -class vFlagHelper { - int i; - -public: - explicit constexpr inline vFlagHelper(int ai) noexcept : i(ai) {} - constexpr inline operator int() const noexcept { return i; } - - explicit constexpr inline vFlagHelper(uint32_t ai) noexcept : i(int(ai)) {} - explicit constexpr inline vFlagHelper(short ai) noexcept : i(int(ai)) {} - explicit constexpr inline vFlagHelper(uint16_t ai) noexcept - : i(int(uint32_t(ai))) - { - } - constexpr inline operator uint32_t() const noexcept { return uint32_t(i); } -}; - -template -class vFlag { -public: - static_assert( - (sizeof(Enum) <= sizeof(int)), - "vFlag only supports int as storage so bigger type will overflow"); - static_assert((std::is_enum::value), - "vFlag is only usable on enumeration types."); - - using Int = typename std::conditional< - std::is_unsigned::type>::value, - uint32_t, signed int>::type; - - using enum_type = Enum; - // compiler-generated copy/move ctor/assignment operators are fine! - - vFlag() = default; - constexpr vFlag(Enum f) noexcept : i(Int(f)) {} - explicit constexpr vFlag(vFlagHelper f) noexcept : i(f) {} - - inline vFlag &operator&=(int mask) noexcept - { - i &= mask; - return *this; - } - inline vFlag &operator&=(uint32_t mask) noexcept - { - i &= mask; - return *this; - } - inline vFlag &operator&=(Enum mask) noexcept - { - i &= Int(mask); - return *this; - } - inline vFlag &operator|=(vFlag f) noexcept - { - i |= f.i; - return *this; - } - inline vFlag &operator|=(Enum f) noexcept - { - i |= Int(f); - return *this; - } - inline vFlag &operator^=(vFlag f) noexcept - { - i ^= f.i; - return *this; - } - inline vFlag &operator^=(Enum f) noexcept - { - i ^= Int(f); - return *this; - } - - constexpr inline operator Int() const noexcept { return i; } - - constexpr inline vFlag operator|(vFlag f) const - { - return vFlag(vFlagHelper(i | f.i)); - } - constexpr inline vFlag operator|(Enum f) const noexcept - { - return vFlag(vFlagHelper(i | Int(f))); - } - constexpr inline vFlag operator^(vFlag f) const noexcept - { - return vFlag(vFlagHelper(i ^ f.i)); - } - constexpr inline vFlag operator^(Enum f) const noexcept - { - return vFlag(vFlagHelper(i ^ Int(f))); - } - constexpr inline vFlag operator&(int mask) const noexcept - { - return vFlag(vFlagHelper(i & mask)); - } - constexpr inline vFlag operator&(uint32_t mask) const noexcept - { - return vFlag(vFlagHelper(i & mask)); - } - constexpr inline vFlag operator&(Enum f) const noexcept - { - return vFlag(vFlagHelper(i & Int(f))); - } - constexpr inline vFlag operator~() const noexcept - { - return vFlag(vFlagHelper(~i)); - } - - constexpr inline bool operator!() const noexcept { return !i; } - - constexpr inline bool testFlag(Enum f) const noexcept - { - return (i & Int(f)) == Int(f) && (Int(f) != 0 || i == Int(f)); - } - inline vFlag &setFlag(Enum f, bool on = true) noexcept - { - return on ? (*this |= f) : (*this &= ~f); - } - - Int i{0}; -}; - -class VColor { -public: - VColor() = default; - explicit VColor(uint8_t red, uint8_t green, uint8_t blue, - uint8_t alpha = 255) noexcept - : a(alpha), r(red), g(green), b(blue) - { - } - inline uint8_t red() const noexcept { return r; } - inline uint8_t green() const noexcept { return g; } - inline uint8_t blue() const noexcept { return b; } - inline uint8_t alpha() const noexcept { return a; } - inline void setRed(uint8_t red) noexcept { r = red; } - inline void setGreen(uint8_t green) noexcept { g = green; } - inline void setBlue(uint8_t blue) noexcept { b = blue; } - inline void setAlpha(uint8_t alpha) noexcept { a = alpha; } - inline bool isOpaque() const { return a == 255; } - inline bool isTransparent() const { return a == 0; } - inline bool operator==(const VColor &o) const - { - return ((a == o.a) && (r == o.r) && (g == o.g) && (b == o.b)); - } - uint32_t premulARGB() const - { - int pr = (r * a) / 255; - int pg = (g * a) / 255; - int pb = (b * a) / 255; - return uint32_t((a << 24) | (pr << 16) | (pg << 8) | (pb)); - } - - uint32_t premulARGB(float opacity) const - { - int alpha = int(a * opacity); - int pr = (r * alpha) / 255; - int pg = (g * alpha) / 255; - int pb = (b * alpha) / 255; - return uint32_t((alpha << 24) | (pr << 16) | (pg << 8) | (pb)); - } - -public: - uint8_t a{0}; - uint8_t r{0}; - uint8_t g{0}; - uint8_t b{0}; -}; - -enum class FillRule: unsigned char { EvenOdd, Winding }; -enum class JoinStyle: unsigned char { Miter, Bevel, Round }; -enum class CapStyle: unsigned char { Flat, Square, Round }; - -enum class BlendMode { - Src, - SrcOver, - DestIn, - DestOut, - Last, -}; - -#ifndef V_CONSTRUCTOR_FUNCTION -#define V_CONSTRUCTOR_FUNCTION0(AFUNC) \ - namespace { \ - static const struct AFUNC##_ctor_class_ { \ - inline AFUNC##_ctor_class_() { AFUNC(); } \ - } AFUNC##_ctor_instance_; \ - } - -#define V_CONSTRUCTOR_FUNCTION(AFUNC) V_CONSTRUCTOR_FUNCTION0(AFUNC) -#endif - -#endif // VGLOBAL_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vimageloader.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vimageloader.cpp deleted file mode 100644 index c2446be9..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vimageloader.cpp +++ /dev/null @@ -1,220 +0,0 @@ -#include "vimageloader.h" -#include "config.h" -#include "vdebug.h" -#include - -#ifdef _WIN32 -# include -#else -# include -#endif // _WIN32 - -using lottie_image_load_f = unsigned char *(*)(const char *filename, int *x, - int *y, int *comp, int req_comp); -using lottie_image_load_data_f = unsigned char *(*)(const char *data, int len, - int *x, int *y, int *comp, - int req_comp); -using lottie_image_free_f = void (*)(unsigned char *); - -#ifdef __cplusplus -extern "C" { -#endif - -extern unsigned char *lottie_image_load(char const *filename, int *x, int *y, - int *comp, int req_comp); -extern unsigned char *lottie_image_load_from_data(const char *imageData, - int len, int *x, int *y, - int *comp, int req_comp); -extern void lottie_image_free(unsigned char *data); - -#ifdef __cplusplus -} -#endif - -struct VImageLoader::Impl { - lottie_image_load_f imageLoad{nullptr}; - lottie_image_free_f imageFree{nullptr}; - lottie_image_load_data_f imageFromData{nullptr}; - -#ifdef LOTTIE_IMAGE_MODULE_SUPPORT -# ifdef _WIN32 - HMODULE dl_handle{nullptr}; - bool moduleLoad() - { - dl_handle = LoadLibraryA(LOTTIE_IMAGE_MODULE_PLUGIN); - return (dl_handle == nullptr); - } - void moduleFree() - { - if (dl_handle) FreeLibrary(dl_handle); - } - void init() - { - imageLoad = reinterpret_cast( - GetProcAddress(dl_handle, "lottie_image_load")); - imageFree = reinterpret_cast( - GetProcAddress(dl_handle, "lottie_image_free")); - imageFromData = reinterpret_cast( - GetProcAddress(dl_handle, "lottie_image_load_from_data")); - } -# else // _WIN32 - void *dl_handle{nullptr}; - void init() - { - imageLoad = reinterpret_cast( - dlsym(dl_handle, "lottie_image_load")); - imageFree = reinterpret_cast( - dlsym(dl_handle, "lottie_image_free")); - imageFromData = reinterpret_cast( - dlsym(dl_handle, "lottie_image_load_from_data")); - } - - void moduleFree() - { - if (dl_handle) dlclose(dl_handle); - } - bool moduleLoad() - { - dl_handle = dlopen(LOTTIE_IMAGE_MODULE_PLUGIN, RTLD_LAZY); - return (dl_handle == nullptr); - } -# endif // _WIN32 -#else // LOTTIE_IMAGE_MODULE_SUPPORT - void init() - { - imageLoad = lottie_image_load; - imageFree = lottie_image_free; - imageFromData = lottie_image_load_from_data; - } - void moduleFree() {} - bool moduleLoad() { return false; } -#endif // LOTTIE_IMAGE_MODULE_SUPPORT - - Impl() - { - if (moduleLoad()) { - vWarning << "Failed to dlopen librlottie-image-loader library"; - return; - } - - init(); - - if (!imageLoad) - vWarning << "Failed to find symbol lottie_image_load in " - "librlottie-image-loader library"; - - if (!imageFree) - vWarning << "Failed to find symbol lottie_image_free in " - "librlottie-image-loader library"; - - if (!imageFromData) - vWarning << "Failed to find symbol lottie_image_load_data in " - "librlottie-image-loader library"; - } - - ~Impl() { moduleFree(); } - - VBitmap createBitmap(unsigned char *data, int width, int height, - int channel) - { - // premultiply alpha - if (channel == 4) - convertToBGRAPremul(data, width, height); - else - convertToBGRA(data, width, height); - - // create a bitmap of same size. - VBitmap result = - VBitmap(width, height, VBitmap::Format::ARGB32_Premultiplied); - - // copy the data to bitmap buffer - memcpy(result.data(), data, width * height * 4); - - // free the image data - imageFree(data); - - return result; - } - - VBitmap load(const char *fileName) - { - if (!imageLoad) return VBitmap(); - - int width, height, n; - unsigned char *data = imageLoad(fileName, &width, &height, &n, 4); - - if (!data) { - return VBitmap(); - } - - return createBitmap(data, width, height, n); - } - - VBitmap load(const char *imageData, size_t len) - { - if (!imageFromData) return VBitmap(); - - int width, height, n; - unsigned char *data = - imageFromData(imageData, static_cast(len), &width, &height, &n, 4); - - if (!data) { - return VBitmap(); - } - - return createBitmap(data, width, height, n); - } - /* - * convert from RGBA to BGRA and premultiply - */ - void convertToBGRAPremul(unsigned char *bits, int width, int height) - { - int pixelCount = width * height; - unsigned char *pix = bits; - for (int i = 0; i < pixelCount; i++) { - unsigned char r = pix[0]; - unsigned char g = pix[1]; - unsigned char b = pix[2]; - unsigned char a = pix[3]; - - r = (r * a) / 255; - g = (g * a) / 255; - b = (b * a) / 255; - - pix[0] = b; - pix[1] = g; - pix[2] = r; - - pix += 4; - } - } - /* - * convert from RGBA to BGRA - */ - void convertToBGRA(unsigned char *bits, int width, int height) - { - int pixelCount = width * height; - unsigned char *pix = bits; - for (int i = 0; i < pixelCount; i++) { - unsigned char r = pix[0]; - unsigned char b = pix[2]; - pix[0] = b; - pix[2] = r; - pix += 4; - } - } -}; - -VImageLoader::VImageLoader() : mImpl(std::make_unique()) {} - -VImageLoader::~VImageLoader() {} - -VBitmap VImageLoader::load(const char *fileName) -{ - return mImpl->load(fileName); -} - -VBitmap VImageLoader::load(const char *data, size_t len) -{ - return mImpl->load(data, int(len)); -} diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vimageloader.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vimageloader.h deleted file mode 100644 index 4d96a7dc..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vimageloader.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef VIMAGELOADER_H -#define VIMAGELOADER_H - -#include - -#include "vbitmap.h" - -class VImageLoader -{ -public: - static VImageLoader& instance() - { - static VImageLoader singleton; - return singleton; - } - - VBitmap load(const char *fileName); - VBitmap load(const char *data, size_t len); - ~VImageLoader(); -private: - VImageLoader(); - struct Impl; - std::unique_ptr mImpl; -}; - -#endif // VIMAGELOADER_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vinterpolator.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vinterpolator.cpp deleted file mode 100644 index fca07846..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vinterpolator.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "vinterpolator.h" -#include - -V_BEGIN_NAMESPACE - -#define NEWTON_ITERATIONS 4 -#define NEWTON_MIN_SLOPE 0.02 -#define SUBDIVISION_PRECISION 0.0000001 -#define SUBDIVISION_MAX_ITERATIONS 10 - -const float VInterpolator::kSampleStepSize = - 1.0f / float(VInterpolator::kSplineTableSize - 1); - -void VInterpolator::init(float aX1, float aY1, float aX2, float aY2) -{ - mX1 = aX1; - mY1 = aY1; - mX2 = aX2; - mY2 = aY2; - - if (mX1 != mY1 || mX2 != mY2) CalcSampleValues(); -} - -/*static*/ float VInterpolator::CalcBezier(float aT, float aA1, float aA2) -{ - // use Horner's scheme to evaluate the Bezier polynomial - return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; -} - -void VInterpolator::CalcSampleValues() -{ - for (int i = 0; i < kSplineTableSize; ++i) { - mSampleValues[i] = CalcBezier(float(i) * kSampleStepSize, mX1, mX2); - } -} - -float VInterpolator::GetSlope(float aT, float aA1, float aA2) -{ - return 3.0f * A(aA1, aA2) * aT * aT + 2.0f * B(aA1, aA2) * aT + C(aA1); -} - -float VInterpolator::value(float aX) const -{ - if (mX1 == mY1 && mX2 == mY2) return aX; - - return CalcBezier(GetTForX(aX), mY1, mY2); -} - -float VInterpolator::GetTForX(float aX) const -{ - // Find interval where t lies - float intervalStart = 0.0; - const float* currentSample = &mSampleValues[1]; - const float* const lastSample = &mSampleValues[kSplineTableSize - 1]; - for (; currentSample != lastSample && *currentSample <= aX; - ++currentSample) { - intervalStart += kSampleStepSize; - } - --currentSample; // t now lies between *currentSample and *currentSample+1 - - // Interpolate to provide an initial guess for t - float dist = - (aX - *currentSample) / (*(currentSample + 1) - *currentSample); - float guessForT = intervalStart + dist * kSampleStepSize; - - // Check the slope to see what strategy to use. If the slope is too small - // Newton-Raphson iteration won't converge on a root so we use bisection - // instead. - float initialSlope = GetSlope(guessForT, mX1, mX2); - if (initialSlope >= NEWTON_MIN_SLOPE) { - return NewtonRaphsonIterate(aX, guessForT); - } else if (initialSlope == 0.0) { - return guessForT; - } else { - return BinarySubdivide(aX, intervalStart, - intervalStart + kSampleStepSize); - } -} - -float VInterpolator::NewtonRaphsonIterate(float aX, float aGuessT) const -{ - // Refine guess with Newton-Raphson iteration - for (int i = 0; i < NEWTON_ITERATIONS; ++i) { - // We're trying to find where f(t) = aX, - // so we're actually looking for a root for: CalcBezier(t) - aX - float currentX = CalcBezier(aGuessT, mX1, mX2) - aX; - float currentSlope = GetSlope(aGuessT, mX1, mX2); - - if (currentSlope == 0.0) return aGuessT; - - aGuessT -= currentX / currentSlope; - } - - return aGuessT; -} - -float VInterpolator::BinarySubdivide(float aX, float aA, float aB) const -{ - float currentX; - float currentT; - int i = 0; - - do { - currentT = aA + (aB - aA) / 2.0f; - currentX = CalcBezier(currentT, mX1, mX2) - aX; - - if (currentX > 0.0) { - aB = currentT; - } else { - aA = currentT; - } - } while (fabs(currentX) > SUBDIVISION_PRECISION && - ++i < SUBDIVISION_MAX_ITERATIONS); - - return currentT; -} - -V_END_NAMESPACE diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vinterpolator.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vinterpolator.h deleted file mode 100644 index 0218eab5..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vinterpolator.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VINTERPOLATOR_H -#define VINTERPOLATOR_H - -#include "vpoint.h" - -V_BEGIN_NAMESPACE - -class VInterpolator { -public: - VInterpolator() - { /* caller must call Init later */ - } - - VInterpolator(float aX1, float aY1, float aX2, float aY2) - { - init(aX1, aY1, aX2, aY2); - } - - VInterpolator(VPointF pt1, VPointF pt2) - { - init(pt1.x(), pt1.y(), pt2.x(), pt2.y()); - } - - void init(float aX1, float aY1, float aX2, float aY2); - - float value(float aX) const; - - void GetSplineDerivativeValues(float aX, float& aDX, float& aDY) const; - -private: - void CalcSampleValues(); - - /** - * Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2. - */ - static float CalcBezier(float aT, float aA1, float aA2); - - /** - * Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2. - */ - static float GetSlope(float aT, float aA1, float aA2); - - float GetTForX(float aX) const; - - float NewtonRaphsonIterate(float aX, float aGuessT) const; - - float BinarySubdivide(float aX, float aA, float aB) const; - - static float A(float aA1, float aA2) { return 1.0f - 3.0f * aA2 + 3.0f * aA1; } - - static float B(float aA1, float aA2) { return 3.0f * aA2 - 6.0f * aA1; } - - static float C(float aA1) { return 3.0f * aA1; } - - float mX1; - float mY1; - float mX2; - float mY2; - enum { kSplineTableSize = 11 }; - float mSampleValues[kSplineTableSize]; - static const float kSampleStepSize; -}; - -V_END_NAMESPACE - -#endif // VINTERPOLATOR_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vline.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vline.h deleted file mode 100644 index ee8b4a56..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vline.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VLINE_H -#define VLINE_H - -#include "vglobal.h" -#include "vpoint.h" - -V_BEGIN_NAMESPACE - -class VLine { -public: - VLine() = default; - VLine(float x1, float y1, float x2, float y2) - : mX1(x1), mY1(y1), mX2(x2), mY2(y2) - { - } - VLine(const VPointF &p1, const VPointF &p2) - : mX1(p1.x()), mY1(p1.y()), mX2(p2.x()), mY2(p2.y()) - { - } - float length() const { return length(mX1, mY1, mX2, mY2);} - void splitAtLength(float length, VLine &left, VLine &right) const; - VPointF p1() const { return {mX1, mY1}; } - VPointF p2() const { return {mX2, mY2}; } - float angle() const; - static float length(float x1, float y1, float x2, float y2); - -private: - float mX1{0}; - float mY1{0}; - float mX2{0}; - float mY2{0}; -}; - -inline float VLine::angle() const -{ - static constexpr float K_PI = 3.141592f; - const float dx = mX2 - mX1; - const float dy = mY2 - mY1; - - const float theta = std::atan2(dy, dx) * 180.0f / K_PI; - return theta; -} - -// approximate sqrt(x*x + y*y) using alpha max plus beta min algorithm. -// With alpha = 1, beta = 3/8, giving results with the largest error less -// than 7% compared to the exact value. -inline V_ALWAYS_INLINE float VLine::length(float x1, float y1, float x2, float y2) -{ - float x = x2 - x1; - float y = y2 - y1; - - x = x < 0 ? -x : x; - y = y < 0 ? -y : y; - - return (x > y ? x + 0.375f * y : y + 0.375f * x); -} - -inline void VLine::splitAtLength(float lengthAt, VLine &left, VLine &right) const -{ - float len = length(); - float dx = ((mX2 - mX1) / len) * lengthAt; - float dy = ((mY2 - mY1) / len) * lengthAt; - - left.mX1 = mX1; - left.mY1 = mY1; - left.mX2 = left.mX1 + dx; - left.mY2 = left.mY1 + dy; - - right.mX1 = left.mX2; - right.mY1 = left.mY2; - right.mX2 = mX2; - right.mY2 = mY2; -} - -#endif //VLINE_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vmatrix.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vmatrix.cpp deleted file mode 100644 index 7efed61b..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vmatrix.cpp +++ /dev/null @@ -1,684 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "vmatrix.h" -#include -#include -#include - -V_BEGIN_NAMESPACE - -/* m11 m21 mtx - * m12 m22 mty - * m13 m23 m33 - */ - -inline float VMatrix::determinant() const -{ - return m11 * (m33 * m22 - mty * m23) - m21 * (m33 * m12 - mty * m13) + - mtx * (m23 * m12 - m22 * m13); -} - -bool VMatrix::isAffine() const -{ - return type() < MatrixType::Project; -} - -bool VMatrix::isIdentity() const -{ - return type() == MatrixType::None; -} - -bool VMatrix::isInvertible() const -{ - return !vIsZero(determinant()); -} - -bool VMatrix::isScaling() const -{ - return type() >= MatrixType::Scale; -} -bool VMatrix::isRotating() const -{ - return type() >= MatrixType::Rotate; -} - -bool VMatrix::isTranslating() const -{ - return type() >= MatrixType::Translate; -} - -VMatrix &VMatrix::operator*=(float num) -{ - if (num == 1.) return *this; - - m11 *= num; - m12 *= num; - m13 *= num; - m21 *= num; - m22 *= num; - m23 *= num; - mtx *= num; - mty *= num; - m33 *= num; - if (dirty < MatrixType::Scale) dirty = MatrixType::Scale; - - return *this; -} - -VMatrix &VMatrix::operator/=(float div) -{ - if (div == 0) return *this; - - div = 1 / div; - return operator*=(div); -} - -VMatrix::MatrixType VMatrix::type() const -{ - if (dirty == MatrixType::None || dirty < mType) return mType; - - switch (dirty) { - case MatrixType::Project: - if (!vIsZero(m13) || !vIsZero(m23) || !vIsZero(m33 - 1)) { - mType = MatrixType::Project; - break; - } - VECTOR_FALLTHROUGH - case MatrixType::Shear: - case MatrixType::Rotate: - if (!vIsZero(m12) || !vIsZero(m21)) { - const float dot = m11 * m12 + m21 * m22; - if (vIsZero(dot)) - mType = MatrixType::Rotate; - else - mType = MatrixType::Shear; - break; - } - VECTOR_FALLTHROUGH - case MatrixType::Scale: - if (!vIsZero(m11 - 1) || !vIsZero(m22 - 1)) { - mType = MatrixType::Scale; - break; - } - VECTOR_FALLTHROUGH - case MatrixType::Translate: - if (!vIsZero(mtx) || !vIsZero(mty)) { - mType = MatrixType::Translate; - break; - } - VECTOR_FALLTHROUGH - case MatrixType::None: - mType = MatrixType::None; - break; - } - - dirty = MatrixType::None; - return mType; -} - -VMatrix &VMatrix::translate(float dx, float dy) -{ - if (dx == 0 && dy == 0) return *this; - - switch (type()) { - case MatrixType::None: - mtx = dx; - mty = dy; - break; - case MatrixType::Translate: - mtx += dx; - mty += dy; - break; - case MatrixType::Scale: - mtx += dx * m11; - mty += dy * m22; - break; - case MatrixType::Project: - m33 += dx * m13 + dy * m23; - VECTOR_FALLTHROUGH - case MatrixType::Shear: - case MatrixType::Rotate: - mtx += dx * m11 + dy * m21; - mty += dy * m22 + dx * m12; - break; - } - if (dirty < MatrixType::Translate) dirty = MatrixType::Translate; - return *this; -} - -VMatrix &VMatrix::scale(float sx, float sy) -{ - if (sx == 1 && sy == 1) return *this; - - switch (type()) { - case MatrixType::None: - case MatrixType::Translate: - m11 = sx; - m22 = sy; - break; - case MatrixType::Project: - m13 *= sx; - m23 *= sy; - VECTOR_FALLTHROUGH - case MatrixType::Rotate: - case MatrixType::Shear: - m12 *= sx; - m21 *= sy; - VECTOR_FALLTHROUGH - case MatrixType::Scale: - m11 *= sx; - m22 *= sy; - break; - } - if (dirty < MatrixType::Scale) dirty = MatrixType::Scale; - return *this; -} - -VMatrix &VMatrix::shear(float sh, float sv) -{ - if (sh == 0 && sv == 0) return *this; - - switch (type()) { - case MatrixType::None: - case MatrixType::Translate: - m12 = sv; - m21 = sh; - break; - case MatrixType::Scale: - m12 = sv * m22; - m21 = sh * m11; - break; - case MatrixType::Project: { - float tm13 = sv * m23; - float tm23 = sh * m13; - m13 += tm13; - m23 += tm23; - VECTOR_FALLTHROUGH - } - case MatrixType::Rotate: - case MatrixType::Shear: { - float tm11 = sv * m21; - float tm22 = sh * m12; - float tm12 = sv * m22; - float tm21 = sh * m11; - m11 += tm11; - m12 += tm12; - m21 += tm21; - m22 += tm22; - break; - } - } - if (dirty < MatrixType::Shear) dirty = MatrixType::Shear; - return *this; -} - -static const float deg2rad = float(0.017453292519943295769); // pi/180 -static const float inv_dist_to_plane = 1. / 1024.; - -VMatrix &VMatrix::rotate(float a, Axis axis) -{ - if (a == 0) return *this; - - float sina = 0; - float cosa = 0; - if (a == 90. || a == -270.) - sina = 1.; - else if (a == 270. || a == -90.) - sina = -1.; - else if (a == 180.) - cosa = -1.; - else { - float b = deg2rad * a; // convert to radians - sina = std::sin(b); // fast and convenient - cosa = std::cos(b); - } - - if (axis == Axis::Z) { - switch (type()) { - case MatrixType::None: - case MatrixType::Translate: - m11 = cosa; - m12 = sina; - m21 = -sina; - m22 = cosa; - break; - case MatrixType::Scale: { - float tm11 = cosa * m11; - float tm12 = sina * m22; - float tm21 = -sina * m11; - float tm22 = cosa * m22; - m11 = tm11; - m12 = tm12; - m21 = tm21; - m22 = tm22; - break; - } - case MatrixType::Project: { - float tm13 = cosa * m13 + sina * m23; - float tm23 = -sina * m13 + cosa * m23; - m13 = tm13; - m23 = tm23; - VECTOR_FALLTHROUGH - } - case MatrixType::Rotate: - case MatrixType::Shear: { - float tm11 = cosa * m11 + sina * m21; - float tm12 = cosa * m12 + sina * m22; - float tm21 = -sina * m11 + cosa * m21; - float tm22 = -sina * m12 + cosa * m22; - m11 = tm11; - m12 = tm12; - m21 = tm21; - m22 = tm22; - break; - } - } - if (dirty < MatrixType::Rotate) dirty = MatrixType::Rotate; - } else { - VMatrix result; - if (axis == Axis::Y) { - result.m11 = cosa; - result.m13 = -sina * inv_dist_to_plane; - } else { - result.m22 = cosa; - result.m23 = -sina * inv_dist_to_plane; - } - result.mType = MatrixType::Project; - *this = result * *this; - } - - return *this; -} - -VMatrix VMatrix::operator*(const VMatrix &m) const -{ - const MatrixType otherType = m.type(); - if (otherType == MatrixType::None) return *this; - - const MatrixType thisType = type(); - if (thisType == MatrixType::None) return m; - - VMatrix t; - MatrixType type = vMax(thisType, otherType); - switch (type) { - case MatrixType::None: - break; - case MatrixType::Translate: - t.mtx = mtx + m.mtx; - t.mty += mty + m.mty; - break; - case MatrixType::Scale: { - float m11v = m11 * m.m11; - float m22v = m22 * m.m22; - - float m31v = mtx * m.m11 + m.mtx; - float m32v = mty * m.m22 + m.mty; - - t.m11 = m11v; - t.m22 = m22v; - t.mtx = m31v; - t.mty = m32v; - break; - } - case MatrixType::Rotate: - case MatrixType::Shear: { - float m11v = m11 * m.m11 + m12 * m.m21; - float m12v = m11 * m.m12 + m12 * m.m22; - - float m21v = m21 * m.m11 + m22 * m.m21; - float m22v = m21 * m.m12 + m22 * m.m22; - - float m31v = mtx * m.m11 + mty * m.m21 + m.mtx; - float m32v = mtx * m.m12 + mty * m.m22 + m.mty; - - t.m11 = m11v; - t.m12 = m12v; - t.m21 = m21v; - t.m22 = m22v; - t.mtx = m31v; - t.mty = m32v; - break; - } - case MatrixType::Project: { - float m11v = m11 * m.m11 + m12 * m.m21 + m13 * m.mtx; - float m12v = m11 * m.m12 + m12 * m.m22 + m13 * m.mty; - float m13v = m11 * m.m13 + m12 * m.m23 + m13 * m.m33; - - float m21v = m21 * m.m11 + m22 * m.m21 + m23 * m.mtx; - float m22v = m21 * m.m12 + m22 * m.m22 + m23 * m.mty; - float m23v = m21 * m.m13 + m22 * m.m23 + m23 * m.m33; - - float m31v = mtx * m.m11 + mty * m.m21 + m33 * m.mtx; - float m32v = mtx * m.m12 + mty * m.m22 + m33 * m.mty; - float m33v = mtx * m.m13 + mty * m.m23 + m33 * m.m33; - - t.m11 = m11v; - t.m12 = m12v; - t.m13 = m13v; - t.m21 = m21v; - t.m22 = m22v; - t.m23 = m23v; - t.mtx = m31v; - t.mty = m32v; - t.m33 = m33v; - } - } - - t.dirty = type; - t.mType = type; - - return t; -} - -VMatrix &VMatrix::operator*=(const VMatrix &o) -{ - const MatrixType otherType = o.type(); - if (otherType == MatrixType::None) return *this; - - const MatrixType thisType = type(); - if (thisType == MatrixType::None) return operator=(o); - - MatrixType t = vMax(thisType, otherType); - switch (t) { - case MatrixType::None: - break; - case MatrixType::Translate: - mtx += o.mtx; - mty += o.mty; - break; - case MatrixType::Scale: { - float m11v = m11 * o.m11; - float m22v = m22 * o.m22; - - float m31v = mtx * o.m11 + o.mtx; - float m32v = mty * o.m22 + o.mty; - - m11 = m11v; - m22 = m22v; - mtx = m31v; - mty = m32v; - break; - } - case MatrixType::Rotate: - case MatrixType::Shear: { - float m11v = m11 * o.m11 + m12 * o.m21; - float m12v = m11 * o.m12 + m12 * o.m22; - - float m21v = m21 * o.m11 + m22 * o.m21; - float m22v = m21 * o.m12 + m22 * o.m22; - - float m31v = mtx * o.m11 + mty * o.m21 + o.mtx; - float m32v = mtx * o.m12 + mty * o.m22 + o.mty; - - m11 = m11v; - m12 = m12v; - m21 = m21v; - m22 = m22v; - mtx = m31v; - mty = m32v; - break; - } - case MatrixType::Project: { - float m11v = m11 * o.m11 + m12 * o.m21 + m13 * o.mtx; - float m12v = m11 * o.m12 + m12 * o.m22 + m13 * o.mty; - float m13v = m11 * o.m13 + m12 * o.m23 + m13 * o.m33; - - float m21v = m21 * o.m11 + m22 * o.m21 + m23 * o.mtx; - float m22v = m21 * o.m12 + m22 * o.m22 + m23 * o.mty; - float m23v = m21 * o.m13 + m22 * o.m23 + m23 * o.m33; - - float m31v = mtx * o.m11 + mty * o.m21 + m33 * o.mtx; - float m32v = mtx * o.m12 + mty * o.m22 + m33 * o.mty; - float m33v = mtx * o.m13 + mty * o.m23 + m33 * o.m33; - - m11 = m11v; - m12 = m12v; - m13 = m13v; - m21 = m21v; - m22 = m22v; - m23 = m23v; - mtx = m31v; - mty = m32v; - m33 = m33v; - } - } - - dirty = t; - mType = t; - - return *this; -} - -VMatrix VMatrix::adjoint() const -{ - float h11, h12, h13, h21, h22, h23, h31, h32, h33; - h11 = m22 * m33 - m23 * mty; - h21 = m23 * mtx - m21 * m33; - h31 = m21 * mty - m22 * mtx; - h12 = m13 * mty - m12 * m33; - h22 = m11 * m33 - m13 * mtx; - h32 = m12 * mtx - m11 * mty; - h13 = m12 * m23 - m13 * m22; - h23 = m13 * m21 - m11 * m23; - h33 = m11 * m22 - m12 * m21; - - VMatrix res; - res.m11 = h11; - res.m12 = h12; - res.m13 = h13; - res.m21 = h21; - res.m22 = h22; - res.m23 = h23; - res.mtx = h31; - res.mty = h32; - res.m33 = h33; - res.mType = MatrixType::None; - res.dirty = MatrixType::Project; - - return res; -} - -VMatrix VMatrix::inverted(bool *invertible) const -{ - VMatrix invert; - bool inv = true; - - switch (type()) { - case MatrixType::None: - break; - case MatrixType::Translate: - invert.mtx = -mtx; - invert.mty = -mty; - break; - case MatrixType::Scale: - inv = !vIsZero(m11); - inv &= !vIsZero(m22); - if (inv) { - invert.m11 = 1.0f / m11; - invert.m22 = 1.0f / m22; - invert.mtx = -mtx * invert.m11; - invert.mty = -mty * invert.m22; - } - break; - default: - // general case - float det = determinant(); - inv = !vIsZero(det); - if (inv) invert = (adjoint() /= det); - // TODO Test above line - break; - } - - if (invertible) *invertible = inv; - - if (inv) { - // inverting doesn't change the type - invert.mType = mType; - invert.dirty = dirty; - } - - return invert; -} - -bool VMatrix::operator==(const VMatrix &o) const -{ - return fuzzyCompare(o); -} - -bool VMatrix::operator!=(const VMatrix &o) const -{ - return !operator==(o); -} - -bool VMatrix::fuzzyCompare(const VMatrix &o) const -{ - return vCompare(m11, o.m11) && vCompare(m12, o.m12) && - vCompare(m21, o.m21) && vCompare(m22, o.m22) && - vCompare(mtx, o.mtx) && vCompare(mty, o.mty); -} - -#define V_NEAR_CLIP 0.000001f -#ifdef MAP -#undef MAP -#endif -#define MAP(x, y, nx, ny) \ - do { \ - float FX_ = x; \ - float FY_ = y; \ - switch (t) { \ - case MatrixType::None: \ - nx = FX_; \ - ny = FY_; \ - break; \ - case MatrixType::Translate: \ - nx = FX_ + mtx; \ - ny = FY_ + mty; \ - break; \ - case MatrixType::Scale: \ - nx = m11 * FX_ + mtx; \ - ny = m22 * FY_ + mty; \ - break; \ - case MatrixType::Rotate: \ - case MatrixType::Shear: \ - case MatrixType::Project: \ - nx = m11 * FX_ + m21 * FY_ + mtx; \ - ny = m12 * FX_ + m22 * FY_ + mty; \ - if (t == MatrixType::Project) { \ - float w = (m13 * FX_ + m23 * FY_ + m33); \ - if (w < V_NEAR_CLIP) w = V_NEAR_CLIP; \ - w = 1. / w; \ - nx *= w; \ - ny *= w; \ - } \ - } \ - } while (0) - -VRect VMatrix::map(const VRect &rect) const -{ - VMatrix::MatrixType t = type(); - if (t <= MatrixType::Translate) - return rect.translated(std::lround(mtx), std::lround(mty)); - - if (t <= MatrixType::Scale) { - int x = std::lround(m11 * rect.x() + mtx); - int y = std::lround(m22 * rect.y() + mty); - int w = std::lround(m11 * rect.width()); - int h = std::lround(m22 * rect.height()); - if (w < 0) { - w = -w; - x -= w; - } - if (h < 0) { - h = -h; - y -= h; - } - return {x, y, w, h}; - } else if (t < MatrixType::Project) { - // see mapToPolygon for explanations of the algorithm. - float x = 0, y = 0; - MAP(rect.left(), rect.top(), x, y); - float xmin = x; - float ymin = y; - float xmax = x; - float ymax = y; - MAP(rect.right() + 1, rect.top(), x, y); - xmin = vMin(xmin, x); - ymin = vMin(ymin, y); - xmax = vMax(xmax, x); - ymax = vMax(ymax, y); - MAP(rect.right() + 1, rect.bottom() + 1, x, y); - xmin = vMin(xmin, x); - ymin = vMin(ymin, y); - xmax = vMax(xmax, x); - ymax = vMax(ymax, y); - MAP(rect.left(), rect.bottom() + 1, x, y); - xmin = vMin(xmin, x); - ymin = vMin(ymin, y); - xmax = vMax(xmax, x); - ymax = vMax(ymax, y); - return VRect(std::lround(xmin), std::lround(ymin), - std::lround(xmax) - std::lround(xmin), - std::lround(ymax) - std::lround(ymin)); - } else { - // Not supported - assert(0); - return {}; - } -} - -VPointF VMatrix::map(const VPointF &p) const -{ - float fx = p.x(); - float fy = p.y(); - - float x = 0, y = 0; - - VMatrix::MatrixType t = type(); - switch (t) { - case MatrixType::None: - x = fx; - y = fy; - break; - case MatrixType::Translate: - x = fx + mtx; - y = fy + mty; - break; - case MatrixType::Scale: - x = m11 * fx + mtx; - y = m22 * fy + mty; - break; - case MatrixType::Rotate: - case MatrixType::Shear: - case MatrixType::Project: - x = m11 * fx + m21 * fy + mtx; - y = m12 * fx + m22 * fy + mty; - if (t == MatrixType::Project) { - float w = 1.0f / (m13 * fx + m23 * fy + m33); - x *= w; - y *= w; - } - } - return {x, y}; -} - -V_END_NAMESPACE diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vmatrix.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vmatrix.h deleted file mode 100644 index 941e16e9..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vmatrix.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VMATRIX_H -#define VMATRIX_H -#include "vglobal.h" -#include "vpoint.h" -#include "vrect.h" - -V_BEGIN_NAMESPACE - -struct VMatrixData; -class VMatrix { -public: - enum class Axis { X, Y, Z }; - enum class MatrixType: unsigned char { - None = 0x00, - Translate = 0x01, - Scale = 0x02, - Rotate = 0x04, - Shear = 0x08, - Project = 0x10 - }; - VMatrix() = default; - bool isAffine() const; - bool isIdentity() const; - bool isInvertible() const; - bool isScaling() const; - bool isRotating() const; - bool isTranslating() const; - MatrixType type() const; - inline float determinant() const; - - float m_11() const { return m11;} - float m_12() const { return m12;} - float m_13() const { return m13;} - - float m_21() const { return m21;} - float m_22() const { return m22;} - float m_23() const { return m23;} - - float m_tx() const { return mtx;} - float m_ty() const { return mty;} - float m_33() const { return m33;} - - VMatrix &translate(VPointF pos) { return translate(pos.x(), pos.y()); } - VMatrix &translate(float dx, float dy); - VMatrix &scale(VPointF s) { return scale(s.x(), s.y()); } - VMatrix &scale(float sx, float sy); - VMatrix &shear(float sh, float sv); - VMatrix &rotate(float a, Axis axis = VMatrix::Axis::Z); - VMatrix &rotateRadians(float a, Axis axis = VMatrix::Axis::Z); - - VPointF map(const VPointF &p) const; - inline VPointF map(float x, float y) const; - VRect map(const VRect &r) const; - - V_REQUIRED_RESULT VMatrix inverted(bool *invertible = nullptr) const; - V_REQUIRED_RESULT VMatrix adjoint() const; - - VMatrix operator*(const VMatrix &o) const; - VMatrix & operator*=(const VMatrix &); - VMatrix & operator*=(float mul); - VMatrix & operator/=(float div); - bool operator==(const VMatrix &) const; - bool operator!=(const VMatrix &) const; - bool fuzzyCompare(const VMatrix &) const; - float scale() const; -private: - friend struct VSpanData; - float m11{1}, m12{0}, m13{0}; - float m21{0}, m22{1}, m23{0}; - float mtx{0}, mty{0}, m33{1}; - mutable MatrixType mType{MatrixType::None}; - mutable MatrixType dirty{MatrixType::None}; -}; - -inline float VMatrix::scale() const -{ - constexpr float SQRT_2 = 1.41421f; - VPointF p1(0, 0); - VPointF p2(SQRT_2, SQRT_2); - p1 = map(p1); - p2 = map(p2); - VPointF final = p2 - p1; - - return std::sqrt(final.x() * final.x() + final.y() * final.y()) / 2.0f; -} - -inline VPointF VMatrix::map(float x, float y) const -{ - return map(VPointF(x, y)); -} - -V_END_NAMESPACE - -#endif // VMATRIX_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vpainter.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vpainter.cpp deleted file mode 100644 index ab5492c7..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vpainter.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "vpainter.h" -#include - - -V_BEGIN_NAMESPACE - - -void VPainter::drawRle(const VPoint &, const VRle &rle) -{ - if (rle.empty()) return; - // mSpanData.updateSpanFunc(); - - if (!mSpanData.mUnclippedBlendFunc) return; - - // do draw after applying clip. - rle.intersect(mSpanData.clipRect(), mSpanData.mUnclippedBlendFunc, - &mSpanData); -} - -void VPainter::drawRle(const VRle &rle, const VRle &clip) -{ - if (rle.empty() || clip.empty()) return; - - if (!mSpanData.mUnclippedBlendFunc) return; - - rle.intersect(clip, mSpanData.mUnclippedBlendFunc, &mSpanData); -} - -static void fillRect(const VRect &r, VSpanData *data) -{ - auto x1 = std::max(r.x(), 0); - auto x2 = std::min(r.x() + r.width(), data->mDrawableSize.width()); - auto y1 = std::max(r.y(), 0); - auto y2 = std::min(r.y() + r.height(), data->mDrawableSize.height()); - - if (x2 <= x1 || y2 <= y1) return; - - const int nspans = 256; - VRle::Span spans[nspans]; - - int y = y1; - while (y < y2) { - int n = std::min(nspans, y2 - y); - int i = 0; - while (i < n) { - spans[i].x = short(x1); - spans[i].len = uint16_t(x2 - x1); - spans[i].y = short(y + i); - spans[i].coverage = 255; - ++i; - } - - data->mUnclippedBlendFunc(n, spans, data); - y += n; - } -} - -void VPainter::drawBitmapUntransform(const VRect & target, - const VBitmap &bitmap, - const VRect & source, - uint8_t const_alpha) -{ - mSpanData.initTexture(&bitmap, const_alpha, source); - if (!mSpanData.mUnclippedBlendFunc) return; - - // update translation matrix for source texture. - mSpanData.dx = float(target.x() - source.x()); - mSpanData.dy = float(target.y() - source.y()); - - fillRect(target, &mSpanData); -} - -VPainter::VPainter(VBitmap *buffer) -{ - begin(buffer); -} -bool VPainter::begin(VBitmap *buffer) -{ - mBuffer.prepare(buffer); - mSpanData.init(&mBuffer); - // TODO find a better api to clear the surface - mBuffer.clear(); - return true; -} -void VPainter::end() {} - -void VPainter::setDrawRegion(const VRect ®ion) -{ - mSpanData.setDrawRegion(region); -} - -void VPainter::setBrush(const VBrush &brush) -{ - mSpanData.setup(brush); -} - -void VPainter::setBlendMode(BlendMode mode) -{ - mSpanData.mBlendMode = mode; -} - -VRect VPainter::clipBoundingRect() const -{ - return mSpanData.clipRect(); -} - -void VPainter::drawBitmap(const VPoint &point, const VBitmap &bitmap, - const VRect &source, uint8_t const_alpha) -{ - if (!bitmap.valid()) return; - - drawBitmap(VRect(point, bitmap.size()), - bitmap, source, const_alpha); -} - -void VPainter::drawBitmap(const VRect &target, const VBitmap &bitmap, - const VRect &source, uint8_t const_alpha) -{ - if (!bitmap.valid()) return; - - // clear any existing brush data. - setBrush(VBrush()); - - if (target.size() == source.size()) { - drawBitmapUntransform(target, bitmap, source, const_alpha); - } else { - // @TODO scaling - } -} - -void VPainter::drawBitmap(const VPoint &point, const VBitmap &bitmap, - uint8_t const_alpha) -{ - if (!bitmap.valid()) return; - - drawBitmap(VRect(point, bitmap.size()), - bitmap, bitmap.rect(), - const_alpha); -} - -void VPainter::drawBitmap(const VRect &rect, const VBitmap &bitmap, - uint8_t const_alpha) -{ - if (!bitmap.valid()) return; - - drawBitmap(rect, bitmap, bitmap.rect(), - const_alpha); -} - -V_END_NAMESPACE diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vpainter.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vpainter.h deleted file mode 100644 index 68abd70f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vpainter.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VPAINTER_H -#define VPAINTER_H - -#include "vbrush.h" -#include "vpoint.h" -#include "vrle.h" -#include "vdrawhelper.h" - -V_BEGIN_NAMESPACE - -class VBitmap; -class VPainter { -public: - VPainter() = default; - explicit VPainter(VBitmap *buffer); - bool begin(VBitmap *buffer); - void end(); - void setDrawRegion(const VRect ®ion); // sub surface rendering area. - void setBrush(const VBrush &brush); - void setBlendMode(BlendMode mode); - void drawRle(const VPoint &pos, const VRle &rle); - void drawRle(const VRle &rle, const VRle &clip); - VRect clipBoundingRect() const; - - void drawBitmap(const VPoint &point, const VBitmap &bitmap, const VRect &source, uint8_t const_alpha = 255); - void drawBitmap(const VRect &target, const VBitmap &bitmap, const VRect &source, uint8_t const_alpha = 255); - void drawBitmap(const VPoint &point, const VBitmap &bitmap, uint8_t const_alpha = 255); - void drawBitmap(const VRect &rect, const VBitmap &bitmap, uint8_t const_alpha = 255); -private: - void drawBitmapUntransform(const VRect &target, const VBitmap &bitmap, - const VRect &source, uint8_t const_alpha); - VRasterBuffer mBuffer; - VSpanData mSpanData; -}; - -V_END_NAMESPACE - -#endif // VPAINTER_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vpath.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vpath.cpp deleted file mode 100644 index d49cd009..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vpath.cpp +++ /dev/null @@ -1,709 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "vpath.h" -#include -#include -#include -#include "vbezier.h" -#include "vdebug.h" -#include "vline.h" -#include "vrect.h" - -V_BEGIN_NAMESPACE - -void VPath::VPathData::transform(const VMatrix &m) -{ - for (auto &i : m_points) { - i = m.map(i); - } - mLengthDirty = true; -} - -float VPath::VPathData::length() const -{ - if (!mLengthDirty) return mLength; - - mLengthDirty = false; - mLength = 0.0; - - size_t i = 0; - for (auto e : m_elements) { - switch (e) { - case VPath::Element::MoveTo: - i++; - break; - case VPath::Element::LineTo: { - mLength += VLine(m_points[i - 1], m_points[i]).length(); - i++; - break; - } - case VPath::Element::CubicTo: { - mLength += VBezier::fromPoints(m_points[i - 1], m_points[i], - m_points[i + 1], m_points[i + 2]) - .length(); - i += 3; - break; - } - case VPath::Element::Close: - break; - } - } - - return mLength; -} - -void VPath::VPathData::checkNewSegment() -{ - if (mNewSegment) { - moveTo(0, 0); - mNewSegment = false; - } -} - -void VPath::VPathData::moveTo(float x, float y) -{ - mStartPoint = {x, y}; - mNewSegment = false; - m_elements.emplace_back(VPath::Element::MoveTo); - m_points.emplace_back(x, y); - m_segments++; - mLengthDirty = true; -} - -void VPath::VPathData::lineTo(float x, float y) -{ - checkNewSegment(); - m_elements.emplace_back(VPath::Element::LineTo); - m_points.emplace_back(x, y); - mLengthDirty = true; -} - -void VPath::VPathData::cubicTo(float cx1, float cy1, float cx2, float cy2, - float ex, float ey) -{ - checkNewSegment(); - m_elements.emplace_back(VPath::Element::CubicTo); - m_points.emplace_back(cx1, cy1); - m_points.emplace_back(cx2, cy2); - m_points.emplace_back(ex, ey); - mLengthDirty = true; -} - -void VPath::VPathData::close() -{ - if (empty()) return; - - const VPointF &lastPt = m_points.back(); - if (!fuzzyCompare(mStartPoint, lastPt)) { - lineTo(mStartPoint.x(), mStartPoint.y()); - } - m_elements.push_back(VPath::Element::Close); - mNewSegment = true; - mLengthDirty = true; -} - -void VPath::VPathData::reset() -{ - if (empty()) return; - - m_elements.clear(); - m_points.clear(); - m_segments = 0; - mLength = 0; - mLengthDirty = false; -} - -size_t VPath::VPathData::segments() const -{ - return m_segments; -} - -void VPath::VPathData::reserve(size_t pts, size_t elms) -{ - if (m_points.capacity() < m_points.size() + pts) - m_points.reserve(m_points.size() + pts); - if (m_elements.capacity() < m_elements.size() + elms) - m_elements.reserve(m_elements.size() + elms); -} - -static VPointF curvesForArc(const VRectF &, float, float, VPointF *, size_t *); -static constexpr float PATH_KAPPA = 0.5522847498f; -static constexpr float K_PI = 3.141592f; - -void VPath::VPathData::arcTo(const VRectF &rect, float startAngle, - float sweepLength, bool forceMoveTo) -{ - size_t point_count = 0; - VPointF pts[15]; - VPointF curve_start = - curvesForArc(rect, startAngle, sweepLength, pts, &point_count); - - reserve(point_count + 1, point_count / 3 + 1); - if (empty() || forceMoveTo) { - moveTo(curve_start.x(), curve_start.y()); - } else { - lineTo(curve_start.x(), curve_start.y()); - } - for (size_t i = 0; i < point_count; i += 3) { - cubicTo(pts[i].x(), pts[i].y(), pts[i + 1].x(), pts[i + 1].y(), - pts[i + 2].x(), pts[i + 2].y()); - } -} - -void VPath::VPathData::addCircle(float cx, float cy, float radius, - VPath::Direction dir) -{ - addOval(VRectF(cx - radius, cy - radius, 2 * radius, 2 * radius), dir); -} - -void VPath::VPathData::addOval(const VRectF &rect, VPath::Direction dir) -{ - if (rect.empty()) return; - - float x = rect.x(); - float y = rect.y(); - - float w = rect.width(); - float w2 = rect.width() / 2; - float w2k = w2 * PATH_KAPPA; - - float h = rect.height(); - float h2 = rect.height() / 2; - float h2k = h2 * PATH_KAPPA; - - reserve(13, 6); // 1Move + 4Cubic + 1Close - if (dir == VPath::Direction::CW) { - // moveto 12 o'clock. - moveTo(x + w2, y); - // 12 -> 3 o'clock - cubicTo(x + w2 + w2k, y, x + w, y + h2 - h2k, x + w, y + h2); - // 3 -> 6 o'clock - cubicTo(x + w, y + h2 + h2k, x + w2 + w2k, y + h, x + w2, y + h); - // 6 -> 9 o'clock - cubicTo(x + w2 - w2k, y + h, x, y + h2 + h2k, x, y + h2); - // 9 -> 12 o'clock - cubicTo(x, y + h2 - h2k, x + w2 - w2k, y, x + w2, y); - } else { - // moveto 12 o'clock. - moveTo(x + w2, y); - // 12 -> 9 o'clock - cubicTo(x + w2 - w2k, y, x, y + h2 - h2k, x, y + h2); - // 9 -> 6 o'clock - cubicTo(x, y + h2 + h2k, x + w2 - w2k, y + h, x + w2, y + h); - // 6 -> 3 o'clock - cubicTo(x + w2 + w2k, y + h, x + w, y + h2 + h2k, x + w, y + h2); - // 3 -> 12 o'clock - cubicTo(x + w, y + h2 - h2k, x + w2 + w2k, y, x + w2, y); - } - close(); -} - -void VPath::VPathData::addRect(const VRectF &rect, VPath::Direction dir) -{ - float x = rect.x(); - float y = rect.y(); - float w = rect.width(); - float h = rect.height(); - - if (vCompare(w, 0.f) && vCompare(h, 0.f)) return; - - reserve(5, 6); // 1Move + 4Line + 1Close - if (dir == VPath::Direction::CW) { - moveTo(x + w, y); - lineTo(x + w, y + h); - lineTo(x, y + h); - lineTo(x, y); - close(); - } else { - moveTo(x + w, y); - lineTo(x, y); - lineTo(x, y + h); - lineTo(x + w, y + h); - close(); - } -} - -void VPath::VPathData::addRoundRect(const VRectF &rect, float roundness, - VPath::Direction dir) -{ - if (2 * roundness > rect.width()) roundness = rect.width() / 2.0f; - if (2 * roundness > rect.height()) roundness = rect.height() / 2.0f; - addRoundRect(rect, roundness, roundness, dir); -} - -void VPath::VPathData::addRoundRect(const VRectF &rect, float rx, float ry, - VPath::Direction dir) -{ - if (vCompare(rx, 0.f) || vCompare(ry, 0.f)) { - addRect(rect, dir); - return; - } - - float x = rect.x(); - float y = rect.y(); - float w = rect.width(); - float h = rect.height(); - // clamp the rx and ry radius value. - rx = 2 * rx; - ry = 2 * ry; - if (rx > w) rx = w; - if (ry > h) ry = h; - - reserve(17, 10); // 1Move + 4Cubic + 1Close - if (dir == VPath::Direction::CW) { - moveTo(x + w, y + ry / 2.f); - arcTo(VRectF(x + w - rx, y + h - ry, rx, ry), 0, -90, false); - arcTo(VRectF(x, y + h - ry, rx, ry), -90, -90, false); - arcTo(VRectF(x, y, rx, ry), -180, -90, false); - arcTo(VRectF(x + w - rx, y, rx, ry), -270, -90, false); - close(); - } else { - moveTo(x + w, y + ry / 2.f); - arcTo(VRectF(x + w - rx, y, rx, ry), 0, 90, false); - arcTo(VRectF(x, y, rx, ry), 90, 90, false); - arcTo(VRectF(x, y + h - ry, rx, ry), 180, 90, false); - arcTo(VRectF(x + w - rx, y + h - ry, rx, ry), 270, 90, false); - close(); - } -} - -static float tForArcAngle(float angle); -void findEllipseCoords(const VRectF &r, float angle, float length, - VPointF *startPoint, VPointF *endPoint) -{ - if (r.empty()) { - if (startPoint) *startPoint = VPointF(); - if (endPoint) *endPoint = VPointF(); - return; - } - - float w2 = r.width() / 2; - float h2 = r.height() / 2; - - float angles[2] = {angle, angle + length}; - VPointF *points[2] = {startPoint, endPoint}; - - for (int i = 0; i < 2; ++i) { - if (!points[i]) continue; - - float theta = angles[i] - 360 * floorf(angles[i] / 360); - float t = theta / 90; - // truncate - int quadrant = int(t); - t -= quadrant; - - t = tForArcAngle(90 * t); - - // swap x and y? - if (quadrant & 1) t = 1 - t; - - float a, b, c, d; - VBezier::coefficients(t, a, b, c, d); - VPointF p(a + b + c * PATH_KAPPA, d + c + b * PATH_KAPPA); - - // left quadrants - if (quadrant == 1 || quadrant == 2) p.rx() = -p.x(); - - // top quadrants - if (quadrant == 0 || quadrant == 1) p.ry() = -p.y(); - - *points[i] = r.center() + VPointF(w2 * p.x(), h2 * p.y()); - } -} - -static float tForArcAngle(float angle) -{ - float radians, cos_angle, sin_angle, tc, ts, t; - - if (vCompare(angle, 0.f)) return 0; - if (vCompare(angle, 90.0f)) return 1; - - radians = (angle / 180) * K_PI; - - cos_angle = cosf(radians); - sin_angle = sinf(radians); - - // initial guess - tc = angle / 90; - - // do some iterations of newton's method to approximate cos_angle - // finds the zero of the function b.pointAt(tc).x() - cos_angle - tc -= ((((2 - 3 * PATH_KAPPA) * tc + 3 * (PATH_KAPPA - 1)) * tc) * tc + 1 - - cos_angle) // value - / (((6 - 9 * PATH_KAPPA) * tc + 6 * (PATH_KAPPA - 1)) * - tc); // derivative - tc -= ((((2 - 3 * PATH_KAPPA) * tc + 3 * (PATH_KAPPA - 1)) * tc) * tc + 1 - - cos_angle) // value - / (((6 - 9 * PATH_KAPPA) * tc + 6 * (PATH_KAPPA - 1)) * - tc); // derivative - - // initial guess - ts = tc; - // do some iterations of newton's method to approximate sin_angle - // finds the zero of the function b.pointAt(tc).y() - sin_angle - ts -= ((((3 * PATH_KAPPA - 2) * ts - 6 * PATH_KAPPA + 3) * ts + - 3 * PATH_KAPPA) * - ts - - sin_angle) / - (((9 * PATH_KAPPA - 6) * ts + 12 * PATH_KAPPA - 6) * ts + - 3 * PATH_KAPPA); - ts -= ((((3 * PATH_KAPPA - 2) * ts - 6 * PATH_KAPPA + 3) * ts + - 3 * PATH_KAPPA) * - ts - - sin_angle) / - (((9 * PATH_KAPPA - 6) * ts + 12 * PATH_KAPPA - 6) * ts + - 3 * PATH_KAPPA); - - // use the average of the t that best approximates cos_angle - // and the t that best approximates sin_angle - t = 0.5f * (tc + ts); - return t; -} - -// The return value is the starting point of the arc -static VPointF curvesForArc(const VRectF &rect, float startAngle, - float sweepLength, VPointF *curves, - size_t *point_count) -{ - if (rect.empty()) { - return {}; - } - - float x = rect.x(); - float y = rect.y(); - - float w = rect.width(); - float w2 = rect.width() / 2; - float w2k = w2 * PATH_KAPPA; - - float h = rect.height(); - float h2 = rect.height() / 2; - float h2k = h2 * PATH_KAPPA; - - VPointF points[16] = { - // start point - VPointF(x + w, y + h2), - - // 0 -> 270 degrees - VPointF(x + w, y + h2 + h2k), VPointF(x + w2 + w2k, y + h), - VPointF(x + w2, y + h), - - // 270 -> 180 degrees - VPointF(x + w2 - w2k, y + h), VPointF(x, y + h2 + h2k), - VPointF(x, y + h2), - - // 180 -> 90 degrees - VPointF(x, y + h2 - h2k), VPointF(x + w2 - w2k, y), VPointF(x + w2, y), - - // 90 -> 0 degrees - VPointF(x + w2 + w2k, y), VPointF(x + w, y + h2 - h2k), - VPointF(x + w, y + h2)}; - - if (sweepLength > 360) - sweepLength = 360; - else if (sweepLength < -360) - sweepLength = -360; - - // Special case fast paths - if (startAngle == 0.0f) { - if (vCompare(sweepLength, 360)) { - for (int i = 11; i >= 0; --i) curves[(*point_count)++] = points[i]; - return points[12]; - } else if (vCompare(sweepLength, -360)) { - for (int i = 1; i <= 12; ++i) curves[(*point_count)++] = points[i]; - return points[0]; - } - } - - int startSegment = int(floorf(startAngle / 90.0f)); - int endSegment = int(floorf((startAngle + sweepLength) / 90.0f)); - - float startT = (startAngle - startSegment * 90) / 90; - float endT = (startAngle + sweepLength - endSegment * 90) / 90; - - int delta = sweepLength > 0 ? 1 : -1; - if (delta < 0) { - startT = 1 - startT; - endT = 1 - endT; - } - - // avoid empty start segment - if (vIsZero(startT - float(1))) { - startT = 0; - startSegment += delta; - } - - // avoid empty end segment - if (vIsZero(endT)) { - endT = 1; - endSegment -= delta; - } - - startT = tForArcAngle(startT * 90); - endT = tForArcAngle(endT * 90); - - const bool splitAtStart = !vIsZero(startT); - const bool splitAtEnd = !vIsZero(endT - float(1)); - - const int end = endSegment + delta; - - // empty arc? - if (startSegment == end) { - const int quadrant = 3 - ((startSegment % 4) + 4) % 4; - const int j = 3 * quadrant; - return delta > 0 ? points[j + 3] : points[j]; - } - - VPointF startPoint, endPoint; - findEllipseCoords(rect, startAngle, sweepLength, &startPoint, &endPoint); - - for (int i = startSegment; i != end; i += delta) { - const int quadrant = 3 - ((i % 4) + 4) % 4; - const int j = 3 * quadrant; - - VBezier b; - if (delta > 0) - b = VBezier::fromPoints(points[j + 3], points[j + 2], points[j + 1], - points[j]); - else - b = VBezier::fromPoints(points[j], points[j + 1], points[j + 2], - points[j + 3]); - - // empty arc? - if (startSegment == endSegment && vCompare(startT, endT)) - return startPoint; - - if (i == startSegment) { - if (i == endSegment && splitAtEnd) - b = b.onInterval(startT, endT); - else if (splitAtStart) - b = b.onInterval(startT, 1); - } else if (i == endSegment && splitAtEnd) { - b = b.onInterval(0, endT); - } - - // push control points - curves[(*point_count)++] = b.pt2(); - curves[(*point_count)++] = b.pt3(); - curves[(*point_count)++] = b.pt4(); - } - - curves[*(point_count)-1] = endPoint; - - return startPoint; -} - -void VPath::VPathData::addPolystar(float points, float innerRadius, - float outerRadius, float innerRoundness, - float outerRoundness, float startAngle, - float cx, float cy, VPath::Direction dir) -{ - const static float POLYSTAR_MAGIC_NUMBER = 0.47829f / 0.28f; - float currentAngle = (startAngle - 90.0f) * K_PI / 180.0f; - float x; - float y; - float partialPointRadius = 0; - float anglePerPoint = (2.0f * K_PI / points); - float halfAnglePerPoint = anglePerPoint / 2.0f; - float partialPointAmount = points - floorf(points); - bool longSegment = false; - size_t numPoints = size_t(ceilf(points) * 2); - float angleDir = ((dir == VPath::Direction::CW) ? 1.0f : -1.0f); - bool hasRoundness = false; - - innerRoundness /= 100.0f; - outerRoundness /= 100.0f; - - if (!vCompare(partialPointAmount, 0)) { - currentAngle += - halfAnglePerPoint * (1.0f - partialPointAmount) * angleDir; - } - - if (!vCompare(partialPointAmount, 0)) { - partialPointRadius = - innerRadius + partialPointAmount * (outerRadius - innerRadius); - x = partialPointRadius * cosf(currentAngle); - y = partialPointRadius * sinf(currentAngle); - currentAngle += anglePerPoint * partialPointAmount / 2.0f * angleDir; - } else { - x = outerRadius * cosf(currentAngle); - y = outerRadius * sinf(currentAngle); - currentAngle += halfAnglePerPoint * angleDir; - } - - if (vIsZero(innerRoundness) && vIsZero(outerRoundness)) { - reserve(numPoints + 2, numPoints + 3); - } else { - reserve(numPoints * 3 + 2, numPoints + 3); - hasRoundness = true; - } - - moveTo(x + cx, y + cy); - - for (size_t i = 0; i < numPoints; i++) { - float radius = longSegment ? outerRadius : innerRadius; - float dTheta = halfAnglePerPoint; - if (!vIsZero(partialPointRadius) && i == numPoints - 2) { - dTheta = anglePerPoint * partialPointAmount / 2.0f; - } - if (!vIsZero(partialPointRadius) && i == numPoints - 1) { - radius = partialPointRadius; - } - float previousX = x; - float previousY = y; - x = radius * cosf(currentAngle); - y = radius * sinf(currentAngle); - - if (hasRoundness) { - float cp1Theta = - (atan2f(previousY, previousX) - K_PI / 2.0f * angleDir); - float cp1Dx = cosf(cp1Theta); - float cp1Dy = sinf(cp1Theta); - float cp2Theta = (atan2f(y, x) - K_PI / 2.0f * angleDir); - float cp2Dx = cosf(cp2Theta); - float cp2Dy = sinf(cp2Theta); - - float cp1Roundness = longSegment ? innerRoundness : outerRoundness; - float cp2Roundness = longSegment ? outerRoundness : innerRoundness; - float cp1Radius = longSegment ? innerRadius : outerRadius; - float cp2Radius = longSegment ? outerRadius : innerRadius; - - float cp1x = cp1Radius * cp1Roundness * POLYSTAR_MAGIC_NUMBER * - cp1Dx / points; - float cp1y = cp1Radius * cp1Roundness * POLYSTAR_MAGIC_NUMBER * - cp1Dy / points; - float cp2x = cp2Radius * cp2Roundness * POLYSTAR_MAGIC_NUMBER * - cp2Dx / points; - float cp2y = cp2Radius * cp2Roundness * POLYSTAR_MAGIC_NUMBER * - cp2Dy / points; - - if (!vIsZero(partialPointAmount) && - ((i == 0) || (i == numPoints - 1))) { - cp1x *= partialPointAmount; - cp1y *= partialPointAmount; - cp2x *= partialPointAmount; - cp2y *= partialPointAmount; - } - - cubicTo(previousX - cp1x + cx, previousY - cp1y + cy, x + cp2x + cx, - y + cp2y + cy, x + cx, y + cy); - } else { - lineTo(x + cx, y + cy); - } - - currentAngle += dTheta * angleDir; - longSegment = !longSegment; - } - - close(); -} - -void VPath::VPathData::addPolygon(float points, float radius, float roundness, - float startAngle, float cx, float cy, - VPath::Direction dir) -{ - // TODO: Need to support floating point number for number of points - const static float POLYGON_MAGIC_NUMBER = 0.25; - float currentAngle = (startAngle - 90.0f) * K_PI / 180.0f; - float x; - float y; - float anglePerPoint = 2.0f * K_PI / floorf(points); - size_t numPoints = size_t(floorf(points)); - float angleDir = ((dir == VPath::Direction::CW) ? 1.0f : -1.0f); - bool hasRoundness = false; - - roundness /= 100.0f; - - currentAngle = (currentAngle - 90.0f) * K_PI / 180.0f; - x = radius * cosf(currentAngle); - y = radius * sinf(currentAngle); - currentAngle += anglePerPoint * angleDir; - - if (vIsZero(roundness)) { - reserve(numPoints + 2, numPoints + 3); - } else { - reserve(numPoints * 3 + 2, numPoints + 3); - hasRoundness = true; - } - - moveTo(x + cx, y + cy); - - for (size_t i = 0; i < numPoints; i++) { - float previousX = x; - float previousY = y; - x = (radius * cosf(currentAngle)); - y = (radius * sinf(currentAngle)); - - if (hasRoundness) { - float cp1Theta = - (atan2f(previousY, previousX) - K_PI / 2.0f * angleDir); - float cp1Dx = cosf(cp1Theta); - float cp1Dy = sinf(cp1Theta); - float cp2Theta = atan2f(y, x) - K_PI / 2.0f * angleDir; - float cp2Dx = cosf(cp2Theta); - float cp2Dy = sinf(cp2Theta); - - float cp1x = radius * roundness * POLYGON_MAGIC_NUMBER * cp1Dx; - float cp1y = radius * roundness * POLYGON_MAGIC_NUMBER * cp1Dy; - float cp2x = radius * roundness * POLYGON_MAGIC_NUMBER * cp2Dx; - float cp2y = radius * roundness * POLYGON_MAGIC_NUMBER * cp2Dy; - - cubicTo(previousX - cp1x + cx, previousY - cp1y + cy, x + cp2x + cx, - y + cp2y + cy, x, y); - } else { - lineTo(x + cx, y + cy); - } - - currentAngle += anglePerPoint * angleDir; - } - - close(); -} - -void VPath::VPathData::addPath(const VPathData &path, const VMatrix *m) -{ - size_t segment = path.segments(); - - // make sure enough memory available - if (m_points.capacity() < m_points.size() + path.m_points.size()) - m_points.reserve(m_points.size() + path.m_points.size()); - - if (m_elements.capacity() < m_elements.size() + path.m_elements.size()) - m_elements.reserve(m_elements.size() + path.m_elements.size()); - - if (m) { - for (const auto &i : path.m_points) { - m_points.push_back(m->map(i)); - } - } else { - std::copy(path.m_points.begin(), path.m_points.end(), - back_inserter(m_points)); - } - - std::copy(path.m_elements.begin(), path.m_elements.end(), - back_inserter(m_elements)); - - m_segments += segment; - mLengthDirty = true; -} - -V_END_NAMESPACE diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vpath.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vpath.h deleted file mode 100644 index 9273cb61..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vpath.h +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VPATH_H -#define VPATH_H -#include -#include "vcowptr.h" -#include "vmatrix.h" -#include "vpoint.h" -#include "vrect.h" - -V_BEGIN_NAMESPACE - -struct VPathData; -class VPath { -public: - enum class Direction { CCW, CW }; - - enum class Element : uint8_t { MoveTo, LineTo, CubicTo, Close }; - bool empty() const; - bool null() const; - void moveTo(const VPointF &p); - void moveTo(float x, float y); - void lineTo(const VPointF &p); - void lineTo(float x, float y); - void cubicTo(const VPointF &c1, const VPointF &c2, const VPointF &e); - void cubicTo(float c1x, float c1y, float c2x, float c2y, float ex, - float ey); - void arcTo(const VRectF &rect, float startAngle, float sweepLength, - bool forceMoveTo); - void close(); - void reset(); - void reserve(size_t pts, size_t elms); - size_t segments() const; - void addCircle(float cx, float cy, float radius, - VPath::Direction dir = Direction::CW); - void addOval(const VRectF &rect, VPath::Direction dir = Direction::CW); - void addRoundRect(const VRectF &rect, float rx, float ry, - VPath::Direction dir = Direction::CW); - void addRoundRect(const VRectF &rect, float roundness, - VPath::Direction dir = Direction::CW); - void addRect(const VRectF &rect, VPath::Direction dir = Direction::CW); - void addPolystar(float points, float innerRadius, float outerRadius, - float innerRoundness, float outerRoundness, - float startAngle, float cx, float cy, - VPath::Direction dir = Direction::CW); - void addPolygon(float points, float radius, float roundness, - float startAngle, float cx, float cy, - VPath::Direction dir = Direction::CW); - void addPath(const VPath &path); - void addPath(const VPath &path, const VMatrix &m); - void transform(const VMatrix &m); - float length() const; - const std::vector &elements() const; - const std::vector & points() const; - void clone(const VPath &srcPath); - bool unique() const { return d.unique();} - size_t refCount() const { return d.refCount();} - -private: - struct VPathData { - bool empty() const { return m_elements.empty(); } - bool null() const { return empty() && !m_elements.capacity();} - void moveTo(float x, float y); - void lineTo(float x, float y); - void cubicTo(float cx1, float cy1, float cx2, float cy2, float ex, float ey); - void close(); - void reset(); - void reserve(size_t, size_t); - void checkNewSegment(); - size_t segments() const; - void transform(const VMatrix &m); - float length() const; - void addRoundRect(const VRectF &, float, float, VPath::Direction); - void addRoundRect(const VRectF &, float, VPath::Direction); - void addRect(const VRectF &, VPath::Direction); - void arcTo(const VRectF &, float, float, bool); - void addCircle(float, float, float, VPath::Direction); - void addOval(const VRectF &, VPath::Direction); - void addPolystar(float points, float innerRadius, float outerRadius, - float innerRoundness, float outerRoundness, - float startAngle, float cx, float cy, - VPath::Direction dir = Direction::CW); - void addPolygon(float points, float radius, float roundness, - float startAngle, float cx, float cy, - VPath::Direction dir = Direction::CW); - void addPath(const VPathData &path, const VMatrix *m = nullptr); - void clone(const VPath::VPathData &o) { *this = o;} - const std::vector &elements() const - { - return m_elements; - } - const std::vector &points() const { return m_points; } - std::vector m_points; - std::vector m_elements; - size_t m_segments; - VPointF mStartPoint; - mutable float mLength{0}; - mutable bool mLengthDirty{true}; - bool mNewSegment; - }; - - vcow_ptr d; -}; - -inline bool VPath::empty() const -{ - return d->empty(); -} - -/* - * path is empty as well as null(no memory for data allocated yet). - */ -inline bool VPath::null() const -{ - return d->null(); -} - -inline void VPath::moveTo(const VPointF &p) -{ - d.write().moveTo(p.x(), p.y()); -} - -inline void VPath::lineTo(const VPointF &p) -{ - d.write().lineTo(p.x(), p.y()); -} - -inline void VPath::close() -{ - d.write().close(); -} - -inline void VPath::reset() -{ - d.write().reset(); -} - -inline void VPath::reserve(size_t pts, size_t elms) -{ - d.write().reserve(pts, elms); -} - -inline size_t VPath::segments() const -{ - return d->segments(); -} - -inline float VPath::length() const -{ - return d->length(); -} - -inline void VPath::cubicTo(const VPointF &c1, const VPointF &c2, - const VPointF &e) -{ - d.write().cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y()); -} - -inline void VPath::lineTo(float x, float y) -{ - d.write().lineTo(x, y); -} - -inline void VPath::moveTo(float x, float y) -{ - d.write().moveTo(x, y); -} - -inline void VPath::cubicTo(float c1x, float c1y, float c2x, float c2y, float ex, - float ey) -{ - d.write().cubicTo(c1x, c1y, c2x, c2y, ex, ey); -} - -inline void VPath::transform(const VMatrix &m) -{ - d.write().transform(m); -} - -inline void VPath::arcTo(const VRectF &rect, float startAngle, - float sweepLength, bool forceMoveTo) -{ - d.write().arcTo(rect, startAngle, sweepLength, forceMoveTo); -} - -inline void VPath::addRect(const VRectF &rect, VPath::Direction dir) -{ - d.write().addRect(rect, dir); -} - -inline void VPath::addRoundRect(const VRectF &rect, float rx, float ry, - VPath::Direction dir) -{ - d.write().addRoundRect(rect, rx, ry, dir); -} - -inline void VPath::addRoundRect(const VRectF &rect, float roundness, - VPath::Direction dir) -{ - d.write().addRoundRect(rect, roundness, dir); -} - -inline void VPath::addCircle(float cx, float cy, float radius, - VPath::Direction dir) -{ - d.write().addCircle(cx, cy, radius, dir); -} - -inline void VPath::addOval(const VRectF &rect, VPath::Direction dir) -{ - d.write().addOval(rect, dir); -} - -inline void VPath::addPolystar(float points, float innerRadius, - float outerRadius, float innerRoundness, - float outerRoundness, float startAngle, float cx, - float cy, VPath::Direction dir) -{ - d.write().addPolystar(points, innerRadius, outerRadius, innerRoundness, - outerRoundness, startAngle, cx, cy, dir); -} - -inline void VPath::addPolygon(float points, float radius, float roundness, - float startAngle, float cx, float cy, - VPath::Direction dir) -{ - d.write().addPolygon(points, radius, roundness, startAngle, cx, cy, dir); -} - -inline void VPath::addPath(const VPath &path) -{ - if (path.empty()) return; - - if (null()) { - *this = path; - } else { - d.write().addPath(path.d.read()); - } -} - -inline void VPath::addPath(const VPath &path, const VMatrix &m) -{ - if (path.empty()) return; - - d.write().addPath(path.d.read(), &m); -} - -inline const std::vector &VPath::elements() const -{ - return d->elements(); -} - -inline const std::vector &VPath::points() const -{ - return d->points(); -} - -inline void VPath::clone(const VPath &o) -{ - d.write().clone(o.d.read()); -} - -V_END_NAMESPACE - -#endif // VPATH_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vpathmesure.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vpathmesure.cpp deleted file mode 100644 index 5d44987c..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vpathmesure.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "vpathmesure.h" -#include -#include "vbezier.h" -#include "vdasher.h" - -V_BEGIN_NAMESPACE - -/* - * start and end value must be normalized to [0 - 1] - * Path mesure trims the path from [start --> end] - * if start > end it treates as a loop and trims as two segment - * [0-->end] and [start --> 1] - */ -VPath VPathMesure::trim(const VPath &path) -{ - if (vCompare(mStart, mEnd)) return VPath(); - - if ((vCompare(mStart, 0.0f) && (vCompare(mEnd, 1.0f))) || - (vCompare(mStart, 1.0f) && (vCompare(mEnd, 0.0f)))) - return path; - - float length = path.length(); - - if (mStart < mEnd) { - float array[4] = { - 0.0f, length * mStart, // 1st segment - (mEnd - mStart) * length, - std::numeric_limits::max(), // 2nd segment - }; - VDasher dasher(array, 4); - dasher.dashed(path, mScratchObject); - return mScratchObject; - } else { - float array[4] = { - length * mEnd, (mStart - mEnd) * length, // 1st segment - (1 - mStart) * length, - std::numeric_limits::max(), // 2nd segment - }; - VDasher dasher(array, 4); - dasher.dashed(path, mScratchObject); - return mScratchObject; - } -} - -V_END_NAMESPACE diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vpathmesure.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vpathmesure.h deleted file mode 100644 index 2a4adb97..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vpathmesure.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VPATHMESURE_H -#define VPATHMESURE_H - -#include "vpath.h" - -V_BEGIN_NAMESPACE - -class VPathMesure { -public: - void setRange(float start, float end) {mStart = start; mEnd = end;} - void setStart(float start){mStart = start;} - void setEnd(float end){mEnd = end;} - VPath trim(const VPath &path); -private: - float mStart{0.0f}; - float mEnd{1.0f}; - VPath mScratchObject; -}; - -V_END_NAMESPACE - -#endif // VPATHMESURE_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vpoint.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vpoint.h deleted file mode 100644 index da1bb2f5..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vpoint.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef VPOINT_H -#define VPOINT_H - -#include "vglobal.h" - -V_BEGIN_NAMESPACE - -class VPointF { -public: - VPointF() = default; - constexpr inline VPointF(float x, float y) noexcept : mx(x), my(y) {} - constexpr inline float x() const noexcept { return mx; } - constexpr inline float y() const noexcept { return my; } - inline float & rx() noexcept { return mx; } - inline float & ry() noexcept { return my; } - inline void setX(float x) { mx = x; } - inline void setY(float y) { my = y; } - inline VPointF operator-() noexcept { return {-mx, -my}; } - inline VPointF & operator+=(const VPointF &p) noexcept; - inline VPointF & operator-=(const VPointF &p) noexcept; - friend const VPointF operator+(const VPointF &p1, const VPointF &p2) - { - return VPointF(p1.mx + p2.mx, p1.my + p2.my); - } - inline friend bool fuzzyCompare(const VPointF &p1, const VPointF &p2); - inline friend VDebug & operator<<(VDebug &os, const VPointF &o); - - friend inline VPointF operator-(const VPointF &p1, const VPointF &p2); - friend inline const VPointF operator*(const VPointF &, float); - friend inline const VPointF operator*(float, const VPointF &); - friend inline const VPointF operator/(const VPointF &, float); - friend inline const VPointF operator/(float, const VPointF &); - -private: - float mx{0}; - float my{0}; -}; - -inline bool fuzzyCompare(const VPointF &p1, const VPointF &p2) -{ - return (vCompare(p1.mx, p2.mx) && vCompare(p1.my, p2.my)); -} - -inline VPointF operator-(const VPointF &p1, const VPointF &p2) -{ - return {p1.mx - p2.mx, p1.my - p2.my}; -} - -inline const VPointF operator*(const VPointF &p, float c) -{ - return VPointF(p.mx * c, p.my * c); -} - -inline const VPointF operator*(float c, const VPointF &p) -{ - return VPointF(p.mx * c, p.my * c); -} - -inline const VPointF operator/(const VPointF &p, float c) -{ - return VPointF(p.mx / c, p.my / c); -} - -inline const VPointF operator/(float c, const VPointF &p) -{ - return VPointF(p.mx / c, p.my / c); -} - -inline VDebug &operator<<(VDebug &os, const VPointF &o) -{ - os << "{P " << o.x() << "," << o.y() << "}"; - return os; -} - -inline VPointF &VPointF::operator+=(const VPointF &p) noexcept -{ - mx += p.mx; - my += p.my; - return *this; -} - -inline VPointF &VPointF::operator-=(const VPointF &p) noexcept -{ - mx -= p.mx; - my -= p.my; - return *this; -} - -class VPoint { -public: - VPoint() = default; - constexpr inline VPoint(int x, int y) noexcept : mx(x), my(y) {} - constexpr inline int x() const noexcept { return mx; } - constexpr inline int y() const noexcept { return my; } - inline void setX(int x) { mx = x; } - inline void setY(int y) { my = y; } - inline VPoint & operator+=(const VPoint &p) noexcept; - inline VPoint & operator-=(const VPoint &p) noexcept; - constexpr inline bool operator==(const VPoint &o) const; - constexpr inline bool operator!=(const VPoint &o) const - { - return !(operator==(o)); - } - friend inline VPoint operator-(const VPoint &p1, const VPoint &p2); - inline friend VDebug &operator<<(VDebug &os, const VPoint &o); - -private: - int mx{0}; - int my{0}; -}; -inline VDebug &operator<<(VDebug &os, const VPoint &o) -{ - os << "{P " << o.x() << "," << o.y() << "}"; - return os; -} - -inline VPoint operator-(const VPoint &p1, const VPoint &p2) -{ - return {p1.mx - p2.mx, p1.my - p2.my}; -} - -constexpr inline bool VPoint::operator==(const VPoint &o) const -{ - return (mx == o.x() && my == o.y()); -} - -inline VPoint &VPoint::operator+=(const VPoint &p) noexcept -{ - mx += p.mx; - my += p.my; - return *this; -} - -inline VPoint &VPoint::operator-=(const VPoint &p) noexcept -{ - mx -= p.mx; - my -= p.my; - return *this; -} - -class VSize { -public: - VSize() = default; - constexpr inline VSize(int w, int h) noexcept : mw(w), mh(h) {} - bool empty() const {return (mw <= 0 || mh <= 0);} - constexpr inline int width() const noexcept { return mw; } - constexpr inline int height() const noexcept { return mh; } - inline void setWidth(int w) { mw = w; } - inline void setHeight(int h) { mh = h; } - inline VSize & operator+=(const VSize &p) noexcept; - inline VSize & operator-=(const VSize &p) noexcept; - constexpr inline bool operator==(const VSize &o) const; - constexpr inline bool operator!=(const VSize &o) const - { - return !(operator==(o)); - } - inline friend VDebug &operator<<(VDebug &os, const VSize &o); - -private: - int mw{0}; - int mh{0}; -}; -inline VDebug &operator<<(VDebug &os, const VSize &o) -{ - os << "{P " << o.width() << "," << o.height() << "}"; - return os; -} -constexpr inline bool VSize::operator==(const VSize &o) const -{ - return (mw == o.width() && mh == o.height()); -} - -inline VSize &VSize::operator+=(const VSize &p) noexcept -{ - mw += p.mw; - mh += p.mh; - return *this; -} - -inline VSize &VSize::operator-=(const VSize &p) noexcept -{ - mw -= p.mw; - mh -= p.mh; - return *this; -} - -V_END_NAMESPACE - -#endif // VPOINT_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vraster.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vraster.cpp deleted file mode 100644 index 8ef7b571..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vraster.cpp +++ /dev/null @@ -1,597 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "vraster.h" -#include -#include -#include -#include "config.h" -#include "v_ft_raster.h" -#include "v_ft_stroker.h" -#include "vdebug.h" -#include "vmatrix.h" -#include "vpath.h" -#include "vrle.h" - -V_BEGIN_NAMESPACE - -template -class dyn_array { -public: - explicit dyn_array(size_t size) - : mCapacity(size), mData(std::make_unique(mCapacity)) - { - } - void reserve(size_t size) - { - if (mCapacity > size) return; - mCapacity = size; - mData = std::make_unique(mCapacity); - } - T * data() const { return mData.get(); } - dyn_array &operator=(dyn_array &&) noexcept = delete; - -private: - size_t mCapacity{0}; - std::unique_ptr mData{nullptr}; -}; - -struct FTOutline { -public: - void reset(); - void grow(size_t, size_t); - void convert(const VPath &path); - void convert(CapStyle, JoinStyle, float, float); - void moveTo(const VPointF &pt); - void lineTo(const VPointF &pt); - void cubicTo(const VPointF &ctr1, const VPointF &ctr2, const VPointF end); - void close(); - void end(); - void transform(const VMatrix &m); - SW_FT_Pos TO_FT_COORD(float x) - { - return SW_FT_Pos(x * 64); - } // to freetype 26.6 coordinate. - SW_FT_Outline ft; - bool closed{false}; - SW_FT_Stroker_LineCap ftCap; - SW_FT_Stroker_LineJoin ftJoin; - SW_FT_Fixed ftWidth; - SW_FT_Fixed ftMiterLimit; - dyn_array mPointMemory{100}; - dyn_array mTagMemory{100}; - dyn_array mContourMemory{10}; - dyn_array mContourFlagMemory{10}; -}; - -void FTOutline::reset() -{ - ft.n_points = ft.n_contours = 0; - ft.flags = 0x0; -} - -void FTOutline::grow(size_t points, size_t segments) -{ - reset(); - mPointMemory.reserve(points + segments); - mTagMemory.reserve(points + segments); - mContourMemory.reserve(segments); - mContourFlagMemory.reserve(segments); - - ft.points = mPointMemory.data(); - ft.tags = mTagMemory.data(); - ft.contours = mContourMemory.data(); - ft.contours_flag = mContourFlagMemory.data(); -} - -void FTOutline::convert(const VPath &path) -{ - const std::vector &elements = path.elements(); - const std::vector & points = path.points(); - - grow(points.size(), path.segments()); - - size_t index = 0; - for (auto element : elements) { - switch (element) { - case VPath::Element::MoveTo: - moveTo(points[index]); - index++; - break; - case VPath::Element::LineTo: - lineTo(points[index]); - index++; - break; - case VPath::Element::CubicTo: - cubicTo(points[index], points[index + 1], points[index + 2]); - index = index + 3; - break; - case VPath::Element::Close: - close(); - break; - } - } - end(); -} - -void FTOutline::convert(CapStyle cap, JoinStyle join, float width, - float miterLimit) -{ - // map strokeWidth to freetype. It uses as the radius of the pen not the - // diameter - width = width / 2.0f; - // convert to freetype co-ordinate - // IMP: stroker takes radius in 26.6 co-ordinate - ftWidth = SW_FT_Fixed(width * (1 << 6)); - // IMP: stroker takes meterlimit in 16.16 co-ordinate - ftMiterLimit = SW_FT_Fixed(miterLimit * (1 << 16)); - - // map to freetype capstyle - switch (cap) { - case CapStyle::Square: - ftCap = SW_FT_STROKER_LINECAP_SQUARE; - break; - case CapStyle::Round: - ftCap = SW_FT_STROKER_LINECAP_ROUND; - break; - default: - ftCap = SW_FT_STROKER_LINECAP_BUTT; - break; - } - switch (join) { - case JoinStyle::Bevel: - ftJoin = SW_FT_STROKER_LINEJOIN_BEVEL; - break; - case JoinStyle::Round: - ftJoin = SW_FT_STROKER_LINEJOIN_ROUND; - break; - default: - ftJoin = SW_FT_STROKER_LINEJOIN_MITER_FIXED; - break; - } -} - -void FTOutline::moveTo(const VPointF &pt) -{ - assert(ft.n_points <= SHRT_MAX - 1); - - ft.points[ft.n_points].x = TO_FT_COORD(pt.x()); - ft.points[ft.n_points].y = TO_FT_COORD(pt.y()); - ft.tags[ft.n_points] = SW_FT_CURVE_TAG_ON; - if (ft.n_points) { - ft.contours[ft.n_contours] = ft.n_points - 1; - ft.n_contours++; - } - // mark the current contour as open - // will be updated if ther is a close tag at the end. - ft.contours_flag[ft.n_contours] = 1; - - ft.n_points++; -} - -void FTOutline::lineTo(const VPointF &pt) -{ - assert(ft.n_points <= SHRT_MAX - 1); - - ft.points[ft.n_points].x = TO_FT_COORD(pt.x()); - ft.points[ft.n_points].y = TO_FT_COORD(pt.y()); - ft.tags[ft.n_points] = SW_FT_CURVE_TAG_ON; - ft.n_points++; -} - -void FTOutline::cubicTo(const VPointF &cp1, const VPointF &cp2, - const VPointF ep) -{ - assert(ft.n_points <= SHRT_MAX - 3); - - ft.points[ft.n_points].x = TO_FT_COORD(cp1.x()); - ft.points[ft.n_points].y = TO_FT_COORD(cp1.y()); - ft.tags[ft.n_points] = SW_FT_CURVE_TAG_CUBIC; - ft.n_points++; - - ft.points[ft.n_points].x = TO_FT_COORD(cp2.x()); - ft.points[ft.n_points].y = TO_FT_COORD(cp2.y()); - ft.tags[ft.n_points] = SW_FT_CURVE_TAG_CUBIC; - ft.n_points++; - - ft.points[ft.n_points].x = TO_FT_COORD(ep.x()); - ft.points[ft.n_points].y = TO_FT_COORD(ep.y()); - ft.tags[ft.n_points] = SW_FT_CURVE_TAG_ON; - ft.n_points++; -} -void FTOutline::close() -{ - assert(ft.n_points <= SHRT_MAX - 1); - - // mark the contour as a close path. - ft.contours_flag[ft.n_contours] = 0; - - int index; - if (ft.n_contours) { - index = ft.contours[ft.n_contours - 1] + 1; - } else { - index = 0; - } - - // make sure atleast 1 point exists in the segment. - if (ft.n_points == index) { - closed = false; - return; - } - - ft.points[ft.n_points].x = ft.points[index].x; - ft.points[ft.n_points].y = ft.points[index].y; - ft.tags[ft.n_points] = SW_FT_CURVE_TAG_ON; - ft.n_points++; -} - -void FTOutline::end() -{ - assert(ft.n_contours <= SHRT_MAX - 1); - - if (ft.n_points) { - ft.contours[ft.n_contours] = ft.n_points - 1; - ft.n_contours++; - } -} - -static void rleGenerationCb(int count, const SW_FT_Span *spans, void *user) -{ - VRle *rle = static_cast(user); - auto *rleSpan = reinterpret_cast(spans); - rle->addSpan(rleSpan, count); -} - -static void bboxCb(int x, int y, int w, int h, void *user) -{ - VRle *rle = static_cast(user); - rle->setBoundingRect({x, y, w, h}); -} - -class SharedRle { -public: - SharedRle() = default; - VRle &unsafe() { return _rle; } - void notify() - { - { - std::lock_guard lock(_mutex); - _ready = true; - } - _cv.notify_one(); - } - void wait() - { - if (!_pending) return; - - { - std::unique_lock lock(_mutex); - while (!_ready) _cv.wait(lock); - } - - _pending = false; - } - - VRle &get() - { - wait(); - return _rle; - } - - void reset() - { - wait(); - _ready = false; - _pending = true; - } - -private: - VRle _rle; - std::mutex _mutex; - std::condition_variable _cv; - bool _ready{true}; - bool _pending{false}; -}; - -struct VRleTask { - SharedRle mRle; - VPath mPath; - float mStrokeWidth; - float mMiterLimit; - VRect mClip; - FillRule mFillRule; - CapStyle mCap; - JoinStyle mJoin; - bool mGenerateStroke; - - VRle &rle() { return mRle.get(); } - - void update(VPath path, FillRule fillRule, const VRect &clip) - { - mRle.reset(); - mPath = std::move(path); - mFillRule = fillRule; - mClip = clip; - mGenerateStroke = false; - } - - void update(VPath path, CapStyle cap, JoinStyle join, float width, - float miterLimit, const VRect &clip) - { - mRle.reset(); - mPath = std::move(path); - mCap = cap; - mJoin = join; - mStrokeWidth = width; - mMiterLimit = miterLimit; - mClip = clip; - mGenerateStroke = true; - } - void render(FTOutline &outRef) - { - SW_FT_Raster_Params params; - - mRle.unsafe().reset(); - - params.flags = SW_FT_RASTER_FLAG_DIRECT | SW_FT_RASTER_FLAG_AA; - params.gray_spans = &rleGenerationCb; - params.bbox_cb = &bboxCb; - params.user = &mRle.unsafe(); - params.source = &outRef.ft; - - if (!mClip.empty()) { - params.flags |= SW_FT_RASTER_FLAG_CLIP; - - params.clip_box.xMin = mClip.left(); - params.clip_box.yMin = mClip.top(); - params.clip_box.xMax = mClip.right(); - params.clip_box.yMax = mClip.bottom(); - } - // compute rle - sw_ft_grays_raster.raster_render(nullptr, ¶ms); - } - - void operator()(FTOutline &outRef, SW_FT_Stroker &stroker) - { - if (mPath.points().size() > SHRT_MAX || - mPath.points().size() + mPath.segments() > SHRT_MAX) { - return; - } - - if (mGenerateStroke) { // Stroke Task - outRef.convert(mPath); - outRef.convert(mCap, mJoin, mStrokeWidth, mMiterLimit); - - uint32_t points, contors; - - SW_FT_Stroker_Set(stroker, outRef.ftWidth, outRef.ftCap, - outRef.ftJoin, outRef.ftMiterLimit); - SW_FT_Stroker_ParseOutline(stroker, &outRef.ft); - SW_FT_Stroker_GetCounts(stroker, &points, &contors); - - outRef.grow(points, contors); - - SW_FT_Stroker_Export(stroker, &outRef.ft); - - } else { // Fill Task - outRef.convert(mPath); - int fillRuleFlag = SW_FT_OUTLINE_NONE; - switch (mFillRule) { - case FillRule::EvenOdd: - fillRuleFlag = SW_FT_OUTLINE_EVEN_ODD_FILL; - break; - default: - fillRuleFlag = SW_FT_OUTLINE_NONE; - break; - } - outRef.ft.flags = fillRuleFlag; - } - - render(outRef); - - mPath = VPath(); - - mRle.notify(); - } -}; - -using VTask = std::shared_ptr; - -#ifdef LOTTIE_THREAD_SUPPORT - -#include -#include "vtaskqueue.h" - -#ifdef __linux__ -#include -#include -#endif - -class RleTaskScheduler { - const unsigned _count{std::thread::hardware_concurrency()}; - std::vector _threads; - std::vector> _q{_count}; - std::atomic _index{0}; - - void run(unsigned i) - { - /* - * initalize per thread objects. - */ - FTOutline outlineRef; - SW_FT_Stroker stroker; - SW_FT_Stroker_New(&stroker); - - // Create Thread Name for Debugging (Linux) -#ifdef __linux__ - std::ostringstream nameStream; - nameStream << "lottie-tsk-" << i; - pthread_setname_np(pthread_self(), nameStream.str().c_str()); -#endif - - // Task Loop - VTask task; - while (true) { - bool success = false; - - for (unsigned n = 0; n != _count * 2; ++n) { - if (_q[(i + n) % _count].try_pop(task)) { - success = true; - break; - } - } - - if (!success && !_q[i].pop(task)) break; - - (*task)(outlineRef, stroker); - } - - // cleanup - SW_FT_Stroker_Done(stroker); - } - - RleTaskScheduler() - { - for (unsigned n = 0; n != _count; ++n) { - _threads.emplace_back([&, n] { run(n); }); - } - - IsRunning = true; - } - -public: - static bool IsRunning; - - static RleTaskScheduler &instance() - { - static RleTaskScheduler singleton; - return singleton; - } - - ~RleTaskScheduler() { stop(); } - - void stop() - { - if (IsRunning) { - IsRunning = false; - - for (auto &e : _q) e.done(); - for (auto &e : _threads) e.join(); - } - } - - void process(VTask task) - { - auto i = _index++; - - for (unsigned n = 0; n != _count; ++n) { - if (_q[(i + n) % _count].try_push(std::move(task))) return; - } - - if (_count > 0) { - _q[i % _count].push(std::move(task)); - } - } -}; - -#else - -class RleTaskScheduler { -public: - FTOutline outlineRef{}; - SW_FT_Stroker stroker; - -public: - static bool IsRunning; - - static RleTaskScheduler &instance() - { - static RleTaskScheduler singleton; - return singleton; - } - - void stop() {} - - RleTaskScheduler() { SW_FT_Stroker_New(&stroker); } - - ~RleTaskScheduler() { SW_FT_Stroker_Done(stroker); } - - void process(VTask task) { (*task)(outlineRef, stroker); } -}; -#endif - -bool RleTaskScheduler::IsRunning{false}; - -struct VRasterizer::VRasterizerImpl { - VRleTask mTask; - - VRle & rle() { return mTask.rle(); } - VRleTask &task() { return mTask; } -}; - -VRle VRasterizer::rle() -{ - if (!d) return VRle(); - return d->rle(); -} - -void VRasterizer::init() -{ - if (!d) d = std::make_shared(); -} - -void VRasterizer::updateRequest() -{ - VTask taskObj = VTask(d, &d->task()); - RleTaskScheduler::instance().process(std::move(taskObj)); -} - -void VRasterizer::rasterize(VPath path, FillRule fillRule, const VRect &clip) -{ - init(); - if (path.empty()) { - d->rle().reset(); - return; - } - d->task().update(std::move(path), fillRule, clip); - updateRequest(); -} - -void VRasterizer::rasterize(VPath path, CapStyle cap, JoinStyle join, - float width, float miterLimit, const VRect &clip) -{ - init(); - if (path.empty() || vIsZero(width)) { - d->rle().reset(); - return; - } - d->task().update(std::move(path), cap, join, width, miterLimit, clip); - updateRequest(); -} - -void lottieShutdownRasterTaskScheduler() -{ - if (RleTaskScheduler::IsRunning) { - RleTaskScheduler::instance().stop(); - } -} - -V_END_NAMESPACE diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vraster.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vraster.h deleted file mode 100644 index fec84135..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vraster.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VRASTER_H -#define VRASTER_H -#include -#include "vglobal.h" -#include "vrect.h" - -V_BEGIN_NAMESPACE - -class VPath; -class VRle; - -class VRasterizer -{ -public: - void rasterize(VPath path, FillRule fillRule = FillRule::Winding, const VRect &clip = VRect()); - void rasterize(VPath path, CapStyle cap, JoinStyle join, float width, - float miterLimit, const VRect &clip = VRect()); - VRle rle(); -private: - struct VRasterizerImpl; - void init(); - void updateRequest(); - std::shared_ptr d{nullptr}; -}; - -V_END_NAMESPACE - -#endif // VRASTER_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vrect.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vrect.cpp deleted file mode 100644 index ff219c67..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vrect.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "vrect.h" -#include - -VRect VRect::operator&(const VRect &r) const -{ - if (empty()) return VRect(); - - int l1 = x1; - int r1 = x1; - if (x2 - x1 + 1 < 0) - l1 = x2; - else - r1 = x2; - - int l2 = r.x1; - int r2 = r.x1; - if (r.x2 - r.x1 + 1 < 0) - l2 = r.x2; - else - r2 = r.x2; - - if (l1 > r2 || l2 > r1) return VRect(); - - int t1 = y1; - int b1 = y1; - if (y2 - y1 + 1 < 0) - t1 = y2; - else - b1 = y2; - - int t2 = r.y1; - int b2 = r.y1; - if (r.y2 - r.y1 + 1 < 0) - t2 = r.y2; - else - b2 = r.y2; - - if (t1 > b2 || t2 > b1) return VRect(); - - VRect tmp; - tmp.x1 = std::max(l1, l2); - tmp.x2 = std::min(r1, r2); - tmp.y1 = std::max(t1, t2); - tmp.y2 = std::min(b1, b2); - return tmp; -} diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vrect.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vrect.h deleted file mode 100644 index f1c673e1..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vrect.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VRECT_H -#define VRECT_H -#include "vglobal.h" -#include "vpoint.h" - -V_BEGIN_NAMESPACE -class VRectF; - -class VRect { -public: - VRect() = default; - VRect(int x, int y, int w, int h):x1(x),y1(y),x2(x+w),y2(y+h){} - explicit VRect(VPoint pt, VSize sz):VRect(pt.x(), pt.y(), sz.width(), sz.height()){} - operator VRectF() const; - V_CONSTEXPR bool empty() const {return x1 >= x2 || y1 >= y2;} - V_CONSTEXPR int left() const {return x1;} - V_CONSTEXPR int top() const {return y1;} - V_CONSTEXPR int right() const {return x2;} - V_CONSTEXPR int bottom() const {return y2;} - V_CONSTEXPR int width() const {return x2-x1;} - V_CONSTEXPR int height() const {return y2-y1;} - V_CONSTEXPR int x() const {return x1;} - V_CONSTEXPR int y() const {return y1;} - VSize size() const {return {width(), height()};} - void setLeft(int l) { x1 = l; } - void setTop(int t) { y1 = t; } - void setRight(int r) { x2 = r; } - void setBottom(int b) { y2 = b; } - void setWidth(int w) { x2 = x1 + w; } - void setHeight(int h) { y2 = y1 + h; } - VRect translated(int dx, int dy) const; - void translate(int dx, int dy); - bool contains(const VRect &r, bool proper = false) const; - bool intersects(const VRect &r); - friend V_CONSTEXPR inline bool operator==(const VRect &, - const VRect &) noexcept; - friend V_CONSTEXPR inline bool operator!=(const VRect &, - const VRect &) noexcept; - friend VDebug & operator<<(VDebug &os, const VRect &o); - - VRect intersected(const VRect &r) const; - VRect operator&(const VRect &r) const; - -private: - int x1{0}; - int y1{0}; - int x2{0}; - int y2{0}; -}; - -inline VRect VRect::intersected(const VRect &r) const -{ - return *this & r; -} - -inline bool VRect::intersects(const VRect &r) -{ - return (right() > r.left() && left() < r.right() && bottom() > r.top() && - top() < r.bottom()); -} - -inline VDebug &operator<<(VDebug &os, const VRect &o) -{ - os << "{R " << o.x() << "," << o.y() << "," << o.width() << "," - << o.height() << "}"; - return os; -} -V_CONSTEXPR inline bool operator==(const VRect &r1, const VRect &r2) noexcept -{ - return r1.x1 == r2.x1 && r1.x2 == r2.x2 && r1.y1 == r2.y1 && r1.y2 == r2.y2; -} - -V_CONSTEXPR inline bool operator!=(const VRect &r1, const VRect &r2) noexcept -{ - return r1.x1 != r2.x1 || r1.x2 != r2.x2 || r1.y1 != r2.y1 || r1.y2 != r2.y2; -} - -inline VRect VRect::translated(int dx, int dy) const -{ - return {x1 + dx, y1 + dy, x2 - x1, y2 - y1}; -} - -inline void VRect::translate(int dx, int dy) -{ - x1 += dx; - y1 += dy; - x2 += dx; - y2 += dy; -} - -inline bool VRect::contains(const VRect &r, bool proper) const -{ - return proper ? - ((x1 < r.x1) && (x2 > r.x2) && (y1 < r.y1) && (y2 > r.y2)) : - ((x1 <= r.x1) && (x2 >= r.x2) && (y1 <= r.y1) && (y2 >= r.y2)); -} - -class VRectF { -public: - VRectF() = default; - - VRectF(double x, double y, double w, double h): - x1(float(x)),y1(float(y)), - x2(float(x+w)),y2(float(y+h)){} - operator VRect() const { - return {int(left()), int(right()), int(width()), int(height())}; - } - - V_CONSTEXPR bool empty() const {return x1 >= x2 || y1 >= y2;} - V_CONSTEXPR float left() const {return x1;} - V_CONSTEXPR float top() const {return y1;} - V_CONSTEXPR float right() const {return x2;} - V_CONSTEXPR float bottom() const {return y2;} - V_CONSTEXPR float width() const {return x2-x1;} - V_CONSTEXPR float height() const {return y2-y1;} - V_CONSTEXPR float x() const {return x1;} - V_CONSTEXPR float y() const {return y1;} - V_CONSTEXPR inline VPointF center() const - { - return {x1 + (x2 - x1) / 2.f, y1 + (y2 - y1) / 2.f}; - } - void setLeft(float l) { x1 = l; } - void setTop(float t) { y1 = t; } - void setRight(float r) { x2 = r; } - void setBottom(float b) { y2 = b; } - void setWidth(float w) { x2 = x1 + w; } - void setHeight(float h) { y2 = y1 + h; } - void translate(float dx, float dy) - { - x1 += dx; - y1 += dy; - x2 += dx; - y2 += dy; - } - -private: - float x1{0}; - float y1{0}; - float x2{0}; - float y2{0}; -}; - -inline VRect::operator VRectF() const -{ - return {double(left()), double(right()), double(width()), double(height())}; -} - -V_END_NAMESPACE - -#endif // VRECT_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vrle.cpp b/presentation/src/main/cpp/third_party/rlottie/src/vector/vrle.cpp deleted file mode 100644 index 753db1a1..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vrle.cpp +++ /dev/null @@ -1,749 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "vrle.h" -#include -#include -#include -#include -#include -#include -#include -#include "vdebug.h" -#include "vglobal.h" - -V_BEGIN_NAMESPACE - -using Result = std::array; -using rle_view = VRle::View; -static size_t _opGeneric(rle_view &a, rle_view &b, Result &result, - VRle::Data::Op op); -static size_t _opIntersect(const VRect &, rle_view &, Result &); -static size_t _opIntersect(rle_view &, rle_view &, Result &); - -static inline uint8_t divBy255(int x) -{ - return (x + (x >> 8) + 0x80) >> 8; -} - -inline static void copy(const VRle::Span *span, size_t count, - std::vector &v) -{ - // make sure enough memory available - if (v.capacity() < v.size() + count) v.reserve(v.size() + count); - std::copy(span, span + count, back_inserter(v)); -} - -void VRle::Data::addSpan(const VRle::Span *span, size_t count) -{ - copy(span, count, mSpans); - mBboxDirty = true; -} - -VRect VRle::Data::bbox() const -{ - updateBbox(); - return mBbox; -} - -void VRle::Data::setBbox(const VRect &bbox) const -{ - mBboxDirty = false; - mBbox = bbox; -} - -void VRle::Data::reset() -{ - mSpans.clear(); - mBbox = VRect(); - mOffset = VPoint(); - mBboxDirty = false; -} - -void VRle::Data::clone(const VRle::Data &o) -{ - *this = o; -} - -void VRle::Data::translate(const VPoint &p) -{ - // take care of last offset if applied - mOffset = p - mOffset; - int x = mOffset.x(); - int y = mOffset.y(); - for (auto &i : mSpans) { - i.x = i.x + x; - i.y = i.y + y; - } - updateBbox(); - mBbox.translate(mOffset.x(), mOffset.y()); -} - -void VRle::Data::addRect(const VRect &rect) -{ - int x = rect.left(); - int y = rect.top(); - int width = rect.width(); - int height = rect.height(); - - mSpans.reserve(size_t(height)); - - VRle::Span span; - for (int i = 0; i < height; i++) { - span.x = x; - span.y = y + i; - span.len = width; - span.coverage = 255; - mSpans.push_back(span); - } - mBbox = rect; -} - -void VRle::Data::updateBbox() const -{ - if (!mBboxDirty) return; - - mBboxDirty = false; - - int l = std::numeric_limits::max(); - const VRle::Span *span = mSpans.data(); - - mBbox = VRect(); - size_t sz = mSpans.size(); - if (sz) { - int t = span[0].y; - int b = span[sz - 1].y; - int r = 0; - for (size_t i = 0; i < sz; i++) { - if (span[i].x < l) l = span[i].x; - if (span[i].x + span[i].len > r) r = span[i].x + span[i].len; - } - mBbox = VRect(l, t, r - l, b - t + 1); - } -} - -void VRle::Data::operator*=(uint8_t alpha) -{ - for (auto &i : mSpans) { - i.coverage = divBy255(i.coverage * alpha); - } -} - -void VRle::Data::opIntersect(const VRect &r, VRle::VRleSpanCb cb, - void *userData) const -{ - if (empty()) return; - - if (r.contains(bbox())) { - cb(mSpans.size(), mSpans.data(), userData); - return; - } - - auto obj = view(); - Result result; - // run till all the spans are processed - while (obj.size()) { - auto count = _opIntersect(r, obj, result); - if (count) cb(count, result.data(), userData); - } -} - -// res = a - b; -void VRle::Data::opSubstract(const VRle::Data &aObj, const VRle::Data &bObj) -{ - // if two rle are disjoint - if (!aObj.bbox().intersects(bObj.bbox())) { - mSpans = aObj.mSpans; - } else { - auto a = aObj.view(); - auto b = bObj.view(); - - auto aPtr = a.data(); - auto aEnd = a.data() + a.size(); - auto bPtr = b.data(); - auto bEnd = b.data() + b.size(); - - // 1. forward a till it intersects with b - while ((aPtr != aEnd) && (aPtr->y < bPtr->y)) aPtr++; - auto count = aPtr - a.data(); - if (count) copy(a.data(), count, mSpans); - - // 2. forward b till it intersects with a - if (aPtr != aEnd) - while ((bPtr != bEnd) && (bPtr->y < aPtr->y)) bPtr++; - - // update a and b object - a = {aPtr, size_t(aEnd - aPtr)}; - b = {bPtr, size_t(bEnd - bPtr)}; - - // 3. calculate the intersect region - Result result; - - // run till all the spans are processed - while (a.size() && b.size()) { - auto count = _opGeneric(a, b, result, Op::Substract); - if (count) copy(result.data(), count, mSpans); - } - - // 4. copy the rest of a - if (a.size()) copy(a.data(), a.size(), mSpans); - } - - mBboxDirty = true; -} - -void VRle::Data::opGeneric(const VRle::Data &aObj, const VRle::Data &bObj, - Op op) -{ - // This routine assumes, obj1(span_y) < obj2(span_y). - - auto a = aObj.view(); - auto b = bObj.view(); - - // reserve some space for the result vector. - mSpans.reserve(a.size() + b.size()); - - // if two rle are disjoint - if (!aObj.bbox().intersects(bObj.bbox())) { - if (a.data()[0].y < b.data()[0].y) { - copy(a.data(), a.size(), mSpans); - copy(b.data(), b.size(), mSpans); - } else { - copy(b.data(), b.size(), mSpans); - copy(a.data(), a.size(), mSpans); - } - } else { - auto aPtr = a.data(); - auto aEnd = a.data() + a.size(); - auto bPtr = b.data(); - auto bEnd = b.data() + b.size(); - - // 1. forward a till it intersects with b - while ((aPtr != aEnd) && (aPtr->y < bPtr->y)) aPtr++; - - auto count = aPtr - a.data(); - if (count) copy(a.data(), count, mSpans); - - // 2. forward b till it intersects with a - if (aPtr != aEnd) - while ((bPtr != bEnd) && (bPtr->y < aPtr->y)) bPtr++; - - count = bPtr - b.data(); - if (count) copy(b.data(), count, mSpans); - - // update a and b object - a = {aPtr, size_t(aEnd - aPtr)}; - b = {bPtr, size_t(bEnd - bPtr)}; - - // 3. calculate the intersect region - Result result; - - // run till all the spans are processed - while (a.size() && b.size()) { - auto count = _opGeneric(a, b, result, op); - if (count) copy(result.data(), count, mSpans); - } - // 3. copy the rest - if (b.size()) copy(b.data(), b.size(), mSpans); - if (a.size()) copy(a.data(), a.size(), mSpans); - } - - mBboxDirty = true; -} - -static inline V_ALWAYS_INLINE void _opIntersectPrepare(VRle::View &a, - VRle::View &b) -{ - auto aPtr = a.data(); - auto aEnd = a.data() + a.size(); - auto bPtr = b.data(); - auto bEnd = b.data() + b.size(); - - // 1. advance a till it intersects with b - while ((aPtr != aEnd) && (aPtr->y < bPtr->y)) aPtr++; - - // 2. advance b till it intersects with a - if (aPtr != aEnd) - while ((bPtr != bEnd) && (bPtr->y < aPtr->y)) bPtr++; - - // update a and b object - a = {aPtr, size_t(aEnd - aPtr)}; - b = {bPtr, size_t(bEnd - bPtr)}; -} - -void VRle::Data::opIntersect(VRle::View a, VRle::View b) -{ - _opIntersectPrepare(a, b); - Result result; - while (a.size()) { - auto count = _opIntersect(a, b, result); - if (count) copy(result.data(), count, mSpans); - } - - updateBbox(); -} - -static void _opIntersect(rle_view a, rle_view b, VRle::VRleSpanCb cb, - void *userData) -{ - if (!cb) return; - - _opIntersectPrepare(a, b); - Result result; - while (a.size()) { - auto count = _opIntersect(a, b, result); - if (count) cb(count, result.data(), userData); - } -} - -/* - * This function will clip a rle list with another rle object - * tmp_clip : The rle list that will be use to clip the rle - * tmp_obj : holds the list of spans that has to be clipped - * result : will hold the result after the processing - * NOTE: if the algorithm runs out of the result buffer list - * it will stop and update the tmp_obj with the span list - * that are yet to be processed as well as the tpm_clip object - * with the unprocessed clip spans. - */ - -static size_t _opIntersect(rle_view &obj, rle_view &clip, Result &result) -{ - auto out = result.data(); - auto available = result.max_size(); - auto spans = obj.data(); - auto end = obj.data() + obj.size(); - auto clipSpans = clip.data(); - auto clipEnd = clip.data() + clip.size(); - int sx1, sx2, cx1, cx2, x, len; - - while (available && spans < end) { - if (clipSpans >= clipEnd) { - spans = end; - break; - } - if (clipSpans->y > spans->y) { - ++spans; - continue; - } - if (spans->y != clipSpans->y) { - ++clipSpans; - continue; - } - // assert(spans->y == (clipSpans->y + clip_offset_y)); - sx1 = spans->x; - sx2 = sx1 + spans->len; - cx1 = clipSpans->x; - cx2 = cx1 + clipSpans->len; - - if (cx1 < sx1 && cx2 < sx1) { - ++clipSpans; - continue; - } else if (sx1 < cx1 && sx2 < cx1) { - ++spans; - continue; - } - x = std::max(sx1, cx1); - len = std::min(sx2, cx2) - x; - if (len) { - out->x = std::max(sx1, cx1); - out->len = (std::min(sx2, cx2) - out->x); - out->y = spans->y; - out->coverage = divBy255(spans->coverage * clipSpans->coverage); - ++out; - --available; - } - if (sx2 < cx2) { - ++spans; - } else { - ++clipSpans; - } - } - - // update the obj view yet to be processed - obj = {spans, size_t(end - spans)}; - - // update the clip view yet to be processed - clip = {clipSpans, size_t(clipEnd - clipSpans)}; - - return result.max_size() - available; -} - -/* - * This function will clip a rle list with a given rect - * clip : The clip rect that will be use to clip the rle - * tmp_obj : holds the list of spans that has to be clipped - * result : will hold the result after the processing - * NOTE: if the algorithm runs out of the result buffer list - * it will stop and update the tmp_obj with the span list - * that are yet to be processed - */ -static size_t _opIntersect(const VRect &clip, rle_view &obj, Result &result) -{ - auto out = result.data(); - auto available = result.max_size(); - auto ptr = obj.data(); - auto end = obj.data() + obj.size(); - - const auto minx = clip.left(); - const auto miny = clip.top(); - const auto maxx = clip.right() - 1; - const auto maxy = clip.bottom() - 1; - - while (available && ptr < end) { - const auto &span = *ptr; - if (span.y > maxy) { - ptr = end; // update spans so that we can breakout - break; - } - if (span.y < miny || span.x > maxx || span.x + span.len <= minx) { - ++ptr; - continue; - } - if (span.x < minx) { - out->len = std::min(span.len - (minx - span.x), maxx - minx + 1); - out->x = minx; - } else { - out->x = span.x; - out->len = std::min(span.len, uint16_t(maxx - span.x + 1)); - } - if (out->len != 0) { - out->y = span.y; - out->coverage = span.coverage; - ++out; - --available; - } - ++ptr; - } - - // update the span list that yet to be processed - obj = {ptr, size_t(end - ptr)}; - - return result.max_size() - available; -} - -static void blitXor(VRle::Span *spans, int count, uint8_t *buffer, int offsetX) -{ - while (count--) { - int x = spans->x + offsetX; - int l = spans->len; - uint8_t *ptr = buffer + x; - while (l--) { - int da = *ptr; - *ptr = divBy255((255 - spans->coverage) * (da) + - spans->coverage * (255 - da)); - ptr++; - } - spans++; - } -} - -static void blitDestinationOut(VRle::Span *spans, int count, uint8_t *buffer, - int offsetX) -{ - while (count--) { - int x = spans->x + offsetX; - int l = spans->len; - uint8_t *ptr = buffer + x; - while (l--) { - *ptr = divBy255((255 - spans->coverage) * (*ptr)); - ptr++; - } - spans++; - } -} - -static void blitSrcOver(VRle::Span *spans, int count, uint8_t *buffer, - int offsetX) -{ - while (count--) { - int x = spans->x + offsetX; - int l = spans->len; - uint8_t *ptr = buffer + x; - while (l--) { - *ptr = spans->coverage + divBy255((255 - spans->coverage) * (*ptr)); - ptr++; - } - spans++; - } -} - -void blitSrc(VRle::Span *spans, int count, uint8_t *buffer, int offsetX) -{ - while (count--) { - int x = spans->x + offsetX; - int l = spans->len; - uint8_t *ptr = buffer + x; - while (l--) { - *ptr = std::max(spans->coverage, *ptr); - ptr++; - } - spans++; - } -} - -size_t bufferToRle(uint8_t *buffer, int size, int offsetX, int y, - VRle::Span *out) -{ - size_t count = 0; - uint8_t value = buffer[0]; - int curIndex = 0; - - // size = offsetX < 0 ? size + offsetX : size; - for (int i = 0; i < size; i++) { - uint8_t curValue = buffer[0]; - if (value != curValue) { - if (value) { - out->y = y; - out->x = offsetX + curIndex; - out->len = i - curIndex; - out->coverage = value; - out++; - count++; - } - curIndex = i; - value = curValue; - } - buffer++; - } - if (value) { - out->y = y; - out->x = offsetX + curIndex; - out->len = size - curIndex; - out->coverage = value; - count++; - } - return count; -} - -struct SpanMerger { - explicit SpanMerger(VRle::Data::Op op) - { - switch (op) { - case VRle::Data::Op::Add: - _blitter = &blitSrcOver; - break; - case VRle::Data::Op::Xor: - _blitter = &blitXor; - break; - case VRle::Data::Op::Substract: - _blitter = &blitDestinationOut; - break; - } - } - using blitter = void (*)(VRle::Span *, int, uint8_t *, int); - blitter _blitter; - std::array _result; - std::array _buffer; - VRle::Span * _aStart{nullptr}; - VRle::Span * _bStart{nullptr}; - - void revert(VRle::Span *&aPtr, VRle::Span *&bPtr) - { - aPtr = _aStart; - bPtr = _bStart; - } - VRle::Span *data() { return _result.data(); } - size_t merge(VRle::Span *&aPtr, const VRle::Span *aEnd, VRle::Span *&bPtr, - const VRle::Span *bEnd); -}; - -size_t SpanMerger::merge(VRle::Span *&aPtr, const VRle::Span *aEnd, - VRle::Span *&bPtr, const VRle::Span *bEnd) -{ - assert(aPtr->y == bPtr->y); - - _aStart = aPtr; - _bStart = bPtr; - int lb = std::min(aPtr->x, bPtr->x); - int y = aPtr->y; - - while (aPtr < aEnd && aPtr->y == y) aPtr++; - while (bPtr < bEnd && bPtr->y == y) bPtr++; - - int ub = std::max((aPtr - 1)->x + (aPtr - 1)->len, - (bPtr - 1)->x + (bPtr - 1)->len); - int length = (lb < 0) ? ub + lb : ub - lb; - - if (length <= 0 || size_t(length) >= _buffer.max_size()) { - // can't handle merge . skip - return 0; - } - - // clear buffer - memset(_buffer.data(), 0, length); - - // blit a to buffer - blitSrc(_aStart, aPtr - _aStart, _buffer.data(), -lb); - - // blit b to buffer - _blitter(_bStart, bPtr - _bStart, _buffer.data(), -lb); - - // convert buffer to span - return bufferToRle(_buffer.data(), length, lb, y, _result.data()); -} - -static size_t _opGeneric(rle_view &a, rle_view &b, Result &result, - VRle::Data::Op op) -{ - SpanMerger merger{op}; - - auto out = result.data(); - size_t available = result.max_size(); - auto aPtr = a.data(); - auto aEnd = a.data() + a.size(); - auto bPtr = b.data(); - auto bEnd = b.data() + b.size(); - - // only logic change for substract operation. - const bool keep = op != (VRle::Data::Op::Substract); - - while (available && aPtr < aEnd && bPtr < bEnd) { - if (aPtr->y < bPtr->y) { - *out++ = *aPtr++; - available--; - } else if (bPtr->y < aPtr->y) { - if (keep) { - *out++ = *bPtr; - available--; - } - bPtr++; - } else { // same y - auto count = merger.merge(aPtr, aEnd, bPtr, bEnd); - if (available >= count) { - if (count) { - memcpy(out, merger.data(), count * sizeof(VRle::Span)); - out += count; - available -= count; - } - } else { - // not enough space try next time. - merger.revert(aPtr, bPtr); - break; - } - } - } - // update the span list that yet to be processed - a = {aPtr, size_t(aEnd - aPtr)}; - b = {bPtr, size_t(bEnd - bPtr)}; - - return result.max_size() - available; -} - -/* - * this api makes use of thread_local temporary - * buffer to avoid creating intermediate temporary rle buffer - * the scratch buffer object will grow its size on demand - * so that future call won't need any more memory allocation. - * this function is thread safe as it uses thread_local variable - * which is unique per thread. - */ -static vthread_local VRle::Data Scratch_Object; - -VRle VRle::opGeneric(const VRle &o, Data::Op op) const -{ - if (empty()) return o; - if (o.empty()) return *this; - - Scratch_Object.reset(); - Scratch_Object.opGeneric(d.read(), o.d.read(), op); - - VRle result; - result.d.write() = Scratch_Object; - - return result; -} - -VRle VRle::operator-(const VRle &o) const -{ - if (empty()) return {}; - if (o.empty()) return *this; - - Scratch_Object.reset(); - Scratch_Object.opSubstract(d.read(), o.d.read()); - - VRle result; - result.d.write() = Scratch_Object; - - return result; -} - -VRle VRle::operator&(const VRle &o) const -{ - if (empty() || o.empty()) return {}; - - Scratch_Object.reset(); - Scratch_Object.opIntersect(d.read().view(), o.d.read().view()); - - VRle result; - result.d.write() = Scratch_Object; - - return result; -} - -void VRle::operator&=(const VRle &o) -{ - if (empty()) return; - if (o.empty()) { - reset(); - return; - } - Scratch_Object.reset(); - Scratch_Object.opIntersect(d.read().view(), o.d.read().view()); - d.write() = Scratch_Object; -} - -VRle operator-(const VRect &rect, const VRle &o) -{ - if (rect.empty()) return {}; - - Scratch_Object.reset(); - Scratch_Object.addRect(rect); - - VRle result; - result.d.write().opSubstract(Scratch_Object, o.d.read()); - - return result; -} - -VRle operator&(const VRect &rect, const VRle &o) -{ - if (rect.empty() || o.empty()) return {}; - - Scratch_Object.reset(); - Scratch_Object.addRect(rect); - - VRle result; - result.d.write().opIntersect(Scratch_Object.view(), o.d.read().view()); - - return result; -} - -void VRle::intersect(const VRle &clip, VRleSpanCb cb, void *userData) const -{ - if (empty() || clip.empty()) return; - - _opIntersect(d.read().view(), clip.d.read().view(), cb, userData); -} - -V_END_NAMESPACE diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vrle.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vrle.h deleted file mode 100644 index 1bbb8365..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vrle.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VRLE_H -#define VRLE_H - -#include -#include "vcowptr.h" -#include "vglobal.h" -#include "vpoint.h" -#include "vrect.h" - -V_BEGIN_NAMESPACE - -class VRle { -public: - struct Span { - short x{0}; - short y{0}; - uint16_t len{0}; - uint8_t coverage{0}; - }; - using VRleSpanCb = void (*)(size_t count, const VRle::Span *spans, - void *userData); - bool empty() const { return d->empty(); } - VRect boundingRect() const { return d->bbox(); } - void setBoundingRect(const VRect &bbox) { d->setBbox(bbox); } - void addSpan(const VRle::Span *span, size_t count) - { - d.write().addSpan(span, count); - } - - void reset() { d.write().reset(); } - void translate(const VPoint &p) { d.write().translate(p); } - - void operator*=(uint8_t alpha) { d.write() *= alpha; } - - void intersect(const VRect &r, VRleSpanCb cb, void *userData) const; - void intersect(const VRle &rle, VRleSpanCb cb, void *userData) const; - - void operator&=(const VRle &o); - VRle operator&(const VRle &o) const; - VRle operator-(const VRle &o) const; - VRle operator+(const VRle &o) const { return opGeneric(o, Data::Op::Add); } - VRle operator^(const VRle &o) const { return opGeneric(o, Data::Op::Xor); } - - friend VRle operator-(const VRect &rect, const VRle &o); - friend VRle operator&(const VRect &rect, const VRle &o); - - bool unique() const { return d.unique(); } - size_t refCount() const { return d.refCount(); } - void clone(const VRle &o) { d.write().clone(o.d.read()); } - -public: - struct View { - Span * _data; - size_t _size; - View(const Span *data, size_t sz) : _data((Span *)data), _size(sz) {} - Span * data() { return _data; } - size_t size() { return _size; } - }; - struct Data { - enum class Op { Add, Xor, Substract }; - VRle::View view() const - { - return VRle::View(mSpans.data(), mSpans.size()); - } - bool empty() const { return mSpans.empty(); } - void addSpan(const VRle::Span *span, size_t count); - void updateBbox() const; - VRect bbox() const; - void setBbox(const VRect &bbox) const; - void reset(); - void translate(const VPoint &p); - void operator*=(uint8_t alpha); - void opGeneric(const VRle::Data &, const VRle::Data &, Op code); - void opSubstract(const VRle::Data &, const VRle::Data &); - void opIntersect(VRle::View a, VRle::View b); - void opIntersect(const VRect &, VRle::VRleSpanCb, void *) const; - void addRect(const VRect &rect); - void clone(const VRle::Data &); - - std::vector mSpans; - VPoint mOffset; - mutable VRect mBbox; - mutable bool mBboxDirty = true; - }; - -private: - VRle opGeneric(const VRle &o, Data::Op opcode) const; - - vcow_ptr d; -}; - -inline void VRle::intersect(const VRect &r, VRleSpanCb cb, void *userData) const -{ - d->opIntersect(r, cb, userData); -} - -V_END_NAMESPACE - -#endif // VRLE_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vsharedptr.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vsharedptr.h deleted file mode 100644 index fc0c419c..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vsharedptr.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef VSHAREDPTR_H -#define VSHAREDPTR_H - -#include -#include -#include - -template -class vshared_ptr { - struct model { - Rc mRef{1}; - - model() = default; - - template - explicit model(Args&&... args) : mValue(std::forward(args)...){} - explicit model(const T& other) : mValue(other){} - - T mValue; - }; - model* mModel{nullptr}; - -public: - using element_type = T; - - vshared_ptr() = default; - - ~vshared_ptr() - { - unref(); - } - - template - explicit vshared_ptr(Args&&... args) : mModel(new model(std::forward(args)...)) - { - } - - vshared_ptr(const vshared_ptr& x) noexcept : vshared_ptr() - { - if (x.mModel) { - mModel = x.mModel; - ++mModel->mRef; - } - } - - vshared_ptr(vshared_ptr&& x) noexcept : vshared_ptr() - { - if (x.mModel) { - mModel = x.mModel; - x.mModel = nullptr; - } - } - - auto operator=(const vshared_ptr& x) noexcept -> vshared_ptr& - { - unref(); - mModel = x.mModel; - ref(); - return *this; - } - - auto operator=(vshared_ptr&& x) noexcept -> vshared_ptr& - { - unref(); - mModel = x.mModel; - x.mModel = nullptr; - return *this; - } - - operator bool() const noexcept { - return mModel != nullptr; - } - - auto operator*() const noexcept -> element_type& { return read(); } - - auto operator-> () const noexcept -> element_type* { return &read(); } - - std::size_t refCount() const noexcept - { - assert(mModel); - - return mModel->mRef; - } - - bool unique() const noexcept - { - assert(mModel); - - return mModel->mRef == 1; - } - -private: - - auto read() const noexcept -> element_type& - { - assert(mModel); - - return mModel->mValue; - } - - void ref() - { - if (mModel) ++mModel->mRef; - } - - void unref() - { - if (mModel && (--mModel->mRef == 0)) { - delete mModel; - mModel = nullptr; - } - } -}; - -// atomic ref counted pointer implementation. -template < typename T> -using arc_ptr = vshared_ptr>; - -// ref counter pointer implementation. -template < typename T> -using rc_ptr = vshared_ptr; - -#endif // VSHAREDPTR_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vstackallocator.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vstackallocator.h deleted file mode 100644 index a305b739..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vstackallocator.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VSTACK_ALLOCATOR_H -#define VSTACK_ALLOCATOR_H - -#include -#include - -template -class arena -{ - alignas(alignment) char buf_[N]; - char* ptr_; - -public: - ~arena() {ptr_ = nullptr;} - arena() noexcept : ptr_(buf_) {} - arena(const arena&) = delete; - arena& operator=(const arena&) = delete; - - template char* allocate(std::size_t n); - void deallocate(char* p, std::size_t n) noexcept; - - static constexpr std::size_t size() noexcept {return N;} - std::size_t used() const noexcept {return static_cast(ptr_ - buf_);} - void reset() noexcept {ptr_ = buf_;} - -private: - static - std::size_t - align_up(std::size_t n) noexcept - {return (n + (alignment-1)) & ~(alignment-1);} - - bool - pointer_in_buffer(char* p) noexcept - {return buf_ <= p && p <= buf_ + N;} -}; - -template -template -char* -arena::allocate(std::size_t n) -{ - static_assert(ReqAlign <= alignment, "alignment is too small for this arena"); - assert(pointer_in_buffer(ptr_) && "stack_alloc has outlived arena"); - auto const aligned_n = align_up(n); - if (static_cast(buf_ + N - ptr_) >= aligned_n) - { - char* r = ptr_; - ptr_ += aligned_n; - return r; - } - - static_assert(alignment <= alignof(std::max_align_t), "you've chosen an " - "alignment that is larger than alignof(std::max_align_t), and " - "cannot be guaranteed by normal operator new"); - return static_cast(::operator new(n)); -} - -template -void -arena::deallocate(char* p, std::size_t n) noexcept -{ - assert(pointer_in_buffer(ptr_) && "stack_alloc has outlived arena"); - if (pointer_in_buffer(p)) - { - n = align_up(n); - if (p + n == ptr_) - ptr_ = p; - } - else - ::operator delete(p); -} - -template -class stack_alloc -{ -public: - using value_type = T; - static auto constexpr alignment = Align; - static auto constexpr size = N; - using arena_type = arena; - -private: - arena_type& a_; - -public: - stack_alloc(const stack_alloc&) = default; - stack_alloc& operator=(const stack_alloc&) = delete; - - stack_alloc(arena_type& a) noexcept : a_(a) - { - static_assert(size % alignment == 0, - "size N needs to be a multiple of alignment Align"); - } - template - stack_alloc(const stack_alloc& a) noexcept - : a_(a.a_) {} - - template struct rebind {using other = stack_alloc<_Up, N, alignment>;}; - - T* allocate(std::size_t n) - { - return reinterpret_cast(a_.template allocate(n*sizeof(T))); - } - void deallocate(T* p, std::size_t n) noexcept - { - a_.deallocate(reinterpret_cast(p), n*sizeof(T)); - } - - template - friend - bool - operator==(const stack_alloc& x, const stack_alloc& y) noexcept; - - template friend class stack_alloc; -}; - -template -inline -bool -operator==(const stack_alloc& x, const stack_alloc& y) noexcept -{ - return N == M && A1 == A2 && &x.a_ == &y.a_; -} - -template -inline -bool -operator!=(const stack_alloc& x, const stack_alloc& y) noexcept -{ - return !(x == y); -} - -#endif // VSTACK_ALLOCATOR_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/vector/vtaskqueue.h b/presentation/src/main/cpp/third_party/rlottie/src/vector/vtaskqueue.h deleted file mode 100644 index e505c2f4..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/vector/vtaskqueue.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef VTASKQUEUE_H -#define VTASKQUEUE_H - -#include - -template -class TaskQueue { - using lock_t = std::unique_lock; - std::deque _q; - bool _done{false}; - std::mutex _mutex; - std::condition_variable _ready; - -public: - bool try_pop(Task &task) - { - lock_t lock{_mutex, std::try_to_lock}; - if (!lock || _q.empty()) return false; - task = std::move(_q.front()); - _q.pop_front(); - return true; - } - - bool try_push(Task &&task) - { - { - lock_t lock{_mutex, std::try_to_lock}; - if (!lock) return false; - _q.push_back(std::move(task)); - } - _ready.notify_one(); - return true; - } - - void done() - { - { - lock_t lock{_mutex}; - _done = true; - } - _ready.notify_all(); - } - - bool pop(Task &task) - { - lock_t lock{_mutex}; - while (_q.empty() && !_done) _ready.wait(lock); - if (_q.empty()) return false; - task = std::move(_q.front()); - _q.pop_front(); - return true; - } - - void push(Task &&task) - { - { - lock_t lock{_mutex}; - _q.push_back(std::move(task)); - } - _ready.notify_one(); - } - -}; - -#endif // VTASKQUEUE_H diff --git a/presentation/src/main/cpp/third_party/rlottie/src/wasm/meson.build b/presentation/src/main/cpp/third_party/rlottie/src/wasm/meson.build deleted file mode 100644 index 9100bf0b..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/wasm/meson.build +++ /dev/null @@ -1,5 +0,0 @@ -source_file = files('rlottiewasm.cpp') - - rlottie_wasm_dep = declare_dependency(include_directories - : include_directories('.'), sources - : source_file) \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/src/wasm/rlottiewasm.cpp b/presentation/src/main/cpp/third_party/rlottie/src/wasm/rlottiewasm.cpp deleted file mode 100644 index af163796..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/src/wasm/rlottiewasm.cpp +++ /dev/null @@ -1,194 +0,0 @@ -#include -#include - -#include "rlottie.h" - -#include - -using namespace emscripten; - -const char *resource = "{\"v\":\"5.1.8\",\"fr\":60,\"ip\":3,\"op\":140,\"w\":500,\"h\":500,\"nm\":\"ANUB\",\"ddd\":0,\"assets\":[],\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":4,\"nm\":\"a\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-3.113,\"ix\":10},\"p\":{\"a\":0,\"k\":[327.214,315.758,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[-17,77,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[-100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":-20.2,\"s\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}],\"e\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":-13.001,\"s\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}],\"e\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":-3.399,\"s\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}],\"e\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":2.999,\"s\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}],\"e\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":13.4,\"s\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}],\"e\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":20.599,\"s\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":32.599,\"s\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":42.2,\"s\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}],\"e\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":49.999,\"s\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}],\"e\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":58.999,\"s\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}],\"e\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":66.2,\"s\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":78.2,\"s\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":87.8,\"s\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}],\"e\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":94.999,\"s\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}],\"e\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":104.599,\"s\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}],\"e\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":111.8,\"s\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":123.8,\"s\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":133.999,\"s\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}],\"e\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}]},{\"t\":138.99921875}],\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0.149019607843,0.133333333333,0.109803921569,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":15,\"ix\":5},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[-22,82],\"ix\":2},\"a\":{\"a\":0,\"k\":[-22,82],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":3,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":-3,\"op\":289,\"st\":-20.2,\"bm\":0},{\"ddd\":0,\"ind\":2,\"ty\":4,\"nm\":\"b\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-6,\"ix\":10},\"p\":{\"a\":0,\"k\":[221.537,318.968,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[-17,77,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":-2.4,\"s\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}],\"e\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":3,\"s\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}],\"e\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":14.401,\"s\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21.6,\"s\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":31.2,\"s\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}],\"e\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":43.2,\"s\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}],\"e\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":50.401,\"s\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}],\"e\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":60,\"s\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":67.2,\"s\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":76.799,\"s\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}],\"e\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":88.799,\"s\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}],\"e\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":96,\"s\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}],\"e\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":105.6,\"s\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":112.799,\"s\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":122.401,\"s\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}],\"e\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":132,\"s\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}],\"e\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}]},{\"t\":139.000390625}],\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0.149019607843,0.133333333333,0.109803921569,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":15,\"ix\":5},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[-22,82],\"ix\":2},\"a\":{\"a\":0,\"k\":[-22,82],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":3,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":288,\"st\":-2.4,\"bm\":0},{\"ddd\":0,\"ind\":3,\"ty\":4,\"nm\":\"c\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-3.113,\"ix\":10},\"p\":{\"a\":0,\"k\":[361.652,319.398,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[-17,77,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[-100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":-14.4,\"s\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}],\"e\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":-7.201,\"s\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}],\"e\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":-0.002,\"s\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}],\"e\":[{\"i\":[[-3.791,-1.166],[-4.083,-10.915]],\"o\":[[3.791,1.166],[3.33,8.322]],\"v\":[[-17,75],[5.704,158.168]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":3,\"s\":[{\"i\":[[-3.791,-1.166],[-4.083,-10.915]],\"o\":[[3.791,1.166],[3.33,8.322]],\"v\":[[-17,75],[5.704,158.168]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11.998,\"s\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":21.6,\"s\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}],\"e\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":28.799,\"s\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}],\"e\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":38.399,\"s\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}],\"e\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":45.6,\"s\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":57.6,\"s\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":67.2,\"s\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}],\"e\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":74.399,\"s\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}],\"e\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":83.998,\"s\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}],\"e\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":91.2,\"s\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":103.2,\"s\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":112.799,\"s\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}],\"e\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":119.998,\"s\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}],\"e\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":130,\"s\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}],\"e\":[{\"i\":[[-3.791,-1.166],[-4.083,-10.915]],\"o\":[[3.791,1.166],[3.33,8.322]],\"v\":[[-17,75],[5.704,158.168]],\"c\":false}]},{\"t\":139.000390625}],\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0.149019607843,0.133333333333,0.109803921569,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":15,\"ix\":5},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[-22,82],\"ix\":2},\"a\":{\"a\":0,\"k\":[-22,82],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":3,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":-20,\"op\":279,\"st\":-14.4,\"bm\":0},{\"ddd\":0,\"ind\":4,\"ty\":4,\"nm\":\"d\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-6,\"ix\":10},\"p\":{\"a\":0,\"k\":[254.302,326.574,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[-17,77,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":-28.8,\"s\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}],\"e\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":-21.601,\"s\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}],\"e\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":-11.999,\"s\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":-4.8,\"s\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":2.8,\"s\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}],\"e\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16.8,\"s\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}],\"e\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":24.001,\"s\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}],\"e\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":33.6,\"s\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":40.8,\"s\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":50.399,\"s\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}],\"e\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":62.399,\"s\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}],\"e\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":69.6,\"s\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}],\"e\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":79.2,\"s\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":86.399,\"s\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":96.001,\"s\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}],\"e\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":106.001,\"s\":[{\"i\":[[-6.5,-2],[-4.5,-15.5]],\"o\":[[6.5,2],[3.209,11.054]],\"v\":[[-17,75],[18,154]],\"c\":false}],\"e\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":113.2,\"s\":[{\"i\":[[-4.161,-1.28],[50.642,-32.142]],\"o\":[[4.161,1.28],[-33.86,21.491]],\"v\":[[-17,75],[1.858,129.142]],\"c\":false}],\"e\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":121.001,\"s\":[{\"i\":[[0,0],[29.75,-14.5]],\"o\":[[0,0],[-29.75,14.5]],\"v\":[[-17,75],[-56.25,145.5]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":130.001,\"s\":[{\"i\":[[0,0],[-7.5,-34]],\"o\":[[0,0],[7.5,34]],\"v\":[[-17,75],[-61,161]],\"c\":false}],\"e\":[{\"i\":[[0,0],[-3.5,-4.5]],\"o\":[[0,0],[3.5,4.5]],\"v\":[[-17,75],[-11.5,164]],\"c\":false}]},{\"t\":139.00078125}],\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0.149019607843,0.133333333333,0.109803921569,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":15,\"ix\":5},\"lc\":2,\"lj\":1,\"ml\":4,\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[-22,82],\"ix\":2},\"a\":{\"a\":0,\"k\":[-22,82],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":3,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":266,\"st\":-28.8,\"bm\":0},{\"ddd\":0,\"ind\":5,\"ty\":4,\"nm\":\"b2\",\"parent\":7,\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.25],\"y\":[1]},\"o\":{\"x\":[0.75],\"y\":[0]},\"n\":[\"0p25_1_0p75_0\"],\"t\":0,\"s\":[-81],\"e\":[-97]},{\"i\":{\"x\":[0.25],\"y\":[1]},\"o\":{\"x\":[0.75],\"y\":[0]},\"n\":[\"0p25_1_0p75_0\"],\"t\":67.199,\"s\":[-97],\"e\":[-81]},{\"t\":136.80078125}],\"ix\":10},\"p\":{\"a\":0,\"k\":[-13.573,-61.514,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[-6,48,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[73.171,73.171,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"a\":0,\"k\":[82,82],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"nm\":\"Ellipse Path 1\",\"mn\":\"ADBE Vector Shape - Ellipse\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.149019607843,0.132484795065,0.111034221275,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[-6,48],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\",\"np\":3,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":141.6,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":6,\"ty\":4,\"nm\":\"b1\",\"parent\":7,\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-87,\"ix\":10},\"p\":{\"a\":0,\"k\":[-27.177,43.546,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[-6,48,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.149019607843,0.132484795065,0.111034221275,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":2,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"a\":0,\"k\":[82,82],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"nm\":\"Ellipse Path 1\",\"mn\":\"ADBE Vector Shape - Ellipse\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.149019607843,0.132484795065,0.111034221275,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[-6,48],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\",\"np\":3,\"cix\":2,\"ix\":2,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":141.6,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":7,\"ty\":4,\"nm\":\"b\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":83,\"ix\":10},\"p\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":5,\"s\":[355.857,302.207,0],\"e\":[355.857,308.207,0],\"to\":[0,1,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":16.801,\"s\":[355.857,308.207,0],\"e\":[355.857,302.207,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":33.6,\"s\":[355.857,302.207,0],\"e\":[355.857,308.207,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":50.4,\"s\":[355.857,308.207,0],\"e\":[355.857,302.207,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":67.199,\"s\":[355.857,302.207,0],\"e\":[355.857,308.207,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":84,\"s\":[355.857,308.207,0],\"e\":[355.857,302.207,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":100.801,\"s\":[355.857,302.207,0],\"e\":[355.857,308.207,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":120,\"s\":[355.857,308.207,0],\"e\":[355.857,302.207,0],\"to\":[0,0,0],\"ti\":[0,1,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":139,\"s\":[355.857,302.207,0],\"e\":[355.857,302.207,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":180,\"s\":[355.857,302.207,0],\"e\":[355.857,308.207,0],\"to\":[0,1,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":196.801,\"s\":[355.857,308.207,0],\"e\":[355.857,302.207,0],\"to\":[0,0,0],\"ti\":[0,1,0]},{\"t\":216}],\"ix\":2},\"a\":{\"a\":0,\"k\":[-5.706,-66.449,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[5.021,11.991],[1.75,-16.75],[3.593,-23.13],[3.492,-8.369],[0,23.5]],\"o\":[[-6.242,-14.906],[-1.081,10.349],[-2.222,14.305],[-14.312,34.299],[0,-55.082]],\"v\":[[14.5,-63],[-40.44,-62.693],[-44.148,-3.184],[-56.34,28.612],[12.218,41.438]],\"c\":true},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.149019607843,0.132484795065,0.111034221275,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":3,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":141.6,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":8,\"ty\":4,\"nm\":\"ne\",\"parent\":6,\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":0,\"s\":[0],\"e\":[20]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":67.199,\"s\":[20],\"e\":[0]},{\"t\":134.400390625}],\"ix\":10},\"p\":{\"a\":0,\"k\":[-12,50,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[-12,50,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0.59,12.987],[1.75,-16.75],[-1.434,-15.164],[4.955,22.972]],\"o\":[[-1,-22],[-1.75,16.75],[3.5,37],[-11,-51]],\"v\":[[3.5,-51.5],[-31.25,-48.25],[-45,45],[12,36.5]],\"c\":true},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.149019607843,0.132484795065,0.111034221275,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":3,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":141.6,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":9,\"ty\":4,\"nm\":\"ta\",\"parent\":5,\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":0,\"s\":[7],\"e\":[75]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":22.801,\"s\":[75],\"e\":[7]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":45.6,\"s\":[7],\"e\":[75]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":68.4,\"s\":[75],\"e\":[7]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":91.199,\"s\":[7],\"e\":[75]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":114,\"s\":[75],\"e\":[7]},{\"t\":136.80078125}],\"ix\":10},\"p\":{\"a\":0,\"k\":[15.301,27.13,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[21.895,-104.814,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[136.667,136.667,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[-4.827,-5.636],[1.374,-48.171],[-2.647,2.438]],\"o\":[[33.061,38.596],[-0.068,2.375],[34.628,-76.569]],\"v\":[[-18.205,-190.23],[15.659,-106.249],[25.25,-102.254]],\"c\":true},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.149019607843,0.132484795065,0.111034221275,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":3,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":141.6,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":10,\"ty\":4,\"nm\":\"el\",\"parent\":11,\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":0,\"s\":[-17],\"e\":[41]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":62.4,\"s\":[41],\"e\":[-17]},{\"t\":129.599609375}],\"ix\":10},\"p\":{\"a\":0,\"k\":[-90.831,16.442,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[16.5,-109.52,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[140.26,140.26,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[-0.618,-7.395],[-2.323,-2.379],[-2.647,2.438]],\"o\":[[6.75,80.75],[1.66,1.7],[38.998,-68.667]],\"v\":[[-1.601,-210.907],[11.871,-104.272],[20.531,-99.66]],\"c\":true},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.149019607843,0.132484795065,0.111034221275,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":3,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":141.6,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":11,\"ty\":4,\"nm\":\"hea\",\"parent\":8,\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":0,\"s\":[-15],\"e\":[8]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":67.199,\"s\":[8],\"e\":[-15]},{\"t\":134.400390625}],\"ix\":10},\"p\":{\"a\":0,\"k\":[-7.5,-46.5,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[-110.468,94.987,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[71.296,71.296,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.149019607843,0.132484795065,0.111034221275,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 2\",\"np\":2,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"a\":0,\"k\":[14.727,19.286],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"nm\":\"Ellipse Path 1\",\"mn\":\"ADBE Vector Shape - Ellipse\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.149019607843,0.132484795065,0.111034221275,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[-175.409,43.844],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[59.914,100],\"ix\":3},\"r\":{\"a\":0,\"k\":-168.452,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 5\",\"np\":3,\"cix\":2,\"ix\":2,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"a\":0,\"k\":[14.727,19.286],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"nm\":\"Ellipse Path 1\",\"mn\":\"ADBE Vector Shape - Ellipse\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.149019607843,0.132484795065,0.111034221275,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[-122.039,45.221],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 3\",\"np\":3,\"cix\":2,\"ix\":3,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[-10.966,2.431],[-1.181,-4.133],[1.601,-0.057],[-0.599,3.554]],\"o\":[[1.746,-0.387],[1.277,4.469],[-14.816,0.529],[0.406,-2.406]],\"v\":[[-8.421,-5.275],[2.908,3.703],[-0.161,10.282],[-18.683,3.926]],\"c\":true},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.933333333333,0.874509803922,0.650980392157,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"eye1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[-181.299,40.461],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667],\"y\":[1,1]},\"o\":{\"x\":[0.333,0.333],\"y\":[0,0]},\"n\":[\"0p667_1_0p333_0\",\"0p667_1_0p333_0\"],\"t\":38.4,\"s\":[100,92.381],\"e\":[100,-0.256]},{\"i\":{\"x\":[0.667,0.667],\"y\":[1,1]},\"o\":{\"x\":[0.333,0.333],\"y\":[0,0]},\"n\":[\"0p667_1_0p333_0\",\"0p667_1_0p333_0\"],\"t\":55.199,\"s\":[100,-0.256],\"e\":[100,-0.256]},{\"i\":{\"x\":[0.667,0.667],\"y\":[1,1]},\"o\":{\"x\":[0.333,0.333],\"y\":[0,0]},\"n\":[\"0p667_1_0p333_0\",\"0p667_1_0p333_0\"],\"t\":62.4,\"s\":[100,-0.256],\"e\":[100,92.381]},{\"t\":79.19921875}],\"ix\":3},\"r\":{\"a\":0,\"k\":-128.667,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 6\",\"np\":3,\"cix\":2,\"ix\":4,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"a\":0,\"k\":[40.675,16.831],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"nm\":\"Ellipse Path 1\",\"mn\":\"ADBE Vector Shape - Ellipse\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.933333333333,0.874509803922,0.650980392157,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"eye2\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[-123.091,45.195],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667,0.667],\"y\":[1,1]},\"o\":{\"x\":[0.333,0.333],\"y\":[0,0]},\"n\":[\"0p667_1_0p333_0\",\"0p667_1_0p333_0\"],\"t\":38.4,\"s\":[100,92.381],\"e\":[100,-0.256]},{\"i\":{\"x\":[0.667,0.667],\"y\":[1,1]},\"o\":{\"x\":[0.333,0.333],\"y\":[0,0]},\"n\":[\"0p667_1_0p333_0\",\"0p667_1_0p333_0\"],\"t\":55.199,\"s\":[100,-0.256],\"e\":[100,-0.256]},{\"i\":{\"x\":[0.667,0.667],\"y\":[1,1]},\"o\":{\"x\":[0.333,0.333],\"y\":[0,0]},\"n\":[\"0p667_1_0p333_0\",\"0p667_1_0p333_0\"],\"t\":62.4,\"s\":[100,-0.256],\"e\":[100,92.381]},{\"t\":79.19921875}],\"ix\":3},\"r\":{\"a\":0,\"k\":-19.654,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 2\",\"np\":3,\"cix\":2,\"ix\":5,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[10.344,0.175],[-115.817,6.255]],\"o\":[[0,0],[-7.047,-0.119],[34.894,-1.884]],\"v\":[[-167.279,58.669],[-254.234,57.818],[-149.783,98.993]],\"c\":true},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.149019607843,0.132484795065,0.111034221275,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[-162,72.234],\"ix\":2},\"a\":{\"a\":0,\"k\":[-164.104,75.74],\"ix\":1},\"s\":{\"a\":0,\"k\":[100.434,93.355],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":3,\"cix\":2,\"ix\":6,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"gr\",\"it\":[{\"d\":1,\"ty\":\"el\",\"s\":{\"a\":0,\"k\":[108,108],\"ix\":2},\"p\":{\"a\":0,\"k\":[0,0],\"ix\":3},\"nm\":\"Ellipse Path 1\",\"mn\":\"ADBE Vector Shape - Ellipse\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.149019607843,0.132484795065,0.111034221275,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[-128,48],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Ellipse 1\",\"np\":3,\"cix\":2,\"ix\":7,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":141.6,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":12,\"ty\":4,\"nm\":\"er\",\"parent\":11,\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":7.199,\"s\":[-17],\"e\":[41]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":67.199,\"s\":[41],\"e\":[-17]},{\"t\":134.400390625}],\"ix\":10},\"p\":{\"a\":0,\"k\":[-151.699,7.848,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[16.5,-109.52,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[131.332,131.332,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[-0.618,-7.395],[-2.323,-2.379],[-2.647,2.438]],\"o\":[[6.75,80.75],[1.66,1.7],[26.148,-64.813]],\"v\":[[-1.601,-210.907],[9.521,-107.006],[20.155,-104.319]],\"c\":true},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.149019607843,0.132484795065,0.111034221275,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":3,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":141.6,\"st\":0,\"bm\":0}],\"markers\":[]}"; - -typedef unsigned char uint8_t; - -class __attribute__((visibility("default"))) RlottieWasm { -public: - static std::unique_ptr create() - { - return std::unique_ptr(new RlottieWasm(resource)); - } - int frames() const { return mFrameCount; } - - bool load(std::string jsonData) - { - mPlayer = rlottie::Animation::loadFromData(std::move(jsonData), "", "", - false); - mFrameCount = mPlayer ? mPlayer->totalFrame() : 0; - return mPlayer ? true : false; - } - - void setFillColor(std::string keypath, float r, float g, float b) - { - if (!mPlayer) return; - - mPlayer->setValue(keypath, - rlottie::Color(r, g, b)); - } - - void setStrokeColor(std::string keypath, float r, float g, float b) - { - if (!mPlayer) return; - - mPlayer->setValue(keypath, - rlottie::Color(r, g, b)); - } - - void setFillOpacity(std::string keypath, float opacity) - { - if (!mPlayer || opacity > 100 || opacity < 0) return; - - mPlayer->setValue(keypath, opacity); - } - - void setStrokeOpacity(std::string keypath, float opacity) - { - if (!mPlayer || opacity > 100 || opacity < 0) return; - - mPlayer->setValue(keypath, opacity); - } - - void setStrokeWidth(std::string keypath, float width) - { - if (!mPlayer || width < 0) return; - - mPlayer->setValue(keypath, width); - } - - void setAnchor(std::string keypath, float x, float y) - { - if (!mPlayer) return; - - mPlayer->setValue(keypath, - rlottie::Point(x, y)); - } - - void setPosition(std::string keypath, float x, float y) - { - if (!mPlayer) return; - - mPlayer->setValue(keypath, - rlottie::Point(x, y)); - } - - void setScale(std::string keypath, float width, float height) - { - if (!mPlayer) return; - - mPlayer->setValue(keypath, - rlottie::Size(width, height)); - } - - void setRotation(std::string keypath, float degree) - { - if (!mPlayer || degree > 360 || degree < 0) return; - - mPlayer->setValue(keypath, degree); - } - - void setOpacity(std::string keypath, float opacity) - { - if (!mPlayer || opacity > 100 || opacity < 0) return; - - mPlayer->setValue(keypath, opacity); - } - - // canvas pixel pix[0] pix[1] pix[2] pix[3] {B G R A} - // lottie pixel pix[0] pix[1] pix[2] pix[3] {R G B A} - val render(int frame, int width, int height) - { - if (!mPlayer) return val(typed_memory_view(0, nullptr)); - - resize(width, height); - mPlayer->renderSync( - frame, rlottie::Surface((uint32_t *)mBuffer.get(), mWidth, mHeight, - mWidth * 4)); - convertToCanvasFormat(); - - return val(typed_memory_view(mWidth * mHeight * 4, mBuffer.get())); - } - ~RlottieWasm() {} - -private: - void resize(int width, int height) - { - if (width == mWidth && height == mHeight) return; - - mWidth = width; - mHeight = height; - - mBuffer = std::make_unique(mWidth * mHeight * 4); - } - - explicit RlottieWasm(const char *data) - { - mPlayer = rlottie::Animation::loadFromData(data, "", "", false); - mFrameCount = mPlayer ? mPlayer->totalFrame() : 0; - } - - void convertToCanvasFormat() - { - int totalBytes = mWidth * mHeight * 4; - uint8_t *buffer = mBuffer.get(); - for (int i = 0; i < totalBytes; i += 4) { - unsigned char a = buffer[i + 3]; - // compute only if alpha is non zero - if (a) { - unsigned char r = buffer[i + 2]; - unsigned char g = buffer[i + 1]; - unsigned char b = buffer[i]; - - if (a != 255) { // un premultiply - r = (r * 255) / a; - g = (g * 255) / a; - b = (b * 255) / a; - - buffer[i] = r; - buffer[i + 1] = g; - buffer[i + 2] = b; - - } else { - // only swizzle r and b - buffer[i] = r; - buffer[i + 2] = b; - } - } - } - } - -private: - int mWidth{0}; - int mHeight{0}; - int mFrameCount{0}; - std::unique_ptr mBuffer; - std::unique_ptr mPlayer; -}; - -// Binding code -EMSCRIPTEN_BINDINGS(rlottie_bindings) -{ - class_("RlottieWasm") - .constructor(&RlottieWasm::create) - .function("load", &RlottieWasm::load, allow_raw_pointers()) - .function("frames", &RlottieWasm::frames) - .function("render", &RlottieWasm::render) - .function("setFillColor", &RlottieWasm::setFillColor) - .function("setStrokeColor", &RlottieWasm::setStrokeColor) - .function("setFillOpacity", &RlottieWasm::setFillOpacity) - .function("setStrokeOpacity", &RlottieWasm::setStrokeOpacity) - .function("setStrokeWidth", &RlottieWasm::setStrokeWidth) - .function("setAnchor", &RlottieWasm::setAnchor) - .function("setPosition", &RlottieWasm::setPosition) - .function("setScale", &RlottieWasm::setScale) - .function("setRotation", &RlottieWasm::setRotation) - .function("setOpacity", &RlottieWasm::setOpacity); -} diff --git a/presentation/src/main/cpp/third_party/rlottie/test/CMakeLists.txt b/presentation/src/main/cpp/third_party/rlottie/test/CMakeLists.txt deleted file mode 100644 index de784113..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/test/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -project(rlottie_tests CXX) -find_package(GTest REQUIRED) - -add_definitions(-DDEMO_DIR="${CMAKE_SOURCE_DIR}/example/resource/") -link_libraries(GTest::GTest GTest::Main) - -add_executable(vectorTestSuite testsuite.cpp test_vrect.cpp test_vpath.cpp - ${CMAKE_SOURCE_DIR}/src/vector/vbezier.cpp - ${CMAKE_SOURCE_DIR}/src/vector/vdebug.cpp - ${CMAKE_SOURCE_DIR}/src/vector/vmatrix.cpp - ${CMAKE_SOURCE_DIR}/src/vector/vpath.cpp) -target_include_directories(vectorTestSuite PRIVATE ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/src/vector ${CMAKE_SOURCE_DIR}/src/vector/pixman) -gtest_add_tests(vectorTestSuite "" AUTO) - -add_executable(animationTestSuite testsuite.cpp - test_lottieanimation.cpp test_lottieanimation_capi.cpp) -target_include_directories(animationTestSuite PRIVATE ${CMAKE_SOURCE_DIR}/inc) -target_link_libraries(animationTestSuite PRIVATE rlottie) -gtest_add_tests(animationTestSuite "" AUTO) diff --git a/presentation/src/main/cpp/third_party/rlottie/test/meson.build b/presentation/src/main/cpp/third_party/rlottie/test/meson.build deleted file mode 100644 index 1dbd66ba..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/test/meson.build +++ /dev/null @@ -1,36 +0,0 @@ - -override_default = ['warning_level=2', 'werror=false'] - -gtest_dep = dependency('gtest') - -vector_test_sources = [ - 'testsuite.cpp', - 'test_vrect.cpp', - 'test_vpath.cpp', - ] - -vector_testsuite = executable('vectorTestSuite', - vector_test_sources, - include_directories : inc, - override_options : override_default, - dependencies : [gtest_dep, rlottie_lib_dep], - ) - -test('Vector Testsuite', vector_testsuite) - - -animation_test_sources = [ - 'testsuite.cpp', - 'test_lottieanimation.cpp', - 'test_lottieanimation_capi.cpp' - ] - -animation_testsuite = executable('animationTestSuite', - animation_test_sources, - include_directories : inc, - override_options : override_default, - link_with : rlottie_lib, - dependencies : gtest_dep, - ) - -test('Animation Testsuite', animation_testsuite) diff --git a/presentation/src/main/cpp/third_party/rlottie/test/test_lottieanimation.cpp b/presentation/src/main/cpp/third_party/rlottie/test/test_lottieanimation.cpp deleted file mode 100644 index 6647946a..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/test/test_lottieanimation.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include "rlottie.h" - -class AnimationTest : public ::testing::Test { -public: - void SetUp() - { - animationInvalid = rlottie::Animation::loadFromFile("wrong_file.json"); - std::string filePath = DEMO_DIR; - filePath +="mask.json"; - animation = rlottie::Animation::loadFromFile(filePath); - - } - void TearDown() - { - - } -public: - std::unique_ptr animationInvalid; - std::unique_ptr animation; -}; - -TEST_F(AnimationTest, loadFromFile_N) { - ASSERT_FALSE(animationInvalid); -} - -TEST_F(AnimationTest, loadFromFile) { - ASSERT_TRUE(animation != nullptr); - ASSERT_EQ(animation->totalFrame(), 30); - size_t width, height; - animation->size(width, height); - ASSERT_EQ(width, 500); - ASSERT_EQ(height, 500); -} diff --git a/presentation/src/main/cpp/third_party/rlottie/test/test_lottieanimation_capi.cpp b/presentation/src/main/cpp/third_party/rlottie/test/test_lottieanimation_capi.cpp deleted file mode 100644 index a0d24ef1..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/test/test_lottieanimation_capi.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include "rlottie_capi.h" - -class AnimationCApiTest : public ::testing::Test { -public: - void SetUp() - { - animationInvalid = lottie_animation_from_file("wrong_file.json"); - std::string filePath = DEMO_DIR; - filePath +="mask.json"; - animation = lottie_animation_from_file(filePath.c_str()); - - } - void TearDown() - { - if (animation) lottie_animation_destroy(animation); - } -public: - Lottie_Animation *animationInvalid; - Lottie_Animation *animation; -}; - -TEST_F(AnimationCApiTest, loadFromFile_N) { - ASSERT_FALSE(animationInvalid); -} - -TEST_F(AnimationCApiTest, loadFromFile) { - ASSERT_TRUE(animation); - ASSERT_EQ(lottie_animation_get_totalframe(animation), 30); - size_t width, height; - lottie_animation_get_size(animation, &width, &height); - ASSERT_EQ(width, 500); - ASSERT_EQ(height, 500); -} diff --git a/presentation/src/main/cpp/third_party/rlottie/test/test_vpath.cpp b/presentation/src/main/cpp/third_party/rlottie/test/test_vpath.cpp deleted file mode 100644 index 01e2d3c1..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/test/test_vpath.cpp +++ /dev/null @@ -1,190 +0,0 @@ -#include -#include "vpath.h" - -class VPathTest : public ::testing::Test { -public: - void SetUp() - { - pathRect.addRect({-10, -20, 100, 100}); - pathRoundRect.addRoundRect({0, 0, 100, 100}, 5, 5); - pathRoundRectZeroCorner.addRoundRect({0, 0, 100, 100}, 0, 0); - pathRoundRectHalfCircle.addRoundRect({0, 0, 100, 100}, 60, 60); - pathOval.addOval({0,0,100,50}); - pathOvalCircle.addOval({0,0,100,100}); - pathCircle.addCircle(0, 0, 100); - pathCircleZeroRadius.addCircle(10, 10, 0); - pathPolygon.addPolygon(10, 50, 5, 0, 0, 0); - pathPolystar.addPolystar(10, 50, 100, 7, 14, 0, 0, 0); - pathPolygonZero.addPolygon(10, 50, 0, 0, 0, 0); - pathPolystarZero.addPolystar(10, 50, 100, 0, 0, 0, 0, 0); - } - void TearDown() - { - - } -public: - VPath pathEmpty; - VPath pathRect; - VPath pathRoundRect; - VPath pathRoundRectZeroCorner; - VPath pathRoundRectHalfCircle; - VPath pathOval; - VPath pathOvalCircle; - VPath pathCircle; - VPath pathCircleZeroRadius; - VPath pathPolygon; - VPath pathPolystar; - VPath pathPolygonZero; - VPath pathPolystarZero; -}; - -TEST_F(VPathTest, emptyPath) { - ASSERT_EQ(sizeof(pathEmpty), sizeof(void *)); - ASSERT_TRUE(pathEmpty.empty()); - ASSERT_FALSE(pathEmpty.segments()); - ASSERT_EQ(pathEmpty.segments() , 0); - ASSERT_EQ(pathEmpty.elements().size() , 0); - ASSERT_EQ(pathEmpty.elements().capacity() , pathEmpty.elements().size()); - ASSERT_EQ(pathEmpty.points().size() , 0); - ASSERT_EQ(pathEmpty.points().capacity() , pathEmpty.points().size()); -} - -TEST_F(VPathTest, reset) { - pathRect.reset(); - ASSERT_TRUE(pathRect.empty()); - ASSERT_EQ(pathRect.segments() , 0); - ASSERT_GE(pathRect.points().capacity(), 1); - ASSERT_GE(pathRect.elements().capacity(), 1); -} - -TEST_F(VPathTest, reserve) { - pathEmpty.reserve(10, 10); - ASSERT_EQ(pathEmpty.points().capacity(), 10); - ASSERT_GE(pathEmpty.elements().capacity(), 10); - ASSERT_EQ(pathEmpty.segments() , 0); - ASSERT_EQ(pathEmpty.points().size(), 0); - ASSERT_GE(pathEmpty.elements().size(), 0); -} - -TEST_F(VPathTest, clone) { - VPath pathClone; - pathClone.clone(pathOval); - ASSERT_TRUE(pathClone.unique()); - ASSERT_EQ(pathClone.segments(), pathOval.segments()); - ASSERT_EQ(pathClone.points().size(), pathOval.points().size()); - ASSERT_NE(pathClone.points().data(), pathOval.points().data()); - ASSERT_EQ(pathClone.elements().size(), pathOval.elements().size()); - ASSERT_NE(pathClone.elements().data(), pathOval.elements().data()); -} - -TEST_F(VPathTest, copyOnWrite) { - VPath pathCopy; - pathCopy = pathOval; - ASSERT_EQ(pathCopy.segments(), pathOval.segments()); - ASSERT_EQ(pathCopy.points().size(), pathOval.points().size()); - ASSERT_EQ(pathCopy.points().data(), pathOval.points().data()); - ASSERT_EQ(pathCopy.elements().size(), pathOval.elements().size()); - ASSERT_EQ(pathCopy.elements().data(), pathOval.elements().data()); -} - -TEST_F(VPathTest, addRect) { - ASSERT_FALSE(pathRect.empty()); - ASSERT_EQ(pathRect.segments() , 1); - ASSERT_EQ(pathRect.elements().capacity() , pathRect.elements().size()); - ASSERT_EQ(pathRect.points().capacity() , pathRect.points().size()); -} - -TEST_F(VPathTest, addRect_N) { - pathEmpty.addRect({}); - ASSERT_TRUE(pathEmpty.empty()); - ASSERT_EQ(pathEmpty.segments() , 0); -} - -TEST_F(VPathTest, addRoundRect) { - ASSERT_FALSE(pathRoundRect.empty()); - ASSERT_EQ(pathRoundRect.segments() , 1); - ASSERT_EQ(pathRoundRect.elements().capacity() , pathRoundRect.elements().size()); - ASSERT_EQ(pathRoundRect.points().capacity() , pathRoundRect.points().size()); -} - -TEST_F(VPathTest, addRoundRectZeoCorner) { - ASSERT_FALSE(pathRoundRectZeroCorner.empty()); - ASSERT_EQ(pathRoundRectZeroCorner.segments() , 1); - ASSERT_EQ(pathRoundRectZeroCorner.elements().size() , pathRect.elements().size()); - ASSERT_EQ(pathRoundRectZeroCorner.elements().capacity() , pathRoundRectZeroCorner.elements().size()); - ASSERT_EQ(pathRoundRectZeroCorner.points().size() , pathRect.points().size()); - ASSERT_EQ(pathRoundRectZeroCorner.points().capacity() , pathRoundRectZeroCorner.points().size()); -} - -TEST_F(VPathTest, addRoundRectHalfCircle) { - ASSERT_FALSE(pathRoundRectHalfCircle.empty()); - ASSERT_EQ(pathRoundRectHalfCircle.segments() , 1); - ASSERT_EQ(pathRoundRectHalfCircle.elements().capacity() , pathRoundRectHalfCircle.elements().size()); - ASSERT_EQ(pathRoundRectHalfCircle.points().capacity() , pathRoundRectHalfCircle.points().size()); -} - -TEST_F(VPathTest, addOval) { - ASSERT_FALSE(pathOval.empty()); - ASSERT_EQ(pathOval.segments() , 1); - ASSERT_EQ(pathOval.elements().capacity() , pathOval.elements().size()); - ASSERT_EQ(pathOval.points().capacity() , pathOval.points().size()); -} - -TEST_F(VPathTest, addOvalCircle) { - ASSERT_FALSE(pathOvalCircle.empty()); - ASSERT_EQ(pathOvalCircle.segments() , 1); - ASSERT_EQ(pathOvalCircle.elements().size() , pathOval.elements().size()); - ASSERT_EQ(pathOvalCircle.elements().capacity() , pathOvalCircle.elements().size()); - ASSERT_EQ(pathOvalCircle.points().size() , pathOval.points().size()); - ASSERT_EQ(pathOvalCircle.points().capacity() , pathOvalCircle.points().size()); -} - -TEST_F(VPathTest, addCircle) { - ASSERT_FALSE(pathCircle.empty()); - ASSERT_EQ(pathCircle.segments() , 1); - ASSERT_EQ(pathCircle.elements().size() , pathOval.elements().size()); - ASSERT_EQ(pathCircle.elements().capacity() , pathCircle.elements().size()); - ASSERT_EQ(pathCircle.points().size() , pathOval.points().size()); - ASSERT_EQ(pathCircle.points().capacity() , pathCircle.points().size()); -} - -TEST_F(VPathTest, addCircleZeroRadius) { - ASSERT_TRUE(pathCircleZeroRadius.empty()); - ASSERT_EQ(pathCircleZeroRadius.segments() , 0); -} - -TEST_F(VPathTest, length) { - ASSERT_EQ(pathRect.length(), 400); -} - -TEST_F(VPathTest, lengthEmptyPath) { - ASSERT_EQ(pathEmpty.length(), 0); -} - -TEST_F(VPathTest, addPolygon) { - ASSERT_FALSE(pathPolygon.empty()); - ASSERT_EQ(pathPolygon.segments() , 1); - ASSERT_EQ(pathPolygon.elements().size() , pathPolygon.elements().capacity()); - ASSERT_EQ(pathPolygon.points().size() , pathPolygon.points().capacity()); -} - -TEST_F(VPathTest, addPolygonZeroRoundness) { - ASSERT_FALSE(pathPolygonZero.empty()); - ASSERT_EQ(pathPolygonZero.segments() , 1); - ASSERT_EQ(pathPolygonZero.elements().size() , pathPolygonZero.elements().capacity()); - ASSERT_EQ(pathPolygonZero.points().size() , pathPolygonZero.points().capacity()); -} - -TEST_F(VPathTest, addPolystar) { - ASSERT_FALSE(pathPolystar.empty()); - ASSERT_EQ(pathPolystar.segments() , 1); - ASSERT_EQ(pathPolystar.elements().size() , pathPolystar.elements().capacity()); - ASSERT_EQ(pathPolystar.points().size() , pathPolystar.points().capacity()); -} - -TEST_F(VPathTest, addPolystarZeroRoundness) { - ASSERT_FALSE(pathPolystarZero.empty()); - ASSERT_EQ(pathPolystarZero.segments() , 1); - ASSERT_EQ(pathPolystarZero.elements().size() , pathPolystarZero.elements().capacity()); - ASSERT_EQ(pathPolystarZero.points().size() , pathPolystarZero.points().capacity()); -} diff --git a/presentation/src/main/cpp/third_party/rlottie/test/test_vrect.cpp b/presentation/src/main/cpp/third_party/rlottie/test/test_vrect.cpp deleted file mode 100644 index 12fa09d0..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/test/test_vrect.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include "vrect.h" - -class VRectFTest : public ::testing::Test { -public: - void SetUp() - { - conersionRect = rect; - } - void TearDown() - { - - } -public: - VRectF Empty; - VRectF illigal{0, 0, -100, 200}; - VRectF conersionRect; - VRect rect{0, 0, 100, 100}; -}; - -class VRectTest : public ::testing::Test { -public: - void SetUp() - { - conersionRect = rect; - } - void TearDown() - { - - } -public: - VRect Empty; - VRect illigal{0, 0, -100, 200}; - VRect conersionRect; - VRectF rect{0, 0, 100.5, 100}; -}; - -TEST_F(VRectFTest, construct) { - VRectF r1{0, 0, 100, 100}; - VRectF r2{0, 0, 100.0, 100}; - VRectF r3 = {0, 0, 100, 100}; - VRectF r4 = {0, 0, 100.0, 100}; - VRectF r6(0, 0, 100, 100); - VRectF r7(0, 0, 100.0, 100); - ASSERT_TRUE(Empty.empty()); - ASSERT_TRUE(illigal.empty()); -} - -TEST_F(VRectTest, construct) { - VRect r1{0, 0, 100, 100}; - VRect r2{0, 0, 10, 100}; - VRect r3 = {0, 0, 100, 100}; - VRect r4 = {0, 0, 10, 100}; - VRect r6(0, 0, 100, 100); - VRect r7(0, 0, 10, 100); - ASSERT_TRUE(Empty.empty()); - ASSERT_TRUE(illigal.empty()); -} diff --git a/presentation/src/main/cpp/third_party/rlottie/test/testsuite.cpp b/presentation/src/main/cpp/third_party/rlottie/test/testsuite.cpp deleted file mode 100644 index 64becff4..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/test/testsuite.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main(int argc, char **argv) { - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/presentation/src/main/cpp/third_party/rlottie/test/wasm_test.html b/presentation/src/main/cpp/third_party/rlottie/test/wasm_test.html deleted file mode 100644 index e53f6b52..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/test/wasm_test.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/vs2019/config.h b/presentation/src/main/cpp/third_party/rlottie/vs2019/config.h deleted file mode 100644 index 3261852a..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/vs2019/config.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Autogenerated by the Meson build system. - * Do not edit, your changes will be lost. - */ - -#pragma once - -#define LOTTIE_CACHE_SUPPORT 1 - -#define LOTTIE_THREAD_SUPPORT 1 diff --git a/presentation/src/main/cpp/third_party/rlottie/vs2019/rlottie.sln b/presentation/src/main/cpp/third_party/rlottie/vs2019/rlottie.sln deleted file mode 100644 index ff86200f..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/vs2019/rlottie.sln +++ /dev/null @@ -1,31 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29020.237 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rlottie", "rlottie.vcxproj", "{9C97B40D-AB46-4EC7-9A17-7F5256FBC059}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {9C97B40D-AB46-4EC7-9A17-7F5256FBC059}.Debug|x64.ActiveCfg = Debug|x64 - {9C97B40D-AB46-4EC7-9A17-7F5256FBC059}.Debug|x64.Build.0 = Debug|x64 - {9C97B40D-AB46-4EC7-9A17-7F5256FBC059}.Debug|x86.ActiveCfg = Debug|Win32 - {9C97B40D-AB46-4EC7-9A17-7F5256FBC059}.Debug|x86.Build.0 = Debug|Win32 - {9C97B40D-AB46-4EC7-9A17-7F5256FBC059}.Release|x64.ActiveCfg = Release|x64 - {9C97B40D-AB46-4EC7-9A17-7F5256FBC059}.Release|x64.Build.0 = Release|x64 - {9C97B40D-AB46-4EC7-9A17-7F5256FBC059}.Release|x86.ActiveCfg = Release|Win32 - {9C97B40D-AB46-4EC7-9A17-7F5256FBC059}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {A8E849A6-AE99-4AEA-92AD-23F0F12B1C68} - EndGlobalSection -EndGlobal diff --git a/presentation/src/main/cpp/third_party/rlottie/vs2019/rlottie.vcxproj b/presentation/src/main/cpp/third_party/rlottie/vs2019/rlottie.vcxproj deleted file mode 100644 index c1685cc2..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/vs2019/rlottie.vcxproj +++ /dev/null @@ -1,252 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - {9C97B40D-AB46-4EC7-9A17-7F5256FBC059} - rlottie - 10.0 - - - - Application - true - v142 - MultiByte - - - Application - false - v142 - true - MultiByte - - - DynamicLibrary - true - v142 - MultiByte - - - DynamicLibrary - false - v142 - true - MultiByte - - - - - - - - - - - - - - - - - - - - - - - Level3 - Disabled - true - true - - - Console - - - - - Level3 - Disabled - true - true - ../inc;./;../src/lottie;../src/vector;../src/vector/pixman;../src/vector/freetype;%(AdditionalIncludeDirectories) - -DRLOTTIE_BUILD %(AdditionalOptions) - 4251;4244;4996 - - - Console - - - - - Level3 - MaxSpeed - true - true - true - true - - - Console - true - true - - - - - Level3 - MaxSpeed - true - true - true - true - ../inc;./;../src/lottie;../src/vector;../src/vector/pixman;../src/vector/freetype;%(AdditionalIncludeDirectories) - -DRLOTTIE_BUILD %(AdditionalOptions) - 4251;4244;4996 - - - Console - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/presentation/src/main/cpp/third_party/rlottie/vs2019/rlottie.vcxproj.filters b/presentation/src/main/cpp/third_party/rlottie/vs2019/rlottie.vcxproj.filters deleted file mode 100644 index 0c511bfa..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/vs2019/rlottie.vcxproj.filters +++ /dev/null @@ -1,385 +0,0 @@ - - - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;ipp;xsd - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {fe19fe8c-ea12-4233-a5b3-e1d3b5eef911} - - - {d270b25a-5e50-4fd3-9552-e97a4855bbce} - - - {14ba4b30-7907-4e82-9e05-46bb1083eb30} - - - {fb769465-148c-4a24-b6f7-d4f296c045f7} - - - {6c95ecc5-8b13-4cdf-b729-ef98cf1e23e0} - - - {089f6054-13bb-4ffe-8129-4b38224412db} - - - {02c6210d-fe4b-4971-a04d-ca33f9b7f033} - - - {d981dfd0-86e1-47ea-9fdb-2c06401fddec} - - - {75db7b83-6147-402f-bc29-25e5edab2531} - - - {386829e3-2415-4992-a85e-b3e9a352278d} - - - {79196b11-c3ac-449b-83d6-52f81e748794} - - - - - inc - - - inc - - - inc - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson - - - src\lottie\rapidjson\error - - - src\lottie\rapidjson\error - - - src\lottie\rapidjson\internal - - - src\lottie\rapidjson\internal - - - src\lottie\rapidjson\internal - - - src\lottie\rapidjson\internal - - - src\lottie\rapidjson\internal - - - src\lottie\rapidjson\internal - - - src\lottie\rapidjson\internal - - - src\lottie\rapidjson\internal - - - src\lottie\rapidjson\internal - - - src\lottie\rapidjson\internal - - - src\lottie\rapidjson\internal - - - src\lottie\rapidjson\internal - - - src\lottie\rapidjson\msinttypes - - - src\lottie\rapidjson\msinttypes - - - src\lottie - - - src\lottie - - - src\lottie - - - src\lottie - - - src\lottie - - - src\lottie - - - src\vector\freetype - - - src\vector\freetype - - - src\vector\freetype - - - src\vector\freetype - - - src\vector\pixman - - - src\vector\stb - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - inc - - - - - src\binding\c - - - src\lottie - - - src\lottie - - - src\lottie - - - src\lottie - - - src\lottie - - - src\lottie - - - src\lottie - - - src\lottie - - - src\vector\freetype - - - src\vector\freetype - - - src\vector\freetype - - - src\vector\stb - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - src\vector - - - - - src\vector\pixman - - - diff --git a/presentation/src/main/cpp/third_party/rlottie/vs2019/rlottie.vcxproj.user b/presentation/src/main/cpp/third_party/rlottie/vs2019/rlottie.vcxproj.user deleted file mode 100644 index 88a55094..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/vs2019/rlottie.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/presentation/src/main/cpp/third_party/rlottie/wasm_build.sh b/presentation/src/main/cpp/third_party/rlottie/wasm_build.sh deleted file mode 100644 index 61ffa6a1..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/wasm_build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -if [ -z "$1" ]; then - echo "Emscripten SDK PATH is not provided" - echo "Usage: wasm_build EMSDK_PATH" - exit 1; -fi - -if [ ! -d "./builddir_wasm" ]; then - sed "s|EMSDK:|$1|g" wasm_cross.txt > /tmp/.wasm_cross.txt - meson -Dthread=false -Dmodule=false -Dcache=false -Dexample=false -Db_lto=true -Ddefault_library=static builddir_wasm --cross-file /tmp/.wasm_cross.txt - cp ./test/wasm_test.html builddir_wasm/src/index.html -fi - -sudo ninja -C builddir_wasm/ -echo "RESULT:" -echo " rlottie-wasm.wasm and rlottie-wasm.js can be found in builddir_wasm/src folder" -ls -lrt builddir_wasm/src/rlottie-wasm.* diff --git a/presentation/src/main/cpp/third_party/rlottie/wasm_cross.txt b/presentation/src/main/cpp/third_party/rlottie/wasm_cross.txt deleted file mode 100644 index eaf7e162..00000000 --- a/presentation/src/main/cpp/third_party/rlottie/wasm_cross.txt +++ /dev/null @@ -1,19 +0,0 @@ -[binaries] -c = 'EMSDK:upstream/emscripten/emcc.py' -cpp = 'EMSDK:upstream/emscripten/em++.py' -ar = 'EMSDK:upstream/emscripten/emar.py' - -[properties] -root = 'EMSDK:upstream/emscripten/system' -cpp_args = ['--bind' , '-s' , 'WASM=1' , '-s' , 'ALLOW_MEMORY_GROWTH=1' , '-s' , 'FILESYSTEM=0' , '-O2'] -cpp_link_args = ['--bind' , '-s' , 'WASM=1' , '-s' , 'ALLOW_MEMORY_GROWTH=1' , '-s' , 'FILESYSTEM=0' , '-O2'] -shared_lib_suffix = 'js' -static_lib_suffix = 'js' -shared_module_suffix = 'js' -exe_suffix = 'js' - -[host_machine] -system = 'emscripten' -cpu_family = 'x86' -cpu = 'i686' -endian = 'little' \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/Avatar.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/Avatar.kt deleted file mode 100644 index c1fb258e..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/Avatar.kt +++ /dev/null @@ -1,238 +0,0 @@ -package org.monogram.presentation.core.ui - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.runtime.key -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage -import coil3.request.ImageRequest -import org.monogram.presentation.R -import org.monogram.presentation.core.util.generateColorFromHash -import org.monogram.presentation.features.chats.currentChat.components.AvatarPlayer -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import java.io.File - -@Composable -fun Avatar( - path: String?, - fallbackPath: String? = null, - name: String, - size: Dp, - videoPlayerPool: VideoPlayerPool, - modifier: Modifier = Modifier, - fontSize: Int = 14, - isOnline: Boolean = false, - isLocal: Boolean = false, - onClick: () -> Unit = {} -) { - val context = LocalContext.current - val combinedModifier = modifier - .size(size) - .clip(CircleShape) - .clickable { onClick() } - - val resolvedPath = resolveAvatarPath(path, fallbackPath) - val imageSource = resolvedPath?.let(::resolveAvatarImageSource) - - Box(modifier = modifier.size(size)) { - val placeholder = @Composable { - PlaceholderAvatar( - name = name, - fontSize = fontSize, - color = generateColorFromHash(name), - modifier = Modifier.fillMaxSize() - ) - } - - if (resolvedPath != null) { - if (isLocal) { - AsyncImage( - model = R.raw.konata, - contentDescription = null, - modifier = combinedModifier, - contentScale = ContentScale.Crop, - ) - } else { - val isVideo = remember(resolvedPath) { resolvedPath.endsWith(".mp4", ignoreCase = true) } - if (isVideo) { - key(imageSource?.cacheKey ?: resolvedPath) { - AvatarPlayer( - path = resolvedPath, - modifier = combinedModifier, - contentScale = ContentScale.Crop, - videoPlayerPool = videoPlayerPool - ) - } - } else { - Box(modifier = combinedModifier) { - placeholder() - AsyncImage( - model = ImageRequest.Builder(context) - .data(imageSource?.model ?: resolvedPath) - .apply { - imageSource?.cacheKey?.let { - memoryCacheKey(it) - diskCacheKey(it) - } - } - .build(), - contentDescription = null, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Crop - ) - } - } - } - } else { - Box(modifier = combinedModifier) { - placeholder() - } - } - - if (isOnline) { - Box( - modifier = Modifier - .size(size / 4) - .align(Alignment.BottomEnd) - .background(MaterialTheme.colorScheme.background, CircleShape) - .padding(2.dp) - .background(Color(0xFF4CAF50), CircleShape) - ) - } - } -} - -@Composable -fun AvatarForChat( - path: String?, - fallbackPath: String? = null, - name: String, - size: Dp, - modifier: Modifier = Modifier, - fontSize: Int = 14, - isOnline: Boolean = false, - isLocal: Boolean = false, - videoPlayerPool: VideoPlayerPool -) { - val context = LocalContext.current - val combinedModifier = modifier - .size(size) - .clip(CircleShape) - - val resolvedPath = resolveAvatarPath(path, fallbackPath) - val imageSource = resolvedPath?.let(::resolveAvatarImageSource) - - Box(modifier = modifier.size(size)) { - val placeholder = @Composable { - PlaceholderAvatar( - name = name, - fontSize = fontSize, - color = generateColorFromHash(name), - modifier = Modifier.fillMaxSize() - ) - } - - if (resolvedPath != null) { - if (isLocal) { - AsyncImage( - model = R.raw.konata, - contentDescription = null, - modifier = combinedModifier, - contentScale = ContentScale.Crop - ) - } else { - val isVideo = remember(resolvedPath) { resolvedPath.endsWith(".mp4", ignoreCase = true) } - if (isVideo) { - key(imageSource?.cacheKey ?: resolvedPath) { - AvatarPlayer( - path = resolvedPath, - modifier = combinedModifier, - contentScale = ContentScale.Crop, - videoPlayerPool = videoPlayerPool - ) - } - } else { - Box(modifier = combinedModifier) { - placeholder() - AsyncImage( - model = ImageRequest.Builder(context) - .data(imageSource?.model ?: resolvedPath) - .apply { - imageSource?.cacheKey?.let { - memoryCacheKey(it) - diskCacheKey(it) - } - } - .build(), - contentDescription = null, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Crop - ) - } - } - } - } else { - Box(modifier = combinedModifier) { - placeholder() - } - } - - if (isOnline) { - Box( - modifier = Modifier - .size(size / 4) - .align(Alignment.BottomEnd) - .background(MaterialTheme.colorScheme.background, CircleShape) - .padding(2.dp) - .background(Color(0xFF4CAF50), CircleShape) - ) - } - } -} - -private data class AvatarImageSource( - val model: Any, - val cacheKey: String? -) - -private fun resolveAvatarImageSource(path: String): AvatarImageSource { - return if (path.startsWith("http") || path.startsWith("content:") || path.startsWith("file:")) { - AvatarImageSource(model = path, cacheKey = path) - } else { - val file = File(path) - if (file.exists()) { - AvatarImageSource( - model = file, - cacheKey = "${file.absolutePath}:${file.lastModified()}:${file.length()}" - ) - } else { - AvatarImageSource(model = path, cacheKey = path) - } - } -} - -private fun resolveAvatarPath(primaryPath: String?, fallbackPath: String?): String? { - val candidates = listOfNotNull(primaryPath?.takeIf { it.isNotBlank() }, fallbackPath?.takeIf { it.isNotBlank() }) - .distinct() - if (candidates.isEmpty()) return null - - val existingCandidates = candidates.filter { File(it).exists() } - val source = if (existingCandidates.isNotEmpty()) existingCandidates else candidates - - return source.firstOrNull { it.endsWith(".mp4", ignoreCase = true) } ?: source.firstOrNull() -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/AvatarHeader.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/AvatarHeader.kt deleted file mode 100644 index 550ca0ba..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/AvatarHeader.kt +++ /dev/null @@ -1,104 +0,0 @@ -package org.monogram.presentation.core.ui - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage -import coil3.request.ImageRequest -import coil3.request.crossfade -import coil3.size.Precision -import coil3.size.Size -import org.monogram.presentation.core.util.generateColorFromHash -import org.monogram.presentation.features.chats.currentChat.components.AvatarPlayer -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import java.io.File - -@Composable -fun AvatarHeader( - path: String?, - fallbackPath: String? = null, - name: String, - size: Dp, - modifier: Modifier = Modifier, - fontSize: Int = 64, - isOnline: Boolean = false, - avatarCornerPercent: Int = 0, - videoPlayerPool: VideoPlayerPool -) { - val context = LocalContext.current - val combinedModifier = modifier - .size(size) - .clip(RoundedCornerShape(percent = avatarCornerPercent)) - - val resolvedPath = resolveAvatarPath(path, fallbackPath) - - Box(modifier = combinedModifier) { - val avatarFile = resolvedPath?.let { File(it) } - - if (avatarFile != null && avatarFile.exists()) { - val isVideo = resolvedPath.endsWith(".mp4", ignoreCase = true) - - when { - isVideo -> { - AvatarPlayer( - path = resolvedPath, - modifier = Modifier.matchParentSize(), - contentScale = ContentScale.Crop, - videoPlayerPool = videoPlayerPool - ) - } - - else -> { - AsyncImage( - model = ImageRequest.Builder(context) - .data(avatarFile) - .size(Size.ORIGINAL) - .precision(Precision.EXACT) - .crossfade(true) - .build(), - contentDescription = null, - modifier = Modifier.matchParentSize(), - contentScale = ContentScale.Crop - ) - } - } - } else { - PlaceholderAvatar(name, fontSize, generateColorFromHash(name)) - } - - if (isOnline) { - Box( - modifier = Modifier - .size(size / 4) - .align(Alignment.BottomEnd) - .background(MaterialTheme.colorScheme.background, CircleShape) - .padding(2.dp) - .background(Color(0xFF4CAF50), CircleShape) - ) - } - } -} - -private fun resolveAvatarPath(primaryPath: String?, fallbackPath: String?): String? { - val candidates = listOfNotNull(primaryPath?.takeIf { it.isNotBlank() }, fallbackPath?.takeIf { it.isNotBlank() }) - .distinct() - if (candidates.isEmpty()) return null - - val existingCandidates = candidates.filter { File(it).exists() } - val source = if (existingCandidates.isNotEmpty()) existingCandidates else candidates - - return source.firstOrNull { it.endsWith(".mp4", ignoreCase = true) } ?: source.firstOrNull() -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/CollapsingToolbarState.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/CollapsingToolbarState.kt deleted file mode 100644 index 8cf07bfe..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/CollapsingToolbarState.kt +++ /dev/null @@ -1,336 +0,0 @@ -package org.monogram.presentation.core.ui - - -import androidx.annotation.FloatRange -import androidx.compose.animation.core.AnimationState -import androidx.compose.animation.core.animateTo -import androidx.compose.animation.core.tween -import androidx.compose.foundation.MutatePriority -import androidx.compose.foundation.gestures.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clipToBounds -import androidx.compose.ui.layout.* -import androidx.compose.ui.unit.Constraints -import androidx.compose.ui.unit.Density -import androidx.compose.ui.unit.IntSize -import androidx.compose.ui.unit.LayoutDirection -import kotlin.math.absoluteValue -import kotlin.math.max -import kotlin.math.min -import kotlin.math.roundToInt - -@Stable -class CollapsingToolbarState( - initial: Int = Int.MAX_VALUE -): ScrollableState { - var height: Int by mutableStateOf(initial) - private set - var minHeight: Int - get() = minHeightState - internal set(value) { - minHeightState = value - - if(height < value) { - height = value - } - } - - var maxHeight: Int - get() = maxHeightState - internal set(value) { - maxHeightState = value - - if(value < height) { - height = value - } - } - - private var maxHeightState by mutableStateOf(Int.MAX_VALUE) - private var minHeightState by mutableStateOf(0) - - val progress: Float - @FloatRange(from = 0.0, to = 1.0) - get() = - if(minHeight == maxHeight) { - 0f - }else{ - ((height - minHeight).toFloat() / (maxHeight - minHeight)).coerceIn(0f, 1f) - } - - private val scrollableState = ScrollableState { value -> - val consume = if(value < 0) { - max(minHeight.toFloat() - height, value) - }else{ - min(maxHeight.toFloat() - height, value) - } - - val current = consume + deferredConsumption - val currentInt = current.toInt() - - if(current.absoluteValue > 0) { - height += currentInt - deferredConsumption = current - currentInt - } - - consume - } - - private var deferredConsumption: Float = 0f - - @Deprecated( - message = "feedScroll() is deprecated, use dispatchRawDelta() instead.", - replaceWith = ReplaceWith("dispatchRawDelta(value)") - ) - fun feedScroll(value: Float): Float = dispatchRawDelta(value) - - - suspend fun expand(duration: Int = 200) { - val anim = AnimationState(height.toFloat()) - - scroll { - var prev = anim.value - anim.animateTo(maxHeight.toFloat(), tween(duration)) { - scrollBy(value - prev) - prev = value - } - } - } - - - suspend fun collapse(duration: Int = 200) { - val anim = AnimationState(height.toFloat()) - - scroll { - var prev = anim.value - anim.animateTo(minHeight.toFloat(), tween(duration)) { - scrollBy(value - prev) - prev = value - } - } - } - - - suspend fun fling(flingBehavior: FlingBehavior, velocity: Float): Float { - var left = velocity - scroll { - with(flingBehavior) { - left = performFling(left) - } - } - - return left - } - - override val isScrollInProgress: Boolean - get() = scrollableState.isScrollInProgress - - override fun dispatchRawDelta(delta: Float): Float = scrollableState.dispatchRawDelta(delta) - - override suspend fun scroll( - scrollPriority: MutatePriority, - block: suspend ScrollScope.() -> Unit - ) = scrollableState.scroll(scrollPriority, block) -} - -@Composable -fun rememberCollapsingToolbarState( - initial: Int = Int.MAX_VALUE -): CollapsingToolbarState { - return remember { - CollapsingToolbarState( - initial = initial - ) - } -} - -@Composable -fun CollapsingToolbar( - modifier: Modifier = Modifier, - collapsingToolbarState: CollapsingToolbarState, - content: @Composable CollapsingToolbarScope.() -> Unit -) { - val measurePolicy = remember(collapsingToolbarState) { - CollapsingToolbarMeasurePolicy(collapsingToolbarState) - } - - Layout( - content = { CollapsingToolbarScopeInstance.content() }, - measurePolicy = measurePolicy, - modifier = modifier - .scrollable( - state = collapsingToolbarState, - orientation = Orientation.Vertical, - flingBehavior = ScrollableDefaults.flingBehavior() - ) - .clipToBounds() - ) -} - -private class CollapsingToolbarMeasurePolicy( - private val collapsingToolbarState: CollapsingToolbarState -): MeasurePolicy { - override fun MeasureScope.measure( - measurables: List, - constraints: Constraints - ): MeasureResult { - val placeables = ArrayList(measurables.size) - measurables.mapTo(placeables) { - it.measure( - constraints.copy( - minWidth = 0, - minHeight = 0, - maxHeight = Constraints.Infinity - ) - ) - } - - val placeStrategy = ArrayList(measurables.size) - measurables.mapTo(placeStrategy) { it.parentData } - - val minHeight = placeables.minOfOrNull { it.height } - ?.coerceIn(constraints.minHeight, constraints.maxHeight) ?: 0 - - val maxHeight = placeables.maxOfOrNull { it.height } - ?.coerceIn(constraints.minHeight, constraints.maxHeight) ?: 0 - - val maxWidth = placeables.maxOfOrNull{ it.width } - ?.coerceIn(constraints.minWidth, constraints.maxWidth) ?: 0 - - collapsingToolbarState.also { - it.minHeight = minHeight - it.maxHeight = maxHeight - } - - val height = collapsingToolbarState.height - return layout(maxWidth, height) { - val progress = collapsingToolbarState.progress - - placeables.forEachIndexed { i, placeable -> - val strategy = placeStrategy[i] - if(strategy is CollapsingToolbarData) { - strategy.progressListener?.onProgressUpdate(progress) - } - - when(strategy) { - is CollapsingToolbarRoadData -> { - val collapsed = strategy.whenCollapsed - val expanded = strategy.whenExpanded - - val collapsedOffset = collapsed.align( - size = IntSize(placeable.width, placeable.height), - space = IntSize(maxWidth, height), - layoutDirection = LayoutDirection.Ltr - ) - - val expandedOffset = expanded.align( - size = IntSize(placeable.width, placeable.height), - space = IntSize(maxWidth, height), - layoutDirection = LayoutDirection.Ltr - ) - - val offset = collapsedOffset + (expandedOffset - collapsedOffset) * progress - - placeable.place(offset.x, offset.y) - } - is CollapsingToolbarParallaxData -> - placeable.place( - x = 0, - y = -((maxHeight - minHeight) * (1 - progress) * strategy.ratio).roundToInt() - ) - else -> placeable.place(0, 0) - } - } - } - } -} - -interface CollapsingToolbarScope { - fun Modifier.progress(listener: ProgressListener): Modifier - - fun Modifier.road(whenCollapsed: Alignment, whenExpanded: Alignment): Modifier - - fun Modifier.parallax(ratio: Float = 0.2f): Modifier - - fun Modifier.pin(): Modifier -} - -internal object CollapsingToolbarScopeInstance: CollapsingToolbarScope { - override fun Modifier.progress(listener: ProgressListener): Modifier { - return this.then(ProgressUpdateListenerModifier(listener)) - } - - override fun Modifier.road(whenCollapsed: Alignment, whenExpanded: Alignment): Modifier { - return this.then(RoadModifier(whenCollapsed, whenExpanded)) - } - - override fun Modifier.parallax(ratio: Float): Modifier { - return this.then(ParallaxModifier(ratio)) - } - - override fun Modifier.pin(): Modifier { - return this.then(PinModifier()) - } -} - -internal class RoadModifier( - private val whenCollapsed: Alignment, - private val whenExpanded: Alignment -): ParentDataModifier { - override fun Density.modifyParentData(parentData: Any?): Any { - return CollapsingToolbarRoadData( - this@RoadModifier.whenCollapsed, this@RoadModifier.whenExpanded, - (parentData as? CollapsingToolbarData)?.progressListener - ) - } -} - -internal class ParallaxModifier( - private val ratio: Float -): ParentDataModifier { - override fun Density.modifyParentData(parentData: Any?): Any { - return CollapsingToolbarParallaxData(ratio, (parentData as? CollapsingToolbarData)?.progressListener) - } -} - -internal class PinModifier: ParentDataModifier { - override fun Density.modifyParentData(parentData: Any?): Any { - return CollapsingToolbarPinData((parentData as? CollapsingToolbarData)?.progressListener) - } -} - -internal class ProgressUpdateListenerModifier( - private val listener: ProgressListener -): ParentDataModifier { - override fun Density.modifyParentData(parentData: Any?): Any { - return CollapsingToolbarProgressData(listener) - } -} - -fun interface ProgressListener { - fun onProgressUpdate(value: Float) -} - -internal sealed class CollapsingToolbarData( - var progressListener: ProgressListener? -) - -internal class CollapsingToolbarProgressData( - progressListener: ProgressListener? -): CollapsingToolbarData(progressListener) - -internal class CollapsingToolbarRoadData( - var whenCollapsed: Alignment, - var whenExpanded: Alignment, - progressListener: ProgressListener? = null -): CollapsingToolbarData(progressListener) - -internal class CollapsingToolbarPinData( - progressListener: ProgressListener? = null -): CollapsingToolbarData(progressListener) - -internal class CollapsingToolbarParallaxData( - var ratio: Float, - progressListener: ProgressListener? = null -): CollapsingToolbarData(progressListener) diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/ConfirmationSheet.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/ConfirmationSheet.kt deleted file mode 100644 index f475769d..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/ConfirmationSheet.kt +++ /dev/null @@ -1,120 +0,0 @@ -package org.monogram.presentation.core.ui - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.BottomSheetDefaults -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.ModalBottomSheet -import androidx.compose.material3.OutlinedButton -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.presentation.R - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ConfirmationSheet( - icon: ImageVector, - title: String, - description: String, - confirmText: String, - onConfirm: () -> Unit, - onDismiss: () -> Unit, - isDestructive: Boolean = true -) { - ModalBottomSheet( - onDismissRequest = onDismiss, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 32.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Icon( - imageVector = icon, - contentDescription = null, - modifier = Modifier.size(48.dp), - tint = if (isDestructive) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.primary - ) - - Spacer(modifier = Modifier.height(16.dp)) - - Text( - text = title, - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - textAlign = TextAlign.Center - ) - - Spacer(modifier = Modifier.height(8.dp)) - - Text( - text = description, - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center - ) - - Spacer(modifier = Modifier.height(24.dp)) - - Column( - modifier = Modifier.fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(12.dp) - ) { - Button( - onClick = onConfirm, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp), - colors = if (isDestructive) { - ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.error, - contentColor = MaterialTheme.colorScheme.onError - ) - } else { - ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.primary, - contentColor = MaterialTheme.colorScheme.onPrimary - ) - } - ) { - Text(confirmText, fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - - OutlinedButton( - onClick = onDismiss, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.cancel_button), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/IntegratedQRScanner.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/IntegratedQRScanner.kt deleted file mode 100644 index b8945504..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/IntegratedQRScanner.kt +++ /dev/null @@ -1,95 +0,0 @@ -package org.monogram.presentation.core.ui - -import androidx.camera.core.CameraSelector -import androidx.camera.mlkit.vision.MlKitAnalyzer -import androidx.camera.view.CameraController -import androidx.camera.view.LifecycleCameraController -import androidx.camera.view.PreviewView -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalLifecycleOwner -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import androidx.compose.ui.viewinterop.AndroidView -import androidx.core.content.ContextCompat -import com.google.mlkit.vision.barcode.BarcodeScannerOptions -import com.google.mlkit.vision.barcode.BarcodeScanning -import com.google.mlkit.vision.barcode.common.Barcode -import org.monogram.presentation.R - -@Composable -fun IntegratedQRScanner( - onCodeDetected: (String) -> Unit, - onBackClicked: () -> Unit -) { - val context = LocalContext.current - val lifecycleOwner = LocalLifecycleOwner.current - val cameraController = remember { - LifecycleCameraController(context).apply { - cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA - } - } - - var lastScannedCode by remember { mutableStateOf("") } - - LaunchedEffect(Unit) { - val barcodeScanner = BarcodeScanning.getClient( - BarcodeScannerOptions.Builder() - .setBarcodeFormats(Barcode.FORMAT_QR_CODE) - .build() - ) - val executor = ContextCompat.getMainExecutor(context) - - cameraController.setImageAnalysisAnalyzer( - executor, - MlKitAnalyzer( - listOf(barcodeScanner), - CameraController.COORDINATE_SYSTEM_VIEW_REFERENCED, - executor - ) { result -> - val barcode = result.getValue(barcodeScanner)?.firstOrNull() - val code = barcode?.rawValue - if (!code.isNullOrEmpty() && code != lastScannedCode) { - lastScannedCode = code - onCodeDetected(code) - } - } - ) - cameraController.bindToLifecycle(lifecycleOwner) - } - - Box(modifier = Modifier.fillMaxSize()) { - AndroidView( - factory = { ctx -> - PreviewView(ctx).apply { - controller = cameraController - scaleType = PreviewView.ScaleType.FILL_CENTER - } - }, - modifier = Modifier.fillMaxSize() - ) - - IconButton( - onClick = onBackClicked, - modifier = Modifier - .padding(16.dp) - .align(Alignment.TopStart) - ) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_close_scanner), - tint = Color.White - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/ItemPosition.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/ItemPosition.kt deleted file mode 100644 index cc845e69..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/ItemPosition.kt +++ /dev/null @@ -1,5 +0,0 @@ -package org.monogram.presentation.core.ui - -enum class ItemPosition { - TOP, MIDDLE, BOTTOM, STANDALONE -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/PlaceholderAvatar.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/PlaceholderAvatar.kt deleted file mode 100644 index 0a407141..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/PlaceholderAvatar.kt +++ /dev/null @@ -1,32 +0,0 @@ -package org.monogram.presentation.core.ui - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.sp - -@Composable -fun PlaceholderAvatar( - name: String, - fontSize: Int, - color: Color, - modifier: Modifier = Modifier.fillMaxSize() -) { - Box( - modifier = modifier - .background(color.copy(alpha = 0.15f)), - contentAlignment = Alignment.Center - ) { - Text( - name.take(1).uppercase(), - style = MaterialTheme.typography.titleSmall.copy(fontSize = fontSize.sp), - color = color - ) - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/QRcode.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/QRcode.kt deleted file mode 100644 index fefb1bad..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/QRcode.kt +++ /dev/null @@ -1,154 +0,0 @@ -package org.monogram.presentation.core.ui - -import android.content.ClipData -import android.content.ContentValues -import android.content.Context -import android.content.Intent -import android.graphics.Bitmap -import android.graphics.Canvas -import android.graphics.Paint -import android.graphics.RectF -import android.os.Build -import android.provider.MediaStore -import android.widget.Toast -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.CornerRadius -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.geometry.Size -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.drawscope.DrawScope -import androidx.compose.ui.graphics.toArgb -import androidx.core.content.FileProvider -import com.google.zxing.BarcodeFormat -import com.google.zxing.EncodeHintType -import com.google.zxing.common.BitMatrix -import com.google.zxing.qrcode.QRCodeWriter -import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel -import java.io.File -import java.io.FileOutputStream -import androidx.compose.foundation.Canvas as ComposeCanvas -import org.monogram.presentation.R - -@Composable -fun StyledQRCode(content: String, modifier: Modifier, primaryColor: Color, backgroundColor: Color) { - val qrMatrix = remember(content) { generateQrMatrix(content) } - ComposeCanvas(modifier = modifier) { - val matrix = qrMatrix ?: return@ComposeCanvas - val matrixSize = matrix.width - val cellSize = size.width / matrixSize - - for (x in 0 until matrixSize) { - for (y in 0 until matrixSize) { - if (matrix.get(x, y) && !isPositionMarker(x, y, matrixSize)) { - drawRoundRect( - color = primaryColor, - topLeft = Offset(x * cellSize + (cellSize * 0.05f), y * cellSize + (cellSize * 0.05f)), - size = Size(cellSize * 0.9f, cellSize * 0.9f), - cornerRadius = CornerRadius(cellSize * 0.35f) - ) - } - } - } - val eyePositions = listOf(Offset(0f, 0f), Offset((matrixSize - 7).toFloat(), 0f), Offset(0f, (matrixSize - 7).toFloat())) - eyePositions.forEach { pos -> - drawCustomEye(Offset(pos.x * cellSize, pos.y * cellSize), cellSize, primaryColor, backgroundColor) - } - } -} -private val QrBackgroundColor = Color(0xFFEFF1E6) -private val QrDarkGreen = Color(0xFF3E4D36) -private val QrSurfaceShapeColor = Color(0xFFE3E6D8) -fun DrawScope.drawCustomEye(offset: Offset, cellSize: Float, primaryColor: Color, backgroundColor: Color) { - drawRoundRect(primaryColor, offset, Size(7 * cellSize, 7 * cellSize), CornerRadius(2 * cellSize)) - drawRoundRect(backgroundColor, Offset(offset.x + cellSize, offset.y + cellSize), Size(5 * cellSize, 5 * cellSize), CornerRadius(1.5f * cellSize)) - drawRoundRect(primaryColor, Offset(offset.x + 2 * cellSize, offset.y + 2 * cellSize), Size(3 * cellSize, 3 * cellSize), CornerRadius(0.8f * cellSize)) -} - -fun isPositionMarker(x: Int, y: Int, matrixSize: Int) = - (x < 7 && y < 7) || (x >= matrixSize - 7 && y < 7) || (x < 7 && y >= matrixSize - 7) - -fun generateQrMatrix(content: String): BitMatrix? = try { - val hints = mapOf(EncodeHintType.MARGIN to 0, EncodeHintType.ERROR_CORRECTION to ErrorCorrectionLevel.H) - QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, 25, 25, hints) -} catch (e: Exception) { null } - -fun generatePureBitmap(content: String, size: Int): Bitmap { - val bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888) - val canvas = Canvas(bitmap) - val paint = Paint(Paint.ANTI_ALIAS_FLAG) - - paint.color = QrSurfaceShapeColor.toArgb() - canvas.drawRoundRect(RectF(0f, 0f, size.toFloat(), size.toFloat()), size * 0.15f, size * 0.15f, paint) - - val matrix = generateQrMatrix(content) ?: return bitmap - val matrixSize = matrix.width - val cellSize = size.toFloat() / (matrixSize + 4) * 0.8f - val xOffset = (size - (matrixSize * cellSize)) / 2f - val yOffset = (size - (matrixSize * cellSize)) / 2.5f - - paint.color = QrDarkGreen.toArgb() - for (x in 0 until matrixSize) { - for (y in 0 until matrixSize) { - if (matrix.get(x, y) && !isPositionMarker(x, y, matrixSize)) { - val left = xOffset + x * cellSize + (cellSize * 0.05f) - val top = yOffset + y * cellSize + (cellSize * 0.05f) - canvas.drawRoundRect(RectF(left, top, left + cellSize * 0.9f, top + cellSize * 0.9f), cellSize * 0.35f, cellSize * 0.35f, paint) - } - } - } - - val eyePositions = listOf(Pair(0, 0), Pair(matrixSize - 7, 0), Pair(0, matrixSize - 7)) - eyePositions.forEach { (ex, ey) -> - val exPos = xOffset + ex * cellSize - val eyPos = yOffset + ey * cellSize - paint.color = QrDarkGreen.toArgb() - canvas.drawRoundRect(RectF(exPos, eyPos, exPos + 7 * cellSize, eyPos + 7 * cellSize), 2 * cellSize, 2 * cellSize, paint) - paint.color = QrSurfaceShapeColor.toArgb() - canvas.drawRoundRect(RectF(exPos + cellSize, eyPos + cellSize, exPos + 6 * cellSize, eyPos + 6 * cellSize), 1.5f * cellSize, 1.5f * cellSize, paint) - paint.color = QrDarkGreen.toArgb() - canvas.drawRoundRect(RectF(exPos + 2 * cellSize, eyPos + 2 * cellSize, exPos + 5 * cellSize, eyPos + 5 * cellSize), 0.8f * cellSize, 0.8f * cellSize, paint) - } - - paint.textSize = size * 0.05f - paint.textAlign = Paint.Align.CENTER - canvas.drawText(content, size / 2f, size * 0.9f, paint) - return bitmap -} - -fun saveBitmapToGallery(context: Context, bitmap: Bitmap) { - val filename = "QR_${System.currentTimeMillis()}.png" - val values = ContentValues().apply { - put(MediaStore.MediaColumns.DISPLAY_NAME, filename) - put(MediaStore.MediaColumns.MIME_TYPE, "image/png") - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) put(MediaStore.MediaColumns.RELATIVE_PATH, "Pictures/QR") - } - val uri = context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values) - uri?.let { - context.contentResolver.openOutputStream(it)?.use { out -> bitmap.compress(Bitmap.CompressFormat.PNG, 100, out) } - Toast.makeText(context, context.getString(R.string.qr_saved_to_gallery), Toast.LENGTH_SHORT).show() - } -} - -fun shareBitmap(context: Context, bitmap: Bitmap) { - try { - val file = File(context.cacheDir, "qr_share.png") - FileOutputStream(file).use { out -> - bitmap.compress(Bitmap.CompressFormat.PNG, 100, out) - out.flush() - } - val authority = "${context.packageName}.fileprovider" - val uri = FileProvider.getUriForFile(context, authority, file) - val intent = Intent(Intent.ACTION_SEND).apply { - type = "image/png" - putExtra(Intent.EXTRA_STREAM, uri) - clipData = ClipData.newRawUri("", uri) - addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) - } - context.startActivity(Intent.createChooser(intent, context.getString(R.string.qr_share_title))) - } catch (e: Exception) { - e.printStackTrace() - Toast.makeText(context, context.getString(R.string.qr_share_error, e.message), Toast.LENGTH_SHORT).show() - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/SettingsGroup.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/SettingsGroup.kt deleted file mode 100644 index 56cc5664..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/SettingsGroup.kt +++ /dev/null @@ -1,29 +0,0 @@ -package org.monogram.presentation.core.ui - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.ColumnScope -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Card -import androidx.compose.material3.CardDefaults -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp - -@Composable -fun SettingsGroup(content: @Composable ColumnScope.() -> Unit) { - Card( - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(24.dp), - colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.surfaceContainer - ), - elevation = CardDefaults.cardElevation(0.dp) - ) { - Column(modifier = Modifier.padding(vertical = 4.dp)) { - content() - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/SettingsItem.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/SettingsItem.kt deleted file mode 100644 index 508a3477..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/SettingsItem.kt +++ /dev/null @@ -1,144 +0,0 @@ -package org.monogram.presentation.core.ui - -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import coil3.compose.AsyncImage -import kotlinx.coroutines.flow.filter -import org.koin.compose.koinInject -import org.monogram.domain.models.FileModel -import org.monogram.domain.repository.MessageRepository -import java.io.File - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun SettingsItem( - icon: Any?, - iconBackgroundColor: Color, - title: String, - subtitle: String? = null, - position: ItemPosition, - onClick: () -> Unit, - onLongClick: (() -> Unit)? = null, - modifier: Modifier = Modifier -) { - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = modifier - .fillMaxWidth() - .clip(shape) - .combinedClickable( - onClick = onClick, - onLongClick = onLongClick - ) - ) { - Row( - modifier = Modifier - .padding(horizontal = 12.dp, vertical = 16.dp) - .heightIn(min = 48.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(40.dp) - .background(color = iconBackgroundColor.copy(0.15f), shape = CircleShape), - contentAlignment = Alignment.Center - ) { - if (icon is ImageVector) { - Icon( - imageVector = icon, - contentDescription = null, - modifier = Modifier.size(24.dp), - tint = iconBackgroundColor - ) - } else if (icon is FileModel) { - val messageRepository: MessageRepository = koinInject() - var localPath by remember(icon.id) { mutableStateOf(icon.local.path) } - - LaunchedEffect(icon.id) { - if (localPath.isEmpty() || !File(localPath).exists()) { - messageRepository.downloadFile(icon.id, 32) - messageRepository.messageDownloadCompletedFlow - .filter { it.first == icon.id.toLong() } - .collect { (_, _, completedPath) -> localPath = completedPath } - } - } - - if (localPath.isNotEmpty() && File(localPath).exists()) { - AsyncImage( - model = File(localPath), - contentDescription = null, - modifier = Modifier.size(24.dp), - contentScale = ContentScale.Crop, - colorFilter = ColorFilter.tint(iconBackgroundColor) - ) - } - } - } - Spacer(modifier = Modifier.width(16.dp)) - Column( - modifier = Modifier - .weight(1f) - .padding(vertical = 2.dp), - verticalArrangement = Arrangement.Center - ) { - Text( - text = title, - style = MaterialTheme.typography.titleMedium, - fontSize = 18.sp, - maxLines = 2, - overflow = TextOverflow.Ellipsis, - lineHeight = 22.sp - ) - subtitle?.let { - Text( - text = it, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 3, - overflow = TextOverflow.Ellipsis, - lineHeight = 18.sp - ) - } - } - } - } - Spacer(Modifier.size(2.dp)) -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/SettingsSwitchTile.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/SettingsSwitchTile.kt deleted file mode 100644 index 42ac2c18..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/SettingsSwitchTile.kt +++ /dev/null @@ -1,116 +0,0 @@ -package org.monogram.presentation.core.ui - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp - -@Composable -fun SettingsSwitchTile( - icon: ImageVector, - title: String, - subtitle: String? = null, - checked: Boolean, - iconColor: Color, - position: ItemPosition = ItemPosition.STANDALONE, - enabled: Boolean = true, - onCheckedChange: (Boolean) -> Unit, - onClick: (() -> Unit)? = null -) { - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Column { - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - .alpha(if (enabled) 1f else 0.5f) - .clickable(enabled = enabled) { - if (onClick != null) { - onClick() - } else { - onCheckedChange(!checked) - } - } - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 16.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(40.dp) - .background(color = iconColor.copy(0.15f), shape = CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = icon, - contentDescription = null, - modifier = Modifier.size(24.dp), - tint = iconColor - ) - } - Spacer(modifier = Modifier.width(16.dp)) - Column(modifier = Modifier.weight(1f)) { - Text( - text = title, - style = MaterialTheme.typography.titleMedium, - fontSize = 18.sp - ) - if (subtitle != null) { - Text( - text = subtitle, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - Switch( - checked = checked, - enabled = enabled, - onCheckedChange = onCheckedChange, - colors = SwitchDefaults.colors( - checkedThumbColor = MaterialTheme.colorScheme.onPrimary, - checkedTrackColor = MaterialTheme.colorScheme.primary, - uncheckedThumbColor = MaterialTheme.colorScheme.outline, - uncheckedTrackColor = MaterialTheme.colorScheme.surfaceContainerHighest, - ) - ) - } - } - if (position != ItemPosition.BOTTOM && position != ItemPosition.STANDALONE) { - Spacer(Modifier.height(2.dp)) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/SettingsTile.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/SettingsTile.kt deleted file mode 100644 index 6368d8c5..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/SettingsTile.kt +++ /dev/null @@ -1,103 +0,0 @@ -package org.monogram.presentation.core.ui - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp - -@Composable -fun SettingsTile( - icon: ImageVector, - title: String, - subtitle: String? = null, - iconColor: Color, - titleColor: Color = MaterialTheme.colorScheme.onSurface, - position: ItemPosition = ItemPosition.STANDALONE, - onClick: () -> Unit, - trailingContent: @Composable (() -> Unit)? = null -) { - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Column { - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - .clickable(onClick = onClick) - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 16.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(40.dp) - .background(color = iconColor.copy(0.15f), shape = CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = icon, - contentDescription = null, - modifier = Modifier.size(24.dp), - tint = iconColor - ) - } - Spacer(modifier = Modifier.width(16.dp)) - Column(modifier = Modifier.weight(1f)) { - Text( - text = title, - style = MaterialTheme.typography.titleMedium, - fontSize = 18.sp, - color = titleColor - ) - if (subtitle != null) { - Text( - text = subtitle, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - if (trailingContent != null) { - trailingContent() - } - } - } - if (position != ItemPosition.BOTTOM && position != ItemPosition.STANDALONE) { - Spacer(Modifier.height(2.dp)) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/Shader3DStar.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/Shader3DStar.kt deleted file mode 100644 index b2cfc2a3..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/Shader3DStar.kt +++ /dev/null @@ -1,446 +0,0 @@ -package org.monogram.presentation.core.ui - -import android.content.Context -import android.graphics.SurfaceTexture -import android.opengl.GLES20 -import android.opengl.Matrix -import android.os.SystemClock -import android.util.Base64 -import android.view.TextureView -import androidx.compose.animation.core.Animatable -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.spring -import androidx.compose.foundation.gestures.detectDragGestures -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.viewinterop.AndroidView -import kotlinx.coroutines.launch -import org.json.JSONObject -import java.nio.ByteBuffer -import java.nio.ByteOrder -import java.util.* -import javax.microedition.khronos.egl.EGL10 -import javax.microedition.khronos.egl.EGLConfig -import javax.microedition.khronos.egl.EGLContext -import kotlin.collections.iterator -import kotlin.math.cos -import kotlin.math.sin -import kotlin.math.sqrt - -@Composable -fun TelegramStarInteractive( - resId: Int, - starColor: Color = Color(0xFFFFD700), - alpha: Float = 1f -) { - val context = LocalContext.current - val geometry = remember(resId) { parseStarFromRaw(context, resId) } - - val rotX = remember { Animatable(0f) } - val rotY = remember { Animatable(0f) } - var isInteracting by remember { mutableStateOf(false) } - val scope = rememberCoroutineScope() - - val starColorFloats = remember(starColor) { - floatArrayOf(starColor.red, starColor.green, starColor.blue) - } - - val renderThreadRef = remember { mutableStateOf(null) } - - LaunchedEffect(isInteracting) { - if (!isInteracting) { - launch { - rotX.animateTo( - targetValue = 0f, - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioMediumBouncy - ) - ) - } - launch { - rotY.animateTo( - targetValue = 0f, - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioMediumBouncy - ) - ) - } - } - } - - AndroidView( - modifier = Modifier - .fillMaxSize() - .pointerInput(Unit) { - detectDragGestures( - onDragStart = { isInteracting = true }, - onDragEnd = { isInteracting = false }, - onDragCancel = { isInteracting = false } - ) { change, dragAmount -> - change.consume() - scope.launch { - rotX.snapTo(rotX.value + dragAmount.x * 0.4f) - rotY.snapTo(rotY.value + dragAmount.y * 0.4f) - } - } - }, - factory = { ctx -> - TextureView(ctx).apply { - isOpaque = false - surfaceTextureListener = object : TextureView.SurfaceTextureListener { - override fun onSurfaceTextureAvailable(st: SurfaceTexture, w: Int, h: Int) { - val thread = StarRenderThread(st, geometry).apply { - updateSize(w, h) - updateParams(rotX.value, rotY.value, starColorFloats, alpha) - start() - } - renderThreadRef.value = thread - } - - override fun onSurfaceTextureSizeChanged(st: SurfaceTexture, w: Int, h: Int) { - renderThreadRef.value?.updateSize(w, h) - } - - override fun onSurfaceTextureDestroyed(st: SurfaceTexture): Boolean { - renderThreadRef.value?.stopRendering() - renderThreadRef.value = null - return true - } - - override fun onSurfaceTextureUpdated(st: SurfaceTexture) {} - } - } - }, - update = { - renderThreadRef.value?.updateParams(rotX.value, rotY.value, starColorFloats, alpha) - } - ) -} - -data class StarParticle( - var x: Float = 0f, - var y: Float = 0f, - var z: Float = 0f, - var vx: Float = 0f, - var vy: Float = 0f, - var vz: Float = 0f, - var scale: Float = 1f, - var rotation: Float = 0f, - var rotSpeed: Float = 0f, - var life: Float = 1f, // 1.0 = full, 0.0 = dead - var active: Boolean = false -) - -class StarRenderThread( - private val surface: SurfaceTexture, - private val geometry: GltfGeometry -) : Thread() { - @Volatile private var running = true - @Volatile private var width = 1 - @Volatile private var height = 1 - @Volatile private var rotX = 0f - @Volatile private var rotY = 0f - @Volatile private var starColor = floatArrayOf(1f, 1f, 1f) - @Volatile private var alpha = 1f - - private val particles = Array(15) { StarParticle() } - private val random = Random() - private var lastFrameTime = 0L - - fun updateParams(rx: Float, ry: Float, sc: FloatArray, a: Float) { - rotX = rx; rotY = ry; starColor = sc; alpha = a - } - - fun updateSize(w: Int, h: Int) { - width = if (w > 0) w else 1 - height = if (h > 0) h else 1 - } - - fun stopRendering() { running = false } - - override fun run() { - val egl = EGLContext.getEGL() as EGL10 - val display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY) - egl.eglInitialize(display, null) - - val configSpec = intArrayOf( - EGL10.EGL_RED_SIZE, 8, EGL10.EGL_GREEN_SIZE, 8, EGL10.EGL_BLUE_SIZE, 8, - EGL10.EGL_ALPHA_SIZE, 8, EGL10.EGL_DEPTH_SIZE, 16, - EGL10.EGL_RENDERABLE_TYPE, 4, EGL10.EGL_NONE - ) - val configs = arrayOfNulls(1) - val numConfig = intArrayOf(0) - egl.eglChooseConfig(display, configSpec, configs, 1, numConfig) - val config = configs[0] ?: return - - val context = egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, intArrayOf(0x3098, 2, EGL10.EGL_NONE)) - val eglSurface = egl.eglCreateWindowSurface(display, config, surface, null) - egl.eglMakeCurrent(display, eglSurface, eglSurface, context) - - val vShaderCode = """ - uniform mat4 uMVPMatrix; - uniform mat4 uModelMatrix; - attribute vec4 vPosition; - attribute vec3 vNormal; - varying vec3 vFragNormal; - varying vec3 vFragPos; - void main() { - gl_Position = uMVPMatrix * vPosition; - vFragPos = vec3(uModelMatrix * vPosition); - vFragNormal = normalize(vec3(uModelMatrix * vec4(vNormal, 0.0))); - } - """.trimIndent() - - val fShaderCode = """ - precision mediump float; - uniform vec3 uBaseColor; - uniform float uAlpha; - varying vec3 vFragNormal; - varying vec3 vFragPos; - - void main() { - vec3 lightPos = vec3(20.0, 50.0, 100.0); - vec3 viewPos = vec3(0.0, 0.0, 110.0); - - vec3 norm = normalize(vFragNormal); - vec3 lightDir = normalize(lightPos - vFragPos); - vec3 viewDir = normalize(viewPos - vFragPos); - vec3 halfDir = normalize(lightDir + viewDir); - - float NdotL = dot(norm, lightDir); - float diff = NdotL * 0.6 + 0.4; - - float spec = pow(max(dot(norm, halfDir), 0.0), 16.0); - - vec3 ambient = uBaseColor * 0.5; - vec3 diffuse = uBaseColor * diff * 0.8; - vec3 specular = vec3(1.0, 0.98, 0.9) * spec * 0.8; - - gl_FragColor = vec4(ambient + diffuse + specular, uAlpha); - } - """.trimIndent() - - val program = GLES20.glCreateProgram().apply { - val vs = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER).also { GLES20.glShaderSource(it, vShaderCode); GLES20.glCompileShader(it) } - val fs = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER).also { GLES20.glShaderSource(it, fShaderCode); GLES20.glCompileShader(it) } - GLES20.glAttachShader(this, vs); GLES20.glAttachShader(this, fs); GLES20.glLinkProgram(this) - } - - val vertexBuffer = ByteBuffer.allocateDirect(geometry.vertices.size * 4).run { order(ByteOrder.nativeOrder()).asFloatBuffer().apply { put(geometry.vertices).position(0) } } - val normalBuffer = ByteBuffer.allocateDirect(geometry.normals.size * 4).run { order(ByteOrder.nativeOrder()).asFloatBuffer().apply { put(geometry.normals).position(0) } } - val indexBuffer = ByteBuffer.allocateDirect(geometry.indices.size * 2).run { order(ByteOrder.nativeOrder()).asShortBuffer().apply { put(geometry.indices).position(0) } } - - GLES20.glEnable(GLES20.GL_DEPTH_TEST) - GLES20.glEnable(GLES20.GL_BLEND) - GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA) - - val projectionMatrix = FloatArray(16) - val viewMatrix = FloatArray(16) - val modelMatrix = FloatArray(16) - val mvpMatrix = FloatArray(16) - - GLES20.glUseProgram(program) - val uMVPLoc = GLES20.glGetUniformLocation(program, "uMVPMatrix") - val uModelLoc = GLES20.glGetUniformLocation(program, "uModelMatrix") - val uColorLoc = GLES20.glGetUniformLocation(program, "uBaseColor") - val uAlphaLoc = GLES20.glGetUniformLocation(program, "uAlpha") - val posHandle = GLES20.glGetAttribLocation(program, "vPosition") - val normalHandle = GLES20.glGetAttribLocation(program, "vNormal") - - GLES20.glEnableVertexAttribArray(posHandle) - GLES20.glVertexAttribPointer(posHandle, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer) - GLES20.glEnableVertexAttribArray(normalHandle) - GLES20.glVertexAttribPointer(normalHandle, 3, GLES20.GL_FLOAT, false, 0, normalBuffer) - - lastFrameTime = SystemClock.uptimeMillis() - - while (running) { - val currentTime = SystemClock.uptimeMillis() - val dt = (currentTime - lastFrameTime) / 1000f - lastFrameTime = currentTime - - updateParticles(dt) - - GLES20.glClearColor(0f, 0f, 0f, 0f) - GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT or GLES20.GL_DEPTH_BUFFER_BIT) - - val curW = width - val curH = height - GLES20.glViewport(0, 0, curW, curH) - - val ratio = curW.toFloat() / curH - Matrix.perspectiveM(projectionMatrix, 0, 45f, ratio, 0.1f, 1000f) - Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, 110f, 0f, 0f, 0f, 0f, 1.0f, 0f) - - for (p in particles) { - if (p.active) { - Matrix.setIdentityM(modelMatrix, 0) - Matrix.translateM(modelMatrix, 0, p.x, p.y, p.z) - Matrix.scaleM(modelMatrix, 0, p.scale, p.scale, p.scale) - Matrix.rotateM(modelMatrix, 0, p.rotation, 0f, 0f, 1f) - - Matrix.multiplyMM(mvpMatrix, 0, viewMatrix, 0, modelMatrix, 0) - Matrix.multiplyMM(mvpMatrix, 0, projectionMatrix, 0, mvpMatrix, 0) - - GLES20.glUniformMatrix4fv(uMVPLoc, 1, false, mvpMatrix, 0) - GLES20.glUniformMatrix4fv(uModelLoc, 1, false, modelMatrix, 0) - - GLES20.glUniform3fv(uColorLoc, 1, starColor, 0) - GLES20.glUniform1f(uAlphaLoc, p.life) - - GLES20.glDrawElements( - GLES20.GL_TRIANGLES, - geometry.indices.size, - GLES20.GL_UNSIGNED_SHORT, - indexBuffer - ) - } - } - - Matrix.setRotateM(modelMatrix, 0, rotX, 0f, 1f, 0f) - Matrix.rotateM(modelMatrix, 0, rotY, 1f, 0f, 0f) - - Matrix.multiplyMM(mvpMatrix, 0, viewMatrix, 0, modelMatrix, 0) - Matrix.multiplyMM(mvpMatrix, 0, projectionMatrix, 0, mvpMatrix, 0) - - GLES20.glUniformMatrix4fv(uMVPLoc, 1, false, mvpMatrix, 0) - GLES20.glUniformMatrix4fv(uModelLoc, 1, false, modelMatrix, 0) - GLES20.glUniform3fv(uColorLoc, 1, starColor, 0) - GLES20.glUniform1f(uAlphaLoc, alpha) - - GLES20.glDrawElements(GLES20.GL_TRIANGLES, geometry.indices.size, GLES20.GL_UNSIGNED_SHORT, indexBuffer) - - egl.eglSwapBuffers(display, eglSurface) - try { sleep(16) } catch (e: Exception) {} - } - - egl.eglMakeCurrent(display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT) - egl.eglDestroySurface(display, eglSurface) - egl.eglDestroyContext(display, context) - egl.eglTerminate(display) - } - - private fun updateParticles(dt: Float) { - for (p in particles) { - if (p.active) { - p.x += p.vx * dt - p.y += p.vy * dt - p.z += p.vz * dt - p.rotation += p.rotSpeed * dt - p.life -= dt * 0.8f // Fade speed - - if (p.life <= 0f) { - p.active = false - } - } - } - - // 15% chance per frame (at 60fps = ~15 stars per second) - if (random.nextFloat() < 0.15f) { - spawnParticle() - } - } - - private fun spawnParticle() { - val p = particles.firstOrNull { !it.active } ?: return - - p.active = true - p.life = 1f - p.scale = 0.2f + random.nextFloat() * 0.15f - - p.x = (random.nextFloat() - 0.5f) * 5f - p.y = (random.nextFloat() - 0.5f) * 5f - p.z = -5f - - val angle = random.nextFloat() * Math.PI * 2.0 - val speed = 25f + random.nextFloat() * 15f - - p.vx = (cos(angle) * speed).toFloat() - p.vy = (sin(angle) * speed).toFloat() - p.vz = 0f - - p.rotation = random.nextFloat() * 360f - p.rotSpeed = (random.nextFloat() - 0.5f) * 200f - } -} - -fun parseStarFromRaw(context: Context, resId: Int): GltfGeometry { - val gltfString = context.resources.openRawResource(resId).bufferedReader().use { it.readText() } - val json = JSONObject(gltfString) - val bufferUri = json.getJSONArray("buffers").getJSONObject(0).getString("uri") - val bytes = Base64.decode(bufferUri.substringAfter("base64,"), Base64.DEFAULT) - val buffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN) - val indexCount = json.getJSONArray("accessors").getJSONObject(0).getInt("count") - val indexArray = ShortArray(indexCount) - buffer.position(0) - for (i in 0 until indexCount) indexArray[i] = buffer.short - val posCount = json.getJSONArray("accessors").getJSONObject(1).getInt("count") - val posOffset = 8680 - val stride = 32 - val vertexArray = FloatArray(posCount * 3) - val normalArray = FloatArray(posCount * 3) - - for (i in 0 until posCount) { - buffer.position(posOffset + (i * stride)) - vertexArray[i * 3] = buffer.float - vertexArray[i * 3 + 1] = buffer.float - vertexArray[i * 3 + 2] = buffer.float - normalArray[i * 3] = buffer.float - normalArray[i * 3 + 1] = buffer.float - normalArray[i * 3 + 2] = buffer.float - } - smoothNormals(vertexArray, normalArray, posCount) - return GltfGeometry(vertexArray, normalArray, indexArray) -} - -fun smoothNormals(vertices: FloatArray, normals: FloatArray, count: Int) { - val posMap = HashMap>() - for (i in 0 until count) { - val key = "${vertices[i * 3]},${vertices[i * 3 + 1]},${vertices[i * 3 + 2]}" - if (!posMap.containsKey(key)) posMap[key] = ArrayList() - posMap[key]?.add(i) - } - for ((_, indices) in posMap) { - var avgX = 0f - var avgY = 0f - var avgZ = 0f - for (idx in indices) { - avgX += normals[idx * 3]; avgY += normals[idx * 3 + 1]; avgZ += normals[idx * 3 + 2] - } - val length = sqrt((avgX * avgX + avgY * avgY + avgZ * avgZ).toDouble()).toFloat() - if (length > 0.00001f) { - avgX /= length; avgY /= length; avgZ /= length - } - for (idx in indices) { - normals[idx * 3] = avgX; normals[idx * 3 + 1] = avgY; normals[idx * 3 + 2] = avgZ - } - } -} - -data class GltfGeometry(val vertices: FloatArray, val normals: FloatArray, val indices: ShortArray) { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as GltfGeometry - - if (!vertices.contentEquals(other.vertices)) return false - if (!normals.contentEquals(other.normals)) return false - if (!indices.contentEquals(other.indices)) return false - - return true - } - - override fun hashCode(): Int { - var result = vertices.contentHashCode() - result = 31 * result + normals.contentHashCode() - result = 31 * result + indices.contentHashCode() - return result - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/Shimmer.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/Shimmer.kt deleted file mode 100644 index 7658e642..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/Shimmer.kt +++ /dev/null @@ -1,73 +0,0 @@ -package org.monogram.presentation.core.ui - -import androidx.compose.animation.core.* -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.drawBehind -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.RectangleShape -import androidx.compose.ui.graphics.Shape - -@Composable -fun rememberShimmerBrush( - durationMillis: Int = 1200, - shimmerWidthPx: Float = 340f, - initialOffset: Float = -600f, - targetOffset: Float = 1200f -): Brush { - val base = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.45f) - val transition = rememberInfiniteTransition(label = "shared_shimmer") - val offset by transition.animateFloat( - initialValue = initialOffset, - targetValue = targetOffset, - animationSpec = infiniteRepeatable( - animation = tween(durationMillis = durationMillis, easing = LinearEasing), - repeatMode = RepeatMode.Restart - ), - label = "shared_shimmer_offset" - ) - - return Brush.linearGradient( - colors = listOf(base, base.copy(alpha = 0.18f), base), - start = Offset(offset, 0f), - end = Offset(offset + shimmerWidthPx, 0f) - ) -} - -@Composable -fun Modifier.shimmerBackground( - shape: Shape = RectangleShape, - durationMillis: Int = 1200, - shimmerWidthPx: Float = 340f, - initialOffset: Float = -600f, - targetOffset: Float = 1200f -): Modifier { - val base = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.45f) - val transition = rememberInfiniteTransition(label = "shared_shimmer") - val offset = transition.animateFloat( - initialValue = initialOffset, - targetValue = targetOffset, - animationSpec = infiniteRepeatable( - animation = tween(durationMillis = durationMillis, easing = LinearEasing), - repeatMode = RepeatMode.Restart - ), - label = "shared_shimmer_offset" - ) - - return this - .clip(shape) - .drawBehind { - val shimmerOffset = offset.value - drawRect( - brush = Brush.linearGradient( - colors = listOf(base, base.copy(alpha = 0.18f), base), - start = Offset(shimmerOffset, 0f), - end = Offset(shimmerOffset + shimmerWidthPx, 0f) - ) - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/StickerSetItem.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/StickerSetItem.kt deleted file mode 100644 index 6e619a91..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/StickerSetItem.kt +++ /dev/null @@ -1,272 +0,0 @@ -package org.monogram.presentation.core.ui - -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.basicMarquee -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.DpOffset -import androidx.compose.ui.unit.dp -import kotlinx.coroutines.flow.firstOrNull -import org.koin.compose.koinInject -import org.monogram.domain.models.StickerSetModel -import org.monogram.domain.repository.StickerRepository -import org.monogram.presentation.R -import org.monogram.presentation.features.stickers.ui.view.StickerImage -import org.monogram.presentation.features.stickers.ui.view.StickerSkeleton - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun StickerSetItem( - stickerSet: StickerSetModel, - position: ItemPosition, - onClick: () -> Unit, - onToggle: () -> Unit, - onArchive: () -> Unit, - showReorder: Boolean = false -) { - val shape = remember(position) { getItemShape(position) } - var showMenu by remember { mutableStateOf(false) } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - .clickable(onClick = onClick) - ) { - Row( - modifier = Modifier - .padding(vertical = 12.dp, horizontal = 16.dp), - verticalAlignment = Alignment.CenterVertically - ) { - if (showReorder) { - Icon( - imageVector = Icons.Rounded.DragHandle, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f), - modifier = Modifier.size(20.dp) - ) - Spacer(modifier = Modifier.width(8.dp)) - } - - StickerThumbnail(stickerSet) - - Spacer(modifier = Modifier.width(16.dp)) - - Column(modifier = Modifier.weight(1f)) { - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = stickerSet.title, - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.SemiBold, - maxLines = 1, - modifier = Modifier - .weight(1f, fill = false) - .basicMarquee() - ) - if (stickerSet.isOfficial) { - Spacer(modifier = Modifier.width(6.dp)) - Icon( - imageVector = Icons.Rounded.Verified, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.size(16.dp) - ) - } - } - - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = stringResource(R.string.stickers_count_format, stickerSet.stickers.size), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - - if (stickerSet.isInstalled && stickerSet.isArchived) { - Spacer(modifier = Modifier.width(8.dp)) - Surface( - color = MaterialTheme.colorScheme.surfaceContainerHighest, - shape = RoundedCornerShape(4.dp), - ) { - Text( - text = stringResource(R.string.sticker_set_archived), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(horizontal = 6.dp, vertical = 2.dp) - ) - } - } - } - } - - Spacer(modifier = Modifier.width(8.dp)) - - if (stickerSet.isInstalled) { - Box { - IconButton(onClick = { showMenu = true }) { - Icon( - imageVector = Icons.Rounded.MoreVert, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - - StickerSetActionsMenu( - expanded = showMenu, - onDismiss = { showMenu = false }, - isArchived = stickerSet.isArchived, - onArchive = { - showMenu = false - onArchive() - }, - onRemove = { - showMenu = false - onToggle() - } - ) - } - } else { - FilledTonalButton( - onClick = onToggle, - contentPadding = PaddingValues(horizontal = 16.dp), - modifier = Modifier.height(36.dp) - ) { - Icon( - Icons.Rounded.Add, - contentDescription = null, - modifier = Modifier.size(18.dp) - ) - Spacer(modifier = Modifier.width(8.dp)) - Text( - text = stringResource(R.string.action_add_sticker_set), - style = MaterialTheme.typography.labelLarge - ) - } - } - } - } -} - -@Composable -private fun StickerSetActionsMenu( - expanded: Boolean, - onDismiss: () -> Unit, - isArchived: Boolean, - onArchive: () -> Unit, - onRemove: () -> Unit -) { - DropdownMenu( - expanded = expanded, - onDismissRequest = onDismiss, - offset = DpOffset(x = 0.dp, y = (-8).dp), - modifier = Modifier.background(MaterialTheme.colorScheme.surfaceContainerHigh) - ) { - DropdownMenuItem( - text = { Text(if (isArchived) stringResource(R.string.menu_unarchive) else stringResource(R.string.menu_archive)) }, - onClick = onArchive, - leadingIcon = { - Icon( - if (isArchived) Icons.Rounded.Unarchive else Icons.Rounded.Archive, - contentDescription = null - ) - } - ) - DropdownMenuItem( - text = { Text(stringResource(R.string.menu_remove_set)) }, - onClick = onRemove, - leadingIcon = { - Icon( - Icons.Rounded.DeleteOutline, - contentDescription = null, - tint = MaterialTheme.colorScheme.error - ) - }, - colors = MenuDefaults.itemColors( - textColor = MaterialTheme.colorScheme.error, - leadingIconColor = MaterialTheme.colorScheme.error - ) - ) - } -} - -@Composable -private fun StickerThumbnail(stickerSet: StickerSetModel) { - val stickerRepository = koinInject() - val firstSticker = stickerSet.stickers.firstOrNull() - val targetSticker = stickerSet.thumbnail ?: firstSticker - - var currentPath by remember(targetSticker) { mutableStateOf(targetSticker?.path) } - - LaunchedEffect(targetSticker) { - if (targetSticker != null && currentPath == null) { - currentPath = stickerRepository.getStickerFile(targetSticker.id).firstOrNull() - } - } - - val emoji = firstSticker?.emoji - - Surface( - modifier = Modifier.size(56.dp), - shape = RoundedCornerShape(16.dp), - color = MaterialTheme.colorScheme.surfaceContainerHigh - ) { - Box(contentAlignment = Alignment.Center) { - if (currentPath != null) { - StickerImage( - path = currentPath, - modifier = Modifier.size(48.dp), - animate = false - ) - } else if (targetSticker != null) { - StickerSkeleton(modifier = Modifier.size(48.dp)) - } else if (!emoji.isNullOrEmpty()) { - Text( - text = emoji, - style = MaterialTheme.typography.headlineSmall - ) - } else { - Icon( - Icons.Rounded.Image, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f), - modifier = Modifier.size(24.dp) - ) - } - } - } -} - -fun getItemShape(position: ItemPosition): Shape { - val cornerRadius = 20.dp - return when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 2.dp, - bottomEnd = 2.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(2.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 2.dp, - topEnd = 2.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/ToolBarUtil.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/ToolBarUtil.kt deleted file mode 100644 index 82c0417d..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/ToolBarUtil.kt +++ /dev/null @@ -1,122 +0,0 @@ -package org.monogram.presentation.core.ui - - -import android.os.Bundle -import androidx.compose.foundation.gestures.ScrollableDefaults -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.saveable.Saver -import androidx.compose.runtime.saveable.SaverScope -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.ui.Modifier -import androidx.compose.ui.input.nestedscroll.nestedScroll -import androidx.compose.ui.layout.Layout -import org.monogram.presentation.core.util.ScrollStrategy - - -@Stable -class CollapsingToolbarScaffoldState( - val toolbarState: CollapsingToolbarState, - initialOffsetY: Int = 0 -) { - val offsetY: Int - get() = offsetYState.value - - internal val offsetYState = mutableStateOf(initialOffsetY) -} - -private class CollapsingToolbarScaffoldStateSaver: Saver { - override fun restore(value: Bundle): CollapsingToolbarScaffoldState = - CollapsingToolbarScaffoldState( - CollapsingToolbarState(value.getInt("height", Int.MAX_VALUE)), - value.getInt("offsetY", 0) - ) - - override fun SaverScope.save(value: CollapsingToolbarScaffoldState): Bundle = - Bundle().apply { - putInt("height", value.toolbarState.height) - putInt("offsetY", value.offsetY) - } -} - -@Composable -fun rememberCollapsingToolbarScaffoldState( - toolbarState: CollapsingToolbarState = rememberCollapsingToolbarState() -): CollapsingToolbarScaffoldState { - return rememberSaveable(toolbarState, saver = CollapsingToolbarScaffoldStateSaver()) { - CollapsingToolbarScaffoldState(toolbarState) - } -} - -@Composable -fun CollapsingToolbarScaffold( - modifier: Modifier, - state: CollapsingToolbarScaffoldState, - scrollStrategy: ScrollStrategy, - enabled: Boolean = true, - toolbarModifier: Modifier = Modifier, - toolbar: @Composable CollapsingToolbarScope.() -> Unit, - body: @Composable () -> Unit -) { - val flingBehavior = ScrollableDefaults.flingBehavior() - - val nestedScrollConnection = remember(scrollStrategy, state) { - scrollStrategy.create(state.offsetYState, state.toolbarState, flingBehavior) - } - - val toolbarState = state.toolbarState - - Layout( - content = { - CollapsingToolbar( - modifier = toolbarModifier, - collapsingToolbarState = toolbarState - ) { - toolbar() - } - body() - }, - modifier = modifier - .then( - if (enabled) { - Modifier.nestedScroll(nestedScrollConnection) - } else { - Modifier - } - ) - ) { measurables, constraints -> - val toolbarConstraints = constraints.copy( - minWidth = 0, - minHeight = 0 - ) - val bodyConstraints = constraints.copy( - minWidth = 0, - minHeight = 0, - maxHeight = when (scrollStrategy) { - ScrollStrategy.ExitUntilCollapsed -> - (constraints.maxHeight - toolbarState.minHeight).coerceAtLeast(0) - - ScrollStrategy.EnterAlways, ScrollStrategy.EnterAlwaysCollapsed -> - constraints.maxHeight - } - ) - - val toolbarPlaceable = measurables[0].measure(toolbarConstraints) - val bodyPlaceables = - measurables.drop(1).map { it.measure(bodyConstraints) } - - val toolbarHeight = toolbarPlaceable.height - - val width = constraints.maxWidth - val height = constraints.maxHeight - - layout(width, height) { - bodyPlaceables.forEach { - it.place(0, toolbarHeight + state.offsetY) - } - toolbarPlaceable.place(0, state.offsetY) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/TypingDots.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/TypingDots.kt deleted file mode 100644 index a67e63d6..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/TypingDots.kt +++ /dev/null @@ -1,58 +0,0 @@ -package org.monogram.presentation.core.ui - -import androidx.compose.animation.core.* -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.LocalContentColor -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp - -@Composable -fun TypingDots( - modifier: Modifier = Modifier, - dotSize: Dp = 4.dp, - dotColor: Color = Color.Unspecified, - spacing: Dp = 2.dp -) { - val infiniteTransition = rememberInfiniteTransition(label = "TypingDots") - val color = if (dotColor == Color.Unspecified) LocalContentColor.current else dotColor - - Row( - modifier = modifier, - verticalAlignment = Alignment.Bottom, - horizontalArrangement = Arrangement.spacedBy(spacing) - ) { - repeat(3) { index -> - val alpha by infiniteTransition.animateFloat( - initialValue = 0.2f, - targetValue = 1f, - animationSpec = infiniteRepeatable( - animation = keyframes { - durationMillis = 600 - 0.2f at 0 - 1f at 300 - 0.2f at 600 - }, - repeatMode = RepeatMode.Restart, - initialStartOffset = StartOffset(index * 200) - ), - label = "DotAlpha" - ) - - Box( - modifier = Modifier - .size(dotSize) - .background(color.copy(alpha = alpha), CircleShape) - ) - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/UserProfileHeader.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/UserProfileHeader.kt deleted file mode 100644 index eb010cf6..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/UserProfileHeader.kt +++ /dev/null @@ -1,186 +0,0 @@ -package org.monogram.presentation.core.ui - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Favorite -import androidx.compose.material.icons.filled.Star -import androidx.compose.material.icons.rounded.Verified -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.geometry.Rect -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Shadow -import androidx.compose.ui.layout.boundsInRoot -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.UserModel -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.stickers.ui.view.StickerImage - -@Composable -fun UserProfileHeader( - userModel: UserModel, - avatarSize: Dp, - headerHeight: Dp, - avatarCornerPercent: Int, - contentPadding: PaddingValues, - currentRadius: Dp, - alpha: Float = 1f, - videoPlayerPool: VideoPlayerPool, - onStatusClick: (() -> Unit)? = null, - onStatusBoundsChanged: ((Rect) -> Unit)? = null -) { - val capHeight = 24.dp - - Box( - modifier = Modifier - .fillMaxWidth() - .padding(contentPadding) - ) { - Box( - modifier = Modifier - .fillMaxWidth() - .height(headerHeight) - .alpha(alpha) - ) { - Box(modifier = Modifier.align(Alignment.Center)) { - AvatarHeader( - path = userModel.avatarPath, - fallbackPath = userModel.personalAvatarPath, - name = "${userModel.firstName} ${userModel.lastName}", - size = avatarSize.coerceAtMost(headerHeight), - avatarCornerPercent = avatarCornerPercent, - videoPlayerPool = videoPlayerPool - ) - } - - val scrimColor = Color.Black.copy(alpha = 0.7f) - Box( - modifier = Modifier - .matchParentSize() - .alpha(alpha / 1.5f) - .background( - brush = Brush.verticalGradient( - colorStops = arrayOf( - 0.0f to scrimColor, - 0.15f to Color.Transparent, - 0.7f to Color.Transparent, - 1.0f to scrimColor - ) - ), - shape = RoundedCornerShape(avatarCornerPercent) - ) - ) - Row( - modifier = Modifier - .align(Alignment.BottomStart) - .padding(bottom = capHeight + 16.dp) - .padding(horizontal = 20.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - text = "${userModel.firstName} ${userModel.lastName ?: ""}".trim(), - style = MaterialTheme.typography.headlineLarge.copy( - shadow = Shadow( - color = Color.Black.copy(alpha = 0.5f), - offset = Offset(2f, 2f), - blurRadius = 8f - ) - ), - fontWeight = FontWeight.Bold, - color = Color.White - ) - - if (userModel.isVerified) { - Spacer(modifier = Modifier.width(6.dp)) - Icon( - imageVector = Icons.Rounded.Verified, - contentDescription = "Verified", - modifier = Modifier.size(28.dp), - tint = Color(0xFF31A6FD) - ) - } - - if (userModel.isSponsor) { - Spacer(modifier = Modifier.width(6.dp)) - Icon( - imageVector = Icons.Default.Favorite, - contentDescription = "Sponsor", - modifier = Modifier.size(28.dp), - tint = Color(0xFFE53935) - ) - } - - if (!userModel.statusEmojiPath.isNullOrEmpty()) { - Spacer(modifier = Modifier.width(6.dp)) - StickerImage( - path = userModel.statusEmojiPath, - modifier = Modifier - .size(26.dp) - .then( - if (onStatusBoundsChanged != null) { - Modifier.onGloballyPositioned { onStatusBoundsChanged(it.boundsInRoot()) } - } else { - Modifier - } - ) - .then( - if (onStatusClick != null) { - Modifier.clickable(onClick = onStatusClick) - } else { - Modifier - } - ), - animate = false - ) - } else if (userModel.isPremium) { - Spacer(modifier = Modifier.width(6.dp)) - Icon( - imageVector = Icons.Default.Star, - contentDescription = null, - modifier = Modifier - .size(28.dp) - .then( - if (onStatusBoundsChanged != null) { - Modifier.onGloballyPositioned { onStatusBoundsChanged(it.boundsInRoot()) } - } else { - Modifier - } - ) - .then( - if (onStatusClick != null) { - Modifier.clickable(onClick = onStatusClick) - } else { - Modifier - } - ), - tint = Color(0xFF31A6FD) - ) - } - } - } - - Box( - modifier = Modifier - .fillMaxWidth() - .height(capHeight) - .align(Alignment.BottomCenter) - .background( - color = MaterialTheme.colorScheme.background, - shape = RoundedCornerShape(topStart = currentRadius, topEnd = currentRadius) - ) - ) - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/core/ui/UsernamesTile.kt b/presentation/src/main/java/org/monogram/presentation/core/ui/UsernamesTile.kt deleted file mode 100644 index cccd076d..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/ui/UsernamesTile.kt +++ /dev/null @@ -1,158 +0,0 @@ -package org.monogram.presentation.core.ui - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.AlternateEmail -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.ClipboardManager -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.presentation.R - -@OptIn(ExperimentalLayoutApi::class) -@Composable -fun UsernamesTile( - activeUsernames: List, - collectibleUsernames: List, - disabledUsernames: List, - clipboardManager: ClipboardManager, - position: ItemPosition -) { - val allUsernames = (activeUsernames + collectibleUsernames + disabledUsernames).distinct() - val primaryUsername = - activeUsernames.firstOrNull() ?: collectibleUsernames.firstOrNull() ?: disabledUsernames.firstOrNull() - - if (primaryUsername == null) return - - val primaryColor = when { - activeUsernames.contains(primaryUsername) -> MaterialTheme.colorScheme.primary - collectibleUsernames.contains(primaryUsername) -> MaterialTheme.colorScheme.tertiary - else -> MaterialTheme.colorScheme.outline - } - - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - .clickable { clipboardManager.setText(AnnotatedString("@$primaryUsername")) } - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 16.dp), - verticalAlignment = Alignment.Top - ) { - Box( - modifier = Modifier - .size(40.dp) - .background(color = primaryColor.copy(0.15f), shape = CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.AlternateEmail, - contentDescription = null, - modifier = Modifier.size(24.dp), - tint = primaryColor - ) - } - Spacer(modifier = Modifier.width(16.dp)) - Column(modifier = Modifier.weight(1f)) { - Text( - text = "@$primaryUsername", - style = MaterialTheme.typography.titleMedium, - fontSize = 18.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - Text( - text = stringResource(R.string.username_label_core), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f) - ) - - val otherUsernames = allUsernames.filter { it != primaryUsername } - if (otherUsernames.isNotEmpty()) { - Spacer(modifier = Modifier.height(12.dp)) - FlowRow( - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - otherUsernames.forEach { username -> - val chipColor = when { - activeUsernames.contains(username) -> MaterialTheme.colorScheme.primary - collectibleUsernames.contains(username) -> MaterialTheme.colorScheme.tertiary - else -> MaterialTheme.colorScheme.outline - } - UsernameChip( - username = username, - color = chipColor, - onClick = { clipboardManager.setText(AnnotatedString("@$username")) } - ) - } - } - } - } - } - } - if (position != ItemPosition.BOTTOM && position != ItemPosition.STANDALONE) { - Spacer(Modifier.height(2.dp)) - } -} - -@Composable -private fun UsernameChip( - username: String, - color: Color, - onClick: () -> Unit -) { - Surface( - color = color.copy(alpha = 0.08f), - shape = RoundedCornerShape(8.dp), - modifier = Modifier - .clip(RoundedCornerShape(8.dp)) - .clickable(onClick = onClick) - ) { - Text( - text = "@$username", - modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp), - style = MaterialTheme.typography.bodySmall, - color = color, - fontWeight = FontWeight.SemiBold - ) - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/AppPreferences.kt b/presentation/src/main/java/org/monogram/presentation/core/util/AppPreferences.kt deleted file mode 100644 index 23c4986a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/AppPreferences.kt +++ /dev/null @@ -1,1082 +0,0 @@ -package org.monogram.presentation.core.util - -import android.content.Context -import android.content.SharedPreferences -import androidx.security.crypto.EncryptedSharedPreferences -import androidx.security.crypto.MasterKey -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.monogram.domain.repository.AppPreferencesProvider -import org.monogram.domain.repository.PushProvider - -enum class NightMode { - SYSTEM, LIGHT, DARK, SCHEDULED, BRIGHTNESS -} - -enum class EmojiStyle { - SYSTEM, APPLE, TWITTER, WINDOWS, CATMOJI, NOTO -} - -class AppPreferences( - private val context: Context, - private val externalScope: CoroutineScope -) : AppPreferencesProvider { - private val prefs: SharedPreferences = context.getSharedPreferences("monogram_prefs", Context.MODE_PRIVATE) - - private val masterKey = MasterKey.Builder(context) - .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) - .build() - - private val securePrefs: SharedPreferences = EncryptedSharedPreferences.create( - context, - "monogram_secure_prefs", - masterKey, - EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, - EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM - ) - - private val _fontSize = MutableStateFlow(prefs.getFloat(KEY_FONT_SIZE, 16f)) - val fontSize: StateFlow = _fontSize - - private val _letterSpacing = MutableStateFlow(prefs.getFloat(KEY_LETTER_SPACING, 0f)) - val letterSpacing: StateFlow = _letterSpacing - - private val _bubbleRadius = MutableStateFlow(prefs.getFloat(KEY_BUBBLE_RADIUS, 18f)) - val bubbleRadius: StateFlow = _bubbleRadius - - private val _wallpaper = MutableStateFlow(prefs.getString(KEY_WALLPAPER, null)) - val wallpaper: StateFlow = _wallpaper - - private val _isWallpaperBlurred = MutableStateFlow(prefs.getBoolean(KEY_WALLPAPER_BLURRED, false)) - val isWallpaperBlurred: StateFlow = _isWallpaperBlurred - - private val _wallpaperBlurIntensity = MutableStateFlow(prefs.getInt(KEY_WALLPAPER_BLUR_INTENSITY, 20)) - val wallpaperBlurIntensity: StateFlow = _wallpaperBlurIntensity - - private val _isWallpaperMoving = MutableStateFlow(prefs.getBoolean(KEY_WALLPAPER_MOVING, false)) - val isWallpaperMoving: StateFlow = _isWallpaperMoving - - private val _wallpaperDimming = MutableStateFlow(prefs.getInt(KEY_WALLPAPER_DIMMING, 0)) - val wallpaperDimming: StateFlow = _wallpaperDimming - - private val _isWallpaperGrayscale = MutableStateFlow(prefs.getBoolean(KEY_WALLPAPER_GRAYSCALE, false)) - val isWallpaperGrayscale: StateFlow = _isWallpaperGrayscale - - private val _isPlayerGesturesEnabled = MutableStateFlow(prefs.getBoolean(KEY_PLAYER_GESTURES_ENABLED, true)) - val isPlayerGesturesEnabled: StateFlow = _isPlayerGesturesEnabled - - private val _isPlayerDoubleTapSeekEnabled = MutableStateFlow(prefs.getBoolean(KEY_PLAYER_DOUBLE_TAP_SEEK, true)) - val isPlayerDoubleTapSeekEnabled: StateFlow = _isPlayerDoubleTapSeekEnabled - - private val _playerSeekDuration = MutableStateFlow(prefs.getInt(KEY_PLAYER_SEEK_DURATION, 10)) - val playerSeekDuration: StateFlow = _playerSeekDuration - - private val _isPlayerZoomEnabled = MutableStateFlow(prefs.getBoolean(KEY_PLAYER_ZOOM_ENABLED, true)) - val isPlayerZoomEnabled: StateFlow = _isPlayerZoomEnabled - - private val _nightMode = MutableStateFlow(NightMode.entries[prefs.getInt(KEY_NIGHT_MODE, NightMode.SYSTEM.ordinal)]) - val nightMode: StateFlow = _nightMode - - private val _isDynamicColorsEnabled = MutableStateFlow(prefs.getBoolean(KEY_DYNAMIC_COLORS, true)) - val isDynamicColorsEnabled: StateFlow = _isDynamicColorsEnabled - - private val _isAmoledThemeEnabled = MutableStateFlow(prefs.getBoolean(KEY_AMOLED_THEME, false)) - val isAmoledThemeEnabled: StateFlow = _isAmoledThemeEnabled - - private val _isCustomThemeEnabled = MutableStateFlow(prefs.getBoolean(KEY_CUSTOM_THEME_ENABLED, false)) - val isCustomThemeEnabled: StateFlow = _isCustomThemeEnabled - - private val _themePrimaryColor = MutableStateFlow(prefs.getInt(KEY_THEME_PRIMARY_COLOR, 0xFF3390EC.toInt())) - val themePrimaryColor: StateFlow = _themePrimaryColor - - private val _themeSecondaryColor = MutableStateFlow(prefs.getInt(KEY_THEME_SECONDARY_COLOR, 0xFF4C7599.toInt())) - val themeSecondaryColor: StateFlow = _themeSecondaryColor - - private val _themeTertiaryColor = MutableStateFlow(prefs.getInt(KEY_THEME_TERTIARY_COLOR, 0xFF00ACC1.toInt())) - val themeTertiaryColor: StateFlow = _themeTertiaryColor - - private val _themeBackgroundColor = - MutableStateFlow(prefs.getInt(KEY_THEME_BACKGROUND_COLOR, 0xFFFFFBFE.toInt())) - val themeBackgroundColor: StateFlow = _themeBackgroundColor - - private val _themeSurfaceColor = MutableStateFlow(prefs.getInt(KEY_THEME_SURFACE_COLOR, 0xFFFFFBFE.toInt())) - val themeSurfaceColor: StateFlow = _themeSurfaceColor - - private val _themePrimaryContainerColor = - MutableStateFlow(prefs.getInt(KEY_THEME_PRIMARY_CONTAINER_COLOR, 0xFFD4E3FF.toInt())) - val themePrimaryContainerColor: StateFlow = _themePrimaryContainerColor - - private val _themeSecondaryContainerColor = - MutableStateFlow(prefs.getInt(KEY_THEME_SECONDARY_CONTAINER_COLOR, 0xFFD0E4F7.toInt())) - val themeSecondaryContainerColor: StateFlow = _themeSecondaryContainerColor - - private val _themeTertiaryContainerColor = - MutableStateFlow(prefs.getInt(KEY_THEME_TERTIARY_CONTAINER_COLOR, 0xFFC4EEF4.toInt())) - val themeTertiaryContainerColor: StateFlow = _themeTertiaryContainerColor - - private val _themeSurfaceVariantColor = - MutableStateFlow(prefs.getInt(KEY_THEME_SURFACE_VARIANT_COLOR, 0xFFE1E2EC.toInt())) - val themeSurfaceVariantColor: StateFlow = _themeSurfaceVariantColor - - private val _themeOutlineColor = - MutableStateFlow(prefs.getInt(KEY_THEME_OUTLINE_COLOR, 0xFF757680.toInt())) - val themeOutlineColor: StateFlow = _themeOutlineColor - - private val _themeDarkPrimaryColor = - MutableStateFlow(prefs.getInt(KEY_THEME_DARK_PRIMARY_COLOR, 0xFF64B5F6.toInt())) - val themeDarkPrimaryColor: StateFlow = _themeDarkPrimaryColor - - private val _themeDarkSecondaryColor = - MutableStateFlow(prefs.getInt(KEY_THEME_DARK_SECONDARY_COLOR, 0xFF81A9CA.toInt())) - val themeDarkSecondaryColor: StateFlow = _themeDarkSecondaryColor - - private val _themeDarkTertiaryColor = - MutableStateFlow(prefs.getInt(KEY_THEME_DARK_TERTIARY_COLOR, 0xFF4DD0E1.toInt())) - val themeDarkTertiaryColor: StateFlow = _themeDarkTertiaryColor - - private val _themeDarkBackgroundColor = - MutableStateFlow(prefs.getInt(KEY_THEME_DARK_BACKGROUND_COLOR, 0xFF121212.toInt())) - val themeDarkBackgroundColor: StateFlow = _themeDarkBackgroundColor - - private val _themeDarkSurfaceColor = - MutableStateFlow(prefs.getInt(KEY_THEME_DARK_SURFACE_COLOR, 0xFF121212.toInt())) - val themeDarkSurfaceColor: StateFlow = _themeDarkSurfaceColor - - private val _themeDarkPrimaryContainerColor = - MutableStateFlow(prefs.getInt(KEY_THEME_DARK_PRIMARY_CONTAINER_COLOR, 0xFF224A77.toInt())) - val themeDarkPrimaryContainerColor: StateFlow = _themeDarkPrimaryContainerColor - - private val _themeDarkSecondaryContainerColor = - MutableStateFlow(prefs.getInt(KEY_THEME_DARK_SECONDARY_CONTAINER_COLOR, 0xFF334F65.toInt())) - val themeDarkSecondaryContainerColor: StateFlow = _themeDarkSecondaryContainerColor - - private val _themeDarkTertiaryContainerColor = - MutableStateFlow(prefs.getInt(KEY_THEME_DARK_TERTIARY_CONTAINER_COLOR, 0xFF1E636F.toInt())) - val themeDarkTertiaryContainerColor: StateFlow = _themeDarkTertiaryContainerColor - - private val _themeDarkSurfaceVariantColor = - MutableStateFlow(prefs.getInt(KEY_THEME_DARK_SURFACE_VARIANT_COLOR, 0xFF44474F.toInt())) - val themeDarkSurfaceVariantColor: StateFlow = _themeDarkSurfaceVariantColor - - private val _themeDarkOutlineColor = - MutableStateFlow(prefs.getInt(KEY_THEME_DARK_OUTLINE_COLOR, 0xFF8E9099.toInt())) - val themeDarkOutlineColor: StateFlow = _themeDarkOutlineColor - - private val _nightModeStartTime = MutableStateFlow(prefs.getString(KEY_NIGHT_MODE_START, "22:00") ?: "22:00") - val nightModeStartTime: StateFlow = _nightModeStartTime - - private val _nightModeEndTime = MutableStateFlow(prefs.getString(KEY_NIGHT_MODE_END, "07:00") ?: "07:00") - val nightModeEndTime: StateFlow = _nightModeEndTime - - private val _nightModeBrightnessThreshold = MutableStateFlow(prefs.getFloat(KEY_NIGHT_MODE_BRIGHTNESS, 0.2f)) - val nightModeBrightnessThreshold: StateFlow = _nightModeBrightnessThreshold - - private val _emojiStyle = - MutableStateFlow(EmojiStyle.entries[prefs.getInt(KEY_EMOJI_STYLE, EmojiStyle.SYSTEM.ordinal)]) - val emojiStyle: StateFlow = _emojiStyle - - private val _isAppleEmojiDownloaded = MutableStateFlow(prefs.getBoolean(KEY_APPLE_EMOJI_DOWNLOADED, false)) - val isAppleEmojiDownloaded: StateFlow = _isAppleEmojiDownloaded - - private val _isTwitterEmojiDownloaded = MutableStateFlow(prefs.getBoolean(KEY_TWITTER_EMOJI_DOWNLOADED, false)) - val isTwitterEmojiDownloaded: StateFlow = _isTwitterEmojiDownloaded - - private val _isWindowsEmojiDownloaded = MutableStateFlow(prefs.getBoolean(KEY_WINDOWS_EMOJI_DOWNLOADED, false)) - val isWindowsEmojiDownloaded: StateFlow = _isWindowsEmojiDownloaded - - private val _isCatmojiEmojiDownloaded = MutableStateFlow(prefs.getBoolean(KEY_CATMOJI_EMOJI_DOWNLOADED, false)) - val isCatmojiEmojiDownloaded: StateFlow = _isCatmojiEmojiDownloaded - - private val _isNotoEmojiDownloaded = MutableStateFlow(prefs.getBoolean(KEY_NOTO_EMOJI_DOWNLOADED, false)) - val isNotoEmojiDownloaded: StateFlow = _isNotoEmojiDownloaded - - private val _autoDownloadMobile = MutableStateFlow(prefs.getBoolean(KEY_AUTO_DOWNLOAD_MOBILE, true)) - override val autoDownloadMobile: StateFlow = _autoDownloadMobile - - private val _autoDownloadWifi = MutableStateFlow(prefs.getBoolean(KEY_AUTO_DOWNLOAD_WIFI, true)) - override val autoDownloadWifi: StateFlow = _autoDownloadWifi - - private val _autoDownloadRoaming = MutableStateFlow(prefs.getBoolean(KEY_AUTO_DOWNLOAD_ROAMING, false)) - override val autoDownloadRoaming: StateFlow = _autoDownloadRoaming - - private val _autoDownloadFiles = MutableStateFlow(prefs.getBoolean(KEY_AUTO_DOWNLOAD_FILES, false)) - override val autoDownloadFiles: StateFlow = _autoDownloadFiles - - private val _autoDownloadStickers = MutableStateFlow(prefs.getBoolean(KEY_AUTO_DOWNLOAD_STICKERS, true)) - override val autoDownloadStickers: StateFlow = _autoDownloadStickers - - private val _autoDownloadVideoNotes = MutableStateFlow(prefs.getBoolean(KEY_AUTO_DOWNLOAD_VIDEO_NOTES, true)) - override val autoDownloadVideoNotes: StateFlow = _autoDownloadVideoNotes - - private val _autoplayGifs = MutableStateFlow(prefs.getBoolean(KEY_AUTOPLAY_GIFS, true)) - val autoplayGifs: StateFlow = _autoplayGifs - - private val _autoplayVideos = MutableStateFlow(prefs.getBoolean(KEY_AUTOPLAY_VIDEOS, true)) - val autoplayVideos: StateFlow = _autoplayVideos - - private val _enableStreaming = MutableStateFlow(prefs.getBoolean(KEY_ENABLE_STREAMING, true)) - val enableStreaming: StateFlow = _enableStreaming - - private val _compressPhotos = MutableStateFlow(prefs.getBoolean(KEY_COMPRESS_PHOTOS, true)) - val compressPhotos: StateFlow = _compressPhotos - - private val _compressVideos = MutableStateFlow(prefs.getBoolean(KEY_COMPRESS_VIDEOS, true)) - val compressVideos: StateFlow = _compressVideos - - private val _cacheLimitSize = MutableStateFlow(prefs.getLong(KEY_CACHE_LIMIT_SIZE, 10L * 1024 * 1024 * 1024)) - val cacheLimitSize: StateFlow = _cacheLimitSize - - private val _autoClearCacheTime = MutableStateFlow(prefs.getInt(KEY_AUTO_CLEAR_CACHE_TIME, 7)) - val autoClearCacheTime: StateFlow = _autoClearCacheTime - - private val _privateChatsNotifications = MutableStateFlow(prefs.getBoolean(KEY_NOTIF_PRIVATE, true)) - override val privateChatsNotifications: StateFlow = _privateChatsNotifications - - private val _groupsNotifications = MutableStateFlow(prefs.getBoolean(KEY_NOTIF_GROUPS, true)) - override val groupsNotifications: StateFlow = _groupsNotifications - - private val _channelsNotifications = MutableStateFlow(prefs.getBoolean(KEY_NOTIF_CHANNELS, true)) - override val channelsNotifications: StateFlow = _channelsNotifications - - private val _inAppSounds = MutableStateFlow(prefs.getBoolean(KEY_IN_APP_SOUNDS, true)) - override val inAppSounds: StateFlow = _inAppSounds - - private val _inAppVibrate = MutableStateFlow(prefs.getBoolean(KEY_IN_APP_VIBRATE, true)) - override val inAppVibrate: StateFlow = _inAppVibrate - - private val _inAppPreview = MutableStateFlow(prefs.getBoolean(KEY_IN_APP_PREVIEW, true)) - override val inAppPreview: StateFlow = _inAppPreview - - private val _contactJoinedNotifications = MutableStateFlow(prefs.getBoolean(KEY_CONTACT_JOINED, true)) - override val contactJoinedNotifications: StateFlow = _contactJoinedNotifications - - private val _pinnedMessagesNotifications = MutableStateFlow(prefs.getBoolean(KEY_PINNED_MESSAGES, true)) - override val pinnedMessagesNotifications: StateFlow = _pinnedMessagesNotifications - - private val _backgroundServiceEnabled = MutableStateFlow(prefs.getBoolean(KEY_BACKGROUND_SERVICE_ENABLED, true)) - override val backgroundServiceEnabled: StateFlow = _backgroundServiceEnabled - - private val _isPowerSavingMode = MutableStateFlow(prefs.getBoolean(KEY_POWER_SAVING_MODE, false)) - override val isPowerSavingMode: StateFlow = _isPowerSavingMode - - private val _isWakeLockEnabled = MutableStateFlow(prefs.getBoolean(KEY_WAKE_LOCK_ENABLED, true)) - override val isWakeLockEnabled: StateFlow = _isWakeLockEnabled - - private val _hideForegroundNotification = - MutableStateFlow(prefs.getBoolean(KEY_HIDE_FOREGROUND_NOTIFICATION, false)) - override val hideForegroundNotification: StateFlow = _hideForegroundNotification - - private val _batteryOptimizationEnabled = - MutableStateFlow(prefs.getBoolean(KEY_BATTERY_OPTIMIZATION_ENABLED, false)) - override val batteryOptimizationEnabled: StateFlow = _batteryOptimizationEnabled - - private val _notificationVibrationPattern = - MutableStateFlow(prefs.getString(KEY_NOTIF_VIBRATION, "default") ?: "default") - override val notificationVibrationPattern: StateFlow = _notificationVibrationPattern - - private val _notificationPriority = MutableStateFlow(prefs.getInt(KEY_NOTIF_PRIORITY, 1)) - override val notificationPriority: StateFlow = _notificationPriority - - private val _repeatNotifications = MutableStateFlow(prefs.getInt(KEY_REPEAT_NOTIFICATIONS, 60)) - override val repeatNotifications: StateFlow = _repeatNotifications - - private val _showSenderOnly = MutableStateFlow(prefs.getBoolean(KEY_SHOW_SENDER_ONLY, false)) - override val showSenderOnly: StateFlow = _showSenderOnly - - private val _pushProvider = - MutableStateFlow(PushProvider.entries[prefs.getInt(KEY_PUSH_PROVIDER, PushProvider.FCM.ordinal)]) - override val pushProvider: StateFlow = _pushProvider - - private val _isArchivePinned = MutableStateFlow(prefs.getBoolean(KEY_IS_ARCHIVE_PINNED, true)) - override val isArchivePinned: StateFlow = _isArchivePinned - - private val _isArchiveAlwaysVisible = MutableStateFlow(prefs.getBoolean(KEY_IS_ARCHIVE_ALWAYS_VISIBLE, false)) - override val isArchiveAlwaysVisible: StateFlow = _isArchiveAlwaysVisible - - private val _showLinkPreviews = MutableStateFlow(prefs.getBoolean(KEY_SHOW_LINK_PREVIEWS, true)) - override val showLinkPreviews: StateFlow = _showLinkPreviews - - private val _isDragToBackEnabled = MutableStateFlow(prefs.getBoolean(KEY_DRAG_TO_BACK, true)) - val isDragToBackEnabled: StateFlow = _isDragToBackEnabled - - private val _isChatAnimationsEnabled = MutableStateFlow(prefs.getBoolean(KEY_CHAT_ANIMATIONS_ENABLED, true)) - override val isChatAnimationsEnabled: StateFlow = _isChatAnimationsEnabled - - private val _chatListMessageLines = MutableStateFlow(prefs.getInt(KEY_CHAT_LIST_MESSAGE_LINES, 1)) - override val chatListMessageLines: StateFlow = _chatListMessageLines - - private val _showChatListPhotos = MutableStateFlow(prefs.getBoolean(KEY_SHOW_CHAT_LIST_PHOTOS, true)) - override val showChatListPhotos: StateFlow = _showChatListPhotos - - private val _isAdBlockEnabled = MutableStateFlow(prefs.getBoolean(KEY_ADBLOCK_ENABLED, false)) - val isAdBlockEnabled: StateFlow = _isAdBlockEnabled - - private val _adBlockKeywords = MutableStateFlow(prefs.getStringSet(KEY_ADBLOCK_KEYWORDS, emptySet()) ?: emptySet()) - val adBlockKeywords: StateFlow> = _adBlockKeywords - - private val _adBlockWhitelistedChannels = MutableStateFlow( - prefs.getStringSet(KEY_ADBLOCK_WHITELISTED_CHANNELS, emptySet())?.mapNotNull { it.toLongOrNull() }?.toSet() - ?: emptySet() - ) - val adBlockWhitelistedChannels: StateFlow> = _adBlockWhitelistedChannels - - private val _enabledProxyId = - MutableStateFlow(if (prefs.contains(KEY_ENABLED_PROXY_ID)) prefs.getInt(KEY_ENABLED_PROXY_ID, 0) else null) - override val enabledProxyId: StateFlow = _enabledProxyId - - private val _isAutoBestProxyEnabled = MutableStateFlow(prefs.getBoolean(KEY_AUTO_BEST_PROXY, false)) - override val isAutoBestProxyEnabled: StateFlow = _isAutoBestProxyEnabled - - private val _isTelegaProxyEnabled = MutableStateFlow(prefs.getBoolean(KEY_TELEGA_PROXY, false)) - override val isTelegaProxyEnabled: StateFlow = _isTelegaProxyEnabled - - private val _telegaProxyUrls = MutableStateFlow(prefs.getStringSet(KEY_TELEGA_PROXY_URLS, emptySet()) ?: emptySet()) - override val telegaProxyUrls: StateFlow> = _telegaProxyUrls - - private val _preferIpv6 = MutableStateFlow(prefs.getBoolean(KEY_PREFER_IPV6, false)) - override val preferIpv6: StateFlow = _preferIpv6 - - private val _userProxyBackups = MutableStateFlow(prefs.getStringSet(KEY_USER_PROXY_BACKUPS, emptySet()) ?: emptySet()) - override val userProxyBackups: StateFlow> = _userProxyBackups - - private val _isBiometricEnabled = MutableStateFlow(securePrefs.getBoolean(KEY_BIOMETRIC_ENABLED, false)) - override val isBiometricEnabled: StateFlow = _isBiometricEnabled - - private val _passcode = MutableStateFlow(securePrefs.getString(KEY_PASSCODE, null)) - override val passcode: StateFlow = _passcode - - private val _isPermissionRequested = MutableStateFlow(prefs.getBoolean(KEY_PERMISSION_REQUESTED, false)) - override val isPermissionRequested: StateFlow = _isPermissionRequested - - private val _isSupportViewed = MutableStateFlow(prefs.getBoolean(KEY_SUPPORT_VIEWED, false)) - override val isSupportViewed: StateFlow = _isSupportViewed - - init { - if (_adBlockKeywords.value.isEmpty()) { - externalScope.launch { - loadBaseKeywords() - } - } - } - - private suspend fun loadBaseKeywords() { - val keywords = withContext(Dispatchers.IO) { - try { - context.assets.open("adblock_keywords.txt").bufferedReader().useLines { lines -> - lines.filter { it.isNotBlank() }.toSet() - } - } catch (e: Exception) { - setOf("erid", "#ad", "#реклама") - } - } - setAdBlockKeywords(keywords) - } - - fun setFontSize(size: Float) { - prefs.edit().putFloat(KEY_FONT_SIZE, size).apply() - _fontSize.value = size - } - - fun setLetterSpacing(spacing: Float) { - prefs.edit().putFloat(KEY_LETTER_SPACING, spacing).apply() - _letterSpacing.value = spacing - } - - fun setBubbleRadius(radius: Float) { - prefs.edit().putFloat(KEY_BUBBLE_RADIUS, radius).apply() - _bubbleRadius.value = radius - } - - fun setWallpaper(wallpaper: String?) { - prefs.edit().putString(KEY_WALLPAPER, wallpaper).apply() - _wallpaper.value = wallpaper - } - - fun setWallpaperBlurred(isBlurred: Boolean) { - prefs.edit().putBoolean(KEY_WALLPAPER_BLURRED, isBlurred).apply() - _isWallpaperBlurred.value = isBlurred - } - - fun setWallpaperBlurIntensity(intensity: Int) { - prefs.edit().putInt(KEY_WALLPAPER_BLUR_INTENSITY, intensity).apply() - _wallpaperBlurIntensity.value = intensity - } - - fun setWallpaperMoving(isMoving: Boolean) { - prefs.edit().putBoolean(KEY_WALLPAPER_MOVING, isMoving).apply() - _isWallpaperMoving.value = isMoving - } - - fun setWallpaperDimming(dimming: Int) { - prefs.edit().putInt(KEY_WALLPAPER_DIMMING, dimming).apply() - _wallpaperDimming.value = dimming - } - - fun setWallpaperGrayscale(isGrayscale: Boolean) { - prefs.edit().putBoolean(KEY_WALLPAPER_GRAYSCALE, isGrayscale).apply() - _isWallpaperGrayscale.value = isGrayscale - } - - fun setPlayerGesturesEnabled(enabled: Boolean) { - prefs.edit().putBoolean(KEY_PLAYER_GESTURES_ENABLED, enabled).apply() - _isPlayerGesturesEnabled.value = enabled - } - - fun setPlayerDoubleTapSeekEnabled(enabled: Boolean) { - prefs.edit().putBoolean(KEY_PLAYER_DOUBLE_TAP_SEEK, enabled).apply() - _isPlayerDoubleTapSeekEnabled.value = enabled - } - - fun setPlayerSeekDuration(duration: Int) { - prefs.edit().putInt(KEY_PLAYER_SEEK_DURATION, duration).apply() - _playerSeekDuration.value = duration - } - - fun setPlayerZoomEnabled(enabled: Boolean) { - prefs.edit().putBoolean(KEY_PLAYER_ZOOM_ENABLED, enabled).apply() - _isPlayerZoomEnabled.value = enabled - } - - fun setNightMode(mode: NightMode) { - prefs.edit().putInt(KEY_NIGHT_MODE, mode.ordinal).apply() - _nightMode.value = mode - } - - fun setDynamicColorsEnabled(enabled: Boolean) { - prefs.edit().putBoolean(KEY_DYNAMIC_COLORS, enabled).apply() - _isDynamicColorsEnabled.value = enabled - } - - fun setAmoledThemeEnabled(enabled: Boolean) { - prefs.edit().putBoolean(KEY_AMOLED_THEME, enabled).apply() - _isAmoledThemeEnabled.value = enabled - } - - fun setCustomThemeEnabled(enabled: Boolean) { - prefs.edit().putBoolean(KEY_CUSTOM_THEME_ENABLED, enabled).apply() - _isCustomThemeEnabled.value = enabled - } - - fun setThemePrimaryColor(color: Int) { - prefs.edit().putInt(KEY_THEME_PRIMARY_COLOR, color).apply() - _themePrimaryColor.value = color - } - - fun setThemeSecondaryColor(color: Int) { - prefs.edit().putInt(KEY_THEME_SECONDARY_COLOR, color).apply() - _themeSecondaryColor.value = color - } - - fun setThemeTertiaryColor(color: Int) { - prefs.edit().putInt(KEY_THEME_TERTIARY_COLOR, color).apply() - _themeTertiaryColor.value = color - } - - fun setThemeBackgroundColor(color: Int) { - prefs.edit().putInt(KEY_THEME_BACKGROUND_COLOR, color).apply() - _themeBackgroundColor.value = color - } - - fun setThemeSurfaceColor(color: Int) { - prefs.edit().putInt(KEY_THEME_SURFACE_COLOR, color).apply() - _themeSurfaceColor.value = color - } - - fun setThemePrimaryContainerColor(color: Int) { - prefs.edit().putInt(KEY_THEME_PRIMARY_CONTAINER_COLOR, color).apply() - _themePrimaryContainerColor.value = color - } - - fun setThemeSecondaryContainerColor(color: Int) { - prefs.edit().putInt(KEY_THEME_SECONDARY_CONTAINER_COLOR, color).apply() - _themeSecondaryContainerColor.value = color - } - - fun setThemeTertiaryContainerColor(color: Int) { - prefs.edit().putInt(KEY_THEME_TERTIARY_CONTAINER_COLOR, color).apply() - _themeTertiaryContainerColor.value = color - } - - fun setThemeSurfaceVariantColor(color: Int) { - prefs.edit().putInt(KEY_THEME_SURFACE_VARIANT_COLOR, color).apply() - _themeSurfaceVariantColor.value = color - } - - fun setThemeOutlineColor(color: Int) { - prefs.edit().putInt(KEY_THEME_OUTLINE_COLOR, color).apply() - _themeOutlineColor.value = color - } - - fun setThemeDarkPrimaryColor(color: Int) { - prefs.edit().putInt(KEY_THEME_DARK_PRIMARY_COLOR, color).apply() - _themeDarkPrimaryColor.value = color - } - - fun setThemeDarkSecondaryColor(color: Int) { - prefs.edit().putInt(KEY_THEME_DARK_SECONDARY_COLOR, color).apply() - _themeDarkSecondaryColor.value = color - } - - fun setThemeDarkTertiaryColor(color: Int) { - prefs.edit().putInt(KEY_THEME_DARK_TERTIARY_COLOR, color).apply() - _themeDarkTertiaryColor.value = color - } - - fun setThemeDarkBackgroundColor(color: Int) { - prefs.edit().putInt(KEY_THEME_DARK_BACKGROUND_COLOR, color).apply() - _themeDarkBackgroundColor.value = color - } - - fun setThemeDarkSurfaceColor(color: Int) { - prefs.edit().putInt(KEY_THEME_DARK_SURFACE_COLOR, color).apply() - _themeDarkSurfaceColor.value = color - } - - fun setThemeDarkPrimaryContainerColor(color: Int) { - prefs.edit().putInt(KEY_THEME_DARK_PRIMARY_CONTAINER_COLOR, color).apply() - _themeDarkPrimaryContainerColor.value = color - } - - fun setThemeDarkSecondaryContainerColor(color: Int) { - prefs.edit().putInt(KEY_THEME_DARK_SECONDARY_CONTAINER_COLOR, color).apply() - _themeDarkSecondaryContainerColor.value = color - } - - fun setThemeDarkTertiaryContainerColor(color: Int) { - prefs.edit().putInt(KEY_THEME_DARK_TERTIARY_CONTAINER_COLOR, color).apply() - _themeDarkTertiaryContainerColor.value = color - } - - fun setThemeDarkSurfaceVariantColor(color: Int) { - prefs.edit().putInt(KEY_THEME_DARK_SURFACE_VARIANT_COLOR, color).apply() - _themeDarkSurfaceVariantColor.value = color - } - - fun setThemeDarkOutlineColor(color: Int) { - prefs.edit().putInt(KEY_THEME_DARK_OUTLINE_COLOR, color).apply() - _themeDarkOutlineColor.value = color - } - - fun setNightModeStartTime(time: String) { - prefs.edit().putString(KEY_NIGHT_MODE_START, time).apply() - _nightModeStartTime.value = time - } - - fun setNightModeEndTime(time: String) { - prefs.edit().putString(KEY_NIGHT_MODE_END, time).apply() - _nightModeEndTime.value = time - } - - fun setNightModeBrightnessThreshold(threshold: Float) { - prefs.edit().putFloat(KEY_NIGHT_MODE_BRIGHTNESS, threshold).apply() - _nightModeBrightnessThreshold.value = threshold - } - - fun setEmojiStyle(style: EmojiStyle) { - prefs.edit().putInt(KEY_EMOJI_STYLE, style.ordinal).apply() - _emojiStyle.value = style - } - - fun setAppleEmojiDownloaded(downloaded: Boolean) { - prefs.edit().putBoolean(KEY_APPLE_EMOJI_DOWNLOADED, downloaded).apply() - _isAppleEmojiDownloaded.value = downloaded - } - - fun setTwitterEmojiDownloaded(downloaded: Boolean) { - prefs.edit().putBoolean(KEY_TWITTER_EMOJI_DOWNLOADED, downloaded).apply() - _isTwitterEmojiDownloaded.value = downloaded - } - - fun setWindowsEmojiDownloaded(downloaded: Boolean) { - prefs.edit().putBoolean(KEY_WINDOWS_EMOJI_DOWNLOADED, downloaded).apply() - _isWindowsEmojiDownloaded.value = downloaded - } - - fun setCatmojiEmojiDownloaded(downloaded: Boolean) { - prefs.edit().putBoolean(KEY_CATMOJI_EMOJI_DOWNLOADED, downloaded).apply() - _isCatmojiEmojiDownloaded.value = downloaded - } - - fun setNotoEmojiDownloaded(downloaded: Boolean) { - prefs.edit().putBoolean(KEY_NOTO_EMOJI_DOWNLOADED, downloaded).apply() - _isNotoEmojiDownloaded.value = downloaded - } - - override fun setAutoDownloadMobile(enabled: Boolean) { - prefs.edit().putBoolean(KEY_AUTO_DOWNLOAD_MOBILE, enabled).apply() - _autoDownloadMobile.value = enabled - } - - override fun setAutoDownloadWifi(enabled: Boolean) { - prefs.edit().putBoolean(KEY_AUTO_DOWNLOAD_WIFI, enabled).apply() - _autoDownloadWifi.value = enabled - } - - override fun setAutoDownloadRoaming(enabled: Boolean) { - prefs.edit().putBoolean(KEY_AUTO_DOWNLOAD_ROAMING, enabled).apply() - _autoDownloadRoaming.value = enabled - } - - override fun setAutoDownloadFiles(enabled: Boolean) { - prefs.edit().putBoolean(KEY_AUTO_DOWNLOAD_FILES, enabled).apply() - _autoDownloadFiles.value = enabled - } - - override fun setAutoDownloadStickers(enabled: Boolean) { - prefs.edit().putBoolean(KEY_AUTO_DOWNLOAD_STICKERS, enabled).apply() - _autoDownloadStickers.value = enabled - } - - override fun setAutoDownloadVideoNotes(enabled: Boolean) { - prefs.edit().putBoolean(KEY_AUTO_DOWNLOAD_VIDEO_NOTES, enabled).apply() - _autoDownloadVideoNotes.value = enabled - } - - fun setAutoplayGifs(enabled: Boolean) { - prefs.edit().putBoolean(KEY_AUTOPLAY_GIFS, enabled).apply() - _autoplayGifs.value = enabled - } - - fun setAutoplayVideos(enabled: Boolean) { - prefs.edit().putBoolean(KEY_AUTOPLAY_VIDEOS, enabled).apply() - _autoplayVideos.value = enabled - } - - fun setEnableStreaming(enabled: Boolean) { - prefs.edit().putBoolean(KEY_ENABLE_STREAMING, enabled).apply() - _enableStreaming.value = enabled - } - - fun setCompressPhotos(enabled: Boolean) { - prefs.edit().putBoolean(KEY_COMPRESS_PHOTOS, enabled).apply() - _compressPhotos.value = enabled - } - - fun setCompressVideos(enabled: Boolean) { - prefs.edit().putBoolean(KEY_COMPRESS_VIDEOS, enabled).apply() - _compressVideos.value = enabled - } - - fun setCacheLimitSize(size: Long) { - prefs.edit().putLong(KEY_CACHE_LIMIT_SIZE, size).apply() - _cacheLimitSize.value = size - } - - fun setAutoClearCacheTime(time: Int) { - prefs.edit().putInt(KEY_AUTO_CLEAR_CACHE_TIME, time).apply() - _autoClearCacheTime.value = time - } - - override fun setPrivateChatsNotifications(enabled: Boolean) { - prefs.edit().putBoolean(KEY_NOTIF_PRIVATE, enabled).apply() - _privateChatsNotifications.value = enabled - } - - override fun setGroupsNotifications(enabled: Boolean) { - prefs.edit().putBoolean(KEY_NOTIF_GROUPS, enabled).apply() - _groupsNotifications.value = enabled - } - - override fun setChannelsNotifications(enabled: Boolean) { - prefs.edit().putBoolean(KEY_NOTIF_CHANNELS, enabled).apply() - _channelsNotifications.value = enabled - } - - override fun setInAppSounds(enabled: Boolean) { - prefs.edit().putBoolean(KEY_IN_APP_SOUNDS, enabled).apply() - _inAppSounds.value = enabled - } - - override fun setInAppVibrate(enabled: Boolean) { - prefs.edit().putBoolean(KEY_IN_APP_VIBRATE, enabled).apply() - _inAppVibrate.value = enabled - } - - override fun setInAppPreview(enabled: Boolean) { - prefs.edit().putBoolean(KEY_IN_APP_PREVIEW, enabled).apply() - _inAppPreview.value = enabled - } - - override fun setContactJoinedNotifications(enabled: Boolean) { - prefs.edit().putBoolean(KEY_CONTACT_JOINED, enabled).apply() - _contactJoinedNotifications.value = enabled - } - - override fun setPinnedMessagesNotifications(enabled: Boolean) { - prefs.edit().putBoolean(KEY_PINNED_MESSAGES, enabled).apply() - _pinnedMessagesNotifications.value = enabled - } - - override fun setBackgroundServiceEnabled(enabled: Boolean) { - prefs.edit().putBoolean(KEY_BACKGROUND_SERVICE_ENABLED, enabled).apply() - _backgroundServiceEnabled.value = enabled - } - - override fun setPowerSavingMode(enabled: Boolean) { - prefs.edit().putBoolean(KEY_POWER_SAVING_MODE, enabled).apply() - _isPowerSavingMode.value = enabled - } - - override fun setWakeLockEnabled(enabled: Boolean) { - prefs.edit().putBoolean(KEY_WAKE_LOCK_ENABLED, enabled).apply() - _isWakeLockEnabled.value = enabled - } - - override fun setHideForegroundNotification(enabled: Boolean) { - prefs.edit().putBoolean(KEY_HIDE_FOREGROUND_NOTIFICATION, enabled).apply() - _hideForegroundNotification.value = enabled - } - - override fun setBatteryOptimizationEnabled(enabled: Boolean) { - prefs.edit().putBoolean(KEY_BATTERY_OPTIMIZATION_ENABLED, enabled).apply() - _batteryOptimizationEnabled.value = enabled - } - - override fun setNotificationVibrationPattern(pattern: String) { - prefs.edit().putString(KEY_NOTIF_VIBRATION, pattern).apply() - _notificationVibrationPattern.value = pattern - } - - override fun setNotificationPriority(priority: Int) { - prefs.edit().putInt(KEY_NOTIF_PRIORITY, priority).apply() - _notificationPriority.value = priority - } - - override fun setRepeatNotifications(minutes: Int) { - prefs.edit().putInt(KEY_REPEAT_NOTIFICATIONS, minutes).apply() - _repeatNotifications.value = minutes - } - - override fun setShowSenderOnly(enabled: Boolean) { - prefs.edit().putBoolean(KEY_SHOW_SENDER_ONLY, enabled).apply() - _showSenderOnly.value = enabled - } - - override fun setPushProvider(provider: PushProvider) { - prefs.edit().putInt(KEY_PUSH_PROVIDER, provider.ordinal).apply() - _pushProvider.value = provider - } - - override fun setArchivePinned(pinned: Boolean) { - prefs.edit().putBoolean(KEY_IS_ARCHIVE_PINNED, pinned).apply() - _isArchivePinned.value = pinned - } - - override fun setArchiveAlwaysVisible(enabled: Boolean) { - prefs.edit().putBoolean(KEY_IS_ARCHIVE_ALWAYS_VISIBLE, enabled).apply() - _isArchiveAlwaysVisible.value = enabled - } - - override fun setShowLinkPreviews(enabled: Boolean) { - prefs.edit().putBoolean(KEY_SHOW_LINK_PREVIEWS, enabled).apply() - _showLinkPreviews.value = enabled - } - - fun setDragToBackEnabled(enabled: Boolean) { - prefs.edit().putBoolean(KEY_DRAG_TO_BACK, enabled).apply() - _isDragToBackEnabled.value = enabled - } - - override fun setChatAnimationsEnabled(enabled: Boolean) { - prefs.edit().putBoolean(KEY_CHAT_ANIMATIONS_ENABLED, enabled).apply() - _isChatAnimationsEnabled.value = enabled - } - - override fun setChatListMessageLines(lines: Int) { - prefs.edit().putInt(KEY_CHAT_LIST_MESSAGE_LINES, lines).apply() - _chatListMessageLines.value = lines - } - - override fun setShowChatListPhotos(enabled: Boolean) { - prefs.edit().putBoolean(KEY_SHOW_CHAT_LIST_PHOTOS, enabled).apply() - _showChatListPhotos.value = enabled - } - - fun setAdBlockEnabled(enabled: Boolean) { - prefs.edit().putBoolean(KEY_ADBLOCK_ENABLED, enabled).apply() - _isAdBlockEnabled.value = enabled - } - - fun setAdBlockKeywords(keywords: Set) { - prefs.edit().putStringSet(KEY_ADBLOCK_KEYWORDS, keywords).apply() - _adBlockKeywords.value = keywords - } - - fun setAdBlockWhitelistedChannels(channels: Set) { - prefs.edit().putStringSet(KEY_ADBLOCK_WHITELISTED_CHANNELS, channels.map { it.toString() }.toSet()).apply() - _adBlockWhitelistedChannels.value = channels - } - - override fun setEnabledProxyId(proxyId: Int?) { - if (proxyId != null) { - prefs.edit().putInt(KEY_ENABLED_PROXY_ID, proxyId).apply() - } else { - prefs.edit().remove(KEY_ENABLED_PROXY_ID).apply() - } - _enabledProxyId.value = proxyId - } - - override fun setAutoBestProxyEnabled(enabled: Boolean) { - prefs.edit().putBoolean(KEY_AUTO_BEST_PROXY, enabled).apply() - _isAutoBestProxyEnabled.value = enabled - } - - override fun setTelegaProxyEnabled(enabled: Boolean) { - prefs.edit().putBoolean(KEY_TELEGA_PROXY, enabled).apply() - _isTelegaProxyEnabled.value = enabled - } - - override fun setTelegaProxyUrls(urls: Set) { - prefs.edit().putStringSet(KEY_TELEGA_PROXY_URLS, urls).apply() - _telegaProxyUrls.value = urls - } - - override fun setPreferIpv6(enabled: Boolean) { - prefs.edit().putBoolean(KEY_PREFER_IPV6, enabled).apply() - _preferIpv6.value = enabled - } - - override fun setUserProxyBackups(backups: Set) { - prefs.edit().putStringSet(KEY_USER_PROXY_BACKUPS, backups).apply() - _userProxyBackups.value = backups - } - - override fun setBiometricEnabled(enabled: Boolean) { - securePrefs.edit().putBoolean(KEY_BIOMETRIC_ENABLED, enabled).apply() - _isBiometricEnabled.value = enabled - } - - override fun setPasscode(passcode: String?) { - if (passcode != null) { - securePrefs.edit().putString(KEY_PASSCODE, passcode).apply() - } else { - securePrefs.edit().remove(KEY_PASSCODE).apply() - } - _passcode.value = passcode - } - - override fun setPermissionRequested(requested: Boolean) { - prefs.edit().putBoolean(KEY_PERMISSION_REQUESTED, requested).apply() - _isPermissionRequested.value = requested - } - - override fun clearPreferences() { - prefs.edit().clear().apply() - _fontSize.value = 16f - _bubbleRadius.value = 18f - _wallpaper.value = null - _isWallpaperBlurred.value = false - _wallpaperBlurIntensity.value = 20 - _isWallpaperMoving.value = false - _wallpaperDimming.value = 0 - _isWallpaperGrayscale.value = false - _isPlayerGesturesEnabled.value = true - _isPlayerDoubleTapSeekEnabled.value = true - _playerSeekDuration.value = 10 - _isPlayerZoomEnabled.value = true - _nightMode.value = NightMode.SYSTEM - _isDynamicColorsEnabled.value = true - _isAmoledThemeEnabled.value = false - _isCustomThemeEnabled.value = false - _themePrimaryColor.value = 0xFF3390EC.toInt() - _themeSecondaryColor.value = 0xFF4C7599.toInt() - _themeTertiaryColor.value = 0xFF00ACC1.toInt() - _themeBackgroundColor.value = 0xFFFFFBFE.toInt() - _themeSurfaceColor.value = 0xFFFFFBFE.toInt() - _themePrimaryContainerColor.value = 0xFFD4E3FF.toInt() - _themeSecondaryContainerColor.value = 0xFFD0E4F7.toInt() - _themeTertiaryContainerColor.value = 0xFFC4EEF4.toInt() - _themeSurfaceVariantColor.value = 0xFFE1E2EC.toInt() - _themeOutlineColor.value = 0xFF757680.toInt() - _themeDarkPrimaryColor.value = 0xFF64B5F6.toInt() - _themeDarkSecondaryColor.value = 0xFF81A9CA.toInt() - _themeDarkTertiaryColor.value = 0xFF4DD0E1.toInt() - _themeDarkBackgroundColor.value = 0xFF121212.toInt() - _themeDarkSurfaceColor.value = 0xFF121212.toInt() - _themeDarkPrimaryContainerColor.value = 0xFF224A77.toInt() - _themeDarkSecondaryContainerColor.value = 0xFF334F65.toInt() - _themeDarkTertiaryContainerColor.value = 0xFF1E636F.toInt() - _themeDarkSurfaceVariantColor.value = 0xFF44474F.toInt() - _themeDarkOutlineColor.value = 0xFF8E9099.toInt() - _nightModeStartTime.value = "22:00" - _nightModeEndTime.value = "07:00" - _nightModeBrightnessThreshold.value = 0.2f - _emojiStyle.value = EmojiStyle.SYSTEM - _isAppleEmojiDownloaded.value = false - _isTwitterEmojiDownloaded.value = false - _isWindowsEmojiDownloaded.value = false - _isCatmojiEmojiDownloaded.value = false - _isNotoEmojiDownloaded.value = false - _autoDownloadMobile.value = true - _autoDownloadWifi.value = true - _autoDownloadRoaming.value = false - _autoDownloadFiles.value = false - _autoDownloadStickers.value = true - _autoDownloadVideoNotes.value = true - _autoplayGifs.value = true - _autoplayVideos.value = true - _enableStreaming.value = true - _compressPhotos.value = true - _compressVideos.value = true - _cacheLimitSize.value = 10L * 1024 * 1024 * 1024 - _autoClearCacheTime.value = 7 - _privateChatsNotifications.value = true - _groupsNotifications.value = true - _channelsNotifications.value = true - _inAppSounds.value = true - _inAppVibrate.value = true - _inAppPreview.value = true - _contactJoinedNotifications.value = true - _pinnedMessagesNotifications.value = true - _backgroundServiceEnabled.value = true - _isPowerSavingMode.value = false - _isWakeLockEnabled.value = true - _hideForegroundNotification.value = false - _batteryOptimizationEnabled.value = false - _notificationVibrationPattern.value = "default" - _notificationPriority.value = 1 - _repeatNotifications.value = 60 - _showSenderOnly.value = false - _pushProvider.value = PushProvider.FCM - _isArchivePinned.value = true - _isArchiveAlwaysVisible.value = false - _showLinkPreviews.value = true - _isDragToBackEnabled.value = true - _isChatAnimationsEnabled.value = true - _chatListMessageLines.value = 1 - _showChatListPhotos.value = true - _isAdBlockEnabled.value = false - _adBlockKeywords.value = emptySet() - _adBlockWhitelistedChannels.value = emptySet() - _enabledProxyId.value = null - _isAutoBestProxyEnabled.value = false - _isTelegaProxyEnabled.value = false - _telegaProxyUrls.value = emptySet() - _preferIpv6.value = false - _userProxyBackups.value = emptySet() - _isPermissionRequested.value = false - } - - override fun clearSecurePreferences() { - securePrefs.edit().clear().apply() - _isBiometricEnabled.value = false - _passcode.value = null - } - - override fun setSupportViewed(viewed: Boolean) { - prefs.edit().putBoolean(KEY_SUPPORT_VIEWED, viewed).apply() - _isSupportViewed.value = viewed - } - - companion object { - private const val KEY_FONT_SIZE = "font_size" - private const val KEY_LETTER_SPACING = "letter_spacing" - private const val KEY_BUBBLE_RADIUS = "bubble_radius" - private const val KEY_WALLPAPER = "wallpaper" - private const val KEY_WALLPAPER_BLURRED = "wallpaper_blurred" - private const val KEY_WALLPAPER_BLUR_INTENSITY = "wallpaper_blur_intensity" - private const val KEY_WALLPAPER_MOVING = "wallpaper_moving" - private const val KEY_WALLPAPER_DIMMING = "wallpaper_dimming" - private const val KEY_WALLPAPER_GRAYSCALE = "wallpaper_grayscale" - private const val KEY_PLAYER_GESTURES_ENABLED = "player_gestures_enabled" - private const val KEY_PLAYER_DOUBLE_TAP_SEEK = "player_double_tap_seek" - private const val KEY_PLAYER_SEEK_DURATION = "player_seek_duration" - private const val KEY_PLAYER_ZOOM_ENABLED = "player_zoom_enabled" - private const val KEY_NIGHT_MODE = "night_mode" - private const val KEY_DYNAMIC_COLORS = "dynamic_colors" - private const val KEY_AMOLED_THEME = "amoled_theme" - private const val KEY_CUSTOM_THEME_ENABLED = "custom_theme_enabled" - private const val KEY_THEME_PRIMARY_COLOR = "theme_primary_color" - private const val KEY_THEME_SECONDARY_COLOR = "theme_secondary_color" - private const val KEY_THEME_TERTIARY_COLOR = "theme_tertiary_color" - private const val KEY_THEME_BACKGROUND_COLOR = "theme_background_color" - private const val KEY_THEME_SURFACE_COLOR = "theme_surface_color" - private const val KEY_THEME_PRIMARY_CONTAINER_COLOR = "theme_primary_container_color" - private const val KEY_THEME_SECONDARY_CONTAINER_COLOR = "theme_secondary_container_color" - private const val KEY_THEME_TERTIARY_CONTAINER_COLOR = "theme_tertiary_container_color" - private const val KEY_THEME_SURFACE_VARIANT_COLOR = "theme_surface_variant_color" - private const val KEY_THEME_OUTLINE_COLOR = "theme_outline_color" - private const val KEY_THEME_DARK_PRIMARY_COLOR = "theme_dark_primary_color" - private const val KEY_THEME_DARK_SECONDARY_COLOR = "theme_dark_secondary_color" - private const val KEY_THEME_DARK_TERTIARY_COLOR = "theme_dark_tertiary_color" - private const val KEY_THEME_DARK_BACKGROUND_COLOR = "theme_dark_background_color" - private const val KEY_THEME_DARK_SURFACE_COLOR = "theme_dark_surface_color" - private const val KEY_THEME_DARK_PRIMARY_CONTAINER_COLOR = "theme_dark_primary_container_color" - private const val KEY_THEME_DARK_SECONDARY_CONTAINER_COLOR = "theme_dark_secondary_container_color" - private const val KEY_THEME_DARK_TERTIARY_CONTAINER_COLOR = "theme_dark_tertiary_container_color" - private const val KEY_THEME_DARK_SURFACE_VARIANT_COLOR = "theme_dark_surface_variant_color" - private const val KEY_THEME_DARK_OUTLINE_COLOR = "theme_dark_outline_color" - private const val KEY_NIGHT_MODE_START = "night_mode_start" - private const val KEY_NIGHT_MODE_END = "night_mode_end" - private const val KEY_NIGHT_MODE_BRIGHTNESS = "night_mode_brightness" - private const val KEY_EMOJI_STYLE = "emoji_style" - private const val KEY_APPLE_EMOJI_DOWNLOADED = "apple_emoji_downloaded" - private const val KEY_TWITTER_EMOJI_DOWNLOADED = "twitter_emoji_downloaded" - private const val KEY_WINDOWS_EMOJI_DOWNLOADED = "windows_emoji_downloaded" - private const val KEY_CATMOJI_EMOJI_DOWNLOADED = "catmoji_emoji_downloaded" - private const val KEY_NOTO_EMOJI_DOWNLOADED = "noto_emoji_downloaded" - - private const val KEY_AUTO_DOWNLOAD_MOBILE = "auto_download_mobile" - private const val KEY_AUTO_DOWNLOAD_WIFI = "auto_download_wifi" - private const val KEY_AUTO_DOWNLOAD_ROAMING = "auto_download_roaming" - private const val KEY_AUTO_DOWNLOAD_FILES = "auto_download_files" - private const val KEY_AUTO_DOWNLOAD_STICKERS = "auto_download_stickers" - private const val KEY_AUTO_DOWNLOAD_VIDEO_NOTES = "auto_download_video_notes" - private const val KEY_AUTOPLAY_GIFS = "autoplay_gifs" - private const val KEY_AUTOPLAY_VIDEOS = "autoplay_videos" - private const val KEY_ENABLE_STREAMING = "enable_streaming" - private const val KEY_COMPRESS_PHOTOS = "compress_photos" - private const val KEY_COMPRESS_VIDEOS = "compress_videos" - - private const val KEY_CACHE_LIMIT_SIZE = "cache_limit_size" - private const val KEY_AUTO_CLEAR_CACHE_TIME = "auto_clear_cache_time" - - private const val KEY_NOTIF_PRIVATE = "notif_private" - private const val KEY_NOTIF_GROUPS = "notif_groups" - private const val KEY_NOTIF_CHANNELS = "notif_channels" - private const val KEY_IN_APP_SOUNDS = "in_app_sounds" - private const val KEY_IN_APP_VIBRATE = "in_app_vibrate" - private const val KEY_IN_APP_PREVIEW = "in_app_preview" - private const val KEY_CONTACT_JOINED = "contact_joined" - private const val KEY_PINNED_MESSAGES = "pinned_messages" - private const val KEY_BACKGROUND_SERVICE_ENABLED = "background_service_enabled" - private const val KEY_POWER_SAVING_MODE = "power_saving_mode" - private const val KEY_WAKE_LOCK_ENABLED = "wake_lock_enabled" - private const val KEY_HIDE_FOREGROUND_NOTIFICATION = "hide_foreground_notification" - private const val KEY_BATTERY_OPTIMIZATION_ENABLED = "battery_optimization_enabled" - private const val KEY_NOTIF_VIBRATION = "notif_vibration" - private const val KEY_NOTIF_PRIORITY = "notif_priority" - private const val KEY_REPEAT_NOTIFICATIONS = "repeat_notifications" - private const val KEY_SHOW_SENDER_ONLY = "show_sender_only" - private const val KEY_PUSH_PROVIDER = "push_provider" - - private const val KEY_IS_ARCHIVE_PINNED = "is_archive_pinned" - private const val KEY_IS_ARCHIVE_ALWAYS_VISIBLE = "is_archive_always_visible" - private const val KEY_SHOW_LINK_PREVIEWS = "show_link_previews" - private const val KEY_DRAG_TO_BACK = "drag_to_back" - private const val KEY_CHAT_ANIMATIONS_ENABLED = "chat_animations_enabled" - private const val KEY_CHAT_LIST_MESSAGE_LINES = "chat_list_message_lines" - private const val KEY_SHOW_CHAT_LIST_PHOTOS = "show_chat_list_photos" - - private const val KEY_ADBLOCK_ENABLED = "adblock_enabled" - private const val KEY_ADBLOCK_KEYWORDS = "adblock_keywords" - private const val KEY_ADBLOCK_WHITELISTED_CHANNELS = "adblock_whitelisted_channels" - - private const val KEY_ENABLED_PROXY_ID = "enabled_proxy_id" - private const val KEY_AUTO_BEST_PROXY = "auto_best_proxy" - private const val KEY_TELEGA_PROXY = "telega_proxy" - private const val KEY_TELEGA_PROXY_URLS = "telega_proxy_urls" - private const val KEY_PREFER_IPV6 = "prefer_ipv6" - private const val KEY_USER_PROXY_BACKUPS = "user_proxy_backups" - - private const val KEY_BIOMETRIC_ENABLED = "biometric_enabled" - private const val KEY_PASSCODE = "passcode" - - private const val KEY_PERMISSION_REQUESTED = "permission_requested" - private const val KEY_SUPPORT_VIEWED = "support_viewed" - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/AppUtils.kt b/presentation/src/main/java/org/monogram/presentation/core/util/AppUtils.kt deleted file mode 100644 index 1c880e8f..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/AppUtils.kt +++ /dev/null @@ -1,40 +0,0 @@ -package org.monogram.presentation.core.util - -import android.content.Context -import android.content.pm.PackageInfo -import android.content.pm.PackageManager -import android.os.Build - -object AppUtils { - private fun getPackageInfo(context: Context): PackageInfo? { - return try { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - context.packageManager.getPackageInfo(context.packageName, PackageManager.PackageInfoFlags.of(0)) - } else { - context.packageManager.getPackageInfo(context.packageName, 0) - } - } catch (e: Exception) { - null - } - } - - fun getVersionName(context: Context): String { - return getPackageInfo(context)?.versionName ?: "1.0.0" - } - - fun getVersionCode(context: Context): Long { - val packageInfo = getPackageInfo(context) ?: return 1L - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - packageInfo.longVersionCode - } else { - @Suppress("DEPRECATION") - packageInfo.versionCode.toLong() - } - } - - fun getFullVersionString(context: Context): String { - val name = getVersionName(context) - val code = getVersionCode(context) - return "$name ($code)" - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/BotPreferences.kt b/presentation/src/main/java/org/monogram/presentation/core/util/BotPreferences.kt deleted file mode 100644 index ca58d230..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/BotPreferences.kt +++ /dev/null @@ -1,68 +0,0 @@ -package org.monogram.presentation.core.util - -import android.content.Context -import android.content.SharedPreferences -import org.monogram.domain.repository.BotPreferencesProvider - -class BotPreferences(context: Context) : BotPreferencesProvider { - private val webappPermsPrefs: SharedPreferences = - context.getSharedPreferences("webapp_permissions", Context.MODE_PRIVATE) - private val webappStoragePrefs: SharedPreferences = - context.getSharedPreferences("webapp_storage", Context.MODE_PRIVATE) - private val webappBiometryPrefs: SharedPreferences = - context.getSharedPreferences("webapp_biometry", Context.MODE_PRIVATE) - - override fun getWebappPermission(botId: Long, permission: String): Boolean { - return webappPermsPrefs.getBoolean("${botId}_$permission", false) - } - - override fun setWebappPermission(botId: Long, permission: String, granted: Boolean) { - webappPermsPrefs.edit().putBoolean("${botId}_$permission", granted).apply() - } - - override fun isWebappPermissionRequested(botId: Long, permission: String): Boolean { - return webappPermsPrefs.contains("${botId}_$permission") - } - - override fun saveWebappData(key: String, value: String) { - webappStoragePrefs.edit().putString(key, value).apply() - } - - override fun getWebappData(key: String): String? { - return webappStoragePrefs.getString(key, null) - } - - override fun getWebappData(keys: List): Map { - return keys.associateWith { webappStoragePrefs.getString(it, null) } - } - - override fun deleteWebappData(key: String) { - webappStoragePrefs.edit().remove(key).apply() - } - - override fun deleteWebappData(keys: List) { - val editor = webappStoragePrefs.edit() - keys.forEach { editor.remove(it) } - editor.apply() - } - - override fun getWebappDataKeys(): List { - return webappStoragePrefs.all.keys.toList() - } - - override fun getWebappBiometryDeviceId(botId: Long): String? { - return webappBiometryPrefs.getString("device_id_$botId", null) - } - - override fun saveWebappBiometryDeviceId(botId: Long, deviceId: String) { - webappBiometryPrefs.edit().putString("device_id_$botId", deviceId).apply() - } - - override fun isWebappBiometryAccessRequested(): Boolean { - return webappBiometryPrefs.getBoolean("access_requested", false) - } - - override fun setWebappBiometryAccessRequested(requested: Boolean) { - webappBiometryPrefs.edit().putBoolean("access_requested", requested).apply() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/CachePreferences.kt b/presentation/src/main/java/org/monogram/presentation/core/util/CachePreferences.kt deleted file mode 100644 index d6f7f69a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/CachePreferences.kt +++ /dev/null @@ -1,142 +0,0 @@ -package org.monogram.presentation.core.util - -import android.content.Context -import android.content.SharedPreferences -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.serialization.json.Json -import org.monogram.domain.models.AttachMenuBotModel -import org.monogram.domain.models.FolderModel -import org.monogram.domain.models.GifModel -import org.monogram.domain.models.RecentEmojiModel -import org.monogram.domain.models.StickerSetModel -import org.monogram.domain.repository.CacheProvider - -class CachePreferences(private val context: Context) : CacheProvider { - private val prefs: SharedPreferences = context.getSharedPreferences("monogram_cache", Context.MODE_PRIVATE) - - private val _recentEmojis = MutableStateFlow>(emptyList()) - override val recentEmojis: StateFlow> = _recentEmojis - - private val _searchHistory = MutableStateFlow>(emptyList()) - override val searchHistory: StateFlow> = _searchHistory - - private val _chatFolders = MutableStateFlow>(emptyList()) - override val chatFolders: StateFlow> = _chatFolders - - private val _attachBots = MutableStateFlow>(emptyList()) - override val attachBots: StateFlow> = _attachBots - - private val _cachedSimCountryIso = MutableStateFlow(null) - override val cachedSimCountryIso: StateFlow = _cachedSimCountryIso - - private val _savedGifs = MutableStateFlow(getSavedGifsFromPrefs()) - override val savedGifs: StateFlow> = _savedGifs - - private val _installedStickerSets = MutableStateFlow>(emptyList()) - override val installedStickerSets: StateFlow> = _installedStickerSets - - private val _customEmojiStickerSets = MutableStateFlow>(emptyList()) - override val customEmojiStickerSets: StateFlow> = _customEmojiStickerSets - - override fun addRecentEmoji(recentEmoji: RecentEmojiModel) { - val current = _recentEmojis.value.toMutableList() - current.removeIf { it.emoji == recentEmoji.emoji && it.sticker?.id == recentEmoji.sticker?.id } - current.add(0, recentEmoji) - if (current.size > 50) { - current.removeAt(current.lastIndex) - } - _recentEmojis.value = current - } - - override fun clearRecentEmojis() { - _recentEmojis.value = emptyList() - } - - override fun setRecentEmojis(emojis: List) { - _recentEmojis.value = emojis - } - - override fun addSearchChatId(chatId: Long) { - val current = _searchHistory.value.toMutableList() - current.remove(chatId) - current.add(0, chatId) - if (current.size > 40) { - current.removeAt(current.lastIndex) - } - _searchHistory.value = current - } - - override fun removeSearchChatId(chatId: Long) { - val current = _searchHistory.value.toMutableList() - if (current.remove(chatId)) { - _searchHistory.value = current - } - } - - override fun clearSearchHistory() { - _searchHistory.value = emptyList() - } - - override fun setSearchHistory(history: List) { - _searchHistory.value = history - } - - override fun setChatFolders(folders: List) { - _chatFolders.value = folders - } - - override fun setAttachBots(bots: List) { - _attachBots.value = bots - } - - override fun setCachedSimCountryIso(iso: String?) { - _cachedSimCountryIso.value = iso - } - - override fun saveChatScrollPosition(chatId: Long, messageId: Long) { - prefs.edit().putLong("chat_scroll_$chatId", messageId).apply() - } - - override fun getChatScrollPosition(chatId: Long): Long { - return prefs.getLong("chat_scroll_$chatId", 0L) - } - - override fun setSavedGifs(gifs: List) { - prefs.edit().putString(KEY_SAVED_GIFS, Json.encodeToString(gifs)).apply() - _savedGifs.value = gifs - } - - override fun setInstalledStickerSets(sets: List) { - _installedStickerSets.value = sets - } - - override fun setCustomEmojiStickerSets(sets: List) { - _customEmojiStickerSets.value = sets - } - - override fun clearAll() { - prefs.edit().clear().apply() - _recentEmojis.value = emptyList() - _searchHistory.value = emptyList() - _chatFolders.value = emptyList() - _attachBots.value = emptyList() - _cachedSimCountryIso.value = null - _savedGifs.value = emptyList() - _installedStickerSets.value = emptyList() - _customEmojiStickerSets.value = emptyList() - } - - private fun getSavedGifsFromPrefs(): List { - val json = prefs.getString(KEY_SAVED_GIFS, null) ?: return emptyList() - return try { - Json.decodeFromString(json) - } catch (e: Exception) { - emptyList() - } - } - - companion object { - private const val KEY_SAVED_GIFS = "saved_gifs" - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/ColorUtils.kt b/presentation/src/main/java/org/monogram/presentation/core/util/ColorUtils.kt deleted file mode 100644 index 7a6b3c5b..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/ColorUtils.kt +++ /dev/null @@ -1,17 +0,0 @@ -package org.monogram.presentation.core.util - -import androidx.compose.ui.graphics.Color -import kotlin.math.abs - - -fun generateColorFromHash(name: String): Color { - val hash = name.hashCode() - val colors = listOf( - Color(0xFFE57373), Color(0xFFF06292), Color(0xFFBA68C8), - Color(0xFF9575CD), Color(0xFF7986CB), Color(0xFF64B5F6), - Color(0xFF4FC3F7), Color(0xFF4DD0E1), Color(0xFF4DB6AC), - Color(0xFF81C784), Color(0xFFAED581), Color(0xFFFFD54F), - Color(0xFFFFB74D), Color(0xFFFF8A65) - ) - return colors[abs(hash) % colors.size] -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/CoroutineCatching.kt b/presentation/src/main/java/org/monogram/presentation/core/util/CoroutineCatching.kt deleted file mode 100644 index 8cc052e0..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/CoroutineCatching.kt +++ /dev/null @@ -1,25 +0,0 @@ -package org.monogram.presentation.core.util - -import kotlinx.coroutines.CancellationException - -inline fun coRunCatching(block: () -> R): Result { - return try { - Result.success(block()) - } catch (e: Throwable) { - if (e is CancellationException) { - throw e - } - Result.failure(e) - } -} - -inline fun T.coRunCatching(block: T.() -> R): Result { - return try { - Result.success(block()) - } catch (e: Throwable) { - if (e is CancellationException) { - throw e - } - Result.failure(e) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/CoroutineExtensions.kt b/presentation/src/main/java/org/monogram/presentation/core/util/CoroutineExtensions.kt deleted file mode 100644 index e9222c95..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/CoroutineExtensions.kt +++ /dev/null @@ -1,19 +0,0 @@ -package org.monogram.presentation.core.util - -import com.arkivanov.essenty.lifecycle.Lifecycle -import com.arkivanov.essenty.lifecycle.LifecycleOwner -import com.arkivanov.essenty.lifecycle.doOnDestroy -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.cancel -import kotlin.coroutines.CoroutineContext - -fun Lifecycle.coroutineScope(context: CoroutineContext = Dispatchers.Main.immediate): CoroutineScope { - val scope = CoroutineScope(context + SupervisorJob()) - doOnDestroy(scope::cancel) - return scope -} - -val LifecycleOwner.componentScope: CoroutineScope - get() = lifecycle.coroutineScope() diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/CountryUtil.kt b/presentation/src/main/java/org/monogram/presentation/core/util/CountryUtil.kt deleted file mode 100644 index cb90cb69..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/CountryUtil.kt +++ /dev/null @@ -1,176 +0,0 @@ -package org.monogram.presentation.core.util - -import org.monogram.presentation.core.util.Country.Companion.FALLBACK_LENGTH - - -/** - * Object representation of selected country - * - * @property name country name - * @property code country numeric code (for example, 7 or 380) - * @property iso country ISO code (for example, RU, UA) - * @property flagEmoji Unicode emoji symbol matching this country - * @property mask optional mask for this number (without country code), can be `null` - **/ -data class Country( - val name: String, - val code: String, - val iso: String, - val flagEmoji: String, - val mask: String? = null -) { - companion object { - private const val FALLBACK_LENGTH = 5 - private const val MASK_CHAR = 'X' - } - - /** - * Get minimum number of digits based on country mask - * - * @return number of digits according to the mask, or [FALLBACK_LENGTH], when mask is too low or empty - **/ - fun getMobileNumberLength(): Int { - val maskChars = mask?.filter { it == MASK_CHAR }?.takeIf { it.length >= FALLBACK_LENGTH } - return maskChars?.length ?: FALLBACK_LENGTH - } -} - -/** - * An object to get and manage countries - **/ -object CountryManager { - private var countries: List = emptyList() - - /** - * @return list of available countries, or empty list, if no valid data present - **/ - fun getCountries(): List { - if (countries.isNotEmpty()) return countries - - try { - val inputStream = javaClass.getResourceAsStream("/countries.txt") ?: return emptyList() - - countries = inputStream.bufferedReader().useLines { lines -> - lines.mapNotNull { line -> - val parts = line.split(";") - if (parts.size >= 3) { - val code = parts[0] - val iso = parts[1] - val name = when (iso) { - "YL" -> "Telegram" - "FT" -> "Fragment Number" - else -> parts[2] - } - val mask = parts.getOrNull(3) - Country( - name = name, - code = code, - iso = iso, - flagEmoji = countryCodeToEmoji(iso), - mask = mask - ) - } else null - }.toList() - } - } catch (e: Exception) { - e.printStackTrace() - } - return countries - } - - /** - * Get country based on phone number - * - * @param phone phone to check - * @return [Country] object associated with this phone - **/ - fun getCountryForPhone(phone: String): Country? { - val digits = phone.filter { it.isDigit() } - if (digits.isEmpty()) return null - - val allCountries = getCountries() - - val matches = allCountries.filter { digits.startsWith(it.code) } - if (matches.isEmpty()) return null - - if (matches.size == 1) return matches[0] - - - // 1. +7 Zone (Russia / Kazakhstan) - if (digits.startsWith("7")) { - val nextDigit = digits.getOrNull(1) - return if (nextDigit == '7' || nextDigit == '6' || nextDigit == '0') { - matches.find { it.iso == "KZ" } ?: matches.find { it.iso == "RU" } ?: matches[0] - } else { - matches.find { it.iso == "RU" } ?: matches.find { it.iso == "KZ" } ?: matches[0] - } - } - - // 2. +1 Zone (North America - USA, Canada, Caribbean, etc.) - if (digits.startsWith("1")) { - // Check for longer codes first (e.g., +1 876 for Jamaica) - val specificMatch = matches.filter { it.code.length > 1 } - .maxByOrNull { it.code.length } - if (specificMatch != null) return specificMatch - - // Default to US if no specific Caribbean/territory code matches - return matches.find { it.iso == "US" } ?: matches.find { it.iso == "CA" } ?: matches[0] - } - - // 3. +44 Zone (UK / Guernsey / Jersey / Isle of Man) - if (digits.startsWith("44")) { - // Usually GB is the main one, others are territories - return matches.find { it.iso == "GB" } ?: matches[0] - } - - // 4. +33 Zone (France / French territories) - if (digits.startsWith("33")) { - return matches.find { it.iso == "FR" } ?: matches[0] - } - - // 5. +358 Zone (Finland / Aland Islands) - if (digits.startsWith("358")) { - return matches.find { it.iso == "FI" } ?: matches[0] - } - - return matches.maxByOrNull { it.code.length } - } - - fun formatPhone(phone: String): String { - val digits = phone.filter { it.isDigit() } - if (digits.isEmpty()) return "" - - val country = getCountryForPhone(digits) ?: return "+$digits" - val mask = country.mask ?: return "+$digits" - - val phoneWithoutCode = digits.removePrefix(country.code) - val result = StringBuilder("+${country.code} ") - var phoneIndex = 0 - - for (char in mask) { - if (phoneIndex >= phoneWithoutCode.length) break - if (char == 'X') { - result.append(phoneWithoutCode[phoneIndex]) - phoneIndex++ - } else { - result.append(char) - } - } - - if (phoneIndex < phoneWithoutCode.length) { - result.append(phoneWithoutCode.substring(phoneIndex)) - } - - return result.toString().trim() - } - - private fun countryCodeToEmoji(countryCode: String): String { - if (countryCode == "FT") return "⭐" - if (countryCode == "YL") return "✈️" - - if (countryCode.length != 2) return "🌐" - val firstLetter = Character.codePointAt(countryCode, 0) - 0x41 + 0x1F1E6 - val secondLetter = Character.codePointAt(countryCode, 1) - 0x41 + 0x1F1E6 - return String(Character.toChars(firstLetter)) + String(Character.toChars(secondLetter)) - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/CryptoManager.kt b/presentation/src/main/java/org/monogram/presentation/core/util/CryptoManager.kt deleted file mode 100644 index 74943e53..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/CryptoManager.kt +++ /dev/null @@ -1,82 +0,0 @@ -package org.monogram.presentation.core.util - -import android.security.keystore.KeyGenParameterSpec -import android.security.keystore.KeyProperties -import android.util.Base64 -import java.security.KeyStore -import javax.crypto.Cipher -import javax.crypto.KeyGenerator -import javax.crypto.SecretKey -import javax.crypto.spec.GCMParameterSpec - -class CryptoManager { - private val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { - load(null) - } - - private val algorithm = KeyProperties.KEY_ALGORITHM_AES - private val blockMode = KeyProperties.BLOCK_MODE_GCM - private val padding = KeyProperties.ENCRYPTION_PADDING_NONE - private val transformation = "$algorithm/$blockMode/$padding" - private val keyAlias = "webapp_secure_key" - - private fun getKey(): SecretKey { - val existingKey = keyStore.getEntry(keyAlias, null) as? KeyStore.SecretKeyEntry - return existingKey?.secretKey ?: createKey() - } - - private fun createKey(): SecretKey { - val keyGenerator = KeyGenerator.getInstance(algorithm, "AndroidKeyStore") - val keySpec = KeyGenParameterSpec.Builder( - keyAlias, - KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT - ) - .setBlockModes(blockMode) - .setEncryptionPaddings(padding) - .setRandomizedEncryptionRequired(true) - .build() - - keyGenerator.init(keySpec) - return keyGenerator.generateKey() - } - - fun encrypt(data: String): String? { - if (data.isEmpty()) return null - try { - val cipher = Cipher.getInstance(transformation) - cipher.init(Cipher.ENCRYPT_MODE, getKey()) - - val iv = cipher.iv - val encryptedBytes = cipher.doFinal(data.toByteArray(Charsets.UTF_8)) - - val ivString = Base64.encodeToString(iv, Base64.DEFAULT).trim() - val encryptedString = Base64.encodeToString(encryptedBytes, Base64.DEFAULT).trim() - - return "$ivString:$encryptedString" - } catch (e: Exception) { - e.printStackTrace() - return null - } - } - - fun decrypt(encryptedData: String?): String? { - if (encryptedData.isNullOrEmpty()) return null - try { - val parts = encryptedData.split(":") - if (parts.size != 2) return null - - val iv = Base64.decode(parts[0], Base64.DEFAULT) - val encryptedBytes = Base64.decode(parts[1], Base64.DEFAULT) - - val cipher = Cipher.getInstance(transformation) - val spec = GCMParameterSpec(128, iv) - cipher.init(Cipher.DECRYPT_MODE, getKey(), spec) - - val decodedBytes = cipher.doFinal(encryptedBytes) - return String(decodedBytes, Charsets.UTF_8) - } catch (e: Exception) { - e.printStackTrace() - return null - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/DownloadUtils.kt b/presentation/src/main/java/org/monogram/presentation/core/util/DownloadUtils.kt deleted file mode 100644 index 1189fbdc..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/DownloadUtils.kt +++ /dev/null @@ -1,303 +0,0 @@ -package org.monogram.presentation.core.util - -import android.app.Activity -import android.content.* -import android.graphics.Bitmap -import android.media.MediaScannerConnection -import android.net.ConnectivityManager -import android.net.NetworkCapabilities -import android.os.Build -import android.os.Environment -import android.provider.MediaStore -import android.webkit.MimeTypeMap -import androidx.core.content.FileProvider -import org.monogram.domain.repository.MessageDisplayer -import java.io.File -import java.io.FileInputStream -import java.io.FileOutputStream - -class DownloadUtils( - private val context: Context, - private val messageDisplayer: MessageDisplayer -) : IDownloadUtils { - - override fun saveFileToDownloads(filePath: String) { - try { - val file = File(filePath) - if (!file.exists()) { - messageDisplayer.show("File not found") - return - } - - val fileName = file.name - val mimeType = getMimeType(filePath) - val relativePath = "${Environment.DIRECTORY_DOWNLOADS}/MonoGram" - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - val contentValues = ContentValues().apply { - put(MediaStore.MediaColumns.DISPLAY_NAME, fileName) - put(MediaStore.MediaColumns.MIME_TYPE, mimeType) - put(MediaStore.MediaColumns.RELATIVE_PATH, relativePath) - } - - val resolver = context.contentResolver - val uri = resolver.insert( - MediaStore.Downloads.EXTERNAL_CONTENT_URI, - contentValues - ) - - if (uri != null) { - resolver.openOutputStream(uri)?.use { outputStream -> - FileInputStream(file).use { inputStream -> - inputStream.copyTo(outputStream) - } - } - messageDisplayer.show("Saved to Downloads/MonoGram") - } else { - messageDisplayer.show("Failed to create file in Downloads") - } - } else { - val downloadsDir = Environment.getExternalStoragePublicDirectory( - Environment.DIRECTORY_DOWNLOADS - ) - val monoGramDir = File(downloadsDir, "MonoGram") - if (!monoGramDir.exists()) { - monoGramDir.mkdirs() - } - - val destinationFile = File(monoGramDir, fileName) - - FileInputStream(file).use { inputStream -> - destinationFile.outputStream().use { outputStream -> - inputStream.copyTo(outputStream) - } - } - - messageDisplayer.show("Saved to Downloads/MonoGram") - } - } catch (e: Exception) { - messageDisplayer.show("Failed to save: ${e.message}") - } - } - - override fun saveBitmapToGallery(bitmap: Bitmap) { - val filename = "IMG_${System.currentTimeMillis()}.jpg" - - try { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - val contentValues = ContentValues().apply { - put(MediaStore.MediaColumns.DISPLAY_NAME, filename) - put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg") - put( - MediaStore.MediaColumns.RELATIVE_PATH, - "${Environment.DIRECTORY_PICTURES}/MonoGram" - ) - put(MediaStore.MediaColumns.IS_PENDING, 1) - } - - val resolver = context.contentResolver - val uri = resolver.insert( - MediaStore.Images.Media.EXTERNAL_CONTENT_URI, - contentValues - ) - - if (uri != null) { - resolver.openOutputStream(uri)?.use { outputStream -> - bitmap.compress( - Bitmap.CompressFormat.JPEG, - 100, - outputStream - ) - } - - contentValues.clear() - contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0) - resolver.update(uri, contentValues, null, null) - - messageDisplayer.show("Screenshot saved to Pictures/MonoGram") - } - } else { - val imagesDir = Environment.getExternalStoragePublicDirectory( - Environment.DIRECTORY_PICTURES - ) - val monoGramDir = File(imagesDir, "MonoGram") - if (!monoGramDir.exists()) { - monoGramDir.mkdirs() - } - - val imageFile = File(monoGramDir, filename) - - imageFile.outputStream().use { outputStream -> - bitmap.compress( - Bitmap.CompressFormat.JPEG, - 100, - outputStream - ) - } - - MediaScannerConnection.scanFile( - context, - arrayOf(imageFile.absolutePath), - null, - null - ) - - messageDisplayer.show("Screenshot saved to Pictures/MonoGram") - } - } catch (e: Exception) { - messageDisplayer.show("Failed to save screenshot: ${e.message}") - } - } - - override fun copyBitmapToClipboard(bitmap: Bitmap) { - try { - val cachePath = File(context.cacheDir, "images") - cachePath.mkdirs() - - val file = File(cachePath, "screenshot_temp.png") - FileOutputStream(file).use { stream -> - bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream) - } - - val uri = FileProvider.getUriForFile( - context, - "${context.packageName}.provider", - file - ) - - val clipboard = - context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - - val clip = ClipData.newUri( - context.contentResolver, - "Screenshot", - uri - ) - - clipboard.setPrimaryClip(clip) - - messageDisplayer.show("Screenshot copied to clipboard") - - } catch (e: Exception) { - messageDisplayer.show("Failed to copy screenshot: ${e.message}") - } - } - - override fun openFile(filePath: String) { - try { - val file = File(filePath) - if (!file.exists()) { - messageDisplayer.show("File not found") - return - } - - val uri = FileProvider.getUriForFile( - context, - "${context.packageName}.provider", - file - ) - - val extension = file.extension.lowercase() - val mimeType = if (extension == "apk") { - "application/vnd.android.package-archive" - } else { - MimeTypeMap.getSingleton() - .getMimeTypeFromExtension(extension) - } - - val intent = Intent(Intent.ACTION_VIEW).apply { - setDataAndType(uri, mimeType) - addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) - if (context !is Activity) { - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - } - - if (extension == "apk") { - context.startActivity(intent) - } else { - context.startActivity( - Intent.createChooser(intent, "Open with") - ) - } - - } catch (e: Exception) { - messageDisplayer.show("Failed to open: ${e.message}") - } - } - - override fun copyImageToClipboard(filePath: String) { - try { - val file = File(filePath) - if (!file.exists()) { - messageDisplayer.show("File not found") - return - } - - val clipboard = - context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - - val uri = FileProvider.getUriForFile( - context, - "${context.packageName}.provider", - file - ) - - val clip = ClipData.newUri( - context.contentResolver, - "Image", - uri - ) - - clipboard.setPrimaryClip(clip) - - messageDisplayer.show("Image copied to clipboard") - - } catch (e: Exception) { - messageDisplayer.show("Failed to copy: ${e.message}") - } - } - - override fun isWifiConnected(): Boolean { - val connectivityManager = - context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager - - val network = connectivityManager.activeNetwork ?: return false - val capabilities = - connectivityManager.getNetworkCapabilities(network) ?: return false - - return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) - } - - override fun isMobileDataConnected(): Boolean { - val connectivityManager = - context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager - - val network = connectivityManager.activeNetwork ?: return false - val capabilities = - connectivityManager.getNetworkCapabilities(network) ?: return false - - return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) - } - - override fun isRoaming(): Boolean { - val connectivityManager = - context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager - - val network = connectivityManager.activeNetwork ?: return false - val capabilities = - connectivityManager.getNetworkCapabilities(network) ?: return false - - return !capabilities.hasCapability( - NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING - ) - } -} - -fun getMimeType(filePath: String): String? { - val file = File(filePath) - val extension = MimeTypeMap.getFileExtensionFromUrl(filePath) - .ifBlank { file.extension } - return MimeTypeMap.getSingleton() - .getMimeTypeFromExtension(extension.lowercase()) -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/ExternalNavigatorImpl.kt b/presentation/src/main/java/org/monogram/presentation/core/util/ExternalNavigatorImpl.kt deleted file mode 100644 index d87ffa28..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/ExternalNavigatorImpl.kt +++ /dev/null @@ -1,57 +0,0 @@ -package org.monogram.presentation.core.util - -import android.content.Context -import android.content.Intent -import android.os.Build -import android.provider.Settings -import androidx.core.net.toUri -import com.google.android.gms.oss.licenses.v2.OssLicensesMenuActivity -import org.monogram.domain.repository.ExternalNavigator - -class ExternalNavigatorImpl( - private val context: Context -) : ExternalNavigator { - override fun openUrl(url: String) { - val intent = Intent(Intent.ACTION_VIEW, url.toUri()) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - - context.startActivity(intent) - } - - override val packageName: String - get() = context.packageName - - override fun navigateToLinkSettings() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - try { - val intent = Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS).apply { - data = "package:${packageName}".toUri() - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - context.startActivity(intent) - } catch (e: Exception) { - val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { - data = "package:${packageName}".toUri() - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - context.startActivity(intent) - } - } else { - try { - val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { - data = "package:${packageName}".toUri() - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - context.startActivity(intent) - } catch (e: Exception) { - e.printStackTrace() - } - } - } - - override fun openOssLicenses() { - val intent = Intent(context, OssLicensesMenuActivity::class.java) - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - context.startActivity(intent) - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/FileUtils.kt b/presentation/src/main/java/org/monogram/presentation/core/util/FileUtils.kt deleted file mode 100644 index 9b4a9098..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/FileUtils.kt +++ /dev/null @@ -1,38 +0,0 @@ -package org.monogram.presentation.core.util - -import android.content.Context -import android.net.Uri -import android.provider.OpenableColumns -import java.io.File -import java.io.FileOutputStream -import java.io.InputStream - -object FileUtils { - fun getPath(context: Context, uri: Uri): String? { - val returnCursor = context.contentResolver.query(uri, null, null, null, null) - val nameIndex = returnCursor?.getColumnIndex(OpenableColumns.DISPLAY_NAME) - returnCursor?.moveToFirst() - val name = nameIndex?.let { returnCursor.getString(it) } - returnCursor?.close() - - val file = File(context.cacheDir, name ?: "temp_file") - try { - val inputStream: InputStream? = context.contentResolver.openInputStream(uri) - val outputStream = FileOutputStream(file) - var read = 0 - val maxBufferSize = 1 * 1024 * 1024 - val bytesAvailable: Int = inputStream?.available() ?: 0 - val bufferSize = Math.min(bytesAvailable, maxBufferSize) - val buffers = ByteArray(bufferSize) - while (inputStream?.read(buffers).also { read = it ?: -1 } != -1) { - outputStream.write(buffers, 0, read) - } - inputStream?.close() - outputStream.close() - } catch (e: Exception) { - e.printStackTrace() - return null - } - return file.path - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/IDownloadUtils.kt b/presentation/src/main/java/org/monogram/presentation/core/util/IDownloadUtils.kt deleted file mode 100644 index 91883322..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/IDownloadUtils.kt +++ /dev/null @@ -1,24 +0,0 @@ -package org.monogram.presentation.core.util - -import android.graphics.Bitmap -import androidx.compose.runtime.Stable - -@Stable -interface IDownloadUtils { - - fun saveFileToDownloads(filePath: String) - - fun saveBitmapToGallery(bitmap: Bitmap) - - fun copyBitmapToClipboard(bitmap: Bitmap) - - fun openFile(filePath: String) - - fun copyImageToClipboard(filePath: String) - - fun isWifiConnected(): Boolean - - fun isMobileDataConnected(): Boolean - - fun isRoaming(): Boolean -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/OperatorUtil.kt b/presentation/src/main/java/org/monogram/presentation/core/util/OperatorUtil.kt deleted file mode 100644 index 3cfb68ef..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/OperatorUtil.kt +++ /dev/null @@ -1,174 +0,0 @@ -package org.monogram.presentation.core.util - -object OperatorManager { - private val operatorsByCountry = mapOf( - "RU" to mapOf( - "MTS" to setOf( - "910", "911", "912", "913", "914", "915", "916", "917", "918", "919", - "980", "981", "982", "983", "984", "985", "986", "987", "988", "989", - "978" - ), - "MegaFon" to setOf( - "920", "921", "922", "923", "924", "925", "926", "927", "928", "929", - "930", "931", "932", "933", "934", "935", "936", "937", "938", "939", - "997" - ), - "Beeline" to setOf( - "900", "902", "903", "904", "905", "906", "908", "909", - "960", "961", "962", "963", "964", "965", "966", "967", "968", "969" - ), - "Tele2" to setOf( - "901", "902", "904", "908", "950", "951", "952", "953", "958", "977", - "991", "992", "993", "994", "995", "996", "999" - ), - "Yota" to setOf("991", "995", "996", "999"), - "Tinkoff" to setOf("995"), - "SberMobile" to setOf("999"), - "Rostelecom" to setOf("902", "939", "958"), - "Motiv" to setOf("900", "904", "908", "952", "953"), - "Tattelecom" to setOf("991") - ), - "UA" to mapOf( - "Kyivstar" to setOf("67", "68", "96", "97", "98"), - "Vodafone" to setOf("50", "66", "95", "99"), - "lifecell" to setOf("63", "73", "93"), - "Intertelecom" to setOf("94"), - "TriMob" to setOf("91") - ), - "KZ" to mapOf( - "Beeline" to setOf("705", "771", "776", "777"), - "Kcell" to setOf("701", "702", "775", "778"), - "Tele2" to setOf("707", "747"), - "Altel" to setOf("700", "708"), - "Activ" to setOf("701", "702") - ), - "BY" to mapOf( - "A1" to setOf("291", "293", "296", "299", "44"), - "MTS" to setOf("292", "295", "297", "298", "33"), - "life:)" to setOf("25") - ), - "UZ" to mapOf( - "Beeline" to setOf("90", "91"), - "Ucell" to setOf("93", "94"), - "Mobiuz" to setOf("88", "97"), - "Uztelecom" to setOf("95", "99"), - "Humans" to setOf("33") - ), - "AZ" to mapOf( - "Azercell" to setOf("50", "51"), - "Bakcell" to setOf("55", "99"), - "Nar" to setOf("70", "77") - ), - "AM" to mapOf( - "Team" to setOf("91", "96", "99"), - "Viva-MTS" to setOf("77", "93", "94", "98"), - "Ucom" to setOf("55", "95") - ), - "GE" to mapOf( - "Magti" to setOf("514", "577", "591", "598"), - "Silknet" to setOf("551", "555", "558", "592", "593", "595", "597", "599"), - "Cellfie" to setOf("511", "568", "571", "574", "579", "596") - ), - "KG" to mapOf( - "Mega" to setOf("55", "75", "99"), - "O!" to setOf("50", "70"), - "Beeline" to setOf("22", "77") - ), - "TJ" to mapOf( - "Babilon-M" to setOf("918", "98"), - "Tcell" to setOf("92", "93"), - "MegaFon" to setOf("90", "88", "55"), - "Zet-Mobile" to setOf("91") - ), - "MD" to mapOf( - "Orange" to setOf("61", "62", "68", "69"), - "Moldcell" to setOf("60", "78", "79"), - "Unite" to setOf("67") - ), - "CN" to mapOf( - "China Mobile" to setOf( - "134", - "135", - "136", - "137", - "138", - "139", - "147", - "150", - "151", - "152", - "157", - "158", - "159", - "178", - "182", - "183", - "184", - "187", - "188", - "198" - ), - "China Unicom" to setOf("130", "131", "132", "145", "155", "156", "166", "175", "176", "185", "186"), - "China Telecom" to setOf("133", "149", "153", "173", "177", "180", "181", "189", "191", "199") - ), - "DE" to mapOf( - "Telekom" to setOf("151", "160", "170", "171", "175"), - "Vodafone" to setOf("152", "162", "172", "173", "174"), - "O2" to setOf("157", "159", "176", "179") - ), - "IT" to mapOf( - "TIM" to setOf("33", "36"), - "Vodafone" to setOf("34"), - "WindTre" to setOf("32", "38"), - "Iliad" to setOf("35") - ) - ) - - fun detectOperator(phone: String, countryIso: String?): String? { - if (countryIso == null) return null - val operators = operatorsByCountry[countryIso] ?: return null - val digits = phone.filter { it.isDigit() } - - val countryCode = getCountryCode(countryIso) ?: return null - if (!digits.startsWith(countryCode)) return null - - val phoneWithoutCode = digits.removePrefix(countryCode) - - if (countryIso == "RU") { - val defCode = phoneWithoutCode.take(3) - if (defCode == "999") return "Yota/SberMobile" - if (defCode == "995") return "Yota/Tinkoff" - if (defCode == "991") return "Yota/Tele2/Tattelecom" - - val matches = operators.filter { it.value.contains(defCode) }.keys - return if (matches.isEmpty()) null else matches.joinToString("/") - } - - val matches = mutableListOf() - for ((operator, prefixes) in operators) { - if (prefixes.any { phoneWithoutCode.startsWith(it) }) { - matches.add(operator) - } - } - - return if (matches.isEmpty()) null else matches.joinToString("/") - } - - private fun getCountryCode(iso: String): String? = when (iso) { - "RU" -> "7" - "UA" -> "380" - "KZ" -> "7" - "BY" -> "375" - "UZ" -> "998" - "AZ" -> "994" - "AM" -> "374" - "GE" -> "995" - "KG" -> "996" - "TJ" -> "992" - "MD" -> "373" - "CN" -> "86" - "DE" -> "49" - "IT" -> "39" - else -> null - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/RelativeVelocityTracker.kt b/presentation/src/main/java/org/monogram/presentation/core/util/RelativeVelocityTracker.kt deleted file mode 100644 index b1093fd7..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/RelativeVelocityTracker.kt +++ /dev/null @@ -1,41 +0,0 @@ -package org.monogram.presentation.core.util - -import android.os.SystemClock -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.input.pointer.util.VelocityTracker - - -internal class RelativeVelocityTracker( - private val timeProvider: CurrentTimeProvider -) { - private val tracker = VelocityTracker() - private var lastY: Float? = null - - fun delta(delta: Float) { - val new = (lastY ?: 0f) + delta - - tracker.addPosition(timeProvider.now(), Offset(0f, new)) - lastY = new - } - - fun reset(): Float { - lastY = null - - val velocity = tracker.calculateVelocity() - tracker.resetTracking() - - return velocity.y - } -} - -internal fun RelativeVelocityTracker.deriveDelta(initial: Float) = - initial - reset() - -internal interface CurrentTimeProvider { - fun now(): Long -} - -internal class CurrentTimeProviderImpl: CurrentTimeProvider { - override fun now(): Long = - SystemClock.uptimeMillis() -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/ScrollStrategy.kt b/presentation/src/main/java/org/monogram/presentation/core/util/ScrollStrategy.kt deleted file mode 100644 index 2c962d20..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/ScrollStrategy.kt +++ /dev/null @@ -1,223 +0,0 @@ -package org.monogram.presentation.core.util - -import androidx.compose.foundation.gestures.FlingBehavior -import androidx.compose.runtime.MutableState -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.input.nestedscroll.NestedScrollConnection -import androidx.compose.ui.input.nestedscroll.NestedScrollSource -import androidx.compose.ui.unit.Velocity -import org.monogram.presentation.core.ui.CollapsingToolbarState - -enum class ScrollStrategy { - EnterAlways { - override fun create( - offsetY: MutableState, - toolbarState: CollapsingToolbarState, - flingBehavior: FlingBehavior - ): NestedScrollConnection = - EnterAlwaysNestedScrollConnection(offsetY, toolbarState, flingBehavior) - }, - EnterAlwaysCollapsed { - override fun create( - offsetY: MutableState, - toolbarState: CollapsingToolbarState, - flingBehavior: FlingBehavior - ): NestedScrollConnection = - EnterAlwaysCollapsedNestedScrollConnection(offsetY, toolbarState, flingBehavior) - }, - ExitUntilCollapsed { - override fun create( - offsetY: MutableState, - toolbarState: CollapsingToolbarState, - flingBehavior: FlingBehavior - ): NestedScrollConnection = - ExitUntilCollapsedNestedScrollConnection(toolbarState, flingBehavior) - }; - - internal abstract fun create( - offsetY: MutableState, - toolbarState: CollapsingToolbarState, - flingBehavior: FlingBehavior - ): NestedScrollConnection -} - -private class ScrollDelegate( - private val offsetY: MutableState -) { - private var scrollToBeConsumed: Float = 0f - - fun doScroll(delta: Float) { - val scroll = scrollToBeConsumed + delta - val scrollInt = scroll.toInt() - - scrollToBeConsumed = scroll - scrollInt - - offsetY.value += scrollInt - } -} - -internal class EnterAlwaysNestedScrollConnection( - private val offsetY: MutableState, - private val toolbarState: CollapsingToolbarState, - private val flingBehavior: FlingBehavior -): NestedScrollConnection { - private val scrollDelegate = ScrollDelegate(offsetY) - private val tracker = RelativeVelocityTracker(CurrentTimeProviderImpl()) - - override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset { - val dy = available.y - tracker.delta(dy) - - val toolbar = toolbarState.height.toFloat() - val offset = offsetY.value.toFloat() - - val consume = if(dy < 0) { - val toolbarConsumption = toolbarState.dispatchRawDelta(dy) - val remaining = dy - toolbarConsumption - val offsetConsumption = remaining.coerceAtLeast(-toolbar - offset) - scrollDelegate.doScroll(offsetConsumption) - - toolbarConsumption + offsetConsumption - }else{ - val offsetConsumption = dy.coerceAtMost(-offset) - scrollDelegate.doScroll(offsetConsumption) - - val toolbarConsumption = toolbarState.dispatchRawDelta(dy - offsetConsumption) - - offsetConsumption + toolbarConsumption - } - - return Offset(0f, consume) - } - - override suspend fun onPreFling(available: Velocity): Velocity { - val velocity = tracker.reset() - - val left = if(velocity > 0) { - toolbarState.fling(flingBehavior, velocity) - }else{ - velocity - } - - return Velocity(x = 0f, y = available.y - left) - } -} - -internal class EnterAlwaysCollapsedNestedScrollConnection( - private val offsetY: MutableState, - private val toolbarState: CollapsingToolbarState, - private val flingBehavior: FlingBehavior -): NestedScrollConnection { - private val scrollDelegate = ScrollDelegate(offsetY) - private val tracker = RelativeVelocityTracker(CurrentTimeProviderImpl()) - - override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset { - val dy = available.y - tracker.delta(dy) - - val consumed = if(dy > 0) { - val offsetConsumption = dy.coerceAtMost(-offsetY.value.toFloat()) - scrollDelegate.doScroll(offsetConsumption) - - offsetConsumption - }else{ - val toolbarConsumption = toolbarState.dispatchRawDelta(dy) - val offsetConsumption = (dy - toolbarConsumption).coerceAtLeast(-toolbarState.height.toFloat() - offsetY.value) - - scrollDelegate.doScroll(offsetConsumption) - - toolbarConsumption + offsetConsumption - } - - return Offset(0f, consumed) - } - - override fun onPostScroll( - consumed: Offset, - available: Offset, - source: NestedScrollSource - ): Offset { - val dy = available.y - - return if(dy > 0) { - Offset(0f, toolbarState.dispatchRawDelta(dy)) - }else{ - Offset(0f, 0f) - } - } - - override suspend fun onPreFling(available: Velocity): Velocity = - Velocity(x = 0f, y = tracker.deriveDelta(available.y)) - - override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity { - val dy = available.y - - val left = if(dy > 0) { - toolbarState.fling(flingBehavior, dy) - }else{ - dy - } - - return Velocity(x = 0f, y = available.y - left) - } -} - -internal class ExitUntilCollapsedNestedScrollConnection( - private val toolbarState: CollapsingToolbarState, - private val flingBehavior: FlingBehavior -): NestedScrollConnection { - private val tracker = RelativeVelocityTracker(CurrentTimeProviderImpl()) - - override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset { - val dy = available.y - tracker.delta(dy) - - val consume = if(dy < 0) { - toolbarState.dispatchRawDelta(dy) - }else{ - 0f - } - - return Offset(0f, consume) - } - - override fun onPostScroll( - consumed: Offset, - available: Offset, - source: NestedScrollSource - ): Offset { - val dy = available.y - - val consume = if(dy > 0) { - toolbarState.dispatchRawDelta(dy) - }else{ - 0f - } - - return Offset(0f, consume) - } - - override suspend fun onPreFling(available: Velocity): Velocity { - val velocity = tracker.reset() - - val left = if(velocity < 0) { - toolbarState.fling(flingBehavior, velocity) - }else{ - velocity - } - - return Velocity(x = 0f, y = available.y - left) - } - - override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity { - val velocity = available.y - - val left = if(velocity > 0) { - toolbarState.fling(flingBehavior, velocity) - }else{ - velocity - } - - return Velocity(x = 0f, y = available.y - left) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/StringUtil.kt b/presentation/src/main/java/org/monogram/presentation/core/util/StringUtil.kt deleted file mode 100644 index ad8170f8..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/StringUtil.kt +++ /dev/null @@ -1,238 +0,0 @@ -package org.monogram.presentation.core.util - -import android.content.Context -import android.text.format.DateUtils -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.font.FontStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextDecoration -import androidx.compose.ui.text.withStyle -import org.monogram.domain.models.* -import org.monogram.presentation.R -import java.text.SimpleDateFormat -import java.util.* - -fun formatLastSeen(lastSeen: Long?, context: Context): String { - if (lastSeen == null || lastSeen <= 0L) return context.getString(R.string.last_seen_recently) - - val now = System.currentTimeMillis() - val diff = now - lastSeen - - if (diff < 0) return context.getString(R.string.last_seen_just_now) - - return when { - diff < 60 * 1000L -> context.getString(R.string.last_seen_just_now) - diff < 60 * 60 * 1000L -> { - val minutes = (diff / (60 * 1000L)).toInt() - context.resources.getQuantityString(R.plurals.last_seen_minutes_ago, minutes, minutes) - } - - DateUtils.isToday(lastSeen) -> { - val time = SimpleDateFormat("HH:mm", Locale.getDefault()).format(Date(lastSeen)) - context.getString(R.string.last_seen_at, time) - } - - isYesterday(lastSeen) -> { - val time = SimpleDateFormat("HH:mm", Locale.getDefault()).format(Date(lastSeen)) - context.getString(R.string.last_seen_yesterday_at, time) - } - - else -> { - val date = SimpleDateFormat("dd.MM.yy", Locale.getDefault()).format(Date(lastSeen)) - context.getString(R.string.last_seen_date, date) - } - } -} - -@Composable -fun rememberUserStatusText(user: UserModel?): String { - if (user == null) return stringResource(R.string.status_offline) - if (user.type == UserTypeEnum.BOT) return stringResource(R.string.status_bot) - - val context = LocalContext.current - return remember(user.userStatus, user.lastSeen) { - when (user.userStatus) { - UserStatusType.ONLINE -> context.getString(R.string.status_online) - UserStatusType.OFFLINE -> formatLastSeen(user.lastSeen, context) - UserStatusType.RECENTLY -> context.getString(R.string.last_seen_recently) - UserStatusType.LAST_WEEK -> context.getString(R.string.last_seen_within_week) - UserStatusType.LAST_MONTH -> context.getString(R.string.last_seen_within_month) - else -> context.getString(R.string.last_seen_long_time_ago) - } - } -} - -private fun isYesterday(timestamp: Long): Boolean { - return DateUtils.isToday(timestamp + DateUtils.DAY_IN_MILLIS) -} - -fun getUserStatusText(user: UserModel?, context: Context): String { - if (user == null) return context.getString(R.string.status_offline) - if (user.type == UserTypeEnum.BOT) return context.getString(R.string.status_bot) - - return when (user.userStatus) { - UserStatusType.ONLINE -> context.getString(R.string.status_online) - UserStatusType.OFFLINE -> formatLastSeen(user.lastSeen, context) - UserStatusType.RECENTLY -> context.getString(R.string.last_seen_recently) - UserStatusType.LAST_WEEK -> context.getString(R.string.last_seen_within_week) - UserStatusType.LAST_MONTH -> context.getString(R.string.last_seen_within_month) - else -> context.getString(R.string.last_seen_long_time_ago) - } -} - -fun buildRichText( - richText: RichText, - linkColor: Color -): AnnotatedString { - return buildAnnotatedString { - append(richText.text) - richText.entities.forEach { entity -> - val style = when (entity.type) { - is MessageEntityType.Bold -> SpanStyle(fontWeight = FontWeight.Bold) - is MessageEntityType.Italic -> SpanStyle(fontStyle = FontStyle.Italic) - is MessageEntityType.Underline -> SpanStyle(textDecoration = TextDecoration.Underline) - is MessageEntityType.Strikethrough -> SpanStyle(textDecoration = TextDecoration.LineThrough) - is MessageEntityType.Spoiler -> SpanStyle(background = Color.Gray.copy(alpha = 0.3f)) - is MessageEntityType.Code -> SpanStyle(background = Color.LightGray.copy(alpha = 0.2f)) - is MessageEntityType.Pre -> SpanStyle(background = Color.LightGray.copy(alpha = 0.2f)) - is MessageEntityType.TextUrl -> SpanStyle(color = linkColor, textDecoration = TextDecoration.Underline) - is MessageEntityType.Url -> SpanStyle(color = linkColor, textDecoration = TextDecoration.Underline) - is MessageEntityType.Mention -> SpanStyle(color = linkColor) - is MessageEntityType.Hashtag -> SpanStyle(color = linkColor) - is MessageEntityType.BotCommand -> SpanStyle(color = linkColor) - is MessageEntityType.Email -> SpanStyle(color = linkColor, textDecoration = TextDecoration.Underline) - is MessageEntityType.PhoneNumber -> SpanStyle( - color = linkColor, - textDecoration = TextDecoration.Underline - ) - - is MessageEntityType.BankCardNumber -> SpanStyle( - color = linkColor, - textDecoration = TextDecoration.Underline - ) - - is MessageEntityType.TextMention -> SpanStyle(color = linkColor) - is MessageEntityType.CustomEmoji -> null - else -> null - } - - if (style != null) { - addStyle(style, entity.offset, entity.offset + entity.length) - } - - when (val type = entity.type) { - is MessageEntityType.TextUrl -> { - addStringAnnotation("URL", type.url, entity.offset, entity.offset + entity.length) - } - - is MessageEntityType.Url -> { - val url = richText.text.substring(entity.offset, entity.offset + entity.length) - addStringAnnotation("URL", url, entity.offset, entity.offset + entity.length) - } - - else -> {} - } - } - } -} - -fun buildRichText( - text: String, - linkColor: Color -): AnnotatedString { - return buildAnnotatedString { - var currentIndex = 0 - val boldRegex = "\\*\\*(.*?)\\*\\*".toRegex() - val urlPattern = Regex("(https?://\\S+|t\\.me/\\S+)") - val mentionPattern = Regex("@[a-zA-Z0-9_]+") - - val boldMatches = boldRegex.findAll(text).toList() - - if (boldMatches.isEmpty()) { - append(text) - } else { - boldMatches.forEach { matchResult -> - val range = matchResult.range - if (range.first > currentIndex) { - append(text.substring(currentIndex, range.first)) - } - - withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { - append(matchResult.groupValues[1]) - } - - currentIndex = range.last + 1 - } - - if (currentIndex < text.length) { - append(text.substring(currentIndex)) - } - } - - val fullText = this.toAnnotatedString().text - - urlPattern.findAll(fullText).forEach { result -> - addStyle( - style = SpanStyle(color = linkColor, textDecoration = TextDecoration.Underline), - start = result.range.first, - end = result.range.last + 1 - ) - addStringAnnotation( - tag = "URL", - annotation = result.value, - start = result.range.first, - end = result.range.last + 1 - ) - } - - mentionPattern.findAll(fullText).forEach { result -> - addStyle( - style = SpanStyle(color = linkColor), - start = result.range.first, - end = result.range.last + 1 - ) - addStringAnnotation( - tag = "URL", - annotation = "https://t.me/${result.value.substring(1)}", - start = result.range.first, - end = result.range.last + 1 - ) - } - } -} - -fun ByteArray.toHex(): String = joinToString("") { "%02x".format(it) } -fun formatPhoneGlobal(phone: String): String { - val digits = phone.filter { it.isDigit() } - - if (digits.isEmpty()) return "" - - if (digits.length == 11 && (digits.startsWith("7") || digits.startsWith("8"))) { - return "+7 (${digits.substring(1, 4)}) ${digits.substring(4, 7)}-${digits.substring(7, 9)}-${digits.substring(9, 11)}" - } - - return "+$digits" -} - -fun formatMaskedGlobal(phone: String): String { - val digits = phone.filter { it.isDigit() } - - if (digits.length < 5) return "****" - - if (digits.length == 11 && (digits.startsWith("7") || digits.startsWith("8"))) { - return "+7 (***) ***-**-${digits.takeLast(2)}" - } - - val visibleCount = 4 - val maskedCount = digits.length - visibleCount - val stars = "*".repeat(maskedCount) - - return "+$stars${digits.takeLast(visibleCount)}" -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/core/util/ToastMessageDisplayer.kt b/presentation/src/main/java/org/monogram/presentation/core/util/ToastMessageDisplayer.kt deleted file mode 100644 index 93e79d72..00000000 --- a/presentation/src/main/java/org/monogram/presentation/core/util/ToastMessageDisplayer.kt +++ /dev/null @@ -1,13 +0,0 @@ -package org.monogram.presentation.core.util - -import android.content.Context -import android.widget.Toast -import org.monogram.domain.repository.MessageDisplayer - -class ToastMessageDisplayer( - private val context: Context -) : MessageDisplayer { - override fun show(message: String) { - Toast.makeText(context, message, Toast.LENGTH_SHORT).show() - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/di/AppContainer.kt b/presentation/src/main/java/org/monogram/presentation/di/AppContainer.kt deleted file mode 100644 index 83b9c100..00000000 --- a/presentation/src/main/java/org/monogram/presentation/di/AppContainer.kt +++ /dev/null @@ -1,59 +0,0 @@ -package org.monogram.presentation.di - -import coil3.ImageLoader -import kotlinx.coroutines.CoroutineScope -import org.monogram.core.DispatcherProvider -import org.monogram.core.Logger -import org.monogram.domain.managers.* -import org.monogram.domain.repository.* -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.components.ExoPlayerCache -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.settings.storage.CacheController - -interface AppContainer { - val preferences: PreferencesContainer - val repositories: RepositoriesContainer - val utils: UtilsContainer - val cacheProvider: CacheProvider -} - -interface PreferencesContainer { - val appPreferences: AppPreferences - val appPreferencesProvider: AppPreferencesProvider - val botPreferencesProvider: BotPreferencesProvider -} - -interface RepositoriesContainer { - val authRepository: AuthRepository - val chatsListRepository: ChatsListRepository - val messageRepository: MessageRepository - val userRepository: UserRepository - val settingsRepository: SettingsRepository - val locationRepository: LocationRepository - val privacyRepository: PrivacyRepository - val linkHandlerRepository: LinkHandlerRepository - val externalProxyRepository: ExternalProxyRepository - val stickerRepository: StickerRepository - val updateRepository: UpdateRepository -} - -interface UtilsContainer { - val videoPlayerPool: VideoPlayerPool - val exoPlayerCache: ExoPlayerCache - val cacheController: CacheController - val imageLoader: ImageLoader - val appCoroutineScope: CoroutineScope - val clipManager: ClipManager - val dispatcherProvider: DispatcherProvider - val logger: Logger - fun messageDisplayer(): MessageDisplayer - fun externalNavigator(): ExternalNavigator - fun phoneManager(): PhoneManager - fun domainManager(): DomainManager - fun assetsManager(): AssetsManager - fun distrManager(): DistrManager - fun downloadUtils(): IDownloadUtils - fun stringProvider(): StringProvider -} diff --git a/presentation/src/main/java/org/monogram/presentation/di/KoinAppContainer.kt b/presentation/src/main/java/org/monogram/presentation/di/KoinAppContainer.kt deleted file mode 100644 index 3cb2995e..00000000 --- a/presentation/src/main/java/org/monogram/presentation/di/KoinAppContainer.kt +++ /dev/null @@ -1,62 +0,0 @@ -package org.monogram.presentation.di - -import coil3.ImageLoader -import kotlinx.coroutines.CoroutineScope -import org.koin.core.Koin -import org.monogram.core.DispatcherProvider -import org.monogram.core.Logger -import org.monogram.domain.managers.* -import org.monogram.domain.repository.* -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.components.ExoPlayerCache -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.settings.storage.CacheController - -class KoinAppContainer(koin: Koin) : AppContainer { - override val preferences = KoinPreferencesContainer(koin) - override val cacheProvider: CacheProvider by lazy { koin.get() } - override val repositories = KoinRepositoriesContainer(koin) - override val utils = KoinUtilsContainer(koin) -} - -class KoinPreferencesContainer(private val koin: Koin) : PreferencesContainer { - override val appPreferences: AppPreferences by lazy { koin.get() } - override val appPreferencesProvider: AppPreferencesProvider by lazy { koin.get() } - override val botPreferencesProvider: BotPreferencesProvider by lazy { koin.get() } -} - -class KoinRepositoriesContainer(private val koin: Koin) : RepositoriesContainer { - override val authRepository: AuthRepository by lazy { koin.get() } - override val chatsListRepository: ChatsListRepository by lazy { koin.get() } - override val messageRepository: MessageRepository by lazy { koin.get() } - override val userRepository: UserRepository by lazy { koin.get() } - override val settingsRepository: SettingsRepository by lazy { koin.get() } - override val locationRepository: LocationRepository by lazy { koin.get() } - override val privacyRepository: PrivacyRepository by lazy { koin.get() } - override val linkHandlerRepository: LinkHandlerRepository by lazy { koin.get() } - override val externalProxyRepository: ExternalProxyRepository by lazy { koin.get() } - override val stickerRepository: StickerRepository by lazy { koin.get() } - override val updateRepository: UpdateRepository by lazy { koin.get() } -} - -class KoinUtilsContainer(private val koin: Koin) : UtilsContainer { - override val appCoroutineScope: CoroutineScope by lazy { koin.get() } - override val videoPlayerPool: VideoPlayerPool by lazy { koin.get() } - override val exoPlayerCache: ExoPlayerCache by lazy { koin.get() } - override val cacheController: CacheController by lazy { koin.get() } - override val imageLoader: ImageLoader by lazy { koin.get() } - override val clipManager: ClipManager by lazy { koin.get() } - override val dispatcherProvider: DispatcherProvider by lazy { koin.get() } - override val logger: Logger by lazy { koin.get() } - - override fun messageDisplayer(): MessageDisplayer = koin.get() - override fun externalNavigator(): ExternalNavigator = koin.get() - override fun phoneManager(): PhoneManager = koin.get() - override fun domainManager(): DomainManager = koin.get() - override fun assetsManager(): AssetsManager = koin.get() - override fun distrManager(): DistrManager = koin.get() - - override fun downloadUtils(): IDownloadUtils = koin.get() - override fun stringProvider(): StringProvider = koin.get() -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/di/coil/LottieDecoder.kt b/presentation/src/main/java/org/monogram/presentation/di/coil/LottieDecoder.kt deleted file mode 100644 index bfc13b55..00000000 --- a/presentation/src/main/java/org/monogram/presentation/di/coil/LottieDecoder.kt +++ /dev/null @@ -1,65 +0,0 @@ -package org.monogram.presentation.di.coil - -import android.graphics.Bitmap -import coil3.ImageLoader -import coil3.asImage -import coil3.decode.DecodeResult -import coil3.decode.Decoder -import coil3.decode.ImageSource -import coil3.fetch.SourceFetchResult -import coil3.request.Options -import org.monogram.presentation.features.stickers.core.RLottieWrapper - -class LottieDecoder( - private val source: ImageSource -) : Decoder { - - override suspend fun decode(): DecodeResult { - val file = java.io.File(source.file().toString()) - val decoder = RLottieWrapper() - try { - if (!decoder.open(file)) { - throw RuntimeException("Failed to load rlottie animation") - } - - val width = decoder.getWidth().coerceAtLeast(1) - val height = decoder.getHeight().coerceAtLeast(1) - val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) - bitmap.eraseColor(0) - - val rendered = decoder.renderFrame( - bitmap = bitmap, - frameNo = 0, - drawLeft = 0, - drawTop = 0, - drawWidth = width, - drawHeight = height - ) - if (!rendered) { - throw RuntimeException("Failed to render rlottie frame") - } - - return DecodeResult( - image = bitmap.asImage(), - isSampled = false - ) - } finally { - decoder.release() - } - } - - class Factory : Decoder.Factory { - override fun create(result: SourceFetchResult, options: Options, imageLoader: ImageLoader): Decoder? { - val isLottie = result.mimeType == "application/tgs" || - result.mimeType == "application/json" || - result.source.file().name.endsWith(".tgs", ignoreCase = true) || - result.source.file().name.endsWith(".json", ignoreCase = true) - - if (isLottie) { - return LottieDecoder(result.source) - } - - return null - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/di/coil/coilModule.kt b/presentation/src/main/java/org/monogram/presentation/di/coil/coilModule.kt deleted file mode 100644 index e9962e58..00000000 --- a/presentation/src/main/java/org/monogram/presentation/di/coil/coilModule.kt +++ /dev/null @@ -1,18 +0,0 @@ -package org.monogram.presentation.di.coil - -import coil3.ImageLoader -import coil3.network.okhttp.OkHttpNetworkFetcherFactory -import coil3.svg.SvgDecoder -import org.koin.dsl.module - -val coilModule = module { - single { - ImageLoader.Builder(get()) - .components { - add(LottieDecoder.Factory()) - add(SvgDecoder.Factory()) - add(OkHttpNetworkFetcherFactory()) - } - .build() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/di/uiModule.kt b/presentation/src/main/java/org/monogram/presentation/di/uiModule.kt deleted file mode 100644 index b6574193..00000000 --- a/presentation/src/main/java/org/monogram/presentation/di/uiModule.kt +++ /dev/null @@ -1,8 +0,0 @@ -package org.monogram.presentation.di - -import org.monogram.presentation.di.coil.coilModule -import org.koin.dsl.module - -val uiModule = module { - includes(coilModule) -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/auth/AuthComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/auth/AuthComponent.kt deleted file mode 100644 index 3a608c2d..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/auth/AuthComponent.kt +++ /dev/null @@ -1,36 +0,0 @@ -package org.monogram.presentation.features.auth - -import com.arkivanov.decompose.value.Value - -interface AuthComponent { - val model: Value - - fun onPhoneEntered(phone: String) - fun onCodeEntered(code: String) - fun onResendCode() - fun onPasswordEntered(password: String) - fun onBackToPhone() - fun onProxyClicked() - fun dismissError() - fun onReset() - - data class Model( - val authState: AuthState, - val isSubmitting: Boolean = false, - val error: String? = null, - val phoneNumber: String? = null - ) - - sealed class AuthState { - object InputPhone : AuthState() - data class InputCode( - val codeLength: Int, - val codeType: String, - val nextCodeType: String? = null, - val timeout: Int = 0, - val emailPattern: String? = null - ) : AuthState() - - object InputPassword : AuthState() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/auth/AuthContent.kt b/presentation/src/main/java/org/monogram/presentation/features/auth/AuthContent.kt deleted file mode 100644 index 6283f528..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/auth/AuthContent.kt +++ /dev/null @@ -1,168 +0,0 @@ -package org.monogram.presentation.features.auth - -import android.content.res.Configuration -import androidx.activity.compose.BackHandler -import androidx.compose.animation.* -import androidx.compose.animation.core.tween -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.SettingsEthernet -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.presentation.R -import org.monogram.presentation.features.auth.components.AuthErrorDialog -import org.monogram.presentation.features.auth.components.CodeInputScreen -import org.monogram.presentation.features.auth.components.PasswordInputScreen -import org.monogram.presentation.features.auth.components.PhoneInputScreen - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun AuthContent(component: AuthComponent) { - val model by component.model.subscribeAsState() - val configuration = LocalConfiguration.current - val isTablet = configuration.screenWidthDp >= 600 - val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE - val maxContentWidth = if (isTablet && isLandscape) 1000.dp else 600.dp - - val isCustomBackHandlingEnabled = model.authState is AuthComponent.AuthState.InputCode || model.authState is AuthComponent.AuthState.InputPassword - - BackHandler(enabled = isCustomBackHandlingEnabled) { - component.onBackToPhone() - } - - Scaffold( - modifier = Modifier.fillMaxSize(), - topBar = { - Surface( - color = MaterialTheme.colorScheme.background, - modifier = Modifier.fillMaxWidth() - ) { - Box( - modifier = Modifier.fillMaxWidth(), - contentAlignment = Alignment.Center - ) { - CenterAlignedTopAppBar( - modifier = Modifier.widthIn(max = maxContentWidth), - title = { - Text( - text = when (model.authState) { - is AuthComponent.AuthState.InputPhone -> stringResource(R.string.auth_title_phone) - is AuthComponent.AuthState.InputCode -> stringResource(R.string.auth_title_verification) - is AuthComponent.AuthState.InputPassword -> stringResource(R.string.auth_title_password) - }, - style = MaterialTheme.typography.titleLarge, - fontWeight = FontWeight.Bold - ) - }, - navigationIcon = { - if (model.authState is AuthComponent.AuthState.InputCode || model.authState is AuthComponent.AuthState.InputPassword) { - IconButton(onClick = component::onBackToPhone) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - } - }, - actions = { - IconButton(onClick = component::onProxyClicked) { - Icon( - imageVector = Icons.Rounded.SettingsEthernet, - contentDescription = stringResource(R.string.cd_proxy_settings), - tint = MaterialTheme.colorScheme.primary - ) - } - }, - colors = TopAppBarDefaults.centerAlignedTopAppBarColors( - containerColor = MaterialTheme.colorScheme.background - ) - ) - } - } - } - ) { padding -> - Box( - modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.background) - .padding(top = padding.calculateTopPadding()) - .imePadding(), - contentAlignment = Alignment.TopCenter - ) { - val contentModifier = Modifier - .widthIn(max = maxContentWidth) - .fillMaxWidth() - - AnimatedContent( - targetState = model.authState, - transitionSpec = { - val direction = if (targetState.index > initialState.index) { - AnimatedContentTransitionScope.SlideDirection.Start - } else { - AnimatedContentTransitionScope.SlideDirection.End - } - slideIntoContainer( - towards = direction, - animationSpec = tween(400) - ) + fadeIn(animationSpec = tween(400)) togetherWith - slideOutOfContainer( - towards = direction, - animationSpec = tween(400) - ) + fadeOut(animationSpec = tween(400)) - }, - label = "AuthTransition" - ) { targetState -> - Box(modifier = contentModifier) { - when (targetState) { - is AuthComponent.AuthState.InputPhone -> PhoneInputScreen( - onConfirm = component::onPhoneEntered, - isSubmitting = model.isSubmitting - ) - - is AuthComponent.AuthState.InputCode -> CodeInputScreen( - phoneNumber = model.phoneNumber ?: "", - codeLength = targetState.codeLength, - codeType = targetState.codeType, - nextCodeType = targetState.nextCodeType, - timeout = targetState.timeout, - emailPattern = targetState.emailPattern, - onConfirm = component::onCodeEntered, - onResend = component::onResendCode, - onBack = component::onBackToPhone, - isSubmitting = model.isSubmitting - ) - - is AuthComponent.AuthState.InputPassword -> PasswordInputScreen( - onConfirm = component::onPasswordEntered, - isSubmitting = model.isSubmitting - ) - } - } - } - - if (model.error != null) { - AuthErrorDialog( - message = model.error!!, - onDismiss = component::dismissError - ) - } - } - } -} - -private val AuthComponent.AuthState.index: Int - get() = when (this) { - is AuthComponent.AuthState.InputPhone -> 1 - is AuthComponent.AuthState.InputCode -> 2 - is AuthComponent.AuthState.InputPassword -> 3 - } diff --git a/presentation/src/main/java/org/monogram/presentation/features/auth/AuthStore.kt b/presentation/src/main/java/org/monogram/presentation/features/auth/AuthStore.kt deleted file mode 100644 index 4e9d8c6b..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/auth/AuthStore.kt +++ /dev/null @@ -1,22 +0,0 @@ -package org.monogram.presentation.features.auth - -import com.arkivanov.mvikotlin.core.store.Store - -interface AuthStore : Store { - - sealed class Intent { - data class PhoneEntered(val phone: String) : Intent() - data class CodeEntered(val code: String) : Intent() - object ResendCode : Intent() - data class PasswordEntered(val password: String) : Intent() - object BackToPhone : Intent() - object ProxyClicked : Intent() - object DismissError : Intent() - object Reset : Intent() - data class UpdateModel(val model: AuthComponent.Model) : Intent() - } - - sealed class Label { - object OpenProxy : Label() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/auth/AuthStoreFactory.kt b/presentation/src/main/java/org/monogram/presentation/features/auth/AuthStoreFactory.kt deleted file mode 100644 index 86fad5b7..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/auth/AuthStoreFactory.kt +++ /dev/null @@ -1,49 +0,0 @@ -package org.monogram.presentation.features.auth - -import com.arkivanov.mvikotlin.core.store.Reducer -import com.arkivanov.mvikotlin.core.store.Store -import com.arkivanov.mvikotlin.core.store.StoreFactory -import com.arkivanov.mvikotlin.extensions.coroutines.CoroutineExecutor -import org.monogram.presentation.features.auth.AuthStore.Intent -import org.monogram.presentation.features.auth.AuthStore.Label - -class AuthStoreFactory( - private val storeFactory: StoreFactory, - private val component: DefaultAuthComponent -) { - - fun create(): AuthStore = - object : AuthStore, Store by storeFactory.create( - name = "AuthStore", - initialState = component.model.value, - executorFactory = ::ExecutorImpl, - reducer = ReducerImpl - ) {} - - private inner class ExecutorImpl : CoroutineExecutor() { - override fun executeIntent(intent: Intent) { - when (intent) { - is Intent.PhoneEntered -> component.onPhoneEntered(intent.phone) - is Intent.CodeEntered -> component.onCodeEntered(intent.code) - Intent.ResendCode -> component.onResendCode() - is Intent.PasswordEntered -> component.onPasswordEntered(intent.password) - Intent.BackToPhone -> component.onBackToPhone() - Intent.ProxyClicked -> component.onProxyClicked() - Intent.DismissError -> component.dismissError() - Intent.Reset -> component.onReset() - is Intent.UpdateModel -> dispatch(Message.UpdateModel(intent.model)) - } - } - } - - private object ReducerImpl : Reducer { - override fun AuthComponent.Model.reduce(msg: Message): AuthComponent.Model = - when (msg) { - is Message.UpdateModel -> msg.model - } - } - - sealed class Message { - data class UpdateModel(val model: AuthComponent.Model) : Message() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/auth/DefaultAuthComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/auth/DefaultAuthComponent.kt deleted file mode 100644 index c2e52603..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/auth/DefaultAuthComponent.kt +++ /dev/null @@ -1,100 +0,0 @@ -package org.monogram.presentation.features.auth - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import org.monogram.domain.repository.AuthRepository -import org.monogram.domain.repository.AuthStep -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.root.AppComponentContext - -class DefaultAuthComponent( - context: AppComponentContext, - private val onOpenProxy: () -> Unit -) : AuthComponent, AppComponentContext by context { - - private val repository: AuthRepository = container.repositories.authRepository - private val scope = componentScope - - private val _model = MutableValue( - AuthComponent.Model(authState = AuthComponent.AuthState.InputPhone) - ) - override val model: Value = _model - - init { - repository.authState - .onEach { step -> - val newAuthState = when (step) { - is AuthStep.InputPhone -> AuthComponent.AuthState.InputPhone - is AuthStep.InputCode -> AuthComponent.AuthState.InputCode( - codeLength = step.codeLength, - codeType = step.codeType, - nextCodeType = step.nextType, - timeout = step.timeout, - emailPattern = step.emailPattern - ) - is AuthStep.InputPassword -> AuthComponent.AuthState.InputPassword - else -> null - } - if (newAuthState != null) { - _model.update { - it.copy( - authState = newAuthState, - isSubmitting = false - ) - } - } - } - .launchIn(scope) - - repository.errors - .onEach { errorMessage -> - _model.update { - it.copy( - error = errorMessage, - isSubmitting = false - ) - } - } - .launchIn(scope) - } - - override fun onPhoneEntered(phone: String) { - _model.update { it.copy(isSubmitting = true, phoneNumber = phone) } - repository.sendPhone(phone) - } - - override fun onCodeEntered(code: String) { - _model.update { it.copy(isSubmitting = true) } - repository.sendCode(code) - } - - override fun onResendCode() { - repository.resendCode() - } - - override fun onPasswordEntered(password: String) { - _model.update { it.copy(isSubmitting = true) } - repository.sendPassword(password) - } - - override fun onBackToPhone() { - _model.update { it.copy(error = null) } - repository.reset() - } - - override fun onProxyClicked() { - onOpenProxy() - } - - override fun dismissError() { - _model.update { it.copy(error = null) } - } - - override fun onReset() { - _model.update { it.copy(error = null) } - repository.reset() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/auth/components/AuthErrorDialog.kt b/presentation/src/main/java/org/monogram/presentation/features/auth/components/AuthErrorDialog.kt deleted file mode 100644 index 7ba60693..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/auth/components/AuthErrorDialog.kt +++ /dev/null @@ -1,47 +0,0 @@ -package org.monogram.presentation.features.auth.components - -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ErrorOutline -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import org.monogram.presentation.R - -@Composable -fun AuthErrorDialog( - message: String, - onDismiss: () -> Unit -) { - AlertDialog( - onDismissRequest = onDismiss, - icon = { - Icon( - imageVector = Icons.Default.ErrorOutline, - contentDescription = null, - tint = MaterialTheme.colorScheme.error - ) - }, - title = { - Text(text = stringResource(R.string.auth_error_title)) - }, - text = { - Text(text = message) - }, - confirmButton = { - Button( - onClick = onDismiss, - colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.errorContainer, - contentColor = MaterialTheme.colorScheme.onErrorContainer - ), - shape = RoundedCornerShape(12.dp) - ) { - Text(stringResource(R.string.dismiss_button)) - } - }, - shape = RoundedCornerShape(28.dp), - containerColor = MaterialTheme.colorScheme.surfaceContainerHigh, - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/auth/components/CodeInputScreen.kt b/presentation/src/main/java/org/monogram/presentation/features/auth/components/CodeInputScreen.kt deleted file mode 100644 index c74301de..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/auth/components/CodeInputScreen.kt +++ /dev/null @@ -1,382 +0,0 @@ -package org.monogram.presentation.features.auth.components - -import android.content.res.Configuration -import androidx.activity.compose.BackHandler -import androidx.compose.animation.core.* -import androidx.compose.foundation.* -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.BasicTextField -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowBack -import androidx.compose.material.icons.automirrored.filled.ArrowForward -import androidx.compose.material.icons.filled.Lock -import androidx.compose.material.icons.filled.Refresh -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.focus.onFocusChanged -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.platform.* -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.DpOffset -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import kotlinx.coroutines.delay -import org.monogram.presentation.R - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun CodeInputScreen( - phoneNumber: String, - codeLength: Int, - codeType: String, - nextCodeType: String? = null, - timeout: Int = 0, - emailPattern: String? = null, - onConfirm: (String) -> Unit, - onResend: () -> Unit, - onBack: () -> Unit, - isSubmitting: Boolean -) { - var code by remember { mutableStateOf("") } - val maxCodeLength = if (codeLength > 0) codeLength else 5 - val configuration = LocalConfiguration.current - val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE - val scrollState = rememberScrollState() - - val focusRequester = remember { FocusRequester() } - val focusManager = LocalFocusManager.current - val keyboardController = LocalSoftwareKeyboardController.current - val clipboardManager = LocalClipboardManager.current - var isFocused by remember { mutableStateOf(false) } - var showPasteMenu by remember { mutableStateOf(false) } - - val isKeyboardVisible = WindowInsets.ime.getBottom(LocalDensity.current) > 0 - val isInputMode = isKeyboardVisible || isFocused - - var timeLeft by remember(timeout) { mutableIntStateOf(timeout) } - LaunchedEffect(timeLeft) { - if (timeLeft > 0) { - delay(1000L) - timeLeft -= 1 - } - } - - LaunchedEffect(isKeyboardVisible) { - if (!isKeyboardVisible && isFocused) { - focusManager.clearFocus() - } - } - - BackHandler(enabled = isFocused) { - focusManager.clearFocus() - } - - val iconSize by animateDpAsState( - targetValue = if (isInputMode) 0.dp else 80.dp, - animationSpec = spring(stiffness = Spring.StiffnessLow), - label = "iconSize" - ) - val iconAlpha by animateFloatAsState( - targetValue = if (isInputMode) 0f else 1f, - animationSpec = tween(durationMillis = 300), - label = "iconAlpha" - ) - val topSpacerHeight by animateDpAsState( - targetValue = if (isInputMode) 0.dp else 32.dp, - animationSpec = spring(stiffness = Spring.StiffnessLow), - label = "topSpacerHeight" - ) - val middleSpacerHeight by animateDpAsState( - targetValue = if (isInputMode) 24.dp else 48.dp, - animationSpec = spring(stiffness = Spring.StiffnessLow), - label = "middleSpacerHeight" - ) - - val content: @Composable () -> Unit = { - Spacer(modifier = Modifier.height(topSpacerHeight)) - - Box( - modifier = Modifier - .size(iconSize) - .alpha(iconAlpha), - contentAlignment = Alignment.Center - ) { - Surface( - modifier = Modifier - .requiredSize(80.dp) - .graphicsLayer { - val scale = if (iconSize.value > 0) iconSize.value / 80f else 0f - scaleX = scale - scaleY = scale - }, - shape = CircleShape, - color = MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.4f) - ) { - Box(contentAlignment = Alignment.Center) { - Icon( - imageVector = Icons.Default.Lock, - contentDescription = null, - modifier = Modifier.size(40.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - } - } - - Spacer(modifier = Modifier.height(if (isInputMode) 12.dp else 24.dp)) - - Text( - text = phoneNumber, - style = if (isInputMode) MaterialTheme.typography.titleLarge else MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - textAlign = TextAlign.Center - ) - - Spacer(modifier = Modifier.height(if (isInputMode) 4.dp else 12.dp)) - - val deliveryMessage = when { - codeType.contains("Email", ignoreCase = true) -> - stringResource(R.string.verification_delivery_email, emailPattern ?: "") - - codeType.contains( - "TelegramMessage", - ignoreCase = true - ) -> stringResource(R.string.verification_delivery_telegram) - - codeType.contains("Sms", ignoreCase = true) -> stringResource(R.string.verification_delivery_sms) - codeType.contains("Call", ignoreCase = true) -> stringResource(R.string.verification_delivery_call) - else -> stringResource(R.string.verification_delivery_default) - } - - Text( - text = deliveryMessage, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center - ) - - Spacer(modifier = Modifier.height(middleSpacerHeight)) - - Box(contentAlignment = Alignment.Center) { - BasicTextField( - value = code, - onValueChange = { - if (it.length <= maxCodeLength && it.all { char -> char.isDigit() }) { - code = it - if (code.length == maxCodeLength) { - onConfirm(code) - } - } - }, - keyboardOptions = KeyboardOptions( - keyboardType = KeyboardType.Number, - imeAction = ImeAction.Done - ), - keyboardActions = KeyboardActions( - onDone = { - if (code.length == maxCodeLength) { - onConfirm(code) - } else { - focusManager.clearFocus() - } - } - ), - modifier = Modifier - .size(1.dp) - .alpha(0f) - .focusRequester(focusRequester) - .onFocusChanged { isFocused = it.isFocused }, - decorationBox = { } - ) - - Row( - horizontalArrangement = Arrangement.spacedBy(12.dp), - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.combinedClickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null, - onClick = { - focusRequester.requestFocus() - keyboardController?.show() - }, - onLongClick = { - if (clipboardManager.hasText()) { - showPasteMenu = true - } - } - ) - ) { - repeat(maxCodeLength) { index -> - val char = code.getOrNull(index)?.toString() ?: "" - val isBoxFocused = code.length == index && isFocused - - Surface( - modifier = Modifier.size(width = 50.dp, height = 64.dp), - shape = RoundedCornerShape(16.dp), - color = if (isBoxFocused) MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.3f) - else MaterialTheme.colorScheme.surfaceContainerHigh, - border = if (isBoxFocused) BorderStroke( - 2.dp, - MaterialTheme.colorScheme.primary - ) else null - ) { - Box(contentAlignment = Alignment.Center) { - Text( - text = char, - style = MaterialTheme.typography.headlineMedium, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - } - } - } - } - - DropdownMenu( - expanded = showPasteMenu, - onDismissRequest = { showPasteMenu = false }, - offset = DpOffset(0.dp, 0.dp) - ) { - DropdownMenuItem( - text = { Text(stringResource(R.string.paste_action)) }, - onClick = { - val pastedText = clipboardManager.getText()?.text ?: "" - val digits = pastedText.filter { it.isDigit() }.take(maxCodeLength) - if (digits.isNotEmpty()) { - code = digits - if (code.length == maxCodeLength) { - onConfirm(code) - } - } - showPasteMenu = false - } - ) - } - } - - Spacer(modifier = Modifier.height(middleSpacerHeight)) - - if (isSubmitting) { - CircularProgressIndicator(modifier = Modifier.size(32.dp)) - } else { - Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { - Button( - onClick = { onConfirm(code) }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - enabled = code.length == maxCodeLength, - shape = RoundedCornerShape(24.dp) - ) { - Text(stringResource(R.string.confirm_button), fontSize = 18.sp, fontWeight = FontWeight.Bold) - Spacer(modifier = Modifier.width(8.dp)) - Icon(Icons.AutoMirrored.Filled.ArrowForward, contentDescription = null) - } - - if (timeLeft > 0) { - val minutes = timeLeft / 60 - val seconds = timeLeft % 60 - Text( - text = stringResource(R.string.resend_code_timer, String.format("%02d:%02d", minutes, seconds)), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.fillMaxWidth(), - textAlign = TextAlign.Center - ) - } else if (nextCodeType != null) { - TextButton( - onClick = onResend, - modifier = Modifier.fillMaxWidth() - ) { - Icon( - Icons.Default.Refresh, - contentDescription = null, - modifier = Modifier.size(18.dp) - ) - Spacer(modifier = Modifier.width(8.dp)) - val resendText = when { - nextCodeType.contains("Sms", ignoreCase = true) -> stringResource(R.string.resend_via_sms) - nextCodeType.contains("Call", ignoreCase = true) -> stringResource(R.string.resend_via_call) - else -> stringResource(R.string.resend_code) - } - Text(resendText) - } - } - - TextButton( - onClick = onBack, - modifier = Modifier.fillMaxWidth() - ) { - Icon( - Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = null, - modifier = Modifier.size(18.dp) - ) - Spacer(modifier = Modifier.width(8.dp)) - Text(stringResource(R.string.wrong_number)) - } - } - } - - Spacer(modifier = Modifier.height(24.dp)) - } - - Surface( - modifier = Modifier - .fillMaxSize() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null - ) { focusManager.clearFocus() }, - color = MaterialTheme.colorScheme.background - ) { - if (isLandscape) { - Row(modifier = Modifier - .fillMaxSize() - .imePadding()) { - Column( - modifier = Modifier - .weight(1f) - .fillMaxHeight() - .verticalScroll(scrollState) - .padding(horizontal = 24.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center - ) { - content() - } - } - } else { - Column( - modifier = Modifier - .fillMaxSize() - .imePadding() - ) { - Column( - modifier = Modifier - .weight(1f) - .fillMaxWidth() - .verticalScroll(scrollState) - .padding(horizontal = 32.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - content() - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/auth/components/LoadingScreen.kt b/presentation/src/main/java/org/monogram/presentation/features/auth/components/LoadingScreen.kt deleted file mode 100644 index 1057143c..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/auth/components/LoadingScreen.kt +++ /dev/null @@ -1,77 +0,0 @@ -package org.monogram.presentation.features.auth.components - -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.fadeIn -import androidx.compose.foundation.layout.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import kotlinx.coroutines.delay -import org.monogram.presentation.R - -@Composable -fun LoadingScreen( - onReset: () -> Unit -) { - var showResetButton by remember { mutableStateOf(false) } - - LaunchedEffect(Unit) { - delay(10000) - showResetButton = true - } - - Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, - modifier = Modifier - .fillMaxSize() - .padding(24.dp) - ) { - CircularProgressIndicator( - modifier = Modifier.size(48.dp), - color = MaterialTheme.colorScheme.primary, - strokeWidth = 4.dp - ) - Spacer(modifier = Modifier.height(24.dp)) - - Text( - text = stringResource(R.string.startup_connecting), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.onSurface - ) - - Spacer(modifier = Modifier.height(8.dp)) - - Text( - text = stringResource(R.string.loading_please_wait), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - - AnimatedVisibility( - visible = showResetButton, - enter = fadeIn() - ) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Spacer(modifier = Modifier.height(48.dp)) - Text( - text = stringResource(R.string.loading_taking_too_long), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.height(12.dp)) - OutlinedButton( - onClick = onReset, - colors = ButtonDefaults.outlinedButtonColors( - contentColor = MaterialTheme.colorScheme.error - ) - ) { - Text(stringResource(R.string.loading_reset_connection)) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/auth/components/PasswordInputScreen.kt b/presentation/src/main/java/org/monogram/presentation/features/auth/components/PasswordInputScreen.kt deleted file mode 100644 index 5bb048d6..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/auth/components/PasswordInputScreen.kt +++ /dev/null @@ -1,248 +0,0 @@ -package org.monogram.presentation.features.auth.components - -import android.content.res.Configuration -import androidx.activity.compose.BackHandler -import androidx.compose.animation.core.* -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowForward -import androidx.compose.material.icons.filled.Visibility -import androidx.compose.material.icons.filled.VisibilityOff -import androidx.compose.material.icons.rounded.VpnKey -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.focus.onFocusChanged -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.text.input.PasswordVisualTransformation -import androidx.compose.ui.text.input.VisualTransformation -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.presentation.R - -@Composable -fun PasswordInputScreen( - onConfirm: (String) -> Unit, - isSubmitting: Boolean -) { - var password by remember { mutableStateOf("") } - var passwordVisible by remember { mutableStateOf(false) } - val focusRequester = remember { FocusRequester() } - val focusManager = LocalFocusManager.current - val configuration = LocalConfiguration.current - val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE - val scrollState = rememberScrollState() - - var isFocused by remember { mutableStateOf(false) } - val isKeyboardVisible = WindowInsets.ime.getBottom(LocalDensity.current) > 0 - val isInputMode = isKeyboardVisible || isFocused - - LaunchedEffect(isKeyboardVisible) { - if (!isKeyboardVisible && isFocused) { - focusManager.clearFocus() - } - } - - BackHandler(enabled = isFocused) { - focusManager.clearFocus() - } - - val iconSize by animateDpAsState( - targetValue = if (isInputMode) 0.dp else 80.dp, - animationSpec = spring(stiffness = Spring.StiffnessLow), - label = "iconSize" - ) - val iconAlpha by animateFloatAsState( - targetValue = if (isInputMode) 0f else 1f, - animationSpec = tween(durationMillis = 300), - label = "iconAlpha" - ) - val topSpacerHeight by animateDpAsState( - targetValue = if (isInputMode) 0.dp else 32.dp, - animationSpec = spring(stiffness = Spring.StiffnessLow), - label = "topSpacerHeight" - ) - val middleSpacerHeight by animateDpAsState( - targetValue = if (isInputMode) 24.dp else 40.dp, - animationSpec = spring(stiffness = Spring.StiffnessLow), - label = "middleSpacerHeight" - ) - - val content: @Composable () -> Unit = { - Spacer(modifier = Modifier.height(topSpacerHeight)) - - Box( - modifier = Modifier - .size(iconSize) - .alpha(iconAlpha), - contentAlignment = Alignment.Center - ) { - Surface( - modifier = Modifier - .requiredSize(80.dp) - .graphicsLayer { - val scale = if (iconSize.value > 0) iconSize.value / 80f else 0f - scaleX = scale - scaleY = scale - }, - shape = CircleShape, - color = MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.4f) - ) { - Box(contentAlignment = Alignment.Center) { - Icon( - imageVector = Icons.Rounded.VpnKey, - contentDescription = null, - modifier = Modifier.size(40.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - } - } - - Spacer(modifier = Modifier.height(if (isInputMode) 12.dp else 24.dp)) - - Text( - text = stringResource(R.string.two_step_verification_title), - style = if (isInputMode) MaterialTheme.typography.titleLarge else MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - textAlign = TextAlign.Center - ) - - Spacer(modifier = Modifier.height(if (isInputMode) 4.dp else 12.dp)) - - Text( - text = stringResource(R.string.two_step_verification_description), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center - ) - - Spacer(modifier = Modifier.height(middleSpacerHeight)) - - OutlinedTextField( - value = password, - onValueChange = { password = it }, - label = { Text(stringResource(R.string.password_label)) }, - modifier = Modifier - .fillMaxWidth() - .focusRequester(focusRequester) - .onFocusChanged { isFocused = it.isFocused }, - singleLine = true, - enabled = !isSubmitting, - visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(), - keyboardOptions = KeyboardOptions( - keyboardType = KeyboardType.Password, - imeAction = ImeAction.Done - ), - keyboardActions = KeyboardActions( - onDone = { if (password.isNotBlank()) onConfirm(password) } - ), - trailingIcon = { - val image = if (passwordVisible) - Icons.Filled.Visibility - else - Icons.Filled.VisibilityOff - - IconButton(onClick = { passwordVisible = !passwordVisible }) { - Icon(imageVector = image, contentDescription = null) - } - }, - shape = RoundedCornerShape(24.dp), - colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = MaterialTheme.colorScheme.primary, - unfocusedBorderColor = MaterialTheme.colorScheme.outline, - focusedContainerColor = MaterialTheme.colorScheme.surfaceContainer, - unfocusedContainerColor = MaterialTheme.colorScheme.surfaceContainer, - ) - ) - - Spacer(modifier = Modifier.height(32.dp)) - - Button( - onClick = { onConfirm(password) }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - enabled = password.isNotBlank() && !isSubmitting, - shape = RoundedCornerShape(24.dp) - ) { - if (isSubmitting) { - CircularProgressIndicator( - modifier = Modifier.size(24.dp), - color = MaterialTheme.colorScheme.onPrimary, - strokeWidth = 2.dp - ) - } else { - Text(stringResource(R.string.unlock_button), fontSize = 18.sp, fontWeight = FontWeight.Bold) - Spacer(modifier = Modifier.width(8.dp)) - Icon(Icons.AutoMirrored.Filled.ArrowForward, contentDescription = null) - } - } - - Spacer(modifier = Modifier.height(24.dp)) - } - - Surface( - modifier = Modifier - .fillMaxSize() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null - ) { focusManager.clearFocus() }, - color = MaterialTheme.colorScheme.background - ) { - if (isLandscape) { - Row( - modifier = Modifier - .fillMaxSize() - .imePadding() - .verticalScroll(scrollState) - .padding(horizontal = 32.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(32.dp) - ) { - Column( - modifier = Modifier.weight(1f), - horizontalAlignment = Alignment.CenterHorizontally - ) { - content() - } - } - } else { - Column( - modifier = Modifier - .fillMaxSize() - .imePadding() - .verticalScroll(scrollState) - .padding(horizontal = 32.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - content() - } - } - } - - LaunchedEffect(Unit) { - focusRequester.requestFocus() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/auth/components/PhoneInputScreen.kt b/presentation/src/main/java/org/monogram/presentation/features/auth/components/PhoneInputScreen.kt deleted file mode 100644 index c60a37b0..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/auth/components/PhoneInputScreen.kt +++ /dev/null @@ -1,527 +0,0 @@ -package org.monogram.presentation.features.auth.components - -import android.content.res.Configuration -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.animateDpAsState -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.spring -import androidx.compose.animation.core.tween -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.ime -import androidx.compose.foundation.layout.imePadding -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.requiredSize -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.BasicTextField -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowForward -import androidx.compose.material.icons.filled.ArrowDropDown -import androidx.compose.material.icons.filled.Phone -import androidx.compose.material.icons.filled.Search -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.CircularProgressIndicator -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.ModalBottomSheet -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.material3.VerticalDivider -import androidx.compose.material3.rememberModalBottomSheetState -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.draw.clip -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.focus.onFocusChanged -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.platform.LocalSoftwareKeyboardController -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.TextRange -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.text.input.TextFieldValue -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.util.Country -import org.monogram.presentation.core.util.CountryManager -import org.monogram.presentation.features.chats.chatList.components.SettingsTextField -import java.util.Locale - -enum class ActiveField { - CODE, PHONE -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun PhoneInputScreen( - onConfirm: (String) -> Unit, - isSubmitting: Boolean -) { - val countries = remember { CountryManager.getCountries() } - val defaultCountry = remember { - val currentIso = Locale.getDefault().country - countries.find { it.iso == currentIso } ?: countries.find { it.code == "380" } ?: countries.first() - } - - var phoneBody by remember { mutableStateOf("") } - var selectedCountry by remember { mutableStateOf(defaultCountry) } - var codeInput by remember { mutableStateOf(selectedCountry.code) } - - var showCountryPicker by remember { mutableStateOf(false) } - var activeField by remember { mutableStateOf(ActiveField.PHONE) } - var searchQuery by remember { mutableStateOf("") } - - val scrollState = rememberScrollState() - val configuration = LocalConfiguration.current - val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE - - val focusRequester = remember { FocusRequester() } - val focusManager = LocalFocusManager.current - val keyboardController = LocalSoftwareKeyboardController.current - var isFocused by remember { mutableStateOf(false) } - val isKeyboardVisible = WindowInsets.ime.getBottom(LocalDensity.current) > 0 - val isInputMode = isKeyboardVisible || isFocused - - val iconSize by animateDpAsState( - targetValue = if (isInputMode) 0.dp else 72.dp, - animationSpec = spring(stiffness = Spring.StiffnessLow), - label = "iconSize" - ) - val iconAlpha by animateFloatAsState( - targetValue = if (isInputMode) 0f else 1f, - animationSpec = tween(durationMillis = 300), - label = "iconAlpha" - ) - val topSpacerHeight by animateDpAsState( - targetValue = if (isInputMode) 0.dp else 24.dp, - animationSpec = spring(stiffness = Spring.StiffnessLow), - label = "topSpacerHeight" - ) - val middleSpacerHeight by animateDpAsState( - targetValue = if (isInputMode) 16.dp else 32.dp, - animationSpec = spring(stiffness = Spring.StiffnessLow), - label = "middleSpacerHeight" - ) - - fun onCodeChanged(newCode: String) { - if (newCode.length <= 4) { - codeInput = newCode - countries.find { it.code == newCode }?.let { selectedCountry = it } - } - } - - fun onCountrySelected(country: Country) { - selectedCountry = country - codeInput = country.code - showCountryPicker = false - searchQuery = "" - activeField = ActiveField.PHONE - } - - val fullNumber = "+$codeInput$phoneBody" - val isFormValid = codeInput.isNotEmpty() && phoneBody.length >= selectedCountry.getMobileNumberLength() - - val content: @Composable () -> Unit = { - Spacer(modifier = Modifier.height(topSpacerHeight)) - - Box( - modifier = Modifier - .size(iconSize) - .alpha(iconAlpha), - contentAlignment = Alignment.Center - ) { - Surface( - modifier = Modifier - .requiredSize(72.dp) - .graphicsLayer { - val scale = if (iconSize.value > 0) iconSize.value / 72f else 0f - scaleX = scale - scaleY = scale - }, - shape = CircleShape, - color = MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.4f) - ) { - Box(contentAlignment = Alignment.Center) { - Icon( - imageVector = Icons.Default.Phone, - contentDescription = null, - modifier = Modifier.size(36.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - } - } - - Spacer(modifier = Modifier.height(if (isInputMode) 8.dp else 16.dp)) - - Text( - text = stringResource(R.string.phone_input_title), - style = if (isInputMode) MaterialTheme.typography.titleLarge else MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - textAlign = TextAlign.Center - ) - - Spacer(modifier = Modifier.height(if (isInputMode) 4.dp else 8.dp)) - - Text( - text = stringResource(R.string.phone_input_description), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center, - modifier = Modifier.padding(horizontal = 16.dp) - ) - - Spacer(modifier = Modifier.height(middleSpacerHeight)) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier - .fillMaxWidth() - .clip(RoundedCornerShape(24.dp)) - .clickable(enabled = !isSubmitting) { - focusManager.clearFocus() - showCountryPicker = true - } - ) { - Row( - modifier = Modifier.padding(horizontal = 16.dp, vertical = 16.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(40.dp) - .background(color = MaterialTheme.colorScheme.primary.copy(0.15f), shape = CircleShape), - contentAlignment = Alignment.Center - ) { - Text(selectedCountry.flagEmoji, fontSize = 20.sp) - } - Spacer(modifier = Modifier.width(16.dp)) - Column(modifier = Modifier.weight(1f)) { - Text( - text = selectedCountry.name, - style = MaterialTheme.typography.titleMedium, - ) - Text( - text = stringResource(R.string.country_label), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - Icon(Icons.Default.ArrowDropDown, null, tint = MaterialTheme.colorScheme.onSurfaceVariant) - } - } - - Spacer(modifier = Modifier.height(12.dp)) - - Box { - val textFieldValue = remember(activeField, codeInput, phoneBody) { - val text = if (activeField == ActiveField.CODE) codeInput else phoneBody - TextFieldValue(text = text, selection = TextRange(text.length)) - } - - BasicTextField( - value = textFieldValue, - onValueChange = { - val newText = it.text.filter { char -> char.isDigit() } - if (activeField == ActiveField.CODE) { - onCodeChanged(newText) - } else { - if (newText.length <= 15) phoneBody = newText - } - }, - keyboardOptions = KeyboardOptions( - keyboardType = KeyboardType.Number, - imeAction = if (activeField == ActiveField.CODE) ImeAction.Next else ImeAction.Done - ), - keyboardActions = KeyboardActions( - onNext = { - activeField = ActiveField.PHONE - }, - onDone = { - if (isFormValid) { - onConfirm(fullNumber) - } else { - focusManager.clearFocus() - } - } - ), - modifier = Modifier - .size(1.dp) - .alpha(0f) - .focusRequester(focusRequester) - .onFocusChanged { isFocused = it.isFocused }, - decorationBox = { } - ) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - Row( - modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .width(70.dp) - .clip(RoundedCornerShape(16.dp)) - .clickable(enabled = !isSubmitting) { - activeField = ActiveField.CODE - focusRequester.requestFocus() - keyboardController?.show() - } - .padding(vertical = 8.dp), - contentAlignment = Alignment.Center - ) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Text( - text = "+$codeInput", - style = MaterialTheme.typography.titleMedium, - color = if (activeField == ActiveField.CODE && isFocused) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface - ) - Text( - stringResource(R.string.code_label), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - - VerticalDivider( - modifier = Modifier - .height(32.dp) - .padding(horizontal = 8.dp), - color = MaterialTheme.colorScheme.outlineVariant - ) - - Box( - modifier = Modifier - .weight(1f) - .clip(RoundedCornerShape(16.dp)) - .clickable(enabled = !isSubmitting) { - activeField = ActiveField.PHONE - focusRequester.requestFocus() - keyboardController?.show() - } - .padding(vertical = 8.dp), - contentAlignment = Alignment.CenterStart - ) { - Column { - Text( - text = if (phoneBody.isEmpty()) stringResource(R.string.phone_number_placeholder) else phoneBody, - style = MaterialTheme.typography.titleMedium, - color = if (phoneBody.isEmpty()) MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f) - else if (activeField == ActiveField.PHONE && isFocused) MaterialTheme.colorScheme.primary - else MaterialTheme.colorScheme.onSurface - ) - Text( - stringResource(R.string.phone_number_label), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } - } - } - - Spacer(modifier = Modifier.height(24.dp)) - - Button( - onClick = { onConfirm(fullNumber) }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - enabled = isFormValid && !isSubmitting, - shape = RoundedCornerShape(24.dp), - colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.primary, - contentColor = MaterialTheme.colorScheme.onPrimary - ) - ) { - if (isSubmitting) { - CircularProgressIndicator( - modifier = Modifier.size(24.dp), - color = MaterialTheme.colorScheme.onPrimary, - strokeWidth = 2.dp - ) - } else { - Text(stringResource(R.string.continue_button), fontSize = 18.sp, fontWeight = FontWeight.Bold) - Spacer(modifier = Modifier.width(8.dp)) - Icon(Icons.AutoMirrored.Filled.ArrowForward, contentDescription = null) - } - } - - Spacer(modifier = Modifier.height(24.dp)) - } - - Surface( - modifier = Modifier - .fillMaxSize() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null - ) { focusManager.clearFocus() }, - color = MaterialTheme.colorScheme.background - ) { - if (isLandscape) { - Row(modifier = Modifier - .fillMaxSize() - .imePadding()) { - Column( - modifier = Modifier - .weight(1f) - .fillMaxHeight() - .verticalScroll(scrollState) - .padding(horizontal = 24.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center - ) { - content() - } - } - } else { - Column( - modifier = Modifier - .fillMaxSize() - .imePadding() - ) { - Column( - modifier = Modifier - .weight(1f) - .fillMaxWidth() - .verticalScroll(scrollState) - .padding(horizontal = 24.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - content() - } - } - } - } - - if (showCountryPicker) { - ModalBottomSheet( - onDismissRequest = { - showCountryPicker = false - searchQuery = "" - }, - containerColor = MaterialTheme.colorScheme.surface, - shape = RoundedCornerShape(topStart = 28.dp, topEnd = 28.dp), - sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) - ) { - Column(modifier = Modifier.padding(bottom = 16.dp)) { - Text( - stringResource(R.string.select_country_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp) - ) - - Box(modifier = Modifier.padding(horizontal = 16.dp)) { - SettingsTextField( - value = searchQuery, - onValueChange = { searchQuery = it }, - placeholder = stringResource(R.string.search_country_hint), - icon = Icons.Default.Search, - position = ItemPosition.STANDALONE, - singleLine = true - ) - } - - val filteredCountries = remember(searchQuery, countries) { - if (searchQuery.isBlank()) countries - else countries.filter { - it.name.contains(searchQuery, ignoreCase = true) || - it.code.contains(searchQuery) - } - } - - Spacer(modifier = Modifier.height(16.dp)) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainerLow, - shape = RoundedCornerShape(28.dp), - modifier = Modifier - .weight(1f) - .fillMaxWidth() - .padding(horizontal = 16.dp) - ) { - LazyColumn( - modifier = Modifier.fillMaxSize() - ) { - itemsIndexed(filteredCountries) { index, country -> - Row( - modifier = Modifier - .fillMaxWidth() - .clickable { onCountrySelected(country) } - .padding(horizontal = 20.dp, vertical = 16.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Text(country.flagEmoji, fontSize = 24.sp) - Spacer(modifier = Modifier.width(16.dp)) - Text( - text = country.name, - modifier = Modifier.weight(1f), - style = MaterialTheme.typography.bodyLarge, - fontWeight = FontWeight.Medium - ) - Text( - text = "+${country.code}", - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) - } - if (index < filteredCountries.size - 1) { - HorizontalDivider( - modifier = Modifier.padding(horizontal = 20.dp), - thickness = 0.5.dp, - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - } - } - } - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/camera/CameraScreen.kt b/presentation/src/main/java/org/monogram/presentation/features/camera/CameraScreen.kt deleted file mode 100644 index 6912782b..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/camera/CameraScreen.kt +++ /dev/null @@ -1,186 +0,0 @@ -package org.monogram.presentation.features.camera - -import android.content.ContentValues -import android.net.Uri -import android.os.Build -import android.provider.MediaStore -import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.tween -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.navigationBarsPadding -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.CameraAlt -import androidx.compose.material.icons.filled.Close -import androidx.compose.material3.Button -import androidx.compose.material3.Card -import androidx.compose.material3.CardDefaults -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch - -@Composable -fun CameraScreen( - onImageCaptured: (Uri) -> Unit, - onDismiss: () -> Unit -) { - val context = LocalContext.current - val scope = rememberCoroutineScope() - var isOpen by remember { mutableStateOf(false) } - val progress by animateFloatAsState( - targetValue = if (isOpen) 1f else 0f, - animationSpec = tween(240), - label = "cameraSheetProgress" - ) - - val dismiss: () -> Unit = { - if (isOpen) { - isOpen = false - scope.launch { - delay(220) - onDismiss() - } - } - } - - var pendingCaptureUri by remember { mutableStateOf(null) } - val cameraLauncher = rememberLauncherForActivityResult( - contract = ActivityResultContracts.TakePicture() - ) { success -> - if (success) { - pendingCaptureUri?.let(onImageCaptured) - } - pendingCaptureUri = null - } - - LaunchedEffect(Unit) { - isOpen = true - } - - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.BottomCenter - ) { - Box( - modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.scrim.copy(alpha = 0.45f * progress)) - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null, - onClick = dismiss - ) - ) - Surface( - modifier = Modifier - .fillMaxWidth() - .navigationBarsPadding() - .graphicsLayer { - translationY = (1f - progress) * 140f - alpha = 0.7f + 0.3f * progress - }, - shape = MaterialTheme.shapes.extraLarge, - tonalElevation = 8.dp - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp), - verticalArrangement = Arrangement.spacedBy(12.dp) - ) { - Box(modifier = Modifier.fillMaxWidth()) { - Text( - text = "Camera", - style = MaterialTheme.typography.titleLarge, - modifier = Modifier.align(Alignment.CenterStart) - ) - IconButton( - onClick = dismiss, - modifier = Modifier.align(Alignment.CenterEnd) - ) { - Icon(Icons.Filled.Close, contentDescription = "Close") - } - } - - Card( - colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.surfaceContainerHigh - ) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp), - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - Text( - text = "Take a high-quality photo", - style = MaterialTheme.typography.titleMedium - ) - Text( - text = "Photo will be added to input attachments.", - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - - Button( - onClick = { - val uri = context.newCameraPhotoUri() ?: return@Button - pendingCaptureUri = uri - cameraLauncher.launch(uri) - }, - modifier = Modifier.fillMaxWidth() - ) { - Icon(Icons.Filled.CameraAlt, contentDescription = null) - Spacer(Modifier.width(8.dp)) - Text("Open Camera") - } - } - } - } -} - -private fun android.content.Context.newCameraPhotoUri(): Uri? { - return try { - val values = ContentValues().apply { - put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg") - put(MediaStore.Images.Media.DISPLAY_NAME, "camera_${System.nanoTime()}.jpg") - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/Monogram") - } - } - contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values) - } catch (_: Exception) { - null - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/ChatListComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/ChatListComponent.kt deleted file mode 100644 index 57027e0b..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/ChatListComponent.kt +++ /dev/null @@ -1,91 +0,0 @@ -package org.monogram.presentation.features.chats - -import kotlinx.coroutines.flow.StateFlow -import org.monogram.domain.models.* -import org.monogram.domain.repository.ConnectionStatus -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -interface ChatListComponent { - val state: StateFlow - val videoPlayerPool: VideoPlayerPool - val appPreferences: AppPreferences - - fun onChatClicked(id: Long) - fun onProfileClicked(id: Long) - fun onMessageClicked(chatId: Long, messageId: Long) - fun onSettingsClicked() - fun onFolderClicked(id: Int) - fun loadMore(folderId: Int? = null) - fun loadMoreMessages() - fun onChatLongClicked(id: Long) - fun clearSelection() - fun retryConnection() - fun onSearchToggle() - fun onSearchQueryChange(query: String) - fun onSetEmojiStatus(customEmojiId: Long, statusPath: String?) - fun onClearSearchHistory() - fun onRemoveSearchHistoryItem(chatId: Long) - fun onMuteSelected(mute: Boolean) - fun onArchiveSelected(archive: Boolean) - fun onPinSelected() - fun onToggleReadSelected() - fun onDeleteSelected() - fun onArchivePinToggle() - fun onConfirmForwarding() - fun onNewChatClicked() - fun onProxySettingsClicked() - fun onEditFoldersClicked() - fun onDeleteFolder(folderId: Int) - fun onEditFolder(folderId: Int) - - fun onOpenInstantView(url: String) - fun onDismissInstantView() - - fun onOpenWebApp(url: String, botUserId: Long, botName: String) - fun onDismissWebApp() - - fun onOpenWebView(url: String) - fun onDismissWebView() - - fun onUpdateClicked() - - fun handleBack(): Boolean - - fun updateScrollPosition(folderId: Int, index: Int, offset: Int) - - data class State( - val chatsByFolder: Map> = emptyMap(), - val folders: List = emptyList(), - val selectedFolderId: Int = -1, - val currentUser: UserModel? = null, - val isLoadingByFolder: Map = emptyMap(), - val selectedChatIds: Set = emptySet(), - val isSearchActive: Boolean = false, - val searchQuery: String = "", - val searchResults: List = emptyList(), - val globalSearchResults: List = emptyList(), - val messageSearchResults: List = emptyList(), - val searchHistory: List = emptyList(), - val connectionStatus: ConnectionStatus = ConnectionStatus.Connected, - val isArchivePinned: Boolean = true, - val isArchiveAlwaysVisible: Boolean = false, - val isForwarding: Boolean = false, - val canLoadMoreMessages: Boolean = false, - val instantViewUrl: String? = null, - val activeChatId: Long? = null, - val isProxyEnabled: Boolean = false, - val attachMenuBots: List = emptyList(), - val botWebAppUrl: String? = null, - val botWebAppName: String? = null, - val webAppUrl: String? = null, - val webAppBotId: Long? = null, - val webAppBotName: String? = null, - val webViewUrl: String? = null, - val updateState: UpdateState = UpdateState.Idle, - val scrollPositions: Map> = emptyMap() - ) { - val chats: List get() = chatsByFolder[selectedFolderId] ?: emptyList() - val isLoading: Boolean get() = isLoadingByFolder[selectedFolderId] ?: false - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/ChatListStore.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/ChatListStore.kt deleted file mode 100644 index 6a894216..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/ChatListStore.kt +++ /dev/null @@ -1,48 +0,0 @@ -package org.monogram.presentation.features.chats - -import com.arkivanov.mvikotlin.core.store.Store - -interface ChatListStore : Store { - - sealed class Intent { - data class ChatClicked(val id: Long) : Intent() - data class ProfileClicked(val id: Long) : Intent() - data class MessageClicked(val chatId: Long, val messageId: Long) : Intent() - object SettingsClicked : Intent() - data class FolderClicked(val id: Int) : Intent() - data class LoadMore(val folderId: Int? = null) : Intent() - object LoadMoreMessages : Intent() - data class ChatLongClicked(val id: Long) : Intent() - object ClearSelection : Intent() - object RetryConnection : Intent() - object SearchToggle : Intent() - data class SearchQueryChange(val query: String) : Intent() - object ClearSearchHistory : Intent() - data class RemoveSearchHistoryItem(val chatId: Long) : Intent() - data class MuteSelected(val mute: Boolean) : Intent() - data class ArchiveSelected(val archive: Boolean) : Intent() - object DeleteSelected : Intent() - object ArchivePinToggle : Intent() - object ConfirmForwarding : Intent() - object NewChatClicked : Intent() - object ProxySettingsClicked : Intent() - data class OpenInstantView(val url: String) : Intent() - object DismissInstantView : Intent() - data class OpenWebApp(val url: String, val botUserId: Long, val botName: String) : Intent() - object DismissWebApp : Intent() - data class OpenWebView(val url: String) : Intent() - object DismissWebView : Intent() - object UpdateClicked : Intent() - data class UpdateScrollPosition(val folderId: Int, val index: Int, val offset: Int) : Intent() - data class UpdateState(val state: ChatListComponent.State) : Intent() - } - - sealed class Label { - data class ChatClicked(val id: Long) : Label() - data class ProfileClicked(val id: Long) : Label() - data class MessageClicked(val chatId: Long, val messageId: Long) : Label() - object SettingsClicked : Label() - object NewChatClicked : Label() - object ProxySettingsClicked : Label() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/ChatListStoreFactory.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/ChatListStoreFactory.kt deleted file mode 100644 index 6f1e9485..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/ChatListStoreFactory.kt +++ /dev/null @@ -1,76 +0,0 @@ -package org.monogram.presentation.features.chats - -import com.arkivanov.mvikotlin.core.store.Reducer -import com.arkivanov.mvikotlin.core.store.Store -import com.arkivanov.mvikotlin.core.store.StoreFactory -import com.arkivanov.mvikotlin.extensions.coroutines.CoroutineExecutor -import org.monogram.presentation.features.chats.ChatListStore.Intent -import org.monogram.presentation.features.chats.ChatListStore.Label -import org.monogram.presentation.features.chats.chatList.DefaultChatListComponent - -class ChatListStoreFactory( - private val storeFactory: StoreFactory, - private val component: DefaultChatListComponent -) { - - fun create(): ChatListStore = - object : ChatListStore, Store by storeFactory.create( - name = "ChatListStore", - initialState = ChatListComponent.State(isForwarding = component.isForwarding), - executorFactory = ::ExecutorImpl, - reducer = ReducerImpl - ) {} - - private inner class ExecutorImpl : CoroutineExecutor() { - override fun executeIntent(intent: Intent) { - when (intent) { - is Intent.ChatClicked -> component.onChatClicked(intent.id) - is Intent.ProfileClicked -> component.onProfileClicked(intent.id) - is Intent.MessageClicked -> component.onMessageClicked(intent.chatId, intent.messageId) - Intent.SettingsClicked -> component.onSettingsClicked() - is Intent.FolderClicked -> component.onFolderClicked(intent.id) - is Intent.LoadMore -> component.loadMore(intent.folderId) - Intent.LoadMoreMessages -> component.loadMoreMessages() - is Intent.ChatLongClicked -> component.onChatLongClicked(id = intent.id) - Intent.ClearSelection -> component.clearSelection() - Intent.RetryConnection -> component.retryConnection() - Intent.SearchToggle -> component.onSearchToggle() - is Intent.SearchQueryChange -> component.onSearchQueryChange(intent.query) - Intent.ClearSearchHistory -> component.onClearSearchHistory() - is Intent.RemoveSearchHistoryItem -> component.onRemoveSearchHistoryItem(intent.chatId) - is Intent.MuteSelected -> component.onMuteSelected(intent.mute) - is Intent.ArchiveSelected -> component.onArchiveSelected(archive = intent.archive) - Intent.DeleteSelected -> component.onDeleteSelected() - Intent.ArchivePinToggle -> component.onArchivePinToggle() - Intent.ConfirmForwarding -> component.onConfirmForwarding() - Intent.NewChatClicked -> component.onNewChatClicked() - Intent.ProxySettingsClicked -> component.onProxySettingsClicked() - is Intent.OpenInstantView -> component.onOpenInstantView(intent.url) - Intent.DismissInstantView -> component.onDismissInstantView() - is Intent.OpenWebApp -> component.onOpenWebApp(intent.url, intent.botUserId, intent.botName) - Intent.DismissWebApp -> component.onDismissWebApp() - is Intent.OpenWebView -> component.onOpenWebView(intent.url) - Intent.DismissWebView -> component.onDismissWebView() - Intent.UpdateClicked -> component.onUpdateClicked() - is Intent.UpdateScrollPosition -> component.updateScrollPosition( - intent.folderId, - intent.index, - intent.offset - ) - - is Intent.UpdateState -> dispatch(Message.UpdateState(intent.state)) - } - } - } - - private object ReducerImpl : Reducer { - override fun ChatListComponent.State.reduce(msg: Message): ChatListComponent.State = - when (msg) { - is Message.UpdateState -> msg.state - } - } - - sealed class Message { - data class UpdateState(val state: ChatListComponent.State) : Message() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/ChatListContent.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/ChatListContent.kt deleted file mode 100644 index c6be49aa..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/ChatListContent.kt +++ /dev/null @@ -1,1296 +0,0 @@ -package org.monogram.presentation.features.chats.chatList - -import android.util.Log -import androidx.activity.compose.BackHandler -import androidx.compose.animation.* -import androidx.compose.animation.core.MutableTransitionState -import androidx.compose.animation.core.animate -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.tween -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.* -import androidx.compose.foundation.pager.HorizontalPager -import androidx.compose.foundation.pager.rememberPagerState -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.automirrored.rounded.Send -import androidx.compose.material.icons.rounded.Close -import androidx.compose.material.icons.rounded.Delete -import androidx.compose.material.icons.rounded.Edit -import androidx.compose.material.icons.rounded.Search -import androidx.compose.material3.* -import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.geometry.Rect -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.TransformOrigin -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.hapticfeedback.HapticFeedbackType -import androidx.compose.ui.input.nestedscroll.NestedScrollConnection -import androidx.compose.ui.input.nestedscroll.NestedScrollSource -import androidx.compose.ui.input.nestedscroll.nestedScroll -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.LocalHapticFeedback -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.IntOffset -import androidx.compose.ui.unit.Velocity -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.window.core.layout.WindowWidthSizeClass -import kotlinx.coroutines.Job -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.launch -import org.koin.compose.koinInject -import org.monogram.domain.models.ChatType -import org.monogram.domain.repository.ConnectionStatus -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.ui.ConfirmationSheet -import org.monogram.presentation.features.chats.ChatListComponent -import org.monogram.presentation.features.chats.chatList.components.* -import org.monogram.presentation.features.chats.currentChat.components.chats.getEmojiFontFamily -import org.monogram.presentation.features.instantview.InstantViewer -import org.monogram.presentation.features.stickers.ui.menu.EmojisGrid -import org.monogram.presentation.features.webapp.MiniAppViewer -import kotlin.math.abs -import kotlin.math.roundToInt - -@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) -@Composable -fun ChatListContent(component: ChatListComponent) { - val state by component.state.collectAsState() - val scope = rememberCoroutineScope() - - val haptic = LocalHapticFeedback.current - - var showAccountMenu by remember { mutableStateOf(false) } - var showStatusMenu by remember { mutableStateOf(false) } - var showDeleteChatsSheet by remember { mutableStateOf(false) } - var statusAnchorBounds by remember { mutableStateOf(null) } - val statusMenuTransitionState = remember { MutableTransitionState(false) } - - LaunchedEffect(showStatusMenu) { - statusMenuTransitionState.targetState = showStatusMenu - } - - val isPermissionRequested by component.appPreferences.isPermissionRequested.collectAsState() - var showPermissionRequest by remember { mutableStateOf(!isPermissionRequested) } - - val adaptiveInfo = currentWindowAdaptiveInfo() - val isTablet = adaptiveInfo.windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.EXPANDED - - val isCustomBackHandlingEnabled = - state.isSearchActive || state.selectedChatIds.isNotEmpty() || state.selectedFolderId == -2 || state.isForwarding || state.instantViewUrl != null || state.webAppUrl != null || state.webViewUrl != null || showStatusMenu - - BackHandler(enabled = isCustomBackHandlingEnabled) { - if (showStatusMenu) { - showStatusMenu = false - } else { - component.handleBack() - } - } - - val pagerState = rememberPagerState( - initialPage = state.folders.indexOfFirst { it.id == state.selectedFolderId }.coerceAtLeast(0), - pageCount = { state.folders.size } - ) - - LaunchedEffect(state.selectedFolderId) { - val index = state.folders.indexOfFirst { it.id == state.selectedFolderId }.coerceAtLeast(0) - if (pagerState.currentPage != index) pagerState.animateScrollToPage(index) - } - - LaunchedEffect(pagerState.currentPage) { - if (state.folders.isNotEmpty()) { - val folderId = state.folders[pagerState.currentPage].id - if (state.selectedFolderId != folderId && state.selectedFolderId != -2) { - component.onFolderClicked(folderId) - } - } - } - - val density = LocalDensity.current - val tabsHeight = if (state.folders.size > 1) 56.dp else 10.dp - val archiveItemHeight = 78.dp - val tabsHeightPx = with(density) { tabsHeight.toPx() } - val archiveItemHeightPx = with(density) { archiveItemHeight.toPx() } - - var headerOffsetPx by remember { mutableFloatStateOf(0f) } - var archiveRevealPx by remember { mutableFloatStateOf(0f) } - - var revealAnimationJob by remember { mutableStateOf(null) } - var headerAnimationJob by remember { mutableStateOf(null) } - - var hasVibrated by remember { mutableStateOf(false) } - var canRevealArchive by remember { mutableStateOf(true) } - - val currentFolder = state.folders.getOrNull(pagerState.currentPage) - val isMainFolder = currentFolder?.id == -1 - - val isArchivePersistent = state.isArchivePinned && (state.isArchiveAlwaysVisible || isMainFolder) - val canShowArchive = isArchivePersistent || isMainFolder - - val lastArchivePersistent = remember { mutableStateOf(isArchivePersistent) } - - LaunchedEffect(isArchivePersistent) { - if (isArchivePersistent == lastArchivePersistent.value) return@LaunchedEffect - lastArchivePersistent.value = isArchivePersistent - - if (isArchivePersistent) { - val startOffset = if (archiveRevealPx > 0f) { - archiveRevealPx - archiveItemHeightPx - } else { - headerOffsetPx - archiveItemHeightPx - } - - headerOffsetPx = startOffset - archiveRevealPx = 0f - - headerAnimationJob?.cancel() - headerAnimationJob = launch { - animate(initialValue = headerOffsetPx, targetValue = 0f) { value, _ -> - headerOffsetPx = value - } - } - } else { - val currentVisibleArchiveHeight = (archiveItemHeightPx + headerOffsetPx).coerceAtLeast(0f) - archiveRevealPx = currentVisibleArchiveHeight - - headerOffsetPx = (headerOffsetPx + archiveItemHeightPx).coerceAtMost(0f) - - if (archiveRevealPx > 0f) { - revealAnimationJob?.cancel() - revealAnimationJob = launch { - animate(initialValue = archiveRevealPx, targetValue = 0f) { value, _ -> - archiveRevealPx = value - } - } - } - } - } - - val isArchiveRevealed = archiveRevealPx > 0f && !isArchivePersistent - BackHandler(enabled = isArchiveRevealed) { - revealAnimationJob?.cancel() - revealAnimationJob = scope.launch { - animate(initialValue = archiveRevealPx, targetValue = 0f) { value, _ -> - archiveRevealPx = value - } - } - } - - val nestedScrollConnection = remember(isArchivePersistent, canShowArchive, state.isArchiveAlwaysVisible, tabsHeightPx) { - object : NestedScrollConnection { - override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset { - if (source == NestedScrollSource.UserInput) { - revealAnimationJob?.cancel() - headerAnimationJob?.cancel() - } - - val delta = available.y - - if (delta < 0) { - if (canShowArchive && !isArchivePersistent && archiveRevealPx > 0f) { - val oldReveal = archiveRevealPx - val newReveal = (oldReveal + delta).coerceAtLeast(0f) - archiveRevealPx = newReveal - - if (newReveal == 0f) hasVibrated = false - - return Offset(0f, newReveal - oldReveal) - } - - val maxHide = if (isArchivePersistent) { - -(archiveItemHeightPx + tabsHeightPx) - } else { - -tabsHeightPx - } - - val oldOffset = headerOffsetPx - val newOffset = (oldOffset + delta).coerceIn(maxHide, 0f) - headerOffsetPx = newOffset - - if (source == NestedScrollSource.UserInput && newOffset < 0f) { - canRevealArchive = false - } - - if (abs(newOffset - oldOffset) > 0.5f) { - return Offset(0f, newOffset - oldOffset) - } - } else { - if (headerOffsetPx < 0f) { - if (source == NestedScrollSource.UserInput) { - canRevealArchive = false - } - - var limit = 0f - if (isArchivePersistent && !state.isArchiveAlwaysVisible) { - limit = -archiveItemHeightPx - } - - if (headerOffsetPx < limit) { - val oldOffset = headerOffsetPx - val newOffset = (oldOffset + delta).coerceAtMost(limit) - headerOffsetPx = newOffset - return Offset(0f, newOffset - oldOffset) - } - } - } - return Offset.Zero - } - - override fun onPostScroll( - consumed: Offset, - available: Offset, - source: NestedScrollSource - ): Offset { - if (source == NestedScrollSource.UserInput) { - revealAnimationJob?.cancel() - headerAnimationJob?.cancel() - } - - val delta = available.y - if (delta > 0) { - if (source == NestedScrollSource.UserInput && (consumed.y > 0f || headerOffsetPx < 0f)) { - canRevealArchive = false - } - - if (headerOffsetPx < 0f) { - val oldOffset = headerOffsetPx - val newOffset = (oldOffset + delta).coerceAtMost(0f) - headerOffsetPx = newOffset - return Offset(0f, newOffset - oldOffset) - } - else if (canShowArchive && !isArchivePersistent && headerOffsetPx == 0f && canRevealArchive && source == NestedScrollSource.UserInput) { - val oldReveal = archiveRevealPx - val newReveal = (oldReveal + delta * 0.5f).coerceIn(0f, archiveItemHeightPx) - archiveRevealPx = newReveal - - if (newReveal >= archiveItemHeightPx && !hasVibrated) { - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - hasVibrated = true - } else if (newReveal < archiveItemHeightPx) { - hasVibrated = false - } - - return Offset(0f, (newReveal - oldReveal) * 2f) - } - } - return Offset.Zero - } - - override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity { - canRevealArchive = true - - if (canShowArchive && !isArchivePersistent && archiveRevealPx > 0f && archiveRevealPx < archiveItemHeightPx) { - val target = if (archiveRevealPx > archiveItemHeightPx / 2) archiveItemHeightPx else 0f - - if (target == 0f) hasVibrated = false - - revealAnimationJob = scope.launch { - animate(initialValue = archiveRevealPx, targetValue = target) { value, _ -> - archiveRevealPx = value - } - } - } - - val maxHide = if (isArchivePersistent) { - -(archiveItemHeightPx + tabsHeightPx) - } else { - -tabsHeightPx - } - - if (headerOffsetPx < 0f && headerOffsetPx > maxHide) { - val target = if (isArchivePersistent) { - if (headerOffsetPx > -archiveItemHeightPx / 2) { - 0f - } else if (headerOffsetPx > -archiveItemHeightPx - tabsHeightPx / 2) { - -archiveItemHeightPx - } else { - maxHide - } - } else { - if (headerOffsetPx > maxHide / 2) 0f else maxHide - } - headerAnimationJob = scope.launch { - animate(initialValue = headerOffsetPx, targetValue = target) { value, _ -> - headerOffsetPx = value - } - } - } - return Velocity.Zero - } - } - } - - val isFabExpanded by remember { derivedStateOf { headerOffsetPx > -10f } } - - var cachedStatusEmojiPath by remember(state.currentUser?.id) { - mutableStateOf(state.currentUser?.statusEmojiPath) - } - - LaunchedEffect(state.currentUser?.id, state.currentUser?.statusEmojiPath) { - val statusEmojiPath = state.currentUser?.statusEmojiPath - if (!statusEmojiPath.isNullOrBlank()) { - cachedStatusEmojiPath = statusEmojiPath - } - } - - val currentUser = remember(state.currentUser, cachedStatusEmojiPath) { - state.currentUser?.let { user -> - if (user.statusEmojiId != 0L && user.statusEmojiPath.isNullOrBlank() && !cachedStatusEmojiPath.isNullOrBlank()) { - user.copy(statusEmojiPath = cachedStatusEmojiPath) - } else { - user - } - } - } - - if (showAccountMenu) { - AccountMenu( - user = currentUser, - attachMenuBots = state.attachMenuBots, - onDismiss = { showAccountMenu = false }, - onSavedMessagesClick = { - currentUser?.id?.let { component.onChatClicked(it) } - }, - onSettingsClick = { component.onSettingsClicked() }, - onAddAccountClick = { /* TODO */ }, - onHelpClick = { - component.onOpenInstantView("https://telegram.org/faq#general-questions") - }, - onProfileClick = { - currentUser?.id?.let { component.onProfileClicked(it) } - }, - updateState = state.updateState, - onUpdateClick = { component.onUpdateClicked() }, - onBotClick = { bot -> - component.onOpenWebApp( - url = state.botWebAppUrl ?: "", - botUserId = bot.botUserId, - botName = state.botWebAppName ?: bot.name - ) - }, - videoPlayerPool = component.videoPlayerPool - ) - } - - if (showPermissionRequest) { - PermissionRequestSheet(onDismiss = { - showPermissionRequest = false - component.appPreferences.setPermissionRequested(true) - }) - } - - val scrollStates = remember { mutableMapOf() } - val firstFolderTransitionCompleted = remember { mutableStateMapOf() } - - val context = LocalContext.current - val emojiStyle by component.appPreferences.emojiStyle.collectAsState() - val emojiFontFamily = remember(context, emojiStyle) { getEmojiFontFamily(context, emojiStyle) } - val messageLines by component.appPreferences.chatListMessageLines.collectAsState() - val showPhotos by component.appPreferences.showChatListPhotos.collectAsState() - - val onChatClicked = remember(component) { { id: Long -> component.onChatClicked(id) } } - val onChatLongClicked = remember(component) { { id: Long -> component.onChatLongClicked(id) } } - val statusMenuScrimAlpha by animateFloatAsState( - targetValue = if (statusMenuTransitionState.targetState) 0.18f else 0f, - animationSpec = tween(durationMillis = 220), - label = "ChatListStatusMenuScrimAlpha" - ) - - Scaffold( - containerColor = if (isTablet) Color.Transparent else MaterialTheme.colorScheme.surfaceContainerLow, - modifier = Modifier.nestedScroll(nestedScrollConnection), - topBar = { - Column(Modifier.fillMaxWidth()) { - AnimatedContent( - targetState = state.selectedChatIds.isNotEmpty() && !state.isForwarding, - label = "TopBarSelectionAnimation", - transitionSpec = { fadeIn() togetherWith fadeOut() } - ) { isSelectionMode -> - if (isSelectionMode) { - val selectedChats = state.chats.filter { state.selectedChatIds.contains(it.id) } - val canMarkUnread = selectedChats.any { !it.isMarkedAsUnread } - val allPinned = selectedChats.isNotEmpty() && selectedChats.all { it.isPinned } - val allMuted = selectedChats.isNotEmpty() && selectedChats.all { it.isMuted } - val isInArchive = state.selectedFolderId == -2 - - SelectionTopBar( - selectedCount = state.selectedChatIds.size, - isInArchive = isInArchive, - allPinned = allPinned, - allMuted = allMuted, - onClearSelection = { component.clearSelection() }, - onPinClick = { component.onPinSelected() }, - onMuteClick = { component.onMuteSelected(!allMuted) }, - onArchiveClick = { component.onArchiveSelected(!isInArchive) }, - onDeleteClick = { showDeleteChatsSheet = true }, - onToggleReadClick = { component.onToggleReadSelected() }, - canMarkUnread = canMarkUnread - ) - } else { - if (state.isForwarding) { - TopAppBar( - title = { - Column { - Text( - stringResource(R.string.forward_to_title), - fontWeight = FontWeight.SemiBold, - style = MaterialTheme.typography.titleMedium - ) - if (state.selectedChatIds.isNotEmpty()) { - Text( - text = stringResource( - R.string.chats_selected_format, - state.selectedChatIds.size - ), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.primary - ) - } - } - }, - navigationIcon = { - IconButton(onClick = { component.handleBack() }) { - Icon(Icons.Rounded.Close, stringResource(R.string.cancel_button)) - } - }, - actions = { - if (state.selectedChatIds.isNotEmpty()) { - IconButton(onClick = { component.onConfirmForwarding() }) { - Icon( - Icons.AutoMirrored.Rounded.Send, - stringResource(R.string.action_send), - tint = MaterialTheme.colorScheme.primary - ) - } - } - }, - colors = TopAppBarDefaults.topAppBarColors(containerColor = MaterialTheme.colorScheme.surfaceContainerLow) - ) - } else if (state.selectedFolderId == -2 && !state.isSearchActive) { - TopAppBar( - title = { - Text( - stringResource(R.string.archived_chats_title), - fontWeight = FontWeight.SemiBold - ) - }, - navigationIcon = { - IconButton(onClick = { component.handleBack() }) { - Icon(Icons.AutoMirrored.Rounded.ArrowBack, stringResource(R.string.cd_back)) - } - }, - actions = { - IconButton(onClick = { component.onSearchToggle() }) { - Icon( - Icons.Rounded.Search, - contentDescription = stringResource(R.string.action_search) - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors(containerColor = MaterialTheme.colorScheme.surfaceContainerLow) - ) - } else { - ChatListTopBar( - user = currentUser, - connectionStatus = state.connectionStatus, - isProxyEnabled = state.isProxyEnabled, - onRetryConnection = { component.retryConnection() }, - onProxySettingsClick = { component.onProxySettingsClicked() }, - isSearchActive = state.isSearchActive, - searchQuery = state.searchQuery, - onSearchQueryChange = component::onSearchQueryChange, - onSearchToggle = component::onSearchToggle, - onStatusClick = { anchorBounds -> - statusAnchorBounds = anchorBounds ?: statusAnchorBounds - showStatusMenu = true - }, - onMenuClick = { showAccountMenu = true }, - videoPlayerPool = component.videoPlayerPool - ) - } - } - } - - if (state.connectionStatus == ConnectionStatus.Connecting || state.connectionStatus == ConnectionStatus.Updating || state.connectionStatus == ConnectionStatus.ConnectingToProxy) { - LinearProgressIndicator( - modifier = Modifier - .fillMaxWidth() - .height(2.dp), - color = MaterialTheme.colorScheme.primary, - trackColor = Color.Transparent - ) - } - - val isMainView = !state.isSearchActive && state.selectedFolderId != -2 - - if (isMainView) { - Box( - modifier = Modifier - .fillMaxWidth() - .height(with(density) { - val visibleArchiveHeight = if (isArchivePersistent) { - (archiveItemHeightPx + headerOffsetPx).coerceAtLeast(0f) - } else if (isMainFolder) { - archiveRevealPx - } else { - 0f - } - val visibleTabsHeight = if (isArchivePersistent) { - (tabsHeightPx + (headerOffsetPx + archiveItemHeightPx).coerceAtMost(0f)).coerceAtLeast( - 0f - ) - } else { - (tabsHeightPx + headerOffsetPx).coerceAtLeast(0f) - } - (visibleArchiveHeight + visibleTabsHeight).toDp() - }) - .clip(RoundedCornerShape(bottomStart = 0.dp, bottomEnd = 0.dp)), - contentAlignment = Alignment.TopCenter - ) { - Column(Modifier.fillMaxWidth()) { - Box( - modifier = Modifier - .fillMaxWidth() - .height(with(density) { - if (isArchivePersistent) { - (archiveItemHeightPx + headerOffsetPx).coerceAtLeast(0f).toDp() - } else if (isMainFolder) { - archiveRevealPx.toDp() - } else { - 0.dp - } - }) - .graphicsLayer { - alpha = if (isArchivePersistent) { - ((archiveItemHeightPx + headerOffsetPx) / archiveItemHeightPx).coerceIn( - 0f, - 1f - ) - } else if (isMainFolder) { - (archiveRevealPx / archiveItemHeightPx).coerceIn(0f, 1f) - } else { - 0f - } - clip = true - } - ) { - Column( - Modifier.offset { - if (isArchivePersistent) { - IntOffset(0, headerOffsetPx.roundToInt()) - } else { - IntOffset(0, 0) - } - } - ) { - ArchiveHeaderCard( - isPinned = state.isArchivePinned, - onClick = { component.onFolderClicked(-2) }, - onLongClick = { component.onArchivePinToggle() } - ) - Spacer(Modifier.height(6.dp)) - } - } - - if (state.folders.size > 1) { - FolderTabs( - modifier = Modifier.offset { - val yOffset = if (isArchivePersistent) { - (headerOffsetPx + archiveItemHeightPx).coerceAtMost(0f) - } else { - headerOffsetPx - } - IntOffset(0, yOffset.roundToInt()) - }, - folders = state.folders, - pagerState = pagerState, - onTabClick = { index -> - if (pagerState.currentPage == index) { - val folderId = state.folders[index].id - scope.launch { - scrollStates[folderId]?.animateScrollToItem(0) - } - } else { - scope.launch { - pagerState.animateScrollToPage(index) - } - } - }, - onEditClick = { component.onEditFoldersClicked() }, - onEditFolderClick = { folder -> component.onEditFolder(folder.id) }, - onDeleteFolderClick = { folder -> component.onDeleteFolder(folder.id) }, - onReorderFoldersClick = { component.onEditFoldersClicked() } - ) - } - } - } - } - } - }, - floatingActionButton = { - if (!isTablet) { - AnimatedVisibility( - visible = !state.isSearchActive && state.selectedFolderId != -2 && !state.isForwarding, - enter = scaleIn() + fadeIn(), - exit = scaleOut() + fadeOut() - ) { - ExtendedFloatingActionButton( - onClick = { component.onNewChatClicked() }, - icon = { Icon(Icons.Rounded.Edit, null) }, - text = { Text(stringResource(R.string.new_chat_fab)) }, - expanded = isFabExpanded, - containerColor = MaterialTheme.colorScheme.primaryContainer, - contentColor = MaterialTheme.colorScheme.onPrimaryContainer - ) - } - - AnimatedVisibility( - visible = state.isForwarding && state.selectedChatIds.isNotEmpty(), - enter = scaleIn() + fadeIn(), - exit = scaleOut() + fadeOut() - ) { - FloatingActionButton( - onClick = { component.onConfirmForwarding() }, - containerColor = MaterialTheme.colorScheme.primary, - contentColor = MaterialTheme.colorScheme.onPrimary - ) { - Icon(Icons.AutoMirrored.Rounded.Send, stringResource(R.string.action_send)) - } - } - } - } - ) { padding -> - Surface( - modifier = Modifier - .padding(top = padding.calculateTopPadding()) - .fillMaxSize(), - shape = if (isTablet) RoundedCornerShape(0.dp) else RoundedCornerShape(topStart = 28.dp, topEnd = 28.dp), - color = if (isTablet) Color.Transparent else MaterialTheme.colorScheme.surface - ) { - if (state.isSearchActive || state.selectedFolderId == -2) { - var showAllGlobal by remember { mutableStateOf(false) } - var showAllMessages by remember { mutableStateOf(false) } - - val scrollState = rememberLazyListState( - initialFirstVisibleItemIndex = if (state.selectedFolderId == -2 && !state.isSearchActive) state.scrollPositions[-2]?.first ?: 0 else 0, - initialFirstVisibleItemScrollOffset = if (state.selectedFolderId == -2 && !state.isSearchActive) state.scrollPositions[-2]?.second ?: 0 else 0 - ) - - if (state.selectedFolderId == -2 && !state.isSearchActive) { - scrollStates[-2] = scrollState - } - - val firstItemId = if (state.selectedFolderId == -2 && !state.isSearchActive) { - state.chatsByFolder[-2]?.firstOrNull()?.id - } else { - null - } - - LaunchedEffect(firstItemId) { - if (state.selectedFolderId == -2 && !state.isSearchActive && !scrollState.isScrollInProgress && scrollState.firstVisibleItemIndex <= 1) { - scrollState.scrollToItem(0, 0) - } - } - - if (state.selectedFolderId == -2 && !state.isSearchActive) { - DisposableEffect(Unit) { - onDispose { - component.updateScrollPosition(-2, scrollState.firstVisibleItemIndex, scrollState.firstVisibleItemScrollOffset) - } - } - } - - val isArchivedView = state.selectedFolderId == -2 && !state.isSearchActive - val archivedChats = if (isArchivedView) state.chatsByFolder[-2] ?: emptyList() else emptyList() - val isArchivedLoading = if (isArchivedView) state.isLoadingByFolder[-2] ?: false else false - val hasArchivedLoadState = if (isArchivedView) state.isLoadingByFolder.containsKey(-2) else false - val showArchivedShimmer = - isArchivedView && archivedChats.isEmpty() && (isArchivedLoading || !hasArchivedLoadState) - val shouldAnimateFirstArchiveTransition = firstFolderTransitionCompleted[-2] != true - - LaunchedEffect(isArchivedView, archivedChats.size, isArchivedLoading, scrollState) { - if (!isArchivedView || isArchivedLoading || archivedChats.isEmpty()) { - return@LaunchedEffect - } - - snapshotFlow { - val lastVisible = scrollState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: -1 - lastVisible >= archivedChats.lastIndex - 5 - } - .distinctUntilChanged() - .collect { shouldLoad -> - if (shouldLoad) { - component.loadMore(-2) - } - } - } - - LaunchedEffect(isArchivedView, hasArchivedLoadState, showArchivedShimmer) { - if (isArchivedView && shouldAnimateFirstArchiveTransition && hasArchivedLoadState && !showArchivedShimmer) { - firstFolderTransitionCompleted[-2] = true - } - } - - Box(modifier = Modifier.fillMaxSize()) { - LazyColumn( - state = scrollState, - modifier = Modifier - .fillMaxSize() - .semantics { contentDescription = "ChatList" }, - contentPadding = PaddingValues(top = 12.dp, bottom = 88.dp), - ) { - if (state.isSearchActive) { - if (state.searchQuery.isEmpty() && state.searchHistory.isNotEmpty()) { - val recentUsers = - state.searchHistory.filter { (it.type == ChatType.PRIVATE || it.type == ChatType.SECRET) && !it.isBot } - val recentOthers = - state.searchHistory.filter { it.type != ChatType.PRIVATE && it.type != ChatType.SECRET || it.isBot } - - item { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(top = 12.dp, bottom = 8.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = stringResource(R.string.search_recent), - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.primary - ) - TextButton(onClick = { component.onClearSearchHistory() }) { - Text(stringResource(R.string.action_clear_all)) - } - } - } - - if (recentUsers.isNotEmpty()) { - item { - LazyRow( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 8.dp), - contentPadding = PaddingValues(horizontal = 16.dp), - horizontalArrangement = Arrangement.spacedBy(16.dp) - ) { - itemsIndexed(items = recentUsers, key = { index, chat -> "recent_user_${chat.id}_$index" }) { _, chat -> - Column( - modifier = Modifier - .width(64.dp) - .combinedClickable( - onClick = { onChatClicked(chat.id) }, - onLongClick = { component.onRemoveSearchHistoryItem(chat.id) } - ), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Box(contentAlignment = Alignment.TopEnd) { - Avatar( - path = chat.avatarPath, - fallbackPath = chat.personalAvatarPath, - name = chat.title, - size = 64.dp, - isOnline = chat.isOnline, - videoPlayerPool = component.videoPlayerPool - ) - Box( - modifier = Modifier - .size(18.dp) - .offset(x = 4.dp, y = (-4).dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.surfaceVariant) - .clickable { component.onRemoveSearchHistoryItem(chat.id) }, - contentAlignment = Alignment.Center - ) { - Icon( - Icons.Rounded.Close, - null, - modifier = Modifier.size(10.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - Spacer(Modifier.height(4.dp)) - Text( - text = chat.title, - style = MaterialTheme.typography.labelSmall, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - textAlign = TextAlign.Center, - lineHeight = 12.sp - ) - } - } - } - } - } - - if (recentOthers.isNotEmpty()) { - itemsIndexed( - items = recentOthers, - key = { _, chat -> "recent_${chat.id}" }) { _, chat -> - ChatListItem( - modifier = Modifier.animateItem(), - chat = chat, - currentUserId = state.currentUser?.id, - isSelected = false, - onClick = { onChatClicked(chat.id) }, - onLongClick = { component.onRemoveSearchHistoryItem(chat.id) }, - emojiFontFamily = emojiFontFamily, - messageLines = messageLines, - showPhotos = showPhotos, - videoPlayerPool = component.videoPlayerPool - ) - } - } - } - - if (state.searchResults.isNotEmpty()) { - item { - Text( - text = stringResource(R.string.search_section_chats), - modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp), - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.primary - ) - } - itemsIndexed(items = state.searchResults, key = { index, chat -> "search_${chat.id}_$index" }) { _, chat -> - ChatListItem( - modifier = Modifier.animateItem(), - chat = chat, - currentUserId = state.currentUser?.id, - isSelected = state.selectedChatIds.contains(chat.id), - onClick = { onChatClicked(chat.id) }, - onLongClick = { onChatLongClicked(chat.id) }, - emojiFontFamily = emojiFontFamily, - messageLines = messageLines, - showPhotos = showPhotos, - videoPlayerPool = component.videoPlayerPool - ) - } - } - - if (state.globalSearchResults.isNotEmpty()) { - item { - Text( - text = stringResource(R.string.search_section_global), - modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp), - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.primary - ) - } - - val globalToDisplay = - if (showAllGlobal) state.globalSearchResults else state.globalSearchResults.take(3) - - itemsIndexed(items = globalToDisplay, key = { _, chat -> "global_${chat.id}" }) { _, chat -> - ChatListItem( - modifier = Modifier.animateItem(), - chat = chat, - currentUserId = state.currentUser?.id, - isSelected = state.selectedChatIds.contains(chat.id), - onClick = { onChatClicked(chat.id) }, - onLongClick = { onChatLongClicked(chat.id) }, - emojiFontFamily = emojiFontFamily, - messageLines = messageLines, - showPhotos = showPhotos, - videoPlayerPool = component.videoPlayerPool - ) - } - - if (!showAllGlobal && state.globalSearchResults.size > 3) { - item { - Box( - modifier = Modifier - .fillMaxWidth() - .clickable { showAllGlobal = true } - .padding(16.dp), - contentAlignment = Alignment.Center - ) { - Text( - text = stringResource(R.string.action_show_more), - color = MaterialTheme.colorScheme.primary, - style = MaterialTheme.typography.labelLarge - ) - } - } - } - } - - if (state.messageSearchResults.isNotEmpty()) { - item { - Text( - text = stringResource(R.string.search_section_messages), - modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp), - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.primary - ) - } - - val messagesToDisplay = - if (showAllMessages) state.messageSearchResults else state.messageSearchResults.take(3) - - itemsIndexed( - items = messagesToDisplay, - key = { index, msg -> "msg_${msg.id}_$index" }) { index, msg -> - if (showAllMessages && index >= messagesToDisplay.lastIndex - 5 && state.canLoadMoreMessages) { - LaunchedEffect(Unit) { component.loadMoreMessages() } - } - - MessageSearchItem( - modifier = Modifier.animateItem(), - message = msg, - onClick = { component.onMessageClicked(msg.chatId, msg.id) }, - videoPlayerPool = component.videoPlayerPool - ) - } - - if (!showAllMessages && state.messageSearchResults.size > 3) { - item { - Box( - modifier = Modifier - .fillMaxWidth() - .clickable { showAllMessages = true } - .padding(16.dp), - contentAlignment = Alignment.Center - ) { - Text( - text = stringResource(R.string.action_show_more), - color = MaterialTheme.colorScheme.primary, - style = MaterialTheme.typography.labelLarge - ) - } - } - } - } - } else { - if (archivedChats.isEmpty() && hasArchivedLoadState && !isArchivedLoading) { - item { - EmptyStateView(modifier = Modifier.fillParentMaxSize()) - } - } - - itemsIndexed(items = archivedChats, key = { _, chat -> chat.id }) { _, chat -> - ChatListItem( - modifier = Modifier.animateItem(), - chat = chat, - currentUserId = state.currentUser?.id, - isSelected = state.selectedChatIds.contains(chat.id), - onClick = { onChatClicked(chat.id) }, - onLongClick = { onChatLongClicked(chat.id) }, - isTabletSelected = isTablet && state.activeChatId == chat.id, - emojiFontFamily = emojiFontFamily, - messageLines = messageLines, - showPhotos = showPhotos, - videoPlayerPool = component.videoPlayerPool - ) - } - } - } - - if (isArchivedView) { - Crossfade( - targetState = showArchivedShimmer, - animationSpec = if (shouldAnimateFirstArchiveTransition) tween(360) else tween(0), - label = "ArchiveChatsCrossfade" - ) { showShimmer -> - if (showShimmer) { - ChatListShimmer(itemCount = 8) - } - } - } - } - } else { - HorizontalPager( - state = pagerState, - modifier = Modifier.fillMaxSize(), - beyondViewportPageCount = 1 - ) { page -> - val folderId = state.folders.getOrNull(page)?.id - ?: state.folders.firstOrNull { it.id == state.selectedFolderId }?.id - if (folderId == null) { - Box(modifier = Modifier.fillMaxSize()) - return@HorizontalPager - } - val folderChats = state.chatsByFolder[folderId] ?: emptyList() - val isFolderLoading = state.isLoadingByFolder[folderId] ?: false - val hasFolderLoadState = state.isLoadingByFolder.containsKey(folderId) - val showFolderShimmer = folderChats.isEmpty() && (isFolderLoading || !hasFolderLoadState) - val shouldAnimateFirstFolderTransition = firstFolderTransitionCompleted[folderId] != true - - val scrollState = rememberLazyListState( - initialFirstVisibleItemIndex = state.scrollPositions[folderId]?.first ?: 0, - initialFirstVisibleItemScrollOffset = state.scrollPositions[folderId]?.second ?: 0 - ) - - scrollStates[folderId] = scrollState - - val firstItemId = folderChats.firstOrNull()?.id - - LaunchedEffect(firstItemId) { - if (!scrollState.isScrollInProgress && scrollState.firstVisibleItemIndex <= 1) { - scrollState.scrollToItem(0, 0) - } - } - - val shouldLoadMoreFolder by remember(folderChats, isFolderLoading, scrollState) { - derivedStateOf { - if (isFolderLoading || folderChats.isEmpty()) { - false - } else { - val lastVisible = scrollState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: -1 - lastVisible >= folderChats.lastIndex - 5 - } - } - } - - LaunchedEffect(shouldLoadMoreFolder, folderId) { - if (shouldLoadMoreFolder) { - component.loadMore(folderId) - } - } - - val isInitialLoad = remember(folderId) { mutableStateOf(true) } - LaunchedEffect(folderChats) { - if (isInitialLoad.value && folderChats.isNotEmpty()) { - if (state.scrollPositions[folderId] == null) { - scrollState.scrollToItem(0, 0) - } - isInitialLoad.value = false - } - } - - LaunchedEffect(folderId, hasFolderLoadState, showFolderShimmer) { - if (shouldAnimateFirstFolderTransition && hasFolderLoadState && !showFolderShimmer) { - firstFolderTransitionCompleted[folderId] = true - } - } - - DisposableEffect(Unit) { - onDispose { - component.updateScrollPosition(folderId, scrollState.firstVisibleItemIndex, scrollState.firstVisibleItemScrollOffset) - } - } - - Box(modifier = Modifier.fillMaxSize()) { - Crossfade( - targetState = showFolderShimmer, - animationSpec = if (shouldAnimateFirstFolderTransition) tween(360) else tween(0), - label = "FolderChatsCrossfade" - ) { showShimmer -> - if (showShimmer) { - ChatListShimmer() - } else { - LazyColumn( - state = scrollState, - modifier = Modifier - .fillMaxSize() - .semantics { contentDescription = "ChatList" }, - contentPadding = PaddingValues(top = 12.dp, bottom = 88.dp) - ) { - if (folderChats.isEmpty() && hasFolderLoadState && !isFolderLoading) { - item { - EmptyStateView(modifier = Modifier.fillParentMaxSize()) - } - } - - itemsIndexed( - items = folderChats, - key = { _, chat -> chat.id } - ) { _, chat -> - ChatListItem( - modifier = Modifier.animateItem(), - chat = chat, - currentUserId = state.currentUser?.id, - isSelected = state.selectedChatIds.contains(chat.id), - onClick = { onChatClicked(chat.id) }, - onLongClick = { onChatLongClicked(chat.id) }, - isTabletSelected = isTablet && state.activeChatId == chat.id, - videoPlayerPool = component.videoPlayerPool, - emojiFontFamily = emojiFontFamily, - messageLines = messageLines, - showPhotos = showPhotos - ) - } - } - } - } - } - } - } - } - } - - if (statusMenuTransitionState.currentState || statusMenuTransitionState.targetState) { - BoxWithConstraints( - modifier = Modifier - .fillMaxSize() - .background(Color.Black.copy(alpha = statusMenuScrimAlpha)) - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null - ) { showStatusMenu = false } - ) { - val menuHorizontalPadding = 16.dp - val menuAnchorOverlap = 12.dp - val menuBottomMargin = 8.dp - val menuWidth = (maxWidth - menuHorizontalPadding * 2).coerceAtLeast(280.dp) - val menuHeightLimit = 520.dp - - val rootWidthPx = constraints.maxWidth.coerceAtLeast(1) - val rootHeightPx = constraints.maxHeight.coerceAtLeast(1) - val menuWidthPx = with(density) { menuWidth.roundToPx() } - val horizontalPaddingPx = with(density) { menuHorizontalPadding.roundToPx() } - val anchorOverlapPx = with(density) { menuAnchorOverlap.roundToPx() } - val menuBottomMarginPx = with(density) { menuBottomMargin.roundToPx() } - val minMenuVisibleHeightPx = with(density) { 220.dp.roundToPx() } - - val statusBarTopPx = WindowInsets.statusBars.getTop(density) - val navigationBarBottomPx = WindowInsets.navigationBars.getBottom(density) - val minTopPx = statusBarTopPx + with(density) { 8.dp.roundToPx() } - val fallbackTopPx = statusBarTopPx + with(density) { 56.dp.roundToPx() } - - val desiredTopPx = statusAnchorBounds - ?.let { it.bottom.roundToInt() - anchorOverlapPx } - ?: fallbackTopPx - val desiredLeftPx = statusAnchorBounds - ?.let { ((it.left + it.right) / 2f - menuWidthPx / 2f).roundToInt() } - ?: horizontalPaddingPx - - val maxLeftPx = (rootWidthPx - menuWidthPx - horizontalPaddingPx).coerceAtLeast(horizontalPaddingPx) - val clampedLeftPx = desiredLeftPx.coerceIn(horizontalPaddingPx, maxLeftPx) - - val maxTopPx = ( - rootHeightPx - navigationBarBottomPx - menuBottomMarginPx - minMenuVisibleHeightPx - ).coerceAtLeast(minTopPx) - val clampedTopPx = desiredTopPx.coerceIn(minTopPx, maxTopPx) - - val maxMenuHeightPx = ( - rootHeightPx - clampedTopPx - navigationBarBottomPx - menuBottomMarginPx - ).coerceAtLeast(minMenuVisibleHeightPx) - val maxMenuHeightDp = with(density) { maxMenuHeightPx.toDp() }.coerceAtMost(menuHeightLimit) - - AnimatedVisibility( - visibleState = statusMenuTransitionState, - enter = fadeIn(animationSpec = tween(180)) + - slideInVertically(animationSpec = tween(260)) { -it / 5 } + - scaleIn( - animationSpec = tween(260), - initialScale = 0.94f, - transformOrigin = TransformOrigin(0.85f, 0f) - ), - exit = fadeOut(animationSpec = tween(130)) + - slideOutVertically(animationSpec = tween(170)) { -it / 6 } + - scaleOut( - animationSpec = tween(170), - targetScale = 0.97f, - transformOrigin = TransformOrigin(0.85f, 0f) - ), - modifier = Modifier.offset { IntOffset(clampedLeftPx, clampedTopPx) } - ) { - Surface( - modifier = Modifier - .width(menuWidth) - .heightIn(max = maxMenuHeightDp) - .clip(RoundedCornerShape(24.dp)) - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null - ) { }, - color = MaterialTheme.colorScheme.surfaceContainerHigh, - tonalElevation = 8.dp, - shadowElevation = 12.dp - ) { - EmojisGrid( - onEmojiSelected = { _, sticker -> - val customEmojiId = sticker?.customEmojiId - if (sticker != null && customEmojiId != null) { - if (!sticker.path.isNullOrBlank()) { - cachedStatusEmojiPath = sticker.path - } - component.onSetEmojiStatus(customEmojiId, sticker.path) - showStatusMenu = false - } - }, - emojiOnlyMode = true, - contentPadding = PaddingValues(bottom = 12.dp) - ) - } - } - } - } - - AnimatedVisibility( - visible = state.instantViewUrl != null, - enter = slideInVertically(initialOffsetY = { it }) + fadeIn(), - exit = slideOutVertically(targetOffsetY = { it }) + fadeOut() - ) { - state.instantViewUrl?.let { url -> - InstantViewer( - url = url, - messageRepository = koinInject(), - onDismiss = { component.onDismissInstantView() }, - onOpenWebView = { component.onOpenWebView(it) }, - videoPlayerPool = component.videoPlayerPool - ) - } - } - - AnimatedVisibility( - visible = state.webAppUrl != null || state.webAppBotId != null, - enter = slideInVertically(initialOffsetY = { it }) + fadeIn(), - exit = slideOutVertically(targetOffsetY = { it }) + fadeOut() - ) { - val webAppUrl = state.webAppUrl - val botUserId = state.webAppBotId - val botName = state.webAppBotName - - Log.d("MiniAppViewer", "webAppUrl: $webAppUrl, botUserId: $botUserId, botName: $botName") - - if (botUserId != null) { - MiniAppViewer( - chatId = botUserId, - botUserId = botUserId, - baseUrl = webAppUrl ?: "", - botName = botName ?: stringResource(R.string.mini_app_default_name), - messageRepository = koinInject(), - onDismiss = { component.onDismissWebApp() } - ) - } - } - - if (showDeleteChatsSheet) { - ConfirmationSheet( - icon = Icons.Rounded.Delete, - title = stringResource(R.string.delete_chats_title, state.selectedChatIds.size), - description = stringResource(R.string.delete_chats_confirmation), - confirmText = stringResource(R.string.action_delete_chats), - onConfirm = { - component.onDeleteSelected() - showDeleteChatsSheet = false - }, - onDismiss = { showDeleteChatsSheet = false } - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/DefaultChatListComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/DefaultChatListComponent.kt deleted file mode 100644 index 3d99834c..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/DefaultChatListComponent.kt +++ /dev/null @@ -1,582 +0,0 @@ -package org.monogram.presentation.features.chats.chatList - -import android.util.Log -import com.arkivanov.decompose.value.Value -import com.arkivanov.mvikotlin.core.instancekeeper.getStore -import com.arkivanov.mvikotlin.extensions.coroutines.stateFlow -import com.arkivanov.mvikotlin.main.store.DefaultStoreFactory -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.* -import kotlinx.coroutines.launch -import org.monogram.domain.models.BotMenuButtonModel -import org.monogram.domain.models.UpdateState -import org.monogram.domain.repository.ChatsListRepository -import org.monogram.domain.repository.SettingsRepository -import org.monogram.domain.repository.UpdateRepository -import org.monogram.domain.repository.UserRepository -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.core.util.coRunCatching -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.features.chats.ChatListComponent -import org.monogram.presentation.features.chats.ChatListStore -import org.monogram.presentation.features.chats.ChatListStoreFactory -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.root.AppComponentContext - -class DefaultChatListComponent( - context: AppComponentContext, - private val onSelect: (Long, Long?) -> Unit, - private val onProfileSelect: (Long) -> Unit, - private val onSettingsClick: () -> Unit, - private val onProxySettingsClick: () -> Unit, - private val onConfirmForward: (Set) -> Unit = {}, - internal val isForwarding: Boolean = false, - private val onNewChatClick: () -> Unit = {}, - private val onEditFoldersClick: () -> Unit = {}, - activeChatId: Value -) : ChatListComponent, AppComponentContext by context { - - private val repository: ChatsListRepository = container.repositories.chatsListRepository - private val repositoryUser: UserRepository = container.repositories.userRepository - private val settingsRepository: SettingsRepository = container.repositories.settingsRepository - private val updateRepository: UpdateRepository = container.repositories.updateRepository - override val appPreferences: AppPreferences = container.preferences.appPreferences - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - - private val _state = MutableStateFlow( - ChatListComponent.State( - isForwarding = isForwarding, - isLoadingByFolder = mapOf(-1 to true) - ) - ) - - private val store = instanceKeeper.getStore { - ChatListStoreFactory( - storeFactory = DefaultStoreFactory(), - component = this - ).create() - } - - override val state: StateFlow = store.stateFlow - - private val scope = componentScope - private var searchJob: Job? = null - private var isFetchingMoreMessages = false - private var nextMessagesOffset = "" - - init { - activeChatId.subscribe { id -> - _state.update { it.copy(activeChatId = id) } - } - - repositoryUser.currentUserFlow - .onEach { user -> - if (user != null) { - _state.update { it.copy(currentUser = user) } - } - } - .launchIn(scope) - - scope.launch { - repositoryUser.getMe() - } - - repository.folderChatsFlow - .onEach { update -> - val distinctList = update.chats.distinctBy { it.id } - val pinnedCount = distinctList.count { it.isPinned } - if (pinnedCount > 0) { - Log.d( - TAG, - "folder=${update.folderId} chats=${distinctList.size} pinned=$pinnedCount pinnedIds=${ - distinctList.filter { it.isPinned }.take(10).joinToString { it.id.toString() } - }" - ) - } - _state.update { - val newChatsByFolder = it.chatsByFolder.toMutableMap() - newChatsByFolder[update.folderId] = distinctList - it.copy(chatsByFolder = newChatsByFolder) - } - } - .launchIn(scope) - - repository.foldersFlow - .onEach { folders -> - _state.update { it.copy(folders = folders) } - } - .launchIn(scope) - - repository.folderLoadingFlow - .onEach { update -> - _state.update { - val newLoadingByFolder = it.isLoadingByFolder.toMutableMap() - newLoadingByFolder[update.folderId] = update.isLoading - it.copy(isLoadingByFolder = newLoadingByFolder) - } - } - .launchIn(scope) - - repository.connectionStateFlow - .onEach { status -> - _state.update { it.copy(connectionStatus = status) } - } - .launchIn(scope) - - appPreferences.enabledProxyId - .onEach { enabledProxyId -> - _state.update { it.copy(isProxyEnabled = enabledProxyId != null) } - } - .launchIn(scope) - - repository.isArchivePinned - .onEach { isPinned -> - _state.update { it.copy(isArchivePinned = isPinned) } - } - .launchIn(scope) - - repository.isArchiveAlwaysVisible - .onEach { alwaysVisible -> - _state.update { it.copy(isArchiveAlwaysVisible = alwaysVisible) } - } - .launchIn(scope) - - repository.searchHistory - .onEach { history -> - _state.update { it.copy(searchHistory = history) } - } - .launchIn(scope) - - settingsRepository.getAttachMenuBots() - .onEach { bots -> - _state.update { it.copy(attachMenuBots = bots) } - - bots.firstOrNull()?.let { bot -> - if (bot.botUserId != 0L) { - val botInfo = repositoryUser.getBotInfo(bot.botUserId) - val menuButton = botInfo?.menuButton - if (menuButton is BotMenuButtonModel.WebApp) { - _state.update { - it.copy( - botWebAppUrl = menuButton.url, - botWebAppName = menuButton.text - ) - } - } - } - } - } - .launchIn(scope) - - updateRepository.updateState - .onEach { updateState -> - _state.update { it.copy(updateState = updateState) } - } - .launchIn(scope) - - scope.launch { - updateRepository.checkForUpdates() - } - - _state.onEach { - store.accept(ChatListStore.Intent.UpdateState(it)) - }.launchIn(scope) - - scope.launch(Dispatchers.IO) { - repository.selectFolder(_state.value.selectedFolderId) - } - } - - override fun retryConnection() { - repository.retryConnection() - } - - override fun onFolderClicked(id: Int) { - if (_state.value.selectedFolderId == id) return - - _state.update { - val loadingByFolder = it.isLoadingByFolder.toMutableMap() - loadingByFolder[id] = true - it.copy( - selectedFolderId = id, - isLoadingByFolder = loadingByFolder - ) - } - - scope.launch(Dispatchers.IO) { - repository.selectFolder(id) - } - } - - override fun loadMore(folderId: Int?) { - val targetFolderId = folderId ?: _state.value.selectedFolderId - if (_state.value.isLoadingByFolder[targetFolderId] == true) return - - scope.launch(Dispatchers.IO) { - if (folderId != null && folderId != _state.value.selectedFolderId) { - return@launch - } - repository.loadNextChunk(20) - } - } - - override fun loadMoreMessages() { - if (isFetchingMoreMessages || nextMessagesOffset.isEmpty()) return - - isFetchingMoreMessages = true - val query = _state.value.searchQuery - scope.launch(Dispatchers.IO) { - val result = repository.searchMessages(query, offset = nextMessagesOffset) - nextMessagesOffset = result.nextOffset - _state.update { - it.copy( - messageSearchResults = it.messageSearchResults + result.messages, - canLoadMoreMessages = nextMessagesOffset.isNotEmpty() - ) - } - isFetchingMoreMessages = false - } - } - - override fun onChatClicked(id: Long) { - if (_state.value.isForwarding) { - toggleSelection(id) - } else if (_state.value.selectedChatIds.isNotEmpty()) { - toggleSelection(id) - } else { - if (_state.value.isSearchActive) { - repository.addSearchChatId(id) - } - onSelect(id, null) - } - } - - override fun onProfileClicked(id: Long) { - onProfileSelect(id) - } - - override fun onMessageClicked(chatId: Long, messageId: Long) { - if (_state.value.isForwarding) { - toggleSelection(chatId) - } else if (_state.value.selectedChatIds.isNotEmpty()) { - toggleSelection(chatId) - } else { - if (_state.value.isSearchActive) { - repository.addSearchChatId(chatId) - } - onSelect(chatId, messageId) - } - } - - override fun onChatLongClicked(id: Long) { - toggleSelection(id) - } - - override fun clearSelection() { - _state.update { it.copy(selectedChatIds = emptySet()) } - } - - override fun onSettingsClicked() { - onSettingsClick() - } - - override fun onSearchToggle() { - _state.update { - it.copy( - isSearchActive = !it.isSearchActive, - searchQuery = "", - searchResults = emptyList(), - globalSearchResults = emptyList(), - messageSearchResults = emptyList(), - canLoadMoreMessages = false - ) - } - nextMessagesOffset = "" - } - - override fun onSearchQueryChange(query: String) { - _state.update { it.copy(searchQuery = query) } - - searchJob?.cancel() - searchJob = scope.launch(Dispatchers.IO) { - delay(300) - if (query.isNotEmpty()) { - if (_state.value.selectedFolderId == -2) { - val archivedChats = _state.value.chatsByFolder[-2].orEmpty() - val trimmedQuery = query.trim() - val archiveResults = archivedChats.filter { chat -> - chat.title.contains(trimmedQuery, ignoreCase = true) || - chat.lastMessageText.contains(trimmedQuery, ignoreCase = true) - } - - _state.update { - it.copy( - searchResults = archiveResults, - globalSearchResults = emptyList(), - messageSearchResults = emptyList(), - canLoadMoreMessages = false - ) - } - nextMessagesOffset = "" - return@launch - } - - val localResults = repository.searchChats(query) - _state.update { it.copy(searchResults = localResults) } - - val globalResults = repository.searchPublicChats(query) - _state.update { it.copy(globalSearchResults = globalResults) } - - val messageResults = repository.searchMessages(query) - nextMessagesOffset = messageResults.nextOffset - _state.update { - it.copy( - messageSearchResults = messageResults.messages, - canLoadMoreMessages = nextMessagesOffset.isNotEmpty() - ) - } - } else { - nextMessagesOffset = "" - _state.update { - it.copy( - searchResults = emptyList(), - globalSearchResults = emptyList(), - messageSearchResults = emptyList(), - canLoadMoreMessages = false - ) - } - } - } - } - - override fun onSetEmojiStatus(customEmojiId: Long, statusPath: String?) { - _state.update { state -> - val user = state.currentUser ?: return@update state - state.copy( - currentUser = user.copy( - statusEmojiId = customEmojiId, - statusEmojiPath = statusPath ?: user.statusEmojiPath - ) - ) - } - - scope.launch(Dispatchers.IO) { - coRunCatching { - repositoryUser.setEmojiStatus(customEmojiId) - } - } - } - - override fun onClearSearchHistory() { - repository.clearSearchHistory() - } - - override fun onRemoveSearchHistoryItem(chatId: Long) { - repository.removeSearchChatId(chatId) - } - - override fun onMuteSelected(mute: Boolean) { - val selectedIds = _state.value.selectedChatIds - val selectedChats = _state.value.chats.filter { selectedIds.contains(it.id) } - val shouldMute = selectedChats.any { !it.isMuted } - - scope.launch(Dispatchers.IO) { - repository.toggleMuteChats(selectedIds, shouldMute) - clearSelection() - } - } - - override fun onArchiveSelected(archive: Boolean) { - val selectedIds = _state.value.selectedChatIds - scope.launch(Dispatchers.IO) { - repository.toggleArchiveChats(selectedIds, archive) - clearSelection() - } - } - - override fun onPinSelected() { - val selectedIds = _state.value.selectedChatIds - val selectedChats = _state.value.chats.filter { selectedIds.contains(it.id) } - val shouldPin = selectedChats.any { !it.isPinned } - val folderId = _state.value.selectedFolderId - - scope.launch(Dispatchers.IO) { - repository.togglePinChats(selectedIds, shouldPin, folderId) - clearSelection() - } - } - - override fun onToggleReadSelected() { - val selectedIds = _state.value.selectedChatIds - val selectedChats = _state.value.chats.filter { selectedIds.contains(it.id) } - val shouldMarkUnread = selectedChats.any { !it.isMarkedAsUnread } - - scope.launch(Dispatchers.IO) { - repository.toggleReadChats(selectedIds, shouldMarkUnread) - clearSelection() - } - } - - override fun onDeleteSelected() { - val selectedIds = _state.value.selectedChatIds - scope.launch(Dispatchers.IO) { - repository.deleteChats(selectedIds) - clearSelection() - } - } - - override fun onArchivePinToggle() { - repository.setArchivePinned(!_state.value.isArchivePinned) - } - - override fun onConfirmForwarding() { - if (_state.value.selectedChatIds.isNotEmpty()) { - onConfirmForward(_state.value.selectedChatIds) - } - } - - override fun onNewChatClicked() { - onNewChatClick() - } - - override fun onProxySettingsClicked() { - onProxySettingsClick() - } - - override fun onEditFoldersClicked() { - onEditFoldersClick() - } - - override fun onDeleteFolder(folderId: Int) { - if (folderId <= 0) return - - scope.launch(Dispatchers.IO) { - repository.deleteFolder(folderId) - if (_state.value.selectedFolderId == folderId) { - onFolderClicked(-1) - } - } - } - - override fun onEditFolder(folderId: Int) { - if (folderId <= 0) return - onEditFoldersClick() - } - - override fun onOpenInstantView(url: String) { - _state.update { it.copy(instantViewUrl = url) } - } - - override fun onDismissInstantView() { - _state.update { it.copy(instantViewUrl = null) } - } - - override fun onOpenWebApp(url: String, botUserId: Long, botName: String) { - _state.update { - it.copy( - webAppUrl = url, - webAppBotId = botUserId, - webAppBotName = botName - ) - } - } - - override fun onDismissWebApp() { - _state.update { - it.copy( - webAppUrl = null, - webAppBotId = null, - webAppBotName = null - ) - } - } - - override fun onOpenWebView(url: String) { - _state.update { it.copy(webViewUrl = url) } - } - - override fun onDismissWebView() { - _state.update { it.copy(webViewUrl = null) } - } - - override fun onUpdateClicked() { - val currentState = _state.value.updateState - when (currentState) { - is UpdateState.UpdateAvailable -> { - updateRepository.downloadUpdate() - } - - is UpdateState.ReadyToInstall -> { - updateRepository.installUpdate() - } - - is UpdateState.Downloading -> { - updateRepository.cancelDownload() - } - - else -> { - onSettingsClick() - } - } - } - - override fun handleBack(): Boolean { - return when { - state.value.webViewUrl != null -> { - onDismissWebView() - true - } - state.value.webAppUrl != null -> { - onDismissWebApp() - true - } - state.value.instantViewUrl != null -> { - onDismissInstantView() - true - } - state.value.isSearchActive -> { - onSearchToggle() - true - } - state.value.selectedChatIds.isNotEmpty() -> { - clearSelection() - true - } - state.value.selectedFolderId == -2 -> { - onFolderClicked(-1) - true - } - - state.value.isForwarding -> { - onSelect(0L, null) - true - } - else -> false - } - } - - override fun updateScrollPosition(folderId: Int, index: Int, offset: Int) { - _state.update { - val newPositions = it.scrollPositions.toMutableMap() - newPositions[folderId] = index to offset - it.copy(scrollPositions = newPositions) - } - } - - companion object { - private const val TAG = "PinnedUiDiag" - } - - private fun toggleSelection(id: Long) { - _state.update { state -> - val newSelection = if (state.selectedChatIds.contains(id)) { - state.selectedChatIds - id - } else { - state.selectedChatIds + id - } - state.copy(selectedChatIds = newSelection) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/AccountMenu.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/AccountMenu.kt deleted file mode 100644 index c181a67e..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/AccountMenu.kt +++ /dev/null @@ -1,679 +0,0 @@ -package org.monogram.presentation.features.chats.chatList.components - -import android.widget.Toast -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.core.Animatable -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.spring -import androidx.compose.animation.core.tween -import androidx.compose.animation.expandVertically -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.shrinkVertically -import androidx.compose.animation.slideInVertically -import androidx.compose.animation.slideOutVertically -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.gestures.detectVerticalDragGestures -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.asPaddingValues -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.offset -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.statusBars -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.layout.widthIn -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.outlined.HelpOutline -import androidx.compose.material.icons.outlined.BookmarkBorder -import androidx.compose.material.icons.rounded.Add -import androidx.compose.material.icons.rounded.Close -import androidx.compose.material.icons.rounded.ExpandMore -import androidx.compose.material.icons.rounded.Person -import androidx.compose.material.icons.rounded.Settings -import androidx.compose.material.icons.rounded.SystemUpdate -import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.LinearProgressIndicator -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.rotate -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.hapticfeedback.HapticFeedbackType -import androidx.compose.ui.input.nestedscroll.NestedScrollConnection -import androidx.compose.ui.input.nestedscroll.NestedScrollSource -import androidx.compose.ui.input.nestedscroll.nestedScroll -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.LocalHapticFeedback -import androidx.compose.ui.platform.LocalUriHandler -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.IntOffset -import androidx.compose.ui.unit.Velocity -import androidx.compose.ui.unit.dp -import androidx.compose.ui.window.Dialog -import androidx.compose.ui.window.DialogProperties -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import org.monogram.domain.models.AttachMenuBotModel -import org.monogram.domain.models.UpdateState -import org.monogram.domain.models.UserModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsItem -import org.monogram.presentation.core.util.AppUtils -import org.monogram.presentation.core.util.CountryManager -import org.monogram.presentation.core.util.formatMaskedGlobal -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import kotlin.math.roundToInt - -@Composable -fun AccountMenu( - user: UserModel?, - videoPlayerPool: VideoPlayerPool, - attachMenuBots: List, - updateState: UpdateState = UpdateState.Idle, - onDismiss: () -> Unit, - onSavedMessagesClick: () -> Unit, - onSettingsClick: () -> Unit, - onAddAccountClick: () -> Unit, - onHelpClick: () -> Unit, - onUpdateClick: () -> Unit = {}, - onProfileClick: () -> Unit = {}, - onBotClick: (AttachMenuBotModel) -> Unit = {} -) { - val context = LocalContext.current - val uriHandler = LocalUriHandler.current - val scope = rememberCoroutineScope() - val density = LocalDensity.current - val addAccountNotImplemented = stringResource(R.string.not_implemented) - - var isVisible by remember { mutableStateOf(false) } - var isExpanded by remember { mutableStateOf(false) } - var isPhoneVisible by remember { mutableStateOf(false) } - - val offsetY = remember { Animatable(0f) } - val scrollState = rememberScrollState() - - val animateDismiss = { - scope.launch { - isVisible = false - delay(300) - onDismiss() - } - } - - val nestedScrollConnection = remember { - object : NestedScrollConnection { - override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset { - val delta = available.y - if (delta > 0 && offsetY.value < 0) { - val newOffset = (offsetY.value + delta).coerceAtMost(0f) - val consumed = newOffset - offsetY.value - scope.launch { offsetY.snapTo(newOffset) } - return Offset(0f, consumed) - } - if (delta < 0 && offsetY.value > 0) { - val newOffset = (offsetY.value + delta).coerceAtLeast(0f) - val consumed = newOffset - offsetY.value - scope.launch { offsetY.snapTo(newOffset) } - return Offset(0f, consumed) - } - return Offset.Zero - } - - override fun onPostScroll( - consumed: Offset, - available: Offset, - source: NestedScrollSource - ): Offset { - val delta = available.y - if (source == NestedScrollSource.UserInput) { - if (delta < 0 && scrollState.value == scrollState.maxValue) { - scope.launch { - val current = offsetY.value - val resistanceDelta = delta / 2 - offsetY.snapTo((current + resistanceDelta).coerceAtLeast(-600f)) - } - return Offset(0f, delta) - } else if (delta > 0 && scrollState.value == 0) { - scope.launch { - val current = offsetY.value - val resistanceDelta = delta / 2 - offsetY.snapTo((current + resistanceDelta).coerceAtMost(600f)) - } - return Offset(0f, delta) - } - } - return Offset.Zero - } - - override suspend fun onPreFling(available: Velocity): Velocity { - val dismissThreshold = with(density) { 100.dp.toPx() } - if (offsetY.value < -dismissThreshold || available.y < -2000f) { - animateDismiss() - return available - } else if (offsetY.value > dismissThreshold || available.y > 2000f) { - animateDismiss() - return available - } else if (offsetY.value != 0f) { - offsetY.animateTo(0f, spring(dampingRatio = Spring.DampingRatioMediumBouncy)) - return available - } - return Velocity.Zero - } - } - } - - LaunchedEffect(Unit) { - isVisible = true - } - - Dialog( - onDismissRequest = { animateDismiss() }, - properties = DialogProperties( - usePlatformDefaultWidth = false, - decorFitsSystemWindows = false - ) - ) { - Box( - modifier = Modifier - .fillMaxSize() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null - ) { animateDismiss() }, - contentAlignment = Alignment.TopCenter - ) { - AnimatedVisibility( - visible = isVisible, - enter = slideInVertically( - initialOffsetY = { -it }, - animationSpec = spring( - dampingRatio = Spring.DampingRatioLowBouncy, - stiffness = Spring.StiffnessMediumLow - ) - ), - exit = slideOutVertically( - targetOffsetY = { - if (offsetY.value > 0) it else -it - }, - animationSpec = tween(300) - ) + fadeOut(animationSpec = tween(300)) - ) { - Surface( - modifier = Modifier - .padding(8.dp) - .padding(top = WindowInsets.statusBars.asPaddingValues().calculateTopPadding()) - .widthIn(max = 600.dp) - .offset { IntOffset(0, offsetY.value.roundToInt()) } - .pointerInput(Unit) { - detectVerticalDragGestures( - onDragEnd = { - val dismissThreshold = with(density) { 100.dp.toPx() } - if (offsetY.value < -dismissThreshold || offsetY.value > dismissThreshold) { - animateDismiss() - } else { - scope.launch { - offsetY.animateTo( - 0f, - spring(dampingRatio = Spring.DampingRatioMediumBouncy) - ) - } - } - }, - onVerticalDrag = { change, dragAmount -> - change.consume() - scope.launch { - val current = offsetY.value - val delta = dragAmount / 2 - offsetY.snapTo((current + delta).coerceIn(-600f, 600f)) - } - } - ) - } - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null - ) { }, - shape = RoundedCornerShape(28.dp), - color = MaterialTheme.colorScheme.surfaceContainerHigh, - tonalElevation = 6.dp, - shadowElevation = 8.dp - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .nestedScroll(nestedScrollConnection) - .verticalScroll(scrollState) - ) { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(top = 12.dp, bottom = 4.dp), - contentAlignment = Alignment.Center - ) { - Box( - modifier = Modifier - .width(32.dp) - .height(4.dp) - .background( - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.4f), - shape = CircleShape - ) - ) - } - - MenuHeader(onDismiss = { animateDismiss() }) - - Column(modifier = Modifier.padding(horizontal = 12.dp)) { - ActiveAccountCard( - user = user, - isExpanded = isExpanded, - onExpandToggle = { - isExpanded = !isExpanded - isPhoneVisible = isExpanded - }, - isPhoneVisible = isPhoneVisible, - onPhoneToggle = { isPhoneVisible = !isPhoneVisible }, - videoPlayerPool = videoPlayerPool - ) - - AnimatedVisibility( - visible = isExpanded, - enter = expandVertically( - animationSpec = spring( - dampingRatio = Spring.DampingRatioNoBouncy, - stiffness = Spring.StiffnessMedium - ) - ) + fadeIn(), - exit = shrinkVertically() + fadeOut() - ) { - Column(modifier = Modifier.padding(top = 8.dp)) { - SettingsItem( - icon = Icons.Rounded.Add, - iconBackgroundColor = MaterialTheme.colorScheme.primary, - title = stringResource(R.string.action_add_account), - subtitle = stringResource(R.string.add_account_subtitle), - position = ItemPosition.STANDALONE, - onClick = { - Toast.makeText( - context, - addAccountNotImplemented, - Toast.LENGTH_SHORT - ).show() - onAddAccountClick() - } - ) - } - } - - Spacer(modifier = Modifier.height(16.dp)) - - val sideMenuBots = attachMenuBots.filter { it.showInSideMenu && it.name.isNotBlank() && it.icon?.icon != null } - - sideMenuBots.forEachIndexed { index, bot -> - SettingsItem( - icon = bot.icon!!.icon!!, - iconBackgroundColor = MaterialTheme.colorScheme.tertiary, - title = bot.name, - position = if (index == 0) ItemPosition.TOP else ItemPosition.MIDDLE, - onClick = { - onBotClick(bot) - animateDismiss() - } - ) - } - - SettingsItem( - icon = Icons.Rounded.Person, - iconBackgroundColor = MaterialTheme.colorScheme.primary, - title = stringResource(R.string.menu_my_profile), - subtitle = stringResource(R.string.menu_my_profile_subtitle), - position = if (sideMenuBots.isEmpty()) ItemPosition.TOP else ItemPosition.MIDDLE, - onClick = { - onProfileClick() - animateDismiss() - } - ) - - SettingsItem( - icon = Icons.Outlined.BookmarkBorder, - iconBackgroundColor = MaterialTheme.colorScheme.primary, - title = stringResource(R.string.menu_saved_messages), - subtitle = stringResource(R.string.menu_saved_messages_subtitle), - position = ItemPosition.MIDDLE, - onClick = { - onSavedMessagesClick() - animateDismiss() - } - ) - - SettingsItem( - icon = Icons.Rounded.Settings, - iconBackgroundColor = MaterialTheme.colorScheme.secondary, - title = stringResource(R.string.menu_settings), - subtitle = stringResource(R.string.menu_settings_subtitle), - position = ItemPosition.MIDDLE, - onClick = { - onSettingsClick() - animateDismiss() - } - ) - - if (updateState is UpdateState.UpdateAvailable || updateState is UpdateState.ReadyToInstall || updateState is UpdateState.Downloading) { - SettingsItem( - icon = Icons.Rounded.SystemUpdate, - iconBackgroundColor = MaterialTheme.colorScheme.error, - title = stringResource(R.string.menu_update_available), - subtitle = when (updateState) { - is UpdateState.UpdateAvailable -> stringResource( - R.string.update_available_subtitle_format, - updateState.info.version - ) - - is UpdateState.Downloading -> stringResource( - R.string.update_downloading_subtitle_format, - (updateState.progress * 100).toInt() - ) - - is UpdateState.ReadyToInstall -> stringResource(R.string.update_ready_subtitle) - else -> null - }, - position = ItemPosition.MIDDLE, - onClick = { - onUpdateClick() - if (updateState !is UpdateState.Downloading) { - animateDismiss() - } - } - ) - if (updateState is UpdateState.Downloading) { - LinearProgressIndicator( - progress = { updateState.progress }, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .height(4.dp) - .clip(CircleShape), - color = MaterialTheme.colorScheme.error, - trackColor = MaterialTheme.colorScheme.error.copy(alpha = 0.2f), - ) - Spacer(modifier = Modifier.height(8.dp)) - } - } - - SettingsItem( - icon = Icons.AutoMirrored.Outlined.HelpOutline, - iconBackgroundColor = MaterialTheme.colorScheme.tertiary, - title = stringResource(R.string.menu_help_feedback), - subtitle = stringResource(R.string.menu_help_feedback_subtitle), - position = ItemPosition.BOTTOM, - onClick = { - onHelpClick() - animateDismiss() - } - ) - } - - MenuFooter( - onPrivacyClick = { - uriHandler.openUri("https://telegram.org/privacy") - animateDismiss() - }, - onTermsClick = { - uriHandler.openUri("https://telegram.org/tos") - animateDismiss() - } - ) - - Box( - modifier = Modifier - .fillMaxWidth() - .padding(top = 4.dp, bottom = 12.dp), - contentAlignment = Alignment.Center - ) { - Box( - modifier = Modifier - .width(32.dp) - .height(4.dp) - .background( - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.4f), - shape = CircleShape - ) - ) - } - } - } - } - } - } -} - -@Composable -private fun MenuHeader(onDismiss: () -> Unit) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(start = 24.dp, end = 12.dp, top = 8.dp, bottom = 8.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = stringResource(R.string.app_name_dev), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - - IconButton( - onClick = onDismiss, - modifier = Modifier.background( - color = MaterialTheme.colorScheme.surfaceContainerHighest.copy(alpha = 0.5f), - shape = CircleShape - ) - ) { - Icon( - imageVector = Icons.Rounded.Close, - contentDescription = stringResource(R.string.cancel_button), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } -} - -@OptIn(ExperimentalFoundationApi::class) -@Composable -private fun ActiveAccountCard( - user: UserModel?, - videoPlayerPool: VideoPlayerPool, - isExpanded: Boolean, - onExpandToggle: () -> Unit, - isPhoneVisible: Boolean, - onPhoneToggle: () -> Unit -) { - val rotation by animateFloatAsState( - targetValue = if (isExpanded) 180f else 0f, - label = "rotation", - animationSpec = spring( - dampingRatio = Spring.DampingRatioMediumBouncy, - stiffness = Spring.StiffnessLow - ) - ) - - val containerColor = if (isExpanded) - MaterialTheme.colorScheme.surfaceContainerHighest - else - MaterialTheme.colorScheme.surfaceContainer - - val haptic = LocalHapticFeedback.current - - Surface( - modifier = Modifier - .fillMaxWidth() - .clip(RoundedCornerShape(20.dp)) - .combinedClickable( - onClick = onExpandToggle, - onLongClick = { - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - onPhoneToggle() - } - ), - shape = RoundedCornerShape(20.dp), - color = containerColor, - tonalElevation = if (isExpanded) 2.dp else 0.dp - ) { - Row( - modifier = Modifier - .padding(16.dp) - .fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically - ) { - Avatar( - path = user?.avatarPath, - fallbackPath = user?.personalAvatarPath, - name = user?.firstName ?: "", - size = 56.dp, - fontSize = 20, - videoPlayerPool = videoPlayerPool - ) - - Spacer(modifier = Modifier.width(16.dp)) - - Column(modifier = Modifier.weight(1f)) { - Text( - text = "${user?.firstName ?: ""} ${user?.lastName ?: ""}".trim() - .ifEmpty { stringResource(R.string.unknown_user) }, - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Text( - text = user?.phoneNumber?.let { - if (isPhoneVisible) CountryManager.formatPhone(it) else formatMaskedGlobal(it) - } ?: user?.username ?: stringResource(R.string.no_info), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null - ) { - onPhoneToggle() - } - ) - } - - IconButton( - onClick = onExpandToggle, - modifier = Modifier - .size(32.dp) - .background( - color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.05f), - shape = CircleShape - ) - ) { - Icon( - imageVector = Icons.Rounded.ExpandMore, - contentDescription = stringResource(R.string.cd_show_accounts), - tint = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier - .size(20.dp) - .rotate(rotation) - ) - } - } - } -} - -@Composable -private fun MenuFooter( - onPrivacyClick: () -> Unit, - onTermsClick: () -> Unit -) { - val context = LocalContext.current - val version = remember { AppUtils.getFullVersionString(context) } - Column( - modifier = Modifier - .fillMaxWidth() - .padding(top = 16.dp, bottom = 24.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - HorizontalDivider( - modifier = Modifier - .padding(horizontal = 24.dp, vertical = 16.dp) - .fillMaxWidth(), - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - FooterLink(text = stringResource(R.string.privacy_policy), onClick = onPrivacyClick) - Text( - text = "•", - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - FooterLink(text = stringResource(R.string.terms_of_service_title), onClick = onTermsClick) - } - - Spacer(modifier = Modifier.height(8.dp)) - - Text( - text = stringResource(R.string.app_version_footer_format, version), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f) - ) - } -} - -@Composable -private fun FooterLink(text: String, onClick: () -> Unit) { - Text( - text = text, - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Medium, - modifier = Modifier - .clip(RoundedCornerShape(4.dp)) - .clickable(onClick = onClick) - .padding(4.dp) - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/ArchiveHeaderCard.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/ArchiveHeaderCard.kt deleted file mode 100644 index 0a140f74..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/ArchiveHeaderCard.kt +++ /dev/null @@ -1,108 +0,0 @@ -package org.monogram.presentation.features.chats.chatList.components - -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.KeyboardArrowRight -import androidx.compose.material.icons.rounded.Archive -import androidx.compose.material.icons.rounded.PushPin -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.rotate -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import org.monogram.presentation.R - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun ArchiveHeaderCard( - isPinned: Boolean, - onClick: () -> Unit, - onLongClick: () -> Unit -) { - Card( - shape = RoundedCornerShape(20), - colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.surfaceContainerHigh, - contentColor = MaterialTheme.colorScheme.onSurface - ), - elevation = CardDefaults.cardElevation(0.dp), - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .height(78.dp) - .clip(RoundedCornerShape(20.dp)) - .combinedClickable( - onClick = onClick, - onLongClick = onLongClick - ) - ) { - Row( - modifier = Modifier - .fillMaxSize() - .padding(horizontal = 16.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(48.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primary.copy(alpha = 0.1f)), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.Archive, - contentDescription = stringResource(R.string.archived_chats_title), - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.size(24.dp) - ) - } - - Spacer(Modifier.width(12.dp)) - - Column( - modifier = Modifier.weight(1f), - verticalArrangement = Arrangement.Center - ) { - Text( - text = stringResource(R.string.archived_chats_title), - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.SemiBold, - color = MaterialTheme.colorScheme.onSurface - ) - Text( - text = stringResource(R.string.archived_chats_subtitle), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - - if (isPinned) { - Icon( - imageVector = Icons.Rounded.PushPin, - contentDescription = stringResource(R.string.cd_pinned), - modifier = Modifier - .size(18.dp) - .rotate(45f), - tint = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f) - ) - Spacer(Modifier.width(8.dp)) - } - - Icon( - imageVector = Icons.AutoMirrored.Rounded.KeyboardArrowRight, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f), - modifier = Modifier.size(24.dp) - ) - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/Avatar.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/Avatar.kt deleted file mode 100644 index 7e42d451..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/Avatar.kt +++ /dev/null @@ -1,108 +0,0 @@ -package org.monogram.presentation.features.chats.chatList.components - -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.key -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import coil3.compose.rememberAsyncImagePainter -import coil3.request.ImageRequest -import org.monogram.presentation.core.util.generateColorFromHash -import org.monogram.presentation.features.chats.currentChat.components.AvatarPlayer -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import java.io.File - -@Composable -fun AvatarTopAppBar( - path: String?, - fallbackPath: String? = null, - name: String, - size: Dp, - videoPlayerPool: VideoPlayerPool, - modifier: Modifier = Modifier, - fontSize: Int = 14, - isOnline: Boolean = false -) { - val context = LocalContext.current - val combinedModifier = modifier - .size(size) - .clip(CircleShape) - - Box(modifier = modifier.size(size)) { - val resolvedPath = resolveAvatarPath(path, fallbackPath) - val avatarFile = resolvedPath?.let { File(it) } - if (avatarFile != null && avatarFile.exists()) { - val avatarVersion = "${avatarFile.absolutePath}:${avatarFile.lastModified()}:${avatarFile.length()}" - if (resolvedPath.endsWith(".mp4", ignoreCase = true)) { - key(avatarVersion) { - AvatarPlayer( - path = resolvedPath, - modifier = combinedModifier, - contentScale = ContentScale.Crop, - videoPlayerPool = videoPlayerPool - ) - } - } else { - Image( - painter = rememberAsyncImagePainter( - model = ImageRequest.Builder(context) - .data(avatarFile) - .memoryCacheKey(avatarVersion) - .diskCacheKey(avatarVersion) - .build() - ), - contentDescription = null, - modifier = combinedModifier, - contentScale = ContentScale.Crop - ) - } - } else { - Box( - modifier = combinedModifier.background(generateColorFromHash(name).copy(alpha = 0.15f)), - contentAlignment = Alignment.Center - ) { - Text( - name.take(1).uppercase(), - style = MaterialTheme.typography.titleSmall.copy(fontSize = fontSize.sp), - color = generateColorFromHash(name) - ) - } - } - - if (isOnline) { - Box( - modifier = Modifier - .size(size / 4) - .align(Alignment.BottomEnd) - .background(MaterialTheme.colorScheme.background, CircleShape) - .padding(2.dp) - .background(Color(0xFF4CAF50), CircleShape) - ) - } - } -} - -private fun resolveAvatarPath(primaryPath: String?, fallbackPath: String?): String? { - val candidates = listOfNotNull(primaryPath?.takeIf { it.isNotBlank() }, fallbackPath?.takeIf { it.isNotBlank() }) - .distinct() - if (candidates.isEmpty()) return null - - val existingCandidates = candidates.filter { File(it).exists() } - val source = if (existingCandidates.isNotEmpty()) existingCandidates else candidates - - return source.firstOrNull { it.endsWith(".mp4", ignoreCase = true) } ?: source.firstOrNull() -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/ChatCreationCommon.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/ChatCreationCommon.kt deleted file mode 100644 index 3dee2605..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/ChatCreationCommon.kt +++ /dev/null @@ -1,244 +0,0 @@ -package org.monogram.presentation.features.chats.chatList.components - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Check -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ItemPosition - -@Composable -fun SectionHeader(text: String, modifier: Modifier = Modifier) { - Text( - text = text, - modifier = modifier - .fillMaxWidth() - .padding(start = 12.dp, bottom = 8.dp, top = 16.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) -} - -@Composable -fun SettingsTextField( - value: String, - onValueChange: (String) -> Unit, - placeholder: String, - icon: ImageVector, - position: ItemPosition, - modifier: Modifier = Modifier, - enabled: Boolean = true, - singleLine: Boolean = false, - minLines: Int = 1, - maxLines: Int = Int.MAX_VALUE, - keyboardOptions: KeyboardOptions = KeyboardOptions.Default, - keyboardActions: KeyboardActions = KeyboardActions.Default, - trailingIcon: @Composable (() -> Unit)? = null -) { - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = modifier.fillMaxWidth() - ) { - TextField( - value = value, - onValueChange = onValueChange, - placeholder = { Text(placeholder) }, - modifier = Modifier.fillMaxWidth(), - enabled = enabled, - singleLine = singleLine, - minLines = minLines, - maxLines = maxLines, - leadingIcon = { - Icon( - imageVector = icon, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary - ) - }, - trailingIcon = trailingIcon, - keyboardOptions = keyboardOptions, - keyboardActions = keyboardActions, - colors = TextFieldDefaults.colors( - focusedContainerColor = Color.Transparent, - unfocusedContainerColor = Color.Transparent, - disabledContainerColor = Color.Transparent, - focusedIndicatorColor = Color.Transparent, - unfocusedIndicatorColor = Color.Transparent, - disabledIndicatorColor = Color.Transparent, - disabledTextColor = MaterialTheme.colorScheme.onSurface, - disabledPlaceholderColor = MaterialTheme.colorScheme.onSurfaceVariant, - disabledLeadingIconColor = MaterialTheme.colorScheme.primary, - disabledTrailingIconColor = MaterialTheme.colorScheme.onSurfaceVariant - ) - ) - } - if (position != ItemPosition.BOTTOM && position != ItemPosition.STANDALONE) { - Spacer(Modifier.height(2.dp)) - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun AutoDeleteSelectorSheet( - selectedTime: Int, - onTimeSelected: (Int) -> Unit, - onDismissRequest: () -> Unit -) { - val options = remember { - listOf( - 0, - 86400, - 172800, - 259200, - 345600, - 432000, - 518400, - 604800, - 1209600, - 1814400, - 2592000, - 5184000, - 7776000, - 10368000, - 12960000, - 15552000, - 31536000 - ) - } - - ModalBottomSheet( - onDismissRequest = onDismissRequest, - sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true), - containerColor = MaterialTheme.colorScheme.background, - dragHandle = { BottomSheetDefaults.DragHandle() }, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 32.dp) - ) { - Text( - text = stringResource(R.string.auto_delete_messages_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(bottom = 16.dp) - ) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - LazyColumn( - modifier = Modifier - .fillMaxWidth() - .heightIn(max = 400.dp) - .padding(vertical = 8.dp) - ) { - items(options.size) { index -> - val seconds = options[index] - val isSelected = selectedTime == seconds - - Row( - modifier = Modifier - .fillMaxWidth() - .clickable { onTimeSelected(seconds) } - .padding(horizontal = 16.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = seconds.toAutoDeleteString(), - modifier = Modifier.weight(1f), - style = MaterialTheme.typography.bodyLarge, - color = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface, - fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Normal - ) - if (isSelected) { - Icon( - imageVector = Icons.Rounded.Check, - contentDescription = stringResource(R.string.chat_settings_selected), - tint = MaterialTheme.colorScheme.primary - ) - } - } - } - } - } - - Spacer(modifier = Modifier.height(24.dp)) - - Button( - onClick = onDismissRequest, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.close_button), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } -} - -@Composable -fun Int.toAutoDeleteString(): String { - return when (this) { - 0 -> stringResource(R.string.auto_delete_off) - 86400 -> stringResource(R.string.auto_delete_1_day) - 172800 -> stringResource(R.string.auto_delete_2_days) - 259200 -> stringResource(R.string.auto_delete_3_days) - 345600 -> stringResource(R.string.auto_delete_4_days) - 432000 -> stringResource(R.string.auto_delete_5_days) - 518400 -> stringResource(R.string.auto_delete_6_days) - 604800 -> stringResource(R.string.auto_delete_1_week) - 1209600 -> stringResource(R.string.auto_delete_2_weeks) - 1814400 -> stringResource(R.string.auto_delete_3_weeks) - 2592000 -> stringResource(R.string.auto_delete_1_month) - 5184000 -> stringResource(R.string.auto_delete_2_months) - 7776000 -> stringResource(R.string.auto_delete_3_months) - 10368000 -> stringResource(R.string.auto_delete_4_months) - 12960000 -> stringResource(R.string.auto_delete_5_months) - 15552000 -> stringResource(R.string.auto_delete_6_months) - 31536000 -> stringResource(R.string.auto_delete_1_year) - else -> stringResource(R.string.auto_delete_off) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/ChatListItem.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/ChatListItem.kt deleted file mode 100644 index df798419..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/ChatListItem.kt +++ /dev/null @@ -1,475 +0,0 @@ -package org.monogram.presentation.features.chats.chatList.components - -import androidx.compose.animation.* -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.rotate -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.text.withStyle -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.ChatModel -import org.monogram.domain.models.MessageEntityType -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.AvatarForChat -import org.monogram.presentation.core.ui.TypingDots -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.chats.currentChat.components.chats.addEmojiStyle -import org.monogram.presentation.features.chats.currentChat.components.chats.buildAnnotatedMessageTextWithEmoji -import org.monogram.presentation.features.chats.currentChat.components.chats.rememberMessageInlineContent -import org.monogram.presentation.features.stickers.ui.view.StickerImage - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun ChatListItem( - chat: ChatModel, - currentUserId: Long?, - isSelected: Boolean, - onClick: () -> Unit, - onLongClick: () -> Unit, - emojiFontFamily: FontFamily, - messageLines: Int, - showPhotos: Boolean, - videoPlayerPool: VideoPlayerPool, - modifier: Modifier = Modifier, - isTabletSelected: Boolean = false -) { - val isSavedMessages = chat.id == currentUserId - - val backgroundColor by animateColorAsState( - targetValue = when { - isSelected -> MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.3f) - isTabletSelected -> MaterialTheme.colorScheme.secondaryContainer.copy(alpha = 0.5f) - chat.isPinned -> MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f) - else -> Color.Transparent - }, - label = "ItemBg" - ) - - Row( - modifier = modifier - .fillMaxWidth() - .padding(horizontal = 8.dp, vertical = 2.dp) - .clip(RoundedCornerShape(24)) - .background(backgroundColor) - .combinedClickable(onClick = onClick, onLongClick = onLongClick) - .padding(horizontal = 8.dp, vertical = 8.dp) - .semantics { contentDescription = chat.title }, - verticalAlignment = Alignment.CenterVertically - ) { - AnimatedVisibility( - visible = showPhotos, - enter = fadeIn() + expandHorizontally(), - exit = fadeOut() + shrinkHorizontally() - ) { - Row { - ChatListItemAvatar( - chat = chat, - isSavedMessages = isSavedMessages, - isSelected = isSelected, - videoPlayerPool = videoPlayerPool - ) - - Spacer(Modifier.width(14.dp)) - } - } - - ChatListItemInfo( - chat = chat, - isSavedMessages = isSavedMessages, - emojiFontFamily = emojiFontFamily, - messageLines = messageLines, - modifier = Modifier.weight(1f) - ) - } -} - -@Composable -private fun ChatListItemAvatar( - chat: ChatModel, - isSavedMessages: Boolean, - isSelected: Boolean, - videoPlayerPool: VideoPlayerPool -) { - Box(contentAlignment = Alignment.Center) { - AnimatedVisibility( - visible = isSelected, - enter = scaleIn() + fadeIn(), - exit = scaleOut() + fadeOut() - ) { - Box( - modifier = Modifier - .size(56.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primary), - contentAlignment = Alignment.Center - ) { - Icon( - Icons.Rounded.Check, - null, - tint = MaterialTheme.colorScheme.onPrimary, - modifier = Modifier.size(26.dp) - ) - } - } - - if (!isSelected) { - Box(modifier = Modifier.size(56.dp)) { - if (isSavedMessages) { - Box( - modifier = Modifier - .fillMaxSize() - .clip(CircleShape) - .background(MaterialTheme.colorScheme.tertiaryContainer), - contentAlignment = Alignment.Center - ) { - Icon( - Icons.Rounded.Bookmark, - null, - tint = MaterialTheme.colorScheme.onTertiaryContainer, - modifier = Modifier.size(28.dp) - ) - } - } else { - AvatarForChat( - path = chat.avatarPath, - fallbackPath = chat.personalAvatarPath, - name = chat.title, - size = 56.dp, - isOnline = chat.isOnline, - videoPlayerPool = videoPlayerPool - ) - } - } - } - } -} - -@Composable -private fun ChatListItemInfo( - chat: ChatModel, - isSavedMessages: Boolean, - emojiFontFamily: FontFamily, - messageLines: Int, - modifier: Modifier = Modifier -) { - Column(modifier = modifier) { - ChatListItemHeader( - chat = chat, - isSavedMessages = isSavedMessages - ) - - Spacer(Modifier.height(4.dp)) - - ChatListItemContent( - chat = chat, - emojiFontFamily = emojiFontFamily, - messageLines = messageLines - ) - } -} - -@Composable -private fun ChatListItemHeader( - chat: ChatModel, - isSavedMessages: Boolean -) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, - modifier = Modifier.fillMaxWidth() - ) { - Row(modifier = Modifier.weight(1f, fill = false), verticalAlignment = Alignment.CenterVertically) { - if (chat.isForum) { - Icon( - imageVector = Icons.Rounded.Forum, - contentDescription = stringResource(R.string.cd_forum), - modifier = Modifier.size(18.dp), - tint = MaterialTheme.colorScheme.primary - ) - Spacer(Modifier.width(4.dp)) - } - Text( - text = if (isSavedMessages) stringResource(R.string.menu_saved_messages) else chat.title, - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.Medium, - color = MaterialTheme.colorScheme.onSurface, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.semantics { contentDescription = "ChatTitle" } - ) - - if (!isSavedMessages && chat.isMuted) { - Spacer(Modifier.width(4.dp)) - Icon( - imageVector = Icons.Rounded.NotificationsOff, - contentDescription = stringResource(R.string.cd_muted), - modifier = Modifier.size(14.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f) - ) - } - - if (!isSavedMessages && chat.isVerified) { - Spacer(Modifier.width(4.dp)) - Icon( - imageVector = Icons.Rounded.Verified, - contentDescription = stringResource(R.string.cd_verified), - modifier = Modifier.size(16.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - - if (!isSavedMessages && chat.isSponsor) { - Spacer(Modifier.width(4.dp)) - Icon( - imageVector = Icons.Rounded.Favorite, - contentDescription = stringResource(R.string.cd_sponsor), - modifier = Modifier.size(16.dp), - tint = Color(0xFFE53935) - ) - } - - if (!isSavedMessages && chat.emojiStatusPath != null) { - Spacer(Modifier.width(4.dp)) - StickerImage( - path = chat.emojiStatusPath, - modifier = Modifier.size(16.dp), - ) - } - } - - Spacer(Modifier.width(8.dp)) - - val timeColor = if (chat.unreadCount > 0 && !chat.isMuted) { - MaterialTheme.colorScheme.primary - } else { - MaterialTheme.colorScheme.onSurfaceVariant - } - - Text( - text = chat.lastMessageTime, - style = MaterialTheme.typography.labelMedium, - color = timeColor - ) - } -} - -@Composable -private fun ChatListItemContent( - chat: ChatModel, - emojiFontFamily: FontFamily, - messageLines: Int -) { - val fontSize = MaterialTheme.typography.bodyMedium.fontSize.value - - Row(verticalAlignment = Alignment.CenterVertically) { - Box(modifier = Modifier.weight(1f)) { - if (chat.typingAction != null) { - Row(verticalAlignment = Alignment.Bottom) { - Text( - text = chat.typingAction ?: "", - maxLines = 1, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.primary - ) - Spacer(Modifier.width(2.dp)) - TypingDots( - dotSize = 3.dp, - dotColor = MaterialTheme.colorScheme.primary, - modifier = Modifier.padding(bottom = 4.dp) - ) - } - } else if (chat.draftMessage != null) { - val draftHasSpoiler = chat.draftMessageEntities.any { it.type is MessageEntityType.Spoiler } - val inlineContent = if (!draftHasSpoiler) { - rememberMessageInlineContent( - entities = chat.draftMessageEntities, - fontSize = fontSize - ) - } else { - emptyMap() - } - val annotatedDraft = if (draftHasSpoiler) { - buildAnnotatedString { - val spoilerLabel = stringResource(R.string.message_spoiler) - append(spoilerLabel) - addStyle( - SpanStyle( - background = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.1f), - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f), - fontWeight = FontWeight.Bold - ), - 0, - spoilerLabel.length - ) - } - } else { - buildAnnotatedMessageTextWithEmoji( - text = chat.draftMessage ?: "", - entities = chat.draftMessageEntities - ) - } - Text( - text = buildAnnotatedString { - withStyle(SpanStyle(color = MaterialTheme.colorScheme.error)) { append(stringResource(R.string.message_draft_prefix)) } - append(annotatedDraft) - }, - inlineContent = inlineContent, - maxLines = messageLines, - overflow = TextOverflow.Ellipsis, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } else { - val lastText = chat.lastMessageText.ifEmpty { - if (chat.isChannel) stringResource(R.string.no_posts_yet) else stringResource(R.string.no_messages_yet) - } - val inlineContent = rememberMessageInlineContent( - entities = chat.lastMessageEntities, - fontSize = fontSize - ) - val annotatedText = if (chat.lastMessageText.isNotEmpty()) { - val hasSpoiler = chat.lastMessageEntities.any { it.type is MessageEntityType.Spoiler } - if (hasSpoiler) { - buildAnnotatedString { - val spoilerLabel = stringResource(R.string.message_spoiler) - append(spoilerLabel) - addStyle( - SpanStyle( - background = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.1f), - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f), - fontWeight = FontWeight.Bold - ), - 0, - spoilerLabel.length - ) - } - } else { - buildAnnotatedMessageTextWithEmoji( - text = chat.lastMessageText, - entities = chat.lastMessageEntities - ) - } - } else { - buildAnnotatedString { - append(lastText) - addEmojiStyle(lastText, emojiFontFamily) - } - } - Text( - text = annotatedText, - inlineContent = inlineContent, - maxLines = messageLines, - overflow = TextOverflow.Ellipsis, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.8f) - ) - } - } - - Spacer(Modifier.width(8.dp)) - - ChatListItemStatus(chat = chat) - } -} - -@Composable -private fun ChatListItemStatus(chat: ChatModel) { - Row(verticalAlignment = Alignment.CenterVertically) { - val hasUnread = chat.unreadCount > 0 || chat.isMarkedAsUnread || chat.unreadMentionCount > 0 - - if (chat.isPinned && !hasUnread) { - Icon( - Icons.Rounded.PushPin, - contentDescription = stringResource(R.string.cd_pinned), - modifier = Modifier - .size(14.dp) - .rotate(45f), - tint = MaterialTheme.colorScheme.secondary - ) - Spacer(Modifier.width(4.dp)) - } - - if (chat.unreadMentionCount > 0) { - Box( - modifier = Modifier - .background(MaterialTheme.colorScheme.primary, CircleShape) - .size(20.dp), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.AlternateEmail, - contentDescription = stringResource(R.string.cd_mentions), - modifier = Modifier.size(14.dp), - tint = MaterialTheme.colorScheme.onPrimary - ) - } - Spacer(Modifier.width(4.dp)) - } - - if (chat.unreadCount > 0 || chat.isMarkedAsUnread) { - val badgeColor = if (chat.isMuted) { - MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - } else { - MaterialTheme.colorScheme.primary - } - val contentColor = if (chat.isMuted) { - MaterialTheme.colorScheme.onSurfaceVariant - } else { - MaterialTheme.colorScheme.onPrimary - } - - Box( - modifier = Modifier - .background(badgeColor, CircleShape) - .padding(horizontal = 6.dp, vertical = 2.dp) - .defaultMinSize(minWidth = 20.dp, minHeight = 20.dp), - contentAlignment = Alignment.Center - ) { - if (chat.unreadCount > 0) { - Text( - text = chat.unreadCount.toString(), - style = MaterialTheme.typography.labelSmall, - color = contentColor, - fontWeight = FontWeight.Bold - ) - } else { - Box( - modifier = Modifier - .size(8.dp) - .background(contentColor, CircleShape) - ) - } - } - } else if (chat.isLastMessageOutgoing) { - val isRead = chat.lastReadOutboxMessageId >= chat.lastMessageId - Icon( - imageVector = if (isRead) Icons.Rounded.DoneAll else Icons.Rounded.Done, - contentDescription = null, - modifier = Modifier.size(18.dp), - tint = if (isRead) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/ChatListShimmer.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/ChatListShimmer.kt deleted file mode 100644 index 01259c58..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/ChatListShimmer.kt +++ /dev/null @@ -1,61 +0,0 @@ -package org.monogram.presentation.features.chats.chatList.components - -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import org.monogram.presentation.core.ui.shimmerBackground - -@Composable -fun ChatListShimmer(itemCount: Int = 10) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(top = 12.dp), - verticalArrangement = Arrangement.spacedBy(4.dp) - ) { - repeat(itemCount) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp) - ) { - Box( - modifier = Modifier - .size(54.dp) - .shimmerBackground(CircleShape) - ) - - Spacer(Modifier.size(14.dp)) - - Column(modifier = Modifier.weight(1f)) { - Box( - modifier = Modifier - .fillMaxWidth(0.55f) - .height(14.dp) - .shimmerBackground(RoundedCornerShape(6.dp)) - ) - Spacer(Modifier.height(9.dp)) - Box( - modifier = Modifier - .fillMaxWidth(0.8f) - .height(12.dp) - .shimmerBackground(RoundedCornerShape(6.dp)) - ) - } - - Spacer(Modifier.size(10.dp)) - - Box( - modifier = Modifier - .padding(top = 2.dp) - .size(width = 30.dp, height = 10.dp) - .shimmerBackground(RoundedCornerShape(4.dp)) - ) - } - } - } -} - diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/ChatListTopBar.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/ChatListTopBar.kt deleted file mode 100644 index 48b742bf..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/ChatListTopBar.kt +++ /dev/null @@ -1,321 +0,0 @@ -package org.monogram.presentation.features.chats.chatList.components - -import androidx.compose.animation.* -import androidx.compose.animation.core.FastOutSlowInEasing -import androidx.compose.animation.core.spring -import androidx.compose.animation.core.tween -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.filled.Star -import androidx.compose.material.icons.rounded.Close -import androidx.compose.material.icons.rounded.Search -import androidx.compose.material.icons.rounded.Shield -import androidx.compose.material.icons.rounded.ShieldMoon -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.Rect -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.boundsInRoot -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.UserModel -import org.monogram.domain.repository.ConnectionStatus -import org.monogram.presentation.R -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.stickers.ui.view.StickerImage - - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ChatListTopBar( - user: UserModel?, - videoPlayerPool: VideoPlayerPool, - connectionStatus: ConnectionStatus?, - isProxyEnabled: Boolean, - onRetryConnection: () -> Unit, - onProxySettingsClick: () -> Unit, - isSearchActive: Boolean, - searchQuery: String, - onSearchQueryChange: (String) -> Unit, - onSearchToggle: () -> Unit, - onStatusClick: (Rect?) -> Unit, - onMenuClick: () -> Unit -) { - var statusAnchorBounds by remember { mutableStateOf(null) } - - AnimatedContent( - targetState = isSearchActive, - transitionSpec = { - if (targetState) { - (fadeIn() + slideInVertically { -it / 4 }).togetherWith(fadeOut()) - } else { - fadeIn().togetherWith(fadeOut() + slideOutVertically { -it / 4 }) - } - }, - label = "TopBarSearchTransition" - ) { active -> - if (active) { - Box( - modifier = Modifier - .fillMaxWidth() - .statusBarsPadding() - .padding(horizontal = 16.dp, vertical = 8.dp) - ) { - SearchBar( - inputField = { - SearchBarDefaults.InputField( - query = searchQuery, - onQueryChange = onSearchQueryChange, - onSearch = {}, - expanded = false, - onExpandedChange = {}, - placeholder = { Text(stringResource(R.string.search_conversations_placeholder)) }, - leadingIcon = { - IconButton(onClick = onSearchToggle) { - Icon(Icons.AutoMirrored.Rounded.ArrowBack, contentDescription = stringResource(R.string.cd_back)) - } - }, - trailingIcon = { - if (searchQuery.isNotEmpty()) { - IconButton(onClick = { onSearchQueryChange("") }) { - Icon(Icons.Rounded.Close, contentDescription = stringResource(R.string.action_clear)) - } - } - } - ) - }, - expanded = false, - onExpandedChange = {}, - shape = RoundedCornerShape(24.dp), - colors = SearchBarDefaults.colors( - containerColor = MaterialTheme.colorScheme.surfaceContainerHigh, - dividerColor = Color.Transparent - ), - modifier = Modifier.fillMaxWidth() - ) {} - } - } else { - Row( - modifier = Modifier - .fillMaxWidth() - .statusBarsPadding() - .padding(horizontal = 20.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Column( - modifier = Modifier - .weight(1f) - .animateContentSize( - animationSpec = spring( - dampingRatio = 0.9f, - stiffness = 450f - ) - ) - ) { - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = stringResource(R.string.app_name_monogram), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - - if (!user?.statusEmojiPath.isNullOrBlank()) { - Spacer(modifier = Modifier.width(8.dp)) - Box( - modifier = Modifier - .onGloballyPositioned { statusAnchorBounds = it.boundsInRoot() } - .clickable { onStatusClick(statusAnchorBounds) } - ) { - StickerImage( - path = user.statusEmojiPath, - modifier = Modifier.size(28.dp), - ) - } - } else if (user?.isPremium == true) { - Spacer(modifier = Modifier.width(8.dp)) - Icon( - imageVector = Icons.Filled.Star, - contentDescription = stringResource(R.string.telegram_premium_title), - modifier = Modifier - .size(22.dp) - .onGloballyPositioned { statusAnchorBounds = it.boundsInRoot() } - .clickable { onStatusClick(statusAnchorBounds) }, - tint = Color(0xFF31A6FD) - ) - } - } - - val statusInfo = when { - connectionStatus != null && connectionStatus !is ConnectionStatus.Connected -> { - val (text, color, action) = when (connectionStatus) { - ConnectionStatus.WaitingForNetwork -> Triple( - stringResource(R.string.waiting_for_network), - MaterialTheme.colorScheme.error, - TopBarStatusAction.Retry - ) - - ConnectionStatus.Connecting -> Triple( - stringResource(R.string.connecting), - MaterialTheme.colorScheme.onSurfaceVariant, - TopBarStatusAction.ProxySettings - ) - - ConnectionStatus.Updating -> Triple( - stringResource(R.string.updating), - MaterialTheme.colorScheme.primary, - TopBarStatusAction.Retry - ) - - ConnectionStatus.ConnectingToProxy -> Triple( - stringResource(R.string.connecting_to_proxy), - MaterialTheme.colorScheme.primary, - TopBarStatusAction.ProxySettings - ) - } - - TopBarStatusInfo(text = text, color = color, action = action) - } - - isProxyEnabled -> TopBarStatusInfo( - text = stringResource(R.string.proxy_enabled), - color = MaterialTheme.colorScheme.primary, - action = TopBarStatusAction.ProxySettings - ) - - else -> null - } - - AnimatedContent( - targetState = statusInfo, - transitionSpec = { - val enter = fadeIn( - animationSpec = tween( - durationMillis = 260, - delayMillis = 40, - easing = FastOutSlowInEasing - ) - ) + - slideInVertically( - animationSpec = tween( - durationMillis = 300, - easing = FastOutSlowInEasing - ), - initialOffsetY = { it / 2 } - ) + - expandVertically( - animationSpec = spring( - dampingRatio = 0.92f, - stiffness = 520f - ), - expandFrom = Alignment.Top - ) - - val exit = fadeOut( - animationSpec = tween( - durationMillis = 200, - easing = FastOutSlowInEasing - ) - ) + - slideOutVertically( - animationSpec = tween( - durationMillis = 220, - easing = FastOutSlowInEasing - ), - targetOffsetY = { it / 3 } - ) + - shrinkVertically( - animationSpec = tween( - durationMillis = 220, - easing = FastOutSlowInEasing - ), - shrinkTowards = Alignment.Top - ) - - enter.togetherWith(exit).using(SizeTransform(clip = false)) - }, - label = "TopBarStatusTextTransition" - ) { info -> - if (info != null) { - Text( - text = info.text, - style = MaterialTheme.typography.labelSmall, - color = info.color, - modifier = Modifier.clickable { - when (info.action) { - TopBarStatusAction.Retry -> onRetryConnection() - TopBarStatusAction.ProxySettings -> onProxySettingsClick() - } - } - ) - } else { - Spacer(modifier = Modifier.height(0.dp)) - } - } - } - - Row(verticalAlignment = Alignment.CenterVertically) { - if (isProxyEnabled) { - val isConnected = - connectionStatus is ConnectionStatus.Connected || connectionStatus is ConnectionStatus.Updating - IconButton(onClick = onProxySettingsClick) { - Icon( - imageVector = if (isConnected) Icons.Rounded.Shield else Icons.Rounded.ShieldMoon, - contentDescription = stringResource(R.string.cd_proxy), - modifier = Modifier.size(24.dp), - tint = if (isConnected) Color(0xFF34A853) else MaterialTheme.colorScheme.error - ) - } - } - - IconButton(onClick = onSearchToggle) { - Icon( - imageVector = Icons.Rounded.Search, - contentDescription = stringResource(R.string.action_search), - modifier = Modifier.size(26.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - - Spacer(modifier = Modifier.width(4.dp)) - - IconButton( - onClick = onMenuClick, - modifier = Modifier - .size(40.dp) - .semantics { contentDescription = "Settings" } - ) { - AvatarTopAppBar( - path = user?.avatarPath, - fallbackPath = user?.personalAvatarPath, - name = user?.firstName ?: "", - size = 36.dp, - videoPlayerPool = videoPlayerPool - ) - } - } - } - } - } -} - -private data class TopBarStatusInfo( - val text: String, - val color: Color, - val action: TopBarStatusAction -) - -private enum class TopBarStatusAction { - Retry, - ProxySettings -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/EmptyStateView.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/EmptyStateView.kt deleted file mode 100644 index e111248a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/EmptyStateView.kt +++ /dev/null @@ -1,64 +0,0 @@ -package org.monogram.presentation.features.chats.chatList.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.ChatBubbleOutline -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import org.monogram.presentation.R - -@Composable -fun EmptyStateView( - modifier: Modifier = Modifier -) { - Column( - modifier = modifier - .fillMaxWidth() - .padding(24.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center - ) { - Box( - modifier = Modifier - .size(96.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primaryContainer), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.ChatBubbleOutline, - contentDescription = null, - modifier = Modifier.size(40.dp), - tint = MaterialTheme.colorScheme.onPrimaryContainer - ) - } - - Spacer(modifier = Modifier.height(24.dp)) - - Text( - text = stringResource(R.string.no_chats_yet), - style = MaterialTheme.typography.headlineSmall, - color = MaterialTheme.colorScheme.onSurface, - textAlign = TextAlign.Center - ) - - Spacer(modifier = Modifier.height(8.dp)) - - Text( - text = stringResource(R.string.start_new_conversation), - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center - ) - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/FolderTabs.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/FolderTabs.kt deleted file mode 100644 index 007373be..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/FolderTabs.kt +++ /dev/null @@ -1,201 +0,0 @@ -package org.monogram.presentation.features.chats.chatList.components - -import androidx.compose.animation.animateColorAsState -import androidx.compose.foundation.background -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.pager.PagerState -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Delete -import androidx.compose.material.icons.rounded.DragIndicator -import androidx.compose.material.icons.rounded.Edit -import androidx.compose.material.icons.rounded.Settings -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.DpOffset -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.FolderModel -import org.monogram.presentation.R -import org.monogram.presentation.settings.folders.getFolderIcon - -@Composable -fun FolderTabs( - folders: List, - pagerState: PagerState, - onTabClick: (Int) -> Unit, - onEditClick: () -> Unit, - onEditFolderClick: (FolderModel) -> Unit, - onDeleteFolderClick: (FolderModel) -> Unit, - onReorderFoldersClick: () -> Unit, - modifier: Modifier = Modifier -) { - val lazyListState = rememberLazyListState() - var contextMenuExpanded by remember { mutableStateOf(false) } - var contextMenuFolderIndex by remember { mutableIntStateOf(-1) } - - LaunchedEffect(pagerState.currentPage) { - lazyListState.animateScrollToItem(pagerState.currentPage) - } - - LazyRow( - state = lazyListState, - modifier = modifier - .fillMaxWidth() - .height(56.dp), - contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - items(folders.size) { index -> - val folder = folders[index] - val isSelected = pagerState.currentPage == index - - val backgroundColor by animateColorAsState( - targetValue = if (isSelected) - MaterialTheme.colorScheme.primaryContainer - else - MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f), - label = "TabBg" - ) - val contentColor by animateColorAsState( - targetValue = if (isSelected) - MaterialTheme.colorScheme.onPrimaryContainer - else - MaterialTheme.colorScheme.onSurfaceVariant, - label = "TabContent" - ) - - Box { - Row( - modifier = Modifier - .clip(RoundedCornerShape(12.dp)) - .background(backgroundColor) - .combinedClickable( - onClick = { onTabClick(index) }, - onLongClick = { - if (folder.id > 0) { - contextMenuFolderIndex = index - contextMenuExpanded = true - } - } - ) - .padding(horizontal = 12.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(6.dp) - ) { - val icon = getFolderIcon(folder.iconName) - if (icon != null) { - Icon( - imageVector = icon, - contentDescription = null, - modifier = Modifier.size(18.dp), - tint = contentColor - ) - } - - Text( - text = if (folder.id == -1) { - stringResource(R.string.folders_system_all_chats) - } else { - folder.title - }, - style = MaterialTheme.typography.labelLarge, - fontWeight = if (isSelected) FontWeight.Bold else FontWeight.Medium, - color = contentColor - ) - - } - - DropdownMenu( - expanded = contextMenuExpanded && contextMenuFolderIndex == index, - onDismissRequest = { contextMenuExpanded = false }, - offset = DpOffset(x = 0.dp, y = 8.dp), - shape = RoundedCornerShape(22.dp), - containerColor = Color.Transparent, - tonalElevation = 0.dp, - shadowElevation = 0.dp - ) { - Surface( - modifier = Modifier.widthIn(min = 220.dp, max = 260.dp), - shape = RoundedCornerShape(22.dp), - color = MaterialTheme.colorScheme.surfaceContainerHigh - ) { - Column(modifier = Modifier.padding(vertical = 8.dp)) { - DropdownMenuItem( - text = { Text(text = stringResource(R.string.folder_tab_edit)) }, - onClick = { - onEditFolderClick(folder) - contextMenuExpanded = false - }, - leadingIcon = { - Icon( - Icons.Rounded.Edit, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary - ) - } - ) - DropdownMenuItem( - text = { Text(text = stringResource(R.string.folder_tab_reorder)) }, - onClick = { - onReorderFoldersClick() - contextMenuExpanded = false - }, - leadingIcon = { - Icon( - Icons.Rounded.DragIndicator, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary - ) - } - ) - - HorizontalDivider( - modifier = Modifier.padding(horizontal = 12.dp), - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - - DropdownMenuItem( - text = { - Text( - text = stringResource(R.string.folder_tab_delete), - color = MaterialTheme.colorScheme.error - ) - }, - onClick = { - onDeleteFolderClick(folder) - contextMenuExpanded = false - }, - leadingIcon = { - Icon( - Icons.Rounded.Delete, - contentDescription = null, - tint = MaterialTheme.colorScheme.error - ) - } - ) - } - } - } - } - } - - item { - IconButton(onClick = onEditClick) { - Icon( - imageVector = Icons.Rounded.Settings, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/MessageSearchItem.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/MessageSearchItem.kt deleted file mode 100644 index 15fdebbd..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/MessageSearchItem.kt +++ /dev/null @@ -1,109 +0,0 @@ -package org.monogram.presentation.features.chats.chatList.components - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import java.text.SimpleDateFormat -import java.util.* - -@Composable -fun MessageSearchItem( - message: MessageModel, - onClick: () -> Unit, - videoPlayerPool: VideoPlayerPool, - modifier: Modifier = Modifier -) { - val date = Date(message.date.toLong() * 1000) - val calendar = Calendar.getInstance() - val currentCalendar = Calendar.getInstance() - calendar.time = date - - val isToday = calendar.get(Calendar.YEAR) == currentCalendar.get(Calendar.YEAR) && - calendar.get(Calendar.DAY_OF_YEAR) == currentCalendar.get(Calendar.DAY_OF_YEAR) - - val format = if (isToday) { - SimpleDateFormat("HH:mm", Locale.getDefault()) - } else { - SimpleDateFormat("MMM d", Locale.getDefault()) - } - val time = format.format(date) - - Row( - modifier = modifier - .fillMaxWidth() - .clickable(onClick = onClick) - .padding(horizontal = 16.dp, vertical = 10.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Avatar( - path = message.senderAvatar, - fallbackPath = message.senderPersonalAvatar, - name = message.senderName, - size = 48.dp, - videoPlayerPool = videoPlayerPool - ) - - Spacer(Modifier.width(14.dp)) - - Column(modifier = Modifier.weight(1f)) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, - modifier = Modifier.fillMaxWidth() - ) { - Text( - text = message.senderName, - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.Medium, - color = MaterialTheme.colorScheme.onSurface, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.weight(1f) - ) - - Spacer(Modifier.width(8.dp)) - - Text( - text = time, - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - - Spacer(Modifier.height(4.dp)) - - val text = when (val content = message.content) { - is MessageContent.Text -> content.text - is MessageContent.Photo -> content.caption.ifEmpty { "Photo" } - is MessageContent.Video -> content.caption.ifEmpty { "Video" } - is MessageContent.Voice -> "Voice message" - is MessageContent.VideoNote -> "Video message" - is MessageContent.Document -> content.caption.ifEmpty { content.fileName } - is MessageContent.Sticker -> "Sticker ${content.emoji}" - is MessageContent.Gif -> content.caption.ifEmpty { "GIF" } - is MessageContent.Poll -> "Poll: ${content.question}" - is MessageContent.Service -> content.text - else -> "Message" - } - - Text( - text = text.replace("\n", " "), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.8f) - ) - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/NewChannelContent.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/NewChannelContent.kt deleted file mode 100644 index 3832585f..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/NewChannelContent.kt +++ /dev/null @@ -1,205 +0,0 @@ -package org.monogram.presentation.features.chats.chatList.components - -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardCapitalization -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsItem - -@Composable -fun NewChannelContent( - title: String, - description: String, - photoPath: String?, - autoDeleteTime: Int, - onTitleChange: (String) -> Unit, - onDescriptionChange: (String) -> Unit, - onPhotoClick: () -> Unit, - onAutoDeleteTimeChange: (Int) -> Unit, - videoPlayerPool: VideoPlayerPool, - modifier: Modifier = Modifier -) { - var showAutoDeleteSheet by remember { mutableStateOf(false) } - val scrollState = rememberScrollState() - val focusManager = LocalFocusManager.current - - Column( - modifier = modifier - .fillMaxSize() - .verticalScroll(scrollState) - .padding(horizontal = 16.dp, vertical = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 8.dp, horizontal = 24.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - ChannelPhotoSelector( - photoPath = photoPath, - title = title, - onClick = onPhotoClick, - videoPlayerPool = videoPlayerPool - ) - Spacer(modifier = Modifier.height(16.dp)) - Text( - text = stringResource(R.string.channel_description_hint), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center, - lineHeight = 20.sp - ) - } - - SectionHeader(stringResource(R.string.channel_details_header)) - - SettingsTextField( - value = title, - onValueChange = onTitleChange, - placeholder = stringResource(R.string.channel_name_placeholder), - icon = Icons.Rounded.Campaign, - position = ItemPosition.TOP, - singleLine = true, - keyboardOptions = KeyboardOptions( - capitalization = KeyboardCapitalization.Sentences, - imeAction = ImeAction.Next - ), - trailingIcon = { - if (title.isNotEmpty()) { - IconButton(onClick = { onTitleChange("") }) { - Icon(Icons.Rounded.Close, contentDescription = stringResource(R.string.action_clear)) - } - } - } - ) - - SettingsTextField( - value = description, - onValueChange = onDescriptionChange, - placeholder = stringResource(R.string.description_optional_placeholder), - icon = Icons.Rounded.Description, - position = ItemPosition.BOTTOM, - minLines = 3, - maxLines = 5, - keyboardOptions = KeyboardOptions( - capitalization = KeyboardCapitalization.Sentences, - imeAction = ImeAction.Done - ), - keyboardActions = KeyboardActions( - onDone = { focusManager.clearFocus() } - ) - ) - - SectionHeader(stringResource(R.string.settings_section_header)) - - SettingsItem( - icon = Icons.Rounded.Timer, - iconBackgroundColor = MaterialTheme.colorScheme.primary, - title = stringResource(R.string.auto_delete_messages_title), - subtitle = autoDeleteTime.toAutoDeleteString(), - position = ItemPosition.STANDALONE, - onClick = { showAutoDeleteSheet = true } - ) - - Spacer(Modifier.height(16.dp)) - Text( - text = stringResource(R.string.channel_join_info), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(horizontal = 16.dp) - ) - } - - if (showAutoDeleteSheet) { - AutoDeleteSelectorSheet( - selectedTime = autoDeleteTime, - onTimeSelected = { - onAutoDeleteTimeChange(it) - showAutoDeleteSheet = false - }, - onDismissRequest = { showAutoDeleteSheet = false } - ) - } -} - -@Composable -private fun ChannelPhotoSelector( - photoPath: String?, - videoPlayerPool: VideoPlayerPool, - title: String, - onClick: () -> Unit -) { - Box( - contentAlignment = Alignment.Center, - modifier = Modifier.clickable(onClick = onClick) - ) { - Box( - modifier = Modifier - .size(100.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primary.copy(alpha = 0.1f)) - .border( - width = 1.dp, - color = MaterialTheme.colorScheme.primary.copy(alpha = 0.2f), - shape = CircleShape - ), - contentAlignment = Alignment.Center - ) { - if (photoPath != null) { - Avatar( - path = photoPath, - name = title, - size = 100.dp, - videoPlayerPool = videoPlayerPool - ) - } else { - Icon( - imageVector = Icons.Rounded.AddAPhoto, - contentDescription = null, - modifier = Modifier.size(36.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - } - - Box( - modifier = Modifier - .align(Alignment.BottomEnd) - .size(32.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primary) - .border(2.dp, MaterialTheme.colorScheme.surface, CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = if (photoPath == null) Icons.Rounded.Add else Icons.Rounded.CameraAlt, - contentDescription = if (photoPath == null) stringResource(R.string.add_photo_cd) else stringResource(R.string.change_photo_cd), - modifier = Modifier.size(16.dp), - tint = MaterialTheme.colorScheme.onPrimary - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/NewGroupContent.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/NewGroupContent.kt deleted file mode 100644 index d128861b..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/NewGroupContent.kt +++ /dev/null @@ -1,205 +0,0 @@ -package org.monogram.presentation.features.chats.chatList.components - -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardCapitalization -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsItem -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -@Composable -fun NewGroupContent( - title: String, - description: String, - photoPath: String?, - autoDeleteTime: Int, - onTitleChange: (String) -> Unit, - onDescriptionChange: (String) -> Unit, - onPhotoClick: () -> Unit, - onAutoDeleteTimeChange: (Int) -> Unit, - videoPlayerPool: VideoPlayerPool, - modifier: Modifier = Modifier -) { - var showAutoDeleteSheet by remember { mutableStateOf(false) } - val scrollState = rememberScrollState() - val focusManager = LocalFocusManager.current - - Column( - modifier = modifier - .fillMaxSize() - .verticalScroll(scrollState) - .padding(horizontal = 16.dp, vertical = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 8.dp, horizontal = 24.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - GroupPhotoSelector( - photoPath = photoPath, - title = title, - onClick = onPhotoClick, - videoPlayerPool = videoPlayerPool - ) - Spacer(modifier = Modifier.height(16.dp)) - Text( - text = stringResource(R.string.group_description_hint), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center, - lineHeight = 20.sp - ) - } - - SectionHeader(stringResource(R.string.group_details_header)) - - SettingsTextField( - value = title, - onValueChange = onTitleChange, - placeholder = stringResource(R.string.group_name_placeholder), - icon = Icons.Rounded.Groups, - position = ItemPosition.TOP, - singleLine = true, - keyboardOptions = KeyboardOptions( - capitalization = KeyboardCapitalization.Sentences, - imeAction = ImeAction.Next - ), - trailingIcon = { - if (title.isNotEmpty()) { - IconButton(onClick = { onTitleChange("") }) { - Icon(Icons.Rounded.Close, contentDescription = stringResource(R.string.action_clear)) - } - } - } - ) - - SettingsTextField( - value = description, - onValueChange = onDescriptionChange, - placeholder = stringResource(R.string.description_optional_placeholder), - icon = Icons.Rounded.Description, - position = ItemPosition.BOTTOM, - minLines = 2, - maxLines = 4, - keyboardOptions = KeyboardOptions( - capitalization = KeyboardCapitalization.Sentences, - imeAction = ImeAction.Done - ), - keyboardActions = KeyboardActions( - onDone = { focusManager.clearFocus() } - ) - ) - - SectionHeader(stringResource(R.string.settings_section_header)) - - SettingsItem( - icon = Icons.Rounded.Timer, - iconBackgroundColor = MaterialTheme.colorScheme.primary, - title = stringResource(R.string.auto_delete_messages_title), - subtitle = autoDeleteTime.toAutoDeleteString(), - position = ItemPosition.STANDALONE, - onClick = { showAutoDeleteSheet = true } - ) - - Spacer(Modifier.height(16.dp)) - Text( - text = stringResource(R.string.group_auto_delete_info), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(horizontal = 16.dp) - ) - } - - if (showAutoDeleteSheet) { - AutoDeleteSelectorSheet( - selectedTime = autoDeleteTime, - onTimeSelected = { - onAutoDeleteTimeChange(it) - showAutoDeleteSheet = false - }, - onDismissRequest = { showAutoDeleteSheet = false } - ) - } -} - -@Composable -private fun GroupPhotoSelector( - photoPath: String?, - videoPlayerPool: VideoPlayerPool, - title: String, - onClick: () -> Unit -) { - Box( - contentAlignment = Alignment.Center, - modifier = Modifier.clickable(onClick = onClick) - ) { - Box( - modifier = Modifier - .size(100.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primary.copy(alpha = 0.1f)) - .border( - width = 1.dp, - color = MaterialTheme.colorScheme.primary.copy(alpha = 0.2f), - shape = CircleShape - ), - contentAlignment = Alignment.Center - ) { - if (photoPath != null) { - Avatar( - path = photoPath, - name = title, - size = 100.dp, - videoPlayerPool = videoPlayerPool - ) - } else { - Icon( - imageVector = Icons.Rounded.AddAPhoto, - contentDescription = null, - modifier = Modifier.size(36.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - } - - Box( - modifier = Modifier - .align(Alignment.BottomEnd) - .size(32.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primary) - .border(2.dp, MaterialTheme.colorScheme.surface, CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = if (photoPath == null) Icons.Rounded.Add else Icons.Rounded.CameraAlt, - contentDescription = if (photoPath == null) stringResource(R.string.add_photo_cd) else stringResource(R.string.change_photo_cd), - modifier = Modifier.size(16.dp), - tint = MaterialTheme.colorScheme.onPrimary - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/PermissionRequestSheet.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/PermissionRequestSheet.kt deleted file mode 100644 index 25fa78a8..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/PermissionRequestSheet.kt +++ /dev/null @@ -1,400 +0,0 @@ -package org.monogram.presentation.features.chats.chatList.components - -import android.Manifest -import android.content.Intent -import android.os.Build -import android.os.PowerManager -import android.provider.Settings -import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalLifecycleOwner -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.core.content.ContextCompat -import androidx.core.content.PermissionChecker -import androidx.core.net.toUri -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleEventObserver -import org.monogram.presentation.R - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun PermissionRequestSheet( - onDismiss: () -> Unit -) { - val context = LocalContext.current - val powerManager = remember { context.getSystemService(PowerManager::class.java) } - - var showNotificationPermission by remember { - mutableStateOf( - Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && - ContextCompat.checkSelfPermission( - context, - Manifest.permission.POST_NOTIFICATIONS - ) != PermissionChecker.PERMISSION_GRANTED - ) - } - - var showBatteryOptimization by remember { - mutableStateOf( - Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && - powerManager?.isIgnoringBatteryOptimizations(context.packageName) == false - ) - } - - var showCameraPermission by remember { - mutableStateOf( - ContextCompat.checkSelfPermission( - context, - Manifest.permission.CAMERA - ) != PermissionChecker.PERMISSION_GRANTED - ) - } - - var showMicrophonePermission by remember { - mutableStateOf( - ContextCompat.checkSelfPermission( - context, - Manifest.permission.RECORD_AUDIO - ) != PermissionChecker.PERMISSION_GRANTED - ) - } - - var showLocationPermission by remember { - mutableStateOf( - ContextCompat.checkSelfPermission( - context, - Manifest.permission.ACCESS_COARSE_LOCATION - ) != PermissionChecker.PERMISSION_GRANTED - ) - } - - var showPhoneStatePermission by remember { - mutableStateOf( - ContextCompat.checkSelfPermission( - context, - Manifest.permission.READ_PHONE_STATE - ) != PermissionChecker.PERMISSION_GRANTED - ) - } - - val lifecycleOwner = LocalLifecycleOwner.current - DisposableEffect(lifecycleOwner) { - val observer = LifecycleEventObserver { _, event -> - if (event == Lifecycle.Event.ON_RESUME) { - showBatteryOptimization = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && - powerManager?.isIgnoringBatteryOptimizations(context.packageName) == false - - showNotificationPermission = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && - ContextCompat.checkSelfPermission( - context, - Manifest.permission.POST_NOTIFICATIONS - ) != PermissionChecker.PERMISSION_GRANTED - - showCameraPermission = ContextCompat.checkSelfPermission( - context, - Manifest.permission.CAMERA - ) != PermissionChecker.PERMISSION_GRANTED - - showMicrophonePermission = ContextCompat.checkSelfPermission( - context, - Manifest.permission.RECORD_AUDIO - ) != PermissionChecker.PERMISSION_GRANTED - - showLocationPermission = ContextCompat.checkSelfPermission( - context, - Manifest.permission.ACCESS_COARSE_LOCATION - ) != PermissionChecker.PERMISSION_GRANTED - - showPhoneStatePermission = ContextCompat.checkSelfPermission( - context, - Manifest.permission.READ_PHONE_STATE - ) != PermissionChecker.PERMISSION_GRANTED - } - } - lifecycleOwner.lifecycle.addObserver(observer) - onDispose { - lifecycleOwner.lifecycle.removeObserver(observer) - } - } - - val notificationLauncher = rememberLauncherForActivityResult( - ActivityResultContracts.RequestPermission() - ) { isGranted -> showNotificationPermission = !isGranted } - - val cameraLauncher = rememberLauncherForActivityResult( - ActivityResultContracts.RequestPermission() - ) { isGranted -> showCameraPermission = !isGranted } - - val microphoneLauncher = rememberLauncherForActivityResult( - ActivityResultContracts.RequestPermission() - ) { isGranted -> showMicrophonePermission = !isGranted } - - val phoneStateLauncher = rememberLauncherForActivityResult( - ActivityResultContracts.RequestPermission() - ) { isGranted -> showPhoneStatePermission = !isGranted } - - val locationLauncher = rememberLauncherForActivityResult( - ActivityResultContracts.RequestMultiplePermissions() - ) { perms -> - showLocationPermission = perms.values.none { it } - } - - val hasAnyPermission = showNotificationPermission || showBatteryOptimization || - showCameraPermission || showMicrophonePermission || showLocationPermission || showPhoneStatePermission - - if (!hasAnyPermission) { - LaunchedEffect(Unit) { onDismiss() } - return - } - - ModalBottomSheet( - onDismissRequest = onDismiss, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.surface, - shape = RoundedCornerShape(topStart = 28.dp, topEnd = 28.dp), - sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 32.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Box( - modifier = Modifier - .size(64.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primaryContainer), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.Security, - contentDescription = null, - tint = MaterialTheme.colorScheme.onPrimaryContainer, - modifier = Modifier.size(32.dp) - ) - } - - Spacer(modifier = Modifier.height(16.dp)) - - Text( - text = stringResource(R.string.permissions_required_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.ExtraBold, - textAlign = TextAlign.Center - ) - - Spacer(modifier = Modifier.height(8.dp)) - - Text( - text = stringResource(R.string.permissions_required_description), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center, - modifier = Modifier.padding(horizontal = 16.dp) - ) - - Spacer(modifier = Modifier.height(24.dp)) - - LazyColumn( - modifier = Modifier.weight(1f, fill = false), - verticalArrangement = Arrangement.spacedBy(12.dp), - contentPadding = PaddingValues(vertical = 8.dp) - ) { - if (showNotificationPermission) { - item(key = "notifications") { - PermissionItem( - modifier = Modifier.animateItem(), - icon = Icons.Rounded.Notifications, - title = stringResource(R.string.permission_notifications_title), - description = stringResource(R.string.permission_notifications_description), - buttonText = stringResource(R.string.permission_allow_button), - onClick = { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - notificationLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) - } - } - ) - } - } - - if (showPhoneStatePermission) { - item(key = "phone_state") { - PermissionItem( - modifier = Modifier.animateItem(), - icon = Icons.Rounded.Phone, - title = stringResource(R.string.permission_phone_state_title), - description = stringResource(R.string.permission_phone_state_description), - buttonText = stringResource(R.string.permission_allow_button), - onClick = { phoneStateLauncher.launch(Manifest.permission.READ_PHONE_STATE) } - ) - } - } - - if (showBatteryOptimization) { - item(key = "battery") { - PermissionItem( - modifier = Modifier.animateItem(), - icon = Icons.Rounded.BatterySaver, - title = stringResource(R.string.permission_battery_optimization_title), - description = stringResource(R.string.permission_battery_optimization_description), - buttonText = stringResource(R.string.permission_disable_button), - onClick = { - val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply { - data = "package:${context.packageName}".toUri() - } - context.startActivity(intent) - } - ) - } - } - - if (showCameraPermission) { - item(key = "camera") { - PermissionItem( - modifier = Modifier.animateItem(), - icon = Icons.Rounded.CameraAlt, - title = stringResource(R.string.permission_camera_title), - description = stringResource(R.string.permission_camera_description), - buttonText = stringResource(R.string.permission_allow_button), - onClick = { cameraLauncher.launch(Manifest.permission.CAMERA) } - ) - } - } - - if (showMicrophonePermission) { - item(key = "microphone") { - PermissionItem( - modifier = Modifier.animateItem(), - icon = Icons.Rounded.Mic, - title = stringResource(R.string.permission_microphone_title), - description = stringResource(R.string.permission_microphone_description), - buttonText = stringResource(R.string.permission_allow_button), - onClick = { microphoneLauncher.launch(Manifest.permission.RECORD_AUDIO) } - ) - } - } - - if (showLocationPermission) { - item(key = "location") { - PermissionItem( - modifier = Modifier.animateItem(), - icon = Icons.Rounded.LocationOn, - title = stringResource(R.string.permission_location_title), - description = stringResource(R.string.permission_location_description), - buttonText = stringResource(R.string.permission_allow_button), - onClick = { - locationLauncher.launch( - arrayOf( - Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_COARSE_LOCATION - ) - ) - } - ) - } - } - } - - Spacer(modifier = Modifier.height(24.dp)) - - Button( - onClick = onDismiss, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.continue_button), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } -} - -@Composable -private fun PermissionItem( - icon: ImageVector, - title: String, - description: String, - buttonText: String, - modifier: Modifier = Modifier, - onClick: () -> Unit -) { - Surface( - color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.3f), - shape = RoundedCornerShape(24.dp), - modifier = modifier.fillMaxWidth() - ) { - Row( - modifier = Modifier - .padding(12.dp) - .fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(48.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primaryContainer), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = icon, - contentDescription = null, - tint = MaterialTheme.colorScheme.onPrimaryContainer, - modifier = Modifier.size(24.dp) - ) - } - - Spacer(modifier = Modifier.width(16.dp)) - - Column(modifier = Modifier.weight(1f)) { - Text( - text = title, - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.SemiBold - ) - Text( - text = description, - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - lineHeight = 16.sp - ) - } - - Spacer(modifier = Modifier.width(12.dp)) - - FilledTonalButton( - onClick = onClick, - shape = RoundedCornerShape(12.dp), - contentPadding = PaddingValues(horizontal = 16.dp), - modifier = Modifier.height(36.dp) - ) { - Text( - text = buttonText, - style = MaterialTheme.typography.labelLarge, - fontWeight = FontWeight.Bold - ) - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/SelectionTopBar.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/SelectionTopBar.kt deleted file mode 100644 index af2b5ac1..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/chatList/components/SelectionTopBar.kt +++ /dev/null @@ -1,72 +0,0 @@ -package org.monogram.presentation.features.chats.chatList.components - -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.VolumeOff -import androidx.compose.material.icons.automirrored.rounded.VolumeUp -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import org.monogram.presentation.R - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun SelectionTopBar( - selectedCount: Int, - isInArchive: Boolean, - allPinned: Boolean, - allMuted: Boolean, - onClearSelection: () -> Unit, - onPinClick: () -> Unit, - onMuteClick: () -> Unit, - onArchiveClick: () -> Unit, - onDeleteClick: () -> Unit, - onToggleReadClick: () -> Unit, - canMarkUnread: Boolean -) { - TopAppBar( - title = { - Text( - text = "$selectedCount", - style = MaterialTheme.typography.titleLarge, - fontWeight = FontWeight.Bold - ) - }, - navigationIcon = { - IconButton(onClick = onClearSelection) { - Icon(Icons.Rounded.Close, contentDescription = stringResource(R.string.cd_clear_selection)) - } - }, - actions = { - IconButton(onClick = onPinClick) { - Icon( - Icons.Rounded.PushPin, - stringResource(if (allPinned) R.string.action_unpin else R.string.action_pin) - ) - } - IconButton(onClick = onMuteClick) { - Icon( - imageVector = if (allMuted) Icons.AutoMirrored.Rounded.VolumeUp else Icons.AutoMirrored.Rounded.VolumeOff, - contentDescription = stringResource(if (allMuted) R.string.menu_unmute else R.string.menu_mute) - ) - } - IconButton(onClick = onArchiveClick) { - Icon( - imageVector = if (isInArchive) Icons.Rounded.Unarchive else Icons.Rounded.Archive, - contentDescription = stringResource(if (isInArchive) R.string.menu_unarchive else R.string.menu_archive) - ) - } - IconButton(onClick = onDeleteClick) { Icon(Icons.Rounded.Delete, stringResource(R.string.action_delete)) } - IconButton(onClick = onToggleReadClick) { - Icon( - Icons.Rounded.DoneAll, - stringResource(if (canMarkUnread) R.string.action_mark_as_unread else R.string.action_mark_as_read) - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.surfaceContainer - ) - ) -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/AutoDownloadSuppression.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/AutoDownloadSuppression.kt deleted file mode 100644 index ae93ab7e..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/AutoDownloadSuppression.kt +++ /dev/null @@ -1,17 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat - -import java.util.concurrent.ConcurrentHashMap - -object AutoDownloadSuppression { - private val suppressedFileIds = ConcurrentHashMap.newKeySet() - - fun suppress(fileId: Int) { - if (fileId != 0) suppressedFileIds.add(fileId) - } - - fun clear(fileId: Int) { - if (fileId != 0) suppressedFileIds.remove(fileId) - } - - fun isSuppressed(fileId: Int): Boolean = fileId != 0 && suppressedFileIds.contains(fileId) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/ChatComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/ChatComponent.kt deleted file mode 100644 index 636cc940..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/ChatComponent.kt +++ /dev/null @@ -1,301 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat - -import androidx.compose.runtime.Stable -import androidx.compose.ui.platform.ClipboardManager -import kotlinx.coroutines.flow.StateFlow -import org.monogram.domain.models.* -import org.monogram.domain.repository.InlineBotResultsModel -import org.monogram.domain.repository.MessageRepository -import org.monogram.domain.repository.StickerRepository -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import java.io.File - -@Stable -interface ChatComponent { - val appPreferences: AppPreferences - val videoPlayerPool: VideoPlayerPool - val stickerRepository: StickerRepository - val state: StateFlow - val repositoryMessage: MessageRepository - val downloadUtils: IDownloadUtils - - fun onSendMessage( - text: String, - entities: List = emptyList(), - sendOptions: MessageSendOptions = MessageSendOptions() - ) - - fun onSendSticker(stickerPath: String) - fun onSendPhoto( - photoPath: String, - caption: String = "", - captionEntities: List = emptyList(), - sendOptions: MessageSendOptions = MessageSendOptions() - ) - - fun onSendVideo( - videoPath: String, - caption: String = "", - captionEntities: List = emptyList(), - sendOptions: MessageSendOptions = MessageSendOptions() - ) - - fun onSendGif(gif: GifModel) - fun onSendGifFile( - path: String, - caption: String = "", - captionEntities: List = emptyList(), - sendOptions: MessageSendOptions = MessageSendOptions() - ) - - fun onSendAlbum( - paths: List, - caption: String = "", - captionEntities: List = emptyList(), - sendOptions: MessageSendOptions = MessageSendOptions() - ) - - fun onSendVoice(path: String, duration: Int, waveform: ByteArray) - fun onRefreshScheduledMessages() - fun onSendScheduledNow(message: MessageModel) - fun loadMore() - fun loadNewer() - fun onBackClicked() - fun onProfileClicked() - fun onMessageClicked(id: Long) - fun onMessageVisible(messageId: Long) - fun onReplyMessage(message: MessageModel) - fun onCancelReply() - fun onVideoRecorded(file: File) - fun onForwardMessage(message: MessageModel) - fun onForwardSelectedMessages() - fun onDeleteMessage(message: MessageModel, revoke: Boolean = false) - fun onEditMessage(message: MessageModel) - fun onCancelEdit() - fun onSaveEditedMessage(text: String, entities: List = emptyList()) - fun onDraftChange(text: String) - fun onPinMessage(message: MessageModel) - fun onUnpinMessage(message: MessageModel) - fun onPinnedMessageClick(message: MessageModel? = null) - fun onShowAllPinnedMessages() - fun onDismissPinnedMessages() - fun onScrollToMessageConsumed() - fun onScrollToBottom() - fun onDownloadFile(fileId: Int) - fun onDownloadHighRes(messageId: Long) - fun onCancelDownloadFile(fileId: Int) - fun updateScrollPosition(messageId: Long) - fun onBottomReached(isAtBottom: Boolean) - fun onHighlightConsumed() - fun onTyping() - fun onSendReaction(messageId: Long, reaction: String) - suspend fun getMessageReadDate(chatId: Long, messageId: Long, messageDate: Int): Int - suspend fun getMessageViewers(chatId: Long, messageId: Long): List - fun toProfile(id: Long) - fun onToggleMessageSelection(messageId: Long) - fun onClearSelection() - fun onClearMessages() - fun onDeleteSelectedMessages(revoke: Boolean = false) - fun onCopySelectedMessages(clipboardManager: ClipboardManager) - - fun onStickerClick(setId: Long) - fun onDismissStickerSet() - fun onAddToGifs(path: String) - fun onPollOptionClick(messageId: Long, optionId: Int) - fun onRetractVote(messageId: Long) - fun onShowVoters(messageId: Long, optionId: Int) - fun onDismissVoters() - fun onClosePoll(messageId: Long) - - fun onTopicClick(topicId: Int) - - fun onOpenInstantView(url: String) - fun onDismissInstantView() - - fun onOpenYouTube(url: String) - fun onDismissYouTube() - - fun onOpenMiniApp(url: String, name: String, botUserId: Long = 0L) - fun onDismissMiniApp() - fun onAcceptMiniAppTOS() - fun onDismissMiniAppTOS() - - fun onOpenWebView(url: String) - fun onDismissWebView() - - fun onOpenImages( - images: List, - captions: List, - startIndex: Int, - messageId: Long? = null, - messageIds: List = emptyList() - ) - fun onDismissImages() - - fun onOpenVideo(path: String? = null, messageId: Long? = null, caption: String? = null) - fun onDismissVideo() - - fun onAddToAdBlockWhitelist() - fun onRemoveFromAdBlockWhitelist() - - fun onToggleMute() - fun onSearchToggle() - fun onSearchQueryChange(query: String) - fun onClearHistory() - fun onDeleteChat() - fun onReport() - fun onReportMessage(message: MessageModel) - fun onReportReasonSelected(reason: String) - fun onDismissReportDialog() - fun onCopyLink(clipboardManager: ClipboardManager) - - fun scrollToMessage(messageId: Long) - - fun onBotCommandClick(command: String) - fun onShowBotCommands() - fun onDismissBotCommands() - - fun onCommentsClick(messageId: Long) - - fun onReplyMarkupButtonClick(messageId: Long, button: InlineKeyboardButtonModel, botUserId: Long) - fun onReplyMarkupButtonClick(messageId: Long, button: KeyboardButtonModel, botUserId: Long) - - fun onLinkClick(url: String) - - fun onOpenInvoice(slug: String? = null, messageId: Long? = null) - fun onDismissInvoice(status: String) - - fun onMentionQueryChange(query: String?) - - fun onJoinChat() - - fun onBlockUser(userId: Long) - fun onUnblockUser(userId: Long) - fun onRestrictUser(userId: Long, permissions: ChatPermissionsModel) - fun onConfirmRestrict(permissions: ChatPermissionsModel, untilDate: Int) - fun onDismissRestrictDialog() - - fun onInlineQueryChange(botUsername: String, query: String) - fun onLoadMoreInlineResults(offset: String) - fun onSendInlineResult(resultId: String) - fun onOpenAttachBot(botUserId: Long, fallbackName: String) - - @Stable - data class State( - val chatId: Long = 0L, - val chatTitle: String = "Chat", - val chatAvatar: String? = null, - val chatPersonalAvatar: String? = null, - val chatEmojiStatus: String? = null, - val isGroup: Boolean = false, - val isChannel: Boolean = false, - val isOnline: Boolean = false, - val isVerified: Boolean = false, - val isSponsor: Boolean = false, - val canWrite: Boolean = false, - val isAdmin: Boolean = false, - val permissions: ChatPermissionsModel = ChatPermissionsModel(), - val memberCount: Int = 0, - val onlineCount: Int = 0, - val unreadCount: Int = 0, - val unreadMentionCount: Int = 0, - val unreadReactionCount: Int = 0, - val userStatus: String? = null, - val typingAction: String? = null, - val messages: List = emptyList(), - val isLoading: Boolean = false, - val isLoadingOlder: Boolean = false, - val isLoadingNewer: Boolean = false, - val replyMessage: MessageModel? = null, - val editingMessage: MessageModel? = null, - val editRequestTime: Long = 0L, - val draftText: String = "", - val pinnedMessage: MessageModel? = null, - val allPinnedMessages: List = emptyList(), - val showPinnedMessagesList: Boolean = false, - val pinnedMessageCount: Int = 0, - val pinnedMessageIndex: Int = 0, - val scrollToMessageId: Long? = null, - val highlightedMessageId: Long? = null, - val isAtBottom: Boolean = true, - val currentScrollMessageId: Long = 0L, - val lastScrollPosition: Long = 0L, - val isLatestLoaded: Boolean = true, - val isOldestLoaded: Boolean = false, - val fontSize: Float = 16f, - val letterSpacing: Float = 0f, - val bubbleRadius: Float = 18f, - val wallpaper: String? = null, - val wallpaperModel: WallpaperModel? = null, - val isWallpaperBlurred: Boolean = false, - val wallpaperBlurIntensity: Int = 20, - val isWallpaperMoving: Boolean = false, - val wallpaperDimming: Int = 0, - val isWallpaperGrayscale: Boolean = false, - val isPlayerGesturesEnabled: Boolean = true, - val isPlayerDoubleTapSeekEnabled: Boolean = true, - val playerSeekDuration: Int = 10, - val isPlayerZoomEnabled: Boolean = true, - val autoDownloadMobile: Boolean = true, - val autoDownloadWifi: Boolean = true, - val autoDownloadRoaming: Boolean = false, - val autoDownloadFiles: Boolean = false, - val autoplayGifs: Boolean = true, - val autoplayVideos: Boolean = true, - val showLinkPreviews: Boolean = true, - val isChatAnimationsEnabled: Boolean = true, - val selectedMessageIds: Set = emptySet(), - val selectedStickerSet: StickerSetModel? = null, - val pollVoters: List = emptyList(), - val showPollVoters: Boolean = false, - val isPollVotersLoading: Boolean = false, - val viewAsTopics: Boolean = false, - val topics: List = emptyList(), - val currentTopicId: Long? = null, - val rootMessage: MessageModel? = null, - val isLoadingTopics: Boolean = false, - val instantViewUrl: String? = null, - val youtubeUrl: String? = null, - val miniAppUrl: String? = null, - val miniAppName: String? = null, - val miniAppBotUserId: Long = 0L, - val showMiniAppTOS: Boolean = false, - val miniAppTOSBotUserId: Long = 0L, - val miniAppTOSUrl: String? = null, - val miniAppTOSName: String? = null, - val webViewUrl: String? = null, - val fullScreenImages: List? = null, - val fullScreenImageMessageIds: List = emptyList(), - val fullScreenCaptions: List = emptyList(), - val fullScreenStartIndex: Int = 0, - val fullScreenVideoMessageId: Long? = null, - val fullScreenVideoPath: String? = null, - val fullScreenVideoCaption: String? = null, - val isWhitelistedInAdBlock: Boolean = false, - val isMuted: Boolean = false, - val isSearchActive: Boolean = false, - val searchQuery: String = "", - val showReportDialog: Boolean = false, - val isBot: Boolean = false, - val botCommands: List = emptyList(), - val botMenuButton: BotMenuButtonModel = BotMenuButtonModel.Default, - val showBotCommands: Boolean = false, - val currentUser: UserModel? = null, - val otherUser: UserModel? = null, - val invoiceSlug: String? = null, - val invoiceMessageId: Long? = null, - val mentionSuggestions: List = emptyList(), - val isMember: Boolean = true, - val restrictUserId: Long? = null, - val inlineBotResults: InlineBotResultsModel? = null, - val currentInlineBotId: Long? = null, - val currentInlineBotUsername: String? = null, - val currentInlineQuery: String? = null, - val isInlineBotLoading: Boolean = false, - val isInstalledFromGooglePlay: Boolean = true, - val attachMenuBots: List = emptyList(), - val scheduledMessages: List = emptyList() - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/ChatContent.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/ChatContent.kt deleted file mode 100644 index 81d2bd68..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/ChatContent.kt +++ /dev/null @@ -1,1264 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat - -import androidx.activity.compose.BackHandler -import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.PickVisualMediaRequest -import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.animation.* -import androidx.compose.animation.core.* -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.gestures.animateScrollBy -import androidx.compose.foundation.gestures.detectHorizontalDragGestures -import androidx.compose.foundation.gestures.scrollBy -import androidx.compose.foundation.interaction.collectIsDraggedAsState -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyListState -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.KeyboardArrowDown -import androidx.compose.material.icons.rounded.Block -import androidx.compose.material3.* -import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.geometry.Rect -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.platform.LocalClipboardManager -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.platform.LocalSoftwareKeyboardController -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.IntSize -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.unit.toSize -import androidx.compose.ui.zIndex -import androidx.window.core.layout.WindowWidthSizeClass -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.* -import kotlinx.coroutines.launch -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.domain.models.ReplyMarkupModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ConfirmationSheet -import org.monogram.presentation.features.chats.currentChat.chatContent.* -import org.monogram.presentation.features.chats.currentChat.components.* -import org.monogram.presentation.features.chats.currentChat.components.chats.BotCommandsSheet -import org.monogram.presentation.features.chats.currentChat.components.chats.LocalLinkHandler -import org.monogram.presentation.features.chats.currentChat.components.chats.PollVotersSheet -import org.monogram.presentation.features.chats.currentChat.components.pins.PinnedMessagesListSheet -import org.monogram.presentation.features.chats.currentChat.editor.photo.PhotoEditorScreen -import org.monogram.presentation.features.chats.currentChat.editor.video.VideoEditorScreen -import org.monogram.presentation.root.RootComponent -import java.io.File -import java.io.FileOutputStream -import java.net.URLEncoder -import java.nio.charset.StandardCharsets -import kotlin.math.abs - -@Composable -fun ChatContent( - component: ChatComponent, - isOverlay: Boolean = false, - previousChild: RootComponent.Child? = null, - renderChild: @Composable (RootComponent.Child) -> Unit = {} -) { - val state by component.state.collectAsState() - val scrollState = rememberLazyListState() - val context = LocalContext.current - val clipboardManager = LocalClipboardManager.current - val keyboardController = LocalSoftwareKeyboardController.current - val focusManager = LocalFocusManager.current - val coroutineScope = rememberCoroutineScope() - - val adaptiveInfo = currentWindowAdaptiveInfo() - val isTablet = adaptiveInfo.windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.EXPANDED - - var isVisible by remember { mutableStateOf(false) } - var showInitialLoading by remember { mutableStateOf(false) } - var isRecordingVideo by remember { mutableStateOf(false) } - - // Menu States - var selectedMessageId by remember { mutableStateOf(null) } - val transformedMessageTexts = remember { mutableStateMapOf() } - val originalMessageTexts = remember { mutableStateMapOf() } - val latestMessagesState = rememberUpdatedState(state.messages) - val selectedMessageIdState = rememberUpdatedState(selectedMessageId) - val displayMessages by remember { - derivedStateOf { - val baseMessages = latestMessagesState.value - if (transformedMessageTexts.isEmpty()) { - baseMessages - } else { - baseMessages.map { message -> - val transformedText = transformedMessageTexts[message.id] ?: return@map message - message.withUpdatedTextContent(transformedText) - } - } - } - } - val selectedMessage by remember { - derivedStateOf { - val currentSelectedId = selectedMessageIdState.value - displayMessages.find { it.id == currentSelectedId } - } - } - var menuOffset by remember { mutableStateOf(Offset.Zero) } - var menuMessageSize by remember { mutableStateOf(IntSize.Zero) } - var clickOffset by remember { mutableStateOf(Offset.Zero) } - var contentRect by remember { mutableStateOf(Rect.Zero) } - - var pendingMediaPaths by remember { mutableStateOf>(emptyList()) } - var editingPhotoPath by remember { mutableStateOf(null) } - var editingVideoPath by remember { mutableStateOf(null) } - var pendingBlockUserId by remember { mutableStateOf(null) } - - val groupedMessages by remember { - derivedStateOf { groupMessagesByAlbum(displayMessages) } - } - val isComments = state.rootMessage != null - val isForumList = state.viewAsTopics && state.currentTopicId == null - var showScrollToBottomButton by remember { mutableStateOf(false) } - - val isAnyViewerOpen = state.fullScreenImages != null || - state.fullScreenVideoPath != null || - state.fullScreenVideoMessageId != null || - state.youtubeUrl != null || - state.instantViewUrl != null || - state.miniAppUrl != null || - state.webViewUrl != null || - editingPhotoPath != null || - editingVideoPath != null || - isRecordingVideo - - val scrollToMessageState = rememberUpdatedState(newValue = { msg: MessageModel -> - val index = groupedMessages.indexOfFirst { item -> - when (item) { - is GroupedMessageItem.Single -> item.message.id == msg.id - is GroupedMessageItem.Album -> item.messages.any { it.id == msg.id } - } - } - if (index != -1) { - coroutineScope.launch { - val targetIndex = if (isComments) { - if (state.rootMessage != null) index + 1 else index - } else index - - scrollState.scrollMessageToCenter( - index = targetIndex, - animated = state.isChatAnimationsEnabled - ) - } - } else { - component.onClearMessages() - component.onPinnedMessageClick(msg) - } - }) - - LaunchedEffect(Unit) { - isVisible = true - if (state.fullScreenVideoPath != null || state.fullScreenVideoMessageId != null) { - component.onDismissVideo() - } - } - - LaunchedEffect(state.messages) { - val ids = state.messages.map { it.id }.toSet() - transformedMessageTexts.keys.toList().forEach { id -> - if (id !in ids) { - transformedMessageTexts.remove(id) - originalMessageTexts.remove(id) - } - } - } - - // Initial Loading Delay logic - LaunchedEffect( - state.isLoading, - state.messages.isEmpty(), - state.viewAsTopics, - state.currentTopicId, - state.isLoadingTopics, - state.rootMessage - ) { - val isActuallyLoading = if (state.viewAsTopics && state.currentTopicId == null) { - state.isLoadingTopics && state.topics.isEmpty() - } else if (state.currentTopicId != null) { - state.isLoading && state.messages.isEmpty() && state.rootMessage == null - } else { - state.isLoading && state.messages.isEmpty() - } - if (isActuallyLoading) { - if (state.isChatAnimationsEnabled) delay(200) - showInitialLoading = true - } else { - showInitialLoading = false - } - } - - // Scroll to message when requested by component - LaunchedEffect(state.scrollToMessageId, groupedMessages) { - state.scrollToMessageId?.let { id -> - val index = groupedMessages.indexOfFirst { item -> - if (id == state.currentTopicId) { - false - } else { - when (item) { - is GroupedMessageItem.Single -> item.message.id == id - is GroupedMessageItem.Album -> item.messages.any { it.id == id } - } - } - } - if (index != -1) { - component.onScrollToMessageConsumed() - - val targetIndex = if (isComments) { - if (state.rootMessage != null) index + 1 else index - } else index - - scrollState.scrollMessageToCenter( - index = targetIndex, - animated = state.isChatAnimationsEnabled - ) - } - } - } - - // Unified bottom-status + bottom-button controller with hysteresis/debounce for smoothness. - LaunchedEffect( - scrollState, - isComments, - isForumList, - showInitialLoading, - state.unreadCount, - state.isLatestLoaded - ) { - snapshotFlow { - BottomVisibilitySnapshot( - isAtBottom = scrollState.isAtBottom( - isComments = isComments, - isLatestLoaded = state.isLatestLoaded - ), - isNearBottom = scrollState.isNearBottom( - isComments = isComments - ), - unreadCount = state.unreadCount - ) - } - .distinctUntilChanged() - .collectLatest { snapshot -> - component.onBottomReached(snapshot.isAtBottom) - - val shouldShow = !isForumList && - !showInitialLoading && - (snapshot.unreadCount > 0 || !snapshot.isNearBottom) - - if (shouldShow) { - showScrollToBottomButton = true - } else { - delay(120) - val keepVisible = state.unreadCount > 0 || !snapshot.isNearBottom - if (!keepVisible) { - showScrollToBottomButton = false - } - } - } - } - - // Save scroll position - LaunchedEffect(scrollState, groupedMessages, isComments, state.rootMessage, state.isLatestLoaded) { - snapshotFlow { scrollState.isScrollInProgress to scrollState.firstVisibleItemIndex } - .filter { !it.first } - .map { - val isAtBottom = scrollState.isAtBottom( - isComments = isComments, - isLatestLoaded = state.isLatestLoaded - ) - - if (isAtBottom && !isComments) { - 0L - } else { - val visibleItems = scrollState.layoutInfo.visibleItemsInfo - if (visibleItems.isNotEmpty()) { - val firstVisibleItem = if (isComments) { - visibleItems.firstOrNull { it.index > 0 } - } else { - visibleItems.firstOrNull { it.index >= 0 } - } - - if (firstVisibleItem != null) { - val groupedIndex = - if (state.rootMessage != null) firstVisibleItem.index - 1 else firstVisibleItem.index - groupedMessages.getOrNull(groupedIndex)?.firstMessageId - } else null - } else null - } - } - .distinctUntilChanged() - .collect { messageId -> - if (messageId != null) { - component.updateScrollPosition(messageId) - } - } - } - - // Performance: Update visible range for repository - LaunchedEffect(scrollState, groupedMessages, state.rootMessage) { - snapshotFlow { scrollState.layoutInfo.visibleItemsInfo } - .map { visibleItems -> - val visibleIds = mutableListOf() - val nearbyIds = mutableListOf() - if (visibleItems.isNotEmpty()) { - val minIndex = visibleItems.minOf { it.index } - val maxIndex = visibleItems.maxOf { it.index } - - visibleItems.forEach { item -> - val groupedIndex = if (state.rootMessage != null) item.index - 1 else item.index - groupedMessages.getOrNull(groupedIndex)?.let { grouped -> - when (grouped) { - is GroupedMessageItem.Single -> visibleIds.add(grouped.message.id) - is GroupedMessageItem.Album -> visibleIds.addAll(grouped.messages.map { it.id }) - } - } - } - - val nearbyStart = (minIndex - 5).coerceAtLeast(0) - val nearbyEnd = maxIndex + 5 - for (index in nearbyStart..nearbyEnd) { - if (index in minIndex..maxIndex) continue - val groupedIndex = if (state.rootMessage != null) index - 1 else index - groupedMessages.getOrNull(groupedIndex)?.let { grouped -> - when (grouped) { - is GroupedMessageItem.Single -> nearbyIds.add(grouped.message.id) - is GroupedMessageItem.Album -> nearbyIds.addAll(grouped.messages.map { it.id }) - } - } - } - } - visibleIds.distinct() to nearbyIds.distinct().filterNot { it in visibleIds } - } - .distinctUntilChanged() - .debounce(100) - .collect { (visibleIds, nearbyIds) -> - (component as? DefaultChatComponent)?.let { - it.repositoryMessage.updateVisibleRange(it.chatId, visibleIds, nearbyIds) - } - } - } - - // Auto-scroll to bottom when new messages arrive and we are already at the bottom - val messageCount = groupedMessages.size - LaunchedEffect(messageCount, state.isLatestLoaded) { - if (isComments) return@LaunchedEffect - - val isAtBottomNow = scrollState.isAtBottom( - isComments = isComments, - isLatestLoaded = state.isLatestLoaded - ) - if ((state.isAtBottom || isAtBottomNow) && - !state.isLoading && - !state.isLoadingOlder && - !state.isLoadingNewer && - !scrollState.isScrollInProgress - ) { - scrollState.scrollToChatBottom( - isComments = isComments, - animated = state.isChatAnimationsEnabled - ) - } - } - - // Scroll Management - val isDragged by scrollState.interactionSource.collectIsDraggedAsState() - LaunchedEffect(isDragged) { - if (isDragged) { - focusManager.clearFocus() - keyboardController?.hide() - } - } - - LaunchedEffect(state.showBotCommands, isRecordingVideo) { - if (state.showBotCommands || isRecordingVideo) { - focusManager.clearFocus(force = true) - keyboardController?.hide() - } - } - - // Pick Media Result - val pickMedia = rememberLauncherForActivityResult(ActivityResultContracts.PickMultipleVisualMedia()) { uris -> - val albumPaths = mutableListOf() - uris.forEach { uri -> - val mimeType = context.contentResolver.getType(uri) - val extension = when { - mimeType == "image/gif" -> "gif" - mimeType?.startsWith("video/") == true -> "mp4" - else -> "jpg" - } - val file = File(context.cacheDir, "temp_media_${System.nanoTime()}.$extension") - context.contentResolver.openInputStream(uri)?.use { input -> - FileOutputStream(file).use { output -> input.copyTo(output) } - } - if (extension == "gif") component.onSendGifFile(file.absolutePath) - else albumPaths.add(file.absolutePath) - } - if (albumPaths.isNotEmpty()) pendingMediaPaths = (pendingMediaPaths + albumPaths).distinct() - } - - - val contentAlpha by animateFloatAsState( - targetValue = if (isVisible || !state.isChatAnimationsEnabled || isOverlay) 1f else 0f, - animationSpec = if (state.isChatAnimationsEnabled && !isOverlay) tween(300) else snap(), - label = "ContentAlpha" - ) - val contentOffset by animateDpAsState( - targetValue = if (isVisible || !state.isChatAnimationsEnabled || isOverlay) 0.dp else 20.dp, - animationSpec = if (state.isChatAnimationsEnabled && !isOverlay) tween(300) else snap(), - label = "ContentOffset" - ) - - val showInputBar = (state.isMember || !state.isChannel && !state.isGroup) && - (state.canWrite || state.currentTopicId != null) && - !isRecordingVideo && - state.selectedMessageIds.isEmpty() && - (!state.viewAsTopics || state.currentTopicId != null) - - val isDragToBackEnabled by component.appPreferences.isDragToBackEnabled.collectAsState() - val dragOffsetX = remember { Animatable(0f) } - var containerSize by remember { mutableStateOf(IntSize.Zero) } - - val isCustomBackHandlingEnabled = - (editingPhotoPath != null || editingVideoPath != null || selectedMessageId != null || state.selectedMessageIds.isNotEmpty() || state.currentTopicId != null || state.showBotCommands || state.restrictUserId != null || state.fullScreenImages != null || state.fullScreenVideoPath != null || state.fullScreenVideoMessageId != null || state.miniAppUrl != null || state.webViewUrl != null || state.instantViewUrl != null || state.youtubeUrl != null) - - CompositionLocalProvider(LocalLinkHandler provides { component.onLinkClick(it) }) { - Box( - modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.background) - .onGloballyPositioned { containerSize = it.size } - ) { - if (isDragToBackEnabled && !isTablet && !isCustomBackHandlingEnabled && dragOffsetX.value > 0 && previousChild != null) { - Box( - modifier = Modifier.fillMaxSize() - ) { - renderChild(previousChild) - Box( - modifier = Modifier - .fillMaxSize() - .background( - Color.Black.copy( - alpha = 0.3f * (1f - (dragOffsetX.value / containerSize.width.toFloat()).coerceIn( - 0f, - 1f - )) - ) - ) - ) - } - } - - Box( - modifier = Modifier - .fillMaxSize() - .then( - if (isDragToBackEnabled && !isTablet && !isCustomBackHandlingEnabled) { - Modifier.pointerInput(Unit) { - var isDragging = false - detectHorizontalDragGestures( - onDragStart = { offset -> - isDragging = offset.x > 48.dp.toPx() - }, - onHorizontalDrag = { change, dragAmount -> - if (isDragging) { - change.consume() - coroutineScope.launch { - val newOffset = dragOffsetX.value + dragAmount - dragOffsetX.snapTo(newOffset.coerceAtLeast(0f)) - } - } - }, - onDragEnd = { - if (isDragging) { - val width = containerSize.width.toFloat() - coroutineScope.launch { - if (dragOffsetX.value > width * 0.15f) { - dragOffsetX.animateTo(width, tween(200)) - component.onBackClicked() - } else { - dragOffsetX.animateTo(0f, spring()) - } - } - isDragging = false - } - }, - onDragCancel = { - if (isDragging) { - coroutineScope.launch { dragOffsetX.animateTo(0f) } - isDragging = false - } - } - ) - } - } else Modifier - ) - .graphicsLayer { - translationX = dragOffsetX.value - shadowElevation = if (dragOffsetX.value > 0) 20f else 0f - } - ) { - Box( - modifier = Modifier - .fillMaxSize() - .graphicsLayer { - alpha = contentAlpha - translationY = contentOffset.toPx() - } - ) { - ChatContentBackground(state = state) - } - - Scaffold( - modifier = Modifier - .fillMaxSize() - .graphicsLayer { alpha = contentAlpha; translationY = contentOffset.toPx() } - .semantics { contentDescription = "ChatContent" }, - containerColor = Color.Transparent, - topBar = { - ChatContentTopBar( - state = state, - component = component, - contentAlpha = contentAlpha, - onBack = { keyboardController?.hide(); component.onBackClicked() }, - onOpenMenu = { - keyboardController?.hide() - focusManager.clearFocus(force = true) - }, - onPinnedMessageClick = { msg -> scrollToMessageState.value(msg) }, - showBack = !isTablet - ) - }, - bottomBar = { - if (showInputBar) { - val inputBarState = remember(state, pendingMediaPaths) { - ChatInputBarState( - replyMessage = state.replyMessage, - editingMessage = state.editingMessage, - draftText = state.draftText, - pendingMediaPaths = pendingMediaPaths, - isClosed = state.topics.find { it.id.toLong() == state.currentTopicId }?.isClosed - ?: false, - permissions = state.permissions, - isAdmin = state.isAdmin, - isChannel = state.isChannel, - isBot = state.isBot, - botCommands = state.botCommands, - botMenuButton = state.botMenuButton, - replyMarkup = state.messages.firstOrNull { it.replyMarkup is ReplyMarkupModel.ShowKeyboard }?.replyMarkup, - mentionSuggestions = state.mentionSuggestions, - inlineBotResults = state.inlineBotResults, - currentInlineBotUsername = state.currentInlineBotUsername, - currentInlineQuery = state.currentInlineQuery, - isInlineBotLoading = state.isInlineBotLoading, - attachBots = state.attachMenuBots, - scheduledMessages = state.scheduledMessages, - isPremiumUser = state.currentUser?.isPremium == true - ) - } - - val inputBarActions = remember(component, pendingMediaPaths) { - ChatInputBarActions( - onSend = { text, entities, options -> - component.onSendMessage( - text, - entities, - options - ) - }, - onStickerClick = { component.onSendSticker(it) }, - onGifClick = { component.onSendGif(it) }, - onAttachClick = { - pickMedia.launch( - PickVisualMediaRequest( - ActivityResultContracts.PickVisualMedia.ImageAndVideo - ) - ) - }, - onCameraClick = { - keyboardController?.hide() - focusManager.clearFocus(force = true) - isRecordingVideo = true - }, - onSendVoice = { path, duration, waveform -> - component.onSendVoice(path, duration, waveform) - }, - onCancelReply = { component.onCancelReply() }, - onCancelEdit = { component.onCancelEdit() }, - onSaveEdit = { t, e -> component.onSaveEditedMessage(t, e) }, - onDraftChange = { component.onDraftChange(it) }, - onTyping = { component.onTyping() }, - onCancelMedia = { pendingMediaPaths = emptyList() }, - onSendMedia = { paths, caption, captionEntities, options -> - if (paths.size > 1) component.onSendAlbum( - paths, - caption, - captionEntities, - options - ) - else paths.firstOrNull()?.let { - if (it.endsWith(".mp4")) component.onSendVideo( - it, - caption, - captionEntities, - options - ) - else component.onSendPhoto(it, caption, captionEntities, options) - } - pendingMediaPaths = emptyList() - }, - onMediaOrderChange = { pendingMediaPaths = it }, - onMediaClick = { path -> - if (path.endsWith(".mp4")) { - editingVideoPath = path - } else { - editingPhotoPath = path - } - }, - onShowBotCommands = { - keyboardController?.hide() - focusManager.clearFocus(force = true) - component.onShowBotCommands() - }, - onReplyMarkupButtonClick = { - component.onReplyMarkupButtonClick( - 0, - it, - if (state.isBot) state.chatId else 0L - ) - }, - onOpenMiniApp = { url, name -> - component.onOpenMiniApp( - url, - name, - if (state.isBot) state.chatId else 0L - ) - }, - onMentionQueryChange = { component.onMentionQueryChange(it) }, - onInlineQueryChange = { bot, query -> - component.onInlineQueryChange(bot, query) - }, - onLoadMoreInlineResults = { offset -> - component.onLoadMoreInlineResults(offset) - }, - onSendInlineResult = { resultId -> component.onSendInlineResult(resultId) }, - onInlineSwitchPm = { botUsername, parameter -> - val encodedParameter = URLEncoder.encode( - parameter, - StandardCharsets.UTF_8.name() - ) - component.onLinkClick("https://t.me/$botUsername?start=$encodedParameter") - }, - onAttachBotClick = { bot -> - component.onOpenAttachBot(bot.botUserId, bot.name) - }, - onRefreshScheduledMessages = { component.onRefreshScheduledMessages() }, - onEditScheduledMessage = { message -> component.onEditMessage(message) }, - onDeleteScheduledMessage = { message -> component.onDeleteMessage(message) }, - onSendScheduledNow = { message -> component.onSendScheduledNow(message) } - ) - } - - ChatInputBar( - state = inputBarState, - actions = inputBarActions, - appPreferences = component.appPreferences, - videoPlayerPool = component.videoPlayerPool, - stickerRepository = component.stickerRepository - ) - } else if (!state.isMember && (state.isChannel || state.isGroup)) { - Surface( - modifier = Modifier - .fillMaxWidth() - .clickable { component.onJoinChat() }, - color = MaterialTheme.colorScheme.surface, - tonalElevation = 2.dp - ) { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp) - .windowInsetsPadding(WindowInsets.navigationBars), - contentAlignment = Alignment.Center - ) { - Text( - text = stringResource(R.string.action_join), - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) - } - } - } - } - ) { padding -> - Box( - modifier = Modifier - .fillMaxSize() - .padding(padding) - .consumeWindowInsets(padding) - .onGloballyPositioned { coordinates -> - contentRect = Rect( - offset = coordinates.positionInWindow(), - size = coordinates.size.toSize() - ) - } - ) { - Box( - modifier = Modifier - .fillMaxSize() - .graphicsLayer { - alpha = contentAlpha - translationY = contentOffset.toPx() - } - ) { - ChatContentList( - showNavPadding = false, - state = state, - component = component, - scrollState = scrollState, - groupedMessages = groupedMessages, - onPhotoDownload = { fileId -> if (fileId != 0) component.onDownloadFile(fileId) }, - onPhotoClick = { msg, paths, captions, messageIds, index -> - val content = msg.content as? MessageContent.Photo - val clickedPath = paths.getOrNull(index) - ?.takeIf { it.isNotBlank() && File(it).exists() } - ?: content?.path?.takeIf { File(it).exists() } - - if (clickedPath != null) { - keyboardController?.hide() - focusManager.clearFocus() - - val validItems = paths.mapIndexedNotNull { itemIndex, path -> - val validPath = path.takeIf { it.isNotBlank() && File(it).exists() } - ?: return@mapIndexedNotNull null - Triple(itemIndex, validPath, captions.getOrNull(itemIndex)) - } - - if (validItems.isNotEmpty()) { - val validPaths = validItems.map { it.second } - val validCaptions = validItems.map { it.third } - val validMessageIds = validItems.map { (itemIndex, _, _) -> - messageIds.getOrNull(itemIndex) ?: msg.id - } - val startIndex = validItems.indexOfFirst { (itemIndex, _, _) -> itemIndex == index } - .takeIf { it >= 0 } - ?: validPaths.indexOf(clickedPath).takeIf { it >= 0 } - ?: 0 - - component.onOpenImages( - images = validPaths, - captions = validCaptions, - startIndex = startIndex, - messageId = msg.id, - messageIds = validMessageIds - ) - } - } else { - content?.fileId?.takeIf { it != 0 }?.let(component::onDownloadFile) - } - }, - onVideoClick = { msg, path, caption -> - if (!isVisible || showInitialLoading || scrollState.isScrollInProgress) { - return@ChatContentList - } - - val videoContent = msg.content as? MessageContent.Video - val supportsStreaming = videoContent?.supportsStreaming ?: false - val validPath = path?.takeIf { File(it).exists() } - - if (validPath != null || supportsStreaming) { - keyboardController?.hide() - focusManager.clearFocus() - component.onOpenVideo(path = validPath, messageId = msg.id, caption = caption) - } else { - val fileId = when (val c = msg.content) { - is MessageContent.Video -> c.fileId - is MessageContent.Gif -> c.fileId - else -> 0 - } - if (fileId != 0) { - when (msg.content) { - is MessageContent.Video -> "video" - is MessageContent.Gif -> "gif" - else -> "unknown" - } - component.onDownloadFile(fileId) - } - } - }, - onDocumentClick = { msg -> - val doc = msg.content as? MessageContent.Document ?: return@ChatContentList - val validDocPath = doc.path?.takeIf { File(it).exists() } - if (validDocPath != null) { - val path = validDocPath.lowercase() - if (path.endsWith(".jpg") || path.endsWith(".png")) { - keyboardController?.hide() - focusManager.clearFocus() - component.onOpenImages( - images = listOf(validDocPath), - captions = listOf(doc.caption), - startIndex = 0, - messageId = msg.id, - messageIds = listOf(msg.id) - ) - } else if (path.endsWith(".mp4")) { - keyboardController?.hide() - focusManager.clearFocus() - component.onOpenVideo( - path = validDocPath, - messageId = msg.id, - caption = doc.caption - ) - } else component.downloadUtils.openFile(validDocPath) - } else component.onDownloadFile(doc.fileId) - }, - onAudioClick = { msg -> - val audio = msg.content as? MessageContent.Audio ?: return@ChatContentList - val validAudioPath = audio.path?.takeIf { File(it).exists() } - if (validAudioPath != null) { - keyboardController?.hide() - focusManager.clearFocus() - component.onOpenVideo( - path = validAudioPath, - messageId = msg.id, - caption = audio.caption - ) - } else component.onDownloadFile(audio.fileId) - }, - onMessageOptionsClick = { msg, pos, size, clickPos -> - keyboardController?.hide() - focusManager.clearFocus(force = true) - selectedMessageId = msg.id - menuOffset = pos; menuMessageSize = size; clickOffset = clickPos - }, - onGoToReply = { scrollToMessageState.value(it) }, - selectedMessageId = selectedMessageId, - onMessagePositionChange = { pos, size -> - menuOffset = pos - menuMessageSize = size - }, - onViaBotClick = { botUsername -> - val prefill = "@$botUsername " - component.onDraftChange(prefill) - component.onInlineQueryChange("", "") - }, - toProfile = { - it.let { component.toProfile(it) } - }, - downloadUtils = component.downloadUtils, - videoPlayerPool = component.videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - - AnimatedVisibility( - visible = showScrollToBottomButton, - enter = slideInVertically(initialOffsetY = { it / 2 }) + fadeIn(), - exit = slideOutVertically(targetOffsetY = { it / 2 }) + fadeOut(), - modifier = Modifier - .align(Alignment.BottomEnd) - .padding(16.dp) - ) { - Box { - FloatingActionButton( - onClick = { - if (!state.isLatestLoaded) { - component.onScrollToBottom() - } else { - coroutineScope.launch { - scrollState.scrollToChatBottom( - isComments = isComments, - animated = state.isChatAnimationsEnabled - ) - } - } - }, - containerColor = MaterialTheme.colorScheme.primaryContainer, - shape = CircleShape, - modifier = Modifier.size(48.dp) - ) { - Icon( - Icons.Default.KeyboardArrowDown, - contentDescription = stringResource(R.string.cd_scroll_to_bottom), - modifier = Modifier.size(24.dp) - ) - } - - AnimatedVisibility( - visible = state.unreadCount > 0, - enter = scaleIn() + fadeIn(), - exit = scaleOut() + fadeOut(), - modifier = Modifier - .align(Alignment.TopCenter) - .offset(y = (-8).dp) - ) { - Surface( - color = MaterialTheme.colorScheme.primary, - shape = CircleShape, - shadowElevation = 4.dp - ) { - AnimatedContent( - targetState = state.unreadCount, - transitionSpec = { - if (targetState > initialState) { - (slideInVertically { height -> height } + fadeIn()).togetherWith( - slideOutVertically { height -> -height } + fadeOut()) - } else { - (slideInVertically { height -> -height } + fadeIn()).togetherWith( - slideOutVertically { height -> height } + fadeOut()) - }.using( - SizeTransform(clip = false) - ) - }, - label = "UnreadCountAnimation" - ) { count -> - Text( - text = if (count > 999) "999+" else count.toString(), - modifier = Modifier.padding(horizontal = 6.dp, vertical = 2.dp), - style = MaterialTheme.typography.labelSmall.copy( - fontWeight = FontWeight.Bold, - fontSize = 10.sp - ), - color = MaterialTheme.colorScheme.onPrimary - ) - } - } - } - } - } - - if (isRecordingVideo) { - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.Black) - .zIndex(10f) - ) { - AdvancedCircularRecorderScreen( - onClose = { isRecordingVideo = false }, - onVideoRecorded = { file -> - isRecordingVideo = false - component.onVideoRecorded(file) - } - ) - } - } - - AnimatedVisibility( - visible = showInitialLoading, - enter = fadeIn(), - exit = fadeOut(animationSpec = tween(400)) - ) { - Box( - modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.surface) - ) { - MessageListShimmer( - isGroup = state.isGroup, - isChannel = state.isChannel - ) - } - } - } - } - } - } - - - // Modals & Overlays - if (state.showPinnedMessagesList) { - PinnedMessagesListSheet( - state = state, - onDismiss = { component.onDismissPinnedMessages() }, - onMessageClick = { scrollToMessageState.value(it); component.onDismissPinnedMessages() }, - onUnpin = { component.onUnpinMessage(it) }, - onReplyClick = { scrollToMessageState.value(it); component.onDismissPinnedMessages() }, - onReactionClick = { id, r -> component.onSendReaction(id, r) }, - downloadUtils = component.downloadUtils, - videoPlayerPool = component.videoPlayerPool - ) - } - - state.selectedStickerSet?.let { stickerSet -> - StickerSetSheet( - stickerSet = stickerSet, - onDismiss = { component.onDismissStickerSet() }, - onStickerClick = { component.onSendSticker(it) } - ) - } - - if (state.showPollVoters) { - PollVotersSheet( - voters = state.pollVoters, - isLoading = state.isPollVotersLoading, - onUserClick = { - component.onDismissVoters() - component.toProfile(it) - }, - onDismiss = { component.onDismissVoters() }, - videoPlayerPool = component.videoPlayerPool - ) - } - - if (state.showBotCommands) { - BotCommandsSheet( - commands = state.botCommands, - onCommandClick = { component.onBotCommandClick(it) }, - onDismiss = { component.onDismissBotCommands() } - ) - } - - ChatContentViewers( - state = state, - component = component, - clipboardManager = clipboardManager - ) - - selectedMessage?.let { msg -> - ChatMessageOptionsMenu( - state = state, - component = component, - selectedMessage = msg, - menuOffset = menuOffset, - menuMessageSize = menuMessageSize, - clickOffset = clickOffset, - contentRect = contentRect, - groupedMessages = groupedMessages, - downloadUtils = component.downloadUtils, - clipboardManager = clipboardManager, - canRestoreOriginalText = originalMessageTexts.containsKey(msg.id), - onApplyTransformedText = { newText -> - val originalText = msg.extractTextContent() - if (!originalText.isNullOrBlank() && !originalMessageTexts.containsKey(msg.id)) { - originalMessageTexts[msg.id] = originalText - } - transformedMessageTexts[msg.id] = newText - }, - onRestoreOriginalText = { - val originalText = originalMessageTexts[msg.id] ?: return@ChatMessageOptionsMenu - transformedMessageTexts[msg.id] = originalText - originalMessageTexts.remove(msg.id) - }, - onBlockRequest = { userId -> - pendingBlockUserId = userId - }, - onDismiss = { selectedMessageId = null } - ) - } - - pendingBlockUserId?.let { userId -> - ConfirmationSheet( - icon = Icons.Rounded.Block, - title = stringResource(R.string.block_user_title), - description = stringResource(R.string.block_user_confirmation), - confirmText = stringResource(R.string.action_block), - onConfirm = { - component.onBlockUser(userId) - pendingBlockUserId = null - }, - onDismiss = { pendingBlockUserId = null } - ) - } - - if (state.showReportDialog) { - ReportChatDialog( - onDismiss = { component.onDismissReportDialog() }, - onReasonSelected = { component.onReportReasonSelected(it) } - ) - } - - if (state.restrictUserId != null) { - RestrictUserSheet( - onDismiss = { component.onDismissRestrictDialog() }, - onConfirm = { permissions, untilDate -> component.onConfirmRestrict(permissions, untilDate) } - ) - } - - editingPhotoPath?.let { path -> - Box( - modifier = Modifier - .fillMaxSize() - .zIndex(20f) - ) { - PhotoEditorScreen( - imagePath = path, - onClose = { editingPhotoPath = null }, - onSave = { newPath -> - val newList = pendingMediaPaths.toMutableList() - val index = newList.indexOf(path) - if (index != -1) { - newList[index] = newPath - pendingMediaPaths = newList - } - editingPhotoPath = null - } - ) - } - } - - editingVideoPath?.let { path -> - Box( - modifier = Modifier - .fillMaxSize() - .zIndex(20f) - ) { - VideoEditorScreen( - videoPath = path, - onClose = { editingVideoPath = null }, - onSave = { newPath -> - val newList = pendingMediaPaths.toMutableList() - val index = newList.indexOf(path) - if (index != -1) { - newList[index] = newPath - pendingMediaPaths = newList - } - editingVideoPath = null - } - ) - } - } - - BackHandler(enabled = isCustomBackHandlingEnabled) { - if (editingPhotoPath != null) editingPhotoPath = null - else if (editingVideoPath != null) editingVideoPath = null - else if (state.selectedMessageIds.isNotEmpty()) component.onClearSelection() - else if (selectedMessageId != null) selectedMessageId = null - else if (state.showBotCommands) component.onDismissBotCommands() - else if (state.restrictUserId != null) component.onDismissRestrictDialog() - else if (state.fullScreenImages != null) component.onDismissImages() - else if (state.fullScreenVideoPath != null || state.fullScreenVideoMessageId != null) component.onDismissVideo() - else if (state.instantViewUrl != null) component.onDismissInstantView() - else if (state.youtubeUrl != null) component.onDismissYouTube() - else if (state.miniAppUrl != null) component.onDismissMiniApp() - else if (state.webViewUrl != null) component.onDismissWebView() - else if (state.currentTopicId != null) component.onBackClicked() - } - } - } -} - -private fun MessageModel.extractTextContent(): String? { - return when (val c = content) { - is MessageContent.Text -> c.text - is MessageContent.Photo -> c.caption - is MessageContent.Video -> c.caption - is MessageContent.Gif -> c.caption - is MessageContent.Document -> c.caption - is MessageContent.Audio -> c.caption - else -> null - } -} - -private fun MessageModel.withUpdatedTextContent(newText: String): MessageModel { - val updatedContent = when (val c = content) { - is MessageContent.Text -> c.copy(text = newText, entities = emptyList(), webPage = null) - is MessageContent.Photo -> c.copy(caption = newText, entities = emptyList()) - is MessageContent.Video -> c.copy(caption = newText, entities = emptyList()) - is MessageContent.Gif -> c.copy(caption = newText, entities = emptyList()) - is MessageContent.Document -> c.copy(caption = newText, entities = emptyList()) - is MessageContent.Audio -> c.copy(caption = newText, entities = emptyList()) - else -> return this - } - return copy(content = updatedContent) -} - -private suspend fun LazyListState.scrollMessageToCenter( - index: Int, - animated: Boolean -) { - if (animated) animateScrollToItem(index) else scrollToItem(index) - - val itemInfo = layoutInfo.visibleItemsInfo.firstOrNull { it.index == index } ?: return - val viewportCenter = (layoutInfo.viewportStartOffset + layoutInfo.viewportEndOffset) / 2 - val itemCenter = itemInfo.offset + (itemInfo.size / 2) - val delta = (itemCenter - viewportCenter).toFloat() - - if (abs(delta) > 1f) { - if (animated) { - animateScrollBy(delta) - } else { - scrollBy(delta) - } - } -} - -private data class BottomVisibilitySnapshot( - val isAtBottom: Boolean, - val isNearBottom: Boolean, - val unreadCount: Int -) - -private fun LazyListState.isAtBottom( - isComments: Boolean, - isLatestLoaded: Boolean -): Boolean { - if (!isLatestLoaded) return false - - val info = layoutInfo - val visible = info.visibleItemsInfo - if (visible.isEmpty()) return true - - return if (isComments) { - val lastVisible = visible.last() - lastVisible.index >= info.totalItemsCount - 1 && - abs((info.viewportEndOffset - (lastVisible.offset + lastVisible.size)).toFloat()) <= 40f - } else { - val firstVisible = visible.first() - firstVisible.index == 0 && - abs((firstVisible.offset - info.viewportStartOffset).toFloat()) <= 40f - } -} - -private fun LazyListState.isNearBottom(isComments: Boolean): Boolean { - val info = layoutInfo - val visible = info.visibleItemsInfo - if (visible.isEmpty()) return true - - return if (isComments) { - val lastVisible = visible.last() - val distance = abs((info.viewportEndOffset - (lastVisible.offset + lastVisible.size)).toFloat()) - lastVisible.index >= info.totalItemsCount - 2 && distance <= 240f - } else { - val firstVisible = visible.first() - val distance = abs((firstVisible.offset - info.viewportStartOffset).toFloat()) - firstVisible.index <= 1 && distance <= 240f - } -} - -private suspend fun LazyListState.scrollToChatBottom( - isComments: Boolean, - animated: Boolean -) { - val targetIndex = if (isComments) { - val total = layoutInfo.totalItemsCount - if (total > 0) total - 1 else 0 - } else { - 0 - } - - if (animated) { - animateScrollToItem(targetIndex) - } else { - scrollToItem(targetIndex) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/ChatStore.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/ChatStore.kt deleted file mode 100644 index 40b83108..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/ChatStore.kt +++ /dev/null @@ -1,169 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat - -import androidx.compose.ui.platform.ClipboardManager -import com.arkivanov.mvikotlin.core.store.Store -import org.monogram.domain.models.* -import java.io.File - -interface ChatStore : Store { - - sealed class Intent { - data class UpdateState(val state: ChatComponent.State) : Intent() - data class SendMessage( - val text: String, - val entities: List = emptyList(), - val sendOptions: MessageSendOptions = MessageSendOptions() - ) : Intent() - - data class SendSticker(val stickerPath: String) : Intent() - data class SendPhoto( - val photoPath: String, - val caption: String = "", - val captionEntities: List = emptyList(), - val sendOptions: MessageSendOptions = MessageSendOptions() - ) : Intent() - - data class SendVideo( - val videoPath: String, - val caption: String = "", - val captionEntities: List = emptyList(), - val sendOptions: MessageSendOptions = MessageSendOptions() - ) : Intent() - - data class SendGif(val gif: GifModel) : Intent() - data class SendGifFile( - val path: String, - val caption: String = "", - val captionEntities: List = emptyList(), - val sendOptions: MessageSendOptions = MessageSendOptions() - ) : Intent() - - data class SendAlbum( - val paths: List, - val caption: String = "", - val captionEntities: List = emptyList(), - val sendOptions: MessageSendOptions = MessageSendOptions() - ) : Intent() - - data class SendVoice(val path: String, val duration: Int, val waveform: ByteArray) : Intent() - object RefreshScheduledMessages : Intent() - data class SendScheduledNow(val message: MessageModel) : Intent() - object LoadMore : Intent() - object LoadNewer : Intent() - object BackClicked : Intent() - object ProfileClicked : Intent() - data class MessageClicked(val id: Long) : Intent() - data class MessageVisible(val messageId: Long) : Intent() - data class ReplyMessage(val message: MessageModel) : Intent() - object CancelReply : Intent() - data class VideoRecorded(val file: File) : Intent() - data class ForwardMessage(val message: MessageModel) : Intent() - object ForwardSelectedMessages : Intent() - data class DeleteMessage(val message: MessageModel, val revoke: Boolean = false) : Intent() - data class EditMessage(val message: MessageModel) : Intent() - object CancelEdit : Intent() - data class SaveEditedMessage(val text: String, val entities: List = emptyList()) : Intent() - data class DraftChange(val text: String) : Intent() - data class PinMessage(val message: MessageModel) : Intent() - data class UnpinMessage(val message: MessageModel) : Intent() - data class PinnedMessageClick(val message: MessageModel? = null) : Intent() - object ShowAllPinnedMessages : Intent() - object DismissPinnedMessages : Intent() - object ScrollToMessageConsumed : Intent() - object ScrollToBottom : Intent() - data class DownloadFile(val fileId: Int) : Intent() - data class DownloadHighRes(val messageId: Long) : Intent() - data class CancelDownloadFile(val fileId: Int) : Intent() - data class UpdateScrollPosition(val messageId: Long) : Intent() - data class BottomReached(val isAtBottom: Boolean) : Intent() - object HighlightConsumed : Intent() - object Typing : Intent() - data class SendReaction(val messageId: Long, val reaction: String) : Intent() - data class ToggleMessageSelection(val messageId: Long) : Intent() - object ClearSelection : Intent() - object ClearMessages : Intent() - data class DeleteSelectedMessages(val revoke: Boolean = false) : Intent() - data class CopySelectedMessages(val clipboardManager: ClipboardManager) : Intent() - data class StickerClick(val setId: Long) : Intent() - object DismissStickerSet : Intent() - data class AddToGifs(val path: String) : Intent() - data class PollOptionClick(val messageId: Long, val optionId: Int) : Intent() - data class RetractVote(val messageId: Long) : Intent() - data class ShowVoters(val messageId: Long, val optionId: Int) : Intent() - object DismissVoters : Intent() - data class ClosePoll(val messageId: Long) : Intent() - data class TopicClick(val topicId: Int) : Intent() - data class OpenInstantView(val url: String) : Intent() - object DismissInstantView : Intent() - data class OpenYouTube(val url: String) : Intent() - object DismissYouTube : Intent() - data class OpenMiniApp(val url: String, val name: String, val botUserId: Long = 0L) : Intent() - object DismissMiniApp : Intent() - object AcceptMiniAppTOS : Intent() - object DismissMiniAppTOS : Intent() - data class OpenWebView(val url: String) : Intent() - object DismissWebView : Intent() - data class OpenImages( - val images: List, - val captions: List, - val startIndex: Int, - val messageId: Long? = null, - val messageIds: List = emptyList() - ) : Intent() - - object DismissImages : Intent() - data class OpenVideo(val path: String? = null, val messageId: Long? = null, val caption: String? = null) : - Intent() - - object DismissVideo : Intent() - object AddToAdBlockWhitelist : Intent() - object RemoveFromAdBlockWhitelist : Intent() - object ToggleMute : Intent() - object SearchToggle : Intent() - data class SearchQueryChange(val query: String) : Intent() - object ClearHistory : Intent() - object DeleteChat : Intent() - object Report : Intent() - data class ReportMessage(val message: MessageModel) : Intent() - data class ReportReasonSelected(val reason: String) : Intent() - object DismissReportDialog : Intent() - data class CopyLink(val clipboardManager: ClipboardManager) : Intent() - data class ScrollToMessage(val messageId: Long) : Intent() - data class BotCommandClick(val command: String) : Intent() - object ShowBotCommands : Intent() - object DismissBotCommands : Intent() - data class CommentsClick(val messageId: Long) : Intent() - data class ReplyMarkupButtonClick( - val messageId: Long, - val button: InlineKeyboardButtonModel, - val botUserId: Long - ) : Intent() - - data class KeyboardButtonClick( - val messageId: Long, - val button: KeyboardButtonModel, - val botUserId: Long - ) : Intent() - - data class LinkClick(val url: String) : Intent() - data class OpenInvoice(val slug: String? = null, val messageId: Long? = null) : Intent() - data class DismissInvoice(val status: String) : Intent() - data class MentionQueryChange(val query: String?) : Intent() - object JoinChat : Intent() - data class BlockUser(val userId: Long) : Intent() - data class UnblockUser(val userId: Long) : Intent() - data class RestrictUser(val userId: Long, val permissions: ChatPermissionsModel) : Intent() - data class ConfirmRestrict(val permissions: ChatPermissionsModel, val untilDate: Int) : Intent() - object DismissRestrictDialog : Intent() - data class InlineQueryChange(val botUsername: String, val query: String) : Intent() - data class LoadMoreInlineResults(val offset: String) : Intent() - data class SendInlineResult(val resultId: String) : Intent() - } - - sealed class Label { - object Back : Label() - data class Profile(val id: Long) : Label() - data class Forward(val chatId: Long, val messageIds: List) : Label() - data class Link(val url: String) : Label() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/ChatStoreFactory.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/ChatStoreFactory.kt deleted file mode 100644 index bc487486..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/ChatStoreFactory.kt +++ /dev/null @@ -1,270 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat - -import com.arkivanov.mvikotlin.core.store.Reducer -import com.arkivanov.mvikotlin.core.store.Store -import com.arkivanov.mvikotlin.core.store.StoreFactory -import com.arkivanov.mvikotlin.extensions.coroutines.CoroutineExecutor -import kotlinx.coroutines.flow.update -import org.monogram.presentation.features.chats.currentChat.ChatStore.Intent -import org.monogram.presentation.features.chats.currentChat.ChatStore.Label -import org.monogram.presentation.features.chats.currentChat.impl.* - -class ChatStoreFactory( - private val storeFactory: StoreFactory, - private val component: DefaultChatComponent -) { - - fun create(): ChatStore = - object : ChatStore, Store by storeFactory.create( - name = "ChatStore", - initialState = component._state.value, - executorFactory = ::ExecutorImpl, - reducer = ReducerImpl - ) {} - - private inner class ExecutorImpl : CoroutineExecutor() { - override fun executeIntent(intent: Intent) { - when (intent) { - is Intent.UpdateState -> dispatch(Message.UpdateState(intent.state)) - is Intent.SendMessage -> component.handleSendMessage(intent.text, intent.entities, intent.sendOptions) - is Intent.SendSticker -> component.handleSendSticker(intent.stickerPath) - is Intent.SendPhoto -> component.handleSendPhoto( - photoPath = intent.photoPath, - caption = intent.caption, - captionEntities = intent.captionEntities, - sendOptions = intent.sendOptions - ) - - is Intent.SendVideo -> component.handleSendVideo( - videoPath = intent.videoPath, - caption = intent.caption, - captionEntities = intent.captionEntities, - sendOptions = intent.sendOptions - ) - - is Intent.SendGif -> component.handleSendGif(intent.gif) - is Intent.SendGifFile -> component.handleSendGifFile( - path = intent.path, - caption = intent.caption, - captionEntities = intent.captionEntities, - sendOptions = intent.sendOptions - ) - - is Intent.SendAlbum -> component.handleSendAlbum( - paths = intent.paths, - caption = intent.caption, - captionEntities = intent.captionEntities, - sendOptions = intent.sendOptions - ) - - is Intent.SendVoice -> component.handleSendVoice(intent.path, intent.duration, intent.waveform) - is Intent.RefreshScheduledMessages -> component.loadScheduledMessages() - is Intent.SendScheduledNow -> component.handleSendScheduledNow(intent.message) - is Intent.LoadMore -> component.loadMoreMessages() - is Intent.LoadNewer -> component.loadNewerMessages() - is Intent.BackClicked -> publish(Label.Back) - is Intent.ProfileClicked -> component.chatId.let { publish(Label.Profile(it)) } - is Intent.MessageClicked -> { /* Handle message click if needed */ - } - - is Intent.MessageVisible -> component.handleMessageVisible(intent.messageId) - is Intent.ReplyMessage -> component._state.update { - it.copy( - replyMessage = intent.message, - editingMessage = null - ) - } - - is Intent.CancelReply -> component._state.update { it.copy(replyMessage = null) } - is Intent.VideoRecorded -> component.handleVideoRecorded(intent.file) - is Intent.ForwardMessage -> publish(Label.Forward(component.chatId, listOf(intent.message.id))) - is Intent.ForwardSelectedMessages -> { - val selectedIds = component._state.value.selectedMessageIds.toList() - if (selectedIds.isNotEmpty()) { - publish(Label.Forward(component.chatId, selectedIds)) - component.handleClearSelection() - } - } - - is Intent.DeleteMessage -> component.handleDeleteMessage(intent.message, intent.revoke) - is Intent.EditMessage -> component._state.update { - it.copy( - editingMessage = intent.message, - replyMessage = null, - draftText = "" - ) - } - - is Intent.CancelEdit -> component._state.update { it.copy(editingMessage = null) } - is Intent.SaveEditedMessage -> component.handleSaveEditedMessage(intent.text, intent.entities) - is Intent.DraftChange -> component.handleDraftChange(intent.text) - is Intent.PinMessage -> component.handlePinMessage(intent.message) - - is Intent.UnpinMessage -> component.handleUnpinMessage(intent.message) - - is Intent.PinnedMessageClick -> component.handlePinnedMessageClick(intent.message) - is Intent.ShowAllPinnedMessages -> { - component._state.update { it.copy(showPinnedMessagesList = true) } - component.loadAllPinnedMessages() - } - is Intent.DismissPinnedMessages -> component._state.update { it.copy(showPinnedMessagesList = false) } - is Intent.ScrollToMessageConsumed -> component._state.update { it.copy(scrollToMessageId = null) } - is Intent.ScrollToBottom -> component.scrollToBottomInternal() - is Intent.DownloadFile -> component.handleDownloadFile(intent.fileId) - is Intent.DownloadHighRes -> component.handleDownloadHighRes(intent.messageId) - - is Intent.CancelDownloadFile -> component.handleCancelDownloadFile(intent.fileId) - - is Intent.UpdateScrollPosition -> component._state.update { it.copy(currentScrollMessageId = intent.messageId) } - is Intent.BottomReached -> component._state.update { it.copy(isAtBottom = intent.isAtBottom) } - is Intent.HighlightConsumed -> component._state.update { it.copy(highlightedMessageId = null) } - is Intent.Typing -> { /* Handle typing */ - } - - is Intent.SendReaction -> component.handleSendReaction(intent.messageId, intent.reaction) - is Intent.ToggleMessageSelection -> component.handleToggleMessageSelection(intent.messageId) - is Intent.ClearSelection -> component.handleClearSelection() - is Intent.ClearMessages -> component.handleClearMessages() - - is Intent.DeleteSelectedMessages -> component.handleDeleteSelectedMessages(intent.revoke) - is Intent.CopySelectedMessages -> component.handleCopySelectedMessages(intent.clipboardManager) - is Intent.StickerClick -> component.handleStickerClick(intent.setId) - is Intent.DismissStickerSet -> component._state.update { it.copy(selectedStickerSet = null) } - is Intent.AddToGifs -> component.handleAddToGifs(intent.path) - is Intent.PollOptionClick -> component.handlePollOptionClick(intent.messageId, intent.optionId) - is Intent.RetractVote -> component.handleRetractVote(intent.messageId) - is Intent.ShowVoters -> component.handleShowVoters(intent.messageId, intent.optionId) - is Intent.DismissVoters -> component._state.update { it.copy(showPollVoters = false) } - is Intent.ClosePoll -> component.handleClosePoll(intent.messageId) - is Intent.TopicClick -> component.handleTopicClick(intent.topicId) - - is Intent.OpenInstantView -> component._state.update { it.copy(instantViewUrl = intent.url) } - is Intent.DismissInstantView -> component._state.update { it.copy(instantViewUrl = null) } - is Intent.OpenYouTube -> publish(Label.Link(intent.url)) - is Intent.DismissYouTube -> component._state.update { it.copy(youtubeUrl = null) } - is Intent.OpenMiniApp -> component.handleOpenMiniApp(intent.url, intent.name, intent.botUserId) - is Intent.DismissMiniApp -> component._state.update { it.copy(miniAppUrl = null) } - is Intent.AcceptMiniAppTOS -> component.handleAcceptMiniAppTOS() - is Intent.DismissMiniAppTOS -> component.handleDismissMiniAppTOS() - is Intent.OpenWebView -> publish(Label.Link(intent.url)) - is Intent.DismissWebView -> component._state.update { it.copy(webViewUrl = null) } - is Intent.OpenImages -> component._state.update { - it.copy( - fullScreenImages = intent.images, - fullScreenImageMessageIds = intent.messageIds, - fullScreenCaptions = intent.captions, - fullScreenStartIndex = intent.startIndex, - fullScreenVideoMessageId = intent.messageId, - fullScreenVideoPath = null, - fullScreenVideoCaption = null - ) - } - - is Intent.DismissImages -> component._state.update { - it.copy( - fullScreenImages = null, - fullScreenImageMessageIds = emptyList(), - fullScreenVideoMessageId = null, - fullScreenVideoPath = null, - fullScreenVideoCaption = null - ) - } - - is Intent.OpenVideo -> component._state.update { - it.copy( - fullScreenVideoPath = intent.path, - fullScreenVideoMessageId = intent.messageId, - fullScreenVideoCaption = intent.caption, - fullScreenImages = null, - fullScreenImageMessageIds = emptyList() - ) - } - - is Intent.DismissVideo -> component._state.update { - it.copy( - fullScreenVideoPath = null, - fullScreenVideoMessageId = null, - fullScreenVideoCaption = null - ) - } - - is Intent.AddToAdBlockWhitelist -> component.handleAddToAdBlockWhitelist() - is Intent.RemoveFromAdBlockWhitelist -> component.handleRemoveFromAdBlockWhitelist() - is Intent.ToggleMute -> component.handleToggleMute() - - is Intent.SearchToggle -> component._state.update { - it.copy( - isSearchActive = !it.isSearchActive, - searchQuery = "" - ) - } - - is Intent.SearchQueryChange -> component._state.update { it.copy(searchQuery = intent.query) } - is Intent.ClearHistory -> component.handleClearHistory() - - is Intent.DeleteChat -> component.handleDeleteChat() - - is Intent.Report -> component._state.update { it.copy(showReportDialog = true) } - is Intent.ReportMessage -> component.handleReportMessage(intent.message) - - is Intent.ReportReasonSelected -> component.handleReportReasonSelected(intent.reason) - - is Intent.DismissReportDialog -> component._state.update { it.copy(showReportDialog = false) } - is Intent.CopyLink -> component.handleCopyLink(intent.clipboardManager) - - is Intent.ScrollToMessage -> component.scrollToMessageInternal(intent.messageId) - is Intent.BotCommandClick -> component.handleBotCommandClick(intent.command) - - is Intent.ShowBotCommands -> component._state.update { it.copy(showBotCommands = true) } - is Intent.DismissBotCommands -> component._state.update { it.copy(showBotCommands = false) } - is Intent.CommentsClick -> component.handleCommentsClick(intent.messageId) - - is Intent.ReplyMarkupButtonClick -> component.handleReplyMarkupButtonClick( - intent.messageId, - intent.button, - intent.botUserId - ) - - is Intent.KeyboardButtonClick -> component.handleKeyboardButtonClick( - intent.messageId, - intent.button, - intent.botUserId - ) - - is Intent.LinkClick -> publish(Label.Link(intent.url)) - is Intent.OpenInvoice -> component.handleOpenInvoice(intent.slug, intent.messageId) - is Intent.DismissInvoice -> component.handleDismissInvoice(intent.status) - is Intent.MentionQueryChange -> component.handleMentionQueryChange( - query = intent.query, - allMembers = component.allMembers, - onMembersUpdated = { component.allMembers = it } - ) - - is Intent.JoinChat -> component.handleJoinChat() - - is Intent.BlockUser -> component.handleBlockUser(intent.userId) - - is Intent.UnblockUser -> component.handleUnblockUser(intent.userId) - - is Intent.RestrictUser -> component._state.update { it.copy(restrictUserId = intent.userId) } - is Intent.ConfirmRestrict -> component.handleConfirmRestrict(intent.permissions, intent.untilDate) - - is Intent.DismissRestrictDialog -> component._state.update { it.copy(restrictUserId = null) } - is Intent.InlineQueryChange -> component.handleInlineQueryChange(intent.botUsername, intent.query) - is Intent.LoadMoreInlineResults -> component.handleLoadMoreInlineResults(intent.offset) - is Intent.SendInlineResult -> component.handleSendInlineResult(intent.resultId) - } - } - } - - private object ReducerImpl : Reducer { - override fun ChatComponent.State.reduce(msg: Message): ChatComponent.State = - when (msg) { - is Message.UpdateState -> msg.state - } - } - - sealed class Message { - data class UpdateState(val state: ChatComponent.State) : Message() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/DefaultChatComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/DefaultChatComponent.kt deleted file mode 100644 index 16071ea0..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/DefaultChatComponent.kt +++ /dev/null @@ -1,527 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat - -import android.util.Log -import androidx.compose.ui.platform.ClipboardManager -import com.arkivanov.essenty.lifecycle.doOnResume -import com.arkivanov.essenty.lifecycle.doOnStart -import com.arkivanov.essenty.lifecycle.doOnStop -import com.arkivanov.mvikotlin.extensions.coroutines.labels -import com.arkivanov.mvikotlin.extensions.coroutines.stateFlow -import com.arkivanov.mvikotlin.main.store.DefaultStoreFactory -import kotlinx.coroutines.* -import kotlinx.coroutines.flow.* -import kotlinx.coroutines.sync.Mutex -import org.monogram.core.DispatcherProvider -import org.monogram.domain.managers.DistrManager -import org.monogram.domain.models.* -import org.monogram.domain.repository.* -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.chats.currentChat.impl.* -import org.monogram.presentation.root.AppComponentContext -import org.monogram.presentation.settings.storage.CacheController -import java.io.File -import java.util.concurrent.ConcurrentHashMap - -class DefaultChatComponent( - context: AppComponentContext, - val chatId: Long, - private val toProfiles: (Long) -> Unit, - private val onBack: () -> Unit, - private val onProfileClick: () -> Unit, - private val onForward: (Long, List) -> Unit, - private val onLink: (String) -> Unit, - private val initialMessageId: Long? = null -) : ChatComponent, AppComponentContext by context { - - internal val settingsRepository: SettingsRepository = container.repositories.settingsRepository - override val downloadUtils: IDownloadUtils = container.utils.downloadUtils() - internal val userRepository: UserRepository = container.repositories.userRepository - override val stickerRepository: StickerRepository = container.repositories.stickerRepository - internal val privacyRepository: PrivacyRepository = container.repositories.privacyRepository - internal val botPreferences: BotPreferencesProvider = container.preferences.botPreferencesProvider - internal val toastMessageDisplayer: MessageDisplayer = container.utils.messageDisplayer() - internal val chatsListRepository: ChatsListRepository = container.repositories.chatsListRepository - override val repositoryMessage: MessageRepository = container.repositories.messageRepository - override val appPreferences: AppPreferences = container.preferences.appPreferences - internal val cacheProvider: CacheProvider = container.cacheProvider - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - internal val cacheController: CacheController = container.utils.cacheController - internal val distrManager: DistrManager = container.utils.distrManager() - internal val dispatcherProvider: DispatcherProvider = container.utils.dispatcherProvider - - val scope = componentScope - val messageMutex = Mutex() - var messageLoadingJob: Job? = null - var loadMoreJob: Job? = null - var loadNewerJob: Job? = null - var inlineBotJob: Job? = null - var draftSaveJob: Job? = null - private var autoLoadJob: Job? = null - private var mentionJob: Job? = null - internal val reactionUpdateSuppressedUntil = ConcurrentHashMap() - internal val remappedMessageIds = ConcurrentHashMap() - internal val mediaDownloadRetryCount = ConcurrentHashMap() - - internal var lastLoadedOlderId: Long = 0L - internal var lastLoadedNewerId: Long = 0L - internal var inFlightOlderAnchorId: Long = 0L - internal var inFlightNewerAnchorId: Long = 0L - - internal val _state = MutableStateFlow( - ChatComponent.State( - chatId = chatId, - fontSize = appPreferences.fontSize.value, - letterSpacing = appPreferences.letterSpacing.value, - bubbleRadius = appPreferences.bubbleRadius.value, - wallpaper = appPreferences.wallpaper.value, - isWallpaperBlurred = appPreferences.isWallpaperBlurred.value, - wallpaperBlurIntensity = appPreferences.wallpaperBlurIntensity.value, - isWallpaperMoving = appPreferences.isWallpaperMoving.value, - wallpaperDimming = appPreferences.wallpaperDimming.value, - isWallpaperGrayscale = appPreferences.isWallpaperGrayscale.value, - isPlayerGesturesEnabled = appPreferences.isPlayerGesturesEnabled.value, - isPlayerDoubleTapSeekEnabled = appPreferences.isPlayerDoubleTapSeekEnabled.value, - playerSeekDuration = appPreferences.playerSeekDuration.value, - isPlayerZoomEnabled = appPreferences.isPlayerZoomEnabled.value, - autoDownloadMobile = appPreferences.autoDownloadMobile.value, - autoDownloadWifi = appPreferences.autoDownloadWifi.value, - autoDownloadRoaming = appPreferences.autoDownloadRoaming.value, - autoDownloadFiles = appPreferences.autoDownloadFiles.value, - autoplayGifs = appPreferences.autoplayGifs.value, - autoplayVideos = appPreferences.autoplayVideos.value, - isWhitelistedInAdBlock = appPreferences.adBlockWhitelistedChannels.value.contains(chatId), - scrollToMessageId = initialMessageId, - highlightedMessageId = initialMessageId, - lastScrollPosition = cacheProvider.getChatScrollPosition(chatId), - isInstalledFromGooglePlay = distrManager.isInstalledFromGooglePlay() - ) - ) - - private val store = ChatStoreFactory( - storeFactory = DefaultStoreFactory(), - component = this - ).create() - - override val state: StateFlow = store.stateFlow - - private var availableWallpapers: List = emptyList() - internal var allMembers: List = emptyList() - - init { - setupLifecycle() - setupCollectors() - initialLoad() - } - - private fun setupLifecycle() { - lifecycle.doOnStart { - startAutoLoad() - } - - lifecycle.doOnStop { - autoLoadJob?.cancel() - } - - lifecycle.doOnResume { - loadChatInfo() - handleResume(initialMessageId) - } - - scope.launch { - try { - awaitCancellation() - } finally { - repositoryMessage.closeChat(chatId) - } - } - - store.labels - .onEach { label -> - when (label) { - ChatStore.Label.Back -> onBack() - is ChatStore.Label.Profile -> toProfiles(label.id) - is ChatStore.Label.Forward -> onForward(label.chatId, label.messageIds) - is ChatStore.Label.Link -> onLink(label.url) - } - } - .launchIn(scope) - } - - private fun setupCollectors() { - setupMessageCollectors() - setupPinnedMessageCollector() - observeUserUpdates() - observeCurrentUser() - cacheProvider.attachBots - .onEach { bots -> - _state.update { - it.copy( - attachMenuBots = bots - ) - } - } - .launchIn(scope) - - appPreferences.adBlockWhitelistedChannels - .onEach { channels -> - _state.update { it.copy(isWhitelistedInAdBlock = channels.contains(chatId)) } - } - .launchIn(scope) - - loadWallpapers { wallpapers -> - availableWallpapers = wallpapers - observePreferences(availableWallpapers) - } - - _state.onEach { - store.accept(ChatStore.Intent.UpdateState(it)) - }.launchIn(scope) - } - - private fun initialLoad() { - scope.launch { - repositoryMessage.openChat(chatId) - withContext(Dispatchers.Main) { - loadChatInfo() - loadDraft() - loadPinnedMessage() - loadScheduledMessages() - loadMembers() - } - } - } - - private fun startAutoLoad() { - autoLoadJob?.cancel() - autoLoadJob = scope.launch { - while (isActive) { - val currentState = _state.value - if ( - initialMessageId == null && - currentState.messages.isEmpty() && - !currentState.isLoading && - !currentState.isLoadingOlder && - !currentState.isLoadingNewer - ) { - Log.d("DefaultChatComponent", "Auto-loading messages...") - loadMessages() - } - delay(5000) - } - } - } - - private fun handleResume(initialMessageId: Long?) { - val currentState = _state.value - if (currentState.isLoading || currentState.isLoadingOlder || currentState.isLoadingNewer) return - - if (!currentState.viewAsTopics) { - if (initialMessageId != null) { - scrollToMessage(initialMessageId) - } else if (currentState.messages.isEmpty()) { - loadMessages() - } - } else if (currentState.messages.isEmpty() && currentState.currentTopicId == null) { - loadMessages() - } - } - - private fun loadMembers() { - scope.launch { - val currentState = _state.value - if (currentState.isGroup || currentState.isChannel) { - if (currentState.isChannel && !currentState.isAdmin) return@launch - - try { - allMembers = userRepository.getChatMembers(chatId, 0, 200, ChatMembersFilter.Recent) - .map { it.user } - } catch (e: Exception) { - Log.e("DefaultChatComponent", "Failed to load members", e) - } - } - } - } - - private fun observeCurrentUser() { - userRepository.currentUserFlow - .onEach { user -> - _state.update { it.copy(currentUser = user) } - } - .launchIn(scope) - } - - override fun onSendMessage( - text: String, - entities: List, - sendOptions: MessageSendOptions - ) = store.accept(ChatStore.Intent.SendMessage(text, entities, sendOptions)) - - override fun onSendSticker(stickerPath: String) = store.accept(ChatStore.Intent.SendSticker(stickerPath)) - override fun onSendPhoto( - photoPath: String, - caption: String, - captionEntities: List, - sendOptions: MessageSendOptions - ) = store.accept(ChatStore.Intent.SendPhoto(photoPath, caption, captionEntities, sendOptions)) - - override fun onSendVideo( - videoPath: String, - caption: String, - captionEntities: List, - sendOptions: MessageSendOptions - ) = store.accept(ChatStore.Intent.SendVideo(videoPath, caption, captionEntities, sendOptions)) - - override fun onSendGif(gif: GifModel) = store.accept(ChatStore.Intent.SendGif(gif)) - override fun onSendGifFile( - path: String, - caption: String, - captionEntities: List, - sendOptions: MessageSendOptions - ) = store.accept(ChatStore.Intent.SendGifFile(path, caption, captionEntities, sendOptions)) - - override fun onSendAlbum( - paths: List, - caption: String, - captionEntities: List, - sendOptions: MessageSendOptions - ) = store.accept(ChatStore.Intent.SendAlbum(paths, caption, captionEntities, sendOptions)) - - override fun onSendVoice(path: String, duration: Int, waveform: ByteArray) = - store.accept(ChatStore.Intent.SendVoice(path, duration, waveform)) - - override fun onRefreshScheduledMessages() = - store.accept(ChatStore.Intent.RefreshScheduledMessages) - - override fun onSendScheduledNow(message: MessageModel) = - store.accept(ChatStore.Intent.SendScheduledNow(message)) - - override fun onVideoRecorded(file: File) = store.accept(ChatStore.Intent.VideoRecorded(file)) - - override fun loadMore() = store.accept(ChatStore.Intent.LoadMore) - override fun loadNewer() = store.accept(ChatStore.Intent.LoadNewer) - - override fun onBackClicked() = store.accept(ChatStore.Intent.BackClicked) - - override fun onProfileClicked() = store.accept(ChatStore.Intent.ProfileClicked) - override fun onMessageClicked(id: Long) = store.accept(ChatStore.Intent.MessageClicked(id)) - override fun onMessageVisible(messageId: Long) = store.accept(ChatStore.Intent.MessageVisible(messageId)) - - override fun onReplyMessage(message: MessageModel) = store.accept(ChatStore.Intent.ReplyMessage(message)) - - override fun onCancelReply() = store.accept(ChatStore.Intent.CancelReply) - - override fun onCancelEdit() = store.accept(ChatStore.Intent.CancelEdit) - - override fun onForwardMessage(message: MessageModel) = store.accept(ChatStore.Intent.ForwardMessage(message)) - - override fun onForwardSelectedMessages() = store.accept(ChatStore.Intent.ForwardSelectedMessages) - - override fun onDeleteMessage(message: MessageModel, revoke: Boolean) = - store.accept(ChatStore.Intent.DeleteMessage(message, revoke)) - - override fun onDeleteSelectedMessages(revoke: Boolean) = - store.accept(ChatStore.Intent.DeleteSelectedMessages(revoke)) - - override fun onEditMessage(message: MessageModel) = store.accept(ChatStore.Intent.EditMessage(message)) - - override fun onSaveEditedMessage(text: String, entities: List) = - store.accept(ChatStore.Intent.SaveEditedMessage(text, entities)) - - override fun onDraftChange(text: String) = store.accept(ChatStore.Intent.DraftChange(text)) - - override fun onPinMessage(message: MessageModel) = store.accept(ChatStore.Intent.PinMessage(message)) - - override fun onUnpinMessage(message: MessageModel) = store.accept(ChatStore.Intent.UnpinMessage(message)) - - override fun onPinnedMessageClick(message: MessageModel?) = - store.accept(ChatStore.Intent.PinnedMessageClick(message)) - - override fun onShowAllPinnedMessages() = store.accept(ChatStore.Intent.ShowAllPinnedMessages) - - override fun onDismissPinnedMessages() = store.accept(ChatStore.Intent.DismissPinnedMessages) - - override fun onScrollToMessageConsumed() = store.accept(ChatStore.Intent.ScrollToMessageConsumed) - - override fun onScrollToBottom() = store.accept(ChatStore.Intent.ScrollToBottom) - - override fun onDownloadFile(fileId: Int) { - AutoDownloadSuppression.clear(fileId) - store.accept(ChatStore.Intent.DownloadFile(fileId)) - } - - override fun onDownloadHighRes(messageId: Long) = store.accept(ChatStore.Intent.DownloadHighRes(messageId)) - - override fun onCancelDownloadFile(fileId: Int) { - AutoDownloadSuppression.suppress(fileId) - store.accept(ChatStore.Intent.CancelDownloadFile(fileId)) - } - - override fun updateScrollPosition(messageId: Long) { - if (_state.value.currentTopicId == null) { - cacheProvider.saveChatScrollPosition(chatId, messageId) - } - _state.update { it.copy(lastScrollPosition = messageId) } - store.accept(ChatStore.Intent.UpdateScrollPosition(messageId)) - } - - override fun onBottomReached(isAtBottom: Boolean) = store.accept(ChatStore.Intent.BottomReached(isAtBottom)) - - override fun onHighlightConsumed() = store.accept(ChatStore.Intent.HighlightConsumed) - - override fun onTyping() = store.accept(ChatStore.Intent.Typing) - - override fun onSendReaction(messageId: Long, reaction: String) = - store.accept(ChatStore.Intent.SendReaction(messageId, reaction)) - - override suspend fun getMessageReadDate(chatId: Long, messageId: Long, messageDate: Int): Int { - return repositoryMessage.getMessageReadDate(chatId, messageId, messageDate) - } - - override suspend fun getMessageViewers(chatId: Long, messageId: Long): List { - return repositoryMessage.getMessageViewers(chatId, messageId) - } - - override fun toProfile(id: Long) = toProfiles(id) - override fun onToggleMessageSelection(messageId: Long) = - store.accept(ChatStore.Intent.ToggleMessageSelection(messageId)) - - override fun onClearSelection() = store.accept(ChatStore.Intent.ClearSelection) - override fun onClearMessages() = store.accept(ChatStore.Intent.ClearMessages) - - override fun onCopySelectedMessages(clipboardManager: ClipboardManager) = - store.accept(ChatStore.Intent.CopySelectedMessages(clipboardManager)) - - override fun onStickerClick(setId: Long) = store.accept(ChatStore.Intent.StickerClick(setId)) - override fun onDismissStickerSet() = store.accept(ChatStore.Intent.DismissStickerSet) - - override fun onAddToGifs(path: String) = store.accept(ChatStore.Intent.AddToGifs(path)) - - override fun onPollOptionClick(messageId: Long, optionId: Int) = - store.accept(ChatStore.Intent.PollOptionClick(messageId, optionId)) - - override fun onRetractVote(messageId: Long) = store.accept(ChatStore.Intent.RetractVote(messageId)) - override fun onShowVoters(messageId: Long, optionId: Int) = - store.accept(ChatStore.Intent.ShowVoters(messageId, optionId)) - - override fun onDismissVoters() = store.accept(ChatStore.Intent.DismissVoters) - override fun onTopicClick(topicId: Int) = store.accept(ChatStore.Intent.TopicClick(topicId)) - - override fun onOpenInstantView(url: String) = store.accept(ChatStore.Intent.OpenInstantView(url)) - - override fun onDismissInstantView() = store.accept(ChatStore.Intent.DismissInstantView) - - override fun onOpenYouTube(url: String) = store.accept(ChatStore.Intent.OpenYouTube(url)) - - override fun onDismissYouTube() = store.accept(ChatStore.Intent.DismissYouTube) - - override fun onOpenMiniApp(url: String, name: String, botUserId: Long) = - store.accept(ChatStore.Intent.OpenMiniApp(url, name, botUserId)) - - override fun onDismissMiniApp() = store.accept(ChatStore.Intent.DismissMiniApp) - override fun onAcceptMiniAppTOS() = store.accept(ChatStore.Intent.AcceptMiniAppTOS) - override fun onDismissMiniAppTOS() = store.accept(ChatStore.Intent.DismissMiniAppTOS) - - override fun onOpenWebView(url: String) = store.accept(ChatStore.Intent.OpenWebView(url)) - - override fun onDismissWebView() = store.accept(ChatStore.Intent.DismissWebView) - - override fun onOpenImages( - images: List, - captions: List, - startIndex: Int, - messageId: Long?, - messageIds: List - ) = - store.accept(ChatStore.Intent.OpenImages(images, captions, startIndex, messageId, messageIds)) - - override fun onDismissImages() = store.accept(ChatStore.Intent.DismissImages) - - override fun onOpenVideo(path: String?, messageId: Long?, caption: String?) = - store.accept(ChatStore.Intent.OpenVideo(path, messageId, caption)) - - override fun onDismissVideo() = store.accept(ChatStore.Intent.DismissVideo) - - override fun onAddToAdBlockWhitelist() = store.accept(ChatStore.Intent.AddToAdBlockWhitelist) - - override fun onRemoveFromAdBlockWhitelist() = store.accept(ChatStore.Intent.RemoveFromAdBlockWhitelist) - - override fun onToggleMute() = store.accept(ChatStore.Intent.ToggleMute) - - override fun onSearchToggle() = store.accept(ChatStore.Intent.SearchToggle) - - override fun onSearchQueryChange(query: String) = store.accept(ChatStore.Intent.SearchQueryChange(query)) - - override fun onClearHistory() = store.accept(ChatStore.Intent.ClearHistory) - override fun onDeleteChat() = store.accept(ChatStore.Intent.DeleteChat) - - override fun onReport() = store.accept(ChatStore.Intent.Report) - - override fun onReportMessage(message: MessageModel) = store.accept(ChatStore.Intent.ReportMessage(message)) - - override fun onReportReasonSelected(reason: String) = store.accept(ChatStore.Intent.ReportReasonSelected(reason)) - - override fun onDismissReportDialog() = store.accept(ChatStore.Intent.DismissReportDialog) - - override fun onCopyLink(clipboardManager: ClipboardManager) = - store.accept(ChatStore.Intent.CopyLink(clipboardManager)) - - override fun scrollToMessage(messageId: Long) = store.accept(ChatStore.Intent.ScrollToMessage(messageId)) - override fun onBotCommandClick(command: String) = store.accept(ChatStore.Intent.BotCommandClick(command)) - override fun onShowBotCommands() = store.accept(ChatStore.Intent.ShowBotCommands) - override fun onDismissBotCommands() = store.accept(ChatStore.Intent.DismissBotCommands) - - override fun onCommentsClick(messageId: Long) = store.accept(ChatStore.Intent.CommentsClick(messageId)) - - override fun onReplyMarkupButtonClick(messageId: Long, button: InlineKeyboardButtonModel, botUserId: Long) = - store.accept(ChatStore.Intent.ReplyMarkupButtonClick(messageId, button, botUserId)) - - override fun onReplyMarkupButtonClick(messageId: Long, button: KeyboardButtonModel, botUserId: Long) = - store.accept(ChatStore.Intent.KeyboardButtonClick(messageId, button, botUserId)) - - override fun onLinkClick(url: String) = store.accept(ChatStore.Intent.LinkClick(url)) - - override fun onOpenInvoice(slug: String?, messageId: Long?) = - store.accept(ChatStore.Intent.OpenInvoice(slug, messageId)) - - override fun onDismissInvoice(status: String) = store.accept(ChatStore.Intent.DismissInvoice(status)) - - override fun onMentionQueryChange(query: String?) = store.accept(ChatStore.Intent.MentionQueryChange(query)) - - override fun onJoinChat() = store.accept(ChatStore.Intent.JoinChat) - - override fun onBlockUser(userId: Long) = store.accept(ChatStore.Intent.BlockUser(userId)) - - override fun onUnblockUser(userId: Long) = store.accept(ChatStore.Intent.UnblockUser(userId)) - - override fun onRestrictUser(userId: Long, permissions: ChatPermissionsModel) = - store.accept(ChatStore.Intent.RestrictUser(userId, permissions)) - - override fun onDismissRestrictDialog() = store.accept(ChatStore.Intent.DismissRestrictDialog) - - override fun onConfirmRestrict(permissions: ChatPermissionsModel, untilDate: Int) = - store.accept(ChatStore.Intent.ConfirmRestrict(permissions, untilDate)) - - override fun onInlineQueryChange(botUsername: String, query: String) = - store.accept(ChatStore.Intent.InlineQueryChange(botUsername, query)) - - override fun onLoadMoreInlineResults(offset: String) = store.accept(ChatStore.Intent.LoadMoreInlineResults(offset)) - override fun onSendInlineResult(resultId: String) = store.accept(ChatStore.Intent.SendInlineResult(resultId)) - override fun onOpenAttachBot(botUserId: Long, fallbackName: String) { - scope.launch { - val botInfo = userRepository.getBotInfo(botUserId) - val menuButton = botInfo?.menuButton - if (menuButton is BotMenuButtonModel.WebApp) { - onOpenMiniApp( - menuButton.url, - menuButton.text.ifBlank { fallbackName }, - botUserId - ) - } - } - } - - override fun onClosePoll(messageId: Long) = store.accept(ChatStore.Intent.ClosePoll(messageId)) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatContentBackground.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatContentBackground.kt deleted file mode 100644 index f8de1cb7..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatContentBackground.kt +++ /dev/null @@ -1,60 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.chatContent - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.blur -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage -import org.monogram.presentation.features.chats.currentChat.ChatComponent -import org.monogram.presentation.settings.chatSettings.components.WallpaperBackground - -import java.io.File - -@Composable -fun ChatContentBackground( - state: ChatComponent.State, - modifier: Modifier = Modifier -) { - val wallpaper = state.wallpaperModel - if (wallpaper != null) { - WallpaperBackground( - wallpaper = wallpaper, - modifier = modifier.fillMaxSize(), - isBlurred = state.isWallpaperBlurred, - isMoving = state.isWallpaperMoving, - blurIntensity = state.wallpaperBlurIntensity, - dimming = state.wallpaperDimming, - isGrayscale = state.isWallpaperGrayscale - ) - } else if (state.wallpaper != null) { - if (File(state.wallpaper!!).exists()) { - var imageModifier = Modifier.fillMaxSize() - if (state.isWallpaperBlurred && state.wallpaperBlurIntensity > 0) { - imageModifier = imageModifier.blur((state.wallpaperBlurIntensity / 4f).dp) - } - AsyncImage( - model = File(state.wallpaper!!), - contentDescription = null, - modifier = imageModifier, - contentScale = ContentScale.Crop - ) - } else { - Box( - modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.surface) - ) - } - } else { - Box( - modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.surface) - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatContentList.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatContentList.kt deleted file mode 100644 index 3de70a0a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatContentList.kt +++ /dev/null @@ -1,1182 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.chatContent - -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.animateColorAsState -import androidx.compose.animation.core.Animatable -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.animateDpAsState -import androidx.compose.animation.core.spring -import androidx.compose.animation.expandHorizontally -import androidx.compose.animation.shrinkHorizontally -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.LazyListState -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.CheckCircle -import androidx.compose.material.icons.rounded.Lock -import androidx.compose.material.icons.rounded.PushPin -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.rotate -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.IntSize -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.launch -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.domain.models.TopicModel -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.ChatComponent -import org.monogram.presentation.features.chats.currentChat.components.* -import org.monogram.presentation.features.chats.currentChat.components.channels.ChannelMessageBubbleContainer -import org.monogram.presentation.features.stickers.ui.view.StickerImage -import java.io.File - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun ChatContentList( - showNavPadding: Boolean = false, - state: ChatComponent.State, - component: ChatComponent, - scrollState: LazyListState, - groupedMessages: List, - onPhotoClick: (MessageModel, List, List, List, Int) -> Unit, - onPhotoDownload: (Int) -> Unit, - onVideoClick: (MessageModel, String?, String?) -> Unit, - onDocumentClick: (MessageModel) -> Unit, - onAudioClick: (MessageModel) -> Unit, - onMessageOptionsClick: (MessageModel, Offset, IntSize, Offset) -> Unit, - onGoToReply: (MessageModel) -> Unit, - modifier: Modifier = Modifier, - selectedMessageId: Long? = null, - onMessagePositionChange: (Offset, IntSize) -> Unit = { _, _ -> }, - onViaBotClick: (String) -> Unit = {}, - toProfile: (Long) -> Unit, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - isAnyViewerOpen: Boolean = false -) { - val isComments = state.rootMessage != null - val isScrolling by remember(scrollState) { derivedStateOf { scrollState.isScrollInProgress } } - - LaunchedEffect( - scrollState, - groupedMessages.size, - state.isLoading, - state.isLoadingOlder, - state.isLoadingNewer, - state.isLatestLoaded, - state.isOldestLoaded, - state.isAtBottom, - isComments - ) { - snapshotFlow { scrollState.layoutInfo.visibleItemsInfo } - .filter { it.isNotEmpty() && groupedMessages.isNotEmpty() } - .map { visibleItems -> - val firstIndex = visibleItems.first().index - val lastIndex = visibleItems.last().index - firstIndex to lastIndex - } - .distinctUntilChanged() - .collect { (firstVisibleIndex, lastVisibleIndex) -> - if (state.isLoading || state.isLoadingOlder || state.isLoadingNewer) return@collect - - val nearStart = firstVisibleIndex <= 2 - val nearEnd = lastVisibleIndex >= (groupedMessages.size - 3).coerceAtLeast(0) - - if (isComments) { - if (!scrollState.isScrollInProgress) return@collect - - if (nearStart && !state.isOldestLoaded) { - component.loadMore() - } else if (nearEnd && !state.isLatestLoaded) { - component.loadNewer() - } - } else { - if (nearEnd && !state.isOldestLoaded) { - component.loadMore() - } else if (nearStart && !state.isAtBottom && !state.isLatestLoaded) { - component.loadNewer() - } - } - } - } - - if (state.viewAsTopics && state.currentTopicId == null) { - TopicsList( - topics = state.topics, - onTopicClick = { component.onTopicClick(it.id) }, - modifier = modifier, - videoPlayerPool = component.videoPlayerPool - ) - return - } - - LazyColumn( - state = scrollState, - modifier = modifier - .fillMaxSize() - .semantics { contentDescription = "ChatMessages" }, - reverseLayout = !isComments, - contentPadding = PaddingValues(vertical = 8.dp) - ) { - if (isComments && state.isLoadingOlder && groupedMessages.isNotEmpty()) { - item(key = "loading_older_top") { - PagingLoadingIndicator() - } - } - - if (!isComments && state.isLoadingNewer && !state.isAtBottom && groupedMessages.isNotEmpty()) { - item(key = "loading_newer_bottom") { - PagingLoadingIndicator() - } - } - - if (isComments) { - if (state.rootMessage != null) { - item(key = "root_header") { - RootMessageSection( - state, - component, - onPhotoClick, - onPhotoDownload, - onVideoClick, - onDocumentClick, - onAudioClick, - onMessageOptionsClick, - onGoToReply, - onViaBotClick, - toProfile, - downloadUtils, - videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } - } - - itemsIndexed( - items = groupedMessages, - key = { _, item -> - when (item) { - is GroupedMessageItem.Single -> "msg_${item.message.id}" - is GroupedMessageItem.Album -> "album_${item.albumId}" - } - } - ) { index, item -> - val olderMsg = remember(groupedMessages, index) { getMessageAt(groupedMessages, index - 1) } - val newerMsg = remember(groupedMessages, index) { getMessageAt(groupedMessages, index + 1) } - - MessageRowItem( - item = item, - state = state, - component = component, - olderMsg = olderMsg, - newerMsg = newerMsg, - isSelected = isItemSelected(item, state.selectedMessageIds), - isSelectionMode = state.selectedMessageIds.isNotEmpty(), - selectedMessageId = selectedMessageId, - onPhotoClick = onPhotoClick, - onPhotoDownload = onPhotoDownload, - onVideoClick = onVideoClick, - onDocumentClick = onDocumentClick, - onAudioClick = onAudioClick, - onMessageOptionsClick = onMessageOptionsClick, - onGoToReply = onGoToReply, - onMessagePositionChange = onMessagePositionChange, - onViaBotClick = onViaBotClick, - toProfile = toProfile, - isScrolling = isScrolling, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } - } else { - if (showNavPadding) { - item { - Spacer( - modifier = Modifier.height( - WindowInsets.navigationBars - .asPaddingValues() - .calculateBottomPadding() - ) - ) - } - } - if (state.rootMessage != null) { - item(key = "root_header") { - RootMessageSection( - state, - component, - onPhotoClick, - onPhotoDownload, - onVideoClick, - onDocumentClick, - onAudioClick, - onMessageOptionsClick, - onGoToReply, - onViaBotClick, - toProfile, - downloadUtils, - videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } - } - itemsIndexed( - items = groupedMessages, - key = { _, item -> - when (item) { - is GroupedMessageItem.Single -> "msg_${item.message.id}" - is GroupedMessageItem.Album -> "album_${item.albumId}" - } - } - ) { index, item -> - val olderMsg = remember(groupedMessages, index) { getMessageAt(groupedMessages, index + 1) } - val newerMsg = remember(groupedMessages, index) { getMessageAt(groupedMessages, index - 1) } - - MessageRowItem( - item = item, - state = state, - component = component, - olderMsg = olderMsg, - newerMsg = newerMsg, - isSelected = isItemSelected(item, state.selectedMessageIds), - isSelectionMode = state.selectedMessageIds.isNotEmpty(), - selectedMessageId = selectedMessageId, - onPhotoClick = onPhotoClick, - onPhotoDownload = onPhotoDownload, - onVideoClick = onVideoClick, - onDocumentClick = onDocumentClick, - onAudioClick = onAudioClick, - onMessageOptionsClick = onMessageOptionsClick, - onGoToReply = onGoToReply, - onMessagePositionChange = onMessagePositionChange, - onViaBotClick = onViaBotClick, - toProfile = toProfile, - isScrolling = isScrolling, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } - } - - if (isComments && state.isLoadingNewer && groupedMessages.isNotEmpty()) { - item(key = "loading_newer_bottom") { - PagingLoadingIndicator() - } - } - - if (!isComments && state.isLoadingOlder && groupedMessages.isNotEmpty()) { - item(key = "loading_older_top") { - PagingLoadingIndicator() - } - } - - if (state.isLoading && groupedMessages.isNotEmpty() && !state.isLoadingOlder && !state.isLoadingNewer) { - item(key = "loading_indicator") { - PagingLoadingIndicator() - } - } - } -} - -@Composable -private fun PagingLoadingIndicator() { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 10.dp), - contentAlignment = Alignment.Center - ) { - Surface( - shape = RoundedCornerShape(20.dp), - color = MaterialTheme.colorScheme.surfaceContainerHigh, - tonalElevation = 1.dp - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 6.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - CircularProgressIndicator( - modifier = Modifier.size(14.dp), - strokeWidth = 2.dp - ) - Text( - text = "Loading...", - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } -} - -@Composable -private fun MessageRowItem( - item: GroupedMessageItem, - state: ChatComponent.State, - component: ChatComponent, - olderMsg: MessageModel?, - newerMsg: MessageModel?, - isSelected: Boolean, - isSelectionMode: Boolean, - selectedMessageId: Long?, - onPhotoClick: (MessageModel, List, List, List, Int) -> Unit, - onPhotoDownload: (Int) -> Unit, - onVideoClick: (MessageModel, String?, String?) -> Unit, - onDocumentClick: (MessageModel) -> Unit, - onAudioClick: (MessageModel) -> Unit, - onMessageOptionsClick: (MessageModel, Offset, IntSize, Offset) -> Unit, - onGoToReply: (MessageModel) -> Unit, - onMessagePositionChange: (Offset, IntSize) -> Unit, - onViaBotClick: (String) -> Unit, - toProfile: (Long) -> Unit, - isScrolling: Boolean, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - isAnyViewerOpen: Boolean = false -) { - val mainMsg = remember(item) { - if (item is GroupedMessageItem.Single) item.message else (item as GroupedMessageItem.Album).messages.last() - } - - val shouldAnimateEntry = state.isChatAnimationsEnabled && !isScrolling - - val scale = remember(mainMsg.id) { - Animatable( - if (shouldAnimateEntry) 0.98f else 1f - ) - } - val itemAlpha = remember(mainMsg.id) { - Animatable( - if (shouldAnimateEntry) 0f else 1f - ) - } - val offsetY = remember(mainMsg.id) { - Animatable( - if (shouldAnimateEntry) 10f else 0f - ) - } - - LaunchedEffect(mainMsg.id) { - component.onMessageVisible(mainMsg.id) - } - - LaunchedEffect(mainMsg.id, shouldAnimateEntry) { - if (shouldAnimateEntry && scale.value < 1f) { - val stiffness = Spring.StiffnessMediumLow - launch { scale.animateTo(1f, spring(Spring.DampingRatioLowBouncy, stiffness)) } - launch { itemAlpha.animateTo(1f, spring(stiffness = stiffness)) } - launch { offsetY.animateTo(0f, spring(stiffness = Spring.StiffnessLow)) } - } else if (!shouldAnimateEntry) { - scale.snapTo(1f) - itemAlpha.snapTo(1f) - offsetY.snapTo(0f) - } - } - - val backgroundColor by animateColorAsState( - targetValue = if (isSelected) MaterialTheme.colorScheme.primary.copy(alpha = 0.15f) else Color.Transparent, - label = "bg" - ) - val horizontalPadding by animateDpAsState(if (isSelectionMode) 16.dp else 8.dp, label = "padding") - - Box( - modifier = Modifier - .fillMaxWidth() - .graphicsLayer { - scaleX = scale.value - scaleY = scale.value - alpha = itemAlpha.value - translationY = offsetY.value - } - .background(backgroundColor) - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null, - enabled = isSelectionMode, - onClick = { component.onToggleMessageSelection(mainMsg.id) } - ) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = horizontalPadding, vertical = 1.dp), - verticalAlignment = Alignment.Bottom - ) { - AnimatedVisibility(visible = isSelectionMode, enter = expandHorizontally(), exit = shrinkHorizontally()) { - SelectionIndicator(isSelected = isSelected, modifier = Modifier.padding(end = 12.dp, bottom = 4.dp)) - } - - Column(modifier = Modifier.weight(1f)) { - if (shouldShowDate(mainMsg, olderMsg)) { - DateSeparator(mainMsg.date) - Spacer(modifier = Modifier.height(16.dp)) - } - - MessageBubbleSwitcher( - item = item, - state = state, - component = component, - olderMsg = olderMsg, - newerMsg = newerMsg, - isSelectionMode = isSelectionMode, - selectedMessageId = selectedMessageId, - onPhotoClick = onPhotoClick, - onPhotoDownload = onPhotoDownload, - onVideoClick = onVideoClick, - onDocumentClick = onDocumentClick, - onAudioClick = onAudioClick, - onMessageOptionsClick = onMessageOptionsClick, - onGoToReply = onGoToReply, - onMessagePositionChange = onMessagePositionChange, - onViaBotClick = onViaBotClick, - toProfile = toProfile, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } - } - } -} - -@Composable -private fun MessageBubbleSwitcher( - item: GroupedMessageItem, - state: ChatComponent.State, - component: ChatComponent, - olderMsg: MessageModel?, - newerMsg: MessageModel?, - isSelectionMode: Boolean, - selectedMessageId: Long?, - onPhotoClick: (MessageModel, List, List, List, Int) -> Unit, - onPhotoDownload: (Int) -> Unit, - onVideoClick: (MessageModel, String?, String?) -> Unit, - onDocumentClick: (MessageModel) -> Unit, - onAudioClick: (MessageModel) -> Unit, - onMessageOptionsClick: (MessageModel, Offset, IntSize, Offset) -> Unit, - onGoToReply: (MessageModel) -> Unit, - onMessagePositionChange: (Offset, IntSize) -> Unit, - onViaBotClick: (String) -> Unit, - toProfile: (Long) -> Unit, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - isAnyViewerOpen: Boolean = false -) { - val isChannel = state.isChannel && state.currentTopicId == null - - when (item) { - is GroupedMessageItem.Single -> { - if (item.message.content is MessageContent.Service) { - ServiceMessage(text = (item.message.content as MessageContent.Service).text) - } else if (isChannel) { - ChannelMessageBubbleContainer( - msg = item.message, - olderMsg = olderMsg, - newerMsg = newerMsg, - autoplayGifs = state.autoplayGifs, - autoplayVideos = state.autoplayVideos, - autoDownloadFiles = state.autoDownloadFiles, - highlighted = state.highlightedMessageId == item.message.id, - onHighlightConsumed = { component.onHighlightConsumed() }, - onPhotoClick = { - if (isSelectionMode) component.onToggleMessageSelection(it.id) else handlePhotoClick( - it, - onPhotoClick - ) - }, - onDownloadPhoto = onPhotoDownload, - onVideoClick = { - if (isSelectionMode) component.onToggleMessageSelection(it.id) else handleVideoClick( - it, - onVideoClick - ) - }, - onDocumentClick = { - if (isSelectionMode) component.onToggleMessageSelection(it.id) else onDocumentClick( - it - ) - }, - onAudioClick = { - if (isSelectionMode) component.onToggleMessageSelection(it.id) else onAudioClick( - it - ) - }, - onCancelDownload = { component.onCancelDownloadFile(it) }, - onReplyClick = { pos, size, click -> - if (isSelectionMode) component.onToggleMessageSelection(item.message.id) else onMessageOptionsClick( - item.message, - pos, - size, - click - ) - }, - onGoToReply = onGoToReply, - onReactionClick = { id, r -> - if (isSelectionMode) component.onToggleMessageSelection(id) else component.onSendReaction( - id, - r - ) - }, - onReplyMarkupButtonClick = { id, btn -> - component.onReplyMarkupButtonClick( - id, - btn, - item.message.senderId - ) - }, - onStickerClick = { - if (isSelectionMode) component.onToggleMessageSelection(item.message.id) else component.onStickerClick( - it - ) - }, - onPollOptionClick = { id, opt -> - if (isSelectionMode) component.onToggleMessageSelection(id) else component.onPollOptionClick( - id, - opt - ) - }, - onRetractVote = { - if (isSelectionMode) component.onToggleMessageSelection(it) else component.onRetractVote( - it - ) - }, - onShowVoters = { id, opt -> - if (isSelectionMode) component.onToggleMessageSelection(id) else component.onShowVoters( - id, - opt - ) - }, - onClosePoll = { - if (isSelectionMode) component.onToggleMessageSelection(it) else component.onClosePoll( - it - ) - }, - fontSize = state.fontSize, - letterSpacing = state.letterSpacing, - bubbleRadius = state.bubbleRadius, - shouldReportPosition = item.message.id == selectedMessageId, - onPositionChange = { _, pos, size -> onMessagePositionChange(pos, size) }, - onCommentsClick = { component.onCommentsClick(it) }, - toProfile = toProfile, - onViaBotClick = onViaBotClick, - onYouTubeClick = { component.onOpenYouTube(it) }, - onInstantViewClick = { component.onOpenInstantView(it) }, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } else { - MessageBubbleContainer( - msg = item.message, - olderMsg = olderMsg, - newerMsg = newerMsg, - isGroup = state.isGroup || state.currentTopicId != null, - fontSize = state.fontSize, - letterSpacing = state.letterSpacing, - bubbleRadius = state.bubbleRadius, - autoDownloadMobile = state.autoDownloadMobile, - autoDownloadWifi = state.autoDownloadWifi, - autoDownloadRoaming = state.autoDownloadRoaming, - autoDownloadFiles = state.autoDownloadFiles, - autoplayGifs = state.autoplayGifs, - autoplayVideos = state.autoplayVideos, - showLinkPreviews = state.showLinkPreviews, - highlighted = state.highlightedMessageId == item.message.id, - onHighlightConsumed = { component.onHighlightConsumed() }, - onPhotoClick = { - if (isSelectionMode) component.onToggleMessageSelection(it.id) else handlePhotoClick( - it, - onPhotoClick - ) - }, - onDownloadPhoto = onPhotoDownload, - onVideoClick = { - if (isSelectionMode) component.onToggleMessageSelection(it.id) else handleVideoClick( - it, - onVideoClick - ) - }, - onDocumentClick = { - if (isSelectionMode) component.onToggleMessageSelection(it.id) else onDocumentClick( - it - ) - }, - onAudioClick = { - if (isSelectionMode) component.onToggleMessageSelection(it.id) else onAudioClick( - it - ) - }, - onCancelDownload = { component.onCancelDownloadFile(it) }, - onReplyClick = { pos, size, click -> - if (isSelectionMode) component.onToggleMessageSelection(item.message.id) else onMessageOptionsClick( - item.message, - pos, - size, - click - ) - }, - onGoToReply = onGoToReply, - onReactionClick = { id, r -> - if (isSelectionMode) component.onToggleMessageSelection(id) else component.onSendReaction( - id, - r - ) - }, - onReplyMarkupButtonClick = { id, btn -> - component.onReplyMarkupButtonClick( - id, - btn, - item.message.senderId - ) - }, - onStickerClick = { - if (isSelectionMode) component.onToggleMessageSelection(item.message.id) else component.onStickerClick( - it - ) - }, - onPollOptionClick = { id, opt -> - if (isSelectionMode) component.onToggleMessageSelection(id) else component.onPollOptionClick( - id, - opt - ) - }, - onRetractVote = { - if (isSelectionMode) component.onToggleMessageSelection(it) else component.onRetractVote( - it - ) - }, - onShowVoters = { id, opt -> - if (isSelectionMode) component.onToggleMessageSelection(id) else component.onShowVoters( - id, - opt - ) - }, - onClosePoll = { - if (isSelectionMode) component.onToggleMessageSelection(it) else component.onClosePoll( - it - ) - }, - onInstantViewClick = { component.onOpenInstantView(it) }, - onYouTubeClick = { component.onOpenYouTube(it) }, - shouldReportPosition = item.message.id == selectedMessageId, - onPositionChange = { _, pos, size -> onMessagePositionChange(pos, size) }, - toProfile = toProfile, - onViaBotClick = onViaBotClick, - canReply = state.canWrite && !isSelectionMode, - onReplySwipe = { component.onReplyMessage(it) }, - swipeEnabled = !isSelectionMode, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } - } - - is GroupedMessageItem.Album -> { - AlbumMessageBubbleContainer( - messages = item.messages, - olderMsg = olderMsg, - newerMsg = newerMsg, - isGroup = state.isGroup || state.currentTopicId != null, - isChannel = isChannel, - autoplayGifs = state.autoplayGifs, - autoplayVideos = state.autoplayVideos, - autoDownloadMobile = state.autoDownloadMobile, - autoDownloadWifi = state.autoDownloadWifi, - autoDownloadRoaming = state.autoDownloadRoaming, - onPhotoClick = { - if (isSelectionMode) component.onToggleMessageSelection(it.id) else handleAlbumPhotoClick( - it, - item.messages, - onPhotoClick - ) - }, - onDownloadPhoto = onPhotoDownload, - onVideoClick = { - if (isSelectionMode) component.onToggleMessageSelection(it.id) else handleAlbumVideoClick( - it, - item.messages, - onPhotoClick, - onVideoClick - ) - }, - onDocumentClick = { - if (isSelectionMode) component.onToggleMessageSelection(it.id) else onDocumentClick( - it - ) - }, - onAudioClick = { - if (isSelectionMode) component.onToggleMessageSelection(it.id) else onAudioClick( - it - ) - }, - onCancelDownload = { component.onCancelDownloadFile(it) }, - onReplyClick = { pos, size, click -> - if (isSelectionMode) component.onToggleMessageSelection(item.messages.last().id) else onMessageOptionsClick( - item.messages.last(), - pos, - size, - click - ) - }, - onGoToReply = onGoToReply, - onReactionClick = { id, r -> - if (isSelectionMode) component.onToggleMessageSelection(id) else component.onSendReaction( - id, - r - ) - }, - shouldReportPosition = item.messages.last().id == selectedMessageId, - onPositionChange = { _, pos, size -> onMessagePositionChange(pos, size) }, - onCommentsClick = { component.onCommentsClick(it) }, - toProfile = toProfile, - onViaBotClick = onViaBotClick, - canReply = state.canWrite && !isSelectionMode, - onReplySwipe = { component.onReplyMessage(it) }, - swipeEnabled = !isSelectionMode, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } - } -} - -@Composable -private fun SelectionIndicator(isSelected: Boolean, modifier: Modifier = Modifier) { - Box( - modifier = modifier - .size(24.dp) - .clip(CircleShape) - .background( - if (isSelected) MaterialTheme.colorScheme.primary - else MaterialTheme.colorScheme.outline.copy(alpha = 0.3f) - ), - contentAlignment = Alignment.Center - ) { - if (isSelected) { - Icon( - Icons.Default.CheckCircle, - null, - tint = MaterialTheme.colorScheme.onPrimary, - modifier = Modifier.size(24.dp) - ) - } - } -} - -@Composable -private fun RootMessageSection( - state: ChatComponent.State, - component: ChatComponent, - onPhotoClick: (MessageModel, List, List, List, Int) -> Unit, - onPhotoDownload: (Int) -> Unit, - onVideoClick: (MessageModel, String?, String?) -> Unit, - onDocumentClick: (MessageModel) -> Unit, - onAudioClick: (MessageModel) -> Unit, - onMessageOptionsClick: (MessageModel, Offset, IntSize, Offset) -> Unit, - onGoToReply: (MessageModel) -> Unit, - onViaBotClick: (String) -> Unit, - toProfile: (Long) -> Unit, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - isAnyViewerOpen: Boolean = false -) { - val root = state.rootMessage ?: return - Column( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 4.dp) - ) { - if (state.isChannel) { - ChannelMessageBubbleContainer( - msg = root, olderMsg = null, newerMsg = null, - autoplayGifs = state.autoplayGifs, autoplayVideos = state.autoplayVideos, - autoDownloadFiles = state.autoDownloadFiles, - onPhotoClick = { handlePhotoClick(it, onPhotoClick) }, - onDownloadPhoto = onPhotoDownload, - onVideoClick = { handleVideoClick(it, onVideoClick) }, - onDocumentClick = onDocumentClick, - onAudioClick = onAudioClick, - onCancelDownload = { component.onCancelDownloadFile(it) }, - onReplyClick = { pos, size, click -> onMessageOptionsClick(root, pos, size, click) }, - onGoToReply = onGoToReply, - onReactionClick = { id, r -> component.onSendReaction(id, r) }, - onReplyMarkupButtonClick = { id, btn -> component.onReplyMarkupButtonClick(id, btn, root.senderId) }, - onStickerClick = { component.onStickerClick(it) }, - onPollOptionClick = { id, opt -> component.onPollOptionClick(id, opt) }, - onRetractVote = { component.onRetractVote(it) }, - onShowVoters = { id, opt -> component.onShowVoters(id, opt) }, - onClosePoll = { component.onClosePoll(it) }, - fontSize = state.fontSize, - letterSpacing = state.letterSpacing, - bubbleRadius = state.bubbleRadius, - onCommentsClick = {}, showComments = false, - toProfile = toProfile, - onViaBotClick = onViaBotClick, - onYouTubeClick = { component.onOpenYouTube(it) }, - onInstantViewClick = { component.onOpenInstantView(it) }, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } else { - MessageBubbleContainer( - msg = root, olderMsg = null, newerMsg = null, isGroup = state.isGroup, - fontSize = state.fontSize, - letterSpacing = state.letterSpacing, - bubbleRadius = state.bubbleRadius, - autoDownloadMobile = state.autoDownloadMobile, autoDownloadWifi = state.autoDownloadWifi, - autoDownloadRoaming = state.autoDownloadRoaming, autoDownloadFiles = state.autoDownloadFiles, - autoplayGifs = state.autoplayGifs, autoplayVideos = state.autoplayVideos, - onPhotoClick = { handlePhotoClick(it, onPhotoClick) }, - onDownloadPhoto = onPhotoDownload, - onVideoClick = { handleVideoClick(it, onVideoClick) }, - onDocumentClick = onDocumentClick, - onAudioClick = onAudioClick, - onCancelDownload = { component.onCancelDownloadFile(it) }, - onReplyClick = { pos, size, click -> onMessageOptionsClick(root, pos, size, click) }, - onGoToReply = onGoToReply, - onReactionClick = { id, r -> component.onSendReaction(id, r) }, - onReplyMarkupButtonClick = { id, btn -> component.onReplyMarkupButtonClick(id, btn, root.senderId) }, - onStickerClick = { component.onStickerClick(it) }, - onPollOptionClick = { id, opt -> component.onPollOptionClick(id, opt) }, - onRetractVote = { component.onRetractVote(it) }, - onShowVoters = { id, opt -> component.onShowVoters(id, opt) }, - onClosePoll = { component.onClosePoll(it) }, - toProfile = toProfile, swipeEnabled = false, - onViaBotClick = onViaBotClick, - onInstantViewClick = { component.onOpenInstantView(it) }, - onYouTubeClick = { component.onOpenYouTube(it) }, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } - - HorizontalDivider( - modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp), - thickness = 0.5.dp, - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - } -} - -private fun getMessageAt(list: List, index: Int): MessageModel? { - return when (val item = list.getOrNull(index)) { - is GroupedMessageItem.Single -> item.message - is GroupedMessageItem.Album -> item.messages.last() - null -> null - } -} - -private fun isItemSelected(item: GroupedMessageItem, selectedIds: Set): Boolean { - return when (item) { - is GroupedMessageItem.Single -> selectedIds.contains(item.message.id) - is GroupedMessageItem.Album -> item.messages.any { selectedIds.contains(it.id) } - } -} - -private fun handlePhotoClick( - msg: MessageModel, - onPhotoClick: (MessageModel, List, List, List, Int) -> Unit -) { - val path = msg.displayMediaPath() ?: return - onPhotoClick(msg, listOf(path), listOf(msg.mediaCaption()), listOf(msg.id), 0) -} - -private fun handleVideoClick(msg: MessageModel, onVideoClick: (MessageModel, String?, String?) -> Unit) { - when (val content = msg.content) { - is MessageContent.Video -> onVideoClick(msg, content.path, content.caption) - is MessageContent.Gif -> onVideoClick(msg, content.path, content.caption) - else -> {} - } -} - -private fun handleAlbumPhotoClick( - clickedMsg: MessageModel, - messages: List, - onPhotoClick: (MessageModel, List, List, List, Int) -> Unit -) { - val entries = buildAlbumMediaEntries(messages) - if (entries.isEmpty()) { - val singlePath = clickedMsg.displayMediaPath() ?: return - onPhotoClick(clickedMsg, listOf(singlePath), listOf(clickedMsg.mediaCaption()), listOf(clickedMsg.id), 0) - return - } - - val index = entries.indexOfFirst { it.message.id == clickedMsg.id } - if (index < 0) { - val singlePath = clickedMsg.displayMediaPath() ?: return - onPhotoClick(clickedMsg, listOf(singlePath), listOf(clickedMsg.mediaCaption()), listOf(clickedMsg.id), 0) - return - } - - onPhotoClick( - clickedMsg, - entries.map { it.path }, - entries.map { it.caption }, - entries.map { it.message.id }, - index - ) -} - -private fun handleAlbumVideoClick( - clickedMsg: MessageModel, - messages: List, - onPhotoClick: (MessageModel, List, List, List, Int) -> Unit, - onVideoClick: (MessageModel, String?, String?) -> Unit -) { - val videoContent = clickedMsg.content as? MessageContent.Video - val gifContent = clickedMsg.content as? MessageContent.Gif - val supportsStreaming = videoContent?.supportsStreaming ?: false - val path = (videoContent?.path ?: gifContent?.path)?.takeIf { it.isNotBlank() && File(it).exists() } - val clickedCaption = clickedMsg.mediaCaption() - - if (path == null && !supportsStreaming) return - if (path == null && supportsStreaming) { - onVideoClick(clickedMsg, null, clickedCaption) - return - } - - val entries = buildAlbumMediaEntries(messages) - if (entries.isEmpty()) { - onVideoClick(clickedMsg, path, clickedCaption) - return - } - - val index = entries.indexOfFirst { it.message.id == clickedMsg.id } - if (index < 0) { - onVideoClick(clickedMsg, path, clickedCaption) - return - } - - onPhotoClick( - clickedMsg, - entries.map { it.path }, - entries.map { it.caption }, - entries.map { it.message.id }, - index - ) - - if (supportsStreaming) { - onVideoClick(clickedMsg, path, entries.getOrNull(index)?.caption) - } -} - -private data class AlbumMediaEntry( - val message: MessageModel, - val path: String, - val caption: String? -) - -private fun buildAlbumMediaEntries(messages: List): List { - return messages.mapNotNull { msg -> - val path = msg.displayMediaPath() ?: return@mapNotNull null - val caption = msg.mediaCaption() - - AlbumMediaEntry(message = msg, path = path, caption = caption) - } -} - -private fun MessageModel.displayMediaPath(): String? { - val raw = when (val content = content) { - is MessageContent.Photo -> content.path ?: content.thumbnailPath - is MessageContent.Video -> content.path - is MessageContent.Gif -> content.path - else -> null - } - - return raw?.takeIf { it.isNotBlank() && File(it).exists() } -} - -private fun MessageModel.mediaCaption(): String? { - return when (val content = content) { - is MessageContent.Photo -> content.caption - is MessageContent.Video -> content.caption - is MessageContent.Gif -> content.caption - else -> null - } -} - - -@Composable -fun TopicsList( - topics: List, - videoPlayerPool: VideoPlayerPool, - onTopicClick: (TopicModel) -> Unit, - modifier: Modifier = Modifier -) { - val sortedTopics = remember(topics) { - topics.sortedWith(compareByDescending { it.isPinned }.thenByDescending { it.order }) - } - - LazyColumn( - modifier = modifier.fillMaxSize(), - contentPadding = PaddingValues(horizontal = 12.dp, vertical = 8.dp), - verticalArrangement = Arrangement.spacedBy(4.dp) - ) { - itemsIndexed(sortedTopics, key = { _, topic -> topic.id }) { _, topic -> - TopicItem(topic = topic, videoPlayerPool = videoPlayerPool, onClick = { onTopicClick(topic) }) - } - } -} - -@Composable -fun TopicItem( - topic: TopicModel, - videoPlayerPool: VideoPlayerPool, - onClick: () -> Unit -) { - Surface( - modifier = Modifier - .fillMaxWidth() - .clickable(onClick = onClick), - color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.3f), - shape = RoundedCornerShape(16.dp) - ) { - Row( - modifier = Modifier - .padding(12.dp) - .fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(44.dp) - .background( - Color(topic.iconColor or 0xFF000000.toInt()).copy(alpha = 0.2f), - shape = RoundedCornerShape(12.dp) - ), - contentAlignment = Alignment.Center - ) { - if (topic.iconCustomEmojiPath != null) { - StickerImage( - path = topic.iconCustomEmojiPath, - modifier = Modifier.size(28.dp), - animate = true - ) - } else { - Text( - text = topic.name.take(1).uppercase(), - color = Color(topic.iconColor or 0xFF000000.toInt()), - fontWeight = FontWeight.Bold, - fontSize = 18.sp - ) - } - } - - Spacer(modifier = Modifier.width(12.dp)) - - Column(modifier = Modifier.weight(1f)) { - Text( - text = topic.name, - style = MaterialTheme.typography.titleMedium.copy( - fontWeight = FontWeight.SemiBold, - color = MaterialTheme.colorScheme.onSurface - ), - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Row(verticalAlignment = Alignment.CenterVertically) { - if (topic.isClosed) { - Icon( - Icons.Rounded.Lock, - contentDescription = "Closed", - modifier = Modifier.size(14.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.width(4.dp)) - } - - if (topic.lastMessageSenderAvatar != null || topic.lastMessageSenderName != null) { - Avatar( - path = topic.lastMessageSenderAvatar, - name = topic.lastMessageSenderName ?: "", - size = 18.dp, - fontSize = 8, - videoPlayerPool = videoPlayerPool - ) - Spacer(modifier = Modifier.width(6.dp)) - } - - Text( - text = if (topic.isClosed && topic.lastMessageText.isEmpty()) "Closed" else topic.lastMessageText, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - } - - Spacer(modifier = Modifier.width(8.dp)) - - Column( - horizontalAlignment = Alignment.End, - verticalArrangement = Arrangement.spacedBy(4.dp) - ) { - if (topic.lastMessageTime.isNotEmpty()) { - Text( - text = topic.lastMessageTime, - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f) - ) - } - Row(verticalAlignment = Alignment.CenterVertically) { - if (topic.isPinned) { - Icon( - Icons.Rounded.PushPin, - contentDescription = "Pinned", - modifier = Modifier - .size(14.dp) - .rotate(45f), - tint = MaterialTheme.colorScheme.primary.copy(alpha = 0.7f) - ) - if (topic.unreadCount > 0) Spacer(modifier = Modifier.width(6.dp)) - } - if (topic.unreadCount > 0) { - Surface( - color = MaterialTheme.colorScheme.primary, - shape = CircleShape - ) { - Text( - text = topic.unreadCount.toString(), - modifier = Modifier.padding(horizontal = 8.dp, vertical = 2.dp), - style = MaterialTheme.typography.labelSmall.copy(fontWeight = FontWeight.Bold), - color = MaterialTheme.colorScheme.onPrimary - ) - } - } - } - } - } - } -} - diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatContentTopBar.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatContentTopBar.kt deleted file mode 100644 index 96308eae..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatContentTopBar.kt +++ /dev/null @@ -1,332 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.chatContent - -import androidx.compose.animation.* -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.spring -import androidx.compose.animation.core.tween -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.Forward -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.ContentCopy -import androidx.compose.material.icons.filled.Delete -import androidx.compose.material.icons.filled.MoreVert -import androidx.compose.material.icons.rounded.PushPin -import androidx.compose.material.icons.rounded.Report -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.TransformOrigin -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.platform.LocalClipboardManager -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import androidx.compose.ui.window.Popup -import androidx.compose.ui.window.PopupProperties -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ConfirmationSheet -import org.monogram.presentation.core.util.rememberUserStatusText -import org.monogram.presentation.features.chats.currentChat.ChatComponent -import org.monogram.presentation.features.chats.currentChat.components.ChatTopBar -import org.monogram.presentation.features.chats.currentChat.components.pins.PinnedMessageBar -import org.monogram.presentation.features.stickers.ui.menu.MenuOptionRow -import org.monogram.presentation.features.viewers.components.ViewerSettingsDropdown - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ChatContentTopBar( - state: ChatComponent.State, - component: ChatComponent, - contentAlpha: Float, - onBack: () -> Unit, - onOpenMenu: () -> Unit = {}, - onPinnedMessageClick: (MessageModel) -> Unit, - showBack: Boolean = true -) { - val clipboardManager = LocalClipboardManager.current - val isAdBlockEnabled by component.appPreferences.isAdBlockEnabled.collectAsState() - val isSelectionMode = state.selectedMessageIds.isNotEmpty() - val isMainChat = state.currentTopicId == null && state.rootMessage == null - val canClearOrDeleteChat = (!state.isGroup && !state.isChannel) || state.isAdmin - val otherUserId = state.otherUser?.id - val canReportChat = state.isGroup || state.isChannel || - (otherUserId != null && state.currentUser?.id != otherUserId) - - var showDeleteSheet by remember { mutableStateOf(false) } - var pendingUnpinMessage by remember { mutableStateOf(null) } - - if (showDeleteSheet) { - val selectedMessages = remember(state.messages, state.selectedMessageIds) { - state.messages.filter { it.id in state.selectedMessageIds } - } - val canRevoke = remember(selectedMessages) { - selectedMessages.any { it.canBeDeletedForAllUsers } - } - - DeleteMessagesSheet( - count = state.selectedMessageIds.size, - canRevoke = canRevoke, - onDismiss = { showDeleteSheet = false }, - onDelete = { revoke -> - component.onDeleteSelectedMessages(revoke = revoke) - showDeleteSheet = false - } - ) - } - - pendingUnpinMessage?.let { pinnedToUnpin -> - ConfirmationSheet( - icon = Icons.Rounded.PushPin, - title = stringResource(R.string.unpin_message_title), - description = stringResource(R.string.unpin_message_confirmation), - confirmText = stringResource(R.string.action_unpin), - onConfirm = { - component.onUnpinMessage(pinnedToUnpin) - pendingUnpinMessage = null - }, - onDismiss = { pendingUnpinMessage = null } - ) - } - - Column( - modifier = Modifier.graphicsLayer { - alpha = contentAlpha - } - ) { - AnimatedContent( - targetState = isSelectionMode, - transitionSpec = { - fadeIn() togetherWith fadeOut() - }, - label = "TopBarSelection" - ) { selectionMode -> - if (selectionMode) { - TopAppBar( - title = { - Text(text = "${state.selectedMessageIds.size}") - }, - navigationIcon = { - IconButton(onClick = { component.onClearSelection() }) { - Icon( - Icons.Default.Close, - contentDescription = stringResource(R.string.cd_clear_selection) - ) - } - }, - actions = { - IconButton(onClick = { component.onForwardSelectedMessages() }) { - Icon( - Icons.AutoMirrored.Filled.Forward, - contentDescription = stringResource(R.string.menu_forward) - ) - } - IconButton(onClick = { component.onCopySelectedMessages(clipboardManager) }) { - Icon( - Icons.Default.ContentCopy, - contentDescription = stringResource(R.string.menu_copy) - ) - } - IconButton(onClick = { showDeleteSheet = true }) { - Icon( - Icons.Default.Delete, - contentDescription = stringResource(R.string.menu_delete) - ) - } - var showMenu by remember { mutableStateOf(false) } - Box { - IconButton(onClick = { - onOpenMenu() - showMenu = true - }) { - Icon( - Icons.Default.MoreVert, - contentDescription = stringResource(R.string.menu_more) - ) - } - if (showMenu) { - Popup( - onDismissRequest = { showMenu = false }, - properties = PopupProperties(focusable = true) - ) { - Box( - modifier = Modifier - .fillMaxSize() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null - ) { showMenu = false } - ) { - var isVisible by remember { mutableStateOf(false) } - LaunchedEffect(Unit) { isVisible = true } - - @Suppress("RemoveRedundantQualifierName") - androidx.compose.animation.AnimatedVisibility( - visible = isVisible, - enter = fadeIn(tween(150)) + scaleIn( - animationSpec = spring( - dampingRatio = 0.8f, - stiffness = Spring.StiffnessMedium - ), - initialScale = 0.8f, - transformOrigin = TransformOrigin(1f, 0f) - ), - exit = fadeOut(tween(150)) + scaleOut( - animationSpec = tween(150), - targetScale = 0.9f, - transformOrigin = TransformOrigin(1f, 0f) - ), - modifier = Modifier - .align(Alignment.TopEnd) - .windowInsetsPadding(WindowInsets.statusBars) - .padding(top = 56.dp, end = 16.dp) - ) { - ViewerSettingsDropdown { - MenuOptionRow( - icon = Icons.AutoMirrored.Filled.Forward, - title = stringResource(R.string.menu_forward), - onClick = { - showMenu = false - component.onForwardSelectedMessages() - } - ) - MenuOptionRow( - icon = Icons.Default.ContentCopy, - title = stringResource(R.string.menu_copy), - onClick = { - showMenu = false - component.onCopySelectedMessages(clipboardManager) - } - ) - MenuOptionRow( - icon = Icons.Rounded.Report, - title = stringResource(R.string.menu_report), - onClick = { - showMenu = false - component.onReport() - } - ) - HorizontalDivider(modifier = Modifier.padding(vertical = 4.dp)) - MenuOptionRow( - icon = Icons.Default.Delete, - title = stringResource(R.string.menu_delete), - textColor = MaterialTheme.colorScheme.error, - iconTint = MaterialTheme.colorScheme.error, - onClick = { - showMenu = false - showDeleteSheet = true - } - ) - } - } - } - } - } - } - } - ) - } else { - val formattedUserStatus = rememberUserStatusText(state.otherUser) - val statusText = when { - state.typingAction != null -> state.typingAction - state.isChannel -> stringResource( - R.string.subscribers_count_format, - state.memberCount - ) - - state.isGroup -> { - if (state.onlineCount > 0) { - stringResource( - R.string.members_online_count_format, - stringResource(R.string.members_count_format, state.memberCount), - state.onlineCount - ) - } else { - stringResource(R.string.members_count_format, state.memberCount) - } - } - - else -> formattedUserStatus - } - val currentTopic = remember(state.currentTopicId, state.topics) { - if (state.currentTopicId != null) { - state.topics.find { it.id.toLong() == state.currentTopicId } - } else null - } - - val threadTitle = stringResource(R.string.thread_title) - val title = remember(currentTopic, state.rootMessage, state.chatTitle, threadTitle) { - when { - currentTopic != null -> currentTopic.name - state.rootMessage != null -> threadTitle - else -> state.chatTitle - } - } - val topicEmojiPath = currentTopic?.iconCustomEmojiPath - - ChatTopBar( - title = title, - avatarPath = state.chatAvatar, - emojiStatusPath = state.chatEmojiStatus, - statusText = statusText, - isOnline = state.isOnline, - isVerified = state.isVerified, - isSponsor = state.isSponsor, - onBack = onBack, - onMenu = onOpenMenu, - onClick = { component.onProfileClicked() }, - topicEmojiPath = topicEmojiPath, - isChannel = state.isChannel, - isWhitelistedInAdBlock = state.isWhitelistedInAdBlock, - onToggleAdBlockWhitelist = if (isMainChat && state.isChannel && isAdBlockEnabled && !state.isInstalledFromGooglePlay) { - { - if (state.isWhitelistedInAdBlock) { - component.onRemoveFromAdBlockWhitelist() - } else { - component.onAddToAdBlockWhitelist() - } - } - } else null, - isMuted = state.isMuted, - onToggleMute = component::onToggleMute, - isSearchActive = state.isSearchActive, - searchQuery = state.searchQuery, - onSearchToggle = component::onSearchToggle, - onSearchQueryChange = component::onSearchQueryChange, - onClearHistory = if (isMainChat && canClearOrDeleteChat) component::onClearHistory else null, - onDeleteChat = if (isMainChat && canClearOrDeleteChat) component::onDeleteChat else null, - onReport = if (isMainChat && canReportChat) component::onReport else null, - onCopyLink = if (isMainChat && (state.isGroup || state.isChannel)) { - { component.onCopyLink(clipboardManager) } - } else null, - onManageMembers = if (isMainChat && state.isGroup && (state.isAdmin || state.permissions.canInviteUsers)) { - { component.onProfileClicked() } - } else null, - showBack = showBack, - personalAvatarPath = state.chatPersonalAvatar, - videoPlayerPool = component.videoPlayerPool - ) - } - } - - val showPinned = state.pinnedMessage != null && !isSelectionMode && state.rootMessage == null - AnimatedVisibility( - visible = showPinned, - enter = expandVertically(), - exit = shrinkVertically() - ) { - state.pinnedMessage?.let { pinned -> - PinnedMessageBar( - message = pinned, - count = state.pinnedMessageCount, - onClose = { pendingUnpinMessage = pinned }, - onClick = { onPinnedMessageClick(pinned) }, - onShowAll = { component.onShowAllPinnedMessages() } - ) - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatContentUtils.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatContentUtils.kt deleted file mode 100644 index 001af250..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatContentUtils.kt +++ /dev/null @@ -1,65 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.chatContent - -import org.monogram.domain.models.MessageModel -import java.text.SimpleDateFormat -import java.util.* - -sealed class GroupedMessageItem { - data class Single(val message: MessageModel) : GroupedMessageItem() - data class Album(val albumId: Long, val messages: List) : GroupedMessageItem() - - val firstMessageId: Long - get() = when (this) { - is Single -> message.id - is Album -> messages.first().id - } -} - -fun groupMessagesByAlbum(messages: List): List { - if (messages.isEmpty()) return emptyList() - - val result = mutableListOf() - var currentAlbumId: Long = 0L - val currentAlbumMessages = mutableListOf() - fun flushCurrentAlbum() { - if (currentAlbumMessages.isEmpty()) return - - if (currentAlbumMessages.size == 1) { - result.add(GroupedMessageItem.Single(currentAlbumMessages.first())) - } else { - result.add(GroupedMessageItem.Album(currentAlbumId, currentAlbumMessages.toList())) - } - currentAlbumMessages.clear() - currentAlbumId = 0L - } - - for (msg in messages) { - if (msg.mediaAlbumId != 0L) { - if (currentAlbumId == msg.mediaAlbumId) { - currentAlbumMessages.add(msg) - } else { - flushCurrentAlbum() - currentAlbumId = msg.mediaAlbumId - currentAlbumMessages.add(msg) - } - } else { - flushCurrentAlbum() - result.add(GroupedMessageItem.Single(msg)) - } - } - flushCurrentAlbum() - return result -} - -fun shouldShowDate(current: MessageModel, older: MessageModel?): Boolean { - val currentTimestamp = System.currentTimeMillis() - val msgTimestamp = current.date.toLong() * 1000 - val fmt = SimpleDateFormat("yyyyDDD", Locale.US) - - if (fmt.format(Date(currentTimestamp)) == fmt.format(Date(msgTimestamp))) { - return false - } - - if (older == null) return true - return !fmt.format(Date(msgTimestamp)).equals(fmt.format(Date(older.date.toLong() * 1000))) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatContentViewers.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatContentViewers.kt deleted file mode 100644 index 35c29971..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatContentViewers.kt +++ /dev/null @@ -1,374 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.chatContent - -import android.util.Log -import androidx.compose.animation.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.key -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.platform.ClipboardManager -import androidx.compose.ui.text.AnnotatedString -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.features.chats.currentChat.ChatComponent -import org.monogram.presentation.features.instantview.InstantViewer -import org.monogram.presentation.features.viewers.ImageViewer -import org.monogram.presentation.features.viewers.VideoViewer -import org.monogram.presentation.features.viewers.YouTubeViewer -import org.monogram.presentation.features.webapp.MiniAppViewer -import org.monogram.presentation.features.webapp.components.InvoiceDialog -import org.monogram.presentation.features.webapp.components.MiniAppTOSBottomSheet -import org.monogram.presentation.features.webview.InternalWebView - -@Composable -fun ChatContentViewers( - state: ChatComponent.State, - component: ChatComponent, - clipboardManager: ClipboardManager -) { - AnimatedVisibility( - visible = state.instantViewUrl != null, - enter = slideInVertically(initialOffsetY = { it }) + fadeIn(), - exit = slideOutVertically(targetOffsetY = { it }) + fadeOut() - ) { - state.instantViewUrl?.let { url -> - InstantViewer( - url = url, - messageRepository = component.repositoryMessage, - onDismiss = { component.onDismissInstantView() }, - onOpenWebView = { component.onOpenWebView(it) }, - videoPlayerPool = component.videoPlayerPool - ) - } - } - - AnimatedVisibility( - visible = state.youtubeUrl != null, - enter = fadeIn(), - exit = fadeOut() - ) { - state.youtubeUrl?.let { url -> - YouTubeViewer( - videoUrl = url, - onDismiss = { component.onDismissYouTube() }, - onForward = { - component.onForwardMessage(state.messages.find { - (it.content as? MessageContent.Text)?.text?.contains( - url - ) == true - } ?: return@YouTubeViewer) - }, - onCopyLink = { clipboardManager.setText(AnnotatedString(it)) }, - onCopyText = { clipboardManager.setText(AnnotatedString(it)) }, - isPipEnabled = !state.isInstalledFromGooglePlay - ) - } - } - - AnimatedVisibility( - visible = state.miniAppUrl != null, - enter = slideInVertically(initialOffsetY = { it }) + fadeIn(), - exit = slideOutVertically(targetOffsetY = { it }) + fadeOut() - ) { - if (state.miniAppUrl != null && state.miniAppName != null) { - MiniAppViewer( - chatId = state.chatId, - botUserId = state.miniAppBotUserId, - baseUrl = state.miniAppUrl, - botName = state.chatTitle, - botAvatarPath = state.chatAvatar, - messageRepository = component.repositoryMessage, - onDismiss = { component.onDismissMiniApp() } - ) - } - } - - AnimatedVisibility( - visible = state.webViewUrl != null, - enter = slideInVertically(initialOffsetY = { it }) + fadeIn(), - exit = slideOutVertically(targetOffsetY = { it }) + fadeOut() - ) { - state.webViewUrl?.let { url -> - InternalWebView( - url = url, - onDismiss = { component.onDismissWebView() } - ) - } - } - - AnimatedVisibility( - visible = state.fullScreenImages != null, - enter = fadeIn() + scaleIn(initialScale = 0.9f), - exit = fadeOut() + scaleOut(targetScale = 0.9f) - ) { - state.fullScreenImages?.let { images -> - val autoDownload = remember(state.autoDownloadWifi, state.autoDownloadRoaming, state.autoDownloadMobile) { - when { - component.downloadUtils.isWifiConnected() -> state.autoDownloadWifi - component.downloadUtils.isRoaming() -> state.autoDownloadRoaming - else -> state.autoDownloadMobile - } - } - - val viewerItems = remember(images, state.fullScreenImageMessageIds, state.messages) { - if (state.fullScreenImageMessageIds.size == images.size) { - state.fullScreenImageMessageIds.mapIndexed { index, messageId -> - val message = state.messages.firstOrNull { it.id == messageId } - val resolvedPath = message?.displayMediaPathForViewer() ?: images[index] - ViewerMediaItem(messageId = messageId, path = resolvedPath) - } - } else { - images.map { path -> - val message = state.messages.firstOrNull { it.content.matchesDisplayPath(path) } - ViewerMediaItem( - messageId = message?.id ?: 0L, - path = message?.displayMediaPathForViewer() ?: path - ) - } - } - } - - val viewerImages = remember(viewerItems) { viewerItems.map { it.path } } - val imageMessageIds = remember(viewerItems) { viewerItems.map { it.messageId } } - var currentImageIndex by remember(viewerImages, state.fullScreenStartIndex) { - mutableIntStateOf( - state.fullScreenStartIndex.coerceIn( - 0, - (viewerImages.lastIndex).coerceAtLeast(0) - ) - ) - } - - val currentViewerMessage = remember(currentImageIndex, imageMessageIds, state.messages) { - imageMessageIds.getOrNull(currentImageIndex) - ?.takeIf { it != 0L } - ?.let { id -> state.messages.firstOrNull { it.id == id } } - } - - val imageDownloadingStates = remember(imageMessageIds, state.messages) { - imageMessageIds.map { id -> - val content = state.messages.firstOrNull { it.id == id }?.content - when (content) { - is MessageContent.Photo -> content.isDownloading - else -> false - } - } - } - - val imageDownloadProgressStates = remember(imageMessageIds, state.messages) { - imageMessageIds.map { id -> - val content = state.messages.firstOrNull { it.id == id }?.content - when (content) { - is MessageContent.Photo -> content.downloadProgress - else -> 0f - } - } - } - - if (viewerImages.isNotEmpty()) { - ImageViewer( - images = viewerImages, - startIndex = state.fullScreenStartIndex.coerceIn(0, viewerImages.lastIndex), - onDismiss = component::onDismissImages, - autoDownload = autoDownload, - onPageChanged = { index -> - currentImageIndex = index - imageMessageIds.getOrNull(index)?.takeIf { it != 0L }?.let(component::onDownloadHighRes) - imageMessageIds.getOrNull(index + 1)?.takeIf { it != 0L }?.let(component::onDownloadHighRes) - }, - onForward = { path -> - val msg = currentViewerMessage ?: state.messages.find { it.content.matchesDisplayPath(path) } - msg?.let { component.onForwardMessage(it) } - }, - onDelete = { path -> - val msg = currentViewerMessage ?: state.messages.find { it.content.matchesDisplayPath(path) } - if (msg?.isOutgoing == true) { - component.onDeleteMessage(msg) - component.onDismissImages() - } - }, - onCopyLink = { path -> - val msg = currentViewerMessage ?: state.messages.find { it.content.matchesDisplayPath(path) } - val link = if (msg != null) { - if (!state.isGroup && !state.isChannel) { - "tg://openmessage?user_id=${state.chatId}&message_id=${msg.id shr 20}" - } else { - "https://t.me/c/${state.chatId.toString().removePrefix("-100")}/${msg.id shr 20}" - } - } else { - path - } - clipboardManager.setText(AnnotatedString(link)) - }, - onCopyText = { path -> - val msg = currentViewerMessage ?: state.messages.find { it.content.matchesDisplayPath(path) } - val textToCopy = when (val content = msg?.content) { - is MessageContent.Photo -> content.caption - is MessageContent.Video -> content.caption - is MessageContent.Gif -> content.caption - else -> "" - } - if (textToCopy.isNotEmpty()) { - clipboardManager.setText(AnnotatedString(textToCopy)) - } - }, - onVideoClick = { path -> - val msg = currentViewerMessage ?: state.messages.find { it.content.matchesDisplayPath(path) } - if (msg != null) { - val mediaPath = msg.displayMediaPathForViewer() ?: path - component.onOpenVideo( - path = mediaPath, - messageId = msg.id, - caption = when (val content = msg.content) { - is MessageContent.Video -> content.caption - is MessageContent.Gif -> content.caption - else -> null - } - ) - } else { - component.onOpenVideo(path = path) - } - }, - captions = state.fullScreenCaptions, - imageDownloadingStates = imageDownloadingStates, - imageDownloadProgressStates = imageDownloadProgressStates, - downloadUtils = component.downloadUtils - ) - } - } - } - - val videoVisible = - (state.fullScreenVideoPath != null || state.fullScreenVideoMessageId != null) && state.fullScreenImages == null - - AnimatedVisibility( - visible = videoVisible, - enter = fadeIn() + scaleIn(initialScale = 0.9f), - exit = fadeOut() + scaleOut(targetScale = 0.9f) - ) { - if (videoVisible) { - val messageId = state.fullScreenVideoMessageId - val path = state.fullScreenVideoPath - - val msg = remember(messageId, path, state.messages) { - state.messages.find { it.id == messageId } ?: state.messages.find { - it.content.matchesDisplayPath(path ?: "") - } - } - - val videoContent = msg?.content as? MessageContent.Video - val gifContent = msg?.content as? MessageContent.Gif - - val fileId = videoContent?.fileId ?: gifContent?.fileId ?: 0 - val supportsStreaming = videoContent?.supportsStreaming ?: false - val finalPath = path ?: videoContent?.path ?: gifContent?.path ?: "" - - if (finalPath.isNotBlank() || (supportsStreaming && fileId != 0)) { - key(finalPath, fileId) { - Log.d("ChatContentViewers", "Rendering VideoViewer for $finalPath") - VideoViewer( - path = finalPath, - onDismiss = component::onDismissVideo, - isGesturesEnabled = state.isPlayerGesturesEnabled, - isDoubleTapSeekEnabled = state.isPlayerDoubleTapSeekEnabled, - seekDuration = state.playerSeekDuration, - isZoomEnabled = state.isPlayerZoomEnabled, - onForward = { videoPath -> - val forwardMsg = state.messages.find { - it.content.matchesDisplayPath(videoPath) - } - forwardMsg?.let { component.onForwardMessage(it) } - }, - onDelete = { videoPath -> - val deleteMsg = state.messages.find { - it.content.matchesDisplayPath(videoPath) - } - if (deleteMsg?.isOutgoing == true) { - component.onDeleteMessage(deleteMsg) - component.onDismissVideo() - } - }, - onCopyLink = { videoPath -> - val linkMsg = state.messages.find { - it.content.matchesDisplayPath(videoPath) - } - val link = if (linkMsg != null) { - if (!state.isGroup && !state.isChannel) { - "tg://openmessage?user_id=${state.chatId}&message_id=${linkMsg.id shr 20}" - } else { - "https://t.me/c/${ - state.chatId.toString().removePrefix("-100") - }/${linkMsg.id shr 20}" - } - } else { - videoPath - } - clipboardManager.setText(AnnotatedString(link)) - }, - onCopyText = { videoPath -> - val textMsg = state.messages.find { - it.content.matchesDisplayPath(videoPath) - } - val textToCopy = when (val content = textMsg?.content) { - is MessageContent.Video -> content.caption - is MessageContent.Gif -> content.caption - else -> "" - } - if (textToCopy.isNotEmpty()) { - clipboardManager.setText(AnnotatedString(textToCopy)) - } - }, - onSaveGif = if (state.messages.any { (it.content as? MessageContent.Gif)?.path == finalPath }) { - { videoPath -> component.onAddToGifs(videoPath) } - } else null, - caption = state.fullScreenVideoCaption, - fileId = fileId, - supportsStreaming = supportsStreaming, - downloadUtils = component.downloadUtils - ) - } - } - } - } - - if (state.invoiceSlug != null || state.invoiceMessageId != null) { - InvoiceDialog( - slug = state.invoiceSlug, - chatId = state.chatId, - messageId = state.invoiceMessageId, - messageRepository = component.repositoryMessage, - onDismiss = { status -> component.onDismissInvoice(status) } - ) - } - - MiniAppTOSBottomSheet( - isVisible = state.showMiniAppTOS, - onDismiss = { component.onDismissMiniAppTOS() }, - onAccept = { component.onAcceptMiniAppTOS() } - ) -} - -private data class ViewerMediaItem( - val messageId: Long, - val path: String -) - -private fun MessageModel.displayMediaPathForViewer(): String? { - return when (val content = content) { - is MessageContent.Photo -> content.path ?: content.thumbnailPath - is MessageContent.Video -> content.path ?: content.thumbnailPath - is MessageContent.Gif -> content.path - else -> null - } -} - -private fun MessageContent.matchesDisplayPath(path: String): Boolean { - return when (this) { - is MessageContent.Photo -> (this.path ?: this.thumbnailPath) == path - is MessageContent.Video -> this.path == path || this.thumbnailPath == path - is MessageContent.Gif -> this.path == path - else -> false - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatMessageOptionsMenu.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatMessageOptionsMenu.kt deleted file mode 100644 index 19004970..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ChatMessageOptionsMenu.kt +++ /dev/null @@ -1,444 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.chatContent - -import org.monogram.presentation.core.util.coRunCatching -import android.util.Log -import androidx.compose.runtime.* -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.geometry.Rect -import androidx.compose.ui.platform.ClipboardManager -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.unit.IntSize -import androidx.compose.ui.unit.dp -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.launch -import org.koin.compose.koinInject -import org.monogram.domain.models.ChatPermissionsModel -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.domain.models.MessageViewerModel -import org.monogram.domain.repository.MessageRepository -import org.monogram.presentation.R -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.ChatComponent -import org.monogram.presentation.features.stickers.ui.menu.MessageOptionsMenu -import java.util.Locale - -@Composable -fun ChatMessageOptionsMenu( - state: ChatComponent.State, - component: ChatComponent, - selectedMessage: MessageModel, - menuOffset: Offset, - menuMessageSize: IntSize, - clickOffset: Offset, - contentRect: Rect, - groupedMessages: List, - downloadUtils: IDownloadUtils, - clipboardManager: ClipboardManager, - canRestoreOriginalText: Boolean, - onApplyTransformedText: (String) -> Unit, - onRestoreOriginalText: () -> Unit, - onBlockRequest: (Long) -> Unit, - onDismiss: () -> Unit -) { - val messageRepository: MessageRepository = koinInject() - val canCheckViewersList = remember(state.isChannel, state.isGroup, state.memberCount) { - !state.isChannel && (!state.isGroup || state.memberCount in 1 until 100) - } - val messageViewsCount = remember(selectedMessage.viewCount, selectedMessage.views) { - selectedMessage.viewCount ?: selectedMessage.views - } - val shouldShowViewsInfo = remember(state.isChannel, messageViewsCount) { - state.isChannel && (messageViewsCount ?: 0) > 0 - } - - val index = groupedMessages.indexOfFirst { item -> - when (item) { - is GroupedMessageItem.Single -> item.message.id == selectedMessage.id - is GroupedMessageItem.Album -> item.messages.any { it.id == selectedMessage.id } - } - } - val olderMsg = if (index != -1) { - when (val olderItem = groupedMessages.getOrNull(index + 1)) { - is GroupedMessageItem.Single -> olderItem.message - is GroupedMessageItem.Album -> olderItem.messages.last() - null -> null - } - } else null - val newerMsg = if (index != -1) { - when (val newerItem = groupedMessages.getOrNull(index - 1)) { - is GroupedMessageItem.Single -> newerItem.message - is GroupedMessageItem.Album -> newerItem.messages.first() - null -> null - } - } else null - - var messageWithReadDate by remember(selectedMessage) { mutableStateOf(selectedMessage) } - var messageViewers by remember(selectedMessage) { mutableStateOf>(emptyList()) } - var isLoadingViewers by remember(selectedMessage) { mutableStateOf(false) } - val scope = rememberCoroutineScope() - - LaunchedEffect(selectedMessage, canCheckViewersList) { - if (canCheckViewersList && - selectedMessage.isOutgoing && - selectedMessage.canGetReadReceipts && - selectedMessage.readDate == 0 - ) { - scope.launch { - val readDate = component.getMessageReadDate(selectedMessage.chatId, selectedMessage.id, selectedMessage.date) - if (readDate > 0) { - messageWithReadDate = selectedMessage.copy(readDate = readDate) - } - } - } - } - - val canShowViewersList = remember(state.memberCount, state.isChannel, selectedMessage) { - state.memberCount in 1 until 100 && - selectedMessage.isOutgoing && - (selectedMessage.canGetReadReceipts || selectedMessage.canGetViewers || !state.isChannel) - } - - suspend fun reloadViewers() { - if (!canShowViewersList) return - isLoadingViewers = true - messageViewers = component - .getMessageViewers(selectedMessage.chatId, selectedMessage.id) - .sortedByDescending { it.viewedDate } - isLoadingViewers = false - } - - LaunchedEffect(selectedMessage, canShowViewersList) { - if (canShowViewersList) { - reloadViewers() - } - } - - val density = LocalDensity.current - - val nextMsgText = (newerMsg?.content as? MessageContent.Text)?.text - val currentCaption = when (val c = selectedMessage.content) { - is MessageContent.Photo -> c.caption - is MessageContent.Video -> c.caption - is MessageContent.Gif -> c.caption - else -> null - } - val isCaptionSameAsNext = currentCaption != null && currentCaption.isNotEmpty() && currentCaption == nextMsgText - val shouldShowSeparatePost = currentCaption != null && currentCaption.isNotEmpty() && !isCaptionSameAsNext - - val splitOffset = remember(selectedMessage, menuMessageSize, density, shouldShowSeparatePost) { - if (!shouldShowSeparatePost) return@remember null - - val isChannel = state.isChannel && state.currentTopicId == null - val width = menuMessageSize.width.toFloat() - - when (val content = selectedMessage.content) { - is MessageContent.Photo -> { - val ratio = if (content.width > 0 && content.height > 0) - (content.width.toFloat() / content.height.toFloat()).let { - if (isChannel) it.coerceIn(0.6f, 1.8f) else it.coerceIn(0.5f, 2f) - } - else 1f - - val height = width / ratio - val maxHeight = with(density) { - if (isChannel) 450.dp.toPx() else 320.dp.toPx() - } - val minHeight = with(density) { - if (isChannel) 130.dp.toPx() else 0f - } - - height.coerceIn(minHeight, maxHeight).toInt() - } - - is MessageContent.Video -> { - val ratio = if (content.width > 0 && content.height > 0) - (content.width.toFloat() / content.height.toFloat()).let { - if (isChannel) it.coerceIn(0.6f, 1.8f) else it.coerceIn(0.5f, 2f) - } - else 1f - - val height = width / ratio - val maxHeight = with(density) { - if (isChannel) 420.dp.toPx() else 500.dp.toPx() - } - val minHeight = with(density) { - if (isChannel) 130.dp.toPx() else 0f - } - - height.coerceIn(minHeight, maxHeight).toInt() - } - - is MessageContent.Gif -> { - val ratio = if (content.width > 0 && content.height > 0) - (content.width.toFloat() / content.height.toFloat()).let { - if (isChannel) it else it.coerceIn(0.5f, 2f) - } - else 1f - - val height = width / ratio - val maxHeight = with(density) { - if (isChannel) 600.dp.toPx() else 400.dp.toPx() - } - val minHeight = with(density) { - if (isChannel) 0f else 160.dp.toPx() - } - - height.coerceIn(minHeight, maxHeight).toInt() - } - - else -> null - } - } - - val senderIsUser = selectedMessage.senderId > 0L - val canModerateInChat = (state.isGroup || state.isChannel) && state.isAdmin - val canBlockUser = !selectedMessage.isOutgoing && senderIsUser && - (canModerateInChat || (!state.isGroup && !state.isChannel)) - val canRestrictUser = canBlockUser && (state.isGroup || state.isChannel) && state.isAdmin - val isOtherUserDialog = state.otherUser?.id?.let { it != state.currentUser?.id } == true - val canReportMessage = !selectedMessage.isOutgoing && ( - state.isGroup || state.isChannel || - isOtherUserDialog - ) - val canCopyLink = state.isGroup || state.isChannel - val canPinMessages = state.isAdmin || state.permissions.canPinMessages - val isPremiumUser = state.currentUser?.isPremium == true - val canUseTelegramSummary = isPremiumUser && canSummarize(selectedMessage) - val canUseTelegramTranslator = isPremiumUser && canTranslate(selectedMessage) - val cocoonAttribution = stringResource(R.string.telegram_cocoon_attribution) - MessageOptionsMenu( - message = messageWithReadDate, - canWrite = state.canWrite, - canPinMessages = canPinMessages, - isPinned = selectedMessage.id == state.pinnedMessage?.id, - messageOffset = menuOffset, - messageSize = menuMessageSize, - clickOffset = clickOffset, - contentRect = contentRect, - isSameSenderAbove = olderMsg?.senderId == selectedMessage.senderId && !shouldShowDate( - selectedMessage, - olderMsg - ), - isSameSenderBelow = newerMsg != null && newerMsg.senderId == selectedMessage.senderId && !shouldShowDate( - newerMsg, - selectedMessage - ), - showReadInfo = canCheckViewersList, - showViewsInfo = shouldShowViewsInfo, - showViewersList = canShowViewersList, - canReport = canReportMessage, - canBlock = canBlockUser, - canRestrict = canRestrictUser, - canCopyLink = canCopyLink, - showTelegramSummary = canUseTelegramSummary, - showTelegramTranslator = canUseTelegramTranslator, - showRestoreOriginalText = canRestoreOriginalText, - viewers = messageViewers, - isLoadingViewers = isLoadingViewers, - onReloadViewers = { - scope.launch { reloadViewers() } - }, - onViewerClick = { component.toProfile(it) }, - videoPlayerPool = component.videoPlayerPool, - bubbleRadius = state.bubbleRadius, - splitOffset = splitOffset, - onReply = { - component.onReplyMessage(selectedMessage) - onDismiss() - }, - onPin = { - if (selectedMessage.id == state.pinnedMessage?.id) component.onUnpinMessage(selectedMessage) else component.onPinMessage( - selectedMessage - ) - onDismiss() - }, - onEdit = { - component.onEditMessage(selectedMessage) - onDismiss() - }, - onDelete = { revoke -> - component.onDeleteMessage(selectedMessage, revoke) - onDismiss() - }, - onForward = { - component.onForwardMessage(selectedMessage) - onDismiss() - }, - onSelect = { - component.onToggleMessageSelection(selectedMessage.id) - onDismiss() - }, - onCopyLink = { - val link = if (!state.isGroup && !state.isChannel) { - "tg://openmessage?user_id=${state.chatId}&message_id=${selectedMessage.id shr 20}" - } else { - "https://t.me/c/${state.chatId.toString().removePrefix("-100")}/${selectedMessage.id shr 20}" - } - clipboardManager.setText(AnnotatedString(link)) - onDismiss() - }, - onCopy = { - val textToCopy = when (val content = selectedMessage.content) { - is MessageContent.Text -> content.text - is MessageContent.Photo -> content.caption - is MessageContent.Video -> content.caption - is MessageContent.Gif -> content.caption - else -> "" - } - if (textToCopy.isNotEmpty()) { - clipboardManager.setText(AnnotatedString(textToCopy)) - } - onDismiss() - }, - onSaveToDownloads = { - val path = when (val content = selectedMessage.content) { - is MessageContent.Photo -> content.path - is MessageContent.Video -> content.path - is MessageContent.Gif -> content.path - is MessageContent.Document -> content.path - is MessageContent.Voice -> content.path - is MessageContent.VideoNote -> content.path - else -> null - } - path?.let { - downloadUtils.saveFileToDownloads(it) - } - onDismiss() - }, - onReaction = { reaction -> - component.onSendReaction(selectedMessage.id, reaction) - onDismiss() - }, - onComments = { - component.onCommentsClick(selectedMessage.id) - onDismiss() - }, - onTelegramSummary = { - telegramAiScope.launch { - coRunCatching { - messageRepository.summarizeMessage( - chatId = selectedMessage.chatId, - messageId = selectedMessage.id - ) - }.onSuccess { summary -> - if (!summary.isNullOrBlank()) { - val transformed = summary.withCocoonAttribution(cocoonAttribution) - Log.d( - TELEGRAM_AI_LOG_TAG, - "summary_applied chatId=${selectedMessage.chatId} messageId=${selectedMessage.id} resultLength=${transformed.length}" - ) - onApplyTransformedText(transformed) - onDismiss() - } else { - Log.d( - TELEGRAM_AI_LOG_TAG, - "summary_empty chatId=${selectedMessage.chatId} messageId=${selectedMessage.id}" - ) - } - }.onFailure { error -> - Log.e( - TELEGRAM_AI_LOG_TAG, - "summary_failed chatId=${selectedMessage.chatId} messageId=${selectedMessage.id}", - error - ) - } - } - }, - onTelegramTranslator = { - telegramAiScope.launch { - val languageCode = state.currentUser?.languageCode?.takeIf { it.isNotBlank() } - ?: Locale.getDefault().language - coRunCatching { - messageRepository.translateMessage( - chatId = selectedMessage.chatId, - messageId = selectedMessage.id, - toLanguageCode = languageCode - ) - }.onSuccess { translation -> - if (!translation.isNullOrBlank()) { - val transformed = translation.withCocoonAttribution(cocoonAttribution) - Log.d( - TELEGRAM_AI_LOG_TAG, - "translation_applied chatId=${selectedMessage.chatId} messageId=${selectedMessage.id} language=$languageCode resultLength=${transformed.length}" - ) - onApplyTransformedText(transformed) - onDismiss() - } else { - Log.d( - TELEGRAM_AI_LOG_TAG, - "translation_empty chatId=${selectedMessage.chatId} messageId=${selectedMessage.id} language=$languageCode" - ) - } - }.onFailure { error -> - Log.e( - TELEGRAM_AI_LOG_TAG, - "translation_failed chatId=${selectedMessage.chatId} messageId=${selectedMessage.id} language=$languageCode", - error - ) - } - } - }, - onRestoreOriginalText = { - Log.d( - TELEGRAM_AI_LOG_TAG, - "restore_original chatId=${selectedMessage.chatId} messageId=${selectedMessage.id}" - ) - onRestoreOriginalText() - onDismiss() - }, - onReport = { - component.onReportMessage(selectedMessage) - onDismiss() - }, - onBlock = { - if (selectedMessage.senderId > 0L) { - onBlockRequest(selectedMessage.senderId) - } - onDismiss() - }, - onRestrict = { - if (selectedMessage.senderId > 0L) { - component.onRestrictUser(selectedMessage.senderId, ChatPermissionsModel()) - } - onDismiss() - }, - onDismiss = onDismiss - ) -} - -private fun String.withCocoonAttribution(attribution: String): String { - val cleanText = trim() - return "$cleanText\n\n$attribution" -} - -private const val TELEGRAM_AI_LOG_TAG = "TelegramAiActions" -private val telegramAiScope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate) - -private fun canTranslate(message: MessageModel): Boolean { - return when (val content = message.content) { - is MessageContent.Text -> content.text.isNotBlank() - is MessageContent.Photo -> content.caption.isNotBlank() - is MessageContent.Video -> content.caption.isNotBlank() - is MessageContent.Gif -> content.caption.isNotBlank() - is MessageContent.Document -> content.caption.isNotBlank() - is MessageContent.Audio -> content.caption.isNotBlank() - else -> false - } -} - -private fun canSummarize(message: MessageModel): Boolean { - return when (val content = message.content) { - is MessageContent.Text -> content.text.isNotBlank() - is MessageContent.Photo -> content.caption.isNotBlank() - is MessageContent.Video -> content.caption.isNotBlank() - is MessageContent.Gif -> content.caption.isNotBlank() - is MessageContent.Document -> content.caption.isNotBlank() - is MessageContent.Audio -> content.caption.isNotBlank() - else -> false - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/DeleteMessagesSheet.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/DeleteMessagesSheet.kt deleted file mode 100644 index af60c207..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/DeleteMessagesSheet.kt +++ /dev/null @@ -1,113 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.chatContent - -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Delete -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.presentation.R - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun DeleteMessagesSheet( - count: Int, - canRevoke: Boolean, - onDismiss: () -> Unit, - onDelete: (revoke: Boolean) -> Unit -) { - ModalBottomSheet( - onDismissRequest = onDismiss, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 32.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Icon( - imageVector = Icons.Rounded.Delete, - contentDescription = null, - modifier = Modifier.size(48.dp), - tint = MaterialTheme.colorScheme.error - ) - - Spacer(modifier = Modifier.height(16.dp)) - - Text( - text = if (count > 1) stringResource(R.string.delete_messages_title, count) else stringResource(R.string.delete_message_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - textAlign = TextAlign.Center - ) - - Spacer(modifier = Modifier.height(8.dp)) - - Text( - text = if (count > 1) stringResource(R.string.delete_messages_confirmation) else stringResource(R.string.delete_message_confirmation), - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center - ) - - Spacer(modifier = Modifier.height(24.dp)) - - Column( - modifier = Modifier.fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(12.dp) - ) { - if (canRevoke) { - Button( - onClick = { onDelete(true) }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp), - colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.errorContainer, - contentColor = MaterialTheme.colorScheme.onErrorContainer - ) - ) { - Text(stringResource(R.string.delete_for_everyone), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - - Button( - onClick = { onDelete(false) }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp), - colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.error, - contentColor = MaterialTheme.colorScheme.onError - ) - ) { - Text(stringResource(R.string.delete_for_me), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - - OutlinedButton( - onClick = onDismiss, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.cancel_button), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ReportChatDialog.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ReportChatDialog.kt deleted file mode 100644 index 10ff0110..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/ReportChatDialog.kt +++ /dev/null @@ -1,226 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.chatContent - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.outlined.KeyboardArrowRight -import androidx.compose.material.icons.outlined.* -import androidx.compose.material.icons.rounded.Edit -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.presentation.R -import org.monogram.presentation.features.chats.chatList.components.SettingsTextField -import org.monogram.presentation.core.ui.ItemPosition - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ReportChatDialog( - onDismiss: () -> Unit, - onReasonSelected: (String) -> Unit -) { - var showCustomInput by remember { mutableStateOf(false) } - var customText by remember { mutableStateOf("") } - - val reasons = listOf( - ReportReason("spam", stringResource(R.string.report_reason_spam), stringResource(R.string.report_reason_spam_description), Icons.Outlined.Report), - ReportReason("violence", stringResource(R.string.report_reason_violence), stringResource(R.string.report_reason_violence_description), Icons.Outlined.Gavel), - ReportReason( - "pornography", - stringResource(R.string.report_reason_pornography), - stringResource(R.string.report_reason_pornography_description), - Icons.Outlined.NoAdultContent - ), - ReportReason("child_abuse", stringResource(R.string.report_reason_child_abuse), stringResource(R.string.report_reason_child_abuse_description), Icons.Outlined.ChildCare), - ReportReason("copyright", stringResource(R.string.report_reason_copyright), stringResource(R.string.report_reason_copyright_description), Icons.Outlined.Copyright), - ReportReason("fake", stringResource(R.string.report_reason_fake), stringResource(R.string.report_reason_fake_description), Icons.Outlined.AccountCircle), - ReportReason( - "illegal_drugs", - stringResource(R.string.report_reason_illegal_drugs), - stringResource(R.string.report_reason_illegal_drugs_description), - Icons.Outlined.Warning - ), - ReportReason( - "personal_details", - stringResource(R.string.report_reason_personal_details), - stringResource(R.string.report_reason_personal_details_description), - Icons.Outlined.VisibilityOff - ), - ReportReason( - "unrelated_location", - stringResource(R.string.report_reason_unrelated_location), - stringResource(R.string.report_reason_unrelated_location_description), - Icons.Outlined.LocationOff - ), - ReportReason("custom", stringResource(R.string.report_reason_other), stringResource(R.string.report_reason_other_description), Icons.Outlined.MoreHoriz) - ) - - ModalBottomSheet( - onDismissRequest = onDismiss, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .navigationBarsPadding() - ) { - if (!showCustomInput) { - Column( - modifier = Modifier - .padding(horizontal = 24.dp, vertical = 8.dp) - .padding(bottom = 16.dp) - ) { - Text( - text = stringResource(R.string.report_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - Spacer(modifier = Modifier.height(4.dp)) - Text( - text = stringResource(R.string.report_description), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - - LazyColumn( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 24.dp) - ) { - itemsIndexed(reasons) { _, reason -> - if (reason.id == "custom") { - HorizontalDivider( - modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp), - thickness = 0.5.dp, - color = MaterialTheme.colorScheme.outlineVariant - ) - } - - ReportReasonItem( - reason = reason, - onClick = { - if (reason.id == "custom") { - showCustomInput = true - } else { - onReasonSelected(reason.id) - } - } - ) - } - } - } else { - Column( - modifier = Modifier - .padding(horizontal = 24.dp, vertical = 8.dp) - .padding(bottom = 32.dp) - ) { - Text( - text = stringResource(R.string.report_details_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - Spacer(modifier = Modifier.height(16.dp)) - - SettingsTextField( - value = customText, - onValueChange = { customText = it }, - placeholder = stringResource(R.string.report_details_placeholder), - icon = Icons.Rounded.Edit, - position = ItemPosition.STANDALONE, - minLines = 3 - ) - - Spacer(modifier = Modifier.height(24.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - OutlinedButton( - onClick = { showCustomInput = false }, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.cd_back), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - - Button( - onClick = { onReasonSelected(customText) }, - enabled = customText.isNotBlank(), - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.report_send), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } - } - } - } -} - -@Composable -private fun ReportReasonItem( - reason: ReportReason, - onClick: () -> Unit -) { - ListItem( - modifier = Modifier.clickable(onClick = onClick), - headlineContent = { - Text( - text = reason.label, - style = MaterialTheme.typography.bodyLarge, - fontWeight = FontWeight.Medium - ) - }, - supportingContent = { - Text( - text = reason.description, - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - }, - leadingContent = { - Icon( - imageVector = reason.icon, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.size(24.dp) - ) - }, - trailingContent = { - Icon( - imageVector = Icons.AutoMirrored.Outlined.KeyboardArrowRight, - contentDescription = null, - tint = MaterialTheme.colorScheme.outline, - modifier = Modifier.size(20.dp) - ) - }, - colors = ListItemDefaults.colors( - containerColor = Color.Transparent - ) - ) -} - -private data class ReportReason( - val id: String, - val label: String, - val description: String, - val icon: ImageVector -) diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/RestrictUserSheet.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/RestrictUserSheet.kt deleted file mode 100644 index ec49902a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/chatContent/RestrictUserSheet.kt +++ /dev/null @@ -1,260 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.chatContent - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.AccessTime -import androidx.compose.material.icons.rounded.CalendarToday -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.ChatPermissionsModel -import org.monogram.presentation.R -import java.text.SimpleDateFormat -import java.util.* - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun RestrictUserSheet( - onDismiss: () -> Unit, - onConfirm: (ChatPermissionsModel, Int) -> Unit -) { - var permissions by remember { mutableStateOf(ChatPermissionsModel()) } - var untilDate by remember { mutableIntStateOf(0) } - var showDatePicker by remember { mutableStateOf(false) } - var showTimePicker by remember { mutableStateOf(false) } - - val calendar = remember(untilDate) { - Calendar.getInstance().apply { - if (untilDate != 0) { - timeInMillis = untilDate.toLong() * 1000 - } - } - } - - if (showDatePicker) { - val datePickerState = rememberDatePickerState( - initialSelectedDateMillis = if (untilDate != 0) untilDate.toLong() * 1000 else System.currentTimeMillis() - ) - DatePickerDialog( - onDismissRequest = { showDatePicker = false }, - confirmButton = { - TextButton(onClick = { - datePickerState.selectedDateMillis?.let { - val newCalendar = Calendar.getInstance().apply { - timeInMillis = it - if (untilDate != 0) { - val oldCal = Calendar.getInstance().apply { timeInMillis = untilDate.toLong() * 1000 } - set(Calendar.HOUR_OF_DAY, oldCal.get(Calendar.HOUR_OF_DAY)) - set(Calendar.MINUTE, oldCal.get(Calendar.MINUTE)) - } - } - untilDate = (newCalendar.timeInMillis / 1000).toInt() - } - showDatePicker = false - }) { - Text(stringResource(R.string.ok_button)) - } - }, - dismissButton = { - TextButton(onClick = { showDatePicker = false }) { - Text(stringResource(R.string.cancel_button)) - } - } - ) { - DatePicker(state = datePickerState) - } - } - - if (showTimePicker) { - val timePickerState = rememberTimePickerState( - initialHour = calendar.get(Calendar.HOUR_OF_DAY), - initialMinute = calendar.get(Calendar.MINUTE) - ) - AlertDialog( - onDismissRequest = { showTimePicker = false }, - confirmButton = { - TextButton(onClick = { - val newCalendar = Calendar.getInstance().apply { - if (untilDate != 0) { - timeInMillis = untilDate.toLong() * 1000 - } - set(Calendar.HOUR_OF_DAY, timePickerState.hour) - set(Calendar.MINUTE, timePickerState.minute) - } - untilDate = (newCalendar.timeInMillis / 1000).toInt() - showTimePicker = false - }) { - Text(stringResource(R.string.ok_button)) - } - }, - dismissButton = { - TextButton(onClick = { showTimePicker = false }) { - Text(stringResource(R.string.cancel_button)) - } - }, - text = { - TimePicker(state = timePickerState) - } - ) - } - - ModalBottomSheet( - onDismissRequest = onDismiss, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 32.dp) - ) { - Text( - text = stringResource(R.string.restrict_user_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(horizontal = 4.dp) - ) - - Spacer(modifier = Modifier.height(16.dp)) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - Column( - modifier = Modifier - .padding(8.dp) - .verticalScroll(rememberScrollState()) - ) { - PermissionToggle(stringResource(R.string.permission_send_messages), permissions.canSendBasicMessages) { - permissions = permissions.copy(canSendBasicMessages = it) - } - PermissionToggle(stringResource(R.string.permission_send_media), permissions.canSendPhotos && permissions.canSendVideos) { - permissions = permissions.copy( - canSendPhotos = it, - canSendVideos = it, - canSendAudios = it, - canSendDocuments = it, - canSendVideoNotes = it, - canSendVoiceNotes = it - ) - } - PermissionToggle(stringResource(R.string.permission_send_stickers_gifs), permissions.canSendOtherMessages) { - permissions = permissions.copy(canSendOtherMessages = it) - } - PermissionToggle(stringResource(R.string.permission_send_polls), permissions.canSendPolls) { - permissions = permissions.copy(canSendPolls = it) - } - PermissionToggle( - stringResource(R.string.permission_embed_links), - permissions.canAddLinkPreviews - ) { - permissions = permissions.copy(canAddLinkPreviews = it) - } - PermissionToggle(stringResource(R.string.permission_pin_messages), permissions.canPinMessages) { - permissions = permissions.copy(canPinMessages = it) - } - PermissionToggle(stringResource(R.string.permission_change_chat_info), permissions.canChangeInfo) { - permissions = permissions.copy(canChangeInfo = it) - } - - HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp)) - - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 12.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Column(modifier = Modifier.weight(1f)) { - Text(stringResource(R.string.restrict_until), style = MaterialTheme.typography.bodyLarge) - Text( - text = if (untilDate == 0) stringResource(R.string.restrict_forever) else SimpleDateFormat( - "MMM d, yyyy, HH:mm", - Locale.getDefault() - ).format(Date(untilDate.toLong() * 1000)), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.primary - ) - } - Row { - IconButton(onClick = { showDatePicker = true }) { - Icon(Icons.Rounded.CalendarToday, contentDescription = stringResource(R.string.cd_select_date)) - } - IconButton(onClick = { showTimePicker = true }) { - Icon(Icons.Rounded.AccessTime, contentDescription = stringResource(R.string.cd_select_time)) - } - } - } - } - } - - Spacer(modifier = Modifier.height(24.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - OutlinedButton( - onClick = onDismiss, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.cancel_button), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - - Button( - onClick = { onConfirm(permissions, untilDate) }, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.action_restrict), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } - } -} - -@Composable -private fun PermissionToggle( - label: String, - checked: Boolean, - onCheckedChange: (Boolean) -> Unit -) { - Row( - modifier = Modifier - .fillMaxWidth() - .clickable { onCheckedChange(!checked) } - .padding(horizontal = 12.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Text(label, style = MaterialTheme.typography.bodyLarge) - Switch( - checked = checked, - onCheckedChange = onCheckedChange, - colors = SwitchDefaults.colors( - checkedThumbColor = MaterialTheme.colorScheme.primary, - checkedTrackColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.5f) - ) - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/AdvancedCircularRecorderScreen.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/AdvancedCircularRecorderScreen.kt deleted file mode 100644 index 344ae121..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/AdvancedCircularRecorderScreen.kt +++ /dev/null @@ -1,1038 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components - -import android.Manifest -import android.annotation.SuppressLint -import android.content.Context -import android.content.pm.PackageManager -import android.graphics.SurfaceTexture -import android.media.* -import android.opengl.EGL14 -import android.opengl.EGLExt -import android.opengl.GLES11Ext -import android.opengl.GLES20 -import android.util.Size -import android.view.Surface -import android.widget.Toast -import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import androidx.camera.core.Camera -import androidx.camera.core.CameraSelector -import androidx.camera.core.FocusMeteringAction -import androidx.camera.core.Preview -import androidx.camera.core.resolutionselector.AspectRatioStrategy -import androidx.camera.core.resolutionselector.ResolutionSelector -import androidx.camera.core.resolutionselector.ResolutionStrategy -import androidx.camera.lifecycle.ProcessCameraProvider -import androidx.camera.video.* -import androidx.camera.view.PreviewView -import androidx.compose.animation.animateColorAsState -import androidx.compose.animation.core.* -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.gestures.detectTransformGestures -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Cameraswitch -import androidx.compose.material.icons.filled.Check -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.Stop -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalLifecycleOwner -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.viewinterop.AndroidView -import androidx.compose.ui.window.Dialog -import androidx.compose.ui.window.DialogProperties -import androidx.core.content.ContextCompat -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.monogram.presentation.R -import java.io.File -import java.nio.ByteBuffer -import java.nio.ByteOrder -import java.nio.FloatBuffer -import java.util.* - -private const val EGL_RECORDABLE_ANDROID = 0x3142 - -@Composable -fun AdvancedCircularRecorderScreen( - onClose: () -> Unit, - onVideoRecorded: (File) -> Unit -) { - val context = LocalContext.current - var hasPermissions by remember { - mutableStateOf( - ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED && - ContextCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED - ) - } - - val launcher = rememberLauncherForActivityResult( - contract = ActivityResultContracts.RequestMultiplePermissions(), - onResult = { perms -> hasPermissions = perms.values.all { it } } - ) - - LaunchedEffect(key1 = true) { - if (!hasPermissions) { - launcher.launch(arrayOf(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO)) - } - } - - Dialog( - onDismissRequest = onClose, - properties = DialogProperties( - dismissOnBackPress = true, - dismissOnClickOutside = false, - usePlatformDefaultWidth = false, - decorFitsSystemWindows = false - ) - ) { - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.Black) - ) { - if (hasPermissions) { - NativeCircularCameraContent(onClose, onVideoRecorded) - } else { - Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { - Text(stringResource(R.string.recorder_permissions_required)) - } - } - } - } -} - -@SuppressLint("MissingPermission", "RestrictedApi") -@Composable -fun NativeCircularCameraContent( - onClose: () -> Unit, - onVideoRecorded: (File) -> Unit -) { - val context = LocalContext.current - val lifecycleOwner = LocalLifecycleOwner.current - val coroutineScope = rememberCoroutineScope() - - val recordedSegments = remember { mutableStateListOf() } - var recording by remember { mutableStateOf(null) } - - var isRecording by remember { mutableStateOf(false) } - var isProcessing by remember { mutableStateOf(false) } - - var isSwitchingCamera by remember { mutableStateOf(false) } - var pendingResume by remember { mutableStateOf(false) } - var shouldDiscardAll by remember { mutableStateOf(false) } - var recordingStartMs by remember { mutableLongStateOf(0L) } - var elapsedSeconds by remember { mutableLongStateOf(0L) } - - var lensFacing by remember { mutableIntStateOf(CameraSelector.LENS_FACING_BACK) } - var camera by remember { mutableStateOf(null) } - var currentZoomRatio by remember { mutableFloatStateOf(1f) } - var minZoom by remember { mutableFloatStateOf(1f) } - var maxZoom by remember { mutableFloatStateOf(1f) } - val zoomRounded = ((currentZoomRatio * 10f).toInt() / 10f) - val minZoomRounded = ((minZoom * 10f).toInt() / 10f) - val maxZoomRounded = ((maxZoom * 10f).toInt() / 10f) - - val pulseTransition = rememberInfiniteTransition(label = "rec_pulse") - val recDotScale by pulseTransition.animateFloat( - initialValue = 0.9f, - targetValue = 1.2f, - animationSpec = infiniteRepeatable( - animation = tween(durationMillis = 700, easing = LinearEasing), - repeatMode = RepeatMode.Reverse - ), - label = "rec_dot_scale" - ) - val recDotAlpha by pulseTransition.animateFloat( - initialValue = 0.55f, - targetValue = 1f, - animationSpec = infiniteRepeatable( - animation = tween(durationMillis = 700, easing = LinearEasing), - repeatMode = RepeatMode.Reverse - ), - label = "rec_dot_alpha" - ) - - val recordInnerSize by animateDpAsState( - targetValue = if (isRecording) 34.dp else 72.dp, - animationSpec = tween(durationMillis = 220), - label = "record_inner_size" - ) - val recordInnerColor by animateColorAsState( - targetValue = if (isRecording) Color(0xFFFF3B30) else Color.White, - animationSpec = tween(durationMillis = 220), - label = "record_inner_color" - ) - val preview = remember { Preview.Builder().build() } - val previewView = remember { - PreviewView(context).apply { - implementationMode = PreviewView.ImplementationMode.COMPATIBLE - scaleType = PreviewView.ScaleType.FILL_CENTER - } - } - - val videoCapture = remember { - val recorder = Recorder.Builder() - .setQualitySelector(QualitySelector.from(Quality.SD)) - .build() - - val resolutionSelector = ResolutionSelector.Builder() - .setAspectRatioStrategy(AspectRatioStrategy.RATIO_4_3_FALLBACK_AUTO_STRATEGY) - .setResolutionStrategy(ResolutionStrategy(Size(640, 480), ResolutionStrategy.FALLBACK_RULE_CLOSEST_HIGHER)) - .build() - - VideoCapture.Builder(recorder) - .setResolutionSelector(resolutionSelector) - .build() - } - - DisposableEffect(Unit) { - onDispose { - try { - val cameraProvider = ProcessCameraProvider.getInstance(context).get() - cameraProvider.unbindAll() - } catch (e: Exception) { - e.printStackTrace() - } - } - } - - fun finishRecording() { - if (recordedSegments.isEmpty()) { - isRecording = false - recording = null - recordingStartMs = 0L - elapsedSeconds = 0L - return - } - isProcessing = true - isRecording = false - recording = null - recordingStartMs = 0L - elapsedSeconds = 0L - try { - val cameraProvider = ProcessCameraProvider.getInstance(context).get() - cameraProvider.unbindAll() - } catch (e: Exception) { e.printStackTrace() } - - coroutineScope.launch(Dispatchers.IO) { - val finalFile = File(context.filesDir, "CIRCLE_FULL_${System.currentTimeMillis()}.mp4") - try { - val segmentsToProcess = ArrayList(recordedSegments) - val transcoder = CircularTranscoder(segmentsToProcess, finalFile) - transcoder.start() - - withContext(Dispatchers.Main) { - onVideoRecorded(finalFile) - } - - segmentsToProcess.forEach { it.delete() } - } catch (e: Exception) { - e.printStackTrace() - withContext(Dispatchers.Main) { - val message = context.getString( - R.string.recorder_processing_error, - e.message ?: "" - ) - Toast.makeText(context, message, Toast.LENGTH_SHORT).show() - } - } finally { - recordedSegments.clear() - isProcessing = false - } - } - } - - LaunchedEffect(isRecording, recordingStartMs) { - if (isRecording && recordingStartMs > 0L) { - while (isRecording) { - elapsedSeconds = ((System.currentTimeMillis() - recordingStartMs) / 1000L).coerceAtLeast(0L) - delay(250) - } - } else { - elapsedSeconds = 0L - } - } - - fun cancelAndClose() { - shouldDiscardAll = true - isSwitchingCamera = false - pendingResume = false - - if (isRecording) { - recording?.stop() - return - } - - recordedSegments.forEach { it.delete() } - recordedSegments.clear() - recording = null - recordingStartMs = 0L - elapsedSeconds = 0L - shouldDiscardAll = false - onClose() - } - - fun handleSegmentSaved(file: File) { - if (shouldDiscardAll) { - file.delete() - recordedSegments.forEach { it.delete() } - recordedSegments.clear() - isRecording = false - recording = null - recordingStartMs = 0L - elapsedSeconds = 0L - shouldDiscardAll = false - onClose() - return - } - - recordedSegments.add(file) - if (isSwitchingCamera) { - lensFacing = if (lensFacing == CameraSelector.LENS_FACING_FRONT) { - CameraSelector.LENS_FACING_BACK - } else { - CameraSelector.LENS_FACING_FRONT - } - } else { - finishRecording() - } - } - - LaunchedEffect(lensFacing) { - val cameraProvider = ProcessCameraProvider.getInstance(context).get() - val cameraSelector = CameraSelector.Builder().requireLensFacing(lensFacing).build() - try { - cameraProvider.unbindAll() - val cam = cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview, videoCapture) - camera = cam - cam.cameraInfo.zoomState.observe(lifecycleOwner) { state -> - currentZoomRatio = state.zoomRatio - minZoom = state.minZoomRatio - maxZoom = state.maxZoomRatio - } - preview.surfaceProvider = previewView.surfaceProvider - - if (pendingResume) { - pendingResume = false - isSwitchingCamera = false - - startNativeSegment( - context, - videoCapture, - onStart = { rec -> recording = rec }, - onSegmentSaved = ::handleSegmentSaved - ) - } - } catch (e: Exception) { e.printStackTrace() } - } - - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.Black) - ) { - Box( - modifier = Modifier - .fillMaxSize() - .pointerInput(Unit) { - detectTransformGestures { _, _, zoom, _ -> - camera?.let { cam -> - val newZoom = (currentZoomRatio * zoom).coerceIn(minZoom, maxZoom) - cam.cameraControl.setZoomRatio(newZoom) - } - } - } - .pointerInput(Unit) { - detectTapGestures { offset -> - camera?.let { cam -> - val point = previewView.meteringPointFactory.createPoint(offset.x, offset.y) - cam.cameraControl.startFocusAndMetering(FocusMeteringAction.Builder(point).build()) - } - } - } - ) { - AndroidView(factory = { previewView }, modifier = Modifier.matchParentSize()) - - Box( - modifier = Modifier - .matchParentSize() - .background( - Brush.radialGradient( - colors = listOf( - Color.Transparent, - Color.Transparent, - Color.Black.copy(alpha = 0.6f) - ) - ) - ) - ) - - Box( - modifier = Modifier - .align(Alignment.Center) - .size(390.dp) - .clip(CircleShape) - .border(2.dp, Color.White.copy(alpha = 0.9f), CircleShape) - ) - } - - Column( - modifier = Modifier - .fillMaxSize() - .padding(horizontal = 20.dp, vertical = 12.dp), - verticalArrangement = Arrangement.SpaceBetween - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .statusBarsPadding() - ) { - IconButton(onClick = onClose, enabled = !isRecording && !isProcessing) { - Icon( - Icons.Default.Close, - contentDescription = stringResource(R.string.recorder_close_cd), - tint = Color.White - ) - } - } - - Column( - modifier = Modifier - .fillMaxWidth() - .navigationBarsPadding(), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Row( - modifier = Modifier - .clip(RoundedCornerShape(999.dp)) - .background(Color.Black.copy(alpha = 0.45f)) - .border(1.dp, Color.White.copy(alpha = 0.2f), RoundedCornerShape(999.dp)) - .padding(horizontal = 10.dp, vertical = 6.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(8.dp) - .graphicsLayer { - scaleX = if (isRecording) recDotScale else 1f - scaleY = if (isRecording) recDotScale else 1f - alpha = if (isRecording) recDotAlpha else 0.5f - } - .clip(CircleShape) - .background(if (isRecording) Color(0xFFFF453A) else Color(0xFF8E8E93)) - ) - Spacer(modifier = Modifier.width(8.dp)) - Text( - text = if (isRecording) { - stringResource(R.string.recorder_rec_label) - } else { - stringResource(R.string.recorder_ready_label) - }, - color = Color.White, - fontWeight = FontWeight.SemiBold - ) - } - - Text( - text = stringResource( - R.string.recorder_time_format, - formatElapsedTime(elapsedSeconds) - ), - color = Color.White, - fontWeight = FontWeight.SemiBold - ) - } - - Spacer(modifier = Modifier.height(8.dp)) - - Text( - text = stringResource( - R.string.recorder_zoom_format, - zoomRounded, - minZoomRounded, - maxZoomRounded - ), - color = Color.White.copy(alpha = 0.88f), - fontWeight = FontWeight.Medium - ) - - Spacer(modifier = Modifier.height(16.dp)) - - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 12.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - IconButton( - onClick = { - if (isRecording) { - isSwitchingCamera = true - pendingResume = true - recording?.stop() - } else { - lensFacing = if (lensFacing == CameraSelector.LENS_FACING_FRONT) { - CameraSelector.LENS_FACING_BACK - } else { - CameraSelector.LENS_FACING_FRONT - } - } - }, - enabled = !isProcessing && !isSwitchingCamera, - modifier = Modifier - .size(56.dp) - .clip(CircleShape) - .background(Color.Black.copy(alpha = 0.45f)) - ) { - Icon( - Icons.Default.Cameraswitch, - contentDescription = stringResource(R.string.recorder_switch_cd), - tint = Color.White, - modifier = Modifier.size(28.dp) - ) - } - - Box( - contentAlignment = Alignment.Center, - modifier = Modifier - .size(94.dp) - .clip(CircleShape) - .background(Color.Black.copy(alpha = 0.5f)) - .border(3.dp, Color.White.copy(alpha = 0.85f), CircleShape) - .pointerInput(Unit) { - detectTapGestures(onTap = { - if (isProcessing || isSwitchingCamera) return@detectTapGestures - if (!isRecording) { - isRecording = true - recordingStartMs = System.currentTimeMillis() - startNativeSegment( - context, - videoCapture, - onStart = { r -> recording = r }, - onSegmentSaved = ::handleSegmentSaved - ) - } else { - recording?.stop() - } - }) - } - ) { - Box( - modifier = Modifier - .size(recordInnerSize) - .clip(if (isRecording) RoundedCornerShape(8.dp) else CircleShape) - .background(recordInnerColor) - ) - if (isRecording) { - Icon( - Icons.Default.Stop, - contentDescription = null, - tint = Color.White, - modifier = Modifier.size(18.dp) - ) - } - } - - IconButton( - onClick = { - if (isRecording) { - recording?.stop() - } else { - finishRecording() - } - }, - enabled = !isProcessing, - modifier = Modifier - .size(56.dp) - .clip(CircleShape) - .background(Color.Black.copy(alpha = 0.45f)) - ) { - Icon( - Icons.Default.Check, - contentDescription = stringResource(R.string.recorder_done_cd), - tint = Color.White, - modifier = Modifier.size(28.dp) - ) - } - } - - Spacer(modifier = Modifier.height(10.dp)) - - TextButton( - onClick = ::cancelAndClose, - enabled = !isProcessing, - modifier = Modifier - .clip(RoundedCornerShape(999.dp)) - .background(Color.Black.copy(alpha = 0.35f)) - ) { - Text( - text = stringResource(R.string.recorder_cancel), - color = Color.White.copy(alpha = 0.95f), - fontWeight = FontWeight.Medium - ) - } - - Spacer(modifier = Modifier.height(8.dp)) - } - } - - if (isProcessing) { - Box(modifier = Modifier - .fillMaxSize() - .background(Color.Black.copy(alpha = 0.8f)), contentAlignment = Alignment.Center) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - CircularProgressIndicator(color = Color.White) - Text( - stringResource(R.string.recorder_processing), - color = Color.White, - modifier = Modifier.padding(top = 16.dp) - ) - } - } - } - } -} - -private fun formatElapsedTime(totalSeconds: Long): String { - val safeSeconds = totalSeconds.coerceAtLeast(0L) - val minutes = safeSeconds / 60 - val seconds = safeSeconds % 60 - return String.format(Locale.US, "%02d:%02d", minutes, seconds) -} - -@SuppressLint("MissingPermission") -fun startNativeSegment( - context: Context, - videoCapture: VideoCapture, - onStart: (Recording) -> Unit, - onSegmentSaved: (File) -> Unit -) { - val tempFile = File(context.cacheDir, "segment_${System.currentTimeMillis()}.mp4") - val outputOptions = FileOutputOptions.Builder(tempFile).build() - - val recording = videoCapture.output - .prepareRecording(context, outputOptions) - .withAudioEnabled() - .start(ContextCompat.getMainExecutor(context)) { event -> - if (event is VideoRecordEvent.Finalize) { - if (!event.hasError()) { - onSegmentSaved(tempFile) - } else { - if (event.cause != null) event.cause?.printStackTrace() - } - } - } - onStart(recording) -} - -class CircularTranscoder(private val inputFiles: List, private val outputFile: File) { - private val OUTPUT_WIDTH = 384 - private val OUTPUT_HEIGHT = 384 - private val OUTPUT_BIT_RATE = 1_800_000 - private val FRAME_RATE = 60 - - private var muxerAudioTrackIndex = -1 - private var muxerVideoTrackIndex = -1 - private var muxerStarted = false - - fun start() { - if (inputFiles.isEmpty()) return - - val muxer = MediaMuxer(outputFile.absolutePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4) - - try { - processVideoSequence(muxer) - if (muxerStarted) { - processAudioSequence(muxer) - } - } finally { - try { - if (muxerStarted) muxer.stop() - muxer.release() - } catch (e: Exception) { e.printStackTrace() } - } - } - - private fun processVideoSequence(muxer: MediaMuxer) { - val outputFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, OUTPUT_WIDTH, OUTPUT_HEIGHT) - outputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface) - outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, OUTPUT_BIT_RATE) - outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE) - outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1) - - val encoder = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC) - encoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE) - val inputSurface = InputSurface(encoder.createInputSurface()) - inputSurface.makeCurrent() - encoder.start() - - var scaleX = 1.0f - var scaleY = 1.0f - - try { - val retriever = MediaMetadataRetriever() - retriever.setDataSource(inputFiles[0].absolutePath) - val widthStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH) - val heightStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT) - val rotationStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION) - - val rawWidth = widthStr?.toIntOrNull() ?: 640 - val rawHeight = heightStr?.toIntOrNull() ?: 480 - val rotation = rotationStr?.toIntOrNull() ?: 0 - - val (inputWidth, inputHeight) = if (rotation == 90 || rotation == 270) { - rawHeight to rawWidth - } else { - rawWidth to rawHeight - } - - val inputAspect = inputWidth.toFloat() / inputHeight - val outputAspect = OUTPUT_WIDTH.toFloat() / OUTPUT_HEIGHT - - if (inputAspect > outputAspect) { - scaleX = inputAspect / outputAspect - scaleY = 1.0f - } else { - scaleX = 1.0f - scaleY = outputAspect / inputAspect - } - retriever.release() - } catch (e: Exception) { - e.printStackTrace() - } - - val bufferInfo = MediaCodec.BufferInfo() - val timeoutUs = 1000L - var totalDurationUs = 0L - - val surfaceTextureRenderer = TextureRenderer() - surfaceTextureRenderer.setScale(scaleX, scaleY) - - for (file in inputFiles) { - val extractor = MediaExtractor() - try { - extractor.setDataSource(file.absolutePath) - val videoTrackIndex = selectTrack(extractor, "video/") - if (videoTrackIndex < 0) continue - - extractor.selectTrack(videoTrackIndex) - val inputFormat = extractor.getTrackFormat(videoTrackIndex) - - val mime = inputFormat.getString(MediaFormat.KEY_MIME)!! - val decoder = MediaCodec.createDecoderByType(mime) - - val surfaceTexture = SurfaceTexture(surfaceTextureRenderer.getTextureId()) - val surface = Surface(surfaceTexture) - - decoder.configure(inputFormat, surface, null, 0) - decoder.start() - - var outputDone = false - var inputDone = false - var fileLastPts = 0L - - while (!outputDone) { - if (!inputDone) { - val inputBufIndex = decoder.dequeueInputBuffer(timeoutUs) - if (inputBufIndex >= 0) { - val inputBuf = decoder.getInputBuffer(inputBufIndex)!! - val chunkSize = extractor.readSampleData(inputBuf, 0) - if (chunkSize < 0) { - decoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM) - inputDone = true - } else { - decoder.queueInputBuffer(inputBufIndex, 0, chunkSize, extractor.sampleTime, 0) - extractor.advance() - } - } - } - - var decoderOutputAvailable = true - while (decoderOutputAvailable) { - val outputBufIndex = decoder.dequeueOutputBuffer(bufferInfo, timeoutUs) - if (outputBufIndex == MediaCodec.INFO_TRY_AGAIN_LATER) { - decoderOutputAvailable = false - } else if (outputBufIndex >= 0) { - val doRender = (bufferInfo.size != 0) - decoder.releaseOutputBuffer(outputBufIndex, doRender) - - if (doRender) { - surfaceTexture.updateTexImage() - surfaceTextureRenderer.draw(OUTPUT_WIDTH, OUTPUT_HEIGHT, surfaceTexture) - - val currentPts = bufferInfo.presentationTimeUs - fileLastPts = currentPts - val finalPts = currentPts + totalDurationUs - - inputSurface.setPresentationTime(finalPts * 1000) - inputSurface.swapBuffers() - } - - if ((bufferInfo.flags and MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { - outputDone = true - decoderOutputAvailable = false - } - } - } - - var encoderOutputAvailable = true - while (encoderOutputAvailable) { - val encoderStatus = encoder.dequeueOutputBuffer(bufferInfo, timeoutUs) - if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) { - encoderOutputAvailable = false - } else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { - if (muxerStarted) throw RuntimeException("Format changed twice") - val newFormat = encoder.outputFormat - muxerVideoTrackIndex = muxer.addTrack(newFormat) - - val audioEx = MediaExtractor() - audioEx.setDataSource(inputFiles[0].absolutePath) - val at = selectTrack(audioEx, "audio/") - if (at >= 0) { - val af = audioEx.getTrackFormat(at) - muxerAudioTrackIndex = muxer.addTrack(af) - } - audioEx.release() - - muxer.start() - muxerStarted = true - } else if (encoderStatus >= 0) { - val encodedData = encoder.getOutputBuffer(encoderStatus)!! - if ((bufferInfo.flags and MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) bufferInfo.size = 0 - - if (bufferInfo.size != 0 && muxerStarted) { - encodedData.position(bufferInfo.offset) - encodedData.limit(bufferInfo.offset + bufferInfo.size) - muxer.writeSampleData(muxerVideoTrackIndex, encodedData, bufferInfo) - } - encoder.releaseOutputBuffer(encoderStatus, false) - } - } - } - - decoder.stop(); decoder.release() - surfaceTexture.release(); surface.release() - - totalDurationUs += (fileLastPts + 20000L) - - } catch (e: Exception) { e.printStackTrace() } - finally { extractor.release() } - } - - encoder.signalEndOfInputStream() - var eos = false - while (!eos) { - val encoderStatus = encoder.dequeueOutputBuffer(bufferInfo, timeoutUs) - if (encoderStatus >= 0) { - val encodedData = encoder.getOutputBuffer(encoderStatus)!! - if ((bufferInfo.flags and MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) bufferInfo.size = 0 - if (bufferInfo.size != 0 && muxerStarted) { - encodedData.position(bufferInfo.offset) - encodedData.limit(bufferInfo.offset + bufferInfo.size) - muxer.writeSampleData(muxerVideoTrackIndex, encodedData, bufferInfo) - } - encoder.releaseOutputBuffer(encoderStatus, false) - if ((bufferInfo.flags and MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) eos = true - } else if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) { - break - } - } - - encoder.stop(); encoder.release() - inputSurface.release() - } - - private fun processAudioSequence(muxer: MediaMuxer) { - if (muxerAudioTrackIndex < 0) return - - var totalDurationUs = 0L - val buffer = ByteBuffer.allocate(256 * 1024) - val bufferInfo = MediaCodec.BufferInfo() - - for (file in inputFiles) { - val extractor = MediaExtractor() - try { - extractor.setDataSource(file.absolutePath) - val trackIndex = selectTrack(extractor, "audio/") - if (trackIndex < 0) continue - - extractor.selectTrack(trackIndex) - var fileLastPts = 0L - - while (true) { - val chunkSize = extractor.readSampleData(buffer, 0) - if (chunkSize < 0) break - - bufferInfo.offset = 0 - bufferInfo.size = chunkSize - bufferInfo.flags = extractor.sampleFlags - - val originalPts = extractor.sampleTime - fileLastPts = originalPts - bufferInfo.presentationTimeUs = originalPts + totalDurationUs - - muxer.writeSampleData(muxerAudioTrackIndex, buffer, bufferInfo) - extractor.advance() - } - totalDurationUs += (fileLastPts + 20000L) - } catch (e: Exception) { e.printStackTrace() } - finally { extractor.release() } - } - } - - private fun selectTrack(extractor: MediaExtractor, prefix: String): Int { - for (i in 0 until extractor.trackCount) { - val format = extractor.getTrackFormat(i) - val mime = format.getString(MediaFormat.KEY_MIME) - if (mime?.startsWith(prefix) == true) return i - } - return -1 - } - - private class TextureRenderer { - private var program = 0; private var textureId = 0 - private var uSTMatrixHandle = 0 - private var uScaleHandle = 0 - private val stMatrix = FloatArray(16) - private val vertexStride = 8 - private val vertexData = floatArrayOf(-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f) - private val vertexBuffer: FloatBuffer = ByteBuffer.allocateDirect(vertexData.size * 4) - .order(ByteOrder.nativeOrder()).asFloatBuffer().put(vertexData).apply { position(0) } - - private var scaleX = 1.0f - private var scaleY = 1.0f - - private val vertexShaderCode = """ - uniform mat4 uSTMatrix; - uniform vec2 uScale; - attribute vec4 aPosition; - varying vec2 vTextureCoord; - varying vec2 vPosition; - void main() { - vec4 scaledPos = vec4(aPosition.x * uScale.x, aPosition.y * uScale.y, aPosition.z, 1.0); - gl_Position = scaledPos; - vPosition = aPosition.xy; - vec2 texCoord = (aPosition.xy + 1.0) / 2.0; - vTextureCoord = (uSTMatrix * vec4(texCoord, 0.0, 1.0)).xy; - } - """ - - private val fragmentShaderCode = """ - #extension GL_OES_EGL_image_external : require - precision mediump float; - varying vec2 vTextureCoord; - varying vec2 vPosition; - uniform samplerExternalOES sTexture; - void main() { - float dist = length(vPosition); - if (dist < 1.0) { - gl_FragColor = texture2D(sTexture, vTextureCoord); - } else { - gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); - } - } - """ - - init { - val textures = IntArray(1) - GLES20.glGenTextures(1, textures, 0); textureId = textures[0] - GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId) - GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST.toFloat()) - GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR.toFloat()) - GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE) - GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE) - program = createProgram(vertexShaderCode, fragmentShaderCode) - uSTMatrixHandle = GLES20.glGetUniformLocation(program, "uSTMatrix") - uScaleHandle = GLES20.glGetUniformLocation(program, "uScale") - } - - fun getTextureId(): Int = textureId - - fun setScale(x: Float, y: Float) { - scaleX = x - scaleY = y - } - - fun draw(width: Int, height: Int, surfaceTexture: SurfaceTexture) { - GLES20.glViewport(0, 0, width, height) - GLES20.glUseProgram(program) - - GLES20.glUniform2f(uScaleHandle, scaleX, scaleY) - - surfaceTexture.getTransformMatrix(stMatrix) - GLES20.glUniformMatrix4fv(uSTMatrixHandle, 1, false, stMatrix, 0) - val positionHandle = GLES20.glGetAttribLocation(program, "aPosition") - GLES20.glEnableVertexAttribArray(positionHandle) - GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer) - GLES20.glActiveTexture(GLES20.GL_TEXTURE0) - GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId) - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4) - GLES20.glDisableVertexAttribArray(positionHandle) - } - - private fun createProgram(vertexSource: String, fragmentSource: String): Int { - val vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource) - val fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource) - val program = GLES20.glCreateProgram() - GLES20.glAttachShader(program, vertexShader); GLES20.glAttachShader(program, fragmentShader) - GLES20.glLinkProgram(program); return program - } - - private fun loadShader(type: Int, shaderCode: String): Int { - val shader = GLES20.glCreateShader(type); GLES20.glShaderSource(shader, shaderCode) - GLES20.glCompileShader(shader); return shader - } - } - - private class InputSurface(surface: Surface) { - private var eglDisplay = EGL14.EGL_NO_DISPLAY; private var eglContext = EGL14.EGL_NO_CONTEXT; private var eglSurface = EGL14.EGL_NO_SURFACE - - init { - eglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY) - val version = IntArray(2); EGL14.eglInitialize(eglDisplay, version, 0, version, 1) - val attribList = intArrayOf(EGL14.EGL_RED_SIZE, 8, EGL14.EGL_GREEN_SIZE, 8, EGL14.EGL_BLUE_SIZE, 8, EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT, EGL_RECORDABLE_ANDROID, 1, EGL14.EGL_NONE) - val configs = arrayOfNulls(1); val numConfigs = IntArray(1) - EGL14.eglChooseConfig(eglDisplay, attribList, 0, configs, 0, configs.size, numConfigs, 0) - val attrib_list = intArrayOf(EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE) - eglContext = EGL14.eglCreateContext(eglDisplay, configs[0], EGL14.EGL_NO_CONTEXT, attrib_list, 0) - val surfaceAttribs = intArrayOf(EGL14.EGL_NONE) - eglSurface = EGL14.eglCreateWindowSurface(eglDisplay, configs[0], surface, surfaceAttribs, 0) - } - - fun makeCurrent() { EGL14.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) } - fun swapBuffers() { EGL14.eglSwapBuffers(eglDisplay, eglSurface) } - fun setPresentationTime(nsecs: Long) { EGLExt.eglPresentationTimeANDROID(eglDisplay, eglSurface, nsecs) } - fun release() { - if (eglDisplay !== EGL14.EGL_NO_DISPLAY) { - EGL14.eglMakeCurrent(eglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT) - EGL14.eglDestroySurface(eglDisplay, eglSurface); EGL14.eglDestroyContext(eglDisplay, eglContext) - EGL14.eglReleaseThread(); EGL14.eglTerminate(eglDisplay) - } - eglDisplay = EGL14.EGL_NO_DISPLAY; eglContext = EGL14.EGL_NO_CONTEXT; eglSurface = EGL14.EGL_NO_SURFACE - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/AlbumMessageBubbleContainer.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/AlbumMessageBubbleContainer.kt deleted file mode 100644 index 60d5c543..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/AlbumMessageBubbleContainer.kt +++ /dev/null @@ -1,251 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components - -import android.content.res.Configuration -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.* -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.geometry.Rect -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.unit.IntSize -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.toSize -import org.monogram.domain.models.InlineKeyboardButtonModel -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.chatContent.shouldShowDate -import org.monogram.presentation.features.chats.currentChat.components.channels.ChannelAlbumMessageBubble -import org.monogram.presentation.features.chats.currentChat.components.chats.ChatAlbumMessageBubble -import org.monogram.presentation.features.chats.currentChat.components.chats.MessageViaBotAttribution -import org.monogram.presentation.features.chats.currentChat.components.chats.ReplyMarkupView - -@Composable -fun AlbumMessageBubbleContainer( - messages: List, - olderMsg: MessageModel? = null, - newerMsg: MessageModel? = null, - isGroup: Boolean, - isChannel: Boolean = false, - autoplayGifs: Boolean = true, - autoplayVideos: Boolean = true, - autoDownloadMobile: Boolean = false, - autoDownloadWifi: Boolean = false, - autoDownloadRoaming: Boolean = false, - onPhotoClick: (MessageModel) -> Unit, - onDownloadPhoto: (Int) -> Unit = {}, - onVideoClick: (MessageModel) -> Unit = {}, - onDocumentClick: (MessageModel) -> Unit = {}, - onAudioClick: (MessageModel) -> Unit = {}, - onCancelDownload: (Int) -> Unit = {}, - onReplyClick: (Offset, IntSize, Offset) -> Unit, - onGoToReply: (MessageModel) -> Unit = {}, - onReactionClick: (Long, String) -> Unit = { _, _ -> }, - onReplyMarkupButtonClick: (Long, InlineKeyboardButtonModel) -> Unit = { _, _ -> }, - fontSize: Float = 16f, - bubbleRadius: Float = 16f, - shouldReportPosition: Boolean = false, - onPositionChange: (Long, Offset, IntSize) -> Unit = { _, _, _ -> }, - onCommentsClick: (Long) -> Unit = {}, - showComments: Boolean = true, - toProfile: (Long) -> Unit, - onViaBotClick: (String) -> Unit = {}, - canReply: Boolean = false, - onReplySwipe: (MessageModel) -> Unit = {}, - swipeEnabled: Boolean = true, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - isAnyViewerOpen: Boolean = false -) { - if (messages.isEmpty()) return - - val firstMsg = messages.first() - val lastMsg = messages.last() - val isOutgoing = firstMsg.isOutgoing - - val configuration = LocalConfiguration.current - val screenWidth = configuration.screenWidthDp.dp - val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE - - val maxWidth = remember(isChannel, isLandscape, screenWidth) { - when { - isChannel -> if (isLandscape) (screenWidth * 0.7f).coerceAtMost(600.dp) else (screenWidth * 0.94f).coerceAtMost( - 500.dp - ) - - isLandscape -> (screenWidth * 0.6f).coerceAtMost(450.dp) - else -> (screenWidth * 0.85f).coerceAtMost(360.dp) - } - } - - val isSameSenderAbove = remember(olderMsg?.senderId, firstMsg.senderId, olderMsg?.date, firstMsg.date) { - olderMsg?.senderId == firstMsg.senderId && !shouldShowDate(firstMsg, olderMsg) - } - val isSameSenderBelow = remember(newerMsg?.senderId, lastMsg.senderId, newerMsg?.date, lastMsg.date) { - newerMsg != null && newerMsg.senderId == lastMsg.senderId && !shouldShowDate(newerMsg, lastMsg) - } - - val topSpacing = if (isChannel && !isSameSenderAbove) 12.dp else 2.dp - - var outerColumnPosition by remember { mutableStateOf(Offset.Zero) } - var bubblePosition by remember { mutableStateOf(Offset.Zero) } - var bubbleSize by remember { mutableStateOf(IntSize.Zero) } - - Column( - modifier = Modifier - .fillMaxWidth() - .onGloballyPositioned { outerColumnPosition = it.positionInWindow() } - .padding(top = topSpacing, bottom = 2.dp) - .pointerInput(Unit) { - detectTapGestures( - onTap = { offset -> - val clickPos = outerColumnPosition + offset - val bubbleRect = Rect(bubblePosition, bubbleSize.toSize()) - if (!bubbleRect.contains(clickPos)) { - onReplyClick(bubblePosition, bubbleSize, clickPos) - } - }, - onLongPress = { offset -> - val clickPos = outerColumnPosition + offset - val bubbleRect = Rect(bubblePosition, bubbleSize.toSize()) - if (!bubbleRect.contains(clickPos)) { - onReplyClick(bubblePosition, bubbleSize, clickPos) - } - } - ) - } - ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = if (isChannel) Arrangement.Center else if (isOutgoing) Arrangement.End else Arrangement.Start, - verticalAlignment = Alignment.Bottom - ) { - if (isGroup && !isOutgoing && !isChannel) { - Avatar( - path = firstMsg.senderAvatar, - fallbackPath = firstMsg.senderPersonalAvatar, - name = firstMsg.senderName, - size = 40.dp, - onClick = { toProfile(firstMsg.senderId) }, - videoPlayerPool = videoPlayerPool - ) - Spacer(modifier = Modifier.width(8.dp)) - } - - Column( - modifier = Modifier - .then(if (isChannel) Modifier.padding(horizontal = 8.dp) else Modifier) - .widthIn(max = maxWidth) - .then(if (isChannel) Modifier.fillMaxWidth() else Modifier) - .onGloballyPositioned { coordinates -> - bubblePosition = coordinates.positionInWindow() - bubbleSize = coordinates.size - if (shouldReportPosition) { - onPositionChange(lastMsg.id, bubblePosition, bubbleSize) - } - } - ) { - if (isGroup && !isOutgoing && !isChannel) { - Text( - text = firstMsg.senderName, - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(start = 12.dp, bottom = 4.dp) - ) - } - - if (isChannel) { - ChannelAlbumMessageBubble( - messages = messages, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - autoplayGifs = autoplayGifs, - autoplayVideos = autoplayVideos, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - onPhotoClick = onPhotoClick, - onDownloadPhoto = onDownloadPhoto, - onVideoClick = onVideoClick, - onDocumentClick = onDocumentClick, - onAudioClick = onAudioClick, - onCancelDownload = onCancelDownload, - onLongClick = { offset -> - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + offset - ) - }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(lastMsg.id, it) }, - onCommentsClick = onCommentsClick, - showComments = showComments, - toProfile = toProfile, - modifier = Modifier.fillMaxWidth(), - fontSize = fontSize, - bubbleRadius = bubbleRadius, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } else { - ChatAlbumMessageBubble( - messages = messages, - isOutgoing = isOutgoing, - isGroup = isGroup, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - autoplayGifs = autoplayGifs, - autoplayVideos = autoplayVideos, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - onPhotoClick = onPhotoClick, - onDownloadPhoto = onDownloadPhoto, - onVideoClick = onVideoClick, - onDocumentClick = onDocumentClick, - onAudioClick = onAudioClick, - onCancelDownload = onCancelDownload, - onLongClick = { offset -> - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + offset - ) - }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(lastMsg.id, it) }, - toProfile = toProfile, - modifier = Modifier, - fontSize = fontSize, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } - - lastMsg.replyMarkup?.let { markup -> - ReplyMarkupView( - replyMarkup = markup, - onButtonClick = { onReplyMarkupButtonClick(lastMsg.id, it) } - ) - } - - MessageViaBotAttribution( - msg = lastMsg, - isOutgoing = isOutgoing, - onViaBotClick = onViaBotClick, - modifier = Modifier.align(if (isOutgoing) Alignment.End else Alignment.Start) - ) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/AlphaVideoPlayer.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/AlphaVideoPlayer.kt deleted file mode 100644 index d0ab279e..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/AlphaVideoPlayer.kt +++ /dev/null @@ -1,615 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components - -import android.annotation.SuppressLint -import android.app.Application -import android.content.ComponentCallbacks2 -import android.content.Context -import android.content.res.Configuration -import android.graphics.Bitmap -import android.graphics.SurfaceTexture -import android.net.Uri -import android.os.Handler -import android.os.Looper -import android.view.Gravity -import android.view.Surface -import android.view.TextureView -import android.view.ViewGroup -import android.widget.FrameLayout -import androidx.annotation.Keep -import androidx.annotation.OptIn -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.core.tween -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalInspectionMode -import androidx.compose.ui.viewinterop.AndroidView -import androidx.core.net.toUri -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleEventObserver -import androidx.lifecycle.compose.LocalLifecycleOwner -import androidx.media3.common.* -import androidx.media3.common.util.UnstableApi -import androidx.media3.database.DatabaseProvider -import androidx.media3.database.StandaloneDatabaseProvider -import androidx.media3.datasource.DataSource -import androidx.media3.datasource.DefaultDataSource -import androidx.media3.datasource.DefaultHttpDataSource -import androidx.media3.datasource.cache.CacheDataSource -import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor -import androidx.media3.datasource.cache.SimpleCache -import androidx.media3.exoplayer.DefaultLoadControl -import androidx.media3.exoplayer.DefaultRenderersFactory -import androidx.media3.exoplayer.ExoPlayer -import androidx.media3.exoplayer.source.DefaultMediaSourceFactory -import androidx.media3.exoplayer.source.MediaSource -import androidx.media3.exoplayer.upstream.DefaultAllocator -import androidx.media3.extractor.DefaultExtractorsFactory -import androidx.media3.extractor.mp4.Mp4Extractor -import coil3.compose.AsyncImage -import coil3.request.ImageRequest -import coil3.request.crossfade -import coil3.video.VideoFrameDecoder -import coil3.video.videoFrameMillis -import kotlinx.coroutines.delay -import kotlinx.coroutines.isActive -import org.monogram.presentation.core.util.getMimeType -import java.io.File -import java.io.FileNotFoundException -import java.util.concurrent.ArrayBlockingQueue -import java.util.concurrent.atomic.AtomicBoolean - -sealed interface VideoType { - val useAlphaChannel: Boolean - val removeBlackBackground: Boolean - - data object Sticker : VideoType { - override val useAlphaChannel: Boolean = true - override val removeBlackBackground: Boolean = true - } - - data object Gif : VideoType { - override val useAlphaChannel: Boolean = false - override val removeBlackBackground: Boolean = false - } -} - -@OptIn(UnstableApi::class) -@Composable -fun VideoStickerPlayer( - path: String, - videoPlayerPool: VideoPlayerPool, - type: VideoType, - modifier: Modifier = Modifier, - animate: Boolean = true, - shouldLoop: Boolean = true, - volume: Float = 0f, - contentScale: ContentScale = ContentScale.Fit, - onProgressUpdate: (Long) -> Unit = {}, - reportProgress: Boolean = false, - fileId: Int = 0, - thumbnailData: Any? = null -) { - if (LocalInspectionMode.current) { - Box(modifier = modifier) - return - } - - val context = LocalContext.current - val lifecycleOwner = LocalLifecycleOwner.current - val currentPath by rememberUpdatedState(path) - - var shouldLoadPlayer by remember { mutableStateOf(false) } - var isVideoFrameReady by remember { mutableStateOf(false) } - - LaunchedEffect(animate, currentPath) { - shouldLoadPlayer = false - isVideoFrameReady = false - if (animate) { - delay(80) - if (isActive) shouldLoadPlayer = true - } - } - - Box(modifier = modifier) { - if (shouldLoadPlayer) { - val exoPlayer = remember(currentPath) { videoPlayerPool.acquire(fileId) } - val isDisposed = remember { AtomicBoolean(false) } - val textureViewRef = remember { mutableStateOf(null) } - - LaunchedEffect(volume) { - if (exoPlayer.volume != volume) exoPlayer.volume = volume - } - - LaunchedEffect(animate, exoPlayer) { - if (animate) exoPlayer.play() else exoPlayer.pause() - } - - LaunchedEffect(exoPlayer, reportProgress) { - if (!reportProgress) return@LaunchedEffect - - while (isActive && !isDisposed.get()) { - if (exoPlayer.isPlaying) { - onProgressUpdate(exoPlayer.currentPosition) - } - delay(1000) - } - } - - DisposableEffect(currentPath, exoPlayer, animate) { - isDisposed.set(false) - - val isNetworkPath = currentPath.startsWith("http") || currentPath.startsWith("content") - if (!isNetworkPath && !File(currentPath).exists()) { - isDisposed.set(true) - return@DisposableEffect onDispose {} - } - - val uri = if (isNetworkPath) { - currentPath.toUri() - } else { - Uri.fromFile(File(currentPath)) - } - - val mediaItem = MediaItem.Builder() - .setUri(uri) - .setMimeType(getMimeType(currentPath) ?: MimeTypes.VIDEO_MP4) - .build() - - val mediaSource = videoPlayerPool.getMediaSourceFactory(fileId) - .createMediaSource(mediaItem) - - exoPlayer.apply { - setMediaSource(mediaSource) - prepare() - playWhenReady = animate - repeatMode = if (shouldLoop) Player.REPEAT_MODE_ONE else Player.REPEAT_MODE_OFF - this.volume = volume - } - - val playerListener = object : Player.Listener { - override fun onVideoSizeChanged(videoSize: VideoSize) { - textureViewRef.value?.setVideoSize(videoSize.width, videoSize.height) - } - - override fun onRenderedFirstFrame() { - if (!isDisposed.get()) isVideoFrameReady = true - } - - override fun onPlayerError(error: PlaybackException) { - if (error.cause is FileNotFoundException) { - isVideoFrameReady = false - } - } - - override fun onIsPlayingChanged(isPlaying: Boolean) { - if (isPlaying && !isVideoFrameReady && !isDisposed.get()) { - Handler(Looper.getMainLooper()).postDelayed({ - isVideoFrameReady = true - }, 50) - } - } - } - exoPlayer.addListener(playerListener) - - val lifecycleObserver = LifecycleEventObserver { _, event -> - if (isDisposed.get()) return@LifecycleEventObserver - when (event) { - Lifecycle.Event.ON_RESUME -> if (animate) exoPlayer.play() - Lifecycle.Event.ON_PAUSE -> exoPlayer.pause() - else -> Unit - } - } - lifecycleOwner.lifecycle.addObserver(lifecycleObserver) - - onDispose { - isDisposed.set(true) - isVideoFrameReady = false - lifecycleOwner.lifecycle.removeObserver(lifecycleObserver) - exoPlayer.removeListener(playerListener) - exoPlayer.setVideoSurface(null) - videoPlayerPool.release(exoPlayer) - } - } - - AndroidView( - factory = { ctx -> - VideoGLTextureView(ctx).apply { - layoutParams = FrameLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT, - Gravity.CENTER - ) - isOpaque = false - this.contentScale = contentScale - this.configure(type.useAlphaChannel, type.removeBlackBackground) - - this.onSurfaceReady = { surface -> - if (!isDisposed.get()) { - exoPlayer.setVideoSurface(surface) - } else { - surface.release() - } - } - textureViewRef.value = this - } - }, - modifier = Modifier.fillMaxSize() - ) - } - - AnimatedVisibility( - visible = !isVideoFrameReady, - enter = fadeIn(tween(100)), - exit = fadeOut(tween(250)), - modifier = Modifier.fillMaxSize() - ) { - AsyncImage( - model = ImageRequest.Builder(context) - .data(thumbnailData ?: currentPath) - .apply { - if (thumbnailData == null) { - decoderFactory(VideoFrameDecoder.Factory()) - videoFrameMillis(0) - memoryCacheKey(currentPath) - diskCacheKey(currentPath) - } - } - .crossfade(false) - .build(), - contentDescription = null, - contentScale = contentScale, - modifier = Modifier.fillMaxSize() - ) - } - } -} - -@OptIn(UnstableApi::class) -class VideoPlayerPool(val context: Context, val exoPlayerCache: ExoPlayerCache) { - private val players = ArrayBlockingQueue(8) - private var isCallbackRegistered = false - private var mediaSourceFactory: MediaSource.Factory? = null - - fun getMediaSourceFactory(fileId: Int = 0): MediaSource.Factory { - if (fileId != 0) { - val streamingRepository = - org.koin.core.context.GlobalContext.get().get() - val dataSourceFactory = streamingRepository.createPayload(fileId) as DataSource.Factory - val extractorsFactory = DefaultExtractorsFactory() - .setConstantBitrateSeekingEnabled(true) - .setMp4ExtractorFlags(Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS) - return DefaultMediaSourceFactory(dataSourceFactory, extractorsFactory) - } - - return mediaSourceFactory ?: synchronized(this) { - val extractorsFactory = DefaultExtractorsFactory() - .setConstantBitrateSeekingEnabled(true) - .setMp4ExtractorFlags(Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS) - - mediaSourceFactory ?: DefaultMediaSourceFactory( - exoPlayerCache.getDataSourceFactory(context), - extractorsFactory - ) - .also { mediaSourceFactory = it } - } - } - - fun acquire(fileId: Int = 0): ExoPlayer { - registerMemoryCallbacks(context.applicationContext) - val player = players.poll() - return player?.apply { - seekTo(0) - playWhenReady = false - } ?: createPlayer(fileId) - } - - fun release(player: ExoPlayer) { - if (Looper.myLooper() == Looper.getMainLooper()) { - resetAndStore(player) - } else { - Handler(Looper.getMainLooper()).post { resetAndStore(player) } - } - } - - private fun resetAndStore(player: ExoPlayer) { - player.stop() - player.clearMediaItems() - if (!players.offer(player)) { - player.release() - } - } - - private fun createPlayer(fileId: Int = 0): ExoPlayer { - val renderersFactory = DefaultRenderersFactory(context).setEnableDecoderFallback(true) - - val loadControl = DefaultLoadControl.Builder() - .setAllocator(DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE)) - .setBufferDurationsMs( - 500, // Min buffer - 3000, // Max buffer - 100, // Buffer to start playback (very low for instant start) - 500 // Buffer for rebuffer - ).build() - - val extractorsFactory = DefaultExtractorsFactory() - .setConstantBitrateSeekingEnabled(true) - .setMp4ExtractorFlags(Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS) - - val mediaSourceFactory = if (fileId != 0) { - val streamingRepository = - org.koin.core.context.GlobalContext.get().get() - val dataSourceFactory = streamingRepository.createPayload(fileId) as DataSource.Factory - DefaultMediaSourceFactory(dataSourceFactory, extractorsFactory) - } else { - DefaultMediaSourceFactory(context, extractorsFactory) - } - - return ExoPlayer.Builder(context, renderersFactory) - .setLoadControl(loadControl) - .setMediaSourceFactory(mediaSourceFactory) - .build() - .apply { - videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT - volume = 0f - repeatMode = Player.REPEAT_MODE_ONE - } - } - - private fun registerMemoryCallbacks(context: Context) { - if (isCallbackRegistered) return - synchronized(this) { - if (isCallbackRegistered) return - isCallbackRegistered = true - (context as? Application)?.registerComponentCallbacks(object : ComponentCallbacks2 { - override fun onTrimMemory(level: Int) { - if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) clearPool() - } - - override fun onConfigurationChanged(newConfig: Configuration) {} - override fun onLowMemory() { - clearPool() - } - }) - } - } - - private fun clearPool() { - val iterator = players.iterator() - while (iterator.hasNext()) { - iterator.next().release() - iterator.remove() - } - } -} - -@SuppressLint("UnsafeOptInUsageError") -class ExoPlayerCache { - @Volatile - private var cacheDataSourceFactory: CacheDataSource.Factory? = null - private var simpleCache: SimpleCache? = null - private var databaseProvider: DatabaseProvider? = null - private val lock = Any() - - fun getDataSourceFactory(context: Context): CacheDataSource.Factory { - return cacheDataSourceFactory ?: synchronized(lock) { - if (cacheDataSourceFactory == null) { - val cacheDir = File(context.applicationContext.cacheDir, "sticker_video_cache") - if (!cacheDir.exists()) cacheDir.mkdirs() - - if (databaseProvider == null) { - databaseProvider = StandaloneDatabaseProvider(context.applicationContext) - } - - val evictor = LeastRecentlyUsedCacheEvictor(250 * 1024 * 1024) - simpleCache = SimpleCache(cacheDir, evictor, databaseProvider!!) - - val upstreamFactory = DefaultHttpDataSource.Factory() - .setAllowCrossProtocolRedirects(true) - .setConnectTimeoutMs(15_000) - .setReadTimeoutMs(15_000) - .setUserAgent("StickerPlayer/2.0") - - val defaultDataSourceFactory = DefaultDataSource.Factory(context.applicationContext, upstreamFactory) - - cacheDataSourceFactory = CacheDataSource.Factory() - .setCache(simpleCache!!) - .setUpstreamDataSourceFactory(defaultDataSourceFactory) - .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR) - } - cacheDataSourceFactory!! - } - } - - fun clearCache(context: Context) { - synchronized(lock) { - try { - simpleCache?.release() - simpleCache = null - cacheDataSourceFactory = null - val cacheDir = File(context.applicationContext.cacheDir, "sticker_video_cache") - if (cacheDir.exists()) { - cacheDir.deleteRecursively() - } - } catch (e: Exception) { - e.printStackTrace() - } - } - } -} - -@Keep -class NativeVideoRenderer { - companion object { - init { - System.loadLibrary("native-lib") - } - } - - private var nativeHandle: Long = 0 - var onSurfaceReady: ((Surface) -> Unit)? = null - private var surfaceTexture: SurfaceTexture? = null - private var surface: Surface? = null - - private var overlayTextureId: Int = 0 - - external fun create(surface: Surface, useAlpha: Boolean, removeBlackBg: Boolean): Long - external fun destroy(handle: Long) - external fun updateSize(handle: Long, width: Int, height: Int) - external fun notifyFrameAvailable(handle: Long) - external fun setFilter(handle: Long, matrix: FloatArray?) - external fun setOverlayTexture(handle: Long, textureId: Int) - - @Keep - fun onGlContextReady(textureId: Int) { - Handler(Looper.getMainLooper()).post { - if (nativeHandle == 0L) return@post - val st = SurfaceTexture(textureId) - surfaceTexture = st - st.setOnFrameAvailableListener { - if (nativeHandle != 0L) { - notifyFrameAvailable(nativeHandle) - } - } - - val s = Surface(st) - surface = s - onSurfaceReady?.invoke(s) - } - } - - @Keep - fun updateTexture(matrix: FloatArray): Long { - surfaceTexture?.updateTexImage() - surfaceTexture?.getTransformMatrix(matrix) - return surfaceTexture?.timestamp ?: 0L - } - - fun init(surface: Surface, useAlpha: Boolean, removeBlackBg: Boolean) { - nativeHandle = create(surface, useAlpha, removeBlackBg) - } - - fun release() { - if (nativeHandle != 0L) { - destroy(nativeHandle) - nativeHandle = 0 - } - surface?.release() - surfaceTexture?.release() - surface = null - surfaceTexture = null - } - - fun setSize(width: Int, height: Int) { - if (nativeHandle != 0L) { - updateSize(nativeHandle, width, height) - } - } - - fun setFilter(matrix: FloatArray?) { - if (nativeHandle != 0L) { - setFilter(nativeHandle, matrix) - } - } - - fun setOverlay(bitmap: Bitmap?) { - if (nativeHandle != 0L) { - if (bitmap != null) { - - } else { - setOverlayTexture(nativeHandle, 0) - } - } - } -} - -class VideoGLTextureView(context: Context) : TextureView(context), TextureView.SurfaceTextureListener { - var onSurfaceReady: ((Surface) -> Unit)? = null - var contentScale: ContentScale = ContentScale.Fit - - private var useAlpha = false - private var removeBlackBg = false - private var nativeRenderer: NativeVideoRenderer? = null - - private var videoWidth = 0 - private var videoHeight = 0 - - init { - surfaceTextureListener = this - isOpaque = false - } - - fun configure(useAlpha: Boolean, removeBlackBg: Boolean) { - this.useAlpha = useAlpha - this.removeBlackBg = removeBlackBg - } - - fun setVideoSize(width: Int, height: Int) { - this.videoWidth = width - this.videoHeight = height - requestLayout() - } - - override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec) - if (videoWidth == 0 || videoHeight == 0) { - setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)) - return - } - - val width = MeasureSpec.getSize(widthMeasureSpec) - val height = MeasureSpec.getSize(heightMeasureSpec) - - val viewRatio = width.toFloat() / height.toFloat() - val videoRatio = videoWidth.toFloat() / videoHeight.toFloat() - - var finalWidth = width - var finalHeight = height - - if (contentScale == ContentScale.Fit) { - if (videoRatio > viewRatio) { - finalHeight = (width / videoRatio).toInt() - } else { - finalWidth = (height * videoRatio).toInt() - } - } else if (contentScale == ContentScale.Crop) { - if (videoRatio > viewRatio) { - finalWidth = (height * videoRatio).toInt() - } else { - finalHeight = (width / videoRatio).toInt() - } - } - - setMeasuredDimension(finalWidth, finalHeight) - } - - fun setFilter(matrix: FloatArray?) { - nativeRenderer?.setFilter(matrix) - } - - override fun onSurfaceTextureAvailable(st: SurfaceTexture, width: Int, height: Int) { - nativeRenderer = NativeVideoRenderer() - nativeRenderer?.onSurfaceReady = { surface -> - onSurfaceReady?.invoke(surface) - } - nativeRenderer?.init(Surface(st), useAlpha, removeBlackBg) - nativeRenderer?.setSize(width, height) - } - - override fun onSurfaceTextureSizeChanged(st: SurfaceTexture, width: Int, height: Int) { - nativeRenderer?.setSize(width, height) - } - - override fun onSurfaceTextureDestroyed(st: SurfaceTexture): Boolean { - nativeRenderer?.release() - nativeRenderer = null - return true - } - - override fun onSurfaceTextureUpdated(st: SurfaceTexture) {} -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/AvatarPlayer.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/AvatarPlayer.kt deleted file mode 100644 index 09aef0fb..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/AvatarPlayer.kt +++ /dev/null @@ -1,121 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components - -import android.net.Uri -import android.view.ViewGroup -import android.widget.FrameLayout -import androidx.annotation.OptIn -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.core.tween -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalInspectionMode -import androidx.compose.ui.viewinterop.AndroidView -import androidx.core.net.toUri -import androidx.media3.common.MediaItem -import androidx.media3.common.PlaybackException -import androidx.media3.common.Player -import androidx.media3.common.util.UnstableApi -import androidx.media3.ui.AspectRatioFrameLayout -import androidx.media3.ui.PlayerView -import coil3.compose.AsyncImage -import coil3.request.ImageRequest -import coil3.request.crossfade -import coil3.video.VideoFrameDecoder -import coil3.video.videoFrameMillis -import java.io.File - -@OptIn(UnstableApi::class) -@Composable -fun AvatarPlayer( - path: String, - modifier: Modifier = Modifier, - contentScale: ContentScale = ContentScale.Crop, - videoPlayerPool: VideoPlayerPool -) { - if (LocalInspectionMode.current) { - Box(modifier = modifier) - return - } - - val context = LocalContext.current - var isVideoFrameReady by remember { mutableStateOf(false) } - - val exoPlayer = remember(path) { - videoPlayerPool.acquire().apply { - val uri = if (path.startsWith("http") || path.startsWith("content") || path.startsWith("file")) { - path.toUri() - } else { - Uri.fromFile(File(path)) - } - val mediaSource = videoPlayerPool.getMediaSourceFactory() - .createMediaSource(MediaItem.fromUri(uri)) - setMediaSource(mediaSource) - prepare() - repeatMode = Player.REPEAT_MODE_ONE - playWhenReady = true - volume = 0f - } - } - - DisposableEffect(exoPlayer) { - val listener = object : Player.Listener { - override fun onRenderedFirstFrame() { - isVideoFrameReady = true - } - - override fun onPlayerError(error: PlaybackException) { - isVideoFrameReady = false - } - } - exoPlayer.addListener(listener) - onDispose { - exoPlayer.removeListener(listener) - exoPlayer.setVideoSurface(null) - videoPlayerPool.release(exoPlayer) - } - } - - Box(modifier = modifier) { - AndroidView( - factory = { ctx -> - PlayerView(ctx).apply { - player = exoPlayer - useController = false - resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM - layoutParams = FrameLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT - ) - } - }, - modifier = Modifier.fillMaxSize() - ) - - AnimatedVisibility( - visible = !isVideoFrameReady, - enter = fadeIn(tween(100)), - exit = fadeOut(tween(250)), - modifier = Modifier.fillMaxSize() - ) { - AsyncImage( - model = ImageRequest.Builder(context) - .data(path) - .decoderFactory(VideoFrameDecoder.Factory()) - .videoFrameMillis(0) - .memoryCacheKey(path) - .diskCacheKey(path) - .crossfade(true) - .build(), - contentDescription = null, - contentScale = contentScale, - modifier = Modifier.fillMaxSize() - ) - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/ChannelMessageBubbleContainer.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/ChannelMessageBubbleContainer.kt deleted file mode 100644 index e713f7a7..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/ChannelMessageBubbleContainer.kt +++ /dev/null @@ -1,287 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components - -import android.content.res.Configuration -import androidx.compose.animation.Animatable -import androidx.compose.animation.core.tween -import androidx.compose.foundation.background -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.unit.IntSize -import androidx.compose.ui.unit.dp -import kotlinx.coroutines.delay -import org.monogram.domain.models.InlineKeyboardButtonModel -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.chatContent.shouldShowDate -import org.monogram.presentation.features.chats.currentChat.components.channels.* -import org.monogram.presentation.features.chats.currentChat.components.chats.DocumentMessageBubble -import org.monogram.presentation.features.chats.currentChat.components.chats.MessageViaBotAttribution -import org.monogram.presentation.features.chats.currentChat.components.chats.ReplyMarkupView - -@Composable -fun ChannelMessageBubbleContainer( - msg: MessageModel, - olderMsg: MessageModel?, - newerMsg: MessageModel?, - autoplayGifs: Boolean = true, - autoplayVideos: Boolean = true, - autoDownloadFiles: Boolean = false, - highlighted: Boolean = false, - onHighlightConsumed: () -> Unit = {}, - onPhotoClick: (MessageModel) -> Unit, - onDownloadPhoto: (Int) -> Unit = {}, - onVideoClick: (MessageModel) -> Unit = {}, - onDocumentClick: (MessageModel) -> Unit = {}, - onAudioClick: (MessageModel) -> Unit = {}, - onReplyClick: (Offset, IntSize, Offset) -> Unit, - onGoToReply: (MessageModel) -> Unit = {}, - autoDownloadMobile: Boolean = false, - autoDownloadWifi: Boolean = false, - autoDownloadRoaming: Boolean = false, - onReactionClick: (Long, String) -> Unit = { _, _ -> }, - onReplyMarkupButtonClick: (Long, InlineKeyboardButtonModel) -> Unit = { _, _ -> }, - onYouTubeClick: ((String) -> Unit)? = null, - onInstantViewClick: ((String) -> Unit)? = null, - fontSize: Float, - letterSpacing: Float, - bubbleRadius: Float, - onCommentsClick: (Long) -> Unit = {}, - showComments: Boolean = true, - toProfile: (Long) -> Unit = {}, - onViaBotClick: (String) -> Unit = {}, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool -) { - val configuration = LocalConfiguration.current - val screenWidth = configuration.screenWidthDp.dp - val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE - - val maxWidth = if (isLandscape) { - (screenWidth * 0.6f).coerceAtMost(450.dp) - } else { - (screenWidth * 0.92f).coerceAtMost(480.dp) - } - - val isSameSenderAbove = olderMsg?.senderId == msg.senderId && !shouldShowDate(msg, olderMsg) - val isSameSenderBelow = newerMsg != null && newerMsg.senderId == msg.senderId && !shouldShowDate(newerMsg, msg) - - val topSpacing = if (!isSameSenderAbove) 12.dp else 2.dp - - val highlightColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f) - val animatedColor = remember { Animatable(Color.Transparent) } - - LaunchedEffect(highlighted) { - if (highlighted) { - animatedColor.animateTo(highlightColor, animationSpec = tween(300)) - delay(450) - animatedColor.animateTo(Color.Transparent, animationSpec = tween(1800)) - onHighlightConsumed() - } - } - - Column( - modifier = Modifier - .fillMaxWidth() - .background(animatedColor.value, RoundedCornerShape(12.dp)) - .padding(top = topSpacing) - ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.Start, - verticalAlignment = Alignment.Bottom - ) { - Spacer(modifier = Modifier.width(12.dp)) - - Column( - modifier = Modifier - .fillMaxWidth() - .widthIn(max = maxWidth) - ) { - var bubblePosition by remember { mutableStateOf(Offset.Zero) } - var bubbleSize by remember { mutableStateOf(IntSize.Zero) } - val bubbleModifier = Modifier - .onGloballyPositioned { coordinates -> - bubblePosition = coordinates.positionInWindow() - bubbleSize = coordinates.size - } - .pointerInput(Unit) { - detectTapGestures( - onTap = { offset -> - onReplyClick(bubblePosition, bubbleSize, bubblePosition + offset) - }, - onLongPress = { offset -> - onReplyClick(bubblePosition, bubbleSize, bubblePosition + offset) - } - ) - } - - when (val content = msg.content) { - is MessageContent.Text -> { - ChannelTextMessageBubble( - content = content, - msg = msg, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - bubbleRadius = bubbleRadius, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - onYouTubeClick = onYouTubeClick, - onInstantViewClick = onInstantViewClick, - toProfile = toProfile, - modifier = bubbleModifier.fillMaxWidth() - ) - } - - is MessageContent.Photo -> { - ChannelPhotoMessageBubble( - content = content, - msg = msg, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - onPhotoClick = onPhotoClick, - onDownloadPhoto = onDownloadPhoto, - onLongClick = { offset -> onReplyClick(bubblePosition, bubbleSize, offset) }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - modifier = bubbleModifier.fillMaxWidth(), - downloadUtils = downloadUtils - ) - } - - is MessageContent.Video -> { - ChannelVideoMessageBubble( - content = content, - msg = msg, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - autoplayVideos = autoplayVideos, - onVideoClick = onVideoClick, - onLongClick = { offset -> onReplyClick(bubblePosition, bubbleSize, offset) }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - modifier = bubbleModifier.fillMaxWidth(), - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool - ) - } - - is MessageContent.Voice -> { - ChannelVoiceMessageBubble( - content = content, - msg = msg, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - bubbleRadius = bubbleRadius, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - autoDownloadFiles = autoDownloadFiles, - onVoiceClick = onAudioClick, - onLongClick = { offset -> onReplyClick(bubblePosition, bubbleSize, offset) }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - onCommentsClick = onCommentsClick, - showComments = showComments, - toProfile = toProfile, - modifier = bubbleModifier.fillMaxWidth(), - downloadUtils = downloadUtils - ) - } - - is MessageContent.Document -> { - DocumentMessageBubble( - content = content, - msg = msg, - isOutgoing = false, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - autoDownloadFiles = autoDownloadFiles, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - onDocumentClick = onDocumentClick, - onLongClick = { offset -> - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + offset - ) - }, - modifier = bubbleModifier.fillMaxWidth(), - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - downloadUtils = downloadUtils - ) - } - - is MessageContent.Gif -> { - ChannelGifMessageBubble( - content = content, - msg = msg, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - autoplayGifs = autoplayGifs, - onGifClick = onVideoClick, - onLongClick = { offset -> onReplyClick(bubblePosition, bubbleSize, offset) }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - modifier = bubbleModifier.fillMaxWidth(), - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool - ) - } - - else -> {} - } - - msg.replyMarkup?.let { markup -> - ReplyMarkupView( - replyMarkup = markup, - onButtonClick = { onReplyMarkupButtonClick(msg.id, it) } - ) - } - - MessageViaBotAttribution( - msg = msg, - isOutgoing = msg.isOutgoing, - onViaBotClick = onViaBotClick, - modifier = Modifier.align(Alignment.Start) - ) - } - Spacer(modifier = Modifier.width(12.dp)) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/ChatInputBar.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/ChatInputBar.kt deleted file mode 100644 index a16f3b40..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/ChatInputBar.kt +++ /dev/null @@ -1,2236 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components - -import android.Manifest -import android.content.Context -import android.content.pm.PackageManager -import android.os.Build -import android.text.format.DateFormat -import android.widget.Toast -import androidx.activity.compose.BackHandler -import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.animation.* -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.spring -import androidx.compose.animation.core.tween -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.horizontalScroll -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowBack -import androidx.compose.material.icons.automirrored.outlined.Subject -import androidx.compose.material.icons.filled.Check -import androidx.compose.material.icons.filled.Schedule -import androidx.compose.material.icons.outlined.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.TransformOrigin -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.platform.* -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.TextRange -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.input.TextFieldValue -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.window.Dialog -import androidx.compose.ui.window.DialogProperties -import androidx.core.content.ContextCompat -import org.monogram.domain.models.* -import org.monogram.domain.repository.InlineBotResultsModel -import org.monogram.domain.repository.StickerRepository -import org.monogram.presentation.R -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.features.camera.CameraScreen -import org.monogram.presentation.features.chats.currentChat.components.chats.BotCommandSuggestions -import org.monogram.presentation.features.chats.currentChat.components.chats.getEmojiFontFamily -import org.monogram.presentation.features.chats.currentChat.components.inputbar.* -import org.monogram.presentation.features.gallery.GalleryScreen -import org.monogram.presentation.features.stickers.ui.menu.StickerEmojiMenu -import java.io.File -import java.io.FileOutputStream -import java.util.* -import kotlinx.coroutines.delay - -@Immutable -data class ChatInputBarState( - val replyMessage: MessageModel? = null, - val editingMessage: MessageModel? = null, - val draftText: String = "", - val pendingMediaPaths: List = emptyList(), - val isClosed: Boolean = false, - val permissions: ChatPermissionsModel = ChatPermissionsModel(), - val isAdmin: Boolean = false, - val isChannel: Boolean = false, - val isBot: Boolean = false, - val botCommands: List = emptyList(), - val botMenuButton: BotMenuButtonModel = BotMenuButtonModel.Default, - val replyMarkup: ReplyMarkupModel? = null, - val mentionSuggestions: List = emptyList(), - val inlineBotResults: InlineBotResultsModel? = null, - val currentInlineBotUsername: String? = null, - val currentInlineQuery: String? = null, - val isInlineBotLoading: Boolean = false, - val attachBots: List = emptyList(), - val scheduledMessages: List = emptyList(), - val isPremiumUser: Boolean = false, -) - -@Immutable -data class ChatInputBarActions( - val onSend: (String, List, MessageSendOptions) -> Unit, - val onStickerClick: (String) -> Unit = {}, - val onGifClick: (GifModel) -> Unit = {}, - val onAttachClick: () -> Unit = {}, - val onCameraClick: () -> Unit = {}, - val onSendVoice: (String, Int, ByteArray) -> Unit = { _, _, _ -> }, - val onCancelReply: () -> Unit = {}, - val onCancelEdit: () -> Unit = {}, - val onSaveEdit: (String, List) -> Unit = { _, _ -> }, - val onDraftChange: (String) -> Unit = {}, - val onTyping: () -> Unit = {}, - val onCancelMedia: () -> Unit = {}, - val onSendMedia: (List, String, List, MessageSendOptions) -> Unit = { _, _, _, _ -> }, - val onMediaOrderChange: (List) -> Unit = {}, - val onMediaClick: (String) -> Unit = {}, - val onShowBotCommands: () -> Unit = {}, - val onReplyMarkupButtonClick: (KeyboardButtonModel) -> Unit = {}, - val onOpenMiniApp: (String, String) -> Unit = { _, _ -> }, - val onMentionQueryChange: (String?) -> Unit = {}, - val onInlineQueryChange: (String, String) -> Unit = { _, _ -> }, - val onLoadMoreInlineResults: (String) -> Unit = {}, - val onSendInlineResult: (String) -> Unit = {}, - val onInlineSwitchPm: (String, String) -> Unit = { _, _ -> }, - val onAttachBotClick: (AttachMenuBotModel) -> Unit = {}, - val onGalleryClick: () -> Unit = {}, - val onRefreshScheduledMessages: () -> Unit = {}, - val onEditScheduledMessage: (MessageModel) -> Unit = {}, - val onDeleteScheduledMessage: (MessageModel) -> Unit = {}, - val onSendScheduledNow: (MessageModel) -> Unit = {}, -) - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ChatInputBar( - state: ChatInputBarState, - actions: ChatInputBarActions, - appPreferences: AppPreferences, - videoPlayerPool: VideoPlayerPool, - stickerRepository: StickerRepository -) { - if (state.isClosed) { - ClosedTopicBar() - return - } - - val context = LocalContext.current - val emojiStyle by appPreferences.emojiStyle.collectAsState() - val emojiFontFamily = remember(context, emojiStyle) { getEmojiFontFamily(context, emojiStyle) } - - val canWriteText = remember(state.isChannel, state.isAdmin, state.permissions.canSendBasicMessages) { - if (state.isChannel) true else (state.isAdmin || state.permissions.canSendBasicMessages) - } - val canSendMedia = remember( - state.isChannel, - state.isAdmin, - state.permissions.canSendPhotos, - state.permissions.canSendVideos, - state.permissions.canSendDocuments - ) { - if (state.isChannel) true else (state.isAdmin || (state.permissions.canSendPhotos || state.permissions.canSendVideos || state.permissions.canSendDocuments)) - } - val canSendStickers = remember(state.isChannel, state.isAdmin, state.permissions.canSendOtherMessages) { - if (state.isChannel) true else (state.isAdmin || state.permissions.canSendOtherMessages) - } - val canSendVoice = remember(state.isChannel, state.isAdmin, state.permissions.canSendVoiceNotes) { - if (state.isChannel) true else (state.isAdmin || state.permissions.canSendVoiceNotes) - } - - var textValue by remember { mutableStateOf(TextFieldValue(state.draftText)) } - var isStickerMenuVisible by remember { mutableStateOf(false) } - var closeStickerMenuWithoutSlide by remember { mutableStateOf(false) } - var openStickerMenuAfterKeyboardClosed by remember { mutableStateOf(false) } - var openKeyboardAfterStickerMenuClosed by remember { mutableStateOf(false) } - var isVideoMessageMode by remember { mutableStateOf(false) } - var isGifSearchFocused by remember { mutableStateOf(false) } - var showGallery by remember { mutableStateOf(false) } // New state for gallery visibility - var showCamera by remember { mutableStateOf(false) } // New state for camera visibility - var showFullScreenEditor by remember { mutableStateOf(false) } - var showFullScreenEmojiPicker by remember { mutableStateOf(false) } - var showFullScreenLinkDialog by remember { mutableStateOf(false) } - var fullScreenLinkValue by remember { mutableStateOf("https://") } - var showFullScreenLanguageDialog by remember { mutableStateOf(false) } - var fullScreenLanguageValue by remember { mutableStateOf("") } - var showSendOptionsSheet by remember { mutableStateOf(false) } - var showScheduleDatePicker by remember { mutableStateOf(false) } - var showScheduleTimePicker by remember { mutableStateOf(false) } - var pendingScheduleDateMillis by remember { mutableStateOf(null) } - var showScheduledMessagesSheet by remember { mutableStateOf(false) } - - val knownCustomEmojis = remember { mutableStateMapOf() } - - val focusManager = LocalFocusManager.current - val keyboardController = LocalSoftwareKeyboardController.current - val focusRequester = remember { FocusRequester() } - val fullScreenFocusRequester = remember { FocusRequester() } - fun hideKeyboardAndClearFocus(force: Boolean = true) { - keyboardController?.hide() - focusManager.clearFocus(force = force) - } - val configuration = LocalConfiguration.current - val density = LocalDensity.current - val imeBottomPx = WindowInsets.ime.getBottom(density) - val isKeyboardVisible = imeBottomPx > 0 - var lastImeHeightPx by remember { mutableIntStateOf(0) } - LaunchedEffect(imeBottomPx) { - if (imeBottomPx > 0) { - lastImeHeightPx = imeBottomPx - } - } - val stickerMenuHeight = with(density) { - val imeHeightDp = maxOf(imeBottomPx, lastImeHeightPx).toDp() - val fallbackHeightDp = maxOf(configuration.screenHeightDp.dp * 0.42f, 320.dp) - maxOf(imeHeightDp, fallbackHeightDp) - } - val transitionHoldBottomInset = with(density) { - if (!isKeyboardVisible && !isStickerMenuVisible && (openStickerMenuAfterKeyboardClosed || openKeyboardAfterStickerMenuClosed)) { - lastImeHeightPx.toDp() - } else { - 0.dp - } - } - - LaunchedEffect(isKeyboardVisible, openStickerMenuAfterKeyboardClosed) { - if (!isKeyboardVisible && openStickerMenuAfterKeyboardClosed) { - openStickerMenuAfterKeyboardClosed = false - closeStickerMenuWithoutSlide = false - isStickerMenuVisible = true - } - } - - LaunchedEffect(isKeyboardVisible, openKeyboardAfterStickerMenuClosed) { - if (isKeyboardVisible && openKeyboardAfterStickerMenuClosed) { - openKeyboardAfterStickerMenuClosed = false - } - } - - LaunchedEffect(showGallery) { - if (showGallery) { - openStickerMenuAfterKeyboardClosed = false - openKeyboardAfterStickerMenuClosed = false - closeStickerMenuWithoutSlide = false - isStickerMenuVisible = false - hideKeyboardAndClearFocus() - } - } - - var lastEditingMessageId by remember { mutableStateOf(null) } - - val voiceRecorder = rememberVoiceRecorder(onRecordingFinished = actions.onSendVoice) - val maxMessageLength = remember(state.pendingMediaPaths, state.isPremiumUser) { - if (state.pendingMediaPaths.isNotEmpty() && !state.isPremiumUser) 1024 else 4096 - } - val currentMessageLength = textValue.text.length - val isOverMessageLimit = currentMessageLength > maxMessageLength - - val sendWithOptions: (MessageSendOptions) -> Unit = sendWithOptions@{ - if (isOverMessageLimit) return@sendWithOptions - val isTextEmpty = textValue.text.isBlank() - val captionEntities = extractEntities(textValue.annotatedString, knownCustomEmojis) - - if (state.pendingMediaPaths.isNotEmpty() && canSendMedia) { - actions.onSendMedia(state.pendingMediaPaths, textValue.text, captionEntities, it) - textValue = TextFieldValue("") - knownCustomEmojis.clear() - } else if (state.editingMessage != null && canWriteText) { - if (!isTextEmpty) { - actions.onSaveEdit(textValue.text, captionEntities) - } - } else if (canWriteText && !isTextEmpty) { - actions.onSend(textValue.text, captionEntities, it) - textValue = TextFieldValue("") - knownCustomEmojis.clear() - } - - if (it.scheduleDate != null) { - actions.onRefreshScheduledMessages() - } - } - - val filteredCommands = remember(textValue.text, state.botCommands) { - if (textValue.text.startsWith("/")) { - val query = textValue.text.substring(1).lowercase() - state.botCommands.filter { it.command.lowercase().startsWith(query) } - } else { - emptyList() - } - } - - val currentOnMentionQueryChange by rememberUpdatedState(actions.onMentionQueryChange) - LaunchedEffect(textValue.text, textValue.selection) { - val text = textValue.text - val selection = textValue.selection - if (selection.collapsed && selection.start > 0) { - val lastAt = text.lastIndexOf('@', selection.start - 1) - if (lastAt != -1) { - val isStartOfWord = lastAt == 0 || text[lastAt - 1].isWhitespace() - if (isStartOfWord) { - val query = text.substring(lastAt + 1, selection.start) - if (!query.contains(' ')) { - currentOnMentionQueryChange(query) - } else { - currentOnMentionQueryChange(null) - } - } else { - currentOnMentionQueryChange(null) - } - } else { - currentOnMentionQueryChange(null) - } - } else { - currentOnMentionQueryChange(null) - } - } - - val currentOnInlineQueryChange by rememberUpdatedState(actions.onInlineQueryChange) - LaunchedEffect(textValue.text, textValue.selection) { - val inlineQuery = parseInlineQueryInput( - text = textValue.text, - selection = textValue.selection - ) - - if (inlineQuery != null) { - currentOnInlineQueryChange(inlineQuery.botUsername, inlineQuery.query) - } else { - currentOnInlineQueryChange("", "") - } - } - - LaunchedEffect(state.draftText) { - val shouldApplyInlinePrefill = - state.editingMessage == null && - state.draftText.isInlineBotPrefillText() && - state.draftText != textValue.text - - if (shouldApplyInlinePrefill || (textValue.text.isEmpty() && state.draftText.isNotEmpty())) { - textValue = TextFieldValue(state.draftText, TextRange(state.draftText.length)) - if (shouldApplyInlinePrefill) { - focusRequester.requestFocus() - } - } - } - - val currentOnDraftChange by rememberUpdatedState(actions.onDraftChange) - val currentOnTyping by rememberUpdatedState(actions.onTyping) - LaunchedEffect(textValue.text) { - if (state.editingMessage == null && textValue.text != state.draftText) { - currentOnDraftChange(textValue.text) - } - if (textValue.text.isNotEmpty()) { - currentOnTyping() - } - } - - LaunchedEffect(state.editingMessage) { - val editingMessage = state.editingMessage - if (editingMessage != null) { - if (editingMessage.id != lastEditingMessageId) { - val content = editingMessage.content - if (content is MessageContent.Text) { - knownCustomEmojis.clear() - content.entities.forEach { entity -> - if (entity.type is MessageEntityType.CustomEmoji) { - val type = entity.type as MessageEntityType.CustomEmoji - if (type.path != null) { - knownCustomEmojis[type.emojiId] = StickerModel( - id = type.emojiId, - customEmojiId = type.emojiId, - width = 0, - height = 0, - emoji = "", - path = type.path, - format = StickerFormat.UNKNOWN - ) - } - } - } - - val annotatedText = buildAnnotatedString { - append(content.text) - content.entities.forEach { entity -> - when (val type = entity.type) { - is MessageEntityType.CustomEmoji -> { - addStringAnnotation( - CUSTOM_EMOJI_TAG, - type.emojiId.toString(), - entity.offset, - entity.offset + entity.length - ) - } - - is MessageEntityType.TextMention -> { - addStringAnnotation( - MENTION_TAG, - type.userId.toString(), - entity.offset, - entity.offset + entity.length - ) - } - - else -> { - val richEntity = richEntityToAnnotation(type) - if (richEntity != null) { - addStringAnnotation( - RICH_ENTITY_TAG, - richEntity, - entity.offset, - entity.offset + entity.length - ) - } - } - } - } - } - - textValue = TextFieldValue(annotatedText, TextRange(content.text.length)) - focusRequester.requestFocus() - } - lastEditingMessageId = editingMessage.id - } - } else { - if (lastEditingMessageId != null) { - textValue = TextFieldValue(state.draftText, TextRange(state.draftText.length)) - lastEditingMessageId = null - knownCustomEmojis.clear() - } - } - } - - BackHandler(enabled = isStickerMenuVisible || openStickerMenuAfterKeyboardClosed || openKeyboardAfterStickerMenuClosed || state.pendingMediaPaths.isNotEmpty() || showGallery || showCamera || showFullScreenEditor || showSendOptionsSheet || showScheduledMessagesSheet || showFullScreenEmojiPicker || showScheduleDatePicker || showScheduleTimePicker) { - if (isGifSearchFocused) { - focusManager.clearFocus() - } else if (openStickerMenuAfterKeyboardClosed) { - openStickerMenuAfterKeyboardClosed = false - } else if (openKeyboardAfterStickerMenuClosed) { - openKeyboardAfterStickerMenuClosed = false - } else if (isStickerMenuVisible) { - closeStickerMenuWithoutSlide = false - isStickerMenuVisible = false - } else if (showFullScreenEmojiPicker) { - showFullScreenEmojiPicker = false - } else if (showScheduleTimePicker) { - showScheduleTimePicker = false - pendingScheduleDateMillis = null - } else if (showScheduleDatePicker) { - showScheduleDatePicker = false - pendingScheduleDateMillis = null - } else if (showSendOptionsSheet) { - showSendOptionsSheet = false - } else if (showScheduledMessagesSheet) { - showScheduledMessagesSheet = false - } else if (showFullScreenEditor) { - showFullScreenEditor = false - } else if (state.pendingMediaPaths.isNotEmpty()) { - actions.onCancelMedia() - } else if (showGallery) { - showGallery = false - } else if (showCamera) { - showCamera = false - } - } - - // Gallery permissions - val galleryPermissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - listOf(Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_VIDEO) - } else { - listOf(Manifest.permission.READ_EXTERNAL_STORAGE) - } - val requestableGalleryPermissions = remember(context, galleryPermissions) { - val declared = context.declaredPermissions() - galleryPermissions.filter { it in declared } - } - val hasGalleryPermission = remember(context) { - mutableStateOf( - requestableGalleryPermissions.isEmpty() || context.hasAllPermissions(requestableGalleryPermissions) - ) - } - val galleryPermissionLauncher = rememberLauncherForActivityResult( - ActivityResultContracts.RequestMultiplePermissions() - ) { result -> - val granted = result.values.all { it } - hasGalleryPermission.value = granted - if (granted || requestableGalleryPermissions.isEmpty()) showGallery = true - } - - // Camera permission - val hasCameraPermission = remember(context) { - mutableStateOf( - ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED - ) - } - val cameraPermissionLauncher = rememberLauncherForActivityResult( - ActivityResultContracts.RequestPermission() - ) { granted -> - hasCameraPermission.value = granted - if (granted) showCamera = true - } - - if (showCamera) { - CameraScreen( - onImageCaptured = { uri -> - val path = context.copyUriToTempPath(uri) - if (path != null) { - actions.onMediaOrderChange((state.pendingMediaPaths + path).distinct()) - } - showCamera = false - }, - onDismiss = { showCamera = false } - ) - } else { - Box { - Surface( - color = MaterialTheme.colorScheme.surface, - tonalElevation = 2.dp - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .imePadding() - .padding(bottom = transitionHoldBottomInset) - ) { - InputPreviewSection( - editingMessage = state.editingMessage, - replyMessage = state.replyMessage, - pendingMediaPaths = state.pendingMediaPaths, - onCancelEdit = actions.onCancelEdit, - onCancelReply = actions.onCancelReply, - onCancelMedia = actions.onCancelMedia, - onMediaOrderChange = actions.onMediaOrderChange, - onMediaClick = actions.onMediaClick - ) - - AnimatedVisibility( - visible = state.mentionSuggestions.isNotEmpty(), - enter = expandVertically(expandFrom = Alignment.Bottom) + fadeIn(), - exit = shrinkVertically(shrinkTowards = Alignment.Bottom) + fadeOut() - ) { - MentionSuggestions( - suggestions = state.mentionSuggestions, - onMentionClick = { user -> - val text = textValue.text - val selection = textValue.selection - val lastAt = text.lastIndexOf('@', selection.start - 1) - if (lastAt != -1) { - val mentionText = user.username ?: user.firstName - val newText = text.replaceRange(lastAt + 1, selection.start, "$mentionText ") - - val annotatedBuilder = AnnotatedString.Builder() - annotatedBuilder.append(newText) - - textValue.annotatedString.getStringAnnotations(0, text.length).forEach { annotation -> - if (annotation.start < lastAt) { - annotatedBuilder.addStringAnnotation( - annotation.tag, - annotation.item, - annotation.start, - annotation.end - ) - } else if (annotation.start >= selection.start) { - val offset = (mentionText.length + 1) - (selection.start - (lastAt + 1)) - annotatedBuilder.addStringAnnotation( - annotation.tag, - annotation.item, - annotation.start + offset, - annotation.end + offset - ) - } - } - - if (user.username == null) { - annotatedBuilder.addStringAnnotation( - MENTION_TAG, - user.id.toString(), - lastAt, - lastAt + mentionText.length + 1 - ) - } - - textValue = TextFieldValue( - annotatedString = annotatedBuilder.toAnnotatedString(), - selection = TextRange(lastAt + mentionText.length + 2) - ) - } - actions.onMentionQueryChange(null) - }, - videoPlayerPool = videoPlayerPool - ) - } - - AnimatedVisibility( - visible = filteredCommands.isNotEmpty(), - enter = expandVertically() + fadeIn(), - exit = shrinkVertically() + fadeOut() - ) { - BotCommandSuggestions( - commands = filteredCommands, - onCommandClick = { command -> - actions.onSend("/$command", emptyList(), MessageSendOptions()) - textValue = TextFieldValue("") - }, - modifier = Modifier.fillMaxWidth() - ) - } - - AnimatedVisibility( - visible = state.currentInlineBotUsername != null || state.isInlineBotLoading, - enter = expandVertically() + fadeIn(), - exit = shrinkVertically() + fadeOut() - ) { - InlineBotResults( - inlineBotResults = state.inlineBotResults, - isInlineMode = state.currentInlineBotUsername != null, - isLoading = state.isInlineBotLoading, - onResultClick = { resultId -> - actions.onSendInlineResult(resultId) - textValue = TextFieldValue("") - }, - onSwitchPmClick = { text -> - state.currentInlineBotUsername?.let { username -> - actions.onInlineSwitchPm(username, text) - } - }, - onLoadMore = { offset -> - actions.onLoadMoreInlineResults(offset) - } - ) - } - - AnimatedVisibility( - visible = !isGifSearchFocused, - enter = expandVertically(animationSpec = tween(200)), - exit = shrinkVertically(animationSpec = tween(200)) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 8.dp, vertical = 8.dp), - verticalAlignment = Alignment.Bottom - ) { - AnimatedVisibility( - visible = !voiceRecorder.isRecording, - enter = fadeIn() + expandHorizontally(), - exit = fadeOut() + shrinkHorizontally() - ) { - InputBarLeadingIcons( - editingMessage = state.editingMessage, - pendingMediaPaths = state.pendingMediaPaths, - canSendMedia = canSendMedia, - onAttachClick = { - openStickerMenuAfterKeyboardClosed = false - openKeyboardAfterStickerMenuClosed = false - closeStickerMenuWithoutSlide = false - isStickerMenuVisible = false - hideKeyboardAndClearFocus() - showGallery = true - } - ) - } - - Box( - modifier = Modifier - .weight(1f) - .padding(start = if (voiceRecorder.isRecording) 0.dp else 4.dp) - ) { - AnimatedContent( - targetState = voiceRecorder.isRecording, - transitionSpec = { - (fadeIn() + scaleIn()).togetherWith(fadeOut() + scaleOut()) - }, - label = "InputContent" - ) { isRecording -> - if (isRecording) { - RecordingUI( - voiceRecorderState = voiceRecorder, - onStop = { voiceRecorder.stopRecording(cancel = false) }, - onCancel = { voiceRecorder.stopRecording(cancel = true) }, - modifier = Modifier.fillMaxWidth() - ) - } else { - InputTextFieldContainer( - textValue = textValue, - onValueChange = { incoming -> - textValue = - mergeInputTextValuePreservingAnnotations(textValue, incoming) - }, - onRichTextValueChange = { incoming -> - textValue = incoming - }, - isBot = state.isBot, - botMenuButton = state.botMenuButton, - botCommands = state.botCommands, - canSendStickers = canSendStickers, - canWriteText = canWriteText, - isStickerMenuVisible = isStickerMenuVisible, - onStickerMenuToggle = { - if (isStickerMenuVisible) { - openStickerMenuAfterKeyboardClosed = false - openKeyboardAfterStickerMenuClosed = true - closeStickerMenuWithoutSlide = true - isStickerMenuVisible = false - focusRequester.requestFocus() - } else { - openKeyboardAfterStickerMenuClosed = false - closeStickerMenuWithoutSlide = false - if (isKeyboardVisible) { - openStickerMenuAfterKeyboardClosed = true - hideKeyboardAndClearFocus() - } else { - openStickerMenuAfterKeyboardClosed = false - isStickerMenuVisible = true - focusManager.clearFocus() - } - } - }, - onShowBotCommands = { - openStickerMenuAfterKeyboardClosed = false - openKeyboardAfterStickerMenuClosed = false - closeStickerMenuWithoutSlide = false - isStickerMenuVisible = false - hideKeyboardAndClearFocus() - actions.onShowBotCommands() - }, - onOpenMiniApp = actions.onOpenMiniApp, - knownCustomEmojis = knownCustomEmojis, - emojiFontFamily = emojiFontFamily, - focusRequester = focusRequester, - pendingMediaPaths = state.pendingMediaPaths, - onFocus = { - openStickerMenuAfterKeyboardClosed = false - openKeyboardAfterStickerMenuClosed = false - if (isStickerMenuVisible) { - closeStickerMenuWithoutSlide = true - } - isStickerMenuVisible = false - }, - onOpenFullScreenEditor = { showFullScreenEditor = true }, - modifier = Modifier.fillMaxWidth() - ) - } - } - } - - if (!voiceRecorder.isLocked) { - if (state.scheduledMessages.isNotEmpty()) { - IconButton(onClick = { - actions.onRefreshScheduledMessages() - showScheduledMessagesSheet = true - }) { - Icon( - imageVector = Icons.Default.Schedule, - contentDescription = stringResource(R.string.action_scheduled_messages), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - - Spacer(modifier = Modifier.width(8.dp)) - - Box(contentAlignment = Alignment.CenterEnd) { - InputBarSendButton( - textValue = textValue, - editingMessage = state.editingMessage, - pendingMediaPaths = state.pendingMediaPaths, - isOverCharLimit = isOverMessageLimit, - canWriteText = canWriteText, - canSendVoice = canSendVoice, - canSendMedia = canSendMedia, - isVideoMessageMode = isVideoMessageMode, - onSendWithOptions = sendWithOptions, - onShowSendOptionsMenu = { - openStickerMenuAfterKeyboardClosed = false - openKeyboardAfterStickerMenuClosed = false - closeStickerMenuWithoutSlide = false - isStickerMenuVisible = false - hideKeyboardAndClearFocus() - showSendOptionsSheet = true - actions.onRefreshScheduledMessages() - }, - onCameraClick = { - hideKeyboardAndClearFocus() - actions.onCameraClick() - }, - onVideoModeToggle = { isVideoMessageMode = !isVideoMessageMode }, - onVoiceStart = { - hideKeyboardAndClearFocus() - voiceRecorder.startRecording() - }, - onVoiceStop = { cancel -> voiceRecorder.stopRecording(cancel) }, - onVoiceLock = { voiceRecorder.lockRecording() } - ) - - SendOptionsPopup( - expanded = showSendOptionsSheet, - scheduledMessagesCount = state.scheduledMessages.size, - onDismiss = { showSendOptionsSheet = false }, - onSendSilent = { - showSendOptionsSheet = false - sendWithOptions(MessageSendOptions(silent = true)) - }, - onScheduleMessage = { - showSendOptionsSheet = false - pendingScheduleDateMillis = null - showScheduleDatePicker = true - }, - onOpenScheduledMessages = { - showSendOptionsSheet = false - showScheduledMessagesSheet = true - actions.onRefreshScheduledMessages() - } - ) - } - } - } - } - - AnimatedVisibility( - visible = !voiceRecorder.isRecording && - !showFullScreenEditor && - currentMessageLength > 1000, - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically() - ) { - Text( - text = stringResource( - R.string.message_length_counter, - currentMessageLength, - maxMessageLength - ), - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp), - textAlign = TextAlign.End, - style = MaterialTheme.typography.labelSmall, - color = if (isOverMessageLimit) { - MaterialTheme.colorScheme.error - } else { - MaterialTheme.colorScheme.onSurfaceVariant - } - ) - } - - AnimatedVisibility( - visible = state.replyMarkup is ReplyMarkupModel.ShowKeyboard && textValue.text.isEmpty() && !isStickerMenuVisible && !isKeyboardVisible, - enter = expandVertically() + fadeIn(), - exit = shrinkVertically() + fadeOut() - ) { - KeyboardMarkupView( - markup = state.replyMarkup as ReplyMarkupModel.ShowKeyboard, - onButtonClick = actions.onReplyMarkupButtonClick, - onOpenMiniApp = actions.onOpenMiniApp - ) - } - - AnimatedVisibility( - visible = isStickerMenuVisible, - enter = slideInVertically( - animationSpec = tween(220), - initialOffsetY = { it } - ) + fadeIn(animationSpec = tween(170)), - exit = if (closeStickerMenuWithoutSlide) { - fadeOut(animationSpec = tween(90)) - } else { - slideOutVertically( - animationSpec = tween(170), - targetOffsetY = { it } - ) + fadeOut(animationSpec = tween(120)) - } - ) { - StickerEmojiMenu( - onStickerSelected = { sticker -> - actions.onStickerClick(sticker) - }, - onEmojiSelected = { emoji, sticker -> - textValue = insertEmojiAtSelection( - value = textValue, - emoji = emoji, - sticker = sticker, - knownCustomEmojis = knownCustomEmojis - ) - }, - onGifSelected = { gif -> - actions.onGifClick(gif) - }, - onSearchFocused = { focused -> - isGifSearchFocused = focused - }, - panelHeight = stickerMenuHeight, - videoPlayerPool = videoPlayerPool, - stickerRepository = stickerRepository - ) - } - Spacer(Modifier.navigationBarsPadding()) - } - } - - if (showGallery) { - GalleryScreen( - onMediaSelected = { uris -> - val localPaths = uris.mapNotNull { uri -> - context.copyUriToTempPath(uri) - } - if (localPaths.isNotEmpty()) { - actions.onMediaOrderChange((state.pendingMediaPaths + localPaths).distinct()) - } - showGallery = false - }, - onDismiss = { showGallery = false }, - onCameraClick = { - showGallery = false - if (hasCameraPermission.value || ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { - showCamera = true - } else { - cameraPermissionLauncher.launch(Manifest.permission.CAMERA) - } - }, - attachBots = state.attachBots, - hasMediaAccess = hasGalleryPermission.value || requestableGalleryPermissions.isEmpty() || context.hasAllPermissions( - requestableGalleryPermissions - ), - onPickFromOtherSources = { - showGallery = false - actions.onAttachClick() - }, - onRequestMediaAccess = { - if (requestableGalleryPermissions.isNotEmpty()) { - galleryPermissionLauncher.launch(requestableGalleryPermissions.toTypedArray()) - } - }, - onAttachBotClick = { bot -> - showGallery = false - actions.onAttachBotClick(bot) - } - ) - } - - if (showFullScreenEditor) { - val editorEntities = remember(textValue.annotatedString, knownCustomEmojis.size) { - extractEntities(textValue.annotatedString, knownCustomEmojis) - } - val richEntityCount = remember(editorEntities) { - editorEntities.count { richEntityToAnnotation(it.type) != null } - } - val hasFormattableSelectionInEditor = hasFormattableSelection(textValue) - val fullScreenContainerColor = MaterialTheme.colorScheme.surfaceContainerLow - val fullScreenFieldColor = MaterialTheme.colorScheme.surfaceContainerHigh - val fullScreenToolbarColor = MaterialTheme.colorScheme.surfaceContainerHighest - val fullScreenAccentColor = MaterialTheme.colorScheme.primary - - Dialog( - onDismissRequest = { showFullScreenEditor = false }, - properties = DialogProperties(usePlatformDefaultWidth = false) - ) { - Box( - modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.scrim.copy(alpha = 0.58f)) - ) { - Surface( - modifier = Modifier - .align(Alignment.BottomCenter) - .fillMaxWidth() - .fillMaxHeight(0.95f), - shape = RoundedCornerShape(topStart = 28.dp, topEnd = 28.dp), - color = fullScreenContainerColor - ) { - Column( - modifier = Modifier - .fillMaxSize() - .statusBarsPadding() - .navigationBarsPadding() - .imePadding() - .padding(horizontal = 16.dp, vertical = 12.dp) - ) { - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically - ) { - IconButton(onClick = { showFullScreenEditor = false }) { - Icon( - imageVector = Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = stringResource(R.string.action_cancel), - tint = fullScreenAccentColor - ) - } - - Text( - text = stringResource(R.string.fullscreen_editor_title), - style = MaterialTheme.typography.headlineSmall, - color = MaterialTheme.colorScheme.onSurface, - textAlign = TextAlign.Center, - modifier = Modifier.weight(1f) - ) - - IconButton( - onClick = { - sendWithOptions(MessageSendOptions()) - showFullScreenEditor = false - }, - enabled = !isOverMessageLimit - ) { - Icon( - imageVector = Icons.Filled.Check, - contentDescription = stringResource(R.string.action_send), - tint = if (isOverMessageLimit) { - MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.4f) - } else { - fullScreenAccentColor - } - ) - } - } - - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 10.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally) - ) { - FullScreenEditorMetaPill( - text = stringResource( - R.string.message_length_counter, - currentMessageLength, - maxMessageLength - ), - color = if (isOverMessageLimit) { - MaterialTheme.colorScheme.error.copy(alpha = 0.22f) - } else { - fullScreenAccentColor.copy(alpha = 0.2f) - }, - contentColor = if (isOverMessageLimit) { - MaterialTheme.colorScheme.error - } else { - fullScreenAccentColor - } - ) - FullScreenEditorMetaPill( - text = stringResource( - R.string.fullscreen_editor_blocks, - richEntityCount - ), - color = MaterialTheme.colorScheme.secondaryContainer.copy(alpha = 0.45f), - contentColor = MaterialTheme.colorScheme.onSurface - ) - } - - Spacer(modifier = Modifier.height(20.dp)) - - Surface( - modifier = Modifier - .weight(1f) - .fillMaxWidth(), - shape = RoundedCornerShape(24.dp), - color = fullScreenFieldColor - ) { - InputTextField( - textValue = textValue, - onValueChange = { incoming -> - textValue = mergeInputTextValuePreservingAnnotations(textValue, incoming) - }, - onRichTextValueChange = { incoming -> - textValue = incoming - }, - enableContextMenu = false, - enableRichContextActions = false, - canWriteText = canWriteText, - knownCustomEmojis = knownCustomEmojis, - emojiFontFamily = emojiFontFamily, - focusRequester = fullScreenFocusRequester, - pendingMediaPaths = state.pendingMediaPaths, - maxEditorHeight = 860.dp, - onFocus = { isStickerMenuVisible = false }, - modifier = Modifier - .fillMaxSize() - .padding(horizontal = 14.dp) - ) - } - - Spacer(modifier = Modifier.height(12.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically - ) { - Surface( - modifier = Modifier - .weight(1f) - .height(58.dp), - shape = RoundedCornerShape(32.dp), - color = fullScreenToolbarColor - ) { - Row( - modifier = Modifier - .fillMaxSize() - .horizontalScroll(rememberScrollState()) - .padding(horizontal = 8.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(2.dp) - ) { - FullScreenEditorToolButton( - icon = Icons.Outlined.FormatBold, - hint = stringResource(R.string.rich_text_bold), - enabled = hasFormattableSelectionInEditor, - onClick = { - textValue = toggleRichEntity(textValue, MessageEntityType.Bold) - } - ) - FullScreenEditorToolButton( - icon = Icons.Outlined.FormatItalic, - hint = stringResource(R.string.rich_text_italic), - enabled = hasFormattableSelectionInEditor, - onClick = { - textValue = toggleRichEntity(textValue, MessageEntityType.Italic) - } - ) - FullScreenEditorToolButton( - icon = Icons.Outlined.FormatUnderlined, - hint = stringResource(R.string.rich_text_underline), - enabled = hasFormattableSelectionInEditor, - onClick = { - textValue = toggleRichEntity(textValue, MessageEntityType.Underline) - } - ) - FullScreenEditorToolButton( - icon = Icons.Outlined.FormatStrikethrough, - hint = stringResource(R.string.rich_text_strikethrough), - enabled = hasFormattableSelectionInEditor, - onClick = { - textValue = toggleRichEntity( - textValue, - MessageEntityType.Strikethrough - ) - } - ) - FullScreenEditorToolButton( - icon = Icons.Outlined.Code, - hint = stringResource(R.string.rich_text_code), - enabled = hasFormattableSelectionInEditor, - onClick = { - textValue = toggleRichEntity(textValue, MessageEntityType.Code) - } - ) - FullScreenEditorToolButton( - icon = Icons.Outlined.Link, - hint = stringResource(R.string.rich_text_link), - enabled = hasFormattableSelectionInEditor, - onClick = { - val selection = textValue.selection - if (selection.start != selection.end) { - val normalized = if (selection.start <= selection.end) { - selection - } else { - TextRange(selection.end, selection.start) - } - val current = textValue.annotatedString - .getStringAnnotations( - RICH_ENTITY_TAG, - normalized.start, - normalized.end - ) - .firstOrNull { - decodeRichEntity(it.item) is MessageEntityType.TextUrl - } - fullScreenLinkValue = - (current?.let { decodeRichEntity(it.item) } as? MessageEntityType.TextUrl)?.url - ?: "https://" - showFullScreenLinkDialog = true - } - } - ) - FullScreenEditorToolButton( - icon = Icons.Outlined.AlternateEmail, - hint = stringResource(R.string.rich_text_mention), - onClick = { - textValue = insertMentionAtSelection(textValue) - } - ) - FullScreenEditorToolButton( - icon = Icons.AutoMirrored.Outlined.Subject, - hint = stringResource(R.string.rich_text_pre), - enabled = hasFormattableSelectionInEditor, - onClick = { - val selection = textValue.selection - if (selection.start != selection.end) { - val normalized = if (selection.start <= selection.end) { - selection - } else { - TextRange(selection.end, selection.start) - } - val current = textValue.annotatedString - .getStringAnnotations( - RICH_ENTITY_TAG, - normalized.start, - normalized.end - ) - .firstOrNull { - decodeRichEntity(it.item) is MessageEntityType.Pre - } - fullScreenLanguageValue = - (current?.let { decodeRichEntity(it.item) } as? MessageEntityType.Pre)?.language.orEmpty() - showFullScreenLanguageDialog = true - } - } - ) - FullScreenEditorToolButton( - icon = Icons.Outlined.FormatClear, - hint = stringResource(R.string.rich_text_clear), - enabled = hasFormattableSelectionInEditor, - onClick = { - textValue = clearRichFormatting(textValue) - } - ) - } - } - - Spacer(modifier = Modifier.width(10.dp)) - - Surface( - modifier = Modifier.size(58.dp), - shape = CircleShape, - color = fullScreenToolbarColor - ) { - IconButton(onClick = { showFullScreenEmojiPicker = true }) { - Text( - text = "☺", - style = MaterialTheme.typography.headlineSmall, - color = fullScreenAccentColor - ) - } - } - } - - AnimatedVisibility(visible = !isKeyboardVisible) { - Text( - text = stringResource(R.string.fullscreen_editor_hint), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center, - maxLines = 2, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 10.dp, vertical = 8.dp) - ) - } - } - } - } - } - - if (showFullScreenLinkDialog) { - AlertDialog( - onDismissRequest = { showFullScreenLinkDialog = false }, - title = { Text(text = stringResource(R.string.rich_text_link_title)) }, - text = { - OutlinedTextField( - value = fullScreenLinkValue, - onValueChange = { fullScreenLinkValue = it }, - modifier = Modifier.fillMaxWidth(), - singleLine = true, - label = { Text(text = stringResource(R.string.rich_text_link_hint)) } - ) - }, - confirmButton = { - TextButton(onClick = { - val normalizedUrl = normalizeEditorUrl(fullScreenLinkValue) - if (normalizedUrl != null) { - textValue = applyTextUrlEntity(textValue, normalizedUrl) - } - showFullScreenLinkDialog = false - }) { - Text(text = stringResource(R.string.action_apply)) - } - }, - dismissButton = { - TextButton(onClick = { showFullScreenLinkDialog = false }) { - Text(text = stringResource(R.string.action_cancel)) - } - } - ) - } - - if (showFullScreenLanguageDialog) { - AlertDialog( - onDismissRequest = { showFullScreenLanguageDialog = false }, - title = { Text(text = stringResource(R.string.rich_text_code_language_title)) }, - text = { - OutlinedTextField( - value = fullScreenLanguageValue, - onValueChange = { fullScreenLanguageValue = it }, - modifier = Modifier.fillMaxWidth(), - singleLine = true, - label = { Text(text = stringResource(R.string.rich_text_code_language_hint)) } - ) - }, - confirmButton = { - TextButton(onClick = { - textValue = applyPreEntity(textValue, fullScreenLanguageValue) - showFullScreenLanguageDialog = false - }) { - Text(text = stringResource(R.string.action_apply)) - } - }, - dismissButton = { - TextButton(onClick = { showFullScreenLanguageDialog = false }) { - Text(text = stringResource(R.string.action_cancel)) - } - } - ) - } - - if (showFullScreenEmojiPicker) { - ModalBottomSheet( - onDismissRequest = { showFullScreenEmojiPicker = false }, - sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) - ) { - StickerEmojiMenu( - onStickerSelected = {}, - onEmojiSelected = { emoji, sticker -> - textValue = insertEmojiAtSelection( - value = textValue, - emoji = emoji, - sticker = sticker, - knownCustomEmojis = knownCustomEmojis - ) - }, - onGifSelected = {}, - emojiOnlyMode = true, - onSearchFocused = {}, - videoPlayerPool = videoPlayerPool, - stickerRepository = stickerRepository - ) - } - } - - } - - if (showScheduleDatePicker) { - ScheduleDatePickerDialog( - onDismiss = { - showScheduleDatePicker = false - pendingScheduleDateMillis = null - }, - onDateSelected = { selectedDateMillis -> - pendingScheduleDateMillis = selectedDateMillis - showScheduleDatePicker = false - showScheduleTimePicker = true - } - ) - } - - if (showScheduleTimePicker) { - val defaultTime = remember { - Calendar.getInstance().let { now -> now.get(Calendar.HOUR_OF_DAY) to now.get(Calendar.MINUTE) } - } - - ScheduleTimePickerDialog( - initialHour = defaultTime.first, - initialMinute = defaultTime.second, - onDismiss = { - showScheduleTimePicker = false - pendingScheduleDateMillis = null - }, - onConfirm = { hour, minute -> - val selectedDateMillis = pendingScheduleDateMillis - pendingScheduleDateMillis = null - showScheduleTimePicker = false - if (selectedDateMillis != null) { - val scheduleDate = buildScheduledDateEpochSeconds(selectedDateMillis, hour, minute) - sendWithOptions(MessageSendOptions(scheduleDate = scheduleDate)) - } - } - ) - } - - if (showScheduledMessagesSheet) { - val scheduledMessagesSorted = remember(state.scheduledMessages) { - state.scheduledMessages.sortedBy { it.date } - } - val nextScheduled = scheduledMessagesSorted.firstOrNull() - val editableScheduledCount = remember(scheduledMessagesSorted) { - scheduledMessagesSorted.count { canEditScheduledMessage(it) } - } - - ModalBottomSheet( - onDismissRequest = { showScheduledMessagesSheet = false }, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp), - sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .navigationBarsPadding() - .padding(horizontal = 16.dp) - .padding(bottom = 28.dp) - ) { - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Text( - text = stringResource(R.string.action_scheduled_messages), - style = MaterialTheme.typography.headlineSmall, - color = MaterialTheme.colorScheme.onSurface - ) - - Surface( - color = MaterialTheme.colorScheme.primary.copy(alpha = 0.14f), - shape = RoundedCornerShape(12.dp) - ) { - Text( - text = scheduledMessagesSorted.size.toString(), - modifier = Modifier.padding(horizontal = 10.dp, vertical = 4.dp), - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.primary - ) - } - } - - Spacer(modifier = Modifier.height(12.dp)) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(20.dp), - modifier = Modifier.fillMaxWidth() - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(12.dp), - verticalArrangement = Arrangement.spacedBy(6.dp) - ) { - Text( - text = stringResource( - R.string.scheduled_messages_summary_count, - scheduledMessagesSorted.size - ), - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.onSurface - ) - Text( - text = if (nextScheduled != null) { - stringResource( - R.string.scheduled_messages_summary_next, - formatScheduledTimestamp(nextScheduled.date) - ) - } else { - stringResource(R.string.scheduled_messages_empty) - }, - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Text( - text = stringResource( - R.string.scheduled_messages_summary_editable, - editableScheduledCount - ), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - - Spacer(modifier = Modifier.height(10.dp)) - - if (scheduledMessagesSorted.isEmpty()) { - Surface( - color = MaterialTheme.colorScheme.surfaceContainerLow, - shape = RoundedCornerShape(16.dp), - modifier = Modifier.fillMaxWidth() - ) { - Text( - text = stringResource(R.string.scheduled_messages_empty), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(14.dp) - ) - } - } else { - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier - .fillMaxWidth() - .heightIn(max = 380.dp) - ) { - LazyColumn( - contentPadding = PaddingValues(vertical = 6.dp), - verticalArrangement = Arrangement.spacedBy(2.dp) - ) { - itemsIndexed( - scheduledMessagesSorted, - key = { _, message -> message.id }) { index, message -> - ScheduledMessageRow( - message = message, - onSendNow = { actions.onSendScheduledNow(message) }, - onEdit = { - actions.onEditScheduledMessage(message) - showScheduledMessagesSheet = false - showFullScreenEditor = true - }, - onDelete = { - actions.onDeleteScheduledMessage(message) - actions.onRefreshScheduledMessages() - } - ) - - if (index < scheduledMessagesSorted.lastIndex) { - HorizontalDivider( - modifier = Modifier.padding(horizontal = 12.dp), - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.45f) - ) - } - } - } - } - } - - Spacer(modifier = Modifier.height(10.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - OutlinedButton( - onClick = { - actions.onRefreshScheduledMessages() - }, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(text = stringResource(R.string.action_refresh)) - } - - Button( - onClick = { showScheduledMessagesSheet = false }, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(text = stringResource(R.string.action_done)) - } - } - } - } - } - } - } - - LaunchedEffect(showFullScreenEditor) { - if (showFullScreenEditor) { - fullScreenFocusRequester.requestFocus() - } - } -} - -@Composable -private fun ClosedTopicBar() { - Surface( - color = MaterialTheme.colorScheme.surface, - tonalElevation = 2.dp, - modifier = Modifier.fillMaxWidth() - ) { - Text( - text = stringResource(R.string.topic_closed_bar), - modifier = Modifier - .fillMaxWidth() - .padding(16.dp) - .windowInsetsPadding(WindowInsets.navigationBars), - textAlign = TextAlign.Center, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } -} - -@Composable -private fun SendOptionsPopup( - expanded: Boolean, - scheduledMessagesCount: Int, - onDismiss: () -> Unit, - onSendSilent: () -> Unit, - onScheduleMessage: () -> Unit, - onOpenScheduledMessages: () -> Unit -) { - var renderPopup by remember { mutableStateOf(expanded) } - var contentVisible by remember { mutableStateOf(false) } - val scrimAlpha by animateFloatAsState( - targetValue = if (contentVisible) 0.44f else 0f, - animationSpec = tween(durationMillis = 180), - label = "SendOptionsScrimAlpha" - ) - val scrimColor = MaterialTheme.colorScheme.scrim.copy(alpha = scrimAlpha) - - LaunchedEffect(expanded) { - if (expanded) { - renderPopup = true - contentVisible = true - } else if (renderPopup) { - contentVisible = false - delay(180) - renderPopup = false - } - } - - if (!renderPopup) return - - Dialog( - onDismissRequest = { - if (expanded) onDismiss() - }, - properties = DialogProperties( - usePlatformDefaultWidth = false, - decorFitsSystemWindows = false - ) - ) { - Box( - modifier = Modifier - .fillMaxSize() - .background(scrimColor) - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null, - onClick = onDismiss - ) - ) { - AnimatedVisibility( - visible = contentVisible, - enter = fadeIn(animationSpec = tween(180)) + - slideInVertically(animationSpec = spring(dampingRatio = 0.82f, stiffness = 700f)) { it / 5 } + - scaleIn( - animationSpec = spring(dampingRatio = 0.86f, stiffness = 650f), - initialScale = 0.92f, - transformOrigin = TransformOrigin(1f, 1f) - ), - exit = fadeOut(animationSpec = tween(140)) + - slideOutVertically(animationSpec = tween(140)) { it / 8 } + - scaleOut( - animationSpec = tween(140), - targetScale = 0.96f, - transformOrigin = TransformOrigin(1f, 1f) - ), - modifier = Modifier - .align(Alignment.BottomEnd) - .padding(end = 12.dp, bottom = 60.dp) - ) { - Surface( - modifier = Modifier.widthIn(min = 220.dp, max = 260.dp), - shape = RoundedCornerShape(22.dp), - color = MaterialTheme.colorScheme.surfaceContainerHigh, - tonalElevation = 8.dp, - shadowElevation = 18.dp - ) { - Column(modifier = Modifier.padding(vertical = 8.dp)) { - AnimatedVisibility( - visible = contentVisible, - enter = fadeIn(animationSpec = tween(220, delayMillis = 35)) + - slideInVertically(animationSpec = tween(220, delayMillis = 35)) { it / 3 }, - exit = fadeOut(animationSpec = tween(90)) - ) { - DropdownMenuItem( - text = { - SendOptionsMenuLabel( - title = stringResource(R.string.action_send_silent) - ) - }, - leadingIcon = { - Icon( - imageVector = Icons.Outlined.NotificationsOff, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary - ) - }, - onClick = onSendSilent - ) - } - - AnimatedVisibility( - visible = contentVisible, - enter = fadeIn(animationSpec = tween(220, delayMillis = 70)) + - slideInVertically(animationSpec = tween(220, delayMillis = 70)) { it / 3 }, - exit = fadeOut(animationSpec = tween(90)) - ) { - DropdownMenuItem( - text = { - SendOptionsMenuLabel( - title = stringResource(R.string.action_schedule_message), - subtitle = stringResource(R.string.cd_select_date) + " / " + stringResource(R.string.cd_select_time) - ) - }, - leadingIcon = { - Icon( - imageVector = Icons.Default.Schedule, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary - ) - }, - onClick = onScheduleMessage - ) - } - - if (scheduledMessagesCount > 0) { - HorizontalDivider( - modifier = Modifier.padding(horizontal = 12.dp), - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - - AnimatedVisibility( - visible = contentVisible, - enter = fadeIn(animationSpec = tween(220, delayMillis = 105)) + - slideInVertically(animationSpec = tween(220, delayMillis = 105)) { it / 3 }, - exit = fadeOut(animationSpec = tween(90)) - ) { - DropdownMenuItem( - text = { - SendOptionsMenuLabel( - title = stringResource( - R.string.action_scheduled_messages_count, - scheduledMessagesCount - ) - ) - }, - leadingIcon = { - Icon( - imageVector = Icons.AutoMirrored.Outlined.Subject, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary - ) - }, - onClick = onOpenScheduledMessages - ) - } - } - } - } - } - } - } -} - -@Composable -private fun SendOptionsMenuLabel( - title: String, - subtitle: String? = null -) { - Column(verticalArrangement = Arrangement.spacedBy(2.dp)) { - Text( - text = title, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurface - ) - if (subtitle != null) { - Text( - text = subtitle, - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun ScheduleDatePickerDialog( - onDismiss: () -> Unit, - onDateSelected: (Long) -> Unit -) { - val datePickerState = rememberDatePickerState( - initialSelectedDateMillis = System.currentTimeMillis() - ) - - DatePickerDialog( - onDismissRequest = onDismiss, - confirmButton = { - TextButton( - enabled = datePickerState.selectedDateMillis != null, - onClick = { - datePickerState.selectedDateMillis?.let(onDateSelected) - } - ) { - Text(text = stringResource(R.string.action_done)) - } - }, - dismissButton = { - TextButton(onClick = onDismiss) { - Text(text = stringResource(R.string.action_cancel)) - } - } - ) { - DatePicker(state = datePickerState) - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun ScheduleTimePickerDialog( - initialHour: Int, - initialMinute: Int, - onDismiss: () -> Unit, - onConfirm: (Int, Int) -> Unit -) { - val context = LocalContext.current - val is24HourFormat = remember(context) { DateFormat.is24HourFormat(context) } - val timePickerState = rememberTimePickerState( - initialHour = initialHour, - initialMinute = initialMinute, - is24Hour = is24HourFormat - ) - - AlertDialog( - onDismissRequest = onDismiss, - title = { Text(text = stringResource(R.string.cd_select_time)) }, - text = { - TimePicker( - state = timePickerState, - modifier = Modifier.fillMaxWidth() - ) - }, - confirmButton = { - TextButton(onClick = { onConfirm(timePickerState.hour, timePickerState.minute) }) { - Text(text = stringResource(R.string.action_done)) - } - }, - dismissButton = { - TextButton(onClick = onDismiss) { - Text(text = stringResource(R.string.action_cancel)) - } - } - ) -} - -@Composable -private fun FullScreenEditorMetaPill( - text: String, - color: Color, - contentColor: Color -) { - Surface( - color = color, - shape = RoundedCornerShape(999.dp) - ) { - Text( - text = text, - color = contentColor, - style = MaterialTheme.typography.labelMedium, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.padding(horizontal = 10.dp, vertical = 6.dp) - ) - } -} - -@Composable -private fun FullScreenEditorToolButton( - icon: ImageVector, - hint: String, - enabled: Boolean = true, - onClick: () -> Unit -) { - val context = LocalContext.current - Box( - modifier = Modifier - .clip(RoundedCornerShape(16.dp)) - .combinedClickable( - enabled = enabled, - onClick = onClick, - onLongClick = { - Toast.makeText(context, hint, Toast.LENGTH_SHORT).show() - } - ) - .padding(horizontal = 10.dp, vertical = 8.dp), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = icon, - contentDescription = hint, - tint = if (enabled) { - MaterialTheme.colorScheme.onSurface - } else { - MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.38f) - } - ) - } -} - -@Composable -private fun InputBarLeadingIcons( - editingMessage: MessageModel?, - pendingMediaPaths: List, - canSendMedia: Boolean, - onAttachClick: () -> Unit -) { - if (editingMessage == null && pendingMediaPaths.isEmpty() && canSendMedia) { - IconButton( - onClick = onAttachClick - ) { - Icon( - imageVector = Icons.Outlined.AddCircleOutline, - contentDescription = stringResource(R.string.cd_attach), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } else if (!canSendMedia) { - Spacer(modifier = Modifier.width(12.dp)) - } -} - -@Composable -private fun ScheduledMessageRow( - message: MessageModel, - onSendNow: () -> Unit, - onEdit: () -> Unit, - onDelete: () -> Unit -) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 12.dp, vertical = 10.dp), - verticalAlignment = Alignment.Top - ) { - Box( - modifier = Modifier - .size(36.dp) - .clip(CircleShape) - .fillMaxSize() - ) { - Surface( - modifier = Modifier.fillMaxSize(), - color = MaterialTheme.colorScheme.primary.copy(alpha = 0.14f), - shape = CircleShape - ) { - Box(contentAlignment = Alignment.Center) { - Text( - text = scheduledMessageTypeLabel(message).take(1), - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.primary - ) - } - } - } - - Spacer(modifier = Modifier.width(10.dp)) - - Column(modifier = Modifier.weight(1f)) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = message.senderName, - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.primary, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Text( - text = formatScheduledTimestamp(message.date), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - - Spacer(modifier = Modifier.height(4.dp)) - - Text( - text = messagePreviewText(message), - style = MaterialTheme.typography.bodyMedium, - maxLines = 2, - overflow = TextOverflow.Ellipsis, - color = MaterialTheme.colorScheme.onSurface - ) - - Spacer(modifier = Modifier.height(2.dp)) - - Text( - text = stringResource(R.string.scheduled_message_id, message.id), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - - Spacer(modifier = Modifier.width(6.dp)) - } - - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 12.dp) - .padding(bottom = 10.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - OutlinedButton( - onClick = onSendNow, - modifier = Modifier - .weight(1f) - .height(40.dp) - ) { - Text( - text = stringResource(R.string.action_send_now), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - softWrap = false - ) - } - - OutlinedButton( - onClick = onEdit, - enabled = canEditScheduledMessage(message), - modifier = Modifier - .weight(1f) - .height(40.dp) - ) { - Text( - text = stringResource(R.string.action_edit), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - softWrap = false - ) - } - - FilledTonalButton( - onClick = onDelete, - modifier = Modifier - .weight(1f) - .height(40.dp) - ) { - Text( - text = stringResource(R.string.action_delete_message), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - softWrap = false - ) - } - } -} - -private fun messagePreviewText(message: MessageModel): String { - return when (val content = message.content) { - is MessageContent.Text -> content.text - is MessageContent.Photo -> if (content.caption.isNotBlank()) content.caption else "Photo" - is MessageContent.Video -> if (content.caption.isNotBlank()) content.caption else "Video" - is MessageContent.Document -> if (content.caption.isNotBlank()) content.caption else "Document" - is MessageContent.Gif -> if (content.caption.isNotBlank()) content.caption else "GIF" - is MessageContent.Sticker -> "Sticker" - is MessageContent.Voice -> "Voice message" - is MessageContent.VideoNote -> "Video message" - is MessageContent.Audio -> "Audio" - is MessageContent.Location -> "Location" - is MessageContent.Venue -> content.title - is MessageContent.Contact -> listOf(content.firstName, content.lastName).filter { it.isNotBlank() } - .joinToString(" ") - - is MessageContent.Service -> content.text - is MessageContent.Poll -> content.question - is MessageContent.Unsupported -> "Unsupported message" - else -> "Message" - } -} - -private fun scheduledMessageTypeLabel(message: MessageModel): String { - return when (message.content) { - is MessageContent.Text -> "Text" - is MessageContent.Photo -> "Photo" - is MessageContent.Video -> "Video" - is MessageContent.Document -> "Document" - is MessageContent.Gif -> "GIF" - is MessageContent.Sticker -> "Sticker" - is MessageContent.Voice -> "Voice" - is MessageContent.VideoNote -> "Video message" - else -> "Message" - } -} - -private fun canEditScheduledMessage(message: MessageModel): Boolean { - return when (message.content) { - is MessageContent.Text -> true - - else -> false - } -} - -private fun formatScheduledTimestamp(epochSeconds: Int): String { - return try { - val formatter = java.text.SimpleDateFormat("dd MMM, HH:mm", Locale.getDefault()) - formatter.format(Date(epochSeconds * 1000L)) - } catch (_: Exception) { - "" - } -} - -private fun buildScheduledDateEpochSeconds(selectedDateMillis: Long, hour: Int, minute: Int): Int { - val utcDate = Calendar.getInstance(TimeZone.getTimeZone("UTC")).apply { - timeInMillis = selectedDateMillis - } - - val selected = Calendar.getInstance().apply { - set(Calendar.YEAR, utcDate.get(Calendar.YEAR)) - set(Calendar.MONTH, utcDate.get(Calendar.MONTH)) - set(Calendar.DAY_OF_MONTH, utcDate.get(Calendar.DAY_OF_MONTH)) - set(Calendar.HOUR_OF_DAY, hour) - set(Calendar.MINUTE, minute) - set(Calendar.SECOND, 0) - set(Calendar.MILLISECOND, 0) - } - - val now = Calendar.getInstance() - if (selected.before(now)) { - selected.timeInMillis = now.timeInMillis + 60_000L - } - - return (selected.timeInMillis / 1000L).toInt() -} - -private fun normalizeEditorUrl(raw: String): String? { - val trimmed = raw.trim() - if (trimmed.isEmpty()) return null - return if (trimmed.contains("://")) trimmed else "https://$trimmed" -} - -private fun insertMentionAtSelection(value: TextFieldValue): TextFieldValue { - val selection = if (value.selection.start <= value.selection.end) value.selection else TextRange( - value.selection.end, - value.selection.start - ) - val base = value.annotatedString - val insertion = - if (selection.start == selection.end) "@" else "@${value.text.substring(selection.start, selection.end)}" - - val newAnnotated = buildAnnotatedString { - append(base.subSequence(0, selection.start)) - append(insertion) - append(base.subSequence(selection.end, base.length)) - } - - val newCursor = selection.start + insertion.length - return value.copy(annotatedString = newAnnotated, selection = TextRange(newCursor, newCursor)) -} - -private fun insertEmojiAtSelection( - value: TextFieldValue, - emoji: String, - sticker: StickerModel?, - knownCustomEmojis: MutableMap -): TextFieldValue { - val currentText = value.annotatedString - val selection = value.selection - - val emojiAnnotated = if (sticker != null) { - val customEmojiEntityId = sticker.customEmojiId ?: sticker.id - knownCustomEmojis[customEmojiEntityId] = sticker - val symbol = emoji.ifBlank { sticker.emoji.ifBlank { "\uD83D\uDE42" } } - buildAnnotatedString { - append(symbol) - addStringAnnotation(CUSTOM_EMOJI_TAG, customEmojiEntityId.toString(), 0, symbol.length) - } - } else { - AnnotatedString(emoji.ifBlank { "\uD83D\uDE42" }) - } - - val newText = buildAnnotatedString { - append(currentText.subSequence(0, selection.start)) - append(emojiAnnotated) - append(currentText.subSequence(selection.end, currentText.length)) - } - - return value.copy( - annotatedString = newText, - selection = TextRange(selection.start + emojiAnnotated.length) - ) -} - -private fun Context.hasAllPermissions(permissions: List): Boolean { - return permissions.all { permission -> - ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED - } -} - -private data class InlineQueryInput( - val botUsername: String, - val query: String -) - -private fun parseInlineQueryInput(text: String, selection: TextRange): InlineQueryInput? { - if (!selection.collapsed) return null - val cursor = selection.start - if (!text.startsWith('@') || cursor !in 0..text.length) return null - - val firstSpaceIndex = text.indexOf(' ') - if (firstSpaceIndex <= 1) return null - if (cursor <= firstSpaceIndex) return null - - val botUsername = text.substring(1, firstSpaceIndex) - if (botUsername.any { !it.isLetterOrDigit() && it != '_' }) return null - - val query = text.substring(firstSpaceIndex + 1) - if (query.isBlank()) return null - if (query.contains('\n')) return null - - return InlineQueryInput( - botUsername = botUsername, - query = query - ) -} - -private fun String.isInlineBotPrefillText(): Boolean { - if (!startsWith("@") || !endsWith(" ")) return false - val username = drop(1).dropLast(1) - return username.isNotEmpty() && username.all { it.isLetterOrDigit() || it == '_' } -} - -private fun Context.declaredPermissions(): Set { - val info = packageManager.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS) - return info.requestedPermissions?.toSet().orEmpty() -} - -private fun Context.copyUriToTempPath(uri: android.net.Uri): String? { - return try { - if (uri.scheme == "file") { - return uri.path - } - val mime = contentResolver.getType(uri).orEmpty() - val ext = when { - mime.contains("video") -> "mp4" - mime.contains("gif") -> "gif" - else -> "jpg" - } - val file = File(cacheDir, "attach_${System.nanoTime()}.$ext") - contentResolver.openInputStream(uri)?.use { input -> - FileOutputStream(file).use { output -> input.copyTo(output) } - } ?: return null - file.absolutePath - } catch (_: Exception) { - null - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/ChatTopBar.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/ChatTopBar.kt deleted file mode 100644 index 083c92d0..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/ChatTopBar.kt +++ /dev/null @@ -1,410 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components - -import androidx.compose.animation.* -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.spring -import androidx.compose.animation.core.tween -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowBack -import androidx.compose.material.icons.automirrored.rounded.PlaylistAddCheck -import androidx.compose.material.icons.automirrored.rounded.VolumeOff -import androidx.compose.material.icons.automirrored.rounded.VolumeUp -import androidx.compose.material.icons.filled.MoreVert -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.TransformOrigin -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.window.Popup -import androidx.compose.ui.window.PopupProperties -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.AvatarForChat -import org.monogram.presentation.core.ui.ConfirmationSheet -import org.monogram.presentation.core.ui.TypingDots -import org.monogram.presentation.features.stickers.ui.menu.MenuOptionRow -import org.monogram.presentation.features.stickers.ui.view.StickerImage -import org.monogram.presentation.features.viewers.components.ViewerSettingsDropdown - - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ChatTopBar( - title: String, - avatarPath: String?, - emojiStatusPath: String?, - statusText: String?, - videoPlayerPool: VideoPlayerPool, - isOnline: Boolean = false, - isVerified: Boolean = false, - isSponsor: Boolean = false, - onBack: () -> Unit, - onMenu: () -> Unit, - onClick: () -> Unit = {}, - topicEmojiPath: String? = null, - isChannel: Boolean = false, - isWhitelistedInAdBlock: Boolean = false, - onToggleAdBlockWhitelist: (() -> Unit)? = null, - isMuted: Boolean = false, - onToggleMute: (() -> Unit)? = null, - isSearchActive: Boolean = false, - searchQuery: String = "", - onSearchToggle: () -> Unit = {}, - onSearchQueryChange: (String) -> Unit = {}, - onClearHistory: (() -> Unit)? = null, - onDeleteChat: (() -> Unit)? = null, - onReport: (() -> Unit)? = null, - onCopyLink: (() -> Unit)? = null, - onManageMembers: (() -> Unit)? = null, - showBack: Boolean = true, - personalAvatarPath: String? = null -) { - var showMenu by remember { mutableStateOf(false) } - var showClearHistorySheet by remember { mutableStateOf(false) } - var showDeleteChatSheet by remember { mutableStateOf(false) } - - Box(modifier = Modifier.fillMaxWidth()) { - AnimatedContent( - targetState = isSearchActive, - transitionSpec = { - fadeIn() togetherWith fadeOut() - }, - label = "TopBarSearchTransition" - ) { searching -> - if (searching) { - TopAppBar( - windowInsets = WindowInsets.statusBars, - title = { - TextField( - value = searchQuery, - onValueChange = onSearchQueryChange, - modifier = Modifier.fillMaxWidth(), - placeholder = { Text(stringResource(R.string.search_messages_hint)) }, - colors = TextFieldDefaults.colors( - focusedContainerColor = Color.Transparent, - unfocusedContainerColor = Color.Transparent, - focusedIndicatorColor = Color.Transparent, - unfocusedIndicatorColor = Color.Transparent, - disabledIndicatorColor = Color.Transparent - ), - singleLine = true - ) - }, - navigationIcon = { - IconButton(onClick = onSearchToggle) { - Icon( - Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - }, - actions = { - if (searchQuery.isNotEmpty()) { - IconButton(onClick = { onSearchQueryChange("") }) { - Icon(Icons.Rounded.Close, contentDescription = stringResource(R.string.action_clear)) - } - } - } - ) - } else { - TopAppBar( - windowInsets = WindowInsets.statusBars, - title = { - Box(modifier = Modifier.clip(RoundedCornerShape(12.dp))) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .clickable(onClick = onClick) - .semantics { contentDescription = "ChatHeaderButton" } - .padding(6.dp) - - ) { - if (topicEmojiPath != null) { - StickerImage( - path = topicEmojiPath, - modifier = Modifier.size(40.dp), - animate = true - ) - } else { - AvatarForChat( - path = avatarPath, - fallbackPath = personalAvatarPath, - name = title, - size = 40.dp, - isOnline = isOnline, - videoPlayerPool = videoPlayerPool - ) - } - Spacer(Modifier.width(12.dp)) - Column { - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = title, - style = MaterialTheme.typography.titleMedium, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.weight(1f, fill = false) - ) - if (isMuted) { - Spacer(modifier = Modifier.width(4.dp)) - Icon( - imageVector = Icons.AutoMirrored.Rounded.VolumeOff, - contentDescription = stringResource(R.string.cd_muted), - modifier = Modifier.size(14.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - if (isVerified) { - Spacer(modifier = Modifier.width(4.dp)) - Icon( - imageVector = Icons.Rounded.Verified, - contentDescription = stringResource(R.string.cd_verified), - modifier = Modifier.size(18.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - if (isSponsor) { - Spacer(modifier = Modifier.width(4.dp)) - Icon( - imageVector = Icons.Rounded.Favorite, - contentDescription = stringResource(R.string.cd_sponsor), - modifier = Modifier.size(18.dp), - tint = Color(0xFFE53935) - ) - } - if (emojiStatusPath != null) { - Spacer(modifier = Modifier.width(4.dp)) - StickerImage( - path = emojiStatusPath, - modifier = Modifier.size(18.dp), - animate = false - ) - } - } - - AnimatedContent( - targetState = statusText, - transitionSpec = { - fadeIn() togetherWith fadeOut() - }, - label = "StatusAnimation" - ) { targetStatus -> - if (!targetStatus.isNullOrEmpty()) { - val isTyping = targetStatus.contains("печатает") || - targetStatus.contains("записывает") || - targetStatus.contains("отправляет") || - targetStatus.contains("выбирает") || - targetStatus.contains("играет") - - Row(verticalAlignment = Alignment.Bottom) { - Text( - text = targetStatus, - style = MaterialTheme.typography.bodySmall, - color = if (isOnline || isTyping) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - if (isTyping) { - Spacer(Modifier.width(2.dp)) - TypingDots( - dotSize = 3.dp, - dotColor = MaterialTheme.colorScheme.primary, - modifier = Modifier.padding(bottom = 4.dp) - ) - } - } - } - } - } - } - } - }, - navigationIcon = { - if (showBack) { - IconButton(onClick = onBack) { - Icon( - Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - } - }, - actions = { - IconButton(onClick = { - onMenu() - showMenu = true - }) { - Icon(Icons.Default.MoreVert, contentDescription = null) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.surface - ) - ) - } - } - - if (showMenu) { - Popup( - onDismissRequest = { showMenu = false }, - properties = PopupProperties(focusable = true) - ) { - Box( - modifier = Modifier - .fillMaxSize() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null - ) { showMenu = false } - ) { - var isVisible by remember { mutableStateOf(false) } - LaunchedEffect(Unit) { isVisible = true } - - @Suppress("RemoveRedundantQualifierName") - androidx.compose.animation.AnimatedVisibility( - visible = isVisible, - enter = fadeIn(tween(150)) + scaleIn( - animationSpec = spring(dampingRatio = 0.8f, stiffness = Spring.StiffnessMedium), - initialScale = 0.8f, - transformOrigin = TransformOrigin(1f, 0f) - ), - exit = fadeOut(tween(150)) + scaleOut( - animationSpec = tween(150), - targetScale = 0.9f, - transformOrigin = TransformOrigin(1f, 0f) - ), - modifier = Modifier - .align(Alignment.TopEnd) - .windowInsetsPadding(WindowInsets.statusBars) - .padding(top = 56.dp, end = 16.dp) - ) { - ViewerSettingsDropdown { -/* MenuOptionRow( - icon = Icons.Rounded.Search, - title = "Search", - onClick = { - showMenu = false - onSearchToggle() - } - ) - */ - if (onToggleMute != null) { - MenuOptionRow( - icon = if (isMuted) Icons.AutoMirrored.Rounded.VolumeUp else Icons.AutoMirrored.Rounded.VolumeOff, - title = if (isMuted) stringResource(R.string.menu_unmute) else stringResource(R.string.menu_mute), - onClick = { - showMenu = false - onToggleMute() - } - ) - } - if (isChannel && onToggleAdBlockWhitelist != null) { - MenuOptionRow( - icon = if (isWhitelistedInAdBlock) Icons.Rounded.Block else Icons.AutoMirrored.Rounded.PlaylistAddCheck, - title = if (isWhitelistedInAdBlock) stringResource(R.string.menu_filter_ads) else stringResource( - R.string.menu_whitelist_channel - ), - onClick = { - showMenu = false - onToggleAdBlockWhitelist() - } - ) - } - if (onCopyLink != null) { - MenuOptionRow( - icon = Icons.Rounded.Link, - title = stringResource(R.string.menu_copy_link), - onClick = { - showMenu = false - onCopyLink() - } - ) - } - if (onManageMembers != null) { - MenuOptionRow( - icon = Icons.Rounded.Groups, - title = stringResource(R.string.members), - onClick = { - showMenu = false - onManageMembers() - } - ) - } - if (onClearHistory != null) { - MenuOptionRow( - icon = Icons.Rounded.CleaningServices, - title = stringResource(R.string.menu_clear_history), - onClick = { - showMenu = false - showClearHistorySheet = true - } - ) - } - if (onDeleteChat != null) { - MenuOptionRow( - icon = Icons.Rounded.Delete, - title = stringResource(R.string.menu_delete_chat), - textColor = MaterialTheme.colorScheme.error, - iconTint = MaterialTheme.colorScheme.error, - onClick = { - showMenu = false - showDeleteChatSheet = true - } - ) - } - if (onReport != null) { - MenuOptionRow( - icon = Icons.Rounded.Report, - title = stringResource(R.string.menu_report), - onClick = { - showMenu = false - onReport() - } - ) - } - } - } - } - } - } - - if (showClearHistorySheet && onClearHistory != null) { - ConfirmationSheet( - icon = Icons.Rounded.CleaningServices, - title = stringResource(R.string.clear_history_title), - description = stringResource(R.string.clear_history_confirmation), - confirmText = stringResource(R.string.action_clear_history), - onConfirm = { - onClearHistory() - showClearHistorySheet = false - }, - onDismiss = { showClearHistorySheet = false } - ) - } - - if (showDeleteChatSheet && onDeleteChat != null) { - ConfirmationSheet( - icon = Icons.Rounded.Delete, - title = stringResource(R.string.delete_chat_title), - description = stringResource(R.string.delete_chat_confirmation), - confirmText = stringResource(R.string.action_delete_chat), - onConfirm = { - onDeleteChat() - showDeleteChatSheet = false - }, - onDismiss = { showDeleteChatSheet = false } - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/CompactMediaMosaic.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/CompactMediaMosaic.kt deleted file mode 100644 index ea0a9c16..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/CompactMediaMosaic.kt +++ /dev/null @@ -1,976 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components - -import androidx.compose.animation.* -import androidx.compose.animation.core.tween -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Download -import androidx.compose.material.icons.filled.PlayArrow -import androidx.compose.material.icons.outlined.Visibility -import androidx.compose.material.icons.rounded.Stream -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.blur -import androidx.compose.ui.draw.clipToBounds -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import coil3.compose.rememberAsyncImagePainter -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.domain.models.MessageSendingState -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.AutoDownloadSuppression -import org.monogram.presentation.features.chats.currentChat.components.channels.formatDuration -import org.monogram.presentation.features.chats.currentChat.components.channels.formatViews -import org.monogram.presentation.features.chats.currentChat.components.chats.ChatTimestampInfo -import org.monogram.presentation.features.chats.currentChat.components.chats.MediaLoadingAction -import org.monogram.presentation.features.chats.currentChat.components.chats.MediaLoadingBackground -import org.monogram.presentation.features.chats.currentChat.components.chats.SpoilerWrapper - -@Composable -fun CompactMediaMosaic( - messages: List, - autoplayGifs: Boolean, - autoplayVideos: Boolean, - onPhotoClick: (MessageModel) -> Unit, - onDownloadPhoto: (Int) -> Unit = {}, - onVideoClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit = {}, - onLongClick: (Offset) -> Unit, - showTimestampOverlay: Boolean, - timestampStr: String, - isRead: Boolean, - isOutgoing: Boolean, - isChannel: Boolean = false, - views: Int? = null, - sendingState: MessageSendingState? = null, - autoDownloadMobile: Boolean = false, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - autoDownloadWifi: Boolean = false, - autoDownloadRoaming: Boolean = false, - toProfile: (Long) -> Unit = {}, - isAnyViewerOpen: Boolean = false -) { - val count = messages.size - val spacing = 2.dp - - @Composable - fun Item( - index: Int, - modifier: Modifier, - contentScale: ContentScale = ContentScale.Crop - ) { - val msg = messages[index] - val isLastItem = index == messages.lastIndex - - Box(modifier = modifier.clipToBounds()) { - when (val content = msg.content) { - is MessageContent.Photo -> { - PhotoItem( - msg = msg, - photo = content, - onPhotoClick = onPhotoClick, - onDownloadPhoto = onDownloadPhoto, - onCancelDownload = onCancelDownload, - onLongClick = onLongClick, - contentScale = contentScale, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - modifier = Modifier.fillMaxSize(), - downloadUtils = downloadUtils - ) - } - - is MessageContent.Video -> { - VideoItem( - msg = msg, - video = content, - autoplayVideos = autoplayVideos, - onVideoClick = onVideoClick, - onCancelDownload = onCancelDownload, - onLongClick = onLongClick, - contentScale = contentScale, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - modifier = Modifier.fillMaxSize(), - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } - - is MessageContent.VideoNote -> { - VideoNoteItem( - msg = msg, - videoNote = content, - autoplayVideos = autoplayVideos, - onVideoClick = onVideoClick, - onCancelDownload = onCancelDownload, - onLongClick = onLongClick, - contentScale = contentScale, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - modifier = Modifier.fillMaxSize(), - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } - - is MessageContent.Gif -> { - GifItem( - msg = msg, - gif = content, - autoplayGifs = autoplayGifs, - onGifClick = onVideoClick, - onCancelDownload = onCancelDownload, - onLongClick = onLongClick, - contentScale = contentScale, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - modifier = Modifier.fillMaxSize(), - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } - - else -> {} - } - - if (isLastItem && showTimestampOverlay) { - TimestampPill( - time = timestampStr, - isRead = isRead, - isOutgoing = isOutgoing, - isChannel = isChannel, - views = views, - sendingState = sendingState, - modifier = Modifier - .align(Alignment.BottomEnd) - .padding(6.dp) - ) - } - } - } - - Column(Modifier.fillMaxWidth()) { - when (count) { - 1 -> { - Box(Modifier - .fillMaxWidth() - .aspectRatio(1.0f.coerceIn(0.8f, 1.5f))) { - Item(0, Modifier.fillMaxSize(), ContentScale.Fit) - } - } - - 2 -> { - Row(Modifier - .fillMaxWidth() - .height(200.dp)) { - Item(0, Modifier - .weight(1f) - .fillMaxHeight()) - Spacer(Modifier.width(spacing)) - Item(1, Modifier - .weight(1f) - .fillMaxHeight()) - } - } - - 3 -> { - Column(Modifier - .fillMaxWidth() - .aspectRatio(1f)) { - Item(0, Modifier - .weight(1.5f) - .fillMaxWidth()) - Spacer(Modifier.height(spacing)) - Row(Modifier - .weight(1f) - .fillMaxWidth()) { - Item(1, Modifier - .weight(1f) - .fillMaxHeight()) - Spacer(Modifier.width(spacing)) - Item(2, Modifier - .weight(1f) - .fillMaxHeight()) - } - } - } - - 4 -> { - Column(Modifier - .fillMaxWidth() - .aspectRatio(1f)) { - Row(Modifier.weight(1f)) { - Item(0, Modifier - .weight(1f) - .fillMaxHeight()) - Spacer(Modifier.width(spacing)) - Item(1, Modifier - .weight(1f) - .fillMaxHeight()) - } - Spacer(Modifier.height(spacing)) - Row(Modifier.weight(1f)) { - Item(2, Modifier - .weight(1f) - .fillMaxHeight()) - Spacer(Modifier.width(spacing)) - Item(3, Modifier - .weight(1f) - .fillMaxHeight()) - } - } - } - - else -> { - Column(Modifier - .fillMaxWidth() - .aspectRatio(0.9f)) { - Row(Modifier.weight(1f)) { - Item(0, Modifier - .weight(1f) - .fillMaxHeight()) - Spacer(Modifier.width(spacing)) - Item(1, Modifier - .weight(1f) - .fillMaxHeight()) - } - Spacer(Modifier.height(spacing)) - Row(Modifier.weight(1f)) { - Item(2, Modifier - .weight(1f) - .fillMaxHeight()) - Spacer(Modifier.width(spacing)) - Item(3, Modifier - .weight(1f) - .fillMaxHeight()) - Spacer(Modifier.width(spacing)) - Item(4, Modifier - .weight(1f) - .fillMaxHeight()) - } - } - } - } - } -} - -@Composable -fun PhotoItem( - msg: MessageModel, - photo: MessageContent.Photo, - onPhotoClick: (MessageModel) -> Unit, - onDownloadPhoto: (Int) -> Unit, - onCancelDownload: (Int) -> Unit, - onLongClick: (Offset) -> Unit, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - modifier: Modifier = Modifier, - contentScale: ContentScale = ContentScale.Crop, - downloadUtils: IDownloadUtils -) { - var stablePath by remember(msg.id) { mutableStateOf(photo.path) } - val hasPath = !stablePath.isNullOrBlank() - var isAutoDownloadSuppressed by remember(msg.id) { mutableStateOf(false) } - - LaunchedEffect(photo.path) { - if (!photo.path.isNullOrBlank()) { - stablePath = photo.path - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(photo.fileId) - } - } - - LaunchedEffect(photo.path, photo.isDownloading, autoDownloadMobile, autoDownloadWifi, autoDownloadRoaming) { - if (photo.path.isNullOrBlank() && !photo.isDownloading && !isAutoDownloadSuppressed && !AutoDownloadSuppression.isSuppressed( - photo.fileId - ) - ) { - val shouldDownload = when { - downloadUtils.isWifiConnected() -> autoDownloadWifi - downloadUtils.isRoaming() -> autoDownloadRoaming - else -> autoDownloadMobile - } - if (shouldDownload) onDownloadPhoto(photo.fileId) - } - } - - var itemPosition by remember { mutableStateOf(Offset.Zero) } - var isRevealed by remember { mutableStateOf(!photo.hasSpoiler) } - - Box(modifier = modifier.clipToBounds()) { - Crossfade( - targetState = hasPath, - animationSpec = tween(300), - label = "PhotoLoading" - ) { resolved -> - if (resolved && !stablePath.isNullOrBlank()) { - Image( - painter = rememberAsyncImagePainter(stablePath), - contentDescription = null, - modifier = Modifier - .fillMaxSize() - .onGloballyPositioned { itemPosition = it.positionInWindow() } - .pointerInput(Unit) { - detectTapGestures( - onTap = { - if (!isRevealed) isRevealed = true - else onPhotoClick(msg) - }, - onLongPress = { offset -> onLongClick(itemPosition + offset) } - ) - }, - contentScale = contentScale - ) - } else { - Box( - modifier = Modifier - .fillMaxSize() - .pointerInput(Unit) { - detectTapGestures( - onTap = { - if (!isRevealed) { - isRevealed = true - } else if (photo.isDownloading) { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(photo.fileId) - onCancelDownload(photo.fileId) - } else { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(photo.fileId) - onDownloadPhoto(photo.fileId) - } - }, - onLongPress = { offset -> onLongClick(itemPosition + offset) } - ) - }, - contentAlignment = Alignment.Center - ) { - MediaLoadingBackground( - previewData = photo.minithumbnail, - contentScale = contentScale - ) - - MediaLoadingAction( - isDownloading = photo.isDownloading, - progress = photo.downloadProgress, - idleIcon = Icons.Default.Download, - idleContentDescription = "Download", - onCancelClick = { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(photo.fileId) - onCancelDownload(photo.fileId) - }, - onIdleClick = { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(photo.fileId) - onDownloadPhoto(photo.fileId) - } - ) - } - } - } - - SpoilerWrapper(isRevealed = isRevealed) { - Box(modifier = Modifier.fillMaxSize()) - } - } -} - -@Composable -fun VideoItem( - msg: MessageModel, - video: MessageContent.Video, - autoplayVideos: Boolean, - onVideoClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit, - onLongClick: (Offset) -> Unit, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - modifier: Modifier = Modifier, - contentScale: ContentScale = ContentScale.Crop, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - isAnyViewerOpen: Boolean = false -) { - var stablePath by remember(msg.id) { mutableStateOf(video.path) } - val hasPath = !stablePath.isNullOrBlank() - var isAutoDownloadSuppressed by remember(msg.id) { mutableStateOf(false) } - - LaunchedEffect(video.path) { - if (!video.path.isNullOrBlank()) { - stablePath = video.path - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(video.fileId) - } - } - - LaunchedEffect(video.path, video.isDownloading, autoDownloadMobile, autoDownloadWifi, autoDownloadRoaming) { - if (video.path.isNullOrBlank() && !video.isDownloading && !video.supportsStreaming && !isAutoDownloadSuppressed && !AutoDownloadSuppression.isSuppressed( - video.fileId - ) - ) { - val shouldDownload = when { - downloadUtils.isWifiConnected() -> autoDownloadWifi - downloadUtils.isRoaming() -> autoDownloadRoaming - else -> autoDownloadMobile - } - if (shouldDownload) onVideoClick(msg) - } - } - - var itemPosition by remember { mutableStateOf(Offset.Zero) } - var isRevealed by remember { mutableStateOf(!video.hasSpoiler) } - - Box(modifier = modifier.clipToBounds()) { - Crossfade( - targetState = hasPath || video.supportsStreaming, - animationSpec = tween(300), - label = "VideoLoading" - ) { targetHasPathOrStreaming -> - if (targetHasPathOrStreaming) { - if (autoplayVideos) { - val videoPath = stablePath ?: "http://streaming/${video.fileId}" - VideoStickerPlayer( - path = videoPath, - type = VideoType.Gif, - modifier = Modifier - .fillMaxSize() - .onGloballyPositioned { itemPosition = it.positionInWindow() } - .pointerInput(Unit) { - detectTapGestures( - onTap = { - if (!isRevealed) isRevealed = true - else onVideoClick(msg) - }, - onLongPress = { offset -> onLongClick(itemPosition + offset) } - ) - }, - animate = !isAnyViewerOpen, - contentScale = contentScale, - videoPlayerPool = videoPlayerPool, - fileId = if (stablePath == null) video.fileId else 0, - thumbnailData = video.minithumbnail - ) - } else { - if (hasPath) { - Image( - painter = rememberAsyncImagePainter(stablePath), - contentDescription = null, - modifier = Modifier - .fillMaxSize() - .onGloballyPositioned { itemPosition = it.positionInWindow() } - .pointerInput(Unit) { - detectTapGestures( - onTap = { - if (!isRevealed) isRevealed = true - else onVideoClick(msg) - }, - onLongPress = { offset -> onLongClick(itemPosition + offset) } - ) - }, - contentScale = contentScale - ) - } else { - if (video.minithumbnail != null) { - Image( - painter = rememberAsyncImagePainter(video.minithumbnail), - contentDescription = null, - modifier = Modifier - .fillMaxSize() - .blur(10.dp), - contentScale = contentScale - ) - } - } - - Box( - modifier = Modifier - .align(Alignment.Center) - .size(48.dp) - .background(Color.Black.copy(alpha = 0.45f), CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Default.PlayArrow, - contentDescription = "Play", - tint = Color.White, - modifier = Modifier.size(32.dp) - ) - } - } - - Box( - modifier = Modifier - .align(Alignment.TopStart) - .padding(6.dp) - .background(Color.Black.copy(alpha = 0.45f), RoundedCornerShape(6.dp)) - .padding(horizontal = 4.dp, vertical = 2.dp) - ) { - val context = LocalContext.current - Text( - text = formatDuration(context, video.duration), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 10.sp), - color = Color.White - ) - } - } else { - Box( - modifier = Modifier - .fillMaxSize() - .pointerInput(Unit) { - detectTapGestures( - onTap = { - if (!isRevealed) { - isRevealed = true - } else if (video.isDownloading) { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(video.fileId) - onCancelDownload(video.fileId) - } else { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(video.fileId) - onVideoClick(msg) - } - }, - onLongPress = { offset -> onLongClick(itemPosition + offset) } - ) - }, - contentAlignment = Alignment.Center - ) { - MediaLoadingBackground( - previewData = video.minithumbnail, - contentScale = contentScale - ) - - MediaLoadingAction( - isDownloading = video.isDownloading, - progress = video.downloadProgress, - idleIcon = if (video.supportsStreaming) Icons.Rounded.Stream else Icons.Default.Download, - idleContentDescription = if (video.supportsStreaming) "Stream" else "Download", - onCancelClick = { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(video.fileId) - onCancelDownload(video.fileId) - }, - onIdleClick = { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(video.fileId) - onVideoClick(msg) - } - ) - } - } - } - - SpoilerWrapper(isRevealed = isRevealed) { - Box(modifier = Modifier.fillMaxSize()) - } - } -} - -@Composable -fun VideoNoteItem( - msg: MessageModel, - videoPlayerPool: VideoPlayerPool, - videoNote: MessageContent.VideoNote, - autoplayVideos: Boolean, - onVideoClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit, - onLongClick: (Offset) -> Unit, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - modifier: Modifier = Modifier, - contentScale: ContentScale = ContentScale.Crop, - downloadUtils: IDownloadUtils, - isAnyViewerOpen: Boolean = false -) { - var stablePath by remember(msg.id) { mutableStateOf(videoNote.path) } - !stablePath.isNullOrBlank() - var isAutoDownloadSuppressed by remember(msg.id) { mutableStateOf(false) } - - LaunchedEffect(videoNote.path) { - if (!videoNote.path.isNullOrBlank()) { - stablePath = videoNote.path - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(videoNote.fileId) - } - } - - LaunchedEffect(videoNote.path, videoNote.isDownloading, autoDownloadMobile, autoDownloadWifi, autoDownloadRoaming) { - if (videoNote.path.isNullOrBlank() && !videoNote.isDownloading && !isAutoDownloadSuppressed && !AutoDownloadSuppression.isSuppressed( - videoNote.fileId - ) - ) { - val shouldDownload = when { - downloadUtils.isWifiConnected() -> autoDownloadWifi - downloadUtils.isRoaming() -> autoDownloadRoaming - else -> autoDownloadMobile - } - if (shouldDownload) onVideoClick(msg) - } - } - - var itemPosition by remember { mutableStateOf(Offset.Zero) } - Box(modifier = modifier.clipToBounds()) { - Crossfade( - targetState = stablePath, - animationSpec = tween(300), - label = "VideoNoteLoading" - ) { path -> - if (!path.isNullOrBlank()) { - if (autoplayVideos) { - VideoStickerPlayer( - path = path, - type = VideoType.Gif, - modifier = Modifier - .fillMaxSize() - .onGloballyPositioned { itemPosition = it.positionInWindow() } - .pointerInput(Unit) { - detectTapGestures( - onTap = { onVideoClick(msg) }, - onLongPress = { offset -> onLongClick(itemPosition + offset) } - ) - }, - animate = !isAnyViewerOpen, - contentScale = contentScale, - videoPlayerPool = videoPlayerPool, - thumbnailData = videoNote.thumbnail - ) - } else { - val model = videoNote.thumbnail ?: path - Image( - painter = rememberAsyncImagePainter(model), - contentDescription = null, - modifier = Modifier - .fillMaxSize() - .onGloballyPositioned { itemPosition = it.positionInWindow() } - .pointerInput(Unit) { - detectTapGestures( - onTap = { onVideoClick(msg) }, - onLongPress = { offset -> onLongClick(itemPosition + offset) } - ) - }, - contentScale = contentScale - ) - - Box( - modifier = Modifier - .align(Alignment.Center) - .size(48.dp) - .background(Color.Black.copy(alpha = 0.45f), CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Default.PlayArrow, - contentDescription = "Play", - tint = Color.White, - modifier = Modifier.size(32.dp) - ) - } - } - - Box( - modifier = Modifier - .align(Alignment.TopStart) - .padding(6.dp) - .background(Color.Black.copy(alpha = 0.45f), RoundedCornerShape(6.dp)) - .padding(horizontal = 4.dp, vertical = 2.dp) - ) { - val context = LocalContext.current - Text( - text = formatDuration(context, videoNote.duration), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 10.sp), - color = Color.White - ) - } - } else { - Box( - modifier = Modifier - .fillMaxSize() - .pointerInput(Unit) { - detectTapGestures( - onTap = { - if (videoNote.isDownloading) { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(videoNote.fileId) - onCancelDownload(videoNote.fileId) - } else { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(videoNote.fileId) - onVideoClick(msg) - } - }, - onLongPress = { offset -> onLongClick(itemPosition + offset) } - ) - }, - contentAlignment = Alignment.Center - ) { - MediaLoadingBackground( - previewData = videoNote.thumbnail, - contentScale = contentScale - ) - - MediaLoadingAction( - isDownloading = videoNote.isDownloading, - progress = videoNote.downloadProgress, - idleIcon = Icons.Default.Download, - idleContentDescription = "Download", - onCancelClick = { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(videoNote.fileId) - onCancelDownload(videoNote.fileId) - }, - onIdleClick = { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(videoNote.fileId) - onVideoClick(msg) - } - ) - } - } - } - } -} - -@Composable -fun GifItem( - msg: MessageModel, - gif: MessageContent.Gif, - autoplayGifs: Boolean, - onGifClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit, - onLongClick: (Offset) -> Unit, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - modifier: Modifier = Modifier, - contentScale: ContentScale = ContentScale.Crop, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - isAnyViewerOpen: Boolean = false -) { - var stablePath by remember(msg.id) { mutableStateOf(gif.path) } - !stablePath.isNullOrBlank() - var isAutoDownloadSuppressed by remember(msg.id) { mutableStateOf(false) } - - LaunchedEffect(gif.path) { - if (!gif.path.isNullOrBlank()) { - stablePath = gif.path - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(gif.fileId) - } - } - - LaunchedEffect(gif.path, gif.isDownloading, autoDownloadMobile, autoDownloadWifi, autoDownloadRoaming) { - if (gif.path.isNullOrBlank() && !gif.isDownloading && !isAutoDownloadSuppressed && !AutoDownloadSuppression.isSuppressed( - gif.fileId - ) - ) { - val shouldDownload = when { - downloadUtils.isWifiConnected() -> autoDownloadWifi - downloadUtils.isRoaming() -> autoDownloadRoaming - else -> autoDownloadMobile - } - if (shouldDownload) onGifClick(msg) - } - } - - var itemPosition by remember { mutableStateOf(Offset.Zero) } - var isRevealed by remember { mutableStateOf(!gif.hasSpoiler) } - - Box(modifier = modifier.clipToBounds()) { - Crossfade( - targetState = stablePath, - animationSpec = tween(300), - label = "GifLoading" - ) { path -> - if (!path.isNullOrBlank()) { - VideoStickerPlayer( - path = path, - type = VideoType.Gif, - modifier = Modifier - .fillMaxSize() - .onGloballyPositioned { itemPosition = it.positionInWindow() } - .pointerInput(Unit) { - detectTapGestures( - onTap = { - if (!isRevealed) isRevealed = true - else onGifClick(msg) - }, - onLongPress = { offset -> onLongClick(itemPosition + offset) } - ) - }, - animate = autoplayGifs && !isAnyViewerOpen, - contentScale = contentScale, - videoPlayerPool = videoPlayerPool, - thumbnailData = gif.minithumbnail - ) - - if (!autoplayGifs) { - Box( - modifier = Modifier - .align(Alignment.Center) - .size(48.dp) - .background(Color.Black.copy(alpha = 0.45f), CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Default.PlayArrow, - contentDescription = "Play", - tint = Color.White, - modifier = Modifier.size(32.dp) - ) - } - } - - Box( - modifier = Modifier - .align(Alignment.TopStart) - .padding(6.dp) - .background(Color.Black.copy(alpha = 0.45f), RoundedCornerShape(6.dp)) - .padding(horizontal = 4.dp, vertical = 2.dp) - ) { - Text( - text = "GIF", - style = MaterialTheme.typography.labelSmall.copy(fontSize = 10.sp), - color = Color.White - ) - } - } else { - Box( - modifier = Modifier - .fillMaxSize() - .pointerInput(Unit) { - detectTapGestures( - onTap = { - if (!isRevealed) { - isRevealed = true - } else if (gif.isDownloading) { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(gif.fileId) - onCancelDownload(gif.fileId) - } else { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(gif.fileId) - onGifClick(msg) - } - }, - onLongPress = { offset -> onLongClick(itemPosition + offset) } - ) - }, - contentAlignment = Alignment.Center - ) { - MediaLoadingBackground( - previewData = gif.minithumbnail, - contentScale = contentScale - ) - - MediaLoadingAction( - isDownloading = gif.isDownloading, - progress = gif.downloadProgress, - idleIcon = Icons.Default.Download, - idleContentDescription = "Download", - onCancelClick = { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(gif.fileId) - onCancelDownload(gif.fileId) - }, - onIdleClick = { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(gif.fileId) - onGifClick(msg) - } - ) - } - } - } - - SpoilerWrapper(isRevealed = isRevealed) { - Box(modifier = Modifier.fillMaxSize()) - } - } -} - -@Composable -fun TimestampPill( - time: String, - isRead: Boolean, - isOutgoing: Boolean, - isChannel: Boolean = false, - views: Int? = null, - sendingState: MessageSendingState? = null, - modifier: Modifier = Modifier -) { - val context = LocalContext.current - Box( - modifier = modifier - .background(Color.Black.copy(alpha = 0.45f), RoundedCornerShape(10.dp)) - .padding(horizontal = 6.dp, vertical = 2.dp) - ) { - Row(verticalAlignment = Alignment.CenterVertically) { - if (isChannel) { - views?.let { viewsCount -> - if (viewsCount > 0) { - Icon( - imageVector = Icons.Outlined.Visibility, - contentDescription = null, - modifier = Modifier.size(12.dp), - tint = Color.White - ) - Spacer(modifier = Modifier.width(4.dp)) - Text( - text = formatViews(context, viewsCount), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 10.sp), - color = Color.White - ) - Spacer(modifier = Modifier.width(8.dp)) - } - } - } - AnimatedContent( - targetState = sendingState to isRead, - transitionSpec = { - fadeIn(animationSpec = tween(300)) togetherWith fadeOut(animationSpec = tween(300)) - }, - label = "SendingState" - ) { (state, read) -> - ChatTimestampInfo( - time = time, - isRead = read, - isOutgoing = isOutgoing, - sendingState = state, - color = Color.White - ) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/DateSeparator.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/DateSeparator.kt deleted file mode 100644 index f9e70476..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/DateSeparator.kt +++ /dev/null @@ -1,38 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components - -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import java.text.SimpleDateFormat -import java.util.* - -@Composable -fun DateSeparator(timestamp: Int) { - val text = SimpleDateFormat("MMMM dd", Locale.getDefault()).format(Date(timestamp.toLong() * 1000)) - Box( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 12.dp), - contentAlignment = Alignment.Center - ) { - Surface( - shape = RoundedCornerShape(12.dp), - color = MaterialTheme.colorScheme.surfaceContainerHighest.copy(alpha = 0.5f), - ) { - Text( - text = text, - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(horizontal = 10.dp, vertical = 4.dp) - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/MessageBubbleContainer.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/MessageBubbleContainer.kt deleted file mode 100644 index 85212e30..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/MessageBubbleContainer.kt +++ /dev/null @@ -1,667 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components - -import android.content.res.Configuration -import androidx.compose.animation.Animatable -import androidx.compose.animation.core.tween -import androidx.compose.foundation.background -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.geometry.Rect -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.unit.IntSize -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.toSize -import kotlinx.coroutines.delay -import org.monogram.domain.models.InlineKeyboardButtonModel -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.chatContent.shouldShowDate -import org.monogram.presentation.features.chats.currentChat.components.chats.* - -@Composable -fun MessageBubbleContainer( - msg: MessageModel, - olderMsg: MessageModel?, - newerMsg: MessageModel?, - isGroup: Boolean, - fontSize: Float, - letterSpacing: Float, - bubbleRadius: Float = 12f, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - autoDownloadFiles: Boolean, - autoplayGifs: Boolean, - autoplayVideos: Boolean, - showLinkPreviews: Boolean = true, - highlighted: Boolean = false, - onHighlightConsumed: () -> Unit = {}, - onPhotoClick: (MessageModel) -> Unit, - onDownloadPhoto: (Int) -> Unit = {}, - onVideoClick: (MessageModel) -> Unit = {}, - onDocumentClick: (MessageModel) -> Unit = {}, - onAudioClick: (MessageModel) -> Unit = {}, - onCancelDownload: (Int) -> Unit = {}, - onReplyClick: (Offset, IntSize, Offset) -> Unit, - onGoToReply: (MessageModel) -> Unit = {}, - onReactionClick: (Long, String) -> Unit = { _, _ -> }, - onStickerClick: (Long) -> Unit = {}, - onPollOptionClick: (Long, Int) -> Unit = { _, _ -> }, - onRetractVote: (Long) -> Unit = {}, - onShowVoters: (Long, Int) -> Unit = { _, _ -> }, - onClosePoll: (Long) -> Unit = {}, - onInstantViewClick: ((String) -> Unit)? = null, - onYouTubeClick: ((String) -> Unit)? = null, - onReplyMarkupButtonClick: (Long, InlineKeyboardButtonModel) -> Unit = { _, _ -> }, - shouldReportPosition: Boolean = false, - onPositionChange: (Long, Offset, IntSize) -> Unit = { _, _, _ -> }, - toProfile: (Long) -> Unit, - onViaBotClick: (String) -> Unit = {}, - canReply: Boolean = true, - onReplySwipe: (MessageModel) -> Unit = {}, - swipeEnabled: Boolean = true, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - isAnyViewerOpen: Boolean = false -) { - val configuration = LocalConfiguration.current - val screenWidth = configuration.screenWidthDp.dp - val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE - - val maxWidth = remember(isLandscape, screenWidth) { - if (isLandscape) { - (screenWidth * 0.6f).coerceAtMost(450.dp) - } else { - (screenWidth * 0.85f).coerceAtMost(360.dp) - } - } - - val isOutgoing = msg.isOutgoing - val isSameSenderAbove = remember(olderMsg?.senderId, msg.senderId, olderMsg?.date, msg.date) { - olderMsg?.senderId == msg.senderId && !shouldShowDate(msg, olderMsg) - } - val isSameSenderBelow = remember(newerMsg?.senderId, msg.senderId, newerMsg?.date, msg.date) { - newerMsg != null && newerMsg.senderId == msg.senderId && !shouldShowDate(newerMsg, msg) - } - - val topSpacing = if (!isSameSenderAbove) 8.dp else 2.dp - - val highlightColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f) - val animatedColor = remember { Animatable(Color.Transparent) } - - LaunchedEffect(highlighted) { - if (highlighted) { - animatedColor.animateTo(highlightColor, animationSpec = tween(300)) - delay(450) - animatedColor.animateTo(Color.Transparent, animationSpec = tween(1800)) - onHighlightConsumed() - } - } - - var outerColumnPosition by remember { mutableStateOf(Offset.Zero) } - var bubblePosition by remember { mutableStateOf(Offset.Zero) } - var bubbleSize by remember { mutableStateOf(IntSize.Zero) } - - Column( - modifier = Modifier - .fillMaxWidth() - .background(animatedColor.value, RoundedCornerShape(12.dp)) - .onGloballyPositioned { outerColumnPosition = it.positionInWindow() } - .padding(top = topSpacing) - .pointerInput(Unit) { - detectTapGestures( - onTap = { offset -> - val clickPos = outerColumnPosition + offset - val bubbleRect = Rect(bubblePosition, bubbleSize.toSize()) - if (!bubbleRect.contains(clickPos)) { - onReplyClick(bubblePosition, bubbleSize, clickPos) - } - }, - onLongPress = { offset -> - val clickPos = outerColumnPosition + offset - val bubbleRect = Rect(bubblePosition, bubbleSize.toSize()) - if (!bubbleRect.contains(clickPos)) { - onReplyClick(bubblePosition, bubbleSize, clickPos) - } - } - ) - } - ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = if (isOutgoing) Arrangement.End else Arrangement.Start, - verticalAlignment = Alignment.Bottom - ) { - MessageAvatar( - msg = msg, - isGroup = isGroup, - isOutgoing = isOutgoing, - isSameSenderBelow = isSameSenderBelow, - toProfile = toProfile, - videoPlayerPool = videoPlayerPool - ) - - Column( - modifier = Modifier - .width(IntrinsicSize.Max) - .widthIn(max = maxWidth) - .onGloballyPositioned { coordinates -> - bubblePosition = coordinates.positionInWindow() - bubbleSize = coordinates.size - if (shouldReportPosition) { - onPositionChange(msg.id, bubblePosition, bubbleSize) - } - }, - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - MessageContentSelector( - msg = msg, - newerMsg = newerMsg, - isOutgoing = isOutgoing, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - isGroup = isGroup, - fontSize = fontSize, - letterSpacing = letterSpacing, - bubbleRadius = bubbleRadius, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - autoDownloadFiles = autoDownloadFiles, - autoplayGifs = autoplayGifs, - autoplayVideos = autoplayVideos, - showLinkPreviews = showLinkPreviews, - onPhotoClick = onPhotoClick, - onDownloadPhoto = onDownloadPhoto, - onVideoClick = onVideoClick, - onDocumentClick = onDocumentClick, - onAudioClick = onAudioClick, - onCancelDownload = onCancelDownload, - onReplyClick = onReplyClick, - onGoToReply = onGoToReply, - onReactionClick = onReactionClick, - onStickerClick = onStickerClick, - onPollOptionClick = onPollOptionClick, - onRetractVote = onRetractVote, - onShowVoters = onShowVoters, - onClosePoll = onClosePoll, - onInstantViewClick = onInstantViewClick, - onYouTubeClick = onYouTubeClick, - toProfile = toProfile, - bubblePosition = bubblePosition, - bubbleSize = bubbleSize, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - - MessageReplyMarkup( - msg = msg, - onReplyMarkupButtonClick = onReplyMarkupButtonClick - ) - - MessageViaBotAttribution( - msg = msg, - isOutgoing = isOutgoing, - onViaBotClick = onViaBotClick, - modifier = Modifier.align(if (isOutgoing) Alignment.End else Alignment.Start) - ) - } - } - } -} - -@Composable -private fun MessageAvatar( - msg: MessageModel, - videoPlayerPool: VideoPlayerPool, - isGroup: Boolean, - isOutgoing: Boolean, - isSameSenderBelow: Boolean, - toProfile: (Long) -> Unit -) { - if (isGroup && !isOutgoing) { - if (!isSameSenderBelow) { - Avatar( - path = msg.senderAvatar, - fallbackPath = msg.senderPersonalAvatar, - name = msg.senderName, - size = 40.dp, - isLocal = msg.senderAvatar?.contains("local") ?: false, - onClick = { toProfile(msg.senderId) }, - videoPlayerPool = videoPlayerPool) - } else { - Spacer(modifier = Modifier.width(40.dp)) - } - Spacer(modifier = Modifier.width(8.dp)) - } -} - -@Composable -private fun MessageContentSelector( - msg: MessageModel, - newerMsg: MessageModel?, - isOutgoing: Boolean, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - isGroup: Boolean, - fontSize: Float, - letterSpacing: Float, - bubbleRadius: Float, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - autoDownloadFiles: Boolean, - autoplayGifs: Boolean, - autoplayVideos: Boolean, - showLinkPreviews: Boolean, - onPhotoClick: (MessageModel) -> Unit, - onDownloadPhoto: (Int) -> Unit, - onVideoClick: (MessageModel) -> Unit, - onDocumentClick: (MessageModel) -> Unit, - onAudioClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit, - onReplyClick: (Offset, IntSize, Offset) -> Unit, - onGoToReply: (MessageModel) -> Unit, - onReactionClick: (Long, String) -> Unit, - onStickerClick: (Long) -> Unit, - onPollOptionClick: (Long, Int) -> Unit, - onRetractVote: (Long) -> Unit, - onShowVoters: (Long, Int) -> Unit, - onClosePoll: (Long) -> Unit, - onInstantViewClick: ((String) -> Unit)?, - onYouTubeClick: ((String) -> Unit)?, - toProfile: (Long) -> Unit, - bubblePosition: Offset, - bubbleSize: IntSize, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - isAnyViewerOpen: Boolean = false -) { - Column( - modifier = Modifier.width(IntrinsicSize.Max), - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - when (val content = msg.content) { - is MessageContent.Text -> { - TextMessageBubble( - content = content, - msg = msg, - isOutgoing = isOutgoing, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - bubbleRadius = bubbleRadius, - isGroup = isGroup, - showLinkPreviews = showLinkPreviews, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - onInstantViewClick = onInstantViewClick, - onYouTubeClick = onYouTubeClick, - onClick = { offset -> - onReplyClick(bubblePosition, bubbleSize, bubblePosition + offset) - }, - onLongClick = { offset -> - onReplyClick(bubblePosition, bubbleSize, bubblePosition + offset) - }, - toProfile = toProfile - ) - } - - is MessageContent.Sticker -> { - StickerMessageBubble( - content = content, - msg = msg, - isOutgoing = isOutgoing, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - onStickerClick = { onStickerClick(it) }, - onLongClick = { - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + (bubbleSize.toSize() / 2f).toOffset() - ) - } - ) - } - - is MessageContent.Photo -> { - PhotoMessageBubble( - content = content, - msg = msg, - isOutgoing = isOutgoing, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - isGroup = isGroup, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - onPhotoClick = onPhotoClick, - onDownloadPhoto = onDownloadPhoto, - onCancelDownload = onCancelDownload, - onLongClick = { offset -> - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + offset - ) - }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - toProfile = toProfile, - modifier = Modifier.fillMaxWidth(), - downloadUtils = downloadUtils - ) - } - - is MessageContent.Video -> { - VideoMessageBubble( - content = content, - msg = msg, - isOutgoing = isOutgoing, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - autoplayVideos = autoplayVideos, - onVideoClick = onVideoClick, - onCancelDownload = onCancelDownload, - onLongClick = { offset -> - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + offset - ) - }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - toProfile = toProfile, - modifier = Modifier.fillMaxWidth(), - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } - - is MessageContent.VideoNote -> { - VideoNoteBubble( - content = content, - msg = msg, - isOutgoing = isOutgoing, - onVideoClick = onVideoClick, - onCancelDownload = onCancelDownload, - onLongClick = { offset -> - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + offset - ) - }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) } - ) - } - - is MessageContent.Voice -> { - VoiceMessageBubble( - content = content, - msg = msg, - isOutgoing = isOutgoing, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - isGroup = isGroup, - autoDownloadFiles = autoDownloadFiles, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - onVoiceClick = onAudioClick, - onCancelDownload = onCancelDownload, - onLongClick = { offset -> - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + offset - ) - }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - toProfile = toProfile, - downloadUtils = downloadUtils - ) - } - - is MessageContent.Gif -> { - GifMessageBubble( - content = content, - msg = msg, - isOutgoing = isOutgoing, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - autoplayGifs = autoplayGifs, - onGifClick = onVideoClick, - onCancelDownload = onCancelDownload, - onLongClick = { offset -> - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + offset - ) - }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - toProfile = toProfile, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } - - is MessageContent.Document -> { - DocumentMessageBubble( - content = content, - msg = msg, - isOutgoing = isOutgoing, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - isGroup = isGroup, - autoDownloadFiles = autoDownloadFiles, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - onDocumentClick = onDocumentClick, - onCancelDownload = onCancelDownload, - onLongClick = { offset -> - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + offset - ) - }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - downloadUtils = downloadUtils - ) - } - - is MessageContent.Audio -> { - AudioMessageBubble( - content = content, - msg = msg, - isOutgoing = isOutgoing, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - isGroup = isGroup, - autoDownloadFiles = autoDownloadFiles, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - onAudioClick = onAudioClick, - onCancelDownload = onCancelDownload, - onLongClick = { offset -> - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + offset - ) - }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - downloadUtils = downloadUtils - ) - } - - is MessageContent.Contact -> { - ContactMessageBubble( - content = content, - msg = msg, - isOutgoing = isOutgoing, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - bubbleRadius = bubbleRadius, - isGroup = isGroup, - onClick = { onGoToReply(msg) }, - onLongClick = { - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + (bubbleSize.toSize() / 2f).toOffset() - ) - }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - videoPlayerPool = videoPlayerPool, - toProfile = toProfile, - showReactions = msg.reactions.isNotEmpty() - ) - } - - is MessageContent.Poll -> { - PollMessageBubble( - content = content, - msg = msg, - isOutgoing = isOutgoing, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - bubbleRadius = bubbleRadius, - onOptionClick = { onPollOptionClick(msg.id, it) }, - onRetractVote = { onRetractVote(msg.id) }, - onLongClick = { offset -> - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + offset - ) - }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - onShowVoters = { onShowVoters(msg.id, it) }, - onClosePoll = { onClosePoll(msg.id) }, - toProfile = toProfile - ) - } - - is MessageContent.Location -> { - LocationMessageBubble( - content = content, - msg = msg, - isOutgoing = isOutgoing, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - isGroup = isGroup, - bubbleRadius = bubbleRadius, - onClick = { onGoToReply(msg) }, - onLongClick = { - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + (bubbleSize.toSize() / 2f).toOffset() - ) - }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - toProfile = toProfile - ) - } - - is MessageContent.Venue -> { - VenueMessageBubble( - content = content, - msg = msg, - isOutgoing = isOutgoing, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - isGroup = isGroup, - bubbleRadius = bubbleRadius, - onClick = { onGoToReply(msg) }, - onLongClick = { - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + (bubbleSize.toSize() / 2f).toOffset() - ) - }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - toProfile = toProfile - ) - } - - else -> { - // Fallback - } - } - } -} - -@Composable -private fun MessageReplyMarkup( - msg: MessageModel, - onReplyMarkupButtonClick: (Long, InlineKeyboardButtonModel) -> Unit -) { - msg.replyMarkup?.let { markup -> - ReplyMarkupView( - replyMarkup = markup, - onButtonClick = { onReplyMarkupButtonClick(msg.id, it) } - ) - } -} - -private fun androidx.compose.ui.geometry.Size.toOffset() = Offset(width, height) diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/MessageListShimmer.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/MessageListShimmer.kt deleted file mode 100644 index 57632374..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/MessageListShimmer.kt +++ /dev/null @@ -1,344 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components - -import androidx.compose.animation.core.* -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp - -@Composable -fun MessageListShimmer( - isGroup: Boolean = false, - isChannel: Boolean = false -) { - val shimmer = rememberMessageShimmerBrush() - - if (isChannel) { - ChannelMessageListShimmer(brush = shimmer) - return - } - - val hasSenderMeta = isGroup && !isChannel - - val items = listOf( - ShimmerConfig(false, 0.62f, listOf(0.9f, 0.56f), false, true), - ShimmerConfig(false, 0.4f, listOf(0.7f), true, false), - ShimmerConfig(true, 0.56f, listOf(0.78f, 0.52f), false, false), - ShimmerConfig(false, 0.5f, listOf(0.74f), false, false), - ShimmerConfig(true, 0.44f, listOf(0.66f), false, false), - ShimmerConfig(false, 0.58f, listOf(0.86f, 0.64f), false, false), - ShimmerConfig(true, 0.66f, listOf(0.94f, 0.72f, 0.48f), false, false), - ShimmerConfig(false, 0.54f, listOf(0.8f), false, false), - ShimmerConfig(true, 0.5f, listOf(0.7f), false, true), - ShimmerConfig(true, 0.6f, listOf(0.9f, 0.58f), true, false), - ShimmerConfig(false, 0.66f, listOf(0.9f, 0.68f), false, true), - ShimmerConfig(false, 0.46f, listOf(0.76f), true, false), - ShimmerConfig(true, 0.52f, listOf(0.78f, 0.52f), false, false), - ShimmerConfig(false, 0.6f, listOf(0.84f, 0.6f), false, false) - ) - - Column( - modifier = Modifier - .fillMaxSize() - .padding(horizontal = 12.dp, vertical = 12.dp), - verticalArrangement = Arrangement.Bottom - ) { - items.forEachIndexed { index, config -> - MessagePlaceholder( - brush = shimmer, - isOutgoing = config.isOutgoing, - bubbleWidth = if (isChannel) { - if (config.isOutgoing) 0.92f else 0.94f - } else { - config.bubbleWidth - }, - lineWidths = config.lineWidths, - reserveAvatarSpace = hasSenderMeta, - showAvatar = hasSenderMeta && !config.isOutgoing && !config.isSameSenderAbove, - showSender = hasSenderMeta && !config.isOutgoing && !config.isSameSenderAbove, - isSameSenderAbove = config.isSameSenderAbove, - isSameSenderBelow = config.isSameSenderBelow - ) - - if (index != items.lastIndex) { - Spacer(modifier = Modifier.height(if (config.isSameSenderBelow) 2.dp else 8.dp)) - } - } - } -} - -@Composable -private fun ChannelMessageListShimmer(brush: Brush) { - val posts = listOf( - listOf(0.95f, 0.88f, 0.92f, 0.8f, 0.72f, 0.45f), - listOf(0.9f, 0.85f, 0.93f, 0.78f, 0.88f, 0.9f, 0.82f, 0.55f), - listOf(0.92f, 0.86f, 0.75f, 0.9f, 0.6f), - listOf(0.88f, 0.8f, 0.5f) - ) - - Column( - modifier = Modifier - .fillMaxSize() - .padding(horizontal = 8.dp, vertical = 12.dp), - verticalArrangement = Arrangement.Bottom - ) { - posts.forEachIndexed { index, lines -> - ChannelPostPlaceholder(brush = brush, lineWidths = lines) - if (index != posts.lastIndex) { - Spacer(modifier = Modifier.height(12.dp)) - } - } - } -} - -@Composable -private fun ChannelPostPlaceholder( - brush: Brush, - lineWidths: List -) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.Center - ) { - Surface( - shape = RoundedCornerShape(18.dp), - color = MaterialTheme.colorScheme.surfaceContainerHigh.copy(alpha = 0.65f), - modifier = Modifier.fillMaxWidth(0.94f) - ) { - Column( - modifier = Modifier.padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 6.dp) - ) { - lineWidths.forEachIndexed { index, width -> - ShimmerBlock( - brush = brush, - modifier = Modifier - .fillMaxWidth(width) - .height(14.dp), - shape = RoundedCornerShape(5.dp) - ) - if (index != lineWidths.lastIndex) { - Spacer(modifier = Modifier.height(6.dp)) - } - } - - Spacer(modifier = Modifier.height(8.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.End - ) { - ShimmerBlock( - brush = brush, - modifier = Modifier.size(14.dp), - shape = RoundedCornerShape(7.dp) - ) - Spacer(modifier = Modifier.width(4.dp)) - ShimmerBlock( - brush = brush, - modifier = Modifier - .width(26.dp) - .height(10.dp), - shape = RoundedCornerShape(3.dp) - ) - Spacer(modifier = Modifier.width(6.dp)) - ShimmerBlock( - brush = brush, - modifier = Modifier - .width(32.dp) - .height(10.dp), - shape = RoundedCornerShape(3.dp) - ) - } - } - } - } -} - -private data class ShimmerConfig( - val isOutgoing: Boolean, - val bubbleWidth: Float, - val lineWidths: List, - val isSameSenderAbove: Boolean, - val isSameSenderBelow: Boolean -) - -@Composable -private fun MessagePlaceholder( - brush: Brush, - isOutgoing: Boolean, - bubbleWidth: Float, - lineWidths: List, - reserveAvatarSpace: Boolean, - showAvatar: Boolean, - showSender: Boolean, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean -) { - val bubbleShape = messageShape( - isOutgoing = isOutgoing, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow - ) - - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.Bottom - ) { - if (!isOutgoing && reserveAvatarSpace) { - if (showAvatar) { - ShimmerBlock( - brush = brush, - modifier = Modifier.size(40.dp), - shape = RoundedCornerShape(20.dp) - ) - } else { - Spacer(modifier = Modifier.size(40.dp)) - } - Spacer(modifier = Modifier.width(8.dp)) - } - - if (isOutgoing) { - Spacer(modifier = Modifier.weight(1f)) - } - - Surface( - shape = bubbleShape, - color = if (isOutgoing) { - MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.45f) - } else { - MaterialTheme.colorScheme.surfaceContainerHigh.copy(alpha = 0.65f) - } - ) { - Column( - modifier = Modifier - .fillMaxWidth(bubbleWidth) - .padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 6.dp) - ) { - if (showSender) { - ShimmerBlock( - brush = brush, - modifier = Modifier - .width(78.dp) - .height(12.dp), - shape = RoundedCornerShape(4.dp) - ) - Spacer(modifier = Modifier.height(6.dp)) - } - - lineWidths.forEachIndexed { index, width -> - ShimmerBlock( - brush = brush, - modifier = Modifier - .fillMaxWidth(width) - .height(14.dp), - shape = RoundedCornerShape(5.dp) - ) - if (index != lineWidths.lastIndex) { - Spacer(modifier = Modifier.height(6.dp)) - } - } - - Spacer(modifier = Modifier.height(6.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically - ) { - Spacer(modifier = Modifier.weight(1f)) - ShimmerBlock( - brush = brush, - modifier = Modifier - .width(32.dp) - .height(10.dp), - shape = RoundedCornerShape(3.dp) - ) - if (isOutgoing) { - Spacer(modifier = Modifier.width(4.dp)) - ShimmerBlock( - brush = brush, - modifier = Modifier - .width(13.dp) - .height(10.dp), - shape = RoundedCornerShape(3.dp) - ) - } - } - } - } - - if (!isOutgoing) { - Spacer(modifier = Modifier.weight(1f)) - } - } -} - -@Composable -private fun ShimmerBlock( - brush: Brush, - modifier: Modifier, - shape: Shape = RoundedCornerShape(6.dp) -) { - Box( - modifier = modifier - .clip(shape) - .background(brush) - ) -} - -private fun messageShape( - isOutgoing: Boolean, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - radius: Dp = 18.dp, - small: Dp = 4.5.dp, - tail: Dp = 2.dp -): RoundedCornerShape { - return if (isOutgoing) { - RoundedCornerShape( - topStart = radius, - topEnd = if (isSameSenderAbove) small else radius, - bottomStart = radius, - bottomEnd = if (isSameSenderBelow) small else tail - ) - } else { - RoundedCornerShape( - topStart = if (isSameSenderAbove) small else radius, - topEnd = radius, - bottomStart = if (isSameSenderBelow) small else tail, - bottomEnd = radius - ) - } -} - -@Composable -private fun rememberMessageShimmerBrush(): Brush { - val base = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.4f) - val transition = rememberInfiniteTransition(label = "message_shimmer") - val offset by transition.animateFloat( - initialValue = -600f, - targetValue = 1400f, - animationSpec = infiniteRepeatable( - animation = tween(durationMillis = 1200, easing = LinearEasing), - repeatMode = RepeatMode.Restart - ), - label = "message_shimmer_offset" - ) - - return Brush.linearGradient( - colors = listOf(base, base.copy(alpha = 0.15f), base), - start = Offset(offset, 0f), - end = Offset(offset + 360f, 0f) - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/ServiceMessage.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/ServiceMessage.kt deleted file mode 100644 index ca5154b0..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/ServiceMessage.kt +++ /dev/null @@ -1,37 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components - -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp - -@Composable -fun ServiceMessage(text: String, modifier: Modifier = Modifier) { - Box( - modifier = modifier - .fillMaxWidth() - .padding(vertical = 16.dp, horizontal = 16.dp), - contentAlignment = Alignment.Center - ) { - Surface( - shape = RoundedCornerShape(16.dp), - color = MaterialTheme.colorScheme.secondaryContainer.copy(alpha = 0.4f), - ) { - Text( - text = text, - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSecondaryContainer, - textAlign = TextAlign.Center, - modifier = Modifier.padding(horizontal = 12.dp, vertical = 6.dp) - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/StickerSetSheet.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/StickerSetSheet.kt deleted file mode 100644 index 1035b864..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/StickerSetSheet.kt +++ /dev/null @@ -1,273 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components - -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context -import android.widget.Toast -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.lazy.grid.items -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.outlined.Share -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.pluralStringResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import kotlinx.coroutines.flow.firstOrNull -import kotlinx.coroutines.launch -import org.koin.compose.koinInject -import org.monogram.domain.models.StickerSetModel -import org.monogram.domain.models.StickerType -import org.monogram.domain.repository.StickerRepository -import org.monogram.presentation.R -import org.monogram.presentation.features.stickers.ui.view.StickerImage -import org.monogram.presentation.features.stickers.ui.view.StickerSkeleton - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun StickerSetSheet( - stickerSet: StickerSetModel, - onDismiss: () -> Unit, - onStickerClick: (String) -> Unit, - stickerRepository: StickerRepository = koinInject() -) { - val context = LocalContext.current - val scope = rememberCoroutineScope() - var isInstalled by remember { mutableStateOf(stickerSet.isInstalled) } - val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) - - ModalBottomSheet( - onDismissRequest = onDismiss, - sheetState = sheetState, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 32.dp) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 4.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Column(modifier = Modifier.weight(1f)) { - Text( - text = stickerSet.title, - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = if (stickerSet.stickerType == StickerType.CUSTOM_EMOJI) { - pluralStringResource(R.plurals.emojis_count, stickerSet.stickers.size, stickerSet.stickers.size) - } else { - pluralStringResource(R.plurals.stickers_count, stickerSet.stickers.size, stickerSet.stickers.size) - }, - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - if (stickerSet.stickerType != StickerType.REGULAR) { - Text( - text = " • ", - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Text( - text = when (stickerSet.stickerType) { - StickerType.MASK -> stringResource(R.string.sticker_type_masks) - StickerType.CUSTOM_EMOJI -> stringResource(R.string.sticker_type_custom_emojis) - else -> "" - }, - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.primary - ) - } - if (stickerSet.isOfficial) { - Text( - text = " • ", - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Text( - text = stringResource(R.string.sticker_official), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.primary - ) - } - } - } - - Row(verticalAlignment = Alignment.CenterVertically) { - val linkCopiedText = stringResource(R.string.link_copied) - IconButton( - onClick = { - val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - val link = "https://t.me/addstickers/${stickerSet.name}" - val clip = ClipData.newPlainText("Sticker Set Link", link) - clipboard.setPrimaryClip(clip) - Toast.makeText(context, linkCopiedText, Toast.LENGTH_SHORT).show() - } - ) { - Icon( - imageVector = Icons.Outlined.Share, - contentDescription = stringResource(R.string.menu_share), - tint = MaterialTheme.colorScheme.primary - ) - } - - stickerSet.thumbnail?.let { thumb -> - var thumbPath by remember { mutableStateOf(thumb.path) } - LaunchedEffect(thumb.id) { - if (thumb.path == null) { - thumbPath = stickerRepository.getStickerFile(thumb.id).firstOrNull() - } - } - Box( - modifier = Modifier - .size(48.dp) - .clip(RoundedCornerShape(8.dp)) - .background(MaterialTheme.colorScheme.surfaceContainer), - contentAlignment = Alignment.Center - ) { - if (thumbPath.isNullOrEmpty()) { - StickerSkeleton(modifier = Modifier.size(40.dp)) - } else { - StickerImage( - path = thumbPath, - modifier = Modifier.size(40.dp) - ) - } - } - } - } - } - - Spacer(modifier = Modifier.height(12.dp)) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - LazyVerticalGrid( - columns = GridCells.Adaptive(minSize = 64.dp), - contentPadding = PaddingValues(8.dp), - modifier = Modifier - .fillMaxWidth() - .height(420.dp), - horizontalArrangement = Arrangement.spacedBy(4.dp), - verticalArrangement = Arrangement.spacedBy(4.dp) - ) { - items(stickerSet.stickers, key = { it.id }) { sticker -> - var currentPath by remember(sticker.id, sticker.path) { mutableStateOf(sticker.path) } - - LaunchedEffect(sticker.id, sticker.path) { - if (sticker.path == null) { - currentPath = stickerRepository.getStickerFile(sticker.id).firstOrNull() - } else { - currentPath = sticker.path - } - } - - Box( - modifier = Modifier - .aspectRatio(1f) - .clip(RoundedCornerShape(12.dp)) - .clickable { - currentPath?.let { path -> - onStickerClick(path) - onDismiss() - } - } - .padding(4.dp), - contentAlignment = Alignment.Center - ) { - if (currentPath.isNullOrEmpty()) { - StickerSkeleton(modifier = Modifier.fillMaxSize()) - } else { - StickerImage( - path = currentPath, - modifier = Modifier.fillMaxSize(), - ) - } - } - } - } - } - - Spacer(modifier = Modifier.height(24.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - OutlinedButton( - onClick = onDismiss, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.close_button), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - - if (!isInstalled) { - Button( - onClick = { - scope.launch { - stickerRepository.toggleStickerSetInstalled(stickerSet.id, true) - isInstalled = true - } - }, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.action_add), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } else { - Button( - onClick = { - scope.launch { - stickerRepository.toggleStickerSetInstalled(stickerSet.id, false) - isInstalled = false - } - }, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp), - colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.errorContainer, - contentColor = MaterialTheme.colorScheme.error - ) - ) { - Text(stringResource(R.string.menu_delete), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/VoicePlayer.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/VoicePlayer.kt deleted file mode 100644 index 9061df72..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/VoicePlayer.kt +++ /dev/null @@ -1,101 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components - -import android.net.Uri -import androidx.compose.runtime.* -import androidx.compose.ui.platform.LocalContext -import androidx.media3.common.MediaItem -import androidx.media3.common.Player -import androidx.media3.exoplayer.ExoPlayer -import kotlinx.coroutines.delay -import kotlinx.coroutines.isActive - -@Composable -fun rememberVoicePlayer(path: String?): VoicePlayerState { - val context = LocalContext.current - val player = remember { - ExoPlayer.Builder(context).build().apply { - repeatMode = Player.REPEAT_MODE_OFF - } - } - - val state = remember(path) { VoicePlayerState(player, path) } - - DisposableEffect(player) { - onDispose { - player.release() - } - } - - LaunchedEffect(path) { - if (path != null) { - player.setMediaItem(MediaItem.fromUri(Uri.parse(path))) - player.prepare() - } - } - - return state -} - -class VoicePlayerState( - private val player: ExoPlayer, - private val path: String? -) { - var isPlaying by mutableStateOf(false) - private set - var progress by mutableFloatStateOf(0f) - private set - var currentPosition by mutableLongStateOf(0L) - private set - var duration by mutableLongStateOf(0L) - private set - - init { - player.addListener(object : Player.Listener { - override fun onIsPlayingChanged(playing: Boolean) { - isPlaying = playing - } - - override fun onPlaybackStateChanged(playbackState: Int) { - if (playbackState == Player.STATE_READY) { - duration = player.duration - } else if (playbackState == Player.STATE_ENDED) { - isPlaying = false - progress = 0f - currentPosition = 0 - player.seekTo(0) - player.pause() - } - } - }) - } - - @Composable - fun ProgressUpdater() { - LaunchedEffect(isPlaying) { - while (isActive && isPlaying) { - currentPosition = player.currentPosition - val total = player.duration - if (total > 0) { - progress = currentPosition.toFloat() / total.toFloat() - } - delay(50) - } - } - } - - fun togglePlayPause() { - if (path == null) return - if (player.isPlaying) { - player.pause() - } else { - player.play() - } - } - - fun seekTo(pos: Float) { - val total = player.duration - if (total > 0) { - player.seekTo((pos * total).toLong()) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelAlbumMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelAlbumMessageBubble.kt deleted file mode 100644 index 7250c827..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelAlbumMessageBubble.kt +++ /dev/null @@ -1,693 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.channels - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.InsertDriveFile -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.Download -import androidx.compose.material.icons.filled.PlayArrow -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.components.CompactMediaMosaic -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.chats.currentChat.components.chats.* - -@Composable -fun ChannelAlbumMessageBubble( - messages: List, - isSameSenderAbove: Boolean = false, - isSameSenderBelow: Boolean = false, - autoplayGifs: Boolean, - autoplayVideos: Boolean, - autoDownloadMobile: Boolean = false, - autoDownloadWifi: Boolean = false, - autoDownloadRoaming: Boolean = false, - autoDownloadFiles: Boolean = false, - fontSize: Float, - bubbleRadius: Float = 16f, - onPhotoClick: (MessageModel) -> Unit, - onDownloadPhoto: (Int) -> Unit = {}, - onVideoClick: (MessageModel) -> Unit, - onDocumentClick: (MessageModel) -> Unit = {}, - onAudioClick: (MessageModel) -> Unit = {}, - onCancelDownload: (Int) -> Unit = {}, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - onCommentsClick: (Long) -> Unit = {}, - showComments: Boolean = true, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - isAnyViewerOpen: Boolean = false -) { - if (messages.isEmpty()) return - - val context = LocalContext.current - val uniqueMessages = remember(messages) { messages.distinct() } - val isDocumentAlbum = remember(uniqueMessages) { uniqueMessages.all { it.content is MessageContent.Document } } - val isAudioAlbum = remember(uniqueMessages) { uniqueMessages.all { it.content is MessageContent.Audio } } - - if (isDocumentAlbum) { - ChannelDocumentAlbumBubble( - messages = uniqueMessages, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - bubbleRadius = bubbleRadius, - autoDownloadFiles = autoDownloadFiles, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - onDocumentClick = onDocumentClick, - onCancelDownload = onCancelDownload, - onLongClick = onLongClick, - onReplyClick = onReplyClick, - onReactionClick = onReactionClick, - onCommentsClick = onCommentsClick, - showComments = showComments, - toProfile = toProfile, - modifier = modifier, - downloadUtils = downloadUtils - ) - return - } - - if (isAudioAlbum) { - ChannelAudioAlbumBubble( - messages = uniqueMessages, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - bubbleRadius = bubbleRadius, - autoDownloadFiles = autoDownloadFiles, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - onAudioClick = onAudioClick, - onCancelDownload = onCancelDownload, - onLongClick = onLongClick, - onReplyClick = onReplyClick, - onReactionClick = onReactionClick, - onCommentsClick = onCommentsClick, - showComments = showComments, - toProfile = toProfile, - modifier = modifier, - downloadUtils = downloadUtils - ) - return - } - - val firstMsg = uniqueMessages.first() - val lastMsg = uniqueMessages.last() - - val cornerRadius = bubbleRadius.dp - val smallCorner = (bubbleRadius / 4f).coerceAtLeast(4f).dp - val tailCorner = 2.dp - - val bubbleShape = RoundedCornerShape( - topStart = if (isSameSenderAbove) smallCorner else cornerRadius, - topEnd = cornerRadius, - bottomStart = if (isSameSenderBelow) smallCorner else tailCorner, - bottomEnd = cornerRadius - ) - - val captionMsg = remember(uniqueMessages) { - uniqueMessages.firstOrNull { - val content = it.content - (content is MessageContent.Photo && content.caption.isNotEmpty()) || - (content is MessageContent.Video && content.caption.isNotEmpty()) || - (content is MessageContent.Gif && content.caption.isNotEmpty()) - } - } - - val caption = remember(captionMsg) { - when (val content = captionMsg?.content) { - is MessageContent.Photo -> content.caption - is MessageContent.Video -> content.caption - is MessageContent.Gif -> content.caption - else -> "" - } - } - - val entities = remember(captionMsg) { - when (val content = captionMsg?.content) { - is MessageContent.Photo -> content.entities - is MessageContent.Video -> content.entities - is MessageContent.Gif -> content.entities - else -> emptyList() - } - } - - val formattedTime = remember(lastMsg.date) { formatTime(context, lastMsg.date) } - val revealedSpoilers = remember { mutableStateListOf() } - var bubblePosition by remember { mutableStateOf(Offset.Zero) } - - Column( - modifier = modifier.onGloballyPositioned { bubblePosition = it.positionInWindow() }, - horizontalAlignment = Alignment.CenterHorizontally - ) { - Surface( - shape = bubbleShape, - color = MaterialTheme.colorScheme.surfaceContainerHigh, - modifier = Modifier - .fillMaxWidth() - .clip(bubbleShape) - ) { - Column { - lastMsg.forwardInfo?.let { forward -> - Box(modifier = Modifier.padding(start = 12.dp, end = 12.dp, top = 8.dp)) { - ForwardContent(forward, false, onForwardClick = toProfile) - } - } - lastMsg.replyToMsg?.let { reply -> - Box(modifier = Modifier.padding(start = 12.dp, end = 12.dp, top = 8.dp)) { - ReplyContent( - replyToMsg = reply, - isOutgoing = false, - onClick = { onReplyClick(reply) } - ) - } - } - - CompactMediaMosaic( - messages = uniqueMessages, - autoplayGifs = autoplayGifs, - autoplayVideos = autoplayVideos, - onPhotoClick = onPhotoClick, - onDownloadPhoto = onDownloadPhoto, - onVideoClick = onVideoClick, - onCancelDownload = onCancelDownload, - onLongClick = onLongClick, - showTimestampOverlay = caption.isEmpty(), - timestampStr = formattedTime, - isRead = lastMsg.isRead, - isOutgoing = lastMsg.isOutgoing, - isChannel = true, - views = lastMsg.views, - sendingState = lastMsg.sendingState, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - toProfile = toProfile, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - - if (caption.isNotEmpty()) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 12.dp, vertical = 8.dp) - ) { - val inlineContent = rememberMessageInlineContent(entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = caption, - entities = entities, - isOutgoing = false, - revealedSpoilers = revealedSpoilers - ) - - MessageText( - text = finalAnnotatedString, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = fontSize.sp, - lineHeight = (fontSize * 1.375f).sp - ), - color = MaterialTheme.colorScheme.onSurface, - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = { offset -> onLongClick(bubblePosition + offset) }, - onLongClick = { offset -> onLongClick(bubblePosition + offset) } - ) - - Box( - modifier = Modifier - .fillMaxWidth() - .padding(top = 2.dp), - contentAlignment = Alignment.CenterEnd - ) { - MessageMetadata( - msg = lastMsg, - isOutgoing = lastMsg.isOutgoing, - contentColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.8f) - ) - } - } - } - } - } - - if (showComments && firstMsg.canGetMessageThread) { - ChannelCommentsButton( - replyCount = firstMsg.replyCount, - bubbleRadius = bubbleRadius, - isSameSenderBelow = isSameSenderBelow, - onClick = { onCommentsClick(firstMsg.id) }, - modifier = Modifier.fillMaxWidth() - ) - } - - MessageReactionsView( - reactions = lastMsg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier - .padding(top = 2.dp) - .align(Alignment.Start) - ) - } -} - -@Composable -fun ChannelDocumentAlbumBubble( - messages: List, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - bubbleRadius: Float, - autoDownloadFiles: Boolean, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - onDocumentClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit, - onReactionClick: (String) -> Unit, - onCommentsClick: (Long) -> Unit, - showComments: Boolean, - toProfile: (Long) -> Unit, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils -) { - val firstMsg = messages.first() - val lastMsg = messages.last() - - val cornerRadius = bubbleRadius.dp - val smallCorner = (bubbleRadius / 4f).coerceAtLeast(4f).dp - val tailCorner = 2.dp - - val bubbleShape = RoundedCornerShape( - topStart = if (isSameSenderAbove) smallCorner else cornerRadius, - topEnd = cornerRadius, - bottomStart = if (isSameSenderBelow) smallCorner else tailCorner, - bottomEnd = cornerRadius - ) - - val backgroundColor = MaterialTheme.colorScheme.surfaceContainerHigh - val contentColor = MaterialTheme.colorScheme.onSurfaceVariant - val timeColor = contentColor.copy(alpha = 0.7f) - - val revealedSpoilers = remember { mutableStateListOf() } - var bubblePosition by remember { mutableStateOf(Offset.Zero) } - - Column( - modifier = modifier.onGloballyPositioned { bubblePosition = it.positionInWindow() }, - horizontalAlignment = Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = backgroundColor, - contentColor = contentColor, - tonalElevation = 1.dp, - modifier = Modifier.fillMaxWidth() - ) { - Column( - modifier = Modifier - .padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 8.dp) - .fillMaxWidth() - ) { - lastMsg.forwardInfo?.let { forward -> - Box(modifier = Modifier.padding(bottom = 8.dp)) { - ForwardContent(forward, false, onForwardClick = toProfile) - } - } - lastMsg.replyToMsg?.let { reply -> - Box(modifier = Modifier.padding(bottom = 8.dp)) { - ReplyContent( - replyToMsg = reply, - isOutgoing = false, - onClick = { onReplyClick(reply) } - ) - } - } - - messages.forEachIndexed { index, msg -> - val content = msg.content as MessageContent.Document - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxWidth() - .padding(bottom = if (index == messages.lastIndex && content.caption.isEmpty()) 0.dp else 8.dp) - .clickable { onDocumentClick(msg) } - ) { - Box( - modifier = Modifier - .size(44.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primary) - .clickable { - if (content.isDownloading) { - onCancelDownload(content.fileId) - } else { - onDocumentClick(msg) - } - }, - contentAlignment = Alignment.Center - ) { - if (content.isDownloading || content.isUploading) { - CircularProgressIndicator( - progress = { if (content.isDownloading) content.downloadProgress else content.uploadProgress }, - modifier = Modifier.size(36.dp), - color = MaterialTheme.colorScheme.onPrimary, - strokeWidth = 3.dp, - trackColor = MaterialTheme.colorScheme.onPrimary.copy(alpha = 0.2f), - ) - Icon( - imageVector = Icons.Default.Close, - contentDescription = "Cancel", - tint = MaterialTheme.colorScheme.onPrimary, - modifier = Modifier.size(18.dp) - ) - } else { - val icon = - if (content.path == null) Icons.Default.Download else Icons.AutoMirrored.Filled.InsertDriveFile - Icon( - imageVector = icon, - contentDescription = "File", - tint = MaterialTheme.colorScheme.onPrimary, - modifier = Modifier.size(24.dp) - ) - } - } - - Spacer(modifier = Modifier.width(12.dp)) - - Column(modifier = Modifier.weight(1f)) { - Text( - text = content.fileName.ifEmpty { "Document" }, - style = MaterialTheme.typography.bodyMedium.copy(fontSize = fontSize.sp), - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Text( - text = formatFileSize(content.size), - style = MaterialTheme.typography.labelSmall, - color = timeColor - ) - } - } - } - - val captionMsg = messages.firstOrNull { (it.content as MessageContent.Document).caption.isNotEmpty() } - if (captionMsg != null) { - val content = captionMsg.content as MessageContent.Document - val inlineContent = rememberMessageInlineContent(content.entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = content.caption, - entities = content.entities, - isOutgoing = false, - revealedSpoilers = revealedSpoilers - ) - - MessageText( - text = finalAnnotatedString, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = fontSize.sp, - lineHeight = (fontSize * 1.375f).sp - ), - modifier = Modifier.padding(vertical = 4.dp), - entities = content.entities, - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = { offset -> onLongClick(bubblePosition + offset) }, - onLongClick = { offset -> onLongClick(bubblePosition + offset) } - ) - } - - Box( - modifier = Modifier - .fillMaxWidth() - .padding(top = 2.dp), - contentAlignment = Alignment.CenterEnd - ) { - MessageMetadata(lastMsg, false, timeColor) - } - } - } - - if (showComments && firstMsg.canGetMessageThread) { - ChannelCommentsButton( - replyCount = firstMsg.replyCount, - bubbleRadius = bubbleRadius, - isSameSenderBelow = isSameSenderBelow, - onClick = { onCommentsClick(firstMsg.id) }, - modifier = Modifier.fillMaxWidth() - ) - } - - MessageReactionsView( - reactions = firstMsg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(top = 2.dp) - ) - } -} - -@Composable -fun ChannelAudioAlbumBubble( - messages: List, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - bubbleRadius: Float, - autoDownloadFiles: Boolean, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - onAudioClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit, - onReactionClick: (String) -> Unit, - onCommentsClick: (Long) -> Unit, - showComments: Boolean, - toProfile: (Long) -> Unit, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils -) { - val firstMsg = messages.first() - val lastMsg = messages.last() - - val cornerRadius = bubbleRadius.dp - val smallCorner = (bubbleRadius / 4f).coerceAtLeast(4f).dp - val tailCorner = 2.dp - - val bubbleShape = RoundedCornerShape( - topStart = if (isSameSenderAbove) smallCorner else cornerRadius, - topEnd = cornerRadius, - bottomStart = if (isSameSenderBelow) smallCorner else tailCorner, - bottomEnd = cornerRadius - ) - - val backgroundColor = MaterialTheme.colorScheme.surfaceContainerHigh - val contentColor = MaterialTheme.colorScheme.onSurfaceVariant - val timeColor = contentColor.copy(alpha = 0.7f) - - val revealedSpoilers = remember { mutableStateListOf() } - var bubblePosition by remember { mutableStateOf(Offset.Zero) } - - Column( - modifier = modifier.onGloballyPositioned { bubblePosition = it.positionInWindow() }, - horizontalAlignment = Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = backgroundColor, - contentColor = contentColor, - tonalElevation = 1.dp, - modifier = Modifier.fillMaxWidth() - ) { - Column( - modifier = Modifier - .padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 8.dp) - .fillMaxWidth() - ) { - lastMsg.forwardInfo?.let { forward -> - Box(modifier = Modifier.padding(bottom = 8.dp)) { - ForwardContent(forward, false, onForwardClick = toProfile) - } - } - lastMsg.replyToMsg?.let { reply -> - Box(modifier = Modifier.padding(bottom = 8.dp)) { - ReplyContent( - replyToMsg = reply, - isOutgoing = false, - onClick = { onReplyClick(reply) } - ) - } - } - - messages.forEachIndexed { index, msg -> - val content = msg.content as MessageContent.Audio - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxWidth() - .padding(bottom = if (index == messages.lastIndex && content.caption.isEmpty()) 0.dp else 8.dp) - .clickable { onAudioClick(msg) } - ) { - Box( - modifier = Modifier - .size(44.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primary) - .clickable { - if (content.isDownloading) { - onCancelDownload(content.fileId) - } else { - onAudioClick(msg) - } - }, - contentAlignment = Alignment.Center - ) { - if (content.isDownloading || content.isUploading) { - CircularProgressIndicator( - progress = { if (content.isDownloading) content.downloadProgress else content.uploadProgress }, - modifier = Modifier.size(36.dp), - color = MaterialTheme.colorScheme.onPrimary, - strokeWidth = 3.dp, - trackColor = MaterialTheme.colorScheme.onPrimary.copy(alpha = 0.2f), - ) - Icon( - imageVector = Icons.Default.Close, - contentDescription = "Cancel", - tint = MaterialTheme.colorScheme.onPrimary, - modifier = Modifier.size(18.dp) - ) - } else { - val icon = if (content.path == null) Icons.Default.Download else Icons.Default.PlayArrow - Icon( - imageVector = icon, - contentDescription = "Play", - tint = MaterialTheme.colorScheme.onPrimary, - modifier = Modifier.size(24.dp) - ) - } - } - - Spacer(modifier = Modifier.width(12.dp)) - - Column(modifier = Modifier.weight(1f)) { - Text( - text = content.title.ifEmpty { content.fileName.ifEmpty { "Audio" } }, - style = MaterialTheme.typography.bodyMedium.copy( - fontSize = fontSize.sp, - fontWeight = FontWeight.Bold - ), - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Text( - text = content.performer.ifEmpty { formatFileSize(content.size) }, - style = MaterialTheme.typography.labelSmall, - color = timeColor, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - } - } - - val captionMsg = messages.firstOrNull { (it.content as MessageContent.Audio).caption.isNotEmpty() } - if (captionMsg != null) { - val content = captionMsg.content as MessageContent.Audio - val inlineContent = rememberMessageInlineContent(content.entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = content.caption, - entities = content.entities, - isOutgoing = false, - revealedSpoilers = revealedSpoilers - ) - - MessageText( - text = finalAnnotatedString, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = fontSize.sp, - lineHeight = (fontSize * 1.375f).sp - ), - modifier = Modifier.padding(vertical = 4.dp), - entities = content.entities, - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = { offset -> onLongClick(bubblePosition + offset) }, - onLongClick = { offset -> onLongClick(bubblePosition + offset) } - ) - } - - Box( - modifier = Modifier - .fillMaxWidth() - .padding(top = 2.dp), - contentAlignment = Alignment.CenterEnd - ) { - MessageMetadata(lastMsg, false, timeColor) - } - } - } - - if (showComments && firstMsg.canGetMessageThread) { - ChannelCommentsButton( - replyCount = firstMsg.replyCount, - bubbleRadius = bubbleRadius, - isSameSenderBelow = isSameSenderBelow, - onClick = { onCommentsClick(firstMsg.id) }, - modifier = Modifier.fillMaxWidth() - ) - } - - MessageReactionsView( - reactions = firstMsg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(top = 2.dp) - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelCommentsButton.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelCommentsButton.kt deleted file mode 100644 index 0c5bb4f7..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelCommentsButton.kt +++ /dev/null @@ -1,72 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.channels - -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.Chat -import androidx.compose.material.icons.filled.ChevronRight -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp - -@Composable -fun ChannelCommentsButton( - replyCount: Int, - bubbleRadius: Float, - isSameSenderBelow: Boolean, - onClick: () -> Unit, - modifier: Modifier = Modifier -) { - val context = LocalContext.current - Surface( - modifier = modifier, - color = MaterialTheme.colorScheme.surfaceContainerHigh, - shape = RoundedCornerShape( - topStart = 4.dp, - topEnd = 4.dp, - bottomStart = if (isSameSenderBelow) 4.dp else bubbleRadius.dp, - bottomEnd = bubbleRadius.dp, - ), - onClick = onClick - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 12.dp, vertical = 10.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Row(verticalAlignment = Alignment.CenterVertically) { - Icon( - imageVector = Icons.AutoMirrored.Rounded.Chat, - contentDescription = null, - modifier = Modifier.size(18.dp), - tint = MaterialTheme.colorScheme.primary - ) - Spacer(modifier = Modifier.width(12.dp)) - Text( - text = formatCommentsCount(context, replyCount), - style = MaterialTheme.typography.labelLarge.copy( - fontSize = 14.sp, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Medium - ) - ) - } - Icon( - imageVector = Icons.Default.ChevronRight, - contentDescription = null, - modifier = Modifier.size(20.dp), - tint = MaterialTheme.colorScheme.primary.copy(alpha = 0.7f) - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelGifMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelGifMessageBubble.kt deleted file mode 100644 index 86fb4342..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelGifMessageBubble.kt +++ /dev/null @@ -1,442 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.channels - -import androidx.compose.animation.* -import androidx.compose.animation.core.tween -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.* -import androidx.compose.material.icons.outlined.Visibility -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clipToBounds -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.zIndex -import coil3.compose.rememberAsyncImagePainter -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.domain.models.MessageSendingState -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.AutoDownloadSuppression -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.chats.currentChat.components.VideoStickerPlayer -import org.monogram.presentation.features.chats.currentChat.components.VideoType -import org.monogram.presentation.features.chats.currentChat.components.chats.* - -@Composable -fun ChannelGifMessageBubble( - content: MessageContent.Gif, - msg: MessageModel, - isSameSenderAbove: Boolean = false, - isSameSenderBelow: Boolean = false, - fontSize: Float, - letterSpacing: Float, - bubbleRadius: Float = 18f, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - autoplayGifs: Boolean, - onGifClick: (MessageModel) -> Unit = {}, - onCancelDownload: (Int) -> Unit = {}, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - onCommentsClick: (Long) -> Unit = {}, - showComments: Boolean = true, - showMetadata: Boolean = true, - showReactions: Boolean = true, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - isAnyViewerOpen: Boolean = false -) { - val context = LocalContext.current - val cornerRadius = bubbleRadius.dp - val smallCorner = (bubbleRadius / 4f).coerceAtLeast(4f).dp - val tailCorner = 2.dp - - val bubbleShape = RoundedCornerShape( - topStart = if (isSameSenderAbove) smallCorner else cornerRadius, - topEnd = cornerRadius, - bottomStart = if (isSameSenderBelow) smallCorner else tailCorner, - bottomEnd = cornerRadius - ) - - var gifPosition by remember { mutableStateOf(Offset.Zero) } - val revealedSpoilers = remember { mutableStateListOf() } - - var stablePath by remember(msg.id) { mutableStateOf(content.path) } - val hasPath = !stablePath.isNullOrBlank() - var isAutoDownloadSuppressed by remember(msg.id) { mutableStateOf(false) } - - LaunchedEffect(content.path) { - if (!content.path.isNullOrBlank()) { - stablePath = content.path - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(content.fileId) - } - } - - LaunchedEffect(content.path, content.isDownloading, autoDownloadMobile, autoDownloadWifi, autoDownloadRoaming) { - if (content.path.isNullOrBlank() && !content.isDownloading && !isAutoDownloadSuppressed && !AutoDownloadSuppression.isSuppressed( - content.fileId - ) - ) { - val shouldDownload = when { - downloadUtils.isWifiConnected() -> autoDownloadWifi - downloadUtils.isRoaming() -> autoDownloadRoaming - else -> autoDownloadMobile - } - if (shouldDownload) { - onGifClick(msg) - } - } - } - - Column( - modifier = modifier, - horizontalAlignment = Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = MaterialTheme.colorScheme.surfaceContainerHigh, - tonalElevation = 1.dp, - modifier = Modifier.fillMaxWidth() - ) { - Column(modifier = Modifier.animateContentSize()) { - msg.forwardInfo?.let { forward -> - Box( - modifier = Modifier - .fillMaxWidth() - .background(MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(start = 12.dp, end = 12.dp, top = 8.dp) - .zIndex(1f) - ) { - ForwardContent(forward, false, onForwardClick = toProfile) - } - } - msg.replyToMsg?.let { reply -> - Box( - modifier = Modifier - .fillMaxWidth() - .background(MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(start = 12.dp, end = 12.dp, top = 8.dp) - .zIndex(1f) - ) { - ReplyContent( - replyToMsg = reply, - isOutgoing = false, - onClick = { onReplyClick(reply) } - ) - } - } - - val mediaRatio = if (content.width > 0 && content.height > 0) - (content.width.toFloat() / content.height.toFloat()).coerceIn(0.5f, 2f) - else 1f - - BoxWithConstraints(modifier = Modifier.fillMaxWidth()) { - val mediaHeight = (maxWidth / mediaRatio).coerceIn(160.dp, 320.dp) - - Box( - modifier = Modifier - .fillMaxWidth() - .height(mediaHeight) - .clipToBounds() - .onGloballyPositioned { gifPosition = it.positionInWindow() } - .pointerInput(Unit) { - detectTapGestures( - onTap = { - if (content.isDownloading) { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(content.fileId) - onCancelDownload(content.fileId) - } else { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(content.fileId) - onGifClick(msg) - } - }, - onLongPress = { offset -> onLongClick(gifPosition + offset) } - ) - } - ) { - if (hasPath) { - if (autoplayGifs) { - stablePath?.let { path -> - VideoStickerPlayer( - path = path, - type = VideoType.Gif, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Fit, - animate = !isAnyViewerOpen, - videoPlayerPool = videoPlayerPool, - thumbnailData = content.minithumbnail - ) - } - } else { - Image( - painter = rememberAsyncImagePainter(stablePath), - contentDescription = content.caption, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Fit - ) - - Box( - modifier = Modifier - .align(Alignment.Center) - .size(48.dp) - .background(Color.Black.copy(alpha = 0.45f), CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Default.PlayArrow, - contentDescription = "Play", - tint = Color.White, - modifier = Modifier.size(32.dp) - ) - } - } - - Box( - modifier = Modifier - .align(Alignment.TopStart) - .padding(8.dp) - .background(Color.Black.copy(alpha = 0.45f), RoundedCornerShape(6.dp)) - .padding(horizontal = 6.dp, vertical = 2.dp) - ) { - Text( - text = "GIF", - style = MaterialTheme.typography.labelSmall, - color = Color.White - ) - } - } else { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - MediaLoadingBackground( - previewData = content.minithumbnail, - contentScale = ContentScale.Fit - ) - - MediaLoadingAction( - isDownloading = content.isDownloading, - progress = content.downloadProgress, - idleIcon = Icons.Default.Download, - idleContentDescription = "Download", - onCancelClick = { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(content.fileId) - onCancelDownload(content.fileId) - }, - onIdleClick = { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(content.fileId) - onGifClick(msg) - } - ) - } - } - - if (content.caption.isEmpty() && (hasPath || msg.isOutgoing || content.minithumbnail != null) && showMetadata) { - Box( - modifier = Modifier - .align(Alignment.BottomEnd) - .padding(6.dp) - .background(Color.Black.copy(alpha = 0.45f), RoundedCornerShape(10.dp)) - .padding(horizontal = 6.dp, vertical = 2.dp) - ) { - Row(verticalAlignment = Alignment.CenterVertically) { - msg.views?.let { viewsCount -> - if (viewsCount > 0) { - Icon( - imageVector = Icons.Outlined.Visibility, - contentDescription = null, - modifier = Modifier.size(12.dp), - tint = Color.White - ) - Spacer(modifier = Modifier.width(4.dp)) - Text( - text = formatViews(context, viewsCount), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 10.sp), - color = Color.White - ) - Spacer(modifier = Modifier.width(8.dp)) - } - } - Text( - text = formatTime(context, msg.date), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 10.sp), - color = Color.White - ) - if (msg.isOutgoing) { - Spacer(modifier = Modifier.width(4.dp)) - AnimatedContent( - targetState = msg.sendingState to msg.isRead, - transitionSpec = { - fadeIn(animationSpec = tween(300)) togetherWith fadeOut( - animationSpec = tween( - 300 - ) - ) - }, - label = "SendingState" - ) { (sendingState, isRead) -> - val statusIcon = when (sendingState) { - is MessageSendingState.Pending -> Icons.Default.Schedule - is MessageSendingState.Failed -> Icons.Default.Error - null -> if (isRead) Icons.Default.DoneAll else Icons.Default.Check - } - Icon( - imageVector = statusIcon, - contentDescription = null, - modifier = Modifier.size(12.dp), - tint = if (sendingState is MessageSendingState.Failed) Color.Red else Color.White - ) - } - } - } - } - } - } - } - - if (content.caption.isNotEmpty()) { - Column( - modifier = Modifier - .fillMaxWidth() - .background(MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 6.dp) - .zIndex(1f) - ) { - val inlineContent = rememberMessageInlineContent(content.entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = content.caption, - entities = content.entities, - isOutgoing = false, - revealedSpoilers = revealedSpoilers - ) - - MessageText( - text = finalAnnotatedString, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = fontSize.sp, - letterSpacing = letterSpacing.sp, - lineHeight = (fontSize * 1.375f).sp - ), - modifier = Modifier.padding(bottom = 2.dp), - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = { offset -> onLongClick(gifPosition + offset) }, - onLongClick = { offset -> onLongClick(gifPosition + offset) } - ) - if (showMetadata) { - Row( - modifier = Modifier.align(Alignment.End), - verticalAlignment = Alignment.CenterVertically - ) { - msg.views?.let { viewsCount -> - if (viewsCount > 0) { - Icon( - imageVector = Icons.Outlined.Visibility, - contentDescription = null, - modifier = Modifier.size(14.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant.copy(0.6f) - ) - Spacer(modifier = Modifier.width(4.dp)) - Text( - text = formatViews(context, viewsCount), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 11.sp), - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(0.6f) - ) - Spacer(modifier = Modifier.width(8.dp)) - } - } - Text( - text = formatTime(context, msg.date), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 11.sp), - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(0.6f) - ) - if (msg.isOutgoing) { - Spacer(modifier = Modifier.width(4.dp)) - AnimatedContent( - targetState = msg.sendingState to msg.isRead, - transitionSpec = { - fadeIn(animationSpec = tween(300)) togetherWith fadeOut( - animationSpec = tween( - 300 - ) - ) - }, - label = "SendingState" - ) { (sendingState, isRead) -> - val statusIcon = when (sendingState) { - is MessageSendingState.Pending -> Icons.Default.Schedule - is MessageSendingState.Failed -> Icons.Default.Error - null -> if (isRead) Icons.Default.DoneAll else Icons.Default.Check - } - Icon( - imageVector = statusIcon, - contentDescription = null, - modifier = Modifier.size(14.dp), - tint = if (sendingState is MessageSendingState.Failed) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.onSurfaceVariant.copy( - 0.6f - ) - ) - } - } - } - } - } - } - } - } - - if (showComments && msg.canGetMessageThread) { - ChannelCommentsButton( - replyCount = msg.replyCount, - bubbleRadius = bubbleRadius, - isSameSenderBelow = isSameSenderBelow, - onClick = { onCommentsClick(msg.id) }, - modifier = Modifier.fillMaxWidth() - ) - } - - // Reactions - if (showReactions) { - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier - .padding(top = 2.dp) - .align(Alignment.Start) - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelMessageBubbleContainer.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelMessageBubbleContainer.kt deleted file mode 100644 index afb585e3..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelMessageBubbleContainer.kt +++ /dev/null @@ -1,408 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.channels - -import android.content.res.Configuration -import androidx.compose.animation.Animatable -import androidx.compose.animation.core.tween -import androidx.compose.foundation.background -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.geometry.Rect -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.unit.IntSize -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.toSize -import kotlinx.coroutines.delay -import org.monogram.domain.models.InlineKeyboardButtonModel -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.chatContent.shouldShowDate -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.chats.currentChat.components.chats.* - -@Composable -fun ChannelMessageBubbleContainer( - msg: MessageModel, - olderMsg: MessageModel?, - newerMsg: MessageModel?, - autoplayGifs: Boolean = true, - autoplayVideos: Boolean = true, - autoDownloadFiles: Boolean = false, - showLinkPreviews: Boolean = true, - highlighted: Boolean = false, - onHighlightConsumed: () -> Unit = {}, - onPhotoClick: (MessageModel) -> Unit, - onDownloadPhoto: (Int) -> Unit = {}, - onVideoClick: (MessageModel) -> Unit = {}, - onDocumentClick: (MessageModel) -> Unit = {}, - onAudioClick: (MessageModel) -> Unit = {}, - onCancelDownload: (Int) -> Unit = {}, - onReplyClick: (Offset, IntSize, Offset) -> Unit, - onGoToReply: (MessageModel) -> Unit = {}, - autoDownloadMobile: Boolean = false, - autoDownloadWifi: Boolean = false, - autoDownloadRoaming: Boolean = false, - onReactionClick: (Long, String) -> Unit = { _, _ -> }, - onReplyMarkupButtonClick: (Long, InlineKeyboardButtonModel) -> Unit = { _, _ -> }, - onStickerClick: (Long) -> Unit = {}, - onPollOptionClick: (Long, Int) -> Unit = { _, _ -> }, - onRetractVote: (Long) -> Unit = {}, - onShowVoters: (Long, Int) -> Unit = { _, _ -> }, - onClosePoll: (Long) -> Unit = {}, - onInstantViewClick: ((String) -> Unit)? = null, - onYouTubeClick: ((String) -> Unit)? = null, - fontSize: Float, - letterSpacing: Float, - bubbleRadius: Float, - shouldReportPosition: Boolean = false, - onPositionChange: (Long, Offset, IntSize) -> Unit = { _, _, _ -> }, - onCommentsClick: (Long) -> Unit = {}, - showComments: Boolean = true, - toProfile: (Long) -> Unit = {}, - onViaBotClick: (String) -> Unit = {}, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - isAnyViewerOpen: Boolean = false -) { - val configuration = LocalConfiguration.current - val screenWidth = configuration.screenWidthDp.dp - val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE - - val maxWidth = if (isLandscape) { - (screenWidth * 0.7f).coerceAtMost(600.dp) - } else { - (screenWidth * 0.94f).coerceAtMost(500.dp) - } - - val isSameSenderAbove = olderMsg?.senderId == msg.senderId && !shouldShowDate(msg, olderMsg) - val isSameSenderBelow = newerMsg != null && newerMsg.senderId == msg.senderId && !shouldShowDate(newerMsg, msg) - - val topSpacing = if (!isSameSenderAbove) 12.dp else 2.dp - - val highlightColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f) - val animatedColor = remember { Animatable(Color.Transparent) } - - LaunchedEffect(highlighted) { - if (highlighted) { - animatedColor.animateTo(highlightColor, animationSpec = tween(300)) - delay(450) - animatedColor.animateTo(Color.Transparent, animationSpec = tween(1800)) - onHighlightConsumed() - } - } - - var outerColumnPosition by remember { mutableStateOf(Offset.Zero) } - var bubblePosition by remember { mutableStateOf(Offset.Zero) } - var bubbleSize by remember { mutableStateOf(IntSize.Zero) } - - Column( - modifier = Modifier - .fillMaxWidth() - .background(animatedColor.value, RoundedCornerShape(12.dp)) - .onGloballyPositioned { outerColumnPosition = it.positionInWindow() } - .padding(top = topSpacing) - .pointerInput(Unit) { - detectTapGestures( - onTap = { offset -> - val clickPos = outerColumnPosition + offset - val bubbleRect = Rect(bubblePosition, bubbleSize.toSize()) - if (!bubbleRect.contains(clickPos)) { - onReplyClick(bubblePosition, bubbleSize, clickPos) - } - }, - onLongPress = { offset -> - val clickPos = outerColumnPosition + offset - val bubbleRect = Rect(bubblePosition, bubbleSize.toSize()) - if (!bubbleRect.contains(clickPos)) { - onReplyClick(bubblePosition, bubbleSize, clickPos) - } - } - ) - } - ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.Center, - verticalAlignment = Alignment.Bottom - ) { - Column( - modifier = Modifier - .padding(horizontal = 8.dp) - .widthIn(max = maxWidth) - .fillMaxWidth() - .onGloballyPositioned { coordinates -> - bubblePosition = coordinates.positionInWindow() - bubbleSize = coordinates.size - if (shouldReportPosition) { - onPositionChange(msg.id, bubblePosition, bubbleSize) - } - } - ) { - when (val content = msg.content) { - is MessageContent.Text -> { - ChannelTextMessageBubble( - content = content, - msg = msg, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - bubbleRadius = bubbleRadius, - showLinkPreviews = showLinkPreviews, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - onInstantViewClick = onInstantViewClick, - onYouTubeClick = onYouTubeClick, - onClick = { offset -> - onReplyClick(bubblePosition, bubbleSize, bubblePosition + offset) - }, - onLongClick = { offset -> - onReplyClick(bubblePosition, bubbleSize, bubblePosition + offset) - }, - onCommentsClick = onCommentsClick, - showComments = showComments, - toProfile = toProfile, - modifier = Modifier.fillMaxWidth() - ) - } - - is MessageContent.Photo -> { - ChannelPhotoMessageBubble( - content = content, - msg = msg, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - bubbleRadius = bubbleRadius, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - onPhotoClick = onPhotoClick, - onDownloadPhoto = onDownloadPhoto, - onCancelDownload = onCancelDownload, - onLongClick = { offset -> - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + offset - ) - }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - onCommentsClick = onCommentsClick, - showComments = showComments, - toProfile = toProfile, - modifier = Modifier.fillMaxWidth(), - downloadUtils = downloadUtils - ) - } - - is MessageContent.Video -> { - ChannelVideoMessageBubble( - content = content, - msg = msg, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - bubbleRadius = bubbleRadius, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - autoplayVideos = autoplayVideos, - onVideoClick = onVideoClick, - onCancelDownload = onCancelDownload, - onLongClick = { offset -> - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + offset - ) - }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - onCommentsClick = onCommentsClick, - showComments = showComments, - toProfile = toProfile, - modifier = Modifier.fillMaxWidth(), - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } - - is MessageContent.Document -> { - DocumentMessageBubble( - content = content, - msg = msg, - isOutgoing = false, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - autoDownloadFiles = autoDownloadFiles, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - onDocumentClick = onDocumentClick, - onCancelDownload = onCancelDownload, - onLongClick = { offset -> - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + offset - ) - }, - toProfile = toProfile, - modifier = Modifier.fillMaxWidth(), - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - downloadUtils = downloadUtils - ) - } - - is MessageContent.Audio -> { - AudioMessageBubble( - content = content, - msg = msg, - isOutgoing = false, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - autoDownloadFiles = autoDownloadFiles, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - onAudioClick = onAudioClick, - onCancelDownload = onCancelDownload, - onLongClick = { offset -> - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + offset - ) - }, - toProfile = toProfile, - modifier = Modifier.fillMaxWidth(), - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - downloadUtils = downloadUtils - ) - } - - is MessageContent.Gif -> { - ChannelGifMessageBubble( - content = content, - msg = msg, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - bubbleRadius = bubbleRadius, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - autoplayGifs = autoplayGifs, - onGifClick = onVideoClick, - onCancelDownload = onCancelDownload, - onLongClick = { offset -> - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + offset - ) - }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - onCommentsClick = onCommentsClick, - showComments = showComments, - toProfile = toProfile, - modifier = Modifier.fillMaxWidth(), - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - } - - is MessageContent.Sticker -> { - StickerMessageBubble( - content = content, - msg = msg, - isOutgoing = false, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - onStickerClick = { onStickerClick(content.setId) }, - onLongClick = { - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + (bubbleSize.toSize() / 2f).toOffset() - ) - }, - toProfile = toProfile - ) - } - - is MessageContent.Poll -> { - ChannelPollMessageBubble( - content = content, - msg = msg, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - bubbleRadius = bubbleRadius, - onOptionClick = { onPollOptionClick(msg.id, it) }, - onRetractVote = { onRetractVote(msg.id) }, - onShowVoters = { onShowVoters(msg.id, it) }, - onClosePoll = { onClosePoll(msg.id) }, - onReplyClick = onGoToReply, - onReactionClick = { onReactionClick(msg.id, it) }, - onLongClick = { offset -> - onReplyClick( - bubblePosition, - bubbleSize, - bubblePosition + offset - ) - }, - onCommentsClick = onCommentsClick, - showComments = showComments, - toProfile = toProfile - ) - } - - else -> {} - } - - msg.replyMarkup?.let { markup -> - ReplyMarkupView( - replyMarkup = markup, - onButtonClick = { onReplyMarkupButtonClick(msg.id, it) } - ) - } - - MessageViaBotAttribution( - msg = msg, - isOutgoing = msg.isOutgoing, - onViaBotClick = onViaBotClick, - modifier = Modifier.align(Alignment.Start) - ) - } - } - } -} - -private fun IntSize.toSize() = androidx.compose.ui.geometry.Size(width.toFloat(), height.toFloat()) -private fun androidx.compose.ui.geometry.Size.toOffset() = Offset(width, height) diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelMessageUtils.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelMessageUtils.kt deleted file mode 100644 index 78f54012..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelMessageUtils.kt +++ /dev/null @@ -1,32 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.channels - -import android.content.Context -import org.monogram.presentation.R -import java.text.SimpleDateFormat -import java.util.* - -fun formatTime(context: Context, ts: Int): String = - SimpleDateFormat(context.getString(R.string.format_time), Locale.getDefault()).format(Date(ts.toLong() * 1000)) - -fun formatViews(context: Context, views: Int): String { - return when { - views < 1000 -> views.toString() - views < 1000000 -> context.getString(R.string.views_k, views / 1000.0) - else -> context.getString(R.string.views_m, views / 1000000.0) - } -} - -fun formatCommentsCount(context: Context, count: Int): String { - return when { - count <= 0 -> context.getString(R.string.comment_leave) - count < 1000 -> context.getString(R.string.comment_count, count) - count < 1000000 -> context.getString(R.string.comment_count_k, count / 1000.0) - else -> context.getString(R.string.comment_count_m, count / 1000000.0) - } -} - -fun formatDuration(context: Context, seconds: Int): String { - val m = seconds / 60 - val s = seconds % 60 - return context.getString(R.string.format_duration, m, s) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelPhotoMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelPhotoMessageBubble.kt deleted file mode 100644 index 37c261ab..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelPhotoMessageBubble.kt +++ /dev/null @@ -1,335 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.channels - -import androidx.compose.animation.animateContentSize -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.tween -import androidx.compose.foundation.background -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Download -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.clipToBounds -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.zIndex -import coil3.compose.AsyncImage -import coil3.compose.AsyncImagePainter -import coil3.request.ImageRequest -import coil3.request.crossfade -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.AutoDownloadSuppression -import org.monogram.presentation.features.chats.currentChat.components.chats.* - -@Composable -fun ChannelPhotoMessageBubble( - content: MessageContent.Photo, - msg: MessageModel, - isSameSenderAbove: Boolean = false, - isSameSenderBelow: Boolean = false, - fontSize: Float, - letterSpacing: Float, - bubbleRadius: Float = 18f, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - onPhotoClick: (MessageModel) -> Unit, - onDownloadPhoto: (Int) -> Unit = {}, - onCancelDownload: (Int) -> Unit = {}, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - onCommentsClick: (Long) -> Unit = {}, - showComments: Boolean = true, - showMetadata: Boolean = true, - showReactions: Boolean = true, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils -) { - val context = LocalContext.current - val cornerRadius = bubbleRadius.dp - val smallCorner = (bubbleRadius / 4f).coerceAtLeast(4f).dp - val tailCorner = 2.dp - - // Corner definitions - val topStart = if (isSameSenderAbove) smallCorner else cornerRadius - val topEnd = cornerRadius - val bottomStart = if (isSameSenderBelow) smallCorner else tailCorner - val bottomEnd = cornerRadius - - val bubbleShape = RoundedCornerShape( - topStart = topStart, - topEnd = topEnd, - bottomStart = bottomStart, - bottomEnd = if (showComments && msg.canGetMessageThread) {bottomStart } else {bottomEnd} - ) - - var imagePosition by remember { mutableStateOf(Offset.Zero) } - val revealedSpoilers = remember { mutableStateListOf() } - - var stablePath by remember(msg.id) { mutableStateOf(content.path) } - val hasPath = !stablePath.isNullOrBlank() - var isAutoDownloadSuppressed by remember(msg.id) { mutableStateOf(false) } - var isFullImageReady by remember(msg.id) { mutableStateOf(false) } - val mediaAlpha by animateFloatAsState( - targetValue = if (hasPath && isFullImageReady) 1f else 0f, - animationSpec = tween(320), - label = "ChannelPhotoMediaAlpha" - ) - - LaunchedEffect(content.path) { - if (!content.path.isNullOrBlank()) { - stablePath = content.path - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(content.fileId) - } - } - - LaunchedEffect(hasPath) { - if (!hasPath) { - isFullImageReady = false - } - } - val hasCaption = content.caption.isNotEmpty() - - LaunchedEffect(content.path, content.isDownloading, autoDownloadMobile, autoDownloadWifi, autoDownloadRoaming) { - if (content.path.isNullOrBlank() && !content.isDownloading && !isAutoDownloadSuppressed && !AutoDownloadSuppression.isSuppressed( - content.fileId - ) - ) { - val shouldDownload = when { - downloadUtils.isWifiConnected() -> autoDownloadWifi - downloadUtils.isRoaming() -> autoDownloadRoaming - else -> autoDownloadMobile - } - if (shouldDownload) onDownloadPhoto(content.fileId) - } - } - - Column( - modifier = modifier, - horizontalAlignment = Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = MaterialTheme.colorScheme.surfaceContainerHigh, - tonalElevation = 1.dp, - modifier = Modifier.fillMaxWidth() - ) { - Column(modifier = Modifier - .fillMaxWidth() - .animateContentSize()) { - // Headers (Forward/Reply) - if (msg.forwardInfo != null || msg.replyToMsg != null) { - Column( - modifier = Modifier - .fillMaxWidth() - .background(MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(horizontal = 12.dp, vertical = 6.dp) - .zIndex(1f) - ) { - msg.forwardInfo?.let { ForwardContent(it, false, onForwardClick = toProfile) } - msg.replyToMsg?.let { ReplyContent(it, false, onClick = { onReplyClick(it) }) } - } - } - - val mediaRatio = if (content.width > 0 && content.height > 0) { - (content.width.toFloat() / content.height.toFloat()).coerceIn(0.5f, 2f) - } else 1f - - BoxWithConstraints(modifier = Modifier.fillMaxWidth()) { - val mediaHeight = (maxWidth / mediaRatio).coerceIn(160.dp, 320.dp) - - Box( - modifier = Modifier - .fillMaxWidth() - .height(mediaHeight) - .clip( - if (hasCaption) RoundedCornerShape( - topStart = topStart, - topEnd = topEnd - ) else bubbleShape - ) - .clipToBounds() - .onGloballyPositioned { imagePosition = it.positionInWindow() } - .pointerInput(Unit) { - detectTapGestures( - onTap = { - if (content.isDownloading) { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(content.fileId) - onCancelDownload(content.fileId) - } else { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(content.fileId) - if (hasPath) { - onPhotoClick(msg) - } else { - onDownloadPhoto(content.fileId) - } - } - }, - onLongPress = { offset -> onLongClick(imagePosition + offset) } - ) - } - ) { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - MediaLoadingBackground( - previewData = content.minithumbnail, - contentScale = ContentScale.Fit - ) - - if (hasPath) { - AsyncImage( - model = ImageRequest.Builder(context) - .data(stablePath) - .crossfade(true) - .build(), - contentDescription = content.caption, - modifier = Modifier - .fillMaxSize() - .graphicsLayer { alpha = mediaAlpha }, - contentScale = ContentScale.Fit, - onState = { state -> - isFullImageReady = state is AsyncImagePainter.State.Success - } - ) - } - - if (!hasPath || !isFullImageReady) { - MediaLoadingAction( - isDownloading = content.isDownloading || hasPath, - progress = content.downloadProgress, - idleIcon = Icons.Default.Download, - idleContentDescription = "Download", - showCancelOnDownload = content.isDownloading, - onCancelClick = { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(content.fileId) - onCancelDownload(content.fileId) - }, - onIdleClick = { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(content.fileId) - if (hasPath) { - onPhotoClick(msg) - } else { - onDownloadPhoto(content.fileId) - } - } - ) - } - } - - if (!hasCaption && showMetadata) { - Box( - modifier = Modifier - .align(Alignment.BottomEnd) - .padding(6.dp) - .background(Color.Black.copy(alpha = 0.45f), RoundedCornerShape(10.dp)) - .padding(horizontal = 6.dp, vertical = 2.dp) - ) { - MessageMetadata(msg, msg.isOutgoing, Color.White) - } - } - } - } - - // Caption Section - if (hasCaption) { - Column( - modifier = Modifier - .fillMaxWidth() - .background(MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(start = 10.dp, end = 10.dp, top = 6.dp, bottom = 4.dp) - .zIndex(1f) - ) { - val inlineContent = rememberMessageInlineContent(content.entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = content.caption, - entities = content.entities, - isOutgoing = false, - revealedSpoilers = revealedSpoilers - ) - - MessageText( - text = finalAnnotatedString, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = fontSize.sp, - letterSpacing = letterSpacing.sp, - lineHeight = (fontSize * 1.35f).sp - ), - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = { offset -> onLongClick(imagePosition + offset) }, - onLongClick = { offset -> onLongClick(imagePosition + offset) } - ) - - if (showMetadata) { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(top = 2.dp), - contentAlignment = Alignment.CenterEnd - ) { - MessageMetadata( - msg = msg, - isOutgoing = msg.isOutgoing, - contentColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.8f) - ) - } - } - } - } - } - } - - if (showComments && msg.canGetMessageThread) { - - ChannelCommentsButton( - replyCount = msg.replyCount, - bubbleRadius = bubbleRadius, - isSameSenderBelow = isSameSenderBelow, - onClick = { onCommentsClick(msg.id) }, - modifier = Modifier.fillMaxWidth() - ) - } - - // Reactions - if (showReactions) { - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier - .padding(top = 2.dp) - .align(Alignment.Start) - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelPollMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelPollMessageBubble.kt deleted file mode 100644 index b392db67..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelPollMessageBubble.kt +++ /dev/null @@ -1,68 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.channels - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.Offset -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.features.chats.currentChat.components.chats.PollMessageBubble - -@Composable -fun ChannelPollMessageBubble( - content: MessageContent.Poll, - msg: MessageModel, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - letterSpacing: Float, - bubbleRadius: Float = 18f, - onOptionClick: (Int) -> Unit, - onRetractVote: () -> Unit = {}, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - onShowVoters: (Int) -> Unit = {}, - onClosePoll: () -> Unit = {}, - onLongClick: (Offset) -> Unit = {}, - onCommentsClick: (Long) -> Unit = {}, - showComments: Boolean = true, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier -) { - Column( - modifier = modifier, - horizontalAlignment = Alignment.Start - ) { - PollMessageBubble( - content = content, - msg = msg, - isOutgoing = false, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - bubbleRadius = bubbleRadius, - onOptionClick = onOptionClick, - onRetractVote = onRetractVote, - onReplyClick = onReplyClick, - onReactionClick = onReactionClick, - onShowVoters = onShowVoters, - onClosePoll = onClosePoll, - onLongClick = onLongClick, - toProfile = toProfile, - modifier = Modifier.fillMaxWidth() - ) - - if (showComments && msg.canGetMessageThread) { - ChannelCommentsButton( - replyCount = msg.replyCount, - bubbleRadius = bubbleRadius, - isSameSenderBelow = isSameSenderBelow, - onClick = { onCommentsClick(msg.id) }, - modifier = Modifier.fillMaxWidth() - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelTextMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelTextMessageBubble.kt deleted file mode 100644 index 423f894c..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelTextMessageBubble.kt +++ /dev/null @@ -1,217 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.channels - -import androidx.compose.animation.* -import androidx.compose.animation.core.tween -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Check -import androidx.compose.material.icons.filled.DoneAll -import androidx.compose.material.icons.filled.Error -import androidx.compose.material.icons.filled.Schedule -import androidx.compose.material.icons.outlined.Visibility -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableStateListOf -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.domain.models.MessageSendingState -import org.monogram.presentation.features.chats.currentChat.components.chats.* - -@Composable -fun ChannelTextMessageBubble( - content: MessageContent.Text, - msg: MessageModel, - isSameSenderAbove: Boolean = false, - isSameSenderBelow: Boolean = false, - fontSize: Float, - letterSpacing: Float, - bubbleRadius: Float, - showLinkPreviews: Boolean = true, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - onInstantViewClick: ((String) -> Unit)? = null, - onYouTubeClick: ((String) -> Unit)? = null, - onClick: (Offset) -> Unit = {}, - onLongClick: (Offset) -> Unit = {}, - onCommentsClick: (Long) -> Unit = {}, - showComments: Boolean = true, - showReactions: Boolean = true, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier -) { - val context = LocalContext.current - val cornerRadius = bubbleRadius.dp - val smallCorner = (bubbleRadius / 4f).coerceAtLeast(4f).dp - val tailCorner = 2.dp - - val bubbleShape = RoundedCornerShape( - topStart = if (isSameSenderAbove) smallCorner else cornerRadius, - topEnd = cornerRadius, - bottomStart = - if (isSameSenderBelow) smallCorner else tailCorner, - bottomEnd = if (showComments && msg.canGetMessageThread) {smallCorner } else {cornerRadius} - ) - - val revealedSpoilers = remember { mutableStateListOf() } - - Column( - modifier = modifier.widthIn(min = 80.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Surface( - shape = bubbleShape, - color = MaterialTheme.colorScheme.surfaceContainerHigh, - tonalElevation = 1.dp, - modifier = Modifier.fillMaxWidth() - ) { - Column( - modifier = Modifier - .padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 6.dp) - .animateContentSize() - ) { - msg.forwardInfo?.let { forward -> - ForwardContent(forward, false, onForwardClick = toProfile) - } - msg.replyToMsg?.let { reply -> - ReplyContent( - replyToMsg = reply, - isOutgoing = false, - onClick = { onReplyClick(reply) } - ) - } - - val inlineContent = rememberMessageInlineContent(content.entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = content.text, - entities = content.entities, - isOutgoing = false, - revealedSpoilers = revealedSpoilers - ) - - val isBigEmoji = remember(content.text, content.entities) { - isBigEmoji(content.text, content.entities) - } - val finalFontSize = if (isBigEmoji) fontSize * 5f else fontSize - - MessageText( - text = finalAnnotatedString, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = finalFontSize.sp, - letterSpacing = letterSpacing.sp, - lineHeight = (finalFontSize * 1.1f).sp - ), - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 2.dp), - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = onClick, - onLongClick = onLongClick - ) - - if (showLinkPreviews) { - content.webPage?.let { webPage -> - LinkPreview( - webPage = webPage, - isOutgoing = msg.isOutgoing, - onInstantViewClick = onInstantViewClick, - onYouTubeClick = onYouTubeClick - ) - } - } - - Row( - modifier = Modifier.align(Alignment.End), - verticalAlignment = Alignment.CenterVertically - ) { - msg.views?.let { viewsCount -> - if (viewsCount > 0) { - Icon( - imageVector = Icons.Outlined.Visibility, - contentDescription = null, - modifier = Modifier.size(14.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant.copy(0.6f) - ) - Spacer(modifier = Modifier.width(4.dp)) - Text( - text = formatViews(context, viewsCount), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 11.sp), - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(0.6f) - ) - Spacer(modifier = Modifier.width(8.dp)) - } - } - - Text( - text = formatTime(context, msg.date), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 11.sp), - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(0.6f) - ) - - if (msg.isOutgoing) { - Spacer(modifier = Modifier.width(4.dp)) - AnimatedContent( - targetState = msg.sendingState to msg.isRead, - transitionSpec = { - fadeIn(animationSpec = tween(300)) togetherWith fadeOut(animationSpec = tween(300)) - }, - label = "SendingState" - ) { (sendingState, isRead) -> - val statusIcon = when (sendingState) { - is MessageSendingState.Pending -> Icons.Default.Schedule - is MessageSendingState.Failed -> Icons.Default.Error - null -> if (isRead) Icons.Default.DoneAll else Icons.Default.Check - } - Icon( - imageVector = statusIcon, - contentDescription = "Status", - modifier = Modifier.size(14.dp), - tint = if (sendingState is MessageSendingState.Failed) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.onSurfaceVariant.copy( - 0.6f - ) - ) - } - } - } - } - } - - if (showComments && msg.canGetMessageThread) { - - ChannelCommentsButton( - replyCount = msg.replyCount, - bubbleRadius = bubbleRadius, - isSameSenderBelow = isSameSenderBelow, - onClick = { onCommentsClick(msg.id) }, - modifier = Modifier.fillMaxWidth() - ) - } - - if (showReactions) { - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier - .padding(top = 2.dp) - .align(Alignment.Start) - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelVideoMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelVideoMessageBubble.kt deleted file mode 100644 index abc74af9..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelVideoMessageBubble.kt +++ /dev/null @@ -1,408 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.channels - -import androidx.compose.animation.animateContentSize -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.VolumeOff -import androidx.compose.material.icons.automirrored.filled.VolumeUp -import androidx.compose.material.icons.filled.Download -import androidx.compose.material.icons.filled.PlayArrow -import androidx.compose.material.icons.rounded.Stream -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.blur -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.clipToBounds -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.layout.boundsInWindow -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.zIndex -import coil3.compose.rememberAsyncImagePainter -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.AutoDownloadSuppression -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.chats.currentChat.components.VideoStickerPlayer -import org.monogram.presentation.features.chats.currentChat.components.VideoType -import org.monogram.presentation.features.chats.currentChat.components.chats.* - -@Composable -fun ChannelVideoMessageBubble( - content: MessageContent.Video, - msg: MessageModel, - isSameSenderAbove: Boolean = false, - isSameSenderBelow: Boolean = false, - fontSize: Float, - letterSpacing: Float, - bubbleRadius: Float = 18f, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - autoplayVideos: Boolean, - onVideoClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit = {}, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - onCommentsClick: (Long) -> Unit = {}, - showComments: Boolean = true, - showMetadata: Boolean = true, - showReactions: Boolean = true, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - isAnyViewerOpen: Boolean = false -) { - val cornerRadius = bubbleRadius.dp - val smallCorner = (bubbleRadius / 4f).coerceAtLeast(4f).dp - val tailCorner = 2.dp - - val topStart = if (isSameSenderAbove) smallCorner else cornerRadius - val topEnd = cornerRadius - val bottomStart = if (isSameSenderBelow) smallCorner else tailCorner - val bottomEnd = cornerRadius - - val bubbleShape = RoundedCornerShape( - topStart = topStart, - topEnd = topEnd, - bottomStart = bottomStart, - bottomEnd = bottomEnd - ) - - var videoPosition by remember { mutableStateOf(Offset.Zero) } - var isMuted by remember { mutableStateOf(true) } - var currentPositionSeconds by remember { mutableIntStateOf(0) } - var isVisible by remember { mutableStateOf(false) } - - val context = LocalContext.current - val screenHeightPx = remember { context.resources.displayMetrics.heightPixels } - val revealedSpoilers = remember { mutableStateListOf() } - - var stablePath by remember(msg.id) { mutableStateOf(content.path) } - val hasPath = !stablePath.isNullOrBlank() - var isAutoDownloadSuppressed by remember(msg.id) { mutableStateOf(false) } - val hasCaption = content.caption.isNotEmpty() - - LaunchedEffect(content.path) { - if (!content.path.isNullOrBlank()) { - stablePath = content.path - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(content.fileId) - } - } - - LaunchedEffect(content.path, content.isDownloading, autoDownloadMobile, autoDownloadWifi, autoDownloadRoaming) { - if (content.path.isNullOrBlank() && !content.isDownloading && !content.supportsStreaming && !isAutoDownloadSuppressed && !AutoDownloadSuppression.isSuppressed( - content.fileId - ) - ) { - val shouldDownload = when { - downloadUtils.isWifiConnected() -> autoDownloadWifi - downloadUtils.isRoaming() -> autoDownloadRoaming - else -> autoDownloadMobile - } - if (shouldDownload) onVideoClick(msg) - } - } - - Column( - modifier = modifier - .onGloballyPositioned { - val rect = it.boundsInWindow() - isVisible = rect.bottom > 0 && rect.top < screenHeightPx - }, - horizontalAlignment = Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = MaterialTheme.colorScheme.surfaceContainerHigh, - tonalElevation = 1.dp, - modifier = Modifier.fillMaxWidth() - ) { - Column(modifier = Modifier - .fillMaxWidth() - .animateContentSize()) { - // Headers - if (msg.forwardInfo != null || msg.replyToMsg != null) { - Column( - modifier = Modifier - .fillMaxWidth() - .background(MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(horizontal = 12.dp, vertical = 6.dp) - .zIndex(1f) - ) { - msg.forwardInfo?.let { ForwardContent(it, false, onForwardClick = toProfile) } - msg.replyToMsg?.let { ReplyContent(it, false, onClick = { onReplyClick(it) }) } - } - } - - val mediaRatio = if (content.width > 0 && content.height > 0) - (content.width.toFloat() / content.height.toFloat()).coerceIn(0.5f, 2f) - else 1f - - BoxWithConstraints(modifier = Modifier.fillMaxWidth()) { - val mediaHeight = (maxWidth / mediaRatio).coerceIn(160.dp, 320.dp) - - Box( - modifier = Modifier - .fillMaxWidth() - .height(mediaHeight) - .clip( - if (hasCaption) RoundedCornerShape( - topStart = topStart, - topEnd = topEnd - ) else bubbleShape - ) - .clipToBounds() - .onGloballyPositioned { videoPosition = it.positionInWindow() } - .pointerInput(Unit) { - detectTapGestures( - onTap = { - if (content.isDownloading) { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(content.fileId) - onCancelDownload(content.fileId) - } else { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(content.fileId) - onVideoClick(msg) - } - }, - onLongPress = { offset -> onLongClick(videoPosition + offset) } - ) - } - ) { - if (hasPath || content.supportsStreaming) { - if (autoplayVideos) { - val videoPath = stablePath ?: "http://streaming/${content.fileId}" - VideoStickerPlayer( - path = videoPath, - type = VideoType.Gif, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Fit, - animate = isVisible && !isAnyViewerOpen, - volume = if (isMuted) 0f else 1f, - reportProgress = true, - onProgressUpdate = { - val seconds = (it / 1000).toInt() - if (seconds != currentPositionSeconds) { - currentPositionSeconds = seconds - } - }, - videoPlayerPool = videoPlayerPool, - fileId = if (!hasPath && content.supportsStreaming) content.fileId else 0, - thumbnailData = content.minithumbnail - ) - - // Volume Toggle - Box( - modifier = Modifier - .align(Alignment.TopEnd) - .padding(8.dp) - .size(30.dp) - .background(Color.Black.copy(alpha = 0.45f), CircleShape) - .clickable { isMuted = !isMuted }, - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = if (isMuted) Icons.AutoMirrored.Filled.VolumeOff else Icons.AutoMirrored.Filled.VolumeUp, - contentDescription = null, - tint = Color.White, - modifier = Modifier.size(16.dp) - ) - } - } else { - if (hasPath) { - Image( - painter = rememberAsyncImagePainter(stablePath), - contentDescription = null, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Fit - ) - } else { - if (content.minithumbnail != null) { - Image( - painter = rememberAsyncImagePainter(content.minithumbnail), - contentDescription = null, - modifier = Modifier - .fillMaxSize() - .blur(10.dp), - contentScale = ContentScale.Fit - ) - } - } - Box( - modifier = Modifier - .align(Alignment.Center) - .size(48.dp) - .background(Color.Black.copy(alpha = 0.45f), CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - Icons.Default.PlayArrow, - null, - tint = Color.White, - modifier = Modifier.size(32.dp) - ) - } - } - - // Duration Tag - Box( - modifier = Modifier - .align(Alignment.TopStart) - .padding(8.dp) - .background(Color.Black.copy(alpha = 0.45f), RoundedCornerShape(6.dp)) - .padding(horizontal = 6.dp, vertical = 2.dp) - ) { - Text( - text = if ((hasPath || content.supportsStreaming) && autoplayVideos) { - "${formatDuration(context, currentPositionSeconds)} / ${formatDuration(context, content.duration)}" - } else { - formatDuration(context, content.duration) - }, - style = MaterialTheme.typography.labelSmall, - color = Color.White - ) - } - } else { - // Placeholder / Download State - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - MediaLoadingBackground( - previewData = content.minithumbnail, - contentScale = ContentScale.Fit - ) - - MediaLoadingAction( - isDownloading = content.isDownloading, - progress = content.downloadProgress, - idleIcon = if (content.supportsStreaming) Icons.Rounded.Stream else Icons.Default.Download, - idleContentDescription = if (content.supportsStreaming) "Stream" else "Download", - onCancelClick = { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(content.fileId) - onCancelDownload(content.fileId) - }, - onIdleClick = { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(content.fileId) - onVideoClick(msg) - } - ) - } - } - - if (!hasCaption && showMetadata) { - Box( - modifier = Modifier - .align(Alignment.BottomEnd) - .padding(6.dp) - .background(Color.Black.copy(alpha = 0.45f), RoundedCornerShape(10.dp)) - .padding(horizontal = 6.dp, vertical = 2.dp) - ) { - MessageMetadata(msg, msg.isOutgoing, Color.White) - } - } - } - } - - // Caption Section - if (hasCaption) { - Column( - modifier = Modifier - .fillMaxWidth() - .background(MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(start = 10.dp, end = 10.dp, top = 6.dp, bottom = 4.dp) - .zIndex(1f) - ) { - val inlineContent = rememberMessageInlineContent(content.entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = content.caption, - entities = content.entities, - isOutgoing = false, - revealedSpoilers = revealedSpoilers - ) - - MessageText( - text = finalAnnotatedString, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = fontSize.sp, - letterSpacing = letterSpacing.sp, - lineHeight = (fontSize * 1.35f).sp - ), - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = { offset -> onLongClick(videoPosition + offset) }, - onLongClick = { offset -> onLongClick(videoPosition + offset) } - ) - - if (showMetadata) { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(top = 2.dp), - contentAlignment = Alignment.CenterEnd - ) { - MessageMetadata( - msg = msg, - isOutgoing = msg.isOutgoing, - contentColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.8f) - ) - } - } - } - } - } - } - - if (showComments && msg.canGetMessageThread) { - ChannelCommentsButton( - replyCount = msg.replyCount, - bubbleRadius = bubbleRadius, - isSameSenderBelow = isSameSenderBelow, - onClick = { onCommentsClick(msg.id) }, - modifier = Modifier.fillMaxWidth() - ) - } - - // Reactions - if (showReactions) { - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier - .padding(top = 2.dp) - .align(Alignment.Start) - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelVoiceMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelVoiceMessageBubble.kt deleted file mode 100644 index c55e3fd6..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/channels/ChannelVoiceMessageBubble.kt +++ /dev/null @@ -1,153 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.channels - -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.components.chats.* - -@Composable -fun ChannelVoiceMessageBubble( - content: MessageContent.Voice, - msg: MessageModel, - isSameSenderAbove: Boolean = false, - isSameSenderBelow: Boolean = false, - fontSize: Float, - letterSpacing: Float, - bubbleRadius: Float = 18f, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - autoDownloadFiles: Boolean, - onVoiceClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit = {}, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - onCommentsClick: (Long) -> Unit = {}, - showComments: Boolean = true, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils -) { - val cornerRadius = bubbleRadius.dp - val smallCorner = (bubbleRadius / 4f).coerceAtLeast(4f).dp - val tailCorner = 2.dp - - val bubbleShape = RoundedCornerShape( - topStart = if (isSameSenderAbove) smallCorner else cornerRadius, - topEnd = cornerRadius, - bottomStart = if (isSameSenderBelow) smallCorner else tailCorner, - bottomEnd = cornerRadius - ) - - val backgroundColor = MaterialTheme.colorScheme.surfaceContainerHigh - val contentColor = MaterialTheme.colorScheme.onSurfaceVariant - val timeColor = contentColor.copy(alpha = 0.7f) - - var bubblePosition by remember { mutableStateOf(Offset.Zero) } - - LaunchedEffect( - content.path, - content.isDownloading, - autoDownloadFiles, - autoDownloadMobile, - autoDownloadWifi, - autoDownloadRoaming - ) { - val shouldDownload = if (autoDownloadFiles) { - when { - downloadUtils.isRoaming() -> autoDownloadRoaming - downloadUtils.isWifiConnected() -> autoDownloadWifi - else -> autoDownloadMobile - } - } else { - false - } - - if (shouldDownload && content.path == null && !content.isDownloading) { - onVoiceClick(msg) - } - } - - Column( - modifier = modifier - .onGloballyPositioned { bubblePosition = it.positionInWindow() }, - horizontalAlignment = Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = backgroundColor, - contentColor = contentColor, - tonalElevation = 1.dp, - modifier = Modifier.fillMaxWidth() - ) { - Column( - modifier = Modifier - .padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 8.dp) - .fillMaxWidth() - ) { - msg.forwardInfo?.let { forward -> - Box(modifier = Modifier.padding(bottom = 8.dp)) { - ForwardContent(forward, false, onForwardClick = toProfile) - } - } - msg.replyToMsg?.let { reply -> - Box(modifier = Modifier.padding(bottom = 8.dp)) { - ReplyContent( - replyToMsg = reply, - isOutgoing = false, - onClick = { onReplyClick(reply) } - ) - } - } - - VoiceRow( - content = content, - msg = msg, - onVoiceClick = onVoiceClick, - onCancelDownload = onCancelDownload, - isOutgoing = false - ) - - Box( - modifier = Modifier - .fillMaxWidth() - .padding(top = 2.dp), - contentAlignment = Alignment.CenterEnd - ) { - MessageMetadata(msg, false, timeColor) - } - } - } - - if (showComments && msg.canGetMessageThread) { - ChannelCommentsButton( - replyCount = msg.replyCount, - bubbleRadius = bubbleRadius, - isSameSenderBelow = isSameSenderBelow, - onClick = { onCommentsClick(msg.id) }, - modifier = Modifier.fillMaxWidth() - ) - } - - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(top = 2.dp) - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/AudioMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/AudioMessageBubble.kt deleted file mode 100644 index d618d279..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/AudioMessageBubble.kt +++ /dev/null @@ -1,571 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.Download -import androidx.compose.material.icons.filled.PlayArrow -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.components.channels.ChannelCommentsButton - -@Composable -fun AudioMessageBubble( - content: MessageContent.Audio, - msg: MessageModel, - isOutgoing: Boolean, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - letterSpacing: Float, - autoDownloadFiles: Boolean, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - onAudioClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit = {}, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - onClick: (Offset) -> Unit = {}, - isGroup: Boolean = false, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils -) { - val cornerRadius = 18.dp - val smallCorner = 4.dp - val tailCorner = 2.dp - - LaunchedEffect( - content.path, - content.isDownloading, - autoDownloadFiles, - autoDownloadMobile, - autoDownloadWifi, - autoDownloadRoaming - ) { - val shouldDownload = if (autoDownloadFiles) { - when { - downloadUtils.isRoaming() -> autoDownloadRoaming - downloadUtils.isWifiConnected() -> autoDownloadWifi - else -> autoDownloadMobile - } - } else { - false - } - - if (shouldDownload && content.path == null && !content.isDownloading) { - onAudioClick(msg) - } - } - - val bubbleShape = RoundedCornerShape( - topStart = if (!isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - topEnd = if (isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - bottomStart = if (!isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius, - bottomEnd = if (isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius - ) - - val backgroundColor = - if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh - val contentColor = - if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant - val timeColor = contentColor.copy(alpha = 0.7f) - - val revealedSpoilers = remember { mutableStateListOf() } - var bubblePosition by remember { mutableStateOf(Offset.Zero) } - - Column( - modifier = modifier - .onGloballyPositioned { bubblePosition = it.positionInWindow() }, - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = backgroundColor, - contentColor = contentColor, - tonalElevation = 1.dp - ) { - Column( - modifier = Modifier - .padding(start = 8.dp, end = 8.dp, top = 8.dp, bottom = 6.dp) - .width(IntrinsicSize.Max) - .widthIn(min = 184.dp, max = 300.dp) - ) { - if (isGroup && !isOutgoing && !isSameSenderAbove) { - MessageSenderName(msg, toProfile = toProfile) - } - - msg.forwardInfo?.let { forward -> - Box(modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp)) { - ForwardContent(forward, isOutgoing, onForwardClick = toProfile) - } - } - msg.replyToMsg?.let { reply -> - Box(modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp)) { - ReplyContent( - replyToMsg = reply, - isOutgoing = isOutgoing, - onClick = { onReplyClick(reply) } - ) - } - } - - AudioRow( - content = content, - msg = msg, - fontSize = fontSize, - letterSpacing = letterSpacing, - onAudioClick = onAudioClick, - onCancelDownload = onCancelDownload - ) - - if (content.caption.isNotEmpty()) { - val inlineContent = rememberMessageInlineContent(content.entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = content.caption, - entities = content.entities, - isOutgoing = isOutgoing, - revealedSpoilers = revealedSpoilers - ) - - MessageText( - text = finalAnnotatedString, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = fontSize.sp, - letterSpacing = letterSpacing.sp, - lineHeight = (fontSize * 1.375f).sp - ), - modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp), - entities = content.entities, - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = { offset -> onClick(offset) }, - onLongClick = { offset -> onLongClick(offset) } - ) - } - - Box( - modifier = Modifier - .fillMaxWidth() - .padding(top = if (content.caption.isEmpty()) 0.dp else 4.dp), - contentAlignment = Alignment.CenterEnd - ) { - MessageMetadata(msg, isOutgoing, timeColor) - } - } - } - - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(horizontal = 4.dp) - ) - } -} - -@Composable -fun AudioRow( - content: MessageContent.Audio, - msg: MessageModel, - fontSize: Float, - letterSpacing: Float, - onAudioClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit -) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 4.dp) - .clickable { onAudioClick(msg) } - ) { - Box( - modifier = Modifier - .size(48.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primary) - .clickable { - if (content.isDownloading) { - onCancelDownload(content.fileId) - } else { - onAudioClick(msg) - } - }, - contentAlignment = Alignment.Center - ) { - if (content.isDownloading || content.isUploading) { - CircularProgressIndicator( - progress = { if (content.isDownloading) content.downloadProgress else content.uploadProgress }, - modifier = Modifier.size(40.dp), - color = MaterialTheme.colorScheme.onPrimary, - strokeWidth = 3.dp, - trackColor = MaterialTheme.colorScheme.onPrimary.copy(alpha = 0.2f), - ) - Icon( - imageVector = Icons.Default.Close, - contentDescription = "Cancel", - tint = MaterialTheme.colorScheme.onPrimary, - modifier = Modifier.size(20.dp) - ) - } else { - val icon = if (content.path == null) Icons.Default.Download else Icons.Default.PlayArrow - Icon( - imageVector = icon, - contentDescription = "Play", - tint = MaterialTheme.colorScheme.onPrimary - ) - } - } - - Spacer(modifier = Modifier.width(12.dp)) - - Column( - modifier = Modifier.weight(1f) - ) { - Text( - text = content.title.ifEmpty { content.fileName.ifEmpty { "Audio" } }, - style = MaterialTheme.typography.bodyMedium.copy( - fontSize = fontSize.sp, - letterSpacing = letterSpacing.sp, - fontWeight = FontWeight.Bold - ), - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Text( - text = content.performer.ifEmpty { formatFileSize(content.size) }, - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f), - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - } -} - -@Composable -fun AudioAlbumBubble( - messages: List, - isOutgoing: Boolean, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - letterSpacing: Float, - autoDownloadFiles: Boolean, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - onAudioClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit, - onReactionClick: (String) -> Unit, - isGroup: Boolean = false, - toProfile: (Long) -> Unit, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils -) { - val cornerRadius = 18.dp - val smallCorner = 4.dp - val tailCorner = 2.dp - - val bubbleShape = RoundedCornerShape( - topStart = if (!isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - topEnd = if (isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - bottomStart = if (!isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius, - bottomEnd = if (isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius - ) - - val backgroundColor = - if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh - val contentColor = - if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant - val timeColor = contentColor.copy(alpha = 0.7f) - - val lastMsg = messages.last() - val revealedSpoilers = remember { mutableStateListOf() } - var bubblePosition by remember { mutableStateOf(Offset.Zero) } - - Column( - modifier = modifier.onGloballyPositioned { bubblePosition = it.positionInWindow() }, - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = backgroundColor, - contentColor = contentColor, - tonalElevation = 1.dp - ) { - Column( - modifier = Modifier - .padding(start = 8.dp, end = 8.dp, top = 8.dp, bottom = 6.dp) - .width(IntrinsicSize.Max) - .widthIn(min = 200.dp, max = 300.dp) - ) { - if (isGroup && !isOutgoing && !isSameSenderAbove) { - MessageSenderName(lastMsg, toProfile = toProfile) - } - - lastMsg.replyToMsg?.let { reply -> - Box(modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp)) { - ReplyContent( - replyToMsg = reply, - isOutgoing = isOutgoing, - onClick = { onReplyClick(reply) } - ) - } - } - - messages.forEachIndexed { index, msg -> - val content = msg.content as MessageContent.Audio - - AudioRow( - content = content, - msg = msg, - fontSize = fontSize, - letterSpacing = letterSpacing, - onAudioClick = onAudioClick, - onCancelDownload = onCancelDownload - ) - if (index < messages.lastIndex || content.caption.isNotEmpty()) { - Spacer(modifier = Modifier.height(4.dp)) - } - } - - val captionMsg = messages.firstOrNull { (it.content as MessageContent.Audio).caption.isNotEmpty() } - if (captionMsg != null) { - val content = captionMsg.content as MessageContent.Audio - val inlineContent = rememberMessageInlineContent(content.entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = content.caption, - entities = content.entities, - isOutgoing = isOutgoing, - revealedSpoilers = revealedSpoilers - ) - - MessageText( - text = finalAnnotatedString, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = fontSize.sp, - letterSpacing = letterSpacing.sp, - lineHeight = (fontSize * 1.375f).sp - ), - modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp), - entities = content.entities, - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = { offset -> onLongClick(bubblePosition + offset) }, - onLongClick = { offset -> onLongClick(bubblePosition + offset) } - ) - } - - Box( - modifier = Modifier - .fillMaxWidth() - .padding(top = 2.dp), - contentAlignment = Alignment.CenterEnd - ) { - MessageMetadata(lastMsg, isOutgoing, timeColor) - } - } - } - - MessageReactionsView( - reactions = lastMsg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(horizontal = 4.dp) - ) - } -} - -@Composable -fun ChannelAudioAlbumBubble( - messages: List, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - letterSpacing: Float, - bubbleRadius: Float, - autoDownloadFiles: Boolean, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - onAudioClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit, - onReactionClick: (String) -> Unit, - onCommentsClick: (Long) -> Unit, - showComments: Boolean, - toProfile: (Long) -> Unit, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils -) { - val firstMsg = messages.first() - val lastMsg = messages.last() - - val cornerRadius = bubbleRadius.dp - val smallCorner = (bubbleRadius / 4f).coerceAtLeast(4f).dp - val tailCorner = 2.dp - - val bubbleShape = RoundedCornerShape( - topStart = if (isSameSenderAbove) smallCorner else cornerRadius, - topEnd = cornerRadius, - bottomStart = if (isSameSenderBelow) smallCorner else tailCorner, - bottomEnd = cornerRadius - ) - - val backgroundColor = MaterialTheme.colorScheme.surfaceContainerHigh - val contentColor = MaterialTheme.colorScheme.onSurfaceVariant - val timeColor = contentColor.copy(alpha = 0.7f) - - val revealedSpoilers = remember { mutableStateListOf() } - var bubblePosition by remember { mutableStateOf(Offset.Zero) } - - Column( - modifier = modifier.onGloballyPositioned { bubblePosition = it.positionInWindow() }, - horizontalAlignment = Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = backgroundColor, - contentColor = contentColor, - tonalElevation = 1.dp, - modifier = Modifier.fillMaxWidth() - ) { - Column( - modifier = Modifier - .padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 8.dp) - .fillMaxWidth() - ) { - lastMsg.forwardInfo?.let { forward -> - Box(modifier = Modifier.padding(bottom = 8.dp)) { - ForwardContent(forward, false, onForwardClick = toProfile) - } - } - lastMsg.replyToMsg?.let { reply -> - Box(modifier = Modifier.padding(bottom = 8.dp)) { - ReplyContent( - replyToMsg = reply, - isOutgoing = false, - onClick = { onReplyClick(reply) } - ) - } - } - - messages.forEachIndexed { index, msg -> - val content = msg.content as MessageContent.Audio - AudioRow( - content = content, - msg = msg, - fontSize = fontSize, - letterSpacing = letterSpacing, - onAudioClick = onAudioClick, - onCancelDownload = onCancelDownload - ) - if (index < messages.lastIndex || content.caption.isNotEmpty()) { - Spacer(modifier = Modifier.height(4.dp)) - } - } - - val captionMsg = messages.firstOrNull { (it.content as MessageContent.Audio).caption.isNotEmpty() } - if (captionMsg != null) { - val content = captionMsg.content as MessageContent.Audio - val inlineContent = rememberMessageInlineContent(content.entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = content.caption, - entities = content.entities, - isOutgoing = false, - revealedSpoilers = revealedSpoilers - ) - - MessageText( - text = finalAnnotatedString, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = fontSize.sp, - letterSpacing = letterSpacing.sp, - lineHeight = (fontSize * 1.375f).sp - ), - modifier = Modifier.padding(vertical = 4.dp), - entities = content.entities, - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = { offset -> onLongClick(bubblePosition + offset) }, - onLongClick = { offset -> onLongClick(bubblePosition + offset) } - ) - } - - Box( - modifier = Modifier - .fillMaxWidth() - .padding(top = 2.dp), - contentAlignment = Alignment.CenterEnd - ) { - MessageMetadata(lastMsg, false, timeColor) - } - } - } - - if (showComments && firstMsg.canGetMessageThread) { - Spacer(modifier = Modifier.height(4.dp)) - ChannelCommentsButton( - replyCount = firstMsg.replyCount, - bubbleRadius = bubbleRadius, - isSameSenderBelow = isSameSenderBelow, - onClick = { onCommentsClick(firstMsg.id) }, - modifier = Modifier.fillMaxWidth() - ) - } - - MessageReactionsView( - reactions = firstMsg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(top = 2.dp) - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/BotCommandItem.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/BotCommandItem.kt deleted file mode 100644 index 47a354e7..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/BotCommandItem.kt +++ /dev/null @@ -1,121 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.PlayArrow -import androidx.compose.material.icons.rounded.Stop -import androidx.compose.material.icons.rounded.Terminal -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.BotCommandModel -import org.monogram.presentation.core.ui.ItemPosition - -@Composable -fun BotCommandItem( - command: BotCommandModel, - position: ItemPosition, - onClick: () -> Unit, - modifier: Modifier = Modifier -) { - val isStart = command.command.lowercase() == "start" - val isStop = command.command.lowercase() == "stop" - - val icon = when { - isStart -> Icons.Rounded.PlayArrow - isStop -> Icons.Rounded.Stop - else -> Icons.Rounded.Terminal - } - - val iconTint = when { - isStart -> Color(0xFF4CAF50) - isStop -> MaterialTheme.colorScheme.error - else -> MaterialTheme.colorScheme.primary - } - - val iconBackground = iconTint.copy(alpha = 0.1f) - - val cornerRadius = 16.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = modifier - .fillMaxWidth() - .clip(shape) - .clickable(onClick = onClick) - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 10.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(36.dp) - .background( - color = iconBackground, - shape = CircleShape - ), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = icon, - contentDescription = null, - modifier = Modifier.size(20.dp), - tint = iconTint - ) - } - Spacer(modifier = Modifier.width(12.dp)) - Column(modifier = Modifier.weight(1f)) { - Text( - text = "/${command.command}", - style = MaterialTheme.typography.titleSmall, - color = iconTint, - fontWeight = FontWeight.Bold, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - if (command.description.isNotEmpty()) { - Text( - text = command.description, - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/BotCommandSuggestions.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/BotCommandSuggestions.kt deleted file mode 100644 index 89ca3186..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/BotCommandSuggestions.kt +++ /dev/null @@ -1,58 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.animation.* -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.heightIn -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.BotCommandModel -import org.monogram.presentation.core.ui.ItemPosition - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun BotCommandSuggestions( - commands: List, - onCommandClick: (String) -> Unit, - modifier: Modifier -) { - AnimatedVisibility( - visible = commands.isNotEmpty(), - enter = fadeIn() + expandVertically(expandFrom = Alignment.Bottom), - exit = fadeOut() + shrinkVertically(shrinkTowards = Alignment.Bottom), - modifier = modifier - .fillMaxWidth() - .padding(horizontal = 8.dp, vertical = 4.dp) - ) { - LazyColumn( - modifier = Modifier - .fillMaxWidth() - .heightIn(max = 240.dp), - verticalArrangement = Arrangement.spacedBy(2.dp) - ) { - itemsIndexed( - items = commands, - key = { index, command -> "cmd_suggest_${index}_${command.command}" } - ) { index, command -> - val position = when { - commands.size == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == commands.size - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - BotCommandItem( - command = command, - position = position, - onClick = { onCommandClick(command.command) }, - modifier = Modifier.animateItem() - ) - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/BotCommandsSheet.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/BotCommandsSheet.kt deleted file mode 100644 index b5fac5fd..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/BotCommandsSheet.kt +++ /dev/null @@ -1,131 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.SmartToy -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.BotCommandModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ItemPosition - -@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) -@Composable -fun BotCommandsSheet( - commands: List, - onCommandClick: (String) -> Unit, - onDismiss: () -> Unit -) { - ModalBottomSheet( - onDismissRequest = onDismiss, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .navigationBarsPadding() - ) { - BotCommandsHeader() - - LazyColumn( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp), - verticalArrangement = Arrangement.spacedBy(2.dp), - contentPadding = PaddingValues(bottom = 24.dp) - ) { - itemsIndexed( - items = commands, - key = { index, command -> "cmd_${index}_${command.command}" } - ) { index, command -> - val position = when { - commands.size == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == commands.size - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - BotCommandItem( - command = command, - position = position, - onClick = { - onCommandClick(command.command) - onDismiss() - }, - modifier = Modifier.animateItem() - ) - } - } - - Box(modifier = Modifier.padding(16.dp)) { - Button( - onClick = onDismiss, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text( - text = stringResource(R.string.close_button), - fontSize = 16.sp, - fontWeight = FontWeight.Bold - ) - } - } - } - } -} - -@Composable -private fun BotCommandsHeader() { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 16.dp, horizontal = 24.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Box( - modifier = Modifier - .size(64.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primary.copy(alpha = 0.1f)), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.SmartToy, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.size(32.dp) - ) - } - Spacer(modifier = Modifier.height(16.dp)) - Text( - text = stringResource(R.string.bot_commands_title), - style = MaterialTheme.typography.titleLarge, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - Text( - text = stringResource(R.string.bot_commands_subtitle), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center - ) - Spacer(modifier = Modifier.height(8.dp)) - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/ChatAlbumMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/ChatAlbumMessageBubble.kt deleted file mode 100644 index 9717543a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/ChatAlbumMessageBubble.kt +++ /dev/null @@ -1,292 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.domain.models.MessageSendingState -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.components.CompactMediaMosaic -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -@Composable -fun ChatAlbumMessageBubble( - messages: List, - isOutgoing: Boolean, - isGroup: Boolean = false, - isSameSenderAbove: Boolean = false, - isSameSenderBelow: Boolean = false, - autoplayGifs: Boolean, - autoplayVideos: Boolean, - autoDownloadMobile: Boolean = false, - autoDownloadWifi: Boolean = false, - autoDownloadRoaming: Boolean = false, - autoDownloadFiles: Boolean = false, - onPhotoClick: (MessageModel) -> Unit, - onDownloadPhoto: (Int) -> Unit = {}, - onVideoClick: (MessageModel) -> Unit, - onDocumentClick: (MessageModel) -> Unit = {}, - onAudioClick: (MessageModel) -> Unit = {}, - onCancelDownload: (Int) -> Unit = {}, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier, - fontSize: Float = 16f, - letterSpacing: Float = 0f, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - isAnyViewerOpen: Boolean = false -) { - if (messages.isEmpty()) return - - val uniqueMessages = remember(messages) { messages.distinct() } - val isDocumentAlbum = remember(uniqueMessages) { uniqueMessages.all { it.content is MessageContent.Document } } - val isAudioAlbum = remember(uniqueMessages) { uniqueMessages.all { it.content is MessageContent.Audio } } - - if (isDocumentAlbum) { - DocumentAlbumBubble( - messages = uniqueMessages, - isOutgoing = isOutgoing, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - autoDownloadFiles = autoDownloadFiles, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - onDocumentClick = onDocumentClick, - onCancelDownload = onCancelDownload, - onLongClick = onLongClick, - onReplyClick = onReplyClick, - onReactionClick = onReactionClick, - isGroup = isGroup, - toProfile = toProfile, - modifier = modifier, - downloadUtils = downloadUtils - ) - return - } - - if (isAudioAlbum) { - AudioAlbumBubble( - messages = uniqueMessages, - isOutgoing = isOutgoing, - isSameSenderAbove = isSameSenderAbove, - isSameSenderBelow = isSameSenderBelow, - fontSize = fontSize, - letterSpacing = letterSpacing, - autoDownloadFiles = autoDownloadFiles, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - onAudioClick = onAudioClick, - onCancelDownload = onCancelDownload, - onLongClick = onLongClick, - onReplyClick = onReplyClick, - onReactionClick = onReactionClick, - isGroup = isGroup, - toProfile = toProfile, - modifier = modifier, - downloadUtils = downloadUtils - ) - return - } - - val cornerRadius = 16.dp - val smallCorner = 4.dp - - val bubbleShape = remember(isOutgoing, isSameSenderAbove, isSameSenderBelow) { - RoundedCornerShape( - topStart = if (!isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - topEnd = if (isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - bottomStart = if (!isOutgoing) { - if (isSameSenderBelow) smallCorner else cornerRadius - } else cornerRadius, - bottomEnd = if (isOutgoing) { - if (isSameSenderBelow) smallCorner else cornerRadius - } else cornerRadius - ) - } - - val captionMsg = remember(uniqueMessages) { - uniqueMessages.firstOrNull { - val content = it.content - (content is MessageContent.Photo && content.caption.isNotEmpty()) || - (content is MessageContent.Video && content.caption.isNotEmpty()) || - (content is MessageContent.Gif && content.caption.isNotEmpty()) - } - } - - val caption = remember(captionMsg) { - when (val content = captionMsg?.content) { - is MessageContent.Photo -> content.caption - is MessageContent.Video -> content.caption - is MessageContent.Gif -> content.caption - else -> "" - } - } - - val entities = remember(captionMsg) { - when (val content = captionMsg?.content) { - is MessageContent.Photo -> content.entities - is MessageContent.Video -> content.entities - is MessageContent.Gif -> content.entities - else -> emptyList() - } - } - - val lastMsg = uniqueMessages.last() - val formattedTime = remember(lastMsg.date) { formatTime(lastMsg.date) } - val revealedSpoilers = remember { mutableStateListOf() } - var bubblePosition by remember { mutableStateOf(Offset.Zero) } - - Column( - modifier = modifier.onGloballyPositioned { bubblePosition = it.positionInWindow() }, - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh, - modifier = Modifier.clip(bubbleShape) - ) { - Column { - lastMsg.replyToMsg?.let { reply -> - Box(modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp)) { - ReplyContent( - replyToMsg = reply, - isOutgoing = isOutgoing, - onClick = { onReplyClick(reply) } - ) - } - } - - CompactMediaMosaic( - messages = uniqueMessages, - autoplayGifs = autoplayGifs, - autoplayVideos = autoplayVideos, - onPhotoClick = onPhotoClick, - onDownloadPhoto = onDownloadPhoto, - onVideoClick = onVideoClick, - onCancelDownload = onCancelDownload, - onLongClick = onLongClick, - showTimestampOverlay = caption.isEmpty(), - timestampStr = formattedTime, - isRead = lastMsg.isRead, - isOutgoing = isOutgoing, - isChannel = false, - views = lastMsg.views, - sendingState = lastMsg.sendingState, - autoDownloadMobile = autoDownloadMobile, - autoDownloadWifi = autoDownloadWifi, - autoDownloadRoaming = autoDownloadRoaming, - toProfile = toProfile, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool, - isAnyViewerOpen = isAnyViewerOpen - ) - - if (caption.isNotEmpty()) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 12.dp, vertical = 8.dp) - ) { - val inlineContent = rememberMessageInlineContent(entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = caption, - entities = entities, - isOutgoing = isOutgoing, - revealedSpoilers = revealedSpoilers - ) - - MessageText( - text = finalAnnotatedString, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = fontSize.sp, - letterSpacing = letterSpacing.sp, - lineHeight = (fontSize * 1.375f).sp - ), - color = if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurface, - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = { offset -> onLongClick(bubblePosition + offset) }, - onLongClick = { offset -> onLongClick(bubblePosition + offset) } - ) - - Row( - modifier = Modifier.align(Alignment.End), - verticalAlignment = Alignment.CenterVertically - ) { - ChatTimestampInfo( - time = formattedTime, - isRead = lastMsg.isRead, - isOutgoing = isOutgoing, - sendingState = lastMsg.sendingState, - color = if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer.copy(0.6f) - else MaterialTheme.colorScheme.onSurfaceVariant.copy(0.6f) - ) - } - } - } - } - } - - MessageReactionsView( - reactions = lastMsg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(horizontal = 4.dp) - ) - } -} - -@Composable -fun ChatTimestampInfo( - time: String, - isRead: Boolean, - isOutgoing: Boolean, - sendingState: MessageSendingState? = null, - color: Color, - modifier: Modifier = Modifier -) { - Row( - modifier = modifier, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = time, - style = MaterialTheme.typography.labelSmall.copy(fontSize = 11.sp), - color = color - ) - if (isOutgoing) { - Spacer(modifier = Modifier.width(4.dp)) - MessageSendingStatusIcon( - sendingState = sendingState, - isRead = isRead, - baseColor = color, - size = 14.dp - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/CodeBlock.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/CodeBlock.kt deleted file mode 100644 index a79baa14..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/CodeBlock.kt +++ /dev/null @@ -1,181 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import android.provider.Settings -import android.widget.Toast -import androidx.compose.foundation.background -import androidx.compose.foundation.horizontalScroll -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ContentCopy -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalClipboardManager -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.koin.compose.koinInject -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.core.util.NightMode -import org.monogram.presentation.features.chats.currentChat.components.chats.code.CodeHighlighter -import java.util.* - -@Composable -fun CodeBlock( - text: String, - language: String, - isOutgoing: Boolean, - modifier: Modifier = Modifier, - appPreferences: AppPreferences = koinInject() -) { - val clipboardManager = LocalClipboardManager.current - val context = LocalContext.current - val backgroundColor = if (isOutgoing) { - MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.08f) - } else { - MaterialTheme.colorScheme.onSurface.copy(alpha = 0.04f) - } - val contentColor = if (isOutgoing) { - MaterialTheme.colorScheme.onPrimaryContainer - } else { - MaterialTheme.colorScheme.onSurfaceVariant - } - val headerColor = if (isOutgoing) { - MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.05f) - } else { - MaterialTheme.colorScheme.onSurface.copy(alpha = 0.02f) - } - - val highlighter = remember { CodeHighlighter() } - val colorScheme = MaterialTheme.colorScheme - - val nightMode by appPreferences.nightMode.collectAsState() - val isDynamicColorsEnabled by appPreferences.isDynamicColorsEnabled.collectAsState() - val startTimeStr by appPreferences.nightModeStartTime.collectAsState() - val endTimeStr by appPreferences.nightModeEndTime.collectAsState() - val brightnessThreshold by appPreferences.nightModeBrightnessThreshold.collectAsState() - - val systemDark = isSystemInDarkTheme() - var screenBrightness by remember { mutableFloatStateOf(1f) } - - if (nightMode == NightMode.BRIGHTNESS) { - DisposableEffect(Unit) { - val contentResolver = context.contentResolver - val listener = object : - android.database.ContentObserver(android.os.Handler(android.os.Looper.getMainLooper())) { - override fun onChange(selfChange: Boolean) { - val brightness = - Settings.System.getInt(contentResolver, Settings.System.SCREEN_BRIGHTNESS, 255) - screenBrightness = brightness / 255f - } - } - contentResolver.registerContentObserver( - Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS), - false, - listener - ) - val brightness = Settings.System.getInt(contentResolver, Settings.System.SCREEN_BRIGHTNESS, 255) - screenBrightness = brightness / 255f - - onDispose { - contentResolver.unregisterContentObserver(listener) - } - } - } - - val isDark = when (nightMode) { - NightMode.SYSTEM -> systemDark - NightMode.LIGHT -> false - NightMode.DARK -> true - NightMode.SCHEDULED -> { - val calendar = Calendar.getInstance() - val nowHour = calendar.get(Calendar.HOUR_OF_DAY) - val nowMinute = calendar.get(Calendar.MINUTE) - val now = nowHour * 60 + nowMinute - - val startParts = startTimeStr.split(":") - val start = if (startParts.size == 2) startParts[0].toInt() * 60 + startParts[1].toInt() else 22 * 60 - - val endParts = endTimeStr.split(":") - val end = if (endParts.size == 2) endParts[0].toInt() * 60 + endParts[1].toInt() else 7 * 60 - - if (start < end) { - now in start until end - } else { - now >= start || now < end - } - } - - NightMode.BRIGHTNESS -> screenBrightness <= brightnessThreshold - } - - Surface( - modifier = modifier - .padding(vertical = 4.dp), - shape = RoundedCornerShape(12.dp), - color = backgroundColor, - border = null - ) { - Column(modifier = Modifier.widthIn(min = 120.dp)) { - Row( - modifier = Modifier - .fillMaxWidth() - .background(headerColor) - .padding(horizontal = 12.dp, vertical = 6.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - if (language.isNotEmpty()) { - Text( - text = language, - style = MaterialTheme.typography.labelSmall, - color = contentColor.copy(alpha = 0.5f), - fontWeight = FontWeight.Bold - ) - } else { - Spacer(modifier = Modifier.weight(1f)) - } - IconButton( - onClick = { - clipboardManager.setText(AnnotatedString(text)) - Toast.makeText(context, "Copied to clipboard", Toast.LENGTH_SHORT).show() - }, - modifier = Modifier.size(24.dp) - ) { - Icon( - imageVector = Icons.Default.ContentCopy, - contentDescription = "Copy", - modifier = Modifier.size(14.dp), - tint = contentColor.copy(alpha = 0.7f) - ) - } - } - Box( - modifier = Modifier - .horizontalScroll(rememberScrollState()) - .padding(12.dp) - ) { - Text( - text = highlighter.highlight( - text = text, - language = language, - isDark = isDark, - scheme = if (isDynamicColorsEnabled) colorScheme else null - ), - style = MaterialTheme.typography.bodyMedium.copy( - fontFamily = FontFamily.Monospace, - fontSize = 13.sp - ), - softWrap = false - ) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/ContactMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/ContactMessageBubble.kt deleted file mode 100644 index 65f09bf5..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/ContactMessageBubble.kt +++ /dev/null @@ -1,240 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.offset -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.layout.widthIn -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Person -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.util.CountryManager -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun ContactMessageBubble( - content: MessageContent.Contact, - msg: MessageModel, - isOutgoing: Boolean, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - letterSpacing: Float, - bubbleRadius: Float, - videoPlayerPool: VideoPlayerPool, - isGroup: Boolean = false, - onClick: () -> Unit, - onLongClick: () -> Unit, - onReplyClick: (MessageModel) -> Unit, - onReactionClick: (String) -> Unit, - toProfile: (Long) -> Unit = {}, - showReactions: Boolean = true -) { - val formattedPhone = remember(content.phoneNumber) { - CountryManager.formatPhone(content.phoneNumber) - } - val country = remember(content.phoneNumber) { - CountryManager.getCountryForPhone(content.phoneNumber) - } - - val cornerRadius = bubbleRadius.dp - val smallCorner = (bubbleRadius / 4f).coerceAtLeast(4f).dp - val tailCorner = 2.dp - - val bubbleShape = RoundedCornerShape( - topStart = if (!isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - topEnd = if (isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - bottomStart = if (!isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius, - bottomEnd = if (isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius - ) - - val backgroundColor = - if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh - val contentColor = - if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant - val timeColor = contentColor.copy(alpha = 0.7f) - - Column( - modifier = Modifier - .padding(horizontal = 8.dp, vertical = 2.dp) - .widthIn(min = 250.dp, max = 320.dp), - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = backgroundColor, - contentColor = contentColor, - tonalElevation = 2.dp, - modifier = Modifier.combinedClickable( - onClick = { - if (content.userId != 0L) { - toProfile(content.userId) - } else { - onClick() - } - }, - onLongClick = onLongClick - ) - ) { - Column(modifier = Modifier.padding(12.dp)) { - if (isGroup && !isOutgoing && !isSameSenderAbove) { - MessageSenderName(msg, toProfile = toProfile) - } - - msg.forwardInfo?.let { forward -> - ForwardContent(forward, isOutgoing, onForwardClick = toProfile) - } - msg.replyToMsg?.let { reply -> - ReplyContent( - replyToMsg = reply, - isOutgoing = isOutgoing, - onClick = { onReplyClick(reply) } - ) - } - - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.fillMaxWidth() - ) { - Box { - Avatar( - path = content.avatarPath, - name = "${content.firstName} ${content.lastName}".trim(), - size = 56.dp, - videoPlayerPool = videoPlayerPool - ) - if (country != null) { - Box( - modifier = Modifier - .align(Alignment.BottomEnd) - .offset(x = 4.dp, y = 4.dp) - .size(24.dp) - .background(MaterialTheme.colorScheme.surface, CircleShape) - .padding(2.dp) - .clip(CircleShape), - contentAlignment = Alignment.Center - ) { - Text( - text = country.flagEmoji, - fontSize = 12.sp, - lineHeight = 12.sp - ) - } - } - } - Spacer(modifier = Modifier.width(16.dp)) - Column(modifier = Modifier.weight(1f)) { - Text( - text = "${content.firstName} ${content.lastName}".trim(), - style = MaterialTheme.typography.titleMedium.copy( - fontWeight = FontWeight.Bold, - fontSize = (fontSize + 2).sp, - letterSpacing = letterSpacing.sp - ), - color = contentColor, - maxLines = 1, - overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis - ) - Text( - text = formattedPhone, - style = MaterialTheme.typography.bodyMedium, - color = contentColor.copy(alpha = 0.7f), - maxLines = 1, - overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis - ) - if (country != null) { - Text( - text = country.name, - style = MaterialTheme.typography.labelSmall, - color = contentColor.copy(alpha = 0.5f), - maxLines = 1, - overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis - ) - } - } - } - - if (content.userId != 0L) { - Spacer(modifier = Modifier.height(12.dp)) - HorizontalDivider( - modifier = Modifier.fillMaxWidth(), - thickness = 0.5.dp, - color = contentColor.copy(alpha = 0.1f) - ) - Spacer(modifier = Modifier.height(8.dp)) - Button( - onClick = { toProfile(content.userId) }, - modifier = Modifier.fillMaxWidth(), - colors = ButtonDefaults.buttonColors( - containerColor = if (isOutgoing) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.secondaryContainer, - contentColor = if (isOutgoing) MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSecondaryContainer - ), - contentPadding = PaddingValues(vertical = 8.dp), - shape = RoundedCornerShape(12.dp) - ) { - Icon( - imageVector = Icons.Default.Person, - contentDescription = null, - modifier = Modifier.size(18.dp) - ) - Spacer(modifier = Modifier.width(8.dp)) - Text( - text = "Open profile", - style = MaterialTheme.typography.labelLarge - ) - } - } - - Box( - modifier = Modifier - .align(Alignment.End) - .padding(top = 8.dp) - ) { - MessageMetadata(msg, isOutgoing, timeColor) - } - } - } - - if (showReactions) { - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(horizontal = 4.dp) - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/DocumentMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/DocumentMessageBubble.kt deleted file mode 100644 index 55709296..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/DocumentMessageBubble.kt +++ /dev/null @@ -1,593 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.InsertDriveFile -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.Download -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.AutoDownloadSuppression -import org.monogram.presentation.features.chats.currentChat.components.channels.ChannelCommentsButton - -@Composable -fun DocumentMessageBubble( - content: MessageContent.Document, - msg: MessageModel, - isOutgoing: Boolean, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - letterSpacing: Float, - autoDownloadFiles: Boolean, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - onDocumentClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit = {}, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - onClick: (Offset) -> Unit = {}, - isGroup: Boolean = false, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils -) { - val cornerRadius = 18.dp - val smallCorner = 4.dp - val tailCorner = 2.dp - - var isAutoDownloadSuppressed by remember(msg.id) { mutableStateOf(false) } - - LaunchedEffect( - content.path, - content.isDownloading, - autoDownloadFiles, - autoDownloadMobile, - autoDownloadWifi, - autoDownloadRoaming - ) { - if (!content.path.isNullOrBlank()) { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(content.fileId) - } - - val shouldDownload = if (autoDownloadFiles) { - when { - downloadUtils.isRoaming() -> autoDownloadRoaming - downloadUtils.isWifiConnected() -> autoDownloadWifi - else -> autoDownloadMobile - } - } else { - false - } - - if (shouldDownload && content.path == null && !content.isDownloading && !isAutoDownloadSuppressed && !AutoDownloadSuppression.isSuppressed( - content.fileId - ) - ) { - onDocumentClick(msg) - } - } - - val bubbleShape = RoundedCornerShape( - topStart = if (!isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - topEnd = if (isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - bottomStart = if (!isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius, - bottomEnd = if (isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius - ) - - val backgroundColor = - if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh - val contentColor = - if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant - val timeColor = contentColor.copy(alpha = 0.7f) - - val revealedSpoilers = remember { mutableStateListOf() } - var bubblePosition by remember { mutableStateOf(Offset.Zero) } - - Column( - modifier = modifier - .onGloballyPositioned { bubblePosition = it.positionInWindow() }, - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = backgroundColor, - contentColor = contentColor, - tonalElevation = 1.dp - ) { - Column( - modifier = Modifier - .padding(start = 8.dp, end = 8.dp, top = 8.dp, bottom = 6.dp) - .width(IntrinsicSize.Max) - .widthIn(min = 184.dp, max = 300.dp) - ) { - if (isGroup && !isOutgoing && !isSameSenderAbove) { - MessageSenderName(msg, toProfile = toProfile) - } - - msg.forwardInfo?.let { forward -> - Box(modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp)) { - ForwardContent(forward, isOutgoing, onForwardClick = toProfile) - } - } - msg.replyToMsg?.let { reply -> - Box(modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp)) { - ReplyContent( - replyToMsg = reply, - isOutgoing = isOutgoing, - onClick = { onReplyClick(reply) } - ) - } - } - - DocumentRow( - content = content, - msg = msg, - fontSize = fontSize, - letterSpacing = letterSpacing, - timeColor = timeColor, - onDocumentClick = { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(content.fileId) - onDocumentClick(it) - }, - onCancelDownload = { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(content.fileId) - onCancelDownload(it) - } - ) - - if (content.caption.isNotEmpty()) { - val inlineContent = rememberMessageInlineContent(content.entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = content.caption, - entities = content.entities, - isOutgoing = isOutgoing, - revealedSpoilers = revealedSpoilers - ) - - MessageText( - text = finalAnnotatedString, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = fontSize.sp, - letterSpacing = letterSpacing.sp, - lineHeight = (fontSize * 1.375f).sp - ), - modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp), - entities = content.entities, - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = { offset -> onClick(offset) }, - onLongClick = { offset -> onLongClick(offset) } - ) - } - - Box( - modifier = Modifier - .fillMaxWidth() - .padding(top = if (content.caption.isEmpty()) 0.dp else 4.dp), - contentAlignment = Alignment.CenterEnd - ) { - MessageMetadata(msg, isOutgoing, timeColor) - } - } - } - - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(horizontal = 4.dp) - ) - } -} - -@Composable -fun DocumentRow( - content: MessageContent.Document, - msg: MessageModel, - fontSize: Float, - letterSpacing: Float, - timeColor: Color, - onDocumentClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit -) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 4.dp) - ) { - Box( - modifier = Modifier - .size(48.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primary) - .clickable { - if (content.isDownloading) { - AutoDownloadSuppression.suppress(content.fileId) - onCancelDownload(content.fileId) - } else { - AutoDownloadSuppression.clear(content.fileId) - onDocumentClick(msg) - } - }, - contentAlignment = Alignment.Center - ) { - if (content.isDownloading || content.isUploading) { - CircularProgressIndicator( - progress = { if (content.isDownloading) content.downloadProgress else content.uploadProgress }, - modifier = Modifier.size(40.dp), - color = MaterialTheme.colorScheme.onPrimary, - strokeWidth = 3.dp, - trackColor = MaterialTheme.colorScheme.onPrimary.copy(alpha = 0.2f), - ) - Icon( - imageVector = Icons.Default.Close, - contentDescription = "Cancel", - tint = MaterialTheme.colorScheme.onPrimary, - modifier = Modifier.size(20.dp) - ) - } else { - val icon = - if (content.path == null) Icons.Default.Download else Icons.AutoMirrored.Filled.InsertDriveFile - Icon( - imageVector = icon, - contentDescription = "File", - tint = MaterialTheme.colorScheme.onPrimary - ) - } - } - - Spacer(modifier = Modifier.width(12.dp)) - - Column( - modifier = Modifier.weight(1f) - ) { - Text( - text = content.fileName.ifEmpty { "Document" }, - style = MaterialTheme.typography.bodyMedium.copy( - fontSize = fontSize.sp, - letterSpacing = letterSpacing.sp, - ), - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Text( - text = formatFileSize(content.size), - style = MaterialTheme.typography.labelSmall, - color = timeColor - ) - } - } -} - -@Composable -fun DocumentAlbumBubble( - messages: List, - isOutgoing: Boolean, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - letterSpacing: Float, - autoDownloadFiles: Boolean, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - onDocumentClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit, - onReactionClick: (String) -> Unit, - isGroup: Boolean = false, - toProfile: (Long) -> Unit, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils -) { - val cornerRadius = 18.dp - val smallCorner = 4.dp - val tailCorner = 2.dp - - val bubbleShape = RoundedCornerShape( - topStart = if (!isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - topEnd = if (isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - bottomStart = if (!isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius, - bottomEnd = if (isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius - ) - - val backgroundColor = - if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh - val contentColor = - if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant - val timeColor = contentColor.copy(alpha = 0.7f) - - val lastMsg = messages.last() - val revealedSpoilers = remember { mutableStateListOf() } - var bubblePosition by remember { mutableStateOf(Offset.Zero) } - - Column( - modifier = modifier.onGloballyPositioned { bubblePosition = it.positionInWindow() }, - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = backgroundColor, - contentColor = contentColor, - tonalElevation = 1.dp - ) { - Column( - modifier = Modifier - .padding(start = 8.dp, end = 8.dp, top = 8.dp, bottom = 6.dp) - .width(IntrinsicSize.Max) - .widthIn(min = 200.dp, max = 300.dp) - ) { - if (isGroup && !isOutgoing && !isSameSenderAbove) { - MessageSenderName(lastMsg, toProfile = toProfile) - } - - lastMsg.replyToMsg?.let { reply -> - Box(modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp)) { - ReplyContent( - replyToMsg = reply, - isOutgoing = isOutgoing, - onClick = { onReplyClick(reply) } - ) - } - } - - messages.forEachIndexed { index, msg -> - val content = msg.content as MessageContent.Document - - DocumentRow( - content = content, - msg = msg, - fontSize = fontSize, - letterSpacing = letterSpacing, - timeColor = timeColor, - onDocumentClick = onDocumentClick, - onCancelDownload = onCancelDownload - ) - if (index < messages.lastIndex || content.caption.isNotEmpty()) { - Spacer(modifier = Modifier.height(4.dp)) - } - } - - val captionMsg = messages.firstOrNull { (it.content as MessageContent.Document).caption.isNotEmpty() } - if (captionMsg != null) { - val content = captionMsg.content as MessageContent.Document - val inlineContent = rememberMessageInlineContent(content.entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = content.caption, - entities = content.entities, - isOutgoing = isOutgoing, - revealedSpoilers = revealedSpoilers - ) - - MessageText( - text = finalAnnotatedString, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = fontSize.sp, - letterSpacing = letterSpacing.sp, - lineHeight = (fontSize * 1.375f).sp - ), - modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp), - entities = content.entities, - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = { offset -> onLongClick(bubblePosition + offset) }, - onLongClick = { offset -> onLongClick(bubblePosition + offset) } - ) - } - - Box( - modifier = Modifier - .fillMaxWidth() - .padding(top = 2.dp), - contentAlignment = Alignment.CenterEnd - ) { - MessageMetadata(lastMsg, isOutgoing, timeColor) - } - } - } - - MessageReactionsView( - reactions = lastMsg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(horizontal = 4.dp) - ) - } -} - -@Composable -fun ChannelDocumentAlbumBubble( - messages: List, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - letterSpacing: Float, - bubbleRadius: Float, - autoDownloadFiles: Boolean, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - onDocumentClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit, - onReactionClick: (String) -> Unit, - onCommentsClick: (Long) -> Unit, - showComments: Boolean, - toProfile: (Long) -> Unit, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils -) { - val firstMsg = messages.first() - val lastMsg = messages.last() - - val cornerRadius = bubbleRadius.dp - val smallCorner = (bubbleRadius / 4f).coerceAtLeast(4f).dp - val tailCorner = 2.dp - - val bubbleShape = RoundedCornerShape( - topStart = if (isSameSenderAbove) smallCorner else cornerRadius, - topEnd = cornerRadius, - bottomStart = if (isSameSenderBelow) smallCorner else tailCorner, - bottomEnd = cornerRadius - ) - - val backgroundColor = MaterialTheme.colorScheme.surfaceContainerHigh - val contentColor = MaterialTheme.colorScheme.onSurfaceVariant - val timeColor = contentColor.copy(alpha = 0.7f) - - val revealedSpoilers = remember { mutableStateListOf() } - var bubblePosition by remember { mutableStateOf(Offset.Zero) } - - Column( - modifier = modifier.onGloballyPositioned { bubblePosition = it.positionInWindow() }, - horizontalAlignment = Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = backgroundColor, - contentColor = contentColor, - tonalElevation = 1.dp, - modifier = Modifier.fillMaxWidth() - ) { - Column( - modifier = Modifier - .padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 8.dp) - .fillMaxWidth() - ) { - lastMsg.forwardInfo?.let { forward -> - Box(modifier = Modifier.padding(bottom = 8.dp)) { - ForwardContent(forward, false, onForwardClick = toProfile) - } - } - lastMsg.replyToMsg?.let { reply -> - Box(modifier = Modifier.padding(bottom = 8.dp)) { - ReplyContent( - replyToMsg = reply, - isOutgoing = false, - onClick = { onReplyClick(reply) } - ) - } - } - - messages.forEachIndexed { index, msg -> - val content = msg.content as MessageContent.Document - DocumentRow( - content = content, - msg = msg, - fontSize = fontSize, - letterSpacing = letterSpacing, - timeColor = timeColor, - onDocumentClick = onDocumentClick, - onCancelDownload = onCancelDownload - ) - if (index < messages.lastIndex || content.caption.isNotEmpty()) { - Spacer(modifier = Modifier.height(4.dp)) - } - } - - val captionMsg = messages.firstOrNull { (it.content as MessageContent.Document).caption.isNotEmpty() } - if (captionMsg != null) { - val content = captionMsg.content as MessageContent.Document - val inlineContent = rememberMessageInlineContent(content.entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = content.caption, - entities = content.entities, - isOutgoing = false, - revealedSpoilers = revealedSpoilers - ) - - MessageText( - text = finalAnnotatedString, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = fontSize.sp, - letterSpacing = letterSpacing.sp, - lineHeight = (fontSize * 1.375f).sp - ), - modifier = Modifier.padding(vertical = 4.dp), - entities = content.entities, - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = { offset -> onLongClick(bubblePosition + offset) }, - onLongClick = { offset -> onLongClick(bubblePosition + offset) } - ) - } - - Box( - modifier = Modifier - .fillMaxWidth() - .padding(top = 2.dp), - contentAlignment = Alignment.CenterEnd - ) { - MessageMetadata(lastMsg, false, timeColor) - } - } - } - - if (showComments && firstMsg.canGetMessageThread) { - Spacer(modifier = Modifier.height(4.dp)) - ChannelCommentsButton( - replyCount = firstMsg.replyCount, - bubbleRadius = bubbleRadius, - isSameSenderBelow = isSameSenderBelow, - onClick = { onCommentsClick(firstMsg.id) }, - modifier = Modifier.fillMaxWidth() - ) - } - - MessageReactionsView( - reactions = firstMsg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(top = 2.dp) - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/ForwardContent.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/ForwardContent.kt deleted file mode 100644 index 26161a5a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/ForwardContent.kt +++ /dev/null @@ -1,93 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.Reply -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.ForwardInfo - -@Composable -fun ForwardContent( - forwardInfo: ForwardInfo, - isOutgoing: Boolean, - onForwardClick: (Long) -> Unit = {} -) { - Row( - modifier = Modifier - .padding(bottom = 4.dp) - .clip(RoundedCornerShape(4.dp)) - .background( - if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.05f) - else MaterialTheme.colorScheme.onSurface.copy(alpha = 0.03f) - ) - .clickable(enabled = forwardInfo.fromId != 0L) { onForwardClick(forwardInfo.fromId) } - .padding(4.dp) - .fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .width(2.dp) - .height(32.dp) - .background( - if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.5f) - else MaterialTheme.colorScheme.primary.copy(alpha = 0.5f), - RoundedCornerShape(2.dp) - ) - ) - - Spacer(modifier = Modifier.width(8.dp)) - - Icon( - imageVector = Icons.AutoMirrored.Rounded.Reply, - contentDescription = null, - modifier = Modifier - .size(18.dp) - .graphicsLayer(scaleX = -1f), // Flip to look like forward - tint = if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.7f) - else MaterialTheme.colorScheme.primary.copy(alpha = 0.7f) - ) - - Spacer(modifier = Modifier.width(8.dp)) - - Column(modifier = Modifier.weight(1f)) { - Text( - text = "Forwarded from", - style = MaterialTheme.typography.labelSmall.copy( - fontSize = 11.sp, - fontWeight = FontWeight.Normal - ), - color = if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.6f) - else MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f), - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - - Text( - text = forwardInfo.fromName, - style = MaterialTheme.typography.labelMedium.copy( - fontWeight = FontWeight.Bold, - fontSize = 13.sp - ), - color = if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer - else MaterialTheme.colorScheme.primary, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/GifMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/GifMessageBubble.kt deleted file mode 100644 index e6ca5ed3..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/GifMessageBubble.kt +++ /dev/null @@ -1,403 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.annotation.OptIn -import androidx.compose.animation.animateContentSize -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Download -import androidx.compose.material.icons.filled.Edit -import androidx.compose.material.icons.filled.PlayArrow -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clipToBounds -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.zIndex -import androidx.media3.common.util.UnstableApi -import coil3.compose.rememberAsyncImagePainter -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.AutoDownloadSuppression -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.chats.currentChat.components.VideoStickerPlayer -import org.monogram.presentation.features.chats.currentChat.components.VideoType - -@OptIn(UnstableApi::class) -@Composable -fun GifMessageBubble( - content: MessageContent.Gif, - msg: MessageModel, - isOutgoing: Boolean, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - letterSpacing: Float, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - autoplayGifs: Boolean, - onGifClick: (MessageModel) -> Unit = {}, - onCancelDownload: (Int) -> Unit = {}, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - showMetadata: Boolean = true, - showReactions: Boolean = true, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - isAnyViewerOpen: Boolean = false -) { - val cornerRadius = 18.dp - val smallCorner = 4.dp - val tailCorner = 2.dp - - var stablePath by remember(msg.id) { mutableStateOf(content.path) } - !stablePath.isNullOrBlank() - var isAutoDownloadSuppressed by remember(msg.id) { mutableStateOf(false) } - - LaunchedEffect(content.path) { - if (!content.path.isNullOrBlank()) { - stablePath = content.path - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(content.fileId) - } - } - - LaunchedEffect(content.path, content.isDownloading, autoDownloadMobile, autoDownloadWifi, autoDownloadRoaming) { - if (content.path.isNullOrBlank() && !content.isDownloading && !isAutoDownloadSuppressed && !AutoDownloadSuppression.isSuppressed( - content.fileId - ) - ) { - val shouldDownload = when { - downloadUtils.isWifiConnected() -> autoDownloadWifi - downloadUtils.isRoaming() -> autoDownloadRoaming - else -> autoDownloadMobile - } - if (shouldDownload) { - onGifClick(msg) - } - } - } - - val topStart = if (!isOutgoing && isSameSenderAbove) smallCorner else cornerRadius - val topEnd = if (isOutgoing && isSameSenderAbove) smallCorner else cornerRadius - val bottomStart = if (!isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius - val bottomEnd = if (isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius - - val bubbleShape = RoundedCornerShape( - topStart = topStart, - topEnd = topEnd, - bottomEnd = bottomEnd, - bottomStart = bottomStart - ) - - var gifPosition by remember { mutableStateOf(Offset.Zero) } - val revealedSpoilers = remember { mutableStateListOf() } - var isMediaSpoilerRevealed by remember { mutableStateOf(!content.hasSpoiler) } - - Column( - modifier = modifier.width(IntrinsicSize.Max), - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh, - contentColor = if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant, - ) { - Column(modifier = Modifier - .widthIn(min = 160.dp, max = 320.dp) - .animateContentSize()) { - msg.forwardInfo?.let { forward -> - Box( - modifier = Modifier - .fillMaxWidth() - .background(if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(horizontal = 12.dp, vertical = 4.dp) - .zIndex(1f) - ) { - ForwardContent(forward, isOutgoing, onForwardClick = toProfile) - } - } - msg.replyToMsg?.let { reply -> - Box( - modifier = Modifier - .fillMaxWidth() - .background(if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(horizontal = 4.dp, vertical = 4.dp) - .zIndex(1f) - ) { - ReplyContent( - replyToMsg = reply, - isOutgoing = isOutgoing, - onClick = { onReplyClick(reply) } - ) - } - } - - Box( - modifier = Modifier - .fillMaxWidth() - .heightIn(min = 160.dp, max = 360.dp) - .aspectRatio( - if (content.width > 0 && content.height > 0) - (content.width.toFloat() / content.height.toFloat()).coerceIn(0.5f, 2f) - else 1f - ) - .clipToBounds() - .onGloballyPositioned { gifPosition = it.positionInWindow() } - .pointerInput(Unit) { - detectTapGestures( - onTap = { - if (!isMediaSpoilerRevealed) { - isMediaSpoilerRevealed = true - } else if (content.isDownloading) { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(content.fileId) - onCancelDownload(content.fileId) - } else { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(content.fileId) - onGifClick(msg) - } - }, - onLongPress = { offset -> onLongClick(gifPosition + offset) } - ) - } - ) { - if (!stablePath.isNullOrBlank()) { - if (autoplayGifs) { - VideoStickerPlayer( - path = stablePath ?: "", - type = VideoType.Gif, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Fit, - animate = !isAnyViewerOpen, - videoPlayerPool = videoPlayerPool, - thumbnailData = content.minithumbnail - ) - } else { - Image( - painter = rememberAsyncImagePainter(stablePath), - contentDescription = content.caption, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Fit - ) - - Box( - modifier = Modifier - .align(Alignment.Center) - .size(48.dp) - .background(Color.Black.copy(alpha = 0.45f), CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Default.PlayArrow, - contentDescription = "Play", - tint = Color.White, - modifier = Modifier.size(32.dp) - ) - } - } - - Box( - modifier = Modifier - .align(Alignment.TopStart) - .padding(8.dp) - .background(Color.Black.copy(alpha = 0.45f), RoundedCornerShape(6.dp)) - .padding(horizontal = 6.dp, vertical = 2.dp) - ) { - Text( - text = "GIF", - style = MaterialTheme.typography.labelSmall, - color = Color.White - ) - } - } else { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - MediaLoadingBackground( - previewData = content.minithumbnail, - contentScale = ContentScale.Fit - ) - - MediaLoadingAction( - isDownloading = content.isDownloading, - progress = content.downloadProgress, - idleIcon = Icons.Default.Download, - idleContentDescription = "Download", - onCancelClick = { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(content.fileId) - onCancelDownload(content.fileId) - }, - onIdleClick = { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(content.fileId) - onGifClick(msg) - } - ) - } - } - - if (content.isUploading) { - Box( - modifier = Modifier - .matchParentSize() - .background(Color.Black.copy(alpha = 0.5f)), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator( - progress = { content.uploadProgress }, - color = Color.White, - trackColor = Color.White.copy(alpha = 0.3f), - ) - } - } - - SpoilerWrapper(isRevealed = isMediaSpoilerRevealed) { - Box(modifier = Modifier.fillMaxSize()) - } - - if (content.caption.isEmpty() && (!content.path.isNullOrBlank() || content.isUploading || content.minithumbnail != null) && showMetadata) { - Box( - modifier = Modifier - .align(Alignment.BottomEnd) - .padding(6.dp) - .background(Color.Black.copy(alpha = 0.45f), RoundedCornerShape(10.dp)) - .padding(horizontal = 6.dp, vertical = 2.dp) - ) { - Row(verticalAlignment = Alignment.CenterVertically) { - if (msg.editDate > 0) { - Icon( - imageVector = Icons.Default.Edit, - contentDescription = "Edited", - modifier = Modifier.size(12.dp), - tint = Color.White - ) - Spacer(modifier = Modifier.width(4.dp)) - } - Text( - text = formatTime(msg.date), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 10.sp), - color = Color.White - ) - if (isOutgoing) { - Spacer(modifier = Modifier.width(4.dp)) - MessageSendingStatusIcon( - sendingState = msg.sendingState, - isRead = msg.isRead, - baseColor = Color.White, - size = 12.dp, - usePrimaryForRead = false - ) - } - } - } - } - } - - if (content.caption.isNotEmpty()) { - val timeColor = - if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer.copy(0.7f) else MaterialTheme.colorScheme.onSurfaceVariant.copy( - 0.7f - ) - Column( - modifier = Modifier - .fillMaxWidth() - .background(if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 12.dp) - .zIndex(1f) - ) { - val inlineContent = rememberMessageInlineContent(content.entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = content.caption, - entities = content.entities, - isOutgoing = isOutgoing, - revealedSpoilers = revealedSpoilers - ) - - MessageText( - text = finalAnnotatedString, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = fontSize.sp, - letterSpacing = letterSpacing.sp, - lineHeight = (fontSize * 1.375f).sp - ), - modifier = Modifier.padding(bottom = 2.dp), - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = { offset -> onLongClick(gifPosition + offset) }, - onLongClick = { offset -> onLongClick(gifPosition + offset) } - ) - if (showMetadata) { - Row( - modifier = Modifier.align(Alignment.End), - verticalAlignment = Alignment.CenterVertically - ) { - if (msg.editDate > 0) { - Icon( - imageVector = Icons.Default.Edit, - contentDescription = "Edited", - modifier = Modifier.size(14.dp), - tint = timeColor - ) - Spacer(modifier = Modifier.width(4.dp)) - } - Text( - text = formatTime(msg.date), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 11.sp), - color = timeColor - ) - if (isOutgoing) { - Spacer(modifier = Modifier.width(4.dp)) - MessageSendingStatusIcon( - sendingState = msg.sendingState, - isRead = msg.isRead, - baseColor = timeColor, - size = 14.dp - ) - } - } - } - } - } - } - } - - if (showReactions) { - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(horizontal = 4.dp) - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/LinkPreview.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/LinkPreview.kt deleted file mode 100644 index e8ab1b63..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/LinkPreview.kt +++ /dev/null @@ -1,317 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.Notes -import androidx.compose.material.icons.filled.PlayArrow -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage -import coil3.request.ImageRequest -import coil3.request.crossfade -import org.monogram.domain.models.WebPage -import org.monogram.presentation.features.viewers.extractYouTubeId - -@Composable -fun LinkPreview( - webPage: WebPage, - isOutgoing: Boolean, - modifier: Modifier = Modifier, - onInstantViewClick: ((String) -> Unit)? = null, - onYouTubeClick: ((String) -> Unit)? = null -) { - val hasSiteName = !webPage.siteName.isNullOrEmpty() - val hasTitle = !webPage.title.isNullOrEmpty() - val hasDescription = !webPage.description.isNullOrEmpty() - - val isVideo = when (webPage.type) { - is WebPage.LinkPreviewType.Video, - is WebPage.LinkPreviewType.ExternalVideo, - is WebPage.LinkPreviewType.EmbeddedVideo, - is WebPage.LinkPreviewType.Animation, - is WebPage.LinkPreviewType.EmbeddedAnimation -> true - else -> webPage.video != null || - webPage.siteName?.contains("YouTube", ignoreCase = true) == true || - webPage.url?.contains("youtu", ignoreCase = true) == true - } - - val hasPhoto = webPage.photo != null - val hasMedia = hasPhoto || isVideo - val isInstantView = webPage.type == WebPage.LinkPreviewType.InstantView || webPage.instantViewVersion > 0 - - if (!hasSiteName && !hasTitle && !hasDescription && !hasMedia) return - - val linkHandler = LocalLinkHandler.current - val colorScheme = MaterialTheme.colorScheme - - val borderColor = if (isOutgoing) { - colorScheme.onPrimaryContainer.copy(alpha = 0.2f) - } else { - colorScheme.primary.copy(alpha = 0.4f) - } - - val isSmallMedia = hasPhoto && !isVideo && (hasSiteName || hasTitle || hasDescription) - val isYouTube = webPage.siteName?.contains("YouTube", ignoreCase = true) == true || - webPage.url?.let { extractYouTubeId(it) != null } == true - - Column( - modifier = modifier - .padding(vertical = 4.dp) - .widthIn(max = 300.dp) - ) { - Column( - modifier = Modifier - .clip(RoundedCornerShape(8.dp)) - .background( - if (isOutgoing) colorScheme.onPrimaryContainer.copy(alpha = 0.05f) - else colorScheme.onSurface.copy(alpha = 0.05f) - ) - .clickable { - val url = webPage.url ?: return@clickable - when { - isYouTube && onYouTubeClick != null -> onYouTubeClick(url) - isInstantView && onInstantViewClick != null -> onInstantViewClick(url) - else -> linkHandler(url) - } - } - ) { - Row(modifier = Modifier.height(IntrinsicSize.Min)) { - Box( - modifier = Modifier - .width(3.dp) - .fillMaxHeight() - .background(borderColor) - ) - Column(modifier = Modifier.padding(8.dp)) { - if (isSmallMedia) { - Row { - Column(modifier = Modifier.weight(1f)) { - LinkPreviewTextContent(webPage, isOutgoing, hasSiteName, hasTitle, hasDescription) - } - Spacer(modifier = Modifier.width(8.dp)) - LinkPreviewSmallImage(webPage) - } - } else { - LinkPreviewTextContent(webPage, isOutgoing, hasSiteName, hasTitle, hasDescription) - - if (hasMedia) { - Spacer(modifier = Modifier.height(8.dp)) - LinkPreviewLargeMedia( - webPage = webPage, - isVideo = isVideo, - isYouTube = isYouTube, - onPlayYouTube = { - if (onYouTubeClick != null && webPage.url != null) { - onYouTubeClick(webPage.url!!) - } - } - ) - } - } - } - } - } - - if (isInstantView && onInstantViewClick != null && webPage.url != null) { - Spacer(modifier = Modifier.height(4.dp)) - Button( - onClick = { onInstantViewClick(webPage.url!!) }, - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(8.dp), - colors = ButtonDefaults.buttonColors( - containerColor = if (isOutgoing) colorScheme.onPrimaryContainer.copy(alpha = 0.1f) - else colorScheme.primary.copy(alpha = 0.1f), - contentColor = if (isOutgoing) colorScheme.onPrimaryContainer else colorScheme.primary - ), - contentPadding = PaddingValues(vertical = 8.dp) - ) { - Icon( - imageVector = Icons.AutoMirrored.Rounded.Notes, - contentDescription = null, - modifier = Modifier.size(18.dp) - ) - Spacer(modifier = Modifier.width(8.dp)) - Text( - text = "INSTANT VIEW", - style = MaterialTheme.typography.labelLarge, - fontWeight = FontWeight.Bold - ) - } - } - } -} - -@Composable -private fun LinkPreviewTextContent( - webPage: WebPage, - isOutgoing: Boolean, - hasSiteName: Boolean, - hasTitle: Boolean, - hasDescription: Boolean -) { - val colorScheme = MaterialTheme.colorScheme - - if (hasSiteName || !webPage.author.isNullOrEmpty()) { - val siteText = buildString { - if (hasSiteName) append(webPage.siteName) - if (!webPage.author.isNullOrEmpty() && webPage.author != webPage.siteName) { - if (isNotEmpty()) append(" • ") - append(webPage.author) - } - } - Text( - text = siteText, - style = MaterialTheme.typography.labelMedium, - color = if (isOutgoing) colorScheme.onPrimaryContainer else colorScheme.primary, - fontWeight = FontWeight.Bold, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - - if (hasTitle) { - Text( - text = webPage.title!!, - style = MaterialTheme.typography.bodyMedium, - fontWeight = FontWeight.Bold, - maxLines = 2, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.padding(top = if (hasSiteName) 2.dp else 0.dp) - ) - } - - if (hasDescription) { - Text( - text = webPage.description!!, - style = MaterialTheme.typography.bodySmall, - maxLines = 3, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.padding(top = if (hasSiteName || hasTitle) 2.dp else 0.dp) - ) - } -} - -@Composable -private fun LinkPreviewSmallImage(webPage: WebPage) { - val photo = webPage.photo - val context = LocalContext.current - - Box( - modifier = Modifier - .size(54.dp) - .clip(RoundedCornerShape(4.dp)) - .background(MaterialTheme.colorScheme.surfaceVariant) - ) { - AsyncImage( - model = ImageRequest.Builder(context) - .data(photo?.path ?: photo?.minithumbnail) - .crossfade(true) - .build(), - contentDescription = null, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Crop - ) - } -} - -@Composable -private fun LinkPreviewLargeMedia( - webPage: WebPage, - isVideo: Boolean, - isYouTube: Boolean, - onPlayYouTube: () -> Unit -) { - val context = LocalContext.current - val linkHandler = LocalLinkHandler.current - val photo = webPage.photo - val video = webPage.video - - val aspectRatio = remember(photo, video) { - val w = video?.width ?: photo?.width ?: 0 - val h = video?.height ?: photo?.height ?: 0 - if (w > 0 && h > 0) w.toFloat() / h.toFloat() else 1.77f - } - - val videoId = remember(webPage.url) { extractYouTubeId(webPage.url) } - - Box( - modifier = Modifier - .fillMaxWidth() - .aspectRatio(aspectRatio) - .clip(RoundedCornerShape(4.dp)) - .background(MaterialTheme.colorScheme.surfaceVariant) - ) { - val modelData = remember(photo, videoId, isYouTube) { - if (isYouTube && videoId != null) { - "https://img.youtube.com/vi/$videoId/maxresdefault.jpg" - } else { - photo?.path ?: photo?.minithumbnail ?: video?.path - } - } - - AsyncImage( - model = ImageRequest.Builder(context) - .data(modelData) - .crossfade(true) - .build(), - contentDescription = null, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Crop - ) - - if (isVideo) { - Box( - modifier = Modifier - .align(Alignment.Center) - .size(48.dp) - .background(Color.Black.copy(alpha = 0.5f), CircleShape) - .clickable { - if (isYouTube) { - onPlayYouTube() - } else { - webPage.url?.let { linkHandler(it) } - } - }, - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Default.PlayArrow, - contentDescription = "Play", - tint = Color.White, - modifier = Modifier.size(32.dp) - ) - } - - if (webPage.duration > 0) { - Box( - modifier = Modifier - .align(Alignment.BottomEnd) - .padding(6.dp) - .background(Color.Black.copy(alpha = 0.7f), RoundedCornerShape(4.dp)) - .padding(horizontal = 6.dp, vertical = 2.dp) - ) { - Text( - text = formatDuration(webPage.duration), - style = MaterialTheme.typography.labelSmall, - color = Color.White, - fontWeight = FontWeight.Medium - ) - } - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/LocationMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/LocationMessageBubble.kt deleted file mode 100644 index 497c8115..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/LocationMessageBubble.kt +++ /dev/null @@ -1,418 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.LocationOn -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.maplibre.compose.MapView -import com.maplibre.compose.camera.CameraState.Centered -import com.maplibre.compose.camera.MapViewCamera -import com.maplibre.compose.rememberSaveableMapViewCamera -import com.maplibre.compose.symbols.Symbol -import org.maplibre.android.geometry.LatLng -import org.maplibre.android.maps.MapLibreMapOptions -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.R -import org.monogram.presentation.features.profile.ProfileComponent -import org.monogram.presentation.features.profile.components.LocationViewer - -private const val MAP_STYLE = "https://tiles.openfreemap.org/styles/bright" - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun LocationMessageBubble( - content: MessageContent.Location, - msg: MessageModel, - isOutgoing: Boolean, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - letterSpacing: Float, - bubbleRadius: Float, - isGroup: Boolean = false, - onClick: () -> Unit, - onLongClick: () -> Unit, - onReplyClick: (MessageModel) -> Unit, - onReactionClick: (String) -> Unit, - toProfile: (Long) -> Unit = {}, - showReactions: Boolean = true -) { - val cornerRadius = bubbleRadius.dp - val smallCorner = (bubbleRadius / 4f).coerceAtLeast(4f).dp - val tailCorner = 2.dp - var showLocationViewer by remember { mutableStateOf(false) } - val context = LocalContext.current - - val bubbleShape = RoundedCornerShape( - topStart = if (!isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - topEnd = if (isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - bottomStart = if (!isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius, - bottomEnd = if (isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius - ) - - val backgroundColor = - if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh - val contentColor = - if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant - val timeColor = contentColor.copy(alpha = 0.7f) - val camera = rememberSaveableMapViewCamera( - MapViewCamera( - Centered( - content.latitude, - content.longitude, - ), - ) - ) - val mapOptions = remember { - MapLibreMapOptions.createFromAttributes(context, null).apply { - scrollGesturesEnabled(false) - zoomGesturesEnabled(false) - tiltGesturesEnabled(false) - rotateGesturesEnabled(false) - doubleTapGesturesEnabled(false) - textureMode(true) - } - } - - Column( - modifier = Modifier - .padding(horizontal = 8.dp, vertical = 2.dp) - .widthIn(min = 280.dp, max = 360.dp), - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = backgroundColor, - contentColor = contentColor, - tonalElevation = 1.dp, - modifier = Modifier.combinedClickable( - onClick = onClick, - onLongClick = onLongClick - ) - ) { - Column(modifier = Modifier.padding(8.dp)) { - if (isGroup && !isOutgoing && !isSameSenderAbove) { - MessageSenderName(msg, toProfile = toProfile) - } - - msg.forwardInfo?.let { forward -> - ForwardContent(forward, isOutgoing, onForwardClick = toProfile) - } - msg.replyToMsg?.let { reply -> - ReplyContent( - replyToMsg = reply, - isOutgoing = isOutgoing, - onClick = { onReplyClick(reply) } - ) - } - - Box( - modifier = Modifier - .fillMaxWidth() - .height(180.dp) - .clip(RoundedCornerShape(bubbleRadius.dp / 2f)) - ) { - MapView( - modifier = Modifier - .fillMaxWidth(), - camera = camera, - styleUrl = MAP_STYLE, - mapOptions = mapOptions - ) { - Symbol( - center = LatLng(content.latitude, content.longitude), - imageId = R.drawable.ic_map_marker, - size = 2f - ) - } - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.Transparent) - .clickable { showLocationViewer = true } - ) - } - - Spacer(modifier = Modifier.height(8.dp)) - - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxWidth() - .clickable { showLocationViewer = true } - .padding(vertical = 4.dp) - ) { - Box( - modifier = Modifier - .size(36.dp) - .background(Color(0xFFEA4335), RoundedCornerShape(18.dp)), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.LocationOn, - contentDescription = null, - tint = Color.White, - modifier = Modifier.size(20.dp) - ) - } - Spacer(modifier = Modifier.width(10.dp)) - Column { - Text( - text = "Location", - style = MaterialTheme.typography.bodyMedium.copy( - fontWeight = FontWeight.Bold, - fontSize = fontSize.sp, - letterSpacing = letterSpacing.sp - ), - color = contentColor - ) - Text( - text = String.format("%.4f, %.4f", content.latitude, content.longitude), - style = MaterialTheme.typography.labelSmall, - color = contentColor.copy(alpha = 0.7f) - ) - } - } - - Box(modifier = Modifier - .align(Alignment.End) - .padding(top = 4.dp)) { - MessageMetadata(msg, isOutgoing, timeColor) - } - } - } - - if (showReactions) { - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(horizontal = 4.dp) - ) - } - } - - if (showLocationViewer) { - LocationViewer( - location = ProfileComponent.LocationData( - latitude = content.latitude, - longitude = content.longitude, - address = "Location" - ), - onDismiss = { showLocationViewer = false } - ) - } -} - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun VenueMessageBubble( - content: MessageContent.Venue, - msg: MessageModel, - isOutgoing: Boolean, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - letterSpacing: Float, - bubbleRadius: Float, - isGroup: Boolean = false, - onClick: () -> Unit, - onLongClick: () -> Unit, - onReplyClick: (MessageModel) -> Unit, - onReactionClick: (String) -> Unit, - toProfile: (Long) -> Unit = {}, - showReactions: Boolean = true -) { - val cornerRadius = bubbleRadius.dp - val smallCorner = (bubbleRadius / 4f).coerceAtLeast(4f).dp - val tailCorner = 2.dp - var showLocationViewer by remember { mutableStateOf(false) } - val context = LocalContext.current - - val bubbleShape = RoundedCornerShape( - topStart = if (!isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - topEnd = if (isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - bottomStart = if (!isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius, - bottomEnd = if (isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius - ) - - val backgroundColor = - if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh - val contentColor = - if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant - val timeColor = contentColor.copy(alpha = 0.7f) - val camera = rememberSaveableMapViewCamera( - MapViewCamera( - Centered( - content.latitude, - content.longitude, - ), - ) - ) - val mapOptions = remember { - MapLibreMapOptions.createFromAttributes(context, null).apply { - scrollGesturesEnabled(true) - zoomGesturesEnabled(true) - tiltGesturesEnabled(false) - rotateGesturesEnabled(false) - doubleTapGesturesEnabled(true) - textureMode(true) - } - } - Column( - modifier = Modifier - .padding(horizontal = 8.dp, vertical = 2.dp) - .widthIn(min = 280.dp, max = 360.dp), - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = backgroundColor, - contentColor = contentColor, - tonalElevation = 1.dp, - modifier = Modifier.combinedClickable( - onClick = onClick, - onLongClick = onLongClick - ) - ) { - Column(modifier = Modifier.padding(8.dp)) { - if (isGroup && !isOutgoing && !isSameSenderAbove) { - MessageSenderName(msg, toProfile = toProfile) - } - - msg.forwardInfo?.let { forward -> - ForwardContent(forward, isOutgoing, onForwardClick = toProfile) - } - msg.replyToMsg?.let { reply -> - ReplyContent( - replyToMsg = reply, - isOutgoing = isOutgoing, - onClick = { onReplyClick(reply) } - ) - } - - Box( - modifier = Modifier - .fillMaxWidth() - .height(180.dp) - .clip(RoundedCornerShape(bubbleRadius.dp / 2f)) - ) { - MapView( - modifier = Modifier - .fillMaxWidth(), - camera = camera, - styleUrl = MAP_STYLE, - mapOptions = mapOptions - ) { - Symbol( - center = LatLng(content.latitude, content.longitude), - imageId = R.drawable.ic_map_marker, - size = 2f - ) - } - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.Transparent) - .clickable { showLocationViewer = true } - ) - } - - Spacer(modifier = Modifier.height(8.dp)) - - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxWidth() - .clickable { showLocationViewer = true } - .padding(vertical = 4.dp) - ) { - Box( - modifier = Modifier - .size(36.dp) - .background(Color(0xFF4285F4), RoundedCornerShape(18.dp)), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.LocationOn, - contentDescription = null, - tint = Color.White, - modifier = Modifier.size(20.dp) - ) - } - Spacer(modifier = Modifier.width(10.dp)) - Column { - Text( - text = content.title, - style = MaterialTheme.typography.bodyMedium.copy( - fontWeight = FontWeight.Bold, - fontSize = fontSize.sp, - letterSpacing = letterSpacing.sp - ), - color = contentColor, - maxLines = 1, - overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis - ) - Text( - text = content.address, - style = MaterialTheme.typography.labelSmall, - color = contentColor.copy(alpha = 0.7f), - maxLines = 1, - overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis - ) - } - } - - Box(modifier = Modifier - .align(Alignment.End) - .padding(top = 4.dp)) { - MessageMetadata(msg, isOutgoing, timeColor) - } - } - } - - if (showReactions) { - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(horizontal = 4.dp) - ) - } - } - - if (showLocationViewer) { - LocationViewer( - location = ProfileComponent.LocationData( - latitude = content.latitude, - longitude = content.longitude, - address = content.address - ), - onDismiss = { showLocationViewer = false } - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MediaLoadingComponents.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MediaLoadingComponents.kt deleted file mode 100644 index 81aa4afa..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MediaLoadingComponents.kt +++ /dev/null @@ -1,129 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.animation.core.* -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Close -import androidx.compose.material3.CircularProgressIndicator -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.blur -import androidx.compose.ui.draw.drawBehind -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import coil3.compose.rememberAsyncImagePainter - -@Composable -fun MediaLoadingBackground( - previewData: Any?, - contentScale: ContentScale, - modifier: Modifier = Modifier, - previewBlur: Dp = 10.dp -) { - val pulse = rememberInfiniteTransition(label = "MediaLoadingPulse") - val pulseAlpha = pulse.animateFloat( - initialValue = 0.06f, - targetValue = 0.16f, - animationSpec = infiniteRepeatable( - animation = tween(durationMillis = 900, easing = LinearEasing), - repeatMode = RepeatMode.Reverse - ), - label = "MediaLoadingPulseAlpha" - ) - - Box( - modifier = modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.surfaceVariant), - contentAlignment = Alignment.Center - ) { - if (previewData != null) { - Image( - painter = rememberAsyncImagePainter(previewData), - contentDescription = null, - modifier = Modifier - .fillMaxSize() - .blur(previewBlur), - contentScale = contentScale - ) - } - - Box( - modifier = Modifier - .fillMaxSize() - .drawBehind { - drawRect(Color.Black.copy(alpha = pulseAlpha.value)) - } - ) - } -} - -@Composable -fun MediaLoadingAction( - isDownloading: Boolean, - progress: Float, - idleIcon: ImageVector, - idleContentDescription: String, - modifier: Modifier = Modifier, - showCancelOnDownload: Boolean = true, - onCancelClick: (() -> Unit)? = null, - onIdleClick: (() -> Unit)? = null -) { - Box( - modifier = modifier - .size(48.dp) - .background(Color.Black.copy(alpha = 0.45f), CircleShape), - contentAlignment = Alignment.Center - ) { - if (isDownloading) { - if (progress > 0f && progress < 1f) { - CircularProgressIndicator( - progress = { progress }, - modifier = Modifier.size(36.dp), - color = Color.White, - trackColor = Color.White.copy(alpha = 0.25f), - strokeWidth = 2.5.dp - ) - } else { - CircularProgressIndicator( - modifier = Modifier.size(36.dp), - color = Color.White, - trackColor = Color.White.copy(alpha = 0.25f), - strokeWidth = 2.5.dp - ) - } - - if (showCancelOnDownload) { - Icon( - imageVector = Icons.Default.Close, - contentDescription = "Cancel", - modifier = Modifier - .size(18.dp) - .clickable(enabled = onCancelClick != null) { onCancelClick?.invoke() }, - tint = Color.White - ) - } - } else { - Icon( - imageVector = idleIcon, - contentDescription = idleContentDescription, - modifier = Modifier - .size(28.dp) - .clickable(enabled = onIdleClick != null) { onIdleClick?.invoke() }, - tint = Color.White - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageReactionsView.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageReactionsView.kt deleted file mode 100644 index 3fe05edc..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageReactionsView.kt +++ /dev/null @@ -1,333 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.animation.* -import androidx.compose.animation.core.* -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.DropdownMenu -import androidx.compose.material3.DropdownMenuItem -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import kotlinx.coroutines.delay -import org.koin.compose.koinInject -import org.monogram.domain.models.MessageReactionModel -import org.monogram.domain.repository.StickerRepository -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.core.util.coRunCatching -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.stickers.ui.view.StickerImage - -@OptIn(ExperimentalLayoutApi::class) -@Composable -fun MessageReactionsView( - reactions: List, - onReactionClick: (String) -> Unit, - modifier: Modifier = Modifier, - stickerRepository: StickerRepository = koinInject(), - appPreferences: AppPreferences = koinInject(), - videoPlayerPool: VideoPlayerPool = koinInject() -) { - val context = LocalContext.current - val emojiStyle by appPreferences.emojiStyle.collectAsState() - val emojiFontFamily = remember(context, emojiStyle) { getEmojiFontFamily(context, emojiStyle) } - val customEmojiStickerSets by stickerRepository.customEmojiStickerSets.collectAsState() - - LaunchedEffect(Unit) { - coRunCatching { stickerRepository.loadCustomEmojiStickerSets() } - } - - val customEmojiFileIdsById = remember(customEmojiStickerSets) { - buildMap { - customEmojiStickerSets.forEach { set -> - set.stickers.forEach { sticker -> - val customEmojiId = sticker.customEmojiId - if (customEmojiId != null) { - put(customEmojiId, sticker.id) - } - } - } - } - } - - AnimatedVisibility( - visible = reactions.isNotEmpty(), - enter = fadeIn(animationSpec = tween(durationMillis = 260, easing = LinearOutSlowInEasing)), - exit = fadeOut(animationSpec = tween(durationMillis = 140)), - modifier = modifier - ) { - FlowRow( - modifier = Modifier.padding(top = 6.dp), - horizontalArrangement = Arrangement.spacedBy(6.dp), - verticalArrangement = Arrangement.spacedBy(6.dp) - ) { - reactions.forEachIndexed { index, reaction -> - key(reaction.emoji ?: reaction.customEmojiId) { - var isVisible by remember { mutableStateOf(false) } - - LaunchedEffect(Unit) { - delay(index * 35L) - isVisible = true - } - - AnimatedVisibility( - visible = isVisible, - enter = scaleIn( - initialScale = 0.88f, - animationSpec = tween( - durationMillis = 280, - easing = FastOutSlowInEasing - ) - ) + - fadeIn(animationSpec = tween(durationMillis = 220)), - exit = scaleOut( - targetScale = 0.92f, - animationSpec = tween(durationMillis = 140) - ) + - fadeOut(animationSpec = tween(durationMillis = 120)) - ) { - MessageReactionItem( - reaction = reaction, - onReactionClick = onReactionClick, - emojiFontFamily = emojiFontFamily, - stickerRepository = stickerRepository, - customEmojiFileIdsById = customEmojiFileIdsById, - videoPlayerPool = videoPlayerPool - ) - } - } - } - } - } -} - -@OptIn(ExperimentalFoundationApi::class) -@Composable -private fun MessageReactionItem( - reaction: MessageReactionModel, - onReactionClick: (String) -> Unit, - emojiFontFamily: FontFamily, - stickerRepository: StickerRepository, - customEmojiFileIdsById: Map, - videoPlayerPool: VideoPlayerPool -) { - val customEmojiId = reaction.customEmojiId - val emoji = reaction.emoji - - if (customEmojiId == null && emoji == null) return - - val isChosen = reaction.isChosen - - val backgroundColor by animateColorAsState( - targetValue = if (isChosen) { - MaterialTheme.colorScheme.primaryContainer - } else { - MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.6f) - }, - animationSpec = tween(durationMillis = 320, easing = FastOutSlowInEasing), - label = "reactionBackground" - ) - - val contentColor by animateColorAsState( - targetValue = if (isChosen) { - MaterialTheme.colorScheme.onPrimaryContainer - } else { - MaterialTheme.colorScheme.onSurfaceVariant - }, - animationSpec = tween(durationMillis = 280, easing = FastOutSlowInEasing), - label = "reactionContent" - ) - - val scale by animateFloatAsState( - targetValue = if (isChosen) 1.05f else 1f, - animationSpec = spring(dampingRatio = Spring.DampingRatioMediumBouncy, stiffness = Spring.StiffnessLow), - label = "reactionScale" - ) - - val alpha by animateFloatAsState( - targetValue = if (isChosen) 1f else 0.96f, - animationSpec = tween(durationMillis = 220, easing = FastOutSlowInEasing), - label = "reactionAlpha" - ) - - val customEmojiFileId = customEmojiId?.let(customEmojiFileIdsById::get) - val customEmojiPath by if (customEmojiFileId != null && reaction.customEmojiPath == null) { - stickerRepository.getStickerFile(customEmojiFileId).collectAsState(initial = null) - } else { - remember { mutableStateOf(reaction.customEmojiPath) } - } - - var showDropdown by remember { mutableStateOf(false) } - val linkHandler = LocalLinkHandler.current - - Box( - modifier = Modifier.graphicsLayer( - scaleX = scale, - scaleY = scale, - alpha = alpha - ) - ) { - Row( - modifier = Modifier - .clip(CircleShape) - .background(backgroundColor) - .padding(horizontal = 10.dp, vertical = 6.dp) - .animateContentSize( - animationSpec = spring( - dampingRatio = Spring.DampingRatioNoBouncy, - stiffness = Spring.StiffnessMediumLow - ) - ), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(6.dp) - ) { - if (customEmojiId != null) { - StickerImage( - path = customEmojiPath, - modifier = Modifier.size(22.dp) - ) - } else if (emoji != null) { - Text( - text = emoji, - fontSize = 18.sp, - fontFamily = emojiFontFamily - ) - } - - AnimatedVisibility( - visible = reaction.recentSenders.isNotEmpty() && reaction.count <= 3, - enter = fadeIn(animationSpec = tween(durationMillis = 220)) + - expandHorizontally( - animationSpec = spring( - dampingRatio = Spring.DampingRatioNoBouncy, - stiffness = Spring.StiffnessMediumLow - ), - expandFrom = Alignment.Start - ), - exit = fadeOut(animationSpec = tween(durationMillis = 120)) + - shrinkHorizontally(animationSpec = tween(durationMillis = 140), shrinkTowards = Alignment.Start) - ) { - Row( - horizontalArrangement = Arrangement.spacedBy((-8).dp), - verticalAlignment = Alignment.CenterVertically - ) { - reaction.recentSenders.take(3).forEach { sender -> - Avatar( - path = sender.avatar, - name = sender.name, - size = 22.dp, - videoPlayerPool = videoPlayerPool, - modifier = Modifier - .background(backgroundColor, CircleShape) - .padding(1.dp) - ) - } - } - } - - if (reaction.count > 3 || reaction.recentSenders.isEmpty()) { - AnimatedContent( - targetState = reaction.count, - transitionSpec = { - if (targetState > initialState) { - (slideInVertically( - animationSpec = tween(durationMillis = 220, easing = FastOutSlowInEasing), - initialOffsetY = { height -> height / 2 } - ) + fadeIn(animationSpec = tween(durationMillis = 180))).togetherWith( - slideOutVertically( - animationSpec = tween(durationMillis = 160), - targetOffsetY = { height -> -height / 2 } - ) + fadeOut(animationSpec = tween(durationMillis = 120)) - ) - } else { - (slideInVertically( - animationSpec = tween(durationMillis = 220, easing = FastOutSlowInEasing), - initialOffsetY = { height -> -height / 2 } - ) + fadeIn(animationSpec = tween(durationMillis = 180))).togetherWith( - slideOutVertically( - animationSpec = tween(durationMillis = 160), - targetOffsetY = { height -> height / 2 } - ) + fadeOut(animationSpec = tween(durationMillis = 120)) - ) - }.using( - SizeTransform(clip = false) - ) - }, - label = "reactionCount" - ) { count -> - Text( - text = count.toString(), - style = MaterialTheme.typography.labelMedium, - fontWeight = FontWeight.Bold, - color = contentColor - ) - } - } - } - - Box( - modifier = Modifier - .matchParentSize() - .clip(CircleShape) - .combinedClickable( - onClick = { - val reactionValue = emoji ?: customEmojiId?.toString() - if (reactionValue != null) { - onReactionClick(reactionValue) - } - }, - onLongClick = { - if (reaction.recentSenders.isNotEmpty()) { - showDropdown = true - } - } - ) - ) - - DropdownMenu( - expanded = showDropdown, - onDismissRequest = { showDropdown = false }, - shape = RoundedCornerShape(16.dp) - ) { - reaction.recentSenders.forEach { sender -> - DropdownMenuItem( - text = { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - Avatar( - path = sender.avatar, - name = sender.name, - size = 28.dp, - videoPlayerPool = videoPlayerPool - ) - Text( - text = sender.name, - style = MaterialTheme.typography.bodyMedium - ) - } - }, - onClick = { - showDropdown = false - linkHandler("tg://user?id=${sender.id}") - } - ) - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageSenderName.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageSenderName.kt deleted file mode 100644 index e185d043..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageSenderName.kt +++ /dev/null @@ -1,77 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Verified -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.MessageModel - -@Composable -fun MessageSenderName( - msg: MessageModel, - modifier: Modifier = Modifier, - toProfile: (Long) -> Unit = {} -) { - Row( - modifier = modifier.padding(bottom = 4.dp), - verticalAlignment = Alignment.CenterVertically - ) { - // 1. Sender Name - Text( - text = msg.senderName, - style = MaterialTheme.typography.labelLarge.copy( - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.primary - ), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - modifier = Modifier - .weight(1f, fill = false) - .clickable { toProfile(msg.senderId) } - ) - - // 2. Verified Icon - if (msg.isSenderVerified) { - Spacer(modifier = Modifier.width(4.dp)) - Icon( - imageVector = Icons.Rounded.Verified, - contentDescription = "Verified", - modifier = Modifier.size(14.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - - // 3. Custom Title - if (!msg.senderCustomTitle.isNullOrEmpty()) { - Spacer(modifier = Modifier.width(6.dp)) - - Surface( - shape = CircleShape, - color = MaterialTheme.colorScheme.primaryContainer, - contentColor = MaterialTheme.colorScheme.onPrimaryContainer, - ) { - Text( - text = msg.senderCustomTitle.toString(), - style = MaterialTheme.typography.labelSmall.copy( - fontWeight = FontWeight.Medium, - fontSize = 10.sp - ), - maxLines = 1, - modifier = Modifier.padding(horizontal = 6.dp, vertical = 1.dp) - ) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageText.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageText.kt deleted file mode 100644 index a41edaea..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageText.kt +++ /dev/null @@ -1,245 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import android.os.Build -import android.widget.Toast -import androidx.compose.animation.core.withInfiniteAnimationFrameMillis -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.text.InlineTextContent -import androidx.compose.material3.LocalContentColor -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawBehind -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.platform.LocalClipboardManager -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalUriHandler -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.TextLayoutResult -import androidx.compose.ui.text.TextStyle -import org.monogram.domain.models.MessageEntity -import org.monogram.domain.models.MessageEntityType - -@Composable -fun MessageText( - text: AnnotatedString, - inlineContent: Map, - style: TextStyle, - modifier: Modifier = Modifier, - color: Color = Color.Unspecified, - entities: List = emptyList(), - isOutgoing: Boolean = false, - onSpoilerClick: (Int) -> Unit = {}, - onClick: (Offset) -> Unit = {}, - onLongClick: (Offset) -> Unit = {} -) { - val uriHandler = LocalUriHandler.current - val clipboardManager = LocalClipboardManager.current - val context = LocalContext.current - val linkHandler = LocalLinkHandler.current - - val blockEntities = entities - .filter { it.type is MessageEntityType.Pre } - .sortedBy { it.offset } - - Column(modifier = modifier) { - if (blockEntities.isEmpty()) { - DefaultTextRender( - text = text, - inlineContent = inlineContent, - style = style, - color = color, - entities = entities, - onSpoilerClick = onSpoilerClick, - onClick = onClick, - onLongClick = onLongClick, - linkHandler = linkHandler, - uriHandler = uriHandler, - clipboardManager = clipboardManager, - context = context - ) - } else { - var lastOffset = 0 - - blockEntities.forEach { entity -> - if (entity.offset > lastOffset) { - val subText = text.subSequence(lastOffset, entity.offset) - if (subText.text.isNotBlank()) { - DefaultTextRender( - text = subText, - inlineContent = inlineContent, - style = style, - color = color, - entities = entities, - onSpoilerClick = onSpoilerClick, - onClick = onClick, - onLongClick = onLongClick, - linkHandler = linkHandler, - uriHandler = uriHandler, - clipboardManager = clipboardManager, - context = context - ) - } - } - - val codeType = entity.type as MessageEntityType.Pre - val codeRawText = text.text.substring(entity.offset, entity.offset + entity.length) - - CodeBlock( - text = codeRawText, - language = codeType.language, - isOutgoing = isOutgoing - ) - - lastOffset = entity.offset + entity.length - } - - if (lastOffset < text.length) { - val subText = text.subSequence(lastOffset, text.length) - if (subText.text.isNotBlank()) { - DefaultTextRender( - text = subText, - inlineContent = inlineContent, - style = style, - color = color, - entities = entities, - onSpoilerClick = onSpoilerClick, - onClick = onClick, - onLongClick = onLongClick, - linkHandler = linkHandler, - uriHandler = uriHandler, - clipboardManager = clipboardManager, - context = context - ) - } - } - } - } -} - -@Composable -private fun DefaultTextRender( - text: AnnotatedString, - inlineContent: Map, - style: TextStyle, - color: Color, - entities: List, - onSpoilerClick: (Int) -> Unit, - onClick: (Offset) -> Unit, - onLongClick: (Offset) -> Unit, - linkHandler: (String) -> Unit, - uriHandler: androidx.compose.ui.platform.UriHandler, - clipboardManager: androidx.compose.ui.platform.ClipboardManager, - context: android.content.Context -) { - val layoutResult = remember { mutableStateOf(null) } - val spoilerColor = if (color != Color.Unspecified) color else LocalContentColor.current - - val time by produceState(0f) { - while (true) { - withInfiniteAnimationFrameMillis { - value = it / 1000f - } - } - } - - val shader = remember { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - SpoilerShaderApi33.createShader(SpoilerShader.SHADER_CODE) - } else null - } - - Text( - text = text, - inlineContent = inlineContent, - style = style, - color = color, - modifier = Modifier - .drawBehind { - layoutResult.value?.let { result -> - val unrevealedSpoilers = text.getStringAnnotations("SPOILER_UNREVEALED", 0, text.length) - unrevealedSpoilers.forEach { spoilerAnnotation -> - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && shader != null) { - drawSpoilerEffectApi33( - layoutResult = result, - start = spoilerAnnotation.start, - end = spoilerAnnotation.end, - shader = shader, - time = time, - color = spoilerColor.copy(alpha = 0.5f) - ) - } else { - drawSpoilerEffectFallback( - layoutResult = result, - start = spoilerAnnotation.start, - end = spoilerAnnotation.end, - time = time, - color = spoilerColor - ) - } - } - } - } - .pointerInput(text) { - detectTapGestures( - onTap = { offset -> - var consumed = false - layoutResult.value?.let { result -> - val rawPosition = result.getOffsetForPosition(offset) - val position = if (text.isNotEmpty()) rawPosition.coerceIn(0, text.length - 1) else 0 - val annotations = buildList { - addAll(text.getStringAnnotations(position, (position + 1).coerceAtMost(text.length))) - if (position > 0) { - addAll(text.getStringAnnotations(position - 1, position)) - } - } - - val annotation = annotations.firstOrNull { it.tag.startsWith("SPOILER") } - ?: annotations.firstOrNull() - - annotation?.let { - when (annotation.tag) { - "URL" -> { - val url = normalizeUrl(annotation.item) - linkHandler(url) - consumed = true - } - - "SPOILER", "SPOILER_REVEALED", "SPOILER_UNREVEALED" -> { - annotation.item.toIntOrNull()?.let { - onSpoilerClick(it) - consumed = true - } - } - - "COPY" -> { - clipboardManager.setText(AnnotatedString(annotation.item)) - Toast.makeText(context, "Copied to clipboard", Toast.LENGTH_SHORT).show() - consumed = true - } - - "MENTION" -> { - val username = annotation.item.removePrefix("@") - linkHandler("https://t.me/$username") - consumed = true - } - - "TEXT_MENTION" -> { - val userId = annotation.item - linkHandler("tg://user?id=$userId") - consumed = true - } - } - } - } - if (!consumed) onClick(offset) - }, - onLongPress = { offset -> onLongClick(offset) } - ) - }, - onTextLayout = { layoutResult.value = it } - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageTextFormatter.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageTextFormatter.kt deleted file mode 100644 index 8b833af5..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageTextFormatter.kt +++ /dev/null @@ -1,243 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.text.InlineTextContent -import androidx.compose.foundation.text.appendInlineContent -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.* -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextDecoration -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.koin.compose.koinInject -import org.monogram.domain.models.MessageEntity -import org.monogram.domain.models.MessageEntityType -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.features.stickers.ui.view.StickerImage - -@Composable -fun rememberMessageInlineContent( - entities: List, - fontSize: Float -): Map { - return remember(entities, fontSize) { - val map = mutableMapOf() - val emojiEntities = entities.filter { it.type is MessageEntityType.CustomEmoji }.sortedBy { it.offset } - emojiEntities.forEachIndexed { index, entity -> - val emojiSize = (fontSize * 1.25f).sp - map["emoji_$index"] = InlineTextContent( - Placeholder(emojiSize, emojiSize, PlaceholderVerticalAlign.Center) - ) { - StickerImage( - path = (entity.type as MessageEntityType.CustomEmoji).path, - modifier = Modifier.size((fontSize * 1.25f).dp) - ) - } - } - map - } -} - -@Composable -fun buildAnnotatedMessageTextWithEmoji( - text: String, - entities: List, - isOutgoing: Boolean = false, - revealedSpoilers: List = emptyList(), - appPreferences: AppPreferences = koinInject() -): AnnotatedString { - val context = LocalContext.current - val emojiStyle by appPreferences.emojiStyle.collectAsState() - val emojiFontFamily = remember(context, emojiStyle) { getEmojiFontFamily(context, emojiStyle) } - - val linkColor = MaterialTheme.colorScheme.primary - val codeBackgroundColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.1f) - val codeTextColor = MaterialTheme.colorScheme.primary - val revealedSpoilersSnapshot = revealedSpoilers.toSet() - - return remember( - text, - entities, - isOutgoing, - revealedSpoilersSnapshot, - emojiFontFamily, - linkColor, - codeBackgroundColor, - codeTextColor - ) { - val emojiEntities = entities.filter { it.type is MessageEntityType.CustomEmoji }.sortedBy { it.offset } - val otherEntities = entities.filter { it.type !is MessageEntityType.CustomEmoji } - - buildAnnotatedString { - var currentPos = 0 - val indexMapping = mutableMapOf() - - emojiEntities.forEachIndexed { index, entity -> - val safeStart = entity.offset.coerceIn(0, text.length) - val safeEnd = (entity.offset + entity.length).coerceIn(safeStart, text.length) - - if (safeStart > currentPos) { - val segment = text.substring(currentPos, safeStart) - segment.forEachIndexed { i, _ -> - indexMapping[currentPos + i] = this.length - append(segment[i]) - } - } - - if (safeStart >= currentPos) { - indexMapping[safeStart] = this.length - appendInlineContent("emoji_$index", "[emoji]") - currentPos = safeEnd - } - } - - if (currentPos < text.length) { - val segment = text.substring(currentPos) - segment.forEachIndexed { i, _ -> - indexMapping[currentPos + i] = this.length - append(segment[i]) - } - } - indexMapping[text.length] = this.length - - if (emojiFontFamily != FontFamily.Default) { - addEmojiStyle(this.toAnnotatedString().text, emojiFontFamily) - } - - otherEntities.forEach { entity -> - val safeStart = entity.offset.coerceIn(0, text.length) - val safeEnd = (entity.offset + entity.length).coerceIn(safeStart, text.length) - val start = indexMapping[safeStart] ?: return@forEach - val end = indexMapping[safeEnd] ?: indexMapping[text.length] ?: return@forEach - if (start >= end) return@forEach - - when (val type = entity.type) { - is MessageEntityType.Bold -> addStyle(SpanStyle(fontWeight = FontWeight.Bold), start, end) - is MessageEntityType.Italic -> addStyle(SpanStyle(fontStyle = FontStyle.Italic), start, end) - is MessageEntityType.Underline -> addStyle( - SpanStyle(textDecoration = TextDecoration.Underline), - start, - end - ) - - is MessageEntityType.Strikethrough -> addStyle( - SpanStyle(textDecoration = TextDecoration.LineThrough), - start, - end - ) - - is MessageEntityType.Spoiler -> { - val spoilerKey = spoilerKeyForEntity(entity) - val isRevealed = revealedSpoilersSnapshot.contains(spoilerKey) - if (isRevealed) { - addStyle(SpanStyle(background = Color.Gray.copy(alpha = 0.2f)), start, end) - addStringAnnotation("SPOILER_REVEALED", spoilerKey.toString(), start, end) - } else { - addStyle( - SpanStyle(color = Color.Transparent), - start, - end - ) - addStringAnnotation("SPOILER_UNREVEALED", spoilerKey.toString(), start, end) - } - addStringAnnotation("SPOILER", spoilerKey.toString(), start, end) - } - - is MessageEntityType.Code -> { - addStyle( - SpanStyle( - fontFamily = FontFamily.Monospace, - background = codeBackgroundColor, - color = codeTextColor - ), start, end - ) - addStringAnnotation( - "COPY", - text.safeSubstring(safeStart, safeEnd), - start, - end - ) - } - - is MessageEntityType.Pre -> { - addStyle( - SpanStyle( - fontFamily = FontFamily.Monospace, - background = codeBackgroundColor, - color = codeTextColor - ), start, end - ) - addStringAnnotation( - "COPY", - text.safeSubstring(safeStart, safeEnd), - start, - end - ) - } - - is MessageEntityType.TextUrl -> { - addStyle(SpanStyle(color = linkColor, textDecoration = TextDecoration.Underline), start, end) - addStringAnnotation("URL", type.url, start, end) - } - - is MessageEntityType.Url -> { - addStyle(SpanStyle(color = linkColor, textDecoration = TextDecoration.Underline), start, end) - addStringAnnotation("URL", text.safeSubstring(safeStart, safeEnd), start, end) - } - - is MessageEntityType.Mention -> { - addStyle(SpanStyle(color = linkColor), start, end) - addStringAnnotation( - "MENTION", - text.safeSubstring(safeStart, safeEnd), - start, - end - ) - } - - is MessageEntityType.TextMention -> { - addStyle(SpanStyle(color = linkColor), start, end) - addStringAnnotation( - "TEXT_MENTION", - type.userId.toString(), - start, - end - ) - } - - is MessageEntityType.Hashtag -> { - addStyle(SpanStyle(color = linkColor), start, end) - addStringAnnotation( - "HASHTAG", - text.safeSubstring(safeStart, safeEnd), - start, - end - ) - } - - else -> {} - } - } - } - } -} - -private fun spoilerKeyForEntity(entity: MessageEntity): Int { - return (entity.offset * 1_000_003) xor entity.length -} - -private fun String.safeSubstring(start: Int, end: Int): String { - if (isEmpty()) return "" - val safeStart = start.coerceIn(0, length) - val safeEnd = end.coerceIn(safeStart, length) - return substring(safeStart, safeEnd) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageUtils.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageUtils.kt deleted file mode 100644 index 8c40848a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageUtils.kt +++ /dev/null @@ -1,314 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import android.content.Context -import androidx.compose.animation.* -import androidx.compose.animation.core.* -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.size -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.* -import androidx.compose.material.icons.outlined.Visibility -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.staticCompositionLocalOf -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.font.Font -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.MessageEntity -import org.monogram.domain.models.MessageEntityType -import org.monogram.domain.models.MessageModel -import org.monogram.domain.models.MessageSendingState -import org.monogram.presentation.core.util.EmojiStyle -import org.monogram.presentation.features.chats.currentChat.components.channels.formatViews -import java.io.File -import java.text.BreakIterator -import java.text.SimpleDateFormat -import java.util.* -import kotlin.math.log10 -import kotlin.math.pow - -val LocalLinkHandler = staticCompositionLocalOf<(String) -> Unit> { - { _ -> } -} - -fun formatTime(ts: Int): String = - SimpleDateFormat("HH:mm", Locale.getDefault()).format(Date(ts.toLong() * 1000)) - -fun formatDuration(seconds: Int): String { - val m = seconds / 60 - val s = seconds % 60 - return String.format(Locale.getDefault(), "%02d:%02d", m, s) -} -fun formatFileSize(size: Long): String { - if (size <= 0) return "0 B" - val units = arrayOf("B", "KB", "MB", "GB", "TB") - val digitGroups = (log10(size.toDouble()) / log10(1024.0)).toInt() - return String.format( - Locale.getDefault(), - "%.1f %s", - size / 1024.0.pow(digitGroups.toDouble()), - units[digitGroups] - ) -} - -fun getEmojiFontFileName(style: EmojiStyle): String? = when (style) { - EmojiStyle.APPLE -> "apple.ttf" - EmojiStyle.TWITTER -> "twemoji.ttf" - EmojiStyle.WINDOWS -> "win11.ttf" - EmojiStyle.CATMOJI -> "catmoji.ttf" - EmojiStyle.NOTO -> "notoemoji.ttf" - EmojiStyle.SYSTEM -> null -} - -@Composable -fun getEmojiFontFamily(style: EmojiStyle): FontFamily { - val context = LocalContext.current - return getEmojiFontFamily(context, style) -} - -fun getEmojiFontFamily(context: Context, style: EmojiStyle): FontFamily { - val fileName = getEmojiFontFileName(style) ?: return FontFamily.Default - val file = File(context.filesDir, "fonts/$fileName") - return if (file.exists()) { - try { - FontFamily(Font(file)) - } catch (e: Exception) { - FontFamily.Default - } - } else { - FontFamily.Default - } -} - -fun AnnotatedString.Builder.addEmojiStyle(text: String, emojiFontFamily: FontFamily) { - var i = 0 - var currentBlockStart = 0 - var isBlockEmoji = false - - while (i < text.length) { - val codePoint = text.codePointAt(i) - val charCount = Character.charCount(codePoint) - - val isCurrentCharEmoji = isEmojiLegacy(codePoint) - - if (i == 0) { - isBlockEmoji = isCurrentCharEmoji - } - - if (isBlockEmoji != isCurrentCharEmoji) { - val fontToUse = if (isBlockEmoji) emojiFontFamily else FontFamily.Default - addStyle(SpanStyle(fontFamily = fontToUse), currentBlockStart, i) - - currentBlockStart = i - isBlockEmoji = isCurrentCharEmoji - } - - i += charCount - } - - val finalFont = if (isBlockEmoji) emojiFontFamily else FontFamily.Default - addStyle(SpanStyle(fontFamily = finalFont), currentBlockStart, text.length) -} - -fun isBigEmoji(text: String, entities: List): Boolean { - val emojiEntities = entities.filter { it.type is MessageEntityType.CustomEmoji } - val otherEntities = entities.filter { it.type !is MessageEntityType.CustomEmoji } - - if (otherEntities.isNotEmpty()) return false - - if (emojiEntities.size == 1) { - val entity = emojiEntities[0] - val textBefore = text.substring(0, entity.offset) - val textAfter = text.substring(entity.offset + entity.length) - return textBefore.trim().isEmpty() && textAfter.trim().isEmpty() - } - - if (emojiEntities.isNotEmpty()) return false - - val trimmed = text.trim() - if (trimmed.isEmpty()) return false - - var i = 0 - while (i < trimmed.length) { - val codePoint = trimmed.codePointAt(i) - if (!isEmojiLegacy(codePoint)) return false - i += Character.charCount(codePoint) - } - - val it = BreakIterator.getCharacterInstance() - it.setText(trimmed) - var count = 0 - while (it.next() != BreakIterator.DONE) { - count++ - } - return count == 1 -} - -fun isEmojiLegacy(codePoint: Int): Boolean { - return when (codePoint) { - in 0x1F600..0x1F64F -> true // Emoticons (😀, 😭, etc.) - in 0x1F300..0x1F5FF -> true // Misc Symbols and Pictographs (🍔, 🌺, 🎤) - in 0x1F680..0x1F6FF -> true // Transport and Map (🚀, 🚗, 🚲) - in 0x1F900..0x1F9FF -> true // Supplemental Symbols and Pictographs (🦕, 🥨, 🧗) - in 0x1FA70..0x1FAFF -> true // Symbols and Pictographs Extended-A (🩰, 🪖, 🫧 - including new Unicode 15) - in 0x1FA00..0x1FA6F -> true // Chess, Mahjong, and other extensions (🩲, 🪰) - - in 0x2600..0x26FF -> true // Misc Symbols (☔, ☕, ♻️, ♀️) - in 0x2700..0x27BF -> true // Dingbats (✂️, ✉️, ✨, ❄️) - in 0x2B50..0x2B55 -> true // Stars and Circles (⭐, ⭕) - in 0x2300..0x23FF -> true // Misc Technical (⌚, ⏰, ⌨️, ⏩ - Watch, Hourglass, Arrows) - in 0x2194..0x2199 -> true // Arrows often used as emoji (↔️, ↕️) - in 0x2B05..0x2B07 -> true // Large Arrows (⬅️, ⬇️) - in 0x2934..0x2935 -> true // Curving Arrows (⤴️) - in 0x3297..0x3299 -> true // Circled CJK (㊙️, ㊗️) - - in 0x1F1E6..0x1F1FF -> true // Regional Indicator Symbols (The letters that make Flags 🇺🇸, 🇮🇹) - in 0x1F191..0x1F19A -> true // Squared ID, VS, etc. (🆔, 🆘) - 0x200D -> true // Zero Width Joiner (Essential for complex emojis like 👨‍👩‍👧‍👦) - 0xFE0F -> true // Variation Selector-16 (Forces emoji style on text chars) - - in 0x1F004..0x1F0CF -> true // Mahjong & Playing Cards (🀄, 🃏) - - else -> false - } -} - -fun normalizeUrl(url: String): String { - return if (url.startsWith("http://") || url.startsWith("https://")) { - url - } else { - "https://$url" - } -} - -@Composable -fun MessageMetadata( - msg: MessageModel, - isOutgoing: Boolean, - contentColor: Color -) { - val context = LocalContext.current - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(4.dp) - ) { - val views = msg.viewCount ?: msg.views - if (views != null && views > 0) { - Icon( - imageVector = Icons.Outlined.Visibility, - contentDescription = null, - modifier = Modifier.size(12.dp), - tint = contentColor - ) - Text( - text = formatViews(context, views), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 10.sp), - color = contentColor - ) - } - - if (msg.editDate > 0) { - Icon( - imageVector = Icons.Default.Edit, - contentDescription = "Edited", - modifier = Modifier.size(12.dp), - tint = contentColor - ) - } - Text( - text = formatTime(msg.date), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 10.sp), - color = contentColor - ) - if (isOutgoing) { - MessageSendingStatusIcon( - sendingState = msg.sendingState, - isRead = msg.isRead, - baseColor = contentColor, - size = 13.dp, - usePrimaryForRead = contentColor != Color.White - ) - } - } -} - -@Composable -fun MessageSendingStatusIcon( - sendingState: MessageSendingState?, - isRead: Boolean, - baseColor: Color, - modifier: Modifier = Modifier, - size: androidx.compose.ui.unit.Dp = 14.dp, - usePrimaryForRead: Boolean = true -) { - val targetTint = when { - sendingState is MessageSendingState.Failed -> MaterialTheme.colorScheme.error - isRead && usePrimaryForRead -> MaterialTheme.colorScheme.primary - else -> baseColor - } - val tint = animateColorAsState(targetValue = targetTint, animationSpec = tween(220), label = "SendingTint").value - - AnimatedContent( - targetState = sendingState to isRead, - transitionSpec = { - val incomingFromBottom = targetState.first == null && initialState.first is MessageSendingState.Pending - val enter = fadeIn(tween(200)) + - slideInVertically(tween(220)) { fullHeight -> if (incomingFromBottom) fullHeight / 2 else -fullHeight / 2 } - val exit = fadeOut(tween(150)) + - slideOutVertically(tween(170)) { fullHeight -> if (incomingFromBottom) -fullHeight / 2 else fullHeight / 2 } - enter.togetherWith(exit).using(SizeTransform(clip = false)) - }, - label = "SendingState" - ) { (state, read) -> - val icon = when (state) { - is MessageSendingState.Pending -> Icons.Default.Schedule - is MessageSendingState.Failed -> Icons.Default.Error - null -> if (read) Icons.Default.DoneAll else Icons.Default.Check - } - - val pendingRotation = if (state is MessageSendingState.Pending) { - val transition = rememberInfiniteTransition(label = "PendingRotation") - transition.animateFloat( - initialValue = 0f, - targetValue = 360f, - animationSpec = infiniteRepeatable( - animation = tween(durationMillis = 1200, easing = LinearEasing), - repeatMode = RepeatMode.Restart - ), - label = "PendingRotationValue" - ).value - } else { - 0f - } - - val settledScale = animateFloatAsState( - targetValue = if (state is MessageSendingState.Pending) 1f else 1.06f, - animationSpec = tween(220), - label = "SendingScale" - ).value - - Icon( - imageVector = icon, - contentDescription = null, - modifier = modifier - .size(size) - .graphicsLayer { - rotationZ = pendingRotation - scaleX = settledScale - scaleY = settledScale - }, - tint = tint - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageViaBotAttribution.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageViaBotAttribution.kt deleted file mode 100644 index 94efd224..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/MessageViaBotAttribution.kt +++ /dev/null @@ -1,54 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.MessageModel - -@Composable -fun MessageViaBotAttribution( - msg: MessageModel, - isOutgoing: Boolean, - onViaBotClick: (String) -> Unit, - modifier: Modifier = Modifier -) { - val botUsername = msg.viaBotName?.takeIf { it.isNotBlank() } ?: return - val textColor = if (isOutgoing) { - MaterialTheme.colorScheme.onPrimaryContainer - } else { - MaterialTheme.colorScheme.onSurfaceVariant - } - - AnimatedVisibility( - visible = true, - enter = fadeIn(), - exit = fadeOut(), - modifier = modifier - ) { - Row(modifier = Modifier.padding(horizontal = 6.dp, vertical = 2.dp)) { - Text( - text = "via", - style = MaterialTheme.typography.labelSmall, - color = textColor.copy(alpha = 0.65f) - ) - Spacer(modifier = Modifier.width(4.dp)) - Text( - text = "@$botUsername", - style = MaterialTheme.typography.labelSmall.copy(fontWeight = FontWeight.SemiBold), - color = MaterialTheme.colorScheme.primary, - modifier = Modifier.clickable { onViaBotClick(botUsername) } - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/PhotoMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/PhotoMessageBubble.kt deleted file mode 100644 index 121216ab..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/PhotoMessageBubble.kt +++ /dev/null @@ -1,354 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.animation.animateContentSize -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.tween -import androidx.compose.foundation.background -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Download -import androidx.compose.material3.CircularProgressIndicator -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clipToBounds -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.zIndex -import coil3.compose.AsyncImage -import coil3.compose.AsyncImagePainter -import coil3.request.ImageRequest -import coil3.request.crossfade -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.AutoDownloadSuppression - -@Composable -fun PhotoMessageBubble( - content: MessageContent.Photo, - msg: MessageModel, - isOutgoing: Boolean, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - letterSpacing: Float, - isGroup: Boolean = false, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - onPhotoClick: (MessageModel) -> Unit, - onDownloadPhoto: (Int) -> Unit = {}, - onCancelDownload: (Int) -> Unit = {}, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - showMetadata: Boolean = true, - showReactions: Boolean = true, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils -) { - val context = LocalContext.current - val cornerRadius = 18.dp - val smallCorner = 4.dp - val tailCorner = 2.dp - - var stablePath by remember(msg.id, content.fileId) { mutableStateOf(content.path) } - val hasPath = !stablePath.isNullOrBlank() - var isFullImageReady by remember(msg.id, content.fileId) { mutableStateOf(false) } - val mediaAlpha by animateFloatAsState( - targetValue = if (hasPath && isFullImageReady) 1f else 0f, - animationSpec = tween(320), - label = "PhotoMediaAlpha" - ) - - LaunchedEffect(content.path, content.fileId) { - if (!content.path.isNullOrBlank()) { - stablePath = content.path - AutoDownloadSuppression.clear(content.fileId) - } else { - stablePath = null - } - } - - LaunchedEffect(hasPath) { - if (!hasPath) { - isFullImageReady = false - } - } - - LaunchedEffect(content.path, content.isDownloading, autoDownloadMobile, autoDownloadWifi, autoDownloadRoaming) { - if (content.path.isNullOrBlank() && !content.isDownloading && !AutoDownloadSuppression.isSuppressed(content.fileId)) { - val shouldDownload = when { - downloadUtils.isWifiConnected() -> autoDownloadWifi - downloadUtils.isRoaming() -> autoDownloadRoaming - else -> autoDownloadMobile - } - if (shouldDownload) { - onDownloadPhoto(content.fileId) - } - } - } - - val topStart = if (!isOutgoing && isSameSenderAbove) smallCorner else cornerRadius - val topEnd = if (isOutgoing && isSameSenderAbove) smallCorner else cornerRadius - val bottomStart = if (!isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius - val bottomEnd = if (isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius - - val bubbleShape = RoundedCornerShape( - topStart = topStart, - topEnd = topEnd, - bottomEnd = bottomEnd, - bottomStart = bottomStart - ) - - var imagePosition by remember { mutableStateOf(Offset.Zero) } - val revealedSpoilers = remember { mutableStateListOf() } - var isMediaSpoilerRevealed by remember { mutableStateOf(!content.hasSpoiler) } - - Column( - modifier = modifier.width(IntrinsicSize.Max), - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh, - contentColor = if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant, - ) { - Column(modifier = Modifier - .widthIn(max = 280.dp) - .animateContentSize()) { - if (isGroup && !isOutgoing && !isSameSenderAbove) { - Box( - modifier = Modifier - .fillMaxWidth() - .background(if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(start = 12.dp, end = 12.dp, top = 8.dp) - .zIndex(1f) - ) { - MessageSenderName(msg) - } - } - - msg.forwardInfo?.let { forward -> - Box( - modifier = Modifier - .fillMaxWidth() - .background(if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(horizontal = 12.dp, vertical = 4.dp) - .zIndex(1f) - ) { - ForwardContent(forward, isOutgoing, onForwardClick = toProfile) - } - } - msg.replyToMsg?.let { reply -> - Box( - modifier = Modifier - .fillMaxWidth() - .background(if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(horizontal = 4.dp, vertical = 4.dp) - .zIndex(1f) - ) { - ReplyContent( - replyToMsg = reply, - isOutgoing = isOutgoing, - onClick = { onReplyClick(reply) } - ) - } - } - - Box( - modifier = Modifier - .fillMaxWidth() - .heightIn(min = 160.dp, max = 320.dp) - .aspectRatio( - if (content.width > 0 && content.height > 0) - (content.width.toFloat() / content.height.toFloat()).coerceIn(0.5f, 2f) - else 1f - ) - .clipToBounds() - .onGloballyPositioned { imagePosition = it.positionInWindow() } - .pointerInput(Unit) { - detectTapGestures( - onTap = { - if (content.hasSpoiler) { - isMediaSpoilerRevealed = !isMediaSpoilerRevealed - } else if (content.isDownloading) { - AutoDownloadSuppression.suppress(content.fileId) - onCancelDownload(content.fileId) - } else { - AutoDownloadSuppression.clear(content.fileId) - if (hasPath) { - onPhotoClick(msg) - } else { - onDownloadPhoto(content.fileId) - } - } - }, - onLongPress = { offset -> onLongClick(imagePosition + offset) } - ) - } - ) { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - MediaLoadingBackground( - previewData = content.minithumbnail, - contentScale = ContentScale.Fit - ) - - if (hasPath) { - AsyncImage( - model = ImageRequest.Builder(context) - .data(stablePath) - .crossfade(true) - .build(), - contentDescription = content.caption, - modifier = Modifier - .fillMaxSize() - .graphicsLayer { alpha = mediaAlpha }, - contentScale = ContentScale.Fit, - onState = { state -> - isFullImageReady = state is AsyncImagePainter.State.Success - } - ) - } - - if (!hasPath || !isFullImageReady) { - MediaLoadingAction( - isDownloading = content.isDownloading || hasPath, - progress = content.downloadProgress, - idleIcon = Icons.Default.Download, - idleContentDescription = "Download", - showCancelOnDownload = content.isDownloading, - onCancelClick = { - AutoDownloadSuppression.suppress(content.fileId) - onCancelDownload(content.fileId) - }, - onIdleClick = { - AutoDownloadSuppression.clear(content.fileId) - if (hasPath) { - onPhotoClick(msg) - } else { - onDownloadPhoto(content.fileId) - } - } - ) - } - } - - if (content.isUploading) { - Box( - modifier = Modifier - .matchParentSize() - .background(Color.Black.copy(alpha = 0.5f)), - contentAlignment = Alignment.Center - ) { - if (content.uploadProgress > 0f) { - CircularProgressIndicator( - progress = { content.uploadProgress }, - color = Color.White, - trackColor = Color.White.copy(alpha = 0.3f), - ) - } else { - CircularProgressIndicator( - color = Color.White - ) - } - } - } - - SpoilerWrapper(isRevealed = isMediaSpoilerRevealed) { - Box(modifier = Modifier.fillMaxSize()) - } - - if (content.caption.isEmpty() && showMetadata) { - Box( - modifier = Modifier - .align(Alignment.BottomEnd) - .padding(6.dp) - .background(Color.Black.copy(alpha = 0.45f), RoundedCornerShape(12.dp)) - .padding(horizontal = 6.dp, vertical = 2.dp) - ) { - MessageMetadata(msg, isOutgoing, Color.White) - } - } - } - - if (content.caption.isNotEmpty()) { - val timeColor = if (isOutgoing) - MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.7f) - else - MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f) - - Column( - modifier = Modifier - .fillMaxWidth() - .background(if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 12.dp) - .zIndex(1f) - ) { - val inlineContent = rememberMessageInlineContent(content.entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = content.caption, - entities = content.entities, - isOutgoing = isOutgoing, - revealedSpoilers = revealedSpoilers - ) - - MessageText( - text = finalAnnotatedString, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = fontSize.sp, - letterSpacing = letterSpacing.sp, - lineHeight = (fontSize * 1.375f).sp - ), - modifier = Modifier.padding(bottom = 4.dp), - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = { offset -> onLongClick(imagePosition + offset) }, - onLongClick = { offset -> onLongClick(imagePosition + offset) } - ) - if (showMetadata) { - Box(modifier = Modifier.align(Alignment.End)) { - MessageMetadata(msg, isOutgoing, timeColor) - } - } - } - } - } - } - - if (showReactions) { - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(horizontal = 4.dp) - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/PollMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/PollMessageBubble.kt deleted file mode 100644 index 1aadb38f..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/PollMessageBubble.kt +++ /dev/null @@ -1,482 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.tween -import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.* -import androidx.compose.material.icons.outlined.RadioButtonUnchecked -import androidx.compose.material.icons.rounded.CheckBoxOutlineBlank -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.res.pluralStringResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.* -import org.monogram.presentation.R - -@Composable -fun PollMessageBubble( - content: MessageContent.Poll, - msg: MessageModel, - isOutgoing: Boolean, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - letterSpacing: Float, - bubbleRadius: Float = 18f, - onOptionClick: (Int) -> Unit, - onRetractVote: () -> Unit = {}, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - onShowVoters: (Int) -> Unit = {}, - onClosePoll: () -> Unit = {}, - onLongClick: (Offset) -> Unit = {}, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier -) { - val cornerRadius = bubbleRadius.dp - val smallCorner = (bubbleRadius / 4f).coerceAtLeast(4f).dp - val tailCorner = 2.dp - - val bubbleShape = RoundedCornerShape( - topStart = if (!isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - topEnd = if (isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - bottomStart = if (!isOutgoing) (if (isSameSenderBelow) smallCorner else tailCorner) else cornerRadius, - bottomEnd = if (isOutgoing) (if (isSameSenderBelow) smallCorner else tailCorner) else cornerRadius - ) - - val containerColor = - if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh - val contentColor = - if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurface - - val hasVoted = content.options.any { it.isChosen } - val isQuiz = content.type is PollType.Quiz - val quizType = content.type as? PollType.Quiz - val isMultiChoice = (content.type as? PollType.Regular)?.allowMultipleAnswers == true - - Column( - modifier = modifier - .width(IntrinsicSize.Max) - .widthIn(min = 240.dp, max = 320.dp) - .pointerInput(Unit) { - detectTapGestures( - onLongPress = { onLongClick(it) } - ) - }, - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = containerColor, - contentColor = contentColor, - tonalElevation = 1.dp - ) { - Column( - modifier = Modifier.padding(12.dp) - ) { - msg.forwardInfo?.let { ForwardContent(it, isOutgoing, onForwardClick = toProfile) } - msg.replyToMsg?.let { ReplyContent(it, isOutgoing) { onReplyClick(it) } } - - PollHeader( - question = content.question, - pollType = content.type, - fontSize = fontSize, - letterSpacing = letterSpacing, - hasVoted = hasVoted, - isClosed = content.isClosed, - isAnonymous = content.isAnonymous, - isOutgoing = isOutgoing, - onRetractVote = onRetractVote, - onClosePoll = onClosePoll - ) - - Spacer(modifier = Modifier.height(12.dp)) - - Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { - content.options.forEachIndexed { index, option -> - val isCorrect = isQuiz && quizType?.correctOptionId == index - val isWrong = isQuiz && option.isChosen && quizType?.correctOptionId != index - - val canVote = !content.isClosed && !hasVoted - - PollOptionItem( - option = option, - isMultiChoice = isMultiChoice, - isQuiz = isQuiz, - isCorrect = isCorrect, - isWrong = isWrong, - showResults = hasVoted || content.isClosed, - isAnonymous = content.isAnonymous, - canVote = canVote, - onClick = { onOptionClick(index) }, - onShowVoters = { onShowVoters(index) } - ) - } - } - - AnimatedVisibility( - visible = isQuiz && hasVoted && !quizType?.explanation.isNullOrBlank() - ) { - QuizExplanationBox( - text = quizType?.explanation ?: "", - containerColor = contentColor.copy(alpha = 0.05f), - textColor = contentColor - ) - } - - Spacer(modifier = Modifier.height(8.dp)) - - PollFooter( - totalVotes = content.totalVoterCount, - date = msg.date, - isOutgoing = isOutgoing, - sendingState = msg.sendingState, - isRead = msg.isRead, - contentColor = contentColor - ) - } - } - - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(horizontal = 4.dp, vertical = 2.dp) - ) - } -} - -@Composable -private fun PollHeader( - question: String, - pollType: PollType, - fontSize: Float, - letterSpacing: Float, - hasVoted: Boolean, - isClosed: Boolean, - isAnonymous: Boolean, - isOutgoing: Boolean, - onRetractVote: () -> Unit, - onClosePoll: () -> Unit -) { - var showMenu by remember { mutableStateOf(false) } - - Column { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.Top - ) { - val isQuiz = pollType is PollType.Quiz - val isMultiChoice = (pollType as? PollType.Regular)?.allowMultipleAnswers == true - - val label = if (isClosed) { - stringResource(R.string.poll_final_results) - } else { - buildString { - append(if (isAnonymous) stringResource(R.string.poll_anonymous) else stringResource(R.string.poll_public)) - append(" ") - append(if (isQuiz) stringResource(R.string.poll_type_quiz) else stringResource(R.string.poll_type_poll)) - if (isMultiChoice) append(stringResource(R.string.poll_multiple_choice)) - } - } - - Text( - text = label.uppercase(), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.SemiBold, - modifier = Modifier.padding(bottom = 4.dp) - ) - - if (!isClosed && (hasVoted || isOutgoing)) { - Box { - IconButton( - onClick = { showMenu = true }, - modifier = Modifier.size(20.dp) - ) { - Icon( - imageVector = Icons.Default.MoreVert, - contentDescription = stringResource(R.string.cd_more), - modifier = Modifier.size(16.dp) - ) - } - DropdownMenu( - expanded = showMenu, - onDismissRequest = { showMenu = false } - ) { - if (hasVoted) { - DropdownMenuItem( - text = { Text(stringResource(R.string.poll_retract_vote)) }, - onClick = { - showMenu = false - onRetractVote() - }, - leadingIcon = { - Icon( - imageVector = Icons.Default.Cancel, - contentDescription = null - ) - } - ) - } - if (isOutgoing) { - DropdownMenuItem( - text = { Text(stringResource(R.string.poll_close_poll)) }, - onClick = { - showMenu = false - onClosePoll() - }, - leadingIcon = { - Icon( - imageVector = Icons.Default.Stop, - contentDescription = null - ) - } - ) - } - } - } - } - } - - Text( - text = question, - style = MaterialTheme.typography.titleMedium.copy( - fontSize = (fontSize + 2).sp, - letterSpacing = letterSpacing.sp, - fontWeight = FontWeight.Bold, - lineHeight = (fontSize + 6).sp - ) - ) - } -} - -@Composable -private fun PollOptionItem( - option: PollOption, - isMultiChoice: Boolean, - isQuiz: Boolean, - isCorrect: Boolean, - isWrong: Boolean, - showResults: Boolean, - isAnonymous: Boolean, - canVote: Boolean, - onClick: () -> Unit, - onShowVoters: () -> Unit -) { - val progress by animateFloatAsState( - targetValue = if (showResults) option.votePercentage / 100f else 0f, - animationSpec = tween(durationMillis = 600), label = "progress" - ) - - val baseContentColor = MaterialTheme.colorScheme.onSurface - val primaryColor = MaterialTheme.colorScheme.primary - val errorColor = MaterialTheme.colorScheme.error - val successColor = Color(0xFF4CAF50) - - val stateColor = when { - showResults && isCorrect -> successColor - showResults && isWrong -> errorColor - option.isChosen -> primaryColor - else -> MaterialTheme.colorScheme.outline - } - - val shape = RoundedCornerShape(12.dp) - val borderColor = - if (option.isChosen || (showResults && isCorrect)) stateColor else MaterialTheme.colorScheme.outlineVariant.copy( - alpha = 0.5f - ) - val backgroundColor = MaterialTheme.colorScheme.surfaceContainer - - Box( - modifier = Modifier - .fillMaxWidth() - .height(IntrinsicSize.Min) - .clip(shape) - .background(backgroundColor) - .border( - border = BorderStroke(if (option.isChosen) 2.dp else 1.dp, borderColor), - shape = shape - ) - .clickable(enabled = canVote || (showResults && !isAnonymous)) { - if (canVote) onClick() else if (showResults && !isAnonymous) onShowVoters() - } - ) { - if (showResults) { - Box( - modifier = Modifier - .fillMaxHeight() - .fillMaxWidth(progress) - .background(stateColor.copy(alpha = 0.15f)) - ) - } - - Row( - modifier = Modifier - .padding(horizontal = 12.dp, vertical = 10.dp) - .fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically - ) { - Box(modifier = Modifier.size(24.dp), contentAlignment = Alignment.Center) { - if (showResults) { - if (isCorrect || isWrong || option.isChosen) { - Icon( - imageVector = when { - isCorrect -> Icons.Default.CheckCircle - isWrong -> Icons.Default.Cancel - else -> Icons.Default.CheckCircle - }, - contentDescription = null, - tint = stateColor, - modifier = Modifier.size(20.dp) - ) - } else { - Text( - text = "${option.votePercentage}%", - style = MaterialTheme.typography.labelSmall, - fontWeight = FontWeight.Bold, - color = baseContentColor.copy(alpha = 0.6f) - ) - } - } else { - val unselectedIcon = - if (isMultiChoice) Icons.Rounded.CheckBoxOutlineBlank else Icons.Outlined.RadioButtonUnchecked - Icon( - imageVector = unselectedIcon, - contentDescription = stringResource(R.string.cd_vote), - tint = MaterialTheme.colorScheme.outline, - modifier = Modifier.size(20.dp) - ) - } - } - - Spacer(modifier = Modifier.width(12.dp)) - - Text( - text = option.text, - style = MaterialTheme.typography.bodyMedium, - color = if (showResults && (isCorrect || isWrong)) stateColor else baseContentColor, - maxLines = 3, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.weight(1f) - ) - - if (showResults) { - Spacer(modifier = Modifier.width(8.dp)) - if (isCorrect || isWrong || option.isChosen) { - Text( - text = "${option.votePercentage}%", - style = MaterialTheme.typography.labelMedium, - fontWeight = FontWeight.Bold, - color = stateColor - ) - } - } - } - } -} - -@Composable -private fun QuizExplanationBox( - text: String, - containerColor: Color, - textColor: Color -) { - Column(modifier = Modifier.padding(top = 12.dp)) { - Surface( - shape = RoundedCornerShape(8.dp), - color = containerColor - ) { - Row( - modifier = Modifier.padding(8.dp), - verticalAlignment = Alignment.Top - ) { - Icon( - imageVector = Icons.Default.Lightbulb, - contentDescription = stringResource(R.string.cd_explanation), - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier - .size(16.dp) - .padding(top = 2.dp) - ) - Spacer(modifier = Modifier.width(8.dp)) - Text( - text = text, - style = MaterialTheme.typography.bodySmall, - color = textColor - ) - } - } - } -} - -@Composable -private fun PollFooter( - totalVotes: Int, - date: Int, - isOutgoing: Boolean, - sendingState: MessageSendingState?, - isRead: Boolean, - contentColor: Color -) { - val metaColor = contentColor.copy(alpha = 0.65f) - - Row( - modifier = Modifier - .fillMaxWidth() - .padding(top = 8.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = pluralStringResource(R.plurals.poll_votes_count, totalVotes, totalVotes), - style = MaterialTheme.typography.labelSmall, - color = metaColor - ) - } - - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = formatTime(date), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 10.sp), - color = metaColor - ) - - if (isOutgoing) { - Spacer(modifier = Modifier.width(4.dp)) - val (icon, tint) = when (sendingState) { - is MessageSendingState.Pending -> Icons.Default.Schedule to metaColor - is MessageSendingState.Failed -> Icons.Default.Error to MaterialTheme.colorScheme.error - null -> if (isRead) Icons.Default.DoneAll to MaterialTheme.colorScheme.primary - else Icons.Default.Check to metaColor - } - - Icon( - imageVector = icon, - contentDescription = null, - modifier = Modifier.size(14.dp), - tint = tint - ) - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/PollVotersSheet.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/PollVotersSheet.kt deleted file mode 100644 index 747805f9..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/PollVotersSheet.kt +++ /dev/null @@ -1,182 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Favorite -import androidx.compose.material.icons.rounded.Verified -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.UserModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun PollVotersSheet( - voters: List, - isLoading: Boolean, - videoPlayerPool: VideoPlayerPool, - onUserClick: (Long) -> Unit, - onDismiss: () -> Unit -) { - ModalBottomSheet( - onDismissRequest = onDismiss, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 32.dp) - ) { - Text( - text = stringResource(R.string.poll_voters_title), - style = MaterialTheme.typography.titleLarge, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp) - ) - - if (isLoading && voters.isEmpty()) { - Box( - modifier = Modifier - .fillMaxWidth() - .height(200.dp), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator() - } - } else if (voters.isEmpty()) { - Box( - modifier = Modifier - .fillMaxWidth() - .height(200.dp), - contentAlignment = Alignment.Center - ) { - Text( - text = stringResource(R.string.poll_no_voters), - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } else { - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - ) { - LazyColumn( - modifier = Modifier.fillMaxWidth() - ) { - itemsIndexed(voters) { index, user -> - VoterItem( - user = user, - videoPlayerPool = videoPlayerPool, - onClick = { onUserClick(user.id) } - ) - if (index < voters.size - 1) { - HorizontalDivider( - modifier = Modifier.padding(horizontal = 16.dp), - thickness = 0.5.dp, - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - } - } - } - } - } - - Spacer(modifier = Modifier.height(24.dp)) - - Box(modifier = Modifier.padding(horizontal = 16.dp)) { - Button( - onClick = onDismiss, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text( - text = stringResource(R.string.action_close), - fontSize = 16.sp, - fontWeight = FontWeight.Bold - ) - } - } - } - } -} - -@Composable -private fun VoterItem( - user: UserModel, - videoPlayerPool: VideoPlayerPool, - onClick: () -> Unit -) { - Row( - modifier = Modifier - .fillMaxWidth() - .clickable(onClick = onClick) - .padding(horizontal = 16.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Avatar( - path = user.avatarPath, - fallbackPath = user.personalAvatarPath, - name = user.firstName, - size = 40.dp, - videoPlayerPool = videoPlayerPool - ) - Spacer(modifier = Modifier.width(12.dp)) - Column(modifier = Modifier.weight(1f)) { - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = "${user.firstName} ${user.lastName ?: ""}".trim(), - style = MaterialTheme.typography.bodyLarge, - fontWeight = FontWeight.Medium, - modifier = Modifier.weight(1f, fill = false) - ) - if (user.isVerified) { - Spacer(Modifier.width(4.dp)) - Icon( - imageVector = Icons.Rounded.Verified, - contentDescription = stringResource(R.string.cd_verified), - modifier = Modifier.size(16.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - if (user.isSponsor) { - Spacer(Modifier.width(4.dp)) - Icon( - imageVector = Icons.Default.Favorite, - contentDescription = stringResource(R.string.cd_sponsor), - modifier = Modifier.size(16.dp), - tint = Color(0xFFE53935) - ) - } - } - user.username?.let { - Text( - text = "@$it", - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/ReplyContent.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/ReplyContent.kt deleted file mode 100644 index 8391ac5a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/ReplyContent.kt +++ /dev/null @@ -1,93 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.R - -@Composable -fun ReplyContent( - replyToMsg: MessageModel, - isOutgoing: Boolean, - onClick: () -> Unit = {} -) { - Row( - modifier = Modifier - .padding(bottom = 4.dp) - .clip(RoundedCornerShape(4.dp)) - .background( - if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.1f) - else MaterialTheme.colorScheme.onSurface.copy(alpha = 0.05f) - ) - .clickable { onClick() } - .padding(4.dp) - .fillMaxWidth() - ) { - Box( - modifier = Modifier - .width(2.dp) - .height(32.dp) - .background( - if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer - else MaterialTheme.colorScheme.primary, - RoundedCornerShape(2.dp) - ) - ) - - Spacer(modifier = Modifier.width(8.dp)) - - Column { - Text( - text = replyToMsg.senderName, - style = MaterialTheme.typography.labelSmall, - color = if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer - else MaterialTheme.colorScheme.primary, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - - val (rawText, entities) = when (val content = replyToMsg.content) { - is MessageContent.Text -> content.text to content.entities - is MessageContent.Photo -> content.caption.ifEmpty { stringResource(R.string.reply_content_photo) } to content.entities - is MessageContent.Video -> content.caption.ifEmpty { stringResource(R.string.reply_content_video) } to content.entities - is MessageContent.Sticker -> stringResource(R.string.reply_content_sticker) to emptyList() - is MessageContent.Voice -> stringResource(R.string.reply_content_voice_message) to emptyList() - is MessageContent.VideoNote -> stringResource(R.string.reply_content_video_message) to emptyList() - is MessageContent.Gif -> content.caption.ifEmpty { stringResource(R.string.reply_content_gif) } to content.entities - is MessageContent.Document -> (content.caption.ifEmpty { content.fileName }) to content.entities - else -> stringResource(R.string.reply_content_message) to emptyList() - } - - val annotatedText = buildAnnotatedMessageTextWithEmoji( - text = rawText, - entities = entities - ) - - val inlineContent = rememberMessageInlineContent( - entities = entities, - fontSize = MaterialTheme.typography.bodySmall.fontSize.value - ) - - Text( - text = annotatedText, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodySmall, - color = if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.8f) - else MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/ReplyMarkupView.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/ReplyMarkupView.kt deleted file mode 100644 index 9e65a526..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/ReplyMarkupView.kt +++ /dev/null @@ -1,170 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Language -import androidx.compose.material.icons.rounded.Link -import androidx.compose.material.icons.rounded.Person -import androidx.compose.material.icons.rounded.ShoppingCart -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.hapticfeedback.HapticFeedbackType -import androidx.compose.ui.platform.LocalClipboardManager -import androidx.compose.ui.platform.LocalHapticFeedback -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.InlineKeyboardButtonModel -import org.monogram.domain.models.InlineKeyboardButtonType -import org.monogram.domain.models.ReplyMarkupModel -import org.monogram.presentation.core.ui.ItemPosition - -@Composable -fun ReplyMarkupView( - replyMarkup: ReplyMarkupModel, - onButtonClick: (InlineKeyboardButtonModel) -> Unit, - modifier: Modifier = Modifier -) { - when (replyMarkup) { - is ReplyMarkupModel.InlineKeyboard -> { - Column( - modifier = modifier - .padding(top = 4.dp) - .fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(2.dp) - ) { - replyMarkup.rows.forEachIndexed { index, row -> - val position = when { - replyMarkup.rows.size == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == replyMarkup.rows.size - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(2.dp) - ) { - row.forEach { button -> - InlineKeyboardButtonView( - button = button, - onClick = { onButtonClick(button) }, - position = position, - modifier = Modifier.weight(1f) - ) - } - } - } - } - } - - else -> {} - } -} - -@OptIn(ExperimentalFoundationApi::class) -@Composable -private fun InlineKeyboardButtonView( - button: InlineKeyboardButtonModel, - onClick: () -> Unit, - position: ItemPosition, - modifier: Modifier = Modifier -) { - val clipboardManager = LocalClipboardManager.current - val haptic = LocalHapticFeedback.current - - val icon = when (button.type) { - is InlineKeyboardButtonType.Url -> Icons.Rounded.Link - is InlineKeyboardButtonType.WebApp -> Icons.Rounded.Language - is InlineKeyboardButtonType.Buy -> Icons.Rounded.ShoppingCart - is InlineKeyboardButtonType.User -> Icons.Rounded.Person - else -> null - } - - val cornerRadius = 12.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 2.dp, - bottomEnd = 2.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(2.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 2.dp, - topEnd = 2.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = modifier - .clip(shape) - .combinedClickable( - onClick = onClick, - onLongClick = { - val dataToCopy = when (val type = button.type) { - is InlineKeyboardButtonType.Callback -> String(type.data) - is InlineKeyboardButtonType.Url -> type.url - is InlineKeyboardButtonType.WebApp -> type.url - is InlineKeyboardButtonType.SwitchInline -> type.query - else -> null - } - if (dataToCopy != null) { - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - clipboardManager.setText(AnnotatedString(dataToCopy)) - } - } - ) - ) { - Row( - modifier = Modifier - .padding(horizontal = 8.dp, vertical = 10.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Center - ) { - if (icon != null) { - Box( - modifier = Modifier - .size(24.dp) - .background( - color = MaterialTheme.colorScheme.primary.copy(alpha = 0.15f), - shape = CircleShape - ), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = icon, - contentDescription = null, - modifier = Modifier.size(14.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - Spacer(modifier = Modifier.width(8.dp)) - } - Text( - text = button.text, - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.onSurface, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/SpoilerShader.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/SpoilerShader.kt deleted file mode 100644 index 4305bf2c..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/SpoilerShader.kt +++ /dev/null @@ -1,126 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import android.os.Build -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.ClipOp -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.drawscope.DrawScope -import androidx.compose.ui.graphics.drawscope.clipPath -import androidx.compose.ui.text.TextLayoutResult -import org.intellij.lang.annotations.Language -import kotlin.math.sin - -object SpoilerShader { - @Language("AGSL") - const val SHADER_CODE = """ -uniform float2 resolution; -uniform float time; -layout(color) uniform half4 particleColor; - -float hash(float2 p) { - return fract(sin(dot(p, float2(12.9898, 78.233))) * 43758.5453); -} - -float2 getFlow(float2 p, float t) { - float freq = 0.01; - float speed = 0.5; - float n1 = sin(p.y * freq + t * speed); - float n2 = cos(p.x * freq + t * speed); - return float2(n1, n2); -} - -half4 main(float2 coord) { - float spacing = 15.0; - float2 currentGrid = floor(coord / spacing); - - float intensity = 0.0; - - for (int x = -1; x <= 1; x++) { - for (int y = -1; y <= 1; y++) { - float2 gridId = currentGrid + float2(x, y); - - float seed = hash(gridId); - - float t = fract(time * 0.2 + seed); - float alpha_pulse = sin(t * 3.14159); - - float2 origin = (gridId + 0.5) * spacing; - float2 randOffset = (float2(hash(gridId + 4.0), hash(gridId + 9.0)) - 0.5) * spacing; - - float2 flow = getFlow(origin, time); - float2 position = origin + randOffset + flow * 40.0 * t; - - float dist = distance(coord, position); - float r = 1.2 + seed * 1.8; - - intensity += smoothstep(r, r - 1.0, dist) * alpha_pulse * (0.3 + 0.7 * seed); - } - } - - intensity = clamp(intensity, 0.0, 1.2); - return half4(particleColor.rgb * intensity, intensity); -} -""" -} - -@Composable -fun SpoilerWrapper( - isRevealed: Boolean, - modifier: Modifier = Modifier, - content: @Composable () -> Unit -) { - Box(modifier = modifier) { - content() - if (!isRevealed) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - AnimatedSpoilerEffectApi33() - } else { - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.Gray.copy(alpha = 0.5f)) - ) - } - } - } -} - -fun DrawScope.drawSpoilerEffectFallback( - layoutResult: TextLayoutResult, - start: Int, - end: Int, - time: Float, - color: Color -) { - val path = layoutResult.getPathForRange(start, end) - drawPath(path = path, color = color.copy(alpha = 0.5f)) - - val bounds = path.getBounds() - val spacing = 11f - val phase = (time * 24f) % spacing - - clipPath(path, clipOp = ClipOp.Intersect) { - var y = bounds.top - spacing + phase - while (y <= bounds.bottom + spacing) { - val rowOffset = if (((y / spacing).toInt() and 1) == 0) 0f else spacing * 0.5f - var x = bounds.left - spacing + rowOffset - - while (x <= bounds.right + spacing) { - val pulse = ((sin((x + y) * 0.07f + time * 3.6f) + 1f) * 0.5f) - drawCircle( - color = color.copy(alpha = 0.10f + 0.22f * pulse), - radius = 1.0f + 1.2f * pulse, - center = Offset(x, y) - ) - x += spacing - } - - y += spacing - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/SpoilerShaderApi33.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/SpoilerShaderApi33.kt deleted file mode 100644 index eb70a536..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/SpoilerShaderApi33.kt +++ /dev/null @@ -1,69 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import android.graphics.RuntimeShader -import android.os.Build -import androidx.annotation.RequiresApi -import androidx.compose.animation.core.withInfiniteAnimationFrameMillis -import androidx.compose.foundation.Canvas -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.produceState -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.ShaderBrush -import androidx.compose.ui.graphics.drawscope.DrawScope -import androidx.compose.ui.graphics.toArgb -import androidx.compose.ui.text.TextLayoutResult - -@RequiresApi(Build.VERSION_CODES.TIRAMISU) -object SpoilerShaderApi33 { - fun createShader(shaderCode: String): Any = RuntimeShader(shaderCode) -} - -@RequiresApi(Build.VERSION_CODES.TIRAMISU) -fun DrawScope.drawSpoilerEffectApi33( - layoutResult: TextLayoutResult, - start: Int, - end: Int, - shader: Any, - time: Float, - color: Color -) { - val runtimeShader = shader as RuntimeShader - val path = layoutResult.getPathForRange(start, end) - runtimeShader.setFloatUniform("resolution", size.width, size.height) - runtimeShader.setFloatUniform("time", time) - runtimeShader.setColorUniform("particleColor", color.toArgb()) - - drawPath( - path = path, - brush = ShaderBrush(runtimeShader) - ) -} - -@RequiresApi(Build.VERSION_CODES.TIRAMISU) -@Composable -fun AnimatedSpoilerEffectApi33( - modifier: Modifier = Modifier, - color: Color = Color.Gray -) { - val time by produceState(0f) { - while (true) { - withInfiniteAnimationFrameMillis { - value = it / 1000f - } - } - } - - val shader = remember { RuntimeShader(SpoilerShader.SHADER_CODE) } - - Canvas(modifier = modifier.fillMaxSize()) { - shader.setFloatUniform("resolution", size.width, size.height) - shader.setFloatUniform("time", time) - shader.setColorUniform("particleColor", color.toArgb()) - - drawRect(brush = ShaderBrush(shader)) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/StickerMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/StickerMessageBubble.kt deleted file mode 100644 index cc7e8547..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/StickerMessageBubble.kt +++ /dev/null @@ -1,166 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.annotation.OptIn -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Download -import androidx.compose.material.icons.filled.Edit -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.media3.common.util.UnstableApi -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.domain.models.StickerModel -import org.monogram.presentation.features.stickers.ui.view.StickerImage -import org.monogram.presentation.features.stickers.ui.view.StickerSkeleton -import java.io.File - -@OptIn(UnstableApi::class, ExperimentalFoundationApi::class) -@Composable -fun StickerMessageBubble( - content: MessageContent.Sticker, - msg: MessageModel, - isOutgoing: Boolean, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - onStickerClick: (Long) -> Unit = {}, - onLongClick: () -> Unit = {}, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier -) { - Column( - modifier = modifier, - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - msg.forwardInfo?.let { forward -> - Surface( - shape = RoundedCornerShape(12.dp), - color = MaterialTheme.colorScheme.surfaceContainerHigh, - modifier = Modifier - .padding(bottom = 4.dp) - .widthIn(max = 200.dp) - ) { - Box(modifier = Modifier.padding(8.dp)) { - ForwardContent(forward, isOutgoing = false, onForwardClick = toProfile) - } - } - } - msg.replyToMsg?.let { reply -> - Surface( - shape = RoundedCornerShape(12.dp), - color = MaterialTheme.colorScheme.surfaceContainerHigh, - modifier = Modifier - .padding(bottom = 4.dp) - .widthIn(max = 200.dp) - ) { - ReplyContent( - replyToMsg = reply, - isOutgoing = false, - onClick = { onReplyClick(reply) } - ) - } - } - - Box( - modifier = Modifier - .size(190.dp) - .combinedClickable( - onClick = { - onStickerClick(content.setId) - }, - onLongClick = onLongClick - ) - ) { - val validPath = content.path?.takeIf { it.isNotBlank() && File(it).exists() } - if (validPath != null) { - val stickerModel = StickerModel( - id = content.id, - width = content.width, - height = content.height, - emoji = content.emoji, - path = validPath, - format = content.format - ) - - StickerImage( - path = stickerModel.path, - animate = true, - modifier = Modifier.fillMaxSize(), - ) - } else { - Box( - modifier = Modifier - .fillMaxSize() - .clip(CircleShape), - contentAlignment = Alignment.Center - ) { - StickerSkeleton(modifier = Modifier.matchParentSize()) - - if (content.isDownloading) { - CircularProgressIndicator( - progress = { content.downloadProgress }, - modifier = Modifier.size(48.dp), - color = Color.White, - trackColor = Color.White.copy(alpha = 0.35f) - ) - } else { - Icon( - imageVector = Icons.Default.Download, - contentDescription = "Download", - modifier = Modifier.size(48.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f) - ) - } - } - } - - Row( - modifier = Modifier - .align(Alignment.BottomEnd) - .padding(4.dp), - verticalAlignment = Alignment.CenterVertically - ) { - if (msg.editDate > 0) { - Icon( - imageVector = Icons.Default.Edit, - contentDescription = "Edited", - modifier = Modifier.size(12.dp), - tint = Color.White - ) - Spacer(modifier = Modifier.width(4.dp)) - } - Text( - text = formatTime(msg.date), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 10.sp), - color = Color.White, - ) - if (isOutgoing) { - Spacer(modifier = Modifier.width(4.dp)) - MessageSendingStatusIcon( - sendingState = msg.sendingState, - isRead = msg.isRead, - baseColor = Color.White, - size = 12.dp, - usePrimaryForRead = false - ) - } - } - } - - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(horizontal = 4.dp) - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/TextMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/TextMessageBubble.kt deleted file mode 100644 index 1c8afada..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/TextMessageBubble.kt +++ /dev/null @@ -1,206 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.animation.* -import androidx.compose.animation.core.FastOutSlowInEasing -import androidx.compose.animation.core.tween -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Edit -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableStateListOf -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel - - -@Composable -fun TextMessageBubble( - content: MessageContent.Text, - msg: MessageModel, - isOutgoing: Boolean, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - letterSpacing: Float, - isGroup: Boolean = false, - bubbleRadius: Float = 18f, - showLinkPreviews: Boolean = true, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - onInstantViewClick: ((String) -> Unit)? = null, - onYouTubeClick: ((String) -> Unit)? = null, - onClick: (Offset) -> Unit = {}, - onLongClick: (Offset) -> Unit = {}, - showReactions: Boolean = true, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier -) { - val cornerRadius = bubbleRadius.dp - val smallCorner = (bubbleRadius / 4f).coerceAtLeast(4f).dp - val tailCorner = 2.dp - - val bubbleShape = remember(isOutgoing, isSameSenderAbove, isSameSenderBelow, cornerRadius, smallCorner) { - RoundedCornerShape( - topStart = if (!isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - topEnd = if (isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - bottomStart = if (!isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius, - bottomEnd = if (isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius - ) - } - - val backgroundColor = - if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh - val contentColor = - if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant - val timeColor = contentColor.copy(alpha = 0.7f) - - val revealedSpoilers = remember { mutableStateListOf() } - - Column( - modifier = modifier - .width(IntrinsicSize.Max) - .widthIn(min = 60.dp), - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = backgroundColor, - contentColor = contentColor, - tonalElevation = 1.dp - ) { - Column( - modifier = Modifier - .padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 6.dp) - .animateContentSize() - ) { - if (isGroup && !isOutgoing && !isSameSenderAbove) { - MessageSenderName(msg, toProfile = toProfile) - } - - msg.forwardInfo?.let { forward -> - ForwardContent(forward, isOutgoing, onForwardClick = toProfile) - } - msg.replyToMsg?.let { reply -> - ReplyContent( - replyToMsg = reply, - isOutgoing = isOutgoing, - onClick = { onReplyClick(reply) } - ) - } - - val inlineContent = rememberMessageInlineContent(content.entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = content.text, - entities = content.entities, - isOutgoing = isOutgoing, - revealedSpoilers = revealedSpoilers - ) - - val isBigEmoji = remember(content.text, content.entities) { - isBigEmoji(content.text, content.entities) - } - val finalFontSize = if (isBigEmoji) fontSize * 5f else fontSize - - AnimatedContent( - targetState = finalAnnotatedString, - transitionSpec = { - (fadeIn(animationSpec = tween(240, easing = FastOutSlowInEasing)) + - scaleIn(initialScale = 0.97f, animationSpec = tween(240, easing = FastOutSlowInEasing)) + - slideInVertically(initialOffsetY = { it / 8 }, animationSpec = tween(240, easing = FastOutSlowInEasing))) - .togetherWith( - fadeOut(animationSpec = tween(180)) + - scaleOut(targetScale = 0.99f, animationSpec = tween(180)) + - slideOutVertically(targetOffsetY = { -it / 10 }, animationSpec = tween(180)) - ) - }, - label = "TextEditAnimation" - ) { targetText -> - MessageText( - text = targetText, - entities = content.entities, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = finalFontSize.sp, - letterSpacing = letterSpacing.sp, - lineHeight = (finalFontSize * 1.1f).sp - ), - modifier = Modifier.padding(bottom = 2.dp), - isOutgoing = isOutgoing, - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = onClick, - onLongClick = onLongClick - ) - } - - if (showLinkPreviews) { - content.webPage?.let { webPage -> - LinkPreview( - webPage = webPage, - isOutgoing = msg.isOutgoing, - onInstantViewClick = onInstantViewClick, - onYouTubeClick = onYouTubeClick - ) - } - } - - Row( - modifier = Modifier.align(Alignment.End), - verticalAlignment = Alignment.CenterVertically - ) { - if (msg.editDate > 0) { - Icon( - imageVector = Icons.Default.Edit, - contentDescription = "Edited", - modifier = Modifier.size(14.dp), - tint = timeColor - ) - Spacer(modifier = Modifier.width(4.dp)) - } - Text( - text = formatTime(msg.date), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 11.sp), - color = timeColor - ) - - if (isOutgoing) { - Spacer(modifier = Modifier.width(4.dp)) - MessageSendingStatusIcon( - sendingState = msg.sendingState, - isRead = msg.isRead, - baseColor = timeColor, - size = 14.dp - ) - } - } - } - } - - if (showReactions) { - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(horizontal = 4.dp) - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/VideoMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/VideoMessageBubble.kt deleted file mode 100644 index 136741a0..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/VideoMessageBubble.kt +++ /dev/null @@ -1,432 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.animation.animateContentSize -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.VolumeOff -import androidx.compose.material.icons.automirrored.filled.VolumeUp -import androidx.compose.material.icons.filled.Download -import androidx.compose.material.icons.filled.PlayArrow -import androidx.compose.material.icons.rounded.Stream -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.blur -import androidx.compose.ui.draw.clipToBounds -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.layout.boundsInWindow -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.zIndex -import coil3.compose.rememberAsyncImagePainter -import coil3.request.ImageRequest -import coil3.request.crossfade -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.AutoDownloadSuppression -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.chats.currentChat.components.VideoStickerPlayer -import org.monogram.presentation.features.chats.currentChat.components.VideoType - -@Composable -fun VideoMessageBubble( - content: MessageContent.Video, - msg: MessageModel, - isOutgoing: Boolean, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - letterSpacing: Float, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - autoplayVideos: Boolean, - onVideoClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit = {}, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - showMetadata: Boolean = true, - showReactions: Boolean = true, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - isAnyViewerOpen: Boolean = false -) { - val cornerRadius = 18.dp - val smallCorner = 4.dp - val tailCorner = 2.dp - - val context = LocalContext.current - var stablePath by remember(msg.id, content.fileId) { mutableStateOf(content.path) } - val hasPath = !stablePath.isNullOrBlank() - var isAutoDownloadSuppressed by remember(msg.id, content.fileId) { mutableStateOf(false) } - - LaunchedEffect(content.path, content.fileId) { - if (!content.path.isNullOrBlank()) { - stablePath = content.path - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(content.fileId) - } else { - stablePath = null - } - } - - LaunchedEffect(content.path, content.isDownloading, autoDownloadMobile, autoDownloadWifi, autoDownloadRoaming) { - if (content.path.isNullOrBlank() && !content.isDownloading && !content.supportsStreaming && !isAutoDownloadSuppressed && !AutoDownloadSuppression.isSuppressed( - content.fileId - ) - ) { - val shouldDownload = when { - downloadUtils.isWifiConnected() -> autoDownloadWifi - downloadUtils.isRoaming() -> autoDownloadRoaming - else -> autoDownloadMobile - } - if (shouldDownload) { - onVideoClick(msg) - } - } - } - - val topStart = if (!isOutgoing && isSameSenderAbove) smallCorner else cornerRadius - val topEnd = if (isOutgoing && isSameSenderAbove) smallCorner else cornerRadius - val bottomStart = if (!isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius - val bottomEnd = if (isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius - - val bubbleShape = RoundedCornerShape( - topStart = topStart, - topEnd = topEnd, - bottomEnd = bottomEnd, - bottomStart = bottomStart - ) - - var videoPosition by remember { mutableStateOf(Offset.Zero) } - var isMuted by remember { mutableStateOf(true) } - var currentPositionSeconds by remember { mutableIntStateOf(0) } - var isVisible by remember { mutableStateOf(false) } - - val screenHeightPx = remember { context.resources.displayMetrics.heightPixels } - val revealedSpoilers = remember { mutableStateListOf() } - var isMediaSpoilerRevealed by remember { mutableStateOf(!content.hasSpoiler) } - - Column( - modifier = modifier.onGloballyPositioned { - val rect = it.boundsInWindow() - isVisible = rect.bottom > 0 && rect.top < screenHeightPx - }, - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh, - contentColor = if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant, - ) { - Column(modifier = Modifier - .widthIn(max = 280.dp) - .animateContentSize()) { - msg.forwardInfo?.let { forward -> - Box( - modifier = Modifier - .fillMaxWidth() - .background(if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(horizontal = 12.dp, vertical = 4.dp) - .zIndex(1f) - ) { - ForwardContent(forward, isOutgoing, onForwardClick = toProfile) - } - } - msg.replyToMsg?.let { reply -> - Box( - modifier = Modifier - .fillMaxWidth() - .background(if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(horizontal = 4.dp, vertical = 4.dp) - .zIndex(1f) - ) { - ReplyContent( - replyToMsg = reply, - isOutgoing = isOutgoing, - onClick = { onReplyClick(reply) } - ) - } - } - - val ratio = if (content.width > 0 && content.height > 0) - (content.width.toFloat() / content.height.toFloat()).coerceIn(0.5f, 2f) - else 1f - - Box( - modifier = Modifier - .fillMaxWidth() - .heightIn(min = 160.dp, max = 360.dp) - .aspectRatio(ratio) - .clipToBounds() - .onGloballyPositioned { videoPosition = it.positionInWindow() } - .pointerInput(Unit) { - detectTapGestures( - onTap = { - if (!isMediaSpoilerRevealed) { - isMediaSpoilerRevealed = true - } else if (content.isDownloading) { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(content.fileId) - onCancelDownload(content.fileId) - } else { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(content.fileId) - onVideoClick(msg) - } - }, - onLongPress = { offset -> onLongClick(videoPosition + offset) } - ) - } - ) { - if (hasPath || content.supportsStreaming) { - if (autoplayVideos) { - val videoPath = stablePath ?: "http://streaming/${content.fileId}" - VideoStickerPlayer( - path = videoPath, - type = VideoType.Gif, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Fit, - animate = isVisible && !isAnyViewerOpen, - volume = if (isMuted) 0f else 1f, - reportProgress = true, - onProgressUpdate = { pos -> - val seconds = (pos / 1000).toInt() - if (seconds != currentPositionSeconds) { - currentPositionSeconds = seconds - } - }, - videoPlayerPool = videoPlayerPool, - fileId = if (!hasPath && content.supportsStreaming) content.fileId else 0, - thumbnailData = content.minithumbnail - ) - - Box( - modifier = Modifier - .align(Alignment.TopEnd) - .padding(8.dp) - .size(30.dp) - .background(Color.Black.copy(alpha = 0.45f), CircleShape) - .clickable { isMuted = !isMuted }, - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = if (isMuted) Icons.AutoMirrored.Filled.VolumeOff else Icons.AutoMirrored.Filled.VolumeUp, - contentDescription = "Toggle Sound", - tint = Color.White, - modifier = Modifier.size(16.dp) - ) - } - } else { - if (hasPath) { - Image( - painter = rememberAsyncImagePainter( - model = ImageRequest.Builder(context) - .data(stablePath) - .crossfade(true) - .build() - ), - contentDescription = content.caption, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Fit - ) - } else { - if (content.minithumbnail != null) { - Image( - painter = rememberAsyncImagePainter(content.minithumbnail), - contentDescription = null, - modifier = Modifier - .fillMaxSize() - .blur(10.dp), - contentScale = ContentScale.Fit - ) - } - } - - Box( - modifier = Modifier - .align(Alignment.Center) - .size(48.dp) - .background(Color.Black.copy(alpha = 0.45f), CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Default.PlayArrow, - contentDescription = "Play", - tint = Color.White, - modifier = Modifier.size(32.dp) - ) - } - } - } else { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - MediaLoadingBackground( - previewData = content.minithumbnail, - contentScale = ContentScale.Fit, - previewBlur = 14.dp - ) - - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.Black.copy(alpha = 0.25f)) - ) - - MediaLoadingAction( - isDownloading = content.isDownloading, - progress = content.downloadProgress, - idleIcon = if (content.supportsStreaming) Icons.Rounded.Stream else Icons.Default.Download, - idleContentDescription = if (content.supportsStreaming) "Stream" else "Download", - onCancelClick = { - isAutoDownloadSuppressed = true - AutoDownloadSuppression.suppress(content.fileId) - onCancelDownload(content.fileId) - }, - onIdleClick = { - isAutoDownloadSuppressed = false - AutoDownloadSuppression.clear(content.fileId) - onVideoClick(msg) - } - ) - } - } - - Box( - modifier = Modifier - .align(Alignment.TopStart) - .padding(8.dp) - .background(Color.Black.copy(alpha = 0.45f), RoundedCornerShape(6.dp)) - .padding(horizontal = 6.dp, vertical = 2.dp) - ) { - Text( - text = if ((hasPath || content.supportsStreaming) && autoplayVideos) { - "${formatDuration(currentPositionSeconds)} / ${formatDuration(content.duration)}" - } else { - formatDuration(content.duration) - }, - style = MaterialTheme.typography.labelSmall, - color = Color.White - ) - } - - if (content.isUploading) { - Box( - modifier = Modifier - .matchParentSize() - .background(Color.Black.copy(alpha = 0.5f)), - contentAlignment = Alignment.Center - ) { - if (content.uploadProgress > 0f) { - CircularProgressIndicator( - progress = { content.uploadProgress }, - color = Color.White, - trackColor = Color.White.copy(alpha = 0.3f) - ) - } else { - CircularProgressIndicator( - color = Color.White - ) - } - } - } - - SpoilerWrapper(isRevealed = isMediaSpoilerRevealed) { - Box(modifier = Modifier.fillMaxSize()) - } - - if (content.caption.isEmpty() && showMetadata) { - Box( - modifier = Modifier - .align(Alignment.BottomEnd) - .padding(6.dp) - .background(Color.Black.copy(alpha = 0.45f), RoundedCornerShape(12.dp)) - .padding(horizontal = 6.dp, vertical = 2.dp) - ) { - MessageMetadata(msg, isOutgoing, Color.White) - } - } - } - - if (content.caption.isNotEmpty()) { - val timeColor = if (isOutgoing) - MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.7f) - else - MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f) - - Column( - modifier = Modifier - .fillMaxWidth() - .background(if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh) - .padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 12.dp) - .zIndex(1f) - ) { - val inlineContent = rememberMessageInlineContent(content.entities, fontSize) - val finalAnnotatedString = buildAnnotatedMessageTextWithEmoji( - text = content.caption, - entities = content.entities, - isOutgoing = isOutgoing, - revealedSpoilers = revealedSpoilers - ) - - MessageText( - text = finalAnnotatedString, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = fontSize.sp, - letterSpacing = letterSpacing.sp, - lineHeight = (fontSize * 1.375f).sp - ), - modifier = Modifier.padding(bottom = 4.dp), - onSpoilerClick = { index -> - if (revealedSpoilers.contains(index)) { - revealedSpoilers.remove(index) - } else { - revealedSpoilers.add(index) - } - }, - onClick = { offset -> onLongClick(videoPosition + offset) }, - onLongClick = { offset -> onLongClick(videoPosition + offset) } - ) - if (showMetadata) { - Box(modifier = Modifier.align(Alignment.End)) { - MessageMetadata(msg, isOutgoing, timeColor) - } - } - } - } - } - } - - if (showReactions) { - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(horizontal = 4.dp) - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/VideoNoteBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/VideoNoteBubble.kt deleted file mode 100644 index 776a2680..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/VideoNoteBubble.kt +++ /dev/null @@ -1,360 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import android.net.Uri -import android.view.ViewGroup.LayoutParams.MATCH_PARENT -import android.widget.FrameLayout -import androidx.annotation.OptIn -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.VolumeOff -import androidx.compose.material.icons.automirrored.filled.VolumeUp -import androidx.compose.material.icons.filled.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.viewinterop.AndroidView -import androidx.media3.common.MediaItem -import androidx.media3.common.MimeTypes -import androidx.media3.common.PlaybackException -import androidx.media3.common.Player -import androidx.media3.common.util.UnstableApi -import androidx.media3.exoplayer.ExoPlayer -import androidx.media3.exoplayer.source.DefaultMediaSourceFactory -import androidx.media3.extractor.DefaultExtractorsFactory -import androidx.media3.extractor.mp4.Mp4Extractor -import androidx.media3.ui.AspectRatioFrameLayout -import androidx.media3.ui.PlayerView -import coil3.compose.rememberAsyncImagePainter -import kotlinx.coroutines.delay -import kotlinx.coroutines.isActive -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.core.util.getMimeType -import org.monogram.presentation.features.stickers.ui.view.shimmerEffect -import java.io.File -import java.io.FileNotFoundException - -@OptIn(UnstableApi::class) -@Composable -fun VideoNoteBubble( - content: MessageContent.VideoNote, - msg: MessageModel, - isOutgoing: Boolean, - onVideoClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit = {}, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier -) { - val size = 260.dp - var notePosition by remember { mutableStateOf(Offset.Zero) } - - Column( - modifier = modifier, - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - msg.forwardInfo?.let { forward -> - Surface( - shape = RoundedCornerShape(12.dp), - color = MaterialTheme.colorScheme.surfaceContainerHigh, - modifier = Modifier - .padding(bottom = 4.dp) - .widthIn(max = 200.dp) - ) { - Box(modifier = Modifier.padding(8.dp)) { - ForwardContent(forward, isOutgoing = false, onForwardClick = toProfile) - } - } - } - msg.replyToMsg?.let { reply -> - Surface( - shape = RoundedCornerShape(12.dp), - color = MaterialTheme.colorScheme.surfaceContainerHigh, - modifier = Modifier - .padding(bottom = 4.dp) - .widthIn(max = 200.dp) - ) { - ReplyContent( - replyToMsg = reply, - isOutgoing = false, - onClick = { onReplyClick(reply) } - ) - } - } - - - Box( - modifier = Modifier - .size(size) - .padding(4.dp) - ) { - val context = LocalContext.current - var isPlaying by remember { mutableStateOf(false) } - var isMuted by remember { mutableStateOf(true) } - var progress by remember { mutableFloatStateOf(0f) } - var hasError by remember { mutableStateOf(false) } - - - Box( - modifier = Modifier - .matchParentSize() - .clip(CircleShape) - .background(Color.Black) - .onGloballyPositioned { notePosition = it.positionInWindow() } - .pointerInput(content.path, content.isDownloading, hasError) { - detectTapGestures( - onTap = { - if (content.path != null && !hasError) { - isMuted = !isMuted - } else if (content.isDownloading) { - onCancelDownload(content.fileId) - } else { - onVideoClick(msg) - } - }, - onLongPress = { offset -> onLongClick(notePosition + offset) } - ) - } - ) { - if (content.path != null && File(content.path).exists() && !hasError) { - val exoPlayer = remember { - val extractorsFactory = DefaultExtractorsFactory() - .setConstantBitrateSeekingEnabled(true) - .setMp4ExtractorFlags(Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS) - - ExoPlayer.Builder(context) - .setMediaSourceFactory(DefaultMediaSourceFactory(context, extractorsFactory)) - .build().apply { - repeatMode = Player.REPEAT_MODE_ONE - val mediaItem = MediaItem.Builder() - .setUri(Uri.parse(content.path)) - .setMimeType(getMimeType(content.path!!) ?: MimeTypes.VIDEO_MP4) - .build() - setMediaItem(mediaItem) - prepare() - volume = 0f - playWhenReady = true - } - } - - DisposableEffect(exoPlayer) { - val listener = object : Player.Listener { - override fun onPlayerError(error: PlaybackException) { - if (error.cause is FileNotFoundException) { - hasError = true - } - } - } - exoPlayer.addListener(listener) - onDispose { - exoPlayer.removeListener(listener) - exoPlayer.release() - } - } - - LaunchedEffect(isMuted) { - exoPlayer.volume = if (isMuted) 0f else 1f - } - - LaunchedEffect(isPlaying) { - if (isPlaying) exoPlayer.play() else exoPlayer.pause() - } - - LaunchedEffect(Unit) { isPlaying = true } - - - LaunchedEffect(isPlaying) { - while (isActive && isPlaying) { - val current = exoPlayer.currentPosition - val total = exoPlayer.duration - if (total > 0) { - progress = current.toFloat() / total.toFloat() - } - delay(50) - } - } - - Box( - modifier = Modifier.matchParentSize() - ) { - AndroidView( - factory = { ctx -> - PlayerView(ctx).apply { - player = exoPlayer - useController = false - resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM - layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT) - } - }, - modifier = Modifier.matchParentSize() - ) - } - } else { - - if (content.thumbnail != null) { - Image( - painter = rememberAsyncImagePainter(content.thumbnail), - contentDescription = null, - modifier = Modifier.matchParentSize(), - contentScale = ContentScale.Crop - ) - } else { - Box( - modifier = Modifier - .matchParentSize() - .shimmerEffect(), - contentAlignment = Alignment.Center - ) { - if (content.isDownloading) { - CircularProgressIndicator( - progress = { content.downloadProgress }, - color = Color.White, - modifier = Modifier.size(48.dp) - ) - } else { - Icon( - imageVector = Icons.Default.Download, - contentDescription = "Download", - modifier = Modifier.size(48.dp), - tint = Color.White.copy(alpha = 0.5f) - ) - } - } - } - } - - - if (content.path != null && isPlaying && !hasError) { - Box(modifier = Modifier - .align(Alignment.TopCenter) - .padding(top = 16.dp)) { - Icon( - imageVector = if (isMuted) Icons.AutoMirrored.Filled.VolumeOff else Icons.AutoMirrored.Filled.VolumeUp, - contentDescription = "Mute", - tint = Color.White.copy(alpha = 0.8f), - modifier = Modifier.size(24.dp) - ) - } - } - } - - - if (content.isUploading) { - Box( - modifier = Modifier - .matchParentSize() - .background(Color.Black.copy(alpha = 0.5f), CircleShape), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator( - progress = { content.uploadProgress }, - color = Color.White, - strokeWidth = 3.dp, - modifier = Modifier.size(48.dp), - trackColor = Color.White.copy(alpha = 0.3f) - ) - } - } else if (content.path != null && !hasError) { - - CircularProgressIndicator( - progress = { progress }, - color = Color.White, - strokeWidth = 2.dp, - modifier = Modifier.matchParentSize(), - trackColor = Color.Transparent - ) - } - - - if (!isPlaying && content.path != null && !hasError) { - Box(modifier = Modifier.matchParentSize(), contentAlignment = Alignment.Center) { - Icon( - imageVector = Icons.Default.PlayArrow, - contentDescription = "Play", - modifier = Modifier - .size(48.dp) - .background(Color.Black.copy(0.4f), CircleShape) - .padding(8.dp) - .clickable { isPlaying = true }, - tint = Color.White - ) - } - } - - - Box( - modifier = Modifier - .align(Alignment.BottomStart) - .padding(4.dp) - .background(Color.Black.copy(alpha = 0.6f), RoundedCornerShape(12.dp)) - .padding(horizontal = 6.dp, vertical = 2.dp) - ) { - Text( - text = formatDuration(content.duration), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 11.sp), - color = Color.White - ) - } - - - Box( - modifier = Modifier - .align(Alignment.BottomEnd) - .padding(4.dp) - .background(Color.Black.copy(alpha = 0.6f), RoundedCornerShape(12.dp)) - .padding(horizontal = 6.dp, vertical = 2.dp) - ) { - Row(verticalAlignment = Alignment.CenterVertically) { - if (msg.editDate > 0) { - Icon( - imageVector = Icons.Default.Edit, - contentDescription = "Edited", - modifier = Modifier.size(12.dp), - tint = Color.White - ) - Spacer(modifier = Modifier.width(4.dp)) - } - Text( - text = formatTime(msg.date), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 11.sp), - color = Color.White - ) - if (isOutgoing) { - Spacer(modifier = Modifier.width(4.dp)) - Icon( - imageVector = if (msg.isRead) Icons.Default.DoneAll else Icons.Default.Check, - contentDescription = null, - modifier = Modifier.size(12.dp), - tint = Color.White - ) - } - } - } - } - - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(horizontal = 4.dp) - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/VoiceMessageBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/VoiceMessageBubble.kt deleted file mode 100644 index bc90e0e7..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/VoiceMessageBubble.kt +++ /dev/null @@ -1,336 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats - -import androidx.compose.foundation.Canvas -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.Download -import androidx.compose.material.icons.filled.Pause -import androidx.compose.material.icons.filled.PlayArrow -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.CornerRadius -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.geometry.Size -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.components.rememberVoicePlayer - -@Composable -fun VoiceMessageBubble( - content: MessageContent.Voice, - msg: MessageModel, - isOutgoing: Boolean, - isSameSenderAbove: Boolean, - isSameSenderBelow: Boolean, - fontSize: Float, - letterSpacing: Float, - autoDownloadFiles: Boolean, - autoDownloadMobile: Boolean, - autoDownloadWifi: Boolean, - autoDownloadRoaming: Boolean, - onVoiceClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit = {}, - onLongClick: (Offset) -> Unit, - onReplyClick: (MessageModel) -> Unit = {}, - onReactionClick: (String) -> Unit = {}, - isGroup: Boolean = false, - toProfile: (Long) -> Unit = {}, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils -) { - val cornerRadius = 18.dp - val smallCorner = 4.dp - val tailCorner = 2.dp - - LaunchedEffect( - content.path, - content.isDownloading, - autoDownloadFiles, - autoDownloadMobile, - autoDownloadWifi, - autoDownloadRoaming - ) { - val shouldDownload = if (autoDownloadFiles) { - when { - downloadUtils.isRoaming() -> autoDownloadRoaming - downloadUtils.isWifiConnected() -> autoDownloadWifi - else -> autoDownloadMobile - } - } else { - false - } - - if (shouldDownload && content.path == null && !content.isDownloading) { - onVoiceClick(msg) - } - } - - val bubbleShape = RoundedCornerShape( - topStart = if (!isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - topEnd = if (isOutgoing && isSameSenderAbove) smallCorner else cornerRadius, - bottomStart = if (!isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius, - bottomEnd = if (isOutgoing) { - if (isSameSenderBelow) smallCorner else tailCorner - } else cornerRadius - ) - - val backgroundColor = - if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh - val contentColor = - if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant - val timeColor = contentColor.copy(alpha = 0.7f) - - var bubblePosition by remember { mutableStateOf(Offset.Zero) } - - Column( - modifier = modifier - .onGloballyPositioned { bubblePosition = it.positionInWindow() }, - horizontalAlignment = if (isOutgoing) Alignment.End else Alignment.Start - ) { - Surface( - shape = bubbleShape, - color = backgroundColor, - contentColor = contentColor, - tonalElevation = 1.dp - ) { - Column( - modifier = Modifier - .padding(start = 8.dp, end = 8.dp, top = 8.dp, bottom = 6.dp) - .width(IntrinsicSize.Max) - .widthIn(min = 184.dp, max = 300.dp) - ) { - if (isGroup && !isOutgoing && !isSameSenderAbove) { - MessageSenderName(msg, toProfile = toProfile) - } - - msg.forwardInfo?.let { forward -> - Box(modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp)) { - ForwardContent(forward, isOutgoing, onForwardClick = toProfile) - } - } - msg.replyToMsg?.let { reply -> - Box(modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp)) { - ReplyContent( - replyToMsg = reply, - isOutgoing = isOutgoing, - onClick = { onReplyClick(reply) } - ) - } - } - - VoiceRow( - content = content, - msg = msg, - onVoiceClick = onVoiceClick, - onCancelDownload = onCancelDownload, - isOutgoing = isOutgoing - ) - - Box( - modifier = Modifier - .fillMaxWidth() - .padding(top = 2.dp), - contentAlignment = Alignment.CenterEnd - ) { - MessageMetadata(msg, isOutgoing, timeColor) - } - } - } - - MessageReactionsView( - reactions = msg.reactions, - onReactionClick = onReactionClick, - modifier = Modifier.padding(horizontal = 4.dp) - ) - } -} - -@Composable -fun VoiceRow( - content: MessageContent.Voice, - msg: MessageModel, - onVoiceClick: (MessageModel) -> Unit, - onCancelDownload: (Int) -> Unit, - isOutgoing: Boolean -) { - val playerState = rememberVoicePlayer(content.path) - playerState.ProgressUpdater() - - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 4.dp) - ) { - Box( - modifier = Modifier - .size(40.dp) - .clip(CircleShape) - .background(if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.primary) - .clickable { - if (content.isDownloading) { - onCancelDownload(content.fileId) - } else if (content.path == null) { - onVoiceClick(msg) - } else { - playerState.togglePlayPause() - } - }, - contentAlignment = Alignment.Center - ) { - if (content.isDownloading || content.isUploading) { - CircularProgressIndicator( - progress = { if (content.isDownloading) content.downloadProgress else content.uploadProgress }, - modifier = Modifier.size(32.dp), - color = if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.onPrimary, - strokeWidth = 2.dp, - trackColor = (if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.onPrimary).copy( - alpha = 0.2f - ), - ) - Icon( - imageVector = Icons.Default.Close, - contentDescription = "Cancel", - tint = if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.onPrimary, - modifier = Modifier.size(16.dp) - ) - } else { - val icon = when { - content.path == null -> Icons.Default.Download - playerState.isPlaying -> Icons.Default.Pause - else -> Icons.Default.PlayArrow - } - Icon( - imageVector = icon, - contentDescription = if (playerState.isPlaying) "Pause" else "Play", - tint = if (isOutgoing) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.onPrimary, - modifier = Modifier.size(24.dp) - ) - } - } - - Spacer(modifier = Modifier.width(12.dp)) - - Column( - modifier = Modifier.weight(1f) - ) { - WaveformView( - waveform = content.waveform, - progress = playerState.progress, - modifier = Modifier - .fillMaxWidth() - .height(32.dp), - activeColor = if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.primary, - inactiveColor = (if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant).copy( - alpha = 0.3f - ) - ) - - Text( - text = if (playerState.isPlaying || playerState.progress > 0) { - "${formatDuration((playerState.currentPosition / 1000).toInt())} / ${formatDuration(content.duration)}" - } else { - formatDuration(content.duration) - }, - style = MaterialTheme.typography.labelSmall.copy(fontSize = 11.sp), - color = (if (isOutgoing) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant).copy( - alpha = 0.7f - ) - ) - } - } -} - -@Composable -fun WaveformView( - waveform: ByteArray?, - progress: Float, - modifier: Modifier = Modifier, - activeColor: Color, - inactiveColor: Color -) { - Canvas(modifier = modifier) { - val width = size.width - val height = size.height - val barWidth = 2.dp.toPx() - val gap = 1.dp.toPx() - val totalBarWidth = barWidth + gap - - val barsCount = (width / totalBarWidth).toInt() - - if (waveform == null || waveform.isEmpty()) { - for (i in 0 until barsCount) { - val barHeight = (height * 0.2f).coerceAtLeast(2.dp.toPx()) - val x = i * totalBarWidth - val color = if (x / width <= progress) activeColor else inactiveColor - drawRoundRect( - color = color, - topLeft = Offset(x, (height - barHeight) / 2), - size = Size(barWidth, barHeight), - cornerRadius = CornerRadius(barWidth / 2) - ) - } - return@Canvas - } - - val samples = decodeWaveform(waveform, barsCount) - - samples.forEachIndexed { i, sample -> - val barHeight = (height * (sample / 31f)).coerceAtLeast(2.dp.toPx()) - val x = i * totalBarWidth - val color = if (i.toFloat() / barsCount <= progress) activeColor else inactiveColor - - drawRoundRect( - color = color, - topLeft = Offset(x, (height - barHeight) / 2), - size = Size(barWidth, barHeight), - cornerRadius = CornerRadius(barWidth / 2) - ) - } - } -} - -private fun decodeWaveform(waveform: ByteArray, count: Int): List { - val bitsCount = waveform.size * 8 - val samplesCount = bitsCount / 5 - if (samplesCount == 0) return List(count) { 0 } - - val result = mutableListOf() - for (i in 0 until samplesCount) { - var val5bit = 0 - for (j in 0 until 5) { - val bitIndex = i * 5 + j - val byteIndex = bitIndex / 8 - val bitInByte = bitIndex % 8 - if ((waveform[byteIndex].toInt() and (1 shl bitInByte)) != 0) { - val5bit = val5bit or (1 shl j) - } - } - result.add(val5bit) - } - - if (result.size == count) return result - - val resampled = mutableListOf() - for (i in 0 until count) { - val index = (i.toFloat() / count * result.size).toInt().coerceIn(0, result.size - 1) - resampled.add(result[index]) - } - return resampled -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/code/CodeHighlighter.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/code/CodeHighlighter.kt deleted file mode 100644 index 8d0571e4..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/code/CodeHighlighter.kt +++ /dev/null @@ -1,327 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats.code - -import androidx.compose.material3.ColorScheme -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.withStyle - -class CodeHighlighter { - private interface CodeTheme { - val Keyword: Color - val String: Color - val Comment: Color - val Number: Color - val Annotation: Color - val Type: Color - val Function: Color - val Field: Color - val Generic: Color - val Operator: Color - val Punctuation: Color - val Default: Color - } - - private object DarkTheme : CodeTheme { - override val Keyword = Color(0xFFCC7832) - override val String = Color(0xFF6A8759) - override val Comment = Color(0xFF808080) - override val Number = Color(0xFF6897BB) - override val Annotation = Color(0xFFBBB529) - override val Type = Color(0xFF769AA5) - override val Function = Color(0xFFA9B7C6) - override val Field = Color(0xFF9876AA) - override val Generic = Color(0xFFB8D7A3) - override val Operator = Color(0xFFD4D4D4) - override val Punctuation = Color(0xFFBBBBBB) - override val Default = Color(0xFFA9B7C6) - } - - private object LightTheme : CodeTheme { - override val Keyword = Color(0xFF0033B3) - override val String = Color(0xFF067D17) - override val Comment = Color(0xFF8A8A8A) - override val Number = Color(0xFF1750EB) - override val Annotation = Color(0xFF795E26) - override val Type = Color(0xFF267F99) - override val Function = Color(0xFF6F42C1) - override val Field = Color(0xFF005CC5) - override val Generic = Color(0xFF22863A) - override val Operator = Color(0xFF24292E) - override val Punctuation = Color(0xFF586069) - override val Default = Color(0xFF24292E) - } - - private class DynamicTheme(scheme: ColorScheme) : CodeTheme { - override val Keyword = scheme.primary - override val String = scheme.tertiary - override val Comment = scheme.outline - override val Number = scheme.secondary - override val Annotation = scheme.primary - override val Type = scheme.primary - override val Function = scheme.secondary - override val Field = scheme.tertiary - override val Generic = scheme.secondary - override val Operator = scheme.onSurfaceVariant - override val Punctuation = scheme.onSurfaceVariant - override val Default = scheme.onSurface - } - - private enum class TokenType { - Keyword, Type, Function, Variable, Field, - String, Number, Comment, Annotation, - Operator, Punctuation, GenericParameter, - Whitespace, Other - } - - private data class Token(val range: IntRange, val type: TokenType) - - private fun configFor(lang: String?): LanguageConfig = - when (lang?.lowercase()) { - "kotlin" -> kotlinConfig - "c", "cpp", "c++", "c#", "cs" -> cLikeConfig - "python", "py" -> pythonConfig - "javascript", "js", "typescript", "ts" -> jsTsConfig - "go", "golang" -> goConfig - "rust", "rs" -> rustConfig - "swift" -> swiftConfig - "sql" -> sqlConfig - "json" -> jsonConfig - "xml", "html" -> xmlConfig - "java" -> javaConfig - "bash", "sh", "zsh" -> bashConfig - "dockerfile" -> dockerConfig - "yaml", "yml" -> yamlConfig - "md", "markdown" -> markdownConfig - "ini" -> iniConfig - "toml" -> tomlConfig - "properties" -> propertiesConfig - "php" -> phpConfig - "ruby", "rb" -> rubyConfig - "lua" -> luaConfig - "haskell", "hs" -> haskellConfig - "r" -> rConfig - "matlab", "m" -> matlabConfig - "asm", "s" -> asmConfig - "proto" -> protoConfig - "graphql", "gql" -> graphqlConfig - "css" -> cssConfig - "scss", "sass" -> scssConfig - "regex", "regexp" -> regexConfig - "nginx" -> nginxConfig - "caddy" -> caddyConfig - else -> kotlinConfig - } - - fun highlight( - text: String, - language: String?, - isDark: Boolean = true, - scheme: ColorScheme? = null - ): AnnotatedString = buildAnnotatedString { - val theme = when { - scheme != null -> DynamicTheme(scheme) - isDark -> DarkTheme - else -> LightTheme - } - withStyle(SpanStyle(color = theme.Default, fontFamily = FontFamily.Monospace)) { - append(text) - } - - val cfg = configFor(language) - val tokens = tokenize(text, cfg) - - tokens.forEach { token -> - val style = styleFor(token.type, theme) ?: return@forEach - addStyle(style, token.range.first, token.range.last + 1) - } - } - - private fun tokenize(text: String, cfg: LanguageConfig): List { - val tokens = mutableListOf() - var i = 0 - val n = text.length - - fun isId(c: Char) = c.isLetterOrDigit() || c == '_' || c == '$' - fun starts(prefix: String) = text.startsWith(prefix, i) - - while (i < n) { - val c = text[i] - - // whitespace - if (c.isWhitespace()) { - val s = i - while (i < n && text[i].isWhitespace()) i++ - tokens += Token(s until i, TokenType.Whitespace) - continue - } - - // single-line comment - val sl = cfg.singleLineComment.firstOrNull { starts(it) } - if (sl != null) { - val s = i - i += sl.length - while (i < n && text[i] != '\n') i++ - tokens += Token(s until i, TokenType.Comment) - continue - } - - // block comment - if (cfg.blockStart != null && cfg.blockEnd != null && starts(cfg.blockStart)) { - val s = i - i += cfg.blockStart.length - val end = text.indexOf(cfg.blockEnd, i).let { if (it == -1) n else it + cfg.blockEnd.length } - i = end - tokens += Token(s until i, TokenType.Comment) - continue - } - - // strings - if (c == '"' || c == '\'') { - val quote = c - val s = i - i++ - var esc = false - while (i < n) { - val ch = text[i] - if (esc) esc = false - else if (ch == '\\') esc = true - else if (ch == quote) { - i++; break - } - i++ - } - tokens += Token(s until i.coerceAtMost(n), TokenType.String) - continue - } - - // annotation - if (c == '@' && cfg.supportsAnnotations) { - val s = i - i++ - while (i < n && isId(text[i])) i++ - tokens += Token(s until i, TokenType.Annotation) - continue - } - - // operators - val ops = listOf( - "==", "===", "!=", "!==", "<=", ">=", "->", "=>", "&&", "||", "::", - "+", "-", "*", "/", "%", "!", "?", "=", "<", ">", ".", ":", ";", "," - ) - val op = ops.firstOrNull { text.startsWith(it, i) } - if (op != null) { - tokens += Token(i until i + op.length, TokenType.Operator) - i += op.length - continue - } - - // punctuation - if (c in listOf('(', ')', '{', '}', '[', ']')) { - tokens += Token(i until i + 1, TokenType.Punctuation) - i++ - continue - } - - // numbers - if (c.isDigit()) { - val s = i - i++ - var dot = false - while (i < n) { - val ch = text[i] - if (ch == '.' && !dot) { - dot = true; i++ - } else if (ch.isDigit()) i++ - else break - } - tokens += Token(s until i, TokenType.Number) - continue - } - - // identifiers - if (c.isLetter() || c == '_' || c == '$') { - val s = i - i++ - while (i < n && isId(text[i])) i++ - val word = text.substring(s, i) - - val key = if (cfg.caseInsensitiveKeywords) word.uppercase() else word - val isKeyword = key in cfg.keywords - val isType = (!cfg.caseInsensitiveKeywords && (word in cfg.types || word.first().isUpperCase())) || - (cfg.caseInsensitiveKeywords && word.uppercase() in cfg.types.map { it.uppercase() }.toSet()) - val isConst = if (cfg.caseInsensitiveKeywords) - word.uppercase() in cfg.constants.map { it.uppercase() }.toSet() - else - word in cfg.constants - - val baseType = when { - isKeyword -> TokenType.Keyword - isType -> TokenType.Type - isConst -> TokenType.Number - else -> TokenType.Variable - } - - val next = text.indexOfFirstNonWs(i) - val isFunc = next != -1 && next < n && text[next] == '(' - - val prev = text.indexOfLastNonWs(s - 1) - val isField = prev != -1 && text[prev] == '.' - - val final = when { - baseType == TokenType.Keyword || baseType == TokenType.Type -> baseType - isFunc -> TokenType.Function - isField -> TokenType.Field - else -> TokenType.Variable - } - - tokens += Token(s until i, final) - continue - } - - tokens += Token(i until i + 1, TokenType.Other) - i++ - } - - // generics - val gen = Regex("<\\s*([A-Z][A-Za-z0-9_]*)\\s*>") - gen.findAll(text).forEach { - val r = it.groups[1]?.range ?: return@forEach - tokens += Token(r, TokenType.GenericParameter) - } - - return tokens.sortedBy { it.range.first } - } - - private fun styleFor(t: TokenType, theme: CodeTheme): SpanStyle? = when (t) { - TokenType.Keyword -> SpanStyle(color = theme.Keyword, fontWeight = FontWeight.Bold) - TokenType.Type -> SpanStyle(color = theme.Type, fontWeight = FontWeight.SemiBold) - TokenType.Function -> SpanStyle(color = theme.Function) - TokenType.Variable -> SpanStyle(color = theme.Default) - TokenType.Field -> SpanStyle(color = theme.Field) - TokenType.String -> SpanStyle(color = theme.String) - TokenType.Number -> SpanStyle(color = theme.Number) - TokenType.Comment -> SpanStyle(color = theme.Comment, fontStyle = FontStyle.Italic) - TokenType.Annotation -> SpanStyle(color = theme.Annotation) - TokenType.Operator -> SpanStyle(color = theme.Operator) - TokenType.Punctuation -> SpanStyle(color = theme.Punctuation) - TokenType.GenericParameter -> SpanStyle(color = theme.Generic, fontStyle = FontStyle.Italic) - TokenType.Whitespace, TokenType.Other -> null - } - - private fun String.indexOfFirstNonWs(from: Int): Int { - var i = from - while (i < length && this[i].isWhitespace()) i++ - return if (i >= length) -1 else i - } - - private fun String.indexOfLastNonWs(before: Int): Int { - var i = before - while (i >= 0 && this[i].isWhitespace()) i-- - return i - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/code/LanguagesConfigs.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/code/LanguagesConfigs.kt deleted file mode 100644 index a1d84bab..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/chats/code/LanguagesConfigs.kt +++ /dev/null @@ -1,531 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.chats.code - -data class LanguageConfig( - val keywords: Set, - val types: Set, - val constants: Set, - val supportsAnnotations: Boolean, - val singleLineComment: List, - val blockStart: String?, - val blockEnd: String?, - val caseInsensitiveKeywords: Boolean = false -) - -// bash -val bashConfig = LanguageConfig( - keywords = setOf( - "if", "then", "else", "elif", "fi", "for", "while", "do", "done", "case", "esac", "function" - ), - types = emptySet(), - constants = setOf("true", "false"), - supportsAnnotations = false, - singleLineComment = listOf("#"), - blockStart = null, - blockEnd = null -) - -// docker -val dockerConfig = LanguageConfig( - keywords = setOf( - "FROM", "RUN", "CMD", "ENTRYPOINT", "COPY", "ADD", "ENV", "EXPOSE", "VOLUME", "WORKDIR", - "USER", "LABEL", "ARG", "ONBUILD", "STOPSIGNAL", "HEALTHCHECK" - ), - types = emptySet(), - constants = emptySet(), - supportsAnnotations = false, - singleLineComment = listOf("#"), - blockStart = null, - blockEnd = null -) - -// yaml -val yamlConfig = LanguageConfig( - keywords = setOf( - "%YAML", "%TAG", "---", "..." - ), - types = setOf( - "string", "int", "float", "bool", "null", "sequence", "mapping", - "timestamp", "binary", "merge" - ), - constants = setOf( - "true", "false", "null", "~", "yes", "no", "on", "off" - ), - supportsAnnotations = true, - singleLineComment = listOf("#"), - blockStart = "|", - blockEnd = ">" -) - -// markdown -val markdownConfig = LanguageConfig( - keywords = setOf("#", "##", "###", "####", "#####", "######", "*", "-", "_", "`", "```"), - types = emptySet(), - constants = emptySet(), - supportsAnnotations = false, - singleLineComment = emptyList(), - blockStart = null, - blockEnd = null -) - -// ini -val iniConfig = LanguageConfig( - keywords = setOf( - "[", "]", "=", ":" - ), - types = setOf( - "string", "int", "float", "bool", "list" - ), - constants = setOf( - "true", "false", "yes", "no", "on", "off", "null", "~" - ), - supportsAnnotations = false, - singleLineComment = listOf(";", "#"), - blockStart = null, - blockEnd = null -) - -// toml -val tomlConfig = LanguageConfig( - keywords = setOf( - "table", "array", "datetime", "inline-table", "[", "[]", "[[", "]]" - ), - types = setOf( - "string", "int", "float", "bool", "datetime", "array", "table", "inline-table" - ), - constants = setOf( - "true", "false", "nan", "inf", "-inf" - ), - supportsAnnotations = false, - singleLineComment = listOf("#"), - blockStart = "\"\"\"", - blockEnd = "\"\"\"" -) - -// properties -val propertiesConfig = LanguageConfig( - keywords = setOf( - "=", ":", "\\", " " - ), - types = setOf( - "string", "int", "float", "bool" - ), - constants = setOf( - "true", "false", "yes", "no", "on", "off" - ), - supportsAnnotations = false, - singleLineComment = listOf("#", "!"), - blockStart = null, - blockEnd = null -) - -// php -val phpConfig = LanguageConfig( - keywords = setOf( - "function", "class", "interface", "trait", "extends", "implements", "public", "private", - "protected", "static", "final", "return", "if", "else", "elseif", "for", "foreach", "while", - "switch", "case", "default", "break", "continue", "try", "catch", "finally", "throw", "new", - "use", "namespace", "global", "var" - ), - types = setOf("int", "float", "string", "bool", "array", "object", "callable", "mixed"), - constants = setOf("true", "false", "null"), - supportsAnnotations = false, - singleLineComment = listOf("//", "#"), - blockStart = "/*", - blockEnd = "*/" -) - -// ruby -val rubyConfig = LanguageConfig( - keywords = setOf( - "def", "class", "module", "if", "elsif", "else", "end", "while", "for", "in", "do", "return", - "yield", "begin", "rescue", "ensure", "case", "when", "require", "include", "extend" - ), - types = emptySet(), - constants = setOf("true", "false", "nil"), - supportsAnnotations = false, - singleLineComment = listOf("#"), - blockStart = null, - blockEnd = null -) - -// lua -val luaConfig = LanguageConfig( - keywords = setOf( - "function", "local", "if", "then", "else", "elseif", "end", "for", "while", "repeat", "until", - "return", "break", "in", "goto" - ), - types = emptySet(), - constants = setOf("true", "false", "nil"), - supportsAnnotations = false, - singleLineComment = listOf("--"), - blockStart = "--[[", - blockEnd = "]]" -) - -// haskell -val haskellConfig = LanguageConfig( - keywords = setOf( - "module", "import", "where", "let", "in", "case", "of", "data", "type", "class", "instance", - "deriving", "do", "if", "then", "else" - ), - types = emptySet(), - constants = setOf("True", "False"), - supportsAnnotations = false, - singleLineComment = listOf("--"), - blockStart = "{-", - blockEnd = "-}" -) - -// r -val rConfig = LanguageConfig( - keywords = setOf( - "function", "if", "else", "for", "while", "repeat", "break", "next", "return" - ), - types = emptySet(), - constants = setOf("TRUE", "FALSE", "NULL", "NA"), - supportsAnnotations = false, - singleLineComment = listOf("#"), - blockStart = null, - blockEnd = null -) - -// matlab -val matlabConfig = LanguageConfig( - keywords = setOf( - "function", "end", "if", "else", "elseif", "for", "while", "switch", "case", "otherwise", - "return", "break", "continue", "try", "catch" - ), - types = emptySet(), - constants = emptySet(), - supportsAnnotations = false, - singleLineComment = listOf("%"), - blockStart = "%{", - blockEnd = "%}" -) - -// asm -val asmConfig = LanguageConfig( - keywords = setOf( - "mov", "add", "sub", "mul", "div", "jmp", "je", "jne", "jg", "jl", "call", "ret", "push", "pop" - ), - types = emptySet(), - constants = emptySet(), - supportsAnnotations = false, - singleLineComment = listOf(";"), - blockStart = null, - blockEnd = null -) - -// proto -val protoConfig = LanguageConfig( - keywords = setOf( - "syntax", "message", "enum", "package", "import", "option", "service", "rpc", "returns" - ), - types = setOf("int32", "int64", "string", "bool", "bytes", "float", "double"), - constants = emptySet(), - supportsAnnotations = false, - singleLineComment = listOf("//"), - blockStart = "/*", - blockEnd = "*/" -) - -// graphql -val graphqlConfig = LanguageConfig( - keywords = setOf( - "type", "query", "mutation", "subscription", "schema", "interface", "union", "enum", "input" - ), - types = emptySet(), - constants = emptySet(), - supportsAnnotations = false, - singleLineComment = listOf("#"), - blockStart = null, - blockEnd = null -) - -// css -val cssConfig = LanguageConfig( - keywords = setOf( - "color", "background", "margin", "padding", "border", "display", "flex", "grid", "position", - "absolute", "relative", "fixed", "font", "width", "height", "content" - ), - types = emptySet(), - constants = emptySet(), - supportsAnnotations = false, - singleLineComment = emptyList(), - blockStart = null, - blockEnd = null -) - -// scss -val scssConfig = LanguageConfig( - keywords = setOf( - "@mixin", "@include", "@import", "@use", "@extend", "@if", "@else", "@for", "@each", "@while" - ), - types = emptySet(), - constants = emptySet(), - supportsAnnotations = false, - singleLineComment = listOf("//"), - blockStart = "/*", - blockEnd = "*/" -) - -// regex -val regexConfig = LanguageConfig( - keywords = setOf( - "\\d", "\\w", "\\s", "\\b", "\\B", ".", "*", "+", "?", "|", "(", ")", "[", "]", "{", "}" - ), - types = emptySet(), - constants = emptySet(), - supportsAnnotations = false, - singleLineComment = emptyList(), - blockStart = null, - blockEnd = null -) - -// Kotlin -val kotlinConfig = LanguageConfig( - keywords = setOf( - "fun", "val", "var", "class", "object", "if", "else", "for", "while", "return", "package", "import", - "private", "public", "protected", "override", "data", "sealed", "interface", "super", "this", - "try", "catch", "finally", "throw", "when", "is", "in", "companion", "suspend", "inline", "noinline", - "crossinline", "reified", "operator", "infix", "enum", "open", "lateinit", "const", "typealias" - ), - types = setOf("Int", "Long", "Short", "Byte", "Float", "Double", "Boolean", "Char", "String", "List", "Map", "Set"), - constants = setOf("true", "false", "null"), - supportsAnnotations = true, - singleLineComment = listOf("//"), - blockStart = "/*", - blockEnd = "*/" -) - -// Java / C / C++ / C# -val cLikeConfig = LanguageConfig( - keywords = setOf( - "public", "private", "protected", "class", "interface", "enum", "static", "final", "void", "int", - "double", "float", "char", "boolean", "if", "else", "for", "while", "do", "switch", "case", "break", - "continue", "return", "new", "this", "super", "try", "catch", "throw", "throws", "namespace", "using", - "struct", "include", "extends", "implements" - ), - types = setOf( - "int", "long", "short", "byte", "float", "double", "boolean", "char", "String", "List", "Map", "Set", - "void" - ), - constants = setOf("true", "false", "null"), - supportsAnnotations = true, - singleLineComment = listOf("//"), - blockStart = "/*", - blockEnd = "*/" -) - -// Python -val pythonConfig = LanguageConfig( - keywords = setOf( - "def", "class", "if", "else", "elif", "for", "while", "return", "import", "from", "as", "try", "except", - "finally", "with", "lambda", "global", "nonlocal", "pass", "raise", "yield", "and", "or", "not", "is", "in" - ), - types = emptySet(), - constants = setOf("None", "True", "False"), - supportsAnnotations = false, - singleLineComment = listOf("#"), - blockStart = null, - blockEnd = null -) - -// JavaScript / TypeScript -val jsTsConfig = LanguageConfig( - keywords = setOf( - "function", "const", "let", "var", "class", "if", "else", "for", "while", "return", "import", "export", - "from", "async", "await", "try", "catch", "throw", "new", "this", "typeof", "instanceof", "void", - "delete", "interface", "type", "enum", "extends", "implements" - ), - types = setOf("string", "number", "boolean", "any", "unknown", "never", "void", "Array", "Promise", "Record"), - constants = setOf("true", "false", "null", "undefined"), - supportsAnnotations = false, - singleLineComment = listOf("//"), - blockStart = "/*", - blockEnd = "*/" -) - -// Go -val goConfig = LanguageConfig( - keywords = setOf( - "func", "var", "const", "type", "struct", "interface", "package", "import", "return", "if", "else", - "for", "range", "go", "defer", "switch", "case", "default", "map", "chan", "select" - ), - types = setOf( - "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64", - "float32", "float64", "string", "bool", "byte", "rune" - ), - constants = setOf("true", "false", "nil", "iota"), - supportsAnnotations = false, - singleLineComment = listOf("//"), - blockStart = "/*", - blockEnd = "*/" -) - -// Rust -val rustConfig = LanguageConfig( - keywords = setOf( - "fn", "let", "mut", "if", "else", "loop", "while", "for", "in", "return", "break", "continue", - "struct", "enum", "impl", "trait", "pub", "use", "mod", "match", "move", "unsafe", "where", - "crate", "super", "self", "Self", "as", "async", "await", "dyn", "ref", "box", "const", "static", - "extern", "type", "union", "macro_rules!" - ), - types = setOf( - "i8", "i16", "i32", "i64", "i128", "isize", - "u8", "u16", "u32", "u64", "u128", "usize", - "f32", "f64", "bool", "char", "str" - ), - constants = setOf( - "true", "false" - ), - supportsAnnotations = false, - singleLineComment = listOf("//", "///", "//!"), - blockStart = "/*", - blockEnd = "*/" -) - -// Swift -val swiftConfig = LanguageConfig( - keywords = setOf( - "func", "var", "let", "if", "else", "guard", "for", "while", "repeat", "return", - "class", "struct", "enum", "extension", "protocol", "init", "deinit", "import", - "switch", "case", "default", "break", "continue", "fallthrough", "where", - "as", "is", "in", "try", "catch", "throw", "throws", "rethrows", "async", "await", - "actor", "nonisolated", "mutating", "nonmutating", "static", "final", "override", - "public", "private", "fileprivate", "internal", "open", "convenience", "required", - "lazy", "weak", "unowned", "associatedtype", "typealias", "subscript", "operator", - "precedencegroup" - ), - types = setOf( - "Int", "Int8", "Int16", "Int32", "Int64", "UInt", "UInt8", "UInt16", "UInt32", - "UInt64", "Float", "Double", "Bool", "Character", "String", "Array", "Dictionary", - "Set", "Optional", "Any", "AnyObject", "CGFloat", "Decimal", "Data", "URL", "Void" - ), - constants = setOf( - "true", "false", "nil" - ), - supportsAnnotations = true, - singleLineComment = listOf("//"), - blockStart = "/*", - blockEnd = "*/", - caseInsensitiveKeywords = false -) - -// SQL -val sqlConfig = LanguageConfig( - keywords = setOf( - "SELECT", "INSERT", "UPDATE", "DELETE", "FROM", "WHERE", "JOIN", "INNER", "LEFT", - "RIGHT", "FULL", "OUTER", "CROSS", "ON", "GROUP", "BY", "ORDER", "HAVING", "LIMIT", - "OFFSET", "CREATE", "TABLE", "DROP", "ALTER", "INDEX", "VIEW", "TRIGGER", "FUNCTION", - "PROCEDURE", "UNION", "ALL", "DISTINCT", "AS", "NULL", "AND", "OR", "NOT", "IN", - "EXISTS", "BETWEEN", "LIKE", "IS", "CASE", "WHEN", "THEN", "ELSE", "END", "WITH", - "PRIMARY", "KEY", "FOREIGN", "REFERENCES", "CONSTRAINT", "CHECK", "DEFAULT", - "VALUES", "RETURNING", "CAST", "EXPLAIN", "ANALYZE" - ), - types = setOf( - "INT", "INTEGER", "SMALLINT", "BIGINT", "SERIAL", "BIGSERIAL", "DECIMAL", "NUMERIC", - "FLOAT", "REAL", "DOUBLE", "BOOLEAN", "BOOL", "CHAR", "VARCHAR", "TEXT", "DATE", - "TIME", "TIMESTAMP", "TIMESTAMPTZ", "INTERVAL", "UUID", "JSON", "JSONB", "BYTEA" - ), - constants = setOf( - "NULL", "TRUE", "FALSE" - ), - supportsAnnotations = false, - singleLineComment = listOf("--", "#"), - blockStart = "/*", - blockEnd = "*/", - caseInsensitiveKeywords = false -) - -// Java -val javaConfig = LanguageConfig( - keywords = setOf( - "class", "interface", "enum", "extends", "implements", "public", "private", "protected", - "static", "final", "void", "new", "return", "if", "else", "for", "while", "switch", "case", - "default", "break", "continue", "try", "catch", "finally", "throw", "throws", "import", - "package", "this", "super", "instanceof", "synchronized", "volatile", "transient" - ), - types = setOf( - "int", "long", "short", "byte", "float", "double", "boolean", "char", "String", "List", "Map", "Set" - ), - constants = setOf("true", "false", "null"), - supportsAnnotations = true, - singleLineComment = listOf("//"), - blockStart = "/*", - blockEnd = "*/" -) - -// JSON -val jsonConfig = LanguageConfig( - keywords = setOf( - "{", "}", "[", "]", ":", "," - ), - types = setOf( - "object", "array", "string", "number", "integer", "boolean", "null" - ), - constants = setOf( - "true", "false", "null" - ), - supportsAnnotations = false, - singleLineComment = emptyList(), - blockStart = null, - blockEnd = null -) - -// XML/HTML -val xmlConfig = LanguageConfig( - keywords = setOf( - "doctype", "html", "head", "body", "title", "meta", "link", "script", "style", - "div", "span", "p", "a", "img", "ul", "ol", "li", "table", "tr", "td", "form", "input" - ), - types = setOf( - "element", "attribute", "text", "cdata", "comment", "pi" - ), - constants = emptySet(), - supportsAnnotations = true, - singleLineComment = emptyList(), - blockStart = "" -) - -// nginx -val nginxConfig = LanguageConfig( - keywords = setOf( - "worker_processes", "events", "http", "server", "location", "listen", "server_name", - "root", "index", "include", "try_files", "proxy_pass", "proxy_set_header", "add_header", - "return", "rewrite", "error_page", "client_max_body_size", "gzip", "gzip_types", - "ssl", "ssl_certificate", "ssl_certificate_key", "upstream", "fastcgi_pass", - "fastcgi_param", "access_log", "error_log", "autoindex", "deny", "allow", "set", - "limit_conn", "limit_req", "resolver", "proxy_cache", "proxy_cache_path" - ), - types = setOf( - "directive", "block", "string", "number", "path" - ), - constants = setOf( - "on", "off", "default", "none" - ), - supportsAnnotations = false, - singleLineComment = listOf("#"), - blockStart = "{", - blockEnd = "}" -) - -// caddy -val caddyConfig = LanguageConfig( - keywords = setOf( - "import", "route", "handle", "handle_path", "reverse_proxy", "file_server", "root", - "redir", "respond", "header", "tls", "encode", "php_fastcgi", "log", "basicauth", - "map", "templates", "bind", "transport", "route", "try_files" - ), - types = setOf( - "directive", "matcher", "handler", "string", "path" - ), - constants = setOf( - "on", "off", "true", "false" - ), - supportsAnnotations = false, - singleLineComment = listOf("#"), - blockStart = "{", - blockEnd = "}" -) \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/InlineBotResults.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/InlineBotResults.kt deleted file mode 100644 index 04b6d668..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/InlineBotResults.kt +++ /dev/null @@ -1,547 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.inputbar - -import androidx.compose.animation.* -import androidx.compose.animation.core.* -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.lazy.grid.itemsIndexed -import androidx.compose.foundation.lazy.grid.rememberLazyGridState -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Image -import androidx.compose.material.icons.rounded.PlayArrow -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import coil3.compose.AsyncImage -import coil3.request.ImageRequest -import coil3.request.crossfade -import org.monogram.domain.models.InlineQueryResultModel -import org.monogram.domain.models.MessageContent -import org.monogram.domain.repository.InlineBotResultsModel -import org.monogram.presentation.R - -private enum class InlineResultsMode { - Loading, - Empty, - Grid, - List -} - -@Composable -fun InlineBotResults( - inlineBotResults: InlineBotResultsModel?, - isInlineMode: Boolean, - isLoading: Boolean, - onResultClick: (String) -> Unit, - onSwitchPmClick: (String) -> Unit, - onLoadMore: (String) -> Unit, - modifier: Modifier = Modifier -) { - val results = inlineBotResults?.results.orEmpty() - val nextOffset = inlineBotResults?.nextOffset?.takeIf { it.isNotBlank() } - val mode = when { - isLoading && results.isEmpty() -> InlineResultsMode.Loading - results.isEmpty() -> InlineResultsMode.Empty - results.shouldUseMediaGrid() -> InlineResultsMode.Grid - else -> InlineResultsMode.List - } - - if (!isInlineMode && results.isEmpty() && inlineBotResults?.switchPmText == null && !isLoading) { - return - } - - Surface( - modifier = modifier - .fillMaxWidth() - .heightIn(max = 400.dp), - color = MaterialTheme.colorScheme.surface, - tonalElevation = 6.dp, - shadowElevation = 6.dp, - shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp) - ) { - Column(modifier = Modifier.fillMaxSize()) { - val switchPmText = inlineBotResults?.switchPmText - val switchPmParameter = inlineBotResults?.switchPmParameter - if (switchPmText != null && switchPmParameter != null) { - SwitchPmButton( - text = switchPmText, - onClick = { onSwitchPmClick(switchPmParameter) } - ) - HorizontalDivider(color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.2f)) - } - - Box(modifier = Modifier.weight(1f)) { - AnimatedContent( - targetState = mode, - transitionSpec = { - fadeIn(animationSpec = tween(220)) togetherWith fadeOut(animationSpec = tween(180)) - }, - label = "InlineResultsMode" - ) { currentMode -> - when (currentMode) { - InlineResultsMode.Loading -> InlineLoadingPlaceholder() - InlineResultsMode.Empty -> EmptyResultsPlaceholder() - InlineResultsMode.Grid -> InlineMediaResultsGrid( - results = results, - nextOffset = nextOffset, - isLoading = isLoading, - onResultClick = onResultClick, - onLoadMore = onLoadMore - ) - - InlineResultsMode.List -> InlineResultsList( - results = results, - nextOffset = nextOffset, - isLoading = isLoading, - onResultClick = onResultClick, - onLoadMore = onLoadMore - ) - } - } - - if (isLoading && results.isNotEmpty()) { - Box( - modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.surface.copy(alpha = 0.25f)), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator(modifier = Modifier.size(30.dp)) - } - } - } - } - } -} - -@Composable -private fun InlineMediaResultsGrid( - results: List, - nextOffset: String?, - isLoading: Boolean, - onResultClick: (String) -> Unit, - onLoadMore: (String) -> Unit -) { - val gridState = rememberLazyGridState() - val isStickerGrid = results.firstOrNull()?.normalizedType() == "sticker" - - var lastRequestedOffset by remember { mutableStateOf(null) } - val shouldLoadMore by remember(results, isLoading, nextOffset) { - derivedStateOf { - val lastVisible = gridState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: -1 - lastVisible >= results.size - 4 && !isLoading && nextOffset != null - } - } - - LaunchedEffect(shouldLoadMore, nextOffset) { - val offset = nextOffset - if (shouldLoadMore && offset != null && offset != lastRequestedOffset) { - lastRequestedOffset = offset - onLoadMore(offset) - } - } - - BoxWithConstraints(modifier = Modifier.fillMaxSize()) { - val minCellWidth = if (isStickerGrid) 74.dp else 112.dp - val maxColumns = if (isStickerGrid) 8 else 5 - val columns = (maxWidth / minCellWidth).toInt().coerceIn(2, maxColumns) - - LazyVerticalGrid( - columns = GridCells.Fixed(columns), - contentPadding = PaddingValues(6.dp), - verticalArrangement = Arrangement.spacedBy(6.dp), - horizontalArrangement = Arrangement.spacedBy(6.dp), - modifier = Modifier.fillMaxSize(), - state = gridState - ) { - itemsIndexed(results, key = { index, item -> "${item.type}:${item.id}:$index" }) { index, result -> - InlineResultAnimatedItem(index = index) { - InlineBotMediaItem( - result = result, - onClick = { onResultClick(result.id) } - ) - } - } - } - } -} - -@Composable -private fun InlineResultsList( - results: List, - nextOffset: String?, - isLoading: Boolean, - onResultClick: (String) -> Unit, - onLoadMore: (String) -> Unit -) { - val listState = rememberLazyListState() - var lastRequestedOffset by remember { mutableStateOf(null) } - val shouldLoadMore by remember(results, isLoading, nextOffset) { - derivedStateOf { - val lastVisible = listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: -1 - lastVisible >= results.size - 4 && !isLoading && nextOffset != null - } - } - - LaunchedEffect(shouldLoadMore, nextOffset) { - val offset = nextOffset - if (shouldLoadMore && offset != null && offset != lastRequestedOffset) { - lastRequestedOffset = offset - onLoadMore(offset) - } - } - - LazyColumn( - modifier = Modifier.fillMaxSize(), - contentPadding = PaddingValues(vertical = 6.dp), - state = listState - ) { - itemsIndexed(results, key = { index, item -> "${item.type}:${item.id}:$index" }) { index, result -> - InlineResultAnimatedItem(index = index) { - InlineBotResultItem( - result = result, - onClick = { onResultClick(result.id) } - ) - } - if (index < results.lastIndex) { - HorizontalDivider( - modifier = Modifier.padding(start = 16.dp), - thickness = 0.5.dp, - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.2f) - ) - } - } - } -} - -@Composable -private fun EmptyResultsPlaceholder() { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - Text( - text = stringResource(R.string.no_results_found), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } -} - -@Composable -private fun InlineLoadingPlaceholder() { - val transition = rememberInfiniteTransition(label = "InlineLoading") - val alpha by transition.animateFloat( - initialValue = 0.35f, - targetValue = 0.75f, - animationSpec = infiniteRepeatable( - animation = tween(durationMillis = 700), - repeatMode = RepeatMode.Reverse - ), - label = "InlineLoadingAlpha" - ) - - Column( - modifier = Modifier - .fillMaxSize() - .padding(horizontal = 10.dp, vertical = 8.dp), - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - repeat(4) { - Box( - modifier = Modifier - .fillMaxWidth() - .height(58.dp) - .clip(RoundedCornerShape(12.dp)) - .background(MaterialTheme.colorScheme.surfaceVariant.copy(alpha = alpha)) - ) - } - } -} - -@Composable -private fun InlineResultAnimatedItem( - index: Int, - content: @Composable () -> Unit -) { - var visible by remember(index) { mutableStateOf(false) } - LaunchedEffect(index) { - visible = true - } - - AnimatedVisibility( - visible = visible, - enter = fadeIn(animationSpec = tween(180, delayMillis = (index.coerceAtMost(6) * 18))) + - scaleIn(animationSpec = tween(220), initialScale = 0.97f) - ) { - content() - } -} - -@Composable -private fun SwitchPmButton( - text: String, - onClick: () -> Unit -) { - Box( - modifier = Modifier - .fillMaxWidth() - .clickable(onClick = onClick) - .padding(12.dp), - contentAlignment = Alignment.Center - ) { - Text( - text = text, - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) - } -} - -@Composable -private fun rememberMediaModel(result: InlineQueryResultModel): Any? { - val context = LocalContext.current - val contentPath = when (val content = result.content) { - is MessageContent.Photo -> content.path - is MessageContent.Video -> content.path - is MessageContent.Gif -> content.path - is MessageContent.Sticker -> content.path - is MessageContent.VideoNote -> content.path - is MessageContent.Document -> content.path - else -> null - } - - return remember(contentPath, result.thumbUrl) { - val data = if (!contentPath.isNullOrBlank()) contentPath else result.thumbUrl - if (data == null) return@remember null - - ImageRequest.Builder(context) - .data(data) - .crossfade(true) - .build() - } -} - -@Composable -private fun InlineBotMediaItem( - result: InlineQueryResultModel, - onClick: () -> Unit, - modifier: Modifier = Modifier -) { - val aspectRatio = remember(result.width, result.height, result.normalizedType()) { - val type = result.normalizedType() - if (type == "sticker") { - 1f - } else if (result.width > 0 && result.height > 0) { - (result.width.toFloat() / result.height.toFloat()).coerceIn(0.7f, 1.6f) - } else { - 1f - } - } - val type = result.normalizedType() - val mediaModel = rememberMediaModel(result) - - Box( - modifier = modifier - .fillMaxWidth() - .aspectRatio(aspectRatio) - .clip(RoundedCornerShape(6.dp)) - .background(MaterialTheme.colorScheme.surfaceVariant) - .clickable(onClick = onClick) - ) { - InlineMediaPlaceholder( - type = type, - modifier = Modifier.matchParentSize() - ) - - if (mediaModel != null) { - AsyncImage( - model = mediaModel, - contentDescription = null, - modifier = Modifier.fillMaxSize(), - contentScale = if (type == "sticker") ContentScale.Fit else ContentScale.Crop - ) - } - - if (type == "gif" || type == "video") { - Box( - modifier = Modifier - .align(Alignment.BottomEnd) - .padding(4.dp) - .clip(RoundedCornerShape(4.dp)) - .background(Color.Black.copy(alpha = 0.65f)) - .padding(horizontal = 5.dp, vertical = 2.dp) - ) { - Text( - text = if (type == "gif") stringResource(R.string.media_type_gif) else stringResource(R.string.media_type_video), - style = MaterialTheme.typography.labelSmall, - color = Color.White, - fontSize = 10.sp, - fontWeight = FontWeight.Bold - ) - } - } - } -} - -@Composable -private fun InlineBotResultItem( - result: InlineQueryResultModel, - onClick: () -> Unit, - modifier: Modifier = Modifier -) { - val mediaModel = rememberMediaModel(result) - val title = result.title?.takeIf { it.isNotBlank() } ?: resultTypeLabel(result) - val description = result.description?.takeIf { it.isNotBlank() } - - Row( - modifier = modifier - .fillMaxWidth() - .clickable(onClick = onClick) - .padding(horizontal = 12.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically - ) { - if (mediaModel != null || result.isVisualResult()) { - Box( - modifier = Modifier - .size(56.dp) - .clip(RoundedCornerShape(8.dp)) - .background(MaterialTheme.colorScheme.surfaceVariant), - contentAlignment = Alignment.Center - ) { - InlineMediaPlaceholder( - type = result.normalizedType(), - modifier = Modifier.matchParentSize() - ) - if (mediaModel != null) { - AsyncImage( - model = mediaModel, - contentDescription = null, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Crop - ) - } - } - Spacer(modifier = Modifier.width(12.dp)) - } - - Column(modifier = Modifier.weight(1f)) { - Text( - text = title, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurface, - fontWeight = FontWeight.SemiBold, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - - if (description != null) { - Text( - text = description, - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 2, - overflow = TextOverflow.Ellipsis - ) - } - } - } -} - -@Composable -private fun InlineMediaPlaceholder( - type: String, - modifier: Modifier = Modifier -) { - val transition = rememberInfiniteTransition(label = "InlinePlaceholder") - val alpha by transition.animateFloat( - initialValue = 0.45f, - targetValue = 0.8f, - animationSpec = infiniteRepeatable( - animation = tween(durationMillis = 950), - repeatMode = RepeatMode.Reverse - ), - label = "InlinePlaceholderAlpha" - ) - - val icon = if (type == "video" || type == "gif") { - Icons.Rounded.PlayArrow - } else { - Icons.Rounded.Image - } - - Box( - modifier = modifier - .background(MaterialTheme.colorScheme.surfaceVariant.copy(alpha = alpha)), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = icon, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f), - modifier = Modifier.size(20.dp) - ) - } -} - -@Composable -private fun resultTypeLabel(result: InlineQueryResultModel): String { - return when (result.normalizedType()) { - "photo" -> stringResource(R.string.media_type_photo) - "video" -> stringResource(R.string.media_type_video) - "sticker" -> stringResource(R.string.media_type_sticker) - "voice" -> stringResource(R.string.media_type_voice) - "gif" -> stringResource(R.string.media_type_gif) - "location" -> stringResource(R.string.media_type_location) - else -> stringResource(R.string.media_type_message) - } -} - -private fun List.shouldUseMediaGrid(): Boolean { - if (isEmpty()) return false - val hasNamedMedia = any { result -> - result.isVisualResult() && (!result.title.isNullOrBlank() || !result.description.isNullOrBlank()) - } - if (hasNamedMedia) return false - - val visualItems = count { it.isVisualResult() } - return visualItems >= size * 0.7f -} - -private fun InlineQueryResultModel.isVisualResult(): Boolean { - return when (normalizedType()) { - "photo", "video", "gif", "sticker" -> true - else -> false - } -} - -private fun InlineQueryResultModel.normalizedType(): String { - val source = type.lowercase() - return when { - "sticker" in source -> "sticker" - "animation" in source || "gif" in source -> "gif" - "photo" in source -> "photo" - "video" in source -> "video" - "voice" in source -> "voice" - "location" in source || "venue" in source -> "location" - else -> "message" - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/InputBarSendButton.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/InputBarSendButton.kt deleted file mode 100644 index 38f9b130..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/InputBarSendButton.kt +++ /dev/null @@ -1,175 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.inputbar - -import androidx.compose.animation.Crossfade -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.gestures.awaitEachGesture -import androidx.compose.foundation.gestures.awaitFirstDown -import androidx.compose.foundation.gestures.waitForUpOrCancellation -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.Send -import androidx.compose.material.icons.filled.Check -import androidx.compose.material.icons.filled.Videocam -import androidx.compose.material.icons.outlined.Mic -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.hapticfeedback.HapticFeedbackType -import androidx.compose.ui.input.pointer.PointerEventType -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.input.pointer.positionChange -import androidx.compose.ui.platform.LocalHapticFeedback -import androidx.compose.ui.text.input.TextFieldValue -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.MessageModel -import org.monogram.domain.models.MessageSendOptions - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun InputBarSendButton( - textValue: TextFieldValue, - editingMessage: MessageModel?, - pendingMediaPaths: List, - isOverCharLimit: Boolean, - canWriteText: Boolean, - canSendVoice: Boolean, - canSendMedia: Boolean, - isVideoMessageMode: Boolean, - onSendWithOptions: (MessageSendOptions) -> Unit, - onShowSendOptionsMenu: () -> Unit, - onCameraClick: () -> Unit, - onVideoModeToggle: () -> Unit, - onVoiceStart: () -> Unit = {}, - onVoiceStop: (Boolean) -> Unit = { _ -> }, - onVoiceLock: () -> Unit = {} -) { - val haptic = LocalHapticFeedback.current - val isTextEmpty = textValue.text.isBlank() - val isSendEnabled = - (!isTextEmpty || editingMessage != null || pendingMediaPaths.isNotEmpty()) && canWriteText && !isOverCharLimit - - var isVoiceRecordingActive by remember { mutableStateOf(false) } - val isRecordingMode = isTextEmpty && editingMessage == null && pendingMediaPaths.isEmpty() && canSendVoice - - if (canWriteText || canSendVoice) { - Box( - modifier = Modifier - .size(48.dp) - .background( - color = if (isSendEnabled || isVoiceRecordingActive) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surfaceVariant, - shape = CircleShape - ) - .clip(CircleShape) - .then( - if (isRecordingMode) { - Modifier.pointerInput(isVideoMessageMode) { - awaitEachGesture { - try { - awaitFirstDown() - - val longPressTimeout = viewConfiguration.longPressTimeoutMillis - val up = withTimeoutOrNull(longPressTimeout) { - waitForUpOrCancellation() - } - - if (up == null) { - if (isVideoMessageMode) { - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - onCameraClick() - waitForUpOrCancellation() - } else { - isVoiceRecordingActive = true - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - onVoiceStart() - - var totalDrag = Offset.Zero - val lockThreshold = -80.dp.toPx() - val cancelThreshold = -80.dp.toPx() - - while (true) { - val event = awaitPointerEvent() - val changes = event.changes - - changes.forEach { change -> - totalDrag += change.positionChange() - change.consume() - } - - if (totalDrag.y < lockThreshold) { - isVoiceRecordingActive = false - onVoiceLock() - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - break - } else if (totalDrag.x < cancelThreshold) { - isVoiceRecordingActive = false - onVoiceStop(true) - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - break - } - - if (event.type == PointerEventType.Release || changes.all { !it.pressed }) { - isVoiceRecordingActive = false - onVoiceStop(false) - break - } - } - } - } else { - onVideoModeToggle() - haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove) - } - } finally { - if (isVoiceRecordingActive) { - isVoiceRecordingActive = false - onVoiceStop(true) - } - } - } - } - } else { - Modifier.combinedClickable( - onClick = { - if (!isOverCharLimit) { - onSendWithOptions(MessageSendOptions()) - } - }, - onLongClick = { - val canShowOptions = editingMessage == null && canWriteText && - (!isTextEmpty || (pendingMediaPaths.isNotEmpty() && canSendMedia)) && - !isOverCharLimit - if (canShowOptions) { - onShowSendOptionsMenu() - } - } - ) - } - ), - contentAlignment = Alignment.Center - ) { - Crossfade( - targetState = when { - pendingMediaPaths.isNotEmpty() -> Icons.AutoMirrored.Filled.Send - editingMessage != null -> Icons.Default.Check - !isTextEmpty -> Icons.AutoMirrored.Filled.Send - isVideoMessageMode -> Icons.Default.Videocam - else -> Icons.Outlined.Mic - }, - label = "IconAnimation" - ) { icon -> - Icon( - imageVector = icon, - contentDescription = null, - tint = if (isSendEnabled || isVoiceRecordingActive) MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/InputPreviewSection.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/InputPreviewSection.kt deleted file mode 100644 index 04877421..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/InputPreviewSection.kt +++ /dev/null @@ -1,372 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.inputbar - -import androidx.compose.animation.* -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.tween -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.gestures.detectDragGesturesAfterLongPress -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.Reply -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.Edit -import androidx.compose.material.icons.filled.PlayCircle -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.scale -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.hapticfeedback.HapticFeedbackType -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.LocalHapticFeedback -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.zIndex -import coil3.compose.AsyncImage -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.R -import java.io.File -import java.util.* - -sealed class InputPreviewState { - object None : InputPreviewState() - data class Reply(val message: MessageModel) : InputPreviewState() - data class Edit(val message: MessageModel) : InputPreviewState() - data class Media(val paths: List) : InputPreviewState() -} - -@Composable -fun InputPreviewSection( - editingMessage: MessageModel?, - replyMessage: MessageModel?, - pendingMediaPaths: List, - onCancelEdit: () -> Unit, - onCancelReply: () -> Unit, - onCancelMedia: () -> Unit, - onMediaOrderChange: (List) -> Unit, - onMediaClick: (String) -> Unit -) { - val previewState = remember(editingMessage, replyMessage, pendingMediaPaths) { - when { - pendingMediaPaths.isNotEmpty() -> InputPreviewState.Media(pendingMediaPaths) - editingMessage != null -> InputPreviewState.Edit(editingMessage) - replyMessage != null -> InputPreviewState.Reply(replyMessage) - else -> InputPreviewState.None - } - } - - AnimatedContent( - targetState = previewState, - transitionSpec = { - val enterTransition = fadeIn(animationSpec = tween(200)) + - expandVertically(animationSpec = tween(200)) - val exitTransition = fadeOut(animationSpec = tween(150)) + - shrinkVertically(animationSpec = tween(150)) - enterTransition togetherWith exitTransition - }, - label = "PreviewAnimation" - ) { state -> - when (state) { - is InputPreviewState.Edit -> EditPreview(message = state.message, onCancel = onCancelEdit) - is InputPreviewState.Reply -> ReplyPreview(message = state.message, onCancel = onCancelReply) - is InputPreviewState.Media -> MediaPreview( - paths = state.paths, - onCancel = onCancelMedia, - onRemove = { path -> - val newList = pendingMediaPaths.toMutableList() - newList.remove(path) - onMediaOrderChange(newList) - }, - onMove = { from, to -> - val newList = pendingMediaPaths.toMutableList() - Collections.swap(newList, from, to) - onMediaOrderChange(newList) - }, - onMediaClick = onMediaClick - ) - - InputPreviewState.None -> Spacer(modifier = Modifier.height(0.dp)) - } - } -} - -@Composable -private fun ReplyPreview( - message: MessageModel, - onCancel: () -> Unit -) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 8.dp, vertical = 4.dp) - .background(MaterialTheme.colorScheme.surfaceContainer, RoundedCornerShape(12.dp)) - .padding(12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Icon( - imageVector = Icons.AutoMirrored.Filled.Reply, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.padding(end = 12.dp) - ) - - Box( - modifier = Modifier - .width(2.dp) - .height(36.dp) - .background(MaterialTheme.colorScheme.primary, RoundedCornerShape(2.dp)) - ) - - Spacer(modifier = Modifier.width(12.dp)) - - Column(modifier = Modifier.weight(1f)) { - Text( - text = message.senderName, - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.primary, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Text( - text = when (val content = message.content) { - is MessageContent.Text -> content.text - is MessageContent.Photo -> stringResource(R.string.media_type_photo) - is MessageContent.Video -> stringResource(R.string.media_type_video) - is MessageContent.Sticker -> stringResource(R.string.media_type_sticker) - is MessageContent.Voice -> stringResource(R.string.media_type_voice) - is MessageContent.VideoNote -> stringResource(R.string.media_type_video_note) - is MessageContent.Gif -> stringResource(R.string.media_type_gif) - is MessageContent.Location -> stringResource(R.string.media_type_location) - is MessageContent.Venue -> content.title - else -> stringResource(R.string.media_type_message) - }, - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - - IconButton(onClick = onCancel) { - Icon( - imageVector = Icons.Default.Close, - contentDescription = stringResource(R.string.action_cancel_reply), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } -} - -@Composable -private fun EditPreview( - message: MessageModel, - onCancel: () -> Unit -) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 8.dp, vertical = 4.dp) - .background(MaterialTheme.colorScheme.surfaceContainer, RoundedCornerShape(12.dp)) - .padding(12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Icon( - imageVector = Icons.Default.Edit, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.padding(end = 12.dp) - ) - - Box( - modifier = Modifier - .width(2.dp) - .height(36.dp) - .background(MaterialTheme.colorScheme.primary, RoundedCornerShape(2.dp)) - ) - - Spacer(modifier = Modifier.width(12.dp)) - - Column(modifier = Modifier.weight(1f)) { - Text( - text = stringResource(R.string.action_edit_message), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.primary, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Text( - text = when (val content = message.content) { - is MessageContent.Text -> content.text - else -> stringResource(R.string.media_type_message) - }, - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - - IconButton(onClick = onCancel) { - Icon( - imageVector = Icons.Default.Close, - contentDescription = stringResource(R.string.action_cancel_edit), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } -} - -@OptIn(ExperimentalFoundationApi::class) -@Composable -private fun MediaPreview( - paths: List, - onCancel: () -> Unit, - onRemove: (String) -> Unit, - onMove: (Int, Int) -> Unit, - onMediaClick: (String) -> Unit = {} -) { - var draggingIndex by remember { mutableStateOf(null) } - var dragOffset by remember { mutableStateOf(0f) } - val haptic = LocalHapticFeedback.current - val density = LocalDensity.current - - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 8.dp, vertical = 4.dp) - .background(MaterialTheme.colorScheme.surfaceContainer, RoundedCornerShape(12.dp)) - .padding(8.dp) - ) { - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Text( - text = if (paths.size > 1) stringResource(R.string.action_send_items_count, paths.size) else stringResource(R.string.action_send_media), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.primary, - modifier = Modifier.padding(start = 4.dp) - ) - IconButton(onClick = onCancel, modifier = Modifier.size(24.dp)) { - Icon( - imageVector = Icons.Default.Close, - contentDescription = stringResource(R.string.action_cancel), - tint = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.size(18.dp) - ) - } - } - - Spacer(modifier = Modifier.height(8.dp)) - - LazyRow( - horizontalArrangement = Arrangement.spacedBy(8.dp), - contentPadding = PaddingValues(horizontal = 4.dp), - modifier = Modifier.fillMaxWidth() - ) { - itemsIndexed(paths, key = { _, path -> path }) { index, path -> - val isDragging = draggingIndex == index - val scale by animateFloatAsState( - targetValue = if (isDragging) 1.1f else 1f, - animationSpec = tween(200), - label = "scale" - ) - - Box( - modifier = Modifier - .size(80.dp) - .scale(scale) - .zIndex(if (isDragging) 1f else 0f) - .pointerInput(paths) { - detectDragGesturesAfterLongPress( - onDragStart = { - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - draggingIndex = index - dragOffset = 0f - }, - onDrag = { change, dragAmount -> - change.consume() - dragOffset += dragAmount.x - - val itemWidth = with(density) { 88.dp.toPx() } - val targetIndex = when { - dragOffset > itemWidth / 2 -> index + 1 - dragOffset < -itemWidth / 2 -> index - 1 - else -> index - } - - if (targetIndex in paths.indices && targetIndex != index) { - onMove(index, targetIndex) - draggingIndex = targetIndex - dragOffset = 0f - } - }, - onDragEnd = { - draggingIndex = null - dragOffset = 0f - }, - onDragCancel = { - draggingIndex = null - dragOffset = 0f - } - ) - } - .clip(RoundedCornerShape(8.dp)) - .background(MaterialTheme.colorScheme.surfaceVariant) - .clickable { onMediaClick(path) } - ) { - AsyncImage( - model = File(path), - contentDescription = null, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Crop - ) - - if (path.endsWith(".mp4")) { - Icon( - imageVector = Icons.Default.PlayCircle, - contentDescription = null, - tint = Color.White, - modifier = Modifier - .align(Alignment.Center) - .size(24.dp) - ) - } - - Box( - modifier = Modifier - .align(Alignment.TopEnd) - .padding(4.dp) - .size(20.dp) - .background(Color.Black.copy(alpha = 0.6f), CircleShape) - .clickable { onRemove(path) }, - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Default.Close, - contentDescription = stringResource(R.string.action_remove), - tint = Color.White, - modifier = Modifier.size(12.dp) - ) - } - } - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/InputTextField.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/InputTextField.kt deleted file mode 100644 index ee1075d3..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/InputTextField.kt +++ /dev/null @@ -1,903 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.inputbar - -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.text.BasicTextField -import androidx.compose.foundation.text.InlineTextContent -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.foundation.text.appendInlineContent -import androidx.compose.foundation.text.contextmenu.builder.item -import androidx.compose.foundation.text.contextmenu.data.TextContextMenuKeys -import androidx.compose.foundation.text.contextmenu.modifier.appendTextContextMenuComponents -import androidx.compose.foundation.text.contextmenu.modifier.filterTextContextMenuComponents -import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.focus.onFocusChanged -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.SolidColor -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.* -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.KeyboardCapitalization -import androidx.compose.ui.text.input.OffsetMapping -import androidx.compose.ui.text.input.TextFieldValue -import androidx.compose.ui.text.input.TransformedText -import androidx.compose.ui.text.style.TextDecoration -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.MessageEntity -import org.monogram.domain.models.MessageEntityType -import org.monogram.domain.models.StickerModel -import org.monogram.presentation.R -import org.monogram.presentation.features.chats.currentChat.components.chats.addEmojiStyle -import org.monogram.presentation.features.stickers.ui.view.StickerImage - -internal const val CUSTOM_EMOJI_TAG = "custom_emoji" -internal const val MENTION_TAG = "mention" -internal const val RICH_ENTITY_TAG = "rich_entity" - -private const val ENTITY_BOLD = "bold" -private const val ENTITY_ITALIC = "italic" -private const val ENTITY_UNDERLINE = "underline" -private const val ENTITY_STRIKE = "strikethrough" -private const val ENTITY_SPOILER = "spoiler" -private const val ENTITY_CODE = "code" -private const val ENTITY_PRE = "pre" -private const val ENTITY_TEXT_URL = "text_url" - -private object RichMenuActionBold -private object RichMenuActionItalic -private object RichMenuActionUnderline -private object RichMenuActionStrike -private object RichMenuActionSpoiler -private object RichMenuActionCode -private object RichMenuActionPre -private object RichMenuActionLink -private object RichMenuActionClear - -private data class Interval(val start: Int, val end: Int) - -@Composable -fun InputTextField( - textValue: TextFieldValue, - onValueChange: (TextFieldValue) -> Unit, - onRichTextValueChange: (TextFieldValue) -> Unit = onValueChange, - enableContextMenu: Boolean = true, - enableRichContextActions: Boolean = true, - canWriteText: Boolean, - knownCustomEmojis: Map, - emojiFontFamily: FontFamily, - focusRequester: FocusRequester, - pendingMediaPaths: List, - maxEditorHeight: Dp = 140.dp, - onFocus: () -> Unit = {}, - modifier: Modifier = Modifier -) { - var showLinkDialog by remember { mutableStateOf(false) } - var linkValue by remember { mutableStateOf("https://") } - var showPreLanguageDialog by remember { mutableStateOf(false) } - var preLanguageValue by remember { mutableStateOf("") } - - val emojiSize = 20.sp - val inlineContent = remember(knownCustomEmojis.size) { - knownCustomEmojis.map { (id, sticker) -> - id.toString() to InlineTextContent( - Placeholder(emojiSize, emojiSize, PlaceholderVerticalAlign.Center) - ) { - StickerImage( - path = sticker.path, - modifier = Modifier.fillMaxSize() - ) - } - }.toMap() - } - - val primaryColor = MaterialTheme.colorScheme.primary - val transformedTextState = remember(textValue.annotatedString, knownCustomEmojis, emojiFontFamily, primaryColor) { - val text = textValue.annotatedString - val emojiAnnotations = text.getStringAnnotations(CUSTOM_EMOJI_TAG, 0, text.length) - val mentionAnnotations = text.getStringAnnotations(MENTION_TAG, 0, text.length) - - val builder = AnnotatedString.Builder() - var lastIndex = 0 - val sortedEmojiAnnotations = emojiAnnotations.sortedBy { it.start } - - for (annotation in sortedEmojiAnnotations) { - if (annotation.start < lastIndex) continue - builder.append(text.subSequence(lastIndex, annotation.start)) - val stickerId = annotation.item.toLongOrNull() - val originalEmoji = text.substring(annotation.start, annotation.end) - if (stickerId != null && knownCustomEmojis.containsKey(stickerId)) { - builder.appendInlineContent(stickerId.toString(), originalEmoji) - } else { - builder.append(originalEmoji) - } - lastIndex = annotation.end - } - if (lastIndex < text.length) builder.append(text.subSequence(lastIndex, text.length)) - - val result = builder.toAnnotatedString() - val finalBuilder = AnnotatedString.Builder(result) - - // Add emoji style - finalBuilder.addEmojiStyle(result.text, emojiFontFamily) - - // Add mention highlighting - mentionAnnotations.forEach { annotation -> - finalBuilder.addStyle(SpanStyle(color = primaryColor), annotation.start, annotation.end) - } - - text.getStringAnnotations(RICH_ENTITY_TAG, 0, text.length).forEach { annotation -> - val style = decodeRichEntity(annotation.item)?.toEditorStyle(primaryColor) - if (style != null && annotation.start < annotation.end && annotation.end <= result.length) { - finalBuilder.addStyle(style, annotation.start, annotation.end) - } - } - - // Highlight @username style mentions that are not yet annotated - val mentionRegex = Regex("@(\\w+)") - mentionRegex.findAll(result.text).forEach { match -> - if (mentionAnnotations.none { it.start <= match.range.first && it.end >= match.range.last + 1 }) { - finalBuilder.addStyle(SpanStyle(color = primaryColor), match.range.first, match.range.last + 1) - } - } - - TransformedText(finalBuilder.toAnnotatedString(), OffsetMapping.Identity) - } - - val hasCustomEmojis = knownCustomEmojis.isNotEmpty() && - textValue.annotatedString.getStringAnnotations(CUSTOM_EMOJI_TAG, 0, textValue.text.length).isNotEmpty() - val hasRichFormatting = textValue.annotatedString - .getStringAnnotations(RICH_ENTITY_TAG, 0, textValue.text.length) - .isNotEmpty() - val shouldUseOverlayText = - hasCustomEmojis || emojiFontFamily != FontFamily.Default || textValue.text.contains('@') || hasRichFormatting - - val scrollState = rememberScrollState() - - LaunchedEffect(textValue.text) { - scrollState.scrollTo(scrollState.maxValue) - } - - val richTextBold = stringResource(R.string.rich_text_bold) - val richTextItalic = stringResource(R.string.rich_text_italic) - val richTextUnderline = stringResource(R.string.rich_text_underline) - val richTextStrike = stringResource(R.string.rich_text_strikethrough) - val richTextSpoiler = stringResource(R.string.rich_text_spoiler) - val richTextCode = stringResource(R.string.rich_text_code) - val richTextPre = stringResource(R.string.rich_text_pre) - val richTextLink = stringResource(R.string.rich_text_link) - val richTextClear = stringResource(R.string.rich_text_clear) - - Box(modifier = modifier.fillMaxWidth()) { - Box( - modifier = Modifier - .padding(vertical = 10.dp) - .heightIn(max = maxEditorHeight) - .verticalScroll(scrollState), - contentAlignment = Alignment.CenterStart - ) { - if (canWriteText) { - val fieldModifier = Modifier - .fillMaxWidth() - .focusRequester(focusRequester) - .onFocusChanged { if (it.isFocused) onFocus() } - .let { base -> - when { - !enableContextMenu -> base.filterTextContextMenuComponents { false } - enableRichContextActions -> { - base - .filterTextContextMenuComponents { component -> - when (component.key) { - TextContextMenuKeys.CutKey, - TextContextMenuKeys.CopyKey, - TextContextMenuKeys.PasteKey, - TextContextMenuKeys.SelectAllKey, - RichMenuActionBold, - RichMenuActionItalic, - RichMenuActionUnderline, - RichMenuActionStrike, - RichMenuActionSpoiler, - RichMenuActionCode, - RichMenuActionPre, - RichMenuActionLink, - RichMenuActionClear -> true - - else -> false - } - } - .appendTextContextMenuComponents { - if (hasFormattableSelection(textValue)) { - separator() - item(RichMenuActionBold, richTextBold) { - onRichTextValueChange( - toggleRichEntity( - textValue, - MessageEntityType.Bold - ) - ) - close() - } - item(RichMenuActionItalic, richTextItalic) { - onRichTextValueChange( - toggleRichEntity( - textValue, - MessageEntityType.Italic - ) - ) - close() - } - item(RichMenuActionUnderline, richTextUnderline) { - onRichTextValueChange( - toggleRichEntity( - textValue, - MessageEntityType.Underline - ) - ) - close() - } - item(RichMenuActionStrike, richTextStrike) { - onRichTextValueChange( - toggleRichEntity( - textValue, - MessageEntityType.Strikethrough - ) - ) - close() - } - item(RichMenuActionSpoiler, richTextSpoiler) { - onRichTextValueChange( - toggleRichEntity( - textValue, - MessageEntityType.Spoiler - ) - ) - close() - } - item(RichMenuActionCode, richTextCode) { - onRichTextValueChange( - toggleRichEntity( - textValue, - MessageEntityType.Code - ) - ) - close() - } - item(RichMenuActionPre, richTextPre) { - val selection = textValue.selection.normalized() - val current = textValue.annotatedString - .getStringAnnotations( - RICH_ENTITY_TAG, - selection.start, - selection.end - ) - .firstOrNull { decodeRichEntity(it.item) is MessageEntityType.Pre } - preLanguageValue = - (current?.let { decodeRichEntity(it.item) } as? MessageEntityType.Pre)?.language.orEmpty() - showPreLanguageDialog = true - close() - } - item(RichMenuActionLink, richTextLink) { - val selection = textValue.selection.normalized() - val current = textValue.annotatedString - .getStringAnnotations( - RICH_ENTITY_TAG, - selection.start, - selection.end - ) - .firstOrNull { decodeRichEntity(it.item) is MessageEntityType.TextUrl } - val existingUrl = - (current?.let { decodeRichEntity(it.item) } as? MessageEntityType.TextUrl)?.url - linkValue = existingUrl ?: "https://" - showLinkDialog = true - close() - } - item(RichMenuActionClear, richTextClear) { - onRichTextValueChange(clearRichFormatting(textValue)) - close() - } - } - } - } - - else -> base - } - } - - BasicTextField( - value = textValue, - onValueChange = onValueChange, - modifier = fieldModifier, - textStyle = MaterialTheme.typography.bodyLarge.copy( - color = if (shouldUseOverlayText) Color.Transparent else MaterialTheme.colorScheme.onSurface - ), - cursorBrush = SolidColor(MaterialTheme.colorScheme.primary), - keyboardOptions = KeyboardOptions(capitalization = KeyboardCapitalization.Sentences), - minLines = 1, - maxLines = Int.MAX_VALUE, - visualTransformation = { transformedTextState }, - decorationBox = { innerTextField -> - Box { - if (shouldUseOverlayText) { - Text( - text = transformedTextState.text, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyLarge.copy( - color = MaterialTheme.colorScheme.onSurface - ), - modifier = Modifier.fillMaxWidth() - ) - } - if (textValue.text.isEmpty()) { - Text( - text = if (pendingMediaPaths.isNotEmpty()) stringResource(R.string.input_placeholder_caption) else stringResource( - R.string.input_placeholder_message - ), - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - innerTextField() - } - } - ) - } else { - Text( - text = stringResource(R.string.input_error_not_allowed), - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f), - modifier = Modifier - .fillMaxWidth() - .padding(start = 4.dp) - ) - } - } - - if (showLinkDialog) { - AlertDialog( - onDismissRequest = { showLinkDialog = false }, - title = { Text(text = stringResource(R.string.rich_text_link_title)) }, - text = { - OutlinedTextField( - value = linkValue, - onValueChange = { linkValue = it }, - modifier = Modifier.fillMaxWidth(), - singleLine = true, - label = { Text(text = stringResource(R.string.rich_text_link_hint)) } - ) - }, - confirmButton = { - TextButton( - onClick = { - val normalizedUrl = normalizeUrl(linkValue) - if (normalizedUrl != null && !textValue.selection.collapsed) { - onRichTextValueChange( - applyRichEntity( - textValue, - MessageEntityType.TextUrl(normalizedUrl), - toggle = false - ) - ) - } - showLinkDialog = false - } - ) { - Text(text = stringResource(R.string.action_apply)) - } - }, - dismissButton = { - TextButton(onClick = { showLinkDialog = false }) { - Text(text = stringResource(R.string.action_cancel)) - } - } - ) - } - - if (showPreLanguageDialog) { - AlertDialog( - onDismissRequest = { showPreLanguageDialog = false }, - title = { Text(text = stringResource(R.string.rich_text_code_language_title)) }, - text = { - OutlinedTextField( - value = preLanguageValue, - onValueChange = { preLanguageValue = it }, - modifier = Modifier.fillMaxWidth(), - singleLine = true, - label = { Text(text = stringResource(R.string.rich_text_code_language_hint)) } - ) - }, - confirmButton = { - TextButton( - onClick = { - onRichTextValueChange(applyPreEntity(textValue, preLanguageValue)) - showPreLanguageDialog = false - } - ) { - Text(text = stringResource(R.string.action_apply)) - } - }, - dismissButton = { - TextButton(onClick = { showPreLanguageDialog = false }) { - Text(text = stringResource(R.string.action_cancel)) - } - } - ) - } - } -} - -internal fun mergeInputTextValuePreservingAnnotations( - currentValue: TextFieldValue, - incomingValue: TextFieldValue -): TextFieldValue { - val trackedTags = setOf(RICH_ENTITY_TAG, CUSTOM_EMOJI_TAG, MENTION_TAG) - val currentTracked = collectTrackedAnnotations(currentValue.annotatedString, trackedTags) - val incomingTracked = collectTrackedAnnotations(incomingValue.annotatedString, trackedTags) - - if (currentValue.text != incomingValue.text) { - val incomingCount = incomingTracked.values.sumOf { it.size } - if (incomingCount > 0) return incomingValue - - val transformedTracked = currentTracked.mapValues { (_, ranges) -> - transformRangesByTextDiff( - oldText = currentValue.text, - newText = incomingValue.text, - ranges = ranges - ) - } - - return incomingValue.copy( - annotatedString = rebuildWithTrackedAnnotations( - base = incomingValue.annotatedString, - trackedTags = trackedTags, - trackedSource = transformedTracked - ) - ) - } - - if (currentTracked == incomingTracked) return incomingValue - - val currentCount = currentTracked.values.sumOf { it.size } - val incomingCount = incomingTracked.values.sumOf { it.size } - val shouldAcceptIncoming = incomingCount >= currentCount - - if (shouldAcceptIncoming) return incomingValue - - return incomingValue.copy( - annotatedString = rebuildWithTrackedAnnotations( - base = incomingValue.annotatedString, - trackedTags = trackedTags, - trackedSource = currentTracked - ) - ) -} - -private fun transformRangesByTextDiff( - oldText: String, - newText: String, - ranges: List> -): List> { - if (ranges.isEmpty()) return emptyList() - - val prefix = longestCommonPrefix(oldText, newText) - val oldRemain = oldText.length - prefix - val newRemain = newText.length - prefix - val suffix = longestCommonSuffix( - oldText = oldText, - newText = newText, - oldLimit = oldRemain, - newLimit = newRemain - ) - - val oldChangedStart = prefix - val oldChangedEnd = oldText.length - suffix - val delta = (newText.length - oldText.length) - - return ranges.mapNotNull { range -> - val start = range.start - val end = range.end - - val shifted = when { - end <= oldChangedStart -> range.copy() - start >= oldChangedEnd -> range.copy(start = start + delta, end = end + delta) - else -> null - } - - shifted?.takeIf { it.start < it.end && it.end <= newText.length } - } -} - -private fun longestCommonPrefix(a: String, b: String): Int { - val max = minOf(a.length, b.length) - var i = 0 - while (i < max && a[i] == b[i]) i++ - return i -} - -private fun longestCommonSuffix(oldText: String, newText: String, oldLimit: Int, newLimit: Int): Int { - val max = minOf(oldLimit, newLimit) - var i = 0 - while (i < max && oldText[oldText.length - 1 - i] == newText[newText.length - 1 - i]) i++ - return i -} - -private fun collectTrackedAnnotations( - text: AnnotatedString, - trackedTags: Set -): Map>> { - return trackedTags.associateWith { tag -> - text.getStringAnnotations(tag, 0, text.length) - } -} - -private fun rebuildWithTrackedAnnotations( - base: AnnotatedString, - trackedTags: Set, - trackedSource: Map>> -): AnnotatedString { - val builder = AnnotatedString.Builder(base.text) - base.getStringAnnotations(0, base.length) - .filter { it.tag !in trackedTags } - .forEach { annotation -> - builder.addStringAnnotation(annotation.tag, annotation.item, annotation.start, annotation.end) - } - - trackedTags.forEach { tag -> - trackedSource[tag].orEmpty().forEach { annotation -> - if (annotation.start < annotation.end && annotation.end <= base.length) { - builder.addStringAnnotation(annotation.tag, annotation.item, annotation.start, annotation.end) - } - } - } - - return builder.toAnnotatedString() -} - -fun extractEntities(text: AnnotatedString, knownCustomEmojis: Map): List { - val entities = mutableListOf() - - text.getStringAnnotations(RICH_ENTITY_TAG, 0, text.length).forEach { annotation -> - val type = decodeRichEntity(annotation.item) ?: return@forEach - if (annotation.start < annotation.end) { - entities.add( - MessageEntity( - offset = annotation.start, - length = annotation.end - annotation.start, - type = type - ) - ) - } - } - - // Custom Emojis - text.getStringAnnotations(CUSTOM_EMOJI_TAG, 0, text.length).forEach { annotation -> - val stickerId = annotation.item.toLongOrNull() - if (stickerId != null) { - val sticker = knownCustomEmojis[stickerId] - entities.add( - MessageEntity( - offset = annotation.start, - length = annotation.end - annotation.start, - type = MessageEntityType.CustomEmoji(stickerId, sticker?.path) - ) - ) - } - } - - // Text Mentions (for users without username) - text.getStringAnnotations(MENTION_TAG, 0, text.length).forEach { annotation -> - val userId = annotation.item.toLongOrNull() - if (userId != null) { - entities.add( - MessageEntity( - offset = annotation.start, - length = annotation.end - annotation.start, - type = MessageEntityType.TextMention(userId) - ) - ) - } - } - - // Regular Mentions - val mentionRegex = Regex("@(\\w+)") - mentionRegex.findAll(text.text).forEach { match -> - if (entities.none { it.offset <= match.range.first && it.offset + it.length >= match.range.last + 1 }) { - entities.add( - MessageEntity( - offset = match.range.first, - length = match.range.last - match.range.first + 1, - type = MessageEntityType.Mention - ) - ) - } - } - - return entities - .sortedWith(compareBy { it.offset }.thenByDescending { it.length }) - .distinctBy { Triple(it.offset, it.length, it.type) } -} - -internal fun richEntityToAnnotation(type: MessageEntityType): String? { - return when (type) { - is MessageEntityType.Bold -> ENTITY_BOLD - is MessageEntityType.Italic -> ENTITY_ITALIC - is MessageEntityType.Underline -> ENTITY_UNDERLINE - is MessageEntityType.Strikethrough -> ENTITY_STRIKE - is MessageEntityType.Spoiler -> ENTITY_SPOILER - is MessageEntityType.Code -> ENTITY_CODE - is MessageEntityType.Pre -> if (type.language.isBlank()) ENTITY_PRE else "$ENTITY_PRE:${type.language}" - is MessageEntityType.TextUrl -> "$ENTITY_TEXT_URL:${type.url}" - else -> null - } -} - -internal fun decodeRichEntity(value: String): MessageEntityType? { - return when { - value == ENTITY_BOLD -> MessageEntityType.Bold - value == ENTITY_ITALIC -> MessageEntityType.Italic - value == ENTITY_UNDERLINE -> MessageEntityType.Underline - value == ENTITY_STRIKE -> MessageEntityType.Strikethrough - value == ENTITY_SPOILER -> MessageEntityType.Spoiler - value == ENTITY_CODE -> MessageEntityType.Code - value == ENTITY_PRE -> MessageEntityType.Pre() - value.startsWith("$ENTITY_PRE:") -> MessageEntityType.Pre(value.substringAfter(':')) - value.startsWith("$ENTITY_TEXT_URL:") -> MessageEntityType.TextUrl(value.substringAfter(':')) - else -> null - } -} - -private fun MessageEntityType.toEditorStyle(primaryColor: Color): SpanStyle? { - val codeBackground = primaryColor.copy(alpha = 0.14f) - val spoilerBackground = primaryColor.copy(alpha = 0.25f) - return when (this) { - is MessageEntityType.Bold -> SpanStyle(fontWeight = FontWeight.Bold) - is MessageEntityType.Italic -> SpanStyle(fontStyle = FontStyle.Italic) - is MessageEntityType.Underline -> SpanStyle(textDecoration = TextDecoration.Underline) - is MessageEntityType.Strikethrough -> SpanStyle(textDecoration = TextDecoration.LineThrough) - is MessageEntityType.Spoiler -> SpanStyle(background = spoilerBackground) - is MessageEntityType.Code -> SpanStyle(fontFamily = FontFamily.Monospace, background = codeBackground) - is MessageEntityType.Pre -> SpanStyle(fontFamily = FontFamily.Monospace, background = codeBackground) - is MessageEntityType.TextUrl -> SpanStyle(color = primaryColor, textDecoration = TextDecoration.Underline) - else -> null - } -} - -internal fun toggleRichEntity(textValue: TextFieldValue, type: MessageEntityType): TextFieldValue { - return applyRichEntity(textValue, type, toggle = true) -} - -private fun applyRichEntity(textValue: TextFieldValue, type: MessageEntityType, toggle: Boolean): TextFieldValue { - val selection = textValue.selection.normalized() - if (selection.collapsed) return textValue - - val applicableSelectionRanges = getFormattableSelectionRanges(textValue, selection) - if (applicableSelectionRanges.isEmpty()) return textValue - - val targetKey = richEntityToAnnotation(type) ?: return textValue - val oldText = textValue.annotatedString - val richAnnotations = oldText.getStringAnnotations(RICH_ENTITY_TAG, 0, oldText.length) - - val sameTypeIntervals = richAnnotations - .filter { it.item == targetKey } - .map { Interval(it.start, it.end) } - - val fullyCovered = if (toggle) { - applicableSelectionRanges.all { range -> - isSelectionFullyCovered( - selection = TextRange(range.start, range.end), - intervals = sameTypeIntervals - ) - } - } else { - false - } - - val builder = AnnotatedString.Builder(oldText.text) - - richAnnotations.forEach { annotation -> - val start = annotation.start - val end = annotation.end - if (start >= end) return@forEach - - if (annotation.item == targetKey && overlapsAny(start, end, applicableSelectionRanges)) { - subtractRanges(Interval(start, end), applicableSelectionRanges).forEach { segment -> - builder.addStringAnnotation(RICH_ENTITY_TAG, annotation.item, segment.start, segment.end) - } - } else { - builder.addStringAnnotation(RICH_ENTITY_TAG, annotation.item, start, end) - } - } - - oldText.getStringAnnotations(0, oldText.length) - .filter { it.tag != RICH_ENTITY_TAG } - .forEach { annotation -> - builder.addStringAnnotation(annotation.tag, annotation.item, annotation.start, annotation.end) - } - - if (!fullyCovered) { - applicableSelectionRanges.forEach { range -> - builder.addStringAnnotation(RICH_ENTITY_TAG, targetKey, range.start, range.end) - } - } - - return textValue.copy(annotatedString = builder.toAnnotatedString(), selection = selection) -} - -internal fun clearRichFormatting(textValue: TextFieldValue): TextFieldValue { - val selection = textValue.selection.normalized() - if (selection.collapsed) return textValue - - val oldText = textValue.annotatedString - val builder = AnnotatedString.Builder(oldText.text) - - oldText.getStringAnnotations(RICH_ENTITY_TAG, 0, oldText.length).forEach { annotation -> - val start = annotation.start - val end = annotation.end - if (start >= end) return@forEach - if (!overlaps(start, end, selection.start, selection.end)) { - builder.addStringAnnotation(RICH_ENTITY_TAG, annotation.item, start, end) - } else { - if (start < selection.start) { - builder.addStringAnnotation(RICH_ENTITY_TAG, annotation.item, start, selection.start) - } - if (end > selection.end) { - builder.addStringAnnotation(RICH_ENTITY_TAG, annotation.item, selection.end, end) - } - } - } - - oldText.getStringAnnotations(0, oldText.length) - .filter { it.tag != RICH_ENTITY_TAG } - .forEach { annotation -> - builder.addStringAnnotation(annotation.tag, annotation.item, annotation.start, annotation.end) - } - - return textValue.copy(annotatedString = builder.toAnnotatedString(), selection = selection) -} - -internal fun applyTextUrlEntity(textValue: TextFieldValue, url: String): TextFieldValue { - return applyRichEntity(textValue, MessageEntityType.TextUrl(url), toggle = false) -} - -internal fun applyPreEntity(textValue: TextFieldValue, language: String): TextFieldValue { - val normalizedLanguage = language.trim() - val entityType = - if (normalizedLanguage.isEmpty()) MessageEntityType.Pre() else MessageEntityType.Pre(normalizedLanguage) - return applyRichEntity(textValue, entityType, toggle = false) -} - -internal fun hasFormattableSelection(textValue: TextFieldValue): Boolean { - val selection = textValue.selection.normalized() - if (selection.collapsed) return false - return getFormattableSelectionRanges(textValue, selection).isNotEmpty() -} - -private fun getFormattableSelectionRanges(textValue: TextFieldValue, selection: TextRange): List { - val normalized = selection.normalized() - if (normalized.collapsed) return emptyList() - - val blocked = mutableListOf() - - textValue.annotatedString.getStringAnnotations(CUSTOM_EMOJI_TAG, 0, textValue.annotatedString.length) - .forEach { annotation -> - if (annotation.start < annotation.end) { - blocked += Interval(annotation.start, annotation.end) - } - } - - blocked += detectEmojiIntervals(textValue.text) - - return subtractRanges(Interval(normalized.start, normalized.end), blocked) -} - -private fun detectEmojiIntervals(text: String): List { - if (text.isEmpty()) return emptyList() - - val intervals = mutableListOf() - var index = 0 - while (index < text.length) { - val cp = Character.codePointAt(text, index) - val cpLength = Character.charCount(cp) - val nextIndex = index + cpLength - if (isEmojiCodePoint(cp)) { - intervals += Interval(index, nextIndex) - } - index = nextIndex - } - return intervals -} - -private fun isEmojiCodePoint(codePoint: Int): Boolean { - return codePoint in 0x1F1E6..0x1F1FF || - codePoint in 0x1F300..0x1FAFF || - codePoint in 0x2600..0x27BF || - codePoint in 0xFE00..0xFE0F || - codePoint in 0x1F3FB..0x1F3FF || - codePoint == 0x200D || - codePoint == 0x20E3 -} - -private fun overlapsAny(start: Int, end: Int, ranges: List): Boolean { - return ranges.any { overlaps(start, end, it.start, it.end) } -} - -private fun subtractRanges(source: Interval, blockedRanges: List): List { - if (source.start >= source.end) return emptyList() - if (blockedRanges.isEmpty()) return listOf(source) - - val relevant = blockedRanges - .filter { overlaps(source.start, source.end, it.start, it.end) } - .sortedBy { it.start } - - if (relevant.isEmpty()) return listOf(source) - - var cursor = source.start - val result = mutableListOf() - - relevant.forEach { blocked -> - val cutStart = blocked.start.coerceIn(source.start, source.end) - val cutEnd = blocked.end.coerceIn(source.start, source.end) - if (cutStart > cursor) { - result += Interval(cursor, cutStart) - } - cursor = maxOf(cursor, cutEnd) - } - - if (cursor < source.end) { - result += Interval(cursor, source.end) - } - - return result -} - -private fun isSelectionFullyCovered(selection: TextRange, intervals: List): Boolean { - if (selection.collapsed) return false - if (intervals.isEmpty()) return false - - val merged = intervals - .filter { it.end > selection.start && it.start < selection.end } - .sortedBy { it.start } - .fold(mutableListOf()) { acc, interval -> - if (acc.isEmpty()) { - acc += interval - } else { - val last = acc.last() - if (interval.start <= last.end) { - acc[acc.lastIndex] = Interval(last.start, maxOf(last.end, interval.end)) - } else { - acc += interval - } - } - acc - } - - var cursor = selection.start - merged.forEach { interval -> - if (interval.start > cursor) return false - cursor = maxOf(cursor, interval.end) - if (cursor >= selection.end) return true - } - return cursor >= selection.end -} - -private fun overlaps(startA: Int, endA: Int, startB: Int, endB: Int): Boolean { - return startA < endB && endA > startB -} - -private fun TextRange.normalized(): TextRange { - return if (start <= end) this else TextRange(end, start) -} - -private fun normalizeUrl(raw: String): String? { - val trimmed = raw.trim() - if (trimmed.isEmpty()) return null - return if (trimmed.contains("://")) trimmed else "https://$trimmed" -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/InputTextFieldContainer.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/InputTextFieldContainer.kt deleted file mode 100644 index ef7bd35c..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/InputTextFieldContainer.kt +++ /dev/null @@ -1,166 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.inputbar - -import androidx.compose.animation.animateContentSize -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Edit -import androidx.compose.material.icons.filled.Keyboard -import androidx.compose.material.icons.filled.Menu -import androidx.compose.material.icons.outlined.EmojiEmotions -import androidx.compose.material.icons.rounded.Language -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.input.TextFieldValue -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.BotCommandModel -import org.monogram.domain.models.BotMenuButtonModel -import org.monogram.domain.models.StickerModel -import org.monogram.presentation.R - -@Composable -fun InputTextFieldContainer( - textValue: TextFieldValue, - onValueChange: (TextFieldValue) -> Unit, - onRichTextValueChange: (TextFieldValue) -> Unit = onValueChange, - isBot: Boolean, - botMenuButton: BotMenuButtonModel, - botCommands: List, - canSendStickers: Boolean, - canWriteText: Boolean, - isStickerMenuVisible: Boolean, - onStickerMenuToggle: () -> Unit, - onShowBotCommands: () -> Unit, - onOpenMiniApp: (String, String) -> Unit, - knownCustomEmojis: Map, - emojiFontFamily: FontFamily, - focusRequester: FocusRequester, - pendingMediaPaths: List, - onFocus: () -> Unit = {}, - onOpenFullScreenEditor: () -> Unit = {}, - modifier: Modifier = Modifier -) { - Surface( - modifier = modifier.animateContentSize(), - shape = RoundedCornerShape(24.dp), - color = MaterialTheme.colorScheme.surfaceVariant - ) { - Row( - verticalAlignment = Alignment.Bottom, - modifier = Modifier.padding(start = 4.dp, end = 12.dp, top = 4.dp, bottom = 4.dp) - ) { - val showBotActions = remember(isBot, textValue.text) { isBot && textValue.text.isEmpty() } - if (showBotActions) { - BotInputActions( - botMenuButton = botMenuButton, - botCommands = botCommands, - canSendStickers = canSendStickers, - isStickerMenuVisible = isStickerMenuVisible, - onStickerMenuToggle = onStickerMenuToggle, - onShowBotCommands = onShowBotCommands, - onOpenMiniApp = onOpenMiniApp - ) - } else if (canSendStickers) { - IconButton( - onClick = onStickerMenuToggle, - modifier = Modifier.size(40.dp) - ) { - Icon( - imageVector = if (isStickerMenuVisible) Icons.Default.Keyboard else Icons.Outlined.EmojiEmotions, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } else { - Spacer(modifier = Modifier.width(8.dp)) - } - - InputTextField( - textValue = textValue, - onValueChange = onValueChange, - onRichTextValueChange = onRichTextValueChange, - canWriteText = canWriteText, - knownCustomEmojis = knownCustomEmojis, - emojiFontFamily = emojiFontFamily, - focusRequester = focusRequester, - pendingMediaPaths = pendingMediaPaths, - onFocus = onFocus, - modifier = Modifier.weight(1f) - ) - - if (canWriteText) { - IconButton( - onClick = onOpenFullScreenEditor, - modifier = Modifier - .align(Alignment.CenterVertically) - .size(36.dp) - ) { - Icon( - imageVector = Icons.Default.Edit, - contentDescription = stringResource(R.string.action_open_fullscreen_editor), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } - } -} - -@Composable -private fun BotInputActions( - botMenuButton: BotMenuButtonModel, - botCommands: List, - canSendStickers: Boolean, - isStickerMenuVisible: Boolean, - onStickerMenuToggle: () -> Unit, - onShowBotCommands: () -> Unit, - onOpenMiniApp: (String, String) -> Unit -) { - Row(verticalAlignment = Alignment.CenterVertically) { - if (botMenuButton is BotMenuButtonModel.WebApp) { - IconButton( - onClick = { onOpenMiniApp(botMenuButton.url, botMenuButton.text) }, - modifier = Modifier.size(40.dp) - ) { - Icon( - imageVector = Icons.Rounded.Language, - contentDescription = botMenuButton.text, - tint = MaterialTheme.colorScheme.primary - ) - } - } - - if (botCommands.isNotEmpty()) { - IconButton( - onClick = onShowBotCommands, - modifier = Modifier.size(40.dp) - ) { - Icon( - imageVector = Icons.Default.Menu, - contentDescription = stringResource(R.string.bot_commands), - tint = MaterialTheme.colorScheme.primary - ) - } - } else if (botMenuButton !is BotMenuButtonModel.WebApp && canSendStickers) { - IconButton( - onClick = onStickerMenuToggle, - modifier = Modifier.size(40.dp) - ) { - Icon( - imageVector = if (isStickerMenuVisible) Icons.Default.Keyboard else Icons.Outlined.EmojiEmotions, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/KeyboardMarkupView.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/KeyboardMarkupView.kt deleted file mode 100644 index 6fff6c4f..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/KeyboardMarkupView.kt +++ /dev/null @@ -1,99 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.inputbar - -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.hapticfeedback.HapticFeedbackType -import androidx.compose.ui.platform.LocalClipboardManager -import androidx.compose.ui.platform.LocalHapticFeedback -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.KeyboardButtonModel -import org.monogram.domain.models.KeyboardButtonType -import org.monogram.domain.models.ReplyMarkupModel - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun KeyboardMarkupView( - markup: ReplyMarkupModel.ShowKeyboard, - onButtonClick: (KeyboardButtonModel) -> Unit, - onOpenMiniApp: (String, String) -> Unit = { _, _ -> } -) { - val rows = remember(markup) { markup.rows.filter { it.isNotEmpty() } } - if (rows.isEmpty()) return - - val clipboardManager = LocalClipboardManager.current - val haptic = LocalHapticFeedback.current - - LazyColumn( - modifier = Modifier - .fillMaxWidth() - .heightIn(max = 260.dp) - .background(MaterialTheme.colorScheme.surface), - verticalArrangement = Arrangement.spacedBy(8.dp), - contentPadding = PaddingValues(8.dp) - ) { - items(rows) { row -> - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - row.forEach { button -> - Surface( - modifier = Modifier - .weight(1f) - .height(48.dp) - .clip(RoundedCornerShape(12.dp)) - .combinedClickable( - onClick = { - if (button.type is KeyboardButtonType.WebApp) { - onOpenMiniApp((button.type as KeyboardButtonType.WebApp).url, button.text) - } else { - onButtonClick(button) - } - }, - onLongClick = { - val dataToCopy = when (val type = button.type) { - is KeyboardButtonType.WebApp -> type.url - else -> button.text - } - - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - clipboardManager.setText(AnnotatedString(dataToCopy)) - } - ), - shape = RoundedCornerShape(12.dp), - color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.6f), - ) { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - Text( - text = button.text, - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurface, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.padding(horizontal = 8.dp) - ) - } - } - } - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/MentionSuggestions.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/MentionSuggestions.kt deleted file mode 100644 index 4b52ec90..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/MentionSuggestions.kt +++ /dev/null @@ -1,77 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.inputbar - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.UserModel -import org.monogram.domain.models.UserStatusType -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.util.getUserStatusText -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -@Composable -fun MentionSuggestions( - suggestions: List, - videoPlayerPool: VideoPlayerPool, - onMentionClick: (UserModel) -> Unit -) { - val context = LocalContext.current - Column( - modifier = Modifier - .fillMaxWidth() - .heightIn(max = 240.dp) - .background(MaterialTheme.colorScheme.surface) - ) { - LazyColumn( - contentPadding = PaddingValues(vertical = 4.dp) - ) { - items(suggestions, key = { it.id }) { user -> - Row( - modifier = Modifier - .fillMaxWidth() - .clickable { onMentionClick(user) } - .padding(horizontal = 16.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Avatar( - path = user.avatarPath, - fallbackPath = user.personalAvatarPath, - name = user.firstName, - size = 36.dp, - isOnline = user.userStatus == UserStatusType.ONLINE, - videoPlayerPool = videoPlayerPool - ) - Spacer(modifier = Modifier.width(12.dp)) - Column(modifier = Modifier.weight(1f)) { - Text( - text = "${user.firstName} ${user.lastName ?: ""}".trim(), - style = MaterialTheme.typography.bodyLarge.copy(fontWeight = FontWeight.Medium), - color = MaterialTheme.colorScheme.onSurface, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - val status = user.username?.let { "@$it" } ?: getUserStatusText(user, context) - Text( - text = status, - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.primary, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - } - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/RecordingUI.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/RecordingUI.kt deleted file mode 100644 index dcc71a55..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/RecordingUI.kt +++ /dev/null @@ -1,276 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.inputbar - -import androidx.compose.animation.* -import androidx.compose.animation.core.* -import androidx.compose.foundation.Canvas -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Delete -import androidx.compose.material.icons.filled.KeyboardArrowUp -import androidx.compose.material.icons.filled.Lock -import androidx.compose.material.icons.filled.Send -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.scale -import androidx.compose.ui.geometry.CornerRadius -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.geometry.Size -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.presentation.R - -@Composable -fun RecordingUI( - voiceRecorderState: VoiceRecorderState, - onStop: () -> Unit, - onCancel: () -> Unit, - modifier: Modifier = Modifier -) { - val slideToCancelAlpha by animateFloatAsState( - targetValue = if (voiceRecorderState.isLocked) 0f else 1f, - animationSpec = tween(300), - label = "SlideToCancelAlpha" - ) - - val animatedAmplitude by animateFloatAsState( - targetValue = if (voiceRecorderState.isRecording) { - 1f + (voiceRecorderState.amplitude + 60f) / 60f - } else 1f, - animationSpec = spring(dampingRatio = Spring.DampingRatioMediumBouncy), - label = "AmplitudeScale" - ) - - val infiniteTransition = rememberInfiniteTransition(label = "RecordingDot") - val dotAlpha by infiniteTransition.animateFloat( - initialValue = 1f, - targetValue = 0.5f, - animationSpec = infiniteRepeatable( - animation = tween(800, easing = LinearEasing), - repeatMode = RepeatMode.Reverse - ), - label = "DotAlpha" - ) - - val lockHintTransition = rememberInfiniteTransition(label = "LockHint") - val lockHintOffset by lockHintTransition.animateFloat( - initialValue = 0f, - targetValue = -4f, - animationSpec = infiniteRepeatable( - animation = tween(1000, easing = FastOutSlowInEasing), - repeatMode = RepeatMode.Reverse - ), - label = "LockHintOffset" - ) - - Row( - modifier = modifier - .fillMaxWidth() - .height(52.dp) - .clip(RoundedCornerShape(26.dp)) - .background( - MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.95f) - ) - .padding(horizontal = 4.dp), - verticalAlignment = Alignment.CenterVertically - ) { - AnimatedContent( - targetState = voiceRecorderState.isLocked, - transitionSpec = { - fadeIn() + slideInHorizontally { -it } togetherWith fadeOut() + slideOutHorizontally { -it } - }, - label = "LeftAction" - ) { isLocked -> - if (isLocked) { - IconButton( - onClick = onCancel, - modifier = Modifier.size(44.dp) - ) { - Icon( - imageVector = Icons.Default.Delete, - contentDescription = stringResource(R.string.recording_delete), - tint = MaterialTheme.colorScheme.error - ) - } - } else { - Box(modifier = Modifier.width(44.dp)) - } - } - - Row( - modifier = Modifier.weight(1f), - horizontalArrangement = Arrangement.Start, - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .padding(start = 12.dp) - .size(10.dp) - .scale(animatedAmplitude) - .alpha(dotAlpha) - .background(Color.Red, CircleShape) - ) - Spacer(modifier = Modifier.width(12.dp)) - Text( - text = formatDuration((voiceRecorderState.durationMillis / 1000).toInt()), - style = MaterialTheme.typography.bodyLarge.copy( - fontWeight = FontWeight.Bold, - fontFeatureSettings = "tnum" - ), - color = MaterialTheme.colorScheme.onSurface - ) - } - - Box( - modifier = Modifier.weight(1.5f), - contentAlignment = Alignment.Center - ) { - if (!voiceRecorderState.isLocked) { - Text( - text = stringResource(R.string.recording_slide_to_cancel), - modifier = Modifier - .alpha(slideToCancelAlpha) - .fillMaxWidth(), - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.onSurfaceVariant, - fontSize = 14.sp, - fontWeight = FontWeight.Normal - ) - } else { - WaveformView( - waveform = voiceRecorderState.waveform, - modifier = Modifier - .fillMaxWidth() - .height(36.dp) - .padding(horizontal = 12.dp) - ) - } - } - - AnimatedContent( - targetState = voiceRecorderState.isLocked, - transitionSpec = { - (scaleIn() + fadeIn()).togetherWith(scaleOut() + fadeOut()) - }, - label = "RightAction" - ) { isLocked -> - if (isLocked) { - IconButton( - onClick = onStop, - modifier = Modifier - .size(44.dp) - .background(MaterialTheme.colorScheme.primary, CircleShape) - ) { - Icon( - imageVector = Icons.Default.Send, - contentDescription = stringResource(R.string.recording_send), - tint = MaterialTheme.colorScheme.onPrimary, - modifier = Modifier.size(20.dp) - ) - } - } else { - Column( - modifier = Modifier - .padding(end = 8.dp) - .width(64.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center - ) { - Icon( - imageVector = Icons.Default.KeyboardArrowUp, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier - .size(14.dp) - .offset(y = lockHintOffset.dp) - ) - Icon( - imageVector = Icons.Default.Lock, - contentDescription = stringResource(R.string.recording_lock), - tint = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.size(16.dp) - ) - Text( - text = stringResource(R.string.recording_swipe_up), - color = MaterialTheme.colorScheme.onSurfaceVariant, - fontSize = 9.sp, - fontWeight = FontWeight.Bold, - textAlign = TextAlign.Center - ) - } - } - } - } -} - -@Composable -fun WaveformView( - waveform: List, - modifier: Modifier = Modifier, - color: Color = MaterialTheme.colorScheme.primary -) { - val barWidth = 2.5.dp - val gap = 2.dp - val fadeColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.8f) - - Canvas(modifier = modifier) { - val width = size.width - val height = size.height - val barWidthPx = barWidth.toPx() - val gapPx = gap.toPx() - val totalBarWidthPx = barWidthPx + gapPx - - val maxBars = (width / totalBarWidthPx).toInt() - val barsToShow = waveform.takeLast(maxBars) - - barsToShow.asReversed().forEachIndexed { index, amplitude -> - val normalizedAmplitude = (amplitude.toFloat() / 31f).coerceIn(0f, 1f) - val minHeight = height * 0.15f - val maxHeight = height * 0.85f - val barHeight = minHeight + (normalizedAmplitude * (maxHeight - minHeight)) - - val x = width - (index + 1) * totalBarWidthPx - val y = (height - barHeight) / 2 - - val alpha = (1f - (index.toFloat() / maxBars)).coerceIn(0.2f, 1f) - - drawRoundRect( - color = color.copy(alpha = alpha), - topLeft = Offset(x, y), - size = Size(barWidthPx, barHeight), - cornerRadius = CornerRadius(barWidthPx / 2, barWidthPx / 2) - ) - } - - drawRect( - brush = Brush.horizontalGradient( - 0f to fadeColor, - 0.2f to Color.Transparent, - startX = 0f, - endX = width * 0.3f - ), - size = Size(width * 0.3f, height) - ) - } -} - -private fun formatDuration(seconds: Int): String { - val m = seconds / 60 - val s = seconds % 60 - return String.format("%02d:%02d", m, s) -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/VoiceRecorder.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/VoiceRecorder.kt deleted file mode 100644 index 8306d077..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/inputbar/VoiceRecorder.kt +++ /dev/null @@ -1,185 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.inputbar - -import android.Manifest -import android.content.Context -import android.content.pm.PackageManager -import android.media.MediaRecorder -import android.os.Build -import androidx.compose.runtime.* -import androidx.compose.ui.platform.LocalContext -import androidx.core.content.ContextCompat -import kotlinx.coroutines.delay -import java.io.File -import kotlin.math.log10 - -@Composable -fun rememberVoiceRecorder( - onRecordingFinished: (String, Int, ByteArray) -> Unit -): VoiceRecorderState { - val context = LocalContext.current - val state = remember { VoiceRecorderState(context) } - - LaunchedEffect(onRecordingFinished) { - state.onRecordingFinished = onRecordingFinished - } - - DisposableEffect(Unit) { - onDispose { - state.stopRecording(cancel = true) - } - } - - LaunchedEffect(state.isRecording) { - if (state.isRecording) { - state.runUpdateLoop() - } - } - - return state -} - -class VoiceRecorderState(private val context: Context) { - var isRecording by mutableStateOf(false) - private set - var isLocked by mutableStateOf(false) - private set - var durationMillis by mutableLongStateOf(0L) - private set - var amplitude by mutableFloatStateOf(0f) - private set - - val waveform = mutableStateListOf() - - private var mediaRecorder: MediaRecorder? = null - private var currentFile: File? = null - private var startTime = 0L - - var onRecordingFinished: ((String, Int, ByteArray) -> Unit)? = null - - @Suppress("DEPRECATION") - fun startRecording() { - if (isRecording) return - - if (ContextCompat.checkSelfPermission( - context, - Manifest.permission.RECORD_AUDIO - ) != PackageManager.PERMISSION_GRANTED - ) { - // TODO: Request permission - return - } - - try { - val supportsOggOpus = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q - val extension = if (supportsOggOpus) "ogg" else "m4a" - - val file = File(context.cacheDir, "voice_note_${System.currentTimeMillis()}.$extension") - currentFile = file - waveform.clear() - - mediaRecorder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - MediaRecorder(context) - } else { - MediaRecorder() - } - - mediaRecorder?.apply { - setAudioSource(MediaRecorder.AudioSource.VOICE_RECOGNITION) - - if (supportsOggOpus) { - setOutputFormat(MediaRecorder.OutputFormat.OGG) - setAudioEncoder(MediaRecorder.AudioEncoder.OPUS) - setAudioEncodingBitRate(320000) - setAudioSamplingRate(48000) - } else { - setOutputFormat(MediaRecorder.OutputFormat.MPEG_4) - setAudioEncoder(MediaRecorder.AudioEncoder.AAC) - setAudioEncodingBitRate(320000) - setAudioSamplingRate(48000) - } - - setOutputFile(file.absolutePath) - prepare() - start() - } - - startTime = System.currentTimeMillis() - isRecording = true - isLocked = false - durationMillis = 0 - } catch (e: Exception) { - e.printStackTrace() - releaseResources() - isRecording = false - } - } - - private fun releaseResources() { - mediaRecorder?.let { recorder -> - try { - recorder.stop() - } catch (e: Exception) { - // Ignore: stop() can fail if called too soon after start() - } finally { - try { - recorder.release() - } catch (e: Exception) { - // Ignore - } - } - } - mediaRecorder = null - } - - fun lockRecording() { - if (isRecording) { - isLocked = true - } - } - - fun stopRecording(cancel: Boolean = false) { - if (!isRecording) return - - val capturedDurationMillis = durationMillis - val wasRecording = isRecording - val file = currentFile - - releaseResources() - isRecording = false - isLocked = false - currentFile = null - - if (wasRecording && !cancel && file != null) { - val durationSec = (capturedDurationMillis / 1000).toInt() - if (durationSec >= 1) { - onRecordingFinished?.invoke(file.absolutePath, durationSec, waveform.toByteArray()) - } else { - file.delete() - } - } else { - file?.delete() - } - } - - suspend fun runUpdateLoop() { - while (isRecording) { - durationMillis = System.currentTimeMillis() - startTime - - val maxAmp = try { - mediaRecorder?.maxAmplitude ?: 0 - } catch (e: Exception) { - 0 - } - - amplitude = if (maxAmp > 0) { - (20 * log10(maxAmp.toDouble() / 32767.0)).toFloat().coerceIn(-60f, 0f) - } else -60f - - // Map -60..0 to 0..31 for TDLib waveform - val normalized = ((amplitude + 60) / 60 * 31).toInt().coerceIn(0, 31) - waveform.add(normalized.toByte()) - - delay(100) - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/pins/PinnedMessageBar.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/pins/PinnedMessageBar.kt deleted file mode 100644 index fb12395d..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/pins/PinnedMessageBar.kt +++ /dev/null @@ -1,165 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.pins - -import androidx.compose.animation.* -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.spring -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.rounded.FormatListBulleted -import androidx.compose.material.icons.rounded.PushPin -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.R - -@Composable -fun PinnedMessageBar( - message: MessageModel, - count: Int, - onClose: () -> Unit, - onClick: () -> Unit, - onShowAll: () -> Unit -) { - Surface( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 12.dp, vertical = 6.dp) - .clip(RoundedCornerShape(16.dp)) - .clickable(onClick = if (count > 1) onShowAll else onClick), - color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.8f), - tonalElevation = 4.dp - ) { - Row( - modifier = Modifier - .padding(start = 16.dp, end = 8.dp, top = 10.dp, bottom = 10.dp) - .height(IntrinsicSize.Min), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .width(4.dp) - .fillMaxHeight() - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primary) - ) - - Spacer(modifier = Modifier.width(16.dp)) - - Column( - modifier = Modifier - .weight(1f) - .padding(vertical = 2.dp) - ) { - Row(verticalAlignment = Alignment.CenterVertically) { - Icon( - imageVector = Icons.Rounded.PushPin, - contentDescription = null, - modifier = Modifier.size(14.dp), - tint = MaterialTheme.colorScheme.primary - ) - Spacer(modifier = Modifier.width(6.dp)) - Text( - text = if (count > 1) stringResource(R.string.pinned_messages) else stringResource(R.string.pinned_message), - style = MaterialTheme.typography.labelLarge.copy( - fontWeight = FontWeight.ExtraBold, - color = MaterialTheme.colorScheme.primary, - letterSpacing = 0.1.sp - ) - ) - if (count > 1) { - Surface( - modifier = Modifier.padding(start = 8.dp), - color = MaterialTheme.colorScheme.primary.copy(alpha = 0.15f), - shape = CircleShape - ) { - Text( - text = count.toString(), - modifier = Modifier.padding(horizontal = 8.dp, vertical = 2.dp), - style = MaterialTheme.typography.labelSmall.copy( - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.primary - ) - ) - } - } - } - - Spacer(modifier = Modifier.height(2.dp)) - - AnimatedContent( - targetState = message, - transitionSpec = { - (slideInVertically(animationSpec = spring(stiffness = Spring.StiffnessLow)) { it } + fadeIn()) - .togetherWith(slideOutVertically(animationSpec = spring(stiffness = Spring.StiffnessLow)) { -it } + fadeOut()) - }, - label = "PinnedMessageContent" - ) { msg -> - val text = when (val content = msg.content) { - is MessageContent.Text -> content.text - is MessageContent.Photo -> content.caption.ifEmpty { stringResource(R.string.chat_mapper_photo) } - is MessageContent.Sticker -> stringResource(R.string.message_type_sticker_format, content.emoji) - is MessageContent.Video -> content.caption.ifEmpty { stringResource(R.string.chat_mapper_video) } - is MessageContent.VideoNote -> stringResource(R.string.message_type_video_message) - is MessageContent.Voice -> stringResource(R.string.chat_mapper_voice) - is MessageContent.Gif -> content.caption.ifEmpty { stringResource(R.string.message_type_gif) } - is MessageContent.Document -> content.caption.ifEmpty { stringResource(R.string.message_type_document) } - is MessageContent.Poll -> stringResource(R.string.message_type_poll_format, content.question) - else -> stringResource(R.string.chat_mapper_message) - } - - Text( - text = text, - style = MaterialTheme.typography.bodyMedium.copy( - lineHeight = 18.sp - ), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - color = MaterialTheme.colorScheme.onSurface - ) - } - } - - Row(verticalAlignment = Alignment.CenterVertically) { - if (count > 1) { - IconButton( - onClick = onShowAll, - modifier = Modifier.size(40.dp) - ) { - Icon( - imageVector = Icons.Rounded.FormatListBulleted, - contentDescription = stringResource(R.string.pinned_show_all), - modifier = Modifier.size(22.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - - IconButton( - onClick = onClose, - modifier = Modifier.size(40.dp) - ) { - Icon( - imageVector = Icons.Default.Close, - contentDescription = stringResource(R.string.pinned_unpin), - modifier = Modifier.size(22.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/pins/PinnedMessagesListSheet.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/pins/PinnedMessagesListSheet.kt deleted file mode 100644 index ecd07ad1..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/components/pins/PinnedMessagesListSheet.kt +++ /dev/null @@ -1,217 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.components.pins - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.pluralStringResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.R -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.ChatComponent -import org.monogram.presentation.features.chats.currentChat.chatContent.GroupedMessageItem -import org.monogram.presentation.features.chats.currentChat.chatContent.groupMessagesByAlbum -import org.monogram.presentation.features.chats.currentChat.chatContent.shouldShowDate -import org.monogram.presentation.features.chats.currentChat.components.* - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun PinnedMessagesListSheet( - state: ChatComponent.State, - onDismiss: () -> Unit, - onMessageClick: (MessageModel) -> Unit, - onUnpin: (MessageModel) -> Unit, - onReplyClick: (MessageModel) -> Unit, - onReactionClick: (Long, String) -> Unit, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool, - isAnyViewerOpen: Boolean = false -) { - val messages = state.allPinnedMessages - val groupedMessages = remember(messages) { groupMessagesByAlbum(messages.distinctBy { it.id }) } - val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) - - ModalBottomSheet( - onDismissRequest = onDismiss, - sheetState = sheetState, - containerColor = MaterialTheme.colorScheme.background, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp), - contentColor = MaterialTheme.colorScheme.onSurface, - dragHandle = { BottomSheetDefaults.DragHandle() } - ) { - Column( - modifier = Modifier - .fillMaxSize() - .windowInsetsPadding(WindowInsets.navigationBars) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Text( - text = stringResource(R.string.pinned_messages), - style = MaterialTheme.typography.titleLarge, - fontWeight = FontWeight.Bold - ) - Text( - text = pluralStringResource(R.plurals.pinned_count, messages.size, messages.size), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - - HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp)) - - LazyColumn( - modifier = Modifier - .weight(1f) - .background(MaterialTheme.colorScheme.background.copy(alpha = 0.05f)), - contentPadding = PaddingValues(8.dp) - ) { - itemsIndexed(groupedMessages, key = { _, item -> - when (item) { - is GroupedMessageItem.Single -> "pin_${item.message.id}" - is GroupedMessageItem.Album -> "pin_album_${item.albumId}" - } - }) { index, item -> - val msg = when (item) { - is GroupedMessageItem.Single -> item.message - is GroupedMessageItem.Album -> item.messages.last() - } - - val olderMsg = when (val olderItem = groupedMessages.getOrNull(index + 1)) { - is GroupedMessageItem.Single -> olderItem.message - is GroupedMessageItem.Album -> olderItem.messages.last() - null -> null - } - - val newerMsg = when (val newerItem = groupedMessages.getOrNull(index - 1)) { - is GroupedMessageItem.Single -> newerItem.message - is GroupedMessageItem.Album -> newerItem.messages.first() - null -> null - } - - if (shouldShowDate(msg, olderMsg)) { - DateSeparator(msg.date) - Spacer(modifier = Modifier.height(8.dp)) - } - - Box(modifier = Modifier.animateItem()) { - if (state.isChannel) { - if (item is GroupedMessageItem.Single) { - ChannelMessageBubbleContainer( - msg = item.message, - olderMsg = olderMsg, - newerMsg = newerMsg, - autoplayGifs = state.autoplayGifs, - autoplayVideos = state.autoplayVideos, - autoDownloadFiles = state.autoDownloadFiles, - onPhotoClick = { onMessageClick(it) }, - onVideoClick = { onMessageClick(it) }, - onDocumentClick = { onMessageClick(it) }, - onReplyClick = { _, _, _ -> onMessageClick(item.message) }, - onGoToReply = { onReplyClick(it) }, - onReactionClick = onReactionClick, - fontSize = state.fontSize, - letterSpacing = state.letterSpacing, - bubbleRadius = state.bubbleRadius, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool - ) - } else if (item is GroupedMessageItem.Album) { - AlbumMessageBubbleContainer( - messages = item.messages, - olderMsg = olderMsg, - newerMsg = newerMsg, - isGroup = false, - isChannel = true, - autoplayGifs = state.autoplayGifs, - autoplayVideos = state.autoplayVideos, - onPhotoClick = { onMessageClick(it) }, - onVideoClick = { onMessageClick(it) }, - onReplyClick = { _, _, _ -> onMessageClick(item.messages.last()) }, - onGoToReply = { onReplyClick(it) }, - onReactionClick = onReactionClick, - toProfile = {}, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool - ) - } - } else { - if (item is GroupedMessageItem.Single) { - MessageBubbleContainer( - msg = item.message, - olderMsg = olderMsg, - newerMsg = newerMsg, - isGroup = state.isGroup, - fontSize = state.fontSize, - letterSpacing = state.letterSpacing, - bubbleRadius = state.bubbleRadius, - autoDownloadMobile = state.autoDownloadMobile, - autoDownloadWifi = state.autoDownloadWifi, - autoDownloadRoaming = state.autoDownloadRoaming, - autoDownloadFiles = state.autoDownloadFiles, - autoplayGifs = state.autoplayGifs, - autoplayVideos = state.autoplayVideos, - onPhotoClick = { onMessageClick(it) }, - onVideoClick = { onMessageClick(it) }, - onDocumentClick = { onMessageClick(it) }, - onReplyClick = { _, _, _ -> onMessageClick(item.message) }, - onGoToReply = { onReplyClick(it) }, - onReactionClick = onReactionClick, - toProfile = {}, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool - ) - } else if (item is GroupedMessageItem.Album) { - AlbumMessageBubbleContainer( - messages = item.messages, - olderMsg = olderMsg, - newerMsg = newerMsg, - isGroup = state.isGroup, - isChannel = false, - autoplayGifs = state.autoplayGifs, - autoplayVideos = state.autoplayVideos, - onPhotoClick = { onMessageClick(it) }, - onVideoClick = { onMessageClick(it) }, - onReplyClick = { _, _, _ -> onMessageClick(item.messages.last()) }, - onGoToReply = { onReplyClick(it) }, - onReactionClick = onReactionClick, - toProfile = {}, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool - ) - } - } - } - Spacer(modifier = Modifier.height(4.dp)) - } - } - - Box(modifier = Modifier.padding(16.dp)) { - Button( - onClick = onDismiss, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(text = stringResource(R.string.pinned_close), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/PhotoEditorScreen.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/PhotoEditorScreen.kt deleted file mode 100644 index 291b36c5..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/PhotoEditorScreen.kt +++ /dev/null @@ -1,496 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.editor.photo - -import androidx.activity.compose.BackHandler -import androidx.compose.animation.AnimatedContent -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.foundation.Canvas -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.gestures.detectDragGestures -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.gestures.detectTransformGestures -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.* -import androidx.compose.ui.graphics.drawscope.Stroke -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.IntSize -import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage -import coil3.request.ImageRequest -import kotlinx.coroutines.launch -import org.monogram.presentation.R -import org.monogram.presentation.features.chats.currentChat.editor.photo.components.* -import java.io.File - -enum class EditorTool(val labelRes: Int, val icon: ImageVector) { - NONE(R.string.photo_editor_tool_view, Icons.Rounded.Visibility), - TRANSFORM(R.string.photo_editor_tool_crop, Icons.Rounded.Crop), - FILTER(R.string.photo_editor_tool_filters, Icons.Rounded.AutoAwesome), - DRAW(R.string.photo_editor_tool_draw, Icons.Rounded.Brush), - TEXT(R.string.photo_editor_tool_text, Icons.Rounded.TextFields), - ERASER(R.string.photo_editor_tool_eraser, Icons.Rounded.CleaningServices) -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun PhotoEditorScreen( - imagePath: String, - onClose: () -> Unit, - onSave: (String) -> Unit -) { - val context = LocalContext.current - val scope = rememberCoroutineScope() - - var currentTool by remember { mutableStateOf(EditorTool.NONE) } - - val paths = remember { mutableStateListOf() } - val pathsRedo = remember { mutableStateListOf() } - val textElements = remember { mutableStateListOf() } - - var selectedColor by remember { mutableStateOf(Color.Red) } - var brushSize by remember { mutableFloatStateOf(15f) } - var currentFilter by remember { mutableStateOf(null) } - - var imageRotation by remember { mutableFloatStateOf(0f) } - var imageScale by remember { mutableFloatStateOf(1f) } - var imageOffset by remember { mutableStateOf(Offset.Zero) } - - var showTextDialog by remember { mutableStateOf(false) } - var editingTextElement by remember { mutableStateOf(null) } - - var canvasSize by remember { mutableStateOf(IntSize.Zero) } - var isSaving by remember { mutableStateOf(false) } - var showDiscardDialog by remember { mutableStateOf(false) } - - val hasChanges by remember { - derivedStateOf { - paths.isNotEmpty() || - textElements.isNotEmpty() || - currentFilter != null || - imageRotation != 0f || - imageScale != 1f || - imageOffset != Offset.Zero - } - } - - val handleBack = { - if (currentTool != EditorTool.NONE) { - currentTool = EditorTool.NONE - } else if (hasChanges) { - showDiscardDialog = true - } else { - onClose() - } - } - - BackHandler(onBack = handleBack) - - Scaffold( - containerColor = Color.Black, - topBar = { - EditorTopBar( - onClose = handleBack, - onSave = { - if (!isSaving) { - scope.launch { - isSaving = true - val result = saveImage( - context, - imagePath, - paths, - textElements, - currentFilter, - canvasSize, - imageRotation, - imageScale, - imageOffset - ) - isSaving = false - if (result != null) onSave(result) - } - } - }, - onUndo = { - if (paths.isNotEmpty()) { - pathsRedo.add(paths.removeAt(paths.lastIndex)) - } else if (textElements.isNotEmpty()) { - textElements.removeAt(textElements.lastIndex) - } - }, - onRedo = { - if (pathsRedo.isNotEmpty()) { - paths.add(pathsRedo.removeAt(pathsRedo.lastIndex)) - } - }, - canUndo = paths.isNotEmpty() || textElements.isNotEmpty(), - canRedo = pathsRedo.isNotEmpty() - ) - }, - bottomBar = { - Surface( - color = MaterialTheme.colorScheme.surface.copy(alpha = 0.95f), - tonalElevation = 3.dp, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier.navigationBarsPadding() - ) { - AnimatedContent( - targetState = currentTool, - label = "ToolOptions", - modifier = Modifier.fillMaxWidth() - ) { tool -> - Box( - modifier = Modifier - .fillMaxWidth() - .heightIn(min = 100.dp), - contentAlignment = Alignment.Center - ) { - when (tool) { - EditorTool.TRANSFORM -> { - TransformControls( - rotation = imageRotation, - scale = imageScale, - onRotationChange = { imageRotation = it }, - onScaleChange = { imageScale = it }, - onReset = { - imageRotation = 0f - imageScale = 1f - imageOffset = Offset.Zero - } - ) - } - - EditorTool.DRAW, EditorTool.ERASER -> { - DrawControls( - isEraser = tool == EditorTool.ERASER, - color = selectedColor, - size = brushSize, - onColorChange = { selectedColor = it }, - onSizeChange = { brushSize = it } - ) - } - - EditorTool.FILTER -> { - FilterControls( - imagePath = imagePath, - currentFilter = currentFilter, - onFilterSelect = { currentFilter = it } - ) - } - - EditorTool.TEXT -> { - Button( - onClick = { - editingTextElement = null - showTextDialog = true - }, - shape = RoundedCornerShape(12.dp) - ) { - Icon(Icons.Rounded.Add, contentDescription = null) - Spacer(Modifier.width(8.dp)) - Text(stringResource(R.string.photo_editor_action_add_text)) - } - } - - else -> { - Text( - stringResource(R.string.photo_editor_label_select_tool), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } - } - - NavigationBar( - containerColor = Color.Transparent, - tonalElevation = 0.dp - ) { - EditorTool.entries.forEach { tool -> - val label = stringResource(tool.labelRes) - NavigationBarItem( - selected = currentTool == tool, - onClick = { currentTool = tool }, - icon = { Icon(tool.icon, contentDescription = label) }, - label = { Text(label) }, - colors = NavigationBarItemDefaults.colors( - indicatorColor = MaterialTheme.colorScheme.primaryContainer, - selectedIconColor = MaterialTheme.colorScheme.onPrimaryContainer, - unselectedIconColor = MaterialTheme.colorScheme.onSurfaceVariant, - unselectedTextColor = MaterialTheme.colorScheme.onSurfaceVariant - ) - ) - } - } - } - } - } - ) { paddingValues -> - Box( - modifier = Modifier - .fillMaxSize() - .padding(paddingValues) - .clip(RectangleShape) - .background(Color.Black) - .onGloballyPositioned { canvasSize = it.size } - ) { - Box( - modifier = Modifier - .fillMaxSize() - .graphicsLayer( - scaleX = imageScale, - scaleY = imageScale, - rotationZ = imageRotation, - translationX = imageOffset.x, - translationY = imageOffset.y - ) - .pointerInput(currentTool) { - if (currentTool == EditorTool.TRANSFORM || currentTool == EditorTool.NONE) { - detectTransformGestures { _, pan, zoom, rotation -> - imageScale *= zoom - imageRotation += rotation - imageOffset += pan - } - } - } - ) { - AsyncImage( - model = ImageRequest.Builder(context) - .data(File(imagePath)) - .build(), - contentDescription = null, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Fit, - colorFilter = currentFilter?.let { ColorFilter.colorMatrix(it.colorMatrix) } - ) - - Canvas( - modifier = Modifier - .fillMaxSize() - .pointerInput(currentTool) { - if (currentTool == EditorTool.DRAW || currentTool == EditorTool.ERASER) { - detectDragGestures( - onDragStart = { offset -> - val path = Path().apply { moveTo(offset.x, offset.y) } - paths.add( - DrawnPath( - path = path, - color = if (currentTool == EditorTool.ERASER) Color.Transparent else selectedColor, - strokeWidth = brushSize, - isEraser = currentTool == EditorTool.ERASER - ) - ) - pathsRedo.clear() - }, - onDrag = { change, _ -> - change.consume() - val index = paths.lastIndex - if (index == -1) return@detectDragGestures - - val currentPathData = paths[index] - val x1 = change.previousPosition.x - val y1 = change.previousPosition.y - val x2 = change.position.x - val y2 = change.position.y - - currentPathData.path.quadraticTo( - x1, y1, (x1 + x2) / 2, (y1 + y2) / 2 - ) - - paths.add(paths.removeAt(index)) - } - ) - } - } - ) { - paths.forEach { pathData -> - drawPath( - path = pathData.path, - color = pathData.color, - alpha = pathData.alpha, - style = Stroke( - width = pathData.strokeWidth, - cap = StrokeCap.Round, - join = StrokeJoin.Round - ), - blendMode = if (pathData.isEraser) BlendMode.Clear else BlendMode.SrcOver - ) - } - } - - textElements.forEach { element -> - val density = LocalDensity.current - - var currentOffset by remember(element.id) { - mutableStateOf( - if (element.offset == Offset.Zero) Offset( - canvasSize.width / 2f, - canvasSize.height / 2f - ) else element.offset - ) - } - var currentScale by remember(element.id) { mutableStateOf(element.scale) } - var currentRotation by remember(element.id) { mutableStateOf(element.rotation) } - - Box( - modifier = Modifier - .offset( - x = with(density) { currentOffset.x.toDp() }, - y = with(density) { currentOffset.y.toDp() } - ) - .graphicsLayer( - scaleX = currentScale, - scaleY = currentScale, - rotationZ = currentRotation, - translationX = -with(density) { 100.dp.toPx() }, - translationY = -with(density) { 25.dp.toPx() } - ) - .pointerInput(currentTool, element.id) { - if (currentTool == EditorTool.TEXT || currentTool == EditorTool.NONE) { - detectTransformGestures( - onGesture = { _, pan, zoom, rotation -> - currentOffset += pan - currentScale *= zoom - currentRotation += rotation - } - ) - } - } - .pointerInput(currentTool, element.id) { - if (currentTool == EditorTool.TEXT || currentTool == EditorTool.NONE) { - detectTapGestures(onTap = { - if (currentTool == EditorTool.TEXT) { - editingTextElement = element - selectedColor = element.color - showTextDialog = true - } - }) - } - } - ) { - LaunchedEffect(currentOffset, currentScale, currentRotation) { - val idx = textElements.indexOfFirst { it.id == element.id } - if (idx != -1 && (textElements[idx].offset != currentOffset || textElements[idx].rotation != currentRotation)) { - textElements[idx] = textElements[idx].copy( - offset = currentOffset, - scale = currentScale, - rotation = currentRotation - ) - } - } - - Text( - text = element.text, - color = element.color, - style = MaterialTheme.typography.headlineLarge.copy( - shadow = Shadow( - color = Color.Black, - offset = Offset(2f, 2f), - blurRadius = 4f - ) - ) - ) - - if (currentTool == EditorTool.TEXT) { - Box( - modifier = Modifier - .matchParentSize() - .border(1.dp, Color.White.copy(alpha = 0.5f), RoundedCornerShape(4.dp)) - ) - } - } - } - } - - AnimatedVisibility( - visible = currentTool == EditorTool.TRANSFORM, - enter = fadeIn(), - exit = fadeOut() - ) { - CropOverlay() - } - - if (isSaving) { - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.Black.copy(0.6f)), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator() - } - } - } - } - - if (showDiscardDialog) { - AlertDialog( - onDismissRequest = { showDiscardDialog = false }, - title = { Text(stringResource(R.string.photo_editor_discard_title)) }, - text = { Text(stringResource(R.string.photo_editor_discard_message)) }, - confirmButton = { - TextButton(onClick = onClose) { - Text(stringResource(R.string.photo_editor_discard_button), color = MaterialTheme.colorScheme.error) - } - }, - dismissButton = { - TextButton(onClick = { showDiscardDialog = false }) { - Text(stringResource(R.string.photo_editor_action_cancel)) - } - } - ) - } - - if (showTextDialog) { - TextEntryDialog( - initialText = editingTextElement?.text ?: "", - initialColor = editingTextElement?.color ?: selectedColor, - onDismiss = { - showTextDialog = false - editingTextElement = null - }, - onConfirm = { text, color -> - if (editingTextElement != null) { - val index = textElements.indexOfFirst { it.id == editingTextElement!!.id } - if (index != -1) { - textElements[index] = textElements[index].copy(text = text, color = color) - } - } else { - textElements.add( - TextElement( - text = text, - color = color, - offset = Offset(canvasSize.width / 2f, canvasSize.height / 2f) - ) - ) - } - showTextDialog = false - editingTextElement = null - }, - onDelete = { - editingTextElement?.let { el -> textElements.removeIf { it.id == el.id } } - showTextDialog = false - editingTextElement = null - } - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/PhotoEditorUtils.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/PhotoEditorUtils.kt deleted file mode 100644 index 344bb578..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/PhotoEditorUtils.kt +++ /dev/null @@ -1,226 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.editor.photo - -import android.content.Context -import android.graphics.* -import androidx.annotation.StringRes -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.* -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.ColorMatrix -import androidx.compose.ui.graphics.Path -import androidx.compose.ui.unit.IntSize -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.monogram.presentation.R -import java.io.File -import java.io.FileOutputStream -import java.util.* -import android.graphics.Canvas as AndroidCanvas -import android.graphics.Paint as AndroidPaint - -data class DrawnPath( - val path: Path, - val color: Color, - val strokeWidth: Float, - val alpha: Float = 1f, - val isEraser: Boolean = false -) - -data class TextElement( - val id: String = UUID.randomUUID().toString(), - val text: String, - val color: Color, - val offset: Offset = Offset.Zero, - val scale: Float = 1f, - val rotation: Float = 0f -) - -data class ImageFilter( - @StringRes val nameRes: Int, - val colorMatrix: ColorMatrix -) - -fun getPresetFilters(): List { - return listOf( - ImageFilter(R.string.photo_editor_filter_original, ColorMatrix()), - ImageFilter(R.string.photo_editor_filter_bw, ColorMatrix().apply { setToSaturation(0f) }), - ImageFilter( - R.string.photo_editor_filter_sepia, ColorMatrix( - floatArrayOf( - 0.393f, 0.769f, 0.189f, 0f, 0f, - 0.349f, 0.686f, 0.168f, 0f, 0f, - 0.272f, 0.534f, 0.131f, 0f, 0f, - 0f, 0f, 0f, 1f, 0f - ) - ) - ), - ImageFilter( - R.string.photo_editor_filter_vintage, ColorMatrix( - floatArrayOf( - 0.9f, 0f, 0f, 0f, 0f, - 0f, 0.7f, 0f, 0f, 0f, - 0f, 0f, 0.5f, 0f, 0f, - 0f, 0f, 0f, 1f, 0f - ) - ) - ), - ImageFilter( - R.string.photo_editor_filter_cool, ColorMatrix( - floatArrayOf( - 1f, 0f, 0f, 0f, 0f, - 0f, 1f, 0.5f, 0f, 0f, - 0f, 0f, 1.5f, 0f, 0f, - 0f, 0f, 0f, 1f, 0f - ) - ) - ), - ImageFilter( - R.string.photo_editor_filter_warm, ColorMatrix( - floatArrayOf( - 1.2f, 0f, 0f, 0f, 0f, - 0f, 1f, 0f, 0f, 0f, - 0f, 0f, 0.8f, 0f, 0f, - 0f, 0f, 0f, 1f, 0f - ) - ) - ), - ImageFilter( - R.string.photo_editor_filter_polaroid, ColorMatrix( - floatArrayOf( - 1.438f, -0.062f, -0.062f, 0f, 0f, - -0.122f, 1.378f, -0.122f, 0f, 0f, - -0.016f, -0.016f, 1.483f, 0f, 0f, - 0f, 0f, 0f, 1f, 0f - ) - ) - ), - ImageFilter( - R.string.photo_editor_filter_invert, ColorMatrix( - floatArrayOf( - -1f, 0f, 0f, 0f, 255f, - 0f, -1f, 0f, 0f, 255f, - 0f, 0f, -1f, 0f, 255f, - 0f, 0f, 0f, 1f, 0f - ) - ) - ) - ) -} - -suspend fun saveImage( - context: Context, - originalPath: String, - paths: List, - textElements: List, - filter: ImageFilter?, - canvasSize: IntSize, - imageRotation: Float = 0f, - imageScale: Float = 1f, - imageOffset: Offset = Offset.Zero -): String? = withContext(Dispatchers.IO) { - try { - val options = BitmapFactory.Options().apply { inMutable = true } - var bitmap = BitmapFactory.decodeFile(originalPath, options) ?: return@withContext null - - if (bitmap.config != Bitmap.Config.ARGB_8888) { - val copy = bitmap.copy(Bitmap.Config.ARGB_8888, true) - bitmap.recycle() - bitmap = copy - } - - val bitmapW = bitmap.width.toFloat() - val bitmapH = bitmap.height.toFloat() - val screenW = canvasSize.width.toFloat() - val screenH = canvasSize.height.toFloat() - - val bitmapRatio = bitmapW / bitmapH - val screenRatio = screenW / screenH - - val baseScale: Float - val dx: Float - val dy: Float - - if (bitmapRatio > screenRatio) { - baseScale = screenW / bitmapW - dx = 0f - dy = (screenH - (bitmapH * baseScale)) / 2f - } else { - baseScale = screenH / bitmapH - dy = 0f - dx = (screenW - (bitmapW * baseScale)) / 2f - } - - val resultBitmap = Bitmap.createBitmap(canvasSize.width, canvasSize.height, Bitmap.Config.ARGB_8888) - val canvas = AndroidCanvas(resultBitmap) - - canvas.save() - canvas.translate(imageOffset.x + screenW / 2f, imageOffset.y + screenH / 2f) - canvas.rotate(imageRotation) - canvas.scale(imageScale, imageScale) - canvas.translate(-screenW / 2f, -screenH / 2f) - - val imagePaint = AndroidPaint().apply { - isAntiAlias = true - if (filter != null) { - colorFilter = android.graphics.ColorMatrixColorFilter(filter.colorMatrix.values) - } - } - val destRect = RectF(dx, dy, dx + bitmapW * baseScale, dy + bitmapH * baseScale) - canvas.drawBitmap(bitmap, null, destRect, imagePaint) - - val pathPaint = AndroidPaint().apply { - isAntiAlias = true - style = AndroidPaint.Style.STROKE - strokeCap = AndroidPaint.Cap.ROUND - strokeJoin = AndroidPaint.Join.ROUND - } - - paths.forEach { pathData -> - if (pathData.isEraser) { - pathPaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR) - } else { - pathPaint.xfermode = null - pathPaint.color = pathData.color.toArgb() - pathPaint.alpha = (pathData.alpha * 255).toInt() - } - pathPaint.strokeWidth = pathData.strokeWidth - canvas.drawPath(pathData.path.asAndroidPath(), pathPaint) - } - - val textPaint = AndroidPaint().apply { - isAntiAlias = true - typeface = Typeface.DEFAULT_BOLD - } - - textElements.forEach { element -> - textPaint.color = element.color.toArgb() - textPaint.textSize = 64f * element.scale - - canvas.save() - canvas.translate(element.offset.x, element.offset.y) - canvas.rotate(Math.toDegrees(element.rotation.toDouble()).toFloat()) - - val textWidth = textPaint.measureText(element.text) - val fontMetrics = textPaint.fontMetrics - val textHeight = fontMetrics.descent - fontMetrics.ascent - - canvas.drawText(element.text, -textWidth / 2f, textHeight / 4f, textPaint) - canvas.restore() - } - - canvas.restore() - - val file = File(context.cacheDir, "edited_${System.currentTimeMillis()}.jpg") - FileOutputStream(file).use { out -> - resultBitmap.compress(Bitmap.CompressFormat.JPEG, 95, out) - } - - bitmap.recycle() - resultBitmap.recycle() - - return@withContext file.absolutePath - } catch (e: Exception) { - e.printStackTrace() - return@withContext null - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/ColorSelector.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/ColorSelector.kt deleted file mode 100644 index 369d8c7a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/ColorSelector.kt +++ /dev/null @@ -1,54 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.editor.photo.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp - -@Composable -fun ColorSelector( - selectedColor: Color, - onSelect: (Color) -> Unit -) { - val colors = listOf( - Color.White, Color.Black, Color.Gray, Color.Red, - Color(0xFFFF5722), Color(0xFFFF9800), Color(0xFFFFC107), - Color.Yellow, Color(0xFF8BC34A), Color.Green, - Color(0xFF009688), Color.Cyan, Color(0xFF03A9F4), - Color.Blue, Color(0xFF3F51B5), Color(0xFF673AB7), - Color.Magenta, Color(0xFFE91E63) - ) - - LazyRow( - horizontalArrangement = Arrangement.spacedBy(12.dp), - contentPadding = PaddingValues(horizontal = 4.dp) - ) { - items(colors) { color -> - val isSelected = color == selectedColor - Box( - modifier = Modifier - .size(if (isSelected) 36.dp else 32.dp) - .clip(CircleShape) - .background(color) - .border( - width = if (isSelected) 2.dp else 1.dp, - color = if (isSelected) MaterialTheme.colorScheme.primary else Color.White.copy(alpha = 0.2f), - shape = CircleShape - ) - .clickable { onSelect(color) } - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/CropOverlay.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/CropOverlay.kt deleted file mode 100644 index e9841bfd..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/CropOverlay.kt +++ /dev/null @@ -1,102 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.editor.photo.components - -import androidx.compose.foundation.Canvas -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.geometry.Rect -import androidx.compose.ui.geometry.Size -import androidx.compose.ui.graphics.BlendMode -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.CompositingStrategy -import androidx.compose.ui.graphics.drawscope.Stroke -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.unit.dp - -@Composable -fun CropOverlay( - modifier: Modifier = Modifier -) { - Canvas( - modifier = modifier - .fillMaxSize() - .graphicsLayer(compositingStrategy = CompositingStrategy.Offscreen) - ) { - val width = size.width - val height = size.height - - val padding = 32.dp.toPx() - val cropWidth = width - padding * 2 - val cropHeight = height - padding * 2 - - val rect = Rect( - offset = Offset(padding, padding), - size = Size(cropWidth, cropHeight) - ) - - drawRect( - color = Color.Black.copy(alpha = 0.7f), - size = size - ) - - drawRect( - color = Color.Transparent, - topLeft = rect.topLeft, - size = rect.size, - blendMode = BlendMode.Clear - ) - - val strokeWidth = 1.dp.toPx() - val gridColor = Color.White.copy(alpha = 0.5f) - - drawLine( - color = gridColor, - start = Offset(rect.left + rect.width / 3, rect.top), - end = Offset(rect.left + rect.width / 3, rect.bottom), - strokeWidth = strokeWidth - ) - drawLine( - color = gridColor, - start = Offset(rect.left + rect.width * 2 / 3, rect.top), - end = Offset(rect.left + rect.width * 2 / 3, rect.bottom), - strokeWidth = strokeWidth - ) - - drawLine( - color = gridColor, - start = Offset(rect.left, rect.top + rect.height / 3), - end = Offset(rect.right, rect.top + rect.height / 3), - strokeWidth = strokeWidth - ) - drawLine( - color = gridColor, - start = Offset(rect.left, rect.top + rect.height * 2 / 3), - end = Offset(rect.right, rect.top + rect.height * 2 / 3), - strokeWidth = strokeWidth - ) - - val cornerLen = 24.dp.toPx() - val cornerStroke = 3.dp.toPx() - val cornerColor = Color.White - - drawLine(cornerColor, rect.topLeft, rect.topLeft.copy(x = rect.left + cornerLen), cornerStroke) - drawLine(cornerColor, rect.topLeft, rect.topLeft.copy(y = rect.top + cornerLen), cornerStroke) - - drawLine(cornerColor, rect.topRight, rect.topRight.copy(x = rect.right - cornerLen), cornerStroke) - drawLine(cornerColor, rect.topRight, rect.topRight.copy(y = rect.top + cornerLen), cornerStroke) - - drawLine(cornerColor, rect.bottomLeft, rect.bottomLeft.copy(x = rect.left + cornerLen), cornerStroke) - drawLine(cornerColor, rect.bottomLeft, rect.bottomLeft.copy(y = rect.bottom - cornerLen), cornerStroke) - - drawLine(cornerColor, rect.bottomRight, rect.bottomRight.copy(x = rect.right - cornerLen), cornerStroke) - drawLine(cornerColor, rect.bottomRight, rect.bottomRight.copy(y = rect.bottom - cornerLen), cornerStroke) - - drawRect( - color = Color.White.copy(alpha = 0.8f), - topLeft = rect.topLeft, - size = rect.size, - style = Stroke(width = 1.dp.toPx()) - ) - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/DrawControls.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/DrawControls.kt deleted file mode 100644 index e5477ad1..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/DrawControls.kt +++ /dev/null @@ -1,71 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.editor.photo.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Slider -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import org.monogram.presentation.R - -@Composable -fun DrawControls( - isEraser: Boolean, - color: Color, - size: Float, - onColorChange: (Color) -> Unit, - onSizeChange: (Float) -> Unit -) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp) - ) { - if (!isEraser) { - ColorSelector(selectedColor = color, onSelect = onColorChange) - Spacer(Modifier.height(12.dp)) - } - - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.fillMaxWidth() - ) { - Text( - text = stringResource(if (isEraser) R.string.photo_editor_tool_eraser else R.string.photo_editor_label_size), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.width(48.dp) - ) - Slider( - value = size, - onValueChange = onSizeChange, - valueRange = 5f..100f, - modifier = Modifier.weight(1f) - ) - Spacer(Modifier.width(12.dp)) - Box( - modifier = Modifier - .size(24.dp) - .clip(CircleShape) - .background(if (isEraser) Color.White else color) - .border(1.dp, MaterialTheme.colorScheme.outlineVariant, CircleShape), - contentAlignment = Alignment.Center - ) { - Box( - modifier = Modifier - .size((size / 100f * 20f).coerceAtLeast(2f).dp) - .clip(CircleShape) - .background(if (isEraser) Color.Black else Color.White) - ) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/EditorTopBar.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/EditorTopBar.kt deleted file mode 100644 index 8d02a6dc..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/EditorTopBar.kt +++ /dev/null @@ -1,76 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.editor.photo.components - -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.padding -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.Redo -import androidx.compose.material.icons.automirrored.filled.Undo -import androidx.compose.material.icons.filled.Close -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import org.monogram.presentation.R - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun EditorTopBar( - onClose: () -> Unit, - onSave: () -> Unit, - onUndo: () -> Unit, - onRedo: () -> Unit, - canUndo: Boolean, - canRedo: Boolean -) { - CenterAlignedTopAppBar( - title = { }, - navigationIcon = { - FilledIconButton( - onClick = onClose, - colors = IconButtonDefaults.filledIconButtonColors( - containerColor = Color.Black.copy(alpha = 0.3f), - contentColor = Color.White - ) - ) { - Icon(Icons.Default.Close, stringResource(R.string.photo_editor_action_close)) - } - }, - actions = { - if (canUndo || canRedo) { - IconButton(onClick = onUndo, enabled = canUndo) { - Icon( - Icons.AutoMirrored.Filled.Undo, - stringResource(R.string.photo_editor_action_undo), - tint = if (canUndo) Color.White else Color.White.copy(alpha = 0.3f) - ) - } - IconButton(onClick = onRedo, enabled = canRedo) { - Icon( - Icons.AutoMirrored.Filled.Redo, - stringResource(R.string.photo_editor_action_redo), - tint = if (canRedo) Color.White else Color.White.copy(alpha = 0.3f) - ) - } - } - Button( - onClick = onSave, - modifier = Modifier.padding(horizontal = 8.dp), - contentPadding = PaddingValues(horizontal = 20.dp), - colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.primary, - contentColor = MaterialTheme.colorScheme.onPrimary - ), - shape = MaterialTheme.shapes.medium - ) { - Text(stringResource(R.string.photo_editor_action_save)) - } - }, - colors = TopAppBarDefaults.centerAlignedTopAppBarColors( - containerColor = Color.Transparent, - actionIconContentColor = Color.White, - navigationIconContentColor = Color.White - ) - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/FilterControls.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/FilterControls.kt deleted file mode 100644 index 7aeee1e5..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/FilterControls.kt +++ /dev/null @@ -1,103 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.editor.photo.components - -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage -import org.monogram.presentation.R -import org.monogram.presentation.features.chats.currentChat.editor.photo.ImageFilter -import org.monogram.presentation.features.chats.currentChat.editor.photo.getPresetFilters -import java.io.File - -@Composable -fun FilterControls( - imagePath: String, - currentFilter: ImageFilter?, - onFilterSelect: (ImageFilter?) -> Unit -) { - val filters = remember { getPresetFilters() } - - LazyRow( - contentPadding = PaddingValues(horizontal = 16.dp, vertical = 12.dp), - horizontalArrangement = Arrangement.spacedBy(12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - item { - FilterPreviewItem( - imagePath = imagePath, - name = stringResource(R.string.photo_editor_filter_original), - filter = null, - isSelected = currentFilter == null, - onClick = { onFilterSelect(null) } - ) - } - items(filters) { filter -> - FilterPreviewItem( - imagePath = imagePath, - name = stringResource(filter.nameRes), - filter = filter, - isSelected = currentFilter?.nameRes == filter.nameRes, - onClick = { onFilterSelect(filter) } - ) - } - } -} - -@Composable -fun FilterPreviewItem( - imagePath: String, - name: String, - filter: ImageFilter?, - isSelected: Boolean, - onClick: () -> Unit -) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier.width(72.dp) - ) { - Box( - modifier = Modifier - .size(64.dp) - .clip(RoundedCornerShape(12.dp)) - .then( - if (isSelected) Modifier.border( - 2.dp, - MaterialTheme.colorScheme.primary, - RoundedCornerShape(12.dp) - ) else Modifier - ) - .clickable { onClick() } - ) { - AsyncImage( - model = File(imagePath), - contentDescription = null, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Crop, - colorFilter = filter?.let { ColorFilter.colorMatrix(it.colorMatrix) } - ) - } - Spacer(Modifier.height(6.dp)) - Text( - text = name, - style = MaterialTheme.typography.labelMedium, - fontWeight = if (isSelected) FontWeight.Bold else FontWeight.Normal, - color = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 1 - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/TextEntryDialog.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/TextEntryDialog.kt deleted file mode 100644 index 54cfe1f3..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/TextEntryDialog.kt +++ /dev/null @@ -1,116 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.editor.photo.components - -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Delete -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.window.Dialog -import androidx.compose.ui.window.DialogProperties -import org.monogram.presentation.R - -@Composable -fun TextEntryDialog( - initialText: String, - initialColor: Color, - onDismiss: () -> Unit, - onConfirm: (String, Color) -> Unit, - onDelete: () -> Unit -) { - var text by remember { mutableStateOf(initialText) } - var color by remember { mutableStateOf(initialColor) } - - Dialog( - onDismissRequest = onDismiss, - properties = DialogProperties(usePlatformDefaultWidth = false) - ) { - Surface( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp), - shape = RoundedCornerShape(28.dp), - color = MaterialTheme.colorScheme.surface, - tonalElevation = 6.dp - ) { - Column( - modifier = Modifier.padding(24.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Row( - Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = stringResource(if (initialText.isEmpty()) R.string.photo_editor_action_add_text else R.string.photo_editor_action_edit_text), - style = MaterialTheme.typography.headlineSmall - ) - if (initialText.isNotEmpty()) { - IconButton(onClick = onDelete) { - Icon( - Icons.Rounded.Delete, - contentDescription = stringResource(R.string.photo_editor_action_delete), - tint = MaterialTheme.colorScheme.error - ) - } - } - } - - Spacer(Modifier.height(20.dp)) - - TextField( - value = text, - onValueChange = { text = it }, - modifier = Modifier.fillMaxWidth(), - textStyle = TextStyle( - color = color, - fontSize = 24.sp, - fontWeight = FontWeight.Bold - ), - placeholder = { Text(stringResource(R.string.photo_editor_label_placeholder_text)) }, - colors = TextFieldDefaults.colors( - focusedContainerColor = Color.Transparent, - unfocusedContainerColor = Color.Transparent, - disabledContainerColor = Color.Transparent, - focusedIndicatorColor = color.copy(alpha = 0.5f), - unfocusedIndicatorColor = color.copy(alpha = 0.2f) - ) - ) - - Spacer(Modifier.height(24.dp)) - - ColorSelector(selectedColor = color, onSelect = { color = it }) - - Spacer(Modifier.height(32.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.End, - verticalAlignment = Alignment.CenterVertically - ) { - TextButton( - onClick = onDismiss, - modifier = Modifier.padding(end = 8.dp) - ) { - Text(stringResource(R.string.photo_editor_action_cancel)) - } - Button( - onClick = { if (text.isNotBlank()) onConfirm(text, color) }, - shape = RoundedCornerShape(12.dp) - ) { - Text(stringResource(R.string.photo_editor_action_apply)) - } - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/TransformControls.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/TransformControls.kt deleted file mode 100644 index 99f663fe..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/photo/components/TransformControls.kt +++ /dev/null @@ -1,79 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.editor.photo.components - -import androidx.compose.foundation.layout.* -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Refresh -import androidx.compose.material.icons.rounded.RotateLeft -import androidx.compose.material.icons.rounded.RotateRight -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import org.monogram.presentation.R - -@Composable -fun TransformControls( - rotation: Float, - scale: Float, - onRotationChange: (Float) -> Unit, - onScaleChange: (Float) -> Unit, - onReset: () -> Unit -) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 12.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceEvenly - ) { - FilledTonalIconButton(onClick = { onRotationChange(rotation - 90f) }) { - Icon( - Icons.Rounded.RotateLeft, - contentDescription = stringResource(R.string.photo_editor_action_rotate_left) - ) - } - - OutlinedButton( - onClick = onReset, - contentPadding = PaddingValues(horizontal = 16.dp) - ) { - Icon(Icons.Rounded.Refresh, contentDescription = null, modifier = Modifier.size(18.dp)) - Spacer(Modifier.width(8.dp)) - Text(stringResource(R.string.photo_editor_action_reset)) - } - - FilledTonalIconButton(onClick = { onRotationChange(rotation + 90f) }) { - Icon( - Icons.Rounded.RotateRight, - contentDescription = stringResource(R.string.photo_editor_action_rotate_right) - ) - } - } - - Spacer(modifier = Modifier.height(12.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically - ) { - Text( - stringResource(R.string.photo_editor_label_zoom), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.width(48.dp) - ) - Slider( - value = scale, - onValueChange = onScaleChange, - valueRange = 0.5f..3f, - modifier = Modifier.weight(1f) - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/VideoEditorScreen.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/VideoEditorScreen.kt deleted file mode 100644 index eb8fb1f7..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/VideoEditorScreen.kt +++ /dev/null @@ -1,524 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.editor.video - -import android.widget.Toast -import androidx.activity.compose.BackHandler -import androidx.annotation.OptIn -import androidx.annotation.StringRes -import androidx.compose.animation.AnimatedContent -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.gestures.detectTransformGestures -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Shadow -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.IntSize -import androidx.compose.ui.unit.dp -import androidx.compose.ui.viewinterop.AndroidView -import androidx.media3.common.* -import androidx.media3.common.util.UnstableApi -import androidx.media3.exoplayer.ExoPlayer -import androidx.media3.exoplayer.source.DefaultMediaSourceFactory -import androidx.media3.extractor.DefaultExtractorsFactory -import androidx.media3.extractor.mp4.Mp4Extractor -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import org.monogram.presentation.R -import org.monogram.presentation.core.util.getMimeType -import org.monogram.presentation.features.chats.currentChat.components.VideoGLTextureView -import org.monogram.presentation.features.chats.currentChat.editor.photo.components.EditorTopBar -import org.monogram.presentation.features.chats.currentChat.editor.photo.components.TextEntryDialog -import org.monogram.presentation.features.chats.currentChat.editor.video.components.VideoCompressionControls -import org.monogram.presentation.features.chats.currentChat.editor.video.components.VideoFilterControls -import org.monogram.presentation.features.chats.currentChat.editor.video.components.VideoTextControls -import org.monogram.presentation.features.chats.currentChat.editor.video.components.VideoTrimControls -import java.io.File -import java.io.FileNotFoundException - -enum class VideoEditorTool(@StringRes val labelRes: Int, val icon: ImageVector) { - NONE(R.string.video_tool_view, Icons.Rounded.Visibility), - TRIM(R.string.video_tool_trim, Icons.Rounded.ContentCut), - FILTER(R.string.video_tool_filters, Icons.Rounded.AutoAwesome), - TEXT(R.string.video_tool_text, Icons.Rounded.TextFields), - COMPRESS(R.string.video_tool_compress, Icons.Rounded.Compress) -} - -@OptIn(UnstableApi::class) -@Composable -fun VideoEditorScreen( - videoPath: String, - onClose: () -> Unit, - onSave: (String) -> Unit -) { - val context = LocalContext.current - val scope = rememberCoroutineScope() - val exoPlayer = remember { - if (!File(videoPath).exists()) { - Toast.makeText(context, context.getString(R.string.video_error_file_not_found), Toast.LENGTH_SHORT).show() - onClose() - } - - val extractorsFactory = DefaultExtractorsFactory() - .setConstantBitrateSeekingEnabled(true) - .setMp4ExtractorFlags(Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS) - - ExoPlayer.Builder(context) - .setMediaSourceFactory(DefaultMediaSourceFactory(context, extractorsFactory)) - .build().apply { - val mediaItem = MediaItem.Builder() - .setUri(videoPath) - .setMimeType(getMimeType(videoPath) ?: MimeTypes.VIDEO_MP4) - .build() - setMediaItem(mediaItem) - prepare() - repeatMode = Player.REPEAT_MODE_ONE - } - } - - var currentTool by remember { mutableStateOf(VideoEditorTool.NONE) } - var isPlaying by remember { mutableStateOf(false) } - var videoDuration by remember { mutableLongStateOf(0L) } - var currentPosition by remember { mutableLongStateOf(0L) } - - var trimRange by remember { mutableStateOf(VideoTrimRange()) } - var selectedFilter by remember { mutableStateOf(null) } - val textElements = remember { mutableStateListOf() } - var videoQuality by remember { mutableStateOf(VideoQuality.ORIGINAL) } - var isMuted by remember { mutableStateOf(false) } - - var showTextDialog by remember { mutableStateOf(false) } - var editingTextElement by remember { mutableStateOf(null) } - var canvasSize by remember { mutableStateOf(IntSize.Zero) } - var showDiscardDialog by remember { mutableStateOf(false) } - var isSaving by remember { mutableStateOf(false) } - - var glView by remember { mutableStateOf(null) } - - val hasChanges by remember { - derivedStateOf { - textElements.isNotEmpty() || - selectedFilter != null || - trimRange.startMs != 0L || - (videoDuration > 0 && trimRange.endMs != videoDuration) || - videoQuality != VideoQuality.ORIGINAL || - isMuted - } - } - - val handleBack = { - if (currentTool != VideoEditorTool.NONE) { - currentTool = VideoEditorTool.NONE - } else if (hasChanges) { - showDiscardDialog = true - } else { - onClose() - } - } - - DisposableEffect(Unit) { - val listener = object : Player.Listener { - override fun onPlaybackStateChanged(playbackState: Int) { - if (playbackState == Player.STATE_READY) { - videoDuration = exoPlayer.duration - if (trimRange.endMs == 0L) { - trimRange = trimRange.copy(endMs = videoDuration) - } - } - } - - override fun onIsPlayingChanged(playing: Boolean) { - isPlaying = playing - } - - override fun onVideoSizeChanged(videoSize: VideoSize) { - glView?.setVideoSize(videoSize.width, videoSize.height) - } - - override fun onPlayerError(error: PlaybackException) { - if (error.cause is FileNotFoundException) { - Toast.makeText(context, context.getString(R.string.video_error_file_missing), Toast.LENGTH_SHORT).show() - onClose() - } - } - } - exoPlayer.addListener(listener) - onDispose { - exoPlayer.removeListener(listener) - exoPlayer.release() - } - } - - LaunchedEffect(isMuted) { - exoPlayer.volume = if (isMuted) 0f else 1f - } - - LaunchedEffect(isPlaying) { - while (isPlaying) { - currentPosition = exoPlayer.currentPosition - if (currentPosition >= trimRange.endMs) { - exoPlayer.seekTo(trimRange.startMs) - } - delay(16) - } - } - - LaunchedEffect(selectedFilter) { - glView?.setFilter(selectedFilter?.colorMatrix?.values) - } - - BackHandler(onBack = handleBack) - - Scaffold( - containerColor = Color.Black, - topBar = { - EditorTopBar( - onClose = handleBack, - onSave = { - if (!isSaving) { - scope.launch { - isSaving = true - val newPath = processVideo( - context = context, - inputPath = videoPath, - trimRange = trimRange, - filter = selectedFilter, - textElements = textElements, - quality = videoQuality, - muteAudio = isMuted - ) - isSaving = false - onSave(newPath) - } - } - }, - onUndo = {}, - onRedo = {}, - canUndo = false, - canRedo = false - ) - }, - bottomBar = { - Surface( - color = MaterialTheme.colorScheme.surface.copy(alpha = 0.95f), - tonalElevation = 3.dp, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier.navigationBarsPadding() - ) { - AnimatedContent( - targetState = currentTool, - label = "VideoToolOptions", - modifier = Modifier.fillMaxWidth() - ) { tool -> - Box( - modifier = Modifier - .fillMaxWidth() - .heightIn(min = 100.dp), - contentAlignment = Alignment.Center - ) { - when (tool) { - VideoEditorTool.TRIM -> { - Column( - modifier = Modifier.padding(vertical = 8.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - VideoTrimControls( - duration = videoDuration, - trimRange = trimRange, - currentPosition = currentPosition, - onTrimChange = { - trimRange = it - exoPlayer.seekTo(it.startMs) - } - ) - TextButton(onClick = { currentTool = VideoEditorTool.NONE }) { - Text(stringResource(R.string.video_editor_apply)) - } - } - } - - VideoEditorTool.FILTER -> { - Column( - modifier = Modifier.padding(vertical = 8.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - VideoFilterControls( - selectedFilter = selectedFilter, - onFilterSelect = { selectedFilter = it } - ) - TextButton(onClick = { currentTool = VideoEditorTool.NONE }) { - Text(stringResource(R.string.video_editor_apply)) - } - } - } - - VideoEditorTool.TEXT -> { - Column( - modifier = Modifier.padding(vertical = 8.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - VideoTextControls(onAddText = { - editingTextElement = null - showTextDialog = true - }) - TextButton(onClick = { currentTool = VideoEditorTool.NONE }) { - Text(stringResource(R.string.video_editor_done)) - } - } - } - - VideoEditorTool.COMPRESS -> { - Column( - modifier = Modifier.padding(vertical = 8.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - VideoCompressionControls( - quality = videoQuality, - onQualityChange = { videoQuality = it } - ) - TextButton(onClick = { currentTool = VideoEditorTool.NONE }) { - Text(stringResource(R.string.video_editor_apply)) - } - } - } - - else -> { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Center, - modifier = Modifier - .fillMaxWidth() - .padding(16.dp) - ) { - FilledIconButton( - onClick = { - if (isPlaying) exoPlayer.pause() else exoPlayer.play() - }, - modifier = Modifier.size(56.dp), - colors = IconButtonDefaults.filledIconButtonColors( - containerColor = MaterialTheme.colorScheme.primaryContainer, - contentColor = MaterialTheme.colorScheme.onPrimaryContainer - ) - ) { - Icon( - if (isPlaying) Icons.Rounded.Pause else Icons.Rounded.PlayArrow, - contentDescription = null, - modifier = Modifier.size(32.dp) - ) - } - - Spacer(modifier = Modifier.width(24.dp)) - - FilledTonalIconButton( - onClick = { isMuted = !isMuted }, - modifier = Modifier.size(48.dp) - ) { - Icon( - if (isMuted) Icons.Rounded.VolumeOff else Icons.Rounded.VolumeUp, - contentDescription = if (isMuted) stringResource(R.string.video_action_unmute) else stringResource(R.string.video_action_mute), - tint = if (isMuted) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.onSurface - ) - } - } - } - } - } - } - - NavigationBar( - containerColor = Color.Transparent, - tonalElevation = 0.dp - ) { - VideoEditorTool.entries.forEach { tool -> - NavigationBarItem( - selected = currentTool == tool, - onClick = { currentTool = tool }, - icon = { Icon(tool.icon, contentDescription = stringResource(tool.labelRes)) }, - label = { Text(stringResource(tool.labelRes)) }, - colors = NavigationBarItemDefaults.colors( - indicatorColor = MaterialTheme.colorScheme.primaryContainer, - selectedIconColor = MaterialTheme.colorScheme.onPrimaryContainer, - unselectedIconColor = MaterialTheme.colorScheme.onSurfaceVariant, - unselectedTextColor = MaterialTheme.colorScheme.onSurfaceVariant - ) - ) - } - } - } - } - } - ) { paddingValues -> - Box( - modifier = Modifier - .fillMaxSize() - .padding(paddingValues) - .onGloballyPositioned { canvasSize = it.size }, - contentAlignment = Alignment.Center - ) { - AndroidView( - factory = { ctx -> - VideoGLTextureView(ctx).apply { - configure(useAlpha = false, removeBlackBg = false) - onSurfaceReady = { surface -> - exoPlayer.setVideoSurface(surface) - } - glView = this - } - }, - modifier = Modifier.fillMaxSize() - ) - - textElements.forEach { element -> - if (currentPosition >= element.startTimeMs && (element.endTimeMs == -1L || currentPosition <= element.endTimeMs)) { - val density = LocalDensity.current - var currentScale by remember(element.id) { mutableFloatStateOf(element.scale) } - var currentRotation by remember(element.id) { mutableFloatStateOf(element.rotation) } - var currentX by remember(element.id) { mutableFloatStateOf(element.positionX) } - var currentY by remember(element.id) { mutableFloatStateOf(element.positionY) } - - Box( - modifier = Modifier - .fillMaxSize() - .pointerInput(currentTool, element.id) { - if (currentTool == VideoEditorTool.TEXT || currentTool == VideoEditorTool.NONE) { - detectTransformGestures { _, pan, zoom, rotation -> - currentX += pan.x / canvasSize.width - currentY += pan.y / canvasSize.height - currentScale *= zoom - currentRotation += rotation - } - } - } - .pointerInput(currentTool, element.id) { - if (currentTool == VideoEditorTool.TEXT || currentTool == VideoEditorTool.NONE) { - detectTapGestures(onTap = { - if (currentTool == VideoEditorTool.TEXT) { - editingTextElement = element - showTextDialog = true - } - }) - } - } - ) { - LaunchedEffect(currentX, currentY, currentScale, currentRotation) { - val idx = textElements.indexOfFirst { it.id == element.id } - if (idx != -1) { - textElements[idx] = textElements[idx].copy( - positionX = currentX, - positionY = currentY, - scale = currentScale, - rotation = currentRotation - ) - } - } - - Text( - text = element.text, - color = element.color, - style = MaterialTheme.typography.headlineLarge.copy( - shadow = Shadow(Color.Black, blurRadius = 8f) - ), - modifier = Modifier - .align(Alignment.TopStart) - .offset( - x = with(density) { (currentX * canvasSize.width).toDp() }, - y = with(density) { (currentY * canvasSize.height).toDp() } - ) - .graphicsLayer( - scaleX = currentScale, - scaleY = currentScale, - rotationZ = currentRotation - ) - .then( - if (currentTool == VideoEditorTool.TEXT) { - Modifier - .border(1.dp, Color.White.copy(0.5f), RoundedCornerShape(4.dp)) - .padding(4.dp) - } else Modifier - ) - ) - } - } - } - - if (isSaving) { - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.Black.copy(0.6f)), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator() - } - } - } - } - - if (showDiscardDialog) { - AlertDialog( - onDismissRequest = { showDiscardDialog = false }, - title = { Text(stringResource(R.string.video_discard_title)) }, - text = { Text(stringResource(R.string.video_discard_text)) }, - confirmButton = { - TextButton(onClick = onClose) { - Text(stringResource(R.string.video_discard_confirm), color = MaterialTheme.colorScheme.error) - } - }, - dismissButton = { - TextButton(onClick = { showDiscardDialog = false }) { - Text(stringResource(R.string.video_editor_cancel)) - } - } - ) - } - - if (showTextDialog) { - TextEntryDialog( - initialText = editingTextElement?.text ?: "", - initialColor = editingTextElement?.color ?: Color.White, - onDismiss = { - showTextDialog = false - editingTextElement = null - }, - onConfirm = { text, color -> - if (editingTextElement != null) { - val index = textElements.indexOfFirst { it.id == editingTextElement!!.id } - if (index != -1) { - textElements[index] = textElements[index].copy(text = text, color = color) - } - } else { - textElements.add( - VideoTextElement( - text = text, - color = color, - positionX = 0.4f, - positionY = 0.4f - ) - ) - } - showTextDialog = false - editingTextElement = null - }, - onDelete = { - editingTextElement?.let { el -> textElements.removeIf { it.id == el.id } } - showTextDialog = false - editingTextElement = null - } - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/VideoEditorUtils.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/VideoEditorUtils.kt deleted file mode 100644 index 4e3630b8..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/VideoEditorUtils.kt +++ /dev/null @@ -1,597 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.editor.video - -import android.content.Context -import android.graphics.SurfaceTexture -import android.media.* -import android.net.Uri -import android.opengl.EGL14 -import android.opengl.EGLExt -import android.opengl.GLES20 -import android.util.Log -import android.view.Surface -import androidx.annotation.StringRes -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.ColorMatrix -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.monogram.presentation.R -import java.io.File -import java.nio.ByteBuffer -import java.nio.ByteOrder -import java.nio.FloatBuffer -import java.util.* -import kotlin.math.roundToInt - -data class VideoTrimRange( - val startMs: Long = 0L, - val endMs: Long = 0L -) - -data class VideoTextElement( - val id: String = UUID.randomUUID().toString(), - val text: String, - val color: Color, - val startTimeMs: Long = 0L, - val endTimeMs: Long = -1L, - val positionX: Float = 0.5f, - val positionY: Float = 0.5f, - val scale: Float = 1f, - val rotation: Float = 0f -) - -data class VideoFilter( - @StringRes val nameRes: Int, - val colorMatrix: ColorMatrix -) - -enum class VideoQuality(val label: String, val height: Int, val bitrate: Int) { - P144("144p", 144, 200_000), - P240("240p", 240, 400_000), - P360("360p", 360, 700_000), - P480("480p", 480, 1_200_000), - P720("720p", 720, 2_500_000), - P1080("1080p", 1080, 5_000_000), - ORIGINAL("Original", -1, -1); - - companion object { - fun fromSliderValue(value: Float): VideoQuality { - val index = (value * (entries.size - 1)).roundToInt().coerceIn(0, entries.size - 1) - return entries[index] - } - } - - fun toSliderValue(): Float { - return ordinal.toFloat() / (entries.size - 1) - } -} - -fun getPresetVideoFilters(): List { - return listOf( - VideoFilter(R.string.video_filter_original, ColorMatrix()), - VideoFilter(R.string.video_filter_bw, ColorMatrix().apply { setToSaturation(0f) }), - VideoFilter( - R.string.video_filter_sepia, ColorMatrix( - floatArrayOf( - 0.393f, 0.769f, 0.189f, 0f, 0f, - 0.349f, 0.686f, 0.168f, 0f, 0f, - 0.272f, 0.534f, 0.131f, 0f, 0f, - 0f, 0f, 0f, 1f, 0f - ) - ) - ), - VideoFilter( - R.string.video_filter_vintage, ColorMatrix( - floatArrayOf( - 0.9f, 0f, 0f, 0f, 0f, - 0f, 0.7f, 0f, 0f, 0f, - 0f, 0f, 0.5f, 0f, 0f, - 0f, 0f, 0f, 1f, 0f - ) - ) - ), - VideoFilter( - R.string.video_filter_cool, ColorMatrix( - floatArrayOf( - 1f, 0f, 0f, 0f, 0f, - 0f, 1f, 0.5f, 0f, 0f, - 0f, 0f, 1.5f, 0f, 0f, - 0f, 0f, 0f, 1f, 0f - ) - ) - ), - VideoFilter( - R.string.video_filter_warm, ColorMatrix( - floatArrayOf( - 1.2f, 0f, 0f, 0f, 0f, - 0f, 1f, 0f, 0f, 0f, - 0f, 0f, 0.8f, 0f, 0f, - 0f, 0f, 0f, 1f, 0f - ) - ) - ), - VideoFilter( - R.string.video_filter_polaroid, ColorMatrix( - floatArrayOf( - 1.438f, -0.062f, -0.062f, 0f, 0f, - -0.122f, 1.378f, -0.122f, 0f, 0f, - -0.016f, -0.016f, 1.483f, 0f, 0f, - 0f, 0f, 0f, 1f, 0f - ) - ) - ), - VideoFilter( - R.string.video_filter_invert, ColorMatrix( - floatArrayOf( - -1f, 0f, 0f, 0f, 255f, - 0f, -1f, 0f, 0f, 255f, - 0f, 0f, -1f, 0f, 255f, - 0f, 0f, 0f, 1f, 0f - ) - ) - ) - ) -} - -fun formatDuration(ms: Long): String { - val totalSeconds = ms / 1000 - val minutes = totalSeconds / 60 - val seconds = totalSeconds % 60 - return "%02d:%02d".format(minutes, seconds) -} - -object VideoEditorUtils { - init { - System.loadLibrary("native-lib") - } - - external fun processVideoNative( - inputPath: String, - outputPath: String, - startMs: Long, - endMs: Long, - targetHeight: Int, - bitrate: Int, - muteAudio: Boolean, - filterMatrix: FloatArray? - ): Boolean -} - -suspend fun processVideo( - context: Context, - inputPath: String, - trimRange: VideoTrimRange = VideoTrimRange(), - filter: VideoFilter? = null, - textElements: List = emptyList(), - quality: VideoQuality = VideoQuality.P720, - muteAudio: Boolean = false -): String = withContext(Dispatchers.IO) { - - val retriever = MediaMetadataRetriever() - var duration = 0L - var originalHeight = 0 - var originalWidth = 0 - var originalBitrate = 0 - var rotation = 0 - - try { - val uri = Uri.parse(inputPath) - if (uri.scheme == "content") { - retriever.setDataSource(context, uri) - } else { - retriever.setDataSource(inputPath) - } - duration = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLongOrNull() ?: 0L - originalHeight = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)?.toIntOrNull() ?: 0 - originalWidth = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)?.toIntOrNull() ?: 0 - originalBitrate = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE)?.toIntOrNull() ?: 0 - rotation = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION)?.toIntOrNull() ?: 0 - } catch (e: Exception) { - e.printStackTrace() - } finally { - try { - retriever.release() - } catch (e: Exception) { - } - } - - val effectiveEndMs = if (trimRange.endMs == 0L) duration else trimRange.endMs - val isTrimmed = trimRange.startMs > 0L || (duration > 0 && effectiveEndMs < duration - 100) - - if (!isTrimmed && - quality == VideoQuality.ORIGINAL && !muteAudio && - filter == null && textElements.isEmpty() - ) { - return@withContext inputPath - } - - if (!isTrimmed && quality == VideoQuality.P720 && !muteAudio && filter == null && textElements.isEmpty() && - inputPath.contains(context.cacheDir.absolutePath) && File(inputPath).name.startsWith("processed_video_") - ) { - return@withContext inputPath - } - - val outputFile = File(context.cacheDir, "processed_video_${System.currentTimeMillis()}.mp4") - - val naturalHeight = if (rotation == 90 || rotation == 270) originalWidth else originalHeight - - val targetHeight = if (quality == VideoQuality.ORIGINAL) -1 - else if (naturalHeight > 0 && quality.height > naturalHeight) naturalHeight - else quality.height - - val targetBitrate = if (quality == VideoQuality.ORIGINAL) -1 - else if (originalBitrate > 0 && quality.bitrate > originalBitrate) (originalBitrate * 0.9).toInt() - else quality.bitrate - - try { - val success = if (targetHeight > 0 || isTrimmed || muteAudio || filter != null) { - VideoTranscoder( - inputPath, - outputFile.absolutePath, - trimRange.startMs, - effectiveEndMs, - targetHeight, - targetBitrate, - muteAudio, - rotation, - filter?.colorMatrix?.values - ).start() - } else { - VideoEditorUtils.processVideoNative( - inputPath = inputPath, - outputPath = outputFile.absolutePath, - startMs = trimRange.startMs, - endMs = if (effectiveEndMs > 0) effectiveEndMs else -1L, - targetHeight = targetHeight, - bitrate = targetBitrate, - muteAudio = muteAudio, - filterMatrix = filter?.colorMatrix?.values - ) - } - - if (success) { - return@withContext outputFile.absolutePath - } else { - return@withContext inputPath - } - - } catch (e: Exception) { - Log.e("VideoEditorUtils", "Error processing video", e) - return@withContext inputPath - } -} - -private class VideoTranscoder( - private val inputPath: String, - private val outputPath: String, - private val startMs: Long, - private val endMs: Long, - private val targetHeight: Int, - private val targetBitrate: Int, - private val muteAudio: Boolean, - private val rotation: Int, - private val filterMatrix: FloatArray? -) { - private val timeoutUs = 10000L - private var muxerStarted = false - private var videoTrackIndex = -1 - private var audioTrackIndex = -1 - - fun start(): Boolean { - val extractor = MediaExtractor() - var muxer: MediaMuxer? = null - try { - extractor.setDataSource(inputPath) - - var videoInputTrack = -1 - var audioInputTrack = -1 - - for (i in 0 until extractor.trackCount) { - val format = extractor.getTrackFormat(i) - val mime = format.getString(MediaFormat.KEY_MIME) ?: "" - if (mime.startsWith("video/")) { - videoInputTrack = i - } else if (mime.startsWith("audio/") && !muteAudio) { - audioInputTrack = i - } - } - - if (videoInputTrack == -1) return false - - muxer = MediaMuxer(outputPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4) - - val videoFormat = extractor.getTrackFormat(videoInputTrack) - val rawWidth = videoFormat.getInteger(MediaFormat.KEY_WIDTH) - val rawHeight = videoFormat.getInteger(MediaFormat.KEY_HEIGHT) - - val (naturalWidth, naturalHeight) = if (rotation == 90 || rotation == 270) { - rawHeight to rawWidth - } else { - rawWidth to rawHeight - } - - val ratio = naturalWidth.toFloat() / naturalHeight.toFloat() - val newHeight = if (targetHeight > 0) targetHeight else naturalHeight - val newWidth = (newHeight * ratio).toInt() and 0xFFFFFFFE.toInt() - - muxer.setOrientationHint(0) - - val outputVideoFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, newWidth, newHeight) - outputVideoFormat.setInteger( - MediaFormat.KEY_COLOR_FORMAT, - MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface - ) - outputVideoFormat.setInteger(MediaFormat.KEY_BIT_RATE, if (targetBitrate > 0) targetBitrate else 2_000_000) - outputVideoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30) - outputVideoFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5) - - val encoder = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC) - encoder.configure(outputVideoFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE) - val inputSurface = InputSurface(encoder.createInputSurface()) - inputSurface.makeCurrent() - encoder.start() - - extractor.selectTrack(videoInputTrack) - val decoder = MediaCodec.createDecoderByType(videoFormat.getString(MediaFormat.KEY_MIME)!!) - - val renderer = TextureRenderer(filterMatrix) - val surfaceTexture = SurfaceTexture(renderer.getTextureId()) - val surface = Surface(surfaceTexture) - - decoder.configure(videoFormat, surface, null, 0) - decoder.start() - - if (startMs > 0) { - extractor.seekTo(startMs * 1000, MediaExtractor.SEEK_TO_PREVIOUS_SYNC) - } - - val bufferInfo = MediaCodec.BufferInfo() - var decoderDone = false - var encoderDone = false - var extractorDone = false - - while (!encoderDone) { - if (!extractorDone) { - val inputBufIndex = decoder.dequeueInputBuffer(timeoutUs) - if (inputBufIndex >= 0) { - val inputBuf = decoder.getInputBuffer(inputBufIndex)!! - val sampleSize = extractor.readSampleData(inputBuf, 0) - if (sampleSize < 0 || (endMs > 0 && extractor.sampleTime > endMs * 1000)) { - decoder.queueInputBuffer(inputBufIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM) - extractorDone = true - } else { - decoder.queueInputBuffer(inputBufIndex, 0, sampleSize, extractor.sampleTime, 0) - extractor.advance() - } - } - } - - if (!decoderDone) { - val outIndex = decoder.dequeueOutputBuffer(bufferInfo, timeoutUs) - if (outIndex >= 0) { - val render = bufferInfo.size > 0 && (bufferInfo.presentationTimeUs >= startMs * 1000) - decoder.releaseOutputBuffer(outIndex, render) - if (render) { - surfaceTexture.updateTexImage() - renderer.draw(newWidth, newHeight, surfaceTexture) - inputSurface.setPresentationTime(bufferInfo.presentationTimeUs * 1000) - inputSurface.swapBuffers() - } - if ((bufferInfo.flags and MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { - decoderDone = true - encoder.signalEndOfInputStream() - } - } - } - - val encIndex = encoder.dequeueOutputBuffer(bufferInfo, timeoutUs) - if (encIndex >= 0) { - val encodedData = encoder.getOutputBuffer(encIndex)!! - if ((bufferInfo.flags and MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) bufferInfo.size = 0 - if (bufferInfo.size != 0) { - if (!muxerStarted) { - videoTrackIndex = muxer.addTrack(encoder.outputFormat) - if (audioInputTrack != -1) { - audioTrackIndex = muxer.addTrack(extractor.getTrackFormat(audioInputTrack)) - } - muxer.start() - muxerStarted = true - } - encodedData.position(bufferInfo.offset) - encodedData.limit(bufferInfo.offset + bufferInfo.size) - muxer.writeSampleData(videoTrackIndex, encodedData, bufferInfo) - } - encoder.releaseOutputBuffer(encIndex, false) - if ((bufferInfo.flags and MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) encoderDone = true - } else if (encIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { - if (!muxerStarted) { - videoTrackIndex = muxer.addTrack(encoder.outputFormat) - if (audioInputTrack != -1) { - audioTrackIndex = muxer.addTrack(extractor.getTrackFormat(audioInputTrack)) - } - muxer.start() - muxerStarted = true - } - } - } - - decoder.stop(); decoder.release() - encoder.stop(); encoder.release() - surface.release(); surfaceTexture.release() - inputSurface.release() - - if (audioInputTrack != -1 && muxerStarted) { - extractor.unselectTrack(videoInputTrack) - extractor.selectTrack(audioInputTrack) - extractor.seekTo(startMs * 1000, MediaExtractor.SEEK_TO_PREVIOUS_SYNC) - val audioBuf = ByteBuffer.allocate(256 * 1024) - while (true) { - val sampleSize = extractor.readSampleData(audioBuf, 0) - if (sampleSize < 0 || (endMs > 0 && extractor.sampleTime > endMs * 1000)) break - if (extractor.sampleTime >= startMs * 1000) { - bufferInfo.offset = 0 - bufferInfo.size = sampleSize - bufferInfo.presentationTimeUs = extractor.sampleTime - bufferInfo.flags = extractor.sampleFlags - muxer.writeSampleData(audioTrackIndex, audioBuf, bufferInfo) - } - extractor.advance() - } - } - - return true - } catch (e: Exception) { - e.printStackTrace() - return false - } finally { - extractor.release() - try { - muxer?.stop() - } catch (e: Exception) { - } - muxer?.release() - } - } - - private class TextureRenderer(private val filterMatrix: FloatArray?) { - private var program = 0 - private var textureId = 0 - private var uSTMatrixHandle = 0 - private var uFilterMatrixHandle = 0 - private var uFilterOffsetHandle = 0 - private val stMatrix = FloatArray(16) - private val vertexData = floatArrayOf(-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f) - private val vertexBuffer: FloatBuffer = ByteBuffer.allocateDirect(vertexData.size * 4) - .order(ByteOrder.nativeOrder()).asFloatBuffer().put(vertexData).apply { position(0) } - - private val vertexShaderCode = """ - uniform mat4 uSTMatrix; - attribute vec4 aPosition; - varying vec2 vTextureCoord; - void main() { - gl_Position = aPosition; - vec2 texCoord = (aPosition.xy + 1.0) / 2.0; - vTextureCoord = (uSTMatrix * vec4(texCoord, 0.0, 1.0)).xy; - } - """ - private val fragmentShaderCode = """ - #extension GL_OES_EGL_image_external : require - precision mediump float; - varying vec2 vTextureCoord; - uniform samplerExternalOES sTexture; - uniform mat4 uFilterMatrix; - uniform vec4 uFilterOffset; - void main() { - vec4 color = texture2D(sTexture, vTextureCoord); - gl_FragColor = uFilterMatrix * color + uFilterOffset; - } - """ - - init { - val textures = IntArray(1) - GLES20.glGenTextures(1, textures, 0); textureId = textures[0] - GLES20.glBindTexture(0x8D65, textureId) - GLES20.glTexParameterf(0x8D65, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST.toFloat()) - GLES20.glTexParameterf(0x8D65, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR.toFloat()) - GLES20.glTexParameteri(0x8D65, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE) - GLES20.glTexParameteri(0x8D65, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE) - program = createProgram(vertexShaderCode, fragmentShaderCode) - uSTMatrixHandle = GLES20.glGetUniformLocation(program, "uSTMatrix") - uFilterMatrixHandle = GLES20.glGetUniformLocation(program, "uFilterMatrix") - uFilterOffsetHandle = GLES20.glGetUniformLocation(program, "uFilterOffset") - } - - fun getTextureId(): Int = textureId - fun draw(width: Int, height: Int, surfaceTexture: SurfaceTexture) { - GLES20.glViewport(0, 0, width, height) - GLES20.glUseProgram(program) - surfaceTexture.getTransformMatrix(stMatrix) - GLES20.glUniformMatrix4fv(uSTMatrixHandle, 1, false, stMatrix, 0) - - val fMatrix = FloatArray(16) - val fOffset = FloatArray(4) - if (filterMatrix != null) { - for (i in 0..3) { - for (j in 0..3) { - fMatrix[j * 4 + i] = filterMatrix[i * 5 + j] - } - fOffset[i] = filterMatrix[i * 5 + 4] / 255f - } - } else { - android.opengl.Matrix.setIdentityM(fMatrix, 0) - } - GLES20.glUniformMatrix4fv(uFilterMatrixHandle, 1, false, fMatrix, 0) - GLES20.glUniform4fv(uFilterOffsetHandle, 1, fOffset, 0) - - val positionHandle = GLES20.glGetAttribLocation(program, "aPosition") - GLES20.glEnableVertexAttribArray(positionHandle) - GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 8, vertexBuffer) - GLES20.glActiveTexture(GLES20.GL_TEXTURE0) - GLES20.glBindTexture(0x8D65, textureId) - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4) - } - - private fun createProgram(vertexSource: String, fragmentSource: String): Int { - val vs = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER) - .apply { GLES20.glShaderSource(this, vertexSource); GLES20.glCompileShader(this) } - val fs = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER) - .apply { GLES20.glShaderSource(this, fragmentSource); GLES20.glCompileShader(this) } - return GLES20.glCreateProgram() - .apply { GLES20.glAttachShader(this, vs); GLES20.glAttachShader(this, fs); GLES20.glLinkProgram(this) } - } - } - - private class InputSurface(surface: Surface) { - private var eglDisplay = EGL14.EGL_NO_DISPLAY - private var eglContext = EGL14.EGL_NO_CONTEXT - private var eglSurface = EGL14.EGL_NO_SURFACE - - init { - eglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY) - val version = IntArray(2); EGL14.eglInitialize(eglDisplay, version, 0, version, 1) - val attribList = intArrayOf( - EGL14.EGL_RED_SIZE, - 8, - EGL14.EGL_GREEN_SIZE, - 8, - EGL14.EGL_BLUE_SIZE, - 8, - EGL14.EGL_RENDERABLE_TYPE, - EGL14.EGL_OPENGL_ES2_BIT, - 0x3142, - 1, - EGL14.EGL_NONE - ) - val configs = arrayOfNulls(1) - val numConfigs = IntArray(1) - EGL14.eglChooseConfig(eglDisplay, attribList, 0, configs, 0, configs.size, numConfigs, 0) - eglContext = EGL14.eglCreateContext( - eglDisplay, - configs[0], - EGL14.EGL_NO_CONTEXT, - intArrayOf(EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE), - 0 - ) - eglSurface = EGL14.eglCreateWindowSurface(eglDisplay, configs[0], surface, intArrayOf(EGL14.EGL_NONE), 0) - } - - fun makeCurrent() { - EGL14.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) - } - - fun swapBuffers() { - EGL14.eglSwapBuffers(eglDisplay, eglSurface) - } - - fun setPresentationTime(nsecs: Long) { - EGLExt.eglPresentationTimeANDROID(eglDisplay, eglSurface, nsecs) - } - - fun release() { - if (eglDisplay !== EGL14.EGL_NO_DISPLAY) { - EGL14.eglMakeCurrent(eglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT) - EGL14.eglDestroySurface(eglDisplay, eglSurface); EGL14.eglDestroyContext(eglDisplay, eglContext) - EGL14.eglReleaseThread(); EGL14.eglTerminate(eglDisplay) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/components/VideoCompressionControls.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/components/VideoCompressionControls.kt deleted file mode 100644 index 7655832d..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/components/VideoCompressionControls.kt +++ /dev/null @@ -1,82 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.editor.video.components - -import androidx.compose.foundation.layout.* -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Slider -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import org.monogram.presentation.R -import org.monogram.presentation.features.chats.currentChat.editor.video.VideoQuality - -@Composable -fun VideoCompressionControls( - quality: VideoQuality, - onQualityChange: (VideoQuality) -> Unit -) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 12.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = stringResource(R.string.video_quality_label), - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Text( - text = quality.label, - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.primary - ) - } - - if (quality != VideoQuality.ORIGINAL) { - Text( - text = stringResource(R.string.video_estimated_bitrate, quality.bitrate / 1000), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.align(Alignment.Start) - ) - } - - Spacer(modifier = Modifier.height(8.dp)) - - Slider( - value = quality.toSliderValue(), - onValueChange = { - onQualityChange(VideoQuality.fromSliderValue(it)) - }, - valueRange = 0f..1f, - steps = VideoQuality.entries.size - 2, - modifier = Modifier.fillMaxWidth() - ) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween - ) { - Text( - stringResource(R.string.video_editor_low), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Text( - stringResource(R.string.video_filter_original), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/components/VideoFilterControls.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/components/VideoFilterControls.kt deleted file mode 100644 index f1ff9428..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/components/VideoFilterControls.kt +++ /dev/null @@ -1,79 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.editor.video.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import org.monogram.presentation.features.chats.currentChat.editor.video.VideoFilter -import org.monogram.presentation.features.chats.currentChat.editor.video.getPresetVideoFilters - - -@Composable -fun VideoFilterControls( - selectedFilter: VideoFilter?, - onFilterSelect: (VideoFilter) -> Unit -) { - val filters = getPresetVideoFilters() - - LazyRow( - modifier = Modifier.fillMaxWidth(), - contentPadding = PaddingValues(horizontal = 16.dp, vertical = 12.dp), - horizontalArrangement = Arrangement.spacedBy(12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - items(filters) { filter -> - val isSelected = (selectedFilter?.nameRes ?: filters.first().nameRes) == filter.nameRes - - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier.width(72.dp) - ) { - val filterName = stringResource(filter.nameRes) - Box( - modifier = Modifier - .size(64.dp) - .clip(RoundedCornerShape(12.dp)) - .background(MaterialTheme.colorScheme.surfaceVariant) - .then( - if (isSelected) Modifier.border( - 2.dp, - MaterialTheme.colorScheme.primary, - RoundedCornerShape(12.dp) - ) else Modifier - ) - .clickable { onFilterSelect(filter) }, - contentAlignment = Alignment.Center - ) { - Text( - text = filterName.take(1), - style = MaterialTheme.typography.titleLarge, - color = if (isSelected) MaterialTheme.colorScheme.primary - else MaterialTheme.colorScheme.onSurfaceVariant - ) - } - - Spacer(modifier = Modifier.height(6.dp)) - - Text( - text = filterName, - style = MaterialTheme.typography.labelMedium, - fontWeight = if (isSelected) FontWeight.Bold else FontWeight.Normal, - color = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 1 - ) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/components/VideoTextControls.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/components/VideoTextControls.kt deleted file mode 100644 index 26de03af..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/components/VideoTextControls.kt +++ /dev/null @@ -1,36 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.editor.video.components - -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Add -import androidx.compose.material3.Button -import androidx.compose.material3.Icon -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import org.monogram.presentation.R - -@Composable -fun VideoTextControls( - onAddText: () -> Unit -) { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp), - contentAlignment = Alignment.Center - ) { - Button( - onClick = onAddText, - shape = RoundedCornerShape(12.dp) - ) { - Icon(Icons.Rounded.Add, contentDescription = null) - Spacer(Modifier.width(8.dp)) - Text(stringResource(R.string.video_action_add_text)) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/components/VideoTrimControls.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/components/VideoTrimControls.kt deleted file mode 100644 index 474adae3..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/editor/video/components/VideoTrimControls.kt +++ /dev/null @@ -1,86 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.editor.video.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.unit.dp -import org.monogram.presentation.features.chats.currentChat.editor.video.VideoTrimRange -import org.monogram.presentation.features.chats.currentChat.editor.video.formatDuration - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun VideoTrimControls( - duration: Long, - trimRange: VideoTrimRange, - currentPosition: Long, - onTrimChange: (VideoTrimRange) -> Unit -) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = formatDuration(trimRange.startMs), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Surface( - color = MaterialTheme.colorScheme.primaryContainer, - shape = RoundedCornerShape(16.dp) - ) { - Text( - text = formatDuration(trimRange.endMs - trimRange.startMs), - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.onPrimaryContainer, - modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp) - ) - } - Text( - text = formatDuration(trimRange.endMs), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - - Spacer(modifier = Modifier.height(4.dp)) - - RangeSlider( - value = trimRange.startMs.toFloat()..trimRange.endMs.toFloat(), - onValueChange = { range -> - onTrimChange(VideoTrimRange(range.start.toLong(), range.endInclusive.toLong())) - }, - valueRange = 0f..(duration.coerceAtLeast(1L).toFloat()), - modifier = Modifier.fillMaxWidth() - ) - - Spacer(modifier = Modifier.height(4.dp)) - - Box( - modifier = Modifier - .fillMaxWidth() - .height(4.dp) - .clip(RoundedCornerShape(2.dp)) - .background(MaterialTheme.colorScheme.outlineVariant) - ) { - val progress = if (duration > 0) currentPosition.toFloat() / duration else 0f - Box( - modifier = Modifier - .fillMaxHeight() - .fillMaxWidth(progress) - .background(MaterialTheme.colorScheme.primary) - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/BotOperations.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/BotOperations.kt deleted file mode 100644 index bb7d880c..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/BotOperations.kt +++ /dev/null @@ -1,410 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.impl - -import android.util.Log -import kotlinx.coroutines.* -import kotlinx.coroutines.flow.update -import org.monogram.domain.models.* -import org.monogram.domain.repository.ChatMembersFilter -import org.monogram.presentation.features.chats.currentChat.DefaultChatComponent - -internal fun DefaultChatComponent.handleMentionQueryChange( - query: String?, - allMembers: List, - onMembersUpdated: (List) -> Unit -): Job? { - if (query == null) { - _state.update { it.copy(mentionSuggestions = emptyList()) } - return null - } - - return scope.launch { - delay(150) - val currentState = _state.value - val suggestions = if (query.isEmpty()) { - if (allMembers.isEmpty()) { - val canLoadMembers = !currentState.isChannel || currentState.isAdmin - if (canLoadMembers && (currentState.isGroup || currentState.isChannel)) { - try { - val members = userRepository.getChatMembers(chatId, 0, 200, ChatMembersFilter.Recent) - .map { it.user } - onMembersUpdated(members) - members - } catch (e: Exception) { - emptyList() - } - } else { - emptyList() - } - } else { - allMembers - } - } else { - val lowerQuery = query.lowercase() - val filtered = allMembers.filter { - it.firstName.lowercase().contains(lowerQuery) || - it.lastName?.lowercase()?.contains(lowerQuery) == true || - it.username?.lowercase()?.contains(lowerQuery) == true - } - if (filtered.isEmpty() && query.length > 2) { - try { - val searchResults = userRepository.searchContacts(query) - searchResults - } catch (e: Exception) { - emptyList() - } - } else { - filtered - } - } - _state.update { it.copy(mentionSuggestions = suggestions) } - } -} - -internal fun DefaultChatComponent.handleInlineQueryChange(botUsername: String, query: String) { - val normalizedUsername = botUsername.trim().removePrefix("@").lowercase() - if (normalizedUsername.isBlank()) { - clearInlineBotState() - return - } - - val normalizedQuery = query - if (normalizedQuery.isBlank()) { - clearInlineBotState() - return - } - - val state = _state.value - if ( - state.currentInlineBotUsername == normalizedUsername && - state.currentInlineQuery == normalizedQuery && - (state.inlineBotResults != null || state.isInlineBotLoading) - ) { - return - } - - inlineBotJob?.cancel() - inlineBotJob = scope.launch { - delay(300) - val currentState = _state.value - val cachedBotId = if (currentState.currentInlineBotUsername == normalizedUsername) { - currentState.currentInlineBotId - } else { - null - } - - _state.update { - it.copy( - inlineBotResults = if (it.currentInlineBotUsername == normalizedUsername) it.inlineBotResults else null, - currentInlineBotId = cachedBotId, - currentInlineBotUsername = normalizedUsername, - currentInlineQuery = normalizedQuery, - isInlineBotLoading = true - ) - } - - try { - val botId = cachedBotId ?: userRepository.searchPublicChat(normalizedUsername) - ?.id - - if (!isActive) return@launch - - if (botId == null) { - clearInlineBotState() - return@launch - } - - val results = repositoryMessage.getInlineBotResults(botId, chatId, normalizedQuery) - if (!isActive) return@launch - - _state.update { liveState -> - if (liveState.currentInlineBotUsername != normalizedUsername || liveState.currentInlineQuery != normalizedQuery) { - liveState - } else { - liveState.copy( - inlineBotResults = results, - currentInlineBotId = botId - ) - } - } - - refreshInlinePreviews( - botId = botId, - botUsername = normalizedUsername, - query = normalizedQuery - ) - } catch (e: CancellationException) { - throw e - } catch (e: Exception) { - Log.e("DefaultChatComponent", "Failed to fetch inline bot results", e) - clearInlineBotState() - } finally { - if (isActive) { - _state.update { liveState -> - if (liveState.currentInlineBotUsername == normalizedUsername && liveState.currentInlineQuery == normalizedQuery) { - liveState.copy(isInlineBotLoading = false) - } else { - liveState - } - } - } - } - } -} - -internal fun DefaultChatComponent.handleLoadMoreInlineResults(offset: String) { - if (offset.isBlank() || _state.value.isInlineBotLoading) return - - val botId = _state.value.currentInlineBotId ?: return - val query = _state.value.currentInlineQuery ?: return - - inlineBotJob?.cancel() - inlineBotJob = scope.launch { - _state.update { it.copy(isInlineBotLoading = true) } - try { - val results = repositoryMessage.getInlineBotResults(botId, chatId, query, offset) - if (!isActive) return@launch - - if (results != null) { - _state.update { currentState -> - val currentResults = currentState.inlineBotResults - if ( - currentResults != null && - currentState.currentInlineBotId == botId && - currentState.currentInlineQuery == query - ) { - val mergedResults = (currentResults.results + results.results) - .distinctBy { "${it.type}:${it.id}" } - - currentState.copy( - inlineBotResults = currentResults.copy( - nextOffset = results.nextOffset, - results = mergedResults, - switchPmText = results.switchPmText ?: currentResults.switchPmText, - switchPmParameter = results.switchPmParameter ?: currentResults.switchPmParameter - ) - ) - } else { - currentState.copy(inlineBotResults = results) - } - } - } - } catch (e: CancellationException) { - throw e - } catch (e: Exception) { - Log.e("DefaultChatComponent", "Failed to load more inline bot results", e) - } finally { - if (isActive) { - _state.update { it.copy(isInlineBotLoading = false) } - } - } - } -} - -internal fun DefaultChatComponent.handleSendInlineResult(resultId: String) { - val results = _state.value.inlineBotResults ?: return - scope.launch { - try { - repositoryMessage.sendInlineBotResult( - chatId = chatId, - queryId = results.queryId, - resultId = resultId, - replyToMsgId = _state.value.replyMessage?.id, - threadId = _state.value.currentTopicId - ) - } catch (e: Exception) { - Log.e("DefaultChatComponent", "Failed to send inline bot result", e) - return@launch - } - - _state.update { - it.copy( - inlineBotResults = null, - currentInlineBotId = null, - currentInlineBotUsername = null, - currentInlineQuery = null, - replyMessage = null - ) - } - } -} - -private fun DefaultChatComponent.clearInlineBotState() { - val currentState = _state.value - if ( - currentState.inlineBotResults == null && - currentState.currentInlineBotId == null && - currentState.currentInlineBotUsername == null && - currentState.currentInlineQuery == null && - !currentState.isInlineBotLoading - ) { - return - } - - _state.update { - it.copy( - inlineBotResults = null, - currentInlineBotId = null, - currentInlineBotUsername = null, - currentInlineQuery = null, - isInlineBotLoading = false - ) - } -} - -private suspend fun DefaultChatComponent.refreshInlinePreviews( - botId: Long, - botUsername: String, - query: String -) { - repeat(4) { attempt -> - val currentState = _state.value - val currentResults = currentState.inlineBotResults - if ( - currentResults == null || - currentState.currentInlineBotId != botId || - currentState.currentInlineBotUsername != botUsername || - currentState.currentInlineQuery != query - ) { - return - } - - val hasPendingVisualPreviews = currentResults.results.any { result -> - result.thumbFileId != 0 && result.thumbUrl.isNullOrBlank() && result.type.isVisualInlineType() - } - if (!hasPendingVisualPreviews) return - - delay(500L + attempt * 350L) - - val refreshed = try { - repositoryMessage.getInlineBotResults(botId, chatId, query) - } catch (e: Exception) { - Log.w("DefaultChatComponent", "Inline preview refresh failed", e) - null - } - if (refreshed == null) return@repeat - - _state.update { liveState -> - if ( - liveState.currentInlineBotId != botId || - liveState.currentInlineBotUsername != botUsername || - liveState.currentInlineQuery != query - ) { - liveState - } else { - val existing = liveState.inlineBotResults ?: return@update liveState - val refreshedByKey = refreshed.results.associateBy { "${it.type}:${it.id}" } - val merged = existing.results.map { old -> - val updated = refreshedByKey["${old.type}:${old.id}"] ?: return@map old - - val improvedThumb = updated.thumbUrl ?: old.thumbUrl - val improvedContent = if (!old.content.hasUsablePreviewPath() && updated.content.hasUsablePreviewPath()) { - updated.content - } else { - old.content ?: updated.content - } - - if ( - improvedThumb != old.thumbUrl || - improvedContent != old.content || - (old.width == 0 && updated.width > 0) || - (old.height == 0 && updated.height > 0) - ) { - old.copy( - thumbUrl = improvedThumb, - content = improvedContent, - width = if (old.width == 0) updated.width else old.width, - height = if (old.height == 0) updated.height else old.height - ) - } else { - old - } - } - - existing.copy(results = merged).let { refreshedResults -> - liveState.copy(inlineBotResults = refreshedResults) - } - } - } - } -} - -private fun String.isVisualInlineType(): Boolean { - val normalized = lowercase() - return normalized.contains("photo") || - normalized.contains("video") || - normalized.contains("gif") || - normalized.contains("animation") || - normalized.contains("sticker") -} - -private fun MessageContent?.hasUsablePreviewPath(): Boolean { - return when (this) { - is MessageContent.Photo -> !path.isNullOrBlank() - is MessageContent.Video -> !path.isNullOrBlank() - is MessageContent.Gif -> !path.isNullOrBlank() - is MessageContent.Sticker -> !path.isNullOrBlank() - is MessageContent.VideoNote -> !path.isNullOrBlank() - is MessageContent.Document -> !path.isNullOrBlank() - else -> false - } -} - -internal fun DefaultChatComponent.handleReplyMarkupButtonClick( - messageId: Long, - button: InlineKeyboardButtonModel, - botUserId: Long -) { - scope.launch { - when (val type = button.type) { - is InlineKeyboardButtonType.Callback -> { - repositoryMessage.onCallbackQuery(chatId, messageId, type.data) - } - - is InlineKeyboardButtonType.Url -> { - onLinkClick(type.url) - } - - is InlineKeyboardButtonType.WebApp -> { - onOpenMiniApp(type.url, button.text, botUserId) - } - - is InlineKeyboardButtonType.Buy -> { - repositoryMessage.onCallbackQueryBuy(chatId, messageId) - } - - is InlineKeyboardButtonType.User -> { - toProfile(type.userId) - } - - else -> { - Log.e("DefaultChatComponent", "Unknown inline keyboard button type: $type") - } - } - } -} - -internal fun DefaultChatComponent.handleKeyboardButtonClick( - messageId: Long, - button: KeyboardButtonModel, - botUserId: Long -) { - scope.launch { - when (val type = button.type) { - is KeyboardButtonType.Text -> { - onSendMessage(button.text) - } - - is KeyboardButtonType.WebApp -> { - onOpenMiniApp(type.url, button.text, botUserId) - } - - else -> { - Log.e("DefaultChatComponent", "Unknown keyboard button type: $type") - } - } - } -} - -internal fun DefaultChatComponent.handleBotCommandClick(command: String) { - onSendMessage(command) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/ChatInfo.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/ChatInfo.kt deleted file mode 100644 index 583e1c47..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/ChatInfo.kt +++ /dev/null @@ -1,205 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.impl - -import kotlinx.coroutines.flow.* -import kotlinx.coroutines.launch -import org.monogram.domain.models.ChatModel -import org.monogram.domain.models.ChatType -import org.monogram.domain.models.UserStatusType -import org.monogram.domain.models.UserTypeEnum -import org.monogram.domain.repository.ChatMemberStatus -import org.monogram.presentation.features.chats.currentChat.DefaultChatComponent - -internal fun DefaultChatComponent.loadChatInfo() { - scope.launch { - val chat = chatsListRepository.getChatById(chatId) - if (chat != null) { - updateChatState(chat) - if (chat.viewAsTopics && _state.value.topics.isEmpty()) { - loadTopics() - } - - val isBot = chat.type == ChatType.PRIVATE && chat.isBot - if (isBot) { - val botInfo = userRepository.getBotInfo(chatId) - if (botInfo != null) { - _state.update { - it.copy( - botCommands = botInfo.commands, - botMenuButton = botInfo.menuButton, - isBot = true - ) - } - } - } - } - } - - chatsListRepository.chatListFlow - .map { chats -> chats.find { it.id == chatId } } - .filterNotNull() - .distinctUntilChanged { old, new -> - old.viewAsTopics == new.viewAsTopics && - old.title == new.title && - old.avatarPath == new.avatarPath && - old.personalAvatarPath == new.personalAvatarPath && - old.isVerified == new.isVerified && - old.isSponsor == new.isSponsor && - old.emojiStatusPath == new.emojiStatusPath && - old.isMuted == new.isMuted && - old.permissions == new.permissions && - old.unreadCount == new.unreadCount && - old.unreadMentionCount == new.unreadMentionCount && - old.unreadReactionCount == new.unreadReactionCount && - old.isMember == new.isMember - } - .onEach { chat -> - val wasTopics = _state.value.viewAsTopics - updateChatState(chat) - if (chat.viewAsTopics) { - if (_state.value.topics.isEmpty()) { - loadTopics() - } - } else if (wasTopics) { - loadMessages() - } - } - .launchIn(scope) - - chatsListRepository.forumTopicsFlow - .filter { it.first == chatId } - .onEach { (_, topics) -> - _state.update { it.copy(topics = topics) } - } - .launchIn(scope) -} - -internal fun DefaultChatComponent.loadTopics() { - if (_state.value.isLoadingTopics) return - scope.launch { - _state.update { it.copy(isLoadingTopics = true) } - try { - val topics = chatsListRepository.getForumTopics(chatId) - _state.update { it.copy(topics = topics) } - } finally { - _state.update { it.copy(isLoadingTopics = false) } - } - } -} - -internal fun DefaultChatComponent.observeUserUpdates() { - if (_state.value.isGroup || _state.value.isChannel) return - scope.launch { - userRepository.getUserFlow(chatId).collectLatest { user -> - if (user != null) { - val isBot = user.type == UserTypeEnum.BOT - _state.update { - it.copy( - isOnline = !isBot && user.userStatus == UserStatusType.ONLINE, - isVerified = user.isVerified, - isSponsor = user.isSponsor, - userStatus = user.userStatus.toString(), - chatPersonalAvatar = user.personalAvatarPath, - otherUser = user - ) - } - } - } - } -} - -internal fun DefaultChatComponent.updateChatState(chat: ChatModel) { - _state.update { currentState -> - val isDetailedInfoMissing = (chat.isGroup || chat.isChannel) && chat.memberCount == 0 - val canWrite = if (chat.isAdmin) true else chat.permissions.canSendBasicMessages - - currentState.copy( - chatTitle = chat.title, - chatAvatar = chat.avatarPath, - chatPersonalAvatar = chat.personalAvatarPath, - chatEmojiStatus = chat.emojiStatusPath, - isGroup = chat.isGroup, - isChannel = chat.isChannel, - isVerified = if (chat.isGroup || chat.isChannel) chat.isVerified else (chat.isVerified || currentState.isVerified), - isSponsor = if (chat.isGroup || chat.isChannel) false else (chat.isSponsor || currentState.isSponsor), - canWrite = canWrite, - isAdmin = chat.isAdmin, - memberCount = if (!isDetailedInfoMissing) chat.memberCount else currentState.memberCount, - onlineCount = if (!isDetailedInfoMissing) chat.onlineCount else currentState.onlineCount, - unreadCount = chat.unreadCount, - unreadMentionCount = chat.unreadMentionCount, - unreadReactionCount = chat.unreadReactionCount, - userStatus = chat.userStatus, - typingAction = chat.typingAction, - viewAsTopics = chat.viewAsTopics, - isMuted = chat.isMuted, - permissions = chat.permissions, - isMember = chat.isMember - ) - } -} - -internal fun DefaultChatComponent.handleToggleMute() { - chatsListRepository.toggleMuteChats(setOf(chatId), !_state.value.isMuted) -} - -internal fun DefaultChatComponent.handleAddToAdBlockWhitelist() { - val current = appPreferences.adBlockWhitelistedChannels.value - if (chatId in current) return - - appPreferences.setAdBlockWhitelistedChannels(current + chatId) - loadMessages(force = true) -} - -internal fun DefaultChatComponent.handleRemoveFromAdBlockWhitelist() { - val current = appPreferences.adBlockWhitelistedChannels.value - if (chatId !in current) return - - appPreferences.setAdBlockWhitelistedChannels(current - chatId) - loadMessages(force = true) -} - -internal fun DefaultChatComponent.handleClearHistory() { - chatsListRepository.clearChatHistory(chatId, true) -} - -internal fun DefaultChatComponent.handleDeleteChat() { - chatsListRepository.deleteChats(setOf(chatId)) - onBackClicked() -} - -internal fun DefaultChatComponent.handleJoinChat() { - scope.launch { - userRepository.setChatMemberStatus(chatId, userRepository.getMe().id, ChatMemberStatus.Member) - } -} - -internal fun DefaultChatComponent.handleBlockUser(userId: Long) { - scope.launch { - if (_state.value.isGroup || _state.value.isChannel) { - userRepository.setChatMemberStatus(chatId, userId, ChatMemberStatus.Banned()) - } else { - privacyRepository.blockUser(userId) - } - } -} - -internal fun DefaultChatComponent.handleUnblockUser(userId: Long) { - scope.launch { - privacyRepository.unblockUser(userId) - } -} - -internal fun DefaultChatComponent.handleConfirmRestrict( - permissions: org.monogram.domain.models.ChatPermissionsModel, - untilDate: Int -) { - val userId = _state.value.restrictUserId ?: return - scope.launch { - userRepository.setChatMemberStatus( - chatId, - userId, - ChatMemberStatus.Restricted(isMember = true, restrictedUntilDate = untilDate, permissions = permissions) - ) - _state.update { it.copy(restrictUserId = null) } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/FileOperations.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/FileOperations.kt deleted file mode 100644 index 20a2a811..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/FileOperations.kt +++ /dev/null @@ -1,28 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.impl - -import android.util.Log -import kotlinx.coroutines.launch -import org.monogram.presentation.features.chats.currentChat.DefaultChatComponent - -internal fun DefaultChatComponent.handleDownloadFile(fileId: Int) { - repositoryMessage.downloadFile(fileId, priority = 32) -} - -internal fun DefaultChatComponent.handleCancelDownloadFile(fileId: Int) { - scope.launch { - try { - repositoryMessage.cancelDownloadFile(fileId) - } catch (e: Throwable) { - Log.e("DownloadDebug", "CancelDownloadFile failed: fileId=$fileId chatId=$chatId", e) - } - } -} - -internal fun DefaultChatComponent.handleDownloadHighRes(messageId: Long) { - scope.launch { - val fileId = repositoryMessage.getHighResFileId(chatId, messageId) - if (fileId != null) { - repositoryMessage.downloadFile(fileId, priority = 32) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/MessageActions.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/MessageActions.kt deleted file mode 100644 index 5e4e1106..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/MessageActions.kt +++ /dev/null @@ -1,339 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.impl - -import android.graphics.Bitmap -import android.graphics.BitmapFactory -import android.media.MediaMetadataRetriever -import androidx.compose.ui.platform.ClipboardManager -import androidx.compose.ui.text.AnnotatedString -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.monogram.domain.models.* -import org.monogram.presentation.features.chats.currentChat.DefaultChatComponent -import org.monogram.presentation.features.chats.currentChat.editor.video.VideoQuality -import org.monogram.presentation.features.chats.currentChat.editor.video.VideoTrimRange -import org.monogram.presentation.features.chats.currentChat.editor.video.processVideo -import java.io.File -import java.io.FileOutputStream - -internal fun DefaultChatComponent.handleSendMessage( - text: String, - entities: List, - sendOptions: MessageSendOptions = MessageSendOptions() -) { - scope.launch { - val currentState = _state.value - val replyId = currentState.replyMessage?.id - val threadId = currentState.currentTopicId - repositoryMessage.sendMessage(chatId, text, replyId, entities, threadId, sendOptions) - onCancelReply() - if (!currentState.isAtBottom) { - onScrollToBottom() - } - if (sendOptions.scheduleDate != null) { - loadScheduledMessages() - } - } -} - -internal fun DefaultChatComponent.handleSendSticker(stickerId: String) { - scope.launch { - val currentState = _state.value - val replyId = currentState.replyMessage?.id - val threadId = currentState.currentTopicId - repositoryMessage.sendSticker(chatId, stickerId, replyToMsgId = replyId, threadId = threadId) - onCancelReply() - if (!currentState.isAtBottom) { - onScrollToBottom() - } - } -} - -internal fun DefaultChatComponent.handleSendPhoto( - photoPath: String, - caption: String, - captionEntities: List = emptyList(), - sendOptions: MessageSendOptions = MessageSendOptions() -) { - scope.launch { - val shouldCompress = appPreferences.compressPhotos.value - - val finalPath = if (shouldCompress) { - withContext(Dispatchers.IO) { - try { - val bitmap = BitmapFactory.decodeFile(photoPath) - val compressedFile = File(cacheController.getCacheDir(), "compressed_photo_${System.currentTimeMillis()}.jpg") - FileOutputStream(compressedFile).use { out -> - bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out) - } - compressedFile.absolutePath - } catch (e: Exception) { - photoPath - } - } - } else { - photoPath - } - - val currentState = _state.value - val replyId = currentState.replyMessage?.id - val threadId = currentState.currentTopicId - repositoryMessage.sendPhoto( - chatId = chatId, - photoPath = finalPath, - caption = caption, - captionEntities = captionEntities, - replyToMsgId = replyId, - threadId = threadId, - sendOptions = sendOptions - ) - onCancelReply() - if (!currentState.isAtBottom) { - onScrollToBottom() - } - if (sendOptions.scheduleDate != null) { - loadScheduledMessages() - } - } -} - -internal fun DefaultChatComponent.handleSendVideo( - videoPath: String, - caption: String, - captionEntities: List = emptyList(), - sendOptions: MessageSendOptions = MessageSendOptions() -) { - scope.launch { - val shouldCompress = appPreferences.compressVideos.value - - val finalPath = if (shouldCompress) { - processVideo( - inputPath = videoPath, - trimRange = VideoTrimRange(), - filter = null, - textElements = emptyList(), - quality = VideoQuality.P720, - muteAudio = false, - context = this@handleSendVideo.cacheController.context - ) - } else { - videoPath - } - - val currentState = _state.value - val replyId = currentState.replyMessage?.id - val threadId = currentState.currentTopicId - repositoryMessage.sendVideo( - chatId = chatId, - videoPath = finalPath, - caption = caption, - captionEntities = captionEntities, - replyToMsgId = replyId, - threadId = threadId, - sendOptions = sendOptions - ) - onCancelReply() - if (!currentState.isAtBottom) { - onScrollToBottom() - } - if (sendOptions.scheduleDate != null) { - loadScheduledMessages() - } - } -} - -internal fun DefaultChatComponent.handleSendGif( - gif: GifModel, - sendOptions: MessageSendOptions = MessageSendOptions() -) { - scope.launch { - val currentState = _state.value - val replyId = currentState.replyMessage?.id - val threadId = currentState.currentTopicId - repositoryMessage.sendGif( - chatId, - gif.fileId.toString(), - replyToMsgId = replyId, - threadId = threadId, - sendOptions = sendOptions - ) - onCancelReply() - if (!currentState.isAtBottom) { - onScrollToBottom() - } - if (sendOptions.scheduleDate != null) { - loadScheduledMessages() - } - } -} - -internal fun DefaultChatComponent.handleSendGifFile( - path: String, - caption: String, - captionEntities: List = emptyList(), - sendOptions: MessageSendOptions = MessageSendOptions() -) { - scope.launch { - val currentState = _state.value - val replyId = currentState.replyMessage?.id - val threadId = currentState.currentTopicId - repositoryMessage.sendGifFile( - chatId = chatId, - gifPath = path, - caption = caption, - captionEntities = captionEntities, - replyToMsgId = replyId, - threadId = threadId, - sendOptions = sendOptions - ) - onCancelReply() - if (!currentState.isAtBottom) { - onScrollToBottom() - } - if (sendOptions.scheduleDate != null) { - loadScheduledMessages() - } - } -} - -internal fun DefaultChatComponent.handleSendAlbum( - paths: List, - caption: String, - captionEntities: List = emptyList(), - sendOptions: MessageSendOptions = MessageSendOptions() -) { - scope.launch { - val compressPhotos = appPreferences.compressPhotos.value - val compressVideos = appPreferences.compressVideos.value - - val processedPaths = paths.map { path -> - when { - path.endsWith(".mp4") -> { - if (compressVideos) { - processVideo( - inputPath = path, - trimRange = VideoTrimRange(), - filter = null, - textElements = emptyList(), - quality = VideoQuality.P720, - muteAudio = false, - context = this@handleSendAlbum.cacheController.context - ) - } else path - } - - path.endsWith(".jpg") || path.endsWith(".jpeg") || path.endsWith(".png") -> { - if (compressPhotos) { - withContext(Dispatchers.IO) { - try { - val bitmap = BitmapFactory.decodeFile(path) - val compressedFile = - File(cacheController.getCacheDir(), "compressed_photo_${System.currentTimeMillis()}.jpg") - FileOutputStream(compressedFile).use { out -> - bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out) - } - compressedFile.absolutePath - } catch (e: Exception) { - path - } - } - } else path - } - - else -> path - } - } - - val currentState = _state.value - val replyId = currentState.replyMessage?.id - val threadId = currentState.currentTopicId - repositoryMessage.sendAlbum( - chatId, - processedPaths, - caption = caption, - captionEntities = captionEntities, - replyToMsgId = replyId, - threadId = threadId, - sendOptions = sendOptions - ) - onCancelReply() - if (!currentState.isAtBottom) { - onScrollToBottom() - } - if (sendOptions.scheduleDate != null) { - loadScheduledMessages() - } - } -} - -internal fun DefaultChatComponent.handleVideoRecorded(file: File) { - scope.launch(Dispatchers.IO) { - try { - val retriever = MediaMetadataRetriever() - retriever.setDataSource(file.absolutePath) - val timeString = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION) - val durationMs = timeString?.toLongOrNull() ?: 0L - val durationSec = (durationMs / 1000).toInt() - retriever.release() - repositoryMessage.sendVideoNote(chatId, file.absolutePath, durationSec, 384) - withContext(Dispatchers.Main) { - if (!_state.value.isAtBottom) { - onScrollToBottom() - } - } - } catch (e: Exception) { - e.printStackTrace() - } - } -} - -internal fun DefaultChatComponent.handleSendVoice(path: String, duration: Int, waveform: ByteArray) { - scope.launch { - repositoryMessage.sendVoiceNote(chatId, path, duration, waveform) - if (!_state.value.isAtBottom) { - onScrollToBottom() - } - } -} - -internal fun DefaultChatComponent.handleCopySelectedMessages(clipboardManager: ClipboardManager) { - val currentState = _state.value - val selectedIds = currentState.selectedMessageIds - val selectedMessages = currentState.messages - .filter { selectedIds.contains(it.id) } - .sortedBy { it.id } - - val text = selectedMessages.joinToString("\n\n") { msg -> - when (val content = msg.content) { - is MessageContent.Text -> content.text - is MessageContent.Photo -> content.caption - is MessageContent.Video -> content.caption - is MessageContent.Document -> content.caption - is MessageContent.Gif -> content.caption - else -> "" - } - } - - if (text.isNotEmpty()) { - clipboardManager.setText(AnnotatedString(text)) - } - onClearSelection() -} - -internal fun DefaultChatComponent.handleReportMessage(message: MessageModel) { - _state.update { it.copy(showReportDialog = true) } -} - -internal fun DefaultChatComponent.handleReportReasonSelected(reason: String) { - chatsListRepository.reportChat(chatId, reason) -} - -internal fun DefaultChatComponent.handleCopyLink(clipboardManager: ClipboardManager) { - scope.launch { - val link = chatsListRepository.getChatLink(chatId) - if (link != null) { - clipboardManager.setText(AnnotatedString(link)) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/MessageLoading.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/MessageLoading.kt deleted file mode 100644 index 01961d8f..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/MessageLoading.kt +++ /dev/null @@ -1,1134 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.impl - -import android.util.Log -import kotlinx.coroutines.* -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.sync.withLock -import org.monogram.domain.models.* -import org.monogram.domain.repository.ReadUpdate -import org.monogram.presentation.features.chats.currentChat.AutoDownloadSuppression -import org.monogram.presentation.features.chats.currentChat.DefaultChatComponent -import java.io.File - - -private const val PAGE_SIZE = 50 -private const val MAX_DOWNLOAD_RETRIES = 3 - -private fun isUsableAvatarPath(path: String?): Boolean { - if (path.isNullOrBlank()) return false - return when { - path.startsWith("http", ignoreCase = true) -> true - path.startsWith("content:", ignoreCase = true) -> true - path.startsWith("file:", ignoreCase = true) -> true - else -> File(path).exists() - } -} - -private fun firstUsableAvatarPath(vararg candidates: String?): String? { - return candidates.firstOrNull { isUsableAvatarPath(it) } - ?: candidates.firstOrNull { !it.isNullOrBlank() } -} - -private fun mergeSenderVisuals(previous: MessageModel, incoming: MessageModel): MessageModel { - if (previous.senderId != incoming.senderId) return incoming - - val mergedAvatar = firstUsableAvatarPath( - incoming.senderAvatar, - incoming.senderPersonalAvatar, - previous.senderAvatar, - previous.senderPersonalAvatar - ) - val mergedPersonalAvatar = firstUsableAvatarPath( - incoming.senderPersonalAvatar, - incoming.senderAvatar, - previous.senderPersonalAvatar, - previous.senderAvatar - ) - - return incoming.copy( - senderName = incoming.senderName.ifBlank { previous.senderName }, - senderAvatar = mergedAvatar, - senderPersonalAvatar = mergedPersonalAvatar, - senderCustomTitle = incoming.senderCustomTitle ?: previous.senderCustomTitle, - senderStatusEmojiPath = incoming.senderStatusEmojiPath ?: previous.senderStatusEmojiPath - ) -} - -private fun reactionsSemanticEqual( - current: List, - incoming: List -): Boolean { - if (current.size != incoming.size) return false - - val currentByReaction = current.associateBy { it.emoji to it.customEmojiId } - if (currentByReaction.size != current.size) return false - - return incoming.all { reaction -> - val previous = currentByReaction[reaction.emoji to reaction.customEmojiId] ?: return@all false - previous.count == reaction.count && - previous.isChosen == reaction.isChosen && - previous.customEmojiPath == reaction.customEmojiPath - } -} - -private fun DefaultChatComponent.resolveRemappedMessageId(messageId: Long): Long { - var current = messageId - repeat(4) { - val mapped = remappedMessageIds[current] ?: return current - if (mapped == current) return current - current = mapped - } - return current -} - -private suspend fun DefaultChatComponent.updateMessagesUnsafe( - newMessages: List, - replace: Boolean = false -) { - val currentState = _state.value - val adBlockEnabled = appPreferences.isAdBlockEnabled.value - val keywords = appPreferences.adBlockKeywords.value - val whitelistedChannels = appPreferences.adBlockWhitelistedChannels.value - val isChannel = currentState.isChannel - val isWhitelisted = whitelistedChannels.contains(chatId) - - val filteredNewMessages = if (adBlockEnabled && isChannel && !isWhitelisted) { - withContext(Dispatchers.Default) { - newMessages.filterNot { message -> - val text = when (val content = message.content) { - is MessageContent.Text -> content.text - is MessageContent.Photo -> content.caption - is MessageContent.Video -> content.caption - is MessageContent.Document -> content.caption - is MessageContent.Gif -> content.caption - else -> "" - } - keywords.any { text.contains(it, ignoreCase = true) } - } - } - } else { - newMessages - } - - _state.update { state -> - if (filteredNewMessages.isEmpty()) { - return@update if (replace && state.messages.any { it.sendingState is MessageSendingState.Pending }) { - state.copy(messages = state.messages.filter { it.sendingState is MessageSendingState.Pending }) - } else { - state - } - } - - val currentList = if (replace) { - state.messages.filter { it.sendingState is MessageSendingState.Pending } - } else { - state.messages - } - - val isComments = state.rootMessage != null - - val messageMap = LinkedHashMap(currentList.size + filteredNewMessages.size) - currentList.forEach { messageMap[it.id] = it } - - var hasChanges = replace - filteredNewMessages.forEach { msg -> - val previous = messageMap[msg.id] - val mergedMessage = if (previous != null) mergeSenderVisuals(previous, msg) else msg - val old = messageMap.put(msg.id, mergedMessage) - if (old != mergedMessage) { - hasChanges = true - } - } - - if (!hasChanges) { - return@update state - } - - val mergedMessages = messageMap.values.let { - if (isComments) { - it.sortedWith(compareBy { it.date }.thenBy { it.id }) - } else { - it.sortedWith(compareByDescending { it.date }.thenByDescending { it.id }) - } - } - - if (mergedMessages == state.messages) state else state.copy(messages = mergedMessages) - } -} - -internal suspend fun DefaultChatComponent.updateMessages(newMessages: List, replace: Boolean = false) { - messageMutex.withLock { - updateMessagesUnsafe(newMessages, replace) - } -} - -internal fun DefaultChatComponent.loadMessages(force: Boolean = false) { - val state = _state.value - if (state.isLoading) return - if (!force && state.messages.size >= PAGE_SIZE && state.currentTopicId == null) return - - cancelAllLoadingJobs() - messageLoadingJob = scope.launch { - _state.update { - it.copy( - isLoading = true, - isOldestLoaded = false, - isLatestLoaded = false - ) - } - - try { - val currentState = _state.value - val threadId = currentState.currentTopicId - val isComments = currentState.rootMessage != null - val savedScrollPosition = if (threadId == null) cacheProvider.getChatScrollPosition(chatId) else 0L - - if (isComments && threadId != null) { - loadComments(threadId) - } else if (savedScrollPosition != 0L) { - loadAroundMessage(savedScrollPosition, threadId, shouldHighlight = false) - } else { - val chat = chatsListRepository.getChatById(chatId) - val firstUnreadId = chat?.lastReadInboxMessageId?.let { lastRead -> - if (chat.unreadCount > 0) { - repositoryMessage.getMessagesNewer(chatId, lastRead, 1, threadId).firstOrNull()?.id - ?: lastRead.takeIf { it > 0L } - } else null - } - - if (firstUnreadId != null) { - loadAroundMessage(firstUnreadId, threadId, shouldHighlight = false) - } else { - loadBottomMessages(threadId) - } - } - } catch (e: CancellationException) { - throw e - } catch (e: Exception) { - Log.e("DefaultChatComponent", "Failed to load messages", e) - } finally { - _state.update { it.copy(isLoading = false) } - } - } -} - -internal suspend fun DefaultChatComponent.loadComments(threadId: Long) { - lastLoadedOlderId = 0L - lastLoadedNewerId = 0L - val messages = repositoryMessage.getMessagesNewer(chatId, threadId, PAGE_SIZE, threadId) - val reachedEnd = messages.size < PAGE_SIZE - - _state.update { - it.copy( - isAtBottom = false, - isLatestLoaded = reachedEnd, - isOldestLoaded = true, - scrollToMessageId = messages.firstOrNull()?.id - ) - } - updateMessages(messages, replace = true) -} - -private suspend fun DefaultChatComponent.loadBottomMessages(threadId: Long?) { - lastLoadedOlderId = 0L - lastLoadedNewerId = 0L - - var hasCachedPreview = false - val cachedMessages = repositoryMessage.getCachedMessages(chatId, PAGE_SIZE) - if (cachedMessages.isNotEmpty()) { - hasCachedPreview = true - _state.update { - it.copy( - isAtBottom = true, - isLatestLoaded = false, - isOldestLoaded = false, - scrollToMessageId = null - ) - } - updateMessages(cachedMessages, replace = true) - refreshCachedSenderProfiles(cachedMessages) - } - - val olderPage = repositoryMessage.getMessagesOlder(chatId, 0, PAGE_SIZE, threadId) - val messages = olderPage.messages - val isRemoteSameAsCachedPreview = hasCachedPreview && cachedMessages.isNotEmpty() && - messages.size == cachedMessages.size && - messages.zip(cachedMessages).all { (remote, cached) -> remote.id == cached.id } - - val isOldestLoaded = if (isRemoteSameAsCachedPreview) { - false - } else { - olderPage.reachedOldest - } - - _state.update { - it.copy( - isAtBottom = true, - isLatestLoaded = !isRemoteSameAsCachedPreview, - isOldestLoaded = isOldestLoaded, - scrollToMessageId = null - ) - } - val shouldReplaceCachedPreview = !hasCachedPreview || messages.isNotEmpty() - updateMessages(messages, replace = shouldReplaceCachedPreview) - if (!isOldestLoaded) { - delay(100) - loadMoreMessages() - } -} - -private suspend fun DefaultChatComponent.loadAroundMessage( - messageId: Long, - threadId: Long?, - shouldHighlight: Boolean = true -) { - lastLoadedOlderId = 0L - lastLoadedNewerId = 0L - val messages = repositoryMessage.getMessagesAround(chatId, messageId, PAGE_SIZE, threadId) - if (messages.isNotEmpty()) { - _state.update { - it.copy( - isAtBottom = false, - isLatestLoaded = false, - isOldestLoaded = false, - scrollToMessageId = messageId, - highlightedMessageId = if (shouldHighlight) messageId else null - ) - } - updateMessages(messages, replace = true) - delay(100) - loadMoreMessages() - loadNewerMessages() - } else { - loadBottomMessages(threadId) - } -} - -internal fun DefaultChatComponent.loadMoreMessages() { - val state = _state.value - val forceLoad = state.isOldestLoaded && state.messages.size < 10 - val isComments = state.rootMessage != null - val visibleAnchorId = if (isComments) { - state.messages.firstOrNull { it.id > 0 }?.id ?: 0L - } else { - state.messages.lastOrNull { it.id > 0 }?.id ?: 0L - } - val requestedAnchorId = listOf(visibleAnchorId, lastLoadedOlderId) - .filter { it > 0L } - .minOrNull() ?: 0L - - if (requestedAnchorId != 0L && requestedAnchorId == inFlightOlderAnchorId) return - if (loadMoreJob?.isActive == true || state.isLoadingOlder || (state.isOldestLoaded && !forceLoad)) return - - if (requestedAnchorId != 0L) { - inFlightOlderAnchorId = requestedAnchorId - } - - loadMoreJob = scope.launch { - _state.update { it.copy(isLoadingOlder = true) } - try { - val currentState = _state.value - val isComments = currentState.rootMessage != null - val threadId = currentState.currentTopicId - - val visibleAnchorId = if (isComments) { - currentState.messages.firstOrNull { it.id > 0 }?.id ?: 0L - } else { - currentState.messages.lastOrNull { it.id > 0 }?.id ?: 0L - } - - val anchorId = listOf(visibleAnchorId, lastLoadedOlderId) - .filter { it > 0L } - .minOrNull() ?: 0L - - inFlightOlderAnchorId = anchorId - - if (anchorId == 0L) { - _state.update { it.copy(isOldestLoaded = true) } - return@launch - } - - var currentAnchorId = anchorId - var isOldestLoaded = false - var attempts = 0 - - while (!isOldestLoaded && attempts < 5) { - attempts++ - - val beforeSize = _state.value.messages.size - val olderPage = repositoryMessage.getMessagesOlder(chatId, currentAnchorId, PAGE_SIZE, threadId) - val olderMessages = olderPage.messages - - val nextOlderAnchorId = olderMessages - .asSequence() - .map { it.id } - .filter { it in 1 until currentAnchorId } - .minOrNull() ?: currentAnchorId - - val hasOlderProgress = nextOlderAnchorId < currentAnchorId - - if (olderMessages.isNotEmpty()) { - updateMessages(olderMessages) - } - - val afterSize = _state.value.messages.size - val listGrew = afterSize > beforeSize - - isOldestLoaded = olderPage.reachedOldest || (olderPage.isRemote && !hasOlderProgress) - - if (hasOlderProgress) { - lastLoadedOlderId = nextOlderAnchorId - currentAnchorId = nextOlderAnchorId - } - - if (!olderPage.isRemote && olderMessages.isEmpty()) { - break - } - - if (isOldestLoaded || listGrew) break - } - - _state.update { it.copy(isOldestLoaded = isOldestLoaded) } - } catch (e: Exception) { - Log.e("DefaultChatComponent", "Failed to load more messages", e) - lastLoadedOlderId = 0L - } finally { - inFlightOlderAnchorId = 0L - _state.update { it.copy(isLoadingOlder = false) } - } - } -} - -internal fun DefaultChatComponent.loadNewerMessages() { - val state = _state.value - val requestedAnchorId = if (state.rootMessage != null) { - state.messages.lastOrNull { it.id > 0 }?.id ?: 0L - } else { - state.messages.firstOrNull { it.id > 0 }?.id ?: 0L - } - - if (requestedAnchorId != 0L && requestedAnchorId == inFlightNewerAnchorId) return - if (loadNewerJob?.isActive == true || state.isLoadingNewer || state.isLatestLoaded) return - - if (requestedAnchorId != 0L) { - inFlightNewerAnchorId = requestedAnchorId - } - - loadNewerJob = scope.launch { - _state.update { it.copy(isLoadingNewer = true) } - try { - val currentState = _state.value - val currentMessages = currentState.messages - val isComments = currentState.rootMessage != null - val threadId = currentState.currentTopicId - - val anchorId = if (isComments) { - currentMessages.lastOrNull { it.id > 0 }?.id ?: return@launch - } else { - currentMessages.firstOrNull { it.id > 0 }?.id ?: return@launch - } - - inFlightNewerAnchorId = anchorId - - if (anchorId != 0L && anchorId == lastLoadedNewerId) { - _state.update { it.copy(isLatestLoaded = true) } - return@launch - } - - val newerMessages = repositoryMessage.getMessagesNewer(chatId, anchorId, PAGE_SIZE, threadId) - val isLatestLoaded = - newerMessages.size < PAGE_SIZE || (newerMessages.isNotEmpty() && newerMessages.all { msg -> currentMessages.any { it.id == msg.id } }) - - if (newerMessages.isNotEmpty()) { - updateMessages(newerMessages) - lastLoadedNewerId = anchorId - } - - _state.update { it.copy(isLatestLoaded = isLatestLoaded) } - } catch (e: Exception) { - Log.e("DefaultChatComponent", "Failed to load newer messages", e) - lastLoadedNewerId = 0L - } finally { - inFlightNewerAnchorId = 0L - _state.update { it.copy(isLoadingNewer = false) } - } - } -} - -internal fun DefaultChatComponent.scrollToMessageInternal(messageId: Long) { - cancelAllLoadingJobs() - messageLoadingJob = scope.launch { - _state.update { - it.copy( - isLoading = true, - isOldestLoaded = false, - isLatestLoaded = false - ) - } - try { - loadAroundMessage(messageId, _state.value.currentTopicId, shouldHighlight = true) - } catch (e: Exception) { - Log.e("DefaultChatComponent", "Failed to scroll to message", e) - } finally { - _state.update { it.copy(isLoading = false) } - } - } -} - -internal fun DefaultChatComponent.scrollToBottomInternal() { - if (_state.value.isLoading) return - cancelAllLoadingJobs() - messageLoadingJob = scope.launch { - _state.update { - it.copy( - isLoading = true, - isOldestLoaded = false, - isLatestLoaded = false - ) - } - try { - loadBottomMessages(_state.value.currentTopicId) - } catch (e: Exception) { - Log.e("DefaultChatComponent", "Failed to scroll to bottom", e) - } finally { - _state.update { it.copy(isLoading = false) } - } - } -} - -internal fun DefaultChatComponent.cancelAllLoadingJobs() { - messageLoadingJob?.cancel() - loadMoreJob?.cancel() - loadNewerJob?.cancel() - inFlightOlderAnchorId = 0L - inFlightNewerAnchorId = 0L -} - -internal fun DefaultChatComponent.setupMessageCollectors() { - repositoryMessage.newMessageFlow - .onEach { message -> - if (message.chatId == chatId) { - if (resolveRemappedMessageId(message.id) != message.id) { - return@onEach - } - val isCorrectThread = - _state.value.currentTopicId == null || message.threadId?.toLong() == _state.value.currentTopicId - if (isCorrectThread) { - updateMessages(listOf(message)) - _state.update { state -> - state.copy( - isLatestLoaded = if (message.isOutgoing || state.isAtBottom) true else state.isLatestLoaded - ) - } - } - } - } - .launchIn(scope) - - repositoryMessage.messageIdUpdateFlow - .onEach { (cId, oldId, newMessage) -> - if (cId == chatId) { - if (oldId != newMessage.id) { - remappedMessageIds[oldId] = newMessage.id - } else { - remappedMessageIds.remove(oldId) - } - messageMutex.withLock { - _state.update { state -> - val isCorrectThread = - state.currentTopicId == null || newMessage.threadId?.toLong() == state.currentTopicId - if (!isCorrectThread) { - return@update state - } - - val withoutOldId = state.messages.filterNot { it.id == oldId } - val canInsert = state.isAtBottom || state.isLatestLoaded || newMessage.isOutgoing - - val updatedMessages = when { - withoutOldId.any { it.id == newMessage.id } -> { - withoutOldId.map { existing -> - if (existing.id == newMessage.id) { - mergeSenderVisuals(existing, newMessage) - } else { - existing - } - } - } - - canInsert -> withoutOldId + newMessage - else -> withoutOldId - } - - val isComments = state.rootMessage != null - val distinctMessages = updatedMessages.distinctBy { it.id } - val sortedMessages = if (isComments) { - distinctMessages.sortedWith(compareBy { it.date }.thenBy { it.id }) - } else { - distinctMessages.sortedWith(compareByDescending { it.date }.thenByDescending { it.id }) - } - state.copy( - messages = sortedMessages, - isLatestLoaded = if (newMessage.isOutgoing || state.isAtBottom) true else state.isLatestLoaded - ) - } - } - } - } - .launchIn(scope) - - repositoryMessage.messageUploadProgressFlow - .onEach { (messageId, progress) -> - updateMessageContent(messageId) { message -> - val isUploading = progress < 1f && message.sendingState is MessageSendingState.Pending - val newSendingState = if (progress >= 1f) null else message.sendingState - - val newContent = when (val content = message.content) { - is MessageContent.Photo -> content.copy(isUploading = isUploading, uploadProgress = progress) - is MessageContent.Video -> content.copy(isUploading = isUploading, uploadProgress = progress) - is MessageContent.VideoNote -> content.copy(isUploading = isUploading, uploadProgress = progress) - is MessageContent.Document -> content.copy(isUploading = isUploading, uploadProgress = progress) - is MessageContent.Gif -> content.copy(isUploading = isUploading, uploadProgress = progress) - is MessageContent.Voice -> content.copy(isUploading = isUploading, uploadProgress = progress) - else -> content - } - message.copy(content = newContent, sendingState = newSendingState) - } - } - .launchIn(scope) - - repositoryMessage.messageDownloadProgressFlow - .onEach { (messageId, progress) -> - updateMessageContent(messageId) { message -> - val isDownloading = progress < 1f - val newContent = when (val content = message.content) { - is MessageContent.Photo -> content.copy( - isDownloading = isDownloading, - downloadProgress = progress, - downloadError = false - ) - - is MessageContent.Video -> content.copy( - isDownloading = isDownloading, - downloadProgress = progress, - downloadError = false - ) - - is MessageContent.VideoNote -> content.copy( - isDownloading = isDownloading, - downloadProgress = progress, - downloadError = false - ) - - is MessageContent.Document -> content.copy( - isDownloading = isDownloading, - downloadProgress = progress, - downloadError = false - ) - - is MessageContent.Gif -> content.copy( - isDownloading = isDownloading, - downloadProgress = progress, - downloadError = false - ) - - is MessageContent.Voice -> content.copy( - isDownloading = isDownloading, - downloadProgress = progress, - downloadError = false - ) - - is MessageContent.Sticker -> content.copy( - isDownloading = isDownloading, - downloadProgress = progress, - downloadError = false - ) - - else -> content - } - message.copy(content = newContent) - } - } - .launchIn(scope) - - repositoryMessage.messageDownloadCancelledFlow - .onEach { messageId -> - var cancelledFileId = 0 - updateMessageContent(messageId) { message -> - val newContent = when (val content = message.content) { - is MessageContent.Photo -> { - cancelledFileId = content.fileId - content.copy( - isDownloading = false, - downloadProgress = 0f, - downloadError = false - ) - } - - is MessageContent.Video -> { - cancelledFileId = content.fileId - content.copy( - isDownloading = false, - downloadProgress = 0f, - downloadError = false - ) - } - - is MessageContent.VideoNote -> { - cancelledFileId = content.fileId - content.copy( - isDownloading = false, - downloadProgress = 0f, - downloadError = false - ) - } - - is MessageContent.Document -> { - cancelledFileId = content.fileId - content.copy( - isDownloading = false, - downloadProgress = 0f, - downloadError = false - ) - } - - is MessageContent.Gif -> { - cancelledFileId = content.fileId - content.copy( - isDownloading = false, - downloadProgress = 0f, - downloadError = false - ) - } - - is MessageContent.Voice -> { - cancelledFileId = content.fileId - content.copy( - isDownloading = false, - downloadProgress = 0f, - downloadError = false - ) - } - - is MessageContent.Sticker -> { - cancelledFileId = content.fileId - content.copy( - isDownloading = false, - downloadProgress = 0f, - downloadError = false - ) - } - - else -> content - } - message.copy(content = newContent) - } - AutoDownloadSuppression.suppress(cancelledFileId) - if (cancelledFileId != 0) { - mediaDownloadRetryCount.remove(cancelledFileId) - } - } - .launchIn(scope) - - repositoryMessage.messageDownloadCompletedFlow - .onEach { (messageId, downloadedFileId, path) -> - var fileIdToRetry: Int? = null - var mainFileId = 0 - var mainPathUpdated = false - - updateMessageContent(messageId) { message -> - val isError = path.isEmpty() - val finalPath = path.ifEmpty { null } - - val newContent = when (val content = message.content) { - is MessageContent.Photo -> { - if (downloadedFileId == content.fileId) { - mainFileId = content.fileId - mainPathUpdated = true - if (isError) fileIdToRetry = content.fileId - content.copy(path = finalPath, isDownloading = false, downloadError = isError) - } else { - if (finalPath != null) content.copy(thumbnailPath = finalPath) else content - } - } - - is MessageContent.Video -> { - if (downloadedFileId == content.fileId) { - mainFileId = content.fileId - mainPathUpdated = true - if (isError) fileIdToRetry = content.fileId - content.copy(path = finalPath, isDownloading = false, downloadError = isError) - } else { - if (finalPath != null) content.copy(thumbnailPath = finalPath) else content - } - } - - is MessageContent.VideoNote -> { - if (downloadedFileId == content.fileId) { - mainFileId = content.fileId - mainPathUpdated = true - if (isError) fileIdToRetry = content.fileId - content.copy(path = finalPath, isDownloading = false, downloadError = isError) - } else { - content - } - } - - is MessageContent.Document -> { - if (downloadedFileId == content.fileId) { - mainFileId = content.fileId - mainPathUpdated = true - if (isError) fileIdToRetry = content.fileId - content.copy(path = finalPath, isDownloading = false, downloadError = isError) - } else { - content - } - } - - is MessageContent.Gif -> { - if (downloadedFileId == content.fileId) { - mainFileId = content.fileId - mainPathUpdated = true - if (isError) fileIdToRetry = content.fileId - content.copy(path = finalPath, isDownloading = false, downloadError = isError) - } else { - content - } - } - - is MessageContent.Voice -> { - if (downloadedFileId == content.fileId) { - mainFileId = content.fileId - mainPathUpdated = true - if (isError) fileIdToRetry = content.fileId - content.copy(path = finalPath, isDownloading = false, downloadError = isError) - } else { - content - } - } - - is MessageContent.Sticker -> { - if (downloadedFileId == content.fileId) { - mainFileId = content.fileId - mainPathUpdated = true - if (isError) fileIdToRetry = content.fileId - content.copy(path = finalPath, isDownloading = false, downloadError = isError) - } else { - content - } - } - - else -> content - } - message.copy(content = newContent) - } - - if (path.isNotEmpty() && mainFileId != 0) { - AutoDownloadSuppression.clear(mainFileId) - mediaDownloadRetryCount.remove(mainFileId) - } - - if (mainPathUpdated && path.isNotEmpty()) { - updateFullScreenImagePath(messageId, path) - } - - if (path.isNotEmpty() && messageId in Int.MIN_VALUE.toLong()..Int.MAX_VALUE.toLong()) { - updateInlineResultsWithFile(messageId.toInt(), path) - } - - fileIdToRetry?.let { - if (it != 0) { - val suppressed = AutoDownloadSuppression.isSuppressed(it) - if (!suppressed) { - val attempts = (mediaDownloadRetryCount[it] ?: 0) + 1 - mediaDownloadRetryCount[it] = attempts - if (attempts <= MAX_DOWNLOAD_RETRIES) { - onDownloadFile(it) - } else { - AutoDownloadSuppression.suppress(it) - Log.w( - "DownloadDebug", - "retryLimitReached: fileId=$it attempts=$attempts chatId=$chatId" - ) - } - } else { - Log.d("DownloadDebug", "retrySkippedBySuppression: fileId=$it chatId=$chatId") - } - } - } - } - .launchIn(scope) - - repositoryMessage.messageDeletedFlow - .onEach { (cId, messageIds) -> - if (cId == chatId) { - messageIds.forEach(reactionUpdateSuppressedUntil::remove) - messageIds.forEach(remappedMessageIds::remove) - remappedMessageIds.entries.removeIf { (_, mappedId) -> mappedId in messageIds } - _state.update { currentState -> - val currentMessages = currentState.messages.toMutableList() - val removed = currentMessages.removeAll { messageIds.contains(it.id) } - if (removed) { - currentState.copy(messages = currentMessages) - } else { - currentState - } - } - } - } - .launchIn(scope) - - repositoryMessage.messageEditedFlow - .onEach { message -> - if (message.chatId == chatId) { - val now = System.currentTimeMillis() - val suppressUntil = reactionUpdateSuppressedUntil[message.id] - val suppressReactionUpdate = suppressUntil != null && now < suppressUntil - - if (!suppressReactionUpdate && suppressUntil != null) { - reactionUpdateSuppressedUntil.remove(message.id, suppressUntil) - } - - updateMessageContent(message.id) { current -> - val mediaSafeMessage = when { - current.content is MessageContent.Photo && message.content is MessageContent.Photo -> { - val currentPhoto = current.content as MessageContent.Photo - val incomingPhoto = message.content as MessageContent.Photo - if (currentPhoto.fileId == incomingPhoto.fileId) { - val resolvedPath = incomingPhoto.path ?: currentPhoto.path - message.copy( - content = incomingPhoto.copy( - path = resolvedPath, - thumbnailPath = incomingPhoto.thumbnailPath ?: currentPhoto.thumbnailPath - ) - ) - } else { - message - } - } - - current.content is MessageContent.Video && message.content is MessageContent.Video -> { - val currentVideo = current.content as MessageContent.Video - val incomingVideo = message.content as MessageContent.Video - if (currentVideo.fileId == incomingVideo.fileId) { - val resolvedPath = incomingVideo.path ?: currentVideo.path - message.copy( - content = incomingVideo.copy( - path = resolvedPath, - thumbnailPath = incomingVideo.thumbnailPath ?: currentVideo.thumbnailPath - ) - ) - } else { - message - } - } - - else -> message - } - - when { - suppressReactionUpdate -> mediaSafeMessage.copy(reactions = current.reactions) - reactionsSemanticEqual( - current.reactions, - mediaSafeMessage.reactions - ) -> mediaSafeMessage.copy(reactions = current.reactions) - - else -> mediaSafeMessage - } - } - } - } - .launchIn(scope) - - repositoryMessage.mediaUpdateFlow - .onEach { - loadChatInfo() - } - .launchIn(scope) - - repositoryMessage.messageReadFlow - .onEach { readUpdate -> - if (readUpdate.chatId == chatId) { - _state.update { currentState -> - val currentMessages = currentState.messages - var hasChanges = false - val updatedMessages = currentMessages.map { message -> - if (readUpdate is ReadUpdate.Outbox && message.isOutgoing && !message.isRead && message.id <= readUpdate.messageId) { - hasChanges = true - message.copy(isRead = true) - } else { - message - } - } - if (hasChanges) { - currentState.copy(messages = updatedMessages) - } else { - currentState - } - } - } - } - .launchIn(scope) - - observeSenderUpdates() -} - -private fun DefaultChatComponent.observeSenderUpdates() { - repositoryMessage.senderUpdateFlow - .onEach { senderId -> - if (senderId <= 0L) return@onEach - val hasAffectedMessages = _state.value.messages.any { it.senderId == senderId } - if (!hasAffectedMessages) return@onEach - - repositoryMessage.invalidateSenderCache(senderId) - val user = userRepository.getUser(senderId) ?: return@onEach - refreshMessagesForSender(senderId, user) - } - .launchIn(scope) -} - -private suspend fun DefaultChatComponent.refreshCachedSenderProfiles(messages: List) { - val senderIds = messages.asSequence() - .map { it.senderId } - .filter { it > 0L } - .distinct() - .toList() - - senderIds.forEach { senderId -> - repositoryMessage.invalidateSenderCache(senderId) - val user = userRepository.getUser(senderId) ?: return@forEach - refreshMessagesForSender(senderId, user) - } -} - -private fun DefaultChatComponent.refreshMessagesForSender(senderId: Long, user: UserModel) { - val fullName = listOfNotNull( - user.firstName.takeIf { it.isNotBlank() }, - user.lastName?.takeIf { it.isNotBlank() } - ).joinToString(" ").ifBlank { "User" } - - _state.update { currentState -> - val updatedMessages = currentState.messages.map { message -> - if (message.senderId == senderId) { - val resolvedAvatar = firstUsableAvatarPath( - user.avatarPath, - user.personalAvatarPath, - message.senderAvatar, - message.senderPersonalAvatar - ) - val resolvedPersonalAvatar = firstUsableAvatarPath( - user.personalAvatarPath, - user.avatarPath, - message.senderPersonalAvatar, - message.senderAvatar - ) - - message.copy( - senderName = fullName, - senderAvatar = resolvedAvatar, - senderPersonalAvatar = resolvedPersonalAvatar, - isSenderVerified = user.isVerified, - isSenderPremium = user.isPremium, - senderStatusEmojiId = user.statusEmojiId, - senderStatusEmojiPath = user.statusEmojiPath ?: message.senderStatusEmojiPath - ) - } else { - message - } - } - currentState.copy(messages = updatedMessages) - } -} - -private fun DefaultChatComponent.updateInlineResultsWithFile(fileId: Int, newPath: String) { - _state.update { currentState -> - val currentResults = currentState.inlineBotResults ?: return@update currentState - val updatedResults = currentResults.results.map { result -> - if (result.thumbFileId == fileId) result.copy(thumbUrl = newPath) else result - } - currentState.copy(inlineBotResults = currentResults.copy(results = updatedResults)) - } -} - -private fun DefaultChatComponent.updateFullScreenImagePath(messageId: Long, newPath: String) { - _state.update { currentState -> - val currentImages = currentState.fullScreenImages ?: return@update currentState - val index = currentState.fullScreenImageMessageIds.indexOf(messageId) - if (index !in currentImages.indices) { - return@update currentState - } - - val updated = currentImages.toMutableList().apply { this[index] = newPath } - currentState.copy(fullScreenImages = updated) - } -} - -private inline fun DefaultChatComponent.updateMessageContent( - messageId: Long, - crossinline transform: (MessageModel) -> MessageModel -) { - scope.launch { - messageMutex.withLock { - val targetMessageId = resolveRemappedMessageId(messageId) - _state.update { currentState -> - val currentMessages = currentState.messages.toMutableList() - val index = currentMessages.indexOfFirst { it.id == targetMessageId } - if (index != -1) { - val currentMessage = currentMessages[index] - val updatedMessage = transform(currentMessage) - if (updatedMessage != currentMessage) { - currentMessages[index] = updatedMessage - currentState.copy(messages = currentMessages) - } else { - currentState - } - } else { - currentState - } - } - } - } -} - -internal fun DefaultChatComponent.loadDraft() { - scope.launch { - val threadId = _state.value.currentTopicId - val draft = repositoryMessage.getChatDraft(chatId, threadId) - if (!draft.isNullOrEmpty()) { - _state.update { it.copy(draftText = draft) } - } - } -} - -internal fun DefaultChatComponent.handleTopicClick(topicId: Int) { - val id = if (topicId == 0) null else topicId.toLong() - _state.update { - it.copy( - currentTopicId = id, - messages = emptyList(), - isOldestLoaded = false, - isLatestLoaded = false, - rootMessage = null, - isAtBottom = id == null - ) - } - loadMessages(force = true) -} - -internal fun DefaultChatComponent.handleCommentsClick(messageId: Long) { - scope.launch { - val message = _state.value.messages.find { it.id == messageId } - _state.update { - it.copy( - currentTopicId = messageId, - rootMessage = message, - messages = emptyList(), - isOldestLoaded = false, - isLatestLoaded = false, - isAtBottom = false - ) - } - loadComments(messageId) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/MessageOperations.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/MessageOperations.kt deleted file mode 100644 index d21ac483..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/MessageOperations.kt +++ /dev/null @@ -1,140 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.impl - -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch -import org.monogram.domain.models.MessageEntity -import org.monogram.domain.models.MessageModel -import org.monogram.domain.models.MessageReactionModel -import org.monogram.presentation.features.chats.currentChat.DefaultChatComponent - -private const val REACTION_UPDATE_SUPPRESSION_MS = 1500L - - -internal fun DefaultChatComponent.handleMessageVisible(messageId: Long) { - scope.launch { - repositoryMessage.markAsRead(chatId, messageId) - if (_state.value.unreadCount > 0) { - repositoryMessage.markAllMentionsAsRead(chatId) - repositoryMessage.markAllReactionsAsRead(chatId) - } - } -} - -internal fun DefaultChatComponent.handleDeleteMessage(message: MessageModel, revoke: Boolean = false) { - scope.launch { - repositoryMessage.deleteMessage(chatId, listOf(message.id), revoke) - } -} - -internal fun DefaultChatComponent.handleSaveEditedMessage(text: String, entities: List) { - val editingMsg = _state.value.editingMessage ?: return - scope.launch { - repositoryMessage.editMessage(chatId, editingMsg.id, text, entities) - onCancelEdit() - } -} - -internal fun DefaultChatComponent.handleDraftChange(text: String) { - _state.update { it.copy(draftText = text) } - draftSaveJob?.cancel() - draftSaveJob = scope.launch { - delay(200) - val currentState = _state.value - val threadId = currentState.currentTopicId - repositoryMessage.saveChatDraft(chatId, text, currentState.replyMessage?.id, threadId) - } -} - -internal fun DefaultChatComponent.handleSendReaction(messageId: Long, reaction: String) { - val suppressUntil = System.currentTimeMillis() + REACTION_UPDATE_SUPPRESSION_MS - reactionUpdateSuppressedUntil[messageId] = suppressUntil - scope.launch { - delay(REACTION_UPDATE_SUPPRESSION_MS) - reactionUpdateSuppressedUntil.remove(messageId, suppressUntil) - } - - _state.update { currentState -> - val currentMessages = currentState.messages.toMutableList() - val index = currentMessages.indexOfFirst { it.id == messageId } - if (index == -1) return@update currentState - - val message = currentMessages[index] - val isCustom = reaction.all { it.isDigit() } - val emoji = if (isCustom) null else reaction - val customEmojiId = if (isCustom) reaction.toLongOrNull() else null - - val existingReaction = message.reactions.find { - (it.emoji != null && it.emoji == emoji) || (it.customEmojiId != null && it.customEmojiId == customEmojiId) - } - - val isChosen = existingReaction?.isChosen ?: false - - val newReactions = message.reactions.toMutableList() - if (isChosen) { - val reactionToUpdate = existingReaction!! - if (reactionToUpdate.count > 1) { - val reactionIndex = newReactions.indexOf(reactionToUpdate) - if (reactionIndex != -1) { - newReactions[reactionIndex] = reactionToUpdate.copy( - count = reactionToUpdate.count - 1, - isChosen = false - ) - } - } else { - newReactions.remove(reactionToUpdate) - } - scope.launch { - repositoryMessage.removeMessageReaction(chatId, messageId, reaction) - } - } else { - if (existingReaction != null) { - val reactionIndex = newReactions.indexOf(existingReaction) - if (reactionIndex != -1) { - newReactions[reactionIndex] = existingReaction.copy( - count = existingReaction.count + 1, - isChosen = true - ) - } - } else { - newReactions.add( - MessageReactionModel( - emoji = emoji, - customEmojiId = customEmojiId, - count = 1, - isChosen = true - ) - ) - } - scope.launch { - repositoryMessage.addMessageReaction(chatId, messageId, reaction) - } - } - - currentMessages[index] = message.copy(reactions = newReactions) - currentState.copy(messages = currentMessages) - } -} - -internal fun DefaultChatComponent.handlePinMessage(message: MessageModel) { - scope.launch { - repositoryMessage.pinMessage(chatId, message.id) - } -} - -internal fun DefaultChatComponent.handleUnpinMessage(message: MessageModel) { - scope.launch { - repositoryMessage.unpinMessage(chatId, message.id) - } -} - -internal fun DefaultChatComponent.handleClearMessages() { - chatsListRepository.clearChatHistory(chatId, false) -} - -internal fun DefaultChatComponent.handleSendScheduledNow(message: MessageModel) { - scope.launch { - repositoryMessage.sendScheduledNow(chatId, message.id) - loadScheduledMessages() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/MessageSelection.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/MessageSelection.kt deleted file mode 100644 index b659ea78..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/MessageSelection.kt +++ /dev/null @@ -1,35 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.impl - -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch -import org.monogram.presentation.features.chats.currentChat.DefaultChatComponent - - -internal fun DefaultChatComponent.handleToggleMessageSelection(messageId: Long) { - _state.update { currentState -> - val current = currentState.selectedMessageIds - if (current.contains(messageId)) { - currentState.copy(selectedMessageIds = current - messageId) - } else { - if (current.size < 100) { - currentState.copy(selectedMessageIds = current + messageId) - } else { - currentState - } - } - } -} - -internal fun DefaultChatComponent.handleClearSelection() { - _state.update { it.copy(selectedMessageIds = emptySet()) } -} - -internal fun DefaultChatComponent.handleDeleteSelectedMessages(revoke: Boolean = false) { - val ids = _state.value.selectedMessageIds.toList().sorted() - if (ids.isNotEmpty()) { - scope.launch { - repositoryMessage.deleteMessage(chatId, ids, revoke) - onClearSelection() - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/MiniAppOperations.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/MiniAppOperations.kt deleted file mode 100644 index 5d19239b..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/MiniAppOperations.kt +++ /dev/null @@ -1,60 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.impl - -import android.util.Log - -import kotlinx.coroutines.flow.update -import org.monogram.presentation.features.chats.currentChat.DefaultChatComponent - -internal fun DefaultChatComponent.handleOpenMiniApp(url: String, name: String, botUserId: Long) { - if (botUserId != 0L && !botPreferences.getWebappPermission(botUserId, "tos_accepted")) { - _state.update { it.copy( - showMiniAppTOS = true, - miniAppTOSBotUserId = botUserId, - miniAppTOSUrl = url, - miniAppTOSName = name - ) } - } else { - _state.update { it.copy( - miniAppUrl = url, - miniAppName = name, - miniAppBotUserId = botUserId - ) } - } -} - -internal fun DefaultChatComponent.handleAcceptMiniAppTOS() { - val botUserId = _state.value.miniAppTOSBotUserId - val url = _state.value.miniAppTOSUrl - val name = _state.value.miniAppTOSName - if (botUserId != 0L && url != null && name != null) { - botPreferences.setWebappPermission(botUserId, "tos_accepted", true) - _state.update { it.copy( - showMiniAppTOS = false, - miniAppTOSBotUserId = 0L, - miniAppTOSUrl = null, - miniAppTOSName = null, - miniAppUrl = url, - miniAppName = name, - miniAppBotUserId = botUserId - ) } - } -} - -internal fun DefaultChatComponent.handleDismissMiniAppTOS() { - _state.update { it.copy( - showMiniAppTOS = false, - miniAppTOSBotUserId = 0L, - miniAppTOSUrl = null, - miniAppTOSName = null - ) } -} - -internal fun DefaultChatComponent.handleOpenInvoice(slug: String?, messageId: Long?) { - Log.d("DefaultChatComponent", "onOpenInvoice: slug=$slug, messageId=$messageId") - _state.update { it.copy(invoiceSlug = slug, invoiceMessageId = messageId) } -} - -internal fun DefaultChatComponent.handleDismissInvoice(status: String) { - Log.d("DefaultChatComponent", "onDismissInvoice: status=$status") - _state.update { it.copy(invoiceSlug = null, invoiceMessageId = null) } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/PinnedMessages.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/PinnedMessages.kt deleted file mode 100644 index 1ae23a2b..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/PinnedMessages.kt +++ /dev/null @@ -1,133 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.impl - -import android.util.Log -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.features.chats.currentChat.DefaultChatComponent - - -internal fun DefaultChatComponent.loadPinnedMessage() { - scope.launch { - val threadId = _state.value.currentTopicId - try { - val pinned = repositoryMessage.getPinnedMessage(chatId, threadId) - val count = repositoryMessage.getPinnedMessageCount(chatId, threadId) - Log.d( - "DefaultChatComponent", - "loadPinnedMessage: chatId=$chatId, threadId=$threadId, pinnedId=${pinned?.id}, count=$count" - ) - _state.update { - it.copy( - pinnedMessage = pinned, - pinnedMessageCount = count, - pinnedMessageIndex = 0 - ) - } - } catch (e: Exception) { - Log.e("DefaultChatComponent", "Error loading pinned message", e) - } - } -} - -internal fun DefaultChatComponent.loadAllPinnedMessages() { - scope.launch { - val threadId = _state.value.currentTopicId - try { - val pinnedMessages = repositoryMessage.getAllPinnedMessages(chatId, threadId) - _state.update { - it.copy(allPinnedMessages = pinnedMessages) - } - } catch (e: Exception) { - Log.e("DefaultChatComponent", "Error loading all pinned messages", e) - } - } -} - -internal fun DefaultChatComponent.loadScheduledMessages() { - scope.launch { - try { - val scheduledMessages = repositoryMessage.getScheduledMessages(chatId) - _state.update { it.copy(scheduledMessages = scheduledMessages) } - } catch (e: Exception) { - Log.e("DefaultChatComponent", "Error loading scheduled messages", e) - } - } -} - -internal fun DefaultChatComponent.setupPinnedMessageCollector() { - repositoryMessage.pinnedMessageFlow - .onEach { cId -> - if (cId == chatId) { - Log.d("DefaultChatComponent", "pinnedMessageFlow triggered for chatId=$chatId") - loadPinnedMessage() - if (_state.value.showPinnedMessagesList) { - loadAllPinnedMessages() - } - } - } - .launchIn(scope) -} - -internal fun DefaultChatComponent.handlePinnedMessageClick(message: MessageModel?) { - if (message != null) { - jumpToMessage(message) - return - } - - val currentState = _state.value - if (currentState.pinnedMessageCount <= 1) { - currentState.pinnedMessage?.let { jumpToMessage(it) } - return - } - - scope.launch { - val threadId = currentState.currentTopicId - val nextIndex = (currentState.pinnedMessageIndex + 1) % currentState.pinnedMessageCount - val pinnedMessages = repositoryMessage.getAllPinnedMessages(chatId, threadId) - if (pinnedMessages.isNotEmpty()) { - val nextPinned = pinnedMessages.getOrNull(nextIndex) ?: pinnedMessages.first() - _state.update { - it.copy( - pinnedMessage = nextPinned, - pinnedMessageIndex = nextIndex - ) - } - jumpToMessage(nextPinned) - } - } -} - -private fun DefaultChatComponent.jumpToMessage(message: MessageModel) { - if (_state.value.isLoading) return - - scope.launch { - _state.update { it.copy(isLoading = true) } - try { - val threadId = _state.value.currentTopicId - val messages = repositoryMessage.getMessagesAround(chatId, message.id, 50, threadId) - if (messages.isNotEmpty()) { - _state.update { - it.copy( - scrollToMessageId = message.id, - highlightedMessageId = message.id, - isAtBottom = false, - isLatestLoaded = false, - isOldestLoaded = false - ) - } - updateMessages(messages, replace = true) - lastLoadedOlderId = 0L - lastLoadedNewerId = 0L - loadMoreMessages() - loadNewerMessages() - } - } catch (e: Exception) { - Log.e("DefaultChatComponent", "Error jumping to message", e) - } finally { - _state.update { it.copy(isLoading = false) } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/PollOperations.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/PollOperations.kt deleted file mode 100644 index ce85ce27..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/PollOperations.kt +++ /dev/null @@ -1,38 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.impl - -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch -import org.monogram.presentation.features.chats.currentChat.DefaultChatComponent - -internal fun DefaultChatComponent.handlePollOptionClick(messageId: Long, optionId: Int) { - scope.launch { - repositoryMessage.setPollAnswer(chatId, messageId, listOf(optionId)) - } -} - -internal fun DefaultChatComponent.handleRetractVote(messageId: Long) { - scope.launch { - repositoryMessage.setPollAnswer(chatId, messageId, emptyList()) - } -} - -internal fun DefaultChatComponent.handleShowVoters(messageId: Long, optionId: Int) { - scope.launch { - _state.update { it.copy( - showPollVoters = true, - pollVoters = emptyList(), - isPollVotersLoading = true - ) } - val voters = repositoryMessage.getPollVoters(chatId, messageId, optionId, 0, 50) - _state.update { it.copy( - pollVoters = voters, - isPollVotersLoading = false - ) } - } -} - -internal fun DefaultChatComponent.handleClosePoll(messageId: Long) { - scope.launch { - repositoryMessage.stopPoll(chatId, messageId) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/Preferences.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/Preferences.kt deleted file mode 100644 index 5ada6f7a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/Preferences.kt +++ /dev/null @@ -1,148 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.impl - - -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.update -import org.monogram.domain.models.WallpaperModel -import org.monogram.presentation.features.chats.currentChat.DefaultChatComponent - -internal fun DefaultChatComponent.observePreferences(availableWallpapers: List) { - appPreferences.fontSize - .onEach { size -> - _state.update { it.copy(fontSize = size) } - } - .launchIn(scope) - - appPreferences.letterSpacing - .onEach { spacing -> - _state.update { it.copy(letterSpacing = spacing) } - } - .launchIn(scope) - - appPreferences.bubbleRadius - .onEach { radius -> - _state.update { it.copy(bubbleRadius = radius) } - } - .launchIn(scope) - - val firstThree = combine( - appPreferences.wallpaper, - appPreferences.isWallpaperBlurred, - appPreferences.wallpaperBlurIntensity - ) { wallpaper, blurred, intensity -> - Triple(wallpaper, blurred, intensity) - } - - val lastThree = combine( - appPreferences.isWallpaperMoving, - appPreferences.wallpaperDimming, - appPreferences.isWallpaperGrayscale - ) { moving, dimming, grayscale -> - Triple(moving, dimming, grayscale) - } - - combine(firstThree, lastThree) { first, last -> - val (wallpaper, blurred, intensity) = first - val (moving, dimming, grayscale) = last - val model = if (wallpaper != null) { - availableWallpapers.find { it.slug == wallpaper || it.localPath == wallpaper } - } else { - null - } - - _state.update { currentState -> - currentState.copy( - wallpaper = wallpaper, - wallpaperModel = model, - isWallpaperBlurred = blurred, - wallpaperBlurIntensity = intensity, - isWallpaperMoving = moving, - wallpaperDimming = dimming, - isWallpaperGrayscale = grayscale - ) - } - }.launchIn(scope) - - appPreferences.isPlayerGesturesEnabled - .onEach { enabled -> - _state.update { it.copy(isPlayerGesturesEnabled = enabled) } - } - .launchIn(scope) - - appPreferences.isPlayerDoubleTapSeekEnabled - .onEach { enabled -> - _state.update { it.copy(isPlayerDoubleTapSeekEnabled = enabled) } - } - .launchIn(scope) - - appPreferences.playerSeekDuration - .onEach { duration -> - _state.update { it.copy(playerSeekDuration = duration) } - } - .launchIn(scope) - - appPreferences.isPlayerZoomEnabled - .onEach { enabled -> - _state.update { it.copy(isPlayerZoomEnabled = enabled) } - } - .launchIn(scope) - - appPreferences.autoDownloadMobile.onEach { value -> - _state.update { it.copy(autoDownloadMobile = value) } - }.launchIn(scope) - - appPreferences.autoDownloadWifi.onEach { value -> - _state.update { it.copy(autoDownloadWifi = value) } - }.launchIn(scope) - - appPreferences.autoDownloadRoaming.onEach { value -> - _state.update { it.copy(autoDownloadRoaming = value) } - }.launchIn(scope) - - appPreferences.autoDownloadFiles.onEach { value -> - _state.update { it.copy(autoDownloadFiles = value) } - }.launchIn(scope) - - appPreferences.autoplayGifs.onEach { value -> - _state.update { it.copy(autoplayGifs = value) } - }.launchIn(scope) - - appPreferences.autoplayVideos.onEach { value -> - _state.update { it.copy(autoplayVideos = value) } - }.launchIn(scope) - - appPreferences.showLinkPreviews.onEach { value -> - _state.update { it.copy(showLinkPreviews = value) } - }.launchIn(scope) - - combine(appPreferences.isChatAnimationsEnabled, appPreferences.isPowerSavingMode) { enabled, powerSaving -> - if (powerSaving) false else enabled - }.onEach { value -> - _state.update { it.copy(isChatAnimationsEnabled = value) } - }.launchIn(scope) - - combine(appPreferences.isAdBlockEnabled, appPreferences.adBlockKeywords) { enabled, keywords -> - enabled to keywords - }.onEach { - if (_state.value.isChannel) { - loadMessages() - } - }.launchIn(scope) -} - -internal fun DefaultChatComponent.loadWallpapers(onLoaded: (List) -> Unit) { - settingsRepository.getWallpapers() - .onEach { wallpapers -> - onLoaded(wallpapers) - val currentWallpaper = appPreferences.wallpaper.value - val model = if (currentWallpaper != null) { - wallpapers.find { it.slug == currentWallpaper || it.localPath == currentWallpaper } - } else { - null - } - _state.update { it.copy(wallpaperModel = model) } - } - .launchIn(scope) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/Stickers.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/Stickers.kt deleted file mode 100644 index df5cb1f7..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/currentChat/impl/Stickers.kt +++ /dev/null @@ -1,24 +0,0 @@ -package org.monogram.presentation.features.chats.currentChat.impl - -import android.util.Log -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch -import org.monogram.presentation.features.chats.currentChat.DefaultChatComponent - -internal fun DefaultChatComponent.handleStickerClick(setId: Long) { - if (setId == 0L) return - scope.launch { - try { - val stickerSet = stickerRepository.getStickerSet(setId) - _state.update { it.copy(selectedStickerSet = stickerSet) } - } catch (e: Exception) { - Log.e("DefaultChatComponent", "Error getting sticker set", e) - } - } -} - -internal fun DefaultChatComponent.handleAddToGifs(path: String) { - scope.launch { - stickerRepository.addSavedGif(path) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/newChat/DefaultNewChatComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/newChat/DefaultNewChatComponent.kt deleted file mode 100644 index 103b7bc9..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/newChat/DefaultNewChatComponent.kt +++ /dev/null @@ -1,329 +0,0 @@ -package org.monogram.presentation.features.chats.newChat - -import com.arkivanov.mvikotlin.core.instancekeeper.getStore -import com.arkivanov.mvikotlin.extensions.coroutines.stateFlow -import com.arkivanov.mvikotlin.main.store.DefaultStoreFactory -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.Job -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.* -import kotlinx.coroutines.launch -import org.monogram.domain.repository.ChatsListRepository -import org.monogram.domain.repository.UserRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.root.AppComponentContext - -class DefaultNewChatComponent( - context: AppComponentContext, - private val onBackClicked: () -> Unit, - private val onChatCreated: (Long) -> Unit, - private val onProfileClicked: (Long) -> Unit -) : NewChatComponent, AppComponentContext by context { - - private val userRepository: UserRepository = container.repositories.userRepository - private val chatsListRepository: ChatsListRepository = container.repositories.chatsListRepository - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - - private val scope = componentScope - private val _state = MutableStateFlow(NewChatComponent.State()) - - private val store = instanceKeeper.getStore { - NewChatStoreFactory( - storeFactory = DefaultStoreFactory(), - component = this - ).create() - } - - @OptIn(ExperimentalCoroutinesApi::class) - override val state: StateFlow = store.stateFlow - - private var searchJob: Job? = null - - init { - loadContacts() - - _state.onEach { - store.accept(NewChatStore.Intent.UpdateState(it)) - }.launchIn(scope) - } - - private fun loadContacts() { - scope.launch { - _state.update { it.copy(isLoading = true) } - val contacts = userRepository.getContacts() - _state.update { it.copy(contacts = contacts, isLoading = false) } - } - } - - override fun onBack() = store.accept(NewChatStore.Intent.Back) - - override fun onUserClicked(userId: Long) = store.accept(NewChatStore.Intent.UserClicked(userId)) - - override fun onOpenProfile(userId: Long) = store.accept(NewChatStore.Intent.OpenProfile(userId)) - - override fun onEditContact(userId: Long, firstName: String, lastName: String) = - store.accept(NewChatStore.Intent.EditContact(userId, firstName, lastName)) - - override fun onRemoveContact(userId: Long) = store.accept(NewChatStore.Intent.RemoveContact(userId)) - - override fun onSearchQueryChange(query: String) = store.accept(NewChatStore.Intent.SearchQueryChange(query)) - - override fun onCreateGroup() = store.accept(NewChatStore.Intent.CreateGroup) - - override fun onCreateChannel() = store.accept(NewChatStore.Intent.CreateChannel) - - override fun onTitleChange(title: String) = store.accept(NewChatStore.Intent.TitleChange(title)) - - override fun onDescriptionChange(description: String) = - store.accept(NewChatStore.Intent.DescriptionChange(description)) - - override fun onPhotoSelected(path: String?) = store.accept(NewChatStore.Intent.PhotoSelected(path)) - - override fun onToggleUserSelection(userId: Long) = store.accept(NewChatStore.Intent.ToggleUserSelection(userId)) - - override fun onAutoDeleteTimeChange(seconds: Int) = store.accept(NewChatStore.Intent.AutoDeleteTimeChange(seconds)) - - override fun onConfirmCreate() = store.accept(NewChatStore.Intent.ConfirmCreate) - - override fun onStepBack() = store.accept(NewChatStore.Intent.StepBack) - - override fun onConsumeValidationError() = store.accept(NewChatStore.Intent.ConsumeValidationError) - - // Internal logic called by Store Executor - internal fun handleBack() { - onBackClicked() - } - - internal fun handleUserClicked(userId: Long) { - if (_state.value.step == NewChatComponent.Step.CONTACTS) { - onChatCreated(userId) - } - } - - internal fun handleOpenProfile(userId: Long) { - if (_state.value.step == NewChatComponent.Step.CONTACTS) { - onProfileClicked(userId) - } - } - - internal fun handleEditContact(userId: Long, firstName: String, lastName: String) { - if (_state.value.step != NewChatComponent.Step.CONTACTS || firstName.isBlank()) return - - val currentContact = _state.value.contacts.firstOrNull { it.id == userId } ?: return - val normalizedLastName = lastName.trim().ifBlank { null } - val trimmedFirstName = firstName.trim() - - scope.launch { - runCatching { - userRepository.addContact( - currentContact.copy( - firstName = trimmedFirstName, - lastName = normalizedLastName, - isContact = true - ) - ) - }.onSuccess { - _state.update { current -> - current.copy( - contacts = current.contacts.map { user -> - if (user.id == userId) { - user.copy(firstName = trimmedFirstName, lastName = normalizedLastName) - } else { - user - } - }, - searchResults = current.searchResults.map { user -> - if (user.id == userId) { - user.copy(firstName = trimmedFirstName, lastName = normalizedLastName) - } else { - user - } - } - ) - } - loadContacts() - } - } - } - - internal fun handleRemoveContact(userId: Long) { - if (_state.value.step != NewChatComponent.Step.CONTACTS) return - - scope.launch { - userRepository.removeContact(userId) - loadContacts() - } - } - - internal fun handleSearchQueryChange(query: String) { - _state.update { it.copy(searchQuery = query) } - searchJob?.cancel() - searchJob = scope.launch { - delay(300) - if (query.isNotEmpty()) { - val results = userRepository.searchContacts(query) - _state.update { it.copy(searchResults = results) } - } else { - _state.update { it.copy(searchResults = emptyList()) } - } - } - } - - internal fun handleCreateGroup() { - _state.update { - it.copy( - step = NewChatComponent.Step.GROUP_MEMBERS, - selectedUserIds = emptySet(), - searchQuery = "", - searchResults = emptyList(), - validationError = null - ) - } - } - - internal fun handleCreateChannel() { - _state.update { - it.copy( - step = NewChatComponent.Step.CHANNEL_INFO, - selectedUserIds = emptySet(), - validationError = null - ) - } - } - - internal fun handleTitleChange(title: String) { - _state.update { it.copy(title = title, validationError = null) } - } - - internal fun handleDescriptionChange(description: String) { - _state.update { it.copy(description = description, validationError = null) } - } - - internal fun handlePhotoSelected(path: String?) { - _state.update { it.copy(photoPath = path) } - } - - internal fun handleToggleUserSelection(userId: Long) { - _state.update { - val newSelected = if (it.selectedUserIds.contains(userId)) { - it.selectedUserIds - userId - } else { - it.selectedUserIds + userId - } - it.copy(selectedUserIds = newSelected) - } - } - - internal fun handleAutoDeleteTimeChange(seconds: Int) { - _state.update { it.copy(autoDeleteTime = seconds) } - } - - internal fun handleConfirmCreate() { - val currentState = _state.value - if (currentState.isCreating) return - - when (currentState.step) { - NewChatComponent.Step.GROUP_MEMBERS -> { - if (currentState.selectedUserIds.isNotEmpty()) { - _state.update { - it.copy( - step = NewChatComponent.Step.GROUP_INFO, - searchQuery = "", - searchResults = emptyList(), - validationError = null - ) - } - } - } - - NewChatComponent.Step.GROUP_INFO -> { - if (currentState.title.isBlank()) { - _state.update { - it.copy(validationError = NewChatComponent.ValidationError.GROUP_TITLE_REQUIRED) - } - return - } - - scope.launch { - _state.update { it.copy(isCreating = true, validationError = null) } - try { - val chatId = chatsListRepository.createGroup( - currentState.title, - currentState.selectedUserIds.toList(), - currentState.autoDeleteTime - ) - if (chatId != 0L) { - if (currentState.photoPath != null) { - chatsListRepository.setChatPhoto(chatId, currentState.photoPath) - } - onChatCreated(chatId) - } - } finally { - _state.update { it.copy(isCreating = false) } - } - } - } - - NewChatComponent.Step.CHANNEL_INFO -> { - if (currentState.title.isBlank()) { - _state.update { - it.copy(validationError = NewChatComponent.ValidationError.CHANNEL_TITLE_REQUIRED) - } - return - } - - scope.launch { - _state.update { it.copy(isCreating = true, validationError = null) } - try { - val chatId = chatsListRepository.createChannel( - currentState.title, - currentState.description, - messageAutoDeleteTime = currentState.autoDeleteTime - ) - if (chatId != 0L) { - if (currentState.photoPath != null) { - chatsListRepository.setChatPhoto(chatId, currentState.photoPath) - } - onChatCreated(chatId) - } - } finally { - _state.update { it.copy(isCreating = false) } - } - } - } - - else -> {} - } - } - - internal fun handleStepBack() { - _state.update { - when (it.step) { - NewChatComponent.Step.GROUP_MEMBERS -> it.copy( - step = NewChatComponent.Step.CONTACTS, - selectedUserIds = emptySet(), - searchQuery = "", - searchResults = emptyList(), - validationError = null - ) - - NewChatComponent.Step.GROUP_INFO -> it.copy( - step = NewChatComponent.Step.GROUP_MEMBERS, - validationError = null - ) - - NewChatComponent.Step.CHANNEL_INFO -> it.copy( - step = NewChatComponent.Step.CONTACTS, - validationError = null - ) - else -> it - } - } - } - - internal fun handleConsumeValidationError() { - _state.update { it.copy(validationError = null) } - } - -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/newChat/NewChatComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/newChat/NewChatComponent.kt deleted file mode 100644 index 6a06d470..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/newChat/NewChatComponent.kt +++ /dev/null @@ -1,53 +0,0 @@ -package org.monogram.presentation.features.chats.newChat - -import kotlinx.coroutines.flow.StateFlow -import org.monogram.domain.models.UserModel -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -interface NewChatComponent { - val state: StateFlow - val videoPlayerPool: VideoPlayerPool - - fun onBack() - fun onUserClicked(userId: Long) - fun onOpenProfile(userId: Long) - fun onEditContact(userId: Long, firstName: String, lastName: String) - fun onRemoveContact(userId: Long) - fun onSearchQueryChange(query: String) - fun onCreateGroup() - fun onCreateChannel() - - // Group/Channel creation - fun onTitleChange(title: String) - fun onDescriptionChange(description: String) - fun onPhotoSelected(path: String?) - fun onToggleUserSelection(userId: Long) - fun onAutoDeleteTimeChange(seconds: Int) - fun onConfirmCreate() - fun onStepBack() - fun onConsumeValidationError() - - data class State( - val contacts: List = emptyList(), - val searchQuery: String = "", - val searchResults: List = emptyList(), - val isLoading: Boolean = false, - val step: Step = Step.CONTACTS, - val selectedUserIds: Set = emptySet(), - val title: String = "", - val description: String = "", - val photoPath: String? = null, - val autoDeleteTime: Int = 0, - val isCreating: Boolean = false, - val validationError: ValidationError? = null - ) - - enum class ValidationError { - GROUP_TITLE_REQUIRED, - CHANNEL_TITLE_REQUIRED - } - - enum class Step { - CONTACTS, GROUP_MEMBERS, GROUP_INFO, CHANNEL_INFO - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/newChat/NewChatContent.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/newChat/NewChatContent.kt deleted file mode 100644 index 010bd129..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/newChat/NewChatContent.kt +++ /dev/null @@ -1,860 +0,0 @@ -package org.monogram.presentation.features.chats.newChat - -import androidx.activity.compose.BackHandler -import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.PickVisualMediaRequest -import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.animation.AnimatedContent -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.Announcement -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.automirrored.rounded.ArrowForward -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.DpOffset -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.UserModel -import org.monogram.domain.models.UserStatusType -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.ui.ConfirmationSheet -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.shimmerBackground -import org.monogram.presentation.core.util.FileUtils -import org.monogram.presentation.core.util.getUserStatusText -import org.monogram.presentation.features.chats.chatList.components.NewChannelContent -import org.monogram.presentation.features.chats.chatList.components.NewGroupContent -import org.monogram.presentation.features.chats.chatList.components.SectionHeader -import org.monogram.presentation.features.chats.chatList.components.SettingsTextField -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun NewChatContent(component: NewChatComponent) { - val state by component.state.collectAsState() - var isSearchActive by remember { mutableStateOf(false) } - var editingContact by remember { mutableStateOf(null) } - var removingContact by remember { mutableStateOf(null) } - var editFirstName by remember { mutableStateOf("") } - var editLastName by remember { mutableStateOf("") } - val snackbarHostState = remember { SnackbarHostState() } - val context = LocalContext.current - - val groupNameRequired = stringResource(R.string.group_name_required) - val channelNameRequired = stringResource(R.string.channel_name_required) - - LaunchedEffect(state.validationError) { - when (state.validationError) { - NewChatComponent.ValidationError.GROUP_TITLE_REQUIRED -> { - snackbarHostState.showSnackbar(groupNameRequired) - component.onConsumeValidationError() - } - - NewChatComponent.ValidationError.CHANNEL_TITLE_REQUIRED -> { - snackbarHostState.showSnackbar(channelNameRequired) - component.onConsumeValidationError() - } - - null -> Unit - } - } - - LaunchedEffect(state.step) { - if (state.step != NewChatComponent.Step.CONTACTS && state.step != NewChatComponent.Step.GROUP_MEMBERS) { - isSearchActive = false - } - } - - val photoPickerLauncher = rememberLauncherForActivityResult( - contract = ActivityResultContracts.PickVisualMedia() - ) { uri -> - if (uri != null) { - val path = FileUtils.getPath(context, uri) - component.onPhotoSelected(path) - } - } - - BackHandler(enabled = state.step != NewChatComponent.Step.CONTACTS) { - component.onStepBack() - } - - Scaffold( - modifier = Modifier.semantics { contentDescription = "NewChatContent" }, - snackbarHost = { SnackbarHost(snackbarHostState) }, - topBar = { - AnimatedContent( - targetState = isSearchActive, - label = "TopBarSearchTransition" - ) { searching -> - if (searching) { - Box( - modifier = Modifier - .fillMaxWidth() - .statusBarsPadding() - .padding(horizontal = 16.dp, vertical = 8.dp) - ) { - SearchBar( - inputField = { - SearchBarDefaults.InputField( - query = state.searchQuery, - onQueryChange = component::onSearchQueryChange, - onSearch = {}, - expanded = false, - onExpandedChange = {}, - placeholder = { Text(stringResource(R.string.search_contacts_hint)) }, - leadingIcon = { - IconButton(onClick = { - isSearchActive = false - component.onSearchQueryChange("") - }) { - Icon(Icons.AutoMirrored.Rounded.ArrowBack, contentDescription = stringResource(R.string.cd_back)) - } - }, - trailingIcon = { - if (state.searchQuery.isNotEmpty()) { - IconButton(onClick = { component.onSearchQueryChange("") }) { - Icon(Icons.Rounded.Close, contentDescription = stringResource(R.string.action_clear)) - } - } - } - ) - }, - expanded = false, - onExpandedChange = {}, - shape = RoundedCornerShape(24.dp), - colors = SearchBarDefaults.colors( - containerColor = MaterialTheme.colorScheme.surfaceContainerHigh, - dividerColor = Color.Transparent - ), - modifier = Modifier.fillMaxWidth() - ) {} - } - } else { - TopAppBar( - title = { - Column { - val title = when (state.step) { - NewChatComponent.Step.CONTACTS -> stringResource(R.string.new_message_title) - NewChatComponent.Step.GROUP_MEMBERS -> stringResource(R.string.add_members_title) - NewChatComponent.Step.GROUP_INFO -> stringResource(R.string.new_group_title) - NewChatComponent.Step.CHANNEL_INFO -> stringResource(R.string.new_channel_title) - } - Text( - text = title, - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - if (state.step == NewChatComponent.Step.CONTACTS && state.contacts.isNotEmpty()) { - Text( - stringResource(R.string.contacts_count_format, state.contacts.size), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } else if (state.step == NewChatComponent.Step.GROUP_MEMBERS) { - Text( - stringResource(R.string.selected_members_count, state.selectedUserIds.size), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - }, - navigationIcon = { - IconButton(onClick = { - if (state.step == NewChatComponent.Step.CONTACTS) component.onBack() - else component.onStepBack() - }) { - Icon(Icons.AutoMirrored.Rounded.ArrowBack, stringResource(R.string.cd_back)) - } - }, - actions = { - if (state.step == NewChatComponent.Step.CONTACTS || state.step == NewChatComponent.Step.GROUP_MEMBERS) { - IconButton(onClick = { isSearchActive = true }) { - Icon(Icons.Rounded.Search, stringResource(R.string.action_search)) - } - } - } - ) - } - } - }, - floatingActionButton = { - if (state.step == NewChatComponent.Step.GROUP_MEMBERS && state.selectedUserIds.isNotEmpty()) { - FloatingActionButton(onClick = { component.onConfirmCreate() }) { - Icon(Icons.AutoMirrored.Rounded.ArrowForward, stringResource(R.string.continue_button)) - } - } else if (state.step == NewChatComponent.Step.GROUP_INFO || state.step == NewChatComponent.Step.CHANNEL_INFO) { - FloatingActionButton( - onClick = { - if (!state.isCreating) { - component.onConfirmCreate() - } - }, - containerColor = if (state.title.isNotBlank() && !state.isCreating) { - MaterialTheme.colorScheme.primary - } else { - MaterialTheme.colorScheme.surfaceVariant - }, - contentColor = if (state.title.isNotBlank() && !state.isCreating) { - MaterialTheme.colorScheme.onPrimary - } else { - MaterialTheme.colorScheme.onSurfaceVariant - } - ) { - if (state.isCreating) { - CircularProgressIndicator( - modifier = Modifier.size(22.dp), - strokeWidth = 2.dp, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } else { - Icon(Icons.Rounded.Check, stringResource(R.string.confirm_button)) - } - } - } - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - Box(modifier = Modifier.padding(padding)) { - when (state.step) { - NewChatComponent.Step.CONTACTS, NewChatComponent.Step.GROUP_MEMBERS -> { - ContactsList( - state = state, - isSearchActive = isSearchActive, - onActionClick = { action -> - when (action) { - "group" -> component.onCreateGroup() - "channel" -> component.onCreateChannel() - } - }, - videoPlayerPool = component.videoPlayerPool, - onUserClick = { user -> - if (state.step == NewChatComponent.Step.GROUP_MEMBERS) { - component.onToggleUserSelection(user.id) - } else { - component.onUserClicked(user.id) - } - }, - onOpenProfile = { user -> - component.onOpenProfile(user.id) - }, - onEditContact = { user -> - editingContact = user - editFirstName = user.firstName - editLastName = user.lastName.orEmpty() - }, - onRemoveContact = { user -> - removingContact = user - } - ) - } - - NewChatComponent.Step.GROUP_INFO -> { - NewGroupContent( - title = state.title, - description = state.description, - photoPath = state.photoPath, - autoDeleteTime = state.autoDeleteTime, - onTitleChange = component::onTitleChange, - onDescriptionChange = component::onDescriptionChange, - onPhotoClick = { - photoPickerLauncher.launch( - PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly) - ) - }, - onAutoDeleteTimeChange = component::onAutoDeleteTimeChange, - videoPlayerPool = component.videoPlayerPool - ) - } - - NewChatComponent.Step.CHANNEL_INFO -> { - NewChannelContent( - title = state.title, - description = state.description, - photoPath = state.photoPath, - autoDeleteTime = state.autoDeleteTime, - onTitleChange = component::onTitleChange, - onDescriptionChange = component::onDescriptionChange, - onPhotoClick = { - photoPickerLauncher.launch( - PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly) - ) - }, - onAutoDeleteTimeChange = component::onAutoDeleteTimeChange, - videoPlayerPool = component.videoPlayerPool - ) - } - } - } - } - - editingContact?.let { contact -> - ModalBottomSheet( - onDismissRequest = { editingContact = null }, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp), - sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 32.dp) - ) { - Text( - text = stringResource(R.string.edit_contact_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - - Spacer(modifier = Modifier.height(12.dp)) - - SettingsTextField( - value = editFirstName, - onValueChange = { editFirstName = it }, - placeholder = stringResource(R.string.first_name_label), - icon = Icons.Rounded.Person, - position = ItemPosition.TOP, - singleLine = true, - modifier = Modifier.fillMaxWidth() - ) - - SettingsTextField( - value = editLastName, - onValueChange = { editLastName = it }, - placeholder = stringResource(R.string.last_name_label), - icon = Icons.Rounded.Edit, - position = ItemPosition.BOTTOM, - singleLine = true, - modifier = Modifier.fillMaxWidth() - ) - - Spacer(modifier = Modifier.height(16.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - OutlinedButton( - onClick = { editingContact = null }, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.cancel_button), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - - Button( - onClick = { - component.onEditContact(contact.id, editFirstName, editLastName) - editingContact = null - }, - enabled = editFirstName.isNotBlank(), - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.action_save), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } - } - } - - removingContact?.let { contact -> - val displayName = "${contact.firstName} ${contact.lastName.orEmpty()}".trim() - ConfirmationSheet( - icon = Icons.Rounded.Delete, - title = stringResource(R.string.remove_contact_title), - description = stringResource(R.string.remove_contact_confirmation, displayName), - confirmText = stringResource(R.string.action_remove_contact), - onConfirm = { - component.onRemoveContact(contact.id) - removingContact = null - }, - onDismiss = { removingContact = null } - ) - } - -} - -@Composable -private fun ContactsList( - state: NewChatComponent.State, - isSearchActive: Boolean, - videoPlayerPool: VideoPlayerPool, - onActionClick: (String) -> Unit, - onUserClick: (UserModel) -> Unit, - onOpenProfile: (UserModel) -> Unit, - onEditContact: (UserModel) -> Unit, - onRemoveContact: (UserModel) -> Unit -) { - val selectedUsers = remember(state.contacts, state.selectedUserIds) { - state.contacts.filter { state.selectedUserIds.contains(it.id) } - } - - LazyColumn( - modifier = Modifier.fillMaxSize(), - contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp) - ) { - if (state.step == NewChatComponent.Step.GROUP_MEMBERS && selectedUsers.isNotEmpty()) { - item { - SectionHeader(stringResource(R.string.selected_members_count, selectedUsers.size)) - LazyRow( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(8.dp), - contentPadding = PaddingValues(bottom = 8.dp) - ) { - items(selectedUsers, key = { it.id }) { user -> - FilterChip( - selected = true, - onClick = { onUserClick(user) }, - label = { - Text( - text = user.firstName, - maxLines = 1 - ) - }, - leadingIcon = { - Icon( - imageVector = Icons.Rounded.Person, - contentDescription = null, - modifier = Modifier.size(16.dp) - ) - }, - trailingIcon = { - Icon( - imageVector = Icons.Rounded.Close, - contentDescription = stringResource(R.string.action_clear), - modifier = Modifier.size(16.dp) - ) - } - ) - } - } - } - } - - if (!isSearchActive && state.step == NewChatComponent.Step.CONTACTS) { - item { - NewChatActionItem( - icon = Icons.Rounded.Group, - title = stringResource(R.string.new_group_action), - position = ItemPosition.TOP, - onClick = { onActionClick("group") } - ) - NewChatActionItem( - icon = Icons.AutoMirrored.Rounded.Announcement, - title = stringResource(R.string.new_channel_action), - position = ItemPosition.BOTTOM, - onClick = { onActionClick("channel") } - ) - } - - item { - SectionHeader(stringResource(R.string.sorted_by_last_seen)) - } - } - - val displayList = if (state.searchQuery.isNotEmpty()) state.searchResults else state.contacts - - if (displayList.isEmpty() && !state.isLoading) { - item { - val message = if (state.searchQuery.isNotEmpty()) { - stringResource(R.string.no_search_results_format, state.searchQuery) - } else { - stringResource(R.string.no_contacts_found) - } - - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp, vertical = 40.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Text( - text = message, - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } - - itemsIndexed(displayList, key = { _, user -> user.id }) { index, user -> - val position = when { - displayList.size == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == displayList.size - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - ContactItem( - user = user, - isSelected = state.selectedUserIds.contains(user.id), - showCheckbox = state.step == NewChatComponent.Step.GROUP_MEMBERS, - enableLongPress = state.step == NewChatComponent.Step.CONTACTS, - position = position, - onClick = { onUserClick(user) }, - onOpenProfile = { onOpenProfile(user) }, - onEditContact = { onEditContact(user) }, - onRemoveContact = { onRemoveContact(user) }, - videoPlayerPool = videoPlayerPool - ) - } - - if (state.isLoading) { - items(6) { index -> - val position = when { - index == 0 -> ItemPosition.TOP - index == 5 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - ContactItemShimmer( - position = position, - showCheckbox = state.step == NewChatComponent.Step.GROUP_MEMBERS - ) - } - } - } - -} - -@Composable -private fun NewChatActionItem( - icon: ImageVector, - title: String, - position: ItemPosition, - onClick: () -> Unit -) { - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - .clickable(onClick = onClick) - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(40.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primaryContainer), - contentAlignment = Alignment.Center - ) { - Icon( - icon, - null, - tint = MaterialTheme.colorScheme.onPrimaryContainer, - modifier = Modifier.size(24.dp) - ) - } - Spacer(modifier = Modifier.width(16.dp)) - Text( - title, - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Medium - ) - } - } - if (position != ItemPosition.BOTTOM && position != ItemPosition.STANDALONE) { - Spacer(Modifier.height(2.dp)) - } -} - -@Composable -private fun ContactItem( - user: UserModel, - isSelected: Boolean, - showCheckbox: Boolean, - enableLongPress: Boolean, - position: ItemPosition, - videoPlayerPool: VideoPlayerPool, - onClick: () -> Unit, - onOpenProfile: () -> Unit, - onEditContact: () -> Unit, - onRemoveContact: () -> Unit -) { - val context = LocalContext.current - val isSupport = user.isSupport - var showMenu by remember { mutableStateOf(false) } - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Box { - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - .combinedClickable( - onClick = onClick, - onLongClick = { - if (enableLongPress) { - showMenu = true - } - } - ) - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Avatar( - path = user.avatarPath, - fallbackPath = user.personalAvatarPath, - name = user.firstName, - size = 40.dp, - isOnline = user.userStatus == UserStatusType.ONLINE && !isSupport, - videoPlayerPool = videoPlayerPool - ) - Spacer(modifier = Modifier.width(16.dp)) - Column(modifier = Modifier.weight(1f)) { - Text( - text = "${user.firstName} ${user.lastName ?: ""}".trim(), - style = MaterialTheme.typography.bodyLarge, - fontWeight = FontWeight.Medium - ) - if (isSupport) { - Text( - text = stringResource(R.string.support_label), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurface - ) - } else { - val statusText = getUserStatusText(user, context) - Text( - text = statusText, - style = MaterialTheme.typography.bodySmall, - color = if (user.userStatus == UserStatusType.ONLINE) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - if (showCheckbox) { - Checkbox(checked = isSelected, onCheckedChange = { onClick() }) - } - } - } - - ContactActionsPopup( - expanded = showMenu && enableLongPress, - onDismiss = { showMenu = false }, - onOpenProfile = { - showMenu = false - onOpenProfile() - }, - onEditContact = { - showMenu = false - onEditContact() - }, - onRemoveContact = { - showMenu = false - onRemoveContact() - } - ) - } - if (position != ItemPosition.BOTTOM && position != ItemPosition.STANDALONE) { - Spacer(Modifier.height(2.dp)) - } -} - -@Composable -private fun ContactActionsPopup( - expanded: Boolean, - onDismiss: () -> Unit, - onOpenProfile: () -> Unit, - onEditContact: () -> Unit, - onRemoveContact: () -> Unit -) { - DropdownMenu( - expanded = expanded, - onDismissRequest = onDismiss, - offset = DpOffset(x = 0.dp, y = 8.dp), - shape = RoundedCornerShape(22.dp), - containerColor = Color.Transparent, - tonalElevation = 0.dp, - shadowElevation = 0.dp - ) { - Surface( - modifier = Modifier.widthIn(min = 220.dp, max = 260.dp), - shape = RoundedCornerShape(22.dp), - color = MaterialTheme.colorScheme.surfaceContainerHigh - ) { - Column(modifier = Modifier.padding(vertical = 8.dp)) { - DropdownMenuItem( - text = { Text(stringResource(R.string.contact_menu_open_profile)) }, - leadingIcon = { - Icon(Icons.Rounded.Person, contentDescription = null, tint = MaterialTheme.colorScheme.primary) - }, - onClick = onOpenProfile - ) - DropdownMenuItem( - text = { Text(stringResource(R.string.contact_menu_edit_name)) }, - leadingIcon = { - Icon(Icons.Rounded.Edit, contentDescription = null, tint = MaterialTheme.colorScheme.primary) - }, - onClick = onEditContact - ) - HorizontalDivider( - modifier = Modifier.padding(horizontal = 12.dp), - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - DropdownMenuItem( - text = { - Text( - text = stringResource(R.string.contact_menu_remove), - color = MaterialTheme.colorScheme.error - ) - }, - leadingIcon = { - Icon(Icons.Rounded.Delete, contentDescription = null, tint = MaterialTheme.colorScheme.error) - }, - onClick = onRemoveContact - ) - } - } - } -} - -@Composable -private fun ContactItemShimmer( - position: ItemPosition, - showCheckbox: Boolean -) { - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(40.dp) - .shimmerBackground(CircleShape) - ) - Spacer(modifier = Modifier.width(16.dp)) - Column(modifier = Modifier.weight(1f)) { - Box( - modifier = Modifier - .fillMaxWidth(0.45f) - .height(16.dp) - .shimmerBackground(RoundedCornerShape(6.dp)) - ) - Spacer(modifier = Modifier.height(6.dp)) - Box( - modifier = Modifier - .fillMaxWidth(0.3f) - .height(12.dp) - .shimmerBackground(RoundedCornerShape(6.dp)) - ) - } - - if (showCheckbox) { - Spacer(modifier = Modifier.width(8.dp)) - Box( - modifier = Modifier - .size(20.dp) - .shimmerBackground(CircleShape) - ) - } - } - } - - if (position != ItemPosition.BOTTOM && position != ItemPosition.STANDALONE) { - Spacer(Modifier.height(2.dp)) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/newChat/NewChatStore.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/newChat/NewChatStore.kt deleted file mode 100644 index cdbecc41..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/newChat/NewChatStore.kt +++ /dev/null @@ -1,31 +0,0 @@ -package org.monogram.presentation.features.chats.newChat - -import com.arkivanov.mvikotlin.core.store.Store - -interface NewChatStore : Store { - - sealed class Intent { - object Back : Intent() - data class UserClicked(val userId: Long) : Intent() - data class OpenProfile(val userId: Long) : Intent() - data class EditContact(val userId: Long, val firstName: String, val lastName: String) : Intent() - data class RemoveContact(val userId: Long) : Intent() - data class SearchQueryChange(val query: String) : Intent() - object CreateGroup : Intent() - object CreateChannel : Intent() - data class TitleChange(val title: String) : Intent() - data class DescriptionChange(val description: String) : Intent() - data class PhotoSelected(val path: String?) : Intent() - data class ToggleUserSelection(val userId: Long) : Intent() - data class AutoDeleteTimeChange(val seconds: Int) : Intent() - object ConfirmCreate : Intent() - object StepBack : Intent() - object ConsumeValidationError : Intent() - data class UpdateState(val state: NewChatComponent.State) : Intent() - } - - sealed class Label { - object Back : Label() - data class UserClicked(val userId: Long) : Label() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/chats/newChat/NewChatStoreFactory.kt b/presentation/src/main/java/org/monogram/presentation/features/chats/newChat/NewChatStoreFactory.kt deleted file mode 100644 index 7de0bdf4..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/chats/newChat/NewChatStoreFactory.kt +++ /dev/null @@ -1,57 +0,0 @@ -package org.monogram.presentation.features.chats.newChat - -import com.arkivanov.mvikotlin.core.store.Reducer -import com.arkivanov.mvikotlin.core.store.Store -import com.arkivanov.mvikotlin.core.store.StoreFactory -import com.arkivanov.mvikotlin.extensions.coroutines.CoroutineExecutor -import org.monogram.presentation.features.chats.newChat.NewChatStore.Intent -import org.monogram.presentation.features.chats.newChat.NewChatStore.Label - -class NewChatStoreFactory( - private val storeFactory: StoreFactory, - private val component: DefaultNewChatComponent -) { - - fun create(): NewChatStore = - object : NewChatStore, Store by storeFactory.create( - name = "NewChatStore", - initialState = NewChatComponent.State(), - executorFactory = ::ExecutorImpl, - reducer = ReducerImpl - ) {} - - private inner class ExecutorImpl : CoroutineExecutor() { - override fun executeIntent(intent: Intent) { - when (intent) { - Intent.Back -> component.handleBack() - is Intent.UserClicked -> component.handleUserClicked(intent.userId) - is Intent.OpenProfile -> component.handleOpenProfile(intent.userId) - is Intent.EditContact -> component.handleEditContact(intent.userId, intent.firstName, intent.lastName) - is Intent.RemoveContact -> component.handleRemoveContact(intent.userId) - is Intent.SearchQueryChange -> component.handleSearchQueryChange(intent.query) - Intent.CreateGroup -> component.handleCreateGroup() - Intent.CreateChannel -> component.handleCreateChannel() - is Intent.TitleChange -> component.handleTitleChange(intent.title) - is Intent.DescriptionChange -> component.handleDescriptionChange(intent.description) - is Intent.PhotoSelected -> component.handlePhotoSelected(intent.path) - is Intent.ToggleUserSelection -> component.handleToggleUserSelection(intent.userId) - is Intent.AutoDeleteTimeChange -> component.handleAutoDeleteTimeChange(intent.seconds) - Intent.ConfirmCreate -> component.handleConfirmCreate() - Intent.StepBack -> component.handleStepBack() - Intent.ConsumeValidationError -> component.handleConsumeValidationError() - is Intent.UpdateState -> dispatch(Message.UpdateState(intent.state)) - } - } - } - - private object ReducerImpl : Reducer { - override fun NewChatComponent.State.reduce(msg: Message): NewChatComponent.State = - when (msg) { - is Message.UpdateState -> msg.state - } - } - - sealed class Message { - data class UpdateState(val state: NewChatComponent.State) : Message() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/gallery/GalleryMediaQueries.kt b/presentation/src/main/java/org/monogram/presentation/features/gallery/GalleryMediaQueries.kt deleted file mode 100644 index 6c21143d..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/gallery/GalleryMediaQueries.kt +++ /dev/null @@ -1,99 +0,0 @@ -package org.monogram.presentation.features.gallery - -import android.content.ContentUris -import android.content.Context -import android.provider.MediaStore - -fun queryImages(context: Context): List { - val result = mutableListOf() - val projection = arrayOf( - MediaStore.Images.Media._ID, - MediaStore.Images.Media.DATE_ADDED, - MediaStore.Images.Media.BUCKET_DISPLAY_NAME, - MediaStore.Images.Media.RELATIVE_PATH - ) - context.contentResolver.query( - MediaStore.Images.Media.EXTERNAL_CONTENT_URI, - projection, - null, - null, - "${MediaStore.Images.Media.DATE_ADDED} DESC" - )?.use { cursor -> - val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID) - val dateColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_ADDED) - val bucketColumn = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME) - val relColumn = cursor.getColumnIndex(MediaStore.Images.Media.RELATIVE_PATH) - while (cursor.moveToNext()) { - val bucket = if (bucketColumn != -1) cursor.getString(bucketColumn).orEmpty() else "" - val relative = if (relColumn != -1) cursor.getString(relColumn).orEmpty() else "" - result.add( - GalleryMediaItem( - uri = ContentUris.withAppendedId( - MediaStore.Images.Media.EXTERNAL_CONTENT_URI, - cursor.getLong(idColumn) - ), - dateAdded = cursor.getLong(dateColumn), - isVideo = false, - bucketName = bucket, - relativePath = relative, - isCamera = isCameraBucket(bucket, relative), - isScreenshot = isScreenshotsBucket(bucket, relative) - ) - ) - } - } - return result -} - -fun queryVideos(context: Context): List { - val result = mutableListOf() - val projection = arrayOf( - MediaStore.Video.Media._ID, - MediaStore.Video.Media.DATE_ADDED, - MediaStore.Video.Media.BUCKET_DISPLAY_NAME, - MediaStore.Video.Media.RELATIVE_PATH - ) - context.contentResolver.query( - MediaStore.Video.Media.EXTERNAL_CONTENT_URI, - projection, - null, - null, - "${MediaStore.Video.Media.DATE_ADDED} DESC" - )?.use { cursor -> - val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID) - val dateColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATE_ADDED) - val bucketColumn = cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_DISPLAY_NAME) - val relColumn = cursor.getColumnIndex(MediaStore.Video.Media.RELATIVE_PATH) - while (cursor.moveToNext()) { - val bucket = if (bucketColumn != -1) cursor.getString(bucketColumn).orEmpty() else "" - val relative = if (relColumn != -1) cursor.getString(relColumn).orEmpty() else "" - result.add( - GalleryMediaItem( - uri = ContentUris.withAppendedId( - MediaStore.Video.Media.EXTERNAL_CONTENT_URI, - cursor.getLong(idColumn) - ), - dateAdded = cursor.getLong(dateColumn), - isVideo = true, - bucketName = bucket, - relativePath = relative, - isCamera = isCameraBucket(bucket, relative), - isScreenshot = isScreenshotsBucket(bucket, relative) - ) - ) - } - } - return result -} - -private fun isCameraBucket(bucket: String, relativePath: String): Boolean { - val b = bucket.lowercase() - val p = relativePath.lowercase() - return b.contains("camera") || p.contains("/camera") -} - -private fun isScreenshotsBucket(bucket: String, relativePath: String): Boolean { - val b = bucket.lowercase() - val p = relativePath.lowercase() - return b.contains("screenshot") || p.contains("screenshots") -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/gallery/GalleryModels.kt b/presentation/src/main/java/org/monogram/presentation/features/gallery/GalleryModels.kt deleted file mode 100644 index fff46821..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/gallery/GalleryModels.kt +++ /dev/null @@ -1,26 +0,0 @@ -package org.monogram.presentation.features.gallery - -import android.net.Uri - -enum class GalleryFilter(val title: String) { - All("All"), - Photos("Photos"), - Videos("Videos") -} - -sealed class BucketFilter(val key: String, val title: String) { - data object All : BucketFilter("all", "All folders") - data object Camera : BucketFilter("camera", "Camera") - data object Screenshots : BucketFilter("screenshots", "Screenshots") - data class Custom(val name: String) : BucketFilter("custom_$name", name) -} - -data class GalleryMediaItem( - val uri: Uri, - val dateAdded: Long, - val isVideo: Boolean, - val bucketName: String, - val relativePath: String, - val isCamera: Boolean, - val isScreenshot: Boolean -) \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/gallery/GalleryScreen.kt b/presentation/src/main/java/org/monogram/presentation/features/gallery/GalleryScreen.kt deleted file mode 100644 index 7844c9de..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/gallery/GalleryScreen.kt +++ /dev/null @@ -1,206 +0,0 @@ -package org.monogram.presentation.features.gallery - -import android.net.Uri -import androidx.compose.animation.* -import androidx.compose.animation.core.tween -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Surface -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.monogram.domain.models.AttachMenuBotModel -import org.monogram.presentation.features.gallery.components.* - -@Composable -fun GalleryScreen( - onMediaSelected: (List) -> Unit, - onDismiss: () -> Unit, - onCameraClick: () -> Unit, - attachBots: List, - hasMediaAccess: Boolean, - onPickFromOtherSources: () -> Unit, - onRequestMediaAccess: () -> Unit, - onAttachBotClick: (AttachMenuBotModel) -> Unit -) { - val context = LocalContext.current - val mediaList = remember { mutableStateListOf() } - val selectedMedia = remember { mutableStateListOf() } - var filter by remember { mutableStateOf(GalleryFilter.All) } - var bucketFilter by remember { mutableStateOf(BucketFilter.All) } - var isLoading by remember { mutableStateOf(false) } - - LaunchedEffect(hasMediaAccess) { - if (!hasMediaAccess) { - mediaList.clear() - selectedMedia.clear() - return@LaunchedEffect - } - isLoading = true - val loaded = withContext(Dispatchers.IO) { - val images = queryImages(context) - val videos = queryVideos(context) - (images + videos).sortedByDescending { it.dateAdded } - } - mediaList.clear() - mediaList.addAll(loaded) - isLoading = false - } - - val buckets by remember { derivedStateOf { buildBuckets(mediaList) } } - - LaunchedEffect(filter, buckets) { - if (filter != GalleryFilter.Photos) return@LaunchedEffect - if (bucketFilter !in buckets) { - bucketFilter = BucketFilter.All - } - } - - val filteredMedia = mediaList.filter { item -> - val byType = when (filter) { - GalleryFilter.All -> true - GalleryFilter.Photos -> !item.isVideo - GalleryFilter.Videos -> item.isVideo - } - val byBucket = if (filter == GalleryFilter.Photos) { - when (val selectedBucket = bucketFilter) { - BucketFilter.All -> true - BucketFilter.Camera -> item.isCamera - BucketFilter.Screenshots -> item.isScreenshot - is BucketFilter.Custom -> item.bucketName.equals(selectedBucket.name, ignoreCase = true) - } - } else { - true - } - byType && byBucket - } - - Scaffold( - topBar = { - GalleryTopBar( - onDismiss = onDismiss, - onPickFromOtherSources = onPickFromOtherSources, - onCameraClick = onCameraClick - ) - }, - containerColor = MaterialTheme.colorScheme.background, - bottomBar = { - AttachBotsSection( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp) - .windowInsetsPadding(WindowInsets.navigationBars), - bots = attachBots.filter { it.showInAttachMenu && it.name.isNotBlank() }, - selectedCount = selectedMedia.size, - onSendSelected = { onMediaSelected(selectedMedia.toList()) }, - onAttachBotClick = onAttachBotClick - ) - } - ) { padding -> - Column( - modifier = Modifier - .fillMaxSize() - .padding( - start = 16.dp, - end = 16.dp, - top = padding.calculateTopPadding(), - bottom = padding.calculateBottomPadding() - ) - ) { - AnimatedVisibility(visible = selectedMedia.isNotEmpty()) { - SelectedCountCard( - selectedCount = selectedMedia.size, - modifier = Modifier - .fillMaxWidth() - .padding(top = 4.dp, bottom = 10.dp) - ) - } - - if (!hasMediaAccess) { - SectionHeader("Permissions") - PermissionCard(onRequestMediaAccess) - return@Column - } - - SectionHeader("Media") - Surface( - modifier = Modifier - .fillMaxWidth() - .weight(1f), - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp) - ) { - Column(modifier = Modifier.fillMaxSize()) { - GalleryTabs( - filter = filter, - onFilterChange = { newFilter -> - filter = newFilter - } - ) - AnimatedVisibility( - visible = filter == GalleryFilter.Photos, - enter = fadeIn(tween(180)) + slideInVertically(tween(180)) { -it / 3 }, - exit = fadeOut(tween(140)) + slideOutVertically(tween(140)) { -it / 4 } - ) { - FolderRow( - buckets = buckets, - selectedBucket = bucketFilter, - onBucketChange = { bucketFilter = it } - ) - } - - val gridStateKey = remember(filter, bucketFilter) { - val bucketKey = when (val value = bucketFilter) { - BucketFilter.All -> value.key - BucketFilter.Camera -> value.key - BucketFilter.Screenshots -> value.key - is BucketFilter.Custom -> value.name.lowercase() - } - "${filter.name}_$bucketKey" - } - - AnimatedContent( - targetState = gridStateKey, - transitionSpec = { - fadeIn(tween(200)) togetherWith fadeOut(tween(130)) - }, - label = "galleryGridTransition", - modifier = Modifier.weight(1f) - ) { - GalleryGrid( - media = filteredMedia, - selected = selectedMedia, - isLoading = isLoading, - modifier = Modifier.fillMaxSize() - ) - } - } - } - } - } -} - -private fun buildBuckets(media: List): List { - val seen = mutableSetOf() - val customBuckets = media - .asSequence() - .map { it.bucketName.trim() } - .filter { it.isNotBlank() } - .filterNot { it.equals("Camera", ignoreCase = true) || it.equals("Screenshots", ignoreCase = true) } - .sortedBy { it.lowercase() } - .filter { seen.add(it.lowercase()) } - .map { BucketFilter.Custom(it) } - .toList() - - return buildList { - add(BucketFilter.All) - add(BucketFilter.Camera) - add(BucketFilter.Screenshots) - addAll(customBuckets) - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/gallery/components/AttachBotsSection.kt b/presentation/src/main/java/org/monogram/presentation/features/gallery/components/AttachBotsSection.kt deleted file mode 100644 index daaef172..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/gallery/components/AttachBotsSection.kt +++ /dev/null @@ -1,173 +0,0 @@ -package org.monogram.presentation.features.gallery.components - -import androidx.compose.animation.* -import androidx.compose.animation.core.tween -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.Send -import androidx.compose.material.icons.filled.Extension -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage -import org.monogram.domain.models.AttachMenuBotModel - -@Composable -fun AttachBotsSection( - modifier: Modifier = Modifier, - bots: List, - selectedCount: Int, - onSendSelected: () -> Unit, - onAttachBotClick: (AttachMenuBotModel) -> Unit -) { - if (bots.isEmpty() && selectedCount == 0) return - - Surface( - modifier = modifier, - shape = RoundedCornerShape(24.dp), - color = MaterialTheme.colorScheme.surfaceContainer - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .animateContentSize(animationSpec = tween(durationMillis = 220)) - .padding(horizontal = 10.dp, vertical = 8.dp), - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - AnimatedVisibility( - visible = selectedCount > 0, - enter = fadeIn(tween(180)) + slideInVertically(tween(180)) { it / 3 }, - exit = fadeOut(tween(130)) + slideOutVertically(tween(130)) { it / 4 } - ) { - SendSelectedButton( - selectedCount = selectedCount, - onSendSelected = onSendSelected - ) - } - - AnimatedVisibility( - visible = bots.isNotEmpty(), - enter = fadeIn(tween(220)) + slideInVertically(tween(220)) { it / 2 }, - exit = fadeOut(tween(140)) - ) { - LazyRow( - contentPadding = PaddingValues(bottom = 2.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - items(bots, key = { it.botUserId }) { bot -> - AttachBotTile( - bot = bot, - onClick = { onAttachBotClick(bot) } - ) - } - } - } - } - } -} - -@Composable -private fun SendSelectedButton( - selectedCount: Int, - onSendSelected: () -> Unit -) { - val suffix = if (selectedCount == 1) "" else "s" - Button( - onClick = onSendSelected, - modifier = Modifier - .fillMaxWidth() - .height(50.dp), - shape = RoundedCornerShape(14.dp), - colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.tertiary, - contentColor = MaterialTheme.colorScheme.onTertiary - ) - ) { - Icon( - imageVector = Icons.AutoMirrored.Filled.Send, - contentDescription = null, - modifier = Modifier.size(18.dp) - ) - Spacer(Modifier.size(8.dp)) - Text( - text = "Send $selectedCount item$suffix", - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.Bold - ) - } -} - -@Composable -private fun AttachBotTile( - bot: AttachMenuBotModel, - onClick: () -> Unit -) { - val colors = botTileColors(bot.name) - Row( - modifier = Modifier - .size(width = 118.dp, height = 58.dp) - .clip(RoundedCornerShape(16.dp)) - .background(colors.first) - .border(1.dp, colors.second.copy(alpha = 0.28f), RoundedCornerShape(16.dp)) - .clickable(onClick = onClick) - .padding(horizontal = 9.dp, vertical = 7.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - val iconPath = bot.icon?.icon?.local?.path - if (!iconPath.isNullOrBlank()) { - AsyncImage( - model = iconPath, - contentDescription = bot.name, - modifier = Modifier - .size(24.dp) - .clip(CircleShape), - contentScale = ContentScale.Crop - ) - } else { - Box( - modifier = Modifier - .size(24.dp) - .clip(CircleShape) - .background(colors.second.copy(alpha = 0.16f)), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Filled.Extension, - contentDescription = null, - tint = colors.second, - modifier = Modifier.size(14.dp) - ) - } - } - - Text( - text = bot.name, - style = MaterialTheme.typography.labelLarge, - color = colors.second, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } -} - -private fun botTileColors(seed: String): Pair { - val hue = ((seed.hashCode() and 0x7fffffff) % 360).toFloat() - val accent = Color.hsv(hue, 0.44f, 0.80f) - val background = accent.copy(alpha = 0.12f) - return background to accent -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/gallery/components/GalleryFilterComponents.kt b/presentation/src/main/java/org/monogram/presentation/features/gallery/components/GalleryFilterComponents.kt deleted file mode 100644 index bd8f9cc2..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/gallery/components/GalleryFilterComponents.kt +++ /dev/null @@ -1,125 +0,0 @@ -package org.monogram.presentation.features.gallery.components - -import androidx.compose.animation.animateColorAsState -import androidx.compose.animation.core.tween -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.selection.selectable -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Image -import androidx.compose.material.icons.filled.PermMedia -import androidx.compose.material.icons.filled.Videocam -import androidx.compose.material3.FilterChip -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.semantics.Role -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import org.monogram.presentation.features.gallery.BucketFilter -import org.monogram.presentation.features.gallery.GalleryFilter - -private data class GalleryTabSpec( - val filter: GalleryFilter, - val icon: ImageVector -) - -@Composable -fun GalleryTabs( - filter: GalleryFilter, - onFilterChange: (GalleryFilter) -> Unit -) { - val tabs = listOf( - GalleryTabSpec(GalleryFilter.All, Icons.Filled.PermMedia), - GalleryTabSpec(GalleryFilter.Photos, Icons.Filled.Image), - GalleryTabSpec(GalleryFilter.Videos, Icons.Filled.Videocam) - ) - - Row( - Modifier - .padding(horizontal = 12.dp, vertical = 10.dp) - .fillMaxWidth() - .height(48.dp) - .background( - MaterialTheme.colorScheme.surfaceContainerHigh, - CircleShape - ) - .padding(4.dp), - horizontalArrangement = Arrangement.SpaceBetween - ) { - tabs.forEach { tab -> - val selected = filter == tab.filter - val backgroundColor by animateColorAsState( - targetValue = if (selected) MaterialTheme.colorScheme.primary else Color.Transparent, - animationSpec = tween(durationMillis = 200), - label = "tabBackground" - ) - val contentColor by animateColorAsState( - targetValue = if (selected) MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurfaceVariant, - animationSpec = tween(durationMillis = 200), - label = "tabContent" - ) - - Box( - Modifier - .weight(1f) - .fillMaxSize() - .clip(CircleShape) - .background(backgroundColor) - .selectable( - selected = selected, - onClick = { onFilterChange(tab.filter) }, - role = Role.Tab - ), - contentAlignment = Alignment.Center - ) { - Row(verticalAlignment = Alignment.CenterVertically) { - Icon( - imageVector = tab.icon, - contentDescription = null, - modifier = Modifier.size(18.dp), - tint = contentColor - ) - Spacer(Modifier.size(8.dp)) - Text( - text = tab.filter.title, - style = MaterialTheme.typography.labelLarge, - color = contentColor, - fontWeight = if (selected) FontWeight.Bold else FontWeight.Medium - ) - } - } - } - } -} - -@Composable -fun FolderRow( - buckets: List, - selectedBucket: BucketFilter, - onBucketChange: (BucketFilter) -> Unit -) { - LazyRow( - contentPadding = PaddingValues(horizontal = 12.dp, vertical = 2.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - items(buckets, key = { it.key }) { bucket -> - FilterChip( - selected = bucket == selectedBucket, - onClick = { onBucketChange(bucket) }, - label = { Text(bucket.title, maxLines = 1, overflow = TextOverflow.Ellipsis) } - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/gallery/components/GalleryMediaGrid.kt b/presentation/src/main/java/org/monogram/presentation/features/gallery/components/GalleryMediaGrid.kt deleted file mode 100644 index 2111f014..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/gallery/components/GalleryMediaGrid.kt +++ /dev/null @@ -1,122 +0,0 @@ -package org.monogram.presentation.features.gallery.components - -import android.net.Uri -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.tween -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.lazy.grid.items -import androidx.compose.foundation.lazy.grid.itemsIndexed -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.CheckCircle -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.scale -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage -import org.monogram.presentation.features.gallery.GalleryMediaItem - -@Composable -fun GalleryGrid( - media: List, - selected: MutableList, - isLoading: Boolean, - modifier: Modifier = Modifier -) { - if (isLoading) { - Box(modifier = modifier.fillMaxWidth(), contentAlignment = Alignment.Center) { - CircularProgressIndicator() - } - return - } - - if (media.isEmpty()) { - Box(modifier = modifier.fillMaxWidth(), contentAlignment = Alignment.Center) { - Text("No media found", color = MaterialTheme.colorScheme.onSurfaceVariant) - } - return - } - - LazyVerticalGrid( - columns = GridCells.Fixed(3), - modifier = modifier - .fillMaxWidth() - .padding(horizontal = 8.dp), - horizontalArrangement = Arrangement.spacedBy(6.dp), - verticalArrangement = Arrangement.spacedBy(6.dp), - contentPadding = PaddingValues(bottom = 12.dp) - ) { - itemsIndexed(media, key = { index, item -> "gallery_${index}_${item.uri}" }) { _, item -> - val isSelected = selected.contains(item.uri) - val scale by animateFloatAsState( - targetValue = if (isSelected) 0.96f else 1f, - animationSpec = tween(120), - label = "mediaScale" - ) - - Box( - modifier = Modifier - .aspectRatio(1f) - .scale(scale) - .clip(RoundedCornerShape(14.dp)) - .clickable { - if (isSelected) selected.remove(item.uri) else selected.add(item.uri) - } - .border( - width = if (isSelected) 2.dp else 0.dp, - color = MaterialTheme.colorScheme.primary, - shape = RoundedCornerShape(14.dp) - ) - ) { - AsyncImage( - model = item.uri, - contentDescription = null, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Crop - ) - - if (item.isVideo) { - Surface( - modifier = Modifier - .align(Alignment.BottomEnd) - .padding(4.dp), - shape = RoundedCornerShape(8.dp), - color = MaterialTheme.colorScheme.surface.copy(alpha = 0.85f) - ) { - Text( - text = "VIDEO", - style = MaterialTheme.typography.labelSmall, - modifier = Modifier.padding(horizontal = 6.dp, vertical = 2.dp) - ) - } - } - - if (isSelected) { - Box( - modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.primary.copy(alpha = 0.35f)) - ) - Icon( - imageVector = Icons.Filled.CheckCircle, - contentDescription = null, - tint = MaterialTheme.colorScheme.onPrimary, - modifier = Modifier - .align(Alignment.TopEnd) - .padding(6.dp) - ) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/gallery/components/GalleryStatusComponents.kt b/presentation/src/main/java/org/monogram/presentation/features/gallery/components/GalleryStatusComponents.kt deleted file mode 100644 index 577a7453..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/gallery/components/GalleryStatusComponents.kt +++ /dev/null @@ -1,112 +0,0 @@ -package org.monogram.presentation.features.gallery.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.AddPhotoAlternate -import androidx.compose.material.icons.filled.CheckCircle -import androidx.compose.material.icons.filled.PermMedia -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp - -@Composable -fun SectionHeader(text: String) { - Text( - text = text, - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp, top = 16.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) -} - -@Composable -fun SelectedCountCard( - selectedCount: Int, - modifier: Modifier = Modifier -) { - val suffix = if (selectedCount == 1) "" else "s" - Surface( - modifier = modifier, - color = MaterialTheme.colorScheme.primaryContainer, - shape = RoundedCornerShape(18.dp) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 12.dp, vertical = 10.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(32.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primary), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Filled.CheckCircle, - contentDescription = null, - tint = MaterialTheme.colorScheme.onPrimary, - modifier = Modifier.size(18.dp) - ) - } - Spacer(Modifier.size(10.dp)) - Column(modifier = Modifier.fillMaxWidth()) { - Text( - text = "$selectedCount item$suffix selected", - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.onPrimaryContainer, - fontWeight = FontWeight.Bold - ) - Text( - text = "Ready to send", - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.78f) - ) - } - } - } -} - -@Composable -fun PermissionCard(onRequestMediaAccess: () -> Unit) { - Surface( - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(24.dp), - color = MaterialTheme.colorScheme.surfaceContainer - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(20.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(10.dp) - ) { - Icon( - imageVector = Icons.Filled.PermMedia, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.size(42.dp) - ) - Text("Allow Media Access", style = MaterialTheme.typography.titleMedium) - Text( - "Grant access to photos and videos to attach files in chat.", - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Button(onClick = onRequestMediaAccess) { - Icon(Icons.Filled.AddPhotoAlternate, contentDescription = null) - Spacer(Modifier.size(6.dp)) - Text("Grant access") - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/gallery/components/GalleryTopBar.kt b/presentation/src/main/java/org/monogram/presentation/features/gallery/components/GalleryTopBar.kt deleted file mode 100644 index 0e5bfa75..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/gallery/components/GalleryTopBar.kt +++ /dev/null @@ -1,44 +0,0 @@ -package org.monogram.presentation.features.gallery.components - -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.Extension -import androidx.compose.material.icons.filled.PhotoCamera -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.text.font.FontWeight - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun GalleryTopBar( - onDismiss: () -> Unit, - onPickFromOtherSources: () -> Unit, - onCameraClick: () -> Unit -) { - TopAppBar( - title = { - Text( - text = "Attachments", - style = MaterialTheme.typography.titleLarge, - fontWeight = FontWeight.Bold - ) - }, - navigationIcon = { - IconButton(onClick = onDismiss) { - Icon(Icons.Filled.Close, contentDescription = "Close") - } - }, - actions = { - IconButton(onClick = onPickFromOtherSources) { - Icon(Icons.Filled.Extension, contentDescription = "Other sources") - } - IconButton(onClick = onCameraClick) { - Icon(Icons.Filled.PhotoCamera, contentDescription = "Camera") - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background - ) - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/instantview/InstantViewer.kt b/presentation/src/main/java/org/monogram/presentation/features/instantview/InstantViewer.kt deleted file mode 100644 index e7a94510..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/instantview/InstantViewer.kt +++ /dev/null @@ -1,975 +0,0 @@ -package org.monogram.presentation.features.instantview - -import androidx.activity.compose.BackHandler -import androidx.compose.animation.* -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.spring -import androidx.compose.animation.core.tween -import androidx.compose.foundation.* -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.selection.SelectionContainer -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.automirrored.rounded.Chat -import androidx.compose.material.icons.automirrored.rounded.OpenInNew -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.TransformOrigin -import androidx.compose.ui.input.nestedscroll.nestedScroll -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalClipboardManager -import androidx.compose.ui.platform.LocalUriHandler -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.webapp.InstantViewModel -import org.monogram.domain.models.webapp.PageBlock -import org.monogram.domain.models.webapp.RichText -import org.monogram.domain.repository.MessageRepository -import org.monogram.presentation.R -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.chats.currentChat.components.chats.normalizeUrl -import org.monogram.presentation.features.instantview.components.* -import org.monogram.presentation.features.stickers.ui.menu.MenuOptionRow -import org.monogram.presentation.features.viewers.components.ViewerSettingsDropdown -import java.text.SimpleDateFormat -import java.util.* - -@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) -@Composable -fun InstantViewer( - url: String, - videoPlayerPool: VideoPlayerPool, - messageRepository: MessageRepository, - onDismiss: () -> Unit, - onOpenWebView: (String) -> Unit -) { - val urlStack = remember { mutableStateListOf(url) } - val currentUrl = urlStack.lastOrNull() ?: url - - var instantView by remember(currentUrl) { mutableStateOf(null) } - var isLoading by remember { mutableStateOf(true) } - var textSizeMultiplier by remember { mutableStateOf(1f) } - var isSearching by remember { mutableStateOf(false) } - var searchQuery by remember { mutableStateOf("") } - var showSettingsMenu by remember { mutableStateOf(false) } - - val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior() - LocalUriHandler.current - val clipboardManager = LocalClipboardManager.current - - LaunchedEffect(url) { - if (urlStack.isEmpty() || urlStack.first() != url) { - urlStack.clear() - urlStack.add(url) - } - } - - LaunchedEffect(currentUrl) { - isLoading = true - val result = messageRepository.getWebPageInstantView(currentUrl) - if (result == null) { - onOpenWebView(normalizeUrl(currentUrl)) - if (urlStack.size > 1) { - urlStack.removeAt(urlStack.size - 1) - } else { - onDismiss() - } - } else { - instantView = result - } - isLoading = false - } - - BackHandler(onBack = { - if (showSettingsMenu) { - showSettingsMenu = false - } else if (isSearching) { - isSearching = false - searchQuery = "" - } else if (urlStack.size > 1) { - urlStack.removeAt(urlStack.size - 1) - } else { - onDismiss() - } - }) - - CompositionLocalProvider( - LocalOnUrlClick provides { newUrl -> urlStack.add(newUrl) }, - LocalMessageRepository provides messageRepository - ) { - Box(modifier = Modifier.fillMaxSize()) { - Scaffold( - modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), - containerColor = MaterialTheme.colorScheme.surface, - contentColor = MaterialTheme.colorScheme.onSurface, - topBar = { - AnimatedContent( - targetState = isSearching, - transitionSpec = { - if (targetState) { - (fadeIn() + slideInVertically { -it / 4 }).togetherWith(fadeOut()) - } else { - fadeIn().togetherWith(fadeOut() + slideOutVertically { -it / 4 }) - } - }, - label = "TopBarSearchTransition" - ) { active -> - if (active) { - Box( - modifier = Modifier - .fillMaxWidth() - .statusBarsPadding() - .padding(horizontal = 16.dp, vertical = 8.dp) - ) { - SearchBar( - inputField = { - SearchBarDefaults.InputField( - query = searchQuery, - onQueryChange = { searchQuery = it }, - onSearch = {}, - expanded = false, - onExpandedChange = {}, - placeholder = { Text(stringResource(R.string.instant_view_search_placeholder)) }, - leadingIcon = { - IconButton(onClick = { isSearching = false; searchQuery = "" }) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.instant_view_back) - ) - } - }, - trailingIcon = { - if (searchQuery.isNotEmpty()) { - IconButton(onClick = { searchQuery = "" }) { - Icon(Icons.Rounded.Close, contentDescription = stringResource(R.string.instant_view_clear)) - } - } - } - ) - }, - expanded = false, - onExpandedChange = {}, - shape = RoundedCornerShape(24.dp), - colors = SearchBarDefaults.colors( - containerColor = MaterialTheme.colorScheme.surfaceContainerHigh, - dividerColor = Color.Transparent - ), - modifier = Modifier.fillMaxWidth() - ) {} - } - } else { - CenterAlignedTopAppBar( - title = { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier.padding(horizontal = 16.dp) - ) { - Text( - text = instantView?.pageBlocks?.filterIsInstance() - ?.firstOrNull()?.title?.let { renderRichText(it).text } - ?: stringResource(R.string.instant_view_title), - style = MaterialTheme.typography.titleMedium, - maxLines = 1, - modifier = Modifier.basicMarquee() - ) - val displayUrl = instantView?.url ?: currentUrl - Text( - text = displayUrl, - style = MaterialTheme.typography.bodySmall, - maxLines = 1, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.basicMarquee() - ) - } - }, - navigationIcon = { - IconButton(onClick = { - if (urlStack.size > 1) { - urlStack.removeAt(urlStack.size - 1) - } else { - onDismiss() - } - }) { - Icon(Icons.AutoMirrored.Rounded.ArrowBack, contentDescription = stringResource(R.string.instant_view_back)) - } - }, - actions = { - IconButton(onClick = { showSettingsMenu = !showSettingsMenu }) { - Icon(Icons.Rounded.MoreVert, contentDescription = stringResource(R.string.instant_view_more)) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.surface, - scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer - ), - scrollBehavior = scrollBehavior - ) - } - } - } - ) { padding -> - Box( - modifier = Modifier - .fillMaxSize() - .padding(padding) - ) { - if (isLoading) { - CircularProgressIndicator(modifier = Modifier.align(Alignment.Center)) - } else if (instantView != null) { - val blocks = remember(instantView, searchQuery) { - if (searchQuery.isEmpty()) { - instantView!!.pageBlocks - } else { - instantView!!.pageBlocks.filter { it.containsText(searchQuery) } - } - } - - SelectionContainer { - LazyColumn( - modifier = Modifier.fillMaxSize(), - contentPadding = PaddingValues(horizontal = 20.dp, vertical = 24.dp), - verticalArrangement = Arrangement.spacedBy(20.dp) - ) { - items(blocks) { block -> - InstantViewBlock(block, textSizeMultiplier, videoPlayerPool) - } - item { - Spacer(modifier = Modifier.height(48.dp)) - if (instantView!!.viewCount > 0) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.Center, - verticalAlignment = Alignment.CenterVertically - ) { - Icon( - Icons.Rounded.Visibility, - contentDescription = null, - modifier = Modifier.size(16.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.width(8.dp)) - Text( - text = stringResource(R.string.instant_view_views_count, instantView!!.viewCount), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - Spacer(modifier = Modifier.height(32.dp)) - } - } - } - } - } - } - - AnimatedVisibility( - visible = showSettingsMenu, - enter = fadeIn(tween(150)) + scaleIn( - animationSpec = spring(dampingRatio = 0.8f, stiffness = Spring.StiffnessMedium), - initialScale = 0.8f, - transformOrigin = TransformOrigin(1f, 0f) - ), - exit = fadeOut(tween(150)) + scaleOut( - animationSpec = tween(150), - targetScale = 0.9f, - transformOrigin = TransformOrigin(1f, 0f) - ), - modifier = Modifier - .fillMaxSize() - .windowInsetsPadding(WindowInsets.statusBars) - .padding(top = 56.dp, end = 16.dp) - ) { - Box( - modifier = Modifier - .fillMaxSize() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null - ) { showSettingsMenu = false }, - contentAlignment = Alignment.TopEnd - ) { - ViewerSettingsDropdown { - MenuOptionRow( - icon = Icons.Rounded.ContentCopy, - title = stringResource(R.string.instant_view_copy_link), - onClick = { - clipboardManager.setText(AnnotatedString(currentUrl)) - showSettingsMenu = false - } - ) - MenuOptionRow( - icon = Icons.AutoMirrored.Rounded.OpenInNew, - title = stringResource(R.string.instant_view_open_in_browser), - onClick = { - onOpenWebView(normalizeUrl(currentUrl)) - showSettingsMenu = false - } - ) - MenuOptionRow( - icon = Icons.Rounded.Search, - title = stringResource(R.string.instant_view_search), - onClick = { - isSearching = true - showSettingsMenu = false - } - ) - HorizontalDivider( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp), - color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f) - ) - MenuOptionRow( - icon = Icons.Rounded.TextFormat, - title = stringResource(R.string.instant_view_text_size), - value = "${(textSizeMultiplier * 100).toInt()}%", - onClick = { - textSizeMultiplier = when (textSizeMultiplier) { - 0.75f -> 1.0f - 1.0f -> 1.25f - 1.25f -> 1.5f - else -> 0.75f - } - } - ) - } - } - } - } - } -} - -@Composable -fun InstantViewBlock(block: PageBlock, textSizeMultiplier: Float, videoPlayerPool: VideoPlayerPool) { - val onUrlClick = LocalOnUrlClick.current - LocalUriHandler.current - when (block) { - is PageBlock.Title -> RichTextView( - richText = block.title, - style = MaterialTheme.typography.displaySmall, - textSizeMultiplier = textSizeMultiplier, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - - is PageBlock.Subtitle -> RichTextView( - richText = block.subtitle, - style = MaterialTheme.typography.headlineSmall, - textSizeMultiplier = textSizeMultiplier, - color = MaterialTheme.colorScheme.primary - ) - - is PageBlock.AuthorDate -> { - val dateStr = if (block.publishDate > 0) { - val date = Date(block.publishDate.toLong() * 1000) - SimpleDateFormat("MMM d, yyyy", Locale.getDefault()).format(date) - } else null - - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically - ) { - RichTextView( - richText = block.author, - style = MaterialTheme.typography.labelLarge, - textSizeMultiplier = textSizeMultiplier, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - - if (dateStr != null) { - Text( - text = " • ", - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Text( - text = dateStr, - style = MaterialTheme.typography.labelLarge.copy( - fontSize = MaterialTheme.typography.labelLarge.fontSize * textSizeMultiplier - ), - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } - - is PageBlock.Header -> RichTextView( - richText = block.header, - style = MaterialTheme.typography.titleLarge, - textSizeMultiplier = textSizeMultiplier, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(top = 16.dp), - color = MaterialTheme.colorScheme.onSurface - ) - - is PageBlock.Subheader -> RichTextView( - richText = block.subheader, - style = MaterialTheme.typography.titleMedium, - textSizeMultiplier = textSizeMultiplier, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(top = 8.dp), - color = MaterialTheme.colorScheme.onSurface - ) - - is PageBlock.Kicker -> RichTextView( - richText = block.kicker, - style = MaterialTheme.typography.labelLarge, - textSizeMultiplier = textSizeMultiplier, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) - - is PageBlock.Paragraph -> RichTextView( - richText = block.text, - style = MaterialTheme.typography.bodyLarge.copy(lineHeight = 32.sp), - textSizeMultiplier = textSizeMultiplier, - color = MaterialTheme.colorScheme.onSurface - ) - - is PageBlock.Preformatted -> Surface( - modifier = Modifier.fillMaxWidth(), - color = MaterialTheme.colorScheme.surfaceContainerHigh, - shape = RoundedCornerShape(8.dp) - ) { - RichTextView( - richText = block.text, - style = MaterialTheme.typography.bodyMedium.copy(fontFamily = FontFamily.Monospace), - textSizeMultiplier = textSizeMultiplier, - modifier = Modifier.padding(16.dp), - color = MaterialTheme.colorScheme.onSurface - ) - } - - is PageBlock.Footer -> RichTextView( - richText = block.footer, - style = MaterialTheme.typography.bodySmall, - textSizeMultiplier = textSizeMultiplier, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - - is PageBlock.Divider -> HorizontalDivider( - modifier = Modifier.padding(vertical = 16.dp), - color = MaterialTheme.colorScheme.outlineVariant - ) - - is PageBlock.PhotoBlock -> { - Column(modifier = Modifier.fillMaxWidth()) { - Box(modifier = Modifier.clip(RoundedCornerShape(12.dp))) { - AsyncImageWithDownload( - path = block.photo.path, - fileId = block.photo.fileId, - minithumbnail = block.photo.minithumbnail, - modifier = Modifier.fillMaxWidth(), - contentScale = ContentScale.FillWidth - ) - } - PageBlockCaptionView(block.caption, textSizeMultiplier, modifier = Modifier.padding(top = 8.dp)) - } - } - - is PageBlock.VideoBlock -> { - var isPlaying by remember { mutableStateOf(false) } - Column(modifier = Modifier.fillMaxWidth()) { - Box( - modifier = Modifier - .fillMaxWidth() - .aspectRatio(block.video.width.toFloat() / block.video.height.toFloat()) - .clip(RoundedCornerShape(12.dp)) - .background(MaterialTheme.colorScheme.surfaceVariant) - .clickable { isPlaying = true }, - contentAlignment = Alignment.Center - ) { - if (isPlaying) { - AsyncVideoWithDownload( - path = block.video.path, - fileId = block.video.fileId, - modifier = Modifier.fillMaxSize(), - shouldLoop = block.isLooped, - contentScale = ContentScale.FillWidth, - videoPlayerPool = videoPlayerPool - ) - } else { - Icon( - imageVector = Icons.Rounded.PlayArrow, - contentDescription = stringResource(R.string.instant_view_play_video), - modifier = Modifier - .size(64.dp) - .background(Color.Black.copy(alpha = 0.4f), CircleShape) - .padding(12.dp), - tint = Color.White - ) - } - } - PageBlockCaptionView(block.caption, textSizeMultiplier, modifier = Modifier.padding(top = 8.dp)) - } - } - - is PageBlock.AnimationBlock -> { - var isPlaying by remember { mutableStateOf(block.needAutoplay) } - Column(modifier = Modifier.fillMaxWidth()) { - Box( - modifier = Modifier - .fillMaxWidth() - .aspectRatio(block.animation.width.toFloat() / block.animation.height.toFloat()) - .clip(RoundedCornerShape(12.dp)) - .background(MaterialTheme.colorScheme.surfaceVariant) - .clickable { isPlaying = !isPlaying }, - contentAlignment = Alignment.Center - ) { - if (isPlaying) { - AsyncVideoWithDownload( - path = block.animation.path, - fileId = block.animation.fileId, - modifier = Modifier.fillMaxSize(), - shouldLoop = true, - contentScale = ContentScale.FillWidth, - videoPlayerPool = videoPlayerPool - ) - } else { - Icon( - imageVector = Icons.Rounded.PlayArrow, - contentDescription = stringResource(R.string.instant_view_play_animation), - modifier = Modifier - .size(48.dp) - .background(Color.Black.copy(alpha = 0.4f), CircleShape) - .padding(8.dp), - tint = Color.White - ) - } - } - PageBlockCaptionView(block.caption, textSizeMultiplier, modifier = Modifier.padding(top = 8.dp)) - } - } - - is PageBlock.AudioBlock -> { - Surface( - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(12.dp), - color = MaterialTheme.colorScheme.surfaceContainer, - tonalElevation = 2.dp - ) { - Column { - ListItem( - headlineContent = { - Text(block.audio.title ?: stringResource(R.string.instant_view_audio), fontWeight = FontWeight.SemiBold) - }, - supportingContent = { - Text(block.audio.performer ?: stringResource(R.string.instant_view_unknown_artist)) - }, - leadingContent = { - IconButton( - onClick = { /* TODO: Play audio */ }, - colors = IconButtonDefaults.filledIconButtonColors( - containerColor = MaterialTheme.colorScheme.primaryContainer, - contentColor = MaterialTheme.colorScheme.onPrimaryContainer - ) - ) { - Icon(Icons.Rounded.PlayArrow, contentDescription = stringResource(R.string.instant_view_play)) - } - }, - trailingContent = { - val duration = block.audio.duration - Text( - "${duration / 60}:${(duration % 60).toString().padStart(2, '0')}", - style = MaterialTheme.typography.labelMedium - ) - }, - colors = ListItemDefaults.colors(containerColor = Color.Transparent) - ) - PageBlockCaptionView( - block.caption, - textSizeMultiplier, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) - ) - } - } - } - - is PageBlock.Embedded -> { - Column(modifier = Modifier.fillMaxWidth()) { - Box( - modifier = Modifier - .fillMaxWidth() - .aspectRatio(if (block.width > 0 && block.height > 0) block.width.toFloat() / block.height.toFloat() else 16f / 9f) - .clip(RoundedCornerShape(12.dp)) - .background(MaterialTheme.colorScheme.surfaceVariant) - .clickable { onUrlClick(normalizeUrl(block.url)) }, - contentAlignment = Alignment.Center - ) { - block.posterPhoto?.let { photo -> - AsyncImageWithDownload( - path = photo.path, - fileId = photo.fileId, - minithumbnail = photo.minithumbnail, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Crop - ) - } - Icon( - imageVector = Icons.AutoMirrored.Rounded.OpenInNew, - contentDescription = stringResource(R.string.instant_view_open), - modifier = Modifier - .size(48.dp) - .background(Color.Black.copy(alpha = 0.4f), CircleShape) - .padding(8.dp), - tint = Color.White - ) - } - PageBlockCaptionView(block.caption, textSizeMultiplier, modifier = Modifier.padding(top = 8.dp)) - } - } - - is PageBlock.EmbeddedPost -> { - Card( - modifier = Modifier.fillMaxWidth(), - colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceContainerLow), - border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant) - ) { - Column(modifier = Modifier.padding(16.dp)) { - Row(verticalAlignment = Alignment.CenterVertically) { - block.authorPhoto?.let { photo -> - AsyncImageWithDownload( - path = photo.path, - fileId = photo.fileId, - minithumbnail = photo.minithumbnail, - modifier = Modifier - .size(40.dp) - .clip(CircleShape), - contentScale = ContentScale.Crop - ) - Spacer(modifier = Modifier.width(12.dp)) - } - Column { - Text( - text = block.author, - style = MaterialTheme.typography.titleSmall, - fontWeight = FontWeight.Bold - ) - if (block.date > 0) { - val date = Date(block.date.toLong() * 1000) - val dateStr = SimpleDateFormat("MMM d, yyyy", Locale.getDefault()).format(date) - Text( - text = dateStr, - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } - Spacer(modifier = Modifier.height(12.dp)) - block.pageBlocks.forEach { innerBlock -> - InstantViewBlock(innerBlock, textSizeMultiplier, videoPlayerPool) - } - PageBlockCaptionView(block.caption, textSizeMultiplier, modifier = Modifier.padding(top = 12.dp)) - } - } - } - - is PageBlock.BlockQuote -> { - Row(modifier = Modifier - .fillMaxWidth() - .height(IntrinsicSize.Min)) { - Box( - modifier = Modifier - .width(4.dp) - .fillMaxHeight() - .background(MaterialTheme.colorScheme.primary, RoundedCornerShape(2.dp)) - ) - Spacer(modifier = Modifier.width(16.dp)) - Column { - RichTextView( - richText = block.text, - style = MaterialTheme.typography.bodyLarge, - textSizeMultiplier = textSizeMultiplier, - fontStyle = FontStyle.Italic, - color = MaterialTheme.colorScheme.onSurface - ) - if (block.credit !is RichText.Plain || (block.credit as RichText.Plain).text.isNotEmpty()) { - RichTextView( - richText = block.credit, - style = MaterialTheme.typography.labelMedium, - textSizeMultiplier = textSizeMultiplier, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(top = 8.dp) - ) - } - } - } - } - - is PageBlock.PullQuote -> { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - RichTextView( - richText = block.text, - style = MaterialTheme.typography.headlineSmall, - textSizeMultiplier = textSizeMultiplier, - fontStyle = FontStyle.Italic, - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.onSurface - ) - if (block.credit !is RichText.Plain || (block.credit as RichText.Plain).text.isNotEmpty()) { - RichTextView( - richText = block.credit, - style = MaterialTheme.typography.labelMedium, - textSizeMultiplier = textSizeMultiplier, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(top = 12.dp) - ) - } - } - } - - is PageBlock.ListBlock -> Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { - block.items.forEach { item -> - Row(verticalAlignment = Alignment.Top) { - Text( - text = if (item.label.isNotEmpty()) "${item.label} " else "• ", - style = MaterialTheme.typography.bodyLarge.copy( - fontSize = MaterialTheme.typography.bodyLarge.fontSize * textSizeMultiplier - ), - modifier = Modifier.padding(end = 8.dp), - color = MaterialTheme.colorScheme.primary - ) - Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { - item.pageBlocks.forEach { innerBlock -> - InstantViewBlock(innerBlock, textSizeMultiplier, videoPlayerPool) - } - } - } - } - } - - is PageBlock.Cover -> InstantViewBlock(block.cover, textSizeMultiplier, videoPlayerPool) - is PageBlock.Details -> { - var isOpen by remember { mutableStateOf(block.isOpen) } - Surface( - modifier = Modifier.animateContentSize(animationSpec = spring(stiffness = Spring.StiffnessLow)), - shape = RoundedCornerShape(12.dp), - color = MaterialTheme.colorScheme.surfaceContainer, - tonalElevation = 1.dp - ) { - Column { - Row( - modifier = Modifier - .fillMaxWidth() - .clickable { isOpen = !isOpen } - .padding(16.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Box(modifier = Modifier.weight(1f)) { - RichTextView( - richText = block.header, - style = MaterialTheme.typography.titleMedium, - textSizeMultiplier = textSizeMultiplier, - fontWeight = FontWeight.SemiBold - ) - } - Icon( - imageVector = if (isOpen) Icons.Rounded.ExpandLess else Icons.Rounded.ExpandMore, - contentDescription = if (isOpen) stringResource(R.string.instant_view_collapse) else stringResource(R.string.instant_view_expand), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - if (isOpen) { - HorizontalDivider(color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f)) - Column( - modifier = Modifier.padding(16.dp), - verticalArrangement = Arrangement.spacedBy(12.dp) - ) { - block.pageBlocks.forEach { innerBlock -> - InstantViewBlock(innerBlock, textSizeMultiplier, videoPlayerPool) - } - } - } - } - } - } - - is PageBlock.Collage -> { - Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { - block.pageBlocks.forEach { innerBlock -> - InstantViewBlock(innerBlock, textSizeMultiplier, videoPlayerPool) - } - PageBlockCaptionView(block.caption, textSizeMultiplier) - } - } - - is PageBlock.Slideshow -> { - Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { - block.pageBlocks.forEach { innerBlock -> - InstantViewBlock(innerBlock, textSizeMultiplier, videoPlayerPool) - } - PageBlockCaptionView(block.caption, textSizeMultiplier) - } - } - - is PageBlock.Table -> { - Card( - colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceContainer), - shape = RoundedCornerShape(12.dp) - ) { - Column(modifier = Modifier.padding(16.dp)) { - if (block.caption !is RichText.Plain || (block.caption as RichText.Plain).text.isNotEmpty()) { - RichTextView( - richText = block.caption, - style = MaterialTheme.typography.titleSmall, - textSizeMultiplier = textSizeMultiplier, - modifier = Modifier.padding(bottom = 12.dp), - color = MaterialTheme.colorScheme.onSurface - ) - } - block.cells.forEachIndexed { index, row -> - Row(modifier = Modifier.fillMaxWidth()) { - row.forEach { cell -> - Box( - modifier = Modifier - .weight(cell.colspan.toFloat()) - .border( - width = if (block.isBordered) 1.dp else 0.dp, - color = MaterialTheme.colorScheme.outlineVariant - ) - .background( - if (cell.isHeader) MaterialTheme.colorScheme.surfaceContainerHigh else Color.Transparent - ) - .padding(8.dp) - ) { - RichTextView( - richText = cell.text, - style = if (cell.isHeader) MaterialTheme.typography.labelLarge else MaterialTheme.typography.bodyMedium, - textSizeMultiplier = textSizeMultiplier, - fontWeight = if (cell.isHeader) FontWeight.Bold else FontWeight.Normal, - color = MaterialTheme.colorScheme.onSurface - ) - } - } - } - if (index < block.cells.size - 1 && !block.isBordered) { - HorizontalDivider(color = MaterialTheme.colorScheme.outlineVariant) - } - } - } - } - } - - is PageBlock.RelatedArticles -> { - Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { - RichTextView( - richText = block.header, - style = MaterialTheme.typography.titleMedium, - textSizeMultiplier = textSizeMultiplier, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - block.articles.forEach { article -> - Card( - onClick = { onUrlClick(normalizeUrl(article.url)) }, - modifier = Modifier.fillMaxWidth(), - colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceContainerLow), - border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant) - ) { - ListItem( - headlineContent = { - Text( - text = article.title, - style = MaterialTheme.typography.titleSmall.copy( - fontSize = MaterialTheme.typography.titleSmall.fontSize * textSizeMultiplier - ), - maxLines = 2, - fontWeight = FontWeight.SemiBold - ) - }, - supportingContent = if (article.description.isNotEmpty()) { - { - Text( - text = article.description, - style = MaterialTheme.typography.bodySmall.copy( - fontSize = MaterialTheme.typography.bodySmall.fontSize * textSizeMultiplier - ), - maxLines = 2, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } else null, - leadingContent = article.photo?.let { photo -> - { - AsyncImageWithDownload( - path = photo.path, - fileId = photo.fileId, - minithumbnail = photo.minithumbnail, - modifier = Modifier - .size(64.dp) - .clip(RoundedCornerShape(8.dp)), - contentScale = ContentScale.Crop - ) - } - }, - colors = ListItemDefaults.colors(containerColor = Color.Transparent) - ) - } - } - } - } - - is PageBlock.MapBlock -> { - Column(modifier = Modifier.fillMaxWidth()) { - Box( - modifier = Modifier - .fillMaxWidth() - .height(200.dp) - .clip(RoundedCornerShape(12.dp)) - .background(MaterialTheme.colorScheme.surfaceVariant), - contentAlignment = Alignment.Center - ) { - Text(stringResource(R.string.instant_view_map_prefix, block.location.latitude, block.location.longitude)) - } - PageBlockCaptionView(block.caption, textSizeMultiplier, modifier = Modifier.padding(top = 8.dp)) - } - } - - is PageBlock.Anchor -> { /* Invisible anchor */ - } - - is PageBlock.ChatLink -> { - FilledTonalButton( - onClick = { onUrlClick("https://t.me/${block.username}") }, - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(12.dp), - contentPadding = PaddingValues(16.dp) - ) { - Icon( - imageVector = Icons.AutoMirrored.Rounded.Chat, - contentDescription = null, - modifier = Modifier.size(20.dp) - ) - Spacer(modifier = Modifier.width(12.dp)) - Text( - text = block.title, - style = MaterialTheme.typography.labelLarge, - fontWeight = FontWeight.Bold - ) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/instantview/components/InstantViewComponents.kt b/presentation/src/main/java/org/monogram/presentation/features/instantview/components/InstantViewComponents.kt deleted file mode 100644 index 0fef6671..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/instantview/components/InstantViewComponents.kt +++ /dev/null @@ -1,257 +0,0 @@ -package org.monogram.presentation.features.instantview.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.text.ClickableText -import androidx.compose.material3.CircularProgressIndicator -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.blur -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.takeOrElse -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.isUnspecified -import coil3.compose.AsyncImage -import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.flow.mapNotNull -import kotlinx.coroutines.launch -import kotlinx.coroutines.withTimeoutOrNull -import org.monogram.domain.models.webapp.PageBlockCaption -import org.monogram.domain.models.webapp.RichText -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.chats.currentChat.components.VideoStickerPlayer -import org.monogram.presentation.features.chats.currentChat.components.VideoType -import org.monogram.presentation.features.chats.currentChat.components.chats.normalizeUrl -import org.monogram.presentation.features.stickers.ui.view.shimmerEffect - -@Composable -fun RichTextView( - richText: RichText, - style: TextStyle, - textSizeMultiplier: Float, - modifier: Modifier = Modifier, - fontWeight: FontWeight? = null, - fontStyle: FontStyle? = null, - color: Color = Color.Unspecified, - textAlign: TextAlign? = null, - maxLines: Int = Int.MAX_VALUE -) { - val onUrlClick = LocalOnUrlClick.current - val linkColor = MaterialTheme.colorScheme.primary - val annotatedString = renderRichText(richText, linkColor) - - val scaledStyle = style.copy( - fontSize = style.fontSize * textSizeMultiplier, - lineHeight = if (!style.lineHeight.isUnspecified) style.lineHeight * textSizeMultiplier else style.lineHeight, - color = color.takeOrElse { style.color.takeOrElse { MaterialTheme.colorScheme.onSurface } }, - textAlign = textAlign ?: TextAlign.Unspecified, - fontWeight = fontWeight ?: style.fontWeight, - fontStyle = fontStyle ?: style.fontStyle - ) - - ClickableText( - text = annotatedString, - style = scaledStyle, - modifier = modifier, - maxLines = maxLines, - onClick = { offset -> - annotatedString.getStringAnnotations(tag = "URL", start = offset, end = offset) - .firstOrNull()?.let { annotation -> - val url = normalizeUrl(annotation.item) - onUrlClick(url) - } - } - ) -} - -@Composable -fun AsyncImageWithDownload( - path: String?, - fileId: Int, - minithumbnail: ByteArray? = null, - modifier: Modifier = Modifier, - contentScale: ContentScale = ContentScale.Fit -) { - val messageRepository = LocalMessageRepository.current - var currentPath by remember(fileId) { mutableStateOf(path) } - var progress by remember { mutableStateOf(0f) } - - LaunchedEffect(path, fileId) { - if (!path.isNullOrEmpty()) { - currentPath = path - } - if (currentPath == null) { - messageRepository.downloadFile(fileId) - - val progressJob = launch { - messageRepository.messageDownloadProgressFlow - .filter { it.first == fileId.toLong() } - .collect { progress = it.second } - } - - val completedPath = withTimeoutOrNull(60_000L) { - messageRepository.messageDownloadCompletedFlow - .filter { it.first == fileId.toLong() } - .mapNotNull { (_, _, candidatePath) -> candidatePath.takeIf { it.isNotEmpty() } } - .first() - } - - currentPath = completedPath ?: messageRepository.getFilePath(fileId) - progressJob.cancel() - } - } - - Box(modifier = modifier, contentAlignment = Alignment.Center) { - if (currentPath != null) { - AsyncImage( - model = currentPath, - contentDescription = null, - modifier = Modifier.fillMaxSize(), - contentScale = contentScale - ) - } else { - if (minithumbnail != null) { - AsyncImage( - model = minithumbnail, - contentDescription = null, - modifier = Modifier - .fillMaxSize() - .blur(10.dp), - contentScale = contentScale, - alpha = 0.5f - ) - } else { - Box( - modifier = Modifier - .fillMaxSize() - .shimmerEffect() - ) - } - - if (progress > 0f && progress < 1f) { - CircularProgressIndicator( - progress = { progress }, - modifier = Modifier.size(32.dp), - strokeWidth = 2.dp, - color = MaterialTheme.colorScheme.primary - ) - } else { - CircularProgressIndicator( - modifier = Modifier.size(24.dp), - strokeWidth = 2.dp, - color = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f) - ) - } - } - } -} - -@Composable -fun AsyncVideoWithDownload( - path: String?, - videoPlayerPool: VideoPlayerPool, - fileId: Int, - modifier: Modifier = Modifier, - shouldLoop: Boolean = true, - contentScale: ContentScale = ContentScale.Fit -) { - val messageRepository = LocalMessageRepository.current - var currentPath by remember(fileId) { mutableStateOf(path) } - var progress by remember { mutableStateOf(0f) } - - LaunchedEffect(path, fileId) { - if (!path.isNullOrEmpty()) { - currentPath = path - } - if (currentPath == null) { - messageRepository.downloadFile(fileId) - - val progressJob = launch { - messageRepository.messageDownloadProgressFlow - .filter { it.first == fileId.toLong() } - .collect { progress = it.second } - } - - val completedPath = withTimeoutOrNull(60_000L) { - messageRepository.messageDownloadCompletedFlow - .filter { it.first == fileId.toLong() } - .mapNotNull { (_, _, candidatePath) -> candidatePath.takeIf { it.isNotEmpty() } } - .first() - } - - currentPath = completedPath ?: messageRepository.getFilePath(fileId) - progressJob.cancel() - } - } - - if (currentPath != null) { - VideoStickerPlayer( - path = currentPath!!, - type = VideoType.Gif, - modifier = modifier, - animate = true, - shouldLoop = shouldLoop, - contentScale = contentScale, - videoPlayerPool = videoPlayerPool - ) - } else { - Box( - modifier = modifier - .background(MaterialTheme.colorScheme.surfaceVariant) - .shimmerEffect(), - contentAlignment = Alignment.Center - ) { - if (progress > 0f && progress < 1f) { - CircularProgressIndicator( - progress = { progress }, - modifier = Modifier.size(32.dp), - strokeWidth = 2.dp, - color = MaterialTheme.colorScheme.primary - ) - } else { - CircularProgressIndicator( - modifier = Modifier.size(24.dp), - strokeWidth = 2.dp, - color = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f) - ) - } - } - } -} - -@Composable -fun PageBlockCaptionView(caption: PageBlockCaption, textSizeMultiplier: Float, modifier: Modifier = Modifier) { - val hasText = caption.text !is RichText.Plain || (caption.text as RichText.Plain).text.isNotEmpty() - val hasCredit = caption.credit !is RichText.Plain || (caption.credit as RichText.Plain).text.isNotEmpty() - - if (hasText || hasCredit) { - Column(modifier = modifier) { - if (hasText) { - RichTextView( - richText = caption.text, - style = MaterialTheme.typography.bodySmall, - textSizeMultiplier = textSizeMultiplier, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - if (hasCredit) { - RichTextView( - richText = caption.credit, - style = MaterialTheme.typography.labelSmall, - textSizeMultiplier = textSizeMultiplier, - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f), - fontStyle = FontStyle.Italic, - modifier = Modifier.padding(top = 4.dp) - ) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/instantview/components/InstantViewUtils.kt b/presentation/src/main/java/org/monogram/presentation/features/instantview/components/InstantViewUtils.kt deleted file mode 100644 index 039e0c1b..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/instantview/components/InstantViewUtils.kt +++ /dev/null @@ -1,215 +0,0 @@ -package org.monogram.presentation.features.instantview.components - -import androidx.compose.runtime.staticCompositionLocalOf -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.BaselineShift -import androidx.compose.ui.text.style.TextDecoration -import androidx.compose.ui.text.withStyle -import org.monogram.domain.models.webapp.PageBlock -import org.monogram.domain.models.webapp.RichText -import org.monogram.domain.repository.MessageRepository -import java.text.SimpleDateFormat -import java.util.* - -val LocalOnUrlClick = staticCompositionLocalOf<(String) -> Unit> { { } } -val LocalMessageRepository = - staticCompositionLocalOf { error("No MessageRepository provided") } - -fun renderRichText(richText: RichText, linkColor: Color = Color(0xFF2196F3)): AnnotatedString { - return buildAnnotatedString { - appendRichText(richText, linkColor) - } -} - -fun AnnotatedString.Builder.appendRichText(richText: RichText, linkColor: Color) { - when (richText) { - is RichText.Plain -> append(richText.text) - is RichText.Bold -> withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { - appendRichText(richText.text, linkColor) - } - - is RichText.Italic -> withStyle(SpanStyle(fontStyle = FontStyle.Italic)) { - appendRichText(richText.text, linkColor) - } - - is RichText.Underline -> withStyle(SpanStyle(textDecoration = TextDecoration.Underline)) { - appendRichText(richText.text, linkColor) - } - - is RichText.Strikethrough -> withStyle(SpanStyle(textDecoration = TextDecoration.LineThrough)) { - appendRichText(richText.text, linkColor) - } - - is RichText.Fixed -> withStyle(SpanStyle(fontFamily = FontFamily.Monospace)) { - appendRichText(richText.text, linkColor) - } - - is RichText.Url -> { - pushStringAnnotation(tag = "URL", annotation = richText.url) - withStyle(SpanStyle(color = linkColor, textDecoration = TextDecoration.Underline)) { - appendRichText(richText.text, linkColor) - } - pop() - } - - is RichText.Texts -> { - richText.texts.forEach { appendRichText(it, linkColor) } - } - - is RichText.Anchor -> { - // Anchor is a position marker, usually invisible in text flow - } - - is RichText.AnchorLink -> { - pushStringAnnotation(tag = "ANCHOR", annotation = richText.anchorName) - withStyle(SpanStyle(color = linkColor, textDecoration = TextDecoration.Underline)) { - appendRichText(richText.text, linkColor) - } - pop() - } - - is RichText.EmailAddress -> { - pushStringAnnotation(tag = "EMAIL", annotation = richText.emailAddress) - withStyle(SpanStyle(color = linkColor, textDecoration = TextDecoration.Underline)) { - appendRichText(richText.text, linkColor) - } - pop() - } - - is RichText.Icon -> { - // Icon is a position marker, usually invisible in text flow - } - - is RichText.Marked -> withStyle(SpanStyle(background = Color(0x55FFFF00))) { - appendRichText(richText.text, linkColor) - } - - is RichText.PhoneNumber -> { - pushStringAnnotation(tag = "PHONE", annotation = richText.phoneNumber) - withStyle(SpanStyle(color = linkColor, textDecoration = TextDecoration.Underline)) { - appendRichText(richText.text, linkColor) - } - pop() - } - - is RichText.Reference -> { - pushStringAnnotation(tag = "URL", annotation = richText.url) - withStyle(SpanStyle(color = linkColor, textDecoration = TextDecoration.Underline)) { - appendRichText(richText.text, linkColor) - } - pop() - } - - is RichText.Subscript -> withStyle(SpanStyle(baselineShift = BaselineShift.Subscript)) { - appendRichText(richText.text, linkColor) - } - - is RichText.Superscript -> withStyle(SpanStyle(baselineShift = BaselineShift.Superscript)) { - appendRichText(richText.text, linkColor) - } - } -} - -fun PageBlock.containsText(query: String): Boolean { - return when (this) { - is PageBlock.Title -> title.containsText(query) - is PageBlock.Subtitle -> subtitle.containsText(query) - is PageBlock.AuthorDate -> author.containsText(query) || (publishDate > 0 && SimpleDateFormat( - "MMM d, yyyy", - Locale.getDefault() - ).format(Date(publishDate.toLong() * 1000)).contains(query, ignoreCase = true)) - - is PageBlock.Header -> header.containsText(query) - is PageBlock.Subheader -> subheader.containsText(query) - is PageBlock.Kicker -> kicker.containsText(query) - is PageBlock.Paragraph -> text.containsText(query) - is PageBlock.Preformatted -> text.containsText(query) - is PageBlock.Footer -> footer.containsText(query) - is PageBlock.BlockQuote -> text.containsText(query) || credit.containsText(query) - is PageBlock.PullQuote -> text.containsText(query) || credit.containsText(query) - is PageBlock.ListBlock -> items.any { item -> - item.label.contains( - query, - ignoreCase = true - ) || item.pageBlocks.any { it.containsText(query) } - } - - is PageBlock.Details -> header.containsText(query) || pageBlocks.any { it.containsText(query) } - is PageBlock.Table -> caption.containsText(query) || cells.any { row -> row.any { it.text.containsText(query) } } - is PageBlock.RelatedArticles -> header.containsText(query) || articles.any { - it.title.contains( - query, - ignoreCase = true - ) || it.description.contains(query, ignoreCase = true) - } - - is PageBlock.PhotoBlock -> caption.text.containsText(query) || caption.credit.containsText(query) - is PageBlock.VideoBlock -> caption.text.containsText(query) || caption.credit.containsText(query) - is PageBlock.AnimationBlock -> caption.text.containsText(query) || caption.credit.containsText(query) - is PageBlock.Collage -> caption.text.containsText(query) || caption.credit.containsText(query) || pageBlocks.any { - it.containsText( - query - ) - } - - is PageBlock.Slideshow -> caption.text.containsText(query) || caption.credit.containsText(query) || pageBlocks.any { - it.containsText( - query - ) - } - - is PageBlock.ChatLink -> title.contains(query, ignoreCase = true) - - is PageBlock.Anchor -> name.contains(query, ignoreCase = true) - is PageBlock.AudioBlock -> caption.text.containsText(query) || caption.credit.containsText(query) - is PageBlock.Cover -> cover.containsText(query) - PageBlock.Divider -> false - is PageBlock.Embedded -> caption.text.containsText(query) || caption.credit.containsText(query) || url.contains( - query, - ignoreCase = true - ) || html.contains(query, ignoreCase = true) - - is PageBlock.EmbeddedPost -> caption.text.containsText(query) || caption.credit.containsText(query) || author.contains( - query, - ignoreCase = true - ) || pageBlocks.any { it.containsText(query) } - - is PageBlock.MapBlock -> caption.text.containsText(query) || caption.credit.containsText(query) - } -} - -fun RichText.containsText(query: String): Boolean { - return when (this) { - is RichText.Plain -> text.contains(query, ignoreCase = true) - is RichText.Bold -> text.containsText(query) - is RichText.Italic -> text.containsText(query) - is RichText.Underline -> text.containsText(query) - is RichText.Strikethrough -> text.containsText(query) - is RichText.Fixed -> text.containsText(query) - is RichText.Url -> text.containsText(query) || url.contains(query, ignoreCase = true) - is RichText.Texts -> texts.any { it.containsText(query) } - is RichText.Anchor -> name.contains(query, ignoreCase = true) - is RichText.AnchorLink -> text.containsText(query) || anchorName.contains( - query, - ignoreCase = true - ) || url.contains(query, ignoreCase = true) - - is RichText.EmailAddress -> text.containsText(query) || emailAddress.contains(query, ignoreCase = true) - is RichText.Icon -> false - is RichText.Marked -> text.containsText(query) - is RichText.PhoneNumber -> text.containsText(query) || phoneNumber.contains(query, ignoreCase = true) - is RichText.Reference -> text.containsText(query) || anchorName.contains( - query, - ignoreCase = true - ) || url.contains(query, ignoreCase = true) - - is RichText.Subscript -> text.containsText(query) - is RichText.Superscript -> text.containsText(query) - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/DefaultProfileComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/DefaultProfileComponent.kt deleted file mode 100644 index c422f5bf..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/DefaultProfileComponent.kt +++ /dev/null @@ -1,1138 +0,0 @@ -package org.monogram.presentation.features.profile - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.* -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import org.monogram.domain.models.* -import org.monogram.domain.repository.* -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.core.util.coRunCatching -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.root.AppComponentContext - -class DefaultProfileComponent( - context: AppComponentContext, - private val chatId: Long, - private val onBackClicked: () -> Unit, - private val onMessageClicked: (MessageModel) -> Unit = {}, - private val onMessageLongClicked: (MessageModel) -> Unit = {}, - private val onAvatarClicked: (String) -> Unit = {}, - private val onEditClicked: () -> Unit = {}, - private val onSendMessageClicked: (Long) -> Unit = {}, - private val onShowLogsClicked: (Long) -> Unit = {}, - private val onMemberClicked: (Long) -> Unit = {}, - private val onMemberLongClicked: (Long, Long) -> Unit = { _, _ -> } -) : ProfileComponent, AppComponentContext by context { - - private val chatsListRepository: ChatsListRepository = container.repositories.chatsListRepository - private val userRepository: UserRepository = container.repositories.userRepository - private val privacyRepository: PrivacyRepository = container.repositories.privacyRepository - override val messageRepository: MessageRepository = container.repositories.messageRepository - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - private val locationRepository: LocationRepository = container.repositories.locationRepository - private val botPreferences: BotPreferencesProvider = container.preferences.botPreferencesProvider - override val downloadUtils: IDownloadUtils = container.utils.downloadUtils() - - private val scope = componentScope - private val _state = MutableValue(ProfileComponent.State(chatId = chatId)) - override val state: Value = _state - - private var lastLoadedMessageId: Long = 0L - private val PAGE_SIZE = 50 - private var membersOffset = 0 - private var isCurrentlyLoadingMedia = false - private val canLoadMoreMediaByFilter = mutableMapOf() - - init { - loadData() - loadMediaNextPage(isFirstLoad = true) - observeProfilePhotos() - observeUserUpdates() - observeCurrentUser() - } - - private fun loadData() { - scope.launch { - _state.update { it.copy(isLoading = true) } - try { - val chat = coRunCatching { chatsListRepository.getChatById(chatId) }.getOrNull() - val user = if (chat == null || (!chat.isGroup && !chat.isChannel)) { - userRepository.getUser(chatId) - } else null - val isBlocked = if (user != null) { - privacyRepository.getBlockedUsers().contains(user.id) - } else { - chat?.blockList == true - } - val fullInfo = coRunCatching { userRepository.getChatFullInfo(chatId) }.getOrNull() - val description = fullInfo?.description - val link = fullInfo?.inviteLink - ?: chat?.username?.let { "https://t.me/$it" } - ?: user?.username?.let { "https://t.me/$it" } - - var botWebAppUrl: String? = null - var botWebAppName: String? = null - var isTOSAccepted = false - - if (user?.type == UserTypeEnum.BOT) { - val botInfo = userRepository.getBotInfo(chatId) - val menuButton = botInfo?.menuButton - if (menuButton is BotMenuButtonModel.WebApp) { - botWebAppUrl = menuButton.url - botWebAppName = menuButton.text - } - isTOSAccepted = botPreferences.getWebappPermission(user.id, "tos_accepted") - } - - val linkedChatId = fullInfo?.linkedChatId?.takeIf { it != 0L } - val linkedChat = linkedChatId?.let { - coRunCatching { chatsListRepository.getChatById(it) }.getOrNull() - } - - _state.update { - it.copy( - chat = chat, - user = user, - isBlocked = isBlocked, - fullInfo = fullInfo, - about = description, - publicLink = link, - botWebAppUrl = botWebAppUrl, - botWebAppName = botWebAppName, - qrContent = link ?: "", - personalAvatarPath = user?.personalAvatarPath, - linkedChat = linkedChat, - isTOSAccepted = isTOSAccepted - ) - } - } finally { - _state.update { it.copy(isLoading = false) } - } - } - } - - private fun observeCurrentUser() { - userRepository.currentUserFlow - .onEach { user -> - _state.update { it.copy(currentUser = user) } - } - .launchIn(scope) - } - - override fun onLoadMoreMedia() { - val isGroup = _state.value.chat?.let { it.isGroup || it.isChannel } ?: false - if (isGroup && _state.value.selectedTabIndex == 1) { - loadMembersNextPage() - } else { - loadMediaNextPage(isFirstLoad = false) - } - } - - override fun onDownloadMedia(message: MessageModel) { - scope.launch { - - val highResId = if (message.content is MessageContent.Photo) { - messageRepository.getHighResFileId(chatId, message.id) - } else null - val fileId = if (highResId != null && highResId != 0) { - highResId - } else { - when (val content = message.content) { - is MessageContent.Photo -> content.fileId - is MessageContent.Video -> content.fileId - else -> 0 - } - } - - if (fileId != 0) { - messageRepository.downloadFile(fileId, priority = 16) - var attempts = 0 - - while (attempts < 60) { - delay(500) - val fileInfo = messageRepository.getFileInfo(fileId) - if (fileInfo?.local?.isDownloadingCompleted == true && fileInfo.local.path.isNotEmpty()) { - withContext(Dispatchers.Main) { - - onFileDownloaded(fileId, fileInfo.local.path) - - - if (message.content is MessageContent.Photo) { - val currentImages = _state.value.fullScreenImages - if (currentImages != null && !_state.value.isViewingProfilePhotos) { - val allPhotos = _state.value.mediaMessages.filter { it.content is MessageContent.Photo } - val index = allPhotos.indexOfFirst { it.id == message.id } - - if (index != -1 && index < currentImages.size) { - val newImages = currentImages.toMutableList() - newImages[index] = fileInfo.local.path - _state.update { it.copy(fullScreenImages = newImages) } - } - } - } - } - break - } - attempts++ - } - } - } - } - - fun onFileDownloaded(fileId: Int, newPath: String) { - if (fileId == 0) return - - val currentState = _state.value - - val updatedMedia = currentState.mediaMessages.map { msg -> - updateMessagePathIfNeeded(msg, fileId, newPath) - } - - val updatedFiles = currentState.fileMessages.map { msg -> - updateMessagePathIfNeeded(msg, fileId, newPath) - } - - if (updatedMedia != currentState.mediaMessages || updatedFiles != currentState.fileMessages) { - _state.update { - var nextState = it.copy( - mediaMessages = updatedMedia, - fileMessages = updatedFiles - ) - - if (it.fullScreenImages != null && !it.isViewingProfilePhotos) { - val allPhotos = updatedMedia.filter { it.content is MessageContent.Photo } - val paths = allPhotos.mapNotNull { (it.content as? MessageContent.Photo)?.displayPath() } - - nextState = nextState.copy( - fullScreenImages = paths - ) - } - nextState - } - } - } - - private fun updateMessagePathIfNeeded(msg: MessageModel, targetFileId: Int, newPath: String): MessageModel { - val content = msg.content - val shouldUpdate = when (content) { - is MessageContent.Photo -> content.fileId == targetFileId - is MessageContent.Video -> content.fileId == targetFileId - is MessageContent.Document -> content.fileId == targetFileId - else -> false - } - - return if (shouldUpdate) { - val newContent = when (content) { - is MessageContent.Photo -> content.copy(path = newPath) - is MessageContent.Video -> content.copy(path = newPath) - is MessageContent.Document -> content.copy(path = newPath) - else -> content - } - msg.copy(content = newContent) - } else { - msg - } - } - - private fun MessageContent.Photo.displayPath(): String? = path ?: thumbnailPath - - private fun loadMembersNextPage() { - if (_state.value.isLoadingMembers || !_state.value.canLoadMoreMembers) return - - scope.launch { - _state.update { it.copy(isLoadingMembers = true) } - try { - val limit = 20 - val newMembers = userRepository.getChatMembers(chatId, membersOffset, limit, ChatMembersFilter.Recent) - - if (newMembers.isEmpty()) { - _state.update { it.copy(canLoadMoreMembers = false) } - } else { - membersOffset += newMembers.size - _state.update { - it.copy( - members = it.members + newMembers, - canLoadMoreMembers = newMembers.size >= limit - ) - } - } - } catch (e: CancellationException) { - throw e - } catch (e: Exception) { - e.printStackTrace() - } finally { - _state.update { it.copy(isLoadingMembers = false) } - } - } - } - - private fun loadMediaNextPage(isFirstLoad: Boolean) { - if (isCurrentlyLoadingMedia) return - val state = _state.value - val isGroup = state.chat?.let { it.isGroup || it.isChannel } ?: false - val tabIndex = state.selectedTabIndex - if (isGroup && tabIndex == 1) return - - val mediaTypeIndex = if (isGroup && tabIndex > 1) tabIndex - 1 else tabIndex - val filter = when (mediaTypeIndex) { - 0 -> ProfileMediaFilter.MEDIA - 1 -> ProfileMediaFilter.FILES - 2 -> ProfileMediaFilter.AUDIO - 3 -> ProfileMediaFilter.VOICE - 4 -> ProfileMediaFilter.LINKS - 5 -> ProfileMediaFilter.GIFS - else -> return - } - val canLoadMoreForFilter = canLoadMoreMediaByFilter[filter] ?: true - if (!isFirstLoad && !canLoadMoreForFilter) return - - val lastId = if (isFirstLoad) 0L else getLastMessageIdForFilter(state, filter) - - scope.launch { - isCurrentlyLoadingMedia = true - _state.update { - it.copy( - isLoadingMedia = isFirstLoad, - isLoadingMoreMedia = !isFirstLoad - ) - } - - try { - val messages = messageRepository.getProfileMedia( - chatId = chatId, - filter = filter, - fromMessageId = lastId, - limit = PAGE_SIZE - ) - - if (messages.isEmpty()) { - canLoadMoreMediaByFilter[filter] = false - _state.update { it.copy(canLoadMoreMedia = false) } - } else { - _state.update { appendMessagesToState(it, filter, messages) } - } - } catch (e: CancellationException) { - throw e - } catch (e: Exception) { - e.printStackTrace() - } finally { - isCurrentlyLoadingMedia = false - _state.update { - it.copy( - isLoadingMedia = false, - isLoadingMoreMedia = false - ) - } - } - } - } - - private fun getLastMessageIdForFilter(state: ProfileComponent.State, filter: ProfileMediaFilter): Long { - val list = when (filter) { - ProfileMediaFilter.MEDIA -> state.mediaMessages - ProfileMediaFilter.FILES -> state.fileMessages - ProfileMediaFilter.AUDIO -> state.audioMessages - ProfileMediaFilter.VOICE -> state.voiceMessages - ProfileMediaFilter.LINKS -> state.linkMessages - ProfileMediaFilter.GIFS -> state.gifMessages - } - return list.lastOrNull()?.id ?: 0L - } - - private fun appendMessagesToState( - currentState: ProfileComponent.State, - filter: ProfileMediaFilter, - newMessages: List - ): ProfileComponent.State { - val canLoadMore = newMessages.size >= PAGE_SIZE - canLoadMoreMediaByFilter[filter] = canLoadMore - - val nextState = when (filter) { - ProfileMediaFilter.MEDIA -> currentState.copy( - mediaMessages = currentState.mediaMessages + newMessages, - canLoadMoreMedia = canLoadMore - ) - ProfileMediaFilter.FILES -> currentState.copy( - fileMessages = currentState.fileMessages + newMessages, - canLoadMoreMedia = canLoadMore - ) - ProfileMediaFilter.AUDIO -> currentState.copy( - audioMessages = currentState.audioMessages + newMessages, - canLoadMoreMedia = canLoadMore - ) - ProfileMediaFilter.VOICE -> currentState.copy( - voiceMessages = currentState.voiceMessages + newMessages, - canLoadMoreMedia = canLoadMore - ) - ProfileMediaFilter.LINKS -> currentState.copy( - linkMessages = currentState.linkMessages + newMessages, - canLoadMoreMedia = canLoadMore - ) - ProfileMediaFilter.GIFS -> currentState.copy( - gifMessages = currentState.gifMessages + newMessages, - canLoadMoreMedia = canLoadMore - ) - } - - if (filter == ProfileMediaFilter.MEDIA && nextState.fullScreenImages != null && !nextState.isViewingProfilePhotos) { - val allPhotos = nextState.mediaMessages.filter { it.content is MessageContent.Photo } - val paths = allPhotos.mapNotNull { (it.content as? MessageContent.Photo)?.path } - val captions = allPhotos.map { (it.content as? MessageContent.Photo)?.caption } - return nextState.copy( - fullScreenImages = paths, - fullScreenCaptions = captions - ) - } - - return nextState - } - - override fun onTabSelected(index: Int) { - if (_state.value.selectedTabIndex == index) return - - val currentState = _state.value - val isGroup = currentState.chat?.let { it.isGroup || it.isChannel } ?: false - val selectedFilter = tabFilter(index, isGroup) - val tabCanLoadMore = selectedFilter?.let { canLoadMoreMediaByFilter[it] ?: true } ?: true - val isTabEmpty = when (selectedFilter) { - ProfileMediaFilter.MEDIA -> currentState.mediaMessages.isEmpty() - ProfileMediaFilter.FILES -> currentState.fileMessages.isEmpty() - ProfileMediaFilter.AUDIO -> currentState.audioMessages.isEmpty() - ProfileMediaFilter.VOICE -> currentState.voiceMessages.isEmpty() - ProfileMediaFilter.LINKS -> currentState.linkMessages.isEmpty() - ProfileMediaFilter.GIFS -> currentState.gifMessages.isEmpty() - null -> false - } - - _state.update { - it.copy( - selectedTabIndex = index, - canLoadMoreMedia = tabCanLoadMore, - isLoadingMedia = isTabEmpty, - isLoadingMoreMedia = false - ) - } - - if (isGroup && index == 1) { - if (_state.value.members.isEmpty()) { - loadMembersNextPage() - } else { - _state.update { it.copy(isLoadingMedia = false) } - } - } else { - if (isTabEmpty) { - loadMediaNextPage(isFirstLoad = true) - } else { - _state.update { it.copy(isLoadingMedia = false) } - } - } - } - - private fun tabFilter(index: Int, isGroup: Boolean): ProfileMediaFilter? { - if (isGroup && index == 1) return null - val mediaTypeIndex = if (isGroup && index > 1) index - 1 else index - return when (mediaTypeIndex) { - 0 -> ProfileMediaFilter.MEDIA - 1 -> ProfileMediaFilter.FILES - 2 -> ProfileMediaFilter.AUDIO - 3 -> ProfileMediaFilter.VOICE - 4 -> ProfileMediaFilter.LINKS - 5 -> ProfileMediaFilter.GIFS - else -> null - } - } - - private fun observeUserUpdates() { - userRepository.getUserFlow(chatId) - .onEach { user -> - if (user != null) { - _state.update { it.copy(user = user, personalAvatarPath = user.personalAvatarPath) } - } - } - .launchIn(scope) - } - - private fun observeProfilePhotos() { - userRepository.getUserProfilePhotosFlow(chatId) - .onEach { photos -> - if (photos.isNotEmpty()) { - _state.update { it.copy(profilePhotos = photos) } - } - } - .launchIn(scope) - } - - override fun onBack() { - onBackClicked() - } - - override fun onMessageClick(message: MessageModel) { - when (val content = message.content) { - is MessageContent.Photo -> { - scope.launch { - val bigFileId = messageRepository.getHighResFileId(chatId, message.id) - if (bigFileId != null && bigFileId != 0) { - messageRepository.downloadFile(bigFileId, priority = 32) - var attempts = 0 - while (attempts < 60) { - delay(500) - val fileInfo = messageRepository.getFileInfo(bigFileId) - if (fileInfo?.local?.isDownloadingCompleted == true && fileInfo.local.path.isNotEmpty()) { - withContext(Dispatchers.Main) { - onFileDownloaded(bigFileId, fileInfo.local.path) - val currentImages = _state.value.fullScreenImages - if (currentImages != null) { - val viewerItems = _state.value.mediaMessages - .asSequence() - .filter { it.content is MessageContent.Photo } - .mapNotNull { - val photo = - it.content as? MessageContent.Photo ?: return@mapNotNull null - photo.displayPath()?.let { path -> it.id to path } - } - .toList() - val index = viewerItems.indexOfFirst { it.first == message.id } - - if (index != -1 && index < currentImages.size) { - val newImages = currentImages.toMutableList() - newImages[index] = fileInfo.local.path - _state.update { it.copy(fullScreenImages = newImages) } - } - } - } - break - } - attempts++ - } - } - } - - val viewerItems = _state.value.mediaMessages - .asSequence() - .filter { it.content is MessageContent.Photo } - .mapNotNull { - val photo = it.content as? MessageContent.Photo ?: return@mapNotNull null - val displayPath = photo.displayPath() ?: return@mapNotNull null - Triple(it.id, displayPath, photo.caption) - } - .toList() - - if (viewerItems.isNotEmpty()) { - val startIndex = viewerItems.indexOfFirst { it.first == message.id } - .takeIf { it != -1 } ?: 0 - - _state.update { - it.copy( - fullScreenImages = viewerItems.map { item -> item.second }, - fullScreenCaptions = viewerItems.map { item -> item.third }, - fullScreenStartIndex = startIndex, - isViewingProfilePhotos = false - ) - } - } - } - is MessageContent.Video -> { - content.path?.let { path -> - _state.update { - it.copy( - fullScreenVideoPath = path, - fullScreenVideoCaption = content.caption - ) - } - } ?: run { - if (content.fileId != 0) { - scope.launch { - messageRepository.downloadFile(content.fileId, priority = 32) - var attempts = 0 - while (attempts < 60) { - delay(500) - val fileInfo = messageRepository.getFileInfo(content.fileId) - if (fileInfo?.local?.isDownloadingCompleted == true && fileInfo.local.path.isNotEmpty()) { - withContext(Dispatchers.Main) { - _state.update { - it.copy( - fullScreenVideoPath = fileInfo.local.path, - fullScreenVideoCaption = content.caption - ) - } - onFileDownloaded(content.fileId, fileInfo.local.path) - } - break - } - attempts++ - } - } - } - } - } - is MessageContent.Gif -> { - content.path?.let { path -> - _state.update { - it.copy( - fullScreenVideoPath = path, - fullScreenVideoCaption = content.caption - ) - } - } - } - is MessageContent.VideoNote -> { - content.path?.let { path -> - _state.update { - it.copy( - fullScreenVideoPath = path, - fullScreenVideoCaption = null - ) - } - } - } - is MessageContent.Location -> { - onLocationClick(content.latitude, content.longitude, "Location") - } - - is MessageContent.Venue -> { - onLocationClick(content.latitude, content.longitude, content.title) - } - else -> onMessageClicked(message) - } - } - - override fun onMessageLongClick(message: MessageModel) { - onMessageLongClicked(message) - } - - override fun onAvatarClick() { - val snapshot = _state.value - val initialPhotos = snapshot.profilePhotos - - if (initialPhotos.isNotEmpty()) { - openProfilePhotos(initialPhotos) - } else { - val avatarPath = snapshot.personalAvatarPath - ?: snapshot.chat?.avatarPath - ?: snapshot.user?.avatarPath - avatarPath?.let { openProfilePhotos(listOf(it)) } - } - - val userId = snapshot.user?.id?.takeIf { it > 0 } ?: snapshot.chatId.takeIf { it > 0 } - if (userId == null) return - - scope.launch { - _state.update { it.copy(isProfilePhotoHdLoading = true) } - try { - val refreshedPhotos = coRunCatching { - userRepository.getUserProfilePhotos( - userId = userId, - offset = 0, - limit = 10, - ensureFullRes = true - ) - }.getOrDefault(emptyList()) - - if (refreshedPhotos.isEmpty()) return@launch - - _state.update { current -> - val next = current.copy(profilePhotos = refreshedPhotos) - val viewerIsOpen = current.fullScreenImages != null || current.fullScreenVideoPath != null - if (!viewerIsOpen) { - next - } else { - applyProfilePhotosToViewer(next, refreshedPhotos) - } - } - } finally { - _state.update { it.copy(isProfilePhotoHdLoading = false) } - } - } - } - - private fun openProfilePhotos(photos: List) { - if (photos.isEmpty()) return - _state.update { current -> - applyProfilePhotosToViewer(current, photos) - } - } - - private fun applyProfilePhotosToViewer( - state: ProfileComponent.State, - photos: List - ): ProfileComponent.State { - val firstPhoto = photos.firstOrNull() ?: return state - if (firstPhoto.endsWith(".mp4", ignoreCase = true)) { - return state.copy( - fullScreenVideoPath = firstPhoto, - fullScreenVideoCaption = null, - fullScreenImages = null, - fullScreenCaptions = emptyList(), - fullScreenStartIndex = 0, - isViewingProfilePhotos = true - ) - } - - val images = photos.filter { !it.endsWith(".mp4", ignoreCase = true) } - if (images.isEmpty()) return state - - val safeIndex = state.fullScreenStartIndex.coerceIn(0, images.lastIndex) - return state.copy( - fullScreenImages = images, - fullScreenCaptions = images.map { null }, - fullScreenStartIndex = safeIndex, - fullScreenVideoPath = null, - fullScreenVideoCaption = null, - isViewingProfilePhotos = true - ) - } - - override fun onDismissViewer() { - _state.update { - it.copy( - fullScreenImages = null, - fullScreenCaptions = emptyList(), - fullScreenVideoPath = null, - fullScreenVideoCaption = null, - isViewingProfilePhotos = false, - isProfilePhotoHdLoading = false - ) - } - } - - override fun onOpenMiniApp(url: String, name: String, chatId: Long) { - _state.update { it.copy(miniAppUrl = url, miniAppName = name, chatId = chatId) } - } - - override fun onDismissMiniApp() { - _state.update { it.copy(miniAppUrl = null, miniAppName = null) } - } - - override fun onToggleMute() { - val chat = _state.value.chat ?: return - val shouldMute = !chat.isMuted - - scope.launch { - chatsListRepository.toggleMuteChats(setOf(chatId), shouldMute) - updateChat(chatId) - } - } - - override fun onEdit() { - onEditClicked() - } - - override fun onShowQRCode() { - _state.update { it.copy(isQrVisible = true) } - } - - override fun onDismissQRCode() { - _state.update { it.copy(isQrVisible = false) } - } - - override fun onSendMessage() { - onSendMessageClicked(chatId) - } - - override fun onToggleBlockUser() { - val userId = _state.value.user?.id ?: return - val shouldBlock = !_state.value.isBlocked - scope.launch { - if (shouldBlock) { - privacyRepository.blockUser(userId) - } else { - privacyRepository.unblockUser(userId) - } - _state.update { it.copy(isBlocked = shouldBlock) } - updateChat(chatId) - } - } - - override fun onDeleteChat() { - scope.launch { - chatsListRepository.deleteChats(setOf(chatId)) - } - } - - override fun onEditContact(firstName: String, lastName: String) { - val user = _state.value.user ?: return - val trimmedFirstName = firstName.trim() - if (trimmedFirstName.isBlank()) return - val normalizedLastName = lastName.trim().ifBlank { null } - - scope.launch { - runCatching { - userRepository.addContact( - user.copy( - firstName = trimmedFirstName, - lastName = normalizedLastName, - isContact = true - ) - ) - }.onSuccess { - _state.update { current -> - current.copy( - user = current.user?.copy( - firstName = trimmedFirstName, - lastName = normalizedLastName - ) - ) - } - } - } - } - - override fun onToggleContact() { - val user = _state.value.user ?: return - scope.launch { - if (user.isContact) { - userRepository.removeContact(user.id) - } else { - userRepository.addContact(user) - } - _state.update { current -> - current.copy(user = current.user?.copy(isContact = !user.isContact)) - } - } - } - - override fun onLeave() { - scope.launch { - chatsListRepository.leaveChat(chatId) - updateChat(chatId) - } - } - - override fun onJoinChat() { - scope.launch { - messageRepository.joinChat(chatId) - updateChat(chatId) - } - } - - override fun onReport(reason: String) { - scope.launch(Dispatchers.IO) { - chatsListRepository.reportChat(chatId, reason) - withContext(Dispatchers.Main) { - _state.update { it.copy(isReportVisible = false) } - } - } - } - - override fun onDismissReport() { - _state.update { it.copy(isReportVisible = false) } - } - - override fun onShowReport() { - _state.update { it.copy(isReportVisible = true) } - } - - override fun onShowLogs() { - onShowLogsClicked(chatId) - } - - override fun onMemberClick(userId: Long) { - scope.launch { - val chat = chatsListRepository.getChatById(userId) - if (chat != null && (chat.isGroup || chat.isChannel)) { - onMemberClicked(userId) - } else { - onSendMessageClicked(userId) - } - } - } - - override fun onMemberLongClick(userId: Long) { - scope.launch { - val member = userRepository.getChatMember(chatId, userId) - if (member?.status is ChatMemberStatus.Administrator || member?.status is ChatMemberStatus.Creator) { - onMemberLongClicked(chatId, userId) - } - } - } - - override fun onUpdateChatTitle(title: String) { - scope.launch { - chatsListRepository.setChatTitle(chatId, title) - updateChat(chatId) - } - } - - override fun onUpdateChatDescription(description: String) { - scope.launch { - chatsListRepository.setChatDescription(chatId, description) - loadData() - } - } - - override fun onUpdateChatUsername(username: String) { - scope.launch { - chatsListRepository.setChatUsername(chatId, username) - loadData() - } - } - - override fun onUpdateChatPermissions(permissions: ChatPermissionsModel) { - scope.launch { - chatsListRepository.setChatPermissions(chatId, permissions) - updateChat(chatId) - } - } - - override fun onUpdateChatSlowModeDelay(delay: Int) { - scope.launch { - chatsListRepository.setChatSlowModeDelay(chatId, delay) - loadData() - } - } - - override fun onUpdateMemberStatus(userId: Long, status: ChatMemberStatus) { - scope.launch { - userRepository.setChatMemberStatus(chatId, userId, status) - membersOffset = 0 - _state.update { it.copy(members = emptyList(), canLoadMoreMembers = true) } - loadMembersNextPage() - } - } - - override fun onShowStatistics() { - scope.launch { - val stats = userRepository.getChatStatistics(chatId, false) - if (stats != null) { - val enrichedStats = enrichInteractionPreviews(stats) - _state.update { it.copy(statistics = enrichedStats, isStatisticsVisible = true) } - } else { - loadData() - } - } - } - - override fun onShowRevenueStatistics() { - scope.launch { - val stats = userRepository.getChatRevenueStatistics(chatId, false) - if (stats != null) { - _state.update { - it.copy(revenueStatistics = stats, isRevenueStatisticsVisible = true) - } - } else { - loadData() - } - } - } - - override fun onDismissStatistics() { - _state.update { - it.copy( - isStatisticsVisible = false, - isRevenueStatisticsVisible = false, - statistics = null, - revenueStatistics = null - ) - } - } - - override fun onLoadStatisticsGraph(token: String) { - scope.launch { - val graph = userRepository.loadStatisticsGraph(chatId, token, 0L) - - if (graph != null) { - _state.update { state -> - val updatedStats = state.statistics?.let { updateStatisticsWithGraph(it, token, graph) } - val updatedRevenueStats = state.revenueStatistics?.let { - updateRevenueStatisticsWithGraph(it, token, graph) - } - state.copy( - statistics = updatedStats ?: state.statistics, - revenueStatistics = updatedRevenueStats ?: state.revenueStatistics - ) - } - } - } - } - - override fun onLinkedChatClick() { - _state.value.linkedChat?.id?.let { onSendMessageClicked(it) } - } - - override fun onShowPermissions() { - val botId = _state.value.user?.id ?: return - val permissions = mapOf( - "Location" to botPreferences.getWebappPermission(botId, "location"), - "Biometry" to botPreferences.getWebappPermission(botId, "biometry"), - "Terms of Service" to botPreferences.getWebappPermission(botId, "tos_accepted") - ) - _state.update { it.copy(isPermissionsVisible = true, botPermissions = permissions) } - } - - override fun onDismissPermissions() { - _state.update { it.copy(isPermissionsVisible = false) } - } - - override fun onTogglePermission(permission: String) { - val botId = _state.value.user?.id ?: return - val key = when (permission) { - "Location" -> "location" - "Biometry" -> "biometry" - "Terms of Service" -> "tos_accepted" - else -> return - } - val current = botPreferences.getWebappPermission(botId, key) - botPreferences.setWebappPermission(botId, key, !current) - - if (key == "tos_accepted") { - _state.update { it.copy(isTOSAccepted = !current) } - } - - onShowPermissions() - } - - override fun onAcceptTOS() { - val botId = _state.value.user?.id ?: return - scope.launch { - _state.update { it.copy(isAcceptingTOS = true) } - delay(1000) // Animation delay - botPreferences.setWebappPermission(botId, "tos_accepted", true) - _state.update { - it.copy( - isTOSVisible = false, - isTOSAccepted = true, - isAcceptingTOS = false - ) - } - } - } - - override fun onDismissTOS() { - _state.update { - it.copy( - isTOSVisible = false, - pendingMiniAppUrl = null, - pendingMiniAppName = null - ) - } - } - - override fun onLocationClick(lat: Double, lon: Double, address: String) { - scope.launch { - var finalAddress = address - if (address == "Location") { - val reverse = locationRepository.reverseGeocode(lat, lon) - if (reverse != null) { - finalAddress = reverse.address?.city ?: reverse.address?.toString() ?: "Location" - } - } - _state.update { - it.copy( - selectedLocation = ProfileComponent.LocationData(lat, lon, finalAddress) - ) - } - } - } - - override fun onDismissLocation() { - _state.update { it.copy(selectedLocation = null) } - } - - private suspend fun enrichInteractionPreviews(stats: ChatStatisticsModel): ChatStatisticsModel { - if (stats.recentInteractions.isEmpty()) return stats - val enriched = stats.recentInteractions.map { interaction -> - if (interaction.type != ChatInteractionType.MESSAGE || interaction.objectId == 0L) { - interaction - } else { - val preview = coRunCatching { - messageRepository - .getMessagesAround(chatId = chatId, messageId = interaction.objectId, limit = 1) - .firstOrNull { it.id == interaction.objectId } - ?.content - ?.toStatisticsPreview() - }.getOrNull() - interaction.copy(previewText = preview) - } - } - return stats.copy(recentInteractions = enriched) - } - - private fun MessageContent.toStatisticsPreview(): String { - return when (this) { - is MessageContent.Text -> text.ifBlank { "Message" } - is MessageContent.Photo -> caption.ifBlank { "Photo" } - is MessageContent.Video -> caption.ifBlank { "Video" } - is MessageContent.Gif -> caption.ifBlank { "GIF" } - is MessageContent.Document -> caption.ifBlank { fileName.ifBlank { "Document" } } - is MessageContent.Audio -> caption.ifBlank { title.ifBlank { "Audio" } } - is MessageContent.Voice -> "Voice message" - is MessageContent.VideoNote -> "Video message" - is MessageContent.Sticker -> "Sticker ${emoji.ifBlank { "" }}".trim() - is MessageContent.Contact -> "Contact: ${firstName} ${lastName}".trim() - is MessageContent.Location -> "Location" - is MessageContent.Venue -> "Venue: $title" - is MessageContent.Poll -> "Poll: $question" - is MessageContent.Service -> text.ifBlank { "Service message" } - MessageContent.Unsupported -> "Unsupported message" - } - } - - private fun updateStatisticsWithGraph( - stats: ChatStatisticsModel, - token: String, - newGraph: StatisticsGraphModel - ): ChatStatisticsModel { - fun StatisticsGraphModel?.matchesToken(token: String): Boolean { - return when (this) { - is StatisticsGraphModel.Async -> this.token == token - is StatisticsGraphModel.Data -> this.zoomToken == token - else -> false - } - } - - return stats.copy( - memberCountGraph = if (stats.memberCountGraph.matchesToken(token)) newGraph else stats.memberCountGraph, - joinGraph = if (stats.joinGraph.matchesToken(token)) newGraph else stats.joinGraph, - muteGraph = if (stats.muteGraph.matchesToken(token)) newGraph else stats.muteGraph, - viewCountByHourGraph = if (stats.viewCountByHourGraph.matchesToken(token)) newGraph else stats.viewCountByHourGraph, - viewCountBySourceGraph = if (stats.viewCountBySourceGraph.matchesToken(token)) newGraph else stats.viewCountBySourceGraph, - joinBySourceGraph = if (stats.joinBySourceGraph.matchesToken(token)) newGraph else stats.joinBySourceGraph, - languageGraph = if (stats.languageGraph.matchesToken(token)) newGraph else stats.languageGraph, - messageContentGraph = if (stats.messageContentGraph.matchesToken(token)) newGraph else stats.messageContentGraph, - actionGraph = if (stats.actionGraph.matchesToken(token)) newGraph else stats.actionGraph, - dayGraph = if (stats.dayGraph.matchesToken(token)) newGraph else stats.dayGraph, - weekGraph = if (stats.weekGraph.matchesToken(token)) newGraph else stats.weekGraph, - topHoursGraph = if (stats.topHoursGraph.matchesToken(token)) newGraph else stats.topHoursGraph, - messageReactionGraph = if (stats.messageReactionGraph.matchesToken(token)) newGraph else stats.messageReactionGraph, - storyInteractionGraph = if (stats.storyInteractionGraph.matchesToken(token)) newGraph else stats.storyInteractionGraph, - storyReactionGraph = if (stats.storyReactionGraph.matchesToken(token)) newGraph else stats.storyReactionGraph - ) - } - - private fun updateRevenueStatisticsWithGraph( - stats: ChatRevenueStatisticsModel, - token: String, - newGraph: StatisticsGraphModel - ): ChatRevenueStatisticsModel { - fun StatisticsGraphModel?.matchesToken(token: String): Boolean { - return when (this) { - is StatisticsGraphModel.Async -> this.token == token - is StatisticsGraphModel.Data -> this.zoomToken == token - else -> false - } - } - - return stats.copy( - revenueByHourGraph = if (stats.revenueByHourGraph.matchesToken(token)) newGraph else stats.revenueByHourGraph, - revenueGraph = if (stats.revenueGraph.matchesToken(token)) newGraph else stats.revenueGraph - ) - } - - private fun updateChat(chatId: Long) { - scope.launch { - val updatedChat = chatsListRepository.getChatById(chatId) - withContext(Dispatchers.Main) { - _state.update { - it.copy( - chat = updatedChat, - isBlocked = updatedChat?.blockList ?: it.isBlocked - ) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/ProfileComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/ProfileComponent.kt deleted file mode 100644 index ece6ce2e..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/ProfileComponent.kt +++ /dev/null @@ -1,140 +0,0 @@ -package org.monogram.presentation.features.profile - -import com.arkivanov.decompose.value.Value -import org.monogram.domain.models.* -import org.monogram.domain.repository.ChatMemberStatus -import org.monogram.domain.repository.MessageRepository -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -interface ProfileComponent { - val state: Value - val messageRepository: MessageRepository - val downloadUtils: IDownloadUtils - val videoPlayerPool: VideoPlayerPool - - fun onBack() - fun onTabSelected(index: Int) - fun onMessageClick(message: MessageModel) - fun onMessageLongClick(message: MessageModel) - fun onAvatarClick() - fun onDismissViewer() - fun onLoadMoreMedia() - fun onOpenMiniApp(url: String, name: String, chatId: Long) - fun onDismissMiniApp() - fun onToggleMute() - fun onEdit() - fun onShowQRCode() - fun onDismissQRCode() - fun onSendMessage() - fun onToggleBlockUser() - fun onDeleteChat() - fun onEditContact(firstName: String, lastName: String) - fun onToggleContact() - fun onLeave() - fun onJoinChat() - fun onReport(reason: String) - fun onDismissReport() - fun onShowReport() - fun onShowLogs() - fun onMemberClick(userId: Long) - fun onMemberLongClick(userId: Long) - - fun onUpdateChatTitle(title: String) - fun onUpdateChatDescription(description: String) - fun onUpdateChatUsername(username: String) - fun onUpdateChatPermissions(permissions: ChatPermissionsModel) - fun onUpdateChatSlowModeDelay(delay: Int) - fun onUpdateMemberStatus(userId: Long, status: ChatMemberStatus) - - fun onShowStatistics() - fun onShowRevenueStatistics() - fun onDismissStatistics() - fun onLoadStatisticsGraph(token: String) - fun onDownloadMedia(message: MessageModel) - fun onLinkedChatClick() - - fun onShowPermissions() - fun onDismissPermissions() - fun onTogglePermission(permission: String) - - fun onAcceptTOS() - fun onDismissTOS() - - fun onLocationClick(lat: Double, lon: Double, address: String) - fun onDismissLocation() - - data class State( - val chatId: Long, - val chat: ChatModel? = null, - val user: UserModel? = null, - - val fullInfo: ChatFullInfoModel? = null, - - val isLoading: Boolean = false, - val about: String? = null, - val publicLink: String? = null, - - val selectedTabIndex: Int = 0, - - val mediaMessages: List = emptyList(), - val fileMessages: List = emptyList(), - val audioMessages: List = emptyList(), - val voiceMessages: List = emptyList(), - val linkMessages: List = emptyList(), - val gifMessages: List = emptyList(), - val members: List = emptyList(), - val isLoadingMembers: Boolean = false, - val canLoadMoreMembers: Boolean = true, - - val isLoadingMedia: Boolean = false, - val isLoadingMoreMedia: Boolean = false, - val canLoadMoreMedia: Boolean = true, - - val profilePhotos: List = emptyList(), - val personalAvatarPath: String? = null, - - val fullScreenImages: List? = null, - val fullScreenCaptions: List = emptyList(), - val fullScreenStartIndex: Int = 0, - val fullScreenVideoPath: String? = null, - val fullScreenVideoCaption: String? = null, - val isViewingProfilePhotos: Boolean = false, - val isProfilePhotoHdLoading: Boolean = false, - - val miniAppUrl: String? = null, - val miniAppName: String? = null, - val currentUser: UserModel? = null, - val isBlocked: Boolean = false, - val botWebAppUrl: String? = null, - val botWebAppName: String? = null, - - val isQrVisible: Boolean = false, - val qrContent: String = "", - val isReportVisible: Boolean = false, - - val statistics: ChatStatisticsModel? = null, - val revenueStatistics: ChatRevenueStatisticsModel? = null, - val isStatisticsVisible: Boolean = false, - val isRevenueStatisticsVisible: Boolean = false, - - val linkedChat: ChatModel? = null, - - val isPermissionsVisible: Boolean = false, - val botPermissions: Map = emptyMap(), - - val isTOSVisible: Boolean = false, - val isTOSAccepted: Boolean = false, - val isAcceptingTOS: Boolean = false, - val pendingMiniAppUrl: String? = null, - val pendingMiniAppName: String? = null, - - val selectedLocation: LocationData? = null - ) - - data class LocationData( - val latitude: Double, - val longitude: Double, - val address: String - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/ProfileContent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/ProfileContent.kt deleted file mode 100644 index 36b1e04d..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/ProfileContent.kt +++ /dev/null @@ -1,702 +0,0 @@ -package org.monogram.presentation.features.profile - -import android.widget.Toast -import androidx.activity.compose.BackHandler -import androidx.compose.animation.* -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.GridItemSpan -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ExitToApp -import androidx.compose.material.icons.rounded.Block -import androidx.compose.material.icons.rounded.Delete -import androidx.compose.material.icons.rounded.Edit -import androidx.compose.material.icons.rounded.Person -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.lerp -import androidx.compose.ui.platform.LocalClipboardManager -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.UserStatusType -import org.monogram.domain.models.UserTypeEnum -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.* -import org.monogram.presentation.core.util.ScrollStrategy -import org.monogram.presentation.core.util.getUserStatusText -import org.monogram.presentation.features.chats.chatList.components.SettingsTextField -import org.monogram.presentation.features.profile.components.* -import org.monogram.presentation.features.viewers.ImageViewer -import org.monogram.presentation.features.viewers.VideoViewer -import org.monogram.presentation.features.webapp.MiniAppViewer - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ProfileContent(component: ProfileComponent) { - val state by component.state.subscribeAsState() - val clipboardManager = LocalClipboardManager.current - val context = LocalContext.current - val collapsingToolbarState = rememberCollapsingToolbarScaffoldState() - - - val chat = state.chat - val user = state.user - val isCurrentUserProfile = user != null && state.currentUser?.id == user.id - val isInitialLoading = state.isLoading && chat == null && user == null - - val avatarPath = remember(state.profilePhotos, state.chat, state.user, state.personalAvatarPath) { - state.personalAvatarPath - ?: state.profilePhotos.firstOrNull() - ?: state.user?.avatarPath - ?: state.chat?.personalAvatarPath - ?: state.chat?.avatarPath - } - - - val unknownTitle = stringResource(R.string.unknown_title) - val title = remember(user, chat, unknownTitle) { - chat?.title ?: listOfNotNull(user?.firstName, user?.lastName) - .joinToString(" ") - .ifBlank { unknownTitle } - } - - val membersCountFormat = stringResource(R.string.members_count_format) - val membersOnlineCountFormat = stringResource(R.string.members_online_count_format) - val ownProfileSubtitle = stringResource(R.string.menu_my_profile_subtitle) - val subtitle = remember( - user, - chat, - isCurrentUserProfile, - membersCountFormat, - membersOnlineCountFormat, - ownProfileSubtitle - ) { - when { - chat?.isGroup == true || chat?.isChannel == true -> { - val members = String.format(membersCountFormat, chat.memberCount) - if (chat.onlineCount > 0) String.format( - membersOnlineCountFormat, - members, - chat.onlineCount - ) else members - } - - isCurrentUserProfile -> { - user.username - ?.takeIf { it.isNotBlank() } - ?.let { "$ownProfileSubtitle • @$it" } - ?: ownProfileSubtitle - } - - else -> getUserStatusText(user, context) - } - } - - val isOnline = user?.type != UserTypeEnum.BOT && user?.userStatus == UserStatusType.ONLINE - - val collapsedColor = MaterialTheme.colorScheme.surface - val expandedColor = MaterialTheme.colorScheme.background - val dynamicContainerColor = lerp( - start = collapsedColor, - stop = expandedColor, - fraction = collapsingToolbarState.toolbarState.progress - ) - - val isCustomBackHandlingEnabled = state.fullScreenImages != null || state.fullScreenVideoPath != null || state.miniAppUrl != null || state.isStatisticsVisible || state.isRevenueStatisticsVisible || state.selectedLocation != null - - BackHandler(enabled = isCustomBackHandlingEnabled) { - if (state.fullScreenImages != null || state.fullScreenVideoPath != null) component.onDismissViewer() - else if (state.miniAppUrl != null) component.onDismissMiniApp() - else if (state.isStatisticsVisible || state.isRevenueStatisticsVisible) component.onDismissStatistics() - else if (state.selectedLocation != null) component.onDismissLocation() - } - - val searchNotImplemented = stringResource(R.string.search_not_implemented) - val linkCopied = stringResource(R.string.link_copied) - val userIdCopied = stringResource(R.string.logs_user_id_copied) - - val isGroupOrChannel = chat?.isGroup == true || chat?.isChannel == true - val canEditTopBar = when { - isCurrentUserProfile -> true - isGroupOrChannel -> chat.isAdmin || chat.permissions.canChangeInfo - else -> false - } - val shareLink = remember(user, chat, state.publicLink) { - user?.username?.takeIf { it.isNotBlank() }?.let { "https://t.me/$it" } - ?: chat?.username?.takeIf { it.isNotBlank() }?.let { "https://t.me/$it" } - ?: state.publicLink?.takeIf { it.isNotBlank() } - } - val fallbackShareText = remember(isCurrentUserProfile, user) { - if (isCurrentUserProfile) user.id.toString() else null - } - val canShareTopBar = !shareLink.isNullOrEmpty() || !fallbackShareText.isNullOrEmpty() - val canReportTopBar = isGroupOrChannel && !isCurrentUserProfile - val canBlockTopBar = !isCurrentUserProfile && !isGroupOrChannel && user?.type != UserTypeEnum.BOT - val canEditContactTopBar = !isCurrentUserProfile && !isGroupOrChannel && user?.isContact == true - val canDeleteTopBar = !isCurrentUserProfile && (!isGroupOrChannel || chat?.isMember == true) - var showLeaveSheet by remember { mutableStateOf(false) } - var showDeleteChatSheet by remember { mutableStateOf(false) } - var showBlockSheet by remember { mutableStateOf(false) } - var showEditContactDialog by remember { mutableStateOf(false) } - var editContactFirstName by remember { mutableStateOf("") } - var editContactLastName by remember { mutableStateOf("") } - - Box(modifier = Modifier.fillMaxSize()) { - Scaffold( - modifier = Modifier.semantics { contentDescription = "ProfileContent" }, - topBar = { - ProfileTopBar( - onBack = component::onBack, - progress = collapsingToolbarState.toolbarState.progress, - title = title, - userModel = user, - chatModel = chat, - isVerified = user?.isVerified == true || chat?.isVerified == true, - isSponsor = user?.isSponsor == true, - canSearch = false, - canShare = canShareTopBar, - canEdit = canEditTopBar, - canEditContact = canEditContactTopBar, - canReport = canReportTopBar, - canBlock = canBlockTopBar, - isBlocked = state.isBlocked, - canDelete = canDeleteTopBar, - onSearch = { Toast.makeText(context, searchNotImplemented, Toast.LENGTH_SHORT).show() }, - onShare = { - val valueToCopy = shareLink ?: fallbackShareText - if (valueToCopy != null) { - clipboardManager.setText(androidx.compose.ui.text.AnnotatedString(valueToCopy)) - val copiedMessage = if (shareLink != null) linkCopied else userIdCopied - Toast.makeText(context, copiedMessage, Toast.LENGTH_SHORT).show() - } - }, - onEdit = component::onEdit, - onEditContact = { - val currentUser = state.user ?: return@ProfileTopBar - editContactFirstName = currentUser.firstName - editContactLastName = currentUser.lastName.orEmpty() - showEditContactDialog = true - }, - onReport = component::onShowReport, - onBlock = { showBlockSheet = true }, - onDelete = { - if (isGroupOrChannel) { - showLeaveSheet = true - } else { - showDeleteChatSheet = true - } - } - ) - }, - containerColor = dynamicContainerColor - ) { padding -> - CollapsingToolbarScaffold( - modifier = Modifier - .fillMaxSize() - .background(dynamicContainerColor), - state = collapsingToolbarState, - scrollStrategy = ScrollStrategy.ExitUntilCollapsed, - toolbar = { - Box( - modifier = Modifier - .fillMaxWidth() - .height(padding.calculateTopPadding()) - .pin() - ) - BoxWithConstraints( - modifier = Modifier - .fillMaxWidth() - .road(Alignment.Center, Alignment.BottomCenter) - ) { - - val progress = collapsingToolbarState.toolbarState.progress - val avatarSize = androidx.compose.ui.unit.lerp(140.dp, maxWidth, progress) - val cornerPercent = (100 * (1f - progress)).toInt() - val sidePadding = androidx.compose.ui.unit.lerp(24.dp, 0.dp, progress) - val topPadding = androidx.compose.ui.unit.lerp( - 0.dp + padding.calculateTopPadding(), - 0.dp, - progress - ) - if (isInitialLoading) { - ProfileHeaderSkeleton( - progress = progress, - contentPadding = PaddingValues( - top = topPadding, - start = sidePadding, - end = sidePadding - ) - ) - } else { - ProfileHeaderTransformed( - avatarPath = avatarPath, - title = title, - subtitle = subtitle, - avatarSize = avatarSize, - avatarCornerPercent = cornerPercent, - isOnline = isOnline, - isVerified = user?.isVerified == true || chat?.isVerified == true, - isSponsor = user?.isSponsor == true, - statusEmojiPath = user?.statusEmojiPath, - progress = progress, - contentPadding = PaddingValues( - top = topPadding, - start = sidePadding, - end = sidePadding - ), - onAvatarClick = component::onAvatarClick, - userModel = user, - chatModel = chat, - onActionClick = {}, - videoPlayerPool = component.videoPlayerPool - ) - } - } - - } - ) { - LazyVerticalGrid( - columns = GridCells.Fixed(3), - modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.background), - horizontalArrangement = Arrangement.spacedBy(2.dp), - verticalArrangement = Arrangement.spacedBy(2.dp) - ) { - item(span = { GridItemSpan(3) }) { - Column(modifier = Modifier.padding(horizontal = 16.dp)) { - if (isInitialLoading) { - ProfileInfoSectionSkeleton( - showLinkedChat = state.chatId < 0 - ) - } else { - ProfileInfoSection( - state = state, - clipboardManager = clipboardManager, - onOpenMiniApp = { url, name, chatId -> component.onOpenMiniApp(url, name, chatId) }, - onSendMessage = component::onSendMessage, - onToggleMute = component::onToggleMute, - onShowQRCode = component::onShowQRCode, - onEdit = component::onEdit, - onLeave = { showLeaveSheet = true }, - onJoin = component::onJoinChat, - onShowLogs = component::onShowLogs, - onShowStatistics = component::onShowStatistics, - onShowRevenueStatistics = component::onShowRevenueStatistics, - onLinkedChatClick = component::onLinkedChatClick, - onShowPermissions = component::onShowPermissions, - onAcceptTOS = component::onAcceptTOS, - onToggleContact = component::onToggleContact, - onLocationClick = component::onLocationClick, - videoPlayerPool = component.videoPlayerPool - ) - } - Spacer(modifier = Modifier.height(12.dp)) - } - } - - profileMediaSection( - state = state, - onTabSelected = component::onTabSelected, - onMessageClick = component::onMessageClick, - onMessageLongClick = component::onMessageLongClick, - onLoadMore = component::onLoadMoreMedia, - onMemberClick = component::onMemberClick, - onMemberLongClick = component::onMemberLongClick, - onLoadMedia = { msg -> - component.onDownloadMedia(msg) - }, - videoPlayerPool = component.videoPlayerPool - ) - - item(span = { GridItemSpan(3) }) { - Spacer(modifier = Modifier.height(32.dp)) - } - } - } - } - - val notImplemented = stringResource(R.string.not_implemented) - AnimatedVisibility( - visible = state.fullScreenImages != null, - enter = fadeIn() + scaleIn(initialScale = 0.9f), - exit = fadeOut() + scaleOut(targetScale = 0.9f) - ) { - state.fullScreenImages?.let { images -> - Box(modifier = Modifier.fillMaxSize()) { - ImageViewer( - images = images, - startIndex = state.fullScreenStartIndex, - onDismiss = component::onDismissViewer, - autoDownload = true, - downloadUtils = component.downloadUtils, - onPageChanged = { index -> - - if (!state.isViewingProfilePhotos && state.canLoadMoreMedia && !state.isLoadingMoreMedia && - index >= images.size - 5 - ) { - component.onLoadMoreMedia() - } - - if (!state.isViewingProfilePhotos) { - val photoMessages = state.mediaMessages.filter { it.content is MessageContent.Photo } - - val message = photoMessages.getOrNull(index) - if (message != null) { - component.onDownloadMedia(message) - - val nextMessage = photoMessages.getOrNull(index + 1) - if (nextMessage != null) { - component.onDownloadMedia(nextMessage) - } - } - } - }, - onForward = { Toast.makeText(context, notImplemented, Toast.LENGTH_SHORT).show() }, - onDelete = { Toast.makeText(context, notImplemented, Toast.LENGTH_SHORT).show() }, - onCopyLink = { Toast.makeText(context, notImplemented, Toast.LENGTH_SHORT).show() }, - onCopyText = { Toast.makeText(context, notImplemented, Toast.LENGTH_SHORT).show() }, - captions = state.fullScreenCaptions.filterNotNull(), - showImageNumber = false - ) - - if (state.isViewingProfilePhotos && state.isProfilePhotoHdLoading) { - Surface( - modifier = Modifier - .align(Alignment.TopCenter) - .padding(top = 56.dp), - shape = RoundedCornerShape(14.dp), - color = MaterialTheme.colorScheme.surfaceContainerHigh.copy(alpha = 0.92f) - ) { - Row( - modifier = Modifier.padding(horizontal = 14.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(10.dp) - ) { - CircularProgressIndicator( - strokeWidth = 2.dp, - modifier = Modifier.size(16.dp) - ) - Text( - text = "Loading HD", - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.onSurface - ) - } - } - } - } - } - } - - AnimatedVisibility( - visible = state.fullScreenVideoPath != null, - enter = fadeIn() + scaleIn(initialScale = 0.9f), - exit = fadeOut() + scaleOut(targetScale = 0.9f) - ) { - state.fullScreenVideoPath?.let { path -> - val msg = state.mediaMessages.find { - when (val content = it.content) { - is MessageContent.Video -> content.path == path - is MessageContent.Gif -> content.path == path - is MessageContent.VideoNote -> content.path == path - else -> false - } - } - val videoContent = msg?.content as? MessageContent.Video - val fileId = videoContent?.fileId ?: (msg?.content as? MessageContent.Gif)?.fileId - ?: (msg?.content as? MessageContent.VideoNote)?.fileId ?: 0 - val supportsStreaming = videoContent?.supportsStreaming ?: false - - VideoViewer( - path = path, - onDismiss = component::onDismissViewer, - isGesturesEnabled = true, - isDoubleTapSeekEnabled = true, - seekDuration = 10, - isZoomEnabled = true, - downloadUtils = component.downloadUtils, - onForward = { Toast.makeText(context, notImplemented, Toast.LENGTH_SHORT).show() }, - onDelete = { Toast.makeText(context, notImplemented, Toast.LENGTH_SHORT).show() }, - onCopyLink = { Toast.makeText(context, notImplemented, Toast.LENGTH_SHORT).show() }, - onCopyText = { Toast.makeText(context, notImplemented, Toast.LENGTH_SHORT).show() }, - caption = state.fullScreenVideoCaption, - fileId = fileId, - supportsStreaming = supportsStreaming - ) - } - } - - AnimatedVisibility( - visible = state.miniAppUrl != null, - enter = slideInVertically(initialOffsetY = { it }) + fadeIn(), - exit = slideOutVertically(targetOffsetY = { it }) + fadeOut() - ) { - if (state.miniAppUrl != null && state.miniAppName != null) { - MiniAppViewer( - baseUrl = state.miniAppUrl.toString(), - botName = title, - onDismiss = { component.onDismissMiniApp() }, - chatId = state.chatId, - botUserId = state.user!!.id, - messageRepository = component.messageRepository, - ) - } - } - - AnimatedVisibility( - visible = state.isStatisticsVisible, - enter = slideInVertically(initialOffsetY = { it }) + fadeIn(), - exit = slideOutVertically(targetOffsetY = { it }) + fadeOut() - ) { - if (state.statistics != null) { - StatisticsViewer( - title = stringResource(R.string.statistics_title), - data = state.statistics!!, - onDismiss = component::onDismissStatistics, - onLoadGraph = component::onLoadStatisticsGraph - ) - } - } - - AnimatedVisibility( - visible = state.isRevenueStatisticsVisible, - enter = slideInVertically(initialOffsetY = { it }) + fadeIn(), - exit = slideOutVertically(targetOffsetY = { it }) + fadeOut() - ) { - if (state.revenueStatistics != null) { - StatisticsViewer( - title = stringResource(R.string.revenue_title), - data = state.revenueStatistics!!, - onDismiss = component::onDismissStatistics, - onLoadGraph = component::onLoadStatisticsGraph - ) - } - } - - ProfileQRDialog( - state = state, - onDismiss = component::onDismissQRCode - ) - - ProfileReportDialog( - state = state, - onDismiss = component::onDismissReport, - onReport = component::onReport - ) - - if (showLeaveSheet) { - ConfirmationSheet( - icon = Icons.AutoMirrored.Rounded.ExitToApp, - title = stringResource(R.string.leave_chat_title), - description = stringResource(R.string.leave_chat_confirmation), - confirmText = stringResource(R.string.action_leave), - onConfirm = { - component.onLeave() - showLeaveSheet = false - }, - onDismiss = { showLeaveSheet = false } - ) - } - - if (showDeleteChatSheet && !isGroupOrChannel) { - ConfirmationSheet( - icon = Icons.Rounded.Delete, - title = stringResource(R.string.delete_chat_title), - description = stringResource(R.string.delete_chat_confirmation), - confirmText = stringResource(R.string.action_delete_chat), - onConfirm = { - component.onDeleteChat() - showDeleteChatSheet = false - }, - onDismiss = { showDeleteChatSheet = false } - ) - } - - if (showBlockSheet && canBlockTopBar) { - ConfirmationSheet( - icon = Icons.Rounded.Block, - title = if (state.isBlocked) stringResource(R.string.unblock_user_title) else stringResource(R.string.block_user_title), - description = if (state.isBlocked) stringResource(R.string.unblock_user_confirmation) else stringResource( - R.string.block_user_confirmation - ), - confirmText = if (state.isBlocked) stringResource(R.string.privacy_unblock_action) else stringResource(R.string.action_block), - onConfirm = { - component.onToggleBlockUser() - showBlockSheet = false - }, - onDismiss = { showBlockSheet = false }, - isDestructive = !state.isBlocked - ) - } - - if (showEditContactDialog && canEditContactTopBar && state.user != null) { - ModalBottomSheet( - onDismissRequest = { showEditContactDialog = false }, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp), - sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 32.dp) - ) { - Text( - text = stringResource(R.string.edit_contact_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = androidx.compose.ui.text.font.FontWeight.Bold - ) - - Spacer(modifier = Modifier.height(12.dp)) - - SettingsTextField( - value = editContactFirstName, - onValueChange = { editContactFirstName = it }, - placeholder = stringResource(R.string.first_name_label), - icon = Icons.Rounded.Person, - position = ItemPosition.TOP, - singleLine = true, - modifier = Modifier.fillMaxWidth() - ) - - SettingsTextField( - value = editContactLastName, - onValueChange = { editContactLastName = it }, - placeholder = stringResource(R.string.last_name_label), - icon = Icons.Rounded.Edit, - position = ItemPosition.BOTTOM, - singleLine = true, - modifier = Modifier.fillMaxWidth() - ) - - Spacer(modifier = Modifier.height(16.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - OutlinedButton( - onClick = { showEditContactDialog = false }, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text( - stringResource(R.string.cancel_button), - fontSize = 16.sp, - fontWeight = androidx.compose.ui.text.font.FontWeight.Bold - ) - } - - Button( - onClick = { - component.onEditContact(editContactFirstName, editContactLastName) - showEditContactDialog = false - }, - enabled = editContactFirstName.isNotBlank(), - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text( - stringResource(R.string.action_save), - fontSize = 16.sp, - fontWeight = androidx.compose.ui.text.font.FontWeight.Bold - ) - } - } - } - } - } - - if (state.miniAppUrl == null) { - ProfilePermissionsDialog( - state = state, - onDismiss = component::onDismissPermissions, - onTogglePermission = component::onTogglePermission - ) - - ProfileTOSDialog( - state = state, - onDismiss = component::onDismissTOS, - onAccept = component::onAcceptTOS - ) - } - - state.selectedLocation?.let { location -> - LocationViewer( - location = location, - onDismiss = component::onDismissLocation - ) - } - } -} - -@Composable -private fun ProfileHeaderSkeleton( - progress: Float, - contentPadding: PaddingValues -) { - val shimmer = rememberShimmerBrush() - val screenHeight = LocalConfiguration.current.screenHeightDp.dp - val titleWidth = androidx.compose.ui.unit.lerp(220.dp, 124.dp, progress) - val subtitleWidth = androidx.compose.ui.unit.lerp(132.dp, 88.dp, progress) - val avatarCornerPercent = (100 * (1f - progress)).toInt() - - BoxWithConstraints( - modifier = Modifier - .fillMaxWidth() - .padding(contentPadding) - ) { - val headerHeight = maxWidth.coerceAtMost(screenHeight * 0.6f) - - Box( - modifier = Modifier - .fillMaxWidth() - .height(headerHeight) - .clip(RoundedCornerShape(avatarCornerPercent)) - .background(shimmer) - ) { - Column( - modifier = Modifier - .align(Alignment.BottomStart) - .padding(horizontal = 20.dp, vertical = 32.dp) - ) { - Box( - modifier = Modifier - .height(22.dp) - .width(titleWidth) - .clip(RoundedCornerShape(10.dp)) - .background(shimmer) - ) - Spacer(modifier = Modifier.height(12.dp)) - Box( - modifier = Modifier - .height(16.dp) - .width(subtitleWidth) - .clip(RoundedCornerShape(10.dp)) - .background(shimmer) - ) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/ProfileStore.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/ProfileStore.kt deleted file mode 100644 index 06baaf5d..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/ProfileStore.kt +++ /dev/null @@ -1,58 +0,0 @@ -package org.monogram.presentation.features.profile - -import com.arkivanov.mvikotlin.core.store.Store -import org.monogram.domain.models.ChatPermissionsModel -import org.monogram.domain.models.MessageModel -import org.monogram.domain.repository.ChatMemberStatus - -interface ProfileStore : Store { - - sealed class Intent { - object Back : Intent() - data class TabSelected(val index: Int) : Intent() - data class MessageClick(val message: MessageModel) : Intent() - data class MessageLongClick(val message: MessageModel) : Intent() - object AvatarClick : Intent() - object DismissViewer : Intent() - object LoadMoreMedia : Intent() - data class OpenMiniApp(val url: String, val name: String, val chatId: Long) : Intent() - object DismissMiniApp : Intent() - object ToggleMute : Intent() - object Edit : Intent() - object ShowQRCode : Intent() - object DismissQRCode : Intent() - object SendMessage : Intent() - object Leave : Intent() - object JoinChat : Intent() - data class Report(val reason: String) : Intent() - object DismissReport : Intent() - object ShowReport : Intent() - object ShowLogs : Intent() - data class MemberClick(val userId: Long) : Intent() - data class MemberLongClick(val userId: Long) : Intent() - data class UpdateChatTitle(val title: String) : Intent() - data class UpdateChatDescription(val description: String) : Intent() - data class UpdateChatUsername(val username: String) : Intent() - data class UpdateChatPermissions(val permissions: ChatPermissionsModel) : Intent() - data class UpdateChatSlowModeDelay(val delay: Int) : Intent() - data class UpdateMemberStatus(val userId: Long, val status: ChatMemberStatus) : Intent() - object ShowStatistics : Intent() - object ShowRevenueStatistics : Intent() - object DismissStatistics : Intent() - data class LoadStatisticsGraph(val token: String) : Intent() - data class DownloadMedia(val message: MessageModel) : Intent() - object LinkedChatClick : Intent() - object ShowPermissions : Intent() - object DismissPermissions : Intent() - data class TogglePermission(val permission: String) : Intent() - object AcceptTOS : Intent() - object DismissTOS : Intent() - data class LocationClick(val lat: Double, val lon: Double, val address: String) : Intent() - object DismissLocation : Intent() - data class UpdateState(val state: ProfileComponent.State) : Intent() - } - - sealed class Label { - object Back : Label() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/ProfileStoreFactory.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/ProfileStoreFactory.kt deleted file mode 100644 index d8233c02..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/ProfileStoreFactory.kt +++ /dev/null @@ -1,82 +0,0 @@ -package org.monogram.presentation.features.profile - -import com.arkivanov.mvikotlin.core.store.Reducer -import com.arkivanov.mvikotlin.core.store.Store -import com.arkivanov.mvikotlin.core.store.StoreFactory -import com.arkivanov.mvikotlin.extensions.coroutines.CoroutineExecutor -import org.monogram.presentation.features.profile.ProfileStore.Intent -import org.monogram.presentation.features.profile.ProfileStore.Label - -class ProfileStoreFactory( - private val storeFactory: StoreFactory, - private val component: DefaultProfileComponent -) { - - fun create(): ProfileStore = - object : ProfileStore, Store by storeFactory.create( - name = "ProfileStore", - initialState = component.state.value, - executorFactory = ::ExecutorImpl, - reducer = ReducerImpl - ) {} - - private inner class ExecutorImpl : CoroutineExecutor() { - override fun executeIntent(intent: Intent) { - when (intent) { - Intent.Back -> component.onBack() - is Intent.TabSelected -> component.onTabSelected(intent.index) - is Intent.MessageClick -> component.onMessageClick(intent.message) - is Intent.MessageLongClick -> component.onMessageLongClick(intent.message) - Intent.AvatarClick -> component.onAvatarClick() - Intent.DismissViewer -> component.onDismissViewer() - Intent.LoadMoreMedia -> component.onLoadMoreMedia() - is Intent.OpenMiniApp -> component.onOpenMiniApp(intent.url, intent.name, intent.chatId) - Intent.DismissMiniApp -> component.onDismissMiniApp() - Intent.ToggleMute -> component.onToggleMute() - Intent.Edit -> component.onEdit() - Intent.ShowQRCode -> component.onShowQRCode() - Intent.DismissQRCode -> component.onDismissQRCode() - Intent.SendMessage -> component.onSendMessage() - Intent.Leave -> component.onLeave() - Intent.JoinChat -> component.onJoinChat() - is Intent.Report -> component.onReport(intent.reason) - Intent.DismissReport -> component.onDismissReport() - Intent.ShowReport -> component.onShowReport() - Intent.ShowLogs -> component.onShowLogs() - is Intent.MemberClick -> component.onMemberClick(intent.userId) - is Intent.MemberLongClick -> component.onMemberLongClick(intent.userId) - is Intent.UpdateChatTitle -> component.onUpdateChatTitle(intent.title) - is Intent.UpdateChatDescription -> component.onUpdateChatDescription(intent.description) - is Intent.UpdateChatUsername -> component.onUpdateChatUsername(intent.username) - is Intent.UpdateChatPermissions -> component.onUpdateChatPermissions(intent.permissions) - is Intent.UpdateChatSlowModeDelay -> component.onUpdateChatSlowModeDelay(intent.delay) - is Intent.UpdateMemberStatus -> component.onUpdateMemberStatus(intent.userId, intent.status) - Intent.ShowStatistics -> component.onShowStatistics() - Intent.ShowRevenueStatistics -> component.onShowRevenueStatistics() - Intent.DismissStatistics -> component.onDismissStatistics() - is Intent.LoadStatisticsGraph -> component.onLoadStatisticsGraph(intent.token) - is Intent.DownloadMedia -> component.onDownloadMedia(intent.message) - Intent.LinkedChatClick -> component.onLinkedChatClick() - Intent.ShowPermissions -> component.onShowPermissions() - Intent.DismissPermissions -> component.onDismissPermissions() - is Intent.TogglePermission -> component.onTogglePermission(intent.permission) - Intent.AcceptTOS -> component.onAcceptTOS() - Intent.DismissTOS -> component.onDismissTOS() - is Intent.LocationClick -> component.onLocationClick(intent.lat, intent.lon, intent.address) - Intent.DismissLocation -> component.onDismissLocation() - is Intent.UpdateState -> dispatch(Message.UpdateState(intent.state)) - } - } - } - - private object ReducerImpl : Reducer { - override fun ProfileComponent.State.reduce(msg: Message): ProfileComponent.State = - when (msg) { - is Message.UpdateState -> msg.state - } - } - - sealed class Message { - data class UpdateState(val state: ProfileComponent.State) : Message() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/AdminManageComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/admin/AdminManageComponent.kt deleted file mode 100644 index ab976958..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/AdminManageComponent.kt +++ /dev/null @@ -1,31 +0,0 @@ -package org.monogram.presentation.features.profile.admin - -import com.arkivanov.decompose.value.Value -import org.monogram.domain.models.GroupMemberModel -import org.monogram.domain.repository.ChatMemberStatus -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -interface AdminManageComponent { - val state: Value - val videoPlayerPool: VideoPlayerPool - - fun onBack() - fun onSave() - fun onTogglePermission(permission: Permission) - fun onUpdateCustomTitle(title: String) - - data class State( - val chatId: Long, - val userId: Long, - val member: GroupMemberModel? = null, - val isLoading: Boolean = false, - val currentStatus: ChatMemberStatus? = null, - val isChannel: Boolean = false - ) - - enum class Permission { - MANAGE_CHAT, CHANGE_INFO, POST_MESSAGES, EDIT_MESSAGES, DELETE_MESSAGES, - INVITE_USERS, RESTRICT_MEMBERS, PIN_MESSAGES, MANAGE_TOPICS, PROMOTE_MEMBERS, - MANAGE_VIDEO_CHATS, POST_STORIES, EDIT_STORIES, DELETE_STORIES, ANONYMOUS - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/AdminManageContent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/admin/AdminManageContent.kt deleted file mode 100644 index c79d2286..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/AdminManageContent.kt +++ /dev/null @@ -1,298 +0,0 @@ -package org.monogram.presentation.features.profile.admin - -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.domain.repository.ChatMemberStatus -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.features.chats.chatList.components.SettingsTextField -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsSwitchTile - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun AdminManageContent(component: AdminManageComponent) { - val state by component.state.subscribeAsState() - val status = state.currentStatus as? ChatMemberStatus.Administrator - - Scaffold( - topBar = { - TopAppBar( - title = { - Text( - text = stringResource(R.string.admin_rights), - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - }, - navigationIcon = { - IconButton(onClick = component::onBack) { - Icon(Icons.AutoMirrored.Rounded.ArrowBack, contentDescription = stringResource(R.string.back)) - } - }, - actions = { - IconButton( - onClick = component::onSave, - enabled = !state.isLoading - ) { - Icon( - Icons.Rounded.Check, - contentDescription = stringResource(R.string.save), - tint = if (state.isLoading) { - MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f) - } else { - MaterialTheme.colorScheme.primary - } - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background - ) - ) - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - if (state.isLoading) { - Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { - CircularProgressIndicator() - } - } else { - LazyColumn( - modifier = Modifier - .fillMaxSize() - .padding(top = padding.calculateTopPadding()), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, top = 0.dp, bottom = 16.dp) - ) { - item { - state.member?.user?.let { user -> - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 16.dp) - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.padding(16.dp) - ) { - Avatar( - path = user.avatarPath, - fallbackPath = user.personalAvatarPath, - name = user.firstName, - size = 64.dp, - videoPlayerPool = component.videoPlayerPool - ) - Spacer(Modifier.width(16.dp)) - Column(modifier = Modifier.weight(1f)) { - Text( - text = listOfNotNull(user.firstName, user.lastName).joinToString(" "), - style = MaterialTheme.typography.titleLarge, - fontWeight = FontWeight.Bold - ) - state.member?.rank?.let { rank -> - if (rank.isNotEmpty()) { - Text( - text = rank, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.primary - ) - } - } - } - IconButton(onClick = { /* TODO: Edit rank or user */ }) { - Icon( - imageVector = Icons.Rounded.Edit, - contentDescription = stringResource(R.string.edit), - tint = MaterialTheme.colorScheme.primary - ) - } - } - } - } - } - - item { - SectionHeader(stringResource(R.string.custom_title)) - SettingsTextField( - value = status?.customTitle ?: "", - onValueChange = component::onUpdateCustomTitle, - placeholder = stringResource(R.string.custom_title), - icon = Icons.Rounded.Badge, - position = ItemPosition.STANDALONE, - singleLine = true - ) - - Text( - text = stringResource(R.string.custom_title_description), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(start = 16.dp, top = 8.dp, bottom = 16.dp) - ) - } - - item { - SectionHeader(stringResource(R.string.what_can_this_admin_do)) - PermissionSwitch( - title = stringResource(R.string.permission_manage_chat), - icon = Icons.Rounded.Settings, - checked = status?.canManageChat == true, - onCheckedChange = { component.onTogglePermission(AdminManageComponent.Permission.MANAGE_CHAT) }, - position = ItemPosition.TOP - ) - PermissionSwitch( - title = stringResource(R.string.permission_change_chat_info), - icon = Icons.Rounded.Info, - checked = status?.canChangeInfo == true, - onCheckedChange = { component.onTogglePermission(AdminManageComponent.Permission.CHANGE_INFO) }, - position = ItemPosition.MIDDLE - ) - if (state.isChannel) { - PermissionSwitch( - title = stringResource(R.string.permission_post_messages), - icon = Icons.Rounded.Edit, - checked = status?.canPostMessages == true, - onCheckedChange = { component.onTogglePermission(AdminManageComponent.Permission.POST_MESSAGES) }, - position = ItemPosition.MIDDLE - ) - PermissionSwitch( - title = stringResource(R.string.permission_edit_messages), - icon = Icons.Rounded.EditNote, - checked = status?.canEditMessages == true, - onCheckedChange = { component.onTogglePermission(AdminManageComponent.Permission.EDIT_MESSAGES) }, - position = ItemPosition.MIDDLE - ) - } - PermissionSwitch( - title = stringResource(R.string.permission_delete_messages), - icon = Icons.Rounded.Delete, - checked = status?.canDeleteMessages == true, - onCheckedChange = { component.onTogglePermission(AdminManageComponent.Permission.DELETE_MESSAGES) }, - position = ItemPosition.MIDDLE - ) - if (!state.isChannel) { - PermissionSwitch( - title = stringResource(R.string.permission_restrict_members), - icon = Icons.Rounded.Block, - checked = status?.canRestrictMembers == true, - onCheckedChange = { component.onTogglePermission(AdminManageComponent.Permission.RESTRICT_MEMBERS) }, - position = ItemPosition.MIDDLE - ) - } - PermissionSwitch( - title = stringResource(R.string.permission_invite_users), - icon = Icons.Rounded.PersonAdd, - checked = status?.canInviteUsers == true, - onCheckedChange = { component.onTogglePermission(AdminManageComponent.Permission.INVITE_USERS) }, - position = ItemPosition.MIDDLE - ) - if (!state.isChannel) { - PermissionSwitch( - title = stringResource(R.string.permission_pin_messages), - icon = Icons.Rounded.PushPin, - checked = status?.canPinMessages == true, - onCheckedChange = { component.onTogglePermission(AdminManageComponent.Permission.PIN_MESSAGES) }, - position = ItemPosition.MIDDLE - ) - PermissionSwitch( - title = stringResource(R.string.permission_manage_topics), - icon = Icons.Rounded.Topic, - checked = status?.canManageTopics == true, - onCheckedChange = { component.onTogglePermission(AdminManageComponent.Permission.MANAGE_TOPICS) }, - position = ItemPosition.MIDDLE - ) - } - PermissionSwitch( - title = stringResource(R.string.permission_manage_video_chats), - icon = Icons.Rounded.Videocam, - checked = status?.canManageVideoChats == true, - onCheckedChange = { component.onTogglePermission(AdminManageComponent.Permission.MANAGE_VIDEO_CHATS) }, - position = ItemPosition.MIDDLE - ) - PermissionSwitch( - title = stringResource(R.string.permission_post_stories), - icon = Icons.Rounded.AddPhotoAlternate, - checked = status?.canPostStories == true, - onCheckedChange = { component.onTogglePermission(AdminManageComponent.Permission.POST_STORIES) }, - position = ItemPosition.MIDDLE - ) - PermissionSwitch( - title = stringResource(R.string.permission_edit_stories), - icon = Icons.Rounded.AutoFixHigh, - checked = status?.canEditStories == true, - onCheckedChange = { component.onTogglePermission(AdminManageComponent.Permission.EDIT_STORIES) }, - position = ItemPosition.MIDDLE - ) - PermissionSwitch( - title = stringResource(R.string.permission_delete_stories), - icon = Icons.Rounded.DeleteForever, - checked = status?.canDeleteStories == true, - onCheckedChange = { component.onTogglePermission(AdminManageComponent.Permission.DELETE_STORIES) }, - position = ItemPosition.MIDDLE - ) - PermissionSwitch( - title = stringResource(R.string.permission_add_new_admins), - icon = Icons.Rounded.AddModerator, - checked = status?.canPromoteMembers == true, - onCheckedChange = { component.onTogglePermission(AdminManageComponent.Permission.PROMOTE_MEMBERS) }, - position = ItemPosition.MIDDLE - ) - PermissionSwitch( - title = stringResource(R.string.permission_remain_anonymous), - icon = Icons.Rounded.VisibilityOff, - checked = status?.isAnonymous == true, - onCheckedChange = { component.onTogglePermission(AdminManageComponent.Permission.ANONYMOUS) }, - position = ItemPosition.BOTTOM - ) - } - } - } - } -} - -@Composable -private fun SectionHeader(text: String) { - Text( - text = text, - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp, top = 16.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) -} - -@Composable -private fun PermissionSwitch( - title: String, - icon: ImageVector, - checked: Boolean, - onCheckedChange: (Boolean) -> Unit, - position: ItemPosition -) { - SettingsSwitchTile( - title = title, - icon = icon, - iconColor = MaterialTheme.colorScheme.primary, - checked = checked, - onCheckedChange = onCheckedChange, - position = position - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/ChatEditComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/admin/ChatEditComponent.kt deleted file mode 100644 index a3eb7612..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/ChatEditComponent.kt +++ /dev/null @@ -1,40 +0,0 @@ -package org.monogram.presentation.features.profile.admin - -import com.arkivanov.decompose.value.Value -import org.monogram.domain.models.ChatModel -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -interface ChatEditComponent { - val state: Value - val videoPlayerPool: VideoPlayerPool - - fun onBack() - fun onUpdateTitle(title: String) - fun onUpdateDescription(description: String) - fun onUpdateUsername(username: String) - fun onTogglePublic(isPublic: Boolean) - fun onToggleTopics(enabled: Boolean) - fun onToggleAutoTranslate(enabled: Boolean) - fun onChangeAvatar(path: String) - fun onSave() - fun onDeleteChat() - - fun onManageAdmins() - fun onManageMembers() - fun onManageBlacklist() - fun onManagePermissions() - - data class State( - val chatId: Long, - val chat: ChatModel? = null, - val title: String = "", - val description: String = "", - val username: String = "", - val isPublic: Boolean = false, - val isForum: Boolean = false, - val isTranslatable: Boolean = false, - val avatarPath: String? = null, - val isLoading: Boolean = false, - val canDelete: Boolean = false - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/ChatEditContent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/admin/ChatEditContent.kt deleted file mode 100644 index 7ca4ce8c..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/ChatEditContent.kt +++ /dev/null @@ -1,285 +0,0 @@ -package org.monogram.presentation.features.profile.admin - -import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.PickVisualMediaRequest -import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.ui.ConfirmationSheet -import org.monogram.presentation.core.util.FileUtils -import org.monogram.presentation.features.chats.chatList.components.SettingsTextField -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsSwitchTile -import org.monogram.presentation.core.ui.SettingsTile - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ChatEditContent(component: ChatEditComponent) { - val state by component.state.subscribeAsState() - val isChannel = state.chat?.isChannel == true - val context = LocalContext.current - var showDeleteChatSheet by remember { mutableStateOf(false) } - - val photoPickerLauncher = rememberLauncherForActivityResult( - contract = ActivityResultContracts.PickVisualMedia(), - onResult = { uri -> - uri?.let { - val path = FileUtils.getPath(context, it) - component.onChangeAvatar(path.toString()) - } - } - ) - - Scaffold( - topBar = { - TopAppBar( - title = { - Text( - text = if (isChannel) stringResource(R.string.edit_channel) else stringResource(R.string.edit_group), - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - }, - navigationIcon = { - IconButton(onClick = component::onBack) { - Icon(Icons.AutoMirrored.Rounded.ArrowBack, contentDescription = stringResource(R.string.back)) - } - }, - actions = { - IconButton(onClick = component::onSave, enabled = !state.isLoading) { - Icon( - Icons.Rounded.Check, - contentDescription = stringResource(R.string.save), - tint = MaterialTheme.colorScheme.primary - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background - ) - ) - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - LazyColumn( - modifier = Modifier - .fillMaxSize() - .padding(top = padding.calculateTopPadding()), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, top = 0.dp, bottom = 16.dp) - ) { - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 24.dp), - contentAlignment = Alignment.Center - ) { - Box( - modifier = Modifier - .size(100.dp) - .clip(CircleShape) - .clickable { - photoPickerLauncher.launch( - PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly) - ) - }, - contentAlignment = Alignment.Center - ) { - Avatar(path = state.avatarPath, name = state.title, size = 100.dp, videoPlayerPool = component.videoPlayerPool) - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.Black.copy(alpha = 0.4f)), - contentAlignment = Alignment.Center - ) { - Icon( - Icons.Rounded.CameraAlt, - null, - tint = Color.White, - modifier = Modifier.size(32.dp) - ) - } - } - } - } - - item { - SettingsTextField( - value = state.title, - onValueChange = component::onUpdateTitle, - placeholder = if (isChannel) stringResource(R.string.channel_name) else stringResource(R.string.group_name), - icon = Icons.Rounded.Title, - position = ItemPosition.TOP - ) - SettingsTextField( - value = state.description, - onValueChange = component::onUpdateDescription, - placeholder = stringResource(R.string.description), - icon = Icons.Rounded.Description, - position = ItemPosition.BOTTOM, - singleLine = false - ) - } - - item { - SectionHeader(stringResource(R.string.settings)) - SettingsSwitchTile( - title = if (isChannel) stringResource(R.string.public_channel) else stringResource(R.string.public_group), - icon = Icons.Rounded.Public, - checked = state.isPublic, - onCheckedChange = component::onTogglePublic, - iconColor = MaterialTheme.colorScheme.primary, - position = ItemPosition.TOP - ) - if (state.isPublic) { - SettingsTextField( - value = state.username, - onValueChange = component::onUpdateUsername, - placeholder = stringResource(R.string.username), - icon = Icons.Rounded.AlternateEmail, - position = ItemPosition.MIDDLE - ) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(4.dp), - modifier = Modifier.fillMaxWidth() - ) { - Text( - text = "https://t.me/${state.username.ifEmpty { "username" }}", - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.primary, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp) - ) - } - Spacer(Modifier.height(2.dp)) - } - - if (isChannel) { - SettingsSwitchTile( - title = stringResource(R.string.auto_translate), - icon = Icons.Rounded.Translate, - checked = state.isTranslatable, - onCheckedChange = component::onToggleAutoTranslate, - iconColor = MaterialTheme.colorScheme.primary, - position = ItemPosition.BOTTOM - ) - } else { - SettingsSwitchTile( - title = stringResource(R.string.topics), - icon = Icons.Rounded.Topic, - checked = state.isForum, - onCheckedChange = component::onToggleTopics, - iconColor = MaterialTheme.colorScheme.primary, - position = ItemPosition.BOTTOM - ) - } - } - - item { - SectionHeader(stringResource(R.string.management)) - SettingsTile( - title = stringResource(R.string.administrators), - icon = Icons.Rounded.AdminPanelSettings, - iconColor = MaterialTheme.colorScheme.primary, - position = ItemPosition.TOP, - onClick = component::onManageAdmins - ) - SettingsTile( - title = if (isChannel) stringResource(R.string.subscribers) else stringResource(R.string.members), - icon = Icons.Rounded.Groups, - iconColor = MaterialTheme.colorScheme.primary, - position = ItemPosition.MIDDLE, - onClick = component::onManageMembers - ) - SettingsTile( - title = stringResource(R.string.permissions), - icon = Icons.Rounded.Lock, - iconColor = MaterialTheme.colorScheme.primary, - position = ItemPosition.MIDDLE, - onClick = component::onManagePermissions - ) - SettingsTile( - title = stringResource(R.string.blacklist), - icon = Icons.Rounded.Block, - iconColor = MaterialTheme.colorScheme.error, - position = ItemPosition.BOTTOM, - onClick = component::onManageBlacklist - ) - } - - item { - Spacer(Modifier.height(24.dp)) - Button( - onClick = { showDeleteChatSheet = true }, - colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.errorContainer, - contentColor = MaterialTheme.colorScheme.error - ), - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(24.dp), - contentPadding = PaddingValues(16.dp) - ) { - Icon(Icons.Rounded.Delete, contentDescription = null) - Spacer(Modifier.width(8.dp)) - Text( - if (isChannel) stringResource(R.string.delete_channel) else stringResource(R.string.delete_group), - fontWeight = FontWeight.Bold - ) - } - } - } - } - - if (showDeleteChatSheet) { - ConfirmationSheet( - icon = Icons.Rounded.Delete, - title = if (isChannel) stringResource(R.string.delete_channel_title) else stringResource(R.string.delete_group_title), - description = if (isChannel) stringResource(R.string.delete_channel_confirmation) else stringResource(R.string.delete_group_confirmation), - confirmText = stringResource(R.string.action_delete), - onConfirm = { - component.onDeleteChat() - showDeleteChatSheet = false - }, - onDismiss = { showDeleteChatSheet = false } - ) - } -} - -@Composable -private fun SectionHeader(text: String) { - Text( - text = text, - modifier = Modifier.padding(start = 12.dp, top = 24.dp, bottom = 8.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/ChatPermissionsComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/admin/ChatPermissionsComponent.kt deleted file mode 100644 index 1c68d382..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/ChatPermissionsComponent.kt +++ /dev/null @@ -1,23 +0,0 @@ -package org.monogram.presentation.features.profile.admin - -import com.arkivanov.decompose.value.Value -import org.monogram.domain.models.ChatPermissionsModel - -interface ChatPermissionsComponent { - val state: Value - - fun onBack() - fun onSave() - fun onTogglePermission(permission: Permission) - - data class State( - val chatId: Long, - val permissions: ChatPermissionsModel = ChatPermissionsModel(), - val isLoading: Boolean = false - ) - - enum class Permission { - SEND_MESSAGES, SEND_MEDIA, SEND_STICKERS, SEND_POLLS, - EMBED_LINKS, ADD_MEMBERS, PIN_MESSAGES, CHANGE_INFO, MANAGE_TOPICS - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/ChatPermissionsContent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/admin/ChatPermissionsContent.kt deleted file mode 100644 index 6f97044d..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/ChatPermissionsContent.kt +++ /dev/null @@ -1,189 +0,0 @@ -package org.monogram.presentation.features.profile.admin - -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.automirrored.rounded.Chat -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.input.nestedscroll.nestedScroll -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsSwitchTile - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ChatPermissionsContent(component: ChatPermissionsComponent) { - val state by component.state.subscribeAsState() - val permissions = state.permissions - val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior() - - Scaffold( - modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), - topBar = { - TopAppBar( - title = { - Text( - text = stringResource(R.string.permissions), - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - }, - navigationIcon = { - IconButton(onClick = component::onBack) { - Icon(Icons.AutoMirrored.Rounded.ArrowBack, contentDescription = stringResource(R.string.back)) - } - }, - actions = { - IconButton(onClick = component::onSave) { - Icon( - Icons.Rounded.Check, - contentDescription = stringResource(R.string.save), - tint = MaterialTheme.colorScheme.primary - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background - ), - scrollBehavior = scrollBehavior - ) - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - LazyColumn( - modifier = Modifier - .fillMaxSize() - .padding(padding), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, bottom = 16.dp) - ) { - item { - SectionHeader(stringResource(R.string.what_can_members_do)) - } - item { - PermissionItem( - stringResource(R.string.permission_send_messages), - Icons.AutoMirrored.Rounded.Chat, - permissions.canSendBasicMessages, - { component.onTogglePermission(ChatPermissionsComponent.Permission.SEND_MESSAGES) }, - ItemPosition.TOP - ) - } - item { - PermissionItem( - stringResource(R.string.permission_send_media), - Icons.Rounded.Image, - permissions.canSendPhotos, - { component.onTogglePermission(ChatPermissionsComponent.Permission.SEND_MEDIA) }, - ItemPosition.MIDDLE - ) - } - item { - PermissionItem( - stringResource(R.string.permission_send_stickers_gifs), - Icons.Rounded.EmojiEmotions, - permissions.canSendOtherMessages, - { component.onTogglePermission(ChatPermissionsComponent.Permission.SEND_STICKERS) }, - ItemPosition.MIDDLE - ) - } - item { - PermissionItem( - stringResource(R.string.permission_send_polls), - Icons.Rounded.Poll, - permissions.canSendPolls, - { component.onTogglePermission(ChatPermissionsComponent.Permission.SEND_POLLS) }, - ItemPosition.MIDDLE - ) - } - item { - PermissionItem( - stringResource(R.string.permission_embed_links), - Icons.Rounded.Link, - permissions.canAddLinkPreviews, - { component.onTogglePermission(ChatPermissionsComponent.Permission.EMBED_LINKS) }, - ItemPosition.MIDDLE - ) - } - item { - PermissionItem( - stringResource(R.string.permission_add_members), - Icons.Rounded.PersonAdd, - permissions.canInviteUsers, - { component.onTogglePermission(ChatPermissionsComponent.Permission.ADD_MEMBERS) }, - ItemPosition.MIDDLE - ) - } - item { - PermissionItem( - stringResource(R.string.permission_pin_messages), - Icons.Rounded.PushPin, - permissions.canPinMessages, - { component.onTogglePermission(ChatPermissionsComponent.Permission.PIN_MESSAGES) }, - ItemPosition.MIDDLE - ) - } - item { - PermissionItem( - stringResource(R.string.permission_change_chat_info), - Icons.Rounded.Info, - permissions.canChangeInfo, - { component.onTogglePermission(ChatPermissionsComponent.Permission.CHANGE_INFO) }, - ItemPosition.MIDDLE - ) - } -// item { -// PermissionItem( -// "Manage Topics", -// Icons.Rounded.Topic, -// permissions.canManageTopics, -// { component.onTogglePermission(ChatPermissionsComponent.Permission.MANAGE_TOPICS) }, -// ItemPosition.BOTTOM -// ) -// } - } - } -} - -@Composable -private fun SectionHeader(text: String) { - Text( - text = text, - modifier = Modifier.padding(start = 12.dp, top = 16.dp, bottom = 8.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) -} - -@Composable -private fun PermissionItem( - title: String, - icon: ImageVector, - checked: Boolean, - onCheckedChange: (Boolean) -> Unit, - position: ItemPosition -) { - SettingsSwitchTile( - title = title, - icon = icon, - checked = checked, - onCheckedChange = onCheckedChange, - iconColor = MaterialTheme.colorScheme.primary, - position = position - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/DefaultAdminManageComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/admin/DefaultAdminManageComponent.kt deleted file mode 100644 index 607d6b64..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/DefaultAdminManageComponent.kt +++ /dev/null @@ -1,124 +0,0 @@ -package org.monogram.presentation.features.profile.admin - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.launch -import org.monogram.domain.repository.ChatMemberStatus -import org.monogram.domain.repository.ChatsListRepository -import org.monogram.domain.repository.UserRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.root.AppComponentContext - -class DefaultAdminManageComponent( - context: AppComponentContext, - private val chatId: Long, - private val userId: Long, - private val onBackClicked: () -> Unit -) : AdminManageComponent, AppComponentContext by context { - - private val userRepository: UserRepository = container.repositories.userRepository - private val chatsListRepository: ChatsListRepository = container.repositories.chatsListRepository - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - - private val scope = componentScope - private val _state = MutableValue(AdminManageComponent.State(chatId = chatId, userId = userId)) - override val state: Value = _state - - init { - loadMember() - } - - private fun loadMember() { - scope.launch { - _state.update { it.copy(isLoading = true) } - try { - val chat = chatsListRepository.getChatById(chatId) - val member = userRepository.getChatMember(chatId, userId) - val initialStatus = when (val status = member?.status) { - is ChatMemberStatus.Administrator -> status - is ChatMemberStatus.Creator -> ChatMemberStatus.Administrator( - customTitle = member.rank ?: "" - ) - - else -> ChatMemberStatus.Administrator( - customTitle = member?.rank ?: "", - canManageChat = false, - canChangeInfo = false, - canPostMessages = false, - canEditMessages = false, - canDeleteMessages = false, - canInviteUsers = false, - canRestrictMembers = false, - canPinMessages = false, - canPromoteMembers = false, - canManageVideoChats = false, - canManageTopics = false, - canPostStories = false, - canEditStories = false, - canDeleteStories = false, - canManageDirectMessages = false, - isAnonymous = false - ) - } - _state.update { - it.copy( - member = member, - currentStatus = initialStatus, - isChannel = chat?.isChannel == true - ) - } - } catch (e: Exception) { - e.printStackTrace() - } finally { - _state.update { it.copy(isLoading = false) } - } - } - } - - override fun onBack() { - onBackClicked() - } - - override fun onSave() { - val status = _state.value.currentStatus ?: return - _state.update { it.copy(isLoading = true) } - scope.launch { - try { - userRepository.setChatMemberStatus(chatId, userId, status) - onBackClicked() - } catch (e: Exception) { - e.printStackTrace() - _state.update { it.copy(isLoading = false) } - } - } - } - - override fun onTogglePermission(permission: AdminManageComponent.Permission) { - val current = _state.value.currentStatus as? ChatMemberStatus.Administrator ?: return - val updated = when (permission) { - AdminManageComponent.Permission.MANAGE_CHAT -> current.copy(canManageChat = !current.canManageChat) - AdminManageComponent.Permission.CHANGE_INFO -> current.copy(canChangeInfo = !current.canChangeInfo) - AdminManageComponent.Permission.POST_MESSAGES -> current.copy(canPostMessages = !current.canPostMessages) - AdminManageComponent.Permission.EDIT_MESSAGES -> current.copy(canEditMessages = !current.canEditMessages) - AdminManageComponent.Permission.DELETE_MESSAGES -> current.copy(canDeleteMessages = !current.canDeleteMessages) - AdminManageComponent.Permission.INVITE_USERS -> current.copy(canInviteUsers = !current.canInviteUsers) - AdminManageComponent.Permission.RESTRICT_MEMBERS -> current.copy(canRestrictMembers = !current.canRestrictMembers) - AdminManageComponent.Permission.PIN_MESSAGES -> current.copy(canPinMessages = !current.canPinMessages) - AdminManageComponent.Permission.MANAGE_TOPICS -> current.copy(canManageTopics = !current.canManageTopics) - AdminManageComponent.Permission.PROMOTE_MEMBERS -> current.copy(canPromoteMembers = !current.canPromoteMembers) - AdminManageComponent.Permission.MANAGE_VIDEO_CHATS -> current.copy(canManageVideoChats = !current.canManageVideoChats) - AdminManageComponent.Permission.POST_STORIES -> current.copy(canPostStories = !current.canPostStories) - AdminManageComponent.Permission.EDIT_STORIES -> current.copy(canEditStories = !current.canEditStories) - AdminManageComponent.Permission.DELETE_STORIES -> current.copy(canDeleteStories = !current.canDeleteStories) - AdminManageComponent.Permission.ANONYMOUS -> current.copy(isAnonymous = !current.isAnonymous) - } - _state.update { it.copy(currentStatus = updated) } - } - - override fun onUpdateCustomTitle(title: String) { - val current = _state.value.currentStatus as? ChatMemberStatus.Administrator ?: return - _state.update { it.copy(currentStatus = current.copy(customTitle = title)) } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/DefaultChatEditComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/admin/DefaultChatEditComponent.kt deleted file mode 100644 index 9405c5c7..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/DefaultChatEditComponent.kt +++ /dev/null @@ -1,127 +0,0 @@ -package org.monogram.presentation.features.profile.admin - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.launch -import org.monogram.domain.repository.ChatsListRepository -import org.monogram.domain.repository.UserRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.root.AppComponentContext - -class DefaultChatEditComponent( - context: AppComponentContext, - private val chatId: Long, - private val onBackClicked: () -> Unit, - private val onManageAdminsClicked: (Long) -> Unit, - private val onManageMembersClicked: (Long) -> Unit, - private val onManageBlacklistClicked: (Long) -> Unit, - private val onManagePermissionsClicked: (Long) -> Unit -) : ChatEditComponent, AppComponentContext by context { - - private val chatsListRepository: ChatsListRepository = container.repositories.chatsListRepository - private val userRepository: UserRepository = container.repositories.userRepository - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - - private val scope = componentScope - private val _state = MutableValue(ChatEditComponent.State(chatId = chatId)) - override val state: Value = _state - - init { - loadChatData() - } - - private fun loadChatData() { - scope.launch { - _state.update { it.copy(isLoading = true) } - val chat = chatsListRepository.getChatById(chatId) - val fullInfo = userRepository.getChatFullInfo(chatId) - if (chat != null) { - _state.update { - it.copy( - chat = chat, - title = chat.title, - description = fullInfo?.description ?: "", - username = chat.username ?: "", - isPublic = !chat.username.isNullOrEmpty(), - isForum = chat.isForum, - isTranslatable = if (chat.isChannel) chat.hasAutomaticTranslation else chat.isTranslatable, - avatarPath = chat.avatarPath, - canDelete = chat.isAdmin, - isLoading = false - ) - } - } - } - } - - override fun onBack() = onBackClicked() - - override fun onUpdateTitle(title: String) { - _state.update { it.copy(title = title) } - } - - override fun onUpdateDescription(description: String) { - _state.update { it.copy(description = description) } - } - - override fun onUpdateUsername(username: String) { - _state.update { it.copy(username = username) } - } - - override fun onTogglePublic(isPublic: Boolean) { - _state.update { it.copy(isPublic = isPublic) } - } - - override fun onToggleTopics(enabled: Boolean) { - _state.update { it.copy(isForum = enabled) } - scope.launch { - chatsListRepository.toggleChatIsForum(chatId, enabled) - } - } - - override fun onToggleAutoTranslate(enabled: Boolean) { - _state.update { it.copy(isTranslatable = enabled) } - scope.launch { - chatsListRepository.toggleChatIsTranslatable(chatId, enabled) - } - } - - override fun onChangeAvatar(path: String) { - _state.update { it.copy(avatarPath = path) } - scope.launch { - chatsListRepository.setChatPhoto(chatId, path) - } - } - - override fun onSave() { - scope.launch { - _state.update { it.copy(isLoading = true) } - val currentState = _state.value - if (currentState.title != currentState.chat?.title) { - chatsListRepository.setChatTitle(chatId, currentState.title) - } - val fullInfo = userRepository.getChatFullInfo(chatId) - if (currentState.description != (fullInfo?.description ?: "")) { - chatsListRepository.setChatDescription(chatId, currentState.description) - } - if (currentState.username != (currentState.chat?.username ?: "")) { - chatsListRepository.setChatUsername(chatId, currentState.username) - } - onBackClicked() - } - } - - override fun onDeleteChat() { - scope.launch { - chatsListRepository.deleteChats(setOf(chatId)) - onBackClicked() - } - } - - override fun onManageAdmins() = onManageAdminsClicked(chatId) - override fun onManageMembers() = onManageMembersClicked(chatId) - override fun onManageBlacklist() = onManageBlacklistClicked(chatId) - override fun onManagePermissions() = onManagePermissionsClicked(chatId) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/DefaultChatPermissionsComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/admin/DefaultChatPermissionsComponent.kt deleted file mode 100644 index f3013df9..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/DefaultChatPermissionsComponent.kt +++ /dev/null @@ -1,59 +0,0 @@ -package org.monogram.presentation.features.profile.admin - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.launch -import org.monogram.domain.repository.ChatsListRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.root.AppComponentContext - -class DefaultChatPermissionsComponent( - context: AppComponentContext, - private val chatId: Long, - private val onBackClicked: () -> Unit -) : ChatPermissionsComponent, AppComponentContext by context { - - private val chatsListRepository: ChatsListRepository = container.repositories.chatsListRepository - private val scope = componentScope - private val _state = MutableValue(ChatPermissionsComponent.State(chatId = chatId)) - override val state: Value = _state - - init { - loadPermissions() - } - - private fun loadPermissions() { - scope.launch { - val chat = chatsListRepository.getChatById(chatId) - if (chat != null) { - _state.update { it.copy(permissions = chat.permissions) } - } - } - } - - override fun onBack() = onBackClicked() - - override fun onSave() { - scope.launch { - chatsListRepository.setChatPermissions(chatId, _state.value.permissions) - onBackClicked() - } - } - - override fun onTogglePermission(permission: ChatPermissionsComponent.Permission) { - val current = _state.value.permissions - val updated = when (permission) { - ChatPermissionsComponent.Permission.SEND_MESSAGES -> current.copy(canSendBasicMessages = !current.canSendBasicMessages) - ChatPermissionsComponent.Permission.SEND_MEDIA -> current.copy(canSendPhotos = !current.canSendPhotos) // Simplified - ChatPermissionsComponent.Permission.SEND_STICKERS -> current.copy(canSendOtherMessages = !current.canSendOtherMessages) - ChatPermissionsComponent.Permission.SEND_POLLS -> current.copy(canSendPolls = !current.canSendPolls) - ChatPermissionsComponent.Permission.EMBED_LINKS -> current.copy(canAddLinkPreviews = !current.canAddLinkPreviews) - ChatPermissionsComponent.Permission.ADD_MEMBERS -> current.copy(canInviteUsers = !current.canInviteUsers) - ChatPermissionsComponent.Permission.PIN_MESSAGES -> current.copy(canPinMessages = !current.canPinMessages) - ChatPermissionsComponent.Permission.CHANGE_INFO -> current.copy(canChangeInfo = !current.canChangeInfo) - ChatPermissionsComponent.Permission.MANAGE_TOPICS -> current.copy(canCreateTopics = !current.canCreateTopics) - } - _state.update { it.copy(permissions = updated) } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/DefaultMemberListComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/admin/DefaultMemberListComponent.kt deleted file mode 100644 index 2584dd9c..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/DefaultMemberListComponent.kt +++ /dev/null @@ -1,140 +0,0 @@ -package org.monogram.presentation.features.profile.admin - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.Job -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import org.monogram.domain.models.GroupMemberModel -import org.monogram.domain.repository.ChatMemberStatus -import org.monogram.domain.repository.ChatMembersFilter -import org.monogram.domain.repository.UserRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.root.AppComponentContext - -class DefaultMemberListComponent( - context: AppComponentContext, - private val chatId: Long, - private val type: MemberListComponent.MemberListType, - private val onBackClicked: () -> Unit, - private val onMemberClicked: (Long) -> Unit, - private val onMemberLongClicked: (Long) -> Unit -) : MemberListComponent, AppComponentContext by context { - - private val userRepository: UserRepository = container.repositories.userRepository - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - - private val scope = componentScope - private val _state = MutableValue(MemberListComponent.State(chatId = chatId, type = type)) - override val state: Value = _state - - private var offset = 0 - private val limit = 50 - private var searchJob: Job? = null - - init { - loadMembers() - } - - private fun loadMembers() { - if (_state.value.isLoading || !_state.value.canLoadMore || _state.value.isSearchActive) return - - scope.launch { - _state.update { it.copy(isLoading = true) } - try { - val filter = when (type) { - MemberListComponent.MemberListType.ADMINS -> ChatMembersFilter.Administrators - MemberListComponent.MemberListType.MEMBERS -> ChatMembersFilter.Recent - MemberListComponent.MemberListType.BLACKLIST -> ChatMembersFilter.Banned - } - - val members = userRepository.getChatMembers(chatId, offset, limit, filter) - - if (members.isEmpty()) { - _state.update { it.copy(canLoadMore = false) } - } else { - offset += members.size - _state.update { - it.copy( - members = it.members + members, - canLoadMore = members.size >= limit - ) - } - } - } catch (e: Exception) { - e.printStackTrace() - } finally { - _state.update { it.copy(isLoading = false) } - } - } - } - - override fun onBack() { - if (_state.value.isSearchActive) { - onToggleSearch() - } else { - onBackClicked() - } - } - - override fun onMemberClick(member: GroupMemberModel) { - if (type == MemberListComponent.MemberListType.ADMINS) { - onMemberLongClicked(member.user.id) - } else { - onMemberClicked(member.user.id) - } - } - - override fun onMemberLongClick(member: GroupMemberModel) = onMemberLongClicked(member.user.id) - override fun onLoadMore() = loadMembers() - - override fun onSearch(query: String) { - _state.update { it.copy(searchQuery = query) } - searchJob?.cancel() - searchJob = scope.launch { - delay(300) - if (query.isBlank()) { - offset = 0 - _state.update { it.copy(members = emptyList(), canLoadMore = true) } - loadMembers() - } else { - _state.update { it.copy(isLoading = true) } - try { - val filter = ChatMembersFilter.Search(query) - val results = userRepository.getChatMembers(chatId, 0, 50, filter) - - val filtered = when (type) { - MemberListComponent.MemberListType.ADMINS -> results.filter { it.status is ChatMemberStatus.Administrator || it.status is ChatMemberStatus.Creator } - MemberListComponent.MemberListType.MEMBERS -> results.filter { it.status is ChatMemberStatus.Member } - MemberListComponent.MemberListType.BLACKLIST -> results.filter { it.status is ChatMemberStatus.Banned } - } - - _state.update { it.copy(members = filtered, canLoadMore = false) } - } finally { - _state.update { it.copy(isLoading = false) } - } - } - } - } - - override fun onToggleSearch() { - val isNowActive = !_state.value.isSearchActive - _state.update { - it.copy( - isSearchActive = isNowActive, - searchQuery = "", - members = if (isNowActive) it.members else emptyList(), - canLoadMore = !isNowActive - ) - } - if (!isNowActive) { - offset = 0 - loadMembers() - } - } - - override fun onAddMember() { - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/MemberListComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/admin/MemberListComponent.kt deleted file mode 100644 index 11585cf3..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/MemberListComponent.kt +++ /dev/null @@ -1,32 +0,0 @@ -package org.monogram.presentation.features.profile.admin - -import com.arkivanov.decompose.value.Value -import org.monogram.domain.models.GroupMemberModel -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -interface MemberListComponent { - val state: Value - val videoPlayerPool: VideoPlayerPool - - fun onBack() - fun onMemberClick(member: GroupMemberModel) - fun onMemberLongClick(member: GroupMemberModel) - fun onLoadMore() - fun onSearch(query: String) - fun onToggleSearch() - fun onAddMember() - - data class State( - val chatId: Long, - val type: MemberListType, - val members: List = emptyList(), - val isLoading: Boolean = false, - val canLoadMore: Boolean = true, - val searchQuery: String = "", - val isSearchActive: Boolean = false - ) - - enum class MemberListType { - ADMINS, MEMBERS, BLACKLIST - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/MemberListContent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/admin/MemberListContent.kt deleted file mode 100644 index 698b8f14..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/admin/MemberListContent.kt +++ /dev/null @@ -1,230 +0,0 @@ -package org.monogram.presentation.features.profile.admin - -import androidx.compose.animation.* -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.BasicTextField -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.Add -import androidx.compose.material.icons.rounded.Close -import androidx.compose.material.icons.rounded.Edit -import androidx.compose.material.icons.rounded.Search -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.SolidColor -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun MemberListContent(component: MemberListComponent) { - val state by component.state.subscribeAsState() - val focusManager = LocalFocusManager.current - val focusRequester = remember { FocusRequester() } - - LaunchedEffect(state.isSearchActive) { - if (state.isSearchActive) { - focusRequester.requestFocus() - } - } - - Scaffold( - topBar = { - TopAppBar( - title = { - AnimatedContent( - targetState = state.isSearchActive, - transitionSpec = { - fadeIn() + slideInHorizontally { it / 2 } togetherWith - fadeOut() + slideOutHorizontally { -it / 2 } - }, - label = "TitleSearch" - ) { isSearch -> - if (isSearch) { - Box( - modifier = Modifier - .fillMaxWidth() - .height(48.dp), - contentAlignment = Alignment.CenterStart - ) { - if (state.searchQuery.isEmpty()) { - Text( - text = stringResource(R.string.search_hint), - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - BasicTextField( - value = state.searchQuery, - onValueChange = component::onSearch, - modifier = Modifier - .fillMaxWidth() - .focusRequester(focusRequester), - textStyle = MaterialTheme.typography.bodyLarge.copy( - color = MaterialTheme.colorScheme.onSurface - ), - cursorBrush = SolidColor(MaterialTheme.colorScheme.primary), - singleLine = true, - keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), - keyboardActions = KeyboardActions(onSearch = { focusManager.clearFocus() }) - ) - } - } else { - Text( - text = when (state.type) { - MemberListComponent.MemberListType.ADMINS -> stringResource(R.string.administrators) - MemberListComponent.MemberListType.MEMBERS -> stringResource(R.string.subscribers) - MemberListComponent.MemberListType.BLACKLIST -> stringResource(R.string.blacklist) - }, - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - } - } - }, - navigationIcon = { - IconButton(onClick = component::onBack) { - Icon(Icons.AutoMirrored.Rounded.ArrowBack, contentDescription = stringResource(R.string.back)) - } - }, - actions = { - if (state.isSearchActive) { - IconButton(onClick = { component.onSearch("") }) { - Icon(Icons.Rounded.Close, contentDescription = stringResource(R.string.clear)) - } - } else { - IconButton(onClick = component::onToggleSearch) { - Icon(Icons.Rounded.Search, contentDescription = stringResource(R.string.search)) - } - if (state.type != MemberListComponent.MemberListType.BLACKLIST) { - IconButton(onClick = component::onAddMember) { - Icon(Icons.Rounded.Add, contentDescription = stringResource(R.string.add)) - } - } - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background - ) - ) - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - if (state.isLoading && state.members.isEmpty()) { - Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { - CircularProgressIndicator() - } - } else { - LazyColumn( - modifier = Modifier - .fillMaxSize() - .padding(top = padding.calculateTopPadding()), - contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp), - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - items(state.members, key = { it.user.id }) { member -> - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - ListItem( - headlineContent = { - Text( - listOfNotNull(member.user.firstName, member.user.lastName).joinToString(" "), - fontWeight = FontWeight.Bold, - style = MaterialTheme.typography.titleMedium - ) - }, - supportingContent = { - member.rank?.let { - if (it.isNotEmpty()) { - Text( - text = it, - color = MaterialTheme.colorScheme.primary, - style = MaterialTheme.typography.bodyMedium - ) - } - } - }, - leadingContent = { - Avatar( - path = member.user.avatarPath, - fallbackPath = member.user.personalAvatarPath, - name = member.user.firstName, - size = 48.dp, - videoPlayerPool = component.videoPlayerPool - ) - }, - trailingContent = { - IconButton(onClick = { component.onMemberClick(member) }) { - Icon( - imageVector = Icons.Rounded.Edit, - contentDescription = stringResource(R.string.edit), - tint = MaterialTheme.colorScheme.primary - ) - } - }, - colors = ListItemDefaults.colors( - containerColor = Color.Transparent - ), - modifier = Modifier.clickable { component.onMemberClick(member) } - ) - } - } - if (state.canLoadMore) { - item { - LaunchedEffect(Unit) { component.onLoadMore() } - Box( - Modifier - .fillMaxWidth() - .padding(16.dp), contentAlignment = Alignment.Center - ) { - CircularProgressIndicator(modifier = Modifier.size(24.dp)) - } - } - } - - if (state.members.isEmpty() && !state.isLoading) { - item { - Box( - modifier = Modifier - .fillParentMaxSize() - .padding(bottom = 100.dp), - contentAlignment = Alignment.Center - ) { - Text( - text = if (state.isSearchActive) stringResource(R.string.no_results_found) else stringResource(R.string.no_members_yet), - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/components/LinkedChatItem.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/components/LinkedChatItem.kt deleted file mode 100644 index 4790fefb..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/components/LinkedChatItem.kt +++ /dev/null @@ -1,99 +0,0 @@ -package org.monogram.presentation.features.profile.components - -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.ChatModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -@Composable -fun LinkedChatItem( - chat: ChatModel, - isDiscussion: Boolean, - videoPlayerPool: VideoPlayerPool, - onClick: () -> Unit -) { - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier - .fillMaxWidth() - .padding(top = 8.dp), - onClick = onClick - ) { - Row( - modifier = Modifier - .padding(12.dp) - .fillMaxWidth(), - verticalAlignment = Alignment.Top - ) { - Avatar( - path = chat.avatarPath, - fallbackPath = chat.personalAvatarPath, - name = chat.title, - size = 64.dp, - modifier = Modifier.clip(CircleShape), - videoPlayerPool = videoPlayerPool - ) - - Spacer(modifier = Modifier.width(12.dp)) - - Column(modifier = Modifier.weight(1f)) { - Text( - text = chat.title, - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.Bold, - maxLines = 2, - overflow = TextOverflow.Ellipsis - ) - val subtitle = buildString { - if (chat.memberCount > 0) { - append(stringResource(R.string.subscribers_count_format, chat.memberCount)) - } - if (!chat.description.isNullOrEmpty()) { - if (isNotEmpty()) append(" • ") - append(chat.description) - } - } - if (subtitle.isNotEmpty()) { - Text( - text = subtitle, - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 2, - overflow = TextOverflow.Ellipsis - ) - } - } - - Spacer(modifier = Modifier.width(12.dp)) - - Surface( - color = MaterialTheme.colorScheme.primaryContainer, - shape = CircleShape, - modifier = Modifier.padding(top = 4.dp) - ) { - Text( - text = if (isDiscussion) stringResource(R.string.label_discussion) else stringResource(R.string.label_channel), - modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onPrimaryContainer, - fontWeight = FontWeight.Bold - ) - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/components/LocationViewer.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/components/LocationViewer.kt deleted file mode 100644 index 11a307be..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/components/LocationViewer.kt +++ /dev/null @@ -1,387 +0,0 @@ -package org.monogram.presentation.features.profile.components - -import android.content.Intent -import android.net.Uri -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Directions -import androidx.compose.material.icons.rounded.Map -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.core.net.toUri -import com.maplibre.compose.MapView -import com.maplibre.compose.camera.CameraState -import com.maplibre.compose.camera.MapViewCamera -import com.maplibre.compose.rememberSaveableMapViewCamera -import com.maplibre.compose.symbols.Symbol -import org.maplibre.android.geometry.LatLng -import org.maplibre.android.maps.MapLibreMapOptions -import org.monogram.presentation.R -import org.monogram.presentation.features.profile.ProfileComponent - -private const val MAP_STYLE = "https://tiles.openfreemap.org/styles/bright" - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun LocationViewer( - location: ProfileComponent.LocationData, - onDismiss: () -> Unit -) { - val sheetState = rememberModalBottomSheetState( - skipPartiallyExpanded = true - ) - var showMapsSelection by remember { mutableStateOf(false) } - var isNavigationMode by remember { mutableStateOf(false) } - val context = LocalContext.current - val camera = rememberSaveableMapViewCamera( - MapViewCamera( - CameraState.Centered( - location.latitude, - location.longitude, - ), - ) - ) - val mapOptions = remember { - MapLibreMapOptions.createFromAttributes(context, null).apply { - scrollGesturesEnabled(true) - zoomGesturesEnabled(true) - tiltGesturesEnabled(false) - rotateGesturesEnabled(false) - doubleTapGesturesEnabled(true) - textureMode(true) - } - } - - ModalBottomSheet( - onDismissRequest = onDismiss, - sheetState = sheetState, - containerColor = MaterialTheme.colorScheme.background, - dragHandle = { BottomSheetDefaults.DragHandle() } - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 40.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Text( - text = stringResource(R.string.location_label), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - - Spacer(modifier = Modifier.height(16.dp)) - - Box( - modifier = Modifier - .fillMaxWidth() - .height(240.dp) - .clip(RoundedCornerShape(16.dp)) - ) { - MapView( - modifier = Modifier - .fillMaxWidth(), - camera = camera, - styleUrl = MAP_STYLE, - mapOptions = mapOptions - ) { - Symbol( - center = LatLng(location.latitude, location.longitude), - imageId = R.drawable.ic_map_marker, - size = 2f - ) - } - } - - Spacer(modifier = Modifier.height(16.dp)) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainerLow, - shape = RoundedCornerShape(16.dp), - modifier = Modifier.fillMaxWidth() - ) { - Column(modifier = Modifier.padding(16.dp)) { - Text( - text = location.address, - style = MaterialTheme.typography.bodyLarge, - textAlign = TextAlign.Center, - modifier = Modifier.fillMaxWidth() - ) - Spacer(modifier = Modifier.height(8.dp)) - Text( - text = "${location.latitude}, ${location.longitude}", - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center, - modifier = Modifier.fillMaxWidth() - ) - } - } - - Spacer(modifier = Modifier.height(24.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - Button( - onClick = { - isNavigationMode = false - showMapsSelection = true - }, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Icon(Icons.Rounded.Map, null) - Spacer(modifier = Modifier.width(8.dp)) - Text(stringResource(R.string.action_open_maps)) - } - - FilledTonalButton( - onClick = { - isNavigationMode = true - showMapsSelection = true - }, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Icon(Icons.Rounded.Directions, null) - Spacer(modifier = Modifier.width(8.dp)) - Text(stringResource(R.string.action_directions)) - } - } - } - } - - if (showMapsSelection) { - MapsSelectionDialog( - location = location, - isNavigation = isNavigationMode, - onDismiss = { showMapsSelection = false } - ) - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun MapsSelectionDialog( - location: ProfileComponent.LocationData, - isNavigation: Boolean, - onDismiss: () -> Unit -) { - val context = LocalContext.current - val mapsApps = - listOf( - MapApp( - name = "Google Maps", - packageName = "com.google.android.apps.maps", - uriBuilder = { lat, lon, addr -> "geo:$lat,$lon?q=${Uri.encode(addr)}".toUri() }, - navigationUriBuilder = { lat, lon -> "google.navigation:q=$lat,$lon".toUri() } - ), - MapApp( - name = "Yandex Maps", - packageName = "ru.yandex.yandexmaps", - uriBuilder = { lat, lon, _ -> "yandexmaps://maps.yandex.ru/?pt=$lon,$lat&z=16&l=map".toUri() }, - navigationUriBuilder = { lat, lon -> "yandexmaps://maps.yandex.ru/?rtext=~$lat,$lon&rtt=auto".toUri() } - ), - MapApp( - name = "Yandex Navigator", - packageName = "ru.yandex.yandexnavi", - uriBuilder = { lat, lon, _ -> "yandexnavi://show_point_on_map?lat=$lat&lon=$lon&zoom=16".toUri() }, - navigationUriBuilder = { lat, lon -> "yandexnavi://build_route_on_map?lat_to=$lat&lon_to=$lon".toUri() } - ), - MapApp( - name = "2GIS", - packageName = "ru.dublgis.dgismobile", - uriBuilder = { lat, lon, _ -> "dgis://2gis.ru/geo/$lon,$lat".toUri() }, - navigationUriBuilder = { lat, lon -> "dgis://2gis.ru/routeSearch/to/$lon,$lat/go".toUri() } - ), - MapApp( - name = "Waze", - packageName = "com.waze", - uriBuilder = { lat, lon, _ -> "waze://?ll=$lat,$lon".toUri() }, - navigationUriBuilder = { lat, lon -> "waze://?ll=$lat,$lon&navigate=yes".toUri() } - ), - MapApp( - name = "HERE WeGo", - packageName = "com.here.app.maps", - uriBuilder = { lat, lon, _ -> "https://share.here.com/l/$lat,$lon".toUri() }, - navigationUriBuilder = { lat, lon -> "here-route://?mylocation&destination=$lat,$lon".toUri() } - ), - MapApp( - name = "Sygic", - packageName = "com.sygic.aura", - uriBuilder = { lat, lon, _ -> "com.sygic.aura://coordinate|$lon|$lat|show".toUri() }, - navigationUriBuilder = { lat, lon -> "com.sygic.aura://coordinate|$lon|$lat|drive".toUri() } - ), - MapApp( - name = "OsmAnd", - packageName = "net.osmand", - uriBuilder = { lat, lon, _ -> "osmand.api://show_point?lat=$lat&lon=$lon".toUri() }, - navigationUriBuilder = { lat, lon -> "osmand.api://navigate?lat=$lat&lon=$lon&profile=car".toUri() } - ), - MapApp( - name = "Organic Maps", - packageName = "app.organicmaps", - uriBuilder = { lat, lon, addr -> "geo:$lat,$lon?q=${Uri.encode(addr)}".toUri() }, - navigationUriBuilder = { lat, lon -> "google.navigation:q=$lat,$lon".toUri() } - ), - MapApp( - name = "Maps.me", - packageName = "com.mapswithme.maps.pro", - uriBuilder = { lat, lon, addr -> "geo:$lat,$lon?q=${Uri.encode(addr)}".toUri() }, - navigationUriBuilder = { lat, lon -> "mapsme://route?sll=0,0&dll=$lat,$lon&type=vehicle".toUri() } - ), - MapApp( - name = "Citymapper", - packageName = "com.citymapper.app.release", - uriBuilder = { lat, lon, addr -> "citymapper://directions?endcoord=$lat,$lon&endname=${Uri.encode(addr)}".toUri() }, - navigationUriBuilder = { lat, lon -> "citymapper://directions?endcoord=$lat,$lon".toUri() } - ), - MapApp( - name = "Petal Maps", - packageName = "com.huawei.maps.app", - uriBuilder = { lat, lon, _ -> "petalmaps://geo?center=$lat,$lon&zoom=16".toUri() }, - navigationUriBuilder = { lat, lon -> "petalmaps://navigation?daddr=$lat,$lon&type=drive".toUri() } - ), - MapApp( - name = "KakaoMap", - packageName = "net.daum.android.map", - uriBuilder = { lat, lon, _ -> "kakaomap://look?p=$lat,$lon".toUri() }, - navigationUriBuilder = { lat, lon -> "kakaomap://route?ep=$lat,$lon&by=CAR".toUri() } - ), - MapApp( - name = "Naver Map", - packageName = "com.nhn.android.nmap", - uriBuilder = { lat, lon, addr -> "nmap://place?lat=$lat&lng=$lon&name=${Uri.encode(addr)}&appname=com.example.app".toUri() }, - navigationUriBuilder = { lat, lon -> "nmap://route/car?dlat=$lat&dlng=$lon&appname=com.example.app".toUri() } - ), - MapApp( - name = "Baidu Maps", - packageName = "com.baidu.BaiduMap", - uriBuilder = { lat, lon, addr -> "baidumap://map/marker?location=$lat,$lon&title=${Uri.encode(addr)}&src=andr.baidu.openAPIdemo".toUri() }, - navigationUriBuilder = { lat, lon -> "baidumap://map/direction?destination=$lat,$lon&mode=driving&src=andr.baidu.openAPIdemo".toUri() } - ), - MapApp( - name = "Gaode / AutoNavi", - packageName = "com.autonavi.minimap", - uriBuilder = { lat, lon, addr -> "androidamap://viewMap?lat=$lat&lon=$lon&poiname=${Uri.encode(addr)}&sourceApplication=appname".toUri() }, - navigationUriBuilder = { lat, lon -> "androidamap://navi?lat=$lat&lon=$lon&dev=0&style=2&sourceApplication=appname".toUri() } - ) - ) - - val installedApps = remember(mapsApps) { - mapsApps.filter { app -> - context.packageManager.getLaunchIntentForPackage(app.packageName) != null - } - } - - ModalBottomSheet( - onDismissRequest = onDismiss, - containerColor = MaterialTheme.colorScheme.background, - dragHandle = { BottomSheetDefaults.DragHandle() } - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 40.dp) - .verticalScroll(rememberScrollState()) - ) { - Text( - text = stringResource(if (isNavigation) R.string.navigate_with else R.string.open_with), - modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainerLow, - shape = RoundedCornerShape(20.dp), - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp) - ) { - Column { - installedApps.forEachIndexed { index, app -> - ListItem( - headlineContent = { - Text( - text = app.name, - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurface - ) - }, - modifier = Modifier.clickable { - val uri = if (isNavigation) { - app.navigationUriBuilder(location.latitude, location.longitude) - } else { - app.uriBuilder(location.latitude, location.longitude, location.address) - } - val intent = Intent(Intent.ACTION_VIEW, uri) - intent.setPackage(app.packageName) - context.startActivity(intent) - onDismiss() - }, - colors = ListItemDefaults.colors(containerColor = Color.Transparent), - ) - if (index < installedApps.size - 1) { - HorizontalDivider( - modifier = Modifier.padding(horizontal = 16.dp), - thickness = 0.5.dp, - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - } - } - - if (installedApps.isNotEmpty()) { - HorizontalDivider( - modifier = Modifier.padding(horizontal = 16.dp), - thickness = 0.5.dp, - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - } - - ListItem( - headlineContent = { Text(stringResource(R.string.browser_other), style = MaterialTheme.typography.bodyLarge) }, - modifier = Modifier.clickable { - val uri = if (isNavigation) { - "google.navigation:q=${location.latitude},${location.longitude}".toUri() - } else { - "geo:${location.latitude},${location.longitude}?q=${Uri.encode(location.address)}".toUri() - } - val intent = Intent(Intent.ACTION_VIEW, uri) - context.startActivity(intent) - onDismiss() - }, - colors = ListItemDefaults.colors(containerColor = Color.Transparent), - ) - } - } - } - } -} - -private data class MapApp( - val name: String, - val packageName: String, - val uriBuilder: (Double, Double, String) -> Uri, - val navigationUriBuilder: (Double, Double) -> Uri -) diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/components/ProfileHeader.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/components/ProfileHeader.kt deleted file mode 100644 index a451d8af..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/components/ProfileHeader.kt +++ /dev/null @@ -1,148 +0,0 @@ -package org.monogram.presentation.features.profile.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Favorite -import androidx.compose.material.icons.rounded.Verified -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.stickers.ui.view.StickerImage - - -@Composable -fun ProfileHeader( - avatarPath: String?, - videoPlayerPool: VideoPlayerPool, - profilePhotos: List, - title: String, - subtitle: String, - isOnline: Boolean, - isVerified: Boolean, - isSponsor: Boolean, - statusEmojiPath: String?, - isBot: Boolean, - onAvatarClick: () -> Unit -) { - val displayPath = profilePhotos.firstOrNull() ?: avatarPath - - Column( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 24.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Box( - contentAlignment = Alignment.BottomEnd - ) { - Avatar( - path = displayPath, - name = title, - size = 120.dp, - fontSize = 48, - videoPlayerPool = videoPlayerPool, - modifier = Modifier - .clip(CircleShape) - .clickable(enabled = displayPath != null) { onAvatarClick() } - ) - - if (isOnline) { - Box( - modifier = Modifier - .size(24.dp) - .background(MaterialTheme.colorScheme.background, CircleShape) - .padding(3.dp) - ) { - Box( - modifier = Modifier - .fillMaxSize() - .background(Color(0xFF4CAF50), CircleShape) - ) - } - } - } - - Spacer(Modifier.height(16.dp)) - - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Center, - modifier = Modifier.padding(horizontal = 24.dp) - ) { - Text( - text = title, - style = MaterialTheme.typography.headlineMedium.copy( - fontWeight = FontWeight.Bold - ), - color = MaterialTheme.colorScheme.onBackground, - textAlign = TextAlign.Center - ) - - if (isVerified) { - Spacer(Modifier.width(6.dp)) - Icon( - imageVector = Icons.Rounded.Verified, - contentDescription = stringResource(R.string.cd_verified), - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.size(22.dp) - ) - } - if (isSponsor) { - Spacer(Modifier.width(6.dp)) - Icon( - imageVector = Icons.Default.Favorite, - contentDescription = stringResource(R.string.cd_sponsor), - tint = Color(0xFFE53935), - modifier = Modifier.size(22.dp) - ) - } - if (statusEmojiPath != null) { - Spacer(Modifier.width(6.dp)) - StickerImage( - path = statusEmojiPath, - modifier = Modifier.size(22.dp), - animate = false - ) - } - if (isBot) { - Spacer(Modifier.width(6.dp)) - Surface( - color = MaterialTheme.colorScheme.tertiaryContainer, - shape = RoundedCornerShape(4.dp) - ) { - Text( - text = stringResource(R.string.label_bot_badge), - style = MaterialTheme.typography.labelSmall, - modifier = Modifier.padding(horizontal = 4.dp, vertical = 1.dp), - color = MaterialTheme.colorScheme.onTertiaryContainer - ) - } - } - } - - Spacer(Modifier.height(4.dp)) - - Text( - text = subtitle, - style = MaterialTheme.typography.bodyLarge, - color = if (isOnline) Color(0xFF4CAF50) else MaterialTheme.colorScheme.onSurfaceVariant - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/components/ProfileHeaderTransformed.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/components/ProfileHeaderTransformed.kt deleted file mode 100644 index 11d4c0d8..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/components/ProfileHeaderTransformed.kt +++ /dev/null @@ -1,207 +0,0 @@ -package org.monogram.presentation.features.profile.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Favorite -import androidx.compose.material.icons.filled.Star -import androidx.compose.material.icons.rounded.Verified -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Shadow -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.ChatModel -import org.monogram.domain.models.UserModel -import org.monogram.presentation.core.ui.AvatarHeader -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.stickers.ui.view.StickerImage - -@Composable -fun ProfileHeaderTransformed( - avatarPath: String?, - title: String, - subtitle: String, - avatarSize: Dp, - userModel: UserModel?, - chatModel: ChatModel?, - avatarCornerPercent: Int, - isOnline: Boolean, - isVerified: Boolean, - isSponsor: Boolean, - statusEmojiPath: String?, - progress: Float, - contentPadding: PaddingValues, - onAvatarClick: () -> Unit, - onActionClick: () -> Unit, - videoPlayerPool: VideoPlayerPool -) { - val screenHeight = LocalConfiguration.current.screenHeightDp.dp - - BoxWithConstraints( - modifier = Modifier - .fillMaxWidth() - .padding(contentPadding) - ) { - val headerHeight = maxWidth.coerceAtMost(screenHeight * 0.6f) - - Box( - modifier = Modifier - .fillMaxWidth() - .height(headerHeight) - .alpha(progress) - ) { - Box( - modifier = Modifier - .align(Alignment.Center) - .clip(RoundedCornerShape(avatarCornerPercent)) - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null, - onClick = onAvatarClick - ) - ) { - AvatarHeader( - path = avatarPath, - name = title, - size = avatarSize.coerceAtMost(headerHeight), - avatarCornerPercent = avatarCornerPercent, - videoPlayerPool = videoPlayerPool - ) - } - - val scrimColor = Color.Black.copy(alpha = 0.7f) - Box( - modifier = Modifier - .matchParentSize() - .alpha(progress / 1.5f) - .background( - brush = Brush.verticalGradient( - colorStops = arrayOf( - 0.0f to scrimColor, - 0.15f to Color.Transparent, - 0.7f to Color.Transparent, - 1.0f to scrimColor - ) - ), - shape = RoundedCornerShape(avatarCornerPercent) - ) - ) - - Column( - modifier = Modifier - .align(Alignment.BottomStart) - .padding(horizontal = 20.dp, vertical = 32.dp) - ) { - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - ) { - Row( - modifier = Modifier.weight(1f), - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = title, - style = MaterialTheme.typography.headlineLarge.copy( - shadow = Shadow( - color = Color.Black.copy(alpha = 0.5f), - offset = Offset(2f, 2f), - blurRadius = 8f - ) - ), - fontWeight = FontWeight.Bold, - color = Color.White, - maxLines = 2, - overflow = TextOverflow.Ellipsis - ) - - if (isVerified) { - Spacer(modifier = Modifier.width(6.dp)) - Icon( - imageVector = Icons.Rounded.Verified, - contentDescription = "Verified", - modifier = Modifier.size(28.dp), - tint = Color(0xFF31A6FD) - ) - } - if (isSponsor) { - Spacer(modifier = Modifier.width(6.dp)) - Icon( - imageVector = Icons.Default.Favorite, - contentDescription = "Sponsor", - modifier = Modifier.size(28.dp), - tint = Color(0xFFE53935) - ) - } - - userModel?.let { user -> - if (!user.statusEmojiPath.isNullOrEmpty()) { - Spacer(modifier = Modifier.width(6.dp)) - StickerImage( - path = user.statusEmojiPath, - modifier = Modifier.size(26.dp), - animate = false - ) - } else if (user.isPremium) { - Spacer(modifier = Modifier.width(6.dp)) - Icon( - imageVector = Icons.Default.Star, - contentDescription = null, - modifier = Modifier.size(28.dp), - tint = Color(0xFF31A6FD) - ) - } - } - } - - - } - - Text( - text = subtitle, - color = if (isOnline) Color(0xFF4CAF50) else Color.White.copy(alpha = 0.9f), - fontSize = 16.sp, - style = MaterialTheme.typography.bodyMedium.copy( - shadow = Shadow( - color = Color.Black.copy(alpha = 0.5f), - offset = Offset(1f, 1f), - blurRadius = 4f - ) - ) - ) - } - } - - Box( - modifier = Modifier - .fillMaxWidth() - .height(24.dp) - .align(Alignment.BottomCenter) - .background( - color = MaterialTheme.colorScheme.background, - shape = RoundedCornerShape( - topStart = (30 * progress).dp, - topEnd = (30 * progress).dp - ) - ) - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/components/ProfileMediaSection.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/components/ProfileMediaSection.kt deleted file mode 100644 index d4d4d905..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/components/ProfileMediaSection.kt +++ /dev/null @@ -1,1093 +0,0 @@ -package org.monogram.presentation.features.profile.components - -import android.content.Intent -import androidx.compose.animation.AnimatedContent -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.slideInHorizontally -import androidx.compose.animation.slideOutHorizontally -import androidx.compose.animation.togetherWith -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.GridItemSpan -import androidx.compose.foundation.lazy.grid.LazyGridScope -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.lazy.grid.itemsIndexed -import androidx.compose.foundation.lazy.grid.rememberLazyGridState -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.InsertDriveFile -import androidx.compose.material.icons.filled.Star -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.rememberVectorPainter -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.LocalWindowInfo -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.zIndex -import androidx.core.net.toUri -import coil3.compose.AsyncImage -import coil3.request.ImageRequest -import coil3.request.crossfade -import org.monogram.domain.models.GroupMemberModel -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.domain.models.UserStatusType -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.ui.rememberShimmerBrush -import org.monogram.presentation.core.util.getUserStatusText -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.chats.currentChat.components.VideoStickerPlayer -import org.monogram.presentation.features.chats.currentChat.components.VideoType -import org.monogram.presentation.features.profile.ProfileComponent -import org.monogram.presentation.features.stickers.ui.view.StickerImage -import java.io.File - -private const val LOAD_MORE_THRESHOLD = 40 - -@OptIn(ExperimentalFoundationApi::class) -fun LazyGridScope.profileMediaSection( - state: ProfileComponent.State, - videoPlayerPool: VideoPlayerPool, - onTabSelected: (Int) -> Unit, - onMessageClick: (MessageModel) -> Unit, - onMessageLongClick: (MessageModel) -> Unit, - onLoadMore: () -> Unit, - onMemberClick: (Long) -> Unit = {}, - onMemberLongClick: (Long) -> Unit = {}, - onLoadMedia: (MessageModel) -> Unit = {} -) { - val isGroup = state.chat?.isGroup == true || state.chat?.isChannel == true - val tabs = mutableListOf<@Composable () -> String>({ stringResource(R.string.tab_media) }) - if (isGroup) tabs.add { stringResource(R.string.tab_members) } - tabs.addAll(listOf( - { stringResource(R.string.tab_files) }, - { stringResource(R.string.tab_audio) }, - { stringResource(R.string.tab_voice) }, - { stringResource(R.string.tab_links) }, - { stringResource(R.string.tab_gifs) } - )) - - stickyHeader { - Surface( - color = MaterialTheme.colorScheme.background, - modifier = Modifier.fillMaxWidth() - ) { - Column( - modifier = Modifier - .background(MaterialTheme.colorScheme.background) - .padding(vertical = 8.dp) - ) { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .background(MaterialTheme.colorScheme.surfaceContainer, RoundedCornerShape(24.dp)) - .clip(RoundedCornerShape(24.dp)) - ) { - PrimaryScrollableTabRow( - selectedTabIndex = state.selectedTabIndex, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 4.dp), - containerColor = MaterialTheme.colorScheme.surfaceContainer, - edgePadding = 4.dp, - divider = {}, - indicator = { - Box( - Modifier - .tabIndicatorOffset(state.selectedTabIndex) - .fillMaxHeight() - .padding(vertical = 4.dp) - .zIndex(-1f) - .clip(RoundedCornerShape(24.dp)) - .background(MaterialTheme.colorScheme.primary) - ) - } - ) { - tabs.forEachIndexed { index, titleFunc -> - val selected = state.selectedTabIndex == index - - Tab( - selected = selected, - onClick = { onTabSelected(index) }, - modifier = Modifier - .height(44.dp) - .padding(vertical = 4.dp) - .clip(RoundedCornerShape(24.dp)), - selectedContentColor = MaterialTheme.colorScheme.onPrimary, - unselectedContentColor = MaterialTheme.colorScheme.onSurfaceVariant, - text = { - Text( - text = titleFunc(), - style = MaterialTheme.typography.labelLarge, - fontWeight = if (selected) FontWeight.Bold else FontWeight.Normal - ) - } - ) - } - } - } - } - } - } - - item(span = { GridItemSpan(3) }) { - LaunchedEffect(state.selectedTabIndex) { - val shouldLoad = if (isGroup) { - when (state.selectedTabIndex) { - 0 -> state.mediaMessages.isEmpty() && state.canLoadMoreMedia && !state.isLoadingMedia - 1 -> state.members.isEmpty() && state.canLoadMoreMembers && !state.isLoadingMembers - 2 -> state.fileMessages.isEmpty() && state.canLoadMoreMedia && !state.isLoadingMedia - 3 -> state.audioMessages.isEmpty() && state.canLoadMoreMedia && !state.isLoadingMedia - 4 -> state.voiceMessages.isEmpty() && state.canLoadMoreMedia && !state.isLoadingMedia - 5 -> state.linkMessages.isEmpty() && state.canLoadMoreMedia && !state.isLoadingMedia - 6 -> state.gifMessages.isEmpty() && state.canLoadMoreMedia && !state.isLoadingMedia - else -> false - } - } else { - when (state.selectedTabIndex) { - 0 -> state.mediaMessages.isEmpty() && state.canLoadMoreMedia && !state.isLoadingMedia - 1 -> state.fileMessages.isEmpty() && state.canLoadMoreMedia && !state.isLoadingMedia - 2 -> state.audioMessages.isEmpty() && state.canLoadMoreMedia && !state.isLoadingMedia - 3 -> state.voiceMessages.isEmpty() && state.canLoadMoreMedia && !state.isLoadingMedia - 4 -> state.linkMessages.isEmpty() && state.canLoadMoreMedia && !state.isLoadingMedia - 5 -> state.gifMessages.isEmpty() && state.canLoadMoreMedia && !state.isLoadingMedia - else -> false - } - } - if (shouldLoad) { - onLoadMore() - } - } - } - - val isMediaLoading = state.isLoadingMedia || state.isLoadingMoreMedia - val canLoadMedia = state.canLoadMoreMedia - - item(span = { GridItemSpan(3) }) { - AnimatedContent( - targetState = state.selectedTabIndex, - transitionSpec = { - if (targetState > initialState) { - slideInHorizontally { width -> width } + fadeIn() togetherWith - slideOutHorizontally { width -> -width } + fadeOut() - } else { - slideInHorizontally { width -> -width } + fadeIn() togetherWith - slideOutHorizontally { width -> width } + fadeOut() - } - }, - label = "tabs" - ) { tab -> - ProfileTabContent( - tab = tab, - state = state, - videoPlayerPool = videoPlayerPool, - onLoadMore = onLoadMore, - onMessageClick = onMessageClick, - onLoadMedia = onLoadMedia, - onMemberClick = onMemberClick, - onMemberLongClick = onMemberLongClick - ) - } - } - - val shouldAutoLoadMore = if (isGroup && state.selectedTabIndex == 1) { - state.canLoadMoreMembers && !state.isLoadingMembers && state.members.isNotEmpty() - } else { - state.canLoadMoreMedia && !state.isLoadingMoreMedia && !state.isLoadingMedia - } - - if (shouldAutoLoadMore) { - item(span = { GridItemSpan(3) }, key = "loader") { - LaunchedEffect(state.selectedTabIndex, state.mediaMessages.size, state.members.size) { - onLoadMore() - } - Spacer(modifier = Modifier.height(1.dp)) - } - } - - val showMembersPaginationSkeleton = - isGroup && state.selectedTabIndex == 1 && state.isLoadingMembers && state.members.isNotEmpty() - val showMediaPaginationSkeleton = - (!isGroup || state.selectedTabIndex != 1) && state.isLoadingMoreMedia - - if (showMembersPaginationSkeleton || showMediaPaginationSkeleton) { - item(span = { GridItemSpan(3) }, key = "pagination_skeleton") { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 8.dp, vertical = 12.dp), - contentAlignment = Alignment.Center - ) { - val shimmer = rememberShimmerBrush() - if (showMembersPaginationSkeleton) { - Column(modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(8.dp)) { - repeat(3) { - MemberListSkeletonRow(shimmer = shimmer) - } - } - } else { - val mediaTypeIndex = if (isGroup && state.selectedTabIndex > 1) { - state.selectedTabIndex - 1 - } else { - state.selectedTabIndex - } - - when (mediaTypeIndex) { - 0, 5 -> { - Row( - horizontalArrangement = Arrangement.spacedBy(4.dp), - modifier = Modifier.fillMaxWidth() - ) { - repeat(3) { - Box( - modifier = Modifier - .weight(1f) - .aspectRatio(1f) - .clip(RoundedCornerShape(4.dp)) - .background(shimmer) - ) - } - } - } - - else -> { - Column( - modifier = Modifier.fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - repeat(2) { - MessageListSkeletonRow(shimmer = shimmer) - } - } - } - } - } - } - } - } -} - -@Composable -fun ProfileTabContent( - tab: Int, - state: ProfileComponent.State, - videoPlayerPool: VideoPlayerPool, - onLoadMore: () -> Unit, - onMessageClick: (MessageModel) -> Unit, - onLoadMedia: (MessageModel) -> Unit, - onMemberClick: (Long) -> Unit, - onMemberLongClick: (Long) -> Unit -) { - val gridState = rememberLazyGridState() - val viewportHeightPx = LocalWindowInfo.current.containerSize.height - val density = LocalDensity.current - - val viewportHeightDp = with(density) { viewportHeightPx.toDp() } - - Box( - modifier = Modifier - .fillMaxWidth() - .heightIn(min = 1.dp, max = viewportHeightDp) - ) { - LazyVerticalGrid( - modifier = Modifier.fillMaxSize(), - columns = GridCells.Fixed(3), - state = gridState - ) { - val isGroup = state.chat?.isGroup == true || state.chat?.isChannel == true - - if (isGroup) { - when (tab) { - 0 -> mediaGrid(state.mediaMessages, state.isLoadingMedia, state.canLoadMoreMedia, onLoadMore, onMessageClick, onLoadMedia) - 1 -> membersList(state.members, videoPlayerPool, state.isLoadingMembers, state.canLoadMoreMembers, onLoadMore, onMemberClick, onMemberLongClick) - 2 -> filesList(state.fileMessages, state.isLoadingMedia, state.canLoadMoreMedia, onLoadMore, onMessageClick) - 3 -> audioList(state.audioMessages, state.isLoadingMedia, state.canLoadMoreMedia, onLoadMore, onMessageClick) - 4 -> voiceList(state.voiceMessages, state.isLoadingMedia, state.canLoadMoreMedia, onLoadMore, onMessageClick) - 5 -> linksList(state.linkMessages, state.isLoadingMedia, state.canLoadMoreMedia, onLoadMore, onMessageClick) - 6 -> gifsGrid(state.gifMessages, videoPlayerPool, state.isLoadingMedia, state.canLoadMoreMedia, onLoadMore, onMessageClick) - } - } else { - when (tab) { - 0 -> mediaGrid(state.mediaMessages, state.isLoadingMedia, state.canLoadMoreMedia, onLoadMore, onMessageClick, onLoadMedia) - 1 -> filesList(state.fileMessages, state.isLoadingMedia, state.canLoadMoreMedia, onLoadMore, onMessageClick) - 2 -> audioList(state.audioMessages, state.isLoadingMedia, state.canLoadMoreMedia, onLoadMore, onMessageClick) - 3 -> voiceList(state.voiceMessages, state.isLoadingMedia, state.canLoadMoreMedia, onLoadMore, onMessageClick) - 4 -> linksList(state.linkMessages, state.isLoadingMedia, state.canLoadMoreMedia, onLoadMore, onMessageClick) - 5 -> gifsGrid(state.gifMessages, videoPlayerPool, state.isLoadingMedia, state.canLoadMoreMedia, onLoadMore, onMessageClick) - } - } - } - } -} - - -@Composable -private fun ScrollableRow( - modifier: Modifier = Modifier, - horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, - content: @Composable () -> Unit -) { - Row( - modifier = modifier.horizontalScroll(rememberScrollState()), - horizontalArrangement = horizontalArrangement, - verticalAlignment = Alignment.CenterVertically - ) { - content() - } -} - -private fun LazyGridScope.membersList( - members: List, - videoPlayerPool: VideoPlayerPool, - isLoading: Boolean, - canLoadMore: Boolean, - onLoadMore: () -> Unit, - onMemberClick: (Long) -> Unit, - onMemberLongClick: (Long) -> Unit -) { - val uniqueMembers = members.distinctBy { it.user.id } - - if (uniqueMembers.isEmpty()) { - if (isLoading) { - item(span = { GridItemSpan(3) }, key = "members_skeleton") { - val shimmer = rememberShimmerBrush() - Column(verticalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) { - repeat(8) { - MemberListSkeletonRow(shimmer = shimmer) - } - } - } - } else { - item(span = { GridItemSpan(3) }) { - EmptyState(stringResource(R.string.empty_members)) - } - } - } else { - itemsIndexed(uniqueMembers, key = { _, member -> "member_${member.user.id}" }, span = { _, _ -> GridItemSpan(3) }) { index, member -> - - // Trigger pre-loading - if (canLoadMore && !isLoading && index >= uniqueMembers.size - LOAD_MORE_THRESHOLD) { - LaunchedEffect(Unit) { - onLoadMore() - } - } - - val user = member.user - val title = listOfNotNull(user.firstName, user.lastName).joinToString(" ") - val isVerified = user.isVerified - - ListItem( - headlineContent = { - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = title, - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.SemiBold, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - color = MaterialTheme.colorScheme.onSurface, - modifier = Modifier.weight(1f, fill = false) - ) - - if (isVerified) { - Spacer(modifier = Modifier.width(4.dp)) - Icon( - imageVector = Icons.Rounded.Verified, - contentDescription = stringResource(R.string.cd_verified), - modifier = Modifier.size(18.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - if (user.isSponsor) { - Spacer(modifier = Modifier.width(4.dp)) - Icon( - imageVector = Icons.Rounded.Favorite, - contentDescription = stringResource(R.string.cd_sponsor), - modifier = Modifier.size(18.dp), - tint = Color(0xFFE53935) - ) - } - - if (!user.statusEmojiPath.isNullOrEmpty()) { - Spacer(modifier = Modifier.width(4.dp)) - StickerImage( - path = user.statusEmojiPath!!, - modifier = Modifier.size(18.dp), - animate = false - ) - } else if (user.isPremium) { - Spacer(modifier = Modifier.width(4.dp)) - Icon( - imageVector = Icons.Default.Star, - contentDescription = null, - modifier = Modifier.size(18.dp), - tint = Color(0xFF31A6FD) - ) - } - - if (member.rank != null) { - Spacer(modifier = Modifier.width(6.dp)) - Surface( - color = MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.5f), - shape = CircleShape, - modifier = Modifier.align(Alignment.CenterVertically) - ) { - Text( - text = member.rank?:"", - style = MaterialTheme.typography.labelSmall.copy(fontSize = 10.sp), - color = MaterialTheme.colorScheme.primary, - modifier = Modifier.padding(horizontal = 6.dp, vertical = 2.dp) - ) - } - } - } - }, - supportingContent = { - val context = LocalContext.current - val statusText = getUserStatusText(user, context) - - Text( - text = statusText, - style = MaterialTheme.typography.bodySmall, - color = if (user.userStatus == UserStatusType.ONLINE) - MaterialTheme.colorScheme.primary - else - MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - }, - leadingContent = { - Avatar( - path = user.avatarPath, - fallbackPath = user.personalAvatarPath, - name = user.firstName, - isOnline = user.userStatus == UserStatusType.ONLINE, - size = 40.dp, - videoPlayerPool = videoPlayerPool, - modifier = Modifier.combinedClickable( - onClick = { onMemberClick(user.id) }, - onLongClick = { onMemberLongClick(user.id) } - ) - ) - }, - modifier = Modifier.combinedClickable( - onClick = { onMemberClick(user.id) }, - onLongClick = { onMemberLongClick(user.id) } - ) - ) - } - } -} - -private fun LazyGridScope.mediaGrid( - messages: List, - isLoading: Boolean, - canLoadMore: Boolean, - onLoadMore: () -> Unit, - onMessageClick: (MessageModel) -> Unit, - onLoadMedia: (MessageModel) -> Unit -) { - val uniqueMessages = messages.distinctBy { it.id } - - if (uniqueMessages.isEmpty()) { - if (isLoading) { - item(span = { GridItemSpan(3) }, key = "media_skeleton") { - MediaGridSkeleton(rows = 3) - } - } else { - item(span = { GridItemSpan(3) }) { - EmptyState(stringResource(R.string.empty_media)) - } - } - } else { - itemsIndexed(uniqueMessages, key = { _, msg -> "media_${msg.id}" }) { index, msg -> - - // Trigger pre-loading - if (canLoadMore && !isLoading && index >= uniqueMessages.size - LOAD_MORE_THRESHOLD) { - LaunchedEffect(Unit) { - onLoadMore() - } - } - - Box( - modifier = Modifier - .aspectRatio(1f) - .background(MaterialTheme.colorScheme.surfaceVariant) - .clickable { onMessageClick(msg) } - ) { - val (path, isVideo) = when (val content = msg.content) { - is MessageContent.Photo -> content.path to false - is MessageContent.Video -> content.path to true - else -> null to false - } - - val thumbnailPath = when (val content = msg.content) { - is MessageContent.Photo -> content.thumbnailPath - is MessageContent.Video -> content.thumbnailPath - else -> null - } - - val minithumbnail = when (val content = msg.content) { - is MessageContent.Photo -> content.minithumbnail - is MessageContent.Video -> content.minithumbnail - else -> null - } - - val context = LocalContext.current - val isValidFile = path != null && File(path).exists() - val isValidThumbnail = thumbnailPath != null && File(thumbnailPath).exists() - - if (isValidFile || isValidThumbnail || minithumbnail != null) { - AsyncImage( - model = remember(path, thumbnailPath, minithumbnail) { - val data = when { - isValidFile -> path - isValidThumbnail -> thumbnailPath - else -> minithumbnail - } - ImageRequest.Builder(context) - .data(data) - .size(300, 300) - .crossfade(true) - .build() - }, - contentDescription = null, - contentScale = ContentScale.Crop, - modifier = Modifier.fillMaxSize(), - error = rememberVectorPainter(Icons.Rounded.BrokenImage) - ) - } else { - Box( - modifier = Modifier - .fillMaxSize() - .background(rememberShimmerBrush()), - contentAlignment = Alignment.Center - ) { - } - } - - if (!isValidFile && !isValidThumbnail) { - LaunchedEffect(msg.id) { - onLoadMedia(msg) - } - } - - if (isVideo) { - val content = msg.content as MessageContent.Video - Icon( - Icons.Rounded.PlayArrow, - contentDescription = stringResource(R.string.media_type_video), - tint = Color.White, - modifier = Modifier - .align(Alignment.TopEnd) - .padding(4.dp) - .size(20.dp) - ) - Box( - modifier = Modifier - .align(Alignment.BottomStart) - .padding(4.dp) - .background(Color.Black.copy(alpha = 0.5f), RoundedCornerShape(4.dp)) - .padding(horizontal = 4.dp, vertical = 1.dp) - ) { - Text( - text = formatDuration(content.duration), - style = MaterialTheme.typography.labelSmall, - color = Color.White, - fontSize = 10.sp - ) - } - } - } - } - } -} - -private fun formatDuration(seconds: Int): String { - val m = seconds / 60 - val s = seconds % 60 - return "%d:%02d".format(m, s) -} - -private fun LazyGridScope.audioList( - messages: List, - isLoading: Boolean, - canLoadMore: Boolean, - onLoadMore: () -> Unit, - onMessageClick: (MessageModel) -> Unit -) { - val uniqueMessages = messages.distinctBy { it.id } - - if (uniqueMessages.isEmpty()) { - if (isLoading) { - item(span = { GridItemSpan(3) }, key = "audio_skeleton") { - val shimmer = rememberShimmerBrush() - Column(verticalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) { - repeat(5) { - MessageListSkeletonRow(shimmer = shimmer) - } - } - } - } else { - item(span = { GridItemSpan(3) }) { - EmptyState(stringResource(R.string.empty_audio)) - } - } - } else { - itemsIndexed(uniqueMessages, key = { _, msg -> "audio_${msg.id}" }, span = { _, _ -> GridItemSpan(3) }) { index, msg -> - - // Trigger pre-loading - if (canLoadMore && !isLoading && index >= uniqueMessages.size - LOAD_MORE_THRESHOLD) { - LaunchedEffect(Unit) { - onLoadMore() - } - } - - val content = msg.content as? MessageContent.Document ?: return@itemsIndexed - Column { - ListItem( - headlineContent = { - Text(content.fileName, maxLines = 1, overflow = TextOverflow.Ellipsis) - }, - supportingContent = { - Text("${content.size / 1024} KB", maxLines = 1) - }, - leadingContent = { - Surface( - shape = CircleShape, - color = MaterialTheme.colorScheme.tertiaryContainer, - modifier = Modifier.size(42.dp) - ) { - Box(contentAlignment = Alignment.Center) { - Icon( - Icons.Rounded.MusicNote, - contentDescription = null, - tint = MaterialTheme.colorScheme.onTertiaryContainer, - modifier = Modifier.size(24.dp) - ) - } - } - }, - modifier = Modifier.clickable { onMessageClick(msg) } - ) - HorizontalDivider(modifier = Modifier.padding(start = 72.dp)) - } - } - } -} - -private fun LazyGridScope.voiceList( - messages: List, - isLoading: Boolean, - canLoadMore: Boolean, - onLoadMore: () -> Unit, - onMessageClick: (MessageModel) -> Unit -) { - val uniqueMessages = messages.distinctBy { it.id } - - if (uniqueMessages.isEmpty()) { - if (isLoading) { - item(span = { GridItemSpan(3) }, key = "voice_skeleton") { - val shimmer = rememberShimmerBrush() - Column(verticalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) { - repeat(5) { - MessageListSkeletonRow(shimmer = shimmer) - } - } - } - } else { - item(span = { GridItemSpan(3) }) { - EmptyState(stringResource(R.string.empty_voice)) - } - } - } else { - itemsIndexed(uniqueMessages, key = { _, msg -> "voice_${msg.id}" }, span = { _, _ -> GridItemSpan(3) }) { index, msg -> - - // Trigger pre-loading - if (canLoadMore && !isLoading && index >= uniqueMessages.size - LOAD_MORE_THRESHOLD) { - LaunchedEffect(Unit) { - onLoadMore() - } - } - - val (icon, labelRes, duration) = when (val content = msg.content) { - is MessageContent.Voice -> Triple(Icons.Rounded.Mic, R.string.media_type_voice, content.duration) - is MessageContent.VideoNote -> Triple(Icons.Rounded.Videocam, R.string.media_type_video_note, content.duration) - else -> return@itemsIndexed - } - - Column { - ListItem( - headlineContent = { Text(stringResource(labelRes), fontWeight = FontWeight.SemiBold) }, - supportingContent = { Text(formatDuration(duration), color = MaterialTheme.colorScheme.onSurfaceVariant) }, - leadingContent = { - Surface( - shape = CircleShape, - color = MaterialTheme.colorScheme.primaryContainer, - modifier = Modifier.size(42.dp) - ) { - Box(contentAlignment = Alignment.Center) { - Icon( - icon, - contentDescription = null, - tint = MaterialTheme.colorScheme.onPrimaryContainer, - modifier = Modifier.size(24.dp) - ) - } - } - }, - modifier = Modifier.clickable { onMessageClick(msg) } - ) - HorizontalDivider(modifier = Modifier.padding(start = 72.dp)) - } - } - } -} - -private fun LazyGridScope.filesList( - messages: List, - isLoading: Boolean, - canLoadMore: Boolean, - onLoadMore: () -> Unit, - onMessageClick: (MessageModel) -> Unit -) { - val uniqueMessages = messages.distinctBy { it.id } - - if (uniqueMessages.isEmpty()) { - if (isLoading) { - item(span = { GridItemSpan(3) }, key = "files_skeleton") { - val shimmer = rememberShimmerBrush() - Column(verticalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) { - repeat(5) { - MessageListSkeletonRow(shimmer = shimmer) - } - } - } - } else { - item(span = { GridItemSpan(3) }) { - EmptyState(stringResource(R.string.empty_files)) - } - } - } else { - itemsIndexed(uniqueMessages, key = { _, msg -> "file_${msg.id}" }, span = { _, _ -> GridItemSpan(3) }) { index, msg -> - - // Trigger pre-loading - if (canLoadMore && !isLoading && index >= uniqueMessages.size - LOAD_MORE_THRESHOLD) { - LaunchedEffect(Unit) { - onLoadMore() - } - } - - when (val content = msg.content) { - is MessageContent.Document -> { - Column { - ListItem( - headlineContent = { - Text(content.fileName, maxLines = 1, overflow = TextOverflow.Ellipsis) - }, - supportingContent = { Text("${content.size / 1024} KB") }, - leadingContent = { - Surface( - shape = RoundedCornerShape(8.dp), - color = MaterialTheme.colorScheme.primaryContainer - ) { - Icon( - Icons.AutoMirrored.Rounded.InsertDriveFile, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.padding(8.dp) - ) - } - }, - modifier = Modifier.clickable { onMessageClick(msg) } - ) - HorizontalDivider(modifier = Modifier.padding(start = 56.dp)) - } - } - else -> {} - } - } - } -} - -private fun LazyGridScope.linksList( - messages: List, - isLoading: Boolean, - canLoadMore: Boolean, - onLoadMore: () -> Unit, - onMessageClick: (MessageModel) -> Unit -) { - val uniqueMessages = messages.distinctBy { it.id } - - if (uniqueMessages.isEmpty()) { - if (isLoading) { - item(span = { GridItemSpan(3) }, key = "links_skeleton") { - val shimmer = rememberShimmerBrush() - Column(verticalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) { - repeat(5) { - MessageListSkeletonRow(shimmer = shimmer) - } - } - } - } else { - item(span = { GridItemSpan(3) }) { - EmptyState(stringResource(R.string.empty_links)) - } - } - } else { - itemsIndexed(uniqueMessages, key = { _, msg -> "link_${msg.id}" }, span = { _, _ -> GridItemSpan(3) }) { index, msg -> - - // Trigger pre-loading - if (canLoadMore && !isLoading && index >= uniqueMessages.size - LOAD_MORE_THRESHOLD) { - LaunchedEffect(Unit) { - onLoadMore() - } - } - - val content = msg.content as? MessageContent.Text ?: return@itemsIndexed - val context = LocalContext.current - val matcher = android.util.Patterns.WEB_URL.matcher(content.text) - val displayUrl = if (matcher.find()) matcher.group() else content.text - - Column { - ListItem( - headlineContent = { - Text(displayUrl, maxLines = 1, overflow = TextOverflow.Ellipsis, color = MaterialTheme.colorScheme.primary) - }, - supportingContent = { - Text(content.text, maxLines = 2, overflow = TextOverflow.Ellipsis) - }, - leadingContent = { - Surface( - shape = RoundedCornerShape(8.dp), - color = MaterialTheme.colorScheme.surfaceVariant - ) { - Icon( - Icons.Rounded.Link, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(8.dp) - ) - } - }, - modifier = Modifier.clickable { - try { - val url = if (!displayUrl.startsWith("http")) "https://$displayUrl" else displayUrl - val intent = Intent(Intent.ACTION_VIEW, url.toUri()) - context.startActivity(intent) - } catch (e: Exception) { - onMessageClick(msg) - } - } - ) - HorizontalDivider(modifier = Modifier.padding(start = 56.dp)) - } - } - } -} - -private fun LazyGridScope.gifsGrid( - messages: List, - videoPlayerPool: VideoPlayerPool, - isLoading: Boolean, - canLoadMore: Boolean, - onLoadMore: () -> Unit, - onMessageClick: (MessageModel) -> Unit -) { - val uniqueMessages = messages.distinctBy { it.id } - - if (uniqueMessages.isEmpty()) { - if (isLoading) { - item(span = { GridItemSpan(3) }, key = "gifs_skeleton") { - MediaGridSkeleton(rows = 2) - } - } else { - item(span = { GridItemSpan(3) }) { - EmptyState(stringResource(R.string.empty_gifs)) - } - } - } else { - itemsIndexed(uniqueMessages, key = { _, msg -> "gif_${msg.id}" }) { index, msg -> - - // Trigger pre-loading - if (canLoadMore && !isLoading && index >= uniqueMessages.size - LOAD_MORE_THRESHOLD) { - LaunchedEffect(Unit) { - onLoadMore() - } - } - - val content = msg.content as? MessageContent.Gif ?: return@itemsIndexed - Box( - modifier = Modifier - .aspectRatio(1f) - .padding(1.dp) - .clip(RoundedCornerShape(2.dp)) - .clickable { onMessageClick(msg) } - .background(Color.Black) - ) { - if (content.path != null) { - VideoStickerPlayer( - path = content.path!!, - type = VideoType.Gif, - modifier = Modifier.fillMaxSize(), - animate = true, - videoPlayerPool = videoPlayerPool - ) - Box( - modifier = Modifier - .align(Alignment.BottomStart) - .padding(4.dp) - .background(Color.Black.copy(alpha = 0.6f), RoundedCornerShape(4.dp)) - .padding(horizontal = 4.dp, vertical = 1.dp) - ) { - Text( - text = stringResource(R.string.media_type_gif), - style = MaterialTheme.typography.labelSmall.copy(fontSize = 8.sp), - color = Color.White - ) - } - } else { - Box( - modifier = Modifier - .fillMaxSize() - .background(rememberShimmerBrush()) - ) - } - } - } - } -} - -@Composable -private fun EmptyState(text: String) { - Column( - modifier = Modifier - .fillMaxWidth() - .height(180.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center - ) { - Icon( - imageVector = Icons.Rounded.PermMedia, - contentDescription = null, - modifier = Modifier - .size(48.dp) - .alpha(0.3f), - tint = MaterialTheme.colorScheme.onSurface - ) - Spacer(modifier = Modifier.height(8.dp)) - Text( - text = text, - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f) - ) - } -} - -@Composable -private fun MediaGridSkeleton(rows: Int) { - val shimmer = rememberShimmerBrush() - Column(verticalArrangement = Arrangement.spacedBy(4.dp), modifier = Modifier.fillMaxWidth()) { - repeat(rows) { - Row(horizontalArrangement = Arrangement.spacedBy(4.dp), modifier = Modifier.fillMaxWidth()) { - repeat(3) { - Box( - modifier = Modifier - .weight(1f) - .aspectRatio(1f) - .clip(RoundedCornerShape(4.dp)) - .background(shimmer) - ) - } - } - } - } -} - -@Composable -private fun MemberListSkeletonRow(shimmer: androidx.compose.ui.graphics.Brush) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 12.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(40.dp) - .clip(CircleShape) - .background(shimmer) - ) - Spacer(modifier = Modifier.width(12.dp)) - Column(modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(8.dp)) { - Box( - modifier = Modifier - .height(14.dp) - .fillMaxWidth(0.52f) - .clip(RoundedCornerShape(6.dp)) - .background(shimmer) - ) - Box( - modifier = Modifier - .height(12.dp) - .fillMaxWidth(0.34f) - .clip(RoundedCornerShape(6.dp)) - .background(shimmer) - ) - } - } -} - -@Composable -private fun MessageListSkeletonRow(shimmer: androidx.compose.ui.graphics.Brush) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 12.dp, vertical = 10.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(40.dp) - .clip(RoundedCornerShape(10.dp)) - .background(shimmer) - ) - Spacer(modifier = Modifier.width(12.dp)) - Column(modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(8.dp)) { - Box( - modifier = Modifier - .height(14.dp) - .fillMaxWidth(0.6f) - .clip(RoundedCornerShape(6.dp)) - .background(shimmer) - ) - Box( - modifier = Modifier - .height(12.dp) - .fillMaxWidth(0.42f) - .clip(RoundedCornerShape(6.dp)) - .background(shimmer) - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/components/ProfileSections.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/components/ProfileSections.kt deleted file mode 100644 index 3eb10613..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/components/ProfileSections.kt +++ /dev/null @@ -1,1487 +0,0 @@ -package org.monogram.presentation.features.profile.components - -import android.content.Intent -import androidx.compose.animation.* -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.Chat -import androidx.compose.material.icons.automirrored.rounded.Login -import androidx.compose.material.icons.automirrored.rounded.Logout -import androidx.compose.material.icons.automirrored.rounded.OpenInNew -import androidx.compose.material.icons.filled.QrCode -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.platform.ClipboardManager -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.core.net.toUri -import org.monogram.domain.models.UserTypeEnum -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.* -import org.monogram.presentation.core.util.CountryManager -import org.monogram.presentation.core.util.OperatorManager -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.profile.ProfileComponent -import java.util.* - -@Composable -fun ProfileInfoSectionSkeleton( - itemCount: Int = 4, - showLinkedChat: Boolean = true -) { - val shimmer = rememberShimmerBrush() - - Spacer(modifier = Modifier.height(12.dp)) - - ProfileQuickActionsSkeleton(shimmer = shimmer) - if (showLinkedChat) { - LinkedChatItemSkeleton(shimmer = shimmer) - } - SectionHeaderSkeleton(shimmer = shimmer) - - repeat(itemCount) { index -> - val position = when { - itemCount == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == itemCount - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = 24.dp, - topEnd = 24.dp, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = 24.dp, - bottomEnd = 24.dp, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(24.dp) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier.fillMaxWidth() - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 12.dp, vertical = 16.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(40.dp) - .clip(CircleShape) - .background(shimmer) - ) - Spacer(modifier = Modifier.width(16.dp)) - Column(modifier = Modifier.fillMaxWidth()) { - Box( - modifier = Modifier - .height(18.dp) - .fillMaxWidth( - when (index % 3) { - 0 -> 0.54f - 1 -> 0.48f - else -> 0.58f - } - ) - .clip(RoundedCornerShape(8.dp)) - .background(shimmer) - ) - Spacer(modifier = Modifier.height(8.dp)) - Box( - modifier = Modifier - .height(12.dp) - .fillMaxWidth( - when (index % 3) { - 0 -> 0.86f - 1 -> 0.78f - else -> 0.9f - } - ) - .clip(RoundedCornerShape(8.dp)) - .background(shimmer) - ) - } - } - } - if (index < itemCount - 1) { - Spacer(modifier = Modifier.height(2.dp)) - } - } -} - -@Composable -private fun ProfileQuickActionsSkeleton(shimmer: androidx.compose.ui.graphics.Brush) { - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 2.dp) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 8.dp, vertical = 4.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally) - ) { - repeat(3) { - Column( - modifier = Modifier - .weight(1f, fill = true) - .widthIn(max = 100.dp) - .padding(vertical = 8.dp, horizontal = 4.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Box( - modifier = Modifier - .fillMaxWidth() - .height(48.dp) - .clip(RoundedCornerShape(12.dp)) - .background(shimmer) - ) - Spacer(modifier = Modifier.height(6.dp)) - Box( - modifier = Modifier - .height(11.dp) - .fillMaxWidth(0.8f) - .clip(RoundedCornerShape(6.dp)) - .background(shimmer) - ) - } - } - } - } - - Spacer(modifier = Modifier.height(8.dp)) -} - -@Composable -private fun LinkedChatItemSkeleton(shimmer: androidx.compose.ui.graphics.Brush) { - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier - .fillMaxWidth() - .padding(top = 8.dp) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(12.dp), - verticalAlignment = Alignment.Top - ) { - Box( - modifier = Modifier - .size(64.dp) - .clip(CircleShape) - .background(shimmer) - ) - - Spacer(modifier = Modifier.width(12.dp)) - - Column(modifier = Modifier.weight(1f)) { - Box( - modifier = Modifier - .padding(top = 4.dp) - .height(18.dp) - .fillMaxWidth(0.58f) - .clip(RoundedCornerShape(8.dp)) - .background(shimmer) - ) - Spacer(modifier = Modifier.height(10.dp)) - Box( - modifier = Modifier - .height(12.dp) - .fillMaxWidth(0.92f) - .clip(RoundedCornerShape(8.dp)) - .background(shimmer) - ) - } - - Spacer(modifier = Modifier.width(12.dp)) - - Box( - modifier = Modifier - .padding(top = 4.dp) - .width(88.dp) - .height(28.dp) - .clip(CircleShape) - .background(shimmer) - ) - } - } - - Spacer(modifier = Modifier.height(16.dp)) -} - -@Composable -private fun SectionHeaderSkeleton(shimmer: androidx.compose.ui.graphics.Brush) { - Box( - modifier = Modifier - .padding(start = 12.dp, top = 16.dp, bottom = 8.dp) - .height(20.dp) - .width(164.dp) - .clip(RoundedCornerShape(10.dp)) - .background(shimmer) - ) -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ProfileInfoSection( - state: ProfileComponent.State, - videoPlayerPool: VideoPlayerPool, - clipboardManager: ClipboardManager, - onOpenMiniApp: (String, String, Long) -> Unit = { _, _, _ -> }, - onSendMessage: () -> Unit = {}, - onToggleMute: () -> Unit = {}, - onShowQRCode: () -> Unit = {}, - onEdit: () -> Unit = {}, - onLeave: () -> Unit = {}, - onJoin: () -> Unit = {}, - onShowLogs: () -> Unit = {}, - onShowStatistics: () -> Unit = {}, - onShowRevenueStatistics: () -> Unit = {}, - onLinkedChatClick: () -> Unit = {}, - onShowPermissions: () -> Unit = {}, - onAcceptTOS: () -> Unit = {}, - onToggleContact: () -> Unit = {}, - onLocationClick: (Double, Double, String) -> Unit = { _, _, _ -> } -) { - val user = state.user - val chat = state.chat - val fullInfo = state.fullInfo - val context = LocalContext.current - var isSponsorSheetVisible by remember { mutableStateOf(false) } - - if (isSponsorSheetVisible) { - val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) - ModalBottomSheet( - onDismissRequest = { isSponsorSheetVisible = false }, - sheetState = sheetState, - containerColor = MaterialTheme.colorScheme.surface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 48.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Icon( - imageVector = Icons.Rounded.Favorite, - contentDescription = null, - modifier = Modifier.size(64.dp), - tint = Color(0xFFFF6D66) - ) - Spacer(modifier = Modifier.height(16.dp)) - Text( - text = stringResource(R.string.support_monogram_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - textAlign = TextAlign.Center - ) - Spacer(modifier = Modifier.height(8.dp)) - Text( - text = stringResource(R.string.sponsor_sheet_description), - style = MaterialTheme.typography.bodyLarge, - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.height(32.dp)) - Button( - onClick = { - context.startActivity( - Intent.createChooser( - Intent(Intent.ACTION_VIEW, "https://boosty.to/monogram".toUri()), - null - ) - ) - isSponsorSheetVisible = false - }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.action_support_boosty)) - } - Spacer(modifier = Modifier.height(12.dp)) - TextButton( - onClick = { isSponsorSheetVisible = false }, - modifier = Modifier.fillMaxWidth() - ) { - Text(stringResource(R.string.action_maybe_later)) - } - } - } - } - - val isGroupOrChannel = chat?.isGroup == true || chat?.isChannel == true - val isCurrentUser = user != null && state.currentUser?.id == user.id - val canEdit = when { - isCurrentUser -> true - isGroupOrChannel -> chat?.isAdmin == true || chat?.permissions?.canChangeInfo == true - else -> false - } - - if (!isCurrentUser) { - ProfileQuickActions( - state = state, - isGroupOrChannel = isGroupOrChannel, - isCurrentUser = isCurrentUser, - onSendMessage = onSendMessage, - onLeave = onLeave, - onJoin = onJoin, - onShowQRCode = onShowQRCode - ) - } - - state.linkedChat?.let { linkedChat -> - LinkedChatItem( - chat = linkedChat, - isDiscussion = chat?.isChannel == true, - onClick = onLinkedChatClick, - videoPlayerPool = videoPlayerPool - ) - } - - val items = mutableListOf<@Composable (ItemPosition) -> Unit>() - - if (user?.isSponsor == true) { - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.Favorite, - title = stringResource(R.string.sponsor_profile_title), - subtitle = stringResource(R.string.sponsor_profile_subtitle), - iconColor = Color(0xFFFF6D66), - position = pos, - onClick = { isSponsorSheetVisible = true } - ) - } - } - - if (!isCurrentUser && !isGroupOrChannel && (state.personalAvatarPath != null || chat?.personalAvatarPath != null)) { - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.Portrait, - title = stringResource(R.string.personal_photo_title), - subtitle = stringResource(R.string.personal_photo_subtitle), - iconColor = MaterialTheme.colorScheme.primary, - position = pos, - onClick = { } - ) - } - } - - if (user?.type == UserTypeEnum.BOT && !state.botWebAppUrl.isNullOrEmpty()) { - val botName = listOfNotNull(user.firstName, user.lastName).joinToString(" ").trim() - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.RocketLaunch, - title = state.botWebAppName ?: stringResource(R.string.open_mini_app), - subtitle = stringResource(R.string.open_mini_app_subtitle), - iconColor = MaterialTheme.colorScheme.primary, - position = pos, - onClick = { onOpenMiniApp(state.botWebAppUrl, state.botWebAppName ?: botName, state.chatId) } - ) - } - } - - if (user?.type == UserTypeEnum.BOT) { - if (!state.isTOSAccepted) { - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.AssignmentTurnedIn, - title = stringResource(R.string.accept_tos), - subtitle = stringResource(R.string.accept_tos_subtitle), - iconColor = MaterialTheme.colorScheme.primary, - position = pos, - onClick = onAcceptTOS - ) - } - } - - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.Security, - title = stringResource(R.string.bot_permissions), - subtitle = stringResource(R.string.bot_permissions_subtitle), - iconColor = MaterialTheme.colorScheme.secondary, - position = pos, - onClick = { onShowPermissions() } - ) - } - } - - val usernames = user?.usernames ?: chat?.usernames - val activeUsernames = usernames?.activeUsernames ?: emptyList() - val disabledUsernames = usernames?.disabledUsernames ?: emptyList() - val collectibleUsernames = usernames?.collectibleUsernames ?: emptyList() - - if (activeUsernames.isNotEmpty() || collectibleUsernames.isNotEmpty() || disabledUsernames.isNotEmpty()) { - items.add { pos -> - UsernamesTile( - activeUsernames = activeUsernames, - collectibleUsernames = collectibleUsernames, - disabledUsernames = disabledUsernames, - clipboardManager = clipboardManager, - isGroupOrChannel = isGroupOrChannel, - position = pos - ) - } - } else { - val displayLink = if (isGroupOrChannel) { - state.publicLink ?: chat?.username - } else { - user?.username ?: chat?.username ?: state.publicLink - } - if (!displayLink.isNullOrEmpty()) { - items.add { pos -> - val isLink = displayLink.startsWith("http", ignoreCase = true) || - displayLink.startsWith("t.me", ignoreCase = true) - val isPrivateInviteLink = isGroupOrChannel && isLink && ( - displayLink.contains("t.me/+", ignoreCase = true) || - displayLink.contains("joinchat", ignoreCase = true) - ) - val finalTitle = when { - isGroupOrChannel && !isLink -> "https://t.me/$displayLink" - isLink -> displayLink - else -> "@$displayLink" - } - val icon = if (isGroupOrChannel || isLink) Icons.Rounded.Link else Icons.Rounded.AlternateEmail - val subtitleText = when { - isPrivateInviteLink -> stringResource(R.string.invite_link_label) - isGroupOrChannel || isLink -> stringResource(R.string.link_label) - else -> stringResource(R.string.username_label) - } - - SettingsTile( - icon = icon, - title = finalTitle, - subtitle = subtitleText, - iconColor = MaterialTheme.colorScheme.primary, - position = pos, - onClick = { - clipboardManager.setText(AnnotatedString(finalTitle)) - } - ) - } - } - } - - val aboutText = fullInfo?.botInfo ?: fullInfo?.description ?: state.about - if (!aboutText.isNullOrEmpty()) { - items.add { pos -> - RichSettingsTile( - icon = Icons.Rounded.Info, - title = when { - user?.type == UserTypeEnum.BOT -> stringResource(R.string.bot_info_label) - isGroupOrChannel -> stringResource(R.string.description_label) - else -> stringResource(R.string.bio_label) - }, - content = aboutText, - iconColor = MaterialTheme.colorScheme.primary, - position = pos, - onCopyClick = { text -> - clipboardManager.setText(AnnotatedString(text)) - } - ) - } - } - - user?.phoneNumber?.takeIf { it.isNotEmpty() }?.let { phone -> - val formattedPhone = CountryManager.formatPhone(phone) - val country = CountryManager.getCountryForPhone(phone) - val operator = OperatorManager.detectOperator(phone, country?.iso) - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.Phone, - title = formattedPhone, - subtitle = buildString { - country?.let { append("${it.flagEmoji} ${it.name}") } - operator?.let { - if (isNotEmpty()) append(" • ") - append(it) - } - }, - iconColor = Color(0xFF34A853), - position = pos, - onClick = { clipboardManager.setText(AnnotatedString(phone)) } - ) - } - } - - fullInfo?.birthdate?.let { birthdate -> - val birthdateText = buildString { - append("${birthdate.day}/${birthdate.month}") - birthdate.year?.let { year -> - append("/$year") - val today = Calendar.getInstance() - var age = today.get(Calendar.YEAR) - year - if (today.get(Calendar.MONTH) + 1 < birthdate.month || - (today.get(Calendar.MONTH) + 1 == birthdate.month && today.get(Calendar.DAY_OF_MONTH) < birthdate.day) - ) { - age-- - } - append(" ($age)") - } - } - - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.Cake, - title = birthdateText, - subtitle = stringResource(R.string.birthdate_label), - iconColor = Color(0xFFE91E63), - position = pos, - onClick = { } - ) - } - } - - fullInfo?.businessInfo?.let { business -> - business.location?.let { loc -> - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.LocationOn, - title = loc.address, - subtitle = stringResource(R.string.location_label), - iconColor = Color(0xFFEA4335), - position = pos, - onClick = { onLocationClick(loc.latitude, loc.longitude, loc.address) } - ) - } - } - - business.openingHours?.let { hours -> - items.add { pos -> - val days = listOf( - stringResource(R.string.monday_short), - stringResource(R.string.tuesday_short), - stringResource(R.string.wednesday_short), - stringResource(R.string.thursday_short), - stringResource(R.string.friday_short), - stringResource(R.string.saturday_short), - stringResource(R.string.sunday_short) - ) - val intervalsByDay = hours.intervals.groupBy { it.startMinute / (24 * 60) } - val formattedHours = days.mapIndexed { index, day -> - val dayIntervals = intervalsByDay[index] - if (dayIntervals.isNullOrEmpty()) { - "$day: ${stringResource(R.string.opening_hours_closed)}" - } else { - val times = dayIntervals.joinToString(", ") { interval -> - val startHour = (interval.startMinute % (24 * 60)) / 60 - val startMinute = interval.startMinute % 60 - val endHour = (interval.endMinute % (24 * 60)) / 60 - val endMinute = interval.endMinute % 60 - String.format("%02d:%02d - %02d:%02d", startHour, startMinute, endHour, endMinute) - } - "$day: $times" - } - }.joinToString("\n") - - SettingsTile( - icon = Icons.Rounded.Schedule, - title = stringResource(R.string.opening_hours_label), - subtitle = formattedHours, - iconColor = Color(0xFFFBBC04), - position = pos, - onClick = { } - ) - } - } - } - - if (chat?.isAdmin == true && isGroupOrChannel) { - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.History, - title = stringResource(R.string.recent_actions_title), - subtitle = stringResource(R.string.recent_actions_subtitle), - iconColor = MaterialTheme.colorScheme.secondary, - position = pos, - onClick = onShowLogs - ) - } - } - - val hasStatisticsAccess = isGroupOrChannel && fullInfo?.canGetStatistics == true - if (hasStatisticsAccess) { - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.BarChart, - title = stringResource(R.string.statistics_title), - subtitle = stringResource(R.string.statistics_subtitle), - iconColor = Color(0xFF00BCD4), - position = pos, - onClick = { onShowStatistics() } - ) - } - } - - if (!isGroupOrChannel && !isCurrentUser && user != null && user.type != UserTypeEnum.BOT) { - val savedByYou = user.isContact - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.PersonAdd, - title = if (savedByYou) stringResource(R.string.action_remove_contact) else stringResource(R.string.action_add_contact), - subtitle = if (savedByYou) { - stringResource(R.string.contact_saved_by_you) - } else { - stringResource(R.string.contact_not_saved_by_you) - }, - iconColor = Color(0xFF5C6BC0), - position = pos, - onClick = onToggleContact - ) - } - } - - if (!isGroupOrChannel && isCurrentUser && fullInfo != null) { - if (fullInfo.hasPostedToProfileStories) { - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.Collections, - title = stringResource(R.string.profile_feature_stories_title), - subtitle = stringResource(R.string.profile_feature_stories_subtitle), - iconColor = Color(0xFFAB47BC), - position = pos, - onClick = { } - ) - } - } - - if (fullInfo.setChatBackground) { - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.Palette, - title = stringResource(R.string.profile_feature_background_title), - subtitle = stringResource(R.string.profile_feature_background_subtitle), - iconColor = Color(0xFF26A69A), - position = pos, - onClick = { } - ) - } - } - - if (fullInfo.hasRestrictedVoiceAndVideoNoteMessages) { - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.MicOff, - title = stringResource(R.string.profile_feature_voice_restricted_title), - subtitle = stringResource(R.string.profile_feature_voice_restricted_subtitle), - iconColor = Color(0xFFFF7043), - position = pos, - onClick = { } - ) - } - } - } - - if (isGroupOrChannel && (fullInfo?.slowModeDelay ?: 0) > 0) { - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.Timer, - title = stringResource(R.string.slow_mode_title), - subtitle = stringResource( - R.string.slow_mode_subtitle_format, - formatInterval(fullInfo?.slowModeDelay ?: 0) - ), - iconColor = Color(0xFF009688), - position = pos, - onClick = { } - ) - } - } - - if (isGroupOrChannel && chat?.hasProtectedContent == true) { - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.Shield, - title = stringResource(R.string.protected_content_title), - subtitle = stringResource(R.string.protected_content_subtitle), - iconColor = Color(0xFF7E57C2), - position = pos, - onClick = { } - ) - } - } - - if (!isGroupOrChannel && fullInfo?.hasPrivateForwards == true) { - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.ForwardToInbox, - title = stringResource(R.string.private_forwards_title), - subtitle = stringResource(R.string.private_forwards_subtitle), - iconColor = Color(0xFF5E35B1), - position = pos, - onClick = { } - ) - } - } - - val hasRevenueAccess = chat?.isChannel == true && fullInfo?.canGetRevenueStatistics == true - - if (hasRevenueAccess) { - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.Payments, - title = stringResource(R.string.revenue_title), - subtitle = stringResource(R.string.revenue_subtitle), - iconColor = Color(0xFFFF9800), - position = pos, - onClick = { onShowRevenueStatistics() } - ) - } - } - - val id = user?.id ?: chat?.id - if (id != null) { - items.add { pos -> - SettingsTile( - icon = Icons.Rounded.Numbers, - title = id.toString(), - subtitle = stringResource(R.string.label_id), - iconColor = MaterialTheme.colorScheme.outline, - position = pos, - onClick = { clipboardManager.setText(AnnotatedString(id.toString())) } - ) - } - } - - AnimatedVisibility( - visible = items.isNotEmpty(), - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically() - ) { - Column { - SectionHeader( - text = stringResource(R.string.info_section_header), - onEditClick = if (canEdit) onEdit else null - ) - items.forEachIndexed { index, item -> - val position = when { - items.size == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == items.size - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - item(position) - } - } - } - - val settingsItems = mutableListOf<@Composable (ItemPosition) -> Unit>() - - if (!isCurrentUser) { - settingsItems.add { pos -> - SettingsSwitchTile( - icon = Icons.Rounded.Notifications, - title = stringResource(R.string.notifications_title), - checked = chat?.isMuted == false, - iconColor = Color(0xFFFF6D66), - position = pos, - onCheckedChange = { onToggleMute() } - ) - } - } - - if (chat != null && chat.messageAutoDeleteTime > 0) { - settingsItems.add { pos -> - SettingsTile( - icon = Icons.Rounded.Timer, - title = "${chat.messageAutoDeleteTime}s", - subtitle = stringResource(R.string.auto_delete_subtitle), - iconColor = Color(0xFF009688), - position = pos, - onClick = { /* */ } - ) - } - } - - AnimatedVisibility( - visible = settingsItems.isNotEmpty(), - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically() - ) { - Column { - SectionHeader( - text = stringResource(R.string.settings_section_header), - onEditClick = null - ) - settingsItems.forEachIndexed { index, item -> - val position = when { - settingsItems.size == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == settingsItems.size - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - item(position) - } - } - } -} - -@Composable -private fun ProfileQuickActions( - state: ProfileComponent.State, - isGroupOrChannel: Boolean, - isCurrentUser: Boolean, - onSendMessage: () -> Unit, - onLeave: () -> Unit, - onJoin: () -> Unit, - onShowQRCode: () -> Unit -) { - val chat = state.chat - - val items = mutableListOf<@Composable (Modifier) -> Unit>() - - if (!isCurrentUser) { - items.add { mod -> - QuickActionItem( - if (chat?.isChannel == true) Icons.AutoMirrored.Rounded.OpenInNew else Icons.AutoMirrored.Filled.Chat, - if (chat?.isChannel == true) stringResource(R.string.action_open) else stringResource(R.string.action_message), - onClick = onSendMessage, - modifier = mod - ) - } - } - - if (isGroupOrChannel) { - if (chat?.isMember == true) { - items.add { mod -> - QuickActionItem( - Icons.AutoMirrored.Rounded.Logout, stringResource(R.string.menu_leave), - onClick = onLeave, - modifier = mod - ) - } - } else { - items.add { mod -> - QuickActionItem( - Icons.AutoMirrored.Rounded.Login, - stringResource(R.string.action_join_chat), - onClick = onJoin, - modifier = mod - ) - } - } - } - - if (!isCurrentUser) { - items.add { mod -> - QuickActionItem( - Icons.Default.QrCode, - stringResource(R.string.action_qr_code), - onClick = onShowQRCode, - modifier = mod - ) - } - } - - AnimatedVisibility( - visible = items.isNotEmpty(), - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically() - ) { - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 2.dp) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 8.dp, vertical = 4.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally) - ) { - items.forEach { item -> - item(Modifier - .weight(1f, fill = true) - .widthIn(max = 100.dp)) - } - } - } - } -} - -@Composable -fun QuickActionItem(icon: ImageVector, label: String, modifier: Modifier = Modifier, onClick: () -> Unit) { - Column( - modifier = modifier - .clip(RoundedCornerShape(12.dp)) - .clickable { onClick() } - .padding(vertical = 8.dp, horizontal = 4.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Box( - modifier = Modifier - .fillMaxWidth() - .height(48.dp) - .background( - MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.4f), - RoundedCornerShape(12.dp) - ), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = icon, - contentDescription = label, - modifier = Modifier.size(24.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - Spacer(modifier = Modifier.height(6.dp)) - Text( - text = label, - style = MaterialTheme.typography.labelSmall.copy(fontSize = 11.sp), - color = MaterialTheme.colorScheme.primary, - textAlign = TextAlign.Center, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } -} - -@Composable -private fun SectionHeader( - text: String, - onEditClick: (() -> Unit)? = null -) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(start = 12.dp, end = 4.dp, bottom = 8.dp, top = 16.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = text, - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) - if (onEditClick != null) { - IconButton( - onClick = onEditClick, - modifier = Modifier.size(24.dp) - ) { - Icon( - imageVector = Icons.Rounded.Edit, - contentDescription = stringResource(R.string.menu_edit), - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.size(18.dp) - ) - } - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ProfileQRDialog( - state: ProfileComponent.State, - onDismiss: () -> Unit -) { - val context = LocalContext.current - if (state.isQrVisible) { - ModalBottomSheet( - onDismissRequest = onDismiss, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - dragHandle = { BottomSheetDefaults.DragHandle() }, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 40.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - val qrContent = state.qrContent - val username = state.user?.username ?: state.chat?.username ?: state.chat?.title ?: "user" - val qrDarkGreen = Color(0xFF3E4D36) - val qrSurfaceShapeColor = Color(0xFFE3E6D8) - - Text( - text = stringResource(R.string.action_qr_code), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface, - modifier = Modifier.padding(bottom = 16.dp) - ) - - Box( - modifier = Modifier - .size(240.dp) - .background(qrSurfaceShapeColor, RoundedCornerShape(24.dp)), - contentAlignment = Alignment.Center - ) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - StyledQRCode( - content = qrContent, - modifier = Modifier.size(160.dp), - primaryColor = qrDarkGreen, - backgroundColor = qrSurfaceShapeColor - ) - Spacer(modifier = Modifier.height(12.dp)) - Text( - text = if (state.user?.username != null || state.chat?.username != null) "@$username" else username, - color = qrDarkGreen, - fontSize = 16.sp, - fontWeight = FontWeight.Medium, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - } - - Spacer(modifier = Modifier.height(32.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - Button( - onClick = { - val bitmap = generatePureBitmap(qrContent, 1024) - saveBitmapToGallery(context, bitmap) - }, - modifier = Modifier - .weight(1f) - .height(56.dp), - colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.primaryContainer, - contentColor = MaterialTheme.colorScheme.onPrimaryContainer - ), - shape = RoundedCornerShape(16.dp) - ) { Text(stringResource(R.string.action_save), fontSize = 16.sp, fontWeight = FontWeight.Bold) } - - Button( - onClick = { - val bitmap = generatePureBitmap(qrContent, 1024) - shareBitmap(context, bitmap) - }, - modifier = Modifier - .weight(1f) - .height(56.dp), - colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary), - shape = RoundedCornerShape(16.dp) - ) { Text(stringResource(R.string.menu_share), fontSize = 16.sp, fontWeight = FontWeight.Bold) } - } - } - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ProfileReportDialog( - state: ProfileComponent.State, - onDismiss: () -> Unit, - onReport: (String) -> Unit -) { - if (state.isReportVisible) { - val reasons = listOf( - stringResource(R.string.report_spam) to "spam", - stringResource(R.string.report_violence) to "violence", - stringResource(R.string.report_pornography) to "pornography", - stringResource(R.string.report_child_abuse) to "child_abuse", - stringResource(R.string.report_copyright) to "copyright", - stringResource(R.string.report_other) to "other" - ) - ModalBottomSheet( - onDismissRequest = onDismiss, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - dragHandle = { BottomSheetDefaults.DragHandle() }, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 40.dp) - ) { - Text( - text = stringResource(R.string.action_report), - modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainerLow, - shape = RoundedCornerShape(20.dp), - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp) - ) { - Column { - reasons.forEachIndexed { index, (label, value) -> - ListItem( - headlineContent = { Text(label, style = MaterialTheme.typography.bodyLarge) }, - modifier = Modifier.clickable { onReport(value) }, - colors = ListItemDefaults.colors(containerColor = Color.Transparent), - ) - if (index < reasons.size - 1) { - HorizontalDivider( - modifier = Modifier.padding(horizontal = 16.dp), - thickness = 0.5.dp, - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - } - } - } - } - - Spacer(modifier = Modifier.height(16.dp)) - - OutlinedButton( - onClick = onDismiss, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.cancel_button), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ProfilePermissionsDialog( - state: ProfileComponent.State, - onDismiss: () -> Unit, - onTogglePermission: (String) -> Unit = {} -) { - if (state.isPermissionsVisible) { - ModalBottomSheet( - onDismissRequest = onDismiss, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - dragHandle = { BottomSheetDefaults.DragHandle() }, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 40.dp) - ) { - Text( - text = stringResource(R.string.bot_permissions), - modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainerLow, - shape = RoundedCornerShape(20.dp), - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp) - ) { - Column { - state.botPermissions.entries.forEachIndexed { index, entry -> - ListItem( - headlineContent = { Text(entry.key, style = MaterialTheme.typography.bodyLarge) }, - trailingContent = { - Switch( - checked = entry.value, - onCheckedChange = { onTogglePermission(entry.key) } - ) - }, - colors = ListItemDefaults.colors(containerColor = Color.Transparent), - ) - if (index < state.botPermissions.size - 1) { - HorizontalDivider( - modifier = Modifier.padding(horizontal = 16.dp), - thickness = 0.5.dp, - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - } - } - } - } - - Spacer(modifier = Modifier.height(16.dp)) - - Button( - onClick = onDismiss, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.close_button), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ProfileTOSDialog( - state: ProfileComponent.State, - onDismiss: () -> Unit, - onAccept: () -> Unit -) { - if (state.isTOSVisible) { - ModalBottomSheet( - onDismissRequest = onDismiss, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - dragHandle = { BottomSheetDefaults.DragHandle() }, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 40.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Text( - text = stringResource(R.string.terms_of_service_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - Spacer(modifier = Modifier.height(12.dp)) - Text( - text = stringResource(R.string.tos_dialog_description), - style = MaterialTheme.typography.bodyLarge, - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.height(32.dp)) - - Button( - onClick = onAccept, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp), - enabled = !state.isAcceptingTOS - ) { - AnimatedContent( - targetState = state.isAcceptingTOS, - transitionSpec = { - fadeIn() togetherWith fadeOut() - }, - label = "AcceptButtonContent" - ) { accepting -> - if (accepting) { - CircularProgressIndicator( - modifier = Modifier.size(24.dp), - color = MaterialTheme.colorScheme.onPrimary, - strokeWidth = 2.dp - ) - } else { - Text( - stringResource(R.string.accept_and_launch), - fontSize = 16.sp, - fontWeight = FontWeight.Bold - ) - } - } - } - - Spacer(modifier = Modifier.height(12.dp)) - OutlinedButton( - onClick = onDismiss, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .height(56.dp), - shape = RoundedCornerShape(16.dp), - enabled = !state.isAcceptingTOS - ) { - Text(stringResource(R.string.cancel_button), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } - } -} - -@OptIn(ExperimentalLayoutApi::class) -@Composable -private fun UsernamesTile( - activeUsernames: List, - collectibleUsernames: List, - disabledUsernames: List, - clipboardManager: ClipboardManager, - isGroupOrChannel: Boolean, - position: ItemPosition -) { - val allUsernames = (activeUsernames + collectibleUsernames + disabledUsernames).distinct() - val primaryUsername = - activeUsernames.firstOrNull() ?: collectibleUsernames.firstOrNull() ?: disabledUsernames.firstOrNull() - - if (primaryUsername == null) return - - val primaryColor = when { - activeUsernames.contains(primaryUsername) -> MaterialTheme.colorScheme.primary - collectibleUsernames.contains(primaryUsername) -> MaterialTheme.colorScheme.tertiary - else -> MaterialTheme.colorScheme.outline - } - - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - .clickable { clipboardManager.setText(AnnotatedString("@$primaryUsername")) } - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 16.dp), - verticalAlignment = Alignment.Top - ) { - Box( - modifier = Modifier - .size(40.dp) - .background(color = primaryColor.copy(0.15f), shape = CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.AlternateEmail, - contentDescription = null, - modifier = Modifier.size(24.dp), - tint = primaryColor - ) - } - Spacer(modifier = Modifier.width(16.dp)) - Column(modifier = Modifier.weight(1f)) { - Text( - text = "@$primaryUsername", - style = MaterialTheme.typography.titleMedium, - fontSize = 18.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - Text( - text = if (isGroupOrChannel) stringResource(R.string.link_label) else stringResource(R.string.username_label), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f) - ) - - val otherUsernames = allUsernames.filter { it != primaryUsername } - if (otherUsernames.isNotEmpty()) { - Spacer(modifier = Modifier.height(12.dp)) - FlowRow( - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - otherUsernames.forEach { username -> - val chipColor = when { - activeUsernames.contains(username) -> MaterialTheme.colorScheme.primary - collectibleUsernames.contains(username) -> MaterialTheme.colorScheme.tertiary - else -> MaterialTheme.colorScheme.outline - } - UsernameChip( - username = username, - color = chipColor, - onClick = { clipboardManager.setText(AnnotatedString("@$username")) } - ) - } - } - } - } - } - } - if (position != ItemPosition.BOTTOM && position != ItemPosition.STANDALONE) { - Spacer(Modifier.height(2.dp)) - } -} - -@Composable -private fun UsernameChip( - username: String, - color: Color, - onClick: () -> Unit -) { - Surface( - color = color.copy(alpha = 0.08f), - shape = RoundedCornerShape(8.dp), - modifier = Modifier - .clip(RoundedCornerShape(8.dp)) - .clickable(onClick = onClick) - ) { - Text( - text = "@$username", - modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp), - style = MaterialTheme.typography.bodySmall, - color = color, - fontWeight = FontWeight.SemiBold - ) - } -} - -private fun formatInterval(value: Int): String { - val seconds = value.coerceAtLeast(0) - return when { - seconds >= 86400 -> "${seconds / 86400}d" - seconds >= 3600 -> "${seconds / 3600}h" - seconds >= 60 -> "${seconds / 60}m" - else -> "${seconds}s" - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/components/ProfileTopBar.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/components/ProfileTopBar.kt deleted file mode 100644 index e4d42425..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/components/ProfileTopBar.kt +++ /dev/null @@ -1,292 +0,0 @@ -package org.monogram.presentation.features.profile.components - -import androidx.compose.animation.* -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.spring -import androidx.compose.animation.core.tween -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.filled.Star -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.TransformOrigin -import androidx.compose.ui.graphics.lerp -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.window.Popup -import androidx.compose.ui.window.PopupProperties -import org.monogram.domain.models.ChatModel -import org.monogram.domain.models.UserModel -import org.monogram.presentation.R -import org.monogram.presentation.features.stickers.ui.menu.MenuOptionRow -import org.monogram.presentation.features.stickers.ui.view.StickerImage -import org.monogram.presentation.features.viewers.components.ViewerSettingsDropdown - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ProfileTopBar( - onBack: () -> Unit, - progress: Float, - title: String, - userModel: UserModel?, - chatModel: ChatModel?, - isVerified: Boolean, - isSponsor: Boolean, - canSearch: Boolean = false, - canShare: Boolean = false, - canEdit: Boolean = false, - canEditContact: Boolean = false, - canReport: Boolean = false, - canBlock: Boolean = false, - isBlocked: Boolean = false, - canDelete: Boolean = false, - onSearch: () -> Unit = {}, - onShare: () -> Unit = {}, - onEdit: () -> Unit = {}, - onEditContact: () -> Unit = {}, - onReport: () -> Unit = {}, - onBlock: () -> Unit = {}, - onDelete: () -> Unit = {} -) { - var showMenu by remember { mutableStateOf(false) } - val hasMenuActions = canShare || canEdit || canEditContact || canReport || canBlock || canDelete - - val iconTint = lerp( - start = MaterialTheme.colorScheme.onSurface, - stop = MaterialTheme.colorScheme.onSurface, - fraction = progress - ) - - val buttonBackground = MaterialTheme.colorScheme.background.copy( - alpha = 0.75f * progress - ) - - Box(modifier = Modifier.fillMaxWidth()) { - TopAppBar( - title = { - Row( - modifier = Modifier - .fillMaxWidth() - .alpha(1f - progress), - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - text = title, - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.SemiBold, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - color = MaterialTheme.colorScheme.onSurface - ) - - if (isVerified) { - Spacer(modifier = Modifier.width(4.dp)) - Icon( - imageVector = Icons.Rounded.Verified, - contentDescription = stringResource(R.string.cd_verified), - modifier = Modifier.size(22.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - if (isSponsor) { - Spacer(modifier = Modifier.width(4.dp)) - Icon( - imageVector = Icons.Rounded.Favorite, - contentDescription = stringResource(R.string.cd_sponsor), - modifier = Modifier.size(22.dp), - tint = Color(0xFFE53935) - ) - } - - userModel?.let { user -> - if (!user.statusEmojiPath.isNullOrEmpty()) { - Spacer(modifier = Modifier.width(4.dp)) - StickerImage( - path = user.statusEmojiPath, - modifier = Modifier.size(22.dp), - animate = false - ) - } else if (user.isPremium) { - Spacer(modifier = Modifier.width(4.dp)) - Icon( - imageVector = Icons.Default.Star, - contentDescription = null, - modifier = Modifier.size(20.dp), - tint = Color(0xFF31A6FD) - ) - } - } - } - }, - navigationIcon = { - Card( - modifier = Modifier.padding(8.dp), - shape = RoundedCornerShape(50), - colors = CardDefaults.cardColors(containerColor = buttonBackground) - ) { - IconButton(onClick = onBack) { - Icon( - imageVector = Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back), - tint = iconTint - ) - } - } - }, - actions = { - if (canSearch || hasMenuActions) { - Card( - modifier = Modifier.padding(8.dp), - shape = RoundedCornerShape(50), - colors = CardDefaults.cardColors(containerColor = buttonBackground) - ) { - Row { - if (canSearch) { - IconButton(onClick = onSearch) { - Icon( - Icons.Rounded.Search, - contentDescription = stringResource(R.string.search_section_chats), - tint = iconTint - ) - } - } - if (hasMenuActions) { - IconButton(onClick = { showMenu = true }) { - Icon(Icons.Rounded.MoreVert, contentDescription = null, tint = iconTint) - } - } - } - } - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = Color.Transparent, - scrolledContainerColor = Color.Transparent - ) - ) - - if (showMenu) { - Popup( - onDismissRequest = { showMenu = false }, - properties = PopupProperties(focusable = true) - ) { - Box( - modifier = Modifier - .fillMaxSize() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null - ) { showMenu = false } - ) { - var isVisible by remember { mutableStateOf(false) } - LaunchedEffect(Unit) { isVisible = true } - - AnimatedVisibility( - visible = isVisible, - enter = fadeIn(tween(150)) + scaleIn( - animationSpec = spring( - dampingRatio = 0.8f, - stiffness = Spring.StiffnessMedium - ), - initialScale = 0.8f, - transformOrigin = TransformOrigin(1f, 0f) - ), - exit = fadeOut(tween(150)) + scaleOut( - animationSpec = tween(150), - targetScale = 0.9f, - transformOrigin = TransformOrigin(1f, 0f) - ), - modifier = Modifier - .align(Alignment.TopEnd) - .windowInsetsPadding(WindowInsets.statusBars) - .padding(top = 56.dp, end = 16.dp) - ) { - ViewerSettingsDropdown { - if (canShare) { - MenuOptionRow( - icon = Icons.Rounded.Share, - title = stringResource(R.string.menu_share), - onClick = { - showMenu = false - onShare() - } - ) - } - if (canEdit) { - MenuOptionRow( - icon = Icons.Rounded.Edit, - title = stringResource(R.string.menu_edit), - onClick = { - showMenu = false - onEdit() - } - ) - } - if (canEditContact) { - MenuOptionRow( - icon = Icons.Rounded.Edit, - title = stringResource(R.string.contact_menu_edit_name), - onClick = { - showMenu = false - onEditContact() - } - ) - } - if (canReport) { - MenuOptionRow( - icon = Icons.Rounded.Report, - title = stringResource(R.string.menu_report), - onClick = { - showMenu = false - onReport() - } - ) - } - if (canBlock && userModel != null) { - MenuOptionRow( - icon = if (isBlocked) Icons.Rounded.LockOpen else Icons.Rounded.Block, - title = if (isBlocked) stringResource(R.string.privacy_unblock_action) else stringResource( - R.string.menu_block_user - ), - textColor = MaterialTheme.colorScheme.error, - iconTint = MaterialTheme.colorScheme.error, - onClick = { - showMenu = false - onBlock() - } - ) - } - if (canDelete) { - MenuOptionRow( - icon = Icons.Rounded.Delete, - title = if (chatModel?.isGroup == true || chatModel?.isChannel == true) stringResource( - R.string.menu_leave - ) else stringResource( - R.string.menu_delete_chat - ), - textColor = MaterialTheme.colorScheme.error, - iconTint = MaterialTheme.colorScheme.error, - onClick = { - showMenu = false - onDelete() - } - ) - } - } - } - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/components/RichSettingsTile.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/components/RichSettingsTile.kt deleted file mode 100644 index dca60a16..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/components/RichSettingsTile.kt +++ /dev/null @@ -1,124 +0,0 @@ -package org.monogram.presentation.features.profile.components - - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.ClickableText -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.platform.LocalUriHandler -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.presentation.core.util.buildRichText -import org.monogram.presentation.core.ui.ItemPosition - -@Composable -fun RichSettingsTile( - icon: ImageVector, - title: String, - content: String, - iconColor: Color, - position: ItemPosition = ItemPosition.STANDALONE, - onCopyClick: (String) -> Unit -) { - val uriHandler = LocalUriHandler.current - val primaryColor = MaterialTheme.colorScheme.primary - - val annotatedContent = remember(content) { - buildRichText(content, primaryColor) - } - - - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape(topStart = cornerRadius, topEnd = cornerRadius, bottomStart = 4.dp, bottomEnd = 4.dp) - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape(bottomStart = cornerRadius, bottomEnd = cornerRadius, topStart = 4.dp, topEnd = 4.dp) - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - - .clickable { onCopyClick(content) } - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 16.dp), - - ) { - - Box( - modifier = Modifier - .size(40.dp) - .background(color = iconColor.copy(0.15f), shape = CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = icon, - contentDescription = null, - modifier = Modifier.size(24.dp), - tint = iconColor - ) - } - - Spacer(modifier = Modifier.width(16.dp)) - - Column(modifier = Modifier.weight(1f)) { - - Text( - text = title, - style = MaterialTheme.typography.titleMedium, - fontSize = 18.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - - Spacer(modifier = Modifier.height(4.dp)) - - - ClickableText( - text = annotatedContent, - style = MaterialTheme.typography.bodyMedium.copy( - color = MaterialTheme.colorScheme.onSurfaceVariant, - fontSize = 15.sp, - lineHeight = 20.sp - ), - onClick = { offset -> - val linkAnnotations = annotatedContent.getStringAnnotations(tag = "URL", start = offset, end = offset) - - if (linkAnnotations.isNotEmpty()) { - val url = linkAnnotations.first().item - try { - uriHandler.openUri(url) - } catch (e: Exception) { - e.printStackTrace() - } - } else { - onCopyClick(content) - } - } - ) - } - } - } - if (position != ItemPosition.BOTTOM && position != ItemPosition.STANDALONE) { - Spacer(Modifier.height(2.dp)) - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/components/StatisticsViewer.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/components/StatisticsViewer.kt deleted file mode 100644 index d272111a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/components/StatisticsViewer.kt +++ /dev/null @@ -1,1583 +0,0 @@ -package org.monogram.presentation.features.profile.components - -import org.monogram.presentation.core.util.coRunCatching -import androidx.compose.animation.* -import androidx.compose.animation.core.* -import androidx.compose.foundation.* -import androidx.compose.foundation.gestures.detectDragGestures -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.selection.SelectionContainer -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.Chat -import androidx.compose.material.icons.automirrored.rounded.Message -import androidx.compose.material.icons.automirrored.rounded.TrendingDown -import androidx.compose.material.icons.automirrored.rounded.TrendingUp -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.* -import androidx.compose.ui.graphics.drawscope.DrawScope -import androidx.compose.ui.graphics.drawscope.Stroke -import androidx.compose.ui.graphics.drawscope.clipRect -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.json.JSONObject -import org.monogram.domain.models.* -import org.monogram.presentation.R -import org.monogram.presentation.features.chats.chatList.components.SectionHeader -import java.text.SimpleDateFormat -import java.util.* -import kotlin.math.abs -import kotlin.math.roundToInt - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun StatisticsViewer( - title: String, - data: Any?, - onDismiss: () -> Unit, - onLoadGraph: (String) -> Unit = {} -) { - ModalBottomSheet( - onDismissRequest = onDismiss, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp), - sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true), - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 4.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = title, - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - } - - Spacer(modifier = Modifier.height(16.dp)) - - Crossfade( - targetState = data, - animationSpec = tween(500), - modifier = Modifier.fillMaxWidth(), - label = "ScreenState" - ) { stateData -> - if (stateData == null) { - Box(modifier = Modifier - .fillMaxWidth() - .height(300.dp), contentAlignment = Alignment.Center) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - CircularProgressIndicator( - strokeWidth = 4.dp, - strokeCap = StrokeCap.Round, - color = MaterialTheme.colorScheme.primary - ) - Spacer(modifier = Modifier.height(16.dp)) - Text( - stringResource(R.string.statistics_analyzing), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } else { - Column( - modifier = Modifier - .fillMaxWidth() - .verticalScroll(rememberScrollState()) - .padding(vertical = 16.dp), - verticalArrangement = Arrangement.spacedBy(24.dp) - ) { - when (stateData) { - is ChatStatisticsModel -> { - if (stateData.type == StatisticsType.SUPERGROUP) { - SupergroupStatistics(stateData, onLoadGraph) - } else { - ChannelStatistics(stateData, onLoadGraph) - } - } - - is ChatRevenueStatisticsModel -> RevenueStatistics(stateData, onLoadGraph) - else -> FallbackView(stateData) - } - } - } - } - } - } -} - -@Composable -fun SupergroupStatistics(stats: ChatStatisticsModel, onLoadGraph: (String) -> Unit) { - Column(verticalArrangement = Arrangement.spacedBy(6.dp)) { - OverviewSection(period = stats.period) - Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { - Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) { - StatCard( - modifier = Modifier.weight(1f), - title = stringResource(R.string.statistics_members), - current = stats.memberCount.value, - previous = stats.memberCount.previousValue, - icon = Icons.Rounded.Groups, - color = Color(0xFF4285F4) - ) - stats.messageCount?.let { - StatCard( - modifier = Modifier.weight(1f), - title = stringResource(R.string.statistics_messages), - current = it.value, - previous = it.previousValue, - icon = Icons.AutoMirrored.Rounded.Chat, - color = Color(0xFF34A853) - ) - } - } - Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) { - stats.viewerCount?.let { - StatCard( - modifier = Modifier.weight(1f), - title = stringResource(R.string.statistics_viewers), - current = it.value, - previous = it.previousValue, - icon = Icons.Rounded.Visibility, - color = Color(0xFFFBBC04) - ) - } - stats.senderCount?.let { - StatCard( - modifier = Modifier.weight(1f), - title = stringResource(R.string.statistics_active_senders), - current = it.value, - previous = it.previousValue, - icon = Icons.Rounded.Person, - color = Color(0xFFEA4335) - ) - } - } - } - } - - stats.memberCountGraph?.let { GraphSection(stringResource(R.string.statistics_member_growth), it, Color(0xFF4285F4), onLoadGraph) } - stats.joinGraph?.let { GraphSection(stringResource(R.string.statistics_new_members), it, Color(0xFF34A853), onLoadGraph) } - stats.muteGraph?.let { GraphSection(stringResource(R.string.notifications_title), it, Color(0xFFEA4335), onLoadGraph) } - stats.messageContentGraph?.let { GraphSection(stringResource(R.string.statistics_message_content), it, Color(0xFF673AB7), onLoadGraph) } - stats.actionGraph?.let { GraphSection(stringResource(R.string.statistics_actions), it, Color(0xFFFBBC04), onLoadGraph) } - stats.dayGraph?.let { GraphSection(stringResource(R.string.statistics_activity_day), it, Color(0xFF00BCD4), onLoadGraph) } - stats.weekGraph?.let { GraphSection(stringResource(R.string.statistics_activity_week), it, Color(0xFF3F51B5), onLoadGraph) } - stats.topHoursGraph?.let { GraphSection(stringResource(R.string.statistics_top_hours), it, Color(0xFFFF9800), onLoadGraph) } - stats.viewCountBySourceGraph?.let { GraphSection(stringResource(R.string.statistics_views_source), it, Color(0xFF00BCD4), onLoadGraph) } - stats.joinBySourceGraph?.let { GraphSection(stringResource(R.string.statistics_new_members_source), it, Color(0xFF3F51B5), onLoadGraph) } - stats.languageGraph?.let { GraphSection(stringResource(R.string.statistics_languages), it, Color(0xFF673AB7), onLoadGraph) } - - if (stats.topSenders.isNotEmpty()) { - ExpandableListSection( - title = stringResource(R.string.statistics_top_senders), - icon = Icons.Rounded.Leaderboard, - items = stats.topSenders, - initialCount = 5 - ) { index, sender -> - val maxSent = stats.topSenders.maxOfOrNull { it.sentMessageCount }?.toFloat() ?: 1f - UserBarChartItem( - rank = index + 1, - userId = sender.userId.toString(), - primaryValue = sender.sentMessageCount.toString(), - primaryLabel = stringResource(R.string.statistics_msgs_label), - secondaryValue = stringResource(R.string.statistics_avg_chars_format, sender.averageCharacterCount), - progress = sender.sentMessageCount / maxSent, - barColor = Color(0xFF34A853) - ) - } - } - - if (stats.topAdministrators.isNotEmpty()) { - ExpandableListSection( - title = stringResource(R.string.statistics_top_admins), - icon = Icons.Rounded.AdminPanelSettings, - items = stats.topAdministrators, - initialCount = 5 - ) { index, admin -> - val maxActions = - stats.topAdministrators.maxOfOrNull { it.deletedMessageCount + it.bannedUserCount }?.toFloat() ?: 1f - val totalActions = admin.deletedMessageCount + admin.bannedUserCount - UserBarChartItem( - rank = index + 1, - userId = admin.userId.toString(), - primaryValue = totalActions.toString(), - primaryLabel = stringResource(R.string.statistics_actions_label), - secondaryValue = stringResource(R.string.statistics_admin_actions_format, admin.deletedMessageCount, admin.bannedUserCount), - progress = totalActions / maxActions, - barColor = Color(0xFFEA4335) - ) - } - } - - if (stats.topInviters.isNotEmpty()) { - ExpandableListSection( - title = stringResource(R.string.statistics_top_inviters), - icon = Icons.Rounded.PersonAdd, - items = stats.topInviters, - initialCount = 5 - ) { index, inviter -> - val maxInvites = stats.topInviters.maxOfOrNull { it.addedMemberCount }?.toFloat() ?: 1f - UserBarChartItem( - rank = index + 1, - userId = inviter.userId.toString(), - primaryValue = inviter.addedMemberCount.toString(), - primaryLabel = stringResource(R.string.statistics_invites_label), - secondaryValue = stringResource(R.string.statistics_added_members_label), - progress = inviter.addedMemberCount / maxInvites, - barColor = Color(0xFFFBBC04) - ) - } - } -} - -@Composable -fun ChannelStatistics(stats: ChatStatisticsModel, onLoadGraph: (String) -> Unit) { - Column(verticalArrangement = Arrangement.spacedBy(6.dp)) { - OverviewSection(period = stats.period) - Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { - StatCard( - modifier = Modifier.fillMaxWidth(), - title = stringResource(R.string.statistics_subscribers), - current = stats.memberCount.value, - previous = stats.memberCount.previousValue, - icon = Icons.Rounded.Groups, - color = Color(0xFF4285F4) - ) - - stats.enabledNotificationsPercentage?.let { - StatCard( - modifier = Modifier.fillMaxWidth(), - title = stringResource(R.string.statistics_notifications_enabled), - current = it, - previous = it, - isPercentage = true, - icon = Icons.Rounded.NotificationsActive, - color = Color(0xFF673AB7) - ) - } - - Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) { - stats.meanViewCount?.let { - StatCard( - modifier = Modifier.weight(1f), - title = stringResource(R.string.statistics_avg_msg_views), - current = it.value, - previous = it.previousValue, - icon = Icons.Rounded.RemoveRedEye, - color = Color(0xFF34A853) - ) - } - stats.meanShareCount?.let { - StatCard( - modifier = Modifier.weight(1f), - title = stringResource(R.string.statistics_avg_msg_shares), - current = it.value, - previous = it.previousValue, - icon = Icons.Rounded.Share, - color = Color(0xFFEA4335) - ) - } - } - - Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) { - stats.meanReactionCount?.let { - StatCard( - modifier = Modifier.weight(1f), - title = stringResource(R.string.statistics_avg_reactions), - current = it.value, - previous = it.previousValue, - icon = Icons.Rounded.EmojiEmotions, - color = Color(0xFFFBBC04) - ) - } - } - } - } - - stats.memberCountGraph?.let { GraphSection(stringResource(R.string.statistics_growth), it, Color(0xFF4285F4), onLoadGraph) } - stats.joinGraph?.let { GraphSection(stringResource(R.string.statistics_new_subscribers), it, Color(0xFF34A853), onLoadGraph) } - stats.muteGraph?.let { GraphSection(stringResource(R.string.notifications_title), it, Color(0xFFEA4335), onLoadGraph) } - stats.viewCountByHourGraph?.let { GraphSection(stringResource(R.string.statistics_views_hour), it, Color(0xFFFBBC04), onLoadGraph) } - stats.viewCountBySourceGraph?.let { GraphSection(stringResource(R.string.statistics_views_source), it, Color(0xFF00BCD4), onLoadGraph) } - stats.joinBySourceGraph?.let { GraphSection(stringResource(R.string.statistics_new_members_source), it, Color(0xFF3F51B5), onLoadGraph) } - stats.languageGraph?.let { GraphSection(stringResource(R.string.statistics_languages), it, Color(0xFF673AB7), onLoadGraph) } - stats.messageContentGraph?.let { GraphSection(stringResource(R.string.statistics_msg_interactions), it, Color(0xFF4CAF50), onLoadGraph) } - stats.actionGraph?.let { GraphSection(stringResource(R.string.statistics_iv_interactions), it, Color(0xFFFF9800), onLoadGraph) } - stats.messageReactionGraph?.let { GraphSection(stringResource(R.string.statistics_msg_reactions), it, Color(0xFF9C27B0), onLoadGraph) } - - if (stats.recentInteractions.isNotEmpty()) { - ExpandableListSection( - title = stringResource(R.string.statistics_recent_interactions), - icon = Icons.Rounded.DynamicFeed, - items = stats.recentInteractions, - initialCount = 5 - ) { _, interaction -> - InteractionItem(interaction) - } - } -} - -@Composable -fun InteractionItem(interaction: ChatInteractionInfoModel) { - var expanded by remember { mutableStateOf(false) } - val totalEngagement = interaction.forwardCount + interaction.reactionCount - val engagementRate = if (interaction.viewCount > 0) { - (totalEngagement.toFloat() / interaction.viewCount.toFloat()) * 100f - } else { - 0f - } - val shareRate = if (interaction.viewCount > 0) { - (interaction.forwardCount.toFloat() / interaction.viewCount.toFloat()) * 100f - } else { - 0f - } - val reactionRate = if (interaction.viewCount > 0) { - (interaction.reactionCount.toFloat() / interaction.viewCount.toFloat()) * 100f - } else { - 0f - } - val dominantMetric = - maxOf(interaction.viewCount, interaction.forwardCount, interaction.reactionCount).coerceAtLeast(1) - - Surface( - modifier = Modifier - .fillMaxWidth() - .clickable { expanded = !expanded } - .animateContentSize( - animationSpec = spring( - dampingRatio = Spring.DampingRatioMediumBouncy, - stiffness = Spring.StiffnessLow - ) - ), - shape = RoundedCornerShape(20.dp), - color = MaterialTheme.colorScheme.surfaceContainerHigh - ) { - Column(modifier = Modifier.padding(16.dp)) { - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(48.dp) - .background(MaterialTheme.colorScheme.primaryContainer, CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = if (interaction.type == ChatInteractionType.MESSAGE) Icons.AutoMirrored.Rounded.Message else Icons.Rounded.AmpStories, - contentDescription = null, - tint = MaterialTheme.colorScheme.onPrimaryContainer, - modifier = Modifier.size(24.dp) - ) - } - Spacer(modifier = Modifier.width(16.dp)) - Column(modifier = Modifier.weight(1f)) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = if (interaction.type == ChatInteractionType.MESSAGE) stringResource(R.string.statistics_interaction_message) else stringResource(R.string.statistics_interaction_story), - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - Icon( - imageVector = if (expanded) Icons.Rounded.ExpandLess else Icons.Rounded.ExpandMore, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary - ) - } - - Spacer(modifier = Modifier.height(10.dp)) - Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) { - InteractionStat(Icons.Rounded.Visibility, interaction.viewCount) - InteractionStat(Icons.Rounded.Share, interaction.forwardCount) - InteractionStat(Icons.Rounded.EmojiEmotions, interaction.reactionCount) - } - Spacer(modifier = Modifier.height(10.dp)) - LinearProgressIndicator( - progress = { (interaction.viewCount.toFloat() / dominantMetric.toFloat()).coerceIn(0f, 1f) }, - modifier = Modifier - .fillMaxWidth() - .height(6.dp) - .clip(CircleShape), - color = MaterialTheme.colorScheme.primary, - trackColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.15f), - drawStopIndicator = {} - ) - Spacer(modifier = Modifier.height(8.dp)) - Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { - CompactInsightChip( - label = "Share rate", - value = String.format("%.1f%%", shareRate), - tint = Color(0xFFEA4335) - ) - CompactInsightChip( - label = "Reaction rate", - value = String.format("%.1f%%", reactionRate), - tint = Color(0xFFFBBC04) - ) - } - interaction.previewText?.takeIf { it.isNotBlank() }?.let { preview -> - Spacer(modifier = Modifier.height(10.dp)) - Surface( - color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.35f), - shape = RoundedCornerShape(10.dp) - ) { - Text( - text = preview, - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurface, - maxLines = 2, - modifier = Modifier.padding(horizontal = 10.dp, vertical = 8.dp) - ) - } - } - } - } - AnimatedVisibility( - visible = expanded, - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically() - ) { - Column(modifier = Modifier.padding(top = 16.dp)) { - HorizontalDivider(color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f)) - Spacer(modifier = Modifier.height(12.dp)) - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween - ) { - Column { - Text( - stringResource(R.string.statistics_post_id), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Text( - interaction.objectId.toString(), - style = MaterialTheme.typography.bodyMedium, - fontWeight = FontWeight.Medium - ) - } - Column(horizontalAlignment = Alignment.End) { - Text( - text = "ER", - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Text( - text = String.format("%.1f%%", engagementRate), - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) - } - } - Spacer(modifier = Modifier.height(10.dp)) - Text( - text = "Total engagement: ${formatStatNumber(totalEngagement)}", - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } - } -} - -@Composable -private fun CompactInsightChip(label: String, value: String, tint: Color) { - Surface( - color = tint.copy(alpha = 0.12f), - shape = RoundedCornerShape(10.dp) - ) { - Row( - modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(4.dp) - ) { - Text( - text = label, - style = MaterialTheme.typography.labelSmall, - color = tint - ) - Text( - text = value, - style = MaterialTheme.typography.labelSmall, - color = tint, - fontWeight = FontWeight.Bold - ) - } - } -} - -@Composable -fun InteractionStat(icon: ImageVector, count: Int) { - Surface( - color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f), - shape = RoundedCornerShape(8.dp) - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp) - ) { - Icon( - imageVector = icon, - contentDescription = null, - modifier = Modifier.size(14.dp), - tint = MaterialTheme.colorScheme.primary - ) - Spacer(modifier = Modifier.width(6.dp)) - Text( - text = count.toString(), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - fontWeight = FontWeight.SemiBold - ) - } - } -} - -@Composable -fun ExpandableListSection( - title: String, - icon: ImageVector, - items: List, - initialCount: Int, - itemContent: @Composable (index: Int, item: T) -> Unit -) { - var isExpanded by remember { mutableStateOf(false) } - val displayItems = if (isExpanded) items else items.take(initialCount) - - Column(modifier = Modifier.animateContentSize(spring(stiffness = Spring.StiffnessLow))) { - SectionHeader(title) - Surface( - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(24.dp), - color = MaterialTheme.colorScheme.surfaceContainer - ) { - Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) { - displayItems.forEachIndexed { index, item -> - itemContent(index, item) - if (index < displayItems.size - 1) { - HorizontalDivider( - thickness = 1.dp, - color = MaterialTheme.colorScheme.surfaceVariant - ) - } - } - - if (items.size > initialCount) { - FilledTonalButton( - onClick = { isExpanded = !isExpanded }, - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(16.dp), - colors = ButtonDefaults.filledTonalButtonColors( - containerColor = MaterialTheme.colorScheme.secondaryContainer - ) - ) { - Text(if (isExpanded) stringResource(R.string.statistics_show_less) else stringResource(R.string.statistics_show_all_format, items.size), fontWeight = FontWeight.Bold) - Spacer(modifier = Modifier.width(8.dp)) - Icon( - if (isExpanded) Icons.Rounded.ExpandLess else Icons.Rounded.ExpandMore, - contentDescription = null - ) - } - } - } - } - } -} - -@Composable -fun RevenueStatistics(stats: ChatRevenueStatisticsModel, onLoadGraph: (String) -> Unit) { - SectionHeader(stringResource(R.string.statistics_revenue_header)) - - val available = stats.revenueAmount.availableBalance - val total = stats.revenueAmount.balance - - Surface( - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(28.dp), - color = MaterialTheme.colorScheme.surfaceContainer, - border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f)) - ) { - Column( - modifier = Modifier.padding(18.dp), - verticalArrangement = Arrangement.spacedBy(14.dp) - ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { - Text( - text = stringResource(R.string.statistics_available_balance), - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Row(verticalAlignment = Alignment.Bottom) { - Text( - text = formatLongCompact(available), - style = MaterialTheme.typography.headlineLarge, - color = MaterialTheme.colorScheme.onSurface, - fontWeight = FontWeight.Black - ) - Spacer(modifier = Modifier.width(6.dp)) - Text( - text = stats.revenueAmount.currency, - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(bottom = 4.dp) - ) - } - } - - Surface( - color = Color(0xFF34A853).copy(alpha = 0.14f), - shape = RoundedCornerShape(12.dp) - ) { - Row( - modifier = Modifier.padding(horizontal = 10.dp, vertical = 6.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(4.dp) - ) { - Icon( - imageVector = Icons.Rounded.Payments, - contentDescription = null, - tint = Color(0xFF34A853), - modifier = Modifier.size(14.dp) - ) - Text( - text = stringResource(R.string.revenue_title), - style = MaterialTheme.typography.labelMedium, - color = Color(0xFF34A853), - fontWeight = FontWeight.Bold - ) - } - } - } - - Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) { - RevenueMetricCard( - modifier = Modifier.weight(1f), - label = stringResource(R.string.statistics_total_balance), - value = "${formatLongCompact(total)} ${stats.revenueAmount.currency}", - tint = Color(0xFF4285F4) - ) - RevenueMetricCard( - modifier = Modifier.weight(1f), - label = stringResource(R.string.statistics_available_balance), - value = "${formatLongCompact(available)} ${stats.revenueAmount.currency}", - tint = Color(0xFFFF9800) - ) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.45f), - shape = RoundedCornerShape(12.dp) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 12.dp, vertical = 8.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = stringResource(R.string.statistics_exchange_rate), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Text( - text = "1 USD = ${ - String.format( - Locale.getDefault(), - "%.4f", - stats.usdRate - ) - } ${stats.revenueAmount.currency}", - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.onSurface, - fontWeight = FontWeight.SemiBold - ) - } - } - } - } - - Spacer(modifier = Modifier.height(16.dp)) - GraphSection(stringResource(R.string.statistics_revenue_growth), stats.revenueGraph, Color(0xFF34A853), onLoadGraph) - GraphSection(stringResource(R.string.statistics_hourly_revenue), stats.revenueByHourGraph, Color(0xFFFBBC04), onLoadGraph) -} - -@Composable -private fun RevenueMetricCard(modifier: Modifier = Modifier, label: String, value: String, tint: Color) { - Surface( - modifier = modifier, - color = tint.copy(alpha = 0.12f), - shape = RoundedCornerShape(14.dp) - ) { - Column( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 10.dp), - verticalArrangement = Arrangement.spacedBy(2.dp) - ) { - Text( - text = label, - style = MaterialTheme.typography.labelSmall, - color = tint - ) - Text( - text = value, - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.onSurface, - fontWeight = FontWeight.Bold - ) - } - } -} - -@Composable -fun GraphSection(title: String, graph: StatisticsGraphModel, color: Color, onLoadGraph: (String) -> Unit) { - if (graph is StatisticsGraphModel.Error) return - val parsedGraph = remember(graph) { - if (graph is StatisticsGraphModel.Data) parseStatisticsGraph(graph.jsonData) else null - } - - Column { - SectionHeader(title) - Surface( - modifier = Modifier - .fillMaxWidth() - .height(280.dp), - shape = RoundedCornerShape(24.dp), - color = MaterialTheme.colorScheme.surfaceContainer - ) { - when (graph) { - is StatisticsGraphModel.Data -> { - Column(modifier = Modifier.padding(20.dp)) { - Box( - modifier = Modifier - .weight(1f) - .fillMaxWidth() - ) { - if (parsedGraph != null) { - InteractiveStatisticsChart(parsedGraph, color) - } else { - SimpleBezierChartContent(color = color) - } - } - } - } - - is StatisticsGraphModel.Async -> { - LaunchedEffect(graph.token) { - onLoadGraph(graph.token) - } - Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - CircularProgressIndicator( - modifier = Modifier.size(48.dp), - strokeWidth = 4.dp, - color = color, - strokeCap = StrokeCap.Round - ) - Spacer(modifier = Modifier.height(16.dp)) - Text( - stringResource(R.string.statistics_rendering_chart), - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - fontWeight = FontWeight.Medium - ) - } - } - } - } - } - } -} - -@Composable -fun StatCard( - modifier: Modifier = Modifier, - title: String, - current: Double, - previous: Double, - icon: ImageVector, - color: Color = MaterialTheme.colorScheme.primary, - isPercentage: Boolean = false, - showComparison: Boolean = true -) { - val diff = current - previous - val percentageChange = if (previous != 0.0) (diff / previous) * 100 else 0.0 - - val deltaColor = when { - diff > 0 -> Color(0xFF4CAF50) - diff < 0 -> Color(0xFFE91E63) - else -> MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f) - } - - val deltaIcon = when { - diff > 0 -> Icons.AutoMirrored.Rounded.TrendingUp - diff < 0 -> Icons.AutoMirrored.Rounded.TrendingDown - else -> Icons.Rounded.HorizontalRule - } - - var startAnimation by remember { mutableStateOf(false) } - LaunchedEffect(current) { startAnimation = true } - - val animatedCurrent by animateFloatAsState( - targetValue = if (startAnimation) current.toFloat() else 0f, - animationSpec = tween(durationMillis = 1200, easing = FastOutSlowInEasing), - label = "stat_count" - ) - - Surface( - modifier = modifier, - shape = RoundedCornerShape(24.dp), - color = MaterialTheme.colorScheme.surfaceContainer - ) { - Column(modifier = Modifier.padding(20.dp)) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.Top - ) { - Box( - modifier = Modifier - .size(48.dp) - .background(color.copy(alpha = 0.15f), RoundedCornerShape(14.dp)), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = icon, - contentDescription = null, - modifier = Modifier.size(24.dp), - tint = color - ) - } - if (showComparison && !isPercentage && previous != 0.0) { - Surface( - color = deltaColor.copy(alpha = 0.1f), - shape = RoundedCornerShape(12.dp) - ) { - Row( - modifier = Modifier.padding(horizontal = 8.dp, vertical = 6.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Icon( - imageVector = deltaIcon, - contentDescription = null, - modifier = Modifier.size(16.dp), - tint = deltaColor - ) - Spacer(modifier = Modifier.width(4.dp)) - Text( - text = "${String.format("%.1f", abs(percentageChange))}%", - style = MaterialTheme.typography.labelMedium, - color = deltaColor, - fontWeight = FontWeight.Bold - ) - } - } - } - } - Spacer(modifier = Modifier.height(20.dp)) - Text( - text = title, - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - fontWeight = FontWeight.SemiBold - ) - Spacer(modifier = Modifier.height(4.dp)) - - val formattedValue = - if (isPercentage) String.format("%.2f%%", animatedCurrent) else animatedCurrent.toInt().toString() - Text( - text = formattedValue, - style = MaterialTheme.typography.headlineMedium, - fontWeight = FontWeight.Black, - color = MaterialTheme.colorScheme.onSurface - ) - - if (showComparison && !isPercentage && previous != 0.0) { - Spacer(modifier = Modifier.height(6.dp)) - if (diff == 0.0) { - Text( - text = "${stringResource(R.string.statistics_no_change)} ${stringResource(R.string.statistics_vs_previous)}", - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - lineHeight = 17.sp - ) - } else { - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = if (diff > 0) "+${diff.toInt()}" else "${diff.toInt()}", - style = MaterialTheme.typography.labelSmall, - color = deltaColor, - fontWeight = FontWeight.Bold - ) - Spacer(modifier = Modifier.width(4.dp)) - Text( - text = stringResource(R.string.statistics_vs_previous), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.weight(1f), - lineHeight = 17.sp - ) - } - } - } - } - } -} - -@Composable -fun UserBarChartItem( - rank: Int, - userId: String, - primaryValue: String, - primaryLabel: String, - secondaryValue: String, - progress: Float, - barColor: Color = MaterialTheme.colorScheme.primary -) { - var startAnimation by remember { mutableStateOf(false) } - LaunchedEffect(Unit) { startAnimation = true } - - val animatedProgress by animateFloatAsState( - targetValue = if (startAnimation) progress.coerceIn(0f, 1f) else 0f, - animationSpec = spring(dampingRatio = Spring.DampingRatioLowBouncy, stiffness = Spring.StiffnessLow), - label = "progress" - ) - - Column(modifier = Modifier - .fillMaxWidth() - .padding(vertical = 4.dp)) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.weight(1f)) { - Box( - modifier = Modifier - .size(44.dp) - .background(barColor.copy(alpha = 0.15f), CircleShape), - contentAlignment = Alignment.Center - ) { - Text( - userId.take(1).uppercase(), - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.Bold, - color = barColor - ) - } - Spacer(modifier = Modifier.width(16.dp)) - Column { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(6.dp) - ) { - Surface( - color = barColor.copy(alpha = 0.15f), - shape = RoundedCornerShape(8.dp) - ) { - Text( - text = "#$rank", - style = MaterialTheme.typography.labelSmall, - color = barColor, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(horizontal = 6.dp, vertical = 2.dp) - ) - } - Text( - text = "${stringResource(R.string.label_id)}: $userId", - style = MaterialTheme.typography.titleSmall, - fontWeight = FontWeight.Bold - ) - } - Text( - secondaryValue, - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - Column(horizontalAlignment = Alignment.End) { - Text( - primaryValue, - style = MaterialTheme.typography.titleLarge, - fontWeight = FontWeight.Black, - color = barColor - ) - Text( - primaryLabel.uppercase(), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - fontWeight = FontWeight.Bold - ) - } - } - Spacer(modifier = Modifier.height(14.dp)) - Box( - modifier = Modifier - .fillMaxWidth() - .height(10.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.4f)) - ) { - Box( - modifier = Modifier - .fillMaxWidth(animatedProgress) - .fillMaxHeight() - .clip(CircleShape) - .background(Brush.horizontalGradient(listOf(barColor.copy(alpha = 0.6f), barColor))) - ) - } - } -} - -@Composable -fun SimpleBezierChartContent(color: Color) { - var isLoaded by remember { mutableStateOf(false) } - LaunchedEffect(Unit) { isLoaded = true } - - val animationProgress by animateFloatAsState( - targetValue = if (isLoaded) 1f else 0f, - animationSpec = tween(durationMillis = 1500, easing = FastOutSlowInEasing), - label = "chartDraw" - ) - - Canvas(modifier = Modifier.fillMaxSize()) { - val width = size.width - val height = size.height - - val path = Path().apply { - moveTo(0f, height * 0.8f) - cubicTo( - width * 0.2f, height * 0.9f, - width * 0.4f, height * 0.2f, - width * 0.6f, height * 0.5f - ) - cubicTo( - width * 0.8f, height * 0.8f, - width * 0.9f, height * 0.1f, - width, height * 0.3f - ) - } - - val fillPath = Path().apply { - addPath(path) - lineTo(width, height) - lineTo(0f, height) - close() - } - - clipRect(right = width * animationProgress) { - drawPath( - path = fillPath, - brush = Brush.verticalGradient( - colors = listOf(color.copy(alpha = 0.4f), Color.Transparent) - ) - ) - - drawPath( - path = path, - color = color, - style = Stroke(width = 4.dp.toPx(), cap = StrokeCap.Round, join = StrokeJoin.Round) - ) - } - } -} - -@Composable -private fun OverviewSection(period: DateRangeModel) { - Text( - text = stringResource(R.string.statistics_overview), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold, - modifier = Modifier - .fillMaxWidth() - .padding(start = 12.dp, bottom = 4.dp) - ) - Surface( - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(20.dp), - color = MaterialTheme.colorScheme.surfaceContainer - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 14.dp, vertical = 12.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - Icon( - imageVector = Icons.Rounded.CalendarMonth, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.size(18.dp) - ) - Text( - text = "${formatDate(period.startDate)} - ${formatDate(period.endDate)}", - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.onSurface - ) - } - Surface( - color = MaterialTheme.colorScheme.secondaryContainer, - shape = RoundedCornerShape(10.dp) - ) { - val days = ((period.endDate - period.startDate) / (24 * 60 * 60)).coerceAtLeast(1) - Text( - text = stringResource(R.string.days_count_format, days), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSecondaryContainer, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp) - ) - } - } - } - Spacer(modifier = Modifier.height(2.dp)) -} - -@Composable -private fun InteractiveStatisticsChart(graph: ParsedStatisticsGraph, accentColor: Color) { - if (graph.series.isEmpty() || graph.labels.isEmpty()) { - Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { - Text( - text = stringResource(R.string.statistics_rendering_chart), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - return - } - - var selectedSeriesIndex by remember(graph) { mutableStateOf(0) } - var selectedPointIndex by remember(graph) { mutableStateOf(graph.labels.lastIndex.coerceAtLeast(0)) } - val activeSeries = graph.series[selectedSeriesIndex.coerceIn(0, graph.series.lastIndex)] - val safePointIndex = selectedPointIndex.coerceIn(0, graph.labels.lastIndex) - val markerInnerColor = MaterialTheme.colorScheme.surface - - Column(modifier = Modifier.fillMaxSize()) { - if (graph.series.size > 1) { - Row( - modifier = Modifier - .horizontalScroll(rememberScrollState()) - .fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - graph.series.forEachIndexed { index, series -> - FilterChip( - selected = index == selectedSeriesIndex, - onClick = { - selectedSeriesIndex = index - selectedPointIndex = graph.labels.lastIndex - }, - label = { - Text( - text = series.name, - maxLines = 1 - ) - }, - leadingIcon = { - Box( - modifier = Modifier - .size(10.dp) - .background(series.color, CircleShape) - ) - } - ) - } - } - Spacer(modifier = Modifier.height(12.dp)) - } - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Column { - Text( - text = graph.labels[safePointIndex], - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Text( - text = formatStatNumber(activeSeries.values[safePointIndex].toInt()), - style = MaterialTheme.typography.titleLarge, - color = activeSeries.color, - fontWeight = FontWeight.Bold - ) - } - Text( - text = "Avg ${formatStatNumber(activeSeries.values.average().toInt())}", - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.End - ) - } - - Spacer(modifier = Modifier.height(10.dp)) - - Canvas( - modifier = Modifier - .fillMaxSize() - .clip(RoundedCornerShape(16.dp)) - .background(MaterialTheme.colorScheme.surfaceContainerHigh.copy(alpha = 0.45f)) - .pointerInput(graph, selectedSeriesIndex) { - detectDragGestures( - onDragStart = { offset -> - selectedPointIndex = pointIndexForOffset( - offset.x, - size.width.toFloat(), - graph.labels.size - ) - }, - onDrag = { change, _ -> - selectedPointIndex = pointIndexForOffset( - change.position.x, - size.width.toFloat(), - graph.labels.size - ) - } - ) - } - .pointerInput(graph, selectedSeriesIndex) { - detectTapGestures { offset -> - selectedPointIndex = pointIndexForOffset( - offset.x, - size.width.toFloat(), - graph.labels.size - ) - } - } - .padding(horizontal = 12.dp, vertical = 12.dp) - ) { - drawChartGrid() - - val lineThickness = 3.dp.toPx() - graph.series.forEachIndexed { index, series -> - val alpha = if (index == selectedSeriesIndex) 1f else 0.3f - drawSeriesPath(series = series, strokeWidth = lineThickness, alpha = alpha) - } - - val xStep = if (graph.labels.size > 1) size.width / (graph.labels.size - 1) else 0f - val pointX = xStep * safePointIndex - drawLine( - color = accentColor.copy(alpha = 0.35f), - start = Offset(pointX, 0f), - end = Offset(pointX, size.height), - strokeWidth = 1.dp.toPx() - ) - - val y = normalizeToCanvasY(activeSeries.values[safePointIndex], activeSeries.values, size.height) - drawCircle( - color = activeSeries.color, - radius = 6.dp.toPx(), - center = Offset(pointX, y) - ) - drawCircle( - color = markerInnerColor, - radius = 3.dp.toPx(), - center = Offset(pointX, y) - ) - } - } -} - -private fun DrawScope.drawSeriesPath(series: ParsedStatisticsSeries, strokeWidth: Float, alpha: Float) { - if (series.values.isEmpty()) return - val values = series.values - val xStep = if (values.size > 1) size.width / (values.size - 1) else 0f - - val linePath = Path().apply { - values.forEachIndexed { index, value -> - val point = Offset( - x = xStep * index, - y = normalizeToCanvasY(value, values, size.height) - ) - if (index == 0) moveTo(point.x, point.y) else lineTo(point.x, point.y) - } - } - - val fillPath = Path().apply { - addPath(linePath) - lineTo(size.width, size.height) - lineTo(0f, size.height) - close() - } - - drawPath( - path = fillPath, - brush = Brush.verticalGradient( - colors = listOf(series.color.copy(alpha = 0.20f * alpha), Color.Transparent) - ) - ) - drawPath( - path = linePath, - color = series.color.copy(alpha = alpha), - style = Stroke(width = strokeWidth, cap = StrokeCap.Round, join = StrokeJoin.Round) - ) -} - -private fun DrawScope.drawChartGrid() { - val stroke = 1.dp.toPx() - repeat(4) { index -> - val y = size.height * (index + 1) / 5f - drawLine( - color = Color.Gray.copy(alpha = 0.22f), - start = Offset(0f, y), - end = Offset(size.width, y), - strokeWidth = stroke - ) - } -} - -private fun normalizeToCanvasY(value: Float, allValues: List, canvasHeight: Float): Float { - val minValue = allValues.minOrNull() ?: 0f - val maxValue = allValues.maxOrNull() ?: 1f - if (maxValue <= minValue) return canvasHeight * 0.5f - val normalized = (value - minValue) / (maxValue - minValue) - return canvasHeight - (normalized * canvasHeight) -} - -private fun pointIndexForOffset(x: Float, width: Float, pointCount: Int): Int { - if (pointCount <= 1 || width <= 0f) return 0 - val safeX = x.coerceIn(0f, width) - return ((safeX / width) * (pointCount - 1)).roundToInt().coerceIn(0, pointCount - 1) -} - -private data class ParsedStatisticsGraph( - val labels: List, - val series: List -) - -private data class ParsedStatisticsSeries( - val key: String, - val name: String, - val color: Color, - val values: List -) - -private fun parseStatisticsGraph(jsonData: String): ParsedStatisticsGraph? { - return coRunCatching { - val root = JSONObject(jsonData) - val columnsArray = root.optJSONArray("columns") ?: return null - val typesObject = root.optJSONObject("types") ?: return null - val namesObject = root.optJSONObject("names") ?: JSONObject() - val colorsObject = root.optJSONObject("colors") ?: JSONObject() - - val columnValuesByKey = linkedMapOf>() - for (i in 0 until columnsArray.length()) { - val column = columnsArray.optJSONArray(i) ?: continue - if (column.length() < 2) continue - val key = column.optString(0) - if (key.isBlank()) continue - val values = mutableListOf() - for (j in 1 until column.length()) { - values.add(column.optDouble(j, 0.0).toFloat()) - } - columnValuesByKey[key] = values - } - - val xKey = typesObject.keys().asSequence().firstOrNull { typesObject.optString(it) == "x" } - val xValues = xKey?.let { columnValuesByKey[it] }.orEmpty() - val labelCount = xValues.size.takeIf { it > 0 } - ?: columnValuesByKey.values.maxOfOrNull { it.size } - ?: return null - - val labels = (0 until labelCount).map { index -> - val rawX = xValues.getOrNull(index)?.toLong() ?: index.toLong() - formatChartXAxisLabel(rawX, labelCount) - } - - val series = mutableListOf() - val typeKeys = typesObject.keys().asSequence().toList() - typeKeys.forEach { key -> - if (typesObject.optString(key) == "x") return@forEach - val values = columnValuesByKey[key].orEmpty() - if (values.isEmpty()) return@forEach - val paddedValues = if (values.size < labelCount) { - values + List(labelCount - values.size) { values.last() } - } else { - values.take(labelCount) - } - val colorString = colorsObject.optString(key) - series += ParsedStatisticsSeries( - key = key, - name = namesObject.optString(key).ifBlank { key }, - color = colorString.toComposeColorOrNull() ?: Color(0xFF4285F4), - values = paddedValues - ) - } - - if (series.isEmpty()) null else ParsedStatisticsGraph(labels = labels, series = series) - }.getOrNull() -} - -private fun formatChartXAxisLabel(rawValue: Long, pointCount: Int): String { - return if (rawValue > 10_000_000_000L) { - val date = Date(rawValue) - if (pointCount <= 24) SimpleDateFormat("HH:mm", Locale.getDefault()).format(date) - else SimpleDateFormat("dd MMM", Locale.getDefault()).format(date) - } else if (rawValue > 1_000_000_000L) { - val date = Date(rawValue * 1000L) - if (pointCount <= 24) SimpleDateFormat("HH:mm", Locale.getDefault()).format(date) - else SimpleDateFormat("dd MMM", Locale.getDefault()).format(date) - } else { - rawValue.toString() - } -} - -private fun String.toComposeColorOrNull(): Color? { - if (!startsWith("#")) return null - return coRunCatching { Color(android.graphics.Color.parseColor(this)) }.getOrNull() -} - -private fun formatStatNumber(value: Int): String { - val absValue = abs(value) - return when { - absValue >= 1_000_000 -> String.format(Locale.getDefault(), "%.1fM", value / 1_000_000f) - absValue >= 1_000 -> String.format(Locale.getDefault(), "%.1fK", value / 1_000f) - else -> value.toString() - } -} - -private fun formatLongCompact(value: Long): String { - val absValue = abs(value) - return when { - absValue >= 1_000_000_000L -> String.format(Locale.getDefault(), "%.1fB", value / 1_000_000_000f) - absValue >= 1_000_000L -> String.format(Locale.getDefault(), "%.1fM", value / 1_000_000f) - absValue >= 1_000L -> String.format(Locale.getDefault(), "%.1fK", value / 1_000f) - else -> value.toString() - } -} - -@Composable -fun DateRangeHeader(period: DateRangeModel) { - val days = (period.endDate - period.startDate) / (24 * 60 * 60) - AssistChip( - onClick = { }, - label = { - Text( - text = "${formatDate(period.startDate)} — ${formatDate(period.endDate)}", - style = MaterialTheme.typography.titleSmall, - fontWeight = FontWeight.Bold - ) - }, - leadingIcon = { - Icon( - Icons.Rounded.CalendarMonth, - contentDescription = null, - modifier = Modifier.size(18.dp) - ) - }, - trailingIcon = { - Surface( - color = MaterialTheme.colorScheme.secondaryContainer, - shape = CircleShape - ) { - Text( - text = stringResource(R.string.days_count_format, days), - style = MaterialTheme.typography.labelSmall, - modifier = Modifier.padding(horizontal = 8.dp, vertical = 2.dp), - color = MaterialTheme.colorScheme.onSecondaryContainer, - fontWeight = FontWeight.Bold - ) - } - }, - colors = AssistChipDefaults.assistChipColors( - containerColor = MaterialTheme.colorScheme.surfaceContainer, - labelColor = MaterialTheme.colorScheme.onSurface - ), - border = AssistChipDefaults.assistChipBorder(borderColor = Color.Transparent, enabled = true), - shape = RoundedCornerShape(16.dp), - modifier = Modifier.padding(bottom = 8.dp) - ) -} - -@Composable -fun FallbackView(data: Any) { - Surface( - shape = RoundedCornerShape(24.dp), - color = MaterialTheme.colorScheme.errorContainer.copy(alpha = 0.5f), - contentColor = MaterialTheme.colorScheme.onErrorContainer, - border = BorderStroke(1.dp, MaterialTheme.colorScheme.error) - ) { - Column(modifier = Modifier.padding(24.dp)) { - Row(verticalAlignment = Alignment.CenterVertically) { - Icon( - Icons.Rounded.ErrorOutline, - contentDescription = null, - modifier = Modifier.size(32.dp), - tint = MaterialTheme.colorScheme.error - ) - Spacer(modifier = Modifier.width(12.dp)) - Text( - text = stringResource(R.string.statistics_unknown_type), - style = MaterialTheme.typography.titleLarge, - fontWeight = FontWeight.Black, - color = MaterialTheme.colorScheme.error - ) - } - Spacer(modifier = Modifier.height(12.dp)) - Text(text = stringResource(R.string.statistics_data_class_format, data::class.simpleName ?: "Unknown"), style = MaterialTheme.typography.bodyMedium) - Spacer(modifier = Modifier.height(16.dp)) - SelectionContainer { - Text( - text = data.toString(), - style = MaterialTheme.typography.bodySmall, - modifier = Modifier - .background(MaterialTheme.colorScheme.surface, RoundedCornerShape(16.dp)) - .padding(16.dp) - .fillMaxWidth() - ) - } - } - } -} - -private fun formatDate(timestamp: Int): String { - val sdf = SimpleDateFormat("dd MMM yyyy", Locale.getDefault()) - return sdf.format(Date(timestamp * 1000L)) -} - -private fun Modifier.alpha(alpha: Float) = this.then(Modifier.graphicsLayer(alpha = alpha)) diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/DefaultProfileLogsComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/logs/DefaultProfileLogsComponent.kt deleted file mode 100644 index b23f605a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/DefaultProfileLogsComponent.kt +++ /dev/null @@ -1,193 +0,0 @@ -package org.monogram.presentation.features.profile.logs - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.launch -import org.monogram.domain.models.ChatEventActionModel -import org.monogram.domain.models.ChatEventLogFiltersModel -import org.monogram.domain.models.MessageSenderModel -import org.monogram.domain.repository.MessageRepository -import org.monogram.domain.repository.UserRepository -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.root.AppComponentContext - -class DefaultProfileLogsComponent( - context: AppComponentContext, - private val chatId: Long, - private val onBackClicked: () -> Unit, - private val onUserClicked: (Long) -> Unit, - override val downloadUtils: IDownloadUtils -) : ProfileLogsComponent, AppComponentContext by context { - - override val messageRepository: MessageRepository = container.repositories.messageRepository - private val userRepository: UserRepository = container.repositories.userRepository - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - - private val scope = componentScope - private val _state = MutableValue(ProfileLogsComponent.State()) - override val state: Value = _state - - private val PAGE_SIZE = 50 - - init { - loadLogs(isFirstLoad = true) - } - - private fun loadLogs(isFirstLoad: Boolean) { - if (isFirstLoad) { - _state.update { it.copy(isLoading = true, logs = emptyList(), canLoadMore = true) } - } else { - if (_state.value.isLoadingMore || !_state.value.canLoadMore) return - _state.update { it.copy(isLoadingMore = true) } - } - - scope.launch { - try { - val fromEventId = if (isFirstLoad) 0L else _state.value.logs.lastOrNull()?.id ?: 0L - val newLogs = messageRepository.getChatEventLog( - chatId = chatId, - fromEventId = fromEventId, - limit = PAGE_SIZE, - filters = _state.value.filters, - userIds = _state.value.filters.userIds - ) - - val senderIds = mutableSetOf() - newLogs.forEach { event -> - when (val sender = event.memberId) { - is MessageSenderModel.User -> senderIds.add(sender.userId) - else -> {} - } - - when (val action = event.action) { - is ChatEventActionModel.MemberJoined -> senderIds.add(action.userId) - is ChatEventActionModel.MemberLeft -> senderIds.add(action.userId) - is ChatEventActionModel.MemberInvited -> senderIds.add(action.userId) - is ChatEventActionModel.MemberPromoted -> senderIds.add(action.userId) - is ChatEventActionModel.MemberRestricted -> senderIds.add(action.userId) - else -> {} - } - } - - val newSenderInfo = senderIds.mapNotNull { userId -> - userRepository.getUser(userId)?.let { user -> - userId to ProfileLogsComponent.SenderInfo( - name = "${user.firstName} ${user.lastName ?: ""}".trim(), - avatarPath = user.avatarPath - ) - } - }.toMap() - - _state.update { - it.copy( - logs = if (isFirstLoad) newLogs else it.logs + newLogs, - isLoading = false, - isLoadingMore = false, - canLoadMore = newLogs.size >= PAGE_SIZE, - senderInfo = it.senderInfo + newSenderInfo - ) - } - } catch (e: Exception) { - _state.update { it.copy(isLoading = false, isLoadingMore = false) } - } - } - } - - override fun onBack() { - onBackClicked() - } - - override fun onLoadMore() { - loadLogs(isFirstLoad = false) - } - - override fun onToggleFilter(filterType: ProfileLogsComponent.FilterType) { - val current = _state.value.pendingFilters - val next = when (filterType) { - ProfileLogsComponent.FilterType.MESSAGE_EDITS -> current.copy(messageEdits = !current.messageEdits) - ProfileLogsComponent.FilterType.MESSAGE_DELETIONS -> current.copy(messageDeletions = !current.messageDeletions) - ProfileLogsComponent.FilterType.MESSAGE_PINS -> current.copy(messagePins = !current.messagePins) - ProfileLogsComponent.FilterType.MEMBER_JOINS -> current.copy(memberJoins = !current.memberJoins) - ProfileLogsComponent.FilterType.MEMBER_LEAVES -> current.copy(memberLeaves = !current.memberLeaves) - ProfileLogsComponent.FilterType.MEMBER_INVITES -> current.copy(memberInvites = !current.memberInvites) - ProfileLogsComponent.FilterType.MEMBER_PROMOTIONS -> current.copy(memberPromotions = !current.memberPromotions) - ProfileLogsComponent.FilterType.MEMBER_RESTRICTIONS -> current.copy(memberRestrictions = !current.memberRestrictions) - ProfileLogsComponent.FilterType.INFO_CHANGES -> current.copy(infoChanges = !current.infoChanges) - ProfileLogsComponent.FilterType.SETTING_CHANGES -> current.copy(settingChanges = !current.settingChanges) - ProfileLogsComponent.FilterType.INVITE_LINK_CHANGES -> current.copy(inviteLinkChanges = !current.inviteLinkChanges) - ProfileLogsComponent.FilterType.VIDEO_CHAT_CHANGES -> current.copy(videoChatChanges = !current.videoChatChanges) - ProfileLogsComponent.FilterType.FORUM_CHANGES -> current.copy(forumChanges = !current.forumChanges) - ProfileLogsComponent.FilterType.SUBSCRIPTION_EXTENSIONS -> current.copy(subscriptionExtensions = !current.subscriptionExtensions) - } - _state.update { it.copy(pendingFilters = next) } - } - - override fun onToggleUserFilter(userId: Long) { - val current = _state.value.pendingFilters - val newUserIds = if (current.userIds.contains(userId)) { - current.userIds - userId - } else { - current.userIds + userId - } - _state.update { it.copy(pendingFilters = current.copy(userIds = newUserIds)) } - } - - override fun onApplyFilters() { - _state.update { it.copy(filters = it.pendingFilters, isFiltersVisible = false) } - loadLogs(isFirstLoad = true) - } - - override fun onResetFilters() { - _state.update { it.copy(pendingFilters = ChatEventLogFiltersModel()) } - } - - override fun onDismissFilters() { - _state.update { it.copy(isFiltersVisible = false) } - } - - override fun onRefresh() { - loadLogs(isFirstLoad = true) - } - - override fun onShowFilters() { - _state.update { it.copy(isFiltersVisible = true, pendingFilters = it.filters) } - } - - override fun onPhotoClick(path: String, caption: String) { - _state.update { - it.copy( - fullScreenPhotoPath = path, - fullScreenPhotoCaption = caption - ) - } - } - - override fun onVideoClick(path: String, caption: String, fileId: Int, supportsStreaming: Boolean) { - _state.update { - it.copy( - fullScreenVideoPath = path, - fullScreenVideoCaption = caption, - fullScreenVideoFileId = fileId, - fullScreenVideoSupportsStreaming = supportsStreaming - ) - } - } - - override fun onDismissViewer() { - _state.update { - it.copy( - fullScreenPhotoPath = null, - fullScreenPhotoCaption = null, - fullScreenVideoPath = null, - fullScreenVideoCaption = null - ) - } - } - - override fun onUserClick(userId: Long) { - onUserClicked(userId) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/ProfileLogsComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/logs/ProfileLogsComponent.kt deleted file mode 100644 index 03ffda77..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/ProfileLogsComponent.kt +++ /dev/null @@ -1,60 +0,0 @@ -package org.monogram.presentation.features.profile.logs - -import com.arkivanov.decompose.value.Value -import org.monogram.domain.models.ChatEventLogFiltersModel -import org.monogram.domain.models.ChatEventModel -import org.monogram.domain.repository.MessageRepository -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -interface ProfileLogsComponent { - val state: Value - val messageRepository: MessageRepository - val downloadUtils: IDownloadUtils - val videoPlayerPool: VideoPlayerPool - - fun onBack() - fun onLoadMore() - fun onToggleFilter(filterType: FilterType) - fun onToggleUserFilter(userId: Long) - fun onApplyFilters() - fun onResetFilters() - fun onDismissFilters() - fun onRefresh() - fun onShowFilters() - - fun onPhotoClick(path: String, caption: String) - fun onVideoClick(path: String, caption: String, fileId: Int, supportsStreaming: Boolean) - fun onDismissViewer() - fun onUserClick(userId: Long) - - data class State( - val logs: List = emptyList(), - val isLoading: Boolean = false, - val isLoadingMore: Boolean = false, - val canLoadMore: Boolean = true, - val filters: ChatEventLogFiltersModel = ChatEventLogFiltersModel(), - val pendingFilters: ChatEventLogFiltersModel = ChatEventLogFiltersModel(), - val isFiltersVisible: Boolean = false, - val senderInfo: Map = emptyMap(), - - val fullScreenPhotoPath: String? = null, - val fullScreenPhotoCaption: String? = null, - val fullScreenVideoPath: String? = null, - val fullScreenVideoCaption: String? = null, - val fullScreenVideoFileId: Int = 0, - val fullScreenVideoSupportsStreaming: Boolean = false - ) - - data class SenderInfo( - val name: String, - val avatarPath: String? - ) - - enum class FilterType { - MESSAGE_EDITS, MESSAGE_DELETIONS, MESSAGE_PINS, MEMBER_JOINS, MEMBER_LEAVES, - MEMBER_INVITES, MEMBER_PROMOTIONS, MEMBER_RESTRICTIONS, INFO_CHANGES, - SETTING_CHANGES, INVITE_LINK_CHANGES, VIDEO_CHAT_CHANGES, FORUM_CHANGES, - SUBSCRIPTION_EXTENSIONS - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/ProfileLogsContent.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/logs/ProfileLogsContent.kt deleted file mode 100644 index d9288233..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/ProfileLogsContent.kt +++ /dev/null @@ -1,405 +0,0 @@ -package org.monogram.presentation.features.profile.logs - -import android.widget.Toast -import androidx.compose.animation.* -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.input.nestedscroll.nestedScroll -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.domain.models.MessageSenderModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.features.chats.chatList.components.SectionHeader -import org.monogram.presentation.features.chats.chatList.components.SettingsTextField -import org.monogram.presentation.features.profile.logs.components.DateHeader -import org.monogram.presentation.features.profile.logs.components.FilterChipCompact -import org.monogram.presentation.features.profile.logs.components.LogBubble -import org.monogram.presentation.features.viewers.ImageViewer -import org.monogram.presentation.features.viewers.VideoViewer -import java.text.SimpleDateFormat -import java.util.* - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ProfileLogsContent(component: ProfileLogsComponent) { - val state by component.state.subscribeAsState() - val listState = rememberLazyListState() - val context = LocalContext.current - val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior() - - LaunchedEffect(state.logs.size) { - snapshotFlow { listState.layoutInfo.visibleItemsInfo } - .collect { visibleItems -> - val lastVisibleItem = visibleItems.lastOrNull() - if (lastVisibleItem != null && lastVisibleItem.index >= state.logs.size - 5 && - state.canLoadMore && !state.isLoadingMore && !state.isLoading - ) { - component.onLoadMore() - } - } - } - - Scaffold( - modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), - topBar = { - TopAppBar( - title = { - Column { - Text(stringResource(R.string.logs_title), style = MaterialTheme.typography.titleMedium) - if (state.logs.isNotEmpty()) { - Text( - text = stringResource(R.string.logs_events_count, state.logs.size), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - }, - navigationIcon = { - IconButton(onClick = component::onBack) { - Icon(Icons.AutoMirrored.Rounded.ArrowBack, contentDescription = stringResource(R.string.back)) - } - }, - actions = { - IconButton(onClick = component::onShowFilters) { - Icon(Icons.Rounded.FilterList, contentDescription = stringResource(R.string.filters)) - } - }, - scrollBehavior = scrollBehavior, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.surface, - scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer - ) - ) - } - ) { padding -> - Surface( - modifier = Modifier - .fillMaxSize() - .padding(padding), - color = MaterialTheme.colorScheme.background - ) { - Box(modifier = Modifier.fillMaxSize()) { - if (state.isLoading) { - CircularProgressIndicator(modifier = Modifier.align(Alignment.Center)) - } else if (state.logs.isEmpty()) { - Column( - modifier = Modifier.align(Alignment.Center), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Text( - text = stringResource(R.string.logs_empty_title), - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.height(8.dp)) - Text( - text = stringResource(R.string.logs_empty_subtitle), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f) - ) - } - } else { - LazyColumn( - state = listState, - modifier = Modifier.fillMaxSize(), - contentPadding = PaddingValues(bottom = 16.dp), - reverseLayout = true - ) { - itemsIndexed( - items = state.logs, - key = { _, event -> event.id } - ) { index, event -> - Column { - val showHeader = index == state.logs.lastIndex || - !isSameDay(event.date, state.logs[index + 1].date) - - if (showHeader) { - DateHeader(event.date) - } - - val senderId = when (val s = event.memberId) { - is MessageSenderModel.User -> s.userId - is MessageSenderModel.Chat -> s.chatId - } - val senderInfo = state.senderInfo[senderId] - - LogBubble( - event = event, - senderInfo = senderInfo, - allSenderInfo = state.senderInfo, - component = component, - modifier = Modifier.animateItem() - ) - } - } - - if (state.isLoadingMore) { - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator(modifier = Modifier.size(24.dp)) - } - } - } - } - } - } - } - - AnimatedVisibility( - visible = state.fullScreenPhotoPath != null, - enter = fadeIn() + scaleIn(initialScale = 0.9f), - exit = fadeOut() + scaleOut(targetScale = 0.9f) - ) { - state.fullScreenPhotoPath?.let { path -> - ImageViewer( - images = listOf(path), - startIndex = 0, - onDismiss = component::onDismissViewer, - autoDownload = true, - onPageChanged = {}, - onForward = { Toast.makeText(context, context.getString(R.string.logs_not_implemented), Toast.LENGTH_SHORT).show() }, - onDelete = { Toast.makeText(context, context.getString(R.string.logs_not_implemented), Toast.LENGTH_SHORT).show() }, - onCopyLink = { Toast.makeText(context, context.getString(R.string.logs_not_implemented), Toast.LENGTH_SHORT).show() }, - onCopyText = { Toast.makeText(context, context.getString(R.string.logs_not_implemented), Toast.LENGTH_SHORT).show() }, - captions = listOfNotNull(state.fullScreenPhotoCaption), - downloadUtils = component.downloadUtils - ) - } - } - - AnimatedVisibility( - visible = state.fullScreenVideoPath != null, - enter = fadeIn() + scaleIn(initialScale = 0.9f), - exit = fadeOut() + scaleOut(targetScale = 0.9f) - ) { - state.fullScreenVideoPath?.let { path -> - VideoViewer( - path = path, - onDismiss = component::onDismissViewer, - isGesturesEnabled = true, - isDoubleTapSeekEnabled = true, - seekDuration = 10, - isZoomEnabled = true, - onForward = { Toast.makeText(context, context.getString(R.string.logs_not_implemented), Toast.LENGTH_SHORT).show() }, - onDelete = { Toast.makeText(context, context.getString(R.string.logs_not_implemented), Toast.LENGTH_SHORT).show() }, - onCopyLink = { Toast.makeText(context, context.getString(R.string.logs_not_implemented), Toast.LENGTH_SHORT).show() }, - onCopyText = { Toast.makeText(context, context.getString(R.string.logs_not_implemented), Toast.LENGTH_SHORT).show() }, - caption = state.fullScreenVideoCaption, - fileId = state.fullScreenVideoFileId, - supportsStreaming = state.fullScreenVideoSupportsStreaming, - downloadUtils = component.downloadUtils - ) - } - } - } - - if (state.isFiltersVisible) { - ModalBottomSheet( - onDismissRequest = component::onDismissFilters, - containerColor = MaterialTheme.colorScheme.surfaceContainerLow, - dragHandle = { BottomSheetDefaults.DragHandle() }, - shape = RoundedCornerShape(topStart = 28.dp, topEnd = 28.dp) - ) { - var searchQuery by remember { mutableStateOf("") } - - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 32.dp) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 16.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = stringResource(R.string.logs_filter_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - Row { - TextButton(onClick = { - component.onResetFilters() - searchQuery = "" - }) { - Text(stringResource(R.string.logs_filter_reset)) - } - Button(onClick = component::onApplyFilters) { - Text(stringResource(R.string.logs_filter_apply)) - } - } - } - - val filterItems = remember { - listOf( - ProfileLogsComponent.FilterType.MESSAGE_EDITS to R.string.logs_action_edits, - ProfileLogsComponent.FilterType.MESSAGE_DELETIONS to R.string.logs_action_deletions, - ProfileLogsComponent.FilterType.MESSAGE_PINS to R.string.logs_action_pins, - ProfileLogsComponent.FilterType.MEMBER_JOINS to R.string.logs_action_joins, - ProfileLogsComponent.FilterType.MEMBER_LEAVES to R.string.logs_action_leaves, - ProfileLogsComponent.FilterType.MEMBER_INVITES to R.string.logs_action_invites, - ProfileLogsComponent.FilterType.MEMBER_PROMOTIONS to R.string.logs_action_promotions, - ProfileLogsComponent.FilterType.MEMBER_RESTRICTIONS to R.string.logs_action_restrictions, - ProfileLogsComponent.FilterType.INFO_CHANGES to R.string.logs_action_info, - ProfileLogsComponent.FilterType.SETTING_CHANGES to R.string.logs_action_settings, - ProfileLogsComponent.FilterType.INVITE_LINK_CHANGES to R.string.logs_action_links, - ProfileLogsComponent.FilterType.VIDEO_CHAT_CHANGES to R.string.logs_action_video - ) - } - - val filteredFilterItems = remember(searchQuery) { - filterItems - } - - val filteredSenderInfo = remember(searchQuery, state.senderInfo) { - state.senderInfo.filter { it.value.name.contains(searchQuery, ignoreCase = true) } - } - - if (filteredFilterItems.isNotEmpty()) { - SectionHeader(stringResource(R.string.logs_filter_section_types)) - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - LazyColumn( - modifier = Modifier - .heightIn(max = 200.dp) - .padding(vertical = 8.dp), - verticalArrangement = Arrangement.spacedBy(2.dp) - ) { - items(filteredFilterItems) { (type, labelRes) -> - val isChecked = when (type) { - ProfileLogsComponent.FilterType.MESSAGE_EDITS -> state.pendingFilters.messageEdits - ProfileLogsComponent.FilterType.MESSAGE_DELETIONS -> state.pendingFilters.messageDeletions - ProfileLogsComponent.FilterType.MESSAGE_PINS -> state.pendingFilters.messagePins - ProfileLogsComponent.FilterType.MEMBER_JOINS -> state.pendingFilters.memberJoins - ProfileLogsComponent.FilterType.MEMBER_LEAVES -> state.pendingFilters.memberLeaves - ProfileLogsComponent.FilterType.MEMBER_INVITES -> state.pendingFilters.memberInvites - ProfileLogsComponent.FilterType.MEMBER_PROMOTIONS -> state.pendingFilters.memberPromotions - ProfileLogsComponent.FilterType.MEMBER_RESTRICTIONS -> state.pendingFilters.memberRestrictions - ProfileLogsComponent.FilterType.INFO_CHANGES -> state.pendingFilters.infoChanges - ProfileLogsComponent.FilterType.SETTING_CHANGES -> state.pendingFilters.settingChanges - ProfileLogsComponent.FilterType.INVITE_LINK_CHANGES -> state.pendingFilters.inviteLinkChanges - ProfileLogsComponent.FilterType.VIDEO_CHAT_CHANGES -> state.pendingFilters.videoChatChanges - else -> false - } - FilterChipCompact( - label = stringResource(labelRes), - selected = isChecked, - onClick = { component.onToggleFilter(type) } - ) - } - } - } - } - - SectionHeader(stringResource(R.string.logs_filter_section_users)) - - SettingsTextField( - value = searchQuery, - onValueChange = { searchQuery = it }, - placeholder = stringResource(R.string.logs_filter_search_placeholder), - icon = if (searchQuery.isEmpty()) Icons.Rounded.Search else Icons.Rounded.Close, - position = ItemPosition.TOP, - singleLine = true, - trailingIcon = if (searchQuery.isNotEmpty()) { - { - IconButton(onClick = { searchQuery = "" }) { - Icon(Icons.Rounded.Close, contentDescription = stringResource(R.string.clear)) - } - } - } else null - ) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(bottomStart = 24.dp, bottomEnd = 24.dp, topStart = 4.dp, topEnd = 4.dp), - modifier = Modifier.fillMaxWidth() - ) { - LazyColumn( - modifier = Modifier - .heightIn(max = 200.dp) - .padding(vertical = 4.dp), - verticalArrangement = Arrangement.spacedBy(2.dp) - ) { - if (filteredSenderInfo.isEmpty()) { - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp), - contentAlignment = Alignment.Center - ) { - Text( - text = if (searchQuery.isEmpty()) stringResource(R.string.logs_filter_no_users) else stringResource(R.string.logs_filter_no_results, searchQuery), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } else { - items(filteredSenderInfo.toList()) { (userId, info) -> - val isSelected = state.pendingFilters.userIds.contains(userId) - Row( - modifier = Modifier - .fillMaxWidth() - .clickable { component.onToggleUserFilter(userId) } - .padding(horizontal = 12.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Avatar(path = info.avatarPath, videoPlayerPool = component.videoPlayerPool, name = info.name, size = 36.dp) - Spacer(Modifier.width(12.dp)) - Text( - text = info.name, - modifier = Modifier.weight(1f), - style = MaterialTheme.typography.bodyLarge, - fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Normal - ) - Icon( - imageVector = if (isSelected) Icons.Rounded.CheckCircle else Icons.Rounded.RadioButtonUnchecked, - contentDescription = null, - tint = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant.copy( - alpha = 0.5f - ) - ) - } - } - } - } - } - } - } - } -} - -private fun isSameDay(date1: Int, date2: Int): Boolean { - val fmt = SimpleDateFormat("yyyyMMdd", Locale.getDefault()) - return fmt.format(Date(date1.toLong() * 1000)) == fmt.format(Date(date2.toLong() * 1000)) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/ActionDetails.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/ActionDetails.kt deleted file mode 100644 index c4d73eea..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/ActionDetails.kt +++ /dev/null @@ -1,372 +0,0 @@ -package org.monogram.presentation.features.profile.logs.components - -import android.widget.Toast -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowForward -import androidx.compose.material.icons.automirrored.rounded.StickyNote2 -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalClipboardManager -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage -import org.monogram.domain.models.ChatEventActionModel -import org.monogram.domain.models.ChatPermissionsModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.features.profile.logs.ProfileLogsComponent -import java.io.File -import java.text.SimpleDateFormat -import java.util.* - -@Composable -fun ActionDetails( - action: ChatEventActionModel, - allSenderInfo: Map, - component: ProfileLogsComponent -) { - when (action) { - is ChatEventActionModel.MessageEdited -> { - Column(modifier = Modifier.padding(top = 8.dp)) { - Text( - text = stringResource(R.string.logs_original_message), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - MessagePreview(action.oldMessage, component = component) - Spacer(modifier = Modifier.height(4.dp)) - Text( - text = stringResource(R.string.logs_new_message), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - MessagePreview( - message = action.newMessage, - oldMessage = action.oldMessage, - component = component - ) - } - } - - is ChatEventActionModel.MessageDeleted -> { - Column(modifier = Modifier.padding(top = 8.dp)) { - Text( - text = stringResource(R.string.logs_deleted_message), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - MessagePreview(action.message, component = component) - } - } - - is ChatEventActionModel.MessagePinned -> { - Column(modifier = Modifier.padding(top = 8.dp)) { - Text( - text = stringResource(R.string.logs_pinned_message), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - MessagePreview(action.message, component = component) - } - } - - is ChatEventActionModel.MessageUnpinned -> { - Column(modifier = Modifier.padding(top = 8.dp)) { - Text( - text = stringResource(R.string.logs_unpinned_message), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - MessagePreview(action.message, component = component) - } - } - - is ChatEventActionModel.MemberPromoted -> { - Column(modifier = Modifier.padding(top = 8.dp)) { - TargetUserRow(action.userId, allSenderInfo, component) - Spacer(modifier = Modifier.height(8.dp)) - StatusTransition(action.oldStatus, action.newStatus) - } - } - - is ChatEventActionModel.MemberRestricted -> { - Column( - modifier = Modifier - .padding(top = 8.dp) - .fillMaxWidth() - ) { - TargetUserRow(action.userId, allSenderInfo, component) - - Spacer(modifier = Modifier.height(8.dp)) - - StatusTransition(action.oldStatus, action.newStatus) - - if (action.untilDate > 0) { - val date = Date(action.untilDate.toLong() * 1000) - val dateText = - SimpleDateFormat("MMM dd, yyyy HH:mm", Locale.getDefault()).format(date) - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.padding(top = 8.dp) - ) { - Icon( - imageVector = Icons.Rounded.Timer, - contentDescription = null, - modifier = Modifier.size(14.dp), - tint = MaterialTheme.colorScheme.error - ) - Spacer(modifier = Modifier.width(4.dp)) - Text( - text = stringResource(R.string.logs_restricted_until, ""), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.error - ) - Text( - text = dateText, - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.error, - fontWeight = FontWeight.Medium - ) - } - } else if (action.untilDate == 0 && action.newStatus.contains( - "Restricted", - ignoreCase = true - ) - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.padding(top = 8.dp) - ) { - Icon( - imageVector = Icons.Rounded.AllInclusive, - contentDescription = null, - modifier = Modifier.size(14.dp), - tint = MaterialTheme.colorScheme.error - ) - Spacer(modifier = Modifier.width(4.dp)) - Text( - text = stringResource(R.string.logs_restricted_permanently), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.error, - fontWeight = FontWeight.Medium - ) - } - } - - if (action.newPermissions != null) { - PermissionsDiff(action.oldPermissions, action.newPermissions!!) - } - } - } - - is ChatEventActionModel.PhotoChanged -> { - Row( - modifier = Modifier.padding(top = 8.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - if (action.oldPhotoPath != null) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Text(stringResource(R.string.logs_photo_old), style = MaterialTheme.typography.labelSmall) - AsyncImage( - model = File(action.oldPhotoPath.toString()), - contentDescription = null, - modifier = Modifier - .size(64.dp) - .clip(CircleShape) - .clickable { - component.onPhotoClick( - action.oldPhotoPath.toString(), - "Old chat photo" - ) - }, - contentScale = ContentScale.Crop - ) - } - } - if (action.newPhotoPath != null) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Text(stringResource(R.string.logs_photo_new), style = MaterialTheme.typography.labelSmall) - AsyncImage( - model = File(action.newPhotoPath.toString()), - contentDescription = null, - modifier = Modifier - .size(64.dp) - .clip(CircleShape) - .clickable { - component.onPhotoClick( - action.newPhotoPath.toString(), - "New chat photo" - ) - }, - contentScale = ContentScale.Crop - ) - } - } - } - } - - else -> {} - } -} - -@Composable -private fun TargetUserRow( - userId: Long, - allSenderInfo: Map, - component: ProfileLogsComponent -) { - val info = allSenderInfo[userId] - val name = info?.name ?: "User $userId" - val clipboardManager = LocalClipboardManager.current - val context = LocalContext.current - - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .clip(RoundedCornerShape(12.dp)) - .background(MaterialTheme.colorScheme.surfaceContainerHighest) - .combinedClickable( - onClick = { component.onUserClick(userId) }, - onLongClick = { - clipboardManager.setText(AnnotatedString(userId.toString())) - Toast.makeText(context, context.getString(R.string.logs_user_id_copied), Toast.LENGTH_SHORT).show() - } - ) - .padding(horizontal = 8.dp, vertical = 6.dp) - ) { - Avatar( - path = info?.avatarPath, - name = name, - size = 28.dp, - fontSize = 12, - videoPlayerPool = component.videoPlayerPool - ) - Spacer(modifier = Modifier.width(8.dp)) - Text( - text = name, - style = MaterialTheme.typography.bodyMedium, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - } -} - -@Composable -private fun StatusTransition(oldStatus: String, newStatus: String) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - StatusChangeRow(stringResource(R.string.logs_status_from), oldStatus) - Icon( - imageVector = Icons.AutoMirrored.Rounded.ArrowForward, - contentDescription = null, - modifier = Modifier.size(14.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - StatusChangeRow(stringResource(R.string.logs_status_to), newStatus) - } -} - -@OptIn(ExperimentalLayoutApi::class) -@Composable -private fun PermissionsDiff(old: ChatPermissionsModel?, new: ChatPermissionsModel) { - Column(modifier = Modifier.padding(top = 12.dp)) { - Text( - text = if (old != null) stringResource(R.string.logs_permissions_changes) else stringResource(R.string.logs_permissions_current), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(bottom = 8.dp), - fontWeight = FontWeight.Bold - ) - FlowRow( - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - PermissionChip( - stringResource(R.string.logs_perm_messages), - old?.canSendBasicMessages, - new.canSendBasicMessages, - Icons.Rounded.ChatBubble - ) - PermissionChip( - stringResource(R.string.logs_perm_media), - (old?.canSendPhotos ?: true) || (old?.canSendVideos ?: true), - new.canSendPhotos || new.canSendVideos, - Icons.Rounded.PermMedia - ) - PermissionChip( - stringResource(R.string.logs_perm_stickers), - old?.canSendOtherMessages, - new.canSendOtherMessages, - Icons.AutoMirrored.Rounded.StickyNote2 - ) - PermissionChip( - stringResource(R.string.logs_perm_links), - old?.canAddLinkPreviews, - new.canAddLinkPreviews, - Icons.Rounded.Link - ) - PermissionChip(stringResource(R.string.logs_perm_polls), old?.canSendPolls, new.canSendPolls, Icons.Rounded.Poll) - PermissionChip( - stringResource(R.string.logs_perm_invite), - old?.canInviteUsers, - new.canInviteUsers, - Icons.Rounded.PersonAdd - ) - PermissionChip(stringResource(R.string.logs_perm_pin), old?.canPinMessages, new.canPinMessages, Icons.Rounded.PushPin) - PermissionChip(stringResource(R.string.logs_perm_info), old?.canChangeInfo, new.canChangeInfo, Icons.Rounded.Info) - } - } -} - -@Composable -private fun PermissionChip(label: String, oldVal: Boolean?, newVal: Boolean, icon: ImageVector) { - val shouldShow = oldVal == null || oldVal != newVal - - if (shouldShow) { - val isRestricted = !newVal - val color = - if (isRestricted) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.primary - val containerColor = color.copy(alpha = 0.12f) - - Row( - modifier = Modifier - .clip(RoundedCornerShape(10.dp)) - .background(containerColor) - .padding(horizontal = 10.dp, vertical = 6.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(6.dp) - ) { - Icon( - imageVector = if (isRestricted) Icons.Rounded.Block else icon, - contentDescription = null, - modifier = Modifier.size(16.dp), - tint = color - ) - Text( - text = label, - style = MaterialTheme.typography.labelMedium, - color = color, - fontWeight = FontWeight.Bold - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/DateHeader.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/DateHeader.kt deleted file mode 100644 index 0c4b1543..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/DateHeader.kt +++ /dev/null @@ -1,65 +0,0 @@ -package org.monogram.presentation.features.profile.logs.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import java.text.SimpleDateFormat -import java.util.* - -@Composable -fun DateHeader(date: Int) { - val dateObj = Date(date.toLong() * 1000) - val calendar = Calendar.getInstance() - val currentYear = calendar.get(Calendar.YEAR) - calendar.time = dateObj - val eventYear = calendar.get(Calendar.YEAR) - - val pattern = if (currentYear == eventYear) "MMMM dd" else "MMMM dd, yyyy" - val text = SimpleDateFormat(pattern, Locale.getDefault()).format(dateObj) - - Box( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 12.dp), - contentAlignment = Alignment.Center - ) { - Surface( - color = MaterialTheme.colorScheme.surfaceContainerHigh.copy(alpha = 0.8f), - shape = RoundedCornerShape(16.dp), - modifier = Modifier.clip(RoundedCornerShape(16.dp)) - ) { - Text( - text = text, - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(horizontal = 14.dp, vertical = 6.dp) - ) - } - } -} - -@Composable -private fun Surface( - color: androidx.compose.ui.graphics.Color, - shape: androidx.compose.ui.graphics.Shape, - modifier: Modifier = Modifier, - content: @Composable () -> Unit -) { - Box( - modifier = modifier.background(color, shape), - contentAlignment = Alignment.Center - ) { - content() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/DiffCalc.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/DiffCalc.kt deleted file mode 100644 index 740576ed..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/DiffCalc.kt +++ /dev/null @@ -1,97 +0,0 @@ -package org.monogram.presentation.features.profile.logs.components - -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.withStyle -import kotlin.math.max - -private enum class DiffType { Same, Added, Removed } - -private data class DiffPart(val text: String, val type: DiffType) - -fun calculateDiff(old: String, new: String): AnnotatedString { - val oldWords = old.split(Regex("\\s+")).filter { it.isNotEmpty() } - val newWords = new.split(Regex("\\s+")).filter { it.isNotEmpty() } - - val diffList = computeDiff(oldWords, newWords) - - return buildAnnotatedString { - diffList.forEachIndexed { index, part -> - val type = part.type - - val style = when (type) { - DiffType.Added -> SpanStyle( - background = Color.Green.copy(alpha = 0.2f), - fontWeight = FontWeight.Bold - ) - - DiffType.Removed -> SpanStyle( - background = Color.Red.copy(alpha = 0.2f), - ) - - DiffType.Same -> null - } - - val nextPart = diffList.getOrNull(index + 1) - val shouldColorSpace = nextPart != null && - nextPart.type == type && - type != DiffType.Same - - val contentAction = { - append(part.text) - if (shouldColorSpace) { - append(" ") - } - } - - if (style != null) { - withStyle(style) { contentAction() } - } else { - contentAction() - } - - if (!shouldColorSpace && index < diffList.size - 1) { - append(" ") - } - } - } -} - -private fun computeDiff(oldList: List, newList: List): List { - val n = oldList.size - val m = newList.size - val dp = Array(n + 1) { IntArray(m + 1) } - - for (i in 1..n) { - for (j in 1..m) { - if (oldList[i - 1] == newList[j - 1]) { - dp[i][j] = dp[i - 1][j - 1] + 1 - } else { - dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) - } - } - } - - val result = mutableListOf() - var i = n - var j = m - - while (i > 0 || j > 0) { - if (i > 0 && j > 0 && oldList[i - 1] == newList[j - 1]) { - result.add(DiffPart(oldList[i - 1], DiffType.Same)) - i-- - j-- - } else if (j > 0 && (i == 0 || dp[i][j - 1] >= dp[i - 1][j])) { - result.add(DiffPart(newList[j - 1], DiffType.Added)) - j-- - } else { - result.add(DiffPart(oldList[i - 1], DiffType.Removed)) - i-- - } - } - - return result.reversed() -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/FilterChipCompact.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/FilterChipCompact.kt deleted file mode 100644 index d4650233..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/FilterChipCompact.kt +++ /dev/null @@ -1,44 +0,0 @@ -package org.monogram.presentation.features.profile.logs.components - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.CheckCircle -import androidx.compose.material.icons.rounded.RadioButtonUnchecked -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp - -@Composable -fun FilterChipCompact(label: String, selected: Boolean, onClick: () -> Unit) { - Row( - modifier = Modifier - .fillMaxWidth() - .clickable(onClick = onClick) - .padding(horizontal = 12.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Text( - text = label, - modifier = Modifier.weight(1f), - style = MaterialTheme.typography.bodyMedium, - fontWeight = if (selected) FontWeight.SemiBold else FontWeight.Normal, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Icon( - imageVector = if (selected) Icons.Rounded.CheckCircle else Icons.Rounded.RadioButtonUnchecked, - contentDescription = null, - modifier = Modifier.size(22.dp), - tint = if (selected) MaterialTheme.colorScheme.primary - else MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f) - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/LogBubble.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/LogBubble.kt deleted file mode 100644 index 20af5b23..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/LogBubble.kt +++ /dev/null @@ -1,185 +0,0 @@ -package org.monogram.presentation.features.profile.logs.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.selection.SelectionContainer -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Block -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalClipboardManager -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.ChatEventActionModel -import org.monogram.domain.models.ChatEventModel -import org.monogram.domain.models.MessageSenderModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.features.profile.logs.ProfileLogsComponent -import java.text.SimpleDateFormat -import java.util.* - -@OptIn(androidx.compose.foundation.ExperimentalFoundationApi::class) -@Composable -fun LogBubble( - event: ChatEventModel, - senderInfo: ProfileLogsComponent.SenderInfo?, - allSenderInfo: Map, - component: ProfileLogsComponent, - modifier: Modifier = Modifier -) { - val isRestriction = event.action is ChatEventActionModel.MemberRestricted - LocalClipboardManager.current - LocalContext.current - - val actionText = when (val action = event.action) { - is ChatEventActionModel.MessageEdited -> stringResource(R.string.logs_action_edited) - is ChatEventActionModel.MessageDeleted -> stringResource(R.string.logs_action_deleted) - is ChatEventActionModel.MessagePinned -> stringResource(R.string.logs_action_pinned) - is ChatEventActionModel.MessageUnpinned -> stringResource(R.string.logs_action_unpinned) - is ChatEventActionModel.MemberJoined -> stringResource(R.string.logs_action_joined) - is ChatEventActionModel.MemberLeft -> stringResource(R.string.logs_action_left) - is ChatEventActionModel.MemberInvited -> { - val targetName = allSenderInfo[action.userId]?.name ?: "User ${action.userId}" - stringResource(R.string.logs_action_invited, targetName) - } - - is ChatEventActionModel.MemberPromoted -> { - val targetName = allSenderInfo[action.userId]?.name ?: "User ${action.userId}" - stringResource(R.string.logs_action_permissions_changed, targetName) - } - - is ChatEventActionModel.MemberRestricted -> { - val targetName = allSenderInfo[action.userId]?.name ?: "User ${action.userId}" - stringResource(R.string.logs_action_restrictions_changed, targetName) - } - - is ChatEventActionModel.TitleChanged -> stringResource(R.string.logs_action_title_changed, action.newTitle) - is ChatEventActionModel.DescriptionChanged -> stringResource(R.string.logs_action_description_changed) - is ChatEventActionModel.UsernameChanged -> stringResource(R.string.logs_action_username_changed, action.newUsername) - is ChatEventActionModel.PhotoChanged -> stringResource(R.string.logs_action_photo_changed) - is ChatEventActionModel.InviteLinkEdited -> stringResource(R.string.logs_action_link_edited) - is ChatEventActionModel.InviteLinkRevoked -> stringResource(R.string.logs_action_link_revoked) - is ChatEventActionModel.InviteLinkDeleted -> stringResource(R.string.logs_action_link_deleted) - is ChatEventActionModel.VideoChatCreated -> stringResource(R.string.logs_action_video_started) - is ChatEventActionModel.VideoChatEnded -> stringResource(R.string.logs_action_video_ended) - is ChatEventActionModel.Unknown -> stringResource(R.string.logs_action_unknown, action.type) - } - - val senderName = senderInfo?.name ?: when (val sender = event.memberId) { - is MessageSenderModel.User -> "User ${sender.userId}" - is MessageSenderModel.Chat -> "Chat ${sender.chatId}" - } - - when (val s = event.memberId) { - is MessageSenderModel.User -> s.userId - is MessageSenderModel.Chat -> s.chatId - } - - var showFullDate by remember { mutableStateOf(false) } - val date = Date(event.date.toLong() * 1000) - val dateText = if (showFullDate) { - SimpleDateFormat("MMM dd, HH:mm:ss", Locale.getDefault()).format(date) - } else { - SimpleDateFormat("HH:mm", Locale.getDefault()).format(date) - } - - Row( - modifier = modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 4.dp), - verticalAlignment = Alignment.Bottom - ) { - Avatar( - path = senderInfo?.avatarPath, - name = senderName, - size = 40.dp, - fontSize = 16, - videoPlayerPool = component.videoPlayerPool, - onClick = { - if (event.memberId is MessageSenderModel.User) { - component.onUserClick((event.memberId as MessageSenderModel.User).userId) - } - } - ) - - Spacer(modifier = Modifier.width(8.dp)) - - val bubbleShape = RoundedCornerShape(16.dp, 16.dp, 16.dp, 4.dp) - Column( - modifier = Modifier - .weight(1f) - .background( - color = if (isRestriction) MaterialTheme.colorScheme.errorContainer.copy(alpha = 0.15f) - else MaterialTheme.colorScheme.surfaceContainerHigh, - shape = bubbleShape - ) - .then( - if (isRestriction) Modifier.border( - width = 1.dp, - color = MaterialTheme.colorScheme.error.copy(alpha = 0.2f), - shape = bubbleShape - ) else Modifier - ) - .padding(12.dp) - ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = senderName, - style = MaterialTheme.typography.titleSmall, - color = if (isRestriction) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold, - modifier = Modifier.clickable { - if (event.memberId is MessageSenderModel.User) { - component.onUserClick((event.memberId as MessageSenderModel.User).userId) - } - } - ) - if (isRestriction) { - Icon( - imageVector = Icons.Rounded.Block, - contentDescription = null, - modifier = Modifier.size(16.dp), - tint = MaterialTheme.colorScheme.error - ) - } - } - Spacer(modifier = Modifier.height(4.dp)) - - SelectionContainer { - Column { - Text( - text = actionText, - style = MaterialTheme.typography.bodyMedium, - fontWeight = if (isRestriction) FontWeight.Medium else FontWeight.Normal - ) - - ActionDetails(event.action, allSenderInfo, component) - } - } - - Spacer(modifier = Modifier.height(4.dp)) - Text( - text = dateText, - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier - .align(Alignment.End) - .clickable { showFullDate = !showFullDate } - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/MessagePreview.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/MessagePreview.kt deleted file mode 100644 index 944791b8..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/MessagePreview.kt +++ /dev/null @@ -1,282 +0,0 @@ -package org.monogram.presentation.features.profile.logs.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.font.FontStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.withStyle -import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageEntity -import org.monogram.domain.models.MessageModel -import org.monogram.presentation.R -import org.monogram.presentation.features.chats.currentChat.components.chats.MessageText -import org.monogram.presentation.features.chats.currentChat.components.chats.buildAnnotatedMessageTextWithEmoji -import org.monogram.presentation.features.chats.currentChat.components.chats.rememberMessageInlineContent -import org.monogram.presentation.features.profile.logs.ProfileLogsComponent -import java.io.File - -@Composable -fun MessagePreview( - message: MessageModel, - oldMessage: MessageModel? = null, - component: ProfileLogsComponent -) { - Surface( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 4.dp), - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(12.dp) - ) { - Row( - modifier = Modifier.padding(12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - val content = message.content - - val mediaPath = when (content) { - is MessageContent.Photo -> content.path - is MessageContent.Gif -> content.path - is MessageContent.Video -> content.path - is MessageContent.Sticker -> content.path - else -> null - } - - if (mediaPath != null) { - val file = File(mediaPath) - if (file.exists()) { - AsyncImage( - model = file, - contentDescription = null, - modifier = Modifier - .size(if (content is MessageContent.Gif) 80.dp else 48.dp) - .clip(RoundedCornerShape(8.dp)) - .background(MaterialTheme.colorScheme.surfaceVariant) - .clickable { - when (content) { - is MessageContent.Photo -> component.onPhotoClick(mediaPath, content.caption) - is MessageContent.Gif -> component.onVideoClick( - mediaPath, - content.caption, - content.fileId, - true - ) - - is MessageContent.Video -> component.onVideoClick( - mediaPath, - content.caption, - content.fileId, - content.supportsStreaming - ) - - else -> {} - } - }, - contentScale = ContentScale.Crop - ) - Spacer(modifier = Modifier.width(12.dp)) - } - } - - Column(modifier = Modifier.weight(1f)) { - val oldContent = oldMessage?.content - when (content) { - is MessageContent.Text -> { - if (oldContent is MessageContent.Text) { - MessageText( - text = calculateDiff(oldContent.text, content.text), - inlineContent = emptyMap(), - style = MaterialTheme.typography.bodyMedium, - entities = emptyList() - ) - } else { - val annotatedText = buildAnnotatedMessageTextWithEmoji( - text = content.text, - entities = content.entities - ) - val inlineContent = rememberMessageInlineContent( - entities = content.entities, - fontSize = 14f - ) - MessageText( - text = annotatedText, - inlineContent = inlineContent, - style = MaterialTheme.typography.bodyMedium, - entities = content.entities - ) - } - } - - is MessageContent.Photo -> { - val oldCaption = (oldContent as? MessageContent.Photo)?.caption - MediaPreviewText(stringResource(R.string.logs_media_photo), content.caption, content.entities, oldCaption) - } - - is MessageContent.Video -> { - val oldCaption = (oldContent as? MessageContent.Video)?.caption - MediaPreviewText(stringResource(R.string.logs_media_video), content.caption, content.entities, oldCaption) - } - - is MessageContent.Document -> { - val oldDoc = oldContent as? MessageContent.Document - val oldText = oldDoc?.caption?.ifEmpty { oldDoc.fileName } - val newText = content.caption.ifEmpty { content.fileName } - MediaPreviewText(stringResource(R.string.logs_media_document), newText, content.entities, oldText) - } - - is MessageContent.Audio -> { - val oldAudio = oldContent as? MessageContent.Audio - val oldText = oldAudio?.caption?.ifEmpty { oldAudio.title.ifEmpty { oldAudio.fileName } } - val newText = content.caption.ifEmpty { content.title.ifEmpty { content.fileName } } - MediaPreviewText(stringResource(R.string.logs_media_audio), newText, content.entities, oldText) - } - - is MessageContent.Sticker -> { - Text( - text = buildAnnotatedString { - withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { - append(stringResource(R.string.logs_media_sticker)) - } - append(" ${content.emoji}") - }, - style = MaterialTheme.typography.bodyMedium - ) - } - - is MessageContent.Voice -> { - Text( - text = buildAnnotatedString { - withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { - append(stringResource(R.string.logs_media_voice)) - } - }, - style = MaterialTheme.typography.bodyMedium - ) - } - - is MessageContent.VideoNote -> { - Text( - text = buildAnnotatedString { - withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { - append(stringResource(R.string.logs_media_video_note)) - } - }, - style = MaterialTheme.typography.bodyMedium - ) - } - - is MessageContent.Gif -> { - val oldCaption = (oldContent as? MessageContent.Gif)?.caption - MediaPreviewText(stringResource(R.string.logs_media_gif), content.caption, content.entities, oldCaption) - } - - is MessageContent.Contact -> { - Text( - text = buildAnnotatedString { - withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { - append(stringResource(R.string.logs_media_contact)) - } - append(": ${content.firstName} ${content.lastName}".trim()) - }, - style = MaterialTheme.typography.bodyMedium - ) - } - - is MessageContent.Poll -> { - Text( - text = buildAnnotatedString { - withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { - append(stringResource(R.string.logs_media_poll)) - } - append(": ${content.question}") - }, - style = MaterialTheme.typography.bodyMedium - ) - } - - is MessageContent.Location -> { - Text( - text = buildAnnotatedString { - withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { - append(stringResource(R.string.logs_media_location)) - } - }, - style = MaterialTheme.typography.bodyMedium - ) - } - - is MessageContent.Venue -> { - Text( - text = buildAnnotatedString { - withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { - append(stringResource(R.string.logs_media_venue)) - } - append(": ${content.title}") - }, - style = MaterialTheme.typography.bodyMedium - ) - } - - is MessageContent.Service -> { - Text( - text = content.text, - style = MaterialTheme.typography.bodyMedium.copy(fontStyle = FontStyle.Italic), - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - - MessageContent.Unsupported -> { - Text( - stringResource(R.string.logs_media_unsupported), - style = MaterialTheme.typography.bodyMedium - ) - } - } - } - } - } -} - -@Composable -private fun MediaPreviewText( - label: String, - text: String, - entities: List, - oldText: String? = null -) { - val annotatedText = buildAnnotatedString { - withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { - append(label) - } - if (text.isNotEmpty() || !oldText.isNullOrEmpty()) { - append(": ") - if (oldText != null && oldText != text) { - append(calculateDiff(oldText, text)) - } else { - append(buildAnnotatedMessageTextWithEmoji(text, entities)) - } - } - } - - MessageText( - text = annotatedText, - inlineContent = emptyMap(), - style = MaterialTheme.typography.bodyMedium, - entities = if (oldText != null && oldText != text) emptyList() else entities - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/StatusChangeRow.kt b/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/StatusChangeRow.kt deleted file mode 100644 index a92a9a1b..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/profile/logs/components/StatusChangeRow.kt +++ /dev/null @@ -1,56 +0,0 @@ -package org.monogram.presentation.features.profile.logs.components - -import androidx.compose.foundation.layout.Row -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import org.monogram.presentation.R - -@Composable -fun StatusChangeRow(label: String, status: String) { - val restrictedStr = stringResource(R.string.logs_role_restricted) - val memberStr = stringResource(R.string.logs_role_member) - val adminStr = stringResource(R.string.logs_role_admin) - val ownerStr = stringResource(R.string.logs_role_owner) - val bannedStr = stringResource(R.string.logs_role_banned) - val unknownStr = "Unknown" - - val formattedStatus = remember(status) { - val name = status.substringBefore("{").trim() - if (name.isEmpty() || name.length > 30) { - when { - status.contains("Restricted", ignoreCase = true) -> restrictedStr - status.contains("Member", ignoreCase = true) -> memberStr - status.contains("Administrator", ignoreCase = true) -> adminStr - status.contains("Creator", ignoreCase = true) -> ownerStr - status.contains("Banned", ignoreCase = true) -> bannedStr - status.contains("Left", ignoreCase = true) -> "Left" - else -> unknownStr - } - } else { - name.replace("ChatMemberStatus", "") - } - } - - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = "$label: ", - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Text( - text = formattedStatus, - style = MaterialTheme.typography.bodySmall, - fontWeight = FontWeight.Bold, - color = when (formattedStatus) { - restrictedStr, bannedStr -> MaterialTheme.colorScheme.error - adminStr, ownerStr, "Administrator", "Creator" -> MaterialTheme.colorScheme.primary - else -> MaterialTheme.colorScheme.onSurface - } - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/core/BitmapPool.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/core/BitmapPool.kt deleted file mode 100644 index 37269a43..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/core/BitmapPool.kt +++ /dev/null @@ -1,45 +0,0 @@ -package org.monogram.presentation.features.stickers.core - -import android.graphics.Bitmap -import androidx.core.graphics.createBitmap -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import java.util.* - -object BitmapPool { - private val pool = LinkedList() - private val mutex = Mutex() - private const val MAX_POOL_SIZE = 50 - - suspend fun obtain(width: Int, height: Int): Bitmap { - mutex.withLock { - val iterator = pool.iterator() - while (iterator.hasNext()) { - val bitmap = iterator.next() - if (bitmap.width == width && bitmap.height == height) { - iterator.remove() - return bitmap - } - } - } - return createBitmap(width, height) - } - - suspend fun recycle(bitmap: Bitmap) { - if (bitmap.isRecycled) return - mutex.withLock { - if (pool.size < MAX_POOL_SIZE) { - pool.add(bitmap) - } else { - bitmap.recycle() - } - } - } - - suspend fun clear() { - mutex.withLock { - pool.forEach { it.recycle() } - pool.clear() - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/core/LottieStickerController.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/core/LottieStickerController.kt deleted file mode 100644 index bce6e367..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/core/LottieStickerController.kt +++ /dev/null @@ -1,259 +0,0 @@ -package org.monogram.presentation.features.stickers.core - -import org.monogram.presentation.core.util.coRunCatching -import android.graphics.Bitmap -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableLongStateOf -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue -import androidx.compose.ui.graphics.ImageBitmap -import androidx.compose.ui.graphics.asImageBitmap -import kotlinx.coroutines.* -import java.io.File -import kotlin.math.max - -class LottieStickerController( - private val filePath: String, - private val scope: CoroutineScope, - private val reqWidth: Int = 512, - private val reqHeight: Int = 512 -) : StickerController { - - override var currentImageBitmap by mutableStateOf(null) - private set - - override var frameVersion by mutableLongStateOf(0L) - private set - - private var renderJob: Job? = null - private var isPaused = false - private var isActiveController = true - private var frontBitmap: Bitmap? = null - private var backBitmap: Bitmap? = null - private var spareBitmap: Bitmap? = null - private var decoder: RLottieWrapper? = null - - override fun start() { - val previousJob = renderJob - renderJob = scope.launch(renderDispatcher) { - previousJob?.cancelAndJoin() - loadAndRender() - } - } - - override fun setPaused(paused: Boolean) { - isPaused = paused - } - - override fun release() { - isActiveController = false - renderJob?.cancel() - currentImageBitmap = null - scope.launch(renderDispatcher) { - renderJob?.join() - - decoder?.release() - decoder = null - - frontBitmap?.let { BitmapPool.recycle(it) } - backBitmap?.let { BitmapPool.recycle(it) } - spareBitmap?.let { BitmapPool.recycle(it) } - frontBitmap = null - backBitmap = null - spareBitmap = null - } - } - - override suspend fun renderFirstFrame(): ImageBitmap? = withContext(renderDispatcher) { - val file = File(filePath) - if (!file.exists()) return@withContext null - - val localDecoder = RLottieWrapper() - try { - if (!localDecoder.open(file)) { - return@withContext null - } - - val compositionWidth = localDecoder.getWidth().coerceAtLeast(1) - val compositionHeight = localDecoder.getHeight().coerceAtLeast(1) - val extraPaddingX = minOf((compositionWidth * OVERFLOW_PADDING_RATIO).toInt(), MAX_OVERFLOW_PADDING_PX) - val extraPaddingY = minOf((compositionHeight * OVERFLOW_PADDING_RATIO).toInt(), MAX_OVERFLOW_PADDING_PX) - val renderWidth = maxOf(reqWidth, compositionWidth + extraPaddingX * 2) - val renderHeight = maxOf(reqHeight, compositionHeight + extraPaddingY * 2) - val boundsLeft = (renderWidth - compositionWidth) / 2 - val boundsTop = (renderHeight - compositionHeight) / 2 - - val bitmap = BitmapPool.obtain(renderWidth, renderHeight) - - bitmap.eraseColor(0) - val rendered = localDecoder.renderFrame( - bitmap = bitmap, - frameNo = 0, - drawLeft = boundsLeft, - drawTop = boundsTop, - drawWidth = compositionWidth, - drawHeight = compositionHeight - ) - if (!rendered) { - BitmapPool.recycle(bitmap) - return@withContext null - } - - val imageBitmap = bitmap.asImageBitmap() - imageBitmap - } catch (e: Exception) { - e.printStackTrace() - null - } finally { - localDecoder.release() - } - } - - private suspend fun loadAndRender() { - while (isPaused && scope.isActive) { - delay(50) - } - - val file = File(filePath) - if (!file.exists()) return - - val localDecoder = RLottieWrapper() - if (!coRunCatching { localDecoder.open(file) }.getOrDefault(false)) { - localDecoder.release() - return - } - decoder = localDecoder - - val compositionWidth = localDecoder.getWidth().coerceAtLeast(1) - val compositionHeight = localDecoder.getHeight().coerceAtLeast(1) - val extraPaddingX = minOf((compositionWidth * OVERFLOW_PADDING_RATIO).toInt(), MAX_OVERFLOW_PADDING_PX) - val extraPaddingY = minOf((compositionHeight * OVERFLOW_PADDING_RATIO).toInt(), MAX_OVERFLOW_PADDING_PX) - val renderWidth = maxOf(reqWidth, compositionWidth + extraPaddingX * 2) - val renderHeight = maxOf(reqHeight, compositionHeight + extraPaddingY * 2) - val boundsLeft = (renderWidth - compositionWidth) / 2 - val boundsTop = (renderHeight - compositionHeight) / 2 - - val fBitmap = BitmapPool.obtain(renderWidth, renderHeight) - val bBitmap = BitmapPool.obtain(renderWidth, renderHeight) - val sBitmap = BitmapPool.obtain(renderWidth, renderHeight) - - if (!isActiveController) { - BitmapPool.recycle(fBitmap) - BitmapPool.recycle(bBitmap) - BitmapPool.recycle(sBitmap) - decoder?.release() - decoder = null - return - } - - frontBitmap = fBitmap - backBitmap = bBitmap - spareBitmap = sBitmap - - fBitmap.eraseColor(0) - val firstFrameRendered = localDecoder.renderFrame( - bitmap = fBitmap, - frameNo = 0, - drawLeft = boundsLeft, - drawTop = boundsTop, - drawWidth = compositionWidth, - drawHeight = compositionHeight - ) - if (!firstFrameRendered) { - BitmapPool.recycle(fBitmap) - BitmapPool.recycle(bBitmap) - BitmapPool.recycle(sBitmap) - frontBitmap = null - backBitmap = null - spareBitmap = null - decoder?.release() - decoder = null - return - } - - currentImageBitmap = fBitmap.asImageBitmap() - - val totalFrames = localDecoder.getTotalFrames().coerceAtLeast(1) - val frameRate = localDecoder.getFrameRate().takeIf { it > 0.0 } - ?: run { - val durationMs = localDecoder.getDurationMs().coerceAtLeast(1L) - max(totalFrames / (durationMs / 1000.0), 1.0) - } - val normalizedFrameRate = frameRate.coerceIn(1.0, 120.0) - - var lastFrameTime = System.nanoTime() - val frameDurationMs = max(1L, (1000.0 / normalizedFrameRate).toLong()) - var frameAccumulator = 0.0 - var frameNo = 0 - - while (isActiveController && scope.isActive) { - val now = System.nanoTime() - if (isPaused) { - delay(100) - lastFrameTime = System.nanoTime() - continue - } - - val dtMs = (now - lastFrameTime) / 1_000_000.0 - frameAccumulator += dtMs * normalizedFrameRate / 1000.0 - val framesToAdvance = frameAccumulator.toInt() - if (framesToAdvance <= 0) { - lastFrameTime = now - delay(1) - continue - } - frameNo = (frameNo + framesToAdvance) % totalFrames - frameAccumulator -= framesToAdvance - - val localBackBitmap = backBitmap ?: break - - localBackBitmap.eraseColor(0) - val rendered = localDecoder.renderFrame( - bitmap = localBackBitmap, - frameNo = frameNo, - drawLeft = boundsLeft, - drawTop = boundsTop, - drawWidth = compositionWidth, - drawHeight = compositionHeight - ) - if (!rendered) { - break - } - - val previousFront = frontBitmap - frontBitmap = backBitmap - backBitmap = spareBitmap - spareBitmap = previousFront - - val localFrontBitmap = frontBitmap - if (localFrontBitmap != null) { - currentImageBitmap = localFrontBitmap.asImageBitmap() - frameVersion++ - } - - lastFrameTime = now - - val workTime = (System.nanoTime() - now) / 1_000_000 - val delayTime = (frameDurationMs - workTime).coerceAtLeast(0) - delay(delayTime) - } - - decoder?.release() - decoder = null - - currentImageBitmap = null - - frontBitmap?.let { BitmapPool.recycle(it) } - backBitmap?.let { BitmapPool.recycle(it) } - spareBitmap?.let { BitmapPool.recycle(it) } - frontBitmap = null - backBitmap = null - spareBitmap = null - } - - companion object { - private val renderDispatcher = Dispatchers.Default.limitedParallelism(8) - private const val OVERFLOW_PADDING_RATIO = 0.20f - private const val MAX_OVERFLOW_PADDING_PX = 96 - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/core/RLottieWrapper.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/core/RLottieWrapper.kt deleted file mode 100644 index 8da4932a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/core/RLottieWrapper.kt +++ /dev/null @@ -1,87 +0,0 @@ -package org.monogram.presentation.features.stickers.core - -import org.monogram.presentation.core.util.coRunCatching -import android.graphics.Bitmap -import java.io.File -import java.io.FileInputStream -import java.util.zip.GZIPInputStream - -class RLottieWrapper { - private var nativePtr: Long = 0 - - init { - System.loadLibrary("native-lib") - nativePtr = create() - } - - fun open(file: File): Boolean { - if (!file.exists()) return false - if (nativePtr == 0L) return false - - return coRunCatching { - val json = if (file.isGzipped()) { - GZIPInputStream(FileInputStream(file)).bufferedReader(Charsets.UTF_8).use { it.readText() } - } else { - file.readText(Charsets.UTF_8) - } - - val cacheKey = "${file.absolutePath}:${file.length()}:${file.lastModified()}" - val resourcePath = file.parent ?: "" - openFromData(nativePtr, json, cacheKey, resourcePath) - }.getOrDefault(false) - } - - fun renderFrame( - bitmap: Bitmap, - frameNo: Int, - drawLeft: Int, - drawTop: Int, - drawWidth: Int, - drawHeight: Int - ): Boolean { - if (nativePtr == 0L) return false - return renderFrame(nativePtr, bitmap, frameNo, drawLeft, drawTop, drawWidth, drawHeight) - } - - fun getWidth(): Int = if (nativePtr == 0L) 0 else getWidth(nativePtr) - fun getHeight(): Int = if (nativePtr == 0L) 0 else getHeight(nativePtr) - fun getTotalFrames(): Int = if (nativePtr == 0L) 0 else getTotalFrames(nativePtr) - fun getFrameRate(): Double = if (nativePtr == 0L) 0.0 else getFrameRate(nativePtr) - fun getDurationMs(): Long = if (nativePtr == 0L) 0L else getDurationMs(nativePtr) - - fun release() { - if (nativePtr == 0L) return - destroy(nativePtr) - nativePtr = 0L - } - - private fun File.isGzipped(): Boolean { - if (!exists() || length() < 2L) return false - return coRunCatching { - FileInputStream(this).use { fis -> - val low = fis.read() - val high = fis.read() - low == 0x1f && high == 0x8b - } - }.getOrDefault(false) - } - - private external fun create(): Long - private external fun openFromData(ptr: Long, json: String, cacheKey: String, resourcePath: String): Boolean - private external fun renderFrame( - ptr: Long, - bitmap: Bitmap, - frameNo: Int, - drawLeft: Int, - drawTop: Int, - drawWidth: Int, - drawHeight: Int - ): Boolean - - private external fun getWidth(ptr: Long): Int - private external fun getHeight(ptr: Long): Int - private external fun getTotalFrames(ptr: Long): Int - private external fun getFrameRate(ptr: Long): Double - private external fun getDurationMs(ptr: Long): Long - private external fun destroy(ptr: Long) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/core/StickerController.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/core/StickerController.kt deleted file mode 100644 index 9656db11..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/core/StickerController.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.monogram.presentation.features.stickers.core - -import androidx.compose.ui.graphics.ImageBitmap - -interface StickerController { - val currentImageBitmap: ImageBitmap? - val frameVersion: Long - - fun start() - fun setPaused(paused: Boolean) - fun release() - - suspend fun renderFirstFrame(): ImageBitmap? = null -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/core/StickerDTO.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/core/StickerDTO.kt deleted file mode 100644 index 64eb9d7c..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/core/StickerDTO.kt +++ /dev/null @@ -1,155 +0,0 @@ -package org.monogram.presentation.features.stickers.core - -import kotlinx.serialization.Serializable -import org.monogram.domain.models.* - -@Serializable -data class StickerSetUiModel( - val id: Long, - val title: String, - val name: String, - val stickers: List, - val thumbnail: StickerUiModel? = null, - val isInstalled: Boolean = false, - val isArchived: Boolean = false, - val isOfficial: Boolean = false, - val stickerType: StickerTypeUi = StickerTypeUi.REGULAR -) - -@Serializable -enum class StickerTypeUi { - REGULAR, - MASK, - CUSTOM_EMOJI -} - -@Serializable -data class StickerSetInfoUiModel( - val id: Long, - val title: String, - val name: String, - val cover: StickerUiModel? = null -) - -@Serializable -enum class StickerFormatUi { - STATIC, - ANIMATED, - VIDEO, - UNKNOWN -} - -@Serializable -data class StickerUiModel( - val id: Long, - val width: Int, - val height: Int, - val emoji: String, - val path: String?, - val format: StickerFormatUi -) - -@Serializable -data class GifUiModel( - val id: String, - val fileId: Long, - val thumbFileId: Long?, - val width: Int, - val height: Int -) - -@Serializable -data class RecentEmojiUiModel( - val emoji: String, - val sticker: StickerUiModel? = null -) - -fun StickerSetModel.toUi() = StickerSetUiModel( - id = id, - title = title, - name = name, - stickers = stickers.map { it.toUi() }, - thumbnail = thumbnail?.toUi(), - isInstalled = isInstalled, - isArchived = isArchived, - isOfficial = isOfficial, - stickerType = stickerType.toUi() -) - -fun StickerSetInfoModel.toUi() = StickerSetInfoUiModel( - id = id, - title = title, - name = name, - cover = cover?.toUi() -) - -fun StickerModel.toUi() = StickerUiModel( - id = id, - width = width, - height = height, - emoji = emoji, - path = path, - format = format.toUi() -) - -fun GifModel.toUi() = GifUiModel( - id = id, - fileId = fileId, - thumbFileId = thumbFileId, - width = width, - height = height -) - -fun RecentEmojiModel.toUi() = RecentEmojiUiModel( - emoji = emoji, - sticker = sticker?.toUi() -) - -fun StickerType.toUi() = StickerTypeUi.valueOf(name) - -fun StickerFormat.toUi() = StickerFormatUi.valueOf(name) - -fun StickerSetUiModel.toDomain() = StickerSetModel( - id = id, - title = title, - name = name, - stickers = stickers.map { it.toDomain() }, - thumbnail = thumbnail?.toDomain(), - isInstalled = isInstalled, - isArchived = isArchived, - isOfficial = isOfficial, - stickerType = stickerType.toDomain() -) - -fun StickerSetInfoUiModel.toDomain() = StickerSetInfoModel( - id = id, - title = title, - name = name, - cover = cover?.toDomain() -) - -fun StickerUiModel.toDomain() = StickerModel( - id = id, - width = width, - height = height, - emoji = emoji, - path = path, - format = format.toDomain() -) - -fun GifUiModel.toDomain() = GifModel( - id = id, - fileId = fileId, - thumbFileId = thumbFileId, - width = width, - height = height -) - -fun RecentEmojiUiModel.toDomain() = RecentEmojiModel( - emoji = emoji, - sticker = sticker?.toDomain() -) - -fun StickerTypeUi.toDomain() = StickerType.valueOf(name) - -fun StickerFormatUi.toDomain() = StickerFormat.valueOf(name) \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/core/StickerThumbnailCache.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/core/StickerThumbnailCache.kt deleted file mode 100644 index 96fc913b..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/core/StickerThumbnailCache.kt +++ /dev/null @@ -1,30 +0,0 @@ -package org.monogram.presentation.features.stickers.core - -import android.util.LruCache -import androidx.compose.ui.graphics.ImageBitmap - -object StickerThumbnailCache { - private const val CACHE_SIZE = 150 - - private val cache = object : LruCache(CACHE_SIZE) { - override fun entryRemoved( - evicted: Boolean, - key: String?, - oldValue: ImageBitmap?, - newValue: ImageBitmap? - ) { - } - } - - fun get(key: String): ImageBitmap? { - return cache.get(key) - } - - fun put(key: String, bitmap: ImageBitmap) { - cache.put(key, bitmap) - } - - fun clear() { - cache.evictAll() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/core/VpxStickerController.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/core/VpxStickerController.kt deleted file mode 100644 index 5eb67328..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/core/VpxStickerController.kt +++ /dev/null @@ -1,202 +0,0 @@ -package org.monogram.presentation.features.stickers.core - -import android.graphics.Bitmap -import android.os.Process -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableLongStateOf -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue -import androidx.compose.ui.graphics.ImageBitmap -import androidx.compose.ui.graphics.asImageBitmap -import kotlinx.coroutines.* -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import java.io.File - -class VpxStickerController( - private val filePath: String, - private val scope: CoroutineScope, -) : StickerController { - private var frontBitmap: Bitmap? = null - private var backBitmap: Bitmap? = null - - override var currentImageBitmap by mutableStateOf(null) - private set - - override var frameVersion by mutableLongStateOf(0L) - private set - - private var decoder: VpxWrapper? = null - private var isActive = true - private var isPaused = false - private val decoderMutex = Mutex() - private var renderJob: Job? = null - - override fun start() { - val previousJob = renderJob - renderJob = scope.launch(Dispatchers.IO) { - previousJob?.cancelAndJoin() - initializeAndLoop() - } - } - - override fun setPaused(paused: Boolean) { - isPaused = paused - } - - private suspend fun initializeAndLoop() { - while (isPaused && scope.isActive) { - delay(50) - } - - val tempDecoder = VpxWrapper() - val file = File(filePath) - - if (!file.exists()) { - return - } - - val opened = try { - tempDecoder.open(file) - } catch (e: Exception) { - e.printStackTrace() - false - } - - if (!opened) { - tempDecoder.release() - return - } - - val (w, h) = decoderMutex.withLock { - if (!isActive) { - tempDecoder.release() - return - } - decoder = tempDecoder - Pair(tempDecoder.getVideoWidth(), tempDecoder.getVideoHeight()) - } - - if (w <= 0 || h <= 0) { - release() - return - } - - try { - frontBitmap = BitmapPool.obtain(w, h) - backBitmap = BitmapPool.obtain(w, h) - } catch (_: OutOfMemoryError) { - release() - return - } - - decoderMutex.withLock { - decoder?.renderFrame(frontBitmap!!) - } - currentImageBitmap = frontBitmap!!.asImageBitmap() - - withContext(Dispatchers.Default) { - renderLoop() - } - } - - private suspend fun renderLoop() { - Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND) - - while (isActive) { - val startTime = System.currentTimeMillis() - var delayMs: Long = -1 - - decoderMutex.withLock { - val localDecoder = decoder - if (isActive && localDecoder != null) { - try { - delayMs = localDecoder.renderFrame(backBitmap!!) - } catch (e: Exception) { - e.printStackTrace() - } - } - } - - if (delayMs == -2L) { - awaitCancellation() - } - - if (!isActive) break - - if (isPaused) { - delay(100) - continue - } - - if (delayMs < 0) { - delay(50) - continue - } - - val temp = frontBitmap - frontBitmap = backBitmap - backBitmap = temp - - currentImageBitmap = frontBitmap!!.asImageBitmap() - frameVersion++ - - val workTime = System.currentTimeMillis() - startTime - val sleepTime = (delayMs - workTime).coerceAtLeast(0) - delay(sleepTime) - } - - currentImageBitmap = null - } - - override fun release() { - isActive = false - renderJob?.cancel() - currentImageBitmap = null - - scope.launch(Dispatchers.IO) { - renderJob?.join() - - decoderMutex.withLock { - try { - decoder?.release() - } catch (e: Exception) { - e.printStackTrace() - } - decoder = null - } - frontBitmap?.let { BitmapPool.recycle(it) } - backBitmap?.let { BitmapPool.recycle(it) } - frontBitmap = null - backBitmap = null - } - } - - override suspend fun renderFirstFrame(): ImageBitmap? = withContext(Dispatchers.IO) { - val file = File(filePath) - if (!file.exists()) return@withContext null - - val tempDecoder = VpxWrapper() - try { - if (!tempDecoder.open(file)) return@withContext null - - val w = tempDecoder.getVideoWidth() - val h = tempDecoder.getVideoHeight() - if (w <= 0 || h <= 0) return@withContext null - - val bitmap = BitmapPool.obtain(w, h) - tempDecoder.renderFrame(bitmap) - - bitmap.asImageBitmap() - } catch (e: Exception) { - e.printStackTrace() - null - } finally { - try { - tempDecoder.release() - } catch (e: Exception) { - e.printStackTrace() - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/core/VpxWrapper.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/core/VpxWrapper.kt deleted file mode 100644 index c83fac02..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/core/VpxWrapper.kt +++ /dev/null @@ -1,49 +0,0 @@ -package org.monogram.presentation.features.stickers.core - -import android.graphics.Bitmap -import android.os.ParcelFileDescriptor -import java.io.File - -class VpxWrapper { - private var nativePtr: Long = 0 - private var pfd: ParcelFileDescriptor? = null - - init { - System.loadLibrary("native-lib") - nativePtr = create() - } - - fun open(file: File): Boolean { - return try { - pfd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY) - open(nativePtr, pfd!!.fd, 0, file.length()) - } catch (e: Exception) { - e.printStackTrace() - false - } - } - - fun renderFrame(bitmap: Bitmap): Long { - if (nativePtr == 0L) return -1 - return decodeNextFrame(nativePtr, bitmap) - } - - fun release() { - if (nativePtr != 0L) { - destroy(nativePtr) - nativePtr = 0 - } - pfd?.close() - } - - fun getVideoWidth(): Int = getWidth(nativePtr) - fun getVideoHeight(): Int = getHeight(nativePtr) - - private external fun create(): Long - private external fun open(ptr: Long, fd: Int, offset: Long, length: Long): Boolean - private external fun decodeNextFrame(ptr: Long, bitmap: Bitmap): Long - private external fun destroy(ptr: Long) - - private external fun getWidth(ptr: Long): Int - private external fun getHeight(ptr: Long): Int -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/EmojisGrid.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/EmojisGrid.kt deleted file mode 100644 index f26dd2d7..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/EmojisGrid.kt +++ /dev/null @@ -1,560 +0,0 @@ -package org.monogram.presentation.features.stickers.ui.menu - -import androidx.compose.animation.* -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.grid.* -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowBack -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.Search -import androidx.compose.material.icons.outlined.EmojiEmotions -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.focus.onFocusChanged -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.PlatformTextStyle -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.launch -import org.koin.compose.koinInject -import org.monogram.domain.models.RecentEmojiModel -import org.monogram.domain.models.StickerModel -import org.monogram.domain.models.StickerSetModel -import org.monogram.domain.repository.StickerRepository -import org.monogram.presentation.R -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.features.chats.currentChat.components.StickerSetSheet -import org.monogram.presentation.features.chats.currentChat.components.chats.getEmojiFontFamily -import org.monogram.presentation.features.stickers.ui.view.LocalIsScrolling -import org.monogram.presentation.features.stickers.ui.view.StickerItem - -@Composable -fun EmojisGrid( - onEmojiSelected: (String, StickerModel?) -> Unit, - emojiOnlyMode: Boolean = false, - onSearchFocused: (Boolean) -> Unit = {}, - contentPadding: PaddingValues = PaddingValues(0.dp), - stickerRepository: StickerRepository = koinInject(), - appPreferences: AppPreferences = koinInject() -) { - var standardEmojis by remember { mutableStateOf>(emptyList()) } - val customEmojiSets by stickerRepository.customEmojiStickerSets.collectAsState(initial = emptyList()) - var selectedSetId by remember { mutableLongStateOf(-1L) } // -1 for recent, -2 for standard - val recentEmojis by stickerRepository.recentEmojis.collectAsState(initial = emptyList()) - var searchQuery by remember { mutableStateOf("") } - var debouncedSearchQuery by remember { mutableStateOf("") } - var isSearchFocused by remember { mutableStateOf(false) } - var previewStickerSet by remember { mutableStateOf(null) } - val scope = rememberCoroutineScope() - val gridState = rememberLazyGridState() - - var searchResultsEmojis by remember { mutableStateOf>(emptyList()) } - var searchResultsCustomEmojis by remember { mutableStateOf>(emptyList()) } - - val context = LocalContext.current - val emojiStyle by appPreferences.emojiStyle.collectAsState() - val emojiFontFamily = remember(context, emojiStyle) { getEmojiFontFamily(context, emojiStyle) } - val filteredRecentEmojis = remember(recentEmojis, emojiOnlyMode) { - if (emojiOnlyMode) recentEmojis.filter { it.sticker?.customEmojiId != null } else recentEmojis - } - val visibleStandardEmojis = remember(standardEmojis, emojiOnlyMode) { - if (emojiOnlyMode) emptyList() else standardEmojis - } - - LaunchedEffect(Unit) { - standardEmojis = stickerRepository.getDefaultEmojis() - stickerRepository.loadCustomEmojiStickerSets() - } - - LaunchedEffect(searchQuery) { - if (searchQuery.isBlank()) { - debouncedSearchQuery = "" - } else { - delay(300) - debouncedSearchQuery = searchQuery - } - } - - LaunchedEffect(debouncedSearchQuery) { - if (debouncedSearchQuery.length >= 2) { - searchResultsEmojis = if (emojiOnlyMode) { - emptyList() - } else { - stickerRepository.searchEmojis(debouncedSearchQuery) - } - searchResultsCustomEmojis = stickerRepository.searchCustomEmojis(debouncedSearchQuery) - } else { - searchResultsEmojis = emptyList() - searchResultsCustomEmojis = emptyList() - } - } - - val sectionOffsets = remember(filteredRecentEmojis, visibleStandardEmojis, customEmojiSets) { - val offsets = mutableListOf() - var cursor = 0 - - if (filteredRecentEmojis.isNotEmpty()) { - val count = filteredRecentEmojis.size + 1 - offsets += EmojiSectionOffset(id = -1L, startIndex = cursor, endExclusive = cursor + count) - cursor += count - } - - if (visibleStandardEmojis.isNotEmpty()) { - val count = visibleStandardEmojis.size + 1 - offsets += EmojiSectionOffset(id = -2L, startIndex = cursor, endExclusive = cursor + count) - cursor += count - } - - customEmojiSets.forEach { set -> - val count = set.stickers.size + 1 - offsets += EmojiSectionOffset(id = set.id, startIndex = cursor, endExclusive = cursor + count) - cursor += count - } - - offsets - } - - val sectionStartById = remember(sectionOffsets) { - sectionOffsets.associate { it.id to it.startIndex } - } - - val localSearchFallbackResults = remember(debouncedSearchQuery, visibleStandardEmojis) { - if (debouncedSearchQuery.isNotEmpty()) { - visibleStandardEmojis.filter { it.contains(debouncedSearchQuery) } - } else { - emptyList() - } - } - - LaunchedEffect(sectionOffsets) { - if (sectionOffsets.isNotEmpty() && sectionOffsets.none { it.id == selectedSetId }) { - selectedSetId = sectionOffsets.first().id - } - } - - LaunchedEffect(gridState, searchQuery, sectionOffsets) { - if (searchQuery.isNotEmpty() || sectionOffsets.isEmpty()) return@LaunchedEffect - - snapshotFlow { gridState.firstVisibleItemIndex } - .distinctUntilChanged() - .collect { firstIndex -> - val currentSectionId = sectionOffsets - .firstOrNull { firstIndex in it.startIndex until it.endExclusive } - ?.id - ?: sectionOffsets.lastOrNull()?.id - - if (currentSectionId != null && currentSectionId != selectedSetId) { - selectedSetId = currentSectionId - } - } - } - - Column(modifier = Modifier.fillMaxSize()) { - EmojiSearchBar( - query = searchQuery, - onQueryChange = { searchQuery = it }, - onFocusChanged = { - isSearchFocused = it - onSearchFocused(it || searchQuery.isNotEmpty()) - }, - isSearchMode = isSearchFocused || searchQuery.isNotEmpty() - ) - - AnimatedVisibility( - visible = !isSearchFocused && searchQuery.isEmpty(), - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically() - ) { - EmojiSetsRow( - customEmojiSets = customEmojiSets, - selectedSetId = selectedSetId, - hasRecent = filteredRecentEmojis.isNotEmpty(), - hasStandard = visibleStandardEmojis.isNotEmpty(), - onSetSelected = { id -> - selectedSetId = id - scope.launch { - val targetIndex = sectionStartById[id] ?: return@launch - gridState.animateScrollToItem(targetIndex) - } - } - ) - } - - HorizontalDivider( - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f), - thickness = 0.5.dp - ) - - Box(modifier = Modifier.fillMaxSize()) { - CompositionLocalProvider(LocalIsScrolling provides gridState.isScrollInProgress) { - LazyVerticalGrid( - columns = GridCells.Adaptive(minSize = 48.dp), - state = gridState, - contentPadding = PaddingValues( - start = 12.dp, - end = 12.dp, - top = 8.dp, - bottom = contentPadding.calculateBottomPadding() + 8.dp - ), - modifier = Modifier.fillMaxSize(), - horizontalArrangement = Arrangement.spacedBy(4.dp), - verticalArrangement = Arrangement.spacedBy(4.dp) - ) { - if (searchQuery.isNotEmpty()) { - if (searchResultsEmojis.isNotEmpty()) { - item(span = { GridItemSpan(maxLineSpan) }) { - PackHeader(stringResource(R.string.emojis_header_all)) - } - itemsIndexed(searchResultsEmojis, key = { index, emoji -> "search_emoji_${index}_$emoji" }) { _, emoji -> - EmojiGridItem(emoji, emojiFontFamily) { - onEmojiSelected(emoji, null) - scope.launch { stickerRepository.addRecentEmoji(RecentEmojiModel(emoji)) } - } - } - } - - if (searchResultsCustomEmojis.isNotEmpty()) { - item(span = { GridItemSpan(maxLineSpan) }) { - PackHeader(stringResource(R.string.emojis_header_custom)) - } - items(searchResultsCustomEmojis, key = { "search_custom_${it.id}" }) { sticker -> - Box( - modifier = Modifier - .aspectRatio(1f) - .background( - color = MaterialTheme.colorScheme.surfaceContainerLow.copy(alpha = 0.5f), - shape = CircleShape - ), - contentAlignment = Alignment.Center - ) { - StickerItem( - sticker = sticker, - modifier = Modifier.size(36.dp), - onClick = { _ -> onEmojiSelected(sticker.emoji, sticker) } - ) - } - } - } - - if (!emojiOnlyMode && searchResultsEmojis.isEmpty() && searchResultsCustomEmojis.isEmpty()) { - itemsIndexed(localSearchFallbackResults, key = { index, emoji -> "search_local_${index}_$emoji" }) { _, emoji -> - EmojiGridItem(emoji, emojiFontFamily) { - onEmojiSelected(emoji, null) - scope.launch { stickerRepository.addRecentEmoji(RecentEmojiModel(emoji)) } - } - } - } - } else { - // Recent Emojis - if (filteredRecentEmojis.isNotEmpty()) { - item(span = { GridItemSpan(maxLineSpan) }) { - PackHeader(stringResource(R.string.emojis_header_recent)) - } - itemsIndexed( - filteredRecentEmojis, - key = { index, item -> - val stickerKey = item.sticker?.customEmojiId ?: item.sticker?.id - "recent_${stickerKey ?: item.emoji}_$index" - } - ) { _, item -> - Box( - modifier = Modifier - .aspectRatio(1f) - .background( - color = MaterialTheme.colorScheme.surfaceContainerLow.copy(alpha = 0.5f), - shape = CircleShape - ), - contentAlignment = Alignment.Center - ) { - val sticker = item.sticker - if (sticker != null) { - StickerItem( - sticker = sticker, - modifier = Modifier.size(36.dp), - onClick = { onEmojiSelected(item.emoji, item.sticker) } - ) - } else { - Box( - modifier = Modifier - .fillMaxSize() - .clickable { onEmojiSelected(item.emoji, null) }, - contentAlignment = Alignment.Center - ) { - Text(item.emoji, fontSize = 28.sp, fontFamily = emojiFontFamily) - } - } - } - } - } - - // Standard Emojis - if (visibleStandardEmojis.isNotEmpty()) { - item(span = { GridItemSpan(maxLineSpan) }) { - PackHeader(stringResource(R.string.emojis_header_standard)) - } - itemsIndexed( - visibleStandardEmojis, - key = { index, emoji -> "standard_${emoji}_$index" } - ) { _, emoji -> - EmojiGridItem(emoji, emojiFontFamily) { - onEmojiSelected(emoji, null) - scope.launch { stickerRepository.addRecentEmoji(RecentEmojiModel(emoji)) } - } - } - } - - // Custom Emoji Sets - customEmojiSets.forEach { set -> - item(key = "header_${set.id}", span = { GridItemSpan(maxLineSpan) }) { - PackHeader(set.title, onClick = { previewStickerSet = set }) - } - items(set.stickers, key = { "custom_${set.id}_${it.id}" }) { sticker -> - Box( - modifier = Modifier - .aspectRatio(1f) - .background( - color = MaterialTheme.colorScheme.surfaceContainerLow.copy(alpha = 0.5f), - shape = CircleShape - ), - contentAlignment = Alignment.Center - ) { - StickerItem( - sticker = sticker, - modifier = Modifier.size(36.dp), - onClick = { _ -> onEmojiSelected(sticker.emoji, sticker) } - ) - } - } - } - } - } - } - } - } - - previewStickerSet?.let { set -> - StickerSetSheet( - stickerSet = set, - onDismiss = { previewStickerSet = null }, - onStickerClick = { path -> - val sticker = set.stickers.find { it.path == path } - onEmojiSelected(sticker?.emoji ?: "", sticker) - previewStickerSet = null - } - ) - } -} - -@Composable -private fun EmojiGridItem( - emoji: String, - fontFamily: FontFamily, - onClick: () -> Unit -) { - Box( - modifier = Modifier - .aspectRatio(1f) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.surfaceContainerLow.copy(alpha = 0.5f)) - .clickable(onClick = onClick), - contentAlignment = Alignment.Center - ) { - Text(emoji, fontSize = 28.sp, fontFamily = fontFamily) - } -} - -@Composable -fun EmojiSearchBar( - query: String, - onQueryChange: (String) -> Unit, - onFocusChanged: (Boolean) -> Unit, - isSearchMode: Boolean = false -) { - val focusManager = LocalFocusManager.current - - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 32.dp, vertical = 4.dp), - verticalAlignment = Alignment.CenterVertically - ) { - if (isSearchMode) { - IconButton( - onClick = { - onQueryChange("") - focusManager.clearFocus() - }, - modifier = Modifier.size(40.dp) - ) { - Icon( - imageVector = Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = stringResource(R.string.common_back), - tint = MaterialTheme.colorScheme.onSurface, - modifier = Modifier.size(20.dp) - ) - } - Spacer(modifier = Modifier.width(4.dp)) - } - - TextField( - value = query, - onValueChange = onQueryChange, - modifier = Modifier - .weight(1f) - .heightIn(min = 44.dp) - .onFocusChanged { onFocusChanged(it.isFocused) }, - placeholder = { - Text( - text = stringResource(R.string.emojis_search_placeholder), - style = MaterialTheme.typography.bodyMedium.copy( - platformStyle = PlatformTextStyle(includeFontPadding = false) - ) - ) - }, - leadingIcon = if (!isSearchMode) { - { - Icon(Icons.Default.Search, contentDescription = null, modifier = Modifier.size(20.dp)) - } - } else null, - trailingIcon = if (query.isNotEmpty()) { - { - IconButton(onClick = { - onQueryChange("") - }) { - Icon(Icons.Default.Close, contentDescription = stringResource(R.string.common_clear), modifier = Modifier.size(20.dp)) - } - } - } else null, - singleLine = true, - shape = RoundedCornerShape(24.dp), - colors = TextFieldDefaults.colors( - focusedIndicatorColor = Color.Transparent, - unfocusedIndicatorColor = Color.Transparent, - disabledIndicatorColor = Color.Transparent, - focusedContainerColor = MaterialTheme.colorScheme.surfaceContainerHigh, - unfocusedContainerColor = MaterialTheme.colorScheme.surfaceContainerHigh - ), - textStyle = MaterialTheme.typography.bodyMedium.copy( - platformStyle = PlatformTextStyle(includeFontPadding = false) - ) - ) - } -} - -@Composable -fun EmojiSetsRow( - customEmojiSets: List, - selectedSetId: Long, - hasRecent: Boolean, - hasStandard: Boolean, - onSetSelected: (Long) -> Unit -) { - val listState = rememberLazyListState() - - LaunchedEffect(selectedSetId) { - val index = when (selectedSetId) { - -1L -> if (hasRecent) 0 else -1 - -2L -> when { - hasRecent -> 1 - hasStandard -> 0 - else -> -1 - } - - else -> { - val base = (if (hasRecent) 1 else 0) + (if (hasStandard) 1 else 0) - customEmojiSets.indexOfFirst { it.id == selectedSetId }.takeIf { it >= 0 }?.let { base + it } ?: -1 - } - } - if (index >= 0) { - listState.scrollToItem(index) - } - } - - LazyRow( - state = listState, - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 4.dp), - contentPadding = PaddingValues(horizontal = 16.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalAlignment = Alignment.CenterVertically - ) { - if (hasRecent) { - item { - SetItem( - isSelected = selectedSetId == -1L, - onClick = { onSetSelected(-1L) }, - icon = { - Icon( - imageVector = Icons.Outlined.EmojiEmotions, - contentDescription = stringResource(R.string.common_recent), - tint = if (selectedSetId == -1L) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.size(20.dp) - ) - } - ) - } - } - - if (hasStandard) { - item { - SetItem( - isSelected = selectedSetId == -2L, - onClick = { onSetSelected(-2L) }, - content = { Text("😀", fontSize = 22.sp) } - ) - } - } - - items( - items = customEmojiSets, - key = { it.id } - ) { set -> - SetItem( - isSelected = selectedSetId == set.id, - onClick = { onSetSelected(set.id) }, - content = { - val firstSticker = set.stickers.firstOrNull() - if (firstSticker != null) { - StickerItem( - sticker = firstSticker, - modifier = Modifier.fillMaxSize(), - animate = false, - onClick = null - ) - } else { - Text( - set.title.take(1), - style = MaterialTheme.typography.labelLarge, - fontWeight = FontWeight.Bold, - color = if (selectedSetId == set.id) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - ) - } - } -} - -private data class EmojiSectionOffset( - val id: Long, - val startIndex: Int, - val endExclusive: Int -) diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/GifsGrid.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/GifsGrid.kt deleted file mode 100644 index f0fc2541..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/GifsGrid.kt +++ /dev/null @@ -1,380 +0,0 @@ -package org.monogram.presentation.features.stickers.ui.menu - -import androidx.compose.animation.* -import androidx.compose.animation.core.tween -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.lazy.grid.itemsIndexed -import androidx.compose.foundation.lazy.grid.rememberLazyGridState -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowBack -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.Search -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.focus.onFocusChanged -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.media3.common.util.UnstableApi -import coil3.compose.SubcomposeAsyncImage -import coil3.request.ImageRequest -import coil3.request.crossfade -import kotlinx.coroutines.delay -import org.monogram.domain.models.GifModel -import org.monogram.domain.repository.StickerRepository -import org.monogram.presentation.R -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.chats.currentChat.components.VideoStickerPlayer -import org.monogram.presentation.features.chats.currentChat.components.VideoType -import org.monogram.presentation.features.stickers.ui.view.shimmerEffect - -@androidx.annotation.OptIn(UnstableApi::class) -@Composable -fun GifsView( - onGifSelected: (GifModel) -> Unit, - onSearchFocused: (Boolean) -> Unit, - contentPadding: PaddingValues = PaddingValues(0.dp), - videoPlayerPool: VideoPlayerPool, - stickerRepository: StickerRepository -) { - var searchQuery by remember { mutableStateOf("") } - var debouncedSearchQuery by remember { mutableStateOf("") } - var savedGifs by remember { mutableStateOf>(emptyList()) } - var searchResults by remember { mutableStateOf>(emptyList()) } - var isLoading by remember { mutableStateOf(false) } - var isFocused by remember { mutableStateOf(false) } - val scope = rememberCoroutineScope() - val gridState = rememberLazyGridState() - - LaunchedEffect(Unit) { - savedGifs = stickerRepository.getSavedGifs() - } - - LaunchedEffect(searchQuery) { - if (searchQuery.isNotEmpty()) { - isLoading = true - delay(300) - debouncedSearchQuery = searchQuery - } else { - debouncedSearchQuery = "" - searchResults = emptyList() - isLoading = false - } - } - - LaunchedEffect(debouncedSearchQuery) { - if (debouncedSearchQuery.isNotEmpty()) { - searchResults = stickerRepository.searchGifs(debouncedSearchQuery) - isLoading = false - } else { - searchResults = emptyList() - isLoading = false - } - } - - val gifsToShow = remember(searchQuery, searchResults, savedGifs) { - if (searchQuery.isNotEmpty()) { - searchResults - } else { - savedGifs - } - } - - val visibleRange by remember { - derivedStateOf { - val visibleItems = gridState.layoutInfo.visibleItemsInfo - if (visibleItems.isEmpty()) { - IntRange.EMPTY - } else { - visibleItems.first().index..visibleItems.last().index - } - } - } - - val onGifClick: (GifModel) -> Unit = remember(scope, stickerRepository, onGifSelected) { - { gif: GifModel -> - onGifSelected(gif) - } - } - - Column(modifier = Modifier.fillMaxSize()) { - GifSearchBar( - query = searchQuery, - onQueryChange = { searchQuery = it }, - onSearchFocused = { - isFocused = it - onSearchFocused(it) - }, - onClearQuery = { searchQuery = "" }, - isSearchMode = isFocused - ) - - AnimatedVisibility( - visible = !isFocused && searchQuery.isEmpty(), - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically() - ) { - Text( - text = stringResource(R.string.gifs_header_recent_saved), - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.SemiBold, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp) - ) - } - - HorizontalDivider( - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f), - thickness = 0.5.dp, - modifier = Modifier.padding(top = 4.dp) - ) - - if (isLoading) { - GifGridSkeleton(contentPadding = contentPadding) - } else { - if (gifsToShow.isEmpty() && searchQuery.isEmpty()) { - Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { - Text(stringResource(R.string.gifs_no_results), style = MaterialTheme.typography.bodyMedium) - } - } else { - LazyVerticalGrid( - state = gridState, - columns = GridCells.Adaptive(minSize = 120.dp), - contentPadding = PaddingValues( - start = 12.dp, - end = 12.dp, - top = 8.dp, - bottom = contentPadding.calculateBottomPadding() + 8.dp - ), - modifier = Modifier.fillMaxSize(), - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - itemsIndexed( - items = gifsToShow, - key = { _, gif -> gif.id }, - contentType = { _, _ -> "GifItem" } - ) { index, gif -> - GifItem( - gif = gif, - stickerRepository = stickerRepository, - onGifSelected = onGifClick, - videoPlayerPool = videoPlayerPool, - animate = index in visibleRange - ) - } - } - } - } - } -} - -@Composable -private fun GifGridSkeleton( - contentPadding: PaddingValues -) { - LazyVerticalGrid( - columns = GridCells.Adaptive(minSize = 120.dp), - contentPadding = PaddingValues( - start = 12.dp, - end = 12.dp, - top = 8.dp, - bottom = contentPadding.calculateBottomPadding() + 8.dp - ), - modifier = Modifier.fillMaxSize(), - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalArrangement = Arrangement.spacedBy(8.dp), - userScrollEnabled = false - ) { - items(20) { - Box( - modifier = Modifier - .aspectRatio(1f) - .clip(RoundedCornerShape(12.dp)) - .shimmerEffect() - ) - } - } -} - -@Composable -fun GifSearchBar( - query: String, - onQueryChange: (String) -> Unit, - onSearchFocused: (Boolean) -> Unit, - onClearQuery: () -> Unit, - isSearchMode: Boolean = false -) { - val focusManager = LocalFocusManager.current - - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp, vertical = 6.dp), - verticalAlignment = Alignment.CenterVertically - ) { - if (isSearchMode) { - IconButton( - onClick = { focusManager.clearFocus() }, - modifier = Modifier.size(40.dp) - ) { - Icon( - imageVector = Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = stringResource(R.string.common_back), - tint = MaterialTheme.colorScheme.onSurface, - modifier = Modifier.size(20.dp) - ) - } - Spacer(modifier = Modifier.width(4.dp)) - } - - TextField( - value = query, - onValueChange = onQueryChange, - modifier = Modifier - .weight(1f) - .height(48.dp) - .onFocusChanged { onSearchFocused(it.isFocused) }, - placeholder = { Text(stringResource(R.string.gifs_search_placeholder), style = MaterialTheme.typography.bodyMedium) }, - leadingIcon = if (!isSearchMode) { - { - Icon( - Icons.Default.Search, - contentDescription = null, - modifier = Modifier.size(20.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } else null, - trailingIcon = if (query.isNotEmpty()) { - { - IconButton(onClick = onClearQuery) { - Icon( - Icons.Default.Close, - contentDescription = stringResource(R.string.common_clear), - modifier = Modifier.size(20.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } else null, - singleLine = true, - shape = RoundedCornerShape(24.dp), - colors = TextFieldDefaults.colors( - focusedIndicatorColor = Color.Transparent, - unfocusedIndicatorColor = Color.Transparent, - disabledIndicatorColor = Color.Transparent, - focusedContainerColor = MaterialTheme.colorScheme.surfaceContainerHigh, - unfocusedContainerColor = MaterialTheme.colorScheme.surfaceContainerHigh - ), - textStyle = MaterialTheme.typography.bodyMedium - ) - } -} - - -@UnstableApi -@Composable -fun GifItem( - videoPlayerPool: VideoPlayerPool, - gif: GifModel, - stickerRepository: StickerRepository, - onGifSelected: (GifModel) -> Unit, - animate: Boolean = true -) { - var gifPath by remember { mutableStateOf(null) } - var thumbPath by remember { mutableStateOf(null) } - - LaunchedEffect(gif, animate) { - if (animate) { - stickerRepository.getGifFile(gif).collect { - gifPath = it - } - } - } - - LaunchedEffect(gif.thumbFileId) { - if (gif.thumbFileId != null) { - stickerRepository.getStickerFile(gif.thumbFileId!!).collect { - thumbPath = it - } - } - } - - val state = when { - gifPath != null -> GifState.Video - thumbPath != null -> GifState.Thumbnail - else -> GifState.Loading - } - - Box( - modifier = Modifier - .aspectRatio(1f) - .clip(RoundedCornerShape(12.dp)) - .background(MaterialTheme.colorScheme.surfaceContainerLow) - .clickable { - onGifSelected(gif) - } - ) { - AnimatedContent( - targetState = state, - transitionSpec = { - fadeIn(animationSpec = tween(200)) togetherWith fadeOut(animationSpec = tween(200)) - }, - label = "GifContentTransition" - ) { targetState -> - when (targetState) { - GifState.Video -> { - VideoStickerPlayer( - path = gifPath!!, - type = VideoType.Gif, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Crop, - videoPlayerPool = videoPlayerPool, - animate = animate, - thumbnailData = thumbPath - ) - } - GifState.Thumbnail -> { - SubcomposeAsyncImage( - model = ImageRequest.Builder(LocalContext.current) - .data(thumbPath) - .crossfade(true) - .build(), - contentDescription = null, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Crop, - loading = { - Box(modifier = Modifier.shimmerEffect()) - } - ) - } - GifState.Loading -> { - Box( - modifier = Modifier - .fillMaxSize() - .shimmerEffect() - ) - } - } - } - } -} - -private enum class GifState { - Loading, - Thumbnail, - Video -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/MenuCommon.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/MenuCommon.kt deleted file mode 100644 index a176dc62..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/MenuCommon.kt +++ /dev/null @@ -1,107 +0,0 @@ -package org.monogram.presentation.features.stickers.ui.menu - -import androidx.compose.animation.animateColorAsState -import androidx.compose.animation.core.animateDpAsState -import androidx.compose.animation.core.spring -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.unit.dp - -@Composable -fun SetItem( - isSelected: Boolean, - onClick: () -> Unit, - icon: @Composable (() -> Unit)? = null, - content: @Composable (() -> Unit)? = null -) { - val containerColor by animateColorAsState( - targetValue = if (isSelected) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerHigh, - label = "containerColor" - ) - - Box( - modifier = Modifier - .size(38.dp) - .clip(CircleShape) - .background(containerColor) - .clickable(onClick = onClick) - .padding(if (icon != null) 8.dp else 3.dp), - contentAlignment = Alignment.Center - ) { - if (icon != null) { - icon() - } else { - content?.invoke() - } - } -} - -@Composable -fun FloatingTabs( - tabs: List>, - selectedTab: Int, - onTabSelected: (Int) -> Unit -) { - Surface( - shape = CircleShape, - color = MaterialTheme.colorScheme.surfaceContainerHighest.copy(alpha = 0.9f), - tonalElevation = 8.dp, - shadowElevation = 12.dp, - modifier = Modifier.padding(horizontal = 16.dp) - ) { - Box(modifier = Modifier.padding(4.dp)) { - val indicatorOffset by animateDpAsState( - targetValue = (selectedTab * 64).dp, - animationSpec = spring(stiffness = 500f), - label = "indicatorOffset" - ) - - Box( - modifier = Modifier - .offset(x = indicatorOffset) - .size(width = 60.dp, height = 40.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primary) - ) - - Row( - horizontalArrangement = Arrangement.spacedBy(4.dp), - verticalAlignment = Alignment.CenterVertically - ) { - tabs.forEach { (title, icon, index) -> - val selected = selectedTab == index - val contentColor by animateColorAsState( - targetValue = if (selected) MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurfaceVariant, - label = "contentColor" - ) - - Box( - modifier = Modifier - .size(width = 60.dp, height = 40.dp) - .clip(CircleShape) - .clickable { onTabSelected(index) }, - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = icon, - contentDescription = title, - tint = contentColor, - modifier = Modifier.size(24.dp) - ) - } - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/MenuComponents.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/MenuComponents.kt deleted file mode 100644 index 8b80de77..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/MenuComponents.kt +++ /dev/null @@ -1,169 +0,0 @@ -package org.monogram.presentation.features.stickers.ui.menu - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Check -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Switch -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.scale -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp - -@Composable -fun MenuOptionRow( - icon: ImageVector, - title: String, - value: String? = null, - onClick: () -> Unit, - iconTint: Color = MaterialTheme.colorScheme.onSurface, - textColor: Color = MaterialTheme.colorScheme.onSurface, - trailingIcon: ImageVector? = null -) { - Row( - modifier = Modifier - .fillMaxWidth() - .clickable(onClick = onClick) - .padding(horizontal = 16.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.weight(1f)) { - Icon( - imageVector = icon, - contentDescription = null, - tint = iconTint, - modifier = Modifier.size(22.dp) - ) - Spacer(modifier = Modifier.width(12.dp)) - Text( - text = title, - style = MaterialTheme.typography.bodyMedium, - color = textColor - ) - } - Row(verticalAlignment = Alignment.CenterVertically) { - if (value != null) { - Text( - text = value, - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.primary - ) - } - if (trailingIcon != null) { - Spacer(modifier = Modifier.width(8.dp)) - Icon( - trailingIcon, - null, - tint = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.size(16.dp) - ) - } - } - } -} - -@Composable -fun MenuOptionRow( - iconRes: Int, - title: String, - value: String? = null, - onClick: () -> Unit, - iconTint: Color = MaterialTheme.colorScheme.onSurface, - textColor: Color = MaterialTheme.colorScheme.onSurface, - trailingIcon: ImageVector? = null -) { - MenuOptionRow( - icon = ImageVector.vectorResource(id = iconRes), - title = title, - value = value, - onClick = onClick, - iconTint = iconTint, - textColor = textColor, - trailingIcon = trailingIcon - ) -} - -@Composable -fun MenuInfoRow( - icon: ImageVector, - title: String, - value: String, - iconTint: Color = MaterialTheme.colorScheme.onSurfaceVariant -) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Icon( - imageVector = icon, - contentDescription = null, - tint = iconTint, - modifier = Modifier.size(20.dp) - ) - Spacer(modifier = Modifier.width(12.dp)) - Column { - Text( - text = title, - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Text( - text = value, - style = MaterialTheme.typography.bodySmall, - fontWeight = FontWeight.Medium, - color = MaterialTheme.colorScheme.onSurface - ) - } - } -} - -@Composable -fun MenuToggleRow( - icon: ImageVector, - title: String, - isChecked: Boolean, - onCheckedChange: (Boolean) -> Unit -) { - Row( - modifier = Modifier - .fillMaxWidth() - .clickable { onCheckedChange(!isChecked) } - .padding(horizontal = 16.dp, vertical = 4.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.weight(1f)) { - Icon( - imageVector = icon, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurface, - modifier = Modifier.size(22.dp) - ) - Spacer(modifier = Modifier.width(12.dp)) - Text( - text = title, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurface - ) - } - Switch( - checked = isChecked, - onCheckedChange = onCheckedChange, - modifier = Modifier.scale(0.8f), - thumbContent = if (isChecked) { - { Icon(Icons.Rounded.Check, null, Modifier.size(12.dp)) } - } else null - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/MessageOptionsMenu.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/MessageOptionsMenu.kt deleted file mode 100644 index 4ed7401a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/MessageOptionsMenu.kt +++ /dev/null @@ -1,1262 +0,0 @@ -package org.monogram.presentation.features.stickers.ui.menu - -import androidx.compose.animation.* -import androidx.compose.animation.core.* -import androidx.compose.foundation.* -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.automirrored.rounded.Chat -import androidx.compose.material.icons.automirrored.rounded.Forward -import androidx.compose.material.icons.automirrored.rounded.Reply -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.runtime.saveable.listSaver -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.drawWithContent -import androidx.compose.ui.geometry.* -import androidx.compose.ui.graphics.* -import androidx.compose.ui.graphics.drawscope.clipRect -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.hapticfeedback.HapticFeedbackType -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.LocalHapticFeedback -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.* -import androidx.compose.ui.zIndex -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import org.koin.compose.koinInject -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.MessageModel -import org.monogram.domain.models.MessageViewerModel -import org.monogram.domain.models.RecentEmojiModel -import org.monogram.domain.repository.StickerRepository -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.features.chats.currentChat.chatContent.DeleteMessagesSheet -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.chats.currentChat.components.chats.getEmojiFontFamily -import org.monogram.presentation.features.stickers.ui.view.StickerImage -import java.text.SimpleDateFormat -import java.util.* - -@Composable -fun MessageOptionsMenu( - message: MessageModel, - canWrite: Boolean, - canPinMessages: Boolean, - isPinned: Boolean, - messageOffset: Offset, - messageSize: IntSize, - clickOffset: Offset, - contentRect: Rect, - isSameSenderAbove: Boolean = false, - isSameSenderBelow: Boolean = false, - isMessageOutgoing: Boolean = message.isOutgoing, - showReadInfo: Boolean = true, - showViewsInfo: Boolean = true, - showViewersList: Boolean = false, - canReport: Boolean = true, - canBlock: Boolean = false, - canRestrict: Boolean = false, - canCopyLink: Boolean = true, - showTelegramSummary: Boolean = false, - showTelegramTranslator: Boolean = false, - showRestoreOriginalText: Boolean = false, - viewers: List = emptyList(), - isLoadingViewers: Boolean = false, - onReloadViewers: () -> Unit = {}, - onViewerClick: (Long) -> Unit = {}, - videoPlayerPool: VideoPlayerPool, - bubbleRadius: Float = 18f, - splitOffset: Int? = null, - onReply: () -> Unit, - onPin: () -> Unit, - onEdit: () -> Unit, - onDelete: (Boolean) -> Unit, - onForward: () -> Unit, - onSelect: () -> Unit = {}, - onCopyLink: () -> Unit, - onCopy: () -> Unit, - onSaveToDownloads: () -> Unit = {}, - onReaction: (String) -> Unit = {}, - onComments: () -> Unit = {}, - onTelegramSummary: () -> Unit = {}, - onTelegramTranslator: () -> Unit = {}, - onRestoreOriginalText: () -> Unit = {}, - onReport: () -> Unit = {}, - onBlock: () -> Unit = {}, - onRestrict: () -> Unit = {}, - onDismiss: () -> Unit -) { - val density = LocalDensity.current - val configuration = LocalConfiguration.current - val haptic = LocalHapticFeedback.current - val scope = rememberCoroutineScope() - val stickerRepository: StickerRepository = koinInject() - - val screenHeight = with(density) { configuration.screenHeightDp.dp.toPx() }.toInt() - val windowInsets = WindowInsets.systemBars.union(WindowInsets.ime) - val topInset = windowInsets.getTop(density) - val bottomInset = windowInsets.getBottom(density) - - val horizontalMargin = with(density) { 16.dp.toPx() }.toInt() - val verticalPadding = with(density) { 8.dp.toPx() }.toInt() - - var menuVisible by remember { mutableStateOf(false) } - val visibilityTransition = updateTransition(targetState = menuVisible, label = "MenuVisibility") - val menuScale by visibilityTransition.animateFloat( - transitionSpec = { - if (targetState) { - spring( - dampingRatio = Spring.DampingRatioNoBouncy, - stiffness = Spring.StiffnessMedium - ) - } else { - tween(durationMillis = 160, easing = FastOutLinearInEasing) - } - }, - label = "MenuScale" - ) { visible -> - if (visible) 1f else 0.94f - } - val menuAlpha by visibilityTransition.animateFloat( - transitionSpec = { - tween( - durationMillis = if (targetState) 170 else 120, - easing = LinearOutSlowInEasing - ) - }, - label = "MenuAlpha" - ) { visible -> - if (visible) 1f else 0f - } - val dimAlpha by visibilityTransition.animateFloat( - transitionSpec = { tween(durationMillis = if (targetState) 190 else 140) }, - label = "MenuDimAlpha" - ) { visible -> - if (visible) 1f else 0f - } - - var menuSize by remember { mutableStateOf(IntSize.Zero) } - var firstScreenWidth by remember { mutableStateOf(null) } - var containerOffset by remember { mutableStateOf(Offset.Zero) } - var containerSize by remember { mutableStateOf(IntSize.Zero) } - val currentSections = remember( - message.id, - canWrite, - canPinMessages, - message.canBeEdited, - message.canBeForwarded, - message.canGetMessageThread, - message.canBeDeletedOnlyForSelf, - message.canBeDeletedForAllUsers, - showViewersList, - showTelegramSummary, - showTelegramTranslator, - showRestoreOriginalText, - canCopyLink, - canReport, - canBlock, - canRestrict, - message.canBeSaved, - message.content - ) { - buildMenuSections( - message = message, - canWrite = canWrite, - canPinMessages = canPinMessages, - showViewersList = showViewersList, - canCopyLink = canCopyLink, - canReport = canReport, - canBlock = canBlock, - canRestrict = canRestrict, - showTelegramSummary = showTelegramSummary, - showTelegramTranslator = showTelegramTranslator, - showRestoreOriginalText = showRestoreOriginalText - ) - } - var savedSections by rememberSaveable(message.id, stateSaver = MessageMenuSections.Saver) { - mutableStateOf(currentSections) - } - var hasReactionsInMessage by remember(message.id) { mutableStateOf(false) } - var suppressNextReactionsAppearanceAnimation by remember(message.id) { mutableStateOf(false) } - var availableReactions by remember(message.chatId, message.id) { mutableStateOf>(emptyList()) } - - LaunchedEffect(message.chatId, message.id) { - availableReactions = stickerRepository.getMessageAvailableReactions(message.chatId, message.id) - } - - fun animateOutAndDismiss(action: (() -> Unit)? = null) { - if (!menuVisible) return - scope.launch { - menuVisible = false - delay(170) - action?.invoke() - onDismiss() - } - } - - val maxMenuHeight = remember(screenHeight, topInset, bottomInset) { - with(density) { - (screenHeight - topInset - bottomInset - 2 * verticalPadding).toFloat().toDp().coerceAtLeast(100.dp) - } - } - - val menuPosition by remember( - menuSize, - messageOffset, - messageSize, - clickOffset, - containerSize, - containerOffset, - topInset, - bottomInset - ) { - derivedStateOf { - if (menuSize == IntSize.Zero || containerSize == IntSize.Zero) return@derivedStateOf IntOffset.Zero - - var x = (clickOffset.x - (menuSize.width / 2)).toInt() - val minX = containerOffset.x.toInt() + horizontalMargin - val maxX = containerOffset.x.toInt() + containerSize.width - menuSize.width - horizontalMargin - x = if (maxX >= minX) x.coerceIn(minX, maxX) else minX - - var y = (clickOffset.y - (menuSize.height / 2)).toInt() - val minY = maxOf(containerOffset.y.toInt() + verticalPadding, topInset + verticalPadding) - val maxY = minOf( - containerOffset.y.toInt() + containerSize.height - menuSize.height - verticalPadding, - screenHeight - bottomInset - menuSize.height - verticalPadding - ) - y = if (maxY >= minY) y.coerceIn(minY, maxY) else minY - - IntOffset(x - containerOffset.x.toInt(), y - containerOffset.y.toInt()) - } - } - - val transformOrigin by remember(menuPosition, menuSize, clickOffset, containerOffset) { - derivedStateOf { - if (menuSize == IntSize.Zero) return@derivedStateOf TransformOrigin.Center - - val relativeClickX = clickOffset.x - containerOffset.x - val relativeClickY = clickOffset.y - containerOffset.y - - val pivotX = ((relativeClickX - menuPosition.x) / menuSize.width).coerceIn(0f, 1f) - val pivotY = ((relativeClickY - menuPosition.y) / menuSize.height).coerceIn(0f, 1f) - TransformOrigin(pivotX, pivotY) - } - } - - LaunchedEffect(Unit) { - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - menuVisible = true - } - - LaunchedEffect(currentSections) { - savedSections = savedSections.merge(currentSections) - } - - var showDeleteSheet by remember { mutableStateOf(false) } - var menuPage by remember { mutableStateOf(MenuPage.Main) } - val sections = savedSections - - LaunchedEffect(menuPage, sections.hasMoreSection) { - if (menuPage == MenuPage.More && !sections.hasMoreSection) { - menuPage = MenuPage.Main - } - } - - if (showDeleteSheet) { - DeleteMessagesSheet( - count = 1, - canRevoke = message.canBeDeletedForAllUsers, - onDismiss = { showDeleteSheet = false }, - onDelete = { revoke -> - animateOutAndDismiss { onDelete(revoke) } - showDeleteSheet = false - } - ) - } - - Box( - modifier = Modifier - .fillMaxSize() - .zIndex(100f) - .onGloballyPositioned { coordinates -> - containerOffset = coordinates.positionInWindow() - containerSize = coordinates.size - } - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null, - onClick = { animateOutAndDismiss() } - ) - .graphicsLayer { compositingStrategy = CompositingStrategy.Offscreen } - .drawWithContent { - val alphaVal = dimAlpha - if (alphaVal > 0f) { - drawRect(Color.Black.copy(alpha = 0.45f * alphaVal)) - clipRect( - left = contentRect.left - containerOffset.x, - top = contentRect.top - containerOffset.y, - right = contentRect.right - containerOffset.x, - bottom = contentRect.bottom - containerOffset.y - ) { - val r = bubbleRadius.dp.toPx() - val s = (bubbleRadius / 4f).coerceAtLeast(4f).dp.toPx() - val t = 2.dp.toPx() - val path = Path().apply { - if (splitOffset != null && splitOffset > 0 && splitOffset < messageSize.height) { - val gap = 2.dp.toPx() - val topHeight = splitOffset.toFloat() - val bottomHeight = messageSize.height - topHeight - gap - val hasBottom = bottomHeight > 0 - - val currentGap = if (hasBottom) 0f else gap - - // Top rect (Media) - addRoundRect( - RoundRect( - rect = Rect( - offset = messageOffset - containerOffset, - size = Size(messageSize.width.toFloat(), topHeight) - ), - topLeft = CornerRadius(if (!isMessageOutgoing && isSameSenderAbove) s else r), - topRight = CornerRadius(if (isMessageOutgoing && isSameSenderAbove) s else r), - bottomRight = if (hasBottom) CornerRadius.Zero else CornerRadius(if (isMessageOutgoing) s else r), - bottomLeft = if (hasBottom) CornerRadius.Zero else CornerRadius(if (!isMessageOutgoing) s else r) - ) - ) - - // Bottom rect (Text) - if (hasBottom) { - addRoundRect( - RoundRect( - rect = Rect( - offset = messageOffset - containerOffset + Offset( - 0f, - topHeight + currentGap - ), - size = Size(messageSize.width.toFloat(), bottomHeight) - ), - topLeft = CornerRadius.Zero, - topRight = CornerRadius.Zero, - bottomRight = CornerRadius(if (isMessageOutgoing) (if (isSameSenderBelow) s else t) else r), - bottomLeft = CornerRadius(if (!isMessageOutgoing) (if (isSameSenderBelow) s else t) else r) - ) - ) - } - } else { - addRoundRect( - RoundRect( - rect = Rect( - offset = messageOffset - containerOffset, - size = Size(messageSize.width.toFloat(), messageSize.height.toFloat()) - ), - topLeft = CornerRadius(if (!isMessageOutgoing && isSameSenderAbove) s else r), - topRight = CornerRadius(if (isMessageOutgoing && isSameSenderAbove) s else r), - bottomRight = CornerRadius(if (isMessageOutgoing) (if (isSameSenderBelow) s else t) else r), - bottomLeft = CornerRadius(if (!isMessageOutgoing) (if (isSameSenderBelow) s else t) else r) - ) - ) - } - } - drawPath(path, Color.Black, blendMode = BlendMode.DstOut) - } - } - drawContent() - } - ) { - Surface( - modifier = Modifier - .align(Alignment.TopStart) - .offset { menuPosition } - .width(IntrinsicSize.Min) - .widthIn(min = 208.dp, max = 276.dp) - .heightIn(max = maxMenuHeight) - .graphicsLayer { - this.alpha = if (menuSize == IntSize.Zero || containerSize == IntSize.Zero) 0f else menuAlpha - scaleX = menuScale - scaleY = menuScale - this.transformOrigin = transformOrigin - shadowElevation = 16.dp.toPx() - shape = RoundedCornerShape(16.dp) - clip = true - } - .onGloballyPositioned { coordinates -> - if (menuSize != coordinates.size) { - menuSize = coordinates.size - } - } - .clickable(enabled = false) {}, - color = MaterialTheme.colorScheme.surfaceContainerHighest, - tonalElevation = 6.dp, - shape = RoundedCornerShape(16.dp) - ) { - AnimatedContent( - targetState = menuPage, - transitionSpec = { - val forwardDuration = 185 - val backDuration = 210 - val forward = targetState.ordinal > initialState.ordinal - if (forward) { - (slideIntoContainer( - towards = AnimatedContentTransitionScope.SlideDirection.Left, - animationSpec = tween(forwardDuration, easing = FastOutSlowInEasing) - ) + scaleIn( - initialScale = 0.985f, - animationSpec = tween(forwardDuration, easing = FastOutSlowInEasing) - )) - .togetherWith( - slideOutOfContainer( - towards = AnimatedContentTransitionScope.SlideDirection.Left, - animationSpec = tween(forwardDuration, easing = FastOutLinearInEasing) - ) + scaleOut( - targetScale = 0.99f, - animationSpec = tween(forwardDuration, easing = FastOutLinearInEasing) - ) - ) - } else { - (slideIntoContainer( - towards = AnimatedContentTransitionScope.SlideDirection.Right, - animationSpec = tween(backDuration, easing = FastOutSlowInEasing) - ) + scaleIn( - initialScale = 0.99f, - animationSpec = tween(backDuration, easing = FastOutSlowInEasing) - )) - .togetherWith( - slideOutOfContainer( - towards = AnimatedContentTransitionScope.SlideDirection.Right, - animationSpec = tween(backDuration, easing = FastOutLinearInEasing) - ) + scaleOut( - targetScale = 0.99f, - animationSpec = tween(backDuration, easing = FastOutLinearInEasing) - ) - ) - } - .using( - SizeTransform( - clip = true, - sizeAnimationSpec = { _, _ -> - tween( - durationMillis = if (forward) forwardDuration else backDuration, - easing = LinearOutSlowInEasing - ) - } - ) - ) - .apply { - targetContentZIndex = if (forward) 1f else 0f - } - }, - label = "MenuTransition" - ) { page -> - val lockedWidth = firstScreenWidth - val contentModifier = Modifier - .then( - if (lockedWidth != null) { - Modifier.width(with(density) { lockedWidth.toDp() }) - } else { - Modifier - } - ) - .onGloballyPositioned { coords -> - if (page == MenuPage.Main && (firstScreenWidth == null || firstScreenWidth != coords.size.width)) { - firstScreenWidth = coords.size.width - } - } - - Column( - modifier = contentModifier - .padding(vertical = 4.dp) - ) { - if (page == MenuPage.Main) { - ReactionsRow( - message = message, - availableReactions = availableReactions, - suppressAppearanceAnimation = suppressNextReactionsAppearanceAnimation, - onAppearanceAnimationConsumed = { - suppressNextReactionsAppearanceAnimation = false - }, - onReactionsChanged = { reactionCount -> - hasReactionsInMessage = reactionCount > 0 - }, - onReaction = { reaction -> - animateOutAndDismiss { onReaction(reaction) } - } - ) - - InternalMenuHeaderInfo( - message = message, - showReadInfo = showReadInfo, - showViewsInfo = showViewsInfo - ) - - if (sections.hasViewersSection) { - InternalMenuOptionItem( - icon = Icons.Rounded.Visibility, - text = "${viewers.size} ${stringResource(R.string.info_views)}", - trailingContent = { - if (isLoadingViewers) { - CircularProgressIndicator( - modifier = Modifier.size(16.dp), - strokeWidth = 2.dp - ) - } else { - Icon( - imageVector = Icons.Rounded.ChevronRight, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f), - modifier = Modifier.size(18.dp) - ) - } - }, - onClick = { - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - onReloadViewers() - menuPage = MenuPage.Viewers - } - ) - } - - if (sections.hasReplyAction) { - InternalMenuOptionItem( - icon = Icons.AutoMirrored.Rounded.Reply, - text = stringResource(R.string.menu_reply), - onClick = { animateOutAndDismiss(onReply) } - ) - } - - if (sections.hasPinAction) { - InternalMenuOptionItem( - icon = Icons.Rounded.PushPin, - text = if (isPinned) stringResource(R.string.menu_unpin) else stringResource(R.string.menu_pin), - onClick = { animateOutAndDismiss(onPin) } - ) - } - - if (sections.hasEditAction) { - InternalMenuOptionItem( - icon = Icons.Rounded.Edit, - text = stringResource(R.string.menu_edit), - onClick = { animateOutAndDismiss(onEdit) } - ) - } - - if (sections.hasCopyAction) { - InternalMenuOptionItem( - icon = Icons.Rounded.ContentCopy, - text = stringResource(R.string.menu_copy), - onClick = { animateOutAndDismiss(onCopy) } - ) - } - - if (sections.hasForwardAction) { - InternalMenuOptionItem( - icon = Icons.AutoMirrored.Rounded.Forward, - text = stringResource(R.string.menu_forward), - onClick = { animateOutAndDismiss(onForward) } - ) - } - - InternalMenuOptionItem( - icon = Icons.Rounded.CheckCircle, - text = stringResource(R.string.menu_select), - onClick = { animateOutAndDismiss(onSelect) } - ) - - if (sections.hasCocoonSection) { - InternalMenuOptionItem( - icon = Icons.Rounded.AutoAwesome, - text = stringResource(R.string.menu_cocoon), - trailingIcon = Icons.Rounded.ChevronRight, - onClick = { - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - menuPage = MenuPage.Cocoon - } - ) - } - - if (sections.hasMoreSection) { - InternalMenuOptionItem( - icon = Icons.Rounded.MoreHoriz, - text = stringResource(R.string.menu_more), - trailingIcon = Icons.Rounded.ChevronRight, - onClick = { - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - menuPage = MenuPage.More - } - ) - } - - if (sections.hasDeleteAction) { - HorizontalDivider( - modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp), - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - InternalMenuOptionItem( - icon = Icons.Rounded.Delete, - text = stringResource(R.string.menu_delete), - textColor = MaterialTheme.colorScheme.error, - iconTint = MaterialTheme.colorScheme.error, - onClick = { showDeleteSheet = true } - ) - } - } else if (page == MenuPage.More) { - InternalMenuOptionItem( - icon = Icons.AutoMirrored.Rounded.ArrowBack, - text = stringResource(R.string.cd_back), - iconTint = MaterialTheme.colorScheme.primary, - textColor = MaterialTheme.colorScheme.primary, - onClick = { - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - if (hasReactionsInMessage) { - suppressNextReactionsAppearanceAnimation = true - } - menuPage = MenuPage.Main - } - ) - - HorizontalDivider( - modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp), - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - - if (sections.hasCommentsAction) { - InternalMenuOptionItem( - icon = Icons.AutoMirrored.Rounded.Chat, - text = stringResource(R.string.menu_view_comments), - onClick = { animateOutAndDismiss(onComments) } - ) - } - - if (sections.hasCopyLinkAction) { - InternalMenuOptionItem( - icon = Icons.Rounded.Link, - text = stringResource(R.string.menu_copy_link), - onClick = { animateOutAndDismiss(onCopyLink) } - ) - } - - if (sections.hasDownloadAction) { - InternalMenuOptionItem( - icon = Icons.Rounded.Download, - text = stringResource(R.string.menu_save_to_downloads), - onClick = { animateOutAndDismiss(onSaveToDownloads) } - ) - } - - if (sections.hasReportAction) { - InternalMenuOptionItem( - icon = Icons.Rounded.Report, - text = stringResource(R.string.menu_report), - onClick = { animateOutAndDismiss(onReport) } - ) - } - - if (sections.hasBlockAction) { - InternalMenuOptionItem( - icon = Icons.Rounded.Block, - text = stringResource(R.string.menu_block_user), - textColor = MaterialTheme.colorScheme.error, - iconTint = MaterialTheme.colorScheme.error, - onClick = { animateOutAndDismiss(onBlock) } - ) - if (sections.hasRestrictAction) { - InternalMenuOptionItem( - icon = Icons.Rounded.Gavel, - text = stringResource(R.string.menu_restrict_user), - textColor = MaterialTheme.colorScheme.error, - iconTint = MaterialTheme.colorScheme.error, - onClick = { animateOutAndDismiss(onRestrict) } - ) - } - } - } else if (page == MenuPage.Cocoon) { - InternalMenuOptionItem( - icon = Icons.AutoMirrored.Rounded.ArrowBack, - text = stringResource(R.string.cd_back), - iconTint = MaterialTheme.colorScheme.primary, - textColor = MaterialTheme.colorScheme.primary, - onClick = { - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - if (hasReactionsInMessage) { - suppressNextReactionsAppearanceAnimation = true - } - menuPage = MenuPage.Main - } - ) - - HorizontalDivider( - modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp), - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - - if (sections.hasTelegramSummaryAction) { - InternalMenuOptionItem( - icon = Icons.Rounded.AutoAwesome, - text = stringResource(R.string.menu_telegram_summary), - onClick = { animateOutAndDismiss(onTelegramSummary) } - ) - } - - if (sections.hasTelegramTranslatorAction) { - InternalMenuOptionItem( - icon = Icons.Rounded.Translate, - text = stringResource(R.string.menu_telegram_translate), - onClick = { animateOutAndDismiss(onTelegramTranslator) } - ) - } - - if (sections.hasRestoreOriginalTextAction) { - InternalMenuOptionItem( - icon = Icons.Rounded.Undo, - text = stringResource(R.string.menu_restore_original_text), - onClick = { animateOutAndDismiss(onRestoreOriginalText) } - ) - } - } else { - InternalMenuOptionItem( - icon = Icons.AutoMirrored.Rounded.ArrowBack, - text = stringResource(R.string.viewer_back), - iconTint = MaterialTheme.colorScheme.primary, - textColor = MaterialTheme.colorScheme.primary, - onClick = { - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - if (hasReactionsInMessage) { - suppressNextReactionsAppearanceAnimation = true - } - menuPage = MenuPage.Main - } - ) - - HorizontalDivider( - modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp), - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - - when { - isLoadingViewers -> { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 24.dp), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator() - } - } - - viewers.isEmpty() -> { - Text( - text = stringResource(R.string.info_views), - modifier = Modifier.padding(horizontal = 16.dp, vertical = 16.dp), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - - else -> { - val viewerDateFormat = - remember { SimpleDateFormat("MMM d, HH:mm", Locale.getDefault()) } - val scrollState = rememberScrollState() - Column( - modifier = Modifier - .fillMaxWidth() - .heightIn(max = 260.dp) - .verticalScroll(scrollState) - ) { - viewers.forEach { viewer -> - ViewerRow( - viewer = viewer, - dateFormat = viewerDateFormat, - videoPlayerPool = videoPlayerPool, - onClick = { - animateOutAndDismiss { - onViewerClick(viewer.user.id) - } - } - ) - } - } - } - } - } - } - } - } - } -} - -private data class MessageMenuSections( - val hasViewersSection: Boolean, - val hasReplyAction: Boolean, - val hasPinAction: Boolean, - val hasEditAction: Boolean, - val hasCopyAction: Boolean, - val hasForwardAction: Boolean, - val hasCocoonSection: Boolean, - val hasMoreSection: Boolean, - val hasDeleteAction: Boolean, - val hasCommentsAction: Boolean, - val hasCopyLinkAction: Boolean, - val hasDownloadAction: Boolean, - val hasReportAction: Boolean, - val hasBlockAction: Boolean, - val hasRestrictAction: Boolean, - val hasTelegramSummaryAction: Boolean, - val hasTelegramTranslatorAction: Boolean, - val hasRestoreOriginalTextAction: Boolean -) { - fun merge(other: MessageMenuSections): MessageMenuSections { - return MessageMenuSections( - hasViewersSection = hasViewersSection || other.hasViewersSection, - hasReplyAction = hasReplyAction || other.hasReplyAction, - hasPinAction = hasPinAction || other.hasPinAction, - hasEditAction = hasEditAction || other.hasEditAction, - hasCopyAction = hasCopyAction || other.hasCopyAction, - hasForwardAction = hasForwardAction || other.hasForwardAction, - hasCocoonSection = hasCocoonSection || other.hasCocoonSection, - hasMoreSection = hasMoreSection || other.hasMoreSection, - hasDeleteAction = hasDeleteAction || other.hasDeleteAction, - hasCommentsAction = hasCommentsAction || other.hasCommentsAction, - hasCopyLinkAction = hasCopyLinkAction || other.hasCopyLinkAction, - hasDownloadAction = hasDownloadAction || other.hasDownloadAction, - hasReportAction = hasReportAction || other.hasReportAction, - hasBlockAction = hasBlockAction || other.hasBlockAction, - hasRestrictAction = hasRestrictAction || other.hasRestrictAction, - hasTelegramSummaryAction = hasTelegramSummaryAction || other.hasTelegramSummaryAction, - hasTelegramTranslatorAction = hasTelegramTranslatorAction || other.hasTelegramTranslatorAction, - hasRestoreOriginalTextAction = hasRestoreOriginalTextAction || other.hasRestoreOriginalTextAction - ) - } - - companion object { - val Saver = listSaver( - save = { - listOf( - it.hasViewersSection, - it.hasReplyAction, - it.hasPinAction, - it.hasEditAction, - it.hasCopyAction, - it.hasForwardAction, - it.hasCocoonSection, - it.hasMoreSection, - it.hasDeleteAction, - it.hasCommentsAction, - it.hasCopyLinkAction, - it.hasDownloadAction, - it.hasReportAction, - it.hasBlockAction, - it.hasRestrictAction, - it.hasTelegramSummaryAction, - it.hasTelegramTranslatorAction, - it.hasRestoreOriginalTextAction - ) - }, - restore = { values -> - MessageMenuSections( - hasViewersSection = values[0], - hasReplyAction = values[1], - hasPinAction = values[2], - hasEditAction = values[3], - hasCopyAction = values[4], - hasForwardAction = values[5], - hasCocoonSection = values[6], - hasMoreSection = values[7], - hasDeleteAction = values[8], - hasCommentsAction = values[9], - hasCopyLinkAction = values[10], - hasDownloadAction = values[11], - hasReportAction = values[12], - hasBlockAction = values[13], - hasRestrictAction = values[14], - hasTelegramSummaryAction = values[15], - hasTelegramTranslatorAction = values[16], - hasRestoreOriginalTextAction = values[17] - ) - } - ) - } -} - -private fun buildMenuSections( - message: MessageModel, - canWrite: Boolean, - canPinMessages: Boolean, - showViewersList: Boolean, - canCopyLink: Boolean, - canReport: Boolean, - canBlock: Boolean, - canRestrict: Boolean, - showTelegramSummary: Boolean, - showTelegramTranslator: Boolean, - showRestoreOriginalText: Boolean -): MessageMenuSections { - val hasCocoonActions = showTelegramSummary || showTelegramTranslator || showRestoreOriginalText - val hasMoreActions = message.canGetMessageThread || - canCopyLink || - shouldShowDownload(message) || - canReport || - canBlock - return MessageMenuSections( - hasViewersSection = showViewersList, - hasReplyAction = canWrite, - hasPinAction = canPinMessages, - hasEditAction = message.canBeEdited, - hasCopyAction = shouldShowCopy(message), - hasForwardAction = message.canBeForwarded, - hasCocoonSection = hasCocoonActions, - hasMoreSection = hasMoreActions, - hasDeleteAction = message.canBeDeletedOnlyForSelf || message.canBeDeletedForAllUsers, - hasCommentsAction = message.canGetMessageThread, - hasCopyLinkAction = canCopyLink, - hasDownloadAction = shouldShowDownload(message), - hasReportAction = canReport, - hasBlockAction = canBlock, - hasRestrictAction = canBlock && canRestrict, - hasTelegramSummaryAction = showTelegramSummary, - hasTelegramTranslatorAction = showTelegramTranslator, - hasRestoreOriginalTextAction = showRestoreOriginalText - ) -} - -private enum class MenuPage { - Main, - More, - Cocoon, - Viewers -} - -@Composable -private fun ReactionsRow( - message: MessageModel, - availableReactions: List, - suppressAppearanceAnimation: Boolean, - onAppearanceAnimationConsumed: () -> Unit, - onReactionsChanged: (Int) -> Unit, - onReaction: (String) -> Unit, - appPreferences: AppPreferences = koinInject() -) { - val haptic = LocalHapticFeedback.current - - val context = LocalContext.current - val emojiStyle by appPreferences.emojiStyle.collectAsState() - val emojiFontFamily = remember(context, emojiStyle) { getEmojiFontFamily(context, emojiStyle) } - - val reactions = remember(availableReactions) { - if (availableReactions.isNotEmpty()) { - availableReactions.map { RecentEmojiModel(it) } - } else { - emptyList() - } - } - - LaunchedEffect(reactions.size) { - onReactionsChanged(reactions.size) - } - - LaunchedEffect(suppressAppearanceAnimation, reactions.isNotEmpty()) { - if (suppressAppearanceAnimation && reactions.isNotEmpty()) { - onAppearanceAnimationConsumed() - } - } - - AnimatedVisibility( - visible = reactions.isNotEmpty(), - enter = if (suppressAppearanceAnimation) { - EnterTransition.None - } else { - fadeIn(animationSpec = tween(150, easing = LinearOutSlowInEasing)) - }, - exit = fadeOut(animationSpec = tween(100, easing = FastOutLinearInEasing)), - label = "ReactionsRowVisibility" - ) { - Column { - Row( - modifier = Modifier - .horizontalScroll(rememberScrollState()) - .padding(vertical = 4.dp) - .padding(horizontal = 12.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - reactions.forEach { reaction -> - val isChosen = message.reactions.any { it.isChosen && it.emoji == reaction.emoji } - - val backgroundColor by animateColorAsState( - targetValue = if (isChosen) MaterialTheme.colorScheme.primaryContainer - else MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f), - animationSpec = spring(stiffness = Spring.StiffnessLow), - label = "reactionBg" - ) - - val scale by animateFloatAsState( - targetValue = if (isChosen) 1.06f else 1f, - animationSpec = tween(durationMillis = 160, easing = LinearOutSlowInEasing), - label = "reactionScale" - ) - - Box( - modifier = Modifier - .size(42.dp) - .graphicsLayer { - scaleX = scale - scaleY = scale - } - .clip(CircleShape) - .background(backgroundColor) - .clickable { - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - onReaction(reaction.emoji) - }, - contentAlignment = Alignment.Center - ) { - val sticker = reaction.sticker - if (sticker != null) { - StickerImage( - path = sticker.path, - modifier = Modifier.size(28.dp), - ) - } else { - Text( - text = reaction.emoji, - fontSize = 24.sp, - fontFamily = emojiFontFamily - ) - } - } - } - } - - HorizontalDivider( - modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp), - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - } - } -} - -@Composable -private fun ViewerRow( - viewer: MessageViewerModel, - dateFormat: SimpleDateFormat, - videoPlayerPool: VideoPlayerPool, - onClick: () -> Unit -) { - val fullName = remember(viewer.user.firstName, viewer.user.lastName) { - listOfNotNull(viewer.user.firstName, viewer.user.lastName) - .joinToString(" ") - .ifBlank { "Unknown" } - } - val subtitle = remember(viewer.viewedDate) { - if (viewer.viewedDate > 0) { - dateFormat.format(Date(viewer.viewedDate.toLong() * 1000)) - } else { - "" - } - } - Row( - modifier = Modifier - .fillMaxWidth() - .clickable(onClick = onClick) - .padding(horizontal = 16.dp, vertical = 10.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Avatar( - path = viewer.user.avatarPath, - fallbackPath = viewer.user.personalAvatarPath, - name = fullName, - size = 32.dp, - videoPlayerPool = videoPlayerPool, - fontSize = 12, - onClick = onClick - ) - - Spacer(modifier = Modifier.width(12.dp)) - - Column(modifier = Modifier.weight(1f)) { - Text( - text = fullName, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurface - ) - if (subtitle.isNotEmpty()) { - Text( - text = subtitle, - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } -} - -@Composable -private fun InternalMenuHeaderInfo( - message: MessageModel, - showReadInfo: Boolean, - showViewsInfo: Boolean -) { - val dateFormat = remember { SimpleDateFormat("MMM d, HH:mm", Locale.getDefault()) } - - val editDate = if (message.editDate > 0) dateFormat.format(Date(message.editDate.toLong() * 1000)) else null - val readDate = if (showReadInfo) - if (message.isOutgoing && message.readDate > 0) dateFormat.format(Date(message.readDate.toLong() * 1000)) else null - else null - val viewsCount = message.viewCount ?: message.views - val views = if (showViewsInfo && viewsCount != null && viewsCount > 0) viewsCount.toString() else null - - val hasHeader = editDate != null || readDate != null || views != null - - if (hasHeader) { - Column { - if (editDate != null) { - InternalMenuInfoRow( - icon = Icons.Rounded.Edit, - label = stringResource(R.string.info_edited), - value = editDate - ) - } - - if (readDate != null) { - InternalMenuInfoRow( - icon = Icons.Rounded.DoneAll, - label = stringResource(R.string.info_read), - value = readDate, - iconTint = MaterialTheme.colorScheme.primary - ) - } - - if (views != null) { - InternalMenuInfoRow( - icon = Icons.Rounded.Visibility, - label = stringResource(R.string.info_views), - value = views - ) - } - - HorizontalDivider( - modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp), - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - } - } -} - -@Composable -private fun InternalMenuInfoRow( - icon: ImageVector, - label: String, - value: String, - iconTint: Color = MaterialTheme.colorScheme.onSurfaceVariant -) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 4.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Icon( - imageVector = icon, - contentDescription = null, - modifier = Modifier.size(16.dp), - tint = iconTint - ) - Spacer(modifier = Modifier.width(16.dp)) - - Column(modifier = Modifier.weight(1f)) { - Text( - text = label, - style = MaterialTheme.typography.labelSmall.copy(fontSize = 10.sp), - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Text( - text = value, - style = MaterialTheme.typography.labelMedium.copy(fontSize = 11.sp), - fontWeight = FontWeight.SemiBold, - color = MaterialTheme.colorScheme.onSurface, - maxLines = 1 - ) - } - } -} - -@Composable -private fun InternalMenuOptionItem( - icon: ImageVector, - text: String, - onClick: () -> Unit, - textColor: Color = MaterialTheme.colorScheme.onSurface, - iconTint: Color = MaterialTheme.colorScheme.onSurface, - trailingIcon: ImageVector? = null, - trailingContent: (@Composable () -> Unit)? = null -) { - Row( - modifier = Modifier - .fillMaxWidth() - .clickable(onClick = onClick) - .padding(horizontal = 16.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Icon( - imageVector = icon, - contentDescription = null, - tint = iconTint, - modifier = Modifier.size(22.dp) - ) - Spacer(modifier = Modifier.width(16.dp)) - Text( - text = text, - style = MaterialTheme.typography.bodyMedium, - color = textColor, - modifier = Modifier.weight(1f) - ) - if (trailingContent != null) { - trailingContent() - } else if (trailingIcon != null) { - Icon( - imageVector = trailingIcon, - contentDescription = null, - tint = iconTint.copy(alpha = 0.5f), - modifier = Modifier.size(18.dp) - ) - } - } -} - -private fun shouldShowCopy(message: MessageModel): Boolean { - return when (val content = message.content) { - is MessageContent.Text -> content.text.isNotEmpty() - is MessageContent.Photo -> content.caption.isNotEmpty() - is MessageContent.Video -> content.caption.isNotEmpty() - is MessageContent.Gif -> content.caption.isNotEmpty() - else -> false - } -} - -private fun shouldShowDownload(message: MessageModel): Boolean { - if (!message.canBeSaved) return false - return when (val content = message.content) { - is MessageContent.Photo -> content.path != null - is MessageContent.Video -> content.path != null - is MessageContent.Gif -> content.path != null - is MessageContent.Document -> content.path != null - is MessageContent.Voice -> content.path != null - is MessageContent.VideoNote -> content.path != null - else -> false - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/StickerEmojiMenu.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/StickerEmojiMenu.kt deleted file mode 100644 index 35c315db..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/StickerEmojiMenu.kt +++ /dev/null @@ -1,114 +0,0 @@ -package org.monogram.presentation.features.stickers.ui.menu - -import androidx.compose.animation.* -import androidx.compose.animation.core.tween -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.outlined.StickyNote2 -import androidx.compose.material.icons.outlined.EmojiEmotions -import androidx.compose.material.icons.outlined.Gif -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.GifModel -import org.monogram.domain.models.StickerModel -import org.monogram.domain.repository.StickerRepository -import org.monogram.presentation.R -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun StickerEmojiMenu( - onStickerSelected: (String) -> Unit, - onEmojiSelected: (String, StickerModel?) -> Unit, - onGifSelected: (GifModel) -> Unit, - panelHeight: Dp = 400.dp, - emojiOnlyMode: Boolean = false, - onSearchFocused: (Boolean) -> Unit = {}, - videoPlayerPool: VideoPlayerPool, - stickerRepository: StickerRepository -) { - var selectedTab by remember(emojiOnlyMode) { mutableIntStateOf(if (emojiOnlyMode) 1 else 0) } - var isSearchMode by remember { mutableStateOf(false) } - val tabs = if (emojiOnlyMode) { - listOf(Triple(stringResource(R.string.sticker_menu_tab_emojis), Icons.Outlined.EmojiEmotions, 1)) - } else { - listOf( - Triple(stringResource(R.string.sticker_menu_tab_stickers), Icons.AutoMirrored.Outlined.StickyNote2, 0), - Triple(stringResource(R.string.sticker_menu_tab_emojis), Icons.Outlined.EmojiEmotions, 1), - Triple(stringResource(R.string.sticker_menu_tab_gifs), Icons.Outlined.Gif, 2) - ) - } - - Surface( - modifier = if (isSearchMode) { - Modifier - .fillMaxSize() - .statusBarsPadding() - } else { - Modifier - .fillMaxWidth() - .height(panelHeight) - .clip(RoundedCornerShape(topStart = 28.dp, topEnd = 28.dp)) - }, - color = MaterialTheme.colorScheme.surfaceContainerLow, - tonalElevation = 2.dp - ) { - Box(modifier = Modifier.fillMaxSize()) { - Box(modifier = Modifier.fillMaxSize()) { - when (selectedTab) { - 0 -> StickersView( - onStickerSelected = onStickerSelected, - onSearchFocused = { focused -> - isSearchMode = focused - onSearchFocused(focused) - }, - contentPadding = PaddingValues(bottom = 76.dp) - ) - - 1 -> EmojisGrid( - onEmojiSelected = onEmojiSelected, - emojiOnlyMode = emojiOnlyMode, - onSearchFocused = { focused -> - isSearchMode = focused - onSearchFocused(focused) - }, - contentPadding = PaddingValues(bottom = 76.dp) - ) - - 2 -> GifsView( - onGifSelected = onGifSelected, - onSearchFocused = { focused -> - isSearchMode = focused - onSearchFocused(focused) - }, - contentPadding = PaddingValues(bottom = 76.dp), - videoPlayerPool = videoPlayerPool, - stickerRepository = stickerRepository - ) - } - } - - AnimatedVisibility( - visible = !isSearchMode && !emojiOnlyMode, - enter = fadeIn(animationSpec = tween(180)) + - slideInVertically(animationSpec = tween(220)) { it / 4 }, - exit = fadeOut(animationSpec = tween(130)) + - slideOutVertically(animationSpec = tween(180)) { it / 4 }, - modifier = Modifier - .align(Alignment.BottomCenter) - .padding(bottom = 16.dp) - ) { - FloatingTabs(tabs, selectedTab) { selectedTab = it } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/StickersGrid.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/StickersGrid.kt deleted file mode 100644 index 740c9e77..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/menu/StickersGrid.kt +++ /dev/null @@ -1,492 +0,0 @@ -package org.monogram.presentation.features.stickers.ui.menu - -import androidx.compose.animation.* -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.grid.* -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowBack -import androidx.compose.material.icons.automirrored.outlined.StickyNote2 -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.Search -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.focus.onFocusChanged -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import org.koin.compose.koinInject -import org.monogram.domain.models.StickerModel -import org.monogram.domain.models.StickerSetModel -import org.monogram.domain.repository.StickerRepository -import org.monogram.presentation.R -import org.monogram.presentation.features.chats.currentChat.components.StickerSetSheet -import org.monogram.presentation.features.stickers.ui.view.LocalIsScrolling -import org.monogram.presentation.features.stickers.ui.view.StickerItem -import org.monogram.presentation.features.stickers.ui.view.StickerSkeleton -import org.monogram.presentation.features.stickers.ui.view.shimmerEffect - -@Composable -fun StickersView( - onStickerSelected: (String) -> Unit, - onSearchFocused: (Boolean) -> Unit = {}, - contentPadding: PaddingValues = PaddingValues(0.dp), - stickerRepository: StickerRepository = koinInject() -) { - val stickerSets by stickerRepository.installedStickerSets.collectAsState(initial = emptyList()) - var selectedSetId by remember { mutableLongStateOf(-1L) } // -1 for recent stickers - var recentStickers by remember { mutableStateOf>(emptyList()) } - var previewStickerSet by remember { mutableStateOf(null) } - var searchQuery by remember { mutableStateOf("") } - var debouncedSearchQuery by remember { mutableStateOf("") } - var isSearchFocused by remember { mutableStateOf(false) } - val scope = rememberCoroutineScope() - val gridState = rememberLazyGridState() - - var searchResultsStickers by remember { mutableStateOf>(emptyList()) } - var searchResultsSets by remember { mutableStateOf>(emptyList()) } - - LaunchedEffect(Unit) { - stickerRepository.loadInstalledStickerSets() - recentStickers = stickerRepository.getRecentStickers() - } - - LaunchedEffect(searchQuery) { - if (searchQuery.isBlank()) { - debouncedSearchQuery = "" - } else { - delay(300) - debouncedSearchQuery = searchQuery - } - } - - LaunchedEffect(debouncedSearchQuery) { - if (debouncedSearchQuery.length >= 2) { - searchResultsStickers = stickerRepository.searchStickers(debouncedSearchQuery) - searchResultsSets = stickerRepository.searchStickerSets(debouncedSearchQuery) - } else { - searchResultsStickers = emptyList() - searchResultsSets = emptyList() - } - } - - val firstVisibleItemIndex by remember { derivedStateOf { gridState.firstVisibleItemIndex } } - LaunchedEffect(firstVisibleItemIndex, stickerSets, recentStickers, searchQuery) { - if (searchQuery.isNotEmpty() || !gridState.isScrollInProgress) return@LaunchedEffect - - var currentCount = 0 - if (recentStickers.isNotEmpty()) { - if (firstVisibleItemIndex < recentStickers.size + 1) { - selectedSetId = -1L - return@LaunchedEffect - } - currentCount += recentStickers.size + 1 - } - - for (set in stickerSets) { - if (firstVisibleItemIndex >= currentCount && firstVisibleItemIndex < currentCount + set.stickers.size + 1) { - selectedSetId = set.id - break - } - currentCount += set.stickers.size + 1 - } - } - - Column(modifier = Modifier.fillMaxSize()) { - StickerSearchBar( - query = searchQuery, - onQueryChange = { searchQuery = it }, - onFocusChanged = { - isSearchFocused = it - onSearchFocused(it || searchQuery.isNotEmpty()) - }, - isSearchMode = isSearchFocused || searchQuery.isNotEmpty() - ) - - AnimatedVisibility( - visible = !isSearchFocused && searchQuery.isEmpty(), - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically() - ) { - StickerSetsRow( - stickerSets = stickerSets, - selectedSetId = selectedSetId, - hasRecent = recentStickers.isNotEmpty(), - onSetSelected = { id -> - selectedSetId = id - scope.launch { - var targetIndex = 0 - if (id == -1L) { - gridState.animateScrollToItem(0) - } else { - if (recentStickers.isNotEmpty()) targetIndex += recentStickers.size + 1 - for (set in stickerSets) { - if (set.id == id) { - gridState.animateScrollToItem(targetIndex) - break - } - targetIndex += set.stickers.size + 1 - } - } - } - } - ) - } - - if (!isSearchFocused && searchQuery.isEmpty()) { - HorizontalDivider( - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f), - thickness = 0.5.dp - ) - } - - Box(modifier = Modifier.fillMaxSize()) { - if (stickerSets.isEmpty() && recentStickers.isEmpty()) { - StickerGridSkeleton(contentPadding = contentPadding) - } else { - CompositionLocalProvider(LocalIsScrolling provides gridState.isScrollInProgress) { - LazyVerticalGrid( - columns = GridCells.Adaptive(minSize = 64.dp), - state = gridState, - contentPadding = PaddingValues( - start = 12.dp, - end = 12.dp, - top = 8.dp, - bottom = contentPadding.calculateBottomPadding() + 8.dp - ), - modifier = Modifier.fillMaxSize(), - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - if (searchQuery.isNotEmpty()) { - if (searchResultsStickers.isNotEmpty()) { - item(span = { GridItemSpan(maxLineSpan) }) { - PackHeader(stringResource(R.string.stickers_header_all)) - } - items(searchResultsStickers, key = { "search_sticker_${it.id}" }) { sticker -> - StickerGridItem(sticker, onStickerSelected, { - scope.launch { - val set = stickerRepository.getStickerSet(sticker.id) - previewStickerSet = set - } - }) - } - } - - searchResultsSets.forEach { set -> - item(key = "search_header_${set.id}", span = { GridItemSpan(maxLineSpan) }) { - PackHeader(set.title, onClick = { previewStickerSet = set }) - } - items(set.stickers, key = { "search_set_${set.id}_${it.id}" }) { sticker -> - StickerGridItem(sticker, onStickerSelected, { - scope.launch { - previewStickerSet = set - } - }) - } - } - - if (searchResultsStickers.isEmpty() && searchResultsSets.isEmpty() && debouncedSearchQuery.isNotEmpty()) { - val filtered = stickerSets.flatMap { it.stickers }.filter { - it.emoji.contains(debouncedSearchQuery) || it.id.toString() - .contains(debouncedSearchQuery) - }.distinctBy { it.id } - - items(filtered, key = { "search_local_${it.id}" }) { sticker -> - StickerGridItem(sticker, onStickerSelected, { - scope.launch { - val set = stickerRepository.getStickerSet(sticker.id) - previewStickerSet = set - } - }) - } - } - } else { - if (recentStickers.isNotEmpty()) { - item(span = { GridItemSpan(maxLineSpan) }) { - PackHeader(stringResource(R.string.stickers_header_recent)) - } - items(recentStickers, key = { "recent_${it.id}" }) { sticker -> - StickerGridItem(sticker, onStickerSelected, { - scope.launch { - val set = stickerRepository.getStickerSet(sticker.id) - previewStickerSet = set - } - }) - } - } - - stickerSets.forEach { set -> - item(key = "header_${set.id}", span = { GridItemSpan(maxLineSpan) }) { - PackHeader(set.title, onClick = { previewStickerSet = set }) - } - items(set.stickers, key = { "set_${set.id}_${it.id}" }) { sticker -> - StickerGridItem(sticker, onStickerSelected, { - scope.launch { - val s = stickerRepository.getStickerSet(sticker.id) - previewStickerSet = s - } - }) - } - } - } - } - } - } - } - } - - previewStickerSet?.let { set -> - StickerSetSheet( - stickerSet = set, - onDismiss = { previewStickerSet = null }, - onStickerClick = { path -> - onStickerSelected(path) - previewStickerSet = null - } - ) - } -} - -@Composable -fun PackHeader( - title: String, - onClick: (() -> Unit)? = null -) { - Text( - text = title, - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.SemiBold, - modifier = Modifier - .fillMaxWidth() - .then( - if (onClick != null) { - Modifier.clickable(onClick = onClick) - } else Modifier - ) - .padding(horizontal = 4.dp, vertical = 8.dp) - ) -} - -@Composable -fun StickerGridItem( - sticker: StickerModel, - onStickerSelected: (String) -> Unit, - onStickerLongClick: (StickerModel) -> Unit -) { - Box( - modifier = Modifier - .aspectRatio(1f) - .background( - color = MaterialTheme.colorScheme.surfaceContainerLow.copy(alpha = 0.5f), - shape = RoundedCornerShape(12.dp) - ), - contentAlignment = Alignment.Center - ) { - StickerItem( - sticker = sticker, - modifier = Modifier - .fillMaxSize() - .padding(8.dp), - onClick = { path -> onStickerSelected(path) }, - onLongClick = onStickerLongClick - ) - } -} - -@Composable -fun StickerSearchBar( - query: String, - onQueryChange: (String) -> Unit, - onFocusChanged: (Boolean) -> Unit, - isSearchMode: Boolean = false -) { - val focusManager = LocalFocusManager.current - - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp, vertical = 6.dp), - verticalAlignment = Alignment.CenterVertically - ) { - if (isSearchMode) { - IconButton( - onClick = { - onQueryChange("") - focusManager.clearFocus() - }, - modifier = Modifier.size(40.dp) - ) { - Icon( - imageVector = Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = stringResource(R.string.common_back), - tint = MaterialTheme.colorScheme.onSurface, - modifier = Modifier.size(20.dp) - ) - } - Spacer(modifier = Modifier.width(4.dp)) - } - - TextField( - value = query, - onValueChange = onQueryChange, - modifier = Modifier - .weight(1f) - .height(48.dp) - .onFocusChanged { onFocusChanged(it.isFocused) }, - placeholder = { Text(stringResource(R.string.stickers_search_placeholder), style = MaterialTheme.typography.bodyMedium) }, - leadingIcon = if (!isSearchMode) { - { - Icon(Icons.Default.Search, contentDescription = null, modifier = Modifier.size(20.dp)) - } - } else null, - trailingIcon = if (query.isNotEmpty()) { - { - IconButton(onClick = { - onQueryChange("") - }) { - Icon(Icons.Default.Close, contentDescription = stringResource(R.string.common_clear), modifier = Modifier.size(20.dp)) - } - } - } else null, - singleLine = true, - shape = RoundedCornerShape(24.dp), - colors = TextFieldDefaults.colors( - focusedIndicatorColor = Color.Transparent, - unfocusedIndicatorColor = Color.Transparent, - disabledIndicatorColor = Color.Transparent, - focusedContainerColor = MaterialTheme.colorScheme.surfaceContainerHigh, - unfocusedContainerColor = MaterialTheme.colorScheme.surfaceContainerHigh - ), - textStyle = MaterialTheme.typography.bodyMedium - ) - } -} - -@Composable -private fun StickerSetsSkeleton() { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 8.dp) - .padding(horizontal = 16.dp), - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - repeat(6) { - Box( - modifier = Modifier - .size(44.dp) - .clip(CircleShape) - .shimmerEffect() - ) - } - } -} - -@Composable -private fun StickerGridSkeleton( - contentPadding: PaddingValues -) { - LazyVerticalGrid( - columns = GridCells.Fixed(5), - contentPadding = PaddingValues( - start = 8.dp, - end = 8.dp, - top = 8.dp, - bottom = contentPadding.calculateBottomPadding() + 8.dp - ), - modifier = Modifier.fillMaxSize(), - userScrollEnabled = false - ) { - items(20) { - StickerSkeleton(modifier = Modifier.fillMaxSize()) - } - } -} - -@Composable -fun StickerSetsRow( - stickerSets: List, - selectedSetId: Long, - hasRecent: Boolean, - onSetSelected: (Long) -> Unit -) { - val listState = rememberLazyListState() - - LaunchedEffect(selectedSetId) { - val index = - if (selectedSetId == -1L) 0 else stickerSets.indexOfFirst { it.id == selectedSetId } + (if (hasRecent) 1 else 0) - if (index >= 0) { - listState.animateScrollToItem(index) - } - } - - LazyRow( - state = listState, - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 4.dp), - contentPadding = PaddingValues(horizontal = 16.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalAlignment = Alignment.CenterVertically - ) { - if (hasRecent) { - item { - SetItem( - isSelected = selectedSetId == -1L, - onClick = { onSetSelected(-1L) }, - icon = { - Icon( - imageVector = Icons.AutoMirrored.Outlined.StickyNote2, - contentDescription = stringResource(R.string.common_recent), - tint = if (selectedSetId == -1L) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.size(20.dp) - ) - } - ) - } - } - - items( - items = stickerSets, - key = { it.id } - ) { set -> - SetItem( - isSelected = selectedSetId == set.id, - onClick = { onSetSelected(set.id) }, - content = { - val firstSticker = set.stickers.firstOrNull() - if (firstSticker != null) { - StickerItem( - sticker = firstSticker, - modifier = Modifier.fillMaxSize(), - animate = false, - onClick = null - ) - } else { - Text( - set.title.take(1), - style = MaterialTheme.typography.labelLarge, - fontWeight = FontWeight.Bold, - color = if (selectedSetId == set.id) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/view/StickerImage.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/view/StickerImage.kt deleted file mode 100644 index 3c3d17a6..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/view/StickerImage.kt +++ /dev/null @@ -1,44 +0,0 @@ -package org.monogram.presentation.features.stickers.ui.view - -import androidx.compose.foundation.layout.Box -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import coil3.compose.SubcomposeAsyncImage -import coil3.request.ImageRequest -import coil3.request.crossfade - -@Composable -fun StickerImage( - modifier: Modifier = Modifier, - path: String?, - animate: Boolean = true, -) { - if (path == null) return - - val isAnimated = path.endsWith(".webm", ignoreCase = true) || - path.endsWith(".tgs", ignoreCase = true) || - path.endsWith(".json", ignoreCase = true) - - if (isAnimated) { - StickerPlayer( - path = path, - modifier = modifier, - ) - return - } - - SubcomposeAsyncImage( - model = ImageRequest.Builder(LocalContext.current) - .data(path) - .crossfade(true) - .build(), - contentDescription = null, - modifier = modifier, - contentScale = ContentScale.Fit, - loading = { - Box(modifier = Modifier.shimmerEffect()) - } - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/view/StickerItem.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/view/StickerItem.kt deleted file mode 100644 index 0c85d35c..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/view/StickerItem.kt +++ /dev/null @@ -1,64 +0,0 @@ -package org.monogram.presentation.features.stickers.ui.view - -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.Box -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import kotlinx.coroutines.flow.firstOrNull -import org.koin.compose.koinInject -import org.monogram.domain.models.StickerModel -import org.monogram.domain.repository.StickerRepository -import java.io.File - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun StickerItem( - sticker: StickerModel, - modifier: Modifier = Modifier, - animate: Boolean = true, - onClick: ((String) -> Unit)? = null, - onLongClick: ((StickerModel) -> Unit)? = null, - stickerRepository: StickerRepository = koinInject() -) { - val isScrolling = LocalIsScrolling.current - var currentPath by remember(sticker.id, sticker.path) { - mutableStateOf(sticker.path.takeIf(::isExistingPath)) - } - - LaunchedEffect(sticker.id, sticker.path, isScrolling) { - if (!sticker.path.isNullOrEmpty() && isExistingPath(sticker.path)) { - currentPath = sticker.path - return@LaunchedEffect - } - - if (!isScrolling && (currentPath == null || !isExistingPath(currentPath))) { - currentPath = null - currentPath = stickerRepository - .getStickerFile(sticker.id) - .firstOrNull() - ?.takeIf(::isExistingPath) - } - } - - Box( - modifier = if ((onClick != null || onLongClick != null) && currentPath != null) { - modifier.combinedClickable( - onClick = { onClick?.invoke(currentPath!!) }, - onLongClick = { onLongClick?.invoke(sticker) } - ) - } else { - modifier - }, - contentAlignment = Alignment.Center - ) { - StickerImage( - path = currentPath, - modifier = Modifier.matchParentSize(), - animate = animate - ) - } -} - -private fun isExistingPath(path: String?): Boolean = !path.isNullOrEmpty() && File(path).exists() diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/view/StickerPlayer.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/view/StickerPlayer.kt deleted file mode 100644 index 018bc8d5..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/view/StickerPlayer.kt +++ /dev/null @@ -1,146 +0,0 @@ -package org.monogram.presentation.features.stickers.ui.view - -import androidx.compose.animation.Crossfade -import androidx.compose.animation.core.tween -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.BoxWithConstraints -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawWithContent -import androidx.compose.ui.graphics.FilterQuality -import androidx.compose.ui.unit.Constraints -import androidx.compose.ui.unit.IntOffset -import androidx.compose.ui.unit.IntSize -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleEventObserver -import androidx.lifecycle.compose.LocalLifecycleOwner -import org.monogram.presentation.features.stickers.core.LottieStickerController -import org.monogram.presentation.features.stickers.core.StickerController -import org.monogram.presentation.features.stickers.core.StickerThumbnailCache -import org.monogram.presentation.features.stickers.core.VpxStickerController -import java.io.File - -@Suppress("COMPOSE_APPLIER_CALL_MISMATCH") // https://issuetracker.google.com/issues/432262806 lol -@Composable -fun StickerPlayer( - path: String, - modifier: Modifier = Modifier -) { - BoxWithConstraints(modifier = modifier) { - val widthPx = constraints.maxWidth - val heightPx = constraints.maxHeight - - val renderWidth = if (widthPx != Constraints.Infinity && widthPx > 0) widthPx else 512 - val renderHeight = if (heightPx != Constraints.Infinity && heightPx > 0) heightPx else 512 - - val scope = rememberCoroutineScope() - val thumbnailKey = remember(path) { - val file = File(path) - if (file.exists()) { - "${path}:${file.length()}:${file.lastModified()}" - } else { - path - } - } - val controller = remember(path) { - val ctrl: StickerController = if (path.endsWith(".webm", ignoreCase = true)) { - VpxStickerController(path, scope) - } else { - LottieStickerController(path, scope, renderWidth, renderHeight) - } - ctrl - } - - var cachedBitmap by remember(thumbnailKey) { - mutableStateOf(StickerThumbnailCache.get(thumbnailKey)) - } - - LaunchedEffect(thumbnailKey, controller) { - if (cachedBitmap == null) { - val firstFrame = controller.renderFirstFrame() - if (firstFrame != null) { - StickerThumbnailCache.put(thumbnailKey, firstFrame) - cachedBitmap = firstFrame - } - } - } - - DisposableEffect(controller) { - controller.start() - onDispose { - controller.release() - } - } - - val lifecycleOwner = LocalLifecycleOwner.current - val isScrolling = LocalIsScrolling.current - - DisposableEffect(controller, lifecycleOwner, isScrolling) { - val observer = LifecycleEventObserver { _, event -> - if (event == Lifecycle.Event.ON_RESUME) { - controller.setPaused(isScrolling) - } else if (event == Lifecycle.Event.ON_PAUSE) { - controller.setPaused(true) - } - } - - controller.setPaused(isScrolling || lifecycleOwner.lifecycle.currentState != Lifecycle.State.RESUMED) - - lifecycleOwner.lifecycle.addObserver(observer) - onDispose { - lifecycleOwner.lifecycle.removeObserver(observer) - } - } - - val isLoaded by remember { - derivedStateOf { controller.currentImageBitmap != null || cachedBitmap != null } - } - - Box(modifier = Modifier.fillMaxSize()) { - Crossfade( - targetState = isLoaded, - animationSpec = tween(200), - label = "StickerCrossfade" - ) { loaded -> - if (loaded) { - Spacer( - modifier = Modifier - .fillMaxSize() - .drawWithContent { - val bitmap = controller.currentImageBitmap ?: cachedBitmap - - if (bitmap != null) { - val srcW = bitmap.width.toFloat() - val srcH = bitmap.height.toFloat() - val dstW = size.width - val dstH = size.height - - val scale = minOf(dstW / srcW, dstH / srcH) - val drawW = srcW * scale - val drawH = srcH * scale - - val left = (dstW - drawW) / 2 - val top = (dstH - drawH) / 2 - - drawImage( - image = bitmap, - dstOffset = IntOffset(left.toInt(), top.toInt()), - dstSize = IntSize(drawW.toInt(), drawH.toInt()), - filterQuality = FilterQuality.Low - ) - } - } - ) - } else { - Box( - modifier = Modifier - .fillMaxSize() - .shimmerEffect() - ) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/view/StickerScrollState.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/view/StickerScrollState.kt deleted file mode 100644 index 9d1065bc..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/view/StickerScrollState.kt +++ /dev/null @@ -1,5 +0,0 @@ -package org.monogram.presentation.features.stickers.ui.view - -import androidx.compose.runtime.compositionLocalOf - -val LocalIsScrolling = compositionLocalOf { false } diff --git a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/view/StickerSkeleton.kt b/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/view/StickerSkeleton.kt deleted file mode 100644 index 3d18163a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/stickers/ui/view/StickerSkeleton.kt +++ /dev/null @@ -1,63 +0,0 @@ -package org.monogram.presentation.features.stickers.ui.view - -import androidx.compose.animation.core.animateFloat -import androidx.compose.animation.core.infiniteRepeatable -import androidx.compose.animation.core.rememberInfiniteTransition -import androidx.compose.animation.core.tween -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.aspectRatio -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.composed -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.unit.IntSize -import androidx.compose.ui.unit.dp - -fun Modifier.shimmerEffect(): Modifier = composed { - var size by remember { mutableStateOf(IntSize.Zero) } - val transition = rememberInfiniteTransition(label = "Shimmer") - val startOffsetX by transition.animateFloat( - initialValue = -2 * size.width.toFloat(), - targetValue = 2 * size.width.toFloat(), - animationSpec = infiniteRepeatable( - animation = tween(1000) - ), - label = "Shimmer" - ) - - val color = MaterialTheme.colorScheme.surfaceVariant - - background( - brush = Brush.linearGradient( - colors = listOf( - color.copy(alpha = 0.6f), - color.copy(alpha = 0.2f), - color.copy(alpha = 0.6f), - ), - start = Offset(startOffsetX, 0f), - end = Offset(startOffsetX + size.width.toFloat(), size.height.toFloat()) - ) - ) - .onGloballyPositioned { - it.size - } -} - -@Composable -fun StickerSkeleton( - modifier: Modifier = Modifier -) { - Box( - modifier = modifier - .padding(4.dp) - .aspectRatio(1f) - .clip(MaterialTheme.shapes.medium) - .shimmerEffect() - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/viewers/ImageViewer.kt b/presentation/src/main/java/org/monogram/presentation/features/viewers/ImageViewer.kt deleted file mode 100644 index 9e102cba..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/viewers/ImageViewer.kt +++ /dev/null @@ -1,40 +0,0 @@ -package org.monogram.presentation.features.viewers - -import androidx.compose.runtime.Composable -import org.monogram.presentation.core.util.IDownloadUtils - -@Composable -fun ImageViewer( - images: List, - startIndex: Int = 0, - onDismiss: () -> Unit, - autoDownload: Boolean = true, - onPageChanged: ((Int) -> Unit)? = null, - onForward: (String) -> Unit = {}, - onDelete: ((String) -> Unit)? = null, - onCopyLink: ((String) -> Unit)? = null, - onCopyText: ((String) -> Unit)? = null, - onVideoClick: ((String) -> Unit)? = null, - captions: List = emptyList(), - imageDownloadingStates: List = emptyList(), - imageDownloadProgressStates: List = emptyList(), - downloadUtils: IDownloadUtils, - showImageNumber: Boolean = true -) { - MediaViewer( - mediaItems = images, - startIndex = startIndex, - onDismiss = onDismiss, - autoDownload = autoDownload, - onPageChanged = onPageChanged, - onForward = onForward, - onDelete = onDelete, - onCopyLink = onCopyLink, - onCopyText = onCopyText, - captions = captions, - imageDownloadingStates = imageDownloadingStates, - imageDownloadProgressStates = imageDownloadProgressStates, - downloadUtils = downloadUtils, - showImageNumber = showImageNumber - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/viewers/MediaViewer.kt b/presentation/src/main/java/org/monogram/presentation/features/viewers/MediaViewer.kt deleted file mode 100644 index d85964d9..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/viewers/MediaViewer.kt +++ /dev/null @@ -1,224 +0,0 @@ -package org.monogram.presentation.features.viewers - -import android.util.Log -import androidx.activity.compose.BackHandler -import androidx.annotation.OptIn -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.spring -import androidx.compose.animation.core.tween -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.pager.HorizontalPager -import androidx.compose.foundation.pager.PageSize -import androidx.compose.foundation.pager.rememberPagerState -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.unit.dp -import androidx.media3.common.util.UnstableApi -import kotlinx.coroutines.launch -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.core.util.getMimeType -import org.monogram.presentation.features.viewers.components.* - -private const val TAG = "MediaViewer" - -@OptIn(ExperimentalFoundationApi::class, UnstableApi::class) -@Composable -fun MediaViewer( - mediaItems: List, - startIndex: Int = 0, - onDismiss: () -> Unit, - autoDownload: Boolean = true, - onPageChanged: ((Int) -> Unit)? = null, - onForward: (String) -> Unit = {}, - onDelete: ((String) -> Unit)? = null, - onCopyLink: ((String) -> Unit)? = null, - onCopyText: ((String) -> Unit)? = null, - onSaveGif: ((String) -> Unit)? = null, - captions: List = emptyList(), - fileIds: List = emptyList(), - imageDownloadingStates: List = emptyList(), - imageDownloadProgressStates: List = emptyList(), - supportsStreaming: Boolean = false, - downloadUtils: IDownloadUtils, - showImageNumber: Boolean = true, - isGesturesEnabled: Boolean = true, - isDoubleTapSeekEnabled: Boolean = true, - seekDuration: Int = 10, - isZoomEnabled: Boolean = true, - isAlwaysVideo: Boolean = false -) { - require(mediaItems.isNotEmpty()) { "mediaItems can't be empty" } - - val scope = rememberCoroutineScope() - val pagerState = rememberPagerState( - initialPage = startIndex, - pageCount = { mediaItems.size } - ) - - val rootState = rememberDismissRootState() - val zoomState = rememberZoomState() - - var showControls by remember { mutableStateOf(true) } - var showSettingsMenu by remember { mutableStateOf(false) } - var currentVideoInPipMode by remember { mutableStateOf(false) } - - val context = LocalContext.current - - val config = LocalConfiguration.current - val density = LocalDensity.current - val screenHeightPx = with(density) { config.screenHeightDp.dp.toPx() } - val dismissDistancePx = with(density) { 160.dp.toPx() } - val dismissVelocityThreshold = with(density) { 1000.dp.toPx() } - - LaunchedEffect(Unit) { - Log.d(TAG, "Opened with ${mediaItems.size} items, startIndex=$startIndex") - launch { - rootState.scale.animateTo(1f, spring(dampingRatio = 0.8f, stiffness = Spring.StiffnessMedium)) - } - launch { - rootState.backgroundAlpha.animateTo(1f, tween(150)) - } - } - - LaunchedEffect(pagerState.currentPage) { - Log.d(TAG, "Page changed to ${pagerState.currentPage}") - onPageChanged?.invoke(pagerState.currentPage) - zoomState.resetInstant(scope) - rootState.resetInstant(scope) - showSettingsMenu = false - currentVideoInPipMode = false - } - - BackHandler { - Log.d(TAG, "BackHandler: showSettingsMenu=$showSettingsMenu, currentVideoInPipMode=$currentVideoInPipMode") - if (showSettingsMenu) { - showSettingsMenu = false - } else { - if (currentVideoInPipMode) { - context.findActivity()?.finishAndRemoveTask() - } else { - onDismiss() - } - } - } - - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.Black.copy(alpha = rootState.backgroundAlpha.value)) - .graphicsLayer { - translationY = rootState.offsetY.value - scaleX = rootState.scale.value - scaleY = rootState.scale.value - } - ) { - HorizontalPager( - state = pagerState, - key = { page -> "media_page_${page}" }, - pageSize = PageSize.Fill, - pageSpacing = 0.dp, - beyondViewportPageCount = 0, - userScrollEnabled = zoomState.scale.value == 1f && rootState.offsetY.value == 0f - ) { page -> - val path = mediaItems.getOrNull(page) ?: return@HorizontalPager - val mimeType = getMimeType(path) - val isVideo = (isAlwaysVideo && path.isNotBlank()) || isVideoPath(path, mimeType) - - if (isVideo) { - VideoPage( - path = path, - fileId = fileIds.getOrNull(page) ?: 0, - caption = captions.getOrNull(page), - supportsStreaming = supportsStreaming, - downloadUtils = downloadUtils, - onDismiss = onDismiss, - showControls = showControls, - onToggleControls = { showControls = !showControls }, - onForward = onForward, - onDelete = onDelete, - onCopyLink = onCopyLink, - onCopyText = onCopyText, - onSaveGif = onSaveGif, - showSettingsMenu = showSettingsMenu, - onToggleSettings = { showSettingsMenu = !showSettingsMenu }, - isGesturesEnabled = isGesturesEnabled, - isDoubleTapSeekEnabled = isDoubleTapSeekEnabled, - seekDuration = seekDuration, - isZoomEnabled = isZoomEnabled, - isActive = pagerState.currentPage == page, - onCurrentVideoPipModeChanged = { inPip -> - if (pagerState.currentPage == page) { - currentVideoInPipMode = inPip - } - }, - zoomState = zoomState, - rootState = rootState, - screenHeightPx = screenHeightPx, - dismissDistancePx = dismissDistancePx, - dismissVelocityThreshold = dismissVelocityThreshold - ) - } else { - ImagePage( - path = path, - isDownloading = imageDownloadingStates.getOrNull(page) == true, - downloadProgress = imageDownloadProgressStates.getOrNull(page) ?: 0f, - zoomState = zoomState, - rootState = rootState, - screenHeightPx = screenHeightPx, - dismissDistancePx = dismissDistancePx, - dismissVelocityThreshold = dismissVelocityThreshold, - onDismiss = onDismiss, - showControls = showControls, - onToggleControls = { showControls = !showControls }, - pageIndex = page, - pagerIndex = pagerState.currentPage - ) - } - } - - val currentPath = mediaItems.getOrNull(pagerState.currentPage) ?: "" - val currentMimeType = getMimeType(currentPath) - val isCurrentVideo = (isAlwaysVideo && currentPath.isNotBlank()) || isVideoPath(currentPath, currentMimeType) - - if (!isCurrentVideo) { - ImageOverlay( - showControls = showControls, - rootState = rootState, - pagerState = pagerState, - mediaItems = mediaItems, - captions = captions, - showImageNumber = showImageNumber, - onDismiss = onDismiss, - showSettingsMenu = showSettingsMenu, - onToggleSettings = { showSettingsMenu = !showSettingsMenu }, - downloadUtils = downloadUtils, - onForward = onForward, - onDelete = onDelete, - onCopyLink = onCopyLink, - onCopyText = onCopyText - ) - } - } -} - -private fun isVideoPath(path: String, mimeType: String?): Boolean { - if (path.isBlank()) return false - if (mimeType?.startsWith("image/") == true) return false - - return mimeType?.startsWith("video/") == true || - path.endsWith(".mp4", ignoreCase = true) || - path.endsWith(".mkv", ignoreCase = true) || - path.endsWith(".mov", ignoreCase = true) || - path.endsWith(".webm", ignoreCase = true) || - path.endsWith(".avi", ignoreCase = true) || - path.endsWith(".3gp", ignoreCase = true) || - path.endsWith(".m4v", ignoreCase = true) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/viewers/VideoViewer.kt b/presentation/src/main/java/org/monogram/presentation/features/viewers/VideoViewer.kt deleted file mode 100644 index 60a2a89e..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/viewers/VideoViewer.kt +++ /dev/null @@ -1,56 +0,0 @@ -package org.monogram.presentation.features.viewers - -import android.util.Log -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import org.monogram.presentation.core.util.IDownloadUtils - -@Composable -fun VideoViewer( - path: String, - onDismiss: () -> Unit, - onForward: (String) -> Unit = {}, - onDelete: ((String) -> Unit)? = null, - onCopyLink: ((String) -> Unit)? = null, - onCopyText: ((String) -> Unit)? = null, - onSaveGif: ((String) -> Unit)? = null, - caption: String? = null, - fileId: Int = 0, - supportsStreaming: Boolean = false, - downloadUtils: IDownloadUtils, - isGesturesEnabled: Boolean = true, - isDoubleTapSeekEnabled: Boolean = true, - seekDuration: Int = 10, - isZoomEnabled: Boolean = true -) { - if (path.isBlank()) { - onDismiss() - return - } - - Log.d("VideoViewer", "Composing VideoViewer for path=$path, fileId=$fileId") - - val mediaItems = remember(path) { listOf(path) } - val captions = remember(caption) { listOf(caption) } - val fileIds = remember(fileId) { listOf(fileId) } - - MediaViewer( - mediaItems = mediaItems, - startIndex = 0, - onDismiss = onDismiss, - onForward = onForward, - onDelete = onDelete, - onCopyLink = onCopyLink, - onCopyText = onCopyText, - onSaveGif = onSaveGif, - captions = captions, - fileIds = fileIds, - supportsStreaming = supportsStreaming, - downloadUtils = downloadUtils, - isGesturesEnabled = isGesturesEnabled, - isDoubleTapSeekEnabled = isDoubleTapSeekEnabled, - seekDuration = seekDuration, - isZoomEnabled = isZoomEnabled, - isAlwaysVideo = true - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/viewers/YouTubeViewer.kt b/presentation/src/main/java/org/monogram/presentation/features/viewers/YouTubeViewer.kt deleted file mode 100644 index a8ef6270..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/viewers/YouTubeViewer.kt +++ /dev/null @@ -1,918 +0,0 @@ -@file:OptIn(ExperimentalMaterial3Api::class) - -package org.monogram.presentation.features.viewers - -import android.app.PictureInPictureParams -import android.content.Context -import android.content.Intent -import android.content.pm.ActivityInfo -import android.media.AudioManager -import android.os.Build -import android.os.Handler -import android.os.Looper -import android.view.View -import android.view.ViewGroup -import android.view.WindowManager -import android.webkit.* -import androidx.activity.compose.BackHandler -import androidx.compose.animation.* -import androidx.compose.animation.core.Animatable -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.spring -import androidx.compose.animation.core.tween -import androidx.compose.foundation.background -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.gestures.detectVerticalDragGestures -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.VolumeUp -import androidx.compose.material.icons.rounded.BrightnessMedium -import androidx.compose.material.icons.rounded.Lock -import androidx.compose.material.icons.rounded.Speed -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.scale -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.TransformOrigin -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalViewConfiguration -import androidx.compose.ui.unit.dp -import androidx.compose.ui.viewinterop.AndroidView -import androidx.core.view.WindowCompat -import androidx.core.view.WindowInsetsCompat -import androidx.core.view.WindowInsetsControllerCompat -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleEventObserver -import androidx.lifecycle.compose.LocalLifecycleOwner -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import org.monogram.presentation.features.viewers.components.* -import java.io.ByteArrayInputStream -import java.text.SimpleDateFormat -import java.util.* -import java.util.regex.Pattern -import kotlin.math.max - -@Composable -fun YouTubeViewer( - videoUrl: String, - onDismiss: () -> Unit, - caption: String? = null, - onForward: (String) -> Unit = {}, - onCopyLink: ((String) -> Unit)? = null, - onCopyText: ((String) -> Unit)? = null, - isPipEnabled: Boolean = true, - isActive: Boolean = true -) { - val youtubeId = extractYouTubeId(videoUrl) ?: return - val startTime = extractYouTubeTime(videoUrl) - val context = LocalContext.current - val lifecycleOwner = LocalLifecycleOwner.current - val playerState = remember { YouTubePlayerState() } - var isInPipMode by remember { mutableStateOf(false) } - var showControls by remember { mutableStateOf(true) } - var showSettingsMenu by remember { mutableStateOf(false) } - var currentTimeStr by remember { mutableStateOf("") } - - val scale = remember { Animatable(0.8f) } - val alpha = remember { Animatable(0f) } - - var gestureIcon by remember { mutableStateOf(null) } - var gestureText by remember { mutableStateOf(null) } - var showGestureOverlay by remember { mutableStateOf(false) } - var forwardSeekFeedback by remember { mutableStateOf(false) } - var rewindSeekFeedback by remember { mutableStateOf(false) } - - var isLongPressing by remember { mutableStateOf(false) } - val originalSpeed = remember { mutableFloatStateOf(1f) } - val viewConfiguration = LocalViewConfiguration.current - val coroutineScope = rememberCoroutineScope() - - val pipId = remember(videoUrl) { videoUrl.hashCode() } - - val adDomains = remember { - listOf( - "googleads", "doubleclick.net", "googlesyndication", "adservice.google", - "pagead", "spotxchange", "smartadserver" - ) - } - - val webView = remember { - WebView(context).apply { - layoutParams = ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT - ) - settings.apply { - javaScriptEnabled = true - domStorageEnabled = true - mediaPlaybackRequiresUserGesture = false - userAgentString = - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.5632.145 Safari/537.36" - setSupportMultipleWindows(true) - } - - webViewClient = object : WebViewClient() { - override fun shouldInterceptRequest( - view: WebView?, - request: WebResourceRequest? - ): WebResourceResponse? { - val url = request?.url.toString().lowercase() - val isAd = adDomains.any { url.contains(it) } - - if (isAd) { - return WebResourceResponse("text/plain", "UTF-8", ByteArrayInputStream("".toByteArray())) - } - return super.shouldInterceptRequest(view, request) - } - } - - addJavascriptInterface( - YoutubeProxy( - state = playerState, - onLoaded = { playerState.isLoading = false } - ), "YoutubeProxy" - ) - webChromeClient = WebChromeClient() - setBackgroundColor(0) - } - } - - fun exitPipMode() { - val activity = context.findActivity() ?: return - if (activity.isInPictureInPictureMode) { - val intent = Intent(context, activity.javaClass).apply { - flags = Intent.FLAG_ACTIVITY_SINGLE_TOP - } - context.startActivity(intent) - } - } - - LaunchedEffect(isActive) { - if (isActive) { - webView.evaluateJavascript("playVideo()", null) - } else { - webView.evaluateJavascript("pauseVideo()", null) - } - } - - PipController( - isPlaying = playerState.isPlaying, - videoAspectRatio = 16f / 9f, - pipId = pipId, - isActive = isActive, - onPlay = { - webView.visibility = View.VISIBLE - webView.onResume() - webView.resumeTimers() - webView.evaluateJavascript("playVideo()", null) - playerState.isPlaying = true - }, - onPause = { - webView.evaluateJavascript("pauseVideo()", null) - playerState.isPlaying = false - }, - onRewind = { - val newTime = max(0f, playerState.currentTime - 10) - playerState.currentTime = newTime - webView.evaluateJavascript("seekTo($newTime, true)", null) - }, - onForward = { - val newTime = playerState.currentTime + 10 - playerState.currentTime = newTime - webView.evaluateJavascript("seekTo($newTime, true)", null) - }, - onPipModeChanged = { isInPipMode = it } - ) - - LaunchedEffect(youtubeId) { - webView.loadDataWithBaseURL( - "https://www.youtube-nocookie.com", - getYouTubeHtml(youtubeId, startTime), - "text/html", - "utf-8", - null - ) - } - - DisposableEffect(lifecycleOwner) { - val activity = context.findActivity() - activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) - - val observer = LifecycleEventObserver { _, event -> - val isPip = activity?.isInPictureInPictureMode == true - - when (event) { - Lifecycle.Event.ON_PAUSE -> { - if (!isPip) { - webView.evaluateJavascript("pauseVideo()", null) - playerState.isPlaying = false - } - } - Lifecycle.Event.ON_STOP -> { - if (!isPip) { - webView.evaluateJavascript("pauseVideo()", null) - playerState.isPlaying = false - webView.onPause() - } - } - Lifecycle.Event.ON_RESUME -> { - webView.onResume() - webView.resumeTimers() - webView.evaluateJavascript("hideOverlays(); checkAds();", null) - } - else -> {} - } - } - lifecycleOwner.lifecycle.addObserver(observer) - - onDispose { - activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) - lifecycleOwner.lifecycle.removeObserver(observer) - exitPipMode() - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - try { - activity?.setPictureInPictureParams( - PictureInPictureParams.Builder() - .setAutoEnterEnabled(false) - .build() - ) - } catch (e: Exception) { - e.printStackTrace() - } - } - - activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED - activity?.let { - WindowCompat.getInsetsController(it.window, it.window.decorView).apply { - show(WindowInsetsCompat.Type.systemBars()) - } - } - webView.stopLoading() - webView.onPause() - webView.destroy() - } - } - - LaunchedEffect(Unit) { - launch { scale.animateTo(1f, spring(dampingRatio = 0.8f, stiffness = Spring.StiffnessMedium)) } - launch { alpha.animateTo(1f, tween(150)) } - } - - LaunchedEffect(showControls, isInPipMode) { - if (!showControls) showSettingsMenu = false - - val activity = context.findActivity() - activity?.let { - val window = it.window - val insetsController = WindowCompat.getInsetsController(window, window.decorView) - insetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE - - if (showControls && !isInPipMode) { - insetsController.show(WindowInsetsCompat.Type.systemBars()) - } else { - insetsController.hide(WindowInsetsCompat.Type.systemBars()) - } - } - } - - LaunchedEffect(showControls, playerState.isPlaying, showSettingsMenu, isInPipMode) { - if (showControls && playerState.isPlaying && !showSettingsMenu && !isInPipMode) { - delay(4000) - showControls = false - } - } - - LaunchedEffect(Unit) { - while (true) { - currentTimeStr = SimpleDateFormat("HH:mm", Locale.getDefault()).format(Date()) - delay(1000) - } - } - - LaunchedEffect(playerState.playbackSpeed) { - webView.evaluateJavascript("setPlaybackRate(${playerState.playbackSpeed})", null) - } - - LaunchedEffect(playerState.isMuted) { - if (playerState.isMuted) webView.evaluateJavascript("mute()", null) - else webView.evaluateJavascript("unMute()", null) - } - - LaunchedEffect(playerState.isLooping) { - webView.evaluateJavascript("setLoop(${playerState.isLooping})", null) - } - - LaunchedEffect(playerState.isCaptionsEnabled) { - webView.evaluateJavascript("setCaptionsEnabled(${playerState.isCaptionsEnabled})", null) - } - - LaunchedEffect(forwardSeekFeedback) { - if (forwardSeekFeedback) { - delay(600); forwardSeekFeedback = false - } - } - LaunchedEffect(rewindSeekFeedback) { - if (rewindSeekFeedback) { - delay(600); rewindSeekFeedback = false - } - } - - BackHandler { - if (isInPipMode) exitPipMode() - else if (showSettingsMenu) showSettingsMenu = false - else onDismiss() - } - - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.Black.copy(alpha = if (isInPipMode) 1f else alpha.value)) - ) { - AndroidView( - factory = { webView }, - modifier = Modifier - .fillMaxSize() - .scale(if (isInPipMode) 1f else scale.value), - update = { view -> - if (isInPipMode) { - view.onResume() - } - } - ) - - if (!isInPipMode) { - Box( - modifier = Modifier - .fillMaxSize() - .pointerInput(playerState.isLocked) { - detectTapGestures( - onDoubleTap = { offset -> - if (!playerState.isLocked) { - val width = size.width - if (offset.x < width / 2) { - val newTime = max(0f, playerState.currentTime - 10) - playerState.currentTime = newTime - webView.evaluateJavascript("seekTo($newTime, true)", null) - rewindSeekFeedback = true - } else { - val newTime = playerState.currentTime + 10 - playerState.currentTime = newTime - webView.evaluateJavascript("seekTo($newTime, true)", null) - forwardSeekFeedback = true - } - } - }, - onTap = { - if (showSettingsMenu) { - showSettingsMenu = false - showControls = false - } else { - showControls = !showControls - } - }, - onPress = { - val longPressJob = coroutineScope.launch { - delay(viewConfiguration.longPressTimeoutMillis) - if (!playerState.isLocked && playerState.isPlaying) { - originalSpeed.floatValue = playerState.playbackSpeed - playerState.playbackSpeed = 2f - isLongPressing = true - gestureIcon = Icons.Rounded.Speed - gestureText = "2x Speed" - showGestureOverlay = true - showControls = false - } - } - try { - awaitRelease() - } finally { - longPressJob.cancel() - if (isLongPressing) { - playerState.playbackSpeed = originalSpeed.floatValue - isLongPressing = false - showGestureOverlay = false - } - } - } - ) - } - .pointerInput(playerState.isLocked) { - detectVerticalDragGestures( - onDragStart = { if (!playerState.isLocked) showGestureOverlay = true }, - onDragEnd = { - if (isLongPressing) { - playerState.playbackSpeed = originalSpeed.floatValue - isLongPressing = false - } - showGestureOverlay = false - }, - onDragCancel = { - if (isLongPressing) { - playerState.playbackSpeed = originalSpeed.floatValue - isLongPressing = false - } - showGestureOverlay = false - } - ) { change, dragAmount -> - if (!playerState.isLocked && !isLongPressing) { - val width = size.width - val isLeft = change.position.x < width / 2 - val activity = context.findActivity() - - if (isLeft && activity != null) { - val lp = activity.window.attributes - var newBrightness = - (lp.screenBrightness.takeIf { it != -1f } ?: 0.5f) - (dragAmount / 1000f) - newBrightness = newBrightness.coerceIn(0f, 1f) - lp.screenBrightness = newBrightness - activity.window.attributes = lp - gestureIcon = Icons.Rounded.BrightnessMedium - gestureText = "${(newBrightness * 100).toInt()}%" - } else { - val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager - val maxVol = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC) - val currentVol = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) - val delta = -(dragAmount / 50f) - val newVol = (currentVol + delta).coerceIn(0f, maxVol.toFloat()) - audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, newVol.toInt(), 0) - gestureIcon = Icons.AutoMirrored.Rounded.VolumeUp - gestureText = "${((newVol / maxVol) * 100).toInt()}%" - } - } - } - } - ) { - if (playerState.isLoading) { - CircularProgressIndicator( - color = MaterialTheme.colorScheme.primary, - modifier = Modifier.align(Alignment.Center) - ) - } - - SeekFeedback(rewindSeekFeedback, true, 10, Modifier - .align(Alignment.CenterStart) - .padding(start = 64.dp)) - SeekFeedback(forwardSeekFeedback, false, 10, Modifier - .align(Alignment.CenterEnd) - .padding(end = 64.dp)) - GestureOverlay(showGestureOverlay, gestureIcon, gestureText, Modifier.align(Alignment.Center)) - - if (playerState.isLocked) { - AnimatedVisibility( - visible = showControls, - enter = fadeIn(), - exit = fadeOut(), - modifier = Modifier.fillMaxSize() - ) { - Box(modifier = Modifier.fillMaxSize()) { - IconButton( - onClick = { playerState.isLocked = false }, - modifier = Modifier - .align(Alignment.TopEnd) - .windowInsetsPadding(WindowInsets.statusBars) - .padding(16.dp) - .background(MaterialTheme.colorScheme.surfaceContainer, CircleShape) - ) { - Icon(Icons.Rounded.Lock, "Unlock", tint = MaterialTheme.colorScheme.onSurface) - } - } - } - } else { - YouTubePlayerControlsUI( - visible = showControls, - isPlaying = playerState.isPlaying, - currentPosition = (playerState.currentTime * 1000).toLong(), - totalDuration = (playerState.duration * 1000).toLong(), - bufferedPosition = (playerState.bufferedAmount * playerState.duration * 1000).toLong(), - videoTitle = playerState.videoTitle, - currentTimeStr = currentTimeStr, - isSettingsOpen = showSettingsMenu, - caption = caption, - onPlayPauseToggle = { - if (playerState.isPlaying) { - webView.evaluateJavascript("pauseVideo()", null) - playerState.isPlaying = false - } else { - webView.evaluateJavascript("playVideo()", null) - playerState.isPlaying = true - } - }, - onSeek = { - val newTime = it / 1000f - playerState.currentTime = newTime - webView.evaluateJavascript("seekTo($newTime, true)", null) - }, - onBack = onDismiss, - onForward = { - val newTime = playerState.currentTime + 10 - playerState.currentTime = newTime - webView.evaluateJavascript("seekTo($newTime, true)", null) - }, - onRewind = { - val newTime = max(0f, playerState.currentTime - 10) - playerState.currentTime = newTime - webView.evaluateJavascript("seekTo($newTime, true)", null) - }, - onSettingsToggle = { showSettingsMenu = !showSettingsMenu } - ) - - AnimatedVisibility( - visible = showSettingsMenu && showControls, - enter = fadeIn(tween(150)) + scaleIn( - animationSpec = spring(dampingRatio = 0.8f, stiffness = Spring.StiffnessMedium), - initialScale = 0.8f, - transformOrigin = TransformOrigin(1f, 0f) - ), - exit = fadeOut(tween(150)) + scaleOut( - animationSpec = tween(150), - targetScale = 0.9f, - transformOrigin = TransformOrigin(1f, 0f) - ), - modifier = Modifier - .fillMaxSize() - .windowInsetsPadding(WindowInsets.statusBars) - .padding(top = 56.dp, end = 16.dp) - ) { - Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.TopEnd) { - YouTubeSettingsMenu( - playbackSpeed = playerState.playbackSpeed, - isMuted = playerState.isMuted, - isLooping = playerState.isLooping, - isCaptionsEnabled = playerState.isCaptionsEnabled, - availableQualities = playerState.availableQualities, - currentQuality = playerState.currentQuality, - onQualitySelected = { - playerState.currentQuality = it - webView.evaluateJavascript("setPlaybackQuality('$it')", null) - }, - onSpeedSelected = { playerState.playbackSpeed = it }, - onMuteToggle = { playerState.isMuted = !playerState.isMuted }, - onLoopToggle = { playerState.isLooping = !playerState.isLooping }, - onCaptionsToggle = { playerState.isCaptionsEnabled = !playerState.isCaptionsEnabled }, - onLockToggle = { playerState.isLocked = true; showSettingsMenu = false }, - onRotationToggle = { - val activity = context.findActivity() - activity?.requestedOrientation = - if (activity.requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) - ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED else ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE - }, - onCopyLink = { onCopyLink?.invoke(videoUrl); showSettingsMenu = false }, - onCopyLinkWithTime = { - val time = playerState.currentTime.toInt() - val baseVideoUrl = videoUrl - .replace(Regex("([?&])t=[^&]*&"), "$1") - .replace(Regex("[?&]t=[^&]*$"), "") - val urlWithTime = - if (baseVideoUrl.contains("?")) "$baseVideoUrl&t=${time}s" else "$baseVideoUrl?t=${time}s" - onCopyLink?.invoke(urlWithTime) - showSettingsMenu = false - }, - onEnterPip = { - if (isPipEnabled) { - showSettingsMenu = false - showControls = false - enterPipMode(context, playerState.isPlaying, 16f / 9f, pipId) - } - }, - onCopyText = if (!caption.isNullOrBlank()) { - { onCopyText?.invoke(caption); showSettingsMenu = false } - } else null, - onForward = { onForward(videoUrl); showSettingsMenu = false } - ) - } - } - } - } - } - } -} - -class YouTubePlayerState { - var isPlaying by mutableStateOf(false) - var currentTime by mutableStateOf(0f) - var duration by mutableStateOf(0f) - var isLoading by mutableStateOf(true) - var playbackSpeed by mutableFloatStateOf(1f) - var isMuted by mutableStateOf(false) - var isLocked by mutableStateOf(false) - var videoTitle by mutableStateOf("") - var bufferedAmount by mutableFloatStateOf(0f) - var isLooping by mutableStateOf(false) - var isCaptionsEnabled by mutableStateOf(false) - var availableQualities by mutableStateOf>(emptyList()) - var currentQuality by mutableStateOf("auto") -} - -class YoutubeProxy( - private val state: YouTubePlayerState, - private val onLoaded: () -> Unit -) { - private val handler = Handler(Looper.getMainLooper()) - - @JavascriptInterface - fun onPlayerStateChange(playerState: Int) { - handler.post { - state.isPlaying = playerState == 1 || playerState == 3 - } - } - - @JavascriptInterface - fun onPlayerNotifyDuration(duration: Float) { - handler.post { state.duration = duration } - } - - @JavascriptInterface - fun onPlayerNotifyCurrentPosition(position: Float) { - handler.post { state.currentTime = position } - } - - @JavascriptInterface - fun onVideoTitle(title: String) { - handler.post { state.videoTitle = title } - } - - @JavascriptInterface - fun onBufferedAmount(amount: Float) { - handler.post { state.bufferedAmount = amount } - } - - @JavascriptInterface - fun onPlayerLoaded() { - handler.post { onLoaded() } - } - - @JavascriptInterface - fun onPlayerError(error: Int) { - } - - @JavascriptInterface - fun onAvailableQualities(qualities: String) { - handler.post { state.availableQualities = qualities.split(",").filter { it.isNotBlank() } } - } - - @JavascriptInterface - fun onQualityChange(quality: String) { - handler.post { state.currentQuality = quality } - } -} - -fun getYouTubeHtml(videoId: String, startTime: Int = 0): String { - val cssHide = """ - .ytp-chrome-top, .ytp-chrome-bottom, .ytp-gradient-top, .ytp-gradient-bottom, - .ytp-pause-overlay, .ytp-youtube-button, .ytp-show-cards-title, - .ytp-paid-content-overlay, .ytp-ce-element, .ytp-watermark, - .ytp-button.ytp-settings-button, .ytp-button.ytp-subtitles-button, - .ytp-button.ytp-fullscreen-button, .ytp-contextmenu, .ytp-error, .ytp-bezel, - .ytp-endscreen-content, .ytp-ce-covering-overlay, .ytp-ce-element-show, - .ytp-ce-video, .ytp-ce-channel, .ytp-suggestion-set, .ytp-scroll-min, - .ytp-ad-overlay-container, .ytp-ad-image-overlay, .ytp-ad-text-overlay, - .ytp-ad-module, .ytp-suggested-action, .ytp-cards-button, .ytp-cards-teaser, - .ytp-tooltip, .ytp-bezel-text, .ytp-miniplayer-ui, .ytp-title-channel, - .annotation, .ytp-branding-logo, .ytp-branding-link, - .video-ads, .ytp-ad-progress-list, .ytp-ad-player-overlay - { display: none !important; opacity: 0 !important; pointer-events: none !important; width: 0 !important; height: 0 !important; } - """.trimIndent() - - return """ - - - - - - - -
- - - - - """.trimIndent() -} - -fun extractYouTubeId(input: String?): String? { - if (input.isNullOrBlank()) return null - val rawIdPattern = "^[a-zA-Z0-9_-]{11}$" - if (Pattern.matches(rawIdPattern, input)) return input - val urlPattern = - "(?:youtube(?:-nocookie)?\\.com/(?:[^/\\n\\s]+/\\S+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\\.be/|youtube\\.com/shorts/)([a-zA-Z0-9_-]{11})" - val matcher = Pattern.compile(urlPattern, Pattern.CASE_INSENSITIVE).matcher(input) - return if (matcher.find()) matcher.group(1) else null -} - -fun extractYouTubeTime(url: String): Int { - val timePattern = Pattern.compile("[?&]t=(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s?)?") - val matcher = timePattern.matcher(url) - if (matcher.find()) { - val hours = matcher.group(1)?.toIntOrNull() ?: 0 - val minutes = matcher.group(2)?.toIntOrNull() ?: 0 - val seconds = matcher.group(3)?.toIntOrNull() ?: 0 - - val simpleTimePattern = Pattern.compile("[?&]t=(\\d+)$") - val simpleMatcher = simpleTimePattern.matcher(url) - if (simpleMatcher.find()) { - return simpleMatcher.group(1)?.toIntOrNull() ?: 0 - } - - return hours * 3600 + minutes * 60 + seconds - } - return 0 -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/viewers/components/ImageGestures.kt b/presentation/src/main/java/org/monogram/presentation/features/viewers/components/ImageGestures.kt deleted file mode 100644 index 91ac2248..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/viewers/components/ImageGestures.kt +++ /dev/null @@ -1,217 +0,0 @@ -package org.monogram.presentation.features.viewers.components - -import androidx.compose.animation.core.* -import androidx.compose.foundation.gestures.awaitEachGesture -import androidx.compose.foundation.gestures.awaitFirstDown -import androidx.compose.foundation.gestures.calculatePan -import androidx.compose.foundation.gestures.calculateZoom -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.input.pointer.PointerInputScope -import androidx.compose.ui.input.pointer.positionChanged -import androidx.compose.ui.input.pointer.util.VelocityTracker -import androidx.compose.ui.input.pointer.util.addPointerInputChange -import androidx.compose.ui.unit.IntSize -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch -import kotlin.math.abs -import kotlin.math.absoluteValue -import kotlin.math.sign - -class ZoomState { - val scale = Animatable(1f) - val offsetX = Animatable(0f) - val offsetY = Animatable(0f) - - fun resetInstant(scope: CoroutineScope) { - scope.launch { - scale.snapTo(1f) - offsetX.snapTo(0f) - offsetY.snapTo(0f) - } - } - - fun onDoubleTap(scope: CoroutineScope, tap: Offset, targetScale: Float, size: IntSize) { - scope.launch { - if (targetScale == 1f) { - launch { scale.animateTo(1f, spring()) } - launch { offsetX.animateTo(0f, spring()) } - launch { offsetY.animateTo(0f, spring()) } - return@launch - } - - val currentScale = scale.value - val centerX = size.width / 2f - val centerY = size.height / 2f - val zoomFactor = targetScale / currentScale - val tapXFromCenter = tap.x - centerX - val tapYFromCenter = tap.y - centerY - - val targetOffsetX = (tapXFromCenter * (1 - zoomFactor)) + (offsetX.value * zoomFactor) - val targetOffsetY = (tapYFromCenter * (1 - zoomFactor)) + (offsetY.value * zoomFactor) - - val maxOffsetX = (size.width * (targetScale - 1f)) / 2f - val maxOffsetY = (size.height * (targetScale - 1f)) / 2f - - val clampedX = targetOffsetX.coerceIn(-maxOffsetX, maxOffsetX) - val clampedY = targetOffsetY.coerceIn(-maxOffsetY, maxOffsetY) - - launch { scale.animateTo(targetScale, spring()) } - launch { offsetX.animateTo(clampedX, spring()) } - launch { offsetY.animateTo(clampedY, spring()) } - } - } - - fun onTransform(scope: CoroutineScope, pan: Offset, zoomFactor: Float, size: IntSize, maxZoom: Float) { - scope.launch { - val newScale = (scale.value * zoomFactor).coerceIn(1f, maxZoom) - scale.snapTo(newScale) - - if (scale.value > 1f) { - val newX = offsetX.value + pan.x - val newY = offsetY.value + pan.y - val maxX = (size.width * (scale.value - 1f)) / 2f - val maxY = (size.height * (scale.value - 1f)) / 2f - offsetX.snapTo(newX.coerceIn(-maxX, maxX)) - offsetY.snapTo(newY.coerceIn(-maxY, maxY)) - } else { - offsetX.snapTo(0f) - offsetY.snapTo(0f) - } - } - } - - fun ensureBounds(screenW: Float, screenH: Float, scope: CoroutineScope) { - scope.launch { - val maxX = (screenW * (scale.value - 1f)) / 2f - val maxY = (screenH * (scale.value - 1f)) / 2f - launch { offsetX.animateTo(offsetX.value.coerceIn(-maxX, maxX), spring()) } - launch { offsetY.animateTo(offsetY.value.coerceIn(-maxY, maxY), spring()) } - if (scale.value < 1f) launch { scale.animateTo(1f, spring()) } - } - } -} - -class DismissRootState { - val offsetY = Animatable(0f) - val scale = Animatable(0.8f) - val backgroundAlpha = Animatable(0f) - - fun resetInstant(scope: CoroutineScope) { - scope.launch { - offsetY.snapTo(0f) - scale.snapTo(1f) - backgroundAlpha.snapTo(1f) - } - } - - suspend fun animateExit(targetY: Float) = coroutineScope { - launch { - backgroundAlpha.animateTo( - targetValue = 0f, - animationSpec = tween(durationMillis = 150, easing = LinearEasing) - ) - } - launch { - offsetY.animateTo( - targetValue = targetY, - animationSpec = tween(durationMillis = 250, easing = FastOutSlowInEasing) - ) - } - } - - suspend fun animateRestore() = coroutineScope { - launch { offsetY.animateTo(0f, tween(150, easing = FastOutSlowInEasing)) } - launch { scale.animateTo(1f, tween(150)) } - launch { backgroundAlpha.animateTo(1f, tween(150)) } - } - - suspend fun drag(delta: Float) { - val currentY = offsetY.value - val targetY = currentY + delta - offsetY.snapTo(targetY) - val progress = (targetY / 1000f).absoluteValue.coerceIn(0f, 1f) - scale.snapTo(1f - (progress * 0.15f)) - backgroundAlpha.snapTo(1f - (progress * 0.8f)) - } -} - -@Composable -fun rememberZoomState(): ZoomState = remember { ZoomState() } - -@Composable -fun rememberDismissRootState(): DismissRootState = remember { DismissRootState() } - -suspend fun PointerInputScope.detectZoomAndDismissGestures( - zoomState: ZoomState, - rootState: DismissRootState, - screenHeightPx: Float, - dismissThreshold: Float, - dismissVelocityThreshold: Float, - onDismiss: () -> Unit, - scope: CoroutineScope -) { - awaitEachGesture { - val down = awaitFirstDown(requireUnconsumed = false) - val tracker = VelocityTracker() - tracker.addPointerInputChange(down) - - val touchSlop = viewConfiguration.touchSlop - var pan = Offset.Zero - var isZooming = false - var isVerticalDrag = false - - while (true) { - val event = awaitPointerEvent() - if (event.changes.any { it.isConsumed }) break - - val pointerCount = event.changes.size - event.changes.forEach { tracker.addPointerInputChange(it) } - - val zoomChange = event.calculateZoom() - val panChange = event.calculatePan() - - if (pointerCount > 1) isZooming = true - - if (!isZooming && !isVerticalDrag && zoomState.scale.value == 1f && pointerCount == 1) { - pan += panChange - val totalPan = pan.getDistance() - if (totalPan > touchSlop) { - if (abs(pan.y) > abs(pan.x) * 2f) { - isVerticalDrag = true - } else if (abs(pan.x) > touchSlop) { - return@awaitEachGesture - } - } - } - - if (isZooming || zoomState.scale.value > 1f) { - zoomState.onTransform(scope, panChange, zoomChange, IntSize(size.width, size.height), 3f) - event.changes.forEach { if (it.positionChanged()) it.consume() } - } else if (isVerticalDrag) { - scope.launch { rootState.drag(panChange.y) } - event.changes.forEach { if (it.positionChanged()) it.consume() } - } - - if (!event.changes.any { it.pressed }) break - } - - val velocity = tracker.calculateVelocity() - if (zoomState.scale.value > 1f) { - zoomState.ensureBounds(size.width.toFloat(), size.height.toFloat(), scope) - } else if (isVerticalDrag) { - val offsetY = rootState.offsetY.value - val shouldDismiss = abs(offsetY) > dismissThreshold || abs(velocity.y) > dismissVelocityThreshold - if (shouldDismiss) { - scope.launch { - rootState.animateExit(screenHeightPx * sign(offsetY)) - onDismiss() - } - } else { - scope.launch { rootState.animateRestore() } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/viewers/components/ImageViewerComponents.kt b/presentation/src/main/java/org/monogram/presentation/features/viewers/components/ImageViewerComponents.kt deleted file mode 100644 index 00b8f3f4..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/viewers/components/ImageViewerComponents.kt +++ /dev/null @@ -1,509 +0,0 @@ -package org.monogram.presentation.features.viewers.components - -import androidx.compose.animation.* -import androidx.compose.animation.core.* -import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.pager.PagerState -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.Forward -import androidx.compose.material.icons.rounded.ContentCopy -import androidx.compose.material.icons.rounded.Delete -import androidx.compose.material.icons.rounded.Download -import androidx.compose.material.icons.rounded.Link -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.TransformOrigin -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage -import coil3.compose.AsyncImagePainter -import coil3.request.ImageRequest -import coil3.request.allowHardware -import coil3.request.crossfade -import coil3.size.Precision -import coil3.size.Size -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch -import org.monogram.presentation.R -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.stickers.ui.menu.MenuOptionRow - -@Composable -fun ImagePage( - path: String, - isDownloading: Boolean, - downloadProgress: Float, - zoomState: ZoomState, - rootState: DismissRootState, - screenHeightPx: Float, - dismissDistancePx: Float, - dismissVelocityThreshold: Float, - onDismiss: () -> Unit, - showControls: Boolean, - onToggleControls: () -> Unit, - pageIndex: Int, - pagerIndex: Int -) { - val scope = rememberCoroutineScope() - Box( - modifier = Modifier - .fillMaxSize() - .pointerInput(Unit) { - detectTapGestures( - onDoubleTap = { offset -> - val currentScale = zoomState.scale.value - val targetScale = if (currentScale > 1.1f) 1f else 3f - zoomState.onDoubleTap(scope, offset, targetScale, size) - }, - onTap = { onToggleControls() } - ) - } - .pointerInput(pagerIndex) { - detectZoomAndDismissGestures( - zoomState = zoomState, - rootState = rootState, - screenHeightPx = screenHeightPx, - dismissThreshold = dismissDistancePx, - dismissVelocityThreshold = dismissVelocityThreshold, - onDismiss = onDismiss, - scope = scope - ) - } - ) { - ZoomableImage( - data = path, - isDownloading = isDownloading, - downloadProgress = downloadProgress, - zoomState = zoomState, - pageIndex = pageIndex, - pagerIndex = pagerIndex - ) - } -} - -@Composable -fun ImageOverlay( - showControls: Boolean, - rootState: DismissRootState, - pagerState: PagerState, - mediaItems: List, - captions: List, - showImageNumber: Boolean, - onDismiss: () -> Unit, - showSettingsMenu: Boolean, - onToggleSettings: () -> Unit, - downloadUtils: IDownloadUtils, - onForward: (String) -> Unit, - onDelete: ((String) -> Unit)?, - onCopyLink: ((String) -> Unit)?, - onCopyText: ((String) -> Unit)? -) { - val scope = rememberCoroutineScope() - - AnimatedVisibility( - visible = showControls && rootState.offsetY.value == 0f, - enter = fadeIn(), - exit = fadeOut(), - modifier = Modifier.fillMaxSize() - ) { - Box(Modifier.fillMaxSize()) { - ViewerTopBar( - onBack = onDismiss, - onActionClick = onToggleSettings, - isActionActive = showSettingsMenu, - modifier = Modifier.align(Alignment.TopCenter) - ) - - Column( - modifier = Modifier - .align(Alignment.BottomCenter) - .fillMaxWidth() - .background( - Brush.verticalGradient( - colors = listOf( - Color.Transparent, - Color.Black.copy(alpha = 0.4f), - Color.Black.copy(alpha = 0.8f) - ) - ) - ) - .windowInsetsPadding(WindowInsets.navigationBars) - .padding(bottom = 8.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - val currentCaption = captions.getOrNull(pagerState.currentPage) - if (!currentCaption.isNullOrBlank()) { - ViewerCaption(caption = currentCaption, showGradient = false) - } - - if (mediaItems.size > 1) { - ThumbnailStrip( - images = mediaItems, - pagerState = pagerState, - scope = scope - ) - - Spacer(modifier = Modifier.height(16.dp)) - if (showImageNumber) { - PageIndicator( - current = pagerState.currentPage + 1, - total = mediaItems.size - ) - Spacer(modifier = Modifier.height(16.dp)) - } - } - } - } - } - - AnimatedVisibility( - visible = showSettingsMenu && showControls, - enter = fadeIn(tween(150)) + scaleIn( - animationSpec = spring(dampingRatio = 0.8f, stiffness = Spring.StiffnessMedium), - initialScale = 0.8f, - transformOrigin = TransformOrigin(1f, 0f) - ), - exit = fadeOut(tween(150)) + scaleOut( - animationSpec = tween(150), - targetScale = 0.9f, - transformOrigin = TransformOrigin(1f, 0f) - ), - modifier = Modifier.fillMaxSize() - ) { - Box( - modifier = Modifier - .fillMaxSize() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null - ) { - onToggleSettings() - } - .windowInsetsPadding(WindowInsets.statusBars) - .padding(top = 56.dp, end = 16.dp), - contentAlignment = Alignment.TopEnd - ) { - val currentIndex = pagerState.currentPage - val currentItem = mediaItems.getOrNull(currentIndex) - - if (currentItem != null) { - val currentCaption = captions.getOrNull(currentIndex) - ImageSettingsMenu( - onDownload = { - downloadUtils.saveFileToDownloads(currentItem) - onToggleSettings() - }, - onCopyImage = { - downloadUtils.copyImageToClipboard(currentItem) - onToggleSettings() - }, - onCopyLink = { - onCopyLink?.invoke(currentItem) - onToggleSettings() - }, - onCopyText = if (!currentCaption.isNullOrBlank()) { - { - onCopyText?.invoke(currentItem) - onToggleSettings() - } - } else null, - onForward = { - onForward(currentItem) - onToggleSettings() - }, - onDelete = onDelete?.let { - { - it(currentItem) - onToggleSettings() - } - } - ) - } - } - } -} - -@Composable -fun ImageSettingsMenu( - onDownload: () -> Unit, - onCopyImage: () -> Unit, - onCopyLink: (() -> Unit)?, - onCopyText: (() -> Unit)? = null, - onForward: () -> Unit, - onDelete: (() -> Unit)? -) { - ViewerSettingsDropdown { - MenuOptionRow( - icon = Icons.Rounded.Download, - title = stringResource(R.string.action_download), - onClick = onDownload - ) - MenuOptionRow( - icon = Icons.Rounded.ContentCopy, - title = stringResource(R.string.action_copy_image), - onClick = onCopyImage - ) - if (onCopyText != null) { - MenuOptionRow( - icon = Icons.Rounded.ContentCopy, - title = stringResource(R.string.action_copy_text), - onClick = onCopyText - ) - } - if (onCopyLink != null) { - MenuOptionRow( - icon = Icons.Rounded.Link, - title = stringResource(R.string.action_copy_link), - onClick = onCopyLink - ) - } - MenuOptionRow( - icon = Icons.AutoMirrored.Rounded.Forward, - title = stringResource(R.string.action_forward), - onClick = onForward - ) - if (onDelete != null) { - HorizontalDivider( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp), - color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f) - ) - MenuOptionRow( - icon = Icons.Rounded.Delete, - title = stringResource(R.string.action_delete), - onClick = onDelete, - iconTint = MaterialTheme.colorScheme.error, - textColor = MaterialTheme.colorScheme.error - ) - } - } -} - -@Composable -fun ThumbnailStrip( - images: List, - pagerState: PagerState, - scope: CoroutineScope, - modifier: Modifier = Modifier, - thumbnailSize: Dp = 60.dp, - thumbnailSpacing: Dp = 8.dp -) { - val listState = rememberLazyListState() - val density = LocalDensity.current - val context = LocalContext.current - - LaunchedEffect(pagerState.currentPage) { - val viewportWidth = listState.layoutInfo.viewportSize.width - if (viewportWidth > 0) { - val itemSizePx = with(density) { thumbnailSize.toPx() } - val centerOffset = (viewportWidth / 2) - (itemSizePx / 2) - - listState.animateScrollToItem( - index = pagerState.currentPage, - scrollOffset = -centerOffset.toInt() - ) - } else { - listState.animateScrollToItem(pagerState.currentPage) - } - } - - LazyRow( - state = listState, - modifier = modifier - .wrapContentWidth() - .height(thumbnailSize + 24.dp), - contentPadding = PaddingValues(horizontal = 16.dp), - horizontalArrangement = Arrangement.spacedBy(thumbnailSpacing), - verticalAlignment = Alignment.CenterVertically - ) { - itemsIndexed( - images, - key = { index, _ -> "thumb_$index" } - ) { index, image -> - val isSelected = pagerState.currentPage == index - - val scale by animateFloatAsState(targetValue = if (isSelected) 1.1f else 0.9f, label = "scale") - val alpha by animateFloatAsState(targetValue = if (isSelected) 1f else 0.5f, label = "alpha") - val borderColor by animateColorAsState( - targetValue = if (isSelected) MaterialTheme.colorScheme.primary else Color.Transparent, - label = "border" - ) - val borderWidth by animateDpAsState(targetValue = if (isSelected) 2.dp else 0.dp, label = "width") - - val request = remember(image) { - ImageRequest.Builder(context) - .data(image) - .crossfade(true) - .allowHardware(true) - .build() - } - - Box( - modifier = Modifier - .size(thumbnailSize) - .graphicsLayer { - scaleX = scale - scaleY = scale - this.alpha = alpha - } - .clip(RoundedCornerShape(12.dp)) - .background(Color.Gray.copy(alpha = 0.2f)) - .clickable { - scope.launch { - pagerState.animateScrollToPage(index) - } - } - ) { - AsyncImage( - model = request, - contentDescription = stringResource(R.string.viewer_thumbnail_cd, index), - contentScale = ContentScale.Crop, - modifier = Modifier.fillMaxSize() - ) - - if (isSelected) { - Box( - modifier = Modifier - .fillMaxSize() - .border(BorderStroke(borderWidth, borderColor), RoundedCornerShape(12.dp)) - ) - } - } - } - } -} - -@Composable -fun PageIndicator(modifier: Modifier = Modifier, current: Int, total: Int) { - Surface( - modifier = modifier, - color = MaterialTheme.colorScheme.surfaceContainerHighest.copy(alpha = 0.5f), - contentColor = MaterialTheme.colorScheme.onSurface, - shape = CircleShape - ) { - Text( - text = stringResource(R.string.viewer_page_indicator, current, total), - modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp), - style = MaterialTheme.typography.labelLarge - ) - } -} - -@Composable -fun ZoomableImage( - data: Any, - isDownloading: Boolean, - downloadProgress: Float, - zoomState: ZoomState, - pageIndex: Int, - pagerIndex: Int -) { - val applyTransforms = pageIndex == pagerIndex - val context = LocalContext.current - - var isHighResLoading by remember(data) { mutableStateOf(true) } - - val thumbnailRequest = remember(data) { - ImageRequest.Builder(context) - .data(data) - .size(100, 100) - .crossfade(true) - .build() - } - - val fullRequest = remember(data) { - ImageRequest.Builder(context) - .data(data) - .size(Size.ORIGINAL) - .precision(Precision.EXACT) - .crossfade(true) - .build() - } - - Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { - AsyncImage( - model = thumbnailRequest, - contentDescription = null, - contentScale = ContentScale.Fit, - modifier = Modifier - .fillMaxSize() - .graphicsLayer { - if (applyTransforms) { - translationX = zoomState.offsetX.value - translationY = zoomState.offsetY.value - scaleX = zoomState.scale.value - scaleY = zoomState.scale.value - } - } - ) - - AsyncImage( - model = fullRequest, - contentDescription = null, - contentScale = ContentScale.Fit, - modifier = Modifier - .fillMaxSize() - .graphicsLayer { - if (applyTransforms) { - translationX = zoomState.offsetX.value - translationY = zoomState.offsetY.value - scaleX = zoomState.scale.value - scaleY = zoomState.scale.value - } - }, - onState = { state -> - isHighResLoading = state is AsyncImagePainter.State.Loading - } - ) - - if (isHighResLoading || isDownloading) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(12.dp) - ) { - CircularProgressIndicator( - modifier = Modifier.size(48.dp), - color = Color.White, - strokeWidth = 3.dp, - progress = { - if (isDownloading && downloadProgress in 0f..1f) { - downloadProgress - } else { - 0f - } - } - ) - Text( - text = if (isDownloading) { - stringResource(R.string.viewer_loading_original) - } else { - stringResource(R.string.loading_text) - }, - color = Color.White, - style = MaterialTheme.typography.bodyMedium - ) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/viewers/components/PipController.kt b/presentation/src/main/java/org/monogram/presentation/features/viewers/components/PipController.kt deleted file mode 100644 index aefd9617..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/viewers/components/PipController.kt +++ /dev/null @@ -1,229 +0,0 @@ -package org.monogram.presentation.features.viewers.components - -import android.app.PendingIntent -import android.app.PictureInPictureParams -import android.app.RemoteAction -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.content.IntentFilter -import android.graphics.drawable.Icon -import android.os.Build -import android.util.Rational -import androidx.compose.runtime.* -import androidx.compose.ui.platform.LocalContext -import androidx.core.app.PictureInPictureModeChangedInfo -import androidx.core.content.ContextCompat -import androidx.core.net.toUri -import androidx.core.util.Consumer -import org.monogram.presentation.R - -private const val ACTION_MEDIA_CONTROL = "org.monogram.pip.MEDIA_CONTROL" -private const val EXTRA_CONTROL_TYPE = "control_type" -private const val EXTRA_ID = "id" -private const val CONTROL_TYPE_PLAY = 1 -private const val CONTROL_TYPE_PAUSE = 2 -private const val CONTROL_TYPE_REWIND = 3 -private const val CONTROL_TYPE_FORWARD = 4 - -@Composable -fun PipController( - isPlaying: Boolean, - videoAspectRatio: Float, - pipId: Int, - isActive: Boolean, - onPlay: () -> Unit, - onPause: () -> Unit, - onRewind: () -> Unit, - onForward: () -> Unit, - onPipModeChanged: (Boolean) -> Unit -) { - val context = LocalContext.current - - val currentOnPlay by rememberUpdatedState(onPlay) - val currentOnPause by rememberUpdatedState(onPause) - val currentOnRewind by rememberUpdatedState(onRewind) - val currentOnForward by rememberUpdatedState(onForward) - val currentOnPipModeChanged by rememberUpdatedState(onPipModeChanged) - - fun createRemoteAction(controlType: Int, iconResId: Int, title: String): RemoteAction? { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val intent = Intent(ACTION_MEDIA_CONTROL).apply { - putExtra(EXTRA_CONTROL_TYPE, controlType) - putExtra(EXTRA_ID, pipId) - data = "monogram://pip/$pipId/$controlType".toUri() - setPackage(context.packageName) - } - - val pendingIntent = PendingIntent.getBroadcast( - context, - controlType, - intent, - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE - ) - return RemoteAction(Icon.createWithResource(context, iconResId), title, title, pendingIntent) - } - return null - } - - fun getPipParams(autoEnter: Boolean): PictureInPictureParams? { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val constrainedRatio = videoAspectRatio.coerceIn(0.4184f, 2.39f) - val ratio = if (constrainedRatio.isNaN() || constrainedRatio <= 0f) Rational(16, 9) - else Rational((constrainedRatio * 1000).toInt(), 1000) - - val params = PictureInPictureParams.Builder() - .setAspectRatio(ratio) - - val actions = mutableListOf() - - // Rewind - createRemoteAction(CONTROL_TYPE_REWIND, R.drawable.ic_replay_10, context.getString(R.string.pip_rewind))?.let { - actions.add(it) - } - - // Play/Pause - val playPauseAction = if (isPlaying) { - createRemoteAction(CONTROL_TYPE_PAUSE, R.drawable.ic_pause, context.getString(R.string.pip_pause)) - } else { - createRemoteAction(CONTROL_TYPE_PLAY, R.drawable.ic_play, context.getString(R.string.pip_play)) - } - playPauseAction?.let { actions.add(it) } - - // Forward - createRemoteAction(CONTROL_TYPE_FORWARD, R.drawable.ic_forward_10, context.getString(R.string.pip_forward))?.let { - actions.add(it) - } - - params.setActions(actions) - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - params.setAutoEnterEnabled(autoEnter) - } - return params.build() - } - return null - } - - fun updatePipParams(autoEnter: Boolean) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val activity = context.findActivity() ?: return - getPipParams(autoEnter)?.let { - try { - activity.setPictureInPictureParams(it) - } catch (e: Exception) { - e.printStackTrace() - } - } - } - } - - val receiver = remember(pipId) { - object : BroadcastReceiver() { - override fun onReceive(context: Context?, intent: Intent?) { - if (intent?.action == ACTION_MEDIA_CONTROL) { - val id = intent.getIntExtra(EXTRA_ID, 0) - if (id == pipId) { - when (intent.getIntExtra(EXTRA_CONTROL_TYPE, 0)) { - CONTROL_TYPE_PLAY -> currentOnPlay() - CONTROL_TYPE_PAUSE -> currentOnPause() - CONTROL_TYPE_REWIND -> currentOnRewind() - CONTROL_TYPE_FORWARD -> currentOnForward() - } - } - } - } - } - } - - DisposableEffect(context, pipId, isActive) { - if (!isActive) return@DisposableEffect onDispose {} - - val filter = IntentFilter(ACTION_MEDIA_CONTROL).apply { - addDataScheme("monogram") - } - ContextCompat.registerReceiver(context, receiver, filter, ContextCompat.RECEIVER_EXPORTED) - onDispose { - try { - context.unregisterReceiver(receiver) - } catch (e: Exception) { - e.printStackTrace() - } - } - } - - DisposableEffect(context) { - val activity = context.findActivity() - val pipConsumer = Consumer { info -> - currentOnPipModeChanged(info.isInPictureInPictureMode) - } - activity?.addOnPictureInPictureModeChangedListener(pipConsumer) - onDispose { - activity?.removeOnPictureInPictureModeChangedListener(pipConsumer) - // Disable auto-PIP when leaving - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - try { - activity?.setPictureInPictureParams( - PictureInPictureParams.Builder() - .setAutoEnterEnabled(false) - .build() - ) - } catch (e: Exception) { - e.printStackTrace() - } - } - } - } - - LaunchedEffect(isPlaying, videoAspectRatio, isActive) { - updatePipParams(isActive && isPlaying) - } -} - -fun enterPipMode(context: Context, isPlaying: Boolean, videoAspectRatio: Float, pipId: Int) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val activity = context.findActivity() ?: return - val constrainedRatio = videoAspectRatio.coerceIn(0.4184f, 2.39f) - val ratio = if (constrainedRatio.isNaN() || constrainedRatio <= 0f) Rational(16, 9) - else Rational((constrainedRatio * 1000).toInt(), 1000) - - val params = PictureInPictureParams.Builder() - .setAspectRatio(ratio) - - val actions = mutableListOf() - - fun createAction(controlType: Int, iconResId: Int, title: String): RemoteAction { - val intent = Intent(ACTION_MEDIA_CONTROL).apply { - putExtra(EXTRA_CONTROL_TYPE, controlType) - putExtra(EXTRA_ID, pipId) - data = "monogram://pip/$pipId/$controlType".toUri() - setPackage(context.packageName) - } - val pendingIntent = PendingIntent.getBroadcast( - context, - controlType, - intent, - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE - ) - return RemoteAction(Icon.createWithResource(context, iconResId), title, title, pendingIntent) - } - - // Rewind - actions.add(createAction(CONTROL_TYPE_REWIND, R.drawable.ic_replay_10, context.getString(R.string.pip_rewind))) - - // Play/Pause - val playPauseAction = if (isPlaying) { - createAction(CONTROL_TYPE_PAUSE, R.drawable.ic_pause, context.getString(R.string.pip_pause)) - } else { - createAction(CONTROL_TYPE_PLAY, R.drawable.ic_play, context.getString(R.string.pip_play)) - } - actions.add(playPauseAction) - - // Forward - actions.add(createAction(CONTROL_TYPE_FORWARD, R.drawable.ic_forward_10, context.getString(R.string.pip_forward))) - - params.setActions(actions) - - activity.enterPictureInPictureMode(params.build()) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/viewers/components/VideoGestures.kt b/presentation/src/main/java/org/monogram/presentation/features/viewers/components/VideoGestures.kt deleted file mode 100644 index 7306314c..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/viewers/components/VideoGestures.kt +++ /dev/null @@ -1,123 +0,0 @@ -package org.monogram.presentation.features.viewers.components - -import android.content.Context -import android.media.AudioManager -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.gestures.detectVerticalDragGestures -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.VolumeUp -import androidx.compose.material.icons.rounded.BrightnessMedium -import androidx.compose.runtime.Composable -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.input.pointer.pointerInput -import androidx.media3.exoplayer.ExoPlayer -import kotlin.math.max - -@Composable -fun Modifier.videoGestures( - exoPlayer: ExoPlayer, - isLocked: Boolean, - isInPipMode: Boolean, - isDoubleTapSeekEnabled: Boolean, - isGesturesEnabled: Boolean, - isZoomEnabled: Boolean, - seekDurationMs: Long, - zoomState: ZoomState, - rootState: DismissRootState, - screenHeightPx: Float, - dismissDistancePx: Float, - dismissVelocityThreshold: Float, - onDismiss: () -> Unit, - onToggleControls: () -> Unit, - onGestureOverlayChange: (Boolean, ImageVector?, String?) -> Unit, - onSeekFeedback: (Boolean, Boolean) -> Unit, - context: Context -): Modifier { - val scope = rememberCoroutineScope() - - return this - .pointerInput(isLocked, isInPipMode) { - if (isInPipMode) return@pointerInput - detectTapGestures( - onDoubleTap = { offset -> - if (zoomState.scale.value > 1f) { - zoomState.onDoubleTap(scope, offset, 1f, size) - } else if (!isLocked && isDoubleTapSeekEnabled) { - val width = size.width - if (offset.x < width / 2) { - exoPlayer.seekTo(max(0, exoPlayer.currentPosition - seekDurationMs)) - onSeekFeedback(true, true) - } else { - exoPlayer.seekTo(exoPlayer.currentPosition + seekDurationMs) - onSeekFeedback(true, false) - } - } - }, - onTap = { onToggleControls() } - ) - } - .pointerInput(isLocked, isInPipMode) { - if (isInPipMode) return@pointerInput - detectVerticalDragGestures( - onDragStart = { change -> - if (!isLocked && isGesturesEnabled && zoomState.scale.value == 1f) { - val width = size.width - val x = change.x - // Only show overlay if dragging on the edges (15% width) - if (x < width * 0.15f || x > width * 0.85f) { - onGestureOverlayChange(true, null, null) - } - } - }, - onDragEnd = { onGestureOverlayChange(false, null, null) }, - onDragCancel = { onGestureOverlayChange(false, null, null) } - ) { change, dragAmount -> - if (!isLocked && isGesturesEnabled && zoomState.scale.value == 1f) { - val width = size.width - val x = change.position.x - val isLeft = x < width * 0.15f - val isRight = x > width * 0.85f - val activity = context.findActivity() - - if (isLeft && activity != null) { - val lp = activity.window.attributes - var newBrightness = (lp.screenBrightness.takeIf { it != -1f } ?: 0.5f) - (dragAmount / 1000f) - newBrightness = newBrightness.coerceIn(0f, 1f) - lp.screenBrightness = newBrightness - activity.window.attributes = lp - onGestureOverlayChange( - true, - Icons.Rounded.BrightnessMedium, - "${(newBrightness * 100).toInt()}%" - ) - } else if (isRight) { - val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager - val maxVol = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC) - val currentVol = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) - val delta = -(dragAmount / 50f) - val newVol = (currentVol + delta).coerceIn(0f, maxVol.toFloat()) - audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, newVol.toInt(), 0) - onGestureOverlayChange( - true, - Icons.AutoMirrored.Rounded.VolumeUp, - "${((newVol / maxVol) * 100).toInt()}%" - ) - } - } - } - } - .pointerInput(isLocked, isInPipMode) { - if (isInPipMode) return@pointerInput - detectZoomAndDismissGestures( - zoomState = zoomState, - rootState = rootState, - screenHeightPx = screenHeightPx, - dismissThreshold = dismissDistancePx, - dismissVelocityThreshold = dismissVelocityThreshold, - onDismiss = onDismiss, - scope = scope - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/viewers/components/VideoViewerComponents.kt b/presentation/src/main/java/org/monogram/presentation/features/viewers/components/VideoViewerComponents.kt deleted file mode 100644 index 7521bcf0..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/viewers/components/VideoViewerComponents.kt +++ /dev/null @@ -1,921 +0,0 @@ -package org.monogram.presentation.features.viewers.components - -import android.os.Build -import android.util.Log -import android.view.ViewGroup.LayoutParams.MATCH_PARENT -import android.widget.FrameLayout -import androidx.annotation.OptIn -import androidx.compose.animation.* -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.spring -import androidx.compose.animation.core.tween -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.interaction.collectIsPressedAsState -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.* -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.scale -import androidx.compose.ui.graphics.* -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.viewinterop.AndroidView -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleEventObserver -import androidx.lifecycle.compose.LocalLifecycleOwner -import androidx.media3.common.* -import androidx.media3.common.util.UnstableApi -import androidx.media3.datasource.DataSource -import androidx.media3.exoplayer.ExoPlayer -import androidx.media3.exoplayer.source.DefaultMediaSourceFactory -import androidx.media3.extractor.DefaultExtractorsFactory -import androidx.media3.extractor.mp4.Mp4Extractor -import androidx.media3.ui.AspectRatioFrameLayout -import androidx.media3.ui.PlayerView -import kotlinx.coroutines.delay -import org.koin.compose.koinInject -import org.monogram.domain.repository.PlayerDataSourceFactory -import org.monogram.domain.repository.StreamingRepository -import org.monogram.presentation.R -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.core.util.getMimeType -import org.monogram.presentation.features.stickers.ui.menu.MenuOptionRow -import org.monogram.presentation.features.stickers.ui.menu.MenuToggleRow -import kotlin.math.max - -private const val TAG = "VideoPage" - -@OptIn(UnstableApi::class) -@Composable -fun VideoPage( - path: String, - fileId: Int, - caption: String?, - supportsStreaming: Boolean, - downloadUtils: IDownloadUtils, - onDismiss: () -> Unit, - showControls: Boolean, - onToggleControls: () -> Unit, - onForward: (String) -> Unit, - onDelete: ((String) -> Unit)?, - onCopyLink: ((String) -> Unit)?, - onCopyText: ((String) -> Unit)?, - onSaveGif: ((String) -> Unit)?, - showSettingsMenu: Boolean, - onToggleSettings: () -> Unit, - isGesturesEnabled: Boolean, - isDoubleTapSeekEnabled: Boolean, - seekDuration: Int, - isZoomEnabled: Boolean, - isActive: Boolean, - onCurrentVideoPipModeChanged: (Boolean) -> Unit, - zoomState: ZoomState, - rootState: DismissRootState, - screenHeightPx: Float, - dismissDistancePx: Float, - dismissVelocityThreshold: Float -) { - val context = LocalContext.current - val lifecycleOwner = LocalLifecycleOwner.current - val streamingRepository = koinInject() - val playerFactory = koinInject() - val seekDurationMs = seekDuration * 1000L - - val currentOnDismiss by rememberUpdatedState(onDismiss) - val currentOnToggleControls by rememberUpdatedState(onToggleControls) - val currentOnToggleSettings by rememberUpdatedState(onToggleSettings) - - var isInPipMode by remember { mutableStateOf(false) } - var isPlaying by remember { mutableStateOf(true) } - var isBuffering by remember { mutableStateOf(true) } - var isEnded by remember { mutableStateOf(false) } - var currentPosition by remember { mutableLongStateOf(0L) } - var totalDuration by remember { mutableLongStateOf(0L) } - var playerView by remember { mutableStateOf(null) } - var videoAspectRatio by remember { mutableFloatStateOf(16f / 9f) } - - var resizeMode by remember { mutableIntStateOf(AspectRatioFrameLayout.RESIZE_MODE_FIT) } - var playbackSpeed by remember { mutableFloatStateOf(1f) } - var isLocked by remember { mutableStateOf(false) } - var repeatMode by remember { mutableIntStateOf(Player.REPEAT_MODE_OFF) } - var isMuted by remember { mutableStateOf(false) } - - var gestureIcon by remember { mutableStateOf(null) } - var gestureText by remember { mutableStateOf(null) } - var showGestureOverlay by remember { mutableStateOf(false) } - var forwardSeekFeedback by remember { mutableStateOf(false) } - var rewindSeekFeedback by remember { mutableStateOf(false) } - - val pipId = remember(fileId, path) { if (fileId != 0) fileId else path.hashCode() } - - val downloadProgress by if (fileId != 0) { - streamingRepository.getDownloadProgress(fileId).collectAsState(initial = 0f) - } else { - remember { mutableStateOf(1f) } - } - - val exoPlayer = remember(path, fileId, supportsStreaming) { - Log.d(TAG, "Creating ExoPlayer for path=$path, fileId=$fileId") - val audioAttributes = AudioAttributes.Builder() - .setUsage(C.USAGE_MEDIA) - .setContentType(C.AUDIO_CONTENT_TYPE_MOVIE) - .build() - - val extractorsFactory = DefaultExtractorsFactory() - .setConstantBitrateSeekingEnabled(true) - .setMp4ExtractorFlags(Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS) - - val playerBuilder = ExoPlayer.Builder(context) - .setAudioAttributes(audioAttributes, true) - - val dataSourceFactory = if (supportsStreaming && fileId != 0) { - playerFactory.createPayload(fileId) as DataSource.Factory - } else { - null - } - - if (dataSourceFactory != null) { - playerBuilder.setMediaSourceFactory(DefaultMediaSourceFactory(dataSourceFactory, extractorsFactory)) - } else { - playerBuilder.setMediaSourceFactory(DefaultMediaSourceFactory(context, extractorsFactory)) - } - - playerBuilder.build().apply { - val mediaItem = MediaItem.Builder() - .setUri(path) - .apply { - getMimeType(path)?.let { setMimeType(it) } - } - .build() - setMediaItem(mediaItem) - prepare() - playWhenReady = isActive - } - } - - DisposableEffect(exoPlayer, lifecycleOwner) { - val activity = context.findActivity() - val observer = LifecycleEventObserver { _, event -> - val isPip = activity?.isInPictureInPictureMode == true - if (event == Lifecycle.Event.ON_PAUSE && !isPip) exoPlayer.pause() - if (event == Lifecycle.Event.ON_STOP && !isPip) exoPlayer.pause() - } - - val listener = object : Player.Listener { - override fun onIsPlayingChanged(isPlayingChanged: Boolean) { - isPlaying = isPlayingChanged - } - - override fun onPlaybackStateChanged(playbackState: Int) { - isBuffering = playbackState == Player.STATE_BUFFERING - isEnded = playbackState == Player.STATE_ENDED - if (playbackState == Player.STATE_READY) { - totalDuration = exoPlayer.duration.coerceAtLeast(0L) - } - } - - override fun onPlayerError(error: PlaybackException) { - Log.e(TAG, "Player error: ${error.message}", error) - isBuffering = false - if (!showControls) currentOnToggleControls() - } - - override fun onVideoSizeChanged(videoSize: VideoSize) { - if (videoSize.width > 0 && videoSize.height > 0) { - val ratio = if ((videoSize.unappliedRotationDegrees / 90) % 2 == 1) - videoSize.height.toFloat() / videoSize.width.toFloat() - else videoSize.width.toFloat() / videoSize.height.toFloat() - if (ratio != videoAspectRatio) { - videoAspectRatio = ratio - } - } - } - } - - exoPlayer.addListener(listener) - lifecycleOwner.lifecycle.addObserver(observer) - onDispose { - Log.d(TAG, "Disposing ExoPlayer for $path") - lifecycleOwner.lifecycle.removeObserver(observer) - exoPlayer.removeListener(listener) - exoPlayer.release() - } - } - - LaunchedEffect(exoPlayer, isActive, isInPipMode) { - if (isActive || isInPipMode) exoPlayer.play() else exoPlayer.pause() - } - - LaunchedEffect(isInPipMode, isActive) { - onCurrentVideoPipModeChanged(if (isActive) isInPipMode else false) - } - - LaunchedEffect(isEnded) { - if (isEnded && !showControls) { - currentOnToggleControls() - } - } - - LaunchedEffect(isPlaying, showControls, showSettingsMenu) { - if (isPlaying && showControls && !showSettingsMenu && !isLocked) { - delay(3500) - if (isPlaying && showControls && !showSettingsMenu && !isLocked) { - currentOnToggleControls() - } - } - } - - PipController( - isPlaying = isPlaying, - videoAspectRatio = videoAspectRatio, - pipId = pipId, - isActive = isActive, - onPlay = { - if (exoPlayer.playbackState == Player.STATE_ENDED) exoPlayer.seekTo(0) - exoPlayer.play() - }, - onPause = { - exoPlayer.pause() - }, - onRewind = { - exoPlayer.seekTo(max(0, exoPlayer.currentPosition - seekDurationMs)) - }, - onForward = { - exoPlayer.seekTo(exoPlayer.currentPosition + seekDurationMs) - }, - onPipModeChanged = { - isInPipMode = it - if (!it && !isActive) exoPlayer.pause() - } - ) - - LaunchedEffect(exoPlayer) { - while (true) { - val pos = exoPlayer.currentPosition - if (currentPosition != pos) { - currentPosition = pos - } - if (totalDuration <= 0L) { - totalDuration = exoPlayer.duration.coerceAtLeast(0L) - } - delay(200) - } - } - - LaunchedEffect(exoPlayer, playbackSpeed) { exoPlayer.setPlaybackSpeed(playbackSpeed) } - LaunchedEffect(exoPlayer, repeatMode) { exoPlayer.repeatMode = repeatMode } - LaunchedEffect(exoPlayer, isMuted) { exoPlayer.volume = if (isMuted) 0f else 1f } - - Box( - modifier = Modifier - .fillMaxSize() - .videoGestures( - exoPlayer = exoPlayer, - isLocked = isLocked, - isInPipMode = isInPipMode, - isDoubleTapSeekEnabled = isDoubleTapSeekEnabled, - isGesturesEnabled = isGesturesEnabled, - isZoomEnabled = isZoomEnabled, - seekDurationMs = seekDurationMs, - zoomState = zoomState, - rootState = rootState, - screenHeightPx = screenHeightPx, - dismissDistancePx = dismissDistancePx, - dismissVelocityThreshold = dismissVelocityThreshold, - onDismiss = currentOnDismiss, - onToggleControls = currentOnToggleControls, - onGestureOverlayChange = { visible, icon, text -> - showGestureOverlay = visible - gestureIcon = icon - gestureText = text - }, - onSeekFeedback = { isRewind, _ -> - if (isRewind) rewindSeekFeedback = true else forwardSeekFeedback = true - }, - context = context - ) - ) { - Box( - modifier = Modifier - .fillMaxSize() - .graphicsLayer { - if (!isInPipMode) { - scaleX = zoomState.scale.value - scaleY = zoomState.scale.value - translationX = zoomState.offsetX.value - translationY = zoomState.offsetY.value - } - } - ) { - AndroidView( - factory = { ctx -> - PlayerView(ctx).apply { - player = exoPlayer - useController = false - layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT) - setResizeMode(if (isInPipMode) AspectRatioFrameLayout.RESIZE_MODE_FIT else resizeMode) - setOnClickListener { currentOnToggleControls() } - playerView = this - } - }, - update = { view -> - view.player = exoPlayer - view.resizeMode = if (isInPipMode) AspectRatioFrameLayout.RESIZE_MODE_FIT else resizeMode - view.setOnClickListener { currentOnToggleControls() } - playerView = view - }, - modifier = Modifier.align(Alignment.Center) - ) - } - - if (!isInPipMode) { - if (isBuffering) CircularProgressIndicator( - color = MaterialTheme.colorScheme.primary, - modifier = Modifier.align(Alignment.Center) - ) - - SeekFeedback( - rewindSeekFeedback, - true, - seekDuration, - Modifier - .align(Alignment.CenterStart) - .padding(start = 64.dp) - ) - SeekFeedback( - forwardSeekFeedback, - false, - seekDuration, - Modifier - .align(Alignment.CenterEnd) - .padding(end = 64.dp) - ) - GestureOverlay(showGestureOverlay, gestureIcon, gestureText, Modifier.align(Alignment.Center)) - - if (isLocked) { - AnimatedVisibility( - visible = showControls, - enter = fadeIn(), - exit = fadeOut(), - modifier = Modifier.fillMaxSize() - ) { - Box(modifier = Modifier.fillMaxSize()) { - IconButton( - onClick = { - isLocked = false - }, - modifier = Modifier - .align(Alignment.TopEnd) - .windowInsetsPadding(WindowInsets.statusBars) - .padding(16.dp) - .background(MaterialTheme.colorScheme.surfaceContainer, CircleShape) - ) { Icon(Icons.Rounded.Lock, stringResource(R.string.action_unlock), tint = MaterialTheme.colorScheme.onSurface) } - } - } - } else { - VideoPlayerControls( - visible = showControls, - isPlaying = isPlaying, - isEnded = isEnded, - currentPosition = currentPosition, - totalDuration = totalDuration, - currentTime = currentTime(), - isSettingsOpen = showSettingsMenu, - caption = caption, - downloadProgress = downloadProgress, - onPlayPauseToggle = { - if (isEnded) { - exoPlayer.seekTo(0); exoPlayer.play() - } else { - if (exoPlayer.isPlaying) exoPlayer.pause() else exoPlayer.play() - } - }, - onSeek = { - exoPlayer.seekTo(it) - }, - onBack = currentOnDismiss, - onForward = { - exoPlayer.seekTo(exoPlayer.currentPosition + seekDurationMs) - }, - onRewind = { - exoPlayer.seekTo(max(0, exoPlayer.currentPosition - seekDurationMs)) - }, - onSettingsToggle = currentOnToggleSettings - ) - - AnimatedVisibility( - visible = showSettingsMenu && showControls, - enter = fadeIn(tween(150)) + scaleIn( - animationSpec = spring(dampingRatio = 0.8f, stiffness = Spring.StiffnessMedium), - initialScale = 0.8f, transformOrigin = TransformOrigin(1f, 0f) - ), - exit = fadeOut(tween(150)) + scaleOut( - animationSpec = tween(150), targetScale = 0.9f, transformOrigin = TransformOrigin(1f, 0f) - ), - modifier = Modifier - .fillMaxSize() - .windowInsetsPadding(WindowInsets.statusBars) - .padding(top = 56.dp, end = 16.dp) - ) { - Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.TopEnd) { - VideoSettingsMenu( - playbackSpeed = playbackSpeed, - repeatMode = repeatMode, - resizeMode = resizeMode, - isMuted = isMuted, - isZoomEnabled = isZoomEnabled, - onSpeedSelected = { - playbackSpeed = it - }, - onRepeatToggle = { - repeatMode = - if (repeatMode == Player.REPEAT_MODE_OFF) Player.REPEAT_MODE_ONE else Player.REPEAT_MODE_OFF - }, - onResizeToggle = { - resizeMode = - if (resizeMode == AspectRatioFrameLayout.RESIZE_MODE_FIT) AspectRatioFrameLayout.RESIZE_MODE_ZOOM else AspectRatioFrameLayout.RESIZE_MODE_FIT - }, - onMuteToggle = { - isMuted = !isMuted - }, - onLockToggle = { - isLocked = true - currentOnToggleSettings() - }, - onRotationToggle = { - val activity = context.findActivity() - activity?.requestedOrientation = - if (activity?.requestedOrientation == android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED else android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE - }, - onEnterPip = { - currentOnToggleSettings() - enterPipMode(context, isPlaying, videoAspectRatio, pipId) - }, - onDownload = { - downloadUtils.saveFileToDownloads(path); currentOnToggleSettings() - }, - onCopyLink = { onCopyLink?.invoke(path); currentOnToggleSettings() }, - onCopyText = if (!caption.isNullOrBlank()) { - { onCopyText?.invoke(path); currentOnToggleSettings() } - } else null, - onForward = { onForward(path); currentOnToggleSettings() }, - onDelete = onDelete?.let { { it(path); currentOnToggleSettings() } }, - onScreenshot = { toClipboard -> - val view = playerView ?: return@VideoSettingsMenu - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val surfaceView = - view.videoSurfaceView as? android.view.SurfaceView ?: return@VideoSettingsMenu - val bitmap = - androidx.core.graphics.createBitmap(surfaceView.width, surfaceView.height) - android.view.PixelCopy.request(surfaceView, bitmap, { result -> - if (result == android.view.PixelCopy.SUCCESS) { - if (toClipboard) downloadUtils.copyBitmapToClipboard(bitmap) else downloadUtils.saveBitmapToGallery( - bitmap - ) - } - }, android.os.Handler(android.os.Looper.getMainLooper())) - } - currentOnToggleSettings() - }, - onSaveGif = onSaveGif?.let { { it(path); currentOnToggleSettings() } } - ) - } - } - } - } - } - - LaunchedEffect(rewindSeekFeedback) { - if (rewindSeekFeedback) { - delay(600) - rewindSeekFeedback = false - } - } - - LaunchedEffect(forwardSeekFeedback) { - if (forwardSeekFeedback) { - delay(600) - forwardSeekFeedback = false - } - } -} - -@Composable -fun VideoPlayerControls( - visible: Boolean, - isPlaying: Boolean, - isEnded: Boolean, - currentPosition: Long, - totalDuration: Long, - currentTime: String, - isSettingsOpen: Boolean, - caption: String? = null, - downloadProgress: Float = 0f, - onPlayPauseToggle: () -> Unit, - onSeek: (Long) -> Unit, - onBack: () -> Unit, - onForward: () -> Unit, - onRewind: () -> Unit, - onSettingsToggle: () -> Unit -) { - var isDragging by remember { mutableStateOf(false) } - var sliderPosition by remember { mutableFloatStateOf(0f) } - - LaunchedEffect(currentPosition, totalDuration, isDragging) { - if (!isDragging && totalDuration > 0) { - val newPos = currentPosition.toFloat() / totalDuration.toFloat() - if (sliderPosition != newPos) { - sliderPosition = newPos - } - } - } - - Box(modifier = Modifier.fillMaxSize()) { - AnimatedVisibility( - visible = visible, - enter = slideInVertically(initialOffsetY = { -it }) + fadeIn(), - exit = slideOutVertically(targetOffsetY = { -it }) + fadeOut(), - modifier = Modifier.align(Alignment.TopCenter) - ) { - ViewerTopBar(onBack = onBack, onActionClick = onSettingsToggle, isActionActive = isSettingsOpen) - } - - AnimatedVisibility( - visible = visible, - enter = scaleIn() + fadeIn(), - exit = scaleOut() + fadeOut(), - modifier = Modifier.align(Alignment.Center) - ) { - Row(horizontalArrangement = Arrangement.spacedBy(48.dp), verticalAlignment = Alignment.CenterVertically) { - IconButton(onClick = onRewind, modifier = Modifier.size(56.dp)) { - Icon(Icons.Rounded.Replay10, stringResource(R.string.viewer_seek_rewind_cd), tint = Color.White, modifier = Modifier.fillMaxSize()) - } - - val interactionSource = remember { MutableInteractionSource() } - val isPressed by interactionSource.collectIsPressedAsState() - val scale by animateFloatAsState(targetValue = if (isPressed) 0.9f else 1f, label = "scale") - - Box( - modifier = Modifier - .scale(scale) - .size(84.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.9f)) - .clickable(interactionSource = interactionSource, indication = null) { onPlayPauseToggle() }, - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = when { - isEnded -> Icons.Rounded.Replay - isPlaying -> Icons.Rounded.Pause - else -> Icons.Rounded.PlayArrow - }, - contentDescription = when { - isEnded -> stringResource(R.string.action_restart) - isPlaying -> stringResource(R.string.action_pause) - else -> stringResource(R.string.action_play) - }, - tint = MaterialTheme.colorScheme.onPrimaryContainer, - modifier = Modifier.size(48.dp) - ) - } - - IconButton(onClick = onForward, modifier = Modifier.size(56.dp)) { - Icon(Icons.Rounded.Forward10, stringResource(R.string.viewer_seek_forward_cd), tint = Color.White, modifier = Modifier.fillMaxSize()) - } - } - } - - AnimatedVisibility( - visible = visible, - enter = slideInVertically(initialOffsetY = { it }) + fadeIn(), - exit = slideOutVertically(targetOffsetY = { it }) + fadeOut(), - modifier = Modifier.align(Alignment.BottomCenter) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .background( - Brush.verticalGradient( - colors = listOf( - Color.Transparent, - Color.Black.copy(alpha = 0.5f), - Color.Black.copy(alpha = 0.9f) - ) - ) - ) - .windowInsetsPadding(WindowInsets.navigationBars) - .padding(horizontal = 24.dp) - .padding(top = 32.dp, bottom = 24.dp) - ) { - if (!caption.isNullOrBlank()) { - ViewerCaption(caption = caption, showGradient = false) - Spacer(modifier = Modifier.height(8.dp)) - } - - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Text( - text = "${formatDuration(if (isDragging) (sliderPosition * totalDuration).toLong() else currentPosition)} / ${ - formatDuration( - totalDuration - ) - }", - color = Color.White, - style = MaterialTheme.typography.labelMedium.copy(fontWeight = FontWeight.SemiBold) - ) - Text( - text = currentTime, - color = Color.White.copy(alpha = 0.8f), - style = MaterialTheme.typography.labelMedium - ) - } - - Spacer(modifier = Modifier.height(12.dp)) - - Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.CenterStart) { - if (downloadProgress < 1f) { - LinearProgressIndicator( - progress = { downloadProgress }, - modifier = Modifier - .fillMaxWidth() - .height(4.dp) - .padding(horizontal = 2.dp), - color = Color.White.copy(alpha = 0.2f), - trackColor = Color.Transparent, - strokeCap = StrokeCap.Round - ) - } - Slider( - value = sliderPosition, - onValueChange = { - isDragging = true - sliderPosition = it - }, - onValueChangeFinished = { - isDragging = false - onSeek((sliderPosition * totalDuration).toLong()) - }, - colors = SliderDefaults.colors( - thumbColor = MaterialTheme.colorScheme.primary, - activeTrackColor = MaterialTheme.colorScheme.primary, - inactiveTrackColor = Color.White.copy(alpha = 0.3f) - ), - modifier = Modifier.fillMaxWidth() - ) - } - } - } - } -} - -private enum class SettingsScreen { MAIN, SPEED, SCREENSHOT } - -@OptIn(UnstableApi::class) -@Composable -fun VideoSettingsMenu( - playbackSpeed: Float, - repeatMode: Int, - resizeMode: Int, - isMuted: Boolean, - isZoomEnabled: Boolean, - onSpeedSelected: (Float) -> Unit, - onRepeatToggle: () -> Unit, - onResizeToggle: () -> Unit, - onMuteToggle: () -> Unit, - onLockToggle: () -> Unit, - onRotationToggle: () -> Unit, - onEnterPip: () -> Unit, - onDownload: () -> Unit, - onScreenshot: (Boolean) -> Unit, - onCopyLink: (() -> Unit)? = null, - onCopyText: (() -> Unit)? = null, - onForward: () -> Unit = {}, - onDelete: (() -> Unit)? = null, - onSaveGif: (() -> Unit)? = null -) { - var currentScreen by remember { mutableStateOf(SettingsScreen.MAIN) } - - ViewerSettingsDropdown { - AnimatedContent( - targetState = currentScreen, - transitionSpec = { - if (targetState != SettingsScreen.MAIN) { - slideInHorizontally { width -> width } + fadeIn() togetherWith slideOutHorizontally { width -> -width } + fadeOut() - } else { - slideInHorizontally { width -> -width } + fadeIn() togetherWith slideOutHorizontally { width -> width } + fadeOut() - } - }, - label = "SettingsNavigation" - ) { screen -> - when (screen) { - SettingsScreen.MAIN -> { - Column(modifier = Modifier.padding(vertical = 4.dp)) { - Text( - text = stringResource(R.string.settings_title), - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f), - modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) - ) - HorizontalDivider( - modifier = Modifier.padding(horizontal = 12.dp), - color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f) - ) - MenuOptionRow( - icon = Icons.Rounded.Speed, - title = stringResource(R.string.settings_playback_speed), - value = "${playbackSpeed}x", - onClick = { currentScreen = SettingsScreen.SPEED }, - trailingIcon = Icons.AutoMirrored.Rounded.KeyboardArrowRight - ) - if (isZoomEnabled) { - MenuOptionRow( - icon = if (resizeMode == AspectRatioFrameLayout.RESIZE_MODE_FIT) Icons.Rounded.AspectRatio else Icons.Rounded.FitScreen, - title = stringResource(R.string.settings_scale_mode), - value = if (resizeMode == AspectRatioFrameLayout.RESIZE_MODE_FIT) stringResource(R.string.settings_scale_fit) else stringResource(R.string.settings_scale_zoom), - onClick = onResizeToggle - ) - } - MenuOptionRow( - icon = Icons.Rounded.ScreenRotation, - title = stringResource(R.string.settings_rotate_screen), - onClick = onRotationToggle - ) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - MenuOptionRow( - icon = Icons.Rounded.PictureInPicture, - title = stringResource(R.string.settings_pip), - onClick = onEnterPip - ) - MenuOptionRow( - icon = Icons.Rounded.Camera, - title = stringResource(R.string.settings_screenshot), - onClick = { currentScreen = SettingsScreen.SCREENSHOT }, - trailingIcon = Icons.AutoMirrored.Rounded.KeyboardArrowRight - ) - } - HorizontalDivider( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp), - color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f) - ) - MenuToggleRow( - icon = if (repeatMode == Player.REPEAT_MODE_ONE) Icons.Rounded.RepeatOne else Icons.Rounded.Repeat, - title = stringResource(R.string.settings_loop_video), - isChecked = repeatMode == Player.REPEAT_MODE_ONE, - onCheckedChange = { onRepeatToggle() }) - MenuToggleRow( - icon = if (isMuted) Icons.AutoMirrored.Rounded.VolumeOff else Icons.AutoMirrored.Rounded.VolumeUp, - title = stringResource(R.string.settings_mute_audio), - isChecked = isMuted, - onCheckedChange = { onMuteToggle() }) - HorizontalDivider( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp), - color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f) - ) - MenuOptionRow(icon = Icons.Rounded.Download, title = stringResource(R.string.action_download_video), onClick = onDownload) - if (onSaveGif != null) MenuOptionRow( - icon = Icons.Rounded.Gif, - title = stringResource(R.string.action_save_gifs), - onClick = onSaveGif - ) - if (onCopyText != null) MenuOptionRow( - icon = Icons.Rounded.ContentCopy, - title = stringResource(R.string.action_copy_text), - onClick = onCopyText - ) - if (onCopyLink != null) MenuOptionRow( - icon = Icons.Rounded.Link, - title = stringResource(R.string.action_copy_link), - onClick = onCopyLink - ) - MenuOptionRow(icon = Icons.AutoMirrored.Rounded.Forward, title = stringResource(R.string.action_forward), onClick = onForward) - MenuOptionRow( - icon = Icons.Rounded.Lock, - title = stringResource(R.string.settings_lock_controls), - onClick = onLockToggle, - iconTint = MaterialTheme.colorScheme.primary, - textColor = MaterialTheme.colorScheme.primary - ) - if (onDelete != null) { - HorizontalDivider( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp), - color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f) - ) - MenuOptionRow( - icon = Icons.Rounded.Delete, - title = stringResource(R.string.action_delete), - onClick = onDelete, - iconTint = MaterialTheme.colorScheme.error, - textColor = MaterialTheme.colorScheme.error - ) - } - } - } - SettingsScreen.SPEED -> { - Column(modifier = Modifier.padding(vertical = 4.dp)) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxWidth() - .clickable { currentScreen = SettingsScreen.MAIN } - .padding(horizontal = 12.dp, vertical = 8.dp) - ) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - stringResource(R.string.viewer_back), - modifier = Modifier.size(20.dp), - tint = MaterialTheme.colorScheme.onSurface - ) - Spacer(Modifier.width(12.dp)) - Text( - stringResource(R.string.settings_playback_speed), - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.onSurface - ) - } - HorizontalDivider(color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f)) - listOf(0.25f, 0.5f, 0.75f, 1f, 1.25f, 1.5f, 2f).forEach { speed -> - SpeedSelectionRow( - speed = speed, - isSelected = playbackSpeed == speed, - onClick = { onSpeedSelected(speed) }) - } - } - } - SettingsScreen.SCREENSHOT -> { - Column(modifier = Modifier.padding(vertical = 4.dp)) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxWidth() - .clickable { currentScreen = SettingsScreen.MAIN } - .padding(horizontal = 12.dp, vertical = 8.dp) - ) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - stringResource(R.string.viewer_back), - modifier = Modifier.size(20.dp), - tint = MaterialTheme.colorScheme.onSurface - ) - Spacer(Modifier.width(12.dp)) - Text( - stringResource(R.string.settings_screenshot), - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.onSurface - ) - } - HorizontalDivider(color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f)) - MenuOptionRow( - icon = Icons.Rounded.Download, - title = stringResource(R.string.action_save_gallery), - onClick = { onScreenshot(false); currentScreen = SettingsScreen.MAIN }) - MenuOptionRow( - icon = Icons.Rounded.ContentPaste, - title = stringResource(R.string.action_copy_clipboard), - onClick = { onScreenshot(true); currentScreen = SettingsScreen.MAIN }) - } - } - } - } - } -} - -@Composable -fun SpeedSelectionRow(speed: Float, isSelected: Boolean, onClick: () -> Unit) { - Row( - modifier = Modifier - .fillMaxWidth() - .clickable(onClick = onClick) - .padding(horizontal = 16.dp, vertical = 10.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Text( - text = if (speed == 1f) stringResource(R.string.settings_speed_normal) else "${speed}x", - style = MaterialTheme.typography.bodyLarge, - fontWeight = if (isSelected) FontWeight.Bold else FontWeight.Normal, - color = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface - ) - if (isSelected) Icon( - Icons.Rounded.Check, - "Selected", - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.size(20.dp) - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/viewers/components/ViewerComponents.kt b/presentation/src/main/java/org/monogram/presentation/features/viewers/components/ViewerComponents.kt deleted file mode 100644 index 1683ac58..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/viewers/components/ViewerComponents.kt +++ /dev/null @@ -1,222 +0,0 @@ -package org.monogram.presentation.features.viewers.components - -import android.content.Context -import android.content.ContextWrapper -import androidx.activity.ComponentActivity -import androidx.compose.animation.* -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.Forward10 -import androidx.compose.material.icons.rounded.MoreVert -import androidx.compose.material.icons.rounded.Replay10 -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.presentation.R -import java.util.* - -@Composable -fun ViewerTopBar( - onBack: () -> Unit, - onActionClick: () -> Unit, - modifier: Modifier = Modifier, - isActionActive: Boolean = false -) { - Box( - modifier = modifier - .fillMaxWidth() - .background( - Brush.verticalGradient( - colors = listOf( - Color.Black.copy(alpha = 0.8f), - Color.Black.copy(alpha = 0.4f), - Color.Transparent - ) - ) - ) - .windowInsetsPadding(WindowInsets.statusBars) - .padding(horizontal = 12.dp) - .padding(top = 8.dp, bottom = 24.dp) - ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - IconButton(onClick = onBack) { - Icon( - imageVector = Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.viewer_back), - tint = Color.White - ) - } - - IconButton( - onClick = onActionClick, - colors = IconButtonDefaults.iconButtonColors( - containerColor = if (isActionActive) Color.White.copy(alpha = 0.2f) else Color.Transparent, - contentColor = Color.White - ) - ) { - Icon( - imageVector = Icons.Rounded.MoreVert, - contentDescription = stringResource(R.string.viewer_options) - ) - } - } - } -} - -@Composable -fun ViewerCaption( - caption: String, - modifier: Modifier = Modifier, - showGradient: Boolean = true -) { - var isExpanded by remember { mutableStateOf(false) } - - Box( - modifier = modifier - .fillMaxWidth() - .then( - if (showGradient) { - Modifier - .background( - Brush.verticalGradient( - colors = listOf( - Color.Transparent, - Color.Black.copy(alpha = 0.5f), - Color.Black.copy(alpha = 0.9f) - ) - ) - ) - .windowInsetsPadding(WindowInsets.navigationBars) - .padding(top = 32.dp) - } else Modifier - ) - .padding(horizontal = 16.dp, vertical = 16.dp) - ) { - Surface( - modifier = Modifier - .fillMaxWidth() - .clickable { isExpanded = !isExpanded } - .animateContentSize(), - color = Color.Black.copy(alpha = 0.4f), - shape = RoundedCornerShape(16.dp) - ) { - Text( - text = caption, - color = Color.White, - style = MaterialTheme.typography.bodyMedium, - maxLines = if (isExpanded) Int.MAX_VALUE else 3, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp) - ) - } - } -} - -@Composable -fun ViewerSettingsDropdown( - modifier: Modifier = Modifier, - content: @Composable ColumnScope.() -> Unit -) { - Surface( - shape = MaterialTheme.shapes.extraLarge, - color = MaterialTheme.colorScheme.surface.copy(alpha = 0.98f), - tonalElevation = 6.dp, - shadowElevation = 2.dp, - modifier = modifier - .width(260.dp) - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null, - onClick = {} - ) - ) { - Column( - modifier = Modifier - .verticalScroll(rememberScrollState()) - .padding(vertical = 4.dp), - content = content - ) - } -} - -@Composable -fun SeekFeedback(visible: Boolean, isRewind: Boolean, seekDuration: Int, modifier: Modifier = Modifier) { - AnimatedVisibility( - visible = visible, - enter = fadeIn() + scaleIn(), - exit = fadeOut() + scaleOut(), - modifier = modifier - ) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Icon( - if (isRewind) Icons.Rounded.Replay10 else Icons.Rounded.Forward10, - null, - tint = Color.White.copy(alpha = 0.9f), - modifier = Modifier.size(56.dp) - ) - Text( - text = if (isRewind) { - stringResource(R.string.viewer_seek_rewind_format, seekDuration) - } else { - stringResource(R.string.viewer_seek_forward_format, seekDuration) - }, - color = Color.White.copy(alpha = 0.9f), - fontWeight = FontWeight.Bold, - fontSize = 18.sp - ) - } - } -} - -@Composable -fun GestureOverlay(visible: Boolean, icon: ImageVector?, text: String?, modifier: Modifier = Modifier) { - AnimatedVisibility(visible = visible, enter = fadeIn(), exit = fadeOut(), modifier = modifier) { - Surface( - color = Color.Black.copy(alpha = 0.7f), - shape = RoundedCornerShape(24.dp), - modifier = Modifier.padding(24.dp) - ) { - Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.padding(24.dp)) { - if (icon != null) Icon(icon, null, tint = Color.White, modifier = Modifier.size(48.dp)) - Spacer(modifier = Modifier.height(12.dp)) - if (text != null) Text(text, color = Color.White, fontSize = 20.sp, fontWeight = FontWeight.SemiBold) - } - } - } -} - -fun formatDuration(durationMs: Long): String { - val totalSeconds = durationMs / 1000 - val minutes = totalSeconds / 60 - val seconds = totalSeconds % 60 - return String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds) -} - -fun currentTime(): String = - java.text.SimpleDateFormat("HH:mm", Locale.getDefault()).format(Date()) - -fun Context.findActivity(): ComponentActivity? = when (this) { - is ComponentActivity -> this - is ContextWrapper -> baseContext.findActivity() - else -> null -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/viewers/components/YouTubeViewerComponents.kt b/presentation/src/main/java/org/monogram/presentation/features/viewers/components/YouTubeViewerComponents.kt deleted file mode 100644 index e8be34d0..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/viewers/components/YouTubeViewerComponents.kt +++ /dev/null @@ -1,496 +0,0 @@ -package org.monogram.presentation.features.viewers.components - -import android.os.Build -import androidx.compose.animation.* -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.interaction.collectIsPressedAsState -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.* -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.scale -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import org.monogram.presentation.R -import org.monogram.presentation.features.stickers.ui.menu.MenuOptionRow -import org.monogram.presentation.features.stickers.ui.menu.MenuToggleRow - -@Composable -fun YouTubePlayerControlsUI( - visible: Boolean, - isPlaying: Boolean, - currentPosition: Long, - totalDuration: Long, - bufferedPosition: Long = 0, - videoTitle: String = "", - currentTimeStr: String, - isSettingsOpen: Boolean, - caption: String? = null, - onPlayPauseToggle: () -> Unit, - onSeek: (Long) -> Unit, - onBack: () -> Unit, - onForward: () -> Unit, - onRewind: () -> Unit, - onSettingsToggle: () -> Unit -) { - var isDragging by remember { mutableStateOf(false) } - var sliderPosition by remember { mutableFloatStateOf(0f) } - - LaunchedEffect(currentPosition, totalDuration, isDragging) { - if (!isDragging && totalDuration > 0) { - sliderPosition = currentPosition.toFloat() / totalDuration.toFloat() - } - } - - Box(modifier = Modifier.fillMaxSize()) { - AnimatedVisibility( - visible = visible, - enter = slideInVertically(initialOffsetY = { -it }) + fadeIn(), - exit = slideOutVertically(targetOffsetY = { -it }) + fadeOut(), - modifier = Modifier.align(Alignment.TopCenter) - ) { - Column( - modifier = Modifier.background( - Brush.verticalGradient( - colors = listOf( - Color.Black.copy(alpha = 0.8f), - Color.Black.copy(alpha = 0.4f), - Color.Transparent - ) - ) - ) - ) { - ViewerTopBar( - onBack = onBack, - onActionClick = onSettingsToggle, - isActionActive = isSettingsOpen, - modifier = Modifier.background(Color.Transparent) - ) - if (videoTitle.isNotEmpty()) { - Text( - text = videoTitle, - color = Color.White, - style = MaterialTheme.typography.titleMedium, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - modifier = Modifier - .padding(horizontal = 16.dp) - .padding(bottom = 16.dp) - ) - } - } - } - - AnimatedVisibility( - visible = visible, - enter = scaleIn() + fadeIn(), - exit = scaleOut() + fadeOut(), - modifier = Modifier.align(Alignment.Center) - ) { - Row( - horizontalArrangement = Arrangement.spacedBy(48.dp), - verticalAlignment = Alignment.CenterVertically - ) { - IconButton(onClick = onRewind, modifier = Modifier.size(56.dp)) { - Icon(Icons.Rounded.Replay10, stringResource(R.string.viewer_seek_rewind_cd), tint = Color.White, modifier = Modifier.fillMaxSize()) - } - - val interactionSource = remember { MutableInteractionSource() } - val isPressed by interactionSource.collectIsPressedAsState() - val scale by animateFloatAsState(targetValue = if (isPressed) 0.9f else 1f, label = "scale") - - Box( - modifier = Modifier - .scale(scale) - .size(84.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.9f)) - .clickable(interactionSource = interactionSource, indication = null) { onPlayPauseToggle() }, - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = if (isPlaying) Icons.Rounded.Pause else Icons.Rounded.PlayArrow, - contentDescription = if (isPlaying) stringResource(R.string.action_pause) else stringResource(R.string.action_play), - tint = MaterialTheme.colorScheme.onPrimaryContainer, - modifier = Modifier.size(48.dp) - ) - } - - IconButton(onClick = onForward, modifier = Modifier.size(56.dp)) { - Icon(Icons.Rounded.Forward10, stringResource(R.string.viewer_seek_forward_cd), tint = Color.White, modifier = Modifier.fillMaxSize()) - } - } - } - - AnimatedVisibility( - visible = visible, - enter = slideInVertically(initialOffsetY = { it }) + fadeIn(), - exit = slideOutVertically(targetOffsetY = { it }) + fadeOut(), - modifier = Modifier.align(Alignment.BottomCenter) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .background( - Brush.verticalGradient( - colors = listOf( - Color.Transparent, - Color.Black.copy(alpha = 0.5f), - Color.Black.copy(alpha = 0.9f) - ) - ) - ) - .windowInsetsPadding(WindowInsets.navigationBars) - .padding(horizontal = 24.dp) - .padding(top = 32.dp, bottom = 24.dp) - ) { - if (!caption.isNullOrBlank()) { - ViewerCaption(caption = caption, showGradient = false) - Spacer(modifier = Modifier.height(8.dp)) - } - - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Text( - text = "${formatDuration(if (isDragging) (sliderPosition * totalDuration).toLong() else currentPosition)} / ${ - formatDuration( - totalDuration - ) - }", - color = Color.White, - style = MaterialTheme.typography.labelMedium.copy(fontWeight = FontWeight.SemiBold) - ) - Text( - text = currentTimeStr, - color = Color.White.copy(alpha = 0.8f), - style = MaterialTheme.typography.labelMedium - ) - } - - Spacer(modifier = Modifier.height(12.dp)) - - Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.CenterStart) { - // Buffered track - if (totalDuration > 0) { - LinearProgressIndicator( - progress = { bufferedPosition.toFloat() / totalDuration.toFloat() }, - modifier = Modifier - .fillMaxWidth() - .height(4.dp) - .padding(horizontal = 2.dp), - color = Color.White.copy(alpha = 0.2f), - trackColor = Color.Transparent, - ) - } - - Slider( - value = sliderPosition, - onValueChange = { isDragging = true; sliderPosition = it }, - onValueChangeFinished = { - isDragging = false; onSeek((sliderPosition * totalDuration).toLong()) - }, - colors = SliderDefaults.colors( - thumbColor = MaterialTheme.colorScheme.primary, - activeTrackColor = MaterialTheme.colorScheme.primary, - inactiveTrackColor = Color.White.copy(alpha = 0.3f) - ), - modifier = Modifier.fillMaxWidth() - ) - } - } - } - } -} - -private enum class YouTubeSettingsScreen { - MAIN, SPEED, QUALITY -} - -@Composable -fun YouTubeSettingsMenu( - playbackSpeed: Float, - isMuted: Boolean, - isLooping: Boolean = false, - isCaptionsEnabled: Boolean = false, - availableQualities: List = emptyList(), - currentQuality: String = "auto", - onQualitySelected: (String) -> Unit = {}, - onSpeedSelected: (Float) -> Unit, - onMuteToggle: () -> Unit, - onLoopToggle: () -> Unit = {}, - onCaptionsToggle: () -> Unit = {}, - onLockToggle: () -> Unit, - onRotationToggle: () -> Unit, - onCopyLink: () -> Unit, - onCopyLinkWithTime: () -> Unit = {}, - onEnterPip: (() -> Unit)? = null, - onCopyText: (() -> Unit)? = null, - onForward: () -> Unit = {} -) { - var currentScreen by remember { mutableStateOf(YouTubeSettingsScreen.MAIN) } - - ViewerSettingsDropdown { - AnimatedContent( - targetState = currentScreen, - transitionSpec = { - if (targetState != YouTubeSettingsScreen.MAIN) { - slideInHorizontally { width -> width } + fadeIn() togetherWith - slideOutHorizontally { width -> -width } + fadeOut() - } else { - slideInHorizontally { width -> -width } + fadeIn() togetherWith - slideOutHorizontally { width -> width } + fadeOut() - } - }, - label = "YouTubeSettingsNavigation" - ) { screen -> - when (screen) { - YouTubeSettingsScreen.MAIN -> { - Column(modifier = Modifier.padding(vertical = 4.dp)) { - Text( - text = stringResource(R.string.settings_title), - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f), - modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) - ) - HorizontalDivider( - modifier = Modifier.padding(horizontal = 12.dp), - color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f) - ) - - MenuOptionRow( - icon = Icons.Rounded.HighQuality, - title = stringResource(R.string.settings_quality), - value = formatQualityLabel(currentQuality), - onClick = { currentScreen = YouTubeSettingsScreen.QUALITY }, - trailingIcon = Icons.AutoMirrored.Rounded.KeyboardArrowRight - ) - - MenuOptionRow( - icon = Icons.Rounded.Speed, - title = stringResource(R.string.settings_playback_speed), - value = "${playbackSpeed}x", - onClick = { currentScreen = YouTubeSettingsScreen.SPEED }, - trailingIcon = Icons.AutoMirrored.Rounded.KeyboardArrowRight - ) - - MenuOptionRow( - icon = Icons.Rounded.ScreenRotation, - title = stringResource(R.string.settings_rotate_screen), - onClick = onRotationToggle - ) - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && onEnterPip != null) { - MenuOptionRow( - icon = Icons.Rounded.PictureInPicture, - title = stringResource(R.string.settings_pip), - onClick = onEnterPip - ) - } - - HorizontalDivider( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp), - color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f) - ) - - MenuToggleRow( - icon = if (isMuted) Icons.AutoMirrored.Rounded.VolumeOff else Icons.AutoMirrored.Rounded.VolumeUp, - title = stringResource(R.string.settings_mute_audio), - isChecked = isMuted, - onCheckedChange = { onMuteToggle() } - ) - - MenuToggleRow( - icon = Icons.Rounded.Repeat, - title = stringResource(R.string.settings_loop_video), - isChecked = isLooping, - onCheckedChange = { onLoopToggle() } - ) - - MenuToggleRow( - icon = Icons.Rounded.ClosedCaption, - title = stringResource(R.string.settings_subtitles), - isChecked = isCaptionsEnabled, - onCheckedChange = { onCaptionsToggle() } - ) - - HorizontalDivider( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp), - color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f) - ) - - if (onCopyText != null) { - MenuOptionRow( - icon = Icons.Rounded.ContentCopy, - title = stringResource(R.string.action_copy_text), - onClick = onCopyText - ) - } - - MenuOptionRow( - icon = Icons.Rounded.Link, - title = stringResource(R.string.action_copy_link), - onClick = onCopyLink - ) - - MenuOptionRow( - icon = Icons.Rounded.Schedule, - title = stringResource(R.string.action_copy_link_time), - onClick = onCopyLinkWithTime - ) - - MenuOptionRow( - icon = Icons.AutoMirrored.Rounded.Forward, - title = stringResource(R.string.action_forward), - onClick = onForward - ) - - MenuOptionRow( - icon = Icons.Rounded.Lock, - title = stringResource(R.string.settings_lock_controls), - onClick = onLockToggle, - iconTint = MaterialTheme.colorScheme.primary, - textColor = MaterialTheme.colorScheme.primary - ) - } - } - - YouTubeSettingsScreen.SPEED -> { - Column(modifier = Modifier.padding(vertical = 4.dp)) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxWidth() - .clickable { currentScreen = YouTubeSettingsScreen.MAIN } - .padding(horizontal = 12.dp, vertical = 8.dp) - ) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - stringResource(R.string.viewer_back), - modifier = Modifier.size(20.dp), - tint = MaterialTheme.colorScheme.onSurface - ) - Spacer(Modifier.width(12.dp)) - Text( - stringResource(R.string.settings_playback_speed), - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.onSurface - ) - } - HorizontalDivider(color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f)) - val speeds = listOf(0.25f, 0.5f, 0.75f, 1f, 1.25f, 1.5f, 2f) - speeds.forEach { speed -> - SpeedSelectionRow( - speed = speed, - isSelected = playbackSpeed == speed, - onClick = { onSpeedSelected(speed) }) - } - } - } - - YouTubeSettingsScreen.QUALITY -> { - Column(modifier = Modifier.padding(vertical = 4.dp)) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxWidth() - .clickable { currentScreen = YouTubeSettingsScreen.MAIN } - .padding(horizontal = 12.dp, vertical = 8.dp) - ) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - stringResource(R.string.viewer_back), - modifier = Modifier.size(20.dp), - tint = MaterialTheme.colorScheme.onSurface - ) - Spacer(Modifier.width(12.dp)) - Text( - stringResource(R.string.settings_video_quality), - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.onSurface - ) - } - HorizontalDivider(color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f)) - - val qualities = (listOf("auto") + availableQualities).distinct() - qualities.forEach { quality -> - val iconRes = getQualityIcon(quality) - if (iconRes != null) { - MenuOptionRow( - iconRes = iconRes, - title = formatQualityLabel(quality), - onClick = { - onQualitySelected(quality) - currentScreen = YouTubeSettingsScreen.MAIN - }, - trailingIcon = if (currentQuality == quality) Icons.Rounded.Check else null, - iconTint = if (currentQuality == quality) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface - ) - } else { - MenuOptionRow( - icon = Icons.Rounded.HighQuality, - title = formatQualityLabel(quality), - onClick = { - onQualitySelected(quality) - currentScreen = YouTubeSettingsScreen.MAIN - }, - trailingIcon = if (currentQuality == quality) Icons.Rounded.Check else null, - iconTint = if (currentQuality == quality) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface - ) - } - } - } - } - } - } - } -} - -@Composable -private fun formatQualityLabel(quality: String): String { - return when (quality.lowercase()) { - "hd4320" -> "4320p" - "hd2880" -> "2880p" - "hd2160" -> "2160p" - "hd1440" -> "1440p" - "hd1080" -> "1080p" - "hd720" -> "720p" - "large" -> "480p" - "medium" -> "360p" - "small" -> "240p" - "tiny" -> "144p" - "auto" -> stringResource(R.string.settings_quality_auto) - "highres" -> stringResource(R.string.settings_quality_high_res) - else -> quality.replaceFirstChar { it.uppercase() } - } -} - -private fun getQualityIcon(quality: String): Int? { - return when (quality.lowercase()) { - "hd4320" -> R.drawable.ic_quality_8k - "hd2880" -> R.drawable.ic_quality_5k - "hd2160" -> R.drawable.ic_quality_4k - "hd1440" -> R.drawable.ic_quality_2k - "hd1080" -> R.drawable.ic_quality_full_hd - "hd720" -> R.drawable.ic_quality_hd - "large", "medium", "small", "tiny" -> R.drawable.ic_quality_sd - "auto" -> R.drawable.ic_quality_auto - "highres" -> R.drawable.ic_quality_high_res - else -> null - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/webapp/MiniAppModels.kt b/presentation/src/main/java/org/monogram/presentation/features/webapp/MiniAppModels.kt deleted file mode 100644 index a843a8b2..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webapp/MiniAppModels.kt +++ /dev/null @@ -1,55 +0,0 @@ -package org.monogram.presentation.features.webapp - -import androidx.compose.ui.graphics.Color - -data class MainButtonState( - val isVisible: Boolean = false, - val isActive: Boolean = true, - val text: String = "CONTINUE", - val color: Color? = null, - val textColor: Color? = null, - val isProgressVisible: Boolean = false, - val hasShineEffect: Boolean = false -) - -data class SecondaryButtonState( - val isVisible: Boolean = false, - val isActive: Boolean = true, - val text: String = "CANCEL", - val color: Color? = null, - val textColor: Color? = null, - val isProgressVisible: Boolean = false, - val hasShineEffect: Boolean = false, - val position: String = "left" -) - -data class PopupButton( - val id: String, - val type: String, - val text: String, - val isDestructive: Boolean -) - -data class PopupState( - val title: String?, - val message: String, - val buttons: List, - val callbackId: String -) - -data class PermissionRequest( - val message: String, - val onGranted: () -> Unit, - val onDenied: () -> Unit, - val onDismiss: () -> Unit = {} -) - -data class CustomMethodRequest( - val reqId: String, - val method: String, - val params: String, - val title: String, - val message: String, - val onConfirm: () -> Unit, - val onCancel: () -> Unit -) diff --git a/presentation/src/main/java/org/monogram/presentation/features/webapp/MiniAppState.kt b/presentation/src/main/java/org/monogram/presentation/features/webapp/MiniAppState.kt deleted file mode 100644 index 0d089c09..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webapp/MiniAppState.kt +++ /dev/null @@ -1,1026 +0,0 @@ -package org.monogram.presentation.features.webapp - -import org.monogram.presentation.core.util.coRunCatching -import android.Manifest -import android.annotation.SuppressLint -import android.app.Activity -import android.content.ClipboardManager -import android.content.Context -import android.content.Intent -import android.content.pm.ActivityInfo -import android.content.pm.PackageManager -import android.content.pm.ShortcutInfo -import android.content.pm.ShortcutManager -import android.graphics.BitmapFactory -import android.graphics.drawable.Icon -import android.location.Location -import android.location.LocationListener -import android.location.LocationManager -import android.os.Build -import android.os.Bundle -import android.os.Looper -import android.webkit.WebView -import androidx.biometric.BiometricManager -import androidx.biometric.BiometricPrompt -import androidx.compose.runtime.* -import androidx.compose.ui.graphics.Color -import androidx.core.content.ContextCompat -import androidx.core.graphics.toColorInt -import androidx.core.net.toUri -import androidx.fragment.app.FragmentActivity -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.suspendCancellableCoroutine -import org.json.JSONArray -import org.json.JSONObject -import org.monogram.domain.models.webapp.OSMReverseResponse -import org.monogram.domain.models.webapp.ThemeParams -import org.monogram.domain.models.webapp.WebAppPopupButton -import org.monogram.domain.repository.BotPreferencesProvider -import org.monogram.domain.repository.LocationRepository -import org.monogram.domain.repository.MessageRepository -import org.monogram.domain.repository.UserRepository -import org.monogram.presentation.R -import org.monogram.presentation.core.util.toHex -import java.net.URLEncoder -import java.security.SecureRandom -import kotlin.coroutines.resume - -@Stable -class MiniAppState( - val context: Context, - val botUserId: Long, - val botName: String, - val botAvatarPath: String?, - val messageRepository: MessageRepository, - val locationRepository: LocationRepository, - val botPreferences: BotPreferencesProvider, - val userRepository: UserRepository, - initialThemeParams: ThemeParams, - val onDismiss: () -> Unit -) { - var themeParams by mutableStateOf(initialThemeParams) - private set - - var webView: WebView? by mutableStateOf(null) - var progress by mutableIntStateOf(0) - var isLoading by mutableStateOf(true) - - var topBarColor by mutableStateOf(initialThemeParams.headerBackgroundColor?.let { Color(it.toColorInt()) }) - var topBarTextColor by mutableStateOf(initialThemeParams.textColor?.let { Color(it.toColorInt()) }) - var accentColor by mutableStateOf(initialThemeParams.accentTextColor?.let { Color(it.toColorInt()) }) - var backgroundColor by mutableStateOf(initialThemeParams.backgroundColor?.let { Color(it.toColorInt()) }) - var bottomBarColor by mutableStateOf(initialThemeParams.bottomBarBackgroundColor?.let { Color(it.toColorInt()) }) - - var headerText by mutableStateOf(botName) - - var isExpanded by mutableStateOf(false) - var isFullscreen by mutableStateOf(false) - - var mainButtonState by mutableStateOf(MainButtonState()) - var secondaryButtonState by mutableStateOf(SecondaryButtonState()) - var isBackButtonVisible by mutableStateOf(false) - var isSettingsButtonVisible by mutableStateOf(false) - var isClosingConfirmationEnabled by mutableStateOf(false) - var showClosingConfirmation by mutableStateOf(false) - - var isInitializing by mutableStateOf(botUserId != 0L) - var launchId by mutableLongStateOf(0L) - var currentUrl by mutableStateOf("") - - var activeInvoiceSlug by mutableStateOf(null) - var activePopup by mutableStateOf(null) - var activeQrText by mutableStateOf(null) - var activeCustomMethod by mutableStateOf(null) - - var showMenu by mutableStateOf(false) - - var hasCameraPermission by mutableStateOf( - ContextCompat.checkSelfPermission( - context, - Manifest.permission.CAMERA - ) == PackageManager.PERMISSION_GRANTED - ) - - var telegramProxy: TelegramWebviewProxy? by mutableStateOf(null) - var showPermissionRequest by mutableStateOf(null) - var onRequestSystemLocationPermission: (() -> Unit)? = null - - var isPermissionsVisible by mutableStateOf(false) - var botPermissions by mutableStateOf>(emptyMap()) - - var isTOSVisible by mutableStateOf(!botPreferences.getWebappPermission(botUserId, "tos_accepted")) - - val biometricManager = BiometricManager.from(context) - private val scope = CoroutineScope(Dispatchers.Main) - private var pendingRequestedContact: String? = null - - fun updateThemeParams(newParams: ThemeParams) { - val oldParams = themeParams - themeParams = newParams - - if (topBarColor == oldParams.headerBackgroundColor?.let { Color(it.toColorInt()) }) { - topBarColor = newParams.headerBackgroundColor?.let { Color(it.toColorInt()) } - } - if (topBarTextColor == oldParams.textColor?.let { Color(it.toColorInt()) }) { - topBarTextColor = newParams.textColor?.let { Color(it.toColorInt()) } - } - if (accentColor == oldParams.accentTextColor?.let { Color(it.toColorInt()) }) { - accentColor = newParams.accentTextColor?.let { Color(it.toColorInt()) } - } - if (backgroundColor == oldParams.backgroundColor?.let { Color(it.toColorInt()) }) { - backgroundColor = newParams.backgroundColor?.let { Color(it.toColorInt()) } - } - if (bottomBarColor == oldParams.bottomBarBackgroundColor?.let { Color(it.toColorInt()) }) { - bottomBarColor = newParams.bottomBarBackgroundColor?.let { Color(it.toColorInt()) } - } - } - - fun handleClose() { - if (isClosingConfirmationEnabled) { - showClosingConfirmation = true - } else { - if (launchId != 0L) { - scope.launch { - messageRepository.closeWebApp(launchId) - } - } - onDismiss() - } - } - - private fun getLastKnownLocation(): Location? { - val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager - val providers = locationManager.getProviders(true) - var bestLocation: Location? = null - for (provider in providers) { - val l = try { - locationManager.getLastKnownLocation(provider) - } catch (e: SecurityException) { - null - } - if (l != null && (bestLocation == null || l.accuracy < bestLocation.accuracy)) { - bestLocation = l - } - } - return bestLocation - } - - private fun savePermission(permission: String, granted: Boolean) { - botPreferences.setWebappPermission(botUserId, permission, granted) - } - - private fun isPermissionGranted(permission: String): Boolean { - return botPreferences.getWebappPermission(botUserId, permission) - } - - private fun isPermissionRequested(permission: String): Boolean { - return botPreferences.isWebappPermissionRequested(botUserId, permission) - } - - fun handleLocationRequest() { - if (ContextCompat.checkSelfPermission( - context, - Manifest.permission.ACCESS_FINE_LOCATION - ) != PackageManager.PERMISSION_GRANTED && - ContextCompat.checkSelfPermission( - context, - Manifest.permission.ACCESS_COARSE_LOCATION - ) != PackageManager.PERMISSION_GRANTED - ) { - sendLocationToWebview(null, "permission_denied") - return - } - - val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager - - val isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) - val isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) - - if (!isGpsEnabled && !isNetworkEnabled) { - sendLocationToWebview(null, "disabled") - return - } - - scope.launch { - val location = getCurrentLocation(locationManager) - - if (location != null) { - val osmResponse = locationRepository.reverseGeocode(location.latitude, location.longitude) - sendLocationToWebview(location, "success", osmResponse) - } else { - sendLocationToWebview(null, "timeout") - } - } - } - - @SuppressLint("MissingPermission") - private suspend fun getCurrentLocation(locationManager: LocationManager): Location? = - suspendCancellableCoroutine { cont -> - val hasFine = ContextCompat.checkSelfPermission( - context, - Manifest.permission.ACCESS_FINE_LOCATION - ) == PackageManager.PERMISSION_GRANTED - val hasCoarse = ContextCompat.checkSelfPermission( - context, - Manifest.permission.ACCESS_COARSE_LOCATION - ) == PackageManager.PERMISSION_GRANTED - - val providers = locationManager.getProviders(true) - var bestLocation: Location? = null - - for (provider in providers) { - if (provider == LocationManager.GPS_PROVIDER && !hasFine) continue - if (provider == LocationManager.NETWORK_PROVIDER && !hasFine && !hasCoarse) continue - - val l = try { - locationManager.getLastKnownLocation(provider) - } catch (e: SecurityException) { - null - } - if (l != null && (bestLocation == null || l.time > bestLocation.time)) { - bestLocation = l - } - } - - if (bestLocation != null && System.currentTimeMillis() - bestLocation.time < 60000) { - cont.resume(bestLocation) - return@suspendCancellableCoroutine - } - - val provider = if (hasFine && locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { - LocationManager.GPS_PROVIDER - } else if ((hasFine || hasCoarse) && locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { - LocationManager.NETWORK_PROVIDER - } else { - null - } - - if (provider == null) { - cont.resume(null) - return@suspendCancellableCoroutine - } - - val listener = object : LocationListener { - override fun onLocationChanged(location: Location) { - if (cont.isActive) { - cont.resume(location) - } - locationManager.removeUpdates(this) - } - - override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {} - override fun onProviderEnabled(provider: String) {} - override fun onProviderDisabled(provider: String) { - if (cont.isActive) cont.resume(null) - } - } - - try { - locationManager.requestSingleUpdate(provider, listener, Looper.getMainLooper()) - } catch (e: Exception) { - if (cont.isActive) cont.resume(null) - } - - cont.invokeOnCancellation { - locationManager.removeUpdates(listener) - } - } - - private fun sendLocationToWebview(location: Location?, status: String, osmData: OSMReverseResponse? = null) { - val json = JSONObject() - - val isAvailable = location != null - json.put("available", isAvailable) - json.put("status", status) - - if (location != null) { - json.put("latitude", location.latitude) - json.put("longitude", location.longitude) - - if (location.hasAccuracy()) { - json.put("horizontal_accuracy", location.accuracy.toDouble()) - json.put("accuracy", location.accuracy.toDouble()) - } else { - json.put("horizontal_accuracy", JSONObject.NULL) - json.put("accuracy", JSONObject.NULL) - } - - if (location.hasAltitude()) { - json.put("altitude", location.altitude) - } else { - json.put("altitude", JSONObject.NULL) - } - - if (location.hasBearing()) { - json.put("course", location.bearing.toDouble()) - } else { - json.put("course", JSONObject.NULL) - } - - if (location.hasSpeed()) { - json.put("speed", location.speed.toDouble()) - } else { - json.put("speed", JSONObject.NULL) - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - if (location.hasVerticalAccuracy()) { - json.put("vertical_accuracy", location.verticalAccuracyMeters.toDouble()) - } else { - json.put("vertical_accuracy", JSONObject.NULL) - } - - if (location.hasBearingAccuracy()) { - json.put("course_accuracy", location.bearingAccuracyDegrees.toDouble()) - } else { - json.put("course_accuracy", JSONObject.NULL) - } - - if (location.hasSpeedAccuracy()) { - json.put("speed_accuracy", location.speedAccuracyMetersPerSecond.toDouble()) - } else { - json.put("speed_accuracy", JSONObject.NULL) - } - } else { - json.put("vertical_accuracy", JSONObject.NULL) - json.put("course_accuracy", JSONObject.NULL) - json.put("speed_accuracy", JSONObject.NULL) - } - - val addr = osmData?.address - val city = addr?.city ?: addr?.town ?: addr?.village ?: addr?.suburb ?: addr?.county - - json.put("city", city ?: JSONObject.NULL) - json.put("country", addr?.country ?: JSONObject.NULL) - json.put("country_code", addr?.country_code ?: JSONObject.NULL) - } - - telegramProxy?.dispatchToWebView("location_requested", json) - } - - fun createHost(secureStorage: Any?) = object : TelegramWebAppHost { - override fun onOpenLink(url: String, tryBrowser: Boolean, tryInstantView: Boolean) { - val intent = Intent(Intent.ACTION_VIEW, url.toUri()) - coRunCatching { context.startActivity(intent) } - } - - override fun onOpenTgLink(path: String) { - val uri = if (path.startsWith("tg://")) path.toUri() else "tg://$path".toUri() - coRunCatching { context.startActivity(Intent(Intent.ACTION_VIEW, uri)) } - } - - override fun onOpenInvoice(slug: String) { - activeInvoiceSlug = slug - } - - override fun onClose(returnBack: Boolean) { - handleClose() - } - - override fun onExpand() { - isExpanded = true - } - - override fun onRequestFullscreen() { - isExpanded = true - isFullscreen = true - } - - override fun onExitFullscreen() { - isFullscreen = false - } - - override fun onToggleOrientationLock(locked: Boolean) { - (context as? Activity)?.requestedOrientation = if (locked) { - ActivityInfo.SCREEN_ORIENTATION_LOCKED - } else { - ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED - } - } - - override fun onAddToHomeScreen() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val shortcutManager = context.getSystemService(ShortcutManager::class.java) - if (shortcutManager.isRequestPinShortcutSupported) { - val shortcutId = "webapp_$botUserId" - val intent = Intent(context, context.javaClass).apply { - action = Intent.ACTION_VIEW - data = "tg://resolve?domain=$botName&startapp=true".toUri() - } - val icon = if (botAvatarPath != null) { - val bitmap = BitmapFactory.decodeFile(botAvatarPath) - if (bitmap != null) Icon.createWithBitmap(bitmap) else Icon.createWithResource( - context, - R.drawable.outline_web_24 - ) - } else { - Icon.createWithResource(context, R.drawable.outline_web_24) - } - val pinShortcutInfo = ShortcutInfo.Builder(context, shortcutId) - .setShortLabel(botName) - .setIcon(icon) - .setIntent(intent) - .build() - - shortcutManager.requestPinShortcut(pinShortcutInfo, null) - telegramProxy?.dispatchToWebView("home_screen_added", JSONObject().put("status", "added")) - } else { - telegramProxy?.dispatchToWebView("home_screen_added", JSONObject().put("status", "unsupported")) - } - } else { - telegramProxy?.dispatchToWebView("home_screen_added", JSONObject().put("status", "unsupported")) - } - } - - override fun onCheckHomeScreen() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val shortcutManager = context.getSystemService(ShortcutManager::class.java) - val shortcutId = "webapp_$botUserId" - val exists = shortcutManager.pinnedShortcuts.any { it.id == shortcutId } - telegramProxy?.dispatchToWebView( - "home_screen_checked", - JSONObject().put("status", if (exists) "added" else "missed") - ) - } else { - telegramProxy?.dispatchToWebView("home_screen_checked", JSONObject().put("status", "unsupported")) - } - } - - override fun onShareToStory(mediaUrl: String, text: String?, widgetLink: JSONObject?) {} - - override fun onOpenPopup( - title: String?, - message: String, - buttons: List, - callbackId: String - ) { - activePopup = PopupState( - title, - message, - buttons.map { PopupButton(it.id, it.type ?: "default", it.text, it.isDestructive) }, - callbackId - ) - } - - override fun onOpenScanQrPopup(text: String?) { - activeQrText = text ?: "" - } - - override fun onCloseScanQrPopup() { - activeQrText = null - } - - override fun onRequestPhone() { - activeCustomMethod = CustomMethodRequest( - reqId = "req_phone", - method = "web_app_request_phone", - params = "", - title = "Share Contact", - message = "Allow $botName to access your phone number?", - onConfirm = { - scope.launch { - val me = userRepository.getMe() - val contactJson = JSONObject().apply { - put("phone_number", me.phoneNumber ?: "") - put("first_name", me.firstName) - put("user_id", me.id) - }.toString() - pendingRequestedContact = "contact=" + URLEncoder.encode(contactJson, "UTF-8") - - telegramProxy?.dispatchToWebView( - "phone_requested", - JSONObject().put("status", "sent") - ) - activeCustomMethod = null - } - }, - onCancel = { - telegramProxy?.dispatchToWebView( - "phone_requested", - JSONObject().put("status", "cancelled") - ) - activeCustomMethod = null - } - ) - } - - override fun onRequestWriteAccess() { - telegramProxy?.dispatchToWebView("write_access_requested", JSONObject().put("status", "allowed")) - } - - override fun onSetupMainButton( - isVisible: Boolean, - isActive: Boolean, - text: String, - color: Int?, - textColor: Int?, - isProgressVisible: Boolean, - hasShineEffect: Boolean - ) { - mainButtonState = mainButtonState.copy( - isVisible = isVisible, - isActive = isActive, - text = text, - color = color?.let { Color(it) }, - textColor = textColor?.let { Color(it) }, - isProgressVisible = isProgressVisible, - hasShineEffect = hasShineEffect - ) - } - - override fun onSetupSecondaryButton( - isVisible: Boolean, - isActive: Boolean, - text: String, - color: Int?, - textColor: Int?, - isProgressVisible: Boolean, - hasShineEffect: Boolean, - position: String - ) { - secondaryButtonState = secondaryButtonState.copy( - isVisible = isVisible, - isActive = isActive, - text = text, - color = color?.let { Color(it) }, - textColor = textColor?.let { Color(it) }, - isProgressVisible = isProgressVisible, - hasShineEffect = hasShineEffect, - position = position - ) - } - - override fun onSetBackButtonVisible(visible: Boolean) { - isBackButtonVisible = visible - } - - override fun onSetSettingsButtonVisible(visible: Boolean) { - isSettingsButtonVisible = visible - } - - override fun onSetBackgroundColor(color: Int) { - backgroundColor = Color(color) - } - - override fun onSetHeaderColor(colorKey: String?, customColor: Int?) { - when (colorKey) { - "secondary_bg_color" -> themeParams.secondaryBackgroundColor?.let { - topBarColor = Color(it.toColorInt()) - } - - "bg_color" -> themeParams.backgroundColor?.let { topBarColor = Color(it.toColorInt()) } - else -> customColor?.let { topBarColor = Color(it) } - } - } - - override fun onResetHeaderColor() { - topBarColor = themeParams.headerBackgroundColor?.let { Color(it.toColorInt()) } - } - - override fun onSetHeaderText(text: String) { - headerText = text - } - - override fun onSetBottomBarColor(color: Int) { - bottomBarColor = Color(color) - } - - override fun onResetBottomBarColor() { - bottomBarColor = themeParams.bottomBarBackgroundColor?.let { Color(it.toColorInt()) } - } - - override fun onSetupClosingBehavior(needConfirmation: Boolean) { - isClosingConfirmationEnabled = needConfirmation - } - - override fun onSetupSwipeBehavior(allowVertical: Boolean) {} - - override fun onSwitchInlineQuery(query: String, chatTypes: List) {} - - override fun onSendWebViewData(data: String) { - if (launchId != 0L) { - scope.launch { - messageRepository.sendWebAppResult(launchId, data) - } - onDismiss() - } - } - - override fun onReadClipboard(reqId: String) { - val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - if (clipboard.hasPrimaryClip()) { - val text = clipboard.primaryClip?.getItemAt(0)?.text?.toString() ?: "" - telegramProxy?.dispatchToWebView( - "clipboard_text_received", - JSONObject().put("req_id", reqId).put("data", text) - ) - } else { - telegramProxy?.dispatchToWebView("clipboard_text_received", JSONObject().put("req_id", reqId)) - } - } - - override fun onInvokeCustomMethod(reqId: String, method: String, params: String) { - val paramsJson = try { - JSONObject(params) - } catch (e: Exception) { - JSONObject() - } - secureStorage as? MiniAppSecureStorage - - fun dispatchResult(result: Any?) { - telegramProxy?.dispatchToWebView( - "custom_method_invoked", - JSONObject().put("req_id", reqId).put("result", result ?: JSONObject.NULL) - ) - } - - fun dispatchError(error: String) { - telegramProxy?.dispatchToWebView( - "custom_method_invoked", - JSONObject().put("req_id", reqId).put("error", error) - ) - } - - fun getKeysList(json: JSONObject, key: String): List { - val arr = json.optJSONArray(key) ?: return emptyList() - return List(arr.length()) { arr.getString(it) } - } - - when (method) { - // TODO: Fix device storage and secure storage - -// "getRequestedContact" -> { -// if (pendingRequestedContact != null) { -// dispatchResult(pendingRequestedContact) -// pendingRequestedContact = null -// } else { -// dispatchResult("") -// } -// } -// -// // Device Storage -// "saveDeviceStorageValue" -> { -// val key = paramsJson.optString("key") -// val value = paramsJson.optString("value") -// if (key.isNotEmpty()) { -// botPreferences.saveWebappData(key, value) -// dispatchResult(true) -// } else dispatchError("INVALID_PARAMS") -// } -// "getDeviceStorageValue" -> dispatchResult(botPreferences.getWebappData(paramsJson.optString("key"))) -// "getDeviceStorageValues" -> { -// val keys = getKeysList(paramsJson, "keys") -// dispatchResult(JSONObject(botPreferences.getWebappData(keys))) -// } -// "deleteDeviceStorageValue" -> { -// botPreferences.deleteWebappData(paramsJson.optString("key")) -// dispatchResult(true) -// } -// "deleteDeviceStorageValues" -> { -// botPreferences.deleteWebappData(getKeysList(paramsJson, "keys")) -// dispatchResult(true) -// } -// "getDeviceStorageKeys" -> { -// val keys = botPreferences.getWebappDataKeys().filter { !it.startsWith("cloud_") } -// dispatchResult(JSONArray(keys)) -// } -// -// // Secure Storage -// "saveSecureStorageValue" -> { -// val key = paramsJson.optString("key") -// val value = paramsJson.optString("value") -// if (key.isNotEmpty() && storage != null) { -// storage.save(key, value) -// dispatchResult(true) -// } else dispatchError("UNAVAILABLE") -// } -// "getSecureStorageValue" -> dispatchResult(storage?.get(paramsJson.optString("key"))) -// "getSecureStorageValues" -> { -// val keys = getKeysList(paramsJson, "keys") -// dispatchResult(storage?.get(keys)?.let { JSONObject(it) }) -// } -// "deleteSecureStorageValue" -> { -// storage?.delete(paramsJson.optString("key")) -// dispatchResult(true) -// } -// "deleteSecureStorageValues" -> { -// storage?.delete(getKeysList(paramsJson, "keys")) -// dispatchResult(true) -// } -// "getSecureStorageKeys" -> dispatchResult(storage?.getKeys()?.let { JSONArray(it) }) - - // Cloud Storage - "saveStorageValue" -> { - val key = "cloud_${botUserId}_${paramsJson.optString("key")}" - botPreferences.saveWebappData(key, paramsJson.optString("value")) - dispatchResult(true) - } - - "getStorageValue" -> dispatchResult( - botPreferences.getWebappData( - "cloud_${botUserId}_${ - paramsJson.optString( - "key" - ) - }" - ) - ) - - "getStorageValues" -> { - val keys = getKeysList(paramsJson, "keys").map { "cloud_${botUserId}_$it" } - val data = botPreferences.getWebappData(keys).mapKeys { it.key.removePrefix("cloud_${botUserId}_") } - dispatchResult(JSONObject(data)) - } - - "deleteStorageValue" -> { - botPreferences.deleteWebappData("cloud_${botUserId}_${paramsJson.optString("key")}") - dispatchResult(true) - } - - "deleteStorageValues" -> { - val keys = getKeysList(paramsJson, "keys").map { "cloud_${botUserId}_$it" } - botPreferences.deleteWebappData(keys) - dispatchResult(true) - } - - "getStorageKeys" -> { - val prefix = "cloud_${botUserId}_" - val keys = botPreferences.getWebappDataKeys().filter { it.startsWith(prefix) } - .map { it.removePrefix(prefix) } - dispatchResult(JSONArray(keys)) - } - - else -> dispatchError("Method not implemented") - } - } - - override fun onSendPreparedMessage(id: String) {} - - override fun onFileDownloadRequested(url: String, fileName: String) { - coRunCatching { context.startActivity(Intent(Intent.ACTION_VIEW, url.toUri())) } - } - - override fun onOpenLocationSettings() { - onShowPermissions() - } - - override fun onSetEmojiStatus(customEmojiId: Long, duration: Int) { - telegramProxy?.dispatchToWebView("emoji_status_set", JSONObject().put("status", "unsupported")) - } - - override fun onRequestEmojiStatusAccess() { - telegramProxy?.dispatchToWebView("emoji_status_access_requested", JSONObject().put("status", "unsupported")) - } - - override fun onVerifyAge(age: Double) {} - - override fun onDeviceStorageSave(key: String, value: String) { - botPreferences.saveWebappData(key, value) - telegramProxy?.dispatchToWebView( - "device_storage_key_saved", - JSONObject().put("key", key).put("value", value) - ) - } - - override fun onDeviceStorageGet(key: String) { - val value = botPreferences.getWebappData(key) - telegramProxy?.dispatchToWebView( - "device_storage_key_loaded", - JSONObject().put("key", key).put("value", value) - ) - } - - override fun onDeviceStorageDelete(key: String) { - botPreferences.deleteWebappData(key) - telegramProxy?.dispatchToWebView("device_storage_key_removed", JSONObject().put("key", key)) - } - - override fun onSecureStorageSave(key: String, value: String) { - (secureStorage as? MiniAppSecureStorage)?.save(key, value) - telegramProxy?.dispatchToWebView( - "secure_storage_key_saved", - JSONObject().put("key", key).put("value", value) - ) - } - - override fun onSecureStorageGet(key: String) { - val value = (secureStorage as? MiniAppSecureStorage)?.get(key) - telegramProxy?.dispatchToWebView( - "secure_storage_key_loaded", - JSONObject().put("key", key).put("value", value) - ) - } - - override fun onSecureStorageDelete(key: String) { - (secureStorage as? MiniAppSecureStorage)?.delete(key) - telegramProxy?.dispatchToWebView("secure_storage_key_removed", JSONObject().put("key", key)) - } - - override fun onBiometryGetInfo() { - val canAuthenticate = biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG) - val isAvailable = - canAuthenticate != BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE && canAuthenticate != BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE - var deviceId = botPreferences.getWebappBiometryDeviceId(botUserId) - if (deviceId == null) { - val bytes = ByteArray(32) - SecureRandom().nextBytes(bytes) - deviceId = bytes.toHex() - botPreferences.saveWebappBiometryDeviceId(botUserId, deviceId) - } - val info = JSONObject().apply { - put("available", isAvailable) - put("access_requested", botPreferences.isWebappBiometryAccessRequested()) - put("access_granted", isPermissionGranted("biometry")) - put("device_can_authenticate", canAuthenticate == BiometricManager.BIOMETRIC_SUCCESS) - put("device_has_biometrics", isAvailable) - put("type", "fingerprint") - put("token_saved", (secureStorage as? MiniAppSecureStorage)?.get("biometry_token") != null) - put("device_id", deviceId) - } - telegramProxy?.dispatchToWebView("biometry_info_received", info) - } - - override fun onBiometryRequestAccess(reason: String?) { - botPreferences.setWebappBiometryAccessRequested(true) - savePermission("biometry", true) - onBiometryGetInfo() - } - - override fun onBiometryRequestAuth(reason: String?) { - val fragmentActivity = context as? FragmentActivity ?: run { - telegramProxy?.dispatchToWebView("biometry_auth_requested", JSONObject().put("status", "failed")) - return - } - val executor = ContextCompat.getMainExecutor(context) - val biometricPrompt = - BiometricPrompt(fragmentActivity, executor, object : BiometricPrompt.AuthenticationCallback() { - override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { - val token = (secureStorage as? MiniAppSecureStorage)?.get("biometry_token") - telegramProxy?.dispatchToWebView("biometry_auth_requested", JSONObject().apply { - put("status", "authorized") - if (token != null) put("token", token) - }) - } - - override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { - telegramProxy?.dispatchToWebView( - "biometry_auth_requested", - JSONObject().put("status", "failed") - ) - } - - override fun onAuthenticationFailed() {} - }) - val promptInfo = BiometricPrompt.PromptInfo.Builder() - .setTitle("Biometric Authentication") - .setSubtitle(reason ?: "Authenticate to continue") - .setNegativeButtonText("Cancel") - .build() - biometricPrompt.authenticate(promptInfo) - } - - override fun onBiometryUpdateToken(token: String) { - (secureStorage as? MiniAppSecureStorage)?.save("biometry_token", token) - telegramProxy?.dispatchToWebView("biometry_token_updated", JSONObject().put("status", "updated")) - } - - override fun onBiometryOpenSettings() { - onShowPermissions() - } - - override fun onRequestLocation() { - if (isPermissionGranted("location")) { - checkSystemLocationAndHandle() - return - } - showPermissionRequest = PermissionRequest( - message = "Allow this bot to access your location?", - onGranted = { - savePermission("location", true) - checkSystemLocationAndHandle() - }, - onDenied = { - savePermission("location", false) - telegramProxy?.dispatchToWebView("location_requested", JSONObject().put("status", "cancelled")) - }, - onDismiss = { - telegramProxy?.dispatchToWebView("location_requested", JSONObject().put("status", "cancelled")) - } - ) - } - - private fun checkSystemLocationAndHandle() { - val hasFine = ContextCompat.checkSelfPermission( - context, - Manifest.permission.ACCESS_FINE_LOCATION - ) == PackageManager.PERMISSION_GRANTED - val hasCoarse = ContextCompat.checkSelfPermission( - context, - Manifest.permission.ACCESS_COARSE_LOCATION - ) == PackageManager.PERMISSION_GRANTED - if (hasFine || hasCoarse) { - handleLocationRequest() - } else { - onRequestSystemLocationPermission?.invoke() - } - } - - override fun onCheckLocation() { - val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager - val isSupported = locationManager.allProviders.isNotEmpty() - - val hasSystemPermission = ContextCompat.checkSelfPermission( - context, - Manifest.permission.ACCESS_FINE_LOCATION - ) == PackageManager.PERMISSION_GRANTED || - ContextCompat.checkSelfPermission( - context, - Manifest.permission.ACCESS_COARSE_LOCATION - ) == PackageManager.PERMISSION_GRANTED - val isInternalGranted = isPermissionGranted("location") - val isRequested = isPermissionRequested("location") - - val json = JSONObject().apply { - put("available", isSupported) - put("access_requested", isRequested) - put("access_granted", hasSystemPermission && isInternalGranted) - } - telegramProxy?.dispatchToWebView("location_checked", json) - } - } - - fun onShowPermissions() { - val permissions = mapOf( - "Location" to botPreferences.getWebappPermission(botUserId, "location"), - "Biometry" to botPreferences.getWebappPermission(botUserId, "biometry"), - "Terms of Service" to botPreferences.getWebappPermission(botUserId, "tos_accepted") - ) - botPermissions = permissions - isPermissionsVisible = true - } - - fun onDismissPermissions() { - isPermissionsVisible = false - } - - fun onTogglePermission(permission: String) { - val key = when (permission) { - "Location" -> "location" - "Biometry" -> "biometry" - "Terms of Service" -> "tos_accepted" - else -> return - } - val current = botPreferences.getWebappPermission(botUserId, key) - botPreferences.setWebappPermission(botUserId, key, !current) - - if (key == "tos_accepted" && current) { - isTOSVisible = true - isPermissionsVisible = false - } else { - onShowPermissions() - } - } - - fun onAcceptTOS() { - botPreferences.setWebappPermission(botUserId, "tos_accepted", true) - isTOSVisible = false - } -} - -interface MiniAppSecureStorage { - fun save(key: String, value: String) - fun get(key: String): String? - fun get(keys: List): Map - fun delete(key: String) - fun delete(keys: List) - fun getKeys(): List -} - -@Composable -fun rememberMiniAppState( - context: Context, - botUserId: Long, - botName: String, - botAvatarPath: String?, - messageRepository: MessageRepository, - locationRepository: LocationRepository, - botPreferences: BotPreferencesProvider, - userRepository: UserRepository, - themeParams: ThemeParams, - onDismiss: () -> Unit -) = remember(botUserId) { - MiniAppState( - context, - botUserId, - botName, - botAvatarPath, - messageRepository, - locationRepository, - botPreferences, - userRepository, - themeParams, - onDismiss - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webapp/MiniAppViewer.kt b/presentation/src/main/java/org/monogram/presentation/features/webapp/MiniAppViewer.kt deleted file mode 100644 index ab01b3f0..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webapp/MiniAppViewer.kt +++ /dev/null @@ -1,466 +0,0 @@ -package org.monogram.presentation.features.webapp - -import android.Manifest -import android.app.Activity -import android.content.Context -import android.content.pm.ActivityInfo -import android.content.res.Configuration -import android.util.Log -import androidx.activity.compose.BackHandler -import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.* -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.toArgb -import androidx.compose.ui.platform.LocalClipboardManager -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.unit.LayoutDirection -import androidx.core.view.WindowCompat -import kotlinx.coroutines.launch -import org.json.JSONObject -import org.koin.compose.koinInject -import org.monogram.domain.models.webapp.ThemeParams -import org.monogram.domain.repository.BotPreferencesProvider -import org.monogram.domain.repository.LocationRepository -import org.monogram.domain.repository.MessageRepository -import org.monogram.domain.repository.UserRepository -import org.monogram.presentation.core.util.CryptoManager -import org.monogram.presentation.features.webapp.components.* -import java.util.* -import kotlin.math.max - -private const val TAG = "MiniAppLog" - -@Composable -fun MiniAppViewer( - chatId: Long, - botUserId: Long, - baseUrl: String, - botName: String, - botAvatarPath: String? = null, - messageRepository: MessageRepository, - onDismiss: () -> Unit -) { - val context = LocalContext.current - val activity = context as? Activity - val clipboardManager = LocalClipboardManager.current - val colorScheme = MaterialTheme.colorScheme - val density = LocalDensity.current - val locationRepository: LocationRepository = koinInject() - val botPreferences: BotPreferencesProvider = koinInject() - val userRepository: UserRepository = koinInject() - val isDark = isSystemInDarkTheme() - val scope = rememberCoroutineScope() - val currentUser by userRepository.currentUserFlow.collectAsState() - val webAppLanguage = remember(currentUser?.languageCode) { - currentUser?.languageCode - ?.trim() - ?.takeIf { it.isNotEmpty() } - ?: Locale.getDefault().toLanguageTag() - } - - val themeParams = remember(colorScheme, isDark) { - ThemeParams( - colorScheme = if (isDark) "dark" else "light", - backgroundColor = colorScheme.surface.toArgb().toHex(), - secondaryBackgroundColor = colorScheme.surfaceVariant.toArgb().toHex(), - headerBackgroundColor = colorScheme.surface.toArgb().toHex(), - bottomBarBackgroundColor = colorScheme.surface.toArgb().toHex(), - sectionBackgroundColor = colorScheme.surface.toArgb().toHex(), - sectionSeparatorColor = colorScheme.outlineVariant.toArgb().toHex(), - textColor = colorScheme.onSurface.toArgb().toHex(), - accentTextColor = colorScheme.primary.toArgb().toHex(), - sectionHeaderTextColor = colorScheme.primary.toArgb().toHex(), - subtitleTextColor = colorScheme.onSurfaceVariant.toArgb().toHex(), - destructiveTextColor = colorScheme.error.toArgb().toHex(), - hintColor = colorScheme.onSurfaceVariant.toArgb().toHex(), - linkColor = colorScheme.primary.toArgb().toHex(), - buttonColor = colorScheme.primary.toArgb().toHex(), - buttonTextColor = colorScheme.onPrimary.toArgb().toHex(), - ) - } - - val state = rememberMiniAppState( - context = context, - botUserId = botUserId, - botName = botName, - botAvatarPath = botAvatarPath, - messageRepository = messageRepository, - locationRepository = locationRepository, - botPreferences = botPreferences, - userRepository = userRepository, - themeParams = themeParams, - onDismiss = onDismiss - ) - - LaunchedEffect(themeParams) { - state.updateThemeParams(themeParams) - state.telegramProxy?.setThemeParams(themeParams) - } - - val locationPermissionLauncher = rememberLauncherForActivityResult( - ActivityResultContracts.RequestMultiplePermissions() - ) { permissions -> - val isGranted = permissions[Manifest.permission.ACCESS_FINE_LOCATION] == true || - permissions[Manifest.permission.ACCESS_COARSE_LOCATION] == true - if (isGranted) { - state.handleLocationRequest() - } else { - state.telegramProxy?.dispatchToWebView("location_requested", JSONObject().put("status", "failed")) - } - } - - LaunchedEffect(state) { - state.onRequestSystemLocationPermission = { - locationPermissionLauncher.launch( - arrayOf( - Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_COARSE_LOCATION - ) - ) - } - } - - val secureStorage = remember(context) { - try { - val sharedPrefs = context.getSharedPreferences("webapp_secure_storage", Context.MODE_PRIVATE) - val cryptoManager = CryptoManager() - object : MiniAppSecureStorage { - override fun save(key: String, value: String) { - cryptoManager.encrypt(value)?.let { sharedPrefs.edit().putString(key, it).apply() } - } - - override fun get(key: String): String? = - sharedPrefs.getString(key, null)?.let { cryptoManager.decrypt(it) } - - override fun get(keys: List): Map { - return keys.associateWith { key -> - sharedPrefs.getString(key, null)?.let { cryptoManager.decrypt(it) } - } - } - - override fun delete(key: String) { - sharedPrefs.edit().remove(key).apply() - } - - override fun delete(keys: List) { - val editor = sharedPrefs.edit() - keys.forEach { editor.remove(it) } - editor.apply() - } - - override fun getKeys(): List { - return sharedPrefs.all.keys.toList() - } - } - } catch (e: Exception) { - Log.e(TAG, "Failed to init secure storage", e) - null - } - } - - val window = activity?.window - if (window != null) { - SideEffect { - WindowCompat.setDecorFitsSystemWindows(window, false) - val insetsController = WindowCompat.getInsetsController(window, window.decorView) - window.statusBarColor = Color.Transparent.toArgb() - window.navigationBarColor = Color.Transparent.toArgb() - insetsController.isAppearanceLightStatusBars = - (state.topBarColor ?: colorScheme.surface).toArgb() > Color.DarkGray.toArgb() - insetsController.isAppearanceLightNavigationBars = - (state.bottomBarColor ?: colorScheme.surface).toArgb() > Color.DarkGray.toArgb() - } - } - - val statusBars = WindowInsets.statusBars - val navigationBars = WindowInsets.navigationBars - val displayCutout = WindowInsets.displayCutout - - LaunchedEffect(state.isFullscreen) { - snapshotFlow { - val topPx = if (state.isFullscreen) max(statusBars.getTop(density), displayCutout.getTop(density)) else 0 - val bottomPx = - if (state.isFullscreen) max(navigationBars.getBottom(density), displayCutout.getBottom(density)) else 0 - val leftPx = if (state.isFullscreen) max( - statusBars.getLeft(density, LayoutDirection.Ltr), - displayCutout.getLeft(density, LayoutDirection.Ltr) - ) else 0 - val rightPx = if (state.isFullscreen) max( - statusBars.getRight(density, LayoutDirection.Ltr), - displayCutout.getRight(density, LayoutDirection.Ltr) - ) else 0 - - val topDp = (topPx / density.density).toInt() - val bottomDp = (bottomPx / density.density).toInt() - val leftDp = (leftPx / density.density).toInt() - val rightDp = (rightPx / density.density).toInt() - - JSONObject().apply { - put("top", topDp) - put("bottom", bottomDp) - put("left", leftDp) - put("right", rightDp) - } - }.collect { safeArea -> - state.telegramProxy?.updateSafeAreas(safeArea, safeArea) - } - } - - LaunchedEffect(baseUrl, botUserId, chatId, state.isTOSVisible) { - if (!state.isTOSVisible) { - if (botUserId != 0L) { - state.isInitializing = true - val result = messageRepository.openWebApp(chatId, botUserId, baseUrl, themeParams) - if (result != null) { - state.launchId = result.launchId - state.currentUrl = result.url - } - state.isInitializing = false - } else { - state.currentUrl = baseUrl - state.isInitializing = false - } - } - } - - DisposableEffect(Unit) { - onDispose { - state.telegramProxy?.destroy() - activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED - if (window != null) { - val insetsController = WindowCompat.getInsetsController(window, window.decorView) - window.statusBarColor = Color.Transparent.toArgb() - val isSystemInDarkTheme = - context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES - insetsController.isAppearanceLightStatusBars = !isSystemInDarkTheme - window.navigationBarColor = Color.Transparent.toArgb() - insetsController.isAppearanceLightNavigationBars = !isSystemInDarkTheme - } - } - } - - rememberLauncherForActivityResult( - ActivityResultContracts.RequestPermission() - ) { isGranted -> - state.hasCameraPermission = isGranted - if (!isGranted) { - state.activeQrText = null - state.telegramProxy?.dispatchToWebView("scan_qr_popup_closed", JSONObject()) - } - } - - BackHandler { - if (state.showMenu) { - state.showMenu = false - } else if (state.activeQrText != null) { - state.activeQrText = null - state.telegramProxy?.dispatchToWebView("scan_qr_popup_closed", JSONObject()) - } else if (state.isBackButtonVisible) { - state.telegramProxy?.dispatchToWebView("back_button_pressed", JSONObject()) - } else if (state.webView?.canGoBack() == true) { - state.webView?.goBack() - } else if (state.isFullscreen) { - state.isFullscreen = false - state.telegramProxy?.dispatchToWebView("fullscreen_changed", JSONObject().put("is_fullscreen", false)) - } else { - state.handleClose() - } - } - - if (state.showClosingConfirmation) { - MiniAppClosingConfirmationDialog( - onConfirm = { - state.showClosingConfirmation = false - if (state.launchId != 0L) { - scope.launch { - messageRepository.closeWebApp(state.launchId) - } - } - - onDismiss() - }, - onDismiss = { state.showClosingConfirmation = false } - ) - } - - if (state.activeInvoiceSlug != null) { - InvoiceDialog( - slug = state.activeInvoiceSlug!!, - messageRepository = messageRepository, - onDismiss = { status -> - val slug = state.activeInvoiceSlug - state.activeInvoiceSlug = null - state.telegramProxy?.dispatchToWebView( - "invoice_closed", - JSONObject().put("slug", slug).put("status", status) - ) - } - ) - } - - state.activePopup?.let { popupState -> - MiniAppPopupDialog( - state = popupState, - onDismiss = { buttonId -> - state.activePopup = null - if (buttonId != null) { - state.telegramProxy?.dispatchToWebView("popup_closed", JSONObject().put("button_id", buttonId)) - } - } - ) - } - - state.showPermissionRequest?.let { request -> - MiniAppPermissionDialog( - request = request, - onDismiss = { state.showPermissionRequest = null } - ) - } - - state.activeCustomMethod?.let { request -> - MiniAppCustomMethodDialog( - request = request, - onDismiss = { state.activeCustomMethod = null } - ) - } - - MiniAppPermissionsBottomSheet( - isVisible = state.isPermissionsVisible, - permissions = state.botPermissions, - onDismiss = { state.onDismissPermissions() }, - onTogglePermission = { state.onTogglePermission(it) } - ) - - MiniAppTOSBottomSheet( - isVisible = state.isTOSVisible, - onDismiss = { onDismiss() }, - onAccept = { state.onAcceptTOS() } - ) - - if (!state.isTOSVisible) { - Surface( - modifier = Modifier.fillMaxSize(), - color = state.backgroundColor ?: MaterialTheme.colorScheme.surface - ) { - Box(modifier = Modifier.fillMaxSize()) { - Column(modifier = Modifier.fillMaxSize()) { - if (!state.isFullscreen) { - MiniAppTopBar( - headerText = state.headerText, - isBackButtonVisible = state.isBackButtonVisible, - isSettingsButtonVisible = state.isSettingsButtonVisible, - isInitializing = state.isInitializing, - topBarColor = state.topBarColor, - topBarTextColor = state.topBarTextColor, - accentColor = state.accentColor, - onBackClick = { - state.telegramProxy?.dispatchToWebView( - "back_button_pressed", - JSONObject() - ) - }, - onCloseClick = { state.handleClose() }, - onSettingsClick = { - state.telegramProxy?.dispatchToWebView( - "settings_button_pressed", - JSONObject() - ) - }, - onMenuClick = { state.showMenu = !state.showMenu } - ) - } - - Box(modifier = Modifier.weight(1f)) { - Column(modifier = Modifier.fillMaxSize()) { - MiniAppLoadingView( - isInitializing = state.isInitializing, - isLoading = state.isLoading, - progress = state.progress, - backgroundColor = state.backgroundColor - ) - - MiniAppWebView( - url = state.currentUrl, - acceptLanguage = webAppLanguage, - themeParams = state.themeParams, - host = state.createHost(secureStorage), - onWebViewCreated = { wv, proxy -> - state.webView = wv - state.telegramProxy = proxy - }, - onProgressChanged = { state.progress = it }, - onLoadingChanged = { state.isLoading = it }, - modifier = Modifier.fillMaxSize() - ) - } - - MiniAppFullscreenControls( - visible = state.isFullscreen, - onBackClick = { - state.telegramProxy?.dispatchToWebView( - "back_button_pressed", - JSONObject() - ) - }, - onMenuClick = { state.showMenu = !state.showMenu } - ) - } - - if (!state.isFullscreen) { - MiniAppBottomBar( - mainButtonState = state.mainButtonState, - secondaryButtonState = state.secondaryButtonState, - bottomBarColor = state.bottomBarColor, - onMainButtonClick = { - state.telegramProxy?.dispatchToWebView( - "main_button_pressed", - JSONObject() - ) - }, - onSecondaryButtonClick = { - state.telegramProxy?.dispatchToWebView( - "secondary_button_pressed", - JSONObject() - ) - } - ) - } - } - - MiniAppMenu( - visible = state.showMenu, - isFullscreen = state.isFullscreen, - url = state.currentUrl, - botUserId = botUserId, - botName = botName, - botAvatarPath = botAvatarPath, - context = context, - clipboardManager = clipboardManager, - onDismiss = { state.showMenu = false }, - onReload = { state.webView?.reload() } - ) - - MiniAppQrScanner( - qrText = state.activeQrText, - onCodeDetected = { code -> - state.activeQrText = null - state.telegramProxy?.dispatchToWebView("qr_text_received", JSONObject().put("data", code)) - }, - onBackClicked = { - state.activeQrText = null - state.telegramProxy?.dispatchToWebView("scan_qr_popup_closed", JSONObject()) - } - ) - } - } - } -} - -private fun Int.toHex(): String = String.format("#%06X", (0xFFFFFF and this)) diff --git a/presentation/src/main/java/org/monogram/presentation/features/webapp/TelegramWebAppHost.kt b/presentation/src/main/java/org/monogram/presentation/features/webapp/TelegramWebAppHost.kt deleted file mode 100644 index 4600bd72..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webapp/TelegramWebAppHost.kt +++ /dev/null @@ -1,92 +0,0 @@ -package org.monogram.presentation.features.webapp - -import org.json.JSONObject -import org.monogram.domain.models.webapp.WebAppPopupButton - -interface TelegramWebAppHost { - // Navigation & UI - fun onOpenLink(url: String, tryBrowser: Boolean, tryInstantView: Boolean) - fun onOpenTgLink(path: String) - fun onOpenInvoice(slug: String) - fun onClose(returnBack: Boolean) - fun onExpand() - fun onRequestFullscreen() - fun onExitFullscreen() - fun onToggleOrientationLock(locked: Boolean) - fun onAddToHomeScreen() - fun onCheckHomeScreen() - fun onShareToStory(mediaUrl: String, text: String?, widgetLink: JSONObject?) - - // Popups & Dialogs - fun onOpenPopup(title: String?, message: String, buttons: List, callbackId: String) - fun onOpenScanQrPopup(text: String?) - fun onCloseScanQrPopup() - fun onRequestPhone() - fun onRequestWriteAccess() - - // Button & Bar Setup - fun onSetupMainButton( - isVisible: Boolean, - isActive: Boolean, - text: String, - color: Int?, - textColor: Int?, - isProgressVisible: Boolean, - hasShineEffect: Boolean - ) - - fun onSetupSecondaryButton( - isVisible: Boolean, - isActive: Boolean, - text: String, - color: Int?, - textColor: Int?, - isProgressVisible: Boolean, - hasShineEffect: Boolean, - position: String - ) - - fun onSetBackButtonVisible(visible: Boolean) - fun onSetSettingsButtonVisible(visible: Boolean) - fun onSetBackgroundColor(color: Int) - fun onSetHeaderColor(colorKey: String?, customColor: Int?) - fun onResetHeaderColor() - fun onSetHeaderText(text: String) - fun onSetBottomBarColor(color: Int) - fun onResetBottomBarColor() - fun onSetupClosingBehavior(needConfirmation: Boolean) - fun onSetupSwipeBehavior(allowVertical: Boolean) - - // Data & Sensors - fun onSwitchInlineQuery(query: String, chatTypes: List) - fun onSendWebViewData(data: String) - fun onReadClipboard(reqId: String) - fun onInvokeCustomMethod(reqId: String, method: String, params: String) - fun onSendPreparedMessage(id: String) - fun onFileDownloadRequested(url: String, fileName: String) - - // Storage (Device & Secure) - fun onDeviceStorageSave(key: String, value: String) - fun onDeviceStorageGet(key: String) - fun onDeviceStorageDelete(key: String) - fun onSecureStorageSave(key: String, value: String) - fun onSecureStorageGet(key: String) - fun onSecureStorageDelete(key: String) - - // Biometry - fun onBiometryGetInfo() - fun onBiometryRequestAccess(reason: String?) - fun onBiometryRequestAuth(reason: String?) - fun onBiometryUpdateToken(token: String) - fun onBiometryOpenSettings() - - // Location - fun onRequestLocation() - fun onCheckLocation() - fun onOpenLocationSettings() - - // Others - fun onSetEmojiStatus(customEmojiId: Long, duration: Int) - fun onRequestEmojiStatusAccess() - fun onVerifyAge(age: Double) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webapp/TelegramWebviewProxy.kt b/presentation/src/main/java/org/monogram/presentation/features/webapp/TelegramWebviewProxy.kt deleted file mode 100644 index 9e9599d8..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webapp/TelegramWebviewProxy.kt +++ /dev/null @@ -1,593 +0,0 @@ -package org.monogram.presentation.features.webapp - -import android.content.Context -import android.hardware.Sensor -import android.hardware.SensorEvent -import android.hardware.SensorEventListener -import android.hardware.SensorManager -import android.os.Build -import android.os.VibrationEffect -import android.os.Vibrator -import android.os.VibratorManager -import android.util.Log -import android.view.inputmethod.InputMethodManager -import android.webkit.JavascriptInterface -import android.webkit.WebView -import androidx.core.graphics.toColorInt -import org.json.JSONObject -import org.monogram.domain.models.webapp.ThemeParams -import org.monogram.domain.models.webapp.WebAppEvent -import org.monogram.domain.models.webapp.WebAppPopupButton -import java.util.concurrent.ConcurrentHashMap - -private const val TAG = "MiniAppLog" - -class TelegramWebviewProxy( - private val context: Context, - private val webView: WebView, - private var themeParams: ThemeParams, - private val host: TelegramWebAppHost -) { - private val vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - (context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager).defaultVibrator - } else { - @Suppress("DEPRECATION") - context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator - } - private val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager - private val activeSensors = ConcurrentHashMap() - - private var lastSafeArea = JSONObject() - private var lastContentSafeArea = JSONObject() - - init { - webView.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> - updateViewport() - } - } - - fun setThemeParams(newParams: ThemeParams) { - if (this.themeParams == newParams) return - this.themeParams = newParams - dispatchToWebView( - "theme_changed", - JSONObject().put("theme_params", JSONObject(newParams.toJson())) - ) - injectCSSVars(newParams.toJson()) - } - - fun updateSafeAreas(safeArea: JSONObject, contentSafeArea: JSONObject) { - if (lastSafeArea.toString() == safeArea.toString() && - lastContentSafeArea.toString() == contentSafeArea.toString() - ) return - - lastSafeArea = safeArea - lastContentSafeArea = contentSafeArea - - dispatchToWebView("safe_area_changed", safeArea) - dispatchToWebView("content_safe_area_changed", contentSafeArea) - - injectSafeAreaCSS(safeArea, contentSafeArea) - } - - private fun injectSafeAreaCSS(safeArea: JSONObject, contentSafeArea: JSONObject) { - val script = """ - document.documentElement.style.setProperty('--tg-safe-area-inset-top', '${safeArea.optInt("top")}px'); - document.documentElement.style.setProperty('--tg-safe-area-inset-bottom', '${safeArea.optInt("bottom")}px'); - document.documentElement.style.setProperty('--tg-safe-area-inset-left', '${safeArea.optInt("left")}px'); - document.documentElement.style.setProperty('--tg-safe-area-inset-right', '${safeArea.optInt("right")}px'); - document.documentElement.style.setProperty('--tg-content-safe-area-inset-top', '${contentSafeArea.optInt("top")}px'); - document.documentElement.style.setProperty('--tg-content-safe-area-inset-bottom', '${ - contentSafeArea.optInt( - "bottom" - ) - }px'); - document.documentElement.style.setProperty('--tg-content-safe-area-inset-left', '${contentSafeArea.optInt("left")}px'); - document.documentElement.style.setProperty('--tg-content-safe-area-inset-right', '${contentSafeArea.optInt("right")}px'); - """.trimIndent() - webView.evaluateJavascript(script, null) - } - - @JavascriptInterface - fun postEvent(eventType: String, eventData: String?) { - Log.d(TAG, "postEvent: $eventType | Data: $eventData") - webView.post { - try { - val json = safeJson(eventData) - val event = parseEvent(eventType, json) - if (event != null) { - handleEvent(event) - } else { - Log.w(TAG, "Unhandled event: $eventType") - } - } catch (e: Exception) { - Log.e(TAG, "Error handling $eventType", e) - } - } - } - - private fun parseEvent(eventType: String, data: JSONObject): WebAppEvent? { - return when (eventType) { - "web_app_ready" -> WebAppEvent.Ready - "web_app_close" -> WebAppEvent.Close(data.optBoolean("return_back", false)) - "web_app_expand" -> WebAppEvent.Expand - "web_app_request_viewport" -> WebAppEvent.RequestViewport - "web_app_request_theme" -> WebAppEvent.RequestTheme - "web_app_set_background_color" -> WebAppEvent.SetBackgroundColor(data.optString("color", "#ffffff")) - "web_app_set_header_color" -> WebAppEvent.SetHeaderColor( - data.optString("color_key").takeIf { it.isNotEmpty() }, - data.optString("color").takeIf { it.isNotEmpty() }) - - "web_app_set_header_text" -> WebAppEvent.SetHeaderText(data.optString("text")) - "web_app_set_bottom_bar_color" -> WebAppEvent.SetBottomBarColor(data.optString("color")) - "web_app_setup_main_button" -> WebAppEvent.SetupMainButton( - data.optBoolean("is_visible"), data.optBoolean("is_active"), - data.optString("text"), data.optString("color").takeIf { it.isNotEmpty() }, - data.optString("text_color").takeIf { it.isNotEmpty() }, - data.optBoolean("is_progress_visible"), data.optBoolean("has_shine_effect") - ) - - "web_app_setup_secondary_button" -> WebAppEvent.SetupSecondaryButton( - data.optBoolean("is_visible"), data.optBoolean("is_active"), - data.optString("text"), data.optString("color").takeIf { it.isNotEmpty() }, - data.optString("text_color").takeIf { it.isNotEmpty() }, - data.optBoolean("is_progress_visible"), data.optBoolean("has_shine_effect"), - data.optString("position", "left") - ) - - "web_app_setup_back_button" -> WebAppEvent.SetupBackButton(data.optBoolean("is_visible")) - "web_app_setup_settings_button" -> WebAppEvent.SetupSettingsButton(data.optBoolean("is_visible")) - "web_app_open_popup" -> { - val buttons = mutableListOf() - data.optJSONArray("buttons")?.let { arr -> - for (i in 0 until arr.length()) { - val b = arr.getJSONObject(i) - buttons.add( - WebAppPopupButton( - b.getString("id"), - b.optString("type"), - b.getString("text"), - b.optBoolean("is_destructive") - ) - ) - } - } - WebAppEvent.OpenPopup( - data.optString("title").takeIf { it.isNotEmpty() }, - data.getString("message"), - buttons - ) - } - - "web_app_open_link" -> WebAppEvent.OpenLink( - data.optString("url"), - data.optBoolean("try_browser"), - data.optBoolean("try_instant_view") - ) - - "web_app_open_tg_link" -> WebAppEvent.OpenTgLink(data.optString("path_full")) - "web_app_open_invoice" -> WebAppEvent.OpenInvoice(data.optString("slug")) - "web_app_open_scan_qr_popup" -> WebAppEvent.OpenScanQrPopup(data.optString("text")) - "web_app_close_scan_qr_popup" -> WebAppEvent.CloseScanQrPopup - "web_app_setup_closing_behavior" -> WebAppEvent.SetupClosingBehavior(data.optBoolean("need_confirmation")) - "web_app_setup_swipe_behavior" -> WebAppEvent.SetupSwipeBehavior(data.optBoolean("allow_vertical_swipe")) - "web_app_trigger_haptic_feedback" -> WebAppEvent.TriggerHapticFeedback( - data.optString("type"), - data.optString("impact_style").takeIf { it.isNotEmpty() }, - data.optString("notification_type").takeIf { it.isNotEmpty() }) - - "web_app_start_accelerometer" -> WebAppEvent.StartAccelerometer(data.optLong("refresh_rate", 1000)) - "web_app_stop_accelerometer" -> WebAppEvent.StopAccelerometer - "web_app_start_gyroscope" -> WebAppEvent.StartGyroscope(data.optLong("refresh_rate", 1000)) - "web_app_stop_gyroscope" -> WebAppEvent.StopGyroscope - "web_app_start_device_orientation" -> WebAppEvent.StartDeviceOrientation( - data.optLong("refresh_rate", 1000), - data.optBoolean("need_absolute") - ) - - "web_app_stop_device_orientation" -> WebAppEvent.StopDeviceOrientation - "web_app_toggle_orientation_lock" -> WebAppEvent.ToggleOrientationLock(data.optBoolean("locked")) - "web_app_request_fullscreen" -> WebAppEvent.RequestFullscreen - "web_app_exit_fullscreen" -> WebAppEvent.ExitFullscreen - "web_app_data_send" -> WebAppEvent.DataSend(data.optString("data")) - "web_app_switch_inline_query" -> { - val types = mutableListOf() - data.optJSONArray("chat_types")?.let { arr -> - for (i in 0 until arr.length()) types.add(arr.getString(i)) - } - WebAppEvent.SwitchInlineQuery(data.optString("query"), types) - } - - "web_app_read_text_from_clipboard" -> WebAppEvent.ReadTextFromClipboard(data.getString("req_id")) - "web_app_request_write_access" -> WebAppEvent.RequestWriteAccess - "web_app_request_phone" -> WebAppEvent.RequestPhone - "web_app_invoke_custom_method" -> WebAppEvent.InvokeCustomMethod( - data.getString("req_id"), - data.getString("method"), - data.optJSONObject("params")?.toString() ?: "{}" - ) - - "web_app_send_prepared_message" -> WebAppEvent.SendPreparedMessage(data.optString("id")) - "web_app_request_file_download" -> WebAppEvent.RequestFileDownload( - data.optString("url"), - data.optString("file_name") - ) - - "web_app_device_storage_save_key" -> WebAppEvent.DeviceStorageSave( - data.getString("key"), - data.getString("value") - ) - - "web_app_device_storage_get_key" -> WebAppEvent.DeviceStorageGet(data.getString("key")) - "web_app_device_storage_remove_key" -> WebAppEvent.DeviceStorageRemove(data.getString("key")) - "web_app_secure_storage_save_key" -> WebAppEvent.SecureStorageSave( - data.getString("key"), - data.getString("value") - ) - - "web_app_secure_storage_get_key" -> WebAppEvent.SecureStorageGet(data.getString("key")) - "web_app_secure_storage_remove_key" -> WebAppEvent.SecureStorageRemove(data.getString("key")) - "web_app_biometry_get_info" -> WebAppEvent.BiometryGetInfo - "web_app_biometry_request_access" -> WebAppEvent.BiometryRequestAccess(data.optString("reason")) - "web_app_biometry_request_auth" -> WebAppEvent.BiometryRequestAuth(data.optString("reason")) - "web_app_biometry_update_token" -> WebAppEvent.BiometryUpdateToken(data.getString("token")) - "web_app_biometry_open_settings" -> WebAppEvent.BiometryOpenSettings - "web_app_share_to_story" -> WebAppEvent.ShareToStory( - data.getString("media_url"), - data.optString("text"), - data.optJSONObject("widget_link")?.toString() - ) - - "web_app_set_emoji_status" -> WebAppEvent.SetEmojiStatus( - data.optLong("custom_emoji_id"), - data.optInt("duration") - ) - - "web_app_request_emoji_status_access" -> WebAppEvent.RequestEmojiStatusAccess - "web_app_add_to_home_screen" -> WebAppEvent.AddToHomeScreen - "web_app_check_home_screen" -> WebAppEvent.CheckHomeScreen - "web_app_request_location" -> WebAppEvent.RequestLocation - "web_app_check_location" -> WebAppEvent.CheckLocation - "web_app_open_location_settings" -> WebAppEvent.OpenLocationSettings - "web_app_verify_age" -> WebAppEvent.VerifyAge(data.optDouble("age")) - "web_app_request_safe_area" -> WebAppEvent.RequestSafeArea - "web_app_request_content_safe_area" -> WebAppEvent.RequestContentSafeArea - "web_app_hide_keyboard" -> WebAppEvent.HideKeyboard - else -> null - } - } - - private fun handleEvent(event: WebAppEvent) { - when (event) { - is WebAppEvent.Ready -> { - dispatchToWebView("theme_changed", JSONObject().put("theme_params", JSONObject(themeParams.toJson()))) - updateViewport() - injectCSSVars(themeParams.toJson()) - dispatchToWebView("safe_area_changed", lastSafeArea) - dispatchToWebView("content_safe_area_changed", lastContentSafeArea) - injectSafeAreaCSS(lastSafeArea, lastContentSafeArea) - } - - is WebAppEvent.Close -> { - host.onClose(event.returnBack) - host.onResetHeaderColor() - host.onResetBottomBarColor() - } - - is WebAppEvent.Expand -> { - updateViewport() - host.onExpand() - } - - is WebAppEvent.RequestViewport -> updateViewport() - is WebAppEvent.RequestTheme -> dispatchToWebView( - "theme_changed", - JSONObject().put("theme_params", JSONObject(themeParams.toJson())) - ) - - is WebAppEvent.SetBackgroundColor -> host.onSetBackgroundColor(parseColor(event.color)) - is WebAppEvent.SetHeaderColor -> host.onSetHeaderColor(event.colorKey, event.color?.let { parseColor(it) }) - is WebAppEvent.SetHeaderText -> host.onSetHeaderText(event.text) - is WebAppEvent.SetBottomBarColor -> host.onSetBottomBarColor(parseColor(event.color)) - is WebAppEvent.SetupMainButton -> host.onSetupMainButton( - event.isVisible, - event.isActive, - event.text, - event.color?.let { parseColor(it) }, - event.textColor?.let { parseColor(it) }, - event.isProgressVisible, - event.hasShineEffect - ) - - is WebAppEvent.SetupSecondaryButton -> host.onSetupSecondaryButton( - event.isVisible, - event.isActive, - event.text, - event.color?.let { parseColor(it) }, - event.textColor?.let { parseColor(it) }, - event.isProgressVisible, - event.hasShineEffect, - event.position - ) - - is WebAppEvent.SetupBackButton -> host.onSetBackButtonVisible(event.isVisible) - is WebAppEvent.SetupSettingsButton -> host.onSetSettingsButtonVisible(event.isVisible) - is WebAppEvent.OpenPopup -> { - host.onOpenPopup(event.title, event.message, event.buttons, "") - } - - is WebAppEvent.OpenLink -> host.onOpenLink(event.url, event.tryBrowser, event.tryInstantView) - is WebAppEvent.OpenTgLink -> host.onOpenTgLink(event.pathFull) - is WebAppEvent.OpenInvoice -> host.onOpenInvoice(event.slug) - is WebAppEvent.OpenScanQrPopup -> host.onOpenScanQrPopup(event.text) - is WebAppEvent.CloseScanQrPopup -> host.onCloseScanQrPopup() - is WebAppEvent.SetupClosingBehavior -> host.onSetupClosingBehavior(event.needConfirmation) - is WebAppEvent.SetupSwipeBehavior -> host.onSetupSwipeBehavior(event.allowVerticalSwipe) - is WebAppEvent.TriggerHapticFeedback -> handleHaptics(event) - is WebAppEvent.StartAccelerometer -> startSensor( - Sensor.TYPE_ACCELEROMETER, - event.refreshRate, - "accelerometer" - ) - - is WebAppEvent.StopAccelerometer -> stopSensor(Sensor.TYPE_ACCELEROMETER, "accelerometer") - is WebAppEvent.StartGyroscope -> startSensor(Sensor.TYPE_GYROSCOPE, event.refreshRate, "gyroscope") - is WebAppEvent.StopGyroscope -> stopSensor(Sensor.TYPE_GYROSCOPE, "gyroscope") - is WebAppEvent.StartDeviceOrientation -> startDeviceOrientation(event.refreshRate, event.needAbsolute) - is WebAppEvent.StopDeviceOrientation -> stopSensor(Sensor.TYPE_ROTATION_VECTOR, "device_orientation") - is WebAppEvent.ToggleOrientationLock -> host.onToggleOrientationLock(event.locked) - is WebAppEvent.RequestFullscreen -> { - host.onRequestFullscreen() - dispatchToWebView("fullscreen_changed", JSONObject().put("is_fullscreen", true)) - } - - is WebAppEvent.ExitFullscreen -> { - host.onExitFullscreen() - dispatchToWebView("fullscreen_changed", JSONObject().put("is_fullscreen", false)) - } - - is WebAppEvent.DataSend -> host.onSendWebViewData(event.data) - is WebAppEvent.SwitchInlineQuery -> host.onSwitchInlineQuery(event.query, event.chatTypes) - is WebAppEvent.ReadTextFromClipboard -> host.onReadClipboard(event.reqId) - is WebAppEvent.RequestWriteAccess -> host.onRequestWriteAccess() - is WebAppEvent.RequestPhone -> host.onRequestPhone() - is WebAppEvent.InvokeCustomMethod -> host.onInvokeCustomMethod(event.reqId, event.method, event.params) - is WebAppEvent.SendPreparedMessage -> host.onSendPreparedMessage(event.id) - is WebAppEvent.RequestFileDownload -> host.onFileDownloadRequested(event.url, event.fileName) - is WebAppEvent.DeviceStorageSave -> host.onDeviceStorageSave(event.key, event.value) - is WebAppEvent.DeviceStorageGet -> host.onDeviceStorageGet(event.key) - is WebAppEvent.DeviceStorageRemove -> host.onDeviceStorageDelete(event.key) - is WebAppEvent.SecureStorageSave -> host.onSecureStorageSave(event.key, event.value) - is WebAppEvent.SecureStorageGet -> host.onSecureStorageGet(event.key) - is WebAppEvent.SecureStorageRemove -> host.onSecureStorageDelete(event.key) - is WebAppEvent.BiometryGetInfo -> host.onBiometryGetInfo() - is WebAppEvent.BiometryRequestAccess -> host.onBiometryRequestAccess(event.reason) - is WebAppEvent.BiometryRequestAuth -> host.onBiometryRequestAuth(event.reason) - is WebAppEvent.BiometryUpdateToken -> host.onBiometryUpdateToken(event.token) - is WebAppEvent.BiometryOpenSettings -> host.onBiometryOpenSettings() - is WebAppEvent.ShareToStory -> host.onShareToStory( - event.mediaUrl, - event.text, - event.widgetLink?.let { JSONObject(it) }) - - is WebAppEvent.SetEmojiStatus -> host.onSetEmojiStatus(event.customEmojiId, event.duration) - is WebAppEvent.RequestEmojiStatusAccess -> host.onRequestEmojiStatusAccess() - is WebAppEvent.AddToHomeScreen -> host.onAddToHomeScreen() - is WebAppEvent.CheckHomeScreen -> host.onCheckHomeScreen() - is WebAppEvent.RequestLocation -> host.onRequestLocation() - is WebAppEvent.CheckLocation -> host.onCheckLocation() - is WebAppEvent.OpenLocationSettings -> host.onOpenLocationSettings() - is WebAppEvent.VerifyAge -> host.onVerifyAge(event.age) - is WebAppEvent.RequestSafeArea -> dispatchToWebView("safe_area_changed", lastSafeArea) - is WebAppEvent.RequestContentSafeArea -> dispatchToWebView("content_safe_area_changed", lastContentSafeArea) - is WebAppEvent.HideKeyboard -> { - val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager - imm?.hideSoftInputFromWindow(webView.windowToken, 0) - } - } - } - - fun dispatchToWebView(eventType: String, eventData: JSONObject?) { - Log.d(TAG, "dispatchToWebView: $eventType | Data: $eventData") - val data = eventData?.toString() ?: "{}" - val script = - "if (window.Telegram && window.Telegram.WebView && window.Telegram.WebView.receiveEvent) { window.Telegram.WebView.receiveEvent('$eventType', $data); }" - webView.evaluateJavascript(script, null) - } - - private fun updateViewport() { - val density = context.resources.displayMetrics.density - val height = (webView.height / density).toInt() - val data = JSONObject().apply { - put("height", height) - put("is_state_stable", true) - put("is_expanded", true) - } - dispatchToWebView("viewport_changed", data) - - val script = """ - document.documentElement.style.setProperty('--tg-viewport-height', '${height}px'); - document.documentElement.style.setProperty('--tg-viewport-stable-height', '${height}px'); - """.trimIndent() - webView.evaluateJavascript(script, null) - } - - private fun injectCSSVars(themeParamsJson: String) { - try { - val json = JSONObject(themeParamsJson) - val sb = StringBuilder("(function() {") - val keys = json.keys() - while (keys.hasNext()) { - val key = keys.next() - val value = json.optString(key) - if (value.isNotEmpty() && value != "null") { - val cssKey = key.replace("_", "-") - sb.append("document.documentElement.style.setProperty('--tg-theme-$cssKey', '$value');") - } - } - sb.append("})();") - webView.evaluateJavascript(sb.toString(), null) - } catch (e: Exception) { - Log.e(TAG, "CSS Inject Error", e) - } - } - - private fun startSensor(type: Int, refreshMs: Long, eventName: String) { - val delay = (refreshMs * 1000).toInt().coerceAtLeast(SensorManager.SENSOR_DELAY_GAME) - - stopSensor(type, eventName) - - val listener = object : SensorEventListener { - override fun onSensorChanged(event: SensorEvent) { - val params = JSONObject() - when (type) { - Sensor.TYPE_ACCELEROMETER, Sensor.TYPE_GYROSCOPE -> { - params.put("x", event.values[0]) - params.put("y", event.values[1]) - params.put("z", event.values[2]) - } - } - dispatchToWebView("${eventName}_changed", params) - } - - override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {} - } - - val sensor = sensorManager.getDefaultSensor(type) - if (sensor != null) { - sensorManager.registerListener(listener, sensor, delay) - activeSensors[type] = listener - dispatchToWebView("${eventName}_started", JSONObject()) - } else { - dispatchToWebView("${eventName}_failed", JSONObject().put("error", "UNSUPPORTED")) - } - } - - private fun startDeviceOrientation(refreshMs: Long, needAbsolute: Boolean) { - val type = if (needAbsolute) Sensor.TYPE_ROTATION_VECTOR else Sensor.TYPE_GAME_ROTATION_VECTOR - val delay = (refreshMs * 1000).toInt().coerceAtLeast(SensorManager.SENSOR_DELAY_GAME) - - stopSensor(Sensor.TYPE_ROTATION_VECTOR, "") - stopSensor(Sensor.TYPE_GAME_ROTATION_VECTOR, "") - - val listener = object : SensorEventListener { - override fun onSensorChanged(event: SensorEvent) { - val rotationMatrix = FloatArray(9) - SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values) - val orientation = FloatArray(3) - SensorManager.getOrientation(rotationMatrix, orientation) - - var alpha = Math.toDegrees(orientation[0].toDouble()) // Azimuth - if (alpha < 0) alpha += 360.0 - val beta = Math.toDegrees(orientation[1].toDouble()) // Pitch - val gamma = Math.toDegrees(orientation[2].toDouble()) // Roll - - val params = JSONObject() - params.put("alpha", alpha) - params.put("beta", beta) - params.put("gamma", gamma) - params.put("absolute", needAbsolute) - - dispatchToWebView("device_orientation_changed", params) - } - - override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {} - } - - val sensor = sensorManager.getDefaultSensor(type) - if (sensor != null) { - sensorManager.registerListener(listener, sensor, delay) - activeSensors[type] = listener - dispatchToWebView("device_orientation_started", JSONObject()) - } else { - dispatchToWebView("device_orientation_failed", JSONObject().put("error", "UNSUPPORTED")) - } - } - - private fun stopSensor(type: Int, eventName: String) { - if (eventName == "device_orientation") { - activeSensors.remove(Sensor.TYPE_ROTATION_VECTOR)?.let { sensorManager.unregisterListener(it) } - activeSensors.remove(Sensor.TYPE_GAME_ROTATION_VECTOR)?.let { sensorManager.unregisterListener(it) } - dispatchToWebView("device_orientation_stopped", JSONObject()) - return - } - - activeSensors.remove(type)?.let { - sensorManager.unregisterListener(it) - dispatchToWebView("${eventName}_stopped", JSONObject()) - } - } - - fun destroy() { - activeSensors.values.forEach { sensorManager.unregisterListener(it) } - activeSensors.clear() - } - - private fun handleHaptics(event: WebAppEvent.TriggerHapticFeedback) { - val effect: VibrationEffect? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - when (event.type) { - "impact" -> { - when (event.impactStyle) { - "light" -> VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK) - "medium" -> VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK) - "heavy" -> VibrationEffect.createPredefined(VibrationEffect.EFFECT_HEAVY_CLICK) - "rigid" -> VibrationEffect.createPredefined(VibrationEffect.EFFECT_DOUBLE_CLICK) - "soft" -> VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK) - else -> VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK) - } - } - - "notification" -> { - when (event.notificationType) { - "error" -> VibrationEffect.createWaveform(longArrayOf(0, 50, 50, 50), -1) - "success" -> VibrationEffect.createWaveform(longArrayOf(0, 50, 50, 50), -1) - "warning" -> VibrationEffect.createWaveform(longArrayOf(0, 50, 100, 50), -1) - else -> null - } - } - "selection_change" -> VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK) - else -> null - } - } else { - null - } - - if (effect != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - vibrator.vibrate(effect) - } else { - @Suppress("DEPRECATION") - vibrator.vibrate(10) - } - } - - private fun safeJson(jsonStr: String?): JSONObject { - if (jsonStr.isNullOrBlank()) return JSONObject() - return try { - JSONObject(jsonStr) - } catch (e: Exception) { - JSONObject() - } - } - - private fun parseColor(color: String): Int = color.toColorInt() or -0x1000000 - - private fun ThemeParams.toJson(): String = - JSONObject().apply { - colorScheme?.let { put("color_scheme", it) } - put("bg_color", backgroundColor) - put("secondary_bg_color", secondaryBackgroundColor) - put("header_bg_color", headerBackgroundColor) - put("bottom_bar_bg_color", bottomBarBackgroundColor) - put("section_bg_color", sectionBackgroundColor) - put("section_separator_color", sectionSeparatorColor) - put("text_color", textColor) - put("accent_text_color", accentTextColor) - put("section_header_text_color", sectionHeaderTextColor) - put("subtitle_text_color", subtitleTextColor) - put("destructive_text_color", destructiveTextColor) - put("hint_color", hintColor) - put("link_color", linkColor) - put("button_color", buttonColor) - put("button_text_color", buttonTextColor) - }.toString() -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/InvoiceDialog.kt b/presentation/src/main/java/org/monogram/presentation/features/webapp/components/InvoiceDialog.kt deleted file mode 100644 index ba031206..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/InvoiceDialog.kt +++ /dev/null @@ -1,213 +0,0 @@ -package org.monogram.presentation.features.webapp.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import coil3.compose.AsyncImage -import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.launch -import org.monogram.domain.models.webapp.InvoiceModel -import org.monogram.domain.repository.MessageRepository - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun InvoiceDialog( - slug: String? = null, - chatId: Long? = null, - messageId: Long? = null, - messageRepository: MessageRepository, - onDismiss: (status: String) -> Unit -) { - var invoice by remember { mutableStateOf(null) } - var isLoading by remember { mutableStateOf(true) } - var isPaying by remember { mutableStateOf(false) } - val scope = rememberCoroutineScope() - - var photoPath by remember { mutableStateOf(null) } - var progress by remember { mutableStateOf(0f) } - - LaunchedEffect(slug, chatId, messageId) { - val inv = messageRepository.getInvoice(slug = slug, chatId = chatId, messageId = messageId) - invoice = inv - isLoading = false - - inv?.photoUrl?.let { fileIdStr -> - val fileId = fileIdStr.toIntOrNull() - if (fileId != null) { - photoPath = messageRepository.getFilePath(fileId) - if (photoPath == null) { - messageRepository.downloadFile(fileId) - launch { - messageRepository.messageDownloadProgressFlow - .filter { it.first == fileId.toLong() } - .collect { progress = it.second } - } - messageRepository.messageDownloadCompletedFlow - .filter { it.first == fileId.toLong() } - .collect { (_, _, completedPath) -> photoPath = completedPath } - } - } else { - photoPath = fileIdStr - } - } - } - - ModalBottomSheet( - onDismissRequest = { if (!isPaying) onDismiss("cancelled") }, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 40.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - if (isLoading) { - CircularProgressIndicator(modifier = Modifier.padding(32.dp)) - } else if (invoice == null) { - Text("Failed to load invoice", color = MaterialTheme.colorScheme.error) - Spacer(Modifier.height(16.dp)) - Button( - onClick = { onDismiss("failed") }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { Text("Close") } - } else { - val inv = invoice!! - if (photoPath != null) { - AsyncImage( - model = photoPath, - contentDescription = null, - modifier = Modifier - .size(120.dp) - .clip(RoundedCornerShape(16.dp)) - .background(MaterialTheme.colorScheme.surfaceVariant), - contentScale = ContentScale.Crop - ) - } else { - Box( - modifier = Modifier - .size(120.dp) - .clip(RoundedCornerShape(16.dp)) - .background(MaterialTheme.colorScheme.surfaceVariant), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator( - progress = { progress }, - modifier = Modifier, - color = ProgressIndicatorDefaults.circularColor, - strokeWidth = 4.dp, - trackColor = ProgressIndicatorDefaults.circularIndeterminateTrackColor, - strokeCap = ProgressIndicatorDefaults.CircularDeterminateStrokeCap, - ) - } - } - - Spacer(Modifier.height(16.dp)) - - Text( - inv.title, - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - textAlign = TextAlign.Center - ) - Spacer(Modifier.height(8.dp)) - Text( - inv.description, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center - ) - Spacer(Modifier.height(24.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text("Total Amount", style = MaterialTheme.typography.titleMedium) - Text( - "${inv.currency} ${inv.totalAmount / 100.0}", - style = MaterialTheme.typography.headlineSmall, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) - } - - if (inv.isTest) { - Spacer(Modifier.height(8.dp)) - Text( - "TEST PAYMENT", - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.error, - fontWeight = FontWeight.Bold - ) - } - - Spacer(Modifier.height(32.dp)) - - Button( - onClick = { - isPaying = true - scope.launch { - val success = - messageRepository.payInvoice(slug = slug, chatId = chatId, messageId = messageId) - isPaying = false - if (success) { - onDismiss("paid") - } - } - }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - enabled = !isPaying, - shape = RoundedCornerShape(16.dp) - ) { - if (isPaying) { - CircularProgressIndicator( - modifier = Modifier.size(20.dp), - color = MaterialTheme.colorScheme.onPrimary, - strokeWidth = 2.dp - ) - } else { - Text( - "Pay ${inv.currency} ${inv.totalAmount / 100.0}", - fontSize = 16.sp, - fontWeight = FontWeight.Bold - ) - } - } - - Spacer(Modifier.height(12.dp)) - - OutlinedButton( - onClick = { onDismiss("cancelled") }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - enabled = !isPaying, - shape = RoundedCornerShape(16.dp) - ) { - Text("Cancel", fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppBottomBar.kt b/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppBottomBar.kt deleted file mode 100644 index 37a163e0..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppBottomBar.kt +++ /dev/null @@ -1,99 +0,0 @@ -package org.monogram.presentation.features.webapp.components - -import androidx.compose.foundation.layout.* -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp -import org.monogram.presentation.features.webapp.MainButtonState -import org.monogram.presentation.features.webapp.SecondaryButtonState - -@Composable -fun MiniAppBottomBar( - mainButtonState: MainButtonState, - secondaryButtonState: SecondaryButtonState, - bottomBarColor: Color?, - onMainButtonClick: () -> Unit, - onSecondaryButtonClick: () -> Unit -) { - if (mainButtonState.isVisible || secondaryButtonState.isVisible) { - Surface( - color = bottomBarColor ?: MaterialTheme.colorScheme.surface, - tonalElevation = 2.dp, - modifier = Modifier.fillMaxWidth() - ) { - Column(modifier = Modifier.navigationBarsPadding()) { - val isHorizontal = - secondaryButtonState.position == "left" || secondaryButtonState.position == "right" - - if (isHorizontal) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - if (secondaryButtonState.position == "left" && secondaryButtonState.isVisible) { - SecondaryButton( - state = secondaryButtonState, - onClick = onSecondaryButtonClick, - modifier = Modifier.weight(1f) - ) - } - - if (mainButtonState.isVisible) { - MainButton( - state = mainButtonState, - onClick = onMainButtonClick, - modifier = Modifier.weight(1f) - ) - } - - if (secondaryButtonState.position == "right" && secondaryButtonState.isVisible) { - SecondaryButton( - state = secondaryButtonState, - onClick = onSecondaryButtonClick, - modifier = Modifier.weight(1f) - ) - } - } - } else { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp), - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - if (secondaryButtonState.position == "top" && secondaryButtonState.isVisible) { - SecondaryButton( - state = secondaryButtonState, - onClick = onSecondaryButtonClick, - modifier = Modifier.fillMaxWidth() - ) - } - - if (mainButtonState.isVisible) { - MainButton( - state = mainButtonState, - onClick = onMainButtonClick, - modifier = Modifier.fillMaxWidth() - ) - } - - if (secondaryButtonState.position == "bottom" && secondaryButtonState.isVisible) { - SecondaryButton( - state = secondaryButtonState, - onClick = onSecondaryButtonClick, - modifier = Modifier.fillMaxWidth() - ) - } - } - } - } - } - } else { - Spacer(Modifier.navigationBarsPadding()) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppButtons.kt b/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppButtons.kt deleted file mode 100644 index ccb47975..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppButtons.kt +++ /dev/null @@ -1,109 +0,0 @@ -package org.monogram.presentation.features.webapp.components - -import androidx.compose.animation.core.* -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.drawWithContent -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp -import org.monogram.presentation.features.webapp.MainButtonState -import org.monogram.presentation.features.webapp.SecondaryButtonState - -@Composable -fun MainButton( - state: MainButtonState, - onClick: () -> Unit, - modifier: Modifier = Modifier, - defaultColor: Color = MaterialTheme.colorScheme.primary, - defaultTextColor: Color = MaterialTheme.colorScheme.onPrimary -) { - val infiniteTransition = rememberInfiniteTransition(label = "shine") - val shineOffset by infiniteTransition.animateFloat( - initialValue = -1f, - targetValue = 2f, - animationSpec = infiniteRepeatable( - animation = tween(durationMillis = 2000, easing = LinearEasing), - repeatMode = RepeatMode.Restart - ), - label = "shineOffset" - ) - - Button( - onClick = onClick, - modifier = modifier.then( - if (state.hasShineEffect) { - Modifier - .clip(MaterialTheme.shapes.medium) - .drawWithContent { - drawContent() - val shineWidth = size.width * 0.5f - drawRect( - brush = Brush.linearGradient( - colors = listOf( - Color.Transparent, - Color.White.copy(alpha = 0.25f), - Color.Transparent, - ), - start = Offset(x = shineOffset * size.width - shineWidth, y = 0f), - end = Offset(x = shineOffset * size.width, y = size.height) - ) - ) - } - } else Modifier - ), - enabled = state.isActive, - colors = ButtonDefaults.buttonColors( - containerColor = state.color ?: defaultColor, - contentColor = state.textColor ?: defaultTextColor - ), - shape = MaterialTheme.shapes.medium - ) { - if (state.isProgressVisible) { - CircularProgressIndicator( - modifier = Modifier.size(20.dp), - color = state.textColor ?: defaultTextColor, - strokeWidth = 2.dp - ) - Spacer(Modifier.width(8.dp)) - } - Text(state.text) - } -} - -@Composable -fun SecondaryButton( - state: SecondaryButtonState, - onClick: () -> Unit, - modifier: Modifier = Modifier, - defaultColor: Color = MaterialTheme.colorScheme.secondaryContainer, - defaultTextColor: Color = MaterialTheme.colorScheme.onSecondaryContainer -) { - Button( - onClick = onClick, - modifier = modifier, - enabled = state.isActive, - colors = ButtonDefaults.buttonColors( - containerColor = state.color ?: defaultColor, - contentColor = state.textColor ?: defaultTextColor - ), - shape = MaterialTheme.shapes.medium - ) { - if (state.isProgressVisible) { - CircularProgressIndicator( - modifier = Modifier.size(20.dp), - color = state.textColor ?: defaultTextColor, - strokeWidth = 2.dp - ) - Spacer(Modifier.width(8.dp)) - } - Text(state.text) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppDialogs.kt b/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppDialogs.kt deleted file mode 100644 index 9731f47f..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppDialogs.kt +++ /dev/null @@ -1,413 +0,0 @@ -package org.monogram.presentation.features.webapp.components - -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.presentation.R -import org.monogram.presentation.features.webapp.CustomMethodRequest -import org.monogram.presentation.features.webapp.PermissionRequest -import org.monogram.presentation.features.webapp.PopupState - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun MiniAppClosingConfirmationDialog( - onConfirm: () -> Unit, - onDismiss: () -> Unit -) { - ModalBottomSheet( - onDismissRequest = onDismiss, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 40.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Text( - text = stringResource(R.string.mini_app_close_confirmation_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - Spacer(modifier = Modifier.height(12.dp)) - Text( - text = stringResource(R.string.mini_app_close_confirmation_text), - style = MaterialTheme.typography.bodyLarge, - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.height(32.dp)) - Button( - onClick = onConfirm, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp), - colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error) - ) { - Text(stringResource(R.string.mini_app_close), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - Spacer(modifier = Modifier.height(12.dp)) - OutlinedButton( - onClick = onDismiss, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.mini_app_cancel), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun MiniAppPopupDialog( - state: PopupState, - onDismiss: (buttonId: String?) -> Unit -) { - ModalBottomSheet( - onDismissRequest = { onDismiss(null) }, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 40.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - state.title?.let { - Text( - text = it, - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - textAlign = TextAlign.Center - ) - Spacer(modifier = Modifier.height(12.dp)) - } - Text( - text = state.message, - style = MaterialTheme.typography.bodyLarge, - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.height(32.dp)) - - Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { - state.buttons.forEach { button -> - if (button.type == "ok" || button.type == "close" || button.type == "default") { - Button( - onClick = { onDismiss(button.id) }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp), - colors = if (button.isDestructive) { - ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error) - } else { - ButtonDefaults.buttonColors() - } - ) { - Text(button.text, fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } else { - OutlinedButton( - onClick = { onDismiss(button.id) }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text( - button.text, - fontSize = 16.sp, - fontWeight = FontWeight.Bold, - color = if (button.isDestructive) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.primary - ) - } - } - } - } - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun MiniAppPermissionDialog( - request: PermissionRequest, - onDismiss: () -> Unit -) { - ModalBottomSheet( - onDismissRequest = { - request.onDismiss() - onDismiss() - }, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 40.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Text( - text = stringResource(R.string.mini_app_permission_request), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - Spacer(modifier = Modifier.height(12.dp)) - Text( - text = request.message, - style = MaterialTheme.typography.bodyLarge, - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.height(32.dp)) - Button( - onClick = { - request.onGranted() - onDismiss() - }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.mini_app_allow), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - Spacer(modifier = Modifier.height(12.dp)) - OutlinedButton( - onClick = { - request.onDenied() - onDismiss() - }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.mini_app_deny), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun MiniAppCustomMethodDialog( - request: CustomMethodRequest, - onDismiss: () -> Unit -) { - ModalBottomSheet( - onDismissRequest = { - request.onCancel() - onDismiss() - }, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 40.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Text( - text = request.title, - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - Spacer(modifier = Modifier.height(12.dp)) - Text( - text = request.message, - style = MaterialTheme.typography.bodyLarge, - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.height(32.dp)) - Button( - onClick = { - request.onConfirm() - onDismiss() - }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.mini_app_allow), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - Spacer(modifier = Modifier.height(12.dp)) - OutlinedButton( - onClick = { - request.onCancel() - onDismiss() - }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.mini_app_deny), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun MiniAppPermissionsBottomSheet( - isVisible: Boolean, - permissions: Map, - onDismiss: () -> Unit, - onTogglePermission: (String) -> Unit -) { - if (isVisible) { - ModalBottomSheet( - onDismissRequest = onDismiss, - containerColor = MaterialTheme.colorScheme.surface, - dragHandle = { BottomSheetDefaults.DragHandle() }, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 24.dp) - ) { - Text( - text = stringResource(R.string.mini_app_bot_permissions), - modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp), - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.Bold - ) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainerLow, - shape = RoundedCornerShape(20.dp), - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp) - ) { - Column { - permissions.entries.forEachIndexed { index, entry -> - ListItem( - headlineContent = { Text(entry.key, style = MaterialTheme.typography.bodyLarge) }, - trailingContent = { - Switch( - checked = entry.value, - onCheckedChange = { onTogglePermission(entry.key) } - ) - }, - colors = ListItemDefaults.colors(containerColor = Color.Transparent), - ) - if (index < permissions.size - 1) { - HorizontalDivider( - modifier = Modifier.padding(horizontal = 16.dp), - thickness = 0.5.dp, - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - } - } - } - } - - Spacer(modifier = Modifier.height(8.dp)) - - TextButton( - onClick = onDismiss, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .height(48.dp) - ) { - Text(stringResource(R.string.mini_app_close), fontSize = 16.sp, fontWeight = FontWeight.Medium) - } - } - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun MiniAppTOSBottomSheet( - isVisible: Boolean, - onDismiss: () -> Unit, - onAccept: () -> Unit -) { - if (isVisible) { - ModalBottomSheet( - onDismissRequest = onDismiss, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - dragHandle = { BottomSheetDefaults.DragHandle() }, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 40.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Text( - text = stringResource(R.string.mini_app_tos_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - Spacer(modifier = Modifier.height(12.dp)) - Text( - text = stringResource(R.string.mini_app_tos_text), - style = MaterialTheme.typography.bodyLarge, - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.height(32.dp)) - Button( - onClick = onAccept, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.mini_app_tos_accept), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - Spacer(modifier = Modifier.height(12.dp)) - OutlinedButton( - onClick = onDismiss, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.mini_app_cancel), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppFullscreenControls.kt b/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppFullscreenControls.kt deleted file mode 100644 index 4327b2a7..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppFullscreenControls.kt +++ /dev/null @@ -1,68 +0,0 @@ -package org.monogram.presentation.features.webapp.components - -import androidx.compose.animation.* -import androidx.compose.foundation.layout.* -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.MoreVert -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.IconButtonDefaults -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp - -@Composable -fun BoxScope.MiniAppFullscreenControls( - visible: Boolean, - onBackClick: () -> Unit, - onMenuClick: () -> Unit -) { - AnimatedVisibility( - visible = visible, - enter = fadeIn() + slideInVertically(), - exit = fadeOut() + slideOutVertically(), - modifier = Modifier - .fillMaxWidth() - .align(Alignment.TopCenter) - .statusBarsPadding() - .padding(top = 8.dp, start = 16.dp, end = 16.dp) - ) { - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - IconButton( - onClick = onBackClick, - colors = IconButtonDefaults.iconButtonColors( - containerColor = MaterialTheme.colorScheme.surface.copy(alpha = 0.7f), - contentColor = MaterialTheme.colorScheme.onSurface - ), - modifier = Modifier.size(40.dp) - ) { - Icon( - imageVector = Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = "Exit Fullscreen", - modifier = Modifier.size(20.dp) - ) - } - IconButton( - onClick = onMenuClick, - colors = IconButtonDefaults.iconButtonColors( - containerColor = MaterialTheme.colorScheme.surface.copy(alpha = 0.7f), - contentColor = MaterialTheme.colorScheme.onSurface - ), - modifier = Modifier.size(40.dp) - ) { - Icon( - imageVector = Icons.Rounded.MoreVert, - contentDescription = "More", - modifier = Modifier.size(20.dp) - ) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppLoadingView.kt b/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppLoadingView.kt deleted file mode 100644 index a20e11bd..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppLoadingView.kt +++ /dev/null @@ -1,44 +0,0 @@ -package org.monogram.presentation.features.webapp.components - -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.material3.CircularProgressIndicator -import androidx.compose.material3.LinearProgressIndicator -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp - -@Composable -fun MiniAppLoadingView( - isInitializing: Boolean, - isLoading: Boolean, - progress: Int, - backgroundColor: Color? -) { - if (isInitializing) { - Surface( - modifier = Modifier.fillMaxSize(), - color = backgroundColor ?: MaterialTheme.colorScheme.surface - ) { - Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { - CircularProgressIndicator() - } - } - } - - if (!isInitializing && (isLoading || progress < 100)) { - LinearProgressIndicator( - progress = { progress / 100f }, - modifier = Modifier - .fillMaxWidth() - .height(2.dp), - color = MaterialTheme.colorScheme.primary - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppMenu.kt b/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppMenu.kt deleted file mode 100644 index 93028ff8..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppMenu.kt +++ /dev/null @@ -1,145 +0,0 @@ -package org.monogram.presentation.features.webapp.components - -import org.monogram.presentation.core.util.coRunCatching -import android.content.Context -import android.content.Intent -import android.content.pm.ShortcutInfo -import android.content.pm.ShortcutManager -import android.graphics.BitmapFactory -import android.graphics.drawable.Icon -import android.os.Build -import androidx.compose.animation.* -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.spring -import androidx.compose.animation.core.tween -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.OpenInNew -import androidx.compose.material.icons.rounded.AddToHomeScreen -import androidx.compose.material.icons.rounded.ContentCopy -import androidx.compose.material.icons.rounded.Refresh -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.TransformOrigin -import androidx.compose.ui.platform.ClipboardManager -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.unit.dp -import androidx.core.net.toUri -import org.monogram.presentation.R -import org.monogram.presentation.features.stickers.ui.menu.MenuOptionRow -import org.monogram.presentation.features.viewers.components.ViewerSettingsDropdown - -@Composable -fun MiniAppMenu( - visible: Boolean, - isFullscreen: Boolean, - url: String, - botUserId: Long, - botName: String, - botAvatarPath: String?, - context: Context, - clipboardManager: ClipboardManager, - onDismiss: () -> Unit, - onReload: () -> Unit -) { - AnimatedVisibility( - visible = visible, - enter = fadeIn(tween(150)) + scaleIn( - animationSpec = spring(dampingRatio = 0.8f, stiffness = Spring.StiffnessMedium), - initialScale = 0.8f, - transformOrigin = TransformOrigin(1f, 0f) - ), - exit = fadeOut(tween(150)) + scaleOut( - animationSpec = tween(150), - targetScale = 0.9f, - transformOrigin = TransformOrigin(1f, 0f) - ), - modifier = Modifier - .fillMaxSize() - .windowInsetsPadding(WindowInsets.statusBars) - .padding(top = if (isFullscreen) 64.dp else 56.dp, end = 16.dp) - ) { - Box( - modifier = Modifier - .fillMaxSize() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null, - onClick = onDismiss - ), - contentAlignment = Alignment.TopEnd - ) { - ViewerSettingsDropdown { - MenuOptionRow( - icon = Icons.Rounded.Refresh, - title = stringResource(R.string.mini_app_menu_reload), - onClick = { - onReload() - onDismiss() - } - ) - MenuOptionRow( - icon = Icons.Rounded.ContentCopy, - title = stringResource(R.string.mini_app_menu_copy_link), - onClick = { - clipboardManager.setText(AnnotatedString(url)) - onDismiss() - } - ) - MenuOptionRow( - icon = Icons.AutoMirrored.Rounded.OpenInNew, - title = stringResource(R.string.mini_app_menu_open_in_browser), - onClick = { - coRunCatching { - context.startActivity( - Intent( - Intent.ACTION_VIEW, - url.toUri() - ) - ) - } - onDismiss() - } - ) - MenuOptionRow( - icon = Icons.Rounded.AddToHomeScreen, - title = stringResource(R.string.mini_app_menu_add_to_home), - onClick = { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val shortcutManager = context.getSystemService(ShortcutManager::class.java) - if (shortcutManager.isRequestPinShortcutSupported) { - val shortcutId = "webapp_$botUserId" - val intent = Intent(context, context.javaClass).apply { - action = Intent.ACTION_VIEW - data = "tg://resolve?domain=$botName&startapp=true".toUri() - } - val icon = if (botAvatarPath != null) { - val bitmap = BitmapFactory.decodeFile(botAvatarPath) - if (bitmap != null) Icon.createWithBitmap(bitmap) else Icon.createWithResource( - context, - R.drawable.outline_web_24 - ) - } else { - Icon.createWithResource(context, R.drawable.outline_web_24) - } - val pinShortcutInfo = ShortcutInfo.Builder(context, shortcutId) - .setShortLabel(botName) - .setIcon(icon) - .setIntent(intent) - .build() - - shortcutManager.requestPinShortcut(pinShortcutInfo, null) - } - } - onDismiss() - } - ) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppQrScanner.kt b/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppQrScanner.kt deleted file mode 100644 index 7df6a67f..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppQrScanner.kt +++ /dev/null @@ -1,48 +0,0 @@ -package org.monogram.presentation.features.webapp.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import org.monogram.presentation.core.ui.IntegratedQRScanner - -@Composable -fun MiniAppQrScanner( - qrText: String?, - onCodeDetected: (String) -> Unit, - onBackClicked: () -> Unit -) { - if (qrText != null) { - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.Black) - ) { - IntegratedQRScanner( - onCodeDetected = onCodeDetected, - onBackClicked = onBackClicked - ) - - if (qrText.isNotEmpty()) { - Text( - text = qrText, - color = Color.White, - modifier = Modifier - .align(Alignment.BottomCenter) - .padding(bottom = 80.dp) - .padding(horizontal = 32.dp), - textAlign = TextAlign.Center, - style = MaterialTheme.typography.bodyLarge - ) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppTopBar.kt b/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppTopBar.kt deleted file mode 100644 index 8c0994c5..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppTopBar.kt +++ /dev/null @@ -1,85 +0,0 @@ -package org.monogram.presentation.features.webapp.components - -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.Close -import androidx.compose.material.icons.rounded.MoreVert -import androidx.compose.material.icons.rounded.Settings -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun MiniAppTopBar( - headerText: String, - isBackButtonVisible: Boolean, - isSettingsButtonVisible: Boolean, - isInitializing: Boolean, - topBarColor: Color?, - topBarTextColor: Color?, - accentColor: Color?, - onBackClick: () -> Unit, - onCloseClick: () -> Unit, - onSettingsClick: () -> Unit, - onMenuClick: () -> Unit -) { - CenterAlignedTopAppBar( - title = { - Text( - text = headerText, - style = MaterialTheme.typography.titleLarge, - fontWeight = FontWeight.SemiBold, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - color = topBarTextColor ?: MaterialTheme.colorScheme.onSurface - ) - }, - navigationIcon = { - if (isBackButtonVisible) { - IconButton(onClick = onBackClick) { - Icon( - imageVector = Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = "Back", - tint = accentColor ?: MaterialTheme.colorScheme.primary - ) - } - } else { - IconButton(onClick = onCloseClick) { - Icon( - imageVector = Icons.Rounded.Close, - contentDescription = "Close", - tint = accentColor ?: MaterialTheme.colorScheme.primary - ) - } - } - }, - actions = { - if (isSettingsButtonVisible) { - IconButton( - onClick = onSettingsClick, - enabled = !isInitializing - ) { - Icon( - imageVector = Icons.Rounded.Settings, - contentDescription = "Settings", - tint = accentColor ?: MaterialTheme.colorScheme.primary - ) - } - } - - IconButton(onClick = onMenuClick, enabled = !isInitializing) { - Icon( - imageVector = Icons.Rounded.MoreVert, - contentDescription = "More", - tint = accentColor ?: MaterialTheme.colorScheme.primary - ) - } - }, - colors = TopAppBarDefaults.centerAlignedTopAppBarColors( - containerColor = topBarColor ?: MaterialTheme.colorScheme.surface - ) - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppWebView.kt b/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppWebView.kt deleted file mode 100644 index a5a4f9c4..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webapp/components/MiniAppWebView.kt +++ /dev/null @@ -1,123 +0,0 @@ -package org.monogram.presentation.features.webapp.components - -import org.monogram.presentation.core.util.coRunCatching -import android.annotation.SuppressLint -import android.content.Intent -import android.graphics.Bitmap -import android.graphics.Color -import android.net.http.SslError -import android.os.Build -import android.view.ViewGroup -import android.webkit.* -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.core.graphics.toColorInt -import androidx.compose.ui.viewinterop.AndroidView -import org.monogram.domain.models.webapp.ThemeParams -import org.monogram.presentation.features.webapp.TelegramWebAppHost -import org.monogram.presentation.features.webapp.TelegramWebviewProxy - -@Composable -fun MiniAppWebView( - url: String, - acceptLanguage: String, - themeParams: ThemeParams, - host: TelegramWebAppHost, - onWebViewCreated: (WebView, TelegramWebviewProxy) -> Unit, - onProgressChanged: (Int) -> Unit, - onLoadingChanged: (Boolean) -> Unit, - modifier: Modifier = Modifier -) { - AndroidView( - factory = { ctx -> - WebView(ctx).apply { - layoutParams = ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT - ) - - @SuppressLint("SetJavaScriptEnabled") - settings.apply { - javaScriptEnabled = true - domStorageEnabled = true - allowFileAccess = true - useWideViewPort = true - loadWithOverviewMode = true - mediaPlaybackRequiresUserGesture = false - mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW - userAgentString = - "Mozilla/5.0 (Linux; Android ${Build.VERSION.RELEASE}; ${Build.MODEL}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Mobile Safari/537.36 Telegram-Android/12.3.1 (Android; ${Build.MODEL}; SDK ${Build.VERSION.SDK_INT}; AVERAGE)" - } - - setBackgroundColor(themeParams.backgroundColor?.toColorInt() ?: Color.TRANSPARENT) - - val bridge = TelegramWebviewProxy( - context = ctx, - webView = this, - themeParams = themeParams, - host = host - ) - - onWebViewCreated(this, bridge) - addJavascriptInterface(bridge, "TelegramWebviewProxy") - - webViewClient = object : WebViewClient() { - override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { - onLoadingChanged(true) - } - - override fun onPageFinished(view: WebView?, url: String?) { - onLoadingChanged(false) - } - - @SuppressLint("WebViewClientOnReceivedSslError") - override fun onReceivedSslError( - view: WebView?, - handler: SslErrorHandler?, - error: SslError? - ) { - handler?.proceed() - } - - override fun shouldOverrideUrlLoading( - view: WebView?, - request: WebResourceRequest? - ): Boolean { - val uri = request?.url ?: return false - if (uri.scheme == "tg" || !listOf("http", "https").contains(uri.scheme)) { - coRunCatching { - ctx.startActivity( - Intent( - Intent.ACTION_VIEW, - uri - ) - ) - } - return true - } - return false - } - } - - webChromeClient = object : WebChromeClient() { - override fun onProgressChanged(view: WebView?, newProgress: Int) { - onProgressChanged(newProgress) - } - } - - CookieManager.getInstance().setAcceptThirdPartyCookies(this, true) - if (url.isNotEmpty()) { - loadUrl(url, mapOf("Accept-Language" to acceptLanguage)) - } - } - }, - modifier = modifier.then(Modifier.fillMaxSize()), - update = { view -> - view.setBackgroundColor(themeParams.backgroundColor?.toColorInt() ?: Color.TRANSPARENT) - if (url.isNotEmpty() && view.url != url) { - view.loadUrl(url, mapOf("Accept-Language" to acceptLanguage)) - } - } - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webview/DefaultWebViewComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/webview/DefaultWebViewComponent.kt deleted file mode 100644 index c08d8aa1..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webview/DefaultWebViewComponent.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.monogram.presentation.features.webview - -import org.monogram.presentation.root.AppComponentContext - -class DefaultWebViewComponent( - context: AppComponentContext, - override val url: String, - private val onDismiss: () -> Unit -) : WebViewComponent, AppComponentContext by context { - override fun onDismiss() = onDismiss.invoke() -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/webview/InternalWebView.kt b/presentation/src/main/java/org/monogram/presentation/features/webview/InternalWebView.kt deleted file mode 100644 index aac74693..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webview/InternalWebView.kt +++ /dev/null @@ -1,435 +0,0 @@ -package org.monogram.presentation.features.webview - -import android.annotation.SuppressLint -import android.content.Intent -import android.content.pm.PackageManager -import android.graphics.Bitmap -import android.net.Uri -import android.net.http.SslCertificate -import android.os.Build -import android.view.ViewGroup -import android.webkit.* -import androidx.activity.compose.BackHandler -import androidx.compose.animation.* -import androidx.compose.animation.core.tween -import androidx.compose.foundation.focusable -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import androidx.compose.ui.viewinterop.AndroidView -import kotlinx.coroutines.launch -import org.monogram.presentation.R -import org.monogram.presentation.features.webview.components.CertificateSheet -import org.monogram.presentation.features.webview.components.FindInPageBar -import org.monogram.presentation.features.webview.components.OptionsSheet -import org.monogram.presentation.features.webview.components.WebViewTopBar -import java.io.ByteArrayInputStream - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun InternalWebView( - url: String, - onDismiss: () -> Unit -) { - val context = LocalContext.current - val scope = rememberCoroutineScope() - - val loadingText = stringResource(R.string.webview_loading) - val defaultTitle = stringResource(R.string.webview_default_title) - - var webView by remember { mutableStateOf(null) } - var title by remember { mutableStateOf(loadingText) } - var currentUrl by remember { mutableStateOf(url) } - var canGoBack by remember { mutableStateOf(false) } - var canGoForward by remember { mutableStateOf(false) } - var progress by remember { mutableFloatStateOf(0f) } - var isLoading by remember { mutableStateOf(true) } - - var showBottomSheet by remember { mutableStateOf(false) } - val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) - var isDesktopMode by remember { mutableStateOf(false) } - var isAdBlockEnabled by remember { mutableStateOf(true) } - var textZoom by remember { mutableIntStateOf(100) } - - var showFindInPage by remember { mutableStateOf(false) } - var findQuery by remember { mutableStateOf("") } - var activeMatchIndex by remember { mutableIntStateOf(0) } - var matchCount by remember { mutableIntStateOf(0) } - - var isSecure by remember { mutableStateOf(url.startsWith("https")) } - var sslCertificate by remember { mutableStateOf(null) } - var showCertificateSheet by remember { mutableStateOf(false) } - val certificateSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) - - val displayUrl = remember(currentUrl) { - currentUrl.removePrefix("https://").removePrefix("http://").removeSuffix("/") - } - - val adBlockKeywords = remember { - listOf( - "doubleclick.net", "googleadservices.com", "googlesyndication.com", - "adsystem.com", "adservice.com", "analytics", "/ads/", "/banners/", "tracker", - "metrika", "sentry", "crashlytics", "app-measurement.com", - "amplitude.com", "mixpanel.com", "facebook.com/tr", "adfox.ru", - "ad.mail.ru", "track.mail.ru", "tns-counter.ru", "hotjar.com", "inspectlet.com" - ) - } - - val defaultUserAgent = remember { WebSettings.getDefaultUserAgent(context) } - val desktopUserAgent = - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36" - - LaunchedEffect(isDesktopMode, webView) { - webView?.let { - val newAgent = if (isDesktopMode) desktopUserAgent else defaultUserAgent - if (it.settings.userAgentString != newAgent) { - it.settings.userAgentString = newAgent - it.reload() - } - } - } - - LaunchedEffect(textZoom) { - webView?.settings?.textZoom = textZoom - } - - DisposableEffect(webView) { - val listener = WebView.FindListener { activeMatchOrdinal, numberOfMatches, isDoneCounting -> - if (isDoneCounting) { - matchCount = numberOfMatches - activeMatchIndex = activeMatchOrdinal - } - } - webView?.setFindListener(listener) - onDispose { - webView?.setFindListener(null) - } - } - - LaunchedEffect(findQuery) { - if (findQuery.isNotEmpty()) { - webView?.findAllAsync(findQuery) - } else { - webView?.clearMatches() - matchCount = 0 - activeMatchIndex = 0 - } - } - - val dismissBottomSheet: () -> Unit = { - scope.launch { - sheetState.hide() - }.invokeOnCompletion { - if (!sheetState.isVisible) { - showBottomSheet = false - } - } - } - - val dismissCertificateSheet: () -> Unit = { - scope.launch { - certificateSheetState.hide() - }.invokeOnCompletion { - if (!certificateSheetState.isVisible) { - showCertificateSheet = false - } - } - } - - BackHandler { - if (showBottomSheet) { - dismissBottomSheet() - } else if (showCertificateSheet) { - dismissCertificateSheet() - } else if (showFindInPage) { - showFindInPage = false - webView?.clearMatches() - } else if (canGoBack) { - webView?.goBack() - } else { - onDismiss() - } - } - - if (showCertificateSheet) { - ModalBottomSheet( - onDismissRequest = { showCertificateSheet = false }, - sheetState = certificateSheetState, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - CertificateSheet( - isSecure = isSecure, - sslCertificate = sslCertificate, - onDismiss = dismissCertificateSheet - ) - } - } - - Scaffold( - topBar = { - AnimatedContent( - targetState = showFindInPage, - transitionSpec = { - fadeIn(animationSpec = tween(300)) togetherWith - fadeOut(animationSpec = tween(300)) - }, - label = "TopBarAnimation" - ) { isFinding -> - if (isFinding) { - FindInPageBar( - query = findQuery, - onQueryChange = { findQuery = it }, - matchCount = matchCount, - activeMatchIndex = activeMatchIndex, - webView = webView, - onClose = { - showFindInPage = false - webView?.clearMatches() - } - ) - } else { - WebViewTopBar( - title = title, - displayUrl = displayUrl, - isSecure = isSecure, - onDismiss = onDismiss, - onMoreOptions = { showBottomSheet = true }, - onCertificateClick = { showCertificateSheet = true } - ) - } - } - } - ) { padding -> - Box( - modifier = Modifier - .padding(padding) - .fillMaxSize() - ) { - AndroidView( - factory = { ctx -> - WebView(ctx).apply { - layoutParams = ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT - ) - - // Fix for input focus/keyboard issue - isFocusable = true - isFocusableInTouchMode = true - @SuppressLint("ClickableViewAccessibility") - setOnTouchListener { v, _ -> - if (!v.hasFocus()) { - v.requestFocus() - } - false - } - - @SuppressLint("SetJavaScriptEnabled") - settings.apply { - javaScriptEnabled = true - userAgentString = if (isDesktopMode) desktopUserAgent else defaultUserAgent - domStorageEnabled = true - loadWithOverviewMode = true - useWideViewPort = true - builtInZoomControls = true - displayZoomControls = false - mixedContentMode = WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - safeBrowsingEnabled = true - } - setSupportZoom(true) - } - webViewClient = object : WebViewClient() { - override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { - isLoading = true - url?.let { currentUrl = it } - } - - override fun onPageFinished(view: WebView?, url: String?) { - isLoading = false - url?.let { - currentUrl = it - isSecure = it.startsWith("https") && view?.certificate != null - sslCertificate = view?.certificate - } - } - - override fun shouldOverrideUrlLoading( - view: WebView?, - request: WebResourceRequest? - ): Boolean { - val uri = request?.url ?: return false - val url = uri.toString() - val context = view?.context ?: return false - - if (url.startsWith("intent://")) { - try { - val intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME) - if (intent != null) { - val packageManager = context.packageManager - val info = packageManager.resolveActivity( - intent, - PackageManager.MATCH_DEFAULT_ONLY - ) - - if (info != null) { - context.startActivity(intent) - return true - } - - val fallbackUrl = intent.getStringExtra("browser_fallback_url") - if (!fallbackUrl.isNullOrEmpty()) { - view.loadUrl(fallbackUrl) - return true - } - - val packagename = intent.`package` - if (!packagename.isNullOrEmpty()) { - val marketIntent = Intent( - Intent.ACTION_VIEW, - Uri.parse("market://details?id=$packagename") - ) - marketIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - context.startActivity(marketIntent) - return true - } - } - } catch (e: Exception) { - // Log error - } - return true - } - - if (!url.startsWith("http://") && !url.startsWith("https://")) { - return try { - val intent = Intent(Intent.ACTION_VIEW, uri) - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - context.startActivity(intent) - true - } catch (e: Exception) { - true - } - } - - if (url.startsWith("http://") || url.startsWith("https://")) { - try { - val intent = Intent(Intent.ACTION_VIEW, uri) - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - - val packageManager = context.packageManager - val resolveInfo = - packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) - - if (resolveInfo != null) { - val packageName = resolveInfo.activityInfo.packageName - - val isBrowser = - packageName == "com.android.chrome" || packageName == "com.google.android.browser" - val isMyPackage = packageName == context.packageName - - if (!isBrowser && !isMyPackage) { - context.startActivity(intent) - return true - } - } - } catch (e: Exception) { - } - } - - return false - } - - override fun shouldInterceptRequest( - view: WebView?, - request: WebResourceRequest? - ): WebResourceResponse? { - if (isAdBlockEnabled) { - val requestUrl = request?.url?.toString()?.lowercase() - if (requestUrl != null && adBlockKeywords.any { requestUrl.contains(it) }) { - return WebResourceResponse( - "text/plain", - "UTF-8", - ByteArrayInputStream(ByteArray(0)) - ) - } - } - return super.shouldInterceptRequest(view, request) - } - } - webChromeClient = object : WebChromeClient() { - override fun onProgressChanged(view: WebView?, newProgress: Int) { - progress = newProgress / 100f - } - - override fun onReceivedTitle(view: WebView?, webTitle: String?) { - title = webTitle ?: defaultTitle - } - } - loadUrl(url) - webView = this - } - }, - onRelease = { view -> view.destroy() }, - modifier = Modifier - .fillMaxSize() - .focusable() - ) - - AnimatedVisibility( - visible = isLoading, - enter = fadeIn(animationSpec = tween(300)) + expandVertically(), - exit = fadeOut(animationSpec = tween(500)) + shrinkVertically(), - modifier = Modifier.align(Alignment.TopCenter) - ) { - LinearProgressIndicator( - progress = { progress }, - modifier = Modifier.fillMaxWidth(), - color = MaterialTheme.colorScheme.primary, - trackColor = Color.Transparent - ) - } - } - - if (showBottomSheet) { - ModalBottomSheet( - onDismissRequest = { showBottomSheet = false }, - sheetState = sheetState, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - OptionsSheet( - webView = webView, - currentUrl = currentUrl, - canGoBack = canGoBack, - canGoForward = canGoForward, - isDesktopMode = isDesktopMode, - isAdBlockEnabled = isAdBlockEnabled, - textZoom = textZoom, - onDesktopModeChange = { isDesktopMode = it }, - onAdBlockChange = { - isAdBlockEnabled = it - webView?.reload() - }, - onTextZoomChange = { textZoom = it }, - onFindInPage = { showFindInPage = true }, - onDismiss = dismissBottomSheet - ) - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/webview/WebViewComponent.kt b/presentation/src/main/java/org/monogram/presentation/features/webview/WebViewComponent.kt deleted file mode 100644 index 90dcaf08..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webview/WebViewComponent.kt +++ /dev/null @@ -1,6 +0,0 @@ -package org.monogram.presentation.features.webview - -interface WebViewComponent { - val url: String - fun onDismiss() -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/features/webview/components/ActionItem.kt b/presentation/src/main/java/org/monogram/presentation/features/webview/components/ActionItem.kt deleted file mode 100644 index acc4ae00..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webview/components/ActionItem.kt +++ /dev/null @@ -1,53 +0,0 @@ -package org.monogram.presentation.features.webview.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp - -@Composable -fun ActionItem( - icon: ImageVector, - label: String, - onClick: () -> Unit -) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier - .width(72.dp) - .clip(RoundedCornerShape(12.dp)) - .clickable(onClick = onClick) - .padding(vertical = 8.dp) - ) { - Box( - modifier = Modifier - .size(48.dp) - .background(MaterialTheme.colorScheme.secondaryContainer, CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = icon, - contentDescription = label, - tint = MaterialTheme.colorScheme.onSecondaryContainer - ) - } - Spacer(modifier = Modifier.height(8.dp)) - Text( - label, - style = MaterialTheme.typography.labelSmall, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webview/components/CertificateInfoItem.kt b/presentation/src/main/java/org/monogram/presentation/features/webview/components/CertificateInfoItem.kt deleted file mode 100644 index 3036d0ee..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webview/components/CertificateInfoItem.kt +++ /dev/null @@ -1,27 +0,0 @@ -package org.monogram.presentation.features.webview.components - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp - -@Composable -fun CertificateInfoItem(label: String, value: String) { - Column(modifier = Modifier.padding(vertical = 8.dp)) { - Text( - text = label, - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) - Text( - text = value, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurface - ) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webview/components/CertificateSheet.kt b/presentation/src/main/java/org/monogram/presentation/features/webview/components/CertificateSheet.kt deleted file mode 100644 index daaaa769..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webview/components/CertificateSheet.kt +++ /dev/null @@ -1,111 +0,0 @@ -package org.monogram.presentation.features.webview.components - -import android.net.http.SslCertificate -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.ErrorOutline -import androidx.compose.material.icons.rounded.Lock -import androidx.compose.material.icons.rounded.Warning -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import org.monogram.presentation.R - -@Composable -fun CertificateSheet( - isSecure: Boolean, - sslCertificate: SslCertificate?, - onDismiss: () -> Unit -) { - val unknownText = stringResource(R.string.webview_cert_unknown) - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 48.dp) - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.padding(bottom = 24.dp) - ) { - Icon( - imageVector = if (isSecure) Icons.Rounded.Lock else Icons.Rounded.Warning, - contentDescription = null, - tint = if (isSecure) Color(0xFF4CAF50) else MaterialTheme.colorScheme.error, - modifier = Modifier.size(32.dp) - ) - Spacer(modifier = Modifier.width(16.dp)) - Text( - text = if (isSecure) stringResource(R.string.webview_security_info_title) else stringResource(R.string.webview_insecure_connection_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - } - - Column( - modifier = Modifier - .fillMaxWidth() - .verticalScroll(rememberScrollState()) - ) { - if (isSecure && sslCertificate != null) { - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(16.dp), - modifier = Modifier.fillMaxWidth() - ) { - Column(modifier = Modifier.padding(16.dp)) { - Text( - stringResource(R.string.webview_secure_connection_desc), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - - Spacer(modifier = Modifier.height(24.dp)) - - CertificateInfoItem(stringResource(R.string.webview_cert_issued_to), sslCertificate.issuedTo?.dName ?: unknownText) - CertificateInfoItem(stringResource(R.string.webview_cert_issued_by), sslCertificate.issuedBy?.dName ?: unknownText) - CertificateInfoItem(stringResource(R.string.webview_cert_valid_until), sslCertificate.validNotAfterDate?.toString() ?: unknownText) - } else { - Surface( - color = MaterialTheme.colorScheme.errorContainer, - shape = RoundedCornerShape(16.dp), - modifier = Modifier.fillMaxWidth() - ) { - Row(modifier = Modifier.padding(16.dp)) { - Icon( - Icons.Rounded.ErrorOutline, - null, - tint = MaterialTheme.colorScheme.onErrorContainer - ) - Spacer(modifier = Modifier.width(12.dp)) - Text( - stringResource(R.string.webview_insecure_connection_desc), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onErrorContainer - ) - } - } - } - } - - Spacer(modifier = Modifier.height(32.dp)) - - Button( - onClick = onDismiss, - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.webview_close)) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webview/components/FindInPageBar.kt b/presentation/src/main/java/org/monogram/presentation/features/webview/components/FindInPageBar.kt deleted file mode 100644 index 9136dfde..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webview/components/FindInPageBar.kt +++ /dev/null @@ -1,68 +0,0 @@ -package org.monogram.presentation.features.webview.components - -import android.webkit.WebView -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.padding -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Close -import androidx.compose.material.icons.rounded.KeyboardArrowDown -import androidx.compose.material.icons.rounded.KeyboardArrowUp -import androidx.compose.material.icons.rounded.Search -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.features.chats.chatList.components.SettingsTextField - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun FindInPageBar( - query: String, - onQueryChange: (String) -> Unit, - matchCount: Int, - activeMatchIndex: Int, - webView: WebView?, - onClose: () -> Unit -) { - TopAppBar( - title = { - SettingsTextField( - value = query, - onValueChange = onQueryChange, - placeholder = stringResource(R.string.webview_find_placeholder), - icon = Icons.Rounded.Search, - position = ItemPosition.STANDALONE, - singleLine = true, - trailingIcon = { - Row(verticalAlignment = Alignment.CenterVertically) { - if (matchCount > 0) { - Text( - "${activeMatchIndex + 1}/$matchCount", - style = MaterialTheme.typography.bodySmall, - modifier = Modifier.padding(end = 8.dp) - ) - } - IconButton(onClick = { webView?.findNext(false) }) { - Icon(Icons.Rounded.KeyboardArrowUp, stringResource(R.string.webview_find_previous)) - } - IconButton(onClick = { webView?.findNext(true) }) { - Icon(Icons.Rounded.KeyboardArrowDown, stringResource(R.string.webview_find_next)) - } - } - } - ) - }, - navigationIcon = { - IconButton(onClick = onClose) { - Icon(Icons.Rounded.Close, stringResource(R.string.webview_find_close)) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp) - ) - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webview/components/NavigationItem.kt b/presentation/src/main/java/org/monogram/presentation/features/webview/components/NavigationItem.kt deleted file mode 100644 index 772b134d..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webview/components/NavigationItem.kt +++ /dev/null @@ -1,48 +0,0 @@ -package org.monogram.presentation.features.webview.components - -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.scale -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.unit.dp - -@Composable -fun NavigationItem( - icon: ImageVector, - label: String, - enabled: Boolean = true, - onClick: () -> Unit -) { - val alpha by animateFloatAsState(if (enabled) 1f else 0.4f, label = "NavAlpha") - val scale by animateFloatAsState(if (enabled) 1f else 0.9f, label = "NavScale") - - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier - .clip(RoundedCornerShape(12.dp)) - .clickable(enabled = enabled, onClick = onClick) - .padding(8.dp) - .alpha(alpha) - .scale(scale) - ) { - Icon( - imageVector = icon, - contentDescription = label, - modifier = Modifier.size(28.dp), - tint = MaterialTheme.colorScheme.onSurface - ) - Spacer(modifier = Modifier.height(4.dp)) - Text(label, style = MaterialTheme.typography.labelSmall) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webview/components/OptionsSheet.kt b/presentation/src/main/java/org/monogram/presentation/features/webview/components/OptionsSheet.kt deleted file mode 100644 index 88150d7c..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webview/components/OptionsSheet.kt +++ /dev/null @@ -1,199 +0,0 @@ -package org.monogram.presentation.features.webview.components - -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context -import android.content.Intent -import android.webkit.WebView -import android.widget.Toast -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.automirrored.rounded.ArrowForward -import androidx.compose.material.icons.automirrored.rounded.OpenInNew -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalUriHandler -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsSwitchTile -import org.monogram.presentation.settings.sessions.SectionHeader - -@Composable -fun OptionsSheet( - webView: WebView?, - currentUrl: String, - canGoBack: Boolean, - canGoForward: Boolean, - isDesktopMode: Boolean, - isAdBlockEnabled: Boolean, - textZoom: Int, - onDesktopModeChange: (Boolean) -> Unit, - onAdBlockChange: (Boolean) -> Unit, - onTextZoomChange: (Int) -> Unit, - onFindInPage: () -> Unit, - onDismiss: () -> Unit -) { - val context = LocalContext.current - val uriHandler = LocalUriHandler.current - - Column( - modifier = Modifier - .fillMaxWidth() - .verticalScroll(rememberScrollState()) - .padding(horizontal = 16.dp) - .padding(bottom = 48.dp) - ) { - Text( - text = stringResource(R.string.webview_options_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(bottom = 16.dp) - ) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 8.dp), - horizontalArrangement = Arrangement.SpaceEvenly - ) { - NavigationItem( - icon = Icons.AutoMirrored.Rounded.ArrowBack, - label = stringResource(R.string.webview_back), - enabled = canGoBack, - onClick = { webView?.goBack() } - ) - NavigationItem( - icon = Icons.AutoMirrored.Rounded.ArrowForward, - label = stringResource(R.string.webview_forward), - enabled = canGoForward, - onClick = { webView?.goForward() } - ) - NavigationItem( - icon = Icons.Rounded.Refresh, - label = stringResource(R.string.webview_refresh), - onClick = { - webView?.reload() - onDismiss() - } - ) - } - } - - SectionHeader(stringResource(R.string.webview_section_actions)) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 12.dp), - horizontalArrangement = Arrangement.SpaceEvenly - ) { - ActionItem(Icons.Rounded.ContentCopy, stringResource(R.string.webview_copy_link)) { - val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - clipboard.setPrimaryClip(ClipData.newPlainText("URL", currentUrl)) - Toast.makeText(context, context.getString(R.string.webview_link_copied), Toast.LENGTH_SHORT).show() - onDismiss() - } - ActionItem(Icons.Rounded.Share, stringResource(R.string.webview_share)) { - val shareIntent = Intent(Intent.ACTION_SEND).apply { - type = "text/plain" - putExtra(Intent.EXTRA_TEXT, currentUrl) - } - context.startActivity(Intent.createChooser(shareIntent, context.getString(R.string.webview_share_chooser_title))) - onDismiss() - } - ActionItem(Icons.AutoMirrored.Rounded.OpenInNew, stringResource(R.string.webview_open_in_browser)) { - uriHandler.openUri(currentUrl) - onDismiss() - } - ActionItem(Icons.Rounded.Search, stringResource(R.string.webview_find_in_page)) { - onDismiss() - onFindInPage() - } - } - } - - SectionHeader(stringResource(R.string.webview_section_settings)) - - SettingsSwitchTile( - icon = Icons.Rounded.DesktopWindows, - title = stringResource(R.string.webview_desktop_site), - checked = isDesktopMode, - iconColor = MaterialTheme.colorScheme.primary, - position = ItemPosition.TOP, - onCheckedChange = onDesktopModeChange - ) - - SettingsSwitchTile( - icon = Icons.Rounded.Block, - title = stringResource(R.string.webview_block_ads), - checked = isAdBlockEnabled, - iconColor = MaterialTheme.colorScheme.primary, - position = ItemPosition.MIDDLE, - onCheckedChange = onAdBlockChange - ) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape( - bottomStart = 24.dp, - bottomEnd = 24.dp, - topStart = 4.dp, - topEnd = 4.dp - ), - modifier = Modifier.fillMaxWidth() - ) { - Column(modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp)) { - Row(verticalAlignment = Alignment.CenterVertically) { - Box( - modifier = Modifier - .size(40.dp) - .background( - color = MaterialTheme.colorScheme.primary.copy(0.15f), - shape = CircleShape - ), - contentAlignment = Alignment.Center - ) { - Icon(Icons.Rounded.TextFormat, null, tint = MaterialTheme.colorScheme.primary) - } - Spacer(modifier = Modifier.width(16.dp)) - Text( - stringResource(R.string.webview_text_size, textZoom), - style = MaterialTheme.typography.titleMedium, - fontSize = 18.sp - ) - } - Slider( - value = textZoom.toFloat(), - onValueChange = { onTextZoomChange(it.toInt()) }, - valueRange = 50f..200f, - steps = 14, - modifier = Modifier.padding(top = 8.dp) - ) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/features/webview/components/WebViewTopBar.kt b/presentation/src/main/java/org/monogram/presentation/features/webview/components/WebViewTopBar.kt deleted file mode 100644 index 41e59072..00000000 --- a/presentation/src/main/java/org/monogram/presentation/features/webview/components/WebViewTopBar.kt +++ /dev/null @@ -1,75 +0,0 @@ -package org.monogram.presentation.features.webview.components - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Close -import androidx.compose.material.icons.rounded.Lock -import androidx.compose.material.icons.rounded.MoreVert -import androidx.compose.material.icons.rounded.Public -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import org.monogram.presentation.R - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun WebViewTopBar( - title: String, - displayUrl: String, - isSecure: Boolean, - onDismiss: () -> Unit, - onMoreOptions: () -> Unit, - onCertificateClick: () -> Unit -) { - TopAppBar( - title = { - Column( - verticalArrangement = Arrangement.Center, - modifier = Modifier.clickable { onCertificateClick() } - ) { - Text( - text = title, - style = MaterialTheme.typography.titleMedium, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Row(verticalAlignment = Alignment.CenterVertically) { - Icon( - imageVector = if (isSecure) Icons.Rounded.Lock else Icons.Rounded.Public, - contentDescription = stringResource(if (isSecure) R.string.webview_secure else R.string.webview_insecure), - modifier = Modifier.size(12.dp), - tint = if (isSecure) Color(0xFF4CAF50) else MaterialTheme.colorScheme.error - ) - Spacer(modifier = Modifier.width(4.dp)) - Text( - text = displayUrl, - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - } - }, - navigationIcon = { - IconButton(onClick = onDismiss) { - Icon(Icons.Rounded.Close, contentDescription = stringResource(R.string.webview_close)) - } - }, - actions = { - IconButton(onClick = onMoreOptions) { - Icon(Icons.Rounded.MoreVert, contentDescription = stringResource(R.string.webview_more_options)) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp), - titleContentColor = MaterialTheme.colorScheme.onSurface - ) - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/root/AppComponentContext.kt b/presentation/src/main/java/org/monogram/presentation/root/AppComponentContext.kt deleted file mode 100644 index 0a86820e..00000000 --- a/presentation/src/main/java/org/monogram/presentation/root/AppComponentContext.kt +++ /dev/null @@ -1,32 +0,0 @@ -package org.monogram.presentation.root - -import com.arkivanov.decompose.ComponentContext -import com.arkivanov.decompose.ComponentContextFactory -import com.arkivanov.decompose.GenericComponentContext -import com.arkivanov.essenty.backhandler.BackHandlerOwner -import com.arkivanov.essenty.instancekeeper.InstanceKeeperOwner -import com.arkivanov.essenty.lifecycle.LifecycleOwner -import com.arkivanov.essenty.statekeeper.StateKeeperOwner -import org.monogram.presentation.di.AppContainer - -interface AppComponentContext : GenericComponentContext { - val container: AppContainer -} - -class DefaultAppComponentContext( - componentContext: ComponentContext, - override val container: AppContainer, -) : AppComponentContext, - LifecycleOwner by componentContext, - StateKeeperOwner by componentContext, - InstanceKeeperOwner by componentContext, - BackHandlerOwner by componentContext { - - override val componentContextFactory: ComponentContextFactory = - ComponentContextFactory { lifecycle, stateKeeper, instanceKeeper, backHandler -> - val ctx = componentContext.componentContextFactory( - lifecycle, stateKeeper, instanceKeeper, backHandler - ) - DefaultAppComponentContext(ctx, container) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/root/DefaultRootComponent.kt b/presentation/src/main/java/org/monogram/presentation/root/DefaultRootComponent.kt deleted file mode 100644 index 1b70eec0..00000000 --- a/presentation/src/main/java/org/monogram/presentation/root/DefaultRootComponent.kt +++ /dev/null @@ -1,728 +0,0 @@ -// DefaultRootComponent.kt -package org.monogram.presentation.root - -import android.os.Parcelable -import android.util.Log -import com.arkivanov.decompose.DelicateDecomposeApi -import com.arkivanov.decompose.router.stack.* -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.flow.* -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import kotlinx.parcelize.Parcelize -import kotlinx.serialization.Serializable -import org.monogram.domain.managers.PhoneManager -import org.monogram.domain.models.MessageContent -import org.monogram.domain.models.ProxyTypeModel -import org.monogram.domain.repository.* -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.core.util.coRunCatching -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.features.auth.DefaultAuthComponent -import org.monogram.presentation.features.chats.chatList.DefaultChatListComponent -import org.monogram.presentation.features.chats.currentChat.DefaultChatComponent -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.chats.newChat.DefaultNewChatComponent -import org.monogram.presentation.features.profile.DefaultProfileComponent -import org.monogram.presentation.features.profile.admin.* -import org.monogram.presentation.features.profile.logs.DefaultProfileLogsComponent -import org.monogram.presentation.features.stickers.core.toUi -import org.monogram.presentation.features.webview.DefaultWebViewComponent -import org.monogram.presentation.settings.about.DefaultAboutComponent -import org.monogram.presentation.settings.adblock.DefaultAdBlockComponent -import org.monogram.presentation.settings.chatSettings.DefaultChatSettingsComponent -import org.monogram.presentation.settings.dataStorage.DefaultDataStorageComponent -import org.monogram.presentation.settings.debug.DefaultDebugComponent -import org.monogram.presentation.settings.folders.DefaultFoldersComponent -import org.monogram.presentation.settings.networkUsage.DefaultNetworkUsageComponent -import org.monogram.presentation.settings.notifications.DefaultNotificationsComponent -import org.monogram.presentation.settings.powersaving.DefaultPowerSavingComponent -import org.monogram.presentation.settings.premium.DefaultPremiumComponent -import org.monogram.presentation.settings.privacy.DefaultPasscodeComponent -import org.monogram.presentation.settings.privacy.DefaultPrivacyComponent -import org.monogram.presentation.settings.profile.DefaultEditProfileComponent -import org.monogram.presentation.settings.proxy.DefaultProxyComponent -import org.monogram.presentation.settings.sessions.DefaultSessionsComponent -import org.monogram.presentation.settings.settings.DefaultSettingsComponent -import org.monogram.presentation.settings.stickers.DefaultStickersComponent -import org.monogram.presentation.settings.storage.DefaultStorageUsageComponent - -class DefaultRootComponent( - private val componentContext: AppComponentContext -) : RootComponent, AppComponentContext by componentContext { - - private val authRepository: AuthRepository = container.repositories.authRepository - private val messageRepository: MessageRepository = container.repositories.messageRepository - private val settingsRepository: SettingsRepository = container.repositories.settingsRepository - private val linkHandlerRepository: LinkHandlerRepository = container.repositories.linkHandlerRepository - private val externalProxyRepository: ExternalProxyRepository = container.repositories.externalProxyRepository - private val stickerRepository: StickerRepository = container.repositories.stickerRepository - private val messageDisplayer: MessageDisplayer = container.utils.messageDisplayer() - private val externalNavigator: ExternalNavigator = container.utils.externalNavigator() - private val downloadUtils: IDownloadUtils = container.utils.downloadUtils() - private val phoneManager: PhoneManager = container.utils.phoneManager() - private val updateRepository: UpdateRepository = container.repositories.updateRepository - private val userRepository: UserRepository = container.repositories.userRepository - private val cacheProvider: CacheProvider = container.cacheProvider - - override val appPreferences: AppPreferences = container.preferences.appPreferences - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - - private val navigation = StackNavigation() - private val scope = componentScope - - private val _stickerSetToPreview = MutableStateFlow(RootComponent.StickerPreviewState()) - override val stickerSetToPreview = _stickerSetToPreview.asStateFlow() - - private val _proxyToConfirm = MutableStateFlow(RootComponent.ProxyConfirmState()) - override val proxyToConfirm = _proxyToConfirm.asStateFlow() - - private val _chatToConfirmJoin = MutableStateFlow(RootComponent.ChatConfirmJoinState()) - override val chatToConfirmJoin = _chatToConfirmJoin.asStateFlow() - - private val _isLocked = MutableStateFlow(false) - override val isLocked = _isLocked.asStateFlow() - - private val _isBiometricEnabled = MutableStateFlow(false) - override val isBiometricEnabled = _isBiometricEnabled.asStateFlow() - - private val _activeChatId = MutableValue(0L) - private val activeChatId: Value = _activeChatId - - override val childStack: Value> = childStack( - source = navigation, - serializer = Config.serializer(), - initialConfiguration = Config.Startup, - handleBackButton = true, - childFactory = ::createChild, - key = "RootStack" - ) - - init { - childStack.subscribe { stack -> - _activeChatId.update { (stack.active.configuration as? Config.ChatDetail)?.chatId ?: 0L } - } - - observeAuthState() - observeMaintenanceSettings() - observeBiometricSettings() - observeStickerLoading() - checkLockState() - updateSimCountryIso() - initExternalProxies() - } - - private fun observeAuthState() { - authRepository.authState - .onEach { state -> - val activeConfig = childStack.value.active.configuration - when (state) { - is AuthStep.Ready -> { - if (activeConfig is Config.Auth || activeConfig is Config.Startup) { - navigation.replaceAll(Config.Chats()) - } - } - - is AuthStep.InputPhone, - is AuthStep.InputCode, - is AuthStep.InputPassword -> { - _isLocked.update { false } - appPreferences.setPasscode(null) - appPreferences.setBiometricEnabled(false) - if (activeConfig !is Config.Auth) { - navigation.replaceAll(Config.Auth) - } - } - - is AuthStep.Loading, - is AuthStep.WaitParameters -> { - if (activeConfig !is Config.Startup && activeConfig !is Config.Auth) { - navigation.replaceAll(Config.Startup) - } - } - } - } - .launchIn(scope) - } - - private fun observeMaintenanceSettings() { - combine(appPreferences.cacheLimitSize, appPreferences.autoClearCacheTime) { limit, time -> - limit to time - }.onEach { (limit, time) -> - val ttl = if (time > 0) time * 24 * 60 * 60 else -1 - settingsRepository.setDatabaseMaintenanceSettings(limit, ttl) - }.launchIn(scope) - } - - private fun observeBiometricSettings() { - appPreferences.isBiometricEnabled - .onEach { bool -> _isBiometricEnabled.update { bool } } - .launchIn(scope) - } - - private fun observeStickerLoading() { - authRepository.authState - .filterIsInstance() - .onEach { - stickerRepository.loadInstalledStickerSets() - stickerRepository.loadCustomEmojiStickerSets() - } - .launchIn(scope) - } - - private fun checkLockState() { - scope.launch { - if (appPreferences.passcode.first() != null) { - _isLocked.update { true } - } - } - } - - private fun updateSimCountryIso() { - val countryCode = phoneManager.getSimCountryIso() - if (!countryCode.isNullOrBlank()) { - scope.launch { - settingsRepository.setCachedSimCountryIso(countryCode) - } - } - } - - private fun initExternalProxies() { - scope.launch { - if (appPreferences.isTelegaProxyEnabled.first()) { - fetchExternalProxies() - } - } - } - - private suspend fun fetchExternalProxies() { - Log.d("RootComponent", "Fetching external proxies...") - val addedProxies = externalProxyRepository.fetchExternalProxies() - Log.d("RootComponent", "Added ${addedProxies.size} proxies. Starting ping...") - - coroutineScope { - addedProxies.forEach { proxy -> - launch { - externalProxyRepository.pingProxy(proxy.id) - } - } - } - Log.d("RootComponent", "Finished pinging external proxies") - } - - override fun onBack() { - navigation.pop() - } - - override fun onSettingsClick() { - navigation.bringToFront(Config.Settings) - } - - override fun onChatsClick() { - navigation.popWhile { it !is Config.Chats } - } - - override fun dismissStickerPreview() { - _stickerSetToPreview.update { it.copy(stickerSet = null) } - } - - override fun handleLink(link: String) { - scope.launch { - coRunCatching { - linkHandlerRepository.handleLink(link) - }.onSuccess { action -> - processLinkAction(action, link) - }.onFailure { e -> - Log.e("RootComponent", "Error handling link: $link", e) - messageDisplayer.show("Error handling link") - openBrowser(link) - } - } - } - - private suspend fun processLinkAction(action: LinkAction, originalLink: String) { - when (action) { - is LinkAction.OpenChat -> navigateToChat(action.chatId) - is LinkAction.OpenUser -> navigation.bringToFront(Config.Profile(action.userId)) - is LinkAction.OpenMessage -> navigateToChat(action.chatId, action.messageId) - - is LinkAction.OpenSettings -> { - val config = when (action.settingsType) { - LinkAction.SettingsType.MAIN -> Config.Settings - LinkAction.SettingsType.PRIVACY -> Config.Privacy - LinkAction.SettingsType.SESSIONS -> Config.SessionsConfig - LinkAction.SettingsType.FOLDERS -> Config.Folders - LinkAction.SettingsType.CHAT -> Config.ChatSettings - LinkAction.SettingsType.DATA_STORAGE -> Config.DataStorage - LinkAction.SettingsType.POWER_SAVING -> Config.PowerSaving - LinkAction.SettingsType.PREMIUM -> Config.Premium - } - navigation.bringToFront(config) - } - - is LinkAction.OpenStickerSet -> { - val set = stickerRepository.getStickerSetByName(action.name) - if (set != null) { - _stickerSetToPreview.update { it.copy(stickerSet = set.toUi()) } - } else { - messageDisplayer.show("Sticker set not found") - } - } - - is LinkAction.JoinChat -> { - val chatId = linkHandlerRepository.joinChat(action.inviteLink) - if (chatId != null) { - navigateToChat(chatId) - } - } - - is LinkAction.ConfirmJoinChat -> { - _chatToConfirmJoin.update { RootComponent.ChatConfirmJoinState(chat = action.chat, fullInfo = action.fullInfo) } - } - - is LinkAction.ConfirmJoinInviteLink -> { - _chatToConfirmJoin.update { - RootComponent.ChatConfirmJoinState( - inviteLink = action.inviteLink, - inviteTitle = action.title, - inviteDescription = action.description, - inviteMemberCount = action.memberCount, - inviteAvatarPath = action.avatarPath, - inviteIsChannel = action.isChannel - ) - } - } - - is LinkAction.OpenWebApp -> openBrowser(action.url) - is LinkAction.OpenExternalLink -> openBrowser(action.url) - is LinkAction.OpenActiveSessions -> navigation.bringToFront(Config.SessionsConfig) - is LinkAction.ShowToast -> messageDisplayer.show(action.message) - is LinkAction.AddProxy -> { - _proxyToConfirm.update { - RootComponent.ProxyConfirmState( - server = action.server, - port = action.port, - type = action.type, - ping = null, - isChecking = true - ) - } - recheckProxyPing() - } - LinkAction.None -> openBrowser(originalLink) - } - } - - override fun dismissProxyConfirm() { - _proxyToConfirm.update { RootComponent.ProxyConfirmState() } - } - - override fun confirmProxy(server: String, port: Int, type: ProxyTypeModel) { - scope.launch { - externalProxyRepository.addProxy(server, port, true, type) - dismissProxyConfirm() - messageDisplayer.show("Proxy added and enabled") - } - } - - override fun recheckProxyPing() { - val currentState = _proxyToConfirm.value - val server = currentState.server ?: return - val port = currentState.port ?: return - val type = currentState.type ?: return - - _proxyToConfirm.update { it.copy(isChecking = true, ping = null) } - - scope.launch { - val ping = try { - withContext(Dispatchers.IO) { - externalProxyRepository.testProxy(server, port, type) - } ?: -1L - } catch (e: Exception) { - -1L - } - - if (_proxyToConfirm.value.server == server && _proxyToConfirm.value.port == port) { - _proxyToConfirm.update { it.copy(ping = ping, isChecking = false) } - } - } - } - - override fun dismissChatConfirmJoin() { - _chatToConfirmJoin.update { RootComponent.ChatConfirmJoinState() } - } - - override fun confirmJoinChat(chatId: Long) { - scope.launch { - messageRepository.joinChat(chatId) - dismissChatConfirmJoin() - navigateToChat(chatId) - } - } - - override fun confirmJoinInviteLink(inviteLink: String) { - scope.launch { - val chatId = linkHandlerRepository.joinChat(inviteLink) - dismissChatConfirmJoin() - if (chatId != null) { - navigateToChat(chatId) - } - } - } - - override fun unlock(passcode: String): Boolean { - val savedPasscode = appPreferences.passcode.value - return if (savedPasscode == passcode) { - _isLocked.update { false } - true - } else { - false - } - } - - override fun unlockWithBiometrics() { - _isLocked.update { false } - } - - override fun logout() { - authRepository.reset() - } - - private fun openBrowser(url: String) { - if (!url.startsWith("http")) return - navigation.push(Config.WebView(url)) - } - - override fun navigateToChat(chatId: Long, messageId: Long?) { - navigation.navigate { stack -> - val newStack = stack.filterNot { it is Config.ChatDetail && it.chatId == chatId } - newStack + Config.ChatDetail(chatId, messageId) - } - } - - @OptIn(DelicateDecomposeApi::class) - private fun createChild(config: Config, context: AppComponentContext): RootComponent.Child { - return when (config) { - is Config.Startup -> RootComponent.Child.StartupChild(DefaultStartupComponent(context)) - is Config.Auth -> RootComponent.Child.AuthChild( - DefaultAuthComponent( - context = context, - onOpenProxy = { navigation.bringToFront(Config.Proxy) } - ) - ) - is Config.Chats -> RootComponent.Child.ChatsChild( - DefaultChatListComponent( - context = context, - onSelect = { chatId, msgId -> - if (chatId == 0L) navigation.pop() else navigateToChat(chatId, msgId) - }, - onProfileSelect = { chatId -> - navigation.bringToFront(Config.Profile(chatId)) - }, - onSettingsClick = { navigation.bringToFront(Config.Settings) }, - onProxySettingsClick = { navigation.bringToFront(Config.Proxy) }, - onConfirmForward = { targetChatIds -> - if (config.forwardingMessageIds != null) { - scope.launch { - targetChatIds.forEach { targetChatId -> - config.forwardingMessageIds.forEach { msgId -> - messageRepository.forwardMessage(targetChatId, config.fromChatId ?: 0L, msgId) - } - } - } - navigation.pop() - if (targetChatIds.size == 1) navigateToChat(targetChatIds.first()) - } - }, - isForwarding = config.forwardingMessageIds != null, - onNewChatClick = { navigation.bringToFront(Config.NewChat) }, - onEditFoldersClick = { navigation.bringToFront(Config.Folders) }, - activeChatId = activeChatId - ) - ) - is Config.NewChat -> RootComponent.Child.NewChatChild( - DefaultNewChatComponent( - context = context, - onBackClicked = { navigation.pop() }, - onChatCreated = { chatId -> - navigation.pop() - navigateToChat(chatId) - }, - onProfileClicked = { userId -> - navigation.bringToFront(Config.Profile(chatId = userId)) - } - ) - ) - is Config.ChatDetail -> RootComponent.Child.ChatDetailChild( - DefaultChatComponent( - context = context, - chatId = config.chatId, - onBack = { navigation.pop() }, - onProfileClick = { navigation.bringToFront(Config.Profile(config.chatId)) }, - onForward = { fromChatId, messageIds -> - navigation.push(Config.Chats(fromChatId = fromChatId, forwardingMessageIds = messageIds)) - }, - onLink = { handleLink(it) }, - initialMessageId = config.messageId, - toProfiles = { id -> navigation.bringToFront(Config.Profile(chatId = id)) } - ) - ) - is Config.Settings -> RootComponent.Child.SettingsChild( - DefaultSettingsComponent( - context = context, - onBack = { navigation.pop() }, - onEditProfileClick = { navigation.push(Config.EditProfile) }, - onDevicesClick = { navigation.bringToFront(Config.SessionsConfig) }, - onFoldersClick = { navigation.bringToFront(Config.Folders) }, - onChatSettingsClick = { navigation.bringToFront(Config.ChatSettings) }, - onDataStorageClick = { navigation.bringToFront(Config.DataStorage) }, - onPowerSavingClick = { navigation.bringToFront(Config.PowerSaving) }, - onPremiumClick = { navigation.bringToFront(Config.Premium) }, - onPrivacyClick = { navigation.bringToFront(Config.Privacy) }, - onNotificationsClick = { navigation.bringToFront(Config.Notifications) }, - onProxySettingsClick = { navigation.bringToFront(Config.Proxy) }, - onStickersClick = { navigation.bringToFront(Config.Stickers) }, - onAboutClick = { navigation.bringToFront(Config.About) }, - onDebugClick = { navigation.bringToFront(Config.Debug) } - ) - ) - - is Config.EditProfile -> RootComponent.Child.EditProfileChild( - DefaultEditProfileComponent( - context = context, - onBackClicked = { navigation.pop() } - ) - ) - is Config.SessionsConfig -> RootComponent.Child.SessionsChild( - DefaultSessionsComponent(context = context, onBack = { navigation.pop() }) - ) - is Config.Folders -> RootComponent.Child.FoldersChild( - DefaultFoldersComponent(context = context, onBack = { navigation.pop() }) - ) - is Config.ChatSettings -> RootComponent.Child.ChatSettingsChild( - DefaultChatSettingsComponent( - context = context, - onBack = { navigation.pop() }, - onAdBlock = { navigation.bringToFront(Config.AdBlock) }) - ) - is Config.DataStorage -> RootComponent.Child.DataStorageChild( - DefaultDataStorageComponent( - context = context, - onBack = { navigation.pop() }, - onStorageUsage = { navigation.bringToFront(Config.StorageUsage) }, - onNetworkUsage = { navigation.bringToFront(Config.NetworkUsage) }) - ) - is Config.StorageUsage -> RootComponent.Child.StorageUsageChild( - DefaultStorageUsageComponent(context = context, onBack = { navigation.pop() }) - ) - is Config.NetworkUsage -> RootComponent.Child.NetworkUsageChild( - DefaultNetworkUsageComponent(context = context, onBack = { navigation.pop() }) - ) - is Config.Profile -> RootComponent.Child.ProfileChild( - DefaultProfileComponent( - context = context, - chatId = config.chatId, - onBackClicked = { navigation.pop() }, - onMessageClicked = { message -> - val path = when (val content = message.content) { - is MessageContent.Document -> content.path - is MessageContent.Voice -> content.path - else -> null - } - if (path != null) downloadUtils.openFile(path) - else messageDisplayer.show("Not implemented") - }, - onAvatarClicked = { }, - onEditClicked = { - scope.launch { - val me = userRepository.getMe() - if (config.chatId == me.id) { - navigation.push(Config.EditProfile) - } else { - navigation.push(Config.ChatEdit(config.chatId)) - } - } - }, - onSendMessageClicked = { navigateToChat(it) }, - onShowLogsClicked = { navigation.push(Config.ProfileLogs(it)) }, - onMemberLongClicked = { chatId, userId -> navigation.push(Config.AdminManage(chatId, userId)) } - ) - ) - is Config.Premium -> RootComponent.Child.PremiumChild( - DefaultPremiumComponent(context = context, onBack = { navigation.pop() }) - ) - is Config.Privacy -> RootComponent.Child.PrivacyChild( - DefaultPrivacyComponent( - context = context, - onBack = { navigation.pop() }, - onSessionsClick = { navigation.bringToFront(Config.SessionsConfig) }, - onProfileClick = { navigation.bringToFront(Config.Profile(it)) }, - onPasscodeClick = { navigation.push(Config.PasscodeConfig) }) - ) - is Config.AdBlock -> RootComponent.Child.AdBlockChild( - DefaultAdBlockComponent(context = context, onBack = { navigation.pop() }) - ) - is Config.PowerSaving -> RootComponent.Child.PowerSavingChild( - DefaultPowerSavingComponent(context = context, onBack = { navigation.pop() }) - ) - is Config.Notifications -> RootComponent.Child.NotificationsChild( - DefaultNotificationsComponent(context = context, onBack = { navigation.pop() }) - ) - is Config.Proxy -> RootComponent.Child.ProxyChild( - DefaultProxyComponent(context = context, onBack = { navigation.pop() }) - ) - is Config.ProfileLogs -> RootComponent.Child.ProfileLogsChild( - DefaultProfileLogsComponent( - context = context, - chatId = config.chatId, - onBackClicked = { navigation.pop() }, - onUserClicked = { navigation.bringToFront(Config.Profile(it)) }, - downloadUtils = downloadUtils - ) - ) - is Config.AdminManage -> RootComponent.Child.AdminManageChild( - DefaultAdminManageComponent( - context = context, - chatId = config.chatId, - userId = config.userId, - onBackClicked = { navigation.pop() } - ) - ) - is Config.ChatEdit -> RootComponent.Child.ChatEditChild( - DefaultChatEditComponent( - context = context, - chatId = config.chatId, - onBackClicked = { navigation.pop() }, - onManageAdminsClicked = { - navigation.push( - Config.MemberList( - it, - MemberListComponent.MemberListType.ADMINS - ) - ) - }, - onManageMembersClicked = { - navigation.push( - Config.MemberList( - it, - MemberListComponent.MemberListType.MEMBERS - ) - ) - }, - onManageBlacklistClicked = { - navigation.push( - Config.MemberList( - it, - MemberListComponent.MemberListType.BLACKLIST - ) - ) - }, - onManagePermissionsClicked = { navigation.push(Config.ChatPermissions(it)) } - ) - ) - - is Config.MemberList -> RootComponent.Child.MemberListChild( - DefaultMemberListComponent( - context = context, - chatId = config.chatId, - type = config.type, - onBackClicked = { navigation.pop() }, - onMemberClicked = { navigation.push(Config.Profile(it)) }, - onMemberLongClicked = { navigation.push(Config.AdminManage(config.chatId, it)) } - ) - ) - - is Config.ChatPermissions -> RootComponent.Child.ChatPermissionsChild( - DefaultChatPermissionsComponent( - context = context, - chatId = config.chatId, - onBackClicked = { navigation.pop() } - ) - ) - - is Config.PasscodeConfig -> RootComponent.Child.PasscodeChild( - DefaultPasscodeComponent(context = context, onBack = { navigation.pop() }) - ) - - is Config.Stickers -> RootComponent.Child.StickersChild( - DefaultStickersComponent( - context = context, - onBack = { navigation.pop() }, - onStickerSetSelect = { set -> - _stickerSetToPreview.update { it.copy(stickerSet = set.toUi()) } - } - ) - ) - - is Config.About -> RootComponent.Child.AboutChild( - DefaultAboutComponent( - context = context, - updateRepository = updateRepository, - onBack = { navigation.pop() }, - onTermsOfService = { externalNavigator.openUrl("https://telegram.org/tos") }, - onOpenSourceLicenses = { externalNavigator.openOssLicenses() } - ) - ) - - is Config.Debug -> RootComponent.Child.DebugChild( - DefaultDebugComponent( - context = context, - onBack = { navigation.pop() } - ) - ) - - is Config.WebView -> RootComponent.Child.WebViewChild( - DefaultWebViewComponent( - context = context, - url = config.url, - onDismiss = { navigation.pop() } - ) - ) - } - } - - @Serializable - sealed class Config : Parcelable { - @Parcelize @Serializable object Startup : Config() - @Parcelize @Serializable object Auth : Config() - @Parcelize @Serializable data class Chats( - val fromChatId: Long? = null, - val forwardingMessageIds: List? = null, - val activeChatId: Long? = null - ) : Config() - @Parcelize @Serializable object NewChat : Config() - @Parcelize @Serializable object SessionsConfig : Config() - @Parcelize @Serializable data class ChatDetail(val chatId: Long, val messageId: Long? = null) : Config() - @Parcelize @Serializable object Settings : Config() - @Parcelize @Serializable object EditProfile : Config() - @Parcelize @Serializable object Folders : Config() - @Parcelize @Serializable object ChatSettings : Config() - @Parcelize @Serializable object DataStorage : Config() - @Parcelize @Serializable object StorageUsage : Config() - @Parcelize @Serializable object NetworkUsage : Config() - @Parcelize @Serializable data class Profile(val chatId: Long) : Config() - @Parcelize @Serializable object Premium : Config() - @Parcelize @Serializable object Privacy : Config() - @Parcelize @Serializable object AdBlock : Config() - @Parcelize @Serializable object PowerSaving : Config() - @Parcelize @Serializable object Notifications : Config() - @Parcelize @Serializable object Proxy : Config() - @Parcelize @Serializable data class ProfileLogs(val chatId: Long) : Config() - @Parcelize @Serializable data class AdminManage(val chatId: Long, val userId: Long) : Config() - @Parcelize @Serializable data class ChatEdit(val chatId: Long) : Config() - @Parcelize @Serializable data class MemberList(val chatId: Long, val type: MemberListComponent.MemberListType) : Config() - @Parcelize @Serializable data class ChatPermissions(val chatId: Long) : Config() - @Parcelize @Serializable object PasscodeConfig : Config() - @Parcelize @Serializable object Stickers : Config() - @Parcelize @Serializable object About : Config() - @Parcelize @Serializable object Debug : Config() - @Parcelize - @Serializable - data class WebView(val url: String) : Config() - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/root/RootComponent.kt b/presentation/src/main/java/org/monogram/presentation/root/RootComponent.kt deleted file mode 100644 index 6b01b196..00000000 --- a/presentation/src/main/java/org/monogram/presentation/root/RootComponent.kt +++ /dev/null @@ -1,127 +0,0 @@ -package org.monogram.presentation.root - -import com.arkivanov.decompose.router.stack.ChildStack -import com.arkivanov.decompose.value.Value -import com.arkivanov.essenty.backhandler.BackHandler -import kotlinx.coroutines.flow.StateFlow -import kotlinx.serialization.Serializable -import org.monogram.domain.models.ChatFullInfoModel -import org.monogram.domain.models.ChatModel -import org.monogram.domain.models.ProxyTypeModel -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.features.auth.AuthComponent -import org.monogram.presentation.features.chats.ChatListComponent -import org.monogram.presentation.features.chats.currentChat.ChatComponent -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.features.chats.newChat.NewChatComponent -import org.monogram.presentation.settings.folders.FoldersComponent -import org.monogram.presentation.features.profile.ProfileComponent -import org.monogram.presentation.features.profile.admin.AdminManageComponent -import org.monogram.presentation.features.profile.admin.ChatEditComponent -import org.monogram.presentation.features.profile.admin.ChatPermissionsComponent -import org.monogram.presentation.features.profile.admin.MemberListComponent -import org.monogram.presentation.features.profile.logs.ProfileLogsComponent -import org.monogram.presentation.features.stickers.core.StickerSetUiModel -import org.monogram.presentation.features.webview.WebViewComponent -import org.monogram.presentation.settings.about.AboutComponent -import org.monogram.presentation.settings.adblock.AdBlockComponent -import org.monogram.presentation.settings.chatSettings.ChatSettingsComponent -import org.monogram.presentation.settings.dataStorage.DataStorageComponent -import org.monogram.presentation.settings.debug.DebugComponent -import org.monogram.presentation.settings.networkUsage.NetworkUsageComponent -import org.monogram.presentation.settings.notifications.NotificationsComponent -import org.monogram.presentation.settings.powersaving.PowerSavingComponent -import org.monogram.presentation.settings.premium.PremiumComponent -import org.monogram.presentation.settings.privacy.PasscodeComponent -import org.monogram.presentation.settings.privacy.PrivacyComponent -import org.monogram.presentation.settings.profile.EditProfileComponent -import org.monogram.presentation.settings.proxy.ProxyComponent -import org.monogram.presentation.settings.sessions.SessionsComponent -import org.monogram.presentation.settings.settings.SettingsComponent -import org.monogram.presentation.settings.stickers.StickersComponent -import org.monogram.presentation.settings.storage.StorageUsageComponent - -interface RootComponent { - val backHandler: BackHandler - val childStack: Value> - val stickerSetToPreview: StateFlow - val proxyToConfirm: StateFlow - val chatToConfirmJoin: StateFlow - val isLocked: StateFlow - val isBiometricEnabled: StateFlow - val videoPlayerPool: VideoPlayerPool - val appPreferences: AppPreferences - - fun onBack() - fun handleLink(link: String) - fun dismissStickerPreview() - fun onSettingsClick() - fun onChatsClick() - fun dismissProxyConfirm() - fun confirmProxy(server: String, port: Int, type: ProxyTypeModel) - fun recheckProxyPing() - fun dismissChatConfirmJoin() - fun confirmJoinChat(chatId: Long) - fun confirmJoinInviteLink(inviteLink: String) - fun unlock(passcode: String): Boolean - fun unlockWithBiometrics() - fun logout() - fun navigateToChat(chatId: Long, messageId: Long? = null) - - sealed class Child { - class StartupChild(val component: StartupComponent) : Child() - class AuthChild(val component: AuthComponent) : Child() - class ChatsChild(val component: ChatListComponent) : Child() - class NewChatChild(val component: NewChatComponent) : Child() - class ChatDetailChild(val component: ChatComponent) : Child() - class SettingsChild(val component: SettingsComponent) : Child() - class EditProfileChild(val component: EditProfileComponent) : Child() - class SessionsChild(val component: SessionsComponent) : Child() - class FoldersChild(val component: FoldersComponent) : Child() - class ChatSettingsChild(val component: ChatSettingsComponent) : Child() - class DataStorageChild(val component: DataStorageComponent) : Child() - class StorageUsageChild(val component: StorageUsageComponent) : Child() - class NetworkUsageChild(val component: NetworkUsageComponent) : Child() - class ProfileChild(val component: ProfileComponent) : Child() - class PremiumChild(val component: PremiumComponent) : Child() - class PrivacyChild(val component: PrivacyComponent) : Child() - class AdBlockChild(val component: AdBlockComponent) : Child() - class PowerSavingChild(val component: PowerSavingComponent) : Child() - class NotificationsChild(val component: NotificationsComponent) : Child() - class ProxyChild(val component: ProxyComponent) : Child() - class ProfileLogsChild(val component: ProfileLogsComponent) : Child() - class AdminManageChild(val component: AdminManageComponent) : Child() - class ChatEditChild(val component: ChatEditComponent) : Child() - class MemberListChild(val component: MemberListComponent) : Child() - class ChatPermissionsChild(val component: ChatPermissionsComponent) : Child() - class PasscodeChild(val component: PasscodeComponent) : Child() - class StickersChild(val component: StickersComponent) : Child() - class AboutChild(val component: AboutComponent) : Child() - class DebugChild(val component: DebugComponent) : Child() - class WebViewChild(val component: WebViewComponent) : Child() - } - - @Serializable - data class StickerPreviewState( - val stickerSet: StickerSetUiModel? = null - ) - - data class ProxyConfirmState( - val server: String? = null, - val port: Int? = null, - val type: ProxyTypeModel? = null, - val ping: Long? = null, - val isChecking: Boolean = false - ) - - data class ChatConfirmJoinState( - val chat: ChatModel? = null, - val fullInfo: ChatFullInfoModel? = null, - val inviteLink: String? = null, - val inviteTitle: String? = null, - val inviteDescription: String? = null, - val inviteMemberCount: Int = 0, - val inviteAvatarPath: String? = null, - val inviteIsChannel: Boolean = false - ) -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/root/StartupComponent.kt b/presentation/src/main/java/org/monogram/presentation/root/StartupComponent.kt deleted file mode 100644 index 444feed1..00000000 --- a/presentation/src/main/java/org/monogram/presentation/root/StartupComponent.kt +++ /dev/null @@ -1,89 +0,0 @@ -package org.monogram.presentation.root - -import androidx.compose.animation.core.* -import androidx.compose.foundation.Canvas -import androidx.compose.foundation.layout.* -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.StrokeCap -import androidx.compose.ui.graphics.drawscope.Stroke -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.ComponentContext -import org.monogram.presentation.R - -interface StartupComponent - -class DefaultStartupComponent( - context: AppComponentContext -) : StartupComponent, AppComponentContext by context - -@Composable -fun StartupContent() { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center - ) { - Loader() - - Spacer(modifier = Modifier.height(32.dp)) - - Text( - text = stringResource(R.string.app_name_monogram), - style = MaterialTheme.typography.headlineMedium.copy( - fontWeight = FontWeight.Bold, - letterSpacing = 2.sp - ), - color = MaterialTheme.colorScheme.primary - ) - - Text( - text = stringResource(R.string.startup_connecting), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f) - ) - } - } -} - -@Composable -private fun Loader() { - val infiniteTransition = rememberInfiniteTransition(label = "loader") - val rotation by infiniteTransition.animateFloat( - initialValue = 0f, - targetValue = 360f, - animationSpec = infiniteRepeatable( - animation = tween(1500, easing = LinearEasing), - repeatMode = RepeatMode.Restart - ), - label = "rotation" - ) - - val primaryColor = MaterialTheme.colorScheme.primary - val secondaryColor = MaterialTheme.colorScheme.primaryContainer - - Canvas(modifier = Modifier.size(64.dp)) { - drawCircle( - color = secondaryColor, - style = Stroke(width = 6.dp.toPx(), cap = StrokeCap.Round) - ) - - drawArc( - color = primaryColor, - startAngle = rotation, - sweepAngle = 90f, - useCenter = false, - style = Stroke(width = 6.dp.toPx(), cap = StrokeCap.Round) - ) - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/settings/about/AboutComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/about/AboutComponent.kt deleted file mode 100644 index 16ed9c72..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/about/AboutComponent.kt +++ /dev/null @@ -1,74 +0,0 @@ -package org.monogram.presentation.settings.about - -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.launch -import org.monogram.domain.models.UpdateState -import org.monogram.domain.repository.UpdateRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.root.AppComponentContext - -interface AboutComponent { - val updateState: StateFlow - val tdLibVersion: StateFlow - val tdLibCommitHash: StateFlow - fun onBackClicked() - fun checkForUpdates() - fun downloadUpdate() - fun installUpdate() - fun onTermsOfServiceClicked() - fun onOpenSourceLicensesClicked() -} - -class DefaultAboutComponent( - context: AppComponentContext, - private val updateRepository: UpdateRepository, - private val onBack: () -> Unit, - private val onTermsOfService: () -> Unit, - private val onOpenSourceLicenses: () -> Unit -) : AboutComponent, AppComponentContext by context { - - private val scope = componentScope - - private val _tdLibVersion = MutableStateFlow("Loading...") - override val tdLibVersion: StateFlow = _tdLibVersion.asStateFlow() - - private val _tdLibCommitHash = MutableStateFlow("") - override val tdLibCommitHash: StateFlow = _tdLibCommitHash.asStateFlow() - - init { - scope.launch { - _tdLibVersion.value = updateRepository.getTdLibVersion() - _tdLibCommitHash.value = updateRepository.getTdLibCommitHash() - } - } - - override val updateState: StateFlow = updateRepository.updateState - - override fun onBackClicked() { - onBack() - } - - override fun checkForUpdates() { - scope.launch { - updateRepository.checkForUpdates() - } - } - - override fun downloadUpdate() { - updateRepository.downloadUpdate() - } - - override fun installUpdate() { - updateRepository.installUpdate() - } - - override fun onTermsOfServiceClicked() { - onTermsOfService() - } - - override fun onOpenSourceLicensesClicked() { - onOpenSourceLicenses() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/about/AboutContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/about/AboutContent.kt deleted file mode 100644 index 6b59bd5e..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/about/AboutContent.kt +++ /dev/null @@ -1,489 +0,0 @@ -package org.monogram.presentation.settings.about - -import androidx.compose.animation.AnimatedContent -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.togetherWith -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.StrokeCap -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalUriHandler -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.UpdateInfo -import org.monogram.domain.models.UpdateState -import org.monogram.presentation.R -import org.monogram.presentation.core.util.buildRichText -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsItem -import org.monogram.presentation.core.util.AppUtils - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun AboutContent(component: AboutComponent) { - val updateState by component.updateState.collectAsState() - val tdLibVersion by component.tdLibVersion.collectAsState() - val tdLibCommitHash by component.tdLibCommitHash.collectAsState() - val uriHandler = LocalUriHandler.current - val context = LocalContext.current - val version = remember { AppUtils.getFullVersionString(context) } - val loadingText = stringResource(R.string.loading_text) - - val versionWithHashFormat = stringResource(R.string.tdlib_version_with_hash) - val displayTdLibVersion = remember(tdLibVersion, tdLibCommitHash, versionWithHashFormat, loadingText) { - if (tdLibVersion == loadingText || tdLibVersion == "Loading...") { - tdLibVersion - } else if (tdLibCommitHash.isNotEmpty()) { - String.format(versionWithHashFormat, tdLibVersion, tdLibCommitHash.take(7)) - } else { - tdLibVersion - } - } - - Scaffold( - topBar = { - TopAppBar( - title = { Text(stringResource(R.string.about_title), fontWeight = FontWeight.Bold) }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - } - ) - } - ) { padding -> - LazyColumn( - modifier = Modifier - .fillMaxSize() - .padding(top = padding.calculateTopPadding()), - contentPadding = PaddingValues(16.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - item { - Spacer(modifier = Modifier.height(24.dp)) - Surface( - modifier = Modifier.size(120.dp), - shape = RoundedCornerShape(32.dp), - color = MaterialTheme.colorScheme.primaryContainer - ) { - Image( - painter = painterResource(id = R.drawable.ic_app_logo), - contentDescription = null, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.FillBounds - ) - } - Spacer(modifier = Modifier.height(16.dp)) - Text( - text = stringResource(R.string.app_name_monogram), - style = MaterialTheme.typography.headlineMedium, - fontWeight = FontWeight.Bold - ) - Text( - text = stringResource(R.string.version_format, version), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.height(32.dp)) - } - - item { - SettingsItem( - icon = Icons.Rounded.Description, - title = stringResource(R.string.terms_of_service_title), - subtitle = stringResource(R.string.terms_of_service_subtitle), - iconBackgroundColor = Color(0xFF4285F4), - position = ItemPosition.TOP, - onClick = { uriHandler.openUri("https://telegram.org/tos") } - ) - SettingsItem( - icon = Icons.Rounded.Code, - title = stringResource(R.string.open_source_licenses_title), - subtitle = stringResource(R.string.open_source_licenses_subtitle), - iconBackgroundColor = Color(0xFF34A853), - position = ItemPosition.MIDDLE, - onClick = component::onOpenSourceLicensesClicked - ) - - SettingsItem( - icon = Icons.Rounded.Public, - title = stringResource(R.string.github_title), - subtitle = stringResource(R.string.github_subtitle), - iconBackgroundColor = Color(0xFF24292E), - position = ItemPosition.MIDDLE, - onClick = { uriHandler.openUri("https://github.com/monogram-android/monogram") } - ) - - SettingsItem( - icon = Icons.Rounded.Terminal, - title = stringResource(R.string.tdlib_version_title), - subtitle = displayTdLibVersion, - iconBackgroundColor = Color(0xFF673AB7), - position = ItemPosition.MIDDLE, - onClick = { - if (tdLibCommitHash.isNotEmpty()) { - uriHandler.openUri("https://github.com/tdlib/td/commit/$tdLibCommitHash") - } - } - ) - - UpdateSection(updateState, component) - } - - item { - Spacer(modifier = Modifier.height(16.dp)) - Text( - text = stringResource(R.string.community_section), - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.primary, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp) - ) - SettingsItem( - icon = Icons.Rounded.Forum, - title = stringResource(R.string.telegram_chat_title), - subtitle = stringResource(R.string.telegram_chat_subtitle), - iconBackgroundColor = Color(0xFF0088CC), - position = ItemPosition.TOP, - onClick = { uriHandler.openUri("https://t.me/monogram_discuss") } - ) - SettingsItem( - icon = Icons.Rounded.Announcement, - title = stringResource(R.string.telegram_channel_title), - subtitle = stringResource(R.string.telegram_channel_subtitle), - iconBackgroundColor = Color(0xFF0088CC), - position = ItemPosition.MIDDLE, - onClick = { uriHandler.openUri("https://t.me/monogram_android") } - ) - SettingsItem( - icon = Icons.Rounded.Favorite, - title = stringResource(R.string.support_monogram_title), - subtitle = stringResource(R.string.support_monogram_subtitle), - iconBackgroundColor = Color(0xFFFF5F2C), - position = ItemPosition.BOTTOM, - onClick = { uriHandler.openUri("https://boosty.to/monogram") } - ) - } - - item { - Spacer(modifier = Modifier.height(16.dp)) - Text( - text = stringResource(R.string.maintainers_section), - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.primary, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp) - ) - SettingsItem( - icon = Icons.Rounded.Person, - title = "gdlbo", - subtitle = stringResource(R.string.role_developer), - iconBackgroundColor = Color(0xFF607D8B), - position = ItemPosition.TOP, - onClick = { uriHandler.openUri("https://t.me/gdlbo") } - ) - SettingsItem( - icon = Icons.Rounded.Person, - title = "Rozetka_img", - subtitle = stringResource(R.string.role_developer), - iconBackgroundColor = Color(0xFF607D8B), - position = ItemPosition.MIDDLE, - onClick = { uriHandler.openUri("https://t.me/Rozetka_img") } - ) - SettingsItem( - icon = Icons.Rounded.Person, - title = "aliveoutside", - subtitle = stringResource(R.string.role_developer), - iconBackgroundColor = Color(0xFF607D8B), - position = ItemPosition.MIDDLE, - onClick = { uriHandler.openUri("https://t.me/toxyxd") } - ) - SettingsItem( - icon = Icons.Rounded.Person, - title = "recodius", - subtitle = stringResource(R.string.role_developer), - iconBackgroundColor = Color(0xFF607D8B), - position = ItemPosition.MIDDLE, - onClick = { uriHandler.openUri("https://t.me/recodius") } - ) - SettingsItem( - icon = Icons.Rounded.Brush, - title = "the8055u", - subtitle = stringResource(R.string.role_designer), - iconBackgroundColor = Color(0xFF607D8B), - position = ItemPosition.BOTTOM, - onClick = { uriHandler.openUri("https://t.me/the8055u") } - ) - } - - item { - Spacer(modifier = Modifier.height(32.dp)) - Text( - text = stringResource(R.string.monogram_description), - style = MaterialTheme.typography.bodyMedium, - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(horizontal = 16.dp) - ) - Spacer(modifier = Modifier.height(24.dp)) - Text( - text = stringResource(R.string.copyright_text), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.outline - ) - Spacer(modifier = Modifier.height(padding.calculateBottomPadding())) - } - } - } -} - -@Composable -private fun UpdateSection(state: UpdateState, component: AboutComponent) { - var showChangelog by remember { mutableStateOf(false) } - - AnimatedContent( - targetState = state is UpdateState.Downloading, - transitionSpec = { fadeIn() togetherWith fadeOut() }, - label = "UpdateSectionAnimation" - ) { isDownloading -> - if (isDownloading && state is UpdateState.Downloading) { - DownloadingUpdateItem(state) - } else { - val title = when (state) { - is UpdateState.Idle -> stringResource(R.string.check_for_updates) - is UpdateState.Checking -> stringResource(R.string.checking_updates) - is UpdateState.UpdateAvailable -> stringResource(R.string.update_available_format, state.info.version) - is UpdateState.UpToDate -> stringResource(R.string.up_to_date) - is UpdateState.ReadyToInstall -> stringResource(R.string.update_ready) - is UpdateState.Error -> stringResource(R.string.update_error) - else -> "" - } - - val subtitle = when (state) { - is UpdateState.Idle -> stringResource(R.string.check_update_subtitle) - is UpdateState.Checking -> stringResource(R.string.connecting_server_subtitle) - is UpdateState.UpdateAvailable -> stringResource(R.string.update_available_subtitle) - is UpdateState.UpToDate -> stringResource(R.string.latest_version_subtitle) - is UpdateState.ReadyToInstall -> stringResource(R.string.install_update_subtitle) - is UpdateState.Error -> state.message - else -> "" - } - - val icon = when (state) { - is UpdateState.ReadyToInstall -> Icons.Rounded.SystemUpdate - is UpdateState.Error -> Icons.Rounded.Error - else -> Icons.Rounded.Update - } - - SettingsItem( - icon = icon, - title = title, - subtitle = subtitle, - iconBackgroundColor = Color(0xFFF9AB00), - position = ItemPosition.BOTTOM, - onClick = { - when (state) { - is UpdateState.Idle, is UpdateState.UpToDate, is UpdateState.Error -> component.checkForUpdates() - is UpdateState.UpdateAvailable -> { - if (state.info.changelog.isNotEmpty()) { - showChangelog = true - } else { - component.downloadUpdate() - } - } - - is UpdateState.ReadyToInstall -> component.installUpdate() - else -> {} - } - } - ) - } - } - - if (showChangelog && state is UpdateState.UpdateAvailable) { - ChangelogSheet( - info = state.info, - onDismiss = { showChangelog = false }, - onDownload = { - showChangelog = false - component.downloadUpdate() - } - ) - } -} - -@Composable -private fun DownloadingUpdateItem(state: UpdateState.Downloading) { - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape( - bottomStart = 24.dp, - bottomEnd = 24.dp, - topStart = 4.dp, - topEnd = 4.dp - ), - modifier = Modifier.fillMaxWidth() - ) { - Column( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 16.dp) - ) { - Row( - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(40.dp) - .background(color = Color(0xFFF9AB00).copy(0.15f), shape = CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.Download, - contentDescription = null, - modifier = Modifier.size(24.dp), - tint = Color(0xFFF9AB00) - ) - } - Spacer(modifier = Modifier.width(16.dp)) - Column(modifier = Modifier.weight(1f)) { - Text( - text = stringResource(R.string.downloading_update), - style = MaterialTheme.typography.titleMedium, - fontSize = 18.sp - ) - Text( - text = stringResource(R.string.update_progress_format, (state.progress * 100).toInt()), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - Spacer(modifier = Modifier.height(12.dp)) - val animatedProgress by animateFloatAsState(targetValue = state.progress, label = "progress") - LinearProgressIndicator( - progress = { animatedProgress }, - modifier = Modifier - .fillMaxWidth() - .height(6.dp), - color = Color(0xFFF9AB00), - trackColor = Color(0xFFF9AB00).copy(alpha = 0.2f), - strokeCap = StrokeCap.Round - ) - } - } - Spacer(Modifier.size(2.dp)) -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun ChangelogSheet( - info: UpdateInfo, - onDismiss: () -> Unit, - onDownload: () -> Unit -) { - ModalBottomSheet( - onDismissRequest = onDismiss, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 32.dp) - ) { - Text( - text = stringResource(R.string.whats_new_format, info.version), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(horizontal = 4.dp) - ) - - Spacer(modifier = Modifier.height(16.dp)) - - Surface( - modifier = Modifier.fillMaxWidth(), - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp) - ) { - Column( - modifier = Modifier.padding(16.dp), - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - info.changelog.forEach { change -> - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.Top - ) { - Text( - text = "•", - style = MaterialTheme.typography.bodyMedium, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(end = 8.dp) - ) - Text( - text = buildRichText(change, MaterialTheme.colorScheme.primary), - style = MaterialTheme.typography.bodyMedium - ) - } - } - } - } - - Spacer(modifier = Modifier.height(24.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - OutlinedButton( - onClick = onDismiss, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.cancel_button), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - - Button( - onClick = onDownload, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text( - stringResource(R.string.download_update_action), - fontSize = 16.sp, - fontWeight = FontWeight.Bold - ) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/adblock/AdBlockComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/adblock/AdBlockComponent.kt deleted file mode 100644 index b8ff7bda..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/adblock/AdBlockComponent.kt +++ /dev/null @@ -1,183 +0,0 @@ -package org.monogram.presentation.settings.adblock - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.monogram.domain.managers.AssetsManager -import org.monogram.domain.managers.ClipManager -import org.monogram.domain.models.ChatModel -import org.monogram.domain.repository.ChatsListRepository -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.root.AppComponentContext - -interface AdBlockComponent { - val state: Value - val videoPlayerPool: VideoPlayerPool - fun onBackClicked() - fun onAdBlockEnabledChanged(enabled: Boolean) - fun onAddKeywords(keywords: String) - fun onRemoveKeyword(keyword: String) - fun onClearKeywords() - fun onCopyKeywords() - fun onRemoveWhitelistedChannel(channelId: Long) - fun onClearWhitelistedChannels() - fun onLoadFromAssets() - fun onWhitelistedChannelsClicked() - fun onAddKeywordClicked() - fun onDismissBottomSheet() - - data class State( - val isEnabled: Boolean = false, - val keywords: Set = emptySet(), - val whitelistedChannels: Set = emptySet(), - val isLoading: Boolean = false, - val showWhitelistedSheet: Boolean = false, - val showAddKeywordSheet: Boolean = false, - val whitelistedChannelModels: List = emptyList() - ) -} - -class DefaultAdBlockComponent( - context: AppComponentContext, - private val onBack: () -> Unit -) : AdBlockComponent, AppComponentContext by context { - - private val appPreferences: AppPreferences = container.preferences.appPreferences - private val chatsRepository: ChatsListRepository = container.repositories.chatsListRepository - private val clipManager: ClipManager = container.utils.clipManager - private val assetsManager: AssetsManager = container.utils.assetsManager() - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - - private val _state = MutableValue( - AdBlockComponent.State( - isEnabled = appPreferences.isAdBlockEnabled.value, - keywords = appPreferences.adBlockKeywords.value, - whitelistedChannels = appPreferences.adBlockWhitelistedChannels.value - ) - ) - override val state: Value = _state - private val scope = componentScope - - init { - appPreferences.isAdBlockEnabled - .onEach { enabled -> - _state.update { it.copy(isEnabled = enabled) } - } - .launchIn(scope) - - appPreferences.adBlockKeywords - .onEach { keywords -> - _state.update { it.copy(keywords = keywords) } - } - .launchIn(scope) - - appPreferences.adBlockWhitelistedChannels - .onEach { channels -> - _state.update { it.copy(whitelistedChannels = channels) } - if (_state.value.showWhitelistedSheet) { - loadWhitelistedModels(channels) - } - } - .launchIn(scope) - } - - private fun loadWhitelistedModels(channels: Set) { - scope.launch { - val models = channels.mapNotNull { chatsRepository.getChatById(it) } - _state.update { it.copy(whitelistedChannelModels = models) } - } - } - - override fun onBackClicked() { - onBack() - } - - override fun onAdBlockEnabledChanged(enabled: Boolean) { - appPreferences.setAdBlockEnabled(enabled) - } - - override fun onAddKeywords(keywords: String) { - if (keywords.isBlank()) return - val newKeywords = keywords.split(Regex("[,\\n]")) - .map { it.trim() } - .filter { it.isNotBlank() } - - val current = appPreferences.adBlockKeywords.value.toMutableSet() - if (current.addAll(newKeywords)) { - appPreferences.setAdBlockKeywords(current) - } - onDismissBottomSheet() - } - - override fun onRemoveKeyword(keyword: String) { - val current = appPreferences.adBlockKeywords.value.toMutableSet() - if (current.remove(keyword)) { - appPreferences.setAdBlockKeywords(current) - } - } - - override fun onClearKeywords() { - appPreferences.setAdBlockKeywords(emptySet()) - } - - override fun onCopyKeywords() { - val text = _state.value.keywords.joinToString("\n") - clipManager.copyToClipboard("AdBlock Keywords", text) - } - - override fun onRemoveWhitelistedChannel(channelId: Long) { - val current = appPreferences.adBlockWhitelistedChannels.value.toMutableSet() - if (current.remove(channelId)) { - appPreferences.setAdBlockWhitelistedChannels(current) - } - } - - override fun onClearWhitelistedChannels() { - appPreferences.setAdBlockWhitelistedChannels(emptySet()) - } - - override fun onLoadFromAssets() { - scope.launch { - _state.update { it.copy(isLoading = true) } - val keywords = withContext(Dispatchers.IO) { - try { - assetsManager.getAssets("adblock_keywords.txt").bufferedReader().useLines { lines -> - lines.filter { it.isNotBlank() }.toSet() - } - } catch (e: Exception) { - emptySet() - } - } - val current = appPreferences.adBlockKeywords.value.toMutableSet() - current.addAll(keywords) - appPreferences.setAdBlockKeywords(current) - _state.update { it.copy(isLoading = false) } - } - } - - override fun onWhitelistedChannelsClicked() { - _state.update { it.copy(showWhitelistedSheet = true) } - loadWhitelistedModels(_state.value.whitelistedChannels) - } - - override fun onAddKeywordClicked() { - _state.update { it.copy(showAddKeywordSheet = true) } - } - - override fun onDismissBottomSheet() { - _state.update { - it.copy( - showWhitelistedSheet = false, - showAddKeywordSheet = false, - whitelistedChannelModels = emptyList() - ) - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/settings/adblock/AdBlockContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/adblock/AdBlockContent.kt deleted file mode 100644 index abec95cc..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/adblock/AdBlockContent.kt +++ /dev/null @@ -1,468 +0,0 @@ -package org.monogram.presentation.settings.adblock - -import androidx.compose.animation.* -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.automirrored.rounded.Label -import androidx.compose.material.icons.automirrored.rounded.PlaylistAddCheck -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.domain.models.ChatModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.features.chats.chatList.components.SettingsTextField -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsSwitchTile -import org.monogram.presentation.core.ui.SettingsTile - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun AdBlockContent(component: AdBlockComponent) { - val state by component.state.subscribeAsState() - - Scaffold( - topBar = { - TopAppBar( - title = { - Text( - text = stringResource(R.string.adblock_channels_title), - fontSize = 22.sp, - fontWeight = FontWeight.Bold - ) - }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background - ) - ) - }, - floatingActionButton = { - AnimatedVisibility( - visible = state.isEnabled, - enter = scaleIn() + fadeIn(), - exit = scaleOut() + fadeOut() - ) { - FloatingActionButton(onClick = component::onAddKeywordClicked) { - Icon( - Icons.Rounded.Add, - contentDescription = stringResource(R.string.cd_add_keyword) - ) - } - } - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - LazyColumn( - modifier = Modifier - .fillMaxSize() - .padding(top = padding.calculateTopPadding()), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, top = 0.dp, bottom = 16.dp) - ) { - item { - SectionHeader(stringResource(R.string.section_general)) - SettingsSwitchTile( - icon = Icons.Rounded.Block, - title = stringResource(R.string.adblock_enable), - subtitle = stringResource(R.string.adblock_channels_subtitle), - checked = state.isEnabled, - iconColor = Color.Red, - position = if (state.isEnabled) ItemPosition.TOP else ItemPosition.STANDALONE, - onCheckedChange = component::onAdBlockEnabledChanged - ) - if (state.isEnabled) { - SettingsTile( - icon = Icons.AutoMirrored.Rounded.PlaylistAddCheck, - title = stringResource(R.string.adblock_whitelisted_channels), - subtitle = stringResource( - R.string.adblock_channels_count_format, - state.whitelistedChannels.size - ), - iconColor = MaterialTheme.colorScheme.primary, - position = ItemPosition.MIDDLE, - onClick = component::onWhitelistedChannelsClicked - ) - SettingsTile( - icon = Icons.Rounded.Download, - title = stringResource(R.string.adblock_load_base), - subtitle = stringResource(R.string.adblock_load_base_subtitle), - iconColor = MaterialTheme.colorScheme.secondary, - position = if (state.keywords.isNotEmpty()) ItemPosition.MIDDLE else ItemPosition.BOTTOM, - onClick = component::onLoadFromAssets - ) - if (state.keywords.isNotEmpty()) { - SettingsTile( - icon = Icons.Rounded.ContentCopy, - title = stringResource(R.string.adblock_copy_all), - subtitle = stringResource(R.string.adblock_copy_all_subtitle), - iconColor = MaterialTheme.colorScheme.tertiary, - position = ItemPosition.MIDDLE, - onClick = component::onCopyKeywords - ) - SettingsTile( - icon = Icons.Rounded.DeleteSweep, - title = stringResource(R.string.adblock_clear_all), - subtitle = stringResource(R.string.adblock_clear_all_subtitle), - iconColor = MaterialTheme.colorScheme.error, - position = ItemPosition.BOTTOM, - onClick = component::onClearKeywords - ) - } - } - } - - if (state.isEnabled) { - item { - SectionHeader(stringResource(R.string.adblock_keywords_section)) - } - val keywordsList = state.keywords.toList() - if (keywordsList.isEmpty()) { - item { - EmptyKeywordsPlaceholder() - } - } else { - itemsIndexed(keywordsList, key = { index, keyword -> "keyword_${index}_$keyword" }) { index, keyword -> - val position = when { - keywordsList.size == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == keywordsList.size - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - KeywordItem( - keyword = keyword, - position = position, - onRemove = { component.onRemoveKeyword(keyword) } - ) - } - } - } - item { Spacer(modifier = Modifier.height(padding.calculateBottomPadding())) } - } - } - - if (state.showAddKeywordSheet) { - AddKeywordBottomSheet( - onDismiss = component::onDismissBottomSheet, - onConfirm = component::onAddKeywords - ) - } - - if (state.showWhitelistedSheet) { - WhitelistedChannelsBottomSheet( - channels = state.whitelistedChannelModels, - onDismiss = component::onDismissBottomSheet, - onRemove = component::onRemoveWhitelistedChannel, - onClear = component::onClearWhitelistedChannels, - videoPlayerPool = component.videoPlayerPool - ) - } -} - -@Composable -private fun KeywordItem(keyword: String, position: ItemPosition, onRemove: () -> Unit) { - SettingsTile( - icon = Icons.AutoMirrored.Rounded.Label, - title = keyword, - iconColor = MaterialTheme.colorScheme.primary, - position = position, - onClick = {}, - trailingContent = { - IconButton(onClick = onRemove) { - Icon( - Icons.Rounded.Delete, - contentDescription = stringResource(R.string.action_delete), - tint = MaterialTheme.colorScheme.error - ) - } - } - ) -} - -@Composable -private fun EmptyKeywordsPlaceholder() { - Surface( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 8.dp), - shape = RoundedCornerShape(24.dp), - color = MaterialTheme.colorScheme.surfaceContainer - ) { - Column( - modifier = Modifier.padding(24.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Icon( - Icons.Rounded.Search, - contentDescription = null, - modifier = Modifier.size(48.dp), - tint = MaterialTheme.colorScheme.outlineVariant - ) - Spacer(modifier = Modifier.height(12.dp)) - Text( - text = stringResource(R.string.adblock_no_keywords), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Text( - text = stringResource(R.string.adblock_no_keywords_subtitle), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center - ) - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun AddKeywordBottomSheet( - onDismiss: () -> Unit, - onConfirm: (String) -> Unit -) { - var text by remember { mutableStateOf("") } - ModalBottomSheet( - onDismissRequest = onDismiss, - sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true), - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 32.dp) - .navigationBarsPadding(), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Box( - modifier = Modifier - .size(64.dp) - .background(MaterialTheme.colorScheme.primaryContainer, CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - Icons.Rounded.AddCircleOutline, - contentDescription = null, - modifier = Modifier.size(32.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - - Spacer(modifier = Modifier.height(16.dp)) - - Text( - text = stringResource(R.string.adblock_add_keywords_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - - Spacer(modifier = Modifier.height(8.dp)) - - Text( - text = stringResource(R.string.adblock_add_keywords_description), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center - ) - - Spacer(modifier = Modifier.height(24.dp)) - - SettingsTextField( - value = text, - onValueChange = { text = it }, - placeholder = stringResource(R.string.adblock_add_keywords_placeholder), - icon = Icons.Rounded.Edit, - position = ItemPosition.STANDALONE, - minLines = 4 - ) - - Spacer(modifier = Modifier.height(24.dp)) - - Button( - onClick = { onConfirm(text) }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - enabled = text.isNotBlank(), - shape = RoundedCornerShape(16.dp) - ) { - Text( - text = stringResource(R.string.adblock_add_to_list), - fontSize = 16.sp, - fontWeight = FontWeight.SemiBold - ) - } - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun WhitelistedChannelsBottomSheet( - channels: List, - videoPlayerPool: VideoPlayerPool, - onDismiss: () -> Unit, - onRemove: (Long) -> Unit, - onClear: () -> Unit -) { - ModalBottomSheet( - onDismissRequest = onDismiss, - sheetState = rememberModalBottomSheetState(), - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 32.dp) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp, vertical = 8.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Column { - Text( - text = stringResource(R.string.adblock_whitelisted_channels), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - Text( - text = stringResource(R.string.adblock_whitelisted_subtitle), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - - if (channels.isNotEmpty()) { - IconButton( - onClick = onClear, - colors = IconButtonDefaults.iconButtonColors( - containerColor = MaterialTheme.colorScheme.errorContainer.copy(alpha = 0.2f) - ) - ) { - Icon( - Icons.Rounded.DeleteSweep, - contentDescription = stringResource(R.string.action_clear_all), - tint = MaterialTheme.colorScheme.error - ) - } - } - } - - Spacer(modifier = Modifier.height(16.dp)) - - if (channels.isEmpty()) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(48.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Icon( - Icons.AutoMirrored.Rounded.PlaylistAddCheck, - contentDescription = null, - modifier = Modifier.size(64.dp), - tint = MaterialTheme.colorScheme.outlineVariant - ) - Spacer(modifier = Modifier.height(16.dp)) - Text( - text = stringResource(R.string.adblock_no_whitelisted), - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } else { - LazyColumn( - modifier = Modifier - .fillMaxWidth() - .heightIn(max = 400.dp), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, bottom = 16.dp) - ) { - items(channels, key = { it.id }) { channel -> - ListItem( - headlineContent = { - Text( - text = channel.title, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - fontWeight = FontWeight.Medium - ) - }, - supportingContent = { - Text( - text = "ID: ${channel.id}", - style = MaterialTheme.typography.bodySmall - ) - }, - leadingContent = { - Avatar( - path = channel.avatarPath, - fallbackPath = channel.personalAvatarPath, - name = channel.title, - videoPlayerPool = videoPlayerPool, - size = 48.dp - ) - }, - trailingContent = { - IconButton( - onClick = { onRemove(channel.id) }, - colors = IconButtonDefaults.iconButtonColors( - contentColor = MaterialTheme.colorScheme.error - ) - ) { - Icon( - Icons.Rounded.Delete, - contentDescription = stringResource(R.string.action_remove) - ) - } - }, - colors = ListItemDefaults.colors(containerColor = Color.Transparent) - ) - } - } - } - } - } -} - -@Composable -private fun SectionHeader(text: String) { - Text( - text = text, - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp, top = 16.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/ChatSettingsComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/ChatSettingsComponent.kt deleted file mode 100644 index 0ec26e30..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/ChatSettingsComponent.kt +++ /dev/null @@ -1,1128 +0,0 @@ -package org.monogram.presentation.settings.chatSettings - -import org.monogram.presentation.core.util.coRunCatching -import android.graphics.Color.colorToHSV -import android.graphics.Color.HSVToColor -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.monogram.domain.managers.AssetsManager -import org.monogram.domain.managers.DistrManager -import org.monogram.domain.models.WallpaperModel -import org.monogram.domain.repository.SettingsRepository -import org.monogram.domain.repository.StickerRepository -import org.monogram.presentation.core.util.* -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.root.AppComponentContext -import org.json.JSONObject -import java.io.File -import java.net.URL - -interface ChatSettingsComponent { - val state: Value - val downloadUtils: IDownloadUtils - val videoPlayerPool: VideoPlayerPool - fun onBackClicked() - fun onFontSizeChanged(size: Float) - fun onLetterSpacingChanged(size: Float) - fun onBubbleRadiusChanged(radius: Float) - fun onWallpaperChanged(wallpaper: String?) - fun onWallpaperSelected(wallpaper: WallpaperModel) - fun onWallpaperBlurChanged(wallpaper: WallpaperModel, isBlurred: Boolean) - fun onWallpaperBlurIntensityChanged(intensity: Int) - fun onWallpaperMotionChanged(wallpaper: WallpaperModel, isMoving: Boolean) - fun onWallpaperDimmingChanged(dimming: Int) - fun onWallpaperGrayscaleChanged(isGrayscale: Boolean) - fun onPlayerGesturesEnabledChanged(enabled: Boolean) - fun onPlayerDoubleTapSeekEnabledChanged(enabled: Boolean) - fun onPlayerSeekDurationChanged(duration: Int) - fun onPlayerZoomEnabledChanged(enabled: Boolean) - fun onClearRecentStickers() - fun onClearRecentEmojis() - fun onArchivePinnedChanged(pinned: Boolean) - fun onArchiveAlwaysVisibleChanged(enabled: Boolean) - fun onShowLinkPreviewsChanged(enabled: Boolean) - fun onNightModeChanged(mode: NightMode) - fun onDynamicColorsChanged(enabled: Boolean) - fun onAmoledThemeChanged(enabled: Boolean) - fun onCustomThemeEnabledChanged(enabled: Boolean) - fun onThemePrimaryColorChanged(color: Int) - fun onThemeSecondaryColorChanged(color: Int) - fun onThemeTertiaryColorChanged(color: Int) - fun onThemeBackgroundColorChanged(color: Int) - fun onThemeSurfaceColorChanged(color: Int) - fun onThemePrimaryContainerColorChanged(color: Int) - fun onThemeSecondaryContainerColorChanged(color: Int) - fun onThemeTertiaryContainerColorChanged(color: Int) - fun onThemeSurfaceVariantColorChanged(color: Int) - fun onThemeOutlineColorChanged(color: Int) - fun onThemeDarkPrimaryColorChanged(color: Int) - fun onThemeDarkSecondaryColorChanged(color: Int) - fun onThemeDarkTertiaryColorChanged(color: Int) - fun onThemeDarkBackgroundColorChanged(color: Int) - fun onThemeDarkSurfaceColorChanged(color: Int) - fun onThemeDarkPrimaryContainerColorChanged(color: Int) - fun onThemeDarkSecondaryContainerColorChanged(color: Int) - fun onThemeDarkTertiaryContainerColorChanged(color: Int) - fun onThemeDarkSurfaceVariantColorChanged(color: Int) - fun onThemeDarkOutlineColorChanged(color: Int) - fun onApplyThemeAccent(color: Int, darkPalette: Boolean) - fun exportCustomThemeJson(): String - fun importCustomThemeJson(json: String): Boolean - fun onNightModeStartTimeChanged(time: String) - fun onNightModeEndTimeChanged(time: String) - fun onNightModeBrightnessThresholdChanged(threshold: Float) - fun onDragToBackChanged(enabled: Boolean) - fun onAdBlockClick() - fun onEmojiStyleChanged(style: EmojiStyle) - fun onEmojiStyleLongClick(style: EmojiStyle) - fun onConfirmRemoveEmojiPack() - fun onDismissRemoveEmojiPack() - fun onCompressPhotosChanged(enabled: Boolean) - fun onCompressVideosChanged(enabled: Boolean) - fun onChatListMessageLinesChanged(lines: Int) - fun onShowChatListPhotosChanged(enabled: Boolean) - - data class State( - val fontSize: Float = 16f, - val letterSpacing: Float = 0f, - val bubbleRadius: Float = 18f, - val wallpaper: String? = null, - val isWallpaperBlurred: Boolean = false, - val wallpaperBlurIntensity: Int = 20, - val isWallpaperMoving: Boolean = false, - val wallpaperDimming: Int = 0, - val isWallpaperGrayscale: Boolean = false, - val availableWallpapers: List = emptyList(), - val selectedWallpaper: WallpaperModel? = null, - val isPlayerGesturesEnabled: Boolean = true, - val isPlayerDoubleTapSeekEnabled: Boolean = true, - val playerSeekDuration: Int = 10, - val isPlayerZoomEnabled: Boolean = true, - val isArchivePinned: Boolean = true, - val isArchiveAlwaysVisible: Boolean = false, - val showLinkPreviews: Boolean = true, - val nightMode: NightMode = NightMode.SYSTEM, - val isDynamicColorsEnabled: Boolean = true, - val isAmoledThemeEnabled: Boolean = false, - val isCustomThemeEnabled: Boolean = false, - val themePrimaryColor: Int = 0xFF3390EC.toInt(), - val themeSecondaryColor: Int = 0xFF4C7599.toInt(), - val themeTertiaryColor: Int = 0xFF00ACC1.toInt(), - val themeBackgroundColor: Int = 0xFFFFFBFE.toInt(), - val themeSurfaceColor: Int = 0xFFFFFBFE.toInt(), - val themePrimaryContainerColor: Int = 0xFFD4E3FF.toInt(), - val themeSecondaryContainerColor: Int = 0xFFD0E4F7.toInt(), - val themeTertiaryContainerColor: Int = 0xFFC4EEF4.toInt(), - val themeSurfaceVariantColor: Int = 0xFFE1E2EC.toInt(), - val themeOutlineColor: Int = 0xFF757680.toInt(), - val themeDarkPrimaryColor: Int = 0xFF64B5F6.toInt(), - val themeDarkSecondaryColor: Int = 0xFF81A9CA.toInt(), - val themeDarkTertiaryColor: Int = 0xFF4DD0E1.toInt(), - val themeDarkBackgroundColor: Int = 0xFF121212.toInt(), - val themeDarkSurfaceColor: Int = 0xFF121212.toInt(), - val themeDarkPrimaryContainerColor: Int = 0xFF224A77.toInt(), - val themeDarkSecondaryContainerColor: Int = 0xFF334F65.toInt(), - val themeDarkTertiaryContainerColor: Int = 0xFF1E636F.toInt(), - val themeDarkSurfaceVariantColor: Int = 0xFF44474F.toInt(), - val themeDarkOutlineColor: Int = 0xFF8E9099.toInt(), - val nightModeStartTime: String = "22:00", - val nightModeEndTime: String = "07:00", - val nightModeBrightnessThreshold: Float = 0.2f, - val isDragToBackEnabled: Boolean = true, - val emojiStyle: EmojiStyle = EmojiStyle.SYSTEM, - val isAppleEmojiDownloaded: Boolean = false, - val isTwitterEmojiDownloaded: Boolean = false, - val isWindowsEmojiDownloaded: Boolean = false, - val isCatmojiEmojiDownloaded: Boolean = false, - val isNotoEmojiDownloaded: Boolean = false, - val isAppleEmojiDownloading: Boolean = false, - val isTwitterEmojiDownloading: Boolean = false, - val isWindowsEmojiDownloading: Boolean = false, - val isCatmojiEmojiDownloading: Boolean = false, - val isNotoEmojiDownloading: Boolean = false, - val emojiPackToRemove: EmojiStyle? = null, - val compressPhotos: Boolean = true, - val compressVideos: Boolean = true, - val chatListMessageLines: Int = 1, - val showChatListPhotos: Boolean = true, - val isInstalledFromGooglePlay: Boolean = true - ) -} - -class DefaultChatSettingsComponent( - context: AppComponentContext, - private val onBack: () -> Unit, - private val onAdBlock: () -> Unit -) : ChatSettingsComponent, AppComponentContext by context { - - private val appPreferences: AppPreferences = container.preferences.appPreferences - override val downloadUtils: IDownloadUtils = container.utils.downloadUtils() - private val settingsRepository: SettingsRepository = container.repositories.settingsRepository - private val stickerRepository: StickerRepository = container.repositories.stickerRepository - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - private val distrManager: DistrManager = container.utils.distrManager() - private val assetsManager: AssetsManager = container.utils.assetsManager() - - private val _state = MutableValue( - ChatSettingsComponent.State( - fontSize = appPreferences.fontSize.value, - letterSpacing = appPreferences.letterSpacing.value, - bubbleRadius = appPreferences.bubbleRadius.value, - wallpaper = appPreferences.wallpaper.value, - isWallpaperBlurred = appPreferences.isWallpaperBlurred.value, - wallpaperBlurIntensity = appPreferences.wallpaperBlurIntensity.value, - isWallpaperMoving = appPreferences.isWallpaperMoving.value, - wallpaperDimming = appPreferences.wallpaperDimming.value, - isWallpaperGrayscale = appPreferences.isWallpaperGrayscale.value, - isPlayerGesturesEnabled = appPreferences.isPlayerGesturesEnabled.value, - isPlayerDoubleTapSeekEnabled = appPreferences.isPlayerDoubleTapSeekEnabled.value, - playerSeekDuration = appPreferences.playerSeekDuration.value, - isPlayerZoomEnabled = appPreferences.isPlayerZoomEnabled.value, - isArchivePinned = appPreferences.isArchivePinned.value, - isArchiveAlwaysVisible = appPreferences.isArchiveAlwaysVisible.value, - showLinkPreviews = appPreferences.showLinkPreviews.value, - nightMode = appPreferences.nightMode.value, - isDynamicColorsEnabled = appPreferences.isDynamicColorsEnabled.value, - isAmoledThemeEnabled = appPreferences.isAmoledThemeEnabled.value, - isCustomThemeEnabled = appPreferences.isCustomThemeEnabled.value, - themePrimaryColor = appPreferences.themePrimaryColor.value, - themeSecondaryColor = appPreferences.themeSecondaryColor.value, - themeTertiaryColor = appPreferences.themeTertiaryColor.value, - themeBackgroundColor = appPreferences.themeBackgroundColor.value, - themeSurfaceColor = appPreferences.themeSurfaceColor.value, - themePrimaryContainerColor = appPreferences.themePrimaryContainerColor.value, - themeSecondaryContainerColor = appPreferences.themeSecondaryContainerColor.value, - themeTertiaryContainerColor = appPreferences.themeTertiaryContainerColor.value, - themeSurfaceVariantColor = appPreferences.themeSurfaceVariantColor.value, - themeOutlineColor = appPreferences.themeOutlineColor.value, - themeDarkPrimaryColor = appPreferences.themeDarkPrimaryColor.value, - themeDarkSecondaryColor = appPreferences.themeDarkSecondaryColor.value, - themeDarkTertiaryColor = appPreferences.themeDarkTertiaryColor.value, - themeDarkBackgroundColor = appPreferences.themeDarkBackgroundColor.value, - themeDarkSurfaceColor = appPreferences.themeDarkSurfaceColor.value, - themeDarkPrimaryContainerColor = appPreferences.themeDarkPrimaryContainerColor.value, - themeDarkSecondaryContainerColor = appPreferences.themeDarkSecondaryContainerColor.value, - themeDarkTertiaryContainerColor = appPreferences.themeDarkTertiaryContainerColor.value, - themeDarkSurfaceVariantColor = appPreferences.themeDarkSurfaceVariantColor.value, - themeDarkOutlineColor = appPreferences.themeDarkOutlineColor.value, - nightModeStartTime = appPreferences.nightModeStartTime.value, - nightModeEndTime = appPreferences.nightModeEndTime.value, - nightModeBrightnessThreshold = appPreferences.nightModeBrightnessThreshold.value, - isDragToBackEnabled = appPreferences.isDragToBackEnabled.value, - emojiStyle = appPreferences.emojiStyle.value, - isAppleEmojiDownloaded = appPreferences.isAppleEmojiDownloaded.value, - isTwitterEmojiDownloaded = appPreferences.isTwitterEmojiDownloaded.value, - isWindowsEmojiDownloaded = appPreferences.isWindowsEmojiDownloaded.value, - isCatmojiEmojiDownloaded = appPreferences.isCatmojiEmojiDownloaded.value, - isNotoEmojiDownloaded = appPreferences.isNotoEmojiDownloaded.value, - compressPhotos = appPreferences.compressPhotos.value, - compressVideos = appPreferences.compressVideos.value, - chatListMessageLines = appPreferences.chatListMessageLines.value, - showChatListPhotos = appPreferences.showChatListPhotos.value, - isInstalledFromGooglePlay = distrManager.isInstalledFromGooglePlay() - ) - ) - override val state: Value = _state - private val scope = componentScope - - init { - appPreferences.fontSize - .onEach { size -> - _state.update { it.copy(fontSize = size) } - } - .launchIn(scope) - - appPreferences.letterSpacing - .onEach { spacing -> - _state.update { it.copy(letterSpacing = spacing) } - } - .launchIn(scope) - - appPreferences.bubbleRadius - .onEach { radius -> - _state.update { it.copy(bubbleRadius = radius) } - } - .launchIn(scope) - - appPreferences.wallpaper - .onEach { wallpaper -> - _state.update { it.copy(wallpaper = wallpaper) } - } - .launchIn(scope) - - appPreferences.isWallpaperBlurred - .onEach { blurred -> - _state.update { it.copy(isWallpaperBlurred = blurred) } - } - .launchIn(scope) - - appPreferences.wallpaperBlurIntensity - .onEach { intensity -> - _state.update { it.copy(wallpaperBlurIntensity = intensity) } - } - .launchIn(scope) - - appPreferences.isWallpaperMoving - .onEach { moving -> - _state.update { it.copy(isWallpaperMoving = moving) } - } - .launchIn(scope) - - appPreferences.wallpaperDimming - .onEach { dimming -> - _state.update { it.copy(wallpaperDimming = dimming) } - } - .launchIn(scope) - - appPreferences.isWallpaperGrayscale - .onEach { grayscale -> - _state.update { it.copy(isWallpaperGrayscale = grayscale) } - } - .launchIn(scope) - - appPreferences.isPlayerGesturesEnabled - .onEach { enabled -> - _state.update { it.copy(isPlayerGesturesEnabled = enabled) } - } - .launchIn(scope) - - appPreferences.isPlayerDoubleTapSeekEnabled - .onEach { enabled -> - _state.update { it.copy(isPlayerDoubleTapSeekEnabled = enabled) } - } - .launchIn(scope) - - appPreferences.playerSeekDuration - .onEach { duration -> - _state.update { it.copy(playerSeekDuration = duration) } - } - .launchIn(scope) - - appPreferences.isPlayerZoomEnabled - .onEach { enabled -> - _state.update { it.copy(isPlayerZoomEnabled = enabled) } - } - .launchIn(scope) - - appPreferences.isArchivePinned - .onEach { pinned -> - _state.update { it.copy(isArchivePinned = pinned) } - } - .launchIn(scope) - - appPreferences.isArchiveAlwaysVisible - .onEach { enabled -> - _state.update { it.copy(isArchiveAlwaysVisible = enabled) } - } - .launchIn(scope) - - appPreferences.showLinkPreviews - .onEach { enabled -> - _state.update { it.copy(showLinkPreviews = enabled) } - } - .launchIn(scope) - - appPreferences.nightMode - .onEach { mode -> - _state.update { it.copy(nightMode = mode) } - } - .launchIn(scope) - - appPreferences.isDynamicColorsEnabled - .onEach { enabled -> - _state.update { it.copy(isDynamicColorsEnabled = enabled) } - } - .launchIn(scope) - - appPreferences.isAmoledThemeEnabled - .onEach { enabled -> - _state.update { it.copy(isAmoledThemeEnabled = enabled) } - } - .launchIn(scope) - - appPreferences.isCustomThemeEnabled - .onEach { enabled -> - _state.update { it.copy(isCustomThemeEnabled = enabled) } - } - .launchIn(scope) - - appPreferences.themePrimaryColor - .onEach { color -> - _state.update { it.copy(themePrimaryColor = color) } - } - .launchIn(scope) - - appPreferences.themeSecondaryColor - .onEach { color -> - _state.update { it.copy(themeSecondaryColor = color) } - } - .launchIn(scope) - - appPreferences.themeTertiaryColor - .onEach { color -> - _state.update { it.copy(themeTertiaryColor = color) } - } - .launchIn(scope) - - appPreferences.themeBackgroundColor - .onEach { color -> - _state.update { it.copy(themeBackgroundColor = color) } - } - .launchIn(scope) - - appPreferences.themeSurfaceColor - .onEach { color -> - _state.update { it.copy(themeSurfaceColor = color) } - } - .launchIn(scope) - - appPreferences.themePrimaryContainerColor - .onEach { color -> - _state.update { it.copy(themePrimaryContainerColor = color) } - } - .launchIn(scope) - - appPreferences.themeSecondaryContainerColor - .onEach { color -> - _state.update { it.copy(themeSecondaryContainerColor = color) } - } - .launchIn(scope) - - appPreferences.themeTertiaryContainerColor - .onEach { color -> - _state.update { it.copy(themeTertiaryContainerColor = color) } - } - .launchIn(scope) - - appPreferences.themeSurfaceVariantColor - .onEach { color -> - _state.update { it.copy(themeSurfaceVariantColor = color) } - } - .launchIn(scope) - - appPreferences.themeOutlineColor - .onEach { color -> - _state.update { it.copy(themeOutlineColor = color) } - } - .launchIn(scope) - - appPreferences.themeDarkPrimaryColor - .onEach { color -> - _state.update { it.copy(themeDarkPrimaryColor = color) } - } - .launchIn(scope) - - appPreferences.themeDarkSecondaryColor - .onEach { color -> - _state.update { it.copy(themeDarkSecondaryColor = color) } - } - .launchIn(scope) - - appPreferences.themeDarkTertiaryColor - .onEach { color -> - _state.update { it.copy(themeDarkTertiaryColor = color) } - } - .launchIn(scope) - - appPreferences.themeDarkBackgroundColor - .onEach { color -> - _state.update { it.copy(themeDarkBackgroundColor = color) } - } - .launchIn(scope) - - appPreferences.themeDarkSurfaceColor - .onEach { color -> - _state.update { it.copy(themeDarkSurfaceColor = color) } - } - .launchIn(scope) - - appPreferences.themeDarkPrimaryContainerColor - .onEach { color -> - _state.update { it.copy(themeDarkPrimaryContainerColor = color) } - } - .launchIn(scope) - - appPreferences.themeDarkSecondaryContainerColor - .onEach { color -> - _state.update { it.copy(themeDarkSecondaryContainerColor = color) } - } - .launchIn(scope) - - appPreferences.themeDarkTertiaryContainerColor - .onEach { color -> - _state.update { it.copy(themeDarkTertiaryContainerColor = color) } - } - .launchIn(scope) - - appPreferences.themeDarkSurfaceVariantColor - .onEach { color -> - _state.update { it.copy(themeDarkSurfaceVariantColor = color) } - } - .launchIn(scope) - - appPreferences.themeDarkOutlineColor - .onEach { color -> - _state.update { it.copy(themeDarkOutlineColor = color) } - } - .launchIn(scope) - - appPreferences.nightModeStartTime - .onEach { time -> - _state.update { it.copy(nightModeStartTime = time) } - } - .launchIn(scope) - - appPreferences.nightModeEndTime - .onEach { time -> - _state.update { it.copy(nightModeEndTime = time) } - } - .launchIn(scope) - - appPreferences.nightModeBrightnessThreshold - .onEach { threshold -> - _state.update { it.copy(nightModeBrightnessThreshold = threshold) } - } - .launchIn(scope) - - appPreferences.isDragToBackEnabled - .onEach { enabled -> - _state.update { it.copy(isDragToBackEnabled = enabled) } - } - .launchIn(scope) - - appPreferences.emojiStyle - .onEach { style -> - _state.update { it.copy(emojiStyle = style) } - } - .launchIn(scope) - - appPreferences.isAppleEmojiDownloaded - .onEach { downloaded -> - _state.update { it.copy(isAppleEmojiDownloaded = downloaded) } - } - .launchIn(scope) - - appPreferences.isTwitterEmojiDownloaded - .onEach { downloaded -> - _state.update { it.copy(isTwitterEmojiDownloaded = downloaded) } - } - .launchIn(scope) - - appPreferences.isWindowsEmojiDownloaded - .onEach { downloaded -> - _state.update { it.copy(isWindowsEmojiDownloaded = downloaded) } - } - .launchIn(scope) - - appPreferences.isCatmojiEmojiDownloaded - .onEach { downloaded -> - _state.update { it.copy(isCatmojiEmojiDownloaded = downloaded) } - } - .launchIn(scope) - - appPreferences.isNotoEmojiDownloaded - .onEach { downloaded -> - _state.update { it.copy(isNotoEmojiDownloaded = downloaded) } - } - .launchIn(scope) - - appPreferences.compressPhotos - .onEach { enabled -> - _state.update { it.copy(compressPhotos = enabled) } - } - .launchIn(scope) - - appPreferences.compressVideos - .onEach { enabled -> - _state.update { it.copy(compressVideos = enabled) } - } - .launchIn(scope) - - appPreferences.chatListMessageLines - .onEach { lines -> - _state.update { it.copy(chatListMessageLines = lines) } - } - .launchIn(scope) - - appPreferences.showChatListPhotos - .onEach { enabled -> - _state.update { it.copy(showChatListPhotos = enabled) } - } - .launchIn(scope) - - loadWallpapers() - checkEmojiFiles() - } - - private fun checkEmojiFiles() { - val filesDir = assetsManager.getFilesDir() - val appleFile = File(filesDir, "fonts/apple.ttf") - val twitterFile = File(filesDir, "fonts/twemoji.ttf") - val windowsFile = File(filesDir, "fonts/win11.ttf") - val catmojiFile = File(filesDir, "fonts/catmoji.ttf") - val notoFile = File(filesDir, "fonts/notoemoji.ttf") - - val isAppleDownloaded = appleFile.exists() - val isTwitterDownloaded = twitterFile.exists() - val isWindowsDownloaded = windowsFile.exists() - val isCatmojiDownloaded = catmojiFile.exists() - val isNotoDownloaded = notoFile.exists() - - appPreferences.setAppleEmojiDownloaded(isAppleDownloaded) - appPreferences.setTwitterEmojiDownloaded(isTwitterDownloaded) - appPreferences.setWindowsEmojiDownloaded(isWindowsDownloaded) - appPreferences.setCatmojiEmojiDownloaded(isCatmojiDownloaded) - appPreferences.setNotoEmojiDownloaded(isNotoDownloaded) - - if (appPreferences.emojiStyle.value == EmojiStyle.APPLE && !isAppleDownloaded) { - appPreferences.setEmojiStyle(EmojiStyle.SYSTEM) - } - if (appPreferences.emojiStyle.value == EmojiStyle.TWITTER && !isTwitterDownloaded) { - appPreferences.setEmojiStyle(EmojiStyle.SYSTEM) - } - if (appPreferences.emojiStyle.value == EmojiStyle.WINDOWS && !isWindowsDownloaded) { - appPreferences.setEmojiStyle(EmojiStyle.SYSTEM) - } - if (appPreferences.emojiStyle.value == EmojiStyle.CATMOJI && !isCatmojiDownloaded) { - appPreferences.setEmojiStyle(EmojiStyle.SYSTEM) - } - if (appPreferences.emojiStyle.value == EmojiStyle.NOTO && !isNotoDownloaded) { - appPreferences.setEmojiStyle(EmojiStyle.SYSTEM) - } - } - - private fun loadWallpapers() { - settingsRepository.getWallpapers() - .onEach { wallpapers -> - _state.update { it.copy(availableWallpapers = wallpapers) } - } - .launchIn(scope) - } - - override fun onBackClicked() { - onBack() - } - - override fun onFontSizeChanged(size: Float) { - appPreferences.setFontSize(size) - } - - override fun onLetterSpacingChanged(spacing: Float) { - appPreferences.setLetterSpacing(spacing) - } - - override fun onBubbleRadiusChanged(radius: Float) { - appPreferences.setBubbleRadius(radius) - } - - override fun onWallpaperChanged(wallpaper: String?) { - appPreferences.setWallpaper(wallpaper) - } - - override fun onWallpaperSelected(wallpaper: WallpaperModel) { - _state.update { it.copy(selectedWallpaper = wallpaper) } - - if (!wallpaper.isDownloaded && wallpaper.documentId != 0L) { - scope.launch { - settingsRepository.downloadWallpaper(wallpaper.documentId.toInt()) - } - } - - val key = when { - wallpaper.slug.isNotEmpty() -> wallpaper.slug - !wallpaper.localPath.isNullOrEmpty() -> wallpaper.localPath - else -> null - } - - key?.let { appPreferences.setWallpaper(it) } - } - - override fun onWallpaperBlurChanged(wallpaper: WallpaperModel, isBlurred: Boolean) { - _state.update { it.copy(isWallpaperBlurred = isBlurred) } - appPreferences.setWallpaperBlurred(isBlurred) - } - - override fun onWallpaperBlurIntensityChanged(intensity: Int) { - appPreferences.setWallpaperBlurIntensity(intensity) - } - - override fun onWallpaperMotionChanged(wallpaper: WallpaperModel, isMoving: Boolean) { - _state.update { it.copy(isWallpaperMoving = isMoving) } - appPreferences.setWallpaperMoving(isMoving) - } - - override fun onWallpaperDimmingChanged(dimming: Int) { - appPreferences.setWallpaperDimming(dimming) - } - - override fun onWallpaperGrayscaleChanged(isGrayscale: Boolean) { - appPreferences.setWallpaperGrayscale(isGrayscale) - } - - override fun onPlayerGesturesEnabledChanged(enabled: Boolean) { - appPreferences.setPlayerGesturesEnabled(enabled) - } - - override fun onPlayerDoubleTapSeekEnabledChanged(enabled: Boolean) { - appPreferences.setPlayerDoubleTapSeekEnabled(enabled) - } - - override fun onPlayerSeekDurationChanged(duration: Int) { - appPreferences.setPlayerSeekDuration(duration) - } - - override fun onPlayerZoomEnabledChanged(enabled: Boolean) { - appPreferences.setPlayerZoomEnabled(enabled) - } - - override fun onClearRecentStickers() { - scope.launch { - stickerRepository.clearRecentStickers() - } - } - - override fun onClearRecentEmojis() { - scope.launch { - stickerRepository.clearRecentEmojis() - } - } - - override fun onArchivePinnedChanged(pinned: Boolean) { - appPreferences.setArchivePinned(pinned) - } - - override fun onArchiveAlwaysVisibleChanged(enabled: Boolean) { - appPreferences.setArchiveAlwaysVisible(enabled) - } - - override fun onShowLinkPreviewsChanged(enabled: Boolean) { - appPreferences.setShowLinkPreviews(enabled) - } - - override fun onNightModeChanged(mode: NightMode) { - appPreferences.setNightMode(mode) - } - - override fun onDynamicColorsChanged(enabled: Boolean) { - appPreferences.setDynamicColorsEnabled(enabled) - } - - override fun onAmoledThemeChanged(enabled: Boolean) { - appPreferences.setAmoledThemeEnabled(enabled) - } - - override fun onCustomThemeEnabledChanged(enabled: Boolean) { - appPreferences.setCustomThemeEnabled(enabled) - } - - override fun onThemePrimaryColorChanged(color: Int) { - appPreferences.setThemePrimaryColor(color) - } - - override fun onThemeSecondaryColorChanged(color: Int) { - appPreferences.setThemeSecondaryColor(color) - } - - override fun onThemeTertiaryColorChanged(color: Int) { - appPreferences.setThemeTertiaryColor(color) - } - - override fun onThemeBackgroundColorChanged(color: Int) { - appPreferences.setThemeBackgroundColor(color) - } - - override fun onThemeSurfaceColorChanged(color: Int) { - appPreferences.setThemeSurfaceColor(color) - } - - override fun onThemePrimaryContainerColorChanged(color: Int) { - appPreferences.setThemePrimaryContainerColor(color) - } - - override fun onThemeSecondaryContainerColorChanged(color: Int) { - appPreferences.setThemeSecondaryContainerColor(color) - } - - override fun onThemeTertiaryContainerColorChanged(color: Int) { - appPreferences.setThemeTertiaryContainerColor(color) - } - - override fun onThemeSurfaceVariantColorChanged(color: Int) { - appPreferences.setThemeSurfaceVariantColor(color) - } - - override fun onThemeOutlineColorChanged(color: Int) { - appPreferences.setThemeOutlineColor(color) - } - - override fun onThemeDarkPrimaryColorChanged(color: Int) { - appPreferences.setThemeDarkPrimaryColor(color) - } - - override fun onThemeDarkSecondaryColorChanged(color: Int) { - appPreferences.setThemeDarkSecondaryColor(color) - } - - override fun onThemeDarkTertiaryColorChanged(color: Int) { - appPreferences.setThemeDarkTertiaryColor(color) - } - - override fun onThemeDarkBackgroundColorChanged(color: Int) { - appPreferences.setThemeDarkBackgroundColor(color) - } - - override fun onThemeDarkSurfaceColorChanged(color: Int) { - appPreferences.setThemeDarkSurfaceColor(color) - } - - override fun onThemeDarkPrimaryContainerColorChanged(color: Int) { - appPreferences.setThemeDarkPrimaryContainerColor(color) - } - - override fun onThemeDarkSecondaryContainerColorChanged(color: Int) { - appPreferences.setThemeDarkSecondaryContainerColor(color) - } - - override fun onThemeDarkTertiaryContainerColorChanged(color: Int) { - appPreferences.setThemeDarkTertiaryContainerColor(color) - } - - override fun onThemeDarkSurfaceVariantColorChanged(color: Int) { - appPreferences.setThemeDarkSurfaceVariantColor(color) - } - - override fun onThemeDarkOutlineColorChanged(color: Int) { - appPreferences.setThemeDarkOutlineColor(color) - } - - override fun onApplyThemeAccent(color: Int, darkPalette: Boolean) { - val secondary = shiftHue(color, 18f) - val tertiary = shiftHue(color, 36f) - val primaryContainer = shiftSaturationAndValue(color, saturationScale = 0.45f, valueScale = if (darkPalette) 0.65f else 1.15f) - val secondaryContainer = shiftSaturationAndValue(secondary, saturationScale = 0.45f, valueScale = if (darkPalette) 0.65f else 1.15f) - val tertiaryContainer = shiftSaturationAndValue(tertiary, saturationScale = 0.45f, valueScale = if (darkPalette) 0.65f else 1.15f) - if (darkPalette) { - appPreferences.setThemeDarkPrimaryColor(color) - appPreferences.setThemeDarkSecondaryColor(secondary) - appPreferences.setThemeDarkTertiaryColor(tertiary) - appPreferences.setThemeDarkPrimaryContainerColor(primaryContainer) - appPreferences.setThemeDarkSecondaryContainerColor(secondaryContainer) - appPreferences.setThemeDarkTertiaryContainerColor(tertiaryContainer) - } else { - appPreferences.setThemePrimaryColor(color) - appPreferences.setThemeSecondaryColor(secondary) - appPreferences.setThemeTertiaryColor(tertiary) - appPreferences.setThemePrimaryContainerColor(primaryContainer) - appPreferences.setThemeSecondaryContainerColor(secondaryContainer) - appPreferences.setThemeTertiaryContainerColor(tertiaryContainer) - } - } - - override fun exportCustomThemeJson(): String { - return JSONObject() - .put( - "lightPalette", - JSONObject() - .put("primaryColor", state.value.themePrimaryColor) - .put("secondaryColor", state.value.themeSecondaryColor) - .put("tertiaryColor", state.value.themeTertiaryColor) - .put("backgroundColor", state.value.themeBackgroundColor) - .put("surfaceColor", state.value.themeSurfaceColor) - .put("primaryContainerColor", state.value.themePrimaryContainerColor) - .put("secondaryContainerColor", state.value.themeSecondaryContainerColor) - .put("tertiaryContainerColor", state.value.themeTertiaryContainerColor) - .put("surfaceVariantColor", state.value.themeSurfaceVariantColor) - .put("outlineColor", state.value.themeOutlineColor) - ) - .put( - "darkPalette", - JSONObject() - .put("primaryColor", state.value.themeDarkPrimaryColor) - .put("secondaryColor", state.value.themeDarkSecondaryColor) - .put("tertiaryColor", state.value.themeDarkTertiaryColor) - .put("backgroundColor", state.value.themeDarkBackgroundColor) - .put("surfaceColor", state.value.themeDarkSurfaceColor) - .put("primaryContainerColor", state.value.themeDarkPrimaryContainerColor) - .put("secondaryContainerColor", state.value.themeDarkSecondaryContainerColor) - .put("tertiaryContainerColor", state.value.themeDarkTertiaryContainerColor) - .put("surfaceVariantColor", state.value.themeDarkSurfaceVariantColor) - .put("outlineColor", state.value.themeDarkOutlineColor) - ) - .put("amoledEnabled", state.value.isAmoledThemeEnabled) - .put("customThemeEnabled", state.value.isCustomThemeEnabled) - .put("dynamicColorsEnabled", state.value.isDynamicColorsEnabled) - .toString(2) - } - - override fun importCustomThemeJson(json: String): Boolean { - return coRunCatching { - val data = JSONObject(json) - val light = data.optJSONObject("lightPalette") ?: data - val dark = data.optJSONObject("darkPalette") ?: data - - val primary = light.getInt("primaryColor") - val secondary = light.getInt("secondaryColor") - val tertiary = light.getInt("tertiaryColor") - val background = light.getInt("backgroundColor") - val surface = light.getInt("surfaceColor") - val darkPrimary = dark.optInt("primaryColor", primary) - val darkSecondary = dark.optInt("secondaryColor", secondary) - val darkTertiary = dark.optInt("tertiaryColor", tertiary) - val darkBackground = dark.optInt("backgroundColor", 0xFF121212.toInt()) - val darkSurface = dark.optInt("surfaceColor", 0xFF121212.toInt()) - val primaryContainer = light.optInt("primaryContainerColor", shiftSaturationAndValue(primary, 0.45f, 1.15f)) - val secondaryContainer = light.optInt("secondaryContainerColor", shiftSaturationAndValue(secondary, 0.45f, 1.15f)) - val tertiaryContainer = light.optInt("tertiaryContainerColor", shiftSaturationAndValue(tertiary, 0.45f, 1.15f)) - val surfaceVariant = light.optInt("surfaceVariantColor", 0xFFE1E2EC.toInt()) - val outline = light.optInt("outlineColor", 0xFF757680.toInt()) - val darkPrimaryContainer = dark.optInt("primaryContainerColor", shiftSaturationAndValue(darkPrimary, 0.45f, 0.65f)) - val darkSecondaryContainer = dark.optInt("secondaryContainerColor", shiftSaturationAndValue(darkSecondary, 0.45f, 0.65f)) - val darkTertiaryContainer = dark.optInt("tertiaryContainerColor", shiftSaturationAndValue(darkTertiary, 0.45f, 0.65f)) - val darkSurfaceVariant = dark.optInt("surfaceVariantColor", 0xFF44474F.toInt()) - val darkOutline = dark.optInt("outlineColor", 0xFF8E9099.toInt()) - val amoled = data.optBoolean("amoledEnabled", false) - val customEnabled = data.optBoolean("customThemeEnabled", true) - val dynamicEnabled = data.optBoolean("dynamicColorsEnabled", true) - - appPreferences.setThemePrimaryColor(primary) - appPreferences.setThemeSecondaryColor(secondary) - appPreferences.setThemeTertiaryColor(tertiary) - appPreferences.setThemeBackgroundColor(background) - appPreferences.setThemeSurfaceColor(surface) - appPreferences.setThemePrimaryContainerColor(primaryContainer) - appPreferences.setThemeSecondaryContainerColor(secondaryContainer) - appPreferences.setThemeTertiaryContainerColor(tertiaryContainer) - appPreferences.setThemeSurfaceVariantColor(surfaceVariant) - appPreferences.setThemeOutlineColor(outline) - appPreferences.setThemeDarkPrimaryColor(darkPrimary) - appPreferences.setThemeDarkSecondaryColor(darkSecondary) - appPreferences.setThemeDarkTertiaryColor(darkTertiary) - appPreferences.setThemeDarkBackgroundColor(darkBackground) - appPreferences.setThemeDarkSurfaceColor(darkSurface) - appPreferences.setThemeDarkPrimaryContainerColor(darkPrimaryContainer) - appPreferences.setThemeDarkSecondaryContainerColor(darkSecondaryContainer) - appPreferences.setThemeDarkTertiaryContainerColor(darkTertiaryContainer) - appPreferences.setThemeDarkSurfaceVariantColor(darkSurfaceVariant) - appPreferences.setThemeDarkOutlineColor(darkOutline) - appPreferences.setAmoledThemeEnabled(amoled) - appPreferences.setCustomThemeEnabled(customEnabled) - appPreferences.setDynamicColorsEnabled(dynamicEnabled) - }.isSuccess - } - - override fun onNightModeStartTimeChanged(time: String) { - appPreferences.setNightModeStartTime(time) - } - - override fun onNightModeEndTimeChanged(time: String) { - appPreferences.setNightModeEndTime(time) - } - - override fun onNightModeBrightnessThresholdChanged(threshold: Float) { - appPreferences.setNightModeBrightnessThreshold(threshold) - } - - override fun onDragToBackChanged(enabled: Boolean) { - appPreferences.setDragToBackEnabled(enabled) - } - - override fun onAdBlockClick() { - onAdBlock() - } - - override fun onEmojiStyleChanged(style: EmojiStyle) { - val isDownloaded = when (style) { - EmojiStyle.APPLE -> state.value.isAppleEmojiDownloaded - EmojiStyle.TWITTER -> state.value.isTwitterEmojiDownloaded - EmojiStyle.WINDOWS -> state.value.isWindowsEmojiDownloaded - EmojiStyle.CATMOJI -> state.value.isCatmojiEmojiDownloaded - EmojiStyle.NOTO -> state.value.isNotoEmojiDownloaded - EmojiStyle.SYSTEM -> true - } - - if (isDownloaded) { - appPreferences.setEmojiStyle(style) - } else { - downloadEmojiPack(style) - } - } - - override fun onEmojiStyleLongClick(style: EmojiStyle) { - val isDownloaded = when (style) { - EmojiStyle.APPLE -> state.value.isAppleEmojiDownloaded - EmojiStyle.TWITTER -> state.value.isTwitterEmojiDownloaded - EmojiStyle.WINDOWS -> state.value.isWindowsEmojiDownloaded - EmojiStyle.CATMOJI -> state.value.isCatmojiEmojiDownloaded - EmojiStyle.NOTO -> state.value.isNotoEmojiDownloaded - EmojiStyle.SYSTEM -> false - } - if (isDownloaded) { - _state.update { it.copy(emojiPackToRemove = style) } - } - } - - override fun onConfirmRemoveEmojiPack() { - val style = state.value.emojiPackToRemove ?: return - _state.update { it.copy(emojiPackToRemove = null) } - removeEmojiPack(style) - } - - override fun onDismissRemoveEmojiPack() { - _state.update { it.copy(emojiPackToRemove = null) } - } - - private fun removeEmojiPack(style: EmojiStyle) { - val fileName = when (style) { - EmojiStyle.APPLE -> "apple.ttf" - EmojiStyle.TWITTER -> "twemoji.ttf" - EmojiStyle.WINDOWS -> "win11.ttf" - EmojiStyle.CATMOJI -> "catmoji.ttf" - EmojiStyle.NOTO -> "notoemoji.ttf" - else -> return - } - - scope.launch(Dispatchers.IO) { - val fontsDir = File(assetsManager.getFilesDir(), "fonts") - val file = File(fontsDir, fileName) - if (file.exists()) { - file.delete() - } - - withContext(Dispatchers.Main) { - when (style) { - EmojiStyle.APPLE -> appPreferences.setAppleEmojiDownloaded(false) - EmojiStyle.TWITTER -> appPreferences.setTwitterEmojiDownloaded(false) - EmojiStyle.WINDOWS -> appPreferences.setWindowsEmojiDownloaded(false) - EmojiStyle.CATMOJI -> appPreferences.setCatmojiEmojiDownloaded(false) - EmojiStyle.NOTO -> appPreferences.setNotoEmojiDownloaded(false) - else -> {} - } - if (appPreferences.emojiStyle.value == style) { - appPreferences.setEmojiStyle(EmojiStyle.SYSTEM) - } - } - } - } - - private fun downloadEmojiPack(style: EmojiStyle) { - val url = when (style) { - EmojiStyle.APPLE -> "https://github.com/monogram-android/emojies/releases/download/1.0/apple.ttf" - EmojiStyle.TWITTER -> "https://github.com/monogram-android/emojies/releases/download/1.0/twemoji.ttf" - EmojiStyle.WINDOWS -> "https://github.com/monogram-android/emojies/releases/download/1.0/win11.ttf" - EmojiStyle.CATMOJI -> "https://github.com/monogram-android/emojies/releases/download/1.0/catmoji.ttf" - EmojiStyle.NOTO -> "https://github.com/monogram-android/emojies/releases/download/1.0/notoemoji.ttf" - else -> return - } - val fileName = when (style) { - EmojiStyle.APPLE -> "apple.ttf" - EmojiStyle.TWITTER -> "twemoji.ttf" - EmojiStyle.WINDOWS -> "win11.ttf" - EmojiStyle.CATMOJI -> "catmoji.ttf" - EmojiStyle.NOTO -> "notoemoji.ttf" - } - - when (style) { - EmojiStyle.APPLE -> _state.update { it.copy(isAppleEmojiDownloading = true) } - EmojiStyle.TWITTER -> _state.update { it.copy(isTwitterEmojiDownloading = true) } - EmojiStyle.WINDOWS -> _state.update { it.copy(isWindowsEmojiDownloading = true) } - EmojiStyle.CATMOJI -> _state.update { it.copy(isCatmojiEmojiDownloading = true) } - EmojiStyle.NOTO -> _state.update { it.copy(isNotoEmojiDownloading = true) } - else -> {} - } - - scope.launch(Dispatchers.IO) { - try { - val fontsDir = File(assetsManager.getFilesDir(), "fonts") - if (!fontsDir.exists()) fontsDir.mkdirs() - val file = File(fontsDir, fileName) - - URL(url).openStream().use { input -> - file.outputStream().use { output -> - input.copyTo(output) - } - } - - withContext(Dispatchers.Main) { - when (style) { - EmojiStyle.APPLE -> { - appPreferences.setAppleEmojiDownloaded(true) - _state.update { it.copy(isAppleEmojiDownloading = false) } - } - - EmojiStyle.TWITTER -> { - appPreferences.setTwitterEmojiDownloaded(true) - _state.update { it.copy(isTwitterEmojiDownloading = false) } - } - - EmojiStyle.WINDOWS -> { - appPreferences.setWindowsEmojiDownloaded(true) - _state.update { it.copy(isWindowsEmojiDownloading = false) } - } - - EmojiStyle.CATMOJI -> { - appPreferences.setCatmojiEmojiDownloaded(true) - _state.update { it.copy(isCatmojiEmojiDownloading = false) } - } - - EmojiStyle.NOTO -> { - appPreferences.setNotoEmojiDownloaded(true) - _state.update { it.copy(isNotoEmojiDownloading = false) } - } - - else -> {} - } - appPreferences.setEmojiStyle(style) - } - } catch (e: Exception) { - withContext(Dispatchers.Main) { - when (style) { - EmojiStyle.APPLE -> _state.update { it.copy(isAppleEmojiDownloading = false) } - EmojiStyle.TWITTER -> _state.update { it.copy(isTwitterEmojiDownloading = false) } - EmojiStyle.WINDOWS -> _state.update { it.copy(isWindowsEmojiDownloading = false) } - EmojiStyle.CATMOJI -> _state.update { it.copy(isCatmojiEmojiDownloading = false) } - EmojiStyle.NOTO -> _state.update { it.copy(isNotoEmojiDownloading = false) } - else -> {} - } - } - e.printStackTrace() - } - } - } - - override fun onCompressPhotosChanged(enabled: Boolean) { - appPreferences.setCompressPhotos(enabled) - } - - override fun onCompressVideosChanged(enabled: Boolean) { - appPreferences.setCompressVideos(enabled) - } - - override fun onChatListMessageLinesChanged(lines: Int) { - appPreferences.setChatListMessageLines(lines) - } - - override fun onShowChatListPhotosChanged(enabled: Boolean) { - appPreferences.setShowChatListPhotos(enabled) - } - - private fun shiftHue(color: Int, delta: Float): Int { - val hsv = FloatArray(3) - colorToHSV(color, hsv) - hsv[0] = (hsv[0] + delta + 360f) % 360f - return HSVToColor(hsv) - } - - private fun shiftSaturationAndValue(color: Int, saturationScale: Float, valueScale: Float): Int { - val hsv = FloatArray(3) - colorToHSV(color, hsv) - hsv[1] = (hsv[1] * saturationScale).coerceIn(0f, 1f) - hsv[2] = (hsv[2] * valueScale).coerceIn(0f, 1f) - return HSVToColor(hsv) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/ChatSettingsContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/ChatSettingsContent.kt deleted file mode 100644 index 5c2aac11..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/ChatSettingsContent.kt +++ /dev/null @@ -1,1346 +0,0 @@ -package org.monogram.presentation.settings.chatSettings - -import androidx.compose.animation.* -import androidx.compose.animation.core.* -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.automirrored.rounded.StickyNote2 -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ConfirmationSheet -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsSwitchTile -import org.monogram.presentation.core.ui.SettingsTile -import org.monogram.presentation.core.util.EmojiStyle -import org.monogram.presentation.core.util.NightMode -import org.monogram.presentation.features.chats.currentChat.components.chats.getEmojiFontFamily -import org.monogram.presentation.settings.chatSettings.components.ChatListPreview -import org.monogram.presentation.settings.chatSettings.components.ChatSettingsPreview -import org.monogram.presentation.settings.chatSettings.components.WallpaperItem - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ChatSettingsContent(component: ChatSettingsComponent) { - val state by component.state.subscribeAsState() - - val blueColor = Color(0xFF4285F4) - val greenColor = Color(0xFF34A853) - val orangeColor = Color(0xFFF9AB00) - val pinkColor = Color(0xFFFF6D66) - val tealColor = Color(0xFF00BFA5) - val purpleColor = Color(0xFF9C27B0) - val redColor = Color(0xFFEA4335) - - var showStartTimePicker by remember { mutableStateOf(false) } - var showEndTimePicker by remember { mutableStateOf(false) } - var showThemeEditor by remember { mutableStateOf(false) } - var showClearRecentStickersSheet by remember { mutableStateOf(false) } - var showClearRecentEmojisSheet by remember { mutableStateOf(false) } - - if (showThemeEditor) { - ChatThemeEditorScreen( - state = state, - component = component, - onBack = { showThemeEditor = false } - ) - return - } - - Scaffold( - modifier = Modifier.semantics { contentDescription = "ChatSettingsContent" }, - topBar = { - TopAppBar( - title = { - Text( - text = stringResource(R.string.chat_settings_header), - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background - ) - ) - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - LazyColumn( - modifier = Modifier.fillMaxSize(), - contentPadding = PaddingValues( - start = 16.dp, - end = 16.dp, - top = padding.calculateTopPadding(), - bottom = padding.calculateBottomPadding() + 16.dp - ), - verticalArrangement = Arrangement.spacedBy(16.dp) - ) { - item { - ChatSettingsPreview( - wallpaper = state.wallpaper, - availableWallpapers = state.availableWallpapers, - fontSize = state.fontSize, - letterSpacing = state.letterSpacing, - bubbleRadius = state.bubbleRadius, - isBlurred = state.isWallpaperBlurred, - isMoving = state.isWallpaperMoving, - blurIntensity = state.wallpaperBlurIntensity, - dimming = state.wallpaperDimming, - isGrayscale = state.isWallpaperGrayscale, - downloadUtils = component.downloadUtils, - videoPlayerPool = component.videoPlayerPool - ) - } - - item { - SectionHeader(stringResource(R.string.appearance_header)) - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - Column( - modifier = Modifier - .padding(16.dp) - .animateContentSize() - ) { - AppearanceSliderItem( - title = stringResource(R.string.message_text_size_title), - value = state.fontSize, - onValueChange = component::onFontSizeChanged, - valueRange = 12f..30f, - steps = 18, - onReset = { component.onFontSizeChanged(16f) }, - valueSuffix = "sp", - startIcon = { - Text( - text = "A", - fontSize = 12.sp, - color = MaterialTheme.colorScheme.onSurfaceVariant, - fontWeight = FontWeight.Medium - ) - }, - endIcon = { - Text( - text = "A", - fontSize = 22.sp, - color = MaterialTheme.colorScheme.onSurfaceVariant, - fontWeight = FontWeight.Bold - ) - } - ) - - HorizontalDivider( - modifier = Modifier.padding(vertical = 12.dp), - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - - AppearanceSliderItem( - title = stringResource(R.string.message_letter_spacing_title), - value = state.letterSpacing, - onValueChange = component::onLetterSpacingChanged, - valueRange = -2f..2f, - steps = 20, - onReset = { component.onLetterSpacingChanged(0f) }, - valueSuffix = "sp", - startIcon = { - Text( - text = "AB", - letterSpacing = (-1f).sp, - fontSize = 12.sp, - color = MaterialTheme.colorScheme.onSurfaceVariant, - fontWeight = FontWeight.Bold - ) - }, - endIcon = { - Text( - text = "AB", - letterSpacing = 2f.sp, - fontSize = 12.sp, - color = MaterialTheme.colorScheme.onSurfaceVariant, - fontWeight = FontWeight.Bold - ) - }, - displayedDecimalPlaces = 2 - ) - - HorizontalDivider( - modifier = Modifier.padding(vertical = 12.dp), - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - - AppearanceSliderItem( - title = stringResource(R.string.bubble_rounding_title), - value = state.bubbleRadius, - onValueChange = component::onBubbleRadiusChanged, - valueRange = 0f..30f, - steps = 30, - onReset = { component.onBubbleRadiusChanged(18f) }, - valueSuffix = "dp", - startIcon = { - Icon( - imageVector = Icons.Rounded.Square, - contentDescription = null, - modifier = Modifier.size(18.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - }, - endIcon = { - Icon( - imageVector = Icons.Rounded.Circle, - contentDescription = null, - modifier = Modifier.size(22.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - ) - } - } - } - - item { - SectionHeader(stringResource(R.string.chat_wallpaper_header)) - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - LazyRow( - horizontalArrangement = Arrangement.spacedBy(12.dp), - contentPadding = PaddingValues(16.dp) - ) { - item { - val isSelected = state.wallpaper == null - - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier - .padding(vertical = 4.dp) - .clickable { component.onWallpaperChanged(null) } - ) { - Box( - modifier = Modifier - .size(80.dp, 120.dp) - .clip(RoundedCornerShape(12.dp)) - .background(MaterialTheme.colorScheme.surfaceContainerHigh) - .then( - if (isSelected) Modifier.background( - MaterialTheme.colorScheme.primary.copy( - alpha = 0.2f - ) - ) else Modifier - ), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.Close, - contentDescription = stringResource(R.string.reset_wallpaper_cd), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - - (this@Column.AnimatedVisibility( - visible = isSelected, - enter = scaleIn() + fadeIn(), - exit = scaleOut() + fadeOut() - ) { - Box( - modifier = Modifier - .size(32.dp) - .background(MaterialTheme.colorScheme.primary, CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.Check, - contentDescription = stringResource(R.string.chat_settings_selected), - tint = MaterialTheme.colorScheme.onPrimary, - modifier = Modifier.size(20.dp) - ) - } - }) - } - } - } - - items( - state.availableWallpapers, - key = { it.id }) { wallpaper -> - val isSelected = - state.wallpaper != null && (state.wallpaper == wallpaper.localPath || state.wallpaper == wallpaper.slug) - - WallpaperItem( - wallpaper = wallpaper, - isSelected = isSelected, - isBlurred = state.isWallpaperBlurred, - blurIntensity = state.wallpaperBlurIntensity, - isMoving = state.isWallpaperMoving, - dimming = state.wallpaperDimming, - isGrayscale = state.isWallpaperGrayscale, - onClick = { component.onWallpaperSelected(wallpaper) }, - onBlurClick = { isBlurred -> - if (!isSelected) { - component.onWallpaperSelected(wallpaper) - } - component.onWallpaperBlurChanged(wallpaper, isBlurred) - }, - onBlurIntensityChange = { intensity -> - component.onWallpaperBlurIntensityChanged(intensity) - }, - onMotionClick = { isMoving -> - if (!isSelected) { - component.onWallpaperSelected(wallpaper) - } - component.onWallpaperMotionChanged(wallpaper, isMoving) - }, - onDimmingChange = { dimming -> - if (!isSelected) { - component.onWallpaperSelected(wallpaper) - } - component.onWallpaperDimmingChanged(dimming) - }, - onGrayscaleClick = { isGrayscale -> - if (!isSelected) { - component.onWallpaperSelected(wallpaper) - } - component.onWallpaperGrayscaleChanged(isGrayscale) - } - ) - } - } - } - } - - item { - SectionHeader(stringResource(R.string.emoji_style_header)) - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - LazyRow( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp), - contentPadding = PaddingValues(16.dp) - ) { - items(EmojiStyle.entries) { style -> - Box(modifier = Modifier.width(100.dp)) { - EmojiStyleItem( - style = style, - selected = state.emojiStyle == style, - isDownloaded = when (style) { - EmojiStyle.APPLE -> state.isAppleEmojiDownloaded - EmojiStyle.TWITTER -> state.isTwitterEmojiDownloaded - EmojiStyle.WINDOWS -> state.isWindowsEmojiDownloaded - EmojiStyle.CATMOJI -> state.isCatmojiEmojiDownloaded - EmojiStyle.NOTO -> state.isNotoEmojiDownloaded - EmojiStyle.SYSTEM -> true - }, - isDownloading = when (style) { - EmojiStyle.APPLE -> state.isAppleEmojiDownloading - EmojiStyle.TWITTER -> state.isTwitterEmojiDownloading - EmojiStyle.WINDOWS -> state.isWindowsEmojiDownloading - EmojiStyle.CATMOJI -> state.isCatmojiEmojiDownloading - EmojiStyle.NOTO -> state.isNotoEmojiDownloading - EmojiStyle.SYSTEM -> false - }, - onClick = { component.onEmojiStyleChanged(style) }, - onLongClick = { component.onEmojiStyleLongClick(style) } - ) - } - } - } - } - } - - item { - SectionHeader(stringResource(R.string.theme_header)) - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - Column( - modifier = Modifier - .padding(16.dp) - .animateContentSize(animationSpec = spring(stiffness = Spring.StiffnessLow)) - ) { - Text( - text = stringResource(R.string.night_mode_title), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.onSurface, - fontWeight = FontWeight.SemiBold - ) - Spacer(modifier = Modifier.height(12.dp)) - - Surface( - shape = RoundedCornerShape(14.dp), - color = MaterialTheme.colorScheme.surfaceContainerLow, - modifier = Modifier.fillMaxWidth() - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 10.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(10.dp) - ) { - Box( - modifier = Modifier - .size(30.dp) - .background( - MaterialTheme.colorScheme.primary.copy(alpha = 0.14f), - CircleShape - ), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.Tune, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.size(16.dp) - ) - } - Column { - Text( - text = stringResource(R.string.night_mode_current_label), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Text( - text = stringResource( - R.string.night_mode_current_format, - nightModeLabel(state.nightMode) - ), - style = MaterialTheme.typography.bodyMedium, - fontWeight = FontWeight.Medium - ) - } - } - } - Spacer(modifier = Modifier.height(12.dp)) - - LazyRow( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(10.dp) - ) { - items(NightMode.entries.toList()) { mode -> - ThemeModeItem( - mode = mode, - selected = state.nightMode == mode, - onClick = { component.onNightModeChanged(mode) }, - modifier = Modifier.widthIn(min = 164.dp) - ) - } - } - - AnimatedContent( - targetState = state.nightMode, - transitionSpec = { - fadeIn(animationSpec = tween(400, easing = EaseOutQuint)) + - slideInVertically( - animationSpec = tween( - 400, - easing = EaseOutQuint - ) - ) { it / 2 } togetherWith - fadeOut(animationSpec = tween(200, easing = EaseInQuint)) + - slideOutVertically(animationSpec = tween(200, easing = EaseInQuint)) { it / 2 } - }, - label = "NightModeSettings" - ) { mode -> - when (mode) { - NightMode.SCHEDULED -> { - Column(modifier = Modifier.padding(top = 20.dp)) { - HorizontalDivider( - modifier = Modifier.padding(bottom = 20.dp), - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - TimeSettingCard( - label = stringResource(R.string.from_label), - time = state.nightModeStartTime, - icon = Icons.Rounded.LightMode, - modifier = Modifier.weight(1f), - onClick = { showStartTimePicker = true } - ) - TimeSettingCard( - label = stringResource(R.string.to_label), - time = state.nightModeEndTime, - icon = Icons.Rounded.DarkMode, - modifier = Modifier.weight(1f), - onClick = { showEndTimePicker = true } - ) - } - - if (showStartTimePicker) { - val parts = state.nightModeStartTime.split(":") - val timePickerState = rememberTimePickerState( - initialHour = parts.getOrNull(0)?.toIntOrNull() ?: 0, - initialMinute = parts.getOrNull(1)?.toIntOrNull() ?: 0, - is24Hour = true - ) - TimePickerDialogWrapper( - onDismissRequest = { showStartTimePicker = false }, - onConfirm = { - component.onNightModeStartTimeChanged( - String.format("%02d:%02d", timePickerState.hour, timePickerState.minute) - ) - showStartTimePicker = false - } - ) { - TimePicker(state = timePickerState) - } - } - - if (showEndTimePicker) { - val parts = state.nightModeEndTime.split(":") - val timePickerState = rememberTimePickerState( - initialHour = parts.getOrNull(0)?.toIntOrNull() ?: 0, - initialMinute = parts.getOrNull(1)?.toIntOrNull() ?: 0, - is24Hour = true - ) - TimePickerDialogWrapper( - onDismissRequest = { showEndTimePicker = false }, - onConfirm = { - component.onNightModeEndTimeChanged( - String.format("%02d:%02d", timePickerState.hour, timePickerState.minute) - ) - showEndTimePicker = false - } - ) { - TimePicker(state = timePickerState) - } - } - } - } - - NightMode.BRIGHTNESS -> { - Column(modifier = Modifier.padding(top = 20.dp)) { - HorizontalDivider( - modifier = Modifier.padding(bottom = 20.dp), - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - Row(verticalAlignment = Alignment.CenterVertically) { - Icon( - Icons.Rounded.BrightnessLow, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.size(20.dp) - ) - Spacer(modifier = Modifier.width(12.dp)) - Text( - text = stringResource( - R.string.brightness_threshold_format, - (state.nightModeBrightnessThreshold * 100).toInt() - ), - style = MaterialTheme.typography.bodyMedium, - fontWeight = FontWeight.Medium - ) - } - Slider( - value = state.nightModeBrightnessThreshold, - onValueChange = component::onNightModeBrightnessThresholdChanged, - valueRange = 0f..1f, - modifier = Modifier.padding(vertical = 8.dp) - ) - Text( - text = stringResource(R.string.brightness_threshold_description), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - - else -> Spacer(modifier = Modifier.height(0.dp)) - } - } - - HorizontalDivider( - modifier = Modifier.padding(vertical = 16.dp), - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - - FilledTonalButton( - onClick = { showThemeEditor = true }, - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(14.dp) - ) { - Icon( - imageVector = Icons.Rounded.Palette, - contentDescription = null - ) - Spacer(modifier = Modifier.width(8.dp)) - Text(stringResource(R.string.chat_settings_edit_custom_theme)) - } - } - } - } - - item { - SectionHeader(stringResource(R.string.data_storage_header)) - SettingsSwitchTile( - icon = Icons.Rounded.Photo, - title = stringResource(R.string.compress_photos_title), - subtitle = stringResource(R.string.compress_photos_subtitle), - checked = state.compressPhotos, - iconColor = blueColor, - position = ItemPosition.TOP, - onCheckedChange = component::onCompressPhotosChanged - ) - SettingsSwitchTile( - icon = Icons.Rounded.VideoFile, - title = stringResource(R.string.compress_videos_title), - subtitle = stringResource(R.string.compress_videos_subtitle), - checked = state.compressVideos, - iconColor = greenColor, - position = ItemPosition.BOTTOM, - onCheckedChange = component::onCompressVideosChanged - ) - } - - item { - SectionHeader(stringResource(R.string.video_player_header)) - SettingsSwitchTile( - icon = Icons.Rounded.Gesture, - title = stringResource(R.string.enable_gestures_title), - subtitle = stringResource(R.string.enable_gestures_subtitle), - checked = state.isPlayerGesturesEnabled, - iconColor = blueColor, - position = ItemPosition.TOP, - onCheckedChange = component::onPlayerGesturesEnabledChanged - ) - SettingsSwitchTile( - icon = Icons.Rounded.Forward10, - title = stringResource(R.string.double_tap_seek_title), - subtitle = stringResource(R.string.double_tap_seek_subtitle), - checked = state.isPlayerDoubleTapSeekEnabled, - iconColor = orangeColor, - position = ItemPosition.MIDDLE, - onCheckedChange = component::onPlayerDoubleTapSeekEnabledChanged - ) - - (AnimatedVisibility( - visible = state.isPlayerDoubleTapSeekEnabled, - enter = expandVertically() + fadeIn(), - exit = shrinkVertically() + fadeOut() - ) { - Column { - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(4.dp), - modifier = Modifier.fillMaxWidth() - ) { - Column(modifier = Modifier.padding(16.dp)) { - AppearanceSliderItem( - title = stringResource(R.string.seek_duration_title), - value = state.playerSeekDuration.toFloat(), - onValueChange = { component.onPlayerSeekDurationChanged(it.toInt()) }, - valueRange = 5f..60f, - steps = 10, - onReset = { component.onPlayerSeekDurationChanged(10) }, - valueSuffix = "s", - startIcon = { - Icon( - Icons.Rounded.FastRewind, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.size(20.dp) - ) - }, - endIcon = { - Icon( - Icons.Rounded.FastForward, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.size(20.dp) - ) - } - ) - } - } - Spacer(modifier = Modifier.height(2.dp)) - } - }) - - SettingsSwitchTile( - icon = Icons.Rounded.ZoomIn, - title = stringResource(R.string.enable_zoom_title), - subtitle = stringResource(R.string.enable_zoom_subtitle), - checked = state.isPlayerZoomEnabled, - iconColor = pinkColor, - position = ItemPosition.BOTTOM, - onCheckedChange = component::onPlayerZoomEnabledChanged - ) - } - - item { - SectionHeader(stringResource(R.string.chat_list_header)) - SettingsSwitchTile( - icon = Icons.Rounded.Archive, - title = stringResource(R.string.pin_archived_chats_title), - subtitle = stringResource(R.string.pin_archived_chats_subtitle), - checked = state.isArchivePinned, - iconColor = orangeColor, - position = ItemPosition.TOP, - onCheckedChange = component::onArchivePinnedChanged - ) - AnimatedVisibility( - visible = state.isArchivePinned, - enter = expandVertically() + fadeIn(), - exit = shrinkVertically() + fadeOut() - ) { - SettingsSwitchTile( - icon = Icons.Rounded.Archive, - title = stringResource(R.string.always_show_pinned_archive_title), - subtitle = stringResource(R.string.always_show_pinned_archive_subtitle), - checked = state.isArchiveAlwaysVisible, - iconColor = orangeColor, - position = ItemPosition.MIDDLE, - onCheckedChange = component::onArchiveAlwaysVisibleChanged - ) - } - SettingsSwitchTile( - icon = Icons.Rounded.Link, - title = stringResource(R.string.show_link_previews_title), - subtitle = stringResource(R.string.show_link_previews_subtitle), - checked = state.showLinkPreviews, - iconColor = blueColor, - position = ItemPosition.MIDDLE, - onCheckedChange = component::onShowLinkPreviewsChanged - ) - SettingsSwitchTile( - icon = Icons.Rounded.SwipeLeft, - title = stringResource(R.string.drag_to_back_title), - subtitle = stringResource(R.string.drag_to_back_subtitle), - checked = state.isDragToBackEnabled, - iconColor = tealColor, - position = ItemPosition.BOTTOM, - onCheckedChange = component::onDragToBackChanged - ) - } - - item { - ChatListPreview( - messageLines = state.chatListMessageLines, - showPhotos = state.showChatListPhotos, - position = ItemPosition.TOP, - videoPlayerPool = component.videoPlayerPool - ) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(4.dp), - modifier = Modifier.fillMaxWidth() - ) { - Column(modifier = Modifier.padding(16.dp)) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - listOf(1, 2).forEach { lines -> - val label = - if (lines == 1) stringResource(R.string.two_line_label) else stringResource(R.string.three_line_label) - Surface( - onClick = { component.onChatListMessageLinesChanged(lines) }, - shape = RoundedCornerShape(16.dp), - color = if (state.chatListMessageLines == lines) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerLow, - border = if (state.chatListMessageLines == lines) BorderStroke( - 2.dp, - MaterialTheme.colorScheme.primary - ) else null, - modifier = Modifier - .weight(1f) - .height(48.dp) - ) { - Box(contentAlignment = Alignment.Center) { - Text( - text = label, - style = MaterialTheme.typography.labelLarge, - color = if (state.chatListMessageLines == lines) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant, - fontWeight = if (state.chatListMessageLines == lines) FontWeight.Bold else FontWeight.Medium - ) - } - } - } - } - } - } - Spacer(modifier = Modifier.height(2.dp)) - - SettingsSwitchTile( - icon = Icons.Rounded.AccountCircle, - title = stringResource(R.string.show_photos_title), - subtitle = stringResource(R.string.show_photos_subtitle), - checked = state.showChatListPhotos, - iconColor = pinkColor, - position = ItemPosition.BOTTOM, - onCheckedChange = component::onShowChatListPhotosChanged - ) - } - - if (!state.isInstalledFromGooglePlay) { - item { - SectionHeader(stringResource(R.string.experimental_header)) - SettingsTile( - icon = Icons.Rounded.Block, - title = stringResource(R.string.adblock_channels_title), - subtitle = stringResource(R.string.adblock_channels_subtitle), - iconColor = redColor, - position = ItemPosition.STANDALONE, - onClick = component::onAdBlockClick - ) - } - } - - item { - SectionHeader(stringResource(R.string.recent_media_header)) - SettingsTile( - icon = Icons.AutoMirrored.Rounded.StickyNote2, - title = stringResource(R.string.clear_recent_stickers_title), - subtitle = stringResource(R.string.clear_recent_stickers_subtitle), - iconColor = purpleColor, - position = ItemPosition.TOP, - onClick = { showClearRecentStickersSheet = true } - ) - SettingsTile( - icon = Icons.Rounded.EmojiEmotions, - title = stringResource(R.string.clear_recent_emojis_title), - subtitle = stringResource(R.string.clear_recent_emojis_subtitle), - iconColor = tealColor, - position = ItemPosition.BOTTOM, - onClick = { showClearRecentEmojisSheet = true } - ) - } - } - } - - if (showClearRecentStickersSheet) { - ConfirmationSheet( - icon = Icons.Rounded.Delete, - title = stringResource(R.string.clear_recent_stickers_title), - description = stringResource(R.string.clear_recent_stickers_confirmation), - confirmText = stringResource(R.string.action_clear_recent_stickers), - onConfirm = { - component.onClearRecentStickers() - showClearRecentStickersSheet = false - }, - onDismiss = { showClearRecentStickersSheet = false } - ) - } - - if (showClearRecentEmojisSheet) { - ConfirmationSheet( - icon = Icons.Rounded.Delete, - title = stringResource(R.string.clear_recent_emojis_title), - description = stringResource(R.string.clear_recent_emojis_confirmation), - confirmText = stringResource(R.string.action_clear_recent_emojis), - onConfirm = { - component.onClearRecentEmojis() - showClearRecentEmojisSheet = false - }, - onDismiss = { showClearRecentEmojisSheet = false } - ) - } - - if (state.emojiPackToRemove != null) { - val style = state.emojiPackToRemove!! - val label = when (style) { - EmojiStyle.APPLE -> stringResource(R.string.emoji_style_apple) - EmojiStyle.TWITTER -> stringResource(R.string.emoji_style_twitter) - EmojiStyle.WINDOWS -> stringResource(R.string.emoji_style_windows) - EmojiStyle.CATMOJI -> stringResource(R.string.emoji_style_catmoji) - EmojiStyle.NOTO -> stringResource(R.string.emoji_style_noto) - else -> "" - } - - ModalBottomSheet( - onDismissRequest = component::onDismissRemoveEmojiPack, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 32.dp) - ) { - Text( - text = stringResource(R.string.remove_emoji_pack_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(horizontal = 4.dp) - ) - - Spacer(modifier = Modifier.height(16.dp)) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - Column( - modifier = Modifier.padding(16.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Box( - modifier = Modifier - .size(64.dp) - .background(MaterialTheme.colorScheme.errorContainer, CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - Icons.Rounded.DeleteOutline, - contentDescription = null, - tint = MaterialTheme.colorScheme.error, - modifier = Modifier.size(32.dp) - ) - } - Spacer(modifier = Modifier.height(16.dp)) - Text( - text = stringResource(R.string.remove_pack_confirmation_format, label), - style = MaterialTheme.typography.titleLarge, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - Spacer(modifier = Modifier.height(8.dp)) - Text( - text = stringResource(R.string.remove_pack_description), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center - ) - } - } - - Spacer(modifier = Modifier.height(24.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - OutlinedButton( - onClick = component::onDismissRemoveEmojiPack, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.cancel_button), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - - Button( - onClick = component::onConfirmRemoveEmojiPack, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp), - colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.error, - contentColor = MaterialTheme.colorScheme.onError - ) - ) { - Text(stringResource(R.string.action_delete), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } - } - } -} - -@Composable -private fun SectionHeader(text: String) { - Text( - text = text, - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp, top = 16.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) -} - -@Composable -private fun AppearanceSliderItem( - title: String, - value: Float, - onValueChange: (Float) -> Unit, - valueRange: ClosedFloatingPointRange, - steps: Int, - onReset: () -> Unit, - valueSuffix: String, - startIcon: @Composable () -> Unit, - endIcon: @Composable () -> Unit, - displayedDecimalPlaces: Int? = 0 -) { - Column { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = title, - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.onSurface, - fontWeight = FontWeight.SemiBold - ) - Spacer(modifier = Modifier.width(8.dp)) - Surface( - color = MaterialTheme.colorScheme.primary.copy(alpha = 0.1f), - shape = RoundedCornerShape(8.dp) - ) { - Text( - text = "${"%.${displayedDecimalPlaces}f".format(value)} $valueSuffix", - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.primary, - modifier = Modifier.padding(horizontal = 8.dp, vertical = 2.dp), - fontWeight = FontWeight.Bold - ) - } - } - TextButton( - onClick = onReset, - contentPadding = PaddingValues(horizontal = 12.dp, vertical = 4.dp), - modifier = Modifier.height(32.dp) - ) { - Text( - stringResource(R.string.reset_button), - style = MaterialTheme.typography.labelLarge, - fontWeight = FontWeight.Bold - ) - } - } - - Spacer(modifier = Modifier.height(8.dp)) - - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - Box(modifier = Modifier.size(24.dp), contentAlignment = Alignment.Center) { - startIcon() - } - Slider( - value = value, - onValueChange = onValueChange, - valueRange = valueRange, - steps = steps, - modifier = Modifier.weight(1f), - colors = SliderDefaults.colors( - thumbColor = MaterialTheme.colorScheme.primary, - activeTrackColor = MaterialTheme.colorScheme.primary, - inactiveTrackColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.2f) - ) - ) - Box(modifier = Modifier.size(24.dp), contentAlignment = Alignment.Center) { - endIcon() - } - } - } -} - -@Composable -private fun ThemeModeItem( - mode: NightMode, - selected: Boolean, - onClick: () -> Unit, - modifier: Modifier = Modifier -) { - val icon = when (mode) { - NightMode.SYSTEM -> Icons.Rounded.BrightnessAuto - NightMode.LIGHT -> Icons.Rounded.LightMode - NightMode.DARK -> Icons.Rounded.DarkMode - NightMode.SCHEDULED -> Icons.Rounded.Schedule - NightMode.BRIGHTNESS -> Icons.Rounded.Brightness4 - } - - val label = nightModeLabel(mode) - - val containerColor by animateColorAsState( - targetValue = if (selected) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerLow, - animationSpec = tween(400, easing = EaseOutQuint), - label = "containerColor" - ) - val contentColor by animateColorAsState( - targetValue = if (selected) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant, - animationSpec = tween(400, easing = EaseOutQuint), - label = "contentColor" - ) - val borderAlpha by animateFloatAsState( - targetValue = if (selected) 1f else 0f, - animationSpec = tween(400, easing = EaseOutQuint), - label = "borderAlpha" - ) - - Surface( - onClick = onClick, - shape = RoundedCornerShape(18.dp), - color = containerColor, - border = if (selected) BorderStroke( - 2.dp, - MaterialTheme.colorScheme.primary.copy(alpha = borderAlpha) - ) else null, - modifier = Modifier - .height(84.dp) - .fillMaxWidth() - .then(modifier) - ) { - Row( - modifier = Modifier - .fillMaxSize() - .padding(horizontal = 10.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(10.dp) - ) { - Box( - modifier = Modifier - .size(34.dp) - .background(contentColor.copy(alpha = if (selected) 0.16f else 0.1f), CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = icon, - contentDescription = null, - tint = contentColor, - modifier = Modifier.size(20.dp) - ) - } - Column(modifier = Modifier.weight(1f)) { - Text( - text = label, - style = MaterialTheme.typography.labelLarge, - color = contentColor, - fontWeight = if (selected) FontWeight.Bold else FontWeight.Medium, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - if (selected) { - Icon( - imageVector = Icons.Rounded.CheckCircle, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.size(18.dp) - ) - } - } - } -} - -@Composable -private fun nightModeLabel(mode: NightMode): String = when (mode) { - NightMode.SYSTEM -> stringResource(R.string.night_mode_system) - NightMode.LIGHT -> stringResource(R.string.night_mode_light) - NightMode.DARK -> stringResource(R.string.night_mode_dark) - NightMode.SCHEDULED -> stringResource(R.string.night_mode_scheduled) - NightMode.BRIGHTNESS -> stringResource(R.string.night_mode_brightness) -} - -@OptIn(ExperimentalFoundationApi::class) -@Composable -private fun EmojiStyleItem( - style: EmojiStyle, - selected: Boolean, - isDownloaded: Boolean, - isDownloading: Boolean, - onClick: () -> Unit, - onLongClick: () -> Unit -) { - val label = when (style) { - EmojiStyle.APPLE -> stringResource(R.string.emoji_style_apple) - EmojiStyle.TWITTER -> stringResource(R.string.emoji_style_twitter) - EmojiStyle.WINDOWS -> stringResource(R.string.emoji_style_windows) - EmojiStyle.CATMOJI -> stringResource(R.string.emoji_style_catmoji) - EmojiStyle.NOTO -> stringResource(R.string.emoji_style_noto) - EmojiStyle.SYSTEM -> stringResource(R.string.emoji_style_system) - } - - val emojiFontFamily = if (isDownloaded) { - getEmojiFontFamily(style) - } else { - FontFamily.Default - } - - val containerColor by animateColorAsState( - targetValue = if (selected) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceContainerLow, - animationSpec = tween(400, easing = EaseOutQuint), - label = "containerColor" - ) - val contentColor by animateColorAsState( - targetValue = if (selected) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurfaceVariant, - animationSpec = tween(400, easing = EaseOutQuint), - label = "contentColor" - ) - val borderAlpha by animateFloatAsState( - targetValue = if (selected) 1f else 0f, - animationSpec = tween(400, easing = EaseOutQuint), - label = "borderAlpha" - ) - - Surface( - modifier = Modifier - .height(100.dp) - .fillMaxWidth() - .clip(RoundedCornerShape(20.dp)) - .combinedClickable( - onClick = onClick, - onLongClick = onLongClick - ), - shape = RoundedCornerShape(20.dp), - color = containerColor, - border = if (selected) BorderStroke( - 2.dp, - MaterialTheme.colorScheme.primary.copy(alpha = borderAlpha) - ) else null, - ) { - Box(contentAlignment = Alignment.Center) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, - modifier = Modifier.padding(8.dp) - ) { - Text( - text = "\uD83D\uDE0A\uD83D\uDE0D\uD83D\uDE0E", - fontSize = 24.sp, - fontFamily = emojiFontFamily, - textAlign = TextAlign.Center - ) - Spacer(modifier = Modifier.height(8.dp)) - Text( - text = label, - style = MaterialTheme.typography.labelMedium, - color = contentColor, - fontWeight = if (selected) FontWeight.Bold else FontWeight.Medium, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - - if (!isDownloaded && style != EmojiStyle.SYSTEM) { - Box( - modifier = Modifier - .matchParentSize() - .background(Color.Black.copy(alpha = 0.3f), RoundedCornerShape(20.dp)), - contentAlignment = Alignment.Center - ) { - if (isDownloading) { - CircularProgressIndicator( - modifier = Modifier.size(24.dp), - color = Color.White, - strokeWidth = 2.dp - ) - } else { - Icon( - imageVector = Icons.Rounded.Download, - contentDescription = stringResource(R.string.action_download), - tint = Color.White, - modifier = Modifier.size(24.dp) - ) - } - } - } - } - } -} - -@Composable -private fun TimeSettingCard( - label: String, - time: String, - icon: ImageVector, - modifier: Modifier = Modifier, - onClick: () -> Unit -) { - Surface( - onClick = onClick, - shape = RoundedCornerShape(16.dp), - color = MaterialTheme.colorScheme.surfaceContainerLow, - modifier = modifier - ) { - Row( - modifier = Modifier.padding(12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Icon( - imageVector = icon, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.size(20.dp) - ) - Spacer(modifier = Modifier.width(12.dp)) - Column { - Text( - label, - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Text( - time, - style = MaterialTheme.typography.bodyLarge, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.primary - ) - } - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun TimePickerDialogWrapper( - onDismissRequest: () -> Unit, - onConfirm: () -> Unit, - content: @Composable () -> Unit, -) { - AlertDialog( - onDismissRequest = onDismissRequest, - confirmButton = { - TextButton(onClick = onConfirm) { - Text(stringResource(R.string.ok_button)) - } - }, - dismissButton = { - TextButton(onClick = onDismissRequest) { - Text(stringResource(R.string.cancel_button)) - } - }, - text = { - content() - } - ) -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/ChatThemeEditorScreen.kt b/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/ChatThemeEditorScreen.kt deleted file mode 100644 index d1e04c3b..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/ChatThemeEditorScreen.kt +++ /dev/null @@ -1,664 +0,0 @@ -package org.monogram.presentation.settings.chatSettings - -import org.monogram.presentation.core.util.coRunCatching -import android.graphics.Color.* -import android.widget.Toast -import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.Download -import androidx.compose.material.icons.rounded.Upload -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.luminance -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import org.monogram.presentation.R -import org.monogram.presentation.core.util.NightMode -import java.util.Calendar - -private enum class PaletteMode { LIGHT, DARK } - -private data class ThemePalette( - val primary: Int, - val secondary: Int, - val tertiary: Int, - val background: Int, - val surface: Int, - val primaryContainer: Int, - val secondaryContainer: Int, - val tertiaryContainer: Int, - val surfaceVariant: Int, - val outline: Int -) - -private data class ThemePreset( - val nameRes: Int, - val descriptionRes: Int, - val light: ThemePalette, - val dark: ThemePalette -) -private data class AccentPreset(val nameRes: Int, val color: Int) -private data class ColorRole(val labelRes: Int, val color: Int, val onApply: (Int) -> Unit) - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ChatThemeEditorScreen( - state: ChatSettingsComponent.State, - component: ChatSettingsComponent, - onBack: () -> Unit -) { - val context = LocalContext.current - val systemDark = isSystemInDarkTheme() - val activePaletteMode = resolveActivePaletteMode(state, systemDark) - var mode by rememberSaveable(activePaletteMode) { mutableStateOf(activePaletteMode) } - val isDark = mode == PaletteMode.DARK - var accentText by remember { mutableStateOf("#FF3390EC") } - var pickerTarget by remember { mutableStateOf(null) } - val modeLabel = if (isDark) stringResource(R.string.chat_theme_editor_dark) else stringResource(R.string.chat_theme_editor_light) - val activeModeLabel = if (activePaletteMode == PaletteMode.DARK) stringResource(R.string.chat_theme_editor_dark) else stringResource(R.string.chat_theme_editor_light) - val themeFileName = stringResource(R.string.chat_theme_editor_theme_file_name) - - val palette = if (isDark) { - ThemePalette( - state.themeDarkPrimaryColor, state.themeDarkSecondaryColor, state.themeDarkTertiaryColor, - state.themeDarkBackgroundColor, state.themeDarkSurfaceColor, - state.themeDarkPrimaryContainerColor, state.themeDarkSecondaryContainerColor, - state.themeDarkTertiaryContainerColor, state.themeDarkSurfaceVariantColor, state.themeDarkOutlineColor - ) - } else { - ThemePalette( - state.themePrimaryColor, state.themeSecondaryColor, state.themeTertiaryColor, - state.themeBackgroundColor, state.themeSurfaceColor, - state.themePrimaryContainerColor, state.themeSecondaryContainerColor, - state.themeTertiaryContainerColor, state.themeSurfaceVariantColor, state.themeOutlineColor - ) - } - LaunchedEffect(palette.primary) { accentText = argbToHex(palette.primary) } - - fun enableCustomThemeSource() { - component.onCustomThemeEnabledChanged(true) - if (state.isDynamicColorsEnabled) component.onDynamicColorsChanged(false) - } - - fun applyPalette(p: ThemePalette, dark: Boolean) { - if (dark) { - component.onThemeDarkPrimaryColorChanged(p.primary); component.onThemeDarkSecondaryColorChanged(p.secondary); component.onThemeDarkTertiaryColorChanged(p.tertiary) - component.onThemeDarkBackgroundColorChanged(p.background); component.onThemeDarkSurfaceColorChanged(p.surface) - component.onThemeDarkPrimaryContainerColorChanged(p.primaryContainer); component.onThemeDarkSecondaryContainerColorChanged(p.secondaryContainer) - component.onThemeDarkTertiaryContainerColorChanged(p.tertiaryContainer); component.onThemeDarkSurfaceVariantColorChanged(p.surfaceVariant) - component.onThemeDarkOutlineColorChanged(p.outline) - } else { - component.onThemePrimaryColorChanged(p.primary); component.onThemeSecondaryColorChanged(p.secondary); component.onThemeTertiaryColorChanged(p.tertiary) - component.onThemeBackgroundColorChanged(p.background); component.onThemeSurfaceColorChanged(p.surface) - component.onThemePrimaryContainerColorChanged(p.primaryContainer); component.onThemeSecondaryContainerColorChanged(p.secondaryContainer) - component.onThemeTertiaryContainerColorChanged(p.tertiaryContainer); component.onThemeSurfaceVariantColorChanged(p.surfaceVariant) - component.onThemeOutlineColorChanged(p.outline) - } - enableCustomThemeSource() - } - - val accents = remember { - listOf( - AccentPreset(R.string.chat_theme_editor_accent_blue, 0xFF3390EC.toInt()), AccentPreset(R.string.chat_theme_editor_accent_green, 0xFF2E7D32.toInt()), - AccentPreset(R.string.chat_theme_editor_accent_orange, 0xFFF57C00.toInt()), AccentPreset(R.string.chat_theme_editor_accent_rose, 0xFFD81B60.toInt()), - AccentPreset(R.string.chat_theme_editor_accent_indigo, 0xFF3F51B5.toInt()), AccentPreset(R.string.chat_theme_editor_accent_cyan, 0xFF0097A7.toInt()) - ) - } - val presets = remember { - listOf( - ThemePreset(R.string.chat_theme_editor_preset_classic_name, - R.string.chat_theme_editor_preset_classic_description, - ThemePalette(0xFF3390EC.toInt(),0xFF4C7599.toInt(),0xFF00ACC1.toInt(),0xFFFFFBFE.toInt(),0xFFFFFBFE.toInt(),0xFFD4E3FF.toInt(),0xFFD0E4F7.toInt(),0xFFC4EEF4.toInt(),0xFFE1E2EC.toInt(),0xFF757680.toInt()), - ThemePalette(0xFF64B5F6.toInt(),0xFF81A9CA.toInt(),0xFF4DD0E1.toInt(),0xFF121212.toInt(),0xFF121212.toInt(),0xFF224A77.toInt(),0xFF334F65.toInt(),0xFF1E636F.toInt(),0xFF44474F.toInt(),0xFF8E9099.toInt()) - ), - ThemePreset(R.string.chat_theme_editor_preset_forest_name, - R.string.chat_theme_editor_preset_forest_description, - ThemePalette(0xFF2E7D32.toInt(),0xFF558B2F.toInt(),0xFF00796B.toInt(),0xFFF6FFF7.toInt(),0xFFFFFFFF.toInt(),0xFFCFEBD2.toInt(),0xFFDFEBD0.toInt(),0xFFCBE7E2.toInt(),0xFFDEE7DD.toInt(),0xFF6F7A73.toInt()), - ThemePalette(0xFF81C784.toInt(),0xFFA5D6A7.toInt(),0xFF80CBC4.toInt(),0xFF101A12.toInt(),0xFF142018.toInt(),0xFF284A30.toInt(),0xFF35523A.toInt(),0xFF25564F.toInt(),0xFF424D46.toInt(),0xFF909B94.toInt()) - ), - ThemePreset(R.string.chat_theme_editor_preset_ocean_name, - R.string.chat_theme_editor_preset_ocean_description, - ThemePalette(0xFF0277BD.toInt(),0xFF0097A7.toInt(),0xFF26A69A.toInt(),0xFFF3FBFF.toInt(),0xFFFFFFFF.toInt(),0xFFC7E7F7.toInt(),0xFFC8EFF2.toInt(),0xFFD2F2EE.toInt(),0xFFDCE8EC.toInt(),0xFF6F7E86.toInt()), - ThemePalette(0xFF4FC3F7.toInt(),0xFF4DD0E1.toInt(),0xFF80CBC4.toInt(),0xFF0D1820.toInt(),0xFF122029.toInt(),0xFF1E4A63.toInt(),0xFF1E5460.toInt(),0xFF275A55.toInt(),0xFF3D4950.toInt(),0xFF8A979E.toInt()) - ), - ThemePreset(R.string.chat_theme_editor_preset_sunset_name, - R.string.chat_theme_editor_preset_sunset_description, - ThemePalette(0xFFE65100.toInt(),0xFFEF6C00.toInt(),0xFFD84315.toInt(),0xFFFFF8F4.toInt(),0xFFFFFFFF.toInt(),0xFFFFDCCB.toInt(),0xFFFFE1CE.toInt(),0xFFFFD9D0.toInt(),0xFFF1E1D9.toInt(),0xFF7C726E.toInt()), - ThemePalette(0xFFFF8A65.toInt(),0xFFFFA726.toInt(),0xFFFF7043.toInt(),0xFF1A1310.toInt(),0xFF201814.toInt(),0xFF6A3B27.toInt(),0xFF704824.toInt(),0xFF6A332A.toInt(),0xFF4E433D.toInt(),0xFFA1958F.toInt()) - ), - ThemePreset(R.string.chat_theme_editor_preset_graphite_name, - R.string.chat_theme_editor_preset_graphite_description, - ThemePalette(0xFF455A64.toInt(),0xFF607D8B.toInt(),0xFF546E7A.toInt(),0xFFF7F8F9.toInt(),0xFFFFFFFF.toInt(),0xFFD6E0E4.toInt(),0xFFD9E1E5.toInt(),0xFFD7E0E3.toInt(),0xFFE2E6E8.toInt(),0xFF737A7D.toInt()), - ThemePalette(0xFF90A4AE.toInt(),0xFFB0BEC5.toInt(),0xFF8FA1A8.toInt(),0xFF121416.toInt(),0xFF1A1E21.toInt(),0xFF34424A.toInt(),0xFF3C4A52.toInt(),0xFF35444B.toInt(),0xFF43494D.toInt(),0xFF949DA2.toInt()) - ), - ThemePreset(R.string.chat_theme_editor_preset_mint_name, - R.string.chat_theme_editor_preset_mint_description, - ThemePalette(0xFF00897B.toInt(),0xFF26A69A.toInt(),0xFF43A047.toInt(),0xFFF3FFFC.toInt(),0xFFFFFFFF.toInt(),0xFFC6EDE7.toInt(),0xFFD2F1EB.toInt(),0xFFD5ECD0.toInt(),0xFFD9EAE4.toInt(),0xFF70807A.toInt()), - ThemePalette(0xFF4DB6AC.toInt(),0xFF80CBC4.toInt(),0xFF81C784.toInt(),0xFF0F1C1A.toInt(),0xFF152422.toInt(),0xFF23534C.toInt(),0xFF2A5B54.toInt(),0xFF2F5634.toInt(),0xFF3D4E4A.toInt(),0xFF8D9F9A.toInt()) - ), - ThemePreset(R.string.chat_theme_editor_preset_ruby_name, - R.string.chat_theme_editor_preset_ruby_description, - ThemePalette(0xFFB71C1C.toInt(),0xFFD84343.toInt(),0xFFC62828.toInt(),0xFFFFF8F8.toInt(),0xFFFFFFFF.toInt(),0xFFF7D6D6.toInt(),0xFFF4D9D9.toInt(),0xFFF1D2D2.toInt(),0xFFEEE1E1.toInt(),0xFF7F7070.toInt()), - ThemePalette(0xFFEF9A9A.toInt(),0xFFFF8A80.toInt(),0xFFE57373.toInt(),0xFF1C1111.toInt(),0xFF241717.toInt(),0xFF6A2E2E.toInt(),0xFF703535.toInt(),0xFF5F2E2E.toInt(),0xFF4A3C3C.toInt(),0xFFA59494.toInt()) - ), - ThemePreset(R.string.chat_theme_editor_preset_lavender_gray_name, - R.string.chat_theme_editor_preset_lavender_gray_description, - ThemePalette(0xFF6A5ACD.toInt(),0xFF7E71B2.toInt(),0xFF8D7AAE.toInt(),0xFFFAF9FF.toInt(),0xFFFFFFFF.toInt(),0xFFE2DDF9.toInt(),0xFFE4E1F1.toInt(),0xFFE8E2F2.toInt(),0xFFE6E3EC.toInt(),0xFF787483.toInt()), - ThemePalette(0xFFAFA4E8.toInt(),0xFFB8AFDD.toInt(),0xFFC1B5DE.toInt(),0xFF141221.toInt(),0xFF1B192A.toInt(),0xFF433A6C.toInt(),0xFF4A4267.toInt(),0xFF514865.toInt(),0xFF474556.toInt(),0xFF9A97A8.toInt()) - ), - ThemePreset(R.string.chat_theme_editor_preset_sand_name, - R.string.chat_theme_editor_preset_sand_description, - ThemePalette(0xFF8D6E63.toInt(),0xFFA1887F.toInt(),0xFFBCAAA4.toInt(),0xFFFFFCF7.toInt(),0xFFFFFFFF.toInt(),0xFFEEDFD6.toInt(),0xFFF0E3DB.toInt(),0xFFF1E8E2.toInt(),0xFFEAE4DE.toInt(),0xFF7E766F.toInt()), - ThemePalette(0xFFD7CCC8.toInt(),0xFFBCAAA4.toInt(),0xFFA1887F.toInt(),0xFF181411.toInt(),0xFF201A16.toInt(),0xFF5A4A3F.toInt(),0xFF594B42.toInt(),0xFF4F433B.toInt(),0xFF47413D.toInt(),0xFF9E948D.toInt()) - ), - ThemePreset(R.string.chat_theme_editor_preset_arctic_name, - R.string.chat_theme_editor_preset_arctic_description, - ThemePalette(0xFF1976D2.toInt(),0xFF64B5F6.toInt(),0xFF00BCD4.toInt(),0xFFF6FCFF.toInt(),0xFFFFFFFF.toInt(),0xFFD7E9F9.toInt(),0xFFDDF0FF.toInt(),0xFFD3F2F6.toInt(),0xFFE1EBF0.toInt(),0xFF75828A.toInt()), - ThemePalette(0xFF90CAF9.toInt(),0xFF81D4FA.toInt(),0xFF80DEEA.toInt(),0xFF101820.toInt(),0xFF16212A.toInt(),0xFF29465F.toInt(),0xFF2C5068.toInt(),0xFF285760.toInt(),0xFF404C55.toInt(),0xFF93A0A8.toInt()) - ), - ThemePreset(R.string.chat_theme_editor_preset_emerald_name, - R.string.chat_theme_editor_preset_emerald_description, - ThemePalette(0xFF0F9D58.toInt(),0xFF2E7D32.toInt(),0xFF00897B.toInt(),0xFFF4FFF8.toInt(),0xFFFFFFFF.toInt(),0xFFCBF0DB.toInt(),0xFFD8EED2.toInt(),0xFFCBEDE7.toInt(),0xFFDEE9E2.toInt(),0xFF6F7E74.toInt()), - ThemePalette(0xFF66D19E.toInt(),0xFF81C784.toInt(),0xFF4DB6AC.toInt(),0xFF0F1913.toInt(),0xFF15211A.toInt(),0xFF1D5A3A.toInt(),0xFF275238.toInt(),0xFF1E5B53.toInt(),0xFF3E4E45.toInt(),0xFF8E9E94.toInt()) - ), - ThemePreset(R.string.chat_theme_editor_preset_copper_name, - R.string.chat_theme_editor_preset_copper_description, - ThemePalette(0xFFBF360C.toInt(),0xFFD84315.toInt(),0xFFF57C00.toInt(),0xFFFFF8F2.toInt(),0xFFFFFFFF.toInt(),0xFFFFDDCF.toInt(),0xFFF8DED4.toInt(),0xFFFFE5CC.toInt(),0xFFEFE3DA.toInt(),0xFF7E726B.toInt()), - ThemePalette(0xFFFFAB91.toInt(),0xFFFF8A65.toInt(),0xFFFFB74D.toInt(),0xFF1D130F.toInt(),0xFF241915.toInt(),0xFF6A3A2A.toInt(),0xFF6A362A.toInt(),0xFF6F4A20.toInt(),0xFF4E433C.toInt(),0xFFA2958D.toInt()) - ), - ThemePreset(R.string.chat_theme_editor_preset_sakura_name, - R.string.chat_theme_editor_preset_sakura_description, - ThemePalette(0xFFC2185B.toInt(),0xFFD81B60.toInt(),0xFFAD1457.toInt(),0xFFFFF7FB.toInt(),0xFFFFFFFF.toInt(),0xFFF8D6E7.toInt(),0xFFF4D4E2.toInt(),0xFFF2D0DE.toInt(),0xFFEFE1E8.toInt(),0xFF7E6F78.toInt()), - ThemePalette(0xFFF48FB1.toInt(),0xFFF06292.toInt(),0xFFE57399.toInt(),0xFF1C1218.toInt(),0xFF251921.toInt(),0xFF69334E.toInt(),0xFF6C3550.toInt(),0xFF5A2C46.toInt(),0xFF4B3E46.toInt(),0xFFA5949E.toInt()) - ), - ThemePreset(R.string.chat_theme_editor_preset_nord_name, - R.string.chat_theme_editor_preset_nord_description, - ThemePalette(0xFF3B5B92.toInt(),0xFF607D8B.toInt(),0xFF4FC3F7.toInt(),0xFFF5F8FC.toInt(),0xFFFFFFFF.toInt(),0xFFD4E0F2.toInt(),0xFFDCE4EC.toInt(),0xFFD2EAF5.toInt(),0xFFE2E8EF.toInt(),0xFF727D88.toInt()), - ThemePalette(0xFF8FA8D6.toInt(),0xFF90A4AE.toInt(),0xFF81D4FA.toInt(),0xFF111722.toInt(),0xFF18202C.toInt(),0xFF2F456C.toInt(),0xFF384B58.toInt(),0xFF2D4F66.toInt(),0xFF404954.toInt(),0xFF94A0AB.toInt()) - ) - ) - } - - val roles = listOf( - ColorRole(R.string.chat_theme_editor_role_primary, palette.primary) { if (isDark) component.onThemeDarkPrimaryColorChanged(it) else component.onThemePrimaryColorChanged(it) }, - ColorRole(R.string.chat_theme_editor_role_secondary, palette.secondary) { if (isDark) component.onThemeDarkSecondaryColorChanged(it) else component.onThemeSecondaryColorChanged(it) }, - ColorRole(R.string.chat_theme_editor_role_tertiary, palette.tertiary) { if (isDark) component.onThemeDarkTertiaryColorChanged(it) else component.onThemeTertiaryColorChanged(it) }, - ColorRole(R.string.chat_theme_editor_role_background, palette.background) { if (isDark) component.onThemeDarkBackgroundColorChanged(it) else component.onThemeBackgroundColorChanged(it) }, - ColorRole(R.string.chat_theme_editor_role_surface, palette.surface) { if (isDark) component.onThemeDarkSurfaceColorChanged(it) else component.onThemeSurfaceColorChanged(it) }, - ColorRole(R.string.chat_theme_editor_role_primary_container, palette.primaryContainer) { if (isDark) component.onThemeDarkPrimaryContainerColorChanged(it) else component.onThemePrimaryContainerColorChanged(it) }, - ColorRole(R.string.chat_theme_editor_role_secondary_container, palette.secondaryContainer) { if (isDark) component.onThemeDarkSecondaryContainerColorChanged(it) else component.onThemeSecondaryContainerColorChanged(it) }, - ColorRole(R.string.chat_theme_editor_role_tertiary_container, palette.tertiaryContainer) { if (isDark) component.onThemeDarkTertiaryContainerColorChanged(it) else component.onThemeTertiaryContainerColorChanged(it) }, - ColorRole(R.string.chat_theme_editor_role_surface_variant, palette.surfaceVariant) { if (isDark) component.onThemeDarkSurfaceVariantColorChanged(it) else component.onThemeSurfaceVariantColorChanged(it) }, - ColorRole(R.string.chat_theme_editor_role_outline, palette.outline) { if (isDark) component.onThemeDarkOutlineColorChanged(it) else component.onThemeOutlineColorChanged(it) } - ) - - if (pickerTarget != null) { - Material3ColorPickerDialog( - title = stringResource(pickerTarget!!.labelRes), - initialColor = pickerTarget!!.color, - onDismiss = { pickerTarget = null }, - onApply = { - pickerTarget!!.onApply(it) - enableCustomThemeSource() - pickerTarget = null - } - ) - } - - val saveLauncher = rememberLauncherForActivityResult(ActivityResultContracts.CreateDocument("application/json")) { uri -> - if (uri == null) return@rememberLauncherForActivityResult - coRunCatching { context.contentResolver.openOutputStream(uri)?.bufferedWriter()?.use { it.write(component.exportCustomThemeJson()) } } - .onSuccess { Toast.makeText(context, context.getString(R.string.chat_theme_editor_theme_file_saved), Toast.LENGTH_SHORT).show() } - .onFailure { Toast.makeText(context, context.getString(R.string.chat_theme_editor_save_failed), Toast.LENGTH_SHORT).show() } - } - val loadLauncher = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) { uri -> - if (uri == null) return@rememberLauncherForActivityResult - coRunCatching { context.contentResolver.openInputStream(uri)?.bufferedReader()?.use { it.readText() }.orEmpty() } - .onSuccess { - val messageRes = if (component.importCustomThemeJson(it)) { - R.string.chat_theme_editor_theme_loaded - } else { - R.string.chat_theme_editor_invalid_file - } - Toast.makeText(context, context.getString(messageRes), Toast.LENGTH_SHORT).show() - } - .onFailure { Toast.makeText(context, context.getString(R.string.chat_theme_editor_load_failed), Toast.LENGTH_SHORT).show() } - } - - Scaffold( - topBar = { - TopAppBar( - title = { Text(stringResource(R.string.chat_theme_editor_title), fontWeight = FontWeight.Bold) }, - navigationIcon = { IconButton(onClick = onBack) { Icon(Icons.AutoMirrored.Rounded.ArrowBack, null) } }, - colors = TopAppBarDefaults.topAppBarColors(containerColor = MaterialTheme.colorScheme.background) - ) - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - LazyColumn( - modifier = Modifier.fillMaxSize(), - contentPadding = PaddingValues(16.dp, padding.calculateTopPadding() + 8.dp, 16.dp, padding.calculateBottomPadding() + 24.dp), - verticalArrangement = Arrangement.spacedBy(14.dp) - ) { - item { EditorHeader(state, component) } - item { - - Surface(shape = RoundedCornerShape(18.dp), color = MaterialTheme.colorScheme.surfaceContainer, modifier = Modifier.fillMaxWidth()) { - Column(Modifier.padding(14.dp), verticalArrangement = Arrangement.spacedBy(10.dp)) { - Text(stringResource(R.string.chat_theme_editor_palette_mode), style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold) - Text( - stringResource(R.string.chat_theme_editor_palette_mode_description), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(10.dp)) { - FilterChip( - selected = !isDark, - onClick = { mode = PaletteMode.LIGHT }, - label = { Text(stringResource(R.string.chat_theme_editor_light)) }, - modifier = Modifier.weight(1f) - ) - FilterChip( - selected = isDark, - onClick = { mode = PaletteMode.DARK }, - label = { Text(stringResource(R.string.chat_theme_editor_dark)) }, - modifier = Modifier.weight(1f) - ) - } - Surface( - shape = RoundedCornerShape(12.dp), - color = MaterialTheme.colorScheme.surfaceContainerLow, - modifier = Modifier.fillMaxWidth() - ) { - Column(Modifier.padding(horizontal = 12.dp, vertical = 10.dp), verticalArrangement = Arrangement.spacedBy(2.dp)) { - Text( - stringResource(R.string.chat_theme_editor_editing_palette, modeLabel), - style = MaterialTheme.typography.bodyMedium, - fontWeight = FontWeight.Medium - ) - Text( - stringResource(R.string.chat_theme_editor_active_palette, activeModeLabel), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } - } - - } - item { - - Surface(shape = RoundedCornerShape(18.dp), color = MaterialTheme.colorScheme.surfaceContainer, modifier = Modifier.fillMaxWidth()) { - Column(Modifier.padding(14.dp), verticalArrangement = Arrangement.spacedBy(10.dp)) { - Text(stringResource(R.string.chat_theme_editor_accent), style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold) - Text( - stringResource(R.string.chat_theme_editor_accent_description, modeLabel), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - LazyRow(horizontalArrangement = Arrangement.spacedBy(8.dp)) { - items(accents) { a -> - Surface(shape = RoundedCornerShape(12.dp), color = MaterialTheme.colorScheme.surfaceContainerLow, modifier = Modifier.clickable { - component.onApplyThemeAccent(a.color, isDark) - enableCustomThemeSource() - }) { - Row(Modifier.padding(horizontal = 10.dp, vertical = 8.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) { - Box( - Modifier - .size(14.dp) - .background(Color(a.color), CircleShape) - ) - Text(stringResource(a.nameRes), style = MaterialTheme.typography.labelLarge) - } - } - } - } - Row(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically) { - OutlinedTextField(value = accentText, onValueChange = { accentText = it }, label = { Text(stringResource(R.string.chat_theme_editor_hex_accent)) }, singleLine = true, modifier = Modifier.weight(1f)) - Button(onClick = { - parseThemeColor(accentText)?.let { - component.onApplyThemeAccent(it, isDark) - enableCustomThemeSource() - } - }) { Text(stringResource(R.string.chat_theme_editor_apply)) } - } - } - - } - } - item { - Surface(shape = RoundedCornerShape(18.dp), color = MaterialTheme.colorScheme.surfaceContainer, modifier = Modifier.fillMaxWidth()) { - Column(Modifier.padding(14.dp), verticalArrangement = Arrangement.spacedBy(10.dp)) { - Text(stringResource(R.string.chat_theme_editor_preset_themes), style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold) - Text( - stringResource(R.string.chat_theme_editor_preset_themes_description), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - LazyRow(horizontalArrangement = Arrangement.spacedBy(10.dp)) { - items(presets) { p -> PresetCard(p, { applyPalette(p.light, false) }, { applyPalette(p.dark, true) }, { applyPalette(p.light, false); applyPalette(p.dark, true) }) } - } - } - - } - } - item { - Surface(shape = RoundedCornerShape(18.dp), color = MaterialTheme.colorScheme.surfaceContainer, modifier = Modifier.fillMaxWidth()) { - Column(Modifier.padding(14.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) { - Text(stringResource(R.string.chat_theme_editor_manual_colors_title, modeLabel), style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold) - roles.forEach { role -> - Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(10.dp)) { - Box( - Modifier - .size(24.dp) - .background(Color(role.color), CircleShape) - .border( - 1.dp, - MaterialTheme.colorScheme.outline.copy(alpha = 0.5f), - CircleShape - ) - ) - Column(Modifier.weight(1f)) { Text(stringResource(role.labelRes)); Text(argbToHex(role.color), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant) } - OutlinedButton(onClick = { pickerTarget = role }) { Text(stringResource(R.string.chat_theme_editor_pick)) } - } - } - } - } - - } - item { ThemePreview(palette, isDark, state.isAmoledThemeEnabled) } - item { - Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(10.dp)) { - Button(onClick = { saveLauncher.launch(themeFileName) }, modifier = Modifier.weight(1f)) { Icon(Icons.Rounded.Download, null); Spacer(Modifier.size(6.dp)); Text(stringResource(R.string.chat_theme_editor_save)) } - Button(onClick = { loadLauncher.launch(arrayOf("application/json", "text/*")) }, modifier = Modifier.weight(1f)) { Icon(Icons.Rounded.Upload, null); Spacer(Modifier.size(6.dp)); Text(stringResource(R.string.chat_theme_editor_load)) } - } - } - - } - } -} - -@Composable -private fun EditorHeader(state: ChatSettingsComponent.State, component: ChatSettingsComponent) { - Surface(shape = RoundedCornerShape(18.dp), color = MaterialTheme.colorScheme.surfaceContainer, modifier = Modifier.fillMaxWidth()) { - Column(Modifier.padding(14.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) { - Text( - stringResource(R.string.chat_theme_editor_theme_source_title), - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.SemiBold - ) - Text( - stringResource(R.string.chat_theme_editor_theme_source_description), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - ToggleRow( - text = stringResource(R.string.chat_theme_editor_custom_theme), - description = stringResource(R.string.chat_theme_editor_custom_theme_description), - value = state.isCustomThemeEnabled - ) { enabled -> component.onCustomThemeEnabledChanged(enabled); if (enabled && state.isDynamicColorsEnabled) component.onDynamicColorsChanged(false) } - ToggleRow( - text = stringResource(R.string.chat_theme_editor_monet), - description = stringResource(R.string.chat_theme_editor_monet_description), - value = state.isDynamicColorsEnabled - ) { enabled -> component.onDynamicColorsChanged(enabled); if (enabled && state.isCustomThemeEnabled) component.onCustomThemeEnabledChanged(false) } - ToggleRow( - text = stringResource(R.string.chat_theme_editor_amoled_dark), - description = stringResource(R.string.chat_theme_editor_amoled_dark_description), - value = state.isAmoledThemeEnabled, - onChange = component::onAmoledThemeChanged - ) - } - } -} - -@Composable -private fun ToggleRow(text: String, description: String, value: Boolean, onChange: (Boolean) -> Unit) { - Surface( - shape = RoundedCornerShape(12.dp), - color = MaterialTheme.colorScheme.surfaceContainerLow, - modifier = Modifier.fillMaxWidth() - ) { - Row( - Modifier - .fillMaxWidth() - .padding(horizontal = 12.dp, vertical = 10.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Column(Modifier.weight(1f)) { - Text(text, fontWeight = FontWeight.Medium) - Text( - description, - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - Spacer(Modifier.width(12.dp)) - Switch(checked = value, onCheckedChange = onChange) - } - } -} - -@Composable -private fun PresetCard(p: ThemePreset, onLight: () -> Unit, onDark: () -> Unit, onBoth: () -> Unit) { - Card(shape = RoundedCornerShape(14.dp), colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceContainerLow), modifier = Modifier.width(320.dp)) { - Column(Modifier.fillMaxSize()) { - Row(Modifier.weight(1f)) { - MiniPalette(stringResource(R.string.chat_theme_editor_light), p.light, Modifier.weight(1f)) - MiniPalette(stringResource(R.string.chat_theme_editor_dark), p.dark, Modifier.weight(1f)) - } - Text(stringResource(p.nameRes), modifier = Modifier.padding(horizontal = 10.dp, vertical = 6.dp), fontWeight = FontWeight.SemiBold) - Text( - stringResource(p.descriptionRes), - modifier = Modifier.padding(horizontal = 10.dp), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 2, - overflow = TextOverflow.Ellipsis - ) - Spacer(Modifier.height(6.dp)) - Row( - Modifier - .fillMaxWidth() - .padding(horizontal = 10.dp), - horizontalArrangement = Arrangement.spacedBy(6.dp) - ) { - ColorInfoChip(stringResource(R.string.chat_theme_editor_chip_light_primary), p.light.primary) - ColorInfoChip(stringResource(R.string.chat_theme_editor_chip_light_container), p.light.primaryContainer) - ColorInfoChip(stringResource(R.string.chat_theme_editor_chip_light_background), p.light.background) - } - Spacer(Modifier.height(4.dp)) - Row( - Modifier - .fillMaxWidth() - .padding(horizontal = 10.dp), - horizontalArrangement = Arrangement.spacedBy(6.dp) - ) { - ColorInfoChip(stringResource(R.string.chat_theme_editor_chip_dark_primary), p.dark.primary) - ColorInfoChip(stringResource(R.string.chat_theme_editor_chip_dark_container), p.dark.primaryContainer) - ColorInfoChip(stringResource(R.string.chat_theme_editor_chip_dark_background), p.dark.background) - } - Row( - Modifier - .fillMaxWidth() - .padding(horizontal = 8.dp), horizontalArrangement = Arrangement.spacedBy(6.dp) - ) { - OutlinedButton(onClick = onLight, modifier = Modifier.weight(1f), contentPadding = PaddingValues(0.dp)) { Text(stringResource(R.string.chat_theme_editor_light)) } - Button(onClick = onDark, modifier = Modifier.weight(1f), contentPadding = PaddingValues(0.dp)) { Text(stringResource(R.string.chat_theme_editor_dark)) } - } - OutlinedButton( - onClick = onBoth, modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 8.dp, vertical = 4.dp), contentPadding = PaddingValues(0.dp) - ) { Text(stringResource(R.string.chat_theme_editor_both)) } - } - } -} - -@Composable -private fun ColorInfoChip(label: String, color: Int) { - val c = Color(color) - val textColor = if (c.luminance() > 0.5f) Color.Black else Color.White - Surface(shape = RoundedCornerShape(8.dp), color = c, tonalElevation = 0.dp) { - Text( - "$label ${argbToHex(color).takeLast(7)}", - modifier = Modifier.padding(horizontal = 6.dp, vertical = 3.dp), - color = textColor, - style = MaterialTheme.typography.labelSmall - ) - } -} - -@Composable -private fun MiniPalette(label: String, p: ThemePalette, modifier: Modifier = Modifier) { - val bg = Color(p.background); val textColor = if (bg.luminance() > 0.5f) Color.Black else Color.White - Column( - modifier - .background(bg) - .padding(8.dp), verticalArrangement = Arrangement.SpaceBetween - ) { - Text(label, color = textColor, style = MaterialTheme.typography.labelSmall, maxLines = 1, overflow = TextOverflow.Ellipsis) - Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) { - Box( - Modifier - .size(9.dp) - .background(Color(p.primary), CircleShape) - .border(1.dp, textColor.copy(alpha = 0.3f), CircleShape) - ) - Box( - Modifier - .size(9.dp) - .background(Color(p.secondary), CircleShape) - .border(1.dp, textColor.copy(alpha = 0.3f), CircleShape) - ) - Box( - Modifier - .size(9.dp) - .background(Color(p.tertiary), CircleShape) - .border(1.dp, textColor.copy(alpha = 0.3f), CircleShape) - ) - } - } -} - -@Composable -private fun ThemePreview(p: ThemePalette, dark: Boolean, amoled: Boolean) { - val bg = if (dark && amoled) Color.Black else Color(p.background) - val surface = if (dark && amoled) Color.Black else Color(p.surface) - val primary = Color(p.primary) - val onBg = if (bg.luminance() > 0.5f) Color.Black else Color.White - Card(shape = RoundedCornerShape(18.dp), colors = CardDefaults.cardColors(containerColor = bg), modifier = Modifier.fillMaxWidth()) { - Column(Modifier.padding(14.dp)) { - Text(stringResource(R.string.chat_theme_editor_preview_title, if (dark) stringResource(R.string.chat_theme_editor_dark) else stringResource(R.string.chat_theme_editor_light)), color = onBg, fontWeight = FontWeight.SemiBold) - Spacer(Modifier.height(8.dp)) - Surface(shape = RoundedCornerShape(12.dp), color = surface) { - Column(Modifier.padding(10.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) { - Surface(shape = RoundedCornerShape(10.dp), color = Color(p.surfaceVariant)) { Text(stringResource(R.string.chat_theme_editor_preview_summary_text), Modifier.padding(8.dp)) } - Surface(shape = RoundedCornerShape(10.dp), color = primary) { Text(stringResource(R.string.chat_theme_editor_preview_action), Modifier.padding(8.dp), color = if (primary.luminance() > 0.5f) Color.Black else Color.White) } - } - } - } - } -} - -@Composable -private fun Material3ColorPickerDialog( - title: String, - initialColor: Int, - onDismiss: () -> Unit, - onApply: (Int) -> Unit -) { - var hsv by remember(initialColor) { mutableStateOf(toHsv(initialColor)) } - var a by remember(initialColor) { mutableStateOf(((initialColor ushr 24) and 0xFF) / 255f) } - var hex by remember(initialColor) { mutableStateOf(argbToHex(initialColor)) } - val current = fromHsv(hsv[0], hsv[1], hsv[2], a) - LaunchedEffect(current) { hex = argbToHex(current) } - - AlertDialog( - onDismissRequest = onDismiss, - confirmButton = { Button(onClick = { onApply(current) }) { Text(stringResource(R.string.chat_theme_editor_apply)) } }, - dismissButton = { TextButton(onClick = onDismiss) { Text(stringResource(R.string.chat_theme_editor_cancel)) } }, - title = { Text(stringResource(R.string.chat_theme_editor_pick_title, title)) }, - text = { - Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { - Box( - Modifier - .fillMaxWidth() - .height(42.dp) - .background(Color(current), RoundedCornerShape(10.dp)) - .border(1.dp, MaterialTheme.colorScheme.outline, RoundedCornerShape(10.dp)) - ) - OutlinedTextField( - value = hex, - onValueChange = { - hex = it - parseThemeColor(it)?.let { c -> hsv = toHsv(c); a = ((c ushr 24) and 0xFF) / 255f } - }, - label = { Text(stringResource(R.string.chat_theme_editor_hex)) }, - singleLine = true, - modifier = Modifier.fillMaxWidth() - ) - Text(stringResource(R.string.chat_theme_editor_hue_format, hsv[0].toInt()), style = MaterialTheme.typography.labelSmall); Slider(hsv[0], { hsv = floatArrayOf(it, hsv[1], hsv[2]) }, valueRange = 0f..360f) - Text(stringResource(R.string.chat_theme_editor_saturation_format, (hsv[1] * 100).toInt()), style = MaterialTheme.typography.labelSmall); Slider(hsv[1], { hsv = floatArrayOf(hsv[0], it, hsv[2]) }, valueRange = 0f..1f) - Text(stringResource(R.string.chat_theme_editor_brightness_format, (hsv[2] * 100).toInt()), style = MaterialTheme.typography.labelSmall); Slider(hsv[2], { hsv = floatArrayOf(hsv[0], hsv[1], it) }, valueRange = 0f..1f) - Text(stringResource(R.string.chat_theme_editor_alpha_format, (a * 100).toInt()), style = MaterialTheme.typography.labelSmall); Slider(a, { a = it }, valueRange = 0f..1f) - } - } - ) -} - -private fun argbToHex(color: Int): String = String.format("#%08X", color) -private fun parseThemeColor(value: String): Int? { - val s = value.trim() - if (!s.startsWith("#") || (s.length != 7 && s.length != 9)) return null - return coRunCatching { val p = parseColor(s); if (s.length == 7) p or (0xFF shl 24) else p }.getOrNull() -} -private fun toHsv(color: Int): FloatArray = FloatArray(3).also { colorToHSV(color, it) } -private fun fromHsv(h: Float, s: Float, v: Float, a: Float): Int = - HSVToColor((a * 255f).toInt().coerceIn(0, 255), floatArrayOf(h, s, v)) - -private fun resolveActivePaletteMode(state: ChatSettingsComponent.State, systemDark: Boolean): PaletteMode { - return when (state.nightMode) { - NightMode.SYSTEM -> if (systemDark) PaletteMode.DARK else PaletteMode.LIGHT - NightMode.LIGHT -> PaletteMode.LIGHT - NightMode.DARK -> PaletteMode.DARK - NightMode.SCHEDULED -> { - val now = Calendar.getInstance().let { it.get(Calendar.HOUR_OF_DAY) * 60 + it.get(Calendar.MINUTE) } - val start = parseTimeToMinutes(state.nightModeStartTime, fallbackHour = 22) - val end = parseTimeToMinutes(state.nightModeEndTime, fallbackHour = 7) - val isDarkNow = if (start < end) now in start until end else now >= start || now < end - if (isDarkNow) PaletteMode.DARK else PaletteMode.LIGHT - } - - NightMode.BRIGHTNESS -> if (systemDark) PaletteMode.DARK else PaletteMode.LIGHT - } -} - -private fun parseTimeToMinutes(value: String, fallbackHour: Int): Int { - val parts = value.split(":") - if (parts.size != 2) return fallbackHour * 60 - val hour = parts[0].toIntOrNull() ?: return fallbackHour * 60 - val minute = parts[1].toIntOrNull() ?: return fallbackHour * 60 - return (hour.coerceIn(0, 23) * 60) + minute.coerceIn(0, 59) -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/components/ChatListPreview.kt b/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/components/ChatListPreview.kt deleted file mode 100644 index 0af9aa45..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/components/ChatListPreview.kt +++ /dev/null @@ -1,168 +0,0 @@ -package org.monogram.presentation.settings.chatSettings.components - -import androidx.compose.animation.* -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.spring -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.core.ui.ItemPosition - -@Composable -fun ChatListPreview( - messageLines: Int, - videoPlayerPool: VideoPlayerPool, - modifier: Modifier = Modifier, - showPhotos: Boolean = true, - position: ItemPosition = ItemPosition.STANDALONE -) { - val cornerRadius = 24.dp - val shape = remember(position) { - when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - } - - Column(modifier = modifier) { - if (position == ItemPosition.TOP || position == ItemPosition.STANDALONE) { - Text( - text = stringResource(R.string.chat_list_preview_title), - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp, top = 16.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier.fillMaxWidth() - ) { - Column( - modifier = Modifier - .padding(16.dp) - .animateContentSize( - animationSpec = spring( - dampingRatio = Spring.DampingRatioNoBouncy, - stiffness = Spring.StiffnessLow - ) - ) - ) { - PreviewChatItem( - name = stringResource(R.string.preview_name_konata), - message = stringResource(R.string.preview_message_konata), - time = stringResource(R.string.preview_time_konata), - lines = messageLines, - showPhotos = showPhotos, - isKonata = true, - videoPlayerPool = videoPlayerPool - ) - Spacer(modifier = Modifier.height(12.dp)) - PreviewChatItem( - name = stringResource(R.string.preview_name_kagami), - message = stringResource(R.string.preview_message_kagami), - time = stringResource(R.string.preview_time_kagami), - lines = messageLines, - showPhotos = showPhotos, - isKonata = false, - videoPlayerPool = videoPlayerPool - ) - } - } - - if (position != ItemPosition.BOTTOM && position != ItemPosition.STANDALONE) { - Spacer(Modifier.size(2.dp)) - } - } -} - -@Composable -private fun PreviewChatItem( - name: String, - message: String, - time: String, - lines: Int, - showPhotos: Boolean, - isKonata: Boolean, - videoPlayerPool: VideoPlayerPool -) { - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically - ) { - AnimatedVisibility( - visible = showPhotos, - enter = fadeIn() + expandHorizontally(), - exit = fadeOut() + shrinkHorizontally() - ) { - Row { - Avatar( - path = if (isKonata) "local" else null, - name = name, - size = 48.dp, - isLocal = isKonata, - videoPlayerPool = videoPlayerPool - ) - - Spacer(modifier = Modifier.width(12.dp)) - } - } - - Column(modifier = Modifier.weight(1f)) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = name, - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.SemiBold, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Text( - text = time, - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - Text( - text = message, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = lines, - overflow = TextOverflow.Ellipsis - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/components/ChatSettingsPreview.kt b/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/components/ChatSettingsPreview.kt deleted file mode 100644 index 88e1fb8b..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/components/ChatSettingsPreview.kt +++ /dev/null @@ -1,244 +0,0 @@ -package org.monogram.presentation.settings.chatSettings.components - -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.blur -import androidx.compose.ui.draw.clip -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage -import org.monogram.domain.models.* -import org.monogram.presentation.R -import org.monogram.presentation.core.util.IDownloadUtils -import org.monogram.presentation.features.chats.currentChat.components.MessageBubbleContainer -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import java.io.File - -@Composable -fun ChatSettingsPreview( - wallpaper: String?, - availableWallpapers: List, - fontSize: Float, - letterSpacing: Float, - bubbleRadius: Float, - isBlurred: Boolean, - isMoving: Boolean = false, - blurIntensity: Int = 20, - dimming: Int = 0, - isGrayscale: Boolean = false, - modifier: Modifier = Modifier, - downloadUtils: IDownloadUtils, - videoPlayerPool: VideoPlayerPool -) { - Column(modifier = modifier) { - Text( - text = stringResource(R.string.chat_settings_preview_title), - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp, top = 16.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) - - Box( - modifier = Modifier - .fillMaxWidth() - .height(400.dp) - .clip(RoundedCornerShape(16.dp)) - ) { - val selectedWallpaper = remember(wallpaper, availableWallpapers) { - if (wallpaper != null) { - availableWallpapers.find { it.slug == wallpaper || it.localPath == wallpaper } - } else null - } - - if (selectedWallpaper != null) { - WallpaperBackground( - wallpaper = selectedWallpaper, - modifier = Modifier.fillMaxSize(), - isBlurred = isBlurred, - isMoving = isMoving, - blurIntensity = blurIntensity, - dimming = dimming, - isGrayscale = isGrayscale, - isChatSettings = true - ) - } else if (wallpaper != null) { - val file = remember(wallpaper) { File(wallpaper) } - val exists = remember(file) { file.exists() } - if (exists) { - val imageModifier = remember(isBlurred, blurIntensity) { - var m = Modifier.fillMaxSize() - if (isBlurred) { - m = m.blur((blurIntensity / 4f).dp) - } - m - } - AsyncImage( - model = file, - contentDescription = null, - modifier = imageModifier, - contentScale = ContentScale.Crop - ) - } else { - WallpaperBackground(wallpaper = null, modifier = Modifier.fillMaxSize()) - } - } else { - WallpaperBackground(wallpaper = null, modifier = Modifier.fillMaxSize()) - } - - val meName = stringResource(R.string.preview_msg_sender_me) - val konataName = stringResource(R.string.preview_name_konata_short) - val msgText1 = stringResource(R.string.preview_msg_text_1) - val msgText2 = stringResource(R.string.preview_msg_text_2) - val msgText3 = stringResource(R.string.preview_msg_text_3) - val msgText4 = stringResource(R.string.preview_msg_text_4) - - val messages = remember(meName, konataName, msgText1, msgText2, msgText3, msgText4) { - val msg2 = MessageModel( - id = 3, - date = 1678887000, - isOutgoing = true, - senderName = meName, - chatId = 1, - content = MessageContent.Text( - text = msgText2, - entities = listOf( - MessageEntity(83, 4, MessageEntityType.TextUrl("https://youtu.be/dQw4w9WgXcQ")) - ) - ), - isRead = true, - senderId = 1, - reactions = listOf( - MessageReactionModel(emoji = "\uD83D\uDE2D", count = 1, isChosen = false) - ) - ) - - val msg1 = MessageModel( - id = 1, - date = 1678886400, - isOutgoing = false, - senderName = konataName, - senderAvatar = "local", - chatId = 1, - content = MessageContent.Text( - text = msgText1, - entities = listOf( - MessageEntity(0, 13, MessageEntityType.Bold), - MessageEntity(80, 20, MessageEntityType.Italic), - MessageEntity(93, 7, MessageEntityType.Spoiler) - ) - ), - senderId = 2, - reactions = listOf( - MessageReactionModel(emoji = "⭐", count = 1, isChosen = false), - MessageReactionModel(emoji = "🔥", count = 3, isChosen = true) - ) - ) - - val msg3 = MessageModel( - id = 4, - date = 1678887060, - isOutgoing = false, - senderName = konataName, - senderAvatar = "local", - chatId = 1, - content = MessageContent.Text( - text = msgText3 - ), - replyToMsg = msg2, - replyToMsgId = msg2.id, - senderId = 2 - ) - - val msg4 = MessageModel( - id = 5, - date = 1678887120, - isOutgoing = true, - senderName = meName, - chatId = 1, - content = MessageContent.Text( - text = msgText4, - entities = listOf( - MessageEntity(5, 16, MessageEntityType.Bold) - ) - ), - senderId = 1 - ) - listOf(msg1, msg2, msg3, msg4) - } - - val onPhotoClick: (MessageModel) -> Unit = remember { {} } - val onReplyClick: (androidx.compose.ui.geometry.Offset, androidx.compose.ui.unit.IntSize, androidx.compose.ui.geometry.Offset) -> Unit = remember { { _, _, _ -> } } - val toProfile: (Long) -> Unit = remember { {} } - - LazyColumn( - modifier = Modifier.fillMaxSize(), - reverseLayout = false, - contentPadding = PaddingValues(horizontal = 8.dp, vertical = 16.dp), - verticalArrangement = Arrangement.spacedBy(12.dp) - ) { - item(key = "date_separator") { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 8.dp), - contentAlignment = Alignment.Center - ) { - Surface( - shape = CircleShape, - color = MaterialTheme.colorScheme.surface.copy(alpha = 0.6f), - ) { - Text( - text = stringResource(R.string.preview_date_today), - style = MaterialTheme.typography.labelSmall, - modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp), - color = MaterialTheme.colorScheme.onSurface - ) - } - } - } - - itemsIndexed( - items = messages, - key = { _, msg -> msg.id } - ) { index, msg -> - val olderMsg = if (index > 0) messages[index - 1] else null - val newerMsg = if (index < messages.size - 1) messages[index + 1] else null - - MessageBubbleContainer( - msg = msg, - olderMsg = olderMsg, - newerMsg = newerMsg, - isGroup = true, - fontSize = fontSize, - letterSpacing = letterSpacing, - bubbleRadius = bubbleRadius, - autoDownloadMobile = true, - autoDownloadWifi = true, - autoDownloadRoaming = false, - autoDownloadFiles = false, - autoplayGifs = true, - autoplayVideos = true, - onPhotoClick = onPhotoClick, - onReplyClick = onReplyClick, - toProfile = toProfile, - downloadUtils = downloadUtils, - videoPlayerPool = videoPlayerPool - ) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/components/WallpaperBackground.kt b/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/components/WallpaperBackground.kt deleted file mode 100644 index 092c1fe3..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/components/WallpaperBackground.kt +++ /dev/null @@ -1,267 +0,0 @@ -package org.monogram.presentation.settings.chatSettings.components - -import android.content.Context -import android.hardware.Sensor -import android.hardware.SensorEvent -import android.hardware.SensorEventListener -import android.hardware.SensorManager -import android.util.Log -import androidx.compose.animation.core.* -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.blur -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.* -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage -import kotlinx.coroutines.flow.collectLatest -import kotlinx.coroutines.launch -import org.monogram.domain.models.WallpaperModel -import java.io.File - -@Composable -fun WallpaperBackground( - wallpaper: WallpaperModel?, - modifier: Modifier = Modifier, - isBlurred: Boolean = false, - isMoving: Boolean = false, - blurIntensity: Int = 20, - dimming: Int = 0, - isGrayscale: Boolean = false, - isChatSettings: Boolean = false -) { - if (wallpaper == null) { - Box(modifier = modifier.background(MaterialTheme.colorScheme.surface)) - return - } - - val activationSpec = remember { - tween(durationMillis = 1000, easing = FastOutSlowInEasing) - } - - val motionSpringSpec = remember { - spring( - dampingRatio = Spring.DampingRatioNoBouncy, - stiffness = 20f - ) - } - - val fadeSpec = remember { - tween(durationMillis = 600, easing = LinearEasing) - } - - val animatedScale by animateFloatAsState( - targetValue = if (isMoving) 1.1f else 1.0f, - animationSpec = activationSpec, - label = "scale" - ) - - val animatedBlur by animateFloatAsState( - targetValue = if (isBlurred) blurIntensity.toFloat() else 0f, - animationSpec = tween(600), - label = "blur" - ) - - val animatedDimming by animateFloatAsState( - targetValue = dimming / 100f, - animationSpec = fadeSpec, - label = "dimming" - ) - - val animatedSaturation by animateFloatAsState( - targetValue = if (isGrayscale) 0f else 1f, - animationSpec = tween(600), - label = "saturation" - ) - - val offsetX = remember { Animatable(0f) } - val offsetY = remember { Animatable(0f) } - - var targetX by remember { mutableFloatStateOf(0f) } - var targetY by remember { mutableFloatStateOf(0f) } - - val context = LocalContext.current - - DisposableEffect(isMoving) { - if (isMoving) { - val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager - val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE) - - val listener = object : SensorEventListener { - override fun onSensorChanged(event: SensorEvent?) { - event?.let { - val yRotationRate = it.values[0] - val xRotationRate = it.values[1] - targetX = (xRotationRate * 30f).coerceIn(-45f, 45f) - targetY = (yRotationRate * 30f).coerceIn(-45f, 45f) - } - } - override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {} - } - - if (sensor != null) { - sensorManager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_GAME) - } - - onDispose { - if (sensor != null) sensorManager.unregisterListener(listener) - } - } else { - onDispose { } - } - } - - LaunchedEffect(isMoving) { - if (isMoving) { - launch { - snapshotFlow { targetX }.collectLatest { target -> - offsetX.animateTo(target, motionSpringSpec) - } - } - launch { - snapshotFlow { targetY }.collectLatest { target -> - offsetY.animateTo(target, motionSpringSpec) - } - } - } else { - launch { offsetX.animateTo(0f, activationSpec) } - launch { offsetY.animateTo(0f, activationSpec) } - } - } - - Box(modifier = modifier) { - val settings = wallpaper.settings - - val hasColors = remember(settings) { - settings?.let { - it.backgroundColor != null || it.secondBackgroundColor != null || - it.thirdBackgroundColor != null || it.fourthBackgroundColor != null - } ?: false - } - - val isFullImage = remember(wallpaper) { - !wallpaper.pattern && !wallpaper.slug.startsWith("emoji") && (wallpaper.documentId != 0L || wallpaper.slug == "built-in") - } - - val isBackgroundDisabled = remember(isFullImage, hasColors) { - isFullImage && !hasColors - } - - val shouldShowBackground = !isBackgroundDisabled || isChatSettings - - if (shouldShowBackground) { - val colors = remember(settings) { - listOfNotNull( - settings?.backgroundColor?.let { Color(it or 0xFF000000.toInt()) }, - settings?.secondBackgroundColor?.let { Color(it or 0xFF000000.toInt()) }, - settings?.thirdBackgroundColor?.let { Color(it or 0xFF000000.toInt()) }, - settings?.fourthBackgroundColor?.let { Color(it or 0xFF000000.toInt()) } - ) - } - - val bgMod = Modifier.fillMaxSize() - if (colors.isNotEmpty()) { - if (colors.size == 1) { - Box(modifier = bgMod.background(colors[0])) - } else { - val rotation = settings?.rotation ?: 0 - Box( - modifier = bgMod.background( - Brush.linearGradient( - colors = colors, - start = Offset(0f, 0f), - end = when (rotation) { - 45 -> Offset(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY) - 90 -> Offset(Float.POSITIVE_INFINITY, 0f) - 135 -> Offset(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY) - 180 -> Offset(0f, Float.NEGATIVE_INFINITY) - 225 -> Offset(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY) - 270 -> Offset(Float.NEGATIVE_INFINITY, 0f) - 315 -> Offset(Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY) - else -> Offset(0f, Float.POSITIVE_INFINITY) - } - ) - ) - ) - } - } else { - Box(modifier = bgMod.background(MaterialTheme.colorScheme.surface)) - } - } - - val imagePath = if (wallpaper.isDownloaded && !wallpaper.localPath.isNullOrEmpty()) { - wallpaper.localPath - } else { - wallpaper.thumbnail?.localPath - } - - if (imagePath != null && File(imagePath).exists()) { - val file = File(imagePath) - - val colorFilter = remember(animatedSaturation) { - if (animatedSaturation < 0.99f) { - val matrix = ColorMatrix().apply { setToSaturation(animatedSaturation) } - ColorFilter.colorMatrix(matrix) - } else { - null - } - } - - val graphicsModifier = Modifier - .fillMaxSize() - .graphicsLayer { - scaleX = animatedScale - scaleY = animatedScale - translationX = offsetX.value - translationY = offsetY.value - rotationY = (offsetX.value / 60f) - rotationX = -(offsetY.value / 60f) - } - .let { - if (animatedBlur > 0f) it.blur((animatedBlur / 4f).dp) else it - } - - if (wallpaper.pattern) { - val intensity = (settings?.intensity ?: 50) / 100f - AsyncImage( - model = file, - contentDescription = null, - modifier = graphicsModifier.graphicsLayer { alpha = intensity }, - contentScale = ContentScale.Crop, - colorFilter = colorFilter - ) - } else { - AsyncImage( - model = file, - contentDescription = null, - modifier = graphicsModifier, - contentScale = ContentScale.Crop, - colorFilter = colorFilter - ) - } - } else if (wallpaper.slug.startsWith("emoji")) { - // TODO: Implement rendering with gradient and emojis - Log.d("WallpaperBackground", "Emoji wallpaper rendering not implemented for slug: ${wallpaper.slug}") - } else if (!shouldShowBackground) { - Box(modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.surface)) - } - - // Dimming Overlay - if (animatedDimming > 0f) { - Box( - modifier = Modifier - .fillMaxSize() - .graphicsLayer { alpha = animatedDimming } - .background(Color.Black) - ) - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/components/WallpaperItem.kt b/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/components/WallpaperItem.kt deleted file mode 100644 index 871f0c5b..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/chatSettings/components/WallpaperItem.kt +++ /dev/null @@ -1,212 +0,0 @@ -package org.monogram.presentation.settings.chatSettings.components - -import androidx.compose.animation.* -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.tween -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Check -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.scale -import androidx.compose.ui.unit.dp -import org.monogram.domain.models.WallpaperModel - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun WallpaperItem( - wallpaper: WallpaperModel?, - isSelected: Boolean, - isBlurred: Boolean, - blurIntensity: Int, - isMoving: Boolean, - dimming: Int, - isGrayscale: Boolean, - onClick: () -> Unit, - onBlurClick: (Boolean) -> Unit, - onBlurIntensityChange: (Int) -> Unit, - onMotionClick: (Boolean) -> Unit, - onDimmingChange: (Int) -> Unit, - onGrayscaleClick: (Boolean) -> Unit -) { - var showMenu by remember { mutableStateOf(false) } - val menuScale by animateFloatAsState(if (showMenu) 0.95f else 1f, label = "menuScale") - val selectionScale by animateFloatAsState( - targetValue = if (isSelected) 1.05f else 1f, - animationSpec = tween(durationMillis = 300), - label = "selectionScale" - ) - - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier - .padding(vertical = 4.dp) - .scale(menuScale * selectionScale) - .combinedClickable( - onClick = onClick, - onLongClick = { showMenu = true } - ) - ) { - Box( - modifier = Modifier - .size(80.dp, 120.dp) - .clip(RoundedCornerShape(12.dp)) - .then( - if (isSelected) Modifier.background(MaterialTheme.colorScheme.primary.copy(alpha = 0.2f)) else Modifier - ), - contentAlignment = Alignment.Center - ) { - WallpaperBackground( - wallpaper = wallpaper, - modifier = Modifier.fillMaxSize(), - isBlurred = isBlurred, - isMoving = isMoving, - blurIntensity = blurIntensity, - dimming = dimming, - isGrayscale = isGrayscale, - isChatSettings = true - ) - - @Suppress("RemoveRedundantQualifierName") - (this@Column.AnimatedVisibility( - visible = isSelected, - enter = scaleIn() + fadeIn(), - exit = scaleOut() + fadeOut() - ) { - Box( - modifier = Modifier - .size(32.dp) - .background(MaterialTheme.colorScheme.primary, CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.Check, - contentDescription = "Selected", - tint = MaterialTheme.colorScheme.onPrimary, - modifier = Modifier.size(20.dp) - ) - } - }) - - MaterialTheme( - shapes = MaterialTheme.shapes.copy(extraSmall = RoundedCornerShape(16.dp)) - ) { - DropdownMenu( - expanded = showMenu, - onDismissRequest = { showMenu = false }, - containerColor = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(16.dp), - modifier = Modifier.width(220.dp) - ) { - DropdownMenuItem( - text = { - Column { - Text("Blur") - @Suppress("RemoveRedundantQualifierName") - (AnimatedVisibility( - visible = isBlurred, - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically() - ) { - Column { - Spacer(modifier = Modifier.height(4.dp)) - Slider( - value = blurIntensity.toFloat(), - onValueChange = { - onBlurIntensityChange(it.toInt()) - if (it.toInt() == 0) { - onBlurClick(false) - } - }, - valueRange = 0f..100f, - modifier = Modifier.height(24.dp) - ) - } - }) - } - }, - trailingIcon = { - Switch( - checked = isBlurred, - onCheckedChange = null - ) - }, - onClick = { - if (!isBlurred && blurIntensity == 0) { - onBlurIntensityChange(20) - } - onBlurClick(!isBlurred) - } - ) - - DropdownMenuItem( - text = { Text("Motion") }, - trailingIcon = { - Switch( - checked = isMoving, - onCheckedChange = null - ) - }, - onClick = { - onMotionClick(!isMoving) - } - ) - - DropdownMenuItem( - text = { - Column { - Text("Dimming") - @Suppress("RemoveRedundantQualifierName") - (AnimatedVisibility( - visible = dimming > 0, - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically() - ) { - Column { - Spacer(modifier = Modifier.height(4.dp)) - Slider( - value = dimming.toFloat(), - onValueChange = { onDimmingChange(it.toInt()) }, - valueRange = 0f..100f, - modifier = Modifier.height(24.dp) - ) - } - }) - } - }, - trailingIcon = { - Switch( - checked = dimming > 0, - onCheckedChange = { onDimmingChange(if (it) 30 else 0) } - ) - }, - onClick = { - onDimmingChange(if (dimming > 0) 0 else 30) - } - ) - - DropdownMenuItem( - text = { Text("Grayscale") }, - trailingIcon = { - Switch( - checked = isGrayscale, - onCheckedChange = null - ) - }, - onClick = { - onGrayscaleClick(!isGrayscale) - } - ) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/dataStorage/DataStorageComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/dataStorage/DataStorageComponent.kt deleted file mode 100644 index 6e324c82..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/dataStorage/DataStorageComponent.kt +++ /dev/null @@ -1,159 +0,0 @@ -package org.monogram.presentation.settings.dataStorage - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.root.AppComponentContext - -interface DataStorageComponent { - val state: Value - fun onBackClicked() - fun onAutoDownloadMobileChanged(enabled: Boolean) - fun onAutoDownloadWifiChanged(enabled: Boolean) - fun onAutoDownloadRoamingChanged(enabled: Boolean) - fun onAutoDownloadFilesChanged(enabled: Boolean) - fun onAutoDownloadStickersChanged(enabled: Boolean) - fun onAutoDownloadVideoNotesChanged(enabled: Boolean) - fun onAutoplayGifsChanged(enabled: Boolean) - fun onAutoplayVideosChanged(enabled: Boolean) - fun onEnableStreamingChanged(enabled: Boolean) - fun onStorageUsageClicked() - fun onNetworkUsageClicked() - fun onClearDatabaseClicked() - - data class State( - val autoDownloadMobile: Boolean = true, - val autoDownloadWifi: Boolean = true, - val autoDownloadRoaming: Boolean = false, - val autoDownloadFiles: Boolean = false, - val autoDownloadStickers: Boolean = true, - val autoDownloadVideoNotes: Boolean = true, - val autoplayGifs: Boolean = true, - val autoplayVideos: Boolean = true, - val enableStreaming: Boolean = true, - val databaseSize: String = "0 B" - ) -} - -class DefaultDataStorageComponent( - context: AppComponentContext, - private val onBack: () -> Unit, - private val onStorageUsage: () -> Unit, - private val onNetworkUsage: () -> Unit -) : DataStorageComponent, AppComponentContext by context { - - private val appPreferences: AppPreferences = container.preferences.appPreferences - private val chatsRepository = container.repositories.chatsListRepository - private val _state = MutableValue(DataStorageComponent.State()) - override val state: Value = _state - private val scope = componentScope - - init { - appPreferences.autoDownloadMobile.onEach { value -> - _state.update { it.copy(autoDownloadMobile = value) } - }.launchIn(scope) - - appPreferences.autoDownloadWifi.onEach { value -> - _state.update { it.copy(autoDownloadWifi = value) } - }.launchIn(scope) - - appPreferences.autoDownloadRoaming.onEach { value -> - _state.update { it.copy(autoDownloadRoaming = value) } - }.launchIn(scope) - - appPreferences.autoDownloadFiles.onEach { value -> - _state.update { it.copy(autoDownloadFiles = value) } - }.launchIn(scope) - - appPreferences.autoDownloadStickers.onEach { value -> - _state.update { it.copy(autoDownloadStickers = value) } - }.launchIn(scope) - - appPreferences.autoDownloadVideoNotes.onEach { value -> - _state.update { it.copy(autoDownloadVideoNotes = value) } - }.launchIn(scope) - - appPreferences.autoplayGifs.onEach { value -> - _state.update { it.copy(autoplayGifs = value) } - }.launchIn(scope) - - appPreferences.autoplayVideos.onEach { value -> - _state.update { it.copy(autoplayVideos = value) } - }.launchIn(scope) - - appPreferences.enableStreaming.onEach { value -> - _state.update { it.copy(enableStreaming = value) } - }.launchIn(scope) - - updateDatabaseSize() - } - - private fun updateDatabaseSize() { - val size = chatsRepository.getDatabaseSize() - _state.update { it.copy(databaseSize = formatSize(size)) } - } - - private fun formatSize(size: Long): String { - if (size <= 0) return "0 B" - val units = arrayOf("B", "KB", "MB", "GB", "TB") - val digitGroups = (Math.log10(size.toDouble()) / Math.log10(1024.0)).toInt() - return String.format("%.1f %s", size / Math.pow(1024.0, digitGroups.toDouble()), units[digitGroups]) - } - - override fun onBackClicked() { - onBack() - } - - override fun onAutoDownloadMobileChanged(enabled: Boolean) { - appPreferences.setAutoDownloadMobile(enabled) - } - - override fun onAutoDownloadWifiChanged(enabled: Boolean) { - appPreferences.setAutoDownloadWifi(enabled) - } - - override fun onAutoDownloadRoamingChanged(enabled: Boolean) { - appPreferences.setAutoDownloadRoaming(enabled) - } - - override fun onAutoDownloadFilesChanged(enabled: Boolean) { - appPreferences.setAutoDownloadFiles(enabled) - } - - override fun onAutoDownloadStickersChanged(enabled: Boolean) { - appPreferences.setAutoDownloadStickers(enabled) - } - - override fun onAutoDownloadVideoNotesChanged(enabled: Boolean) { - appPreferences.setAutoDownloadVideoNotes(enabled) - } - - override fun onAutoplayGifsChanged(enabled: Boolean) { - appPreferences.setAutoplayGifs(enabled) - } - - override fun onAutoplayVideosChanged(enabled: Boolean) { - appPreferences.setAutoplayVideos(enabled) - } - - override fun onEnableStreamingChanged(enabled: Boolean) { - appPreferences.setEnableStreaming(enabled) - } - - override fun onStorageUsageClicked() { - onStorageUsage() - } - - override fun onNetworkUsageClicked() { - onNetworkUsage() - } - - override fun onClearDatabaseClicked() { - chatsRepository.clearDatabase() - updateDatabaseSize() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/dataStorage/DataStorageContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/dataStorage/DataStorageContent.kt deleted file mode 100644 index 0b8f5887..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/dataStorage/DataStorageContent.kt +++ /dev/null @@ -1,188 +0,0 @@ -package org.monogram.presentation.settings.dataStorage - -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsSwitchTile -import org.monogram.presentation.core.ui.SettingsTile - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun DataStorageContent(component: DataStorageComponent) { - val state by component.state.subscribeAsState() - - val blueColor = Color(0xFF4285F4) - val greenColor = Color(0xFF34A853) - val orangeColor = Color(0xFFF9AB00) - val pinkColor = Color(0xFFFF6D66) - - Scaffold( - modifier = Modifier.semantics { contentDescription = "DataStorageContent" }, - topBar = { - TopAppBar( - title = { - Text( - text = stringResource(R.string.data_storage_title_header), - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background - ) - ) - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - LazyColumn( - modifier = Modifier - .fillMaxSize() - .padding(top = padding.calculateTopPadding()), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, top = 0.dp, bottom = 16.dp), - verticalArrangement = Arrangement.spacedBy(16.dp) - ) { - item { - SectionHeader(stringResource(R.string.disk_network_usage_header)) - SettingsTile( - icon = Icons.Rounded.PieChart, - title = stringResource(R.string.storage_usage_title), - subtitle = stringResource(R.string.storage_usage_subtitle), - iconColor = orangeColor, - position = ItemPosition.TOP, - onClick = component::onStorageUsageClicked - ) - SettingsTile( - icon = Icons.Rounded.DataUsage, - title = stringResource(R.string.network_usage_title), - subtitle = stringResource(R.string.network_usage_subtitle), - iconColor = blueColor, - position = ItemPosition.BOTTOM, - onClick = component::onNetworkUsageClicked - ) - } - - item { - SectionHeader(stringResource(R.string.automatic_media_download_header)) - SettingsSwitchTile( - icon = Icons.Rounded.SignalCellularAlt, - title = stringResource(R.string.when_using_mobile_data_title), - subtitle = if (state.autoDownloadMobile) stringResource(R.string.enabled_label) else stringResource( - R.string.disabled_label - ), - checked = state.autoDownloadMobile, - iconColor = blueColor, - position = ItemPosition.TOP, - onCheckedChange = component::onAutoDownloadMobileChanged - ) - SettingsSwitchTile( - icon = Icons.Rounded.Wifi, - title = stringResource(R.string.when_connected_on_wifi_title), - subtitle = if (state.autoDownloadWifi) stringResource(R.string.enabled_label) else stringResource(R.string.disabled_label), - checked = state.autoDownloadWifi, - iconColor = greenColor, - position = ItemPosition.MIDDLE, - onCheckedChange = component::onAutoDownloadWifiChanged - ) - SettingsSwitchTile( - icon = Icons.Rounded.Public, - title = stringResource(R.string.when_roaming_title), - subtitle = if (state.autoDownloadRoaming) stringResource(R.string.enabled_label) else stringResource( - R.string.disabled_label - ), - checked = state.autoDownloadRoaming, - iconColor = orangeColor, - position = ItemPosition.MIDDLE, - onCheckedChange = component::onAutoDownloadRoamingChanged - ) - SettingsSwitchTile( - icon = Icons.Rounded.FileDownload, - title = stringResource(R.string.auto_download_files_title), - subtitle = stringResource(R.string.auto_download_files_subtitle), - checked = state.autoDownloadFiles, - iconColor = blueColor, - position = ItemPosition.MIDDLE, - onCheckedChange = component::onAutoDownloadFilesChanged - ) - SettingsSwitchTile( - icon = Icons.Rounded.StickyNote2, - title = stringResource(R.string.auto_download_stickers_title), - subtitle = stringResource(R.string.auto_download_stickers_subtitle), - checked = state.autoDownloadStickers, - iconColor = pinkColor, - position = ItemPosition.MIDDLE, - onCheckedChange = component::onAutoDownloadStickersChanged - ) - SettingsSwitchTile( - icon = Icons.Rounded.VideoFile, - title = stringResource(R.string.auto_download_video_notes_title), - subtitle = stringResource(R.string.auto_download_video_notes_subtitle), - checked = state.autoDownloadVideoNotes, - iconColor = blueColor, - position = ItemPosition.BOTTOM, - onCheckedChange = component::onAutoDownloadVideoNotesChanged - ) - } - - item { - SectionHeader(stringResource(R.string.autoplay_media_header)) - SettingsSwitchTile( - icon = Icons.Rounded.Gif, - title = stringResource(R.string.gifs_title), - subtitle = stringResource(R.string.gifs_autoplay_subtitle), - checked = state.autoplayGifs, - iconColor = pinkColor, - position = ItemPosition.TOP, - onCheckedChange = component::onAutoplayGifsChanged - ) - SettingsSwitchTile( - icon = Icons.Rounded.PlayCircle, - title = stringResource(R.string.videos_title), - subtitle = stringResource(R.string.videos_autoplay_subtitle), - checked = state.autoplayVideos, - iconColor = blueColor, - position = ItemPosition.BOTTOM, - onCheckedChange = component::onAutoplayVideosChanged - ) - } - - item { Spacer(modifier = Modifier.height(padding.calculateBottomPadding() - 16.dp)) } - } - } -} - -@Composable -private fun SectionHeader(text: String) { - Text( - text = text, - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp, top = 16.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/debug/DebugComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/debug/DebugComponent.kt deleted file mode 100644 index 85238d0c..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/debug/DebugComponent.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.monogram.presentation.settings.debug - -interface DebugComponent { - fun onBackClicked() - fun onCrashClicked() - fun onShowSponsorSheetClicked() - fun onForceSponsorSyncClicked() - fun onDropDatabasesClicked() - fun onDropCachePrefsClicked() - fun onDropPrefsClicked() - fun onDropDatabaseCacheClicked() -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/settings/debug/DebugContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/debug/DebugContent.kt deleted file mode 100644 index 7384ee7f..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/debug/DebugContent.kt +++ /dev/null @@ -1,175 +0,0 @@ -package org.monogram.presentation.settings.debug - -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsItem - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun DebugContent(component: DebugComponent) { - var isSponsorSheetVisible by remember { mutableStateOf(false) } - - if (isSponsorSheetVisible) { - val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) - ModalBottomSheet( - onDismissRequest = { isSponsorSheetVisible = false }, - sheetState = sheetState, - containerColor = MaterialTheme.colorScheme.surface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 48.dp), - horizontalAlignment = androidx.compose.ui.Alignment.CenterHorizontally - ) { - Icon( - imageVector = Icons.Rounded.Favorite, - contentDescription = null, - modifier = Modifier.size(64.dp), - tint = Color(0xFFFF6D66) - ) - Spacer(modifier = Modifier.height(16.dp)) - Text( - text = stringResource(R.string.support_monogram_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - textAlign = TextAlign.Center - ) - Spacer(modifier = Modifier.height(8.dp)) - Text( - text = stringResource(R.string.sponsor_sheet_description), - style = MaterialTheme.typography.bodyLarge, - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.height(32.dp)) - Button( - onClick = { - component.onShowSponsorSheetClicked() - isSponsorSheetVisible = false - }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.action_support_boosty)) - } - Spacer(modifier = Modifier.height(12.dp)) - TextButton( - onClick = { isSponsorSheetVisible = false }, - modifier = Modifier.fillMaxWidth() - ) { - Text(stringResource(R.string.action_maybe_later)) - } - } - } - } - - Scaffold( - topBar = { - TopAppBar( - title = { Text("Debug", fontWeight = FontWeight.Bold) }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon(Icons.AutoMirrored.Rounded.ArrowBack, contentDescription = "Back") - } - } - ) - } - ) { padding -> - LazyColumn( - modifier = Modifier - .fillMaxSize() - .padding(padding), - contentPadding = PaddingValues(16.dp) - ) { - item { - SettingsItem( - icon = Icons.Rounded.Favorite, - title = stringResource(R.string.debug_sponsor_sheet_title), - subtitle = stringResource(R.string.debug_sponsor_sheet_subtitle), - iconBackgroundColor = Color(0xFFFF6D66), - position = ItemPosition.TOP, - onClick = { isSponsorSheetVisible = true } - ) - } - item { - SettingsItem( - icon = Icons.Rounded.Sync, - title = stringResource(R.string.debug_force_sponsor_sync_title), - subtitle = stringResource(R.string.debug_force_sponsor_sync_subtitle), - iconBackgroundColor = Color(0xFF00ACC1), - position = ItemPosition.MIDDLE, - onClick = component::onForceSponsorSyncClicked - ) - } - item { - SettingsItem( - icon = Icons.Rounded.BugReport, - title = "Crash App", - subtitle = "Trigger a manual RuntimeException", - iconBackgroundColor = Color.Red, - position = ItemPosition.MIDDLE, - onClick = component::onCrashClicked - ) - } - item { - SettingsItem( - icon = Icons.Rounded.Storage, - title = "Drop Databases", - subtitle = "Delete all app databases and tdlib", - iconBackgroundColor = Color.Red, - position = ItemPosition.MIDDLE, - onClick = component::onDropDatabasesClicked - ) - } - item { - SettingsItem( - icon = Icons.Rounded.Storage, - title = "Drop Cache Database", - subtitle = "Delete cache database", - iconBackgroundColor = Color.Red, - position = ItemPosition.MIDDLE, - onClick = component::onDropDatabaseCacheClicked - ) - } - item { - SettingsItem( - icon = Icons.Rounded.DeleteSweep, - title = "Drop Cache", - subtitle = "Delete all cache", - iconBackgroundColor = Color.Red, - position = ItemPosition.MIDDLE, - onClick = component::onDropCachePrefsClicked - ) - } - item { - SettingsItem( - icon = Icons.Rounded.Delete, - title = "Drop Prefs", - subtitle = "Delete all preferences", - iconBackgroundColor = Color.Red, - position = ItemPosition.BOTTOM, - onClick = component::onDropPrefsClicked - ) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/debug/DefaultDebugComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/debug/DefaultDebugComponent.kt deleted file mode 100644 index 70d1fdf1..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/debug/DefaultDebugComponent.kt +++ /dev/null @@ -1,57 +0,0 @@ -package org.monogram.presentation.settings.debug - -import org.monogram.presentation.root.AppComponentContext -import java.io.File - -class DefaultDebugComponent( - private val context: AppComponentContext, - private val onBack: () -> Unit -) : DebugComponent, AppComponentContext by context { - - private val messageDisplayer = container.utils.messageDisplayer() - private val assetsManager = container.utils.assetsManager() - private val externalNavigator = container.utils.externalNavigator() - private val userRepository = container.repositories.userRepository - - override fun onBackClicked() { - onBack() - } - - override fun onCrashClicked() { - throw RuntimeException("Test crash") - } - - override fun onShowSponsorSheetClicked() { - externalNavigator.openUrl("https://boosty.to/monogram") - } - - override fun onForceSponsorSyncClicked() { - userRepository.forceSponsorSync() - messageDisplayer.show("Sponsor sync started") - } - - override fun onDropDatabasesClicked() { - messageDisplayer.show("Dropping databases and restarting...") - assetsManager.getDatabasePath("monogram_db").delete() - File(assetsManager.getFilesDir(), "td-db").deleteRecursively() - assetsManager.exitProcess(0) - } - - override fun onDropDatabaseCacheClicked() { - messageDisplayer.show("Dropping databases and restarting...") - assetsManager.getDatabasePath("monogram_db").delete() - assetsManager.exitProcess(0) - } - - override fun onDropCachePrefsClicked() { - messageDisplayer.show("Dropping cache prefs and restarting...") - assetsManager.clearSharedPreferences("monogram_cache") - assetsManager.exitProcess(0) - } - - override fun onDropPrefsClicked() { - messageDisplayer.show("Dropping prefs and restarting...") - assetsManager.clearSharedPreferences("monogram_prefs") - assetsManager.exitProcess(0) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/folders/FolderDialog.kt b/presentation/src/main/java/org/monogram/presentation/settings/folders/FolderDialog.kt deleted file mode 100644 index 60bc3960..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/folders/FolderDialog.kt +++ /dev/null @@ -1,248 +0,0 @@ -package org.monogram.presentation.settings.folders - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.lazy.grid.items -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.ChatModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.features.chats.chatList.components.SectionHeader -import org.monogram.presentation.features.chats.chatList.components.SettingsTextField -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun FolderDialog( - title: String, - initialText: String, - initialIcon: String? = null, - initialSelectedChatIds: List = emptyList(), - availableChats: List = emptyList(), - confirmButtonText: String, - videoPlayerPool: VideoPlayerPool, - isEditMode: Boolean = false, - onDismiss: () -> Unit, - onConfirm: (String, String?, List) -> Unit, - onDelete: (() -> Unit)? = null, - onSearchChats: (String) -> Unit = {} -) { - var text by remember { mutableStateOf(initialText) } - var selectedIcon by remember { mutableStateOf(initialIcon) } - var selectedChatIds by remember { mutableStateOf(initialSelectedChatIds.toSet()) } - var searchQuery by remember { mutableStateOf("") } - - val icons = listOf( - "All", "Unread", "Unmuted", "Bots", "Channels", "Groups", "Private", "Custom", - "Setup", "Cat", "Crown", "Favorite", "Flower", "Game", "Home", "Love", - "Mask", "Party", "Sport", "Study", "Trade", "Travel", "Work", "Airplane", - "Book", "Light", "Like", "Money", "Note", "Palette" - ) - - ModalBottomSheet( - onDismissRequest = onDismiss, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp), - sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 32.dp) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 4.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = title, - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - if (isEditMode && onDelete != null) { - IconButton(onClick = onDelete) { - Icon( - Icons.Rounded.Delete, - contentDescription = stringResource(R.string.folders_delete), - tint = MaterialTheme.colorScheme.error - ) - } - } - } - - Spacer(modifier = Modifier.height(16.dp)) - - SettingsTextField( - value = text, - onValueChange = { text = it }, - placeholder = stringResource(R.string.folders_name_placeholder), - icon = getFolderIcon(selectedIcon) ?: Icons.Rounded.Folder, - position = ItemPosition.STANDALONE, - singleLine = true - ) - - SectionHeader(stringResource(R.string.folders_choose_icon)) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - LazyVerticalGrid( - columns = GridCells.Adaptive(48.dp), - modifier = Modifier - .height(140.dp) - .padding(8.dp), - contentPadding = PaddingValues(4.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - items(icons) { iconName -> - val icon = getFolderIcon(iconName) - if (icon != null) { - Box( - modifier = Modifier - .size(48.dp) - .clip(CircleShape) - .background( - if (selectedIcon == iconName) MaterialTheme.colorScheme.primary.copy(alpha = 0.2f) - else Color.Transparent - ) - .clickable { selectedIcon = iconName } - .padding(8.dp), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = icon, - contentDescription = iconName, - tint = if (selectedIcon == iconName) MaterialTheme.colorScheme.primary - else MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } - } - } - - SectionHeader(stringResource(R.string.folders_included_chats)) - - SettingsTextField( - value = searchQuery, - onValueChange = { - searchQuery = it - onSearchChats(it) - }, - placeholder = stringResource(R.string.folders_search_chats), - icon = Icons.Rounded.Search, - position = ItemPosition.TOP, - singleLine = true - ) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(bottomStart = 24.dp, bottomEnd = 24.dp, topStart = 4.dp, topEnd = 4.dp), - modifier = Modifier.fillMaxWidth() - ) { - LazyColumn( - modifier = Modifier - .height(200.dp) - .padding(vertical = 4.dp), - verticalArrangement = Arrangement.spacedBy(2.dp) - ) { - items(availableChats) { chat -> - val isSelected = selectedChatIds.contains(chat.id) - Row( - modifier = Modifier - .fillMaxWidth() - .clickable { - selectedChatIds = if (isSelected) { - selectedChatIds - chat.id - } else { - selectedChatIds + chat.id - } - } - .padding(horizontal = 12.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Avatar( - path = chat.avatarPath, - fallbackPath = chat.personalAvatarPath, - name = chat.title, - size = 36.dp, - videoPlayerPool = videoPlayerPool - ) - Spacer(Modifier.width(12.dp)) - Text( - text = chat.title, - modifier = Modifier.weight(1f), - style = MaterialTheme.typography.bodyLarge, - fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Normal - ) - Icon( - imageVector = if (isSelected) Icons.Rounded.CheckCircle else Icons.Rounded.RadioButtonUnchecked, - contentDescription = null, - tint = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant.copy( - alpha = 0.5f - ) - ) - } - } - } - } - - Spacer(modifier = Modifier.height(24.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - OutlinedButton( - onClick = onDismiss, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.folders_cancel), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - - Button( - onClick = { if (text.isNotBlank()) onConfirm(text, selectedIcon, selectedChatIds.toList()) }, - enabled = text.isNotBlank(), - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(confirmButtonText, fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/folders/FolderItem.kt b/presentation/src/main/java/org/monogram/presentation/settings/folders/FolderItem.kt deleted file mode 100644 index e50d3452..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/folders/FolderItem.kt +++ /dev/null @@ -1,163 +0,0 @@ -package org.monogram.presentation.settings.folders - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.FolderModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ItemPosition - -@Composable -fun FolderItem( - folder: FolderModel, - isSystem: Boolean, - position: ItemPosition, - onClick: () -> Unit, - onMoveUp: (() -> Unit)? = null, - onMoveDown: (() -> Unit)? = null, - modifier: Modifier = Modifier -) { - val icon = if (isSystem) Icons.Rounded.AllInbox else getFolderIcon(folder.iconName) ?: Icons.Rounded.Folder - val iconColor = if (isSystem) Color(0xFF4285F4) else Color(0xFFF9AB00) - - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = modifier - .fillMaxWidth() - .clip(shape) - .clickable(onClick = onClick) - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(40.dp) - .background(color = iconColor.copy(0.15f), shape = CircleShape), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = icon, - contentDescription = null, - modifier = Modifier.size(24.dp), - tint = iconColor - ) - } - Spacer(modifier = Modifier.width(16.dp)) - Column(modifier = Modifier.weight(1f)) { - Text( - text = if (isSystem) { - stringResource(R.string.folders_system_all_chats) - } else { - folder.title - }, - style = MaterialTheme.typography.titleMedium, - fontSize = 18.sp - ) - Text( - text = if (isSystem) { - stringResource(R.string.folders_system_all_chats) - } else { - stringResource(R.string.folders_user_chats_count, folder.includedChatIds.size) - }, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - if (!isSystem) { - Row(verticalAlignment = Alignment.CenterVertically) { - if (onMoveUp != null) { - IconButton(onClick = onMoveUp) { - Icon( - imageVector = Icons.Rounded.KeyboardArrowUp, - contentDescription = stringResource(R.string.folders_move_up), - tint = MaterialTheme.colorScheme.primary - ) - } - } - if (onMoveDown != null) { - IconButton(onClick = onMoveDown) { - Icon( - imageVector = Icons.Rounded.KeyboardArrowDown, - contentDescription = stringResource(R.string.folders_move_down), - tint = MaterialTheme.colorScheme.primary - ) - } - } - } - } - } - } -} - -fun getFolderIcon(iconName: String?): ImageVector? { - return when (iconName) { - "All" -> Icons.Rounded.AllInbox - "Unread" -> Icons.Rounded.MarkChatUnread - "Unmuted" -> Icons.Rounded.NotificationsActive - "Bots" -> Icons.Rounded.SmartToy - "Channels" -> Icons.Rounded.Campaign - "Groups" -> Icons.Rounded.Groups - "Private" -> Icons.Rounded.Person - "Custom" -> Icons.Rounded.Folder - "Setup" -> Icons.Rounded.Settings - "Cat" -> Icons.Rounded.Pets - "Crown" -> Icons.Rounded.EmojiEvents - "Favorite" -> Icons.Rounded.Star - "Flower" -> Icons.Rounded.LocalFlorist - "Game" -> Icons.Rounded.Gamepad - "Home" -> Icons.Rounded.Home - "Love" -> Icons.Rounded.Favorite - "Mask" -> Icons.Rounded.TheaterComedy - "Party" -> Icons.Rounded.Celebration - "Sport" -> Icons.Rounded.SportsBasketball - "Study" -> Icons.Rounded.School - "Trade" -> Icons.Rounded.TrendingUp - "Travel" -> Icons.Rounded.Flight - "Work" -> Icons.Rounded.Work - "Airplane" -> Icons.Rounded.AirplanemodeActive - "Book" -> Icons.Rounded.Book - "Light" -> Icons.Rounded.Lightbulb - "Like" -> Icons.Rounded.ThumbUp - "Money" -> Icons.Rounded.Payments - "Note" -> Icons.Rounded.Description - "Palette" -> Icons.Rounded.Palette - else -> null - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/settings/folders/FoldersComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/folders/FoldersComponent.kt deleted file mode 100644 index 13d0f5ae..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/folders/FoldersComponent.kt +++ /dev/null @@ -1,134 +0,0 @@ -package org.monogram.presentation.settings.folders - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch -import org.monogram.domain.models.ChatModel -import org.monogram.domain.models.FolderModel -import org.monogram.domain.repository.ChatsListRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.root.AppComponentContext - -interface FoldersComponent { - val state: Value - val videoPlayerPool: VideoPlayerPool - fun onBackClicked() - fun onCreateFolderClicked() - fun onFolderClicked(folderId: Int) - fun onDeleteFolder(folderId: Int) - fun onEditFolder(folderId: Int, newTitle: String, iconName: String?, includedChatIds: List) - fun onAddFolder(title: String, iconName: String?, includedChatIds: List) - fun onMoveFolder(fromIndex: Int, toIndex: Int) - fun onSearchChats(query: String) - - data class State( - val folders: List = emptyList(), - val isLoading: Boolean = false, - val showAddFolderDialog: Boolean = false, - val showEditFolderDialog: Boolean = false, - val selectedFolder: FolderModel? = null, - val availableChats: List = emptyList(), - val selectedChatIds: List = emptyList() - ) -} - -class DefaultFoldersComponent( - context: AppComponentContext, - private val onBack: () -> Unit -) : FoldersComponent, AppComponentContext by context { - - private val repository: ChatsListRepository = container.repositories.chatsListRepository - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - - private val _state = MutableValue(FoldersComponent.State()) - override val state: Value = _state - - private val scope = componentScope - - init { - repository.foldersFlow.onEach { folders -> - _state.update { it.copy(folders = folders) } - }.launchIn(scope) - - repository.chatListFlow.onEach { chats -> - _state.update { it.copy(availableChats = chats) } - }.launchIn(scope) - } - - override fun onBackClicked() { - onBack() - } - - override fun onCreateFolderClicked() { - _state.update { it.copy(showAddFolderDialog = true, selectedChatIds = emptyList()) } - } - - override fun onFolderClicked(folderId: Int) { - val folder = _state.value.folders.find { it.id == folderId } - if (folder != null) { - _state.update { - it.copy( - showEditFolderDialog = true, - selectedFolder = folder, - selectedChatIds = folder.includedChatIds - ) - } - } - } - - override fun onDeleteFolder(folderId: Int) { - scope.launch { - repository.deleteFolder(folderId) - _state.update { it.copy(showEditFolderDialog = false, selectedFolder = null) } - } - } - - override fun onEditFolder(folderId: Int, newTitle: String, iconName: String?, includedChatIds: List) { - scope.launch { - repository.updateFolder(folderId, newTitle, iconName, includedChatIds) - _state.update { it.copy(showEditFolderDialog = false, selectedFolder = null) } - } - } - - override fun onAddFolder(title: String, iconName: String?, includedChatIds: List) { - scope.launch { - repository.createFolder(title, iconName, includedChatIds) - _state.update { it.copy(showAddFolderDialog = false) } - } - } - - override fun onMoveFolder(fromIndex: Int, toIndex: Int) { - val folders = _state.value.folders.toMutableList() - if (fromIndex !in folders.indices || toIndex !in folders.indices) return - - val folder = folders.removeAt(fromIndex) - folders.add(toIndex, folder) - - _state.update { it.copy(folders = folders) } - - scope.launch { - val newUserFolderIds = folders - .filter { it.id >= 0 } - .map { it.id } - - repository.reorderFolders(newUserFolderIds) - } - } - - override fun onSearchChats(query: String) { - scope.launch { - val results = repository.searchChats(query) - _state.update { it.copy(availableChats = results) } - } - } - - fun dismissDialog() { - _state.update { - it.copy(showAddFolderDialog = false, showEditFolderDialog = false, selectedFolder = null) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/folders/FoldersContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/folders/FoldersContent.kt deleted file mode 100644 index ac2c096e..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/folders/FoldersContent.kt +++ /dev/null @@ -1,350 +0,0 @@ -package org.monogram.presentation.settings.folders - -import androidx.compose.animation.animateColorAsState -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.Add -import androidx.compose.material.icons.rounded.Delete -import androidx.compose.material.icons.rounded.FolderSpecial -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.domain.models.FolderModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ItemPosition - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun FoldersContent(component: FoldersComponent) { - val state by component.state.subscribeAsState() - val defaultComponent = component as? DefaultFoldersComponent - - Scaffold( - modifier = Modifier - .fillMaxSize() - .semantics { contentDescription = "FoldersContent" }, - topBar = { - TopAppBar( - title = { - Text( - text = stringResource(R.string.folders_title), - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.folders_back) - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background - ) - ) - }, - floatingActionButton = { - ExtendedFloatingActionButton( - onClick = component::onCreateFolderClicked, - icon = { Icon(Icons.Rounded.Add, contentDescription = null) }, - text = { Text(stringResource(R.string.folders_new_folder)) }, - containerColor = MaterialTheme.colorScheme.primary, - contentColor = MaterialTheme.colorScheme.onPrimary, - expanded = true - ) - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - val systemFolders = remember(state.folders) { state.folders.filter { it.id < 0 } } - val userFolders = remember(state.folders) { state.folders.filter { it.id >= 0 } } - - Box( - modifier = Modifier - .fillMaxSize() - .padding(top = padding.calculateTopPadding()) - ) { - if (state.isLoading) { - CircularProgressIndicator(modifier = Modifier.align(Alignment.Center)) - } else { - FolderList( - systemFolders = systemFolders, - userFolders = userFolders, - onFolderClick = component::onFolderClicked, - onDeleteClick = component::onDeleteFolder, - onReorder = { fromIndex, toIndex -> - val fromFolder = userFolders.getOrNull(fromIndex) - val toFolder = userFolders.getOrNull(toIndex) - if (fromFolder != null && toFolder != null) { - val globalFrom = state.folders.indexOfFirst { it.id == fromFolder.id } - val globalTo = state.folders.indexOfFirst { it.id == toFolder.id } - - if (globalFrom != -1 && globalTo != -1) { - component.onMoveFolder(globalFrom, globalTo) - } - } - } - ) - } - } - } - - if (state.showAddFolderDialog) { - FolderDialog( - title = stringResource(R.string.folders_new_folder), - initialText = "", - availableChats = state.availableChats, - confirmButtonText = stringResource(R.string.folders_create), - onDismiss = { defaultComponent?.dismissDialog() }, - onConfirm = component::onAddFolder, - onSearchChats = component::onSearchChats, - videoPlayerPool = component.videoPlayerPool - ) - } - - if (state.showEditFolderDialog && state.selectedFolder != null) { - FolderDialog( - title = stringResource(R.string.folders_edit_folder), - initialText = state.selectedFolder!!.title, - initialIcon = state.selectedFolder!!.iconName, - initialSelectedChatIds = state.selectedChatIds, - availableChats = state.availableChats, - confirmButtonText = stringResource(R.string.folders_save), - isEditMode = true, - onDismiss = { defaultComponent?.dismissDialog() }, - onConfirm = { title, icon, chatIds -> - component.onEditFolder( - state.selectedFolder!!.id, - title, - icon, - chatIds - ) - }, - onDelete = { component.onDeleteFolder(state.selectedFolder!!.id) }, - onSearchChats = component::onSearchChats, - videoPlayerPool = component.videoPlayerPool - ) - } -} - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun FolderList( - systemFolders: List, - userFolders: List, - onFolderClick: (Int) -> Unit, - onDeleteClick: (Int) -> Unit, - onReorder: (Int, Int) -> Unit -) { - val listState = rememberLazyListState() - - LazyColumn( - state = listState, - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, top = 0.dp, bottom = 16.dp), - modifier = Modifier.fillMaxSize(), - verticalArrangement = Arrangement.spacedBy(2.dp) - ) { - item { - FolderHeaderDescription() - Spacer(Modifier.height(14.dp)) - } - - if (systemFolders.isNotEmpty()) { - item { - SectionHeader(stringResource(R.string.folders_default_section)) - } - itemsIndexed(systemFolders, key = { _, folder -> "sys_${folder.id}" }) { index, folder -> - val position = when { - systemFolders.size == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == systemFolders.size - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - FolderItem( - folder = folder, - isSystem = true, - position = position, - onClick = { } - ) - } - item { Spacer(Modifier.height(14.dp)) } - } - - if (userFolders.isNotEmpty()) { - item { - SectionHeader(stringResource(R.string.folders_custom_section)) - } - itemsIndexed(userFolders, key = { index, folder -> "user_${folder.id}_$index" }) { index, folder -> - val position = when { - userFolders.size == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == userFolders.size - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - - SwipeToDeleteContainer( - onDelete = { onDeleteClick(folder.id) } - ) { - FolderItem( - folder = folder, - isSystem = false, - position = position, - onClick = { onFolderClick(folder.id) }, - onMoveUp = if (index > 0) { - { onReorder(index, index - 1) } - } else null, - onMoveDown = if (index < userFolders.size - 1) { - { onReorder(index, index + 1) } - } else null - ) - } - } - } - - if (userFolders.isEmpty() && systemFolders.isEmpty()) { - item { EmptyFoldersState() } - } - - item { Spacer(Modifier.height(80.dp)) } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun SwipeToDeleteContainer( - onDelete: () -> Unit, - enabled: Boolean = true, - content: @Composable () -> Unit -) { - if (!enabled) { - content() - return - } - - val dismissState = rememberSwipeToDismissBoxState( - confirmValueChange = { - if (it == SwipeToDismissBoxValue.EndToStart) { - onDelete() - true - } else false - } - ) - - SwipeToDismissBox( - state = dismissState, - enableDismissFromStartToEnd = false, - backgroundContent = { - val color by animateColorAsState( - (if (dismissState.targetValue == SwipeToDismissBoxValue.EndToStart) - MaterialTheme.colorScheme.errorContainer - else Color.Transparent), - label = "color" - ) - Box( - Modifier - .fillMaxSize() - .background(color) - .padding(horizontal = 20.dp), - contentAlignment = Alignment.CenterEnd - ) { - if (dismissState.targetValue == SwipeToDismissBoxValue.EndToStart) { - Icon( - Icons.Rounded.Delete, - contentDescription = stringResource(R.string.folders_delete), - tint = MaterialTheme.colorScheme.onErrorContainer - ) - } - } - }, - content = { content() } - ) -} - -@Composable -fun FolderHeaderDescription() { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 8.dp, horizontal = 24.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Box( - modifier = Modifier - .size(72.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primary.copy(alpha = 0.1f)), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.FolderSpecial, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.size(40.dp) - ) - } - Spacer(modifier = Modifier.height(16.dp)) - Text( - text = stringResource(R.string.folders_header_description), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center, - lineHeight = 20.sp - ) - } -} - -@Composable -fun EmptyFoldersState() { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(top = 48.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Text( - text = stringResource(R.string.folders_empty_title), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.onSurface - ) - Spacer(modifier = Modifier.height(4.dp)) - Text( - text = stringResource(R.string.folders_empty_subtitle), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } -} - -@Composable -private fun SectionHeader(text: String) { - Text( - text = text, - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp, top = 16.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/folders/FoldersStore.kt b/presentation/src/main/java/org/monogram/presentation/settings/folders/FoldersStore.kt deleted file mode 100644 index df4463f9..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/folders/FoldersStore.kt +++ /dev/null @@ -1,28 +0,0 @@ -package org.monogram.presentation.settings.folders - -import com.arkivanov.mvikotlin.core.store.Store - -interface FoldersStore : Store { - - sealed class Intent { - object BackClicked : Intent() - object CreateFolderClicked : Intent() - data class FolderClicked(val folderId: Int) : Intent() - data class DeleteFolder(val folderId: Int) : Intent() - data class EditFolder( - val folderId: Int, - val newTitle: String, - val iconName: String?, - val includedChatIds: List - ) : Intent() - - data class AddFolder(val title: String, val iconName: String?, val includedChatIds: List) : Intent() - data class MoveFolder(val fromIndex: Int, val toIndex: Int) : Intent() - data class SearchChats(val query: String) : Intent() - data class UpdateState(val state: FoldersComponent.State) : Intent() - } - - sealed class Label { - object Back : Label() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/folders/FoldersStoreFactory.kt b/presentation/src/main/java/org/monogram/presentation/settings/folders/FoldersStoreFactory.kt deleted file mode 100644 index 54efef11..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/folders/FoldersStoreFactory.kt +++ /dev/null @@ -1,55 +0,0 @@ -package org.monogram.presentation.settings.folders - -import com.arkivanov.mvikotlin.core.store.Reducer -import com.arkivanov.mvikotlin.core.store.Store -import com.arkivanov.mvikotlin.core.store.StoreFactory -import com.arkivanov.mvikotlin.extensions.coroutines.CoroutineExecutor -import org.monogram.presentation.settings.folders.FoldersStore.Intent -import org.monogram.presentation.settings.folders.FoldersStore.Label - -class FoldersStoreFactory( - private val storeFactory: StoreFactory, - private val component: DefaultFoldersComponent -) { - - fun create(): FoldersStore = - object : FoldersStore, Store by storeFactory.create( - name = "FoldersStore", - initialState = component.state.value, - executorFactory = ::ExecutorImpl, - reducer = ReducerImpl - ) {} - - private inner class ExecutorImpl : CoroutineExecutor() { - override fun executeIntent(intent: Intent) { - when (intent) { - Intent.BackClicked -> component.onBackClicked() - Intent.CreateFolderClicked -> component.onCreateFolderClicked() - is Intent.FolderClicked -> component.onFolderClicked(intent.folderId) - is Intent.DeleteFolder -> component.onDeleteFolder(intent.folderId) - is Intent.EditFolder -> component.onEditFolder( - intent.folderId, - intent.newTitle, - intent.iconName, - intent.includedChatIds - ) - - is Intent.AddFolder -> component.onAddFolder(intent.title, intent.iconName, intent.includedChatIds) - is Intent.MoveFolder -> component.onMoveFolder(intent.fromIndex, intent.toIndex) - is Intent.SearchChats -> component.onSearchChats(intent.query) - is Intent.UpdateState -> dispatch(Message.UpdateState(intent.state)) - } - } - } - - private object ReducerImpl : Reducer { - override fun FoldersComponent.State.reduce(msg: Message): FoldersComponent.State = - when (msg) { - is Message.UpdateState -> msg.state - } - } - - sealed class Message { - data class UpdateState(val state: FoldersComponent.State) : Message() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/networkUsage/NetworkUsageComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/networkUsage/NetworkUsageComponent.kt deleted file mode 100644 index 4d1dc720..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/networkUsage/NetworkUsageComponent.kt +++ /dev/null @@ -1,75 +0,0 @@ -package org.monogram.presentation.settings.networkUsage - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.launch -import org.monogram.domain.models.NetworkUsageModel -import org.monogram.domain.repository.SettingsRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.root.AppComponentContext - -interface NetworkUsageComponent { - val state: Value - fun onBackClicked() - fun onResetClicked() - fun onToggleNetworkStats(enabled: Boolean) - - data class State( - val usage: NetworkUsageModel? = null, - val isLoading: Boolean = true, - val isNetworkStatsEnabled: Boolean = true - ) -} - -class DefaultNetworkUsageComponent( - context: AppComponentContext, - private val onBack: () -> Unit -) : NetworkUsageComponent, AppComponentContext by context { - - private val settingsRepository: SettingsRepository = container.repositories.settingsRepository - private val _state = MutableValue(NetworkUsageComponent.State()) - override val state: Value = _state - private val scope = componentScope - - init { - loadStatistics() - } - - private fun loadStatistics() { - _state.update { it.copy(isLoading = true) } - scope.launch { - val isEnabled = settingsRepository.getNetworkStatisticsEnabled() - val usage = if (isEnabled) settingsRepository.getNetworkUsage() else null - _state.update { it.copy(usage = usage, isLoading = false, isNetworkStatsEnabled = isEnabled) } - } - } - - override fun onBackClicked() { - onBack() - } - - override fun onResetClicked() { - scope.launch { - val success = settingsRepository.resetNetworkStatistics() - if (success) { - loadStatistics() - } - } - } - - override fun onToggleNetworkStats(enabled: Boolean) { - scope.launch { - settingsRepository.setNetworkStatisticsEnabled(enabled) - if (!enabled) { - settingsRepository.resetNetworkStatistics() - } - _state.update { it.copy(isNetworkStatsEnabled = enabled) } - if (enabled) { - loadStatistics() - } else { - _state.update { it.copy(usage = null) } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/networkUsage/NetworkUsageContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/networkUsage/NetworkUsageContent.kt deleted file mode 100644 index 5aea294f..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/networkUsage/NetworkUsageContent.kt +++ /dev/null @@ -1,563 +0,0 @@ -package org.monogram.presentation.settings.networkUsage - -import androidx.compose.animation.AnimatedContent -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.spring -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.togetherWith -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.selection.selectable -import androidx.compose.foundation.selection.selectableGroup -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.Role -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.domain.models.NetworkTypeUsage -import org.monogram.domain.models.NetworkUsageCategory -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ItemPosition -import java.util.* - -private enum class NetworkTab(val titleRes: Int, val icon: ImageVector) { - Mobile(R.string.mobile_tab, Icons.Rounded.SignalCellularAlt), - Wifi(R.string.wifi_tab, Icons.Rounded.Wifi), - Roaming(R.string.roaming_tab, Icons.Rounded.Public), - Other(R.string.other_tab, Icons.Rounded.DevicesOther) -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun NetworkUsageContent(component: NetworkUsageComponent) { - val state by component.state.subscribeAsState() - - val blueColor = Color(0xFF4285F4) - val greenColor = Color(0xFF34A853) - val orangeColor = Color(0xFFF9AB00) - val purpleColor = Color(0xFF9C27B0) - - var selectedTab by remember { mutableStateOf(NetworkTab.Mobile) } - - Scaffold( - topBar = { - TopAppBar( - title = { - Text( - text = stringResource(R.string.network_usage_header), - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - }, - actions = { - if (state.isNetworkStatsEnabled) { - IconButton(onClick = component::onResetClicked) { - Icon( - Icons.Rounded.Refresh, - contentDescription = stringResource(R.string.reset_statistics_cd) - ) - } - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background - ) - ) - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - if (state.isLoading) { - Box( - modifier = Modifier - .fillMaxSize() - .padding(padding), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator() - } - } else { - Column( - modifier = Modifier - .padding(padding) - .fillMaxSize() - ) { - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier - .padding(horizontal = 16.dp, vertical = 8.dp) - .fillMaxWidth() - ) { - Row( - modifier = Modifier - .padding(16.dp) - .fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically - ) { - Column(modifier = Modifier.weight(1f)) { - Text( - text = stringResource(R.string.network_statistics_title), - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.Bold - ) - Text( - text = stringResource(R.string.network_statistics_description), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - Spacer(modifier = Modifier.width(16.dp)) - Switch( - checked = state.isNetworkStatsEnabled, - onCheckedChange = { component.onToggleNetworkStats(it) } - ) - } - } - - if (!state.isNetworkStatsEnabled) { - DisabledStateView() - } else { - val usage = state.usage - if (usage != null) { - Row( - Modifier - .padding(horizontal = 16.dp, vertical = 8.dp) - .selectableGroup() - .fillMaxWidth() - .background( - MaterialTheme.colorScheme.surfaceContainer, - RoundedCornerShape(24.dp) - ) - .padding(4.dp), - horizontalArrangement = Arrangement.SpaceBetween - ) { - NetworkTab.entries.forEach { tab -> - val selected = (selectedTab == tab) - Box( - Modifier - .weight(1f) - .height(40.dp) - .clip(RoundedCornerShape(20.dp)) - .background(if (selected) MaterialTheme.colorScheme.primary else Color.Transparent) - .selectable( - selected = selected, - onClick = { selectedTab = tab }, - role = Role.Tab - ), - contentAlignment = Alignment.Center - ) { - Row(verticalAlignment = Alignment.CenterVertically) { - Icon( - tab.icon, - contentDescription = null, - modifier = Modifier.size(18.dp), - tint = if (selected) MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(Modifier.width(8.dp)) - Text( - text = stringResource(tab.titleRes), - style = MaterialTheme.typography.labelLarge, - color = if (selected) MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurfaceVariant, - fontWeight = if (selected) FontWeight.Bold else FontWeight.Normal - ) - } - } - } - } - - AnimatedContent( - targetState = selectedTab, - transitionSpec = { - fadeIn(animationSpec = spring(stiffness = Spring.StiffnessMediumLow)) togetherWith - fadeOut(animationSpec = spring(stiffness = Spring.StiffnessMediumLow)) - }, - label = "TabContent", - modifier = Modifier.weight(1f) - ) { tab -> - val data = when (tab) { - NetworkTab.Mobile -> usage.mobile - NetworkTab.Wifi -> usage.wifi - NetworkTab.Roaming -> usage.roaming - NetworkTab.Other -> usage.other - } - - NetworkTabBody( - usage = data, - primaryColor = when (tab) { - NetworkTab.Mobile -> greenColor - NetworkTab.Wifi -> blueColor - NetworkTab.Roaming -> orangeColor - NetworkTab.Other -> purpleColor - } - ) - } - } else { - EmptyStateView(modifier = Modifier.weight(1f)) - } - } - } - } - } -} - -@Composable -private fun DisabledStateView() { - Column( - modifier = Modifier - .fillMaxSize() - .padding(32.dp), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally - ) { - Icon( - Icons.Rounded.DataUsage, - null, - modifier = Modifier.size(80.dp), - tint = MaterialTheme.colorScheme.primary.copy(alpha = 0.6f) - ) - Spacer(modifier = Modifier.height(24.dp)) - Text( - stringResource(R.string.network_stats_disabled_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - textAlign = TextAlign.Center - ) - Spacer(modifier = Modifier.height(12.dp)) - Text( - stringResource(R.string.network_stats_disabled_description), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center - ) - } -} - -@Composable -private fun NetworkTabBody( - usage: NetworkTypeUsage, - primaryColor: Color -) { - val totalBytes = usage.sent + usage.received - val sortedCategories = remember(usage.details) { - usage.details.sortedByDescending { it.sent + it.received } - } - val maxCategoryBytes = remember(sortedCategories) { - if (sortedCategories.isNotEmpty()) sortedCategories.maxOf { it.sent + it.received } else 1L - } - - LazyColumn( - modifier = Modifier.fillMaxSize(), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, top = 0.dp, bottom = 16.dp) - ) { - item { - SectionHeader(stringResource(R.string.overview_header)) - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - Column(modifier = Modifier.padding(16.dp)) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Column { - Text( - text = formatSize(totalBytes), - style = MaterialTheme.typography.headlineMedium, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - Text( - text = stringResource(R.string.total_usage_label), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - Box( - modifier = Modifier - .size(48.dp) - .clip(CircleShape) - .background(primaryColor.copy(alpha = 0.15f)), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.PieChart, - contentDescription = null, - modifier = Modifier.size(28.dp), - tint = primaryColor - ) - } - } - - Spacer(modifier = Modifier.height(20.dp)) - - val sentProgress = if (totalBytes > 0) usage.sent.toFloat() / totalBytes.toFloat() else 0f - Row( - modifier = Modifier - .fillMaxWidth() - .height(8.dp) - .clip(RoundedCornerShape(4.dp)) - .background(primaryColor.copy(alpha = 0.2f)) - ) { - Box( - modifier = Modifier - .fillMaxHeight() - .fillMaxWidth(sentProgress) - .background(primaryColor) - ) - } - - Spacer(modifier = Modifier.height(12.dp)) - - Row(modifier = Modifier.fillMaxWidth()) { - Row(verticalAlignment = Alignment.CenterVertically) { - Box(modifier = Modifier - .size(8.dp) - .background(primaryColor, CircleShape)) - Spacer(modifier = Modifier.width(6.dp)) - Text( - stringResource(R.string.sent_label), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.width(4.dp)) - Text( - formatSize(usage.sent), - style = MaterialTheme.typography.labelMedium, - fontWeight = FontWeight.SemiBold - ) - } - Spacer(modifier = Modifier.weight(1f)) - Row(verticalAlignment = Alignment.CenterVertically) { - Box(modifier = Modifier - .size(8.dp) - .background(primaryColor.copy(alpha = 0.3f), CircleShape)) - Spacer(modifier = Modifier.width(6.dp)) - Text( - stringResource(R.string.received_label), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.width(4.dp)) - Text( - formatSize(usage.received), - style = MaterialTheme.typography.labelMedium, - fontWeight = FontWeight.SemiBold - ) - } - } - } - } - } - - item { - SectionHeader(stringResource(R.string.app_usage_header)) - } - - if (sortedCategories.isEmpty()) { - item { - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - Box(modifier = Modifier - .fillMaxWidth() - .padding(24.dp), contentAlignment = Alignment.Center) { - Text( - stringResource(R.string.no_usage_data_recorded), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.outline - ) - } - } - } - } else { - itemsIndexed(sortedCategories) { index, category -> - val position = when { - sortedCategories.size == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == sortedCategories.size - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - UsageRowItem( - category = category, - maxCategoryBytes = maxCategoryBytes, - accentColor = primaryColor, - position = position - ) - if (index < sortedCategories.size - 1) { - Spacer(Modifier.height(2.dp)) - } - } - } - item { Spacer(modifier = Modifier.height(16.dp)) } - } -} - -@Composable -private fun UsageRowItem( - category: NetworkUsageCategory, - maxCategoryBytes: Long, - accentColor: Color, - position: ItemPosition -) { - val itemTotal = category.sent + category.received - val visualProgress = if (maxCategoryBytes > 0) itemTotal.toFloat() / maxCategoryBytes.toFloat() else 0f - - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - .clickable { } - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(40.dp) - .clip(CircleShape) - .background(accentColor.copy(alpha = 0.15f)), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.DataUsage, - contentDescription = null, - tint = accentColor, - modifier = Modifier.size(24.dp) - ) - } - - Spacer(modifier = Modifier.width(16.dp)) - - Column(modifier = Modifier.weight(1f)) { - Text( - text = category.name, - style = MaterialTheme.typography.titleMedium, - fontSize = 16.sp, - maxLines = 1 - ) - Text( - text = "${stringResource(R.string.sent_label)}: ${formatSize(category.sent)} • ${stringResource(R.string.received_label)}: ${ - formatSize( - category.received - ) - }", - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.height(6.dp)) - LinearProgressIndicator( - progress = { visualProgress }, - modifier = Modifier - .fillMaxWidth(0.8f) - .height(4.dp) - .clip(CircleShape), - color = accentColor, - trackColor = MaterialTheme.colorScheme.surfaceVariant, - ) - } - Spacer(modifier = Modifier.width(8.dp)) - Text( - text = formatSize(itemTotal), - style = MaterialTheme.typography.bodyMedium, - fontWeight = FontWeight.Bold, - color = accentColor - ) - } - } -} - -@Composable -private fun SectionHeader(text: String) { - Text( - text = text, - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp, top = 16.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) -} - -@Composable -private fun EmptyStateView(modifier: Modifier = Modifier) { - Column( - modifier = modifier.fillMaxSize(), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally - ) { - Icon( - Icons.Rounded.SignalWifiOff, - null, - modifier = Modifier.size(64.dp), - tint = MaterialTheme.colorScheme.outline - ) - Spacer(modifier = Modifier.height(16.dp)) - Text( - stringResource(R.string.no_statistics_available), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } -} - -private fun formatSize(bytes: Long): String { - if (bytes < 1024) return "$bytes B" - val exp = (Math.log(bytes.toDouble()) / Math.log(1024.0)).toInt() - val pre = "KMGTPE"[exp - 1] - return String.format(Locale.US, "%.1f %cB", bytes / Math.pow(1024.0, exp.toDouble()), pre) -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/notifications/NotificationsComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/notifications/NotificationsComponent.kt deleted file mode 100644 index 2522408c..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/notifications/NotificationsComponent.kt +++ /dev/null @@ -1,338 +0,0 @@ -package org.monogram.presentation.settings.notifications - -import android.os.Parcelable -import com.arkivanov.decompose.router.stack.* -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch -import kotlinx.parcelize.Parcelize -import kotlinx.serialization.Serializable -import org.monogram.domain.managers.DistrManager -import org.monogram.domain.models.ChatModel -import org.monogram.domain.repository.PushProvider -import org.monogram.domain.repository.SettingsRepository -import org.monogram.domain.repository.SettingsRepository.TdNotificationScope -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.root.AppComponentContext - -interface NotificationsComponent { - val state: Value - val videoPlayerPool: VideoPlayerPool - val childStack: Value> - - fun onBackClicked() - fun onPrivateChatsToggled(enabled: Boolean) - fun onGroupsToggled(enabled: Boolean) - fun onChannelsToggled(enabled: Boolean) - fun onInAppSoundsToggled(enabled: Boolean) - fun onInAppVibrateToggled(enabled: Boolean) - fun onInAppPreviewToggled(enabled: Boolean) - fun onContactJoinedToggled(enabled: Boolean) - fun onPinnedMessagesToggled(enabled: Boolean) - fun onBackgroundServiceToggled(enabled: Boolean) - fun onHideForegroundNotificationToggled(enabled: Boolean) - fun onVibrationPatternChanged(pattern: String) - fun onPriorityChanged(priority: Int) - fun onRepeatNotificationsChanged(minutes: Int) - fun onShowSenderOnlyToggled(enabled: Boolean) - fun onPushProviderChanged(provider: PushProvider) - fun onResetNotificationsClicked() - fun onExceptionClicked(scope: TdNotificationScope) - fun onChatExceptionToggled(chatId: Long, enabled: Boolean) - fun onChatExceptionReset(chatId: Long) - - data class State( - val privateChatsEnabled: Boolean = true, - val groupsEnabled: Boolean = true, - val channelsEnabled: Boolean = true, - val inAppSounds: Boolean = true, - val inAppVibrate: Boolean = true, - val inAppPreview: Boolean = true, - val contactJoined: Boolean = true, - val pinnedMessages: Boolean = true, - val backgroundServiceEnabled: Boolean = true, - val hideForegroundNotification: Boolean = false, - val vibrationPattern: String = "default", - val priority: Int = 1, - val repeatNotifications: Int = 0, - val showSenderOnly: Boolean = false, - val pushProvider: PushProvider = PushProvider.FCM, - val isGmsAvailable: Boolean = false, - val privateExceptions: List? = null, - val groupExceptions: List? = null, - val channelExceptions: List? = null - ) - - sealed class Child { - object Main : Child() - class Exceptions(val scope: TdNotificationScope) : Child() - } -} - -class DefaultNotificationsComponent( - context: AppComponentContext, - private val onBack: () -> Unit -) : NotificationsComponent, AppComponentContext by context { - - private val appPreferences: AppPreferences = container.preferences.appPreferences - private val settingsRepository: SettingsRepository = container.repositories.settingsRepository - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - private val distrManager: DistrManager = container.utils.distrManager() - - private val scope = componentScope - private val navigation = StackNavigation() - - override val childStack: Value> = childStack( - source = navigation, - serializer = Config.serializer(), - initialConfiguration = Config.Main, - handleBackButton = true, - childFactory = ::createChild - ) - - private fun createChild(config: Config, context: AppComponentContext): NotificationsComponent.Child = - when (config) { - is Config.Main -> NotificationsComponent.Child.Main - is Config.Exceptions -> NotificationsComponent.Child.Exceptions(config.scope) - } - - private val _state = MutableValue(NotificationsComponent.State()) - override val state: Value = _state - - init { - appPreferences.privateChatsNotifications.onEach { value -> - _state.update { it.copy(privateChatsEnabled = value) } - }.launchIn(scope) - - appPreferences.groupsNotifications.onEach { value -> - _state.update { it.copy(groupsEnabled = value) } - }.launchIn(scope) - - appPreferences.channelsNotifications.onEach { value -> - _state.update { it.copy(channelsEnabled = value) } - }.launchIn(scope) - - appPreferences.inAppSounds.onEach { value -> - _state.update { it.copy(inAppSounds = value) } - }.launchIn(scope) - - appPreferences.inAppVibrate.onEach { value -> - _state.update { it.copy(inAppVibrate = value) } - }.launchIn(scope) - - appPreferences.inAppPreview.onEach { value -> - _state.update { it.copy(inAppPreview = value) } - }.launchIn(scope) - - appPreferences.contactJoinedNotifications.onEach { value -> - _state.update { it.copy(contactJoined = value) } - }.launchIn(scope) - - appPreferences.pinnedMessagesNotifications.onEach { value -> - _state.update { it.copy(pinnedMessages = value) } - }.launchIn(scope) - - appPreferences.backgroundServiceEnabled.onEach { value -> - _state.update { it.copy(backgroundServiceEnabled = value) } - }.launchIn(scope) - - appPreferences.hideForegroundNotification.onEach { value -> - _state.update { it.copy(hideForegroundNotification = value) } - }.launchIn(scope) - - appPreferences.notificationVibrationPattern.onEach { value -> - _state.update { it.copy(vibrationPattern = value) } - }.launchIn(scope) - - appPreferences.notificationPriority.onEach { value -> - _state.update { it.copy(priority = value) } - }.launchIn(scope) - - appPreferences.repeatNotifications.onEach { value -> - _state.update { it.copy(repeatNotifications = value) } - }.launchIn(scope) - - appPreferences.showSenderOnly.onEach { value -> - _state.update { it.copy(showSenderOnly = value) } - }.launchIn(scope) - - appPreferences.pushProvider.onEach { value -> - _state.update { it.copy(pushProvider = value) } - }.launchIn(scope) - - _state.update { it.copy(isGmsAvailable = distrManager.isGmsAvailable()) } - - syncSettings() - } - - private fun syncSettings() { - scope.launch { - val privateEnabled = settingsRepository.getNotificationSettings(TdNotificationScope.PRIVATE_CHATS) - appPreferences.setPrivateChatsNotifications(privateEnabled) - - val groupsEnabled = settingsRepository.getNotificationSettings(TdNotificationScope.GROUPS) - appPreferences.setGroupsNotifications(groupsEnabled) - - val channelsEnabled = settingsRepository.getNotificationSettings(TdNotificationScope.CHANNELS) - appPreferences.setChannelsNotifications(channelsEnabled) - } - } - - private fun loadExceptions(scope: TdNotificationScope) { - this.scope.launch { - _state.update { - when (scope) { - TdNotificationScope.PRIVATE_CHATS -> it.copy(privateExceptions = null) - TdNotificationScope.GROUPS -> it.copy(groupExceptions = null) - TdNotificationScope.CHANNELS -> it.copy(channelExceptions = null) - } - } - - val exceptions = settingsRepository.getExceptions(scope) - - _state.update { - when (scope) { - TdNotificationScope.PRIVATE_CHATS -> it.copy(privateExceptions = exceptions) - TdNotificationScope.GROUPS -> it.copy(groupExceptions = exceptions) - TdNotificationScope.CHANNELS -> it.copy(channelExceptions = exceptions) - } - } - } - } - - override fun onBackClicked() { - if (childStack.value.items.size > 1) { - navigation.pop() - } else { - onBack() - } - } - - override fun onPrivateChatsToggled(enabled: Boolean) { - appPreferences.setPrivateChatsNotifications(enabled) - scope.launch { - settingsRepository.setNotificationSettings(TdNotificationScope.PRIVATE_CHATS, enabled) - } - } - - override fun onGroupsToggled(enabled: Boolean) { - appPreferences.setGroupsNotifications(enabled) - scope.launch { - settingsRepository.setNotificationSettings(TdNotificationScope.GROUPS, enabled) - } - } - - override fun onChannelsToggled(enabled: Boolean) { - appPreferences.setChannelsNotifications(enabled) - scope.launch { - settingsRepository.setNotificationSettings(TdNotificationScope.CHANNELS, enabled) - } - } - - override fun onInAppSoundsToggled(enabled: Boolean) { - appPreferences.setInAppSounds(enabled) - } - - override fun onInAppVibrateToggled(enabled: Boolean) { - appPreferences.setInAppVibrate(enabled) - } - - override fun onInAppPreviewToggled(enabled: Boolean) { - appPreferences.setInAppPreview(enabled) - } - - override fun onContactJoinedToggled(enabled: Boolean) { - appPreferences.setContactJoinedNotifications(enabled) - } - - override fun onPinnedMessagesToggled(enabled: Boolean) { - appPreferences.setPinnedMessagesNotifications(enabled) - } - - override fun onBackgroundServiceToggled(enabled: Boolean) { - appPreferences.setBackgroundServiceEnabled(enabled) - } - - override fun onHideForegroundNotificationToggled(enabled: Boolean) { - appPreferences.setHideForegroundNotification(enabled) - } - - override fun onVibrationPatternChanged(pattern: String) { - appPreferences.setNotificationVibrationPattern(pattern) - } - - override fun onPriorityChanged(priority: Int) { - appPreferences.setNotificationPriority(priority) - } - - override fun onRepeatNotificationsChanged(minutes: Int) { - appPreferences.setRepeatNotifications(minutes) - } - - override fun onShowSenderOnlyToggled(enabled: Boolean) { - appPreferences.setShowSenderOnly(enabled) - } - - override fun onPushProviderChanged(provider: PushProvider) { - appPreferences.setPushProvider(provider) - } - - override fun onResetNotificationsClicked() { - onPrivateChatsToggled(true) - onGroupsToggled(true) - onChannelsToggled(true) - onInAppSoundsToggled(true) - onInAppVibrateToggled(true) - onInAppPreviewToggled(true) - onContactJoinedToggled(true) - onPinnedMessagesToggled(true) - onBackgroundServiceToggled(true) - onHideForegroundNotificationToggled(false) - onVibrationPatternChanged("default") - onPriorityChanged(1) - onRepeatNotificationsChanged(0) - onShowSenderOnlyToggled(false) - onPushProviderChanged(if (_state.value.isGmsAvailable) PushProvider.FCM else PushProvider.GMS_LESS) - } - - override fun onExceptionClicked(scope: TdNotificationScope) { - loadExceptions(scope) - navigation.push(Config.Exceptions(scope)) - } - - override fun onChatExceptionToggled(chatId: Long, enabled: Boolean) { - scope.launch { - settingsRepository.setChatNotificationSettings(chatId, enabled) - val currentChild = childStack.value.active.instance - if (currentChild is NotificationsComponent.Child.Exceptions) { - loadExceptions(currentChild.scope) - } - } - } - - override fun onChatExceptionReset(chatId: Long) { - scope.launch { - settingsRepository.resetChatNotificationSettings(chatId) - val currentChild = childStack.value.active.instance - if (currentChild is NotificationsComponent.Child.Exceptions) { - loadExceptions(currentChild.scope) - } - } - } - - @Serializable - sealed class Config : Parcelable { - @Parcelize - @Serializable - object Main : Config() - - @Parcelize - @Serializable - data class Exceptions(val scope: TdNotificationScope) : Config() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/notifications/NotificationsContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/notifications/NotificationsContent.kt deleted file mode 100644 index e2331729..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/notifications/NotificationsContent.kt +++ /dev/null @@ -1,449 +0,0 @@ -package org.monogram.presentation.settings.notifications - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.automirrored.rounded.VolumeUp -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.stack.Children -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.domain.repository.PushProvider -import org.monogram.domain.repository.SettingsRepository.TdNotificationScope -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsItem -import org.monogram.presentation.core.ui.SettingsSwitchTile - -@Composable -fun NotificationsContent(component: NotificationsComponent) { - Children(stack = component.childStack) { - when (val child = it.instance) { - is NotificationsComponent.Child.Main -> NotificationsMainContent(component) - is NotificationsComponent.Child.Exceptions -> NotificationsExceptionsContent(component, child.scope) - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun NotificationsMainContent(component: NotificationsComponent) { - val state by component.state.subscribeAsState() - var showVibrationSheet by remember { mutableStateOf(false) } - var showPrioritySheet by remember { mutableStateOf(false) } - var showRepeatSheet by remember { mutableStateOf(false) } - var showPushProviderSheet by remember { mutableStateOf(false) } - - Scaffold( - modifier = Modifier.semantics { contentDescription = "NotificationsContent" }, - topBar = { - TopAppBar( - title = { - Text( - stringResource(R.string.notifications_sounds_header), - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface) }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - } - ) - } - ) { padding -> - LazyColumn( - modifier = Modifier - .fillMaxSize() - .padding(top = padding.calculateTopPadding()), - contentPadding = PaddingValues(16.dp), - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - item { - SectionHeader(stringResource(R.string.message_notifications_header)) - SettingsSwitchTile( - icon = Icons.Rounded.Person, - title = stringResource(R.string.private_chats_title), - subtitle = if (!state.privateExceptions.isNullOrEmpty()) { - stringResource( - R.string.exceptions_count_format, - if (state.privateChatsEnabled) stringResource(R.string.on_label) else stringResource(R.string.off_label), - state.privateExceptions?.size ?: 0 - ) - } else { - if (state.privateChatsEnabled) stringResource(R.string.on_label) else stringResource(R.string.off_label) - }, - checked = state.privateChatsEnabled, - iconColor = Color(0xFF4285F4), - position = ItemPosition.TOP, - onCheckedChange = component::onPrivateChatsToggled, - onClick = { component.onExceptionClicked(TdNotificationScope.PRIVATE_CHATS) } - ) - SettingsSwitchTile( - icon = Icons.Rounded.Group, - title = stringResource(R.string.groups_title), - subtitle = if (!state.groupExceptions.isNullOrEmpty()) { - stringResource( - R.string.exceptions_count_format, - if (state.groupsEnabled) stringResource(R.string.on_label) else stringResource(R.string.off_label), - state.groupExceptions?.size ?: 0 - ) - } else { - if (state.groupsEnabled) stringResource(R.string.on_label) else stringResource(R.string.off_label) - }, - checked = state.groupsEnabled, - iconColor = Color(0xFF34A853), - position = ItemPosition.MIDDLE, - onCheckedChange = component::onGroupsToggled, - onClick = { component.onExceptionClicked(TdNotificationScope.GROUPS) } - ) - SettingsSwitchTile( - icon = Icons.Rounded.Campaign, - title = stringResource(R.string.channels_title), - subtitle = if (!state.channelExceptions.isNullOrEmpty()) { - stringResource( - R.string.exceptions_count_format, - if (state.channelsEnabled) stringResource(R.string.on_label) else stringResource(R.string.off_label), - state.channelExceptions?.size ?: 0 - ) - } else { - if (state.channelsEnabled) stringResource(R.string.on_label) else stringResource(R.string.off_label) - }, - checked = state.channelsEnabled, - iconColor = Color(0xFFF9AB00), - position = ItemPosition.BOTTOM, - onCheckedChange = component::onChannelsToggled, - onClick = { component.onExceptionClicked(TdNotificationScope.CHANNELS) } - ) - } - - item { - SectionHeader(stringResource(R.string.notification_settings_header)) - SettingsItem( - icon = Icons.Rounded.Vibration, - title = stringResource(R.string.vibration_title), - subtitle = when (state.vibrationPattern) { - "short" -> stringResource(R.string.vibration_pattern_short) - "long" -> stringResource(R.string.vibration_pattern_long) - "disabled" -> stringResource(R.string.vibration_pattern_disabled) - else -> stringResource(R.string.vibration_pattern_default) - }, - iconBackgroundColor = Color(0xFF9C27B0), - position = ItemPosition.TOP, - onClick = { showVibrationSheet = true } - ) - SettingsItem( - icon = Icons.Rounded.PriorityHigh, - title = stringResource(R.string.priority_title), - subtitle = when(state.priority) { - 0 -> stringResource(R.string.priority_low) - 2 -> stringResource(R.string.priority_high) - else -> stringResource(R.string.priority_default) - }, - iconBackgroundColor = Color(0xFFFF5722), - position = ItemPosition.MIDDLE, - onClick = { showPrioritySheet = true } - ) - SettingsItem( - icon = Icons.Rounded.Repeat, - title = stringResource(R.string.repeat_notifications_title), - subtitle = when (state.repeatNotifications) { - 0 -> stringResource(R.string.repeat_never) - 60 -> stringResource(R.string.repeat_hour_format) - 120, 240 -> stringResource(R.string.repeat_hours_format, state.repeatNotifications / 60) - else -> stringResource(R.string.repeat_minutes_format, state.repeatNotifications) - }, - iconBackgroundColor = Color(0xFF3F51B5), - position = ItemPosition.MIDDLE, - onClick = { showRepeatSheet = true } - ) - SettingsSwitchTile( - icon = Icons.Rounded.Visibility, - title = stringResource(R.string.show_sender_only_title), - subtitle = stringResource(R.string.show_sender_only_subtitle), - checked = state.showSenderOnly, - iconColor = Color(0xFF607D8B), - position = ItemPosition.BOTTOM, - onCheckedChange = component::onShowSenderOnlyToggled - ) - } - - item { - SectionHeader(stringResource(R.string.push_service_header)) - SettingsItem( - icon = Icons.Rounded.NotificationsActive, - title = stringResource(R.string.push_provider_title), - subtitle = when (state.pushProvider) { - PushProvider.FCM -> stringResource(R.string.push_provider_fcm) - PushProvider.GMS_LESS -> stringResource(R.string.push_provider_gms_less) - }, - iconBackgroundColor = Color(0xFF4CAF50), - position = ItemPosition.TOP, - onClick = { showPushProviderSheet = true } - ) - SettingsSwitchTile( - icon = Icons.Rounded.Sync, - title = stringResource(R.string.keep_alive_service_title), - subtitle = stringResource(R.string.keep_alive_service_subtitle), - checked = state.backgroundServiceEnabled, - iconColor = Color(0xFF607D8B), - position = ItemPosition.MIDDLE, - onCheckedChange = component::onBackgroundServiceToggled - ) - SettingsSwitchTile( - icon = Icons.Rounded.VisibilityOff, - title = stringResource(R.string.hide_foreground_notification_title), - subtitle = stringResource(R.string.hide_foreground_notification_subtitle), - checked = state.hideForegroundNotification, - iconColor = Color(0xFF9E9E9E), - position = ItemPosition.BOTTOM, - onCheckedChange = component::onHideForegroundNotificationToggled - ) - } - - item { - SectionHeader(stringResource(R.string.in_app_notifications_header)) - SettingsSwitchTile( - icon = Icons.AutoMirrored.Rounded.VolumeUp, - title = stringResource(R.string.in_app_sounds_title), - checked = state.inAppSounds, - iconColor = Color(0xFFE91E63), - position = ItemPosition.TOP, - onCheckedChange = component::onInAppSoundsToggled - ) - SettingsSwitchTile( - icon = Icons.Rounded.Vibration, - title = stringResource(R.string.in_app_vibrate_title), - checked = state.inAppVibrate, - iconColor = Color(0xFF9C27B0), - position = ItemPosition.MIDDLE, - onCheckedChange = component::onInAppVibrateToggled - ) - SettingsSwitchTile( - icon = Icons.Rounded.ChatBubbleOutline, - title = stringResource(R.string.in_app_preview_title), - checked = state.inAppPreview, - iconColor = Color(0xFF00BCD4), - position = ItemPosition.BOTTOM, - onCheckedChange = component::onInAppPreviewToggled - ) - } - - item { - SectionHeader(stringResource(R.string.events_header)) - SettingsSwitchTile( - icon = Icons.Rounded.PersonAdd, - title = stringResource(R.string.contact_joined_telegram_title), - checked = state.contactJoined, - iconColor = Color(0xFF4CAF50), - position = ItemPosition.TOP, - onCheckedChange = component::onContactJoinedToggled - ) - SettingsSwitchTile( - icon = Icons.Rounded.PushPin, - title = stringResource(R.string.pinned_messages_title), - checked = state.pinnedMessages, - iconColor = Color(0xFFFF9800), - position = ItemPosition.BOTTOM, - onCheckedChange = component::onPinnedMessagesToggled - ) - } - - item { - Spacer(modifier = Modifier.height(16.dp)) - SettingsItem( - icon = Icons.Rounded.Refresh, - title = stringResource(R.string.reset_all_notifications_title), - subtitle = stringResource(R.string.reset_all_notifications_subtitle), - iconBackgroundColor = MaterialTheme.colorScheme.error, - position = ItemPosition.STANDALONE, - onClick = component::onResetNotificationsClicked - ) - } - item { Spacer(modifier = Modifier.height(padding.calculateBottomPadding()-16.dp)) } - } - } - - if (showVibrationSheet) { - val options = listOf( - "default" to stringResource(R.string.vibration_pattern_default), - "short" to stringResource(R.string.vibration_pattern_short), - "long" to stringResource(R.string.vibration_pattern_long), - "disabled" to stringResource(R.string.vibration_pattern_disabled) - ) - NotificationOptionSheet( - title = stringResource(R.string.vibration_pattern_title), - options = options, - selectedOption = state.vibrationPattern, - onOptionSelected = { - component.onVibrationPatternChanged(it) - showVibrationSheet = false - }, - onDismiss = { showVibrationSheet = false } - ) - } - - if (showPrioritySheet) { - val options = listOf( - "0" to stringResource(R.string.priority_low), - "1" to stringResource(R.string.priority_default), - "2" to stringResource(R.string.priority_high) - ) - NotificationOptionSheet( - title = stringResource(R.string.notification_priority_title), - options = options, - selectedOption = state.priority.toString(), - onOptionSelected = { - component.onPriorityChanged(it.toInt()) - showPrioritySheet = false - }, - onDismiss = { showPrioritySheet = false } - ) - } - - if (showRepeatSheet) { - val options = listOf( - "0" to stringResource(R.string.repeat_never), - "5" to stringResource(R.string.repeat_minutes_format, 5), - "10" to stringResource(R.string.repeat_minutes_format, 10), - "30" to stringResource(R.string.repeat_minutes_format, 30), - "60" to stringResource(R.string.repeat_hour_format), - "120" to stringResource(R.string.repeat_hours_format, 2), - "240" to stringResource(R.string.repeat_hours_format, 4) - ) - NotificationOptionSheet( - title = stringResource(R.string.repeat_notifications_title), - options = options, - selectedOption = state.repeatNotifications.toString(), - onOptionSelected = { - component.onRepeatNotificationsChanged(it.toInt()) - showRepeatSheet = false - }, - onDismiss = { showRepeatSheet = false } - ) - } - - if (showPushProviderSheet) { - val options = mutableListOf>() - if (state.isGmsAvailable) { - options.add(PushProvider.FCM.name to stringResource(R.string.push_provider_fcm)) - } - options.add(PushProvider.GMS_LESS.name to stringResource(R.string.push_provider_gms_less)) - - NotificationOptionSheet( - title = stringResource(R.string.push_provider_title), - options = options, - selectedOption = state.pushProvider.name, - onOptionSelected = { - component.onPushProviderChanged(PushProvider.valueOf(it)) - showPushProviderSheet = false - }, - onDismiss = { showPushProviderSheet = false } - ) - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun NotificationOptionSheet( - title: String, - options: List>, - selectedOption: String, - onOptionSelected: (String) -> Unit, - onDismiss: () -> Unit -) { - ModalBottomSheet( - onDismissRequest = onDismiss, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 32.dp) - ) { - Text( - text = title, - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(bottom = 16.dp, start = 8.dp) - ) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - LazyColumn( - modifier = Modifier.padding(vertical = 8.dp) - ) { - items(options) { (value, label) -> - val isSelected = value == selectedOption - Row( - modifier = Modifier - .fillMaxWidth() - .clickable { onOptionSelected(value) } - .padding(horizontal = 16.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = label, - modifier = Modifier.weight(1f), - style = MaterialTheme.typography.bodyLarge, - color = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface, - fontWeight = if (isSelected) FontWeight.Bold else FontWeight.Normal - ) - RadioButton( - selected = isSelected, - onClick = { onOptionSelected(value) } - ) - } - } - } - } - - Spacer(modifier = Modifier.height(16.dp)) - - Button( - onClick = onDismiss, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.cancel_button), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } -} - -@Composable -private fun SectionHeader(text: String) { - Text( - text = text, - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp, top = 16.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/notifications/NotificationsExceptionsContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/notifications/NotificationsExceptionsContent.kt deleted file mode 100644 index 3688c70b..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/notifications/NotificationsExceptionsContent.kt +++ /dev/null @@ -1,498 +0,0 @@ -package org.monogram.presentation.settings.notifications - -import androidx.compose.animation.* -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.domain.models.ChatModel -import org.monogram.domain.repository.SettingsRepository.TdNotificationScope -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.core.ui.ItemPosition - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun NotificationsExceptionsContent( - component: NotificationsComponent, - scope: TdNotificationScope -) { - val state by component.state.subscribeAsState() - val exceptions = remember(state, scope) { - when (scope) { - TdNotificationScope.PRIVATE_CHATS -> state.privateExceptions - TdNotificationScope.GROUPS -> state.groupExceptions - TdNotificationScope.CHANNELS -> state.channelExceptions - } - } - - val title = remember(scope) { - when (scope) { - TdNotificationScope.PRIVATE_CHATS -> "Private Chats" - TdNotificationScope.GROUPS -> "Groups" - TdNotificationScope.CHANNELS -> "Channels" - } - } - - var selectedChat by remember { mutableStateOf(null) } - var searchQuery by remember { mutableStateOf("") } - var isSearchActive by remember { mutableStateOf(false) } - - val filteredExceptions = remember(exceptions, searchQuery) { - if (searchQuery.isEmpty()) { - exceptions - } else { - exceptions?.filter { it.title.contains(searchQuery, ignoreCase = true) } - } - } - - Scaffold( - topBar = { - AnimatedContent( - targetState = isSearchActive, - transitionSpec = { - if (targetState) { - (fadeIn() + slideInVertically { -it / 4 }).togetherWith(fadeOut()) - } else { - fadeIn().togetherWith(fadeOut() + slideOutVertically { -it / 4 }) - } - }, - label = "TopBarSearchTransition" - ) { active -> - if (active) { - Box( - modifier = Modifier - .fillMaxWidth() - .statusBarsPadding() - .padding(horizontal = 16.dp, vertical = 8.dp) - ) { - SearchBar( - inputField = { - SearchBarDefaults.InputField( - query = searchQuery, - onQueryChange = { searchQuery = it }, - onSearch = {}, - expanded = false, - onExpandedChange = {}, - placeholder = { Text("Search exceptions...") }, - leadingIcon = { - IconButton(onClick = { - isSearchActive = false - searchQuery = "" - }) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = "Back" - ) - } - }, - trailingIcon = { - if (searchQuery.isNotEmpty()) { - IconButton(onClick = { searchQuery = "" }) { - Icon(Icons.Rounded.Close, contentDescription = "Clear") - } - } - } - ) - }, - expanded = false, - onExpandedChange = {}, - shape = RoundedCornerShape(24.dp), - colors = SearchBarDefaults.colors( - containerColor = MaterialTheme.colorScheme.surfaceContainerHigh, - dividerColor = Color.Transparent - ), - modifier = Modifier.fillMaxWidth() - ) {} - } - } else { - TopAppBar( - title = { - Column { - Text(title, - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface) - Text( - text = "Exceptions", - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon(Icons.AutoMirrored.Rounded.ArrowBack, contentDescription = null) - } - }, - actions = { - if (!exceptions.isNullOrEmpty()) { - IconButton(onClick = { isSearchActive = true }) { - Icon(Icons.Rounded.Search, contentDescription = "Search") - } - } - } - ) - } - } - } - ) { padding -> - when { - exceptions == null -> { - Box( - modifier = Modifier - .fillMaxSize() - .padding(padding), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator() - } - } - - exceptions.isEmpty() -> { - EmptyExceptionsPlaceholder(Modifier.padding(padding)) - } - - filteredExceptions.isNullOrEmpty() -> { - Box( - modifier = Modifier - .fillMaxSize() - .padding(padding), - contentAlignment = Alignment.Center - ) { - Text( - text = "No results found for \"$searchQuery\"", - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - - else -> { - LazyColumn( - modifier = Modifier - .fillMaxSize() - .padding(padding), - contentPadding = PaddingValues(16.dp) - ) { - item { - Text( - text = "CHATS", - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp), - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) - } - - itemsIndexed(filteredExceptions) { index, chat -> - val position = when { - filteredExceptions.size == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == filteredExceptions.size - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - - ExceptionItem( - chat = chat, - position = position, - onClick = { selectedChat = chat }, - videoPlayerPool = component.videoPlayerPool - ) - } - - item { - Spacer(modifier = Modifier.height(16.dp)) - Text( - text = "Tap on a chat to change its notification settings or remove the exception.", - modifier = Modifier.padding(horizontal = 12.dp), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } - } - } - - selectedChat?.let { chat -> - ExceptionActionsSheet( - chat = chat, - onDismiss = { selectedChat = null }, - onToggleMute = { - component.onChatExceptionToggled(chat.id, chat.isMuted) - selectedChat = null - }, - videoPlayerPool = component.videoPlayerPool, - onRemoveException = { - component.onChatExceptionReset(chat.id) - selectedChat = null - } - ) - } -} - -@Composable -private fun EmptyExceptionsPlaceholder(modifier: Modifier = Modifier) { - Box( - modifier = modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(16.dp), - modifier = Modifier.padding(32.dp) - ) { - Box( - modifier = Modifier - .size(80.dp) - .background( - MaterialTheme.colorScheme.primaryContainer, - CircleShape - ), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.Notifications, - contentDescription = null, - modifier = Modifier.size(40.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - Text( - text = "No Exceptions", - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - Text( - text = "You can add specific notification settings for individual chats. These settings will override the global defaults.", - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center - ) - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun ExceptionActionsSheet( - chat: ChatModel, - videoPlayerPool: VideoPlayerPool, - onDismiss: () -> Unit, - onToggleMute: () -> Unit, - onRemoveException: () -> Unit -) { - ModalBottomSheet( - onDismissRequest = onDismiss, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 20.dp) - .padding(bottom = 32.dp) - ) { - Text( - text = "Exception Settings", - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - - Spacer(modifier = Modifier.height(24.dp)) - - Row( - modifier = Modifier - .fillMaxWidth() - .clip(RoundedCornerShape(24.dp)) - .background(MaterialTheme.colorScheme.surfaceContainer) - .padding(16.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Avatar( - path = chat.avatarPath, - fallbackPath = chat.personalAvatarPath, - name = chat.title, - size = 48.dp, - videoPlayerPool = videoPlayerPool - ) - Spacer(modifier = Modifier.width(16.dp)) - Column { - Text( - text = chat.title, - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.Bold - ) - Text( - text = if (chat.isMuted) "Notifications are muted" else "Notifications are enabled", - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - - Spacer(modifier = Modifier.height(24.dp)) - - Text( - text = "Actions", - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.primary, - modifier = Modifier.padding(start = 8.dp, bottom = 8.dp) - ) - - Column( - modifier = Modifier - .fillMaxWidth() - .clip(RoundedCornerShape(24.dp)) - .background(MaterialTheme.colorScheme.surfaceContainer) - ) { - ListItem( - headlineContent = { - Text( - if (chat.isMuted) "Unmute Chat" else "Mute Chat", - style = MaterialTheme.typography.bodyLarge - ) - }, - leadingContent = { - Icon( - if (chat.isMuted) Icons.Rounded.Notifications else Icons.Rounded.NotificationsOff, - contentDescription = null, - tint = if (chat.isMuted) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.error - ) - }, - colors = ListItemDefaults.colors(containerColor = Color.Transparent), - modifier = Modifier.clickable(onClick = onToggleMute) - ) - - HorizontalDivider( - modifier = Modifier.padding(horizontal = 16.dp), - thickness = 0.5.dp, - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - - ListItem( - headlineContent = { - Text( - "Remove Exception", - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.error - ) - }, - leadingContent = { - Icon( - Icons.Rounded.Delete, - contentDescription = null, - tint = MaterialTheme.colorScheme.error - ) - }, - colors = ListItemDefaults.colors(containerColor = Color.Transparent), - modifier = Modifier.clickable(onClick = onRemoveException) - ) - } - - Spacer(modifier = Modifier.height(32.dp)) - - Button( - onClick = onDismiss, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text("Close", fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } -} - -@Composable -private fun ExceptionItem( - chat: ChatModel, - position: ItemPosition, - videoPlayerPool: VideoPlayerPool, - onClick: () -> Unit -) { - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - .clickable(onClick = onClick) - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Avatar( - path = chat.avatarPath, - fallbackPath = chat.personalAvatarPath, - name = chat.title, - size = 44.dp, - videoPlayerPool = videoPlayerPool - ) - Spacer(modifier = Modifier.width(16.dp)) - Column(modifier = Modifier.weight(1f)) { - Text( - text = chat.title, - style = MaterialTheme.typography.titleMedium, - fontSize = 17.sp, - fontWeight = FontWeight.SemiBold - ) - Text( - text = if (chat.isMuted) "Muted" else "Always On", - style = MaterialTheme.typography.bodyMedium, - color = if (chat.isMuted) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.primary - ) - } - Icon( - imageVector = if (chat.isMuted) Icons.Rounded.NotificationsOff else Icons.Rounded.Notifications, - contentDescription = null, - tint = if (chat.isMuted) MaterialTheme.colorScheme.error.copy(alpha = 0.6f) else MaterialTheme.colorScheme.primary.copy( - alpha = 0.6f - ), - modifier = Modifier.size(20.dp) - ) - } - } - Spacer(Modifier.size(2.dp)) -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/powersaving/PowerSavingComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/powersaving/PowerSavingComponent.kt deleted file mode 100644 index 4ab8baaa..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/powersaving/PowerSavingComponent.kt +++ /dev/null @@ -1,86 +0,0 @@ -package org.monogram.presentation.settings.powersaving - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import org.monogram.domain.repository.AppPreferencesProvider -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.root.AppComponentContext - -interface PowerSavingComponent { - val state: Value - - fun onBackClicked() - fun onChatAnimationsToggled(enabled: Boolean) - fun onBackgroundServiceToggled(enabled: Boolean) - fun onPowerSavingModeToggled(enabled: Boolean) - fun onWakeLockToggled(enabled: Boolean) - fun onBatteryOptimizationToggled(enabled: Boolean) - - data class State( - val isChatAnimationsEnabled: Boolean = true, - val backgroundServiceEnabled: Boolean = true, - val isPowerSavingModeEnabled: Boolean = false, - val isWakeLockEnabled: Boolean = true, - val batteryOptimizationEnabled: Boolean = false - ) -} - -class DefaultPowerSavingComponent( - context: AppComponentContext, - private val onBack: () -> Unit -) : PowerSavingComponent, AppComponentContext by context { - - private val appPreferences: AppPreferencesProvider = container.preferences.appPreferences - private val _state = MutableValue(PowerSavingComponent.State()) - override val state: Value = _state - private val scope = componentScope - - init { - appPreferences.isChatAnimationsEnabled.onEach { value -> - _state.update { it.copy(isChatAnimationsEnabled = value) } - }.launchIn(scope) - - appPreferences.backgroundServiceEnabled.onEach { value -> - _state.update { it.copy(backgroundServiceEnabled = value) } - }.launchIn(scope) - - appPreferences.isPowerSavingMode.onEach { value -> - _state.update { it.copy(isPowerSavingModeEnabled = value) } - }.launchIn(scope) - - appPreferences.isWakeLockEnabled.onEach { value -> - _state.update { it.copy(isWakeLockEnabled = value) } - }.launchIn(scope) - - appPreferences.batteryOptimizationEnabled.onEach { value -> - _state.update { it.copy(batteryOptimizationEnabled = value) } - }.launchIn(scope) - } - - override fun onBackClicked() { - onBack() - } - - override fun onChatAnimationsToggled(enabled: Boolean) { - appPreferences.setChatAnimationsEnabled(enabled) - } - - override fun onBackgroundServiceToggled(enabled: Boolean) { - appPreferences.setBackgroundServiceEnabled(enabled) - } - - override fun onPowerSavingModeToggled(enabled: Boolean) { - appPreferences.setPowerSavingMode(enabled) - } - - override fun onWakeLockToggled(enabled: Boolean) { - appPreferences.setWakeLockEnabled(enabled) - } - - override fun onBatteryOptimizationToggled(enabled: Boolean) { - appPreferences.setBatteryOptimizationEnabled(enabled) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/powersaving/PowerSavingContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/powersaving/PowerSavingContent.kt deleted file mode 100644 index 7ea417aa..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/powersaving/PowerSavingContent.kt +++ /dev/null @@ -1,129 +0,0 @@ -package org.monogram.presentation.settings.powersaving - -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsSwitchTile - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun PowerSavingContent(component: PowerSavingComponent) { - val state by component.state.subscribeAsState() - - Scaffold( - topBar = { - TopAppBar( - title = { - Text( - stringResource(R.string.power_saving_header), - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface) }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - } - ) - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - LazyColumn( - modifier = Modifier - .fillMaxSize() - .padding(top = padding.calculateTopPadding()), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, top = 0.dp, bottom = 16.dp), - verticalArrangement = Arrangement.spacedBy(16.dp) - ) { - item { - SectionHeader(stringResource(R.string.battery_header)) - SettingsSwitchTile( - icon = Icons.Rounded.BatteryAlert, - title = stringResource(R.string.power_saving_mode_title), - subtitle = stringResource(R.string.power_saving_mode_subtitle), - checked = state.isPowerSavingModeEnabled, - iconColor = Color(0xFFF44336), - position = ItemPosition.TOP, - onCheckedChange = component::onPowerSavingModeToggled - ) - SettingsSwitchTile( - icon = Icons.Rounded.BatterySaver, - title = stringResource(R.string.optimize_battery_usage_title), - subtitle = stringResource(R.string.optimize_battery_usage_subtitle), - checked = state.batteryOptimizationEnabled, - iconColor = Color(0xFF4CAF50), - position = ItemPosition.MIDDLE, - onCheckedChange = component::onBatteryOptimizationToggled - ) - SettingsSwitchTile( - icon = Icons.Rounded.Power, - title = stringResource(R.string.wake_lock_title), - subtitle = stringResource(R.string.wake_lock_subtitle), - checked = if (state.isPowerSavingModeEnabled || state.batteryOptimizationEnabled) false else state.isWakeLockEnabled, - enabled = !state.isPowerSavingModeEnabled && !state.batteryOptimizationEnabled, - iconColor = Color(0xFFFF9800), - position = ItemPosition.BOTTOM, - onCheckedChange = component::onWakeLockToggled - ) - } - - item { - SectionHeader(stringResource(R.string.animations_header)) - SettingsSwitchTile( - icon = Icons.Rounded.Animation, - title = stringResource(R.string.chat_animations_title), - subtitle = stringResource(R.string.chat_animations_subtitle), - checked = if (state.isPowerSavingModeEnabled) false else state.isChatAnimationsEnabled, - enabled = !state.isPowerSavingModeEnabled, - iconColor = Color(0xFF4285F4), - position = ItemPosition.STANDALONE, - onCheckedChange = component::onChatAnimationsToggled - ) - } - - item { - SectionHeader(stringResource(R.string.background_header)) - SettingsSwitchTile( - icon = Icons.Rounded.Sync, - title = stringResource(R.string.keep_alive_service_title), - subtitle = stringResource(R.string.keep_alive_power_saving_subtitle), - checked = if (state.isPowerSavingModeEnabled) false else state.backgroundServiceEnabled, - enabled = !state.isPowerSavingModeEnabled, - iconColor = Color(0xFF607D8B), - position = ItemPosition.STANDALONE, - onCheckedChange = component::onBackgroundServiceToggled - ) - } - - item { Spacer(modifier = Modifier.height(padding.calculateBottomPadding())) } - } - } -} - -@Composable -private fun SectionHeader(text: String) { - Text( - text = text, - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp, top = 16.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/settings/premium/PremiumComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/premium/PremiumComponent.kt deleted file mode 100644 index 14326f23..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/premium/PremiumComponent.kt +++ /dev/null @@ -1,180 +0,0 @@ -package org.monogram.presentation.settings.premium - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch -import org.monogram.domain.models.PremiumFeatureType -import org.monogram.domain.models.PremiumLimitType -import org.monogram.domain.models.PremiumSource -import org.monogram.domain.repository.UserRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.root.AppComponentContext - -interface PremiumComponent { - val state: Value - fun onBackClicked() - fun onSubscribeClicked() - - data class State( - val features: List = emptyList(), - val isLoading: Boolean = false, - val isPremium: Boolean = false, - val statusText: String? = null - ) - - data class PremiumFeature( - val icon: String, - val title: String, - val description: String, - val color: Long - ) -} - -class DefaultPremiumComponent( - context: AppComponentContext, - private val onBack: () -> Unit -) : PremiumComponent, AppComponentContext by context { - - private val userRepository: UserRepository = container.repositories.userRepository - private val stringProvider = container.utils.stringProvider() - private val scope = componentScope - - private val _state = MutableValue(PremiumComponent.State()) - override val state: Value = _state - - init { - userRepository.currentUserFlow.onEach { user -> - if (user != null) { - _state.update { it.copy(isPremium = user.isPremium) } - } - }.launchIn(scope) - - loadPremiumState() - } - - private fun loadPremiumState() { - scope.launch { - _state.update { it.copy(isLoading = true) } - - val premiumState = userRepository.getPremiumState() - val features = userRepository.getPremiumFeatures(PremiumSource.SETTINGS) - - val mappedFeatures = features.mapNotNull { featureType -> - mapToPremiumFeature(featureType) - } - - _state.update { - it.copy( - features = mappedFeatures, - statusText = premiumState?.state, - isLoading = false - ) - } - } - } - - private suspend fun mapToPremiumFeature(featureType: PremiumFeatureType): PremiumComponent.PremiumFeature? { - return when (featureType) { - PremiumFeatureType.DOUBLE_LIMITS -> { - val channels = userRepository.getPremiumLimit(PremiumLimitType.SUPERGROUP_COUNT) - val folders = userRepository.getPremiumLimit(PremiumLimitType.CHAT_FOLDER_COUNT) - val pins = userRepository.getPremiumLimit(PremiumLimitType.PINNED_CHAT_COUNT) - val publicLinks = userRepository.getPremiumLimit(PremiumLimitType.CREATED_PUBLIC_CHAT_COUNT) - PremiumComponent.PremiumFeature( - icon = "star", - title = stringProvider.getString("premium_feature_doubled_limits_title"), - description = stringProvider.getString( - "premium_feature_doubled_limits_description", - channels, - folders, - pins, - publicLinks - ), - color = 0xFFAF52DE - ) - } - - PremiumFeatureType.VOICE_TO_TEXT -> PremiumComponent.PremiumFeature( - icon = "mic", - title = stringProvider.getString("premium_feature_voice_to_text_title"), - description = stringProvider.getString("premium_feature_voice_to_text_description"), - color = 0xFF4285F4 - ) - - PremiumFeatureType.FASTER_DOWNLOAD -> PremiumComponent.PremiumFeature( - icon = "download", - title = stringProvider.getString("premium_feature_faster_download_title"), - description = stringProvider.getString("premium_feature_faster_download_description"), - color = 0xFF34A853 - ) - - PremiumFeatureType.TRANSLATION -> PremiumComponent.PremiumFeature( - icon = "translate", - title = stringProvider.getString("premium_feature_translation_title"), - description = stringProvider.getString("premium_feature_translation_description"), - color = 0xFFF9AB00 - ) - - PremiumFeatureType.ANIMATED_EMOJI -> PremiumComponent.PremiumFeature( - icon = "face", - title = stringProvider.getString("premium_feature_animated_emoji_title"), - description = stringProvider.getString("premium_feature_animated_emoji_description"), - color = 0xFFFF6D66 - ) - - PremiumFeatureType.ADVANCED_CHAT_MANAGEMENT -> PremiumComponent.PremiumFeature( - icon = "folder", - title = stringProvider.getString("premium_feature_chat_management_title"), - description = stringProvider.getString("premium_feature_chat_management_description"), - color = 0xFF536DFE - ) - - PremiumFeatureType.NO_ADS -> PremiumComponent.PremiumFeature( - icon = "block", - title = stringProvider.getString("premium_feature_no_ads_title"), - description = stringProvider.getString("premium_feature_no_ads_description"), - color = 0xFF00BFA5 - ) - - PremiumFeatureType.INFINITE_REACTIONS -> PremiumComponent.PremiumFeature( - icon = "heart", - title = stringProvider.getString("premium_feature_infinite_reactions_title"), - description = stringProvider.getString("premium_feature_infinite_reactions_description"), - color = 0xFFFF6D66 - ) - - PremiumFeatureType.BADGE -> PremiumComponent.PremiumFeature( - icon = "verified", - title = stringProvider.getString("premium_feature_badge_title"), - description = stringProvider.getString("premium_feature_badge_description"), - color = 0xFF24A1DE - ) - - PremiumFeatureType.PROFILE_BADGE -> PremiumComponent.PremiumFeature( - icon = "face", - title = stringProvider.getString("premium_feature_emoji_status_title"), - description = stringProvider.getString("premium_feature_emoji_status_description"), - color = 0xFFF9AB00 - ) - - PremiumFeatureType.APP_ICONS -> PremiumComponent.PremiumFeature( - icon = "settings", - title = stringProvider.getString("premium_feature_app_icons_title"), - description = stringProvider.getString("premium_feature_app_icons_description"), - color = 0xFF673AB7 - ) - - PremiumFeatureType.UNKNOWN -> null - } - } - - override fun onBackClicked() { - onBack() - } - - override fun onSubscribeClicked() { - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/settings/premium/PremiumContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/premium/PremiumContent.kt deleted file mode 100644 index c2fdefd5..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/premium/PremiumContent.kt +++ /dev/null @@ -1,283 +0,0 @@ -package org.monogram.presentation.settings.premium - -import android.content.Intent -import android.net.Uri -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.lerp -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.CollapsingToolbarScaffold -import org.monogram.presentation.core.ui.TelegramStarInteractive -import org.monogram.presentation.core.ui.rememberCollapsingToolbarScaffoldState -import org.monogram.presentation.core.util.ScrollStrategy - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun PremiumContent(component: PremiumComponent) { - val state by component.state.subscribeAsState() - val context = LocalContext.current - val states = rememberCollapsingToolbarScaffoldState() - val currentRadius = 28.dp * states.toolbarState.progress - val collapsedColor = MaterialTheme.colorScheme.surface - val expandedColor = MaterialTheme.colorScheme.primaryContainer - val dynamicContainerColor = lerp( - start = collapsedColor, - stop = expandedColor, - fraction = states.toolbarState.progress - ) - - Scaffold( - modifier = Modifier.semantics { contentDescription = "PremiumContent" }, - topBar = { - TopAppBar( - title = { - Text( - stringResource(R.string.premium_title), - fontWeight = FontWeight.Bold, - fontSize = 20.sp - ) - }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.premium_back) - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = dynamicContainerColor, - scrolledContainerColor = dynamicContainerColor - ) - ) - }, - bottomBar = { - if (!state.isPremium) { - Surface( - color = MaterialTheme.colorScheme.background, - tonalElevation = 8.dp, - shadowElevation = 8.dp - ) { - Column(modifier = Modifier.navigationBarsPadding()) { - Button( - onClick = { - val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://t.me/PremiumBot")) - context.startActivity(intent) - component.onSubscribeClicked() - }, - modifier = Modifier - .fillMaxWidth() - .padding(16.dp) - .height(56.dp), - shape = RoundedCornerShape(16.dp), - colors = ButtonDefaults.buttonColors( - containerColor = Color(0xFFAF52DE) - ) - ) { - Text( - stringResource(R.string.premium_subscribe_button, "$4.99"), - fontSize = 16.sp, - fontWeight = FontWeight.Bold - ) - } - } - } - } - } - ) { padding -> - CollapsingToolbarScaffold( - modifier = Modifier - .fillMaxSize() - .background(dynamicContainerColor) - .padding(top = padding.calculateTopPadding()), - state = states, - scrollStrategy = ScrollStrategy.ExitUntilCollapsed, - toolbar = { - Box( - modifier = Modifier - .fillMaxWidth() - .height(0.dp) - .pin() - .background(dynamicContainerColor) - ) - - Column( - modifier = Modifier - .fillMaxWidth() - .road(Alignment.Center, Alignment.BottomCenter) - .padding(top = 16.dp, bottom = 48.dp) - .alpha(states.toolbarState.progress), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Box(modifier = Modifier - .fillMaxWidth() - .height(270.dp)) { - TelegramStarInteractive( - resId = R.raw.star, - alpha = states.toolbarState.progress - ) - } - } - } - ) { - Card( - modifier = Modifier.fillMaxSize(), - shape = RoundedCornerShape(topStart = currentRadius, topEnd = currentRadius), - colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.background - ) - ) { - LazyColumn( - modifier = Modifier.fillMaxSize(), - contentPadding = PaddingValues(top = 24.dp, bottom = padding.calculateBottomPadding()) - ) { - item { - PremiumStatusCard( - isPremium = state.isPremium, - statusText = state.statusText, - onClick = { - val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://t.me/PremiumBot")) - context.startActivity(intent) - } - ) - Spacer(modifier = Modifier.height(24.dp)) - } - - items(state.features) { feature -> - PremiumFeatureItem(feature) - } - } - } - } - } -} - -@Composable -fun PremiumStatusCard( - isPremium: Boolean, - statusText: String?, - onClick: () -> Unit -) { - Card( - shape = RoundedCornerShape(24.dp), - colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.surfaceContainerHigh, - ), - onClick = onClick, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Column( - modifier = Modifier - .weight(1f) - .padding(start = 8.dp), - verticalArrangement = Arrangement.Center - ) { - if (isPremium && statusText != null) { - Text( - text = statusText, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center, - lineHeight = 20.sp - ) - } else if (!isPremium) { - Text( - text = stringResource(R.string.premium_unlock_features), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - - } - } -} - -@Composable -fun PremiumFeatureItem(feature: PremiumComponent.PremiumFeature) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp, vertical = 12.dp), - verticalAlignment = Alignment.Top - ) { - Box( - modifier = Modifier - .size(40.dp) - .clip(RoundedCornerShape(10.dp)) - .background(Color(feature.color).copy(alpha = 0.1f)), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = getIconForName(feature.icon), - contentDescription = null, - tint = Color(feature.color), - modifier = Modifier.size(24.dp) - ) - } - - Spacer(modifier = Modifier.width(16.dp)) - - Column { - Text( - text = feature.title, - fontSize = 16.sp, - fontWeight = FontWeight.Bold - ) - Text( - text = feature.description, - fontSize = 14.sp, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } -} - -fun getIconForName(name: String): ImageVector { - return when (name) { - "star" -> Icons.Rounded.Star - "mic" -> Icons.Rounded.Mic - "download" -> Icons.Rounded.Download - "translate" -> Icons.Rounded.Translate - "face" -> Icons.Rounded.Face - "folder" -> Icons.Rounded.Folder - "block" -> Icons.Rounded.Block - "heart" -> Icons.Rounded.Favorite - "verified" -> Icons.Rounded.Verified - "settings" -> Icons.Rounded.Settings - else -> Icons.Rounded.Star - } -} - diff --git a/presentation/src/main/java/org/monogram/presentation/settings/privacy/BlockedUsersComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/privacy/BlockedUsersComponent.kt deleted file mode 100644 index 02e4b5c4..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/privacy/BlockedUsersComponent.kt +++ /dev/null @@ -1,90 +0,0 @@ -package org.monogram.presentation.settings.privacy - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.launch -import org.monogram.domain.models.UserModel -import org.monogram.domain.repository.PrivacyRepository -import org.monogram.domain.repository.UserRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.root.AppComponentContext - -interface BlockedUsersComponent { - val state: Value - val videoPlayerPool: VideoPlayerPool - fun onBackClicked() - fun onUnblockUserClicked(userId: Long) - fun onAddBlockedUserClicked() - fun onUserClicked(userId: Long) - - data class State( - val isLoading: Boolean = false, - val blockedUsers: List = emptyList() - ) -} - -class DefaultBlockedUsersComponent( - context: AppComponentContext, - private val onBack: () -> Unit, - private val onProfileClick: (Long) -> Unit, - private val onAddBlockedUser: () -> Unit -) : BlockedUsersComponent, AppComponentContext by context { - - private val privacyRepository: PrivacyRepository = container.repositories.privacyRepository - private val userRepository: UserRepository = container.repositories.userRepository - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - - private val _state = MutableValue(BlockedUsersComponent.State()) - override val state: Value = _state - private val scope = componentScope - - init { - loadBlockedUsers() - } - - private fun loadBlockedUsers() { - scope.launch { - _state.update { it.copy(isLoading = true) } - try { - val blockedIds = privacyRepository.getBlockedUsers() - val users = blockedIds.mapNotNull { id -> - try { - userRepository.getUser(id) - } catch (e: Exception) { - null - } - } - _state.update { it.copy(blockedUsers = users) } - } catch (e: Exception) { - // Handle error - } finally { - _state.update { it.copy(isLoading = false) } - } - } - } - - override fun onBackClicked() { - onBack() - } - - override fun onUnblockUserClicked(userId: Long) { - scope.launch { - try { - privacyRepository.unblockUser(userId) - loadBlockedUsers() - } catch (e: Exception) { - // Handle error - } - } - } - - override fun onAddBlockedUserClicked() { - onAddBlockedUser() - } - - override fun onUserClicked(userId: Long) { - onProfileClick(userId) - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/settings/privacy/BlockedUsersContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/privacy/BlockedUsersContent.kt deleted file mode 100644 index e6e93a78..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/privacy/BlockedUsersContent.kt +++ /dev/null @@ -1,271 +0,0 @@ -package org.monogram.presentation.settings.privacy - -import androidx.compose.animation.* -import androidx.compose.animation.core.EaseIn -import androidx.compose.animation.core.EaseOut -import androidx.compose.animation.core.tween -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.filled.Favorite -import androidx.compose.material.icons.rounded.Add -import androidx.compose.material.icons.rounded.MoreVert -import androidx.compose.material.icons.rounded.Verified -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.domain.models.UserModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun BlockedUsersContent(component: BlockedUsersComponent) { - val state by component.state.subscribeAsState() - - Scaffold( - topBar = { - TopAppBar( - title = { - Column { - Text( - text = stringResource(R.string.blocked_users_title), - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - if (state.blockedUsers.isNotEmpty()) { - Text( - text = stringResource(R.string.blocked_users_count_format, state.blockedUsers.size), - fontSize = 14.sp, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background - ) - ) - }, - floatingActionButton = { - FloatingActionButton( - onClick = component::onAddBlockedUserClicked, - containerColor = MaterialTheme.colorScheme.primary, - contentColor = MaterialTheme.colorScheme.onPrimary - ) { - Icon(Icons.Rounded.Add, contentDescription = stringResource(R.string.privacy_block_user_cd)) - } - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - AnimatedContent( - targetState = state.isLoading to state.blockedUsers.isEmpty(), - transitionSpec = { - fadeIn(animationSpec = tween(300, easing = EaseIn)) + - scaleIn(initialScale = 0.95f, animationSpec = tween(300, easing = EaseIn)) togetherWith - fadeOut(animationSpec = tween(200, easing = EaseOut)) - }, - label = "BlockedUsersContent", - modifier = Modifier - .fillMaxSize() - .padding(padding) - ) { (isLoading, isEmpty) -> - when { - isLoading -> { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator() - } - } - - isEmpty -> { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - Text( - text = stringResource(R.string.privacy_no_blocked_users), - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - - else -> { - LazyColumn( - modifier = Modifier.fillMaxSize(), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, top = 0.dp, bottom = 80.dp), - verticalArrangement = Arrangement.spacedBy(0.dp) - ) { - item { - Text( - text = stringResource(R.string.privacy_blocked_users_help), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(vertical = 16.dp, horizontal = 12.dp) - ) - } - - item { - state.blockedUsers.forEachIndexed { index, user -> - val position = when { - state.blockedUsers.size == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == state.blockedUsers.size - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - BlockedUserItem( - user = user, - position = position, - onUnblock = { component.onUnblockUserClicked(user.id) }, - onClick = { component.onUserClicked(user.id) }, - videoPlayerPool = component.videoPlayerPool - ) - } - } - } - } - } - } - } -} - -@Composable -fun BlockedUserItem( - user: UserModel, - position: ItemPosition, - videoPlayerPool: VideoPlayerPool, - onUnblock: () -> Unit, - onClick: () -> Unit -) { - var showMenu by remember { mutableStateOf(false) } - - val deletedText = stringResource(R.string.privacy_user_deleted) - val displayName = remember(user, deletedText) { - buildString { - if (user.firstName.isBlank()) { - append("${user.id} $deletedText") - } else { - append(user.firstName) - if (!user.lastName.isNullOrBlank()) { - append(" ") - append(user.lastName) - } - } - if (!user.username.isNullOrBlank()) { - append(" (@${user.username})") - } - } - } - - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - .clickable(onClick = onClick) - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Avatar( - path = user.avatarPath, - fallbackPath = user.personalAvatarPath, - name = user.firstName.ifBlank { "D" }, - size = 40.dp, - videoPlayerPool = videoPlayerPool - ) - Spacer(modifier = Modifier.width(16.dp)) - Row(modifier = Modifier.weight(1f), verticalAlignment = Alignment.CenterVertically) { - Text( - displayName, - style = MaterialTheme.typography.titleMedium, - fontSize = 16.sp, - modifier = Modifier.weight(1f, fill = false) - ) - if (user.isVerified) { - Spacer(Modifier.width(4.dp)) - Icon( - imageVector = Icons.Rounded.Verified, - contentDescription = stringResource(R.string.cd_verified), - modifier = Modifier.size(16.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - if (user.isSponsor) { - Spacer(Modifier.width(4.dp)) - Icon( - imageVector = Icons.Default.Favorite, - contentDescription = stringResource(R.string.cd_sponsor), - modifier = Modifier.size(16.dp), - tint = Color(0xFFE53935) - ) - } - } - Box { - IconButton(onClick = { showMenu = true }) { - Icon(Icons.Rounded.MoreVert, contentDescription = null) - } - DropdownMenu( - expanded = showMenu, - onDismissRequest = { showMenu = false } - ) { - DropdownMenuItem( - text = { Text(stringResource(R.string.privacy_unblock_action)) }, - onClick = { - onUnblock() - showMenu = false - } - ) - } - } - } - } - Spacer(Modifier.size(2.dp)) -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PasscodeComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/privacy/PasscodeComponent.kt deleted file mode 100644 index 3b23c8e6..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PasscodeComponent.kt +++ /dev/null @@ -1,50 +0,0 @@ -package org.monogram.presentation.settings.privacy - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import org.monogram.domain.repository.AppPreferencesProvider -import org.monogram.presentation.root.AppComponentContext - -interface PasscodeComponent { - val state: Value - fun onBackClicked() - fun onPasscodeEntered(passcode: String) - fun onClearPasscode() - - data class State( - val isPasscodeSet: Boolean = false, - val error: String? = null - ) -} - -class DefaultPasscodeComponent( - context: AppComponentContext, - private val onBack: () -> Unit -) : PasscodeComponent, AppComponentContext by context { - - private val appPreferences: AppPreferencesProvider = container.preferences.appPreferences - private val _state = MutableValue(PasscodeComponent.State(isPasscodeSet = appPreferences.passcode.value != null)) - override val state: Value = _state - - override fun onBackClicked() { - onBack() - } - - override fun onPasscodeEntered(passcode: String) { - if (passcode.length < 4) { - _state.update { it.copy(error = "Passcode must be at least 4 digits") } - return - } - appPreferences.setPasscode(passcode) - _state.update { it.copy(isPasscodeSet = true, error = null) } - onBack() - } - - override fun onClearPasscode() { - appPreferences.setPasscode(null) - appPreferences.setBiometricEnabled(false) - _state.update { it.copy(isPasscodeSet = false) } - onBack() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PasscodeContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/privacy/PasscodeContent.kt deleted file mode 100644 index 25b13eb1..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PasscodeContent.kt +++ /dev/null @@ -1,207 +0,0 @@ -package org.monogram.presentation.settings.privacy - -import androidx.activity.compose.BackHandler -import androidx.compose.animation.* -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.Lock -import androidx.compose.material.icons.rounded.LockOpen -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.onFocusChanged -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.text.input.PasswordVisualTransformation -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.presentation.R - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun PasscodeContent(component: PasscodeComponent) { - val state by component.state.subscribeAsState() - val focusManager = LocalFocusManager.current - var isFocused by remember { mutableStateOf(false) } - var passcode by remember { mutableStateOf("") } - - val isLocked = state.isPasscodeSet - val iconScale by animateFloatAsState(targetValue = if (isLocked) 1.2f else 1f, label = "iconScale") - - val isKeyboardVisible = WindowInsets.ime.getBottom(LocalDensity.current) > 0 - LaunchedEffect(isKeyboardVisible) { - if (!isKeyboardVisible && isFocused) { - focusManager.clearFocus() - } - } - - BackHandler(enabled = isFocused) { - focusManager.clearFocus() - } - - Scaffold( - topBar = { - TopAppBar( - title = { Text(stringResource(R.string.passcode_lock_title), fontWeight = FontWeight.Bold) }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.surface, - titleContentColor = MaterialTheme.colorScheme.onSurface - ) - ) - } - ) { padding -> - Column( - modifier = Modifier - .fillMaxSize() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null - ) { focusManager.clearFocus() } - .padding(padding) - .padding(24.dp) - .animateContentSize(), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Top - ) { - AnimatedVisibility( - visible = !isFocused, - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically() - ) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Spacer(modifier = Modifier.height(32.dp)) - Box( - modifier = Modifier - .size(80.dp * iconScale) - .background( - color = if (isLocked) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.secondaryContainer, - shape = CircleShape - ), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = if (isLocked) Icons.Rounded.Lock else Icons.Rounded.LockOpen, - contentDescription = null, - modifier = Modifier.size(40.dp * iconScale), - tint = if (isLocked) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.secondary - ) - } - Spacer(modifier = Modifier.height(24.dp)) - } - } - - Text( - text = if (state.isPasscodeSet) stringResource(R.string.passcode_change_title) else stringResource(R.string.passcode_set_title), - fontSize = if (isFocused) 20.sp else 24.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - - AnimatedVisibility( - visible = !isFocused, - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically() - ) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Spacer(modifier = Modifier.height(8.dp)) - Text( - text = if (state.isPasscodeSet) - stringResource(R.string.passcode_change_description) - else - stringResource(R.string.passcode_set_description), - color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center, - style = MaterialTheme.typography.bodyLarge - ) - } - } - - Spacer(modifier = Modifier.height(if (isFocused) 24.dp else 48.dp)) - - OutlinedTextField( - value = passcode, - onValueChange = { if (it.length <= 4 && it.all { char -> char.isDigit() }) passcode = it }, - label = { Text(stringResource(R.string.passcode_label)) }, - visualTransformation = PasswordVisualTransformation(), - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.NumberPassword), - modifier = Modifier - .fillMaxWidth() - .onFocusChanged { isFocused = it.isFocused }, - singleLine = true, - isError = state.error != null, - shape = MaterialTheme.shapes.medium, - colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = MaterialTheme.colorScheme.primary, - unfocusedBorderColor = MaterialTheme.colorScheme.outline - ), - leadingIcon = { - Icon(Icons.Rounded.Lock, contentDescription = null) - } - ) - - AnimatedVisibility( - visible = state.error != null, - enter = fadeIn(), - exit = fadeOut() - ) { - Text( - text = state.error ?: "", - color = MaterialTheme.colorScheme.error, - modifier = Modifier.padding(top = 8.dp), - style = MaterialTheme.typography.bodyMedium - ) - } - - Spacer(modifier = Modifier.height(if (isFocused) 24.dp else 32.dp)) - - Button( - onClick = { component.onPasscodeEntered(passcode) }, - modifier = Modifier - .fillMaxWidth() - .height(50.dp), - enabled = passcode.length == 4, - shape = MaterialTheme.shapes.medium - ) { - Text(stringResource(R.string.passcode_save_action), fontSize = 16.sp) - } - - if (state.isPasscodeSet) { - Spacer(modifier = Modifier.height(16.dp)) - OutlinedButton( - onClick = component::onClearPasscode, - modifier = Modifier - .fillMaxWidth() - .height(50.dp), - colors = ButtonDefaults.outlinedButtonColors( - contentColor = MaterialTheme.colorScheme.error - ), - border = androidx.compose.foundation.BorderStroke(1.dp, MaterialTheme.colorScheme.error), - shape = MaterialTheme.shapes.medium - ) { - Text(stringResource(R.string.passcode_off_action)) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacyComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacyComponent.kt deleted file mode 100644 index 730bccc2..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacyComponent.kt +++ /dev/null @@ -1,142 +0,0 @@ -package org.monogram.presentation.settings.privacy - -import com.arkivanov.decompose.router.stack.* -import com.arkivanov.decompose.value.Value -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.launch -import kotlinx.serialization.Serializable -import org.monogram.domain.repository.PrivacyKey -import org.monogram.domain.repository.PrivacyRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.root.AppComponentContext -import org.monogram.presentation.settings.privacy.userSelection.DefaultUserSelectionComponent -import org.monogram.presentation.settings.privacy.userSelection.UserSelectionComponent - -interface PrivacyComponent { - val childStack: Value> - - sealed class Child { - class ListChild(val component: PrivacyListComponent) : Child() - class SettingChild(val component: PrivacySettingComponent) : Child() - class BlockedUsersChild(val component: BlockedUsersComponent) : Child() - class UserSelectionChild(val component: UserSelectionComponent) : Child() - } -} - -class DefaultPrivacyComponent( - context: AppComponentContext, - private val onBack: () -> Unit, - private val onSessionsClick: () -> Unit, - private val onProfileClick: (Long) -> Unit, - private val onPasscodeClick: () -> Unit -) : PrivacyComponent, AppComponentContext by context { - - private val privacyRepository: PrivacyRepository = container.repositories.privacyRepository - private val navigation = StackNavigation() - private val scope = componentScope - - override val childStack: Value> = childStack( - source = navigation, - serializer = Config.serializer(), - initialConfiguration = Config.List, - handleBackButton = true, - childFactory = ::createChild - ) - - private fun createChild(config: Config, context: AppComponentContext): PrivacyComponent.Child = - when (config) { - is Config.List -> PrivacyComponent.Child.ListChild( - DefaultPrivacyListComponent( - context = context, - onBack = onBack, - onNavigateToPrivacySetting = { key -> navigation.push(Config.Setting(key)) }, - onNavigateToBlockedUsers = { navigation.push(Config.BlockedUsers) }, - onSessionsClick = onSessionsClick, - onPasscodeClick = onPasscodeClick - ) - ) - - is Config.Setting -> PrivacyComponent.Child.SettingChild( - DefaultPrivacySettingComponent( - context = context, - privacyKey = config.key, - onBack = { navigation.pop() }, - onProfileClick = onProfileClick, - onUserSelect = { isAllow -> navigation.push(Config.UserSelection(config.key, isAllow)) } - ) - ) - - is Config.BlockedUsers -> PrivacyComponent.Child.BlockedUsersChild( - DefaultBlockedUsersComponent( - context = context, - onBack = { navigation.pop() }, - onProfileClick = onProfileClick, - onAddBlockedUser = { navigation.push(Config.UserSelection(null, false)) } - ) - ) - - is Config.UserSelection -> PrivacyComponent.Child.UserSelectionChild( - DefaultUserSelectionComponent( - context = context, - onBack = { navigation.pop() }, - onUserSelected = { userId -> - navigation.pop() - scope.launch { - if (config.privacyKey != null) { - updatePrivacyRule(config.privacyKey, userId, config.isAllow) - } else { - privacyRepository.blockUser(userId) - } - } - } - ) - ) - } - - private suspend fun updatePrivacyRule(key: PrivacyKey, userId: Long, isAllow: Boolean) { - val rules = privacyRepository.getPrivacyRules(key).first() - val config = rules.toPrivacyRuleConfig() - - val allowUsers = config.allowUsers.toMutableList() - val disallowUsers = config.disallowUsers.toMutableList() - - if (isAllow) { - if (!allowUsers.contains(userId)) { - allowUsers.add(userId) - disallowUsers.remove(userId) - } - } else { - if (!disallowUsers.contains(userId)) { - disallowUsers.add(userId) - allowUsers.remove(userId) - } - } - - privacyRepository.setPrivacyRule( - key, - buildPrivacyRules( - key = key, - value = config.baseValue, - allowUsers = allowUsers, - disallowUsers = disallowUsers, - allowChats = config.allowChats, - disallowChats = config.disallowChats - ) - ) - } - - @Serializable - sealed class Config { - @Serializable - object List : Config() - - @Serializable - data class Setting(val key: PrivacyKey) : Config() - - @Serializable - object BlockedUsers : Config() - - @Serializable - data class UserSelection(val privacyKey: PrivacyKey?, val isAllow: Boolean) : Config() - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacyContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacyContent.kt deleted file mode 100644 index b853c1a7..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacyContent.kt +++ /dev/null @@ -1,23 +0,0 @@ -package org.monogram.presentation.settings.privacy - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import com.arkivanov.decompose.extensions.compose.stack.Children -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.presentation.settings.privacy.userSelection.UserSelectionContent - -@Composable -fun PrivacyContent(component: PrivacyComponent) { - val childStack by component.childStack.subscribeAsState() - - Children( - stack = childStack - ) { - when (val child = it.instance) { - is PrivacyComponent.Child.ListChild -> PrivacyListContent(child.component) - is PrivacyComponent.Child.SettingChild -> PrivacySettingContent(child.component) - is PrivacyComponent.Child.BlockedUsersChild -> BlockedUsersContent(child.component) - is PrivacyComponent.Child.UserSelectionChild -> UserSelectionContent(child.component) - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacyListComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacyListComponent.kt deleted file mode 100644 index b6c6cfe7..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacyListComponent.kt +++ /dev/null @@ -1,273 +0,0 @@ -package org.monogram.presentation.settings.privacy - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch -import org.monogram.domain.managers.DistrManager -import org.monogram.domain.models.PrivacyRule -import org.monogram.domain.models.PrivacyValue -import org.monogram.domain.repository.AppPreferencesProvider -import org.monogram.domain.repository.PrivacyKey -import org.monogram.domain.repository.PrivacyRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.root.AppComponentContext - -interface PrivacyListComponent { - val state: Value - fun onBackClicked() - fun onBlockedUsersClicked() - fun onPhoneNumberClicked() - fun onLastSeenClicked() - fun onProfilePhotoClicked() - fun onBioClicked() - fun onForwardedMessagesClicked() - fun onCallsClicked() - fun onGroupsAndChannelsClicked() - fun onTwoStepVerificationClicked() - fun onActiveSessionsClicked() - fun onDeleteAccountClicked(reason: String) - fun onAccountTtlChanged(days: Int) - fun onSensitiveContentChanged(enabled: Boolean) - fun onPasscodeClicked() - fun onPasscodeVerificationSubmitted(passcode: String) - fun onPasscodeVerificationDismissed() - fun onBiometricChanged(enabled: Boolean) - - data class State( - val isLoading: Boolean = false, - val phoneNumberPrivacy: PrivacyValue = PrivacyValue.EVERYBODY, - val lastSeenPrivacy: PrivacyValue = PrivacyValue.EVERYBODY, - val profilePhotoPrivacy: PrivacyValue = PrivacyValue.EVERYBODY, - val bioPrivacy: PrivacyValue = PrivacyValue.EVERYBODY, - val forwardedMessagesPrivacy: PrivacyValue = PrivacyValue.EVERYBODY, - val callsPrivacy: PrivacyValue = PrivacyValue.EVERYBODY, - val groupsAndChannelsPrivacy: PrivacyValue = PrivacyValue.EVERYBODY, - val blockedUsersCount: Int = 0, - val accountTtlDays: Int = 180, - val isTwoStepVerificationEnabled: Boolean = false, - val canShowSensitiveContent: Boolean = false, - val isSensitiveContentEnabled: Boolean = false, - val isPasscodeEnabled: Boolean = false, - val isPasscodeVerificationVisible: Boolean = false, - val isPasscodeVerificationInvalid: Boolean = false, - val isBiometricEnabled: Boolean = false, - val error: String? = null, - val isInstalledFromGooglePlay: Boolean = true - ) -} - -class DefaultPrivacyListComponent( - context: AppComponentContext, - private val onBack: () -> Unit, - private val onNavigateToPrivacySetting: (PrivacyKey) -> Unit, - private val onNavigateToBlockedUsers: () -> Unit, - private val onSessionsClick: () -> Unit, - private val onPasscodeClick: () -> Unit -) : PrivacyListComponent, AppComponentContext by context { - - private val privacyRepository: PrivacyRepository = container.repositories.privacyRepository - private val appPreferences: AppPreferencesProvider = container.preferences.appPreferences - private val distrManager: DistrManager = container.utils.distrManager() - - private val _state = MutableValue(PrivacyListComponent.State()) - override val state: Value = _state - private val scope = componentScope - - init { - loadPrivacySettings() - observePrivacyRules() - observeAppPreferences() - } - - private fun loadPrivacySettings() { - scope.launch { - _state.update { it.copy(isLoading = true) } - try { - val blockedUsers = privacyRepository.getBlockedUsers() - val ttl = privacyRepository.getAccountTtl() - val isTwoStepEnabled = privacyRepository.getPasswordState() - val canShowSensitive = privacyRepository.canShowSensitiveContent() - val isSensitiveEnabled = privacyRepository.isShowSensitiveContentEnabled() - - _state.update { - it.copy( - blockedUsersCount = blockedUsers.size, - accountTtlDays = ttl, - isTwoStepVerificationEnabled = isTwoStepEnabled, - canShowSensitiveContent = canShowSensitive, - isSensitiveContentEnabled = isSensitiveEnabled, - isInstalledFromGooglePlay = distrManager.isInstalledFromGooglePlay() - ) - } - } catch (e: Exception) { - // Handle error - } finally { - _state.update { it.copy(isLoading = false) } - } - } - } - - private fun observePrivacyRules() { - observeRule(PrivacyKey.PHONE_NUMBER) { rules -> - _state.update { it.copy(phoneNumberPrivacy = rules.toPrivacyValue()) } - } - observeRule(PrivacyKey.LAST_SEEN) { rules -> - _state.update { it.copy(lastSeenPrivacy = rules.toPrivacyValue()) } - } - observeRule(PrivacyKey.PROFILE_PHOTO) { rules -> - _state.update { it.copy(profilePhotoPrivacy = rules.toPrivacyValue()) } - } - observeRule(PrivacyKey.BIO) { rules -> - _state.update { it.copy(bioPrivacy = rules.toPrivacyValue()) } - } - observeRule(PrivacyKey.FORWARDED_MESSAGES) { rules -> - _state.update { it.copy(forwardedMessagesPrivacy = rules.toPrivacyValue()) } - } - observeRule(PrivacyKey.CALLS) { rules -> - _state.update { it.copy(callsPrivacy = rules.toPrivacyValue()) } - } - observeRule(PrivacyKey.GROUPS_AND_CHANNELS) { rules -> - _state.update { it.copy(groupsAndChannelsPrivacy = rules.toPrivacyValue()) } - } - } - - private fun observeAppPreferences() { - appPreferences.passcode.onEach { passcode -> - _state.update { it.copy(isPasscodeEnabled = passcode != null) } - }.launchIn(scope) - - appPreferences.isBiometricEnabled.onEach { enabled -> - _state.update { it.copy(isBiometricEnabled = enabled) } - }.launchIn(scope) - } - - private fun observeRule(key: PrivacyKey, onUpdate: (List) -> Unit) { - privacyRepository.getPrivacyRules(key) - .onEach { onUpdate(it) } - .launchIn(scope) - } - - override fun onBackClicked() { - onBack() - } - - override fun onBlockedUsersClicked() { - onNavigateToBlockedUsers() - } - - override fun onPhoneNumberClicked() { - onNavigateToPrivacySetting(PrivacyKey.PHONE_NUMBER) - } - - override fun onLastSeenClicked() { - onNavigateToPrivacySetting(PrivacyKey.LAST_SEEN) - } - - override fun onProfilePhotoClicked() { - onNavigateToPrivacySetting(PrivacyKey.PROFILE_PHOTO) - } - - override fun onBioClicked() { - onNavigateToPrivacySetting(PrivacyKey.BIO) - } - - override fun onForwardedMessagesClicked() { - onNavigateToPrivacySetting(PrivacyKey.FORWARDED_MESSAGES) - } - - override fun onCallsClicked() { - onNavigateToPrivacySetting(PrivacyKey.CALLS) - } - - override fun onGroupsAndChannelsClicked() { - onNavigateToPrivacySetting(PrivacyKey.GROUPS_AND_CHANNELS) - } - - override fun onTwoStepVerificationClicked() { - } - - override fun onActiveSessionsClicked() { - onSessionsClick() - } - - override fun onDeleteAccountClicked(reason: String) { - scope.launch { - _state.update { it.copy(isLoading = true, error = null) } - try { - privacyRepository.deleteAccount(reason, "") - onBack() - } catch (e: Exception) { - _state.update { it.copy(error = e.message) } - } finally { - _state.update { it.copy(isLoading = false) } - } - } - } - - override fun onAccountTtlChanged(days: Int) { - scope.launch { - try { - privacyRepository.setAccountTtl(days) - _state.update { it.copy(accountTtlDays = days) } - } catch (e: Exception) { - // Handle error - } - } - } - - override fun onSensitiveContentChanged(enabled: Boolean) { - scope.launch { - try { - privacyRepository.setShowSensitiveContent(enabled) - _state.update { it.copy(isSensitiveContentEnabled = enabled) } - } catch (e: Exception) { - // Handle error - } - } - } - - override fun onPasscodeClicked() { - if (_state.value.isPasscodeEnabled) { - _state.update { - it.copy( - isPasscodeVerificationVisible = true, - isPasscodeVerificationInvalid = false - ) - } - return - } - - onPasscodeClick() - } - - override fun onPasscodeVerificationSubmitted(passcode: String) { - val savedPasscode = appPreferences.passcode.value - if (savedPasscode == passcode) { - _state.update { - it.copy( - isPasscodeVerificationVisible = false, - isPasscodeVerificationInvalid = false - ) - } - onPasscodeClick() - } else { - _state.update { it.copy(isPasscodeVerificationInvalid = true) } - } - } - - override fun onPasscodeVerificationDismissed() { - _state.update { - it.copy( - isPasscodeVerificationVisible = false, - isPasscodeVerificationInvalid = false - ) - } - } - - override fun onBiometricChanged(enabled: Boolean) { - appPreferences.setBiometricEnabled(enabled) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacyListContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacyListContent.kt deleted file mode 100644 index 36db9983..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacyListContent.kt +++ /dev/null @@ -1,440 +0,0 @@ -package org.monogram.presentation.settings.privacy - -import android.widget.Toast -import androidx.compose.animation.AnimatedContent -import androidx.compose.animation.core.tween -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.togetherWith -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.text.input.PasswordVisualTransformation -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.domain.models.PrivacyValue -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsSwitchTile -import org.monogram.presentation.core.ui.SettingsTile - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun PrivacyListContent(component: PrivacyListComponent) { - val state by component.state.subscribeAsState() - val context = LocalContext.current - - val blueColor = Color(0xFF4285F4) - val greenColor = Color(0xFF34A853) - val orangeColor = Color(0xFFF9AB00) - val pinkColor = Color(0xFFFF6D66) - val tealColor = Color(0xFF00BFA5) - val purpleColor = Color(0xFFAF52DE) - val indigoColor = Color(0xFF536DFE) - val redColor = Color(0xFFFF3B30) - - var showTtlSheet by remember { mutableStateOf(false) } - var showDeleteConfirmation by remember { mutableStateOf(false) } - var verificationPasscode by remember { mutableStateOf("") } - - LaunchedEffect(state.isPasscodeVerificationVisible) { - if (!state.isPasscodeVerificationVisible) { - verificationPasscode = "" - } - } - - Scaffold( - modifier = Modifier.semantics { contentDescription = "PrivacyContent" }, - topBar = { - TopAppBar( - title = { - Text( - text = stringResource(R.string.privacy_security_header), - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background - ) - ) - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - AnimatedContent( - targetState = state.isLoading, - transitionSpec = { - fadeIn(animationSpec = tween(300)) togetherWith fadeOut(animationSpec = tween(300)) - }, - label = "PrivacyListContent", - modifier = Modifier - .fillMaxSize() - .padding(padding) - ) { isLoading -> - if (isLoading) { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator() - } - } else { - LazyColumn( - modifier = Modifier.fillMaxSize(), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, top = 0.dp, bottom = 16.dp), - verticalArrangement = Arrangement.spacedBy(16.dp) - ) { - item { - SectionHeader(stringResource(R.string.privacy_section_header)) - SettingsTile( - icon = Icons.Rounded.Block, - title = stringResource(R.string.blocked_users_title), - subtitle = if (state.blockedUsersCount > 0) stringResource( - R.string.blocked_users_count_format, - state.blockedUsersCount - ) else stringResource(R.string.none_label), - iconColor = redColor, - position = ItemPosition.TOP, - onClick = component::onBlockedUsersClicked - ) - SettingsTile( - icon = Icons.Rounded.Phone, - title = stringResource(R.string.phone_number_title), - subtitle = state.phoneNumberPrivacy.toUiString(), - iconColor = orangeColor, - position = ItemPosition.MIDDLE, - onClick = component::onPhoneNumberClicked - ) - SettingsTile( - icon = Icons.Rounded.AccessTime, - title = stringResource(R.string.last_seen_title), - subtitle = state.lastSeenPrivacy.toUiString(), - iconColor = blueColor, - position = ItemPosition.MIDDLE, - onClick = component::onLastSeenClicked - ) - SettingsTile( - icon = Icons.Rounded.Person, - title = stringResource(R.string.profile_photos_title), - subtitle = state.profilePhotoPrivacy.toUiString(), - iconColor = purpleColor, - position = ItemPosition.MIDDLE, - onClick = component::onProfilePhotoClicked - ) - SettingsTile( - icon = Icons.Rounded.Info, - title = stringResource(R.string.bio_label), - subtitle = state.bioPrivacy.toUiString(), - iconColor = tealColor, - position = ItemPosition.MIDDLE, - onClick = component::onBioClicked - ) - SettingsTile( - icon = Icons.Rounded.Forward, - title = stringResource(R.string.forwarded_messages_title), - subtitle = state.forwardedMessagesPrivacy.toUiString(), - iconColor = greenColor, - position = ItemPosition.MIDDLE, - onClick = component::onForwardedMessagesClicked - ) - SettingsTile( - icon = Icons.Rounded.Call, - title = stringResource(R.string.calls_title), - subtitle = state.callsPrivacy.toUiString(), - iconColor = indigoColor, - position = ItemPosition.MIDDLE, - onClick = component::onCallsClicked - ) - SettingsTile( - icon = Icons.Rounded.Group, - title = stringResource(R.string.groups_channels_title), - subtitle = state.groupsAndChannelsPrivacy.toUiString(), - iconColor = pinkColor, - position = ItemPosition.BOTTOM, - onClick = component::onGroupsAndChannelsClicked - ) - } - - item { - SectionHeader(stringResource(R.string.security_section_header)) - SettingsTile( - icon = Icons.Rounded.Lock, - title = stringResource(R.string.passcode_lock_title), - subtitle = if (state.isPasscodeEnabled) stringResource(R.string.on_label) else stringResource( - R.string.off_label - ), - iconColor = blueColor, - position = ItemPosition.TOP, - onClick = component::onPasscodeClicked - ) - if (state.isPasscodeEnabled) { - SettingsSwitchTile( - icon = Icons.Rounded.Fingerprint, - title = stringResource(R.string.biometric_unlock_title), - subtitle = stringResource(R.string.biometric_unlock_subtitle), - iconColor = greenColor, - checked = state.isBiometricEnabled, - position = ItemPosition.MIDDLE, - onCheckedChange = component::onBiometricChanged - ) - } - SettingsTile( - icon = Icons.Rounded.Security, - title = stringResource(R.string.two_step_verification_title), - subtitle = if (state.isTwoStepVerificationEnabled) stringResource(R.string.on_label) else stringResource( - R.string.off_label - ), - iconColor = greenColor, - position = if (state.isPasscodeEnabled) ItemPosition.MIDDLE else ItemPosition.MIDDLE, - onClick = { - Toast.makeText(context, context.getString(R.string.not_implemented), Toast.LENGTH_SHORT) - .show() - } - ) - SettingsTile( - icon = Icons.Rounded.Devices, - title = stringResource(R.string.active_sessions_title), - subtitle = stringResource(R.string.active_sessions_subtitle), - iconColor = orangeColor, - position = ItemPosition.BOTTOM, - onClick = component::onActiveSessionsClicked - ) - } - - if (state.canShowSensitiveContent && !state.isInstalledFromGooglePlay) { - item { - SectionHeader(stringResource(R.string.sensitive_content_header)) - SettingsSwitchTile( - icon = Icons.Rounded.Visibility, - title = stringResource(R.string.disable_filtering_title), - subtitle = stringResource(R.string.disable_filtering_subtitle), - iconColor = pinkColor, - checked = state.isSensitiveContentEnabled, - position = ItemPosition.STANDALONE, - onCheckedChange = component::onSensitiveContentChanged - ) - } - } - - item { - SectionHeader(stringResource(R.string.advanced_section_header)) - SettingsTile( - icon = Icons.Rounded.DeleteForever, - title = stringResource(R.string.delete_my_account_title), - subtitle = stringResource( - R.string.delete_my_account_subtitle, - state.accountTtlDays.toTtlString() - ), - iconColor = purpleColor, - position = ItemPosition.TOP, - onClick = { showTtlSheet = true } - ) - SettingsTile( - icon = Icons.Rounded.Warning, - title = stringResource(R.string.delete_account_now_title), - subtitle = stringResource(R.string.delete_account_now_subtitle), - iconColor = redColor, - position = ItemPosition.BOTTOM, - onClick = { showDeleteConfirmation = true } - ) - } - - item { Spacer(modifier = Modifier.height(16.dp)) } - } - } - } - } - - if (showTtlSheet) { - ModalBottomSheet( - onDismissRequest = { showTtlSheet = false }, - containerColor = MaterialTheme.colorScheme.background, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp), - dragHandle = { BottomSheetDefaults.DragHandle() } - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 32.dp) - ) { - Text( - text = stringResource(R.string.self_destruct_title), - style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold), - modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp) - ) - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - ) { - Column(modifier = Modifier.padding(vertical = 8.dp)) { - val options = listOf(30, 90, 180, 365, 548, 720) - options.forEachIndexed { index, days -> - ListItem( - headlineContent = { Text(days.toTtlString()) }, - trailingContent = { - RadioButton( - selected = state.accountTtlDays == days, - onClick = null - ) - }, - modifier = Modifier.clickable { - component.onAccountTtlChanged(days) - showTtlSheet = false - }, - colors = ListItemDefaults.colors( - containerColor = Color.Transparent - ) - ) - if (index < options.size - 1) { - HorizontalDivider( - modifier = Modifier.padding(horizontal = 16.dp), - thickness = 0.5.dp, - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - } - } - } - } - } - } - } - - if (showDeleteConfirmation) { - AlertDialog( - onDismissRequest = { showDeleteConfirmation = false }, - title = { Text(stringResource(R.string.delete_account_confirmation_title)) }, - text = { Text(stringResource(R.string.delete_account_confirmation_message)) }, - confirmButton = { - TextButton( - onClick = { - component.onDeleteAccountClicked("User requested deletion") - showDeleteConfirmation = false - }, - colors = ButtonDefaults.textButtonColors(contentColor = MaterialTheme.colorScheme.error) - ) { - Text(stringResource(R.string.action_delete)) - } - }, - dismissButton = { - TextButton(onClick = { showDeleteConfirmation = false }) { - Text(stringResource(R.string.cancel_button)) - } - } - ) - } - - if (state.isPasscodeVerificationVisible) { - AlertDialog( - onDismissRequest = component::onPasscodeVerificationDismissed, - title = { Text(stringResource(R.string.passcode_verify_title)) }, - text = { - Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { - Text(stringResource(R.string.passcode_verify_description)) - OutlinedTextField( - value = verificationPasscode, - onValueChange = { - if (it.length <= 4 && it.all(Char::isDigit)) { - verificationPasscode = it - } - }, - label = { Text(stringResource(R.string.passcode_current_label)) }, - visualTransformation = PasswordVisualTransformation(), - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.NumberPassword), - singleLine = true, - isError = state.isPasscodeVerificationInvalid, - modifier = Modifier.fillMaxWidth() - ) - if (state.isPasscodeVerificationInvalid) { - Text( - text = stringResource(R.string.passcode_verify_error), - color = MaterialTheme.colorScheme.error, - style = MaterialTheme.typography.bodySmall - ) - } - } - }, - confirmButton = { - TextButton( - onClick = { component.onPasscodeVerificationSubmitted(verificationPasscode) }, - enabled = verificationPasscode.length == 4 - ) { - Text(stringResource(R.string.confirm_button)) - } - }, - dismissButton = { - TextButton(onClick = component::onPasscodeVerificationDismissed) { - Text(stringResource(R.string.cancel_button)) - } - } - ) - } -} - -@Composable -private fun SectionHeader(text: String) { - Text( - text = text, - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp, top = 16.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) -} - -@Composable -private fun Int.toTtlString(): String { - return when (this) { - 30 -> stringResource(R.string.ttl_1_month) - 90 -> stringResource(R.string.ttl_3_months) - 180 -> stringResource(R.string.ttl_6_months) - 365 -> stringResource(R.string.ttl_1_year) - 548 -> stringResource(R.string.ttl_18_months) - 720 -> stringResource(R.string.ttl_2_years) - 730 -> stringResource(R.string.ttl_2_years) - else -> if (this % 30 == 0) { - stringResource(R.string.ttl_months_format, this / 30) - } else { - stringResource(R.string.ttl_days_format, this) - } - } -} - -@Composable -private fun PrivacyValue.toUiString(): String { - return when (this) { - PrivacyValue.EVERYBODY -> stringResource(R.string.privacy_everybody) - PrivacyValue.MY_CONTACTS -> stringResource(R.string.privacy_my_contacts) - PrivacyValue.NOBODY -> stringResource(R.string.privacy_nobody) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacyRuleValueMapper.kt b/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacyRuleValueMapper.kt deleted file mode 100644 index 74dd5483..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacyRuleValueMapper.kt +++ /dev/null @@ -1,83 +0,0 @@ -package org.monogram.presentation.settings.privacy - -import org.monogram.domain.models.PrivacyRule -import org.monogram.domain.models.PrivacyValue -import org.monogram.domain.repository.PrivacyKey - -internal data class PrivacyRuleConfig( - val baseValue: PrivacyValue, - val allowUsers: List = emptyList(), - val disallowUsers: List = emptyList(), - val allowChats: List = emptyList(), - val disallowChats: List = emptyList() -) - -internal fun List.toPrivacyValue(): PrivacyValue { - return when { - any { it is PrivacyRule.AllowAll } -> PrivacyValue.EVERYBODY - any { it is PrivacyRule.AllowContacts } -> PrivacyValue.MY_CONTACTS - any { it is PrivacyRule.AllowNone } -> PrivacyValue.NOBODY - any { it is PrivacyRule.DisallowContacts || it is PrivacyRule.DisallowUsers || it is PrivacyRule.DisallowChatMembers } -> PrivacyValue.EVERYBODY - any { it is PrivacyRule.AllowUsers || it is PrivacyRule.AllowChatMembers } -> PrivacyValue.NOBODY - else -> PrivacyValue.EVERYBODY - } -} - -internal fun List.toPrivacyRuleConfig(): PrivacyRuleConfig { - val allowUsers = mutableListOf() - val disallowUsers = mutableListOf() - val allowChats = mutableListOf() - val disallowChats = mutableListOf() - - forEach { rule -> - when (rule) { - is PrivacyRule.AllowUsers -> allowUsers.addAll(rule.userIds) - is PrivacyRule.DisallowUsers -> disallowUsers.addAll(rule.userIds) - is PrivacyRule.AllowChatMembers -> allowChats.addAll(rule.chatIds) - is PrivacyRule.DisallowChatMembers -> disallowChats.addAll(rule.chatIds) - else -> Unit - } - } - - return PrivacyRuleConfig( - baseValue = toPrivacyValue(), - allowUsers = allowUsers, - disallowUsers = disallowUsers, - allowChats = allowChats, - disallowChats = disallowChats - ) -} - -internal fun buildPrivacyRules( - key: PrivacyKey, - value: PrivacyValue, - allowUsers: List, - disallowUsers: List, - allowChats: List, - disallowChats: List -): List { - return buildList { - if (allowUsers.isNotEmpty()) add(PrivacyRule.AllowUsers(allowUsers)) - if (disallowUsers.isNotEmpty()) add(PrivacyRule.DisallowUsers(disallowUsers)) - if (allowChats.isNotEmpty()) add(PrivacyRule.AllowChatMembers(allowChats)) - if (disallowChats.isNotEmpty()) add(PrivacyRule.DisallowChatMembers(disallowChats)) - - when (value) { - PrivacyValue.EVERYBODY -> add(PrivacyRule.AllowAll) - PrivacyValue.MY_CONTACTS -> { - add(PrivacyRule.AllowContacts) - if (key != PrivacyKey.PHONE_NUMBER_SEARCH) { - add(PrivacyRule.AllowNone) - } - } - - PrivacyValue.NOBODY -> { - if (key == PrivacyKey.PHONE_NUMBER_SEARCH) { - add(PrivacyRule.AllowContacts) - } else { - add(PrivacyRule.AllowNone) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacySettingComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacySettingComponent.kt deleted file mode 100644 index 762bb2c4..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacySettingComponent.kt +++ /dev/null @@ -1,237 +0,0 @@ -package org.monogram.presentation.settings.privacy - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch -import org.monogram.domain.models.ChatModel -import org.monogram.domain.models.PrivacyValue -import org.monogram.domain.models.UserModel -import org.monogram.domain.repository.ChatsListRepository -import org.monogram.domain.repository.PrivacyKey -import org.monogram.domain.repository.PrivacyRepository -import org.monogram.domain.repository.UserRepository -import org.monogram.presentation.R -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.root.AppComponentContext - -interface PrivacySettingComponent { - val state: Value - val videoPlayerPool: VideoPlayerPool - fun onBackClicked() - fun onPrivacyValueChanged(value: PrivacyValue) - fun onSearchPrivacyValueChanged(value: PrivacyValue) - fun onAddExceptionClicked(isAllow: Boolean) - fun onUserClicked(userId: Long) - fun onRemoveUser(userId: Long, isAllow: Boolean) - fun onRemoveChat(chatId: Long, isAllow: Boolean) - - data class State( - val titleRes: Int, - val privacyKey: PrivacyKey, - val selectedValue: PrivacyValue = PrivacyValue.EVERYBODY, - val searchSelectedValue: PrivacyValue = PrivacyValue.EVERYBODY, - val allowUsers: List = emptyList(), - val disallowUsers: List = emptyList(), - val allowChats: List = emptyList(), - val disallowChats: List = emptyList(), - val isLoading: Boolean = false - ) -} - -class DefaultPrivacySettingComponent( - context: AppComponentContext, - private val privacyKey: PrivacyKey, - private val onBack: () -> Unit, - private val onProfileClick: (Long) -> Unit, - private val onUserSelect: (Boolean) -> Unit -) : PrivacySettingComponent, AppComponentContext by context { - - private val userRepository: UserRepository = container.repositories.userRepository - private val privacyRepository: PrivacyRepository = container.repositories.privacyRepository - private val chatsRepository: ChatsListRepository = container.repositories.chatsListRepository - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - - private val _state = - MutableValue(PrivacySettingComponent.State(titleRes = getTitleRes(privacyKey), privacyKey = privacyKey)) - override val state: Value = _state - private val scope = componentScope - - init { - observePrivacyRules() - if (privacyKey == PrivacyKey.PHONE_NUMBER) { - observeSearchPrivacyRules() - } - } - - private fun observePrivacyRules() { - privacyRepository.getPrivacyRules(privacyKey) - .onEach { rules -> - val config = rules.toPrivacyRuleConfig() - - val allowUsers = config.allowUsers.mapNotNull { id -> - try { - userRepository.getUser(id) - } catch (e: Exception) { - null - } - } - - val disallowUsers = config.disallowUsers.mapNotNull { id -> - try { - userRepository.getUser(id) - } catch (e: Exception) { - null - } - } - - val allowChats = config.allowChats.mapNotNull { id -> - try { - chatsRepository.getChatById(id) - } catch (e: Exception) { - null - } - } - - val disallowChats = config.disallowChats.mapNotNull { id -> - try { - chatsRepository.getChatById(id) - } catch (e: Exception) { - null - } - } - - _state.update { - it.copy( - selectedValue = config.baseValue, - allowUsers = allowUsers, - disallowUsers = disallowUsers, - allowChats = allowChats, - disallowChats = disallowChats - ) - } - } - .launchIn(scope) - } - - private fun observeSearchPrivacyRules() { - privacyRepository.getPrivacyRules(PrivacyKey.PHONE_NUMBER_SEARCH) - .onEach { rules -> - _state.update { it.copy(searchSelectedValue = rules.toPrivacyValue()) } - } - .launchIn(scope) - } - - override fun onBackClicked() { - onBack() - } - - override fun onPrivacyValueChanged(value: PrivacyValue) { - scope.launch { - val currentAllowUsers = _state.value.allowUsers.map { it.id } - val currentDisallowUsers = _state.value.disallowUsers.map { it.id } - val currentAllowChats = _state.value.allowChats.map { it.id } - val currentDisallowChats = _state.value.disallowChats.map { it.id } - updateRules( - privacyKey, - currentAllowUsers, - currentDisallowUsers, - currentAllowChats, - currentDisallowChats, - value - ) - } - } - - override fun onSearchPrivacyValueChanged(value: PrivacyValue) { - scope.launch { - updateRules(PrivacyKey.PHONE_NUMBER_SEARCH, emptyList(), emptyList(), emptyList(), emptyList(), value) - } - } - - override fun onAddExceptionClicked(isAllow: Boolean) { - onUserSelect(isAllow) - } - - override fun onUserClicked(userId: Long) { - onProfileClick(userId) - } - - override fun onRemoveUser(userId: Long, isAllow: Boolean) { - scope.launch { - val currentAllowUsers = _state.value.allowUsers.map { it.id }.toMutableList() - val currentDisallowUsers = _state.value.disallowUsers.map { it.id }.toMutableList() - val currentAllowChats = _state.value.allowChats.map { it.id } - val currentDisallowChats = _state.value.disallowChats.map { it.id } - - if (isAllow) { - currentAllowUsers.remove(userId) - } else { - currentDisallowUsers.remove(userId) - } - - updateRules( - privacyKey, - currentAllowUsers, - currentDisallowUsers, - currentAllowChats, - currentDisallowChats, - _state.value.selectedValue - ) - } - } - - override fun onRemoveChat(chatId: Long, isAllow: Boolean) { - scope.launch { - val currentAllowUsers = _state.value.allowUsers.map { it.id } - val currentDisallowUsers = _state.value.disallowUsers.map { it.id } - val currentAllowChats = _state.value.allowChats.map { it.id }.toMutableList() - val currentDisallowChats = _state.value.disallowChats.map { it.id }.toMutableList() - - if (isAllow) { - currentAllowChats.remove(chatId) - } else { - currentDisallowChats.remove(chatId) - } - - updateRules( - privacyKey, - currentAllowUsers, - currentDisallowUsers, - currentAllowChats, - currentDisallowChats, - _state.value.selectedValue - ) - } - } - - private suspend fun updateRules( - key: PrivacyKey, - allowUsers: List, - disallowUsers: List, - allowChats: List, - disallowChats: List, - value: PrivacyValue - ) { - privacyRepository.setPrivacyRule( - key, - buildPrivacyRules(key, value, allowUsers, disallowUsers, allowChats, disallowChats) - ) - } - - private fun getTitleRes(key: PrivacyKey): Int { - return when (key) { - PrivacyKey.PHONE_NUMBER -> R.string.phone_number_title - PrivacyKey.PHONE_NUMBER_SEARCH -> R.string.privacy_phone_number_search_title - PrivacyKey.LAST_SEEN -> R.string.last_seen_title - PrivacyKey.PROFILE_PHOTO -> R.string.profile_photos_title - PrivacyKey.BIO -> R.string.bio_label - PrivacyKey.FORWARDED_MESSAGES -> R.string.forwarded_messages_title - PrivacyKey.CALLS -> R.string.calls_title - PrivacyKey.GROUPS_AND_CHANNELS -> R.string.groups_channels_title - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacySettingContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacySettingContent.kt deleted file mode 100644 index 6d58e267..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/privacy/PrivacySettingContent.kt +++ /dev/null @@ -1,468 +0,0 @@ -package org.monogram.presentation.settings.privacy - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.Add -import androidx.compose.material.icons.rounded.Check -import androidx.compose.material.icons.rounded.Close -import androidx.compose.material.icons.rounded.RemoveCircle -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.domain.models.ChatModel -import org.monogram.domain.models.PrivacyValue -import org.monogram.domain.models.UserModel -import org.monogram.domain.models.UserStatusType -import org.monogram.domain.repository.PrivacyKey -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsTile - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun PrivacySettingContent(component: PrivacySettingComponent) { - val state by component.state.subscribeAsState() - - val greenColor = Color(0xFF34A853) - val redColor = Color(0xFFFF3B30) - val isPhoneNumberPrivacy = state.privacyKey == PrivacyKey.PHONE_NUMBER - val isPhoneNumberSearchPrivacy = state.privacyKey == PrivacyKey.PHONE_NUMBER_SEARCH - val mainSectionTitle = when (state.privacyKey) { - PrivacyKey.PHONE_NUMBER -> stringResource(R.string.privacy_who_can_see_my_phone_number) - PrivacyKey.PHONE_NUMBER_SEARCH -> stringResource(R.string.privacy_who_can_find_me_by_number) - PrivacyKey.LAST_SEEN -> stringResource(R.string.privacy_who_can_see_my_last_seen) - PrivacyKey.PROFILE_PHOTO -> stringResource(R.string.privacy_who_can_see_my_profile_photos) - PrivacyKey.BIO -> stringResource(R.string.privacy_who_can_see_my_bio) - PrivacyKey.FORWARDED_MESSAGES -> stringResource(R.string.privacy_who_can_link_my_account_in_forwarded_messages) - PrivacyKey.CALLS -> stringResource(R.string.privacy_who_can_call_me) - PrivacyKey.GROUPS_AND_CHANNELS -> stringResource(R.string.privacy_who_can_add_me_to_groups_and_channels) - } - - Scaffold( - topBar = { - TopAppBar( - title = { - Text( - text = stringResource(state.titleRes), - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background - ) - ) - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - LazyColumn( - modifier = Modifier - .fillMaxSize() - .padding(top = padding.calculateTopPadding()), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, top = 0.dp, bottom = 16.dp), - verticalArrangement = Arrangement.spacedBy(16.dp) - ) { - item { - SectionHeader(mainSectionTitle) - PrivacyOption( - title = stringResource(R.string.privacy_everybody), - selected = state.selectedValue == PrivacyValue.EVERYBODY, - position = ItemPosition.TOP, - onClick = { component.onPrivacyValueChanged(PrivacyValue.EVERYBODY) } - ) - PrivacyOption( - title = stringResource(R.string.privacy_my_contacts), - selected = state.selectedValue == PrivacyValue.MY_CONTACTS, - position = if (isPhoneNumberSearchPrivacy) ItemPosition.BOTTOM else ItemPosition.MIDDLE, - onClick = { component.onPrivacyValueChanged(PrivacyValue.MY_CONTACTS) } - ) - - if (!isPhoneNumberSearchPrivacy) { - PrivacyOption( - title = stringResource(R.string.privacy_nobody), - selected = state.selectedValue == PrivacyValue.NOBODY, - position = ItemPosition.BOTTOM, - onClick = { component.onPrivacyValueChanged(PrivacyValue.NOBODY) } - ) - } - } - - if (isPhoneNumberPrivacy) { - item { - SectionHeader(stringResource(R.string.privacy_who_can_find_me_by_number)) - PrivacyOption( - title = stringResource(R.string.privacy_everybody), - selected = state.searchSelectedValue == PrivacyValue.EVERYBODY, - position = ItemPosition.TOP, - onClick = { component.onSearchPrivacyValueChanged(PrivacyValue.EVERYBODY) } - ) - PrivacyOption( - title = stringResource(R.string.privacy_my_contacts), - selected = state.searchSelectedValue == PrivacyValue.MY_CONTACTS, - position = ItemPosition.BOTTOM, - onClick = { component.onSearchPrivacyValueChanged(PrivacyValue.MY_CONTACTS) } - ) - Text( - text = stringResource(R.string.privacy_phone_number_search_help), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(vertical = 8.dp, horizontal = 12.dp) - ) - } - } - - if (!isPhoneNumberSearchPrivacy) { - item { - SectionHeader(stringResource(R.string.privacy_add_exceptions)) - val showAlways = state.selectedValue != PrivacyValue.EVERYBODY - val showNever = state.selectedValue != PrivacyValue.NOBODY - - if (showAlways) { - val total = state.allowUsers.size + state.allowChats.size - SettingsTile( - icon = Icons.Rounded.Add, - title = stringResource(R.string.privacy_always_allow), - subtitle = if (total > 0) stringResource( - R.string.privacy_exceptions_count_format, - total - ) else null, - iconColor = greenColor, - position = if (showNever) ItemPosition.TOP else ItemPosition.STANDALONE, - onClick = { component.onAddExceptionClicked(true) } - ) - } - - if (showNever) { - val total = state.disallowUsers.size + state.disallowChats.size - SettingsTile( - icon = Icons.Rounded.RemoveCircle, - title = stringResource(R.string.privacy_never_allow), - subtitle = if (total > 0) stringResource( - R.string.privacy_exceptions_count_format, - total - ) else null, - iconColor = redColor, - position = if (showAlways) ItemPosition.BOTTOM else ItemPosition.STANDALONE, - onClick = { component.onAddExceptionClicked(false) } - ) - } - } - } - - if (!isPhoneNumberSearchPrivacy && (state.allowUsers.isNotEmpty() || state.allowChats.isNotEmpty())) { - item { - SectionHeader(stringResource(R.string.privacy_always_allow)) - val totalItems = state.allowUsers.size + state.allowChats.size - var currentIndex = 0 - - state.allowUsers.forEach { user -> - val position = when { - totalItems == 1 -> ItemPosition.STANDALONE - currentIndex == 0 -> ItemPosition.TOP - currentIndex == totalItems - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - ExceptionUserItem( - user = user, - position = position, - onClick = { component.onUserClicked(user.id) }, - onRemove = { component.onRemoveUser(user.id, true) }, - videoPlayerPool = component.videoPlayerPool - ) - currentIndex++ - } - state.allowChats.forEach { chat -> - val position = when { - totalItems == 1 -> ItemPosition.STANDALONE - currentIndex == 0 -> ItemPosition.TOP - currentIndex == totalItems - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - ExceptionChatItem( - chat = chat, - position = position, - onRemove = { component.onRemoveChat(chat.id, true) }, - videoPlayerPool = component.videoPlayerPool - ) - currentIndex++ - } - } - } - - if (!isPhoneNumberSearchPrivacy && (state.disallowUsers.isNotEmpty() || state.disallowChats.isNotEmpty())) { - item { - SectionHeader(stringResource(R.string.privacy_never_allow)) - val totalItems = state.disallowUsers.size + state.disallowChats.size - var currentIndex = 0 - - state.disallowUsers.forEach { user -> - val position = when { - totalItems == 1 -> ItemPosition.STANDALONE - currentIndex == 0 -> ItemPosition.TOP - currentIndex == totalItems - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - ExceptionUserItem( - user = user, - position = position, - onClick = { component.onUserClicked(user.id) }, - onRemove = { component.onRemoveUser(user.id, false) }, - videoPlayerPool = component.videoPlayerPool - ) - currentIndex++ - } - state.disallowChats.forEach { chat -> - val position = when { - totalItems == 1 -> ItemPosition.STANDALONE - currentIndex == 0 -> ItemPosition.TOP - currentIndex == totalItems - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - ExceptionChatItem( - chat = chat, - position = position, - onRemove = { component.onRemoveChat(chat.id, false) }, - videoPlayerPool = component.videoPlayerPool - ) - currentIndex++ - } - } - } - item { Spacer(modifier = Modifier.height(padding.calculateBottomPadding()-16.dp)) } - } - } -} - -@Composable -fun ExceptionUserItem( - user: UserModel, - position: ItemPosition, - videoPlayerPool: VideoPlayerPool, - onClick: () -> Unit, - onRemove: () -> Unit -) { - val deletedText = stringResource(R.string.privacy_user_deleted) - val displayName = remember(user, deletedText) { - buildString { - if (user.firstName.isBlank()) { - append("${user.id} $deletedText") - } else { - append(user.firstName) - if (!user.lastName.isNullOrBlank()) { - append(" ") - append(user.lastName) - } - } - if (!user.username.isNullOrBlank()) { - append(" (@${user.username})") - } - } - } - - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - .clickable(onClick = onClick) - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Avatar( - path = user.avatarPath, - fallbackPath = user.personalAvatarPath, - name = user.firstName.ifBlank { "D" }, - size = 40.dp, - isOnline = user.userStatus == UserStatusType.ONLINE, - videoPlayerPool = videoPlayerPool - ) - Spacer(modifier = Modifier.width(16.dp)) - Column(modifier = Modifier.weight(1f)) { - Text(text = displayName, style = MaterialTheme.typography.titleMedium, fontSize = 16.sp) - } - IconButton(onClick = onRemove) { - Icon(Icons.Rounded.Close, contentDescription = stringResource(R.string.action_delete)) - } - } - } - Spacer(Modifier.size(2.dp)) -} - -@Composable -fun ExceptionChatItem( - chat: ChatModel, - position: ItemPosition, - videoPlayerPool: VideoPlayerPool, - onRemove: () -> Unit -) { - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Avatar( - path = chat.avatarPath, - fallbackPath = chat.personalAvatarPath, - name = chat.title.take(1), - size = 40.dp, - videoPlayerPool = videoPlayerPool - ) - Spacer(modifier = Modifier.width(16.dp)) - Column(modifier = Modifier.weight(1f)) { - Text(text = chat.title, style = MaterialTheme.typography.titleMedium, fontSize = 16.sp) - Text( - text = stringResource(R.string.privacy_chat_members), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - IconButton(onClick = onRemove) { - Icon(Icons.Rounded.Close, contentDescription = stringResource(R.string.action_delete)) - } - } - } - Spacer(Modifier.size(2.dp)) -} - -@Composable -fun PrivacyOption( - title: String, - selected: Boolean, - position: ItemPosition, - onClick: () -> Unit -) { - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - .clickable(onClick = onClick) - ) { - Row( - modifier = Modifier.padding(horizontal = 16.dp, vertical = 16.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = title, - style = MaterialTheme.typography.titleMedium, - fontSize = 18.sp, - modifier = Modifier.weight(1f) - ) - if (selected) { - Icon( - imageVector = Icons.Rounded.Check, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary - ) - } - } - } - Spacer(Modifier.size(2.dp)) -} - -@Composable -private fun SectionHeader(text: String) { - Text( - text = text, - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp, top = 16.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/privacy/userSelection/DefaultUserSelectionComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/privacy/userSelection/DefaultUserSelectionComponent.kt deleted file mode 100644 index 03f86218..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/privacy/userSelection/DefaultUserSelectionComponent.kt +++ /dev/null @@ -1,89 +0,0 @@ -package org.monogram.presentation.settings.privacy.userSelection - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.async -import kotlinx.coroutines.Job -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import org.monogram.domain.repository.UserRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.root.AppComponentContext - -class DefaultUserSelectionComponent( - context: AppComponentContext, - private val onBack: () -> Unit, - private val onUserSelected: (Long) -> Unit -) : UserSelectionComponent, AppComponentContext by context { - - private val userRepository: UserRepository = container.repositories.userRepository - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - - private val _state = MutableValue(UserSelectionComponent.State()) - override val state: Value = _state - private val scope = componentScope - private var searchJob: Job? = null - - init { - loadContacts() - } - - private fun loadContacts() { - scope.launch { - _state.update { it.copy(isLoading = true) } - try { - val contacts = userRepository.getContacts() - _state.update { it.copy(users = contacts) } - } catch (_: Exception) { - _state.update { it.copy(users = emptyList()) } - } finally { - _state.update { it.copy(isLoading = false) } - } - } - } - - override fun onBackClicked() { - onBack() - } - - override fun onSearchQueryChanged(query: String) { - _state.update { it.copy(searchQuery = query) } - searchJob?.cancel() - - if (query.isBlank()) { - loadContacts() - return - } - - searchJob = scope.launch { - delay(500) // Debounce - _state.update { it.copy(isLoading = true) } - try { - val contactsDeferred = async { userRepository.searchContacts(query) } - val directUserDeferred = async { - query.toLongOrNull()?.let { userRepository.getUser(it) } - } - - val results = LinkedHashMap() - contactsDeferred.await().forEach { user -> - results[user.id] = user - } - directUserDeferred.await()?.let { user -> - results[user.id] = user - } - - _state.update { it.copy(users = results.values.toList()) } - } catch (e: Exception) { - _state.update { it.copy(users = emptyList()) } - } finally { - _state.update { it.copy(isLoading = false) } - } - } - } - - override fun onUserClicked(userId: Long) { - onUserSelected(userId) - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/privacy/userSelection/UserSelectionComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/privacy/userSelection/UserSelectionComponent.kt deleted file mode 100644 index 976c4ca9..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/privacy/userSelection/UserSelectionComponent.kt +++ /dev/null @@ -1,19 +0,0 @@ -package org.monogram.presentation.settings.privacy.userSelection - -import com.arkivanov.decompose.value.Value -import org.monogram.domain.models.UserModel -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -interface UserSelectionComponent { - val state: Value - val videoPlayerPool: VideoPlayerPool - fun onBackClicked() - fun onSearchQueryChanged(query: String) - fun onUserClicked(userId: Long) - - data class State( - val searchQuery: String = "", - val users: List = emptyList(), - val isLoading: Boolean = false - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/privacy/userSelection/UserSelectionContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/privacy/userSelection/UserSelectionContent.kt deleted file mode 100644 index 0d6d2cf3..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/privacy/userSelection/UserSelectionContent.kt +++ /dev/null @@ -1,196 +0,0 @@ -package org.monogram.presentation.settings.privacy.userSelection - -import androidx.compose.animation.* -import androidx.compose.animation.core.EaseIn -import androidx.compose.animation.core.EaseOut -import androidx.compose.animation.core.tween -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.filled.Favorite -import androidx.compose.material.icons.rounded.Verified -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.domain.models.UserModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.ui.SettingsGroup -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun UserSelectionContent(component: UserSelectionComponent) { - val state by component.state.subscribeAsState() - - Scaffold( - topBar = { - TopAppBar( - title = { - TextField( - value = state.searchQuery, - onValueChange = component::onSearchQueryChanged, - placeholder = { Text(stringResource(R.string.privacy_search_users_placeholder)) }, - colors = TextFieldDefaults.colors( - focusedContainerColor = Color.Transparent, - unfocusedContainerColor = Color.Transparent, - focusedIndicatorColor = Color.Transparent, - unfocusedIndicatorColor = Color.Transparent - ), - modifier = Modifier.fillMaxWidth() - ) - }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - }, - colors = TopAppBarDefaults.centerAlignedTopAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background - ) - ) - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - AnimatedContent( - targetState = state.isLoading to (state.users.isEmpty() && state.searchQuery.isNotEmpty()), - transitionSpec = { - fadeIn(animationSpec = tween(300, easing = EaseIn)) + - scaleIn(initialScale = 0.95f, animationSpec = tween(300, easing = EaseIn)) togetherWith - fadeOut(animationSpec = tween(200, easing = EaseOut)) - }, - label = "UserSelectionContent", - modifier = Modifier - .fillMaxSize() - .consumeWindowInsets(padding) - ) { (isLoading, isEmptySearch) -> - when { - isLoading -> { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator() - } - } - - isEmptySearch -> { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - Text( - text = stringResource(R.string.privacy_no_users_found), - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - - else -> { - LazyColumn( - modifier = Modifier.fillMaxSize(), - contentPadding = PaddingValues( - top = padding.calculateTopPadding() + 8.dp, - bottom = padding.calculateBottomPadding() + 16.dp, - start = 16.dp, - end = 16.dp - ) - ) { - if (state.users.isNotEmpty()) { - item { - SettingsGroup { - state.users.forEach { user -> - UserSelectionItem( - user = user, - onClick = { component.onUserClicked(user.id) }, - modifier = Modifier.animateItem(), - videoPlayerPool = component.videoPlayerPool - ) - } - } - } - } - } - } - } - } - } -} - -@Composable -fun UserSelectionItem( - user: UserModel, - onClick: () -> Unit, - videoPlayerPool: VideoPlayerPool, - modifier: Modifier = Modifier -) { - val deletedText = stringResource(R.string.privacy_user_deleted) - val displayName = remember(user, deletedText) { - buildString { - if (user.firstName.isBlank()) { - append("${user.id} $deletedText") - } else { - append(user.firstName) - if (!user.lastName.isNullOrBlank()) { - append(" ") - append(user.lastName) - } - } - if (!user.username.isNullOrBlank()) { - append(" (@${user.username})") - } - } - } - - ListItem( - headlineContent = { - Row(verticalAlignment = Alignment.CenterVertically) { - Text(displayName, modifier = Modifier.weight(1f, fill = false)) - if (user.isVerified) { - Spacer(Modifier.width(4.dp)) - Icon( - imageVector = Icons.Rounded.Verified, - contentDescription = stringResource(R.string.cd_verified), - modifier = Modifier.size(16.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - if (user.isSponsor) { - Spacer(Modifier.width(4.dp)) - Icon( - imageVector = Icons.Default.Favorite, - contentDescription = stringResource(R.string.cd_sponsor), - modifier = Modifier.size(16.dp), - tint = Color(0xFFE53935) - ) - } - } - }, - leadingContent = { - Avatar( - path = user.avatarPath, - fallbackPath = user.personalAvatarPath, - name = user.firstName.ifBlank { "D" }, - size = 40.dp, - videoPlayerPool = videoPlayerPool - ) - }, - modifier = modifier.clickable(onClick = onClick), - colors = ListItemDefaults.colors( - containerColor = Color.Transparent - ) - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/privacy/userSelection/UserSelectionStore.kt b/presentation/src/main/java/org/monogram/presentation/settings/privacy/userSelection/UserSelectionStore.kt deleted file mode 100644 index a4821cb6..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/privacy/userSelection/UserSelectionStore.kt +++ /dev/null @@ -1,18 +0,0 @@ -package org.monogram.presentation.settings.privacy.userSelection - -import com.arkivanov.mvikotlin.core.store.Store - -interface UserSelectionStore : - Store { - - sealed class Intent { - object BackClicked : Intent() - data class SearchQueryChanged(val query: String) : Intent() - data class UserClicked(val userId: Long) : Intent() - data class UpdateState(val state: UserSelectionComponent.State) : Intent() - } - - sealed class Label { - object Back : Label() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/privacy/userSelection/UserSelectionStoreFactory.kt b/presentation/src/main/java/org/monogram/presentation/settings/privacy/userSelection/UserSelectionStoreFactory.kt deleted file mode 100644 index 65eae839..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/privacy/userSelection/UserSelectionStoreFactory.kt +++ /dev/null @@ -1,45 +0,0 @@ -package org.monogram.presentation.settings.privacy.userSelection - -import com.arkivanov.mvikotlin.core.store.Reducer -import com.arkivanov.mvikotlin.core.store.Store -import com.arkivanov.mvikotlin.core.store.StoreFactory -import com.arkivanov.mvikotlin.extensions.coroutines.CoroutineExecutor -import org.monogram.presentation.settings.privacy.userSelection.UserSelectionStore.Intent -import org.monogram.presentation.settings.privacy.userSelection.UserSelectionStore.Label - -class UserSelectionStoreFactory( - private val storeFactory: StoreFactory, - private val component: DefaultUserSelectionComponent -) { - - fun create(): UserSelectionStore = - object : UserSelectionStore, Store by storeFactory.create( - name = "UserSelectionStore", - initialState = component.state.value, - executorFactory = ::ExecutorImpl, - reducer = ReducerImpl - ) {} - - private inner class ExecutorImpl : - CoroutineExecutor() { - override fun executeIntent(intent: Intent) { - when (intent) { - Intent.BackClicked -> component.onBackClicked() - is Intent.SearchQueryChanged -> component.onSearchQueryChanged(intent.query) - is Intent.UserClicked -> component.onUserClicked(intent.userId) - is Intent.UpdateState -> dispatch(Message.UpdateState(intent.state)) - } - } - } - - private object ReducerImpl : Reducer { - override fun UserSelectionComponent.State.reduce(msg: Message): UserSelectionComponent.State = - when (msg) { - is Message.UpdateState -> msg.state - } - } - - sealed class Message { - data class UpdateState(val state: UserSelectionComponent.State) : Message() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/profile/DefaultEditProfileComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/profile/DefaultEditProfileComponent.kt deleted file mode 100644 index 56326883..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/profile/DefaultEditProfileComponent.kt +++ /dev/null @@ -1,229 +0,0 @@ -package org.monogram.presentation.settings.profile - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.launch -import org.monogram.domain.models.BirthdateModel -import org.monogram.domain.models.BusinessOpeningHoursModel -import org.monogram.domain.repository.ChatsListRepository -import org.monogram.domain.repository.LocationRepository -import org.monogram.domain.repository.UserRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.root.AppComponentContext - -class DefaultEditProfileComponent( - context: AppComponentContext, - private val onBackClicked: () -> Unit -) : EditProfileComponent, AppComponentContext by context { - - private val userRepository: UserRepository = container.repositories.userRepository - private val chatsListRepository: ChatsListRepository = container.repositories.chatsListRepository - private val locationRepository: LocationRepository = container.repositories.locationRepository - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - - private val _state = MutableValue(EditProfileComponent.State()) - override val state: Value = _state - private val scope = componentScope - - init { - scope.launch { - _state.update { it.copy(isLoading = true) } - try { - val me = userRepository.getMe() - val fullInfo = userRepository.getChatFullInfo(me.id) - val linkedChat = - fullInfo?.linkedChatId?.let { if (it != 0L) chatsListRepository.getChatById(it) else null } - - _state.update { - it.copy( - user = me, - firstName = me.firstName, - lastName = me.lastName ?: "", - bio = fullInfo?.description ?: "", - username = me.username ?: "", - birthdate = fullInfo?.birthdate, - personalChatId = fullInfo?.linkedChatId ?: 0L, - linkedChat = linkedChat, - businessBio = fullInfo?.businessInfo?.startPage?.message ?: "", - businessAddress = fullInfo?.businessInfo?.location?.address ?: "", - businessLatitude = fullInfo?.businessInfo?.location?.latitude ?: 0.0, - businessLongitude = fullInfo?.businessInfo?.location?.longitude ?: 0.0, - businessOpeningHours = fullInfo?.businessInfo?.openingHours, - avatarPath = me.avatarPath, - isLoading = false - ) - } - } catch (e: Exception) { - _state.update { it.copy(isLoading = false, error = e.message) } - } - } - } - - override fun onBack() { - onBackClicked() - } - - override fun onUpdateFirstName(firstName: String) { - _state.update { it.copy(firstName = firstName) } - } - - override fun onUpdateLastName(lastName: String) { - _state.update { it.copy(lastName = lastName) } - } - - override fun onUpdateBio(bio: String) { - _state.update { it.copy(bio = bio) } - } - - override fun onUpdateUsername(username: String) { - _state.update { it.copy(username = username) } - } - - override fun onUpdateBirthdate(birthdate: BirthdateModel?) { - _state.update { it.copy(birthdate = birthdate) } - } - - override fun onUpdatePersonalChatId(chatId: Long) { - _state.update { it.copy(personalChatId = chatId) } - if (chatId != 0L) { - scope.launch { - val chat = chatsListRepository.getChatById(chatId) - _state.update { it.copy(linkedChat = chat) } - } - } else { - _state.update { it.copy(linkedChat = null) } - } - } - - override fun onUpdateBusinessBio(bio: String) { - _state.update { it.copy(businessBio = bio) } - } - - override fun onUpdateBusinessAddress(address: String, latitude: Double, longitude: Double) { - _state.update { - it.copy( - businessAddress = address, - businessLatitude = latitude, - businessLongitude = longitude - ) - } - } - - override fun onUpdateBusinessOpeningHours(openingHours: BusinessOpeningHoursModel?) { - _state.update { it.copy(businessOpeningHours = openingHours) } - } - - override fun onChangeAvatar(path: String) { - _state.update { it.copy(avatarPath = path) } - scope.launch { - try { - userRepository.setProfilePhoto(path) - } catch (e: Exception) { - _state.update { it.copy(error = e.message) } - } - } - } - - override fun onShowAvatarPicker(show: Boolean) { - _state.update { it.copy(showAvatarPicker = show) } - } - - override fun onReverseGeocode(lat: Double, lon: Double) { - scope.launch { - try { - val response = locationRepository.reverseGeocode(lat, lon) - response?.let { address -> - _state.update { - it.copy( - businessAddress = (address.address?.fullAddress ?: address.display_name).toString(), - businessLatitude = lat, - businessLongitude = lon - ) - } - } - } catch (e: Exception) { - // Ignore geocode errors for now - } - } - } - - override fun onToggleUsername(username: String, active: Boolean) { - scope.launch { - try { - userRepository.toggleUsernameIsActive(username, active) - val me = userRepository.getMe() - _state.update { it.copy(user = me) } - } catch (e: Exception) { - _state.update { it.copy(error = e.message) } - } - } - } - - override fun onReorderUsernames(usernames: List) { - scope.launch { - try { - userRepository.reorderActiveUsernames(usernames) - val me = userRepository.getMe() - _state.update { it.copy(user = me, username = me.username ?: "") } - } catch (e: Exception) { - _state.update { it.copy(error = e.message) } - } - } - } - - override fun onSave() { - scope.launch { - _state.update { it.copy(isLoading = true) } - try { - val currentState = _state.value - val user = currentState.user ?: return@launch - - if (currentState.firstName != user.firstName || currentState.lastName != (user.lastName ?: "")) { - userRepository.setName(currentState.firstName, currentState.lastName) - } - - val fullInfo = userRepository.getChatFullInfo(user.id) - if (currentState.bio != (fullInfo?.description ?: "")) { - userRepository.setBio(currentState.bio) - } - - if (currentState.username != (user.username ?: "")) { - userRepository.setUsername(currentState.username) - } - - if (currentState.birthdate != fullInfo?.birthdate) { - userRepository.setBirthdate(currentState.birthdate) - } - - if (currentState.personalChatId != (fullInfo?.linkedChatId ?: 0L)) { - userRepository.setPersonalChat(currentState.personalChatId) - } - - if (currentState.businessBio != (fullInfo?.businessInfo?.startPage?.message ?: "")) { - userRepository.setBusinessBio(currentState.businessBio) - } - - if (currentState.businessAddress != (fullInfo?.businessInfo?.location?.address ?: "") || - currentState.businessLatitude != (fullInfo?.businessInfo?.location?.latitude ?: 0.0) || - currentState.businessLongitude != (fullInfo?.businessInfo?.location?.longitude ?: 0.0) - ) { - userRepository.setBusinessLocation( - currentState.businessAddress, - currentState.businessLatitude, - currentState.businessLongitude - ) - } - - if (currentState.businessOpeningHours != fullInfo?.businessInfo?.openingHours) { - userRepository.setBusinessOpeningHours(currentState.businessOpeningHours) - } - - onBack() - } catch (e: Exception) { - _state.update { it.copy(isLoading = false, error = e.message) } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/profile/EditProfileComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/profile/EditProfileComponent.kt deleted file mode 100644 index bf0dc2ae..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/profile/EditProfileComponent.kt +++ /dev/null @@ -1,51 +0,0 @@ -package org.monogram.presentation.settings.profile - -import com.arkivanov.decompose.value.Value -import org.monogram.domain.models.BirthdateModel -import org.monogram.domain.models.BusinessOpeningHoursModel -import org.monogram.domain.models.ChatModel -import org.monogram.domain.models.UserModel -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -interface EditProfileComponent { - val state: Value - val videoPlayerPool: VideoPlayerPool - - fun onBack() - fun onUpdateFirstName(firstName: String) - fun onUpdateLastName(lastName: String) - fun onUpdateBio(bio: String) - fun onUpdateUsername(username: String) - fun onUpdateBirthdate(birthdate: BirthdateModel?) - fun onUpdatePersonalChatId(chatId: Long) - fun onUpdateBusinessBio(bio: String) - fun onUpdateBusinessAddress(address: String, latitude: Double = 0.0, longitude: Double = 0.0) - fun onUpdateBusinessOpeningHours(openingHours: BusinessOpeningHoursModel?) - fun onChangeAvatar(path: String) - fun onSave() - fun onReverseGeocode(lat: Double, lon: Double) - fun onToggleUsername(username: String, active: Boolean) - fun onReorderUsernames(usernames: List) - - data class State( - val user: UserModel? = null, - val firstName: String = "", - val lastName: String = "", - val bio: String = "", - val username: String = "", - val birthdate: BirthdateModel? = null, - val personalChatId: Long = 0L, - val linkedChat: ChatModel? = null, - val businessBio: String = "", - val businessAddress: String = "", - val businessLatitude: Double = 0.0, - val businessLongitude: Double = 0.0, - val businessOpeningHours: BusinessOpeningHoursModel? = null, - val avatarPath: String? = null, - val isLoading: Boolean = false, - val error: String? = null, - val showAvatarPicker: Boolean = false - ) - - fun onShowAvatarPicker(show: Boolean) -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/profile/EditProfileContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/profile/EditProfileContent.kt deleted file mode 100644 index 953b88da..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/profile/EditProfileContent.kt +++ /dev/null @@ -1,1094 +0,0 @@ -package org.monogram.presentation.settings.profile - -import android.Manifest -import android.content.pm.PackageManager -import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.PickVisualMediaRequest -import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.window.Dialog -import androidx.core.content.ContextCompat -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import com.google.android.gms.location.LocationServices -import com.google.android.gms.location.Priority -import com.maplibre.compose.MapView -import com.maplibre.compose.camera.CameraState -import com.maplibre.compose.camera.MapViewCamera -import com.maplibre.compose.rememberSaveableMapViewCamera -import com.maplibre.compose.symbols.Symbol -import kotlinx.coroutines.delay -import org.maplibre.android.geometry.LatLng -import org.maplibre.android.maps.MapLibreMapOptions -import org.monogram.domain.models.BirthdateModel -import org.monogram.domain.models.BusinessOpeningHoursIntervalModel -import org.monogram.domain.models.BusinessOpeningHoursModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.Avatar -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.util.FileUtils -import org.monogram.presentation.features.chats.chatList.components.SectionHeader -import org.monogram.presentation.features.chats.chatList.components.SettingsTextField -import java.util.* - -private const val MAP_STYLE = "https://tiles.openfreemap.org/styles/bright" - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun EditProfileContent(component: EditProfileComponent) { - val state by component.state.subscribeAsState() - val context = LocalContext.current - - val photoPickerLauncher = rememberLauncherForActivityResult( - contract = ActivityResultContracts.PickVisualMedia(), - onResult = { uri -> - uri?.let { - val path = FileUtils.getPath(context, it) - component.onChangeAvatar(path.toString()) - } - } - ) - - val mapOptions = remember { - MapLibreMapOptions.createFromAttributes(context, null).apply { - scrollGesturesEnabled(true) - zoomGesturesEnabled(true) - tiltGesturesEnabled(true) - rotateGesturesEnabled(true) - doubleTapGesturesEnabled(true) - textureMode(true) - } - } - - var showDatePicker by remember { mutableStateOf(false) } - var showWorkHoursSheet by remember { mutableStateOf(false) } - var showGeoDialog by remember { mutableStateOf(false) } - var showUsernamePicker by remember { mutableStateOf(false) } - - if (showUsernamePicker) { - val activeUsernames = state.user?.usernames?.activeUsernames ?: emptyList() - val disabledUsernames = state.user?.usernames?.disabledUsernames ?: emptyList() - val collectibleUsernames = state.user?.usernames?.collectibleUsernames ?: emptyList() - - var retryAfterSeconds by remember { mutableIntStateOf(0) } - - LaunchedEffect(retryAfterSeconds) { - if (retryAfterSeconds > 0) { - while (retryAfterSeconds > 0) { - delay(1000) - retryAfterSeconds-- - } - } - } - - LaunchedEffect(state.error) { - if (state.error?.contains("retry after", ignoreCase = true) == true) { - val seconds = state.error?.filter { it.isDigit() }?.toIntOrNull() ?: 0 - if (seconds > 0) { - retryAfterSeconds = seconds - } - } - } - - ModalBottomSheet( - onDismissRequest = { showUsernamePicker = false }, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onSurface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 32.dp) - ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = stringResource(R.string.usernames_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(horizontal = 4.dp) - ) - - if (retryAfterSeconds > 0) { - Surface( - color = MaterialTheme.colorScheme.errorContainer, - shape = RoundedCornerShape(8.dp) - ) { - Text( - text = stringResource(R.string.retry_after_format, retryAfterSeconds), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onErrorContainer, - modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp) - ) - } - } - } - - Spacer(modifier = Modifier.height(16.dp)) - - LazyColumn( - modifier = Modifier.weight(1f, fill = false), - verticalArrangement = Arrangement.spacedBy(4.dp) - ) { - if (activeUsernames.isNotEmpty()) { - item(key = "active_header") { - SectionHeader( - stringResource(R.string.active_usernames_title), - modifier = Modifier - .animateItem() - .padding(start = 4.dp) - ) - } - itemsIndexed(activeUsernames, key = { index, username -> "active_${index}_$username" }) { _, username -> - ListItem( - headlineContent = { Text("@$username") }, - trailingContent = { - Row(verticalAlignment = Alignment.CenterVertically) { - if (activeUsernames.size > 1) { - IconButton(onClick = { - val newList = activeUsernames.toMutableList() - val index = newList.indexOf(username) - if (index > 0) { - Collections.swap(newList, index, index - 1) - component.onReorderUsernames(newList) - } - }, - enabled = activeUsernames.indexOf(username) > 0 && retryAfterSeconds == 0 - ) { - Icon(Icons.Rounded.KeyboardArrowUp, null) - } - IconButton(onClick = { - val newList = activeUsernames.toMutableList() - val index = newList.indexOf(username) - if (index < newList.size - 1) { - Collections.swap(newList, index, index + 1) - component.onReorderUsernames(newList) - } - }, - enabled = activeUsernames.indexOf(username) < activeUsernames.size - 1 && retryAfterSeconds == 0 - ) { - Icon(Icons.Rounded.KeyboardArrowDown, null) - } - } - Switch( - checked = true, - onCheckedChange = { component.onToggleUsername(username, false) }, - enabled = retryAfterSeconds == 0 - ) - } - }, - colors = ListItemDefaults.colors(containerColor = MaterialTheme.colorScheme.surfaceContainer), - modifier = Modifier - .animateItem() - .clip(RoundedCornerShape(16.dp)) - .clickable(enabled = retryAfterSeconds == 0) { - val newList = activeUsernames.toMutableList() - newList.remove(username) - newList.add(0, username) - component.onReorderUsernames(newList) - } - ) - } - } - - if (disabledUsernames.isNotEmpty()) { - item(key = "disabled_header") { - SectionHeader( - stringResource(R.string.disabled_usernames_title), - modifier = Modifier - .animateItem() - .padding(start = 4.dp) - ) - } - itemsIndexed(disabledUsernames, key = { index, username -> "disabled_${index}_$username" }) { _, username -> - ListItem( - headlineContent = { - Text( - "@$username", - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - }, - trailingContent = { - Switch( - checked = false, - onCheckedChange = { component.onToggleUsername(username, true) }, - enabled = retryAfterSeconds == 0 - ) - }, - colors = ListItemDefaults.colors(containerColor = MaterialTheme.colorScheme.surfaceContainer), - modifier = Modifier - .animateItem() - .clip(RoundedCornerShape(16.dp)) - ) - } - } - - if (collectibleUsernames.isNotEmpty()) { - item(key = "collectible_header") { - SectionHeader( - stringResource(R.string.collectible_usernames_title), - modifier = Modifier - .animateItem() - .padding(start = 4.dp) - ) - } - itemsIndexed(collectibleUsernames, key = { index, username -> "collectible_${index}_$username" }) { _, username -> - val isActive = activeUsernames.contains(username) - ListItem( - headlineContent = { Text("@$username") }, - trailingContent = { - Switch( - checked = isActive, - onCheckedChange = { component.onToggleUsername(username, it) }, - enabled = retryAfterSeconds == 0 - ) - }, - colors = ListItemDefaults.colors(containerColor = MaterialTheme.colorScheme.surfaceContainer), - modifier = Modifier - .animateItem() - .clip(RoundedCornerShape(16.dp)) - ) - } - } - } - - Spacer(modifier = Modifier.height(24.dp)) - - Button( - onClick = { showUsernamePicker = false }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.done_button), fontSize = 16.sp, fontWeight = FontWeight.Bold) - } - } - } - } - - if (showDatePicker) { - val datePickerState = rememberDatePickerState( - initialSelectedDateMillis = state.birthdate?.let { - Calendar.getInstance().apply { - set(it.year ?: 2000, it.month - 1, it.day) - }.timeInMillis - } - ) - DatePickerDialog( - onDismissRequest = { showDatePicker = false }, - confirmButton = { - TextButton(onClick = { - datePickerState.selectedDateMillis?.let { - val cal = Calendar.getInstance().apply { timeInMillis = it } - component.onUpdateBirthdate( - BirthdateModel( - day = cal.get(Calendar.DAY_OF_MONTH), - month = cal.get(Calendar.MONTH) + 1, - year = cal.get(Calendar.YEAR) - ) - ) - } - showDatePicker = false - }) { - Text(stringResource(R.string.ok_button)) - } - }, - dismissButton = { - TextButton(onClick = { showDatePicker = false }) { - Text(stringResource(R.string.cancel_button)) - } - } - ) { - DatePicker(state = datePickerState) - } - } - - if (showWorkHoursSheet) { - ModalBottomSheet( - onDismissRequest = { showWorkHoursSheet = false }, - dragHandle = { BottomSheetDefaults.DragHandle() } - ) { - val initialIntervals = state.businessOpeningHours?.intervals ?: emptyList() - val initialDays = initialIntervals.map { (it.startMinute / 1440) + 1 }.toSet() - val firstInterval = initialIntervals.firstOrNull() - - var selectedDays by remember { - mutableStateOf(if (initialDays.isEmpty()) setOf(1, 2, 3, 4, 5) else initialDays) - } - var startMinuteOfDay by remember { - mutableStateOf(firstInterval?.let { it.startMinute % 1440 } ?: (9 * 60)) - } - var endMinuteOfDay by remember { - mutableStateOf(firstInterval?.let { it.endMinute % 1440 } ?: (18 * 60)) - } - - var showStartTimePicker by remember { mutableStateOf(false) } - var showEndTimePicker by remember { mutableStateOf(false) } - - if (showStartTimePicker) { - val timePickerState = rememberTimePickerState( - initialHour = startMinuteOfDay / 60, - initialMinute = startMinuteOfDay % 60 - ) - Dialog(onDismissRequest = { showStartTimePicker = false }) { - Surface( - shape = RoundedCornerShape(28.dp), - color = MaterialTheme.colorScheme.surface, - tonalElevation = 6.dp - ) { - Column( - modifier = Modifier.padding(24.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Text( - stringResource(R.string.select_start_time), - style = MaterialTheme.typography.labelLarge, - modifier = Modifier.fillMaxWidth() - ) - Spacer(modifier = Modifier.height(20.dp)) - TimePicker(state = timePickerState) - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.End - ) { - TextButton(onClick = { - showStartTimePicker = false - }) { Text(stringResource(R.string.cancel_button)) } - TextButton(onClick = { - startMinuteOfDay = timePickerState.hour * 60 + timePickerState.minute - showStartTimePicker = false - }) { Text(stringResource(R.string.ok_button)) } - } - } - } - } - } - - if (showEndTimePicker) { - val timePickerState = rememberTimePickerState( - initialHour = endMinuteOfDay / 60, - initialMinute = endMinuteOfDay % 60 - ) - Dialog(onDismissRequest = { showEndTimePicker = false }) { - Surface( - shape = RoundedCornerShape(28.dp), - color = MaterialTheme.colorScheme.surface, - tonalElevation = 6.dp - ) { - Column( - modifier = Modifier.padding(24.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Text( - stringResource(R.string.select_end_time), - style = MaterialTheme.typography.labelLarge, - modifier = Modifier.fillMaxWidth() - ) - Spacer(modifier = Modifier.height(20.dp)) - TimePicker(state = timePickerState) - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.End - ) { - TextButton(onClick = { - showEndTimePicker = false - }) { Text(stringResource(R.string.cancel_button)) } - TextButton(onClick = { - endMinuteOfDay = timePickerState.hour * 60 + timePickerState.minute - showEndTimePicker = false - }) { Text(stringResource(R.string.ok_button)) } - } - } - } - } - } - - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 40.dp) - ) { - Text( - text = stringResource(R.string.work_hours_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - Spacer(modifier = Modifier.height(24.dp)) - - Text( - text = stringResource(R.string.working_days_title), - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.primary - ) - Spacer(modifier = Modifier.height(12.dp)) - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween - ) { - val days = listOf( - stringResource(R.string.monday_short), - stringResource(R.string.tuesday_short), - stringResource(R.string.wednesday_short), - stringResource(R.string.thursday_short), - stringResource(R.string.friday_short), - stringResource(R.string.saturday_short), - stringResource(R.string.sunday_short) - ) - days.forEachIndexed { index, day -> - val dayNum = index + 1 - val isSelected = selectedDays.contains(dayNum) - Box( - modifier = Modifier - .size(40.dp) - .clip(CircleShape) - .background(if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surfaceVariant) - .clickable { - selectedDays = if (isSelected) selectedDays - dayNum else selectedDays + dayNum - }, - contentAlignment = Alignment.Center - ) { - Text( - text = day, - color = if (isSelected) MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurfaceVariant, - fontWeight = FontWeight.Bold - ) - } - } - } - - Spacer(modifier = Modifier.height(24.dp)) - Text( - text = stringResource(R.string.time_range_title), - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.primary - ) - Spacer(modifier = Modifier.height(12.dp)) - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically - ) { - Surface( - onClick = { showStartTimePicker = true }, - modifier = Modifier.weight(1f), - shape = RoundedCornerShape(12.dp), - color = MaterialTheme.colorScheme.surfaceVariant - ) { - Column(modifier = Modifier.padding(12.dp)) { - Text(stringResource(R.string.from_label), style = MaterialTheme.typography.labelSmall) - Text( - String.format("%02d:%02d", startMinuteOfDay / 60, startMinuteOfDay % 60), - style = MaterialTheme.typography.titleMedium - ) - } - } - Text("-", modifier = Modifier.padding(horizontal = 16.dp), fontWeight = FontWeight.Bold) - Surface( - onClick = { showEndTimePicker = true }, - modifier = Modifier.weight(1f), - shape = RoundedCornerShape(12.dp), - color = MaterialTheme.colorScheme.surfaceVariant - ) { - Column(modifier = Modifier.padding(12.dp)) { - Text(stringResource(R.string.to_label), style = MaterialTheme.typography.labelSmall) - Text( - String.format("%02d:%02d", endMinuteOfDay / 60, endMinuteOfDay % 60), - style = MaterialTheme.typography.titleMedium - ) - } - } - } - - Spacer(modifier = Modifier.height(32.dp)) - Button( - onClick = { - val intervals = selectedDays.map { day -> - val offset = (day - 1) * 1440 - BusinessOpeningHoursIntervalModel( - startMinute = offset + startMinuteOfDay, - endMinute = offset + endMinuteOfDay - ) - }.sortedBy { it.startMinute } - - component.onUpdateBusinessOpeningHours( - BusinessOpeningHoursModel( - timeZoneId = TimeZone.getDefault().id, - intervals = intervals - ) - ) - showWorkHoursSheet = false - }, - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.action_save)) - } - } - } - } - - if (showGeoDialog) { - Dialog( - onDismissRequest = { showGeoDialog = false }, - properties = androidx.compose.ui.window.DialogProperties(usePlatformDefaultWidth = false) - ) { - var selectedLatitude by remember { - mutableStateOf( - if (state.businessLatitude != 0.0 || state.businessLongitude != 0.0) { - state.businessLatitude - } else { - 51.505 - } - ) - } - var selectedLongitude by remember { - mutableStateOf( - if (state.businessLatitude != 0.0 || state.businessLongitude != 0.0) { - state.businessLongitude - } else { - -0.09 - } - ) - } - - val camera = rememberSaveableMapViewCamera( - MapViewCamera( - CameraState.Centered( - selectedLatitude, - selectedLongitude, - ), - ) - ) - - val fusedLocationClient = remember { LocationServices.getFusedLocationProviderClient(context) } - val permissionLauncher = rememberLauncherForActivityResult( - ActivityResultContracts.RequestMultiplePermissions() - ) { permissions -> - if (permissions[Manifest.permission.ACCESS_FINE_LOCATION] == true || - permissions[Manifest.permission.ACCESS_COARSE_LOCATION] == true - ) { - fusedLocationClient.getCurrentLocation(Priority.PRIORITY_HIGH_ACCURACY, null) - .addOnSuccessListener { location -> - location?.let { - selectedLatitude = it.latitude - selectedLongitude = it.longitude - component.onReverseGeocode(it.latitude, it.longitude) - } - } - } - } - - Scaffold( - modifier = Modifier.fillMaxSize(), - topBar = { - TopAppBar( - title = { - Text( - stringResource(R.string.business_location_title), - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - }, - navigationIcon = { - IconButton(onClick = { showGeoDialog = false }) { - Icon(Icons.AutoMirrored.Rounded.ArrowBack, null) - } - }, - actions = { - IconButton(onClick = { - if (ContextCompat.checkSelfPermission( - context, - Manifest.permission.ACCESS_FINE_LOCATION - ) == PackageManager.PERMISSION_GRANTED - ) { - fusedLocationClient.getCurrentLocation(Priority.PRIORITY_HIGH_ACCURACY, null) - .addOnSuccessListener { location -> - location?.let { - selectedLatitude = it.latitude - selectedLongitude = it.longitude - component.onReverseGeocode(it.latitude, it.longitude) - } - } - } else { - permissionLauncher.launch( - arrayOf( - Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_COARSE_LOCATION - ) - ) - } - }) { - Icon(Icons.Rounded.MyLocation, contentDescription = "My Location") - } - } - ) - } - ) { padding -> - Box( - modifier = Modifier - .fillMaxSize() - .padding(padding) - ) { - MapView( - modifier = Modifier - .fillMaxWidth(), - camera = camera, - styleUrl = MAP_STYLE, - mapOptions = mapOptions, - onTapGestureCallback = { coordinate -> - selectedLatitude = coordinate.coordinate.latitude - selectedLongitude = coordinate.coordinate.longitude - component.onReverseGeocode(coordinate.coordinate.latitude, coordinate.coordinate.longitude) - } - ) { - Symbol( - center = LatLng(selectedLatitude, selectedLongitude), - imageId = R.drawable.ic_map_marker, - size = 2f - ) - } - - Icon( - Icons.Rounded.Add, - contentDescription = null, - modifier = Modifier - .align(Alignment.Center) - .size(32.dp), - tint = MaterialTheme.colorScheme.primary.copy(alpha = 0.5f) - ) - - Card( - modifier = Modifier - .align(Alignment.BottomCenter) - .fillMaxWidth() - .padding(16.dp) - .navigationBarsPadding(), - shape = RoundedCornerShape(24.dp), - colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface.copy(alpha = 0.9f)), - elevation = CardDefaults.cardElevation(defaultElevation = 8.dp) - ) { - Column(modifier = Modifier.padding(20.dp)) { - OutlinedTextField( - value = state.businessAddress, - onValueChange = { - component.onUpdateBusinessAddress( - it, - selectedLatitude, - selectedLongitude - ) - }, - label = { Text(stringResource(R.string.address_label)) }, - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(12.dp), - leadingIcon = { - Icon( - Icons.Rounded.LocationOn, - null, - tint = MaterialTheme.colorScheme.primary - ) - } - ) - - Spacer(modifier = Modifier.height(20.dp)) - Button( - onClick = { - component.onUpdateBusinessAddress( - state.businessAddress, - selectedLatitude, - selectedLongitude - ) - showGeoDialog = false - }, - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(16.dp), - contentPadding = PaddingValues(16.dp) - ) { - Text( - stringResource(R.string.confirm_location_button), - fontSize = 16.sp, - fontWeight = FontWeight.Bold - ) - } - } - } - } - } - } - } - - Scaffold( - modifier = Modifier.semantics { contentDescription = "EditProfileContent" }, - topBar = { - TopAppBar( - title = { - Text( - text = stringResource(R.string.edit_profile_title), - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - }, - navigationIcon = { - IconButton(onClick = component::onBack) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - }, - actions = { - if (state.isLoading) { - CircularProgressIndicator( - modifier = Modifier - .size(24.dp) - .padding(end = 16.dp), - strokeWidth = 2.dp - ) - } else if (state.user != null) { - IconButton(onClick = component::onSave) { - Icon( - Icons.Rounded.Check, - contentDescription = stringResource(R.string.action_save), - tint = MaterialTheme.colorScheme.primary - ) - } - } - } - ) - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - if (state.user == null && state.isLoading) { - Box( - modifier = Modifier - .fillMaxSize() - .padding(padding), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator() - } - } else { - LazyColumn( - modifier = Modifier - .fillMaxSize() - .padding(top = padding.calculateTopPadding()), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, top = 0.dp, bottom = 100.dp) - ) { - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 24.dp), - contentAlignment = Alignment.Center - ) { - Box( - modifier = Modifier - .size(100.dp) - .clip(CircleShape) - .clickable { - photoPickerLauncher.launch( - PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly) - ) - }, - contentAlignment = Alignment.Center - ) { - Avatar( - path = state.avatarPath, - name = state.firstName, - size = 100.dp, - videoPlayerPool = component.videoPlayerPool, - onClick = { - photoPickerLauncher.launch( - PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly) - ) - } - ) - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.Black.copy(alpha = 0.4f)), - contentAlignment = Alignment.Center - ) { - Icon( - Icons.Rounded.CameraAlt, - null, - tint = Color.White, - modifier = Modifier.size(32.dp) - ) - } - } - } - } - - item { - SettingsTextField( - value = state.firstName, - onValueChange = component::onUpdateFirstName, - placeholder = stringResource(R.string.first_name_placeholder), - icon = Icons.Rounded.Person, - position = ItemPosition.TOP - ) - SettingsTextField( - value = state.lastName, - onValueChange = component::onUpdateLastName, - placeholder = stringResource(R.string.last_name_placeholder), - icon = Icons.Rounded.PersonOutline, - position = ItemPosition.MIDDLE - ) - SettingsTextField( - value = state.bio, - onValueChange = component::onUpdateBio, - placeholder = stringResource(R.string.bio_placeholder), - icon = Icons.Rounded.Info, - position = ItemPosition.BOTTOM, - singleLine = false - ) - - Text( - text = stringResource(R.string.bio_description), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) - ) - } - - item { - Spacer(modifier = Modifier.height(24.dp)) - Text( - text = stringResource(R.string.username_title), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp) - ) - - val hasMultipleUsernames = state.user?.usernames?.let { - it.activeUsernames.size + it.disabledUsernames.size + it.collectibleUsernames.size > 1 - } ?: false - - SettingsTextField( - value = state.username, - onValueChange = component::onUpdateUsername, - placeholder = stringResource(R.string.username_label), - icon = Icons.Rounded.AlternateEmail, - position = ItemPosition.STANDALONE, - trailingIcon = if (hasMultipleUsernames) { - { - IconButton(onClick = { showUsernamePicker = true }) { - Icon(Icons.Rounded.KeyboardArrowDown, null) - } - } - } else null - ) - Text( - text = stringResource(R.string.username_description), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) - ) - } - - item { - Spacer(modifier = Modifier.height(24.dp)) - Text( - text = stringResource(R.string.birthday_title), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp) - ) - - val birthdateText = state.birthdate?.let { "${it.day}/${it.month}/${it.year ?: ""}" } - ?: stringResource(R.string.not_set) - Box(modifier = Modifier.clickable { showDatePicker = true }) { - SettingsTextField( - value = birthdateText, - onValueChange = { }, - placeholder = stringResource(R.string.birthday_placeholder), - icon = Icons.Rounded.Cake, - position = ItemPosition.STANDALONE, - enabled = false - ) - } - } - - if (state.user?.isPremium == true) { - item { - Spacer(modifier = Modifier.height(24.dp)) - Text( - text = stringResource(R.string.telegram_business_title), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp) - ) - - Column( - modifier = Modifier - .fillMaxWidth() - .clip(RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp)) - .background(MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f)) - ) { - SettingsTextField( - value = if (state.personalChatId != 0L) state.personalChatId.toString() else "", - onValueChange = { - it.toLongOrNull()?.let { id -> component.onUpdatePersonalChatId(id) } - }, - placeholder = stringResource(R.string.linked_channel_id_placeholder), - icon = Icons.Rounded.Link, - position = ItemPosition.TOP - ) - - state.linkedChat?.let { chat -> - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Avatar( - path = chat.avatarPath, - fallbackPath = chat.personalAvatarPath, - name = chat.title, - size = 40.dp, - videoPlayerPool = component.videoPlayerPool - ) - Spacer(modifier = Modifier.width(12.dp)) - Column { - Text( - text = chat.title, - style = MaterialTheme.typography.titleSmall, - fontWeight = FontWeight.Bold - ) - chat.username?.let { - Text( - text = "@$it", - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.primary - ) - } - } - } - } - - Spacer(Modifier.height(8.dp)) - } - - Spacer(Modifier.height(2.dp)) - - SettingsTextField( - value = state.businessBio, - onValueChange = component::onUpdateBusinessBio, - placeholder = stringResource(R.string.business_bio_placeholder), - icon = Icons.Rounded.Business, - position = ItemPosition.MIDDLE - ) - - SettingsTextField( - value = state.businessAddress, - onValueChange = { - component.onUpdateBusinessAddress( - it, - state.businessLatitude, - state.businessLongitude - ) - }, - placeholder = stringResource(R.string.business_address_placeholder), - icon = Icons.Rounded.LocationOn, - position = ItemPosition.MIDDLE - ) - - val geoText = if (state.businessLatitude != 0.0 || state.businessLongitude != 0.0) { - "${String.format("%.4f", state.businessLatitude)}, ${ - String.format( - "%.4f", - state.businessLongitude - ) - }" - } else stringResource(R.string.not_set) - - Box(modifier = Modifier.clickable { showGeoDialog = true }) { - SettingsTextField( - value = geoText, - onValueChange = { }, - placeholder = stringResource(R.string.location_geo_placeholder), - icon = Icons.Rounded.Map, - position = ItemPosition.MIDDLE, - enabled = false - ) - } - - Spacer(Modifier.height(2.dp)) - - val hoursText = state.businessOpeningHours?.intervals?.firstOrNull()?.let { - val startH = (it.startMinute % 1440) / 60 - val startM = (it.startMinute % 1440) % 60 - val endH = (it.endMinute % 1440) / 60 - val endM = (it.endMinute % 1440) % 60 - val daysCount = state.businessOpeningHours?.intervals?.size ?: 0 - String.format( - "%02d:%02d - %02d:%02d %s", - startH, - startM, - endH, - endM, - stringResource(R.string.days_count_format, daysCount) - ) - } ?: stringResource(R.string.not_set) - - Box(modifier = Modifier.clickable { showWorkHoursSheet = true }) { - SettingsTextField( - value = hoursText, - onValueChange = { }, - placeholder = stringResource(R.string.opening_hours_placeholder), - icon = Icons.Rounded.Schedule, - position = ItemPosition.BOTTOM, - enabled = false - ) - } - - Text( - text = stringResource(R.string.premium_business_description), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) - ) - } - } - - item { - Spacer(modifier = Modifier.height(100.dp)) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/proxy/ProxyComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/proxy/ProxyComponent.kt deleted file mode 100644 index 1b953d9e..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/proxy/ProxyComponent.kt +++ /dev/null @@ -1,539 +0,0 @@ -package org.monogram.presentation.settings.proxy - -import android.util.Log -import androidx.core.net.toUri -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.* -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import org.json.JSONObject -import org.monogram.domain.models.ProxyModel -import org.monogram.domain.models.ProxyTypeModel -import org.monogram.domain.repository.AppPreferencesProvider -import org.monogram.domain.repository.CacheProvider -import org.monogram.domain.repository.ExternalProxyRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.root.AppComponentContext - -interface ProxyComponent { - val state: Value - - fun onBackClicked() - fun onAddProxyClicked() - fun onEditProxyClicked(proxy: ProxyModel) - fun onProxyClicked(proxy: ProxyModel) - fun onProxyLongClicked(proxy: ProxyModel) - fun onEnableProxy(proxyId: Int) - fun onDisableProxy() - fun onRemoveProxy(proxyId: Int) - fun onPingAll() - fun onPingProxy(proxyId: Int) - fun onTestProxy(server: String, port: Int, type: ProxyTypeModel) - fun onAddProxy(server: String, port: Int, type: ProxyTypeModel) - fun onEditProxy(proxyId: Int, server: String, port: Int, type: ProxyTypeModel) - fun onDismissDeleteConfirmation() - fun onConfirmDelete() - fun onDismissAddEdit() - fun onAutoBestProxyToggled(enabled: Boolean) - fun onTelegaProxyToggled(enabled: Boolean) - fun onPreferIpv6Toggled(enabled: Boolean) - fun onFetchTelegaProxies() - fun onClearUnavailableProxies() - fun onRemoveAllProxies() - fun onConfirmClearUnavailableProxies() - fun onConfirmRemoveAllProxies() - fun onDismissToast() - fun onDismissMassDeleteDialogs() - - data class State( - val proxies: List = emptyList(), - val telegaProxies: List = emptyList(), - val telegaProxyPing: Long? = null, - val isTelegaProxyEnabled: Boolean = false, - val isLoading: Boolean = false, - val isAddingProxy: Boolean = false, - val isAutoBestProxyEnabled: Boolean = false, - val preferIpv6: Boolean = false, - val proxyToEdit: ProxyModel? = null, - val proxyToDelete: ProxyModel? = null, - val testPing: Long? = null, - val isTesting: Boolean = false, - val isFetchingExternal: Boolean = false, - val toastMessage: String? = null, - val isRussianNumber: Boolean = false, - val showClearOfflineConfirmation: Boolean = false, - val showRemoveAllConfirmation: Boolean = false - ) -} - -class DefaultProxyComponent( - context: AppComponentContext, - private val onBack: () -> Unit -) : ProxyComponent, AppComponentContext by context { - - private val appPreferences: AppPreferencesProvider = container.preferences.appPreferences - private val cacheProvider: CacheProvider = container.cacheProvider - private val externalProxyRepository: ExternalProxyRepository = container.repositories.externalProxyRepository - - private val _state = MutableValue(ProxyComponent.State()) - override val state: Value = _state - private val scope = componentScope - private var restoreAttempted = false - - init { - checkIfRussianNumber() - scope.launch { - refreshProxies(shouldPing = true) - } - - combine( - appPreferences.isAutoBestProxyEnabled, - appPreferences.isTelegaProxyEnabled, - appPreferences.preferIpv6 - ) { autoBest, telega, ipv6 -> Triple(autoBest, telega, ipv6) } - .distinctUntilChanged() - .onEach { (autoBest, telega, ipv6) -> - if (telega && autoBest) { - appPreferences.setAutoBestProxyEnabled(false) - } - _state.update { - it.copy( - isAutoBestProxyEnabled = if (telega) false else autoBest, - isTelegaProxyEnabled = telega, - preferIpv6 = ipv6 - ) - } - }.launchIn(scope) - } - - private fun checkIfRussianNumber() { - val cachedIso = cacheProvider.cachedSimCountryIso.value - if (cachedIso != null) { - val isRussian = cachedIso.equals("ru", ignoreCase = true) - _state.update { it.copy(isRussianNumber = isRussian) } - return - } else { - _state.update { it.copy(isRussianNumber = false) } - } - } - - private suspend fun refreshProxies(shouldPing: Boolean = false) { - _state.update { it.copy(isLoading = true) } - restoreUserProxiesIfNeeded() - val allProxies = externalProxyRepository.getProxies() - val telegaIdentifiers = getTelegaIdentifiers() - - val telegaProxies = allProxies.filter { isProxyTelega(it, telegaIdentifiers) } - val regularProxies = allProxies.filter { !isProxyTelega(it, telegaIdentifiers) } - - _state.update { - it.copy( - proxies = regularProxies, - telegaProxies = telegaProxies, - isLoading = false - ) - } - updateTelegaStatus(allProxies) - if (shouldPing) { - performPingAll() - } - } - - private suspend fun restoreUserProxiesIfNeeded() { - if (restoreAttempted) return - restoreAttempted = true - - val backups = appPreferences.userProxyBackups.value - if (backups.isEmpty()) return - - val existing = externalProxyRepository.getProxies() - if (existing.isNotEmpty()) return - - backups.mapNotNull { parseProxyBackup(it) }.forEach { backup -> - externalProxyRepository.addProxy( - server = backup.server, - port = backup.port, - enable = false, - type = backup.type - ) - } - } - - private fun addProxyToBackup(proxy: ProxyModel) { - val current = appPreferences.userProxyBackups.value.toMutableSet() - current.add(serializeProxyBackup(proxy)) - appPreferences.setUserProxyBackups(current) - } - - private fun removeProxyFromBackup(proxy: ProxyModel) { - val current = appPreferences.userProxyBackups.value.toMutableSet() - current.remove(serializeProxyBackup(proxy)) - appPreferences.setUserProxyBackups(current) - } - - private fun replaceProxyInBackup(oldProxy: ProxyModel?, newProxy: ProxyModel) { - val current = appPreferences.userProxyBackups.value.toMutableSet() - if (oldProxy != null) { - current.remove(serializeProxyBackup(oldProxy)) - } - current.add(serializeProxyBackup(newProxy)) - appPreferences.setUserProxyBackups(current) - } - - private fun serializeProxyBackup(proxy: ProxyModel): String = JSONObject().apply { - put("server", proxy.server) - put("port", proxy.port) - when (val type = proxy.type) { - is ProxyTypeModel.Mtproto -> { - put("type", "mtproto") - put("secret", type.secret) - } - - is ProxyTypeModel.Socks5 -> { - put("type", "socks5") - put("username", type.username) - put("password", type.password) - } - - is ProxyTypeModel.Http -> { - put("type", "http") - put("username", type.username) - put("password", type.password) - put("httpOnly", type.httpOnly) - } - } - }.toString() - - private fun parseProxyBackup(raw: String): ProxyBackup? { - return runCatching { - val json = JSONObject(raw) - val type = when (json.optString("type")) { - "mtproto" -> ProxyTypeModel.Mtproto(json.optString("secret")) - "socks5" -> ProxyTypeModel.Socks5( - username = json.optString("username"), - password = json.optString("password") - ) - - "http" -> ProxyTypeModel.Http( - username = json.optString("username"), - password = json.optString("password"), - httpOnly = json.optBoolean("httpOnly", false) - ) - - else -> return null - } - - val server = json.optString("server") - val port = json.optInt("port", 443) - if (server.isBlank() || port !in 1..65535) return null - ProxyBackup(server = server, port = port, type = type) - }.getOrNull() - } - - private data class ProxyBackup( - val server: String, - val port: Int, - val type: ProxyTypeModel - ) - - private fun updateTelegaStatus(allProxies: List) { - val identifiers = getTelegaIdentifiers() - val enabledProxy = allProxies.find { it.isEnabled } - val isTelega = enabledProxy?.let { isProxyTelega(it, identifiers) } ?: false - - _state.update { - it.copy( - isTelegaProxyEnabled = appPreferences.isTelegaProxyEnabled.value, - telegaProxyPing = if (isTelega) enabledProxy.ping else null - ) - } - } - - private fun getTelegaIdentifiers(): Set { - val urls = appPreferences.telegaProxyUrls.value - Log.d("ProxyComponent", "Getting identifiers for ${urls.size} URLs") - return urls.mapNotNull { url -> - try { - val uri = url.replace("t.me/proxy", "tg://proxy").toUri() - val server = uri.getQueryParameter("server") - if (server != null) { - val port = uri.getQueryParameter("port") ?: "443" - "$server:$port" - } else { - val serverMatch = Regex("server=([^&]+)").find(url) - val portMatch = Regex("port=([^&]+)").find(url) - val s = serverMatch?.groupValues?.get(1) - val p = portMatch?.groupValues?.get(1) ?: "443" - if (s != null) "$s:$p" else null - } - } catch (e: Exception) { - null - } - }.toSet().also { - Log.d("ProxyComponent", "Generated ${it.size} identifiers: $it") - } - } - - private fun isProxyTelega(proxy: ProxyModel, identifiers: Set): Boolean { - val id = "${proxy.server}:${proxy.port}" - val isTelega = id in identifiers - if (isTelega) Log.d("ProxyComponent", "Proxy $id is identified as Telega") - return isTelega - } - - override fun onBackClicked() = onBack() - - override fun onAddProxyClicked() { - _state.update { it.copy(isAddingProxy = true, proxyToEdit = null, testPing = null, isTesting = false) } - } - - override fun onEditProxyClicked(proxy: ProxyModel) { - _state.update { it.copy(proxyToEdit = proxy, isAddingProxy = false, testPing = null, isTesting = false) } - } - - override fun onProxyClicked(proxy: ProxyModel) { - if (proxy.isEnabled) { - onDisableProxy() - } else { - onEnableProxy(proxy.id) - } - } - - override fun onProxyLongClicked(proxy: ProxyModel) { - onEditProxyClicked(proxy) - } - - override fun onEnableProxy(proxyId: Int) { - scope.launch { - if (externalProxyRepository.enableProxy(proxyId)) { - refreshProxies(shouldPing = false) - onPingProxy(proxyId) - } - } - } - - override fun onDisableProxy() { - scope.launch { - if (externalProxyRepository.disableProxy()) { - refreshProxies(shouldPing = false) - } - } - } - - override fun onRemoveProxy(proxyId: Int) { - val proxy = (_state.value.proxies + _state.value.telegaProxies).find { it.id == proxyId } - _state.update { it.copy(proxyToDelete = proxy) } - } - - override fun onPingAll() { - scope.launch { - performPingAll() - } - } - - private suspend fun performPingAll() { - val allProxies = _state.value.proxies + _state.value.telegaProxies - val pings = coroutineScope { - allProxies.map { proxy -> - proxy.id to async { - withTimeoutOrNull(5000) { - externalProxyRepository.pingProxy(proxy.id) - } ?: -1L - } - }.associate { (id, job) -> id to job.await() } - } - - val updatedRegular = _state.value.proxies.map { proxy -> - pings[proxy.id]?.let { proxy.copy(ping = it) } ?: proxy - } - val updatedTelega = _state.value.telegaProxies.map { proxy -> - pings[proxy.id]?.let { proxy.copy(ping = it) } ?: proxy - } - - _state.update { it.copy(proxies = updatedRegular, telegaProxies = updatedTelega) } - updateTelegaStatus(updatedRegular + updatedTelega) - } - - override fun onPingProxy(proxyId: Int) { - scope.launch { - val ping = withTimeoutOrNull(5000) { - externalProxyRepository.pingProxy(proxyId) - } ?: -1L - - val updatedRegular = _state.value.proxies.map { - if (it.id == proxyId) it.copy(ping = ping) else it - } - val updatedTelega = _state.value.telegaProxies.map { - if (it.id == proxyId) it.copy(ping = ping) else it - } - - _state.update { it.copy(proxies = updatedRegular, telegaProxies = updatedTelega) } - updateTelegaStatus(updatedRegular + updatedTelega) - } - } - - override fun onTestProxy(server: String, port: Int, type: ProxyTypeModel) { - _state.update { it.copy(isTesting = true, testPing = null) } - scope.launch { - val ping = withTimeoutOrNull(10000) { - externalProxyRepository.testProxy(server, port, type) - } ?: -1L - _state.update { it.copy(isTesting = false, testPing = ping) } - } - } - - override fun onAddProxy(server: String, port: Int, type: ProxyTypeModel) { - scope.launch { - val proxy = externalProxyRepository.addProxy(server, port, true, type) - if (proxy != null) { - addProxyToBackup(proxy) - _state.update { it.copy(isAddingProxy = false) } - refreshProxies(shouldPing = false) - onPingProxy(proxy.id) - } - } - } - - override fun onEditProxy(proxyId: Int, server: String, port: Int, type: ProxyTypeModel) { - scope.launch { - val oldProxy = (_state.value.proxies + _state.value.telegaProxies).find { it.id == proxyId } - val proxy = externalProxyRepository.editProxy(proxyId, server, port, true, type) - if (proxy != null) { - replaceProxyInBackup(oldProxy, proxy) - _state.update { it.copy(proxyToEdit = null) } - refreshProxies(shouldPing = false) - onPingProxy(proxy.id) - } - } - } - - override fun onDismissDeleteConfirmation() { - _state.update { it.copy(proxyToDelete = null) } - } - - override fun onConfirmDelete() { - val proxy = _state.value.proxyToDelete ?: return - scope.launch { - if (externalProxyRepository.removeProxy(proxy.id)) { - removeProxyFromBackup(proxy) - _state.update { it.copy(proxyToDelete = null) } - refreshProxies(shouldPing = false) - } - } - } - - override fun onDismissAddEdit() { - _state.update { it.copy(isAddingProxy = false, proxyToEdit = null, testPing = null, isTesting = false) } - } - - override fun onAutoBestProxyToggled(enabled: Boolean) { - appPreferences.setAutoBestProxyEnabled(enabled) - } - - override fun onTelegaProxyToggled(enabled: Boolean) { - appPreferences.setTelegaProxyEnabled(enabled) - if (enabled) { - appPreferences.setAutoBestProxyEnabled(false) - scope.launch { - if (_state.value.telegaProxies.isEmpty()) { - onFetchTelegaProxies() - } - refreshProxies(shouldPing = false) - } - } else { - scope.launch { - externalProxyRepository.disableProxy() - refreshProxies(shouldPing = false) - } - } - } - - override fun onPreferIpv6Toggled(enabled: Boolean) { - externalProxyRepository.setPreferIpv6(enabled) - } - - override fun onFetchTelegaProxies() { - if (_state.value.isFetchingExternal) return - - scope.launch { - _state.update { it.copy(isFetchingExternal = true) } - try { - Log.d("ProxyComponent", "Fetching telega proxies...") - val addedProxies = externalProxyRepository.fetchExternalProxies() - Log.d("ProxyComponent", "Added ${addedProxies.size} proxies") - - if (addedProxies.isEmpty()) { - _state.update { it.copy(isFetchingExternal = false) } - return@launch - } - - refreshProxies(shouldPing = false) - } catch (e: Exception) { - Log.e("ProxyComponent", "Error fetching proxies", e) - _state.update { it.copy(toastMessage = "Failed to fetch proxies") } - } finally { - _state.update { it.copy(isFetchingExternal = false) } - } - } - } - - override fun onClearUnavailableProxies() { - _state.update { - it.copy( - showClearOfflineConfirmation = true, - showRemoveAllConfirmation = false - ) - } - } - - override fun onConfirmClearUnavailableProxies() { - scope.launch { - val proxiesToDelete = _state.value.proxies.filter { it.ping == -1L } - proxiesToDelete.forEach { proxy -> - if (externalProxyRepository.removeProxy(proxy.id)) { - removeProxyFromBackup(proxy) - } - } - _state.update { it.copy(showClearOfflineConfirmation = false) } - refreshProxies(shouldPing = false) - } - } - - override fun onRemoveAllProxies() { - _state.update { - it.copy( - showRemoveAllConfirmation = true, - showClearOfflineConfirmation = false - ) - } - } - - override fun onConfirmRemoveAllProxies() { - scope.launch { - _state.value.proxies.forEach { proxy -> - if (externalProxyRepository.removeProxy(proxy.id)) { - removeProxyFromBackup(proxy) - } - } - _state.update { it.copy(showRemoveAllConfirmation = false) } - refreshProxies(shouldPing = false) - } - } - - override fun onDismissToast() { - _state.update { it.copy(toastMessage = null) } - } - - override fun onDismissMassDeleteDialogs() { - _state.update { - it.copy( - showClearOfflineConfirmation = false, - showRemoveAllConfirmation = false - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/proxy/ProxyContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/proxy/ProxyContent.kt deleted file mode 100644 index 4a846879..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/proxy/ProxyContent.kt +++ /dev/null @@ -1,843 +0,0 @@ -package org.monogram.presentation.settings.proxy - -import android.content.Intent -import android.net.Uri -import androidx.compose.animation.* -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.selection.selectable -import androidx.compose.foundation.selection.selectableGroup -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.Role -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.domain.models.ProxyModel -import org.monogram.domain.models.ProxyTypeModel -import org.monogram.presentation.R -import org.monogram.presentation.features.chats.chatList.components.SettingsTextField -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsSwitchTile -import org.monogram.presentation.core.ui.SettingsTile - -@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) -@Composable -fun ProxyContent(component: ProxyComponent) { - val state by component.state.subscribeAsState() - val snackbarHostState = remember { SnackbarHostState() } - val context = LocalContext.current - - LaunchedEffect(state.toastMessage) { - state.toastMessage?.let { message -> - snackbarHostState.showSnackbar(message) - component.onDismissToast() - } - } - - Scaffold( - snackbarHost = { SnackbarHost(snackbarHostState) }, - topBar = { - TopAppBar( - title = { - Text( - stringResource(R.string.proxy_settings_header), - fontSize = 22.sp, - fontWeight = FontWeight.Bold - ) - }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - }, - actions = { - IconButton(onClick = component::onPingAll) { - Icon(Icons.Rounded.Refresh, contentDescription = stringResource(R.string.refresh_pings_cd)) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.background - ) - ) - }, - floatingActionButton = { - ExtendedFloatingActionButton( - onClick = { component.onAddProxyClicked() }, - containerColor = MaterialTheme.colorScheme.primary, - contentColor = MaterialTheme.colorScheme.onPrimary, - icon = { Icon(Icons.Rounded.Add, contentDescription = null) }, - text = { Text(stringResource(R.string.add_proxy_button)) } - ) - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - LazyColumn( - modifier = Modifier - .fillMaxSize() - .padding(top = padding.calculateTopPadding()), - contentPadding = PaddingValues(16.dp), - verticalArrangement = Arrangement.spacedBy(4.dp) - ) { - item { - SectionHeader(stringResource(R.string.connection_section_header)) - } - item { - Column( - modifier = Modifier - .fillMaxWidth() - .clip(RoundedCornerShape(24.dp)) - .background(MaterialTheme.colorScheme.surfaceContainer) - ) { - AnimatedVisibility( - visible = !state.isTelegaProxyEnabled, - enter = expandVertically() + fadeIn(), - exit = shrinkVertically() + fadeOut() - ) { - SettingsSwitchTile( - icon = Icons.Rounded.Bolt, - title = stringResource(R.string.smart_switching_title), - subtitle = stringResource(R.string.smart_switching_subtitle), - checked = state.isAutoBestProxyEnabled, - iconColor = Color(0xFFAF52DE), - position = ItemPosition.TOP, - onCheckedChange = component::onAutoBestProxyToggled - ) - } - - SettingsSwitchTile( - icon = Icons.Rounded.Public, - title = stringResource(R.string.prefer_ipv6_title), - subtitle = stringResource(R.string.prefer_ipv6_subtitle), - checked = state.preferIpv6, - iconColor = Color(0xFF34A853), - position = if (state.isTelegaProxyEnabled) ItemPosition.TOP else ItemPosition.MIDDLE, - onCheckedChange = component::onPreferIpv6Toggled - ) - - val isDirect = state.proxies.none { it.isEnabled } && state.telegaProxies.none { it.isEnabled } - SettingsTile( - icon = Icons.Rounded.LinkOff, - title = stringResource(R.string.disable_proxy_title), - subtitle = if (isDirect) stringResource(R.string.connected_directly_subtitle) else stringResource( - R.string.switch_to_direct_subtitle - ), - iconColor = if (isDirect) Color(0xFF34A853) else MaterialTheme.colorScheme.error, - position = ItemPosition.BOTTOM, - onClick = { component.onDisableProxy() }, - trailingContent = { - if (isDirect) { - Icon(Icons.Rounded.Check, contentDescription = null, tint = Color(0xFF34A853)) - } - } - ) - } - } - - item { - AnimatedVisibility( - visible = state.isRussianNumber, - enter = expandVertically() + fadeIn(), - exit = shrinkVertically() + fadeOut() - ) { - Column { - SectionHeader( - text = stringResource(R.string.telega_proxy_header), - subtitle = stringResource(R.string.telega_proxy_subtitle), - onSubtitleClick = { - val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://t.me/telegaru")) - context.startActivity(intent) - } - ) - - Column( - modifier = Modifier - .fillMaxWidth() - .clip(RoundedCornerShape(24.dp)) - .background(MaterialTheme.colorScheme.surfaceContainer) - ) { - SettingsSwitchTile( - icon = Icons.Rounded.CloudDownload, - title = stringResource(R.string.enable_telega_proxy_title), - subtitle = stringResource(R.string.enable_telega_proxy_subtitle), - checked = state.isTelegaProxyEnabled, - iconColor = Color(0xFF0088CC), - position = if (state.isTelegaProxyEnabled && state.telegaProxies.isNotEmpty()) ItemPosition.TOP else ItemPosition.STANDALONE, - onCheckedChange = component::onTelegaProxyToggled - ) - - AnimatedVisibility( - visible = state.isTelegaProxyEnabled, - enter = expandVertically() + fadeIn(), - exit = shrinkVertically() + fadeOut() - ) { - SettingsTile( - icon = Icons.Rounded.Refresh, - title = stringResource(R.string.refresh_list_title), - subtitle = stringResource(R.string.refresh_list_subtitle), - iconColor = Color(0xFF0088CC), - position = ItemPosition.BOTTOM, - onClick = { component.onFetchTelegaProxies() }, - trailingContent = { - if (state.isFetchingExternal) { - CircularProgressIndicator( - modifier = Modifier.size(20.dp), - strokeWidth = 2.dp - ) - } - } - ) - } - } - - AnimatedVisibility( - visible = state.isTelegaProxyEnabled && state.telegaProxies.isNotEmpty(), - enter = expandVertically() + fadeIn(), - exit = shrinkVertically() + fadeOut() - ) { - Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { - Spacer(modifier = Modifier.height(8.dp)) - state.telegaProxies.forEachIndexed { index, proxy -> - val position = when { - state.telegaProxies.size == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == state.telegaProxies.size - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - - ProxyItem( - proxy = proxy, - position = position, - onClick = { component.onProxyClicked(proxy) }, - onLongClick = { component.onProxyLongClicked(proxy) }, - onRefreshPing = { component.onPingProxy(proxy.id) } - ) - } - } - } - } - } - } - - item { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(start = 12.dp, bottom = 8.dp, top = 24.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = stringResource(R.string.your_proxies_header), - style = MaterialTheme.typography.titleMedium, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.primary - ) - - if (state.proxies.isNotEmpty()) { - Row { - IconButton(onClick = { component.onClearUnavailableProxies() }) { - Icon( - Icons.Rounded.DeleteSweep, - stringResource(R.string.clear_offline_cd), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - IconButton(onClick = { component.onRemoveAllProxies() }) { - Icon( - Icons.Rounded.DeleteForever, - stringResource(R.string.remove_all_cd), - tint = MaterialTheme.colorScheme.error - ) - } - } - } - } - } - - itemsIndexed(state.proxies, key = { _, it -> it.id }) { index, proxy -> - val position = when { - state.proxies.size == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == state.proxies.size - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - - SwipeToDeleteContainer( - onDelete = { component.onRemoveProxy(proxy.id) } - ) { - ProxyItem( - proxy = proxy, - position = position, - onClick = { component.onProxyClicked(proxy) }, - onLongClick = { component.onProxyLongClicked(proxy) }, - onRefreshPing = { component.onPingProxy(proxy.id) } - ) - } - } - - if (state.proxies.isEmpty() && (!state.isTelegaProxyEnabled || state.telegaProxies.isEmpty()) && !state.isLoading) { - item { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 48.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center - ) { - Icon( - Icons.Rounded.Language, - contentDescription = null, - modifier = Modifier.size(64.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.2f) - ) - Spacer(Modifier.height(16.dp)) - Text( - stringResource(R.string.no_proxies_label), - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } - - item { Spacer(modifier = Modifier.height(80.dp)) } - } - } - - if (state.isAddingProxy || state.proxyToEdit != null) { - ProxyAddEditSheet( - proxy = state.proxyToEdit, - onDismiss = component::onDismissAddEdit, - onTest = component::onTestProxy, - testPing = state.testPing, - isTesting = state.isTesting, - onSave = { server, port, type -> - if (state.proxyToEdit != null) { - component.onEditProxy(state.proxyToEdit!!.id, server, port, type) - } else { - component.onAddProxy(server, port, type) - } - } - ) - } - - state.proxyToDelete?.let { proxy -> - AlertDialog( - onDismissRequest = component::onDismissDeleteConfirmation, - title = { Text(stringResource(R.string.delete_proxy_title)) }, - text = { Text(stringResource(R.string.delete_proxy_confirmation_format, proxy.server)) }, - confirmButton = { - TextButton( - onClick = component::onConfirmDelete, - colors = ButtonDefaults.textButtonColors(contentColor = MaterialTheme.colorScheme.error) - ) { - Text(stringResource(R.string.action_delete)) - } - }, - dismissButton = { - TextButton(onClick = component::onDismissDeleteConfirmation) { - Text(stringResource(R.string.cancel_button)) - } - } - ) - } - - if (state.showClearOfflineConfirmation) { - AlertDialog( - onDismissRequest = component::onDismissMassDeleteDialogs, - title = { Text(stringResource(R.string.clear_offline_title)) }, - text = { Text(stringResource(R.string.clear_offline_confirmation)) }, - confirmButton = { - TextButton( - onClick = component::onConfirmClearUnavailableProxies, - colors = ButtonDefaults.textButtonColors(contentColor = MaterialTheme.colorScheme.error) - ) { - Text(stringResource(R.string.action_delete)) - } - }, - dismissButton = { - TextButton(onClick = component::onDismissMassDeleteDialogs) { - Text(stringResource(R.string.cancel_button)) - } - } - ) - } - - if (state.showRemoveAllConfirmation) { - AlertDialog( - onDismissRequest = component::onDismissMassDeleteDialogs, - title = { Text(stringResource(R.string.remove_all_proxies_title)) }, - text = { Text(stringResource(R.string.remove_all_proxies_confirmation)) }, - confirmButton = { - TextButton( - onClick = component::onConfirmRemoveAllProxies, - colors = ButtonDefaults.textButtonColors(contentColor = MaterialTheme.colorScheme.error) - ) { - Text(stringResource(R.string.action_delete)) - } - }, - dismissButton = { - TextButton(onClick = component::onDismissMassDeleteDialogs) { - Text(stringResource(R.string.cancel_button)) - } - } - ) - } -} - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun ProxyItem( - proxy: ProxyModel, - position: ItemPosition, - onClick: () -> Unit, - onLongClick: () -> Unit, - onRefreshPing: () -> Unit -) { - val typeName = when (proxy.type) { - is ProxyTypeModel.Mtproto -> "MTProto" - is ProxyTypeModel.Socks5 -> "SOCKS5" - is ProxyTypeModel.Http -> "HTTP" - } - - val isEnabled = proxy.isEnabled - - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - val backgroundColor by animateColorAsState( - if (isEnabled) MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.4f) - else MaterialTheme.colorScheme.surfaceContainer, - label = "bg" - ) - - Surface( - color = backgroundColor, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - .combinedClickable( - onClick = onClick, - onLongClick = onLongClick - ) - ) { - Row( - modifier = Modifier.padding(horizontal = 16.dp, vertical = 16.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(44.dp) - .background( - color = if (isEnabled) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surfaceVariant, - shape = CircleShape - ), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = if (isEnabled) Icons.Rounded.Check else Icons.Rounded.Language, - contentDescription = null, - modifier = Modifier.size(24.dp), - tint = if (isEnabled) MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurfaceVariant - ) - } - - Spacer(modifier = Modifier.width(16.dp)) - - Column(modifier = Modifier.weight(1f)) { - Text( - text = proxy.server, - style = MaterialTheme.typography.titleMedium, - maxLines = 1, - color = if (isEnabled) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface - ) - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = typeName, - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier - .background(MaterialTheme.colorScheme.surfaceVariant, RoundedCornerShape(4.dp)) - .padding(horizontal = 4.dp, vertical = 1.dp) - ) - Spacer(Modifier.width(8.dp)) - Text( - text = "Port ${proxy.port}", - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - maxLines = 1 - ) - } - } - - Column(horizontalAlignment = Alignment.End) { - ProxyPingIndicator( - ping = proxy.ping, - isChecking = proxy.ping == null, - ) - - IconButton(onClick = onRefreshPing, modifier = Modifier.size(32.dp)) { - Icon( - Icons.Rounded.Refresh, - contentDescription = stringResource(R.string.refresh_list_title), - modifier = Modifier.size(16.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } - } -} - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun SwipeToDeleteContainer( - onDelete: () -> Unit, - enabled: Boolean = true, - content: @Composable () -> Unit -) { - if (!enabled) { - content() - return - } - - val dismissState = rememberSwipeToDismissBoxState( - confirmValueChange = { - if (it == SwipeToDismissBoxValue.EndToStart) { - onDelete() - true - } else false - } - ) - - SwipeToDismissBox( - state = dismissState, - enableDismissFromStartToEnd = false, - backgroundContent = { - val color by animateColorAsState( - (if (dismissState.targetValue == SwipeToDismissBoxValue.EndToStart) - MaterialTheme.colorScheme.errorContainer - else Color.Transparent), - label = "color" - ) - Box( - Modifier - .fillMaxSize() - .background(color) - .padding(horizontal = 20.dp), - contentAlignment = Alignment.CenterEnd - ) { - if (dismissState.targetValue == SwipeToDismissBoxValue.EndToStart) { - Icon( - Icons.Rounded.Delete, - contentDescription = stringResource(R.string.action_delete), - tint = MaterialTheme.colorScheme.onErrorContainer - ) - } - } - }, - content = { content() } - ) -} - -@Composable -private fun SectionHeader( - text: String, - subtitle: String? = null, - onSubtitleClick: (() -> Unit)? = null -) { - Column(modifier = Modifier.padding(start = 12.dp, bottom = 8.dp, top = 16.dp)) { - Text( - text = text, - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) - if (subtitle != null) { - Text( - text = subtitle, - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = if (onSubtitleClick != null) { - Modifier.clickable(onClick = onSubtitleClick) - } else { - Modifier - } - ) - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ProxyAddEditSheet( - proxy: ProxyModel?, - onDismiss: () -> Unit, - onTest: (String, Int, ProxyTypeModel) -> Unit, - testPing: Long?, - isTesting: Boolean, - onSave: (String, Int, ProxyTypeModel) -> Unit -) { - val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) - - var server by remember { mutableStateOf(proxy?.server ?: "") } - var port by remember { mutableStateOf(proxy?.port?.toString() ?: "") } - var type by remember { - mutableStateOf( - when (proxy?.type) { - is ProxyTypeModel.Socks5 -> "SOCKS5" - is ProxyTypeModel.Http -> "HTTP" - else -> "MTProto" - } - ) - } - - var secret by remember { mutableStateOf((proxy?.type as? ProxyTypeModel.Mtproto)?.secret ?: "") } - var username by remember { - mutableStateOf( - when (val t = proxy?.type) { - is ProxyTypeModel.Socks5 -> t.username - is ProxyTypeModel.Http -> t.username - else -> "" - } - ) - } - var password by remember { - mutableStateOf( - when (val t = proxy?.type) { - is ProxyTypeModel.Socks5 -> t.password - is ProxyTypeModel.Http -> t.password - else -> "" - } - ) - } - - val currentProxyType = remember(type, secret, username, password) { - when (type) { - "MTProto" -> ProxyTypeModel.Mtproto(secret) - "SOCKS5" -> ProxyTypeModel.Socks5(username, password) - else -> ProxyTypeModel.Http(username, password, false) - } - } - - val isInputValid = server.isNotBlank() && port.isNotBlank() && (type != "MTProto" || secret.isNotBlank()) - - ModalBottomSheet( - onDismissRequest = onDismiss, - sheetState = sheetState, - dragHandle = { BottomSheetDefaults.DragHandle() }, - containerColor = MaterialTheme.colorScheme.surface, - shape = RoundedCornerShape(topStart = 28.dp, topEnd = 28.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 32.dp) - ) { - Text( - text = if (proxy == null) stringResource(R.string.new_proxy_title) else stringResource(R.string.edit_proxy_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold - ) - - Spacer(modifier = Modifier.height(24.dp)) - - Row( - Modifier - .selectableGroup() - .fillMaxWidth() - .background(MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f), RoundedCornerShape(50)) - .padding(4.dp), - horizontalArrangement = Arrangement.SpaceBetween - ) { - listOf("MTProto", "SOCKS5", "HTTP").forEach { text -> - val selected = (text == type) - Box( - Modifier - .weight(1f) - .height(44.dp) - .clip(RoundedCornerShape(50)) - .background(if (selected) MaterialTheme.colorScheme.primary else Color.Transparent) - .selectable( - selected = selected, - onClick = { type = text }, - role = Role.RadioButton - ), - contentAlignment = Alignment.Center - ) { - Text( - text = text, - style = MaterialTheme.typography.labelLarge, - color = if (selected) MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurfaceVariant, - fontWeight = if (selected) FontWeight.Bold else FontWeight.Normal - ) - } - } - } - - Spacer(modifier = Modifier.height(24.dp)) - - SettingsTextField( - value = server, - onValueChange = { server = it }, - placeholder = stringResource(R.string.server_address_placeholder), - icon = Icons.Rounded.Language, - position = ItemPosition.TOP, - singleLine = true - ) - - SettingsTextField( - value = port, - onValueChange = { if (it.all { char -> char.isDigit() }) port = it }, - placeholder = stringResource(R.string.port_placeholder), - icon = Icons.Rounded.Numbers, - position = ItemPosition.BOTTOM, - singleLine = true - ) - - Spacer(modifier = Modifier.height(16.dp)) - - AnimatedContent(targetState = type, label = "TypeFields") { targetType -> - Column { - when (targetType) { - "MTProto" -> { - SettingsTextField( - value = secret, - onValueChange = { secret = it }, - placeholder = stringResource(R.string.secret_hex_placeholder), - icon = Icons.Rounded.Key, - position = ItemPosition.STANDALONE, - singleLine = true - ) - } - - "SOCKS5", "HTTP" -> { - SettingsTextField( - value = username, - onValueChange = { username = it }, - placeholder = stringResource(R.string.username_optional_placeholder), - icon = Icons.Rounded.Person, - position = ItemPosition.TOP, - singleLine = true - ) - SettingsTextField( - value = password, - onValueChange = { password = it }, - placeholder = stringResource(R.string.password_optional_placeholder), - icon = Icons.Rounded.Password, - position = ItemPosition.BOTTOM, - singleLine = true - ) - } - } - } - } - - Spacer(modifier = Modifier.height(32.dp)) - - if (testPing != null || isTesting) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 12.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = stringResource(R.string.test_proxy_result), - style = MaterialTheme.typography.labelLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - ProxyPingIndicator( - ping = testPing, - isChecking = isTesting - ) - } - } - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - OutlinedButton( - onClick = { - val p = port.toIntOrNull() ?: 443 - onTest(server, p, currentProxyType) - }, - enabled = isInputValid && !isTesting, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - if (isTesting) { - CircularProgressIndicator( - modifier = Modifier.size(18.dp), - strokeWidth = 2.dp - ) - } else { - Text(stringResource(R.string.test_proxy_button)) - } - } - - Button( - onClick = { - val p = port.toIntOrNull() ?: 443 - onSave(server, p, currentProxyType) - }, - enabled = isInputValid, - modifier = Modifier - .weight(1f) - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text( - if (proxy == null) stringResource(R.string.add_proxy_button) else stringResource(R.string.save_changes_button), - fontSize = 16.sp, - fontWeight = FontWeight.Bold - ) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/proxy/ProxyPingIndicator.kt b/presentation/src/main/java/org/monogram/presentation/settings/proxy/ProxyPingIndicator.kt deleted file mode 100644 index adfad522..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/proxy/ProxyPingIndicator.kt +++ /dev/null @@ -1,81 +0,0 @@ -package org.monogram.presentation.settings.proxy - -import androidx.compose.animation.core.* -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.presentation.R - -@Composable -fun ProxyPingIndicator( - ping: Long?, - isChecking: Boolean, - modifier: Modifier = Modifier -) { - if (!isChecking && ping == null) return - - Row( - modifier = modifier, - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.End - ) { - if (isChecking) { - val infiniteTransition = rememberInfiniteTransition(label = "ping") - val alpha by infiniteTransition.animateFloat( - initialValue = 0.3f, - targetValue = 1f, - animationSpec = infiniteRepeatable( - animation = tween(800, easing = LinearEasing), - repeatMode = RepeatMode.Reverse - ), - label = "alpha" - ) - - Box( - modifier = Modifier - .size(8.dp) - .alpha(alpha) - .background(MaterialTheme.colorScheme.outline, CircleShape) - ) - Spacer(Modifier.width(4.dp)) - Text( - stringResource(R.string.proxy_checking), - style = MaterialTheme.typography.labelSmall, - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f) - ) - } else { - val (color, text) = when { - ping == null || ping == -1L -> Color(0xFFEA4335) to stringResource(R.string.proxy_offline) - ping < 300 -> Color(0xFF34A853) to stringResource(R.string.proxy_ping_format, ping) - ping < 800 -> Color(0xFFFBBC04) to stringResource(R.string.proxy_ping_format, ping) - else -> Color(0xFFEA4335) to stringResource(R.string.proxy_ping_format, ping) - } - - Box( - modifier = Modifier - .size(8.dp) - .background(color, CircleShape) - ) - Spacer(Modifier.width(4.dp)) - Text( - text = text, - style = MaterialTheme.typography.labelSmall, - fontWeight = FontWeight.Bold, - color = color, - fontSize = 11.sp - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/sessions/SessionItem.kt b/presentation/src/main/java/org/monogram/presentation/settings/sessions/SessionItem.kt deleted file mode 100644 index adb5cc86..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/sessions/SessionItem.kt +++ /dev/null @@ -1,214 +0,0 @@ -package org.monogram.presentation.settings.sessions - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.Logout -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.graphics.vector.rememberVectorPainter -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.monogram.domain.models.SessionModel -import org.monogram.domain.models.SessionType -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ItemPosition -import java.text.SimpleDateFormat -import java.util.* - -@Composable -fun SessionItem( - session: SessionModel, - isPending: Boolean = false, - position: ItemPosition = ItemPosition.STANDALONE, - onTerminate: (() -> Unit)? -) { - val isOculus = remember(session.type, session.deviceModel) { - session.type == SessionType.Android && session.deviceModel.contains("OculusQuest", ignoreCase = true) - } - - val isChrome = remember(session.type, session.deviceModel) { - session.type == SessionType.Chrome || session.deviceModel.contains("Chrome", ignoreCase = true) - } - - val brandColor = remember(session.type, isPending, isOculus) { - if (isPending) return@remember Color(0xFFF9AB00) - if (isOculus) return@remember Color(0xFF000000) - if (isChrome) return@remember Color(0xFF4285F4) - - when (session.type) { - SessionType.Android -> Color(0xFF34A853) - SessionType.Linux, SessionType.Ubuntu -> Color(0xFFFCC624) - SessionType.Apple, SessionType.Mac, SessionType.Iphone, SessionType.Ipad -> Color(0xFF000000) - SessionType.Windows -> Color(0xFF0078D7) - SessionType.Chrome -> Color(0xFF4285F4) - SessionType.Edge -> Color(0xFF0078D7) - SessionType.Firefox -> Color(0xFFE66000) - SessionType.Safari -> Color(0xFF007AFF) - SessionType.Opera -> Color(0xFFFF1B2D) - SessionType.Vivaldi -> Color(0xFFEF3939) - SessionType.Brave -> Color(0xFFFF1B2D) - SessionType.Xbox -> Color(0xFF107C10) - else -> Color(0xFF4285F4) - } - } - - val iconPainter: Painter = when { - isPending -> rememberVectorPainter(Icons.Rounded.Warning) - isOculus -> painterResource(R.drawable.ic_oculus) - isChrome -> painterResource(R.drawable.ic_chrome) - - session.type == SessionType.Android -> rememberVectorPainter(Icons.Rounded.Android) - session.type in listOf( - SessionType.Apple, - SessionType.Mac, - SessionType.Iphone, - SessionType.Ipad - ) -> painterResource(R.drawable.ic_apple) - - session.type == SessionType.Windows -> painterResource(R.drawable.ic_windows) - session.type in listOf(SessionType.Linux, SessionType.Ubuntu) -> rememberVectorPainter(Icons.Rounded.Terminal) - - session.type == SessionType.Chrome -> painterResource(R.drawable.ic_chrome) - session.type == SessionType.Xbox -> rememberVectorPainter(Icons.Rounded.VideogameAsset) - - session.type in listOf( - SessionType.Firefox, - SessionType.Safari, - SessionType.Edge, - SessionType.Opera, - SessionType.Brave, - SessionType.Vivaldi - ) -> rememberVectorPainter(Icons.Rounded.Language) - - else -> rememberVectorPainter(Icons.Rounded.Laptop) - } - - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 12.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(40.dp) - .background(color = brandColor.copy(alpha = 0.15f), shape = CircleShape), - contentAlignment = Alignment.Center - ) { - val iconTint = when { - isPending -> brandColor - isOculus -> Color.Unspecified - isChrome -> Color.Unspecified - session.type == SessionType.Chrome -> Color.Unspecified - else -> brandColor - } - - Icon( - painter = iconPainter, - contentDescription = null, - modifier = Modifier.size(24.dp), - tint = iconTint - ) - } - - Spacer(modifier = Modifier.width(16.dp)) - - Column( - modifier = Modifier.weight(1f), - verticalArrangement = Arrangement.Center - ) { - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = if (isPending) "Попытка входа" else session.deviceModel, - style = MaterialTheme.typography.titleMedium, - fontSize = 18.sp, - fontWeight = if (isPending) FontWeight.Bold else FontWeight.Normal, - color = MaterialTheme.colorScheme.onSurface - ) - - if (session.isOfficial && !isPending) { - Spacer(modifier = Modifier.width(6.dp)) - Icon( - imageVector = Icons.Rounded.Verified, - contentDescription = "Official", - modifier = Modifier.size(16.dp), - tint = Color(0xFF31A6FD) - ) - } - } - - Text( - text = if (isPending) "${session.deviceModel} • ${session.location}" - else "${session.applicationName} ${session.applicationVersion} • ${session.platform}", - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - - Text( - text = if (isPending) "Не подтверждено • ${convertTimestampToTimeLegacy(session.lastActiveDate.toLong())}" - else "${session.location} • ${convertTimestampToTimeLegacy(session.lastActiveDate.toLong())}", - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f) - ) - } - - if (onTerminate != null) { - IconButton( - onClick = onTerminate, - modifier = Modifier.padding(start = 8.dp) - ) { - Icon( - imageVector = Icons.AutoMirrored.Rounded.Logout, - contentDescription = "Terminate session", - tint = MaterialTheme.colorScheme.error - ) - } - } - } - } -} - -private fun convertTimestampToTimeLegacy(timestamp: Long): String { - val date = Date(timestamp) - val format = SimpleDateFormat("HH:mm", Locale.getDefault()) - return format.format(date) -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/settings/sessions/SessionsComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/sessions/SessionsComponent.kt deleted file mode 100644 index 242f8b7e..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/sessions/SessionsComponent.kt +++ /dev/null @@ -1,81 +0,0 @@ -package org.monogram.presentation.settings.sessions - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.launch -import org.monogram.domain.models.SessionModel -import org.monogram.domain.repository.SettingsRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.root.AppComponentContext - -interface SessionsComponent { - val state: Value - fun onBackClicked() - fun terminateSession(id: Long) - fun onQrCodeScanned(link: String) - fun confirmAuth() - fun dismissAuth() - fun toggleScanner(show: Boolean) - fun refresh() - - data class State( - val sessions: List = emptyList(), - val isLoading: Boolean = false, - val isScanning: Boolean = false, - val pendingLink: String? = null, - val showConfirmation: Boolean = false - ) -} - -class DefaultSessionsComponent( - context: AppComponentContext, - private val onBack: () -> Unit -) : SessionsComponent, AppComponentContext by context { - - private val repository: SettingsRepository = container.repositories.settingsRepository - private val _state = MutableValue(SessionsComponent.State()) - override val state: Value = _state - private val scope = componentScope - - init { - refresh() - } - - override fun refresh() { - _state.update { it.copy(isLoading = true) } - scope.launch { - val list = repository.getActiveSessions() - _state.update { it.copy(sessions = list, isLoading = false) } - } - } - - override fun terminateSession(id: Long) { - scope.launch { - if (repository.terminateSession(id)) refresh() - } - } - - override fun onQrCodeScanned(link: String) { - _state.update { it.copy(pendingLink = link, showConfirmation = true, isScanning = false) } - } - - override fun confirmAuth() { - val link = _state.value.pendingLink ?: return - _state.update { it.copy(showConfirmation = false, isLoading = true, pendingLink = null) } - scope.launch { - val success = repository.confirmQrCode(link) - if (success) refresh() else _state.update { it.copy(isLoading = false) } - } - } - - override fun dismissAuth() { - _state.update { it.copy(showConfirmation = false, pendingLink = null) } - } - - override fun toggleScanner(show: Boolean) { - _state.update { it.copy(isScanning = show) } - } - - override fun onBackClicked() = onBack() -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/settings/sessions/SessionsContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/sessions/SessionsContent.kt deleted file mode 100644 index 958d7a70..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/sessions/SessionsContent.kt +++ /dev/null @@ -1,236 +0,0 @@ -package org.monogram.presentation.settings.sessions - -import android.Manifest -import android.content.pm.PackageManager -import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.core.tween -import androidx.compose.animation.fadeOut -import androidx.compose.animation.shrinkVertically -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.QrCodeScanner -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.core.content.ContextCompat -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import kotlinx.coroutines.delay -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.IntegratedQRScanner -import org.monogram.presentation.core.ui.ItemPosition - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun SessionsContent(component: SessionsComponent) { - val state by component.state.subscribeAsState() - val context = LocalContext.current - val cameraPermissionLauncher = rememberLauncherForActivityResult( - contract = ActivityResultContracts.RequestPermission() - ) { isGranted -> - if (isGranted) { - component.toggleScanner(true) - } - } - - fun checkPermissionAndScan() { - when (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA)) { - PackageManager.PERMISSION_GRANTED -> component.toggleScanner(true) - else -> cameraPermissionLauncher.launch(Manifest.permission.CAMERA) - } - } - if (state.showConfirmation) { - AlertDialog( - onDismissRequest = component::dismissAuth, - title = { Text(stringResource(R.string.confirmation_title)) }, - text = { Text(stringResource(R.string.confirmation_message)) }, - confirmButton = { - Button(onClick = component::confirmAuth) { - Text(stringResource(R.string.confirm_auth_action)) - } - }, - dismissButton = { - TextButton(onClick = component::dismissAuth) { - Text(stringResource(R.string.cancel_action)) - } - } - ) - } - - Scaffold( - topBar = { - TopAppBar( - title = { - Text( - text = if (state.isScanning) - stringResource(R.string.scan_qr_title) - else - stringResource(R.string.devices_title), - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - }, - navigationIcon = { - IconButton(onClick = { - if (state.isScanning) component.toggleScanner(false) else component.onBackClicked() - }) { - Icon( - imageVector = Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_navigate_back) - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background - ) - ) - }, - floatingActionButton = { - if (!state.isScanning) { - ExtendedFloatingActionButton( - onClick = { checkPermissionAndScan() }, - icon = { - Icon( - Icons.Rounded.QrCodeScanner, - contentDescription = stringResource(R.string.cd_qr_icon) - ) - }, - text = { Text(stringResource(R.string.link_device_action)) }, - containerColor = MaterialTheme.colorScheme.primary, - contentColor = MaterialTheme.colorScheme.onPrimary - ) - } - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - Box( - modifier = Modifier - .padding(top = padding.calculateTopPadding()) - .fillMaxSize() - ) { - val (current, others) = state.sessions.partition { it.isCurrent } - val (pending, active) = others.partition { it.isUnconfirmed } - - LazyColumn( - modifier = Modifier.fillMaxSize(), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, top = 0.dp, bottom = 16.dp), - verticalArrangement = Arrangement.spacedBy(16.dp) - ) { - if (current.isNotEmpty()) { - item { - SectionHeader(stringResource(R.string.current_device_section)) - } - items(current, key = { it.id }) { session -> - SessionItem( - session = session, - isPending = false, - position = ItemPosition.STANDALONE, - onTerminate = null - ) - } - } - - if (pending.isNotEmpty()) { - item { - SectionHeader(stringResource(R.string.login_requests_section)) - } - items(pending, key = { it.id }) { session -> - var isVisible by remember { mutableStateOf(true) } - LaunchedEffect(isVisible) { - if (!isVisible) { - delay(350) - component.terminateSession(session.id) - } - } - - AnimatedVisibility( - visible = isVisible, - exit = shrinkVertically(animationSpec = tween(300)) + - fadeOut(animationSpec = tween(300)) - ) { - SessionItem( - session = session, - isPending = true, - position = ItemPosition.STANDALONE - ) { - isVisible = false - } - } - } - } - - if (active.isNotEmpty()) { - item { - SectionHeader(stringResource(R.string.active_sessions_section)) - } - items(active, key = { it.id }) { session -> - var isVisible by remember { mutableStateOf(true) } - LaunchedEffect(isVisible) { - if (!isVisible) { - delay(350) - component.terminateSession(session.id) - } - } - - AnimatedVisibility( - visible = isVisible, - exit = shrinkVertically(animationSpec = tween(300)) + - fadeOut(animationSpec = tween(300)) - ) { - SessionItem( - session = session, - isPending = false, - position = ItemPosition.STANDALONE - ) { - isVisible = false - } - } - } - } - - item { Spacer(modifier = Modifier.height(padding.calculateBottomPadding())) } - } - if (state.isScanning) { - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.Black) - ) { - IntegratedQRScanner( - onCodeDetected = component::onQrCodeScanned, - onBackClicked = { component.toggleScanner(false) } - ) - } - } - - if (state.isLoading) { - CircularProgressIndicator(Modifier.align(Alignment.Center)) - } - } - } -} - -@Composable -fun SectionHeader(text: String) { - Text( - text = text, - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp, top = 16.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/settings/settings/DefaultSettingsComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/settings/DefaultSettingsComponent.kt deleted file mode 100644 index 62f3f6ca..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/settings/DefaultSettingsComponent.kt +++ /dev/null @@ -1,212 +0,0 @@ -package org.monogram.presentation.settings.settings - -import org.monogram.presentation.core.util.coRunCatching -import android.os.Build -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.collectLatest -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch -import org.monogram.domain.managers.DomainManager -import org.monogram.domain.repository.AppPreferencesProvider -import org.monogram.domain.repository.ExternalNavigator -import org.monogram.domain.repository.UserRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool -import org.monogram.presentation.root.AppComponentContext - -class DefaultSettingsComponent( - context: AppComponentContext, - private val onBack: () -> Unit, - private val onEditProfileClick: () -> Unit, - private val onDevicesClick: () -> Unit, - private val onFoldersClick: () -> Unit, - private val onChatSettingsClick: () -> Unit, - private val onDataStorageClick: () -> Unit, - private val onPowerSavingClick: () -> Unit, - private val onPremiumClick: () -> Unit, - private val onPrivacyClick: () -> Unit, - private val onNotificationsClick: () -> Unit, - private val onProxySettingsClick: () -> Unit, - private val onStickersClick: () -> Unit, - private val onAboutClick: () -> Unit, - private val onDebugClick: () -> Unit -) : SettingsComponent, AppComponentContext by context { - - private val repository: UserRepository = container.repositories.userRepository - private val externalNavigator: ExternalNavigator = container.utils.externalNavigator() - private val domainManager: DomainManager = container.utils.domainManager() - private val preferences: AppPreferencesProvider = container.preferences.appPreferences - override val videoPlayerPool: VideoPlayerPool = container.utils.videoPlayerPool - - private val _state = MutableValue(SettingsComponent.State()) - override val state: Value = _state - private val scope = componentScope - - init { - scope.launch { - try { - val me = repository.getMe() - val link = if (me.username?.isNotEmpty() == true) "https://t.me/${me.username}" else "" - - _state.update { - it.copy( - currentUser = me, - qrContent = link - ) - } - - repository.getUserProfilePhotosFlow(me.id) - .onEach { photos -> - val highResPhoto = photos.firstOrNull { it.endsWith(".mp4", ignoreCase = true) } - ?: photos.firstOrNull() - if (highResPhoto != null) { - _state.update { state -> - state.copy( - currentUser = state.currentUser?.copy(avatarPath = highResPhoto) - ) - } - } - } - .launchIn(scope) - - } catch (e: Exception) { - _state.update { it.copy(currentUser = null) } - } - } - - scope.launch { - preferences.isSupportViewed.collectLatest { viewed -> - if (!viewed) { - _state.update { it.copy(isSupportVisible = true) } - } - } - } - checkLinkStatus() - } - - override fun onBackClicked() { - onBack() - } - - override fun onEditProfileClicked() { - onEditProfileClick() - } - - override fun onLogoutClicked() { - repository.logOut() - } - - override fun onNotificationToggled(enabled: Boolean) { - _state.update { it.copy(areNotificationsEnabled = enabled) } - } - - override fun onDevicesClicked() { - onDevicesClick() - } - - override fun onFoldersClicked() { - onFoldersClick() - } - - override fun onChatSettingsClicked() { - onChatSettingsClick() - } - - override fun onDataStorageClicked() { - onDataStorageClick() - } - - override fun onPowerSavingClicked() { - onPowerSavingClick() - } - - override fun onPremiumClicked() { - onPremiumClick() - } - - override fun onPrivacyClicked() { - onPrivacyClick() - } - - override fun onNotificationsClicked() { - onNotificationsClick() - } - - override fun onLinkSettingsClicked() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - externalNavigator.navigateToLinkSettings() - } - } - - override fun checkLinkStatus() { - _state.update { it.copy(isTMeLinkEnabled = domainManager.isEnabled() ) } - } - - override fun onQrCodeClicked() { - _state.update { it.copy(isQrVisible = true) } - } - - override fun onQrCodeDismissed() { - _state.update { it.copy(isQrVisible = false) } - } - - override fun onProxySettingsClicked() { - onProxySettingsClick() - } - - override fun onStickersClicked() { - onStickersClick() - } - - override fun onAboutClicked() { - onAboutClick() - } - - override fun onDebugClicked() { - onDebugClick() - } - - override fun onSupportClicked() { - externalNavigator.openUrl("https://boosty.to/monogram") - onSupportDismissed() - } - - override fun onSupportDismissed() { - preferences.setSupportViewed(true) - _state.update { it.copy(isSupportVisible = false) } - } - - override fun onShowSupportClicked() { - _state.update { it.copy(isSupportVisible = true) } - } - - override fun onMoreOptionsClicked() { - _state.update { it.copy(isMoreOptionsVisible = true) } - } - - override fun onMoreOptionsDismissed() { - _state.update { it.copy(isMoreOptionsVisible = false) } - } - - override fun onSetEmojiStatus(customEmojiId: Long, statusPath: String?) { - _state.update { state -> - val user = state.currentUser ?: return@update state - state.copy( - currentUser = user.copy( - statusEmojiId = customEmojiId, - statusEmojiPath = statusPath ?: user.statusEmojiPath - ) - ) - } - - scope.launch(Dispatchers.IO) { - coRunCatching { - repository.setEmojiStatus(customEmojiId) - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/settings/SettingsComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/settings/SettingsComponent.kt deleted file mode 100644 index 83cbb5d3..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/settings/SettingsComponent.kt +++ /dev/null @@ -1,47 +0,0 @@ -package org.monogram.presentation.settings.settings - -import com.arkivanov.decompose.value.Value -import org.monogram.domain.models.UserModel -import org.monogram.presentation.features.chats.currentChat.components.VideoPlayerPool - -interface SettingsComponent { - val state: Value - val videoPlayerPool: VideoPlayerPool - - fun onBackClicked() - fun onEditProfileClicked() - fun onLogoutClicked() - fun onNotificationToggled(enabled: Boolean) - fun onDevicesClicked() - fun onFoldersClicked() - fun onChatSettingsClicked() - fun onDataStorageClicked() - fun onPowerSavingClicked() - fun onPremiumClicked() - fun onPrivacyClicked() - fun onNotificationsClicked() - fun onLinkSettingsClicked() - fun checkLinkStatus() - fun onQrCodeClicked() - fun onQrCodeDismissed() - fun onProxySettingsClicked() - fun onStickersClicked() - fun onAboutClicked() - fun onDebugClicked() - fun onSupportClicked() - fun onSupportDismissed() - fun onShowSupportClicked() - fun onMoreOptionsClicked() - fun onMoreOptionsDismissed() - fun onSetEmojiStatus(customEmojiId: Long, statusPath: String?) - - data class State( - val currentUser: UserModel? = null, - val areNotificationsEnabled: Boolean = true, - val isTMeLinkEnabled: Boolean = true, - val isQrVisible: Boolean = false, - val qrContent: String = "", - val isSupportVisible: Boolean = false, - val isMoreOptionsVisible: Boolean = false - ) -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/settings/SettingsContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/settings/SettingsContent.kt deleted file mode 100644 index 59c4006b..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/settings/SettingsContent.kt +++ /dev/null @@ -1,980 +0,0 @@ -package org.monogram.presentation.settings.settings - -import android.content.Intent -import android.net.Uri -import android.os.Build -import android.provider.Settings -import androidx.activity.compose.BackHandler -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.core.MutableTransitionState -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.tween -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.scaleIn -import androidx.compose.animation.scaleOut -import androidx.compose.animation.slideInVertically -import androidx.compose.animation.slideOutVertically -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.BoxWithConstraints -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.heightIn -import androidx.compose.foundation.layout.navigationBars -import androidx.compose.foundation.layout.offset -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.statusBars -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.Chat -import androidx.compose.material.icons.automirrored.rounded.ExitToApp -import androidx.compose.material.icons.filled.MoreVert -import androidx.compose.material.icons.filled.PhoneIphone -import androidx.compose.material.icons.filled.QrCode2 -import androidx.compose.material.icons.filled.Share -import androidx.compose.material.icons.filled.Star -import androidx.compose.material.icons.rounded.ArrowBack -import androidx.compose.material.icons.rounded.BugReport -import androidx.compose.material.icons.rounded.DataUsage -import androidx.compose.material.icons.rounded.Edit -import androidx.compose.material.icons.rounded.Favorite -import androidx.compose.material.icons.rounded.Folder -import androidx.compose.material.icons.rounded.Info -import androidx.compose.material.icons.rounded.Language -import androidx.compose.material.icons.rounded.Link -import androidx.compose.material.icons.rounded.Lock -import androidx.compose.material.icons.rounded.Notifications -import androidx.compose.material.icons.rounded.Person -import androidx.compose.material.icons.rounded.PowerSettingsNew -import androidx.compose.material.icons.rounded.SentimentSatisfiedAlt -import androidx.compose.material.icons.rounded.SettingsEthernet -import androidx.compose.material.icons.rounded.Star -import androidx.compose.material.icons.rounded.Verified -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.Card -import androidx.compose.material3.CardDefaults -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.ModalBottomSheet -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.material3.TextButton -import androidx.compose.material3.TopAppBar -import androidx.compose.material3.TopAppBarDefaults -import androidx.compose.material3.rememberModalBottomSheetState -import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisposableEffect -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.Rect -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.TransformOrigin -import androidx.compose.ui.graphics.lerp -import androidx.compose.ui.hapticfeedback.HapticFeedbackType -import androidx.compose.ui.layout.boundsInRoot -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.platform.LocalClipboardManager -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.LocalHapticFeedback -import androidx.compose.ui.platform.LocalLifecycleOwner -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.IntOffset -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.lerp -import androidx.compose.ui.unit.sp -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleEventObserver -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.CollapsingToolbarScaffold -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsItem -import org.monogram.presentation.core.ui.StyledQRCode -import org.monogram.presentation.core.ui.UserProfileHeader -import org.monogram.presentation.core.ui.UsernamesTile -import org.monogram.presentation.core.ui.generatePureBitmap -import org.monogram.presentation.core.ui.rememberCollapsingToolbarScaffoldState -import org.monogram.presentation.core.ui.saveBitmapToGallery -import org.monogram.presentation.core.ui.shareBitmap -import org.monogram.presentation.core.util.CountryManager -import org.monogram.presentation.core.util.ScrollStrategy -import org.monogram.presentation.core.util.formatMaskedGlobal -import org.monogram.presentation.features.stickers.ui.menu.EmojisGrid -import org.monogram.presentation.features.stickers.ui.view.StickerImage -import org.monogram.presentation.settings.sessions.SectionHeader -import java.util.Locale -import kotlin.math.roundToInt - -val QrBackgroundColor = Color(0xFFEFF1E6) -val QrDarkGreen = Color(0xFF3E4D36) -val QrSurfaceShapeColor = Color(0xFFE3E6D8) - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun SettingsContent(component: SettingsComponent) { - val state by component.state.subscribeAsState() - val context = LocalContext.current - val lifecycleOwner = LocalLifecycleOwner.current - val haptic = LocalHapticFeedback.current - val blueColor = Color(0xFF4285F4) - val greenColor = Color(0xFF34A853) - val orangeColor = Color(0xFFF9AB00) - val pinkColor = Color(0xFFFF6D66) - val tealColor = Color(0xFF00BFA5) - val purpleColor = Color(0xFFAF52DE) - val indigoColor = Color(0xFF536DFE) - val phoneColor = Color(0xFF007AFF) - val usernameColor = Color(0xFF34C759) - val idColor = Color(0xFFAF52DE) - - val collapsingToolbarState = rememberCollapsingToolbarScaffoldState() - var isPhoneVisible by remember { mutableStateOf(false) } - var showStatusMenu by remember { mutableStateOf(false) } - var statusAnchorBounds by remember { mutableStateOf(null) } - var topBarStatusAnchorBounds by remember { mutableStateOf(null) } - var headerStatusAnchorBounds by remember { mutableStateOf(null) } - val statusMenuTransitionState = remember { MutableTransitionState(false) } - val density = LocalDensity.current - - LaunchedEffect(showStatusMenu) { - statusMenuTransitionState.targetState = showStatusMenu - } - - var cachedStatusEmojiPath by remember(state.currentUser?.id) { - mutableStateOf(state.currentUser?.statusEmojiPath) - } - - LaunchedEffect(state.currentUser?.id, state.currentUser?.statusEmojiPath) { - val statusEmojiPath = state.currentUser?.statusEmojiPath - if (!statusEmojiPath.isNullOrBlank()) { - cachedStatusEmojiPath = statusEmojiPath - } - } - - val currentUser = remember(state.currentUser, cachedStatusEmojiPath) { - state.currentUser?.let { user -> - if (user.statusEmojiId != 0L && user.statusEmojiPath.isNullOrBlank() && !cachedStatusEmojiPath.isNullOrBlank()) { - user.copy(statusEmojiPath = cachedStatusEmojiPath) - } else { - user - } - } - } - - val clipboardManager = LocalClipboardManager.current - val collapsedColor = MaterialTheme.colorScheme.surface - val expandedColor = MaterialTheme.colorScheme.background - val dynamicContainerColor = lerp( - start = collapsedColor, - stop = expandedColor, - fraction = collapsingToolbarState.toolbarState.progress - ) - val dynamicContainerColorTopBar = lerp( - start = collapsedColor, - stop = Color.Transparent, - fraction = collapsingToolbarState.toolbarState.progress - ) - - DisposableEffect(lifecycleOwner) { - val observer = LifecycleEventObserver { _, event -> - if (event == Lifecycle.Event.ON_RESUME) { - component.checkLinkStatus() - } - } - lifecycleOwner.lifecycle.addObserver(observer) - onDispose { - lifecycleOwner.lifecycle.removeObserver(observer) - } - } - - BackHandler(enabled = showStatusMenu) { - showStatusMenu = false - } - - if (state.isQrVisible) { - val sheetState = rememberModalBottomSheetState() - ModalBottomSheet( - onDismissRequest = component::onQrCodeDismissed, - sheetState = sheetState, - containerColor = MaterialTheme.colorScheme.background, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - val username = state.currentUser?.username ?: "user" - val qrContent = state.qrContent.ifEmpty { "https://t.me/$username" } - - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 48.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Text( - text = stringResource(R.string.qr_code_title), - style = MaterialTheme.typography.titleLarge, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.primary, - modifier = Modifier.padding(bottom = 24.dp) - ) - - Box( - modifier = Modifier - .size(300.dp) - .background(QrSurfaceShapeColor, RoundedCornerShape(32.dp)), - contentAlignment = Alignment.Center - ) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - StyledQRCode( - content = qrContent, - modifier = Modifier.size(200.dp), - primaryColor = QrDarkGreen, - backgroundColor = QrSurfaceShapeColor - ) - Spacer(modifier = Modifier.height(16.dp)) - Text( - text = "@$username", - color = QrDarkGreen, - fontSize = 18.sp, - fontWeight = FontWeight.Medium - ) - } - } - - Spacer(modifier = Modifier.height(32.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - Button( - onClick = { - val bitmap = generatePureBitmap(qrContent, 1024) - saveBitmapToGallery(context, bitmap) - }, - modifier = Modifier - .weight(1f) - .height(50.dp), - colors = ButtonDefaults.buttonColors(containerColor = QrDarkGreen), - shape = RoundedCornerShape(12.dp) - ) { Text(stringResource(R.string.action_save)) } - - Button( - onClick = { - val bitmap = generatePureBitmap(qrContent, 1024) - shareBitmap(context, bitmap) - }, - modifier = Modifier - .weight(1f) - .height(50.dp), - colors = ButtonDefaults.buttonColors(containerColor = QrDarkGreen), - shape = RoundedCornerShape(12.dp) - ) { Text(stringResource(R.string.action_share)) } - } - } - } - } - - if (state.isSupportVisible) { - val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) - ModalBottomSheet( - onDismissRequest = component::onSupportDismissed, - sheetState = sheetState, - containerColor = MaterialTheme.colorScheme.surface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 48.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Icon( - imageVector = Icons.Rounded.Favorite, - contentDescription = null, - modifier = Modifier.size(64.dp), - tint = pinkColor - ) - Spacer(modifier = Modifier.height(16.dp)) - Text( - text = stringResource(R.string.support_monogram_title), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.Bold, - textAlign = TextAlign.Center - ) - Spacer(modifier = Modifier.height(8.dp)) - Text( - text = stringResource(R.string.sponsor_sheet_description), - style = MaterialTheme.typography.bodyLarge, - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.height(32.dp)) - Button( - onClick = component::onSupportClicked, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), - shape = RoundedCornerShape(16.dp) - ) { - Text(stringResource(R.string.action_support_boosty)) - } - Spacer(modifier = Modifier.height(12.dp)) - TextButton( - onClick = component::onSupportDismissed, - modifier = Modifier.fillMaxWidth() - ) { - Text(stringResource(R.string.action_maybe_later)) - } - } - } - } - - if (state.isMoreOptionsVisible && state.currentUser?.username != null) { - val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) - ModalBottomSheet( - onDismissRequest = component::onMoreOptionsDismissed, - sheetState = sheetState, - containerColor = MaterialTheme.colorScheme.surface, - shape = RoundedCornerShape(topStart = 24.dp, topEnd = 24.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .padding(bottom = 48.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - SettingsItem( - icon = Icons.Default.Share, - title = stringResource(R.string.share_profile_title), - subtitle = stringResource(R.string.share_profile_subtitle), - iconBackgroundColor = blueColor, - position = ItemPosition.TOP, - onClick = { - state.currentUser?.username?.let { username -> - val shareIntent = Intent(Intent.ACTION_SEND).apply { - type = "text/plain" - putExtra(Intent.EXTRA_TEXT, "https://t.me/$username") - } - context.startActivity(Intent.createChooser(shareIntent, null)) - } - component.onMoreOptionsDismissed() - } - ) - SettingsItem( - icon = Icons.Rounded.Link, - title = stringResource(R.string.copy_link_title), - subtitle = stringResource(R.string.copy_link_subtitle), - iconBackgroundColor = greenColor, - position = ItemPosition.BOTTOM, - onClick = { - state.currentUser?.username?.let { username -> - clipboardManager.setText(AnnotatedString("https://t.me/$username")) - haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove) - } - component.onMoreOptionsDismissed() - } - ) - } - } - } - - val statusMenuScrimAlpha by animateFloatAsState( - targetValue = if (statusMenuTransitionState.targetState) 0.18f else 0f, - animationSpec = tween(durationMillis = 220), - label = "StatusMenuScrimAlpha" - ) - - val iconTint = lerp( - start = MaterialTheme.colorScheme.onSurface, - stop = MaterialTheme.colorScheme.onSurface, - fraction = collapsingToolbarState.toolbarState.progress - ) - - val buttonBackground = MaterialTheme.colorScheme.background.copy( - alpha = 0.75f * collapsingToolbarState.toolbarState.progress - ) - - Scaffold( - modifier = Modifier.semantics { contentDescription = "SettingsContent" }, - topBar = { - TopAppBar( - title = { - currentUser?.let { userModel -> - Row( - modifier = Modifier - .fillMaxWidth() - .alpha(1f - collapsingToolbarState.toolbarState.progress), - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - text = "${userModel.firstName} ${userModel.lastName ?: ""}".trim(), - style = MaterialTheme.typography.headlineSmall, - fontWeight = FontWeight.SemiBold, - color = MaterialTheme.colorScheme.onSurface - ) - - if (userModel.isVerified) { - Spacer(modifier = Modifier.width(4.dp)) - Icon( - imageVector = Icons.Rounded.Verified, - contentDescription = stringResource(R.string.cd_verified), - modifier = Modifier.size(22.dp), - tint = MaterialTheme.colorScheme.primary - ) - } - - if (userModel.isSponsor) { - Spacer(modifier = Modifier.width(4.dp)) - Icon( - imageVector = Icons.Rounded.Favorite, - contentDescription = stringResource(R.string.cd_sponsor), - modifier = Modifier.size(22.dp), - tint = Color(0xFFE53935) - ) - } - - if (!userModel.statusEmojiPath.isNullOrEmpty()) { - Spacer(modifier = Modifier.width(4.dp)) - StickerImage( - path = userModel.statusEmojiPath, - modifier = Modifier - .size(22.dp) - .onGloballyPositioned { topBarStatusAnchorBounds = it.boundsInRoot() } - .clickable(onClick = { - statusAnchorBounds = topBarStatusAnchorBounds ?: statusAnchorBounds - showStatusMenu = true - }), - animate = false - ) - } else if (userModel.isPremium) { - Spacer(modifier = Modifier.width(4.dp)) - Icon( - imageVector = Icons.Default.Star, - contentDescription = null, - modifier = Modifier - .size(20.dp) - .onGloballyPositioned { topBarStatusAnchorBounds = it.boundsInRoot() } - .clickable(onClick = { - statusAnchorBounds = topBarStatusAnchorBounds ?: statusAnchorBounds - showStatusMenu = true - }), - tint = Color(0xFF31A6FD) - ) - } - } - } - }, - navigationIcon = { - Card( - modifier = Modifier.padding(8.dp), - shape = RoundedCornerShape(50), - colors = CardDefaults.cardColors(containerColor = buttonBackground), - ) { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back), - tint = iconTint - ) - } - } - }, - actions = { - Card( - modifier = Modifier.padding(8.dp), - shape = RoundedCornerShape(50), - colors = CardDefaults.cardColors(containerColor = buttonBackground), - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.padding(horizontal = 4.dp) - ) { - IconButton(onClick = component::onQrCodeClicked) { - Icon( - imageVector = Icons.Default.QrCode2, - contentDescription = stringResource(R.string.action_qr_code), - tint = iconTint - ) - } - IconButton(onClick = component::onEditProfileClicked) { - Icon( - imageVector = Icons.Rounded.Edit, - contentDescription = stringResource(R.string.cd_edit_profile), - tint = iconTint - ) - } - if (!state.currentUser?.username.isNullOrEmpty()) { - IconButton(onClick = component::onMoreOptionsClicked) { - Icon( - imageVector = Icons.Default.MoreVert, - contentDescription = null, - tint = iconTint - ) - } - } - } - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = dynamicContainerColorTopBar, - scrolledContainerColor = Color.Transparent, - - ) - ) - } - ) { padding -> - var safeTopPadding by remember { mutableStateOf(0.dp) } - var safeBottomPadding by remember { mutableStateOf(0.dp) } - val language = remember { - Locale.getDefault().displayLanguage - .replaceFirstChar { it.uppercase() } - } - val currentTop = padding.calculateTopPadding() - val currentBottom = padding.calculateBottomPadding() - - if (currentTop > 0.dp) safeTopPadding = currentTop - if (currentBottom > 0.dp) safeBottomPadding = currentBottom - - CollapsingToolbarScaffold( - modifier = Modifier - .fillMaxSize() - .background(dynamicContainerColor), - state = collapsingToolbarState, - scrollStrategy = ScrollStrategy.ExitUntilCollapsed, - toolbar = { - Box( - modifier = Modifier - .fillMaxWidth() - .pin() - ) - - BoxWithConstraints( - modifier = Modifier - .fillMaxWidth() - .road(Alignment.Center, Alignment.BottomCenter) - ) { - val progress = collapsingToolbarState.toolbarState.progress - val avatarSize = lerp(140.dp, maxWidth, progress) - val cornerPercent = (100 * (1f - progress)).toInt() - val sidePadding = lerp(24.dp, 0.dp, progress) - val topPadding = 0.dp - - val configuration = LocalConfiguration.current - val screenHeight = configuration.screenHeightDp.dp - val headerHeight = maxWidth.coerceAtMost(screenHeight * 0.6f) - - Box( - modifier = Modifier - .fillMaxWidth() - .height(headerHeight) - ) { - state.currentUser?.let { user -> - UserProfileHeader( - userModel = user, - avatarSize = avatarSize, - headerHeight = headerHeight, - avatarCornerPercent = cornerPercent, - currentRadius = 30.dp * progress, - alpha = progress, - contentPadding = PaddingValues( - top = topPadding, - start = sidePadding, - end = sidePadding - ), - videoPlayerPool = component.videoPlayerPool, - onStatusClick = { - statusAnchorBounds = headerStatusAnchorBounds ?: statusAnchorBounds - showStatusMenu = true - }, - onStatusBoundsChanged = { headerStatusAnchorBounds = it } - ) - } - } - } - }, - body = { - LazyColumn( - modifier = Modifier - .fillMaxSize() - .semantics { contentDescription = "SettingsList" }, - contentPadding = PaddingValues( - start = 16.dp, - end = 16.dp, - top = 0.dp, - bottom = safeBottomPadding - ), - verticalArrangement = Arrangement.spacedBy(16.dp), - ) { - item { - state.currentUser?.let { user -> - val rawPhone = user.phoneNumber ?: "" - - SettingsItem( - icon = Icons.Default.PhoneIphone, - title = if (isPhoneVisible) CountryManager.formatPhone( - rawPhone - ) else formatMaskedGlobal( - rawPhone - ), - subtitle = if (isPhoneVisible) stringResource(R.string.phone_subtitle_visible) else stringResource( - R.string.phone_subtitle_hidden - ), - iconBackgroundColor = phoneColor, - position = ItemPosition.TOP, - onLongClick = { - isPhoneVisible = !isPhoneVisible - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - }, - onClick = { - haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove) - clipboardManager.setText( - AnnotatedString( - CountryManager.formatPhone( - rawPhone - ) - ) - ) - } - ) - - val usernames = user.usernames - if (usernames != null && (usernames.activeUsernames.isNotEmpty() || usernames.collectibleUsernames.isNotEmpty() || usernames.disabledUsernames.isNotEmpty())) { - UsernamesTile( - activeUsernames = usernames.activeUsernames, - collectibleUsernames = usernames.collectibleUsernames, - disabledUsernames = usernames.disabledUsernames, - clipboardManager = clipboardManager, - position = ItemPosition.MIDDLE - ) - } else if (!user.username.isNullOrEmpty()) { - SettingsItem( - icon = Icons.Rounded.Person, - title = "@${user.username}", - subtitle = stringResource(R.string.username_label), - iconBackgroundColor = usernameColor, - position = ItemPosition.MIDDLE, - onClick = { - haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove) - clipboardManager.setText(AnnotatedString("@${user.username}")) - } - ) - } - - SettingsItem( - icon = Icons.Rounded.Info, - title = user.id.toString(), - subtitle = stringResource(R.string.your_id_label), - iconBackgroundColor = idColor, - position = ItemPosition.MIDDLE, - onClick = { - haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove) - clipboardManager.setText(AnnotatedString(user.id.toString())) - } - ) - - SettingsItem( - icon = Icons.Rounded.Edit, - title = stringResource(R.string.menu_edit), - subtitle = stringResource(R.string.edit_profile_subtitle), - iconBackgroundColor = blueColor, - position = ItemPosition.BOTTOM, - onClick = component::onEditProfileClicked, - modifier = Modifier.semantics { contentDescription = "SettingsEditProfile" } - ) - } - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && !state.isTMeLinkEnabled) { - item { - SettingsItem( - icon = Icons.Rounded.Link, - title = stringResource(R.string.enable_tme_links), - subtitle = stringResource(R.string.enable_tme_links_subtitle), - iconBackgroundColor = blueColor, - position = ItemPosition.STANDALONE, - onClick = component::onLinkSettingsClicked - ) - } - } - - item { - SectionHeader(stringResource(R.string.section_general)) - SettingsItem( - icon = Icons.AutoMirrored.Rounded.Chat, - title = stringResource(R.string.chat_settings_title), - subtitle = stringResource(R.string.chat_settings_subtitle), - iconBackgroundColor = blueColor, - position = ItemPosition.TOP, - onClick = component::onChatSettingsClicked, - modifier = Modifier.semantics { contentDescription = "SettingsChatSettings" } - ) - SettingsItem( - icon = Icons.Rounded.Lock, - title = stringResource(R.string.privacy_security_title), - subtitle = stringResource(R.string.privacy_security_subtitle), - iconBackgroundColor = greenColor, - position = ItemPosition.MIDDLE, - onClick = component::onPrivacyClicked, - modifier = Modifier.semantics { contentDescription = "SettingsPrivacy" } - ) - SettingsItem( - icon = Icons.Rounded.Notifications, - title = stringResource(R.string.notifications_sounds_title), - subtitle = stringResource(R.string.notifications_sounds_subtitle), - iconBackgroundColor = pinkColor, - position = ItemPosition.MIDDLE, - onClick = component::onNotificationsClicked, - modifier = Modifier.semantics { contentDescription = "SettingsNotifications" } - ) - SettingsItem( - icon = Icons.Rounded.DataUsage, - title = stringResource(R.string.data_storage_title), - subtitle = stringResource(R.string.data_storage_subtitle), - iconBackgroundColor = tealColor, - position = ItemPosition.MIDDLE, - onClick = component::onDataStorageClicked, - modifier = Modifier.semantics { contentDescription = "SettingsDataStorage" } - ) - SettingsItem( - icon = Icons.Rounded.PowerSettingsNew, - title = stringResource(R.string.power_saving_title), - subtitle = stringResource(R.string.power_saving_subtitle), - iconBackgroundColor = orangeColor, - position = ItemPosition.MIDDLE, - onClick = component::onPowerSavingClicked - ) - SettingsItem( - icon = Icons.Rounded.Folder, - title = stringResource(R.string.chat_folders_title), - subtitle = stringResource(R.string.chat_folders_subtitle), - iconBackgroundColor = indigoColor, - position = ItemPosition.MIDDLE, - onClick = component::onFoldersClicked, - modifier = Modifier.semantics { contentDescription = "SettingsFolders" } - ) - SettingsItem( - icon = Icons.Rounded.SentimentSatisfiedAlt, - title = stringResource(R.string.stickers_emoji_title), - subtitle = stringResource(R.string.stickers_emoji_subtitle), - iconBackgroundColor = orangeColor, - position = ItemPosition.MIDDLE, - onClick = component::onStickersClicked - ) - SettingsItem( - icon = Icons.Rounded.Person, - title = stringResource(R.string.devices_title), - subtitle = stringResource(R.string.devices_subtitle), - iconBackgroundColor = tealColor, - position = ItemPosition.MIDDLE, - onClick = component::onDevicesClicked - ) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - SettingsItem( - icon = Icons.Rounded.Language, - title = stringResource(R.string.language_title), - subtitle = language, - iconBackgroundColor = blueColor, - position = ItemPosition.MIDDLE, - onClick = { - val intent = - Intent(Settings.ACTION_APP_LOCALE_SETTINGS).apply { - data = - Uri.fromParts("package", context.packageName, null) - } - context.startActivity(intent) - } - ) - } - SettingsItem( - icon = Icons.Rounded.SettingsEthernet, - title = stringResource(R.string.proxy_settings_title), - subtitle = stringResource(R.string.proxy_settings_subtitle), - iconBackgroundColor = purpleColor, - position = ItemPosition.BOTTOM, - onClick = component::onProxySettingsClicked - ) - } - - item { - SettingsItem( - icon = Icons.Rounded.Star, - title = stringResource(R.string.telegram_premium_title), - subtitle = stringResource(R.string.telegram_premium_subtitle), - iconBackgroundColor = purpleColor, - position = ItemPosition.TOP, - onClick = component::onPremiumClicked, - modifier = Modifier.semantics { contentDescription = "SettingsPremium" } - ) - SettingsItem( - icon = Icons.Rounded.Favorite, - title = stringResource(R.string.support_monogram_title), - subtitle = stringResource(R.string.support_monogram_subtitle_settings), - iconBackgroundColor = pinkColor, - position = ItemPosition.BOTTOM, - onClick = component::onShowSupportClicked - ) - } - - item { - SettingsItem( - icon = Icons.Rounded.Info, - title = stringResource(R.string.about_title), - subtitle = stringResource(R.string.about_subtitle_settings), - iconBackgroundColor = blueColor, - position = ItemPosition.TOP, - onClick = component::onAboutClicked - ) - SettingsItem( - icon = Icons.Rounded.BugReport, - title = stringResource(R.string.debug_title), - subtitle = stringResource(R.string.debug_subtitle), - iconBackgroundColor = Color.Gray, - position = ItemPosition.MIDDLE, - onClick = component::onDebugClicked - ) - SettingsItem( - icon = Icons.AutoMirrored.Rounded.ExitToApp, - title = stringResource(R.string.log_out_title), - subtitle = stringResource(R.string.log_out_subtitle), - iconBackgroundColor = MaterialTheme.colorScheme.error, - position = ItemPosition.BOTTOM, - onClick = component::onLogoutClicked - ) - } - } - } - ) - } - - if (statusMenuTransitionState.currentState || statusMenuTransitionState.targetState) { - BoxWithConstraints( - modifier = Modifier - .fillMaxSize() - .background(Color.Black.copy(alpha = statusMenuScrimAlpha)) - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null - ) { showStatusMenu = false } - ) { - val menuHorizontalPadding = 16.dp - val menuAnchorOverlap = 12.dp - val menuBottomMargin = 8.dp - val menuWidth = (maxWidth - menuHorizontalPadding * 2).coerceAtLeast(280.dp) - val menuHeightLimit = 520.dp - - val rootWidthPx = constraints.maxWidth.coerceAtLeast(1) - val rootHeightPx = constraints.maxHeight.coerceAtLeast(1) - val menuWidthPx = with(density) { menuWidth.roundToPx() } - val horizontalPaddingPx = with(density) { menuHorizontalPadding.roundToPx() } - val anchorOverlapPx = with(density) { menuAnchorOverlap.roundToPx() } - val menuBottomMarginPx = with(density) { menuBottomMargin.roundToPx() } - val minMenuVisibleHeightPx = with(density) { 220.dp.roundToPx() } - - val statusBarTopPx = WindowInsets.statusBars.getTop(density) - val navigationBarBottomPx = WindowInsets.navigationBars.getBottom(density) - val minTopPx = statusBarTopPx + with(density) { 8.dp.roundToPx() } - val fallbackTopPx = statusBarTopPx + with(density) { 56.dp.roundToPx() } - - val desiredTopPx = statusAnchorBounds - ?.let { it.bottom.roundToInt() - anchorOverlapPx } - ?: fallbackTopPx - val desiredLeftPx = statusAnchorBounds - ?.let { ((it.left + it.right) / 2f - menuWidthPx / 2f).roundToInt() } - ?: horizontalPaddingPx - - val maxLeftPx = (rootWidthPx - menuWidthPx - horizontalPaddingPx).coerceAtLeast(horizontalPaddingPx) - val clampedLeftPx = desiredLeftPx.coerceIn(horizontalPaddingPx, maxLeftPx) - - val maxTopPx = ( - rootHeightPx - navigationBarBottomPx - menuBottomMarginPx - minMenuVisibleHeightPx - ).coerceAtLeast(minTopPx) - val clampedTopPx = desiredTopPx.coerceIn(minTopPx, maxTopPx) - - val maxMenuHeightPx = ( - rootHeightPx - clampedTopPx - navigationBarBottomPx - menuBottomMarginPx - ).coerceAtLeast(minMenuVisibleHeightPx) - val maxMenuHeightDp = with(density) { maxMenuHeightPx.toDp() }.coerceAtMost(menuHeightLimit) - - AnimatedVisibility( - visibleState = statusMenuTransitionState, - enter = fadeIn(animationSpec = tween(180)) + - slideInVertically(animationSpec = tween(260)) { -it / 5 } + - scaleIn( - animationSpec = tween(260), - initialScale = 0.94f, - transformOrigin = TransformOrigin(0.85f, 0f) - ), - exit = fadeOut(animationSpec = tween(130)) + - slideOutVertically(animationSpec = tween(170)) { -it / 6 } + - scaleOut( - animationSpec = tween(170), - targetScale = 0.97f, - transformOrigin = TransformOrigin(0.85f, 0f) - ), - modifier = Modifier.offset { IntOffset(clampedLeftPx, clampedTopPx) } - ) { - Surface( - modifier = Modifier - .width(menuWidth) - .heightIn(max = maxMenuHeightDp) - .clip(RoundedCornerShape(24.dp)) - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null - ) { }, - color = MaterialTheme.colorScheme.surfaceContainerHigh, - tonalElevation = 8.dp, - shadowElevation = 12.dp - ) { - EmojisGrid( - onEmojiSelected = { _, sticker -> - val customEmojiId = sticker?.customEmojiId - if (sticker != null && customEmojiId != null) { - if (!sticker.path.isNullOrBlank()) { - cachedStatusEmojiPath = sticker.path - } - component.onSetEmojiStatus(customEmojiId, sticker.path) - showStatusMenu = false - } - }, - emojiOnlyMode = true, - contentPadding = PaddingValues(bottom = 12.dp) - ) - } - } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/settings/SettingsStore.kt b/presentation/src/main/java/org/monogram/presentation/settings/settings/SettingsStore.kt deleted file mode 100644 index 31c0bdfc..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/settings/SettingsStore.kt +++ /dev/null @@ -1,37 +0,0 @@ -package org.monogram.presentation.settings.settings - -import com.arkivanov.mvikotlin.core.store.Store - -interface SettingsStore : Store { - - sealed class Intent { - object BackClicked : Intent() - object EditProfileClicked : Intent() - object LogoutClicked : Intent() - data class NotificationToggled(val enabled: Boolean) : Intent() - object DevicesClicked : Intent() - object FoldersClicked : Intent() - object ChatSettingsClicked : Intent() - object DataStorageClicked : Intent() - object PowerSavingClicked : Intent() - object PremiumClicked : Intent() - object PrivacyClicked : Intent() - object NotificationsClicked : Intent() - object LinkSettingsClicked : Intent() - object CheckLinkStatus : Intent() - object QrCodeClicked : Intent() - object QrCodeDismissed : Intent() - object ProxySettingsClicked : Intent() - object StickersClicked : Intent() - object AboutClicked : Intent() - object DebugClicked : Intent() - object SupportClicked : Intent() - object SupportDismissed : Intent() - object ShowSupportClicked : Intent() - data class UpdateState(val state: SettingsComponent.State) : Intent() - } - - sealed class Label { - object Back : Label() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/settings/SettingsStoreFactory.kt b/presentation/src/main/java/org/monogram/presentation/settings/settings/SettingsStoreFactory.kt deleted file mode 100644 index 5114d53f..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/settings/SettingsStoreFactory.kt +++ /dev/null @@ -1,64 +0,0 @@ -package org.monogram.presentation.settings.settings - -import com.arkivanov.mvikotlin.core.store.Reducer -import com.arkivanov.mvikotlin.core.store.Store -import com.arkivanov.mvikotlin.core.store.StoreFactory -import com.arkivanov.mvikotlin.extensions.coroutines.CoroutineExecutor -import org.monogram.presentation.settings.settings.SettingsStore.Intent -import org.monogram.presentation.settings.settings.SettingsStore.Label - -class SettingsStoreFactory( - private val storeFactory: StoreFactory, - private val component: DefaultSettingsComponent -) { - - fun create(): SettingsStore = - object : SettingsStore, Store by storeFactory.create( - name = "SettingsStore", - initialState = component.state.value, - executorFactory = ::ExecutorImpl, - reducer = ReducerImpl - ) {} - - private inner class ExecutorImpl : CoroutineExecutor() { - override fun executeIntent(intent: Intent) { - when (intent) { - Intent.BackClicked -> component.onBackClicked() - Intent.EditProfileClicked -> component.onEditProfileClicked() - Intent.LogoutClicked -> component.onLogoutClicked() - is Intent.NotificationToggled -> component.onNotificationToggled(intent.enabled) - Intent.DevicesClicked -> component.onDevicesClicked() - Intent.FoldersClicked -> component.onFoldersClicked() - Intent.ChatSettingsClicked -> component.onChatSettingsClicked() - Intent.DataStorageClicked -> component.onDataStorageClicked() - Intent.PowerSavingClicked -> component.onPowerSavingClicked() - Intent.PremiumClicked -> component.onPremiumClicked() - Intent.PrivacyClicked -> component.onPrivacyClicked() - Intent.NotificationsClicked -> component.onNotificationsClicked() - Intent.LinkSettingsClicked -> component.onLinkSettingsClicked() - Intent.CheckLinkStatus -> component.checkLinkStatus() - Intent.QrCodeClicked -> component.onQrCodeClicked() - Intent.QrCodeDismissed -> component.onQrCodeDismissed() - Intent.ProxySettingsClicked -> component.onProxySettingsClicked() - Intent.StickersClicked -> component.onStickersClicked() - Intent.AboutClicked -> component.onAboutClicked() - Intent.DebugClicked -> component.onDebugClicked() - Intent.SupportClicked -> component.onSupportClicked() - Intent.SupportDismissed -> component.onSupportDismissed() - Intent.ShowSupportClicked -> component.onShowSupportClicked() - is Intent.UpdateState -> dispatch(Message.UpdateState(intent.state)) - } - } - } - - private object ReducerImpl : Reducer { - override fun SettingsComponent.State.reduce(msg: Message): SettingsComponent.State = - when (msg) { - is Message.UpdateState -> msg.state - } - } - - sealed class Message { - data class UpdateState(val state: SettingsComponent.State) : Message() - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/stickers/StickersComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/stickers/StickersComponent.kt deleted file mode 100644 index 4831032a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/stickers/StickersComponent.kt +++ /dev/null @@ -1,196 +0,0 @@ -package org.monogram.presentation.settings.stickers - -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.flow.collectLatest -import kotlinx.coroutines.launch -import org.monogram.domain.models.StickerSetModel -import org.monogram.domain.repository.StickerRepository -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.root.AppComponentContext - -interface StickersComponent { - val state: Value - - fun onBackClicked() - fun onStickerSetClicked(stickerSet: StickerSetModel) - fun onToggleStickerSet(stickerSet: StickerSetModel) - fun onArchiveStickerSet(stickerSet: StickerSetModel) - fun onClearRecentStickers() - fun onClearRecentEmojis() - fun onTabSelected(index: Int) - fun onSearchQueryChanged(query: String) - fun onMoveStickerSet(fromIndex: Int, toIndex: Int) - fun onAddStickersClicked() - fun onDismissMiniApp() - - data class State( - val stickerSets: List = emptyList(), - val emojiSets: List = emptyList(), - val archivedStickerSets: List = emptyList(), - val archivedEmojiSets: List = emptyList(), - val isLoading: Boolean = true, - val selectedTabIndex: Int = 0, - val searchQuery: String = "", - val miniAppUrl: String? = null, - val miniAppName: String? = null, - val miniAppBotUserId: Long = 0L - ) -} - -class DefaultStickersComponent( - context: AppComponentContext, - private val onBack: () -> Unit, - private val onStickerSetSelect: (StickerSetModel) -> Unit -) : StickersComponent, AppComponentContext by context { - - private val stickerRepository: StickerRepository = container.repositories.stickerRepository - private val _state = MutableValue( - StickersComponent.State( - stickerSets = stickerRepository.installedStickerSets.value, - emojiSets = stickerRepository.customEmojiStickerSets.value, - archivedStickerSets = stickerRepository.archivedStickerSets.value, - archivedEmojiSets = stickerRepository.archivedEmojiSets.value, - isLoading = stickerRepository.installedStickerSets.value.isEmpty() - ) - ) - override val state: Value = _state - private val scope = componentScope - - init { - scope.launch { - stickerRepository.loadInstalledStickerSets() - stickerRepository.loadCustomEmojiStickerSets() - stickerRepository.loadArchivedStickerSets() - stickerRepository.loadArchivedEmojiSets() - } - - scope.launch { - stickerRepository.installedStickerSets.collectLatest { sets -> - _state.update { - it.copy( - stickerSets = sets, - isLoading = false - ) - } - } - } - - scope.launch { - stickerRepository.customEmojiStickerSets.collectLatest { sets -> - _state.update { - it.copy( - emojiSets = sets - ) - } - } - } - - scope.launch { - stickerRepository.archivedStickerSets.collectLatest { sets -> - _state.update { - it.copy( - archivedStickerSets = sets - ) - } - } - } - - scope.launch { - stickerRepository.archivedEmojiSets.collectLatest { sets -> - _state.update { - it.copy( - archivedEmojiSets = sets - ) - } - } - } - } - - override fun onBackClicked() { - onBack() - } - - override fun onStickerSetClicked(stickerSet: StickerSetModel) { - onStickerSetSelect(stickerSet) - } - - override fun onToggleStickerSet(stickerSet: StickerSetModel) { - scope.launch { - stickerRepository.toggleStickerSetInstalled(stickerSet.id, !stickerSet.isInstalled) - } - } - - override fun onArchiveStickerSet(stickerSet: StickerSetModel) { - scope.launch { - stickerRepository.toggleStickerSetArchived(stickerSet.id, !stickerSet.isArchived) - } - } - - override fun onClearRecentStickers() { - scope.launch { - stickerRepository.clearRecentStickers() - } - } - - override fun onClearRecentEmojis() { - scope.launch { - stickerRepository.clearRecentEmojis() - } - } - - override fun onTabSelected(index: Int) { - _state.update { it.copy(selectedTabIndex = index) } - } - - override fun onSearchQueryChanged(query: String) { - _state.update { it.copy(searchQuery = query) } - } - - override fun onMoveStickerSet(fromIndex: Int, toIndex: Int) { - val currentTabIndex = _state.value.selectedTabIndex - val currentList = if (currentTabIndex == 0) _state.value.stickerSets else _state.value.emojiSets - - if (fromIndex !in currentList.indices || toIndex !in currentList.indices) return - - val newList = currentList.toMutableList().apply { - add(toIndex, removeAt(fromIndex)) - } - - if (currentTabIndex == 0) { - _state.update { it.copy(stickerSets = newList) } - } else { - _state.update { it.copy(emojiSets = newList) } - } - - scope.launch { - val type = if (currentTabIndex == 0) { - StickerRepository.TdLibStickerType.REGULAR - } else { - StickerRepository.TdLibStickerType.CUSTOM_EMOJI - } - stickerRepository.reorderStickerSets(type, newList.map { it.id }) - } - } - - override fun onAddStickersClicked() { - _state.update { - it.copy( - miniAppUrl = "menu://https://webappinternal.telegram.org/stickers", - miniAppName = "Stickers", - miniAppBotUserId = 429000L - ) - } - } - - override fun onDismissMiniApp() { - _state.update { - it.copy( - miniAppUrl = null, - miniAppName = null, - miniAppBotUserId = 0L - ) - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/stickers/StickersContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/stickers/StickersContent.kt deleted file mode 100644 index 56495a1a..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/stickers/StickersContent.kt +++ /dev/null @@ -1,620 +0,0 @@ -package org.monogram.presentation.settings.stickers - -import androidx.compose.animation.* -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.animateDpAsState -import androidx.compose.animation.core.spring -import androidx.compose.foundation.background -import androidx.compose.foundation.gestures.detectDragGesturesAfterLongPress -import androidx.compose.foundation.gestures.scrollBy -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.LazyListState -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.selection.selectable -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.automirrored.rounded.StickyNote2 -import androidx.compose.material.icons.rounded.Add -import androidx.compose.material.icons.rounded.Close -import androidx.compose.material.icons.rounded.Delete -import androidx.compose.material.icons.rounded.EmojiEmotions -import androidx.compose.material.icons.rounded.Search -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.shadow -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.hapticfeedback.HapticFeedbackType -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.platform.LocalHapticFeedback -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.Role -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.zIndex -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import kotlinx.coroutines.Job -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import org.koin.compose.koinInject -import org.monogram.domain.models.StickerSetModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ConfirmationSheet -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsTile -import org.monogram.presentation.core.ui.StickerSetItem -import org.monogram.presentation.core.ui.getItemShape -import org.monogram.presentation.features.stickers.ui.view.LocalIsScrolling -import org.monogram.presentation.features.webapp.MiniAppViewer -import kotlin.math.abs - -private enum class StickerTab(val titleRes: Int, val icon: ImageVector) { - Stickers(R.string.stickers_tab, Icons.AutoMirrored.Rounded.StickyNote2), - Emoji(R.string.emoji_tab, Icons.Rounded.EmojiEmotions) -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun StickersContent(component: StickersComponent) { - val state by component.state.subscribeAsState() - var debouncedSearchQuery by remember { mutableStateOf("") } - var showClearRecentStickersSheet by remember { mutableStateOf(false) } - var showClearRecentEmojisSheet by remember { mutableStateOf(false) } - - LaunchedEffect(state.searchQuery) { - if (state.searchQuery.isBlank()) { - debouncedSearchQuery = "" - } else { - delay(300) - debouncedSearchQuery = state.searchQuery - } - } - - val orangeColor = Color(0xFFF9AB00) - val tealColor = Color(0xFF00BFA5) - - val stickersListState = rememberLazyListState() - val emojisListState = rememberLazyListState() - - Box(modifier = Modifier.fillMaxSize()) { - Scaffold( - topBar = { - Column(modifier = Modifier.background(MaterialTheme.colorScheme.background)) { - TopAppBar( - title = { - Text( - text = stringResource(R.string.stickers_emoji_header), - style = MaterialTheme.typography.titleLarge, - fontWeight = FontWeight.Bold - ) - }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background - ) - ) - - Row( - Modifier - .padding(horizontal = 16.dp, vertical = 8.dp) - .fillMaxWidth() - .height(48.dp) - .background( - MaterialTheme.colorScheme.surfaceContainerHigh, - CircleShape - ) - .padding(4.dp), - horizontalArrangement = Arrangement.SpaceBetween - ) { - StickerTab.entries.forEachIndexed { index, tab -> - val selected = (state.selectedTabIndex == index) - val count = if (index == 0) state.stickerSets.size else state.emojiSets.size - - val backgroundColor by animateColorAsState( - if (selected) MaterialTheme.colorScheme.primary else Color.Transparent, - label = "tabBackground" - ) - val contentColor by animateColorAsState( - if (selected) MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurfaceVariant, - label = "tabContent" - ) - - Box( - Modifier - .weight(1f) - .fillMaxHeight() - .clip(CircleShape) - .background(backgroundColor) - .selectable( - selected = selected, - onClick = { component.onTabSelected(index) }, - role = Role.Tab - ), - contentAlignment = Alignment.Center - ) { - Row(verticalAlignment = Alignment.CenterVertically) { - Icon( - tab.icon, - contentDescription = null, - modifier = Modifier.size(18.dp), - tint = contentColor - ) - Spacer(Modifier.width(8.dp)) - Text( - text = stringResource(tab.titleRes), - style = MaterialTheme.typography.labelLarge, - color = contentColor, - fontWeight = if (selected) FontWeight.Bold else FontWeight.Medium - ) - if (count > 0) { - Spacer(Modifier.width(4.dp)) - Text( - text = "($count)", - style = MaterialTheme.typography.labelSmall, - color = contentColor.copy(alpha = 0.7f) - ) - } - } - } - } - } - } - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - Box( - modifier = Modifier - .fillMaxSize() - .padding(top = padding.calculateTopPadding()) - ) { - AnimatedContent( - targetState = state.selectedTabIndex, - transitionSpec = { - fadeIn(animationSpec = spring(stiffness = Spring.StiffnessMediumLow)) togetherWith - fadeOut(animationSpec = spring(stiffness = Spring.StiffnessMediumLow)) - }, - label = "TabContent" - ) { tabIndex -> - if (state.isLoading && ((tabIndex == 0 && state.stickerSets.isEmpty()) || (tabIndex == 1 && state.emojiSets.isEmpty()))) { - Box( - modifier = Modifier - .fillMaxSize() - .padding(32.dp), - contentAlignment = Alignment.Center - ) { - CircularProgressIndicator() - } - } else { - when (tabIndex) { - 0 -> { - val filteredSets = remember(state.stickerSets, debouncedSearchQuery) { - if (debouncedSearchQuery.isEmpty()) state.stickerSets - else state.stickerSets.filter { - it.title.contains( - debouncedSearchQuery, - ignoreCase = true - ) - } - } - GenericStickerList( - sets = filteredSets, - archivedSets = state.archivedStickerSets, - recentHeader = stringResource(R.string.recent_stickers_header), - setsHeader = stringResource(R.string.sticker_sets_header), - archivedHeader = stringResource(R.string.archived_stickers_header), - addStickersTitle = stringResource(R.string.add_own_stickers_title), - addStickersSubtitle = stringResource(R.string.add_own_stickers_subtitle), - clearRecentTitle = stringResource(R.string.clear_recent_stickers_title), - clearRecentSubtitle = stringResource(R.string.clear_recent_stickers_subtitle), - clearRecentIcon = Icons.AutoMirrored.Rounded.StickyNote2, - clearRecentIconColor = orangeColor, - onClearRecent = { showClearRecentStickersSheet = true }, - onSetClick = component::onStickerSetClicked, - onSetToggle = component::onToggleStickerSet, - onSetArchive = component::onArchiveStickerSet, - onMoveSet = component::onMoveStickerSet, - listState = stickersListState, - searchQuery = state.searchQuery, - onSearchQueryChange = component::onSearchQueryChanged, - emptyText = if (debouncedSearchQuery.isEmpty()) stringResource(R.string.no_sticker_sets_installed) else stringResource( - R.string.no_stickers_found_format, - debouncedSearchQuery - ), - onAddStickers = component::onAddStickersClicked - ) - } - - 1 -> { - val filteredSets = remember(state.emojiSets, debouncedSearchQuery) { - if (debouncedSearchQuery.isEmpty()) state.emojiSets - else state.emojiSets.filter { - it.title.contains( - debouncedSearchQuery, - ignoreCase = true - ) - } - } - GenericStickerList( - sets = filteredSets, - archivedSets = state.archivedEmojiSets, - recentHeader = stringResource(R.string.recent_emojis_header), - setsHeader = stringResource(R.string.emoji_packs_header), - archivedHeader = stringResource(R.string.archived_emojis_header), - addStickersTitle = stringResource(R.string.add_own_emoji_title), - addStickersSubtitle = stringResource(R.string.add_own_emoji_subtitle), - clearRecentTitle = stringResource(R.string.clear_recent_emojis_title_settings), - clearRecentSubtitle = stringResource(R.string.clear_recent_emojis_subtitle_settings), - clearRecentIcon = Icons.Rounded.EmojiEmotions, - clearRecentIconColor = tealColor, - onClearRecent = { showClearRecentEmojisSheet = true }, - onSetClick = component::onStickerSetClicked, - onSetToggle = component::onToggleStickerSet, - onSetArchive = component::onArchiveStickerSet, - onMoveSet = component::onMoveStickerSet, - listState = emojisListState, - searchQuery = state.searchQuery, - onSearchQueryChange = component::onSearchQueryChanged, - emptyText = if (debouncedSearchQuery.isEmpty()) stringResource(R.string.no_emoji_packs_installed) else stringResource( - R.string.no_emojis_found_format, - debouncedSearchQuery - ), - onAddStickers = component::onAddStickersClicked - ) - } - } - } - } - } - } - - AnimatedVisibility( - visible = state.miniAppUrl != null, - enter = slideInVertically(initialOffsetY = { it }) + fadeIn(), - exit = slideOutVertically(targetOffsetY = { it }) + fadeOut() - ) { - if (state.miniAppUrl != null && state.miniAppName != null) { - MiniAppViewer( - chatId = state.miniAppBotUserId, - botUserId = state.miniAppBotUserId, - baseUrl = state.miniAppUrl!!, - botName = state.miniAppName!!, - messageRepository = koinInject(), - onDismiss = { component.onDismissMiniApp() } - ) - } - } - - if (showClearRecentStickersSheet) { - ConfirmationSheet( - icon = Icons.Rounded.Delete, - title = stringResource(R.string.clear_recent_stickers_title), - description = stringResource(R.string.clear_recent_stickers_confirmation), - confirmText = stringResource(R.string.action_clear_recent_stickers), - onConfirm = { - component.onClearRecentStickers() - showClearRecentStickersSheet = false - }, - onDismiss = { showClearRecentStickersSheet = false } - ) - } - - if (showClearRecentEmojisSheet) { - ConfirmationSheet( - icon = Icons.Rounded.Delete, - title = stringResource(R.string.clear_recent_emojis_title_settings), - description = stringResource(R.string.clear_recent_emojis_confirmation), - confirmText = stringResource(R.string.action_clear_recent_emojis), - onConfirm = { - component.onClearRecentEmojis() - showClearRecentEmojisSheet = false - }, - onDismiss = { showClearRecentEmojisSheet = false } - ) - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun GenericStickerList( - sets: List, - archivedSets: List, - recentHeader: String, - setsHeader: String, - archivedHeader: String, - addStickersTitle: String, - addStickersSubtitle: String, - clearRecentTitle: String, - clearRecentSubtitle: String, - clearRecentIcon: ImageVector, - clearRecentIconColor: Color, - onClearRecent: () -> Unit, - onSetClick: (StickerSetModel) -> Unit, - onSetToggle: (StickerSetModel) -> Unit, - onSetArchive: (StickerSetModel) -> Unit, - onMoveSet: (Int, Int) -> Unit, - listState: LazyListState, - searchQuery: String, - onSearchQueryChange: (String) -> Unit, - emptyText: String, - onAddStickers: () -> Unit -) { - val isScrolling = listState.isScrollInProgress - val scope = rememberCoroutineScope() - val haptic = LocalHapticFeedback.current - - var draggedItemId by remember { mutableStateOf(null) } - var dragOffset by remember { mutableStateOf(0f) } - var initialDragStartOffset by remember { mutableStateOf(0) } - var initialPointerY by remember { mutableStateOf(0f) } - var totalDragDistance by remember { mutableStateOf(0f) } - var autoScrollJob by remember { mutableStateOf(null) } - var autoScrollVelocity by remember { mutableStateOf(0f) } - - CompositionLocalProvider(LocalIsScrolling provides isScrolling) { - LazyColumn( - state = listState, - modifier = Modifier.fillMaxSize(), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, top = 8.dp, bottom = 16.dp), - verticalArrangement = Arrangement.spacedBy(2.dp) - ) { - item { - SearchBar( - query = searchQuery, - onQueryChange = onSearchQueryChange, - onSearch = { }, - active = false, - onActiveChange = { }, - placeholder = { Text(stringResource(R.string.search_packs_placeholder)) }, - leadingIcon = { - Icon(Icons.Rounded.Search, contentDescription = stringResource(R.string.action_search)) - }, - trailingIcon = { - if (searchQuery.isNotEmpty()) { - IconButton(onClick = { onSearchQueryChange("") }) { - Icon(Icons.Rounded.Close, contentDescription = stringResource(R.string.action_clear)) - } - } - }, - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 8.dp), - colors = SearchBarDefaults.colors( - containerColor = MaterialTheme.colorScheme.surfaceContainerHigh - ), - windowInsets = WindowInsets(0, 0, 0, 0) - ) {} - } - - item { - SettingsTile( - icon = Icons.Rounded.Add, - title = addStickersTitle, - subtitle = addStickersSubtitle, - iconColor = MaterialTheme.colorScheme.primary, - position = ItemPosition.STANDALONE, - onClick = onAddStickers - ) - } - - item { - SectionHeader(recentHeader) - } - item { - SettingsTile( - icon = clearRecentIcon, - title = clearRecentTitle, - subtitle = clearRecentSubtitle, - iconColor = clearRecentIconColor, - position = ItemPosition.STANDALONE, - onClick = onClearRecent - ) - } - - if (sets.isNotEmpty()) { - item { - SectionHeader(setsHeader) - } - itemsIndexed(sets, key = { _, set -> set.id }) { index, set -> - val currentSets by rememberUpdatedState(sets) - val currentIndex by rememberUpdatedState(index) - val currentOnMoveSet by rememberUpdatedState(onMoveSet) - - val isDragging = draggedItemId == set.id - val elevation by animateDpAsState( - targetValue = if (isDragging) 8.dp else 0.dp, - animationSpec = spring(stiffness = Spring.StiffnessMediumLow), - label = "elevation" - ) - - val position = when { - sets.size == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == sets.size - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - - Box( - modifier = Modifier - .zIndex(if (isDragging) 1f else 0f) - .then(if (isDragging) Modifier else Modifier.animateItem()) - .graphicsLayer { - translationY = if (isDragging) dragOffset else 0f - scaleX = if (isDragging) 1.02f else 1f - scaleY = if (isDragging) 1.02f else 1f - } - .shadow(elevation, shape = getItemShape(position)) - .pointerInput(searchQuery) { - if (searchQuery.isNotEmpty()) return@pointerInput - - detectDragGesturesAfterLongPress( - onDragStart = { offset -> - draggedItemId = set.id - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - - val itemInfo = listState.layoutInfo.visibleItemsInfo - .firstOrNull { it.key == set.id } - initialDragStartOffset = itemInfo?.offset ?: 0 - initialPointerY = offset.y + (itemInfo?.offset ?: 0) - totalDragDistance = 0f - dragOffset = 0f - }, - onDrag = { change, dragAmount -> - change.consume() - totalDragDistance += dragAmount.y - - val currentItemInfo = listState.layoutInfo.visibleItemsInfo - .firstOrNull { it.key == set.id } ?: return@detectDragGesturesAfterLongPress - - val targetY = initialDragStartOffset + totalDragDistance - dragOffset = targetY - currentItemInfo.offset - - val draggedCenter = targetY + currentItemInfo.size / 2 - - val targetItem = listState.layoutInfo.visibleItemsInfo - .firstOrNull { item -> - draggedCenter > item.offset && - draggedCenter < item.offset + item.size && - item.index >= 5 - } - - if (targetItem != null) { - val targetIndex = targetItem.index - 5 - if (targetIndex != currentIndex && targetIndex in currentSets.indices) { - currentOnMoveSet(currentIndex, targetIndex) - haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove) - } - } - - val viewPortHeight = listState.layoutInfo.viewportSize.height - val topThreshold = 100.dp.toPx() - val bottomThreshold = viewPortHeight - 100.dp.toPx() - val pointerY = initialPointerY + totalDragDistance - - if (pointerY < topThreshold) { - val intensity = ((topThreshold - pointerY) / topThreshold).coerceIn(0f, 1f) - autoScrollVelocity = -(6f + (18f * intensity)) - } else if (pointerY > bottomThreshold) { - val intensity = - ((pointerY - bottomThreshold) / topThreshold).coerceIn(0f, 1f) - autoScrollVelocity = 6f + (18f * intensity) - } else { - autoScrollVelocity = 0f - autoScrollJob?.cancel() - autoScrollJob = null - } - - if (autoScrollJob == null && abs(autoScrollVelocity) > 0f) { - autoScrollJob = scope.launch { - while (abs(autoScrollVelocity) > 0f) { - listState.scrollBy(autoScrollVelocity) - delay(16) - } - }.also { job -> - job.invokeOnCompletion { - if (autoScrollJob === job) autoScrollJob = null - } - } - } - }, - onDragEnd = { - draggedItemId = null - dragOffset = 0f - totalDragDistance = 0f - autoScrollVelocity = 0f - autoScrollJob?.cancel() - autoScrollJob = null - }, - onDragCancel = { - draggedItemId = null - dragOffset = 0f - totalDragDistance = 0f - autoScrollVelocity = 0f - autoScrollJob?.cancel() - autoScrollJob = null - } - ) - } - ) { - StickerSetItem( - stickerSet = set, - position = position, - onClick = { onSetClick(set) }, - onToggle = { onSetToggle(set) }, - onArchive = { onSetArchive(set) }, - showReorder = searchQuery.isEmpty() - ) - } - } - } else { - item { - EmptyState(emptyText) - } - } - - if (archivedSets.isNotEmpty() && searchQuery.isEmpty()) { - item { - SectionHeader(archivedHeader) - } - itemsIndexed(archivedSets, key = { _, set -> "archived_${set.id}" }) { index, set -> - val position = when { - archivedSets.size == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == archivedSets.size - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - StickerSetItem( - stickerSet = set, - position = position, - onClick = { onSetClick(set) }, - onToggle = { onSetToggle(set) }, - onArchive = { onSetArchive(set) }, - showReorder = false - ) - } - } - } - } -} - -@Composable -private fun SectionHeader(text: String) { - Text( - text = text, - modifier = Modifier.padding(start = 16.dp, bottom = 8.dp, top = 24.dp), - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) -} - -@Composable -private fun EmptyState(text: String) { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 32.dp), - contentAlignment = Alignment.Center - ) { - Text( - text = text, - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/settings/storage/CacheController.kt b/presentation/src/main/java/org/monogram/presentation/settings/storage/CacheController.kt deleted file mode 100644 index 4b62ab37..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/storage/CacheController.kt +++ /dev/null @@ -1,26 +0,0 @@ -package org.monogram.presentation.settings.storage - -import android.content.Context -import coil3.imageLoader -import org.monogram.presentation.features.chats.currentChat.components.ExoPlayerCache -import java.io.File - -class CacheController(val context: Context, val exoPlayerCache: ExoPlayerCache) { - fun clearExo() { - exoPlayerCache.clearCache(context) - } - - fun clearImageLoader() { - context.imageLoader.memoryCache?.clear() - context.imageLoader.diskCache?.clear() - } - - fun clearAllCache() { - clearExo() - clearImageLoader() - } - - fun getCacheDir(): File? { - return context.cacheDir - } -} \ No newline at end of file diff --git a/presentation/src/main/java/org/monogram/presentation/settings/storage/StorageUsageComponent.kt b/presentation/src/main/java/org/monogram/presentation/settings/storage/StorageUsageComponent.kt deleted file mode 100644 index 6a441176..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/storage/StorageUsageComponent.kt +++ /dev/null @@ -1,127 +0,0 @@ -package org.monogram.presentation.settings.storage - -import androidx.annotation.OptIn -import androidx.media3.common.util.UnstableApi -import coil3.annotation.ExperimentalCoilApi -import com.arkivanov.decompose.value.MutableValue -import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.update -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch -import org.monogram.domain.models.StorageUsageModel -import org.monogram.domain.repository.SettingsRepository -import org.monogram.domain.repository.StickerRepository -import org.monogram.presentation.core.util.AppPreferences -import org.monogram.presentation.core.util.componentScope -import org.monogram.presentation.root.AppComponentContext - -interface StorageUsageComponent { - val state: Value - fun onBackClicked() - fun onClearAllClicked() - fun onClearChatClicked(chatId: Long) - fun onCacheLimitSizeChanged(size: Long) - fun onAutoClearCacheTimeChanged(time: Int) - fun onStorageOptimizerChanged(enabled: Boolean) - - data class State( - val usage: StorageUsageModel? = null, - val isLoading: Boolean = true, - val cacheLimitSize: Long = -1L, - val autoClearCacheTime: Int = -1, - val isStorageOptimizerEnabled: Boolean = false - ) -} - -class DefaultStorageUsageComponent( - context: AppComponentContext, - private val onBack: () -> Unit -) : StorageUsageComponent, AppComponentContext by context { - - private val settingsRepository: SettingsRepository = container.repositories.settingsRepository - private val appPreferences: AppPreferences = container.preferences.appPreferences - private val stickerRepository: StickerRepository = container.repositories.stickerRepository - private val cacheController: CacheController = container.utils.cacheController - - private val _state = MutableValue(StorageUsageComponent.State()) - override val state: Value = _state - private val scope = componentScope - - init { - loadStatistics() - appPreferences.cacheLimitSize.onEach { value -> - _state.update { it.copy(cacheLimitSize = value) } - }.launchIn(scope) - - appPreferences.autoClearCacheTime.onEach { value -> - _state.update { it.copy(autoClearCacheTime = value) } - }.launchIn(scope) - - scope.launch { - val enabled = settingsRepository.getStorageOptimizerEnabled() - _state.update { it.copy(isStorageOptimizerEnabled = enabled) } - } - } - - private fun loadStatistics() { - _state.update { it.copy(isLoading = true) } - scope.launch { - val usage = settingsRepository.getStorageUsage() - _state.update { it.copy(usage = usage, isLoading = false) } - } - } - - private fun updateDatabaseMaintenanceSettings( - limit: Long = _state.value.cacheLimitSize, - time: Int = _state.value.autoClearCacheTime - ) { - scope.launch { - val ttl = if (time > 0) time * 24 * 60 * 60 else -1 - settingsRepository.setDatabaseMaintenanceSettings(limit, ttl) - loadStatistics() - } - } - - override fun onBackClicked() { - onBack() - } - - @OptIn(UnstableApi::class, ExperimentalCoilApi::class) - override fun onClearAllClicked() { - scope.launch { - val success = settingsRepository.clearStorage() - if (success) { - stickerRepository.clearCache() - cacheController.clearAllCache() - loadStatistics() - } - } - } - - override fun onClearChatClicked(chatId: Long) { - scope.launch { - val success = settingsRepository.clearStorage(chatId) - if (success) { - loadStatistics() - } - } - } - - override fun onCacheLimitSizeChanged(size: Long) { - appPreferences.setCacheLimitSize(size) - updateDatabaseMaintenanceSettings(limit = size) - } - - override fun onAutoClearCacheTimeChanged(time: Int) { - appPreferences.setAutoClearCacheTime(time) - updateDatabaseMaintenanceSettings(time = time) - } - - override fun onStorageOptimizerChanged(enabled: Boolean) { - scope.launch { - settingsRepository.setStorageOptimizerEnabled(enabled) - _state.update { it.copy(isStorageOptimizerEnabled = enabled) } - } - } -} diff --git a/presentation/src/main/java/org/monogram/presentation/settings/storage/StorageUsageContent.kt b/presentation/src/main/java/org/monogram/presentation/settings/storage/StorageUsageContent.kt deleted file mode 100644 index dd716414..00000000 --- a/presentation/src/main/java/org/monogram/presentation/settings/storage/StorageUsageContent.kt +++ /dev/null @@ -1,711 +0,0 @@ -package org.monogram.presentation.settings.storage - -import androidx.compose.animation.core.Animatable -import androidx.compose.animation.core.FastOutSlowInEasing -import androidx.compose.animation.core.tween -import androidx.compose.foundation.Canvas -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.ArrowBack -import androidx.compose.material.icons.rounded.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.geometry.Size -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.StrokeCap -import androidx.compose.ui.graphics.drawscope.Stroke -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import org.monogram.domain.models.ChatStorageUsageModel -import org.monogram.presentation.R -import org.monogram.presentation.core.ui.ItemPosition -import org.monogram.presentation.core.ui.SettingsTile -import java.util.* -import kotlin.math.roundToInt - -private val ChartColors = listOf( - Color(0xFF4285F4), // Blue - Color(0xFF34A853), // Green - Color(0xFFF9AB00), // Orange - Color(0xFFEA4335), // Red - Color(0xFFAF52DE), // Purple - Color(0xFF00BFA5), // Teal - Color(0xFFFBBC04), // Yellow - Color(0xFFFA7B17), // Deep Orange - Color(0xFFF06292), // Pink - Color(0xFF4DB6AC), // Light Teal - Color(0xFF7986CB), // Indigo - Color(0xFF9575CD), // Deep Purple - Color(0xFFAED581), // Light Green - Color(0xFFFFD54F), // Amber - Color(0xFFFF8A65), // Coral - Color(0xFF90A4AE) // Blue Grey -) - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun StorageUsageContent(component: StorageUsageComponent) { - val state by component.state.subscribeAsState() - var selectedChatForDeletion by remember { mutableStateOf(null) } - var showClearAllConfirmation by remember { mutableStateOf(false) } - var showCacheLimitDialog by remember { mutableStateOf(false) } - var showAutoClearDialog by remember { mutableStateOf(false) } - - Scaffold( - topBar = { - TopAppBar( - title = { - Text( - text = stringResource(R.string.storage_usage_header), - fontSize = 22.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - }, - navigationIcon = { - IconButton(onClick = component::onBackClicked) { - Icon( - Icons.AutoMirrored.Rounded.ArrowBack, - contentDescription = stringResource(R.string.cd_back) - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background - ) - ) - }, - containerColor = MaterialTheme.colorScheme.background - ) { padding -> - if (state.isLoading) { - Box(modifier = Modifier - .fillMaxSize() - .padding(padding), contentAlignment = Alignment.Center) { - CircularProgressIndicator() - } - } else { - val usage = state.usage - LazyColumn( - modifier = Modifier - .fillMaxSize() - .padding(padding), - contentPadding = PaddingValues(start = 16.dp, end = 16.dp, top = 0.dp, bottom = 16.dp) - ) { - if (usage != null && usage.totalSize > 0) { - item { - SectionHeader(stringResource(R.string.overview_header)) - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = RoundedCornerShape(24.dp), - modifier = Modifier.fillMaxWidth() - ) { - StorageChartHeader( - totalSize = usage.totalSize, - totalFileCount = usage.fileCount, - chatStats = usage.chatStats - ) - } - } - - item { - Column(modifier = Modifier.fillMaxWidth()) { - Spacer(Modifier.height(24.dp)) - FilledTonalButton( - onClick = { showClearAllConfirmation = true }, - modifier = Modifier.fillMaxWidth(), - colors = ButtonDefaults.filledTonalButtonColors( - containerColor = MaterialTheme.colorScheme.errorContainer, - contentColor = MaterialTheme.colorScheme.onErrorContainer - ), - contentPadding = PaddingValues(vertical = 16.dp), - shape = RoundedCornerShape(20.dp) - ) { - Icon(Icons.Rounded.Delete, null) - Spacer(Modifier.width(12.dp)) - Text( - stringResource(R.string.clear_all_cache_format, formatSize(usage.totalSize)), - style = MaterialTheme.typography.titleMedium - ) - } - - Text( - text = stringResource(R.string.clear_cache_description), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier - .padding(top = 8.dp, start = 16.dp, end = 16.dp) - .align(Alignment.CenterHorizontally), - textAlign = TextAlign.Center - ) - } - } - } - - item { - SectionHeader(stringResource(R.string.settings_section_header)) - SettingsTile( - icon = Icons.Rounded.SdStorage, - title = stringResource(R.string.cache_limit_title), - subtitle = formatCacheLimit(state.cacheLimitSize), - iconColor = Color(0xFF4285F4), - position = ItemPosition.TOP, - onClick = { showCacheLimitDialog = true } - ) - Spacer(Modifier.height(2.dp)) - SettingsTile( - icon = Icons.Rounded.Timer, - title = stringResource(R.string.auto_clear_cache_title), - subtitle = formatAutoClearTime(state.autoClearCacheTime), - iconColor = Color(0xFF34A853), - position = ItemPosition.MIDDLE, - onClick = { showAutoClearDialog = true } - ) - Spacer(Modifier.height(2.dp)) - SettingsTile( - icon = Icons.Rounded.AutoFixHigh, - title = stringResource(R.string.storage_optimizer_title), - subtitle = stringResource(R.string.storage_optimizer_subtitle), - iconColor = Color(0xFFAF52DE), - position = ItemPosition.BOTTOM, - onClick = { component.onStorageOptimizerChanged(!state.isStorageOptimizerEnabled) }, - trailingContent = { - Switch( - checked = state.isStorageOptimizerEnabled, - onCheckedChange = { component.onStorageOptimizerChanged(it) } - ) - } - ) - } - - if (usage != null && usage.totalSize > 0) { - item { - SectionHeader(stringResource(R.string.detailed_usage_header)) - } - val sortedChats = usage.chatStats.sortedByDescending { it.size } - val maxChatSize = sortedChats.firstOrNull()?.size?.toFloat() ?: 1f - - itemsIndexed(sortedChats) { index, chatUsage -> - val position = when { - sortedChats.size == 1 -> ItemPosition.STANDALONE - index == 0 -> ItemPosition.TOP - index == sortedChats.size - 1 -> ItemPosition.BOTTOM - else -> ItemPosition.MIDDLE - } - StorageItemRow( - chatUsage = chatUsage, - maxFileSize = maxChatSize, - position = position, - onClick = { selectedChatForDeletion = chatUsage } - ) - if (index < sortedChats.size - 1) { - Spacer(Modifier.height(2.dp)) - } - } - } else if (usage == null || usage.totalSize == 0L) { - item { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 32.dp), - contentAlignment = Alignment.Center - ) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Icon( - Icons.Rounded.Folder, - null, - modifier = Modifier.size(64.dp), - tint = MaterialTheme.colorScheme.surfaceVariant - ) - Spacer(modifier = Modifier.height(16.dp)) - Text( - stringResource(R.string.storage_clean_title), - style = MaterialTheme.typography.titleMedium - ) - Text( - stringResource(R.string.storage_clean_description), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } - } - item { Spacer(modifier = Modifier.height(padding.calculateBottomPadding()))} - } - } - } - - selectedChatForDeletion?.let { chat -> - AlertDialog( - onDismissRequest = { selectedChatForDeletion = null }, - title = { Text(stringResource(R.string.clear_cache_title_dialog)) }, - text = { - Text( - stringResource(R.string.clear_cache_confirmation_format, chat.chatTitle, formatSize(chat.size)) - ) - }, - confirmButton = { - Button( - onClick = { - component.onClearChatClicked(chat.chatId) - selectedChatForDeletion = null - }, - colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error) - ) { - Text(stringResource(R.string.action_clear)) - } - }, - dismissButton = { - TextButton(onClick = { selectedChatForDeletion = null }) { - Text(stringResource(R.string.cancel_action)) - } - } - ) - } - - if (showClearAllConfirmation) { - AlertDialog( - onDismissRequest = { showClearAllConfirmation = false }, - title = { Text(stringResource(R.string.clear_all_cache_title)) }, - text = { Text(stringResource(R.string.clear_all_cache_confirmation)) }, - confirmButton = { - Button( - onClick = { - component.onClearAllClicked() - showClearAllConfirmation = false - }, - colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error) - ) { - Text(stringResource(R.string.action_clear_all)) - } - }, - dismissButton = { - TextButton(onClick = { showClearAllConfirmation = false }) { - Text(stringResource(R.string.cancel_action)) - } - } - ) - } - - if (showCacheLimitDialog) { - val steps = 2 - val range = 0f..3f - var sliderValue by remember { - mutableFloatStateOf( - when (state.cacheLimitSize) { - 5L * 1024 * 1024 * 1024 -> 0f - 10L * 1024 * 1024 * 1024 -> 1f - 15L * 1024 * 1024 * 1024 -> 2f - else -> 3f - } - ) - } - - AlertDialog( - onDismissRequest = { showCacheLimitDialog = false }, - title = { Text(stringResource(R.string.cache_limit_title)) }, - text = { - Column { - Text( - text = when (sliderValue.roundToInt()) { - 0 -> "5 GB" - 1 -> "10 GB" - 2 -> "15 GB" - else -> stringResource(R.string.unlimited_label) - }, - style = MaterialTheme.typography.titleMedium, - modifier = Modifier.align(Alignment.CenterHorizontally) - ) - Spacer(modifier = Modifier.height(16.dp)) - Slider( - value = sliderValue, - onValueChange = { sliderValue = it }, - valueRange = range, - steps = steps - ) - } - }, - confirmButton = { - Button( - onClick = { - val size = when (sliderValue.roundToInt()) { - 0 -> 5L * 1024 * 1024 * 1024 - 1 -> 10L * 1024 * 1024 * 1024 - 2 -> 15L * 1024 * 1024 * 1024 - else -> -1L - } - component.onCacheLimitSizeChanged(size) - showCacheLimitDialog = false - } - ) { - Text(stringResource(R.string.action_save)) - } - }, - dismissButton = { - TextButton(onClick = { showCacheLimitDialog = false }) { - Text(stringResource(R.string.cancel_action)) - } - } - ) - } - - if (showAutoClearDialog) { - val steps = 2 - val range = 0f..3f - var sliderValue by remember { - mutableFloatStateOf( - when (state.autoClearCacheTime) { - 1 -> 0f - 7 -> 1f - 30 -> 2f - else -> 3f - } - ) - } - - AlertDialog( - onDismissRequest = { showAutoClearDialog = false }, - title = { Text(stringResource(R.string.auto_clear_cache_title)) }, - text = { - Column { - Text( - text = when (sliderValue.roundToInt()) { - 0 -> stringResource(R.string.every_day_label) - 1 -> stringResource(R.string.every_week_label) - 2 -> stringResource(R.string.every_month_label) - else -> stringResource(R.string.never_label) - }, - style = MaterialTheme.typography.titleMedium, - modifier = Modifier.align(Alignment.CenterHorizontally) - ) - Spacer(modifier = Modifier.height(16.dp)) - Slider( - value = sliderValue, - onValueChange = { sliderValue = it }, - valueRange = range, - steps = steps - ) - } - }, - confirmButton = { - Button( - onClick = { - val time = when (sliderValue.roundToInt()) { - 0 -> 1 - 1 -> 7 - 2 -> 30 - else -> -1 - } - component.onAutoClearCacheTimeChanged(time) - showAutoClearDialog = false - } - ) { - Text(stringResource(R.string.action_save)) - } - }, - dismissButton = { - TextButton(onClick = { showAutoClearDialog = false }) { - Text(stringResource(R.string.cancel_action)) - } - } - ) - } -} - -@Composable -fun StorageChartHeader( - totalSize: Long, - totalFileCount: Int, - chatStats: List -) { - val fileTypeStats = remember(chatStats) { - chatStats.flatMap { it.byFileType } - .groupBy { it.fileType } - .map { (type, list) -> - Triple(type, list.sumOf { it.size }, list.sumOf { it.fileCount }) - } - .sortedByDescending { it.second } - } - - val chartData = remember(fileTypeStats) { - fileTypeStats.mapIndexed { index, (type, size, count) -> - ChartSegment(size, count, ChartColors[index % ChartColors.size], formatFileType(type)) - } - } - - val animationProgress = remember { Animatable(0f) } - LaunchedEffect(Unit) { - animationProgress.animateTo(1f, animationSpec = tween(1000, easing = FastOutSlowInEasing)) - } - - Column( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 16.dp) - ) { - Box( - contentAlignment = Alignment.Center, - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 24.dp) - ) { - Canvas(modifier = Modifier.size(200.dp)) { - val strokeWidth = 24.dp.toPx() - val radius = size.minDimension / 2 - strokeWidth / 2 - var startAngle = -90f - - val total = chartData.sumOf { it.value }.toFloat() - - if (total > 0) { - chartData.forEach { segment -> - val sweepAngle = (segment.value / total) * 360f * animationProgress.value - drawArc( - color = segment.color, - startAngle = startAngle, - sweepAngle = sweepAngle, - useCenter = false, - style = Stroke(width = strokeWidth, cap = StrokeCap.Round), - size = Size(radius * 2, radius * 2), - topLeft = Offset(center.x - radius, center.y - radius) - ) - startAngle += sweepAngle - } - } - } - - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Text( - text = stringResource(R.string.total_used_label), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Text( - text = formatSize(totalSize), - style = MaterialTheme.typography.headlineMedium.copy(fontWeight = FontWeight.Bold), - color = MaterialTheme.colorScheme.onSurface - ) - Text( - text = stringResource(R.string.files_count_label, totalFileCount), - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(top = 4.dp) - ) - } - } - - if (chartData.isNotEmpty()) { - HorizontalDivider( - modifier = Modifier.padding(horizontal = 16.dp), - color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f) - ) - Spacer(modifier = Modifier.height(16.dp)) - - Column(modifier = Modifier.padding(horizontal = 16.dp)) { - chartData.forEach { segment -> - Row( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 6.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box(modifier = Modifier - .size(12.dp) - .background(segment.color, CircleShape)) - Spacer(modifier = Modifier.width(12.dp)) - - Column(modifier = Modifier.weight(1f)) { - Text( - text = segment.label, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurface - ) - Text( - text = stringResource(R.string.files_count_label, segment.count), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - - Column(horizontalAlignment = Alignment.End) { - Text( - text = formatSize(segment.value), - style = MaterialTheme.typography.bodyMedium.copy(fontWeight = FontWeight.SemiBold), - color = MaterialTheme.colorScheme.onSurface - ) - val percentage = if (totalSize > 0) (segment.value.toFloat() / totalSize * 100) else 0f - if (percentage >= 0.1f) { - Text( - text = "${String.format(Locale.US, "%.1f", percentage)}%", - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - } - } - } - } - } - } - } -} - -@Composable -fun StorageItemRow( - chatUsage: ChatStorageUsageModel, - maxFileSize: Float, - position: ItemPosition, - onClick: () -> Unit -) { - val relativeProgress = if (maxFileSize > 0) { - (chatUsage.size / maxFileSize).coerceIn(0f, 1f) - } else 0f - - val color = - ChartColors[(chatUsage.chatId.hashCode() % ChartColors.size).let { if (it < 0) it + ChartColors.size else it }] - - val cornerRadius = 24.dp - val shape = when (position) { - ItemPosition.TOP -> RoundedCornerShape( - topStart = cornerRadius, - topEnd = cornerRadius, - bottomStart = 4.dp, - bottomEnd = 4.dp - ) - - ItemPosition.MIDDLE -> RoundedCornerShape(4.dp) - ItemPosition.BOTTOM -> RoundedCornerShape( - bottomStart = cornerRadius, - bottomEnd = cornerRadius, - topStart = 4.dp, - topEnd = 4.dp - ) - - ItemPosition.STANDALONE -> RoundedCornerShape(cornerRadius) - } - - Surface( - color = MaterialTheme.colorScheme.surfaceContainer, - shape = shape, - modifier = Modifier - .fillMaxWidth() - .clip(shape) - .clickable(onClick = onClick) - ) { - Row( - modifier = Modifier.padding(horizontal = 12.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Box( - modifier = Modifier - .size(40.dp) - .clip(CircleShape) - .background(color.copy(alpha = 0.15f)), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Rounded.Folder, - contentDescription = null, - tint = color, - modifier = Modifier.size(24.dp) - ) - } - - Spacer(modifier = Modifier.width(16.dp)) - - Column(modifier = Modifier.weight(1f)) { - Text( - text = chatUsage.chatTitle, - style = MaterialTheme.typography.titleMedium, - fontSize = 16.sp, - maxLines = 1 - ) - val fileTypesSummary = chatUsage.byFileType.sortedByDescending { it.size }.take(2) - .joinToString(", ") { formatFileType(it.fileType) } - Text( - text = if (fileTypesSummary.isNotEmpty()) "$fileTypesSummary • ${ - stringResource( - R.string.files_count_label, - chatUsage.fileCount - ) - }" else stringResource(R.string.files_count_label, chatUsage.fileCount), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) - Spacer(modifier = Modifier.height(6.dp)) - LinearProgressIndicator( - progress = { relativeProgress }, - modifier = Modifier - .fillMaxWidth(0.8f) - .height(4.dp) - .clip(CircleShape), - color = color, - trackColor = MaterialTheme.colorScheme.surfaceVariant, - ) - } - Text( - text = formatSize(chatUsage.size), - style = MaterialTheme.typography.bodyMedium, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.primary - ) - } - } -} - -@Composable -private fun SectionHeader(text: String) { - Text( - text = text, - modifier = Modifier.padding(start = 12.dp, bottom = 8.dp, top = 16.dp), - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.primary, - fontWeight = FontWeight.Bold - ) -} - -private data class ChartSegment(val value: Long, val count: Int, val color: Color, val label: String) - -private fun formatFileType(type: String): String { - return type.replace("FileType", "") - .replace(Regex("(? stringResource(R.string.unlimited_label) - else -> formatSize(size) - } -} - -@Composable -private fun formatAutoClearTime(days: Int): String { - return when (days) { - -1 -> stringResource(R.string.never_label) - 1 -> stringResource(R.string.every_day_label) - 7 -> stringResource(R.string.every_week_label) - 30 -> stringResource(R.string.every_month_label) - else -> stringResource(R.string.repeat_hours_format, days / 24) - } -} diff --git a/presentation/src/main/res/drawable/ic_app_logo.xml b/presentation/src/main/res/drawable/ic_app_logo.xml deleted file mode 100644 index 70d88748..00000000 --- a/presentation/src/main/res/drawable/ic_app_logo.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/presentation/src/main/res/drawable/ic_apple.xml b/presentation/src/main/res/drawable/ic_apple.xml deleted file mode 100644 index f6a7409c..00000000 --- a/presentation/src/main/res/drawable/ic_apple.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/presentation/src/main/res/drawable/ic_chrome.xml b/presentation/src/main/res/drawable/ic_chrome.xml deleted file mode 100644 index b645ef1a..00000000 --- a/presentation/src/main/res/drawable/ic_chrome.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/presentation/src/main/res/drawable/ic_forward_10.xml b/presentation/src/main/res/drawable/ic_forward_10.xml deleted file mode 100644 index ec7c5887..00000000 --- a/presentation/src/main/res/drawable/ic_forward_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - \ No newline at end of file diff --git a/presentation/src/main/res/drawable/ic_map_marker.xml b/presentation/src/main/res/drawable/ic_map_marker.xml deleted file mode 100644 index 027da863..00000000 --- a/presentation/src/main/res/drawable/ic_map_marker.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - \ No newline at end of file diff --git a/presentation/src/main/res/drawable/ic_oculus.xml b/presentation/src/main/res/drawable/ic_oculus.xml deleted file mode 100644 index cfd73367..00000000 --- a/presentation/src/main/res/drawable/ic_oculus.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/presentation/src/main/res/drawable/ic_pause.xml b/presentation/src/main/res/drawable/ic_pause.xml deleted file mode 100644 index 100ea8ed..00000000 --- a/presentation/src/main/res/drawable/ic_pause.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - \ No newline at end of file diff --git a/presentation/src/main/res/drawable/ic_play.xml b/presentation/src/main/res/drawable/ic_play.xml deleted file mode 100644 index bacb4152..00000000 --- a/presentation/src/main/res/drawable/ic_play.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - \ No newline at end of file diff --git a/presentation/src/main/res/drawable/ic_quality_2k.xml b/presentation/src/main/res/drawable/ic_quality_2k.xml deleted file mode 100644 index 17b865cf..00000000 --- a/presentation/src/main/res/drawable/ic_quality_2k.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/presentation/src/main/res/drawable/ic_quality_4k.xml b/presentation/src/main/res/drawable/ic_quality_4k.xml deleted file mode 100644 index b6b314aa..00000000 --- a/presentation/src/main/res/drawable/ic_quality_4k.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/presentation/src/main/res/drawable/ic_quality_5k.xml b/presentation/src/main/res/drawable/ic_quality_5k.xml deleted file mode 100644 index 048adb46..00000000 --- a/presentation/src/main/res/drawable/ic_quality_5k.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/presentation/src/main/res/drawable/ic_quality_8k.xml b/presentation/src/main/res/drawable/ic_quality_8k.xml deleted file mode 100644 index 5a7f677f..00000000 --- a/presentation/src/main/res/drawable/ic_quality_8k.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/presentation/src/main/res/drawable/ic_quality_auto.xml b/presentation/src/main/res/drawable/ic_quality_auto.xml deleted file mode 100644 index 1e840767..00000000 --- a/presentation/src/main/res/drawable/ic_quality_auto.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/presentation/src/main/res/drawable/ic_quality_full_hd.xml b/presentation/src/main/res/drawable/ic_quality_full_hd.xml deleted file mode 100644 index 6631665f..00000000 --- a/presentation/src/main/res/drawable/ic_quality_full_hd.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/presentation/src/main/res/drawable/ic_quality_hd.xml b/presentation/src/main/res/drawable/ic_quality_hd.xml deleted file mode 100644 index 0f5a4ed9..00000000 --- a/presentation/src/main/res/drawable/ic_quality_hd.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/presentation/src/main/res/drawable/ic_quality_high_res.xml b/presentation/src/main/res/drawable/ic_quality_high_res.xml deleted file mode 100644 index 1305fbe2..00000000 --- a/presentation/src/main/res/drawable/ic_quality_high_res.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/presentation/src/main/res/drawable/ic_quality_sd.xml b/presentation/src/main/res/drawable/ic_quality_sd.xml deleted file mode 100644 index 22bd184a..00000000 --- a/presentation/src/main/res/drawable/ic_quality_sd.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/presentation/src/main/res/drawable/ic_replay_10.xml b/presentation/src/main/res/drawable/ic_replay_10.xml deleted file mode 100644 index f2881a18..00000000 --- a/presentation/src/main/res/drawable/ic_replay_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - \ No newline at end of file diff --git a/presentation/src/main/res/drawable/ic_windows.xml b/presentation/src/main/res/drawable/ic_windows.xml deleted file mode 100644 index 6a105a36..00000000 --- a/presentation/src/main/res/drawable/ic_windows.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/presentation/src/main/res/drawable/outline_web_24.xml b/presentation/src/main/res/drawable/outline_web_24.xml deleted file mode 100644 index b62d2ade..00000000 --- a/presentation/src/main/res/drawable/outline_web_24.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/presentation/src/main/res/raw/konata b/presentation/src/main/res/raw/konata deleted file mode 100644 index 6c45f28c..00000000 Binary files a/presentation/src/main/res/raw/konata and /dev/null differ diff --git a/presentation/src/main/res/raw/star.gltf b/presentation/src/main/res/raw/star.gltf deleted file mode 100644 index d1d236e3..00000000 --- a/presentation/src/main/res/raw/star.gltf +++ /dev/null @@ -1 +0,0 @@ -{"accessors" : [{"bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 4338, "type" : "SCALAR", "max" : [1077], "min" : [0]}, {"bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 1078, "type" : "VEC3", "max" : [32.547000885009766, 31.11210060119629, 6.589240074157715], "min" : [-32.547000885009766, -31.11210060119629, -6.589240074157715], "name" : "POSITION"}, {"bufferView" : 1, "byteOffset" : 12, "componentType" : 5126, "count" : 1078, "type" : "VEC3", "max" : [0, 1, 0], "min" : [0, 1, 0], "name" : "NORMAL"}, {"bufferView" : 1, "byteOffset" : 24, "componentType" : 5126, "count" : 1078, "type" : "VEC2", "max" : [0, 1], "min" : [0, 1], "name" : "TEXCOORD_0"}], "asset" : {"generator" : "Aspose.3D 25.11.0", "version" : "2.0"}, "buffers" : [{"uri" : "data:application/octet-stream;base64,AAABAAIAAwAEAAUABgAHAAgACQAKAAsACQALAAwACwANAA4ACwAOAA8ADAALAA8ADAAPABAACQAMABEADAAQABEADgANABIADgASABMADwAOABMADwATABQAEAAPABQAEAAUABUAEQAQABUAEQAVABYAEwASABcAEwAXABgAFAATABgAFAAYABkAFQAUABkAFQAZABoAFgAVABoAFgAaABsAHAAdAB4AHAAeAB8AFwAgACEAFwAhACIAGAAXACIAGAAiACMAGQAYACMAGQAjACQAGgAZACQAGgAkACUAGwAaACUAGwAlACYAJwAbACYAJwAmACgAKQAcAB8AKQAfACoAKgAfACsAHwAeACsALAApACoALAAqAC0ALgAsAC0ALgAtAC8AIQAuAC8AIQAvADAAIgAhADAAIgAwADEAIwAiADEAIwAxADIAJAAjADIAJAAyADMAJQAkADMAJQAzADQANAAzADUANAA1ADYAJgAlADQAJgA0ADcANwA0ADYANwA2ADgAKAAmADcAKAA3ADkAOQA3ADgAOQA4ADoAOwAoADkAOwA5ADwAPAA5ADoAPAA6AD0APgA7ADwAPgA8AD8APwA8AD0APwA9AEAAQQA+AD8AQQA/AEIAQwBEAEUAQwBFAEYARABBAEIARABCAEUAQgA/AEAAQgBAAEcARgBFAEgARQBCAEcARQBHAEgALQAqACsALQArAEkASQArAEoALwAtAEkALwBJAEsAMAAvAEsAMABLAEwAMQAwAEwAMQBMAE0AMgAxAE0AMgBNAE4ASwBJAEoASwBKAE8ATABLAE8ATABPAFAATQBMAFAATQBQAFEAUABPAFIAUABSAFMAUQBQAFMAUQBTAFQAVQBRAFQAVQBUAFYAUwBSAFcAUwBXAFgAVABTAFgAVABYAFkAVgBUAFkAVgBZAFoAWwBWAFoAWwBaAFwAXQBbAFwAXQBcAF4AXQBeAF8AXQBfAGAAWABXAGEAWABhAGIAWQBYAGIAWQBiAGMAWgBZAGMAWgBjAGQAXABaAGQAXABkAGUAXgBcAGUAXgBlAGYAXwBeAGYAXwBmAGcAYABfAGcAYABnAGgAYgBhAGkAYgBpAGoAYwBiAGoAYwBqAGsAZQBkAGwAZQBsAG0AZABjAGsAZABrAGwAbABrAG4AbABuAG8AZgBlAG0AZgBtAHAAZwBmAHAAZwBwAHEAcQBwAHIAcQByAHMAaABnAHEAaABxAHQAdQBoAHQAdQB0AHYAaQB3AHgAaQB4AHkAawBqAHoAawB6AG4AagBpAHkAagB5AHoAeQB4AHsAeQB7AHwAbwBuAH0AbgB6AH0AegB5AHwAegB8AH0AdABxAHMAdABzAH4AfgBzAH8AcwByAH8AdgB0AH4AdgB+AIAAgQB2AIAAgQCAAIIAgAB+AH8AgAB/AIMAggCAAIMAggCDAIQAcgBwAIUAhACDAIYAgwB/AIYAfwByAIUAfwCFAIYAhgCHAIgAhgCIAIQAhACIAIkAhACJAIoAhACKAIIAgQCCAIoAdgCBAIsAdgCLAHUAgQCKAIsAdQCLAIwAdQCMAGAAdQBgAGgAVgBbAI0AVgCNAFUAWwBdAI0AYACMAI0AYACNAF0AjQCOAFEAjQBRAFUAUQCOAI8AUQCPAE0AMgBOAJAATQCPAJAATQCQAE4ANgA1AJEANQAzAJEAMwAyAJAAMwCQAJEAPQA6AJIAOgA4AJIAOAA2AJEAOACRAJIARwBAAJMAPQCSAJMAPQCTAEAASABHAJMASACTAJQASACUAJUASACVAEYARgCVAJYARgCWAEMAlgCXAJgAlgCYAEMAQQBEAJgARABDAJgAOwA+AJkAPgBBAJgAPgCYAJkAOwCZACcAOwAnACgAJwCZAJoAJwCaAJsAEQAWAJsAJwCbABYAJwAWABsACgAJAJwACQARAJwAEQCbAJwAnACdAJ4AnACeAAoACwAKAJ8ACwCfAA0ACgCeAJ8AEgANAJ8AEgCfAKAAEgCgAKEAEgChABcALgAhACAALgAgAKIAFwChAKIAFwCiACAALAAuAKIAHAApAKMALACiAKMALACjACkAHACjAKQAHACkAB0AHQCkAKUAHgAdAKUAHgClAKYAUgBPAEoAUgBKAKcASgArAKcAKwAeAKYAKwCmAKcAUgCnAKgAaQBhAKkAaQCpAHcAYQBXAKkAVwBSAKgAVwCoAKkAewB4AKoAeAB3AKoAdwCpAKoAqgCrAKwAqgCsAHsAfQB8AK0AfAB7AKwAfACsAK0AbQBsAG8AbQBvAK4AfQCtAK4AfQCuAG8AcABtAK8AcACvAIUAbQCuAK8AsACxALIAsACyALMAswCyALQAswC0ALUAtgC3ALgAtgC4ALkAugC7ALwAugC8AL0AvQC8AL4AvQC+AL8AvwC+AMAAvwDAAMEAwgDDAMQAwgDEAMUAxgDHAMgAxgDIAMkAyQDIAMoAyQDKAMsAzADNAM4AzADOAM8A0ADRANIA0ADSANMA0wDSANQA0wDUANUA1QDUANYA1QDWANcA2ADZANoA2ADaANsA3ADdAN4A3ADeAN8A3wDeAOAA3wDgAOEA4gDjAOQA4gDkAOUA5gDnAOgA5gDoAOkA6QDoAOoA6QDqAOsA6wDqAOwA6wDsAO0A7gDvAPAA7gDwAPEA8gDzAPQA8gD0APUA9QD0APYA9QD2APcA+AD5APoA+AD6APsA/AD9AP4A/AD+AP8A/wD+AAAB/wAAAQEBAQEAAQIBAQECAQMBBAEFAQYBBAEGAQcBCAEJAQoBCAEKAQsBCwEKAQwBCwEMAQ0BDgEPARABDgEQAREBEgETARQBEgEUARUBFQEUARYBFQEWARcBFwEWARgBFwEYARkBGQEYARoBGQEaARsBHAEdAR4BHAEeAR8BIAEhASIBIAEiASMBIwEiASQBIwEkASUBJgEnASgBJgEoASkBKgErASwBKgEsAS0BLQEsAS4BLQEuAS8BLwEuATABLwEwATEBMgEzATQBMgE0ATUBNgE3ATgBNgE4ATkBOgE7ATwBOgE8AT0BOwE+AT8BOwE/ATwBPgFAAUEBPgFBAT8BQgFDAUQBQgFEAUUBRgFHAUgBRgFIAUkBRwFKAUsBRwFLAUgBTAFNAU4BTAFOAU8BUAFRAVIBUAFSAVMBUQFUAVUBUQFVAVIBVAFWAVcBVAFXAVUBVgFYAVkBVgFZAVcBWgFbAVwBWgFcAV0BXgFfAWABXgFgAWEBXwFiAWMBXwFjAWABZAFlAWYBZAFmAWcBaAFpAWoBaAFqAWsBaQFsAW0BaQFtAWoBbAFuAW8BbAFvAW0BcAFxAXIBcAFyAXMBdAF1AXYBdAF2AXcBdQF4AXkBdQF5AXYBegF7AXwBegF8AX0BfgF/AYABfgGAAYEBfwGCAYMBfwGDAYABggGEAYUBggGFAYMBhgGHAYgBhgGIAYkBigGLAYwBigGMAY0BiwGOAY8BiwGPAYwBkAGRAZIBkAGSAZMBlAGVAZYBlAGWAZcBlQGYAZkBlQGZAZYBmAGaAZsBmAGbAZkBnAGdAZ4BnAGeAZ8BoAGhAaIBoAGiAaMBoQGkAaUBoQGlAaIBpgGnAagBpgGoAakBqgGrAawBqgGsAa0BqwGuAa8BqwGvAawBrgGwAbEBrgGxAa8BsgGzAbQBsgG0AbUBtgG3AbgBtgG4AbkBtwG6AbsBtwG7AbgBvAG9ATcBvAE3ATYBvgG/ATsBvgE7AToBvwHAAT4BvwE+ATsBwAHBAUABwAFAAT4BwgHDAUMBwgFDAUIBxAHFAUcBxAFHAUYBxQHGAUoBxQFKAUcBxwHIAU0BxwFNAUwByQHKAVEByQFRAVABygHLAVQBygFUAVEBywHMAVYBywFWAVQBzAHNAVgBzAFYAVYBzgHPAVsBzgFbAVoB0AHRAV8B0AFfAV4B0QHSAWIB0QFiAV8B0wHUAWUB0wFlAWQB1QHWAWkB1QFpAWgB1gHXAWwB1gFsAWkB1wHYAW4B1wFuAWwB2QHaAXEB2QFxAXAB2wHcAXUB2wF1AXQB3AHdAXgB3AF4AXUB3gHfAXsB3gF7AXoB4AHhAX8B4AF/AX4B4QHiAYIB4QGCAX8B4gHjAYQB4gGEAYIB5AHlAYcB5AGHAYYB5gHnAYsB5gGLAYoB5wHoAY4B5wGOAYsB6QHqAZEB6QGRAZAB6wHsAZUB6wGVAZQB7AHtAZgB7AGYAZUB7QHuAZoB7QGaAZgB7wHwAZ0B7wGdAZwB8QHyAaEB8QGhAaAB8gHzAaQB8gGkAaEB9AH1AacB9AGnAaYB9gH3AasB9gGrAaoB9wH4Aa4B9wGuAasB+AH5AbAB+AGwAa4B+gH7AbMB+gGzAbIB/AH9AbcB/AG3AbYB/QH+AboB/QG6AbcB/wEAAr0B/wG9AbwBAQICAr8BAQK/Ab4BAgIDAsABAgLAAb8BAwIEAsEBAwLBAcABBQIGAsMBBQLDAcIBBwIIAsUBBwLFAcQBCAIJAsYBCALGAcUBCgILAsgBCgLIAccBDAINAsoBDALKAckBDQIOAssBDQLLAcoBDgIPAswBDgLMAcsBDwIQAs0BDwLNAcwBEQISAs8BEQLPAc4BEwIUAtEBEwLRAdABFAIVAtIBFALSAdEBFgIXAtQBFgLUAdMBGAIZAtYBGALWAdUBGQIaAtcBGQLXAdYBGgIbAtgBGgLYAdcBHAIdAtoBHALaAdkBHgIfAtwBHgLcAdsBHwIgAt0BHwLdAdwBIQIiAt8BIQLfAd4BIwIkAuEBIwLhAeABJAIlAuIBJALiAeEBJQImAuMBJQLjAeIBJwIoAuUBJwLlAeQBKQIqAucBKQLnAeYBKgIrAugBKgLoAecBLAItAuoBLALqAekBLgIvAuwBLgLsAesBLwIwAu0BLwLtAewBMAIxAu4BMALuAe0BMgIzAvABMgLwAe8BNAI1AvIBNALyAfEBNQI2AvMBNQLzAfIBNwI4AvUBNwL1AfQBOQI6AvcBOQL3AfYBOgI7AvgBOgL4AfcBOwI8AvkBOwL5AfgBPQI+AvsBPQL7AfoBPwJAAv0BPwL9AfwBQAJBAv4BQAL+Af0BQgJDAgACQgIAAv8BRAJFAgICRAICAgECRQJGAgMCRQIDAgICRgJHAgQCRgIEAgMCSAJJAgYCSAIGAgUCSgJLAggCSgIIAgcCSwJMAgkCSwIJAggCTQJOAgsCTQILAgoCTwJQAg0CTwINAgwCUAJRAg4CUAIOAg0CUQJSAg8CUQIPAg4CUgJTAhACUgIQAg8CVAJVAhICVAISAhECVgJXAhQCVgIUAhMCVwJYAhUCVwIVAhQCWQJaAhcCWQIXAhYCWwJcAhkCWwIZAhgCXAJdAhoCXAIaAhkCXQJeAhsCXQIbAhoCXwJgAh0CXwIdAhwCYQJiAh8CYQIfAh4CYgJjAiACYgIgAh8CZAJlAiICZAIiAiECZgJnAiQCZgIkAiMCZwJoAiUCZwIlAiQCaAJpAiYCaAImAiUCagJrAigCagIoAicCbAJtAioCbAIqAikCbQJuAisCbQIrAioCbwJwAi0CbwItAiwCcQJyAi8CcQIvAi4CcgJzAjACcgIwAi8CcwJ0AjECcwIxAjACdQJ2AjMCdQIzAjICdwJ4AjUCdwI1AjQCeAJ5AjYCeAI2AjUCegJ7AjgCegI4AjcCfAJ9AjoCfAI6AjkCfQJ+AjsCfQI7AjoCfgJ/AjwCfgI8AjsCgAKBAj4CgAI+Aj0CggKDAkACggJAAj8CgwKEAkECgwJBAkAChQKGAkMChQJDAkIChwKIAkUChwJFAkQCiAKJAkYCiAJGAkUCiQKKAkcCiQJHAkYCiwKMAkkCiwJJAkgCjQKOAksCjQJLAkoCjgKPAkwCjgJMAksCkAKRAk4CkAJOAk0CkgKTAlACkgJQAk8CkwKUAlECkwJRAlAClAKVAlIClAJSAlEClQKWAlMClQJTAlIClwKYAlUClwJVAlQCmQKaAlcCmQJXAlYCmgKbAlgCmgJYAlcCnAKdAloCnAJaAlkCngKfAlwCngJcAlsCnwKgAl0CnwJdAlwCoAKhAl4CoAJeAl0CogKjAmACogJgAl8CpAKlAmICpAJiAmECpQKmAmMCpQJjAmICpwKoAmUCpwJlAmQCqQKqAmcCqQJnAmYCqgKrAmgCqgJoAmcCqwKsAmkCqwJpAmgCrQKuAmsCrQJrAmoCrwKwAm0CrwJtAmwCsAKxAm4CsAJuAm0CsgKzAnACsgJwAm8CtAK1AnICtAJyAnECtQK2AnMCtQJzAnICtgK3AnQCtgJ0AnMCuAK5AnYCuAJ2AnUCugK7AngCugJ4AncCuwK8AnkCuwJ5AngCvQK+AnsCvQJ7AnoCvwLAAn0CvwJ9AnwCwALBAn4CwAJ+An0CwQLCAn8CwQJ/An4CwwLEAoECwwKBAoACxQLGAoMCxQKDAoICxgLHAoQCxgKEAoMCyALJAsoCyALKAssCzALNAskCzALJAs4CyALOAskCzALPAs0C0ALRAs0C0ALNAtICzwLSAs0C0gLTAtAC0gLUAtUC0gLVAtMC1gLXAtUC1ALWAtUC2ALZAtcC2gLYAtcC2gLXAtYC2wLcAt0C2wLdAtkC2ALeAtsC2ALbAtkC3wLgAt0C3wLdAuEC4gLhAt0C4gLdAuMC3ALjAt0C5ALgAt8C5ALfAuUC5gLkAuUC5gLlAucC5wLoAuYC6QLqAusC7ALtAugC7ALoAu4C6gLuAugC6wLqAugC7wLwAu0C7ALvAu0C8ALxAvIC8ALyAu0C8wL0AvIC8wLyAvUC8QL1AvIC8wL2AvcC8wL3AvQC+AL3AvYC+AL2AvkC+gL7AvgC+gL4AvkC/AL9AvoC/AL6Av4C/wL+AvoC+QL/AvoCBwAGAP0CAAMBAwcAAAMHAP0C/AIAA/0CCAACAwYAAwMEAwIDBQMDAwIDCAAFAwIDBAAGAwQDBAAEAwUABwMFAAQDAwMHAwQDCAMDAAUACAMAAAMAAgAJAwAACgMBAAAACgMAAAgDAgALAwwDAgAMAwkDDQMOAw8DDQMPAwwDEAMNAwwDCwMRAxADCwMQAwwDEgMTAxQDEgMUAw8DDgMSAw8DEwMVAxQDFgMXAxUDFgMVAxMDGAMZAxcDGAMXAxYDGAMaAxkDGwMcAxkDGgMdAxsDGgMbAxkDGwMeAx8DGwMfAxwDIAMhAyIDIwMkAx8DIwMfAyUDHgMlAx8DJgMnAygDJgMoAykDKgMmAykDJAMqAykDJwMrAygDLAMtAysDLAMrAycDLgMvAy0DLgMtAywDywIvAy4DywIuAzADywLKAi8DMQMyAwUAMQMFAAcDAwMxAwcDMgMKAwgDMgMIAwUAMwM0AzIDMwMyAzEDAwMzAzEDNAM1AwoDNAMKAzIDNQMBAAoDNgM3AzQDNgM0AzMDBQM2AzMDBQMzAwMDNwM4AzUDNwM1AzQDOAMBADUDCAA5AzYDCAA2AwUDOQM6AzcDOQM3AzYDOgM7AzgDOgM4AzcDOwMCAAEAOwMBADgDPAM9AzkDPAM5AwgAAQM8AwgAAQMIAAcAPQM+AzoDPQM6AzkDPgM/AzsDPgM7AzoDPwNAAwIAPwMCADsDQAMRAwsDQAMLAwIAQQNCAzwDQQM8AwEDQwNBAwEDQwMBAwADQgNEAz0DQgM9AzwDRAPpAj4DRAM+Az0D6QJFAz8D6QI/Az4DRQNGA0ADRQNAAz8DRgNHAxEDRgMRA0ADRwNIAxADRwMQAxED9gJJA/8C9gL/AvkCSQNKA/4CSQP+Av8C8wJJA/YC8wL1AkoD8wJKA0kDSgNLA/wCSgP8Av4C9QLxAksD9QJLA0oDSwNDAwADSwMAA/wC8QLwAkMD8QJDA0sD8ALvAkED8AJBA0MD7wLsAkID7wJCA0ED7ALuAkQD7AJEA0ID7gLqAukC7gLpAkQD5wLlAkYD5wJGA0UD5QJMA0cD5QJHA0YDTANNA0gDTANIA0cDSANOAw0DSAMNAxADTQNPA04DTQNOA0gDTgNQAw4DTgMOAw0DTwMYA1ADTwNQA04DUANRAxIDUAMSAw4DGANRA1ADUQMWAxMDUQMTAxIDGAMWA1ED3wJSA0wD3wJMA+UCUgMdA00DUgNNA0wDHQMaA08DHQNPA00DGgMYA08D4gJTA98C4gLfAuECUwNUA1IDUwNSA98CVAMbAx0DVAMdA1IDVQNWA1MDVQNTA+ICVwNVA+ICVwPiAuMCVgNYA1QDVgNUA1MDWAMeAxsDWAMbA1QDWQNXA+MCWQPjAtwCWgNZA9wC2wJaA9wCWwNcA1cDWwNXA1kDXQNbA1kDXQNZA1oDXANeA1UDXANVA1cDXgNfA1YDXgNWA1UDXwNgA1gDXwNYA1YDYAMlAx4DYAMeA1gD3gJdA1oD3gJaA9sCYQNiA10DYQNdA94C2gJhA94C2gLeAtgCYgPIAlsDYgNbA10DyALLAlwDyAJcA1sDywIwA14DywJeA1wDMANjA18DMANfA14DYwNkA2ADYwNgA18DZAMjAyUDZAMlA2ADZQNmA2EDZQNhA9oC1AJlA9oC1ALaAtYCZgNnA2IDZgNiA2EDZwPOAsgCZwPIAmIDLgNoA2MDLgNjAzADaANpA2QDaANkA2MDaQNqAyMDaQMjA2QDagMqAyQDagMkAyMD0gLPAmUD0gJlA9QCzwLMAmYDzwJmA2UDzAJnA2YDzALOAmcDawNoAy4DLANrAy4DawNpA2gDawNsA2oDawNqA2kDbAMmAyoDbAMqA2oDLANsA2sDLAMnAyYDLAMmA2wDOAFtA24DOAFuAzkBPAFvA3ADPAFwAz0BPwFxA28DPwFvAzwBQQFyA3EDQQFxAz8BRAFzA3QDRAF0A0UBSAF1A3YDSAF2A0kBSwF3A3UDSwF1A0gBTgF4A3kDTgF5A08BUgF6A3sDUgF7A1MBVQF8A3oDVQF6A1IBVwF9A3wDVwF8A1UBWQF+A30DWQF9A1cBXAF/A4ADXAGAA10BYAGBA4IDYAGCA2EBYwGDA4EDYwGBA2ABZgGEA4UDZgGFA2cBagGGA4cDagGHA2sBbQGIA4YDbQGGA2oBbwGJA4gDbwGIA20BcgGKA4sDcgGLA3MBdgGMA40DdgGNA3cBeQGOA4wDeQGMA3YBfAGPA5ADfAGQA30BgAGRA5IDgAGSA4EBgwGTA5EDgwGRA4ABhQGUA5MDhQGTA4MBiAGVA5YDiAGWA4kBjAGXA5gDjAGYA40BjwGZA5cDjwGXA4wBkgGaA5sDkgGbA5MBlgGcA50DlgGdA5cBmQGeA5wDmQGcA5YBmwGfA54DmwGeA5kBngGgA6EDngGhA58BogGiA6MDogGjA6MBpQGkA6IDpQGiA6IBqAGlA6YDqAGmA6kBrAGnA6gDrAGoA60BrwGpA6cDrwGnA6wBsQGqA6kDsQGpA68BtAGrA6wDtAGsA7UBuAGtA64DuAGuA7kBuwGvA60DuwGtA7gBbQOwA7EDbQOxA24DbwOyA7MDbwOzA3ADcQO0A7IDcQOyA28DcgO1A7QDcgO0A3EDcwO2A7cDcwO3A3QDdQO4A7kDdQO5A3YDdwO6A7gDdwO4A3UDeAO7A7wDeAO8A3kDegO9A74DegO+A3sDfAO/A70DfAO9A3oDfQPAA78DfQO/A3wDfgPBA8ADfgPAA30DfwPCA8MDfwPDA4ADgQPEA8UDgQPFA4IDgwPGA8QDgwPEA4EDhAPHA8gDhAPIA4UDhgPJA8oDhgPKA4cDiAPLA8kDiAPJA4YDiQPMA8sDiQPLA4gDigPNA84DigPOA4sDjAPPA9ADjAPQA40DjgPRA88DjgPPA4wDjwPSA9MDjwPTA5ADkQPUA9UDkQPVA5IDkwPWA9QDkwPUA5EDlAPXA9YDlAPWA5MDlQPYA9kDlQPZA5YDlwPaA9sDlwPbA5gDmQPcA9oDmQPaA5cDmgPdA94DmgPeA5sDnAPfA+ADnAPgA50DngPhA98DngPfA5wDnwPiA+EDnwPhA54DoAPjA+QDoAPkA6EDogPlA+YDogPmA6MDpAPnA+UDpAPlA6IDpQPoA+kDpQPpA6YDpwPqA+sDpwPrA6gDqQPsA+oDqQPqA6cDqgPtA+wDqgPsA6kDqwPuA+8DqwPvA6wDrQPwA/EDrQPxA64DrwPyA/ADrwPwA60DsAPzA/QDsAP0A7EDsgP1A/YDsgP2A7MDtAP3A/UDtAP1A7IDtQP4A/cDtQP3A7QDtgP5A/oDtgP6A7cDuAP7A/wDuAP8A7kDugP9A/sDugP7A7gDuwP+A/8DuwP/A7wDvQMABAEEvQMBBL4DvwMCBAAEvwMABL0DwAMDBAIEwAMCBL8DwQMEBAMEwQMDBMADwgMFBAYEwgMGBMMDxAMHBAgExAMIBMUDxgMJBAcExgMHBMQDxwMKBAsExwMLBMgDyQMMBA0EyQMNBMoDywMOBAwEywMMBMkDzAMPBA4EzAMOBMsDzQMQBBEEzQMRBM4DzwMSBBMEzwMTBNAD0QMUBBIE0QMSBM8D0gMVBBYE0gMWBNMD1AMXBBgE1AMYBNUD1gMZBBcE1gMXBNQD1wMaBBkE1wMZBNYD2AMbBBwE2AMcBNkD2gMdBB4E2gMeBNsD3AMfBB0E3AMdBNoD3QMgBCEE3QMhBN4D3wMiBCME3wMjBOAD4QMkBCIE4QMiBN8D4gMlBCQE4gMkBOED4wMmBCcE4wMnBOQD5QMoBCkE5QMpBOYD5wMqBCgE5wMoBOUD6AMrBCwE6AMsBOkD6gMtBC4E6gMuBOsD7AMvBC0E7AMtBOoD7QMwBC8E7QMvBOwD7gMxBDIE7gMyBO8D8AMzBDQE8AM0BPED8gM1BDME8gMzBPAD8wMyATUB8wM1AfQD9QMvATEB9QMxAfYD9wMtAS8B9wMvAfUD+AMqAS0B+AMtAfcD+QMmASkB+QMpAfoD+wMjASUB+wMlAfwD/QMgASMB/QMjAfsD/gMcAR8B/gMfAf8DAAQZARsBAAQbAQEEAgQXARkBAgQZAQAEAwQVARcBAwQXAQIEBAQSARUBBAQVAQMEBQQOAREBBQQRAQYEBwQLAQ0BBwQNAQgECQQIAQsBCQQLAQcECgQEAQcBCgQHAQsEDAQBAQMBDAQDAQ0EDgT/AAEBDgQBAQwEDwT8AP8ADwT/AA4EEAT4APsAEAT7ABEEEgT1APcAEgT3ABMEFATyAPUAFAT1ABIEFQTuAPEAFQTxABYEFwTrAO0AFwTtABgEGQTpAOsAGQTrABcEGgTmAOkAGgTpABkEGwTiAOUAGwTlABwEHQTfAOEAHQThAB4EHwTcAN8AHwTfAB0EIATYANsAIATbACEEIgTVANcAIgTXACMEJATTANUAJATVACIEJQTQANMAJQTTACQEJgTMAM8AJgTPACcEKATJAMsAKATLACkEKgTGAMkAKgTJACgEKwTCAMUAKwTFACwELQS/AMEALQTBAC4ELwS9AL8ALwS/AC0EMAS6AL0AMAS9AC8EMQS2ALkAMQS5ADIEMwSzALUAMwS1ADQENQSwALMANQSzADME6QLrAucC6QLnAkUD6ALnAusCAAAAAMLMF0EEVlRBkzqlQAAAAAAAAIA/AAAAAAAAAAAAAIA/q8/1QDtwbkHFcqJAAAAAAAAAgD8AAAAAAAAAAAAAgD8/dPdAmEwzQfFLs0AAAAAAAACAPwAAAAAAAAAAAACAPxA7M0CrPudB4h7zPwAAAAAAAIA/AAAAAAAAAAAAAIA/stePP0CT9EE1Xq4/AAAAAAAAgD8AAAAAAAAAAAAAgD8gKJc+L27OQXTSOUAAAAAAAACAPwAAAAAAAAAAAACAPy9uK8EQWD5B9RClQAAAAAAAAIA/AAAAAAAAAAAAAIA/zTsswcGoMkE51qdAAAAAAAAAgD8AAAAAAAAAAAAAgD/JduLAhskyQdbFs0AAAAAAAACAPwAAAAAAAAAAAACAP/fkO8CP5L9BJJdZwAAAAAAAAIA/AAAAAAAAAAAAAIA/4lbJPtDVv0FgdlXAAAAAAAAAgD8AAAAAAAAAAAAAgD89YMY+RAulQeV+G8AAAAAAAACAPwAAAAAAAAAAAACAPxKgPsA3GqVB+KofwAAAAAAAAIA/AAAAAAAAAAAAAIA/DTdwQIX8pEHnGCDAAAAAAAAAgD8AAAAAAAAAAAAAgD/y0nFA7uuJQUvl3b8AAAAAAACAPwAAAAAAAAAAAACAP806wz7h+olB/prUvwAAAAAAAIA/AAAAAAAAAAAAAIA/fQVBwAkKikF5Bt2/AAAAAAAAgD8AAAAAAAAAAAAAgD+3C83A/BiKQXQk978AAAAAAACAPwAAAAAAAAAAAACAP2Xf5kALJF1BMXyovwAAAAAAAIA/AAAAAAAAAAAAAIA/Wg1zQFtCXUH1So2/AAAAAAAAgD8AAAAAAAAAAAAAgD8p678+qmBdQU7ug78AAAAAAACAPwAAAAAAAAAAAACAPxIUQ8CRfl1B12mMvwAAAAAAAIA/AAAAAAAAAAAAAIA/9+TOwOCcXUH1uaa/AAAAAAAAgD8AAAAAAAAAAAAAgD/27udAvjAmQQG+U78AAAAAAACAPwAAAAAAAAAAAACAP/Plc0AOTyZB4QkdvwAAAAAAAIA/AAAAAAAAAAAAAIA/xXW8PsZtJkEBNAq/AAAAAAAAgD8AAAAAAAAAAAAAgD8uykTAFYwmQSxEG78AAAAAAACAPwAAAAAAAAAAAACAP51j0MBlqiZB7DJQvwAAAAAAAIA/AAAAAAAAAAAAAIA/PujBQaW93EAm/GjAAAAAAAAAgD8AAAAAAAAAAAAAgD+ASNxBnYDcQM7flcAAAAAAAACAPwAAAAAAAAAAAACAP1vC3EFGX1tAUYOPwAAAAAAAAIA/AAAAAAAAAAAAAIA/t1HCQanZW0CPGVzAAAAAAAAAgD8AAAAAAAAAAAAAgD8/xipBbxImQZccl78AAAAAAACAPwAAAAAAAAAAAACAP3lYK0HEsd1AJCVVvwAAAAAAAIA/AAAAAAAAAAAAAIA/Ap/oQOHu3UCnk/S+AAAAAAAAgD8AAAAAAAAAAAAAgD/mXHRA6SveQAK3hr4AAAAAAACAPwAAAAAAAAAAAACAP3rfuD7xaN5AxcVBvgAAAAAAAIA/AAAAAAAAAAAAAIA//iZGwPil3kADJ4O+AAAAAAAAgD8AAAAAAAAAAAAAgD/shtHAAOPeQJJ07b4AAAAAAACAPwAAAAAAAAAAAACAP8kCH8G0yCZBp3SUvwAAAAAAAIA/AAAAAAAAAAAAAIA/xM4fwQgg30Acz0+/AAAAAAAAgD8AAAAAAAAAAAAAgD/jNqdBrfrcQFXeLsAAAAAAAACAPwAAAAAAAAAAAACAP5GPp0ENVFxANNchwAAAAAAAAIA/AAAAAAAAAAAAAIA//6GnQWF01Lxgkx3AAAAAAAAAgD8AAAAAAAAAAAAAgD9IP4xBtTfdQCL9+r8AAAAAAACAPwAAAAAAAAAAAACAPyuHjEFwzlxAn7DgvwAAAAAAAIA/AAAAAAAAAAAAAIA/oBpiQbx03UCo46m/AAAAAAAAgD8AAAAAAAAAAAAAgD/9h2JB1EhdQFpkj78AAAAAAACAPwAAAAAAAAAAAACAP26jK0E3w11Ax9YfvwAAAAAAAIA/AAAAAAAAAAAAAIA/ie/oQJs9XkA8hIm+AAAAAAAAgD8AAAAAAAAAAAAAgD+GcnRA/rdeQIQRW70AAAAAAACAPwAAAAAAAAAAAACAP+AstT5hMl9A/Z+oPAAAAAAAAIA/AAAAAAAAAAAAAIA/XylHwMWsX0AufT69AAAAAAAAgD8AAAAAAAAAAAAAgD/QYrE+6P2aPE3Etj0AAAAAAACAPwAAAAAAAAAAAACAP33QR8CWO9g8MAW1PAAAAAAAAIA/AAAAAAAAAAAAAIA/J07SwCgnYEBwYIK+AAAAAAAAgD8AAAAAAAAAAAAAgD+7uNLAorwKPU+tPr4AAAAAAACAPwAAAAAAAAAAAACAPzJVIMGMoWBAiX0avwAAAAAAAIA/AAAAAAAAAAAAAIA/6pUgwZRbKT0xCwm/AAAAAAAAgD8AAAAAAAAAAAAAgD9GlFbBEF3fQARWpr8AAAAAAACAPwAAAAAAAAAAAACAP3E9V8HvG2FAv9SLvwAAAAAAAIA/AAAAAAAAAAAAAIA/CYpXwWv6Rz23KIO/AAAAAAAAgD8AAAAAAAAAAAAAgD9dfobBF5rfQA2O9r8AAAAAAACAPwAAAAAAAAAAAACAP1rkhsFTlmFA5j/cvwAAAAAAAIA/AAAAAAAAAAAAAIA/LhCHwUKZZj2UpNO/AAAAAAAAgD8AAAAAAAAAAAAAgD9seKHBNNffQI82LMAAAAAAAACAPwAAAAAAAAAAAACAP57vocG2EGJAxy4fwAAAAAAAAIA/AAAAAAAAAAAAAIA/y5DWwURR4EAAHZTAAAAAAAAAgD8AAAAAAAAAAAAAgD8OLbzBPBTgQCHlZcAAAAAAAACAPwAAAAAAAAAAAACAPz+1vMEai2JADAJZwAAAAAAAAIA/AAAAAAAAAAAAAIA//CnXwX0FY0CtwI3AAAAAAAAAgD8AAAAAAAAAAAAAgD8tIaLBDJyCPZrrGsAAAAAAAACAPwAAAAAAAAAAAACAP4vsvMGF65E9KctUwAAAAAAAAIA/AAAAAAAAAAAAAIA/EpSMQbM2l7xNFdi/AAAAAAAAgD8AAAAAAAAAAAAAgD8yZoxBCylfwHMu4b8AAAAAAACAPwAAAAAAAAAAAACAP7yWYkEK8jO8UriGvwAAAAAAAIA/AAAAAAAAAAAAAIA/HqcrQQ/aZbsXZQ6/AAAAAAAAgD8AAAAAAAAAAAAAgD924OhA2wmCO0T3TL4AAAAAAACAPwAAAAAAAAAAAACAP9UmdEB0gDs8jaF3PAAAAAAAAIA/AAAAAAAAAAAAAIA/RUdiQaeuXsB+44+/AAAAAAAAgD8AAAAAAAAAAAAAgD+IYytBRDRewJ3XIL8AAAAAAACAPwAAAAAAAAAAAACAPwhy6EDguV3A7IiLvgAAAAAAAIA/AAAAAAAAAAAAAIA/mplhQXQk3sDv4aq/AAAAAAAAgD8AAAAAAAAAAAAAgD9/2SpBbefdwMAmV78AAAAAAACAPwAAAAAAAAAAAACAP76k50Blqt3AgJz4vgAAAAAAAIA/AAAAAAAAAAAAAIA/zHpzQH0/XcD0Qmu9AAAAAAAAgD8AAAAAAAAAAAAAgD/BbnJAXW3dwN/Cir4AAAAAAACAPwAAAAAAAAAAAACAPyKOYEFSSSbB1qjXvwAAAAAAAIA/AAAAAAAAAAAAAIA/mggqQZkqJsHxnZi/AAAAAAAAgD8AAAAAAAAAAAAAgD//eOZASgwmwT/EVr8AAAAAAACAPwAAAAAAAAAAAACAP9oDcUD67SXBBhIgvwAAAAAAAIA/AAAAAAAAAAAAAIA/9pupPlUw3cCL3km+AAAAAAAAgD8AAAAAAAAAAAAAgD/fqKU+q88lwUc8Db8AAAAAAACAPwAAAAAAAAAAAACAP3wKSMA489zAWTKHvgAAAAAAAIA/AAAAAAAAAAAAAIA/jZxHwFuxJcFFSx6/AAAAAAAAgD8AAAAAAAAAAAAAgD/FydHAo5Ilwfw3U78AAAAAAACAPwAAAAAAAAAAAACAP6K0H8FUdCXBAfaVvwAAAAAAAIA/AAAAAAAAAAAAAIA/RiVfQe84XcFFEgvAAAAAAAAAgD8AAAAAAAAAAAAAgD+q8ShBCRtdwQN4178AAAAAAACAPwAAAAAAAAAAAACAP57v5EC5/FzB9n+qvwAAAAAAAIA/AAAAAAAAAAAAAIA/vTpvQGreXMG1T4+/AAAAAAAAgD8AAAAAAAAAAAAAgD/7saE+GsBcwbvyhb8AAAAAAACAPwAAAAAAAAAAAACAP2PRRsA0olzBSG2OvwAAAAAAAIA/AAAAAAAAAAAAAIA/nL/QwOSDXMHDu6i/AAAAAAAAgD8AAAAAAAAAAAAAgD+Y3R7BlWVcwVvT1L8AAAAAAACAPwAAAAAAAAAAAACAP9lfXUFg5YnBkx0zwAAAAAAAAIA/AAAAAAAAAAAAAIA/GJUnQTnWicHvAxTAAAAAAAAAgD8AAAAAAAAAAAAAgD9sCeNARceJwVFm+78AAAAAAACAPwAAAAAAAAAAAACAP+QUbUBSuInBK2rgvwAAAAAAAIA/AAAAAAAAAAAAAIA/I7ydPl+picHiHte/AAAAAAAAgD8AAAAAAAAAAAAAgD9lx+BAm9WkwTP5LsAAAAAAAACAPwAAAAAAAAAAAACAP5+TakCoxqTB6ZohwAAAAAAAAIA/AAAAAAAAAAAAAIA/KqlFwGuaicG5iN+/AAAAAAAAgD8AAAAAAAAAAAAAgD95WM/ARIuJwRak+b8AAAAAAACAPwAAAAAAAAAAAACAPwskRMD2qKTBriohwAAAAAAAAIA/AAAAAAAAAAAAAIA/2ZTNwDeapME7GS7AAAAAAAAAgD8AAAAAAAAAAAAAgD/swB3BUHyJwT6zEsAAAAAAAACAPwAAAAAAAAAAAACAP4cWVcFFR1zBsVAJwAAAAAAAAIA/AAAAAAAAAAAAAIA/aJFTwV1ticFKXjHAAAAAAAAAgD8AAAAAAAAAAAAAgD8EZ4lBVPSJwU3zWsAAAAAAAACAPwAAAAAAAAAAAACAP/AWiEFBAqXBU66FwAAAAAAAAIA/AAAAAAAAAAAAAIA/FD9bQU3zpMF15WPAAAAAAAAAgD8AAAAAAAAAAAAAgD8f9CVBj+SkwTgVRcAAAAAAAACAPwAAAAAAAAAAAACAP1aOhkG6yb/BnS6iwAAAAAAAAIA/AAAAAAAAAAAAAIA/+MJYQfu6v8GPqo7AAAAAAAAAgD8AAAAAAAAAAAAAgD9WDiRBcay/wWLbfsAAAAAAAACAPwAAAAAAAAAAAACAPwdfHMFEi6TBVMZDwAAAAAAAAIA/AAAAAAAAAAAAAIA/XLgawSxUv8Eijn3AAAAAAAAAgD8AAAAAAAAAAAAAgD8hsFHBhXykwaIoYsAAAAAAAACAPwAAAAAAAAAAAACAP0eDhMFqXonBvcZYwAAAAAAAAIA/AAAAAAAAAAAAAIA/j1ODwZFtpMHEmYTAAAAAAAAAgD8AAAAAAAAAAAAAgD+Cc0/BokW/wWDNjcAAAAAAAACAPwAAAAAAAAAAAACAP7PqgcHjNr/BsBuhwAAAAAAAAIA/AAAAAAAAAAAAAIA/mEzJv/hTn8FKtRPAAAAAAAAAgD8AAAAAAAAAAAAAgD8+6GXBsq7fwa7Tv8AAAAAAAACAPwAAAAAAAAAAAACAPyGwg8GtaeLB5QrRwAAAAAAAAIA/AAAAAAAAAAAAAIA/RUeSwSEf2MGdnc/AAAAAAAAAgD8AAAAAAAAAAAAAgD+cM5bB6GrGwQ8LvMAAAAAAAACAPwAAAAAAAAAAAACAPwfOicGTuoXBlZpbwAAAAAAAAIA/AAAAAAAAAAAAAIA/SS52wSV1S8En2hXAAAAAAAAAgD8AAAAAAAAAAAAAgD9CPj/BMd8ewbhYsb8AAAAAAACAPwAAAAAAAAAAAACAP9PBNkCr7DHAC20MOwAAAAAAAIA/AAAAAAAAAAAAAIA/aHlkQE7R/b//S6A5AAAAAAAAgD8AAAAAAAAAAAAAgD/XwGBACwtqvwfTsDwAAAAAAACAPwAAAAAAAAAAAACAP/QaOUDmeI2+5GpEPQAAAAAAAIA/AAAAAAAAAAAAAIA/H9cAQJ7PEL4LcpE9AAAAAAAAgD8AAAAAAAAAAAAAgD8+eWjB/z5BwKhvob8AAAAAAACAPwAAAAAAAAAAAACAP9uKm8HbhTLAPUQRwAAAAAAAAIA/AAAAAAAAAAAAAIA/3hO+wcTP777lm1fAAAAAAAAAgD8AAAAAAAAAAAAAgD85xeXBzqp7QDS6osAAAAAAAACAPwAAAAAAAAAAAACAP1p17cEkYr9AzhmywAAAAAAAAIA/AAAAAAAAAAAAAIA/YcPnwYLiAkFS1a/AAAAAAAAAgD8AAAAAAAAAAAAAgD/u2tfBd/MTQVIKncAAAAAAAACAPwAAAAAAAAAAAACAP6pgN8FL6idBfA+vvwAAAAAAAIA/AAAAAAAAAAAAAIA/X/sewZHtMEEvwJ6/AAAAAAAAgD8AAAAAAAAAAAAAgD/Apg7BKVxFQQ1Upr8AAAAAAACAPwAAAAAAAAAAAACAPxeaK8Am5NZBPDGJwAAAAAAAAIA/AAAAAAAAAAAAAIA/G0yPv3RG40EhzZjAAAAAAAAAgD8AAAAAAAAAAAAAgD9HA4g/qEbjQfyMmMAAAAAAAACAPwAAAAAAAAAAAACAP0q1J0Am5NZBxJSIwAAAAAAAAIA/AAAAAAAAAAAAAIA/u1UNQSlcRUGFJZ6/AAAAAAAAgD8AAAAAAAAAAAAAgD/Gpx1Bke0wQSeglb8AAAAAAACAPwAAAAAAAAAAAACAP2IQNkFL6idBAYekvwAAAAAAAIA/AAAAAAAAAAAAAIA/NBHYQWTYE0EhsJfAAAAAAAAAgD8AAAAAAAAAAAAAgD+G2udB2yIDQbvyqcAAAAAAAACAPwAAAAAAAAAAAACAPxe37UF2GsBA9E+swAAAAAAAAIA/AAAAAAAAAAAAAIA/BSPmQU5FfEAbR53AAAAAAAAAgD8AAAAAAAAAAAAAgD8LJIdBm1rRwBDp578AAAAAAACAPwAAAAAAAAAAAACAP/mgf0Hi6fzAkGbgvwAAAAAAAIA/AAAAAAAAAAAAAIA/ih9+QVmXGMFyM/S/AAAAAAAAgD8AAAAAAAAAAAAAgD/pppZBkzrHweiHucAAAAAAAACAPwAAAAAAAAAAAACAP+O2kkHRotjBWtjMwAAAAAAAAIA/AAAAAAAAAAAAAIA/yyGEQcbt4sHrqM7AAAAAAAAAgD8AAAAAAAAAAAAAgD9qvGZB0DPgwarUvcAAAAAAAACAPwAAAAAAAAAAAACAP7Swvz/4U5/B6/8SwAAAAAAAAIA/AAAAAAAAAAAAAIA/bTYbvfvcm8Fr1AvAAAAAAAAAgD8AAAAAAAAAAAAAgD99s72/5wyhwcOBFMAAAAAAAACAPwAAAAAAAAAAAACAP5hMyb/4U5/BSrUTwAAAAAAAAIA/AAAAAAAAAAAAAIA/bTYbvfvcm8Fr1AvAAAAAAAAAgD8AAAAAAAAAAAAAgD/A7xq978mdwUUSDcAAAAAAAACAPwAAAAAAAAAAAACAP7Swvz/4U5/B6/8SwAAAAAAAAIA/AAAAAAAAAAAAAIA/ixq0P7MMocE01xPAAAAAAAAAgD8AAAAAAAAAAAAAgD+LGrQ/swyhwTTXE8AAAAAAAACAPwAAAAAAAAAAAACAP7Swvz/4U5/B6/8SwAAAAAAAAIA/AAAAAAAAAAAAAIA/arxmQdAz4MGq1L3AAAAAAAAAgD8AAAAAAAAAAAAAgD+LbGVBjvXhwReavsAAAAAAAACAPwAAAAAAAAAAAACAP4tsZUGO9eHBF5q+wAAAAAAAAIA/AAAAAAAAAAAAAIA/arxmQdAz4MGq1L3AAAAAAAAAgD8AAAAAAAAAAAAAgD/LIYRBxu3iweuozsAAAAAAAACAPwAAAAAAAAAAAACAP1B8hEG02eTBgXjQwAAAAAAAAIA/AAAAAAAAAAAAAIA/47aSQdGi2MFa2MzAAAAAAAAAgD8AAAAAAAAAAAAAgD8FRZRB47bZwV6AzsAAAAAAAACAPwAAAAAAAAAAAACAP+mmlkGTOsfB6Ie5wAAAAAAAAIA/AAAAAAAAAAAAAIA//XaYQUI+x8HF/rnAAAAAAAAAgD8AAAAAAAAAAAAAgD/9dphBQj7HwcX+ucAAAAAAAACAPwAAAAAAAAAAAACAP+mmlkGTOsfB6Ie5wAAAAAAAAIA/AAAAAAAAAAAAAIA/ih9+QVmXGMFyM/S/AAAAAAAAgD8AAAAAAAAAAAAAgD9X7IBBXksYwV2/9L8AAAAAAACAPwAAAAAAAAAAAACAP1fsgEFeSxjBXb/0vwAAAAAAAIA/AAAAAAAAAAAAAIA/ih9+QVmXGMFyM/S/AAAAAAAAgD8AAAAAAAAAAAAAgD/5oH9B4un8wJBm4L8AAAAAAACAPwAAAAAAAAAAAACAP5yigUEYYP/A0xPivwAAAAAAAIA/AAAAAAAAAAAAAIA/CySHQZta0cAQ6ee/AAAAAAAAgD8AAAAAAAAAAAAAgD/OiIhBjV3WwGow6b8AAAAAAACAPwAAAAAAAAAAAACAP86IiEGNXdbAajDpvwAAAAAAAIA/AAAAAAAAAAAAAIA/CySHQZta0cAQ6ee/AAAAAAAAgD8AAAAAAAAAAAAAgD8FI+ZBTkV8QBtHncAAAAAAAACAPwAAAAAAAAAAAACAPwWj50FVGHNA4POdwAAAAAAAAIA/AAAAAAAAAAAAAIA/BaPnQVUYc0Dg853AAAAAAAAAgD8AAAAAAAAAAAAAgD8FI+ZBTkV8QBtHncAAAAAAAACAPwAAAAAAAAAAAACAPxe37UF2GsBA9E+swAAAAAAAAIA/AAAAAAAAAAAAAIA/Q63vQUOQv0B87a3AAAAAAAAAgD8AAAAAAAAAAAAAgD+G2udB2yIDQbvyqcAAAAAAAACAPwAAAAAAAAAAAACAP49T6UE9xAVB0VyrwAAAAAAAAIA/AAAAAAAAAAAAAIA/NBHYQWTYE0EhsJfAAAAAAAAAgD8AAAAAAAAAAAAAgD91k9hBBH8XQf32l8AAAAAAAACAPwAAAAAAAAAAAACAP3WT2EEEfxdB/faXwAAAAAAAAIA/AAAAAAAAAAAAAIA/NBHYQWTYE0EhsJfAAAAAAAAAgD8AAAAAAAAAAAAAgD9iEDZBS+onQQGHpL8AAAAAAACAPwAAAAAAAAAAAACAP8bcNkHqlStBCkukvwAAAAAAAIA/AAAAAAAAAAAAAIA/xtw2QeqVK0EKS6S/AAAAAAAAgD8AAAAAAAAAAAAAgD9iEDZBS+onQQGHpL8AAAAAAACAPwAAAAAAAAAAAACAP8anHUGR7TBBJ6CVvwAAAAAAAIA/AAAAAAAAAAAAAIA/FeMfQZ0RNEHSOpa/AAAAAAAAgD8AAAAAAAAAAAAAgD+7VQ1BKVxFQYUlnr8AAAAAAACAPwAAAAAAAAAAAACAP6uEEEFqTUdBOEqevwAAAAAAAIA/AAAAAAAAAAAAAIA/q4QQQWpNR0E4Sp6/AAAAAAAAgD8AAAAAAAAAAAAAgD+7VQ1BKVxFQYUlnr8AAAAAAACAPwAAAAAAAAAAAACAP0q1J0Am5NZBxJSIwAAAAAAAAIA/AAAAAAAAAAAAAIA/xoUzQKH410Fa9YjAAAAAAAAAgD8AAAAAAAAAAAAAgD/GhTNAofjXQVr1iMAAAAAAAACAPwAAAAAAAAAAAACAP0q1J0Am5NZBxJSIwAAAAAAAAIA/AAAAAAAAAAAAAIA/RwOIP6hG40H8jJjAAAAAAAAAgD8AAAAAAAAAAAAAgD/OcJM/cRvlQeXtmcAAAAAAAACAPwAAAAAAAAAAAACAPxtMj790RuNBIc2YwAAAAAAAAIA/AAAAAAAAAAAAAIA/Ja+avz0b5UFIM5rAAAAAAAAAgD8AAAAAAAAAAAAAgD8XmivAJuTWQTwxicAAAAAAAACAPwAAAAAAAAAAAACAP/FoN8DV+NdBy5yJwAAAAAAAAIA/AAAAAAAAAAAAAIA/8Wg3wNX410HLnInAAAAAAAAAgD8AAAAAAAAAAAAAgD8XmivAJuTWQTwxicAAAAAAAACAPwAAAAAAAAAAAACAP8CmDsEpXEVBDVSmvwAAAAAAAIA/AAAAAAAAAAAAAIA/ptURwWpNR0Hwp6a/AAAAAAAAgD8AAAAAAAAAAAAAgD+m1RHBak1HQfCnpr8AAAAAAACAPwAAAAAAAAAAAACAP8CmDsEpXEVBDVSmvwAAAAAAAIA/AAAAAAAAAAAAAIA/X/sewZHtMEEvwJ6/AAAAAAAAgD8AAAAAAAAAAAAAgD96NiHBnRE0QfJ7n78AAAAAAACAPwAAAAAAAAAAAACAP6pgN8FL6idBfA+vvwAAAAAAAIA/AAAAAAAAAAAAAIA/Di04weqVK0FQ366/AAAAAAAAgD8AAAAAAAAAAAAAgD8OLTjB6pUrQVDfrr8AAAAAAACAPwAAAAAAAAAAAACAP6pgN8FL6idBfA+vvwAAAAAAAIA/AAAAAAAAAAAAAIA/7trXwXfzE0FSCp3AAAAAAAAAgD8AAAAAAAAAAAAAgD9qXtjB45kXQQRWncAAAAAAAACAPwAAAAAAAAAAAACAP2pe2MHjmRdBBFadwAAAAAAAAIA/AAAAAAAAAAAAAIA/7trXwXfzE0FSCp3AAAAAAAAAgD8AAAAAAAAAAAAAgD9hw+fBguICQVLVr8AAAAAAAACAPwAAAAAAAAAAAACAP3c+6cHlfgVB3EuxwAAAAAAAAIA/AAAAAAAAAAAAAIA/WnXtwSRiv0DOGbLAAAAAAAAAgD8AAAAAAAAAAAAAgD9/au/BnMS+QL7Bs8AAAAAAAACAPwAAAAAAAAAAAACAPznF5cHOqntANLqiwAAAAAAAAIA/AAAAAAAAAAAAAIA/xELnwXNjckANbKPAAAAAAAAAgD8AAAAAAAAAAAAAgD/EQufBc2NyQA1so8AAAAAAAACAPwAAAAAAAAAAAACAPznF5cHOqntANLqiwAAAAAAAAIA/AAAAAAAAAAAAAIA/3hO+wcTP777lm1fAAAAAAAAAgD8AAAAAAAAAAAAAgD90JL/BhC4pvwnEV8AAAAAAAACAPwAAAAAAAAAAAACAP3Qkv8GELim/CcRXwAAAAAAAAIA/AAAAAAAAAAAAAIA/3hO+wcTP777lm1fAAAAAAAAAgD8AAAAAAAAAAAAAgD/bipvB24UywD1EEcAAAAAAAACAPwAAAAAAAAAAAACAPzoSnMFPI0HAJGIQwAAAAAAAAIA/AAAAAAAAAAAAAIA/Pnlowf8+QcCob6G/AAAAAAAAgD8AAAAAAAAAAAAAgD+9UmjBnBZQwFeVnb8AAAAAAACAPwAAAAAAAAAAAACAP71SaMGcFlDAV5WdvwAAAAAAAIA/AAAAAAAAAAAAAIA/Pnlowf8+QcCob6G/AAAAAAAAgD8AAAAAAAAAAAAAgD8f1wBAns8QvgtykT0AAAAAAACAPwAAAAAAAAAAAACAP/IHAUA2rr++hbDaPQAAAAAAAIA/AAAAAAAAAAAAAIA/8gcBQDauv76FsNo9AAAAAAAAgD8AAAAAAAAAAAAAgD8f1wBAns8QvgtykT0AAAAAAACAPwAAAAAAAAAAAACAP/QaOUDmeI2+5GpEPQAAAAAAAIA/AAAAAAAAAAAAAIA/MBIyQL3g+75l47E9AAAAAAAAgD8AAAAAAAAAAAAAgD/XwGBACwtqvwfTsDwAAAAAAACAPwAAAAAAAAAAAACAP3B3UkCOr4G/YNeFPQAAAAAAAIA/AAAAAAAAAAAAAIA/aHlkQE7R/b//S6A5AAAAAAAAgD8AAAAAAAAAAAAAgD/Fj1VAY2LzvxRuQz0AAAAAAACAPwAAAAAAAAAAAACAP9PBNkCr7DHAC20MOwAAAAAAAIA/AAAAAAAAAAAAAIA/MNgtQO8DJsAS3Eg9AAAAAAAAgD8AAAAAAAAAAAAAgD8w2C1A7wMmwBLcSD0AAAAAAACAPwAAAAAAAAAAAACAP9PBNkCr7DHAC20MOwAAAAAAAIA/AAAAAAAAAAAAAIA/Qj4/wTHfHsG4WLG/AAAAAAAAgD8AAAAAAAAAAAAAgD9qTUHBVNIbwUAYrL8AAAAAAACAPwAAAAAAAAAAAACAP2pNQcFU0hvBQBisvwAAAAAAAIA/AAAAAAAAAAAAAIA/Qj4/wTHfHsG4WLG/AAAAAAAAgD8AAAAAAAAAAAAAgD9JLnbBJXVLwSfaFcAAAAAAAACAPwAAAAAAAAAAAACAP+wvecHsL0nBO1MUwAAAAAAAAIA/AAAAAAAAAAAAAIA/B86JwZO6hcGVmlvAAAAAAAAAgD8AAAAAAAAAAAAAgD+EjYvBtSaFwXY3W8AAAAAAAACAPwAAAAAAAAAAAACAP4SNi8G1JoXBdjdbwAAAAAAAAIA/AAAAAAAAAAAAAIA/B86JwZO6hcGVmlvAAAAAAAAAgD8AAAAAAAAAAAAAgD+cM5bB6GrGwQ8LvMAAAAAAAACAPwAAAAAAAAAAAACAP+QDmMFLasbB04e8wAAAAAAAAIA/AAAAAAAAAAAAAIA/5AOYwUtqxsHTh7zAAAAAAAAAgD8AAAAAAAAAAAAAgD+cM5bB6GrGwQ8LvMAAAAAAAACAPwAAAAAAAAAAAACAP0VHksEhH9jBnZ3PwAAAAAAAAIA/AAAAAAAAAAAAAIA/OdaTwWEy2cFRTtHAAAAAAAAAgD8AAAAAAAAAAAAAgD8hsIPBrWniweUK0cAAAAAAAACAPwAAAAAAAAAAAACAPwkKhMGbVeTBDtvSwAAAAAAAAIA/AAAAAAAAAAAAAIA/PuhlwbKu38Gu07/AAAAAAAAAgD8AAAAAAAAAAAAAgD+Nl2TBb3DhwZ+TwMAAAAAAAACAPwAAAAAAAAAAAACAP42XZMFvcOHBn5PAwAAAAAAAAIA/AAAAAAAAAAAAAIA/PuhlwbKu38Gu07/AAAAAAAAAgD8AAAAAAAAAAAAAgD+YTMm/+FOfwUq1E8AAAAAAAACAPwAAAAAAAAAAAACAP32zvb/nDKHBw4EUwAAAAAAAAIA/AAAAAAAAAAAAAIA/wkyzv7/9r8HcEVZAAAAAAAAAgD8AAAAAAAAAAAAAgD9Pr3HBIOP0waipIb8AAAAAAACAPwAAAAAAAAAAAACAPyDScMEPi/TBTTFbvwAAAAAAAIA/AAAAAAAAAAAAAIA/2smwv1TSr8FKJEdAAAAAAAAAgD8AAAAAAAAAAAAAgD9Pr3HBIOP0waipIb8AAAAAAACAPwAAAAAAAAAAAACAP3IKjsGuWPjBCHKovwAAAAAAAIA/AAAAAAAAAAAAAIA/JLmNwVMF+MHQs8W/AAAAAAAAgD8AAAAAAAAAAAAAgD8g0nDBD4v0wU0xW78AAAAAAACAPwAAAAAAAAAAAACAPwmbocGXkOrBgLegvwAAAAAAAIA/AAAAAAAAAAAAAIA/2HChwf8h6sHm6L2/AAAAAAAAgD8AAAAAAAAAAAAAgD96pabByBjUwVDC9L4AAAAAAACAPwAAAAAAAAAAAACAP0eDpsGmitPBdqczvwAAAAAAAIA/AAAAAAAAAAAAAIA/eqWmwcgY1MFQwvS+AAAAAAAAgD8AAAAAAAAAAAAAgD99LpnBLhCNwdUhDUAAAAAAAACAPwAAAAAAAAAAAACAP28SmcGTmIzBvjD9PwAAAAAAAIA/AAAAAAAAAAAAAIA/R4OmwaaK08F2pzO/AAAAAAAAgD8AAAAAAAAAAAAAgD99LpnBLhCNwdUhDUAAAAAAAACAPwAAAAAAAAAAAACAP0ymiMGzDFLBBW5bQAAAAAAAAIA/AAAAAAAAAAAAAIA/poqIwRUdUcFy4UxAAAAAAAAAgD8AAAAAAAAAAAAAgD9vEpnBk5iMwb4w/T8AAAAAAACAPwAAAAAAAAAAAACAP8l2U8Gg1B/BXDiQQAAAAAAAAIA/AAAAAAAAAAAAAIA/5j9TwdjkHsHl8ohAAAAAAAAAgD8AAAAAAAAAAAAAgD/JdlPBoNQfwVw4kEAAAAAAAACAPwAAAAAAAAAAAACAP1bUJEAlQBfAx0vAQAAAAAAAAIA/AAAAAAAAAAAAAIA/4e4iQCzUFMA57rhAAAAAAAAAgD8AAAAAAAAAAAAAgD/mP1PB2OQeweXyiEAAAAAAAACAPwAAAAAAAAAAAACAP1bUJEAlQBfAx0vAQAAAAAAAAIA/AAAAAAAAAAAAAIA/b/BBQPCF7b8wR8BAAAAAAAAAgD8AAAAAAAAAAAAAgD/L8z5APx3rvyHquEAAAAAAAACAPwAAAAAAAAAAAACAP+HuIkAs1BTAOe64QAAAAAAAAIA/AAAAAAAAAAAAAIA/jgZAQNFcp7/on8BAAAAAAAAAgD8AAAAAAAAAAAAAgD9sJj1Atwupv5s9uUAAAAAAAACAPwAAAAAAAAAAAACAPxaHLUAPRYG/GQTBQAAAAAAAAIA/AAAAAAAAAAAAAIA/Uu0rQFuUhb/UmrlAAAAAAAAAgD8AAAAAAAAAAAAAgD8fLglA+zpsv8x6wUAAAAAAAACAPwAAAAAAAAAAAACAP7TlCEAAqXW/Gw26QAAAAAAAAIA/AAAAAAAAAAAAAIA/Hy4JQPs6bL/MesFAAAAAAAAAgD8AAAAAAAAAAAAAgD+4QHjB/7J/wBVSk0AAAAAAAACAPwAAAAAAAAAAAACAP2iRd8EJxIDAavuLQAAAAAAAAIA/AAAAAAAAAAAAAIA/tOUIQACpdb8bDbpAAAAAAAAAgD8AAAAAAAAAAAAAgD+4QHjB/7J/wBVSk0AAAAAAAACAPwAAAAAAAAAAAACAP74fqMF2N2/ANzdeQAAAAAAAAIA/AAAAAAAAAAAAAIA/0MSnwa4NccAmjU9AAAAAAAAAgD8AAAAAAAAAAAAAgD9okXfBCcSAwGr7i0AAAAAAAACAPwAAAAAAAAAAAACAP5jMzsHFyZG/iJ0PQAAAAAAAAIA/AAAAAAAAAAAAAIA/AG/Owc6Nlb8B+wBAAAAAAAAAgD8AAAAAAAAAAAAAgD+YzM7BxcmRv4idD0AAAAAAAACAPwAAAAAAAAAAAACAP+2e+sFsIW5APzaxPgAAAAAAAIA/AAAAAAAAAAAAAIA/ejb6wQ7za0AN/fM9AAAAAAAAgD8AAAAAAAAAAAAAgD8Ab87Bzo2VvwH7AEAAAAAAAACAPwAAAAAAAAAAAACAP+2e+sFsIW5APzaxPgAAAAAAAIA/AAAAAAAAAAAAAIA/ITACwsRfykCXcIi+AAAAAAAAgD8AAAAAAAAAAAAAgD+qAgLCSL/JQEt0/r4AAAAAAACAPwAAAAAAAAAAAACAP3o2+sEO82tADf3zPQAAAAAAAIA/AAAAAAAAAAAAAIA/Hbj8wZ1oFEE+5y6+AAAAAAAAgD8AAAAAAAAAAAAAgD+fTfzBPHcUQbIQzb4AAAAAAACAPwAAAAAAAAAAAACAP/2H6MGdESpBasETPwAAAAAAAIA/AAAAAAAAAAAAAIA/OwHowas+KkFqErQ+AAAAAAAAgD8AAAAAAAAAAAAAgD/9h+jBnREqQWrBEz8AAAAAAACAPwAAAAAAAAAAAACAP23nRsE+eT9B/KmMQAAAAAAAAIA/AAAAAAAAAAAAAIA/2IFGwciYP0EWMIVAAAAAAAAAgD8AAAAAAAAAAAAAgD87AejBqz4qQWoStD4AAAAAAACAPwAAAAAAAAAAAACAP23nRsE+eT9B/KmMQAAAAAAAAIA/AAAAAAAAAAAAAIA/24oxwWRdR0FwQpBAAAAAAAAAgD8AAAAAAAAAAAAAgD/ecTHBqmBHQRe8iEAAAAAAAACAPwAAAAAAAAAAAACAP9iBRsHImD9BFjCFQAAAAAAAAIA/AAAAAAAAAAAAAIA/WDkjwfJBWUHNko5AAAAAAAAAgD8AAAAAAAAAAAAAgD8mUyPBUwVZQQYSh0AAAAAAAACAPwAAAAAAAAAAAACAP1g5I8HyQVlBzZKOQAAAAAAAAIA/AAAAAAAAAAAAAIA/4WJfwJAx6UEvF50/AAAAAAAAgD8AAAAAAAAAAAAAgD+DwGDABcXoQaHbfz8AAAAAAACAPwAAAAAAAAAAAACAPyZTI8FTBVlBBhKHQAAAAAAAAIA/AAAAAAAAAAAAAIA/4WJfwJAx6UEvF50/AAAAAAAAgD8AAAAAAAAAAAAAgD/g28C/YOX4QTPeGj8AAAAAAACAPwAAAAAAAAAAAACAP1ovwr+KjvhBxEC/PgAAAAAAAIA/AAAAAAAAAAAAAIA/g8BgwAXF6EGh238/AAAAAAAAgD8AAAAAAAAAAAAAgD9FnrQ/leX4QRmMHT8AAAAAAACAPwAAAAAAAAAAAACAPyQotj+/jvhBDafEPgAAAAAAAIA/AAAAAAAAAAAAAIA/I/NYQJAx6UHUQ6A/AAAAAAAAgD8AAAAAAAAAAAAAgD+la1pA0MToQd4fgz8AAAAAAACAPwAAAAAAAAAAAACAPyPzWECQMelB1EOgPwAAAAAAAIA/AAAAAAAAAAAAAIA/Qj4hQfJBWUEl6ZBAAAAAAAAAgD8AAAAAAAAAAAAAgD8HXyFBUwVZQdxoiUAAAAAAAACAPwAAAAAAAAAAAACAP6VrWkDQxOhB3h+DPwAAAAAAAIA/AAAAAAAAAAAAAIA/Qj4hQfJBWUEl6ZBAAAAAAAAAgD8AAAAAAAAAAAAAgD+5jS9BZF1HQcjNkkAAAAAAAACAPwAAAAAAAAAAAACAP0p7L0GqYEdBBkeLQAAAAAAAAIA/AAAAAAAAAAAAAIA/B18hQVMFWUHcaIlAAAAAAAAAgD8AAAAAAAAAAAAAgD/A7ERBPnk/QSOEj0AAAAAAAACAPwAAAAAAAAAAAACAP4qOREHImD9B2QiIQAAAAAAAAIA/AAAAAAAAAAAAAIA/wOxEQT55P0EjhI9AAAAAAAAAgD8AAAAAAAAAAAAAgD8ldehBWvUpQfcDQj8AAAAAAACAPwAAAAAAAAAAAACAPw3x50FoIipBYTMIPwAAAAAAAIA/AAAAAAAAAAAAAIA/io5EQciYP0HZCIhAAAAAAAAAgD8AAAAAAAAAAAAAgD8ldehBWvUpQfcDQj8AAAAAAACAPwAAAAAAAAAAAACAPzSA/EHZvRRBS9P7PAAAAAAAAIA/AAAAAAAAAAAAAIA/Xxj8QRbNFEGeBky+AAAAAAAAgD8AAAAAAAAAAAAAgD8N8edBaCIqQWEzCD8AAAAAAACAPwAAAAAAAAAAAACAPyEwAkJvZMtAljqNvQAAAAAAAIA/AAAAAAAAAAAAAIA/MwQCQpPGykCeeZm+AAAAAAAAgD8AAAAAAAAAAAAAgD+PwvpBPx1vQCi5Bz8AAAAAAACAPwAAAAAAAAAAAACAPy9d+kHQ8mxACwqbPgAAAAAAAIA/AAAAAAAAAAAAAIA/j8L6QT8db0AouQc/AAAAAAAAgD8AAAAAAAAAAAAAgD/f4JRBOGfwwKSIeEAAAAAAAACAPwAAAAAAAAAAAACAP/u6lEEwnvDAL4tpQAAAAAAAAIA/AAAAAAAAAAAAAIA/L136QdDybEALCps+AAAAAAAAgD8AAAAAAAAAAAAAgD/f4JRBOGfwwKSIeEAAAAAAAACAPwAAAAAAAAAAAACAP1R0jkFgSAvBguJ7QAAAAAAAAIA/AAAAAAAAAAAAAIA/YGWOQegfC8G+2WxAAAAAAAAAgD8AAAAAAAAAAAAAgD/7upRBMJ7wwC+LaUAAAAAAAACAPwAAAAAAAAAAAACAP+nIjUGDLyLBLCtzQAAAAAAAAIA/AAAAAAAAAAAAAIA/AryNQXS1IcELQWRAAAAAAAAAgD8AAAAAAAAAAAAAgD/pyI1Bgy8iwSwrc0AAAAAAAACAPwAAAAAAAAAAAACAPwTWpkEfBdXBHZTIvgAAAAAAAIA/AAAAAAAAAAAAAIA/RramQf121MELlx2/AAAAAAAAgD8AAAAAAAAAAAAAgD8CvI1BdLUhwQtBZEAAAAAAAACAPwAAAAAAAAAAAACAPwTWpkEfBdXBHZTIvgAAAAAAAIA/AAAAAAAAAAAAAIA/P8ahQfMf68EebZS/AAAAAAAAgD8AAAAAAAAAAAAAgD+EnqFBJ7Hqwc+gsb8AAAAAAACAPwAAAAAAAAAAAACAP0a2pkH9dtTBC5cdvwAAAAAAAIA/AAAAAAAAAAAAAIA/nzyOQZXl+MF5O56/AAAAAAAAgD8AAAAAAAAAAAAAgD8v7o1B0ZH4wc+Du78AAAAAAACAPwAAAAAAAAAAAACAP6MBckFBcfXBEykRvwAAAAAAAIA/AAAAAAAAAAAAAIA/xylxQfwY9cEzw0q/AAAAAAAAgD8AAAAAAAAAAAAAgD+jAXJBQXH1wRMpEb8AAAAAAACAPwAAAAAAAAAAAACAPzp6pD+//a/BdbBWQAAAAAAAAIA/AAAAAAAAAAAAAIA/Ci6iP1TSr8GYwEdAAAAAAAAAgD8AAAAAAAAAAAAAgD/HKXFB/Bj1wTPDSr8AAAAAAACAPwAAAAAAAAAAAACAPzp6pD+//a/BdbBWQAAAAAAAAIA/AAAAAAAAAAAAAIA/jHBuvcP1rMF5Bl1AAAAAAAAAgD8AAAAAAAAAAAAAgD9l+mq9MtWswdIATkAAAAAAAACAPwAAAAAAAAAAAACAPwouoj9U0q/BmMBHQAAAAAAAAIA/AAAAAAAAAAAAAIA/wkyzv7/9r8HcEVZAAAAAAAAAgD8AAAAAAAAAAAAAgD/aybC/VNKvwUokR0AAAAAAAACAPwAAAAAAAAAAAACAPzOKub9Nla/Bc51kQAAAAAAAAIA/AAAAAAAAAAAAAIA/E/JywTSi9MEDRNG+AAAAAAAAgD8AAAAAAAAAAAAAgD8T8nLBNKL0wQNE0b4AAAAAAACAPwAAAAAAAAAAAACAP5M6jsEfBfjBoguKvwAAAAAAAIA/AAAAAAAAAAAAAIA/fT+hwe2e6sFui4K/AAAAAAAAgD8AAAAAAAAAAAAAgD89LKbBxaDUwWiWhL4AAAAAAACAPwAAAAAAAAAAAACAPz0spsHFoNTBaJaEvgAAAAAAAIA/AAAAAAAAAAAAAIA/17SYwZyzjcEl6RpAAAAAAAAAgD8AAAAAAAAAAAAAgD/XtJjBnLONwSXpGkAAAAAAAACAPwAAAAAAAAAAAACAPyBBiMGWslPBx9doQAAAAAAAAIA/AAAAAAAAAAAAAIA/UPxSwdO8IcGlvZZAAAAAAAAAgD8AAAAAAAAAAAAAgD9Q/FLB07whwaW9lkAAAAAAAACAPwAAAAAAAAAAAACAP3CZKUAjhB3AMNjGQAAAAAAAAIA/AAAAAAAAAAAAAIA/cJkpQCOEHcAw2MZAAAAAAAAAgD8AAAAAAAAAAAAAgD8jvklAKEnzv0rSxkAAAAAAAACAPwAAAAAAAAAAAACAP6WDR0AmjaG/wTnHQAAAAAAAAIA/AAAAAAAAAAAAAIA/MGQxQDP8Z7+vscdAAAAAAAAAgD8AAAAAAAAAAAAAgD8LYwlAxm5Pv+w0yEAAAAAAAACAPwAAAAAAAAAAAACAPwtjCUDGbk+/7DTIQAAAAAAAAIA/AAAAAAAAAAAAAIA/WvV4wU8GecBoBZpAAAAAAAAAgD8AAAAAAAAAAAAAgD9a9XjBTwZ5wGgFmkAAAAAAAACAPwAAAAAAAAAAAACAP+9JqMHLnGjAtvNrQAAAAAAAAIA/AAAAAAAAAAAAAIA/ksvOwRkEhr/Oqh1AAAAAAAAAgD8AAAAAAAAAAAAAgD+Sy87BGQSGv86qHUAAAAAAAACAPwAAAAAAAAAAAACAP4GE+sH1SnNAIAoSPwAAAAAAAIA/AAAAAAAAAAAAAIA/gYT6wfVKc0AgChI/AAAAAAAAgD8AAAAAAAAAAAAAgD9mCALCOC3LQDSY67wAAAAAAACAPwAAAAAAAAAAAACAPyeg/MHjfBNBBGODPQAAAAAAAIA/AAAAAAAAAAAAAIA/ZN3owYqwKEGcwUs/AAAAAAAAgD8AAAAAAAAAAAAAgD9k3ejBirAoQZzBSz8AAAAAAACAPwAAAAAAAAAAAACAP4EER8E6Iz5BzcyTQAAAAAAAAIA/AAAAAAAAAAAAAIA/gQRHwTojPkHNzJNAAAAAAAAAgD8AAAAAAAAAAAAAgD/J5TDBDk9GQQqFl0AAAAAAAACAPwAAAAAAAAAAAACAP9cSIsGh1lhBEceVQAAAAAAAAIA/AAAAAAAAAAAAAIA/1xIiwaHWWEERx5VAAAAAAAAAgD8AAAAAAAAAAAAAgD9nLFrApT3pQYKLuT8AAAAAAACAPwAAAAAAAAAAAACAP2csWsClPelBgou5PwAAAAAAAIA/AAAAAAAAAAAAAIA/v9S7v+Cc+EFfRFc/AAAAAAAAgD8AAAAAAAAAAAAAgD9wX68/FZ34QWXfWT8AAAAAAACAPwAAAAAAAAAAAACAP0miU0ClPelB06S8PwAAAAAAAIA/AAAAAAAAAAAAAIA/SaJTQKU96UHTpLw/AAAAAAAAgD8AAAAAAAAAAAAAgD80ESBBOdZYQSYZmEAAAAAAAACAPwAAAAAAAAAAAACAPzQRIEE51lhBJhmYQAAAAAAAAIA/AAAAAAAAAAAAAIA/seEuQQ5PRkHtDZpAAAAAAAAAgD8AAAAAAAAAAAAAgD9HA0VBOiM+QV2nlkAAAAAAAACAPwAAAAAAAAAAAACAP0cDRUE6Iz5BXaeWQAAAAAAAAIA/AAAAAAAAAAAAAIA/S8joQUaUKEGmDno/AAAAAAAAgD8AAAAAAAAAAAAAgD9LyOhBRpQoQaYOej8AAAAAAACAPwAAAAAAAAAAAACAP5tm/EHfzxNBlumHPgAAAAAAAIA/AAAAAAAAAAAAAIA/3AYCQgspzEBYrSw+AAAAAAAAgD8AAAAAAAAAAAAAgD8LpPpBfjp0QFEyQT8AAAAAAACAPwAAAAAAAAAAAACAPwuk+kF+OnRAUTJBPwAAAAAAAIA/AAAAAAAAAAAAAIA/v46UQfiI7sAFi4NAAAAAAAAAgD8AAAAAAAAAAAAAgD+/jpRB+IjuwAWLg0AAAAAAAACAPwAAAAAAAAAAAACAPz7ojUF5BgvB4UWFQAAAAAAAAIA/AAAAAAAAAAAAAIA/FzeNQTy9IsGLw4BAAAAAAAAAgD8AAAAAAAAAAAAAgD8XN41BPL0iwYvDgEAAAAAAAACAPwAAAAAAAAAAAACAP4ZapkF4i9XBofUwvgAAAAAAAIA/AAAAAAAAAAAAAIA/hlqmQXiL1cGh9TC+AAAAAAAAgD8AAAAAAAAAAAAAgD9zaKFBFC7rwXCUbL8AAAAAAACAPwAAAAAAAAAAAACAP+JpjkFvkvjBmZ9/vwAAAAAAAIA/AAAAAAAAAAAAAIA/qz5zQb4w9cFcArC+AAAAAAAAgD8AAAAAAAAAAAAAgD+rPnNBvjD1wVwCsL4AAAAAAACAPwAAAAAAAAAAAACAP+2Bqj9Nla/BnkFlQAAAAAAAAIA/AAAAAAAAAAAAAIA/7YGqP02Vr8GeQWVAAAAAAAAAgD8AAAAAAAAAAAAAgD/P13G9dnGswS3Pa0AAAAAAAACAPwAAAAAAAAAAAACAPzOKub9Nla/Bc51kQAAAAAAAAIA/AAAAAAAAAAAAAIA/yOrCv/+hrsHmV3FAAAAAAAAAgD8AAAAAAAAAAAAAgD9Ke3TB083zwebnVr4AAAAAAACAPwAAAAAAAAAAAACAP0p7dMHTzfPB5udWvgAAAAAAAIA/AAAAAAAAAAAAAIA/nESOwToS98Ee/lq/AAAAAAAAgD8AAAAAAAAAAAAAgD8yZqDBKUvqwQK5TL8AAAAAAACAPwAAAAAAAAAAAACAP5wipcFNFdXBRHCHvQAAAAAAAIA/AAAAAAAAAAAAAIA/nCKlwU0V1cFEcIe9AAAAAAAAgD8AAAAAAAAAAAAAgD++sJfB5XKOwdGRJkAAAAAAAACAPwAAAAAAAAAAAACAP76wl8Hlco7B0ZEmQAAAAAAAAIA/AAAAAAAAAAAAAIA/JmSHwTLmVcHBynNAAAAAAAAAgD8AAAAAAAAAAAAAgD/121HBAG8kwUTdm0AAAAAAAACAPwAAAAAAAAAAAACAP/XbUcEAbyTBRN2bQAAAAAAAAIA/AAAAAAAAAAAAAIA/LsowQJ4HJ8Ap7ctAAAAAAAAAgD8AAAAAAAAAAAAAgD8uyjBAngcnwCnty0AAAAAAAACAPwAAAAAAAAAAAACAP66eVUCl2vu/9+TLQAAAAAAAAIA/AAAAAAAAAAAAAIA/LudSQPEpmL9eY8xAAAAAAAAAgD8AAAAAAAAAAAAAgD9CJjdAXAQ+vwX6zEAAAAAAAACAPwAAAAAAAAAAAACAP41/CUCT/yG/wZDNQAAAAAAAAIA/AAAAAAAAAAAAAIA/jX8JQJP/Ib/BkM1AAAAAAAAAgD8AAAAAAAAAAAAAgD9JnXnBZCNuwKVrn0AAAAAAAACAPwAAAAAAAAAAAACAP0mdecFkI27ApWufQAAAAAAAAIA/AAAAAAAAAAAAAIA/qz6owZjdXcDPZndAAAAAAAAAgD8AAAAAAAAAAAAAgD/ua87BzLNmv5y/KUAAAAAAAACAPwAAAAAAAAAAAACAP+5rzsHMs2a/nL8pQAAAAAAAAIA/AAAAAAAAAAAAAIA/p+j5wf7xekDqIkU/AAAAAAAAgD8AAAAAAAAAAAAAgD+n6PnB/vF6QOoiRT8AAAAAAACAPwAAAAAAAAAAAACAPyiPAcLoE8xApWhFPgAAAAAAAIA/AAAAAAAAAAAAAIA/lAf8wSPKEUFq+48+AAAAAAAAgD8AAAAAAAAAAAAAgD/V+OjBnzwmQTSDfD8AAAAAAACAPwAAAAAAAAAAAACAP9X46MGfPCZBNIN8PwAAAAAAAIA/AAAAAAAAAAAAAIA/OdZGwRe3O0E75JlAAAAAAAAAgD8AAAAAAAAAAAAAgD851kbBF7c7QTvkmUAAAAAAAACAPwAAAAAAAAAAAACAP2iRL8HfT0RBOsydQAAAAAAAAIA/AAAAAAAAAAAAAIA/mPofwTbNV0Hf+JtAAAAAAAAAgD8AAAAAAAAAAAAAgD+Y+h/BNs1XQd/4m0AAAAAAAACAPwAAAAAAAAAAAACAP3CZUcBt5+hBB3zSPwAAAAAAAIA/AAAAAAAAAAAAAIA/cJlRwG3n6EEHfNI/AAAAAAAAgD8AAAAAAAAAAAAAgD8/kbO/mbv3QX5vhz8AAAAAAACAPwAAAAAAAAAAAACAPynopj/Nu/dBrK2IPwAAAAAAAIA/AAAAAAAAAAAAAIA/YvhKQDjn6EGOddU/AAAAAAAAgD8AAAAAAAAAAAAAgD9i+EpAOOfoQY511T8AAAAAAACAPwAAAAAAAAAAAACAP1jzHUE2zVdBLUOeQAAAAAAAAIA/AAAAAAAAAAAAAIA/WPMdQTbNV0EtQ55AAAAAAAAAgD8AAAAAAAAAAAAAgD+Uhy1B309EQR5QoEAAAAAAAACAPwAAAAAAAAAAAACAP6vPREEXtztBDr6cQAAAAAAAAIA/AAAAAAAAAAAAAIA/q89EQRe3O0EOvpxAAAAAAAAAgD8AAAAAAAAAAAAAgD8Z4uhB8x8mQdRllT8AAAAAAACAPwAAAAAAAAAAAACAPxni6EHzHyZB1GWVPwAAAAAAAIA/AAAAAAAAAAAAAIA/as37QXoZEkG9q/Y+AAAAAAAAgD8AAAAAAAAAAAAAgD8VjAFCUAHNQPZ6xz4AAAAAAACAPwAAAAAAAAAAAACAPxkE+kGzzXtAqkV0PwAAAAAAAIA/AAAAAAAAAAAAAIA/GQT6QbPNe0CqRXQ/AAAAAAAAgD8AAAAAAAAAAAAAgD8wzJNBajDrwMbhiUAAAAAAAACAPwAAAAAAAAAAAACAPzDMk0FqMOvAxuGJQAAAAAAAAIA/AAAAAAAAAAAAAIA/082MQSJgCsGasYtAAAAAAAAAgD8AAAAAAAAAAAAAgD9GFIxBsVAjwdz0hkAAAAAAAACAPwAAAAAAAAAAAACAP0YUjEGxUCPB3PSGQAAAAAAAAIA/AAAAAAAAAAAAAIA/Dk+lQe781cHk6KA8AAAAAAAAgD8AAAAAAAAAAAAAgD8OT6VB7vzVweTooDwAAAAAAACAPwAAAAAAAAAAAACAP7mNoEEd2urBs140vwAAAAAAAIA/AAAAAAAAAAAAAIA/QXGOQfOf98Egfka/AAAAAAAAgD8AAAAAAAAAAAAAgD9hw3RBxlz0weW4E74AAAAAAACAPwAAAAAAAAAAAACAP2HDdEHGXPTB5bgTvgAAAAAAAIA/AAAAAAAAAAAAAIA/p7OzP/+hrsGWBHJAAAAAAAAAgD8AAAAAAAAAAAAAgD+ns7M//6GuwZYEckAAAAAAAACAPwAAAAAAAAAAAACAPzLadL1hVKvBYOV4QAAAAAAAAIA/AAAAAAAAAAAAAIA/yOrCv/+hrsHmV3FAAAAAAAAAgD8AAAAAAAAAAAAAgD+Ihc6/AjytwSL9ekAAAAAAAACAPwAAAAAAAAAAAACAP90kdsF4evLBYhdgvQAAAAAAAIA/AAAAAAAAAAAAAIA/3SR2wXh68sFiF2C9AAAAAAAAgD8AAAAAAAAAAAAAgD8eJ47BjZf1wYVDK78AAAAAAACAPwAAAAAAAAAAAACAP0Akn8F+nenBZ+4dvwAAAAAAAIA/AAAAAAAAAAAAAIA/nKKjwehq1cFsbqY9AAAAAAAAgD8AAAAAAAAAAAAAgD+coqPB6GrVwWxupj0AAAAAAACAPwAAAAAAAAAAAACAP5k7lsFkO4/BfPIuQAAAAAAAAIA/AAAAAAAAAAAAAIA/mTuWwWQ7j8F88i5AAAAAAAAAgD8AAAAAAAAAAAAAgD9GJYbBO3BYwRsve0AAAAAAAACAPwAAAAAAAAAAAACAP5AxUMEepyfBPBSfQAAAAAAAAIA/AAAAAAAAAAAAAIA/kDFQwR6nJ8E8FJ9AAAAAAAAAgD8AAAAAAAAAAAAAgD+vsTlACtwywMQIz0AAAAAAAACAPwAAAAAAAAAAAACAP6+xOUAK3DLAxAjPQAAAAAAAAIA/AAAAAAAAAAAAAIA/CmhkQOQxA8AN/c5AAAAAAAAAgD8AAAAAAAAAAAAAgD/oE2FAJh6Mv3SYz0AAAAAAAACAPwAAAAAAAAAAAACAP0c9PkDsvQi/71XQQAAAAAAAAIA/AAAAAAAAAAAAAIA/XoAJQF2/0L59BdFAAAAAAAAAgD8AAAAAAAAAAAAAgD9egAlAXb/Qvn0F0UAAAAAAAACAPwAAAAAAAAAAAACAP7snesEJG2DA7PqiQAAAAAAAAIA/AAAAAAAAAAAAAIA/uyd6wQkbYMDs+qJAAAAAAAAAgD8AAAAAAAAAAAAAgD8u/6fBNQdQwGFsf0AAAAAAAACAPwAAAAAAAAAAAACAP3q2zcG8Pje/l6gyQAAAAAAAAIA/AAAAAAAAAAAAAIA/erbNwbw+N7+XqDJAAAAAAAAAgD8AAAAAAAAAAAAAgD/u2vjBQSuCQCDRbD8AAAAAAACAPwAAAAAAAAAAAACAP+7a+MFBK4JAINFsPwAAAAAAAIA/AAAAAAAAAAAAAIA/FNAAwiL9zEBHksA+AAAAAAAAgD8AAAAAAAAAAAAAgD8i/frB13oPQeLo6j4AAAAAAACAPwAAAAAAAAAAAACAPz/X6MFN8yJBvJaQPwAAAAAAAIA/AAAAAAAAAAAAAIA/P9fowU3zIkG8lpA/AAAAAAAAgD8AAAAAAAAAAAAAgD+qYEbBDXE4QQhVnkAAAAAAAACAPwAAAAAAAAAAAACAP6pgRsENcThBCFWeQAAAAAAAAIA/AAAAAAAAAAAAAIA/5q4twQCRQUEYeKJAAAAAAAAAgD8AAAAAAAAAAAAAgD88JR3B5j9WQYeKoEAAAAAAAACAPwAAAAAAAAAAAACAPzwlHcHmP1ZBh4qgQAAAAAAAAIA/AAAAAAAAAAAAAIA/on9GwEw36EFZbuU/AAAAAAAAgD8AAAAAAAAAAAAAgD+if0bATDfoQVlu5T8AAAAAAACAPwAAAAAAAAAAAACAP4PdqL8/V/ZB0xOePwAAAAAAAIA/AAAAAAAAAAAAAIA/fAqcP3NX9kEDPp8/AAAAAAAAgD8AAAAAAAAAAAAAgD8MzT9AFzfoQZY+6D8AAAAAAACAPwAAAAAAAAAAAACAPwzNP0AXN+hBlj7oPwAAAAAAAIA/AAAAAAAAAAAAAIA/xBkbQeY/VkFYyqJAAAAAAAAAgD8AAAAAAAAAAAAAgD/EGRtB5j9WQVjKokAAAAAAAACAPwAAAAAAAAAAAACAP/mgK0GXkEFBBvWkQAAAAAAAAIA/AAAAAAAAAAAAAIA/BFZEQQ1xOEEjLaFAAAAAAAAAgD8AAAAAAAAAAAAAgD8EVkRBDXE4QSMtoUAAAAAAAACAPwAAAAAAAAAAAACAP7G/6EGh1iJBW7GnPwAAAAAAAIA/AAAAAAAAAAAAAIA/sb/oQaHWIkFbsac/AAAAAAAAgD8AAAAAAAAAAAAAgD8tw/pBbcUPQbaAKD8AAAAAAACAPwAAAAAAAAAAAACAP6zLAEIw2M1Acm8SPwAAAAAAAIA/AAAAAAAAAAAAAIA/E/L4QZOMgkDI740/AAAAAAAAgD8AAAAAAAAAAAAAgD8T8vhBk4yCQMjvjT8AAAAAAACAPwAAAAAAAAAAAACAPwiskkFGsebASKeOQAAAAAAAAIA/AAAAAAAAAAAAAIA/CKySQUax5sBIp45AAAAAAAAAgD8AAAAAAAAAAAAAgD+4QItBtGUJwdaQkEAAAAAAAACAPwAAAAAAAAAAAACAP7l8ikH12yPB1ouLQAAAAAAAAIA/AAAAAAAAAAAAAIA/uXyKQfXbI8HWi4tAAAAAAAAAgD8AAAAAAAAAAAAAgD+fzaNBpU7WwaN3Kj4AAAAAAACAPwAAAAAAAAAAAACAP5/No0GlTtbBo3cqPgAAAAAAAIA/AAAAAAAAAAAAAIA/9UqfQdQr6sHEzQW/AAAAAAAAgD8AAAAAAAAAAAAAgD+DUY5BryX2wVW/Fr8AAAAAAACAPwAAAAAAAAAAAACAP9xodkHVCfPBc+g+PAAAAAAAAIA/AAAAAAAAAAAAAIA/3Gh2QdUJ88Fz6D48AAAAAAAAgD8AAAAAAAAAAAAAgD+uKr8/AjytwXi0e0AAAAAAAACAPwAAAAAAAAAAAACAP64qvz8CPK3BeLR7QAAAAAAAAIA/AAAAAAAAAAAAAIA/Dyt3vV66qcH+fYFAAAAAAAAAgD8AAAAAAAAAAAAAgD+Ihc6/AjytwSL9ekAAAAAAAACAPwAAAAAAAAAAAACAP4M027+OhqvBCkuAQAAAAAAAAIA/AAAAAAAAAAAAAIA/M8R3wSPK8MFQ4Sg9AAAAAAAAgD8AAAAAAAAAAAAAgD8zxHfBI8rwwVDhKD0AAAAAAACAPwAAAAAAAAAAAACAP/fkjcGTuvPBhq0JvwAAAAAAAIA/AAAAAAAAAAAAAIA/MZmdwR6n6MHnyPq+AAAAAAAAgD8AAAAAAAAAAAAAgD8g0qHB/JjVwduHLD4AAAAAAACAPwAAAAAAAAAAAACAPyDSocH8mNXB24csPgAAAAAAAIA/AAAAAAAAAAAAAIA/eHqUwT75j8GDNDNAAAAAAAAAgD8AAAAAAAAAAAAAgD94epTBPvmPwYM0M0AAAAAAAACAPwAAAAAAAAAAAACAP0CkhMFiEFvBRUd+QAAAAAAAAIA/AAAAAAAAAAAAAIA/UidOwUATK8EOEKBAAAAAAAAAgD8AAAAAAAAAAAAAgD9SJ07BQBMrwQ4QoEAAAAAAAACAPwAAAAAAAAAAAACAP4dtQ0Br1D/ADtvPQAAAAAAAAIA/AAAAAAAAAAAAAIA/h21DQGvUP8AO289AAAAAAAAAgD8AAAAAAAAAAAAAgD/goXRAGOwIwOrKz0AAAAAAAACAPwAAAAAAAAAAAACAP7qgcEDeOH2/g4bQQAAAAAAAAIA/AAAAAAAAAAAAAIA/iPRFQCXpmr4Ab9FAAAAAAAAAgD8AAAAAAAAAAAAAgD+qZQlAICYhvlQ60kAAAAAAAACAPwAAAAAAAAAAAACAP6plCUAgJiG+VDrSQAAAAAAAAIA/AAAAAAAAAAAAAIA/lId6wRVSUMD7V6RAAAAAAAAAgD8AAAAAAAAAAAAAgD+Uh3rBFVJQwPtXpEAAAAAAAACAPwAAAAAAAAAAAACAP52Rp8E+eUDAZ5uBQAAAAAAAAIA/AAAAAAAAAAAAAIA/PL3MwXBgAr8wgTdAAAAAAAAAgD8AAAAAAAAAAAAAgD88vczBcGACvzCBN0AAAAAAAACAPwAAAAAAAAAAAACAP/d198HlRIdAYY6CPwAAAAAAAIA/AAAAAAAAAAAAAIA/93X3weVEh0BhjoI/AAAAAAAAgD8AAAAAAAAAAAAAgD82vP/B9tHNQMu9AD8AAAAAAACAPwAAAAAAAAAAAACAP9Sa+cHPyQxBOUQUPwAAAAAAAIA/AAAAAAAAAAAAAIA/s3vowQ8oH0E9Cps/AAAAAAAAgD8AAAAAAAAAAAAAgD+ze+jBDygfQT0Kmz8AAAAAAACAPwAAAAAAAAAAAACAP7ivRcGppDRBgq2gQAAAAAAAAIA/AAAAAAAAAAAAAIA/uK9FwamkNEGCraBAAAAAAAAAgD8AAAAAAAAAAAAAgD8vbivBEFg+QfUQpUAAAAAAAACAPwAAAAAAAAAAAACAP4baGcEEVlRB9wajQAAAAAAAAIA/AAAAAAAAAAAAAIA/htoZwQRWVEH3BqNAAAAAAAAAgD8AAAAAAAAAAAAAgD/P9znAqz7nQSx98D8AAAAAAACAPwAAAAAAAAAAAACAP8/3OcCrPudBLH3wPwAAAAAAAIA/AAAAAAAAAAAAAIA/O8ecvwyT9EFNSq0/AAAAAAAAgD8AAAAAAAAAAAAAgD+y148/QJP0QTVerj8AAAAAAACAPwAAAAAAAAAAAACAPxA7M0CrPudB4h7zPwAAAAAAAIA/AAAAAAAAAAAAAIA/EDszQKs+50HiHvM/AAAAAAAAgD8AAAAAAAAAAAAAgD/CzBdBBFZUQZM6pUAAAAAAAACAPwAAAAAAAAAAAACAP8LMF0EEVlRBkzqlQAAAAAAAAIA/AAAAAAAAAAAAAIA/ZF0pQRBYPkGIhadAAAAAAAAAgD8AAAAAAAAAAAAAgD+cokNBqaQ0QRKDo0AAAAAAAACAPwAAAAAAAAAAAACAP5yiQ0GppDRBEoOjQAAAAAAAAIA/AAAAAAAAAAAAAIA/j2ToQfAKH0F3FbI/AAAAAAAAgD8AAAAAAAAAAAAAgD+PZOhB8AofQXcVsj8AAAAAAACAPwAAAAAAAAAAAACAP05i+UETDw1BjfBGPwAAAAAAAIA/AAAAAAAAAAAAAIA/W7H/QUqYzkC8lDI/AAAAAAAAgD8AAAAAAAAAAAAAgD83ifdBC5iHQMAEmj8AAAAAAACAPwAAAAAAAAAAAACAPzeJ90ELmIdAwASaPwAAAAAAAIA/AAAAAAAAAAAAAIA/9UqRQf594cB8YZFAAAAAAAAAgD8AAAAAAAAAAAAAgD/1SpFB/n3hwHxhkUAAAAAAAACAPwAAAAAAAAAAAACAPwpoiUEMMAjBz2aTQAAAAAAAAIA/AAAAAAAAAAAAAIA/yJiIQRpRJMHsEo5AAAAAAAAAgD8AAAAAAAAAAAAAgD/ImIhBGlEkwewSjkAAAAAAAACAPwAAAAAAAAAAAACAP7n8oUFseNbBpYeBPgAAAAAAAIA/AAAAAAAAAAAAAIA/ufyhQWx41sGlh4E+AAAAAAAAgD8AAAAAAAAAAAAAgD/mv51B1zTpwbISy74AAAAAAACAPwAAAAAAAAAAAACAP7kNjkG0SPTBzlLqvgAAAAAAAIA/AAAAAAAAAAAAAIA/vAV4QX9Z8cEX8d09AAAAAAAAgD8AAAAAAAAAAAAAgD+8BXhBf1nxwRfx3T0AAAAAAACAPwAAAAAAAAAAAACAP7HEyz+OhqvBm6yAQAAAAAAAAIA/AAAAAAAAAAAAAIA/scTLP46Gq8GbrIBAAAAAAAAAgD8AAAAAAAAAAAAAgD8Nj3i9x8unwWaIhEAAAAAAAACAPwAAAAAAAAAAAACAP4M027+OhqvBCkuAQAAAAAAAAIA/AAAAAAAAAAAAAIA/DvhQwNBElMFioZNAAAAAAAAAgD8AAAAAAAAAAAAAgD+DNNu/joarwQpLgEAAAAAAAACAPwAAAAAAAAAAAACAPw2PeL3Hy6fBZoiEQAAAAAAAAIA/AAAAAAAAAAAAAIA/8uvHPqI0lMFg5ZVAAAAAAAAAgD8AAAAAAAAAAAAAgD/OGSXBoVbOwYeiDkAAAAAAAACAPwAAAAAAAAAAAACAPzPEd8EjyvDBUOEoPQAAAAAAAIA/AAAAAAAAAAAAAIA//mBOwL1jscHGFnJAAAAAAAAAgD8AAAAAAAAAAAAAgD/c113Bm2bOwRiV3D8AAAAAAACAPwAAAAAAAAAAAACAPzGZncEep+jB58j6vgAAAAAAAIA/AAAAAAAAAAAAAIA/9+SNwZO688GGrQm/AAAAAAAAgD8AAAAAAAAAAAAAgD/UGovBYHbOwdl3iT8AAAAAAACAPwAAAAAAAAAAAACAPyDSocH8mNXB24csPgAAAAAAAIA/AAAAAAAAAAAAAIA/PL2MwaOjscGsHAJAAAAAAAAAgD8AAAAAAAAAAAAAgD94epTBPvmPwYM0M0AAAAAAAACAPwAAAAAAAAAAAACAP6MjjsFThZTBcT02QAAAAAAAAIA/AAAAAAAAAAAAAIA/QKSEwWIQW8FFR35AAAAAAAAAgD8AAAAAAAAAAAAAgD+comTBGy9uwQTihUAAAAAAAACAPwAAAAAAAAAAAACAP1InTsFAEyvBDhCgQAAAAAAAAIA/AAAAAAAAAAAAAIA/GsBiwVp1lMGgpmBAAAAAAAAAgD8AAAAAAAAAAAAAgD/SbyvBke0ywcZtp0AAAAAAAACAPwAAAAAAAAAAAACAP7KFVsCFfO7Ao6/GQAAAAAAAAIA/AAAAAAAAAAAAAIA/h21DQGvUP8AO289AAAAAAAAAgD8AAAAAAAAAAAAAgD8XSCrBvw5uwSeDlkAAAAAAAACAPwAAAAAAAAAAAACAP1IP+kBL6mzAVmXGQAAAAAAAAIA/AAAAAAAAAAAAAIA/4KF0QBjsCMDqys9AAAAAAAAAgD8AAAAAAAAAAAAAgD//54JABW5twLPNzUAAAAAAAACAPwAAAAAAAAAAAACAP/nagkAz+e3AcXLGQAAAAAAAAIA/AAAAAAAAAAAAAIA/AMm8PtI67sDK/chAAAAAAAAAgD8AAAAAAAAAAAAAgD+6oHBA3jh9v4OG0EAAAAAAAACAPwAAAAAAAAAAAACAP/cB+kBdKgA9fuPIQAAAAAAAAIA/AAAAAAAAAAAAAIA/iPRFQCXpmr4Ab9FAAAAAAAAAgD8AAAAAAAAAAAAAgD/XwIJA1Wq+PH9N0EAAAAAAAACAPwAAAAAAAAAAAACAP6plCUAgJiG+VDrSQAAAAAAAAIA/AAAAAAAAAAAAAIA/+5OwPkvlb0DUfdBAAAAAAAAAgD8AAAAAAAAAAAAAgD9eu7Q+3wF5PA7b0kAAAAAAAACAPwAAAAAAAAAAAACAP0cgBECJLK08AybSQAAAAAAAAIA/AAAAAAAAAAAAAIA/k2/jwA1aaro1XslAAAAAAAAAgD8AAAAAAAAAAAAAgD+Uh3rBFVJQwPtXpEAAAAAAAACAPwAAAAAAAAAAAACAP1xVWMA/XOo78IrQQAAAAAAAAIA/AAAAAAAAAAAAAIA/JCgtwV95Erz7V71AAAAAAAAAgD8AAAAAAAAAAAAAgD9qTWjBpSaLvEF9rEAAAAAAAACAPwAAAAAAAAAAAACAP/eGkcGKEM28KNWWQAAAAAAAAIA/AAAAAAAAAAAAAIA/nZGnwT55QMBnm4FAAAAAAAAAgD8AAAAAAAAAAAAAgD9jf8vBD3Iovf2HOkAAAAAAAACAPwAAAAAAAAAAAACAPzy9zMFwYAK/MIE3QAAAAAAAAIA/AAAAAAAAAAAAAIA/waiuwTd9B70L0nhAAAAAAAAAgD8AAAAAAAAAAAAAgD/Z3+fBesdrQK7T3D8AAAAAAACAPwAAAAAAAAAAAACAP/d198HlRIdAYY6CPwAAAAAAAIA/AAAAAAAAAAAAAIA/Nrz/wfbRzUDLvQA/AAAAAAAAgD8AAAAAAAAAAAAAgD9kXefBICntQLVswT8AAAAAAACAPwAAAAAAAAAAAACAP7N76MEPKB9BPQqbPwAAAAAAAIA/AAAAAAAAAAAAAIA/1Jr5wc/JDEE5RBQ/AAAAAAAAgD8AAAAAAAAAAAAAgD8OLZHBOe7tQBFwjUAAAAAAAACAPwAAAAAAAAAAAACAP7ivRcGppDRBgq2gQAAAAAAAAIA/AAAAAAAAAAAAAIA/rjauwYas7UByM2ZAAAAAAAAAgD8AAAAAAAAAAAAAgD+O9crB02rtQNYcKEAAAAAAAACAPwAAAAAAAAAAAACAP+/JZ8HsL+5AJQajQAAAAAAAAIA/AAAAAAAAAAAAAIA/0NUswZ9x7kDd0rNAAAAAAAAAgD8AAAAAAAAAAAAAgD+G2hnBBFZUQfcGo0AAAAAAAACAPwAAAAAAAAAAAACAP6gA0cAKV5RBZkmNQAAAAAAAAIA/AAAAAAAAAAAAAIA/z/c5wKs+50EsffA/AAAAAAAAgD8AAAAAAAAAAAAAgD8tW+HAY+5tQS3sokAAAAAAAACAPwAAAAAAAAAAAACAPzvHnL8Mk/RBTUqtPwAAAAAAAIA/AAAAAAAAAAAAAIA/xm1SwGpezkHhYjVAAAAAAAAAgD8AAAAAAAAAAAAAgD/wM3hA9H3OQfLqNEAAAAAAAACAPwAAAAAAAAAAAACAP2RdKUEQWD5BiIWnQAAAAAAAAIA/AAAAAAAAAAAAAIA/Z0R7QFiosUH2QHNAAAAAAAAAgD8AAAAAAAAAAAAAgD+utjZBXW0zQckfp0AAAAAAAACAPwAAAAAAAAAAAACAP5yiQ0GppDRBEoOjQAAAAAAAAIA/AAAAAAAAAAAAAIA/woaWQTl/8ECjQIxAAAAAAAAAgD8AAAAAAAAAAAAAgD9+jLNB7MDwQEpeY0AAAAAAAACAPwAAAAAAAAAAAACAP49k6EHwCh9BdxWyPwAAAAAAAIA/AAAAAAAAAAAAAIA/TYRyQYY98ECZEqJAAAAAAAAAgD8AAAAAAAAAAAAAgD8YlTdB0vvvQLAbs0AAAAAAAACAPwAAAAAAAAAAAACAP6hG0EGfAvFAs9IkQAAAAAAAAIA/AAAAAAAAAAAAAIA/KqnsQVJE8UC78rk/AAAAAAAAgD8AAAAAAAAAAAAAgD9OYvlBEw8NQY3wRj8AAAAAAACAPwAAAAAAAAAAAACAP1ux/0FKmM5AvJQyPwAAAAAAAIA/AAAAAAAAAAAAAIA/2U7tQfMCdEDfT9U/AAAAAAAAgD8AAAAAAAAAAAAAgD83ifdBC5iHQMAEmj8AAAAAAACAPwAAAAAAAAAAAACAP2FDtEET/4E9I/h1QAAAAAAAAIA/AAAAAAAAAAAAAIA/9UqRQf594cB8YZFAAAAAAAAAgD8AAAAAAAAAAAAAgD9NFZdBRl9rwOgwk0AAAAAAAACAPwAAAAAAAAAAAACAP7ADc0EaNO3A98yhQAAAAAAAAIA/AAAAAAAAAAAAAIA/CmiJQQwwCMHPZpNAAAAAAAAAgD8AAAAAAAAAAAAAgD8cfHNB1uJrwLYQqUAAAAAAAACAPwAAAAAAAAAAAACAP0YlckGaCDLBmMCVQAAAAAAAAIA/AAAAAAAAAAAAAIA/yJiIQRpRJMHsEo5AAAAAAAAAgD8AAAAAAAAAAAAAgD+eXpRB8eOTwRToM0AAAAAAAACAPwAAAAAAAAAAAACAP7n8oUFseNbBpYeBPgAAAAAAAIA/AAAAAAAAAAAAAIA/yJiIQRpRJMHsEo5AAAAAAAAAgD8AAAAAAAAAAAAAgD9YOW9BH/STwYrIXkAAAAAAAACAPwAAAAAAAAAAAACAP55elEHx45PBFOgzQAAAAAAAAIA/AAAAAAAAAAAAAIA/seFwQQIrbcGZ8IRAAAAAAAAAgD8AAAAAAAAAAAAAgD8VjJFBRdjNweHuhD8AAAAAAACAPwAAAAAAAAAAAACAP3TGj0H+VOrBuXCAvQAAAAAAAIA/AAAAAAAAAAAAAIA/5r+dQdc06cGyEsu+AAAAAAAAgD8AAAAAAAAAAAAAgD+5/KFBbHjWwaWHgT4AAAAAAACAPwAAAAAAAAAAAACAP0YUk0HkA7HBXp3/PwAAAAAAAIA/AAAAAAAAAAAAAIA/uQ2OQbRI9MHOUuq+AAAAAAAAgD8AAAAAAAAAAAAAgD956WdBj2TqwYzWFT8AAAAAAACAPwAAAAAAAAAAAACAP7wFeEF/WfHBF/HdPQAAAAAAAIA/AAAAAAAAAAAAAIA/r5mAQMpDscHPoHFAAAAAAAAAgD8AAAAAAAAAAAAAgD+xxMs/joarwZusgEAAAAAAAACAPwAAAAAAAAAAAACAP9V4gUCpJJTBlWWTQAAAAAAAAIA/AAAAAAAAAAAAAIA/3nFUwGaIsUFjuXNAAAAAAAAAgD8AAAAAAAAAAAAAgD+bWZs+X5ixQec1eEAAAAAAAACAPwAAAAAAAAAAAACAP9wRVsA4Z5RBM1CUQAAAAAAAAIA/AAAAAAAAAAAAAIA/fZafPmZ3lEHzk5ZAAAAAAAAAgD8AAAAAAAAAAAAAgD8K9H1AlIeUQakTlEAAAAAAAACAPwAAAAAAAAAAAACAP+hNV8C/Dm5BvQCqQAAAAAAAAIA/AAAAAAAAAAAAAIA/iNmjPhsvbkHpSKxAAAAAAAAAgD8AAAAAAAAAAAAAgD+GIIBA309uQd/DqUAAAAAAAACAPwAAAAAAAAAAAACAP68lWMBL6jJB9+S6QAAAAAAAAIA/AAAAAAAAAAAAAIA/wR2oPg8LM0GpML1AAAAAAAAAgD8AAAAAAAAAAAAAgD/5FIFA1CszQfCnukAAAAAAAACAPwAAAAAAAAAAAACAPx8u48BTs+5ALc+/QAAAAAAAAIA/AAAAAAAAAAAAAIA/W5lYwAb17kDY9cZAAAAAAAAAgD8AAAAAAAAAAAAAgD+nXaw+uTbvQP5DyUAAAAAAAACAPwAAAAAAAAAAAACAP+DWgUBseO9AprjGQAAAAAAAAIA/AAAAAAAAAAAAAIA/5bP4QB+670DKVL9AAAAAAAAAgD8AAAAAAAAAAAAAgD/dJC3BHVpuQC7/ukAAAAAAAACAPwAAAAAAAAAAAACAP/GA48DX3W5A8wLHQAAAAAAAAIA/AAAAAAAAAAAAAIA/2T1owWLWbUDQJ6pAAAAAAAAAgD8AAAAAAAAAAAAAgD8VqVjAkWFvQDQuzkAAAAAAAACAPwAAAAAAAAAAAACAP6plgkDcaHBA2PDNQAAAAAAAAIA/AAAAAAAAAAAAAIA/DY75QJbscEBRiMZAAAAAAAAAgD8AAAAAAAAAAAAAgD+7JzhBUHBxQIRHukAAAAAAAACAPwAAAAAAAAAAAACAPzY8c0EK9HFAhzOpQAAAAAAAAIA/AAAAAAAAAAAAAIA//mXLwTRLbEAN/TVAAAAAAAAAgD8AAAAAAAAAAAAAgD9Nla7B7s5sQKg6dEAAAAAAAACAPwAAAAAAAAAAAACAP3J5kcGoUm1AI4SUQAAAAAAAAIA/AAAAAAAAAAAAAIA/L244QU8fIT0noLxAAAAAAAAAgD8AAAAAAAAAAAAAgD/zjnNBQhRCPZCIq0AAAAAAAACAPwAAAAAAAAAAAACAP471lkHEd3JAuVOTQAAAAAAAAIA/AAAAAAAAAAAAAIA/EiWXQTQJYz0WpJVAAAAAAAAAgD8AAAAAAAAAAAAAgD+5DbRBf/tyQI1icUAAAAAAAACAPwAAAAAAAAAAAACAPx3a0EE5f3NAJa8yQAAAAAAAAIA/AAAAAAAAAAAAAIA/Cmg4QZBmbMCJJLpAAAAAAAAAgD8AAAAAAAAAAAAAgD/ItflAgLftwNQOv0AAAAAAAACAPwAAAAAAAAAAAACAP00VOEHNde3A5dWyQAAAAAAAAIA/AAAAAAAAAAAAAIA/hZmCQH9qMsHqPrpAAAAAAAAAgD8AAAAAAAAAAAAAgD9v9fhAI0oywSrjskAAAAAAAACAPwAAAAAAAAAAAACAP3+kwD5EizLBZce8QAAAAAAAAIA/AAAAAAAAAAAAAIA/93U3QV8pMsFWt6ZAAAAAAAAAgD8AAAAAAAAAAAAAgD+3C1XACKwywch7ukAAAAAAAACAPwAAAAAAAAAAAACAP3rk4MDNzDLB5lyzQAAAAAAAAIA/AAAAAAAAAAAAAIA/PDFTwJ/NbcGSdKlAAAAAAAAAgD8AAAAAAAAAAAAAgD+aXMQ+Q61twei8q0AAAAAAAACAPwAAAAAAAAAAAACAP+FF38D67W3BV2CiQAAAAAAAAIA/AAAAAAAAAAAAAIA/eSOCQH6MbcEyOKlAAAAAAAAAgD8AAAAAAAAAAAAAgD9GzvdAImxtwYLnoUAAAAAAAACAPwAAAAAAAAAAAACAPwmKNkFeS23B8s2VQAAAAAAAAIA/AAAAAAAAAAAAAIA/odYowSxllMFW1IBAAAAAAAAAgD8AAAAAAAAAAAAAgD+3Rd3A/lSUwb+ajEAAAAAAAACAPwAAAAAAAAAAAACAP45A9kB7FJTBJSOMQAAAAAAAAIA/AAAAAAAAAAAAAIA/VFI1QU0ElMEEIYBAAAAAAAAAgD8AAAAAAAAAAAAAgD8cfGDBqZOxwWwhLEAAAAAAAACAPwAAAAAAAAAAAACAP0McJ8Gwg7HBUtVMQAAAAAAAAIA/AAAAAAAAAAAAAIA/NuXawLZzscFvKmRAAAAAAAAAgD8AAAAAAAAAAAAAgD/CTPRA0DOxwas+Y0AAAAAAAACAPwAAAAAAAAAAAACAP3DOM0HXI7HBbXNLQAAAAAAAAIA/AAAAAAAAAAAAAIA/pSxtQd4TscGQSSpAAAAAAAAAgD8AAAAAAAAAAAAAgD+X/zFBz/fNwbJGDUAAAAAAAACAPwAAAAAAAAAAAACAP2q8akEK6M3Bx/TYPwAAAAAAAIA/AAAAAAAAAAAAAIA/tvNiwRQu5sErMLbAAAAAAAAAgD8AAAAAAAAAAAAAgD9hjqa/rWmlwe1H+r8AAAAAAACAPwAAAAAAAAAAAACAP21nhcGYbunBesfKwAAAAAAAAIA/AAAAAAAAAAAAAIA/tvNiwRQu5sErMLbAAAAAAAAAgD8AAAAAAAAAAAAAgD/7y5fB23ncwX/2yMAAAAAAAACAPwAAAAAAAAAAAACAPzeJnMHuWsfBeZKxwAAAAAAAAIA/AAAAAAAAAAAAAIA/quCPwd6ThMEgtUHAAAAAAAAAgD8AAAAAAAAAAAAAgD83iZzB7lrHwXmSscAAAAAAAACAPwAAAAAAAAAAAACAPwRWgMGVZUXBGjTwvwAAAAAAAIA/AAAAAAAAAAAAAIA/quCPwd6ThMEgtUHAAAAAAAAAgD8AAAAAAAAAAAAAgD/bikbBITAWwTLoXL8AAAAAAACAPwAAAAAAAAAAAACAP+DzG0B87Q3AYacMPwAAAAAAAIA/AAAAAAAAAAAAAIA/24pGwSEwFsEy6Fy/AAAAAAAAgD8AAAAAAAAAAAAAgD+DUTdAbcXev+iEDD8AAAAAAACAPwAAAAAAAAAAAACAP+DzG0B87Q3AYacMPwAAAAAAAIA/AAAAAAAAAAAAAIA/9YQ1QGjQnL/eHw8/AAAAAAAAgD8AAAAAAAAAAAAAgD8YISRAAAJyv6kREj8AAAAAAACAPwAAAAAAAAAAAACAP671AUA5CV2/VI4VPwAAAAAAAIA/AAAAAAAAAAAAAIA/XCBpwSYecMC3lkW/AAAAAAAAgD8AAAAAAAAAAAAAgD+u9QFAOQldv1SOFT8AAAAAAACAPwAAAAAAAAAAAACAP8DsncFBn2DAPPfqvwAAAAAAAIA/AAAAAAAAAAAAAIA/XCBpwSYecMC3lkW/AAAAAAAAgD8AAAAAAAAAAAAAgD8XSMLBpIiIv3BfP8AAAAAAAACAPwAAAAAAAAAAAACAP0R668HNHmBAeseYwAAAAAAAAIA/AAAAAAAAAAAAAIA/F0jCwaSIiL9wXz/AAAAAAAAAgD8AAAAAAAAAAAAAgD/jpfTBgGC+QCs1q8AAAAAAAACAPwAAAAAAAAAAAACAP0R668HNHmBAeseYwAAAAAAAAIA/AAAAAAAAAAAAAIA/TXPtwZqUC0FhVKjAAAAAAAAAgD8AAAAAAAAAAAAAgD/VeNrBVvEfQRfUkcAAAAAAAACAPwAAAAAAAAAAAACAPwK8OsFiEDRBzqZ3vwAAAAAAAIA/AAAAAAAAAAAAAIA/1XjawVbxH0EX1JHAAAAAAAAAgD8AAAAAAAAAAAAAgD8epybBs3s7QembXL8AAAAAAACAPwAAAAAAAAAAAACAPwK8OsFiEDRBzqZ3vwAAAAAAAIA/AAAAAAAAAAAAAIA/ZjEZwdNNTEFvSmm/AAAAAAAAgD8AAAAAAAAAAAAAgD8VAFHAuEDbQUSLfMAAAAAAAACAPwAAAAAAAAAAAACAP2YxGcHTTUxBb0ppvwAAAAAAAIA/AAAAAAAAAAAAAIA/ak2zv3sD6kEz/pDAAAAAAAAAgD8AAAAAAAAAAAAAgD8VAFHAuEDbQUSLfMAAAAAAAACAPwAAAAAAAAAAAACAP5LLqz+wA+pBl62QwAAAAAAAAIA/AAAAAAAAAAAAAIA/I/NMQINA20EwDXvAAAAAAAAAgD8AAAAAAAAAAAAAgD/e1BdBak1MQYm2V78AAAAAAACAPwAAAAAAAAAAAACAPyPzTECDQNtBMA17wAAAAAAAAIA/AAAAAAAAAAAAAIA/gEglQbN7O0HheUm/AAAAAAAAgD8AAAAAAAAAAAAAgD/e1BdBak1MQYm2V78AAAAAAACAPwAAAAAAAAAAAACAP9lfOUFiEDRBSDNivwAAAAAAAIA/AAAAAAAAAAAAAIA/HqfaQbbWH0GEZIzAAAAAAAAAgD8AAAAAAAAAAAAAgD/ZXzlBYhA0QUgzYr8AAAAAAACAPwAAAAAAAAAAAACAP8V+7UG45AtBPUSiwAAAAAAAAIA/AAAAAAAAAAAAAIA/HqfaQbbWH0GEZIzAAAAAAAAAgD8AAAAAAAAAAAAAgD/+5fRBhlW/QBNEpcAAAAAAAACAPwAAAAAAAAAAAACAP8Db60GNC2FAGD6TwAAAAAAAAIA/AAAAAAAAAAAAAIA/GBWMQRbe4cDIe7m/AAAAAAAAgD8AAAAAAAAAAAAAgD/A2+tBjQthQBg+k8AAAAAAAACAPwAAAAAAAAAAAACAPw8LhkEc3wLB8S6zvwAAAAAAAIA/AAAAAAAAAAAAAIA/GBWMQRbe4cDIe7m/AAAAAAAAgD8AAAAAAAAAAAAAgD/iaYVB+WYYweaRw78AAAAAAACAPwAAAAAAAAAAAACAP8n2nEHvOMjB8PmuwAAAAAAAAIA/AAAAAAAAAAAAAIA/4mmFQflmGMHmkcO/AAAAAAAAgD8AAAAAAAAAAAAAgD+iNJhBnQDdwQETxsAAAAAAAACAPwAAAAAAAAAAAACAP8n2nEHvOMjB8PmuwAAAAAAAAIA/AAAAAAAAAAAAAIA/odaFQRnz6cH+YMjAAAAAAAAAgD8AAAAAAAAAAAAAgD9VwWNB0LPmwbw/tMAAAAAAAACAPwAAAAAAAAAAAACAP0GfnD+taaXBER75vwAAAAAAAIA/AAAAAAAAAAAAAIA/VcFjQdCz5sG8P7TAAAAAAAAAgD8AAAAAAAAAAAAAgD9xIyC9LpCiwQU07b8AAAAAAACAPwAAAAAAAAAAAACAP0GfnD+taaXBER75vwAAAAAAAIA/AAAAAAAAAAAAAIA/YY6mv61ppcHtR/q/AAAAAAAAgD8AAAAAAAAAAAAAgD89CmPBhtrkwTiEu8AAAAAAAACAPwAAAAAAAAAAAACAPxlzq79IP6TBRKgIwAAAAAAAAIA/AAAAAAAAAAAAAIA/pPCEwbwF6MHRkc/AAAAAAAAAgD8AAAAAAAAAAAAAgD89CmPBhtrkwTiEu8AAAAAAAACAPwAAAAAAAAAAAACAPza8lsEcfNvBkdDNwAAAAAAAAIA/AAAAAAAAAAAAAIA/EFibwXPoxsFbCLfAAAAAAAAAgD8AAAAAAAAAAAAAgD93vo7B4YuEwTCeTcAAAAAAAACAPwAAAAAAAAAAAACAPxBYm8Fz6MbBWwi3wAAAAAAAAIA/AAAAAAAAAAAAAIA/aLN+wWkARsGSswTAAAAAAAAAgD8AAAAAAAAAAAAAgD93vo7B4YuEwTCeTcAAAAAAAACAPwAAAAAAAAAAAACAPzojRcEcQhfBavaIvwAAAAAAAIA/AAAAAAAAAAAAAIA/EsIfQHoZE8CVRqw+AAAAAAAAgD8AAAAAAAAAAAAAgD86I0XBHEIXwWr2iL8AAAAAAACAPwAAAAAAAAAAAACAPxPVPUDHEeO/gO6rPgAAAAAAAIA/AAAAAAAAAAAAAIA/EsIfQHoZE8CVRqw+AAAAAAAAgD8AAAAAAAAAAAAAgD9IvztAiZiWv9v6sT4AAAAAAACAPwAAAAAAAAAAAACAP18MJ0BW8Fe/Ef+4PgAAAAAAAIA/AAAAAAAAAAAAAIA/hJ4BQHf3QL/rqsA+AAAAAAAAgD8AAAAAAAAAAAAAgD9lqmjB1LdowFteeb8AAAAAAACAPwAAAAAAAAAAAACAP4SeAUB390C/66rAPgAAAAAAAIA/AAAAAAAAAAAAAIA/vVKdwdFcWcDqygHAAAAAAAAAgD8AAAAAAAAAAAAAgD9lqmjB1LdowFteeb8AAAAAAACAPwAAAAAAAAAAAACAP+hZwcEdqnm/EwpLwAAAAAAAAIA/AAAAAAAAAAAAAIA/W0LqwbjpY0AJM57AAAAAAAAAgD8AAAAAAAAAAAAAgD/oWcHBHap5vxMKS8AAAAAAAACAPwAAAAAAAAAAAACAP5Ax88FHPb5A4iOwwAAAAAAAAIA/AAAAAAAAAAAAAIA/W0LqwbjpY0AJM57AAAAAAAAAgD8AAAAAAAAAAAAAgD9kO+zBoRAKQcBbrcAAAAAAAACAPwAAAAAAAAAAAACAP0K+2cEE5x1B73KXwAAAAAAAAIA/AAAAAAAAAAAAAIA/b/A5wTj4MUHP95O/AAAAAAAAgD8AAAAAAAAAAAAAgD9CvtnBBOcdQe9yl8AAAAAAAACAPwAAAAAAAAAAAACAP0I+JcGynTlB9guGvwAAAAAAAIA/AAAAAAAAAAAAAIA/b/A5wTj4MUHP95O/AAAAAAAAgD8AAAAAAAAAAAAAgD+FXxfBtvNKQdaQjL8AAAAAAACAPwAAAAAAAAAAAACAP4AOS8CWQ9pB3+CDwAAAAAAAAIA/AAAAAAAAAAAAAIA/hV8XwbbzSkHWkIy/AAAAAAAAgD8AAAAAAAAAAAAAgD/2l62/eqXoQUwalsAAAAAAAACAPwAAAAAAAAAAAACAP4AOS8CWQ9pB3+CDwAAAAAAAAIA/AAAAAAAAAAAAAIA/zTumP6+l6EFPzJXAAAAAAAAAgD8AAAAAAAAAAAAAgD8zFkdAYUPaQVIng8AAAAAAAACAPwAAAAAAAAAAAACAP4UIFkFN80pBh+GDvwAAAAAAAIA/AAAAAAAAAAAAAIA/MxZHQGFD2kFSJ4PAAAAAAAAAgD8AAAAAAAAAAAAAgD/35CNBsp05QS4feb8AAAAAAACAPwAAAAAAAAAAAACAP4UIFkFN80pBh+GDvwAAAAAAAIA/AAAAAAAAAAAAAIA/Apo4QTj4MUGlSYm/AAAAAAAAgD8AAAAAAAAAAAAAgD8179lBWcwdQa8IksAAAAAAAACAPwAAAAAAAAAAAACAPwKaOEE4+DFBpUmJvwAAAAAAAIA/AAAAAAAAAAAAAIA/WErsQUpeCkHeVKfAAAAAAAAAgD8AAAAAAAAAAAAAgD8179lBWcwdQa8IksAAAAAAAACAPwAAAAAAAAAAAACAP01z80HMKL9A+zqqwAAAAAAAAIA/AAAAAAAAAAAAAIA/qaTqQdrJZEAQr5jAAAAAAAAAgD8AAAAAAAAAAAAAgD9iIYtBDwvfwGzP0L8AAAAAAACAPwAAAAAAAAAAAACAP6mk6kHayWRAEK+YwAAAAAAAAIA/AAAAAAAAAAAAAIA/c+iEQfcBAsEEVsq/AAAAAAAAgD8AAAAAAAAAAAAAgD9iIYtBDwvfwGzP0L8AAAAAAACAPwAAAAAAAAAAAACAP8RChEEDMhjBJjbbvwAAAAAAAIA/AAAAAAAAAAAAAIA/48ebQf7Dx8EVdLTAAAAAAAAAgD8AAAAAAAAAAAAAgD/EQoRBAzIYwSY2278AAAAAAACAPwAAAAAAAAAAAACAP4cnl0FBAtzB0PLKwAAAAAAAAIA/AAAAAAAAAAAAAIA/48ebQf7Dx8EVdLTAAAAAAAAAgD8AAAAAAAAAAAAAgD/lYYVBCYrowfkszcAAAAAAAACAPwAAAAAAAAAAAACAP4zbY0HZX+XBZJK5wAAAAAAAAIA/AAAAAAAAAAAAAIA/kq6hP0g/pMG/DgjAAAAAAAAAgD8AAAAAAAAAAAAAgD+M22NB2V/lwWSSucAAAAAAAACAPwAAAAAAAAAAAACAP9KFHb1CT6HBKe0BwAAAAAAAAIA/AAAAAAAAAAAAAIA/kq6hP0g/pMG/DgjAAAAAAAAAgD8AAAAAAAAAAAAAgD8Zc6u/SD+kwUSoCMAAAAAAAACAPwAAAAAAAAAAAACAPz2bY8FSOOPB1xe/wAAAAAAAAIA/AAAAAAAAAAAAAIA/N2yzv3e+osHlsxDAAAAAAAAAgD8AAAAAAAAAAAAAgD9seITBM0TmwWBZ0sAAAAAAAACAPwAAAAAAAAAAAACAPz2bY8FSOOPB1xe/wAAAAAAAAIA/AAAAAAAAAAAAAIA/B1+Vwe5a2sG4r9DAAAAAAAAAgD8AAAAAAAAAAAAAgD9SyZnBgZXGwUbOusAAAAAAAACAPwAAAAAAAAAAAACAP+xAjcF3voTB5GZWwAAAAAAAAIA/AAAAAAAAAAAAAIA/UsmZwYGVxsFGzrrAAAAAAAAAgD8AAAAAAAAAAAAAgD8hH3zBpU5HwaVrDsAAAAAAAACAPwAAAAAAAAAAAACAP+xAjcF3voTB5GZWwAAAAAAAAIA/AAAAAAAAAAAAAIA/MlVDwRQzGcFVMJ6/AAAAAAAAgD8AAAAAAAAAAAAAgD+B7CVAUWYbwEAYKD4AAAAAAACAPwAAAAAAAAAAAACAPzJVQ8EUMxnBVTCevwAAAAAAAIA/AAAAAAAAAAAAAIA/C0FIQBMs6r8lIyc+AAAAAAAAgD8AAAAAAAAAAAAAgD+B7CVAUWYbwEAYKD4AAAAAAACAPwAAAAAAAAAAAACAP+W4RUB9P42/TN01PgAAAAAAAIA/AAAAAAAAAAAAAIA/J9orQMfxL7+LbEc+AAAAAAAAgD8AAAAAAAAAAAAAgD+YTAFAu9MVv0T7WD4AAAAAAACAPwAAAAAAAAAAAACAP4hjaMGSrl3A5e2QvwAAAAAAAIA/AAAAAAAAAAAAAIA/mEwBQLvTFb9E+1g+AAAAAAAAgD8AAAAAAAAAAAAAgD9Pr5zBkINOwCwOC8AAAAAAAACAPwAAAAAAAAAAAACAP4hjaMGSrl3A5e2QvwAAAAAAAIA/AAAAAAAAAAAAAIA/OUXAwUjeVb8mcFPAAAAAAAAAgD8AAAAAAAAAAAAAgD9wzujBFjVqQAXdocAAAAAAAACAPwAAAAAAAAAAAACAPzlFwMFI3lW/JnBTwAAAAAAAAIA/AAAAAAAAAAAAAIA/8WPxwcRfvkAjFbPAAAAAAAAAgD8AAAAAAAAAAAAAgD9wzujBFjVqQAXdocAAAAAAAACAPwAAAAAAAAAAAACAP4DI6sHu9wdB3nGwwAAAAAAAAIA/AAAAAAAAAAAAAIA/tgTZwTUHG0FEaZvAAAAAAAAAgD8AAAAAAAAAAAAAgD+/DjnBSgwvQYKLpb8AAAAAAACAPwAAAAAAAAAAAACAP7YE2cE1BxtBRGmbwAAAAAAAAIA/AAAAAAAAAAAAAIA/NV4jwZEPN0HX+pa/AAAAAAAAgD8AAAAAAAAAAAAAgD+/DjnBSgwvQYKLpb8AAAAAAACAPwAAAAAAAAAAAACAP4LWFMGTOklBHcmdvwAAAAAAAIA/AAAAAAAAAAAAAIA/xT1CwDQi2UF1yIfAAAAAAAAAgD8AAAAAAAAAAAAAgD+C1hTBkzpJQR3Jnb8AAAAAAACAPwAAAAAAAAAAAACAP2kdpb+89OZBokWZwAAAAAAAAIA/AAAAAAAAAAAAAIA/xT1CwDQi2UF1yIfAAAAAAAAAgD8AAAAAAAAAAAAAgD8w2J0/8fTmQX/7mMAAAAAAAACAPwAAAAAAAAAAAACAP+NTPkD/IdlBBReHwAAAAAAAAIA/AAAAAAAAAAAAAIA/e4MTQZM6SUEpP5W/AAAAAAAAgD8AAAAAAAAAAAAAgD/jUz5A/yHZQQUXh8AAAAAAAACAPwAAAAAAAAAAAACAPwMJIkGRDzdB7ZmNvwAAAAAAAIA/AAAAAAAAAAAAAIA/e4MTQZM6SUEpP5W/AAAAAAAAgD8AAAAAAAAAAAAAgD9qvDdBSgwvQSHqmr8AAAAAAACAPwAAAAAAAAAAAACAPx042UGB7BpBqwSWwAAAAAAAAIA/AAAAAAAAAAAAAIA/arw3QUoML0Eh6pq/AAAAAAAAgD8AAAAAAAAAAAAAgD+62upB00EIQWB2qsAAAAAAAACAPwAAAAAAAAAAAACAPx042UGB7BpBqwSWwAAAAAAAAIA/AAAAAAAAAAAAAIA/tabxQQg9v0AmNq3AAAAAAAAAgD8AAAAAAAAAAAAAgD9VMOlBDAJrQAdfnMAAAAAAAACAPwAAAAAAAAAAAACAP6foiUF7FNvAijzhvwAAAAAAAIA/AAAAAAAAAAAAAIA/VTDpQQwCa0AHX5zAAAAAAAAAgD8AAAAAAAAAAAAAgD+9Y4NBGukAwV972r8AAAAAAACAPwAAAAAAAAAAAACAP6foiUF7FNvAijzhvwAAAAAAAIA/AAAAAAAAAAAAAIA/rraCQXgoGMEHJey/AAAAAAAAgD8AAAAAAAAAAAAAgD/7OppBkW3HwT4/uMAAAAAAAACAPwAAAAAAAAAAAACAP662gkF4KBjBByXsvwAAAAAAAIA/AAAAAAAAAAAAAIA/ZMyVQULg2sFV2c3AAAAAAAAAgD8AAAAAAAAAAAAAgD/7OppBkW3HwT4/uMAAAAAAAACAPwAAAAAAAAAAAACAP3/qhEFLyObB7fXPwAAAAAAAAIA/AAAAAAAAAAAAAIA/AG9kQaW948HRIr3AAAAAAAAAgD8AAAAAAAAAAAAAgD8uxak/d76iwdcSEMAAAAAAAACAPwAAAAAAAAAAAACAPwBvZEGlvePB0SK9wAAAAAAAAIA/AAAAAAAAAAAAAIA/YrsbvTCqn8GoqQnAAAAAAAAAgD8AAAAAAAAAAAAAgD8uxak/d76iwdcSEMAAAAAAAACAPwAAAAAAAAAAAACAPzdss793vqLB5bMQwAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAA==", "byteLength" : 43180}], "bufferViews" : [{"buffer" : 0, "byteOffset" : 0, "byteLength" : 8676, "target" : 34963}, {"buffer" : 0, "byteOffset" : 8680, "byteLength" : 34496, "byteStride" : 32, "target" : 34962}], "images" : [{"uri" : "../Downloads/shine.png"}, {"uri" : "../Downloads/texture.jpg"}], "materials" : [{"name" : "Mat", "pbrMetallicRoughness" : {"baseColorFactor" : [1, 1, 1, 1], "baseColorTexture" : {"index" : 1, "texCoord" : 0}, "metallicFactor" : 1, "roughnessFactor" : 1}, "emissiveTexture" : {"index" : 0, "texCoord" : 0}, "emissiveFactor" : [0, 0, 0], "alphaMode" : "OPAQUE", "doubleSided" : false}], "meshes" : [{"primitives" : [{"attributes" : {"POSITION" : 1, "NORMAL" : 2, "TEXCOORD_0" : 3}, "indices" : 0, "material" : 0, "mode" : 4}], "name" : ""}], "nodes" : [{"matrix" : [0.1, 0, 0, 0, 0, 0.1, 0, 0, 0, 0, 0.1, 0, 0, 0, 0, 1], "mesh" : 0, "name" : "star"}], "samplers" : [{"magFilter" : 9729, "minFilter" : 9985, "wrapS" : 33071, "wrapT" : 33071}, {"magFilter" : 9729, "minFilter" : 9729, "wrapS" : 33648, "wrapT" : 33648}], "scene" : 0, "scenes" : [{"nodes" : [0]}], "textures" : [{"sampler" : 0, "source" : 0, "name" : ""}, {"sampler" : 1, "source" : 1, "name" : ""}]} \ No newline at end of file diff --git a/presentation/src/main/res/values-ru-rRU/string.xml b/presentation/src/main/res/values-ru-rRU/string.xml deleted file mode 100644 index 7a08cf15..00000000 --- a/presentation/src/main/res/values-ru-rRU/string.xml +++ /dev/null @@ -1,1858 +0,0 @@ - - - Подтверждение - Вы действительно хотите подтвердить вход на этом устройстве? - Да, войти - Отмена - - Сканировать QR-код - Устройства - Подключить устройство - - Это устройство - Запросы на вход - Активные сеансы - - Назад - Закрыть сканер - Иконка QR-сканера - - - Подключение к Telegram… - - - О приложении - Назад - MonoGram - Версия %1$s - Условия использования - Ознакомьтесь с условиями использования - Лицензии - Используемое ПО с открытым исходным кодом - GitHub - Исходный код приложения - Версия TDLib - %1$s (%2$s) - Сообщество - Чат поддержки - Обсуждение функций и помощь - Канал MonoGram - Новости и обновления проекта - Поддержать разработку - Помочь проекту развиваться - Разработчики - Разработчик - Дизайнер - MonoGram — неофициальный клиент Telegram на базе Material Design 3 - © 2026 MonoGram - - - Проверить обновления - Проверка… - Доступно обновление: %1$s - У Вас установлена последняя версия - Обновление готово - Ошибка при обновлении - Нажмите, чтобы проверить наличие новой версии - Подключение к серверу - Доступна новая версия для загрузки - Вы используете актуальную версию - Нажмите, чтобы установить обновление - Загрузка обновления… - %1$d%% - Что нового в %1$s - Скачать обновление - Отмена - Загрузка… - - - Ваш телефон - Проверка - Пароль - Настройки прокси - Ваш номер телефона - Пожалуйста, подтвердите код страны и введите свой номер телефона. - Страна - Код - Номер телефона - 000 00 00 - Продолжить - Выберите страну - Поиск страны или кода… - Код подтверждения был отправлен через Telegram на другое Ваше устройство. - Мы отправили СМС с кодом подтверждения на Ваш номер. - Мы звоним Вам, чтобы сообщить код. - Мы отправили код на %1$s. - Мы отправили код подтверждения. - Подтвердить - Отправить ещё раз через %1$s - Отправить по СМС - Позвонить для получения кода - Отправить код ещё раз - Неверный номер? - Двухэтапная аутентификация - Ваш аккаунт защищён облачным паролем. - Пароль - Разблокировать - Вставить - Ошибка авторизации - Закрыть - - - Пожалуйста, подождите… - Загрузка длится слишком долго? - Сбросить соединение - - - Переслать… - Выбрано чатов: %1$d - Отправить - Архив - Новый чат - Недавние - Очистить всё - Чаты и контакты - Глобальный поиск - Сообщения - Показать больше - Поиск чатов… - Ожидание сети… - Подключение… - Обновление… - Подключение к прокси… - Прокси включен - Прокси - Форум - Спойлер - Черновик: - Постов пока нет - Сообщений пока нет - Закреплено - Упоминания - Скрыто из основного списка - Чатов пока нет - Начните новую беседу - Mini App - - - MonoGram Dev - Добавить аккаунт - Войти в другой аккаунт - Мой профиль - Просмотр профиля - Избранное - Облачное хранилище - Настройки - Конфигурация приложения - Доступно обновление - Доступна новая версия %1$s - Загрузка обновления… %1$d%% - Обновление готово к установке - Помощь - FAQ и поддержка - Политика конфиденциальности - MonoGram Dev для Android v%1$s - Неизвестный пользователь - Нет информации - Показать аккаунты - - - Поиск сообщений… - Очистить - Без звука - Подтверждённый аккаунт - Включить уведомления - Выключить уведомления - Фильтровать рекламу - Добавить в белый список - Копировать ссылку - Очистить историю - Удалить чат - Пожаловаться - ПОДПИСАТЬСЯ - Прокрутить вниз - Эта тема закрыта - Прикрепить - - - Удалить сообщение? - Удалить %1$d сообщений? - Вы уверены, что хотите удалить это сообщение? - Вы уверены, что хотите удалить эти сообщения? - Удалить у всех - Удалить у меня - - Почему Вы жалуетесь на это? - Ваша жалоба анонимна. Мы проверим историю чата для обеспечения безопасности. - Детали жалобы - Опишите проблему… - Отправить жалобу - Спам - Нежелательная реклама или мошенничество - Насилие - Угрозы или пропаганда насилия - Порнография - Неприемлемый контент или нецензурная лексика - Детская безопасность - Контент, наносящий вред несовершеннолетним - Авторское право - Использование чужой интеллектуальной собственности - Выдача себя за другого - Выдача себя за другое лицо или бота - Наркотики - Пропаганда продажи или употребления запрещенных веществ - Нарушение приватности - Распространение личных контактных данных или адресов - Несоответствующее место - Контент не имеет отношения к этому месту - Другое - Что-то другое, что нарушает наши условия - - Ограничить пользователя - Отправка сообщений - Отправка медиа - Отправка стикеров и GIF - Отправка опросов - Предпросмотр ссылок - Закрепление сообщений - Изменение данных чата - Ограничить до - Навсегда - Выбрать дату - Выбрать время - Ограничить - - Ответить - Копировать - Закрепить - Открепить - Переслать - Выбрать - Ещё - Удалить - Посмотреть комментарии - Сохранить в загрузки - Cocoon - Сводка - Перевести - Создано с помощью Telegram Cocoon - Вернуть исходный текст - Ограничить - изменено - прочитано - просмотры - - - Неизвестно - Участники: %1$d - %1$s, %2$d в сети - Ещё не реализовано - Поиск пока не работает - Функция «Поделиться» пока недоступна - Блокировка пока недоступна - Удаление пока недоступно - Статистика - Доход - Поделиться - Изменить - Заблокировать - Покинуть - Открыть - Сообщение - Вступить - Пожаловаться - QR-код - Добавить - Фотография профиля - Это фото видите только Вы - Открыть Mini App - Запустить веб-приложение бота - Принять условия - Просмотрите и примите условия обслуживания бота - Разрешения для бота - Управление правами этого бота - Имя пользователя - Ссылка - Ссылка-приглашение - Информация о боте - Описание - О себе - Дата рождения - Местоположение - Часы работы - Недавние действия - Журнал событий чата - Детальная статистика чата - Статистика доходов чата - Добавил(а) Вас в контакты - Не добавил(а) Вас в контакты - Сохранён(а) в Ваших контактах - Не сохранён(а) в Ваших контактах - Истории профиля - Вы можете публиковать истории от своего профиля - Фон чата - Вы можете устанавливать пользовательские фоны - Голосовые и видеосообщения - Отправка голосовых и видеосообщений ограничена - Медленный режим - Участники могут отправлять одно сообщение каждые %1$s - Защищенный контент - Пересылка и сохранение ограничены - Приватная пересылка - Пересланные сообщения скрывают ссылку на профиль - Статистика - Администраторы: %1$d - Ограничено: %1$d - Заблокировано: %1$d - Информация - Уведомления - Автоудаление - Настройки - Сохранить - Спам - Насилие - Порнография - Жестокое обращение с детьми - Нарушение авторских прав - Другое - Закрыть - Запуская это Mini App, Вы соглашаетесь с Условиями обслуживания и Политикой конфиденциальности. Бот сможет получить доступ к Вашей основной информации профиля. - Принять и запустить - - - QR-код - Поделиться - MonoGram — бесплатный проект с открытым исходным кодом. Ваша поддержка помогает нам развивать приложение и добавлять новые функции. - Бейдж спонсора с сердцем выдаётся с уровня поддержки Advanced или при - эквивалентной поддержке от 150 ₽ (примерно $1.96). - - Поддержать на Boosty - Может быть позже - Изменить профиль - Долгое нажатие, чтобы скрыть - Удерживайте, чтобы показать, нажмите для копирования - Ваш ID - Имя, информация о себе и фото профиля - Включить ссылки t.me - Открывать ссылки Telegram внутри приложения - Общие настройки - Настройки чатов - Темы, размер текста, видеоплеер - Конфиденциальность - Код-пароль, сеансы, приватность - Уведомления и звуки - Сообщения, группы, звонки - Данные и память - Использование сети, автозагрузка - Энергосбережение - Настройки экономии заряда - Папки - Управление папками с чатами - Стикеры и эмодзи - Наборы стикеров и эмодзи - Связанные устройства - Язык - Английский - Прокси - MTProto, SOCKS5, HTTP - Telegram Premium - Эксклюзивные функции - Помощь в развитии проекта - Поддержал MonoGram - Этот пользователь поддерживает проект и помогает нам развиваться - Версия и информация о MonoGram - Отладка - Параметры для разработчиков - Показать окно спонсора - Открыть нижнюю панель с информацией о спонсоре - Принудительная синхронизация спонсоров - Сейчас загрузить ID спонсоров из канала - Выйти - Завершить сеанс - - - Имена пользователя - Повторите попытку через %1$d с - Активные имена - Отключенные имена - Коллекционные имена - Готово - ОК - Выберите время начала - Выберите время окончания - Часы работы - Рабочие дни - Диапазон времени - От - До - Адрес компании - Адрес - Подтвердить местоположение - Изменить профиль - Имя (обязательно) - Фамилия (необязательно) - О себе - Вы можете добавить немного информации о себе. Она будет видна в Вашем профиле. - Имя пользователя - Вы можете выбрать имя пользователя в Telegram. Если Вы это сделаете, люди смогут найти Вас по этому имени и связаться с Вами, не зная Вашего номера телефона. - День рождения - Дата рождения - Telegram для бизнеса - ID связанного канала - Описание бизнеса - Адрес бизнеса - Геопозиция - Часы работы - С подпиской Premium Вы можете привязать канал и добавить сведения о бизнесе в свой профиль. - Не указано - (%1$d дн.) - Пн - Вт - Ср - Чт - Пт - Сб - Вс - - - Конфиденциальность - Приватность - Черный список - Пользователей: %1$d - Нет - Номер телефона - Последняя активность - Фотографии профиля - Пересылка сообщений - Звонки - Группы и каналы - Безопасность - Код-пароль - Вкл. - Выкл. - Разблокировка биометрией - Использовать отпечаток пальца или лицо - Активные сеансы - Управление устройствами - Контент деликатного характера - Выключить фильтрацию - Отображать деликатный контент в публичных каналах на всех Ваших устройствах. - Дополнительно - Удалить мой аккаунт - Если я не заходил %1$s - Удалить аккаунт сейчас - Безвозвратно удалить аккаунт и все данные - Если я не захожу… - Удалить аккаунт - Вы уверены, что хотите удалить свой аккаунт? Это действие необратимо, все данные будут потеряны. - Все - Мои контакты - Никто - 1 месяц - 3 месяца - 6 месяцев - 1 год - 18 месяцев - 2 года - %1$d мес. - %1$d дн. - Удаление по запросу пользователя - - - Настройки прокси - Обновить задержку - Добавить прокси - Соединение - Умное переключение - Автоматически выбирать самый быстрый прокси - Предпочитать IPv6 - Использовать IPv6 при наличии - Отключить прокси - Прямое подключение - Переключиться на прямое соединение - Telega Proxy - Telega Proxy обвиняли в перехвате трафика. MTProto защищает данные сообщений от перехвата, но используйте этот прокси на свой риск. Подробнее: t.me/telegaru - Включить Telega Proxy - Автоматическое получение и переключение - Обновить список - Получить актуальные прокси от сообщества - Ваши прокси - Очистить офлайн - Удалить все - Удалить офлайн-прокси - Это действие удалит все прокси, которые сейчас недоступны. Продолжить? - Удалить все прокси - Это действие удалит все настроенные прокси из приложения. Продолжить? - Нет добавленных прокси - Удалить прокси - Вы уверены, что хотите удалить прокси %1$s? - Новый прокси - Изменить прокси - Адрес сервера - Порт - Секрет (Hex) - Имя пользователя (опционально) - Пароль (опционально) - Сохранить изменения - Проверить - Результат проверки - Удалить - Проверка... - Недоступен - %1$d мс - - - Ваши имена пользователя - Дополнительно - - - Уведомления и звуки - Уведомления о сообщениях - Личные чаты - Группы - Каналы - Настройки уведомлений - Вибрация - Приоритет - Повтор уведомлений - Только отправитель - Скрывать текст сообщения в уведомлениях - Push-служба - Провайдер Push-уведомлений - Фоновая служба - Работа приложения в фоне для надёжной доставки уведомлений - Скрыть уведомление службы - Скрыть сервисное уведомление. Может привести к завершению работы системы - Уведомления в приложении - Звуки в приложении - Вибрация в приложении - Предпросмотр в приложении - События - Контакт присоединился к Telegram - Закреплённые сообщения - Сбросить все уведомления - Сброс всех персональных настроек уведомлений для контактов и групп - Тип вибрации - Приоритет уведомлений - %1$s, исключений: %2$d - По умолчанию - Короткая - Длинная - Отключена - Низкий - По умолчанию - Высокий - Никогда - Каждые %1$d мин. - Каждый час - Каждые %1$d ч. - Firebase Cloud Messaging - Без GMS (фоновая служба) - - - Настройки чатов - Внешний вид - Размер текста сообщений - Межбуквенный интервал сообщений - Скругление блоков - Сбросить - Обои чата - Сбросить обои - Стиль эмодзи - Тема - Ночной режим - Системная - Светлая - Тёмная - По расписанию - Автоматически - Текущий режим - Сейчас: %1$s - Порог яркости: %1$d%% - Переключение на тёмную тему при яркости ниже этого уровня. - Динамические цвета - Динамические цвета - Использовать системную палитру (Material You) - Данные и память - Сжимать фотографии - Уменьшать размер фото перед отправкой - Сжимать видео - Уменьшать размер видео перед отправкой - Видеоплеер - Включить жесты - Громкость и яркость свайпами по экрану - Перемотка двойным нажатием - Нажатия по краям видео для перемотки - Интервал перемотки - Масштабирование - Увеличение видео жестом щипка - Список чатов - Закрепить архив - Архив всегда в начале списка чатов - Всегда показывать архив - Не скрывать закреплённый архив при прокрутке - Предпросмотр ссылок - Отображать превью для ссылок в сообщениях - Свайп для возврата - Возврат назад свайпом от левого края - Две строки - Три строки - Показывать фотографии - Фото профиля в списке чатов - Экспериментальные функции - AdBlock для каналов - Скрывать рекламные посты в каналах - Недавние медиа - Очистить недавние стикеры - Удалить список недавно использованных стикеров - Очистить недавние эмодзи - Удалить список недавно использованных эмодзи - Удалить набор эмодзи - Удалить набор «%1$s»? - Загруженный набор эмодзи будет удалён с устройства. Его можно будет скачать снова. - Изменить свою тему - Выбрано - Apple - Twitter - Windows - Catmoji - Noto - Системные - - - Данные и память - Использование памяти и сети - Использование памяти - Управление локальным кэшем - Использование сети - Объём отправленных и полученных данных - Автозагрузка медиа - Через мобильную сеть - Через Wi-Fi - В роуминге - Файлы - Автоматически скачивать входящие файлы - Стикеры - Автоматически скачивать стикеры - Видеосообщения - Автоматически скачивать видеосообщения - Автовоспроизведение - GIF-анимации - В списке чатов и в самих чатах - Видео - Внутри диалогов и групп - Включено - Отключено - - - Энергосбережение - Батарея - Режим энергосбережения - Ограничение фоновой активности для экономии заряда - Оптимизация батареи - Агрессивное ограничение фоновой работы - Wake Lock - Разрешить ЦП работать в фоне. Отключите для экономии заряда - Анимации - Анимации в чате - Отключить для продления работы от аккумулятора - Фон - Отключение может привести к задержке уведомлений - - - Стикеры и эмодзи - Стикеры - Эмодзи - Недавние стикеры - Наборы стикеров - Архивные стикеры - Создать свои стикеры - С помощью официального бота @Stickers - Наборы стикеров не установлены - Стикеры по запросу «%1$s» не найдены - Недавние эмодзи - Наборы эмодзи - Архивные эмодзи - Создать свои эмодзи - С помощью официального бота @Stickers - Очистить недавние эмодзи - Удалить список недавно использованных эмодзи - Наборы эмодзи не установлены - Эмодзи по запросу «%1$s» не найдены - Поиск наборов - Поиск - - %1$d стикер - %1$d стикера - %1$d стикеров - %1$d стикеров - - - %1$d эмодзи - %1$d эмодзи - %1$d эмодзи - %1$d эмодзи - - Маски - Эмодзи - Официальный - Ссылка скопирована - - - Использование сети - Сбросить статистику - Статистика сети - Контроль трафика. Отключение экономит место на диске. - Статистика отключена - Включите отслеживание, чтобы видеть расход трафика в сетях. - Всего использовано - Отправлено - Получено - Обзор - Расход трафика - Нет данных об использовании - Статистика недоступна - Мобильная сеть - Wi-Fi - Роуминг - Другое - - - Использование памяти - Очистить весь кэш • %1$s - Включает медиафайлы из всех Ваших чатов. - Максимальный размер кэша - Хранить медиа - Оптимизатор хранилища - Фоновая очистка памяти - Подробности - Память свободна - Кэшированные файлы не найдены. - Очистить кэш - Очистить кэш для «%1$s»? Будет освобождено %2$s. - Очистить весь кэш - Это удалит все закэшированные медиафайлы из всех чатов. Продолжить? - Без ограничений - Всегда - 1 день - 1 неделя - 1 месяц - Всего использовано - Файлов: %1$d - Файлов: %1$d - - - Кто может добавлять меня в группы? - Кто может мне звонить? - Кто видит время моего последнего входа? - Кто видит мои фотографии профиля? - Кто видит сведения «О себе»? - Кто может ссылаться на мой аккаунт при пересылке моих сообщений? - Кто может добавлять меня в группы и каналы? - Кто может видеть мой номер телефона? - Кто может найти меня по номеру? - Пользователи, сохранившие Ваш номер, увидят его в Telegram, только если это разрешено настройкой выше. - Добавить исключения - Всегда разрешать - Никогда не разрешать - Объектов: %1$d - (удалён) - Участники чата - Поиск по номеру - Список пуст - Заблокированные пользователи не смогут Вам писать и видеть Вашу сетевую активность. - Разблокировать - Заблокировать - Поиск пользователей - Пользователи не найдены - - - Изменить код-пароль - Установить код-пароль - Ваше приложение защищено кодом. Введите новый код. - Введите 4-значный код для защиты приложения. - Код-пароль - Текущий код-пароль - Сохранить - Отключить код-пароль - Подтвердите код-пароль - Перед изменением или отключением кода-пароля введите текущий. - Неверный код-пароль. - - - Добавить ключевое слово - Включить AdBlock - Белый список каналов - Разрешено каналов: %1$d - Загрузить базу слов - Импорт стандартных рекламных ключей - Копировать список - Скопировать все ключи в буфер обмена - Очистить список - Удалить все ключевые слова - Ключевые слова для фильтрации - Список пуст - Нажмите «+», чтобы добавить слова для фильтрации - Добавить слова - Введите слова через запятую или с новой строки. - напр. #реклама, ad, promo - Добавить в список - Посты в этих каналах не будут фильтроваться - Список пуст - Удалить - - - был(а) недавно - был(а) только что - - был(а) %1$d минуту назад - был(а) %1$d минуты назад - был(а) %1$d минут назад - был(а) %1$d минут назад - - был(а) в %1$s - был(а) вчера в %1$s - был(а) %1$s - был(а) на этой неделе - был(а) в этом месяце - был(а) очень давно - в сети - не в сети - бот - Имя пользователя - Стикеров: %1$d - В архиве - Добавить - Разархивировать - В архив - Удалить набор - - - Новое сообщение - Добавить участников - Новая группа - Новый канал - Контактов: %1$d - %1$d / 200000 - Выбрано: %1$d - Поиск контактов… - Контакты не найдены - Нет результатов для "%1$s" - По времени посещения - Создать группу - Создать канал - Поддержка - Каналы — это инструмент для трансляции Ваших сообщений неограниченной аудитории. - Данные канала - Название канала - Описание (необязательно) - Автоудаление сообщений - Выкл. - 1 день - 2 дня - 3 дня - 4 дня - 5 дней - 6 дней - 1 неделя - 2 недели - 3 недели - 1 месяц - 2 месяца - 3 месяца - 4 месяца - 5 месяцев - 6 месяцев - 1 год - Вы можете добавить описание канала. Любой пользователь сможет подписаться на Ваш канал, если у него есть ссылка. - Укажите название и добавьте фото для Вашей новой группы. - Данные группы - Название группы - Введите название группы - Введите название канала - Открыть профиль - Изменить имя - Удалить контакт - Редактирование контакта - Имя - Фамилия - Удалить контакт? - Вы уверены, что хотите удалить %1$s из контактов? - Автоматически удалять новые сообщения в этой группе через определенное время. - Добавить фото - Изменить фото - - - Необходимы разрешения - Для обеспечения наилучшего опыта MonoGram необходимы следующие разрешения. - Уведомления - Получайте уведомления о новых сообщениях - Разрешить - Состояние телефона - Управление состоянием устройства для лучшего опыта - Оптимизация батареи - Обеспечение надежной фоновой работы - Отключить - Камера - Делайте фото и записывайте видеосообщения - Микрофон - Записывайте голосовые и видеосообщения - Местоположение - Делитесь местоположением и находите пользователей рядом - - - Очистить выделение - Закрепить - - - Команды бота - Выберите команду для отправки боту - - - Список чатов - Коната Идзуми - Я не коротышка, я просто концентрированная крутость! 🍫 А ещё я решила стать профессиональной соней 😴 - 12:45 - Кагами Хиираги - Не забудь про домашку! Её нужно сдать завтра утром, и она довольно сложная. - 11:20 - - - Предпросмотр - Я - Я не коротышка, я просто концентрированная крутость! 🍫\nА ещё я решила стать профессиональной соней 😴 - Ты так говоришь каждый раз, когда не можешь дотянуться до верхней полки... 🙄\nЗацени: вот - Хватит меня разоблачать! 😤✨\nЯ просто использую своё секретное оружие: 💯 чистая лень - Это суперэффективно! 😵‍💫 - Сегодня - Коната - - %1$d подписчиков - Ветка - - - Удалить запись - < Проведите для отмены - Отправить запись - Заблокировать запись - Проведите вверх - - - Добавить подпись… - Сообщение - Отправка сообщений запрещена - - - Фото - Видео - Стикер - Голосовое сообщение - Видеосообщение - GIF - Геопозиция - Сообщение - - - Отменить ответ - Изменить сообщение - Отменить редактирование - Отправить %1$d объектов - Отправить медиа - Отмена - Копировать - Вставить - Вырезать - Выделить все - Применить - Готово - Обновить - Полноэкранный редактор - Редактор - Отправить без звука - Отложить сообщение - Отложенные сообщения - Отложенные сообщения (%1$d) - Пока нет отложенных сообщений - Всего отложено: %1$d - Ближайшая отправка: %1$s - Можно редактировать: %1$d - ID: %1$d - Изменить - Отправить - Удалить - - Жирный - Курсив - Подчеркнутый - Зачеркнутый - Спойлер - Код - Моноширинный - Ссылка - Упомянуть - Эмодзи - Очистить - Добавить ссылку - URL - Язык кода - Язык (например, kotlin) - - %1$d символов • %2$d блоков форматирования - %1$d блоков форматирования - Выделите текст, чтобы применить форматирование как в Telegram - %1$d/%2$d - - - Команды - - - печатает - записывает видео - записывает голосовое - отправляет фото - отправляет видео - отправляет файл - выбирает стикер - играет - Кто-то - и - и еще %d - печатают - - %d человек печатает - %d человека печатают - %d человек печатают - %d человек печатают - - - - Фотографии - Видео - Документы - Стикеры - Музыка - Голосовые сообщения - Видеосообщения - Другие файлы - Прочее / Кэш - Чат %d - - - Звонки - - - Ожидание новых сообщений - Остановить - Фоновая работа - Уведомление о работе приложения в фоне - - - 📷 Фото - 📹 Видео - 🎤 Голосовое сообщение - 🧩 Стикер - 📎 Документ - 🎵 Аудио - GIF - 🎬 Видеосообщение - 👤 Контакт - 📊 Опрос - 📍 Геолокация - 📞 Звонок - 🎮 Игра - 💳 Счёт - 📚 История - 📌 Закреплённое сообщение - Сообщение - Бот - В сети - Не в сети - был(а) только что - был(а) %d минуту назад - был(а) %d минут назад - был(а) в %s - был(а) вчера в %s - был(а) %s - был(а) недавно - был(а) на этой неделе - был(а) в этом месяце - - - Закреплённые сообщения - Закреплённое сообщение - Показать все закреплённые - Открепить - Закрыть - - %d сообщение - %d сообщения - %d сообщений - %d сообщений - - - - Видеосообщение - GIF - Документ - Опрос: %s - Стикер %s - - - Просмотр - Обрезка - Фильтры - Рисование - Текст - Ластик - - - Оригинал - Ч/Б - Сепия - Винтаж - Холодный - Теплый - Полароид - Инверсия - - - Сохранить - Отмена - Отменить - Повторить - Закрыть - Сбросить - Поворот влево - Поворот вправо - Добавить текст - Изменить текст - Применить - Удалить - - - Размер - Масштаб - Введите текст... - Выберите инструмент для редактирования - - - Сбросить изменения? - У вас есть несохраненные изменения. Вы уверены, что хотите их удалить? - Сбросить - - - Применить - Готово - Отмена - Низкое - - - Просмотр - Обрезка - Фильтры - Текст - Сжатие - - - Включить звук - Выключить звук - Добавить текст - Качество видео - Примерный битрейт: %1$d кбит/с - - - Оригинал - Ч/Б - Сепия - Винтаж - Холодный - Тёплый - Полароид - Инверсия - - - Файл не найден - Видеофайл отсутствует - Сбросить изменения? - У вас есть несохранённые изменения. Вы уверены, что хотите их сбросить? - Сбросить - - - Загрузка… - Веб-просмотр - Закрыть - Ещё - - - Опции - Назад - Вперед - Обновить - Действия - Настройки - Копировать - Ссылка скопирована - Поделиться - Поделиться через - Браузер - Поиск - Версия для ПК - Блок рекламы - Размер текста: %1$d%% - - - Безопасно - Небезопасно - Безопасность - Незащищенное соединение - Подключение к этому сайту зашифровано и защищено. - Подключение к этому сайту не защищено. Не вводите личные данные (пароли или карты), так как они могут быть украдены. - Кому выдан - Кем выдан - Действителен до - Неизвестно - - - Поиск на странице… - Пред. - След. - Закрыть поиск - - - Обсуждение - Канал - Открыть карты - Маршруты - Использовать для навигации - Открыть с помощью - Браузер / Другое - Медиа - Участники - Файлы - Музыка - Голос - Ссылки - GIF - Участники не найдены - Медиа не найдены - Аудиозаписи не найдены - Голосовые сообщения не найдены - Файлы не найдены - Ссылки не найдены - GIF не найдены - БОТ - Закрыто - ID - - - Анализ статистики… - Обзор - Участники - Сообщения - Зрители - Активные отправители - Рост аудитории - Новые участники - Тип контента - Действия - Активность по дням - Активность по неделям - Популярные часы - Источники просмотров - Источники новых участников - Языки - Топ участников - сообщ. - Ср. кол-во символов: %1$d - Топ администраторов - действий - Удал: %1$d | Бан: %2$d - Топ приглашающих - приглашений - Добавлено участников - Подписчики - Уведомления включены - Ср. количество просмотров - Ср. количество пересылок - Ср. количество реакций - Рост - Новые подписчики - Просмотры по часам - Взаимодействие с сообщениями - Взаимодействие с Instant View - Реакции на сообщения - Недавние взаимодействия - Сообщение - История - ID поста - Скрыть - Показать все (%1$d) - Доход - Доступный баланс - Общий баланс - Курс обмена - Рост дохода - Почасовой доход - Данные загружены - Увеличить - Построение графика… - Без изменений - по сравнению с прошлым пер. - Неизвестный тип статистики - Класс данных: %1$s - - - Назад - Опции - Перемотать на 10 секунд назад - Перемотать на 10 секунд вперёд - -%1$ds - +%1$ds - Миниатюра %1$d - %1$d из %2$d - Загружается оригинал... - - - Загрузить - Скачать видео - Копировать фото - Копировать текст - Копировать ссылку - Ссылка с привязкой ко времени - Переслать - Сохранить в GIF - В галерею - В буфер обмена - Начать заново - Пауза - Воспроизвести - Разблокировать - - - Настройки - Скорость воспроизведения - Режим масштабирования - Вписать - Заполнить - Поворот экрана - Картинка в картинке - Скриншот - Зациклить видео - Выключить звук - Субтитры - Заблокировать управление - Качество - Качество видео - Авто - Высокое - Обычная - - - Играть - Пауза - Назад - Вперёд - - - Стикеры - Эмодзи - GIF - - - Недавние стикеры - Стикеры - Найти стикеры - - - Недавние эмодзи - Стандартные эмодзи - Пользовательские эмодзи - Эмодзи - Найти эмодзи - - - Недавние и сохранённые - GIF не найдены - Найти GIF - - - Назад - Очистить - Недавние - - - Saved to Gallery - Поделиться QR - Ошибка при отправке: %1$s - - - Изм. канал - Изм. группу - Название канала - Название группы - Описание - Настройки - Публичный канал - Публичная группа - Автоперевод - Темы - Управление - Удалить канал - Удалить группу - - - Поиск... - Администраторы - Подписчики - Участники - Чёрный список - Ничего не найдено - Участников пока нет - - - Права админа - Должность - Эта подпись будет видна всем участникам в чате - Что может делать этот админ? - Управление чатом - Публикация сообщений - Изменение сообщений - Удаление сообщений - Блокировка участников - Добавление участников - Управление темами - Управление видеочатами - Публикация историй - Редактирование историй - Удаление историй - Добавление администраторов - Анонимность - - - Разрешения - Что могут делать участники группы? - Добавление участников - - - Назад - Сохранить - Очистить - Поиск - Добавить - Изм. - Имя пользователя - Фильтры - - - Недавние действия - Загружено событий: %d - Действий не найдено - Попробуйте изменить фильтры - Не реализовано - ID пользователя скопирован - - - Фильтры - Сбросить - Применить - Типы действий - По участникам - Поиск… - Пользователи не найдены - Нет результатов по запросу «%s» - - - Правки - Удаления - Закрепы - Входы - Выходы - Приглашения - Повышения - Ограничения - Инфо - Настройки - Ссылки - Видео - - - отредактировал(а) сообщение - удалил(а) сообщение - закрепил(а) сообщение - открепил(а) сообщение - присоединился(ась) к чату - покинул(а) чат - пригласил(а) %s - изменил(а) права для %s - изменил(а) ограничения для %s - изменил(а) название чата на «%s» - изменил(а) описание чата - изменил(а) имя пользователя на @%s - изменил(а) фото чата - изменил(а) пригласительную ссылку - отозвал(а) пригласительную ссылку - удалил(а) пригласительную ссылку - начал(а) видеочат - завершил(а) видеочат - выполнил(а) действие: %s - - - Старое сообщение: - Новое сообщение: - Удалённое сообщение: - Закреплённое сообщение: - Откреплённое сообщение: - До: %s - Ограничен навсегда - Было - Стало - Старое фото чата - Новое фото чата - С - На - Изменения прав: - Текущие права: - - - Сообщения - Медиа - Стикеры - Ссылки - Опросы - Приглашения - Закрепление - Данные - - Админ - Владелец - Ограничен - Забанен - Участник - - - Фото - Видео - GIF - Стикер - Файл - Аудио - Голосовое сообщение - Видеосообщение - Контакт - Опрос - Геопозиция - Место - Неподдерживаемое сообщение - - - HH:mm - %1$02d:%2$02d - - - %1$.1fK - %1$.1fM - - - Прокомментировать - %1$d комментариев - %1$.1fK комментариев - %1$.1fM комментариев - - - Финальные результаты - Анонимный опрос - Публичный опрос - Викторина - Опрос - • Выбор нескольких вариантов - Отменить голос - Остановить опрос - - %d голос - %d голоса - %d голосов - %d голоса - - - - Ещё - Голосовать - Объяснение - - - Проголосовавшие - Никто ещё не проголосовал - Закрыть - - - Фотография - Видео - Стикер - Голосовое сообщение - Видеосообщение - GIF - Сообщение - - - Папки с чатами - Назад - Новая папка - Создать - Изм. папку - Сохранить - Стандартные папки - Личные папки - Удалить - Создавайте папки для разных групп чатов и быстро переключайтесь между ними. - У Вас нет папок - Нажмите на кнопку «+», чтобы создать - Все чаты - %1$d чатов - Переместить вверх - Переместить вниз - Название папки - Выбрать иконку - Включённые чаты - Поиск чатов… - Отмена - - - Telegram Premium - Назад - Подписаться за %s в месяц - Разблокируйте эксклюзивные функции - - - Удвоенные лимиты - До %1$d каналов, %2$d папок, %3$d закрепов, %4$d публичных ссылок и не только. - Расшифровка голоса - Читайте текстовую версию любого голосового сообщения одним нажатием. - Ускоренная загрузка - Снятие ограничений на скорость загрузки фото, видео и документов. - Перевод в реальном времени - Мгновенный перевод целых чатов одним касанием. - Анимированные эмодзи - Использование авторских анимированных эмодзи в сообщениях. - Управление чатами - Выбор папки по умолчанию, автоархивация и скрытие новых чатов. - Отключение рекламы - Рекламные сообщения в каналах больше не будут отображаться. - Активные реакции - Тысячи эмодзи для реакций и до 3 реакций на одно сообщение. - Значок подписчика - Особый значок рядом с Вашим именем, подтверждающий подписку. - Эмодзи-статусы - Установка любого эмодзи в качестве статуса рядом с именем. - Иконки приложения - Эксклюзивные иконки для приложения Telegram на главном экране. - - - Обновить - Копировать ссылку - Открыть в браузере - На главный экран - - - Закрыть приложение? - У Вас есть несохранённые изменения. Вы уверены, что хотите закрыть мини-приложение? - Закрыть - Отмена - Запрос разрешения - Разрешить - Отклонить - Разрешения бота - Условия использования - Запуская это мини-приложение, Вы принимаете Условия использования и Политику конфиденциальности. Бот получит доступ к данным Вашего профиля. - Принять и запустить - - - Поиск в статье… - Назад - Очистить - Быстрый просмотр - Ещё - %d просмотров - Копировать ссылку - Открыть в браузере - Поиск - Размер текста - Воспроизвести видео - Воспроизвести анимацию - Аудио - Неизвестный исполнитель - Воспроизвести - Открыть - Свернуть - Развернуть - Карта: %1$s, %2$s - - - Поделиться профилем - Поделиться ссылкой на ваш профиль в Monogram - Копировать ссылку - Копировать ссылку на профиль Monogram в буфер обмена - - - Редактор тем - Режим палитры - Выберите палитру для редактирования. По умолчанию открывается палитра, которая сейчас активна в приложении. - Светлая - Тёмная - Редактируется: палитра %1$s - Сейчас активна в приложении: %1$s - Акцент - Акцент изменяет только палитру %1$s. - Hex-акцент - Применить - Отмена - Выбрать - Сохранить - Загрузить - Обе - Hex - monogram-theme.json - - Файл темы сохранён - Ошибка сохранения - Тема загружена - Некорректный файл - Ошибка загрузки - - Источник темы - Выберите один источник цветов. «Своя тема» использует ваши палитры, «Monet» — динамические цвета Android. «AMOLED» влияет только на тёмный режим. - Своя тема - Используйте свои палитры, акценты, пресеты и ручную настройку ролей. - Monet - Цвета Material You на основе обоев системы (Android 12+). - AMOLED (чёрный) - Чистый чёрный цвет для экономии заряда на OLED-экранах. - - Готовые темы - У каждого пресета есть светлый и тёмный варианты. Нажмите «Светлая», «Тёмная» или «Обе», чтобы применить их. - Ручные цвета (%1$s) - Предпросмотр: %1$s - Пример текста - Действие - Выбор: %1$s - Тон %1$d° - Насыщенность %1$d%% - Яркость %1$d%% - Прозрачность %1$d%% - - Основной - Вторичный - Третичный - Фон - Поверхность - Контейнер осн. - Контейнер втор. - Контейнер трет. - Вариант пов. - Контур - - С О - С К - С Ф - Т О - Т К - Т Ф - - Синий - Зелёный - Оранжевый - Розовый - Индиго - Голубой - - Классика - Сбалансированный синий с высокой читаемостью и нейтральным фоном. - - Лес - Натуральные зелёные тона со спокойным контрастом. - - Океан - Свежий сине-голубой градиент с глубоким тёмным режимом. - - Закат - Тёплые оранжевые и коралловые акценты с чётким текстом. - - Графит - Нейтральная серая база с сине-серыми акцентами. Строгий стиль. - - Мята - Сочетание мяты и морской волны с мягкими переходами. - - Рубин - Глубокие красные акценты для фокуса на важных действиях. - - Лаванда - Приглушённый фиолетово-серый стиль с чистым контрастом. - - Песок - Бежевая и янтарная палитра для минимальной нагрузки на глаза. - - Арктика - Ледяной сине-белый стиль с очень чёткими границами. - - Изумруд - Яркая зелёная палитра с чистыми поверхностями и современным контрастом. - - Медь - Тёплая медно-оранжевая тема с чётким текстом в обоих режимах. - - Сакура - Мягкие розово-пурпурные тона с деликатными контейнерами и яркими акцентами. - - Норд - Прохладные северные синие оттенки со спокойным профессиональным балансом. - - Нужны разрешения на камеру и микрофон - Обработка... - Ошибка обработки: %1$s - Закрыть запись - Переключить камеру - Завершить запись - REC - ГОТОВ - Время: %1$s - Зум: %1$.1fx (диапазон %2$.1fx - %3$.1fx) - Отмена - - Очистить историю? - Вы уверены, что хотите очистить историю чата? Это действие нельзя отменить. - Очистить историю - Удалить чат? - Вы уверены, что хотите удалить этот чат? Это действие нельзя отменить. - Удалить чат - Покинуть чат? - Вы уверены, что хотите покинуть этот чат? - Покинуть - Удалить канал? - Удалить группу? - Вы уверены, что хотите удалить этот канал? Все сообщения и медиа будут потеряны. - Вы уверены, что хотите удалить эту группу? Все сообщения и медиа будут потеряны. - Удалить %1$d чатов? - Вы уверены, что хотите удалить выбранные чаты? - Удалить чаты - Заблокировать пользователя? - Вы уверены, что хотите заблокировать этого пользователя? Он не сможет отправлять вам сообщения. - Заблокировать - Разблокировать пользователя? - Вы уверены, что хотите разблокировать этого пользователя? Он снова сможет - отправлять вам сообщения. - - Открепить сообщение? - Вы уверены, что хотите открепить это сообщение? - Открепить - Вы уверены, что хотите очистить недавние стикеры? - Очистить стикеры - Вы уверены, что хотите очистить недавние эмодзи? - Очистить эмодзи - Добавить в контакты - Удалить из контактов - Пометить прочитанным - Пометить непрочитанным - Изменить - Порядок - Удалить - diff --git a/presentation/src/main/res/values-sk/string.xml b/presentation/src/main/res/values-sk/string.xml deleted file mode 100644 index 0abe4ee8..00000000 --- a/presentation/src/main/res/values-sk/string.xml +++ /dev/null @@ -1,1989 +0,0 @@ - - - Potvrdenie - Naozaj chcete autorizovať toto zariadenie? - Áno, prihlásiť sa - Zrušiť - - Skenovať QR - Zariadenia - Prepojiť zariadenie - - Toto zariadenie - Žiadosti o prihlásenie - Aktívne relácie - - Späť - Zavrieť skener - Ikona QR skenera - - - Pripájanie k Telegramu… - - - O aplikácii - Späť - MonoGram - Verzia %1$s - Podmienky služby - Prečítajte si naše podmienky - Open Source licencie - Softvér použitý v MonoGrame - GitHub - Zobraziť zdrojový kód - Verzia TDLib - %1$s (%2$s) - Komunita - Telegram chat - Pridajte sa do našej komunity a diskutujte o funkciách alebo požiadajte o - pomoc - - Telegram kanál - Sledujte najnovšie správy a oznámenia - Podporte MonoGram - Podporte vývoj a pomôžte nám udržať projekt nažive - Správcovia - Vývojár - Dizajnér ikon a loga - MonoGram je neoficiálny klient Telegramu vytvorený s Material Design 3 - © 2026 MonoGram - - - Skontrolovať aktualizácie - Kontrolujem... - Dostupná aktualizácia: %1$s - Máte najnovšiu verziu - Aktualizácia pripravená - Chyba aktualizácie - Klepnutím skontrolujete novú verziu - Pripájanie k serveru - Je dostupná nová verzia na stiahnutie - Používate najnovšiu verziu - Klepnutím nainštalujete aktualizáciu - Sťahovanie aktualizácie... - %1$d%% - Čo je nové vo verzii %1$s - Stiahnuť aktualizáciu - Zrušiť - Načítavam... - - - Váš telefón - Overenie - Heslo - Nastavenia proxy - Vaše telefónne číslo - Potvrďte kód krajiny a zadajte svoje telefónne číslo. - Krajina - Kód - Telefónne číslo - 000 00 00 - Pokračovať - Vybrať krajinu - Hľadať krajinu alebo kód... - Kód sme odoslali do aplikácie Telegram na vašom inom zariadení. - - Kód sme odoslali cez SMS. - Voláme vám s kódom. - Kód sme poslali na %1$s. - Overovací kód bol odoslaný. - Potvrdiť - Znovu odoslať kód o %1$s - Znovu odoslať cez SMS - Znovu odoslať hovorom - Znovu odoslať kód - Zlé číslo? - Dvojstupňové overenie - Váš účet je chránený dodatočným heslom. - Heslo - Odomknúť - Vložiť - Chyba overenia - Zamietnuť - - - Chvíľu počkajte - Trvá to príliš dlho? - Obnoviť pripojenie - - - Preposlať do... - Vybraných %1$d chatov - Odoslať - Archivované chaty - Nový chat - Nedávne - Vymazať všetko - Chaty a kontakty - Globálne vyhľadávanie - Správy - Zobraziť viac - Hľadať konverzácie… - Čakám na sieť… - Pripájam… - Aktualizujem… - Pripájam sa k proxy… - Proxy je zapnuté - Proxy - Fórum - Spoiler - Koncept: - Zatiaľ žiadne príspevky - Zatiaľ žiadne správy - Pripnuté - Zmienky - Skryté z hlavného zoznamu - Zatiaľ žiadne chaty - Začať novú konverzáciu - Mini aplikácia - - - MonoGram Dev - Pridať účet - Prihlásiť sa do iného účtu - Môj profil - Zobraziť váš profil - Uložené správy - Cloudové úložisko - Nastavenia - Konfigurácia aplikácie - Dostupná aktualizácia - Je dostupná nová verzia %1$s - Sťahovanie aktualizácie... %1$d%% - Aktualizácia pripravená na inštaláciu - Pomoc a spätná väzba - FAQ a podpora - Zásady ochrany súkromia - MonoGram Dev pre Android v%1$s - Neznámy používateľ - Žiadne informácie - Zobraziť účty - - - Hľadať správy... - Vymazať - Stlmené - Overené - Sponzor - Zapnúť zvuk - Stlmiť - Filtrovať reklamy - Pridať kanál na whitelist - Kopírovať odkaz - Vymazať históriu - Odstrániť chat - Nahlásiť - PRIPOJIŤ SA - Prejsť na koniec - Táto téma je uzavretá - Priložiť - - - Odstrániť správu? - Odstrániť %1$d správ? - Naozaj chcete odstrániť túto správu? - Naozaj chcete odstrániť tieto správy? - Odstrániť pre všetkých - Odstrániť pre mňa - - Prečo to nahlasujete? - Vaše nahlásenie je anonymné. Skontrolujeme históriu chatu, aby sme zaistili - bezpečnosť. - - Podrobnosti nahlásenia - Opíšte problém… - Odoslať nahlásenie - Spam - Nežiadúci komerčný obsah alebo podvody - Násilie - Vyhrážky alebo oslavovanie násilia - Pornografia - Nevhodné médiá alebo explicitný obsah - Bezpečnosť detí - Obsah zahŕňajúci ublíženie maloletým - Autorské práva - Použitie duševného vlastníctva inej osoby - Vydávanie sa za inú osobu - Predstieranie, že ste niekto iný, alebo bot - Nelegálne drogy - Propagovanie predaja alebo používania zakázaných látok - - Porušenie súkromia - Zdieľanie súkromných kontaktných údajov alebo adries - - Nesúvisiaca poloha - Obsah, ktorý nie je relevantný pre toto konkrétne - miesto - - Iné - Niečo iné, čo porušuje naše podmienky - - Obmedziť používateľa - Odosielanie správ - Odosielanie médií - Odosielanie nálepiek a GIFov - Odosielanie ankiet - Vkladanie odkazov - Pripínanie správ - Zmena informácií o chate - Obmedziť do - Navždy - Vybrať dátum - Vybrať čas - Obmedziť - - Odpovedať - Kopírovať - Pripnúť - Odopnúť - Preposlať - Vybrať - Viac - Odstrániť - Zobraziť komentáre - Uložiť do stiahnutých - Cocoon - Zhrnutie - Preložiť - Vygenerované pomocou Telegram Cocoon - Obnoviť pôvodný text - Obmedziť používateľa - Upravené - Prečítané - Zobrazenia - - - Neznáme - %1$d členov - %1$s, %2$d online - Nie je implementované - Vyhľadávanie nie je implementované - Zdieľanie nie je implementované - Blokovanie nie je implementované - Odstránenie nie je implementované - Štatistiky - Príjmy - Zdieľať - Upraviť - Blokovať používateľa - Opustiť - Otvoriť - Správa - Pripojiť sa - Nahlásiť - QR kód - Pridať - Osobná fotografia - Táto fotografia je viditeľná iba vám - Otvoriť mini aplikáciu - Spustiť webovú aplikáciu bota - Prijať podmienky - Prečítajte a prijmite podmienky služby bota - Oprávnenia bota - Spravovať oprávnenia pre tohto bota - Používateľské meno - Odkaz - Pozvánkový odkaz - Informácie o botovi - Popis - Bio - Dátum narodenia - Poloha - Otváracie hodiny - Nedávne akcie - Zobraziť záznam udalostí chatu - Zobraziť podrobné štatistiky chatu - Zobraziť štatistiky príjmov chatu - Pridal vás do kontaktov - Nepridalo vás do kontaktov - Uložené vo vašich kontaktoch - Neuložené vo vašich kontaktoch - Príbehy profilu - Môžete zverejňovať príbehy zo svojho profilu - Pozadie chatu - Môžete nastaviť vlastné pozadie - Hlasové a video správy - Odosielanie hlasových a video správ je obmedzené - Pomalý režim - Členovia môžu odoslať jednu správu každých %1$s - Chránený obsah - Preposielanie a ukladanie sú obmedzené - Súkromné preposielanie - Preposielané správy skrývajú odkaz na profil - Štatistiky chatu - %1$d správcov - %1$d obmedzených - %1$d zablokovaných - Informácie - Oznámenia - Automaticky odstrániť správy - Nastavenia - Uložiť - Spam - Násilie - Pornografia - Zneužívanie detí - Autorské práva - Iné - Zavrieť - Spustením tejto mini aplikácie súhlasíte s Podmienkami služby a Zásadami - ochrany súkromia. Bot bude mať prístup k základným informáciám vášho profilu. - - Prijať a spustiť - - - QR kód - Zdieľať - MonoGram je bezplatný projekt s otvoreným zdrojovým kódom. Vaša podpora - nám pomáha udržať ho nažive a vyvíjať nové funkcie. - - Sponzorský odznak so srdiečkom je dostupný od úrovne Advanced alebo - ekvivalentným príspevkom 150 RUB (asi 1,70 $). - - Podporiť cez Boosty - Možno neskôr - Upraviť profil - Dlhým stlačením skryjete - Podržaním zobrazíte, klepnutím skopírujete - Vaše ID - Zmeniť meno, bio a profilovú fotografiu - Povoliť odkazy t.me - Otvárajte Telegram odkazy priamo v aplikácii - Všeobecné - Nastavenia chatu - Témy, veľkosť textu, video prehrávač - Súkromie a bezpečnosť - Kód, aktívne relácie, súkromie - Oznámenia a zvuky - Správy, skupiny, hovory - Dáta a úložisko - Spotreba siete, automatické sťahovanie - Úspora energie - Nastavenia spotreby batérie - Priečinky chatov - Usporiadajte svoje chaty - Nálepky a emoji - Spravovať sady nálepiek a balíčky emoji - Prepojené zariadenia - Jazyk - Angličtina - Nastavenia proxy - MTProto, SOCKS5, HTTP - Telegram Premium - Odomknúť exkluzívne funkcie - Pomôžte nám rozvíjať projekt - Podporuje MonoGram - Tento používateľ podporuje projekt a pomáha nám ho neustále zlepšovať - - Verzia a informácie o MonoGrame - Ladenie - Možnosti ladenia - Zobraziť sponzorský panel - Otvoriť spodný panel s informáciami o sponzorovi - Vynútiť synchronizáciu sponzorov - Načítať ID sponzorov z kanála teraz - Odhlásiť sa - Odpojiť sa od účtu - - - Používateľské mená - Skúsiť znova za %1$ds - Aktívne používateľské mená - Deaktivované používateľské mená - Zberateľské používateľské mená - Hotovo - OK - Vybrať čas začiatku - Vybrať čas konca - Pracovné hodiny - Pracovné dni - Časové rozmedzie - Od - Do - Firemná poloha - Adresa - Potvrdiť polohu - Upraviť profil - Meno (povinné) - Priezvisko (voliteľné) - Bio - Ľubovoľné údaje, ako vek, povolanie alebo mesto. Príklad: 23-ročný dizajnér zo San - Francisca. - - Používateľské meno - Na Telegrame si môžete zvoliť používateľské meno. Ak tak urobíte, ľudia vás budú - môcť nájsť podľa neho a kontaktovať vás bez potreby poznať vaše telefónne číslo. - - Vaše narodeniny - Narodeniny - Telegram Business - ID prepojeného kanála - Firemné bio - Firemná adresa - Geografická poloha - Otváracie hodiny - Ako používateľ Premium môžete prepojiť kanál a nastaviť firemné údaje vo - svojom profile - - Nenastavené - (%1$d dní) - P - U - S - Š - P - S - N - - - Súkromie a bezpečnosť - Súkromie - Zablokovaní používatelia - %1$d používateľov - Žiadne - Telefónne číslo - Posledná aktivita a online stav - Fotografie profilu - Preposielané správy - Hovory - Skupiny a kanály - Bezpečnosť - Zámok kódom - Zapnuté - Vypnuté - Odomknúť biometriou - Použiť odtlačok prsta alebo tvár na odomknutie - Aktívne relácie - Spravovať prihlásené zariadenia - Citlivý obsah - Vypnúť filtrovanie - Zobrazovať citlivé médiá vo verejných kanáloch na všetkých vašich - zariadeniach. - - Rozšírené - Odstrániť môj účet - Ak som neaktívny počas %1$s - Odstrániť účet teraz - Natrvalo odstrániť váš účet a všetky dáta - Samozničenie pri neaktivite počas... - Odstrániť účet - Naozaj chcete odstrániť váš účet? Táto akcia je trvalá a nedá sa - vrátiť späť. - - Všetci - Moje kontakty - Nikto - 1 mesiac - 3 mesiace - 6 mesiacov - 1 rok - 18 mesiacov - 2 roky - %1$d mesiacov - %1$d dní - Používateľ požiadal o odstránenie - - - Nastavenia proxy - Obnoviť pingy - Pridať proxy - Pripojenie - Inteligentné prepínanie - Automaticky použiť najrýchlejšie proxy - Uprednostniť IPv6 - Použiť IPv6, keď je dostupné - Vypnúť proxy - Pripojené priamo - Prepnúť na priame pripojenie - Telega Proxy - Proxy od komunity. Používajte na vlastné riziko. Viac info: t.me/telegaru - - Povoliť Telega Proxy - Automaticky načítať a prepnúť na najlepšie - Obnoviť zoznam - Načítať najnovšie proxy od komunity - Vaše proxy - Odstrániť offline - Odstrániť všetky - Odstrániť offline proxy - Táto akcia odstráni všetky proxy, ktoré sú momentálne offline. Pokračovať? - Odstrániť všetky proxy - Táto akcia odstráni všetky nakonfigurované proxy z aplikácie. Pokračovať? - Žiadne proxy nie sú pridané - Odstrániť proxy - Naozaj chcete odstrániť proxy %1$s? - Nové proxy - Upraviť proxy - Adresa servera - Port - Tajný kľúč (Hex) - Používateľské meno (voliteľné) - Heslo (voliteľné) - Uložiť zmeny - Otestovať - Výsledok testu - Odstrániť - Kontrolujem... - Offline - %1$d ms - - - Vaše používateľské mená - Viac možností - - - Oznámenia a zvuky - Oznámenia správ - Súkromné chaty - Skupiny - Kanály - Nastavenia oznámení - Vibrácie - Priorita - Opakovanie oznámení - Zobraziť iba odosielateľa - Skryť obsah správy v oznámeniach - Služba push - Poskytovateľ push - Služba keep-alive - Udržiavať aplikáciu bežiacu na pozadí pre spoľahlivé oznámenia - - Skryť oznámenie popredia - Skryť oznámenie služby po spustení. Môže viesť k ukončeniu - služby systémom - - Oznámenia v aplikácii - Zvuky v aplikácii - Vibrácie v aplikácii - Náhľad v aplikácii - Udalosti - Kontakt sa pripojil k Telegramu - Pripnuté správy - Obnoviť všetky oznámenia - Vrátiť všetky vlastné nastavenia oznámení pre všetky kontakty a - skupiny - - Vzor vibrácií - Priorita oznámenia - %1$s, %2$d výnimiek - Predvolené - Krátke - Dlhé - Vypnuté - Nízka - Predvolená - Vysoká - Nikdy - Každých %1$d minút - Každú 1 hodinu - Každých %1$d hodín - Firebase Cloud Messaging - Bez GMS (služba na pozadí) - - - Nastavenia chatu - Vzhľad - Veľkosť textu správy - Zaoblenie bublín - Obnoviť - Tapeta chatu - Obnoviť tapetu - Štýl emoji - Téma - Nočný režim - Systém - Svetlý - Tmavý - Plán - Automaticky - Aktuálne správanie - Použité: %1$s - Prah jasu: %1$d%% - Prepnúť na tmavú tému, keď jas obrazovky klesne pod túto úroveň. - - Dynamické farby - Dynamické farby - Použiť systémové farby pre tému aplikácie - Dáta a úložisko - Komprimovať fotografie - Zmenšiť veľkosť fotografie pred odoslaním - Komprimovať videá - Zmenšiť veľkosť videa pred odoslaním - Video prehrávač - Povoliť gestá - Potiahnutím ovládať hlasitosť a jas - Dvojité klepnutie na presun - Dvojitým klepnutím na okraje videa preskočiť - Dĺžka preskočenia - Povoliť priblíženie - Priblížiť stiahnutím prstov vo video prehrávači - Zoznam chatov - Pripnúť archivované chaty - Udržiavať archivované chaty navrchu zoznamu - Vždy zobraziť pripnutý archív - Udržiavať pripnutý archív viditeľný aj pri posúvaní - Zobraziť náhľady odkazov - Zobrazovať náhľady odkazov v správach - Potiahnutím späť - Potiahnutím z ľavého okraja sa vrátiť späť - Dvojriadkové - Trojriadkové - Zobraziť fotografie - Zobrazovať profilové fotografie v zozname chatov - Experimentálne - AdBlock pre kanály - Skryť sponzorované príspevky v kanáloch - Nedávne médiá - Vymazať nedávne nálepky - Odstrániť všetky naposledy použité nálepky - Vymazať nedávne emoji - Odstrániť všetky naposledy použité emoji - Odstrániť balíček emoji - Odstrániť balíček %1$s? - Tým sa zo zariadenia odstráni stiahnutý balíček emoji. Neskôr si ho môžete - znova stiahnuť. - - Upraviť vlastnú tému - Vybrané - Apple - Twitter - Windows - Catmoji - Noto - Systémové - - - Dáta a úložisko - Spotreba disku a siete - Využitie úložiska - Spravovať lokálnu vyrovnávaciu pamäť - Spotreba siete - Zobraziť odoslané a prijaté dáta - Automatické sťahovanie médií - Pri použití mobilných dát - Pri pripojení na Wi-Fi - Pri roamingu - Automatické sťahovanie súborov - Automaticky sťahovať prichádzajúce súbory - Automatické sťahovanie nálepiek - Automaticky sťahovať nálepky - Automatické sťahovanie video správ - Automaticky sťahovať video správy - Automatické prehrávanie médií - GIFy - Automaticky prehrávať GIFy v zozname chatov a chatoch - Videá - Automaticky prehrávať videá v chatoch - Zapnuté - Vypnuté - - - Úspora energie - Batéria - Režim úspory energie - Znižuje aktivitu na pozadí a animácie na šetrenie batérie - Optimalizovať spotrebu batérie - Agresívne obmedzovať prácu na pozadí a uvoľňovať wake locky - Wake Lock - Udržiavať CPU aktívne pre úlohy na pozadí. Vypnite pre úsporu batérie - Animácie - Animácie chatu - Vypnúť animácie v chate pre úsporu batérie - Pozadie - Vypnutím sa zníži spotreba energie, ale môžu sa oneskoriť oznámenia - na pozadí - - - - Nálepky a emoji - Nálepky - Emoji - Nedávne nálepky - Sady nálepiek - Archivované nálepky - Pridať vlastné nálepky - Vytvoriť vlastné sady nálepiek pomocou bota @Stickers - Žiadne sady nálepiek nie sú nainštalované - Žiadne nálepky neboli nájdené pre „%1$s" - Nedávne emoji - Balíčky emoji - Archivované emoji - Pridať vlastné emoji - Vytvoriť vlastné balíčky emoji pomocou bota @Stickers - Vymazať nedávne emoji - Odstrániť všetky naposledy použité emoji - Žiadne balíčky emoji nie sú nainštalované - Žiadne emoji neboli nájdené pre „%1$s" - Hľadať balíčky - Hľadať - - %1$d nálepka - %1$d nálepky - %1$d nálepiek - %1$d nálepiek - - - %1$d emoji - %1$d emoji - %1$d emoji - %1$d emoji - - Masky - Vlastné emoji - Oficiálne - Odkaz skopírovaný do schránky - - - Spotreba siete - Obnoviť štatistiky - Štatistiky siete - Sledujte, koľko dát spotrebúvate. Vypnutie môže znížiť využitie miesta - na disku. - - Štatistiky siete sú vypnuté - Sledovanie spotreby siete je momentálne vypnuté. Zapnite ho - pomocou prepínača vyššie a sledujte, koľko dát používate cez mobilné dáta, Wi-Fi a roaming. - - Celková spotreba - Odoslané - Prijaté - Prehľad - Spotreba aplikácie - Žiadne dáta o spotrebe neboli zaznamenané - Žiadne štatistiky nie sú dostupné - Mobil - Wi-Fi - Roaming - Iné - - - Využitie úložiska - Vymazať celú vyrovnávaciu pamäť • %1$s - Zahŕňa fotografie, videá, dokumenty, nálepky a GIFy zo všetkých chatov. - - Limit vyrovnávacej pamäte - Automatické vymazanie vyrovnávacej pamäte - Optimalizátor úložiska - Optimalizácia úložiska na pozadí - Podrobná spotreba - Úložisko je čisté - Žiadne uložené súbory sa nenašli. - Vymazať vyrovnávaciu pamäť - Naozaj chcete vymazať vyrovnávaciu pamäť pre „%1$s"? Uvoľní sa tým - %2$s. - - Vymazať celú vyrovnávaciu pamäť - Tým sa odstránia všetky uložené mediálne súbory zo všetkých chatov. - Naozaj chcete pokračovať? - - Neobmedzené - Nikdy - Každý deň - Každý týždeň - Každý mesiac - Celkovo použité - %1$d súborov - %1$d súborov - - - Kto ma môže pridať do %1$s? - Kto mi môže volať? - Kto môže vidieť čas mojej poslednej aktivity? - Kto môže vidieť moje profilové fotografie? - Kto môže vidieť moje bio? - Kto môže pridať odkaz na môj účet pri - preposielaní mojich správ? - - Kto ma môže pridať do skupín a kanálov? - Kto môže vidieť moje telefónne číslo? - Kto ma môže nájsť podľa čísla? - Používatelia, ktorí pridajú vaše číslo do kontaktov, ho uvidia na - Telegrame iba ak to umožňuje nastavenie vyššie. - - Pridať výnimky - Vždy povoliť - Nikdy nepovoliť - %1$d používateľov/chatov - (odstránené) - Členovia chatu - Vyhľadávanie podľa telefónneho čísla - Žiadni zablokovaní používatelia - Zablokovaní používatelia vás nebudú môcť kontaktovať a neuvidia čas vašej - poslednej aktivity. - - Odblokovať - Blokovať používateľa - Hľadať používateľov - Žiadni používatelia sa nenašli - - - Zmeniť kód - Nastaviť kód - Vaša aplikácia je momentálne chránená kódom. Zadajte nový kód na jeho - zmenu. - - Zadajte 4-ciferný kód na zamknutie aplikácie a ochranu súkromia. - Kód - Aktuálny kód - Uložiť kód - Vypnúť kód - Overiť kód - Zadajte aktuálny kód pred jeho zmenou alebo vypnutím. - Nesprávny kód. - - - Pridať kľúčové slovo - Povoliť AdBlock - Kanály na whiteliste - %1$d povolených kanálov - Načítať základné kľúčové slová - Importovať bežné reklamné kľúčové slová z prostriedkov - Kopírovať všetky kľúčové slová - Kopírovať aktuálny zoznam do schránky - Vymazať všetky kľúčové slová - Odstrániť všetky kľúčové slová zo zoznamu - Kľúčové slová na skrytie príspevkov - Žiadne kľúčové slová nie sú pridané - Klepnutím na tlačidlo + pridáte kľúčové slová na filtrovanie - Pridať kľúčové slová - Zadajte kľúčové slová oddelené čiarkami alebo novými riadkami na - filtrovanie príspevkov v kanáloch. - - napr. #promo, ad, реклама - Pridať do zoznamu - Príspevky z týchto kanálov nebudú filtrované - Žiadne kanály nie sú na whiteliste - Odstrániť - - - naposledy aktívny nedávno - naposledy aktívny práve teraz - - naposledy aktívny pred %1$d minútou - naposledy aktívny pred %1$d minútami - naposledy aktívny pred %1$d minútami - naposledy aktívny pred %1$d minútami - - naposledy aktívny o %1$s - naposledy aktívny včera o %1$s - naposledy aktívny %1$s - naposledy aktívny tento týždeň - naposledy aktívny tento mesiac - naposledy aktívny dávno - online - offline - bot - Používateľské meno - %1$d nálepiek - Archivované - Pridať - Odarchivovať - Archivovať - Odstrániť sadu - - - Nová správa - Pridať členov - Nová skupina - Nový kanál - %1$d kontaktov - %1$d / 200 000 - %1$d vybraných - Hľadať kontakty... - Neboli nájdené žiadne kontakty - Žiadne výsledky pre „%1$s“ - Zoradené podľa poslednej aktivity - Nová skupina - Nový kanál - Podpora - Kanály sú nástroj na vysielanie správ neobmedzenému počtu príjemcov. - - Podrobnosti kanála - Názov kanála - Popis (voliteľné) - Automatické odstraňovanie správ - Vypnuté - 1 deň - 2 dni - 3 dni - 4 dni - 5 dní - 6 dní - 1 týždeň - 2 týždne - 3 týždne - 1 mesiac - 2 mesiace - 3 mesiace - 4 mesiace - 5 mesiacov - 6 mesiacov - 1 rok - Môžete pridať voliteľný popis kanála. Ktokoľvek sa môže pripojiť, ak má odkaz. - - Zadajte názov a voliteľnú fotografiu pre novú skupinu. - Podrobnosti skupiny - Názov skupiny - Zadajte názov skupiny - Zadajte názov kanála - Otvoriť profil - Upraviť meno - Odstrániť kontakt - Upraviť kontakt - Meno - Priezvisko - Odstrániť kontakt? - Naozaj chcete odstrániť %1$s z vašich kontaktov? - Automaticky odstrániť nové správy odoslané v tejto skupine po určitom čase. - - Pridať fotografiu - Zmeniť fotografiu - - - Vyžadované oprávnenia - Na poskytnutie najlepšieho zážitku MonoGram potrebuje nasledujúce - oprávnenia. - - Oznámenia - Dostávať upozornenia na nové správy - Povoliť - Stav telefónu - Spravovať stavy zariadenia pre lepší používateľský zážitok - - Optimalizácia batérie - Zabezpečiť spoľahlivú prevádzku na pozadí - Vypnúť - Fotoaparát - Fotografovať a nahrávať video správy - Mikrofón - Nahrávať hlasové a video správy - Poloha - Zdieľať polohu a vidieť používateľov v blízkosti - - - Zrušiť výber - Pripnúť - - - Príkazy bota - Vyberte príkaz na odoslanie botovi - - - Zoznam chatov - Konata Izumi - Nie som malá, som len skoncentrovaná úžasnosť! 🍫 Tiež som sa rozhodla stať - profesionálnou spáčkou 😴 - - 12:45 - Kagami Hiiragi - Nezabudni na domácu úlohu! Je na zajtra ráno a je dosť ťažká. - 11:20 - - - Náhľad - Ja - Nie som malá, som len skoncentrovaná úžasnosť! 🍫\nTiež som sa rozhodla stať - profesionálnou spáčkou 😴 - - To hovoríš vždy, keď nedočiahneš na hornú policu... 🙄\nPozri na toto: - Prestaň ma odhaľovať! 😤✨\nPoužijem svoju tajnú zbraň: 💯 čistú lenivosť - Je to super efektívne! 😵‍💫 - Dnes - Konata - - %1$d odberateľov - Vlákno - - - Odstrániť nahrávku - < Potiahnutím zrušiť - Odoslať nahrávku - Uzamknúť nahrávanie - Potiahnite nahor - - - Pridať popis… - Správa - Odosielanie správ nie je povolené - - - Fotografia - Video - Nálepka - Hlasová správa - Video správa - GIF - Poloha - Správa - - - Zrušiť odpoveď - Upraviť správu - Zrušiť úpravu - Odoslať %1$d položiek - Odoslať médiá - Zrušiť - Kopírovať - Vložiť - Vystrihnúť - Vybrať všetko - Použiť - Hotovo - Obnoviť - Editor na celú obrazovku - Editor - Odoslať ticho - Naplánovať správu - Naplánované správy - Naplánované správy (%1$d) - Zatiaľ žiadne naplánované správy - Celkovo naplánovaných: %1$d - Nasledujúce odoslanie: %1$s - Teraz upraviteľných: %1$d - ID: %1$d - Upraviť - Odoslať - Odstrániť - %1$d znakov • %2$d blokov formátovania - %1$d blokov formátovania - Vyberte text a použite bohaté formátovanie ako v Telegrame - %1$d/%2$d - - Tučné - Kurzíva - Podčiarknuté - Prečiarknuté - Spoiler - Kód - Neproporcionálne - Odkaz - Zmienka - Emoji - Vymazať - Pridať odkaz - URL - Jazyk kódu - Jazyk (napr. kotlin) - - - Príkazy - - - píše - nahráva video - nahráva hlasovú správu - odosiela fotografiu - odosiela video - odosiela súbor - vyberá nálepku - hrá - Niekto - a - a %d ďalší - píšu - - %d osoba píše - %d osoby píšu - %d osôb píše - %d osôb píše - - - Fotografie - Videá - Dokumenty - Nálepky - Hudba - Hlasové správy - Video správy - Ostatné súbory - Ostatné / Vyrovnávacia pamäť - Chat %d - - - Hovory - - - Čakám na nové správy - Zastaviť - Služba na pozadí - Oznámenie o behu aplikácie na pozadí - - - Fotografia - Video - Hlasová správa - Nálepka - Dokument - Audio - GIF - Video správa - Kontakt - Anketa - Poloha - Hovor - Hra - Faktúra - Príbeh - Pripnutá správa - Správa - Bot - Online - Offline - Naposledy aktívny práve teraz - Naposledy aktívny pred %d minútou - Naposledy aktívny pred %d minútami - Naposledy aktívny o %s - Naposledy aktívny včera o %s - Naposledy aktívny %s - Naposledy aktívny nedávno - Naposledy aktívny tento týždeň - Naposledy aktívny tento mesiac - - - Pripnuté správy - Pripnutá správa - Zobraziť všetky pripnuté - Odopnúť - Zavrieť - - %d správa - %d správy - %d správ - %d správ - - - Video správa - GIF - Dokument - Anketa: %s - Nálepka %s - - - Zobrazenie - Orezať - Filtre - Kresliť - Text - Guma - - - Originál - Č&B - Sépia - Vintage - Studený - Teplý - Polaroid - Invertovať - - - Uložiť - Zrušiť - Späť - Znovu - Zavrieť - Obnoviť - Otočiť doľava - Otočiť doprava - Pridať text - Upraviť text - Použiť - Odstrániť - - - Veľkosť - Priblíženie - Napíšte niečo... - Vyberte nástroj na začatie úprav - - - Zahodiť zmeny? - Máte neuložené zmeny. Naozaj ich chcete zahodiť? - Zahodiť - - - Použiť - Hotovo - Zrušiť - Nízka - - - Zobrazenie - Orezať - Filtre - Text - Komprimovať - - - Zapnúť zvuk - Stlmiť - Pridať textový overlay - Kvalita videa - Odhadovaný bitrate: %1$d kbps - - - Originál - Č&B - Sépia - Vintage - Studený - Teplý - Polaroid - Invertovať - - - Súbor sa nenašiel - Video súbor chýba - Zahodiť zmeny? - Máte neuložené zmeny. Naozaj ich chcete zahodiť? - Zahodiť - - - Načítavam… - Webové zobrazenie - Zavrieť - Viac možností - - - Možnosti - Späť - Vpred - Obnoviť - Akcie - Nastavenia - Kopírovať - Odkaz skopírovaný - Zdieľať - Zdieľať odkaz cez - Prehliadač - Hľadať - Desktopová verzia - Blokovať reklamy - Veľkosť textu: %1$d%% - - - Zabezpečené - Nezabezpečené - Informácie o zabezpečení - Nezabezpečené pripojenie - Pripojenie k tejto stránke je šifrované a zabezpečené. - Pripojenie k tejto stránke nie je zabezpečené. Nezadávajte žiadne - citlivé informácie (napr. heslá alebo čísla kreditných kariet), pretože ich môžu ukradnúť útočníci. - - Vydané pre - Vydané kým - Platné do - Neznáme - - - Hľadať na stránke… - Predchádzajúce - Nasledujúce - Zavrieť hľadanie - - - Diskusia - Kanál - Otvoriť mapy - Trasa - Navigovať pomocou - Otvoriť pomocou - Prehliadač / Iné - Médiá - Členovia - Súbory - Audio - Hlas - Odkazy - GIFy - Žiadni členovia sa nenašli - Žiadne médiá sa nenašli - Žiadne audio sa nenašlo - Žiadne hlasové správy sa nenašli - Žiadne súbory sa nenašli - Žiadne odkazy sa nenašli - Žiadne GIFy sa nenašli - BOT - Zatvorené - ID - - - Analyzujem štatistiky... - Prehľad - Členovia - Správy - Diváci - Aktívni odosielatelia - Rast členov - Noví členovia - Obsah správ - Akcie - Aktivita podľa dňa - Aktivita podľa týždňa - Najaktívnejšie hodiny - Zobrazenia podľa zdroja - Noví členovia podľa zdroja - Jazyky - Najaktívnejší odosielatelia - správ - Priemerný počet znakov: %1$d - Najaktívnejší správcovia - akcií - Odstr.: %1$d | Zákaz: %2$d - Najaktívnejší pozývači - pozvánok - Pridaní členovia - Odberatelia - Oznámenia zapnuté - Priemerné zobrazenia správ - Priemerné zdieľania správ - Priemerné reakcie - Rast - Noví odberatelia - Zobrazenia podľa hodiny - Interakcie so správami - Interakcie s Instant View - Reakcie na správy - Nedávne interakcie - Správa - Príbeh - ID príspevku - Zobraziť menej - Zobraziť všetko (%1$d) - Príjmy - Dostupný zostatok - Celkový zostatok - Výmenný kurz - Rast príjmov - Hodinové príjmy - Prehľady načítané - Priblížiť - Vykresľujem graf... - Bez zmeny - oproti predchádzajúcemu - Neznámy typ štatistík - Trieda dát: %1$s - - - Späť - Možnosti - Pretočiť o 10 sekúnd späť - Pretočiť o 10 sekúnd vpred - -%1$ds - +%1$ds - Miniatúra %1$d - %1$d / %2$d - Načítavam pôvodnú verziu... - - - Stiahnuť - Stiahnuť video - Kopírovať obrázok - Kopírovať text - Kopírovať odkaz - Kopírovať odkaz s časom - Preposlať - Uložiť do GIFov - Uložiť do galérie - Kopírovať do schránky - Reštartovať - Pozastaviť - Prehrať - Odomknúť - - - Nastavenia - Rýchlosť prehrávania - Režim mierky - Prispôsobiť - Priblížiť - Otočiť obrazovku - Obraz v obraze - Snímka obrazovky - Opakovať video - Stlmiť zvuk - Titulky - Uzamknúť ovládacie prvky - Kvalita - Kvalita videa - Automaticky - Vysoké rozlíšenie - Normálna - - - Prehrať - Pozastaviť - Pretočiť späť - Pretočiť vpred - - - Nálepky - Emoji - GIFy - - - Nedávne nálepky - Nálepky - Hľadať nálepky - - - Nedávne emoji - Štandardné emoji - Vlastné emoji - Emoji - Hľadať emoji - - - Nedávne a uložené GIFy - Žiadne GIFy sa nenašli - Hľadať GIFy - - - Späť - Vymazať - Nedávne - - - Uložené do galérie - Zdieľať QR - Chyba pri odosielaní: %1$s - - - Upraviť kanál - Upraviť skupinu - Názov kanála - Názov skupiny - Popis - Nastavenia - Verejný kanál - Verejná skupina - Automatický preklad - Témy - Správa - Odstrániť kanál - Odstrániť skupinu - - - Hľadať... - Správcovia - Odberatelia - Členovia - Čierna listina - Žiadne výsledky - Zatiaľ žiadni členovia - - - Práva správcu - Vlastný titul - Tento titul bude viditeľný pre všetkých členov chatu - Čo môže tento správca robiť? - Spravovať chat - Zverejňovať správy - Upravovať správy - Odstraňovať správy - Obmedzovať členov - Pozývať používateľov - Spravovať témy - Spravovať videohovory - Zverejňovať príbehy - Upravovať príbehy - Odstraňovať príbehy - Pridávať nových správcov - Zostať anonymný - - - Oprávnenia - Čo môžu členovia tejto skupiny robiť? - Pridávať členov - - - Späť - Uložiť - Vymazať - Hľadať - Pridať - Upraviť - Používateľské meno - Filtre - - - Nedávne akcie - Načítaných %d udalostí - Žiadne nedávne akcie - Skúste zmeniť filtre - Nie je implementované - ID používateľa skopírované - - - Filtrovať akcie - Obnoviť - Použiť - Typy akcií - Podľa používateľov - Hľadať… - Žiadni používatelia sa nenašli - Žiadne výsledky pre „%s" - - - Úpravy - Odstránenia - Pripnutia - Pripojenia - Odchody - Pozvánky - Povýšenia - Obmedzenia - Informácie - Nastavenia - Odkazy - Video - - - upravil správu - odstránil správu - pripol správu - odopol správu - pripojil sa do chatu - opustil chat - pozval %s - zmenil oprávnenia pre %s - zmenil obmedzenia pre %s - zmenil názov chatu na „%s" - zmenil popis chatu - zmenil používateľské meno na @%s - zmenil fotografiu chatu - upravil pozývací odkaz - zrušil pozývací odkaz - odstránil pozývací odkaz - spustil videohovor - ukončil videohovor - vykonal akciu: %s - - - Pôvodná správa: - Nová správa: - Odstránená správa: - Pripnutá správa: - Odopnutá správa: - Do: %s - Obmedzený natrvalo - Stará - Nová - Stará fotografia chatu - Nová fotografia chatu - Od - Na - Zmeny oprávnení: - Aktuálne oprávnenia: - - - Správy - Médiá - Nálepky - Odkazy - Ankety - Pozvánky - Pripnúť - Informácie - - Správca - Vlastník - Obmedzený - Zablokovaný - Člen - - - Fotografia - Video - GIF - Nálepka - Dokument - Audio - Hlasová správa - Video správa - Kontakt - Anketa - Poloha - Miesto - Nepodporovaná správa - - - HH:mm - %1$02d:%2$02d - - - %1$.1f tis. - %1$.1f mil. - - - Napísať komentár - %1$d komentárov - %1$.1f tis. komentárov - %1$.1f mil. komentárov - - - Konečné výsledky - Anonymná - Verejná - Kvíz - Anketa - • Viacnásobný výber - Zrušiť hlas - Uzavrieť anketu - - %d hlas - %d hlasy - %d hlasov - %d hlasov - - - Viac - Hlasovať - Vysvetlenie - - - Hlasujúci - Zatiaľ žiadni hlasujúci - Zavrieť - - - Fotografia - Video - Nálepka - Hlasová správa - Video správa - GIF - Správa - - - Priečinky chatov - Späť - Nový priečinok - Vytvoriť - Upraviť priečinok - Uložiť - Predvolené priečinky - Vlastné priečinky - Odstrániť - Vytvorte priečinky pre rôzne skupiny chatov a rýchlo medzi nimi - prepínajte. - - Žiadne vlastné priečinky - Klepnutím na tlačidlo + vytvoríte nový - Všetky chaty - %1$d chatov - Presunúť nahor - Presunúť nadol - Názov priečinka - Vybrať ikonu - Zahrnuté chaty - Hľadať chaty… - Zrušiť - - - Telegram Premium - Späť - Prihlásiť sa za %s mesačne - Odomknúť exkluzívne funkcie - - - Zdvojené limity - Až %1$d kanálov, %2$d priečinkov chatov, %3$d pripnutých - správ, %4$d verejných odkazov a viac. - - Prevod hlasu na text - Prečítajte si prepis ľubovoľnej hlasovej správy klepnutím - na tlačidlo vedľa nej. - - Rýchlejšie sťahovanie - Žiadne obmedzenia rýchlosti sťahovania médií a - dokumentov. - - Preklad v reálnom čase - Preložte celé chaty v reálnom čase jedným klepnutím. - Animované emoji - Vkladajte animované emoji zo stoviek balíčkov do správ. - - Pokročilá správa chatov - Nástroje na nastavenie predvoleného priečinka, - automatické archivovanie a skrytie nových chatov od neznámych kontaktov. - - Bez reklám - Verejné kanály niekedy zobrazujú reklamy, ale vám sa už zobrazovať - nebudú. - - Neobmedzené reakcie - Reagujte tisíckami emoji — až 3 na správu. - Premium odznak - Špeciálny odznak vedľa vášho mena zobrazujúci, že ste - predplatiteľom Telegram Premium. - - Emoji statusy - Vyberte si z tisícok emoji na zobrazenie vedľa svojho - mena. - - Prémiové ikony aplikácie - Vyberte si ikonu aplikácie Telegram pre plochu zo širokej - ponuky. - - - - Znovu načítať - Kopírovať odkaz - Otvoriť v prehliadači - Pridať na plochu - - - Zavrieť mini aplikáciu? - Máte neuložené zmeny. Naozaj chcete zavrieť? - Zavrieť - Zrušiť - Žiadosť o oprávnenie - Povoliť - Odmietnuť - Oprávnenia bota - Podmienky služby - Spustením tejto mini aplikácie súhlasíte s Podmienkami služby a Zásadami ochrany - súkromia. Bot bude mať prístup k základným informáciám vášho profilu. - - Prijať a spustiť - - - Hľadať v článku… - Späť - Vymazať - Instant View - Viac - %d zobrazení - Kopírovať odkaz - Otvoriť v prehliadači - Hľadať - Veľkosť textu - Prehrať video - Prehrať animáciu - Audio - Neznámy interpret - Prehrať - Otvoriť - Zbaliť - Rozbaliť - Mapa: %1$s, %2$s - - - Zdieľať profil - Zdieľajte odkaz na váš profil v MonoGrame - Kopírovať odkaz - Kopírovať odkaz na váš profil v MonoGrame do schránky - - - Editor témy - Režim palety - Vyberte, ktorú paletu upravujete. Editor sa otvára na - palete, ktorá je momentálne aktívna v aplikácii. - - Svetlá - Tmavá - Úprava: paleta %1$s - Momentálne aktívna v aplikácii: %1$s - Zvýraznenie - Zvýraznenie aktualizuje iba paletu %1$s. - Hex zvýraznenie - Použiť - Zrušiť - Vybrať - Uložiť - Načítať - Obe - Hex - monogram-theme.json - - Súbor témy uložený - Uloženie zlyhalo - Téma načítaná - Neplatný súbor - Načítanie zlyhalo - - Zdroj témy - Vyberte práve jeden zdroj farieb aplikácie. Vlastná téma - používa vaše upraviteľné palety, Monet používa dynamické farby Androidu. AMOLED ovplyvňuje iba tmavé pozadie. - - Vlastná téma - Použiť vlastné svetlé/tmavé palety, zvýraznenia, predvolby - a ručne nastavené farby rolí. - - Monet - Použiť systémom generované farby Material You na základe tapety - (Android 12+). - - AMOLED tmavá - Vynútiť čisto čiernu pre tmavé plochy na zníženie žiary a - úsporu energie na OLED obrazovkách. - - - Predvolené témy - Každá predvolba má pripravené svetlé aj tmavé varianty. - Klepnutím na Svetlá, Tmavá alebo Obe ich okamžite použijete. - - Ručné farby (%1$s) - Náhľad %1$s - Súhrnný text - Akcia - Vybrať %1$s - Odtieň %1$d° - Sýtosť %1$d%% - Jas %1$d%% - Priehľadnosť %1$d%% - - Primárna - Sekundárna - Terciárna - Pozadie - Povrch - Primárny kontajner - Sekundárny kontajner - Terciárny kontajner - Variant povrchu - Obrys - - S P - S K - S P - T P - T K - T P - - Modrá - Zelená - Oranžová - Ružová - Indigo - Azúrová - - Klasická - Vyvážená modrá s čitateľnosťou a neutrálnymi plochami. - - - Les - Prírodné zelené s pokojným kontrastom a jemnými - kontajnermi. - - - Oceán - Svieži azúrovo-modrý gradient so svetlým a hlbokým tmavým - režimom. - - - Západ slnka - Teplé oranžové a koralové zvýraznenia s vysokou - čitateľnosťou. - - - Grafit - Neutrálna sivá základňa s modrosivými zvýrazneniami a - silnou štruktúrou. - - - Mäta - Svieža kombinácia mätovej a tyrkysovej s jemnými - kontajnermi. - - - Rubín - Hlboké červené zvýraznenie s neutrálnymi kontajnermi pre - silný dôraz na akcie. - - - Levanduľová sivá - Tlmená fialovo-sivá schéma s kontrolovanou - sýtosťou a čistým kontrastom. - - - Piesok - Béžová a jantárová paleta pre veľmi jemný vizuálny šum. - - - Arktická - Ľadovo bielo-modrý pocit s vysokou čitateľnosťou a - ostrými hranicami. - - - Smaragd - Živá zelená paleta s čistými plochami a moderným - kontrastom. - - - Meď - Teplá medeno-oranžová téma so zachovanou čitateľnosťou - textu v oboch režimoch. - - - Sakura - Jemné ružovo-purpurové tóny s mäkkými kontajnermi a - silnými zvýrazneniami. - - - Nord - Chladné severské modré s pokojnou a profesionálnou - vizuálnou rovnováhou. - - - - Vyžadujú sa oprávnenia pre fotoaparát a mikrofón - Spracovávam... - Chyba spracovania: %1$s - Zavrieť rekordér - Prepnúť fotoaparát - Ukončiť nahrávanie - NAH - PRIPRAVENÉ - Čas: %1$s - Priblíženie: %1$.1fx (rozsah %2$.1fx – %3$.1fx) - Zrušiť - - Vymazať históriu? - Naozaj chcete vymazať históriu chatu? Túto akciu nie je možné vrátiť - späť. - - Vymazať históriu - Odstrániť chat? - Naozaj chcete odstrániť tento chat? Túto akciu nie je možné vrátiť späť. - - Odstrániť chat - Odísť z chatu? - Naozaj chcete odísť z tohto chatu? - Odísť - Odstrániť kanál? - Odstrániť skupinu? - Naozaj chcete odstrániť tento kanál? Všetky správy a médiá budú - stratené. - - Naozaj chcete odstrániť túto skupinu? Všetky správy a médiá budú - stratené. - - Odstrániť %1$d chatov? - Naozaj chcete odstrániť vybrané chaty? - Odstrániť chaty - Blokovať používateľa? - Naozaj chcete zablokovať tohto používateľa? Tento používateľ vám nebude môcť - posielať správy. - - Blokovať - Odblokovať používateľa? - Naozaj chcete odblokovať tohto používateľa? Bude vám môcť znovu posielať - správy. - - Odipnúť správu? - Naozaj chcete odipnúť túto správu? - Odipnúť - Naozaj chcete vymazať nedávne nálepky? - Vymazať nedávne nálepky - Naozaj chcete vymazať nedávne emoji? - Vymazať nedávne emoji - Pridať do kontaktov - Odstrániť z kontaktov - Označiť ako prečítané - Označiť ako neprečítané - Upraviť - Poradie - Odstrániť - diff --git a/presentation/src/main/res/values-uk/string.xml b/presentation/src/main/res/values-uk/string.xml deleted file mode 100644 index 48cee7ec..00000000 --- a/presentation/src/main/res/values-uk/string.xml +++ /dev/null @@ -1,1858 +0,0 @@ - - - Підтвердження - Ви дійсно хочете підтвердити вхід на цьому пристрої? - Так, увійти - Скасувати - - Сканувати QR-код - Пристрої - Підключити пристрій - - Цей пристрій - Запити на вхід - Активні сеанси - - Назад - Закрити сканер - Піктограма QR-сканера - - - Підключення до Telegram… - - - Про застосунок - Назад - MonoGram - Версія %1$s - Умови використання - Ознайомтеся з умовами використання - Ліцензії - Використовуване ПЗ з відкритим кодом - GitHub - Вихідний код застосунку - Версія TDLib - %1$s (%2$s) - Спільнота - Чат підтримки - Обговорення функцій та допомога - Канал MonoGram - Новини та оновлення проєкту - Підтримати розробку - Допомогти проєкту розвиватися - Розробники - Розробник - Дизайнер - MonoGram — неофіційний клієнт Telegram на базі Material Design 3 - © 2026 MonoGram - - - Перевірити оновлення - Перевірка… - Доступне оновлення: %1$s - У Вас встановлена остання версія - Оновлення готове - Помилка при оновленні - Натисніть, щоб перевірити наявність нової версії - Підключення до сервера - Доступна нова версія для завантаження - Ви використовуєте актуальну версію - Натисніть, щоб встановити оновлення - Завантаження оновлення… - %1$d%% - Що нового у %1$s - Завантажити оновлення - Скасувати - Завантаження… - - - Ваш телефон - Перевірка - Пароль - Налаштування проксі - Ваш номер телефону - Будь ласка, підтвердьте код країни та введіть свій номер телефону. - Країна - Код - Номер телефону - 000 00 00 - Продовжити - Виберіть країну - Пошук країни або коду… - Код підтвердження надіслано через Telegram на інший Ваш пристрій. - Ми надіслали СМС із кодом підтвердження на Ваш номер. - Ми телефонуємо Вам, щоб повідомити код. - Ми надіслали код на %1$s. - Ми надіслали код підтвердження. - Підтвердити - Надіслати ще раз через %1$s - Надіслати через СМС - Зателефонувати для отримання коду - Надіслати код ще раз - Неправильний номер? - Двокрокова перевірка - Ваш акаунт захищено хмарним паролем. - Пароль - Розблокувати - Вставити - Помилка авторизації - Закрити - - - Будь ласка, зачекайте… - Завантаження триває занадто довго? - Скинути з\'єднання - - - Переслати… - Вибрано чатів: %1$d - Надіслати - Архів - Новий чат - Недавні - Очистити все - Чати та контакти - Глобальний пошук - Повідомлення - Більше результатів - Пошук чатів… - Очікування мережі… - Підключення… - Оновлення… - Підключення до проксі… - Проксі увімкнено - Проксі - Форум - Спойлер - Чернетка: - Дописів поки немає - Повідомлень поки немає - Закріплено - Згадування - Приховано з основного списку - Чатів поки немає - Почніть нову розмову - Mini App - - - MonoGram Dev - Додати акаунт - Увійти в інший акаунт - Мій профіль - Перегляд профілю - Збережене - Хмарне сховище - Налаштування - Конфігурація застосунку - Доступне оновлення - Доступна нова версія %1$s - Завантаження оновлення… %1$d%% - Оновлення готове до встановлення - Допомога - FAQ та підтримка - Політика конфіденційності - MonoGram Dev для Android v%1$s - Невідомий користувач - Немає інформації - Показати акаунти - - - Пошук повідомлень… - Очистити - Без звуку - Підтверджений акаунт - Увімкнути сповіщення - Вимкнути сповіщення - Фільтрувати рекламу - Додати до білого списку - Копіювати посилання - Очистити історію - Видалити чат - Поскаржитися - ПІДПИСАТИСЯ - Прокрутити вниз - Цю тему закрито - Прикріпити - - - Видалити повідомлення? - Видалити %1$d повідомлень? - Ви впевнені, що хочете видалити це повідомлення? - Ви впевнені, що хочете видалити ці повідомлення? - Видалити у всіх - Видалити у мене - - Чому Ви скаржитесь на це? - Ваша скарга анонімна. Ми перевіримо історію чату для забезпечення безпеки. - Подробиці скарги - Опишіть проблему… - Надіслати скаргу - Спам - Небажана реклама або шахрайство - Насильство - Погрози або пропаганда насильства - Порнографія - Неприйнятний контент або нецензурна лексика - Дитяча безпека - Контент, що завдає шкоди неповнолітнім - Авторське право - Використання чужої інтелектуальної власності - Видавання себе за іншого - Видавання себе за іншу особу або бота - Наркотики - Пропаганда продажу або вживання заборонених речовин - Порушення приватності - Поширення особистих контактних даних або адрес - Невідповідне місце - Контент не має відношення до цього місця - Інше - Щось інше, що порушує наші умови - - Обмежити користувача - Надсилання повідомлень - Надсилання медіа - Надсилання наліпок та GIF - Надсилання опитувань - Попередній перегляд посилань - Закріплення повідомлень - Зміна даних чату - Обмежити до - Назавжди - Вибрати дату - Вибрати час - Обмежити - - Відповісти - Копіювати - Закріпити - Відкріпити - Переслати - Вибрати - Ще - Видалити - Переглянути коментарі - Зберегти у завантаження - Cocoon - Підсумок - Перекласти - Створено за допомогою Telegram Cocoon - Повернути оригінальний текст - Обмежити - змінено - прочитано - перегляди - - - Невідомо - Учасники: %1$d - %1$s, %2$d в мережі - Ще не реалізовано - Пошук поки не працює - Функція «Поділитися» поки недоступна - Блокування поки недоступне - Видалення поки недоступне - Статистика - Дохід - Поділитися - Змінити - Заблокувати - Покинути - Відкрити - Повідомлення - Вступить - Поскаржитися - QR-код - Додати - Фотографія профілю - Це фото бачите тільки Ви - Відкрити Mini App - Запустити вебзастосунок бота - Прийняти умови - Перегляньте та прийміть умови обслуговування бота - Дозволи для бота - Керування правами цього бота - Ім\'я користувача - Посилання - Посилання-запрошення - Інформація про бота - Опис - Про себе - Дата народження - Місцезнаходження - Години роботи - Недавні дії - Журнал подій чату - Детальна статистика чату - Статистика доходів чату - Додав(ла) Вас до контактів - Не додав(ла) Вас до контактів - Збережено у Ваших контактах - Не збережено у Ваших контактах - Історії профілю - Ви можете публікувати історії зі свого профілю - Фон чату - Ви можете встановлювати власні фони - Голосові та відеоповідомлення - Надсилання голосових та відеоповідомлень обмежено - Повільний режим - Учасники можуть надсилати одне повідомлення кожні %1$s - Захищений контент - Пересилання та збереження обмежено - Приватне пересилання - Переслані повідомлення приховують посилання на профіль - Статистика - Адміністратори: %1$d - Обмежено: %1$d - Заблоковано: %1$d - Інформація - Сповіщення - Автовидалення - Налаштування - Зберегти - Спам - Насильство - Порнографія - Жорстоке поводження з дітьми - Порушення авторських прав - Інше - Закрити - Запускаючи цей Mini App, Ви погоджуєтесь з Умовами обслуговування та Політикою конфіденційності. Бот зможе отримати доступ до Вашої основної інформації профілю. - Прийняти та запустити - - - QR-код - Поділитися - MonoGram — безкоштовний проєкт із відкритим кодом. Ваша підтримка допомагає нам розвивати застосунок та додавати нові функції. - Бейдж спонсора з сердечком надається з рівня підтримки Advanced або за - еквівалентну підтримку від 150 ₽ (приблизно $1.96). - - Підтримати на Boosty - Можливо, пізніше - Змінити профіль - Довге натискання, щоб приховати - Утримуйте, щоб показати, натисніть для копіювання - Ваш ID - Ім\'я, інформація про себе та фото профілю - Увімкнути посилання t.me - Відкривати посилання Telegram всередині застосунку - Загальні налаштування - Налаштування чатів - Теми, розмір тексту, відеопрогравач - Приватність і безпека - Код-пароль, сеанси, приватність - Сповіщення та звуки - Повідомлення, групи, дзвінки - Дані та пам\'ять - Використання мережі, автозавантаження - Енергоощадність - Налаштування економії заряду - Папки - Керування папками з чатами - Наліпки та емодзі - Набори наліпок та емодзі - Приєднані пристрої - Мова - Англійська - Проксі - MTProto, SOCKS5, HTTP - Telegram Premium - Ексклюзивні функції - Допомога в розвитку проєкту - Підтримав MonoGram - Цей користувач підтримує проєкт і допомагає нам розвиватися - Версія та інформація про MonoGram - Налагодження - Параметри для розробників - Показати вікно спонсора - Відкрити нижню панель з інформацією про спонсора - Примусова синхронізація спонсорів - Завантажити ID спонсорів із каналу зараз - Вийти - Завершити сеанс - - - Імена користувача - Повторіть спробу через %1$d с - Активні імена - Вимкнені імена - Колекційні імена - Готово - ОК - Виберіть час початку - Виберіть час завершення - Години роботи - Робочі дні - Діапазон часу - Від - До - Адреса компанії - Адреса - Підтвердити місцезнаходження - Змінити профіль - Ім\'я (обов\'язково) - Прізвище (необов\'язково) - Про себе - Ви можете додати трохи інформації про себе. Вона буде видна у Вашому профілі. - Ім\'я користувача - Ви можете вибрати ім\'я користувача в Telegram. Якщо Ви це зробите, люди зможуть знайти Вас за цим ім\'ям і зв\'язатися з Вами, не знаючи Вашого номера телефону. - День народження - Дата народження - Telegram для бізнесу - ID приєднаного каналу - Опис бізнесу - Адреса бізнесу - Геопозиція - Години роботи - З підпискою Premium Ви можете приєднати канал та додати відомості про бізнес у свій профіль. - Не вказано - (%1$d дн.) - Пн - Вт - Ср - Чт - Пт - Сб - Нд - - - Конфіденційність - Приватність - Чорний список - Користувачів: %1$d - Немає - Номер телефону - Остання активність - Фотографії профілю - Пересилання повідомлень - Дзвінки - Групи та канали - Безпека - Код-пароль - Увімк. - Вимк. - Розблокування біометрією - Використовувати відбиток пальця або обличчя - Активні сеанси - Керування пристроями - Вміст делікатного характеру - Вимкнути фільтрацію - Відображати делікатний вміст у публічних каналах на всіх Ваших пристроях. - Додатково - Видалити мій акаунт - Якщо я не заходив %1$s - Видалити акаунт зараз - Безповоротно видалити акаунт і всі дані - Якщо я не заходжу… - Видалити акаунт - Ви впевнені, що хочете видалити свій акаунт? Ця дія є незворотною, всі дані буде втрачено. - Усі - Мої контакти - Ніхто - 1 місяць - 3 місяці - 6 місяців - 1 рік - 18 місяців - 2 роки - %1$d міс. - %1$d дн. - Видалення за запитом користувача - - - Налаштування проксі - Оновити затримку - Додати проксі - Підключення - Розумне перемикання - Автоматично вибирати найшвидший проксі - Віддавати перевагу IPv6 - Використовувати IPv6 за наявності - Вимкнути проксі - Пряме підключення - Перемкнутися на пряме з\'єднання - Telega Proxy - Telega Proxy звинувачували у перехопленні трафіку. MTProto захищає дані повідомлень від перехоплення, але використовуйте цей проксі на власний ризик. Докладніше: t.me/telegaru - Увімкнути Telega Proxy - Автоматичне отримання та перемикання - Оновити список - Отримати актуальні проксі від спільноти - Ваші проксі - Очистити офлайн - Видалити всі - Видалити офлайн-проксі - Ця дія видалить усі проксі, які зараз недоступні. Продовжити? - Видалити всі проксі - Ця дія видалить усі налаштовані проксі з застосунку. Продовжити? - Немає доданих проксі - Видалити проксі - Ви впевнені, що хочете видалити проксі %1$s? - Новий проксі - Змінити проксі - Адреса сервера - Порт - Секрет (Hex) - Ім\'я користувача (опціонально) - Пароль (опціонально) - Зберегти зміни - Перевірити - Результат перевірки - Видалити - 檢查中... - 離線 - %1$dms - - - Ваші імена користувача - Додатково - - - Сповіщення та звуки - Сповіщення про повідомлення - Особисті чати - Групи - Канали - Налаштування сповіщень - Вібрація - Пріоритет - Повтор сповіщень - Тільки відправник - Приховувати текст повідомлення у сповіщеннях - Push-служба - Провайдер Push-сповіщень - Фонова служба - Робота застосунку у фоні для надійної доставки сповіщень - Приховати сповіщення служби - Приховати сервісне сповіщення. Може призвести до завершення роботи системою - Сповіщення у застоспонку - Звуки у застосунку - Вібрація у застосунку - Попередній перегляд - Події - Контакт приєднався до Telegram - Закріплені повідомлення - Скинути всі сповіщення - Скинути всі персональні налаштування сповіщень для контактів та груп - Тип вібрації - Пріоритет сповіщень - %1$s, винятків: %2$d - Стандартна - Коротка - Довга - Вимкнена - Низький - Стандартний - Високий - Ніколи - Кожні %1$d хв. - Щогодини - Кожні %1$d год. - Firebase Cloud Messaging - Без GMS (фонова служба) - - - Налаштування чатів - Зовнішній вигляд - Розмір тексту повідомлень - Міжлітерний інтервал повідомлень - Скруглення блоків - Скинути - Шпалери чату - Скинути шпалери - Стиль емодзі - Тема - Нічний режим - Системна - Світла - Темна - За розкладом - Автоматично - Поточний режим - Зараз: %1$s - Поріг яскравості: %1$d%% - Перемикання на темну тему при яскравості нижче цього рівня. - Динамічні кольори - Динамічні кольори - Використовувати системну палітру (Material You) - Дані та пам\'ять - Стискати фотографії - Зменшувати розмір фото перед надсиланням - Стискати відео - Зменшувати розмір відео перед надсиланням - Відеопрогравач - Увімкнути жести - Гучність та яскравість свайпами по екрану - Перемотка подвійним натисканням - Натискання по краях відео для перемотки - Інтервал перемотки - Масштабування - Збільшення відео жестом щипка - Список чатів - Закріпити архів - Архів завжди на початку списку чатів - Завжди показувати архів - Не приховувати закріплений архів при прокручуванні - Попередній перегляд посилань - Відображати прев\'ю для посилань у повідомленнях - Свайп для повернення - Повернення назад свайпом від лівого краю - Дві рядки - Три рядки - Показувати фотографії - Фото профілю у списку чатів - Експериментальні функції - AdBlock для каналів - Приховувати рекламні дописи в каналах - Недавні медіа - Очистити недавні наліпки - Видалити список недавно використаних наліпок - Очистити недавні емодзі - Видалити список недавно використаних емодзі - Видалити набір емодзі - Видалити набір «%1$s»? - Завантажений набір емодзі буде видалено з пристрою. Його можна буде завантажити знову. - Змінити свою тему - Вибрано - Apple - Twitter - Windows - Catmoji - Noto - Системні - - - Дані та пам\'ять - Використання пам\'яті та мережі - Використання сховища - Керування локальним кешем - Використання мережі - Обсяг надісланих та отриманих даних - Автозавантаження медіа - Через мобільну мережу - Через Wi-Fi - У роумінгу - Файли - Автоматично завантажувати вхідні файли - Наліпки - Автоматично завантажувати наліпки - Відеоповідомлення - Автоматично завантажувати відеоповідомлення - Автопрогравання - GIF-анімації - У списку чатів та в самих чатах - Відео - Усередині діалогів та груп - Увімкнено - Вимкнено - - - Енергоощадність - Батарея - Режим енергоощадності - Обмеження фонової активності для економії заряду - Оптимізація батареї - Агресивне обмеження фонової роботи - Wake Lock - Дозволити ЦП працювати у фоні. Вимкніть для економії заряду - Анімації - Анімації у чаті - Вимкнути для продовження роботи від акумулятора - Фон - Вимкнення може призвести до затримки сповіщень - - - Наліпки та емодзі - Наліпки - Емодзі - Недавні наліпки - Набори наліпок - Архівні наліпки - Створити свої наліпки - За допомогою офіційного бота @Stickers - Набори наліпок не встановлено - Наліпки за запитом «%1$s» не знайдено - Недавні емодзі - Набори емодзі - Архівні емодзі - Створити свої емодзі - За допомогою офіційного бота @Stickers - Очистити недавні емодзі - Видалити список недавно використаних емодзі - Набори емодзі не встановлено - Емодзі за запитом «%1$s» не знайдено - Пошук наборів - Пошук - - %1$d наліпка - %1$d наліпки - %1$d наліпок - %1$d наліпок - - - %1$d емодзі - %1$d емодзі - %1$d емодзі - %1$d емодзі - - Маски - Емодзі - Офіційний - Посилання скопійовано - - - Використання мережі - Скинути статистику - Статистика мережі - Контроль трафіку. Вимкнення заощаджує місце на диску. - Статистика вимкнена - Увімкніть відстеження, щоб бачити витрати трафіку в мережах. - Усього використано - Надіслано - Отримано - Огляд - Витрати трафіку - Немає даних про використання - Статистика недоступна - Мобільна мережа - Wi-Fi - Роумінг - Інше - - - Використання сховища - Очистити весь кеш • %1$s - Включає медіафайли з усіх Ваших чатів. - Максимальний розмір кешу - Зберігати медіа - Оптимізатор сховища - Фонова очистка пам\'яті - Подробиці - Пам\'ять вільна - Кешовані файли не знайдено. - Очистити кеш - Очистити кеш для «%1$s»? Буде звільнено %2$s. - Очистити весь кеш - Це видалить усі кешовані медіафайли з усіх чатів. Продовжити? - Без обмежень - Завжди - 1 день - 1 тиждень - 1 місяць - Усього використано - Файлів: %1$d - Файлів: %1$d - - - Хто може додавати мене в групи? - Хто може мені телефонувати? - Хто бачить час мого останнього входу? - Хто бачить мої фотографії профілю? - Хто бачить мою інформацію «Про себе»? - Хто може посилатися на мій акаунт при пересиланні моїх повідомлень? - Хто може додавати мене до груп та каналів? - Хто може бачити мій номер телефону? - Хто може знайти мене за номером? - Користувачі, які зберегли Ваш номер, побачать його в Telegram, тільки якщо це дозволено налаштуванням вище. - Додати винятки - Завжди дозволяти - Ніколи не дозволяти - Об\'єктів: %1$d - (видалений) - Учасники чату - Пошук за номером - Список порожній - Заблоковані користувачі не зможуть Вам писати та бачити Вашу мережеву активність. - Розблокувати - Заблокувати - Пошук користувачів - Користувачів не знайдено - - - Змінити код-пароль - Встановити код-пароль - Ваш застосунок захищено кодом. Введіть новий код. - Введіть 4-значний код для захисту застосунку. - Код-пароль - Поточний код-пароль - Зберегти - Вимкнути код-пароль - Підтвердити код-пароль - Перш ніж змінити або вимкнути код-пароль, введіть поточний. - Неправильний код-пароль. - - - Додати ключове слово - Увімкнути AdBlock - Білий список каналів - Дозволено каналів: %1$d - Завантажити базу слів - Імпорт стандартних рекламних ключів - Копіювати список - Скопіювати всі ключі в буфер обміну - Очистити список - Видалити всі ключові слова - Ключеві слова для фільтрації - Список порожній - Натисніть «+», щоб додати слова для фільтрації - Додати слова - Введіть слова через кому або з нового рядка. - напр. #реклама, ad, promo - Додати до списку - Дописи в цих каналах не фільтруватимуться - Список порожній - Видалити - - - був(ла) нещодавно - був(ла) щойно - - був(ла) %1$d хвилину тому - був(ла) %1$d хвилини тому - був(ла) %1$d хвилин тому - був(ла) %1$d хвилин тому - - був(ла) о %1$s - був(ла) вчора о %1$s - був(ла) %1$s - був(ла) цього тижня - був(ла) цього місяця - був(ла) дуже давно - у мережі - не в мережі - бот - Ім\'я користувача - Наліпок: %1$d - В архіві - Додати - Розархівувати - В архів - Видалити набір - - - Нове повідомлення - Додати учасників - Нова група - Новий канал - Контактів: %1$d - %1$d / 200000 - Вибрано: %1$d - Пошук контактів… - Контакти не знайдено - Немає результатів для "%1$s" - За часом відвідування - Створити групу - Створити канал - Підтримка - Канали — це інструмент для трансляції Ваших повідомлень необмеженій аудиторії. - Дані каналу - Назва каналу - Опис (необов\'язково) - Автовидалення повідомлень - Вимкнено - 1 день - 2 дні - 3 дні - 4 дні - 5 днів - 6 днів - 1 тиждень - 2 тижні - 3 тижні - 1 місяць - 2 місяці - 3 місяці - 4 місяці - 5 місяців - 6 місяців - 1 рік - Ви можете додати опис каналу. Будь-хто зможе приєднатися до Вашого каналу, якщо матиме посилання. - Вкажіть назву та додайте фото для Вашої нової групи. - Дані групи - Назва групи - Введіть назву групи - Введіть назву каналу - Відкрити профіль - Змінити ім’я - Видалити контакт - Редагування контакту - Ім’я - Прізвище - Видалити контакт? - Ви впевнені, що хочете видалити %1$s з контактів? - Автоматично видаляти нові повідомлення в цій групі через певний час. - Додати фото - Змінити фото - - - Необхідні дозволи - Для забезпечення найкращого досвіду MonoGram потребує наступних дозволів. - Сповіщення - Отримуйте сповіщення про нові повідомлення - Дозволити - Стан телефону - Керування станом пристрою для найкращого досвіду - Оптимізація батареї - Забезпечення надійної фонової роботи - Вимкнути - Камера - Робіть фото та записуйте відеоповідомлення - Мікрофон - Записуйте голосові та відеоповідомлення - Місцезнаходження - Діліться місцезнаходженням та знаходьте користувачів поруч - - - Очистити виділення - Закріпити - - - Команди бота - Виберіть команду, щоб надіслати боту - - - Список чатів - Коната Ідзумі - Я не маленька, я просто концентрована крутість! 🍫 А ще я вирішила стати професійною сплюхою 😴 - 12:45 - Кагамі Хііраґі - Не забудь про домашку! Тобі треба здати її завтра вранці, і вона досить складна. - 11:20 - - - Попередній перегляд - Я - Я не маленька, я просто концентрована крутість! 🍫\nА ще я вирішила стати професійною сплюхою 😴 - Ти так кажеш кожного разу, коли не можеш дотягнутися до верхньої полиці... 🙄\nГлянь на це: ось - Досить мене викривати! 😤✨\nЯ просто використаю свою секретну зброю: 💯 чиста лінь - Це надзвичайно ефективно! 😵‍💫 - Сьогодні - Коната - - %1$d підписників - Гілка - - - Видалити запис - < Проведіть для скасування - Надіслати запис - Заблокувати запис - Проведіть вгору - - - Додати підпис… - Повідомлення - Надсилання повідомлень заборонено - - - Фото - Відео - Наліпка - Голосове повідомлення - Відеоповідомлення - GIF - Локація - Повідомлення - - - Скасувати відповідь - Редагувати повідомлення - Скасувати редагування - Надіслати %1$d об’єктів - Надіслати медіа - Скасувати - Копіювати - Вставити - Вирізати - Виділити все - Застосувати - Готово - Оновити - Повноекранний редактор - Редактор - Надіслати без звуку - Відкласти повідомлення - Відкладені повідомлення - Відкладені повідомлення (%1$d) - Поки немає відкладених повідомлень - Усього відкладено: %1$d - Найближча відправка: %1$s - Можна редагувати: %1$d - ID: %1$d - Змінити - Надіслати - Видалити - - Жирний - Курсив - Підкреслений - Перекреслений - Спойлер - Код - Моноширинний - Посилання - Згадати - Емодзі - Очистити - Додати посилання - URL - Мова коду - Мова (наприклад, kotlin) - - %1$d символів • %2$d блоків форматування - %1$d блоків форматування - Виділіть текст, щоб застосувати форматування як у Telegram - %1$d/%2$d - - - Команди - - - друкує - записує відео - записує голосове - надсилає фото - надсилає відео - надсилає файл - вибирає стікер - грає - Хтось - і - і ще %d - друкують - - %d людина друкує - %d людини друкують - %d людей друкують - %d людей друкують - - - - Фотографії - Відео - Документи - Стікери - Музика - Голосові повідомлення - Відеоповідомлення - Інші файли - Інше / Кеш - Чат %d - - - Дзвінки - - - Очікування нових повідомлень - Зупинити - Фонова робота - Сповіщення про роботу програми у фоновому режимі - - - 📷 Фото - 📹 Відео - 🎤 Голосове повідомлення - 🧩 Стікер - 📎 Документ - 🎵 Аудіо - GIF - 🎬 Відеоповідомлення - 👤 Контакт - 📊 Опитування - 📍 Геолокація - 📞 Дзвінок - 🎮 Гра - 💳 Рахунок - 📚 Історія - 📌 Закріплене повідомлення - Повідомлення - Бот - В мережі - Не в мережі - був(ла) щойно - був(ла) %d хвилину тому - був(ла) %d хвилин тому - був(ла) о %s - був(ла) вчора о %s - був(ла) %s - був(ла) нещодавно - був(ла) на цьому тижні - був(ла) в цьому місяці - - - Закріплені повідомлення - Закріплене повідомлення - Показати всі закріплені - Відкріпити - Закрити - - %d повідомлення - %d повідомлення - %d повідомлень - %d повідомлень - - - - Відеоповідомлення - GIF - Документ - Опитування: %s - Стікер %s - - - Перегляд - Обрізка - Фільтри - Малювання - Текст - Ластик - - - Оригінал - Ч/Б - Сепія - Вінтаж - Холодний - Теплий - Полароїд - Інверсія - - - Зберегти - Скасувати - Відмінити - Повторити - Закрити - Скинути - Поворот ліворуч - Поворот праворуч - Додати текст - Змінити текст - Застосувати - Видалити - - - Розмір - Масштаб - Введіть текст... - Оберіть інструмент для редагування - - - Відхилити зміни? - У вас є незбережені зміни. Ви впевнені, що хочете їх видалити? - Відхилити - - - Застосувати - Готово - Скасувати - Низька - - - Перегляд - Обрізка - Фільтри - Текст - Стиснення - - - Увімкнути звук - Вимкнути звук - Додати текст - Якість відео - Очікуваний бітрейт: %1$d кбіт/с - - - Оригінал - Ч/Б - Сепія - Вінтаж - Холодний - Теплий - Полароїд - Інверсія - - - Файл не знайдено - Відеофайл відсутній - Відхилити зміни? - Ви маєте незбережені зміни. Ви впевнені, що хочете їх відхилити? - Відхилити - - - Завантаження… - Веб-перегляд - Закрити - Більше - - - Опції - Назад - Вперед - Оновити - Дії - Налаштування - Копіювати - Посилання скопійовано - Поділитися - Поділитися через - Браузер - Пошук - Версія для ПК - Блок реклами - Розмір тексту: %1$d%% - - - Безпечно - Небезпечно - Безпека - Незахищене з’єднання - З’єднання з цим сайтом зашифроване та безпечне. - З’єднання з цим сайтом не є безпечним. Вам не слід вводити конфіденційну інформацію (паролі чи картки), оскільки її можуть викрасти зловмисники. - Кому виданий - Ким виданий - Дійсний до - Невідомо - - - Пошук на сторінці… - Попер. - Наст. - Закрити пошук - - - Обговорення - Канал - Відкрити карти - Маршрути - Використовувати для навігації - Відкрити за допомогою - Браузер / Інше - Медіа - Учасники - Файли - Музика - Голос - Посилання - GIF - Учасників не знайдено - Медіа не знайдено - Аудіозаписів не знайдено - Голосових повідомлень не знайдено - Файлів не знайдено - Посилань не знайдено - GIF не знайдено - БОТ - Зачинено - ID - - - Аналіз статистики… - Огляд - Учасники - Повідомлення - Глядачі - Активні відправники - Ріст аудиторії - Нові учасники - Тип контенту - Дії - Активність за днями - Активність за тижнями - Популярні години - Джерела переглядів - Джерела нових учасників - Мови - Топ учасників - повід. - Сер. к-сть символів: %1$d - Топ адміністраторів - дій - Видал: %1$d | Бан: %2$d - Топ тих, хто запрошує - запрошень - Додано учасників - Підписники - Сповіщення ввімкнено - Сер. кількість переглядів - Сер. кількість пересилань - Сер. кількість реакцій - Ріст - Нові підписники - Перегляди за годинами - Взаємодія з повідомленнями - Взаємодія з Instant View - Реакції на повідомлення - Останні взаємодії - Повідомлення - Розповідь - ID поста - Згорнути - Показати всі (%1$d) - Дохід - Доступний баланс - Загальний баланс - Курс обміну - Ріст доходу - Погодинний дохід - Дані завантажено - Збільшити - Побудова графіка… - Без змін - порівняно з минулим пер. - Невідомий тип статистики - Клас даних: %1$s - - - Назад - Опції - Перемотати на 10 секунд назад - Перемотати на 10 секунд вперед - -%1$ds - +%1$ds - Мініатюра %1$d - %1$d із %2$d - Завантажується оригінал... - - - Завантажити - Завантажити відео - Копіювати зображення - Копіювати текст - Копіювати посилання - Копіювати посилання з часом - Переслати - Зберегти у GIF - У галерею - У буфер обміну - Почати спочатку - Пауза - Відтворити - Розблокувати - - - Налаштування - Швидкість відтворення - Режим масштабування - Вписати - Заповнити - Поворот екрана - Картинка в картинці - Скріншот - Зациклити відео - Вимкнути звук - Субтитри - Заблокувати керування - Якість - Якість відео - Авто - Висока - Звичайна - - - Грати - Пауза - Назад - Вперед - - - Стікери - Емодзі - GIF - - - Нещодавні стікери - Стікери - Пошук стікерів - - - Нещодавні емодзі - Стандартні емодзі - Авторські емодзі - Емодзі - Пошук емодзі - - - Нещодавні та збережені - GIF не знайдено - Пошук GIF - - - Назад - Очистити - Нещодавні - - - Збережено до галереї - Поділитися QR - Помилка при надсиланні: %1$s - - - Редагувати канал - Редагувати групу - Назва каналу - Назва групи - Опис - Налаштування - Публічний канал - Публічна група - Автопереклад - Теми - Керування - Видалити канал - Видалити групу - - - Пошук... - Адміністратори - Підписники - Учасники - Чорний список - Нічого не знайдено - Учасників поки немає - - - Права адміна - Посада - Цей підпис бачитимуть усі учасники в чаті - Що може робити цей адмін? - Керування чатом - Надсилання повідомлень - Редагування повідомлень - Видалення повідомлень - Блокування учасників - Додавання учасників - Керування темами - Керування відеочатами - Публікація розповідей - Редагування розповідей - Видалення розповідей - Призначення адміністраторів - Анонімність - - - Дозволи - Що можуть робити учасники цієї групи? - Додавання учасників - - - Назад - Зберегти - Очистити - Пошук - Додати - Редагувати - Ім’я користувача - Фільтри - - - Недавні дії - Завантажено подій: %d - Дій не знайдено - Спробуйте змінити фільтри - Не реалізовано - ID користувача скопійовано - - - Фільтри - Скинути - Застосувати - Типи дій - За учасниками - Пошук… - Користувачів не знайдено - Немає результатів за запитом «%s» - - - Правки - Видалення - Закріплення - Входи - Виходи - Запрошення - Підвищення - Обмеження - Інфо - Налаштування - Посилання - Відео - - - відредагував(ла) повідомлення - видалив(ла) повідомлення - закріпив(ла) повідомлення - відкріпив(ла) повідомлення - приєднався(лася) до чату - покинув(ла) чат - запросив(ла) %s - змінив(ла) дозволи для %s - змінив(ла) обмеження для %s - змінив(ла) назву чату на «%s» - змінив(ла) опис чату - змінив(ла) ім\'я користувача на @%s - змінив(ла) фото чату - змінив(ла) посилання для запрошення - відкликав(ла) посилання для запрошення - видалив(ла) посилання для запрошення - розпочав(ла) відеочат - завершив(ла) відеочат - виконав(ла) дію: %s - - - Старе повідомлення: - Нове повідомлення: - Видалене повідомлення: - Закріплене повідомлення: - Відкріплене повідомлення: - До: %s - Обмежено назавжди - Було - Стало - Старе фото чату - Нове фото чату - З - На - Зміни дозволів: - Поточні дозволи: - - - Повідомлення - Медіа - Стікери - Посилання - Опитування - Запрошення - Закріплення - Дані - - Адмін - Власник - Обмежений - Забанений - Учасник - - - Фото - Відео - GIF - Стікер - Файл - Аудіо - Голосове повідомлення - Відеоповідомлення - Контакт - Опитування - Геопозиція - Місце - Непідтримуване повідомлення - - - HH:mm - %1$02d:%2$02d - - - %1$.1fK - %1$.1fM - - - Залишити коментар - %1$d коментарів - %1$.1fK коментарів - %1$.1fM коментарів - - - Остаточні результати - Анонімне опитування - Публічне опитування - Вікторина - Опитування - • Вибір кількох варіантів - Скасувати голос - Зупинити опитування - - %d голос - %d голоси - %d голосів - %d голосу - - - - Більше - Голосувати - Пояснення - - - Проголосували - Ще ніхто не проголосував - Закрити - - - Фотографія - Відео - Стікер - Голосове повідомлення - Відеоповідомлення - GIF - Повідомлення - - - Папки з чатами - Назад - Нова папка - Створити - Редагувати папку - Зберегти - Стандартні папки - Власні папки - Видалити - Створюйте папки для різних груп чатів і швидко перемикайтеся між ними. - У Вас немає папок - Натисніть на «+», щоб створити нову - Усі чати - %1$d чатів - Перемістити вгору - Перемістити вниз - Назва папки - Вибрати іконку - Додані чати - Пошук чатів… - Скасувати - - - Telegram Premium - Назад - Підписатися за %s на місяць - Розблокуйте ексклюзивні функції - - - Подвоєні ліміти - До %1$d каналів, %2$d папок, %3$d закріплень, %4$d публічних посилань та інше. - Розшифровка голосу - Читайте текстову версію будь-якого голосового повідомлення одним натисканням. - Швидке завантаження - Більше жодних обмежень на швидкість завантаження медіа та документів. - Переклад у реальному часі - Миттєвий переклад цілих чатів одним дотиком. - Анімовані емодзі - Використовуйте анімовані емодзі з сотень наборів у своїх повідомленнях. - Керування чатами - Інструменти для вибору папки за замовчуванням, автоархівування та приховування нових чатів. - Без реклами - У публічних каналах іноді показується реклама, але вона більше не з’явиться для вас. - Активні реакції - Тисячі емодзі для реакцій — до 3 на одне повідомлення. - Значок підписника - Спеціальний значок поруч із вашим ім’ям, що підтверджує підписку. - Емодзі-статуси - Вибирайте з тисяч емодзі, щоб відобразити їх поруч із вашим ім’ям. - Іконки додатка - Виберіть одну з ексклюзивних іконок Telegram для головного екрана. - - - Оновити - Копіювати посилання - Відкрити у браузері - На головний екран - - - Закрити застосунок? - У вас є незбережені зміни. Ви впевнені, що хочете закрити мінідодаток? - Закрити - Скасувати - Запит на дозвіл - Дозволити - Відхилити - Дозволи бота - Умови використання - Запускаючи цей мінідодаток, ви погоджуєтеся з Умовами надання послуг та Політикою конфіденційності. Бот отримає доступ до основної інформації вашого профілю. - Прийняти та запустити - - - Пошук у статті… - Назад - Очистити - Швидкий перегляд - Ще - %d переглядів - Копіювати посилання - Відкрити у браузері - Пошук - Розмір тексту - Відтворити відео - Відтворити анімацію - Аудіо - Невідомий виконавець - Відтворити - Відкрити - Згорнути - Розгорнути - Мапа: %1$s, %2$s - - - Поділитися профілем - Поділитися посиланням на ваш профіль у Monogram - Копіювати посилання - Копіювати посилання на профіль Monogram у буфер обміну - - - Редактор тем - Режим палітри - Виберіть палітру для редагування. За замовчуванням відкривається палітра, яка зараз активна в застосунку. - Світла - Темна - Редагується: палітра %1$s - Зараз активна в застосунку: %1$s - Акцент - Акцент змінює лише палітру %1$s. - Hex-акцент - Застосувати - Скасувати - Вибрати - Зберегти - Завантажити - Обидві - Hex - monogram-theme.json - - Файл теми збережено - Помилка збереження - Тему завантажено - Некоректний файл - Помилка завантаження - - Джерело теми - Виберіть одне джерело кольорів. «Своя тема» використовує ваші палітри, «Monet» — динамічні кольори Android. «AMOLED» впливає лише на темний режим. - Своя тема - Використовуйте власні палітри, акценти, пресети та ручне налаштування ролей. - Monet - Кольори Material You на основі шпалер системи (Android 12+). - AMOLED (чорний) - Чистий чорний колір для зменшення світіння та економії заряду на OLED-екранах. - - Готові теми - Кожен пресет має світлий та темний варіанти. Натисніть «Світла», «Темна» або «Обидві», щоб застосувати їх. - Ручні кольори (%1$s) - Перегляд: %1$s - Приклад тексту - Дія - Вибір: %1$s - Відтінок %1$d° - Насиченість %1$d%% - Яскравість %1$d%% - Прозорість %1$d%% - - Основний - Вторинний - Третинний - Фон - Поверхня - Контейнер осн. - Контейнер втор. - Контейнер трет. - Варіант пов. - Контур - - С О - С К - С Ф - Т О - Т К - Т Ф - - Синій - Зелений - Помаранчевий - Рожевий - Індиго - Блакитний - - Класика - Збалансований синій з високою читабельністю та нейтральним фоном. - - Ліс - Натуральні зелені тони зі спокійним контрастом. - - Океан - Свіжий синьо-блакитний градієнт з глибоким темним режимом. - - Захід сонця - Теплі помаранчеві та коралові акценти з чітким текстом. - - Графіт - Нейтральна сіра база з синьо-сірими акцентами. Строгий стиль. - - М’ята - Поєднання м’яти та морської хвилі з м’якими переходами. - - Рубін - Глибокі червоні акценти для фокусу на важливих діях. - - Лаванда - Приглушений фіолетово-сірий стиль з чистим контрастом. - - Пісок - Бежева та бурштинова палітра для мінімальної напруги очей. - - Арктика - Крижаний синьо-білий стиль з дуже чіткими межами. - - Смарагд - Яскрава зелена палітра з чистими поверхнями та сучасним контрастом. - - Мідь - Тепла мідно-помаранчева тема з чітким текстом в обох режимах. - - Сакура - М’які рожево-пурпурні тони з делікатними контейнерами та виразними акцентами. - - Норд - Прохолодні північні сині відтінки зі спокійним професійним балансом. - - Потрібні дозволи на камеру та мікрофон - Обробка... - Помилка обробки: %1$s - Закрити запис - Перемкнути камеру - Завершити запис - REC - ГОТОВО - Час: %1$s - Зум: %1$.1fx (діапазон %2$.1fx - %3$.1fx) - Скасувати - - Очистити історію? - Ви впевнені, що хочете очистити історію чату? Цю дію неможливо скасувати. - Очистити історію - Видалити чат? - Ви впевнені, що хочете видалити цей чат? Цю дію неможливо скасувати. - Видалити чат - Покинути чат? - Ви впевнені, що хочете покинути цей чат? - Покинути - Видалити канал? - Видалити групу? - Ви впевнені, що хочете видалити цей канал? Усі повідомлення та медіа буде втрачено. - Ви впевнені, що хочете видалити цю групу? Усі повідомлення та медіа буде втрачено. - Видалити %1$d чатів? - Ви впевнені, що хочете видалити вибрані чати? - Видалити чати - Заблокувати користувача? - Ви впевнені, що хочете заблокувати цього користувача? Він не зможе надсилати вам повідомлення. - Заблокувати - Розблокувати користувача? - Ви впевнені, що хочете розблокувати цього користувача? Він знову зможе - надсилати вам повідомлення. - - Відкріпити повідомлення? - Ви впевнені, що хочете відкріпити це повідомлення? - Відкріпити - Ви впевнені, що хочете очистити нещодавні стікери? - Очистити стікери - Ви впевнені, що хочете очистити нещодавні емодзі? - Очистити емодзі - Додати до контактів - Видалити з контактів - Позначити як прочитане - Позначити як непрочитане - Змінити - Порядок - Видалити - diff --git a/presentation/src/main/res/values-zh-rCN/string.xml b/presentation/src/main/res/values-zh-rCN/string.xml deleted file mode 100644 index 22ded357..00000000 --- a/presentation/src/main/res/values-zh-rCN/string.xml +++ /dev/null @@ -1,1841 +0,0 @@ - - - 确认 - 您确定要授权此设备吗? - 是,登录 - 取消 - - 扫描二维码 - 设备 - 关联设备 - - 此设备 - 登录请求 - 活跃会话 - - 返回 - 关闭扫描器 - 二维码扫描图标 - - - 正在连接 Telegram… - - - 关于 - 返回 - MonoGram - 版本 %1$s - 服务条款 - 阅读我们的条款和条件 - 开源许可 - MonoGram 使用的软件 - GitHub - 查看源代码 - TDLib 版本 - %1$s (%2$s) - 社区 - Telegram 群组 - 加入我们的社区讨论功能并获取帮助 - Telegram 频道 - 获取最新消息和公告 - 支持 MonoGram - 支持开发并帮助我们维持项目 - 维护者 - 开发者 - 设计师 - MonoGram 是一款基于 Material Design 3 构建的非官方 Telegram 客户端 - © 2026 MonoGram - - - 检查更新 - 正在检查… - 有可用更新: %1$s - 已是最新版本 - 更新已就绪 - 更新错误 - 点击检查新版本 - 正在连接服务器 - 有新版本可供下载 - 您正在使用最新版本 - 点击安装更新 - 正在下载更新… - %1$d%% - %1$s 的更新内容 - 下载更新 - 取消 - 加载中… - - - 您的手机 - 验证码 - 密码 - 代理设置 - 您的手机号码 - 请确认您的国家代码并输入手机号码。 - 国家 - 代码 - 手机号码 - 000 00 00 - 继续 - 选择国家 - 搜索国家或代码… - 我们已通过 Telegram 发送验证码到您的其他设备。 - 我们已通过短信发送验证码。 - 我们正在拨打您的电话以告知验证码。 - 我们已将验证码发送至 %1$s。 - 我们已发送验证码。 - 确认 - %1$s 后重新发送 - 通过短信重新发送 - 通过电话重新发送 - 重新发送验证码 - 号码错误? - 两步验证 - 您的账号受附加密码保护。 - 密码 - 解锁 - 粘贴 - 认证错误 - 关闭 - - - 请稍候 - 加载时间过长? - 重置连接 - - - 转发至… - 已选择 %1$d 个会话 - 发送 - 已归档会话 - 新消息 - 最近搜索 - 全部清除 - 会话和联系人 - 全局搜索 - 消息 - 显示更多 - 搜索会话… - 等待网络连接… - 正在连接… - 正在更新… - 正在连接代理… - 代理已启用 - 代理 - 论坛 - 剧透 - 草稿: - 暂无动态 - 暂无消息 - 已置顶 - 提到我的 - 已从主列表中隐藏 - 暂无会话 - 开始新对话 - 小程序 - - - MonoGram Dev - 添加账号 - 登录另一个账号 - 我的个人资料 - 查看个人资料 - 收藏夹 - 云端存储 - 设置 - 应用配置 - 有可用更新 - 新版本 %1$s 已发布 - 正在下载更新… %1$d%% - 更新已就绪,点击安装 - 帮助 - 常见问题与支持 - 隐私政策 - MonoGram Dev for Android v%1$s - 未知用户 - 暂无信息 - 显示账号 - - - 搜索消息… - 清除 - 已静音 - 已验证 - 取消静音 - 静音 - 过滤广告 - 白名单该频道 - 复制链接 - 清除历史记录 - 删除会话 - 举报 - 加入 - 滚动到底部 - 此话题已关闭 - 附件 - - - 删除消息? - 删除 %1$d 条消息? - 确定要删除这条消息吗? - 确定要删除这些消息吗? - 为所有人删除 - 为我删除 - - 为什么举报该内容? - 您的举报是匿名的。我们将审查聊天记录以确保安全。 - 举报详情 - 描述问题… - 发送举报 - 垃圾信息 - 不受欢迎的商业内容或诈骗 - 暴力 - 威胁或美化暴力 - 色情 - 不当媒体或显露性语言 - 儿童安全 - 涉及伤害未成年人的内容 - 版权 - 使用他人的知识产权 - 冒充 - 假冒他人或机器人 - 违禁药物 - 促销或使用违禁物质 - 侵犯隐私 - 分享私人联系信息或地址 - 无关地点 - 与此特定地点无关的内容 - 其他 - 其他违反我们条款的行为 - - 限制用户 - 发送消息 - 发送媒体 - 发送贴纸和 GIF - 发送投票 - 嵌入链接 - 置顶消息 - 更改会话信息 - 限制直到 - 永久 - 选择日期 - 选择时间 - 限制 - - 回复 - 复制 - 置顶 - 取消置顶 - 转发 - 选择 - 更多 - 删除 - 查看评论 - 保存到下载 - Cocoon - 摘要 - 翻译 - 由 Telegram Cocoon 生成 - 恢复原始文本 - 限制用户 - 已编辑 - 已读 - 浏览次数 - - - 未知 - %1$d 名成员 - %1$s,%2$d 人在线 - 未实现 - 搜索尚未实现 - 分享尚未实现 - 屏蔽尚未实现 - 删除尚未实现 - 统计 - 收入 - 分享 - 编辑 - 屏蔽用户 - 退出 - 打开 - 发消息 - 加入 - 举报 - 二维码 - 添加 - 个人照片 - 此照片仅对您可见 - 打开小程序 - 启动机器人的 Web 应用 - 接受服务条款 - 查看并接受机器人的服务条款 - 机器人权限 - 管理此机器人的权限 - 用户名 - 链接 - 邀请链接 - 机器人信息 - 描述 - 简介 - 生日 - 位置 - 营业时间 - 最近操作 - 查看会话事件日志 - 查看详细会话统计 - 查看会话收入统计 - 已将你加入联系人 - 未将你加入联系人 - 已保存到你的联系人 - 未保存到你的联系人 - 个人资料动态 - 你可以从个人资料发布动态 - 聊天背景 - 你可以设置自定义背景 - 语音与视频消息 - 发送语音和视频消息受限 - 慢速模式 - 成员每 %1$s 只能发送一条消息 - 受保护内容 - 限制转发和保存 - 隐私转发 - 转发消息会隐藏个人资料链接 - 会话统计 - %1$d 名管理员 - %1$d 人受限 - %1$d 人被封禁 - 信息 - 通知 - 自动删除消息 - 设置 - 保存 - 垃圾信息 - 暴力 - 色情 - 虐待儿童 - 版权 - 其他 - 关闭 - 通过启动此小程序,您同意其服务条款和隐私政策。此机器人将能够访问您的基本个人资料信息。 - 接受并启动 - - - 二维码 - 分享 - MonoGram 是一个免费且开源的项目。您的支持有助于我们维持项目并开发新功能。 - 带爱心的赞助者徽章可通过 Advanced 支持等级获得,或通过等值于 150 卢布(约 - $1.96)的支持获得。 - - 在 Boosty 上支持 - 稍后再说 - 编辑个人资料 - 长按遮盖 - 按住显示,点击复制 - 您的 ID - 修改您的姓名、简介和个人照片 - 启用 t.me 链接 - 在应用内直接打开 Telegram 链接 - 常规 - 会话设置 - 主题、文字大小、视频播放器 - 隐私和安全 - 锁屏码、活跃会话、隐私设置 - 通知和声音 - 消息、群组、电话 - 数据和存储 - 网络使用情况、自动下载 - 省电模式 - 电池使用设置 - 会话文件夹 - 整理您的会话 - 表情符号和贴纸 - 管理贴纸包和表情包 - 已关联设备 - 语言 - 英语 - 代理设置 - MTProto, SOCKS5, HTTP - Telegram Premium - 解锁专属功能 - 帮助我们开发项目 - 支持了 MonoGram - 该用户正在支持项目,帮助我们持续改进 - MonoGram 版本和信息 - 调试 - 调试选项 - 显示赞助者弹窗 - 打开赞助者信息底部弹窗 - 强制同步赞助者 - 立即从频道拉取赞助者 ID - 退出登录 - 断开账号连接 - - - 用户名 - %1$d 秒后重试 - 活跃用户名 - 已禁用用户名 - 收藏级用户名 - 完成 - 确定 - 选择开始时间 - 选择结束时间 - 办公时间 - 工作日 - 时间范围 - - - 业务地点 - 地址 - 确认位置 - 编辑个人资料 - 名字(必填) - 姓氏(选填) - 简介 - 任何详情,如年龄、职业或城市。 - 用户名 - 您可以在 Telegram 上选择一个用户名。如果您这样做,人们就可以通过该用户名找到并联系您,而无需知道您的电话号码。 - 您的生日 - 生日 - Telegram 商务版 - 关联频道 ID - 业务简介 - 业务地址 - 地理位置 - 营业时间 - 作为 Premium 用户,您可以关联频道,并为您的个人资料设置业务详情 - 未设置 - (%1$d 天) - - - - - - - - - - 隐私和安全 - 隐私 - 黑名单 - %1$d 个用户 - - 手机号码 - 最近上线时间 - 个人头像 - 转发的消息 - 语音通话 - 群组和频道 - 安全 - 锁屏码 - 开启 - 关闭 - 指纹解锁 - 使用指纹或面部解锁 - 活跃会话 - 管理您已登录的设备 - 敏感内容 - 停止过滤 - 在您的所有设备上显示公共频道中的敏感媒体内容。 - 高级 - 注销我的账号 - 如果离开时间超过 %1$s - 立即注销账号 - 永久注销您的账号及所有数据 - 如果我不活跃超过… - 注销账号 - 您确定要注销账号吗?此操作不可逆,所有数据都将丢失。 - 所有人 - 我的联系人 - 没有人 - 1 个月 - 3 个月 - 6 个月 - 1 年 - 18 个月 - 2 年 - %1$d 个月 - %1$d 天 - 用户请求注销 - - - 代理设置 - 刷新延迟 - 添加代理 - 连接 - 智能切换 - 自动使用速度最快的代理 - IPv6 优先 - 如果可用,优先使用 IPv6 - 禁用代理 - 直接连接 - 切换到直接连接 - Telega Proxy - Telega Proxy 曾被曝光存在流量拦截风险。MTProto 可保护消息数据不被中间人拦截,但仍请自行评估风险后使用。更多信息: t.me/telegaru - 启用 Telega Proxy - 自动获取并切换到最佳代理 - 刷新列表 - 获取最新的社区代理 - 您的代理 - 清除离线 - 全部移除 - 删除离线代理 - 此操作将删除当前所有离线代理。是否继续? - 删除所有代理 - 此操作将从应用中删除所有已配置的代理。是否继续? - 未添加代理 - 删除代理 - 您确定要删除代理 %1$s 吗? - 新代理 - 编辑代理 - 服务器地址 - 端口 - 密钥 (Hex) - 用户名(选填) - 密码(选填) - 保存修改 - 测试 - 测试结果 - 删除 - 检查中... - 离线 - %1$dms - - - 您的用户名 - 更多选项 - - - 通知和声音 - 消息通知 - 私聊 - 群组 - 频道 - 通知设置 - 振动 - 优先级 - 重复通知 - 仅显示发送者 - 在通知中隐藏消息内容 - 推送服务 - 推送提供商 - 常驻服务 - 让应用在后台运行,以保证通知的可靠性 - 隐藏前台通知 - 服务启动后隐藏通知。这可能导致服务被系统终止 - 应用内通知 - 应用内声音 - 应用内振动 - 应用内预览 - 事件 - 联系人加入了 Telegram - 置顶消息 - 重置所有通知 - 撤销对所有联系人和群组的自定义通知设置 - 振动模式 - 通知优先级 - %1$s,%2$d 个例外 - 默认 - - - 已禁用 - - 默认 - - 从不 - 每 %1$d 分钟 - 每 1 小时 - 每 %1$d 小时 - Firebase Cloud Messaging - GMS-less (后台服务) - - - 会话设置 - 外观 - 消息文字大小 - 字元間距 - 气泡圆角 - 重置 - 会话壁纸 - 重置壁纸 - 表情风格 - 主题 - 夜间模式 - 跟随系统 - 浅色 - 深色 - 定时计划 - 自动 - 当前模式 - 当前使用:%1$s - 亮度阈值: %1$d%% - 当屏幕亮度低于此水平时切换到深色主题。 - 动态色彩 - 动态色彩 - 应用主题使用系统配色 - 数据和存储 - 压缩照片 - 发送前减小照片大小 - 压缩视频 - 发送前减小视频大小 - 视频播放器 - 启用手势 - 滑动控制音量和亮度 - 双击快进/快退 - 双击视频边缘进行快进/快退 - 跳转时长 - 启用缩放 - 在视频播放器中捏合缩放 - 会话列表 - 置顶已归档会话 - 将已归档会话固定在列表顶部 - 始终显示置顶归档 - 滚动时始终保持置顶归档可见 - 显示链接预览 - 在消息中显示链接预览 - 拖拽返回 - 从左边缘滑动返回 - 两行显示 - 三行显示 - 显示头像 - 在会话列表中显示个人头像 - 实验性功能 - 频道广告屏蔽 - 隐藏频道中的赞助内容 - 最近媒体 - 清除最近贴纸 - 移除所有最近使用的贴纸 - 清除最近表情 - 移除所有最近使用的表情符号 - 移除表情包 - 移除 %1$s 表情包? - 这将从您的设备中删除已下载的表情包。您可以稍后再次下载。 - 编辑自定义主题 - 已选中 - Apple - Twitter - Windows - Catmoji - Noto - 系统默认 - - - 数据和存储 - 磁盘和网络使用情况 - 存储使用情况 - 管理您的本地缓存 - 网络使用情况 - 查看已发送和已接收的数据量 - 自动媒体下载 - 使用移动数据时 - 使用 Wi-Fi 时 - 漫游时 - 自动下载文件 - 自动下载接收到的文件 - 自动下载贴纸 - 自动下载贴纸 - 自动下载视频消息 - 自动下载视频消息 - 自动播放媒体 - GIF - 在会话列表和聊天中自动播放 GIF - 视频 - 在聊天中自动播放视频 - 已启用 - 已禁用 - - - 省电模式 - 电池 - 省电模式 - 减少后台活动和动画以节省电量 - 优化电池使用 - 严格限制后台工作并释放唤醒锁 - 唤醒锁 - 为后台任务保持 CPU 唤醒。禁用以省电 - 动画 - 聊天动画 - 禁用聊天动画以省电 - 后台 - 禁用此项将减少功耗,但可能会延迟后台通知 - - - 表情符号和贴纸 - 贴纸 - 表情 - 最近贴纸 - 贴纸包 - 已归档贴纸 - 添加自己的贴纸 - 使用 @Stickers 机器人创建您自己的贴纸包 - 未安装贴纸包 - 未找到关于 “%1$s” 的贴纸 - 最近表情 - 表情包 - 已归档表情 - 添加自己的表情 - 使用 @Stickers 机器人创建您自己的表情包 - 清除最近表情 - 移除所有最近使用的表情符号 - 未安装表情包 - 未找到关于 “%1$s” 的表情 - 搜索表情包 - 搜索 - - %1$d 个贴纸 - %1$d 个贴纸 - - - %1$d 个表情符号 - %1$d 个表情符号 - - 面具 - 自定义表情 - 官方 - 链接已复制到剪贴板 - - - 网络使用情况 - 重置统计数据 - 网络统计 - 跟踪您使用了多少数据。禁用可减少磁盘空间占用。 - 网络统计已禁用 - 网络使用情况跟踪当前已关闭。使用上方开关启用它,以查看您在移动数据、Wi-Fi 和漫游网络上使用了多少数据。 - 总使用量 - 已发送 - 已接收 - 概览 - 应用使用 - 暂无使用数据记录 - 暂无统计数据 - 移动数据 - Wi-Fi - 漫游 - 其他 - - - 存储使用情况 - 清除所有缓存 • %1$s - 包括来自所有会话的照片、视频、文档、贴纸和 GIF。 - 缓存限制 - 自动清除缓存 - 存储优化器 - 后台存储优化 - 详细使用情况 - 存储空间已清理 - 未找到缓存文件。 - 清除缓存 - 您确定要清除 “%1$s” 的缓存吗?这将释放 %2$s。 - 清除所有缓存 - 这将从所有会话中删除所有缓存的媒体文件。您确定吗? - 无限 - 从不 - 每天 - 每周 - 每月 - 总已用量 - %1$d 个文件 - %1$d 个文件 - - - 谁可以将我添加到 %1$s? - 谁可以给我打电话? - 谁可以看到我的最后上线时间? - 谁可以看到我的个人头像? - 谁可以看到我的个人简介? - 谁可以在转发我的消息时添加帐号链接? - 谁可以将我添加到群组和频道? - 谁可以看到我的手机号码? - 谁可以通过我的电话号码找到我? - 只有当上述设置允许时,将您的号码添加到联系人的用户才能在 Telegram 上看到它。 - 添加例外 - 始终允许 - 从不允许 - %1$d 个用户/会话 - (已注销) - 群组成员 - 手机号码搜索 - 暂无黑名单用户 - 黑名单中的用户将无法联系您,也无法看到您的最近上线时间。 - 解除屏蔽 - 屏蔽用户 - 搜索用户 - 未找到用户 - - - 修改锁屏码 - 设置锁屏码 - 您的应用当前受锁屏码保护。输入新代码以修改。 - 输入 4 位锁屏码以锁定应用并保护您的隐私。 - 锁屏码 - 当前锁屏码 - 保存锁屏码 - 关闭锁屏码 - 验证锁屏码 - 更改或关闭锁屏码前,请先输入当前锁屏码。 - 锁屏码不正确。 - - - 添加关键词 - 启用广告屏蔽 - 白名单频道 - 已允许 %1$d 个频道 - 加载基础关键词 - 从资源中导入常见广告关键词 - 复制所有关键词 - 将当前列表复制到剪贴板 - 清除所有关键词 - 从列表中移除所有关键词 - 屏蔽含有以下关键词的消息 - 未添加关键词 - 点击 + 按钮添加关键词进行过滤 - 添加关键词 - 输入以逗号或换行分隔的关键词,以过滤频道消息。 - 例如 #promo, ad, 广告 - 添加到列表 - 来自这些频道的消息将不会被过滤 - 暂无白名单频道 - 移除 - - - 最近上线 - 刚刚上线 - - 最近上线于 %1$d 分钟前 - - 最近上线于 %1$s - 昨天 %1$s 上线 - 最近上线于 %1$s - 一周内上线过 - 一个月内上线过 - 很久以前上线过 - 在线 - 离线 - 机器人 - 用户名 - %1$d 个贴纸 - 已归档 - 添加 - 取消归档 - 归档 - 移除贴纸包 - - - 新消息 - 添加成员 - 新建群组 - 新建频道 - %1$d 个联系人 - %1$d / 200000 - 已选择 %1$d 个 - 搜索联系人… - 未找到联系人 - 未找到 "%1$s" 的结果 - 按最后上线时间排序 - 新建群组 - 新建频道 - 支持 - 频道是向无限受众广播消息的工具。 - 频道详情 - 频道名称 - 描述(选填) - 自动删除消息 - 关闭 - 1 天 - 2 天 - 3 天 - 4 天 - 5 天 - 6 天 - 1 周 - 2 周 - 3 周 - 1 个月 - 2 个月 - 3 个月 - 4 个月 - 5 个月 - 6 个月 - 1 年 - 您可以为频道提供可选描述。任何拥有链接的人都可以加入您的频道。 - 为您的新群组提供名称和可选照片。 - 群组详情 - 群组名称 - 请输入群组名称 - 请输入频道名称 - 查看资料 - 编辑名称 - 删除联系人 - 编辑联系人 - - - 删除联系人? - 您确定要将 %1$s 从联系人中移除吗? - 在一定时间后自动删除该群组中发送的新消息。 - 添加照片 - 更改照片 - - - 需要权限 - 为了提供最佳体验,MonoGram 需要以下权限。 - 通知 - 获取新消息通知 - 允许 - 电话状态 - 管理设备状态以获得更好的用户体验 - 电池优化 - 确保可靠的后台运行 - 禁用 - 相机 - 拍摄照片和录制视频消息 - 麦克风 - 录制语音和视频消息 - 位置 - 共享您的位置并查看附近的用户 - - - 清除选择 - 置顶 - - - 机器人指令 - 选择要发送给机器人的指令 - - - 会话列表 - 泉此方 - 我不是矮,我只是浓缩的精华!🍫 而且,我已经决定成为一名职业睡觉家了 😴 - 12:45 - 柊镜 - 别忘了作业!明天早上就要交了,而且挺难的。 - 11:20 - - - 预览 - - 我不是矮,我只是浓缩的精华!🍫\n而且,我已经决定成为一名职业睡觉家了 😴 - 当你够不到最上面的架子时你总是这么说… 🙄\n看看这个:这个 - 别揭穿我!😤✨\n我只是在使用我的秘密武器:💯 纯粹的懒惰 - 效果拔群!😵‍💫 - 今天 - 此方 - - %1$d 位订阅者 - 回复 - - - 删除录音 - < 左滑取消 - 发送录音 - 锁定录音 - 向上滑动 - - - 添加说明… - 消息 - 不允许发送消息 - - - 照片 - 视频 - 贴纸 - 语音消息 - 视频消息 - GIF - 位置 - 消息 - - - 取消回复 - 编辑消息 - 取消编辑 - 发送 %1$d 个项目 - 发送媒体 - 取消 - 复制 - 粘贴 - 剪切 - 全选 - 应用 - 完成 - 刷新 - 全屏编辑器 - 编辑器 - 静默发送 - 定时发送消息 - 定时消息 - 定时消息(%1$d) - 暂无定时消息 - 定时总数:%1$d - 下次发送:%1$s - 可编辑:%1$d - ID:%1$d - 编辑 - 发送 - 删除 - - 加粗 - 斜体 - 下划线 - 删除线 - 剧透 - 代码 - 等宽 - 链接 - 提及 - 表情 - 清除 - 添加链接 - URL - 代码语言 - 语言(例如 kotlin) - - %1$d 个字符 • %2$d 个格式块 - %1$d 个格式块 - 选中文本以应用类似 Telegram 的富文本格式 - %1$d/%2$d - - - 指令 - - - 正在输入 - 正在录制视频 - 正在录制语音消息 - 正在发送照片 - 正在发送视频 - 正在发送文件 - 正在选择贴纸 - 正在玩游戏 - 有人 - - 以及另外 %d 人 - 正在输入 - - %d 人正在输入 - %d 人正在输入 - - - - 照片 - 视频 - 文档 - 贴纸 - 音乐 - 语音消息 - 视频消息 - 其他文件 - 其他 / 缓存 - 会话 %d - - - 通话 - - - 正在等待新消息 - 停止 - 后台服务 - 关于应用在后台运行的通知 - - - 📷 照片 - 📹 视频 - 🎤 语音消息 - 🧩 贴纸 - 📎 文档 - 🎵 音频 - GIF - 🎬 视频消息 - 👤 联系人 - 📊 投票 - 📍 位置 - 📞 通话 - 🎮 游戏 - 💳 账单 - 📚 故事 - 📌 已置顶消息 - 消息 - 机器人 - 在线 - 离线 - 刚刚在线 - %d 分钟前在线 - %d 分钟前在线 - 在 %s 在线 - 昨天 %s 在线 - 在 %s 在线 - 最近在线 - 一周内在线 - 一个月内在线 - - - 置顶消息 - 置顶消息 - 显示所有置顶 - 取消置顶 - 关闭 - - %d 条消息 - - - - 视频消息 - GIF - 文档 - 投票:%s - 贴纸 %s - - - 预览 - 裁剪 - 滤镜 - 绘制 - 文字 - 橡皮擦 - - - 原图 - 黑白 - 棕褐色 - 复古 - 冷色 - 暖色 - 拍立得 - 反色 - - - 保存 - 取消 - 撤销 - 重做 - 关闭 - 重置 - 向左旋转 - 向右旋转 - 添加文字 - 编辑文字 - 应用 - 删除 - - - 大小 - 缩放 - 输入文字... - 选择工具开始编辑 - - - 放弃更改? - 更改尚未保存,确定要放弃吗? - 放弃 - - - 应用 - 完成 - 取消 - - - - 预览 - 裁剪 - 滤镜 - 文字 - 压缩 - - - 取消静音 - 静音 - 添加文字 - 视频质量 - 预计码率: %1$d kbps - - - 原图 - 黑白 - 怀旧 - 复古 - 冷色 - 暖色 - 拍立得 - 反色 - - - 未找到文件 - 视频文件丢失 - 放弃更改? - 您有未保存的更改。确定要放弃这些更改吗? - 放弃 - - - 加载中… - 网页视图 - 关闭 - 更多 - - - 选项 - 后退 - 前进 - 刷新 - 操作 - 设置 - 复制 - 链接已复制 - 分享 - 分享至 - 浏览器 - 查找 - 桌面版网站 - 广告拦截 - 字体大小: %1$d%% - - - 安全 - 不安全 - 安全信息 - 连接不安全 - 与此网站的连接已加密且安全。 - 与此网站的连接不安全。请勿输入任何敏感信息(如密码或信用卡号),因为这些信息可能会被攻击者窃取。 - 颁发给 - 颁发者 - 有效期至 - 未知 - - - 在页面中查找… - 上一个 - 下一个 - 关闭查找 - - - 讨论 - 频道 - 打开地图 - 路线 - 使用...导航 - 打开方式 - 浏览器 / 其他 - 媒体 - 成员 - 文件 - 音乐 - 语音 - 链接 - GIF - 未找到成员 - 未找到媒体文件 - 未找到音频文件 - 未找到语音消息 - 未找到文件 - 未找到链接 - 未找到 GIF - 机器人 - 已关闭 - ID - - - 正在分析统计数据... - 概览 - 成员 - 消息 - 观众 - 活跃发送者 - 成员增长 - 新成员 - 消息内容 - 操作 - 按天统计活动 - 按周统计活动 - 活跃时间 - 浏览来源 - 新成员来源 - 语言 - 发送者排名 - 条消息 - 平均字符数: %1$d - 管理员排名 - 次操作 - 删除: %1$d | 封禁: %2$d - 邀请者排名 - 次邀请 - 已添加成员 - 订阅者 - 通知已开启 - 平均消息浏览量 - 平均消息分享数 - 平均反应数 - 增长 - 新订阅者 - 按小时统计浏览量 - 消息交互 - 即时预览交互 - 消息反应 - 最近交互 - 消息 - 故事 - 文章 ID - 显示较少 - 显示全部 (%1$d) - 收益 - 可用余额 - 总余额 - 汇率 - 收益增长 - 每小时收益 - 数据已加载 - 放大 - 正在生成图表... - 无变化 - 与前期相比 - 未知统计类型 - 数据类: %1$s - - - 返回 - 选项 - 后退 10 秒 - 前进 10 秒 - -%1$ds - +%1$ds - 缩略图 %1$d - %1$d / %2$d - 正在加载原图... - - - 下载 - 下载视频 - 复制图片 - 复制文本 - 复制链接 - 复制当前时间链接 - 转发 - 保存至 GIF - 保存到相册 - 复制到剪贴板 - 重新开始 - 暂停 - 播放 - 解锁 - - - 设置 - 播放速度 - 缩放模式 - 适应屏幕 - 裁剪填充 - 旋转屏幕 - 画中画 - 屏幕截图 - 循环播放 - 静音 - 字幕 - 锁定控制 - 清晰度 - 视频质量 - 自动 - 高画质 - 正常 - - - 播放 - 暂停 - 后退 - 前进 - - - 贴纸 - 表情 - GIF - - - 最近贴纸 - 贴纸 - 搜索贴纸 - - - 最近表情 - 标准表情 - 自定义表情 - 表情 - 搜索表情 - - - 最近与已保存 - 未找到 GIF - 搜索 GIF - - - 返回 - 清除 - 最近 - - - 已保存到相册 - 分享二维码 - 发送时出错:%1$s - - - 编辑频道 - 编辑群组 - 频道名称 - 群组名称 - 简介 - 设置 - 公开频道 - 公开群组 - 自动翻译 - 话题 - 管理 - 删除频道 - 删除群组 - - - 搜索... - 管理员 - 订阅者 - 成员 - 黑名单 - 未找到相关结果 - 暂无成员 - - - 管理员权限 - 自定义头衔 - 此头衔将对聊天中的所有成员可见 - 该管理员拥有哪些权限? - 管理聊天 - 发布消息 - 编辑消息 - 删除消息 - 封禁成员 - 邀请用户 - 管理话题 - 管理视频聊天 - 发布故事 - 编辑故事 - 删除故事 - 添加新管理员 - 保持匿名 - - - 权限 - 此群组的成员可以做什么? - 添加成员 - - - 返回 - 保存 - 清除 - 搜索 - 添加 - 编辑 - 用户名 - 过滤器 - - - 近期操作 - 已加载 %d 条记录 - 未发现近期操作 - 尝试更改过滤器 - 未实现 - 用户 ID 已复制 - - - 筛选操作 - 重置 - 应用 - 操作类型 - 按用户 - 搜索… - 未找到用户 - 未找到关于“%s”的结果 - - - 编辑 - 删除 - 置顶 - 加入 - 离开 - 邀请 - 提拔 - 限制 - 信息 - 设置 - 链接 - 视频 - - - 编辑了消息 - 删删了消息 - 置顶了消息 - 取消了置顶 - 加入了群聊 - 退出了群聊 - 邀请了 %s - 更改了 %s 的权限 - 更改了 %s 的限制 - 将群名称更改为“%s” - 更改了群简介 - 将用户名更改为 @%s - 更改了群头像 - 编辑了邀请链接 - 撤销了邀请链接 - 删除了邀请链接 - 开启了视频聊天 - 结束了视频聊天 - 执行了操作:%s - - - 原消息: - 新消息: - 已删除的消息: - 已置顶的消息: - 已取消置顶的消息: - 直到:%s - 永久限制 - - - 旧群头像 - 新群头像 - - - 权限更改: - 当前权限: - - - 消息 - 媒体 - 贴纸 - 链接 - 投票 - 邀请 - 置顶 - 详情 - - 管理员 - 群主 - 受限 - 已封禁 - 成员 - - - 照片 - 视频 - GIF - 贴纸 - 文件 - 音频 - 语音消息 - 视频消息 - 联系人 - 投票 - 位置 - 地点 - 不支持的消息 - - - HH:mm - %1$02d:%2$02d - - - %1$.1fK 次观看 - %1$.1fM 次观看 - - - 发表评论 - %1$d 条评论 - %1$.1fK 条评论 - %1$.1fM 条评论 - - - 最终结果 - 匿名投票 - 公开投票 - 知识竞赛 - 投票 - • 多选 - 撤销投票 - 停止投票 - - %d 票 - - - - 更多 - 投票 - 解释 - - - 投票者 - 尚无投票者 - 关闭 - - - 图片 - 视频 - 贴纸 - 语音消息 - 视频消息 - GIF - 消息 - - - 聊天分組 - 返回 - 新建分組 - 創建 - 編輯分組 - 保存 - 默認分組 - 自定義分組 - 刪除 - 為不同類型的聊天創建分組,並在它們之間快速切換。 - 尚無自定義分組 - 點擊 + 按鈕創建一個 - 所有聊天 - %1$d 個聊天 - 上移 - 下移 - 分組名稱 - 選擇圖標 - 包含的聊天 - 搜索聊天… - 取消 - - - Telegram Premium - 返回 - 以每月 %s 订阅 - 解锁专属功能 - - - 限制翻倍 - 最多可加入 %1$d 个频道,创建 %2$d 个聊天分组,置顶 %3$d 个聊天,%4$d 条公开链接等。 - 语音转文字 - 点击语音消息旁的按钮即可查看文字转录。 - 更快的下载速度 - 下载媒体和文档时不再有速度限制。 - 实时翻译 - 只需轻轻一点,即可实时翻译整个聊天。 - 动态表情符号 - 可在消息中使用数百个表情包中的动态表情。 - 高级对话管理 - 可设置默认收藏夹、自动归档以及对非联系人隐藏新聊天。 - 无广告 - 公共频道有时会显示广告,订阅后将不再显示。 - 无限回应 - 可使用数千种表情符号进行回应,每条消息最多可添加 3 个。 - Premium 徽章 - 名字旁边会出现专属徽章,表明您已订阅 Telegram Premium。 - 表情符号状态 - 从数千个表情符号中选择一个显示在您的名字旁边。 - Premium 应用图标 - 可从精选的 Telegram 图标中选择并替换主屏幕图标。 - - - 重新加载 - 复制链接 - 在浏览器中打开 - 添加到主屏幕 - - - 关闭小程序? - 您有未保存的更改。确定要关闭吗? - 关闭 - 取消 - 权限请求 - 允许 - 拒绝 - 机器人权限 - 服务条款 - 启动此小程序即表示您同意其服务条款和隐私政策。该机器人将能够访问您的基本个人资料信息。 - 接受并启动 - - - 在文章中搜索… - 返回 - 清除 - 即时预览 - 更多 - %d 次查看 - 复制链接 - 在浏览器中打开 - 搜索 - 文字大小 - 播放视频 - 播放动画 - 音频 - 未知艺术家 - 播放 - 打开 - 折叠 - 展开 - 地图: %1$s, %2$s - - - 分享个人资料 - 分享您的 Monogram 个人资料链接 - 复制链接 - 将您的 Monogram 个人资料链接复制到剪贴板 - - - 主题编辑器 - 调色板模式 - 选择要编辑的调色板。编辑器会默认打开当前在应用中生效的调色板。 - 浅色 - 深色 - 正在编辑:%1$s 调色板 - 当前应用生效:%1$s - 强调色 - 强调色只会更新 %1$s 调色板。 - Hex 强调色 - 应用 - 取消 - 选择 - 保存 - 加载 - 全部应用 - Hex - monogram-theme.json - - 主题文件已保存 - 保存失败 - 主题已加载 - 无效文件 - 加载失败 - - 主题来源 - 选择一种应用色彩来源。“自定义”使用可编辑的调色板,“Monet”使用 Android 动态色彩。“AMOLED”仅影响深色背景。 - 自定义主题 - 使用您自己的浅色/深色调色板、强调色、预设和手动角色色彩。 - Monet - 根据壁纸生成的 Material You 色彩 (Android 12+)。 - AMOLED 纯黑 - 在深色模式下强制使用纯黑色,以减少屏幕光晕并节省 OLED 屏幕电量。 - - 预设主题 - 每个预设都有浅色和深色版本。点击浅色、深色或全部应用即可生效。 - 手动调色 (%1$s) - %1$s 预览 - 摘要文本 - 操作 - 选择 %1$s - 色相 %1$d° - 饱和度 %1$d%% - 亮度 %1$d%% - 不透明度 %1$d%% - - 主要 - 次要 - 第三色 - 背景 - 表面 - 主要容器 - 次要容器 - 第三容器 - 表面变体 - 轮廓 - - L P - L C - L BG - D P - D C - D BG - - 蓝色 - 绿色 - 橙色 - 玫瑰红 - 靛蓝色 - 青色 - - 经典 - 均衡的蓝色,具有清晰的易读性和中性的表面色。 - - 森林 - 具有冷静对比度和柔和容器色调的自然绿色。 - - 海洋 - 清爽的青蓝色渐变,包含清新的浅色和深邃的深色模式。 - - 日落 - 温暖的橙色和珊瑚色调,具有极高的前景色清晰度。 - - 石墨 - 中性灰阶基调,配以蓝灰色点缀,结构感强。 - - 薄荷 - 清新的薄荷色与鸭绿色的组合,容器色调温和。 - - 红宝石 - 深红色调配以中性容器,强调行动视觉焦点。 - - 薰衣草灰 - 柔和的紫灰色调,具有受控的饱和度和洁净的对比度。 - - 沙滩 - 米色和琥珀色调,专为极柔和的视觉效果而设计。 - - 极地 - 冰蓝色与白色的观感,具有极佳的可读性和清晰的边界。 - - 祖母绿 - 鲜明的绿色主题,搭配干净表面与现代对比度。 - - 铜色 - 温暖的铜橙色方案,在浅色和深色模式下都保持清晰文本。 - - 樱花 - 柔和的粉紫色调,容器过渡细腻,重点高亮更明显。 - - 北境 - 冷调北欧蓝色风格,整体观感沉稳且专业。 - - 需要相机和麦克风权限 - 处理中... - 处理错误: %1$s - 关闭录制器 - 切换摄像头 - 完成录制 - 录制中 - 就绪 - 时长: %1$s - 变焦: %1$.1fx (范围 %2$.1fx - %3$.1fx) - 取消 - - 清除历史记录? - 您确定要清除聊天记录吗?此操作无法撤销。 - 清除历史记录 - 删除聊天? - 您确定要删除此聊天吗?此操作无法撤销。 - 删除聊天 - 退出聊天? - 您确定要退出此聊天吗? - 退出 - 删除频道? - 删除群组? - 您确定要删除此频道吗?所有消息和媒体将丢失。 - 您确定要删除此群组吗?所有消息和媒体将丢失。 - 删除 %1$d 个聊天? - 您确定要删除所选聊天吗? - 删除聊天 - 屏蔽用户? - 您确定要屏蔽此用户吗?该用户将无法向您发送消息。 - 屏蔽 - 解除屏蔽用户? - 您确定要解除屏蔽此用户吗?对方将可以再次向您发送消息。 - 取消置顶消息? - 您确定要取消置顶此消息吗? - 取消置顶 - 您确定要清除最近使用的贴纸吗? - 清除贴纸 - 您确定要清除最近使用的表情吗? - 清除表情 - 添加到联系人 - 从联系人中移除 - 标为已读 - 标为未读 - 编辑 - 排序 - 删除 - diff --git a/presentation/src/main/res/values/string.xml b/presentation/src/main/res/values/string.xml deleted file mode 100644 index 631ba62a..00000000 --- a/presentation/src/main/res/values/string.xml +++ /dev/null @@ -1,1886 +0,0 @@ - - - Confirmation - Do you really want to authorize this device? - Yes, sign in - Cancel - - Scan QR - Devices - Link a device - - This device - Login requests - Active sessions - - Navigate back - Close scanner - QR Scanner icon - - - Connecting to Telegram… - - - About - Back - MonoGram - Version %1$s - Terms of Service - Read our terms and conditions - Open Source Licenses - Software used in MonoGram - GitHub - View source code - TDLib Version - %1$s (%2$s) - Community - Telegram Chat - Join our community to discuss features and get help - Telegram Channel - Stay updated with the latest news and announcements - Support MonoGram - Support the development and help us keep the project alive - Maintainers - Developer - Icon & Logo Designer - MonoGram is an unofficial Telegram client built with Material Design 3 - © 2026 MonoGram - - - Check for Updates - Checking... - Update Available: %1$s - You are up to date - Update Ready - Update Error - Tap to check for new version - Connecting to server - New version is available for download - You are using the latest version - Tap to install the update - Downloading Update... - %1$d%% - What\'s New in %1$s - Download Update - Cancel - Loading... - - - Your Phone - Verification - Password - Proxy Settings - Your Phone Number - Please confirm your country code and enter your phone number. - Country - Code - Phone Number - 000 00 00 - Continue - Select Country - Search country or code... - We\'ve sent the code to the Telegram app on your other device. - - We\'ve sent the code via SMS. - We\'re calling you with the code. - We\'ve sent the code to %1$s. - We\'ve sent the verification code. - Confirm - Resend code in %1$s - Resend via SMS - Resend via Call - Resend code - Wrong number? - Two-Step Verification - Your account is protected with an additional password. - Password - Unlock - Paste - Authentication Error - Dismiss - - - Please wait a moment - Taking too long? - Reset Connection - - - Forward to... - %1$d chats selected - Send - Archived Chats - New Chat - Recent - Clear All - Chats and contacts - Global search - Messages - Show more - Search conversations… - Waiting for network… - Connecting… - Updating… - Connecting to proxy… - Proxy enabled - Proxy - Forum - Spoiler - Draft: - No posts yet - No messages yet - Pinned - Mentions - Hidden from the main list - No chats yet - Start a new conversation - Mini App - - - MonoGram Dev - Add Account - Login to another account - My Profile - View your profile - Saved Messages - Cloud storage - Settings - App configuration - Update Available - New version %1$s is available - Downloading update... %1$d%% - Update ready to install - Help & Feedback - FAQ and support - Privacy Policy - MonoGram Dev for Android v%1$s - Unknown User - No info - Show accounts - - - Search messages... - Clear - Muted - Verified - Sponsor - Unmute - Mute - Filter Ads - Whitelist Channel - Copy Link - Clear History - Delete Chat - Report - JOIN - Scroll to bottom - This topic is closed - Attach - - - Delete message? - Delete %1$d messages? - Are you sure you want to delete this message? - Are you sure you want to delete these messages? - Delete for everyone - Delete for me - - Why are you reporting this? - Your report is anonymous. We will review the chat history to ensure safety. - Report details - Describe the issue… - Send Report - Spam - Unwanted commercial content or scams - Violence - Threats or glorification of violence - Pornography - Inappropriate media or explicit language - Child safety - Content involving harm to minors - Copyright - Using someone else\'s intellectual property - Impersonation - Pretending to be someone else or a bot - Illegal drugs - Promoting the sale or use of prohibited substances - Privacy violation - Sharing private contact info or addresses - Unrelated location - Content not relevant to this specific place - Other - Something else that violates our terms - - Restrict User - Send Messages - Send Media - Send Stickers & GIFs - Send Polls - Embed Links - Pin Messages - Change Chat Info - Restrict until - Forever - Select Date - Select Time - Restrict - - Reply - Copy - Pin - Unpin - Forward - Select - More - Delete - View Comments - Save to Downloads - Cocoon - Summary - Translate - Generated with Telegram Cocoon - Restore Original Text - Restrict User - Edited - Read - Views - - - Unknown - %1$d members - %1$s, %2$d online - Not implemented - Search not implemented - Share not implemented - Block not implemented - Delete not implemented - Statistics - Revenue - Share - Edit - Block User - Leave - Open - Message - Join - Report - QR Code - Add - Personal Photo - This photo is only visible to you - Open Mini App - Launch bot\'s web application - Accept TOS - Review and accept bot\'s terms of service - Bot Permissions - Manage permissions for this bot - Username - Link - Invitation Link - Bot Info - Description - Bio - Birthdate - Location - Opening Hours - Recent Actions - View chat event log - View detailed chat statistics - View chat revenue statistics - Added you to contacts - Did not add you to contacts - Saved in your contacts - Not saved in your contacts - Profile stories - You can publish stories from your profile - Chat background - You can set custom backgrounds - Voice and video notes - Sending voice and video notes is restricted - Slow mode - Members can send one message every %1$s - Protected content - Forwarding and saving are restricted - Private forwards - Forwarded messages hide profile link - Chat Stats - %1$d admins - %1$d restricted - %1$d banned - Info - Notifications - Auto-delete messages - Settings - Save - Spam - Violence - Pornography - Child Abuse - Copyright - Other - Close - By launching this Mini App, you agree to the Terms of Service and Privacy - Policy. The bot will be able to access your basic profile information. - - Accept and Launch - - - QR Code - Share - MonoGram is a free and open-source project. Your support helps us to - keep it alive and develop new features. - - The sponsor badge with a heart is available from Advanced support level or - an equivalent contribution of 150 RUB (about $1.96). - - Support on Boosty - Maybe later - Edit Profile - Long press to mask - Hold to show, click to copy - Your ID - Change your name, bio, and profile photo - Enable t.me links - Open Telegram links to open them in-app - General - Chat Settings - Themes, text size, video player - Privacy and Security - Passcode, active sessions, privacy - Notifications and Sounds - Messages, groups, calls - Data and Storage - Network usage, auto-download - Power Saving - Battery usage settings - Chat Folders - Organize your chats - Stickers and Emoji - Manage sticker sets and emoji packs - Linked devices - Language - English - Proxy Settings - MTProto, SOCKS5, HTTP - Telegram Premium - Unlock exclusive features - Help us develop the project - Supports MonoGram - This user supports the project and helps us keep improving it - MonoGram version and info - Debug - Debug options - Show sponsor sheet - Open sponsor info bottom sheet - Force sponsor sync - Fetch sponsor IDs from channel now - Log Out - Disconnect from account - - - Usernames - Retry in %1$ds - Active Usernames - Disabled Usernames - Collectible Usernames - Done - OK - Select Start Time - Select End Time - Work Hours - Working Days - Time Range - From - To - Business Location - Address - Confirm Location - Edit Profile - First Name (Required) - Last Name (Optional) - Bio - Any details such as age, occupation or city. Example: 23 y.o. designer from San - Francisco. - - Username - You can choose a username on Telegram. If you do, people will be able to find - you by this username and contact you without needing your phone number. - - Your Birthday - Birthday - Telegram Business - Linked Channel ID - Business Bio - Business Address - Location Geo - Opening Hours - As a Premium user, you can add your link a channel, and set business - details to your profile - - Not set - (%1$d days) - M - T - W - T - F - S - S - - - Privacy and Security - Privacy - Blocked Users - %1$d users - None - Phone Number - Last Seen & Online - Profile Photos - Forwarded Messages - Calls - Groups & Channels - Security - Passcode Lock - On - Off - Unlock with Biometrics - Use fingerprint or face to unlock - Active Sessions - Manage your logged-in devices - Sensitive Content - Disable filtering - Display sensitive media in public channels on all your devices. - Advanced - Delete My Account - If away for %1$s - Delete Account Now - Permanently delete your account and all data - Self-Destruct if Inactive For... - Delete Account - Are you sure you want to delete your account? This action is - permanent and cannot be undone. - - Everybody - My Contacts - Nobody - 1 month - 3 months - 6 months - 1 year - 18 months - 2 years - %1$d months - %1$d days - User requested deletion - - - Proxy Settings - Refresh Pings - Add Proxy - Connection - Smart Switching - Automatically use the fastest proxy - Prefer IPv6 - Use IPv6 when available - Disable Proxy - Connected directly - Switch to direct connection - Telega Proxy - Telega Proxy has been accused of intercepting traffic. MTProto protects message data from interception, but use this proxy at your own risk. More info: t.me/telegaru - - Enable Telega Proxy - Auto-fetch and switch to best - Refresh List - Fetch latest community proxies - Your Proxies - Clear Offline - Remove All - Delete Offline Proxies - This will remove all currently offline proxies. Continue? - Delete All Proxies - This will remove all configured proxies from the app. Continue? - No proxies added - Delete Proxy - Are you sure you want to delete the proxy %1$s? - New Proxy - Edit Proxy - Server Address - Port - Secret (Hex) - Username (Optional) - Password (Optional) - Save Changes - Test - Test Result - Delete - Checking... - Offline - %1$dms - - - Your Usernames - More options - - - Notifications and Sounds - Message Notifications - Private Chats - Groups - Channels - Notification Settings - Vibration - Priority - Repeat Notifications - Show Sender Only - Hide message content in notifications - Push Service - Push Provider - Keep-Alive Service - Keep the app running in the background for reliable notifications - - Hide Foreground Notification - Hide the service notification after it starts. May lead to - service termination by system - - In-App Notifications - In-App Sounds - In-App Vibrate - In-App Preview - Events - Contact Joined Telegram - Pinned Messages - Reset All Notifications - Undo all custom notification settings for all your contacts and - groups - - Vibration Pattern - Notification Priority - %1$s, %2$d exceptions - Default - Short - Long - Disabled - Low - Default - High - Never - Every %1$d minutes - Every 1 hour - Every %1$d hours - Firebase Cloud Messaging - GMS-less (Background Service) - - - Chat Settings - Appearance - Message text size - Message letter spacing - Bubble rounding - Reset - Chat Wallpaper - Reset Wallpaper - Emoji Style - Theme - Night Mode - System - Light - Dark - Schedule - Auto - Current behavior - Using: %1$s - Brightness threshold: %1$d%% - Switch to dark theme when screen brightness is below this level. - - Dynamic Colors - Dynamic Colors - Use system colors for the app theme - Data and Storage - Compress Photos - Reduce photo size before sending - Compress Videos - Reduce video size before sending - Video Player - Enable Gestures - Swipe to control volume and brightness - Double Tap to Seek - Double tap on video edges to seek - Seek Duration - Enable Zoom - Pinch to zoom in video player - Chat List - Pin Archived Chats - Keep archived chats at the top of the list - Always Show Pinned Archive - Keep pinned archive visible even when scrolling - Show Link Previews - Display previews for links in messages - Drag to Back - Swipe from left edge to go back - Two-line - Three-line - Show Photos - Display profile photos in the chat list - Experimental - AdBlock for Channels - Hide sponsored posts in channels - Recent Media - Clear Recent Stickers - Remove all recently used stickers - Clear Recent Emojis - Remove all recently used emojis - Remove Emoji Pack - Remove %1$s Pack? - This will delete the downloaded emoji pack from your device. You can download - it again later. - - Edit custom theme - Selected - Apple - Twitter - Windows - Catmoji - Noto - System - - - Data and Storage - Disk and network usage - Storage Usage - Manage your local cache - Network Usage - View data sent and received - Automatic media download - When using mobile data - When connected on Wi-Fi - When roaming - Auto Download files - Automatically download incoming files - Auto Download stickers - Automatically download stickers - Auto Download video notes - Automatically download video notes - Autoplay media - GIFs - Autoplay GIFs in chat list and chats - Videos - Autoplay videos in chats - Enabled - Disabled - - - Power Saving - Battery - Power Saving Mode - Reduces background activity and animations to save battery - Optimize Battery Usage - Aggressively limit background work and release wake locks - Wake Lock - Keep CPU awake for background tasks. Disable to save battery - Animations - Chat Animations - Disable animations in chat to save battery - Background - Disabling this will reduce power usage but may delay background - notifications - - - - Stickers and Emoji - Stickers - Emoji - Recent Stickers - Sticker Sets - Archived Stickers - Add own stickers - Create your own sticker sets using @Stickers bot - No sticker sets installed - No stickers found for \"%1$s\" - Recent Emojis - Emoji Packs - Archived Emojis - Add own emoji - Create your own emoji packs using @Stickers bot - Clear Recent Emojis - Remove all recently used emojis - No emoji packs installed - No emojis found for \"%1$s\" - Search packs - Search - - %1$d sticker - %1$d stickers - - - %1$d emoji - %1$d emojis - - Masks - Custom Emojis - Official - Link copied to clipboard - - - Network Usage - Reset Statistics - Network Statistics - Keep track of how much data you use. Disabling can reduce disk space - usage. - - Network Statistics Disabled - Network usage tracking is currently turned off. Enable it using - the switch above to see how much data you\'re using on mobile, Wi-Fi, and roaming networks. - - Total Usage - Sent - Received - Overview - App Usage - No usage data recorded - No statistics available - Mobile - Wi-Fi - Roaming - Other - - - Storage Usage - Clear All Cache • %1$s - Includes photos, videos, documents, stickers, and GIFs from all chats. - - Cache Limit - Auto-Clear Cache - Storage Optimizer - Background storage optimization - Detailed Usage - Storage is Clean - No cached files found. - Clear Cache - Are you sure you want to clear cache for \"%1$s\"? This will free up - %2$s. - - Clear All Cache - This will remove all cached media files from all chats. Are you sure? - - Unlimited - Never - Every Day - Every Week - Every Month - Total Used - %1$d files - %1$d files - - - Who can add me to %1$s? - Who can call me? - Who can see my last seen time? - Who can see my profile photos? - Who can see my bio? - Who can add a link to my account when forwarding my messages? - Who can add me to groups and channels? - Who can see my phone number? - Who can find me by my number? - Users who add your number to their contacts will see it on Telegram - only if they are allowed to by the setting above. - - Add exceptions - Always Allow - Never Allow - %1$d users/chats - (deleted) - Chat members - Phone Number Search - No blocked users - Blocked users will not be able to contact you and will not see your Last - Seen time. - - Unblock - Block User - Search users - No users found - - - Change Passcode - Set Passcode - Your app is currently protected with a passcode. Enter a new one to - change it. - - Enter a 4-digit passcode to lock the app and protect your privacy. - Passcode - Current Passcode - Save Passcode - Turn Passcode Off - Verify Passcode - Enter your current passcode before changing or turning it off. - Incorrect passcode. - - - Add Keyword - Enable AdBlock - Whitelisted Channels - %1$d channels allowed - Load base keywords - Import common ad keywords from assets - Copy all keywords - Copy current list to clipboard - Clear all keywords - Remove all keywords from the list - Keywords to hide posts - No keywords added - Tap the + button to add keywords for filtering - Add Keywords - Enter keywords separated by commas or new lines to filter channel - posts. - - e.g. #promo, ad, реклама - Add to List - Posts from these channels won\'t be filtered - No channels whitelisted - Remove - - - last seen recently - last seen just now - - last seen %1$d minute ago - last seen %1$d minutes ago - - last seen at %1$s - last seen yesterday at %1$s - last seen %1$s - last seen within a week - last seen within a month - last seen a long time ago - online - offline - bot - Username - %1$d stickers - Archived - Add - Unarchive - Archive - Remove set - - - New Message - Add Members - New Group - New Channel - %1$d contacts - %1$d / 200000 - %1$d selected - Search contacts... - No contacts found - No results for "%1$s" - Sorted by last seen time - New Group - New Channel - Support - Channels are a tool for broadcasting your messages to unlimited audiences. - Channel Details - Channel Name - Description (optional) - Auto-Delete Messages - Off - 1 day - 2 days - 3 days - 4 days - 5 days - 6 days - 1 week - 2 weeks - 3 weeks - 1 month - 2 months - 3 months - 4 months - 5 months - 6 months - 1 year - You can provide an optional description for your channel. Any person can join your channel if they have a link. - Provide a name and an optional photo for your new group. - Group Details - Group Name - Please enter a group name - Please enter a channel name - Open Profile - Edit Name - Remove Contact - Edit Contact - First Name - Last Name - Remove contact? - Are you sure you want to remove %1$s from your contacts? - Automatically delete new messages sent in this group after a certain period of time. - Add photo - Change photo - - - Permissions Required - To provide the best experience, MonoGram needs the following permissions. - Notifications - Get notified about new messages - Allow - Phone State - Manage device states for better user experience - Battery Optimization - Ensure reliable background operation - Disable - Camera - Take photos and record video messages - Microphone - Record voice and video messages - Location - Share your location and see nearby users - - - Clear selection - Pin - - - Bot Commands - Select a command to send to the bot - - - Chat List - Konata Izumi - I\'m not short, I\'m just concentrated awesome! 🍫 Also, I\'ve decided to become a professional sleeper 😴 - 12:45 - Kagami Hiiragi - Don\'t forget about the homework! It\'s due tomorrow morning and it\'s quite difficult. - 11:20 - - - Preview - Me - I\'m not short, I\'m just concentrated awesome! 🍫\nAlso, I\'ve decided to become a professional sleeper 😴 - That\'s what you say every time you can\'t reach the top shelf... 🙄\nCheck this out: this - Stop exposing me! 😤✨\nI\'ll just use my secret weapon: 💯 pure laziness - It\'s super effective! 😵‍💫 - Today - Konata - - %1$d subscribers - Thread - - - Delete Recording - < Slide to cancel - Send Recording - Lock Recording - Swipe up - - - Add a caption… - Message - Sending messages is not allowed - - - Photo - Video - Sticker - Voice message - Video message - GIF - Location - Message - - - Cancel reply - Edit Message - Cancel edit - Send %1$d items - Send media - Cancel - Copy - Paste - Cut - Select all - Apply - Done - Refresh - Fullscreen editor - Editor - Send silently - Schedule message - Scheduled messages - Scheduled messages (%1$d) - No scheduled messages yet - Total scheduled: %1$d - Next send: %1$s - Editable now: %1$d - ID: %1$d - Edit - Send - Delete - %1$d chars • %2$d format blocks - %1$d format blocks - Select text to apply rich formatting like in Telegram - %1$d/%2$d - - Bold - Italic - Underline - Strikethrough - Spoiler - Code - Monospace - Link - Mention - Emoji - Clear - Add link - URL - Code language - Language (e.g. kotlin) - - - Commands - - - is typing - is recording video - is recording voice note - is sending photo - is sending video - is sending file - is choosing a sticker - is playing - Someone - and - and %d more - are typing - - %d person is typing - %d people are typing - - - - Photos - Videos - Documents - Stickers - Music - Voice Messages - Video Messages - Other Files - Other / Cache - Chat %d - - - Calls - - - Waiting for new messages - Stop - Background Service - Notification about app running in background - - - 📷 Photo - 📹 Video - 🎤 Voice message - 🧩 Sticker - 📎 Document - 🎵 Audio - GIF - 🎬 Video message - 👤 Contact - 📊 Poll - 📍 Location - 📞 Call - 🎮 Game - 💳 Invoice - 📚 Story - 📌 Pinned message - Message - Bot - Online - Offline - Last seen just now - Last seen %d minute ago - Last seen %d minutes ago - Last seen at %s - Last seen yesterday at %s - Last seen %s - Last seen recently - Last seen within a week - Last seen within a month - - - Pinned Messages - Pinned Message - Show all pinned - Unpin - Close - - %d message - %d messages - - - - Video message - GIF - Document - Poll: %s - Sticker %s - - - View - Crop - Filters - Draw - Text - Eraser - - - Original - B&W - Sepia - Vintage - Cool - Warm - Polaroid - Invert - - - Save - Cancel - Undo - Redo - Close - Reset - Rotate Left - Rotate Right - Add Text - Edit Text - Apply - Delete - - - Size - Zoom - Type something... - Select a tool to start editing - - - Discard changes? - You have unsaved changes. Are you sure you want to discard them? - Discard - - - Apply - Done - Cancel - Low - - - View - Trim - Filters - Text - Compress - - - Unmute - Mute - Add Text Overlay - Video Quality - Estimated Bitrate: %1$d kbps - - - Original - B&W - Sepia - Vintage - Cool - Warm - Polaroid - Invert - - - File not found - Video file missing - Discard changes? - You have unsaved changes. Are you sure you want to discard them? - Discard - - - Loading… - Web View - Close - More options - - - Options - Back - Forward - Refresh - Actions - Settings - Copy - Link copied - Share - Share link via - Browser - Find - Desktop Site - Block Ads - Text Size: %1$d%% - - - Secure - Insecure - Security Information - Insecure Connection - The connection to this site is encrypted and secure. - The connection to this site is not secure. You should not enter any sensitive information (such as passwords or credit cards) because it could be stolen by attackers. - Issued to - Issued by - Valid until - Unknown - - - Find in page… - Previous - Next - Close Find - - - Discussion - Channel - Open Maps - Directions - Navigate with - Open with - Browser / Other - Media - Members - Files - Audio - Voice - Links - GIFs - No members found - No media found - No audio found - No voice messages found - No files found - No links found - No GIFs found - BOT - Closed - ID - - - Analyzing Statistics... - Overview - Members - Messages - Viewers - Active Senders - Member Growth - New Members - Message Content - Actions - Activity by Day - Activity by Week - Top Hours - Views by Source - New Members by Source - Languages - Top Senders - msgs - Avg chars: %1$d - Top Administrators - actions - Del: %1$d | Ban: %2$d - Top Inviters - invites - Added members - Subscribers - Notifications Enabled - Avg Msg Views - Avg Msg Shares - Avg Reactions - Growth - New Subscribers - Views by Hour - Message Interactions - Instant View Interactions - Message Reactions - Recent Interactions - Message - Story - Post ID - Show Less - Show All (%1$d) - Revenue - Available Balance - Total Balance - Exchange Rate - Revenue Growth - Hourly Revenue - Insights Loaded - Zoom In - Rendering Chart... - No change - vs previous - Unknown Statistics Type - Data class: %1$s - - - Back - Options - Rewind 10 seconds - Forward 10 seconds - -%1$ds - +%1$ds - Thumbnail %1$d - %1$d / %2$d - Loading original... - - - Download - Download Video - Copy Image - Copy Text - Copy Link - Copy Link with Time - Forward - Save to GIFs - Save to Gallery - Copy to Clipboard - Restart - Pause - Play - Unlock - - - Settings - Playback Speed - Scale Mode - Fit - Zoom - Rotate Screen - Picture in Picture - Screenshot - Loop Video - Mute Audio - Subtitles - Lock Controls - Quality - Video Quality - Auto - High Res - Normal - - - Play - Pause - Rewind - Forward - - - Stickers - Emojis - GIFs - - - Recent Stickers - Stickers - Search stickers - - - Recent Emojis - Standard Emojis - Custom Emojis - Emojis - Search emojis - - - Recent & Saved GIFs - No GIFs found - Search GIFs - - - Back - Clear - Recent - - - Saved to Gallery - Share QR - Error while sending: %1$s - - - Edit Channel - Edit Group - Channel Name - Group Name - Description - Settings - Public Channel - Public Group - Auto-Translate - Topics - Management - Delete Channel - Delete Group - - - Search... - Administrators - Subscribers - Members - Blacklist - No results found - No members yet - - - Admin Rights - Custom Title - This title will be visible to all members in the chat - What can this admin do? - Manage Chat - Post Messages - Edit Messages - Delete Messages - Restrict Members - Invite Users - Manage Topics - Manage Video Chats - Post Stories - Edit Stories - Delete Stories - Add New Admins - Remain Anonymous - - - Permissions - What can members of this group do? - Add Members - - - Back - Save - Clear - Search - Add - Edit - Username - Filters - - - Recent Actions - %d events loaded - No recent actions found - Try changing filters - Not implemented - User ID copied - - - Filter Actions - Reset - Apply - Action Types - By Users - Search… - No users found - No results for \"%s\" - - - Edits - Deletions - Pins - Joins - Leaves - Invites - Promotions - Restrictions - Info - Settings - Links - Video - - - edited a message - deleted a message - pinned a message - unpinned a message - joined the chat - left the chat - invited %s - changed permissions for %s - changed restrictions for %s - changed chat title to \"%s\" - changed chat description - changed username to @%s - changed chat photo - edited invite link - revoked invite link - deleted invite link - started a video chat - ended video chat - performed an action: %s - - - Original message: - New message: - Deleted message: - Pinned message: - Unpinned message: - Until: %s - Restricted permanently - Old - New - Old chat photo - New chat photo - From - To - Permission changes: - Current permissions: - - - Messages - Media - Stickers - Links - Polls - Invite - Pin - Info - - Admin - Owner - Restricted - Banned - Member - - - Photo - Video - GIF - Sticker - Document - Audio - Voice message - Video message - Contact - Poll - Location - Venue - Unsupported message - - - HH:mm - %1$02d:%2$02d - - - %1$.1fK - %1$.1fM - - - Leave a comment - %1$d comments - %1$.1fK comments - %1$.1fM comments - - - Final Results - Anonymous - Public - Quiz - Poll - • Multiple Choice - Retract Vote - Close Poll - - %d vote - %d votes - - - - More - Vote - Explanation - - - Poll Voters - No voters yet - Close - - - Photo - Video - Sticker - Voice message - Video message - GIF - Message - - - Chat Folders - Back - New Folder - Create - Edit Folder - Save - Default Folders - Custom Folders - Delete - Create folders for different groups of chats and quickly switch between them. - No custom folders - Tap the + button to create one - All chats - %1$d chats - Move Up - Move Down - Folder Name - Choose Icon - Included Chats - Search chats… - Cancel - - - Telegram Premium - Back - Subscribe for %s per month - Unlock exclusive features - - - Doubled Limits - Up to %1$d channels, %2$d chat folders, %3$d pins, %4$d public links and more. - Voice-to-Text Conversion - Read the transcript of any voice message by tapping the button next to it. - Faster Download Speed - No more limits on the speed with which media and documents are downloaded. - Real-Time Translation - Translate entire chats in real time with a single tap. - Animated Emojis - Include animated emojis from hundreds of packs in your messages. - Advanced Chat Management - Tools to set default folder, auto-archive and hide new chats from non-contacts. - No Ads - Public channels sometimes show ads, but they will no longer appear for you. - Infinite Reactions - React with thousands of emojis — using up to 3 per message. - Premium Badge - A special badge next to your name showing that you subscribe to Telegram Premium. - Emoji Statuses - Choose from thousands of emojis to show next to your name. - Premium App Icons - Choose from a selection of Telegram app icons for your home screen. - - - Reload - Copy link - Open in browser - Add to Home Screen - - - Close Mini App? - You have unsaved changes. Are you sure you want to close? - Close - Cancel - Permission Request - Allow - Deny - Bot Permissions - Terms of Service - By launching this Mini App, you agree to the Terms of Service and Privacy Policy. The bot will be able to access your basic profile information. - Accept and Launch - - - Search in article… - Back - Clear - Instant View - More - %d views - Copy Link - Open in Browser - Search - Text Size - Play Video - Play Animation - Audio - Unknown Artist - Play - Open - Collapse - Expand - Map: %1$s, %2$s - - - Share Profile - Share your Monogram profile link - Copy Link - Copy your Monogram profile link to clipboard - - - Theme Editor - Palette Mode - Choose which palette you are editing. The editor opens on the palette currently active in the app. - Light - Dark - Editing: %1$s palette - Currently active in app: %1$s - Accent - Accent updates only the %1$s palette. - Hex accent - Apply - Cancel - Pick - Save - Load - Both - Hex - monogram-theme.json - - Theme file saved - Save failed - Theme loaded - Invalid file - Load failed - - Theme Source - Choose exactly one source for your app colors. Custom uses your editable palettes, Monet uses Android dynamic color. AMOLED only affects dark backgrounds. - Custom theme - Use your own Light/Dark palettes, accents, presets, and manual role colors. - Monet - Use system-generated Material You colors based on wallpaper (Android 12+). - AMOLED dark - Force pure black for dark surfaces to reduce glow and save power on OLED screens. - - Preset Themes - Each preset has ready Light and Dark variants. Tap Light, Dark, or Both to apply instantly. - Manual Colors (%1$s) - %1$s preview - Summary text - Action - Pick %1$s - Hue %1$d° - Saturation %1$d%% - Brightness %1$d%% - Alpha %1$d%% - - Primary - Secondary - Tertiary - Background - Surface - Primary Container - Secondary Container - Tertiary Container - Surface Variant - Outline - - L P - L C - L BG - D P - D C - D BG - - Blue - Green - Orange - Rose - Indigo - Cyan - - Classic - Balanced blue with clear readability and neutral surfaces. - - Forest - Natural greens with calm contrast and soft container tones. - - Ocean - Cool cyan-blue gradient feeling with fresh light and deep dark mode. - - Sunset - Warm orange and coral accent set with high foreground clarity. - - Graphite - Neutral grayscale base with blue-gray accents and strong structure. - - Mint - Fresh mint and teal combination with gentle containers. - - Ruby - Deep red accent with neutral containers for strong action focus. - - Lavender Gray - Muted violet-gray scheme with controlled saturation and clean contrast. - - Sand - Beige and amber palette tuned for very soft visual noise. - - Arctic - Icy blue-white feel with high legibility and crisp boundaries. - - Emerald - Vibrant green palette with clean surfaces and modern contrast. - - Copper - Warm copper-orange theme that keeps text clear in both modes. - - Sakura - Soft pink-magenta tones with gentle containers and strong highlights. - - Nord - Cool northern blues with a calm, professional visual balance. - - Camera and microphone permissions are required - Processing... - Processing error: %1$s - Close recorder - Switch camera - Finish recording - REC - READY - Time: %1$s - Zoom: %1$.1fx (range %2$.1fx - %3$.1fx) - Cancel - - Clear History? - Are you sure you want to clear chat history? This action cannot be undone. - Clear History - Delete Chat? - Are you sure you want to delete this chat? This action cannot be undone. - Delete Chat - Leave Chat? - Are you sure you want to leave this chat? - Leave - Delete Channel? - Delete Group? - Are you sure you want to delete this channel? All messages and media will be lost. - Are you sure you want to delete this group? All messages and media will be lost. - Delete %1$d chats? - Are you sure you want to delete the selected chats? - Delete Chats - Block User? - Are you sure you want to block this user? This user will not be able to send you messages. - Block - Unblock User? - Are you sure you want to unblock this user? They will be able to send you - messages again. - - Unpin message? - Are you sure you want to unpin this message? - Unpin - Are you sure you want to clear recent stickers? - Clear Stickers - Are you sure you want to clear recent emojis? - Clear Emojis - Add to contacts - Remove from contacts - Mark as read - Mark as unread - Edit - Reorder - Delete - diff --git a/presentation/src/main/res/xml/file_paths.xml b/presentation/src/main/res/xml/file_paths.xml deleted file mode 100644 index 624ed13a..00000000 --- a/presentation/src/main/res/xml/file_paths.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/presentation/src/main/resources/countries.txt b/presentation/src/main/resources/countries.txt deleted file mode 100644 index a799d8c9..00000000 --- a/presentation/src/main/resources/countries.txt +++ /dev/null @@ -1,237 +0,0 @@ -1876;JM;Jamaica;XXX XXXX -1869;KN;Saint Kitts & Nevis;XXX XXXX -1868;TT;Trinidad & Tobago;XXX XXXX -1784;VC;Saint Vincent & the Grenadines;XXX XXXX -1767;DM;Dominica;XXX XXXX -1758;LC;Saint Lucia;XXX XXXX -1721;SX;Sint Maarten;XXX XXXX -1684;AS;American Samoa;XXX XXXX -1671;GU;Guam;XXX XXXX -1670;MP;Northern Mariana Islands;XXX XXXX -1664;MS;Montserrat;XXX XXXX -1649;TC;Turks & Caicos Islands;XXX XXXX -1473;GD;Grenada;XXX XXXX -1441;BM;Bermuda;XXX XXXX -1345;KY;Cayman Islands;XXX XXXX -1340;VI;US Virgin Islands;XXX XXXX -1284;VG;British Virgin Islands;XXX XXXX -1268;AG;Antigua & Barbuda;XXX XXXX -1264;AI;Anguilla;XXX XXXX -1246;BB;Barbados;XXX XXXX -1242;BS;Bahamas;XXX XXXX -998;UZ;Uzbekistan;XX XXXXXXX -996;KG;Kyrgyzstan;XXX XXXXXX -995;GE;Georgia;XXX XXX XXX -994;AZ;Azerbaijan;XX XXX XXXX -993;TM;Turkmenistan;XX XXXXXX -992;TJ;Tajikistan;XX XXX XXXX -977;NP;Nepal;XX XXXX XXXX -976;MN;Mongolia;XX XX XXXX -975;BT;Bhutan;XX XXX XXX -974;QA;Qatar;XX XXX XXX -973;BH;Bahrain;XXXX XXXX -972;IL;Israel;XX XXX XXXX -971;AE;United Arab Emirates;XX XXX XXXX -970;PS;Palestine;XXX XX XXXX -968;OM;Oman;XXXX XXXX -967;YE;Yemen;XXX XXX XXX -966;SA;Saudi Arabia;XX XXX XXXX -965;KW;Kuwait;XXXX XXXX -964;IQ;Iraq;XXX XXX XXXX -963;SY;Syria;XXX XXX XXX -962;JO;Jordan;X XXXX XXXX -961;LB;Lebanon -960;MV;Maldives;XXX XXXX -888;FT;Anonymous Numbers;XXXX XXXX -886;TW;Taiwan;XXX XXX XXX -883;GO;International Networks -882;GO;International Networks -881;GO;Global Mobile Satellite -880;BD;Bangladesh -856;LA;Laos;XX XX XXX XXX -855;KH;Cambodia -853;MO;Macau;XXXX XXXX -852;HK;Hong Kong;X XXX XXXX -850;KP;North Korea -692;MH;Marshall Islands -691;FM;Micronesia -690;TK;Tokelau -689;PF;French Polynesia -688;TV;Tuvalu -687;NC;New Caledonia -686;KI;Kiribati -685;WS;Samoa -683;NU;Niue -682;CK;Cook Islands -681;WF;Wallis & Futuna -680;PW;Palau -679;FJ;Fiji -678;VU;Vanuatu -677;SB;Solomon Islands -676;TO;Tonga -675;PG;Papua New Guinea -674;NR;Nauru -673;BN;Brunei Darussalam;XXX XXXX -672;NF;Norfolk Island -670;TL;Timor-Leste -599;BQ;Bonaire, Sint Eustatius & Saba -599;CW;Curaçao -598;UY;Uruguay;X XXX XXXX -597;SR;Suriname;XXX XXXX -596;MQ;Martinique -595;PY;Paraguay;XXX XXX XXX -594;GF;French Guiana -593;EC;Ecuador;XX XXX XXXX -592;GY;Guyana -591;BO;Bolivia;X XXX XXXX -590;GP;Guadeloupe;XXX XX XX XX -509;HT;Haiti -508;PM;Saint Pierre & Miquelon -507;PA;Panama;XXXX XXXX -506;CR;Costa Rica;XXXX XXXX -505;NI;Nicaragua;XXXX XXXX -504;HN;Honduras;XXXX XXXX -503;SV;El Salvador;XXXX XXXX -502;GT;Guatemala;X XXX XXXX -501;BZ;Belize -500;FK;Falkland Islands -423;LI;Liechtenstein -421;SK;Slovakia;XXX XXX XXX -420;CZ;Czech Republic;XXX XXX XXX -389;MK;Macedonia;XX XXX XXX -387;BA;Bosnia & Herzegovina;XX XXX XXX -386;SI;Slovenia;XX XXX XXX -385;HR;Croatia -383;XK;Kosovo;XXXX XXXX -382;ME;Montenegro -381;RS;Serbia;XX XXX XXXX -380;UA;Ukraine;XX XXX XX XX -378;SM;San Marino;XXX XXX XXXX -377;MC;Monaco;XXXX XXXX -376;AD;Andorra;XX XX XX -375;BY;Belarus;XX XXX XXXX -374;AM;Armenia;XX XXX XXX -373;MD;Moldova;XX XXX XXX -372;EE;Estonia -371;LV;Latvia;XXX XXXXX -370;LT;Lithuania;XXX XXXXX -359;BG;Bulgaria -358;FI;Finland -357;CY;Cyprus;XXXX XXXX -356;MT;Malta;XX XX XX XX -355;AL;Albania;XX XXX XXXX -354;IS;Iceland;XXX XXXX -353;IE;Ireland;XX XXX XXXX -352;LU;Luxembourg -351;PT;Portugal;X XXXX XXXX -350;GI;Gibraltar;XXXX XXXX -299;GL;Greenland;XXX XXX -298;FO;Faroe Islands;XXX XXX -297;AW;Aruba;XXX XXXX -291;ER;Eritrea;X XXX XXX -290;SH;Saint Helena;XX XXX -269;KM;Comoros;XXX XXXX -268;SZ;Swaziland;XXXX XXXX -267;BW;Botswana;XX XXX XXX -266;LS;Lesotho;XX XXX XXX -265;MW;Malawi;77 XXX XXXX -264;NA;Namibia;XX XXX XXXX -263;ZW;Zimbabwe;XX XXX XXXX -262;RE;Réunion;XXX XXX XXX -261;MG;Madagascar;XX XX XXX XX -260;ZM;Zambia;XX XXX XXXX -258;MZ;Mozambique;XX XXX XXXX -257;BI;Burundi;XX XX XXXX -256;UG;Uganda;XX XXX XXXX -255;TZ;Tanzania;XX XXX XXXX -254;KE;Kenya;XXX XXX XXX -253;DJ;Djibouti;XX XX XX XX -252;SO;Somalia;XX XXX XXX -251;ET;Ethiopia;XX XXX XXXX -250;RW;Rwanda;XXX XXX XXX -249;SD;Sudan;XX XXX XXXX -248;SC;Seychelles;X XX XX XX -247;SH;Saint Helena;XXXX -246;IO;Diego Garcia;XXX XXXX -245;GW;Guinea-Bissau;XXX XXXX -244;AO;Angola;XXX XXX XXX -243;CD;Congo (Dem. Rep.);XX XXX XXXX -242;CG;Congo (Rep.);XX XXX XXXX -241;GA;Gabon;X XX XX XX -240;GQ;Equatorial Guinea;XXX XXX XXX -239;ST;São Tomé & Príncipe;XX XXXXX -238;CV;Cape Verde;XXX XXXX -237;CM;Cameroon;XXXX XXXX -236;CF;Central African Rep.;XX XX XX XX -235;TD;Chad;XX XX XX XX -234;NG;Nigeria -233;GH;Ghana -232;SL;Sierra Leone;XX XXX XXX -231;LR;Liberia -230;MU;Mauritius -229;BJ;Benin;XX XXX XXX -228;TG;Togo;XX XXX XXX -227;NE;Niger;XX XX XX XX -226;BF;Burkina Faso;XX XX XX XX -225;CI;Côte d`Ivoire;XX XXX XXX -224;GN;Guinea;XXX XXX XXX -223;ML;Mali;XXXX XXXX -222;MR;Mauritania;XXXX XXXX -221;SN;Senegal;XX XXX XXXX -220;GM;Gambia;XXX XXXX -218;LY;Libya;XX XXX XXXX -216;TN;Tunisia;XX XXX XXX -213;DZ;Algeria;XXX XX XX XX -212;MA;Morocco;XX XXX XXXX -211;SS;South Sudan;XX XXX XXXX -98;IR;Iran;XXX XXX XXXX -95;MM;Myanmar -94;LK;Sri Lanka;XX XXX XXXX -93;AF;Afghanistan;XXX XXX XXX -92;PK;Pakistan;XXX XXX XXXX -91;IN;India;XXXXX XXXXX -90;TR;Turkey;XXX XXX XXXX -86;CN;China;XXX XXXX XXXX -84;VN;Vietnam -82;KR;South Korea -81;JP;Japan;XX XXXX XXXX -66;TH;Thailand;X XXXX XXXX -65;SG;Singapore;XXXX XXXX -64;NZ;New Zealand -63;PH;Philippines;XXX XXX XXXX -62;ID;Indonesia -61;AU;Australia;XXX XXX XXX -60;MY;Malaysia -58;VE;Venezuela;XXX XXX XXXX -57;CO;Colombia;XXX XXX XXXX -56;CL;Chile;X XXXX XXXX -55;BR;Brazil;XX XXXXX XXXX -54;AR;Argentina -53;CU;Cuba;XXXX XXXX -52;MX;Mexico -51;PE;Peru;XXX XXX XXX -49;DE;Germany -48;PL;Poland;XXX XXX XXX -47;NO;Norway;XXXX XXXX -46;SE;Sweden;XX XXX XXXX -45;DK;Denmark;XXXX XXXX -44;GB;United Kingdom;XXXX XXXXXX -43;AT;Austria -42;YL;Y-land -41;CH;Switzerland;XX XXX XXXX -40;RO;Romania;XXX XXX XXX -39;IT;Italy -36;HU;Hungary;XXX XXX XXX -34;ES;Spain;XXX XXX XXX -33;FR;France;X XX XX XX XX -32;BE;Belgium;XXX XX XX XX -31;NL;Netherlands;X XX XX XX XX -30;GR;Greece;XXX XXX XXXX -27;ZA;South Africa;XX XXX XXXX -20;EG;Egypt;XX XXXX XXXX -7;KZ;Kazakhstan;XXX XXX XX XX -7;RU;Russian Federation;XXX XXX XXXX -1;PR;Puerto Rico;XXX XXX XXXX -1;DO;Dominican Rep.;XXX XXX XXXX -1;CA;Canada;XXX XXX XXXX -1;US;USA;XXX XXX XXXX \ No newline at end of file diff --git a/presentation/src/test/java/org/monogram/presentation/core/util/CountryManagerTest.kt b/presentation/src/test/java/org/monogram/presentation/core/util/CountryManagerTest.kt deleted file mode 100644 index 3d081b17..00000000 --- a/presentation/src/test/java/org/monogram/presentation/core/util/CountryManagerTest.kt +++ /dev/null @@ -1,100 +0,0 @@ -package org.monogram.presentation.core.util - -import org.junit.Assert.assertEquals -import org.junit.Assert.fail -import org.junit.Test - -private const val FALLBACK_VALUE = 5 - -/** - * Test cases for country manager - **/ -class CountryManagerTest { - private val countryList: List = CountryManager.getCountries() - - @Test - fun `When we get countries list, then list is not empty`() { - val result = countryList.size - - assert(result > 0) - } - - @Test - fun `When country mask is empty, then return default value`() { - val country = countryList.random().copy(mask = "") - val result = country.getMobileNumberLength() - - assertEquals(FALLBACK_VALUE, result) - } - - @Test - fun `When country mask is incorrect, then extension returns default value`() { - val country = countryList.random().copy(mask = "UNKNOWN") - val result = country.getMobileNumberLength() - - assertEquals(FALLBACK_VALUE, result) - } - - @Test - fun `When number ISO is Telegram anonymous number, then check proceeds normally`() { - val country = countryList.find { it.name == "Telegram" } - val result: Int? = country?.getMobileNumberLength() - - assertEquals("42", country!!.code) - assertEquals(FALLBACK_VALUE, result) - } - - @Test - fun `When number ISO is Fragment number, then check proceeds normally`() { - val country = countryList.find { it.name.contains("Fragment") } - val result: Int? = country?.getMobileNumberLength() - - assertEquals("888", country!!.code) - assertEquals(8, result) - } - - @Test - fun `When US, RU, UA numbers provided, then all of them passes correctly`() { - val ruIso = countryList.find { it.iso == "RU" } - val uaIso = countryList.find { it.iso == "UA" } - val usIso = countryList.find { it.iso == "US" } - - if (listOfNotNull(ruIso, uaIso, usIso).size != 3) { - fail("Some of major countries check failed") - } - - // without country code - assertEquals(10, ruIso!!.getMobileNumberLength()) - assertEquals(9, uaIso!!.getMobileNumberLength()) - assertEquals(10, usIso!!.getMobileNumberLength()) - } - - @Test - fun `When all countries checked, then all checks passed`() { - countryList.forEach { country -> - assert(country.getMobileNumberLength() >= FALLBACK_VALUE) { - fail("Failed, country $country lower than of fallback value") - } - } - } - - @Test - fun `When country phone is invalid, then return null value`() { - val result = CountryManager.getCountryForPhone("null") - assertEquals(null, result) - } - - @Test - fun `When country phone is valid, then return valid value`() { - val country = Country( - "Russian Federation", - "7", - iso = "RU", - flagEmoji = "\uD83C\uDDF7\uD83C\uDDFA", - mask = "XXX XXX XXXX" - ) - val result = CountryManager.getCountryForPhone("79000000001") - assertEquals(country, result) - } -} - diff --git a/settings.gradle.kts b/settings.gradle.kts index b7822a3a..fd31fefb 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -29,4 +29,5 @@ include(":domain") include(":presentation") include(":data") include(":core") -include(":baselineprofile") \ No newline at end of file +include(":baselineprofile") +include(":tdlib") \ No newline at end of file diff --git a/tdlib b/tdlib new file mode 160000 index 00000000..e7e66e51 --- /dev/null +++ b/tdlib @@ -0,0 +1 @@ +Subproject commit e7e66e512c82bdfde3313c4eac33f160b294e08b